From 6b2c35c7d86ba16c2602617eadf5a3913e764ad9 Mon Sep 17 00:00:00 2001 From: Sathish Ambley Date: Mon, 26 Oct 2015 10:19:57 -0700 Subject: [PATCH 01/86] msm: ADSPRPC: Register for SMMU fault handler When a SMMU fault occurs for a particular session, the fault is recorded and any further invocations from user space is returned with an error and only kernel invocations are allowed with the remote processor to allow for the session to be torn down. Change-Id: Ia787055ec6e278e6fafc4965237c41bfc876dea5 Signed-off-by: Sathish Ambley --- drivers/char/adsprpc.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 8d3241afaec2..eb180545b7d6 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -51,6 +51,7 @@ #define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D #define TZ_PIL_AUTH_QDSP6_PROC 1 #define ADSP_MMAP_HEAP_ADDR 4 +#define FASTRPC_ENOSUCH 39 #define RPC_TIMEOUT (5 * HZ) #define BALIGN 128 @@ -146,6 +147,7 @@ struct fastrpc_smmu { struct dma_iommu_mapping *mapping; int cb; int enabled; + int faults; }; struct fastrpc_session_ctx { @@ -1171,6 +1173,10 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, &ctx)); if (err) goto bail; + if (fl->sctx->smmu.faults) + err = FASTRPC_ENOSUCH; + if (err) + goto bail; if (ctx) goto wait; } @@ -1607,6 +1613,7 @@ static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int *session) if (err) goto bail; set_bit(idx, &chan->bitmap); + chan->session[idx].smmu.faults = 0; *session = idx; bail: return err; @@ -1810,6 +1817,21 @@ static int fastrpc_restart_notifier_cb(struct notifier_block *nb, return NOTIFY_DONE; } +static int fastrpc_smmu_fault_handler(struct iommu_domain *domain, + struct device *dev, unsigned long iova, int flags, void *token) +{ + struct fastrpc_session_ctx *sess = (struct fastrpc_session_ctx *)token; + int err = 0; + + VERIFY(err, sess != NULL); + if (err) + return err; + sess->smmu.faults++; + dev_err(dev, "ADSPRPC context fault: iova=0x%08lx, cb = %d, faults=%d", + iova, sess->smmu.cb, sess->smmu.faults); + return 0; +} + static const struct file_operations fops = { .open = fastrpc_device_open, .release = fastrpc_device_release, @@ -1864,6 +1886,8 @@ static int fastrpc_cb_probe(struct device *dev) iommu_domain_set_attr(sess->smmu.mapping->domain, DOMAIN_ATTR_COHERENT_HTW_DISABLE, &disable_htw); + iommu_set_fault_handler(sess->smmu.mapping->domain, + fastrpc_smmu_fault_handler, sess); VERIFY(err, !arm_iommu_attach_device(dev, sess->smmu.mapping)); if (err) goto bail; From 8e92fa45ded715248dd97f0d3b1b7546066db320 Mon Sep 17 00:00:00 2001 From: Andrey Markovytch Date: Sun, 15 Nov 2015 15:00:35 +0200 Subject: [PATCH 02/86] pfk: fixed bug that caused eCryptfs ignore some of its files Our logic that distinguished eCryptfs files from non eCryptfs ones checked bi_vcnt field in bio to make sure it has valid bio vecs. Apparently this field is not updated in some cases by block layer and in general can't be trusted outside of code that own bio. There is another field that need to be used for this purpose - bi_size Change-Id: Ibf225543618373699a0d5adc3295daf9ded6169a Signed-off-by: Andrey Markovytch --- security/pfe/pfk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/security/pfe/pfk.c b/security/pfe/pfk.c index 718f3565dbce..eef66acc789a 100644 --- a/security/pfe/pfk.c +++ b/security/pfe/pfk.c @@ -153,8 +153,8 @@ static int pfk_get_page_index(const struct bio *bio, pgoff_t *page_index) if (!bio || !page_index) return -EPERM; - /* check bio vec count > 0 before using the bio->bi_io_vec[] array */ - if (!bio->bi_vcnt) + /* check bio bi_size > 0 before using the bio->bi_io_vec[] array */ + if (!(bio->bi_iter).bi_size) return -EINVAL; if (!bio->bi_io_vec) return -EINVAL; @@ -183,8 +183,8 @@ static struct inode *pfk_bio_get_inode(const struct bio *bio) { if (!bio) return NULL; - /* check bio vec count > 0 before using the bio->bi_io_vec[] array */ - if (!bio->bi_vcnt) + /* check bio bi_size > 0 before using the bio->bi_io_vec[] array */ + if (!(bio->bi_iter).bi_size) return NULL; if (!bio->bi_io_vec) return NULL; From 42c75f47f3462a60d1d3ed0373aba6e1d1ccf224 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Fri, 6 Nov 2015 17:13:15 -0800 Subject: [PATCH 03/86] msm: mdss: add additional bound checks for deinterlace layers Add necessary buffer size checks for deinterlace layers during validate. Invalid src rect configuration on mdp hardware was leading to unmapped memory access. A valid bound check fixes the input validataion and avoids such memory access. Change-Id: Ic83ef5ea008e8d8043ab2bcf9278ec72e0269fa1 Signed-off-by: Veera Sundaram Sankaran --- drivers/video/msm/mdss/mdss_mdp_layer.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_mdp_layer.c b/drivers/video/msm/mdss/mdss_mdp_layer.c index 7e04980df544..d1b241cfcead 100644 --- a/drivers/video/msm/mdss/mdss_mdp_layer.c +++ b/drivers/video/msm/mdss/mdss_mdp_layer.c @@ -167,7 +167,7 @@ static int __layer_param_check(struct msm_fb_data_type *mfd, int content_secure; struct mdss_data_type *mdata = mfd_to_mdata(mfd); struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd); - u32 src_w, src_h, dst_w, dst_h; + u32 src_w, src_h, dst_w, dst_h, width, height; if (!ctl) { pr_err("ctl is null\n"); @@ -199,16 +199,21 @@ static int __layer_param_check(struct msm_fb_data_type *mfd, return -EINVAL; } + width = layer->buffer.width; + height = layer->buffer.height; + if (layer->flags & MDP_LAYER_DEINTERLACE) { + width *= 2; + height /= 2; + } + if (layer->buffer.width > MAX_IMG_WIDTH || layer->buffer.height > MAX_IMG_HEIGHT || layer->src_rect.w < min_src_size || layer->src_rect.h < min_src_size || - CHECK_LAYER_BOUNDS(layer->src_rect.x, layer->src_rect.w, - layer->buffer.width) || - CHECK_LAYER_BOUNDS(layer->src_rect.y, layer->src_rect.h, - layer->buffer.height)) { - pr_err("invalid source image img wh=%dx%d rect=%d,%d,%d,%d\n", - layer->buffer.width, layer->buffer.height, + CHECK_LAYER_BOUNDS(layer->src_rect.x, layer->src_rect.w, width) || + CHECK_LAYER_BOUNDS(layer->src_rect.y, layer->src_rect.h, height)) { + pr_err("invalid source image img flag=%d wh=%dx%d rect=%d,%d,%d,%d\n", + layer->flags, width, height, layer->src_rect.x, layer->src_rect.y, layer->src_rect.w, layer->src_rect.h); return -EINVAL; From 72928562a4f007337eec964db3d4dfe29abf2701 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Mon, 21 Dec 2015 14:43:42 +0530 Subject: [PATCH 04/86] mmc: sdhci: revert MMC_PM_KEEP_POWER changes related to emmc This change reverts the following gerrits as they cause the timeout issues with Hynix cards. Also, the latest code supports sleep/awake through CMD5 and hence MMC_PM_KEEP_POWER need not be set for Hynix eMMC cards. edcf5be "mmc: host: add detect vops chain" 09287cb "mmc: sdhci-msm: configure MMC_PM_KEEP_POWER for SDIO" 7cf603a "mmc: schci: add support for MMC_PM_KEEP_POWER in eMMC" c085820 "mmc: core: set MMC_PM_KEEP_POWER for certain Hynix mmc cards" CRs-Fixed: 947299 Change-Id: If863771191ee7c2b717d5817f4a88e4ad936653a Signed-off-by: Sahitya Tummala --- drivers/mmc/core/mmc.c | 22 ---------------------- drivers/mmc/core/sdio.c | 3 --- drivers/mmc/host/sdhci-msm.c | 14 -------------- drivers/mmc/host/sdhci.c | 18 ------------------ drivers/mmc/host/sdhci.h | 1 - include/linux/mmc/card.h | 1 - include/linux/mmc/host.h | 2 -- 7 files changed, 61 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 9cd075db3500..0ff1d92d8982 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -124,12 +124,6 @@ static void mmc_set_erase_size(struct mmc_card *card) mmc_init_erase(card); } -static void add_pm_flag_mmc(struct mmc_card *card, int data) -{ - if (mmc_card_mmc(card)) - card->host->pm_flags |= data; -} - static const struct mmc_fixup mmc_fixups[] = { /* avoid HPI for specific cards */ @@ -140,9 +134,6 @@ static const struct mmc_fixup mmc_fixups[] = { MMC_FIXUP("MMC16G", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, MMC_QUIRK_CACHE_DISABLE), - MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, CID_OEMID_ANY, - add_pm_flag_mmc, MMC_PM_KEEP_POWER, MMC_V5_0), - END_FIXUP }; @@ -444,9 +435,6 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) */ card->ext_csd.rev = ext_csd[EXT_CSD_REV]; - /* fixup device after ext_csd revision field is updated */ - mmc_fixup_device(card, mmc_fixups); - card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; @@ -2353,9 +2341,6 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) if (mmc_card_suspended(host->card)) goto out; - if (is_suspend) - host->dev_status = DEV_SUSPENDING; - if (host->card->cmdq_init) { BUG_ON(host->cmdq_ctx.active_reqs); @@ -2398,11 +2383,6 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) mmc_card_set_suspended(host->card); } out: - if (err) - host->dev_status = DEV_UNKNOWN; - else if (is_suspend) - host->dev_status = DEV_SUSPENDED; - /* Kick CMDQ thread to process any requests came in while suspending */ if (host->card->cmdq_init) wake_up(&host->cmdq_ctx.wait); @@ -2556,8 +2536,6 @@ static int _mmc_resume(struct mmc_host *host) mmc_hostname(host), __func__, err); out: - if (!err) - host->dev_status = DEV_RESUMED; return err; } diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 6a7e34a342a4..4ef8cd3bf355 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -980,9 +980,6 @@ static void mmc_sdio_detect(struct mmc_host *host) */ err = _mmc_detect_card_removed(host); - if (host->ops && host->ops->detect) - host->ops->detect(host, err); - mmc_release_host(host); /* diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index baf486301f32..22af3d2d9f7b 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -3161,19 +3161,6 @@ static void sdhci_msm_clear_set_dumpregs(struct sdhci_host *host, bool set) } } -static void sdhci_msm_detect(struct sdhci_host *host, bool detected) -{ - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - struct sdhci_msm_host *msm_host = pltfm_host->priv; - struct mmc_host *mmc = msm_host->mmc; - struct mmc_card *card = mmc->card; - - if (detected && mmc_card_sdio(card)) - mmc->pm_caps |= MMC_PM_KEEP_POWER; - else - mmc->pm_caps &= ~MMC_PM_KEEP_POWER; -} - int sdhci_msm_notify_load(struct sdhci_host *host, enum mmc_load state) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -3726,7 +3713,6 @@ static struct sdhci_ops sdhci_msm_ops = { .reset = sdhci_msm_reset, .clear_set_dumpregs = sdhci_msm_clear_set_dumpregs, .enhanced_strobe_mask = sdhci_msm_enhanced_strobe_mask, - .detect = sdhci_msm_detect, .notify_load = sdhci_msm_notify_load, .reset_workaround = sdhci_msm_reset_workaround, .init = sdhci_msm_init, diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f06cd8f08396..8bd772ade73f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1422,16 +1422,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode, struct mmc_host *mmc = host->mmc; u8 pwr = 0; - /* - * Don't disable/re-enable power to the card when running a - * suspend/resume sequence and the pm_flags are configured to preserve - * card power during suspend. - */ - if (mmc_card_keep_power(mmc) && - ((mmc->dev_status == DEV_SUSPENDED && mode == MMC_POWER_UP) || - (mmc->dev_status == DEV_SUSPENDING && mode == MMC_POWER_OFF))) - return; - if (!IS_ERR(mmc->supply.vmmc)) { spin_unlock_irq(&host->lock); mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); @@ -2638,13 +2628,6 @@ static void sdhci_card_event(struct mmc_host *mmc) spin_unlock_irqrestore(&host->lock, flags); } -static void sdhci_detect(struct mmc_host *mmc, bool detected) -{ - struct sdhci_host *host = mmc_priv(mmc); - - if (host->ops->detect) - host->ops->detect(host, detected); -} static int sdhci_late_init(struct mmc_host *mmc) { struct sdhci_host *host = mmc_priv(mmc); @@ -2685,7 +2668,6 @@ static const struct mmc_host_ops sdhci_ops = { .disable = sdhci_disable, .notify_load = sdhci_notify_load, .notify_halt = sdhci_notify_halt, - .detect = sdhci_detect, .force_err_irq = sdhci_force_err_irq, }; diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 741b1110f83b..80f36d61f11f 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -332,7 +332,6 @@ struct sdhci_ops { int (*enable_controller_clock)(struct sdhci_host *host); void (*clear_set_dumpregs)(struct sdhci_host *host, bool set); void (*enhanced_strobe_mask)(struct sdhci_host *host, bool set); - void (*detect)(struct sdhci_host *host, bool detected); int (*notify_load)(struct sdhci_host *host, enum mmc_load state); void (*reset_workaround)(struct sdhci_host *host, u32 enable); void (*init)(struct sdhci_host *host); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index df291c535fe3..771e8623d848 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -478,7 +478,6 @@ struct mmc_fixup { #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 #define CID_MANFID_KINGSTON 0x70 -#define CID_MANFID_HYNIX 0x90 #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index fc07b008069e..0a44d6226e6e 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -176,7 +176,6 @@ struct mmc_host_ops { unsigned long (*get_min_frequency)(struct mmc_host *host); int (*notify_load)(struct mmc_host *, enum mmc_load); void (*notify_halt)(struct mmc_host *mmc, bool halt); - void (*detect)(struct mmc_host *host, bool detected); void (*force_err_irq)(struct mmc_host *host, u64 errmask); }; @@ -289,7 +288,6 @@ enum dev_state { DEV_SUSPENDING = 1, DEV_SUSPENDED, DEV_RESUMED, - DEV_UNKNOWN, /* Device is in an unknown state */ }; /** From 488d6ca373a86e5df8dd0b2a95476d45cd2b1d11 Mon Sep 17 00:00:00 2001 From: Ashay Jaiswal Date: Tue, 29 Dec 2015 13:50:07 +0530 Subject: [PATCH 05/86] ARM: dts: msm: enable charger LED support for MSM8937 Enable charger LED and configure it in software controlled blinking mode. CRs-Fixed: 948641 Change-Id: Ie0b885351c9c34a1a4223050c0d503e54eb0f6eb Signed-off-by: Ashay Jaiswal --- arch/arm/boot/dts/qcom/msm8937-pmi8937-mtp.dtsi | 2 ++ arch/arm/boot/dts/qcom/msm8937-pmi8950-mtp.dtsi | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8937-pmi8937-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8937-pmi8937-mtp.dtsi index 74e40796c322..593ddb23f004 100644 --- a/arch/arm/boot/dts/qcom/msm8937-pmi8937-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8937-pmi8937-mtp.dtsi @@ -39,4 +39,6 @@ &pmi8937_charger { qcom,battery-data = <&mtp_batterydata>; + qcom,chg-led-sw-controls; + qcom,chg-led-support; }; diff --git a/arch/arm/boot/dts/qcom/msm8937-pmi8950-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8937-pmi8950-mtp.dtsi index 64e9e17d2a64..c90d3cc0441a 100644 --- a/arch/arm/boot/dts/qcom/msm8937-pmi8950-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8937-pmi8950-mtp.dtsi @@ -39,6 +39,8 @@ &pmi8950_charger { qcom,battery-data = <&mtp_batterydata>; + qcom,chg-led-sw-controls; + qcom,chg-led-support; }; &mdss_dsi0 { From 4d2403802f84b70fc69ce7df9a0bc8aeabd11a21 Mon Sep 17 00:00:00 2001 From: Shilpa Mamidi Date: Wed, 23 Dec 2015 13:49:13 +0530 Subject: [PATCH 06/86] msm: cpp: Set GDRC register set after FW load As per hardware specifications register read cannot be done upon setting GDRC register with HW_CONTROL. This change will set GDRC register with HW_CONTROL after firmware load to ensure that HW version returns correct value CRs-Fixed: 950485 Change-Id: Ia08a14f9f05cd410140cf01c26b41d3afba94513 Signed-off-by: Shilpa Mamidi --- .../media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index f26ac00c9a6e..001fb0a7d4e9 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -1129,12 +1129,6 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev) } } - rc = msm_cpp_update_gdscr_status(cpp_dev, true); - if (rc < 0) { - pr_err("update cpp gdscr status failed\n"); - goto req_irq_fail; - } - cpp_dev->hw_info.cpp_hw_version = msm_camera_io_r(cpp_dev->cpp_hw_base); if (cpp_dev->hw_info.cpp_hw_version == CPP_HW_VERSION_4_1_0) { @@ -1376,6 +1370,10 @@ static int32_t cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin) MSM_CPP_MSG_ID_JUMP_ACK, rc); } + rc = msm_cpp_update_gdscr_status(cpp_dev, true); + if (rc < 0) + pr_err("update cpp gdscr status failed\n"); + end: return rc; } From 42128ceba4a11dbb0cc0b2ab62dc7954e6b9e33e Mon Sep 17 00:00:00 2001 From: Komal Seelam Date: Wed, 30 Dec 2015 02:53:40 -0800 Subject: [PATCH 07/86] cnss-sdio: Dynamically allocate ramdump memory Existing solution to reserve the memory region for CNSS ramdump collection has it's own limitations because of reserving the memory region for each platforms even before CNSS driver is probed. Add implementation to allocate the required memory for CNSS ramdump using dma_alloc_coherent API and update the physical address in dump table so that tools can find the starting address of the CNSS ramdump in the crash dump. Change-Id: I9fb3d77fdd35de54ca2a7a27d4a55bd12049311f Signed-off-by: Komal Seelam CRs-Fixed: 957203 --- drivers/net/wireless/cnss/cnss_sdio.c | 113 ++++++++++++++++++++------ 1 file changed, 88 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/cnss/cnss_sdio.c b/drivers/net/wireless/cnss/cnss_sdio.c index ee0fe5829eb8..98c2b05473c7 100644 --- a/drivers/net/wireless/cnss/cnss_sdio.c +++ b/drivers/net/wireless/cnss/cnss_sdio.c @@ -39,6 +39,11 @@ #define WLAN_VREG_XTAL_MIN 1800000 #define POWER_ON_DELAY 4 +/* Values for Dynamic Ramdump Collection*/ +#define CNSS_DUMP_FORMAT_VER 0x11 +#define CNSS_DUMP_MAGIC_VER_V2 0x42445953 +#define CNSS_DUMP_NAME "CNSS_WLAN" + struct cnss_unsafe_channel_list { u16 unsafe_ch_count; u16 unsafe_ch_list[CNSS_MAX_CH_NUM]; @@ -70,6 +75,8 @@ struct cnss_ssr_info { unsigned long ramdump_size; void *ramdump_addr; phys_addr_t ramdump_phys; + struct msm_dump_data dump_data; + bool ramdump_dynamic; char subsys_name[10]; }; @@ -354,19 +361,45 @@ static void cnss_subsys_exit(void) ssr_info->subsys = NULL; } +static int cnss_configure_dump_table(struct cnss_ssr_info *ssr_info) +{ + struct msm_dump_entry dump_entry; + int ret; + + ssr_info->dump_data.addr = ssr_info->ramdump_phys; + ssr_info->dump_data.len = ssr_info->ramdump_size; + ssr_info->dump_data.version = CNSS_DUMP_FORMAT_VER; + ssr_info->dump_data.magic = CNSS_DUMP_MAGIC_VER_V2; + strlcpy(ssr_info->dump_data.name, CNSS_DUMP_NAME, + sizeof(ssr_info->dump_data.name)); + + dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN; + dump_entry.addr = virt_to_phys(&ssr_info->dump_data); + + ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry); + if (ret) + pr_err("%s: Dump table setup failed: %d\n", __func__, ret); + + return ret; +} + static int cnss_configure_ramdump(void) { struct cnss_ssr_info *ssr_info; int ret = 0; struct resource *res; const char *name; + u32 ramdump_size = 0; + struct device *dev; if (!cnss_pdata) return -ENODEV; + + dev = &cnss_pdata->pdev->dev; + ssr_info = &cnss_pdata->ssr_info; - ret = of_property_read_string(cnss_pdata->pdev->dev.of_node, - CNSS_SUBSYS_NAME_KEY, + ret = of_property_read_string(dev->of_node, CNSS_SUBSYS_NAME_KEY, &name); if (ret) { pr_err("%s: cnss missing DT key '%s'\n", __func__, @@ -374,44 +407,65 @@ static int cnss_configure_ramdump(void) ret = -ENODEV; goto err_subsys_name_query; } + strlcpy(ssr_info->subsys_name, name, sizeof(ssr_info->subsys_name)); - res = platform_get_resource_byname(cnss_pdata->pdev, - IORESOURCE_MEM, "ramdump"); - if (res) { - ssr_info->ramdump_phys = res->start; - ssr_info->ramdump_size = resource_size(res); + if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic", + &ramdump_size) == 0) { + ssr_info->ramdump_addr = dma_alloc_coherent(dev, ramdump_size, + &ssr_info->ramdump_phys, + GFP_KERNEL); + if (ssr_info->ramdump_addr) + ssr_info->ramdump_size = ramdump_size; + ssr_info->ramdump_dynamic = true; } else { - pr_err("%s: CNSS ramdump mem not available\n", __func__); - return 0; + res = platform_get_resource_byname(cnss_pdata->pdev, + IORESOURCE_MEM, "ramdump"); + if (res) { + ssr_info->ramdump_phys = res->start; + ramdump_size = resource_size(res); + ssr_info->ramdump_addr = ioremap(ssr_info->ramdump_phys, + ramdump_size); + if (ssr_info->ramdump_addr) + ssr_info->ramdump_size = ramdump_size; + ssr_info->ramdump_dynamic = false; + } } - ssr_info->ramdump_addr = ioremap(ssr_info->ramdump_phys, - ssr_info->ramdump_size); + pr_info("%s: ramdump addr: %p, phys: %pa subsys:'%s'\n", __func__, + ssr_info->ramdump_addr, &ssr_info->ramdump_phys, + ssr_info->subsys_name); - if (!ssr_info->ramdump_addr || ssr_info->ramdump_size == 0) { - ssr_info->ramdump_size = 0; - ssr_info->ramdump_addr = NULL; - pr_err("%s: CNSS ramdump will not be collected\n", __func__); + if (ssr_info->ramdump_size == 0) { + pr_info("%s: CNSS ramdump will not be collected", __func__); return 0; } - pr_info("%s: ramdump addr: %p, phys: %pa subsys:'%s'\n", __func__, - ssr_info->ramdump_addr, - &ssr_info->ramdump_phys, - ssr_info->subsys_name); + if (ssr_info->ramdump_dynamic) { + ret = cnss_configure_dump_table(ssr_info); + if (ret) + goto err_configure_dump_table; + } ssr_info->ramdump_dev = create_ramdump_device(ssr_info->subsys_name, - &cnss_pdata->pdev->dev); + dev); if (!ssr_info->ramdump_dev) { ret = -ENOMEM; pr_err("%s: ramdump dev create failed: error=%d\n", __func__, ret); - goto err_create_ramdump; + goto err_configure_dump_table; } + return 0; -err_create_ramdump: - iounmap(ssr_info->ramdump_addr); + +err_configure_dump_table: + if (ssr_info->ramdump_dynamic) + dma_free_coherent(dev, ssr_info->ramdump_size, + ssr_info->ramdump_addr, + ssr_info->ramdump_phys); + else + iounmap(ssr_info->ramdump_addr); + ssr_info->ramdump_addr = NULL; ssr_info->ramdump_size = 0; err_subsys_name_query: @@ -421,13 +475,22 @@ static int cnss_configure_ramdump(void) static void cnss_ramdump_cleanup(void) { struct cnss_ssr_info *ssr_info; + struct device *dev; if (!cnss_pdata) return; + dev = &cnss_pdata->pdev->dev; ssr_info = &cnss_pdata->ssr_info; - if (ssr_info->ramdump_addr) - iounmap(ssr_info->ramdump_addr); + if (ssr_info->ramdump_addr) { + if (ssr_info->ramdump_dynamic) + dma_free_coherent(dev, ssr_info->ramdump_size, + ssr_info->ramdump_addr, + ssr_info->ramdump_phys); + else + iounmap(ssr_info->ramdump_addr); + } + ssr_info->ramdump_addr = NULL; if (ssr_info->ramdump_dev) destroy_ramdump_device(ssr_info->ramdump_dev); From 3b780c74f7c2ffddc87c3a0b884e27c3e4f47554 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Tue, 7 Mar 2017 15:54:56 +0100 Subject: [PATCH 08/86] android: binder: add padding to binder_fd_array_object. binder_fd_array_object starts with a 4-byte header, followed by a few fields that are 8 bytes when ANDROID_BINDER_IPC_32BIT=N. This can cause alignment issues in a 64-bit kernel with a 32-bit userspace, as on x86_32 an 8-byte primitive may be aligned to a 4-byte address. Pad with a __u32 to fix this. Signed-off-by: Martijn Coenen Git-commit: a388cf91c7fd5279e923e167af59925826b055d5 Git-repo: https://android.googlesource.com/kernel/common Change-Id: I4374ed2cc3ccd3c6a1474cb7209b53ebfd91077b Signed-off-by: Nirmal Abraham --- drivers/staging/android/uapi/binder.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index 4212aff58153..0fd7ce41c75f 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -131,6 +131,7 @@ enum { /* struct binder_fd_array_object - object describing an array of fds in a buffer * @hdr: common header structure + * @pad: padding to ensure correct alignment * @num_fds: number of file descriptors in the buffer * @parent: index in offset array to buffer holding the fd array * @parent_offset: start offset of fd array in the buffer @@ -151,6 +152,7 @@ enum { */ struct binder_fd_array_object { struct binder_object_header hdr; + __u32 pad; binder_size_t num_fds; binder_size_t parent; binder_size_t parent_offset; From 68130c50fc6dc6fb1de04377414655851413b443 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Tue, 20 Jun 2017 15:25:05 +0530 Subject: [PATCH 09/86] ARM: dts: msm: Mount the vendor partition during early init Add support to early mount vendor partition so that vendor modules can be loaded during early init for msm8917, msm8937, msm8953 and msm8996. CRs-Fixed: 2055039 Change-Id: If9c7d4b1f7d0e5ae811890b59ec0d9fba20f2f15 Signed-off-by: Swetha Chikkaboraiah Signed-off-by: Nirmal Abraham --- .../devicetree/bindings/arm/msm/android.txt | 54 +++++++++++++++++++ .../devicetree/bindings/vendor-prefixes.txt | 1 + arch/arm/boot/dts/qcom/msm8917.dtsi | 17 ++++++ arch/arm/boot/dts/qcom/msm8937.dtsi | 17 ++++++ arch/arm/boot/dts/qcom/msm8953.dtsi | 17 ++++++ arch/arm/boot/dts/qcom/msm8996.dtsi | 17 ++++++ 6 files changed, 123 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/msm/android.txt diff --git a/Documentation/devicetree/bindings/arm/msm/android.txt b/Documentation/devicetree/bindings/arm/msm/android.txt new file mode 100644 index 000000000000..9f4616fadcaf --- /dev/null +++ b/Documentation/devicetree/bindings/arm/msm/android.txt @@ -0,0 +1,54 @@ +Android firmware + +Node to specify early mount of vendor partition. + +Required properties + +-compatible: "android,firmware" + +Child nodes: +------------ + +fstab: +------------------------------ + +fstab entry to specify mount attributes of vendor partition. + +Required properties: + +-compatible: "android,fstab" + +Child nodes: +------------ + +vendor: +----------------- + +vendor partition specification. + +Required properties: + +-compatible: "android,vendor" +-dev: block device corresponding to vendor partition +-type: file system type of vendor partition +-mnt_flags: mount flags +-fsmgr_flags: fsmgr flags + +Example: + + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/soc/1da4000.ufshc/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,slotselect"; + status = "ok"; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 1806c1435c4b..410ea1973688 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -17,6 +17,7 @@ amd Advanced Micro Devices (AMD), Inc. amlogic Amlogic, Inc. ams AMS AG amstaos AMS-Taos Inc. +android Google Inc. apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. armadeus ARMadeus Systems SARL diff --git a/arch/arm/boot/dts/qcom/msm8917.dtsi b/arch/arm/boot/dts/qcom/msm8917.dtsi index 159e985d6018..fe0812a7655f 100644 --- a/arch/arm/boot/dts/qcom/msm8917.dtsi +++ b/arch/arm/boot/dts/qcom/msm8917.dtsi @@ -49,6 +49,23 @@ sdhc2 = &sdhc_2; /* SDC2 for SD card */ }; + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; + }; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm/boot/dts/qcom/msm8937.dtsi b/arch/arm/boot/dts/qcom/msm8937.dtsi index 6582bbdab806..34a226fafe2e 100644 --- a/arch/arm/boot/dts/qcom/msm8937.dtsi +++ b/arch/arm/boot/dts/qcom/msm8937.dtsi @@ -25,6 +25,23 @@ bootargs = "sched_enable_hmp=1"; }; + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; + }; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm/boot/dts/qcom/msm8953.dtsi b/arch/arm/boot/dts/qcom/msm8953.dtsi index 89d86bc24ad9..95c1e5daf2ed 100644 --- a/arch/arm/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953.dtsi @@ -26,6 +26,23 @@ bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1"; }; + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; + }; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index ee299bc0ac98..9eb4a78787df 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -158,6 +158,23 @@ soc: soc { }; + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/soc/7464900.sdhci/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; + }; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; From c384e211a2899542640526f43084f01160408f24 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Mon, 10 Jul 2017 11:36:21 +0530 Subject: [PATCH 10/86] ARM: dts: msm: Mount the system partition during early init Add support to early mount system partition so that system modules can be loaded during early init for msm8917, msm8937, msm8953 and msm8996. Change-Id: I9d75bec6ff9bada5ab2db6de2a58e40323aa6ca2 Signed-off-by: Swetha Chikkaboraiah Signed-off-by: Nirmal Abraham --- .../devicetree/bindings/arm/msm/android.txt | 34 ++++++++++++++++++- arch/arm/boot/dts/qcom/msm8917.dtsi | 9 +++++ arch/arm/boot/dts/qcom/msm8937.dtsi | 9 +++++ arch/arm/boot/dts/qcom/msm8953.dtsi | 9 +++++ arch/arm/boot/dts/qcom/msm8996.dtsi | 9 +++++ 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/msm/android.txt b/Documentation/devicetree/bindings/arm/msm/android.txt index 9f4616fadcaf..50f7fd08ecff 100644 --- a/Documentation/devicetree/bindings/arm/msm/android.txt +++ b/Documentation/devicetree/bindings/arm/msm/android.txt @@ -1,6 +1,6 @@ Android firmware -Node to specify early mount of vendor partition. +Node to specify early mount of vendor and system partition. Required properties @@ -52,3 +52,35 @@ Example: }; }; }; + +system: +----------------- + +system partition specification. + +Required properties: + +-compatible: "android,system" +-dev: block device corresponding to system partition +-type: file system type of system partition +-mnt_flags: mount flags +-fsmgr_flags: fsmgr flags + +Example: + + firmware: firmware { + android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/platform/soc/1da4000.ufshc/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,slotselect"; + status = "ok"; + }; + }; + }; + }; diff --git a/arch/arm/boot/dts/qcom/msm8917.dtsi b/arch/arm/boot/dts/qcom/msm8917.dtsi index fe0812a7655f..c529836d6d66 100644 --- a/arch/arm/boot/dts/qcom/msm8917.dtsi +++ b/arch/arm/boot/dts/qcom/msm8917.dtsi @@ -62,6 +62,15 @@ fsmgr_flags = "wait"; status = "ok"; }; + system { + compatible = "android,system"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8937.dtsi b/arch/arm/boot/dts/qcom/msm8937.dtsi index 34a226fafe2e..ddf40d1b3bb3 100644 --- a/arch/arm/boot/dts/qcom/msm8937.dtsi +++ b/arch/arm/boot/dts/qcom/msm8937.dtsi @@ -38,6 +38,15 @@ fsmgr_flags = "wait"; status = "ok"; }; + system { + compatible = "android,system"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8953.dtsi b/arch/arm/boot/dts/qcom/msm8953.dtsi index 95c1e5daf2ed..4847acd8c03d 100644 --- a/arch/arm/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953.dtsi @@ -39,6 +39,15 @@ fsmgr_flags = "wait"; status = "ok"; }; + system { + compatible = "android,system"; + dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait"; + status = "ok"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index 9eb4a78787df..52fd16226434 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -171,6 +171,15 @@ fsmgr_flags = "wait"; status = "ok"; }; + system { + compatible = "android,system"; + dev = "/dev/block/platform/soc/7464900.sdhci/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,discard"; + fsmgr_flags = "wait,verify"; + status = "ok"; + }; + }; }; }; From ebb115cf6560da7aa5dee112a9fc6fa06ceec3a2 Mon Sep 17 00:00:00 2001 From: Prasad Sodagudi Date: Mon, 6 Mar 2017 12:08:11 -0800 Subject: [PATCH 11/86] arm64: Remove orig_addr_limit check in do_page_fault Remove the orig_addr_limit check against KERNEL_DS in do_page_fault handler for permissions faults. This check is part of UAO and PAN features and these features are disabled by default. Change-Id: I5de760b983edcf14d1c0bee2a53dc091ceca31da Signed-off-by: Prasad Sodagudi --- arch/arm64/mm/fault.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 3d3879de426f..daf36e4fc308 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -257,10 +257,6 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, } if (addr < USER_DS && is_permission_fault(esr, regs)) { - /* regs->orig_addr_limit may be 0 if we entered from EL0 */ - if (regs->orig_addr_limit == KERNEL_DS) - die("Accessing user space memory with fs=KERNEL_DS", regs, esr); - if (is_el1_instruction_abort(esr)) die("Attempting to execute userspace memory", regs, esr); From c6564a281beffd0ffdfb0e6ada3a587ca249d41f Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Wed, 2 Aug 2017 15:55:14 +0530 Subject: [PATCH 12/86] msm: camera: isp: avoid spin lock recursion Use spin lock only for a required share resource. Avoid potential dead lock during overflow . Change-Id: Icfefc8f3714ea9b58d7632a60ae9137bd94e5a77 Signed-off-by: VijayaKumar T M --- .../media/platform/msm/camera_v2/isp/msm_isp_axi_util.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 5f7a015da16a..6a339a97a671 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1547,12 +1547,11 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, { int i, j; uint32_t update_state; - unsigned long flags, flags1; + unsigned long flags; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_stream *stream_info; int num_stream = 0; - spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags); for (i = 0; i < VFE_AXI_SRC_MAX; i++) { if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) != frame_src) { @@ -1566,7 +1565,7 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, !stream_info->controllable_output) || stream_info->state == AVAILABLE) continue; - spin_lock_irqsave(&stream_info->lock, flags1); + spin_lock_irqsave(&stream_info->lock, flags); if (stream_info->state == PAUSING) { /*AXI Stopped, apply update*/ stream_info->state = PAUSED; @@ -1580,10 +1579,8 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, } else if (stream_info->state == RESUMING) { msm_isp_update_dual_HW_axi(vfe_dev, stream_info); } - spin_unlock_irqrestore(&stream_info->lock, flags1); + spin_unlock_irqrestore(&stream_info->lock, flags); } - spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock, - flags); if (num_stream) update_state = atomic_dec_return( &axi_data->axi_cfg_update[frame_src]); From e8a0d0b4240b753aaedef4464c8f416fb86970b2 Mon Sep 17 00:00:00 2001 From: Sarada Prasanna Garnayak Date: Tue, 8 Aug 2017 12:52:44 +0530 Subject: [PATCH 13/86] wcnss: update MAC address generate logic from the serial number The WLAN host driver use device serial number to generate MAC address. The wcnss platform driver export symbol for WLAN host driver to read the device serial number to generate the MAC address. Add updated SOC API to get the device serial number in the wcnss platform driver. CRs-Fixed: 2089225 Change-Id: Ic540f2e6e705131f18b59e8f139087d5d99024f6 Signed-off-by: Sarada Prasanna Garnayak --- drivers/net/wireless/wcnss/wcnss_wlan.c | 57 +++---------------------- 1 file changed, 6 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c index 11d038aea950..0b487822a0cb 100644 --- a/drivers/net/wireless/wcnss/wcnss_wlan.c +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -186,13 +187,11 @@ static DEFINE_SPINLOCK(reg_spinlock); #define WCNSS_MAX_BUILD_VER_LEN 256 #define WCNSS_MAX_CMD_LEN (128) #define WCNSS_MIN_CMD_LEN (3) -#define WCNSS_MIN_SERIAL_LEN (6) /* control messages from userspace */ #define WCNSS_USR_CTRL_MSG_START 0x00000000 -#define WCNSS_USR_SERIAL_NUM (WCNSS_USR_CTRL_MSG_START + 1) -#define WCNSS_USR_HAS_CAL_DATA (WCNSS_USR_CTRL_MSG_START + 2) -#define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 3) +#define WCNSS_USR_HAS_CAL_DATA (WCNSS_USR_CTRL_MSG_START + 1) +#define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 2) #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" #define SHOW_MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x\n" @@ -364,7 +363,6 @@ static struct { unsigned char wcnss_version[WCNSS_VERSION_LEN]; unsigned char fw_major; unsigned char fw_minor; - unsigned int serial_number; int thermal_mitigation; enum wcnss_hw_type wcnss_hw_type; void (*tm_notify)(struct device *, int); @@ -481,34 +479,6 @@ static ssize_t wcnss_wlan_macaddr_show(struct device *dev, static DEVICE_ATTR(wcnss_mac_addr, S_IRUSR | S_IWUSR, wcnss_wlan_macaddr_show, wcnss_wlan_macaddr_store); -static ssize_t wcnss_serial_number_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (!penv) - return -ENODEV; - - return scnprintf(buf, PAGE_SIZE, "%08X\n", penv->serial_number); -} - -static ssize_t wcnss_serial_number_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int value; - - if (!penv) - return -ENODEV; - - if (sscanf(buf, "%08X", &value) != 1) - return -EINVAL; - - penv->serial_number = value; - return count; -} - -static DEVICE_ATTR(serial_number, S_IRUSR | S_IWUSR, - wcnss_serial_number_show, wcnss_serial_number_store); - - static ssize_t wcnss_thermal_mitigation_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1203,13 +1173,9 @@ static int wcnss_create_sysfs(struct device *dev) if (!dev) return -ENODEV; - ret = device_create_file(dev, &dev_attr_serial_number); - if (ret) - return ret; - ret = device_create_file(dev, &dev_attr_thermal_mitigation); if (ret) - goto remove_serial; + return ret; ret = device_create_file(dev, &dev_attr_wcnss_version); if (ret) @@ -1225,8 +1191,6 @@ static int wcnss_create_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_wcnss_version); remove_thermal: device_remove_file(dev, &dev_attr_thermal_mitigation); -remove_serial: - device_remove_file(dev, &dev_attr_serial_number); return ret; } @@ -1234,7 +1198,6 @@ static int wcnss_create_sysfs(struct device *dev) static void wcnss_remove_sysfs(struct device *dev) { if (dev) { - device_remove_file(dev, &dev_attr_serial_number); device_remove_file(dev, &dev_attr_thermal_mitigation); device_remove_file(dev, &dev_attr_wcnss_version); device_remove_file(dev, &dev_attr_wcnss_mac_addr); @@ -1683,7 +1646,8 @@ EXPORT_SYMBOL(wcnss_unregister_thermal_mitigation); unsigned int wcnss_get_serial_number(void) { if (penv) - return penv->serial_number; + return socinfo_get_serial_number(); + return 0; } EXPORT_SYMBOL(wcnss_get_serial_number); @@ -2687,15 +2651,6 @@ void process_usr_ctrl_cmd(u8 *buf, size_t len) switch (cmd) { - case WCNSS_USR_SERIAL_NUM: - if (WCNSS_MIN_SERIAL_LEN > len) { - pr_err("%s: Invalid serial number\n", __func__); - return; - } - penv->serial_number = buf[2] << 24 | buf[3] << 16 - | buf[4] << 8 | buf[5]; - break; - case WCNSS_USR_HAS_CAL_DATA: if (1 < buf[2]) pr_err("%s: Invalid data for cal %d\n", __func__, From 69bd0dfd83b29671195098b94022ed36f036459a Mon Sep 17 00:00:00 2001 From: Hardik Kantilal Patel Date: Fri, 11 Aug 2017 19:00:19 +0530 Subject: [PATCH 14/86] wcnss: Reassign the correct control message id With the change 'commit 010bbac71 ("wcnss: update MAC address generate logic from the serial number")', incorrect control message id are assigned which result into wrong MAC address assignment to WLAN Host Driver. To resove this issue reassign the correct control message id. Change-Id: I975108a54721b65132cd2ebc1dfadad227bf585f Signed-off-by: Hardik Kantilal Patel --- drivers/net/wireless/wcnss/wcnss_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c index 0b487822a0cb..a4cd9e0442f9 100644 --- a/drivers/net/wireless/wcnss/wcnss_wlan.c +++ b/drivers/net/wireless/wcnss/wcnss_wlan.c @@ -190,8 +190,8 @@ static DEFINE_SPINLOCK(reg_spinlock); /* control messages from userspace */ #define WCNSS_USR_CTRL_MSG_START 0x00000000 -#define WCNSS_USR_HAS_CAL_DATA (WCNSS_USR_CTRL_MSG_START + 1) -#define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 2) +#define WCNSS_USR_HAS_CAL_DATA (WCNSS_USR_CTRL_MSG_START + 2) +#define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 3) #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" #define SHOW_MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x\n" From c5f2f6dcb73ed593e09b25ddc6c18a2dfacc2db3 Mon Sep 17 00:00:00 2001 From: Prabhakar Reddy Krishnappa Date: Thu, 18 May 2017 17:43:17 -0700 Subject: [PATCH 15/86] msm: vidc: Cancel userptr validation during secure decode Secure decode doesn't need userptr and uses ion fd instead. We were conducting userptr validation regardless of the decode mode (secure/ unsecure). This forced user to populate userptr with a dummy value during QBUF in secure mode decode on both output and capture ports to avoid a userptr validation fail. CRs-Fixed: 2049213 Change-Id: I0060efb52792201a2634072f648a537ebb02d17c Signed-off-by: Prabhakar Reddy Krishnappa Signed-off-by: Vasantha Balla --- drivers/media/platform/msm/vidc/msm_vidc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 39ab47a5932c..0c60d1ace21a 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -936,7 +936,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) b->m.planes[i].m.userptr = buffer_info->uvaddr[i]; b->m.planes[i].reserved[0] = buffer_info->fd[i]; b->m.planes[i].reserved[1] = buffer_info->buff_off[i]; - if (!b->m.planes[i].m.userptr) { + if (!(inst->flags & VIDC_SECURE) && !b->m.planes[i].m.userptr) { dprintk(VIDC_ERR, "%s: Failed to find user virtual address, %#lx, %d, %d\n", __func__, b->m.planes[i].m.userptr, b->type, i); From 61772868b96643c5e178a0d63ab07f4c47d66f63 Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Thu, 31 Aug 2017 16:14:21 +0530 Subject: [PATCH 16/86] defconfig: Disable CONFIG_SYSVIPC for msm Android SELinux policies block SysV IPC. New kernels should not be built with it. Change-Id: I64296bd66b4297d550071fb8292726ca57a2ae15 Signed-off-by: Srinivasarao P --- arch/arm64/configs/msm-perf_defconfig | 1 - arch/arm64/configs/msm_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index d2d0ef991f7d..eec185b158ca 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -1,5 +1,4 @@ CONFIG_LOCALVERSION="-perf" -CONFIG_SYSVIPC=y CONFIG_AUDIT=y # CONFIG_AUDITSYSCALL is not set CONFIG_NO_HZ=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 373cf3316d0e..9a85788611b1 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -1,4 +1,3 @@ -CONFIG_SYSVIPC=y CONFIG_AUDIT=y # CONFIG_AUDITSYSCALL is not set CONFIG_NO_HZ=y From 5eeee545207528ada81d5b214f4277e44edada00 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Mon, 28 Aug 2017 13:19:13 +0530 Subject: [PATCH 17/86] defconfig: msm: Disable DEVPORT config for msm8937 and msm8996 Disable CONFIG_DEVPORT config for msm8937 and msm8996. As selinux policy requires this node to be not accessible to userspace. CRs-Fixed: 2077590 Change-Id: I302d71a56764504ec246ddb6a98d8c07094846e4 Signed-off-by: Mohammed Khajapasha Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/msm-perf_defconfig | 1 + arch/arm64/configs/msm8937-perf_defconfig | 1 + arch/arm64/configs/msm8937_defconfig | 1 + arch/arm64/configs/msm_defconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index eec185b158ca..a3a3d11a3b89 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -320,6 +320,7 @@ CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_MSM_RDBG=m diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig index 6c0b3e98e057..de324e558210 100644 --- a/arch/arm64/configs/msm8937-perf_defconfig +++ b/arch/arm64/configs/msm8937-perf_defconfig @@ -323,6 +323,7 @@ CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_MSM_RDBG=m diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig index 4a2c824c7953..843f345ea619 100644 --- a/arch/arm64/configs/msm8937_defconfig +++ b/arch/arm64/configs/msm8937_defconfig @@ -324,6 +324,7 @@ CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_MSM_RDBG=m diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 9a85788611b1..71369eeb1994 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -323,6 +323,7 @@ CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_MSM_RDBG=m From 8c6d236f469a3ddaebec2a79f4769686141bc62e Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 31 Aug 2017 17:02:11 +0530 Subject: [PATCH 18/86] defconfig : enable quota feature for MSM8996 The recent Android upgrade mandates disk quota feature to be enabled by default on /data. Hence, enable the required kernel config options to support the same. Change-Id: I5d50c71a1758f43ec4312081f5944cb758b927b5 Signed-off-by: Ankit Jain --- arch/arm64/configs/msm-perf_defconfig | 2 ++ arch/arm64/configs/msm_defconfig | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index a3a3d11a3b89..1e0df185e3b0 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -593,7 +593,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index 71369eeb1994..d8b890c1a15b 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -614,7 +614,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y From df1c09bd7a920b49d185ea6c69ced9463b417f27 Mon Sep 17 00:00:00 2001 From: Tirupathi Reddy Date: Fri, 1 Sep 2017 11:16:42 +0530 Subject: [PATCH 19/86] power: qpnp-smbcharger: expose CURRENT_MAX prop via batt psy Expose CURRENT_MAX property as it is a required battery power supply property. CRs-Fixed: 2068899 Change-Id: Ib46c0c73e0e298d35b7d671f87c8cd67e328e017 Signed-off-by: Tirupathi Reddy --- drivers/power/qpnp-smbcharger.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c index 224e48c65b42..328877a87951 100644 --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -5940,6 +5940,24 @@ static int smbchg_get_prop_batt_charge_counter(struct smbchg_chip *chip) return val.intval; } +static int smbchg_get_prop_batt_current_max(struct smbchg_chip *chip) +{ + int rc; + union power_supply_propval val; + + if (!chip->usb_psy) + return -EINVAL; + + rc = power_supply_get_property(chip->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &val); + if (rc < 0) { + pr_smb(PR_STATUS, "Couldn't get current max rc = %d\n", rc); + return rc; + } + + return val.intval; +} + static void update_typec_capability_status(struct smbchg_chip *chip, const union power_supply_propval *val) { @@ -6118,6 +6136,7 @@ static enum power_supply_property smbchg_battery_properties[] = { POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_VOLTAGE_NOW, @@ -6283,6 +6302,9 @@ static int smbchg_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX: val->intval = smbchg_float_voltage_get(chip); break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + val->intval = smbchg_get_prop_batt_current_max(chip); + break; case POWER_SUPPLY_PROP_HEALTH: val->intval = get_prop_batt_health(chip); break; From 81d2bd866dc1f9f5e9c9495a3b0a4a005f6b64a9 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Tue, 5 Sep 2017 15:04:20 +0530 Subject: [PATCH 20/86] msm: camera: isp: Check null pointer for VFE0 base Add NULL pointer check for vfe_base of VFE0. CRs-Fixed: 1032715 Change-Id: I540d9ff831fc9447ecf145f75ea84da3668c4f6f Signed-off-by: Haibin Liu Signed-off-by: VijayaKumar T M --- drivers/media/platform/msm/camera_v2/isp/msm_isp40.c | 6 ++++++ drivers/media/platform/msm/camera_v2/isp/msm_isp44.c | 8 +++++++- drivers/media/platform/msm/camera_v2/isp/msm_isp46.c | 8 +++++++- drivers/media/platform/msm/camera_v2/isp/msm_isp47.c | 6 ++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 8a0854487d38..299c576fb5bc 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -717,6 +717,12 @@ static void msm_vfe40_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { + if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { + pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); + spin_unlock_irqrestore(&vfe_dev->reg_update_lock, + flags); + return; + } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + 0x378); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c index 4eb088403717..090a5a6584ef 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -558,6 +558,12 @@ static void msm_vfe44_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { + if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { + pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); + spin_unlock_irqrestore(&vfe_dev->reg_update_lock, + flags); + return; + } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + 0x378); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c index 1c1df3f629f6..eae645b93bef 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -498,6 +498,12 @@ static void msm_vfe46_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { + if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { + pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); + spin_unlock_irqrestore(&vfe_dev->reg_update_lock, + flags); + return; + } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + 0x3D8); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index d7b4e1ec1303..7bb003b66def 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -714,6 +714,12 @@ void msm_vfe47_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { + if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { + pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); + spin_unlock_irqrestore(&vfe_dev->reg_update_lock, + flags); + return; + } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res-> vfe_base[ISP_VFE0] + 0x4AC); From 82adad07637a73424407b8cee0c21c99c2c07178 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Wed, 6 Sep 2017 11:03:04 +0530 Subject: [PATCH 21/86] defconfig: Enable and disable few configs for msm8909/20/30/37/53/96 This change enables and disables below list of configs to address the VTS KernelConfig test case failures. Enable configs: CONFIG_QUOTA_NETLINK_INTERFACE CONFIG_QFMT_V2 CONFIG_SECURITY_PERF_EVENTS_RESTRICT Disable configs in perf defconfig: CONFIG_USELIB CONFIG_DEVKMEM CONFIG_DEVMEM CRs-Fixed: 2104095 Change-Id: Ieb07c9319ec4538ff71257168f6aba18ab01dd4f Signed-off-by: Swetha Chikkaboraiah --- arch/arm/configs/msm8909-perf_defconfig | 6 ++++++ arch/arm/configs/msm8909_defconfig | 6 ++++++ arch/arm/configs/msm8937-perf_defconfig | 6 ++++++ arch/arm/configs/msm8937_defconfig | 6 ++++++ arch/arm/configs/msmcortex-perf_defconfig | 4 ++++ arch/arm/configs/msmcortex_defconfig | 6 ++++++ arch/arm64/configs/msm-perf_defconfig | 2 ++ arch/arm64/configs/msm8937-perf_defconfig | 6 ++++++ arch/arm64/configs/msm8937_defconfig | 6 ++++++ arch/arm64/configs/msm_defconfig | 2 ++ arch/arm64/configs/msmcortex-perf_defconfig | 4 ++++ arch/arm64/configs/msmcortex_defconfig | 6 ++++++ 12 files changed, 60 insertions(+) diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig index 5580fac604aa..04a4c6791928 100644 --- a/arch/arm/configs/msm8909-perf_defconfig +++ b/arch/arm/configs/msm8909-perf_defconfig @@ -1,5 +1,6 @@ CONFIG_EARLY_IOREMAP=y CONFIG_LOCALVERSION="-perf" +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -291,6 +292,8 @@ CONFIG_SENSORS_AKM8963=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=m # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y @@ -490,7 +493,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y @@ -510,6 +515,7 @@ CONFIG_SCHED_STACK_END_CHECK=y CONFIG_TIMER_STATS=y CONFIG_IPC_LOGGING=y CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig index 51b420d90d44..a0fcbbf09325 100644 --- a/arch/arm/configs/msm8909_defconfig +++ b/arch/arm/configs/msm8909_defconfig @@ -1,4 +1,5 @@ CONFIG_EARLY_IOREMAP=y +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -297,6 +298,8 @@ CONFIG_SENSORS_AKM8963=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=m # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y @@ -507,7 +510,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y @@ -552,6 +557,7 @@ CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_DEBUG_USER=y CONFIG_FREE_PAGES_RDONLY=y CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 860adf42cff6..5007cd91c653 100644 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -1,5 +1,6 @@ CONFIG_EARLY_IOREMAP=y CONFIG_LOCALVERSION="-perf" +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -322,6 +323,8 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y @@ -597,7 +600,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -618,6 +623,7 @@ CONFIG_TIMER_STATS=y CONFIG_IPC_LOGGING=y CONFIG_CPU_FREQ_SWITCH_PROFILER=y CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index cf0075d24c64..c15165ce13f6 100644 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -1,4 +1,5 @@ CONFIG_EARLY_IOREMAP=y +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -323,6 +324,8 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y @@ -613,7 +616,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -667,6 +672,7 @@ CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_DEBUG_USER=y CONFIG_FREE_PAGES_RDONLY=y CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/msmcortex-perf_defconfig b/arch/arm/configs/msmcortex-perf_defconfig index c495f39841d1..e0a82c8be586 100644 --- a/arch/arm/configs/msmcortex-perf_defconfig +++ b/arch/arm/configs/msmcortex-perf_defconfig @@ -1,5 +1,6 @@ CONFIG_EARLY_IOREMAP=y CONFIG_LOCALVERSION="-perf" +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -586,7 +587,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -607,6 +610,7 @@ CONFIG_TIMER_STATS=y CONFIG_IPC_LOGGING=y CONFIG_CPU_FREQ_SWITCH_PROFILER=y CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index 442a999dfd13..38023fcaa0de 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -1,4 +1,5 @@ CONFIG_EARLY_IOREMAP=y +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -306,6 +307,8 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=m # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y @@ -595,7 +598,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y @@ -640,6 +645,7 @@ CONFIG_CPU_FREQ_SWITCH_PROFILER=y CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_DEBUG_USER=y CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig index 1e0df185e3b0..132ac7640db9 100644 --- a/arch/arm64/configs/msm-perf_defconfig +++ b/arch/arm64/configs/msm-perf_defconfig @@ -1,4 +1,5 @@ CONFIG_LOCALVERSION="-perf" +# CONFIG_USELIB is not set CONFIG_AUDIT=y # CONFIG_AUDITSYSCALL is not set CONFIG_NO_HZ=y @@ -622,6 +623,7 @@ CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_DEBUG_RODATA=y CONFIG_DEBUG_ALIGN_RODATA=y CONFIG_PFK=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y diff --git a/arch/arm64/configs/msm8937-perf_defconfig b/arch/arm64/configs/msm8937-perf_defconfig index de324e558210..8b8d1b2810ea 100644 --- a/arch/arm64/configs/msm8937-perf_defconfig +++ b/arch/arm64/configs/msm8937-perf_defconfig @@ -1,4 +1,5 @@ CONFIG_LOCALVERSION="-perf" +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -318,6 +319,8 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y @@ -605,7 +608,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -627,6 +632,7 @@ CONFIG_IPC_LOGGING=y CONFIG_CPU_FREQ_SWITCH_PROFILER=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_DEBUG_RODATA=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/msm8937_defconfig b/arch/arm64/configs/msm8937_defconfig index 843f345ea619..8da238759a4b 100644 --- a/arch/arm64/configs/msm8937_defconfig +++ b/arch/arm64/configs/msm8937_defconfig @@ -1,3 +1,4 @@ +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -317,6 +318,8 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y @@ -620,7 +623,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -675,6 +680,7 @@ CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_FREE_PAGES_RDONLY=y CONFIG_DEBUG_RODATA=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig index d8b890c1a15b..c07b2f978c3f 100644 --- a/arch/arm64/configs/msm_defconfig +++ b/arch/arm64/configs/msm_defconfig @@ -1,3 +1,4 @@ +# CONFIG_USELIB is not set CONFIG_AUDIT=y # CONFIG_AUDITSYSCALL is not set CONFIG_NO_HZ=y @@ -677,6 +678,7 @@ CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_FREE_PAGES_RDONLY=y CONFIG_DEBUG_RODATA=y CONFIG_PFK=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index f151e7d171b3..49d3fbbd5bdd 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -1,4 +1,5 @@ CONFIG_LOCALVERSION="-perf" +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -589,7 +590,9 @@ CONFIG_MSM_TZ_LOG=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y @@ -610,6 +613,7 @@ CONFIG_IPC_LOGGING=y CONFIG_CPU_FREQ_SWITCH_PROFILER=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_DEBUG_RODATA=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 001e387ba444..137fb7b3cbc8 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -1,3 +1,4 @@ +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -310,6 +311,8 @@ CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MSM_HS=y CONFIG_SERIAL_MSM_HSL=y CONFIG_SERIAL_MSM_HSL_CONSOLE=y @@ -625,7 +628,9 @@ CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -675,6 +680,7 @@ CONFIG_PANIC_ON_DATA_CORRUPTION=y CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_FREE_PAGES_RDONLY=y CONFIG_DEBUG_RODATA=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 From 877a5e9a246986beec1d4608286cf322ea9b1c6f Mon Sep 17 00:00:00 2001 From: Avaneesh Kumar Dwivedi Date: Tue, 5 Sep 2017 17:43:35 +0530 Subject: [PATCH 22/86] soc: qcom: Reorganize PIL code for reclaiming MSS mem during SSR This change ask hypervisor to remove memory mapping for MSS from IOMMU second stage table and assign the ownership back to HLOS just after MBA is booted. Presently this is being done only after MBA is booted and MDT is authenticated. Change-Id: I724c1bcc664827e666612dd34cd078f3f044498a Signed-off-by: Avaneesh Kumar Dwivedi --- drivers/soc/qcom/peripheral-loader.c | 15 +++------------ drivers/soc/qcom/peripheral-loader.h | 2 +- drivers/soc/qcom/pil-msa.c | 21 ++++++++++++++++++--- drivers/soc/qcom/subsys-pil-bg.c | 3 ++- drivers/soc/qcom/subsys-pil-tz.c | 3 ++- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c index d17d2e8d231b..8c4d140b4050 100644 --- a/drivers/soc/qcom/peripheral-loader.c +++ b/drivers/soc/qcom/peripheral-loader.c @@ -831,7 +831,9 @@ int pil_boot(struct pil_desc *desc) } if (desc->ops->init_image) - ret = desc->ops->init_image(desc, fw->data, fw->size); + ret = desc->ops->init_image(desc, fw->data, fw->size, + priv->region_start, + priv->region_end - priv->region_start); if (ret) { pil_err(desc, "Invalid firmware metadata\n"); subsys_set_error(desc->subsys_dev, firmware_error_msg); @@ -847,17 +849,6 @@ int pil_boot(struct pil_desc *desc) } if (desc->subsys_vmid > 0) { - /* In case of modem ssr, we need to assign memory back to linux. - * This is not true after cold boot since linux already owns it. - * Also for secure boot devices, modem memory has to be released - * after MBA is booted. */ - if (desc->modem_ssr) { - ret = pil_assign_mem_to_linux(desc, priv->region_start, - (priv->region_end - priv->region_start)); - if (ret) - pil_err(desc, "Failed to assign to linux, ret- %d\n", - ret); - } ret = pil_assign_mem_to_subsys_and_linux(desc, priv->region_start, (priv->region_end - priv->region_start)); diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h index 40aff8ce7e8c..fdc21342e64e 100644 --- a/drivers/soc/qcom/peripheral-loader.h +++ b/drivers/soc/qcom/peripheral-loader.h @@ -88,7 +88,7 @@ struct pil_image_info { */ struct pil_reset_ops { int (*init_image)(struct pil_desc *pil, const u8 *metadata, - size_t size); + size_t size, phys_addr_t addr, size_t sz); int (*mem_setup)(struct pil_desc *pil, phys_addr_t addr, size_t size); int (*verify_blob)(struct pil_desc *pil, phys_addr_t phy_addr, size_t size); diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c index a61ecc14dc2d..cb5de40ed004 100644 --- a/drivers/soc/qcom/pil-msa.c +++ b/drivers/soc/qcom/pil-msa.c @@ -651,7 +651,7 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) } static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, - size_t size) + size_t size, phys_addr_t phy_addr, size_t phy_sz) { struct modem_data *drv = dev_get_drvdata(pil->dev); void *mdata_virt; @@ -680,6 +680,19 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, wmb(); if (pil->subsys_vmid > 0) { + /** + * In case of modem ssr, we need to assign memory back to linux. + * This is not true after cold boot since linux already owns + * it. Also for secure boot devices, modem memory has to be + * released after MBA is booted + */ + if (pil->modem_ssr) { + ret = pil_assign_mem_to_linux(pil, phy_addr, phy_sz); + if (ret) + dev_err(pil->dev, + "Failed to assign to linux, ret- %d\n", + ret); + } ret = pil_assign_mem_to_subsys(pil, mdata_phys, ALIGN(size, SZ_4K)); if (ret) { @@ -732,7 +745,8 @@ static int pil_msa_auth_modem_mdt(struct pil_desc *pil, const u8 *metadata, } static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil, - const u8 *metadata, size_t size) + const u8 *metadata, size_t size, + phys_addr_t modem_reg, size_t sz_modem_reg) { int ret; @@ -740,7 +754,8 @@ static int pil_msa_mss_reset_mba_load_auth_mdt(struct pil_desc *pil, if (ret) return ret; - return pil_msa_auth_modem_mdt(pil, metadata, size); + return pil_msa_auth_modem_mdt(pil, metadata, size, + modem_reg, sz_modem_reg); } static int pil_msa_mba_verify_blob(struct pil_desc *pil, phys_addr_t phy_addr, diff --git a/drivers/soc/qcom/subsys-pil-bg.c b/drivers/soc/qcom/subsys-pil-bg.c index 8816c47ef146..64b2e62339df 100644 --- a/drivers/soc/qcom/subsys-pil-bg.c +++ b/drivers/soc/qcom/subsys-pil-bg.c @@ -303,7 +303,8 @@ static int bg_shutdown(const struct subsys_desc *subsys, bool force_stop) * Return: 0 on success. Error code on failure. */ static int bg_auth_metadata(struct pil_desc *pil, - const u8 *metadata, size_t size) + const u8 *metadata, size_t size, + phys_addr_t addr, size_t sz) { struct pil_bg_data *bg_data = desc_to_data(pil); struct tzapp_bg_req bg_tz_req; diff --git a/drivers/soc/qcom/subsys-pil-tz.c b/drivers/soc/qcom/subsys-pil-tz.c index c8d615049487..9c82f7a010de 100644 --- a/drivers/soc/qcom/subsys-pil-tz.c +++ b/drivers/soc/qcom/subsys-pil-tz.c @@ -582,7 +582,8 @@ static void pil_remove_proxy_vote(struct pil_desc *pil) } static int pil_init_image_trusted(struct pil_desc *pil, - const u8 *metadata, size_t size) + const u8 *metadata, size_t size, + phys_addr_t addr, size_t sz) { struct pil_tz_data *d = desc_to_data(pil); struct pas_init_image_req { From ef29177c0f1ff0cc04d123720e5ed27220fe3369 Mon Sep 17 00:00:00 2001 From: Puja Gupta Date: Thu, 2 Feb 2017 13:41:04 -0800 Subject: [PATCH 23/86] soc: qcom: pil: Fix error case scenario in subsystem ramdump During ramdump collection we assign memory to HLOS from subsystem for non-secure pil. Whether ramdump collection is successful or not, we should assign memory back to subsystem. This is to avoid access violations in powerup path which happens after ramdump. CRs-Fixed: 2002073 Change-Id: I7f1d42aebb44464fe077ca544ce91c2d7a8eefbb Signed-off-by: Puja Gupta --- drivers/soc/qcom/peripheral-loader.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c index 8c4d140b4050..d0fdce05adc5 100644 --- a/drivers/soc/qcom/peripheral-loader.c +++ b/drivers/soc/qcom/peripheral-loader.c @@ -172,7 +172,11 @@ int pil_do_ramdump(struct pil_desc *desc, void *ramdump_dev) ret = do_elf_ramdump(ramdump_dev, ramdump_segs, count); kfree(ramdump_segs); - if (!ret && desc->subsys_vmid > 0) + if (ret) + pil_err(desc, "%s: Ramdump collection failed for subsys %s rc:%d\n", + __func__, desc->name, ret); + + if (desc->subsys_vmid > 0) ret = pil_assign_mem_to_subsys(desc, priv->region_start, (priv->region_end - priv->region_start)); From 3e9d36e9e188fa4f52c83cc13d6edf88f56eb4b8 Mon Sep 17 00:00:00 2001 From: Kyle Yan Date: Thu, 11 May 2017 11:15:31 -0700 Subject: [PATCH 24/86] soc: qcom: pil: Align size of MBA and DP image to 4k Image address and size must be aligned to 4k as the SMMU works on a 4k granularity. Change-Id: I4780aa67f09796ec0a8dd5b62da0e9a99c50e596 Signed-off-by: Kyle Yan --- drivers/soc/qcom/pil-msa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c index cb5de40ed004..aea264a8ecae 100644 --- a/drivers/soc/qcom/pil-msa.c +++ b/drivers/soc/qcom/pil-msa.c @@ -571,6 +571,7 @@ int pil_mss_reset_load_mba(struct pil_desc *pil) } drv->dp_size = dp_fw->size; drv->mba_dp_size += drv->dp_size; + drv->mba_dp_size = ALIGN(drv->mba_dp_size, SZ_4K); } mba_dp_virt = dma_alloc_attrs(dma_dev, drv->mba_dp_size, &mba_dp_phys, From 1c1feff8ad664232d48367609e85722a4e0d1689 Mon Sep 17 00:00:00 2001 From: raghavendra ambadas Date: Thu, 31 Aug 2017 16:37:34 +0530 Subject: [PATCH 25/86] Revert "Revert "msm: mdss: enable pll regulator during phy on sequence"" This reverts commit 0a4917a2b6aca2f87dbf1b4a770ffb688bd0924e. This change is causing corruption issue on msm8996 dual dsi cmd mode panel. Change-Id: Iba316b22c7cc211c384f5b5204e0b6f11d169d8a Signed-off-by: Raghavendra Ambadas --- drivers/video/msm/mdss/msm_mdss_io_8974.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c index 8a1b72d79335..4a43949e634f 100644 --- a/drivers/video/msm/mdss/msm_mdss_io_8974.c +++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c @@ -899,8 +899,11 @@ static void mdss_dsi_8996_phy_power_off( { int ln; void __iomem *base; + u32 data; - MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, 0x7f); + /* Turn off PLL power */ + data = MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0); + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, data & ~BIT(7)); /* 4 lanes + clk lane configuration */ for (ln = 0; ln < 5; ln++) { @@ -956,6 +959,7 @@ static void mdss_dsi_8996_phy_power_on( void __iomem *base; struct mdss_dsi_phy_ctrl *pd; char *ip; + u32 data; pd = &(((ctrl->panel_data).panel_info.mipi).dsi_phy_db); @@ -975,6 +979,10 @@ static void mdss_dsi_8996_phy_power_on( } mdss_dsi_8996_phy_regulator_enable(ctrl); + + /* Turn on PLL power */ + data = MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0); + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, data | BIT(7)); } static void mdss_dsi_phy_power_on( @@ -1078,6 +1086,7 @@ static void mdss_dsi_8996_phy_config(struct mdss_dsi_ctrl_pdata *ctrl) mdss_dsi_8996_pll_source_standalone(ctrl); } + MIPI_OUTP(ctrl->phy_io.base + DSIPHY_CMN_CTRL_0, 0x7f); wmb(); /* make sure registers committed */ } From c1c08ed4406a069309983f50b9f0612e73ee9602 Mon Sep 17 00:00:00 2001 From: Aravind Venkateswaran Date: Tue, 12 Apr 2016 18:20:10 -0700 Subject: [PATCH 26/86] msm: mdss: modify DSI phy init sequence for split-DSI config For split-DSI hardware configuration, both the DSI controller clocks are sourced from a single PLL (clock-master). In such cases, it is important to initialize both DSI0 PHY and DSI1 PHY prior to enabling the PLL. This is due to the fact that for certain HW versions, PLL programming for the clock-master may require configure some PLL registers on the clock-slave. If the PHY init sequence for the clock-slave is called after PLL is programmed, it could reset those PLL registers leading to unexpected behavior. Fix this by ensuring that PHY init sequence is done for both controllers at the same time for split display usecases. CRs-Fixed: 1000724 Change-Id: I09fb8097d31cd0390cea5c32bb7aabceeff2c37e Signed-off-by: Aravind Venkateswaran Signed-off-by: Ashish Garg --- drivers/video/msm/mdss/msm_mdss_io_8974.c | 60 ++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/msm_mdss_io_8974.c b/drivers/video/msm/mdss/msm_mdss_io_8974.c index 4a43949e634f..fcc8545a12ed 100644 --- a/drivers/video/msm/mdss/msm_mdss_io_8974.c +++ b/drivers/video/msm/mdss/msm_mdss_io_8974.c @@ -443,7 +443,7 @@ int mdss_dsi_phy_pll_reset_status(struct mdss_dsi_ctrl_pdata *ctrl) return rc; } -void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl) +static void mdss_dsi_phy_sw_reset_sub(struct mdss_dsi_ctrl_pdata *ctrl) { struct mdss_dsi_ctrl_pdata *sctrl = NULL; struct dsi_shared_data *sdata; @@ -500,7 +500,39 @@ void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl) } mutex_unlock(&sdata->phy_reg_lock); +} + +void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl) +{ + struct mdss_dsi_ctrl_pdata *sctrl = NULL; + struct dsi_shared_data *sdata; + + if (ctrl == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return; + } + + sdata = ctrl->shared_data; + + /* + * When operating in split display mode, make sure that the PHY reset + * is only done from the clock master. This will ensure that the PLL is + * off when PHY reset is called. + */ + if (mdss_dsi_is_ctrl_clk_slave(ctrl)) + return; + + mdss_dsi_phy_sw_reset_sub(ctrl); + if (mdss_dsi_is_ctrl_clk_master(ctrl)) { + sctrl = mdss_dsi_get_ctrl_clk_slave(); + if (sctrl) + mdss_dsi_phy_sw_reset_sub(sctrl); + else + pr_warn("%s: unable to get slave ctrl\n", __func__); + } + + /* All other quirks go here */ if ((sdata->hw_rev == MDSS_DSI_HW_REV_103) && !mdss_dsi_is_hw_config_dual(sdata) && mdss_dsi_is_right_ctrl(ctrl)) { @@ -1202,12 +1234,36 @@ void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl) wmb(); } -void mdss_dsi_phy_init(struct mdss_dsi_ctrl_pdata *ctrl) +static void mdss_dsi_phy_init_sub(struct mdss_dsi_ctrl_pdata *ctrl) { mdss_dsi_phy_regulator_ctrl(ctrl, true); mdss_dsi_phy_ctrl(ctrl, true); } +void mdss_dsi_phy_init(struct mdss_dsi_ctrl_pdata *ctrl) +{ + struct mdss_dsi_ctrl_pdata *sctrl = NULL; + + /* + * When operating in split display mode, make sure that both the PHY + * blocks are initialized together prior to the PLL being enabled. This + * is achieved by calling the phy_init function for the clk_slave from + * the clock_master. + */ + if (mdss_dsi_is_ctrl_clk_slave(ctrl)) + return; + + mdss_dsi_phy_init_sub(ctrl); + + if (mdss_dsi_is_ctrl_clk_master(ctrl)) { + sctrl = mdss_dsi_get_ctrl_clk_slave(); + if (sctrl) + mdss_dsi_phy_init_sub(sctrl); + else + pr_warn("%s: unable to get slave ctrl\n", __func__); + } +} + void mdss_dsi_core_clk_deinit(struct device *dev, struct dsi_shared_data *sdata) { if (sdata->mmss_misc_ahb_clk) From 8bee216cbbd8c3c8ec253f8b7a37f5ca59a88fef Mon Sep 17 00:00:00 2001 From: Divya Narayanan Poojary Date: Fri, 8 Sep 2017 18:46:36 +0530 Subject: [PATCH 27/86] wsa881x-analog: Increment probing counter when presence fails Probing counter is not incremented when wsa presence check fails. This is blocking probe call of machine driver Increment the counter even when presence check fails Change-Id: Ie9a23cffa0b8d888a3260914ec37e9ba25135ce0 Signed-off-by: Divya Narayanan Poojary --- arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi | 8 ++++++++ sound/soc/codecs/wsa881x-analog.c | 1 + 2 files changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi index c181a81d7741..f8c71d4422ed 100644 --- a/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi @@ -31,6 +31,14 @@ status = "okay"; }; +&wsa881x_i2c_e { + status = "okay"; +}; + +&wsa881x_i2c_44 { + status = "okay"; +}; + &wsa881x_i2c_f { status = "okay"; }; diff --git a/sound/soc/codecs/wsa881x-analog.c b/sound/soc/codecs/wsa881x-analog.c index ba26579d71d5..ab58e43a7773 100644 --- a/sound/soc/codecs/wsa881x-analog.c +++ b/sound/soc/codecs/wsa881x-analog.c @@ -1342,6 +1342,7 @@ static int wsa881x_i2c_probe(struct i2c_client *client, dev_err(&client->dev, "failed to ping wsa with addr:%x, ret = %d\n", client->addr, ret); + wsa881x_probing_count++; goto err1; } pdata->version = wsa881x_i2c_read_device(pdata, From a3d5aff730b9df0f3e71c12385f550652b4ac5c6 Mon Sep 17 00:00:00 2001 From: Mohan Pallaka Date: Mon, 8 May 2017 11:51:41 -0700 Subject: [PATCH 28/86] input: synaptics_dsx: fix mutex init Initialize mutex before using in irq handler. CRs-fixed: 2047720 Change-Id: I5ebfbc22f2a64dde239fcbb13eb26be50543b484 Signed-off-by: Mohan Pallaka --- .../touchscreen/synaptics_dsx/synaptics_dsx_core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c index 21b14c3ddac7..e7b3571a44a7 100644 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c +++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c @@ -5,7 +5,7 @@ * * Copyright (C) 2012 Alexandra Chin * Copyright (C) 2012 Scott Lin - * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * 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 @@ -3704,6 +3704,12 @@ static int synaptics_rmi4_probe(struct platform_device *pdev) rmi4_data->irq = gpio_to_irq(bdata->irq_gpio); + if (!exp_data.initialized) { + mutex_init(&exp_data.mutex); + INIT_LIST_HEAD(&exp_data.list); + exp_data.initialized = true; + } + retval = synaptics_rmi4_irq_enable(rmi4_data, true); if (retval < 0) { dev_err(&pdev->dev, @@ -3712,12 +3718,6 @@ static int synaptics_rmi4_probe(struct platform_device *pdev) goto err_enable_irq; } - if (!exp_data.initialized) { - mutex_init(&exp_data.mutex); - INIT_LIST_HEAD(&exp_data.list); - exp_data.initialized = true; - } - exp_data.workqueue = create_singlethread_workqueue("dsx_exp_workqueue"); INIT_DELAYED_WORK(&exp_data.work, synaptics_rmi4_exp_fn_work); exp_data.rmi4_data = rmi4_data; From 2c5e8634eb04d9ba3d6ac06023ff2f0c73aacc47 Mon Sep 17 00:00:00 2001 From: Xu YiPing Date: Tue, 5 Sep 2017 10:21:52 -0700 Subject: [PATCH 29/86] FROMLIST: binder: fix memory corruption in binder_transaction binder (from https://patchwork.kernel.org/patch/9939405/) commit 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe") made a change to enqueue tcomplete to thread->todo before enqueuing the transaction. However, in err_dead_proc_or_thread case, the tcomplete is directly freed, without dequeued. It may cause the thread->todo list to be corrupted. So, dequeue it before freeing. Bug: 65333488 Change-Id: I14ef48095d9f690148b1a50ea62d05dd67779505 Signed-off-by: Xu YiPing Signed-off-by: Todd Kjos Git-commit: 86578a0fd70edffb11c78b5df85b8e113e44bfe1 Git-repo: https://android.googlesource.com/kernel/common Signed-off-by: Kyle Yan Signed-off-by: Srinivasarao P --- drivers/staging/android/binder.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 9d2b48c8e847..d7c963fdc583 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -3250,6 +3250,7 @@ static void binder_transaction(struct binder_proc *proc, err_dead_proc_or_thread: return_error = BR_DEAD_REPLY; return_error_line = __LINE__; + binder_dequeue_work(proc, tcomplete); err_translate_failed: err_bad_object_type: err_bad_offset: From 4c99ac1c0f15eca008eb0ffc5c325f8d4e4a9b51 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Mon, 28 Aug 2017 13:19:13 +0530 Subject: [PATCH 30/86] defconfig: msm: Disable DEVPORT config for msm8953_64 Disable CONFIG_DEVPORT config for msm8953_64 As selinux policy requires this node to be not accessible to userspace. CRs-Fixed: 2077590 Change-Id: I187626de63d36f4f1e102ae5f417c601f6cadd72 Signed-off-by: Mohammed Khajapasha Signed-off-by: Chetan C R --- arch/arm64/configs/msmcortex-perf_defconfig | 1 + arch/arm64/configs/msmcortex_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 49d3fbbd5bdd..6d2181a2cf62 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -318,6 +318,7 @@ CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_MSM_RDBG=m diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index ff676ac1abe9..387d9795d329 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -320,6 +320,7 @@ CONFIG_SERIAL_MSM_SMD=y CONFIG_DIAG_CHAR=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_DEVPORT is not set CONFIG_MSM_SMD_PKT=y CONFIG_MSM_ADSPRPC=y CONFIG_MSM_RDBG=m From 2dd6fc3577cc01162a329d8298bc156370bf371e Mon Sep 17 00:00:00 2001 From: Anoob Soman Date: Wed, 15 Feb 2017 20:25:39 +0000 Subject: [PATCH 31/86] packet: Do not call fanout_release from atomic contexts [ Upstream commit 2bd624b4611ffee36422782d16e1c944d1351e98 ] Commit 6664498280cf ("packet: call fanout_release, while UNREGISTERING a netdev"), unfortunately, introduced the following issues. 1. calling mutex_lock(&fanout_mutex) (fanout_release()) from inside rcu_read-side critical section. rcu_read_lock disables preemption, most often, which prohibits calling sleeping functions. [ ] include/linux/rcupdate.h:560 Illegal context switch in RCU read-side critical section! [ ] [ ] rcu_scheduler_active = 1, debug_locks = 0 [ ] 4 locks held by ovs-vswitchd/1969: [ ] #0: (cb_lock){++++++}, at: [] genl_rcv+0x19/0x40 [ ] #1: (ovs_mutex){+.+.+.}, at: [] ovs_vport_cmd_del+0x4a/0x100 [openvswitch] [ ] #2: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x17/0x20 [ ] #3: (rcu_read_lock){......}, at: [] packet_notifier+0x5/0x3f0 [ ] [ ] Call Trace: [ ] [] dump_stack+0x85/0xc4 [ ] [] lockdep_rcu_suspicious+0x107/0x110 [ ] [] ___might_sleep+0x57/0x210 [ ] [] __might_sleep+0x70/0x90 [ ] [] mutex_lock_nested+0x3c/0x3a0 [ ] [] ? vprintk_default+0x1f/0x30 [ ] [] ? printk+0x4d/0x4f [ ] [] fanout_release+0x1d/0xe0 [ ] [] packet_notifier+0x2f9/0x3f0 2. calling mutex_lock(&fanout_mutex) inside spin_lock(&po->bind_lock). "sleeping function called from invalid context" [ ] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:620 [ ] in_atomic(): 1, irqs_disabled(): 0, pid: 1969, name: ovs-vswitchd [ ] INFO: lockdep is turned off. [ ] Call Trace: [ ] [] dump_stack+0x85/0xc4 [ ] [] ___might_sleep+0x202/0x210 [ ] [] __might_sleep+0x70/0x90 [ ] [] mutex_lock_nested+0x3c/0x3a0 [ ] [] fanout_release+0x1d/0xe0 [ ] [] packet_notifier+0x2f9/0x3f0 3. calling dev_remove_pack(&fanout->prot_hook), from inside spin_lock(&po->bind_lock) or rcu_read-side critical-section. dev_remove_pack() -> synchronize_net(), which might sleep. [ ] BUG: scheduling while atomic: ovs-vswitchd/1969/0x00000002 [ ] INFO: lockdep is turned off. [ ] Call Trace: [ ] [] dump_stack+0x85/0xc4 [ ] [] __schedule_bug+0x64/0x73 [ ] [] __schedule+0x6b/0xd10 [ ] [] schedule+0x6b/0x80 [ ] [] schedule_timeout+0x38d/0x410 [ ] [] synchronize_sched_expedited+0x53d/0x810 [ ] [] synchronize_rcu_expedited+0xe/0x10 [ ] [] synchronize_net+0x35/0x50 [ ] [] dev_remove_pack+0x13/0x20 [ ] [] fanout_release+0xbe/0xe0 [ ] [] packet_notifier+0x2f9/0x3f0 4. fanout_release() races with calls from different CPU. To fix the above problems, remove the call to fanout_release() under rcu_read_lock(). Instead, call __dev_remove_pack(&fanout->prot_hook) and netdev_run_todo will be happy that &dev->ptype_specific list is empty. In order to achieve this, I moved dev_{add,remove}_pack() out of fanout_{add,release} to __fanout_{link,unlink}. So, call to {,__}unregister_prot_hook() will make sure fanout->prot_hook is removed as well Fixes: 6664498280cf ("packet: call fanout_release, while UNREGISTERING a netdev") Reported-by: Eric Dumazet Signed-off-by: Anoob Soman Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Git-commit: fe41cfb48f2d82577ca5b56909ee251ae52cd172 Git-repo: https://source.codeaurora.org/quic/la/kernel/msm-4.4/commit/ Change-Id: If5c94fcd9ee7fb15fadd50fa05f3a73688be61e8 Signed-off-by: Tejaswi Tanikella --- net/packet/af_packet.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1db48a5760b2..3878c34b531b 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1380,6 +1380,8 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po) f->arr[f->num_members] = sk; smp_wmb(); f->num_members++; + if (f->num_members == 1) + dev_add_pack(&f->prot_hook); spin_unlock(&f->lock); } @@ -1396,6 +1398,8 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) BUG_ON(i >= f->num_members); f->arr[i] = f->arr[f->num_members - 1]; f->num_members--; + if (f->num_members == 0) + __dev_remove_pack(&f->prot_hook); spin_unlock(&f->lock); } @@ -1468,7 +1472,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) match->prot_hook.func = packet_rcv_fanout; match->prot_hook.af_packet_priv = match; match->prot_hook.id_match = match_fanout_group; - dev_add_pack(&match->prot_hook); list_add(&match->list, &fanout_list); } err = -EINVAL; @@ -1489,7 +1492,14 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) return err; } -static void fanout_release(struct sock *sk) +/* If pkt_sk(sk)->fanout->sk_ref is zero, this function removes + * pkt_sk(sk)->fanout from fanout_list and returns pkt_sk(sk)->fanout. + * It is the responsibility of the caller to free the returned packet_fanout + * (after synchronize_net()) + * This Branch still does not have support classic BPF fanout mode. + * upstream commit 47dceb8ecdc: packet: add classic BPF fanout mode + */ +static struct packet_fanout *fanout_release(struct sock *sk) { struct packet_sock *po = pkt_sk(sk); struct packet_fanout *f; @@ -1499,13 +1509,15 @@ static void fanout_release(struct sock *sk) if (f) { po->fanout = NULL; - if (atomic_dec_and_test(&f->sk_ref)) { + if (atomic_dec_and_test(&f->sk_ref)) list_del(&f->list); - dev_remove_pack(&f->prot_hook); - kfree(f); - } + else + f = NULL; + } mutex_unlock(&fanout_mutex); + + return f; } static bool packet_extra_vlan_len_allowed(const struct net_device *dev, @@ -2587,6 +2599,7 @@ static int packet_release(struct socket *sock) { struct sock *sk = sock->sk; struct packet_sock *po; + struct packet_fanout *f; struct net *net; union tpacket_req_u req_u; @@ -2626,9 +2639,13 @@ static int packet_release(struct socket *sock) packet_set_ring(sk, &req_u, 1, 1); } - fanout_release(sk); + f = fanout_release(sk); synchronize_net(); + + if (f) + kfree(f); + /* * Now the socket is dead. No more input will appear. */ @@ -3567,7 +3584,6 @@ static int packet_notifier(struct notifier_block *this, } if (msg == NETDEV_UNREGISTER) { packet_cached_dev_reset(po); - fanout_release(sk); po->ifindex = -1; if (po->prot_hook.dev) dev_put(po->prot_hook.dev); From 98f5a7b812ecc55b9a2a817e179cc5034c8ddfd1 Mon Sep 17 00:00:00 2001 From: Divya Ojha Date: Thu, 25 Aug 2016 15:25:51 +0530 Subject: [PATCH 32/86] ARM: dts: msm: update micbias type for 8937/53/17 CDP 8937/53/17 CDP uses external bias resistor. Hence change micbias type to external. CRs-fixed: 1045680 Change-Id: I7ca26e9b37e5730e8c8b7b1640fb7c55ad2fe532 Signed-off-by: Divya Ojha --- arch/arm/boot/dts/qcom/msm8917-audio-cdp.dtsi | 2 +- arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi | 2 +- arch/arm/boot/dts/qcom/msm8953-audio-cdp.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8917-audio-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8917-audio-cdp.dtsi index a0de690d101c..93a14bb12ad6 100644 --- a/arch/arm/boot/dts/qcom/msm8917-audio-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8917-audio-cdp.dtsi @@ -13,7 +13,7 @@ &int_codec { status = "okay"; - qcom,msm-hs-micbias-type = "internal"; + qcom,msm-hs-micbias-type = "external"; asoc-wsa-codec-names = "wsa881x-i2c-codec.2-000f"; asoc-wsa-codec-prefixes = "SpkrMono"; diff --git a/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi index f8c71d4422ed..be24d3d789fd 100644 --- a/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8937-audio-cdp.dtsi @@ -13,7 +13,7 @@ &int_codec { status = "okay"; - qcom,msm-hs-micbias-type = "internal"; + qcom,msm-hs-micbias-type = "external"; asoc-wsa-codec-names = "wsa881x-i2c-codec.2-000f"; asoc-wsa-codec-prefixes = "SpkrMono"; diff --git a/arch/arm/boot/dts/qcom/msm8953-audio-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8953-audio-cdp.dtsi index 91eb8c6e2bfe..ff4669e4e46f 100644 --- a/arch/arm/boot/dts/qcom/msm8953-audio-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-audio-cdp.dtsi @@ -13,7 +13,7 @@ &int_codec { status = "okay"; - qcom,msm-hs-micbias-type = "internal"; + qcom,msm-hs-micbias-type = "external"; }; &pm8953_diangu_dig { From 54c0877579ffcb7ed10e3b4a2a46e82ba532f444 Mon Sep 17 00:00:00 2001 From: smanag Date: Tue, 19 Sep 2017 11:12:09 +0530 Subject: [PATCH 33/86] ASoC: wsa881x-analog: Handle update of WSA probe count wsa881x_probing_count is checked in machine driver of 8953/37/17 for sound card register to proceed. Machine probe was getting deferred continuously if targets do not have wsa speakers as the wsa probe count was not updated. Change is to update wsa probe count in this case. Change-Id: Ib86f70442daae5066e1a8082b65d377c3de667fb Signed-off-by: smanag --- sound/soc/codecs/wsa881x-analog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa881x-analog.c b/sound/soc/codecs/wsa881x-analog.c index ab58e43a7773..8f9256a9aebc 100644 --- a/sound/soc/codecs/wsa881x-analog.c +++ b/sound/soc/codecs/wsa881x-analog.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1258,8 +1258,10 @@ static int wsa881x_i2c_probe(struct i2c_client *client, if ((client->addr == WSA881X_I2C_SPK0_SLAVE1_ADDR || client->addr == WSA881X_I2C_SPK1_SLAVE1_ADDR) && - (pdata->status == WSA881X_STATUS_PROBING)) + (pdata->status == WSA881X_STATUS_PROBING)) { + wsa881x_probing_count++; return ret; + } if (pdata->status == WSA881X_STATUS_I2C) { dev_dbg(&client->dev, "%s:probe for other slaves\n" From b114d7667a6aebd3ebdc14dfd4c27b40b1d744d6 Mon Sep 17 00:00:00 2001 From: Karthikeyan Periasamy Date: Tue, 11 Oct 2016 12:21:42 -0700 Subject: [PATCH 34/86] msm: vidc: Check ion_handle for errors When ion imports dma buf, it will return negative error number in the case of failure like bad file number or invalid dma buf file. check ion_handle for error numbers. CRs-Fixed: 1071602 Change-Id: I1ea93161b85deb667cbb6f8515ff7c6943da6e3d Signed-off-by: Karthikeyan Periasamy --- drivers/media/platform/msm/vidc/msm_smem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index bb2715654f45..90047a608984 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -475,7 +475,7 @@ bool msm_smem_compare_buffers(void *clt, int fd, void *priv) } handle = ion_import_dma_buf(client->clnt, fd); ret = handle == priv; - handle ? ion_free(client->clnt, handle) : 0; + (!IS_ERR_OR_NULL(handle)) ? ion_free(client->clnt, handle) : 0; return ret; } From cac5c61b73222ac5973ce0cdec72013383caa241 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Thu, 14 Sep 2017 17:52:00 +0530 Subject: [PATCH 35/86] msm: ais: Instead of read_lock use read_lock_irqsave Prevent deadlock between tasklet and delete_stream by stopping irq during delete_stream. Change-Id: Ib6b1cbf35ffa0fccf210103c096e2a4ab70426e4 CRs-Fixed: 2076578 Signed-off-by: Rahul Sharma --- drivers/media/platform/msm/ais/msm.c | 11 ++- .../media/platform/msm/ais/msm_vb2/msm_vb2.c | 83 ++++++++++--------- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/drivers/media/platform/msm/ais/msm.c b/drivers/media/platform/msm/ais/msm.c index f6d6a45c2988..b450cb97901e 100644 --- a/drivers/media/platform/msm/ais/msm.c +++ b/drivers/media/platform/msm/ais/msm.c @@ -292,6 +292,7 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id) return; while (1) { + unsigned long wl_flags; if (try_count > 5) { pr_err("%s : not able to delete stream %d\n", @@ -299,18 +300,20 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id) break; } - write_lock(&session->stream_rwlock); + write_lock_irqsave(&session->stream_rwlock, wl_flags); try_count++; stream = msm_queue_find(&session->stream_q, struct msm_stream, list, __msm_queue_find_stream, &stream_id); if (!stream) { - write_unlock(&session->stream_rwlock); + write_unlock_irqrestore(&session->stream_rwlock, + wl_flags); return; } if (msm_vb2_get_stream_state(stream) != 1) { - write_unlock(&session->stream_rwlock); + write_unlock_irqrestore(&session->stream_rwlock, + wl_flags); continue; } @@ -320,7 +323,7 @@ void msm_delete_stream(unsigned int session_id, unsigned int stream_id) kfree(stream); stream = NULL; spin_unlock_irqrestore(&(session->stream_q.lock), flags); - write_unlock(&session->stream_rwlock); + write_unlock_irqrestore(&session->stream_rwlock, wl_flags); break; } diff --git a/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c index aa2f6969b5d5..f782b98eda82 100644 --- a/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c @@ -46,22 +46,23 @@ int msm_vb2_buf_init(struct vb2_buffer *vb) struct msm_stream *stream; struct msm_session *session; struct msm_vb2_buffer *msm_vb2_buf; + unsigned long rl_flags; session = msm_get_session_from_vb2q(vb->vb2_queue); if (IS_ERR_OR_NULL(session)) return -EINVAL; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s: Couldn't find stream\n", __func__); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } msm_vb2_buf = container_of(vb, struct msm_vb2_buffer, vb2_buf); msm_vb2_buf->in_freeq = 0; - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return 0; } @@ -70,7 +71,7 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb) struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; struct msm_session *session; - unsigned long flags; + unsigned long flags, rl_flags; msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); @@ -83,19 +84,19 @@ static void msm_vb2_buf_queue(struct vb2_buffer *vb) if (IS_ERR_OR_NULL(session)) return; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s:%d] NULL stream", __func__, __LINE__); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return; } spin_lock_irqsave(&stream->stream_lock, flags); list_add_tail(&msm_vb2->list, &stream->queued_list); spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); } static void msm_vb2_buf_finish(struct vb2_buffer *vb) @@ -103,7 +104,7 @@ static void msm_vb2_buf_finish(struct vb2_buffer *vb) struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; struct msm_session *session; - unsigned long flags; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2_entry, *temp; msm_vb2 = container_of(vb, struct msm_vb2_buffer, vb2_buf); @@ -117,12 +118,12 @@ static void msm_vb2_buf_finish(struct vb2_buffer *vb) if (IS_ERR_OR_NULL(session)) return; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream_from_vb2q(vb->vb2_queue); if (!stream) { pr_err("%s:%d] NULL stream", __func__, __LINE__); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return; } @@ -135,7 +136,7 @@ static void msm_vb2_buf_finish(struct vb2_buffer *vb) } } spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); } static void msm_vb2_stop_stream(struct vb2_queue *q) @@ -143,19 +144,19 @@ static void msm_vb2_stop_stream(struct vb2_queue *q) struct msm_vb2_buffer *msm_vb2, *temp; struct msm_stream *stream; struct msm_session *session; - unsigned long flags; + unsigned long flags, rl_flags; struct vb2_buffer *vb2_buf; session = msm_get_session_from_vb2q(q); if (IS_ERR_OR_NULL(session)) return; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream_from_vb2q(q); if (!stream) { pr_err_ratelimited("%s:%d] NULL stream", __func__, __LINE__); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return; } @@ -174,7 +175,7 @@ static void msm_vb2_stop_stream(struct vb2_queue *q) msm_vb2->in_freeq = 0; } spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); } int msm_vb2_get_stream_state(struct msm_stream *stream) @@ -252,17 +253,17 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, struct vb2_buffer *vb2_buf = NULL; struct msm_session *session; struct msm_vb2_buffer *msm_vb2 = NULL; - unsigned long flags; + unsigned long flags, rl_flags; session = msm_get_session(session_id); if (IS_ERR_OR_NULL(session)) return NULL; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream(session, stream_id); if (IS_ERR_OR_NULL(stream)) { - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return NULL; } @@ -288,7 +289,7 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, vb2_buf = NULL; end: spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return vb2_buf; } @@ -299,18 +300,18 @@ static struct vb2_buffer *msm_vb2_get_buf_by_idx(int session_id, struct vb2_buffer *vb2_buf = NULL; struct msm_session *session; struct msm_vb2_buffer *msm_vb2 = NULL; - unsigned long flags; + unsigned long flags, rl_flags; session = msm_get_session(session_id); if (IS_ERR_OR_NULL(session)) return NULL; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream(session, stream_id); if (IS_ERR_OR_NULL(stream)) { - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return NULL; } @@ -334,7 +335,7 @@ static struct vb2_buffer *msm_vb2_get_buf_by_idx(int session_id, vb2_buf = NULL; end: spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return vb2_buf; } @@ -346,17 +347,17 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, struct msm_vb2_buffer *msm_vb2; struct vb2_buffer *vb2_buf = NULL; int rc = 0; - unsigned long flags; + unsigned long flags, rl_flags; session = msm_get_session(session_id); if (IS_ERR_OR_NULL(session)) return -EINVAL; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream(session, stream_id); if (IS_ERR_OR_NULL(stream)) { - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } @@ -371,6 +372,8 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, pr_err("VB buffer is INVALID vb=%pK, ses_id=%d, str_id=%d\n", vb, session_id, stream_id); spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, + rl_flags); return -EINVAL; } msm_vb2 = @@ -386,7 +389,7 @@ static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, rc = -EINVAL; } spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } @@ -394,7 +397,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, unsigned int stream_id, uint32_t sequence, struct timeval *ts, uint32_t reserved) { - unsigned long flags; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; struct vb2_buffer *vb2_buf = NULL; @@ -405,11 +408,11 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, if (IS_ERR_OR_NULL(session)) return -EINVAL; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream(session, stream_id); if (IS_ERR_OR_NULL(stream)) { - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } @@ -424,6 +427,8 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n", session_id, stream_id, vb); spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, + rl_flags); return -EINVAL; } msm_vb2 = @@ -444,7 +449,7 @@ static int msm_vb2_buf_done(struct vb2_buffer *vb, int session_id, rc = -EINVAL; } spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } @@ -455,18 +460,18 @@ long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id, struct vb2_buffer *vb2_buf = NULL; struct msm_session *session; struct msm_vb2_buffer *msm_vb2 = NULL; - unsigned long flags; + unsigned long flags, rl_flags; long rc = -EINVAL; session = msm_get_session(session_id); if (IS_ERR_OR_NULL(session)) return rc; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream(session, stream_id); if (IS_ERR_OR_NULL(stream)) { - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } @@ -494,14 +499,14 @@ long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id, end: spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return rc; } EXPORT_SYMBOL(msm_vb2_return_buf_by_idx); static int msm_vb2_flush_buf(int session_id, unsigned int stream_id) { - unsigned long flags; + unsigned long flags, rl_flags; struct msm_vb2_buffer *msm_vb2; struct msm_stream *stream; struct vb2_buffer *vb2_buf = NULL; @@ -511,11 +516,11 @@ static int msm_vb2_flush_buf(int session_id, unsigned int stream_id) if (IS_ERR_OR_NULL(session)) return -EINVAL; - read_lock(&session->stream_rwlock); + read_lock_irqsave(&session->stream_rwlock, rl_flags); stream = msm_get_stream(session, stream_id); if (IS_ERR_OR_NULL(stream)) { - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return -EINVAL; } @@ -527,7 +532,7 @@ static int msm_vb2_flush_buf(int session_id, unsigned int stream_id) msm_vb2->in_freeq = 0; } spin_unlock_irqrestore(&stream->stream_lock, flags); - read_unlock(&session->stream_rwlock); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); return 0; } From e068d59fdd806be900dbd0ab73b78ce378e2bf4c Mon Sep 17 00:00:00 2001 From: Ray Zhang Date: Thu, 27 Oct 2016 16:15:34 +0800 Subject: [PATCH 36/86] ARM: dts: msm: add a new panel driver to enable display for QVR8998 These are the panel settings for s6e3ha3 amoled panel. As QVR8998 will use this panel for display, so add a new file for it. Snapshot of hw-panel-samsung-s6e3ha3x01-5p7-1440p-dual0-cmd.dtsi as of a805a3e1e791ec0fb931d1f44bd70f3307532ec5 to enable display for QVR8998. Rename the file to dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi and modify these panel settings in this file for QVR8998 display. Squash commit messages: commit a805a3e1e791 ("arm64/dts: angler: Don't blank screen when leaving low persistence mode") commit 0e4484ea2ceb ("dts: Reduce low-persistence brightness to 50%") commit 651c6dd35a1f ("dts: msm: Sets the low-persist pulse to be at cycle start") commit 2fc4b8aa55dd ("Add ioctl for low persistence display mode to MDSS driver.") commit 1b0565b24e19 ("Revert "ARM64: dts: angler: Enable AMOLED ACL function."") commit 3200385cb224 ("ARM64: dts: angler: Reduce delay time in Amoled initial code to save the screen on time.") commit de8be2535af7 ("ARM64: dts: angler: Enable qcom,dynamic-dsi-timing-enable for amoled command mode panel") commit 0cce00b5a108 ("Angler: LCD: enable EOT packet transmission") commit 16cd03800bba ("angler: LCD: enable partial update in dtsi") commit f1f63dfc50c9 ("ARM64: dts: angler: Enable AMOLED ACL function.") commit 900833cdd0c9 ("angler: LCD: send display on commands one time") commit 4afd0a7929f1 ("anlger: LCD: enable lcd esd effect recovery function") commit 7ae89bce8295 ("angler: LCD: amend LCD physical width and height dimension") commit 5eff7f8c1c41 ("angler: LCD: fix tearing at the top part of the screen") commit cb8d1be44bcc ("angler: fix flickers when low battery finally") commit 41e4849b13c7 ("angler-kernel: fix bugs of dts before angler-v4") commit 1bd832f295f5 ("ARM64: dts: angler: add dts configuration for v4 device.") Git-commit: a805a3e1e791ec0fb931d1f44bd70f3307532ec5 Git-repo: https://source.codeaurora.org/quic/la/kernel/msm-3.10/ Change-Id: I91a6cfcc3b78159cea505e388749e1610dadeae6 Signed-off-by: Ray Zhang --- ...anel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi diff --git a/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi new file mode 100644 index 000000000000..7bd844ae6770 --- /dev/null +++ b/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi @@ -0,0 +1,91 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_dual_s6e3ha3_amoled_cmd: qcom,mdss_dsi_s6e3ha3_amoled_wqhd_cmd{ + qcom,mdss-dsi-panel-name = + "Dual s6e3ha3 amoled cmd mode dsi panel"; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <720>; + qcom,mdss-dsi-panel-height = <2560>; + qcom,mdss-dsi-h-front-porch = <100>; + qcom,mdss-dsi-h-back-porch = <100>; + qcom,mdss-dsi-h-pulse-width = <40>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <31>; + qcom,mdss-dsi-v-front-porch = <30>; + qcom,mdss-dsi-v-pulse-width = <8>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-color-order = "rgb_swap_rgb"; + qcom,mdss-dsi-on-command = [05 01 00 00 05 00 02 11 00 + 39 01 00 00 00 00 05 2a 00 00 05 9f + 39 01 00 00 00 00 05 2b 00 00 09 ff + 39 01 00 00 00 00 03 f0 5a 5a + 39 01 00 00 00 00 02 b0 10 + 39 01 00 00 00 00 02 b5 a0 + 39 01 00 00 00 00 02 c4 03 + 39 01 00 00 00 00 0a + f6 42 57 37 00 aa cc d0 00 00 + 39 01 00 00 00 00 02 f9 03 + 39 01 00 00 00 00 14 + c2 00 00 d8 d8 00 80 2b 05 08 + 0e 07 0b 05 0d 0a 15 13 20 1e + 39 01 00 00 78 00 03 f0 a5 a5 + 39 01 00 00 00 00 02 35 00 + 39 01 00 00 00 00 02 53 20 + 39 01 00 00 00 00 02 51 60 + 05 01 00 00 05 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 3c 00 02 28 00 + 05 01 00 00 b4 00 02 10 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; + qcom,mdss-dsi-lane-map = "lane_map_0123"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-tx-eot-append; + qcom,dcs-cmd-by-left; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-wr-mem-start = <0x2c>; + qcom,mdss-dsi-wr-mem-continue = <0x3c>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-panel-timings = + [eb 38 26 00 6a 66 32 3c 2f 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x2c>; + qcom,mdss-dsi-t-clk-pre = <0x1c>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <255>; + qcom,mdss-pan-physical-width-dimension = <68>; + qcom,mdss-pan-physical-height-dimension = <122>; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + }; +}; From 6491bca8fa4f9583dad1ca348505f60d406bfdfa Mon Sep 17 00:00:00 2001 From: Yahui Wang Date: Mon, 12 Dec 2016 15:50:38 +0800 Subject: [PATCH 37/86] msm: mdss: Add low persistence mode support for display Snapshot of low persistence mode changes as of 26cfe58bd94a ("msm: mdss: Add support for low persistence display mode") and a805a3e1e791 ("arm64/dts: angler: Don't blank screen when leaving low persistence mode"), to add low persistence mode support for display. Also, add some changes to optimize the implementation for LP mode and fix crash issue when VR APP is up. CRs-Fixed: 1104888 1108207 Change-Id: I509fb5c87d93e2416882942a226cb9b48bc1d3bf Signed-off-by: Yahui Wang --- .../devicetree/bindings/fb/mdss-dsi-panel.txt | 27 ++++++ ...anel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi | 56 ++++++++++++- drivers/video/msm/mdss/mdss_dsi.h | 2 + drivers/video/msm/mdss/mdss_dsi_panel.c | 63 ++++++++++++++ drivers/video/msm/mdss/mdss_fb.c | 82 ++++++++++++++++++- drivers/video/msm/mdss/mdss_fb.h | 3 +- drivers/video/msm/mdss/mdss_panel.h | 9 ++ 7 files changed, 237 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt index 93512a486f1f..444b4104e774 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt @@ -61,6 +61,30 @@ Required properties: transmitted byte 5, 6: 16 bits length in network byte order byte 7 and beyond: number byte of payload +- qcom,mdss-dsi-lp-mode-on: This is used to enable display low persistence mode. + A byte stream formed by multiple dcs packets base on + qcom dsi controller protocol. + byte 0: dcs data type + byte 1: set to indicate this is an individual packet + (no chain) + byte 2: virtual channel number + byte 3: expect ack from client (dcs read command) + byte 4: wait number of specified ms after dcs command + transmitted + byte 5, 6: 16 bits length in network byte order + byte 7 and beyond: number byte of payload +- qcom,mdss-dsi-lp-mode-off: This is used to disable display low persistence mode. + A byte stream formed by multiple dcs packets base on + qcom dsi controller protocol. + byte 0: dcs data type + byte 1: set to indicate this is an individual packet + (no chain) + byte 2: virtual channel number + byte 3: expect ack from client (dcs read command) + byte 4: wait number of specified ms after dcs command + transmitted + byte 5, 6: 16 bits length in network byte order + byte 7 and beyond: number byte of payload - qcom,mdss-dsi-post-panel-on-command: same as "qcom,mdss-dsi-on-command" except commands are sent after displaying an image. @@ -611,6 +635,9 @@ Example: qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; qcom,mdss-dsi-off-command = [22 01 00 00 00 00 00]; qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-lp-mode-on = [32 01 00 00 00 00 02 00 00 + 29 01 00 00 10 00 02 FF 99]; + qcom,mdss-dsi-lp-mode-off = [22 01 00 00 00 00 00]; qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; qcom,mdss-dsi-pan-enable-dynamic-fps; qcom,mdss-dsi-pan-fps-update = "dfps_suspend_resume_mode"; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi index 7bd844ae6770..6d91e72851ec 100644 --- a/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi +++ b/arch/arm/boot/dts/qcom/dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -57,6 +57,60 @@ 05 01 00 00 b4 00 02 10 00]; qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-lp-mode-on = [39 00 00 00 05 00 03 f0 5a 5a + 39 00 00 00 05 00 03 f1 5a 5a + 39 00 00 00 05 00 03 fc 5a 5a + 39 00 00 00 05 00 02 b0 17 + 39 00 00 00 05 00 02 cb 10 + 39 00 00 00 05 00 02 b0 2d + 39 00 00 00 05 00 02 cb cd + 39 00 00 00 05 00 02 b0 0e + 39 00 00 00 05 00 02 cb 02 + 39 00 00 00 05 00 02 b0 0f + 39 00 00 00 05 00 02 cb 09 + 39 00 00 00 05 00 02 b0 02 + 39 00 00 00 05 00 02 f2 c9 + 39 00 00 00 05 00 02 b0 03 + 39 00 00 00 05 00 02 f2 c0 + 39 00 00 00 05 00 02 b0 03 + 39 00 00 00 05 00 02 f4 aa + 39 00 00 00 05 00 02 b0 08 + 39 00 00 00 05 00 02 b1 30 + 39 00 00 00 05 00 02 b0 09 + 39 00 00 00 05 00 02 b1 0a + 39 00 00 00 05 00 02 b0 0d + 39 00 00 00 05 00 02 b1 10 + 39 00 00 00 05 00 02 b0 00 + 39 00 00 00 05 00 02 f7 03 + 39 00 00 00 05 00 02 fe 30 + 39 01 00 00 05 00 02 fe b0]; + qcom,mdss-dsi-lp-mode-off = [39 00 00 00 05 00 03 f0 5a 5a + 39 00 00 00 05 00 03 f1 5a 5a + 39 00 00 00 05 00 03 fc 5a 5a + 39 00 00 00 05 00 02 b0 2d + 39 00 00 00 05 00 02 cb 4d + 39 00 00 00 05 00 02 b0 17 + 39 00 00 00 05 00 02 cb 04 + 39 00 00 00 05 00 02 b0 0e + 39 00 00 00 05 00 02 cb 06 + 39 00 00 00 05 00 02 b0 0f + 39 00 00 00 05 00 02 cb 05 + 39 00 00 00 05 00 02 b0 02 + 39 00 00 00 05 00 02 f2 b8 + 39 00 00 00 05 00 02 b0 03 + 39 00 00 00 05 00 02 f2 80 + 39 00 00 00 05 00 02 b0 03 + 39 00 00 00 05 00 02 f4 8a + 39 00 00 00 05 00 02 b0 08 + 39 00 00 00 05 00 02 b1 10 + 39 00 00 00 05 00 02 b0 09 + 39 00 00 00 05 00 02 b1 0a + 39 00 00 00 05 00 02 b0 0d + 39 00 00 00 05 00 02 b1 80 + 39 00 00 00 05 00 02 b0 00 + 39 00 00 00 05 00 02 f7 03 + 39 00 00 00 05 00 02 fe 30 + 39 01 00 00 05 00 02 fe b0]; qcom,mdss-dsi-h-sync-pulse = <0>; qcom,mdss-dsi-traffic-mode = "non_burst_sync_event"; qcom,mdss-dsi-lane-map = "lane_map_0123"; diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h index 420e740d0288..d4b3cb3ba17e 100644 --- a/drivers/video/msm/mdss/mdss_dsi.h +++ b/drivers/video/msm/mdss/mdss_dsi.h @@ -470,6 +470,8 @@ struct mdss_dsi_ctrl_pdata { struct dsi_panel_cmds post_dms_on_cmds; struct dsi_panel_cmds post_panel_on_cmds; struct dsi_panel_cmds off_cmds; + struct dsi_panel_cmds lp_on_cmds; + struct dsi_panel_cmds lp_off_cmds; struct dsi_panel_cmds status_cmds; struct dsi_panel_cmds idle_on_cmds; /* for lp mode */ struct dsi_panel_cmds idle_off_cmds; diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c index 0633be15f261..8e4920c7a924 100644 --- a/drivers/video/msm/mdss/mdss_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c @@ -161,6 +161,25 @@ int mdss_dsi_panel_cmd_read(struct mdss_dsi_ctrl_pdata *ctrl, char cmd0, return mdss_dsi_cmdlist_put(ctrl, &cmdreq); } +static void mdss_dsi_panel_apply_settings(struct mdss_dsi_ctrl_pdata *ctrl, + struct dsi_panel_cmds *pcmds) +{ + struct dcs_cmd_req cmdreq; + struct mdss_panel_info *pinfo; + + pinfo = &(ctrl->panel_data.panel_info); + if ((pinfo->dcs_cmd_by_left) && (ctrl->ndx != DSI_CTRL_LEFT)) + return; + + memset(&cmdreq, 0, sizeof(cmdreq)); + cmdreq.cmds = pcmds->cmds; + cmdreq.cmds_cnt = pcmds->cmd_cnt; + cmdreq.flags = CMD_REQ_COMMIT; + cmdreq.rlen = 0; + cmdreq.cb = NULL; + mdss_dsi_cmdlist_put(ctrl, &cmdreq); +} + static void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl, struct dsi_panel_cmds *pcmds, u32 flags) { @@ -665,6 +684,38 @@ static int mdss_dsi_set_col_page_addr(struct mdss_panel_data *pdata, return 0; } +static int mdss_dsi_panel_apply_display_setting(struct mdss_panel_data *pdata, + u32 mode) +{ + struct mdss_dsi_ctrl_pdata *ctrl = NULL; + struct dsi_panel_cmds *lp_on_cmds; + struct dsi_panel_cmds *lp_off_cmds; + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return -EINVAL; + } + + ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + + lp_on_cmds = &ctrl->lp_on_cmds; + lp_off_cmds = &ctrl->lp_off_cmds; + + /* Apply display settings for low-persistence mode */ + if ((mode == MDSS_PANEL_LOW_PERSIST_MODE_ON) && + (lp_on_cmds->cmd_cnt)) + mdss_dsi_panel_apply_settings(ctrl, lp_on_cmds); + else if ((mode == MDSS_PANEL_LOW_PERSIST_MODE_OFF) && + (lp_on_cmds->cmd_cnt)) + mdss_dsi_panel_apply_settings(ctrl, lp_off_cmds); + else + return -EINVAL; + + pr_debug("%s: Persistence mode %d applied\n", __func__, mode); + return 0; +} + static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata, int mode) { @@ -838,6 +889,9 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata) mdss_dsi_panel_on_hdmi(ctrl, pinfo); + /* Ensure low persistence mode is set as before */ + mdss_dsi_panel_apply_display_setting(pdata, pinfo->persist_mode); + end: pr_debug("%s:-\n", __func__); return ret; @@ -2019,6 +2073,12 @@ static int mdss_dsi_parse_panel_features(struct device_node *np, __func__, __LINE__); } + mdss_dsi_parse_dcs_cmds(np, &ctrl->lp_on_cmds, + "qcom,mdss-dsi-lp-mode-on", NULL); + + mdss_dsi_parse_dcs_cmds(np, &ctrl->lp_off_cmds, + "qcom,mdss-dsi-lp-mode-off", NULL); + return 0; } @@ -2807,12 +2867,15 @@ int mdss_dsi_panel_init(struct device_node *node, pinfo->dynamic_switch_pending = false; pinfo->is_lpm_mode = false; pinfo->esd_rdy = false; + pinfo->persist_mode = false; ctrl_pdata->on = mdss_dsi_panel_on; ctrl_pdata->post_panel_on = mdss_dsi_post_panel_on; ctrl_pdata->off = mdss_dsi_panel_off; ctrl_pdata->low_power_config = mdss_dsi_panel_low_power_config; ctrl_pdata->panel_data.set_backlight = mdss_dsi_panel_bl_ctrl; + ctrl_pdata->panel_data.apply_display_setting = + mdss_dsi_panel_apply_display_setting; ctrl_pdata->switch_mode = mdss_dsi_panel_switch_mode; ctrl_pdata->panel_data.get_idle = mdss_dsi_panel_get_idle_mode; return 0; diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index d55bde099f89..deb0887735c6 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -816,6 +816,73 @@ static ssize_t mdss_fb_get_dfps_mode(struct device *dev, return ret; } +static ssize_t mdss_fb_change_persist_mode(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par; + struct mdss_panel_info *pinfo = NULL; + struct mdss_panel_data *pdata; + int ret = 0; + u32 persist_mode; + + if (!mfd || !mfd->panel_info) { + pr_err("%s: Panel info is NULL!\n", __func__); + return len; + } + + pinfo = mfd->panel_info; + + if (kstrtouint(buf, 0, &persist_mode)) { + pr_err("kstrtouint buf error!\n"); + return len; + } + + mutex_lock(&mfd->mdss_sysfs_lock); + if (mdss_panel_is_power_off(mfd->panel_power_state)) { + pinfo->persist_mode = persist_mode; + goto end; + } + + mutex_lock(&mfd->bl_lock); + + pdata = dev_get_platdata(&mfd->pdev->dev); + if ((pdata) && (pdata->apply_display_setting)) + ret = pdata->apply_display_setting(pdata, persist_mode); + + mutex_unlock(&mfd->bl_lock); + + if (!ret) { + pr_debug("%s: Persist mode %d\n", __func__, persist_mode); + pinfo->persist_mode = persist_mode; + } + +end: + mutex_unlock(&mfd->mdss_sysfs_lock); + return len; +} + +static ssize_t mdss_fb_get_persist_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par; + struct mdss_panel_data *pdata; + struct mdss_panel_info *pinfo; + int ret; + + pdata = dev_get_platdata(&mfd->pdev->dev); + if (!pdata) { + pr_err("no panel connected!\n"); + return -EINVAL; + } + pinfo = &pdata->panel_info; + + ret = scnprintf(buf, PAGE_SIZE, "%d\n", pinfo->persist_mode); + + return ret; +} + static DEVICE_ATTR(msm_fb_type, S_IRUGO, mdss_fb_get_type, NULL); static DEVICE_ATTR(msm_fb_split, S_IRUGO | S_IWUSR, mdss_fb_show_split, mdss_fb_store_split); @@ -834,6 +901,8 @@ static DEVICE_ATTR(msm_fb_dfps_mode, S_IRUGO | S_IWUSR, mdss_fb_get_dfps_mode, mdss_fb_change_dfps_mode); static DEVICE_ATTR(measured_fps, S_IRUGO | S_IWUSR | S_IWGRP, mdss_fb_get_fps_info, NULL); +static DEVICE_ATTR(msm_fb_persist_mode, S_IRUGO | S_IWUSR, + mdss_fb_get_persist_mode, mdss_fb_change_persist_mode); static struct attribute *mdss_fb_attrs[] = { &dev_attr_msm_fb_type.attr, &dev_attr_msm_fb_split.attr, @@ -846,6 +915,7 @@ static struct attribute *mdss_fb_attrs[] = { &dev_attr_msm_fb_panel_status.attr, &dev_attr_msm_fb_dfps_mode.attr, &dev_attr_measured_fps.attr, + &dev_attr_msm_fb_persist_mode.attr, NULL, }; @@ -1196,6 +1266,7 @@ static int mdss_fb_probe(struct platform_device *pdev) INIT_LIST_HEAD(&mfd->file_list); mutex_init(&mfd->bl_lock); + mutex_init(&mfd->mdss_sysfs_lock); mutex_init(&mfd->switch_lock); fbi_list[fbi_list_index++] = fbi; @@ -1962,7 +2033,7 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info) mfd->index, ret); return ret; } - + mutex_lock(&mfd->mdss_sysfs_lock); if (mfd->op_enable == 0) { if (blank_mode == FB_BLANK_UNBLANK) mfd->suspend.panel_power_state = MDSS_PANEL_POWER_ON; @@ -1972,7 +2043,8 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info) mfd->suspend.panel_power_state = MDSS_PANEL_POWER_LP1; else mfd->suspend.panel_power_state = MDSS_PANEL_POWER_OFF; - return 0; + ret = 0; + goto end; } pr_debug("mode: %d\n", blank_mode); @@ -1986,7 +2058,11 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info) pdata->panel_info.is_lpm_mode = false; } - return mdss_fb_blank_sub(blank_mode, info, mfd->op_enable); + ret = mdss_fb_blank_sub(blank_mode, info, mfd->op_enable); + +end: + mutex_unlock(&mfd->mdss_sysfs_lock); + return ret; } static inline int mdss_fb_create_ion_client(struct msm_fb_data_type *mfd) diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h index 205b8f7fac01..b03b3b571f27 100644 --- a/drivers/video/msm/mdss/mdss_fb.h +++ b/drivers/video/msm/mdss/mdss_fb.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -311,6 +311,7 @@ struct msm_fb_data_type { bool allow_bl_update; u32 bl_level_scaled; struct mutex bl_lock; + struct mutex mdss_sysfs_lock; bool ipc_resume; struct platform_device *pdev; diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h index d3256783722c..84e54759154d 100644 --- a/drivers/video/msm/mdss/mdss_panel.h +++ b/drivers/video/msm/mdss/mdss_panel.h @@ -117,6 +117,11 @@ enum { MDSS_PANEL_POWER_LP2, }; +enum { + MDSS_PANEL_LOW_PERSIST_MODE_OFF = 0, + MDSS_PANEL_LOW_PERSIST_MODE_ON, +}; + enum { MODE_GPIO_NOT_VALID = 0, MODE_GPIO_HIGH, @@ -743,6 +748,9 @@ struct mdss_panel_info { /* debugfs structure for the panel */ struct mdss_panel_debugfs_info *debugfs_info; + /* persistence mode on/off */ + bool persist_mode; + /* HDR properties of display panel*/ struct mdss_panel_hdr_properties hdr_properties; }; @@ -784,6 +792,7 @@ struct mdss_panel_timing { struct mdss_panel_data { struct mdss_panel_info panel_info; void (*set_backlight) (struct mdss_panel_data *pdata, u32 bl_level); + int (*apply_display_setting)(struct mdss_panel_data *pdata, u32 mode); unsigned char *mmss_cc_base; /** From b8a6b8b456453383fca16ffe4f4f23d30e21bdcd Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Wed, 20 Sep 2017 11:48:01 +0530 Subject: [PATCH 38/86] defconfig: arm: msm: enable vmalloc saving on msm8917/20/37/40 For some targets that have less vmalloc space, increase the size by enabling the vmalloc_savings option. Config ENABLE_VMALLOC_SAVING reclaims virtual mappings which remains unused because of non hlos carveout reservations in lowmem. Change-Id: I04d75852ef2eabb855f7886c336e9778164a5b6a CRs-Fixed: 2112076 Signed-off-by: Swetha Chikkaboraiah --- arch/arm/configs/msm8937-perf_defconfig | 1 + arch/arm/configs/msm8937_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/configs/msm8937-perf_defconfig b/arch/arm/configs/msm8937-perf_defconfig index 5007cd91c653..a11264dc4586 100644 --- a/arch/arm/configs/msm8937-perf_defconfig +++ b/arch/arm/configs/msm8937-perf_defconfig @@ -62,6 +62,7 @@ CONFIG_CMA=y CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_PROCESS_RECLAIM=y +CONFIG_ENABLE_VMALLOC_SAVING=y CONFIG_SECCOMP=y CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y CONFIG_AUTO_ZRELADDR=y diff --git a/arch/arm/configs/msm8937_defconfig b/arch/arm/configs/msm8937_defconfig index 5da435cff5c8..b9c8a17ab1ea 100644 --- a/arch/arm/configs/msm8937_defconfig +++ b/arch/arm/configs/msm8937_defconfig @@ -63,6 +63,7 @@ CONFIG_CMA=y CONFIG_CMA_DEBUGFS=y CONFIG_ZSMALLOC=y CONFIG_PROCESS_RECLAIM=y +CONFIG_ENABLE_VMALLOC_SAVING=y CONFIG_SECCOMP=y CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y CONFIG_AUTO_ZRELADDR=y From 520d4120171e65a8ce2a7ad7f4dfe78e107c2e7e Mon Sep 17 00:00:00 2001 From: Vidyasagar Pasmel Date: Fri, 22 Sep 2017 17:43:52 +0530 Subject: [PATCH 39/86] msm-3.18:Added IO-expander node to dtsi file Change-Id: Ia1655cf473689e2e2123f959979f8bb5b86100df Signed-off-by: Vidyasagar Pasmel Signed-off-by: Vivek Singh --- .../dts/qcom/apq8017-io-expander-cdp.dtsi | 95 +++++++++++++++++++ .../dts/qcom/apq8017-no-pmi-wcd-rome-cdp.dts | 1 + arch/arm/boot/dts/qcom/msm8917-cdp.dtsi | 77 --------------- 3 files changed, 96 insertions(+), 77 deletions(-) create mode 100644 arch/arm/boot/dts/qcom/apq8017-io-expander-cdp.dtsi diff --git a/arch/arm/boot/dts/qcom/apq8017-io-expander-cdp.dtsi b/arch/arm/boot/dts/qcom/apq8017-io-expander-cdp.dtsi new file mode 100644 index 000000000000..906ce6972c01 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apq8017-io-expander-cdp.dtsi @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msm8917-pinctrl.dtsi" +#include "msm8917-camera-sensor-cdp.dtsi" + +&soc { + usbhub_vbus_vreg: usbhub_vbus_vreg { + compatible = "regulator-fixed"; + regulator-name = "usbhub_vbus_vreg"; + gpio = <&ioexp_gpios 3 0>; + enable-active-high; + }; + + usbeth_vbus_vreg: usbeth_vbus_vreg { + compatible = "regulator-fixed"; + regulator-name = "usbeth_vbus_vreg"; + gpio = <&ioexp_gpios 7 0>; + enable-active-high; + vin-supply = <&usbhub_vbus_vreg>; + }; +}; + +/* SX1509q i/o expander */ +&i2c_2 { + status = "ok"; + ioexp2_gpios: sx150x@3e { + status = "ok"; + compatible = "sx1509q"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x3E>; /* I2C Client Addr */ + sx150x,pullup_ena = <0x0>; + sx150x,pulldn_ena = <0x0>; + sx150x,float_ena = <0x00>; + sx150x,polarity = <0x0>; + sx150x,gpio_base= <300>; + }; +}; + +/* SX1508q i/o expander */ +&i2c_4 { + status = "ok"; + ioexp_gpios: sx150x@20 { + status = "ok"; + compatible = "sx1508q"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x20>; /* I2C Client Addr */ + sx150x,pullup_ena = <0x0>; + sx150x,pulldn_ena = <0x0>; + sx150x,float_ena = <0x00>; + sx150x,polarity = <0x0>; + sx150x,gpio_base = <200>; + vdd-supply = <&pm8917_l6>; + qcom,vdd-max-voltage = <1800000>; + qcom,vdd-min-voltage = <1800000>; + }; + /* usb2533 flex hub */ + usb2533@2c { + status = "disabled"; + compatible = "qcom,usb2533-flex-hub"; + reg = <0x2d>; + vbus-supply = <&usbeth_vbus_vreg>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2533_hub_reset>; + qcom,hub-reset-gpio = <&tlmm 100 0>; + qcom,usbeth-reset-gpio = <&ioexp_gpios 5 0>; + }; +}; + +/* KS8851 eth over spi */ +&spi_6 { + status = "ok"; + ethernet@0 { + status = "ok"; + compatible = "micrel,ks8851"; + reg = <1>; /* CS-1 */ + interrupt-parent = <&tlmm>; + interrupts = <97 0>; + reset-gpios = <&ioexp_gpios 2 0>; + spi-max-frequency = <40000000>; + }; +}; + diff --git a/arch/arm/boot/dts/qcom/apq8017-no-pmi-wcd-rome-cdp.dts b/arch/arm/boot/dts/qcom/apq8017-no-pmi-wcd-rome-cdp.dts index 47341abd6155..cf60299fd983 100644 --- a/arch/arm/boot/dts/qcom/apq8017-no-pmi-wcd-rome-cdp.dts +++ b/arch/arm/boot/dts/qcom/apq8017-no-pmi-wcd-rome-cdp.dts @@ -17,6 +17,7 @@ #include "apq8017-no-pmi-cdp.dtsi" #include "apq8017-rome.dtsi" #include "apq8017-audio.dtsi" +#include "apq8017-io-expander-cdp.dtsi" / { model = "Qualcomm Technologies, Inc. APQ8017 CDP no-PMI \ diff --git a/arch/arm/boot/dts/qcom/msm8917-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8917-cdp.dtsi index 32da1aa920e5..9ddbf75c4042 100644 --- a/arch/arm/boot/dts/qcom/msm8917-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8917-cdp.dtsi @@ -78,21 +78,6 @@ qcom,notify-host-mode; status = "disabled"; }; - - usbhub_vbus_vreg: usbhub_vbus_vreg { - compatible = "regulator-fixed"; - regulator-name = "usbhub_vbus_vreg"; - gpio = <&ioexp_gpios 3 0>; - enable-active-high; - }; - - usbeth_vbus_vreg: usbeth_vbus_vreg { - compatible = "regulator-fixed"; - regulator-name = "usbeth_vbus_vreg"; - gpio = <&ioexp_gpios 7 0>; - enable-active-high; - vin-supply = <&usbhub_vbus_vreg>; - }; }; &spi_3 { /* BLSP1 QUP3 */ @@ -264,65 +249,3 @@ status = "ok"; }; -/* SX1509q i/o expander */ -&i2c_2 { - status = "ok"; - ioexp2_gpios: sx150x@3e { - status = "ok"; - compatible = "sx1509q"; - #gpio-cells = <2>; - gpio-controller; - reg = <0x3E>; /* I2C Client Addr */ - sx150x,pullup_ena = <0x0>; - sx150x,pulldn_ena = <0x0>; - sx150x,float_ena = <0x00>; - sx150x,polarity = <0x0>; - sx150x,gpio_base= <300>; - }; -}; - -/* SX1508q i/o expander */ -&i2c_4 { - status = "ok"; - ioexp_gpios: sx150x@20 { - status = "ok"; - compatible = "sx1508q"; - #gpio-cells = <2>; - gpio-controller; - reg = <0x20>; /* I2C Client Addr */ - sx150x,pullup_ena = <0x0>; - sx150x,pulldn_ena = <0x0>; - sx150x,float_ena = <0x00>; - sx150x,polarity = <0x0>; - sx150x,gpio_base = <200>; - vdd-supply = <&pm8917_l6>; - qcom,vdd-max-voltage = <1800000>; - qcom,vdd-min-voltage = <1800000>; - }; - /* usb2533 flex hub */ - usb2533@2c { - status = "disabled"; - compatible = "qcom,usb2533-flex-hub"; - reg = <0x2d>; - vbus-supply = <&usbeth_vbus_vreg>; - pinctrl-names = "default"; - pinctrl-0 = <&usb2533_hub_reset>; - qcom,hub-reset-gpio = <&tlmm 100 0>; - qcom,usbeth-reset-gpio = <&ioexp_gpios 5 0>; - }; -}; - -/* KS8851 eth over spi */ -&spi_6 { - status = "ok"; - ethernet@0 { - status = "ok"; - compatible = "micrel,ks8851"; - reg = <1>; /* CS-1 */ - interrupt-parent = <&tlmm>; - interrupts = <97 0>; - reset-gpios = <&ioexp_gpios 2 0>; - spi-max-frequency = <40000000>; - }; -}; - From c53f47bcbcca29e3c69235efac90fb9e9b530792 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 29 Sep 2017 12:01:45 +0800 Subject: [PATCH 40/86] drivers: leds: Fix aw2013 driver usleep -> udelay Change-Id: I1c7c7736e3be892c3749140828278d2903bd0910 --- drivers/leds/leds-aw2013.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c index d0a39fab2821..1fa2ac5ab38e 100644 --- a/drivers/leds/leds-aw2013.c +++ b/drivers/leds/leds-aw2013.c @@ -385,7 +385,7 @@ static int aw_2013_check_chipid(struct aw2013_led *led) u8 val; aw2013_write(led, AW_REG_RESET, AW_LED_RESET_MASK); - usleep(AW_LED_RESET_DELAY); + udelay(AW_LED_RESET_DELAY); aw2013_read(led, AW_REG_RESET, &val); if (val == AW2013_CHIPID) return 0; From c6bbdfa55501f00b4a2986c9fead193d1eea4513 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 29 Sep 2017 12:02:25 +0800 Subject: [PATCH 41/86] fs: f2fs: Fix caf merge issue duplicate get_data_block_bmap Change-Id: I70f634dbb66ffc9c77ef43386ff240a1a1b5106e --- fs/f2fs/data.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a9ac9b39b793..6d467fdaf900 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1301,15 +1301,6 @@ static int f2fs_mpage_readpages(struct address_space *mapping, return 0; } -static int get_data_block_bmap(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) -{ - /* Block number less than F2FS MAX BLOCKS */ - if (unlikely(iblock >= max_file_size(0))) - return -EFBIG; - return get_data_block_ro(inode, iblock, bh_result, create); -} - static int f2fs_read_data_page(struct file *file, struct page *page) { struct inode *inode = page->mapping->host; From 6c9be71aedcdcfae28394a57ee460f839c8b6776 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 07:06:25 +0000 Subject: [PATCH 42/86] arm: dtsi: Import dtsi files Change-Id: Ia599b79a0b39861883923f82ef4c5f3bf3adcc19 --- .../batterydata-qrd-coslight-4v4-4100mah.dtsi | 48 + .../batterydata-qrd-desay-4v4-4100mah.dtsi | 62 + ...erydata-qrd-desay-lisheng-4v4-4100mah.dtsi | 48 + .../qcom/batterydata-qrd-id1-4v4-4000mah.dtsi | 61 + .../qcom/batterydata-qrd-id2-4v4-4000mah.dtsi | 61 + .../batterydata-qrd-sku1-4v4-4000mah.dtsi | 61 + .../batterydata-qrd-sunwoda-4v4-4100mah.dtsi | 62 + ...tterydata-qrd-sunwoda-ATL-4v4-4100mah.dtsi | 48 + .../dts/qcom/dsi-panel-nt35532-fhd-video.dtsi | 4228 ++++++++++++++++ .../dts/qcom/dsi-panel-nt35596-fhd-video.dtsi | 93 + .../dsi-panel-nt35596-tianma-fhd-video.dtsi | 4263 +++++++++++++++++ arch/arm/boot/dts/qcom/msm-audio.dtsi | 15 +- arch/arm/boot/dts/qcom/msm-pm8953.dtsi | 35 +- arch/arm/boot/dts/qcom/msm-pmi8950.dtsi | 38 +- arch/arm/boot/dts/qcom/msm8953-audio.dtsi | 20 +- .../dts/qcom/msm8953-camera-sensor-qrd.dtsi | 876 +++- .../boot/dts/qcom/msm8953-mdss-panels.dtsi | 33 +- arch/arm/boot/dts/qcom/msm8953-mdss-pll.dtsi | 4 - arch/arm/boot/dts/qcom/msm8953-mtp.dtsi | 20 +- arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi | 102 +- arch/arm/boot/dts/qcom/msm8953-pm.dtsi | 1 + arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dts | 2 +- arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dtsi | 41 +- arch/arm/boot/dts/qcom/msm8953-qrd.dtsi | 204 +- arch/arm/boot/dts/qcom/msm8953.dtsi | 28 +- 25 files changed, 10292 insertions(+), 162 deletions(-) create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-coslight-4v4-4100mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-desay-4v4-4100mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-desay-lisheng-4v4-4100mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-id1-4v4-4000mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-id2-4v4-4000mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-sku1-4v4-4000mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-4v4-4100mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-ATL-4v4-4100mah.dtsi create mode 100644 arch/arm/boot/dts/qcom/dsi-panel-nt35532-fhd-video.dtsi create mode 100644 arch/arm/boot/dts/qcom/dsi-panel-nt35596-fhd-video.dtsi create mode 100644 arch/arm/boot/dts/qcom/dsi-panel-nt35596-tianma-fhd-video.dtsi diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-coslight-4v4-4100mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-coslight-4v4-4100mah.dtsi new file mode 100644 index 000000000000..29e77f4a212e --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-coslight-4v4-4100mah.dtsi @@ -0,0 +1,48 @@ + +qcom,2786095_mido_coslight_4100mah_averaged_masterslave_feb3rd2017 { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4100>; + qcom,batt-id-kohm = <50>; + qcom,battery-beta = <3435>; + qcom,battery-type = "qrd_msm8953_coslight_4100mah"; + qcom,chg-rslow-comp-c1 = <3439671>; + qcom,chg-rslow-comp-c2 = <5394943>; + qcom,chg-rs-to-rslow = <823652>; + qcom,chg-rslow-comp-thr = <0xAE>; + qcom,checksum = <0xF02E>; + qcom,gui-version = "PMI8950GUI - 2.0.0.16"; + qcom,fg-profile-data = [ + DF 83 B4 7C + E0 80 A2 76 + 56 83 B7 5E + DF 82 41 8E + 40 82 BC 98 + C2 B6 78 C2 + 57 17 EA 83 + B7 7C CA 80 + 59 76 4F 83 + 37 6B 71 78 + EE 86 41 82 + FA 99 50 BD + 65 CA 55 0D + 07 10 F0 58 + 14 70 DA FC + 05 3E F6 35 + FE 12 00 00 + 3B 3D 7B 30 + 92 45 00 00 + 00 00 00 00 + 00 00 00 00 + 7B 6A 86 69 + 1C 68 1C 7B + 0C 6C 60 60 + 63 6A F6 7A + BF 64 C1 58 + C0 84 BB 7E + 1B C9 61 20 + 5F A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-desay-4v4-4100mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-desay-4v4-4100mah.dtsi new file mode 100644 index 000000000000..bfcd7a82fd53 --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-desay-4v4-4100mah.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,2508175_bn41hdesay_4100mah_averaged_masterslave_jun27th2016 { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4100>; + qcom,batt-id-kohm = <82>; + qcom,battery-beta = <3435>; + qcom,battery-type = "qrd_msm8953_desay_4100mah"; + qcom,fastchg-current-ma = <2000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,chg-rslow-comp-c1 = <2760396>; + qcom,chg-rslow-comp-c2 = <3348384>; + qcom,chg-rs-to-rslow = <870409>; + qcom,chg-rslow-comp-thr = <0x99>; + qcom,checksum = <0xFA46>; + qcom,gui-version = "PMI8950GUI - 2.0.0.16"; + qcom,fg-profile-data = [ + DE 83 BE 7C + 15 81 58 77 + 62 83 13 74 + 3F 89 50 94 + 1D 82 DE 99 + AC BC 0C C9 + 56 10 10 88 + A4 7E 60 82 + D2 7C 48 83 + 30 72 2E 75 + 75 6D 4E 82 + 80 99 A9 BC + 5C C9 5E 0C + C9 0F 82 5A + 14 70 DA FC + 20 2F 05 46 + 07 41 00 00 + FF 4C 56 3B + AF 41 00 00 + 00 00 00 00 + 00 00 00 00 + 4D 70 1A 6A + C9 74 9E 89 + 9F 77 D2 70 + A3 58 9F 81 + 91 74 A5 68 + 7D 66 B5 9B + 2F 05 63 F3 + 64 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-desay-lisheng-4v4-4100mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-desay-lisheng-4v4-4100mah.dtsi new file mode 100644 index 000000000000..93aff0b8790c --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-desay-lisheng-4v4-4100mah.dtsi @@ -0,0 +1,48 @@ + +qcom,2781148_mido_desay_4100mah_averaged_masterslave_feb3rd2017 { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4100>; + qcom,batt-id-kohm = <62>; + qcom,battery-beta = <3435>; + qcom,battery-type = "batterydata-qrd-desay-lisheng-4v4-4100mah"; + qcom,chg-rslow-comp-c1 = <2747468>; + qcom,chg-rslow-comp-c2 = <3764702>; + qcom,chg-rs-to-rslow = <770184>; + qcom,chg-rslow-comp-thr = <0xA2>; + qcom,checksum = <0x3826>; + qcom,gui-version = "PMI8950GUI - 2.0.0.16"; + qcom,fg-profile-data = [ + F0 83 6D 7D + 90 81 15 7C + 5C 83 50 67 + 0E 83 A6 8D + 22 82 AE 9A + 28 BE B5 CB + 5A 0E FC 83 + 78 7D 8C 81 + 0B 7C 62 83 + D4 65 5D 88 + 2D 94 57 82 + BB 99 28 BD + 42 CA 52 0D + 2A 10 98 59 + 14 70 DA FC + 09 44 6E 3D + AF 39 00 00 + 23 47 66 38 + AF 31 00 00 + 00 00 00 00 + 00 00 00 00 + 28 6B 33 6A + E6 70 BF 88 + 0C 74 27 69 + 7B 5A 38 80 + 26 6E 19 68 + 25 6E 46 A1 + 1D D3 5A 1B + 5C A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-id1-4v4-4000mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-id1-4v4-4000mah.dtsi new file mode 100644 index 000000000000..e15c1146273d --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-id1-4v4-4000mah.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,qrd_msm8953_id1_4000mah { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4000>; + qcom,batt-id-kohm = <33>; + qcom,battery-beta = <3380>; + qcom,battery-type = "qrd_msm8953_sunwoda_4000mah"; + qcom,fastchg-current-ma = <2000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,chg-rslow-comp-c1 = <6733839>; + qcom,chg-rslow-comp-c2 = <23336040>; + qcom,chg-rs-to-rslow = <1049243>; + qcom,chg-rslow-comp-thr = <0xDB>; + qcom,checksum = <0x7E2A>; + qcom,gui-version = "PMI8950GUI - 2.0.0.14"; + qcom,fg-profile-data = [ + C6 83 8A 77 + 3E 80 84 75 + 72 83 A1 7C + A0 90 FC 97 + 3F 82 09 99 + 92 B7 97 C3 + 4C 14 EB 83 + A7 7C CE 80 + 79 76 60 83 + 3B 64 34 88 + 19 94 49 82 + 07 9A 7F BD + BF CA 53 0D + 32 0B 68 59 + 14 70 71 FD + 8C 28 9C 45 + 3F 21 00 00 + B6 47 FE 30 + 0B 40 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 70 78 6B + F7 77 7F 88 + 32 7C F2 70 + 64 75 0B 79 + 2B 77 F3 6B + CA 70 7D B1 + 21 57 6B 6B + 6D A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-id2-4v4-4000mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-id2-4v4-4000mah.dtsi new file mode 100644 index 000000000000..8d9d5820f583 --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-id2-4v4-4000mah.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,qrd_msm8953_id2_4000mah { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4000>; + qcom,batt-id-kohm = <82>; + qcom,battery-beta = <3380>; + qcom,battery-type = "qrd_msm8953_desay_4000mah"; + qcom,fastchg-current-ma = <2000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,chg-rslow-comp-c1 = <6733839>; + qcom,chg-rslow-comp-c2 = <23336040>; + qcom,chg-rs-to-rslow = <1049243>; + qcom,chg-rslow-comp-thr = <0xDB>; + qcom,checksum = <0x7E2A>; + qcom,gui-version = "PMI8950GUI - 2.0.0.14"; + qcom,fg-profile-data = [ + C6 83 8A 77 + 3E 80 84 75 + 72 83 A1 7C + A0 90 FC 97 + 3F 82 09 99 + 92 B7 97 C3 + 4C 14 EB 83 + A7 7C CE 80 + 79 76 60 83 + 3B 64 34 88 + 19 94 49 82 + 07 9A 7F BD + BF CA 53 0D + 32 0B 68 59 + 14 70 71 FD + 8C 28 9C 45 + 3F 21 00 00 + B6 47 FE 30 + 0B 40 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 70 78 6B + F7 77 7F 88 + 32 7C F2 70 + 64 75 0B 79 + 2B 77 F3 6B + CA 70 7D B1 + 21 57 6B 6B + 6D A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-sku1-4v4-4000mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-sku1-4v4-4000mah.dtsi new file mode 100644 index 000000000000..661516a403b2 --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-sku1-4v4-4000mah.dtsi @@ -0,0 +1,61 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,qrd_msm8953_sku1_4000mah { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4000>; + qcom,batt-id-kohm = <33>; + qcom,battery-beta = <3380>; + qcom,battery-type = "qrd_msm8953_sku1_4000mah"; + qcom,fastchg-current-ma = <2000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,chg-rslow-comp-c1 = <6733839>; + qcom,chg-rslow-comp-c2 = <23336040>; + qcom,chg-rs-to-rslow = <1049243>; + qcom,chg-rslow-comp-thr = <0xDB>; + qcom,checksum = <0x7E2A>; + qcom,gui-version = "PMI8950GUI - 2.0.0.14"; + qcom,fg-profile-data = [ + C6 83 8A 77 + 3E 80 84 75 + 72 83 A1 7C + A0 90 FC 97 + 3F 82 09 99 + 92 B7 97 C3 + 4C 14 EB 83 + A7 7C CE 80 + 79 76 60 83 + 3B 64 34 88 + 19 94 49 82 + 07 9A 7F BD + BF CA 53 0D + 32 0B 68 59 + 14 70 71 FD + 8C 28 9C 45 + 3F 21 00 00 + B6 47 FE 30 + 0B 40 00 00 + 00 00 00 00 + 00 00 00 00 + 3A 70 78 6B + F7 77 7F 88 + 32 7C F2 70 + 64 75 0B 79 + 2B 77 F3 6B + CA 70 7D B1 + 21 57 6B 6B + 6D A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-4v4-4100mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-4v4-4100mah.dtsi new file mode 100644 index 000000000000..1d9d574af37d --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-4v4-4100mah.dtsi @@ -0,0 +1,62 @@ +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +qcom,qrd_msm8953_id1_4100mah { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4100>; + qcom,batt-id-kohm = <33>; + qcom,battery-beta = <3435>; + qcom,battery-type = "qrd_msm8953_sunwoda_4100mah"; + qcom,fastchg-current-ma = <2000>; + qcom,fg-cc-cv-threshold-mv = <4390>; + qcom,chg-rslow-comp-c1 = <3047055>; + qcom,chg-rslow-comp-c2 = <3708812>; + qcom,chg-rs-to-rslow = <1708063>; + qcom,chg-rslow-comp-thr = <0x99>; + qcom,checksum = <0x6FF9>; + qcom,gui-version = "PMI8950GUI - 2.0.0.16"; + qcom,fg-profile-data = [ + DC 83 9E 7C + CD 80 80 76 + 60 83 FD 6E + 04 89 50 94 + 38 82 24 99 + C7 B7 F4 C3 + 56 0F 06 88 + F9 7D BA 81 + 0F 7C 54 83 + B3 69 2B 7A + FE 87 4B 82 + DA 99 33 BD + 45 CA 58 0D + 13 10 39 58 + 14 70 DA FC + 3A 36 CF 46 + 1E 42 00 00 + 5D 46 C4 3B + 0A 44 00 00 + 00 00 00 00 + 00 00 00 00 + AD 72 EE 70 + 73 58 12 88 + E9 75 4D 68 + 47 61 B0 7A + 24 74 10 53 + 19 74 5B AA + 23 44 69 3E + 67 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-ATL-4v4-4100mah.dtsi b/arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-ATL-4v4-4100mah.dtsi new file mode 100644 index 000000000000..878bd648d093 --- /dev/null +++ b/arch/arm/boot/dts/qcom/batterydata-qrd-sunwoda-ATL-4v4-4100mah.dtsi @@ -0,0 +1,48 @@ + +qcom,2728170_mido_sunwoda_4100mah_averaged_masterslave_jan3rd2017 { + qcom,max-voltage-uv = <4400000>; + qcom,nom-batt-capacity-mah = <4100>; + qcom,batt-id-kohm = <40>; + qcom,battery-beta = <3435>; + qcom,battery-type = "qrd_msm8953_sunwoda_atl_4100mah"; + qcom,chg-rslow-comp-c1 = <3159320>; + qcom,chg-rslow-comp-c2 = <4074348>; + qcom,chg-rs-to-rslow = <921524>; + qcom,chg-rslow-comp-thr = <0x9C>; + qcom,checksum = <0xDC57>; + qcom,gui-version = "PMI8950GUI - 2.0.0.16"; + qcom,fg-profile-data = [ + DC 83 AD 7C + 04 81 2F 77 + 5E 83 68 6E + C6 88 02 94 + 34 82 87 99 + 7C BC F0 C8 + 57 0F 11 88 + BA 7E 69 82 + D1 7C 48 83 + 1C 72 05 75 + 09 6D 53 82 + 5A 99 80 BC + 1E C9 60 0C + EC 0F E8 59 + 14 70 DA FC + 59 32 B3 45 + 5F 28 00 00 + 05 47 6C 38 + 6E 33 00 00 + 00 00 00 00 + 00 00 00 00 + 8A 70 78 6A + BA 7E 25 88 + 28 7C B2 71 + DF 6C 90 78 + 2E 74 DB 68 + FD 5B BA A1 + 32 86 68 DC + 66 A0 71 0C + 28 00 FF 36 + F0 11 30 03 + 00 00 00 0C + ]; +}; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35532-fhd-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35532-fhd-video.dtsi new file mode 100644 index 000000000000..e5a810a7de3e --- /dev/null +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35532-fhd-video.dtsi @@ -0,0 +1,4228 @@ +/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_nt35532_fhd_vid: qcom,mdss_dsi_nt35532_fhd_video { + qcom,mdss-dsi-panel-name = "nt35532 fhd video mode dsi panel"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <124>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <12>; + qcom,mdss-dsi-v-front-porch = <7>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [29 01 00 00 01 00 02 ff 05 + 29 01 00 00 00 00 02 fb 01 + 29 01 00 00 00 00 02 d6 22 + 29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 fb 01 + 29 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 02 51 ff + 29 01 00 00 00 00 02 53 2c + 29 01 00 00 00 00 02 55 00 + 29 01 00 00 00 00 02 d3 0E + 29 01 00 00 00 00 02 d4 07 + 29 01 00 00 78 00 02 11 00 + 29 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-off-command = [29 01 00 00 00 00 02 ff 00 + 05 01 00 00 14 00 02 28 00 + 05 01 00 00 3C 00 02 10 00 + 29 01 00 00 00 00 02 ff 00 + 29 01 00 00 14 00 02 4F 01]; + qcom,mdss-dsi-CABC_on-command = [29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 55 B1]; + qcom,mdss-dsi-CABC_off-command = [29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-CE_off-command = [29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-CE_on-command = [23 00 00 00 00 00 02 FF 00 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 55 B0 + 23 00 00 00 00 00 02 FF 03 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 0D + 23 00 00 00 00 00 02 02 15 + 23 00 00 00 00 00 02 03 1C + 23 00 00 00 00 00 02 04 21 + 23 00 00 00 00 00 02 05 26 + 23 00 00 00 00 00 02 06 2B + 23 00 00 00 00 00 02 07 2C + 23 00 00 00 00 00 02 08 2D + 23 00 00 00 00 00 02 09 2D + 23 00 00 00 00 00 02 0A 2D + 23 00 00 00 00 00 02 0B 2D + 23 00 00 00 00 00 02 0C 2C + 23 00 00 00 00 00 02 0D 2A + 23 00 00 00 00 00 02 0E 27 + 23 00 00 00 00 00 02 0F 23 + 23 00 00 00 00 00 02 10 1D + 23 00 00 00 00 00 02 11 17 + 23 00 00 00 00 00 02 12 0B + 23 00 00 00 00 00 02 13 00 + 23 00 00 00 00 00 02 1A 00 + 23 00 00 00 00 00 02 1B 00 + 23 00 00 00 00 00 02 1C 00 + 23 00 00 00 00 00 02 1D 00 + 23 00 00 00 00 00 02 1E 00 + 23 00 00 00 00 00 02 1F 00 + 23 00 00 00 00 00 02 20 00 + 23 00 00 00 00 00 02 21 00 + 23 00 00 00 00 00 02 22 00 + 23 00 00 00 00 00 02 23 00 + 23 00 00 00 00 00 02 24 00 + 23 00 00 00 00 00 02 25 00 + 23 00 00 00 00 00 02 26 00 + 23 00 00 00 00 00 02 27 00 + 23 00 00 00 00 00 02 28 00 + 23 01 00 00 00 00 02 29 00 + + 23 00 00 00 00 00 02 2A 00 + 23 00 00 00 00 00 02 2B 00 + 23 00 00 00 00 00 02 2F 00 + 23 00 00 00 00 00 02 30 00 + 23 00 00 00 00 00 02 31 00 + 23 00 00 00 00 00 02 32 85 + 23 00 00 00 00 00 02 33 07 + 23 00 00 00 00 00 02 34 0A + 23 00 00 00 00 00 02 35 0D + 23 00 00 00 00 00 02 36 12 + 23 00 00 00 00 00 02 37 16 + 23 00 00 00 00 00 02 38 1B + 23 00 00 00 00 00 02 39 1D + 23 00 00 00 00 00 02 3A 1C + 23 00 00 00 00 00 02 3B 1B + 23 00 00 00 00 00 02 3F 18 + 23 00 00 00 00 00 02 40 14 + 23 00 00 00 00 00 02 41 13 + 23 00 00 00 00 00 02 42 12 + 23 00 00 00 00 00 02 43 13 + 23 00 00 00 00 00 02 44 13 + 23 00 00 00 00 00 02 45 11 + 23 00 00 00 00 00 02 46 0D + 23 00 00 00 00 00 02 47 09 + 23 00 00 00 00 00 02 48 07 + 23 00 00 00 00 00 02 49 07 + 23 00 00 00 00 00 02 4A 07 + 23 00 00 00 00 00 02 4B 06 + 23 00 00 00 00 00 02 4C 06 + 23 00 00 00 00 00 02 4D 00 + 23 00 00 00 00 00 02 4E 00 + 23 00 00 00 00 00 02 4F 00 + 23 00 00 00 00 00 02 50 00 + 23 00 00 00 00 00 02 51 00 + 23 00 00 00 00 00 02 52 00 + 23 00 00 00 00 00 02 53 05 + 23 00 00 00 00 00 02 54 04 + 23 00 00 00 00 00 02 55 04 + 23 00 00 00 00 00 02 56 00 + 23 01 00 00 00 00 02 68 00]; + + qcom,mdss-dsi-cold_gamma-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 6E 80 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 D6 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 DE + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A ED + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C FA + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 08 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 13 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 1D + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 28 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 31 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 53 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 71 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C A0 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 01 00 00 00 00 02 92 37 + + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 38 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 68 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 9D + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A C0 + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C F3 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 16 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 43 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 52 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 63 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 91 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AF + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C0 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 C8 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 C9 + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 D6 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 DE + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 ED + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA FA + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 08 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 13 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 1D + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 28 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 31 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 53 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 71 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA A0 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 01 00 00 00 00 02 D0 37 + + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 38 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 68 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 9D + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 C0 + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA F3 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 16 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 43 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 52 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 63 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 91 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AF + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C0 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC C8 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE C9 + 23 00 00 00 00 00 02 EF 01 + 23 00 00 00 00 00 02 F0 03 + 23 00 00 00 00 00 02 F1 01 + 23 00 00 00 00 00 02 F2 09 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 13 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 1E + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 27 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 30 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 39 + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 41 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 49 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 66 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 80 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B AB + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CF + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 01 00 00 00 00 02 11 39 + + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 69 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9E + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C1 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F4 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 18 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 45 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 54 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 65 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 94 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AE + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C0 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F C8 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 C9 + 23 00 00 00 00 00 02 32 01 + 23 00 00 00 00 00 02 33 03 + 23 00 00 00 00 00 02 34 01 + 23 00 00 00 00 00 02 35 09 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 13 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 1E + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 27 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 30 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 39 + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 41 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 49 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 66 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 80 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B AB + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CF + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 01 00 00 00 00 02 51 39 + + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 69 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9E + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C1 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F4 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 18 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 45 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 54 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 65 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 94 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AE + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C0 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E C8 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 C9 + 23 00 00 00 00 00 02 71 00 + 23 00 00 00 00 00 02 72 01 + 23 00 00 00 00 00 02 73 00 + 23 00 00 00 00 00 02 74 40 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 70 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 8F + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A AA + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C BD + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E CE + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 DF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 EC + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 1C + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 43 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 7D + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A AB + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C F2 + 23 00 00 00 00 00 02 8D 02 + 23 01 00 00 00 00 02 8E 29 + + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 2B + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 5D + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 94 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 B7 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 EB + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 14 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 4B + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 62 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 86 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 A5 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 B3 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 BC + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C2 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC C8 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE C9 + 23 00 00 00 00 00 02 AF 00 + 23 00 00 00 00 00 02 B0 01 + 23 00 00 00 00 00 02 B1 00 + 23 00 00 00 00 00 02 B2 40 + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 70 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 8F + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 AA + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA BD + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC CE + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE DF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 EC + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 1C + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 43 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 7D + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 AB + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA F2 + 23 00 00 00 00 00 02 CB 02 + 23 01 00 00 00 00 02 CC 29 + + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 2B + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 5D + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 94 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 B7 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 EB + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 14 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 4B + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 62 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 86 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 A5 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 B3 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 BC + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C2 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 C8 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA C9]; + + + qcom,mdss-dsi-warm_gamma-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 6E 80 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 01 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7A + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 98 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E AF + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C2 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D3 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E2 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F0 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 1D + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 41 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 7A + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E A7 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 EC + 23 00 00 00 00 00 02 91 02 + 23 01 00 00 00 00 02 92 22 + + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 24 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 54 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 87 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A A7 + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C D7 + 23 00 00 00 00 00 02 9D 02 + 23 00 00 00 00 00 02 9E F7 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 22 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 2F + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 3D + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 4D + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 62 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC 83 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE AF + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 C6 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 C9 + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 01 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7A + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 98 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC AF + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C2 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D3 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E2 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F0 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 1D + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 41 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 7A + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC A7 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE EC + 23 00 00 00 00 00 02 CF 02 + 23 01 00 00 00 00 02 D0 22 + + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 24 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 54 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 87 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 A7 + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA D7 + 23 00 00 00 00 00 02 DB 02 + 23 00 00 00 00 00 02 DC F7 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 22 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 2F + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 3D + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 4D + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 62 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 83 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA AF + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC C6 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE C9 + 23 00 00 00 00 00 02 EF 01 + 23 00 00 00 00 00 02 F0 2D + 23 00 00 00 00 00 02 F1 01 + 23 00 00 00 00 00 02 F2 31 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 39 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 41 + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 48 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 4E + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 55 + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 5B + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 62 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 7A + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 8F + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B B4 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D D4 + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 08 + 23 00 00 00 00 00 02 10 02 + 23 01 00 00 00 00 02 11 36 + + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 37 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 62 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 93 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 B3 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B E3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 04 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 2F + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 3D + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 4C + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 5F + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 77 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 97 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B B5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F C7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 C9 + 23 00 00 00 00 00 02 32 01 + 23 00 00 00 00 00 02 33 2D + 23 00 00 00 00 00 02 34 01 + 23 00 00 00 00 00 02 35 31 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 39 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 41 + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 48 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 4E + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 55 + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 5B + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 62 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 7A + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 8F + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B B4 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D D4 + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 08 + 23 00 00 00 00 00 02 50 02 + 23 01 00 00 00 00 02 51 36 + + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 37 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 62 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 93 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A B3 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C E3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 04 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 2F + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 3D + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 4C + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 5F + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 77 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A 97 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C B5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E C7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 C9 + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 2C + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 30 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 38 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 3F + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 46 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 4C + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 53 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 59 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 60 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 77 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 8C + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 B1 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A D1 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 06 + 23 00 00 00 00 00 02 8D 02 + 23 01 00 00 00 00 02 8E 34 + + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 35 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 61 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 92 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 B2 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 E4 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 08 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 3B + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 4F + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 69 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 9C + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 B9 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 BE + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C1 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC C8 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE C9 + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 2C + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 30 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 38 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 3F + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 46 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 4C + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 53 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 59 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 60 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 77 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 8C + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 B1 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 D1 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 06 + 23 00 00 00 00 00 02 CB 02 + 23 01 00 00 00 00 02 CC 34 + + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 35 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 61 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 92 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 B2 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 E4 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 08 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 3B + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 4F + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 69 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 9C + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 B9 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 BE + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C1 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 C8 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA C9]; + + qcom,mdss-dsi-default_gamma-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 6E 80 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 01 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4F + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7F + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9E + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B6 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C9 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DB + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EB + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F9 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B4 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F9 + 23 00 00 00 00 00 02 91 02 + 23 01 00 00 00 00 02 92 2F + + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A B9 + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C EB + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 0F + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3C + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4A + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 59 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 6C + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 87 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C3 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CC + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CD + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 01 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4F + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7F + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9E + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B6 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C9 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DB + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EB + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F9 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B4 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F9 + 23 00 00 00 00 00 02 CF 02 + 23 01 00 00 00 00 02 D0 2F + + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 B9 + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA EB + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 0F + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3C + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4A + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 59 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 6C + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 87 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C3 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CC + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CD + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 04 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2D + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 37 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3F + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5E + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 79 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A7 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CC + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 08 + 23 00 00 00 00 00 02 10 02 + 23 01 00 00 00 00 02 11 39 + + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3A + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 69 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9D + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 16 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C3 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CC + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CD + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 04 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2D + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 37 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3F + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5E + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 79 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A7 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CC + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 08 + 23 00 00 00 00 00 02 50 02 + 23 01 00 00 00 00 02 51 39 + + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3A + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 69 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9D + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 16 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C3 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CC + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CD + 23 00 00 00 00 00 02 71 00 + 23 00 00 00 00 00 02 72 A9 + 23 00 00 00 00 00 02 73 00 + 23 00 00 00 00 00 02 74 B3 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 C6 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 D6 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A E4 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C F1 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E FE + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 0B + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 15 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 3B + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 5B + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 8F + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A B9 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C FB + 23 00 00 00 00 00 02 8D 02 + 23 01 00 00 00 00 02 8E 30 + + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 31 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 62 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 98 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 BB + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 F0 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 17 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 52 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 6C + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 97 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 B6 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 BF + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 C2 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C7 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CC + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CD + 23 00 00 00 00 00 02 AF 00 + 23 00 00 00 00 00 02 B0 A9 + 23 00 00 00 00 00 02 B1 00 + 23 00 00 00 00 00 02 B2 B3 + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 C6 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 D6 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 E4 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA F1 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC FE + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 0B + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 15 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 3B + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 5B + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 8F + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 B9 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA FB + 23 00 00 00 00 00 02 CB 02 + 23 01 00 00 00 00 02 CC 30 + + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 31 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 62 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 98 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 BB + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 F0 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 17 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 52 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 6C + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 97 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 B6 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 BF + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 C2 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C7 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CC + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CD]; + + qcom,mdss-dsi-PM1-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 09 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 0E + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 19 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 22 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 2C + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 34 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 3D + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 45 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 4C + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 69 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 82 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 AC + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A D0 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 0A + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 3A + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 3B + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 69 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 9D + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 C1 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 F4 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 17 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 42 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 50 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 5F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 71 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 88 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 A6 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C0 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 09 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 0E + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 19 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 22 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 2C + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 34 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 3D + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 45 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 4C + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 69 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 82 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 AC + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 D0 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 0A + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 3A + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 3B + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 69 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 9D + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 C1 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 F4 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 17 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 42 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 50 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 5F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 71 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 88 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 A6 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C0 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + qcom,mdss-dsi-PM2-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 4A + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 4E + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 55 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 5B + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 62 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 68 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 6E + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 74 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 7A + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 90 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 A4 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 C7 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A E5 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 18 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 44 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 45 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 71 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 A4 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 C8 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 FB + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 1D + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 48 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 55 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 64 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 76 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 8E + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 AA + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C2 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 4A + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 4E + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 55 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 5B + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 62 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 68 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 6E + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 74 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 7A + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 90 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 A4 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 C7 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 E5 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 18 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 44 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 45 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 71 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 A4 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 C8 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 FB + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 1D + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 48 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 55 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 64 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 76 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 8E + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 AA + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C2 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + qcom,mdss-dsi-PM3-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 7A + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 7D + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 82 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 87 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 8C + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 91 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 96 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 9B + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 9F + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 B1 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 C1 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 DE + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A F8 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 25 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 4E + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 4F + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 79 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 AB + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 D0 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 02 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 24 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 4D + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 5A + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 6A + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 7C + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 93 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 AE + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C3 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 7A + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 7D + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 82 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 87 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 8C + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 91 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 96 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 9B + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 9F + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 B1 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 C1 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 DE + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 F8 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 25 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 4E + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 4F + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 79 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 AB + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 D0 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 02 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 24 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 4D + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 5A + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 6A + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 7C + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 93 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 AE + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C3 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + + qcom,mdss-dsi-PM4-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 99 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 9B + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 A0 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 A4 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A A8 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C AC + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E B0 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 B4 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 B8 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 C7 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 D5 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 EF + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 06 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 2F + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 56 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 57 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 7F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 B1 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 D7 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 08 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 29 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 52 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 5F + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 6E + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 80 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 98 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 B1 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C4 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 99 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 9B + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 A0 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 A4 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 A8 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA AC + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC B0 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE B4 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 B8 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 C7 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 D5 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 EF + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 06 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 2F + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 56 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 57 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 7F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 B1 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 D7 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 08 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 29 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 52 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 5F + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 6E + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 80 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 98 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 B1 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C4 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + qcom,mdss-dsi-PM5-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 BF + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 C1 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 C4 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 C8 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A CB + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C CE + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E D1 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 D5 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 D8 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 E4 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 EF + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 05 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 19 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 3D + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 61 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 62 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 89 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 BA + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 E0 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 11 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 30 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 59 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 66 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 75 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 88 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 9E + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 B5 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C6 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 BF + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 C1 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 C4 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 C8 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 CB + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA CE + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC D1 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE D5 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 D8 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 E4 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 EF + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 05 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 19 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 3D + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 61 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 62 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 89 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 BA + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 E0 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 11 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 30 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 59 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 66 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 75 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 88 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 9E + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 B5 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C6 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + qcom,mdss-dsi-PM6-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 D6 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 D7 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 DA + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 DD + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A E0 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C E3 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E E6 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 E9 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 EB + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 F5 + 23 00 00 00 00 00 02 85 02 + 23 00 00 00 00 00 02 86 00 + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 13 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 25 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 47 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 69 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 6A + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 90 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 C1 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 E6 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 17 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 36 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 5E + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 6B + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 7A + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 8D + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 A3 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 B8 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C7 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 D6 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 D7 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 DA + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 DD + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 E0 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA E3 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC E6 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE E9 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 EB + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 F5 + 23 00 00 00 00 00 02 C3 02 + 23 00 00 00 00 00 02 C4 00 + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 13 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 25 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 47 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 69 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 6A + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 90 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 C1 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 E6 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 17 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 36 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 5E + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 6B + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 7A + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 8D + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 A3 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 B8 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C7 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + qcom,mdss-dsi-PM7-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 EF + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 F0 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 F2 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 F4 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A F7 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C F9 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E FC + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 FE + 23 00 00 00 00 00 02 81 02 + 23 00 00 00 00 00 02 82 00 + 23 00 00 00 00 00 02 83 02 + 23 00 00 00 00 00 02 84 0A + 23 00 00 00 00 00 02 85 02 + 23 00 00 00 00 00 02 86 12 + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 23 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 33 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 53 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 73 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 74 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 98 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 CB + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 EE + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 1F + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 3D + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 64 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 71 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 81 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 93 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 A9 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 BB + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C8 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CD + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CE + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 EF + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 F0 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 F2 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 F4 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 F7 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA F9 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC FC + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE FE + 23 00 00 00 00 00 02 BF 02 + 23 00 00 00 00 00 02 C0 00 + 23 00 00 00 00 00 02 C1 02 + 23 00 00 00 00 00 02 C2 0A + 23 00 00 00 00 00 02 C3 02 + 23 00 00 00 00 00 02 C4 12 + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 23 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 33 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 53 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 73 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 74 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 98 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 CB + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 EE + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 1F + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 3D + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 64 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 71 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 81 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 93 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 A9 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 BB + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C8 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CD + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CE]; + + qcom,mdss-dsi-PM8-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 4C + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 7C + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 9B + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B4 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C8 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DA + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 E9 + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 F7 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 27 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 4C + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 86 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E B3 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 F8 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 2F + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 30 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 61 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 97 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C ED + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 11 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 3F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 60 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 77 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B0 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 CD + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 CE + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 4C + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 7C + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 9B + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B4 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C8 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DA + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 E9 + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 F7 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 27 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 4C + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 86 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC B3 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE F8 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 2F + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 30 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 61 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 97 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA ED + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 11 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 3F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 60 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 77 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B0 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC CD + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE CE + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 F1 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F7 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 0F + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 19 + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 23 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 2C + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 35 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3E + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 5D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 78 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 06 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 37 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 38 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 67 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9C + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C0 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B F3 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 17 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 44 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 53 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 7A + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 95 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 B0 + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F CD + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 CE + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 F1 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F7 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 0F + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 19 + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 23 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 2C + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 35 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3E + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 5D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 78 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 06 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 37 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 38 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 67 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9C + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C0 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C F3 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 17 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 44 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 53 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 7A + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 95 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A B0 + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E CD + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 CE + 23 00 00 00 00 00 02 71 02 + 23 00 00 00 00 00 02 72 11 + 23 00 00 00 00 00 02 73 02 + 23 00 00 00 00 00 02 74 12 + 23 00 00 00 00 00 02 75 02 + 23 00 00 00 00 00 02 76 14 + 23 00 00 00 00 00 02 77 02 + 23 00 00 00 00 00 02 78 16 + 23 00 00 00 00 00 02 79 02 + 23 00 00 00 00 00 02 7A 18 + 23 00 00 00 00 00 02 7B 02 + 23 00 00 00 00 00 02 7C 1A + 23 00 00 00 00 00 02 7D 02 + 23 00 00 00 00 00 02 7E 1B + 23 00 00 00 00 00 02 7F 02 + 23 00 00 00 00 00 02 80 1D + 23 00 00 00 00 00 02 81 02 + 23 00 00 00 00 00 02 82 1F + 23 00 00 00 00 00 02 83 02 + 23 00 00 00 00 00 02 84 26 + 23 00 00 00 00 00 02 85 02 + 23 00 00 00 00 00 02 86 2D + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 3B + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 49 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 65 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 83 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 84 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 A7 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 DB + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 FE + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 2C + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 49 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 70 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 7D + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 8C + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 9E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 B1 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 BF + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C9 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC CE + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE CF + 23 00 00 00 00 00 02 AF 02 + 23 00 00 00 00 00 02 B0 11 + 23 00 00 00 00 00 02 B1 02 + 23 00 00 00 00 00 02 B2 12 + 23 00 00 00 00 00 02 B3 02 + 23 00 00 00 00 00 02 B4 14 + 23 00 00 00 00 00 02 B5 02 + 23 00 00 00 00 00 02 B6 16 + 23 00 00 00 00 00 02 B7 02 + 23 00 00 00 00 00 02 B8 18 + 23 00 00 00 00 00 02 B9 02 + 23 00 00 00 00 00 02 BA 1A + 23 00 00 00 00 00 02 BB 02 + 23 00 00 00 00 00 02 BC 1B + 23 00 00 00 00 00 02 BD 02 + 23 00 00 00 00 00 02 BE 1D + 23 00 00 00 00 00 02 BF 02 + 23 00 00 00 00 00 02 C0 1F + 23 00 00 00 00 00 02 C1 02 + 23 00 00 00 00 00 02 C2 26 + 23 00 00 00 00 00 02 C3 02 + 23 00 00 00 00 00 02 C4 2D + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 3B + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 49 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 65 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 83 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 84 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 A7 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 DB + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 FE + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 2C + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 49 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 70 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 7D + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 8C + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 9E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 B1 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 BF + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C9 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 CE + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA CF]; + + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CABC_on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CABC_off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CE_on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CE_off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-cold_gamma-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-warm_gamma-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-default_gamma-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM1-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM2-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM3-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM4-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM5-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM6-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM7-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM8-command-state = "dsi_hs_mode"; + + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-panel-timings = [7d 25 1d 00 37 33 + 22 27 1e 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x0d>; + qcom,mdss-dsi-t-clk-pre = <0x30>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,esd-check-enabled; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 01 0A]; + qcom,mdss-dsi-panel-status-command-mode = "dsi_lp_mode"; + qcom,mdss-dsi-panel-status-check-mode = "TE_check_NT35596"; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-status-value = <0x9C>; + qcom,mdss-dsi-panel-max-error-count = <3>; + qcom,mdss-pan-physical-width-dimension = <69>; + qcom,mdss-pan-physical-height-dimension = <122>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35596-fhd-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35596-fhd-video.dtsi new file mode 100644 index 000000000000..e5580d75c639 --- /dev/null +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35596-fhd-video.dtsi @@ -0,0 +1,93 @@ +/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_nt35596_fhd_vid: qcom,mdss_dsi_nt35596_fhd_video { + qcom,mdss-dsi-panel-name = "nt35596 fhd video mode dsi panel"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <128>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <10>; + qcom,mdss-dsi-v-front-porch = <9>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [29 01 00 00 01 00 02 ff 00 + 29 01 00 00 00 00 02 fb 01 + 29 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 02 36 00 + 29 01 00 00 00 00 02 51 ff + 29 01 00 00 00 00 02 53 2c + 29 01 00 00 00 00 02 55 00 + 29 01 00 00 00 00 02 d3 0C + 29 01 00 00 00 00 02 d4 09 + 29 01 00 00 00 00 02 ff 01 + 29 01 00 00 00 00 02 fb 01 + 29 01 00 00 00 00 02 72 21 + 29 01 00 00 00 00 02 FF 05 + 29 01 00 00 00 00 02 Fb 01 + 29 01 00 00 00 00 02 e7 80 + 29 01 00 00 00 00 02 FF 00 + 29 01 00 00 78 00 02 11 00 + 29 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-CABC_on-command = [29 01 00 00 01 00 02 ff 00 + 29 01 00 00 00 00 02 55 01]; + qcom,mdss-dsi-CABC_off-command = [29 01 00 00 01 00 02 ff 00 + 29 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CABC_on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CABC_off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; //burst_mode non_burst_sync_event + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-t-clk-post = <0x0d>; + qcom,mdss-dsi-t-clk-pre = <0x30>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 5>, <0 5>, <1 5>, <0 5>, <1 20>; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 01 0A]; + qcom,mdss-dsi-panel-status-command-mode = "dsi_lp_mode"; + qcom,mdss-dsi-panel-status-check-mode = "TE_check_NT35596"; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-status-valid-params = <1>; + qcom,mdss-dsi-panel-status-value = <0x9c>; + qcom,mdss-dsi-panel-max-error-count = <3>; + qcom,mdss-pan-physical-width-dimension = <69>; + qcom,mdss-pan-physical-height-dimension = <122>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/dsi-panel-nt35596-tianma-fhd-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-nt35596-tianma-fhd-video.dtsi new file mode 100644 index 000000000000..12c73c75ea62 --- /dev/null +++ b/arch/arm/boot/dts/qcom/dsi-panel-nt35596-tianma-fhd-video.dtsi @@ -0,0 +1,4263 @@ +/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&mdss_mdp { + dsi_nt35596_tianma_fhd_vid: qcom,mdss_dsi_nt35596_tianma_fhd_video { + qcom,mdss-dsi-panel-name = "nt35596 tianma fhd video mode dsi panel"; + qcom,mdss-dsi-panel-type = "dsi_video_mode"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <1920>; + qcom,mdss-dsi-h-front-porch = <96>; + qcom,mdss-dsi-h-back-porch = <64>; + qcom,mdss-dsi-h-pulse-width = <16>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <4>; + qcom,mdss-dsi-v-front-porch = <14>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-on-command = [29 01 00 00 01 00 02 ff 00 + 29 01 00 00 00 00 02 fb 01 + 29 01 00 00 00 00 02 35 00 + 29 01 00 00 00 00 02 36 00 + 29 01 00 00 00 00 02 51 ff + 29 01 00 00 00 00 02 53 2c + 29 01 00 00 00 00 02 55 00 + 29 01 00 00 00 00 02 d3 06 + 29 01 00 00 00 00 02 d4 0e + 29 01 00 00 00 00 02 ff 01 + 29 01 00 00 00 00 02 fb 01 + 29 01 00 00 00 00 02 72 21 + 29 01 00 00 00 00 02 6D 33 + 29 01 00 00 00 00 02 FF 05 + 29 01 00 00 00 00 02 Fb 01 + 29 01 00 00 00 00 02 E7 80 + 29 01 00 00 00 00 02 FF 00 + 29 01 00 00 78 00 02 11 00 + 29 01 00 00 14 00 02 29 00]; + qcom,mdss-dsi-off-command = [29 01 00 00 00 00 02 FF 00 + 05 01 00 00 14 00 02 28 00 + 05 01 00 00 3C 00 02 10 00]; + qcom,mdss-dsi-CABC_on-command = [29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 55 B1]; + qcom,mdss-dsi-CABC_off-command = [29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-CE_off-command = [29 01 00 00 00 00 02 ff 00 + 29 01 00 00 00 00 02 55 00]; + qcom,mdss-dsi-CE_on-command = [23 00 00 00 00 00 02 FF 00 + 23 00 00 00 00 00 02 FB 01 + + 23 00 00 00 00 00 02 55 B0 + 23 00 00 00 00 00 02 FF 03 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 0D + 23 00 00 00 00 00 02 02 15 + 23 00 00 00 00 00 02 03 1C + 23 00 00 00 00 00 02 04 21 + 23 00 00 00 00 00 02 05 26 + 23 00 00 00 00 00 02 06 2B + 23 00 00 00 00 00 02 07 2C + 23 00 00 00 00 00 02 08 2D + 23 00 00 00 00 00 02 09 2D + 23 00 00 00 00 00 02 0A 2D + 23 00 00 00 00 00 02 0B 2D + 23 00 00 00 00 00 02 0C 2C + 23 00 00 00 00 00 02 0D 2A + 23 00 00 00 00 00 02 0E 27 + 23 00 00 00 00 00 02 0F 23 + 23 00 00 00 00 00 02 10 1D + 23 00 00 00 00 00 02 11 17 + 23 00 00 00 00 00 02 12 0B + 23 00 00 00 00 00 02 13 00 + 23 00 00 00 00 00 02 1A 00 + 23 00 00 00 00 00 02 1B 00 + 23 00 00 00 00 00 02 1C 00 + 23 00 00 00 00 00 02 1D 00 + 23 00 00 00 00 00 02 1E 00 + 23 00 00 00 00 00 02 1F 00 + 23 00 00 00 00 00 02 20 00 + 23 00 00 00 00 00 02 21 00 + 23 00 00 00 00 00 02 22 00 + 23 00 00 00 00 00 02 23 00 + 23 00 00 00 00 00 02 24 00 + 23 00 00 00 00 00 02 25 00 + 23 00 00 00 00 00 02 26 00 + 23 00 00 00 00 00 02 27 00 + 23 00 00 00 00 00 02 28 00 + 23 01 00 00 00 00 02 29 00 + + 23 00 00 00 00 00 02 2A 00 + 23 00 00 00 00 00 02 2B 00 + 23 00 00 00 00 00 02 2F 00 + 23 00 00 00 00 00 02 30 00 + 23 00 00 00 00 00 02 31 00 + 23 00 00 00 00 00 02 32 85 + 23 00 00 00 00 00 02 33 07 + 23 00 00 00 00 00 02 34 0A + 23 00 00 00 00 00 02 35 0D + 23 00 00 00 00 00 02 36 12 + 23 00 00 00 00 00 02 37 16 + 23 00 00 00 00 00 02 38 1B + 23 00 00 00 00 00 02 39 1D + 23 00 00 00 00 00 02 3A 1C + 23 00 00 00 00 00 02 3B 1B + 23 00 00 00 00 00 02 3F 18 + 23 00 00 00 00 00 02 40 14 + 23 00 00 00 00 00 02 41 13 + 23 00 00 00 00 00 02 42 12 + 23 00 00 00 00 00 02 43 13 + 23 00 00 00 00 00 02 44 13 + 23 00 00 00 00 00 02 45 11 + 23 00 00 00 00 00 02 46 0D + 23 00 00 00 00 00 02 47 09 + 23 00 00 00 00 00 02 48 07 + 23 00 00 00 00 00 02 49 07 + 23 00 00 00 00 00 02 4A 07 + 23 00 00 00 00 00 02 4B 06 + 23 00 00 00 00 00 02 4C 06 + 23 00 00 00 00 00 02 4D 00 + 23 00 00 00 00 00 02 4E 00 + 23 00 00 00 00 00 02 4F 00 + 23 00 00 00 00 00 02 50 00 + 23 00 00 00 00 00 02 51 00 + 23 00 00 00 00 00 02 52 00 + 23 00 00 00 00 00 02 53 05 + 23 00 00 00 00 00 02 54 04 + 23 00 00 00 00 00 02 55 04 + 23 00 00 00 00 00 02 5B 00 + 23 01 00 00 00 00 02 63 00]; + + qcom,mdss-dsi-cold_gamma-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 F6 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 FE + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 0E + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 1C + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 2A + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 36 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 41 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 4B + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 55 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 77 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 93 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C BE + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E E0 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 14 + 23 00 00 00 00 00 02 91 02 + 23 01 00 00 00 00 02 92 41 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 43 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 71 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 AC + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A D5 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 0C + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 30 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 59 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 6A + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 75 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 84 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 90 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC A3 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE A7 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 A9 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 AD + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 F6 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 FE + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 0E + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 1C + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 2A + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 36 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 41 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 4B + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 55 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 77 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 93 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA BE + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC E0 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 14 + 23 00 00 00 00 00 02 CF 02 + 23 01 00 00 00 00 02 D0 41 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 43 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 71 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 AC + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 D5 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 0C + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 30 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 59 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 6A + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 75 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 84 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 90 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 A3 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA A7 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC A9 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE AD + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 B5 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 C0 + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 D5 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 EA + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 FE + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 11 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 20 + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 2D + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 3A + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 63 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 83 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B B4 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D D9 + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 11 + 23 00 00 00 00 00 02 10 02 + 23 01 00 00 00 00 02 11 40 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 41 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 71 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 AE + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D8 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 0F + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 33 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5F + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 6B + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 79 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 89 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 99 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AF + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C9 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D3 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D4 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 B5 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 C0 + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 D5 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 EA + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B FE + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 11 + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 20 + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 2D + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 3A + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 63 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 83 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B B4 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D D9 + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 11 + 23 00 00 00 00 00 02 50 02 + 23 01 00 00 00 00 02 51 40 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 41 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 71 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 AE + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D8 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 0F + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 33 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5F + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 6B + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 79 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 89 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 99 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AF + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C9 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D3 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D4 + + 23 00 00 00 00 00 02 71 00 + 23 00 00 00 00 00 02 72 3A + 23 00 00 00 00 00 02 73 00 + 23 00 00 00 00 00 02 74 5D + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 8E + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 B2 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A CE + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C E6 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E FA + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 0C + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 1C + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 4E + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 74 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 AA + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A D2 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 0C + 23 00 00 00 00 00 02 8D 02 + 23 01 00 00 00 00 02 8E 3C + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 3D + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 6C + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 A8 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 D1 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 07 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 2B + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 57 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 65 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 77 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 82 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 8A + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 90 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 93 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AC + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D4 + + 23 00 00 00 00 00 02 AF 00 + 23 00 00 00 00 00 02 B0 3A + 23 00 00 00 00 00 02 B1 00 + 23 00 00 00 00 00 02 B2 5D + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 8E + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 B2 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 CE + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA E6 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC FA + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 0C + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 1C + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 4E + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 74 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 AA + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 D2 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 0C + 23 00 00 00 00 00 02 CB 02 + 23 01 00 00 00 00 02 CC 3C + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 3D + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 6C + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 A8 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 D1 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 07 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 2B + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 57 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 65 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 77 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 82 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 8A + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 90 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 93 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AC + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D4]; + + qcom,mdss-dsi-warm_gamma-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 41 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 5B + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 83 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C A3 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E BD + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 D3 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 E7 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 F9 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 09 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 3B + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 61 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 99 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C2 + 23 00 00 00 00 00 02 8F 01 + 23 00 00 00 00 00 02 90 FE + 23 00 00 00 00 00 02 91 02 + 23 01 00 00 00 00 02 92 2D + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 2F + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 5C + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 94 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A BB + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C EF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 12 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 40 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 4E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 5D + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 70 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 7F + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC 99 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C0 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D2 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D4 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 41 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 5B + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 83 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA A3 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC BD + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE D3 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 E7 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 F9 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 09 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 3B + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 61 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 99 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C2 + 23 00 00 00 00 00 02 CD 01 + 23 00 00 00 00 00 02 CE FE + 23 00 00 00 00 00 02 CF 02 + 23 01 00 00 00 00 02 D0 2D + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 2F + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 5C + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 94 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 BB + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA EF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 12 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 40 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 4E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 5D + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 70 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 7F + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 99 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C0 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D2 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D4 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 EA + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 F3 + 23 00 00 00 00 00 02 F3 01 + 23 00 00 00 00 00 02 F4 03 + 23 00 00 00 00 00 02 F5 01 + 23 00 00 00 00 00 02 F6 12 + 23 00 00 00 00 00 02 F7 01 + 23 00 00 00 00 00 02 F8 1F + 23 00 00 00 00 00 02 F9 01 + 23 00 00 00 00 00 02 FA 2B + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 01 + 23 00 00 00 00 00 02 01 36 + 23 00 00 00 00 00 02 02 01 + 23 00 00 00 00 00 02 03 41 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 4B + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 6D + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 89 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B B4 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D D7 + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 0B + 23 00 00 00 00 00 02 10 02 + 23 01 00 00 00 00 02 11 38 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 39 + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 66 + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 9F + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 C5 + 23 00 00 00 00 00 02 1A 02 + 23 00 00 00 00 00 02 1B FA + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 1D + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 49 + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 55 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 64 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 73 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 85 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 9C + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B B4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D0 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D2 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 EA + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 F3 + 23 00 00 00 00 00 02 36 01 + 23 00 00 00 00 00 02 37 03 + 23 00 00 00 00 00 02 38 01 + 23 00 00 00 00 00 02 39 12 + 23 00 00 00 00 00 02 3A 01 + 23 00 00 00 00 00 02 3B 1F + 23 00 00 00 00 00 02 3D 01 + 23 00 00 00 00 00 02 3F 2B + 23 00 00 00 00 00 02 40 01 + 23 00 00 00 00 00 02 41 36 + 23 00 00 00 00 00 02 42 01 + 23 00 00 00 00 00 02 43 41 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 4B + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 6D + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 89 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B B4 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D D7 + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 0B + 23 00 00 00 00 00 02 50 02 + 23 01 00 00 00 00 02 51 38 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 39 + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 66 + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 9F + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A C5 + 23 00 00 00 00 00 02 5B 02 + 23 00 00 00 00 00 02 5C FA + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 1D + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 49 + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 55 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 64 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 73 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 85 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A 9C + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C B4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D0 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D2 + + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 3A + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 3F + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 49 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 52 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 5B + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 63 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 6A + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 72 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 79 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 92 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 A8 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 CB + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A E8 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 16 + 23 00 00 00 00 00 02 8D 02 + 23 01 00 00 00 00 02 8E 3F + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 40 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 6B + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 A1 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 C7 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 FA + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 1C + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 47 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 53 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 5F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 6B + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 82 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 86 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA AC + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B2 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D4 + + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 3A + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 3F + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 49 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 52 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 5B + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 63 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 6A + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 72 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 79 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 92 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 A8 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 CB + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 E8 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 16 + 23 00 00 00 00 00 02 CB 02 + 23 01 00 00 00 00 02 CC 3F + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 40 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 6B + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 A1 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 C7 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 FA + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 1C + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 47 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 53 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 5F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 6B + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 82 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 86 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 AC + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B2 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D4]; + + qcom,mdss-dsi-default_gamma-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 2D + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 6A + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 93 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E B3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 CF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 E5 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 F9 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 0B + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 41 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 69 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C A4 + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E CD + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 0A + 23 00 00 00 00 00 02 91 02 + 23 01 00 00 00 00 02 92 3A + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 3C + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 6B + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A8 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A D1 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 08 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 2E + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 58 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 65 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 6F + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 7B + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 85 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC 8B + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE 8F + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 A1 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 B2 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 2D + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 6A + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 93 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC B3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE CF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 E5 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 F9 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 0B + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 41 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 69 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA A4 + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC CD + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 0A + 23 00 00 00 00 00 02 CF 02 + 23 01 00 00 00 00 02 D0 3A + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 3C + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 6B + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A8 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 D1 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 08 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 2E + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 58 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 65 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 6F + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 7B + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 85 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 8B + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA 8F + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC A1 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE B2 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2B + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 69 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 94 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 B5 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA D0 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 E7 + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 FB + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 0C + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 43 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 6C + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A5 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D D1 + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 0F + 23 00 00 00 00 00 02 10 02 + 23 01 00 00 00 00 02 11 3D + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3E + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6E + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 AC + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D5 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 0D + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 30 + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 74 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 81 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 90 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 9F + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B AC + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F AF + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 B2 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2B + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 69 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 94 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B B5 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F D0 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 E7 + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 FB + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 0C + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 43 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 6C + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A5 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D D1 + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 0F + 23 00 00 00 00 00 02 50 02 + 23 01 00 00 00 00 02 51 3D + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3E + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6E + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 AC + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D5 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 0D + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 30 + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 74 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 81 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 90 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A 9F + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C AC + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E AF + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 B2 + + 23 00 00 00 00 00 02 71 00 + 23 00 00 00 00 00 02 72 00 + 23 00 00 00 00 00 02 73 00 + 23 00 00 00 00 00 02 74 34 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 75 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 A1 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A C1 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C DB + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E F2 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 04 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 15 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 4C + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 72 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 AF + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A D7 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 11 + 23 00 00 00 00 00 02 8D 02 + 23 01 00 00 00 00 02 8E 3F + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 40 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 6E + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 AB + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 D1 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 07 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 2B + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 58 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 64 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 78 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 A3 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 AA + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 AE + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA BF + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC B1 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE B2 + + 23 00 00 00 00 00 02 AF 00 + 23 00 00 00 00 00 02 B0 00 + 23 00 00 00 00 00 02 B1 00 + 23 00 00 00 00 00 02 B2 34 + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 75 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 A1 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 C1 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA DB + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC F2 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 04 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 15 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 4C + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 72 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 AF + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 D7 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 11 + 23 00 00 00 00 00 02 CB 02 + 23 01 00 00 00 00 02 CC 3F + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 40 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 6E + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 AB + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 D1 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 07 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 2B + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 58 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 64 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 78 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 A3 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 AA + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 AE + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 AF + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 B1 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA B2]; + + qcom,mdss-dsi-PM1-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 22 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 5E + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 8A + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E AC + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C7 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DE + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 F2 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 04 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 3B + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 64 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9F + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E CA + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 06 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 37 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 38 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 68 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A4 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 2A + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 92 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC A8 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C1 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D6 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 22 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 5E + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 8A + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC AC + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C7 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DE + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 F2 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 04 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 3B + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 64 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9F + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC CA + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 06 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 37 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 38 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 68 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A4 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 2A + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 92 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 A8 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C1 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D6 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 31 + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 69 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 92 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 B2 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA CC + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 E3 + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 F7 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 08 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 3F + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 68 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A3 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CD + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 0A + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 3A + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3C + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6C + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A9 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D4 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 85 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 97 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AC + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 31 + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 69 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 92 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B B2 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F CC + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 E3 + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 F7 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 08 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 3F + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 68 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A3 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CD + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 0A + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 3A + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3C + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6C + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A9 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D4 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 85 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 97 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AC + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 00 + 23 00 00 00 00 00 02 72 FF + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 08 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 17 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 25 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 32 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 3E + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 49 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 53 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 5D + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 7E + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 99 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 C4 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A E5 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 17 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 44 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 45 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 73 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 AD + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 D7 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 07 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 32 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 5E + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 6C + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 7A + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 8A + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 9D + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 B2 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA C8 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 00 + 23 00 00 00 00 00 02 B0 FF + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 08 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 17 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 25 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 32 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 3E + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 49 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 53 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 5D + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 7E + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 99 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 C4 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 E5 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 17 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 44 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 45 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 73 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 AD + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 D7 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 07 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 32 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 5E + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 6C + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 7A + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 8A + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 9D + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 B2 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 C8 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM2-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 22 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 5E + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 8A + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E AC + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 C7 + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 DE + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 F2 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 04 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 3B + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 64 + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9F + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E CA + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 06 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 37 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 38 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 68 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A4 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 2A + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 92 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC A8 + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C1 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D6 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 22 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 5E + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 8A + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC AC + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE C7 + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 DE + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 F2 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 04 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 3B + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 64 + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9F + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC CA + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 06 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 37 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 38 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 68 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A4 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 2A + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 92 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 A8 + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C1 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D6 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 31 + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 69 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 92 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 B2 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA CC + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 E3 + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 F7 + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 08 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 3F + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 68 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B A3 + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CD + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 0A + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 3A + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3C + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6C + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A9 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D4 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 85 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 97 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AC + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C4 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 31 + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 69 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 92 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B B2 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F CC + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 E3 + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 F7 + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 08 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 3F + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 68 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B A3 + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CD + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 0A + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 3A + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3C + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6C + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A9 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D4 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 85 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 97 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AC + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C4 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 59 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 5D + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 66 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 6E + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 76 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C 7D + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E 84 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 8A + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 91 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 A8 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 BB + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 DD + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A F6 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 24 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 4D + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 4F + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 7B + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 B6 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 DF + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 0D + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 39 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 64 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 71 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 7F + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 8E + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 A1 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 B5 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA CA + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 59 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 5D + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 66 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 6E + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 76 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA 7D + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC 84 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE 8A + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 91 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 A8 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 BB + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 DD + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 F6 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 24 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 4D + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 4F + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 7B + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 B6 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 DF + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 0D + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 39 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 64 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 71 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 7F + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 8E + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 A1 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 B5 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 CA + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM3-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 21 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 58 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 82 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E A3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 BF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D6 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EA + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 FC + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 34 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 5E + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9B + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 36 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 37 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 67 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A3 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 29 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D7 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 21 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 58 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 82 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC A3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE BF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D6 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EA + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 FC + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 34 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 5E + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9B + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 36 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 37 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 67 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A3 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 29 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D7 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2E + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 62 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 89 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 A9 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA C4 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 DB + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 EE + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 00 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 38 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 62 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B 9E + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 39 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6B + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A8 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D3 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 86 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 98 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AD + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2E + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 62 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 89 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B A9 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F C4 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 DB + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 EE + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 00 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 38 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 62 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B 9E + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 39 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6B + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A8 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D3 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 86 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 98 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AD + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 8B + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 8E + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 94 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 99 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A 9F + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C A4 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E A9 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 AE + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 B3 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 C4 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 D4 + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 F0 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 06 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 2F + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 56 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 58 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 83 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 BE + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 E6 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 12 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 3D + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 68 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 76 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 85 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 97 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 AA + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 BE + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA CE + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 8B + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 8E + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 94 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 99 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 9F + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA A4 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC A9 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE AE + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 B3 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 C4 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 D4 + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 F0 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 06 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 2F + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 56 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 58 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 83 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 BE + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 E6 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 12 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 3D + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 68 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 76 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 85 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 97 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 AA + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 BE + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 CE + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM4-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 21 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 58 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 82 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E A3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 BF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D6 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EA + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 FC + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 34 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 5E + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9B + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 36 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 37 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 67 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A3 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 29 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D7 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 21 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 58 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 82 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC A3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE BF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D6 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EA + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 FC + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 34 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 5E + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9B + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 36 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 37 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 67 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A3 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 29 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D7 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2E + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 62 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 89 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 A9 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA C4 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 DB + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 EE + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 00 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 38 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 62 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B 9E + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 39 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6B + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A8 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D3 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 86 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 98 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AD + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2E + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 62 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 89 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B A9 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F C4 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 DB + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 EE + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 00 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 38 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 62 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B 9E + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 39 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6B + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A8 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D3 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 86 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 98 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AD + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 B2 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 B4 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 B9 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 BD + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A C1 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C C5 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E C9 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 CC + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 D0 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 DE + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 EB + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 01 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 15 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 3A + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 60 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 61 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 8B + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 C6 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 ED + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 23 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 44 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 6E + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 7B + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 8A + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 9B + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 AE + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 C0 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA CF + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 B2 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 B4 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 B9 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 BD + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 C1 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA C5 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC C9 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE CC + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 D0 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 DE + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 EB + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 01 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 15 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 3A + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 60 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 61 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 8B + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 C6 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 ED + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 23 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 44 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 6E + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 7B + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 8A + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 9B + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 AE + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 C0 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 CF + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM5-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 21 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 58 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 82 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E A3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 BF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D6 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EA + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 FC + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 34 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 5E + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9B + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 36 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 37 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 67 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A3 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 29 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D7 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 21 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 58 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 82 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC A3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE BF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D6 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EA + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 FC + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 34 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 5E + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9B + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 36 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 37 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 67 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A3 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 29 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D7 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2E + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 62 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 89 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 A9 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA C4 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 DB + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 EE + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 00 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 38 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 62 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B 9E + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 39 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6B + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A8 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D3 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 86 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 98 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AD + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2E + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 62 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 89 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B A9 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F C4 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 DB + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 EE + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 00 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 38 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 62 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B 9E + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 39 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6B + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A8 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D3 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 86 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 98 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AD + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 D0 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 D2 + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 D5 + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 D8 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A DC + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C DF + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E E2 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 E5 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 E8 + 23 00 00 00 00 00 02 83 01 + 23 00 00 00 00 00 02 84 F3 + 23 00 00 00 00 00 02 85 01 + 23 00 00 00 00 00 02 86 FD + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 10 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 22 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 45 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 69 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 6A + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 94 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 CF + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 F4 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 2A + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 4A + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 74 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 81 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 90 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 A0 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 B2 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 C3 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA D0 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 D0 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 D2 + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 D5 + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 D8 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 DC + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA DF + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC E2 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE E5 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 E8 + 23 00 00 00 00 00 02 C1 01 + 23 00 00 00 00 00 02 C2 F3 + 23 00 00 00 00 00 02 C3 01 + 23 00 00 00 00 00 02 C4 FD + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 10 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 22 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 45 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 69 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 6A + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 94 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 CF + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 F4 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 2A + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 4A + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 74 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 81 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 90 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 A0 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 B2 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 C3 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 D0 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM6-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 21 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 58 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 82 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E A3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 BF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D6 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EA + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 FC + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 34 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 5E + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9B + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 36 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 37 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 67 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A3 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 29 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D7 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 21 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 58 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 82 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC A3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE BF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D6 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EA + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 FC + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 34 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 5E + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9B + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 36 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 37 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 67 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A3 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 29 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D7 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2E + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 62 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 89 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 A9 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA C4 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 DB + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 EE + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 00 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 38 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 62 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B 9E + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 39 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6B + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A8 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D3 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 86 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 98 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AD + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2E + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 62 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 89 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B A9 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F C4 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 DB + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 EE + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 00 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 38 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 62 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B 9E + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 39 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6B + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A8 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D3 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 86 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 98 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AD + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 01 + 23 00 00 00 00 00 02 72 E9 + 23 00 00 00 00 00 02 73 01 + 23 00 00 00 00 00 02 74 EA + 23 00 00 00 00 00 02 75 01 + 23 00 00 00 00 00 02 76 ED + 23 00 00 00 00 00 02 77 01 + 23 00 00 00 00 00 02 78 F0 + 23 00 00 00 00 00 02 79 01 + 23 00 00 00 00 00 02 7A F2 + 23 00 00 00 00 00 02 7B 01 + 23 00 00 00 00 00 02 7C F4 + 23 00 00 00 00 00 02 7D 01 + 23 00 00 00 00 00 02 7E F6 + 23 00 00 00 00 00 02 7F 01 + 23 00 00 00 00 00 02 80 F9 + 23 00 00 00 00 00 02 81 01 + 23 00 00 00 00 00 02 82 FB + 23 00 00 00 00 00 02 83 02 + 23 00 00 00 00 00 02 84 05 + 23 00 00 00 00 00 02 85 02 + 23 00 00 00 00 00 02 86 0E + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 1F + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 2F + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 50 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 72 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 74 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 9D + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 D8 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 FA + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 31 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 51 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 7A + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 87 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 95 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 A5 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 B6 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 C5 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA D1 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 01 + 23 00 00 00 00 00 02 B0 E9 + 23 00 00 00 00 00 02 B1 01 + 23 00 00 00 00 00 02 B2 EA + 23 00 00 00 00 00 02 B3 01 + 23 00 00 00 00 00 02 B4 ED + 23 00 00 00 00 00 02 B5 01 + 23 00 00 00 00 00 02 B6 F0 + 23 00 00 00 00 00 02 B7 01 + 23 00 00 00 00 00 02 B8 F2 + 23 00 00 00 00 00 02 B9 01 + 23 00 00 00 00 00 02 BA F4 + 23 00 00 00 00 00 02 BB 01 + 23 00 00 00 00 00 02 BC F6 + 23 00 00 00 00 00 02 BD 01 + 23 00 00 00 00 00 02 BE F9 + 23 00 00 00 00 00 02 BF 01 + 23 00 00 00 00 00 02 C0 FB + 23 00 00 00 00 00 02 C1 02 + 23 00 00 00 00 00 02 C2 05 + 23 00 00 00 00 00 02 C3 02 + 23 00 00 00 00 00 02 C4 0E + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 1F + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 2F + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 50 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 72 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 74 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 9D + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 D8 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 FA + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 31 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 51 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 7A + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 87 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 95 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 A5 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 B6 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 C5 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 D1 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM7-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 21 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 58 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 82 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E A3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 BF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D6 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EA + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 FC + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 34 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 5E + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9B + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 36 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 37 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 67 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A3 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 29 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D7 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 21 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 58 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 82 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC A3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE BF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D6 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EA + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 FC + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 34 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 5E + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9B + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 36 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 37 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 67 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A3 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 29 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D7 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2E + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 62 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 89 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 A9 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA C4 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 DB + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 EE + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 00 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 38 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 62 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B 9E + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 39 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6B + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A8 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D3 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 86 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 98 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AD + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2E + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 62 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 89 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B A9 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F C4 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 DB + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 EE + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 00 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 38 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 62 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B 9E + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 39 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6B + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A8 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D3 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 86 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 98 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AD + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 02 + 23 00 00 00 00 00 02 72 00 + 23 00 00 00 00 00 02 73 02 + 23 00 00 00 00 00 02 74 01 + 23 00 00 00 00 00 02 75 02 + 23 00 00 00 00 00 02 76 03 + 23 00 00 00 00 00 02 77 02 + 23 00 00 00 00 00 02 78 05 + 23 00 00 00 00 00 02 79 02 + 23 00 00 00 00 00 02 7A 08 + 23 00 00 00 00 00 02 7B 02 + 23 00 00 00 00 00 02 7C 0A + 23 00 00 00 00 00 02 7D 02 + 23 00 00 00 00 00 02 7E 0C + 23 00 00 00 00 00 02 7F 02 + 23 00 00 00 00 00 02 80 0E + 23 00 00 00 00 00 02 81 02 + 23 00 00 00 00 00 02 82 10 + 23 00 00 00 00 00 02 83 02 + 23 00 00 00 00 00 02 84 18 + 23 00 00 00 00 00 02 85 02 + 23 00 00 00 00 00 02 86 20 + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 30 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 40 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 60 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 80 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 81 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 A8 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 E2 + 23 00 00 00 00 00 02 95 03 + 23 00 00 00 00 00 02 96 02 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 39 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 58 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 81 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 8D + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 9C + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 AB + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 BA + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 C8 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA D3 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 02 + 23 00 00 00 00 00 02 B0 00 + 23 00 00 00 00 00 02 B1 02 + 23 00 00 00 00 00 02 B2 01 + 23 00 00 00 00 00 02 B3 02 + 23 00 00 00 00 00 02 B4 03 + 23 00 00 00 00 00 02 B5 02 + 23 00 00 00 00 00 02 B6 05 + 23 00 00 00 00 00 02 B7 02 + 23 00 00 00 00 00 02 B8 08 + 23 00 00 00 00 00 02 B9 02 + 23 00 00 00 00 00 02 BA 0A + 23 00 00 00 00 00 02 BB 02 + 23 00 00 00 00 00 02 BC 0C + 23 00 00 00 00 00 02 BD 02 + 23 00 00 00 00 00 02 BE 0E + 23 00 00 00 00 00 02 BF 02 + 23 00 00 00 00 00 02 C0 10 + 23 00 00 00 00 00 02 C1 02 + 23 00 00 00 00 00 02 C2 18 + 23 00 00 00 00 00 02 C3 02 + 23 00 00 00 00 00 02 C4 20 + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 30 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 40 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 60 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 80 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 81 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 A8 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 E2 + 23 00 00 00 00 00 02 D3 03 + 23 00 00 00 00 00 02 D4 02 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 39 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 58 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 81 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 8D + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 9C + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 AB + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 BA + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 C8 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 D3 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-PM8-command = [23 00 00 00 00 00 02 FF 01 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 75 00 + 23 00 00 00 00 00 02 76 00 + 23 00 00 00 00 00 02 77 00 + 23 00 00 00 00 00 02 78 21 + 23 00 00 00 00 00 02 79 00 + 23 00 00 00 00 00 02 7A 58 + 23 00 00 00 00 00 02 7B 00 + 23 00 00 00 00 00 02 7C 82 + 23 00 00 00 00 00 02 7D 00 + 23 00 00 00 00 00 02 7E A3 + 23 00 00 00 00 00 02 7F 00 + 23 00 00 00 00 00 02 80 BF + 23 00 00 00 00 00 02 81 00 + 23 00 00 00 00 00 02 82 D6 + 23 00 00 00 00 00 02 83 00 + 23 00 00 00 00 00 02 84 EA + 23 00 00 00 00 00 02 85 00 + 23 00 00 00 00 00 02 86 FC + 23 00 00 00 00 00 02 87 01 + 23 00 00 00 00 00 02 88 34 + 23 00 00 00 00 00 02 89 01 + 23 00 00 00 00 00 02 8A 5E + 23 00 00 00 00 00 02 8B 01 + 23 00 00 00 00 00 02 8C 9B + 23 00 00 00 00 00 02 8D 01 + 23 00 00 00 00 00 02 8E C7 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 05 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 36 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 37 + 23 00 00 00 00 00 02 95 02 + 23 00 00 00 00 00 02 96 67 + 23 00 00 00 00 00 02 97 02 + 23 00 00 00 00 00 02 98 A3 + 23 00 00 00 00 00 02 99 02 + 23 00 00 00 00 00 02 9A CE + 23 00 00 00 00 00 02 9B 02 + 23 00 00 00 00 00 02 9C FF + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 29 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 56 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 63 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 71 + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 81 + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA 94 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC AA + 23 00 00 00 00 00 02 AD 03 + 23 00 00 00 00 00 02 AE C4 + 23 00 00 00 00 00 02 AF 03 + 23 00 00 00 00 00 02 B0 D7 + 23 00 00 00 00 00 02 B1 03 + 23 01 00 00 00 00 02 B2 D9 + + 23 00 00 00 00 00 02 B3 00 + 23 00 00 00 00 00 02 B4 00 + 23 00 00 00 00 00 02 B5 00 + 23 00 00 00 00 00 02 B6 21 + 23 00 00 00 00 00 02 B7 00 + 23 00 00 00 00 00 02 B8 58 + 23 00 00 00 00 00 02 B9 00 + 23 00 00 00 00 00 02 BA 82 + 23 00 00 00 00 00 02 BB 00 + 23 00 00 00 00 00 02 BC A3 + 23 00 00 00 00 00 02 BD 00 + 23 00 00 00 00 00 02 BE BF + 23 00 00 00 00 00 02 BF 00 + 23 00 00 00 00 00 02 C0 D6 + 23 00 00 00 00 00 02 C1 00 + 23 00 00 00 00 00 02 C2 EA + 23 00 00 00 00 00 02 C3 00 + 23 00 00 00 00 00 02 C4 FC + 23 00 00 00 00 00 02 C5 01 + 23 00 00 00 00 00 02 C6 34 + 23 00 00 00 00 00 02 C7 01 + 23 00 00 00 00 00 02 C8 5E + 23 00 00 00 00 00 02 C9 01 + 23 00 00 00 00 00 02 CA 9B + 23 00 00 00 00 00 02 CB 01 + 23 00 00 00 00 00 02 CC C7 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 05 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 36 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 37 + 23 00 00 00 00 00 02 D3 02 + 23 00 00 00 00 00 02 D4 67 + 23 00 00 00 00 00 02 D5 02 + 23 00 00 00 00 00 02 D6 A3 + 23 00 00 00 00 00 02 D7 02 + 23 00 00 00 00 00 02 D8 CE + 23 00 00 00 00 00 02 D9 02 + 23 00 00 00 00 00 02 DA FF + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 29 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE 56 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 63 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 71 + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 81 + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 94 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 AA + 23 00 00 00 00 00 02 E9 03 + 23 00 00 00 00 00 02 EA C4 + 23 00 00 00 00 00 02 EB 03 + 23 00 00 00 00 00 02 EC D7 + 23 00 00 00 00 00 02 ED 03 + 23 01 00 00 00 00 02 EE D9 + + 23 00 00 00 00 00 02 EF 00 + 23 00 00 00 00 00 02 F0 00 + 23 00 00 00 00 00 02 F1 00 + 23 00 00 00 00 00 02 F2 2E + 23 00 00 00 00 00 02 F3 00 + 23 00 00 00 00 00 02 F4 62 + 23 00 00 00 00 00 02 F5 00 + 23 00 00 00 00 00 02 F6 89 + 23 00 00 00 00 00 02 F7 00 + 23 00 00 00 00 00 02 F8 A9 + 23 00 00 00 00 00 02 F9 00 + 23 00 00 00 00 00 02 FA C4 + 23 00 00 00 00 00 02 FF 02 + 23 00 00 00 00 00 02 FB 01 + 23 00 00 00 00 00 02 00 00 + 23 00 00 00 00 00 02 01 DB + 23 00 00 00 00 00 02 02 00 + 23 00 00 00 00 00 02 03 EE + 23 00 00 00 00 00 02 04 01 + 23 00 00 00 00 00 02 05 00 + 23 00 00 00 00 00 02 06 01 + 23 00 00 00 00 00 02 07 38 + 23 00 00 00 00 00 02 08 01 + 23 00 00 00 00 00 02 09 62 + 23 00 00 00 00 00 02 0A 01 + 23 00 00 00 00 00 02 0B 9E + 23 00 00 00 00 00 02 0C 01 + 23 00 00 00 00 00 02 0D CA + 23 00 00 00 00 00 02 0E 02 + 23 00 00 00 00 00 02 0F 09 + 23 00 00 00 00 00 02 10 02 + 23 00 00 00 00 00 02 11 39 + 23 00 00 00 00 00 02 12 02 + 23 00 00 00 00 00 02 13 3B + 23 00 00 00 00 00 02 14 02 + 23 00 00 00 00 00 02 15 6B + 23 00 00 00 00 00 02 16 02 + 23 00 00 00 00 00 02 17 A8 + 23 00 00 00 00 00 02 18 02 + 23 00 00 00 00 00 02 19 D3 + 23 00 00 00 00 00 02 1A 03 + 23 00 00 00 00 00 02 1B 04 + 23 00 00 00 00 00 02 1C 03 + 23 00 00 00 00 00 02 1D 2F + 23 00 00 00 00 00 02 1E 03 + 23 00 00 00 00 00 02 1F 5B + 23 00 00 00 00 00 02 20 03 + 23 00 00 00 00 00 02 21 68 + 23 00 00 00 00 00 02 22 03 + 23 00 00 00 00 00 02 23 76 + 23 00 00 00 00 00 02 24 03 + 23 00 00 00 00 00 02 25 86 + 23 00 00 00 00 00 02 26 03 + 23 00 00 00 00 00 02 27 98 + 23 00 00 00 00 00 02 28 03 + 23 00 00 00 00 00 02 29 AD + 23 00 00 00 00 00 02 2A 03 + 23 00 00 00 00 00 02 2B C5 + 23 00 00 00 00 00 02 2D 03 + 23 00 00 00 00 00 02 2F D7 + 23 00 00 00 00 00 02 30 03 + 23 01 00 00 00 00 02 31 D9 + + 23 00 00 00 00 00 02 32 00 + 23 00 00 00 00 00 02 33 00 + 23 00 00 00 00 00 02 34 00 + 23 00 00 00 00 00 02 35 2E + 23 00 00 00 00 00 02 36 00 + 23 00 00 00 00 00 02 37 62 + 23 00 00 00 00 00 02 38 00 + 23 00 00 00 00 00 02 39 89 + 23 00 00 00 00 00 02 3A 00 + 23 00 00 00 00 00 02 3B A9 + 23 00 00 00 00 00 02 3D 00 + 23 00 00 00 00 00 02 3F C4 + 23 00 00 00 00 00 02 40 00 + 23 00 00 00 00 00 02 41 DB + 23 00 00 00 00 00 02 42 00 + 23 00 00 00 00 00 02 43 EE + 23 00 00 00 00 00 02 44 01 + 23 00 00 00 00 00 02 45 00 + 23 00 00 00 00 00 02 46 01 + 23 00 00 00 00 00 02 47 38 + 23 00 00 00 00 00 02 48 01 + 23 00 00 00 00 00 02 49 62 + 23 00 00 00 00 00 02 4A 01 + 23 00 00 00 00 00 02 4B 9E + 23 00 00 00 00 00 02 4C 01 + 23 00 00 00 00 00 02 4D CA + 23 00 00 00 00 00 02 4E 02 + 23 00 00 00 00 00 02 4F 09 + 23 00 00 00 00 00 02 50 02 + 23 00 00 00 00 00 02 51 39 + 23 00 00 00 00 00 02 52 02 + 23 00 00 00 00 00 02 53 3B + 23 00 00 00 00 00 02 54 02 + 23 00 00 00 00 00 02 55 6B + 23 00 00 00 00 00 02 56 02 + 23 00 00 00 00 00 02 58 A8 + 23 00 00 00 00 00 02 59 02 + 23 00 00 00 00 00 02 5A D3 + 23 00 00 00 00 00 02 5B 03 + 23 00 00 00 00 00 02 5C 04 + 23 00 00 00 00 00 02 5D 03 + 23 00 00 00 00 00 02 5E 2F + 23 00 00 00 00 00 02 5F 03 + 23 00 00 00 00 00 02 60 5B + 23 00 00 00 00 00 02 61 03 + 23 00 00 00 00 00 02 62 68 + 23 00 00 00 00 00 02 63 03 + 23 00 00 00 00 00 02 64 76 + 23 00 00 00 00 00 02 65 03 + 23 00 00 00 00 00 02 66 86 + 23 00 00 00 00 00 02 67 03 + 23 00 00 00 00 00 02 68 98 + 23 00 00 00 00 00 02 69 03 + 23 00 00 00 00 00 02 6A AD + 23 00 00 00 00 00 02 6B 03 + 23 00 00 00 00 00 02 6C C5 + 23 00 00 00 00 00 02 6D 03 + 23 00 00 00 00 00 02 6E D7 + 23 00 00 00 00 00 02 6F 03 + 23 01 00 00 00 00 02 70 D9 + + 23 00 00 00 00 00 02 71 02 + 23 00 00 00 00 00 02 72 14 + 23 00 00 00 00 00 02 73 02 + 23 00 00 00 00 00 02 74 15 + 23 00 00 00 00 00 02 75 02 + 23 00 00 00 00 00 02 76 17 + 23 00 00 00 00 00 02 77 02 + 23 00 00 00 00 00 02 78 19 + 23 00 00 00 00 00 02 79 02 + 23 00 00 00 00 00 02 7A 1B + 23 00 00 00 00 00 02 7B 02 + 23 00 00 00 00 00 02 7C 1D + 23 00 00 00 00 00 02 7D 02 + 23 00 00 00 00 00 02 7E 1F + 23 00 00 00 00 00 02 7F 02 + 23 00 00 00 00 00 02 80 21 + 23 00 00 00 00 00 02 81 02 + 23 00 00 00 00 00 02 82 23 + 23 00 00 00 00 00 02 83 02 + 23 00 00 00 00 00 02 84 2B + 23 00 00 00 00 00 02 85 02 + 23 00 00 00 00 00 02 86 33 + 23 00 00 00 00 00 02 87 02 + 23 00 00 00 00 00 02 88 43 + 23 00 00 00 00 00 02 89 02 + 23 00 00 00 00 00 02 8A 53 + 23 00 00 00 00 00 02 8B 02 + 23 00 00 00 00 00 02 8C 73 + 23 00 00 00 00 00 02 8D 02 + 23 00 00 00 00 00 02 8E 93 + 23 00 00 00 00 00 02 8F 02 + 23 00 00 00 00 00 02 90 94 + 23 00 00 00 00 00 02 91 02 + 23 00 00 00 00 00 02 92 B4 + 23 00 00 00 00 00 02 93 02 + 23 00 00 00 00 00 02 94 EB + 23 00 00 00 00 00 02 95 03 + 23 00 00 00 00 00 02 96 09 + 23 00 00 00 00 00 02 97 03 + 23 00 00 00 00 00 02 98 42 + 23 00 00 00 00 00 02 99 03 + 23 00 00 00 00 00 02 9A 60 + 23 00 00 00 00 00 02 9B 03 + 23 00 00 00 00 00 02 9C 88 + 23 00 00 00 00 00 02 9D 03 + 23 00 00 00 00 00 02 9E 94 + 23 00 00 00 00 00 02 9F 03 + 23 00 00 00 00 00 02 A0 A2 + 23 00 00 00 00 00 02 A2 03 + 23 00 00 00 00 00 02 A3 B0 + 23 00 00 00 00 00 02 A4 03 + 23 00 00 00 00 00 02 A5 BE + 23 00 00 00 00 00 02 A6 03 + 23 00 00 00 00 00 02 A7 CA + 23 00 00 00 00 00 02 A9 03 + 23 00 00 00 00 00 02 AA D3 + 23 00 00 00 00 00 02 AB 03 + 23 00 00 00 00 00 02 AC D7 + 23 00 00 00 00 00 02 AD 03 + 23 01 00 00 00 00 02 AE D9 + + 23 00 00 00 00 00 02 AF 02 + 23 00 00 00 00 00 02 B0 14 + 23 00 00 00 00 00 02 B1 02 + 23 00 00 00 00 00 02 B2 15 + 23 00 00 00 00 00 02 B3 02 + 23 00 00 00 00 00 02 B4 17 + 23 00 00 00 00 00 02 B5 02 + 23 00 00 00 00 00 02 B6 19 + 23 00 00 00 00 00 02 B7 02 + 23 00 00 00 00 00 02 B8 1B + 23 00 00 00 00 00 02 B9 02 + 23 00 00 00 00 00 02 BA 1D + 23 00 00 00 00 00 02 BB 02 + 23 00 00 00 00 00 02 BC 1F + 23 00 00 00 00 00 02 BD 02 + 23 00 00 00 00 00 02 BE 21 + 23 00 00 00 00 00 02 BF 02 + 23 00 00 00 00 00 02 C0 23 + 23 00 00 00 00 00 02 C1 02 + 23 00 00 00 00 00 02 C2 2B + 23 00 00 00 00 00 02 C3 02 + 23 00 00 00 00 00 02 C4 33 + 23 00 00 00 00 00 02 C5 02 + 23 00 00 00 00 00 02 C6 43 + 23 00 00 00 00 00 02 C7 02 + 23 00 00 00 00 00 02 C8 53 + 23 00 00 00 00 00 02 C9 02 + 23 00 00 00 00 00 02 CA 73 + 23 00 00 00 00 00 02 CB 02 + 23 00 00 00 00 00 02 CC 93 + 23 00 00 00 00 00 02 CD 02 + 23 00 00 00 00 00 02 CE 94 + 23 00 00 00 00 00 02 CF 02 + 23 00 00 00 00 00 02 D0 B4 + 23 00 00 00 00 00 02 D1 02 + 23 00 00 00 00 00 02 D2 EB + 23 00 00 00 00 00 02 D3 03 + 23 00 00 00 00 00 02 D4 09 + 23 00 00 00 00 00 02 D5 03 + 23 00 00 00 00 00 02 D6 42 + 23 00 00 00 00 00 02 D7 03 + 23 00 00 00 00 00 02 D8 60 + 23 00 00 00 00 00 02 D9 03 + 23 00 00 00 00 00 02 DA 88 + 23 00 00 00 00 00 02 DB 03 + 23 00 00 00 00 00 02 DC 94 + 23 00 00 00 00 00 02 DD 03 + 23 00 00 00 00 00 02 DE A2 + 23 00 00 00 00 00 02 DF 03 + 23 00 00 00 00 00 02 E0 B0 + 23 00 00 00 00 00 02 E1 03 + 23 00 00 00 00 00 02 E2 BE + 23 00 00 00 00 00 02 E3 03 + 23 00 00 00 00 00 02 E4 CA + 23 00 00 00 00 00 02 E5 03 + 23 00 00 00 00 00 02 E6 D3 + 23 00 00 00 00 00 02 E7 03 + 23 00 00 00 00 00 02 E8 D7 + 23 00 00 00 00 00 02 E9 03 + 23 01 00 00 00 00 02 EA D9]; + + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CABC_on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CABC_off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CE_on-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-CE_off-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-cold_gamma-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-warm_gamma-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-default_gamma-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM1-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM2-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM3-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM4-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM5-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM6-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM7-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-PM8-command-state = "dsi_hs_mode"; + qcom,mdss-dsi-h-sync-pulse = <1>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-t-clk-post = <0x0d>; + qcom,mdss-dsi-t-clk-pre = <0x2f>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-reset-sequence = <1 5>, <0 5>, <1 5>, <0 5>, <1 20>; + qcom,mdss-dsi-tx-eot-append; + qcom,esd-check-enabled; + qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 01 0A]; + qcom,mdss-dsi-panel-status-command-mode = "dsi_lp_mode"; + qcom,mdss-dsi-panel-status-check-mode = "TE_check_NT35596"; + qcom,mdss-dsi-panel-status-read-length = <1>; + qcom,mdss-dsi-panel-status-value = <0x9C>; + qcom,mdss-dsi-panel-max-error-count = <3>; + qcom,mdss-pan-physical-width-dimension = <69>; + qcom,mdss-pan-physical-height-dimension = <122>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm-audio.dtsi b/arch/arm/boot/dts/qcom/msm-audio.dtsi index 777fcdf1d27b..50bbd493556c 100644 --- a/arch/arm/boot/dts/qcom/msm-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio.dtsi @@ -306,7 +306,7 @@ }; int_codec: sound { - status = "disabled"; + status = "ok"; compatible = "qcom,msm8952-audio-codec"; qcom,model = "msm8952-snd-card-mtp"; reg = <0xc051000 0x4>, @@ -322,20 +322,19 @@ qcom,msm-mclk-freq = <9600000>; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; - qcom,msm-hs-micbias-type = "external"; + qcom,msm-hs-micbias-type = "internal"; qcom,msm-micbias1-ext-cap; qcom,audio-routing = "RX_BIAS", "MCLK", "SPK_RX_BIAS", "MCLK", "INT_LDO_H", "MCLK", "MIC BIAS External", "Handset Mic", - "MIC BIAS External2", "Headset Mic", - "MIC BIAS External", "Secondary Mic", + "MIC BIAS Internal2", "Headset Mic", + "MIC BIAS Internal1", "Secondary Mic", "AMIC1", "MIC BIAS External", - "AMIC2", "MIC BIAS External2", - "AMIC3", "MIC BIAS External", - "WSA_SPK OUT", "VDD_WSA_SWITCH", - "SpkrMono WSA_IN", "WSA_SPK OUT"; + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS Internal1"; + qcom,hdmi-dba-codec-rx; diff --git a/arch/arm/boot/dts/qcom/msm-pm8953.dtsi b/arch/arm/boot/dts/qcom/msm-pm8953.dtsi index 7fad9be18b27..62ffb0be9a8a 100644 --- a/arch/arm/boot/dts/qcom/msm-pm8953.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm8953.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -39,6 +40,10 @@ qcom,pon_1 { qcom,pon-type = <0>; qcom,pull-up = <1>; + qcom,support-reset = <1>; + qcom,s1-timer = <6720>; + qcom,s2-timer = <0>; + qcom,s2-type = <7>; linux,code = <116>; }; @@ -47,6 +52,15 @@ qcom,pull-up = <1>; linux,code = <114>; }; + + qcom,pon_3 { + qcom,pon-type = <3>; + qcom,support-reset = <1>; + qcom,s1-timer = <6720>; + qcom,s2-timer = <2000>; + qcom,s2-type = <7>; + qcom,pull-up = <1>; + }; }; pm8953_temp_alarm: qcom,temp-alarm@2400 { @@ -150,7 +164,7 @@ gpio@c700 { reg = <0xc700 0x100>; qcom,pin-num = <8>; - status = "disabled"; + qcom,master-en = <0>; }; }; @@ -245,25 +259,6 @@ }; }; - pm8953_typec: qcom,pm8953_typec@bf00 { - compatible = "qcom,qpnp-typec"; - reg = <0xbf00 0x100>; - interrupts = <0x0 0xbf 0x0>, - <0x0 0xbf 0x1>, - <0x0 0xbf 0x2>, - <0x0 0xbf 0x3>, - <0x0 0xbf 0x4>, - <0x0 0xbf 0x6>, - <0x0 0xbf 0x7>; - - interrupt-names = "vrd-change", - "ufp-detect", - "ufp-detach", - "dfp-detect", - "dfp-detach", - "vbus-err", - "vconn-oc"; - }; }; pm8953_1: qcom,pm8953@1 { diff --git a/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi index a7146546f309..16d9ae9e950f 100644 --- a/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8950.dtsi @@ -152,7 +152,12 @@ gpio@c000 { reg = <0xc000 0x100>; qcom,pin-num = <1>; - status = "disabled"; + qcom,mode = <1>; + qcom,pull = <4>; + qcom,src-sel = <2>; + qcom,master-en = <1>; + qcom,out-strength = <2>; + status = "okay"; }; gpio@c100 { @@ -203,19 +208,19 @@ #size-cells = <1>; qcom,iterm-ma = <100>; - qcom,float-voltage-mv = <4200>; - qcom,resume-delta-mv = <200>; + qcom,float-voltage-mv = <4400>; + qcom,resume-delta-mv = <50>; qcom,chg-inhibit-fg; + qcom,charge-unknown-battery; qcom,rparasitic-uohm = <100000>; qcom,bms-psy-name = "bms"; qcom,thermal-mitigation = <1500 700 600 0>; - qcom,parallel-usb-min-current-ma = <1400>; - qcom,parallel-usb-9v-min-current-ma = <900>; - qcom,parallel-allowed-lowering-ma = <500>; qcom,pmic-revid = <&pmi8950_revid>; qcom,force-aicl-rerun; qcom,aicl-rerun-period-s = <180>; qcom,autoadjust-vfloat; + qcom,fastchg-current-comp = <900>; + qcom,float-voltage-comp = <11>; qcom,chgr@1000 { reg = <0x1000 0x100>; @@ -317,16 +322,18 @@ compatible = "qcom,qpnp-fg"; #address-cells = <1>; #size-cells = <1>; - qcom,resume-soc = <95>; + qcom,resume-soc = <99>; status = "okay"; qcom,bcl-lm-threshold-ma = <127>; qcom,bcl-mh-threshold-ma = <405>; qcom,fg-iterm-ma = <150>; qcom,fg-chg-iterm-ma = <100>; qcom,pmic-revid = <&pmi8950_revid>; - qcom,fg-cutoff-voltage-mv = <3500>; + qcom,fg-cutoff-voltage-mv = <3400>; qcom,cycle-counter-en; qcom,capacity-learning-on; + qcom,fg-cc-cv-threshold-mv = <4380>; + qcom,fg-vbat-estimate-diff-mv = <200>; qcom,fg-soc@4000 { status = "okay"; @@ -419,7 +426,7 @@ #size-cells = <1>; pmi8950_pwm: pwm@b000 { - status = "disabled"; + status = "okay"; compatible = "qcom,qpnp-pwm"; reg = <0xb000 0x100>; reg-names = "qpnp-lpg-channel-base"; @@ -529,7 +536,6 @@ qcom,sync-dly-us = <800>; qcom,fs-curr-ua = <20000>; qcom,led-strings-list = [00 01]; - qcom,en-ext-pfet-sc-pro; qcom,cons-sync-write-delay-us = <1000>; }; @@ -578,6 +584,16 @@ qcom,current = <625>; }; + pmi8950_flashlight: qcom,flashlight { + label = "torch"; + qcom,led-name = "flashlight"; + qcom,default-led-trigger = + "torch0_trigger"; + qcom,max-current = <200>; + qcom,id = <0>; + qcom,current = <120>; + }; + pmi8950_torch0: qcom,torch_0 { label = "torch"; qcom,led-name = "led:torch_0"; @@ -625,7 +641,7 @@ qcom,wave-play-rate-us = <5263>; qcom,actuator-type = "erm"; qcom,wave-shape = "square"; - qcom,vmax-mv = <2000>; + qcom,vmax-mv = <3000>; qcom,ilim-ma = <800>; qcom,sc-deb-cycles = <8>; qcom,int-pwm-freq-khz = <505>; diff --git a/arch/arm/boot/dts/qcom/msm8953-audio.dtsi b/arch/arm/boot/dts/qcom/msm8953-audio.dtsi index 386bc5fc7b57..0bd875b83bee 100644 --- a/arch/arm/boot/dts/qcom/msm8953-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-audio.dtsi @@ -15,12 +15,24 @@ &int_codec { qcom,model = "msm8953-snd-card-mtp"; - + qcom,msm-ext-pa = "primary"; qcom,cdc-us-euro-gpios = <&tlmm 63 0>; + qcom,msm-spk-ext-pa = <&tlmm 96 0>; qcom,msm-mbhc-hphl-swh = <0>; qcom,msm-mbhc-gnd-swh = <0>; qcom,msm-hs-micbias-type = "internal"; qcom,msm-micbias1-ext-cap; + qcom,msm-mclk-freq = <9600000>; + qcom,audio-routing = + "RX_BIAS", "MCLK", + "SPK_RX_BIAS", "MCLK", + "INT_LDO_H", "MCLK", + "MIC BIAS External", "Handset Mic", + "MIC BIAS Internal2", "Headset Mic", + "MIC BIAS Internal1", "Secondary Mic", + "AMIC1", "MIC BIAS External", + "AMIC2", "MIC BIAS Internal2", + "AMIC3", "MIC BIAS Internal1"; qcom,msm-gpios = "pri_i2s", @@ -115,12 +127,6 @@ asoc-codec = <&stub_codec>, <&pm8953_diangu_dig>, <&hdmi_dba>; asoc-codec-names = "msm-stub-codec.1", "cajon_codec", "msm-hdmi-dba-codec-rx"; - asoc-wsa-codec-names = "wsa881x-i2c-codec.2-000f"; - asoc-wsa-codec-prefixes = "SpkrMono"; - - msm-vdd-wsa-switch-supply = <&pm8953_l5>; - qcom,msm-vdd-wsa-switch-voltage = <1800000>; - qcom,msm-vdd-wsa-switch-current = <10000>; }; &pm8953_gpios { diff --git a/arch/arm/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi index da00fb4624aa..9db8293353c6 100644 --- a/arch/arm/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi @@ -11,6 +11,17 @@ * GNU General Public License for more details. */ +&soc { + led_flash0: qcom,camera-flash { + cell-index = <0>; + compatible = "qcom,camera-flash"; + qcom,flash-type = <1>; + qcom,flash-source = <&pmi8950_flash0 &pmi8950_flash1>; + qcom,torch-source = <&pmi8950_torch0 &pmi8950_torch1>; + qcom,switch-source = <&pmi8950_switch>; + }; +}; + &cci { actuator0: qcom,actuator@0 { cell-index = <0>; @@ -26,20 +37,147 @@ eeprom0: qcom,eeprom@0 { cell-index = <0>; + reg = <0x0>; + qcom,eeprom-name = "qtech_s5k3l8"; compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xA0>; qcom,cci-master = <0>; - reg = <0x0>; - cam_vio-supply = <&pm8953_l6>; + qcom,num-blocks = <6>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xA0>; + qcom,mem0 = <5 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xA0>; + qcom,mem1 = <6 0x000C 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xA0>; + qcom,mem2 = <13 0x0019 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xA0>; + qcom,mem3 = <1769 0x0027 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xA0>; + qcom,mem4 = <899 0x0711 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xA0>; + qcom,mem5 = <3 0x0D99 2 0 1 0>; + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf"; - qcom,cam-vreg-min-voltage = <0 1100000 2850000>; - qcom,cam-vreg-max-voltage = <0 1100000 2850000>; - qcom,cam-vreg-op-mode = <0 105000 100000>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + gpios = <&tlmm 26 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk0_default &cam_sensor_rear_default>; pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom1: qcom,eeprom@1 { + cell-index = <1>; + reg = <0x1>; + qcom,eeprom-name = "ofilm_s5k3l8"; + compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xB0>; + qcom,cci-master = <0>; + qcom,num-blocks = <9>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xB0>; + qcom,mem0 = <1 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xB0>; + qcom,mem1 = <1 0x000B 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xB0>; + qcom,mem2 = <3 0x0015 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xB0>; + qcom,mem3 = <5 0x0019 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xB0>; + qcom,mem4 = <1 0x0021 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xB0>; + qcom,mem5 = <6 0x002A 2 0 1 0>; + + qcom,page6 = <0 0 0 0 0 0>; + qcom,poll6 = <0 0 0 0 0 0>; + qcom,saddr6 = <0xB0>; + qcom,mem6 = <6 0x0038 2 0 1 0>; + + qcom,page7 = <0 0 0 0 0 0>; + qcom,poll7 = <0 0 0 0 0 0>; + qcom,saddr7 = <0xB0>; + qcom,mem7 = <1769 0x003F 2 0 1 0>; + + qcom,page8 = <0 0 0 0 0 0>; + qcom,poll8 = <0 0 0 0 0 0>; + qcom,saddr8 = <0xB0>; + qcom,mem8 = <901 0x0729 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; gpios = <&tlmm 26 0>, <&tlmm 40 0>, <&tlmm 39 0>; @@ -50,6 +188,17 @@ qcom,gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0", "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; status = "ok"; clocks = <&clock_gcc clk_mclk0_clk_src>, <&clock_gcc clk_gcc_camss_mclk0_clk>; @@ -60,15 +209,144 @@ eeprom2: qcom,eeprom@2 { cell-index = <2>; reg = <0x2>; + qcom,eeprom-name = "sunny_s5k3l8"; + compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xB0>; + qcom,cci-master = <0>; + qcom,num-blocks = <7>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xB0>; + qcom,mem0 = <2 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xB0>; + qcom,mem1 = <3 0x0005 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xB0>; + qcom,mem2 = <5 0x000C 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xB0>; + qcom,mem3 = <7 0x0019 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xB0>; + qcom,mem4 = <1769 0x0027 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xB0>; + qcom,mem5 = <899 0x0711 2 0 1 0>; + + qcom,page6 = <0 0 0 0 0 0>; + qcom,poll6 = <0 0 0 0 0 0>; + qcom,saddr6 = <0xB0>; + qcom,mem6 = <3 0x0D99 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + gpios = <&tlmm 26 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom3: qcom,eeprom@3 { + cell-index = <3>; + reg = <0x3>; compatible = "qcom,eeprom"; qcom,cci-master = <1>; + + qcom,eeprom-name = "qtech_s5k5e8"; + qcom,slave-addr = <0x20>; + qcom,num-blocks = <8>; + + qcom,page0 = <1 0x0A02 2 0x4 1 0>; + qcom,pageen0 = <1 0x0A00 2 0x1 1 0>; + qcom,poll0 = <0 0x0 2 0 1 0>; + qcom,mem0 = <64 0x0A04 2 0 1 0>; + + qcom,page1 = <1 0x0A02 2 0x5 1 0>; + qcom,pageen1 = <1 0x0A00 2 0x1 1 0>; + qcom,poll1 = <0 0x0 2 0 1 0>; + qcom,mem1 = <64 0x0A04 2 0 1 0>; + + qcom,page2 = <1 0x0A02 2 0x6 1 0>; + qcom,pageen2 = <1 0x0A00 2 0x1 1 0>; + qcom,poll2 = <0 0x0 2 0 1 0>; + qcom,mem2 = <64 0x0A04 2 0 1 0>; + + qcom,page3 = <1 0x0A02 2 0x7 1 0>; + qcom,pageen3 = <1 0x0A00 2 0x1 1 0>; + qcom,poll3 = <0 0x0 2 0 1 0>; + qcom,mem3 = <64 0x0A04 2 0 1 0>; + + qcom,page4 = <1 0x0A02 2 0x8 1 0>; + qcom,pageen4 = <1 0x0A00 2 0x1 1 0>; + qcom,poll4 = <0 0x0 2 0 1 0>; + qcom,mem4 = <64 0x0A04 2 0 1 0>; + + qcom,page5 = <1 0x0A02 2 0x9 1 0>; + qcom,pageen5 = <1 0x0A00 2 0x1 1 0>; + qcom,poll5 = <0 0x0 2 0 1 0>; + qcom,mem5 = <64 0x0A04 2 0 1 0>; + + qcom,page6 = <1 0x0A02 2 0xA 1 0>; + qcom,pageen6 = <1 0x0A00 2 0x1 1 0>; + qcom,poll6 = <0 0x0 2 0 1 0>; + qcom,mem6 = <64 0x0A04 2 0 1 0>; + + qcom,page7 = <1 0x0A02 2 0xE 1 0>; + qcom,pageen7 = <1 0x0A00 2 0x1 1 0>; + qcom,poll7 = <0 0x0 2 0 1 0>; + qcom,mem7 = <2 0x0A04 2 0 1 0>; + cam_vdig-supply = <&pm8953_l23>; cam_vana-supply = <&pm8953_l22>; cam_vio-supply = <&pm8953_l6>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000>; - qcom,cam-vreg-op-mode = <105000 0 80000>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; qcom,gpio-no-mux = <0>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_default @@ -84,7 +362,100 @@ qcom,gpio-req-tbl-label = "CAMIF_MCLK2", "CAM_RESET2", "CAM_STANDBY2"; - qcom,sensor-mode = <0>; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 10 1 1>; + + status = "ok"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom4: qcom,eeprom@4 { + cell-index = <4>; + reg = <0x4>; + compatible = "qcom,eeprom"; + qcom,cci-master = <1>; + + qcom,eeprom-name = "sunny_s5k5e8"; + qcom,slave-addr = <0x20>; + qcom,num-blocks = <8>; + + qcom,page0 = <1 0x0A02 2 0x4 1 0>; + qcom,pageen0 = <1 0x0A00 2 0x1 1 0>; + qcom,poll0 = <0 0x0 2 0 1 0>; + qcom,mem0 = <64 0x0A04 2 0 1 0>; + + qcom,page1 = <1 0x0A02 2 0x5 1 0>; + qcom,pageen1 = <1 0x0A00 2 0x1 1 0>; + qcom,poll1 = <0 0x0 2 0 1 0>; + qcom,mem1 = <64 0x0A04 2 0 1 0>; + + qcom,page2 = <1 0x0A02 2 0x6 1 0>; + qcom,pageen2 = <1 0x0A00 2 0x1 1 0>; + qcom,poll2 = <0 0x0 2 0 1 0>; + qcom,mem2 = <64 0x0A04 2 0 1 0>; + + qcom,page3 = <1 0x0A02 2 0x7 1 0>; + qcom,pageen3 = <1 0x0A00 2 0x1 1 0>; + qcom,poll3 = <0 0x0 2 0 1 0>; + qcom,mem3 = <64 0x0A04 2 0 1 0>; + + qcom,page4 = <1 0x0A02 2 0x8 1 0>; + qcom,pageen4 = <1 0x0A00 2 0x1 1 0>; + qcom,poll4 = <0 0x0 2 0 1 0>; + qcom,mem4 = <64 0x0A04 2 0 1 0>; + + qcom,page5 = <1 0x0A02 2 0x9 1 0>; + qcom,pageen5 = <1 0x0A00 2 0x1 1 0>; + qcom,poll5 = <0 0x0 2 0 1 0>; + qcom,mem5 = <64 0x0A04 2 0 1 0>; + + qcom,page6 = <1 0x0A02 2 0xA 1 0>; + qcom,pageen6 = <1 0x0A00 2 0x1 1 0>; + qcom,poll6 = <0 0x0 2 0 1 0>; + qcom,mem6 = <64 0x0A04 2 0 1 0>; + + qcom,page7 = <1 0x0A02 2 0xE 1 0>; + qcom,pageen7 = <1 0x0A00 2 0x1 1 0>; + qcom,poll7 = <0 0x0 2 0 1 0>; + qcom,mem7 = <2 0x0A04 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l23>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_default + &cam_sensor_front1_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 129 0>, + <&tlmm 130 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 10 1 1>; + status = "ok"; clocks = <&clock_gcc clk_mclk1_clk_src>, <&clock_gcc clk_gcc_camss_mclk1_clk>; @@ -92,6 +463,445 @@ qcom,clock-rates = <19200000 0>; }; + eeprom5: qcom,eeprom@5 { + cell-index = <5>; + reg = <0x5>; + compatible = "qcom,eeprom"; + qcom,cci-master = <1>; + + qcom,eeprom-name = "ofilm_s5k5e8"; + qcom,slave-addr = <0x5A>; + qcom,num-blocks = <8>; + + qcom,page0 = <1 0x0A02 2 0x4 1 0>; + qcom,pageen0 = <1 0x0A00 2 0x1 1 0>; + qcom,poll0 = <0 0x0 2 0 1 0>; + qcom,mem0 = <64 0x0A04 2 0 1 0>; + + qcom,page1 = <1 0x0A02 2 0x5 1 0>; + qcom,pageen1 = <1 0x0A00 2 0x1 1 0>; + qcom,poll1 = <0 0x0 2 0 1 0>; + qcom,mem1 = <64 0x0A04 2 0 1 0>; + + qcom,page2 = <1 0x0A02 2 0x6 1 0>; + qcom,pageen2 = <1 0x0A00 2 0x1 1 0>; + qcom,poll2 = <0 0x0 2 0 1 0>; + qcom,mem2 = <64 0x0A04 2 0 1 0>; + + qcom,page3 = <1 0x0A02 2 0x7 1 0>; + qcom,pageen3 = <1 0x0A00 2 0x1 1 0>; + qcom,poll3 = <0 0x0 2 0 1 0>; + qcom,mem3 = <64 0x0A04 2 0 1 0>; + + qcom,page4 = <1 0x0A02 2 0x8 1 0>; + qcom,pageen4 = <1 0x0A00 2 0x1 1 0>; + qcom,poll4 = <0 0x0 2 0 1 0>; + qcom,mem4 = <64 0x0A04 2 0 1 0>; + + qcom,page5 = <1 0x0A02 2 0x9 1 0>; + qcom,pageen5 = <1 0x0A00 2 0x1 1 0>; + qcom,poll5 = <0 0x0 2 0 1 0>; + qcom,mem5 = <64 0x0A04 2 0 1 0>; + + qcom,page6 = <1 0x0A02 2 0xA 1 0>; + qcom,pageen6 = <1 0x0A00 2 0x1 1 0>; + qcom,poll6 = <0 0x0 2 0 1 0>; + qcom,mem6 = <64 0x0A04 2 0 1 0>; + + qcom,page7 = <1 0x0A02 2 0xE 1 0>; + qcom,pageen7 = <1 0x0A00 2 0x1 1 0>; + qcom,poll7 = <0 0x0 2 0 1 0>; + qcom,mem7 = <2 0x0A04 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l23>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk1_default + &cam_sensor_front1_default>; + pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>; + gpios = <&tlmm 27 0>, + <&tlmm 129 0>, + <&tlmm 130 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK2", + "CAM_RESET2", + "CAM_STANDBY2"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 10 1 1>; + + status = "ok"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom6: qcom,eeprom@6 { + cell-index = <6>; + reg = <0x6>; + qcom,eeprom-name = "ofilm_imx258"; + compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xB0>; + qcom,cci-master = <0>; + qcom,num-blocks = <8>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xB0>; + qcom,mem0 = <1024 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xB0>; + qcom,mem1 = <1024 0x0400 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xB0>; + qcom,mem2 = <1024 0x0800 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xB0>; + qcom,mem3 = <1024 0x0C00 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xB0>; + qcom,mem4 = <1024 0x1000 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xB0>; + qcom,mem5 = <1024 0x1400 2 0 1 0>; + + qcom,page6 = <0 0 0 0 0 0>; + qcom,poll6 = <0 0 0 0 0 0>; + qcom,saddr6 = <0xB0>; + qcom,mem6 = <1024 0x1800 2 0 1 0>; + + qcom,page7 = <0 0 0 0 0 0>; + qcom,poll7 = <0 0 0 0 0 0>; + qcom,saddr7 = <0xB0>; + qcom,mem7 = <1024 0x1C00 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + gpios = <&tlmm 26 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom7: qcom,eeprom@7 { + cell-index = <7>; + reg = <0x7>; + qcom,eeprom-name = "qtech_imx258"; + compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xA0>; + qcom,cci-master = <0>; + qcom,num-blocks = <8>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xA0>; + qcom,mem0 = <1024 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xA0>; + qcom,mem1 = <1024 0x0400 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xA0>; + qcom,mem2 = <1024 0x0800 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xA0>; + qcom,mem3 = <1024 0x0C00 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xA0>; + qcom,mem4 = <1024 0x1000 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xA0>; + qcom,mem5 = <1024 0x1400 2 0 1 0>; + + qcom,page6 = <0 0 0 0 0 0>; + qcom,poll6 = <0 0 0 0 0 0>; + qcom,saddr6 = <0xA0>; + qcom,mem6 = <1024 0x1800 2 0 1 0>; + + qcom,page7 = <0 0 0 0 0 0>; + qcom,poll7 = <0 0 0 0 0 0>; + qcom,saddr7 = <0xA0>; + qcom,mem7 = <1024 0x1C00 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + gpios = <&tlmm 26 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom8: qcom,eeprom@8 { + cell-index = <8>; + reg = <0x8>; + qcom,eeprom-name = "sunny_imx258"; + compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xB0>; + qcom,cci-master = <0>; + qcom,num-blocks = <8>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xB0>; + qcom,mem0 = <1024 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xB0>; + qcom,mem1 = <1024 0x0400 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xB0>; + qcom,mem2 = <1024 0x0800 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xB0>; + qcom,mem3 = <1024 0x0C00 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xB0>; + qcom,mem4 = <1024 0x1000 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xB0>; + qcom,mem5 = <1024 0x1400 2 0 1 0>; + + qcom,page6 = <0 0 0 0 0 0>; + qcom,poll6 = <0 0 0 0 0 0>; + qcom,saddr6 = <0xB0>; + qcom,mem6 = <1024 0x1800 2 0 1 0>; + + qcom,page7 = <0 0 0 0 0 0>; + qcom,poll7 = <0 0 0 0 0 0>; + qcom,saddr7 = <0xB0>; + qcom,mem7 = <1024 0x1C00 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + gpios = <&tlmm 26 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + + eeprom9: qcom,eeprom@9 { + cell-index = <9>; + reg = <0x9>; + qcom,eeprom-name = "qtech_ov13855"; + compatible = "qcom,eeprom"; + + qcom,slave-addr = <0xA0>; + qcom,cci-master = <0>; + qcom,num-blocks = <8>; + + qcom,page0 = <0 0 0 0 0 0>; + qcom,poll0 = <0 0 0 0 0 0>; + qcom,saddr0 = <0xA0>; + qcom,mem0 = <1024 0x0000 2 0 1 0>; + + qcom,page1 = <0 0 0 0 0 0>; + qcom,poll1 = <0 0 0 0 0 0>; + qcom,saddr1 = <0xA0>; + qcom,mem1 = <1024 0x0400 2 0 1 0>; + + qcom,page2 = <0 0 0 0 0 0>; + qcom,poll2 = <0 0 0 0 0 0>; + qcom,saddr2 = <0xA0>; + qcom,mem2 = <1024 0x0800 2 0 1 0>; + + qcom,page3 = <0 0 0 0 0 0>; + qcom,poll3 = <0 0 0 0 0 0>; + qcom,saddr3 = <0xA0>; + qcom,mem3 = <1024 0x0C00 2 0 1 0>; + + qcom,page4 = <0 0 0 0 0 0>; + qcom,poll4 = <0 0 0 0 0 0>; + qcom,saddr4 = <0xA0>; + qcom,mem4 = <1024 0x1000 2 0 1 0>; + + qcom,page5 = <0 0 0 0 0 0>; + qcom,poll5 = <0 0 0 0 0 0>; + qcom,saddr5 = <0xA0>; + qcom,mem5 = <1024 0x1400 2 0 1 0>; + + qcom,page6 = <0 0 0 0 0 0>; + qcom,poll6 = <0 0 0 0 0 0>; + qcom,saddr6 = <0xA0>; + qcom,mem6 = <1024 0x1800 2 0 1 0>; + + qcom,page7 = <0 0 0 0 0 0>; + qcom,poll7 = <0 0 0 0 0 0>; + qcom,saddr7 = <0xA0>; + qcom,mem7 = <1024 0x1C00 2 0 1 0>; + + cam_vdig-supply = <&pm8953_l2>; + cam_vana-supply = <&pm8953_l22>; + cam_vio-supply = <&pm8953_l6>; + cam_vaf-supply = <&pm8953_l17>; + qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; + qcom,cam-vreg-type = <0 1 0 0>; + qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; + qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,gpio-no-mux = <0>; + gpios = <&tlmm 26 0>, + <&tlmm 40 0>, + <&tlmm 39 0>; + qcom,gpio-reset = <1>; + qcom,gpio-standby = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-req-tbl-label = "CAMIF_MCLK0", + "CAM_RESET0", + "CAM_STANDBY0"; + qcom,cam-power-seq-type = "sensor_gpio", "sensor_gpio", "sensor_vreg", + "sensor_vreg", "sensor_vreg", "sensor_vreg", "sensor_clk" , "sensor_gpio", "sensor_gpio"; + qcom,cam-power-seq-val = "sensor_gpio_reset", "sensor_gpio_standby", "cam_vana", + "cam_vdig", "cam_vio","cam_vaf", "sensor_cam_mclk", "sensor_gpio_reset", "sensor_gpio_standby"; + qcom,cam-power-seq-cfg-val = <0 0 1 1 1 1 24000000 1 1>; + qcom,cam-power-seq-delay = <1 1 0 0 0 1 1 1 1>; + + pinctrl-names = "cam_default", "cam_suspend"; + pinctrl-0 = <&cam_sensor_mclk0_default + &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; + status = "ok"; + clocks = <&clock_gcc clk_mclk0_clk_src>, + <&clock_gcc clk_gcc_camss_mclk0_clk>; + clock-names = "cam_src_clk", "cam_clk"; + qcom,clock-rates = <19200000 0>; + }; + qcom,camera@0 { cell-index = <0>; compatible = "qcom,camera"; @@ -99,7 +909,7 @@ qcom,csiphy-sd-index = <0>; qcom,csid-sd-index = <0>; qcom,mount-angle = <90>; - qcom,eeprom-src = <&eeprom0>; + qcom,eeprom-src = <&eeprom0 &eeprom1 &eeprom2 &eeprom6 &eeprom7 &eeprom8 &eeprom9>; qcom,actuator-src = <&actuator0>; qcom,led-flash-src = <&led_flash0>; cam_vdig-supply = <&pm8953_l2>; @@ -133,46 +943,6 @@ clock-names = "cam_src_clk", "cam_clk"; qcom,clock-rates = <24000000 0>; }; - qcom,camera@1 { - cell-index = <1>; - compatible = "qcom,camera"; - reg = <0x1>; - qcom,csiphy-sd-index = <1>; - qcom,csid-sd-index = <1>; - qcom,mount-angle = <90>; - cam_vdig-supply = <&pm8953_l23>; - cam_vana-supply = <&pm8953_l22>; - cam_vio-supply = <&pm8953_l6>; - cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", - "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-op-mode = <200000 0 80000 100000>; - pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk2_default - &cam_sensor_front_default>; - pinctrl-1 = <&cam_sensor_mclk2_sleep - &cam_sensor_front_sleep>; - gpios = <&tlmm 28 0>, - <&tlmm 131 0>, - <&tlmm 132 0>; - qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; - qcom,gpio-req-tbl-label = "CAMIF_MCLK1", - "CAM_RESET1", - "CAM_STANDBY1"; - qcom,sensor-position = <1>; - qcom,sensor-mode = <0>; - qcom,cci-master = <0>; - status = "disabled"; - clocks = <&clock_gcc clk_mclk2_clk_src>, - <&clock_gcc clk_gcc_camss_mclk2_clk>; - clock-names = "cam_src_clk", "cam_clk"; - qcom,clock-rates = <24000000 0>; - }; qcom,camera@2 { cell-index = <2>; @@ -181,7 +951,7 @@ qcom,csiphy-sd-index = <2>; qcom,csid-sd-index = <2>; qcom,mount-angle = <270>; - qcom,eeprom-src = <&eeprom2>; + qcom,eeprom-src = <&eeprom3 &eeprom4 &eeprom5>; cam_vdig-supply = <&pm8953_l23>; cam_vana-supply = <&pm8953_l22>; cam_vio-supply = <&pm8953_l6>; diff --git a/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi index 4fa5cd19a17c..59b29ea35972 100644 --- a/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -9,7 +10,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - +#include "dsi-panel-nt35532-fhd-video.dtsi" +#include "dsi-panel-nt35596-fhd-video.dtsi" +#include "dsi-panel-nt35596-tianma-fhd-video.dtsi" #include "dsi-panel-sim-video.dtsi" #include "dsi-panel-sim-dualmipi-video.dtsi" #include "dsi-panel-sim-cmd.dtsi" @@ -49,6 +52,34 @@ }; }; +/* Rain bow lcd nt35532 */ + +&dsi_nt35532_fhd_vid { + qcom,mdss-dsi-panel-timings-8996 = [24 1f 08 09 05 03 04 a0 + 24 1f 08 09 05 03 04 a0 + 24 1f 08 09 05 03 04 a0 + 24 1f 08 09 05 03 04 a0 + 24 1b 08 09 05 03 04 a0]; +}; + +&dsi_nt35596_fhd_vid { + qcom,mdss-dsi-panel-timings-8996 = [24 1f 08 09 05 03 04 a0 + 24 1f 08 09 05 03 04 a0 + 24 1f 08 09 05 03 04 a0 + 24 1f 08 09 05 03 04 a0 + 24 1b 08 08 05 03 04 a0]; +}; + +&dsi_nt35596_tianma_fhd_vid { + qcom,mdss-dsi-panel-timings-8996 = [23 1e 08 09 05 03 04 a0 + 23 1e 08 09 05 03 04 a0 + 23 1e 08 09 05 03 04 a0 + 23 1e 08 09 05 03 04 a0 + 23 1a 08 09 05 03 04 a0]; +}; + + + &dsi_truly_1080_vid { qcom,mdss-dsi-panel-timings-phy-v2 = [23 1e 08 09 05 03 04 a0 23 1e 08 09 05 03 04 a0 diff --git a/arch/arm/boot/dts/qcom/msm8953-mdss-pll.dtsi b/arch/arm/boot/dts/qcom/msm8953-mdss-pll.dtsi index a279453a1c74..f291a4caa033 100644 --- a/arch/arm/boot/dts/qcom/msm8953-mdss-pll.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-mdss-pll.dtsi @@ -28,8 +28,6 @@ clock-names = "iface_clk"; clock-rate = <0>; - qcom,dsi-pll-ssc-en; - qcom,dsi-pll-ssc-mode = "down-spread"; /* Memory region for passing dynamic refresh pll codes */ memory-region = <&dfps_data_mem>; @@ -61,8 +59,6 @@ gdsc-supply = <&gdsc_mdss>; - qcom,dsi-pll-ssc-en; - qcom,dsi-pll-ssc-mode = "down-spread"; clocks = <&clock_gcc clk_gcc_mdss_ahb_clk>; clock-names = "iface_clk"; clock-rate = <0>; diff --git a/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi index af1d61ae20b4..66badc2084dd 100644 --- a/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-mtp.dtsi @@ -241,11 +241,21 @@ status = "ok"; }; -&pm8953_typec { - ss-mux-supply = <&pm8953_l13>; - qcom,ssmux-gpio = <&tlmm 139 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&typec_ssmux_config>; + +/{ + mtp_batterydata: qcom,battery-data { + qcom,batt-id-range-pct = <15>; + #include "batterydata-itech-3000mah.dtsi" + #include "batterydata-ascent-3450mAh.dtsi" + }; +}; + +&pmi8950_fg { + qcom,battery-data = <&mtp_batterydata>; +}; + +&pmi8950_charger { + qcom,battery-data = <&mtp_batterydata>; }; &pm8953_gpios { diff --git a/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi index c3eed191d94f..be05db5c84bd 100644 --- a/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -460,7 +460,7 @@ mdss_te_active: mdss_te_active { mux { pins = "gpio24"; - function = "mdp_vsync"; + function = "gpio"; }; config { pins = "gpio24"; @@ -472,7 +472,7 @@ mdss_te_suspend: mdss_te_suspend { mux { pins = "gpio24"; - function = "mdp_vsync"; + function = "gpio"; }; config { pins = "gpio24"; @@ -762,6 +762,104 @@ }; }; + goodix_spi_active: goodix_spi_active{ + mux { + pins = "gpio135", "gpio136", "gpio137", "gpio138"; + function = "blsp_spi6"; + }; + config { + pins = "gpio135", "gpio136", "gpio137", "gpio138"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + goodix_reset_reset: goodix_reset_reset{ + mux { + pins = "gpio140"; + function = "gpio"; + }; + config { + pins = "gpio140"; + drive-strength = <2>; + bias-disable = <0>; + output-low; + }; + }; + goodix_reset_active: goodix_reset_active{ + mux { + pins = "gpio140"; + function = "gpio"; + }; + config { + pins = "gpio140"; + drive-strength = <2>; + bias-disable = <0>; + output-high; + }; + }; + goodix_irq_active: goodix_irq_active { + mux { + pins = "gpio48"; + function = "gpio"; + }; + config { + pins = "gpio48"; + drive-strength = <2>; + bias-disable = <0>; + input-enable; + }; + }; + + /* fingerprint pin function */ + fpc_spi_active: fpc_spi_active { + mux { + pins = "gpio135", "gpio136", "gpio137", "gpio138"; + function = "blsp_spi7"; + }; + + config { + pins = "gpio135", "gpio136", "gpio137", "gpio138"; + drive-strength = <2>; + bias-disable; + }; + }; + fpc_reset_reset: fpc_reset_reset { + mux { + pins = "gpio140"; + function = "gpio"; + }; + config { + pins = "gpio140"; + drive-strength = <2>; + bias-disable; + output-low; + }; + }; + fpc_reset_active: fpc_reset_active { + mux { + pins = "gpio140"; + function = "gpio"; + }; + config { + pins = "gpio140"; + drive-strength = <2>; + bias-disable; + output-high; + }; + }; + fpc_irq_active: fpc_irq_active { + mux { + pins = "gpio48"; + function = "gpio"; + }; + config { + pins = "gpio48"; + drive-strength = <2>; + bias-disable; + input-enable; + }; + }; + pmx_rd_nfc_int { /*qcom,pins = <&gp 17>;*/ pins = "gpio17"; diff --git a/arch/arm/boot/dts/qcom/msm8953-pm.dtsi b/arch/arm/boot/dts/qcom/msm8953-pm.dtsi index d30fe282fb35..76b9f37f9bae 100644 --- a/arch/arm/boot/dts/qcom/msm8953-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-pm.dtsi @@ -475,6 +475,7 @@ <72 139>, <73 140>, <74 141>, + <0xff 24>, <0xff 88>; }; diff --git a/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dts b/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dts index b6acd5abbae7..aeb2f4d8aded 100644 --- a/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dts +++ b/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dts @@ -20,7 +20,7 @@ model = "Qualcomm Technologies, Inc. MSM8953 + PMI8950 QRD SKU3"; compatible = "qcom,msm8953-qrd-sku3", "qcom,msm8953-qrd", "qcom,msm8953", "qcom,qrd"; - qcom,board-id= <0x2000b 0>; + qcom,board-id= <0x0b 0>; }; &soc { diff --git a/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dtsi b/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dtsi index 871e7f286703..a1087c692827 100644 --- a/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-qrd-sku3.dtsi @@ -70,8 +70,7 @@ lab-supply = <&lab_regulator>; ibb-supply = <&ibb_regulator>; /delete-property/ vdd-supply; - - qcom,dsi-pref-prim-pan = <&dsi_r69006_1080p_cmd>; + qcom,dsi-pref-prim-pan = <&dsi_nt35596_fhd_vid>; pinctrl-names = "mdss_default", "mdss_sleep"; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; @@ -88,6 +87,21 @@ qpnp,qpnp-labibb-mode = "lcd"; }; +&dsi_nt35532_fhd_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + +}; + +&dsi_nt35596_fhd_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + +}; + +&dsi_nt35596_tianma_fhd_vid { + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; + +}; + &dsi_r69006_1080p_cmd { qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; }; @@ -97,19 +111,19 @@ }; &int_codec { - status = "disabled"; + status = "ok"; }; &pm8953_diangu_dig { - status = "disabled"; + status = "ok"; }; &pm8953_diangu_analog { - status = "disabled"; + status = "ok"; }; &ext_codec { - status = "ok"; + status = "disabled"; qcom,model = "msm8953-sku3-tasha-snd-card"; qcom,audio-routing = @@ -136,25 +150,18 @@ }; &slim_msm { - status = "ok"; + status = "disabled"; }; &dai_slim { - status = "ok"; -}; - -&wcd9xxx_intc { - status = "ok"; + status = "disabled"; }; &clock_audio { - status = "ok"; + status = "disabled"; }; &wcd9335 { - status = "ok"; + status = "disabled"; }; -&wcd_rst_gpio { - status = "ok"; -}; diff --git a/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi index c081a1c30822..62347ec23fe3 100644 --- a/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -31,6 +32,63 @@ }; }; + pwm_ir { + compatible = "pwm-ir"; + pwms = <&pmi8950_pwm 0 0>; + reg-id = "vdd"; + vdd-supply = <&pm8953_l8>; + }; + + goodix_fp { + compatible = "goodix,fingerprint"; + spi-max-frequency = <1000000>; + input-device-name = "gf3208"; + interrupt-parent = <&tlmm>; + interrupts = <9 0x0>; + + goodix,gpio_reset = <&tlmm 140 0>; + goodix,gpio_irq = <&tlmm 48 0>; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>; + + pinctrl-names = "goodixfp_spi_active", + "goodixfp_reset_reset", + "goodixfp_reset_active", + "goodixfp_irq_active"; + + pinctrl-0 = <&goodix_spi_active>; + pinctrl-1 = <&goodix_reset_reset>; + pinctrl-2 = <&goodix_reset_active>; + pinctrl-3 = <&goodix_irq_active>; + }; + + fpc1020 { + compatible = "fpc,fpc1020"; + spi-max-frequency = <1000000>; + input-device-name = "fpc1020"; + interrupt-parent = <&tlmm>; + interrupts = <9 0x0>; + + fpc,gpio_rst = <&tlmm 140 0>; + fpc,gpio_irq = <&tlmm 48 0>; + + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, + <&clock_gcc clk_gcc_blsp1_qup1_spi_apps_clk>; + + pinctrl-names = "fpc1020_spi_active", + "fpc1020_reset_reset", + "fpc1020_reset_active", + "fpc1020_irq_active"; + + pinctrl-0 = <&fpc_spi_active>; + pinctrl-1 = <&fpc_reset_reset>; + pinctrl-2 = <&fpc_reset_active>; + pinctrl-3 = <&fpc_irq_active>; + }; + i2c@78b7000 { /* BLSP1 QUP3 */ status = "okay"; synaptics@4b { @@ -58,6 +116,105 @@ clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, <&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>; }; + focaltech@38 { + compatible = "focaltech,5435"; + reg = <0x38>; + interrupt-parent = <&tlmm>; + interrupts = <65 0x2>; + vdd-supply = <&pm8953_l10>; + vcc_i2c-supply = <&pm8953_l6>; + /* pins used by touchscreen */ + pinctrl-names = "pmx_ts_active","pmx_ts_suspend", + "pmx_ts_release"; + pinctrl-0 = <&ts_int_active &ts_reset_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + pinctrl-2 = <&ts_release>; + focaltech,name = "ft5435"; + focaltech,family-id = <0x54>; + focaltech,reset-gpio = <&tlmm 64 0x0>; + focaltech,irq-gpio = <&tlmm 65 0x2008>; + focaltech,display-coords = <0 0 1080 1920>; + focaltech,panel-coords = <0 0 1080 1920>; + focaltech,no-force-update; + focaltech,i2c-pull-up; + focaltech,group-id = <1>; + focaltech,hard-reset-delay-ms = <200>; + focaltech,soft-reset-delay-ms = <200>; + focaltech,num-max-touches = <10>; + focaltech,fw-delay-aa-ms = <2>; + focaltech,fw-delay-55-ms = <2>; + focaltech,fw-upgrade-id1 = <0x54>; + focaltech,fw-upgrade-id2 = <0x2c>; + focaltech,fw-delay-readid-ms = <10>; + focaltech,fw-delay-era-flsh-ms = <2000>; + focaltech,fw-auto-cal; + focaltech,fw-vkey-support; + focaltech,resume-in-workqueue; + focaltech,num-virtual-key = <3>; + focal,virtual_key_1 = <172 500 2040>;/*home*/ + focal,virtual_key_2 = <139 200 2040>;/*menu*/ + focal,virtual_key_3 = <158 800 2040>;/*back*/ + }; + imagis@50 { + compatible = "imagis,ist30xx-ts"; + reg = <0x50>; + interrupt-parent = <&tlmm>; + interrupts = <65 0x2>; + vdd-supply = <&pm8953_l10>; + vcc_i2c-supply = <&pm8953_l6>; + /* pins used by touchscreen */ + pinctrl-names = "pmx_ts_active","pmx_ts_suspend", + "pmx_ts_release"; + pinctrl-0 = <&ts_int_active &ts_reset_active>; + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>; + pinctrl-2 = <&ts_release>; + imagis,reset-gpio = <&tlmm 64 0x0>; + imagis,irq-gpio = <&tlmm 65 0x2008>; + imagis,i2c-pull-up; + }; + + }; + + i2c@78b6000 { /* BLSP1 QUP3 */ + aw2013@45 { + compatible = "awinic"; + reg = <0x45>; + vdd-supply = <&pm8953_l10>; + vcc-supply = <&pm8953_l5>; + + aw2013,red { + aw2013,name = "red"; + aw2013,id = <0>; + aw2013,max-brightness = <150>; + aw2013,max-current = <1>; + aw2013,rise-time-ms = <3>; + aw2013,hold-time-ms = <1>; + aw2013,fall-time-ms = <3>; + aw2013,off-time-ms = <3>; + }; + + aw2013,green { + aw2013,name = "green"; + aw2013,id = <1>; + aw2013,max-brightness = <150>; + aw2013,max-current = <1>; + aw2013,rise-time-ms = <3>; + aw2013,hold-time-ms = <1>; + aw2013,fall-time-ms = <3>; + aw2013,off-time-ms = <3>; + }; + + aw2013,blue { + aw2013,name = "blue"; + aw2013,id = <2>; + aw2013,max-brightness = <150>; + aw2013,max-current = <1>; + aw2013,rise-time-ms = <3>; + aw2013,hold-time-ms = <1>; + aw2013,fall-time-ms = <3>; + aw2013,off-time-ms = <3>; + }; + }; }; vdd_vreg: vdd_vreg { @@ -72,55 +229,52 @@ }; &spmi_bus { - qcom,pmi8950@2 { + qcom,pm8953@0 { qcom,leds@a100 { status = "okay"; + compatible = "qcom,leds-qpnp"; + reg = <0xa100 0x100>; + label = "mpp"; qcom,led_mpp_2 { label = "mpp"; - linux,name = "green"; + linux,name = "button-backlight"; linux,default-trigger = "none"; qcom,default-state = "off"; - qcom,max-current = <40>; + qcom,max-current = <5>; qcom,current-setting = <5>; qcom,id = <6>; qcom,mode = "manual"; qcom,source-sel = <1>; - qcom,mode-ctrl = <0x60>; + qcom,mode-ctrl = <0x61>; }; }; + }; }; / { qrd_batterydata: qcom,battery-data { - qcom,batt-id-range-pct = <15>; - #include "batterydata-qrd-sku1-4v4-2800mah.dtsi" + qcom,batt-id-range-pct = <5>; + #include "batterydata-qrd-sunwoda-4v4-4100mah.dtsi" + #include "batterydata-qrd-sunwoda-ATL-4v4-4100mah.dtsi" + #include "batterydata-qrd-coslight-4v4-4100mah.dtsi" + #include "batterydata-qrd-desay-lisheng-4v4-4100mah.dtsi" + #include "batterydata-qrd-desay-4v4-4100mah.dtsi" }; }; -&pm8953_typec { - ss-mux-supply = <&pm8953_l6>; - qcom,ssmux-gpio = <&tlmm 139 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&typec_ssmux_config>; -}; - &pmi8950_charger { qcom,battery-data = <&qrd_batterydata>; qcom,float-voltage-mv = <4400>; - qcom,chg-led-sw-controls; - qcom,chg-led-support; - qcom,external-typec; - qcom,typec-psy-name = "typec"; qcom,thermal-mitigation = <3000 2500 2000 1500 1000 500 0>; status = "okay"; }; - &pmi8950_fg { qcom,battery-data = <&qrd_batterydata>; - qcom,cold-bat-decidegc = <(-100)>; - qcom,cool-bat-decidegc = <0>; - qcom,warm-bat-decidegc = <550>; + qcom,thermal-coefficients = [c8 86 c1 50 d3 37]; + qcom,cold-bat-decidegc = <0>; + qcom,cool-bat-decidegc = <100>; + qcom,warm-bat-decidegc = <500>; qcom,hot-bat-decidegc = <550>; qcom,bad-battery-detection-enable; qcom,hold-soc-while-full; @@ -228,14 +382,10 @@ status = "ok"; }; -&flash_led { - /delete-node/ qcom,flash_1; - /delete-node/ qcom,torch_1; -}; &led_flash0{ - qcom,flash-source = <&pmi8950_flash0>; - qcom,torch-source = <&pmi8950_torch0>; + qcom,flash-source = <&pmi8950_flash0 &pmi8950_flash1>; + qcom,torch-source = <&pmi8950_torch0 &pmi8950_torch1>; }; &pm8953_vadc { diff --git a/arch/arm/boot/dts/qcom/msm8953.dtsi b/arch/arm/boot/dts/qcom/msm8953.dtsi index b857f1895562..de6bc38ba3fb 100644 --- a/arch/arm/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953.dtsi @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -60,7 +61,7 @@ other_ext_mem: other_ext_region@0 { compatible = "removed-dma-pool"; no-map; - reg = <0x0 0x85b00000 0x0 0xd00000>; + reg = <0x0 0x84A00000 0x0 0x1E00000>; }; modem_mem: modem_region@0 { @@ -126,6 +127,14 @@ alignment = <0 0x400000>; size = <0 0x800000>; }; + + pstore_reserve_mem: pstore_reserve_mem_region@0 { + linux,reserve-contiguous-region; + linux,reserve-region; + linux,remove-completely; + reg = <0x0 0x9ff00000 0x0 0x00100000>; + label = "pstore_reserve_mem"; + }; }; aliases { @@ -1277,6 +1286,12 @@ reg-names = "fuse-base"; }; + sn_fuse: snfuse@0xa4128 { + compatible = "qcom,sn-fuse"; + reg = <0xa4128 0x4>; + reg-names = "sn-base"; + }; + jtag_mm0: jtagmm@619c000 { compatible = "qcom,jtagv8-mm"; reg = <0x619c000 0x1000>, @@ -1671,9 +1686,9 @@ qcom,ce-opp-freq = <100000000>; }; - qcom_seecom: qseecom@85b00000 { + qcom_seecom: qseecom@84a00000 { compatible = "qcom,qseecom"; - reg = <0x85b00000 0x800000>; + reg = <0x84a00000 0x1900000>; reg-names = "secapp-region"; qcom,hlos-num-ce-hw-instances = <1>; qcom,hlos-ce-hw-instance = <0>; @@ -2088,6 +2103,7 @@ qcom,msm-bus,name = "usb3"; qcom,msm-bus,num-cases = <3>; qcom,msm-bus,num-paths = <1>; + qcom,detect-dpdm-floating; qcom,msm-bus,vectors-KBps = <61 512 0 0>, <61 512 240000 800000>, @@ -2202,9 +2218,9 @@ qcom,vdd-voltage-level = <0 925000 925000>; qcom,qusb-phy-init-seq = <0xF8 0x80 - 0xB3 0x84 - 0x83 0x88 - 0xC0 0x8C + 0x53 0x84 + 0x93 0x88 + 0xCf 0x8C 0x14 0x9C 0x30 0x08 0x79 0x0C From 23dfe9fbfc741a335881f7c272ab927e13ca4e71 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 19 May 2017 16:44:44 +0800 Subject: [PATCH 43/86] drivers: input: touchscreen: Add ft5346 and ist3038c drivers * touchscreens used on Xiaomi Redmi Note 4 (mido) * unused firmwares dropped for both * test code for ft5346 droped * added code to qpnp-smbcharger to notify touchscreen about charger connection --- drivers/input/touchscreen/Kconfig | 27 +- drivers/input/touchscreen/Makefile | 2 + drivers/input/touchscreen/ft5346 | 3078 ++++++++++++ ...12_C6_FT5435_Biel0x3b_Ver0a_20170119_app.i | 3186 ++++++++++++ ...2_C6_FT5435_Ofilm0x51_Ver0a_20170119_app.i | 3186 ++++++++++++ drivers/input/touchscreen/ft5435/Makefile | 7 + drivers/input/touchscreen/ft5435/ft5435_ts.c | 4292 +++++++++++++++++ drivers/input/touchscreen/ft5435/ft5435_ts.h | 93 + .../input/touchscreen/ft5435/mcap_test_lib.h | 26 + .../ist3038c/IST3038C1_00000C6GFF_VER000007.h | 4054 ++++++++++++++++ drivers/input/touchscreen/ist3038c/Makefile | 7 + drivers/input/touchscreen/ist3038c/ist30xxc.c | 2341 +++++++++ drivers/input/touchscreen/ist3038c/ist30xxc.h | 606 +++ .../touchscreen/ist3038c/ist30xxc_cmcs.c | 2106 ++++++++ .../touchscreen/ist3038c/ist30xxc_cmcs.h | 154 + .../touchscreen/ist3038c/ist30xxc_cmcs_bin.h | 756 +++ .../touchscreen/ist3038c/ist30xxc_fw_v02_t1.h | 4054 ++++++++++++++++ .../touchscreen/ist3038c/ist30xxc_misc.c | 2325 +++++++++ .../touchscreen/ist3038c/ist30xxc_misc.h | 53 + .../input/touchscreen/ist3038c/ist30xxc_sys.c | 493 ++ .../touchscreen/ist3038c/ist30xxc_tracking.c | 222 + .../touchscreen/ist3038c/ist30xxc_tracking.h | 44 + .../touchscreen/ist3038c/ist30xxc_update.c | 1623 +++++++ .../touchscreen/ist3038c/ist30xxc_update.h | 95 + drivers/power/qpnp-smbcharger.c | 16 +- 25 files changed, 32842 insertions(+), 4 deletions(-) create mode 100644 drivers/input/touchscreen/ft5346 create mode 100644 drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Biel0x3b_Ver0a_20170119_app.i create mode 100644 drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Ofilm0x51_Ver0a_20170119_app.i create mode 100644 drivers/input/touchscreen/ft5435/Makefile create mode 100644 drivers/input/touchscreen/ft5435/ft5435_ts.c create mode 100644 drivers/input/touchscreen/ft5435/ft5435_ts.h create mode 100644 drivers/input/touchscreen/ft5435/mcap_test_lib.h create mode 100644 drivers/input/touchscreen/ist3038c/IST3038C1_00000C6GFF_VER000007.h create mode 100644 drivers/input/touchscreen/ist3038c/Makefile create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc.c create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc.h create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.c create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.h create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_cmcs_bin.h create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_fw_v02_t1.h create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_misc.c create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_misc.h create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_sys.c create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_tracking.c create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_tracking.h create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_update.c create mode 100644 drivers/input/touchscreen/ist3038c/ist30xxc_update.h diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index dd9b928e3694..364dc15ddeb6 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -547,6 +547,32 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. +config TOUCHSCREEN_FT5435 + tristate "FocalTech touchscreens" + depends on I2C + help + Say Y here if you have a ft5435 touchscreen. + Ft5435 controllers are multi touch controllers which can + report 5 touches at a time. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called ft5435_ts. + +config TOUCHSCREEN_IST3038C + tristate "imagies touchscreens" + depends on I2C + help + Say Y here if you have a ist3038c touchscreen. + Ft5x06 controllers are multi touch controllers which can + report 5 touches at a time. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called ist3038c_ts. + config TOUCHSCREEN_MIGOR tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C @@ -871,7 +897,6 @@ config TOUCHSCREEN_TSC2005 depends on SPI_MASTER help Say Y here if you have a TSC2005 based touchscreen. - If unsure, say N. To compile this driver as a module, choose M here: the diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index be0eb9b34f5b..a475ebd97c4b 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -89,4 +89,6 @@ obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o +obj-$(CONFIG_TOUCHSCREEN_FT5435) += ft5435/ +obj-$(CONFIG_TOUCHSCREEN_IST3038C) += ist3038c/ obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/ diff --git a/drivers/input/touchscreen/ft5346 b/drivers/input/touchscreen/ft5346 new file mode 100644 index 000000000000..4e00345a331e --- /dev/null +++ b/drivers/input/touchscreen/ft5346 @@ -0,0 +1,3078 @@ +0x2, 0x1a,0xb1,0x2, 0xb4,0x79,0xeb,0xaa,0x8, 0x22,0x22,0x2, 0x0, 0x49,0xb4,0x2, +0x4, 0xa9,0xb7,0xea,0x22,0x24,0xff,0xa9,0x97,0xea,0x22,0x2, 0x50,0x23,0xb4,0x2, +0x4, 0xa9,0xb6,0xea,0x22,0x24,0xff,0xa9,0x96,0xea,0x22,0x2, 0x6f,0xfb,0x7f,0x60, +0xa9,0xc2,0xea,0x74,0x1, 0x12,0x12,0x64,0x7f,0x6, 0x12,0x4, 0x6b,0x7f,0x6, 0x2, +0x8, 0xb8,0x22,0x2, 0x70,0x17,0xb2,0x86,0x22,0x32,0x32,0x2, 0x0, 0x4a,0x12,0xf, +0x37,0x2, 0x12,0x47,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32,0x2, 0x0, 0x76,0x1, 0x2, +0x4, 0x8, 0x10,0x20,0x40,0x80,0xf5,0xfd,0xe5,0xfe,0x22,0x2, 0x0, 0x5a,0xe4,0x2, +0x2e,0xe1,0xff,0x2, 0xe, 0xe7,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b, +0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0xd, 0x7e,0xf, 0x3a,0xd4, +0x69,0x30,0x0, 0x4, 0x7a,0x73,0x3a,0xe4,0x7e,0x73,0x3a,0xe4,0xa, 0x37,0x5e,0x34, +0x0, 0x4, 0x68,0x4, 0xd2,0xc, 0x80,0x2, 0xc2,0xc, 0x7e,0x34,0x0, 0x1f,0x79,0x30, +0x0, 0x4, 0xc2,0xc3,0x12,0xf, 0xcd,0x12,0x71,0x52,0x7e,0x1f,0x3a,0xd4,0x69,0x31, +0x0, 0x2, 0x5e,0x34,0x0, 0x40,0x68,0x2e,0x6c,0xaa,0x7e,0x10,0x2, 0xac,0x1a,0x7e, +0x1f,0x3a,0xd4,0x7f,0x71,0x2d,0xf0,0x69,0x17,0x0, 0x9c,0x59,0x10,0x3a,0xd8,0xb, +0xa0,0xbe,0xa0,0x3, 0x78,0xe4,0x69,0x11,0x0, 0xa4,0x7a,0x17,0x3a,0xe0,0x69,0x31, +0x0, 0xa2,0x7a,0x37,0x3a,0xde,0xa9,0xc1,0xc4,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda, +0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x7d,0x13, +0x7e,0x1f,0x3b,0x9, 0x1b,0x1a,0x10,0xc2,0xc6,0xd2,0xee,0x22,0xff,0xff,0x54,0x2c, +0xca,0x3b,0x7f,0x30,0x74,0x1, 0x12,0x12,0xac,0x29,0x73,0x0, 0xef,0x2e,0x70,0xff, +0x92,0x1, 0x29,0xb3,0x0, 0xf0,0x12,0x12,0x7d,0x7f,0x3, 0x12,0xb, 0xb8,0x7f,0x3, +0x12,0x5, 0x71,0x29,0x73,0x0, 0x6, 0xa, 0x37,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, +0x24,0x29,0x73,0x0, 0x9f,0xa, 0x27,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e, +0x24,0x3e,0x24,0x3e,0x24,0x69,0x33,0x0, 0xfb,0x4d,0x32,0x7e,0xf, 0x3a,0xd4,0x79, +0x30,0x0, 0x2, 0x29,0x73,0x0, 0x6, 0xa, 0x47,0x29,0x73,0x0, 0x1, 0xa, 0x57,0x9d, +0x54,0xf5,0x35,0x29,0xb3,0x0, 0xa1,0x70,0xb, 0x29,0xb3,0x0, 0xf4,0x29,0x73,0x0, +0xf3,0x12,0x9, 0xf3,0x29,0x73,0x0, 0xa1,0x2e,0x70,0xff,0x92,0x1, 0xe5,0x35,0x12, +0x9, 0x64,0x69,0x33,0x0, 0xf9,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x28,0x69,0x23, +0x0, 0xf7,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x29,0x73, +0x0, 0xf6,0xa, 0x37,0x2d,0x32,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x2a,0x29,0x73, +0x0, 0xf5,0xa, 0x37,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x2c,0x7e,0x34,0x0, 0x1, +0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x34,0x7e,0x34,0x1, 0xb, 0x7e,0xf, 0x3a,0xd4, +0x79,0x30,0x0, 0x2e,0x29,0x73,0x0, 0x1, 0xa, 0x37,0x7e,0xf, 0x3a,0xd4,0x79,0x30, +0x0, 0x10,0x69,0x33,0x0, 0xa4,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x1c,0x69,0x33, +0x0, 0xa6,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x1e,0x6c,0xaa,0x7e,0x50,0x2, 0xac, +0x5a,0x69,0x13,0x0, 0xfd,0x2d,0x12,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x30,0x7e,0xf, +0x3a,0xd4,0x2d,0x12,0x79,0x30,0x0, 0x44,0xb, 0xa0,0xbe,0xa0,0xc, 0x40,0xdd,0xda, +0x3b,0x22,0xca,0xf8,0x7f,0x50,0x7c,0xfb,0x7e,0x34,0x0, 0x24,0x7e,0x8, 0x0, 0x2c, +0x7e,0x24,0x0, 0x2, 0x12,0x51,0xa6,0xe5,0x2c,0xbe,0xb0,0x0, 0x38,0x2, 0x41,0x6c, +0xe5,0x2c,0xbe,0xb0,0x15,0x28,0x2, 0x41,0x6c,0x7e,0xf1,0x2c,0xbe,0xf0,0x15,0x38, +0x2, 0x41,0x9a,0x7e,0x34,0x1a,0x4c,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1a,0x30,0x79, +0x35,0x0, 0x4, 0xbe,0xf0,0x81,0x68,0x2, 0x41,0x93,0x74,0x23,0x7a,0x5b,0xb0,0x74, +0x1c,0x61,0x5d,0x74,0x1, 0x7a,0x5b,0xb0,0x61,0x5d,0x7c,0xbf,0x14,0xbe,0xb0,0x15, +0x40,0x2, 0x61,0x2b,0x7e,0xa0,0x3, 0xa4,0x90,0x2, 0xac,0x73,0x2, 0x2, 0xed,0x2, +0x2, 0xed,0x2, 0x3, 0x2b,0x2, 0x2, 0xed,0x2, 0x3, 0x2b,0x2, 0x2, 0xf3,0x2, 0x2, +0xed,0x2, 0x3, 0xf, 0x2, 0x3, 0x2b,0x2, 0x3, 0x2b,0x2, 0x3, 0xf, 0x2, 0x3, 0x2b, +0x2, 0x3, 0x2b,0x2, 0x3, 0xf, 0x2, 0x3, 0x2b,0x2, 0x3, 0x2b,0x2, 0x3, 0x1, 0x2, +0x3, 0x2b,0x2, 0x3, 0x1d,0x2, 0x3, 0x1d,0x2, 0x2, 0xed,0x41,0xed,0x7e,0x34,0x1a, +0x20,0x61,0x13,0x7e,0x34,0x1a,0x4c,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1a,0x11,0x61, +0x37,0x7e,0x34,0x1a,0x20,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x19,0xe1,0x61,0x37,0x7e, +0x34,0x1a,0x4c,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1a,0x30,0x61,0x37,0x7e,0x34,0x19, +0xc5,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x19,0xf5,0x61,0x37,0x7e,0x34,0x1a,0x4c,0x79, +0x35,0x0, 0x2, 0x7e,0x34,0x1a,0x30,0x79,0x35,0x0, 0x4, 0x7e,0x70,0x3, 0xac,0x7f, +0x7d,0x23,0x2e,0x24,0x1a,0x70,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0x7a,0x5b, +0xb0,0x2e,0x34,0x1a,0x71,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0x39,0xb5,0x0, +0x1, 0xda,0xf8,0x22,0xca,0xf8,0x7f,0x70,0x7e,0x7b,0xf0,0x29,0x77,0x0, 0x1, 0xbc, +0x7f,0x28,0x2, 0x7c,0xf7,0x69,0x17,0x0, 0x6, 0x6d,0x0, 0x7e,0x34,0x0, 0xf2,0x74, +0xff,0x12,0x1b,0xb8,0x7f,0x7, 0x12,0xd, 0x92,0xa9,0xd6,0xcb,0x6c,0xaa,0x80,0x2d, +0x6c,0x77,0x80,0x1f,0x7e,0x10,0xb, 0xac,0x1a,0xa, 0x17,0x2d,0x1, 0x3e,0x4, 0x69, +0x17,0x0, 0x6, 0x2d,0x10,0x6d,0x0, 0xb, 0xa, 0x20,0x6e,0x24,0xff,0xff,0x1b,0xa, +0x20,0xb, 0x70,0x29,0x67,0x0, 0x1, 0xbc,0x67,0x38,0xd9,0xb, 0xa0,0x7e,0x7b,0x60, +0xbc,0x6a,0x38,0xcc,0x69,0x37,0x0, 0x6, 0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0x4, +0x7c,0x4f,0x6c,0x55,0xa, 0x3f,0x2d,0x32,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0xc, +0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xd0,0x12,0xd, 0xea, +0x6c,0xaa,0xbe,0xa0,0x4, 0x50,0x18,0x7e,0x70,0x4, 0xac,0x7a,0x7c,0xb7,0x7e,0x1f, +0x33,0xfc,0x69,0x41,0x0, 0x26,0x60,0x42,0x1e,0x44,0x14,0x78,0xfb,0x80,0x3b,0xbe, +0xa0,0x8, 0x50,0x1b,0xa, 0x3a,0x1b,0x36,0x3e,0x34,0x3e,0x34,0x7c,0xb7,0x7e,0x1f, +0x33,0xfc,0x69,0x41,0x0, 0x28,0x60,0x22,0x1e,0x44,0x14,0x78,0xfb,0x80,0x1b,0xa, +0x3a,0x9e,0x34,0x0, 0x8, 0x3e,0x34,0x3e,0x34,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69, +0x41,0x0, 0x2a,0x60,0x5, 0x1e,0x44,0x14,0x78,0xfb,0x5e,0x44,0x0, 0xf, 0x7e,0x50, +0x2, 0xac,0x5a,0x69,0x37,0x0, 0x6, 0x2d,0x32,0x6d,0x22,0x1b,0x1a,0x40,0xb, 0xa0, +0xbe,0xa0,0xb, 0x40,0x8d,0xa9,0xc6,0xcb,0xda,0xf8,0x22,0x29,0x70,0x0, 0x92,0x29, +0x90,0x0, 0x94,0x29,0x60,0x0, 0x93,0x29,0x80,0x0, 0x89,0xbe,0x80,0x4, 0x38,0x4, +0x6c,0xaa,0x80,0x21,0xbe,0x80,0x8, 0x38,0x5, 0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x80, +0x10,0x38,0x5, 0x7e,0xa0,0x2, 0x80,0xd, 0xbe,0x80,0x20,0x38,0x5, 0x7e,0xa0,0x3, +0x80,0x3, 0x7e,0xa0,0x4, 0xbe,0x90,0x3, 0x28,0x3, 0x7e,0x90,0x3, 0xbe,0x80,0x3f, +0x28,0x3, 0x7e,0x80,0x3f,0xbe,0x60,0x1, 0x28,0x3, 0x7e,0x60,0x1, 0xbe,0x70,0x2, +0x28,0x2, 0x6c,0x77,0xa, 0x28,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24, +0x7c,0x89,0x6c,0x99,0x3e,0x44,0x3e,0x44,0x3e,0x44,0x2d,0x42,0xa, 0x26,0x3e,0x24, +0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d,0x24,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x2d,0x32, +0x7e,0x7f,0x3b,0x9, 0x79,0x37,0x0, 0x2, 0x29,0xb0,0x0, 0x88,0x7c,0x4b,0x6c,0x55, +0x29,0xb0,0x0, 0x87,0xa, 0x3b,0x2d,0x32,0x7e,0x7f,0x3a,0xcc,0x79,0x37,0x0, 0x80, +0x69,0x30,0x0, 0x9c,0x7e,0x7f,0x3b,0x9, 0x79,0x37,0x0, 0xc, 0x69,0x30,0x0, 0x9a, +0x5e,0x34,0xe0,0xf, 0x29,0xb0,0x0, 0x88,0xa, 0x2b,0x1b,0x24,0x3e,0x24,0x3e,0x24, +0x3e,0x24,0x3e,0x24,0x2d,0x32,0x7e,0x7f,0x3a,0xcc,0x79,0x37,0x0, 0x82,0xa, 0x2a, +0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x29,0xb0,0x0, 0x95,0xa, 0x3b,0x2d,0x32, +0x7e,0x7f,0x3b,0x9, 0x79,0x37,0x0, 0x6, 0x69,0x30,0x0, 0x98,0x7e,0x7f,0x3b,0x9, +0x79,0x37,0x0, 0x8, 0x69,0x30,0x0, 0x96,0x7e,0xf, 0x3b,0x9, 0x79,0x30,0x0, 0xa, +0x22,0x7f,0x60,0x74,0x1, 0x12,0x12,0xac,0x29,0x36,0x0, 0xf1,0x29,0x26,0x0, 0x9f, +0x29,0x16,0x0, 0xa0,0xbe,0x20,0x2, 0x28,0x3, 0x7e,0x20,0x2, 0xbe,0x10,0x40,0x28, +0x3, 0x7e,0x10,0x40,0x7e,0x34,0x0, 0x4, 0x7c,0xb2,0x60,0x5, 0x3e,0x34,0x14,0x78, +0xfb,0x7c,0x7, 0xa, 0x31,0x7e,0x2f,0x3a,0xd4,0x79,0x32,0x0, 0x12,0x7c,0x73,0xac, +0x70,0xa, 0x21,0x12,0x18,0xac,0x7c,0x27,0xa, 0x32,0x7e,0x2f,0x3a,0xd4,0x79,0x32, +0x0, 0x14,0x7c,0x73,0xac,0x70,0x29,0x26,0x0, 0xf2,0xa, 0x22,0xad,0x32,0xa, 0x21, +0x8d,0x32,0x7d,0x43,0x7c,0x73,0xac,0x70,0xa, 0x21,0x12,0x18,0xac,0x7c,0xa7,0x7c, +0x2a,0x7c,0xb9,0x2c,0xab,0xbe,0xa0,0xc, 0x50,0x3, 0x7e,0xa0,0xc, 0xbe,0x20,0xc, +0x50,0x3, 0x7e,0x20,0xc, 0xa, 0x20,0xa, 0x31,0x12,0x18,0xac,0x7d,0xe3,0xa, 0x3a, +0xb, 0x34,0xad,0x3e,0xb, 0x34,0xbe,0x34,0x2, 0x0, 0x40,0x4, 0x7e,0x34,0x1, 0xff, +0x29,0x46,0x0, 0xf3,0x7e,0x50,0x2, 0xac,0x45,0xa, 0xf2,0xad,0xfe,0x2d,0x2f,0xb, +0x24,0xbe,0x24,0x2, 0x0, 0x40,0x4, 0x7e,0x24,0x1, 0xff,0xa, 0x13,0x7e,0x7f,0x3a, +0xd4,0x79,0x17,0x0, 0xa, 0x1e,0x24,0x7c,0x45,0x6c,0x55,0x1e,0x34,0x2d,0x32,0x7e, +0xf, 0x3a,0xd4,0x79,0x30,0x0, 0xc, 0xa, 0x3a,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, +0x22,0x22,0x7f,0x21,0xa9,0xd6,0xcb,0x69,0x30,0x0, 0x4, 0x7e,0x7f,0x33,0xfc,0x79, +0x37,0x0, 0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x6, 0x69, +0x30,0x0, 0x6, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x8, 0x29,0x70,0x0, 0x1, 0x7c, +0x47,0x6c,0x55,0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,0x7e,0x7f,0x33,0xfc,0x79,0x37, +0x0, 0xc, 0x29,0x70,0x0, 0x2, 0xa, 0x37,0x1b,0x34,0x7e,0x7f,0x33,0xfc,0x79,0x37, +0x0, 0xa, 0x69,0x30,0x0, 0xa, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xe, 0x69,0x30, +0x0, 0xc, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x10,0x69,0x30,0x0, 0xe, 0x7e,0x7f, +0x33,0xfc,0x79,0x37,0x0, 0x12,0x29,0x70,0x0, 0x3, 0x7c,0x27,0x6c,0x33,0x7e,0x1f, +0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xa0,0x12,0xd, 0xea,0x7e,0x1f,0x33,0xfc, +0x69,0x11,0x0, 0x1a,0x7a,0x2b,0x30,0x69,0x11,0x0, 0x1c,0x39,0x32,0x0, 0x1, 0x69, +0x11,0x0, 0x16,0x79,0x12,0x0, 0x2, 0x69,0x11,0x0, 0x18,0x79,0x12,0x0, 0x4, 0x69, +0x11,0x0, 0x22,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x24,0x79,0x12,0x0, 0x8, 0x69, +0x11,0x0, 0x1e,0x79,0x12,0x0, 0xa, 0x69,0x31,0x0, 0x20,0x79,0x32,0x0, 0xc, 0xa9, +0xc6,0xcb,0x22,0xca,0x3b,0x7c,0x57,0x7c,0x4b,0x5e,0x40,0x3, 0x69,0x30,0x0, 0x4, +0x5e,0x60,0x3f,0x6c,0xaa,0xa, 0x4a,0x69,0xf0,0x0, 0xa, 0x69,0xe0,0x0, 0x8, 0x2d, +0xf4,0x7e,0x7b,0xb0,0xa, 0xfb,0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4,0xa, 0xea, +0x69,0xd0,0x0, 0xe, 0x69,0xc0,0x0, 0xc, 0x2d,0xde,0x7e,0x6b,0xb0,0xa, 0x4b,0x2d, +0x4f,0x7e,0xd0,0x28,0xac,0xd5,0x7e,0xf0,0x2, 0xac,0xfa,0x7d,0xd7,0x2d,0xd6,0x7e, +0xf0,0xf0,0xac,0xf4,0x2d,0xd7,0x7e,0x7f,0x3b,0x5, 0x2d,0xfd,0x79,0x47,0x1, 0x8c, +0xb, 0xa0,0xbe,0xa0,0xe, 0x78,0xae,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x69,0xf0, +0x0, 0x2, 0xb, 0xa, 0xe0,0x2d,0xf4,0xb, 0x7a,0x40,0x7e,0xd0,0x28,0xac,0xd5,0x7e, +0xf0,0x2, 0xac,0xfa,0x7d,0xd7,0x2d,0xd6,0x7e,0xf0,0xf0,0xac,0xf4,0x2d,0xd7,0x7e, +0x7f,0x3b,0x5, 0x2d,0xfd,0x79,0x47,0x1, 0x80,0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xc9, +0x7e,0x90,0xf0,0xac,0x94,0x74,0x28,0xac,0xb5,0x7d,0xf5,0x2d,0xf4,0x7e,0x2f,0x3b, +0x5, 0x2d,0x5f,0x79,0x32,0x1, 0x88,0x69,0x30,0x0, 0x6, 0x7e,0x30,0xf0,0xac,0x34, +0x74,0x28,0xac,0x5b,0x2d,0x21,0x7e,0xf, 0x3b,0x5, 0x2d,0x12,0x79,0x30,0x1, 0x8a, +0xda,0x3b,0x22,0x74,0x1, 0x7a,0xb3,0x38,0x38,0x22,0xf5,0xfd,0x7a,0x71,0xfe,0x22, +0x7c,0x7b,0x7e,0x7f,0x3a,0xd4,0x69,0x47,0x0, 0xc, 0x6c,0x88,0x3e,0x44,0x69,0x7, +0x0, 0xa, 0x69,0x57,0x0, 0x2, 0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54, +0x1e,0x54,0x1e,0x54,0x5e,0x54,0x0, 0x3, 0x7e,0x14,0x0, 0x4, 0x70,0x2, 0x1, 0x35, +0x3e,0x14,0x14,0x78,0xfb,0x7c,0xa3,0xa, 0xda,0xad,0xd0,0x7d,0xcd,0x6d,0x11,0x79, +0x17,0x0, 0x8c,0x7c,0xb7,0x70,0x2, 0x1, 0x4e,0x1e,0xd4,0x14,0x78,0xfb,0xbe,0xd4, +0x1, 0x0, 0x38,0x2, 0x1, 0x5c,0x7e,0xd4,0x1, 0x0, 0x1, 0x68,0xbe,0xd4,0x0, 0x10, +0x40,0x2, 0x1, 0x68,0x7e,0xd4,0x0, 0x10,0x7d,0x3d,0x12,0x11,0x6a,0xa, 0x1b,0x7e, +0x1f,0x3a,0xd4,0x79,0x11,0x0, 0x90,0x7e,0x1f,0x3a,0xd4,0x79,0xd1,0x0, 0x8e,0x7e, +0x7f,0x3a,0xd4,0x69,0x37,0x0, 0x8, 0xad,0x3c,0x8d,0x3d,0x79,0x37,0x0, 0x92,0x7e, +0x14,0x0, 0x6, 0x7e,0x1f,0x3a,0xd4,0x79,0x11,0x0, 0x94,0x7d,0x24,0x9d,0x20,0xa, +0x3a,0xad,0x32,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x96,0x7e,0x34,0x0, 0x10,0x7e, +0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x98,0x22,0xca,0x79,0x29,0x70,0x0, 0x7, 0xa, 0x27, +0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,0x6d,0x44,0x6c,0xaa,0x7e,0x50,0x2, 0xac,0x5a, +0x7e,0x7f,0x3a,0xcc,0x2d,0xf2,0x79,0x47,0x0, 0x2, 0xb, 0xa0,0xbe,0xa0,0x23,0x78, +0xea,0x6c,0xaa,0x80,0x4f,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0x67,0x0, 0x48,0xbe, +0x60,0x23,0x50,0x1d,0x29,0xb7,0x0, 0xb0,0x7c,0x8b,0x6c,0x99,0x7e,0x50,0x2, 0xac, +0x56,0x7e,0x7f,0x3a,0xcc,0x2d,0xf2,0xb, 0xf5,0xb, 0x7a,0x20,0x4d,0x24,0x1b,0x7a, +0x20,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0xb7,0x0, 0x48,0xa, 0x4b,0x7e,0x50,0x2, +0xac,0x5a,0x7e,0x7f,0x3a,0xcc,0x2d,0xf2,0xb, 0xf5,0xb, 0x7a,0x20,0x4d,0x24,0x1b, +0x7a,0x20,0xb, 0xa0,0xbc,0x7a,0x38,0xad,0x6c,0xaa,0x80,0x1d,0xa, 0x3a,0x2d,0x31, +0x7d,0x20,0x29,0xb1,0x0, 0x6b,0xa, 0x4b,0x7e,0xf0,0x2, 0xac,0xfa,0x7e,0x1f,0x3a, +0xcc,0x2d,0x37,0x79,0x41,0x0, 0x48,0xb, 0xa0,0x29,0xb0,0x0, 0x1, 0xbc,0xba,0x38, +0xdb,0xda,0x79,0x22,0x7c,0x5b,0x7e,0xf, 0x3a,0xd4,0x69,0x40,0x0, 0x22,0x30,0x1, +0x6b,0x6d,0xff,0x7d,0x3f,0xbe,0x50,0x10,0x28,0x2e,0x7e,0x54,0xff,0xff,0x79,0x50, +0x0, 0x42,0x9e,0x50,0x10,0x6c,0xaa,0x80,0x11,0x7e,0xe4,0x0, 0x1, 0x7c,0xba,0x60, +0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x2d,0x3e,0xb, 0xa0,0xbc,0x5a,0x38,0xeb,0x7e,0x6f, +0x3a,0xd4,0x79,0x36,0x0, 0x40,0x80,0x25,0x79,0xf0,0x0, 0x40,0x6c,0xaa,0x80,0x11, +0x7e,0xf4,0x0, 0x1, 0x7c,0xba,0x60,0x5, 0x3e,0xf4,0x14,0x78,0xfb,0x2d,0x3f,0xb, +0xa0,0xbc,0x5a,0x38,0xeb,0x7e,0x7f,0x3a,0xd4,0x79,0x37,0x0, 0x42,0x7d,0x34,0x2e, +0x34,0x0, 0xc, 0x7e,0x7f,0x3a,0xd4,0x79,0x37,0x0, 0x16,0x22,0x6d,0x33,0x79,0x30, +0x0, 0x40,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x42,0x7e,0x1f,0x3a,0xd4,0x79,0x41, +0x0, 0x16,0x22,0x7c,0x17,0x7c,0x3b,0x6d,0x33,0x7e,0x2f,0x3a,0xd4,0x79,0x32,0x0, +0x40,0x7e,0x2f,0x3a,0xd4,0x79,0x32,0x0, 0x42,0x7e,0x7f,0x3a,0xd4,0x69,0x57,0x0, +0x12,0x7c,0xab,0x69,0x37,0x0, 0x2, 0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e, +0x34,0x1e,0x34,0x1e,0x34,0x5e,0x34,0x0, 0x3, 0x7c,0xb7,0x7e,0x44,0x0, 0x4, 0x60, +0x5, 0x3e,0x44,0x14,0x78,0xfb,0x7c,0x29,0xa, 0x22,0xa, 0x3a,0x12,0x18,0xac,0xa, +0x23,0x2d,0x32,0x7c,0xb7,0x7c,0x61,0x6c,0x77,0xa, 0xb, 0x1e,0x4, 0x2d,0x3, 0x79, +0x7, 0x0, 0xc, 0x7c,0x73,0xac,0x72,0xa, 0x2a,0x12,0x18,0xac,0x7e,0xf, 0x3a,0xd4, +0x79,0x30,0x0, 0x16,0x6d,0x33,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x22,0x22,0xa9, +0xd6,0xcb,0x69,0x30,0x0, 0x6, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30, +0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x8, 0x29,0x70,0x0, 0x2, 0x7c,0x47, +0x6c,0x55,0x29,0x70,0x0, 0x3, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32, +0x0, 0xc, 0x7e,0xb, 0x70,0x7c,0x47,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e, +0x2f,0x33,0xfc,0x79,0x32,0x0, 0xa, 0x29,0x70,0x0, 0x4, 0xa, 0x37,0x7e,0x2f,0x33, +0xfc,0x79,0x32,0x0, 0xe, 0x29,0xb0,0x0, 0x5, 0x54,0x1, 0x7c,0x2b,0x6c,0x33,0x7e, +0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xc0,0x12,0xd, 0xea,0xa9,0xc6,0xcb, +0x22,0xca,0x79,0x7c,0xab,0x5e,0xa0,0x3, 0x6c,0x77,0x7e,0x50,0x2, 0xac,0x57,0x69, +0xd0,0x0, 0xe, 0x69,0xc0,0x0, 0xc, 0x2d,0xd2,0x29,0x66,0x0, 0x1, 0xa, 0xf6,0x7d, +0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4,0x7e,0x6b,0x60,0xa, 0x46,0x2d,0x4f,0x7e,0xf0, +0xf0,0xac,0xfa,0x2d,0x27,0x7e,0x7f,0x3b,0x5, 0x2d,0xf2,0x79,0x47,0x2, 0x54,0xb, +0x70,0xbe,0x70,0xe, 0x40,0xc4,0x69,0x40,0x0, 0x4, 0x7e,0xf0,0xf0,0xac,0xfa,0x7e, +0x1f,0x3b,0x5, 0x2d,0x37,0x79,0x41,0x2, 0x50,0x69,0x30,0x0, 0x6, 0x74,0xf0,0xa4, +0x7e,0xf, 0x3b,0x5, 0x2d,0x15,0x79,0x30,0x2, 0x52,0xda,0x79,0x22,0xa9,0xd6,0xcb, +0xc2,0x1b,0x69,0x30,0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30, +0x0, 0x6, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x6, 0x69,0x30,0x0, 0x8, 0x7e,0x2f, +0x33,0xfc,0x79,0x32,0x0, 0x8, 0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, +0x1, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x29,0x70,0x0, +0x2, 0xa, 0x37,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xe, 0x29,0xb0,0x0, 0x3, 0x54, +0x1, 0xa, 0x5b,0x7c,0xab,0xe4,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x50,0x69,0x30,0x0, +0xa, 0x12,0xd, 0xea,0xa9,0xc6,0xcb,0x22,0x69,0x30,0x0, 0xaa,0x7e,0x2f,0x3a,0xd4, +0x79,0x32,0x0, 0x6, 0x29,0x50,0x0, 0xa2,0xa, 0x55,0x7d,0x23,0x1e,0x24,0x9d,0x25, +0x7e,0x2f,0x3a,0xd4,0x79,0x22,0x0, 0x18,0x7d,0x23,0x1e,0x24,0x1b,0x25,0x7e,0x2f, +0x3a,0xd4,0x79,0x22,0x0, 0x38,0x69,0x20,0x0, 0xf9,0x1e,0x34,0x9d,0x32,0x9e,0x34, +0x0, 0xa, 0x7e,0x2f,0x3a,0xd4,0x79,0x32,0x0, 0x26,0x29,0x70,0x0, 0xa3,0xa, 0x37, +0x7e,0x2f,0x3a,0xd4,0x79,0x32,0x0, 0x1a,0x29,0x70,0x0, 0x7, 0xa, 0x27,0x7e,0xb, +0x70,0x2d,0x32,0x7e,0x2f,0x3a,0xd4,0x79,0x32,0x0, 0x8, 0x2, 0x8, 0xb8,0xa9,0xd6, +0xcb,0x69,0x30,0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, +0x6, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x6, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33, +0xfc,0x79,0x32,0x0, 0x8, 0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x1, +0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x29,0x70,0x0, 0x2, +0xa, 0x37,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0xe, 0x6d,0x11,0x7e,0x1f,0x33,0xfc, +0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xe0,0x12,0xd, 0xea,0xa9,0xc6,0xcb,0x22,0xca,0x3b, +0xf5,0x24,0x7f,0x41,0x7f,0x30,0xe5,0x25,0x7e,0x8, 0x0, 0x26,0x12,0x2, 0x42,0xe5, +0x24,0xbe,0xb0,0x23,0x28,0x3, 0x75,0x24,0x23,0x6c,0xaa,0x80,0x36,0xa, 0x3a,0x2d, +0x39,0x7d,0x28,0x7e,0x1b,0xb0,0xbe,0xb1,0x26,0x40,0xd, 0x74,0x23,0xa, 0x4a,0x7f, +0x3, 0x2d,0x14,0x7a,0xb, 0xb0,0x80,0x19,0x7e,0x1b,0xb0,0xa, 0x3b,0x2e,0x35,0x28, +0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0xa, 0x4a,0x7f,0x13,0x2d,0x34,0x7a,0x1b, +0xb0,0xb, 0xa0,0xe5,0x24,0xbc,0xba,0x38,0xc4,0xda,0x3b,0x22,0xa9,0xd6,0xcb,0x69, +0x20,0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x22,0x0, 0x4, 0x69,0x20,0x0, 0x8, 0x7e, +0x2f,0x33,0xfc,0x79,0x22,0x0, 0x8, 0x7e,0xb, 0x50,0xa, 0x55,0x7c,0xab,0xe4,0x29, +0x50,0x0, 0x1, 0xa, 0x25,0x2d,0x25,0x7e,0x2f,0x33,0xfc,0x79,0x22,0x0, 0xc, 0x29, +0x50,0x0, 0x2, 0xa, 0x25,0x7e,0xf, 0x33,0xfc,0x79,0x20,0x0, 0xe, 0x7e,0xf, 0x33, +0xfc,0x79,0x30,0x0, 0xa, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34, +0x0, 0x40,0x12,0xd, 0xea,0xa9,0xc6,0xcb,0x22,0x7c,0xab,0x7e,0x34,0x0, 0x1, 0x7e, +0xf, 0x3b,0x9, 0x79,0x30,0x0, 0xe, 0xc2,0x1a,0xe4,0x7a,0xb3,0x3b,0x4, 0x5e,0xa0, +0x3, 0xa, 0x1a,0x3e,0x14,0x7e,0x1f,0x3a,0xcc,0x1b,0x1a,0x10,0x7e,0xf, 0x3a,0xcc, +0x2e,0x14,0x0, 0x84,0xb, 0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x74,0x1, 0x12, +0x12,0x24,0x7e,0xf, 0x3b,0x9, 0xb, 0xa, 0x30,0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xa9, +0xd3,0xcd,0x7e,0xf, 0x3b,0x9, 0xb, 0x15,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,0xa, +0x30,0x22,0x7f,0x10,0xa9,0xd6,0xcb,0x69,0x11,0x0, 0x2, 0x7e,0x2f,0x33,0xfc,0x79, +0x12,0x0, 0x4, 0x69,0x11,0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x12,0x0, 0x6, 0x69, +0x11,0x0, 0x6, 0x7e,0x2f,0x33,0xfc,0x79,0x12,0x0, 0x8, 0x7e,0x1b,0x30,0xa, 0x3, +0x7e,0x14,0x1, 0x0, 0xad,0x10,0x29,0x71,0x0, 0x1, 0xa, 0x37,0x2d,0x31,0x7e,0xf, +0x33,0xfc,0x79,0x30,0x0, 0xc, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e, +0x34,0x0, 0x60,0x12,0xd, 0xea,0xa9,0xc6,0xcb,0x22,0xa9,0xd7,0xcb,0x7d,0x23,0x4e, +0x50,0x1, 0x7e,0xf, 0x33,0xfc,0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, 0x30,0x80,0x1e, +0x7e,0xf, 0x33,0xfc,0xb, 0xa, 0x30,0x7d,0x23,0x5e,0x24,0x0, 0x8, 0xbe,0x24,0x0, +0x8, 0x78,0xb, 0xa9,0xd7,0xcb,0x4e,0x70,0x4, 0x1b,0xa, 0x30,0xd2,0x1b,0x7e,0xf, +0x33,0xfc,0xb, 0xa, 0x30,0x7d,0x23,0x5e,0x24,0x80,0x0, 0xbe,0x24,0x80,0x0, 0x78, +0xcf,0x4e,0x60,0x40,0x1b,0xa, 0x30,0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10, +0x22,0xca,0x3b,0xf5,0x24,0x7f,0x41,0x7f,0x30,0xe5,0x25,0x7e,0x8, 0x0, 0x26,0x12, +0x2, 0x42,0x6c,0xaa,0x80,0x36,0xa, 0x3a,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0xbe, +0xb1,0x27,0x40,0xd, 0x74,0x1c,0xa, 0x4a,0x7f,0x3, 0x2d,0x14,0x7a,0xb, 0xb0,0x80, +0x19,0x7e,0x1b,0xb0,0xa, 0x3b,0x2e,0x35,0x2a,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4, +0x93,0xa, 0x4a,0x7f,0x13,0x2d,0x34,0x7a,0x1b,0xb0,0xb, 0xa0,0xe5,0x24,0xbc,0xba, +0x38,0xc4,0xda,0x3b,0x22,0xca,0xf8,0x7d,0xe2,0x7d,0xd3,0x7c,0xfb,0xbe,0x30,0x1, +0x28,0x6, 0x7e,0xf4,0x0, 0x10,0x80,0xf, 0xbe,0x30,0x0, 0x28,0x6, 0x7e,0xf4,0x0, +0x8, 0x80,0x4, 0x7e,0xf4,0x0, 0x4, 0x7d,0x1f,0x6d,0x0, 0x6d,0x33,0x7e,0x24,0x0, +0x10,0x12,0x19,0x4b,0x7f,0x1, 0x7d,0x3d,0x6d,0x22,0x12,0x18,0xde,0x7d,0x1e,0x12, +0x18,0xf8,0x74,0x4, 0xac,0xbf,0x7e,0xf, 0x3a,0xd4,0x2d,0x15,0x79,0x30,0x0, 0x82, +0x79,0x20,0x0, 0x80,0xda,0xf8,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca, +0x2b,0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0x1a,0x7e,0xf, 0x3b, +0x9, 0xb, 0xa, 0x30,0x7c,0x57,0x7a,0x53,0x3b,0x4, 0x4e,0x70,0xc, 0x1b,0xa, 0x30, +0xc2,0xc6,0x6d,0x33,0x7e,0xf, 0x3b,0x9, 0x79,0x30,0x0, 0xe, 0x12,0xf, 0xcd,0x12, +0x71,0x52,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b, +0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x74,0x3, 0x12,0x12,0x24,0xa9,0xd1,0xc4,0x7e, +0xf, 0x3a,0xcc,0x2e,0x14,0x0, 0x84,0xb, 0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30, +0x7e,0x14,0x0, 0x1, 0x7e,0x1f,0x3a,0xcc,0x1b,0x1a,0x10,0x7e,0xf, 0x3a,0xd4,0xb, +0x16,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,0xa, 0x30,0xc2,0xd, 0xe4,0x7a,0xb3,0x3a, +0xe4,0x7e,0x1f,0x3a,0xcc,0xb, 0x1a,0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0x74,0x2, +0x2, 0x12,0x24,0x7c,0x6b,0x6c,0xaa,0x80,0x17,0x7e,0x90,0x2, 0xac,0x9a,0x7e,0x7f, +0x3b,0x5, 0x2d,0xf4,0xb, 0x7a,0x20,0x7f,0x70,0x2d,0xf4,0x1b,0x7a,0x20,0xb, 0xa0, +0xbc,0x7a,0x38,0xe5,0x6c,0xaa,0x80,0x20,0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x3b, +0x5, 0x2d,0xf2,0x69,0x27,0x0, 0x38,0xa, 0xf7,0xa, 0x4a,0x2d,0x4f,0x3e,0x44,0x7f, +0x70,0x2d,0xf4,0x1b,0x7a,0x20,0xb, 0xa0,0xbc,0x6a,0x38,0xdc,0x22,0x7e,0xf, 0x3a, +0xcc,0x2e,0x14,0x0, 0x84,0xb, 0xa, 0x30,0x5e,0x70,0xdf,0x1b,0xa, 0x30,0x74,0x3, +0x12,0x12,0x24,0x7e,0x14,0x0, 0x3, 0x7e,0x1f,0x3a,0xcc,0x1b,0x1a,0x10,0x7e,0x1f, +0x3a,0xcc,0xb, 0x1a,0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0xe4,0x2, 0x12,0x24,0xff, +0xca,0x79,0x7c,0xab,0x5e,0xa0,0x3, 0x6c,0x77,0x7e,0x50,0x2, 0xac,0x57,0x7f,0x60, +0x2d,0xd2,0x29,0x66,0x0, 0x1, 0xa, 0xf6,0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4, +0x7e,0x6b,0x60,0xa, 0x46,0x2d,0x4f,0x7e,0xf0,0xf0,0xac,0xfa,0x2d,0x27,0x7e,0x7f, +0x3b,0x5, 0x2d,0xf2,0x79,0x47,0x2, 0x54,0xb, 0x70,0xbe,0x70,0xe, 0x40,0xca,0xda, +0x79,0x22,0x29,0x50,0x0, 0xf1,0xac,0x5b,0x7e,0xf, 0x3a,0xd4,0x69,0x30,0x0, 0xc, +0xa, 0x56,0x3e,0x54,0xbe,0x24,0x2, 0x0, 0x40,0x4, 0x7e,0x24,0x1, 0xff,0xbd,0x25, +0x28,0x1f,0x2e,0x14,0x0, 0xc, 0x6c,0x66,0x1b,0xa, 0x30,0x1e,0x24,0x7c,0x45,0x6c, +0x55,0x7e,0xf, 0x3a,0xd4,0x2e,0x14,0x0, 0xc, 0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, +0x30,0x22,0x7c,0x6b,0x6c,0xaa,0x7e,0x50,0x28,0xac,0x57,0x7e,0x90,0x2, 0xac,0x9a, +0x2d,0x42,0x7e,0x50,0xf0,0xac,0x56,0x2d,0x24,0x7e,0x7f,0x3b,0x5, 0x2d,0xf2,0x69, +0x27,0x1, 0x8c,0x6c,0x44,0xa, 0x4a,0x7f,0x60,0x2d,0xd4,0x7e,0x6b,0xb0,0x7c,0x8b, +0x6c,0x99,0x4d,0x24,0x79,0x27,0x1, 0x8c,0xb, 0xa0,0xbe,0xa0,0xe, 0x40,0xc7,0x22, +0x7c,0x6b,0x6c,0xaa,0x7e,0x50,0x28,0xac,0x57,0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x42, +0x7e,0x50,0xf0,0xac,0x56,0x2d,0x24,0x7e,0x7f,0x3b,0x5, 0x2d,0xf2,0x69,0x27,0x1, +0x8c,0x6c,0x55,0xa, 0x4a,0x7f,0x60,0x2d,0xd4,0x7e,0x6b,0xb0,0xa, 0x4b,0x4d,0x24, +0x79,0x27,0x1, 0x8c,0xb, 0xa0,0xbe,0xa0,0xe, 0x40,0xc9,0x22,0x12,0x50,0x1d,0x7c, +0x6b,0x12,0xb7,0xd8,0x7c,0x7b,0x6c,0xaa,0xbe,0x60,0x15,0x68,0x4, 0xa5,0xbf,0x15, +0x22,0xbc,0x76,0x68,0x5, 0x7e,0xa0,0xf1,0x80,0xb, 0x12,0xb9,0xf9,0xbe,0xb0,0x51, +0x68,0x3, 0x7e,0xa0,0xf2,0x7c,0xba,0x12,0xb9,0xf4,0x4c,0xaa,0x68,0x5, 0x12,0xb5, +0xfa,0x80,0xfe,0x22,0xa9,0xd6,0xcb,0x54,0x3f,0x5e,0x70,0x1f,0x7c,0x2b,0x6c,0x33, +0x3e,0x14,0x3e,0x14,0x2e,0x14,0x0, 0x5, 0xa, 0x37,0x3e,0x34,0x3e,0x34,0x3e,0x34, +0x3e,0x34,0x3e,0x34,0x2d,0x31,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0x2, 0x7e,0xf, +0x33,0xfc,0x79,0x20,0x0, 0x14,0xa9,0xc6,0xcb,0x22,0x7d,0x23,0x6c,0x66,0x7e,0x30, +0x2, 0xac,0x36,0x2e,0x14,0x1b,0x69,0x7a,0x31,0x82,0x7a,0x21,0x83,0xe4,0x93,0xa, +0x1b,0xbd,0x12,0x28,0x7, 0xb, 0x60,0xbe,0x60,0x14,0x40,0xe2,0x7e,0x70,0x2, 0xac, +0x67,0x2e,0x34,0x1b,0x6a,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0x22,0x2e,0x34, +0x4, 0x0, 0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x60,0x7e,0x34,0x4, 0x0, 0x9d,0x32, +0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x62,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x3a,0xd4, +0x79,0x30,0x0, 0x64,0xa, 0x3b,0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x66,0x22,0x7c, +0xa5,0xbe,0x34,0x0, 0x0, 0x28,0x10,0xa, 0x1b,0x3e,0x14,0x7d,0x23,0x7c,0x45,0x6c, +0x55,0x2d,0x21,0xa, 0x3a,0x80,0x8, 0xa, 0x2b,0x3e,0x24,0x7c,0x67,0x6c,0x77,0x2d, +0x32,0x7e,0xf, 0x3b,0x9, 0x79,0x30,0x0, 0x4, 0x22,0x7c,0xa7,0x7e,0x1f,0x3a,0xcc, +0x69,0x41,0x0, 0x8a,0x5e,0x44,0x10,0xf, 0xa, 0x1a,0x3e,0x14,0x3e,0x14,0x3e,0x14, +0x3e,0x14,0xa, 0x5b,0xc4,0x23,0x54,0xe0,0x7c,0xab,0xe4,0x2d,0x51,0x4d,0x45,0x79, +0x41,0x0, 0x8a,0x22,0x7e,0xf, 0x3a,0xcc,0x69,0x30,0x0, 0x84,0x5e,0x70,0xe7,0x1b, +0xb1,0x68,0xc, 0x14,0x68,0xc, 0xb, 0xb1,0x78,0x5, 0x4e,0x70,0x10,0x80,0x3, 0x4e, +0x70,0x8, 0x79,0x30,0x0, 0x84,0x22,0x7e,0x34,0x0, 0x1f,0x7e,0xf, 0x3a,0xd4,0x79, +0x30,0x0, 0x4, 0xa9,0xd2,0xcd,0x7e,0xf, 0x3a,0xd4,0xb, 0xa, 0x30,0x4e,0x70,0x1, +0x1b,0xa, 0x30,0x22,0xbe,0xb0,0x0, 0x28,0xa, 0xa9,0xd7,0xca,0xa9,0xd3,0xcb,0xa9, +0xd2,0xcb,0x22,0xa9,0xc7,0xca,0xa9,0xc3,0xcb,0xa9,0xc2,0xcb,0x22,0x30,0x1, 0xa, +0x54,0x3, 0xa, 0x3b,0x2e,0x34,0x2, 0x0, 0x80,0x2, 0x6d,0x33,0x7e,0xf, 0x3a,0xd4, +0x79,0x30,0x0, 0x3a,0x22,0x7e,0xf, 0x3a,0xcc,0x69,0x30,0x0, 0x8a,0x60,0x5, 0x4e, +0x60,0x10,0x80,0x3, 0x5e,0x60,0xef,0x79,0x30,0x0, 0x8a,0x22,0xbe,0xb0,0x0, 0x28, +0x9, 0xa9,0xd6,0xca,0xd2,0xcd,0xa9,0xd1,0xcb,0x22,0xa9,0xc6,0xca,0xc2,0xcd,0xa9, +0xc1,0xcb,0x22,0x7e,0x34,0x0, 0xf, 0x7e,0xf, 0x3a,0xd4,0x79,0x30,0x0, 0x4, 0xc2, +0xc3,0xd2,0xeb,0x22,0x6, 0xe, 0x15,0x1a,0x1f,0x26,0x2b,0x2d,0x2e,0x2f,0x2c,0x2a, +0x24,0x1f,0x1a,0x14,0xf, 0x8, 0x3, 0x3, 0x6, 0xb, 0x10,0x15,0x1c,0x22,0x28,0x2d, +0x34,0x39,0x3d,0x40,0xe, 0x3, 0x0, 0x0, 0x0, 0x3, 0x8, 0xc, 0x11,0x16,0x1c,0x23, +0x2b,0x32,0x37,0x3c,0x40,0x45,0x4a,0x4d,0x4c,0x4b,0x4a,0x48,0x46,0x46,0x45,0x45, +0x44,0x44,0x43,0x44,0x45,0x78,0x65,0x55,0x2, 0xd, 0x14,0x1b,0x21,0x25,0x2b,0x31, +0x37,0x36,0x33,0x2d,0x28,0x20,0x19,0x14,0xd, 0x8, 0x1, 0x2, 0x5, 0xb, 0x10,0x18, +0x1e,0x23,0x2a,0x30,0x35,0x3a,0x3e,0x3f,0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, +0x1, 0x4, 0x9, 0xf, 0x15,0x1d,0x24,0x2a,0x30,0x35,0x3b,0x3e,0x3f,0x40,0x3f,0x3e, +0x3d,0x3d,0x3c,0x3c,0x3b,0x3b,0x39,0x37,0x1a,0x2d,0x65,0x55,0x1b,0x29,0x27,0x1e, +0x14,0x11,0x1a,0x26,0x2e,0x37,0x3d,0x3f,0x3d,0x37,0x2e,0x21,0x16,0xc, 0x5, 0x1, +0x0, 0x0, 0x1, 0x3, 0xa, 0x13,0x1d,0x26,0x2e,0x33,0x38,0x3a,0x16,0x21,0x2b,0x32, +0x30,0x2a,0x27,0x2a,0x2f,0x2d,0x24,0x1a,0x10,0x7, 0x1, 0x0, 0x2, 0x7, 0x10,0x19, +0x23,0x2d,0x36,0x41,0x49,0x4c,0x4a,0x45,0x3c,0x34,0x2a,0x27,0x51,0x71,0x50,0x55, +0x28,0x12,0x11,0x18,0x23,0x29,0x2b,0x2a,0x2e,0x35,0x3c,0x3e,0x3f,0x39,0x31,0x28, +0x1e,0x15,0xe, 0x6, 0x3, 0x1, 0x0, 0x0, 0x3, 0xc, 0x16,0x20,0x2b,0x32,0x37,0x39, +0x20,0x29,0x32,0x37,0x31,0x28,0x21,0x2a,0x31,0x2d,0x23,0x1b,0x13,0x8, 0x1, 0x0, +0x1, 0x5, 0xc, 0x18,0x20,0x29,0x34,0x3e,0x47,0x4f,0x50,0x4d,0x45,0x3c,0x34,0x31, +0x26,0xcb,0x50,0x55,0x1d,0x2f,0x2c,0x25,0x1a,0x1b,0x20,0x29,0x31,0x31,0x2e,0x2d, +0x35,0x3d,0x3f,0x3d,0x38,0x2c,0x22,0x15,0xd, 0x6, 0x1, 0x0, 0x1, 0x6, 0x10,0x1b, +0x24,0x2f,0x38,0x3d,0xd, 0x1b,0x27,0x31,0x32,0x28,0x1e,0x14,0x15,0x1d,0x28,0x31, +0x34,0x2a,0x1f,0x14,0x9, 0x1, 0x0, 0x4, 0xd, 0x17,0x21,0x2c,0x35,0x40,0x47,0x47, +0x44,0x3c,0x34,0x30,0x1b,0x82,0x50,0x55,0x19,0x2e,0x2a,0x1f,0x18,0x1b,0x22,0x2d, +0x30,0x2e,0x2e,0x35,0x3d,0x3f,0x3d,0x3a,0x2f,0x24,0x18,0xf, 0x7, 0x1, 0x0, 0x0, +0x3, 0xb, 0x16,0x1e,0x29,0x32,0x3a,0x3d,0x11,0x1f,0x28,0x32,0x30,0x26,0x1b,0x14, +0x1c,0x25,0x2e,0x35,0x2e,0x23,0x19,0x11,0x4, 0x0, 0x1, 0x8, 0x10,0x1c,0x25,0x30, +0x38,0x40,0x42,0x3f,0x39,0x32,0x2c,0x27,0xc0,0xd1,0x50,0x55,0x18,0x2c,0x29,0x1e, +0x14,0x13,0x16,0x1e,0x29,0x30,0x2e,0x2c,0x2b,0x37,0x3d,0x3f,0x3e,0x39,0x30,0x25, +0x1b,0x10,0x8, 0x1, 0x0, 0x2, 0x9, 0x13,0x1f,0x2d,0x38,0x3c,0x11,0x1a,0x23,0x2f, +0x33,0x29,0x20,0x16,0xe, 0x13,0x1d,0x28,0x32,0x31,0x28,0x1e,0x16,0xb, 0x2, 0x0, +0x1, 0x8, 0x12,0x1e,0x29,0x33,0x3b,0x3f,0x3c,0x32,0x29,0x26,0x30,0x6e,0x50,0x55, +0x16,0x2b,0x24,0x17,0xd, 0xa, 0xe, 0x15,0x24,0x28,0x25,0x23,0x2b,0x36,0x3b,0x3d, +0x3b,0x37,0x2b,0x20,0x15,0xb, 0x4, 0x0, 0x0, 0x3, 0xe, 0x19,0x27,0x33,0x3d,0x3f, +0x13,0x21,0x2e,0x37,0x3a,0x31,0x27,0x1c,0x13,0x1c,0x28,0x34,0x3e,0x37,0x2d,0x22, +0x18,0xc, 0x1, 0x0, 0x3, 0xd, 0x18,0x25,0x31,0x3c,0x47,0x48,0x42,0x38,0x2e,0x2a, +0x31,0x62,0x50,0x55,0x35,0x2e,0x27,0x22,0x1f,0x1b,0x16,0x10,0xc, 0x8, 0x6, 0x4, +0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x6, 0xb, 0xe, 0x12,0x17,0x1d,0x22,0x26,0x2a,0x30, +0x35,0x39,0x3d,0x3f,0x0, 0x0, 0x1, 0x4, 0x6, 0x8, 0xb, 0x10,0x16,0x1b,0x1f,0x23, +0x28,0x2d,0x32,0x36,0x3b,0x40,0x44,0x48,0x4a,0x4b,0x4c,0x4b,0x4a,0x48,0x46,0x43, +0x40,0x3e,0x3c,0x3a,0x3c,0x9c,0x34,0x55,0x9, 0x17,0x1d,0x26,0x2e,0x37,0x3c,0x3f, +0x3b,0x33,0x2b,0x22,0x1a,0x11,0xb, 0x5, 0x3, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x6, +0xa, 0x11,0x19,0x22,0x2a,0x32,0x39,0x3d,0x30,0x30,0x2f,0x2c,0x26,0x1e,0x17,0xd, +0x5, 0x0, 0x0, 0x1, 0x6, 0xe, 0x15,0x1e,0x26,0x2c,0x32,0x3a,0x41,0x48,0x50,0x5b, +0x61,0x64,0x64,0x60,0x5b,0x56,0x51,0x4f,0xd8,0x2c,0x33,0x55,0x26,0x1c,0x19,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x17,0x17,0x15,0xf, 0x9, 0x4, 0x1, 0x0, 0x0, 0x0, +0x0, 0x1, 0x4, 0xb, 0x12,0x18,0x1f,0x28,0x31,0x37,0x3c,0x40,0x1, 0x7, 0xe, 0x14, +0x1c,0x23,0x2c,0x34,0x3e,0x44,0x4c,0x54,0x5b,0x60,0x5d,0x55,0x4f,0x49,0x43,0x3d, +0x38,0x32,0x2b,0x26,0x22,0x1f,0x1e,0x1c,0x1c,0x1c,0x1c,0x1d,0x66,0x54,0x74,0x55, +0x3e,0x2c,0x21,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1e,0x1e, +0x1d,0x1a,0x11,0xc, 0x7, 0x2, 0x0, 0x0, 0x3, 0xa, 0x12,0x1c,0x23,0x2c,0x38,0x40, +0xc, 0x0, 0x6, 0xf, 0x17,0x22,0x29,0x32,0x3b,0x41,0x47,0x4f,0x55,0x5c,0x66,0x71, +0x79,0x3e,0x76,0x6d,0x64,0x5a,0x52,0x4b,0x42,0x39,0x35,0x33,0x32,0x32,0x31,0x31, +0xf3,0xdb,0x74,0x55,0x9, 0x7, 0x6, 0x6, 0x5, 0x5, 0x4, 0x4, 0x4, 0x4, 0x3, 0x2, +0x2, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa, 0x10,0x14,0x1b,0x22,0x28,0x2e, +0x34,0x39,0x3d,0x40,0x0, 0xb, 0x11,0x16,0x1b,0x22,0x28,0x2c,0x33,0x39,0x40,0x46, +0x4d,0x52,0x56,0x5c,0x61,0x68,0x6d,0x73,0x73,0x71,0x71,0x71,0x70,0x70,0x6f,0x6f, +0x6f,0x6f,0x6d,0x6e,0x79,0x80,0x44,0x55,0x17,0x13,0x12,0x12,0x11,0x10,0xf, 0xd, +0xc, 0xb, 0x9, 0x8, 0x7, 0x4, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x1, 0x4, 0xb, 0x10, +0x16,0x1d,0x24,0x29,0x31,0x39,0x3d,0x40,0x0, 0xe, 0x16,0x1a,0x1f,0x24,0x29,0x2e, +0x33,0x38,0x3e,0x43,0x47,0x50,0x55,0x59,0x62,0x69,0x6e,0x75,0x7c,0xff,0x7d,0x7c, +0x79,0x73,0x6d,0x68,0x60,0x5a,0x57,0x56,0x5d,0x8, 0x44,0x55,0x0, 0x7, 0xb, 0xd, +0x10,0x12,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x19,0x1c,0x1e,0x20,0x22,0x23,0x25, +0x27,0x29,0x2b,0x30,0x32,0x33,0x35,0x38,0x39,0x3b,0x3d,0x3f,0x3e,0x29,0x1f,0x18, +0xf, 0x7, 0x6, 0xc, 0x12,0x1d,0x25,0x2d,0x36,0x3e,0x3b,0x35,0x2c,0x26,0x20,0x19, +0x11,0xa, 0x3, 0x3, 0x9, 0x10,0x18,0x24,0x2c,0x33,0x3a,0x3e,0x60,0x9b,0x32,0x55, +0x0, 0x5, 0x5, 0x5, 0x4, 0x3, 0x2, 0x3, 0x5, 0x7, 0xa, 0xe, 0x11,0x19,0x1b,0x1c, +0x1d,0x1c,0x1c,0x1d,0x1f,0x22,0x25,0x2a,0x31,0x33,0x35,0x37,0x38,0x39,0x3c,0x40, +0x0, 0x12,0x1c,0x24,0x2b,0x34,0x3c,0x39,0x2f,0x29,0x21,0x16,0xf, 0xd, 0x14,0x1e, +0x2a,0x33,0x31,0x27,0x20,0x18,0x10,0x7, 0xa, 0x10,0x1a,0x26,0x2f,0x37,0x3d,0x3f, +0xfb,0x8f,0x32,0x55,0x2c,0x23,0x1f,0x19,0x13,0xc, 0x7, 0x3, 0x0, 0x0, 0x0, 0x1, +0x5, 0xa, 0xf, 0x16,0x1d,0x23,0x2a,0x30,0x36,0x3b,0x3e,0x40,0x3f,0x3e,0x3b,0x38, +0x33,0x2f,0x2b,0x28,0x9, 0x1, 0x0, 0x1, 0x3, 0x9, 0xe, 0x14,0x1b,0x21,0x27,0x2e, +0x36,0x3b,0x3e,0x41,0x41,0x40,0x3d,0x3a,0x36,0x2f,0x2b,0x26,0x20,0x1c,0x16,0x10, +0xc, 0xa, 0x9, 0xb, 0x36,0xdc,0x30,0x55,0x1a,0x9, 0x5, 0x1, 0x0, 0x0, 0x0, 0x2, +0x5, 0x9, 0xf, 0x16,0x1c,0x22,0x2a,0x31,0x36,0x39,0x3c,0x3e,0x3f,0x3f,0x3d,0x38, +0x30,0x27,0x1f,0x18,0x12,0xb, 0x6, 0x5, 0x7, 0x12,0x19,0x22,0x2c,0x36,0x3f,0x49, +0x53,0x5c,0x63,0x66,0x64,0x5f,0x58,0x4c,0x43,0x3d,0x34,0x2b,0x22,0x1b,0x15,0xb, +0x4, 0x0, 0x0, 0x1, 0x4, 0xb, 0x13,0x18,0xf1,0xc, 0x30,0x55,0x39,0x2b,0x24,0x1c, +0x15,0xe, 0x9, 0x6, 0x5, 0x6, 0x9, 0x10,0x19,0x22,0x27,0x2e,0x35,0x3b,0x3e,0x3f, +0x3d,0x38,0x32,0x2c,0x26,0x1f,0x19,0x13,0xb, 0x5, 0x1, 0x0, 0x6, 0x0, 0x1, 0x2, +0x6, 0xb, 0x11,0x17,0x1d,0x24,0x2a,0x2f,0x32,0x34,0x35,0x36,0x37,0x3b,0x41,0x47, +0x4e,0x56,0x5d,0x61,0x64,0x65,0x65,0x63,0x60,0x5c,0x57,0x54,0xd1,0x4a,0x46,0x55, +0x0, 0x1, 0x3, 0x5, 0x7, 0x8, 0xa, 0xb, 0xc, 0xe, 0xf, 0x11,0x12,0x14,0x16,0x1a, +0x1e,0x22,0x24,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x3f, +0x1, 0xe, 0x14,0x1b,0x23,0x28,0x2e,0x35,0x3a,0x40,0x48,0x4f,0x56,0x5d,0x62,0x61, +0x5a,0x53,0x4e,0x47,0x40,0x3b,0x35,0x2d,0x29,0x22,0x1b,0x17,0x10,0x9, 0x5, 0x1, +0x6d,0x7d,0x54,0x55,0x0, 0x2, 0x3, 0x5, 0x6, 0x8, 0xb, 0x10,0x13,0x16,0x17,0x19, +0x1b,0x1d,0x1f,0x21,0x22,0x22,0x22,0x22,0x23,0x25,0x28,0x2e,0x31,0x34,0x36,0x38, +0x3a,0x3c,0x3e,0x3f,0x6, 0x17,0x20,0x27,0x30,0x38,0x3e,0x39,0x32,0x2b,0x25,0x1e, +0x18,0x10,0x9, 0x9, 0x10,0x18,0x1f,0x26,0x2f,0x36,0x3c,0x38,0x2f,0x27,0x1f,0x18, +0xf, 0x8, 0x1, 0x2, 0xc7,0x75,0x31,0x55,0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x8, +0xd, 0x12,0x15,0x17,0x18,0x1a,0x1b,0x1c,0x1d,0x1d,0x1e,0x1f,0x22,0x27,0x2e,0x35, +0x38,0x3b,0x3d,0x3e,0x3f,0x40,0x3f,0x3e,0x6, 0x15,0x1b,0x23,0x29,0x2f,0x37,0x3c, +0x37,0x2e,0x27,0x20,0x1a,0x13,0xe, 0x14,0x1a,0x21,0x27,0x2f,0x38,0x3f,0x3d,0x35, +0x2e,0x26,0x20,0x18,0x11,0xb, 0x3, 0x0, 0x67,0x3f,0x31,0x55,0xc2,0xd5,0x7c,0xb4, +0x30,0xe7,0x8, 0xb2,0xd5,0x6e,0x24,0xff,0xff,0xb, 0x24,0x7c,0xb6,0x30,0xe7,0x12, +0xb2,0xd5,0x6e,0x34,0xff,0xff,0xb, 0x34,0x8d,0x32,0x6e,0x24,0xff,0xff,0xb, 0x24, +0x80,0x2, 0x8d,0x32,0x30,0xd5,0x6, 0x6e,0x34,0xff,0xff,0xb, 0x34,0x22,0x7d,0x51, +0xad,0x3, 0x7d,0x2, 0x7d,0x21,0xad,0x5, 0x2d,0x12,0xad,0x35,0x2d,0x21,0x22,0x7d, +0x2, 0xad,0x31,0xad,0x10,0x2d,0x21,0x22,0x6d,0x0, 0x74,0x10,0x4d,0x0, 0x78,0xb, +0x4d,0x22,0x78,0x27,0x8d,0x31,0x7d,0x12,0x6d,0x22,0x22,0x7d,0x43,0x7d,0x32,0x6d, +0x22,0x2f,0x11,0x2d,0x44,0x50,0x2, 0xa5,0xf, 0xbf,0x10,0x40,0x4, 0x9f,0x10,0xb, +0x90,0x14,0x78,0xed,0x7f,0x1, 0x6d,0x22,0x7d,0x34,0x22,0x7d,0x41,0x7d,0x13,0x8d, +0x24,0x7d,0x2, 0x2f,0x0, 0x40,0x4, 0xbd,0x4, 0x40,0x4, 0x9d,0x4, 0xb, 0x14,0x14, +0x78,0xf1,0x7d,0x23,0x7d,0x31,0x7d,0x10,0x6d,0x0, 0x22,0xc2,0xd5,0x7c,0xb0,0x30, +0xe7,0x8, 0xb2,0xd5,0x9f,0x22,0x9f,0x20,0x7f,0x2, 0x7c,0xb4,0x30,0xe7,0x13,0xb2, +0xd5,0x9f,0x22,0x9f,0x21,0x7f,0x12,0x12,0x18,0xfa,0x9f,0x22,0x9f,0x20,0x7f,0x2, +0x80,0x3, 0x12,0x18,0xfa,0x30,0xd5,0x6, 0x9f,0x22,0x9f,0x21,0x7f,0x12,0x22,0x6c, +0xaa,0x4d,0x11,0x68,0x1a,0x1e,0x54,0x68,0xe, 0xb, 0x38,0x20,0x1b,0x18,0x20,0xb, +0x35,0xb, 0x15,0x1b,0x54,0x78,0xf2,0x50,0x6, 0x7e,0x39,0x40,0x7a,0x19,0x40,0x22, +0x6c,0xaa,0x4d,0x11,0x68,0x1e,0x1e,0x54,0x50,0xc, 0x7e,0x1b,0x0, 0x7a,0x19,0x0, +0x68,0x12,0xb, 0x1c,0xb, 0x14,0xb, 0x1a,0x0, 0x1b,0x18,0x0, 0xb, 0x1d,0xb, 0x15, +0x1b,0x54,0x78,0xf2,0x22,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, +0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x1c,0x1d,0x1e,0x1f,0x20,0x21, +0x22,0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12, +0x13,0x14,0x15,0x16,0x17,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xe, 0xf, +0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x0, 0x1, 0x2, 0x3, 0x4, 0x1c,0x1d,0x1e,0x1f, +0x20,0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, +0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22, +0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, +0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x0, 0x1, 0x2, 0x3, +0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13, +0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x0, +0x1, 0x1, 0x1, 0x10,0x1c,0x2, 0x10,0x1c,0x0, 0x1, 0x1, 0x4, 0xf, 0x1c,0x0, 0x1, +0x1, 0x6, 0x1b,0xf, 0x7, 0xe, 0x1c,0x8, 0x23,0x15,0x0, 0x1, 0x1, 0xa, 0x10,0x19, +0xb, 0x14,0x1c,0xc, 0xf, 0x18,0x0, 0x1, 0x1, 0xe, 0x23,0x15,0x0, 0x1, 0x1, 0x0, +0x1, 0x1, 0x11,0xd, 0x14,0x12,0x10,0x19,0x13,0x1c,0x10,0x14,0x1a,0x10,0x15,0x10, +0x19,0x75,0x84,0x1, 0x7e,0x44,0x3f,0xff,0xe4,0x7a,0x49,0xb0,0x1b,0x44,0x78,0xf9, +0x7e,0xf8,0x3b,0x1e,0x75,0xc, 0x0, 0x75,0xd, 0x0, 0x75,0xe, 0x0, 0xc2,0x8, 0xc2, +0x9, 0x75,0x1c,0x0, 0xc2,0xe, 0xc2,0xf, 0xc2,0x11,0x75,0x1d,0x0, 0x75,0x1e,0x0, +0xc2,0x13,0x75,0x1f,0x0, 0xc2,0x15,0x75,0x5a,0x0, 0xc2,0x16,0xc2,0x17,0xc2,0xa, +0x75,0x1a,0x0, 0x75,0x1b,0x64,0xc2,0x18,0xc2,0x19,0x75,0x5b,0x0, 0xd2,0x5, 0xd2, +0x6, 0xd2,0x7, 0xd2,0x1a,0xc2,0xc, 0xd2,0xd, 0x7e,0x4, 0x0, 0xff,0x7e,0x14,0x1c, +0xa, 0xb, 0xa, 0x40,0x5d,0x44,0x68,0x1a,0x69,0x20,0x0, 0x2, 0xb, 0xe, 0xb, 0x44, +0x80,0xa, 0x7e,0xb, 0xb0,0x7a,0x29,0xb0,0xb, 0x24,0xb, 0xc, 0x1b,0x44,0x78,0xf2, +0x80,0xdf,0x2, 0x1d,0x9b,0x0, 0x0, 0x0, 0x47,0x0, 0xcb,0x1, 0x0, 0x0, 0x10,0xfd, +0xc7,0xfb,0x7e,0xfb,0xfb,0x1, 0xbb,0xc, 0x9e,0x19,0x0, 0x21,0x45,0x0, 0xe, 0x1, +0xf, 0x2, 0x10,0x3, 0x11,0x4, 0x12,0x5, 0x13,0x6, 0x14,0x7, 0x15,0x8, 0x16,0x9, +0x17,0xa, 0x18,0xb, 0x19,0xc, 0x1a,0xd, 0x1b,0xdf,0x22,0xc3,0x21,0xa9,0x20,0x94, +0x1f,0x81,0x1e,0x70,0x1d,0x62,0x1c,0x55,0x1b,0x4a,0x1a,0x41,0x19,0x38,0x18,0x31, +0x17,0x2b,0x16,0x25,0x15,0x21,0x14,0x1c,0x13,0x19,0x12,0x16,0x11,0x13,0x10,0x11, +0xf, 0x10,0xe, 0xca,0xf8,0x7f,0x20,0x80,0xa, 0x7e,0x1b,0xf0,0x7a,0x2b,0xf0,0xb, +0x34,0xb, 0x54,0x69,0xff,0xff,0xfc,0x7d,0xef,0x1b,0xe4,0x79,0xef,0xff,0xfc,0x4d, +0xff,0x78,0xe6,0x7f,0x10,0xda,0xf8,0x22,0x7d,0x43,0x7f,0x10,0x80,0x7, 0x1b,0x44, +0x7a,0xb, 0xb0,0xb, 0x14,0x4d,0x44,0x78,0xf5,0x22,0x5, 0x63,0x31,0x20,0x18,0x13, +0xf, 0xd, 0xc, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x32,0x1, 0x19,0x1, 0x0, 0x2, +0xf8,0x4, 0xe7,0x5, 0xce,0x6, 0xc2,0x7, 0xb5,0x8, 0xff,0x0, 0x1, 0x2, 0x0, 0xff, +0x1, 0x2, 0x0, 0x1, 0xff,0x2, 0x0, 0x1, 0x2, 0xff,0x7d,0x23,0xbe,0x24,0x0, 0x0, +0x48,0x3, 0x7d,0x32,0x22,0x6d,0x33,0x9d,0x32,0x22,0x0, 0x4, 0x36,0xae,0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x34,0x4f,0x1, 0x0, 0x1, 0x25,0xf6,0x1, 0x0, 0x1, 0x39,0x69, +0x0, 0x0, 0x2, 0x39,0xbb,0x0, 0x0, 0x0, 0x2, 0x39,0xbd,0x0, 0x0, 0x0, 0x1, 0x39, +0xbf,0x0, 0x0, 0x1, 0x3b,0x1b,0x0, 0x0, 0x1, 0x3b,0x1c,0x0, 0x0, 0x1, 0x30,0x36, +0x0, 0x0, 0x1, 0x31,0xc7,0x0, 0x0, 0x1, 0x31,0xc8,0x0, 0x0, 0x1, 0x38,0x2d,0x1, +0x0, 0x2, 0x38,0x30,0x0, 0x0, 0x0, 0x1, 0x34,0x88,0x0, 0x0, 0x1, 0x34,0x89,0x0, +0x0, 0x1, 0x34,0x8a,0x0, 0x0, 0x1, 0x38,0x34,0x1, 0x0, 0x1, 0x38,0xae,0x0, 0x0, +0x1, 0x3b,0x1d,0x0, 0x0, 0x6, 0x3b,0xd, 0x3f,0x1f,0x50,0x11,0x20,0x10,0x0, 0x1, +0x3b,0x13,0x16,0x0, 0x1, 0x3b,0x14,0x0, 0x0, 0x1, 0x3b,0x15,0x0, 0x0, 0x1, 0x3b, +0x16,0x0, 0x0, 0x1, 0x3b,0x17,0x0, 0x0, 0x1, 0x3b,0x18,0x0, 0x0, 0x1, 0x0, 0x5c, +0x0, 0x0, 0x1, 0x3, 0xf9,0x0, 0x0, 0x1, 0x31,0xf3,0x0, 0x0, 0x2, 0x32,0x14,0x0, +0x0, 0x0, 0x1, 0x32,0x52,0x0, 0x0, 0x4, 0x39,0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, +0x3, 0xfa,0x0, 0x0, 0x1, 0x3, 0xfb,0x0, 0x0, 0x2, 0x3, 0xfc,0x0, 0x0, 0x0, 0x1, +0x3, 0xfe,0x64,0x0, 0x1, 0x3, 0xff,0x0, 0x0, 0x1, 0x3b,0x1e,0x0, 0x0, 0x1, 0x3b, +0x19,0x0, 0x0, 0x1, 0x3b,0x1a,0x0, 0x0, 0x2, 0x2b,0xb5,0x2b,0xbb,0x0, 0x1, 0x2f, +0x7b,0x2, 0x0, 0x1, 0x2f,0xa4,0x0, 0x0, 0x1, 0x33,0xf1,0x0, 0x0, 0x1, 0x3a,0xc, +0xff,0x0, 0x1, 0x3a,0xd, 0x0, 0x0, 0x1, 0x3a,0xe, 0x0, 0x0, 0x1, 0x3a,0xf, 0x40, +0x0, 0x1, 0x3a,0x10,0x40,0x0, 0x4, 0x3b,0x5, 0x0, 0x0, 0x50,0x0, 0x0, 0x4, 0x3b, +0x9, 0x0, 0x0, 0x64,0x0, 0x0, 0x4, 0x3a,0xcc,0x0, 0x0, 0x6c,0x0, 0x0, 0x4, 0x3a, +0xd0,0x0, 0x0, 0x68,0xc0,0x0, 0x4, 0x3a,0xd4,0x0, 0x0, 0x68,0x0, 0x0, 0x4, 0x3a, +0xe5,0x0, 0x0, 0x40,0x0, 0x0, 0x4, 0x33,0xfc,0x0, 0x0, 0x60,0x0, 0x0, 0x0, 0x3, +0xe8,0x0, 0xc, 0x1, 0xf4,0x3, 0x20,0x0, 0xa, 0x1, 0x4a,0x2, 0xbc,0x0, 0x9, 0x0, +0xc8,0x1, 0xf4,0x0, 0x6, 0x0, 0x3c,0x1, 0x2c,0x0, 0x6, 0x0, 0x3c,0x0, 0x64,0x0, +0x6, 0x0, 0x3c,0x0, 0x50,0x0, 0x6, 0x0, 0x0, 0x0, 0xe, 0x1c,0x23,0x5, 0xdc,0x0, +0x32,0x3, 0xe8,0x0, 0x28,0x0, 0x0, 0x0, 0x1e,0x12,0x26,0xa0,0x12,0x2f,0xc4,0x12, +0x1f,0xe5,0x12,0x31,0xb1,0x12,0x36,0x95,0x2, 0x7, 0xf3,0x12,0x50,0x4f,0x12,0x1d, +0xbd,0x12,0x47,0x2a,0x12,0x1d,0x89,0x7e,0xb3,0x38,0xd6,0x24,0xfd,0x68,0x9, 0xb, +0xb1,0x78,0xf4,0x12,0x38,0xd4,0x80,0xef,0x12,0x2f,0x45,0x80,0xea,0x7e,0x54,0x0, +0x54,0x7e,0x44,0x0, 0xff,0x69,0x32,0x0, 0x4, 0x69,0x22,0x0, 0x2, 0xb, 0x2a,0x10, +0x7a,0x1d,0x26,0x7a,0x15,0x24,0x7e,0x34,0x0, 0x20,0x7e,0x8, 0x0, 0x24,0x7e,0x24, +0x0, 0x6, 0x12,0x51,0xa6,0x7e,0x34,0x61,0x4f,0x12,0x1e,0x81,0x1e,0x34,0x1e,0x34, +0x7a,0x73,0x38,0xaf,0x7e,0x34,0x61,0x51,0x12,0x1e,0x81,0xe, 0x34,0xe, 0x34,0x7a, +0x73,0x38,0xb0,0x7e,0x34,0x61,0x55,0x12,0x1e,0x81,0x12,0x1f,0x85,0x7a,0x73,0x38, +0xb1,0x7e,0x34,0x61,0x57,0x12,0x1e,0x81,0x12,0x1f,0x85,0x7a,0x73,0x38,0xb2,0x7e, +0x34,0x61,0x59,0x12,0x1e,0x81,0x12,0x1f,0x85,0x7a,0x73,0x38,0xb3,0x7e,0x34,0x61, +0x5b,0x12,0x1e,0x81,0x12,0x1f,0x85,0x7a,0x73,0x38,0xb4,0x7e,0x34,0x0, 0x59,0xca, +0x39,0x7e,0x34,0x61,0x5f,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x38,0xb5,0x12,0x1b,0x93, +0x1b,0xfd,0xe5,0x25,0x7a,0xb3,0x38,0xe0,0xe5,0x28,0x7a,0xb3,0x38,0xcf,0x22,0x7e, +0x34,0x61,0x4f,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x30,0x7a,0x37,0x2a,0x5a,0x7e,0x34, +0x61,0x51,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x30,0x7a,0x37,0x2a,0x5c,0x7e,0x34,0x61, +0x53,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x30,0x22,0x7e,0x34,0x61,0x55,0x12,0x1e,0x81, +0x7a,0x37,0x28,0x95,0x7e,0x34,0x61,0xba,0x12,0x1e,0x81,0x7a,0x37,0x28,0x99,0x7e, +0x34,0x61,0xb8,0x12,0x1e,0x81,0x7a,0x37,0x28,0x97,0x7e,0x34,0x62,0x12,0x12,0x1e, +0x81,0x7a,0x37,0x28,0x9b,0x7e,0x34,0x61,0xbc,0x12,0x1e,0x81,0x7a,0x37,0x28,0x9d, +0x7e,0x34,0x61,0xbe,0x12,0x1e,0x81,0x7a,0x37,0x28,0x9f,0x7e,0x34,0x61,0xc0,0x12, +0x1e,0x81,0x7a,0x37,0x28,0xa1,0x7e,0x34,0x61,0xc2,0x12,0x1e,0x81,0x7a,0x37,0x28, +0xa3,0x90,0x61,0xc4,0xe4,0x93,0x7a,0xb3,0x28,0xa5,0xe4,0x7a,0xb3,0x28,0xa8,0x12, +0x3f,0xcf,0x3e,0x34,0x7e,0x8, 0x25,0xf7,0xe4,0x2, 0x1b,0xb8,0x12,0x1f,0x8e,0x7e, +0xb3,0x38,0x3f,0xb4,0x1, 0x16,0x7e,0x34,0x62,0x34,0x12,0x1e,0x81,0x7a,0x37,0x2a, +0x5a,0x7e,0x34,0x62,0x36,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x5c,0x7e,0xb3,0x28,0xa8, +0xb4,0x1, 0x37,0x7e,0x34,0x62,0x3e,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x5a,0x7e,0x34, +0x62,0x40,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x5c,0x7e,0x34,0x62,0x42,0x12,0x1e,0x81, +0x7a,0x37,0x2a,0x4f,0x7e,0x34,0x62,0x44,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x51,0x7e, +0x34,0x62,0x46,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x53,0x7e,0xb3,0x2a,0x2, 0x70,0x21, +0x7e,0x27,0x2a,0x5a,0x7d,0x32,0x7e,0x14,0x0, 0x4, 0xad,0x13,0x7d,0x31,0x12,0x1f, +0x85,0xbe,0x34,0x0, 0x50,0x28,0x4, 0x7e,0x34,0x0, 0x50,0x2d,0x32,0x7a,0x37,0x2a, +0x5a,0x22,0xb, 0x28,0x30,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x22,0x12,0x1e, +0x5f,0x12,0x58,0x4b,0x7e,0x34,0x61,0x55,0x12,0x1e,0x81,0x12,0xc0,0x6, 0x12,0x1e, +0x81,0x7a,0x37,0x2a,0x51,0x7e,0x34,0x61,0x59,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x53, +0x22,0x7e,0xb3,0x38,0x37,0x60,0xf, 0x74,0x1, 0x7a,0xb3,0x38,0x3f,0x7e,0xb3,0x38, +0xad,0x70,0x3, 0x12,0xa6,0x8f,0x7e,0xb3,0x38,0x3f,0xb4,0x1, 0xc, 0x74,0x3, 0x12, +0xc0,0x18,0x12,0x1e,0x81,0x3e,0x34,0x80,0x7, 0xe4,0x12,0xc0,0x18,0x12,0x1e,0x81, +0x7a,0x37,0x2a,0x62,0x22,0x12,0x47,0x73,0x12,0x77,0xf8,0x2, 0x1f,0xee,0x7e,0x34, +0x0, 0x3, 0x6d,0x22,0x2, 0x1f,0xf7,0x7d,0x43,0x7e,0xa3,0x34,0x38,0xbe,0xa0,0x5, +0x50,0x16,0x7e,0x70,0x4, 0xac,0x7a,0x59,0x43,0x34,0x3b,0x59,0x23,0x34,0x3d,0x7c, +0xba,0x4, 0x7a,0xb3,0x34,0x38,0xc3,0x22,0xd3,0x22,0xca,0xf8,0x7c,0xab,0xbe,0xa0, +0x34,0x38,0x2, 0x21,0x0, 0xbe,0xa0,0x35,0x78,0x6, 0x7e,0xb3,0x2b,0xc, 0x41,0x16, +0xbe,0xa0,0x36,0x68,0x5, 0xbe,0xa0,0x37,0x78,0x1d,0x7e,0x35,0x8, 0x7d,0x23,0xb, +0x24,0x7a,0x25,0x8, 0x2e,0x37,0x36,0xac,0x7e,0x39,0xb0,0xbe,0xa0,0x37,0x68,0x2, +0x41,0x16,0x75,0x19,0x36,0x41,0x16,0xbe,0xa0,0x38,0x68,0x5, 0xbe,0xa0,0x39,0x78, +0x1b,0x7e,0xf3,0x39,0x8e,0x7c,0xbf,0x4, 0x7a,0xb3,0x39,0x8e,0xbe,0xa0,0x39,0x78, +0x3, 0x75,0x19,0x38,0xa, 0x3f,0x9, 0xb3,0x2b,0x1d,0x41,0x16,0xbe,0xa0,0x3a,0x68, +0x5, 0xbe,0xa0,0x3b,0x78,0x1b,0x7e,0xf3,0x39,0x90,0x7c,0xbf,0x4, 0x7a,0xb3,0x39, +0x90,0xbe,0xa0,0x3b,0x78,0x3, 0x75,0x19,0x3a,0xa, 0x3f,0x9, 0xb3,0x2b,0x40,0x41, +0x16,0xbe,0xa0,0xfb,0x78,0x6, 0x7e,0xb3,0x2b,0xe, 0x41,0x16,0xbe,0xa0,0x3c,0x68, +0x5, 0xbe,0xa0,0x3d,0x78,0x1b,0x7e,0xf3,0x39,0x92,0x7c,0xbf,0x4, 0x7a,0xb3,0x39, +0x92,0xbe,0xa0,0x3d,0x78,0x3, 0x75,0x19,0x3c,0xa, 0x3f,0x9, 0xb3,0x2a,0x76,0x41, +0x16,0xbe,0xa0,0x3e,0x68,0x5, 0xbe,0xa0,0x3f,0x78,0x1b,0x7e,0xf3,0x39,0x94,0x7c, +0xbf,0x4, 0x7a,0xb3,0x39,0x94,0xbe,0xa0,0x3f,0x78,0x3, 0x75,0x19,0x3e,0xa, 0x3f, +0x9, 0xb3,0x2a,0x99,0x41,0x16,0xbe,0xa0,0x40,0x40,0xd, 0xbe,0xa0,0x48,0x38,0x8, +0xa, 0x3a,0x9, 0xb3,0x39,0x6a,0x41,0x16,0xbe,0xa0,0x4e,0x68,0x5, 0xbe,0xa0,0x4f, +0x78,0x1e,0x7e,0xf3,0x39,0xaf,0x7c,0xbf,0x4, 0x7a,0xb3,0x39,0xaf,0xbe,0xa0,0x4f, +0x78,0x3, 0x75,0x19,0x4e,0xa, 0x3f,0x2e,0x37,0x36,0xaa,0x7e,0x39,0xb0,0x41,0x16, +0xbe,0xa0,0x51,0x68,0x5, 0xbe,0xa0,0x52,0x78,0x28,0x7e,0x14,0x60,0x0, 0x6d,0x0, +0x2e,0x4, 0x0, 0xff,0x7e,0xb3,0x39,0xba,0xa, 0x3b,0x6d,0x22,0x2f,0x10,0x7e,0x1b, +0x70,0x4, 0x7a,0xb3,0x39,0xba,0xbe,0xa0,0x52,0x78,0x3, 0x75,0x19,0x51,0x7c,0xb7, +0x41,0x16,0xbe,0xa0,0x5c,0x68,0x5, 0xbe,0xa0,0x5d,0x78,0x1a,0x7e,0xf3,0x39,0x83, +0x7c,0xbf,0x4, 0x7a,0xb3,0x39,0x83,0xbe,0xa0,0x5d,0x78,0x3, 0x75,0x19,0x5c,0x7c, +0xbf,0x12,0xaf,0x5, 0x41,0x16,0xbe,0xa0,0x60,0x40,0xd, 0xbe,0xa0,0x6c,0x38,0x8, +0xa, 0x3a,0x9, 0xb3,0x3a,0x8d,0x80,0x7e,0xbe,0xa0,0xf4,0x68,0x5, 0xbe,0xa0,0xf5, +0x78,0x18,0x7e,0x35,0xa, 0x7d,0x23,0xb, 0x24,0x7a,0x25,0xa, 0x9, 0xb3,0x36,0xb2, +0xbe,0xa0,0xf5,0x78,0x61,0x75,0x19,0xf4,0x80,0x5c,0xbe,0xa0,0xf0,0x68,0x5, 0xbe, +0xa0,0xf1,0x78,0x9, 0x7c,0x1a,0x2e,0x10,0x1f,0xa5,0xe7,0x80,0x49,0xbe,0xa0,0xf2, +0x68,0x5, 0xbe,0xa0,0xf3,0x78,0x1b,0x7e,0x15,0xf, 0x3e,0x14,0x7e,0x1f,0x36,0xae, +0x2d,0x31,0xb, 0x1a,0x30,0xbe,0xa0,0xf2,0x78,0x4, 0xa, 0x56,0x80,0x28,0x7d,0x53, +0x80,0x24,0xbe,0xa0,0xf6,0x78,0x4, 0xe5,0xe, 0x80,0x1b,0xbe,0xa0,0xf7,0x78,0xd, +0x7e,0x34,0x62,0x48,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x50,0x80,0x9, 0xbe,0xa0,0xfd, +0x78,0x3, 0xe4,0x80,0x1, 0xe4,0xda,0xf8,0x22,0x7c,0x7b,0x6c,0xaa,0x12,0x24,0xf1, +0x78,0x9, 0x7c,0xb7,0x12,0x68,0x66,0x7c,0xab,0x80,0xa, 0xb4,0x4, 0x7, 0x7c,0xb7, +0x12,0x20,0x1a,0x7c,0xab,0x7c,0xba,0x22,0x30,0x90,0x19,0xc2,0x90,0xe5,0x17,0x70, +0x9, 0x75,0x17,0x1, 0xe5,0x91,0xf5,0x19,0x80,0x11,0x7e,0x71,0x91,0xe5,0x19,0x12, +0x22,0x63,0x5, 0x19,0x30,0x91,0xb, 0xc2,0x91,0x5, 0x19,0xe5,0x19,0x12,0x22,0x19, +0xf5,0x91,0x22,0x7c,0x6b,0x12,0x24,0xf1,0x78,0x5, 0x7c,0xb6,0x2, 0x70,0x49,0xb4, +0x4, 0x5, 0x7c,0xb6,0x2, 0x22,0x78,0x22,0xca,0xf8,0x7c,0x6b,0xa5,0xbe,0x0, 0x9, +0x7c,0xb7,0x12,0x70,0x1e,0xd2,0x8, 0x81,0xe7,0xa5,0xbe,0x1, 0x3d,0x7a,0x73,0x39, +0x6b,0xa5,0xbf,0xad,0x2, 0x80,0x2f,0xa5,0xbf,0xae,0x4, 0xd2,0x9, 0x81,0xe7,0xa5, +0xbf,0xaa,0x5, 0x12,0xc0,0x33,0x80,0x1e,0xa5,0xbf,0xab,0xa, 0x7e,0x34,0x5, 0x7a, +0x7a,0x37,0x36,0xac,0x80,0x10,0xa5,0xbf,0xac,0x2, 0x80,0x2, 0x81,0xe7,0x7e,0x34, +0x4, 0xfc,0x7a,0x37,0x36,0xac,0x6d,0x33,0x61,0x6c,0xbe,0x60,0x4, 0x40,0x22,0xbe, +0x60,0x8, 0x38,0x1d,0xd2,0x8, 0x12,0x24,0xea,0xa5,0xbe,0x7, 0x7, 0x6d,0x33,0x7a, +0x35,0xa, 0x81,0xe7,0xa5,0xbe,0x8, 0x2, 0x80,0x2, 0x81,0xe7,0x12,0x0, 0x46,0x81, +0xe7,0xa5,0xbe,0xa, 0x9, 0x43,0xc, 0x20,0x7a,0x73,0x39,0x74,0x81,0xe7,0xbe,0x60, +0x1b,0x40,0x7, 0xbe,0x60,0x1c,0x38,0x2, 0x81,0x88,0xbe,0x60,0x1e,0x40,0xd, 0xbe, +0x60,0x23,0x38,0x8, 0x12,0x24,0xea,0x43,0xc, 0x40,0x81,0xe7,0xbe,0x60,0x15,0x40, +0x1a,0xbe,0x60,0x18,0x38,0x15,0x12,0x24,0xea,0xd2,0x8, 0xa5,0xbe,0x15,0x2, 0x80, +0x2, 0x81,0xe7,0x74,0x7, 0x7a,0xb3,0x39,0x6e,0x81,0xe7,0xa5,0xbe,0x19,0x7, 0xe4, +0x7a,0xb3,0x39,0x83,0x81,0xe7,0xbe,0x60,0x24,0x40,0x7, 0xbe,0x60,0x2c,0x38,0x2, +0x81,0x88,0xa5,0xbe,0x2d,0x1b,0x12,0x24,0xea,0x20,0x9, 0x2, 0x81,0xe7,0x7e,0x63, +0x39,0x96,0x7c,0x46,0x6c,0x55,0xa, 0x37,0x2d,0x32,0x3e,0x34,0x7a,0x35,0x8, 0x81, +0xe7,0xbe,0x60,0x2f,0x40,0xa, 0xbe,0x60,0x33,0x38,0x5, 0x43,0xc, 0x8, 0x81,0x88, +0xa5,0xbe,0x34,0xf, 0x43,0xc, 0x10,0xbe,0x70,0x64,0x38,0x2, 0x81,0x88,0x7e,0x70, +0x64,0x81,0x88,0xbe,0x60,0x38,0x68,0x4, 0xa5,0xbe,0x39,0x21,0x43,0xc, 0x1, 0x7e, +0xf3,0x39,0x8f,0x7c,0xbf,0x4, 0x7a,0xb3,0x39,0x8f,0xa, 0x2f,0x19,0x72,0x2b,0x1d, +0xa5,0xbe,0x39,0x2, 0x80,0x2, 0x81,0xe7,0x75,0x19,0x38,0x81,0xe7,0xbe,0x60,0x3a, +0x68,0x4, 0xa5,0xbe,0x3b,0x21,0x43,0xc, 0x2, 0x7e,0xf3,0x39,0x91,0x7c,0xbf,0x4, +0x7a,0xb3,0x39,0x91,0xa, 0x2f,0x19,0x72,0x2b,0x40,0xa5,0xbe,0x3b,0x2, 0x80,0x2, +0x81,0xe7,0x75,0x19,0x3a,0x81,0xe7,0xa5,0xbe,0xfb,0x9, 0x43,0xc, 0x4, 0x7a,0x73, +0x2b,0xe, 0x81,0xe7,0xa5,0xbe,0x50,0x6, 0x7a,0x73,0x39,0xba,0x81,0xe7,0xbe,0x60, +0x3c,0x68,0x4, 0xa5,0xbe,0x3d,0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x39,0x93,0x7c,0xbf, +0x4, 0x7a,0xb3,0x39,0x93,0xa, 0x2f,0x19,0x72,0x2a,0x76,0xa5,0xbe,0x3d,0x2, 0x80, +0x2, 0x81,0xe7,0x75,0x19,0x3c,0x81,0xe7,0xbe,0x60,0x3e,0x68,0x4, 0xa5,0xbe,0x3f, +0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x39,0x95,0x7c,0xbf,0x4, 0x7a,0xb3,0x39,0x95,0xa, +0x2f,0x19,0x72,0x2a,0x99,0xa5,0xbe,0x3f,0x2, 0x80,0x2, 0x81,0xe7,0x75,0x19,0x3e, +0x81,0xe7,0xbe,0x60,0x40,0x40,0xd, 0xbe,0x60,0x42,0x38,0x8, 0x12,0x24,0xea,0x75, +0xd, 0x1, 0x80,0xa, 0xa5,0xbe,0x43,0xb, 0x12,0x24,0xea,0x75,0xd, 0x2, 0x12,0x24, +0xf9,0x80,0x74,0xa5,0xbe,0x44,0x8, 0x12,0x24,0xea,0x12,0x26,0xfd,0x80,0x68,0xbe, +0x60,0x45,0x68,0x4, 0xa5,0xbe,0x46,0x5, 0x12,0x24,0xea,0x80,0x5a,0xbe,0x60,0x4e, +0x68,0x4, 0xa5,0xbe,0x4f,0x20,0x43,0xd, 0x4, 0x7e,0xf3,0x39,0xb0,0x7c,0xbf,0x4, +0x7a,0xb3,0x39,0xb0,0xa, 0x2f,0x2e,0x27,0x36,0xaa,0x7a,0x29,0x70,0xa5,0xbe,0x4f, +0x36,0x75,0x19,0x4e,0x80,0x31,0xbe,0x60,0xf0,0x40,0x25,0xbe,0x60,0xf3,0x38,0x20, +0x7c,0x16,0x2e,0x10,0x1f,0x7c,0xb7,0xa5,0xf7,0xa5,0xbe,0xf3,0x1a,0x7e,0x15,0x11, +0x7e,0x5, 0xf, 0x3e,0x4, 0x7e,0x1f,0x36,0xae,0x2d,0x30,0x1b,0x1a,0x10,0x80,0x7, +0xa5,0xbe,0xf6,0x3, 0x7a,0x71,0xe, 0xda,0xf8,0x22,0xa, 0x26,0x19,0x72,0x39,0x6a, +0x22,0x7e,0xb3,0x39,0x6a,0xc4,0x54,0x7, 0x22,0x12,0x27,0x95,0xb4,0x1, 0x14,0xca, +0x39,0x7e,0x18,0x39,0xaa,0x7e,0x8, 0x25,0xee,0x12,0x1b,0x93,0x1b,0xfd,0x12,0x26, +0xd6,0x80,0x12,0xca,0x39,0x7e,0x18,0x39,0xaa,0x7e,0x8, 0x2b,0x6c,0x12,0x1b,0x93, +0x1b,0xfd,0x12,0x26,0xf4,0x2, 0x25,0x28,0x7a,0x1f,0x2a,0xf8,0x7a,0xf, 0x2a,0xf4, +0x22,0x7a,0xb3,0x2a,0xfc,0x70,0x14,0x12,0x26,0xf4,0x12,0x25,0x28,0x7e,0x18,0x6, +0x76,0x7a,0x1f,0x6, 0xf4,0x7e,0x18,0x4, 0x7e,0x80,0x10,0xb4,0x1, 0x11,0x12,0x26, +0xd6,0x12,0x25,0x28,0x12,0xae,0x36,0x7e,0x18,0x4, 0x0, 0x7a,0x1f,0x6, 0xf8,0x22, +0x74,0x1, 0x12,0x0, 0x1e,0xe4,0x12,0x25,0x31,0x12,0x25,0x78,0xe4,0x12,0x0, 0x1e, +0x74,0x1, 0x12,0x25,0x31,0x2, 0x25,0x78,0xca,0x3b,0x90,0x61,0x26,0xe4,0x93,0x7c, +0xdb,0x90,0x61,0x27,0xe4,0x93,0x7c,0xcb,0x7e,0x8, 0x1f,0x44,0x7e,0x34,0x0, 0x46, +0x74,0x3f,0x12,0x1b,0xb8,0x7e,0x8, 0x1f,0x8a,0x7e,0x34,0x0, 0x46,0x12,0x1b,0xb8, +0x7e,0x8, 0x1f,0xd0,0x7e,0x34,0x0, 0xa, 0xe4,0x12,0x1b,0xb8,0x7e,0x8, 0x1f,0xda, +0x7e,0x34,0x0, 0xa, 0x12,0x1b,0xb8,0x7e,0xf3,0x2a,0xf8,0x7e,0x18,0x2a,0xd8,0x7a, +0x1d,0x24,0x7e,0x18,0x1f,0xd0,0x7a,0x1d,0x28,0x7c,0xbd,0x7c,0x7c,0x7e,0x8, 0x2a, +0xb5,0x12,0xb8,0x7, 0x6c,0xee,0x80,0x27,0xa, 0x3e,0x9, 0xa3,0x2a,0xd8,0xa, 0x3a, +0x12,0x90,0xc7,0x7c,0xab,0xbe,0xa0,0x1c,0x50,0x13,0xa, 0x3e,0x12,0x26,0x98,0xa, +0x4a,0x19,0xb4,0x1f,0x44,0x7e,0xb3,0x2a,0xf7,0x19,0xb4,0x1f,0x8a,0xb, 0xe0,0xbc, +0xce,0x38,0xd5,0x6c,0xee,0x80,0x24,0xa, 0x3e,0x9, 0xa3,0x2a,0xb5,0xbe,0xa0,0x23, +0x50,0x17,0xa, 0x2e,0xa, 0x3c,0x2d,0x32,0x12,0x26,0x98,0xa, 0x4a,0x19,0xb4,0x1f, +0x60,0x7e,0xb3,0x2a,0xf7,0x19,0xb4,0x1f,0xa6,0xb, 0xe0,0xbc,0xde,0x38,0xd8,0x7e, +0xb3,0x2a,0xf9,0x7e,0x8, 0x1f,0xe4,0x60,0x9, 0x7e,0x18,0x1f,0xd0,0x12,0xb6,0x36, +0x80,0x3, 0x12,0xb9,0x53,0x6c,0xee,0x7e,0x18,0x1f,0xe4,0x7a,0x1f,0x1f,0x34,0x74, +0x2, 0xac,0xbe,0x49,0x35,0x1f,0xd0,0x7a,0x37,0x1f,0x38,0x74,0x2, 0xac,0xbe,0x49, +0x35,0x1f,0xda,0x7a,0x37,0x1f,0x3a,0x7e,0x70,0xe, 0xac,0x7e,0x2e,0x34,0x1f,0x44, +0x6d,0x22,0x7a,0x1f,0x1f,0x3c,0x7e,0x70,0xe, 0xac,0x7e,0x2e,0x34,0x1f,0x8a,0x7a, +0x1f,0x1f,0x40,0x7e,0x8, 0x1f,0x34,0x7c,0xbf,0x7c,0x7e,0x12,0x7, 0x23,0xb, 0xe0, +0xbe,0xe0,0x5, 0x40,0xb2,0xda,0x3b,0x22,0x2e,0x37,0x2a,0xfa,0x7e,0x39,0xb0,0x22, +0x74,0x1, 0x7a,0xb3,0x38,0xd6,0x12,0xa9,0x9c,0x12,0x12,0xc3,0x12,0xb8,0xcb,0xe4, +0x12,0x8, 0x0, 0x7e,0x24,0x3, 0xd4,0x12,0x2f,0xe1,0x74,0x1, 0x12,0x25,0x31,0x12, +0xc0,0x44,0x7e,0x34,0xd0,0xc, 0x12,0x1, 0xe, 0x12,0x25,0x60,0x7e,0x34,0x0, 0x1, +0x12,0xbf,0xd9,0x2, 0x10,0xfc,0x7e,0x1f,0x25,0xf2,0x7e,0xf, 0x25,0xee,0x22,0x7a, +0xb3,0x2a,0xfc,0x70,0x5, 0x12,0x26,0xf4,0x80,0x6, 0xb4,0x1, 0x6, 0x12,0x26,0xd6, +0x12,0x25,0x28,0x22,0x7e,0x1f,0x2b,0x70,0x7e,0xf, 0x2b,0x6c,0x22,0x12,0x27,0x95, +0xb4,0x1, 0x17,0xca,0x39,0x7e,0x18,0x25,0xee,0x7e,0x8, 0x39,0xaa,0x12,0x1b,0x93, +0x1b,0xfd,0x12,0xc0,0x2a,0x12,0x26,0xd6,0x80,0x1a,0xca,0x39,0x7e,0x18,0x2b,0x6c, +0x7e,0x8, 0x39,0xaa,0x12,0x1b,0x93,0x1b,0xfd,0x7e,0x37,0x2b,0x72,0x7a,0x37,0x36, +0xaa,0x12,0x26,0xf4,0x2, 0x25,0x28,0xe5,0xd, 0x60,0x52,0xe5,0xd, 0x30,0xe0,0x6, +0x53,0xd, 0xfe,0x12,0x27,0x8e,0xe5,0xd, 0x30,0xe1,0x14,0x53,0xd, 0xfd,0x7e,0xb3, +0x39,0xae,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x12,0xc0,0x3c,0x12,0x6d,0x91,0xe5, +0xd, 0x30,0xe2,0x29,0x53,0xd, 0xfb,0xe4,0x7a,0xb3,0x39,0xaf,0x7e,0xb3,0x39,0xae, +0x70,0xa, 0x74,0x1, 0x12,0x0, 0x1e,0x12,0x26,0xf4,0x80,0x7, 0xe4,0x12,0x0, 0x1e, +0x12,0x26,0xd6,0x12,0x25,0x28,0x7e,0xb3,0x2a,0xf8,0x2, 0x28,0x6e,0x22,0x7e,0x8, +0x2a,0x6d,0x2, 0x4, 0x6b,0x7e,0xb3,0x39,0xae,0x7e,0x34,0x0, 0x4, 0x22,0x7c,0x96, +0x7c,0xa7,0x12,0x25,0x31,0x7c,0xba,0x12,0x12,0x95,0x74,0xa, 0x12,0x4b,0x6c,0x7c, +0xb9,0x12,0x0, 0x1e,0x2, 0x27,0xb7,0xca,0x3b,0x90,0x61,0x27,0xe4,0x93,0x7c,0xeb, +0x7e,0xf3,0x2a,0xf6,0x74,0x1, 0x7a,0xb3,0x2a,0xf6,0x12,0x27,0x8e,0x12,0xbf,0xd7, +0x7e,0x17,0x2a,0xfa,0x6d,0x0, 0x90,0x61,0x28,0x93,0xa, 0x3b,0xe4,0x12,0x1b,0xb8, +0x7e,0xd0,0x7, 0x12,0x2b,0x13,0x6c,0xcc,0x80,0x19,0x7e,0x34,0x0, 0x1, 0x7c,0xbd, +0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7c,0x67,0x12,0xbf,0xf3,0x4c,0x76,0x7a,0x29, +0x70,0xb, 0xc0,0x12,0x28,0xe1,0x38,0xe2,0x12,0x28,0xf3,0x30,0x1a,0xfd,0x12,0xbf, +0xe9,0x90,0x61,0x26,0xe4,0x93,0x7c,0x7e,0x12,0x2a,0x52,0x6c,0xcc,0x80,0x29,0x74, +0x2, 0xac,0xbc,0x49,0x35,0x6, 0xfc,0xbe,0x34,0x15,0x40,0x50,0x19,0x7e,0x34,0x0, +0x1, 0x7c,0xbd,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7c,0xb7,0x64,0xff,0x12,0xbf, +0xf3,0x5c,0x7b,0x7a,0x29,0x70,0xb, 0xc0,0x12,0x28,0xe1,0x38,0xd2,0x1b,0xd0,0xbe, +0xd0,0x0, 0x58,0x8f,0x12,0x29,0x16,0x74,0x2, 0x12,0xc0,0x3c,0x12,0x28,0x6e,0x74, +0x2, 0x12,0x0, 0x1e,0x7a,0xf3,0x2a,0xf6,0x12,0x27,0x8e,0xda,0x3b,0x22,0xca,0x79, +0x7c,0xfb,0x7e,0x8, 0x24,0xf2,0x12,0x6e,0x13,0x93,0x7c,0x7b,0x6c,0xee,0x80,0x1d, +0xa, 0x2e,0x9, 0x62,0x2a,0xd8,0xa, 0x26,0x12,0x69,0x2f,0x7c,0x6b,0xbe,0x60,0x1c, +0x50,0x9, 0xa, 0x2e,0x12,0x28,0xe9,0x19,0xb2,0x24,0xf2,0xb, 0xe0,0xbc,0x7e,0x38, +0xdf,0x6c,0xee,0x80,0x1a,0xa, 0x2e,0x9, 0x62,0x2a,0xb5,0xbe,0x60,0x23,0x50,0xd, +0xa, 0x1e,0xa, 0x27,0x2d,0x21,0x12,0x28,0xe9,0x19,0xb2,0x25,0xe, 0xb, 0xe0,0xbc, +0xae,0x38,0xe2,0x6c,0xee,0x7e,0x30,0xe, 0xac,0x3e,0x2e,0x14,0x24,0xf2,0x6d,0x0, +0x7c,0xbf,0x7c,0x7e,0x12,0x10,0x82,0xb, 0xe0,0xbe,0xe0,0x5, 0x40,0xe7,0xda,0x79, +0x22,0x90,0x61,0x28,0xe4,0x93,0xbc,0xbc,0x22,0x2e,0x27,0x2a,0xfa,0x7e,0x29,0xb0, +0xa, 0x26,0x22,0x74,0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0xf8,0x12,0x28,0x6e,0x74, +0x2, 0x12,0x0, 0x1e,0x74,0x5, 0x7e,0x70,0x9b,0x12,0x11,0xfa,0x12,0x29,0x9e,0x7e, +0xb3,0x2a,0xf8,0x2, 0xd, 0x39,0xca,0xd8,0xca,0x79,0x7e,0xf0,0xa, 0x74,0x1, 0x7a, +0xb3,0x2a,0xf6,0x90,0x61,0x28,0xe4,0x93,0x7c,0xeb,0x80,0x65,0x12,0x2b,0x13,0x12, +0x28,0xf3,0x30,0x1a,0xfd,0x12,0xbf,0xe9,0x7e,0xb3,0x2a,0x6d,0x7e,0x73,0x2a,0x6e, +0x12,0x2a,0x52,0x6c,0xdd,0x80,0x3d,0x7e,0x50,0x2, 0xac,0x5d,0x49,0x32,0x6, 0xfc, +0xbe,0x34,0x14,0x78,0x50,0x14,0xa, 0x1d,0x2e,0x17,0x2a,0xfa,0x7e,0x19,0xb0,0xbe, +0xb0,0x0, 0x28,0x1e,0x14,0x7a,0x19,0xb0,0x80,0x18,0xbe,0x34,0x19,0x28,0x28,0x10, +0xa, 0x3d,0x12,0x26,0x98,0xbe,0xb0,0xff,0x68,0x8, 0x4, 0x7a,0x39,0xb0,0x80,0x2, +0x1b,0xe0,0xb, 0xd0,0x90,0x61,0x28,0xe4,0x93,0xbc,0xbd,0x38,0xba,0x4c,0xee,0x68, +0x8, 0x7c,0xaf,0x1b,0xf0,0x4c,0xaa,0x78,0x93,0xda,0x79,0xda,0xd8,0x22,0x6c,0xaa, +0x80,0x1e,0xa, 0x3a,0x9, 0x73,0x2a,0xd8,0x12,0x90,0xc7,0x7c,0x7b,0xa, 0x47,0x7e, +0x50,0x2, 0xac,0x5a,0x7e,0xf, 0x3a,0xcc,0x2d,0x12,0x79,0x40,0x0, 0x48,0xb, 0xa0, +0x12,0x5b,0x73,0x38,0xdd,0x22,0xbe,0xb0,0x1, 0x28,0x2, 0xe4,0x22,0x12,0x77,0xeb, +0x12,0x27,0x8e,0x7e,0x73,0x2a,0xf6,0xa, 0x37,0x3e,0x34,0x3e,0x34,0xe4,0x7e,0x50, +0x1, 0x12,0x11,0xcf,0x12,0x29,0x4, 0x74,0x1, 0x22,0xca,0xd8,0xca,0x79,0x7c,0xfb, +0x7f,0x51,0x7f,0x40,0x7f,0x15,0x12,0x67,0xfb,0x12,0xc0,0x44,0x7e,0xe0,0x1, 0x12, +0x29,0x4, 0x30,0x1a,0xfd,0x74,0x2, 0x12,0x0, 0x1e,0x7f,0x4, 0x90,0x61,0x26,0xe4, +0x93,0xca,0xb8,0x12,0x71,0xc1,0xda,0xb8,0x12,0x2a,0x52,0x6c,0xdd,0x80,0x18,0x74, +0x2, 0xac,0xbd,0x7f,0x14,0x2d,0x35,0xb, 0x1a,0x20,0x74,0x2, 0xac,0xbd,0x7f,0x5, +0x2d,0x15,0x12,0xc0,0x21,0xb, 0xd0,0x90,0x61,0x28,0xe4,0x93,0x7c,0x7b,0xbc,0x7d, +0x38,0xdd,0x1b,0xe0,0x78,0xb9,0x7f,0x5, 0x7c,0xbf,0x12,0xb7,0x9e,0xda,0x79,0xda, +0xd8,0x22,0x12,0xf, 0x83,0x74,0x2, 0x2, 0x0, 0x1e,0x7e,0xb3,0x2a,0xfe,0x70,0x41, +0x12,0x78,0xc, 0x50,0xfb,0xe4,0x6c,0x77,0x6c,0x66,0x12,0x27,0x9e,0x7e,0x8, 0x6, +0xfc,0x7e,0x1f,0x6, 0xf4,0x7e,0xb3,0x2b,0x6e,0x12,0x29,0xea,0x74,0x1, 0x7e,0x70, +0x1, 0x7e,0x60,0x1, 0x12,0x27,0x9e,0x7e,0x8, 0x7, 0x7a,0x7e,0x1f,0x6, 0xf4,0x7e, +0xb3,0x25,0xf0,0x12,0x29,0xea,0x74,0x2, 0x7a,0xb3,0x2a,0xfe,0xe4,0x7a,0xb3,0x16, +0x90,0x22,0xca,0xf8,0x7e,0xf3,0x39,0x6e,0xbe,0xf0,0x5, 0x78,0xb, 0x74,0x1, 0x7a, +0xb3,0x39,0x6e,0x12,0x0, 0x9, 0x80,0x52,0xbe,0xf0,0x4, 0x78,0x13,0x12,0x2e,0xf4, +0x12,0x1e,0x81,0x12,0x2b,0x17,0xe4,0x7a,0xb3,0x2a,0xfe,0x12,0x2a,0x5a,0x80,0x3a, +0xbe,0xf0,0x6, 0x78,0x19,0x12,0x2e,0xf4,0x12,0x1e,0x81,0x12,0x2b,0x17,0x12,0x35, +0xdb,0xe4,0x7a,0xb3,0x2b,0x1a,0x12,0x78,0x17,0x12,0x2f,0xe8,0x80,0x1c,0xbe,0xf0, +0x7, 0x78,0x1d,0x12,0x2e,0xf4,0x12,0x1e,0x81,0x12,0x2b,0x17,0x12,0x78,0xc, 0x50, +0xfb,0x12,0x78,0xc8,0x12,0x2f,0xcd,0x12,0x31,0xb1,0x74,0x2, 0x7a,0xb3,0x39,0x6e, +0xda,0xf8,0x22,0x7e,0x34,0x3, 0xe8,0x6d,0x22,0x7a,0x27,0x3a,0xe9,0x7a,0x37,0x3a, +0xeb,0x22,0xca,0xd8,0xca,0x79,0x7d,0xd3,0x90,0x60,0x50,0xe4,0x93,0x7c,0xfb,0x90, +0x60,0x51,0xe4,0x93,0x7c,0x8b,0xa, 0x38,0xa, 0xcf,0x2d,0xc3,0xb, 0xc4,0x7d,0x3c, +0x7c,0xe7,0x7e,0x34,0x60,0xa3,0x12,0x1e,0x81,0x12,0x2b,0x17,0xa9,0xd0,0xc4,0xa9, +0xd5,0xcb,0x74,0x7, 0x12,0x0, 0x66,0x7c,0x8b,0x74,0x7, 0x7e,0x70,0xf, 0x12,0x2e, +0xea,0x7e,0x54,0x0, 0x78,0x7e,0x1f,0x3a,0xd0,0x79,0x51,0x0, 0x6, 0x7e,0x54,0x0, +0x80,0x7e,0x1f,0x3a,0xd0,0x79,0x51,0x0, 0x8, 0x7e,0x54,0x0, 0xc, 0x7e,0x1f,0x3a, +0xd0,0x79,0x51,0x0, 0x10,0xbe,0xd4,0x0, 0x2, 0x78,0xb, 0x7e,0x1f,0x3a,0xd0,0x12, +0x2c,0xef,0x44,0x1, 0x80,0x20,0x7e,0x1f,0x3a,0xd0,0x12,0x2c,0xef,0x44,0x8, 0x1b, +0x1a,0x50,0x4d,0xdd,0x7e,0x1f,0x3a,0xd0,0x78,0x7, 0x12,0x2c,0xef,0x54,0xfb,0x80, +0x5, 0x12,0x2c,0xef,0x44,0x4, 0x1b,0x1a,0x50,0x7e,0x1f,0x3a,0xcc,0x69,0xe1,0x0, +0x84,0x69,0x51,0x0, 0x90,0x7d,0xf5,0x2e,0x34,0x0, 0x90,0x5e,0xa0,0xf6,0x1b,0x1a, +0x50,0x7e,0xb3,0x38,0xe0,0xbe,0xb0,0x6, 0x40,0x3, 0xb4,0xff,0xe, 0x12,0x2c,0xfa, +0x54,0xe6,0x12,0x2c,0xf7,0x4e,0x54,0x1, 0xa4,0x80,0xc, 0x12,0x2c,0xfa,0x5e,0x54, +0xfe,0xe6,0x12,0x2c,0xf7,0x44,0xa4,0x1b,0x1a,0x50,0xbe,0xd4,0x0, 0x2, 0x78,0x23, +0x7e,0x1f,0x3a,0xd0,0x12,0x2c,0xef,0x5e,0x54,0x0, 0xf, 0x1b,0x1a,0x50,0x7e,0x1f, +0x3a,0xd0,0x12,0x2c,0xef,0x44,0x50,0x12,0x2d,0x6, 0x12,0x2f,0xfb,0x7a,0x37,0x36, +0xb2,0x81,0xab,0x6c,0xdd,0x80,0x7e,0x4c,0xdd,0x78,0x4, 0x6c,0x99,0x80,0x2b,0xbc, +0xfd,0x40,0x12,0xa, 0xcd,0x9, 0x9c,0x2a,0xb4,0xbe,0x90,0x23,0x40,0x3, 0x7e,0x90, +0x22,0xb, 0x90,0x80,0x15,0xa, 0x3f,0xa, 0xcd,0x9d,0xc3,0x9, 0x9c,0x2a,0xd7,0xbe, +0x90,0x1c,0x40,0x3, 0x7e,0x90,0x1b,0x2e,0x90,0x24,0x7e,0x1f,0x3a,0xd0,0x12,0x2c, +0xef,0x5e,0x54,0x0, 0xf, 0x1b,0x1a,0x50,0xa, 0xc9,0x3e,0xc4,0x3e,0xc4,0x3e,0xc4, +0x3e,0xc4,0x7e,0x1f,0x3a,0xd0,0x12,0x2c,0xef,0x4d,0x5c,0x12,0x2d,0x6, 0xbe,0xd4, +0x0, 0x1, 0x78,0x10,0x12,0x2d,0x10,0x12,0x2f,0xfb,0x74,0x2, 0xac,0xbd,0x59,0x35, +0x36,0xb4,0x80,0xf, 0x12,0x2f,0xfb,0xa, 0x5e,0xa, 0x2d,0x2d,0x25,0x3e,0x24,0x59, +0x32,0x36,0xb4,0xb, 0xd0,0xbc,0xed,0x28,0x2, 0x81,0x27,0xa9,0xd5,0xcb,0x74,0x7, +0x7c,0x78,0x12,0x2e,0xea,0xa9,0xc0,0xc4,0x7e,0x1f,0x3a,0xcc,0x79,0xe1,0x0, 0x84, +0x7e,0x1f,0x3a,0xcc,0x79,0xf1,0x0, 0x90,0x6d,0x33,0x7e,0xf, 0x3a,0xd0,0x79,0x30, +0x0, 0x6, 0x7e,0xf, 0x3a,0xd0,0x79,0x30,0x0, 0x8, 0x7e,0xf, 0x3a,0xd0,0x79,0x30, +0x0, 0x10,0x7e,0xf, 0x3a,0xd0,0x79,0x30,0x0, 0xe, 0xda,0x79,0xda,0xd8,0x22,0x2e, +0x34,0x0, 0xe, 0xb, 0x1a,0x50,0x22,0x1b,0x1a,0x50,0x7e,0x1f,0x3a,0xcc,0x2e,0x34, +0x0, 0x84,0xb, 0x1a,0x50,0x22,0x1b,0x1a,0x50,0x7e,0x34,0x0, 0x2, 0x12,0x2d,0x37, +0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x3a,0xd0,0x79,0x30,0x0, 0x4, 0x7e,0xf, 0x3a,0xd0, +0x69,0x30,0x0, 0x12,0x5e,0x34,0x0, 0x1, 0x68,0xf2,0x7e,0x34,0x0, 0x1, 0x79,0x30, +0x0, 0x12,0x22,0x7e,0x34,0x0, 0x1, 0x7d,0x23,0x80,0x12,0x7e,0x30,0x4, 0x80,0x5, +0x74,0xfa,0x12,0x4b,0x6c,0x7c,0x23,0x1b,0x30,0xa5,0xba,0x0, 0xf3,0x7d,0x32,0x1b, +0x24,0x4d,0x33,0x78,0xe6,0x22,0x30,0x8, 0x3b,0xc2,0x8, 0x12,0x2a,0xa2,0x7e,0x73, +0x39,0x6f,0x7a,0x73,0x2a,0x4d,0x7e,0x73,0x39,0x70,0x7a,0x73,0x2b,0x19,0x7e,0x73, +0x39,0x70,0x7a,0x73,0x2a,0xfd,0x7e,0xb3,0x39,0x71,0x60,0x18,0x7e,0x34,0x0, 0x2, +0x12,0x2b,0x22,0x7e,0x34,0x0, 0x1, 0x12,0x2b,0x22,0x6d,0x33,0x12,0x2b,0x22,0xe4, +0x7a,0xb3,0x39,0x71,0x12,0x27,0x37,0x2, 0x2d,0x9a,0xe5,0xc, 0x70,0x2, 0xc1,0xb7, +0xe5,0xc, 0x30,0xe0,0x10,0x53,0xc, 0xfe,0x12,0x5a,0x7c,0x12,0x5a,0xe6,0x7e,0x8, +0x2a,0x6d,0x12,0x8, 0xb8,0xe5,0xc, 0x30,0xe1,0x6, 0x53,0xc, 0xfd,0x12,0xb9,0x64, +0xe5,0xc, 0x30,0xe2,0x32,0x53,0xc, 0xfb,0x7e,0xb3,0x2b,0xe, 0x60,0x9, 0x7e,0x8, +0x2a,0x6d,0x12,0x5, 0x71,0x80,0xb, 0x7e,0xb3,0x2b,0x61,0x7e,0x73,0x2b,0x60,0x12, +0x9, 0xf3,0x7e,0x73,0x2b,0xe, 0x2e,0x70,0xff,0x92,0x1, 0x90,0x60,0x51,0xe4,0x93, +0x9e,0xb3,0x2a,0x73,0x12,0x9, 0x64,0xe5,0xc, 0x30,0xe3,0x45,0x53,0xc, 0xf7,0x7e, +0x73,0x39,0x9c,0x7a,0x73,0x2b,0xb, 0x12,0x67,0x1c,0x7a,0xb3,0x0, 0x5c,0xbe,0xb0, +0xff,0x68,0xb, 0x43,0xc, 0x20,0x7e,0x73,0x0, 0x5c,0x7a,0x73,0x39,0x74,0x12,0x34, +0xd4,0x12,0x67,0xdb,0x7e,0x73,0x39,0x9d,0xbe,0x73,0x2b,0x5e,0x68,0x6, 0x7a,0x73, +0x2b,0x5e,0xd2,0xe, 0x30,0xe, 0x7, 0x12,0xa9,0x9a,0xe4,0x12,0x8, 0x0, 0x12,0x36, +0x95,0xe5,0xc, 0x30,0xe4,0xf, 0x53,0xc, 0xef,0x7e,0x43,0x39,0x9e,0x7e,0x50,0xa, +0xac,0x45,0x12,0x2f,0xe1,0xe5,0xc, 0x30,0xe6,0x4e,0x53,0xc, 0xbf,0x7e,0x73,0x39, +0x8a,0xbe,0x70,0x7, 0x28,0x6, 0x74,0x7, 0x7a,0xb3,0x39,0x8a,0xa9,0xd5,0xcb,0x74, +0xe, 0x12,0x0, 0x66,0x7c,0x7b,0x5e,0x70,0xf, 0x7e,0x63,0x39,0x8a,0xa, 0x26,0x2e, +0x24,0x0, 0x3, 0x12,0x53,0xfe,0x7c,0x65,0x4c,0x76,0x74,0xe, 0x12,0x7, 0xfa,0x12, +0x0, 0x66,0x12,0x2e,0xed,0x7e,0x73,0x39,0x8d,0x7a,0x73,0x2b,0x10,0x7e,0x73,0x39, +0x8c,0x7a,0x73,0x2b,0x1b,0x12,0x2f,0xe8,0xe5,0xc, 0x30,0xe5,0xa, 0x53,0xc, 0xdf, +0x7e,0xb3,0x39,0x74,0x2, 0x38,0x1d,0x22,0x12,0xc0,0x33,0x12,0xc0,0x2a,0x6d,0x33, +0x7a,0x35,0xa, 0x12,0x37,0xfc,0x12,0x38,0x9a,0x74,0x50,0x7a,0xb3,0x39,0x9e,0x7e, +0x24,0x3, 0x20,0x12,0x2f,0xe1,0xe4,0x12,0xbf,0xc2,0x6d,0x33,0x7a,0x37,0x3, 0xfc, +0x22,0x7a,0xb3,0x2a,0xfe,0x7a,0xb3,0x2b,0x1a,0x22,0x12,0x7, 0xfa,0x75,0xfd,0xff, +0xa9,0xc5,0xcb,0x22,0x74,0x1, 0x7a,0xb3,0x39,0x6e,0x7e,0x34,0x60,0xa3,0x22,0x24, +0xab,0x68,0x10,0x24,0xef,0x68,0x1c,0x24,0xde,0x68,0x26,0x24,0xde,0x78,0x2f,0x74, +0x5, 0x80,0x2d,0x7e,0xb3,0x34,0x4f,0xb4,0x5, 0x2a,0x12,0x2d,0x33,0x12,0xb4,0xd4, +0x2, 0xb5,0xe3,0x7e,0xb3,0x34,0x4f,0xb4,0x5, 0x1a,0x12,0x2d,0x33,0x75,0xe9,0xff, +0x22,0x7e,0xb3,0x34,0x4f,0xb4,0x5, 0xc, 0x12,0x2d,0x33,0x2, 0xb5,0xdd,0x74,0x1, +0x7a,0xb3,0x34,0x4f,0x22,0x12,0x2e,0xb8,0x7e,0xb3,0x38,0xd6,0xb4,0x3, 0x68,0x12, +0xb6,0x1, 0x12,0x2b,0x13,0x12,0x2d,0x56,0x7e,0xb3,0x39,0x6a,0x30,0xe7,0xe9,0x12, +0x30,0xa8,0x12,0x2f,0xf1,0xca,0x39,0x7e,0x18,0x4, 0x0, 0x7e,0x8, 0x4, 0xfc,0x12, +0x1b,0x93,0x1b,0xfd,0x12,0x2f,0xf1,0xca,0x39,0x7e,0x18,0x4, 0x7e,0x7e,0x8, 0x5, +0x7a,0x12,0x1b,0x93,0x1b,0xfd,0x7e,0xb3,0x2b,0x19,0xb4,0x1, 0x18,0x12,0x46,0xf7, +0x12,0xa2,0xdc,0x12,0xa9,0xac,0x12,0xa5,0x11,0x12,0x79,0x40,0x12,0x6a,0x8a,0x12, +0x39,0x52,0x12,0x30,0x1e,0x12,0x38,0xa3,0x12,0xaf,0x85,0x7e,0xb3,0x39,0x6a,0x54, +0x7f,0x7a,0xb3,0x39,0x6a,0x80,0x91,0x12,0x78,0xc2,0x2, 0x0, 0x6e,0x7e,0x34,0xd, +0xac,0x12,0x2b,0x17,0x12,0x2a,0x5a,0x12,0x78,0x17,0x2, 0x2f,0xcd,0x30,0x11,0x10, +0x12,0x33,0xb2,0x50,0x3, 0x12,0xaf,0xcc,0x12,0x67,0x4d,0x12,0x78,0x3d,0xc2,0x11, +0x22,0x7d,0x32,0x74,0xfa,0x2, 0x11,0x9e,0x7e,0x73,0x39,0x8b,0x7a,0x73,0x2b,0x1c, +0x22,0x90,0x61,0x28,0xe4,0x93,0xa, 0x3b,0x3e,0x34,0x22,0x7e,0xf, 0x3a,0xd0,0x69, +0x30,0x0, 0xa, 0x7d,0x23,0x6d,0x33,0x69,0x10,0x0, 0xc, 0x6d,0x0, 0x2f,0x10,0x74, +0x7, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x22,0xca,0xd8, +0xca,0x79,0x7e,0x73,0x2a,0x6e,0x7e,0xf3,0x2a,0x6d,0xac,0xf7,0x7d,0x37,0x3e,0x34, +0x7e,0x8, 0x1f,0x34,0xe4,0x12,0x1b,0xb8,0x7e,0xb3,0x39,0x85,0xb4,0x1, 0x64,0x7e, +0x73,0x39,0x86,0xbe,0x70,0x0, 0x28,0x5b,0x6c,0xdd,0x80,0x3c,0x12,0x2b,0x13,0x12, +0x30,0xa8,0x6d,0x33,0x80,0x28,0x7e,0x35,0x24,0x3e,0x34,0x49,0x33,0xd, 0xc8,0x12, +0x1b,0xfa,0x7a,0x35,0x26,0x7e,0x35,0x24,0x7d,0x13,0x3e,0x14,0x49,0x21,0x1f,0x34, +0xbe,0x25,0x26,0x58,0x7, 0x7e,0x25,0x26,0x59,0x21,0x1f,0x34,0xb, 0x34,0x7a,0x35, +0x24,0xbe,0x75,0x24,0x38,0xd0,0xb, 0xd0,0x7e,0x73,0x39,0x86,0xbc,0x7d,0x38,0xbc, +0x7d,0x37,0x3e,0x34,0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0xd, 0xc8,0x12,0x1b, +0x93,0x1b,0xfd,0xda,0x79,0xda,0xd8,0x22,0xca,0x3b,0x12,0x78,0xc, 0x50,0xfb,0x7e, +0xf3,0x2b,0xb, 0x7c,0xbf,0x12,0x67,0x3e,0x12,0xb6,0xb5,0x7e,0xb3,0x2b,0x1b,0xf5, +0x28,0x7e,0xb3,0x2b,0x1c,0xf5,0x29,0x7e,0xb3,0x38,0xd6,0xb4,0x1, 0xf, 0x12,0x36, +0x4e,0x7e,0xb3,0x16,0x91,0x70,0x6, 0x12,0x31,0xb1,0xc3,0x21,0xae,0x12,0x2f,0xf1, +0xca,0x39,0x7e,0x18,0x6, 0xfc,0x7e,0x8, 0x4, 0x7e,0x12,0x1b,0x93,0x1b,0xfd,0x12, +0x2f,0xf1,0xca,0x39,0x7e,0x18,0x7, 0x7a,0x7e,0x8, 0x4, 0x0, 0x12,0x1b,0x93,0x1b, +0xfd,0x7e,0xb3,0x38,0xd6,0xb4,0x3, 0x7, 0x12,0x5b,0x7b,0x7a,0x37,0x39,0xb1,0x74, +0x1, 0x7a,0xb3,0x16,0x90,0x12,0x2f,0xc4,0x12,0x5b,0xe8,0x7e,0xc3,0x3, 0xf9,0x12, +0x31,0xcb,0xe4,0x12,0x12,0xac,0x12,0x31,0xb1,0x7e,0x8, 0x4, 0x7e,0x7a,0xd, 0x2a, +0x7e,0x18,0x6, 0x76,0x7e,0xb3,0x2b,0x6e,0x12,0x32,0x25,0x7e,0x8, 0x4, 0x0, 0x7a, +0xd, 0x2a,0x7e,0x18,0x5, 0xf8,0x7e,0xb3,0x25,0xf0,0x12,0x32,0x25,0x7e,0xd3,0x2b, +0x1b,0x7e,0xe3,0x2b,0x1c,0xe5,0x28,0x7a,0xb3,0x2b,0x1b,0xe5,0x29,0x12,0x33,0xae, +0x50,0x5, 0x7c,0xbc,0x12,0x37,0x7d,0x7e,0x34,0x8, 0xa, 0x7e,0x4, 0xd, 0xc8,0x7d, +0x20,0x7d,0x10,0x12,0x32,0x7a,0x7a,0xd3,0x2b,0x1b,0x7a,0xe3,0x2b,0x1c,0x7c,0xbf, +0x12,0x66,0xbc,0x12,0xa5,0x21,0x7e,0xb3,0x3, 0xff,0x4, 0x7a,0xb3,0x3, 0xff,0x7e, +0x73,0x3, 0xff,0xbe,0x70,0xfa,0x28,0x6, 0x74,0x64,0x7a,0xb3,0x3, 0xff,0x7e,0xb3, +0x16,0x90,0x60,0x9, 0x7e,0xb3,0x16,0x91,0x60,0x3, 0xd3,0x80,0x1, 0xc3,0xda,0x3b, +0x22,0xe4,0x7a,0xb3,0x34,0x3a,0x7a,0xb3,0x34,0x39,0x12,0x71,0x31,0xb4,0x1, 0x4, +0x74,0x1, 0x80,0x2, 0x74,0x3, 0x7a,0xb3,0x34,0x3a,0x22,0x7e,0xa3,0x0, 0x5c,0xbe, +0xa0,0xff,0x68,0x48,0xbe,0xa3,0x3, 0xf9,0x68,0x42,0x74,0x5, 0xa4,0x12,0x37,0xda, +0x12,0x32,0x1d,0x12,0x37,0xd1,0x12,0x32,0x1d,0x12,0x37,0xc8,0x12,0x33,0xb2,0x50, +0x9, 0x7e,0xb3,0x0, 0x5c,0x12,0x37,0x7d,0x80,0x6, 0x12,0x32,0x1d,0x12,0x37,0xbf, +0x12,0x34,0xd4,0x12,0x37,0xb8,0x7e,0x73,0x2b,0x10,0xa, 0x37,0x7e,0xf, 0x3a,0xd4, +0x79,0x30,0x0, 0x1a,0x7e,0x73,0x0, 0x5c,0x7a,0x73,0x3, 0xf9,0x22,0x7e,0xa3,0x0, +0x5c,0x74,0x5, 0xa4,0x22,0xca,0xf8,0x7c,0xab,0x7f,0x51,0x7f,0x40,0x90,0x61,0x28, +0xe4,0x93,0x7c,0xfb,0x7e,0xd, 0x2a,0x7c,0xba,0x7c,0x7f,0x12,0xb7,0x9e,0xa, 0x3f, +0x3e,0x34,0xca,0x39,0x7e,0x1d,0x2a,0x7f,0x4, 0x12,0x1b,0x93,0x1b,0xfd,0x7e,0xb3, +0x2a,0xfd,0xb4,0x1, 0x22,0x6c,0xaa,0x80,0x1a,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x5, +0x2d,0x13,0xb, 0xa, 0x20,0x7f,0x4, 0x2d,0x13,0xb, 0xa, 0x30,0x9d,0x32,0x1b,0xa, +0x30,0xb, 0xa0,0xbc,0xfa,0x38,0xe2,0xda,0xf8,0x22,0x7e,0xb3,0x2a,0x6d,0xca,0x3b, +0x7c,0xdb,0x7a,0x5, 0x39,0x7d,0x71,0x7a,0x25,0x37,0x7a,0x35,0x35,0x12,0x33,0xb2, +0x50,0x7c,0x6c,0xcc,0x80,0x11,0x7e,0x73,0x2a,0x6e,0x12,0x33,0xa5,0x12,0x33,0x8b, +0x7e,0x34,0x34,0x0, 0x12,0x33,0xc3,0x12,0x33,0xdb,0x38,0xea,0x6c,0xcc,0x80,0x58, +0x7e,0xa3,0x2a,0x6e,0x7c,0x7a,0x12,0x33,0xa5,0x75,0x3b,0x0, 0x80,0x27,0x7e,0xb3, +0x39,0x7f,0xbe,0xb1,0x3b,0x7e,0x70,0x4, 0x28,0x8, 0xac,0x7c,0x49,0x43,0x3, 0x6d, +0x80,0x6, 0xac,0x7c,0x49,0x43,0x3, 0x6f,0x7e,0x71,0x3b,0x74,0x2, 0xac,0x7b,0x59, +0x43,0x34,0x50,0x5, 0x3b,0x7e,0xb3,0x2a,0x70,0xbe,0xb1,0x3b,0x38,0xd0,0x12,0x77, +0xcf,0x68,0xb, 0x7e,0x34,0x10,0x0, 0x74,0x2, 0xa4,0x59,0x35,0x34,0x4e,0x12,0x33, +0x8b,0x7e,0x34,0x34,0x50,0x12,0x33,0xc3,0xbc,0xdc,0x38,0xa4,0x80,0x2c,0x7a,0xd3, +0x25,0xb6,0x7e,0x73,0x2a,0x70,0x7a,0x73,0x25,0xb7,0xe4,0x7a,0xb3,0x25,0xb9,0x74, +0x6, 0x7a,0xb3,0x25,0xb8,0x7a,0x77,0x25,0xba,0x7a,0x77,0x25,0xbe,0x7e,0x8, 0x25, +0xb6,0x7e,0x73,0x2b,0x1b,0xa, 0x37,0x12,0xc, 0xdc,0x7d,0x37,0x12,0x87,0xf3,0x7e, +0x35,0x39,0x7a,0x37,0x25,0xbe,0xe4,0x7a,0xb3,0x25,0xb8,0x12,0x33,0x9c,0x7a,0xd3, +0x25,0xb6,0x7e,0xb3,0x2b,0x19,0x70,0xf, 0xe4,0x7a,0xb3,0x25,0xb9,0x7a,0x77,0x25, +0xba,0x7e,0x34,0x0, 0x20,0x80,0x16,0x74,0x1, 0x7a,0xb3,0x25,0xb9,0x7e,0x35,0x35, +0x7a,0x37,0x25,0xba,0x7e,0x35,0x37,0x7a,0x37,0x25,0xbc,0x6d,0x33,0x7a,0x37,0x25, +0xc0,0x7e,0x8, 0x25,0xb6,0x12,0xb, 0x4d,0xda,0x3b,0x22,0x74,0xc, 0x7a,0xb3,0x25, +0xb8,0x74,0x1, 0x7a,0xb3,0x25,0xb6,0xe4,0x7a,0xb3,0x25,0xb9,0x7e,0x73,0x2a,0x6e, +0x7a,0x73,0x25,0xb7,0x22,0xac,0x7c,0x3e,0x34,0x7d,0xf7,0x2d,0xf3,0x22,0x7a,0xb3, +0x2b,0x1c,0x7e,0xb3,0x38,0xd6,0xb4,0x3, 0x8, 0x7e,0xb3,0x39,0x80,0x70,0x2, 0xc3, +0x22,0xd3,0x22,0x7a,0x37,0x25,0xba,0x7d,0x3f,0x7a,0x37,0x25,0xbc,0x7a,0x37,0x25, +0xbe,0x7e,0x8, 0x25,0xb6,0x12,0xc, 0x1e,0xb, 0xc0,0x22,0x7e,0x73,0x2a,0x6f,0xbc, +0x7c,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x14,0x1d,0x79,0x7e,0x4, 0x0, 0xff, +0x69,0x30,0x0, 0x2, 0xb, 0xa, 0x20,0x7a,0x1d,0x2c,0x7e,0x73,0x2a,0x6d,0xa, 0x37, +0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x1b,0x93,0x1b,0xfd,0x6c,0xdd,0x12, +0x37,0xeb,0x7a,0xb3,0x1f,0x34,0x6c,0xcc,0x80,0x4f,0x12,0x34,0xc0,0x40,0x48,0x12, +0x34,0xb6,0x50,0x43,0x74,0x2, 0xac,0xbc,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0x10,0x7d, +0x3f,0x12,0x1b,0xfa,0x7d,0x3, 0x7d,0x31,0x12,0x1b,0xfa,0xbd,0x30,0x58,0x2, 0x7d, +0xf1,0xbe,0x15,0x2a,0x8, 0x5, 0x7e,0x15,0x2a,0x80,0xb, 0x6d,0x0, 0x9e,0x5, 0x2a, +0xbd,0x1, 0x8, 0x2, 0x7d,0x10,0x7d,0x31,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3, +0x1f,0x34,0x4, 0x7a,0xb3,0x1f,0x34,0xb, 0xc0,0x12,0x33,0xdb,0x38,0xac,0x7e,0x73, +0x1f,0x34,0x4c,0x77,0x68,0x34,0x12,0xa4,0x81,0x8, 0x2, 0x7d,0x7f,0xbe,0x75,0x2a, +0x8, 0x5, 0x7e,0x75,0x2a,0x80,0xb, 0x6d,0xee,0x9e,0xe5,0x2a,0xbd,0xe7,0x8, 0x2, +0x7d,0x7e,0x6c,0xcc,0x80,0xf, 0x12,0x34,0xc0,0x40,0x8, 0x12,0x34,0xb6,0x50,0x3, +0x12,0xa4,0x6c,0xb, 0xc0,0x12,0x33,0xdb,0x38,0xec,0xb, 0xd0,0xbe,0xd0,0x3, 0x50, +0x2, 0x81,0xf, 0xda,0x3b,0x22,0x7c,0x1d,0x2e,0x10,0x2d,0xa5,0xe7,0xbc,0xab,0x22, +0xa, 0xec,0x9, 0xae,0x2a,0xb5,0x7c,0x1d,0x2e,0x10,0x2c,0xa5,0xe7,0xbc,0xab,0x22, +0x7a,0xb3,0x2b,0xb, 0x12,0x34,0xdc,0x7a,0x37,0x2b,0x17,0x22,0x7e,0x23,0x2b,0xb, +0x7e,0x33,0x39,0x9b,0x7e,0x34,0x60,0xd6,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x0, 0xac, +0x23,0x2d,0x10,0xbe,0x14,0x0, 0xa, 0x50,0x4, 0x7e,0x14,0x0, 0xa, 0x7e,0x63,0x2b, +0xc, 0xbe,0x14,0xf, 0x3c,0x40,0x4, 0x7e,0x14,0xf, 0x3c,0xbe,0x14,0x7, 0x8, 0x40, +0x3, 0xe4,0x80,0x21,0xbe,0x14,0x3, 0x84,0x40,0x16,0x90,0x61,0x1b,0xe4,0x93,0x7c, +0x7b,0xbe,0x70,0x1, 0x28,0x4, 0x74,0x1, 0x80,0xb, 0x7a,0x73,0x2b,0xc, 0x80,0x9, +0x90,0x61,0x1b,0xe4,0x93,0x7a,0xb3,0x2b,0xc, 0x7e,0x73,0x2b,0xc, 0xbc,0x76,0x68, +0x2, 0xd2,0xe, 0x7e,0x24,0x1, 0xf4,0x7d,0x31,0x8d,0x32,0x7c,0x17,0xbe,0x10,0x7, +0x28,0x3, 0x7e,0x10,0x7, 0x7e,0x1f,0x3a,0xcc,0x69,0x51,0x0, 0x86,0x54,0x1f,0xa, +0x1, 0x12,0x37,0xf3,0x3e,0x4, 0x2d,0x5, 0x79,0x1, 0x0, 0x86,0x6d,0x0, 0x7e,0x34, +0xb8,0x0, 0x7e,0x24,0x0, 0xb, 0x2, 0x19,0x4b,0x12,0x34,0xd0,0x30,0xe, 0xa, 0x12, +0xa9,0x9a,0x30,0x0, 0x4, 0xe4,0x12,0x8, 0x0, 0x30,0x0, 0x9, 0x12,0xa7,0xe0,0x12, +0x36,0x98,0x2, 0x7c,0xaf,0x22,0x7e,0xb, 0x70,0x7a,0x73,0x2b,0xb, 0x29,0x70,0x0, +0x4, 0x7a,0x73,0x2b,0x5e,0x29,0x70,0x0, 0x1, 0x7a,0x73,0x2b,0x10,0x29,0x70,0x0, +0x3, 0x7a,0x73,0x2b,0x1c,0x12,0x34,0xd4,0x12,0x37,0xb8,0xd2,0x0, 0xc2,0x1, 0x2, +0x35,0xc2,0x30,0x0, 0x3, 0x12,0x38,0x14,0xa2,0x1, 0x92,0x2, 0x12,0x72,0x5b,0x2, +0x35,0xd2,0x7e,0x73,0x2b,0x1c,0x7a,0x73,0x39,0x8b,0x22,0x74,0x40,0x12,0x33,0xae, +0x50,0x9, 0xd2,0x0, 0xd2,0x1, 0x12,0x35,0xc2,0x80,0x1c,0x74,0x1, 0x12,0x71,0xdf, +0x7e,0x43,0x39,0x89,0x7e,0x50,0x64,0xac,0x45,0x12,0x8f,0xe9,0x7a,0xb3,0x2b,0x1b, +0x7e,0xf, 0x3a,0xe5,0x12,0x75,0x39,0x12,0x35,0xd2,0x7e,0x73,0x2b,0x1b,0x7a,0x73, +0x39,0x8c,0x2, 0x38,0x14,0xca,0xf8,0x7c,0xfb,0x74,0x5, 0xac,0xbf,0x12,0x37,0xda, +0x12,0x37,0xd1,0x12,0x37,0xbf,0x12,0x37,0xc8,0x7a,0xf3,0x0, 0x5c,0x7c,0xbf,0x12, +0x37,0x7d,0x12,0x34,0xd4,0x74,0x5, 0xac,0xbf,0x9, 0xb5,0x26,0x37,0x12,0xa9,0x81, +0x12,0x36,0x98,0x12,0x7, 0xf3,0xe4,0x7a,0xb3,0x16,0x91,0xda,0xf8,0x22,0x7e,0xb3, +0x38,0x34,0x60,0x6, 0x14,0x7a,0xb3,0x38,0x34,0x22,0x12,0x7c,0xcc,0x90,0x61,0xc5, +0xe4,0x93,0xbe,0xb0,0x4, 0x28,0x3, 0x12,0x36,0x98,0x7e,0xb3,0x38,0xba,0x70,0xe, +0x7e,0xb3,0x3b,0x1d,0xb4,0x1, 0x7, 0xe4,0x12,0x36,0x15,0x12,0xbf,0xdf,0x12,0x37, +0xb2,0x12,0xa8,0x12,0x7e,0xa3,0x38,0xba,0x7a,0xa3,0x3b,0x1d,0xbe,0xb0,0xff,0x68, +0x3, 0x2, 0x36,0x15,0x22,0x12,0x37,0x73,0x7e,0xb3,0x2b,0xb, 0xca,0x3b,0x7c,0xeb, +0x6c,0xff,0x7e,0x34,0x60,0xd6,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0xc0,0x7e,0x73,0x39, +0x9b,0xa, 0xb7,0x7e,0xb3,0x2b,0xc, 0xf5,0x36,0x12,0x37,0xe3,0xbe,0xd0,0x4, 0x38, +0x5, 0xe4,0x7a,0xb3,0x38,0x40,0xa, 0x3e,0xad,0x3b,0x7d,0xa3,0x2d,0xac,0x75,0x35, +0x0, 0x7e,0xa3,0x38,0x40,0xbc,0xad,0x40,0x2, 0x80,0x19,0xbe,0xa0,0x0, 0x28,0x19, +0x74,0x5, 0xa4,0x9, 0x75,0x26,0x33,0xbc,0x7e,0x78,0xe, 0x7c,0xbd,0x14,0xbe,0xb3, +0x38,0x40,0x78,0x5, 0xe4,0x7a,0xb3,0x38,0x40,0x7e,0xc3,0x38,0x40,0x80,0x41,0x7e, +0xb3,0x38,0x40,0x4, 0x7a,0xb3,0x38,0x40,0x7e,0x90,0x5, 0xac,0x9c,0x9, 0xa4,0x26, +0x33,0xbc,0xae,0x68,0x29,0xe5,0x35,0xa, 0xdb,0x19,0xcd,0x38,0x44,0xa, 0x9a,0xad, +0x9b,0x2d,0x9c,0x7e,0xa1,0x35,0x7c,0xba,0x4, 0xf5,0x35,0x7c,0xba,0x7d,0x39,0x7d, +0x2a,0x7e,0x31,0x36,0x12,0xe, 0x95,0xb, 0xf0,0xbe,0xf0,0x3, 0x50,0x6, 0xb, 0xc0, +0xbc,0xdc,0x38,0xbb,0x7a,0xf3,0x38,0x41,0xda,0x3b,0x22,0x7e,0x34,0x60,0xa3,0x12, +0x1e,0x81,0x12,0x2b,0x17,0x12,0x50,0x4f,0x12,0x47,0x2a,0x12,0x26,0xa0,0x12,0x2f, +0xbd,0x12,0xbf,0xc0,0x12,0x1f,0xe5,0x12,0x31,0xb1,0x12,0x48,0x3b,0x12,0x36,0x95, +0x2, 0x7, 0xf3,0x12,0xa7,0xe0,0x74,0x1, 0x7a,0xb3,0x38,0x34,0x22,0xca,0xf8,0x7c, +0xfb,0x7e,0x34,0x0, 0x38,0xca,0x39,0xac,0x7f,0x2e,0x34,0x0, 0x5d,0x6d,0x22,0x7e, +0x8, 0x34,0x0, 0x12,0x1b,0x93,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0xac,0x7f, +0x2e,0x34,0x1, 0x3d,0x6d,0x22,0x7e,0x8, 0x3, 0x6d,0x12,0x1b,0x93,0x1b,0xfd,0xda, +0xf8,0x22,0x12,0x4f,0x41,0x2, 0x1f,0xb1,0x7e,0x8, 0x2a,0x6d,0x2, 0x1, 0x20,0x9, +0x75,0x26,0x35,0x7a,0x73,0x2b,0x1b,0x22,0x9, 0x75,0x26,0x36,0x7a,0x73,0x2b,0x1c, +0x22,0x9, 0x75,0x26,0x34,0x7a,0x73,0x2b,0x10,0x22,0x9, 0x75,0x26,0x33,0x7a,0x73, +0x2b,0xb, 0x22,0x90,0x61,0xc5,0xe4,0x93,0x7c,0xdb,0x22,0x7e,0xf4,0x7f,0xff,0x9f, +0x44,0xe4,0x22,0x3e,0x4, 0x3e,0x4, 0x3e,0x4, 0x3e,0x4, 0x22,0x7e,0x73,0x2b,0xb, +0x7a,0x73,0x39,0x9c,0x7e,0x73,0x2b,0x1b,0x7a,0x73,0x39,0x8c,0x7e,0x73,0x2b,0x1c, +0x7a,0x73,0x39,0x8b,0x7e,0x73,0x2b,0x10,0x7a,0x73,0x39,0x8d,0x22,0xca,0xd8,0xca, +0x79,0x7c,0xdb,0x90,0x61,0xc5,0xe4,0x93,0x7c,0xab,0xbe,0xd0,0x80,0x78,0x18,0x7e, +0xe0,0xff,0x6c,0xff,0x80,0xb, 0x12,0x38,0x8e,0x38,0x4, 0x7c,0xeb,0x7c,0xdf,0xb, +0xf0,0xbc,0xaf,0x38,0xf1,0x80,0x1a,0xbe,0xd0,0x81,0x78,0x15,0x6c,0xee,0x6c,0xff, +0x80,0xb, 0x12,0x38,0x8e,0x40,0x4, 0x7c,0xeb,0x7c,0xdf,0xb, 0xf0,0xbc,0xaf,0x38, +0xf1,0xbc,0xad,0x38,0x2, 0x6c,0xdd,0x7c,0xbd,0x12,0x36,0x15,0x12,0x38,0x14,0x7e, +0x73,0x2b,0x1b,0x7a,0x73,0x39,0x8c,0x12,0x35,0xd2,0x7e,0x73,0x2b,0xb, 0x7a,0x73, +0x39,0x9c,0x12,0x38,0x9a,0x7a,0xd3,0x39,0x74,0xda,0x79,0xda,0xd8,0x22,0x7e,0x90, +0x5, 0xac,0x9f,0x9, 0xb4,0x26,0x33,0xbc,0xbe,0x22,0x7e,0x73,0x2b,0x5e,0x7a,0x73, +0x39,0x9d,0x22,0xa2,0xc, 0xe4,0x33,0x7a,0xb3,0x39,0x98,0x7e,0x73,0x39,0x9c,0xbe, +0x73,0x2b,0xb, 0x68,0xa, 0xe5,0xc, 0x70,0x6, 0x12,0x37,0xfc,0x12,0x38,0x9a,0x22, +0x7e,0xb3,0x38,0xd3,0xb4,0x1, 0x4, 0xe4,0x2, 0x38,0xcc,0x22,0x70,0x3, 0xd2,0x86, +0x22,0xc2,0x86,0x22,0x12,0x48,0x28,0x12,0x6f,0xeb,0x7e,0xb3,0x38,0xd6,0xb4,0x1, +0x6b,0x12,0xb6,0x1, 0x7e,0x34,0x60,0xa5,0x12,0x1e,0x81,0x12,0x2b,0x17,0x12,0x90, +0x6f,0x12,0x53,0xa9,0x12,0x30,0xa8,0x50,0xde,0x12,0x46,0xf7,0x12,0xa2,0xdc,0x7e, +0xb3,0x38,0xd3,0xb4,0x1, 0x4, 0xe4,0x12,0x38,0xcc,0x12,0xa9,0xac,0x12,0xa5,0x11, +0x12,0x3f,0x5c,0x40,0xc2,0x12,0x79,0x40,0x12,0x3f,0x5c,0x40,0xba,0x12,0x6a,0x8a, +0x12,0x39,0x52,0x12,0x3f,0xf8,0x12,0x8f,0x95,0x12,0x96,0xd3,0x12,0x54,0x7e,0x12, +0x8f,0x56,0x12,0x88,0x4f,0x12,0x8d,0xa8,0x12,0x8a,0x18,0x12,0xbb,0x16,0x12,0x42, +0xb8,0x12,0x48,0x12,0x12,0x48,0x4e,0x12,0x47,0xbc,0x80,0x8b,0x12,0x78,0xc2,0x2, +0x38,0xc0,0x12,0x91,0x33,0x12,0x3b,0x2d,0x12,0x3b,0x2d,0x12,0x7f,0xb2,0x12,0x80, +0x89,0x12,0x3b,0x2d,0x12,0x9d,0xa0,0x12,0x3b,0x2d,0x12,0x3b,0x2d,0x2, 0x39,0x70, +0xca,0x3b,0x75,0x24,0x0, 0x6c,0xcc,0x6c,0xdd,0x7e,0xf3,0x28,0x84,0xa, 0xcf,0x3e, +0xc4,0xca,0xc9,0x7e,0x18,0x26,0xfa,0x7e,0x8, 0x1f,0x34,0x12,0x1b,0x93,0x1b,0xfd, +0x6c,0x88,0x6c,0xee,0x41,0x31,0x7e,0xc4,0x3, 0xff,0x7e,0xc0,0xff,0x6c,0x99,0x80, +0x4c,0x74,0x2, 0xac,0xb9,0x9, 0xb5,0x1f,0x34,0xbe,0xb0,0xff,0x68,0x3d,0x7c,0xb9, +0x12,0x3f,0x74,0x60,0x36,0x74,0x2, 0xac,0xb9,0x9, 0x75,0x1f,0x35,0xa, 0x27,0x74, +0x2, 0xac,0xbe,0x9, 0x75,0x3a,0x54,0xa, 0x37,0x12,0x5c,0x8, 0x74,0x2, 0xac,0xb9, +0x9, 0x75,0x1f,0x34,0xa, 0x27,0x74,0x2, 0xac,0xbe,0x9, 0x75,0x3a,0x53,0x12,0x87, +0x43,0x2d,0x13,0xbd,0xc1,0x28,0x4, 0x7d,0xc1,0x7c,0xc9,0xb, 0x90,0xbc,0xf9,0x38, +0xb0,0xbe,0xc0,0xff,0x68,0x39,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x1f,0x34,0x9, +0x73,0x1f,0x35,0x12,0x3b,0x73,0xbe,0x37,0x2a,0x5a,0x48,0x23,0x7e,0x70,0x2, 0xac, +0x7c,0x9, 0x53,0x1f,0x34,0x74,0x2, 0xac,0xbd,0x19,0x55,0x1f,0x70,0x9, 0x53,0x1f, +0x35,0x19,0x55,0x1f,0x71,0x74,0xff,0x19,0xb3,0x1f,0x34,0xb, 0x80,0xb, 0xd0,0xb, +0xe0,0x7e,0x73,0x3a,0x52,0xbc,0x7e,0x28,0x2, 0x21,0x96,0x7c,0xe8,0x80,0x6d,0x6d, +0xdd,0x7e,0x80,0xff,0x6c,0x99,0x80,0x3c,0x7c,0xb9,0x12,0x3f,0x74,0x60,0x33,0x12, +0x3f,0xd6,0xbe,0xb0,0xff,0x68,0x2b,0x9, 0x73,0x1f,0x35,0x12,0x6e,0x2c,0x7f,0x71, +0xb, 0x7a,0x50,0xbe,0x54,0x0, 0x0, 0x58,0x5, 0x6d,0x55,0x1b,0x7a,0x50,0xb, 0x7a, +0xc0,0xbd,0xcd,0x8, 0xd, 0x12,0x3f,0xd6,0xf5,0x24,0x9, 0xc3,0x1f,0x35,0x7d,0xdc, +0x7c,0x89,0xb, 0x90,0xbc,0xf9,0x38,0xc0,0xbe,0x80,0xff,0x68,0x1d,0x7e,0x71,0x24, +0x74,0x2, 0xac,0xbd,0x19,0x75,0x1f,0x70,0x19,0xc5,0x1f,0x71,0x7e,0xa0,0xff,0x7e, +0x70,0x2, 0xac,0x78,0x19,0xa3,0x1f,0x34,0xb, 0xd0,0xb, 0xe0,0x90,0x60,0x99,0xe4, +0x93,0xbc,0xbe,0x38,0x8a,0x90,0x60,0x9a,0x12,0xa4,0x65,0xa4,0xca,0x59,0x7e,0x18, +0x1f,0x70,0x7e,0x8, 0x1f,0x34,0x12,0x1b,0x93,0x1b,0xfd,0x7c,0xfd,0x12,0x3f,0xe0, +0x7e,0x8, 0x3a,0x53,0x74,0xff,0x12,0x1b,0xb8,0xbe,0xf0,0x0, 0x28,0x35,0xa, 0x3f, +0x3e,0x34,0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x26,0xfa,0x12,0x1b,0x93,0x1b, +0xfd,0xa, 0x3f,0x3e,0x34,0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x3a,0x53,0x12, +0x1b,0x93,0x1b,0xfd,0x6c,0xee,0x80,0x7, 0x7c,0xbe,0x12,0x3f,0x8d,0xb, 0xe0,0xbc, +0xfe,0x38,0xf5,0x7a,0xf3,0x3a,0x52,0x7a,0xf3,0x28,0x84,0x90,0x60,0x99,0xe4,0x93, +0xbe,0xb3,0x28,0x84,0x50,0x4, 0x7a,0xb3,0x28,0x84,0xda,0x3b,0x22,0xca,0x79,0x6c, +0xff,0x6c,0xee,0x80,0x2e,0x7c,0xbe,0x12,0x3f,0x74,0x60,0x25,0x7e,0x34,0x0, 0x2, +0xca,0x39,0xac,0x7e,0x2e,0x34,0x26,0xfa,0x6d,0x22,0x7e,0x30,0x2, 0xac,0x3f,0x2e, +0x14,0x26,0xfa,0x6d,0x0, 0x12,0x1b,0x93,0x1b,0xfd,0x7c,0xbf,0x12,0x3f,0x8d,0xb, +0xf0,0xb, 0xe0,0x12,0x87,0x6f,0x38,0xcd,0x7a,0xf3,0x28,0x84,0xda,0x79,0x22,0x7c, +0xba,0x7c,0x79,0x12,0x6e,0x2c,0xb, 0x1a,0x30,0x22,0xca,0x3b,0x7c,0xfb,0x75,0x3d, +0x0, 0x7e,0xb3,0x2a,0x6f,0xf5,0x42,0x7e,0xb3,0x2a,0x70,0xf5,0x43,0x75,0x44,0x28, +0x7e,0xd3,0x28,0x84,0xe4,0x7a,0xb3,0x31,0xf5,0x7a,0xb3,0x31,0xf1,0x7a,0xb3,0x31, +0xf2,0x7e,0x8, 0x31,0xf6,0x12,0x3f,0xcf,0xe4,0x12,0x1b,0xb8,0x12,0x3f,0xcf,0x3e, +0x34,0x7e,0x8, 0x32,0x16,0xe4,0x12,0x1b,0xb8,0xbe,0xd0,0x2, 0x50,0x2, 0xe1,0x50, +0x6c,0xcc,0xe1,0x4a,0x12,0x6f,0x32,0xf5,0x24,0x9, 0xb3,0x26,0xfb,0xf5,0x25,0x4c, +0xcc,0x68,0x8, 0xa, 0x3c,0x9, 0xb3,0x31,0xf6,0x70,0xa, 0xa, 0x3c,0xb, 0x34,0xa, +0x2c,0x19,0x72,0x31,0xf6,0x7c,0xbd,0x14,0xbc,0xbc,0x78,0x2, 0xe1,0x50,0xa, 0x5c, +0xb, 0x54,0xf5,0x2e,0xe1,0x41,0x7e,0x71,0x2e,0x12,0x46,0x90,0x7a,0xa1,0x26,0x9, +0xb3,0x26,0xfb,0xf5,0x27,0xa, 0x2a,0xe5,0x24,0x12,0x3f,0x55,0x7c,0xb7,0xf5,0x28, +0xe5,0x27,0xa, 0x2b,0x12,0x3f,0x53,0x7c,0xb7,0xf5,0x29,0xe5,0x28,0xbe,0xb0,0x5, +0x40,0x2, 0xe1,0x3f,0xe5,0x29,0xbe,0xb0,0x5, 0x40,0x2, 0xe1,0x3f,0x12,0x3f,0xec, +0x12,0x6e,0x42,0x7a,0xb3,0x31,0xf4,0x85,0x25,0x54,0x85,0x26,0x55,0x85,0x27,0x56, +0x7e,0x8, 0x0, 0x31,0x7e,0x18,0x0, 0x33,0xe5,0x24,0x12,0xb0,0x82,0x75,0x3d,0x0, +0x6c,0xee,0x75,0x30,0x0, 0xe5,0x24,0x7e,0x71,0x25,0x12,0x3b,0x73,0x7a,0x35,0x35, +0xe5,0x26,0x7e,0x71,0x27,0x12,0x3b,0x73,0x7a,0x35,0x37,0x7e,0x35,0x35,0xbe,0x35, +0x37,0x8, 0x5, 0x7e,0x35,0x37,0x80,0x3, 0x7e,0x35,0x35,0x7a,0x35,0x3b,0xe, 0x34, +0x7a,0x35,0x39,0xe5,0x28,0xbe,0xb0,0x1, 0x38,0x2c,0xe5,0x29,0xbe,0xb0,0x1, 0x38, +0x25,0x7c,0xbf,0x30,0xe1,0x20,0xe5,0x26,0x7e,0x71,0x25,0x12,0x3b,0x73,0x7d,0x43, +0xe5,0x24,0x7e,0x71,0x27,0x12,0x3b,0x73,0x2d,0x34,0xbe,0x35,0x39,0x18,0x2, 0xc1, +0xda,0x75,0x30,0x1, 0xc1,0xda,0xe5,0x28,0xbe,0xb0,0x1, 0x38,0x9, 0xe5,0x29,0xbe, +0xb0,0x1, 0x38,0x2, 0xc1,0xda,0xe5,0x28,0xbe,0xb0,0x5, 0x40,0x2, 0xc1,0xda,0xe5, +0x29,0xbe,0xb0,0x5, 0x40,0x2, 0xc1,0xda,0x7c,0xbf,0x20,0xe0,0x2, 0xc1,0xda,0x6d, +0x33,0x7a,0x35,0x4d,0x75,0x4f,0x0, 0x7a,0x35,0x50,0x75,0x52,0x0, 0xc2,0x2, 0xc2, +0x3, 0xe5,0x26,0xbe,0xb1,0x24,0x28,0x4, 0xe5,0x24,0x80,0x2, 0xe5,0x26,0xf5,0x2a, +0xe5,0x26,0xbe,0xb1,0x24,0x50,0x4, 0xe5,0x24,0x80,0x2, 0xe5,0x26,0xf5,0x2c,0xe5, +0x27,0xbe,0xb1,0x25,0x28,0x4, 0xe5,0x25,0x80,0x2, 0xe5,0x27,0xf5,0x2b,0xe5,0x27, +0xbe,0xb1,0x25,0x50,0x4, 0xe5,0x25,0x80,0x2, 0xe5,0x27,0xf5,0x2d,0xe5,0x2c,0xbe, +0xb1,0x2a,0x78,0x29,0xd2,0x2, 0xe5,0x2a,0x60,0x8, 0xe5,0x42,0x14,0xbe,0xb1,0x2a, +0x78,0x2, 0xd2,0x3, 0xe5,0x2a,0xbe,0xb0,0x0, 0x28,0x2, 0x15,0x2a,0xe5,0x42,0xa, +0x2b,0x1b,0x24,0xe5,0x2c,0xa, 0x3b,0xbd,0x32,0x58,0x2, 0x5, 0x2c,0xe5,0x2d,0xbe, +0xb1,0x2b,0x78,0x29,0xd2,0x2, 0xe5,0x2b,0x60,0x8, 0xe5,0x43,0x14,0xbe,0xb1,0x2b, +0x78,0x2, 0xd2,0x3, 0xe5,0x2b,0xbe,0xb0,0x0, 0x28,0x2, 0x15,0x2b,0xe5,0x43,0xa, +0x2b,0x1b,0x24,0xe5,0x2d,0xa, 0x3b,0xbd,0x32,0x58,0x2, 0x5, 0x2d,0x85,0x2a,0x3e, +0x80,0x5b,0x85,0x2b,0x3f,0x80,0x4d,0xe5,0x3e,0x7e,0x71,0x3f,0x12,0x3b,0x73,0x7a, +0x35,0x40,0xe5,0x2a,0xbe,0xb1,0x3e,0x68,0x15,0xe5,0x2c,0xbe,0xb1,0x3e,0x68,0xe, +0xe5,0x2b,0xbe,0xb1,0x3f,0x68,0x7, 0xe5,0x2d,0xbe,0xb1,0x3f,0x78,0xd, 0x7e,0x35, +0x40,0x2e,0x35,0x4d,0x7a,0x35,0x4d,0x5, 0x4f,0x80,0x17,0x5, 0x52,0x7e,0x35,0x40, +0x2e,0x35,0x50,0x7a,0x35,0x50,0x7e,0x35,0x33,0xbe,0x35,0x40,0x58,0x2, 0x5, 0x3d, +0xb, 0xe0,0x5, 0x3f,0xe5,0x2d,0xbe,0xb1,0x3f,0x50,0xac,0x5, 0x3e,0xe5,0x2c,0xbe, +0xb1,0x3e,0x50,0x9e,0xe5,0x2c,0x7e,0x71,0x2b,0x12,0x3b,0x73,0x7e,0x45,0x4d,0x9d, +0x43,0xe5,0x2a,0x7e,0x71,0x2d,0x12,0x3b,0x73,0x9d,0x43,0xe5,0x2a,0x7e,0x71,0x2b, +0x12,0x3b,0x73,0x9d,0x43,0xe5,0x2c,0x7e,0x71,0x2d,0x12,0x3b,0x73,0x7d,0x23,0x7d, +0x34,0x9d,0x32,0x7a,0x35,0x4d,0x7e,0x35,0x37,0x2e,0x35,0x35,0x7a,0x35,0x39,0x30, +0x2, 0x10,0x20,0x3, 0xd, 0x7e,0x35,0x4d,0x9e,0x35,0x39,0x7a,0x35,0x4d,0x15,0x4f, +0x15,0x4f,0xe5,0x4f,0xbe,0xb0,0x4, 0x28,0x6, 0xe5,0x4f,0x24,0xfc,0xf5,0x4f,0x7e, +0x35,0x4d,0xbe,0x34,0x0, 0x0, 0x58,0x5, 0x6d,0x33,0x7a,0x35,0x4d,0x75,0x44,0x28, +0xe5,0x42,0x14,0xbe,0xb1,0x24,0x68,0xd, 0xbe,0xb1,0x26,0x68,0x8, 0xe5,0x24,0x60, +0x4, 0xe5,0x26,0x70,0x8, 0x12,0xb1,0x11,0x28,0x3, 0x75,0x44,0x2c,0x7e,0x15,0x50, +0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x4d,0x1a,0x26,0x1a,0x24,0x2f,0x10,0xe5,0x44,0xa, +0x1b,0x6d,0x0, 0x12,0x18,0xde,0x7f,0x71,0x7a,0x7d,0x45,0x7e,0x15,0x39,0x1a,0x2, +0x1a,0x0, 0x7e,0x35,0x31,0x1a,0x26,0x1a,0x24,0x12,0x18,0xde,0xe5,0x52,0xa, 0xdb, +0x6d,0xcc,0xe5,0x4f,0xa, 0x1b,0x6d,0x0, 0x2f,0x6, 0x12,0x18,0xde,0x7a,0x1d,0x49, +0xbf,0x71,0x8, 0x3, 0x75,0x30,0x2, 0xc2,0x1, 0x20,0xa, 0xe, 0x12,0x3f,0xec,0x12, +0xb3,0xd1,0x92,0x1, 0x20,0x1, 0x3, 0x75,0x30,0x0, 0xe5,0x30,0xbe,0xb0,0x0, 0x28, +0x5e,0xe5,0x30,0xa, 0x3b,0x2e,0x34,0x31,0xf0,0x12,0x9a,0x5d,0xe5,0x2e,0xa, 0x3b, +0x9, 0xa3,0x31,0xf6,0x4c,0xaa,0x78,0xc, 0xa, 0x2c,0x9, 0xb2,0x31,0xf6,0x19,0xb3, +0x31,0xf6,0x80,0x3b,0xa, 0x2c,0x9, 0xb2,0x31,0xf6,0xf5,0x53,0xbc,0xba,0x28,0x3, +0x7a,0xa1,0x53,0x75,0x2f,0x0, 0x80,0x22,0x9, 0x33,0x31,0xf6,0xe5,0x2f,0xa, 0x2b, +0x9, 0x22,0x31,0xf6,0xbc,0x23,0x68,0xa, 0xa, 0xc, 0x9, 0x30,0x31,0xf6,0xbc,0x23, +0x78,0x6, 0xe5,0x53,0x19,0xb2,0x31,0xf6,0x5, 0x2f,0xbe,0xd1,0x2f,0x38,0xd9,0x5, +0x2e,0xbe,0xd1,0x2e,0x28,0x2, 0x61,0xf6,0xb, 0xc0,0xbc,0xdc,0x28,0x2, 0x61,0xc4, +0xda,0x3b,0x22,0xe5,0x25,0xa, 0x3b,0x9d,0x32,0x2, 0x1b,0xfa,0xc2,0x0, 0x7e,0xb3, +0x16,0x91,0x60,0x6, 0x7e,0xb3,0x16,0x90,0x70,0x7, 0x12,0x9d,0x98,0x28,0x2, 0xd2, +0x0, 0xa2,0x0, 0x22,0x7c,0x7b,0x12,0xab,0x5b,0x9, 0xa2,0x27,0x72,0x7c,0xb7,0x54, +0x7, 0xa, 0x3b,0x2e,0x34,0x0, 0x5e,0x12,0x90,0xcb,0x5c,0xba,0x22,0x7e,0x70,0x1, +0x7c,0x67,0x7c,0x7b,0xc4,0x23,0x54,0x1f,0x7c,0xab,0x7c,0xb7,0x54,0x7, 0xa, 0x2b, +0x2e,0x24,0x0, 0x5e,0x12,0x69,0x33,0x7c,0x7b,0x4c,0x66,0x68,0xf, 0xa, 0x2a,0x2e, +0x24,0x27,0x72,0x7e,0x29,0xb0,0x4c,0xb7,0x7a,0x29,0xb0,0x22,0x7c,0xb7,0x64,0xff, +0xa, 0x2a,0x2e,0x24,0x27,0x72,0x7e,0x29,0x70,0x5c,0x7b,0x7a,0x29,0x70,0x22,0x90, +0x60,0x9a,0x93,0xa, 0x3b,0x22,0x7e,0x70,0x2, 0xac,0x79,0x9, 0xb3,0x1f,0x34,0x22, +0x90,0x60,0x99,0xe4,0x93,0x7c,0x7b,0x74,0x2, 0xac,0x7b,0x22,0xe5,0x24,0x7e,0x71, +0x25,0x7e,0x61,0x26,0x7e,0x51,0x27,0x22,0x2, 0x3f,0xfb,0xca,0x3b,0x6c,0xff,0x12, +0xa4,0x59,0x7e,0xb3,0x16,0x91,0xb4,0x1, 0x2, 0x80,0x2, 0x1, 0xe3,0x6c,0xcc,0x1, +0xd5,0x12,0x6f,0x32,0xf5,0x27,0x9, 0xb3,0x26,0xfb,0xf5,0x28,0x75,0x25,0x2, 0x75, +0x26,0x2, 0x7c,0xbc,0x12,0x40,0xe6,0xd2,0x0, 0x12,0x42,0x61,0xe5,0x27,0x60,0xc, +0xa, 0x2e,0x1b,0x24,0xe5,0x27,0xa, 0x3b,0xbd,0x32,0x48,0x3, 0x75,0x25,0x1, 0xe5, +0x28,0x60,0xc, 0xa, 0x2d,0x1b,0x24,0xe5,0x28,0xa, 0x3b,0xbd,0x32,0x48,0x3, 0x75, +0x26,0x1, 0x75,0x24,0x0, 0x80,0x38,0xe5,0x24,0xbc,0xbc,0x68,0x30,0x12,0x46,0x8d, +0x7a,0xa1,0x29,0x9, 0xb3,0x26,0xfb,0xf5,0x2a,0xa, 0x2a,0xe5,0x27,0x12,0x3f,0x55, +0xbe,0x34,0x0, 0x3, 0x18,0x17,0xe5,0x2a,0xa, 0x2b,0xe5,0x28,0x12,0x3f,0x55,0xbe, +0x34,0x0, 0x3, 0x18,0x8, 0x75,0x25,0x1, 0x75,0x26,0x1, 0x80,0x7, 0x5, 0x24,0x12, +0xc0,0x4b,0x38,0xc3,0xe5,0x27,0x7e,0x71,0x28,0x12,0xa5,0x89,0x50,0x6, 0x12,0x42, +0x11,0x12,0x42,0xb1,0xe5,0x25,0x7e,0x71,0x26,0x7c,0x6c,0x7c,0x5f,0x12,0x6a,0xf0, +0x90,0x61,0x36,0xe4,0x93,0xb4,0x1, 0x16,0x7e,0x70,0x9, 0xac,0x7c,0x7d,0x13,0x2e, +0x14,0x27,0x76,0x6d,0x0, 0x2e,0x34,0x27,0x78,0x6d,0x22,0x12,0x88,0x40,0x12,0x42, +0x11,0xb, 0xf0,0xb, 0xc0,0x7e,0x73,0x28,0x84,0xbc,0x7c,0x28,0x2, 0x1, 0x11,0x7a, +0xf3,0x28,0x84,0xda,0x3b,0x22,0xca,0x3b,0x7c,0x5b,0x7e,0x43,0x28,0x84,0xbe,0x40, +0x1, 0x28,0x2, 0x21,0xe1,0x7e,0xa3,0x2a,0x6e,0x7e,0x70,0x2, 0xac,0x75,0x9, 0xd3, +0x26,0xfa,0x9, 0xc3,0x26,0xfb,0x7c,0xbd,0x7c,0x7c,0x12,0x6e,0x2c,0x7f,0x1, 0x90, +0x60,0xaa,0xe4,0x93,0x70,0x12,0x7c,0xfc,0x7c,0x9d,0x7e,0x83,0x2a,0x70,0x7e,0xe3, +0x2a,0x6f,0xa, 0xca,0x6d,0xbb,0x9d,0xbc,0xa, 0xa8,0x1b,0xa5,0xa, 0x5f,0xbd,0x5a, +0x58,0x2, 0x21,0xe1,0xa, 0x59,0x1b,0x54,0xbe,0x54,0x0, 0x0, 0x48,0x4e,0x7c,0xb9, +0x14,0x12,0x42,0x3f,0x50,0x46,0x7c,0xb9,0x14,0x12,0x41,0xe4,0xb, 0x1a,0xe0,0x7d, +0x3b,0x12,0x42,0xa3,0x8, 0x11,0x9d,0xae,0xbe,0xa4,0x0, 0x0, 0x58,0x4, 0x6d,0x55, +0x80,0x2, 0x7d,0x5a,0x12,0x42,0x9b,0x7c,0xb8,0x24,0xfe,0xbc,0xbf,0x78,0x1d,0x90, +0x60,0xaa,0xe4,0x93,0x70,0x4, 0x7d,0xfd,0x1b,0xf4,0x7d,0x5f,0x12,0x41,0xeb,0xb, +0x1a,0x30,0xbd,0x3a,0x8, 0x6, 0x12,0x41,0xed,0x1b,0x1a,0xa0,0xa, 0xa9,0xb, 0xa4, +0xa, 0x5e,0xbd,0xa5,0x58,0x4b,0x7c,0xb9,0x4, 0x12,0x42,0x3f,0x50,0x43,0x7c,0xb9, +0x4, 0x12,0x41,0xe4,0xb, 0x1a,0xe0,0x7d,0x3c,0x12,0x42,0xa3,0x8, 0x11,0x9d,0xae, +0xbe,0xa4,0x0, 0x0, 0x58,0x4, 0x6d,0x55,0x80,0x2, 0x7d,0x5a,0x12,0x42,0x9b,0x7c, +0xb8,0x24,0xfe,0xbc,0xbf,0x78,0x1a,0x90,0x60,0xaa,0xe4,0x93,0x70,0x4, 0x7d,0xfd, +0x1b,0xf4,0x7d,0x5f,0x12,0x41,0xeb,0xb, 0x1a,0x50,0xbd,0x5a,0x8, 0x3, 0x1b,0x1a, +0xa0,0xda,0x3b,0x22,0x12,0x41,0xf4,0x7d,0xd3,0x7d,0x5d,0x3e,0x54,0x7e,0x1f,0x13, +0x8a,0x2d,0x35,0x22,0x7c,0x5b,0x7e,0x43,0x2a,0x6e,0x90,0x60,0xab,0xe4,0x93,0x7c, +0xab,0x90,0x60,0xaa,0xe4,0x93,0x70,0x8, 0x7c,0x75,0xac,0x74,0xa, 0x2a,0x2d,0x32, +0x22,0x12,0x46,0x7b,0x60,0x28,0x6c,0x22,0x80,0x1c,0x7c,0xb2,0x12,0x42,0x3f,0x50, +0x13,0x7c,0xb2,0x12,0x41,0xf4,0x7d,0x3, 0x12,0x46,0x73,0x49,0x55,0x3a,0xfa,0x7d, +0x40,0x12,0x9f,0x8d,0xb, 0x20,0x7e,0x73,0x2a,0x71,0xbc,0x72,0x38,0xdc,0x22,0x7c, +0xab,0x6c,0x77,0x80,0x11,0xa, 0x27,0x2e,0x24,0x60,0xac,0x12,0x69,0x33,0xbc,0xba, +0x78,0x2, 0xd3,0x22,0xb, 0x70,0x90,0x60,0xa7,0xe4,0x93,0xbc,0xb7,0x38,0xe6,0xc3, +0x22,0x12,0x46,0x7b,0x60,0x34,0x6c,0x22,0x80,0x28,0x7c,0xb2,0x12,0x42,0x3f,0x50, +0x1f,0x7c,0xb2,0x12,0x41,0xf4,0x3e,0x34,0x7e,0x7f,0x13,0x8a,0x2d,0xf3,0xb, 0x7a, +0x30,0x12,0x46,0x73,0x59,0x35,0x3a,0xfa,0x30,0x0, 0x5, 0x6d,0x33,0x1b,0x7a,0x30, +0xb, 0x20,0x7e,0x73,0x2a,0x71,0xbc,0x72,0x38,0xd0,0x22,0x2d,0x31,0x7d,0x20,0x1b, +0x1a,0x50,0x22,0x3e,0x34,0x7f,0x40,0x2d,0x93,0xb, 0x4a,0xa0,0xbe,0xe4,0x0, 0x0, +0x22,0x75,0x25,0x0, 0x75,0x26,0x0, 0x22,0xca,0x3b,0x75,0x24,0x0, 0x6c,0xff,0x12, +0x42,0xb1,0x75,0x28,0x3, 0x6c,0xee,0x7e,0x48,0x29,0xbc,0x7e,0xb3,0x2a,0xb, 0x70, +0xe, 0x7e,0xb3,0x2a,0x7, 0x70,0x8, 0x7e,0xb3,0x2a,0x8, 0x70,0x2, 0x81,0xaa,0x30, +0x10,0x6, 0x7e,0x68,0x33,0x59,0x80,0x4, 0x7e,0x68,0x33,0x1b,0x7f,0x6, 0x12,0xbf, +0xfd,0x7e,0x73,0x2a,0x4, 0x7a,0x6b,0x70,0x6c,0xdd,0x81,0x5b,0x74,0x9, 0xac,0xbd, +0x9, 0xc5,0x29,0xc, 0x7c,0xbc,0x54,0xf, 0x12,0x44,0xd3,0xf5,0x28,0x7c,0xbc,0x54, +0xf0,0xbe,0xb0,0x0, 0x28,0x2, 0x81,0x59,0xe5,0x28,0xbe,0xb0,0x3, 0x78,0x2, 0x81, +0x59,0x7e,0x8, 0x0, 0x28,0x7c,0xbc,0x12,0x97,0xe5,0x50,0x2, 0x81,0x59,0x74,0x9, +0xac,0xbd,0x9, 0xb5,0x29,0xd, 0xf5,0x25,0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xe, +0xc4,0x54,0xf0,0xf5,0x26,0x7e,0x73,0x2a,0x4d,0xbc,0x7c,0x28,0x54,0x7e,0xb3,0x2a, +0x9, 0x70,0x2a,0x75,0x29,0xf, 0x7e,0x8, 0x0, 0x25,0xa, 0x3c,0x2e,0x34,0x33,0x7, +0x6d,0x22,0x74,0x1, 0x12,0x44,0xdd,0x75,0x29,0x20,0x7e,0x8, 0x0, 0x26,0xa, 0x3c, +0x2e,0x34,0x33,0x11,0x6d,0x22,0x74,0x10,0x12,0x44,0xdd,0x80,0xe, 0xa, 0x3c,0x9, +0xb3,0x33,0x7, 0xf5,0x25,0x9, 0xb3,0x33,0x11,0xf5,0x26,0xa, 0x3c,0x12,0x44,0xd5, +0xb4,0x1, 0xe, 0xe4,0xa, 0x3c,0x19,0xb3,0x33,0x7, 0x19,0xb3,0x33,0x11,0x12,0x42, +0xb1,0x7e,0xb3,0x2a,0x64,0xb4,0xff,0x13,0x75,0x25,0x0, 0x74,0x9, 0xac,0xbd,0x9, +0xb5,0x29,0xc, 0xbe,0xb0,0xff,0x68,0x3, 0x75,0x25,0x1, 0x7e,0x90,0x9, 0xac,0x9d, +0x49,0xb4,0x29,0x8, 0x49,0xa4,0x29,0xa, 0xe5,0x28,0xb4,0x1, 0x2c,0x75,0x27,0x0, +0x80,0x1d,0x7e,0x71,0x27,0x74,0x9, 0xac,0x7b,0x9, 0xb3,0x33,0x9b,0x54,0xf, 0xbc, +0xbc,0x78,0xa, 0x49,0xb3,0x33,0x97,0x49,0xa3,0x33,0x99,0x80,0xc, 0x5, 0x27,0x90, +0x60,0x99,0xe4,0x93,0xbe,0xb1,0x27,0x38,0xd9,0x5e,0xb4,0xf, 0xff,0x5e,0xa4,0xf, +0xff,0x9, 0x74,0x29,0xc, 0xa, 0x57,0xc4,0x54,0xf0,0x7c,0xab,0xe4,0x2d,0xa5,0xbe, +0x70,0xff,0x68,0x16,0xe5,0x28,0xbe,0xb0,0x1, 0x68,0x2, 0x5, 0x24,0xb, 0xf0,0xe5, +0x28,0xa, 0x5b,0x12,0xb6,0x90,0x2d,0xb5,0x80,0x4, 0x2e,0xb4,0xc0,0x0, 0x7e,0x70, +0x6, 0xac,0x7e,0x7f,0x6, 0x2d,0x13,0x79,0xb0,0x0, 0x2, 0x7f,0x6, 0x2d,0x13,0x79, +0xa0,0x0, 0x4, 0xe5,0x25,0x7f,0x6, 0x2d,0x13,0x39,0xb0,0x0, 0x6, 0xe5,0x26,0x2d, +0x3d,0x7d,0x2c,0x39,0xb1,0x0, 0x7, 0xb, 0xe0,0xb, 0xd0,0x7e,0x73,0x2a,0x4d,0xbc, +0x7d,0x28,0x2, 0x41,0xfc,0xe5,0x24,0x39,0xb6,0x0, 0x1, 0x7e,0xb3,0x38,0xff,0xb4, +0x1, 0x9, 0x7e,0xb3,0x2a,0x8, 0xb4,0x1, 0x17,0x80,0xd, 0xbe,0xf0,0x0, 0x38,0x6, +0x7e,0xb3,0x2a,0x8, 0x60,0xa, 0xb2,0x10,0x12,0x70,0xf4,0x74,0x1, 0x12,0x38,0xcc, +0x7e,0xb3,0x2a,0x7, 0x60,0x5, 0x7f,0x4, 0x12,0x46,0x99,0xe4,0x7a,0xb3,0x2a,0xb, +0x7a,0xb3,0x2a,0x7, 0x7a,0xb3,0x2a,0x8, 0x80,0x4, 0xe4,0x12,0x38,0xcc,0x12,0x8c, +0x6c,0xca,0x59,0x7e,0x18,0x29,0x8, 0x7e,0x8, 0x33,0x97,0x12,0x1b,0x93,0x1b,0xfd, +0x4c,0xff,0x78,0xc, 0x12,0x46,0xeb,0x7e,0x8, 0x33,0x97,0x74,0xff,0x12,0x1b,0xb8, +0xda,0x3b,0x22,0xa, 0x3b,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0x22,0x7c,0x9b,0x7f, +0x71,0x7e,0x7b,0x80,0x4c,0x88,0x78,0x7, 0x7e,0xb, 0x90,0x7a,0x7b,0x90,0x22,0xa, +0x28,0x7e,0xb, 0x80,0xa, 0x38,0x9d,0x32,0x12,0x1b,0xfa,0xe5,0x29,0xa, 0x2b,0xbd, +0x32,0x8, 0x15,0x7e,0x7b,0xa0,0x7e,0xb, 0xb0,0xbc,0xba,0x7c,0xba,0x28,0x4, 0x2c, +0xb9,0x80,0x2, 0x9c,0xb9,0x7a,0x7b,0xb0,0x7e,0x7b,0x70,0x7a,0xb, 0x70,0x22,0xca, +0x3b,0x7f,0x40,0x7e,0xe3,0x28,0x84,0x6c,0xdd,0x7e,0xc0,0x1, 0x80,0x1a,0xa, 0x3d, +0x2d,0x39,0x7d,0x28,0x7e,0x1b,0x60,0xa, 0x2c,0x7f,0x4, 0x2d,0x12,0x7e,0xb, 0x70, +0xbc,0x76,0x40,0x2, 0x7c,0xdc,0xb, 0xc0,0xbc,0xec,0x38,0xe2,0xa, 0x3d,0x2d,0x39, +0x7d,0x28,0x7e,0x1b,0xd0,0x6c,0xff,0x7e,0xc0,0x1, 0xc1,0x65,0x75,0x2b,0x0, 0x6d, +0x33,0x7a,0x35,0x2c,0x12,0x42,0xb1,0x7e,0x18,0x1f,0x70,0x7a,0x1d,0x27,0x74,0xff, +0x7e,0x34,0x1f,0x71,0x7e,0x24,0x0, 0x0, 0x7a,0x1b,0xb0,0x7e,0x1d,0x27,0x7a,0x1b, +0xb0,0xe4,0x7e,0x1d,0x27,0x39,0xb1,0x0, 0x3, 0x7e,0x1d,0x27,0x39,0xb1,0x0, 0x2, +0x7e,0x1d,0x27,0x12,0x46,0x85,0x44,0x1, 0x7a,0x1b,0xb0,0x75,0x24,0x0, 0x80,0x68, +0x12,0x46,0x8d,0x9, 0x93,0x26,0xfb,0xe5,0x24,0x12,0x44,0xd3,0xbc,0xbc,0x78,0x56, +0x5, 0x2b,0x7c,0xba,0x25,0x25,0xf5,0x25,0x7c,0xb9,0x25,0x26,0xf5,0x26,0x12,0x3b, +0x6f,0xbe,0x35,0x2c,0x8, 0x6, 0x12,0x3b,0x6f,0x7a,0x35,0x2c,0x7e,0x1d,0x27,0x7e, +0x1b,0xb0,0xbc,0xba,0x28,0x3, 0x7a,0x1b,0xa0,0x7e,0x1d,0x27,0x29,0xb1,0x0, 0x2, +0xbc,0xba,0x50,0x4, 0x39,0xa1,0x0, 0x2, 0x7e,0x1d,0x27,0x29,0xb1,0x0, 0x1, 0xbc, +0xb9,0x28,0x4, 0x39,0x91,0x0, 0x1, 0x7e,0x1d,0x27,0x29,0xb1,0x0, 0x3, 0xbc,0xb9, +0x50,0x4, 0x39,0x91,0x0, 0x3, 0x5, 0x24,0xbe,0xe1,0x24,0x38,0x93,0xe5,0x2b,0xbe, +0xb0,0x0, 0x28,0x4f,0x7e,0xd, 0x27,0x12,0xb1,0x19,0x7e,0xa1,0x2b,0xe5,0x25,0x84, +0xf5,0x25,0x7e,0xa1,0x2b,0xe5,0x26,0x84,0xf5,0x26,0x7e,0xa1,0x25,0x7e,0x70,0x2, +0xac,0x7f,0x19,0xa3,0x32,0x16,0x7e,0xa1,0x26,0x7e,0x70,0x2, 0xac,0x7f,0x19,0xa3, +0x32,0x17,0x7e,0x37,0x32,0x14,0x4d,0x33,0x68,0x17,0xe5,0x25,0x7e,0x71,0x26,0x12, +0x3b,0x73,0x7e,0x25,0x2c,0x7e,0x70,0x2, 0xac,0x7f,0x2e,0x37,0x32,0x14,0x1b,0x38, +0x20,0xb, 0xf0,0xb, 0xc0,0xbc,0xdc,0x40,0x2, 0xa1,0x5c,0x12,0x9e,0xb7,0x7c,0xbf, +0xda,0x3b,0x22,0x7c,0xa3,0xb, 0x30,0x74,0x2, 0xa4,0x22,0x6c,0x33,0x90,0x60,0xa7, +0xe4,0x93,0x22,0x7f,0x16,0x2e,0x34,0x0, 0x5, 0x7e,0x1b,0xb0,0x22,0x7e,0x71,0x24, +0x74,0x2, 0xac,0x7b,0x9, 0xa3,0x26,0xfa,0x22,0x6c,0xaa,0x80,0x20,0x74,0x3, 0x12, +0x77,0xe1,0x7f,0x10,0x2d,0x34,0x39,0xb1,0x0, 0xa, 0x12,0x57,0x29,0x7f,0x70,0x2d, +0xf3,0x79,0x47,0x0, 0x14,0x2d,0x31,0x79,0x41,0x0, 0x28,0xb, 0xa0,0x12,0x54,0x76, +0x38,0xdb,0x22,0x12,0x46,0xeb,0x7e,0x24,0x0, 0x3, 0xad,0x32,0x7e,0x8, 0x28,0xae, +0x74,0xff,0x12,0x1b,0xb8,0x12,0x9a,0x65,0x7e,0x8, 0x29,0xbc,0x12,0x46,0x99,0x7e, +0x8, 0x2a,0x2, 0x7e,0x34,0x0, 0xb, 0xe4,0x2, 0x1b,0xb8,0x90,0x60,0x99,0xe4,0x93, +0x7c,0x7b,0x74,0x9, 0xac,0x7b,0x22,0x90,0x60,0xa7,0xe4,0x93,0x60,0x2b,0x6c,0x33, +0x80,0x1f,0x7c,0xb3,0x12,0x42,0x3f,0x40,0x16,0x7c,0xb3,0x12,0x41,0xf4,0x7d,0x43, +0x6d,0x55,0x7d,0x4, 0x3e,0x4, 0x7e,0x1f,0x13,0x8a,0x2d,0x30,0x1b,0x1a,0x50,0xb, +0x30,0x7e,0x23,0x2a,0x71,0xbc,0x23,0x38,0xd9,0x22,0x12,0x63,0x86,0x12,0x58,0xa4, +0x12,0x0, 0xa, 0x12,0xae,0x36,0x7e,0x18,0x4, 0x0, 0x7a,0x1f,0x6, 0xf8,0x7e,0xf, +0x6, 0xf8,0x7e,0x1f,0x6, 0xf4,0x12,0x67,0xfb,0x7e,0x18,0x8, 0xa, 0x7a,0x1f,0x13, +0x86,0x7e,0x18,0xd, 0xc8,0x7a,0x1f,0x13,0x8a,0x7e,0xf, 0x13,0x8a,0x7e,0x1f,0x13, +0x86,0x12,0x66,0xa, 0x12,0x47,0xf3,0x12,0x57,0xd1,0x12,0x47,0x81,0x12,0x46,0xc3, +0x2, 0x47,0x73,0xe4,0x7a,0xb3,0x34,0x38,0x7a,0xb3,0x34,0x39,0x7a,0xb3,0x34,0x3a, +0x22,0x7e,0x8, 0x26,0x5b,0x7e,0x34,0x2, 0x3a,0xe4,0x12,0x1b,0xb8,0x90,0x60,0x9c, +0x93,0xa, 0x3b,0x3e,0x34,0x7e,0x8, 0x26,0x8c,0x74,0xff,0x12,0x1b,0xb8,0x90,0x60, +0x9c,0x12,0x2f,0xf4,0x7e,0x8, 0x26,0xb4,0x74,0xff,0x12,0x1b,0xb8,0x90,0x60,0x9a, +0x12,0x46,0xee,0x7e,0x8, 0x27,0x76,0x74,0xff,0x2, 0x1b,0xb8,0x7e,0x8, 0x39,0xc1, +0x12,0x47,0xfd,0x7e,0x8, 0x39,0xc9,0x12,0x47,0xfd,0x12,0x47,0xf6,0x12,0xbe,0x12, +0x2, 0x47,0xd3,0x7e,0x37,0x39,0xc1,0xbe,0x34,0x0, 0x0, 0x28,0x15,0x7e,0x73,0x3, +0xff,0xbe,0x70,0x5, 0x50,0xc, 0x7e,0xb3,0x38,0xff,0x70,0x6, 0x12,0x48,0x47,0x12, +0x4a,0x1a,0x22,0x2, 0x1e,0x89,0x7e,0x8, 0x2b,0xb3,0x2, 0x47,0xfd,0xb, 0xa, 0x30, +0xe5,0x5b,0xa, 0x2b,0xbd,0x32,0x28,0x4, 0x9d,0x32,0x80,0x2, 0x6d,0x33,0x1b,0xa, +0x30,0x22,0x7e,0x73,0x28,0x93,0x7a,0x73,0x28,0x94,0x7e,0x73,0x2a,0x2, 0x7a,0x73, +0x2a,0x3, 0xe4,0x7a,0xb3,0x2a,0x6, 0x22,0x12,0xbf,0xc0,0x12,0x48,0x47,0x7a,0x37, +0x3, 0xfc,0x12,0x2f,0xbd,0x12,0x31,0xb1,0x2, 0x48,0x3b,0x74,0x3, 0x7a,0xb3,0x2f, +0xa5,0xe4,0x7a,0xb3,0x30,0x0, 0x22,0x6d,0x33,0x7a,0x37,0x3a,0x8f,0x22,0x7e,0xb3, +0x38,0xd4,0x14,0x68,0x5d,0x14,0x78,0x2, 0x1, 0xef,0x14,0x68,0x6d,0x24,0x3, 0x68, +0x2, 0x1, 0xe7,0x12,0x4a,0x21,0x38,0x8, 0x30,0x12,0xf, 0x12,0x96,0x1e,0x68,0xa, +0x12,0x48,0x47,0xe4,0x7a,0xb3,0x3a,0x91,0x80,0x75,0x7e,0xb3,0x38,0xb5,0x30,0xe0, +0x6e,0x7e,0x73,0x38,0xb6,0xa, 0x27,0x7e,0x34,0x4, 0x0, 0xad,0x32,0x7e,0xb3,0x38, +0xff,0xb4,0x1, 0xb, 0x7e,0x34,0x62,0x64,0x12,0x1e,0x81,0x2e,0x34,0x4, 0x0, 0xbe, +0x37,0x3a,0x8f,0x50,0x4a,0x12,0x48,0x47,0x12,0x4a,0x1a,0xe4,0x7a,0xb3,0x3a,0x93, +0x80,0x3d,0x12,0x4a,0x21,0x28,0x33,0xe4,0x7a,0xb3,0x38,0xd4,0x7e,0xb3,0x3a,0x91, +0xb4,0x1, 0x3, 0x12,0x4a,0x1a,0xd2,0x19,0x80,0x20,0x7e,0x34,0x60,0xa5,0x12,0x1e, +0x81,0x12,0x2b,0x17,0x12,0x4a,0xfd,0x12,0x37,0x4b,0xe4,0x7a,0xb3,0x38,0xd4,0x7a, +0xb3,0x3, 0xff,0xd2,0x19,0x80,0x8, 0x12,0x4a,0x1a,0xe4,0x7a,0xb3,0x3, 0xff,0x12, +0x4b,0x87,0x2, 0x48,0xf5,0xca,0xd8,0xca,0x79,0x7e,0xb3,0x38,0xd4,0xb4,0x1, 0x2, +0x80,0x2, 0x41,0x15,0x6c,0xdd,0x6c,0xff,0x12,0x90,0x68,0x7d,0xf3,0x12,0x78,0xc, +0x50,0xfb,0x74,0x1, 0x7a,0xb3,0x3a,0x92,0x12,0x25,0x31,0x12,0x12,0x95,0x12,0x0, +0x1e,0x74,0xa, 0x12,0x4b,0x6c,0x12,0xbf,0xd7,0x7e,0xe7,0x2b,0x9, 0x7a,0xe5,0x24, +0x7e,0xe3,0x2a,0xf6,0x74,0x4, 0x7a,0xb3,0x2a,0xf6,0x7e,0xe7,0x2b,0x9, 0x5e,0xe4, +0x0, 0x3f,0x7a,0xe7,0x2b,0x9, 0x7e,0xb3,0x2a,0xf6,0x12,0xb9,0xad,0x7c,0x7b,0x74, +0x8, 0xac,0x7b,0x7e,0x24,0x0, 0x4, 0x12,0x18,0xac,0x7d,0x23,0x7d,0x3f,0x12,0x1f, +0x85,0xad,0x32,0x7a,0x37,0x2b,0x3, 0x12,0x27,0x8e,0x12,0x2b,0x13,0x7e,0xb3,0x38, +0xff,0xb4,0x1, 0x4, 0x74,0x10,0x80,0x2, 0x74,0x14,0x12,0x90,0xbd,0x12,0x29,0x4, +0x80,0xf, 0x80,0x7, 0x12,0x4a,0x7e,0xe4,0x12,0x4a,0xb6,0x20,0x93,0xf6,0x12,0x4a, +0x4e,0x30,0x1a,0xf7,0x30,0x19,0xf4,0xd2,0x1, 0x12,0x4a,0x34,0xe4,0x12,0x12,0xac, +0xb, 0xd0,0x12,0x4c,0x3f,0x12,0x90,0xd4,0x7e,0xa3,0x3a,0x91,0x4c,0xaa,0x78,0x6, +0x74,0x1, 0x7a,0xb3,0x3a,0x92,0x4c,0xaa,0x68,0xb, 0x7e,0xb3,0x38,0xff,0x70,0x5, +0xe4,0x7a,0xb3,0x3a,0x91,0x12,0x4a,0x29,0x78,0x18,0x7e,0xb3,0x3a,0x91,0x60,0x12, +0xe4,0x7a,0xb3,0x3a,0x91,0x7a,0xb3,0x2a,0x2, 0x7a,0xb3,0x2a,0x3, 0x7e,0xf0,0x1, +0x80,0x1c,0x12,0x4a,0x29,0x68,0x10,0x7e,0xb3,0x3a,0x91,0x70,0xa, 0x7e,0xf0,0x1, +0xe4,0x7a,0xb3,0x38,0xd4,0x80,0x7, 0xbe,0xd0,0x32,0x50,0x2, 0x21,0x6a,0xe4,0x7a, +0xb3,0x2b,0x0, 0x7e,0x35,0x24,0x7a,0x37,0x2b,0x9, 0x7a,0xe3,0x2a,0xf6,0x4c,0xff, +0x68,0x3, 0x12,0x31,0xb1,0xda,0x79,0xda,0xd8,0x22,0x74,0x1, 0x7a,0xb3,0x38,0xd4, +0x22,0x7e,0x73,0x2a,0x2, 0xbe,0x70,0x0, 0x22,0x7e,0x73,0x3b,0x4, 0xa, 0x37,0x5e, +0x34,0x0, 0x2, 0x22,0x30,0x1, 0x6, 0x12,0x4b,0x4a,0x2, 0x12,0x64,0x12,0x4f,0xd7, +0xc2,0x2, 0x2, 0x4a,0x45,0xa9,0xd0,0xce,0xa2,0x2, 0xa9,0x91,0xc9,0x22,0x30,0x1a, +0x5, 0xc2,0x1, 0x12,0x4a,0x34,0xa9,0xd1,0xcd,0xa9,0xc5,0xea,0x30,0x19,0x3, 0x20, +0x1a,0x14,0x12,0x4a,0x7e,0xa9,0xd0,0xce,0xa9,0xc4,0xc9,0x74,0x2, 0x12,0x4a,0xb6, +0xa9,0xd0,0xce,0xa9,0xd4,0xc9,0xa9,0xc1,0xcd,0xd2,0x1, 0x2, 0x4a,0x34,0x74,0x81, +0x7a,0xb3,0x3, 0xfa,0x22,0x80,0x1d,0x12,0x4a,0x7e,0x12,0x4b,0xce,0x68,0x5, 0xc2, +0x1, 0x12,0x4a,0x34,0x7e,0xb3,0x34,0x3a,0xbe,0xb0,0x2, 0x68,0x18,0x20,0x19,0x15, +0xe4,0x12,0x4a,0xb6,0x20,0x93,0xe0,0x12,0x4a,0x7e,0xa9,0xd1,0xcd,0xa9,0xc5,0xea, +0x74,0x2, 0x2, 0x4a,0xb6,0x22,0x7c,0xab,0x7e,0xb3,0x3, 0xfa,0xb4,0x81,0x38,0x4c, +0xaa,0x78,0x5, 0xa9,0xd0,0x87,0x80,0x29,0xbe,0xa0,0x1, 0x78,0xf, 0xc2,0xaf,0xa9, +0xd0,0xce,0xa9,0xc7,0xc9,0xa9,0xd1,0x87,0xd2,0xaf,0x80,0x15,0xbe,0xa0,0x2, 0x78, +0x16,0xc2,0xaf,0x20,0x93,0x9, 0xa9,0xd0,0xce,0xa9,0xd7,0xc9,0xa9,0xd1,0x87,0xd2, +0xaf,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4,0x7a,0xb3,0x3, 0xfa,0x22,0x12,0x4a,0x7e, +0x12,0x4f,0xde,0x75,0xcd,0x0, 0xa9,0xd6,0xeb,0xa9,0xd7,0xcd,0xc2,0xce,0x12,0x5f, +0xe1,0x12,0x4b,0xd6,0x74,0x1, 0x12,0x4a,0xb6,0xa9,0xc6,0xeb,0xa9,0xc7,0xcd,0xd2, +0xce,0xe5,0x25,0x7e,0x71,0x24,0x2, 0x4b,0x29,0x7c,0x6b,0xa9,0xd5,0xcb,0x74,0xf, +0x12,0x7, 0xfa,0x7a,0x61,0xfc,0x12,0x2e,0xed,0x12,0x4c,0x5, 0xd2,0x0, 0x12,0x4f, +0xf0,0x12,0x4b,0x4a,0x12,0x12,0xac,0x2, 0x12,0x64,0xd2,0x2, 0x12,0x4a,0x45,0x74, +0x1, 0x22,0xd2,0x0, 0x80,0x12,0x30,0x0, 0xc, 0x12,0x4b,0xce,0x68,0x7, 0xc2,0x0, +0xc2,0x1, 0x12,0x4a,0x34,0x12,0x4a,0x85,0x30,0x19,0xeb,0x22,0x7c,0xab,0x80,0xe, +0x7e,0x70,0x3, 0x80,0x1, 0x0, 0x7c,0x67,0x1b,0x70,0xa5,0xbe,0x0, 0xf7,0x7c,0x6a, +0x1b,0xa0,0xa5,0xbe,0x0, 0xea,0x22,0x74,0x1, 0x12,0x4b,0xa6,0x20,0x19,0x6, 0x12, +0x4b,0x52,0x12,0x4b,0xaf,0x7e,0xb3,0x34,0x3a,0xb4,0x1, 0x6, 0x12,0x4b,0xb4,0x12, +0x4b,0xaf,0xe4,0x2, 0x4b,0xa6,0xbe,0xb0,0x8, 0x50,0x3, 0x12,0xc0,0xf, 0x22,0xd2, +0x1, 0x2, 0x4a,0x34,0x74,0xc8,0x7a,0xb3,0x3, 0xfe,0xc2,0x19,0x80,0xa, 0x12,0x4a, +0x85,0x30,0x19,0x4, 0x75,0xe9,0xff,0x22,0x12,0x4b,0xce,0x68,0xf1,0x22,0x7e,0xb3, +0x34,0x3a,0xbe,0xb0,0x1, 0x22,0x12,0x4f,0xd7,0xc2,0x0, 0x12,0x4f,0xe7,0xc2,0x2, +0x12,0x4a,0x45,0xc2,0x0, 0x12,0x4f,0xf0,0xa9,0xd5,0xcb,0x74,0xf, 0x12,0x0, 0x66, +0x7a,0x1b,0xb0,0x74,0xf, 0x6c,0x77,0x12,0x7, 0xfa,0xe5,0xfc,0x7a,0xb, 0xb0,0x43, +0xfc,0x10,0x2, 0x2e,0xed,0xca,0xf8,0xa2,0xaf,0xe4,0x33,0x7c,0xfb,0xd2,0x0, 0x12, +0x4f,0xe7,0xa9,0xd0,0xcb,0xc2,0xaf,0xa9,0xd0,0x9e,0x75,0x9d,0x0, 0xa9,0xd0,0x9e, +0x75,0x9c,0x20,0xa9,0xd0,0x9e,0xa9,0xd4,0x9e,0xa9,0xd0,0xcd,0x74,0x41,0x12,0x4b, +0x6c,0xa9,0xd0,0x9e,0xa9,0xd7,0x9e,0x2e,0xf0,0xff,0x92,0xaf,0xda,0xf8,0x22,0xca, +0x3b,0x7e,0x8, 0x1f,0x34,0x12,0x77,0xbf,0x7e,0x1f,0x3b,0x5, 0x7a,0x1d,0x26,0x90, +0x61,0x27,0x93,0xf5,0x2d,0x7e,0xb3,0x3a,0x92,0xb4,0x1, 0x6, 0x7e,0x38,0x3a,0x94, +0x80,0x4, 0x7e,0x38,0x5, 0xf8,0x6d,0x33,0x7a,0x35,0x2a,0x74,0x2, 0x12,0x0, 0x1e, +0x7e,0xb3,0x3a,0x93,0x70,0xe, 0x7e,0xb3,0x3a,0x91,0x70,0x8, 0x74,0x1, 0x7a,0xb3, +0x3a,0x93,0xa1,0x13,0x7e,0xb3,0x3a,0x93,0x70,0x6, 0x74,0x1, 0x7a,0xb3,0x3a,0x93, +0x7e,0xb3,0x3a,0x92,0xb4,0x1, 0x17,0x75,0x2c,0x0, 0x80,0x9, 0x12,0x4d,0x40,0x12, +0x4d,0x4e,0x12,0x4d,0x5e,0xe5,0x2d,0xbe,0xb1,0x2c,0x38,0xf0,0x80,0x1b,0x75,0x2c, +0x0, 0x80,0xf, 0x12,0x4d,0x40,0x12,0x4d,0x4e,0x3e,0x24,0x3e,0x24,0x1e,0x24,0x12, +0x4d,0x5e,0xe5,0x2d,0xbe,0xb1,0x2c,0x38,0xea,0x7e,0x34,0x61,0x59,0x12,0x1e,0x81, +0x7a,0x35,0x2e,0x7e,0x18,0x1f,0x34,0x7f,0x1, 0x12,0xa1,0xf4,0x75,0x2c,0x0, 0x80, +0x16,0x12,0x4d,0x40,0x12,0x4d,0x47,0xbe,0x35,0x2a,0x8, 0x9, 0x12,0x4d,0x40,0x12, +0x4d,0x47,0x7a,0x35,0x2a,0x5, 0x2c,0xe5,0x2d,0xbe,0xb1,0x2c,0x38,0xe3,0x12,0x4d, +0x56,0x40,0x25,0x7e,0xb3,0x3a,0x92,0xb4,0x1, 0x1e,0x5, 0x1d,0xe5,0x1d,0xbe,0xb0, +0xa, 0x40,0x15,0x75,0x1d,0x0, 0xe5,0x2d,0xa, 0x3b,0x3e,0x34,0xca,0x39,0x7e,0x1d, +0x26,0x7f,0x3, 0x12,0x1b,0x93,0x1b,0xfd,0x74,0x2, 0x12,0x0, 0x1e,0x12,0x4d,0x56, +0x50,0xb, 0x74,0x2, 0x7a,0xb3,0x3b,0x4, 0xe4,0x7a,0xb3,0x3a,0x93,0xda,0x3b,0x22, +0x7e,0xa1,0x2c,0x74,0x2, 0xa4,0x22,0x49,0x35,0x1f,0x34,0x2, 0x1b,0xfa,0x7f,0x13, +0x2d,0x35,0xb, 0x1a,0x20,0x22,0x7e,0x37,0x2b,0x3, 0xbe,0x35,0x2a,0x22,0x7e,0xd, +0x26,0x2d,0x15,0xb, 0xa, 0x30,0x9d,0x32,0x59,0x35,0x1f,0x34,0x5, 0x2c,0x22,0xca, +0xf8,0x7e,0xa3,0x2a,0x2, 0x7e,0xb3,0x2a,0x3, 0xbe,0xa0,0x1, 0x38,0x21,0xbe,0xb0, +0x1, 0x38,0x1c,0x7e,0x47,0x28,0x86,0xbe,0x44,0x0, 0x1e,0x28,0x2, 0x80,0x10,0x7e, +0xf3,0x2f,0x7c,0x4c,0xff,0x68,0x17,0x7e,0x47,0x2b,0xb3,0x4d,0x44,0x78,0xf, 0x12, +0x48,0x47,0x74,0x1, 0x7a,0xb3,0x3a,0x91,0x7a,0xb3,0x38,0xd4,0x80,0x35,0x4c,0xaa, +0x78,0x36,0xb4,0x1, 0x33,0x7e,0x37,0x2b,0xb3,0x7a,0x37,0x2f,0x7e,0x7e,0xb3,0x2f, +0x7c,0xb4,0x3, 0x1f,0x7e,0x37,0x2b,0xb3,0xbe,0x34,0x0, 0x0, 0x28,0x15,0x74,0x4, +0x7a,0xb3,0x2f,0x7c,0x7e,0x37,0x2f,0x94,0x7e,0x27,0x2f,0x96,0x12,0x4e,0x80,0xc1, +0x79,0x80,0x0, 0x12,0xbe,0x6, 0xc1,0x79,0x7e,0xc7,0x29,0x8, 0x7e,0xd7,0x29,0xa, +0x4c,0xff,0x78,0x19,0x70,0x57,0xbe,0xa0,0x1, 0x78,0x52,0x7d,0x3c,0x7d,0x2d,0x12, +0xbd,0xa1,0x12,0x4e,0x7c,0x74,0x1, 0x7a,0xb3,0x2f,0x7c,0x80,0x40,0xbe,0xf0,0x1, +0x78,0x2e,0x7e,0x27,0x2f,0x84,0x9e,0x27,0x2f,0x8c,0x7e,0x14,0x62,0x8a,0x12,0x4f, +0x39,0xbd,0x23,0x38,0x13,0x7e,0x27,0x2f,0x92,0x9e,0x27,0x2f,0x8a,0x7e,0x14,0x62, +0x8c,0x12,0x4f,0x39,0xbd,0x23,0x28,0x15,0x74,0x3, 0x7a,0xb3,0x2f,0x7c,0x80,0x5, +0xbe,0xf0,0x3, 0x78,0x8, 0x7a,0xc7,0x2f,0x94,0x7a,0xd7,0x2f,0x96,0x7e,0xb3,0x2f, +0x7c,0x60,0x26,0x7d,0x3c,0x7d,0x2d,0x7e,0x17,0x2b,0xb7,0x7e,0x7, 0x2b,0xb9,0x12, +0xbd,0x89,0xa, 0x2b,0x7e,0x73,0x2f,0x7b,0xa, 0x37,0xbd,0x32,0x58,0xb, 0x12,0x4e, +0x7c,0x7a,0xc7,0x2b,0xb7,0x7a,0xd7,0x2b,0xb9,0xda,0xf8,0x22,0x7d,0x3c,0x7d,0x2d, +0x7d,0x42,0x7d,0x13,0x7d,0x24,0x12,0xbd,0x68,0x7d,0x31,0x12,0xbc,0xfc,0x2, 0x4e, +0x91,0x7e,0x3, 0x2f,0xa4,0xbe,0x0, 0xf0,0x50,0x2, 0xe1,0x2a,0xe1,0x1f,0x6c,0x99, +0x7e,0xb3,0x2f,0x7b,0xbe,0xb0,0x20,0x50,0x5, 0x4, 0x7a,0xb3,0x2f,0x7b,0x7e,0x1f, +0x2b,0xbb,0x7a,0x1f,0x1f,0x34,0x7e,0x80,0x1, 0x80,0x49,0x74,0x4, 0xac,0xb8,0x49, +0x35,0x2b,0xbb,0x49,0x25,0x2b,0xbd,0x7e,0x17,0x1f,0x34,0x7e,0x7, 0x1f,0x36,0x12, +0xbd,0x89,0x7c,0x1b,0x7e,0x3, 0x2f,0x7b,0xbc,0x1, 0x38,0x26,0xb, 0x90,0x7e,0x70, +0x4, 0xac,0x78,0x2e,0x34,0x2b,0xbb,0x7e,0x14,0x1f,0x34,0x74,0x4, 0x12,0x19,0x7f, +0x7e,0x34,0x1f,0x34,0x7e,0x30,0x4, 0xac,0x39,0x2e,0x14,0x2b,0xbb,0x74,0x4, 0x12, +0x19,0x7f,0xb, 0x80,0x7e,0x3, 0x2f,0xa4,0xbc,0x8, 0x38,0xaf,0xa, 0x59,0xb, 0x54, +0x7c,0xb, 0x7a,0x3, 0x2f,0xa4,0x7e,0x3, 0x2f,0x7b,0xbe,0x0, 0x20,0x50,0xb, 0x7e, +0x3, 0x2f,0xa4,0xbe,0x0, 0xec,0x40,0x2, 0xc1,0x9e,0x22,0x7d,0x34,0x9e,0x34,0x0, +0x40,0x7d,0x2e,0x9d,0x23,0x7e,0x14,0x61,0x49,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x30, +0x22,0x7e,0x73,0x38,0x37,0x7a,0x73,0x38,0xad,0x7e,0x27,0x3a,0xe2,0x7e,0x14,0x61, +0xc8,0x12,0x4f,0x39,0x1e,0x34,0xbd,0x32,0x50,0x6, 0x74,0x1, 0x7a,0xb3,0x38,0x37, +0x7e,0x14,0x61,0xc8,0x12,0x4f,0x39,0xbd,0x32,0x50,0x8, 0xe4,0x7a,0xb3,0x38,0x35, +0x12,0xa6,0x7e,0x7e,0x37,0x38,0x3d,0xbd,0x32,0x50,0x4, 0x7a,0x27,0x38,0x3d,0x12, +0xa9,0x4a,0x38,0xa, 0x12,0xa9,0x42,0x38,0x5, 0x12,0xa9,0x3a,0x28,0x3d,0x12,0xa6, +0x27,0x7e,0x14,0x61,0xc8,0x12,0x4f,0x39,0x1e,0x34,0x1e,0x34,0xbd,0x32,0x28,0x21, +0x7e,0xb3,0x38,0x35,0x4, 0x7a,0xb3,0x38,0x35,0x7e,0x73,0x38,0x35,0xbe,0x70,0x32, +0x28,0x14,0x74,0x32,0x7a,0xb3,0x38,0x35,0x12,0xbf,0xdf,0x7a,0xb3,0x38,0xaa,0x80, +0x5, 0xe4,0x7a,0xb3,0x38,0x35,0x7d,0x32,0x2, 0xa6,0xba,0x2, 0x4f,0xce,0x12,0xa6, +0x85,0xe4,0x7a,0xb3,0x38,0x43,0x22,0xe4,0x12,0x12,0xac,0x2, 0x12,0x64,0x12,0x4b, +0xce,0x68,0xfb,0x20,0x93,0xfd,0x22,0xa9,0xd0,0xce,0xa2,0x0, 0xa9,0x95,0xc9,0x22, +0xa2,0x0, 0xa9,0x97,0xc1,0xa2,0x0, 0xa9,0x97,0xc2,0x22,0x7e,0x37,0x3a,0xe9,0xb, +0x34,0x7a,0x37,0x3a,0xe9,0x7e,0x37,0x3a,0xeb,0xbe,0x37,0x3a,0xe9,0x28,0x3, 0x2, +0x50,0x13,0x22,0xe5,0x9a,0x60,0x5, 0xd2,0x9c,0xa9,0xd6,0xdf,0x22,0x74,0x15,0x22, +0x2, 0x4f,0xfb,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca, +0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0x12,0x50,0x20,0xd0,0x82,0xd0,0x83,0xd0,0xd0, +0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0xe4, +0x12,0x52,0xe6,0x12,0xb5,0x8a,0x12,0x2b,0x13,0x12,0xb5,0xfa,0x12,0x53,0x17,0x12, +0xb4,0xca,0x12,0xb5,0x96,0x12,0x0, 0x42,0x12,0xb5,0xa2,0x12,0x52,0x43,0x12,0xb5, +0xb2,0xd2,0xaf,0x12,0xb5,0x1c,0x12,0x50,0x9d,0x12,0x52,0xb8,0x12,0x4c,0x5, 0x7e, +0x8, 0x3a,0xed,0x12,0x52,0x92,0x90,0x60,0x50,0xe4,0x93,0xca,0xb8,0x90,0x60,0x51, +0xe4,0x93,0x7c,0x7b,0x7e,0x24,0xff,0xff,0xda,0xb8,0x2, 0x11,0x34,0xd2,0xc8,0x43, +0xed,0xf, 0xc2,0xea,0x75,0xb3,0x13,0xa9,0xd1,0xb4,0xa9,0xc0,0xb4,0x12,0x52,0x33, +0xe4,0x12,0x50,0xc0,0x2, 0x50,0xb7,0xa9,0xc5,0xca,0xe4,0x7a,0xb3,0x3b,0x1e,0x22, +0xca,0xf8,0x7c,0xfb,0x74,0x2, 0x12,0x51,0x3e,0x4c,0xff,0x78,0x5, 0x5e,0x70,0xdf, +0x80,0x3, 0x4e,0x70,0x20,0x74,0x2, 0x12,0x50,0xe1,0xda,0xf8,0x22,0x74,0x6, 0x7d, +0x30,0x7d,0x23,0x7c,0x6b,0xa, 0x14,0x7c,0x73,0x7d,0x52,0x7c,0xab,0x7e,0xb3,0x3b, +0x1e,0xb4,0xa5,0x42,0x12,0x51,0xde,0x75,0xb5,0x1, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6, +0xb3,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x75,0xb5,0x0, 0xa9,0x36, +0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a, +0x71,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0xa1,0xb5,0xa9,0x36,0xb3,0xfc, +0xa9,0xc6,0xb3,0xa9,0xd2,0xb4,0x22,0x74,0x4, 0x7d,0x30,0x2, 0x50,0xe1,0x7c,0x6b, +0x6c,0x77,0x6c,0xaa,0x7e,0xb3,0x3b,0x1e,0xb4,0xa5,0x52,0x12,0x51,0xde,0x75,0xb5, +0x5, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9, +0xc6,0xb3,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9, +0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3, +0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0x71,0xb5,0x75,0xb5,0x0, +0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0xa1,0xb5,0xa9,0xd2,0xb4,0x7c,0x47,0x6c, +0x55,0xa, 0x3a,0x4d,0x32,0x22,0x7d,0x42,0x7f,0x60,0x7d,0x3, 0x12,0x52,0x33,0x74, +0x2, 0x12,0x51,0x3e,0x7d,0xf3,0x4e,0xf4,0x0, 0x1, 0x4e,0xf4,0x0, 0xa, 0x12,0x51, +0xd7,0x7a,0x45,0x36,0x7d,0x30,0x6d,0x22,0x7f,0x6, 0x12,0x51,0xef,0x5e,0xf4,0xff, +0xfd,0x12,0x51,0xd7,0x2, 0x50,0xb7,0x74,0x2, 0x7d,0x3f,0x2, 0x50,0xe1,0xa9,0xc2, +0xb4,0xa9,0xc6,0xb3,0x22,0x74,0x6, 0x12,0x51,0x3e,0x7d,0x3, 0x6c,0x11,0x22,0x12, +0x51,0xfd,0x7e,0x35,0x36,0x12,0xb6,0x1a,0xa9,0xd2,0xb4,0xd3,0x22,0x7d,0x52,0xf5, +0x3a,0x7c,0xb6,0x7c,0xa5,0xa, 0x44,0xf5,0x39,0x7f,0x21,0xf5,0x38,0xa9,0xc2,0xb4, +0x74,0xb, 0x12,0x52,0x28,0xe5,0x3a,0x12,0x52,0x28,0xe5,0x39,0x12,0x52,0x28,0xe5, +0x38,0x12,0x52,0x28,0xe4,0x2, 0x52,0x28,0xf5,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6, +0xb3,0xd3,0x22,0xa9,0xd5,0xca,0xa9,0xd1,0xea,0xa9,0xc1,0xea,0x74,0xa5,0x7a,0xb3, +0x3b,0x1e,0x22,0xe4,0x7a,0xb3,0x39,0x6a,0x7e,0x8, 0x33,0x1b,0x12,0xbf,0xfd,0x7e, +0x8, 0x33,0x59,0x7e,0x34,0x0, 0x3e,0x12,0x1b,0xb8,0x7e,0x18,0x33,0x1b,0x7a,0x1d, +0x13,0x12,0x52,0x74,0x2, 0x52,0x67,0x75,0x17,0x0, 0x75,0x19,0x0, 0x7e,0xb3,0x39, +0x6a,0xf5,0x91,0x22,0x2, 0x52,0x77,0x90,0x60,0x0, 0xe4,0x93,0x54,0xfe,0x75,0x91, +0x0, 0xc2,0x90,0xc2,0x91,0xc2,0xc9,0x54,0xfe,0xf5,0x92,0xd2,0xe8,0xc2,0xc0,0xd2, +0xad,0x22,0xd2,0xc9,0x75,0xf2,0x30,0x75,0xf3,0x80,0x75,0xf4,0xc, 0x75,0xf5,0x1, +0x6c,0xaa,0xe5,0xf5,0x54,0x80,0xb4,0x80,0xf9,0xe5,0xf6,0x12,0x77,0xe1,0xb, 0xa0, +0xbe,0xa0,0xd, 0x40,0xed,0xc2,0xc9,0x22,0x6d,0x33,0x7e,0x8, 0x0, 0x24,0x7e,0x24, +0x0, 0x12,0x12,0x51,0xa6,0xe5,0x34,0x20,0xe7,0x1b,0xa9,0xd5,0xcb,0x74,0x3, 0x7e, +0x71,0x27,0x12,0x7, 0xfa,0x74,0xb, 0x7e,0x71,0x2f,0x12,0x7, 0xfa,0x74,0xc, 0x7e, +0x71,0x30,0x12,0x2e,0xea,0x22,0xa9,0xc4,0xca,0xa9,0xc5,0xca,0xbe,0xb0,0x8, 0x50, +0x3, 0x12,0xc0,0xf, 0xa9,0xd0,0xce,0xa9,0xc0,0xc9,0xd2,0x2, 0x12,0x4a,0x45,0xa9, +0xc2,0xea,0x75,0xc1,0x6, 0x75,0xc2,0xc, 0xd2,0x0, 0x12,0x4f,0xf0,0xa9,0xc1,0xc4, +0xa9,0xd2,0xc4,0xa9,0xc2,0xe1,0x22,0xca,0x79,0xa9,0xd5,0xcb,0x74,0x2, 0x7e,0x70, +0x3f,0x12,0x7, 0xfa,0x74,0xf, 0x12,0x0, 0x66,0x7c,0xfb,0x74,0xf, 0x7c,0x7f,0x5e, +0x70,0xfe,0x12,0x7, 0xfa,0x74,0xc, 0x12,0x0, 0x66,0x7c,0xfb,0x54,0x7f,0x68,0x8, +0x74,0xc, 0x7e,0x70,0xf8,0x12,0x7, 0xfa,0x90,0x61,0x18,0xe4,0x93,0x7c,0xab,0xbe, +0xa0,0x7, 0x38,0xb, 0x12,0x53,0x9a,0x7c,0xb7,0xa, 0x7b,0xb, 0x75,0x80,0x16,0x90, +0x61,0x17,0xe4,0x93,0xb4,0x1, 0xe, 0xbe,0xa0,0x7, 0x28,0x9, 0x12,0x53,0x9a,0xa, +0x77,0x2e,0x74,0x0, 0x7, 0x74,0xe, 0x7c,0x7f,0x12,0x7, 0xfa,0x74,0x7, 0x12,0x0, +0x66,0x7c,0xfb,0x5e,0xf0,0xfb,0x90,0x60,0x2, 0x12,0x2f,0xf4,0x3e,0x34,0x4c,0xf7, +0x74,0x7, 0x7c,0x7f,0x12,0x2e,0xea,0xda,0x79,0x22,0xa, 0x3a,0x2e,0x34,0x0, 0x3, +0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x22,0x7e,0x34,0x38,0xaf,0x30,0xf, 0x4b, +0xc2,0xf, 0x9, 0x53,0x0, 0x2, 0x12,0x53,0xfc,0x7a,0x27,0x2a,0x4f,0x9, 0x53,0x0, +0x3, 0x12,0x53,0xfc,0x7a,0x27,0x2a,0x51,0x9, 0x53,0x0, 0x4, 0x12,0x53,0xfc,0x7a, +0x27,0x2a,0x53,0x7e,0x39,0x50,0xa, 0x25,0x3e,0x24,0x3e,0x24,0x7a,0x27,0x2a,0x5a, +0x9, 0x53,0x0, 0x1, 0xa, 0x25,0x3e,0x24,0x3e,0x24,0x7a,0x27,0x2a,0x5c,0x9, 0x73, +0x0, 0x5, 0xa, 0x37,0x12,0x53,0xa0,0x7a,0x37,0x2a,0x62,0x22,0xa, 0x25,0x3e,0x24, +0x3e,0x24,0x3e,0x24,0x3e,0x24,0x22,0x7c,0x67,0x7c,0x7b,0xa5,0xbf,0x0, 0x17,0xbe, +0x60,0x0, 0x28,0xf, 0x74,0x1, 0x7a,0xb3,0x2a,0x7, 0xe4,0x7a,0xb3,0x2a,0x9, 0x7a, +0xb3,0x2a,0xa, 0x2, 0x9a,0x71,0xa5,0xbe,0x0, 0x1d,0x6c,0xaa,0x80,0xe, 0x7e,0x60, +0xff,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x62,0x29,0x66,0xb, 0xa0,0x12,0x54,0x76,0x38, +0xed,0x74,0x1, 0x7a,0xb3,0x2a,0x6, 0x6c,0xaa,0x80,0x26,0x7e,0x30,0x9, 0xac,0x3a, +0x2e,0x14,0x28,0xae,0xb, 0x18,0x20,0x12,0x53,0xfe,0x1b,0x18,0x20,0x7e,0x30,0x9, +0xac,0x3a,0x2e,0x14,0x28,0xb0,0xb, 0x18,0x20,0x12,0x53,0xfe,0x1b,0x18,0x20,0xb, +0xa0,0xbc,0x7a,0x38,0xd6,0x22,0x90,0x60,0x99,0xe4,0x93,0xbc,0xba,0x22,0xca,0xf8, +0x7e,0x68,0x29,0xbc,0x6c,0xaa,0x80,0x19,0x7e,0x70,0xff,0x12,0x57,0x33,0xe4,0xa, +0x4a,0x19,0xb4,0x1f,0x34,0x74,0xff,0x19,0xb4,0x1f,0x46,0x19,0xb4,0x1f,0x50,0xb, +0xa0,0x12,0x54,0x76,0x38,0xe2,0x7e,0x73,0x2a,0x2, 0xa5,0xbf,0x0, 0x23,0x7e,0xb3, +0x3b,0x1b,0x70,0x2, 0xc1,0x8d,0x6c,0xaa,0x80,0x10,0x7e,0x44,0x7f,0xff,0x12,0x57, +0x3d,0x79,0x40,0x0, 0x14,0x12,0x57,0x20,0xb, 0xa0,0x12,0x54,0x76,0x38,0xeb,0xc1, +0x8d,0x7e,0xb3,0x3b,0x1b,0x70,0x3d,0xbe,0x70,0x0, 0x28,0x38,0x6c,0xaa,0x80,0x2a, +0x7e,0x90,0x9, 0xac,0x9a,0x49,0x34,0x28,0xae,0x12,0x57,0x3d,0x79,0x30,0x0, 0x14, +0x49,0x34,0x28,0xb0,0x7f,0x6, 0x2d,0x12,0x79,0x30,0x0, 0x28,0x74,0x1, 0xa, 0x3a, +0x19,0xb3,0x1f,0x34,0x19,0xa4,0x28,0xb2,0xb, 0xa0,0x7e,0xb3,0x2a,0x2, 0xbc,0xba, +0x38,0xce,0xc1,0x8d,0x6c,0xaa,0x80,0x17,0x12,0x57,0x29,0x3e,0x34,0x59,0x43,0x15, +0x4e,0x59,0x43,0x15,0x50,0x59,0x43,0x15,0x76,0x59,0x43,0x15,0x78,0xb, 0xa0,0x12, +0x54,0x76,0x38,0xe4,0x6c,0xaa,0x80,0x3d,0x6c,0xff,0x80,0x32,0x7e,0x70,0x2, 0xac, +0x7f,0x7f,0x6, 0x2d,0x13,0x69,0x30,0x0, 0x14,0xbe,0x34,0x7f,0xff,0x68,0x1d,0xa, +0x4f,0x9, 0xb4,0x1f,0x50,0xb4,0xff,0x14,0x12,0x57,0x18,0x59,0x32,0x15,0x4e,0x69, +0x30,0x0, 0x28,0x59,0x32,0x15,0x50,0x12,0x57,0x47,0x80,0x7, 0xb, 0xf0,0x12,0x57, +0x10,0x38,0xc9,0xb, 0xa0,0x7e,0xb3,0x3b,0x1b,0xbc,0xba,0x38,0xbb,0x6c,0xaa,0x80, +0x24,0xa, 0x3a,0x9, 0xb3,0x1f,0x46,0xb4,0xff,0x19,0x6c,0xff,0x80,0x10,0xa, 0x4f, +0x9, 0xb4,0x1f,0x50,0xb4,0xff,0x5, 0x12,0x57,0x47,0x80,0x7, 0xb, 0xf0,0x12,0x57, +0x10,0x38,0xeb,0xb, 0xa0,0x12,0x54,0x76,0x38,0xd7,0x6c,0xaa,0x80,0x1a,0x7e,0x70, +0x9, 0xac,0x7a,0x49,0x43,0x28,0xae,0x12,0x57,0x18,0x59,0x42,0x15,0x76,0x49,0x33, +0x28,0xb0,0x59,0x32,0x15,0x78,0xb, 0xa0,0x7e,0xb3,0x2a,0x2, 0xbc,0xba,0x38,0xde, +0x7e,0x34,0x15,0x4e,0x7a,0x37,0x1f,0x40,0x7e,0x34,0x15,0x76,0x7a,0x37,0x1f,0x42, +0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f,0x44,0x7e,0x73,0x3b,0x1b,0x7a,0x73,0x1f,0x3e, +0x7e,0x73,0x2a,0x2, 0x7a,0x73,0x1f,0x3f,0x7e,0x8, 0x1f,0x3e,0x12,0x3, 0x64,0x6c, +0xaa,0x80,0x59,0x7e,0x70,0xff,0x6c,0xff,0x80,0x19,0x7e,0x50,0x2, 0xac,0x5f,0x49, +0x12,0x15,0x9e,0xa, 0x2a,0xbd,0x21,0x78,0x8, 0xa, 0x3f,0x9, 0x73,0x1f,0x46,0x80, +0x7, 0xb, 0xf0,0x12,0x57,0x10,0x38,0xe2,0xbe,0x70,0xff,0x68,0x2d,0x12,0x57,0x33, +0x74,0x1, 0xa, 0x47,0x19,0xb4,0x1f,0x34,0x7e,0x90,0x9, 0xac,0x9a,0x49,0x24,0x28, +0xae,0x7e,0x30,0x2, 0xac,0x37,0x2d,0x1d,0x7d,0xc, 0x79,0x20,0x0, 0x14,0x49,0x44, +0x28,0xb0,0x7e,0x50,0x2, 0xac,0x57,0x12,0x57,0x20,0xb, 0xa0,0x7e,0x63,0x2a,0x2, +0xbc,0x6a,0x38,0x9f,0x6c,0xaa,0x80,0x20,0xa, 0x3a,0x9, 0xb3,0x1f,0x34,0xbe,0xb0, +0x1, 0x68,0x13,0x12,0x57,0x29,0x7f,0x6, 0x2d,0x13,0x79,0x40,0x0, 0x14,0x2d,0x3d, +0x7d,0x2c,0x79,0x41,0x0, 0x28,0xb, 0xa0,0x12,0x54,0x76,0x38,0xdb,0x7e,0xf3,0x2a, +0x2, 0x7a,0xf3,0x3b,0x1b,0x6c,0xaa,0x80,0x68,0xa, 0x3a,0x9, 0xb3,0x1f,0x34,0xb4, +0x1, 0x2c,0x12,0x57,0x9, 0x29,0xb1,0x0, 0xa, 0xb4,0x1, 0x6, 0x74,0x3, 0x39,0xb1, +0x0, 0xa, 0x12,0x57,0x9, 0x29,0x31,0x0, 0xa, 0xa5,0xbb,0x3, 0x6, 0xe4,0x7a,0x1b, +0xb0,0x80,0x32,0xa5,0xbb,0x0, 0x2e,0x74,0x2, 0x7a,0x1b,0xb0,0x80,0x27,0x12,0x57, +0x9, 0x29,0xb1,0x0, 0xa, 0xbe,0xb0,0x2, 0x68,0x2, 0x70,0x14,0x74,0x1, 0x7a,0x1b, +0xb0,0x7c,0x2f,0xb, 0xf0,0x7e,0x30,0x9, 0xac,0x23,0x19,0xa1,0x28,0xb2,0x80,0x5, +0x74,0x3, 0x7a,0x1b,0xb0,0x12,0x57,0x9, 0x7e,0x1b,0xb0,0x39,0xb1,0x0, 0xa, 0xb, +0xa0,0x12,0x54,0x76,0x38,0x93,0xda,0xf8,0x22,0xa, 0x3a,0x2d,0x3d,0x7d,0x2c,0x22, +0x90,0x60,0x99,0xe4,0x93,0xbc,0xbf,0x22,0x7e,0x50,0x2, 0xac,0x5a,0x3e,0x24,0x22, +0x7f,0x6, 0x2d,0x12,0x79,0x40,0x0, 0x28,0x22,0x7e,0x44,0x7f,0xff,0x7e,0x70,0x2, +0xac,0x7a,0x22,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x72,0x28,0xb2,0x22,0x7e,0x50,0x2, +0xac,0x5a,0x7f,0x6, 0x2d,0x12,0x22,0xa, 0x3a,0x19,0xf3,0x1f,0x46,0x74,0x1, 0x19, +0xb4,0x1f,0x50,0x22,0x7c,0xab,0x7e,0x8, 0x29,0xbc,0x12,0x54,0x76,0x28,0x1f,0xa, +0x3a,0x7f,0x70,0x2d,0xf3,0x7e,0x7b,0xb0,0xb4,0x2, 0x4, 0x74,0x1, 0x80,0x2, 0x74, +0x3, 0x7a,0x7b,0xb0,0x74,0x3, 0x2d,0x31,0x7d,0x20,0x39,0xb1,0x0, 0xa, 0x22,0xca, +0x79,0x7e,0xf3,0x2a,0x2, 0x7e,0xe3,0x2a,0x3, 0x7c,0xbf,0x7c,0x7e,0x12,0x54,0x7, +0x7c,0xbf,0x12,0x8d,0xe9,0x4c,0xee,0x78,0x17,0x12,0x8c,0x6c,0xca,0x59,0x7e,0x18, +0x28,0xae,0x7e,0x8, 0x29,0x62,0x12,0x1b,0x93,0x1b,0xfd,0x12,0x97,0xa4,0x80,0xe, +0x7e,0xb3,0x2a,0x9, 0x70,0x8, 0x12,0x97,0xa4,0x7c,0xbf,0x12,0x97,0x13,0x7c,0xbf, +0x12,0x98,0xb6,0xbe,0xf0,0x0, 0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x2a,0xb, 0xda,0x79, +0x22,0x90,0x60,0x99,0xe4,0x93,0x7a,0xb3,0x2a,0x4d,0x90,0x60,0x9e,0xe4,0x93,0x7a, +0xb3,0x2a,0x4e,0x7e,0x34,0x61,0x55,0x12,0x1e,0x81,0x12,0xc0,0x6, 0x12,0x1e,0x81, +0x7a,0x37,0x2a,0x51,0x7e,0x14,0x61,0x59,0x12,0x5f,0x55,0x7a,0x27,0x2a,0x53,0x7a, +0x37,0x2a,0x55,0x90,0x60,0x9d,0xe4,0x93,0x7a,0xb3,0x2a,0x59,0x12,0x1e,0x5f,0x12, +0x58,0x4b,0x7e,0x34,0x62,0x12,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x60,0x90,0x60,0x9f, +0xe4,0x93,0x7a,0xb3,0x2a,0x64,0x90,0x60,0xa0,0xe4,0x93,0x7a,0xb3,0x2a,0x65,0x7e, +0x34,0x60,0xa1,0x12,0x1e,0x81,0x7a,0x37,0x2a,0x66,0x7e,0x34,0x61,0x5b,0x12,0x1e, +0x81,0x7a,0x37,0x2a,0x62,0xe4,0x7a,0xb3,0x16,0x92,0x22,0x6e,0x34,0xff,0xff,0xb, +0x34,0x7a,0x37,0x2a,0x5e,0x22,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x7e,0x34,0x61,0x2d, +0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x6c,0x12,0x1b,0x93,0x1b,0xfd,0x7e,0x34,0x2a, +0xe, 0x7a,0x37,0x2b,0x72,0xe4,0x7a,0xb3,0x2b,0x70,0x7a,0xb3,0x2b,0x71,0x7e,0x34, +0x0, 0x4, 0xca,0x39,0x12,0x5f,0xea,0x7e,0x8, 0x25,0xee,0x12,0x1b,0x93,0x1b,0xfd, +0x7e,0x34,0x2b,0x74,0x7a,0x37,0x25,0xf4,0xe4,0x7a,0xb3,0x25,0xf2,0x74,0x1, 0x7a, +0xb3,0x25,0xf3,0x22,0xca,0xd8,0xca,0x79,0x90,0x60,0x50,0xe4,0x93,0x7c,0xdb,0x90, +0x60,0x51,0xe4,0x93,0x7c,0xeb,0x90,0x61,0x27,0xe4,0x93,0xbc,0xbe,0x28,0x4, 0x7c, +0xfb,0x80,0x2, 0x7c,0xfe,0x7a,0xd3,0x2a,0x6d,0x7a,0xe3,0x2a,0x6e,0x90,0x60,0xa8, +0xe4,0x93,0x7c,0xab,0x7a,0xa3,0x2a,0x73,0x90,0x60,0xa9,0xe4,0x93,0xa, 0x2b,0xa, +0x3d,0x9d,0x32,0x7c,0xb7,0x7a,0xb3,0x2a,0x6f,0xa, 0x2a,0xa, 0x3e,0x9d,0x32,0x7a, +0x73,0x2a,0x70,0x90,0x60,0x91,0xe4,0x93,0x7a,0xb3,0x2a,0x74,0x90,0x60,0x94,0xe4, +0x93,0x7a,0xb3,0x2a,0x75,0xa, 0x3d,0xca,0x39,0x7e,0x34,0x60,0x52,0x7e,0x24,0x0, +0xff,0x7e,0x8, 0x2a,0x76,0x12,0x1b,0x93,0x1b,0xfd,0xa, 0x3f,0xca,0x39,0x7e,0x34, +0x60,0x75,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2a,0x99,0x12,0x1b,0x93,0x1b,0xfd,0x7e, +0x34,0x0, 0x23,0xca,0x39,0x7e,0x34,0x60,0xd8,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b, +0x1d,0x12,0x1b,0x93,0x1b,0xfd,0x12,0x5a,0x7c,0x12,0x5a,0xe6,0x90,0x60,0xaa,0xe4, +0x93,0x70,0x8, 0x7a,0xd3,0x2a,0x71,0x7a,0xe3,0x2a,0x72,0x12,0x58,0x56,0x74,0x1, +0x12,0x25,0x31,0xe4,0x7a,0xb3,0x2a,0xfd,0x7a,0xb3,0x2a,0xfe,0x12,0x5b,0x24,0x7a, +0x37,0x2b,0x9, 0x74,0x3, 0x7a,0xb3,0x2a,0xff,0xe4,0x7a,0xb3,0x2b,0x0, 0x74,0x2, +0x7a,0xb3,0x2b,0x1, 0x7e,0x34,0x61,0x59,0x12,0x1e,0x81,0x7a,0x37,0x2b,0x3, 0x74, +0x4, 0x7a,0xb3,0x2b,0x2, 0x7e,0x34,0x0, 0xf, 0x7a,0x37,0x2b,0x5, 0x7e,0x34,0x20, +0x5f,0x7a,0x37,0x2b,0x7, 0x90,0x61,0x1a,0xe4,0x93,0x7a,0xb3,0x2b,0x5e,0x90,0x61, +0x1b,0xe4,0x93,0x7a,0xb3,0x2b,0xc, 0x90,0x61,0x1c,0xe4,0x93,0x7a,0xb3,0x2b,0xd, +0x74,0x4, 0x7a,0xb3,0x2b,0xf, 0x90,0x60,0xd5,0xe4,0x93,0x12,0x34,0xd0,0xe4,0x7a, +0xb3,0x2b,0x19,0x7a,0xb3,0x2b,0x1a,0x7e,0x34,0x61,0x22,0x12,0x1e,0x81,0x7a,0x37, +0x2b,0x15,0x90,0x60,0xd3,0x93,0x7a,0xb3,0x2b,0xe, 0x90,0x61,0x24,0xe4,0x93,0x7a, +0xb3,0x2b,0x1c,0x90,0x61,0x19,0xe4,0x93,0x7a,0xb3,0x2b,0x1b,0x7e,0x34,0x61,0x1e, +0x12,0x1e,0x81,0x7a,0x37,0x2b,0x11,0x7e,0x34,0x61,0x20,0x12,0x1e,0x81,0x7a,0x37, +0x2b,0x13,0x90,0x61,0x1d,0xe4,0x93,0x7a,0xb3,0x2b,0x10,0x7e,0x34,0x0, 0x30,0x7a, +0x37,0x2b,0x66,0x74,0x5, 0x7a,0xb3,0x2b,0x63,0x7e,0x34,0x0, 0x5, 0x7a,0x37,0x2b, +0x64,0xe4,0x7a,0xb3,0x2b,0x62,0x7e,0x34,0x4, 0x6d,0x7a,0x37,0x2b,0x68,0x74,0x1, +0x7a,0xb3,0x2b,0x5f,0x74,0x6, 0x7a,0xb3,0x2b,0x60,0xe4,0x7a,0xb3,0x2b,0x61,0x74, +0x1, 0x7a,0xb3,0x2b,0x5c,0xe4,0x7a,0xb3,0x2b,0x5d,0x7e,0x34,0x1b,0x35,0x7a,0x37, +0x2b,0x6a,0xa, 0x3e,0xca,0x39,0x7e,0x34,0x60,0xfb,0x7e,0x24,0x0, 0xff,0x7e,0x8, +0x2b,0x40,0x12,0x1b,0x93,0x1b,0xfd,0xda,0x79,0xda,0xd8,0x22,0x12,0x5f,0xe1,0x12, +0x5a,0xb2,0x12,0x5a,0xa0,0x2e,0x14,0x2a,0x76,0x12,0x5a,0xa8,0xe5,0x25,0x12,0x1b, +0xb8,0x12,0x5a,0xa0,0x2e,0x14,0x2b,0x1d,0x12,0x5a,0xa8,0xe5,0x24,0x2, 0x1b,0xb8, +0x90,0x60,0x50,0xe4,0x93,0xa, 0x1b,0x22,0x6d,0x0, 0x90,0x60,0x91,0xe4,0x93,0xa, +0x3b,0x22,0x6c,0xaa,0x6c,0x99,0x80,0xc, 0xa, 0xf9,0x9, 0xbf,0x2a,0x76,0xbc,0xba, +0x68,0x7, 0xb, 0x90,0x12,0x5a,0xde,0x38,0xef,0x12,0x5a,0xde,0x68,0x7, 0xb, 0xa0, +0xbe,0xa0,0x23,0x40,0xdf,0x7a,0xb, 0xa0,0x74,0x6e,0x7a,0x1b,0xb0,0x22,0x90,0x60, +0x50,0xe4,0x93,0xbc,0xb9,0x22,0xca,0xf8,0x90,0x60,0x50,0xe4,0x93,0x7c,0xab,0x12, +0x5f,0xc9,0x90,0x61,0x27,0xe4,0x93,0xbc,0xbf,0x28,0x2, 0x7c,0xfb,0x75,0x25,0x15, +0x7e,0x8, 0x2a,0xb5,0x7e,0x18,0x2a,0x76,0x7e,0xb3,0x2a,0x74,0x2c,0xba,0x12,0xc, +0x7e,0x75,0x25,0x15,0x7e,0x8, 0x2a,0xd8,0x7e,0x18,0x2a,0x99,0x7c,0xbf,0x12,0xe, +0x41,0xda,0xf8,0x22,0x6d,0x33,0x6c,0xaa,0x80,0x17,0xa, 0x2a,0x9, 0x52,0x2a,0xd8, +0x5e,0x50,0x1, 0xa5,0xbd,0x0, 0x5, 0x4e,0x70,0x1, 0x80,0x3, 0x4e,0x70,0x10,0xb, +0xa0,0x12,0x5b,0x73,0x38,0xe4,0x6c,0xaa,0x80,0x1f,0xa, 0x2a,0x9, 0xb2,0x2a,0xb5, +0xbe,0xb0,0xd, 0x38,0x5, 0x4e,0x70,0xc0,0x80,0xd, 0xbe,0xb0,0x1b,0x38,0x5, 0x4e, +0x60,0x8, 0x80,0x3, 0x4e,0x60,0x50,0xb, 0xa0,0x90,0x61,0x26,0xe4,0x93,0xbc,0xba, +0x38,0xd8,0x22,0x90,0x61,0x27,0xe4,0x93,0xbc,0xba,0x22,0x6d,0x11,0xe4,0x12,0x0, +0x1e,0x6c,0xaa,0x80,0x5b,0x7e,0x10,0x2, 0xac,0x1a,0x7e,0x7f,0x3b,0x5, 0x2d,0xf0, +0x69,0x27,0x1, 0x0, 0x69,0x37,0x0, 0x80,0x9d,0x32,0x12,0x1b,0xfa,0xbd,0x31,0x28, +0x16,0x7e,0x70,0x2, 0xac,0x7a,0x7e,0xf, 0x3b,0x5, 0x2d,0x13,0x69,0x20,0x1, 0x0, +0x69,0x30,0x0, 0x80,0x12,0x5c,0x8, 0x7e,0x10,0x2, 0xac,0x1a,0x7e,0x1f,0x3b,0x5, +0x2d,0x30,0x69,0x1, 0x0, 0x80,0xbe,0x4, 0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff, +0x69,0x1, 0x1, 0x0, 0xbe,0x4, 0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0xb, 0xa0, +0x12,0x5b,0x73,0x38,0xa0,0x7d,0x31,0x22,0x12,0x5b,0x7b,0x7e,0x14,0x62,0x7, 0x12, +0x5f,0x55,0xbd,0x32,0x28,0x3, 0xd2,0x15,0x22,0xc2,0x15,0x22,0x49,0x25,0x29,0x64, +0x74,0x9, 0xac,0xbe,0x49,0x35,0x28,0xb0,0x9d,0x32,0x12,0x1b,0xfa,0x7d,0x13,0x22, +0x7d,0x41,0x7d,0x2, 0x7c,0x37,0x7c,0x2b,0x74,0x4, 0xac,0xb2,0x49,0x35,0x2b,0xbb, +0x49,0xf5,0x2b,0xbd,0x74,0x4, 0xac,0xb3,0x49,0x25,0x2b,0xbb,0x49,0x55,0x2b,0xbd, +0x12,0x5c,0x8, 0x7d,0x3f,0x9d,0x35,0x12,0x1b,0xfa,0x9d,0x34,0x12,0x1b,0xfa,0x7e, +0x54,0x62,0x6a,0x7e,0x44,0x0, 0xff,0xb, 0x2a,0x20,0xbd,0x32,0x50,0x11,0x12,0x5f, +0xaa,0x7e,0x14,0x62,0x6a,0x12,0x5f,0x55,0xbd,0x32,0x50,0x3, 0x74,0x1, 0x22,0xe4, +0x22,0xca,0xf8,0x6c,0xff,0x7e,0xb7,0x2f,0x98,0x7e,0xc7,0x2f,0x9a,0x7e,0x97,0x2f, +0x80,0x7e,0xd7,0x2f,0x82,0x7e,0xa7,0x2f,0x94,0x7e,0xe7,0x2f,0x96,0xe4,0x7e,0x73, +0x2f,0xa4,0x1b,0x70,0x7d,0x2b,0x7d,0x1c,0x12,0x5c,0x10,0x70,0x2, 0xa1,0x98,0x7e, +0x73,0x2f,0xa4,0xbe,0x70,0xa, 0x28,0x13,0xe4,0x7e,0x70,0x9, 0x7e,0x27,0x2f,0x9c, +0x7e,0x17,0x2f,0x9e,0x12,0x5c,0x10,0x70,0x2, 0xa1,0x98,0x7e,0x73,0x2f,0xa4,0xbe, +0x70,0x14,0x28,0x13,0xe4,0x7e,0x70,0x13,0x7e,0x27,0x2f,0xa0,0x7e,0x17,0x2f,0xa2, +0x12,0x5c,0x10,0x70,0x2, 0xa1,0x98,0x7e,0x34,0x62,0x72,0x12,0x5d,0x9d,0xbd,0xfc, +0x28,0x4c,0x7e,0x34,0x62,0x70,0x12,0x5d,0x9d,0xbd,0xfb,0x50,0x41,0x7e,0xb3,0x2f, +0x7d,0x70,0x3b,0x7e,0x34,0x62,0x76,0x12,0x1e,0x81,0x12,0x5d,0xa5,0x7d,0x8f,0x9d, +0x83,0xbe,0x87,0x2f,0x7e,0x50,0x27,0x7e,0x34,0x62,0x74,0x12,0x5f,0xb9,0x9d,0xf8, +0xbe,0xf7,0x2f,0x7e,0x28,0x18,0x7d,0xfc,0x3e,0xf4,0xbd,0xfb,0x40,0x2, 0xa1,0x98, +0xbd,0xa9,0x50,0x5, 0x7e,0xf0,0x20,0x80,0x7f,0x7e,0xf0,0x21,0x80,0x7a,0x7e,0x34, +0x62,0x7a,0x12,0x5d,0x9d,0xbd,0xfb,0x28,0x6f,0x7e,0x34,0x62,0x78,0x12,0x5d,0x9d, +0xbd,0xfc,0x50,0x64,0x7e,0xb3,0x2f,0x7d,0x70,0x5e,0x7e,0x34,0x62,0x7e,0x12,0x1e, +0x81,0x12,0x5d,0xa5,0x7d,0xaf,0x9d,0xa3,0xbe,0xa7,0x2f,0x7e,0x50,0x4a,0x7e,0x34, +0x62,0x7c,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0xa0,0x9d,0xfa,0xbe,0xf7,0x2f,0x7e,0x28, +0x37,0x7d,0xfb,0x3e,0xf4,0xbd,0xfc,0x50,0x2f,0xbd,0xed,0x50,0x5, 0x7e,0xf0,0x22, +0x80,0x26,0x12,0x5f,0xc1,0x49,0x35,0x2b,0xb7,0x49,0x15,0x2b,0xb9,0x49,0x25,0x2b, +0xa7,0x49,0x5, 0x2b,0xa9,0x9d,0x10,0xbe,0x14,0x0, 0x20,0x18,0x8, 0x9d,0x32,0xbe, +0x34,0x0, 0x10,0x58,0x3, 0x7e,0xf0,0x23,0x7c,0xbf,0xda,0xf8,0x22,0x7e,0x24,0x0, +0xff,0xb, 0x1a,0xf0,0x22,0x7e,0x14,0x62,0x8e,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0xf0, +0x22,0xca,0xd8,0xca,0x79,0x7c,0xd4,0x7c,0xe5,0x7c,0xfb,0x7c,0xbd,0x12,0x98,0x39, +0x7d,0xf3,0x7c,0xbe,0x7c,0x7d,0x12,0x9b,0x9a,0x7d,0x3, 0x74,0x9, 0xac,0xbf,0x12, +0x97,0x97,0x12,0x5c,0x8, 0x12,0x5e,0x47,0x7d,0x13,0x5d,0x10,0x7e,0x70,0x9, 0xac, +0x7f,0x49,0xe3,0x29,0x62,0x74,0x9, 0xac,0xbe,0x49,0x25,0x28,0xae,0xbd,0x2e,0x28, +0xf, 0x7d,0x53,0x2e,0x54,0x29,0x62,0x7d,0x2e,0x2d,0x21,0x1b,0x58,0x20,0x80,0x9, +0x2e,0x34,0x29,0x62,0x9d,0xe1,0x1b,0x38,0xe0,0x74,0x9, 0xac,0xbf,0x12,0x5b,0xfc, +0x12,0x5e,0x47,0x7d,0x13,0x5d,0x10,0x7e,0x50,0x9, 0xac,0x5f,0x49,0x32,0x29,0x64, +0x74,0x9, 0xac,0xbe,0x49,0x5, 0x28,0xb0,0xbd,0x3, 0x28,0xd, 0x7d,0x2, 0x2e,0x4, +0x29,0x64,0x2d,0x13,0x1b,0x8, 0x10,0x80,0x9, 0x2e,0x24,0x29,0x64,0x9d,0x31,0x1b, +0x28,0x30,0xda,0x79,0xda,0xd8,0x22,0x7d,0x3f,0xad,0x31,0x7c,0x76,0x7c,0x65,0xa, +0x24,0x22,0x7d,0xc3,0x7e,0x34,0x61,0x37,0x12,0x5f,0xb1,0x90,0x61,0x35,0xe4,0x93, +0x70,0x3, 0x7d,0x3c,0x22,0x90,0x61,0x36,0xe4,0x93,0xb4,0x1, 0x6, 0x7e,0x83,0x2a, +0x70,0x80,0x4, 0x7e,0x83,0x2a,0x6f,0x12,0x5f,0xd9,0xbe,0xc4,0x0, 0x3f,0x38,0x21, +0x7e,0xe4,0x0, 0x3f,0x9d,0xec,0x7e,0x34,0x61,0x3b,0x12,0x5d,0x9d,0x12,0x5f,0x48, +0x7f,0x71,0x12,0x5f,0x37,0xbf,0x71,0x40,0x2, 0x7f,0x71,0x9f,0x17,0x7f,0x71,0xe1, +0x34,0x12,0x5f,0xa3,0xbd,0x5c,0x38,0x26,0x7d,0xec,0x9d,0xe5,0x7e,0x34,0x61,0x3d, +0x12,0x5d,0x9d,0x12,0x5f,0x48,0x7f,0x71,0x90,0x61,0x3a,0xe4,0x93,0xa, 0x3b,0xbf, +0x71,0x40,0x4, 0x7f,0x71,0x1b,0x7c,0x12,0x5f,0x3f,0x2f,0x71,0x80,0x66,0x7d,0xb4, +0xb, 0xb4,0x1e,0xb4,0x7d,0x5b,0x1b,0x54,0xbd,0x5c,0x40,0xc, 0x7d,0xf5,0x9d,0xfc, +0x6d,0xee,0x7e,0x34,0x61,0x3f,0x80,0xa, 0x7d,0xfc,0x9d,0xfb,0x6d,0xee,0x7e,0x34, +0x61,0x41,0x12,0x5f,0xd1,0x7f,0x17,0x12,0x18,0xef,0x7f,0x71,0x12,0x5e,0x4b,0x7f, +0x71,0xbd,0x5c,0x7d,0x3d,0x40,0xc, 0x1e,0x34,0x1b,0x34,0x6d,0x22,0x9f,0x17,0x7f, +0x71,0x80,0x6, 0x1e,0x34,0x6d,0x22,0x2f,0x71,0x12,0x5f,0x37,0x6d,0x22,0xbf,0x71, +0x50,0x4, 0x7f,0x71,0x80,0xe, 0x90,0x61,0x3a,0xe4,0x93,0x12,0x5f,0x3f,0xbf,0x71, +0x28,0x2, 0x7f,0x71,0x7d,0x3f,0x22,0x90,0x61,0x39,0xe4,0x93,0xa, 0x3b,0x22,0xa, +0x2b,0x7d,0x3d,0x9d,0x32,0x6d,0x22,0x22,0xad,0xfe,0x6d,0xee,0x7d,0x3f,0x7d,0x2e, +0x7c,0x76,0x7c,0x65,0x22,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x20,0x22,0x12,0x5f,0x97, +0x7a,0x37,0x2f,0x98,0x12,0x5f,0x8e,0x7a,0x37,0x2f,0x9a,0x12,0x5c,0x61,0x60,0x1, +0x22,0x7e,0x73,0x2f,0xa4,0xa, 0x37,0x7a,0x35,0x24,0x7e,0x8, 0x2b,0xbb,0x7e,0x18, +0x2f,0x7c,0x2, 0x62,0xa5,0x7e,0x8, 0x1f,0x34,0x7e,0x18,0x21,0x14,0x22,0x7e,0x37, +0x2f,0x92,0x9e,0x37,0x2f,0x8a,0x22,0x7e,0x37,0x2f,0x84,0x9e,0x37,0x2f,0x8c,0x22, +0x2, 0x5d,0xb1,0x7d,0x54,0x9e,0x54,0x0, 0x3f,0x22,0x7d,0x31,0x9d,0x30,0x2, 0x1b, +0xfa,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0xd0,0x22,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x80, +0x22,0x7e,0xa3,0x2f,0xa4,0x74,0x4, 0xa4,0x22,0x90,0x60,0x51,0xe4,0x93,0x7c,0xfb, +0x22,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x10,0x22,0x7e,0x90,0x40,0xac,0x89,0x1b,0x44, +0x22,0x7e,0x8, 0x0, 0x25,0x7e,0x18,0x0, 0x24,0x22,0x7e,0x34,0x61,0x29,0x7e,0x24, +0x0, 0xff,0x22,0x2d,0xdc,0xe, 0xd4,0x7d,0x6d,0x7c,0xbd,0xa, 0xd7,0x22,0xff,0xff, +0x70,0x8f,0x0, 0xff,0x51,0xae,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x46,0x54,0x53,0x35,0x58,0x34,0x36,0x50,0x30,0x30,0x31,0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x2, 0xfd,0x30,0x30,0x31,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0xe, 0x19,0x3, 0x2, 0x7, 0x6, 0x5, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0x4, 0x1, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x11,0x4, 0x10,0x3, 0xf, 0x2, 0xe, 0x1, 0xd, 0x0, 0xc, +0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x0, 0x0, +0x0, 0x5, 0x0, 0x3, 0xff,0x23,0x1c,0x2, 0xdf,0xa, 0x1e,0xa, 0x64,0x1e,0x10,0x0, +0x4, 0x0, 0x64,0xd, 0xac,0x0, 0xc8,0x3, 0x1, 0x0, 0x0, 0x18,0x2, 0x6, 0xb, 0x0, +0x0, 0x0, 0x96,0x0, 0xf0,0x1, 0xcc,0x2, 0x26,0x3, 0x48,0x3, 0xa2,0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8,0x1, 0xf4,0x3, 0x20,0x0, 0x0, 0x0, 0x0, 0x7, +0xf8,0x0, 0x14,0x1, 0x19,0x41,0x1, 0xf4,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x0, 0x4, 0x31,0x18,0x1, 0x20,0x1, 0x0, 0x0, +0x0, 0x0, 0x1, 0xf4,0x38,0x40,0xe, 0x19,0x27,0x10,0x25,0x6, 0x80,0x10,0x25,0x6, +0x78,0x8, 0x10,0x4, 0x20,0x1, 0x0, 0x4, 0x38,0x3d,0x3d,0x2, 0x1a,0x2, 0x2e,0x1, +0x39,0x1, 0x45,0x7, 0xe0,0x48,0x43,0x2, 0x22,0x1, 0xf3,0x1, 0x58,0x1, 0x58,0x0, +0xf0,0x0, 0xc8,0x0, 0xb4,0x1, 0x18,0x1, 0x18,0x1, 0x18,0xa, 0x0, 0x1, 0xa4,0x1, +0xf, 0xb, 0x1e,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22,0x15,0x0, 0x1, 0x54,0x1, 0x0, 0x2, +0x1, 0x51,0x1, 0x11,0x0, 0x0, 0x1, 0x1, 0xd, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96,0x2, 0x26,0x0, 0x50,0x0, 0x2b, +0x0, 0x4, 0x0, 0x4, 0x1, 0x4, 0x1, 0x90,0x0, 0xc8,0x0, 0x50,0x1, 0xf4,0x0, 0x96, +0x1, 0x2c,0x1, 0x2c,0x4, 0x41,0x1, 0x31,0x38,0x18,0x1a,0x2, 0x3a,0x3d,0x20,0x20, +0x2, 0x3c,0x3f,0x20,0x54,0x1, 0x31,0x38,0x30,0x41,0x1, 0x31,0x38,0x18,0x41,0x1, +0x31,0x38,0x18,0x41,0x1, 0x31,0x38,0x18,0x41,0x1, 0x31,0x38,0x18,0x4, 0x5, 0x25, +0x26,0x27,0x28,0x29,0x4, 0x0, 0xd2,0x2, 0x30,0x64,0x0, 0xc8,0x1, 0x5e,0x0, 0x64, +0x0, 0x64,0x0, 0x96,0x0, 0x64,0xb, 0xb8,0x8, 0x5, 0x6, 0x80,0x1, 0x90,0x1, 0x2c, +0x1, 0xc2,0x3, 0x20,0xf, 0xa0,0x1, 0x3, 0x20,0x4, 0xb0,0x3, 0x20,0x1, 0x2, 0x2, +0x4, 0x4, 0x6, 0x40,0x1, 0x2c,0x1, 0x18,0x1, 0x90,0x1, 0x90,0x1, 0x90,0x1, 0x90, +0x1, 0x2c,0x1, 0x90,0x1, 0x7c,0x1, 0x7c,0x0, 0x50,0x0, 0x46,0x0, 0x78,0x0, 0x78, +0x0, 0x78,0x1, 0x18,0x1, 0x18,0xa, 0x5, 0x0, 0x50,0x3, 0xe8,0x0, 0x50,0x7, 0x90, +0x0, 0x32,0x1, 0xf4,0x1, 0xf4,0x3, 0x20,0x0, 0xc8,0x0, 0x4d,0x0, 0x1e,0x0, 0x80, +0x1, 0xe, 0x0, 0xfc,0x0, 0x3c,0x3, 0xe8,0x1, 0xf8,0x0, 0x87,0x0, 0x3c,0x3, 0xe8, +0x0, 0x20,0x4, 0x18,0x0, 0x0, 0x7, 0xe0,0x0, 0x64,0x0, 0xa0,0x0, 0xa0,0x13,0x88, +0x1, 0x2c,0x0, 0xa0,0x0, 0xa0,0x10,0x0, 0xc, 0x0, 0xb, 0xc, 0x5, 0x6, 0x8, 0x9, +0x6, 0x6, 0xc, 0x64,0xc8,0xca,0xf8,0x7e,0x45,0x24,0x7c,0xb9,0x7a,0xb3,0x3a,0xd, +0x74,0xff,0x7a,0xb3,0x3a,0xc, 0x6d,0x55,0x80,0x19,0x7d,0xf5,0x3e,0xf4,0x12,0x66, +0x38,0x7d,0xe5,0x3e,0xe4,0x59,0xfe,0x1f,0x34,0x69,0xf6,0x0, 0x2, 0x59,0xfe,0x21, +0x14,0xb, 0x54,0xbd,0x45,0x38,0xe3,0x7e,0x33,0x3a,0xd, 0xbe,0x30,0x4, 0x38,0x2, +0x61,0x67,0x69,0xf1,0x0, 0x1c,0x69,0x11,0x0, 0x1e,0xbd,0x1f,0x18,0x19,0x4d,0x11, +0x78,0x4, 0x7e,0x14,0x0, 0x1, 0x7d,0x3f,0x7d,0x21,0x12,0x18,0xac,0x7c,0xf7,0x74, +0x40,0x7a,0xb3,0x3a,0x10,0x80,0x43,0x4d,0xff,0x78,0x4, 0x7e,0xf4,0x0, 0x1, 0x7d, +0x31,0x7d,0x2f,0x12,0x18,0xac,0x7c,0xf7,0x74,0x80,0x7a,0xb3,0x3a,0x10,0x7d,0xf, +0x2d,0xf, 0xbd,0x1, 0x8, 0x24,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x3a,0x10,0xa, 0x37, +0x6d,0x22,0x12,0x18,0xde,0x7d,0x5f,0x1a,0x4a,0x1a,0x48,0x7d,0x1f,0x1a,0x2, 0x1a, +0x0, 0x2f,0x2, 0x12,0x18,0xfa,0x7a,0x73,0x3a,0x10,0xbe,0xf0,0x5, 0x58,0x14,0x12, +0x5f,0x85,0x12,0xbe,0x19,0x12,0x5f,0x85,0x12,0x64,0xa6,0x12,0x5f,0x85,0x12,0xbf, +0x4, 0x80,0xa, 0x74,0x7d,0x80,0x2, 0x74,0x7f,0x7a,0xb3,0x3a,0xc, 0xe4,0x7a,0xb3, +0x3a,0xd, 0x7e,0x73,0x3b,0x13,0xbe,0x73,0x3a,0xc, 0x48,0x6, 0x7e,0xb3,0x3a,0xe, +0x80,0x1, 0xe4,0xda,0xf8,0x22,0xe4,0x7a,0xb3,0x39,0x6a,0x7a,0xb3,0x39,0x6b,0x90, +0x60,0x50,0x93,0x7a,0xb3,0x39,0x6c,0x90,0x60,0x51,0xe4,0x93,0x7a,0xb3,0x39,0x6d, +0xe4,0x7a,0xb3,0x39,0x6e,0x90,0x60,0x99,0x93,0x7a,0xb3,0x39,0x6f,0xe4,0x7a,0xb3, +0x39,0x70,0x7a,0xb3,0x39,0x71,0x90,0x61,0xc4,0x93,0x7a,0xb3,0x39,0x73,0x7e,0x34, +0x61,0x4f,0x12,0x1e,0x81,0x7a,0x73,0x39,0x77,0x7e,0x34,0x61,0x55,0x12,0x1e,0x81, +0x7a,0x73,0x39,0x78,0x74,0x64,0x7a,0xb3,0x39,0x89,0x90,0x61,0x18,0xe4,0x93,0x7a, +0xb3,0x39,0x8a,0x90,0x61,0x17,0xe4,0x93,0x7a,0xb3,0x39,0x76,0x90,0x61,0x19,0xe4, +0x93,0x7a,0xb3,0x39,0x8c,0x90,0x61,0x24,0xe4,0x93,0x7a,0xb3,0x39,0x8b,0x90,0x61, +0x1d,0xe4,0x93,0x7a,0xb3,0x39,0x8d,0x90,0x61,0x25,0xe4,0x93,0x7a,0xb3,0x39,0x88, +0xe4,0x7a,0xb3,0x39,0x83,0x74,0xc8,0x7a,0xb3,0x39,0x81,0x74,0x1e,0x7a,0xb3,0x39, +0x82,0x74,0x1, 0x7a,0xb3,0x39,0x80,0x74,0xf, 0x7a,0xb3,0x39,0x7f,0x74,0x1, 0x7a, +0xb3,0x39,0x84,0xe4,0x7a,0xb3,0x39,0x85,0x7a,0xb3,0x39,0x86,0x7e,0x8, 0x39,0x8e, +0x7e,0x34,0x0, 0x2c,0x12,0x1b,0xb8,0x7e,0x34,0x60,0xd6,0x12,0x1e,0x81,0xa, 0x36, +0x7a,0x73,0x39,0x99,0x7e,0x34,0x60,0xd6,0x12,0x1e,0x81,0x7a,0x73,0x39,0x9a,0x90, +0x60,0xd4,0x93,0x7a,0xb3,0x39,0x9b,0x90,0x60,0xd5,0xe4,0x93,0x7a,0xb3,0x39,0x9c, +0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,0x5f,0xea,0x7e,0x8, 0x39,0xaa,0x12,0x1b,0x93, +0x1b,0xfd,0x74,0x5, 0x7a,0xb3,0x39,0xb7,0x74,0x1, 0x7a,0xb3,0x39,0xae,0x7e,0x34, +0x0, 0x28,0xca,0x39,0x7e,0x34,0x61,0xd5,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x26,0x33, +0x12,0x1b,0x93,0x1b,0xfd,0x22,0xca,0x3b,0x7f,0x71,0x7e,0x60,0x1, 0xb, 0xa, 0x20, +0xb, 0x7a,0x50,0x7c,0x4b,0x7a,0x53,0x22,0xf4,0x7a,0x43,0x23,0xe4,0x7e,0x70,0x1, +0x7e,0xa0,0x1, 0xa1,0xc7,0x7e,0x90,0x2, 0xac,0x9a,0x7f,0x60,0x2d,0xd4,0xb, 0x6a, +0xd0,0x7d,0x7d,0x7c,0xbf,0xf5,0x26,0x7f,0x67,0x2d,0xd4,0xb, 0x6a,0x40,0xa, 0xd5, +0xa, 0xbb,0x7d,0xab,0x9d,0xad,0x7d,0x7a,0x7c,0x8f,0xbe,0x80,0x0, 0x58,0x5, 0x6e, +0x80,0xff,0xb, 0x80,0xa, 0xa4,0xa, 0x79,0x9d,0x7a,0xbe,0xf0,0x0, 0x58,0x5, 0x6e, +0xf0,0xff,0xb, 0xf0,0xbe,0x80,0x2, 0x58,0x7, 0xbe,0xf0,0x2, 0x58,0x2, 0xa1,0xc5, +0xbe,0x60,0x0, 0x18,0x2, 0xa1,0xad,0xbe,0x70,0xec,0x28,0x2, 0xa1,0xd1,0xbe,0x80, +0x8, 0x58,0x5, 0xbe,0xf0,0x8, 0x48,0x61,0xa, 0xa7,0xb, 0xa4,0x7d,0x6a,0x7c,0x7d, +0xa, 0xa5,0x2d,0xab,0x12,0x66,0x2d,0x19,0xba,0x22,0xf4,0xa, 0xd9,0xa, 0xa4,0x2d, +0xad,0x12,0x66,0x2d,0x19,0xba,0x23,0xe4,0x9, 0xba,0x22,0xf4,0xa, 0xdb,0xa, 0xc5, +0x2d,0xcd,0xe, 0xc4,0x7d,0x6c,0x7c,0xbd,0xa, 0xc7,0x19,0xbc,0x22,0xf3,0x9, 0xbc, +0x23,0xe4,0xa, 0xcb,0xa, 0xa4,0x2d,0xac,0x12,0x66,0x2d,0x19,0xba,0x23,0xe3,0x2d, +0xdb,0x12,0x5f,0xf5,0x19,0xbd,0x22,0xf5,0xa, 0xd9,0x12,0x5f,0xf3,0x19,0xbd,0x23, +0xe5,0xb, 0xd5,0x7d,0x6d,0x7c,0x7d,0x80,0x24,0xbe,0x80,0x4, 0x58,0x5, 0xbe,0xf0, +0x4, 0x48,0x1a,0xe5,0x26,0xa, 0xcb,0xa, 0xd5,0x12,0x5f,0xf3,0x19,0xbd,0x22,0xf4, +0xa, 0xc9,0xa, 0xd4,0x12,0x5f,0xf3,0x19,0xbd,0x23,0xe4,0xb, 0x70,0xbe,0x70,0xf0, +0x50,0x1f,0x7e,0x51,0x26,0x7c,0x49,0xe5,0x26,0xa, 0xd7,0x19,0xbd,0x22,0xf4,0x19, +0x9d,0x23,0xe4,0xb, 0x70,0xb, 0xa0,0x7e,0xb3,0x3a,0xd, 0xbc,0xba,0x28,0x2, 0x81, +0xc5,0x7a,0x73,0x3a,0xd, 0x7e,0xa0,0x1, 0x80,0x25,0xa, 0x3a,0x9, 0xb3,0x22,0xf4, +0xa, 0x2b,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x60,0x2d,0xd3,0x1b,0x6a,0x20,0xa, 0x2a, +0x9, 0xb2,0x23,0xe4,0xa, 0x4b,0x2d,0x3f,0x7d,0x2e,0x1b,0x1a,0x40,0xb, 0xa0,0x7e, +0xb3,0x3a,0xd, 0xbc,0xba,0x38,0xd3,0xda,0x3b,0x22,0x7f,0x60,0x7e,0xa3,0x2a,0x6d, +0x7e,0xb3,0x2a,0x6e,0xa4,0x7d,0xf5,0x3e,0xf4,0x7f,0x1, 0x7d,0x3f,0xe4,0x12,0x1b, +0xb8,0x7f,0x6, 0x7d,0x3f,0x12,0x1b,0xb8,0x7a,0xb3,0x16,0x91,0x22,0xe, 0xa4,0x7d, +0x6a,0x7c,0xbd,0xa, 0xa7,0x22,0x7d,0xf4,0x3e,0xf4,0x7f,0x60,0x2d,0xdf,0xb, 0x6a, +0xf0,0x22,0x7c,0xab,0x6d,0x44,0x80,0x29,0x4c,0xaa,0x68,0x11,0x12,0x66,0x79,0x60, +0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x12,0x66,0x36,0x2d,0xfe,0x80,0xf, 0x12,0x66,0x79, +0x60,0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x12,0x66,0x36,0x9d,0xfe,0x1b,0x6a,0xf0,0xb, +0x44,0x7e,0xf5,0x2a,0xbd,0xf4,0x38,0xd0,0x22,0x7f,0x71,0x2d,0xf4,0x7e,0x7b,0xb0, +0x1a,0xeb,0x7f,0x61,0x2e,0xd5,0x2a,0x7e,0x6b,0xb0,0x22,0x7c,0x7b,0x90,0x60,0x93, +0xe4,0x93,0xa, 0x1b,0x7e,0x63,0x2a,0x6d,0xa, 0x6, 0x2d,0x1, 0x7e,0x63,0x2a,0x6e, +0xa, 0x16,0xad,0x10,0x7d,0x21,0x12,0xb4,0x47,0xa, 0x26,0x7a,0x25,0x2a,0x74,0x1d, +0xac,0x7b,0x2e,0x34,0x39,0x12,0x6d,0x22,0xe4,0x2, 0x66,0x42,0x7c,0x2b,0x7e,0xb3, +0x1f,0x33,0xbc,0x2b,0x68,0x55,0x12,0x67,0x20,0x7c,0x3b,0x7c,0xb2,0x12,0x67,0x20, +0x7c,0xab,0xbe,0x30,0xff,0x68,0x44,0xbe,0xa0,0xff,0x68,0x3f,0x7e,0x70,0x4, 0xac, +0x73,0xa, 0x2a,0x2d,0x32,0x2e,0x34,0x1b,0xea,0x12,0x90,0xcb,0xbe,0xb0,0x2, 0x38, +0x2a,0xa, 0x2b,0x7e,0x34,0x2, 0xe0,0xad,0x32,0x2e,0x34,0x16,0x93,0x6d,0x22,0x30, +0x18,0x3, 0x2, 0x66,0x8b,0x7e,0xb3,0x2b,0x19,0xb4,0x1, 0xf, 0x12,0x67,0xd1,0x7a, +0x55,0x2a,0x7e,0x8, 0xd, 0xc8,0x74,0x1, 0x2, 0x66,0x42,0x22,0x7e,0xb3,0x2b,0xb, +0x7c,0xab,0x6c,0x77,0x7e,0x50,0x5, 0xac,0x57,0x9, 0x62,0x26,0x33,0xbc,0x6a,0x78, +0x3, 0x7c,0xb7,0x22,0xb, 0x70,0xbe,0x70,0x4, 0x40,0xe9,0x74,0xff,0x22,0x7c,0xab, +0x12,0x67,0xe2,0xd2,0x18,0x7c,0xba,0x12,0x66,0xbc,0xc2,0x18,0x22,0x7e,0xf, 0x13, +0x8a,0x7e,0x18,0x8, 0xa, 0xca,0x3b,0x7a,0x1d,0x2a,0x7f,0x30,0x12,0x67,0xd1,0x7a, +0x55,0x32,0x7e,0xb3,0x2b,0x19,0xf5,0x2f,0xe4,0x7a,0xb3,0x2b,0x19,0x7f,0x3, 0x7e, +0x1d,0x2a,0x12,0x66,0xa, 0x12,0x67,0xf2,0x12,0x67,0xdb,0x75,0x2e,0x0, 0x12,0x71, +0xd0,0x30,0xd, 0xfd,0x74,0x1, 0x12,0x67,0xea,0x7e,0x14,0x40,0x0, 0x7d,0x21,0x7d, +0x7, 0x12,0x32,0x7a,0x12,0xb3,0xfd,0x6d,0x33,0x80,0x19,0x7e,0x35,0x30,0x3e,0x34, +0x7f,0x3, 0x2d,0x13,0xb, 0xa, 0x20,0x7e,0xd, 0x2a,0x2d,0x13,0x12,0xc0,0x21,0x7e, +0x35,0x30,0xb, 0x34,0x7a,0x35,0x30,0x7e,0x35,0x32,0xbe,0x35,0x30,0x38,0xdc,0x5, +0x2e,0xe5,0x2e,0xbe,0xb0,0x1, 0x40,0xb6,0xe5,0x2f,0x7a,0xb3,0x2b,0x19,0xda,0x3b, +0x22,0x7e,0xa3,0x2a,0x6e,0x7e,0xb3,0x2a,0x6d,0xa4,0x22,0x7e,0x8, 0x2a,0x6d,0x2, +0xb, 0xb8,0xa9,0xd1,0xcb,0x74,0x1, 0x2, 0x0, 0xe, 0x12,0x0, 0xe, 0x7e,0x1f,0x13, +0x86,0x22,0x74,0x1, 0x12,0x12,0xac,0xe4,0x2, 0x0, 0x1e,0x7f,0x70,0x90,0x61,0x28, +0xe4,0x93,0x7c,0xab,0x3e,0xa0,0xe4,0x7a,0xb3,0x16,0x90,0x7f,0x1, 0xa, 0x3a,0x12, +0x1b,0xb8,0x7f,0x7, 0xa, 0x3a,0x2, 0x1b,0xb8,0x7e,0xa3,0x2f,0xa4,0x7e,0x70,0x4, +0xac,0x7a,0xb, 0x34,0xbe,0x37,0x39,0xbb,0x40,0x39,0x7e,0x37,0x39,0xbb,0xb, 0x34, +0x7a,0x37,0x39,0xbb,0xbe,0x34,0x0, 0x1, 0x78,0x5, 0x7e,0xb3,0x39,0x2, 0x22,0xbe, +0x34,0x0, 0x2, 0x78,0x3, 0x7c,0xba,0x22,0xbe,0x34,0x0, 0x2, 0x50,0x9, 0x7d,0x23, +0x1b,0x25,0x9, 0xb2,0x3b,0xd, 0x22,0x9e,0x34,0x0, 0x3, 0x2e,0x37,0x2b,0xb5,0x7e, +0x39,0xb0,0x22,0x74,0xff,0x22,0x70,0x5, 0x7e,0xb3,0x39,0x6a,0x22,0xbe,0xb0,0x3, +0x38,0x15,0x75,0x1c,0x0, 0x30,0x10,0x6, 0x7e,0x18,0x33,0x1b,0x80,0x4, 0x7e,0x18, +0x33,0x59,0x7a,0x1d,0x13,0x80,0x8, 0xbe,0xb0,0x5e,0x38,0x10,0x75,0x1c,0x0, 0xa, +0x1b,0x7e,0x1d,0x13,0x2d,0x31,0x1b,0x34,0x7e,0x1b,0xb0,0x22,0xbe,0xb0,0xd3,0x68, +0x3, 0xb4,0xd4,0x10,0xb4,0xd3,0x8, 0x6d,0x33,0x7a,0x37,0x39,0xbb,0x80,0x2, 0x15, +0x19,0x2, 0x68,0x19,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x3, 0x2, 0x68,0xfd,0xbe, +0xb0,0x80,0x40,0xc, 0xbe,0xb0,0xdf,0x38,0x7, 0xa, 0x3b,0x9, 0xb3,0x38,0x2f,0x22, +0xb4,0xfc,0x5, 0x7e,0xb3,0x38,0xd6,0x22,0xb4,0xfd,0x17,0x6c,0xaa,0x7e,0xb3,0x28, +0xa8,0x60,0x3, 0x4e,0xa0,0x1, 0x7e,0xb3,0x38,0x3f,0x60,0x3, 0x4e,0xa0,0x2, 0x7c, +0xba,0x22,0xb4,0xfe,0x5, 0x7e,0xb3,0x2b,0xb, 0x22,0x74,0xff,0x22,0xb4,0xeb,0x5, +0xe4,0x7a,0xb3,0x39,0xc0,0x7e,0x73,0x39,0xc0,0xa, 0x27,0x2e,0x24,0x0, 0x6, 0x12, +0x69,0x33,0x7c,0xab,0x7c,0xb7,0x4, 0x7a,0xb3,0x39,0xc0,0xb4,0x3, 0xb, 0xe4,0x7a, +0xb3,0x39,0xc0,0x6d,0x33,0x7a,0x37,0x39,0xbd,0x75,0x19,0xeb,0x7c,0xba,0x22,0x2e, +0x24,0x1b,0x4d,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0x22,0xca,0x3b,0x6d,0xee, +0x7e,0xc3,0x2a,0x6e,0x7e,0xd3,0x2a,0x6d,0x7e,0xb3,0x28,0x84,0x70,0x2, 0x21,0xda, +0x7e,0xb3,0x2a,0x3, 0x60,0x2, 0x21,0xda,0x7e,0xa3,0x26,0xfa,0x7e,0x73,0x26,0xfb, +0x7a,0x71,0x24,0x6c,0xee,0x6d,0xff,0x6c,0xff,0xa, 0x47,0x80,0x20,0x12,0x3b,0x6f, +0xbe,0x34,0x0, 0x96,0x8, 0x1d,0xb, 0xe0,0xbe,0xa0,0x0, 0x28,0x6, 0x7c,0xba,0x14, +0x12,0x6a,0x71,0x12,0x6a,0x81,0x58,0x3, 0x12,0x6a,0x6e,0x1b,0x44,0xbe,0x44,0x0, +0x0, 0x58,0xda,0xe5,0x24,0xa, 0x4b,0x80,0x1e,0x12,0x3b,0x6f,0xbe,0x34,0x0, 0x96, +0x8, 0x21,0xb, 0xe0,0xbe,0xa0,0x0, 0x28,0x6, 0x7c,0xba,0x14,0x12,0x6a,0x71,0x12, +0x6a,0x81,0x58,0x3, 0x12,0x6a,0x6e,0x7d,0x24,0xb, 0x24,0x7d,0x42,0xa, 0x3c,0xbd, +0x23,0x48,0xd6,0xbe,0xe0,0x3, 0x50,0x2, 0x80,0x10,0x7d,0x3f,0x12,0x1b,0xfa,0xa, +0x2f,0x12,0x18,0xac,0xbe,0x34,0x0, 0x28,0x8, 0x7, 0xe4,0x7a,0xb3,0x31,0xc7,0x41, +0x6b,0x6d,0xdd,0xbe,0xa0,0x0, 0x28,0x8, 0x7c,0xba,0x14,0x12,0x6a,0x7b,0x2d,0xd3, +0xa, 0x3d,0x1b,0x34,0xa, 0xca,0xbd,0xc3,0x58,0x8, 0x7c,0xba,0x4, 0x12,0x6a,0x7b, +0x2d,0xd3,0x7e,0x70,0x8, 0x80,0x2a,0x7e,0x50,0x2, 0xac,0x57,0x7d,0xc2,0x2e,0xc4, +0x1b,0xda,0x7d,0x1c,0x7a,0x31,0x82,0x7a,0x21,0x83,0xe4,0x93,0x1a,0xcb,0xbd,0xcd, +0x8, 0xf, 0x7d,0xc2,0x2e,0xc4,0x1b,0xdb,0x7d,0x2c,0x12,0x69,0x33,0x1a,0xcb,0x2d, +0xec,0x7c,0x67,0x1b,0x70,0xa5,0xbe,0x0, 0xce,0x7c,0xba,0x12,0x6a,0x7b,0x12,0x1b, +0xfa,0xbe,0x34,0xa, 0xf0,0x8, 0x4, 0x2e,0xe4,0x0, 0x28,0xbe,0xe4,0x0, 0xfa,0x28, +0x4, 0x7e,0xe4,0x0, 0xfa,0x7e,0xb3,0x31,0xc7,0xa, 0x3b,0xbd,0x3e,0x50,0x8, 0x7d, +0x3e,0x7c,0xb7,0x7a,0xb3,0x31,0xc7,0x7e,0xb3,0x31,0xc7,0xda,0x3b,0x22,0x7c,0xba, +0x4, 0x7c,0x79,0x12,0x3b,0x73,0x2d,0xf3,0xb, 0xf0,0x22,0x7e,0x71,0x24,0x2, 0x3b, +0x73,0xa, 0x2d,0x1b,0x24,0xa, 0x3a,0xbd,0x32,0x22,0x12,0x6a,0x95,0x12,0x69,0x3c, +0x7a,0xb3,0x2a,0xc, 0x22,0x7e,0xa3,0x28,0x84,0xe4,0x7a,0xb3,0x30,0x15,0x6c,0x33, +0x80,0x3d,0x7e,0x70,0x2, 0xac,0x73,0x9, 0x23,0x26,0xfb,0x7e,0x10,0x1, 0x6c,0x0, +0x80,0x27,0xbc,0x3, 0x68,0x21,0x7e,0x70,0x2, 0xac,0x70,0x9, 0x93,0x26,0xfb,0xa, +0x29,0xa, 0x32,0x12,0x6a,0xe6,0x18,0x2, 0xb, 0x10,0xbe,0x10,0x2, 0x40,0x8, 0x74, +0x2, 0x7a,0xb3,0x30,0x15,0x80,0x6, 0xb, 0x0, 0xbc,0xa0,0x38,0xd5,0xb, 0x30,0xbc, +0xa3,0x38,0xbf,0x22,0x1a,0x3b,0x9d,0x32,0x12,0x1b,0xfa,0xbe,0x34,0x0, 0x1, 0x22, +0xca,0x3b,0x12,0x6e,0xa, 0x74,0x9, 0xac,0xbf,0x7d,0xd5,0x2e,0xd4,0x27,0x76,0x6d, +0xcc,0x7e,0x37,0x2a,0x66,0x7a,0x35,0x43,0xe4,0x39,0xb6,0x0, 0x6, 0x7e,0x70,0x2, +0xac,0x7e,0x9, 0xb3,0x26,0xfa,0xf5,0x31,0x9, 0xb3,0x26,0xfb,0xf5,0x32,0x7e,0x73, +0x2a,0x6e,0x7c,0x6d,0x7e,0x8, 0x0, 0x35,0x12,0x6d,0x3e,0xf5,0x33,0xe5,0x31,0x7e, +0x73,0x2a,0x6d,0x7c,0x6c,0x7e,0x8, 0x0, 0x34,0x12,0x6d,0x3e,0x7c,0xab,0xe5,0x34, +0x7e,0x71,0x35,0x12,0x6e,0x2c,0x7a,0x35,0x3f,0x7e,0x34,0x15,0x9e,0x7a,0x35,0x41, +0x85,0x34,0x39,0x85,0x35,0x3a,0x7a,0xa1,0x3b,0x85,0x33,0x3c,0x7e,0xb3,0x2a,0x59, +0xf5,0x3d,0x75,0x3e,0x0, 0x7e,0x8, 0x0, 0x39,0x12,0x6e,0x2, 0x7d,0x23,0x6d,0x33, +0x7e,0x97,0x15,0xa0,0x6d,0x88,0x2f,0x41,0x7e,0x37,0x15,0xa2,0x6d,0x22,0x7d,0x3, +0x6d,0x11,0x7e,0x37,0x15,0xa4,0x2f,0x10,0x7a,0x1d,0x2b,0x7e,0x37,0x15,0xa6,0x7d, +0x23,0x6d,0x33,0x7e,0xb7,0x15,0xa8,0x6d,0xaa,0x2f,0x51,0x7f,0x74,0xa, 0x4c,0xe5, +0x31,0xa, 0x5b,0x9d,0x54,0xf5,0x2f,0x81,0x91,0xa, 0x4d,0xe5,0x32,0xa, 0x5b,0x9d, +0x54,0xf5,0x30,0x81,0x7b,0xe5,0x2f,0xbe,0xb0,0x0, 0x58,0x2, 0x81,0x79,0x7e,0x73, +0x2a,0x6d,0xbe,0x71,0x2f,0x18,0x2, 0x81,0x79,0xe5,0x30,0xbe,0xb0,0x0, 0x58,0x2, +0x81,0x79,0x7e,0x73,0x2a,0x6e,0xbe,0x71,0x30,0x18,0x2, 0x81,0x79,0xe5,0x2f,0x7e, +0x71,0x30,0x12,0x3b,0x73,0x7e,0x53,0x2a,0x59,0xa, 0x25,0x9d,0x32,0x7a,0x35,0x37, +0xbe,0x34,0x0, 0x0, 0x18,0x2, 0x81,0x79,0x7e,0x35,0x43,0xbe,0x35,0x37,0x18,0xd, +0x7f,0x16,0x2e,0x34,0x0, 0x6, 0x7e,0x1b,0xb0,0x4, 0x7a,0x1b,0xb0,0xe5,0x31,0xa, +0x2b,0xe5,0x2f,0x12,0x6a,0xe4,0x18,0xb, 0xe5,0x32,0xa, 0x2b,0xe5,0x30,0x12,0x6a, +0xe4,0x8, 0x56,0xe5,0x2f,0x7e,0x71,0x30,0x7c,0x6e,0x12,0x6f,0x91,0xf5,0x36,0xb4, +0x2, 0xc, 0x7e,0x35,0x37,0x7d,0x23,0xe, 0x24,0x9d,0x32,0x7a,0x35,0x37,0xe5,0x36, +0xbe,0xb0,0x2, 0x68,0x5, 0xe5,0x36,0xb4,0x1, 0x2f,0x7e,0x45,0x37,0x7d,0x34,0x1a, +0x26,0x1a,0x24,0xe5,0x2f,0x12,0x6d,0x20,0x7f,0x1, 0x7e,0x1d,0x2b,0x9f,0x10,0x7a, +0x1d,0x2b,0x7d,0x34,0x1a,0x26,0x1a,0x24,0xe5,0x30,0x12,0x6d,0x20,0x9f,0x51,0x12, +0x6d,0x27,0x9f,0x41,0x12,0x6d,0x27,0x9f,0x71,0x5, 0x30,0xa, 0x2d,0xe5,0x32,0xa, +0x3b,0x2d,0x32,0x1a,0x27,0xe5,0x30,0x1a,0x3b,0xbd,0x32,0x18,0x2, 0x61,0xb5,0x5, +0x2f,0xa, 0x2c,0xe5,0x31,0xa, 0x3b,0x2d,0x32,0x1a,0x27,0xe5,0x2f,0x1a,0x3b,0xbd, +0x32,0x18,0x2, 0x61,0xa9,0xbe,0x48,0x0, 0x0, 0x78,0x2, 0xb, 0x4c,0xbe,0x78,0x0, +0x0, 0x78,0x2, 0xb, 0x7c,0x7e,0x1d,0x2b,0x7f,0x4, 0x12,0x6d,0x2f,0x1b,0x6a,0x30, +0x7f,0x15,0x7f,0x7, 0x12,0x6d,0x2f,0x79,0x36,0x0, 0x2, 0x7e,0xb3,0x2a,0x65,0x60, +0xd, 0x1e,0xf4,0x1e,0xe4,0x50,0x4, 0x4e,0xf4,0x80,0x0, 0x14,0x78,0xf3,0xbe,0x78, +0x0, 0x7f,0x28,0x4, 0x7e,0x78,0x0, 0x7f,0x7d,0x3f,0x39,0x76,0x0, 0x5, 0x74,0x9, +0xac,0xbe,0x9, 0x75,0x27,0x7c,0x39,0x76,0x0, 0x6, 0xbe,0x70,0xf, 0x28,0x6, 0x74, +0xf, 0x39,0xb6,0x0, 0x6, 0x7e,0xa1,0x31,0x7e,0x70,0x9, 0xac,0x7f,0x19,0xa3,0x27, +0x7d,0x7e,0xa1,0x32,0x7e,0x70,0x9, 0xac,0x7f,0x19,0xa3,0x27,0x7e,0xda,0x3b,0x22, +0x1a,0x1b,0x1a,0x2, 0x2, 0x18,0xde,0x7e,0x35,0x37,0x1a,0x26,0x1a,0x24,0x22,0x74, +0x6, 0x2f,0x11,0x14,0x78,0xfb,0x12,0x18,0xfa,0x2e,0x18,0x0, 0x20,0x22,0xca,0xf8, +0x7c,0xf6,0x7c,0x87,0x7c,0x9b,0xa, 0x2f,0x7d,0x32,0x3e,0x34,0xb, 0x34,0x7c,0xb7, +0xbc,0xf9,0x38,0x14,0xa, 0xf8,0x1b,0xf4,0xa, 0x3f,0x9d,0xf3,0xa, 0x39,0xbd,0x3f, +0x18,0x6, 0x7c,0xab,0xa, 0x39,0x80,0x1d,0xbc,0xf9,0x28,0xd, 0xa, 0x39,0xa, 0x5f, +0x2d,0x53,0xb, 0x54,0x7c,0xab,0xe4,0x80,0x10,0xa, 0x3f,0xa, 0x58,0x2d,0x53,0xa, +0x39,0x9d,0x53,0x7c,0xab,0x9d,0x32,0x7c,0xb7,0x7a,0xb, 0xb0,0x7c,0xba,0xda,0xf8, +0x22,0xca,0x79,0x7c,0xfb,0x7e,0x8, 0x1f,0x34,0x12,0x6e,0x13,0x93,0x7c,0x6b,0x6c, +0xee,0x80,0x1e,0xa, 0x2e,0x9, 0x72,0x2a,0xd8,0xbe,0x70,0x1c,0x50,0x11,0xa, 0x27, +0x12,0x69,0x2f,0x7c,0x7b,0x7e,0xb3,0x2a,0xf7,0xa, 0x27,0x19,0xb2,0x1f,0x34,0xb, +0xe0,0xbc,0x6e,0x38,0xde,0x6c,0xee,0x80,0x17,0xa, 0x3e,0x9, 0x73,0x2a,0xb5,0xbe, +0x70,0x23,0x50,0xa, 0x7e,0x63,0x2a,0xf7,0xa, 0x27,0x19,0x62,0x1f,0x50,0xb, 0xe0, +0xbc,0xae,0x38,0xe5,0x6c,0xee,0x7e,0x30,0xe, 0xac,0x3e,0x2e,0x14,0x1f,0x34,0x6d, +0x0, 0x7c,0xbf,0x7c,0x7e,0x12,0x10,0xc0,0xb, 0xe0,0xbe,0xe0,0x5, 0x40,0xe7,0xda, +0x79,0x22,0x12,0xa, 0x6f,0x7e,0x37,0x15,0x9e,0x22,0x7c,0xf5,0x7c,0xe6,0x7c,0xd7, +0x7c,0xcb,0x22,0x7e,0x34,0x0, 0x46,0x74,0x3f,0x12,0x1b,0xb8,0x90,0x61,0x26,0xe4, +0x93,0x7c,0xab,0x90,0x61,0x27,0xe4,0x22,0x7c,0xbd,0x7c,0x7e,0x7e,0x13,0x2a,0x6e, +0xac,0x1b,0x3e,0x4, 0x7e,0x30,0x2, 0xac,0x37,0x2d,0x10,0x7e,0x1f,0x13,0x8a,0x2d, +0x31,0x22,0xca,0x3b,0x12,0x6e,0xa, 0x75,0x54,0x0, 0x7e,0xa1,0x54,0x74,0x6, 0xa4, +0x12,0x6f,0x25,0x30,0xe1,0x2e,0x7f,0x7, 0x7c,0xbc,0x12,0x6e,0xc9,0x50,0x25,0x7f, +0x7, 0x7c,0xbe,0x12,0x6e,0x91,0x50,0x1c,0x7f,0x7, 0x7c,0xbd,0x6c,0x77,0x12,0x6e, +0x94,0x50,0x11,0x7f,0x7, 0x7c,0xbf,0x6c,0x77,0x12,0x6e,0x94,0x50,0x6, 0x29,0xb7, +0x0, 0x4, 0x80,0xa, 0x5, 0x54,0xe5,0x54,0xbe,0xb0,0x1e,0x40,0xbd,0xe4,0xda,0x3b, +0x22,0x7e,0x70,0x1, 0x7c,0x87,0x7c,0x9b,0x29,0xa0,0x0, 0x3, 0x29,0x60,0x0, 0x1, +0x7e,0x70,0x1, 0xbe,0x80,0x1, 0x78,0x7, 0x29,0xa0,0x0, 0x2, 0x7e,0xb, 0x60,0xa, +0x7, 0xa, 0x29,0x2d,0x2, 0xa, 0x16,0xbd,0x1, 0x48,0xc, 0xa, 0x17,0xa, 0x3a,0x2d, +0x31,0xbd,0x23,0x18,0x2, 0xd3,0x22,0xc3,0x22,0x7e,0x70,0x1, 0x2, 0x6e,0x94,0xca, +0x3b,0x7e,0xe3,0x28,0x84,0x6c,0xdd,0x6c,0xff,0x74,0x6, 0xac,0xbd,0x12,0x6f,0x25, +0x30,0xe0,0x37,0x6c,0xcc,0x80,0x27,0x12,0x6f,0x32,0x7a,0xb3,0x1f,0x70,0x9, 0xa3, +0x26,0xfb,0x7a,0xa3,0x1f,0x71,0x7f,0x7, 0x12,0x6e,0x91,0x50,0xf, 0x7f,0x7, 0x7e, +0xb3,0x1f,0x71,0x6c,0x77,0x12,0x6e,0x94,0x50,0x2, 0xb, 0xf0,0xb, 0xc0,0xbc,0xec, +0x38,0xd5,0xbe,0xf0,0x2, 0x40,0x3, 0xd3,0x80,0x8, 0xb, 0xd0,0xbe,0xd0,0x1e,0x40, +0xb6,0xc3,0xda,0x3b,0x22,0x7d,0xf5,0x2e,0xf4,0x32,0x53,0x6d,0xee,0x29,0xb7,0x0, +0x5, 0x22,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x26,0xfa,0x22,0xca,0xf8,0x7e,0xf3, +0x2a,0x70,0x7a,0x37,0x1f,0x3a,0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f,0x3c,0xe4,0x7a, +0xb3,0x1f,0x34,0x7a,0xb3,0x1f,0x35,0x7e,0x73,0x2a,0x6f,0x7a,0x73,0x1f,0x36,0x7a, +0xf3,0x1f,0x37,0x7a,0xb3,0x1f,0x38,0x7a,0xb3,0x1f,0x39,0x7e,0x8, 0x1f,0x34,0x12, +0x6e,0x2, 0x6d,0x22,0x7d,0x3, 0x6d,0x11,0x7e,0x37,0x15,0xa0,0x2f,0x10,0x7e,0x33, +0x1f,0x36,0x6d,0x0, 0x12,0x18,0xfa,0xa, 0x1f,0x6d,0x0, 0x12,0x18,0xfa,0xda,0xf8, +0x22,0x7c,0xa6,0x7c,0x37,0x7c,0x2b,0xe4,0x6c,0x11,0x80,0x46,0xbc,0xa1,0x68,0x40, +0x1a,0x41,0x3e,0x44,0x9, 0x4, 0x26,0xfb,0xa, 0x20,0xa, 0x33,0x9d,0x32,0x12,0x1b, +0xfa,0x7c,0x7, 0x1a,0x41,0x3e,0x44,0x9, 0x74,0x26,0xfa,0xa, 0x27,0xa, 0x32,0x9d, +0x32,0x12,0x1b,0xfa,0x7c,0x97,0xbe,0x90,0x1, 0x18,0x8, 0xbe,0x0, 0x1, 0x18,0x3, +0x74,0x1, 0x22,0xbe,0x90,0x2, 0x18,0x8, 0xbe,0x0, 0x2, 0x18,0x3, 0x74,0x2, 0x22, +0xb, 0x10,0x7e,0x83,0x28,0x84,0xbc,0x81,0x18,0xb2,0x22,0x7e,0xa3,0x39,0x69,0x7c, +0xba,0x4, 0x7a,0xb3,0x39,0x69,0x7a,0xa3,0x38,0xc0,0x22,0xca,0x7b,0xca,0x2b,0xca, +0x1b,0xca,0xb, 0xc0,0x83,0xc0,0x82,0x12,0x22,0x38,0xd0,0x82,0xd0,0x83,0xda,0xb, +0xda,0x1b,0xda,0x2b,0xda,0x7b,0x32,0xa9,0xc0,0x93,0x75,0x17,0x0, 0x32,0x7a,0xb3, +0x39,0x6a,0xc4,0x54,0x7, 0xbe,0xb0,0x4, 0x68,0x3, 0xb4,0x2, 0x4, 0x74,0x3, 0x80, +0x7, 0x60,0x3, 0xb4,0x1, 0x7, 0x74,0x1, 0x7a,0xb3,0x38,0xd6,0x22,0x74,0x1, 0x7a, +0xb3,0x38,0xd6,0xe4,0x7a,0xb3,0x39,0x6a,0x22,0x7c,0xa7,0x7c,0x3b,0xa5,0xbb,0x0, +0x7, 0x7c,0xba,0x12,0x70,0x1e,0x80,0x2c,0xbe,0x30,0xeb,0x68,0x4, 0xa5,0xbb,0xec, +0x9, 0x7c,0xb3,0x7c,0x7a,0x12,0x70,0xb8,0x80,0x1a,0xbe,0x30,0x80,0x40,0x15,0xbe, +0x30,0xdf,0x38,0x10,0x7c,0xb3,0x24,0x80,0x7c,0x7a,0x12,0x70,0x94,0xa5,0xbb,0x8f, +0x3, 0x75,0x18,0x1, 0xa5,0xbb,0xfc,0x5, 0x7c,0xba,0x2, 0x2e,0xff,0x74,0x1, 0x7a, +0xb3,0x34,0x4f,0x22,0x7c,0x6b,0x2e,0x60,0xdd,0x68,0x1c,0x2e,0x60,0xfd,0x68,0x17, +0x1b,0x61,0x68,0x13,0x2e,0x60,0xfa,0x68,0xe, 0x1b,0x60,0x68,0xa, 0x80,0x0, 0xa, +0x2b,0x19,0x72,0x38,0xaf,0xd2,0xf, 0x22,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x33, +0x7e,0x27,0x39,0xbd,0x4d,0x22,0x78,0xe, 0xa5,0xbf,0xaa,0xa, 0x7e,0x24,0x0, 0x1, +0x7a,0x27,0x39,0xbd,0x15,0x19,0x7e,0x27,0x39,0xbd,0xbe,0x24,0x0, 0x1, 0x78,0x10, +0xa5,0xbf,0x9, 0x6, 0x7e,0x34,0x0, 0x2, 0x80,0x2, 0x6d,0x33,0x7a,0x37,0x39,0xbd, +0x75,0x19,0xea,0x22,0x7e,0xb3,0x39,0xbf,0x4, 0x7a,0xb3,0x39,0xbf,0xe5,0x18,0xb4, +0x1, 0x8, 0xe4,0x7a,0xb3,0x39,0xbf,0x75,0x18,0x0, 0x7e,0x73,0x39,0xbf,0x7a,0x73, +0x38,0xbe,0x22,0x12,0x67,0xf2,0xe4,0x12,0x0, 0xe, 0x7e,0x8, 0x2a,0x6d,0x2, 0xb, +0xb8,0xb4,0x3, 0x5, 0x12,0x71,0x13,0x80,0x2, 0xe4,0x22,0x12,0x71,0xd4,0x74,0x1, +0x22,0x12,0x71,0xb8,0x38,0x2, 0xe4,0x22,0x12,0x71,0x4a,0x49,0x55,0x34,0x3b,0xbe, +0xb0,0x2, 0x38,0x3, 0x2, 0x29,0xc6,0x2, 0x71,0x21,0x7e,0xa3,0x34,0x39,0x74,0x4, +0xa4,0x22,0x30,0x1a,0x8, 0x74,0x5, 0x7e,0x70,0x99,0x12,0x11,0xfa,0x7e,0xb3,0x34, +0x3a,0xb4,0x1, 0x53,0x12,0x71,0x4a,0x49,0x35,0x34,0x3b,0x49,0x15,0x34,0x3d,0x6d, +0x0, 0xbe,0x8, 0x0, 0x0, 0x68,0x1e,0xbe,0x70,0x0, 0x40,0x19,0xbe,0x70,0x2, 0x38, +0x14,0x74,0x2, 0x12,0x0, 0x1e,0x90,0x61,0x26,0xe4,0x93,0xca,0xb8,0x12,0x71,0xc1, +0xda,0xb8,0x12,0xf, 0x83,0x7e,0xb3,0x34,0x39,0x4, 0x7a,0xb3,0x34,0x39,0x12,0x71, +0xb8,0x28,0xe, 0x12,0x71,0x31,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x6, 0x74,0x3, 0x80, +0x2, 0x74,0x2, 0x7a,0xb3,0x34,0x3a,0x22,0x7e,0x73,0x34,0x38,0xbe,0x73,0x34,0x39, +0x22,0x90,0x61,0x27,0xe4,0x93,0x7c,0x7b,0x22,0x7e,0x8, 0x2a,0x6d,0x12,0xb, 0xb8, +0xe4,0x12,0x0, 0xe, 0x74,0x1, 0x7e,0x70,0x99,0x12,0x11,0xfa,0x2, 0x0, 0x4e,0xca, +0x3b,0x7c,0xdb,0xe4,0x7a,0xb3,0x2b,0x10,0x12,0x67,0xdb,0x7e,0xc0,0xa, 0x12,0x71, +0xd0,0x30,0xd, 0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x1f,0x3a,0xe5,0x12,0x90,0x8, +0x7d,0x73,0xbe,0x74,0xff,0xff,0x78,0x9, 0x12,0x72,0x4f,0x2e,0x34,0x0, 0x3, 0x80, +0x18,0xbe,0x74,0x80,0x0, 0x28,0x7, 0x12,0x72,0x4f,0xb, 0x35,0x80,0xb, 0xbe,0x74, +0x40,0x0, 0x28,0xc, 0x12,0x72,0x4f,0xb, 0x34,0x1b,0xa, 0x30,0x1b,0xc0,0x78,0xbe, +0xbe,0xd0,0x1, 0x78,0x9, 0x7e,0x1f,0x3a,0xe5,0x12,0x6f,0x3c,0x7d,0x73,0x7e,0x1f, +0x3a,0xd4,0x69,0x31,0x0, 0x1a,0x7a,0x73,0x2b,0x10,0x7d,0x37,0xda,0x3b,0x22,0x7e, +0xf, 0x3a,0xd4,0x2e,0x14,0x0, 0x1a,0xb, 0xa, 0x30,0x22,0xca,0x3b,0x7e,0x34,0xff, +0xff,0x7a,0x35,0x35,0x7e,0xb3,0x39,0x7f,0xf5,0x2a,0x7e,0xb3,0x2a,0x6d,0xf5,0x2b, +0x7e,0xb3,0x2a,0x6e,0xf5,0x2c,0x7e,0xb3,0x2a,0x70,0xf5,0x2d,0x7e,0xb3,0x2a,0x6f, +0xf5,0x2e,0x7e,0x34,0x27,0x10,0x7a,0x35,0x2f,0x7e,0x18,0x40,0x0, 0x7a,0x1d,0x31, +0x12,0x71,0xc9,0x30,0xd, 0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x8, 0x34,0x0, 0x12, +0x77,0xbf,0x6c,0xff,0x80,0x35,0x12,0x74,0xcc,0x6c,0xee,0x80,0x19,0x7e,0x11,0x2c, +0xac,0x1e,0x3e,0x4, 0x7e,0x30,0x2, 0xac,0x3f,0x2d,0x10,0x7e,0x1d,0x31,0x2d,0x31, +0xb, 0x1a,0x10,0x12,0x74,0xd5,0xe5,0x2e,0xbc,0xbe,0x38,0xe1,0xe5,0x2e,0x12,0x74, +0xe4,0x74,0x2, 0xac,0xbf,0x59,0x35,0x34,0x0, 0xb, 0xf0,0xe5,0x2d,0xbc,0xbf,0x38, +0xc5,0x12,0x77,0xcf,0x68,0xb, 0x7e,0x34,0x10,0x0, 0x12,0x4d,0x40,0x59,0x35,0x33, +0xfe,0x6c,0xff,0x80,0x74,0x12,0x74,0xcc,0x6c,0xee,0x80,0x12,0x12,0x75,0x12,0x1e, +0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x12,0x74,0xd3,0xe5,0x2a, +0xbc,0xbe,0x38,0xe8,0xe5,0x2a,0x12,0x74,0xe4,0x74,0x4, 0xac,0xbf,0x59,0x35,0x3, +0x6d,0xe5,0x2a,0xbe,0xb1,0x2d,0x50,0x33,0x12,0x74,0xcc,0x7e,0xe1,0x2a,0x80,0x12, +0x12,0x75,0x12,0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x12, +0x74,0xd3,0xe5,0x2d,0xbc,0xbe,0x38,0xe8,0xe5,0x2a,0xa, 0x3b,0x6d,0x22,0xe5,0x2d, +0xa, 0x1b,0x6d,0x0, 0x9f,0x1, 0x12,0x74,0xe8,0x80,0x4, 0x7e,0x34,0x10,0x0, 0x74, +0x4, 0xac,0xbf,0x59,0x35,0x3, 0x6f,0xb, 0xf0,0xe5,0x2e,0xbc,0xbf,0x38,0x86,0xe5, +0x2d,0xa, 0x1b,0x6d,0x0, 0x7e,0x78,0x0, 0xcc,0x12,0x75,0xa, 0x80,0x2e,0x74,0x2, +0xac,0xbf,0x49,0x25,0x34,0x0, 0xa, 0x5f,0xad,0x53,0x7e,0x14,0x10,0x0, 0x9d,0x15, +0xad,0x12,0x74,0xc, 0x1e,0x14,0x1e,0x4, 0x50,0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4, +0x7d,0x21,0x74,0x2, 0xac,0xbf,0x59,0x25,0x34,0x0, 0xb, 0xf0,0xe5,0x2d,0xbc,0xbf, +0x38,0xcc,0xe5,0x2b,0xa, 0x1b,0x6d,0x0, 0x12,0x75,0xa, 0x80,0x5c,0x74,0x4, 0xac, +0xbf,0x49,0x25,0x3, 0x6d,0xa, 0x1f,0xad,0x13,0x7e,0xf4,0x10,0x0, 0x9d,0xf1,0xad, +0xf2,0x74,0xc, 0x1e,0xf4,0x1e,0xe4,0x50,0x4, 0x4e,0xf4,0x80,0x0, 0x14,0x78,0xf3, +0x7d,0x2f,0x74,0x4, 0xac,0xbf,0x59,0x25,0x3, 0x6d,0xe5,0x2a,0xbe,0xb1,0x2d,0x50, +0x26,0x74,0x4, 0xac,0xbf,0x49,0x25,0x3, 0x6f,0x2e,0x14,0x10,0x0, 0xad,0x12,0x74, +0xc, 0x1e,0x14,0x1e,0x4, 0x50,0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4,0x7d,0x21,0x74, +0x4, 0xac,0xbf,0x59,0x25,0x3, 0x6f,0xb, 0xf0,0xe5,0x2b,0xbc,0xbf,0x38,0x9e,0x7e, +0x73,0x39,0x81,0xa, 0x37,0x6d,0x22,0x74,0xc, 0x2f,0x11,0x14,0x78,0xfb,0x7e,0xf4, +0x0, 0x64,0x7d,0x1f,0x12,0x18,0xf8,0x7d,0xe3,0x7a,0xe5,0x35,0x7e,0x73,0x39,0x82, +0xa, 0x37,0x6d,0x22,0x74,0xc, 0x2f,0x11,0x14,0x78,0xfb,0x7d,0x1f,0x12,0x18,0xf8, +0x7d,0x63,0x6c,0xff,0x80,0x20,0x74,0x2, 0xac,0xbf,0x49,0x45,0x34,0x0, 0xbe,0x45, +0x35,0x28,0x9, 0x7e,0x35,0x35,0x59,0x35,0x34,0x0, 0x80,0x8, 0xbd,0x46,0x50,0x4, +0x59,0x65,0x34,0x0, 0xb, 0xf0,0xe5,0x2d,0xbc,0xbf,0x38,0xda,0x6c,0xff,0x80,0x3a, +0x74,0x4, 0xac,0xbf,0x49,0x45,0x3, 0x6d,0xbe,0x45,0x35,0x28,0x9, 0x7e,0x35,0x35, +0x59,0x35,0x3, 0x6d,0x80,0x8, 0xbd,0x46,0x50,0x4, 0x59,0x65,0x3, 0x6d,0x49,0x45, +0x3, 0x6f,0xbe,0x45,0x35,0x28,0x9, 0x7e,0x35,0x35,0x59,0x35,0x3, 0x6f,0x80,0x8, +0xbd,0x46,0x50,0x4, 0x59,0x65,0x3, 0x6f,0xb, 0xf0,0xe5,0x2b,0xbc,0xbf,0x38,0xc0, +0x30,0x2, 0x6, 0x7e,0xd, 0x31,0x12,0x75,0x39,0xda,0x3b,0x22,0x9f,0x11,0x7a,0x1f, +0x24,0xf4,0x22,0x7d,0x13,0x6d,0x0, 0x7e,0x1f,0x24,0xf4,0x2f,0x10,0x7a,0x1f,0x24, +0xf4,0xb, 0xe0,0x22,0xa, 0x1b,0x6d,0x0, 0x7e,0x1f,0x24,0xf4,0x12,0x18,0xfa,0x7a, +0x1f,0x24,0xf4,0x7e,0x25,0x2f,0x74,0xc, 0x7d,0x13,0x7d,0x32,0x6d,0x22,0x60,0x5, +0x2f,0x11,0x14,0x78,0xfb,0xb, 0x14,0x2, 0x18,0xf8,0x7f,0x17,0x12,0x18,0xfa,0x6c, +0xff,0x22,0x7e,0x11,0x2c,0xac,0x1f,0x3e,0x4, 0x7e,0x30,0x2, 0xac,0x3e,0x2d,0x10, +0x7e,0x1d,0x31,0x2d,0x31,0xb, 0x1a,0x20,0x7a,0x27,0x24,0xf2,0x74,0x2, 0xac,0xbe, +0x49,0x35,0x34,0x0, 0xad,0x23,0x74,0xc, 0x22,0x12,0x75,0x43,0xb, 0x34,0x7a,0x73, +0x2b,0x1c,0x22,0xca,0x79,0x7f,0x10,0x9f,0x0, 0x12,0x77,0xc7,0x4c,0xaa,0x78,0x6, +0x7e,0x34,0x0, 0x40,0x80,0x6c,0x6c,0x99,0x80,0x38,0xa, 0xe9,0x2e,0xe4,0x60,0xac, +0x7d,0x7e,0x7a,0xf1,0x82,0x7a,0xe1,0x83,0xe4,0x93,0x7c,0x8b,0x90,0x60,0xaa,0xe4, +0x93,0x70,0xe, 0x7e,0xf3,0x2a,0x6e,0xac,0xf8,0x7e,0xb3,0x2a,0x70,0xa, 0xfb,0x2d, +0xf7,0x7d,0xef,0x3e,0xe4,0x7f,0x61,0x2d,0xde,0xb, 0x6a,0xd0,0x6d,0xcc,0x2f,0x6, +0xb, 0x90,0xbc,0xa9,0x38,0xc4,0xbe,0x8, 0x0, 0x0, 0x78,0x2, 0xb, 0xc, 0xa, 0x5a, +0x6d,0x44,0x7f,0x10,0x7f,0x2, 0x12,0x18,0xfa,0x7f,0x1, 0xb, 0xc, 0x7e,0x34,0xc4, +0x0, 0x7e,0x24,0x0, 0x9, 0x12,0x18,0xfa,0xbe,0x34,0x0, 0xfa,0x28,0x4, 0x7e,0x34, +0x0, 0xfa,0xda,0x79,0x22,0xca,0x3b,0x7a,0xd, 0x2f,0x7c,0xcb,0x7e,0xb3,0x2b,0x19, +0xf5,0x33,0x7e,0xb3,0x2b,0xb, 0xf5,0x34,0x7e,0xd3,0x2b,0x10,0x7e,0xe3,0x2b,0x1b, +0x7e,0xf3,0x2b,0x1c,0x7e,0x34,0x0, 0x38,0xca,0x39,0x7e,0x18,0x34,0x0, 0x7e,0x8, +0x24,0xf2,0x12,0x1b,0x93,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x18,0x3, +0x6d,0x7e,0x8, 0x25,0x2a,0x12,0x1b,0x93,0x1b,0xfd,0x7c,0xbc,0x12,0x37,0x7d,0x74, +0x1, 0x7a,0xb3,0x2b,0x19,0x74,0x5, 0xac,0xbc,0x12,0x37,0xd1,0x74,0x5, 0xac,0xbc, +0x12,0x37,0xbf,0x74,0x5, 0xac,0xbc,0x12,0x37,0xc8,0x74,0x5, 0xac,0xbc,0x9, 0x75, +0x26,0x37,0xbe,0x73,0x2b,0x5e,0x68,0x6, 0x7a,0x73,0x2b,0x5e,0xd2,0xe, 0xc2,0x0, +0x12,0x77,0xd8,0x12,0x35,0x79,0x12,0x71,0xc9,0x30,0xd, 0xfd,0x74,0x1, 0x12,0x0, +0xe, 0x7e,0x14,0x40,0x0, 0x7d,0x31,0x7e,0x2f,0x13,0x86,0x7d,0x25,0x7e,0x4, 0xd, +0xc8,0x12,0x32,0x7a,0x12,0x67,0xd1,0x7a,0x55,0x35,0x7e,0xd, 0x2f,0x7e,0x18,0xd, +0xc8,0x12,0x77,0x7, 0x12,0x76,0xb8,0xe5,0x33,0x7a,0xb3,0x2b,0x19,0xe5,0x34,0x7a, +0xb3,0x2b,0xb, 0x7a,0xd3,0x2b,0x10,0x7a,0xe3,0x2b,0x1b,0x7a,0xf3,0x2b,0x1c,0x7e, +0x34,0x0, 0x38,0xca,0x39,0x7e,0x18,0x24,0xf2,0x7e,0x8, 0x34,0x0, 0x12,0x1b,0x93, +0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x18,0x25,0x2a,0x7e,0x8, 0x3, 0x6d, +0x12,0x1b,0x93,0x1b,0xfd,0xda,0x3b,0x22,0x90,0x60,0x93,0xe4,0x93,0xa, 0xb, 0x7e, +0x73,0x2a,0x6d,0xa, 0x17,0x2d,0x10,0x7e,0xa3,0x2a,0x6e,0xa, 0x3a,0xad,0x13,0x7d, +0x21,0x6c,0x33,0x80,0x20,0xa, 0x3, 0x2d,0x2, 0x3e,0x4, 0x7e,0x7f,0x3a,0xe5,0x2d, +0xf0,0xb, 0x7a,0x0, 0x7e,0x90,0x2, 0xac,0x93,0x49,0xf4,0x13,0x8e,0x9d,0xf, 0x59, +0x4, 0x25,0xb6,0xb, 0x30,0xbc,0xa3,0x38,0xdc,0x7a,0x35,0x35,0x7e,0xf, 0x39,0xe, +0x7e,0x18,0x25,0xb6,0x2, 0x77,0x7, 0xca,0xf8,0x7f,0x71,0x6d,0xdd,0x6c,0xaa,0x7e, +0xf0,0x80,0xc2,0x0, 0x6d,0x44,0x80,0x32,0x12,0x77,0xa8,0x12,0x77,0xb9,0xbd,0x3d, +0x48,0x26,0x12,0x77,0xa8,0xb, 0x1a,0x30,0xbe,0x34,0x0, 0x0, 0x8, 0x4, 0xd2,0x0, +0x80,0x9, 0x12,0x1b,0xfa,0xbd,0x3d,0x68,0x2, 0xc2,0x0, 0x7d,0x34,0x3e,0x34,0x2d, +0x3f,0x7d,0x2e,0x12,0x77,0xb9,0x7d,0xd3,0xb, 0x44,0x7e,0xc5,0x35,0xbd,0xc4,0x38, +0xc7,0x30,0x0, 0xc, 0x7e,0xf0,0x7f,0x80,0x7, 0xb, 0xa0,0xbe,0xa0,0x8, 0x50,0x11, +0x7c,0xba,0x7d,0x3d,0x60,0x5, 0xe, 0x34,0x14,0x78,0xfb,0xa, 0xcf,0xbd,0x3c,0x18, +0xe8,0x7f,0x10,0x2e,0x35,0x35,0x7a,0x1b,0xa0,0x6d,0x44,0x80,0x21,0x7d,0x54,0x3e, +0x54,0x7f,0x17,0x2d,0x35,0xb, 0x1a,0x30,0x7f,0x60,0x2e,0xd5,0x35,0x7e,0x6b,0xb0, +0x60,0x5, 0xe, 0x34,0x14,0x78,0xfb,0x7c,0xb7,0x12,0x77,0xe3,0xb, 0x44,0x7e,0x55, +0x35,0xbd,0x54,0x38,0xd8,0xda,0xf8,0x22,0x7d,0xc4,0x3e,0xc4,0x7f,0x17,0x2d,0x3c, +0x22,0x74,0x2, 0xac,0xbe,0x7f,0x17,0x2d,0x35,0xb, 0x1a,0x30,0x2, 0x1b,0xfa,0x7e, +0x34,0x0, 0x38,0xe4,0x2, 0x1b,0xb8,0x90,0x60,0xa7,0xe4,0x93,0x7c,0xab,0x22,0x90, +0x60,0xaa,0xe4,0x93,0xbe,0xb0,0x1, 0x22,0x74,0x5, 0xac,0xbc,0x9, 0xb5,0x26,0x33, +0x22,0xa, 0x4a,0x7f,0x10,0x2d,0x34,0x7a,0x1b,0xb0,0x22,0x7c,0xab,0x12,0x26,0xdf, +0x7c,0xba,0x12,0x12,0x95,0x2, 0x0, 0x1e,0x6d,0x33,0x7e,0x24,0x6, 0xfc,0x12,0x1f, +0xf7,0x7e,0x34,0x0, 0x1, 0x7e,0x24,0x7, 0x7a,0x2, 0x1f,0xf7,0x7e,0xb3,0x34,0x3a, +0xb4,0x1, 0x2, 0xc3,0x22,0xd3,0x22,0x7e,0xb3,0x2b,0x1a,0x70,0x1f,0x12,0x2b,0x13, +0x12,0x78,0xc, 0x50,0xfb,0x12,0x67,0x4d,0x12,0x78,0xc8,0x20,0x11,0x3, 0x12,0x78, +0x3d,0x74,0x2, 0x7a,0xb3,0x2b,0x1a,0xe4,0x7a,0xb3,0x16,0x91,0x22,0xca,0x3b,0x7e, +0xb3,0x2b,0xb, 0x7a,0xb3,0x1f,0x33,0x7e,0xf3,0x2b,0x5e,0x12,0x67,0x20,0x7c,0xdb, +0xbe,0xd0,0xff,0x68,0x6a,0x6c,0xcc,0x12,0x77,0xd8,0xf5,0x2a,0x7e,0x73,0x2b,0xb, +0xbe,0x71,0x2a,0x68,0x3c,0x7e,0x70,0x4, 0xac,0x7d,0xa, 0x2c,0x2d,0x32,0x2e,0x34, +0x1b,0xea,0x12,0x90,0xcb,0x7c,0xeb,0xbe,0xe0,0x2, 0x38,0x43,0xa, 0xe, 0x7e,0x14, +0x2, 0xe0,0xad,0x10,0x2e,0x14,0x16,0x93,0x6d,0x0, 0x7a,0xd, 0x2b,0x7e,0x70,0x1d, +0xac,0x7e,0x2e,0x34,0x39,0x12,0x6d,0x22,0x7a,0x1f,0x39,0xe, 0x7c,0xbc,0x12,0x75, +0xc5,0xb, 0xc0,0xbe,0xc0,0x4, 0x40,0xaf,0x7e,0x73,0x2b,0x5e,0xbc,0x7f,0x68,0x6, +0x7a,0xf3,0x2b,0x5e,0xd2,0xe, 0xd2,0x0, 0x7e,0xb3,0x1f,0x33,0x12,0x35,0x79,0xda, +0x3b,0x22,0x12,0x78,0xc, 0x50,0xfb,0x22,0x12,0x33,0xb2,0x50,0x3, 0xd2,0x11,0x22, +0xc2,0x11,0x22,0x12,0x78,0xdc,0x12,0x79,0xc, 0x2, 0x78,0xc8,0x6c,0xaa,0x80,0x26, +0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x5, 0xf8,0x49,0x32,0x4, 0x0, 0x2d,0x31,0x59, +0x32,0x5, 0xf8,0x30,0x6, 0xe, 0x49,0x12,0x4, 0x7e,0x49,0x32,0x6, 0x76,0x2d,0x31, +0x59,0x32,0x6, 0x76,0xb, 0xa0,0x12,0x7e,0x8c,0x38,0xd5,0x22,0x7e,0x8, 0x24,0xf2, +0x7e,0x34,0x0, 0xc, 0xe4,0x12,0x1b,0xb8,0x12,0xa5,0x6a,0x12,0xa5,0x61,0xa9,0xd1, +0xcb,0x12,0x67,0xea,0x7a,0x37,0x24,0xf6,0x7e,0x1f,0x3a,0xe5,0x7a,0x37,0x24,0xf8, +0x7e,0x1f,0x13,0x86,0x7a,0x37,0x24,0xfa,0x6d,0x33,0x12,0xb6,0xfc,0x2, 0xb, 0x4d, +0x12,0x81,0xa, 0x12,0x79,0x9a,0x12,0x7b,0x20,0x7e,0xb3,0x38,0xd4,0xb4,0x1, 0x1e, +0x7e,0x34,0x61,0xc0,0x12,0x5f,0xd1,0x7e,0x24,0x0, 0x5, 0xad,0x12,0x7a,0x17,0x28, +0xa1,0x7e,0x14,0x61,0xc2,0x12,0x4f,0x39,0xad,0x32,0x7a,0x37,0x28,0xa3,0x7e,0xb3, +0x3b,0x1c,0x60,0x7, 0x14,0x7a,0xb3,0x3b,0x1c,0x80,0x6, 0x7e,0xb3,0x28,0xac,0x60, +0x9, 0x12,0x78,0xd3,0x12,0x7c,0xaf,0x12,0xb4,0x50,0x7e,0xb3,0x28,0xad,0x60,0x9, +0x12,0x7e,0x16,0x12,0x7d,0x6b,0x2, 0x7d,0xf, 0x22,0x7e,0x90,0x1, 0x7e,0x94,0x61, +0xc0,0x7e,0x84,0x0, 0xff,0xb, 0x4a,0x30,0x7a,0x37,0x28,0xa1,0x7e,0xb4,0x61,0xc2, +0x7e,0xa4,0x0, 0xff,0xb, 0x5a,0x30,0x7a,0x37,0x28,0xa3,0x12,0x7c,0x92,0xb, 0x1a, +0x20,0x7e,0x14,0x61,0x4f,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0xd0,0xe4,0x7a,0xb3,0x28, +0xac,0x12,0x7b,0x0, 0x7e,0x34,0xff,0xfa,0xad,0x32,0x12,0x87,0xc4,0x7d,0xc3,0xe, +0x34,0x7e,0x27,0x7, 0xfe,0xbd,0x2c,0x58,0x1c,0x7e,0xc7,0x7, 0xfc,0xbd,0xc3,0x58, +0x14,0x6d,0xcc,0x9e,0xc7,0x2a,0x5a,0xbe,0xc7,0x28,0x8e,0x8, 0x8, 0x12,0x7e,0x94, +0x60,0x3, 0x12,0x7c,0x9b,0x12,0xa5,0xa3,0x40,0x5, 0xe4,0x7a,0xb3,0x28,0xa8,0x12, +0x96,0x16,0x68,0x6, 0x7e,0xb3,0x3b,0x17,0x60,0x7, 0xe4,0x7a,0xb3,0x28,0xad,0x80, +0x6f,0x12,0x7b,0x7, 0x28,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x30,0x12,0x5, 0xe4,0x7a, +0xb3,0x28,0xad,0x12,0xa5,0xe1,0x50,0xa, 0x12,0x7b,0x0, 0x12,0x7b,0x3d,0x7c,0x9b, +0x80,0x17,0x7e,0xb3,0x26,0x84,0x70,0x11,0x7e,0xb3,0x26,0x85,0x70,0xb, 0x12,0x7b, +0x7, 0x28,0x6, 0x7e,0x90,0x3, 0x12,0x7b,0x0, 0x7e,0xc7,0x7, 0xfa,0xbe,0xc4,0x5, +0xdc,0x8, 0x17,0x12,0x7b,0x7, 0x28,0x12,0x6d,0xcc,0x9d,0xcd,0xbe,0xc7,0x28,0x8e, +0x58,0x8, 0x12,0x7b,0x12,0xe4,0x7a,0xb3,0x28,0xad,0xa, 0x29,0xb, 0x4a,0x30,0xad, +0x32,0x7a,0x37,0x28,0xa1,0xa, 0x29,0xb, 0x5a,0x30,0xad,0x32,0x7a,0x37,0x28,0xa3, +0x12,0x7b,0xf, 0x50,0xd, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x87,0xcb,0x28,0x3, 0x12, +0x7b,0x12,0x7e,0xc7,0x28,0x8a,0xbd,0xcd,0x8, 0x1f,0x7e,0x24,0x0, 0x2, 0x7d,0x3d, +0x12,0x18,0xac,0x6e,0x34,0xff,0xff,0xb, 0x34,0xbe,0x37,0x28,0x8e,0x58,0xa, 0x12, +0x7b,0xf, 0x50,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x7b,0xa5,0xb4,0x1, 0x5, 0xe4, +0x7a,0xb3,0x28,0xad,0x12,0x7d,0xbc,0x7e,0xb3,0x34,0x88,0xbe,0xb0,0x0, 0x28,0x1f, +0x14,0x7a,0xb3,0x34,0x88,0x70,0x18,0xe4,0x7a,0xb3,0x28,0xad,0x12,0x7c,0xa7,0x7a, +0xb3,0x16,0x91,0x7a,0xb3,0x16,0x90,0x7a,0xb3,0x28,0x84,0x7a,0xb3,0x26,0x83,0x22, +0x74,0x1, 0x7a,0xb3,0x28,0xad,0x22,0x7e,0x83,0x28,0x84,0xbe,0x80,0x0, 0x22,0xa2, +0x15,0x22,0xe4,0x7a,0xb3,0x34,0x88,0x7a,0xb3,0x28,0xac,0x74,0x2, 0x2, 0x2e,0xe1, +0x12,0xae,0x3f,0x60,0x17,0x12,0x7b,0x0, 0x7e,0x37,0x28,0xa1,0x3e,0x34,0x7a,0x37, +0x28,0xa1,0x7e,0x37,0x28,0xa3,0x3e,0x34,0x7a,0x37,0x28,0xa3,0x22,0x7e,0xa0,0x1, +0x7e,0x47,0x7, 0xf8,0x12,0x7c,0x92,0xb, 0x1a,0x0, 0x7e,0x34,0xff,0xfa,0xad,0x30, +0x7e,0x14,0x0, 0x2, 0x12,0x7b,0x9d,0x8, 0x12,0x7e,0xb3,0x28,0xac,0x60,0x7, 0xe4, +0x7a,0xb3,0x28,0xad,0x80,0x32,0x7e,0xa0,0x5, 0x80,0x2d,0x7e,0x34,0xff,0xfb,0x12, +0x7b,0x9b,0x8, 0x5, 0x7e,0xa0,0x4, 0x80,0x1f,0x7e,0x34,0xff,0xfc,0x12,0x7b,0x9b, +0x8, 0x5, 0x7e,0xa0,0x3, 0x80,0x11,0x7e,0x34,0xff,0xfd,0x12,0x7b,0x9b,0x8, 0x5, +0x7e,0xa0,0x2, 0x80,0x3, 0x7e,0xa0,0x1, 0x7c,0xba,0x22,0xad,0x30,0x7d,0x21,0x12, +0x18,0xac,0xbd,0x34,0x22,0xca,0x3b,0x12,0xa1,0xec,0x38,0x2, 0x81,0x68,0x7e,0xc3, +0x34,0x8b,0x4c,0xcc,0x78,0x3d,0x7a,0xb3,0x34,0x8b,0xe4,0x7a,0xb3,0x34,0x8d,0x6c, +0xaa,0x80,0x26,0x12,0x7c,0x73,0x7e,0x70,0x2, 0xac,0x7a,0x9, 0xd3,0x26,0xfa,0x9, +0xe3,0x26,0xfb,0x7a,0x49,0xd0,0x19,0xe4,0x0, 0x1, 0x74,0x1, 0x19,0xb4,0x0, 0x8, +0x12,0x7c,0x7d,0x59,0x34,0x0, 0x2, 0xb, 0xa0,0x7e,0xb3,0x28,0x84,0xbc,0xba,0x38, +0xd2,0x80,0x7b,0x7c,0xfc,0x6c,0xaa,0x80,0x31,0x12,0x7c,0x73,0x7e,0x49,0xd0,0x9, +0xe4,0x0, 0x1, 0x9, 0xb4,0x0, 0x8, 0x70,0x4, 0x1b,0xf0,0x80,0x1b,0x12,0x7c,0x7d, +0x7d,0x23,0x49,0x34,0x0, 0x2, 0x12,0x8d,0xd9,0xbe,0xf4,0x0, 0x23,0x8, 0x9, 0x74, +0x5, 0x19,0xb4,0x0, 0x8, 0x75,0x5a,0x1, 0xb, 0xa0,0xbc,0xfa,0x38,0xcb,0x4c,0xff, +0x78,0x2, 0x80,0x26,0x7e,0x73,0x34,0x8d,0xbe,0x70,0x4, 0x40,0x22,0x6c,0xaa,0x80, +0xe, 0x12,0x7c,0x73,0x9, 0xb4,0x0, 0x8, 0xbe,0xb0,0x5, 0x68,0x6, 0xb, 0xa0,0xbc, +0xfa,0x38,0xee,0xbc,0xfa,0x78,0x3, 0x75,0x5a,0x0, 0x12,0x7c,0x84,0x80,0xf, 0x7c, +0xb7,0x4, 0x7a,0xb3,0x34,0x8d,0x80,0x6, 0x12,0x7c,0x84,0x75,0x5a,0x0, 0xe5,0x5a, +0xda,0x3b,0x22,0x7e,0x90,0x9, 0xac,0x9a,0x2e,0x44,0x34,0x8e,0x22,0x7c,0xbd,0x7c, +0x7e,0x2, 0x3b,0x73,0xe4,0x7a,0xb3,0x34,0x8c,0x7a,0xb3,0x34,0x8b,0x7a,0xb3,0x34, +0x8d,0x22,0x7e,0x34,0x61,0x55,0x7e,0x24,0x0, 0xff,0x22,0x74,0x2, 0x7a,0xb3,0x34, +0x88,0x12,0x7c,0xa7,0x2, 0x2e,0xe1,0x74,0x1, 0x7a,0xb3,0x28,0xac,0xe4,0x22,0x12, +0x7c,0xcc,0x6d,0x33,0x7a,0x37,0x38,0xab,0x6c,0xaa,0x80,0x5, 0x12,0x7d,0x5d,0xb, +0xa0,0x12,0x7d,0x7, 0x38,0xf6,0xe4,0x7a,0xb3,0x38,0x40,0x22,0x7e,0x37,0x3a,0xde, +0x12,0x1f,0x85,0x7a,0x37,0x38,0xab,0x6c,0xaa,0x80,0x23,0x12,0x7d,0x7, 0x28,0x26, +0xa, 0x4a,0x9, 0x64,0x38,0x44,0xbc,0x6b,0x50,0x12,0x7e,0x50,0x2, 0xac,0x5a,0x49, +0x42,0x3a,0xd8,0x7e,0x70,0xc, 0xac,0x67,0x59,0x43,0x38,0x4e,0xb, 0xa0,0x7e,0xb3, +0x38,0x41,0xbc,0xba,0x38,0xd5,0x22,0x90,0x61,0xc5,0xe4,0x93,0xbc,0xba,0x22,0x6c, +0xaa,0x80,0x44,0x7e,0x70,0xc, 0xac,0x7a,0x12,0xa7,0xd3,0xbe,0x34,0x3, 0xe8,0x8, +0x5, 0x12,0x7d,0x5d,0x80,0x2f,0x7e,0x50,0xc, 0xac,0x5a,0x49,0x32,0x38,0x52,0x49, +0x12,0x38,0x4e,0xbd,0x13,0x28,0xf, 0x7d,0x2, 0x2e,0x4, 0x38,0x52,0x7d,0x13,0xb, +0x15,0x1b,0x8, 0x10,0x80,0xf, 0xbe,0x34,0x0, 0x2, 0x28,0x9, 0x2e,0x24,0x38,0x52, +0x1b,0x35,0x1b,0x28,0x30,0xb, 0xa0,0x12,0x7d,0x7, 0x38,0xb7,0x22,0x7e,0x50,0xc, +0xac,0x5a,0x49,0x32,0x38,0x4e,0x59,0x32,0x38,0x52,0x22,0x7e,0x43,0x2a,0x6e,0x7e, +0x53,0x2a,0x6d,0xac,0x54,0x7e,0x17,0x28,0xa1,0x12,0xa5,0x5a,0x6d,0x0, 0x80,0x37, +0x7d,0x40,0x3e,0x44,0x7e,0x7f,0x3a,0xe5,0x2d,0xf4,0xb, 0x7a,0x30,0xbd,0x13,0x58, +0x10,0x7d,0xf4,0x2e,0xf4,0x8, 0xa, 0xb, 0xf8,0x50,0x9d,0x51,0x1b,0xf8,0x50,0x80, +0x14,0x6d,0x55,0x9d,0x51,0xbd,0x53,0x8, 0xc, 0x2e,0x44,0x8, 0xa, 0xb, 0x48,0x50, +0x2d,0x51,0x1b,0x48,0x50,0xb, 0x4, 0xbd,0x20,0x38,0xc5,0x22,0x7e,0x60,0x4, 0x7e, +0x27,0x3, 0xfc,0xbe,0x24,0x3, 0xe8,0x28,0x3, 0x7e,0x60,0x8, 0x7e,0xb3,0x28,0xac, +0xb4,0x1, 0x1a,0x7e,0x73,0x34,0x89,0xbc,0x76,0x50,0xf, 0xe4,0x7a,0xb3,0x28,0xad, +0x12,0x7b,0x12,0x7e,0xb3,0x34,0x89,0x4, 0x80,0x4, 0xe4,0x80,0x1, 0xe4,0x7a,0xb3, +0x34,0x89,0x7e,0xb3,0x28,0xad,0xb4,0x1, 0x17,0x7e,0xa3,0x34,0x8a,0xbe,0xa0,0x5, +0x50,0xa, 0xe4,0x7a,0xb3,0x28,0xad,0x7c,0xba,0x4, 0x80,0x5, 0x74,0x5, 0x80,0x1, +0xe4,0x7a,0xb3,0x34,0x8a,0x22,0x7e,0x27,0x28,0xa3,0x6d,0x11,0x9d,0x12,0x6c,0xaa, +0x80,0x64,0x30,0x5, 0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x5, 0xf8,0x49,0x4, +0x4, 0x0, 0xbd,0x2, 0x8, 0x11,0x7e,0xb3,0x25,0xf6,0xb4,0x1, 0x16,0x7d,0xf2,0x2d, +0xf3,0x59,0xf4,0x5, 0xf8,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59, +0x4, 0x5, 0xf8,0x30,0x7, 0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x6, 0x76,0x49, +0x4, 0x4, 0x7e,0xbd,0x2, 0x8, 0x11,0x7e,0xb3,0x25,0xf6,0xb4,0x1, 0x16,0x7d,0xf2, +0x2d,0xf3,0x59,0xf4,0x6, 0x76,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, +0x59,0x4, 0x6, 0x76,0xb, 0xa0,0x12,0x7e,0x8c,0x38,0x97,0x22,0x90,0x61,0x28,0xe4, +0x93,0xbc,0xba,0x22,0x6c,0x66,0x90,0x60,0xa7,0xe4,0x93,0xbe,0xb0,0x0, 0x28,0x71, +0x90,0x60,0xaa,0xe4,0x93,0x70,0x6a,0x7e,0xb3,0x28,0xa8,0xb4,0x1, 0x63,0x7e,0x73, +0x26,0xf2,0xbe,0x70,0x0, 0x28,0x5a,0x6c,0x33,0x80,0x4e,0xa, 0x23,0x9, 0x72,0x26, +0xe6,0x7e,0xb3,0x2a,0x6e,0x14,0xbc,0x7b,0x78,0x3d,0x6c,0x22,0x80,0x27,0x7c,0xb2, +0x7c,0x73,0x12,0xa5,0x73,0x50,0x1c,0xa, 0x22,0x7e,0x73,0x2a,0x6e,0xa, 0x7, 0x2d, +0x2, 0x3e,0x4, 0x49,0x20,0x4, 0xfc,0x6d,0x0, 0x9e,0x7, 0x2a,0x4f,0xbd,0x20,0x58, +0x2, 0xb, 0x60,0xb, 0x20,0x7e,0x73,0x2a,0x6d,0xbc,0x72,0x38,0xd1,0xbe,0x60,0x0, +0x28,0x3, 0x74,0x1, 0x22,0xe4,0x22,0xb, 0x30,0x7e,0x73,0x26,0xf2,0xbc,0x73,0x38, +0xaa,0x74,0x1, 0x22,0xca,0x3b,0x90,0x61,0x27,0xe4,0x93,0xf5,0x27,0x12,0x7b,0xf, +0x50,0x2, 0xe1,0xa7,0x6d,0x33,0x9e,0x37,0x2a,0x4f,0x3e,0x34,0xbe,0x37,0x7, 0xf8, +0x18,0x75,0x7e,0xb3,0x16,0x92,0x70,0x6f,0x7e,0xb3,0x28,0xa8,0xb4,0x1, 0x65,0x7e, +0x77,0x2a,0x51,0x7e,0x67,0x2a,0x53,0x75,0x24,0x0, 0x80,0x53,0xe5,0x24,0x12,0x3f, +0x74,0x60,0x4a,0x12,0x7f,0xaa,0x12,0x87,0xe6,0x7e,0xb3,0x2a,0x3, 0xb4,0x1, 0xe, +0x90,0x60,0xab,0xe4,0x93,0xbe,0xb1,0x26,0x78,0x4, 0xe, 0x64,0xe, 0x74,0x7e,0xa1, +0x26,0x74,0x2, 0xa4,0x49,0x35,0x4, 0xfc,0xbd,0x36,0x48,0x14,0xe5,0x25,0xa, 0x2b, +0xe5,0x27,0xa, 0x3b,0x2d,0x32,0x3e,0x34,0x49,0x33,0x4, 0xfc,0xbd,0x37,0x58,0xd, +0xe5,0x24,0x6c,0x77,0x12,0x3f,0x90,0x12,0x7f,0xaa,0x12,0x87,0xa1,0x5, 0x24,0x12, +0xc0,0x4b,0x38,0xa8,0x12,0xa1,0xa3,0xda,0x3b,0x22,0x7e,0x71,0x24,0x74,0x2, 0xac, +0x7b,0x22,0x12,0xa1,0x8c,0x12,0x9d,0x2, 0x12,0x7f,0x14,0x12,0x9f,0xef,0x2, 0x7f, +0xc1,0xca,0x3b,0x12,0x3b,0x2d,0x7e,0xb3,0x28,0x84,0x60,0x6, 0x7e,0xb3,0x38,0x2d, +0x60,0x9, 0xe4,0x7a,0xb3,0x38,0x2f,0x7a,0xb3,0x37,0xb4,0x7e,0xb3,0x38,0x2d,0x70, +0x6b,0x6c,0x99,0x80,0x5f,0x74,0x2, 0xac,0xb9,0x9, 0x85,0x26,0xfa,0x9, 0xf5,0x26, +0xfb,0x7c,0xb9,0x12,0xa0,0x9f,0x40,0x4a,0x6c,0xee,0x80,0x3e,0x74,0x2, 0xac,0xbe, +0x9, 0xd5,0x37,0xb5,0x9, 0xc5,0x37,0xb6,0xa, 0x28,0xa, 0x3d,0x12,0x80,0x6f,0x78, +0x27,0xa, 0x2f,0xa, 0x3c,0x12,0x80,0x6f,0x78,0x1e,0x7c,0xb9,0x12,0x80,0x77,0x7e, +0x14,0x62,0x2b,0x12,0x5f,0x55,0xbd,0x32,0x58,0xe, 0x7c,0xb9,0x6c,0x77,0x12,0x3f, +0x90,0x7c,0xb8,0x7c,0x7f,0x12,0x87,0xa9,0xb, 0xe0,0x7e,0x73,0x38,0x2f,0xbc,0x7e, +0x38,0xba,0xb, 0x90,0x7e,0x73,0x28,0x84,0xbc,0x79,0x38,0x99,0x7e,0x73,0x37,0xb4, +0x7a,0x73,0x38,0x2f,0xa, 0x37,0x3e,0x34,0xca,0x39,0x7e,0x18,0x37,0xf1,0x7e,0x8, +0x37,0xb5,0x12,0x1b,0x93,0x1b,0xfd,0xe4,0x7a,0xb3,0x38,0x2d,0xda,0x3b,0x22,0x9d, +0x32,0x12,0x1b,0xfa,0x4d,0x33,0x22,0x7c,0xab,0x7e,0x70,0x2, 0xac,0x7a,0x9, 0xb3, +0x26,0xfa,0x9, 0x73,0x26,0xfb,0x2, 0x3b,0x73,0xca,0x79,0x6c,0x88,0x80,0x70,0x74, +0x2, 0xac,0xb8,0x9, 0xf5,0x26,0xfa,0x9, 0x75,0x26,0xfb,0x7a,0x71,0x24,0x7c,0xbf, +0x12,0xa5,0x73,0x50,0x58,0x6c,0xee,0x80,0x4f,0xbc,0xe8,0x68,0x49,0x7e,0x70,0x2, +0xac,0x7e,0x12,0x87,0xe6,0x6c,0x99,0x90,0x60,0xaa,0xe4,0x93,0x70,0x18,0x7e,0xb3, +0x2a,0x70,0x14,0xbe,0xb1,0x26,0x78,0xe, 0xa, 0x2f,0x12,0x3f,0x53,0xbe,0x34,0x0, +0x1, 0x18,0x3, 0x7e,0x90,0x1, 0xbe,0x90,0x1, 0x78,0x1b,0x7c,0xbe,0x12,0x80,0x77, +0x7d,0xf3,0x7c,0xb8,0x12,0x80,0x77,0xbd,0x3f,0x8, 0x4, 0x7c,0xbe,0x80,0x2, 0x7c, +0xb8,0x6c,0x77,0x12,0x3f,0x90,0xb, 0xe0,0x12,0x87,0x6f,0x38,0xac,0xb, 0x80,0x7e, +0x73,0x28,0x84,0xbc,0x78,0x38,0x88,0xda,0x79,0x22,0xca,0xd8,0xca,0x79,0x7e,0xa3, +0x2a,0x6e,0x7e,0x47,0x28,0x99,0xe4,0x7a,0xb3,0x28,0xa6,0x7e,0xb3,0x26,0xf0,0xbe, +0xb0,0x0, 0x28,0x4c,0x7e,0x73,0x28,0x85,0xbe,0x70,0x0, 0x28,0x43,0x6c,0xff,0x80, +0x3b,0x7e,0x50,0x2, 0xac,0x5f,0x9, 0xd2,0x27,0x36,0x9, 0xe2,0x27,0x37,0x7e,0x50, +0x2, 0xac,0x5e,0x49,0x12,0x4, 0xfc,0x6d,0x22,0x9e,0x27,0x2a,0x53,0xbd,0x12,0x58, +0x19,0x12,0x82,0x2c,0x49,0x12,0x4, 0xfc,0x6d,0x22,0x9e,0x27,0x2a,0x51,0xbd,0x12, +0x58,0x8, 0x74,0x1, 0x7a,0xb3,0x28,0xa6,0x80,0x6, 0xb, 0xf0,0xbc,0x7f,0x38,0xc1, +0xe4,0x7a,0xb3,0x28,0xa7,0x7e,0xb3,0x26,0x83,0x70,0x40,0x12,0x87,0xcb,0x28,0x3b, +0x6c,0xff,0x80,0x33,0x7e,0x50,0x2, 0xac,0x5f,0x9, 0xd2,0x26,0xfa,0x9, 0xe2,0x26, +0xfb,0x12,0x82,0x2c,0x49,0x2, 0x5, 0x7a,0x6d,0x11,0x9d,0x14,0xbd,0x1, 0x48,0xd, +0x7e,0x10,0x2, 0xac,0x1e,0x49,0x20,0x5, 0x7a,0xbd,0x21,0x58,0x8, 0x74,0x1, 0x7a, +0xb3,0x28,0xa7,0x80,0x6, 0xb, 0xf0,0xbc,0x7f,0x38,0xc9,0x12,0x82,0x35,0xe4,0x7a, +0xb3,0x28,0xa9,0x7e,0x37,0x28,0x88,0x2e,0x37,0x28,0x86,0xbe,0x37,0x28,0x9f,0x28, +0x6, 0x74,0x1, 0x7a,0xb3,0x28,0xa9,0x74,0x1, 0x7a,0xb3,0x28,0xaa,0x6c,0xff,0x80, +0x1f,0x12,0x82,0x22,0x49,0x25,0x25,0xf7,0x7d,0x43,0x9d,0x42,0x7d,0x34,0x12,0x1b, +0xfa,0xbe,0x37,0x28,0x9d,0x8, 0x7, 0xe4,0x7a,0xb3,0x28,0xaa,0x80,0xa, 0xb, 0xf0, +0x7e,0x73,0x28,0x84,0xbc,0x7f,0x38,0xd9,0x6c,0xff,0x80,0x9, 0x12,0x82,0x22,0x59, +0x35,0x25,0xf7,0xb, 0xf0,0x7e,0x73,0x28,0x84,0xbc,0x7f,0x38,0xef,0xda,0x79,0xda, +0xd8,0x22,0x7c,0xbf,0x12,0x80,0x77,0x74,0x2, 0xac,0xbf,0x22,0xa, 0x1d,0xa, 0x2a, +0x2d,0x21,0x3e,0x24,0x22,0xca,0x79,0xc2,0x0, 0x6c,0xee,0x7e,0x57,0x28,0x99,0x7d, +0xf5,0x7e,0xe7,0x28,0x97,0x7e,0x37,0x39,0xc9,0x4d,0x33,0x68,0x4, 0x7d,0xf5,0xe, +0xf4,0x6c,0xff,0x7e,0xa3,0x2a,0x6e,0x7c,0x8a,0x7e,0xb3,0x28,0xa5,0x14,0x68,0x21, +0x14,0x68,0x14,0x24,0xc2,0x68,0x8, 0x24,0xfb,0x68,0x16,0x24,0x45,0x78,0x10,0x7c, +0xfa,0x7e,0x83,0x2a,0x6d,0x80,0xa, 0x7e,0x73,0x2a,0x6d,0x2c,0x87,0x80,0x2, 0x6c, +0x88,0x6c,0x99,0x80,0xf, 0x7c,0xb9,0x12,0x80,0x77,0xbe,0x34,0x2, 0x58,0x8, 0x2, +0xb, 0xe0,0xb, 0x90,0x7e,0x73,0x28,0x84,0xbc,0x79,0x38,0xe9,0xbe,0xe0,0x3, 0x40, +0x2, 0x61,0x83,0x7e,0x63,0x28,0x85,0xbe,0x60,0x0, 0x38,0xb, 0xbe,0x70,0x0, 0x28, +0x37,0x7e,0xb3,0x26,0x83,0x70,0x31,0x6c,0x99,0x80,0x29,0xa, 0x19,0xa, 0xf, 0x2d, +0x1, 0x3e,0x4, 0x49,0x10,0x5, 0x7a,0xbd,0x1f,0x8, 0x17,0x49,0x10,0x4, 0xfc,0xbd, +0x1e,0x58,0xf, 0x6d,0x33,0x9d,0x3e,0x12,0x87,0xc4,0xbd,0x13,0x8, 0x4, 0xd2,0x0, +0x80,0x6, 0xb, 0x90,0xbc,0x89,0x38,0xd3,0x6d,0x55,0x9e,0x57,0x2a,0x4f,0xbe,0x57, +0x7, 0xf8,0x8, 0x2, 0xc2,0x0, 0x30,0x0, 0x20,0x7e,0xb3,0x3b,0x17,0x4, 0x7a,0xb3, +0x3b,0x17,0x7e,0x73,0x3b,0x17,0xbe,0x70,0xa, 0x28,0x1f,0x74,0xa, 0x7a,0xb3,0x3b, +0x17,0x74,0x1, 0x7a,0xb3,0x28,0xa8,0x80,0x11,0x7e,0x73,0x3b,0x17,0xbe,0x70,0x0, +0x28,0x8, 0x7c,0x97,0x1e,0x90,0x7a,0x93,0x3b,0x17,0x6c,0xaa,0x6c,0x99,0x80,0x17, +0xa, 0x39,0xa, 0xef,0x2d,0xe3,0x3e,0xe4,0x49,0xee,0x5, 0x7a,0xbd,0xef,0x8, 0x5, +0x7e,0xa0,0x1, 0x80,0x6, 0xb, 0x90,0xbc,0x89,0x38,0xe5,0x4c,0xaa,0x78,0x25,0x7e, +0xb3,0x3b,0x18,0x4, 0x7a,0xb3,0x3b,0x18,0x7e,0x73,0x3b,0x18,0xbe,0x70,0x5, 0x28, +0x22,0x74,0x5, 0x7a,0xb3,0x3b,0x18,0x7e,0xb3,0x28,0xa8,0x60,0x2, 0xd2,0x17,0x12, +0x87,0xdc,0x80,0xf, 0x7e,0x73,0x3b,0x18,0xbe,0x70,0x0, 0x28,0x6, 0x1e,0x70,0x7a, +0x73,0x3b,0x18,0xda,0x79,0x22,0xca,0xf8,0x7c,0xfb,0x7e,0x70,0x2, 0x12,0xa0,0xc1, +0x7f,0x71,0x7c,0xbf,0x12,0x80,0x77,0x12,0x83,0xa4,0x7f,0x17,0x12,0x19,0x4b,0x7c, +0xb7,0xda,0xf8,0x22,0x7d,0x13,0x1a,0x2, 0x1a,0x0, 0x22,0xca,0x3b,0x7c,0xfb,0x7f, +0x61,0x7f,0x40,0x9f,0x11,0x7f,0x51,0x7f,0x71,0x7a,0x1d,0x3c,0x7a,0x1d,0x40,0x7a, +0x1d,0x44,0xbe,0xf0,0xa, 0x78,0x6, 0x7e,0x54,0x1, 0x3c,0x80,0x4, 0x7e,0x54,0x2, +0x35,0x7a,0x57,0x23,0x43,0x6c,0xee,0x80,0x60,0xa, 0x5e,0x7f,0x14,0x12,0x84,0xfc, +0x7a,0x55,0x4a,0xa, 0x5e,0x7f,0x16,0x12,0x84,0xfc,0x7a,0x55,0x48,0x7e,0x35,0x48, +0x12,0x83,0xa4,0x2f,0x50,0x7e,0x65,0x4a,0x7d,0x16,0x1a,0x2, 0x1a,0x0, 0x2f,0x70, +0x12,0x83,0xa4,0x12,0x84,0xf2,0x7e,0x1d,0x3c,0x2f,0x10,0x7a,0x1d,0x3c,0x7d,0x16, +0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x4a,0x12,0x84,0xf2,0x7e,0x1d,0x40,0x2f,0x10,0x7a, +0x1d,0x40,0x7e,0x15,0x4a,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x48,0x12,0x84,0xf2,0x7e, +0x1d,0x44,0x2f,0x10,0x7a,0x1d,0x44,0xb, 0xe0,0xbc,0xfe,0x38,0x9c,0xa, 0xdf,0x6d, +0xcc,0x7f,0x15,0x7f,0x6, 0x12,0x19,0x4b,0x7f,0x51,0x7f,0x17,0x7f,0x6, 0x12,0x19, +0x4b,0x7f,0x71,0x7e,0x94,0x0, 0x64,0x7e,0x1d,0x3c,0x7d,0x19,0x12,0x18,0xef,0x7e, +0x87,0x23,0x43,0x7d,0x18,0x7d,0xd8,0x1a,0x12,0x1a,0xc2,0x7f,0x6, 0x12,0x19,0x4b, +0x7a,0x1d,0x3c,0x7e,0x1d,0x40,0x7d,0x19,0x12,0x18,0xef,0x7f,0x6, 0x12,0x19,0x4b, +0x7a,0x1d,0x40,0x7e,0x1d,0x44,0x7d,0x19,0x12,0x18,0xef,0x7d,0x18,0x1a,0x2, 0x1a, +0x0, 0x12,0x19,0x4b,0x7a,0x1d,0x44,0x7f,0x15,0x7f,0x7, 0x12,0x18,0xde,0x7e,0x6d, +0x44,0x9f,0x61,0x7f,0x15,0x7f,0x5, 0x12,0x18,0xde,0x7e,0x5d,0x3c,0x9f,0x51,0x7f, +0x17,0x7f,0x7, 0x12,0x18,0xde,0x7e,0x7d,0x40,0x9f,0x71,0xbe,0x58,0x0, 0x0, 0x68, +0x6, 0xbe,0x78,0x0, 0x0, 0x78,0x6, 0x7e,0x44,0x0, 0x64,0x80,0x18,0x7f,0x16,0x7d, +0x19,0x12,0x18,0xef,0x7f,0x5, 0x12,0x19,0x4b,0x7f,0x6, 0x12,0x18,0xde,0x7f,0x7, +0x12,0x19,0x4b,0x7d,0x43,0xbe,0x44,0x0, 0x0, 0x18,0x2, 0x6d,0x44,0x7c,0xb9,0xda, +0x3b,0x22,0x1a,0x26,0x1a,0x24,0x12,0x18,0xde,0x7f,0x1, 0x22,0x2d,0x35,0x7e,0x1b, +0x70,0xa, 0x57,0x22,0xca,0x3b,0xf5,0x2a,0x7f,0x31,0x7a,0xd, 0x26,0xe4,0x7a,0xb3, +0x22,0xf6,0x7a,0xb3,0x22,0xf7,0x7a,0xb3,0x22,0xf8,0x7e,0x34,0x3, 0xe8,0x7a,0x37, +0x22,0xfd,0x74,0x3c,0x7a,0xb3,0x22,0xf5,0x75,0x2f,0x46,0x75,0x2b,0x0, 0xc1,0xf5, +0x12,0x87,0x30,0x28,0x1e,0x7e,0x34,0x0, 0x44,0xca,0x39,0x7e,0x71,0x2b,0x74,0x44, +0xac,0x7b,0x2e,0x34,0x12,0xd4,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x22,0xff,0x12,0x1b, +0x93,0x1b,0xfd,0x6d,0x33,0x7a,0x37,0x22,0xf9,0x7a,0x35,0x30,0x7a,0x37,0x22,0xfb, +0x7a,0x35,0x32,0x7a,0x35,0x34,0x7e,0x34,0x22,0xff,0x7a,0x35,0x36,0x7e,0x34,0x23, +0x1f,0x7a,0x35,0x38,0x75,0x2c,0x0, 0x80,0x59,0xe5,0x2c,0xa, 0x3b,0x7e,0xd, 0x26, +0x12,0x87,0x38,0x2e,0x35,0x36,0x12,0x87,0x40,0x7d,0xd3,0x7e,0xc7,0x22,0xfb,0xbd, +0xcd,0x58,0x4, 0x7a,0xd7,0x22,0xfb,0xe5,0x2c,0xa, 0x3b,0x7f,0x3, 0x12,0x87,0x38, +0x2e,0x35,0x38,0x12,0x87,0x40,0x7d,0xc3,0x7e,0x35,0x32,0xbd,0x3c,0x58,0x3, 0x7a, +0xc5,0x32,0x7e,0x37,0x22,0xf9,0x2d,0x3d,0x7a,0x37,0x22,0xf9,0x7d,0x3c,0x2e,0x35, +0x30,0x7a,0x35,0x30,0x2d,0xcd,0x7e,0x35,0x34,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x34, +0x5, 0x2c,0xe5,0x2a,0xbe,0xb1,0x2c,0x38,0xa0,0xe5,0x2a,0xb4,0xa, 0x2a,0x7e,0x37, +0x22,0xfb,0xbe,0x34,0x0, 0x40,0x48,0xb, 0x7e,0x25,0x32,0xbe,0x24,0x0, 0x40,0x48, +0x2, 0xc1,0xf3,0xbe,0x34,0x0, 0x60,0x8, 0x2, 0xc1,0xf3,0x7e,0x35,0x32,0xbe,0x34, +0x0, 0x60,0x8, 0x2, 0xc1,0xf3,0x80,0x28,0x7e,0x37,0x22,0xfb,0xbe,0x34,0x0, 0x20, +0x8, 0xb, 0x7e,0x25,0x32,0xbe,0x24,0x0, 0x20,0x8, 0x2, 0xc1,0xf3,0xbe,0x34,0x0, +0x30,0x8, 0x2, 0xc1,0xf3,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x30,0x8, 0x2, 0xc1,0xf3, +0x7e,0xa3,0x3a,0xf, 0x74,0xc, 0xa4,0xbe,0x57,0x22,0xf9,0x58,0x2, 0xc1,0xf3,0x7e, +0xa3,0x3a,0x10,0x74,0xc, 0xa4,0xbe,0x55,0x30,0x58,0x2, 0xc1,0xf3,0x7e,0x15,0x36, +0x6d,0x0, 0x7e,0x1d,0x26,0xe5,0x2a,0x12,0x83,0xab,0x7a,0xb3,0x22,0xf4,0x7e,0x15, +0x38,0x6d,0x0, 0x7f,0x13,0xe5,0x2a,0x12,0x83,0xab,0xf5,0x2d,0x7e,0x73,0x22,0xf5, +0xbe,0x73,0x22,0xf4,0x38,0x7d,0xbe,0x71,0x2d,0x38,0x78,0xe5,0x2d,0x7e,0x31,0x2d, +0xac,0x3b,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x22,0xf4,0xac,0x77,0x1a,0x26,0x1a,0x24, +0x2f,0x10,0xe5,0x2d,0xa, 0x5b,0x6d,0x44,0x7e,0x33,0x22,0xf4,0xa, 0x13,0x6d,0x0, +0x2f,0x2, 0x12,0x18,0xfa,0x7c,0xb7,0xf5,0x2e,0xe5,0x2f,0xbe,0xb1,0x2e,0x38,0x43, +0x7e,0x37,0x22,0xfb,0x2e,0x35,0x32,0x2e,0x35,0x34,0x7a,0x35,0x3a,0xe5,0x2e,0xa, +0x2b,0x7e,0x34,0x0, 0x64,0x9d,0x32,0x3e,0x34,0x2e,0x35,0x3a,0x7a,0x35,0x3a,0x7e, +0x37,0x22,0xfd,0xbe,0x35,0x3a,0x8, 0x1b,0x7e,0x35,0x3a,0x7a,0x37,0x22,0xfd,0xe5, +0x2e,0x7a,0xb3,0x22,0xf7,0x7e,0x73,0x23,0x41,0x7a,0x73,0x22,0xf8,0xe5,0x2b,0x7a, +0xb3,0x22,0xf6,0x5, 0x2b,0x12,0x87,0x30,0x28,0x2, 0xa1,0x30,0x7e,0xa3,0x22,0xf7, +0xbe,0xa1,0x2f,0x40,0x20,0x7e,0xb3,0x22,0xf8,0xbe,0xb0,0x0, 0x28,0x17,0xbe,0xb0, +0xff,0x50,0x12,0x7e,0x73,0x22,0xf6,0xa, 0x37,0xb, 0x34,0x7a,0x73,0x3a,0xc, 0x7a, +0xb3,0x3a,0xe, 0x80,0x6, 0x74,0x7c,0x7a,0xb3,0x3a,0xc, 0x7c,0xba,0xda,0x3b,0x22, +0x7e,0x73,0x3b,0x13,0xbe,0x71,0x2b,0x22,0x2d,0x13,0x7e,0xb, 0x50,0xa, 0x25,0x22, +0x7e,0x39,0x70,0xa, 0x37,0x9d,0x32,0x2, 0x1b,0xfa,0xca,0xd8,0xca,0x79,0x6c,0xff, +0x6c,0xee,0x80,0xf, 0x7c,0xbe,0x12,0x83,0x86,0x7c,0xdb,0xbc,0xfd,0x58,0x2, 0x7c, +0xfd,0xb, 0xe0,0x12,0x87,0x6f,0x38,0xec,0x7c,0xbf,0xda,0x79,0xda,0xd8,0x22,0x7e, +0x73,0x28,0x84,0xbc,0x7e,0x22,0xca,0xf8,0x6c,0xff,0x80,0x17,0x7c,0xbf,0x12,0x80, +0x77,0xbe,0x37,0x2a,0x5c,0x58,0xa, 0x7c,0xbf,0x12,0x87,0xd3,0xac,0x7f,0x12,0x87, +0xa1,0xb, 0xf0,0x7e,0x73,0x28,0x84,0xbc,0x7f,0x38,0xe1,0x12,0x3b,0x2d,0xda,0xf8, +0x22,0x9, 0xb3,0x26,0xfa,0x9, 0x73,0x26,0xfb,0x7c,0x6b,0x7e,0xa3,0x37,0xb4,0x7e, +0x50,0x2, 0xac,0x5a,0x19,0x62,0x37,0xf1,0x19,0x72,0x37,0xf2,0x7c,0xba,0x4, 0x7a, +0xb3,0x37,0xb4,0x22,0x7e,0x24,0x0, 0x2, 0x2, 0x18,0xac,0x7e,0x73,0x28,0x84,0xbe, +0x70,0x0, 0x22,0x6c,0x77,0x12,0x3f,0x90,0x7e,0x70,0x2, 0x22,0xe4,0x7a,0xb3,0x28, +0xa8,0x7a,0xb3,0x3b,0x17,0x22,0x9, 0xb3,0x26,0xfa,0xf5,0x25,0x9, 0xb3,0x26,0xfb, +0xf5,0x26,0x22,0x7d,0xf3,0x6d,0xee,0x6c,0x99,0x80,0x3c,0x7c,0xb9,0x12,0x41,0xf4, +0x7d,0xd3,0x7d,0xcd,0x3e,0xc4,0x7f,0x57,0x2d,0xbc,0xb, 0x5a,0x10,0x1a,0x2, 0x1a, +0x0, 0x7e,0x83,0x2b,0x1c,0xa, 0x98,0x6d,0x88,0x7f,0x10,0x7f,0x4, 0x12,0x18,0xde, +0x74,0x6, 0x7f,0x1, 0x1e,0x14,0x1e,0x4, 0x50,0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4, +0x7d,0xc1,0x1b,0x5a,0xc0,0xb, 0x90,0x7e,0x83,0x2a,0x71,0xbc,0x89,0x38,0xbc,0x22, +0x7f,0x20,0xb, 0x2a,0x10,0xb, 0x1a,0x0, 0x1b,0x2a,0x0, 0x1b,0x1a,0x10,0x22,0xca, +0xf8,0x7e,0xa3,0x2a,0x2, 0x4c,0xaa,0x78,0x11,0x7e,0xb3,0x2a,0x3, 0xbe,0xb0,0x0, +0x28,0x13,0x74,0x1, 0x7a,0xb3,0x2a,0x7, 0x80,0xb, 0xbe,0xa0,0x0, 0x28,0x6, 0x74, +0x1, 0x7a,0xb3,0x2a,0xb, 0x12,0x8c,0x6c,0xca,0x59,0x7e,0x18,0x28,0xae,0x7e,0x8, +0x29,0x8, 0x12,0x1b,0x93,0x1b,0xfd,0x90,0x61,0x35,0xe4,0x93,0xbe,0xb0,0x0, 0x28, +0x23,0x6c,0xff,0x80,0x1a,0x12,0x8a,0xc9,0x12,0x5e,0x52,0x74,0x9, 0xac,0xbf,0x59, +0x35,0x29,0x8, 0x49,0x35,0x28,0xb0,0x12,0x88,0xb7,0x12,0x8a,0xf, 0xb, 0xf0,0x12, +0x57,0x10,0x38,0xe1,0xda,0xf8,0x22,0x7d,0xe3,0x9f,0x11,0x7e,0x14,0x61,0x43,0x12, +0x5d,0xa9,0x90,0x61,0x35,0xe4,0x93,0x70,0x3, 0x7d,0x3e,0x22,0x90,0x61,0x36,0xe4, +0x93,0xb4,0x1, 0x6, 0x7e,0x83,0x2a,0x6f,0x80,0x4, 0x7e,0x83,0x2a,0x70,0x12,0x5f, +0xd9,0xbe,0xe4,0x0, 0x3f,0x38,0x1e,0x7e,0x24,0x0, 0x3f,0x9d,0x2e,0x7e,0x14,0x61, +0x47,0x12,0x4f,0x39,0x12,0x89,0xf0,0x90,0x61,0x45,0x12,0x89,0xe7,0x48,0x2, 0x7f, +0x10,0x9f,0x1, 0x7f,0x10,0x12,0x77,0xc7,0xbe,0xa0,0x0, 0x28,0x36,0x7d,0x14,0x9e, +0x14,0x0, 0x3f,0xbd,0x1e,0x38,0x15,0x12,0x89,0xfb,0xbd,0x1e,0x40,0xe, 0x12,0x4f, +0x2b,0x12,0x89,0xda,0x48,0x34,0x7f,0x10,0x1b,0x1c,0x80,0x2e,0x12,0x89,0xfb,0xbd, +0x1e,0x50,0x31,0x7d,0x34,0x9e,0x34,0x0, 0x20,0x12,0x4f,0x31,0x12,0x89,0xf0,0x7d, +0x1f,0x80,0x1d,0x4c,0xaa,0x78,0x1d,0x12,0x5f,0xa3,0xbd,0x5e,0x38,0x16,0x12,0x4f, +0x2b,0x12,0x89,0xda,0x48,0x4, 0x7f,0x10,0x1b,0x1c,0xa, 0xb, 0x7d,0x1f,0x9d,0x10, +0x6d,0x0, 0x2f,0x10,0xbe,0xe4,0x0, 0x3f,0x28,0x6f,0x12,0x5f,0xa3,0xbd,0x5e,0x28, +0x68,0x7d,0xd4,0xb, 0xd4,0x1e,0xd4,0x7d,0x5d,0x1b,0x54,0xbd,0x5e,0x40,0xc, 0x7d, +0x35,0x9d,0x3e,0x6d,0x22,0x7e,0x14,0x61,0x4b,0x80,0xa, 0x7d,0x3e,0x9d,0x3d,0x6d, +0x22,0x7e,0x14,0x61,0x4d,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x10,0x12,0x18,0xef,0x12, +0x89,0xf4,0xbd,0x5e,0x7d,0x1f,0x40,0xc, 0x1e,0x14,0x1b,0x14,0x6d,0x0, 0x9f,0x1, +0x7f,0x10,0x80,0x6, 0x1e,0x14,0x6d,0x0, 0x2f,0x10,0x90,0x61,0x45,0x12,0x89,0xe7, +0x58,0x4, 0x7f,0x10,0x80,0x13,0x90,0x61,0x46,0xe4,0x93,0xa, 0xb, 0x7d,0x1f,0x9d, +0x10,0x6d,0x0, 0xbf,0x10,0x8, 0x2, 0x7f,0x10,0x22,0xad,0x32,0x6d,0x22,0x7c,0x76, +0x7c,0x65,0x1a,0x24,0x90,0x61,0x46,0xe4,0x93,0xa, 0x1b,0x6d,0x0, 0xbf,0x10,0x22, +0xad,0x32,0x6d,0x22,0x7c,0x76,0x7c,0x65,0x1a,0x24,0x22,0x7d,0x4, 0x9e,0x4, 0x0, +0x1f,0x7e,0xd4,0x60,0xd1,0x7e,0xc4,0x0, 0xff,0xb, 0x6a,0x10,0x2d,0x10,0x22,0x74, +0x9, 0xac,0xbf,0x59,0x35,0x29,0xa, 0x22,0xca,0xd8,0xca,0x79,0x7e,0x34,0x61,0x43, +0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x40,0x90,0x61,0x35,0xe4,0x93,0x70,0x2, 0x41,0xc4, +0x90,0x60,0xa7,0xe4,0x93,0x70,0x2, 0x41,0xc4,0x6c,0xff,0x41,0xbd,0x7e,0x70,0x9, +0xac,0x7f,0x9, 0xe3,0x29,0xc, 0x5e,0xe0,0xf, 0x49,0xc3,0x29,0xa, 0x7e,0x14,0x60, +0xd1,0x12,0x5f,0x55,0x2d,0x24,0xbd,0xc2,0x40,0x42,0x49,0xd3,0x29,0x8, 0x7d,0x3d, +0x12,0x8f,0x62,0x7c,0xdb,0x90,0x60,0xa7,0xe4,0x93,0xbc,0xbd,0x38,0xe, 0x7d,0x34, +0x1b,0x34,0x12,0x8a,0xf, 0x7c,0xbe,0x12,0x57,0x54,0x80,0x3f,0x7e,0x70,0x2, 0xac, +0x7d,0x2e,0x34,0x60,0xc5,0x12,0x5f,0xb1,0x74,0x9, 0xac,0xbf,0x59,0xd5,0x29,0x8, +0x7e,0x34,0x60,0xcf,0x12,0x1e,0x81,0x12,0x8a,0xf, 0x80,0x1f,0xbd,0xc4,0x40,0x1b, +0x7d,0x54,0x2e,0x54,0x0, 0xa, 0xbd,0xc5,0x40,0x5, 0x7c,0xbe,0x12,0x57,0x54,0x7d, +0xc4,0x1b,0xc4,0x74,0x9, 0xac,0xbf,0x59,0xc5,0x29,0xa, 0xb, 0xf0,0x12,0x57,0x10, +0x28,0x2, 0x41,0x3d,0xda,0x79,0xda,0xd8,0x22,0x74,0x9, 0xac,0xbf,0x49,0x35,0x28, +0xae,0x22,0xca,0xd8,0xca,0x79,0x6d,0x11,0x7e,0xe3,0x2a,0x2, 0x4c,0xee,0x78,0x23, +0x6c,0xff,0x80,0x1a,0x74,0x2, 0xac,0xbf,0x12,0x8c,0x5b,0x7e,0x70,0x9, 0xac,0x7f, +0x19,0xa3,0x31,0x53,0x74,0x2, 0xa, 0x3f,0x19,0xb3,0x31,0xbd,0xb, 0xf0,0x12,0x57, +0x10,0x38,0xe1,0x6c,0xff,0x81,0x32,0x74,0x9, 0xac,0xbf,0x9, 0x95,0x28,0xb2,0x5e, +0x90,0xf, 0x12,0x8c,0x77,0x38,0x2, 0x81,0x30,0xa, 0x19,0x9, 0xb1,0x29,0xbc,0xbe, +0xb0,0x1, 0x78,0x2, 0x81,0x16,0x6c,0x88,0x81,0x9, 0x74,0x9, 0xac,0xb8,0x9, 0xd5, +0x31,0x53,0xbc,0xd9,0x68,0x2, 0x81,0x7, 0x49,0x25,0x31,0x51,0x74,0x9, 0xac,0xbf, +0x49,0x35,0x28,0xb0,0x9d,0x32,0x12,0x1b,0xfa,0x7d,0x3, 0x74,0x9, 0xac,0xb8,0x49, +0x25,0x31,0x4f,0x12,0x8a,0xc9,0x9d,0x32,0x12,0x1b,0xfa,0x2d,0x3, 0xa, 0x1d,0x9, +0xa1,0x31,0xbd,0xbe,0xa0,0x0, 0x28,0x17,0x7e,0x30,0x2, 0xac,0x3d,0x59,0x1, 0x31, +0xa9,0xa, 0x1d,0x2e,0x14,0x31,0xbd,0x7c,0xba,0x14,0x7a,0x19,0xb0,0x81,0x30,0x74, +0x2, 0xac,0xbd,0x49,0x15,0x31,0xa9,0xbe,0x14,0x0, 0x32,0x28,0x8, 0xbe,0x4, 0x0, +0x32,0x28,0x2, 0x80,0x6c,0x7d,0x31,0x2e,0x34,0x0, 0x32,0xbd,0x30,0x50,0x8, 0xbe, +0x14,0x0, 0x32,0x28,0x2, 0x80,0x5a,0xbe,0x4, 0x0, 0xa0,0x28,0x50,0xa, 0x19,0x9, +0xb1,0x29,0xbc,0x70,0x4, 0x74,0x3, 0x80,0x2, 0x74,0x1, 0xa, 0x19,0x19,0xb1,0x29, +0xbc,0x74,0x3, 0xa, 0x1d,0x19,0xb1,0x29,0xc6,0xbe,0xe0,0x0, 0x28,0x62,0x1b,0xe0, +0x12,0x8f,0x4c,0x7e,0x14,0x1f,0x34,0x74,0x9, 0x12,0x19,0x7f,0x7e,0x70,0x9, 0xac, +0x7e,0x12,0x8d,0xe1,0xac,0x3f,0x12,0x8c,0x63,0x7e,0x34,0x1f,0x34,0x7e,0x30,0x9, +0xac,0x3e,0x12,0x8c,0x63,0x1b,0xf0,0x74,0x2, 0xac,0xbd,0x80,0x4, 0x74,0x2, 0xac, +0xbd,0x59,0x5, 0x31,0xa9,0x80,0x29,0xb, 0x80,0x90,0x60,0x99,0xe4,0x93,0xbc,0xb8, +0x28,0x2, 0x61,0x2a,0x80,0x1a,0x6d,0x11,0x74,0x2, 0xac,0xb9,0x12,0x8c,0x5b,0x7e, +0x30,0x9, 0xac,0x39,0x19,0xa1,0x31,0x53,0x74,0x2, 0xa, 0x19,0x19,0xb1,0x31,0xbd, +0xb, 0xf0,0xbc,0xef,0x28,0x2, 0x61,0x7, 0xe4,0x7a,0xb3,0x16,0x92,0x90,0x60,0x99, +0x12,0x8c,0x70,0xca,0x59,0x7e,0x18,0x28,0xae,0x7e,0x8, 0x31,0x4f,0x12,0x1b,0x93, +0x1b,0xfd,0x7a,0xe3,0x2a,0x2, 0xda,0x79,0xda,0xd8,0x22,0x59,0x15,0x31,0xa9,0x7e, +0xa0,0xff,0x22,0x2e,0x14,0x28,0xae,0x74,0x9, 0x2, 0x19,0x7f,0x90,0x60,0x99,0xe4, +0x93,0x7c,0xab,0x74,0x9, 0xa4,0x22,0x90,0x60,0x99,0xe4,0x93,0xbc,0xb9,0x22,0xca, +0x69,0xca,0xf8,0x7e,0xa3,0x2a,0x2, 0x7e,0x8, 0x29,0xbc,0x4c,0xaa,0x78,0x5, 0x12, +0x48,0x3b,0xa1,0x8f,0x6c,0x99,0xa1,0x88,0x7e,0x70,0x9, 0xac,0x79,0x9, 0x83,0x29, +0xc, 0xbe,0x80,0xff,0x78,0x2, 0xa1,0x86,0xa, 0x28,0x7f,0x70,0x2d,0xf2,0x7e,0x7b, +0xf0,0xbe,0xf0,0x2, 0x68,0x2, 0xa1,0x69,0x12,0x8d,0x9e,0x49,0x33,0x29,0x8, 0x12, +0x8d,0xd9,0x7e,0x70,0x4, 0xac,0x78,0x49,0x23,0x31,0xcb,0x12,0x8d,0x94,0x9d,0x32, +0x12,0x1b,0xfa,0x7d,0xe3,0x7e,0x73,0x2f,0xa5,0xa, 0x27,0xbd,0x2f,0x28,0x54,0xbd, +0x2e,0x28,0x50,0x12,0x8d,0x9e,0x7e,0xd0,0x9, 0xac,0xd9,0x59,0x26,0x29,0x8, 0x7e, +0x50,0x4, 0xac,0x58,0x49,0x22,0x31,0xcb,0x7e,0xd0,0x9, 0xac,0xd9,0x59,0x26,0x29, +0xa, 0xbe,0xa0,0x0, 0x28,0x2, 0x1b,0xa0,0x4c,0xaa,0x78,0x7a,0x7e,0xb3,0x30,0x0, +0x4, 0x7a,0xb3,0x30,0x0, 0x7e,0x63,0x30,0x0, 0xbe,0x60,0x32,0x40,0x68,0xe4,0x7a, +0xb3,0x30,0x0, 0x7e,0xb3,0x2f,0xa5,0xbe,0xb0,0x2, 0x50,0x5a,0x4, 0x7a,0xb3,0x2f, +0xa5,0x80,0x53,0x7e,0x50,0x9, 0xac,0x59,0x49,0xd2,0x29,0x8, 0x7e,0xd0,0x4, 0xac, +0xd8,0x59,0xd6,0x31,0xc9,0x49,0x22,0x29,0xa, 0x59,0x26,0x31,0xcb,0xbe,0x70,0x3, +0x40,0x4, 0x74,0x2, 0x80,0x8, 0xbe,0x70,0x1, 0x28,0x7, 0x7c,0xb7,0x14,0x7a,0xb3, +0x2f,0xa5,0xe4,0x7a,0xb3,0x30,0x0, 0x80,0x1d,0x4c,0xff,0x78,0x19,0x7e,0x70,0x9, +0xac,0x79,0x49,0x33,0x29,0x8, 0x7e,0x50,0x4, 0xac,0x58,0x59,0x32,0x31,0xc9,0x12, +0x8d,0x94,0x59,0x32,0x31,0xcb,0xb, 0x90,0x12,0x8c,0x77,0x28,0x2, 0x81,0x98,0xda, +0xf8,0xda,0x69,0x22,0x7e,0x70,0x9, 0xac,0x79,0x49,0x33,0x29,0xa, 0x22,0x7e,0x50, +0x4, 0xac,0x58,0x49,0x22,0x31,0xc9,0x22,0x12,0x8c,0x7f,0x2, 0x8d,0xae,0x7e,0xb3, +0x2a,0x9, 0x70,0x24,0x7e,0xa3,0x30,0x15,0x4c,0xaa,0x78,0x3, 0xe4,0x80,0x7, 0xbe, +0xa0,0x2, 0x78,0x6, 0x74,0x3, 0x7a,0xb3,0x30,0x20,0x7e,0x73,0x30,0x21,0xbe,0x73, +0x30,0x20,0x28,0x4, 0x7a,0x73,0x30,0x20,0x22,0x9d,0x32,0x12,0x1b,0xfa,0x7d,0xf3, +0x22,0x2e,0x34,0x28,0xae,0x7e,0x30,0x9, 0x22,0xca,0xd8,0xca,0x79,0x7c,0xdb,0x90, +0x60,0x99,0xe4,0x93,0x7c,0xfb,0x6c,0x11,0x80,0x21,0x7e,0x0, 0xff,0x74,0x9, 0xac, +0xb1,0x19,0x5, 0x1f,0x38,0x7e,0x34,0x7f,0xff,0x74,0x9, 0xac,0xb1,0x59,0x35,0x1f, +0x34,0x74,0x9, 0xac,0xb1,0x59,0x35,0x1f,0x36,0xb, 0x10,0xbc,0xf1,0x38,0xdb,0xe4, +0x6c,0x77,0x7c,0x6d,0x12,0x8f,0x42,0x7c,0x7d,0x7c,0x6f,0x12,0x8f,0x42,0x6c,0x0, +0x80,0x39,0x6c,0xee,0x80,0x16,0x74,0x9, 0xac,0xbe,0x9, 0x65,0x1f,0x38,0x74,0x9, +0xac,0xb0,0x9, 0x75,0x28,0xb2,0xbc,0x76,0x68,0x6, 0xb, 0xe0,0xbc,0x1e,0x38,0xe6, +0xbc,0x1e,0x78,0x15,0x7e,0x70,0x9, 0xac,0x70,0x12,0x8d,0xe1,0xac,0x31,0x2e,0x14, +0x1f,0x34,0x74,0x9, 0x12,0x19,0x7f,0xb, 0x10,0xb, 0x0, 0xbc,0xf0,0x38,0xc3,0x74, +0x9, 0xac,0xbf,0xca,0x59,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x29,0x62,0x12,0x1b,0x93, +0x1b,0xfd,0xda,0x79,0xda,0xd8,0x22,0xca,0x3b,0x7c,0x46,0x7c,0xab,0x6c,0x66,0xe1, +0x2a,0x7c,0x57,0xe1,0x22,0x7e,0xf0,0x9, 0xac,0xf6,0x9, 0x87,0x29,0x66,0x7c,0x98, +0x7e,0xd0,0x9, 0xac,0xd5,0x9, 0xb6,0x28,0xb2,0xbc,0xb9,0x78,0x73,0xbe,0x90,0xff, +0x68,0x6e,0x12,0x8f,0x3a,0x2d,0xf7,0x39,0x87,0x0, 0x4, 0xa, 0xf9,0x9, 0xbf,0x29, +0xbc,0x7e,0xf0,0x9, 0x70,0xc, 0xac,0xf5,0x7d,0x97,0x2e,0x94,0x28,0xae,0x6d,0x88, +0x80,0xa, 0xac,0xf6,0x7d,0x97,0x2e,0x94,0x29,0x62,0x6d,0x88,0xb, 0x4a,0xd0,0x12, +0x8f,0x3a,0x2d,0xf7,0x1b,0x7a,0xd0,0x69,0xf4,0x0, 0x2, 0x7e,0xf0,0x9, 0xac,0xfa, +0x7f,0x60,0x2d,0xd7,0x79,0xf6,0x0, 0x2, 0x7e,0xf0,0x9, 0xac,0xf5,0x9, 0x87,0x28, +0xb3,0x12,0x8f,0x3a,0x2d,0xf7,0x39,0x87,0x0, 0x5, 0x7e,0xf0,0x9, 0xac,0xf5,0x9, +0x87,0x28,0xb4,0x12,0x8f,0x3a,0x2d,0xf7,0x39,0x87,0x0, 0x6, 0xb, 0xa0,0x80,0x8, +0xb, 0x50,0xbc,0x45,0x28,0x2, 0xc1,0x95,0xb, 0x60,0x90,0x60,0x99,0xe4,0x93,0xbc, +0xb6,0x28,0x2, 0xc1,0x91,0x7c,0xba,0xda,0x3b,0x22,0x7e,0xf0,0x9, 0xac,0xfa,0x7f, +0x70,0x22,0x7e,0x8, 0x1f,0x34,0x12,0x8e,0x87,0x7c,0x1b,0x22,0x7e,0x70,0x9, 0xac, +0x7f,0x2e,0x34,0x28,0xae,0x22,0x7e,0xb3,0x38,0xff,0x70,0x3, 0x12,0x8a,0xd2,0x2, +0x57,0x7f,0x6c,0xaa,0x80,0x23,0x7e,0x30,0x4, 0xac,0x3a,0x7d,0xf1,0x2e,0xf4,0x60, +0xb1,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x20,0xbd,0x23,0x38,0xb, 0x2e,0x14,0x60,0xb3, +0x12,0x5f,0x55,0xbd,0x23,0x50,0xb, 0xb, 0xa0,0x90,0x60,0xa7,0xe4,0x93,0xbc,0xba, +0x38,0xd4,0x7c,0xba,0x22,0x2, 0x8f,0x98,0xca,0x79,0x6c,0xff,0x7e,0xd7,0x2a,0x5a, +0x6c,0xee,0x80,0x35,0x7c,0xbe,0x12,0x80,0x77,0xbd,0x3d,0x48,0x2a,0x7c,0xbe,0x12, +0x3f,0x74,0x60,0x23,0x7e,0xc4,0x0, 0x9, 0xca,0xc9,0x7e,0x70,0x9, 0xac,0x7e,0x2e, +0x34,0x27,0x76,0x6d,0x22,0x7e,0x30,0x9, 0xac,0x3f,0x2e,0x14,0x28,0xae,0x6d,0x0, +0x12,0x1b,0x93,0x1b,0xfd,0xb, 0xf0,0xb, 0xe0,0x12,0x87,0x6f,0x38,0xc6,0x7a,0x73, +0x28,0x93,0x7a,0xf3,0x2a,0x2, 0xda,0x79,0x22,0x7d,0x13,0x7d,0x32,0x6d,0x22,0x74, +0x6, 0x2f,0x11,0x14,0x78,0xfb,0xb, 0x14,0x12,0x18,0xf8,0x7d,0x53,0xbe,0x54,0x0, +0xff,0x28,0x4, 0x7e,0x54,0x0, 0x40,0x22,0x7a,0x37,0x1f,0x38,0x7e,0x34,0x15,0xa8, +0x7a,0x37,0x1f,0x3c,0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f,0x3a,0x7e,0x73,0x2a,0x6f, +0x7a,0x73,0x1f,0x35,0x7e,0x73,0x2a,0x70,0x7a,0x73,0x1f,0x34,0x7e,0x37,0x2a,0x5c, +0x7a,0x37,0x1f,0x3e,0x7e,0x37,0x2a,0x5e,0x7a,0x37,0x1f,0x40,0x7e,0x37,0x2a,0x60, +0x7a,0x37,0x1f,0x42,0x74,0x1, 0x7a,0xb3,0x1f,0x36,0x7a,0xb3,0x1f,0x37,0x7e,0x8, +0x1f,0x34,0x7e,0x18,0x1f,0x44,0x12,0x6, 0x52,0x7e,0x37,0x1f,0x4e,0x7e,0x27,0x1f, +0x4a,0xbd,0x23,0x28,0x2, 0x7d,0x32,0x22,0x7e,0x34,0x61,0x59,0x2, 0x1e,0x81,0x7e, +0xb3,0x38,0xd4,0x70,0x37,0x7e,0x73,0x38,0xb7,0xbe,0x70,0x10,0x40,0x2, 0x6c,0x77, +0x7e,0xb3,0x38,0xff,0xb4,0x1, 0x8, 0x74,0x6, 0x7a,0xb3,0x38,0xb7,0x80,0x4, 0x7a, +0x73,0x38,0xb7,0xa, 0x37,0x2e,0x34,0x1b,0xca,0x12,0x90,0xcb,0x7c,0xab,0xe5,0x5b, +0xa, 0x3b,0x2e,0x37,0x3a,0x8f,0x7a,0x37,0x3a,0x8f,0x80,0xc, 0x7e,0xa3,0x38,0xb8, +0xbe,0xa0,0x7f,0x28,0x3, 0x7e,0xa0,0x7f,0x7c,0xba,0x2, 0x90,0xbd,0x75,0x5b,0x0, +0x7a,0xb3,0x3, 0xfe,0xc2,0x19,0x22,0x2e,0x34,0x1b,0x4d,0x7a,0x71,0x82,0x7a,0x61, +0x83,0xe4,0x93,0x22,0x7e,0xb3,0x3a,0x92,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x7a, +0xb3,0x3a,0x92,0x22,0x7f,0x20,0xc2,0x1, 0x7e,0x2b,0x60,0x29,0x72,0x0, 0x2, 0x9c, +0x76,0x1a,0x37,0x12,0x1b,0xfa,0x7c,0x27,0x29,0x72,0x0, 0x1, 0x29,0x32,0x0, 0x3, +0x9c,0x37,0x1a,0x33,0x12,0x1b,0xfa,0x7c,0x37,0x1a,0x23,0x1a,0x32,0x9d,0x32,0x12, +0x1b,0xfa,0x7c,0x67,0x7c,0x72,0xbc,0x32,0x58,0x2, 0x7c,0x73,0xbe,0x60,0x5, 0x18, +0x5, 0xbe,0x70,0x6, 0x58,0x8, 0x7e,0x37,0x39,0xc1,0x4d,0x33,0x68,0x2, 0xd2,0x1, +0xa2,0x1, 0x22,0xca,0xd8,0xca,0x79,0xc2,0x0, 0x6d,0x88,0x7a,0x87,0x3a,0xa, 0xe4, +0x7a,0xb3,0x1f,0x58,0xe5,0x1e,0xbe,0xb0,0xff,0x50,0x2, 0x5, 0x1e,0x7e,0xb3,0x28, +0x84,0x60,0xc, 0x12,0x7c,0x92,0xb, 0x1a,0x80,0xbe,0x87,0x7, 0xfa,0x28,0xa, 0xc2, +0x12,0x6d,0x88,0x7a,0x87,0x39,0xcb,0x41,0x64,0x12,0x96,0x4c,0x60,0x12,0x7e,0x34, +0x62,0xe, 0x12,0x5f,0xb9,0x7a,0x87,0x39,0xc1,0x12,0x92,0xce,0x7a,0x87,0x39,0xcb, +0x7e,0x87,0x39,0xc1,0x4d,0x88,0x68,0x6, 0x74,0x1, 0x7a,0xb3,0x28,0xa9,0x6c,0xff, +0x80,0x77,0xe4,0xa, 0x3f,0x19,0xb3,0x1f,0x34,0x12,0x92,0xe8,0x7e,0x8, 0x1f,0x52, +0x7c,0xbd,0x7c,0x7e,0x12,0x93,0x5f,0x7d,0x93,0x7e,0x87,0x39,0xcb,0xbd,0x89,0x50, +0x4, 0x7a,0x97,0x39,0xcb,0x7e,0x87,0x3a,0xa, 0xbd,0x89,0x50,0x4, 0x7a,0x97,0x3a, +0xa, 0xe5,0x1e,0xbe,0xb0,0x5, 0x38,0x1f,0x7e,0x8, 0x39,0xcd,0x12,0x93,0x19,0x50, +0x7, 0x12,0x92,0xdf,0xd2,0x0, 0x80,0x2f,0x7e,0x8, 0x39,0xcd,0x7e,0x18,0x1f,0x52, +0x12,0x95,0xe4,0x50,0x22,0x80,0x10,0x12,0x92,0xce,0xbd,0x89,0x38,0x19,0x7e,0x8, +0x1f,0x52,0x12,0x90,0xe4,0x50,0x10,0x12,0x92,0xdf,0x7e,0x8, 0x1f,0x58,0x7e,0x18, +0x1f,0x52,0x12,0x96,0x26,0xd2,0x0, 0xb, 0xf0,0x7e,0x73,0x28,0x84,0xbc,0x7f,0x38, +0x81,0x30,0x0, 0x36,0x6c,0xff,0x80,0x1c,0x12,0x92,0xe8,0x7e,0x8, 0x1f,0x58,0x12, +0x93,0x19,0x40,0x9, 0xa, 0x3f,0x9, 0xb3,0x1f,0x34,0xb4,0x1, 0x5, 0x7c,0xbf,0x12, +0x92,0xf5,0xb, 0xf0,0x7e,0x73,0x28,0x84,0xbc,0x7f,0x38,0xdc,0x75,0x1e,0x0, 0x7e, +0x34,0x62,0xe, 0x12,0x1e,0x81,0x7a,0x37,0x39,0xc1,0x7e,0x63,0x1f,0x58,0x7e,0x70, +0x6, 0xac,0x67,0xb, 0x34,0xca,0x39,0x7e,0x18,0x1f,0x58,0x7e,0x8, 0x39,0xcd,0x12, +0x1b,0x93,0x1b,0xfd,0x7e,0x37,0x39,0xc1,0x4d,0x33,0x78,0x39,0x90,0x62,0x9, 0xe4, +0x93,0xa, 0x3b,0xbe,0x37,0x39,0xcb,0x38,0x43,0x7c,0x7b,0x1e,0x70,0xa, 0x37,0xbe, +0x37,0x3a,0xa, 0x38,0x37,0x90,0x60,0x51,0x12,0x92,0xd6,0x7e,0x73,0x26,0xf7,0xa, +0x37,0xbd,0x32,0x8, 0x27,0x90,0x60,0x50,0x12,0x92,0xd6,0x7e,0x73,0x26,0xf6,0xa, +0x37,0xbd,0x32,0x8, 0x17,0x6c,0xff,0x80,0x7, 0x7c,0xbf,0x12,0x92,0xf5,0xb, 0xf0, +0x7e,0x73,0x28,0x84,0xbc,0x7f,0x38,0xf1,0xd2,0x0, 0x80,0x6, 0x6d,0x33,0x7a,0x37, +0x39,0xcb,0xa2,0x0, 0x92,0x12,0x12,0x95,0xcd,0xda,0x79,0xda,0xd8,0x22,0x90,0x62, +0x9, 0xe4,0x93,0xa, 0x8b,0x22,0xe4,0x93,0x7c,0x7b,0x1e,0x70,0xa, 0x27,0x22,0x74, +0x1, 0xa, 0x8f,0x19,0xb8,0x1f,0x34,0x22,0x74,0x2, 0xac,0xbf,0x9, 0xd5,0x26,0xfa, +0x9, 0xe5,0x26,0xfb,0x22,0x7c,0xab,0x7e,0xb3,0x3b,0x17,0x70,0x1b,0x7e,0xb3,0x28, +0xa8,0x70,0x15,0x12,0x96,0x1e,0x68,0x10,0x7e,0xb3,0x2a,0x6b,0xbe,0xb0,0x1, 0x68, +0x7, 0x7c,0xba,0x6c,0x77,0x2, 0x3f,0x90,0x22,0x7c,0xbd,0x7c,0x7e,0x7c,0x6b,0xc2, +0x1, 0x6c,0xaa,0x80,0x30,0x7e,0x50,0x6, 0xac,0x5a,0x7f,0x70,0x2d,0xf2,0xb, 0xf4, +0x29,0xb7,0x0, 0x2, 0xbc,0xb6,0x40,0x1b,0x7e,0x7b,0xb0,0xbc,0xb6,0x38,0x14,0x29, +0xb7,0x0, 0x3, 0xbc,0xb7,0x40,0xc, 0x29,0xb7,0x0, 0x1, 0xbc,0xb7,0x38,0x4, 0xd2, +0x1, 0x80,0x9, 0xb, 0xa0,0x7e,0xb, 0xb0,0xbc,0xba,0x38,0xc9,0xa2,0x1, 0x22,0xca, +0x3b,0x7c,0xc7,0x7c,0xfb,0x7f,0x40,0x6d,0x33,0x7a,0x35,0x24,0x7f,0x4, 0x7e,0x34, +0x0, 0x6, 0xe4,0x12,0x1b,0xb8,0x7e,0x73,0x2a,0x6d,0xa, 0x37,0x1b,0x34,0x7a,0x4b, +0x70,0x7e,0x73,0x2a,0x6e,0xa, 0x37,0x1b,0x34,0x39,0x74,0x0, 0x1, 0x7c,0xec,0x80, +0x1f,0x75,0x26,0x0, 0x7c,0xdf,0x80,0xd, 0x12,0x95,0xbb,0x12,0x94,0x53,0x70,0xa, +0x12,0x95,0xc2,0x1b,0xd0,0xbe,0xd0,0x0, 0x58,0xee,0xe5,0x26,0x60,0x7, 0x1b,0xe0, +0xbe,0xe0,0x0, 0x58,0xdc,0x7c,0xec,0x80,0x26,0x75,0x26,0x0, 0x1a,0x3f,0xb, 0x34, +0x7c,0xd7,0x80,0xd, 0x12,0x95,0xbb,0x12,0x94,0x53,0x70,0xd, 0x12,0x95,0xc2,0xb, +0xd0,0x7e,0x73,0x2a,0x6d,0xbc,0x7d,0x18,0xeb,0xe5,0x26,0x60,0x7, 0x1b,0xe0,0xbe, +0xe0,0x0, 0x58,0xd5,0x1a,0x3c,0xb, 0x34,0x7c,0xe7,0x80,0x1f,0x75,0x26,0x0, 0x7c, +0xdf,0x80,0xd, 0x12,0x95,0xbb,0x12,0x94,0x53,0x70,0xa, 0x12,0x95,0xc2,0x1b,0xd0, +0xbe,0xd0,0x0, 0x58,0xee,0xe5,0x26,0x60,0xa, 0xb, 0xe0,0x7e,0x73,0x2a,0x6e,0xbc, +0x7e,0x18,0xd9,0x1a,0x3c,0xb, 0x34,0x7c,0xe7,0x80,0x24,0x75,0x26,0x0, 0x1a,0x6f, +0xb, 0x64,0x80,0xd, 0x12,0x95,0xbb,0x12,0x94,0x53,0x70,0xd, 0x12,0x95,0xc2,0xb, +0xd0,0x7e,0x73,0x2a,0x6d,0xbc,0x7d,0x18,0xeb,0xe5,0x26,0x60,0xa, 0xb, 0xe0,0x7e, +0x73,0x2a,0x6e,0xbc,0x7e,0x18,0xd4,0x7e,0x35,0x24,0x7d,0x23,0x39,0x54,0x0, 0x5, +0xda,0x3b,0x22,0xca,0x3b,0x7f,0x70,0x7c,0xe7,0x7c,0xdb,0x7e,0xc0,0x4, 0x7e,0x34, +0x62,0xa, 0x12,0x5f,0xb1,0x6c,0xff,0x12,0x6e,0x28,0x7f,0x51,0xb, 0x5a,0x30,0x7e, +0x14,0x62,0xa, 0x12,0x5f,0x55,0xbd,0x32,0x8, 0xc, 0x7e,0x27,0x28,0x8a,0xbe,0x24, +0x3, 0x20,0x8, 0x2, 0xa1,0x7d,0xb, 0xa, 0xc0,0x1e,0xc4,0xbd,0x3c,0x8, 0xc, 0x7e, +0xc7,0x28,0x8a,0xbe,0xc4,0x3, 0x20,0x58,0x2, 0xa1,0x7d,0x6c,0xaa,0x7c,0x8d,0x80, +0x1e,0x7c,0x9e,0xbe,0x80,0x0, 0x48,0x13,0x7e,0xb3,0x2a,0x6d,0xbc,0xb8,0x8, 0xb, +0x12,0x95,0xb4,0xbd,0x3d,0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0x1b,0x80,0x1a, +0x2c,0x1a,0x3d,0x9d,0x32,0x1a,0xc8,0xbd,0xc3,0x18,0xd6,0xbc,0xca,0x18,0x5, 0x4e, +0xf0,0x1, 0xa1,0x7d,0x6c,0xaa,0x7c,0x8d,0x80,0x1e,0x7c,0x9e,0xbe,0x80,0x0, 0x48, +0x13,0x7e,0xb3,0x2a,0x6d,0xbc,0xb8,0x8, 0xb, 0x12,0x95,0xb4,0xbd,0x3d,0x58,0x14, +0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0xb, 0x80,0x1a,0x2c,0x1a,0x3d,0x2d,0x32,0x1a,0xc8, +0xbd,0xc3,0x48,0xd6,0xbc,0xca,0x18,0x5, 0x4e,0xf0,0x2, 0x80,0x70,0x6c,0xaa,0x7c, +0x9e,0x80,0x1e,0x7c,0x8d,0xbe,0x90,0x0, 0x48,0x13,0x7e,0xb3,0x2a,0x6e,0xbc,0xb9, +0x8, 0xb, 0x12,0x95,0xb4,0xbd,0x3d,0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0x1b, +0x90,0x1a,0x2c,0x1a,0x3e,0x9d,0x32,0x1a,0xc9,0xbd,0xc3,0x18,0xd6,0xbc,0xca,0x18, +0x5, 0x4e,0xf0,0x4, 0x80,0x37,0x6c,0xaa,0x7c,0x9e,0x80,0x1e,0x7c,0x8d,0xbe,0x90, +0x0, 0x48,0x13,0x7e,0xb3,0x2a,0x6e,0xbc,0xb9,0x8, 0xb, 0x12,0x95,0xb4,0xbd,0x3d, +0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0xb, 0x90,0x1a,0x2c,0x1a,0x3e,0x2d,0x32, +0x1a,0xc9,0xbd,0xc3,0x48,0xd6,0xbc,0xca,0x18,0x3, 0x4e,0xf0,0x8, 0x4c,0xff,0x68, +0x2e,0x7e,0x7b,0xb0,0xbc,0xbd,0x40,0x3, 0x7a,0x7b,0xd0,0x29,0xb7,0x0, 0x2, 0xbc, +0xbd,0x38,0x4, 0x39,0xd7,0x0, 0x2, 0x29,0xb7,0x0, 0x1, 0xbc,0xbe,0x40,0x4, 0x39, +0xe7,0x0, 0x1, 0x29,0xb7,0x0, 0x3, 0xbc,0xbe,0x38,0x4, 0x39,0xe7,0x0, 0x3, 0x7c, +0xbf,0xda,0x3b,0x22,0x7c,0xb8,0x7c,0x79,0x2, 0x3b,0x73,0x7c,0xbd,0x7c,0x7e,0x7f, +0x4, 0x22,0x5, 0x26,0x7e,0x35,0x24,0xb, 0x34,0x7a,0x35,0x24,0x22,0x30,0x12,0x13, +0x12,0x96,0x16,0x68,0x6, 0x7e,0xb3,0x3b,0x17,0x60,0x8, 0x7e,0x34,0xb, 0xb8,0x7a, +0x37,0x39,0xc9,0x22,0x7f,0x61,0x7f,0x50,0x7e,0x6b,0x90,0x80,0x1f,0x29,0x86,0x0, +0x1, 0x80,0xf, 0x7f,0x5, 0x7c,0xb9,0x7c,0x78,0x12,0x93,0x1d,0x50,0x2, 0xd3,0x22, +0xb, 0x80,0x29,0x76,0x0, 0x3, 0xbc,0x78,0x50,0xe9,0xb, 0x90,0x29,0x76,0x0, 0x2, +0xbc,0x79,0x50,0xd9,0xc3,0x22,0x7e,0xb3,0x28,0xa8,0xbe,0xb0,0x1, 0x22,0x7e,0xb3, +0x38,0xff,0xbe,0xb0,0x1, 0x22,0x7f,0x60,0x7e,0x6b,0xa0,0xbe,0xa0,0xa, 0x50,0x1b, +0x7e,0x14,0x0, 0x6, 0xca,0x19,0x74,0x6, 0xa4,0x7f,0x6, 0x2d,0x15,0xb, 0x14,0x12, +0x1b,0x93,0x1b,0xfd,0x7e,0x6b,0xb0,0x4, 0x7a,0x6b,0xb0,0x22,0x6c,0xaa,0x7e,0x63, +0x2a,0x6e,0x7e,0x73,0x2a,0x6d,0xac,0x76,0x7d,0x13,0x1e,0x14,0x7e,0x27,0x28,0x88, +0x2e,0x27,0x28,0x86,0xbd,0x21,0x38,0xa, 0x1e,0x34,0x1e,0x34,0xbe,0x37,0x28,0x86, +0x50,0x29,0x90,0x60,0x51,0xe4,0x93,0x1e,0xb0,0xa, 0x2b,0x7e,0xb3,0x26,0xf7,0xa, +0x3b,0xbd,0x32,0x8, 0x16,0x90,0x60,0x50,0xe4,0x93,0x1e,0xb0,0xa, 0x2b,0x7e,0xb3, +0x26,0xf6,0xa, 0x3b,0xbd,0x32,0x8, 0x3, 0x7e,0xa0,0x1, 0x7c,0xba,0x22,0x12,0x97, +0xb, 0x38,0x2f,0xbe,0xa3,0x2a,0x2, 0x50,0x19,0x7e,0xb3,0x2a,0xc, 0xbe,0xb3,0x31, +0xc8,0x28,0x14,0x7e,0xb3,0x31,0xc8,0x4, 0x7a,0xb3,0x31,0xc8,0x7a,0xa3,0x2a,0x2, +0x80,0x5, 0xe4,0x7a,0xb3,0x31,0xc8,0x7e,0xb3,0x2a,0x2, 0x70,0x5, 0xe4,0x7a,0xb3, +0x2a,0xb, 0x22,0x12,0x96,0xd9,0x2, 0x96,0x9e,0x7e,0xb3,0x2a,0x2, 0x70,0x22,0x12, +0x97,0xb, 0x28,0x1d,0x7e,0xb3,0x30,0x36,0x70,0x11,0x7a,0xa3,0x2a,0x2, 0x74,0x1, +0x7a,0xb3,0x2a,0x9, 0x7e,0xb3,0x30,0x36,0x4, 0x80,0x1, 0xe4,0x7a,0xb3,0x30,0x36, +0x22,0xe4,0x7a,0xb3,0x30,0x36,0x7a,0xb3,0x2a,0x9, 0x22,0x7e,0xa3,0x2a,0x3, 0xbe, +0xa0,0x0, 0x22,0xca,0x3b,0x7c,0xfb,0x6c,0xee,0x80,0x6d,0x6c,0xdd,0x80,0x16,0x74, +0x9, 0xac,0xbd,0x9, 0x65,0x29,0x66,0x74,0x9, 0xac,0xbe,0x9, 0x75,0x28,0xb2,0xbc, +0x67,0x68,0x7, 0xb, 0xd0,0x12,0x97,0x8f,0x38,0xe5,0x12,0x97,0x8f,0x28,0x4d,0x74, +0x9, 0xac,0xbd,0x9, 0xc5,0x29,0x66,0x12,0x5b,0xfc,0x74,0x9, 0xac,0xbd,0x12,0x97, +0x97,0x9d,0x32,0x12,0x1b,0xfa,0x2d,0x31,0x7a,0x35,0x24,0xa, 0x3c,0x9, 0xb3,0x29, +0xbc,0xb4,0x1, 0xe, 0x6d,0x33,0x74,0x2, 0xac,0xbc,0x59,0x35,0x30,0x1, 0x59,0x35, +0x30,0x22,0x7e,0x35,0x24,0x7c,0xbd,0x7c,0x5e,0x7c,0x4c,0x12,0x9a,0x8a,0x7a,0x35, +0x24,0x7c,0xbd,0x12,0x5f,0xa0,0xb, 0xe0,0xbc,0xfe,0x38,0x8f,0xda,0x3b,0x22,0x90, +0x60,0x99,0xe4,0x93,0xbc,0xbd,0x22,0x49,0x25,0x29,0x62,0x74,0x9, 0xac,0xbe,0x49, +0x35,0x28,0xae,0x22,0x7e,0xa3,0x2a,0x2, 0x6c,0x77,0x80,0x34,0x7e,0x90,0x9, 0xac, +0x97,0x9, 0x64,0x29,0x66,0xa, 0x26,0x9, 0xb2,0x29,0xbc,0x70,0x21,0x7e,0x30,0x1, +0x7e,0x50,0x9, 0xac,0x56,0x19,0x32,0x2f,0xa9,0x49,0x14,0x28,0xae,0x59,0x12,0x2f, +0xaa,0x49,0x14,0x28,0xb0,0x59,0x12,0x2f,0xac,0xe4,0x19,0xb2,0x2f,0xae,0xb, 0x70, +0xbc,0xa7,0x38,0xc8,0x22,0x7c,0xab,0x7e,0xb, 0xb0,0x60,0x3, 0xb4,0x2, 0x31,0xa, +0x4a,0x9, 0x74,0x30,0x16,0xbe,0x73,0x30,0x20,0x50,0xe, 0x7d,0x24,0x2e,0x24,0x30, +0x16,0x7c,0xb7,0x4, 0x7a,0x29,0xb0,0xd3,0x22,0xbe,0x73,0x30,0x20,0x40,0x9, 0xbe, +0x70,0xff,0x68,0x4, 0xe4,0x7a,0xb, 0xb0,0x74,0xff,0x19,0xb4,0x30,0x16,0x80,0x17, +0xa, 0x3a,0x9, 0xb3,0x30,0x16,0xbe,0xb0,0xff,0x68,0x7, 0xe4,0x19,0xb3,0x30,0x16, +0xd3,0x22,0xe4,0x19,0xb3,0x30,0x16,0xc3,0x22,0xca,0xf8,0x7c,0xfb,0x7d,0xf3,0x7e, +0x17,0x2a,0x62,0xbd,0x13,0x38,0x6, 0x7e,0x34,0x1, 0x0, 0x80,0x15,0x6d,0x22,0x7c, +0x56,0x7c,0x67,0x6c,0x77,0x12,0x18,0xf8,0xbe,0x34,0x0, 0x8, 0x50,0x4, 0x7e,0x34, +0x0, 0x8, 0x74,0x2, 0xac,0xbf,0x49,0x25,0x30,0x22,0xbd,0x2f,0x28,0x6, 0x49,0x35, +0x30,0x1, 0x80,0x4, 0x59,0x35,0x30,0x1, 0x59,0xf5,0x30,0x22,0xbe,0x34,0x1, 0x0, +0x28,0x4, 0x7e,0x34,0x1, 0x0, 0xbe,0x34,0x0, 0x20,0x50,0x15,0x7e,0x50,0x9, 0xac, +0x5f,0x9, 0xb2,0x2f,0xae,0xb4,0x1, 0x9, 0x7e,0x34,0x1, 0x0, 0xe4,0x19,0xb2,0x2f, +0xae,0xbe,0x34,0x0, 0x40,0x28,0xc, 0x7e,0xa0,0x1, 0x7e,0x50,0x9, 0xac,0x5f,0x19, +0xa2,0x2f,0xae,0xda,0xf8,0x22,0xca,0xd8,0xca,0x79,0x70,0xc, 0x7e,0x8, 0x30,0x37, +0x12,0x9a,0x12,0x74,0xff,0x12,0x1b,0xb8,0x6c,0xff,0x21,0xff,0x7e,0x50,0x9, 0xac, +0x5f,0x49,0xd2,0x29,0x62,0x1e,0xd4,0x1e,0xd4,0x1e,0xd4,0x1e,0xd4,0x49,0xc2,0x29, +0x64,0x1e,0xc4,0x1e,0xc4,0x1e,0xc4,0x1e,0xc4,0x9, 0xe2,0x29,0x66,0x2e,0x24,0x28, +0xae,0x12,0x1f,0x82,0x1b,0x28,0x30,0x7e,0x50,0x9, 0xac,0x5f,0x2e,0x24,0x28,0xb0, +0x12,0x1f,0x82,0x1b,0x28,0x30,0x74,0x9, 0xac,0xbf,0x19,0xe5,0x28,0xb2,0x74,0x9, +0xac,0xbf,0x9, 0x75,0x29,0x67,0x19,0x75,0x28,0xb3,0x74,0x9, 0xac,0xbf,0x9, 0x75, +0x29,0x68,0x19,0x75,0x28,0xb4,0x7c,0xae,0x5e,0xa0,0xf, 0xa, 0x2a,0x12,0x9a,0x12, +0xbd,0x23,0x48,0x2, 0x21,0xfd,0x7c,0xea,0xa, 0x3e,0x9, 0xb3,0x29,0xbc,0xbe,0xb0, +0x3, 0x78,0x2, 0x21,0xfd,0xb4,0x1, 0x7, 0x74,0xff,0x12,0x9a,0xb, 0x21,0xfd,0xa, +0x3e,0x9, 0x13,0x30,0x37,0xa5,0xb9,0xff,0x38,0x74,0x1, 0x12,0x9a,0xb, 0x74,0x9, +0xac,0xbf,0x59,0xd5,0x28,0xae,0x74,0x9, 0xac,0xbf,0x59,0xc5,0x28,0xb0,0x6c,0xdd, +0x12,0x8f,0x4c,0x7e,0x50,0x9, 0xac,0x5d,0x7e,0x30,0x1b,0xac,0x3e,0x2d,0x12,0x2e, +0x14,0x30,0x41,0x74,0x9, 0x12,0x19,0x7f,0xb, 0xd0,0xbe,0xd0,0x3, 0x78,0xe1,0x80, +0x6c,0xbe,0x10,0x3, 0x40,0x4, 0xe4,0x12,0x9a,0xb, 0xa, 0x3e,0x9, 0x3, 0x30,0x37, +0x7e,0x10,0x9, 0xac,0x1, 0x7e,0x30,0x1b,0xac,0x3e,0x7d,0xb1,0x2d,0xb0,0x59,0xdb, +0x30,0x41,0x59,0xcb,0x30,0x43,0x7e,0xb3,0x2a,0x9, 0x70,0x13,0xe4,0x12,0x9a,0x23, +0x12,0x9a,0x1a,0x74,0x1, 0x7e,0x30,0x1b,0xac,0x3e,0x12,0x9a,0x23,0x80,0x1d,0x49, +0x3b,0x30,0x41,0x12,0x9a,0x1a,0xa, 0x3e,0x9, 0x43,0x30,0x37,0x7e,0x50,0x9, 0xac, +0x45,0x7e,0x70,0x1b,0xac,0x7e,0x2d,0x32,0x49,0x33,0x30,0x43,0x74,0x9, 0xac,0xbf, +0x59,0x35,0x28,0xb0,0xa, 0x3e,0x2e,0x34,0x30,0x37,0x12,0x9a,0x5d,0xb, 0xf0,0x12, +0x57,0x10,0x28,0x2, 0x1, 0xcc,0xda,0x79,0xda,0xd8,0x22,0xa, 0x3e,0x19,0xb3,0x30, +0x37,0x22,0x90,0x60,0x99,0xe4,0x93,0xa, 0x3b,0x22,0x74,0x9, 0xac,0xbf,0x59,0x35, +0x28,0xae,0x22,0x2e,0x14,0x30,0x41,0x6d,0x0, 0x7c,0xab,0x6d,0x33,0x6c,0x55,0x4c, +0xaa,0x7e,0x90,0x9, 0x78,0xd, 0xac,0x95,0x7f,0x70,0x2d,0xf4,0xb, 0x7a,0x40,0x2d, +0x34,0x80,0xc, 0xac,0x95,0x7f,0x70,0x2d,0xf4,0x69,0x47,0x0, 0x2, 0x2d,0x34,0xb, +0x50,0xbe,0x50,0x3, 0x40,0xd9,0x7e,0x24,0x0, 0x3, 0x8d,0x32,0x22,0x7e,0x39,0xb0, +0x4, 0x7a,0x39,0xb0,0x22,0x7e,0x8, 0x30,0x15,0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x1b, +0xb8,0x12,0x3f,0xe0,0x7e,0x8, 0x30,0x22,0xe4,0x12,0x1b,0xb8,0x90,0x60,0x99,0x12, +0x3f,0xe4,0x7e,0x8, 0x30,0x1, 0xe4,0x2, 0x1b,0xb8,0xca,0x3b,0x7c,0xab,0x7d,0x3, +0x7e,0x20,0x10,0x7d,0x30,0x7e,0x90,0x9, 0xac,0x95,0x9, 0x34,0x28,0xb4,0xbe,0x30, +0x10,0x28,0x2, 0x7c,0x23,0xbe,0x20,0x18,0x28,0x3, 0x7e,0x20,0x18,0x49,0xe4,0x28, +0xae,0xbe,0xe4,0x6, 0x50,0x40,0x20,0x7e,0x33,0x2a,0x6f,0x12,0x9b,0x86,0xbd,0xef, +0x38,0x15,0x49,0xe4,0x28,0xb0,0xbe,0xe4,0x6, 0x50,0x40,0xb, 0x7e,0x33,0x2a,0x70, +0x12,0x9b,0x86,0xbd,0xef,0x28,0x3, 0x7e,0x20,0x8, 0x7e,0xf0,0x10,0xac,0xf2,0xbd, +0x70,0x40,0x5d,0x7e,0xf0,0x9, 0xac,0xf4,0x9, 0xb7,0x2f,0xae,0x70,0x52,0x7e,0xd0, +0x8, 0xac,0xd2,0xbd,0x60,0x50,0x3c,0x9, 0xb7,0x2f,0xa7,0x70,0x1f,0x9, 0xb7,0x2f, +0xa8,0xbe,0xb0,0x0, 0x28,0xc, 0x7d,0x37,0x2e,0x34,0x2f,0xa8,0x14,0x7a,0x39,0xb0, +0x80,0x6, 0x74,0x1, 0x19,0xb7,0x2f,0xa7,0x6d,0x33,0x80,0x34,0x9, 0xb7,0x2f,0xa8, +0xbe,0xb0,0x14,0x50,0x2b,0x7d,0x37,0x2e,0x34,0x2f,0xa8,0x4, 0x7a,0x39,0xb0,0x6d, +0x33,0x80,0x1d,0xe4,0x19,0xb7,0x2f,0xa8,0x19,0xb7,0x2f,0xa7,0x6d,0x33,0x80,0x10, +0x6c,0x33,0x7e,0xf0,0x9, 0xac,0xf4,0x19,0x37,0x2f,0xa8,0xe4,0x19,0xb7,0x2f,0xa7, +0x7e,0x30,0x8, 0xac,0x23,0xbd,0x10,0x40,0x2a,0x7e,0x70,0x9, 0xac,0x7a,0x49,0x33, +0x29,0x62,0x59,0x34,0x28,0xae,0x74,0x9, 0xa4,0x49,0x35,0x29,0x64,0x74,0x9, 0xac, +0xb5,0x59,0x35,0x28,0xb0,0x7e,0xa0,0x1, 0x7e,0x70,0x9, 0xac,0x74,0x19,0xa3,0x2f, +0xa6,0x6d,0x33,0xda,0x3b,0x22,0x7e,0xf0,0x40,0xac,0xf3,0x7d,0xf7,0x9e,0xf4,0x0, +0x65,0x3e,0xf4,0x3e,0xf4,0x3e,0xf4,0x3e,0xf4,0x22,0x7c,0x17,0x7c,0xab,0x7e,0x14, +0xff,0xfc,0x7e,0x3, 0x2a,0x2, 0x7e,0x90,0x9, 0xac,0x91,0x9, 0xb4,0x2f,0xa9,0xb4, +0x1, 0x49,0xa5,0xb8,0x1, 0xc, 0xbe,0x14,0xff,0x0, 0x28,0x10,0x7e,0x14,0xff,0x0, +0x80,0xa, 0xbe,0x14,0xff,0xe0,0x28,0x4, 0x7e,0x14,0xff,0xe0,0x49,0x34,0x2f,0xaa, +0x7e,0x50,0x9, 0xac,0x5a,0x49,0x22,0x28,0xae,0x12,0x9c,0xb3,0x8, 0x3, 0x12,0x9c, +0xbd,0x7e,0x70,0x9, 0xac,0x71,0x49,0x33,0x2f,0xac,0x7e,0x50,0x9, 0xac,0x5a,0x49, +0x22,0x28,0xb0,0x12,0x9c,0xb3,0x8, 0x3, 0x12,0x9c,0xbd,0x7e,0x70,0x9, 0xac,0x7a, +0x9, 0x3, 0x28,0xb4,0xbe,0x0, 0xc, 0x28,0xc, 0xbe,0x14,0xff,0x80,0x28,0x26,0x7e, +0x14,0xff,0x80,0x80,0x20,0xbe,0x0, 0x8, 0x28,0xc, 0xbe,0x14,0xff,0xe0,0x28,0x15, +0x7e,0x14,0xff,0xe0,0x80,0xf, 0xbe,0x0, 0x6, 0x28,0xa, 0xbe,0x14,0xff,0xf0,0x28, +0x4, 0x7e,0x14,0xff,0xf0,0x7e,0x50,0x9, 0xac,0x51,0x49,0x22,0x2f,0xaa,0x49,0x33, +0x28,0xae,0x12,0x9c,0xa9,0x18,0x16,0x74,0x9, 0xac,0x1b,0x49,0x20,0x2f,0xac,0x7e, +0x70,0x9, 0xac,0x7a,0x49,0x33,0x28,0xb0,0x12,0x9c,0xa9,0x8, 0x4, 0x7e,0x14,0xff, +0xfc,0x7e,0x50,0x9, 0xac,0x5a,0x49,0x2, 0x28,0xae,0xbe,0x4, 0x6, 0x50,0x40,0x32, +0x7e,0x63,0x2a,0x6f,0x7e,0x70,0x40,0xac,0x67,0x9e,0x34,0x0, 0x65,0x12,0x53,0xa0, +0xbd,0x3, 0x38,0x1e,0x49,0x32,0x28,0xb0,0xbe,0x34,0x6, 0x50,0x40,0x14,0x7e,0x3, +0x2a,0x70,0x7e,0x10,0x40,0xac,0x1, 0x9e,0x4, 0x0, 0x65,0x12,0x37,0xf3,0xbd,0x30, +0x28,0x4, 0x7e,0x14,0xff,0xff,0x7d,0x31,0x22,0x9d,0x32,0x12,0x1b,0xfa,0xbe,0x34, +0x4, 0x0, 0x22,0x9d,0x32,0x12,0x1b,0xfa,0xbe,0x34,0x1, 0x0, 0x22,0x6c,0x0, 0x7e, +0x70,0x9, 0xac,0x71,0x19,0x3, 0x2f,0xa9,0x22,0xca,0x3b,0x6d,0x44,0x7e,0xf3,0x28, +0x84,0x6c,0xee,0x80,0x24,0x7c,0xbe,0x12,0x3f,0x74,0x60,0x1b,0x74,0x2, 0xac,0xbe, +0x9, 0xd5,0x26,0xfa,0x9, 0xc5,0x26,0xfb,0x7c,0xbd,0x7c,0x7c,0x12,0x3b,0x73,0x7d, +0xf3,0xbd,0x4f,0x58,0x2, 0x7d,0x4f,0xb, 0xe0,0xbc,0xfe,0x38,0xd8,0x7d,0x34,0xda, +0x3b,0x22,0xca,0x3b,0x7e,0x77,0x2a,0x5c,0x12,0x9c,0xc9,0x7d,0x63,0x3e,0x34,0x3e, +0x34,0x7e,0xe4,0x0, 0xa, 0x12,0x9d,0x90,0x7e,0xb3,0x28,0xa8,0x60,0xf, 0x7e,0x37, +0x38,0x30,0xbd,0x36,0x48,0x7, 0x3e,0x34,0x3e,0x34,0x12,0x9d,0x90,0xbe,0x64,0x4, +0x4c,0x8, 0xf, 0x12,0x9f,0x99,0x50,0x6, 0x7e,0xb3,0x28,0xa8,0x60,0x4, 0x74,0xa, +0x80,0x13,0x7e,0xb3,0x28,0xa8,0x60,0xc, 0x7e,0xb3,0x38,0x2e,0xbe,0xb0,0x0, 0x28, +0x8, 0x14,0x80,0x1, 0xe4,0x7a,0xb3,0x38,0x2e,0x7e,0xe7,0x2a,0x5c,0x7d,0x3e,0x12, +0x53,0xa2,0x7e,0x53,0x38,0x2e,0xbe,0x50,0x0, 0x28,0x12,0xbd,0x3f,0x58,0x4, 0x7d, +0xf3,0x80,0x6, 0xbd,0xef,0x8, 0x2, 0x7d,0xfe,0x7a,0xf7,0x2a,0x5c,0x12,0x9d,0x98, +0x28,0x3, 0x12,0x87,0x76,0x7a,0x67,0x38,0x30,0x7a,0x77,0x2a,0x5c,0xda,0x3b,0x22, +0x7d,0x2e,0x12,0x18,0xac,0x7d,0xf3,0x22,0x7e,0x73,0x28,0x84,0xbe,0x70,0x1, 0x22, +0xca,0x79,0xc2,0x0, 0x7e,0xf0,0x3, 0x12,0x9f,0xbf,0x7e,0xe3,0x2a,0x3, 0x7e,0x34, +0x1f,0x34,0x7a,0x37,0x32,0x14,0x12,0x9d,0x98,0x38,0x2, 0xc1,0x7c,0x12,0x6e,0xcf, +0x92,0xb, 0x12,0x9e,0x85,0x7c,0xbf,0x12,0x3b,0x7a,0x4c,0xee,0x68,0xe, 0x7e,0xa3, +0x31,0xf1,0x4c,0xaa,0x78,0xa, 0x7e,0xb3,0x31,0xf2,0x70,0x4, 0xd2,0x0, 0x80,0x25, +0xbe,0xe0,0x1, 0x28,0xb, 0xe5,0x1b,0xbe,0xb0,0x8, 0x28,0x4, 0xd2,0x0, 0x80,0x15, +0xd2,0x0, 0x7e,0xb3,0x28,0x84,0xbc,0xbe,0x78,0xb, 0x20,0xb, 0x8, 0x4c,0xaa,0x78, +0x4, 0x6c,0xff,0xc2,0x0, 0x20,0x0, 0x5, 0x7c,0xbf,0x12,0x3b,0x7a,0x7e,0x8, 0x31, +0xf6,0x12,0x45,0x1f,0x7a,0xb3,0x31,0xf5,0xbe,0xb3,0x28,0x84,0x50,0x3d,0x7e,0x33, +0x31,0xf5,0x80,0x29,0x7e,0x70,0x2, 0xac,0x73,0x9, 0x23,0x32,0x16,0x9, 0x13,0x32, +0x17,0x2e,0x37,0x32,0x14,0xb, 0x38,0x50,0x7e,0x93,0x2a,0x6e,0xac,0x92,0xa, 0x31, +0x2d,0x43,0x12,0x9f,0x8d,0x7c,0xb3,0x7e,0x70,0x1, 0x12,0x3f,0x90,0x7c,0x3, 0x1b, +0x30,0xa5,0xb8,0x0, 0xcf,0x74,0x1, 0x7a,0xb3,0x31,0xf3,0x7e,0xa3,0x31,0xf5,0x7a, +0xa3,0x28,0x84,0x74,0x2, 0xa4,0xca,0x59,0x7e,0x18,0x32,0x16,0x7e,0x8, 0x26,0xfa, +0x12,0x1b,0x93,0x1b,0xfd,0x12,0x9f,0x4, 0xf5,0x1b,0x80,0x6, 0x75,0x1b,0x64,0x12, +0x9f,0x81,0xda,0x79,0x22,0x6c,0xaa,0x12,0x9e,0xf8,0x12,0x9e,0xb0,0x7e,0xb, 0xb0, +0x54,0xfe,0x12,0x9e,0xad,0x7e,0xb, 0xb0,0x54,0x7, 0x12,0x9e,0xad,0x7e,0xb, 0xb0, +0x54,0xfb,0x7a,0xb, 0xb0,0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xdb,0x22,0x7a,0xb, 0xb0, +0x7f,0x1, 0x2e,0x14,0x0, 0x5, 0x22,0x6c,0xaa,0x12,0x9e,0xf8,0x29,0x81,0x0, 0x5, +0x7c,0x98,0x5e,0x90,0x1, 0x3e,0x90,0x12,0x9e,0xb0,0x7c,0xb8,0x54,0xfd,0x4c,0xb9, +0x7a,0xb, 0xb0,0x29,0xb1,0x0, 0x5, 0x30,0xe0,0x16,0x30,0xe2,0x13,0xc4,0x23,0x54, +0x1f,0xb4,0x1, 0xc, 0x7f,0x1, 0xb, 0x16,0x7e,0xb, 0xb0,0x1e,0xb0,0x7a,0xb, 0xb0, +0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xc2,0x22,0x7e,0x70,0x6, 0xac,0x7a,0x2e,0x34,0x32, +0x53,0x6d,0x22,0x22,0x7e,0x30,0x64,0x7e,0x20,0x64,0x6c,0x11,0x80,0x4a,0xa, 0x31, +0xb, 0x34,0x7c,0x7, 0x80,0x38,0x7e,0x70,0x2, 0xac,0x70,0x9, 0xb3,0x26,0xfa,0x12, +0x9f,0x79,0x9, 0xb3,0x26,0xfa,0x12,0x3f,0x55,0x7c,0x97,0x7e,0x70,0x2, 0xac,0x70, +0x9, 0xb3,0x26,0xfb,0x12,0x9f,0x79,0x9, 0xb3,0x26,0xfb,0x12,0x3f,0x55,0x7c,0x87, +0xbc,0x39,0x28,0x2, 0x7c,0x39,0xbc,0x28,0x28,0x2, 0x7c,0x28,0xb, 0x0, 0x7e,0xb3, +0x28,0x84,0xbc,0xb0,0x38,0xc0,0xb, 0x10,0x7e,0xb3,0x28,0x84,0xbc,0xb1,0x38,0xae, +0xa5,0xbb,0x64,0x2, 0x6c,0x33,0xa5,0xba,0x64,0x2, 0x6c,0x22,0xbc,0x23,0x28,0x4, +0x7c,0xa2,0x80,0x2, 0x7c,0xa3,0x7c,0xba,0x22,0xa, 0x2b,0x7e,0x70,0x2, 0xac,0x71, +0x22,0x7e,0x8, 0x32,0x53,0x7e,0x34,0x0, 0xb4,0xe4,0x2, 0x1b,0xb8,0x3e,0x44,0x7e, +0x1f,0x13,0x8a,0x2d,0x34,0x1b,0x1a,0x50,0x22,0x6c,0x99,0x6c,0x88,0x80,0xf, 0x7c, +0xb8,0x12,0x80,0x77,0xbe,0x34,0x1, 0xf4,0x8, 0x2, 0xb, 0x90,0xb, 0x80,0x7e,0x73, +0x28,0x84,0xbc,0x78,0x38,0xe9,0xbe,0x90,0x1, 0x38,0x2, 0xc3,0x22,0xd3,0x22,0x7e, +0x73,0x2a,0x3, 0xbe,0x70,0x0, 0x28,0x8, 0x7e,0xb3,0x28,0x84,0x70,0x2, 0xf5,0x1a, +0x7e,0xb3,0x28,0x84,0x70,0x18,0xe5,0x1a,0xbe,0xb0,0xfa,0x50,0x2, 0x5, 0x1a,0xe5, +0x1a,0xbe,0xb0,0x5, 0x40,0x8, 0xe4,0x7a,0xb3,0x32,0x52,0x75,0x1a,0xfa,0x22,0xca, +0xd8,0xca,0x79,0x7e,0x34,0x62,0x27,0x12,0xa0,0x97,0x12,0x9f,0x99,0x50,0x2, 0x1, +0x92,0x7e,0x34,0x62,0x2b,0x12,0x1e,0x81,0x7a,0x35,0x2a,0x90,0x62,0x26,0xe4,0x93, +0x70,0x2, 0x1, 0x92,0x7e,0xb3,0x28,0xa8,0xb4,0x1, 0x7, 0x7e,0x34,0x62,0x29,0x12, +0xa0,0x97,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x4, 0x4c,0x8, 0x66,0x6c,0xdd,0x80,0x5a, +0xc2,0x0, 0x7c,0xbd,0x12,0x80,0x77,0x7a,0x35,0x26,0x7c,0xbd,0x7e,0x70,0x1, 0x12, +0xa0,0xc1,0x7a,0x35,0x24,0x9e,0x35,0x26,0x7a,0x35,0x24,0x7e,0x35,0x26,0x3e,0x34, +0x3e,0x34,0x12,0x87,0xc4,0x7a,0x35,0x28,0xbe,0x75,0x28,0x58,0x3, 0x7a,0x75,0x28, +0x7e,0x35,0x28,0xbe,0x35,0x24,0x8, 0xa, 0x7e,0x35,0x2a,0xbe,0x35,0x26,0x8, 0x2, +0xd2,0x0, 0x7c,0xbd,0x12,0xa0,0x9f,0x50,0x2, 0xc2,0x0, 0x30,0x0, 0xa, 0x7c,0xbd, +0x12,0x87,0xd3,0xac,0x7d,0x12,0x87,0xa1,0xb, 0xd0,0x7e,0x73,0x28,0x84,0xbc,0x7d, +0x38,0x9e,0xda,0x79,0xda,0xd8,0x22,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0x70,0x22,0x7c, +0x4b,0x74,0x2, 0xac,0xb4,0x9, 0x55,0x26,0xfa,0x9, 0x65,0x26,0xfb,0x7e,0x73,0x28, +0x8c,0xbc,0x75,0x78,0xa, 0x7e,0x73,0x28,0x8d,0xbc,0x76,0x78,0x2, 0xd3,0x22,0xc3, +0x22,0xca,0x79,0x7c,0xa7,0x7c,0x8b,0x7e,0xb3,0x2a,0x6f,0x7a,0xb3,0x1f,0x9a,0x7e, +0xb3,0x2a,0x70,0x7a,0xb3,0x1f,0x9b,0x7e,0x70,0x2, 0xac,0x78,0x9, 0x93,0x26,0xfa, +0x9, 0x83,0x26,0xfb,0x9f,0x77,0x1a,0x3a,0x1a,0x79,0x9d,0x73,0x21,0x79,0x7a,0xf1, +0x58,0xbe,0xf0,0x0, 0x58,0xe, 0x1a,0x3f,0x1a,0x29,0x9d,0x23,0x1a,0x39,0x2d,0x32, +0x7c,0xb7,0xf5,0x58,0x7e,0xb3,0x1f,0x9a,0xbc,0xbf,0x18,0xe, 0x1a,0x39,0x1a,0x2f, +0x9d,0x23,0x1a,0x39,0x9d,0x32,0x7c,0xb7,0xf5,0x58,0x1a,0x2a,0x1a,0x38,0x9d,0x32, +0x7c,0xb7,0xf5,0x57,0x80,0x43,0x85,0x57,0x59,0xe5,0x57,0xbe,0xb0,0x0, 0x58,0x10, +0xe5,0x57,0x1a,0x3b,0x1a,0x28,0x9d,0x23,0x1a,0x38,0x2d,0x32,0x7c,0xb7,0xf5,0x59, +0x7e,0xb3,0x1f,0x9b,0xbe,0xb1,0x57,0x18,0x10,0x1a,0x38,0xe5,0x57,0x1a,0x2b,0x9d, +0x23,0x1a,0x38,0x9d,0x32,0x7c,0xb7,0xf5,0x59,0xe5,0x58,0x7e,0x71,0x59,0x12,0x3b, +0x73,0x1a,0x26,0x1a,0x24,0x2f,0x71,0x5, 0x57,0x1a,0x3a,0x1a,0x28,0x2d,0x23,0xe5, +0x57,0x1a,0x3b,0xbd,0x32,0x8, 0xaf,0xb, 0xf0,0x1a,0x3a,0x1a,0x29,0x2d,0x23,0x1a, +0x3f,0xbd,0x32,0x18,0x2, 0x1, 0xee,0x7f,0x17,0xda,0x79,0x22,0xe4,0x7a,0xb3,0x37, +0xb4,0x7e,0xb3,0x28,0x84,0x60,0x6, 0x7e,0xb3,0x38,0x2d,0x60,0x5, 0xe4,0x7a,0xb3, +0x38,0x2f,0x22,0x7e,0xa0,0x1, 0x7e,0x37,0x2a,0x4f,0x12,0xa1,0xec,0x28,0x35,0x6d, +0x22,0x9d,0x23,0xbe,0x27,0x7, 0xf8,0x58,0x2b,0x12,0x87,0xc4,0xbe,0x37,0x7, 0xfa, +0x8, 0x22,0xe4,0x7a,0xb3,0x28,0x84,0x7e,0xb3,0x2a,0x3, 0x70,0x17,0x7e,0xb3,0x38, +0xd6,0xb4,0x1, 0x10,0x6c,0xaa,0x5, 0x1f,0xe5,0x1f,0xbe,0xb0,0x10,0x28,0x5, 0xd2, +0x13,0x75,0x1f,0x0, 0x4c,0xaa,0x68,0x3, 0x75,0x1f,0x0, 0x22,0x7e,0xb3,0x28,0x84, +0xbe,0xb0,0x0, 0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x73,0x2a,0x6e,0xa, 0x37, +0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x1b,0x93,0x1b,0xfd,0x6c,0xdd,0x12, +0x37,0xeb,0x7a,0xb3,0x1f,0x6c,0x6c,0xcc,0x80,0x4a,0x12,0xa2,0x9d,0x78,0x43,0x74, +0x2, 0xac,0xbc,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0xe0,0x7d,0x3f,0x12,0x1b,0xfa,0x7d, +0x13,0x7d,0x3e,0x12,0x1b,0xfa,0xbd,0x31,0x58,0x2, 0x7d,0xfe,0xbe,0xe5,0x2e,0x8, +0x5, 0x7e,0xe5,0x2e,0x80,0xb, 0x6d,0x33,0x9e,0x35,0x2e,0xbd,0x3e,0x8, 0x2, 0x7d, +0xe3,0x7d,0x3e,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x1f,0x6c,0x4, 0x7a,0xb3, +0x1f,0x6c,0xb, 0xc0,0x7e,0x73,0x2a,0x70,0xbc,0x7c,0x38,0xae,0x7e,0x73,0x1f,0x6c, +0x4c,0x77,0x68,0x1d,0x12,0xa4,0x81,0x8, 0x2, 0x7d,0x7f,0x6c,0xcc,0x80,0xa, 0x12, +0xa2,0x9d,0x78,0x3, 0x12,0xa4,0x6c,0xb, 0xc0,0x7e,0x73,0x2a,0x70,0xbc,0x7c,0x38, +0xee,0xb, 0xd0,0xbe,0xd0,0x2, 0x50,0x2, 0x41,0xf, 0xda,0x3b,0x22,0xa, 0xec,0x9, +0x7e,0x2a,0xd8,0xa, 0x37,0x5e,0x34,0x0, 0x1, 0xa, 0xed,0xbd,0x3e,0x22,0xca,0x3b, +0x7f,0x31,0x7a,0xd, 0x24,0x7e,0x35,0x28,0x7a,0x35,0x2e,0x7e,0xd, 0x24,0x7f,0x13, +0x12,0xa1,0xf4,0x7e,0x35,0x28,0x7a,0x35,0x2a,0x12,0xa4,0x62,0xa4,0x7e,0xd, 0x24, +0x2d,0x15,0x7f,0x13,0x2d,0x35,0x12,0x33,0xe2,0xda,0x3b,0x22,0x7e,0x37,0x2a,0x4f, +0x1e,0x34,0x7a,0x35,0x28,0x7e,0x8, 0x4, 0xfc,0x7e,0x18,0x4, 0x0, 0x12,0xa2,0xae, +0x7e,0x37,0x28,0x99,0xe, 0x34,0x7a,0x35,0x28,0x7e,0x8, 0x5, 0x7a,0x7e,0x18,0x4, +0x7e,0x12,0xa2,0xae,0x12,0xa3,0x1e,0x12,0xa4,0x99,0x2, 0xa3,0xd, 0xe4,0x7a,0xb3, +0x3b,0x1a,0x7e,0xb3,0x28,0xa8,0x60,0x5, 0xe4,0x7a,0xb3,0x3b,0x1a,0x22,0xca,0x3b, +0x7e,0xf3,0x2a,0x6e,0x12,0xa4,0x59,0x6c,0xcc,0x80,0x13,0x7c,0x7c,0xac,0x7f,0x3e, +0x34,0x7e,0xf, 0x13,0x8a,0x2d,0x13,0x7c,0xbd,0x12,0xa3,0x45,0xb, 0xc0,0xbc,0xec, +0x38,0xe9,0xda,0x3b,0x22,0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f,0x70,0xc2,0x0, 0x6c, +0xdd,0x6d,0xdd,0x7e,0x34,0x1d,0x7d,0x7e,0x24,0x0, 0xff,0x7e,0x14,0x1f,0x34,0x74, +0xc, 0x12,0x19,0xa0,0x6d,0x11,0x7e,0x4, 0x7f,0xff,0x6c,0xee,0x80,0x13,0x12,0x77, +0xb1,0x7d,0xc3,0xbd,0xdc,0x50,0x2, 0x7d,0xdc,0xbd,0xc, 0x28,0x2, 0x7d,0xc, 0xb, +0xe0,0xbc,0xfe,0x38,0xe9,0xbe,0xd4,0x0, 0x1e,0x58,0xa, 0x7e,0xb3,0x28,0x94,0x70, +0x4, 0x6d,0x33,0x81,0x4a,0xbe,0xd4,0x4, 0xb0,0x8, 0x2, 0xd2,0x0, 0x6c,0xee,0x74, +0x4, 0xac,0xbe,0x49,0x45,0x1f,0x34,0xbd,0x4d,0x58,0x6, 0x49,0xd5,0x1f,0x36,0x80, +0x7, 0xb, 0xe0,0xbe,0xe0,0x3, 0x40,0xe7,0xbe,0xe0,0x3, 0x78,0x4, 0x6d,0x33,0x81, +0x4a,0xbd,0xd, 0x8, 0x5, 0x30,0x0, 0x2, 0x7d,0xd0,0x9f,0x55,0x6c,0xee,0x80,0xb, +0x12,0x77,0xb1,0x1a,0x26,0x1a,0x24,0x2f,0x51,0xb, 0xe0,0xbc,0xfe,0x38,0xf1,0xa, +0x1f,0x12,0xa4,0x4f,0x9f,0x55,0x6c,0xee,0x80,0x22,0x74,0x2, 0xac,0xbe,0x7f,0x17, +0x2d,0x35,0xb, 0x1a,0x90,0x7d,0x39,0x12,0x1b,0xfa,0x7d,0xc3,0xbd,0x1c,0x28,0xa, +0x7d,0x39,0x1a,0x26,0x1a,0x24,0x2f,0x51,0xb, 0xd0,0xb, 0xe0,0xbc,0xfe,0x38,0xda, +0x6d,0x11,0xbe,0xd0,0x0, 0x28,0x5, 0xa, 0x1d,0x12,0xa4,0x4f,0xbd,0x1d,0x8, 0x4, +0x7d,0x1d,0x80,0xa, 0x6d,0x0, 0x9d,0xd, 0xbd,0x1, 0x8, 0x2, 0x7d,0x10,0x6c,0xee, +0x80,0x12,0x74,0x2, 0xac,0xbe,0x7f,0x17,0x2d,0x35,0xb, 0x1a,0x0, 0x9d,0x1, 0x1b, +0x1a,0x0, 0xb, 0xe0,0xbc,0xfe,0x38,0xea,0x7d,0x31,0xda,0x79,0xda,0xd8,0x22,0x6d, +0x0, 0x7f,0x15,0x12,0x19,0x4b,0x7d,0x13,0x22,0x7e,0xe3,0x2a,0x6f,0x7e,0xd3,0x2a, +0x70,0x22,0x90,0x61,0x27,0xe4,0x93,0x7c,0xab,0x74,0x2, 0x22,0x74,0x2, 0xac,0xbc, +0x7f,0x16,0x2d,0x35,0xb, 0x1a,0xe0,0x9d,0xe7,0x7f,0x15,0x2d,0x35,0x1b,0x1a,0xe0, +0x22,0xa, 0x17,0x6d,0x0, 0x7f,0x14,0x12,0x19,0x4b,0x7d,0x73,0x12,0x1b,0xfa,0x7d, +0xe3,0x7d,0x3f,0x12,0x1b,0xfa,0xbd,0x3e,0x22,0x7e,0x63,0x2a,0x6e,0x90,0x60,0xa7, +0xe4,0x93,0x60,0x6c,0xc2,0x14,0x6c,0x33,0x80,0x56,0x90,0x60,0xaa,0xe4,0x93,0x70, +0x13,0x7c,0x96,0xac,0x93,0x90,0x60,0xab,0xe4,0x93,0xa, 0x5b,0x1b,0x54,0x2d,0x45, +0x7d,0xd4,0xb, 0xd4,0x7d,0x54,0x3e,0x54,0x7e,0x7f,0x13,0x8a,0x2d,0xf5,0xb, 0x7a, +0x50,0xbe,0x57,0x2a,0x5a,0x8, 0x27,0x7c,0xb3,0x12,0x42,0x3f,0x50,0x20,0x7d,0x5d, +0x3e,0x54,0x7e,0x7f,0x13,0x8a,0x7f,0x57,0x2d,0xb5,0xb, 0x5a,0xc0,0x7d,0x54,0x3e, +0x54,0x2d,0xf5,0xb, 0x7a,0x50,0xbd,0x5c,0x8, 0x4, 0xd2,0x14,0x80,0xa, 0xb, 0x30, +0x7e,0x73,0x2a,0x71,0xbc,0x73,0x38,0xa2,0x30,0x14,0x5, 0xd2,0x0, 0x2, 0x42,0x61, +0x22,0x90,0x60,0xa7,0xe4,0x93,0x60,0x8, 0x30,0x14,0x5, 0x12,0x42,0x11,0xc2,0x14, +0x22,0x7e,0xb3,0x2b,0x19,0xb4,0x1, 0x31,0x12,0xa5,0x5a,0x7e,0x1f,0x3a,0xe5,0x7a, +0x37,0x24,0xfa,0x7e,0x34,0xd, 0xc8,0x7a,0x37,0x24,0xf6,0x12,0xa5,0x61,0x12,0xa5, +0x6a,0xe4,0x7a,0xb3,0x24,0xf5,0x7e,0x34,0x0, 0x20,0x7a,0x37,0x24,0xfc,0x7a,0xb3, +0x24,0xf4,0x7e,0x8, 0x24,0xf2,0x2, 0xb, 0x4d,0x22,0xa9,0xd1,0xcb,0xe4,0x2, 0x0, +0xe, 0x7e,0x73,0x2a,0x6d,0x7a,0x73,0x24,0xf2,0x22,0x7e,0x73,0x2a,0x6e,0x7a,0x73, +0x24,0xf3,0x22,0x7c,0xab,0x90,0x60,0xab,0xe4,0x93,0xbc,0xb7,0x78,0x9, 0x7c,0xba, +0x12,0x42,0x3f,0x50,0x2, 0xd3,0x22,0xc3,0x22,0x7c,0xa7,0x7c,0x7b,0x90,0x60,0xaa, +0xe4,0x93,0x60,0x2, 0x7c,0xa7,0x90,0x60,0xab,0xe4,0x93,0xbc,0xba,0x78,0x2, 0xd3, +0x22,0xc3,0x22,0xd2,0x0, 0x6c,0xaa,0x6c,0x77,0x80,0x1f,0x7e,0x63,0x2a,0x6e,0xa, +0x16,0xa, 0x27,0x2d,0x21,0x7c,0x65,0x7e,0x50,0x2, 0xac,0x56,0x49,0x22,0x5, 0x7a, +0xbe,0x24,0xfe,0xc, 0x58,0x2, 0xb, 0xa0,0xb, 0x70,0x7e,0xb3,0x2a,0x6d,0xbc,0xb7, +0x38,0xd9,0xa, 0x2b,0x1e,0x24,0xa, 0x3a,0xbd,0x32,0x8, 0x2, 0xc2,0x0, 0xa2,0x0, +0x22,0xc2,0x0, 0x7e,0xa3,0x2a,0x70,0x7e,0xb3,0x26,0xf1,0x60,0x4, 0xd2,0x0, 0x80, +0x33,0x7e,0x70,0x2, 0x80,0x22,0x7e,0x50,0x2, 0xac,0x57,0x49,0x12,0x4, 0xfc,0x7e, +0xf4,0x61,0x59,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x0, 0x6d,0x22,0x9d,0x20,0xbd,0x12, +0x58,0x4, 0xd2,0x0, 0x80,0xe, 0xb, 0x70,0xa, 0x1a,0x9e,0x14,0x0, 0x3, 0xa, 0x27, +0xbd,0x21,0x48,0xd2,0xa2,0x0, 0x22,0x7e,0xb3,0x38,0x43,0xb4,0x1, 0x3, 0x2, 0xa6, +0x7e,0x7e,0xb3,0x38,0xa9,0x4, 0x7a,0xb3,0x38,0xa9,0x7e,0xb3,0x38,0x37,0xb4,0x2, +0x18,0x7e,0xb3,0x38,0xa8,0x4, 0x7a,0xb3,0x38,0xa8,0xb4,0x1, 0x6, 0x74,0x1, 0x7a, +0xb3,0x38,0xa9,0x74,0x1, 0x7a,0xb3,0x38,0x37,0x7e,0x73,0x38,0xa8,0xbe,0x70,0x3, +0x40,0xf, 0x74,0x1, 0x7a,0xb3,0x38,0x43,0x12,0xa6,0x7e,0x12,0xa6,0x8f,0x12,0xa6, +0x85,0x7e,0x73,0x38,0xa9,0xbe,0x70,0xa, 0x28,0x3, 0x2, 0xa6,0x85,0x22,0x74,0x2, +0x7a,0xb3,0x38,0x37,0x22,0xe4,0x7a,0xb3,0x38,0xa9,0x7a,0xb3,0x38,0xa8,0x22,0xe4, +0x7a,0xb3,0x38,0x35,0x6c,0xaa,0x80,0xd, 0x6d,0x44,0x7e,0x70,0xc, 0xac,0x7a,0x59, +0x43,0x38,0x4c,0xb, 0xa0,0x12,0x7d,0x7, 0x38,0xee,0xe4,0x7a,0xb3,0x38,0x36,0x6d, +0x33,0x7a,0x37,0x38,0x3d,0x7a,0x37,0x38,0x32,0x22,0x7d,0x23,0x7e,0x14,0x61,0xc8, +0x12,0x4f,0x39,0x7e,0x14,0x0, 0x5, 0xad,0x13,0x1e,0x14,0xbd,0x12,0x50,0xd, 0x7e, +0x33,0x38,0xaa,0xbe,0x30,0x8, 0x50,0x45,0x74,0x8, 0x80,0x3d,0x7d,0x13,0x3e,0x14, +0xbd,0x12,0x50,0xd, 0x7e,0x33,0x38,0xaa,0xbe,0x30,0x6, 0x50,0x30,0x74,0x6, 0x80, +0x28,0x7e,0x14,0x0, 0x3, 0xad,0x13,0x1e,0x14,0xbd,0x12,0x50,0xd, 0x7e,0x33,0x38, +0xaa,0xbe,0x30,0x4, 0x50,0x17,0x74,0x4, 0x80,0xf, 0xbd,0x32,0x50,0xf, 0x7e,0x73, +0x38,0xaa,0xbe,0x70,0x2, 0x50,0x6, 0x74,0x2, 0x7a,0xb3,0x38,0xaa,0x7e,0xb3,0x38, +0xaa,0xbe,0xb0,0x0, 0x28,0x1b,0x14,0x7a,0xb3,0x38,0xaa,0x74,0x1, 0x7a,0xb3,0x16, +0x92,0x90,0x61,0xfd,0xe4,0x93,0xbe,0xb3,0x38,0xaa,0x50,0x5, 0xe4,0x7a,0xb3,0x16, +0x91,0x22,0x7c,0x3b,0x7e,0x44,0xff,0xff,0x6c,0x22,0x80,0x2a,0x12,0xa7,0xbb,0x68, +0x23,0x7e,0x70,0xc, 0xac,0x72,0x12,0xa7,0xd3,0x7d,0x23,0x7e,0x70,0xc, 0xac,0x72, +0x59,0x23,0x38,0x50,0x49,0x3, 0x38,0x50,0x49,0x23,0x38,0x4c,0xbd,0x20,0x50,0x4, +0x59,0x3, 0x38,0x4c,0xb, 0x20,0xbc,0x32,0x50,0xd2,0x6c,0xaa,0x6c,0x22,0x80,0x18, +0x12,0xa7,0xbb,0x68,0x11,0x7e,0x70,0xc, 0xac,0x72,0x49,0x3, 0x38,0x4c,0xbd,0x4, +0x50,0x4, 0x7d,0x40,0x7c,0xa2,0xb, 0x20,0xbc,0x32,0x50,0xe4,0x7e,0x37,0x38,0x32, +0xbe,0x37,0x38,0xab,0x50,0x8, 0x7e,0x37,0x38,0xab,0x7a,0x37,0x38,0x32,0x12,0xa7, +0xc9,0x4d,0x33,0x78,0x3, 0x7e,0xa0,0xff,0x7c,0xba,0x22,0x7e,0x10,0x5, 0xac,0x12, +0x9, 0xb0,0x26,0x33,0xbe,0xb3,0x2b,0xb, 0x22,0x7e,0x70,0xc, 0xac,0x7a,0x49,0x33, +0x38,0x4c,0x22,0x49,0x23,0x38,0x52,0x49,0x33,0x38,0x4e,0x9d,0x32,0x2, 0x1b,0xfa, +0x7e,0x8, 0x38,0x48,0x7e,0x34,0x0, 0x60,0xe4,0x12,0x1b,0xb8,0x6c,0xaa,0x7e,0x44, +0xff,0xff,0x7e,0x70,0xc, 0xac,0x7a,0x59,0x43,0x38,0x4a,0x59,0x43,0x38,0x52,0xb, +0xa0,0xbe,0xa0,0x8, 0x40,0xe8,0x7e,0x8, 0x38,0x36,0x7e,0x34,0x0, 0xd, 0xe4,0x2, +0x1b,0xb8,0xca,0xd8,0xca,0x79,0x7e,0xe0,0xff,0x12,0xa9,0x52,0x7e,0xb3,0x38,0x39, +0xb4,0x1, 0x8, 0x12,0x78,0xd3,0xe4,0x7a,0xb3,0x38,0x39,0x7e,0xb3,0x38,0x38,0x60, +0x4, 0x74,0xff,0x21,0x35,0x7e,0xb3,0x38,0x37,0xb4,0x2, 0x2, 0x80,0x2, 0x21,0x29, +0x12,0xa9,0x4a,0x38,0xc, 0x12,0xa9,0x42,0x38,0x7, 0x12,0xa9,0x3a,0x38,0x2, 0x21, +0x29,0x12,0x37,0xe3,0xa, 0x3d,0x1b,0x34,0xbe,0x34,0x0, 0x3, 0x48,0x4, 0x74,0x3, +0x80,0x3, 0x7c,0xbd,0x14,0x12,0xa7,0x42,0x7c,0xfb,0x7e,0xb3,0x38,0x36,0x4, 0x7a, +0xb3,0x38,0x36,0x90,0x61,0xc5,0xe4,0x93,0x14,0x12,0xa7,0x42,0x7c,0xab,0xbe,0xa0, +0xff,0x68,0x2c,0xbe,0xf0,0xff,0x68,0x25,0x7e,0x30,0xc, 0xac,0x3f,0x49,0x21,0x38, +0x4c,0x7e,0xf4,0x61,0xcc,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x30,0xbd,0x23,0x28,0xf, +0x12,0xa7,0xc9,0x3e,0x34,0xbd,0x23,0x28,0x6, 0x7c,0xfa,0x80,0x2, 0x7c,0xfa,0xbe, +0xf0,0xff,0x78,0x11,0xe4,0x7a,0xb3,0x38,0x36,0x7a,0xb3,0x38,0x37,0x7a,0xb3,0x38, +0x43,0x74,0xff,0x80,0x70,0x90,0x61,0xd4,0xe4,0x93,0xbe,0xb3,0x38,0x36,0x50,0x59, +0x74,0xc, 0xac,0xbf,0x49,0x25,0x38,0x4c,0x7e,0x14,0x61,0xcc,0x12,0x4f,0x39,0xbd, +0x23,0x50,0x3d,0x7e,0x34,0x61,0xd0,0x12,0x1e,0x81,0xbe,0x37,0x38,0x32,0x40,0xd, +0x7e,0x34,0x61,0xd2,0x12,0x1e,0x81,0xbe,0x37,0x38,0x3d,0x50,0x23,0x74,0x5, 0xac, +0xbf,0x9, 0x75,0x26,0x33,0xbe,0x73,0x2b,0xb, 0x68,0x15,0x7c,0xef,0xbe,0xe0,0x4, +0x50,0x8, 0x12,0x67,0x1c,0xbe,0xb0,0x4, 0x40,0x6, 0x74,0x1, 0x7a,0xb3,0x38,0x39, +0xe4,0x7a,0xb3,0x38,0x43,0x7a,0xb3,0x38,0x37,0xbe,0xe0,0xff,0x68,0x5, 0xe4,0x7a, +0xb3,0x38,0x36,0x7c,0xbe,0xda,0x79,0xda,0xd8,0x22,0x7e,0x73,0x26,0xf5,0xbe,0x70, +0x0, 0x22,0x7e,0x73,0x26,0xf4,0xbe,0x70,0x0, 0x22,0x7e,0x73,0x28,0x92,0xbe,0x70, +0x0, 0x22,0x7e,0xb3,0x38,0x38,0xb4,0x1, 0x27,0x7e,0xb3,0x38,0xae,0x4, 0x7a,0xb3, +0x38,0xae,0x7e,0x73,0x38,0xae,0xbe,0x70,0x3, 0x40,0x15,0x12,0x7c,0xaf,0x7e,0x73, +0x38,0xae,0xbe,0x70,0x6, 0x40,0x9, 0xe4,0x7a,0xb3,0x38,0xae,0x7a,0xb3,0x38,0x38, +0x22,0x7e,0xa3,0x2b,0x5e,0xbc,0xab,0x68,0x6, 0x7a,0xb3,0x2b,0x5e,0xd2,0xe, 0x30, +0xe, 0x7, 0x12,0xa9,0x9a,0xe4,0x2, 0x8, 0x0, 0x22,0xc2,0xe, 0x7e,0x8, 0x2a,0x6d, +0x12,0x1, 0x20,0x7e,0x8, 0x2a,0x6d,0x74,0x3, 0x2, 0x10,0x42,0x12,0x1e,0xfc,0xe4, +0x7a,0xb3,0x3b,0x19,0x2, 0xa9,0xb7,0xe4,0x7a,0xb3,0x28,0x93,0x12,0xac,0xf7,0x7e, +0xb3,0x16,0x91,0xb4,0x1, 0x8, 0x7e,0x73,0x28,0x84,0x7a,0x73,0x28,0x92,0x7e,0x18, +0x4, 0xfc,0x7a,0x1f,0x6, 0xf8,0x12,0xae,0x36,0x12,0xa9,0xff,0x12,0xab,0x96,0x7e, +0xb3,0x16,0x90,0xb4,0x1, 0x18,0x7e,0x73,0x26,0x83,0x7a,0x73,0x26,0xf3,0x7e,0x73, +0x26,0x85,0x7a,0x73,0x26,0xf5,0x7e,0x73,0x26,0x84,0x7a,0x73,0x26,0xf4,0x22,0x7e, +0x8, 0x26,0x86,0x7e,0x34,0x0, 0x3, 0xe4,0x12,0x1b,0xb8,0x7e,0x8, 0x26,0x89,0x7e, +0x34,0x0, 0x3, 0x12,0x1b,0xb8,0x7a,0xb3,0x26,0x83,0x7a,0xb3,0x26,0x84,0x7a,0xb3, +0x26,0x85,0x7a,0xb3,0x26,0xf0,0x7a,0xb3,0x26,0xf1,0x7a,0xb3,0x26,0xf2,0x7e,0x18, +0x26,0x6f,0x12,0xab,0x6d,0x6c,0x55,0x12,0xaa,0xc5,0x7a,0xb3,0x26,0x85,0x7e,0x18, +0x26,0x5b,0x12,0xab,0x7d,0x6c,0x55,0x12,0xaa,0xc5,0x7a,0xb3,0x26,0x84,0x6c,0x77, +0x80,0x14,0x12,0xab,0x4e,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb,0x12,0xab,0x57,0x2e, +0x24,0x26,0x86,0x12,0xab,0x62,0x7e,0x63,0x26,0x84,0xbc,0x67,0x38,0xe4,0x6c,0x77, +0x80,0x14,0x12,0xab,0x4e,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb,0x12,0xab,0x57,0x2e, +0x24,0x26,0x89,0x12,0xab,0x62,0x7e,0xa3,0x26,0x85,0xbc,0xa7,0x38,0xe4,0x7e,0xb3, +0x26,0x84,0xa4,0x7a,0xb3,0x26,0x83,0x7e,0x18,0x26,0xe6,0x12,0xab,0x6d,0x7e,0x50, +0x1, 0x12,0xaa,0xc5,0x7a,0xb3,0x26,0xf2,0x7e,0x18,0x26,0xdc,0x12,0xab,0x7d,0x7e, +0x50,0x1, 0x12,0xaa,0xc5,0x7c,0xab,0x7a,0xa3,0x26,0xf1,0x7e,0xb3,0x26,0xf2,0xa4, +0x7a,0xb3,0x26,0xf0,0x22,0xca,0x69,0xca,0xf8,0x7c,0x4b,0x6c,0xaa,0x6d,0xff,0x6c, +0xff,0x80,0x70,0x7e,0xd0,0x2, 0xac,0xdf,0x7f,0x60,0x2d,0xd6,0xb, 0x6a,0xe0,0x4c, +0x55,0x68,0x6, 0x6e,0xe4,0xff,0xff,0xb, 0xe4,0xbd,0x3e,0x58,0x54,0x4c,0xff,0x78, +0x8, 0x6d,0x44,0x69,0xf0,0x0, 0x2, 0x80,0x1b,0x7c,0xb4,0x14,0xbc,0xbf,0x7f,0x56, +0x78,0x9, 0x1b,0xb5,0xb, 0x5a,0x40,0x6d,0xff,0x80,0x9, 0x1b,0xb5,0xb, 0x5a,0x40, +0x69,0xf6,0x0, 0x2, 0x4c,0x55,0x68,0xc, 0x6e,0x44,0xff,0xff,0xb, 0x44,0x6e,0xf4, +0xff,0xff,0xb, 0xf4,0xbd,0x4e,0x58,0x19,0xbd,0xfe,0x18,0x15,0xa, 0xba,0x7e,0x6d, +0x24,0x2d,0xdb,0x7a,0x6b,0xf0,0xb, 0xa0,0x90,0x60,0x9b,0xe4,0x93,0xbc,0xba,0x28, +0x6, 0xb, 0xf0,0xbc,0x4f,0x38,0x8c,0x7c,0xba,0xda,0xf8,0xda,0x69,0x22,0x7c,0xb7, +0x54,0x7, 0x7e,0x24,0x0, 0x1, 0x22,0x7c,0xa5,0x7c,0xb7,0xc4,0x23,0x54,0x1f,0xa, +0x2b,0x22,0x7e,0x29,0x60,0x4c,0x6a,0x7a,0x29,0x60,0xb, 0x70,0x22,0x7a,0x1d,0x24, +0x7e,0xf, 0x6, 0xf8,0x7e,0xb3,0x2a,0x6e,0x7e,0x37,0x2a,0x53,0x22,0x7a,0x1d,0x24, +0x7e,0xa3,0x2a,0x6e,0x74,0x2, 0xa4,0x7e,0xf, 0x6, 0xf8,0x2d,0x15,0x7e,0xb3,0x2a, +0x6d,0x7e,0x37,0x2a,0x51,0x22,0xca,0x3b,0x6d,0x99,0x7d,0xa9,0x7d,0x89,0x7d,0x39, +0x7d,0x29,0x7d,0xb9,0x75,0x24,0x0, 0x6c,0xaa,0x7e,0x8, 0x4, 0xfc,0x7e,0x78,0x5, +0x7a,0xe4,0x7a,0xb3,0x8, 0x8, 0x7a,0xb3,0x8, 0x9, 0x7a,0xb3,0x26,0xf6,0x7a,0xb3, +0x26,0xf8,0x7a,0xb3,0x26,0xf7,0x7a,0xb3,0x26,0xf9,0x6c,0x99,0x80,0x45,0x12,0xac, +0xc7,0xbd,0xca,0x58,0x4, 0x7d,0xac,0x80,0x6, 0xbd,0xc3,0x8, 0x2, 0x7d,0x3c,0x12, +0xac,0xb6,0xbd,0xdb,0x58,0x2, 0x7d,0xbd,0x7e,0x67,0x2a,0x53,0x12,0xac,0xbe,0x8, +0x2, 0x5, 0x24,0x12,0xac,0xd4,0x8, 0xb, 0x7e,0xb3,0x26,0xf7,0x4, 0x7a,0xb3,0x26, +0xf7,0x80,0xe, 0x12,0xac,0xe2,0x58,0x9, 0x7e,0xb3,0x26,0xf9,0x4, 0x7a,0xb3,0x26, +0xf9,0xb, 0x90,0x90,0x61,0x27,0xe4,0x93,0xbc,0xb9,0x38,0xb2,0x7a,0xa7,0x7, 0xfe, +0x7a,0x37,0x8, 0x2, 0xe5,0x24,0x7a,0xb3,0x8, 0x9, 0x90,0x61,0x27,0xe4,0x93,0x7c, +0x9b,0x74,0x2, 0xac,0x9b,0x2d,0x14,0x2d,0xf4,0x6c,0x99,0x80,0x45,0x12,0xac,0xc7, +0xbd,0xc8,0x58,0x4, 0x7d,0x8c,0x80,0x6, 0xbd,0xc2,0x8, 0x2, 0x7d,0x2c,0x12,0xac, +0xb6,0xbd,0xd9,0x58,0x2, 0x7d,0x9d,0x7e,0x67,0x2a,0x51,0x12,0xac,0xbe,0x8, 0x2, +0xb, 0xa0,0x12,0xac,0xd4,0x8, 0xb, 0x7e,0xb3,0x26,0xf6,0x4, 0x7a,0xb3,0x26,0xf6, +0x80,0xe, 0x12,0xac,0xe2,0x58,0x9, 0x7e,0xb3,0x26,0xf8,0x4, 0x7a,0xb3,0x26,0xf8, +0xb, 0x90,0x90,0x61,0x26,0xe4,0x93,0xbc,0xb9,0x38,0xb2,0x7a,0x87,0x7, 0xfc,0x7a, +0x27,0x8, 0x0, 0x7a,0xa3,0x8, 0x8, 0x7a,0x97,0x8, 0x4, 0x7a,0xb7,0x8, 0x6, 0xbd, +0x8a,0x58,0x2, 0x7d,0xa8,0x7a,0xa7,0x7, 0xf8,0xbd,0x32,0x58,0x2, 0x7d,0x32,0x7a, +0x37,0x7, 0xfa,0xda,0x3b,0x22,0x2d,0x7f,0x7d,0x6e,0xb, 0x3a,0xd0,0x22,0x7e,0x74, +0x0, 0x3, 0xad,0x76,0xbd,0xc7,0x22,0x7e,0xf0,0x2, 0xac,0xf9,0x7f,0x60,0x2d,0xd7, +0xb, 0x6a,0xc0,0x22,0x7e,0x74,0x62,0x10,0x7e,0x64,0x0, 0xff,0xb, 0x3a,0xd0,0xbd, +0xcd,0x22,0x7e,0xf0,0x2, 0xac,0xf9,0x2d,0x71,0x7d,0x60,0xb, 0x3a,0xc0,0x6e,0xd4, +0xff,0xff,0xb, 0xd4,0xbd,0xcd,0x22,0x6c,0x33,0x80,0x9, 0xe4,0xa, 0x33,0x19,0xb3, +0x27,0x72,0xb, 0x30,0x90,0x60,0x9a,0xe4,0x93,0x12,0xab,0x5b,0xb, 0x24,0xa, 0x33, +0xbd,0x32,0x48,0xe7,0xe4,0x7a,0xb3,0x28,0x84,0x7a,0xb3,0x28,0x85,0x6d,0x33,0x7a, +0x37,0x28,0x86,0x7a,0x37,0x28,0x88,0x7a,0x37,0x28,0x8a,0x7a,0x37,0x28,0x8e,0x7e, +0xd4,0x1f,0x36,0x5e,0xd4,0xff,0xfe,0x6d,0xcc,0x7e,0x1f,0x13,0x8a,0x7a,0x37,0x1f, +0x76,0x7d,0x3d,0x7a,0x37,0x1f,0x7a,0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f,0x78,0x7e, +0x73,0x2a,0x6d,0x7a,0x73,0x1f,0x73,0x7e,0x73,0x2a,0x6e,0x7a,0x73,0x1f,0x72,0x7e, +0x37,0x2a,0x5c,0x7a,0x37,0x1f,0x7c,0x7e,0x37,0x2a,0x5e,0x7a,0x37,0x1f,0x7e,0x7e, +0x37,0x2a,0x60,0x7a,0x37,0x1f,0x80,0x90,0x60,0x9a,0x93,0x7a,0xb3,0x1f,0x74,0x7e, +0x73,0x3b,0x1a,0x7a,0x73,0x1f,0x75,0x7e,0x8, 0x1f,0x72,0x7e,0x18,0x1f,0x82,0x12, +0x6, 0x52,0x7e,0x73,0x1f,0x82,0x7a,0x73,0x28,0x84,0x7e,0x73,0x1f,0x83,0x7a,0x73, +0x28,0x85,0x7e,0x37,0x1f,0x84,0x7a,0x37,0x28,0x86,0x7e,0x37,0x1f,0x86,0x7a,0x37, +0x28,0x88,0x7e,0x37,0x1f,0x8c,0x7a,0x37,0x28,0x8a,0x7e,0x37,0x1f,0x8e,0x7d,0x23, +0x7a,0x53,0x28,0x8c,0xa, 0x36,0x7a,0x73,0x28,0x8d,0x7e,0x37,0x1f,0x88,0x7a,0x37, +0x28,0x8e,0x7e,0x37,0x1f,0x8a,0x7d,0x23,0x7a,0x53,0x28,0x90,0xa, 0x36,0x7a,0x73, +0x28,0x91,0x6c,0x33,0x80,0x20,0x7c,0xb3,0x7e,0x70,0x1, 0x12,0x3f,0x90,0x74,0x2, +0xac,0xb3,0x49,0x45,0x15,0x9e,0xa, 0x38,0x7c,0x27,0x19,0x25,0x26,0xfa,0x7c,0x29, +0x19,0x25,0x26,0xfb,0xb, 0x30,0x7e,0x23,0x28,0x84,0xbc,0x23,0x38,0xd8,0x6c,0x33, +0x80,0x1b,0x74,0x2, 0xac,0xb3,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0x40,0xa, 0x38,0x7c, +0x27,0x19,0x25,0x27,0x36,0x7c,0x29,0x19,0x25,0x27,0x37,0xb, 0x30,0x7e,0x23,0x28, +0x85,0xbc,0x23,0x38,0xdd,0x22,0x7e,0x18,0x5, 0xf8,0x7a,0x1f,0x6, 0xf4,0x22,0x6d, +0x33,0x7d,0x23,0x7d,0x3, 0x6c,0x33,0x80,0x45,0x6c,0x22,0x80,0x37,0x7e,0xb3,0x2a, +0x6e,0xac,0xb3,0xa, 0x42,0x2d,0x54,0x7d,0x45,0x3e,0x44,0x7e,0x7f,0x13,0x8a,0x2d, +0xf4,0xb, 0x7a,0x40,0xbe,0x44,0x0, 0x32,0x8, 0x8, 0xbe,0x44,0x2, 0x58,0x58,0x2, +0xb, 0x24,0xbe,0x44,0xff,0xce,0x58,0x8, 0xbe,0x44,0xfd,0xa8,0x8, 0x2, 0xb, 0x4, +0xb, 0x34,0xb, 0x21,0x7e,0x93,0x2a,0x6e,0xbc,0x92,0x38,0xc1,0xb, 0x31,0x7e,0xb3, +0x2a,0x6d,0xbc,0xb3,0x38,0xb3,0x7e,0x54,0x0, 0x6, 0xad,0x53,0x7d,0x15,0x1e,0x14, +0x1e,0x14,0x1e,0x14,0x12,0x1f,0x87,0xbd,0x12,0x50,0x22,0xbd,0x30,0x28,0x1e,0xe4, +0x7a,0xb3,0x3b,0x14,0x7e,0xb3,0x3b,0x15,0xbe,0xb0,0x5, 0x50,0x7, 0x4, 0x7a,0xb3, +0x3b,0x15,0x80,0x3c,0xe4,0x7a,0xb3,0x3b,0x15,0x74,0x1, 0x80,0x2f,0xbd,0x10,0x50, +0x22,0xbd,0x32,0x28,0x1e,0xe4,0x7a,0xb3,0x3b,0x15,0x7e,0xb3,0x3b,0x14,0xbe,0xb0, +0x5, 0x50,0x7, 0x4, 0x7a,0xb3,0x3b,0x14,0x80,0x16,0xe4,0x7a,0xb3,0x3b,0x14,0x74, +0x2, 0x80,0x9, 0xe4,0x7a,0xb3,0x3b,0x14,0x7a,0xb3,0x3b,0x15,0x7a,0xb3,0x3b,0x16, +0x7e,0xb3,0x3b,0x16,0x22,0x7c,0xab,0xbe,0xa0,0x0, 0x40,0x11,0x7e,0xb3,0x2a,0x6e, +0xbc,0xba,0x28,0x9, 0x74,0x2, 0xa4,0x49,0x25,0x34,0x0, 0x80,0x51,0x7e,0x13,0x2a, +0x6e,0xbc,0x1a,0x38,0x1c,0x7e,0x3, 0x2a,0x6d,0xa, 0x10,0xa, 0x21,0x2d,0x12,0xa, +0x3a,0xbd,0x31,0x58,0xc, 0x9d,0x32,0x3e,0x34,0x3e,0x34,0x49,0x23,0x3, 0x6d,0x80, +0x2d,0x7e,0x3, 0x2a,0x6d,0xa, 0x20,0xa, 0x11,0x7d,0x41,0x2d,0x42,0xa, 0x3a,0xbd, +0x34,0x48,0x19,0x7e,0x10,0x2, 0xac,0x1, 0x2d,0x1, 0xbd,0x30,0x58,0xe, 0x9d,0x31, +0x9d,0x32,0x3e,0x34,0x3e,0x34,0x49,0x23,0x3, 0x6f,0x80,0x2, 0xe4,0x22,0x7e,0x34, +0x0, 0x64,0xad,0x23,0x74,0xc, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14, +0x78,0xf4,0x7c,0xb7,0x22,0xca,0xf8,0x80,0x38,0x7c,0xbf,0x12,0xaf,0x5, 0xa, 0x1b, +0x7e,0x63,0x2a,0x6e,0x7e,0x70,0x2, 0xac,0x67,0x7e,0x10,0x2, 0xac,0x1f,0x2d,0x3, +0x7e,0x1f,0x13,0x8a,0x2d,0x30,0x12,0xaf,0xc4,0x9d,0x35,0x1b,0x1a,0x10,0xb, 0xf0, +0x12,0xaf,0xc4,0x7e,0x73,0x2a,0x6e,0xa, 0x27,0x2d,0x25,0xa, 0x3f,0xbd,0x32,0x48, +0xc8,0xda,0xf8,0x22,0x7e,0xa3,0x2a,0x6d,0x74,0x2, 0xa4,0x22,0xca,0xf8,0x6c,0xff, +0x80,0x34,0x7e,0x73,0x0, 0x5c,0xbc,0x7f,0x68,0x2a,0x7e,0x30,0x5, 0xac,0x3f,0x12, +0xb0,0x5e,0xca,0x39,0x7e,0x30,0x38,0xac,0x3f,0x12,0xb0,0x53,0x12,0x1b,0x93,0x1b, +0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x30,0x8c,0xac,0x3f,0x12,0xb0,0x48,0x12, +0x1b,0x93,0x1b,0xfd,0xb, 0xf0,0x90,0x61,0xc5,0xe4,0x93,0xbc,0xbf,0x38,0xc3,0x7e, +0x23,0x0, 0x5c,0x7e,0x30,0x5, 0xac,0x23,0x12,0xb0,0x5e,0xca,0x39,0x7e,0x23,0x0, +0x5c,0x7e,0x30,0x38,0xac,0x23,0x12,0xb0,0x53,0x12,0x1b,0x93,0x1b,0xfd,0x7e,0x34, +0x0, 0x8c,0xca,0x39,0x7e,0x23,0x0, 0x5c,0x7e,0x30,0x8c,0xac,0x23,0x12,0xb0,0x48, +0x12,0x1b,0x93,0x1b,0xfd,0xda,0xf8,0x22,0x2e,0x14,0x1, 0x3d,0x6d,0x0, 0x7e,0x18, +0x3, 0x6d,0x22,0x2e,0x14,0x0, 0x5d,0x6d,0x0, 0x7e,0x18,0x34,0x0, 0x22,0x2e,0x14, +0x26,0x33,0x6d,0x0, 0x12,0x35,0x96,0x7e,0x34,0x0, 0x38,0x22,0x7e,0x37,0x28,0x8a, +0xbe,0x34,0x3, 0xe8,0x8, 0xa, 0x12,0x87,0x4a,0xbe,0xb0,0x8, 0x48,0x2, 0xd3,0x22, +0xc3,0x22,0xca,0xf8,0x7c,0xfb,0x7f,0x61,0x7f,0x50,0x7e,0x34,0x1d,0x4f,0x7e,0x24, +0x0, 0xff,0x7e,0x14,0x1f,0x70,0x74,0x2a,0x12,0x19,0xa0,0x7e,0x48,0x1f,0x70,0x12, +0xb0,0x6c,0x92,0xa, 0x7c,0xbf,0x7e,0x71,0x54,0x12,0x3b,0x73,0x7d,0x43,0xe5,0x55, +0x7e,0x71,0x56,0x12,0x3b,0x73,0x2d,0x34,0xe, 0x34,0x7f,0x4, 0x7e,0x50,0x7, 0xb, +0xa, 0x50,0xbd,0x53,0x58,0x10,0x69,0x30,0x0, 0x2, 0x1b,0x5a,0x30,0x69,0x30,0x0, +0x4, 0x1b,0x6a,0x30,0x80,0x8, 0x2e,0x14,0x0, 0x6, 0x1b,0x50,0x78,0xe1,0x12,0xb1, +0x11,0x28,0x2b,0xb, 0x5a,0x20,0x7e,0x34,0x0, 0xd, 0xad,0x32,0x7e,0x24,0x0, 0x10, +0x12,0x18,0xac,0x1b,0x5a,0x30,0xb, 0x6a,0x30,0x1a,0x26,0x1a,0x24,0x7e,0x14,0x0, +0xd, 0x12,0x18,0xef,0x7e,0x8, 0x0, 0x10,0x12,0x19,0x4b,0x1b,0x6a,0x30,0xda,0xf8, +0x22,0x7e,0x73,0x31,0xf4,0xbe,0x70,0x5, 0x22,0xca,0x79,0x7f,0x70,0x7e,0xb4,0xff, +0xff,0x6c,0xee,0xc2,0x1, 0xc2,0x2, 0x29,0x67,0x0, 0x2, 0x7e,0x7b,0x70,0xbc,0x76, +0x78,0xe, 0x29,0x67,0x0, 0x3, 0x29,0x77,0x0, 0x1, 0xbc,0x76,0x78,0x2, 0xd2,0x2, +0x6c,0xff,0x12,0xb2,0xe3,0x6d,0xaa,0x29,0xb6,0x0, 0x5, 0x20,0xe1,0x2, 0x21,0xd3, +0x7f,0x6, 0x7e,0x7b,0xb0,0x12,0x6e,0xc9,0x50,0x2d,0x7f,0x6, 0x29,0xb7,0x0, 0x2, +0x12,0x6e,0xc9,0x50,0x22,0x7f,0x6, 0x29,0xb7,0x0, 0x1, 0x6c,0x77,0x12,0x6e,0x94, +0x50,0x15,0x7f,0x6, 0x29,0xb7,0x0, 0x3, 0x6c,0x77,0x12,0x6e,0x94,0x50,0x8, 0x7c, +0xef,0xd2,0x1, 0x6d,0xbb,0x80,0x55,0x7e,0x6b,0x70,0xa, 0x27,0x7e,0x7b,0x70,0x12, +0x87,0x43,0x2d,0xa3,0x29,0x76,0x0, 0x2, 0xa, 0x27,0x29,0x77,0x0, 0x2, 0x12,0x87, +0x43,0x2d,0xa3,0x29,0x76,0x0, 0x1, 0xa, 0x27,0x29,0x77,0x0, 0x1, 0x12,0x87,0x43, +0x2d,0xa3,0x29,0x76,0x0, 0x3, 0xa, 0x27,0x29,0x77,0x0, 0x3, 0x12,0x87,0x43,0x2d, +0xa3,0xbd,0xab,0x50,0x4, 0x7d,0xba,0x7c,0xef,0xbe,0xa4,0x0, 0x4, 0x38,0x4, 0xd2, +0x1, 0x80,0x9, 0xb, 0xf0,0xbe,0xf0,0x1e,0x50,0x2, 0x21,0x42,0x20,0x1, 0xb, 0x20, +0x2, 0x8, 0xbe,0xb4,0x0, 0x8, 0x50,0x2, 0xd2,0x1, 0x20,0x1, 0x2, 0x41,0x94,0x74, +0x6, 0xac,0xbe,0x12,0xb2,0xe7,0x29,0x76,0x0, 0x5, 0x7c,0xb7,0xc4,0x23,0x54,0x1f, +0xbe,0xb0,0x1f,0x50,0x16,0x7f,0x6, 0x2e,0x14,0x0, 0x5, 0x7c,0x67,0x2e,0x60,0x8, +0x5e,0x60,0xf8,0x5e,0x70,0x7, 0x4c,0x76,0x7a,0xb, 0x70,0x20,0x2, 0x11,0x29,0xb6, +0x0, 0x4, 0xbe,0xb0,0xfa,0x50,0x8, 0x7f,0x16,0xb, 0x36,0x4, 0x7a,0x1b,0xb0,0x29, +0x67,0x0, 0x3, 0x29,0x76,0x0, 0x3, 0xbc,0x76,0x28,0x6, 0x29,0x76,0x0, 0x3, 0x80, +0x4, 0x29,0x77,0x0, 0x3, 0x39,0x76,0x0, 0x3, 0x29,0x67,0x0, 0x2, 0x29,0x76,0x0, +0x2, 0xbc,0x76,0x28,0x6, 0x29,0x76,0x0, 0x2, 0x80,0x4, 0x29,0x77,0x0, 0x2, 0x39, +0x76,0x0, 0x2, 0x29,0x67,0x0, 0x1, 0x29,0x76,0x0, 0x1, 0xbc,0x76,0x50,0x6, 0x29, +0x76,0x0, 0x1, 0x80,0x4, 0x29,0x77,0x0, 0x1, 0x39,0x76,0x0, 0x1, 0x7e,0x7b,0x60, +0x7e,0x6b,0x70,0xbc,0x76,0x50,0x5, 0x7e,0x6b,0x70,0x80,0x3, 0x7e,0x7b,0x70,0x7a, +0x6b,0x70,0x80,0x31,0x6c,0xff,0x74,0x6, 0xac,0xbf,0x9, 0xb5,0x32,0x58,0x30,0xe1, +0x7, 0xb, 0xf0,0xbe,0xf0,0x1e,0x40,0xee,0xbe,0xf0,0x1e,0x50,0x33,0x74,0x1, 0x39, +0xb7,0x0, 0x4, 0x12,0xb2,0xe3,0x7e,0x34,0x0, 0x6, 0xca,0x39,0x7f,0x17,0x7f,0x6, +0x12,0x1b,0x93,0x1b,0xfd,0x12,0x46,0x83,0x44,0x1, 0x7a,0x1b,0xb0,0x12,0x46,0x83, +0x44,0x2, 0x7a,0x1b,0xb0,0x30,0x2, 0x8, 0x12,0x46,0x83,0x44,0x4, 0x7a,0x1b,0xb0, +0xda,0x79,0x22,0x74,0x6, 0xac,0xbf,0x7d,0xd5,0x2e,0xd4,0x32,0x53,0x6d,0xcc,0x22, +0xca,0x3b,0x7c,0x45,0x7c,0x6, 0x7c,0x57,0x7c,0x1b,0x7e,0x34,0x4, 0xfc,0x7e,0xb3, +0x26,0x83,0x7e,0xf3,0x2a,0x6e,0x7c,0x31,0x7c,0xe0,0x7c,0x25,0x7c,0xa4,0xbc,0x1, +0x50,0x4, 0x7c,0x30,0x7c,0xe1,0xbc,0x45,0x50,0x4, 0x7c,0x24,0x7c,0xa5,0xbe,0xb0, +0x1, 0x50,0x2, 0x61,0xb9,0x7e,0x90,0x2, 0xac,0x9f,0x7e,0x50,0x2, 0xac,0x53,0x2d, +0x24,0x2d,0x23,0xb, 0x28,0x20,0x7e,0x10,0x2, 0xac,0x1e,0x2d,0x4, 0x2d,0x3, 0xb, +0x8, 0x40,0xa, 0x3, 0xb, 0x4, 0x7c,0x31,0x80,0x2a,0x7e,0xd0,0x2, 0xac,0xdf,0x7e, +0x10,0x2, 0xac,0x13,0x2d,0x6, 0x12,0xb3,0xbd,0xbd,0xdb,0x58,0x15,0xad,0xf4,0xbd, +0xdf,0x58,0xf, 0xbe,0x24,0x0, 0x0, 0x8, 0x9, 0xbe,0x44,0x0, 0x0, 0x8, 0x3, 0xc3, +0x80,0x48,0xb, 0x30,0xbc,0xe3,0x38,0xd2,0x7e,0x50,0x2, 0xac,0x52,0x2d,0x23,0xb, +0x28,0x20,0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x43,0xb, 0x48,0x40,0xa, 0x12,0xb, 0x14, +0x80,0x23,0x7e,0x10,0x2, 0xac,0x13,0x12,0xb3,0xbd,0xbd,0xdb,0x58,0x15,0xad,0xf4, +0xbd,0xdf,0x58,0xf, 0xbe,0x24,0x0, 0x0, 0x8, 0x9, 0xbe,0x44,0x0, 0x0, 0x8, 0x3, +0xc3,0x80,0x7, 0xb, 0x30,0xbc,0xa3,0x38,0xd9,0xd3,0xda,0x3b,0x22,0x2d,0x3, 0xb, +0x8, 0x0, 0x7e,0xf4,0x0, 0x9, 0x7d,0xb2,0xad,0xbf,0x7e,0xd4,0x0, 0xa, 0xad,0xd0, +0x22,0x12,0xb2,0xf0,0x92,0x4, 0x30,0x4, 0xc, 0x7e,0xb3,0x32,0x52,0xbe,0xb0,0xfa, +0x50,0x11,0x4, 0x80,0xa, 0x7e,0xb3,0x32,0x52,0xbe,0xb0,0x0, 0x28,0x5, 0x14,0x7a, +0xb3,0x32,0x52,0x7e,0xb3,0x32,0x52,0x70,0x2, 0xc3,0x22,0xd3,0x22,0x7e,0xa3,0x2a, +0x6e,0xa, 0x3a,0x3e,0x34,0x7e,0x8, 0x13,0x8e,0xe4,0x12,0x1b,0xb8,0x90,0x60,0x93, +0x93,0xa, 0x3b,0x7e,0xb3,0x2a,0x6d,0xa, 0x2b,0x2d,0x23,0xa, 0x3a,0xad,0x32,0x7d, +0x43,0x6c,0x77,0x80,0x1d,0xa, 0x27,0x2d,0x24,0x12,0xb4,0x47,0xb, 0xa, 0x0, 0x7e, +0x30,0x2, 0xac,0x37,0x2e,0x14,0x13,0x8e,0xb, 0x18,0x20,0x2d,0x20,0x1b,0x18,0x20, +0xb, 0x70,0xbc,0xa7,0x38,0xdf,0x22,0x3e,0x24,0x7e,0xf, 0x3a,0xe5,0x2d,0x12,0x22, +0x6c,0xaa,0x80,0x1c,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x13,0xc6,0x49,0x32,0x13, +0x8e,0xbd,0x31,0x28,0x9, 0x2e,0x24,0x13,0x8e,0x9d,0x31,0x1b,0x28,0x30,0xb, 0xa0, +0x7e,0xb3,0x2a,0x6e,0xbc,0xba,0x38,0xdc,0x22,0xca,0x78,0xa9,0x31,0xe5,0x6, 0xa9, +0xd5,0xea,0xa9,0xc5,0xea,0xa9,0x30,0xe5,0x19,0xa9,0xd0,0x9e,0xa9,0xd4,0x9e,0x5, +0x5b,0x7e,0x73,0x3, 0xfe,0xbe,0x71,0x5b,0x38,0x2, 0xd2,0x19,0xa9,0xd0,0x9e,0xa9, +0xd7,0x9e,0xa9,0x34,0xe5,0x5, 0xa9,0xc4,0xcd,0xc2,0x95,0xa9,0x32,0xe5,0x3, 0xa9, +0xc2,0xcd,0xa9,0x33,0xe5,0x3, 0xa9,0xc3,0xcd,0xa9,0x37,0xe5,0x3, 0xa9,0xc7,0xcd, +0xa9,0x36,0xe5,0x3, 0xa9,0xc6,0xcd,0xda,0x78,0x32,0xc2,0x9a,0xa9,0xd4,0xa6,0xc2, +0x88,0xd2,0xa8,0x22,0x7e,0x14,0xd7,0xe8,0x7e,0x4, 0x0, 0xff,0x7e,0x34,0x47,0x52, +0x7e,0x24,0x55,0x50,0x79,0x30,0x0, 0x2, 0x1b,0xa, 0x20,0x7e,0x34,0x45,0x20,0x7e, +0x24,0x41,0x44,0x79,0x30,0x0, 0x6, 0x79,0x20,0x0, 0x4, 0x7e,0x34,0x99,0x33,0x7e, +0x24,0x66,0xcc,0x79,0x30,0x0, 0xa, 0x79,0x20,0x0, 0x8, 0x7e,0x34,0x41,0x47,0x7e, +0x24,0x46,0x4c,0x79,0x30,0x0, 0xe, 0x79,0x20,0x0, 0xc, 0x22,0xa9,0xd5,0xcb,0x74, +0x10,0x12,0x0, 0x66,0x7c,0x7b,0x12,0x2e,0xed,0x30,0xe7,0x3, 0x7e,0x70,0x2, 0xd2, +0xcd,0x7e,0x24,0x0, 0xef,0x7e,0xf, 0x3a,0xcc,0x79,0x20,0x0, 0x84,0x7e,0x24,0x20, +0x5f,0x7e,0xf, 0x3a,0xcc,0x79,0x20,0x0, 0x82,0x7e,0x24,0x41,0x0, 0x7e,0xf, 0x3a, +0xcc,0x79,0x20,0x0, 0x90,0x7c,0x67,0x6c,0x77,0x2e,0x34,0x0, 0xc1,0x7e,0xf, 0x3a, +0xcc,0x79,0x30,0x0, 0x86,0x7e,0x34,0x29,0x90,0x7e,0xf, 0x3a,0xcc,0x79,0x30,0x0, +0x8a,0x7e,0x34,0x6a,0xd1,0x7e,0xf, 0x3a,0xcc,0x79,0x30,0x0, 0x8c,0x7e,0x34,0x3, +0x61,0x7e,0xf, 0x3a,0xcc,0x79,0x30,0x0, 0x8e,0x22,0xa9,0xc6,0xeb,0xa9,0xd6,0xac, +0xa9,0xd6,0xec,0xd2,0x86,0x22,0x75,0x9a,0x2f,0xa9,0xd1,0x99,0xd2,0x9c,0xa9,0xd6, +0xdf,0x22,0xc2,0x8e,0x43,0x89,0x20,0x75,0x8d,0x1, 0x75,0x8b,0x0, 0xd2,0x8e,0xd2, +0xab,0x22,0x75,0xb7,0x0, 0x75,0xb8,0x0, 0x75,0xf7,0x0, 0x75,0xf8,0x0, 0xa9,0xd0, +0xb7,0xd2,0xb8,0xa9,0xd5,0xb7,0xd2,0xbd,0xa9,0xd0,0xf7,0xd2,0xf8,0xa9,0xc1,0xb7, +0xc2,0xb9,0xa9,0xc3,0xb7,0xc2,0xbb,0xa9,0xc6,0xb7,0xc2,0xbe,0x22,0x75,0xe7,0x6b, +0x2, 0xb5,0xe3,0xe4,0x7e,0x34,0xd7,0xfc,0x7e,0x24,0x0, 0xff,0x7a,0x1b,0xb0,0x7e, +0x34,0xd7,0xfd,0x7a,0x1b,0xb0,0x75,0xe9,0xff,0x22,0xa9,0xd0,0x99,0xa9,0xc6,0xdf, +0x22,0x7e,0x37,0x3, 0xfc,0xb, 0x34,0x7a,0x37,0x3, 0xfc,0xbe,0x34,0xff,0x0, 0x40, +0x8, 0x7e,0x34,0xff,0x0, 0x7a,0x37,0x3, 0xfc,0x22,0x6d,0x22,0x80,0x13,0x75,0xb5, +0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0xe5,0xb5,0x7a,0xb, 0xb0,0xb, 0x14,0xb, +0x24,0xbd,0x32,0x38,0xe9,0x22,0x7f,0x71,0x69,0x37,0x0, 0x2, 0x7d,0x53,0x12,0xb6, +0x90,0xb, 0x7a,0x20,0x2d,0x25,0x1b,0xa, 0x20,0x69,0x27,0x0, 0x4, 0x7d,0x52,0xc4, +0x54,0xf0,0x7c,0xab,0xe4,0x1e,0x34,0x1e,0x34,0x2d,0x35,0x79,0x30,0x0, 0x2, 0x69, +0x37,0x0, 0x6, 0x7d,0x53,0x7c,0xab,0xe4,0x3e,0x54,0x3e,0x54,0x1e,0x24,0x1e,0x24, +0x1e,0x24,0x1e,0x24,0x2d,0x25,0x79,0x20,0x0, 0x4, 0x69,0x27,0x0, 0x8, 0x7c,0x45, +0x6c,0x55,0x12,0x1f,0x85,0x1e,0x34,0x1e,0x34,0x2d,0x32,0x79,0x30,0x0, 0x6, 0x22, +0x3, 0x3, 0x54,0xc0,0x7c,0xab,0xe4,0x22,0x6d,0x33,0x90,0x60,0x91,0xe4,0x93,0xbe, +0xb0,0x0, 0x28,0x3, 0x2, 0xb9,0xff,0x90,0x60,0x92,0xe4,0x93,0xbe,0xb0,0x0, 0x28, +0x3, 0x2, 0xb7,0x5, 0x22,0x12,0x67,0xe2,0x7e,0x34,0xd, 0xc8,0x7e,0xb3,0x2a,0x6d, +0x12,0xb6,0xd1,0x12,0xb6,0x98,0x7a,0x37,0x3a,0xe2,0x74,0x1, 0x7a,0xb3,0x16,0x91, +0x22,0x7a,0xb3,0x24,0xf2,0x7e,0x53,0x2a,0x6e,0x7a,0x53,0x24,0xf3,0x7a,0x37,0x24, +0xfa,0xe4,0x7a,0xb3,0x24,0xf4,0x7a,0xb3,0x24,0xf5,0x7e,0x34,0x40,0x0, 0x7a,0x37, +0x24,0xf6,0x7e,0x34,0x0, 0x20,0x12,0xb6,0xfc,0x2, 0xb, 0x4d,0x7a,0x37,0x24,0xfc, +0x7e,0x8, 0x24,0xf2,0x22,0xca,0xf8,0x6d,0xee,0x7d,0xfe,0x7e,0x83,0x2a,0x6e,0xa, +0xd8,0x90,0x60,0x94,0xe4,0x93,0xb4,0xff,0x2f,0x7e,0x8, 0x13,0x8e,0x6c,0xaa,0x80, +0x18,0x7e,0x70,0x2, 0xac,0x7a,0x49,0x23,0x13,0xfe,0x7f,0x50,0x2d,0xb3,0xb, 0x5a, +0xc0,0x9d,0xc2,0x59,0xc3,0x13,0xc6,0xb, 0xa0,0xbc,0x8a,0x38,0xe4,0x90,0x60,0x92, +0xe4,0x93,0x7c,0x9b,0x6d,0xdd,0x80,0x11,0x7e,0x8, 0x13,0xfe,0x90,0x60,0x92,0xe4, +0x93,0xa, 0xcb,0x1b,0xc4,0x7d,0x3c,0x7c,0x97,0x6c,0xff,0x80,0x38,0x6c,0xaa,0x80, +0x28,0xa, 0x3a,0x7d,0x23,0x2d,0x2e,0x3e,0x24,0x49,0xc2,0x13,0xfe,0x2d,0x3d,0x3e, +0x34,0x2d,0x31,0x7d,0x20,0xb, 0x1a,0xb0,0x7d,0x3c,0x9d,0x3b,0x12,0x1b,0xfa,0x7d, +0xa3,0xbd,0xfa,0x58,0x2, 0x7d,0xfa,0xb, 0xa0,0xbc,0x8a,0x38,0xd4,0xa, 0xc8,0x2d, +0xec,0x2d,0xdc,0xb, 0xf0,0xbc,0x9f,0x38,0xc4,0x7d,0x3f,0xda,0xf8,0x22,0xca,0xd8, +0xca,0x79,0x7c,0xf7,0x7f,0x70,0x12,0xb9,0xad,0x7c,0xeb,0x6c,0xdd,0x80,0x20,0x74, +0x2, 0xac,0xbd,0x7f,0x67,0x2d,0xd5,0xb, 0x6a,0x30,0x6d,0x22,0x74,0x4, 0x2f,0x11, +0x14,0x78,0xfb,0xa, 0x1e,0x6d,0x0, 0x12,0x18,0xfa,0x1b,0x6a,0x30,0xb, 0xd0,0xbc, +0xfd,0x38,0xdc,0xda,0x79,0xda,0xd8,0x22,0x7e,0xb3,0x38,0xcf,0x22,0x7c,0xab,0x9f, +0x11,0x30,0x0, 0x22,0x6c,0x99,0x80,0x1a,0xa, 0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b, +0xb0,0x7e,0x78,0x0, 0x1, 0x60,0x5, 0x2f,0x77,0x14,0x78,0xfb,0x4d,0x3f,0x4d,0x2e, +0xb, 0x90,0xbc,0xa9,0x38,0xe2,0x22,0x7c,0x57,0x7c,0xab,0x6c,0x77,0x80,0x50,0xa, +0x47,0x7e,0x7d,0x24,0x2d,0xf4,0x7e,0x7b,0x60,0xa, 0x46,0x2e,0x44,0x1b,0x4d,0x7a, +0x91,0x82,0x7a,0x81,0x83,0xe4,0x93,0x7c,0x6b,0xbe,0x60,0xd, 0x38,0x12,0x7e,0xd4, +0x0, 0x1, 0x7c,0xb6,0x60,0x5, 0x3e,0xd4,0x14,0x78,0xfb,0x7e,0x7d,0x28,0x80,0x15, +0x9e,0x60,0xe, 0x7e,0xd4,0x0, 0x1, 0x7c,0xb6,0x60,0x5, 0x3e,0xd4,0x14,0x78,0xfb, +0x7e,0x7d,0x28,0xb, 0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40,0xb, 0x70,0xbc, +0x57,0x38,0xac,0x6c,0x77,0x80,0x58,0xa, 0x27,0x7f,0x70,0x2d,0xf2,0x7e,0x7b,0x60, +0xbe,0x60,0xd, 0x38,0x11,0x12,0xb8,0xc4,0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb,0x7e, +0x7d,0x28,0xb, 0xf6,0x80,0x2f,0xbe,0x60,0x1b,0x38,0x16,0x9e,0x60,0xe, 0x12,0xb8, +0xc4,0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb,0x7e,0x7d,0x28,0x2e,0xf4,0x0, 0x6, 0x80, +0x14,0x9e,0x60,0x1c,0x12,0xb8,0xc4,0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb,0x7e,0x7d, +0x28,0x2e,0xf4,0x0, 0x8, 0xb, 0x7a,0x20,0x4d,0x24,0x1b,0x7a,0x20,0xb, 0x70,0xbc, +0xa7,0x38,0xa4,0x22,0x7e,0x44,0x0, 0x1, 0x7c,0xb6,0x22,0xca,0xf8,0x12,0x5f,0xc9, +0x7e,0x8, 0x1f,0x34,0x12,0xb9,0x53,0x7e,0x8, 0x1f,0x3c,0x12,0xb9,0x5b,0xd2,0x0, +0x7e,0x8, 0x2a,0xd8,0x7c,0xbf,0x12,0xb7,0xdd,0x7e,0x8, 0x1f,0x34,0x7a,0xf, 0x1f, +0x58,0x7f,0x1, 0x7a,0x17,0x1f,0x5c,0x7d,0x32,0x7a,0x37,0x1f,0x5e,0x7e,0x18,0x1f, +0x3c,0x7a,0x1f,0x1f,0x64,0x6c,0x77,0x80,0xe, 0x12,0xb9,0xa3,0x50,0x7, 0x12,0xb9, +0x9a,0x19,0x51,0x1f,0x3c,0xb, 0x70,0xbc,0xf7,0x38,0xee,0x12,0xb9,0x40,0xe4,0x12, +0xb9,0x48,0xe4,0x12,0xa, 0xe1,0x6d,0x33,0x7a,0x37,0x1f,0x5c,0x7a,0x37,0x1f,0x5e, +0x12,0xb9,0x40,0x74,0x1, 0x12,0xb9,0x48,0x74,0x1, 0x12,0xa, 0xe1,0xda,0xf8,0x22, +0xa9,0xc6,0xea,0x7e,0x8, 0x1f,0x58,0x22,0x12,0xa, 0xe1,0xa9,0xd6,0xea,0x7e,0x8, +0x1f,0x58,0x22,0x7e,0x34,0x0, 0x8, 0xe4,0x2, 0x1b,0xb8,0x7e,0x34,0x0, 0x1c,0x74, +0x3f,0x2, 0x1b,0xb8,0x7e,0x8, 0x1f,0x34,0x12,0xb9,0x5b,0x6c,0x77,0x80,0xe, 0x12, +0xb9,0xa3,0x50,0x7, 0x12,0xb9,0x9a,0x19,0x51,0x1f,0x34,0xb, 0x70,0x7e,0x53,0x2a, +0x6e,0xbc,0x57,0x38,0xea,0xa9,0xc6,0xea,0x7e,0x8, 0x1f,0x34,0xe4,0x12,0x10,0x0, +0xa9,0xd6,0xea,0x7e,0x8, 0x1f,0x34,0x2, 0x10,0x0, 0xa, 0x27,0x9, 0x52,0x2b,0x40, +0xa, 0x16,0x22,0xa, 0x27,0x9, 0x62,0x2a,0xd8,0xbe,0x60,0x1c,0x22,0x7c,0x7b,0xa5, +0xbf,0x0, 0x3, 0x74,0x10,0x22,0xbe,0x70,0x4, 0x38,0x4, 0x6c,0xaa,0x80,0x21,0xbe, +0x70,0x8, 0x38,0x5, 0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x70,0x10,0x38,0x5, 0x7e,0xa0, +0x2, 0x80,0xd, 0xbe,0x70,0x20,0x38,0x5, 0x7e,0xa0,0x3, 0x80,0x3, 0x7e,0xa0,0x4, +0xa, 0x47,0x3e,0x44,0x3e,0x44,0x3e,0x44,0x7c,0xba,0x60,0x5, 0x1e,0x44,0x14,0x78, +0xfb,0x7c,0xb9,0x22,0x7a,0xb3,0x38,0xda,0x22,0x90,0x61,0x81,0xe4,0x93,0x22,0xca, +0xf8,0x6d,0x44,0x7e,0xf3,0x2a,0x6e,0x90,0x60,0x93,0xe4,0x93,0xa, 0xfb,0x7e,0xb3, +0x2a,0x6d,0xa, 0xeb,0x2d,0xef,0xa, 0xff,0xad,0xfe,0xa, 0xef,0x2d,0xef,0x90,0x60, +0x94,0xe4,0x93,0xb4,0xff,0x31,0x7e,0x8, 0x13,0x8e,0x6c,0xaa,0x80,0x23,0xa, 0xda, +0x2d,0xdf,0x3e,0xd4,0x7e,0x1f,0x3a,0xe5,0x2d,0x3d,0xb, 0x1a,0xd0,0x7e,0x50,0x2, +0xac,0x5a,0x7f,0x50,0x2d,0xb2,0xb, 0x5a,0x30,0x9d,0x3d,0x59,0x32,0x13,0xc6,0xb, +0xa0,0xbc,0xfa,0x38,0xd9,0x80,0xa, 0x7d,0x5e,0x3e,0x54,0x7e,0xf, 0x3a,0xe5,0x2d, +0x15,0x6c,0xaa,0x80,0x2c,0xa, 0xea,0x2d,0xef,0x3e,0xe4,0x7e,0x1f,0x3a,0xe5,0x2d, +0x3e,0xb, 0x1a,0xe0,0x7e,0x70,0x2, 0xac,0x7a,0x2d,0x31,0x7d,0x20,0xb, 0x1a,0xd0, +0x7d,0x3e,0x9d,0x3d,0x12,0x1b,0xfa,0x7d,0xc3,0xbd,0x4c,0x58,0x2, 0x7d,0x4c,0xb, +0xa0,0xbc,0xfa,0x38,0xd0,0x7d,0x34,0xda,0xf8,0x22,0x7c,0x7b,0xa, 0x57,0x9e,0x54, +0x0, 0x20,0xe, 0x54,0xe, 0x54,0xe, 0x54,0xe, 0x54,0x7c,0xab,0x7c,0x67,0x5e,0x60, +0xf0,0xa5,0xbe,0x20,0x1d,0x7c,0xb7,0x54,0xf, 0x7e,0x24,0x0, 0x1, 0x60,0x5, 0x3e, +0x24,0x14,0x78,0xfb,0x7e,0x73,0x3b,0xd, 0xa, 0x47,0x5d,0x42,0x7e,0x73,0x39,0x0, +0x80,0x36,0xa5,0xbe,0x30,0x18,0x12,0xbb,0xd, 0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb, +0x7e,0x53,0x3b,0xe, 0xa, 0x45,0x5d,0x43,0x7e,0x73,0x39,0x1, 0x80,0x1a,0x12,0xbb, +0xd, 0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0xa, 0x2a,0x9, 0xb2,0x3b,0xd, 0xa, 0x4b, +0x5d,0x43,0xa, 0x5a,0x9, 0x75,0x39,0x2, 0xa, 0x57,0x5d,0x54,0x22,0x7c,0xb7,0x54, +0xf, 0x7e,0x34,0x0, 0x1, 0x22,0x7e,0xb3,0x38,0xff,0x70,0x6, 0x12,0xbb,0x4f,0x2, +0xbc,0xeb,0x12,0x4d,0x6f,0x12,0xbc,0xf1,0x50,0xa, 0x12,0x5f,0x5d,0x7c,0x3b,0x12, +0xbb,0x4f,0x80,0x5, 0x12,0xbb,0x55,0x7c,0x3b,0x4c,0x33,0x68,0x11,0x7c,0xb3,0x12, +0xba,0x9a,0x60,0xa, 0x7a,0x33,0x39,0x2, 0x74,0x1, 0x7a,0xb3,0x2a,0x8, 0x22,0xe4, +0x7a,0xb3,0x2f,0x7c,0x22,0xca,0xd8,0xca,0x79,0x6c,0xff,0x6d,0xdd,0x7d,0xed,0x7d, +0xfd,0x7e,0xd3,0x2a,0x2, 0x7e,0xe3,0x2a,0x3, 0x7e,0xb3,0x33,0xf1,0x60,0x11,0x7e, +0xc7,0x33,0xfa,0x4d,0xcc,0x78,0x2, 0x81,0x53,0xbe,0xd0,0x1, 0x28,0x2, 0x81,0x53, +0xbe,0xd0,0x1, 0x78,0x1d,0xbe,0xb0,0x4, 0x78,0x2, 0x81,0x53,0x7e,0xe7,0x29,0x8, +0x7e,0xf7,0x29,0xa, 0x7d,0x3e,0x7d,0x2f,0x12,0xbc,0xb2,0xbe,0xb0,0x1, 0x78,0x2, +0x81,0x53,0x7e,0xa3,0x33,0xf1,0x7c,0xba,0x14,0x68,0x29,0x14,0x68,0x54,0x14,0x68, +0x23,0x14,0x78,0x2, 0x81,0x46,0xb, 0xb2,0x68,0x2, 0x81,0x53,0xbe,0xd0,0x1, 0x68, +0x2, 0x81,0x62,0x4c,0xee,0x68,0x2, 0x81,0x62,0x74,0x1, 0x7a,0xb3,0x33,0xf1,0x12, +0xbc,0x69,0x80,0x65,0x4c,0xdd,0x78,0x1d,0xbe,0xa0,0x1, 0x78,0xc, 0x74,0x2, 0x7a, +0xb3,0x33,0xf1,0x7e,0x34,0x62,0x64,0x80,0x54,0x74,0x4, 0x7a,0xb3,0x33,0xf1,0x7e, +0x34,0x62,0x68,0x80,0x48,0x12,0xbc,0x72,0x90,0x62,0x57,0x12,0xbc,0x7b,0x68,0x53, +0x80,0x60,0xbe,0xd0,0x1, 0x78,0x5b,0x4c,0xee,0x78,0x57,0x12,0xbc,0x72,0x7e,0x34, +0x62,0x60,0x12,0x1e,0x81,0x7e,0x14,0x62,0x64,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0xc0, +0x9d,0xc3,0xbe,0xc7,0x33,0xfa,0x40,0x2b,0x90,0x62,0x56,0x12,0xbc,0x7b,0x68,0x23, +0x12,0xbc,0x69,0x74,0x3, 0x7a,0xb3,0x33,0xf1,0x7e,0x34,0x62,0x64,0x12,0x1e,0x81, +0x7a,0x37,0x33,0xfa,0x80,0x1c,0x7e,0x37,0x33,0xfa,0xbe,0x34,0x0, 0x32,0x50,0x12, +0x7e,0xf0,0x24,0xe4,0x7a,0xb3,0x33,0xf1,0x6d,0x33,0x7a,0x37,0x33,0xfa,0x7c,0xbf, +0x80,0x2, 0x7c,0xbf,0xda,0x79,0xda,0xd8,0x22,0x7a,0xe7,0x33,0xf2,0x7a,0xf7,0x33, +0xf4,0x22,0x7a,0xe7,0x33,0xf6,0x7a,0xf7,0x33,0xf8,0x22,0xe4,0x93,0xa, 0x3b,0x12, +0xbc,0x87,0xa, 0xdb,0x4d,0xdd,0x22,0x7d,0x13,0x3e,0x14,0x3e,0x14,0x3e,0x14,0x7e, +0x37,0x33,0xf6,0x9e,0x37,0x33,0xf2,0x12,0x1b,0xfa,0xbd,0x31,0x38,0x12,0x7e,0x37, +0x33,0xf8,0x9e,0x37,0x33,0xf4,0x12,0x1b,0xfa,0xbd,0x31,0x38,0x3, 0x74,0x1, 0x22, +0xe4,0x22,0x7d,0x13,0x7e,0x54,0x62,0x58,0x12,0xbc,0xe1,0x50,0x21,0x7e,0x54,0x62, +0x5a,0x12,0xbc,0xe1,0x28,0x18,0x7e,0x14,0x62,0x5c,0x12,0x4f,0x39,0xbd,0x32,0x50, +0xd, 0x7e,0x14,0x62,0x5e,0x12,0x4f,0x39,0xbd,0x32,0x28,0x2, 0xe4,0x22,0x74,0x1, +0x22,0x7e,0x44,0x0, 0xff,0xb, 0x2a,0x30,0xbd,0x31,0x22,0xe4,0x7a,0xb3,0x33,0xf1, +0x22,0x7e,0xb3,0x2f,0x7c,0xb4,0x4, 0x2, 0xd3,0x22,0xc3,0x22,0x7e,0x17,0x2f,0x8c, +0xbd,0x13,0x28,0xa, 0x7a,0x37,0x2f,0x8c,0x7a,0x27,0x2f,0x8e,0x80,0x10,0x7e,0x17, +0x2f,0x84,0xbd,0x13,0x50,0x8, 0x7a,0x37,0x2f,0x84,0x7a,0x27,0x2f,0x86,0x7e,0x17, +0x2f,0x8a,0xbd,0x12,0x28,0xa, 0x7a,0x27,0x2f,0x8a,0x7a,0x37,0x2f,0x88,0x80,0x10, +0x7e,0x17,0x2f,0x92,0xbd,0x12,0x50,0x8, 0x7a,0x27,0x2f,0x92,0x7a,0x37,0x2f,0x90, +0x7e,0xb3,0x2f,0xa4,0xb4,0xa, 0xf, 0x12,0x5f,0x97,0x7a,0x37,0x2f,0x9c,0x12,0x5f, +0x8e,0x7a,0x37,0x2f,0x9e,0x22,0xb4,0x14,0xe, 0x12,0x5f,0x97,0x7a,0x37,0x2f,0xa0, +0x12,0x5f,0x8e,0x7a,0x37,0x2f,0xa2,0x22,0x7e,0xa3,0x2f,0xa4,0xbe,0xa0,0xf0,0x50, +0x17,0x74,0x4, 0xa4,0x59,0x35,0x2b,0xbb,0x12,0x5f,0xc1,0x59,0x25,0x2b,0xbd,0x7e, +0xb3,0x2f,0xa4,0x4, 0x7a,0xb3,0x2f,0xa4,0x22,0x7d,0x51,0x7d,0x12,0x9d,0x35,0x12, +0x1b,0xfa,0x7c,0xa7,0x12,0x5f,0xaa,0x7c,0xb7,0xbc,0xba,0x50,0x3, 0x7c,0xba,0x22, +0x22,0x7d,0xf2,0x7d,0xe3,0x7e,0x8, 0x2f,0x7c,0x7e,0x34,0x0, 0x28,0xe4,0x12,0x1b, +0xb8,0x7e,0x8, 0x2b,0xbb,0x7e,0x34,0x3, 0xc0,0x12,0x1b,0xb8,0x7a,0xb3,0x39,0x2, +0x7e,0x34,0x62,0x8e,0x12,0x1e,0x81,0x7a,0x37,0x2b,0xb3,0x7a,0xe7,0x2f,0x80,0x7a, +0xf7,0x2f,0x82,0x7a,0xe7,0x2f,0x84,0x7a,0xe7,0x2f,0x88,0x7a,0xe7,0x2f,0x8c,0x7a, +0xe7,0x2f,0x90,0x7a,0xf7,0x2f,0x86,0x7a,0xf7,0x2f,0x8a,0x7a,0xf7,0x2f,0x8e,0x7a, +0xf7,0x2f,0x92,0x7a,0xe7,0x2b,0xb7,0x7a,0xf7,0x2b,0xb9,0x7a,0xb3,0x2f,0xa4,0x74, +0x2, 0x7a,0xb3,0x2f,0x7b,0x22,0x74,0xfe,0x7a,0xb3,0x39,0x2, 0xe4,0x7a,0xb3,0x2f, +0x7c,0x22,0x7e,0x8, 0x33,0xfa,0x2, 0x47,0xfd,0xca,0xf8,0x7f,0x51,0x7f,0x40,0x7e, +0x37,0x2f,0x8c,0x7a,0x35,0x2a,0x7e,0x37,0x2f,0x8a,0x7a,0x35,0x2c,0x7e,0x37,0x2f, +0x98,0x7a,0x35,0x26,0x7e,0x37,0x2f,0x9a,0x7a,0x35,0x28,0x6c,0xff,0x80,0x1e,0x7e, +0x34,0x0, 0x26,0x7e,0x14,0x0, 0x2f,0x74,0x9, 0x12,0x19,0x7f,0x74,0x2, 0xac,0xbf, +0x7f,0x4, 0x2d,0x15,0x7f,0x15,0x2d,0x35,0x12,0xbe,0x68,0xb, 0xf0,0x7e,0x73,0x3a, +0xd, 0xbc,0x7f,0x38,0xda,0xda,0xf8,0x22,0x7f,0x71,0x7f,0x60,0x7e,0x35,0x2f,0xbe, +0x34,0x0, 0x0, 0x38,0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x2f,0x7e,0x35,0x31,0xbe, +0x34,0x0, 0x0, 0x38,0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x31,0xb, 0x6a,0x30,0x9e, +0x35,0x33,0x6d,0x22,0x7e,0x33,0x3a,0xf, 0x12,0xbe,0xbd,0x7e,0x15,0x2f,0x12,0x18, +0xf8,0x1b,0x6a,0x30,0xb, 0x7a,0x30,0x9e,0x35,0x35,0x6d,0x22,0x7e,0x33,0x3a,0x10, +0x12,0xbe,0xbd,0x7e,0x15,0x31,0x12,0x18,0xf8,0x1b,0x7a,0x30,0x22,0xa, 0x13,0x6d, +0x0, 0x2, 0x18,0xde,0xca,0x79,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x7f,0x70,0x2d, +0xf4,0xb, 0x7a,0xf0,0x7d,0x7f,0x7c,0xbf,0xa, 0xfa,0x19,0xbf,0x3a,0x11,0x7f,0x71, +0x2d,0xf4,0xb, 0x7a,0x40,0x7c,0xb9,0xa, 0x4a,0x19,0xb4,0x3a,0x31,0xb, 0xa0,0xbe, +0xa0,0x20,0x40,0xd4,0x7e,0x8, 0x3a,0x11,0x7e,0x18,0x3a,0x31,0x74,0x20,0x12,0x85, +0x4, 0xda,0x79,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x73,0x3a,0xd, 0xbe,0x70, +0x20,0x40,0x52,0x7e,0xf0,0x2, 0x80,0x3c,0xa, 0x3f,0x6d,0x22,0x74,0x5, 0x2f,0x11, +0x14,0x78,0xfb,0x7e,0x33,0x3a,0xd, 0xa, 0x13,0x6d,0x0, 0x12,0x18,0xfa,0x7c,0xe7, +0xbe,0xe0,0x2, 0x50,0x3, 0x7e,0xe0,0x2, 0xa, 0x6f,0x1b,0x64,0xa, 0x3e,0x1b,0x34, +0x7c,0xc7,0x7f,0x5, 0x7c,0xbd,0x12,0xbf,0x6e,0x7f,0x6, 0x7c,0xbd,0x7c,0x7c,0x12, +0xbf,0x6e,0xb, 0xf0,0x7e,0x73,0x3a,0xd, 0xbc,0x7f,0x50,0xbc,0x7f,0x5, 0x7f,0x16, +0x12,0xbe,0xc4,0x80,0x6, 0x74,0x7e,0x7a,0xb3,0x3a,0xc, 0xda,0x3b,0x22,0x7c,0x97, +0x7c,0xab,0x7f,0x10,0x7e,0x30,0x2, 0xac,0x3a,0x2d,0x13,0x7d,0x2, 0xb, 0xa, 0x10, +0x7e,0x10,0x2, 0xac,0x19,0x7f,0x71,0x2d,0xf0,0xb, 0x7a,0x0, 0x7c,0x21,0xa5,0xba, +0x0, 0x14,0x1a,0x3, 0x1b,0x7a,0x0, 0xbc,0x9a,0x68,0x24,0x6d,0x44,0x74,0x2, 0xa4, +0x2d,0x35,0x1b,0x1a,0x40,0x22,0xbc,0x9a,0x68,0x15,0x1a,0x2, 0x1a,0x13,0x2d,0x10, +0xe, 0x14,0x1b,0x7a,0x10,0x6d,0x11,0x74,0x2, 0xa4,0x2d,0x35,0x1b,0x1a,0x10,0x22, +0x74,0x1, 0x7a,0xb3,0x2a,0xfd,0x7a,0xb3,0x2b,0x19,0x22,0xa, 0x47,0x7f,0x70,0x2d, +0xf4,0x7e,0x7b,0x60,0xbc,0x6b,0x22,0x6d,0x33,0xe4,0x6c,0x55,0x2, 0x11,0xcf,0xe4, +0x7a,0xb3,0x38,0x37,0x7a,0xb3,0x38,0x3f,0x22,0x74,0x2, 0x12,0x0, 0x1e,0x7e,0x8, +0x6, 0xfc,0x22,0xa, 0x2c,0x2e,0x27,0x2a,0xfa,0x7e,0x29,0x70,0x22,0x7e,0x34,0x0, +0x3e,0x74,0xff,0x2, 0x1b,0xb8,0x7a,0x37,0x2a,0x4f,0x7e,0x34,0x61,0x57,0x22,0xa, +0x5b,0x2e,0x54,0x0, 0x8, 0xf5,0xcc,0x22,0x7a,0xb3,0x30,0x21,0x7e,0x34,0x61,0x5b, +0x22,0xb, 0xa, 0x30,0x2d,0x32,0x1b,0xa, 0x30,0x22,0x7e,0x37,0x25,0xf4,0x7a,0x37, +0x36,0xaa,0x22,0x7e,0x34,0xd, 0xc8,0x7a,0x37,0x36,0xac,0x22,0x12,0x0, 0x1e,0x7e, +0xb3,0x2a,0xf8,0x22,0x7e,0x8, 0x2a,0x6d,0x2, 0x0, 0x2e,0x7e,0x73,0x28,0x84,0xbe, +0x71,0x24,0x22,0xff,0xc0,0x54,0x3f,0xab,0x39,0xc6,0x2, 0x51, diff --git a/drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Biel0x3b_Ver0a_20170119_app.i b/drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Biel0x3b_Ver0a_20170119_app.i new file mode 100644 index 000000000000..b407af8140cf --- /dev/null +++ b/drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Biel0x3b_Ver0a_20170119_app.i @@ -0,0 +1,3186 @@ +0x2, 0x1f,0xd2,0x2, 0xb6,0x1a,0xeb,0xaa,0x8, 0x22,0x22,0x2, 0x0, 0x49,0xb4,0x2, +0x4, 0xa9,0xb7,0xea,0x22,0x24,0xff,0xa9,0x97,0xea,0x22,0x2, 0x50,0x32,0xb4,0x2, +0x4, 0xa9,0xb6,0xea,0x22,0x24,0xff,0xa9,0x96,0xea,0x22,0x2, 0x68,0x4, 0x7f,0x60, +0xa9,0xc2,0xea,0x74,0x1, 0x12,0x13,0x96,0x7f,0x6, 0x12,0x5, 0xb4,0x7f,0x6, 0x2, +0x9, 0xa1,0x22,0x2, 0x68,0x20,0x2, 0x26,0x11,0x32,0x32,0x2, 0x0, 0x4a,0x12,0x10, +0xa2,0x2, 0x13,0x79,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32,0x2, 0x0, 0x76,0x1, 0x2, +0x4, 0x8, 0x10,0x20,0x40,0x80,0xf5,0xfd,0xe5,0xfe,0x22,0x2, 0x0, 0x5a,0xd2,0x1, +0x2, 0x37,0xa6,0x2, 0x10,0x52,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b, +0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0xf, 0x7e,0xf, 0x39,0xc9, +0x69,0x30,0x0, 0x4, 0x7a,0x73,0x39,0xd9,0x7e,0x73,0x39,0xd9,0xa, 0x37,0x5e,0x34, +0x0, 0x4, 0x68,0x4, 0xd2,0xe, 0x80,0x2, 0xc2,0xe, 0x7e,0x34,0x0, 0x1f,0x79,0x30, +0x0, 0x4, 0xc2,0xc3,0x12,0x12,0x9e,0x12,0x69,0x5, 0x7e,0x1f,0x39,0xc9,0x69,0x31, +0x0, 0x2, 0x5e,0x34,0x0, 0x40,0x68,0x2e,0x6c,0xaa,0x7e,0x10,0x2, 0xac,0x1a,0x7e, +0x1f,0x39,0xc9,0x7f,0x71,0x2d,0xf0,0x69,0x17,0x0, 0x9c,0x59,0x10,0x39,0xcd,0xb, +0xa0,0xbe,0xa0,0x3, 0x78,0xe4,0x69,0x11,0x0, 0xa4,0x7a,0x17,0x39,0xd5,0x69,0x31, +0x0, 0xa2,0x7a,0x37,0x39,0xd3,0xa9,0xc1,0xc4,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda, +0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x7d,0x13, +0x7e,0x1f,0x39,0xf8,0x1b,0x1a,0x10,0xc2,0xc6,0xd2,0xee,0x22,0xff,0xff,0x54,0x2c, +0xca,0x79,0x7f,0x50,0x7c,0xeb,0x7e,0x34,0x0, 0x24,0x7e,0x8, 0x0, 0x2c,0x7e,0x24, +0x0, 0x2, 0x12,0x63,0x62,0xe5,0x2c,0xbe,0xb0,0x0, 0x38,0x2, 0x21,0x4a,0xe5,0x2c, +0xbe,0xb0,0x76,0x28,0x2, 0x21,0x4a,0x7e,0xe1,0x2c,0xbe,0xe0,0x76,0x38,0x2, 0x21, +0x78,0x7e,0x34,0x1e,0x45,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1e,0x29,0x79,0x35,0x0, +0x4, 0xbe,0xe0,0x81,0x68,0x2, 0x21,0x71,0x74,0x23,0x7a,0x5b,0xb0,0x74,0x1c,0x61, +0x84,0x74,0x1, 0x7a,0x5b,0xb0,0x61,0x84,0x7c,0xbe,0x14,0xbe,0xb0,0x75,0x40,0x2, +0x61,0x33,0x7e,0xa0,0x3, 0xa4,0x2e,0x54,0x1, 0x8c,0x89,0x54,0x2, 0x2, 0xfb,0x2, +0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x2, 0xed,0x2, 0x2, +0xfb,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x2, 0xfb, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x25,0x2, 0x3, 0x33,0x2, 0x3, 0x9, 0x2, +0x2, 0xfb,0x2, 0x3, 0x17,0x2, 0x3, 0x17,0x2, 0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x2, 0xfb,0x41,0xfb,0x7e,0x34,0x1e, +0x45,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1d,0xe2,0x61,0x3f,0x7e,0x34,0x1e,0x19,0x79, +0x35,0x0, 0x2, 0x7e,0x34,0x1e,0x29,0x61,0x3f,0x7e,0x34,0x1e,0x19,0x79,0x35,0x0, +0x2, 0x7e,0x34,0x1d,0xb2,0x61,0x3f,0x7e,0x34,0x1d,0x96,0x79,0x35,0x0, 0x2, 0x7e, +0x34,0x1d,0xc6,0x61,0x3f,0x7e,0x34,0x1e,0xa, 0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1d, +0xf1,0x61,0x3f,0x7e,0x34,0x1e,0x45,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1e,0x29,0x79, +0x35,0x0, 0x4, 0xbe,0xe0,0x16,0x28,0x2, 0x61,0x4e,0x7c,0xfe,0x61,0x62,0x7e,0xf0, +0x16,0xbe,0xe0,0x72,0x50,0x2, 0x61,0x62,0xa, 0x3e,0x9e,0x34,0x0, 0x72,0xb, 0x34, +0x2c,0xf7,0x7e,0x70,0x3, 0xac,0x7f,0x7d,0x23,0x2e,0x24,0x1e,0x69,0x7a,0x51,0x82, +0x7a,0x41,0x83,0xe4,0x93,0x7a,0x5b,0xb0,0x2e,0x34,0x1e,0x6a,0x7a,0x71,0x82,0x7a, +0x61,0x83,0xe4,0x93,0x39,0xb5,0x0, 0x1, 0xda,0x79,0x22,0xca,0x3b,0x7f,0x30,0x74, +0x1, 0x12,0x13,0xde,0x29,0x73,0x0, 0xf3,0x2e,0x70,0xff,0x92,0x1, 0x29,0xb3,0x0, +0xf4,0x12,0x13,0xaf,0x7f,0x3, 0x12,0xd, 0x72,0x7f,0x3, 0x12,0x6, 0xba,0x29,0x73, +0x0, 0xa, 0xa, 0x37,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x24,0x29,0x73,0x0, 0xa3, +0xa, 0x27,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24, +0x69,0x33,0x0, 0xff,0x4d,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2, 0x29,0x73, +0x0, 0xa, 0xa, 0x47,0x29,0x73,0x0, 0x5, 0xa, 0x57,0x9d,0x54,0xf5,0x34,0x29,0xb3, +0x0, 0xa5,0x70,0xb, 0x29,0xb3,0x0, 0xf8,0x29,0x73,0x0, 0xf7,0x12,0xb, 0xad,0x29, +0x73,0x0, 0xa5,0x2e,0x70,0xff,0x92,0x1, 0xe5,0x34,0x12,0xb, 0x1e,0x69,0x33,0x0, +0xfd,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x28,0x69,0x23,0x0, 0xfb,0x3e,0x24,0x3e, +0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x29,0x73,0x0, 0xfa,0xa, 0x37,0x2d, +0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2a,0x29,0x73,0x0, 0xf9,0xa, 0x37,0x7e, +0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2c,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x39,0xc9,0x79, +0x30,0x0, 0x34,0x7e,0x34,0x1, 0xb, 0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2e,0x29, +0x73,0x0, 0x5, 0xa, 0x37,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x10,0x69,0x33,0x0, +0xa8,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x1c,0x69,0x33,0x0, 0xaa,0x7e,0xf, 0x39, +0xc9,0x79,0x30,0x0, 0x1e,0x6c,0xaa,0x7e,0x50,0x2, 0xac,0x5a,0x69,0x13,0x1, 0x1, +0x2d,0x12,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x30,0x7e,0xf, 0x39,0xc9,0x2d,0x12,0x79, +0x30,0x0, 0x44,0xb, 0xa0,0xbe,0xa0,0xc, 0x40,0xdd,0xda,0x3b,0x22,0xca,0xf8,0x7f, +0x70,0x7e,0x7b,0xf0,0x29,0x77,0x0, 0x1, 0xbc,0x7f,0x28,0x2, 0x7c,0xf7,0x69,0x17, +0x0, 0x6, 0x6d,0x0, 0x7e,0x34,0x0, 0xf2,0x74,0xff,0x12,0x20,0xe8,0x7f,0x7, 0x12, +0xe, 0xed,0xa9,0xd6,0xcb,0x6c,0xaa,0x80,0x2d,0x6c,0x77,0x80,0x1f,0x7e,0x10,0xb, +0xac,0x1a,0xa, 0x17,0x2d,0x1, 0x3e,0x4, 0x69,0x17,0x0, 0x6, 0x2d,0x10,0x6d,0x0, +0xb, 0xa, 0x20,0x6e,0x24,0xff,0xff,0x1b,0xa, 0x20,0xb, 0x70,0x29,0x67,0x0, 0x1, +0xbc,0x67,0x38,0xd9,0xb, 0xa0,0x7e,0x7b,0x60,0xbc,0x6a,0x38,0xcc,0x69,0x37,0x0, +0x6, 0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0x4, 0x7c,0x4f,0x6c,0x55,0xa, 0x3f,0x2d, +0x32,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0xc, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b, +0x1a,0x10,0x7e,0x34,0x0, 0xd0,0x12,0xf, 0x45,0x6c,0xaa,0xbe,0xa0,0x4, 0x50,0x18, +0x7e,0x70,0x4, 0xac,0x7a,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69,0x41,0x0, 0x26,0x60, +0x42,0x1e,0x44,0x14,0x78,0xfb,0x80,0x3b,0xbe,0xa0,0x8, 0x50,0x1b,0xa, 0x3a,0x1b, +0x36,0x3e,0x34,0x3e,0x34,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69,0x41,0x0, 0x28,0x60, +0x22,0x1e,0x44,0x14,0x78,0xfb,0x80,0x1b,0xa, 0x3a,0x9e,0x34,0x0, 0x8, 0x3e,0x34, +0x3e,0x34,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69,0x41,0x0, 0x2a,0x60,0x5, 0x1e,0x44, +0x14,0x78,0xfb,0x5e,0x44,0x0, 0xf, 0x7e,0x50,0x2, 0xac,0x5a,0x69,0x37,0x0, 0x6, +0x2d,0x32,0x6d,0x22,0x1b,0x1a,0x40,0xb, 0xa0,0xbe,0xa0,0xb, 0x40,0x8d,0xa9,0xc6, +0xcb,0xda,0xf8,0x22,0x29,0x70,0x0, 0x96,0x29,0x90,0x0, 0x98,0x29,0x60,0x0, 0x97, +0x29,0x80,0x0, 0x8d,0xbe,0x80,0x4, 0x38,0x4, 0x6c,0xaa,0x80,0x21,0xbe,0x80,0x8, +0x38,0x5, 0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x80,0x10,0x38,0x5, 0x7e,0xa0,0x2, 0x80, +0xd, 0xbe,0x80,0x20,0x38,0x5, 0x7e,0xa0,0x3, 0x80,0x3, 0x7e,0xa0,0x4, 0xbe,0x90, +0x3, 0x28,0x3, 0x7e,0x90,0x3, 0xbe,0x80,0x3f,0x28,0x3, 0x7e,0x80,0x3f,0xbe,0x60, +0x1, 0x28,0x3, 0x7e,0x60,0x1, 0xbe,0x70,0x2, 0x28,0x2, 0x6c,0x77,0xa, 0x28,0x3e, +0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x7c,0x89,0x6c,0x99,0x3e,0x44,0x3e, +0x44,0x3e,0x44,0x2d,0x42,0xa, 0x26,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d, +0x24,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x2d,0x32,0x7e,0x7f,0x39,0xf8,0x79,0x37,0x0, +0x2, 0x29,0xb0,0x0, 0x8c,0x7c,0x4b,0x6c,0x55,0x29,0xb0,0x0, 0x8b,0xa, 0x3b,0x2d, +0x32,0x7e,0x7f,0x39,0xc1,0x79,0x37,0x0, 0x80,0x69,0x30,0x0, 0xa0,0x7e,0x7f,0x39, +0xf8,0x79,0x37,0x0, 0xc, 0x69,0x30,0x0, 0x9e,0x5e,0x34,0xe0,0xf, 0x29,0xb0,0x0, +0x8c,0xa, 0x2b,0x1b,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d,0x32,0x7e, +0x7f,0x39,0xc1,0x79,0x37,0x0, 0x82,0xa, 0x2a,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e, +0x24,0x29,0xb0,0x0, 0x99,0xa, 0x3b,0x2d,0x32,0x7e,0x7f,0x39,0xf8,0x79,0x37,0x0, +0x6, 0x69,0x30,0x0, 0x9c,0x7e,0x7f,0x39,0xf8,0x79,0x37,0x0, 0x8, 0x69,0x30,0x0, +0x9a,0x7e,0xf, 0x39,0xf8,0x79,0x30,0x0, 0xa, 0x22,0x7f,0x60,0x74,0x1, 0x12,0x13, +0xde,0x29,0x36,0x0, 0xf5,0x29,0x26,0x0, 0xa3,0x29,0x16,0x0, 0xa4,0xbe,0x20,0x2, +0x28,0x3, 0x7e,0x20,0x2, 0xbe,0x10,0x40,0x28,0x3, 0x7e,0x10,0x40,0x7e,0x34,0x0, +0x4, 0x7c,0xb2,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7c,0x7, 0xa, 0x31,0x7e,0x2f, +0x39,0xc9,0x79,0x32,0x0, 0x12,0x7c,0x73,0xac,0x70,0xa, 0x21,0x12,0x1e,0xb9,0x7c, +0x27,0xa, 0x32,0x7e,0x2f,0x39,0xc9,0x79,0x32,0x0, 0x14,0x7c,0x73,0xac,0x70,0x29, +0x26,0x0, 0xf6,0xa, 0x22,0xad,0x32,0xa, 0x21,0x8d,0x32,0x7d,0x43,0x7c,0x73,0xac, +0x70,0xa, 0x21,0x12,0x1e,0xb9,0x7c,0xa7,0x7c,0x2a,0x7c,0xb9,0x2c,0xab,0xbe,0xa0, +0xc, 0x50,0x3, 0x7e,0xa0,0xc, 0xbe,0x20,0xc, 0x50,0x3, 0x7e,0x20,0xc, 0xa, 0x20, +0xa, 0x31,0x12,0x1e,0xb9,0x7d,0xe3,0xa, 0x3a,0xb, 0x34,0xad,0x3e,0xb, 0x34,0xbe, +0x34,0x2, 0x0, 0x40,0x4, 0x7e,0x34,0x1, 0xff,0x29,0x46,0x0, 0xf7,0x7e,0x50,0x2, +0xac,0x45,0xa, 0xf2,0xad,0xfe,0x2d,0x2f,0xb, 0x24,0xbe,0x24,0x2, 0x0, 0x40,0x4, +0x7e,0x24,0x1, 0xff,0xa, 0x13,0x7e,0x7f,0x39,0xc9,0x79,0x17,0x0, 0xa, 0x1e,0x24, +0x7c,0x45,0x6c,0x55,0x1e,0x34,0x2d,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0xc, +0xa, 0x3a,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x22,0x22,0xa9,0xd6,0xcb,0x69,0x30, +0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x6, 0x7e,0x2f, +0x33,0xfc,0x79,0x32,0x0, 0x6, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x32, +0x0, 0x8, 0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d, +0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x29,0x70,0x0, 0x2, 0xa, 0x37,0x7e, +0xf, 0x33,0xfc,0x79,0x30,0x0, 0xe, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10, +0x7e,0x34,0x0, 0xe0,0x12,0xf, 0x45,0xa9,0xc6,0xcb,0x22,0xb2,0x86,0x22,0xff,0xff, +0x7f,0x21,0xa9,0xd6,0xcb,0x69,0x30,0x0, 0x4, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, +0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x6, 0x69,0x30,0x0, +0x6, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x8, 0x29,0x70,0x0, 0x1, 0x7c,0x47,0x6c, +0x55,0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xc, +0x29,0x70,0x0, 0x2, 0xa, 0x37,0x1b,0x34,0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xa, +0x69,0x30,0x0, 0xa, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xe, 0x69,0x30,0x0, 0xc, +0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x10,0x69,0x30,0x0, 0xe, 0x7e,0x7f,0x33,0xfc, +0x79,0x37,0x0, 0x12,0x29,0x70,0x0, 0x3, 0x7c,0x27,0x6c,0x33,0x7e,0x1f,0x33,0xfc, +0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xa0,0x12,0xf, 0x45,0x7e,0x1f,0x33,0xfc,0x69,0x11, +0x0, 0x1a,0x7a,0x2b,0x30,0x69,0x11,0x0, 0x1c,0x39,0x32,0x0, 0x1, 0x69,0x11,0x0, +0x16,0x79,0x12,0x0, 0x2, 0x69,0x11,0x0, 0x18,0x79,0x12,0x0, 0x4, 0x69,0x11,0x0, +0x22,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x24,0x79,0x12,0x0, 0x8, 0x69,0x11,0x0, +0x1e,0x79,0x12,0x0, 0xa, 0x69,0x31,0x0, 0x20,0x79,0x32,0x0, 0xc, 0xa9,0xc6,0xcb, +0x22,0xca,0x3b,0x7c,0x57,0x7c,0x4b,0x5e,0x40,0x3, 0x69,0x30,0x0, 0x4, 0x5e,0x60, +0x3f,0x6c,0xaa,0xa, 0x4a,0x69,0xf0,0x0, 0xa, 0x69,0xe0,0x0, 0x8, 0x2d,0xf4,0x7e, +0x7b,0xb0,0xa, 0xfb,0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4,0xa, 0xea,0x69,0xd0, +0x0, 0xe, 0x69,0xc0,0x0, 0xc, 0x2d,0xde,0x7e,0x6b,0xb0,0xa, 0x4b,0x2d,0x4f,0x7e, +0xd0,0x28,0xac,0xd5,0x7e,0xf0,0x2, 0xac,0xfa,0x7d,0xd7,0x2d,0xd6,0x7e,0xf0,0xf0, +0xac,0xf4,0x2d,0xd7,0x7e,0x7f,0x39,0xf4,0x2d,0xfd,0x79,0x47,0x1, 0x8c,0xb, 0xa0, +0xbe,0xa0,0xe, 0x78,0xae,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x69,0xf0,0x0, 0x2, +0xb, 0xa, 0xe0,0x2d,0xf4,0xb, 0x7a,0x40,0x7e,0xd0,0x28,0xac,0xd5,0x7e,0xf0,0x2, +0xac,0xfa,0x7d,0xd7,0x2d,0xd6,0x7e,0xf0,0xf0,0xac,0xf4,0x2d,0xd7,0x7e,0x7f,0x39, +0xf4,0x2d,0xfd,0x79,0x47,0x1, 0x80,0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xc9,0x7e,0x90, +0xf0,0xac,0x94,0x74,0x28,0xac,0xb5,0x7d,0xf5,0x2d,0xf4,0x7e,0x2f,0x39,0xf4,0x2d, +0x5f,0x79,0x32,0x1, 0x88,0x69,0x30,0x0, 0x6, 0x7e,0x30,0xf0,0xac,0x34,0x74,0x28, +0xac,0x5b,0x2d,0x21,0x7e,0xf, 0x39,0xf4,0x2d,0x12,0x79,0x30,0x1, 0x8a,0xda,0x3b, +0x22,0x29,0x60,0x0, 0xb, 0xa, 0x46,0x29,0x60,0x0, 0x4, 0xa, 0x26,0x2d,0x24,0x7c, +0x65,0x29,0xb0,0x0, 0x6, 0xbc,0xb6,0x28,0x2, 0x7c,0x6b,0x29,0x70,0x0, 0x5, 0x29, +0xb0,0x0, 0x7, 0xbc,0xb7,0x28,0x2, 0x7c,0x7b,0x6c,0xaa,0x6d,0x22,0x7e,0x90,0x2, +0xac,0x9a,0x7e,0x7f,0x39,0xc1,0x2d,0xf4,0x79,0x27,0x0, 0x2, 0xb, 0xa0,0xbe,0xa0, +0x23,0x78,0xea,0x6c,0xaa,0x80,0x55,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0x57,0x0, +0x4c,0xbe,0x50,0x23,0x50,0x23,0x29,0x47,0x0, 0xb4,0xa, 0xd4,0x7d,0x4d,0x7c,0x89, +0x6c,0x99,0x7d,0xd4,0x7e,0x90,0x2, 0xac,0x95,0x7e,0x7f,0x39,0xc1,0x2d,0xf4,0xb, +0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40,0xa, 0x4a,0x7f,0x70,0x2d,0xf4,0x29, +0x47,0x0, 0x4c,0xa, 0xd4,0x7e,0x90,0x2, 0xac,0x9a,0x7e,0x7f,0x39,0xc1,0x2d,0xf4, +0xb, 0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40,0xb, 0xa0,0xbc,0x6a,0x38,0xa7, +0x6c,0xaa,0x80,0x1d,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0x67,0x0, 0x6f,0xa, 0x46, +0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x39,0xc1,0x2d,0xf2,0x79,0x47,0x0, 0x48,0xb, +0xa0,0xbc,0x7a,0x38,0xdf,0x22,0x7c,0x7b,0x7e,0x7f,0x39,0xc9,0x69,0x47,0x0, 0xc, +0x6c,0x88,0x3e,0x44,0x69,0x7, 0x0, 0xa, 0x69,0x57,0x0, 0x2, 0x1e,0x54,0x1e,0x54, +0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x5e,0x54,0x0, 0x3, 0x7e,0x14, +0x0, 0x4, 0x70,0x2, 0x41,0x9b,0x3e,0x14,0x14,0x78,0xfb,0x7c,0xa3,0xa, 0xda,0xad, +0xd0,0x7d,0xcd,0x6d,0x11,0x79,0x17,0x0, 0x8c,0x7c,0xb7,0x70,0x2, 0x41,0xb4,0x1e, +0xd4,0x14,0x78,0xfb,0xbe,0xd4,0x1, 0x0, 0x38,0x2, 0x41,0xc2,0x7e,0xd4,0x1, 0x0, +0x41,0xce,0xbe,0xd4,0x0, 0x10,0x40,0x2, 0x41,0xce,0x7e,0xd4,0x0, 0x10,0x7d,0x3d, +0x12,0x12,0x6a,0xa, 0x1b,0x7e,0x1f,0x39,0xc9,0x79,0x11,0x0, 0x90,0x7e,0x1f,0x39, +0xc9,0x79,0xd1,0x0, 0x8e,0x7e,0x7f,0x39,0xc9,0x69,0x37,0x0, 0x8, 0xad,0x3c,0x8d, +0x3d,0x79,0x37,0x0, 0x92,0x7e,0x14,0x0, 0x6, 0x7e,0x1f,0x39,0xc9,0x79,0x11,0x0, +0x94,0x7d,0x24,0x9d,0x20,0xa, 0x3a,0xad,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, +0x96,0x7e,0x34,0x0, 0x10,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x98,0x22,0x7c,0x5b, +0x7e,0xf, 0x39,0xc9,0x69,0x40,0x0, 0x22,0x30,0x1, 0x6b,0x6d,0xff,0x7d,0x3f,0xbe, +0x50,0x10,0x28,0x2e,0x7e,0x54,0xff,0xff,0x79,0x50,0x0, 0x42,0x9e,0x50,0x10,0x6c, +0xaa,0x80,0x11,0x7e,0xe4,0x0, 0x1, 0x7c,0xba,0x60,0x5, 0x3e,0xe4,0x14,0x78,0xfb, +0x2d,0x3e,0xb, 0xa0,0xbc,0x5a,0x38,0xeb,0x7e,0x6f,0x39,0xc9,0x79,0x36,0x0, 0x40, +0x80,0x25,0x79,0xf0,0x0, 0x40,0x6c,0xaa,0x80,0x11,0x7e,0xf4,0x0, 0x1, 0x7c,0xba, +0x60,0x5, 0x3e,0xf4,0x14,0x78,0xfb,0x2d,0x3f,0xb, 0xa0,0xbc,0x5a,0x38,0xeb,0x7e, +0x7f,0x39,0xc9,0x79,0x37,0x0, 0x42,0x7d,0x34,0x2e,0x34,0x0, 0xc, 0x7e,0x7f,0x39, +0xc9,0x79,0x37,0x0, 0x16,0x22,0x6d,0x33,0x79,0x30,0x0, 0x40,0x7e,0xf, 0x39,0xc9, +0x79,0x30,0x0, 0x42,0x7e,0x1f,0x39,0xc9,0x79,0x41,0x0, 0x16,0x22,0x7c,0x17,0x7c, +0x3b,0x6d,0x33,0x7e,0x2f,0x39,0xc9,0x79,0x32,0x0, 0x40,0x7e,0x2f,0x39,0xc9,0x79, +0x32,0x0, 0x42,0x7e,0x7f,0x39,0xc9,0x69,0x57,0x0, 0x12,0x7c,0xab,0x69,0x37,0x0, +0x2, 0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x5e, +0x34,0x0, 0x3, 0x7c,0xb7,0x7e,0x44,0x0, 0x4, 0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb, +0x7c,0x29,0xa, 0x22,0xa, 0x3a,0x12,0x1e,0xb9,0xa, 0x23,0x2d,0x32,0x7c,0xb7,0x7c, +0x61,0x6c,0x77,0xa, 0xb, 0x1e,0x4, 0x2d,0x3, 0x79,0x7, 0x0, 0xc, 0x7c,0x73,0xac, +0x72,0xa, 0x2a,0x12,0x1e,0xb9,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x16,0x6d,0x33, +0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x22,0x22,0xa9,0xd6,0xcb,0x69,0x30,0x0, 0x6, +0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33,0xfc, +0x79,0x32,0x0, 0x8, 0x29,0x70,0x0, 0x2, 0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x3, +0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x7e,0xb, 0x70,0x7c, +0x47,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, +0xa, 0x29,0x70,0x0, 0x4, 0xa, 0x37,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xe, 0x29, +0xb0,0x0, 0x5, 0x54,0x1, 0x7c,0x2b,0x6c,0x33,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10, +0x7e,0x34,0x0, 0xc0,0x12,0xf, 0x45,0xa9,0xc6,0xcb,0x22,0xca,0x79,0x7c,0xab,0x5e, +0xa0,0x3, 0x6c,0x77,0x7e,0x50,0x2, 0xac,0x57,0x69,0xd0,0x0, 0xe, 0x69,0xc0,0x0, +0xc, 0x2d,0xd2,0x29,0x66,0x0, 0x1, 0xa, 0xf6,0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d, +0xf4,0x7e,0x6b,0x60,0xa, 0x46,0x2d,0x4f,0x7e,0xf0,0xf0,0xac,0xfa,0x2d,0x27,0x7e, +0x7f,0x39,0xf4,0x2d,0xf2,0x79,0x47,0x2, 0x54,0xb, 0x70,0xbe,0x70,0xe, 0x40,0xc4, +0x69,0x40,0x0, 0x4, 0x7e,0xf0,0xf0,0xac,0xfa,0x7e,0x1f,0x39,0xf4,0x2d,0x37,0x79, +0x41,0x2, 0x50,0x69,0x30,0x0, 0x6, 0x74,0xf0,0xa4,0x7e,0xf, 0x39,0xf4,0x2d,0x15, +0x79,0x30,0x2, 0x52,0xda,0x79,0x22,0xa9,0xd6,0xcb,0xc2,0x1e,0x69,0x30,0x0, 0x4, +0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x6, 0x7e,0x2f,0x33,0xfc, +0x79,0x32,0x0, 0x6, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x8, +0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e, +0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x29,0x70,0x0, 0x2, 0xa, 0x37,0x7e,0x2f,0x33, +0xfc,0x79,0x32,0x0, 0xe, 0x29,0xb0,0x0, 0x3, 0x54,0x1, 0xa, 0x5b,0x7c,0xab,0xe4, +0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x50,0x69,0x30,0x0, 0xa, 0x12,0xf, 0x45,0xa9,0xc6, +0xcb,0x22,0x69,0x30,0x0, 0xae,0x7e,0x2f,0x39,0xc9,0x79,0x32,0x0, 0x6, 0x29,0x50, +0x0, 0xa6,0xa, 0x55,0x7d,0x23,0x1e,0x24,0x9d,0x25,0x7e,0x2f,0x39,0xc9,0x79,0x22, +0x0, 0x18,0x7d,0x23,0x1e,0x24,0x1b,0x25,0x7e,0x2f,0x39,0xc9,0x79,0x22,0x0, 0x38, +0x69,0x20,0x0, 0xfd,0x1e,0x34,0x9d,0x32,0x9e,0x34,0x0, 0xa, 0x7e,0x2f,0x39,0xc9, +0x79,0x32,0x0, 0x26,0x29,0x70,0x0, 0xa7,0xa, 0x37,0x7e,0x2f,0x39,0xc9,0x79,0x32, +0x0, 0x1a,0x29,0x70,0x0, 0xb, 0xa, 0x27,0x29,0x70,0x0, 0x4, 0x2d,0x32,0x7e,0x2f, +0x39,0xc9,0x79,0x32,0x0, 0x8, 0x2, 0x9, 0xa1,0xca,0x3b,0xf5,0x24,0x7f,0x41,0x7f, +0x30,0xe5,0x25,0x7e,0x8, 0x0, 0x26,0x12,0x1, 0x20,0xe5,0x24,0xbe,0xb0,0x23,0x28, +0x3, 0x75,0x24,0x23,0x6c,0xaa,0x80,0x36,0xa, 0x3a,0x2d,0x39,0x7d,0x28,0x7e,0x1b, +0xb0,0xbe,0xb1,0x26,0x40,0xd, 0x74,0x23,0xa, 0x4a,0x7f,0x3, 0x2d,0x14,0x7a,0xb, +0xb0,0x80,0x19,0x7e,0x1b,0xb0,0xa, 0x3b,0x2e,0x35,0x28,0x7a,0x71,0x82,0x7a,0x61, +0x83,0xe4,0x93,0xa, 0x4a,0x7f,0x13,0x2d,0x34,0x7a,0x1b,0xb0,0xb, 0xa0,0xe5,0x24, +0xbc,0xba,0x38,0xc4,0xda,0x3b,0x22,0xa9,0xd6,0xcb,0x69,0x20,0x0, 0x4, 0x7e,0x2f, +0x33,0xfc,0x79,0x22,0x0, 0x4, 0x69,0x20,0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x22, +0x0, 0x8, 0x7e,0xb, 0x50,0xa, 0x55,0x7c,0xab,0xe4,0x29,0x50,0x0, 0x1, 0xa, 0x25, +0x2d,0x25,0x7e,0x2f,0x33,0xfc,0x79,0x22,0x0, 0xc, 0x29,0x50,0x0, 0x2, 0xa, 0x25, +0x7e,0xf, 0x33,0xfc,0x79,0x20,0x0, 0xe, 0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0xa, +0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0x40,0x12,0xf, 0x45, +0xa9,0xc6,0xcb,0x22,0x7c,0xab,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x39,0xf8,0x79,0x30, +0x0, 0xe, 0xc2,0x1d,0xe4,0x7a,0xb3,0x39,0xf3,0x5e,0xa0,0x3, 0xa, 0x1a,0x3e,0x14, +0x7e,0x1f,0x39,0xc1,0x1b,0x1a,0x10,0x7e,0xf, 0x39,0xc1,0x2e,0x14,0x0, 0x84,0xb, +0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x74,0x1, 0x12,0x13,0x56,0x7e,0xf, 0x39, +0xf8,0xb, 0xa, 0x30,0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xa9,0xd3,0xcd,0x7e,0xf, 0x39, +0xf8,0xb, 0x15,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,0xa, 0x30,0x22,0x7f,0x10,0xa9, +0xd6,0xcb,0x69,0x11,0x0, 0x2, 0x7e,0x2f,0x33,0xfc,0x79,0x12,0x0, 0x4, 0x69,0x11, +0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x6, 0x7e,0x2f, +0x33,0xfc,0x79,0x12,0x0, 0x8, 0x7e,0x1b,0x30,0xa, 0x3, 0x7e,0x14,0x1, 0x0, 0xad, +0x10,0x29,0x71,0x0, 0x1, 0xa, 0x37,0x2d,0x31,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, +0xc, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0x60,0x12,0xf, +0x45,0xa9,0xc6,0xcb,0x22,0xa9,0xd7,0xcb,0x7d,0x23,0x4e,0x50,0x1, 0x7e,0xf, 0x33, +0xfc,0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, 0x30,0x80,0x1e,0x7e,0xf, 0x33,0xfc,0xb, +0xa, 0x30,0x7d,0x23,0x5e,0x24,0x0, 0x8, 0xbe,0x24,0x0, 0x8, 0x78,0xb, 0xa9,0xd7, +0xcb,0x4e,0x70,0x4, 0x1b,0xa, 0x30,0xd2,0x1e,0x7e,0xf, 0x33,0xfc,0xb, 0xa, 0x30, +0x7d,0x23,0x5e,0x24,0x80,0x0, 0xbe,0x24,0x80,0x0, 0x78,0xcf,0x4e,0x60,0x40,0x1b, +0xa, 0x30,0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x22,0xca,0x3b,0xf5,0x24, +0x7f,0x41,0x7f,0x30,0xe5,0x25,0x7e,0x8, 0x0, 0x26,0x12,0x1, 0x20,0x6c,0xaa,0x80, +0x36,0xa, 0x3a,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0xbe,0xb1,0x27,0x40,0xd, 0x74, +0x1c,0xa, 0x4a,0x7f,0x3, 0x2d,0x14,0x7a,0xb, 0xb0,0x80,0x19,0x7e,0x1b,0xb0,0xa, +0x3b,0x2e,0x35,0x2a,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0xa, 0x4a,0x7f,0x13, +0x2d,0x34,0x7a,0x1b,0xb0,0xb, 0xa0,0xe5,0x24,0xbc,0xba,0x38,0xc4,0xda,0x3b,0x22, +0x5, 0x63,0x31,0x20,0x18,0x13,0xf, 0xd, 0xc, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, +0xca,0xf8,0x7d,0xe2,0x7d,0xd3,0x7c,0xfb,0xbe,0x30,0x1, 0x28,0x6, 0x7e,0xf4,0x0, +0x10,0x80,0xf, 0xbe,0x30,0x0, 0x28,0x6, 0x7e,0xf4,0x0, 0x8, 0x80,0x4, 0x7e,0xf4, +0x0, 0x4, 0x7d,0x1f,0x6d,0x0, 0x6d,0x33,0x7e,0x24,0x0, 0x10,0x12,0x1f,0x58,0x7f, +0x1, 0x7d,0x3d,0x6d,0x22,0x12,0x1e,0xeb,0x7d,0x1e,0x12,0x1f,0x5, 0x74,0x4, 0xac, +0xbf,0x7e,0xf, 0x39,0xc9,0x2d,0x15,0x79,0x30,0x0, 0x82,0x79,0x20,0x0, 0x80,0xda, +0xf8,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca,0xb, +0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0x1d,0x7e,0xf, 0x39,0xf8,0xb, 0xa, 0x30,0x7c, +0x57,0x7a,0x53,0x39,0xf3,0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xc2,0xc6,0x6d,0x33,0x7e, +0xf, 0x39,0xf8,0x79,0x30,0x0, 0xe, 0x12,0x12,0x9e,0x12,0x69,0x5, 0xd0,0x82,0xd0, +0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda, +0x7b,0x32,0x74,0x3, 0x12,0x13,0x56,0xa9,0xd1,0xc4,0x7e,0xf, 0x39,0xc1,0x2e,0x14, +0x0, 0x84,0xb, 0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x7e,0x14,0x0, 0x1, 0x7e, +0x1f,0x39,0xc1,0x1b,0x1a,0x10,0x7e,0xf, 0x39,0xc9,0xb, 0x16,0xb, 0xa, 0x30,0x4e, +0x70,0x1, 0x1b,0xa, 0x30,0xc2,0xf, 0xe4,0x7a,0xb3,0x39,0xd9,0x7e,0x1f,0x39,0xc1, +0xb, 0x1a,0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0x74,0x2, 0x2, 0x13,0x56,0x7c,0x6b, +0x6c,0xaa,0x80,0x17,0x7e,0x90,0x2, 0xac,0x9a,0x7e,0x7f,0x39,0xf4,0x2d,0xf4,0xb, +0x7a,0x20,0x7f,0x70,0x2d,0xf4,0x1b,0x7a,0x20,0xb, 0xa0,0xbc,0x7a,0x38,0xe5,0x6c, +0xaa,0x80,0x20,0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x39,0xf4,0x2d,0xf2,0x69,0x27, +0x0, 0x38,0xa, 0xf7,0xa, 0x4a,0x2d,0x4f,0x3e,0x44,0x7f,0x70,0x2d,0xf4,0x1b,0x7a, +0x20,0xb, 0xa0,0xbc,0x6a,0x38,0xdc,0x22,0xca,0x79,0x7c,0xab,0x5e,0xa0,0x3, 0x6c, +0x77,0x7e,0x50,0x2, 0xac,0x57,0x7f,0x60,0x2d,0xd2,0x29,0x66,0x0, 0x1, 0xa, 0xf6, +0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4,0x7e,0x6b,0x60,0xa, 0x46,0x2d,0x4f,0x7e, +0xf0,0xf0,0xac,0xfa,0x2d,0x27,0x7e,0x7f,0x39,0xf4,0x2d,0xf2,0x79,0x47,0x2, 0x54, +0xb, 0x70,0xbe,0x70,0xe, 0x40,0xca,0xda,0x79,0x22,0x29,0x50,0x0, 0xf5,0xac,0x5b, +0x7e,0xf, 0x39,0xc9,0x69,0x30,0x0, 0xc, 0xa, 0x56,0x3e,0x54,0xbe,0x24,0x2, 0x0, +0x40,0x4, 0x7e,0x24,0x1, 0xff,0xbd,0x25,0x28,0x1f,0x2e,0x14,0x0, 0xc, 0x6c,0x66, +0x1b,0xa, 0x30,0x1e,0x24,0x7c,0x45,0x6c,0x55,0x7e,0xf, 0x39,0xc9,0x2e,0x14,0x0, +0xc, 0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, 0x30,0x22,0x7c,0x6b,0x6c,0xaa,0x7e,0x50, +0x28,0xac,0x57,0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x42,0x7e,0x50,0xf0,0xac,0x56,0x2d, +0x24,0x7e,0x7f,0x39,0xf4,0x2d,0xf2,0x69,0x27,0x1, 0x8c,0x6c,0x44,0xa, 0x4a,0x7f, +0x60,0x2d,0xd4,0x7e,0x6b,0xb0,0x7c,0x8b,0x6c,0x99,0x4d,0x24,0x79,0x27,0x1, 0x8c, +0xb, 0xa0,0xbe,0xa0,0xe, 0x40,0xc7,0x22,0x7c,0x6b,0x6c,0xaa,0x7e,0x50,0x28,0xac, +0x57,0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x42,0x7e,0x50,0xf0,0xac,0x56,0x2d,0x24,0x7e, +0x7f,0x39,0xf4,0x2d,0xf2,0x69,0x27,0x1, 0x8c,0x6c,0x55,0xa, 0x4a,0x7f,0x60,0x2d, +0xd4,0x7e,0x6b,0xb0,0xa, 0x4b,0x4d,0x24,0x79,0x27,0x1, 0x8c,0xb, 0xa0,0xbe,0xa0, +0xe, 0x40,0xc9,0x22,0xa9,0xd6,0xcb,0x54,0x3f,0x5e,0x70,0x1f,0x7c,0x2b,0x6c,0x33, +0x3e,0x14,0x3e,0x14,0x2e,0x14,0x0, 0x5, 0xa, 0x37,0x3e,0x34,0x3e,0x34,0x3e,0x34, +0x3e,0x34,0x3e,0x34,0x2d,0x31,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0x2, 0x7e,0xf, +0x33,0xfc,0x79,0x20,0x0, 0x14,0xa9,0xc6,0xcb,0x22,0x7d,0x23,0x6c,0x66,0x7e,0x30, +0x2, 0xac,0x36,0x2e,0x14,0x20,0x99,0x7a,0x31,0x82,0x7a,0x21,0x83,0xe4,0x93,0xa, +0x1b,0xbd,0x12,0x28,0x7, 0xb, 0x60,0xbe,0x60,0x14,0x40,0xe2,0x7e,0x70,0x2, 0xac, +0x67,0x2e,0x34,0x20,0x9a,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0x22,0x7e,0xf, +0x39,0xc1,0x2e,0x14,0x0, 0x84,0xb, 0xa, 0x30,0x5e,0x70,0xdf,0x1b,0xa, 0x30,0x74, +0x3, 0x12,0x13,0x56,0x7e,0x14,0x0, 0x3, 0x7e,0x1f,0x39,0xc1,0x1b,0x1a,0x10,0x7e, +0x1f,0x39,0xc1,0xb, 0x1a,0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0xe4,0x2, 0x13,0x56, +0x2e,0x34,0x4, 0x0, 0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x60,0x7e,0x34,0x4, 0x0, +0x9d,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x62,0x7e,0x34,0x0, 0x1, 0x7e,0xf, +0x39,0xc9,0x79,0x30,0x0, 0x64,0xa, 0x3b,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x66, +0x22,0x7c,0xa5,0xbe,0x34,0x0, 0x0, 0x28,0x10,0xa, 0x1b,0x3e,0x14,0x7d,0x23,0x7c, +0x45,0x6c,0x55,0x2d,0x21,0xa, 0x3a,0x80,0x8, 0xa, 0x2b,0x3e,0x24,0x7c,0x67,0x6c, +0x77,0x2d,0x32,0x7e,0xf, 0x39,0xf8,0x79,0x30,0x0, 0x4, 0x22,0x7c,0xa7,0x7e,0x1f, +0x39,0xc1,0x69,0x41,0x0, 0x8a,0x5e,0x44,0x10,0xf, 0xa, 0x1a,0x3e,0x14,0x3e,0x14, +0x3e,0x14,0x3e,0x14,0xa, 0x5b,0xc4,0x23,0x54,0xe0,0x7c,0xab,0xe4,0x2d,0x51,0x4d, +0x45,0x79,0x41,0x0, 0x8a,0x22,0x7e,0xf, 0x39,0xc1,0x69,0x30,0x0, 0x84,0x5e,0x70, +0xe7,0x1b,0xb1,0x68,0xc, 0x14,0x68,0xc, 0xb, 0xb1,0x78,0x5, 0x4e,0x70,0x10,0x80, +0x3, 0x4e,0x70,0x8, 0x79,0x30,0x0, 0x84,0x22,0x7e,0x34,0x0, 0x1f,0x7e,0xf, 0x39, +0xc9,0x79,0x30,0x0, 0x4, 0xa9,0xd2,0xcd,0x7e,0xf, 0x39,0xc9,0xb, 0xa, 0x30,0x4e, +0x70,0x1, 0x1b,0xa, 0x30,0x22,0xbe,0xb0,0x0, 0x28,0xa, 0xa9,0xd7,0xca,0xa9,0xd3, +0xcb,0xa9,0xd2,0xcb,0x22,0xa9,0xc7,0xca,0xa9,0xc3,0xcb,0xa9,0xc2,0xcb,0x22,0x30, +0x1, 0xa, 0x54,0x3, 0xa, 0x3b,0x2e,0x34,0x2, 0x0, 0x80,0x2, 0x6d,0x33,0x7e,0xf, +0x39,0xc9,0x79,0x30,0x0, 0x3a,0x22,0x7e,0xf, 0x39,0xc1,0x69,0x30,0x0, 0x8a,0x60, +0x5, 0x4e,0x60,0x10,0x80,0x3, 0x5e,0x60,0xef,0x79,0x30,0x0, 0x8a,0x22,0xbe,0xb0, +0x0, 0x28,0x9, 0xa9,0xd6,0xca,0xd2,0xcd,0xa9,0xd1,0xcb,0x22,0xa9,0xc6,0xca,0xc2, +0xcd,0xa9,0xc1,0xcb,0x22,0x7e,0x34,0x0, 0xf, 0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, +0x4, 0xc2,0xc3,0xd2,0xeb,0x22,0x6, 0xe, 0x15,0x1a,0x1f,0x26,0x2b,0x2d,0x2e,0x2f, +0x2c,0x2a,0x24,0x1f,0x1a,0x14,0xf, 0x8, 0x3, 0x3, 0x6, 0xb, 0x10,0x15,0x1c,0x22, +0x28,0x2d,0x34,0x39,0x3d,0x40,0xe, 0x3, 0x0, 0x0, 0x0, 0x3, 0x8, 0xc, 0x11,0x16, +0x1c,0x23,0x2b,0x32,0x37,0x3c,0x40,0x45,0x4a,0x4d,0x4c,0x4b,0x4a,0x48,0x46,0x46, +0x45,0x45,0x44,0x44,0x43,0x44,0x45,0x78,0x65,0x55,0x2, 0xd, 0x14,0x1b,0x21,0x25, +0x2b,0x31,0x37,0x36,0x33,0x2d,0x28,0x20,0x19,0x14,0xd, 0x8, 0x1, 0x2, 0x5, 0xb, +0x10,0x18,0x1e,0x23,0x2a,0x30,0x35,0x3a,0x3e,0x3f,0x0, 0x1, 0x1, 0x0, 0x0, 0x0, +0x0, 0x0, 0x1, 0x4, 0x9, 0xf, 0x15,0x1d,0x24,0x2a,0x30,0x35,0x3b,0x3e,0x3f,0x40, +0x3f,0x3e,0x3d,0x3d,0x3c,0x3c,0x3b,0x3b,0x39,0x37,0x1a,0x2d,0x65,0x55,0x1b,0x29, +0x27,0x1e,0x14,0x11,0x1a,0x26,0x2e,0x37,0x3d,0x3f,0x3d,0x37,0x2e,0x21,0x16,0xc, +0x5, 0x1, 0x0, 0x0, 0x1, 0x3, 0xa, 0x13,0x1d,0x26,0x2e,0x33,0x38,0x3a,0x16,0x21, +0x2b,0x32,0x30,0x2a,0x27,0x2a,0x2f,0x2d,0x24,0x1a,0x10,0x7, 0x1, 0x0, 0x2, 0x7, +0x10,0x19,0x23,0x2d,0x36,0x41,0x49,0x4c,0x4a,0x45,0x3c,0x34,0x2a,0x27,0x51,0x71, +0x50,0x55,0x28,0x12,0x11,0x18,0x23,0x29,0x2b,0x2a,0x2e,0x35,0x3c,0x3e,0x3f,0x39, +0x31,0x28,0x1e,0x15,0xe, 0x6, 0x3, 0x1, 0x0, 0x0, 0x3, 0xc, 0x16,0x20,0x2b,0x32, +0x37,0x39,0x20,0x29,0x32,0x37,0x31,0x28,0x21,0x2a,0x31,0x2d,0x23,0x1b,0x13,0x8, +0x1, 0x0, 0x1, 0x5, 0xc, 0x18,0x20,0x29,0x34,0x3e,0x47,0x4f,0x50,0x4d,0x45,0x3c, +0x34,0x31,0x26,0xcb,0x50,0x55,0x1d,0x2f,0x2c,0x25,0x1a,0x1b,0x20,0x29,0x31,0x31, +0x2e,0x2d,0x35,0x3d,0x3f,0x3d,0x38,0x2c,0x22,0x15,0xd, 0x6, 0x1, 0x0, 0x1, 0x6, +0x10,0x1b,0x24,0x2f,0x38,0x3d,0xd, 0x1b,0x27,0x31,0x32,0x28,0x1e,0x14,0x15,0x1d, +0x28,0x31,0x34,0x2a,0x1f,0x14,0x9, 0x1, 0x0, 0x4, 0xd, 0x17,0x21,0x2c,0x35,0x40, +0x47,0x47,0x44,0x3c,0x34,0x30,0x1b,0x82,0x50,0x55,0x19,0x2e,0x2a,0x1f,0x18,0x1b, +0x22,0x2d,0x30,0x2e,0x2e,0x35,0x3d,0x3f,0x3d,0x3a,0x2f,0x24,0x18,0xf, 0x7, 0x1, +0x0, 0x0, 0x3, 0xb, 0x16,0x1e,0x29,0x32,0x3a,0x3d,0x11,0x1f,0x28,0x32,0x30,0x26, +0x1b,0x14,0x1c,0x25,0x2e,0x35,0x2e,0x23,0x19,0x11,0x4, 0x0, 0x1, 0x8, 0x10,0x1c, +0x25,0x30,0x38,0x40,0x42,0x3f,0x39,0x32,0x2c,0x27,0xc0,0xd1,0x50,0x55,0x18,0x2c, +0x29,0x1e,0x14,0x13,0x16,0x1e,0x29,0x30,0x2e,0x2c,0x2b,0x37,0x3d,0x3f,0x3e,0x39, +0x30,0x25,0x1b,0x10,0x8, 0x1, 0x0, 0x2, 0x9, 0x13,0x1f,0x2d,0x38,0x3c,0x11,0x1a, +0x23,0x2f,0x33,0x29,0x20,0x16,0xe, 0x13,0x1d,0x28,0x32,0x31,0x28,0x1e,0x16,0xb, +0x2, 0x0, 0x1, 0x8, 0x12,0x1e,0x29,0x33,0x3b,0x3f,0x3c,0x32,0x29,0x26,0x30,0x6e, +0x50,0x55,0x16,0x2b,0x24,0x17,0xd, 0xa, 0xe, 0x15,0x24,0x28,0x25,0x23,0x2b,0x36, +0x3b,0x3d,0x3b,0x37,0x2b,0x20,0x15,0xb, 0x4, 0x0, 0x0, 0x3, 0xe, 0x19,0x27,0x33, +0x3d,0x3f,0x13,0x21,0x2e,0x37,0x3a,0x31,0x27,0x1c,0x13,0x1c,0x28,0x34,0x3e,0x37, +0x2d,0x22,0x18,0xc, 0x1, 0x0, 0x3, 0xd, 0x18,0x25,0x31,0x3c,0x47,0x48,0x42,0x38, +0x2e,0x2a,0x31,0x62,0x50,0x55,0x35,0x2e,0x27,0x22,0x1f,0x1b,0x16,0x10,0xc, 0x8, +0x6, 0x4, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x6, 0xb, 0xe, 0x12,0x17,0x1d,0x22,0x26, +0x2a,0x30,0x35,0x39,0x3d,0x3f,0x0, 0x0, 0x1, 0x4, 0x6, 0x8, 0xb, 0x10,0x16,0x1b, +0x1f,0x23,0x28,0x2d,0x32,0x36,0x3b,0x40,0x44,0x48,0x4a,0x4b,0x4c,0x4b,0x4a,0x48, +0x46,0x43,0x40,0x3e,0x3c,0x3a,0x3c,0x9c,0x34,0x55,0x9, 0x17,0x1d,0x26,0x2e,0x37, +0x3c,0x3f,0x3b,0x33,0x2b,0x22,0x1a,0x11,0xb, 0x5, 0x3, 0x1, 0x1, 0x0, 0x0, 0x0, +0x1, 0x6, 0xa, 0x11,0x19,0x22,0x2a,0x32,0x39,0x3d,0x30,0x30,0x2f,0x2c,0x26,0x1e, +0x17,0xd, 0x5, 0x0, 0x0, 0x1, 0x6, 0xe, 0x15,0x1e,0x26,0x2c,0x32,0x3a,0x41,0x48, +0x50,0x5b,0x61,0x64,0x64,0x60,0x5b,0x56,0x51,0x4f,0xd8,0x2c,0x33,0x55,0x26,0x1c, +0x19,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x17,0x17,0x15,0xf, 0x9, 0x4, 0x1, 0x0, +0x0, 0x0, 0x0, 0x1, 0x4, 0xb, 0x12,0x18,0x1f,0x28,0x31,0x37,0x3c,0x40,0x1, 0x7, +0xe, 0x14,0x1c,0x23,0x2c,0x34,0x3e,0x44,0x4c,0x54,0x5b,0x60,0x5d,0x55,0x4f,0x49, +0x43,0x3d,0x38,0x32,0x2b,0x26,0x22,0x1f,0x1e,0x1c,0x1c,0x1c,0x1c,0x1d,0x66,0x54, +0x74,0x55,0x3e,0x2c,0x21,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d, +0x1e,0x1e,0x1d,0x1a,0x11,0xc, 0x7, 0x2, 0x0, 0x0, 0x3, 0xa, 0x12,0x1c,0x23,0x2c, +0x38,0x40,0xc, 0x0, 0x6, 0xf, 0x17,0x22,0x29,0x32,0x3b,0x41,0x47,0x4f,0x55,0x5c, +0x66,0x71,0x79,0x3e,0x76,0x6d,0x64,0x5a,0x52,0x4b,0x42,0x39,0x35,0x33,0x32,0x32, +0x31,0x31,0xf3,0xdb,0x74,0x55,0x9, 0x7, 0x6, 0x6, 0x5, 0x5, 0x4, 0x4, 0x4, 0x4, +0x3, 0x2, 0x2, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa, 0x10,0x14,0x1b,0x22, +0x28,0x2e,0x34,0x39,0x3d,0x40,0x0, 0xb, 0x11,0x16,0x1b,0x22,0x28,0x2c,0x33,0x39, +0x40,0x46,0x4d,0x52,0x56,0x5c,0x61,0x68,0x6d,0x73,0x73,0x71,0x71,0x71,0x70,0x70, +0x6f,0x6f,0x6f,0x6f,0x6d,0x6e,0x79,0x80,0x44,0x55,0x17,0x13,0x12,0x12,0x11,0x10, +0xf, 0xd, 0xc, 0xb, 0x9, 0x8, 0x7, 0x4, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x1, 0x4, +0xb, 0x10,0x16,0x1d,0x24,0x29,0x31,0x39,0x3d,0x40,0x0, 0xe, 0x16,0x1a,0x1f,0x24, +0x29,0x2e,0x33,0x38,0x3e,0x43,0x47,0x50,0x55,0x59,0x62,0x69,0x6e,0x75,0x7c,0xff, +0x7d,0x7c,0x79,0x73,0x6d,0x68,0x60,0x5a,0x57,0x56,0x5d,0x8, 0x44,0x55,0x0, 0x7, +0xb, 0xd, 0x10,0x12,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x19,0x1c,0x1e,0x20,0x22, +0x23,0x25,0x27,0x29,0x2b,0x30,0x32,0x33,0x35,0x38,0x39,0x3b,0x3d,0x3f,0x3e,0x29, +0x1f,0x18,0xf, 0x7, 0x6, 0xc, 0x12,0x1d,0x25,0x2d,0x36,0x3e,0x3b,0x35,0x2c,0x26, +0x20,0x19,0x11,0xa, 0x3, 0x3, 0x9, 0x10,0x18,0x24,0x2c,0x33,0x3a,0x3e,0x60,0x9b, +0x32,0x55,0x0, 0x5, 0x5, 0x5, 0x4, 0x3, 0x2, 0x3, 0x5, 0x7, 0xa, 0xe, 0x11,0x19, +0x1b,0x1c,0x1d,0x1c,0x1c,0x1d,0x1f,0x22,0x25,0x2a,0x31,0x33,0x35,0x37,0x38,0x39, +0x3c,0x40,0x0, 0x12,0x1c,0x24,0x2b,0x34,0x3c,0x39,0x2f,0x29,0x21,0x16,0xf, 0xd, +0x14,0x1e,0x2a,0x33,0x31,0x27,0x20,0x18,0x10,0x7, 0xa, 0x10,0x1a,0x26,0x2f,0x37, +0x3d,0x3f,0xfb,0x8f,0x32,0x55,0x2c,0x23,0x1f,0x19,0x13,0xc, 0x7, 0x3, 0x0, 0x0, +0x0, 0x1, 0x5, 0xa, 0xf, 0x16,0x1d,0x23,0x2a,0x30,0x36,0x3b,0x3e,0x40,0x3f,0x3e, +0x3b,0x38,0x33,0x2f,0x2b,0x28,0x9, 0x1, 0x0, 0x1, 0x3, 0x9, 0xe, 0x14,0x1b,0x21, +0x27,0x2e,0x36,0x3b,0x3e,0x41,0x41,0x40,0x3d,0x3a,0x36,0x2f,0x2b,0x26,0x20,0x1c, +0x16,0x10,0xc, 0xa, 0x9, 0xb, 0x36,0xdc,0x30,0x55,0x1a,0x9, 0x5, 0x1, 0x0, 0x0, +0x0, 0x2, 0x5, 0x9, 0xf, 0x16,0x1c,0x22,0x2a,0x31,0x36,0x39,0x3c,0x3e,0x3f,0x3f, +0x3d,0x38,0x30,0x27,0x1f,0x18,0x12,0xb, 0x6, 0x5, 0x7, 0x12,0x19,0x22,0x2c,0x36, +0x3f,0x49,0x53,0x5c,0x63,0x66,0x64,0x5f,0x58,0x4c,0x43,0x3d,0x34,0x2b,0x22,0x1b, +0x15,0xb, 0x4, 0x0, 0x0, 0x1, 0x4, 0xb, 0x13,0x18,0xf1,0xc, 0x30,0x55,0x18,0x2c, +0x34,0x39,0x3c,0x3d,0x3f,0x3f,0x3f,0x3d,0x3b,0x36,0x30,0x2a,0x24,0x1c,0x16,0xd, +0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x5, 0x9, 0xf, 0x17,0x1e,0x24,0x1, 0x2, +0x8, 0xe, 0x14,0x1a,0x21,0x28,0x30,0x37,0x40,0x49,0x50,0x55,0x59,0x5c,0x5c,0x58, +0x51,0x48,0x3f,0x38,0x31,0x2b,0x25,0x1d,0x17,0x11,0xa, 0x4, 0x1, 0x1, 0x9d,0xbf, +0x30,0x55,0x16,0x7, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x8, 0xe, 0x16,0x1f,0x28, +0x30,0x38,0x3c,0x3e,0x3f,0x40,0x3f,0x3f,0x3d,0x3b,0x37,0x32,0x2c,0x25,0x1d,0x16, +0xf, 0xc, 0x53,0x46,0x3e,0x35,0x2e,0x27,0x20,0x1a,0x14,0xd, 0x6, 0x1, 0x0, 0x0, +0x3, 0xa, 0x13,0x1a,0x20,0x27,0x2d,0x33,0x3a,0x40,0x48,0x4f,0x54,0x58,0x5a,0x5a, +0x58,0x57,0xc6,0x55,0x30,0x55,0x7, 0x1, 0x4, 0xa, 0x10,0x18,0x20,0x2a,0x32,0x38, +0x3c,0x3e,0x3f,0x3e,0x3d,0x3b,0x39,0x35,0x30,0x27,0x21,0x19,0x12,0xb, 0x6, 0x3, +0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32,0x1d,0x12,0x9, 0x5, 0x1, 0x0, 0x0, 0x1, 0x5, +0xd, 0x17,0x20,0x2a,0x32,0x3b,0x45,0x4e,0x58,0x63,0x69,0x6b,0x6a,0x64,0x5d,0x57, +0x4f,0x47,0x40,0x38,0x32,0x2f,0x1a,0xb5,0x30,0x55,0x21,0x13,0xc, 0x8, 0x5, 0x2, +0x1, 0x0, 0x0, 0x1, 0x3, 0x8, 0xf, 0x17,0x1e,0x24,0x2b,0x32,0x39,0x3d,0x3e,0x3f, +0x3f,0x3d,0x3a,0x36,0x30,0x29,0x21,0x1a,0x16,0x13,0x5, 0x9, 0xe, 0x14,0x1a,0x22, +0x29,0x30,0x38,0x3f,0x47,0x4d,0x51,0x51,0x4f,0x4d,0x49,0x42,0x39,0x31,0x2b,0x25, +0x1e,0x17,0x10,0x8, 0x3, 0x0, 0x0, 0x1, 0x3, 0x5, 0xaf,0x13,0x30,0x55,0x38,0x3f, +0x3d,0x3a,0x36,0x2e,0x26,0x1f,0x14,0xb, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x2, 0x5, +0x9, 0xe, 0x14,0x1c,0x23,0x2a,0x34,0x38,0x3a,0x3b,0x3d,0x3d,0x3d,0x3d,0x29,0x1a, +0x10,0x9, 0x4, 0x0, 0x0, 0x1, 0x4, 0xc, 0x14,0x1c,0x22,0x28,0x2f,0x37,0x3f,0x47, +0x4f,0x56,0x5a,0x5b,0x59,0x56,0x4e,0x47,0x40,0x37,0x30,0x28,0x22,0x1f,0x2a,0xa9, +0x30,0x55,0x3e,0x3b,0x38,0x33,0x2b,0x24,0x1d,0x16,0x10,0x7, 0x3, 0x1, 0x0, 0x0, +0x0, 0x1, 0x1, 0x3, 0x6, 0xc, 0x15,0x1c,0x23,0x29,0x2f,0x35,0x38,0x3b,0x3c,0x3e, +0x3f,0x3f,0x1f,0x10,0xa, 0x6, 0x0, 0x0, 0x0, 0x2, 0x4, 0xc, 0x12,0x18,0x1e,0x25, +0x2c,0x35,0x3c,0x42,0x4a,0x51,0x56,0x56,0x53,0x4e,0x49,0x40,0x3a,0x33,0x2c,0x25, +0x1f,0x1c,0xf9,0xa2,0x30,0x55,0x1f,0x2b,0x31,0x35,0x38,0x3b,0x3e,0x3f,0x3f,0x3d, +0x3a,0x34,0x2d,0x27,0x23,0x1d,0x17,0x10,0x9, 0x4, 0x1, 0x0, 0x0, 0x1, 0x3, 0x6, +0xa, 0xf, 0x15,0x1b,0x20,0x23,0x45,0x42,0x3e,0x38,0x34,0x2d,0x24,0x1c,0x15,0x11, +0xb, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x7, 0xd, 0x12,0x18,0x20,0x28,0x30,0x36, +0x3c,0x42,0x47,0x48,0x49,0x4a,0x65,0x9d,0x30,0x55,0x1c,0x2a,0x33,0x39,0x3c,0x3e, +0x3f,0x3f,0x3e,0x3d,0x3a,0x35,0x2e,0x28,0x23,0x1c,0x15,0xf, 0x9, 0x4, 0x1, 0x0, +0x0, 0x1, 0x1, 0x4, 0x8, 0xd, 0x13,0x19,0x1e,0x22,0x40,0x3e,0x3a,0x33,0x2f,0x29, +0x22,0x1b,0x15,0x10,0xa, 0x5, 0x1, 0x0, 0x0, 0x1, 0x2, 0x5, 0xa, 0x11,0x17,0x1c, +0x24,0x2a,0x30,0x35,0x3b,0x40,0x43,0x44,0x45,0x45,0xcb,0xc6,0x30,0x55,0x5, 0x3, +0x4, 0x7, 0xa, 0x10,0x17,0x21,0x28,0x2e,0x33,0x38,0x3c,0x3e,0x3f,0x3f,0x3e,0x3b, +0x38,0x31,0x29,0x21,0x18,0xf, 0x9, 0x4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26,0x35, +0x3d,0x45,0x4b,0x51,0x53,0x52,0x4f,0x4c,0x46,0x41,0x3b,0x34,0x2e,0x25,0x1e,0x17, +0x11,0x9, 0x3, 0x0, 0x0, 0x2, 0x6, 0xc, 0x12,0x18,0x1e,0x24,0x2c,0x31,0xf4,0xb6, +0x30,0x55,0xa, 0x5, 0x5, 0x5, 0x8, 0xf, 0x16,0x20,0x29,0x31,0x36,0x3a,0x3c,0x3e, +0x3f,0x3f,0x3e,0x3c,0x3a,0x33,0x2d,0x24,0x1c,0x14,0xf, 0x8, 0x4, 0x0, 0x0, 0x0, +0x1, 0x2, 0x35,0x46,0x4e,0x56,0x5d,0x65,0x68,0x66,0x60,0x57,0x4f,0x47,0x3f,0x37, +0x2e,0x25,0x1e,0x16,0x10,0x6, 0x2, 0x0, 0x1, 0x5, 0xb, 0x15,0x1d,0x28,0x2f,0x39, +0x41,0x45,0xf0,0xbc,0x30,0x55,0x7, 0x3, 0x3, 0x3, 0x4, 0x7, 0xf, 0x17,0x20,0x28, +0x30,0x36,0x3b,0x3d,0x3f,0x3f,0x3d,0x39,0x36,0x2d,0x25,0x1d,0x16,0xd, 0x8, 0x2, +0x0, 0x0, 0x1, 0x2, 0x3, 0x5, 0x2e,0x3f,0x48,0x50,0x59,0x5f,0x67,0x68,0x63,0x5d, +0x52,0x4a,0x3e,0x35,0x2b,0x20,0x18,0x10,0xa, 0x3, 0x0, 0x0, 0x1, 0x7, 0xe, 0x19, +0x22,0x2b,0x31,0x3a,0x42,0x47,0xef,0xc9,0x30,0x55,0x3b,0x3c,0x3c,0x3b,0x39,0x36, +0x2f,0x27,0x21,0x19,0x11,0xb, 0x5, 0x1, 0x0, 0x0, 0x1, 0x2, 0x4, 0x6, 0xa, 0x10, +0x16,0x1f,0x26,0x2d,0x33,0x39,0x3c,0x3e,0x3f,0x3f,0x22,0x31,0x3b,0x41,0x47,0x4d, +0x56,0x59,0x5a,0x58,0x55,0x51,0x4b,0x43,0x3d,0x35,0x29,0x20,0x18,0x11,0x9, 0x3, +0x0, 0x0, 0x1, 0x3, 0x7, 0xf, 0x15,0x1b,0x21,0x26,0x2b,0xa0,0x30,0x55,0x37,0x38, +0x37,0x34,0x2d,0x26,0x1c,0x16,0xe, 0x9, 0x4, 0x2, 0x0, 0x0, 0x0, 0x1, 0x2, 0x5, +0xa, 0x10,0x17,0x20,0x26,0x2e,0x35,0x3a,0x3c,0x3e,0x3f,0x3f,0x3e,0x3e,0x30,0x40, +0x49,0x50,0x59,0x5e,0x60,0x5d,0x56,0x50,0x47,0x41,0x39,0x33,0x2a,0x20,0x1a,0x10, +0xa, 0x5, 0x1, 0x0, 0x0, 0x3, 0x8, 0x10,0x17,0x1f,0x25,0x2f,0x38,0x3c,0x37,0xc3, +0x30,0x55,0x3b,0x3d,0x3d,0x3b,0x38,0x32,0x27,0x1c,0x13,0xe, 0x8, 0x3, 0x0, 0x0, +0x0, 0x1, 0x3, 0x7, 0xb, 0x12,0x18,0x20,0x28,0x31,0x39,0x3d,0x3f,0x40,0x3f,0x3f, +0x3e,0x3e,0x33,0x45,0x4e,0x57,0x5d,0x65,0x6c,0x6a,0x66,0x63,0x5c,0x53,0x4a,0x40, +0x38,0x2e,0x25,0x1a,0x11,0x8, 0x4, 0x0, 0x0, 0x2, 0x9, 0x10,0x19,0x21,0x2a,0x32, +0x39,0x3e,0x7, 0x90,0x30,0x55,0x39,0x2b,0x24,0x1c,0x15,0xe, 0x9, 0x6, 0x5, 0x6, +0x9, 0x10,0x19,0x22,0x27,0x2e,0x35,0x3b,0x3e,0x3f,0x3d,0x38,0x32,0x2c,0x26,0x1f, +0x19,0x13,0xb, 0x5, 0x1, 0x0, 0x6, 0x0, 0x1, 0x2, 0x6, 0xb, 0x11,0x17,0x1d,0x24, +0x2a,0x2f,0x32,0x34,0x35,0x36,0x37,0x3b,0x41,0x47,0x4e,0x56,0x5d,0x61,0x64,0x65, +0x65,0x63,0x60,0x5c,0x57,0x54,0xd1,0x4a,0x46,0x55,0x0, 0x1, 0x3, 0x5, 0x7, 0x8, +0xa, 0xb, 0xc, 0xe, 0xf, 0x11,0x12,0x14,0x16,0x1a,0x1e,0x22,0x24,0x27,0x2a,0x2c, +0x2e,0x31,0x33,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x3f,0x1, 0xe, 0x14,0x1b,0x23,0x28, +0x2e,0x35,0x3a,0x40,0x48,0x4f,0x56,0x5d,0x62,0x61,0x5a,0x53,0x4e,0x47,0x40,0x3b, +0x35,0x2d,0x29,0x22,0x1b,0x17,0x10,0x9, 0x5, 0x1, 0x6d,0x7d,0x54,0x55,0x0, 0x2, +0x3, 0x5, 0x6, 0x8, 0xb, 0x10,0x13,0x16,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x22,0x22, +0x22,0x22,0x23,0x25,0x28,0x2e,0x31,0x34,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x6, 0x17, +0x20,0x27,0x30,0x38,0x3e,0x39,0x32,0x2b,0x25,0x1e,0x18,0x10,0x9, 0x9, 0x10,0x18, +0x1f,0x26,0x2f,0x36,0x3c,0x38,0x2f,0x27,0x1f,0x18,0xf, 0x8, 0x1, 0x2, 0xc7,0x75, +0x31,0x55,0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x8, 0xd, 0x12,0x15,0x17,0x18,0x1a, +0x1b,0x1c,0x1d,0x1d,0x1e,0x1f,0x22,0x27,0x2e,0x35,0x38,0x3b,0x3d,0x3e,0x3f,0x40, +0x3f,0x3e,0x6, 0x15,0x1b,0x23,0x29,0x2f,0x37,0x3c,0x37,0x2e,0x27,0x20,0x1a,0x13, +0xe, 0x14,0x1a,0x21,0x27,0x2f,0x38,0x3f,0x3d,0x35,0x2e,0x26,0x20,0x18,0x11,0xb, +0x3, 0x0, 0x67,0x3f,0x31,0x55,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, +0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x1c,0x1d,0x1e,0x1f,0x20, +0x21,0x22,0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11, +0x12,0x13,0x14,0x15,0x16,0x17,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xe, +0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x0, 0x1, 0x2, 0x3, 0x4, 0x1c,0x1d,0x1e, +0x1f,0x20,0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, +0x18,0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11, +0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x6, 0x5, 0x4, 0x3, 0x2, 0x1, +0x0, 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, +0x7, 0x8, 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, +0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16, +0x17,0x18,0x19,0x1a,0x1b,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, +0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, +0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x0, 0x1, 0x1, 0x1, 0x10,0x1c,0x2, 0x10, +0x1c,0x0, 0x1, 0x1, 0x4, 0xf, 0x1c,0x0, 0x1, 0x1, 0x6, 0x1b,0xf, 0x7, 0xe, 0x1c, +0x8, 0x23,0x15,0x0, 0x1, 0x1, 0xa, 0x10,0x19,0xb, 0x14,0x1c,0xc, 0xf, 0x18,0x0, +0x1, 0x1, 0xe, 0x23,0x15,0xf, 0xd, 0x19,0x0, 0x1, 0x1, 0x11,0xd, 0x14,0x12,0x10, +0x19,0x13,0x1c,0x10,0x14,0x1a,0x10,0x15,0x10,0x19,0x16,0x23,0x1c,0x72,0x23,0x15, +0x73,0x23,0x1c,0x74,0x23,0x1c,0x75,0xe, 0x1c,0xc2,0xd5,0x7c,0xb4,0x30,0xe7,0x8, +0xb2,0xd5,0x6e,0x24,0xff,0xff,0xb, 0x24,0x7c,0xb6,0x30,0xe7,0x12,0xb2,0xd5,0x6e, +0x34,0xff,0xff,0xb, 0x34,0x8d,0x32,0x6e,0x24,0xff,0xff,0xb, 0x24,0x80,0x2, 0x8d, +0x32,0x30,0xd5,0x6, 0x6e,0x34,0xff,0xff,0xb, 0x34,0x22,0x7d,0x51,0xad,0x3, 0x7d, +0x2, 0x7d,0x21,0xad,0x5, 0x2d,0x12,0xad,0x35,0x2d,0x21,0x22,0x7d,0x2, 0xad,0x31, +0xad,0x10,0x2d,0x21,0x22,0x6d,0x0, 0x74,0x10,0x4d,0x0, 0x78,0xb, 0x4d,0x22,0x78, +0x27,0x8d,0x31,0x7d,0x12,0x6d,0x22,0x22,0x7d,0x43,0x7d,0x32,0x6d,0x22,0x2f,0x11, +0x2d,0x44,0x50,0x2, 0xa5,0xf, 0xbf,0x10,0x40,0x4, 0x9f,0x10,0xb, 0x90,0x14,0x78, +0xed,0x7f,0x1, 0x6d,0x22,0x7d,0x34,0x22,0x7d,0x41,0x7d,0x13,0x8d,0x24,0x7d,0x2, +0x2f,0x0, 0x40,0x4, 0xbd,0x4, 0x40,0x4, 0x9d,0x4, 0xb, 0x14,0x14,0x78,0xf1,0x7d, +0x23,0x7d,0x31,0x7d,0x10,0x6d,0x0, 0x22,0xc2,0xd5,0x7c,0xb0,0x30,0xe7,0x8, 0xb2, +0xd5,0x9f,0x22,0x9f,0x20,0x7f,0x2, 0x7c,0xb4,0x30,0xe7,0x13,0xb2,0xd5,0x9f,0x22, +0x9f,0x21,0x7f,0x12,0x12,0x1f,0x7, 0x9f,0x22,0x9f,0x20,0x7f,0x2, 0x80,0x3, 0x12, +0x1f,0x7, 0x30,0xd5,0x6, 0x9f,0x22,0x9f,0x21,0x7f,0x12,0x22,0x6c,0xaa,0x4d,0x11, +0x68,0x1a,0x1e,0x54,0x68,0xe, 0xb, 0x38,0x20,0x1b,0x18,0x20,0xb, 0x35,0xb, 0x15, +0x1b,0x54,0x78,0xf2,0x50,0x6, 0x7e,0x39,0x40,0x7a,0x19,0x40,0x22,0x6c,0xaa,0x4d, +0x11,0x68,0x1e,0x1e,0x54,0x50,0xc, 0x7e,0x1b,0x0, 0x7a,0x19,0x0, 0x68,0x12,0xb, +0x1c,0xb, 0x14,0xb, 0x1a,0x0, 0x1b,0x18,0x0, 0xb, 0x1d,0xb, 0x15,0x1b,0x54,0x78, +0xf2,0x22,0x75,0x84,0x1, 0x7e,0x44,0x3f,0xff,0xe4,0x7a,0x49,0xb0,0x1b,0x44,0x78, +0xf9,0x7e,0xf8,0x3a,0x10,0x75,0xc, 0x0, 0x75,0xd, 0x0, 0x75,0xe, 0x2, 0x75,0xf, +0x0, 0xc2,0x8, 0xc2,0x9, 0x75,0x1d,0x0, 0xc2,0x10,0xc2,0x11,0xc2,0x13,0x75,0x1e, +0x0, 0x75,0x1f,0x0, 0xc2,0xa, 0xc2,0xb, 0x75,0x5a,0x0, 0xc2,0x15,0x75,0x5b,0x0, +0xc2,0x17,0x75,0x5c,0x0, 0xc2,0x18,0xc2,0x19,0xc2,0x1a,0x75,0x5d,0x0, 0xc2,0xc, +0x75,0x1b,0x0, 0x75,0x1c,0x64,0xc2,0x1b,0xc2,0x1c,0x75,0x5e,0x0, 0xd2,0x5, 0xd2, +0x6, 0xd2,0x7, 0xd2,0x1d,0xc2,0xe, 0xd2,0xf, 0x7e,0x4, 0x0, 0xff,0x7e,0x14,0x21, +0x1a,0xb, 0xa, 0x40,0x5d,0x44,0x68,0x1a,0x69,0x20,0x0, 0x2, 0xb, 0xe, 0xb, 0x44, +0x80,0xa, 0x7e,0xb, 0xb0,0x7a,0x29,0xb0,0xb, 0x24,0xb, 0xc, 0x1b,0x44,0x78,0xf2, +0x80,0xdf,0x2, 0x28,0x9, 0x0, 0x0, 0x0, 0x47,0x0, 0xcb,0x1, 0x0, 0x0, 0x10,0xfd, +0xc7,0xfb,0x7e,0xfb,0xfb,0x1, 0xbb,0xc, 0x9e,0x19,0x0, 0x21,0x45,0x0, 0xe, 0x1, +0xf, 0x2, 0x10,0x3, 0x11,0x4, 0x12,0x5, 0x13,0x6, 0x14,0x7, 0x15,0x8, 0x16,0x9, +0x17,0xa, 0x18,0xb, 0x19,0xc, 0x1a,0xd, 0x1b,0xdf,0x22,0xc3,0x21,0xa9,0x20,0x94, +0x1f,0x81,0x1e,0x70,0x1d,0x62,0x1c,0x55,0x1b,0x4a,0x1a,0x41,0x19,0x38,0x18,0x31, +0x17,0x2b,0x16,0x25,0x15,0x21,0x14,0x1c,0x13,0x19,0x12,0x16,0x11,0x13,0x10,0x11, +0xf, 0x10,0xe, 0xca,0xf8,0x7f,0x20,0x80,0xa, 0x7e,0x1b,0xf0,0x7a,0x2b,0xf0,0xb, +0x34,0xb, 0x54,0x69,0xff,0xff,0xfc,0x7d,0xef,0x1b,0xe4,0x79,0xef,0xff,0xfc,0x4d, +0xff,0x78,0xe6,0x7f,0x10,0xda,0xf8,0x22,0x7d,0x43,0x7f,0x10,0x80,0x7, 0x1b,0x44, +0x7a,0xb, 0xb0,0xb, 0x14,0x4d,0x44,0x78,0xf5,0x22,0xff,0x0, 0x1, 0x2, 0x0, 0xff, +0x1, 0x2, 0x0, 0x1, 0xff,0x2, 0x0, 0x1, 0x2, 0xff,0x7d,0x23,0xbe,0x24,0x0, 0x0, +0x48,0x3, 0x7d,0x32,0x22,0x6d,0x33,0x9d,0x32,0x22,0x0, 0x4, 0x32,0xe5,0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x3, 0xff,0x1, 0x0, 0x1, 0x25,0xf6,0x1, 0x0, 0x1, 0x38,0x9c, +0x0, 0x0, 0x2, 0x38,0xee,0x0, 0x0, 0x0, 0x2, 0x38,0xf0,0x0, 0x0, 0x0, 0x1, 0x38, +0xf2,0x0, 0x0, 0x1, 0x37,0xe1,0xff,0x0, 0x1, 0x34,0x4f,0x0, 0x0, 0x1, 0x3a,0xe, +0x0, 0x0, 0x1, 0x34,0x8b,0x0, 0x0, 0x2, 0x34,0xb4,0x0, 0x0, 0x0, 0x1, 0x34,0xb6, +0x0, 0x0, 0x1, 0x34,0xc4,0x0, 0x0, 0x1, 0x34,0xc5,0x0, 0x0, 0x1, 0x34,0xda,0x0, +0x0, 0x1, 0x34,0xdb,0x0, 0x0, 0x1, 0x35,0x54,0x0, 0x0, 0x1, 0x35,0x55,0x1, 0x0, +0x1, 0x35,0x56,0x0, 0x0, 0x3c,0x36,0xe9,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x37,0x61,0x0, 0x0, 0x1, 0x37,0x62,0x0, 0x0, 0x1, +0x37,0x63,0x0, 0x0, 0x1, 0x36,0xe2,0x1, 0x0, 0x2, 0x36,0xe5,0x0, 0x0, 0x0, 0x1, +0x2f,0xa9,0x0, 0x0, 0x1, 0x2f,0xaa,0x0, 0x0, 0x1, 0x2f,0xab,0x0, 0x0, 0x1, 0x37, +0x66,0x1, 0x0, 0x1, 0x37,0xe0,0x0, 0x0, 0x1, 0x3a,0xf, 0x0, 0x0, 0x6, 0x39,0xfc, +0x3f,0x1f,0x50,0x11,0x20,0x10,0x0, 0x1, 0x3a,0x2, 0x24,0x0, 0x1, 0x3a,0x9, 0x0, +0x0, 0x1, 0x3a,0xa, 0x0, 0x0, 0x1, 0x3a,0xb, 0x0, 0x0, 0x1, 0x3a,0xc, 0x0, 0x0, +0x1, 0x3a,0xd, 0x0, 0x0, 0x1, 0x0, 0x5f,0x0, 0x0, 0x1, 0x3, 0xfc,0x0, 0x0, 0x1, +0x31,0xcd,0x0, 0x0, 0x2, 0x31,0xee,0x0, 0x0, 0x0, 0x1, 0x32,0x2c,0x0, 0x0, 0x4, +0x38,0x41,0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3a,0x3, 0x0, 0x0, 0x1, 0x3a,0x4, 0x0, +0x0, 0x2, 0x3a,0x5, 0x0, 0x0, 0x0, 0x1, 0x3a,0x7, 0x64,0x0, 0x1, 0x3a,0x8, 0x0, +0x0, 0x1, 0x3a,0x10,0x0, 0x0, 0x1, 0x3, 0xfd,0x0, 0x0, 0x1, 0x3, 0xfe,0x0, 0x0, +0x2, 0x2b,0xb9,0x2b,0xbf,0x0, 0x1, 0x2f,0x7f,0x2, 0x0, 0x1, 0x2f,0xa8,0x0, 0x0, +0x1, 0x39,0x3f,0xff,0x0, 0x1, 0x39,0x40,0x0, 0x0, 0x1, 0x39,0x41,0x0, 0x0, 0x1, +0x39,0x42,0x40,0x0, 0x1, 0x39,0x43,0x40,0x0, 0x1, 0x39,0xde,0x0, 0x0, 0x4, 0x39, +0xf4,0x0, 0x0, 0x50,0x0, 0x0, 0x4, 0x39,0xf8,0x0, 0x0, 0x64,0x0, 0x0, 0x4, 0x39, +0xc1,0x0, 0x0, 0x6c,0x0, 0x0, 0x4, 0x39,0xc5,0x0, 0x0, 0x68,0xc0,0x0, 0x4, 0x39, +0xc9,0x0, 0x0, 0x68,0x0, 0x0, 0x4, 0x39,0xda,0x0, 0x0, 0x40,0x0, 0x0, 0x4, 0x33, +0xfc,0x0, 0x0, 0x60,0x0, 0x0, 0x0, 0x3, 0x84,0x0, 0xd, 0x1, 0xf4,0x2, 0xbc,0x0, +0xd, 0x1, 0x4a,0x2, 0x58,0x0, 0xc, 0x0, 0xc8,0x1, 0xf4,0x0, 0xb, 0x0, 0xa0,0x1, +0x90,0x0, 0x9, 0x0, 0x50,0x0, 0xc8,0x0, 0x7, 0x0, 0x1e,0x0, 0x3c,0x0, 0x14,0x0, +0x18,0x0, 0xe, 0x1c,0x23,0x5, 0xdc,0x0, 0x32,0x3, 0xe8,0x0, 0x28,0x0, 0x0, 0x0, +0x1e,0x12,0x31,0xa9,0x12,0x23,0x91,0x12,0x23,0x5c,0x12,0x24,0x36,0x2, 0x23,0x20, +0x12,0x23,0x31,0x7e,0xb3,0x2b,0xf, 0x12,0x57,0xfc,0x74,0x1, 0x7a,0xb3,0x37,0x6a, +0x22,0x12,0xab,0x26,0x74,0x1, 0x7a,0xb3,0x37,0x66,0x22,0x12,0x23,0xc8,0x12,0x28, +0x2b,0x12,0x58,0xef,0x12,0x31,0xa9,0x12,0x23,0xc8,0x12,0x23,0x91,0x12,0xc6,0x6e, +0x12,0x23,0x5c,0x12,0x24,0x36,0x12,0x24,0x66,0x2, 0x23,0x20,0x12,0x59,0x38,0x12, +0x23,0xae,0x2, 0x23,0x65,0x7e,0x34,0x0, 0x3, 0x6d,0x22,0x2, 0x23,0x6e,0x7d,0x43, +0x7e,0xa3,0x34,0x38,0xbe,0xa0,0x5, 0x50,0x16,0x7e,0x70,0x4, 0xac,0x7a,0x59,0x43, +0x34,0x3b,0x59,0x23,0x34,0x3d,0x7c,0xba,0x4, 0x7a,0xb3,0x34,0x38,0xc3,0x22,0xd3, +0x22,0x12,0x36,0xad,0x12,0x69,0x83,0x2, 0x23,0x9a,0x30,0x13,0x10,0x12,0x57,0x8e, +0x50,0x3, 0x12,0x51,0xf9,0x12,0x69,0xa9,0x12,0x55,0xae,0xc2,0x13,0x22,0x6d,0x33, +0x7e,0x24,0x6, 0xfc,0x12,0x23,0x6e,0x7e,0x34,0x0, 0x1, 0x7e,0x24,0x7, 0x7a,0x2, +0x23,0x6e,0x74,0x1, 0x7a,0xb3,0x38,0xa1,0x7e,0x34,0xd, 0xac,0x6d,0x22,0x7a,0x27, +0x33,0xeb,0x7a,0x37,0x33,0xed,0x22,0xca,0xf8,0x7e,0xf3,0x38,0xa1,0xbe,0xf0,0x5, +0x78,0xb, 0x74,0x1, 0x7a,0xb3,0x38,0xa1,0x12,0x0, 0xa, 0x80,0x40,0xbe,0xf0,0x4, +0x78,0xd, 0x12,0x23,0xc2,0xe4,0x7a,0xb3,0x2b,0x2, 0x12,0x36,0xad,0x80,0x2e,0xbe, +0xf0,0x6, 0x78,0x13,0x12,0x23,0xc2,0x12,0x3b,0xd3,0xe4,0x7a,0xb3,0x2b,0x1e,0x12, +0x69,0x83,0x12,0xc6,0xd0,0x80,0x16,0xbe,0xf0,0x7, 0x78,0x17,0x12,0x23,0xc2,0x12, +0x69,0x78,0x50,0xfb,0x12,0x6a,0xb8,0x12,0x23,0x9a,0x12,0x24,0x36,0x74,0x2, 0x7a, +0xb3,0x38,0xa1,0xda,0xf8,0x22,0xe4,0x7a,0xb3,0x34,0x3a,0x7a,0xb3,0x34,0x39,0x12, +0x3f,0xd2,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x2, 0x74,0x3, 0x7a,0xb3,0x34,0x3a,0x22, +0x12,0xc6,0x6e,0x12,0x4a,0x2e,0x7a,0x37,0x3a,0x5, 0x12,0x23,0xc8,0x12,0x23,0x91, +0x12,0x24,0x36,0x2, 0x24,0x66,0x74,0xa, 0x7a,0xb3,0x34,0x89,0xe4,0x7a,0xb3,0x34, +0x8a,0x7e,0x8, 0x34,0x8c,0x7e,0x34,0x0, 0xa, 0x74,0xa, 0x12,0x20,0xe8,0x7e,0x8, +0x34,0x96,0x7e,0x34,0x0, 0xa, 0xe4,0x2, 0x20,0xe8,0xca,0x3b,0x12,0x69,0x78,0x50, +0xfb,0x7e,0xf3,0x2b,0xf, 0x7c,0xbf,0x12,0x8b,0x38,0x12,0xb8,0xc9,0x7e,0xb3,0x2b, +0x1f,0xf5,0x28,0x7e,0xc3,0x2b,0x20,0x7e,0xb3,0x38,0x9, 0xb4,0x1, 0xf, 0x12,0x51, +0xbf,0x7e,0xb3,0x16,0x91,0x70,0x6, 0x12,0x24,0x36,0xc3,0xa1,0x86,0x12,0x25,0x89, +0x3e,0x34,0xca,0x39,0x7e,0x18,0x6, 0xfc,0x7e,0x8, 0x4, 0x7e,0x12,0x20,0xc3,0x1b, +0xfd,0x12,0x25,0x89,0x3e,0x34,0xca,0x39,0x7e,0x18,0x7, 0x7a,0x7e,0x8, 0x4, 0x0, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xb3,0x38,0x9, 0xb4,0x3, 0x7, 0x12,0xa5,0x25,0x7a, +0x37,0x38,0xe4,0x74,0x1, 0x7a,0xb3,0x16,0x90,0x12,0x23,0x91,0x12,0xa5,0x16,0x12, +0x50,0xd8,0xe4,0x12,0x13,0xde,0x12,0x24,0x36,0x7e,0x8, 0x4, 0x7e,0x7a,0xd, 0x29, +0x7e,0x18,0x6, 0x76,0x7e,0xb3,0x2b,0x72,0x12,0xb9,0xea,0x7e,0x8, 0x4, 0x0, 0x7a, +0xd, 0x29,0x7e,0x18,0x5, 0xf8,0x7e,0xb3,0x25,0xf0,0x12,0xb9,0xea,0x7e,0xd3,0x2b, +0x1f,0x7e,0xe3,0x2b,0x20,0xe5,0x28,0x7a,0xb3,0x2b,0x1f,0x7a,0xc3,0x2b,0x20,0x7e, +0x34,0x8, 0xa, 0x7e,0x4, 0xd, 0xc8,0x7d,0x20,0x7d,0x10,0x12,0x56,0x2d,0x7a,0xd3, +0x2b,0x1f,0x7a,0xe3,0x2b,0x20,0x7c,0xbf,0x12,0x8a,0xbb,0x12,0xa4,0x16,0x7e,0xb3, +0x3a,0x8, 0x4, 0x7a,0xb3,0x3a,0x8, 0x7e,0x73,0x3a,0x8, 0xbe,0x70,0xfa,0x28,0x6, +0x74,0x64,0x7a,0xb3,0x3a,0x8, 0x7e,0xb3,0x16,0x90,0x60,0x9, 0x7e,0xb3,0x16,0x91, +0x60,0x3, 0xd3,0x80,0x1, 0xc3,0xda,0x3b,0x22,0x7e,0x73,0x2a,0x74,0xa, 0x27,0x7e, +0x73,0x2a,0x73,0xa, 0x37,0x2d,0x32,0x22,0x12,0x3a,0xc6,0x7e,0xb3,0x38,0x9, 0xb4, +0x3, 0x69,0x12,0xb8,0x28,0x12,0x2f,0xe7,0x12,0x2d,0x59,0x7e,0xb3,0x38,0x9d,0x30, +0xe7,0xe9,0x12,0x24,0x8a,0x12,0x25,0x89,0x3e,0x34,0xca,0x39,0x7e,0x18,0x4, 0x0, +0x7e,0x8, 0x4, 0xfc,0x12,0x20,0xc3,0x1b,0xfd,0x12,0x25,0x89,0x3e,0x34,0xca,0x39, +0x7e,0x18,0x4, 0x7e,0x7e,0x8, 0x5, 0x7a,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xb3,0x2b, +0x1d,0xb4,0x1, 0x15,0x12,0x67,0x6c,0x12,0x85,0xfd,0x12,0x44,0xaf,0x12,0x6a,0xc3, +0x12,0x77,0x1d,0x12,0x26,0x1b,0x12,0x3f,0xfa,0x12,0x3b,0x8, 0x12,0xad,0x82,0x7e, +0xb3,0x38,0x9d,0x54,0x7f,0x7a,0xb3,0x38,0x9d,0x80,0x90,0x12,0x6a,0x6d,0x2, 0x0, +0x46,0xe4,0x7a,0xb3,0x2b,0x2, 0x7a,0xb3,0x2b,0x1e,0x22,0x12,0x73,0x74,0x12,0x75, +0x4a,0x12,0x75,0x4a,0x12,0x8c,0xdb,0x12,0xa1,0xc1,0x12,0x88,0x7e,0x12,0x75,0x4a, +0x12,0x92,0xe7,0x12,0x75,0x4a,0x12,0x96,0xc8,0x12,0x75,0x4a,0x2, 0x26,0x3f,0xca, +0x3b,0x75,0x24,0x0, 0x6c,0xcc,0x6c,0xdd,0x7e,0xc4,0x0, 0x3c,0xca,0xc9,0x7e,0x18, +0x37,0x25,0x7e,0x8, 0x36,0xe9,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xf3,0x28,0x84,0xa, +0xcf,0x3e,0xc4,0xca,0xc9,0x7e,0x18,0x26,0xfa,0x7e,0x8, 0x1f,0x34,0x12,0x20,0xc3, +0x1b,0xfd,0x6c,0x88,0x6c,0xee,0xe1,0x13,0x7e,0xc4,0x3, 0xff,0x7e,0xc0,0xff,0x6c, +0x99,0x80,0x4c,0x74,0x2, 0xac,0xb9,0x9, 0xb5,0x1f,0x34,0xbe,0xb0,0xff,0x68,0x3d, +0x7c,0xb9,0x12,0x88,0x65,0x60,0x36,0x74,0x2, 0xac,0xb9,0x9, 0x75,0x1f,0x35,0xa, +0x27,0x74,0x2, 0xac,0xbe,0x9, 0x75,0x37,0x26,0x12,0x96,0xa4,0x7d,0x13,0x74,0x2, +0xac,0xb9,0x9, 0x75,0x1f,0x34,0xa, 0x27,0x74,0x2, 0xac,0xbe,0x9, 0x75,0x37,0x25, +0x12,0x96,0xa4,0x2d,0x13,0xbd,0xc1,0x28,0x4, 0x7d,0xc1,0x7c,0xc9,0xb, 0x90,0xbc, +0xf9,0x38,0xb0,0xbe,0xc0,0xff,0x68,0x39,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x1f, +0x34,0x9, 0x73,0x1f,0x35,0x12,0x6d,0xcb,0xbe,0x37,0x2a,0x5a,0x48,0x23,0x7e,0x70, +0x2, 0xac,0x7c,0x9, 0x53,0x1f,0x34,0x74,0x2, 0xac,0xbd,0x19,0x55,0x1f,0x70,0x9, +0x53,0x1f,0x35,0x19,0x55,0x1f,0x71,0x74,0xff,0x19,0xb3,0x1f,0x34,0xb, 0x80,0xb, +0xd0,0xb, 0xe0,0x7e,0x73,0x36,0xe8,0xbc,0x7e,0x28,0x2, 0xc1,0x78,0x7c,0xe8,0x80, +0x6d,0x6d,0xdd,0x7e,0x80,0xff,0x6c,0x99,0x80,0x3c,0x7c,0xb9,0x12,0x88,0x65,0x60, +0x33,0x12,0xc6,0x99,0xbe,0xb0,0xff,0x68,0x2b,0x9, 0x73,0x1f,0x35,0x12,0x6f,0x81, +0x7f,0x71,0xb, 0x7a,0x50,0xbe,0x54,0x0, 0x0, 0x58,0x5, 0x6d,0x55,0x1b,0x7a,0x50, +0xb, 0x7a,0xc0,0xbd,0xcd,0x8, 0xd, 0x12,0xc6,0x99,0xf5,0x24,0x9, 0xc3,0x1f,0x35, +0x7d,0xdc,0x7c,0x89,0xb, 0x90,0xbc,0xf9,0x38,0xc0,0xbe,0x80,0xff,0x68,0x1d,0x7e, +0x71,0x24,0x74,0x2, 0xac,0xbd,0x19,0x75,0x1f,0x70,0x19,0xc5,0x1f,0x71,0x7e,0xa0, +0xff,0x7e,0x70,0x2, 0xac,0x78,0x19,0xa3,0x1f,0x34,0xb, 0xd0,0xb, 0xe0,0xbe,0xe0, +0xa, 0x40,0x8e,0x7e,0x34,0x0, 0x3c,0xca,0x39,0x7e,0x18,0x1f,0x70,0x7e,0x8, 0x1f, +0x34,0x12,0x20,0xc3,0x1b,0xfd,0x7c,0xfd,0x7e,0x8, 0x37,0x25,0x7e,0x34,0x0, 0x14, +0x74,0xff,0x12,0x20,0xe8,0xbe,0xf0,0x0, 0x28,0x35,0xa, 0x3f,0x3e,0x34,0xca,0x39, +0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x26,0xfa,0x12,0x20,0xc3,0x1b,0xfd,0xa, 0x3f,0x3e, +0x34,0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x37,0x25,0x12,0x20,0xc3,0x1b,0xfd, +0x6c,0xee,0x80,0x7, 0x7c,0xbe,0x12,0x76,0xfb,0xb, 0xe0,0xbc,0xfe,0x38,0xf5,0x7a, +0xf3,0x36,0xe8,0x7a,0xf3,0x28,0x84,0x7e,0x73,0x28,0x84,0xbe,0x70,0xa, 0x28,0x6, +0x74,0xa, 0x7a,0xb3,0x28,0x84,0xda,0x3b,0x22,0x12,0x28,0x2b,0x12,0x62,0xf6,0x12, +0x58,0xef,0x12,0x23,0x11,0x7e,0xb3,0x38,0x9, 0x24,0xfd,0x68,0x9, 0xb, 0xb1,0x78, +0xf4,0x12,0x40,0x98,0x80,0xef,0x12,0x25,0x98,0x80,0xea,0xe4,0x12,0xb6,0xbd,0x12, +0xb7,0xaa,0x12,0x2f,0xe7,0x12,0xb8,0x21,0x12,0x28,0x6e,0x12,0xb6,0x6b,0x12,0xb7, +0xc1,0x12,0x0, 0x9, 0x12,0xb7,0xcd,0x12,0x68,0xad,0x12,0xb7,0xdd,0xd2,0xaf,0x12, +0xb7,0x3c,0x12,0x64,0x46,0x12,0x2a,0x98,0x12,0xb7,0x2, 0x7e,0x8, 0x33,0xef,0x12, +0xb8,0x41,0x74,0xe, 0x7e,0x70,0x19,0x7e,0x24,0xff,0xff,0x2, 0x12,0x34,0xa9,0xd5, +0xcb,0x74,0x2, 0x7e,0x70,0x3f,0x12,0x28,0xba,0x74,0xf, 0x12,0x0, 0x66,0x7c,0x7b, +0x74,0xf, 0x5e,0x70,0xfe,0x12,0x28,0xba,0x74,0xc, 0x12,0x0, 0x66,0x54,0x7f,0x68, +0x8, 0x74,0xc, 0x7e,0x70,0xf8,0x12,0x28,0xba,0x7e,0x70,0x72,0x74,0xe, 0x12,0x28, +0xba,0x74,0x7, 0x12,0x0, 0x66,0x7c,0x7b,0x5e,0x70,0xfb,0x74,0x7, 0x2, 0x28,0xb0, +0x12,0x28,0xba,0x75,0xfd,0xff,0xa9,0xc5,0xcb,0x22,0xf5,0xfd,0x7a,0x71,0xfe,0x22, +0xca,0x79,0x7d,0xd3,0x7e,0x80,0xe, 0x7e,0xf0,0x28,0x12,0x2f,0xe7,0xa9,0xd0,0xc4, +0xa9,0xd5,0xcb,0x74,0x7, 0x12,0x0, 0x66,0xf5,0x24,0x74,0x7, 0x7e,0x70,0xf, 0x12, +0x28,0xb0,0x7e,0x54,0x0, 0x78,0x7e,0x1f,0x39,0xc5,0x79,0x51,0x0, 0x6, 0x7e,0x54, +0x0, 0x80,0x7e,0x1f,0x39,0xc5,0x79,0x51,0x0, 0x8, 0x7e,0x54,0x0, 0xc, 0x7e,0x1f, +0x39,0xc5,0x79,0x51,0x0, 0x10,0xbe,0xd4,0x0, 0x2, 0x78,0x7, 0x12,0x2a,0x7d,0x44, +0x1, 0x80,0x1c,0x12,0x2a,0x7d,0x44,0x8, 0x1b,0x1a,0x50,0x4d,0xdd,0x7e,0x1f,0x39, +0xc5,0x78,0x7, 0x12,0x2a,0x81,0x54,0xfb,0x80,0x5, 0x12,0x2a,0x81,0x44,0x4, 0x1b, +0x1a,0x50,0x7e,0x1f,0x39,0xc1,0x69,0xe1,0x0, 0x84,0x69,0x51,0x0, 0x90,0x7d,0xf5, +0x2e,0x34,0x0, 0x90,0x5e,0xa0,0xf6,0x1b,0x1a,0x50,0x7e,0xb3,0x38,0x13,0xbe,0xb0, +0x6, 0x40,0x3, 0xb4,0xff,0xe, 0x12,0x2a,0x8c,0x54,0xe6,0x12,0x2a,0x89,0x4e,0x54, +0x1, 0xa4,0x80,0xc, 0x12,0x2a,0x8c,0x5e,0x54,0xfe,0xe6,0x12,0x2a,0x89,0x44,0xa4, +0x1b,0x1a,0x50,0xbe,0xd4,0x0, 0x2, 0x78,0x26,0x12,0x2f,0x3, 0x5e,0x34,0x0, 0xf, +0x1b,0xa, 0x30,0x12,0x2f,0x3, 0x4e,0x70,0x50,0x1b,0xa, 0x30,0x7e,0x34,0x0, 0x2, +0x12,0x2d,0x3a,0x12,0x2d,0x13,0x12,0x2c,0xf0,0x7a,0x37,0x32,0xe9,0x41,0x3a,0x6c, +0xee,0x41,0x34,0x4c,0xee,0x78,0x4, 0x6c,0x99,0x80,0x2b,0xbc,0x8e,0x40,0x12,0xa, +0xce,0x9, 0x9c,0x2a,0xb8,0xbe,0x90,0x23,0x40,0x3, 0x7e,0x90,0x22,0xb, 0x90,0x80, +0x15,0xa, 0x38,0xa, 0xce,0x9d,0xc3,0x9, 0x9c,0x2a,0xdb,0xbe,0x90,0x1c,0x40,0x3, +0x7e,0x90,0x1b,0x2e,0x90,0x24,0x12,0x2a,0x7d,0x5e,0x54,0x0, 0xf, 0x1b,0x1a,0x50, +0xa, 0xc9,0x3e,0xc4,0x3e,0xc4,0x3e,0xc4,0x3e,0xc4,0x12,0x2a,0x7d,0x4d,0x5c,0x1b, +0x1a,0x50,0xe5,0xe, 0x60,0x7, 0xe5,0xe, 0xbe,0xb0,0x64,0x28,0x6, 0x7e,0x34,0x0, +0x2, 0x80,0x4, 0xe5,0xe, 0xa, 0x3b,0x12,0x2d,0x3a,0x12,0x2d,0x13,0xbe,0xd4,0x0, +0x1, 0x78,0x10,0x12,0x2d,0x13,0x12,0x2c,0xf0,0x74,0x2, 0xac,0xbe,0x59,0x35,0x32, +0xeb,0x80,0xf, 0x12,0x2c,0xf0,0xa, 0x5f,0xa, 0x2e,0x2d,0x25,0x3e,0x24,0x59,0x32, +0x32,0xeb,0xb, 0xe0,0xbc,0xfe,0x28,0x2, 0x21,0xa3,0xa9,0xd5,0xcb,0x74,0x7, 0x7e, +0x71,0x24,0x12,0x28,0xb0,0xa9,0xc0,0xc4,0x7e,0x1f,0x39,0xc1,0x79,0xe1,0x0, 0x84, +0x7e,0x1f,0x39,0xc1,0x79,0xf1,0x0, 0x90,0x6d,0x33,0x7e,0xf, 0x39,0xc5,0x79,0x30, +0x0, 0x6, 0x7e,0xf, 0x39,0xc5,0x79,0x30,0x0, 0x8, 0x7e,0xf, 0x39,0xc5,0x79,0x30, +0x0, 0x10,0x7e,0xf, 0x39,0xc5,0x79,0x30,0x0, 0xe, 0xda,0x79,0x22,0x7e,0x1f,0x39, +0xc5,0x2e,0x34,0x0, 0xe, 0xb, 0x1a,0x50,0x22,0x1b,0x1a,0x50,0x7e,0x1f,0x39,0xc1, +0x2e,0x34,0x0, 0x84,0xb, 0x1a,0x50,0x22,0x6d,0x33,0x7e,0x8, 0x0, 0x24,0x7e,0x24, +0x0, 0x12,0x12,0x63,0x62,0xe5,0x34,0x20,0xe7,0x1b,0xa9,0xd5,0xcb,0x74,0x3, 0x7e, +0x71,0x27,0x12,0x28,0xba,0x74,0xb, 0x7e,0x71,0x2f,0x12,0x28,0xba,0x74,0xc, 0x7e, +0x71,0x30,0x12,0x28,0xb0,0x22,0xca,0xf8,0x7c,0xab,0xbe,0xa0,0x34,0x38,0x2, 0x61, +0xd7,0xbe,0xa0,0x35,0x78,0x6, 0x7e,0xb3,0x2b,0x10,0x81,0xed,0xbe,0xa0,0x36,0x68, +0x5, 0xbe,0xa0,0x37,0x78,0x1d,0x7e,0x35,0x8, 0x7d,0x23,0xb, 0x24,0x7a,0x25,0x8, +0x2e,0x37,0x32,0xe3,0x7e,0x39,0xb0,0xbe,0xa0,0x37,0x68,0x2, 0x81,0xed,0x75,0x1a, +0x36,0x81,0xed,0xbe,0xa0,0x38,0x68,0x5, 0xbe,0xa0,0x39,0x78,0x1b,0x7e,0xf3,0x38, +0xc1,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc1,0xbe,0xa0,0x39,0x78,0x3, 0x75,0x1a,0x38, +0xa, 0x3f,0x9, 0xb3,0x2b,0x21,0x81,0xed,0xbe,0xa0,0x3a,0x68,0x5, 0xbe,0xa0,0x3b, +0x78,0x1b,0x7e,0xf3,0x38,0xc3,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc3,0xbe,0xa0,0x3b, +0x78,0x3, 0x75,0x1a,0x3a,0xa, 0x3f,0x9, 0xb3,0x2b,0x44,0x81,0xed,0xbe,0xa0,0xfb, +0x78,0x6, 0x7e,0xb3,0x2b,0x12,0x81,0xed,0xbe,0xa0,0x5e,0x78,0x26,0x7e,0xf, 0x39, +0xc1,0x69,0x30,0x0, 0x8e,0xa, 0x56,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x5e,0x54,0x0, +0x1, 0x3, 0x3, 0x54,0xc0,0xa, 0x36,0x5e,0x34,0x0, 0x3, 0x7c,0xa7,0x4c,0xba,0x44, +0x80,0x81,0xed,0xbe,0xa0,0x3c,0x68,0x5, 0xbe,0xa0,0x3d,0x78,0x1b,0x7e,0xf3,0x38, +0xc5,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc5,0xbe,0xa0,0x3d,0x78,0x3, 0x75,0x1a,0x3c, +0xa, 0x3f,0x9, 0xb3,0x2a,0x7a,0x81,0xed,0xbe,0xa0,0x3e,0x68,0x5, 0xbe,0xa0,0x3f, +0x78,0x1b,0x7e,0xf3,0x38,0xc7,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc7,0xbe,0xa0,0x3f, +0x78,0x3, 0x75,0x1a,0x3e,0xa, 0x3f,0x9, 0xb3,0x2a,0x9d,0x81,0xed,0xbe,0xa0,0x40, +0x40,0xd, 0xbe,0xa0,0x4d,0x38,0x8, 0xa, 0x3a,0x9, 0xb3,0x38,0x9d,0x81,0xed,0xbe, +0xa0,0x4e,0x68,0x5, 0xbe,0xa0,0x4f,0x78,0x1e,0x7e,0xf3,0x38,0xe2,0x7c,0xbf,0x4, +0x7a,0xb3,0x38,0xe2,0xbe,0xa0,0x4f,0x78,0x3, 0x75,0x1a,0x4e,0xa, 0x3f,0x2e,0x37, +0x32,0xe1,0x7e,0x39,0xb0,0x81,0xed,0xbe,0xa0,0x51,0x68,0x5, 0xbe,0xa0,0x52,0x78, +0x28,0x7e,0x14,0x60,0x0, 0x6d,0x0, 0x2e,0x4, 0x0, 0xff,0x7e,0xb3,0x38,0xed,0xa, +0x3b,0x6d,0x22,0x2f,0x10,0x7e,0x1b,0x70,0x4, 0x7a,0xb3,0x38,0xed,0xbe,0xa0,0x52, +0x78,0x3, 0x75,0x1a,0x51,0x7c,0xb7,0x81,0xed,0xbe,0xa0,0x5c,0x68,0x5, 0xbe,0xa0, +0x5d,0x78,0x1a,0x7e,0xf3,0x38,0xb6,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xb6,0xbe,0xa0, +0x5d,0x78,0x3, 0x75,0x1a,0x5c,0x7c,0xbf,0x12,0xad,0x2, 0x81,0xed,0xbe,0xa0,0x60, +0x40,0xd, 0xbe,0xa0,0x6c,0x38,0x8, 0xa, 0x3a,0x9, 0xb3,0x33,0x8f,0x80,0x7e,0xbe, +0xa0,0x6d,0x78,0x4, 0xe5,0xe, 0x80,0x75,0xbe,0xa0,0xf4,0x68,0x5, 0xbe,0xa0,0xf5, +0x78,0x18,0x7e,0x35,0xa, 0x7d,0x23,0xb, 0x24,0x7a,0x25,0xa, 0x9, 0xb3,0x32,0xe9, +0xbe,0xa0,0xf5,0x78,0x58,0x75,0x1a,0xf4,0x80,0x53,0xbe,0xa0,0xf0,0x68,0x5, 0xbe, +0xa0,0xf1,0x78,0x9, 0x7c,0x1a,0x2e,0x10,0x20,0xa5,0xe7,0x80,0x40,0xbe,0xa0,0xf2, +0x68,0x5, 0xbe,0xa0,0xf3,0x78,0x1b,0x7e,0x15,0x10,0x3e,0x14,0x7e,0x1f,0x32,0xe5, +0x2d,0x31,0xb, 0x1a,0x30,0xbe,0xa0,0xf2,0x78,0x4, 0xa, 0x56,0x80,0x1f,0x7d,0x53, +0x80,0x1b,0xbe,0xa0,0xf6,0x78,0x4, 0xe5,0xf, 0x80,0x12,0xbe,0xa0,0xf7,0x78,0x4, +0x74,0x32,0x80,0x9, 0xbe,0xa0,0xfd,0x78,0x3, 0xe4,0x80,0x1, 0xe4,0xda,0xf8,0x22, +0x7e,0xf, 0x39,0xc5,0x69,0x30,0x0, 0xa, 0x7d,0x23,0x6d,0x33,0x69,0x10,0x0, 0xc, +0x6d,0x0, 0x2f,0x10,0x74,0x7, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14, +0x78,0xf4,0x22,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x39,0xc5,0x79,0x30,0x0, 0x4, 0x7e, +0xf, 0x39,0xc5,0x69,0x30,0x0, 0x12,0x5e,0x34,0x0, 0x1, 0x68,0xf2,0x7e,0x34,0x0, +0x1, 0x79,0x30,0x0, 0x12,0x22,0x7e,0x34,0x0, 0x1, 0x7d,0x23,0x80,0x12,0x7e,0x30, +0x4, 0x80,0x5, 0x74,0xfa,0x12,0x2f,0x39,0x7c,0x23,0x1b,0x30,0xa5,0xba,0x0, 0xf3, +0x7d,0x32,0x1b,0x24,0x4d,0x33,0x78,0xe6,0x22,0x30,0x8, 0x3b,0xc2,0x8, 0x12,0x23, +0xd7,0x7e,0x73,0x38,0xa2,0x7a,0x73,0x2a,0x4d,0x7e,0x73,0x38,0xa3,0x7a,0x73,0x2b, +0x1d,0x7e,0x73,0x38,0xa3,0x7a,0x73,0x2b,0x1, 0x7e,0xb3,0x38,0xa4,0x60,0x18,0x7e, +0x34,0x0, 0x2, 0x12,0x28,0xc0,0x7e,0x34,0x0, 0x1, 0x12,0x28,0xc0,0x6d,0x33,0x12, +0x28,0xc0,0xe4,0x7a,0xb3,0x38,0xa4,0x12,0x36,0x2d,0x2, 0x2d,0x9d,0xe5,0xc, 0x70, +0x2, 0xc1,0xbc,0xe5,0xc, 0x30,0xe0,0x10,0x53,0xc, 0xfe,0x12,0xaa,0xc5,0x12,0x64, +0xdf,0x7e,0x8, 0x2a,0x6d,0x12,0x9, 0xa1,0xe5,0xc, 0x30,0xe1,0x6, 0x53,0xc, 0xfd, +0x12,0xbb,0x4c,0xe5,0xc, 0x30,0xe2,0x2f,0x53,0xc, 0xfb,0x7e,0xb3,0x2b,0x12,0x60, +0x9, 0x7e,0x8, 0x2a,0x6d,0x12,0x6, 0xba,0x80,0xb, 0x7e,0xb3,0x2b,0x65,0x7e,0x73, +0x2b,0x64,0x12,0xb, 0xad,0x7e,0x73,0x2b,0x12,0x2e,0x70,0xff,0x92,0x1, 0x74,0x19, +0x9e,0xb3,0x2a,0x77,0x12,0xb, 0x1e,0xe5,0xc, 0x30,0xe3,0x4a,0x53,0xc, 0xf7,0x7e, +0x73,0x38,0xcf,0x7a,0x73,0x2b,0xf, 0x12,0x8b,0x16,0x7a,0xb3,0x0, 0x5f,0xbe,0xb0, +0xff,0x68,0xb, 0x43,0xc, 0x20,0x7e,0x73,0x0, 0x5f,0x7a,0x73,0x38,0xa7,0x12,0x51, +0x36,0x12,0x3f,0xeb,0x7e,0x73,0x38,0xd0,0xbe,0x73,0x2b,0x62,0x68,0x6, 0x7a,0x73, +0x2b,0x62,0xd2,0x10,0x30,0x10,0x9, 0xc2,0x10,0x12,0x57,0xd5,0xe4,0x12,0xa, 0x66, +0x12,0x23,0x31,0x12,0x57,0xf8,0xe5,0xc, 0x30,0xe4,0xf, 0x53,0xc, 0xef,0x7e,0x43, +0x38,0xd1,0x7e,0x50,0xa, 0xac,0x45,0x12,0x3a,0xf8,0xe5,0xc, 0x30,0xe6,0x4e,0x53, +0xc, 0xbf,0x7e,0x73,0x38,0xbd,0xbe,0x70,0x7, 0x28,0x6, 0x74,0x7, 0x7a,0xb3,0x38, +0xbd,0xa9,0xd5,0xcb,0x74,0xe, 0x12,0x0, 0x66,0x7c,0x7b,0x5e,0x70,0xf, 0x7e,0x63, +0x38,0xbd,0xa, 0x26,0x2e,0x24,0x0, 0x3, 0x12,0x7f,0x9, 0x7c,0x65,0x4c,0x76,0x74, +0xe, 0x12,0x28,0xba,0x12,0x0, 0x66,0x12,0x28,0xb3,0x7e,0x73,0x38,0xc0,0x7a,0x73, +0x2b,0x14,0x7e,0x73,0x38,0xbf,0x7a,0x73,0x2b,0x1f,0x12,0xc6,0xd0,0xe5,0xc, 0x30, +0xe5,0xa, 0x53,0xc, 0xdf,0x7e,0xb3,0x38,0xa7,0x2, 0x3b,0x46,0x22,0x24,0xab,0x68, +0x10,0x24,0xef,0x68,0x1c,0x24,0xde,0x68,0x26,0x24,0xde,0x78,0x2f,0x74,0x5, 0x80, +0x2d,0x7e,0xb3,0x3, 0xff,0xb4,0x5, 0x2a,0x12,0x2d,0x36,0x12,0xb6,0x75,0x2, 0xb8, +0xe, 0x7e,0xb3,0x3, 0xff,0xb4,0x5, 0x1a,0x12,0x2d,0x36,0x75,0xe9,0xff,0x22,0x7e, +0xb3,0x3, 0xff,0xb4,0x5, 0xc, 0x12,0x2d,0x36,0x2, 0xb8,0x8, 0x74,0x1, 0x7a,0xb3, +0x3, 0xff,0x22,0x7e,0xf, 0x39,0xc5,0x2e,0x14,0x0, 0xe, 0xb, 0xa, 0x30,0x22,0x7c, +0x6b,0xa9,0xd5,0xcb,0x74,0xf, 0x12,0x28,0xba,0x7a,0x61,0xfc,0x12,0x28,0xb3,0x12, +0xb7,0x2, 0xd2,0x0, 0x12,0xb6,0xee,0x12,0x2f,0xee,0x12,0x13,0xde,0x2, 0x13,0x96, +0x74,0x4, 0x7d,0x30,0x12,0x2f,0x58,0x74,0x14,0x7c,0xab,0x80,0xe, 0x7e,0x70,0x3, +0x80,0x1, 0x0, 0x7c,0x67,0x1b,0x70,0xa5,0xbe,0x0, 0xf7,0x7c,0x6a,0x1b,0xa0,0xa5, +0xbe,0x0, 0xea,0x22,0x74,0x2, 0x7d,0x3f,0x7d,0x23,0x7c,0x6b,0xa, 0x14,0x7c,0x73, +0x7d,0x52,0x7c,0xab,0x7e,0xb3,0x3a,0x10,0xb4,0xa5,0x3c,0x12,0x64,0x8d,0x75,0xb5, +0x1, 0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9, +0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3, +0x7a,0x71,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0xa1,0xb5,0xa9,0x36,0xb3, +0xfc,0xa9,0xc6,0xb3,0xa9,0xd2,0xb4,0x22,0xa9,0xc6,0xb3,0x75,0xb5,0x0, 0x22,0x12, +0xc7,0x9, 0xc2,0x0, 0x12,0xb6,0xf9,0xc2,0x2, 0x12,0x2f,0xde,0xc2,0x0, 0x12,0xb6, +0xee,0xa9,0xd5,0xcb,0x74,0xf, 0x12,0x0, 0x66,0x7a,0x1b,0xb0,0x74,0xf, 0x6c,0x77, +0x12,0x28,0xba,0xe5,0xfc,0x7a,0xb, 0xb0,0x43,0xfc,0x10,0x2, 0x28,0xb3,0xa9,0xd0, +0xce,0xa2,0x2, 0xa9,0x91,0xc9,0x22,0x7e,0x34,0x3, 0xe8,0x2, 0x23,0xcc,0xd2,0x2, +0x12,0x2f,0xde,0x74,0x1, 0x22,0x12,0xc6,0xd9,0xb4,0x1, 0x19,0xca,0x39,0x7e,0x18, +0x38,0xdd,0x7e,0x8, 0x25,0xee,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x1f,0x25,0xf2,0x7e, +0xf, 0x25,0xee,0x80,0x17,0xca,0x39,0x7e,0x18,0x38,0xdd,0x7e,0x8, 0x2b,0x70,0x12, +0x20,0xc3,0x1b,0xfd,0x7e,0x1f,0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x2, 0x30,0x2f,0x7a, +0x1f,0x2a,0xfc,0x7a,0xf, 0x2a,0xf8,0x22,0x7a,0xb3,0x2b,0x0, 0x70,0x19,0x7e,0x1f, +0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x12,0x30,0x2f,0x7e,0x18,0x6, 0x76,0x7a,0x1f,0x6, +0xf4,0x7e,0x18,0x4, 0x7e,0x80,0x15,0xb4,0x1, 0x16,0x7e,0x1f,0x25,0xf2,0x7e,0xf, +0x25,0xee,0x12,0x30,0x2f,0x12,0x5d,0xd5,0x7e,0x18,0x4, 0x0, 0x7a,0x1f,0x6, 0xf8, +0x22,0x74,0x1, 0x12,0x0, 0x1e,0xe4,0x12,0x30,0x38,0x12,0x30,0x89,0xe4,0x12,0x0, +0x1e,0x74,0x1, 0x12,0x30,0x38,0x2, 0x30,0x89,0xca,0x3b,0x7e,0xd3,0x2a,0x73,0x7e, +0xc3,0x2a,0x74,0x7e,0x8, 0x1f,0x44,0x12,0xb9,0xa7,0x7e,0x8, 0x1f,0x8a,0x7e,0x34, +0x0, 0x46,0x12,0x20,0xe8,0x7e,0x8, 0x1f,0xd0,0x7e,0x34,0x0, 0xa, 0xe4,0x12,0x20, +0xe8,0x7e,0x8, 0x1f,0xda,0x7e,0x34,0x0, 0xa, 0x12,0x20,0xe8,0x7e,0xf3,0x2a,0xfc, +0x7e,0x18,0x2a,0xdc,0x7a,0x1d,0x24,0x7e,0x18,0x1f,0xd0,0x7a,0x1d,0x28,0x7c,0xbd, +0x7c,0x7c,0x7e,0x8, 0x2a,0xb9,0x12,0x31,0xdf,0x6c,0xee,0x80,0x2b,0xa, 0x3e,0x9, +0xa3,0x2a,0xdc,0xa, 0x3a,0x2e,0x34,0x20,0x7d,0x12,0x88,0x5c,0x7c,0xab,0xbe,0xa0, +0x1c,0x50,0x13,0xa, 0x3e,0x12,0x31,0xa1,0xa, 0x4a,0x19,0xb4,0x1f,0x44,0x7e,0xb3, +0x2a,0xfb,0x19,0xb4,0x1f,0x8a,0xb, 0xe0,0xbc,0xce,0x38,0xd1,0x6c,0xee,0x80,0x24, +0xa, 0x3e,0x9, 0xa3,0x2a,0xb9,0xbe,0xa0,0x23,0x50,0x17,0xa, 0x2e,0xa, 0x3c,0x2d, +0x32,0x12,0x31,0xa1,0xa, 0x4a,0x19,0xb4,0x1f,0x60,0x7e,0xb3,0x2a,0xfb,0x19,0xb4, +0x1f,0xa6,0xb, 0xe0,0xbc,0xde,0x38,0xd8,0x7e,0xb3,0x2a,0xfd,0x7e,0x8, 0x1f,0xe4, +0x60,0x9, 0x7e,0x18,0x1f,0xd0,0x12,0x7e,0x45,0x80,0x3, 0x12,0xbb,0x3b,0x6c,0xee, +0x7e,0x18,0x1f,0xe4,0x7a,0x1f,0x1f,0x34,0x74,0x2, 0xac,0xbe,0x49,0x35,0x1f,0xd0, +0x7a,0x37,0x1f,0x38,0x74,0x2, 0xac,0xbe,0x49,0x35,0x1f,0xda,0x7a,0x37,0x1f,0x3a, +0x7e,0x70,0xe, 0xac,0x7e,0x2e,0x34,0x1f,0x44,0x6d,0x22,0x7a,0x1f,0x1f,0x3c,0x7e, +0x70,0xe, 0xac,0x7e,0x2e,0x34,0x1f,0x8a,0x7a,0x1f,0x1f,0x40,0x7e,0x8, 0x1f,0x34, +0x7c,0xbf,0x7c,0x7e,0x12,0x8, 0xd1,0xb, 0xe0,0xbe,0xe0,0x5, 0x40,0xb2,0xda,0x3b, +0x22,0x2e,0x37,0x2a,0xfe,0x7e,0x39,0xb0,0x22,0x74,0x1, 0x7a,0xb3,0x38,0x9, 0x12, +0x57,0xd5,0x12,0x13,0xf5,0x12,0xba,0xb3,0xe4,0x12,0xa, 0x66,0x7e,0x24,0x3, 0xd4, +0x12,0x3a,0xf8,0x74,0x1, 0x12,0x30,0x38,0x12,0xc6,0xf2,0x7e,0x34,0xd0,0xc, 0x12, +0x1, 0xe, 0x12,0x30,0x71,0x7e,0x34,0x0, 0x1, 0xe4,0x6c,0x55,0x2, 0x13,0x1, 0x7c, +0x57,0x7c,0xab,0x6c,0x77,0x80,0x4b,0xa, 0x47,0x7e,0x7d,0x24,0x2d,0xf4,0x7e,0x7b, +0x60,0xa, 0x46,0x2e,0x44,0x20,0x7d,0x12,0xc6,0xb6,0x7c,0x6b,0xbe,0x60,0xd, 0x38, +0x12,0x7e,0xd4,0x0, 0x1, 0x7c,0xb6,0x60,0x5, 0x3e,0xd4,0x14,0x78,0xfb,0x7e,0x7d, +0x28,0x80,0x15,0x9e,0x60,0xe, 0x7e,0xd4,0x0, 0x1, 0x7c,0xb6,0x60,0x5, 0x3e,0xd4, +0x14,0x78,0xfb,0x7e,0x7d,0x28,0xb, 0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40, +0xb, 0x70,0xbc,0x57,0x38,0xb1,0x6c,0x77,0x80,0x58,0xa, 0x27,0x7f,0x70,0x2d,0xf2, +0x7e,0x7b,0x60,0xbe,0x60,0xd, 0x38,0x11,0x12,0x32,0x97,0x60,0x5, 0x3e,0x44,0x14, +0x78,0xfb,0x7e,0x7d,0x28,0xb, 0xf6,0x80,0x2f,0xbe,0x60,0x1b,0x38,0x16,0x9e,0x60, +0xe, 0x12,0x32,0x97,0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb,0x7e,0x7d,0x28,0x2e,0xf4, +0x0, 0x6, 0x80,0x14,0x9e,0x60,0x1c,0x12,0x32,0x97,0x60,0x5, 0x3e,0x44,0x14,0x78, +0xfb,0x7e,0x7d,0x28,0x2e,0xf4,0x0, 0x8, 0xb, 0x7a,0x20,0x4d,0x24,0x1b,0x7a,0x20, +0xb, 0x70,0xbc,0xa7,0x38,0xa4,0x22,0x7e,0x44,0x0, 0x1, 0x7c,0xb6,0x22,0x7c,0x96, +0x7c,0xa7,0x12,0x30,0x38,0x7c,0xba,0x12,0x13,0xc7,0x74,0xa, 0x12,0x2f,0x39,0x7c, +0xb9,0x12,0x0, 0x1e,0x2, 0x32,0xb7,0xca,0x3b,0x7e,0xe3,0x2a,0x74,0x7e,0xf3,0x2a, +0xfa,0x74,0x1, 0x7a,0xb3,0x2a,0xfa,0x12,0x35,0xfd,0x12,0xc6,0xc8,0x12,0x25,0x89, +0x7e,0x17,0x2a,0xfe,0x6d,0x0, 0x12,0x20,0xe8,0x7e,0xd0,0x7, 0x12,0x2f,0xe7,0x6c, +0xcc,0x80,0x19,0x7e,0x34,0x0, 0x1, 0x7c,0xbd,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb, +0x7c,0x67,0x12,0x36,0x98,0x4c,0x76,0x7a,0x29,0x70,0xb, 0xc0,0x12,0x34,0x64,0xa, +0x3c,0xbd,0x32,0x48,0xde,0x12,0x34,0x73,0x30,0x1d,0xfd,0x12,0xc6,0xac,0x7e,0xb3, +0x2a,0x73,0x7c,0x7e,0x12,0x37,0x66,0x6c,0xcc,0x80,0x29,0x74,0x2, 0xac,0xbc,0x49, +0x35,0x6, 0xfc,0xbe,0x34,0x15,0x40,0x50,0x19,0x7e,0x34,0x0, 0x1, 0x7c,0xbd,0x60, +0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7c,0xb7,0x64,0xff,0x12,0x36,0x98,0x5c,0x7b,0x7a, +0x29,0x70,0xb, 0xc0,0x12,0x34,0x64,0xa, 0x3c,0xbd,0x32,0x48,0xce,0x1b,0xd0,0xbe, +0xd0,0x0, 0x58,0x88,0x12,0x33,0xe6,0x74,0x2, 0x12,0xc6,0xe2,0x12,0x33,0x6e,0x74, +0x2, 0x12,0x0, 0x1e,0x7a,0xf3,0x2a,0xfa,0x12,0x35,0xfd,0xda,0x3b,0x22,0xca,0x79, +0x7c,0xfb,0x7e,0x8, 0x24,0xf2,0x12,0xb9,0xa7,0x7e,0xa3,0x2a,0x73,0x7e,0x73,0x2a, +0x74,0x6c,0xee,0x80,0x1d,0xa, 0x2e,0x9, 0x62,0x2a,0xdc,0xa, 0x26,0x12,0x67,0x43, +0x7c,0x6b,0xbe,0x60,0x1c,0x50,0x9, 0xa, 0x2e,0x12,0x36,0x8e,0x19,0xb2,0x24,0xf2, +0xb, 0xe0,0xbc,0x7e,0x38,0xdf,0x6c,0xee,0x80,0x1a,0xa, 0x2e,0x9, 0x62,0x2a,0xb9, +0xbe,0x60,0x23,0x50,0xd, 0xa, 0x1e,0xa, 0x27,0x2d,0x21,0x12,0x36,0x8e,0x19,0xb2, +0x25,0xe, 0xb, 0xe0,0xbc,0xae,0x38,0xe2,0x6c,0xee,0x7e,0x30,0xe, 0xac,0x3e,0x2e, +0x14,0x24,0xf2,0x6d,0x0, 0x7c,0xbf,0x7c,0x7e,0x12,0x11,0xba,0xb, 0xe0,0xbe,0xe0, +0x5, 0x40,0xe7,0xda,0x79,0x22,0xca,0xd8,0xca,0x79,0x7e,0xf0,0xa, 0x74,0x1, 0x7a, +0xb3,0x2a,0xfa,0x12,0x25,0x89,0x7c,0xe7,0x80,0x5d,0x12,0x2f,0xe7,0x12,0x34,0x73, +0x30,0x1d,0xfd,0x12,0xc6,0xac,0x12,0x37,0x5e,0x6c,0xdd,0x80,0x3d,0x7e,0x50,0x2, +0xac,0x5d,0x49,0x32,0x6, 0xfc,0xbe,0x34,0x14,0x78,0x50,0x14,0xa, 0x1d,0x2e,0x17, +0x2a,0xfe,0x7e,0x19,0xb0,0xbe,0xb0,0x0, 0x28,0x1e,0x14,0x7a,0x19,0xb0,0x80,0x18, +0xbe,0x34,0x19,0x28,0x28,0x10,0xa, 0x3d,0x12,0x31,0xa1,0xbe,0xb0,0xff,0x68,0x8, +0x4, 0x7a,0x39,0xb0,0x80,0x2, 0x1b,0xe0,0xb, 0xd0,0x12,0x34,0x64,0xa, 0x3d,0xbd, +0x32,0x48,0xba,0x4c,0xee,0x68,0x8, 0x7c,0xaf,0x1b,0xf0,0x4c,0xaa,0x78,0x9b,0xda, +0x79,0xda,0xd8,0x22,0x7e,0x73,0x2a,0x74,0xa, 0x37,0x7e,0x53,0x2a,0x73,0xa, 0x25, +0x2d,0x23,0x22,0x74,0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0xfc,0x12,0x33,0x6e,0x74, +0x2, 0x12,0x0, 0x1e,0x74,0x5, 0x7e,0x70,0x9b,0x12,0x13,0x2c,0x12,0x34,0x96,0x7e, +0xb3,0x2a,0xfc,0x2, 0xe, 0x94,0x6c,0xaa,0x80,0x22,0xa, 0x3a,0x9, 0x73,0x2a,0xdc, +0x2e,0x34,0x20,0x7d,0x12,0x88,0x5c,0x7c,0x7b,0xa, 0x47,0x7e,0x50,0x2, 0xac,0x5a, +0x7e,0xf, 0x39,0xc1,0x2d,0x12,0x79,0x40,0x0, 0x48,0xb, 0xa0,0x7e,0x63,0x2a,0x74, +0xbc,0x6a,0x38,0xd6,0x22,0xca,0x3b,0x7e,0xb3,0x38,0x7, 0xb4,0x1, 0x2, 0x80,0x2, +0xa1,0xfa,0x6c,0xcc,0x6c,0xdd,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x8, 0x7e,0xe0,0x10, +0x7e,0xf0,0x32,0x80,0x6, 0x7e,0xe0,0xa, 0x7e,0xf0,0x1e,0x12,0x87,0xf3,0x7d,0xf3, +0x12,0x69,0x78,0x50,0xfb,0x74,0x1, 0x7a,0xb3,0x39,0x87,0x12,0x30,0x38,0x12,0x13, +0xc7,0x12,0x0, 0x1e,0x74,0xa, 0x12,0x2f,0x39,0x12,0xc6,0xc8,0x7e,0xe7,0x2b,0xd, +0x7a,0xe5,0x25,0x7e,0xb3,0x2a,0xfa,0xf5,0x24,0x74,0x4, 0x7a,0xb3,0x2a,0xfa,0x7e, +0xe7,0x2b,0xd, 0x5e,0xe4,0x0, 0x3f,0x7a,0xe7,0x2b,0xd, 0x7e,0xb3,0x2a,0xfa,0x12, +0xba,0x42,0x7c,0x7b,0x74,0x6, 0xac,0x7b,0x7e,0x24,0x0, 0x4, 0x12,0x1e,0xb9,0x7d, +0x23,0x7d,0x3f,0x12,0x7e,0x3c,0xad,0x32,0x7a,0x37,0x2b,0x7, 0x12,0x35,0xfd,0x12, +0x8f,0xf5,0xa1,0xdb,0x12,0x2f,0xe7,0x30,0x11,0x2, 0xa1,0xe1,0x7c,0xbe,0x12,0x88, +0x4c,0x12,0x34,0x84,0x80,0xf, 0x80,0x7, 0x12,0x37,0x6e,0xe4,0x12,0x49,0xe7,0x20, +0x93,0xf6,0x12,0x37,0xb7,0x30,0x1d,0xf7,0x30,0x1c,0xf4,0xd2,0x1, 0x12,0x37,0xa6, +0xe4,0x12,0x13,0xde,0xb, 0xc0,0x12,0x83,0xf3,0x12,0x90,0x3d,0x7e,0xa3,0x39,0x86, +0x4c,0xaa,0x78,0x6, 0x74,0x1, 0x7a,0xb3,0x39,0x87,0x4c,0xaa,0x68,0xb, 0x7e,0xb3, +0x38,0x32,0x70,0x5, 0xe4,0x7a,0xb3,0x39,0x86,0x12,0x36,0xa2,0x78,0x18,0x7e,0xb3, +0x39,0x86,0x60,0x12,0xe4,0x7a,0xb3,0x39,0x86,0x7a,0xb3,0x2a,0x2, 0x7a,0xb3,0x2a, +0x3, 0x7e,0xd0,0x1, 0x80,0x1b,0x12,0x36,0xa2,0x68,0x10,0x7e,0xb3,0x39,0x86,0x70, +0xa, 0x7e,0xd0,0x1, 0xe4,0x7a,0xb3,0x38,0x7, 0x80,0x6, 0xbc,0xfc,0x28,0x2, 0xa1, +0x54,0xe4,0x7a,0xb3,0x2b,0x4, 0x7e,0x35,0x25,0x7a,0x37,0x2b,0xd, 0xe5,0x24,0x7a, +0xb3,0x2a,0xfa,0x4c,0xdd,0x68,0x3, 0x12,0x24,0x36,0xda,0x3b,0x22,0x7e,0x8, 0x2a, +0x6d,0x2, 0x5, 0xb4,0x7e,0xd7,0x2b,0xd, 0xbe,0xb0,0x1, 0x28,0x2, 0xe4,0x22,0x12, +0x65,0x47,0x12,0x35,0xfd,0x7a,0xd7,0x2b,0xd, 0x7e,0x73,0x2a,0xfa,0x12,0x46,0xb2, +0xe4,0x7e,0x50,0x1, 0x12,0x13,0x1, 0x12,0x34,0x84,0x74,0x1, 0x22,0xe5,0xd, 0x60, +0x5c,0xe5,0xd, 0x30,0xe0,0x6, 0x53,0xd, 0xfe,0x12,0x35,0xfd,0xe5,0xd, 0x30,0xe1, +0x14,0x53,0xd, 0xfd,0x7e,0xb3,0x38,0xe1,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x12, +0xc6,0xe2,0x12,0xb9,0x31,0xe5,0xd, 0x30,0xe2,0x33,0x53,0xd, 0xfb,0xe4,0x7a,0xb3, +0x38,0xe2,0x7e,0xb3,0x38,0xe1,0x70,0xf, 0x74,0x1, 0x12,0x0, 0x1e,0x7e,0x1f,0x2b, +0x74,0x7e,0xf, 0x2b,0x70,0x80,0xc, 0xe4,0x12,0x0, 0x1e,0x7e,0x1f,0x25,0xf2,0x7e, +0xf, 0x25,0xee,0x12,0x30,0x2f,0x7e,0xb3,0x2a,0xfc,0x2, 0x33,0x6e,0x22,0x2e,0x27, +0x2a,0xfe,0x7e,0x29,0xb0,0xa, 0x26,0x22,0xa, 0x2c,0x2e,0x27,0x2a,0xfe,0x7e,0x29, +0x70,0x22,0x7e,0x73,0x39,0xf3,0xa, 0x37,0x5e,0x34,0x0, 0x2, 0x22,0x7e,0xb3,0x2b, +0x2, 0x70,0x41,0x12,0x69,0x78,0x50,0xfb,0xe4,0x6c,0x77,0x6c,0x66,0x12,0x32,0x9e, +0x7e,0x8, 0x6, 0xfc,0x7e,0x1f,0x6, 0xf4,0x7e,0xb3,0x2b,0x72,0x12,0x36,0xf5,0x74, +0x1, 0x7e,0x70,0x1, 0x7e,0x60,0x1, 0x12,0x32,0x9e,0x7e,0x8, 0x7, 0x7a,0x7e,0x1f, +0x6, 0xf4,0x7e,0xb3,0x25,0xf0,0x12,0x36,0xf5,0x74,0x2, 0x7a,0xb3,0x2b,0x2, 0xe4, +0x7a,0xb3,0x16,0x90,0x22,0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f,0x51,0x7f,0x40,0x7f, +0x15,0x12,0x65,0x54,0x12,0xc6,0xf2,0x7e,0xe0,0x1, 0x12,0x34,0x84,0x30,0x1d,0xfd, +0x74,0x2, 0x12,0x0, 0x1e,0x7f,0x4, 0x12,0x37,0x5e,0x6c,0xdd,0x80,0x18,0x74,0x2, +0xac,0xbd,0x7f,0x14,0x2d,0x35,0xb, 0x1a,0x20,0x74,0x2, 0xac,0xbd,0x7f,0x5, 0x2d, +0x15,0x12,0xc6,0xbf,0xb, 0xd0,0x7e,0x73,0x2a,0x74,0xa, 0x7, 0x7e,0x63,0x2a,0x73, +0xa, 0x16,0x2d,0x10,0xa, 0x2d,0xbd,0x21,0x48,0xd4,0x1b,0xe0,0x78,0xbc,0x7f,0x5, +0x7c,0xbf,0x2e,0x73,0x2a,0x73,0x12,0xb9,0xb0,0xda,0x79,0xda,0xd8,0x22,0x7e,0xb3, +0x2a,0x73,0x7e,0x73,0x2a,0x74,0x12,0x10,0xee,0x74,0x2, 0x2, 0x0, 0x1e,0x74,0x81, +0x7a,0xb3,0x3a,0x3, 0x22,0x80,0x1d,0x12,0x37,0x6e,0x12,0x49,0x8a,0x68,0x5, 0xc2, +0x1, 0x12,0x37,0xa6,0x7e,0xb3,0x34,0x3a,0xbe,0xb0,0x2, 0x68,0x18,0x20,0x1c,0x15, +0xe4,0x12,0x49,0xe7,0x20,0x93,0xe0,0x12,0x37,0x6e,0xa9,0xd1,0xcd,0xa9,0xc5,0xea, +0x74,0x2, 0x2, 0x49,0xe7,0x22,0x30,0x1, 0x6, 0x12,0x2f,0xee,0x2, 0x13,0x96,0x12, +0xc7,0x9, 0xc2,0x2, 0x2, 0x2f,0xde,0x30,0x1d,0x5, 0xc2,0x1, 0x12,0x37,0xa6,0xa9, +0xd1,0xcd,0xa9,0xc5,0xea,0x30,0x1c,0x3, 0x20,0x1d,0x14,0x12,0x37,0x6e,0xa9,0xd0, +0xce,0xa9,0xc4,0xc9,0x74,0x2, 0x12,0x49,0xe7,0xa9,0xd0,0xce,0xa9,0xd4,0xc9,0xa9, +0xc1,0xcd,0xd2,0x1, 0x2, 0x37,0xa6,0xca,0xf8,0x7c,0x6b,0xa5,0xbe,0x0, 0xa, 0x7c, +0xb7,0x12,0x68,0x27,0xd2,0x8, 0x2, 0x3a,0x6a,0xa5,0xbe,0x1, 0x3d,0x7a,0x73,0x38, +0x9e,0xa5,0xbf,0xad,0x2, 0x80,0x2f,0xa5,0xbf,0xae,0x4, 0xd2,0x9, 0x41,0x6a,0xa5, +0xbf,0xaa,0x5, 0x12,0x3a,0xef,0x80,0x1e,0xa5,0xbf,0xab,0xa, 0x7e,0x34,0x5, 0x7a, +0x7a,0x37,0x32,0xe3,0x80,0x10,0xa5,0xbf,0xac,0x2, 0x80,0x2, 0x41,0x6a,0x7e,0x34, +0x4, 0xfc,0x7a,0x37,0x32,0xe3,0x6d,0x33,0x1, 0xe6,0xbe,0x60,0x4, 0x40,0x20,0xbe, +0x60,0x8, 0x38,0x1b,0x12,0x3a,0x6d,0xa5,0xbe,0x7, 0x7, 0x6d,0x33,0x7a,0x35,0xa, +0x41,0x6a,0xa5,0xbe,0x8, 0x2, 0x80,0x2, 0x41,0x6a,0x12,0x7, 0xfb,0x41,0x6a,0xa5, +0xbe,0xa, 0x9, 0x43,0xc, 0x20,0x7a,0x73,0x38,0xa7,0x41,0x6a,0xa5,0xbe,0xb, 0x8, +0x12,0x3a,0x6d,0x12,0x3a,0xba,0x41,0x6a,0xbe,0x60,0x1b,0x40,0x7, 0xbe,0x60,0x1c, +0x38,0x2, 0x41,0x2, 0xbe,0x60,0x1e,0x40,0xd, 0xbe,0x60,0x23,0x38,0x8, 0x12,0x3a, +0x6f,0x43,0xc, 0x40,0x41,0x6a,0xbe,0x60,0x15,0x40,0x1a,0xbe,0x60,0x18,0x38,0x15, +0x12,0x3a,0x6f,0xd2,0x8, 0xa5,0xbe,0x15,0x2, 0x80,0x2, 0x41,0x6a,0x74,0x7, 0x7a, +0xb3,0x38,0xa1,0x41,0x6a,0xa5,0xbe,0x19,0x7, 0xe4,0x7a,0xb3,0x38,0xb6,0x41,0x6a, +0xbe,0x60,0x24,0x40,0x7, 0xbe,0x60,0x2c,0x38,0x2, 0x41,0x2, 0xa5,0xbe,0x2d,0x1b, +0x12,0x3a,0x6f,0x20,0x9, 0x2, 0x41,0x6a,0x7e,0x63,0x38,0xc9,0x7c,0x46,0x6c,0x55, +0xa, 0x37,0x2d,0x32,0x3e,0x34,0x7a,0x35,0x8, 0x41,0x6a,0xbe,0x60,0x2f,0x40,0xa, +0xbe,0x60,0x33,0x38,0x5, 0x43,0xc, 0x8, 0x41,0x2, 0xa5,0xbe,0x34,0xf, 0x43,0xc, +0x10,0xbe,0x70,0x64,0x38,0x2, 0x41,0x2, 0x7e,0x70,0x64,0x41,0x2, 0xbe,0x60,0x38, +0x68,0x4, 0xa5,0xbe,0x39,0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x38,0xc2,0x7c,0xbf,0x4, +0x7a,0xb3,0x38,0xc2,0xa, 0x2f,0x19,0x72,0x2b,0x21,0xa5,0xbe,0x39,0x2, 0x80,0x2, +0x41,0x6a,0x75,0x1a,0x38,0x41,0x6a,0xbe,0x60,0x3a,0x68,0x4, 0xa5,0xbe,0x3b,0x21, +0x43,0xc, 0x2, 0x7e,0xf3,0x38,0xc4,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc4,0xa, 0x2f, +0x19,0x72,0x2b,0x44,0xa5,0xbe,0x3b,0x2, 0x80,0x2, 0x41,0x6a,0x75,0x1a,0x3a,0x41, +0x6a,0xa5,0xbe,0xfb,0x9, 0x43,0xc, 0x4, 0x7a,0x73,0x2b,0x12,0x41,0x6a,0xa5,0xbe, +0x50,0x6, 0x7a,0x73,0x38,0xed,0x41,0x6a,0xbe,0x60,0x3c,0x68,0x4, 0xa5,0xbe,0x3d, +0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x38,0xc6,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc6,0xa, +0x2f,0x19,0x72,0x2a,0x7a,0xa5,0xbe,0x3d,0x2, 0x80,0x2, 0x41,0x6a,0x75,0x1a,0x3c, +0x41,0x6a,0xbe,0x60,0x3e,0x68,0x4, 0xa5,0xbe,0x3f,0x21,0x43,0xc, 0x1, 0x7e,0xf3, +0x38,0xc8,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc8,0xa, 0x2f,0x19,0x72,0x2a,0x9d,0xa5, +0xbe,0x3f,0x2, 0x80,0x2, 0x41,0x6a,0x75,0x1a,0x3e,0x41,0x6a,0xbe,0x60,0x40,0x40, +0xd, 0xbe,0x60,0x42,0x38,0x8, 0x12,0x3a,0x6f,0x75,0xd, 0x1, 0x80,0xa, 0xa5,0xbe, +0x43,0xb, 0x12,0x3a,0x6f,0x75,0xd, 0x2, 0x12,0x2f,0xf6,0x80,0x7d,0xa5,0xbe,0x44, +0x8, 0x12,0x3a,0x6f,0x12,0x3a,0x76,0x80,0x71,0xbe,0x60,0x45,0x68,0x4, 0xa5,0xbe, +0x46,0x5, 0x12,0x3a,0x6f,0x80,0x63,0xbe,0x60,0x4e,0x68,0x4, 0xa5,0xbe,0x4f,0x20, +0x43,0xd, 0x4, 0x7e,0xf3,0x38,0xe3,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xe3,0xa, 0x2f, +0x2e,0x27,0x32,0xe1,0x7a,0x29,0x70,0xa5,0xbe,0x4f,0x3f,0x75,0x1a,0x4e,0x80,0x3a, +0xa5,0xbe,0x6d,0x5, 0x7a,0x71,0xe, 0x80,0x31,0xbe,0x60,0xf0,0x40,0x25,0xbe,0x60, +0xf3,0x38,0x20,0x7c,0x16,0x2e,0x10,0x20,0x7c,0xb7,0xa5,0xf7,0xa5,0xbe,0xf3,0x1a, +0x7e,0x15,0x12,0x7e,0x5, 0x10,0x3e,0x4, 0x7e,0x1f,0x32,0xe5,0x2d,0x30,0x1b,0x1a, +0x10,0x80,0x7, 0xa5,0xbe,0xf6,0x3, 0x7a,0x71,0xf, 0xda,0xf8,0x22,0xd2,0x8, 0xa, +0x26,0x19,0x72,0x38,0x9d,0x22,0x12,0xc6,0xd9,0xb4,0x1, 0x1c,0xca,0x39,0x7e,0x18, +0x25,0xee,0x7e,0x8, 0x38,0xdd,0x12,0x20,0xc3,0x1b,0xfd,0x12,0x3a,0xbd,0x7e,0x1f, +0x25,0xf2,0x7e,0xf, 0x25,0xee,0x80,0x1f,0xca,0x39,0x7e,0x18,0x2b,0x70,0x7e,0x8, +0x38,0xdd,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x37,0x2b,0x76,0x7a,0x37,0x32,0xe1,0x7e, +0x1f,0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x2, 0x30,0x2f,0xb2,0x82,0x22,0x7e,0x37,0x25, +0xf4,0x7a,0x37,0x32,0xe1,0x22,0x12,0x3a,0xef,0x12,0x3a,0xbd,0x6d,0x33,0x7a,0x35, +0xa, 0x12,0x3b,0x25,0x12,0x3a,0xff,0x74,0x50,0x7a,0xb3,0x38,0xd1,0x7e,0x24,0x3, +0x20,0x12,0x3a,0xf8,0xe4,0x12,0xc6,0x70,0x6d,0x33,0x7a,0x37,0x3a,0x5, 0x22,0x7e, +0x34,0xd, 0xc8,0x7a,0x37,0x32,0xe3,0x22,0x7d,0x32,0x74,0xfa,0x2, 0x12,0xd0,0x7e, +0x73,0x2b,0x62,0x7a,0x73,0x38,0xd0,0x22,0xa2,0xe, 0xe4,0x33,0x7a,0xb3,0x38,0xcb, +0x7e,0x73,0x38,0xcf,0xbe,0x73,0x2b,0xf, 0x68,0xa, 0xe5,0xc, 0x70,0x6, 0x12,0x3b, +0x25,0x12,0x3a,0xff,0x22,0x7e,0x73,0x2b,0xf, 0x7a,0x73,0x38,0xcf,0x7e,0x73,0x2b, +0x1f,0x7a,0x73,0x38,0xbf,0x7e,0x73,0x2b,0x20,0x7a,0x73,0x38,0xbe,0x7e,0x73,0x2b, +0x14,0x7a,0x73,0x38,0xc0,0x22,0xca,0xd8,0xca,0x79,0x7c,0xdb,0x7e,0xa0,0x4, 0xbe, +0xd0,0x80,0x78,0x18,0x7e,0xe0,0xff,0x6c,0xff,0x80,0xb, 0x12,0x3b,0xae,0x38,0x4, +0x7c,0xeb,0x7c,0xdf,0xb, 0xf0,0xbc,0xaf,0x38,0xf1,0x80,0x1a,0xbe,0xd0,0x81,0x78, +0x15,0x6c,0xee,0x6c,0xff,0x80,0xb, 0x12,0x3b,0xae,0x40,0x4, 0x7c,0xeb,0x7c,0xdf, +0xb, 0xf0,0xbc,0xaf,0x38,0xf1,0xbc,0xad,0x38,0x2, 0x6c,0xdd,0x7c,0xbd,0x12,0x51, +0x89,0x12,0x3b,0x3d,0x12,0x3f,0x95,0x12,0x3b,0xca,0x7e,0x73,0x2b,0xf, 0x7a,0x73, +0x38,0xcf,0x12,0x3a,0xff,0x7a,0xd3,0x38,0xa7,0xda,0x79,0xda,0xd8,0x22,0x7e,0x90, +0x5, 0xac,0x9f,0x9, 0xb4,0x26,0x33,0xbc,0xbe,0x22,0x30,0x0, 0x3, 0x12,0x3b,0x3d, +0xa2,0x1, 0x92,0x2, 0x12,0x3c,0x88,0x2, 0x3b,0xca,0x7e,0x73,0x2b,0x20,0x7a,0x73, +0x38,0xbe,0x22,0x74,0x40,0x7a,0xb3,0x2b,0x20,0x12,0x57,0x8e,0x50,0x9, 0xd2,0x0, +0xd2,0x1, 0x12,0x3b,0xba,0x80,0x1c,0x74,0x1, 0x12,0x3c,0xc, 0x7e,0x43,0x38,0xbc, +0x7e,0x50,0x64,0xac,0x45,0x12,0x80,0x27,0x7a,0xb3,0x2b,0x1f,0x7e,0xf, 0x39,0xda, +0x12,0x3e,0xfb,0x12,0x3b,0xca,0x12,0x3f,0x95,0x2, 0x3b,0x3d,0xca,0x3b,0x7c,0xdb, +0xe4,0x7a,0xb3,0x2b,0x14,0x12,0x3f,0xeb,0x7e,0xc0,0xa, 0x12,0x3f,0xa5,0x30,0xf, +0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x1f,0x39,0xda,0x12,0x83,0x93,0x7d,0x73,0xbe, +0x74,0xff,0xff,0x78,0x9, 0x12,0x3c,0x7c,0x2e,0x34,0x0, 0x3, 0x80,0x18,0xbe,0x74, +0x80,0x0, 0x28,0x7, 0x12,0x3c,0x7c,0xb, 0x35,0x80,0xb, 0xbe,0x74,0x40,0x0, 0x28, +0xc, 0x12,0x3c,0x7c,0xb, 0x34,0x1b,0xa, 0x30,0x1b,0xc0,0x78,0xbe,0xbe,0xd0,0x1, +0x78,0x9, 0x7e,0x1f,0x39,0xda,0x12,0x80,0x46,0x7d,0x73,0x7e,0x1f,0x39,0xc9,0x69, +0x31,0x0, 0x1a,0x7a,0x73,0x2b,0x14,0x7d,0x37,0xda,0x3b,0x22,0x7e,0xf, 0x39,0xc9, +0x2e,0x14,0x0, 0x1a,0xb, 0xa, 0x30,0x22,0xca,0x3b,0x7e,0x34,0xff,0xff,0x7a,0x35, +0x34,0x7e,0xb3,0x38,0xb2,0xf5,0x29,0x7e,0xb3,0x2a,0x6d,0xf5,0x2a,0x7e,0xb3,0x2a, +0x6e,0xf5,0x2b,0x7e,0xb3,0x2a,0x70,0xf5,0x2c,0x7e,0xb3,0x2a,0x6f,0xf5,0x2d,0x7e, +0x34,0x27,0x10,0x7a,0x35,0x2e,0x7e,0x18,0x40,0x0, 0x7a,0x1d,0x30,0x12,0x3f,0x9e, +0x30,0xf, 0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x8, 0x34,0x0, 0x12,0x3f,0xf2,0x6c, +0xff,0x80,0x34,0x9f,0x77,0x6c,0xee,0x80,0x19,0x7e,0x11,0x2b,0xac,0x1e,0x3e,0x4, +0x7e,0x30,0x2, 0xac,0x3f,0x2d,0x10,0x7e,0x1d,0x30,0x2d,0x31,0xb, 0x1a,0x30,0x12, +0x3e,0xf4,0xe5,0x2d,0xbc,0xbe,0x38,0xe1,0xe5,0x2d,0x12,0x3f,0x6b,0x74,0x2, 0xac, +0xbf,0x59,0x35,0x34,0x0, 0xb, 0xf0,0xe5,0x2c,0xbc,0xbf,0x38,0xc6,0x7e,0x34,0x10, +0x0, 0x7e,0xa1,0x2b,0x74,0x2, 0xa4,0x59,0x35,0x33,0xfe,0x6c,0xff,0x80,0x72,0x9f, +0x77,0x6c,0xee,0x80,0x12,0x12,0xc6,0x47,0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60, +0x80,0x14,0x78,0xf4,0x12,0x3e,0xf4,0xe5,0x29,0xbc,0xbe,0x38,0xe8,0xe5,0x29,0x12, +0x3f,0x6b,0x74,0x4, 0xac,0xbf,0x59,0x35,0x3, 0x70,0xe5,0x29,0xbe,0xb1,0x2c,0x50, +0x32,0x9f,0x77,0x7e,0xe1,0x29,0x80,0x12,0x12,0xc6,0x47,0x1e,0x34,0x1e,0x24,0x50, +0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x12,0x3e,0xf4,0xe5,0x2c,0xbc,0xbe,0x38,0xe8, +0xe5,0x29,0xa, 0x3b,0x6d,0x22,0xe5,0x2c,0xa, 0x1b,0x6d,0x0, 0x9f,0x1, 0x12,0x3f, +0x6f,0x80,0x4, 0x7e,0x34,0x10,0x0, 0x74,0x4, 0xac,0xbf,0x59,0x35,0x3, 0x72,0xb, +0xf0,0xe5,0x2d,0xbc,0xbf,0x38,0x88,0xe5,0x2c,0xa, 0x1b,0x6d,0x0, 0x7e,0x78,0x0, +0xcc,0x12,0x3f,0x8d,0x80,0x2e,0x74,0x2, 0xac,0xbf,0x49,0x25,0x34,0x0, 0xa, 0x5f, +0xad,0x53,0x7e,0x14,0x10,0x0, 0x9d,0x15,0xad,0x12,0x74,0xc, 0x1e,0x14,0x1e,0x4, +0x50,0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4,0x7d,0x21,0x74,0x2, 0xac,0xbf,0x59,0x25, +0x34,0x0, 0xb, 0xf0,0xe5,0x2c,0xbc,0xbf,0x38,0xcc,0xe5,0x2a,0xa, 0x1b,0x6d,0x0, +0x12,0x3f,0x8d,0x80,0x5c,0x74,0x4, 0xac,0xbf,0x49,0x25,0x3, 0x70,0xa, 0x1f,0xad, +0x13,0x7e,0xf4,0x10,0x0, 0x9d,0xf1,0xad,0xf2,0x74,0xc, 0x1e,0xf4,0x1e,0xe4,0x50, +0x4, 0x4e,0xf4,0x80,0x0, 0x14,0x78,0xf3,0x7d,0x2f,0x74,0x4, 0xac,0xbf,0x59,0x25, +0x3, 0x70,0xe5,0x29,0xbe,0xb1,0x2c,0x50,0x26,0x74,0x4, 0xac,0xbf,0x49,0x25,0x3, +0x72,0x2e,0x14,0x10,0x0, 0xad,0x12,0x74,0xc, 0x1e,0x14,0x1e,0x4, 0x50,0x3, 0x4e, +0x20,0x80,0x14,0x78,0xf4,0x7d,0x21,0x74,0x4, 0xac,0xbf,0x59,0x25,0x3, 0x72,0xb, +0xf0,0xe5,0x2a,0xbc,0xbf,0x38,0x9e,0x7e,0x73,0x38,0xb4,0xa, 0x37,0x6d,0x22,0x74, +0xc, 0x2f,0x11,0x14,0x78,0xfb,0x7e,0xf4,0x0, 0x64,0x7d,0x1f,0x12,0x1f,0x5, 0x7d, +0xe3,0x7a,0xe5,0x34,0x7e,0x73,0x38,0xb5,0xa, 0x37,0x6d,0x22,0x74,0xc, 0x2f,0x11, +0x14,0x78,0xfb,0x7d,0x1f,0x12,0x1f,0x5, 0x7d,0x63,0x6c,0xff,0x80,0x20,0x74,0x2, +0xac,0xbf,0x49,0x45,0x34,0x0, 0xbe,0x45,0x34,0x28,0x9, 0x7e,0x35,0x34,0x59,0x35, +0x34,0x0, 0x80,0x8, 0xbd,0x46,0x50,0x4, 0x59,0x65,0x34,0x0, 0xb, 0xf0,0xe5,0x2c, +0xbc,0xbf,0x38,0xda,0x6c,0xff,0x80,0x3a,0x74,0x4, 0xac,0xbf,0x49,0x45,0x3, 0x70, +0xbe,0x45,0x34,0x28,0x9, 0x7e,0x35,0x34,0x59,0x35,0x3, 0x70,0x80,0x8, 0xbd,0x46, +0x50,0x4, 0x59,0x65,0x3, 0x70,0x49,0x45,0x3, 0x72,0xbe,0x45,0x34,0x28,0x9, 0x7e, +0x35,0x34,0x59,0x35,0x3, 0x72,0x80,0x8, 0xbd,0x46,0x50,0x4, 0x59,0x65,0x3, 0x72, +0xb, 0xf0,0xe5,0x2a,0xbc,0xbf,0x38,0xc0,0x30,0x2, 0x6, 0x7e,0xd, 0x30,0x12,0x3e, +0xfb,0xda,0x3b,0x22,0x6d,0x22,0x2f,0x71,0xb, 0xe0,0x22,0x12,0x3f,0x5, 0xb, 0x34, +0x7a,0x73,0x2b,0x20,0x22,0xca,0x79,0x7f,0x10,0x9f,0x0, 0x6c,0xaa,0xa, 0x4a,0x2e, +0x44,0x60,0xac,0x12,0xc6,0xb6,0x7c,0x9b,0x7e,0xf3,0x2a,0x6e,0xac,0xf9,0x7e,0xb3, +0x2a,0x70,0xa, 0xfb,0x2d,0xf7,0x7d,0xef,0x3e,0xe4,0x7f,0x61,0x2d,0xde,0xb, 0x6a, +0xd0,0x6d,0xcc,0x2f,0x6, 0xb, 0xa0,0xbe,0xa0,0x3, 0x78,0xd1,0xbe,0x8, 0x0, 0x0, +0x78,0x2, 0xb, 0xc, 0x7e,0x54,0x0, 0x3, 0x7f,0x10,0x7d,0x15,0x12,0x1f,0x5, 0x7f, +0x1, 0xb, 0xc, 0x7e,0x34,0xc4,0x0, 0x7e,0x24,0x0, 0x9, 0x12,0x1f,0x7, 0xbe,0x34, +0x0, 0xfa,0x28,0x4, 0x7e,0x34,0x0, 0xfa,0xda,0x79,0x22,0xa, 0x1b,0x6d,0x0, 0x7f, +0x17,0x12,0x1f,0x7, 0x7f,0x71,0x7e,0x25,0x2e,0x74,0xc, 0x7d,0x13,0x7d,0x32,0x6d, +0x22,0x60,0x5, 0x2f,0x11,0x14,0x78,0xfb,0xb, 0x14,0x2, 0x1f,0x5, 0x7f,0x17,0x12, +0x1f,0x7, 0x6c,0xff,0x22,0x7e,0x73,0x2b,0x1f,0x7a,0x73,0x38,0xbf,0x22,0x7e,0x8, +0x2a,0x6d,0x12,0xd, 0x72,0xe4,0x12,0x0, 0xe, 0x74,0x1, 0x7e,0x70,0x99,0x12,0x13, +0x2c,0x2, 0x0, 0x4e,0xb4,0x3, 0x5, 0x12,0x3f,0xc4,0x80,0x2, 0xe4,0x22,0x12,0x3f, +0xa9,0x74,0x1, 0x22,0x12,0xc6,0xa3,0xe4,0x12,0x0, 0xe, 0x7e,0x8, 0x2a,0x6d,0x2, +0xd, 0x72,0x12,0x69,0x6f,0x38,0x2, 0xe4,0x22,0x12,0x69,0x67,0x49,0x55,0x34,0x3b, +0xbe,0xb0,0x2, 0x38,0x3, 0x2, 0x36,0x4, 0x2, 0x3f,0xb4,0x7e,0x8, 0x2a,0x6d,0x2, +0xd, 0x72,0x7e,0x34,0x0, 0x38,0xe4,0x2, 0x20,0xe8,0xca,0xd8,0xca,0x79,0x7e,0x73, +0x2a,0x6e,0x7e,0xf3,0x2a,0x6d,0xac,0xf7,0x7d,0x37,0x3e,0x34,0x7e,0x8, 0x1f,0x34, +0xe4,0x12,0x20,0xe8,0x7e,0xb3,0x38,0xb8,0xb4,0x1, 0x64,0x7e,0x73,0x38,0xb9,0xbe, +0x70,0x0, 0x28,0x5b,0x6c,0xdd,0x80,0x3c,0x12,0x2f,0xe7,0x12,0x24,0x8a,0x6d,0x33, +0x80,0x28,0x7e,0x35,0x24,0x3e,0x34,0x49,0x33,0xd, 0xc8,0x12,0x21,0xa, 0x7a,0x35, +0x26,0x7e,0x35,0x24,0x7d,0x13,0x3e,0x14,0x49,0x21,0x1f,0x34,0xbe,0x25,0x26,0x58, +0x7, 0x7e,0x25,0x26,0x59,0x21,0x1f,0x34,0xb, 0x34,0x7a,0x35,0x24,0xbe,0x75,0x24, +0x38,0xd0,0xb, 0xd0,0x7e,0x73,0x38,0xb9,0xbc,0x7d,0x38,0xbc,0x7d,0x37,0x3e,0x34, +0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0xd, 0xc8,0x12,0x20,0xc3,0x1b,0xfd,0xda, +0x79,0xda,0xd8,0x22,0x7e,0xb3,0x38,0x6, 0xb4,0x1, 0x4, 0xe4,0x2, 0x40,0x90,0x22, +0x70,0x3, 0xd2,0x86,0x22,0xc2,0x86,0x22,0x12,0x24,0x50,0x12,0x67,0xf4,0x7e,0xb3, +0x38,0x9, 0xb4,0x1, 0x67,0x12,0xb8,0x28,0x12,0x4f,0xc5,0x12,0x88,0x7, 0x12,0x46, +0x4b,0x12,0x24,0x8a,0x50,0xe5,0x12,0x67,0x6c,0x12,0x85,0xfd,0x7e,0xb3,0x38,0x6, +0xb4,0x1, 0x4, 0xe4,0x12,0x40,0x90,0x12,0x44,0xaf,0x12,0x44,0x6c,0x40,0xcc,0x12, +0x6a,0xc3,0x12,0x44,0x6c,0x40,0xc4,0x12,0x77,0x1d,0x12,0x26,0x1b,0x12,0x47,0xc8, +0x12,0x44,0xdd,0x12,0x6f,0xf1,0x12,0x92,0x54,0x12,0x59,0xe3,0x12,0x7d,0x5a,0x12, +0x78,0x8e,0x12,0x7f,0xf6,0x12,0x79,0xe9,0x12,0x97,0xf6,0x12,0x4d,0x91,0x12,0x41, +0x12,0x12,0x4f,0xf7,0x12,0x49,0x92,0x12,0x48,0x28,0x80,0x8f,0x12,0x6a,0x6d,0x2, +0x40,0x84,0xca,0x3b,0x75,0x24,0x0, 0x6c,0xff,0x12,0x43,0x2a,0x75,0x28,0x3, 0x6c, +0xee,0x7e,0x48,0x29,0xbc,0x7e,0xb3,0x2a,0xb, 0x70,0xe, 0x7e,0xb3,0x2a,0x7, 0x70, +0x8, 0x7e,0xb3,0x2a,0x8, 0x70,0x2, 0x41,0xff,0x30,0x12,0x6, 0x7e,0x68,0x35,0xd1, +0x80,0x4, 0x7e,0x68,0x35,0x93,0x7f,0x6, 0x12,0x68,0xfc,0x7e,0x73,0x2a,0x4, 0x7a, +0x6b,0x70,0x6c,0xdd,0x41,0xb0,0x74,0x9, 0xac,0xbd,0x9, 0xc5,0x29,0xc, 0x7c,0xbc, +0x54,0xf, 0x12,0x44,0x62,0xf5,0x28,0x7c,0xbc,0x54,0xf0,0xbe,0xb0,0x0, 0x28,0x2, +0x41,0xae,0xe5,0x28,0xbe,0xb0,0x3, 0x78,0x2, 0x41,0xae,0x7e,0x8, 0x0, 0x28,0x7c, +0xbc,0x12,0x9f,0xac,0x50,0x2, 0x41,0xae,0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xd, +0xf5,0x25,0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xe, 0xc4,0x54,0xf0,0xf5,0x26,0x7e, +0x73,0x2a,0x4d,0xbc,0x7c,0x28,0x54,0x7e,0xb3,0x2a,0x9, 0x70,0x2a,0x75,0x29,0xf, +0x7e,0x8, 0x0, 0x25,0xa, 0x3c,0x2e,0x34,0x35,0x7f,0x6d,0x22,0x74,0x1, 0x12,0x46, +0x9, 0x75,0x29,0x20,0x7e,0x8, 0x0, 0x26,0xa, 0x3c,0x2e,0x34,0x35,0x89,0x6d,0x22, +0x74,0x10,0x12,0x46,0x9, 0x80,0xe, 0xa, 0x3c,0x9, 0xb3,0x35,0x7f,0xf5,0x25,0x9, +0xb3,0x35,0x89,0xf5,0x26,0xa, 0x3c,0x12,0x44,0x64,0xb4,0x1, 0xe, 0xe4,0xa, 0x3c, +0x19,0xb3,0x35,0x7f,0x19,0xb3,0x35,0x89,0x12,0x43,0x2a,0x7e,0xb3,0x2a,0x64,0xb4, +0xff,0x13,0x75,0x25,0x0, 0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xc, 0xbe,0xb0,0xff, +0x68,0x3, 0x75,0x25,0x1, 0x7e,0x90,0x9, 0xac,0x9d,0x49,0xb4,0x29,0x8, 0x49,0xa4, +0x29,0xa, 0xe5,0x28,0xb4,0x1, 0x27,0x75,0x27,0x0, 0x7e,0x71,0x27,0x74,0x9, 0xac, +0x7b,0x9, 0xb3,0x36,0x13,0x54,0xf, 0xbc,0xbc,0x78,0xa, 0x49,0xb3,0x36,0xf, 0x49, +0xa3,0x36,0x11,0x80,0x9, 0x5, 0x27,0xe5,0x27,0xbe,0xb0,0xa, 0x40,0xdc,0x5e,0xb4, +0xf, 0xff,0x5e,0xa4,0xf, 0xff,0x9, 0x74,0x29,0xc, 0xa, 0x57,0xc4,0x54,0xf0,0x7c, +0xab,0xe4,0x2d,0xa5,0xbe,0x70,0xff,0x68,0x16,0xe5,0x28,0xbe,0xb0,0x1, 0x68,0x2, +0x5, 0x24,0xb, 0xf0,0xe5,0x28,0xa, 0x5b,0x12,0x7f,0x90,0x2d,0xb5,0x80,0x4, 0x2e, +0xb4,0xc0,0x0, 0x7e,0x70,0x6, 0xac,0x7e,0x7f,0x6, 0x2d,0x13,0x79,0xb0,0x0, 0x2, +0x7f,0x6, 0x2d,0x13,0x79,0xa0,0x0, 0x4, 0xe5,0x25,0x7f,0x6, 0x2d,0x13,0x39,0xb0, +0x0, 0x6, 0xe5,0x26,0x2d,0x3d,0x7d,0x2c,0x39,0xb1,0x0, 0x7, 0xb, 0xe0,0xb, 0xd0, +0x7e,0x73,0x2a,0x4d,0xbc,0x7d,0x28,0x2, 0x21,0x56,0xe5,0x24,0x39,0xb6,0x0, 0x1, +0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x9, 0x7e,0xb3,0x2a,0x8, 0xb4,0x1, 0x17,0x80,0xd, +0xbe,0xf0,0x0, 0x38,0x6, 0x7e,0xb3,0x2a,0x8, 0x60,0xa, 0xb2,0x12,0x12,0x68,0x52, +0x74,0x1, 0x12,0x40,0x90,0x7e,0xb3,0x2a,0x7, 0x60,0x5, 0x7f,0x4, 0x12,0x59,0xb1, +0xe4,0x7a,0xb3,0x2a,0xb, 0x7a,0xb3,0x2a,0x7, 0x7a,0xb3,0x2a,0x8, 0x80,0x4, 0xe4, +0x12,0x40,0x90,0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x29,0x8, 0x7e,0x8, 0x36, +0xf, 0x12,0x20,0xc3,0x1b,0xfd,0x4c,0xff,0x78,0xd, 0x7e,0x8, 0x36,0xf, 0x7e,0x34, +0x0, 0x5a,0x74,0xff,0x12,0x20,0xe8,0xda,0x3b,0x22,0x75,0x25,0x0, 0x75,0x26,0x0, +0x22,0xca,0x3b,0x6c,0xff,0x7e,0xb3,0x2a,0x6f,0xf5,0x29,0x7e,0xe3,0x2a,0x70,0x6c, +0xdd,0x7e,0xb3,0x16,0x91,0xbe,0xb0,0x1, 0x68,0xf, 0x60,0x2, 0x81,0x52,0x7e,0xb3, +0x28,0x84,0xb4,0x1, 0x2, 0x80,0x2, 0x81,0x52,0x6c,0xcc,0x81,0x44,0x12,0x97,0xd4, +0xf5,0x27,0x9, 0xb3,0x26,0xfb,0xf5,0x28,0x75,0x25,0x2, 0x75,0x26,0x2, 0x12,0xa1, +0xbe,0x50,0x6, 0x75,0x25,0x3, 0x75,0x26,0x3, 0x7c,0xbc,0x12,0x70,0x47,0xd2,0x0, +0x12,0x67,0xa3,0xe5,0x27,0x60,0xe, 0xe5,0x29,0xa, 0x2b,0x1b,0x24,0xe5,0x27,0xa, +0x3b,0xbd,0x32,0x48,0x3, 0x75,0x25,0x1, 0xe5,0x28,0x60,0xc, 0xa, 0x2e,0x1b,0x24, +0xe5,0x28,0xa, 0x3b,0xbd,0x32,0x48,0x3, 0x75,0x26,0x1, 0x75,0x24,0x0, 0x80,0x6a, +0xe5,0x24,0xbc,0xbc,0x68,0x62,0x12,0xb5,0x9b,0x7a,0xa1,0x2a,0x9, 0xb3,0x26,0xfb, +0xf5,0x2b,0xa, 0x2a,0xe5,0x27,0x12,0x44,0x5b,0xbe,0x34,0x0, 0x3, 0x18,0x11,0x12, +0x44,0x55,0xbe,0x34,0x0, 0x3, 0x18,0x8, 0x75,0x25,0x1, 0x75,0x26,0x1, 0x80,0x3f, +0xe5,0x2a,0xa, 0x2b,0xe5,0x27,0x12,0x44,0x5b,0xbe,0x34,0x0, 0x8, 0x18,0xf, 0xe5, +0x2a,0xa, 0x2b,0xe5,0x27,0x12,0x44,0x5b,0xbe,0x34,0x0, 0x3, 0x18,0x12,0x12,0x44, +0x55,0xbe,0x34,0x0, 0x8, 0x18,0x11,0x12,0x44,0x55,0xbe,0x34,0x0, 0x3, 0x8, 0x8, +0x75,0x25,0x2, 0x75,0x26,0x2, 0x80,0x7, 0x5, 0x24,0x12,0x8f,0xd6,0x38,0x91,0xe5, +0x27,0x7e,0x71,0x28,0x12,0x88,0xe8,0x50,0x6, 0x12,0x44,0x84,0x12,0x43,0x2a,0xe5, +0x25,0x7e,0x71,0x26,0x7c,0x6c,0x7c,0x5f,0x7c,0x4d,0x12,0x80,0xa3,0x12,0x44,0x84, +0xb, 0xf0,0xb, 0xc0,0x7e,0x73,0x28,0x84,0xbc,0x7c,0x28,0x2, 0x61,0x5d,0x7a,0xf3, +0x28,0x84,0xda,0x3b,0x22,0xe5,0x2b,0xa, 0x2b,0xe5,0x28,0xa, 0x3b,0x9d,0x32,0x2, +0x21,0xa, 0xa, 0x3b,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0x22,0xc2,0x0, 0x7e,0xb3, +0x16,0x91,0x60,0x6, 0x7e,0xb3,0x16,0x90,0x70,0x7, 0x12,0x97,0xcc,0x28,0x2, 0xd2, +0x0, 0xa2,0x0, 0x22,0x6c,0x33,0x6c,0x22,0x80,0x1c,0x7c,0xb2,0x12,0x67,0x50,0x50, +0x13,0x7c,0xb2,0x12,0x67,0x98,0x7d,0x3, 0x12,0x67,0xda,0x49,0x55,0x39,0xe9,0x7d, +0x40,0x12,0xc6,0x79,0xb, 0x20,0x7e,0x73,0x2a,0x75,0xbc,0x72,0x38,0xdc,0x22,0x12, +0x45,0xb8,0x12,0x44,0xc1,0x12,0x44,0xcc,0x30,0x16,0x5, 0x12,0x44,0x84,0xc2,0x16, +0x22,0x2, 0x44,0xc4,0x7e,0x73,0x2a,0x6b,0x2e,0x70,0xff,0x22,0x12,0x44,0xc4,0x40, +0xb, 0x12,0xab,0x58,0xe4,0x7a,0xb3,0x3, 0xfd,0x2, 0x45,0xbe,0x22,0xca,0x3b,0x7e, +0x73,0x38,0x26,0xa, 0x37,0x6d,0x22,0x7a,0x1d,0x26,0x7e,0x33,0x38,0x28,0xa, 0xf3, +0x6d,0xee,0x7a,0x7d,0x2a,0x7e,0x33,0x38,0x27,0xa, 0x93,0x6d,0x88,0x7e,0x33,0x38, +0x29,0xa, 0x73,0x6d,0x66,0x7e,0x44,0x4, 0x38,0x7d,0x14,0x12,0x1e,0xfc,0x12,0x45, +0xb1,0x7a,0x1d,0x26,0x7e,0x54,0x7, 0x80,0x7f,0x17,0x7d,0x15,0x12,0x1e,0xfc,0x12, +0x45,0xb1,0x7a,0x1d,0x2a,0x7f,0x14,0x7d,0x14,0x12,0x1e,0xfc,0x12,0x45,0xb1,0x7f, +0x41,0x7f,0x13,0x7d,0x15,0x12,0x1e,0xfc,0x7c,0xf6,0x7c,0xe5,0xa, 0x64,0x12,0x44, +0xc4,0x50,0x60,0x7e,0xb3,0x16,0x91,0xb4,0x1, 0x59,0x75,0x2e,0x0, 0x80,0x4b,0x7e, +0xa1,0x2e,0x74,0x9, 0xa4,0x49,0x35,0x27,0x76,0x12,0x7a,0xa2,0x7a,0x35,0x24,0x7e, +0xa1,0x2e,0x74,0x9, 0xa4,0x49,0x35,0x27,0x78,0x12,0x78,0xeb,0x7d,0xa3,0x7e,0x35, +0x24,0x6d,0x22,0x7e,0xd, 0x26,0xbf,0x10,0x40,0x17,0x7d,0x5a,0x6d,0x44,0x7e,0xd, +0x2a,0xbf,0x20,0x40,0xc, 0xbf,0x14,0x38,0x8, 0x7d,0x3a,0x6d,0x22,0xbf,0x13,0x28, +0x7, 0xe5,0x2e,0x6c,0x77,0x12,0x73,0x2e,0x5, 0x2e,0x7e,0x73,0x28,0x84,0xbe,0x71, +0x2e,0x38,0xac,0xda,0x3b,0x22,0x9d,0x32,0x12,0x21,0xa, 0x7d,0x13,0x7d,0x30,0xad, +0x31,0x7c,0x76,0x7c,0x65,0xa, 0x24,0x22,0x12,0x47,0xcb,0x2, 0x45,0xbe,0xe4,0x7a, +0xb3,0x28,0x93,0x12,0xa3,0x3f,0x12,0xbc,0x1a,0x7e,0xb3,0x16,0x91,0xb4,0x1, 0x8, +0x7e,0x73,0x28,0x84,0x7a,0x73,0x28,0x92,0x7e,0x18,0x4, 0xfc,0x7a,0x1f,0x6, 0xf8, +0x12,0x5d,0xd5,0x12,0x89,0x37,0x12,0x86,0x47,0x7e,0xb3,0x16,0x90,0xb4,0x1, 0x18, +0x7e,0x73,0x26,0x83,0x7a,0x73,0x26,0xf3,0x7e,0x73,0x26,0x85,0x7a,0x73,0x26,0xf5, +0x7e,0x73,0x26,0x84,0x7a,0x73,0x26,0xf4,0x22,0x7c,0x9b,0x7f,0x71,0x7e,0x7b,0x80, +0x4c,0x88,0x78,0x7, 0x7e,0xb, 0x90,0x7a,0x7b,0x90,0x22,0xa, 0x28,0x7e,0xb, 0x80, +0xa, 0x38,0x9d,0x32,0x12,0x21,0xa, 0xe5,0x29,0xa, 0x2b,0xbd,0x32,0x8, 0x15,0x7e, +0x7b,0xa0,0x7e,0xb, 0xb0,0xbc,0xba,0x7c,0xba,0x28,0x4, 0x2c,0xb9,0x80,0x2, 0x9c, +0xb9,0x7a,0x7b,0xb0,0x7e,0x7b,0x70,0x7a,0xb, 0x70,0x22,0x7e,0x24,0x37,0xe2,0x30, +0x11,0x54,0xc2,0x11,0x9, 0x72,0x0, 0x2, 0x12,0x46,0xa7,0x7a,0x37,0x2a,0x4f,0x9, +0x72,0x0, 0x3, 0x12,0x46,0xa7,0x7a,0x37,0x2a,0x51,0x9, 0x72,0x0, 0x4, 0x12,0x46, +0xa7,0x7a,0x37,0x2a,0x53,0x7e,0x29,0x70,0x12,0x46,0xb2,0x7a,0x37,0x2a,0x5a,0x9, +0x72,0x0, 0x1, 0x12,0x46,0xb2,0x7a,0x37,0x2a,0x5c,0x9, 0x72,0x0, 0x5, 0x12,0x46, +0xa7,0x7a,0x37,0x2a,0x62,0x9, 0x72,0x0, 0x41,0xbe,0x73,0x2a,0x6b,0x68,0x7, 0x7a, +0x73,0x2a,0x6b,0x2, 0x47,0xda,0x22,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e, +0x34,0x22,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x22,0x7e,0x30,0x64,0x7e,0x20,0x64,0x6c, +0x11,0x80,0x4a,0xa, 0x31,0xb, 0x34,0x7c,0x7, 0x80,0x38,0x7e,0x70,0x2, 0xac,0x70, +0x9, 0xb3,0x26,0xfa,0x12,0x47,0x2e,0x9, 0xb3,0x26,0xfa,0x12,0x44,0x5b,0x7c,0x97, +0x7e,0x70,0x2, 0xac,0x70,0x9, 0xb3,0x26,0xfb,0x12,0x47,0x2e,0x9, 0xb3,0x26,0xfb, +0x12,0x44,0x5b,0x7c,0x87,0xbc,0x39,0x28,0x2, 0x7c,0x39,0xbc,0x28,0x28,0x2, 0x7c, +0x28,0xb, 0x0, 0x7e,0xb3,0x28,0x84,0xbc,0xb0,0x38,0xc0,0xb, 0x10,0x7e,0xb3,0x28, +0x84,0xbc,0xb1,0x38,0xae,0xa5,0xbb,0x64,0x2, 0x6c,0x33,0xa5,0xba,0x64,0x2, 0x6c, +0x22,0xbc,0x23,0x28,0x4, 0x7c,0xa2,0x80,0x2, 0x7c,0xa3,0x7c,0xba,0x22,0xa, 0x2b, +0x7e,0x70,0x2, 0xac,0x71,0x22,0xca,0x79,0x7c,0xe5,0x7c,0xfb,0x7e,0xe4,0xff,0xfc, +0x7c,0xb4,0x12,0xa0,0x0, 0x7d,0x3, 0x74,0x9, 0xac,0xbf,0x12,0x7f,0xa8,0x12,0x45, +0xa6,0x7d,0x13,0x5e,0x30,0xfc,0x7e,0x70,0x9, 0xac,0x7f,0x49,0xf3,0x29,0x62,0x74, +0x9, 0xac,0xbe,0x49,0x25,0x28,0xae,0xbd,0x2f,0x28,0xf, 0x7d,0x53,0x2e,0x54,0x29, +0x62,0x7d,0x2f,0x2d,0x21,0x1b,0x58,0x20,0x80,0x9, 0x2e,0x34,0x29,0x62,0x9d,0xf1, +0x1b,0x38,0xf0,0x74,0x9, 0xac,0xbf,0x49,0x25,0x29,0x64,0x74,0x9, 0xac,0xbe,0x49, +0x35,0x28,0xb0,0x12,0x45,0xa6,0x7d,0x13,0x5d,0x1e,0x7e,0x50,0x9, 0xac,0x5f,0x49, +0x32,0x29,0x64,0x74,0x9, 0xac,0xbe,0x49,0x5, 0x28,0xb0,0xbd,0x3, 0x28,0xd, 0x7d, +0x2, 0x2e,0x4, 0x29,0x64,0x2d,0x13,0x1b,0x8, 0x10,0x80,0x9, 0x2e,0x24,0x29,0x64, +0x9d,0x31,0x1b,0x28,0x30,0xda,0x79,0x22,0x2, 0x43,0x31,0x12,0x47,0xe2,0x2, 0x47, +0xd1,0x12,0x44,0xc4,0x50,0x3, 0x2, 0x48,0x9, 0x22,0x12,0x44,0xc4,0xd2,0x1a,0x2, +0x26,0x11,0x12,0x5d,0xde,0x7e,0x34,0x0, 0x78,0x7a,0x37,0x2a,0x5c,0x7e,0x34,0xff, +0x6a,0x7a,0x37,0x2a,0x5e,0x2, 0x47,0xf8,0x7e,0x34,0x0, 0xfa,0x7a,0x37,0x2a,0x4f, +0x7a,0x37,0x2a,0x51,0x7a,0x37,0x2a,0x53,0x22,0x7e,0x34,0x0, 0x32,0x7a,0x37,0x2a, +0x5a,0x7e,0x34,0x0, 0x28,0x7a,0x37,0x2a,0x5c,0x7e,0x34,0x0, 0x78,0x7a,0x37,0x2a, +0x4f,0x7e,0x34,0x0, 0x64,0x2, 0x48,0x0, 0x7e,0x8, 0x38,0xf4,0x12,0x48,0x5c,0x7e, +0x8, 0x38,0xfc,0x12,0x48,0x5c,0x12,0x48,0x71,0x12,0x48,0x78,0x2, 0x48,0x3f,0x7e, +0x37,0x38,0xf4,0xbe,0x34,0x0, 0x0, 0x28,0x12,0x7e,0x73,0x3a,0x8, 0xbe,0x70,0x5, +0x50,0x9, 0x7e,0xb3,0x38,0x32,0x70,0x3, 0x12,0x48,0x7f,0x22,0xb, 0xa, 0x30,0xe5, +0x5e,0xa, 0x2b,0xbd,0x32,0x28,0x4, 0x9d,0x32,0x80,0x2, 0x6d,0x33,0x1b,0xa, 0x30, +0x22,0x7e,0x8, 0x2b,0xb7,0x2, 0x48,0x5c,0x7e,0x8, 0x39,0xe7,0x2, 0x48,0x5c,0x6d, +0x33,0x7a,0x37,0x39,0x84,0x74,0x1, 0x7a,0xb3,0x38,0x7, 0x22,0x7e,0xb3,0x38,0x7, +0x14,0x68,0x51,0x14,0x78,0x2, 0x21,0x20,0x14,0x68,0x61,0x24,0x3, 0x78,0x79,0x12, +0x49,0x26,0x38,0x8, 0x30,0x14,0xf, 0x12,0x4f,0xd4,0x68,0xa, 0x12,0x4a,0x2e,0xe4, +0x7a,0xb3,0x39,0x86,0x80,0x6a,0x7e,0xb3,0x37,0xe8,0x30,0xe0,0x63,0x7e,0x73,0x37, +0xe9,0xa, 0x27,0x7e,0x34,0x4, 0x0, 0xad,0x32,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x4, +0x7e,0x34,0x5, 0xf4,0xbe,0x37,0x39,0x84,0x50,0x46,0x12,0x48,0x7f,0xe4,0x7a,0xb3, +0x39,0x88,0x80,0x3c,0x12,0x49,0x26,0x28,0x32,0xe4,0x7a,0xb3,0x38,0x7, 0x7e,0xb3, +0x39,0x86,0xb4,0x1, 0x3, 0x12,0x48,0x85,0xd2,0x1c,0x80,0x1f,0x74,0xff,0x7a,0xb3, +0x37,0xe1,0x12,0x4f,0xc5,0x12,0x49,0xb2,0x12,0x23,0x3b,0xe4,0x7a,0xb3,0x38,0x7, +0x7a,0xb3,0x3a,0x8, 0xd2,0x1c,0x80,0x8, 0x12,0x48,0x85,0xe4,0x7a,0xb3,0x3a,0x8, +0x12,0x49,0x2e,0x2, 0x34,0xc5,0x7e,0x73,0x2a,0x2, 0xbe,0x70,0x0, 0x22,0x74,0x1, +0x12,0x49,0x4d,0x20,0x1c,0x6, 0x12,0x49,0x70,0x12,0x0, 0x6e,0x7e,0xb3,0x34,0x3a, +0xb4,0x1, 0x6, 0x12,0x49,0x56,0x12,0x0, 0x6e,0xe4,0x2, 0x49,0x4d,0xbe,0xb0,0x8, +0x50,0x3, 0x12,0x4f,0xdc,0x22,0x74,0xc8,0x7a,0xb3,0x3a,0x7, 0xc2,0x1c,0x80,0xa, +0x12,0x37,0x75,0x30,0x1c,0x4, 0x75,0xe9,0xff,0x22,0x12,0x49,0x8a,0x68,0xf1,0x22, +0xd2,0x0, 0x80,0x12,0x30,0x0, 0xc, 0x12,0x49,0x8a,0x68,0x7, 0xc2,0x0, 0xc2,0x1, +0x12,0x37,0xa6,0x12,0x37,0x75,0x30,0x1c,0xeb,0x22,0x7e,0xb3,0x34,0x3a,0xbe,0xb0, +0x1, 0x22,0x12,0x48,0x8c,0x7e,0x73,0x37,0xe1,0xbe,0x70,0xff,0x68,0x13,0xbe,0x73, +0x38,0x7, 0x68,0xd, 0x7a,0x73,0x38,0x7, 0x74,0xff,0x7a,0xb3,0x37,0xe1,0x2, 0x48, +0x8c,0x22,0x12,0x37,0x6e,0x12,0x49,0xde,0x75,0xcd,0x0, 0xa9,0xd6,0xeb,0xa9,0xd7, +0xcd,0xc2,0xce,0x12,0x4f,0xee,0x12,0x2f,0xaf,0x74,0x1, 0x12,0x49,0xe7,0xa9,0xc6, +0xeb,0xa9,0xc7,0xcd,0xd2,0xce,0xe5,0x25,0x7e,0x71,0x24,0x2, 0x2f,0xf, 0x12,0x49, +0x8a,0x68,0xfb,0x20,0x93,0xfd,0x22,0x7c,0xab,0x7e,0xb3,0x3a,0x3, 0xb4,0x81,0x38, +0x4c,0xaa,0x78,0x5, 0xa9,0xd0,0x87,0x80,0x29,0xbe,0xa0,0x1, 0x78,0xf, 0xc2,0xaf, +0xa9,0xd0,0xce,0xa9,0xc7,0xc9,0xa9,0xd1,0x87,0xd2,0xaf,0x80,0x15,0xbe,0xa0,0x2, +0x78,0x16,0xc2,0xaf,0x20,0x93,0x9, 0xa9,0xd0,0xce,0xa9,0xd7,0xc9,0xa9,0xd1,0x87, +0xd2,0xaf,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4,0x7a,0xb3,0x3a,0x3, 0x22,0x6d,0x33, +0x7a,0x37,0x39,0x84,0x22,0xca,0xf8,0x7e,0xa3,0x2a,0x2, 0x7e,0x73,0x2a,0x3, 0xbe, +0xa0,0x1, 0x38,0x21,0xbe,0x70,0x1, 0x38,0x1c,0x7e,0x27,0x28,0x86,0xbe,0x24,0x0, +0x1e,0x28,0x2, 0x80,0x10,0x7e,0xf3,0x2f,0x80,0x4c,0xff,0x68,0x17,0x7e,0x27,0x2b, +0xb7,0x4d,0x22,0x78,0xf, 0x12,0x4a,0x2e,0x74,0x1, 0x7a,0xb3,0x39,0x86,0x7a,0xb3, +0x38,0x7, 0x80,0x36,0x4c,0xaa,0x78,0x37,0xa5,0xbf,0x1, 0x33,0x7e,0x37,0x2b,0xb7, +0x7a,0x37,0x2f,0x82,0x7e,0xb3,0x2f,0x80,0xb4,0x3, 0x1f,0x7e,0x37,0x2b,0xb7,0xbe, +0x34,0x0, 0x0, 0x28,0x15,0x74,0x4, 0x7a,0xb3,0x2f,0x80,0x7e,0x37,0x2f,0x98,0x7e, +0x27,0x2f,0x9a,0x12,0x4b,0x3e,0x61,0x37,0x80,0x0, 0x12,0xbe,0x2f,0x61,0x37,0x7e, +0x63,0x34,0x88,0x7e,0x50,0x9, 0xac,0x56,0x49,0xc2,0x29,0x8, 0x49,0xd2,0x29,0xa, +0x4c,0xff,0x78,0x1b,0xa5,0xbf,0x0, 0x43,0xbe,0xa0,0x1, 0x78,0x3e,0x7d,0x3c,0x7d, +0x2d,0x12,0xbd,0xcd,0x12,0x4b,0x3a,0x74,0x1, 0x7a,0xb3,0x2f,0x80,0x80,0x2c,0xbe, +0xf0,0x1, 0x78,0x1a,0x12,0x4c,0x76,0xbe,0x34,0x0, 0x64,0x38,0x9, 0x12,0x4c,0x1, +0xbe,0x34,0x0, 0xa0,0x28,0x15,0x74,0x3, 0x7a,0xb3,0x2f,0x80,0x80,0x5, 0xbe,0xf0, +0x3, 0x78,0x8, 0x7a,0xc7,0x2f,0x98,0x7a,0xd7,0x2f,0x9a,0x7e,0xb3,0x2f,0x80,0x60, +0x26,0x7d,0x3c,0x7d,0x2d,0x7e,0x17,0x2b,0xbb,0x7e,0x7, 0x2b,0xbd,0x12,0x4b,0xe9, +0xa, 0x2b,0x7e,0x73,0x2f,0x7f,0xa, 0x37,0xbd,0x32,0x58,0xb, 0x12,0x4b,0x3a,0x7a, +0xc7,0x2b,0xbb,0x7a,0xd7,0x2b,0xbd,0xda,0xf8,0x22,0x7d,0x3c,0x7d,0x2d,0x7d,0x42, +0x7d,0x13,0x7d,0x24,0x12,0x4f,0x6a,0x7d,0x31,0x12,0x4c,0xa, 0x2, 0x4b,0x4f,0x7e, +0x3, 0x2f,0xa8,0xbe,0x0, 0xf0,0x50,0x2, 0x61,0xe8,0x61,0xdd,0x6c,0x99,0x7e,0xb3, +0x2f,0x7f,0xbe,0xb0,0x20,0x50,0x5, 0x4, 0x7a,0xb3,0x2f,0x7f,0x7e,0x1f,0x2b,0xbf, +0x7a,0x1f,0x1f,0x34,0x7e,0x80,0x1, 0x80,0x49,0x74,0x4, 0xac,0xb8,0x49,0x35,0x2b, +0xbf,0x49,0x25,0x2b,0xc1,0x7e,0x17,0x1f,0x34,0x7e,0x7, 0x1f,0x36,0x12,0x4b,0xe9, +0x7c,0x1b,0x7e,0x3, 0x2f,0x7f,0xbc,0x1, 0x38,0x26,0xb, 0x90,0x7e,0x70,0x4, 0xac, +0x78,0x2e,0x34,0x2b,0xbf,0x7e,0x14,0x1f,0x34,0x74,0x4, 0x12,0x1f,0x8c,0x7e,0x34, +0x1f,0x34,0x7e,0x30,0x4, 0xac,0x39,0x2e,0x14,0x2b,0xbf,0x74,0x4, 0x12,0x1f,0x8c, +0xb, 0x80,0x7e,0x3, 0x2f,0xa8,0xbc,0x8, 0x38,0xaf,0xa, 0x59,0xb, 0x54,0x7c,0xb, +0x7a,0x3, 0x2f,0xa8,0x7e,0x3, 0x2f,0x7f,0xbe,0x0, 0x20,0x50,0xb, 0x7e,0x3, 0x2f, +0xa8,0xbe,0x0, 0xec,0x40,0x2, 0x61,0x5c,0x22,0x7d,0x51,0x7d,0x12,0x9d,0x35,0x12, +0x21,0xa, 0x7c,0xa7,0x12,0x4f,0xe, 0x7c,0xb7,0xbc,0xba,0x50,0x3, 0x7c,0xba,0x22, +0x22,0x7e,0x37,0x2f,0x96,0x9e,0x37,0x2f,0x8e,0x22,0x7e,0x17,0x2f,0x90,0xbd,0x13, +0x28,0xa, 0x7a,0x37,0x2f,0x90,0x7a,0x27,0x2f,0x92,0x80,0x10,0x7e,0x17,0x2f,0x88, +0xbd,0x13,0x50,0x8, 0x7a,0x37,0x2f,0x88,0x7a,0x27,0x2f,0x8a,0x7e,0x17,0x2f,0x8e, +0xbd,0x12,0x28,0xa, 0x7a,0x27,0x2f,0x8e,0x7a,0x37,0x2f,0x8c,0x80,0x10,0x7e,0x17, +0x2f,0x96,0xbd,0x12,0x50,0x8, 0x7a,0x27,0x2f,0x96,0x7a,0x37,0x2f,0x94,0x7e,0xb3, +0x2f,0xa8,0xb4,0xa, 0xf, 0x12,0x4c,0x76,0x7a,0x37,0x2f,0xa0,0x12,0x4c,0x1, 0x7a, +0x37,0x2f,0xa2,0x22,0xb4,0x14,0xe, 0x12,0x4c,0x76,0x7a,0x37,0x2f,0xa4,0x12,0x4c, +0x1, 0x7a,0x37,0x2f,0xa6,0x22,0x7e,0x37,0x2f,0x88,0x9e,0x37,0x2f,0x90,0x22,0x12, +0x4c,0x76,0x7a,0x37,0x2f,0x9c,0x12,0x4c,0x1, 0x7a,0x37,0x2f,0x9e,0x12,0x4d,0xd0, +0x60,0x1, 0x22,0x7e,0x73,0x2f,0xa8,0xa, 0x37,0x7a,0x35,0x24,0x7e,0x8, 0x2b,0xbf, +0x7e,0x18,0x2f,0x80,0x2, 0x4c,0xa7,0xca,0xf8,0x7e,0x45,0x24,0x7c,0xb9,0x7a,0xb3, +0x39,0x40,0x74,0xff,0x7a,0xb3,0x39,0x3f,0x6d,0x55,0x80,0x19,0x7d,0xf5,0x3e,0xf4, +0x12,0x4f,0x17,0x7d,0xe5,0x3e,0xe4,0x59,0xfe,0x1f,0x34,0x69,0xf6,0x0, 0x2, 0x59, +0xfe,0x21,0x14,0xb, 0x54,0xbd,0x45,0x38,0xe3,0x7e,0x33,0x39,0x40,0xbe,0x30,0x4, +0x38,0x2, 0xa1,0x69,0x69,0xf1,0x0, 0x1c,0x69,0x11,0x0, 0x1e,0xbd,0x1f,0x18,0x19, +0x4d,0x11,0x78,0x4, 0x7e,0x14,0x0, 0x1, 0x7d,0x3f,0x7d,0x21,0x12,0x1e,0xb9,0x7c, +0xf7,0x74,0x40,0x7a,0xb3,0x39,0x43,0x80,0x43,0x4d,0xff,0x78,0x4, 0x7e,0xf4,0x0, +0x1, 0x7d,0x31,0x7d,0x2f,0x12,0x1e,0xb9,0x7c,0xf7,0x74,0x80,0x7a,0xb3,0x39,0x43, +0x7d,0xf, 0x2d,0xf, 0xbd,0x1, 0x8, 0x24,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x39,0x43, +0xa, 0x37,0x6d,0x22,0x12,0x1e,0xeb,0x7d,0x5f,0x1a,0x4a,0x1a,0x48,0x7d,0x1f,0x1a, +0x2, 0x1a,0x0, 0x2f,0x2, 0x12,0x1f,0x7, 0x7a,0x73,0x39,0x43,0xbe,0xf0,0x5, 0x58, +0x14,0x12,0x4d,0x88,0x12,0xc1,0xd5,0x12,0x4d,0x88,0x12,0xc3,0x7c,0x12,0x4d,0x88, +0x12,0xc2,0xc0,0x80,0xa, 0x74,0x7d,0x80,0x2, 0x74,0x7f,0x7a,0xb3,0x39,0x3f,0xe4, +0x7a,0xb3,0x39,0x40,0x7e,0x73,0x3a,0x2, 0xbe,0x73,0x39,0x3f,0x48,0x6, 0x7e,0xb3, +0x39,0x41,0x80,0x1, 0xe4,0xda,0xf8,0x22,0x7e,0x8, 0x1f,0x34,0x7e,0x18,0x21,0x14, +0x22,0x7e,0xb3,0x38,0x32,0x70,0x6, 0x12,0x4d,0xca,0x2, 0x4f,0xbf,0x12,0x4a,0x35, +0x12,0xbd,0xc2,0x50,0xa, 0x12,0x4c,0x7f,0x7c,0x3b,0x12,0x4d,0xca,0x80,0x5, 0x12, +0xc5,0x1f,0x7c,0x3b,0x4c,0x33,0x68,0x11,0x7c,0xb3,0x12,0xbd,0x46,0x60,0xa, 0x7a, +0x33,0x38,0x35,0x74,0x1, 0x7a,0xb3,0x2a,0x8, 0x22,0xe4,0x7a,0xb3,0x2f,0x80,0x22, +0xca,0xf8,0x6c,0xff,0x7e,0xb7,0x2f,0x9c,0x7e,0xc7,0x2f,0x9e,0x7e,0x97,0x2f,0x84, +0x7e,0xd7,0x2f,0x86,0x7e,0xa7,0x2f,0x98,0x7e,0xe7,0x2f,0x9a,0xe4,0x7e,0x73,0x2f, +0xa8,0x1b,0x70,0x7d,0x2b,0x7d,0x1c,0x12,0x4e,0xc2,0x70,0x2, 0xc1,0xbd,0x7e,0x73, +0x2f,0xa8,0xbe,0x70,0xa, 0x28,0x13,0xe4,0x7e,0x70,0x9, 0x7e,0x27,0x2f,0xa0,0x7e, +0x17,0x2f,0xa2,0x12,0x4e,0xc2,0x70,0x2, 0xc1,0xbd,0x7e,0x73,0x2f,0xa8,0xbe,0x70, +0x14,0x28,0x13,0xe4,0x7e,0x70,0x13,0x7e,0x27,0x2f,0xa4,0x7e,0x17,0x2f,0xa6,0x12, +0x4e,0xc2,0x70,0x2, 0xc1,0xbd,0xbe,0xc4,0x0, 0xf0,0x50,0x2d,0xbe,0xb4,0x1, 0xe, +0x28,0x27,0x7e,0xb3,0x2f,0x81,0x70,0x21,0x12,0x4f,0x5, 0x28,0x1c,0xbe,0xf4,0x13, +0x4c,0x50,0x16,0x7d,0xfc,0x3e,0xf4,0xbd,0xfb,0x50,0x62,0xbd,0xa9,0x50,0x5, 0x7e, +0xf0,0x20,0x80,0x59,0x7e,0xf0,0x21,0x80,0x54,0xbe,0xb4,0x0, 0x87,0x50,0x4e,0xbe, +0xc4,0x1, 0xe0,0x28,0x48,0x7e,0xb3,0x2f,0x81,0x70,0x42,0x12,0x4f,0x5, 0x28,0x3d, +0xbe,0xf4,0x13,0x4c,0x50,0x37,0x7d,0xfb,0x3e,0xf4,0xbd,0xfc,0x50,0x2f,0xbd,0xed, +0x50,0x5, 0x7e,0xf0,0x22,0x80,0x26,0x12,0x4f,0x8b,0x49,0x35,0x2b,0xbb,0x49,0x15, +0x2b,0xbd,0x49,0x25,0x2b,0xab,0x49,0x5, 0x2b,0xad,0x9d,0x10,0xbe,0x14,0x0, 0x20, +0x18,0x8, 0x9d,0x32,0xbe,0x34,0x0, 0x10,0x58,0x3, 0x7e,0xf0,0x23,0x7c,0xbf,0xda, +0xf8,0x22,0x7d,0x41,0x7d,0x2, 0x7c,0x37,0x7c,0x2b,0x74,0x4, 0xac,0xb2,0x49,0x35, +0x2b,0xbf,0x49,0xf5,0x2b,0xc1,0x74,0x4, 0xac,0xb3,0x49,0x25,0x2b,0xbf,0x49,0x55, +0x2b,0xc1,0x12,0x4f,0xcc,0x7d,0x3f,0x9d,0x35,0x12,0x21,0xa, 0x9d,0x34,0x12,0x21, +0xa, 0xbe,0x34,0x0, 0x4d,0x58,0xc, 0x12,0x4f,0xe, 0xbe,0x34,0x0, 0x4d,0x58,0x3, +0x74,0x1, 0x22,0xe4,0x22,0x7e,0xf7,0x2f,0x82,0xbe,0xf4,0xf, 0xa0,0x22,0x7d,0x31, +0x9d,0x30,0x2, 0x21,0xa, 0x7d,0xf4,0x3e,0xf4,0x7f,0x60,0x2d,0xdf,0xb, 0x6a,0xf0, +0x22,0x7c,0xab,0x6d,0x44,0x80,0x29,0x4c,0xaa,0x68,0x11,0x12,0x4f,0x58,0x60,0x5, +0x3e,0xe4,0x14,0x78,0xfb,0x12,0x4f,0x15,0x2d,0xfe,0x80,0xf, 0x12,0x4f,0x58,0x60, +0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x12,0x4f,0x15,0x9d,0xfe,0x1b,0x6a,0xf0,0xb, 0x44, +0x7e,0xf5,0x29,0xbd,0xf4,0x38,0xd0,0x22,0x7f,0x71,0x2d,0xf4,0x7e,0x7b,0xb0,0x1a, +0xeb,0x7f,0x61,0x2e,0xd5,0x29,0x7e,0x6b,0xb0,0x22,0x7e,0xa3,0x2f,0xa8,0xbe,0xa0, +0xf0,0x50,0x17,0x74,0x4, 0xa4,0x59,0x35,0x2b,0xbf,0x12,0x4f,0x8b,0x59,0x25,0x2b, +0xc1,0x7e,0xb3,0x2f,0xa8,0x4, 0x7a,0xb3,0x2f,0xa8,0x22,0x7e,0xa3,0x2f,0xa8,0x74, +0x4, 0xa4,0x22,0x7c,0x7b,0x7e,0x63,0x2a,0x71,0xa, 0x6, 0x2e,0x4, 0x0, 0x3, 0x7e, +0x63,0x2a,0x6e,0xa, 0x16,0xad,0x10,0x7d,0x21,0x12,0x4f,0xe5,0xa, 0x26,0x7a,0x25, +0x29,0x74,0x1d,0xac,0x7b,0x2e,0x34,0x38,0x45,0x6d,0x22,0xe4,0x2, 0x4f,0x21,0xe4, +0x7a,0xb3,0x39,0xde,0x22,0x7e,0x34,0x0, 0xc8,0x2, 0x23,0xcc,0x9d,0x32,0x12,0x21, +0xa, 0x7d,0x13,0x22,0x7e,0xb3,0x38,0x32,0xbe,0xb0,0x1, 0x22,0xa, 0x5b,0x2e,0x54, +0x0, 0x8, 0xf5,0xcc,0x22,0x3e,0x24,0x7e,0xf, 0x39,0xda,0x2d,0x12,0x22,0x7e,0x8, +0x0, 0x25,0x7e,0x18,0x0, 0x24,0x22,0x7e,0x73,0x28,0x93,0x7a,0x73,0x28,0x94,0x7e, +0x73,0x2a,0x2, 0x7a,0x73,0x2a,0x3, 0xe4,0x7a,0xb3,0x2a,0x6, 0x22,0x7e,0x37,0x33, +0xeb,0xb, 0x34,0x7a,0x37,0x33,0xeb,0x7e,0x37,0x33,0xed,0xbe,0x37,0x33,0xeb,0x28, +0x3, 0x2, 0x50,0x28,0x22,0x2, 0x50,0xd, 0xe5,0x9a,0x60,0x5, 0xd2,0x9c,0xa9,0xd6, +0xdf,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca,0xb, +0xc0,0xd0,0xc0,0x83,0xc0,0x82,0x12,0x50,0x25,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda, +0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x7e,0x23, +0x2b,0xf, 0x7e,0x33,0x38,0xce,0xac,0x23,0x2e,0x14,0x1, 0xf4,0xbe,0x14,0x0, 0xa, +0x50,0x4, 0x7e,0x14,0x0, 0xa, 0x7e,0x63,0x2b,0x10,0xbe,0x14,0xf, 0x3c,0x40,0x4, +0x7e,0x14,0xf, 0x3c,0xbe,0x14,0x7, 0x8, 0x40,0x3, 0xe4,0x80,0x2, 0x74,0x1, 0x7a, +0xb3,0x2b,0x10,0x7e,0x73,0x2b,0x10,0xbc,0x76,0x68,0x2, 0xd2,0x10,0x7e,0x24,0x1, +0xf4,0x7d,0x31,0x8d,0x32,0x7c,0x17,0xbe,0x10,0x7, 0x28,0x3, 0x7e,0x10,0x7, 0x7e, +0x1f,0x39,0xc1,0x69,0x51,0x0, 0x86,0x54,0x1f,0xa, 0x1, 0x3e,0x4, 0x3e,0x4, 0x3e, +0x4, 0x3e,0x4, 0x3e,0x4, 0x2d,0x5, 0x79,0x1, 0x0, 0x86,0x6d,0x0, 0x7e,0x34,0xb8, +0x0, 0x7e,0x24,0x0, 0xb, 0x2, 0x1f,0x58,0x7e,0xa3,0x0, 0x5f,0xbe,0xa0,0xff,0x68, +0x48,0xbe,0xa3,0x3, 0xfc,0x68,0x42,0x74,0x5, 0xa4,0x12,0x57,0x7c,0x12,0x51,0x2a, +0x12,0x55,0x70,0x12,0x51,0x2a,0x12,0x55,0x67,0x12,0x57,0x8e,0x50,0x9, 0x7e,0xb3, +0x0, 0x5f,0x12,0x55,0x79,0x80,0x6, 0x12,0x51,0x2a,0x12,0x54,0x6a,0x12,0x51,0x36, +0x12,0x54,0x63,0x7e,0x73,0x2b,0x14,0xa, 0x37,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, +0x1a,0x7e,0x73,0x0, 0x5f,0x7a,0x73,0x3, 0xfc,0x22,0x7e,0xa3,0x0, 0x5f,0x74,0x5, +0xa4,0x22,0x7a,0xb3,0x2b,0xf, 0x12,0x50,0x5e,0x7a,0x37,0x2b,0x1b,0x22,0x12,0x51, +0x32,0x30,0x10,0xc, 0xc2,0x10,0x12,0x57,0xd5,0x30,0x0, 0x4, 0xe4,0x12,0xa, 0x66, +0x30,0x0, 0x9, 0x12,0xab,0x26,0x12,0x57,0xf8,0x2, 0x57,0x9f,0x22,0x7e,0xb, 0x70, +0x7a,0x73,0x2b,0xf, 0x29,0x70,0x0, 0x4, 0x7a,0x73,0x2b,0x62,0x29,0x70,0x0, 0x1, +0x7a,0x73,0x2b,0x14,0x29,0x70,0x0, 0x3, 0x7a,0x73,0x2b,0x20,0x12,0x51,0x36,0x12, +0x54,0x63,0xd2,0x0, 0xc2,0x1, 0x2, 0x3b,0xba,0xca,0xf8,0x7c,0xfb,0x74,0x5, 0xac, +0xbf,0x12,0x57,0x7c,0x12,0x55,0x70,0x12,0x54,0x6a,0x12,0x55,0x67,0x7a,0xf3,0x0, +0x5f,0x7c,0xbf,0x12,0x55,0x79,0x12,0x51,0x36,0x74,0x5, 0xac,0xbf,0x9, 0xb5,0x26, +0x37,0x12,0x57,0xba,0x12,0x23,0x23,0xe4,0x7a,0xb3,0x16,0x91,0xda,0xf8,0x22,0x7e, +0xb3,0x37,0x66,0x60,0x6, 0x14,0x7a,0xb3,0x37,0x66,0x22,0x12,0xa7,0xf9,0x7e,0xb3, +0x37,0xed,0x70,0xe, 0x7e,0xb3,0x3a,0xf, 0xb4,0x1, 0x7, 0xe4,0x12,0x51,0x89,0x12, +0x57,0xee,0x12,0x54,0x27,0x12,0xa9,0x2d,0x7e,0xa3,0x37,0xed,0x7a,0xa3,0x3a,0xf, +0xbe,0xb0,0xff,0x68,0x3, 0x2, 0x51,0x89,0x22,0xca,0xf8,0x6c,0xff,0x7e,0x73,0x0, +0x5f,0xbc,0x7f,0x68,0x2a,0x7e,0x30,0x5, 0xac,0x3f,0x12,0x52,0x6f,0xca,0x39,0x7e, +0x30,0x38,0xac,0x3f,0x12,0x52,0x88,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c, +0xca,0x39,0x7e,0x30,0x8c,0xac,0x3f,0x12,0x52,0x7d,0x12,0x20,0xc3,0x1b,0xfd,0xb, +0xf0,0xbe,0xf0,0x4, 0x40,0xc7,0x7e,0x23,0x0, 0x5f,0x7e,0x30,0x5, 0xac,0x23,0x12, +0x52,0x6f,0xca,0x39,0x7e,0x23,0x0, 0x5f,0x7e,0x30,0x38,0xac,0x23,0x12,0x52,0x88, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x23,0x0, 0x5f,0x7e, +0x30,0x8c,0xac,0x23,0x12,0x52,0x7d,0x12,0x20,0xc3,0x1b,0xfd,0xda,0xf8,0x22,0x2e, +0x14,0x26,0x33,0x6d,0x0, 0x12,0x51,0x5d,0x7e,0x34,0x0, 0x38,0x22,0x2e,0x14,0x1, +0x40,0x6d,0x0, 0x7e,0x18,0x3, 0x70,0x22,0x2e,0x14,0x0, 0x60,0x6d,0x0, 0x7e,0x18, +0x34,0x0, 0x22,0xca,0xd8,0xca,0x79,0x7e,0xd0,0xe, 0x7e,0xe0,0x19,0x7e,0x73,0x2a, +0x74,0xbe,0x70,0x19,0x28,0x4, 0x7c,0xf7,0x80,0x2, 0x7c,0xfe,0x7a,0xd3,0x2a,0x6d, +0x7a,0xe3,0x2a,0x6e,0x7a,0xd3,0x2a,0x71,0x7a,0xe3,0x2a,0x72,0x7a,0xd3,0x2a,0x73, +0x7a,0xe3,0x2a,0x74,0x74,0x1, 0x7a,0xb3,0x2a,0x77,0x7a,0xd3,0x2a,0x6f,0xa, 0x3e, +0x1b,0x34,0x7a,0x73,0x2a,0x70,0x74,0x5, 0x7a,0xb3,0x2a,0x78,0x74,0xff,0x7a,0xb3, +0x2a,0x79,0xa, 0x3d,0xca,0x39,0x7e,0x34,0x60,0x52,0x7e,0x24,0x0, 0xff,0x7e,0x8, +0x2a,0x7a,0x12,0x20,0xc3,0x1b,0xfd,0xa, 0x3f,0xca,0x39,0x7e,0x34,0x60,0x75,0x7e, +0x24,0x0, 0xff,0x7e,0x8, 0x2a,0x9d,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x23, +0xca,0x39,0x7e,0x34,0x60,0xd8,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x21,0x12,0x20, +0xc3,0x1b,0xfd,0x12,0xaa,0xc5,0x12,0x64,0xdf,0x7a,0xd3,0x2a,0x75,0x7a,0xe3,0x2a, +0x76,0x12,0x5d,0x7e,0x74,0x1, 0x12,0x30,0x38,0xe4,0x7a,0xb3,0x2b,0x1, 0x7a,0xb3, +0x2b,0x2, 0x12,0x62,0xab,0x7a,0x37,0x2b,0xd, 0x74,0x3, 0x7a,0xb3,0x2b,0x3, 0xe4, +0x7a,0xb3,0x2b,0x4, 0x74,0x2, 0x7a,0xb3,0x2b,0x5, 0x7e,0x34,0x0, 0xfa,0x7a,0x37, +0x2b,0x7, 0x74,0x4, 0x7a,0xb3,0x2b,0x6, 0x7e,0x34,0x0, 0xf, 0x7a,0x37,0x2b,0x9, +0x7e,0x34,0x20,0x5f,0x7a,0x37,0x2b,0xb, 0x74,0x20,0x7a,0xb3,0x2b,0x62,0x74,0x1, +0x7a,0xb3,0x2b,0x10,0x74,0x20,0x7a,0xb3,0x2b,0x11,0x74,0x4, 0x7a,0xb3,0x2b,0x13, +0x74,0x1e,0x12,0x51,0x32,0xe4,0x7a,0xb3,0x2b,0x1d,0x7a,0xb3,0x2b,0x1e,0x7e,0x34, +0x1, 0xf4,0x7a,0x37,0x2b,0x19,0x74,0x1, 0x7a,0xb3,0x2b,0x12,0x74,0x56,0x7a,0xb3, +0x2b,0x20,0x74,0x4f,0x7a,0xb3,0x2b,0x1f,0x6d,0x33,0x7a,0x37,0x2b,0x15,0x7a,0x37, +0x2b,0x17,0x74,0x3, 0x7a,0xb3,0x2b,0x14,0x7e,0x34,0x0, 0x30,0x7a,0x37,0x2b,0x6a, +0x7a,0xb3,0x2b,0x67,0x7e,0x34,0x0, 0x5, 0x7a,0x37,0x2b,0x68,0xe4,0x7a,0xb3,0x2b, +0x66,0x7e,0x34,0x4, 0x6d,0x7a,0x37,0x2b,0x6c,0x74,0x1, 0x7a,0xb3,0x2b,0x63,0x74, +0x4, 0x7a,0xb3,0x2b,0x64,0xe4,0x7a,0xb3,0x2b,0x65,0x74,0x1, 0x7a,0xb3,0x2b,0x60, +0xe4,0x7a,0xb3,0x2b,0x61,0x7e,0x34,0x20,0x65,0x7a,0x37,0x2b,0x6e,0xa, 0x3e,0xca, +0x39,0x7e,0x34,0x60,0xfb,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x44,0x12,0x20,0xc3, +0x1b,0xfd,0xda,0x79,0xda,0xd8,0x22,0x12,0xa7,0x37,0x2, 0x54,0x2d,0x7e,0xb3,0x37, +0x69,0x60,0xf, 0x74,0x1, 0x7a,0xb3,0x37,0x71,0x7e,0xb3,0x37,0xdf,0x70,0x3, 0x12, +0xa7,0xd0,0x7e,0xb3,0x37,0x71,0xb4,0x1, 0xc, 0x74,0x3, 0x7a,0xb3,0x34,0xc3,0x7e, +0x34,0x14,0x0, 0x80,0x9, 0xe4,0x7a,0xb3,0x34,0xc3,0x7e,0x34,0xa, 0x0, 0x7a,0x37, +0x2a,0x62,0x22,0x7e,0x8, 0x2a,0x6d,0x2, 0x3, 0x8b,0x9, 0x75,0x26,0x35,0x7a,0x73, +0x2b,0x1f,0x22,0xca,0x3b,0x7a,0xd, 0x2e,0x7c,0xcb,0x7e,0xb3,0x2b,0x1d,0xf5,0x32, +0x7e,0xb3,0x2b,0xf, 0xf5,0x33,0x7e,0xd3,0x2b,0x14,0x7e,0xe3,0x2b,0x1f,0x7e,0xf3, +0x2b,0x20,0x7e,0x34,0x0, 0x38,0xca,0x39,0x7e,0x18,0x34,0x0, 0x7e,0x8, 0x24,0xf2, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x18,0x3, 0x70,0x7e, +0x8, 0x25,0x2a,0x12,0x20,0xc3,0x1b,0xfd,0x7c,0xbc,0x12,0x55,0x79,0x74,0x1, 0x7a, +0xb3,0x2b,0x1d,0x74,0x5, 0xac,0xbc,0x12,0x55,0x70,0x74,0x5, 0xac,0xbc,0x12,0x54, +0x6a,0x74,0x5, 0xac,0xbc,0x12,0x55,0x67,0x74,0x5, 0xac,0xbc,0x9, 0x75,0x26,0x37, +0xbe,0x73,0x2b,0x62,0x68,0x6, 0x7a,0x73,0x2b,0x62,0xd2,0x10,0xc2,0x0, 0x12,0x57, +0x85,0x12,0x51,0x3e,0x12,0x3f,0x9e,0x30,0xf, 0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e, +0x14,0x40,0x0, 0x7d,0x31,0x7e,0x2f,0x13,0x86,0x7d,0x25,0x7e,0x4, 0xd, 0xc8,0x12, +0x56,0x2d,0x12,0x57,0xe5,0xa4,0x7a,0x55,0x34,0x7e,0xd, 0x2e,0x7e,0x18,0xd, 0xc8, +0x12,0x5d,0xf1,0x12,0xb5,0xa7,0xe5,0x32,0x7a,0xb3,0x2b,0x1d,0xe5,0x33,0x7a,0xb3, +0x2b,0xf, 0x7a,0xd3,0x2b,0x14,0x7a,0xe3,0x2b,0x1f,0x7a,0xf3,0x2b,0x20,0x7e,0x34, +0x0, 0x38,0xca,0x39,0x7e,0x18,0x24,0xf2,0x7e,0x8, 0x34,0x0, 0x12,0x20,0xc3,0x1b, +0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x18,0x25,0x2a,0x7e,0x8, 0x3, 0x70,0x12, +0x20,0xc3,0x1b,0xfd,0xda,0x3b,0x22,0x9, 0x75,0x26,0x36,0x7a,0x73,0x2b,0x20,0x22, +0x9, 0x75,0x26,0x34,0x7a,0x73,0x2b,0x14,0x22,0xca,0xf8,0x7c,0xfb,0x7e,0x34,0x0, +0x38,0xca,0x39,0xac,0x7f,0x2e,0x34,0x0, 0x60,0x6d,0x22,0x7e,0x8, 0x34,0x0, 0x12, +0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0xac,0x7f,0x2e,0x34,0x1, 0x40, +0x6d,0x22,0x7e,0x8, 0x3, 0x70,0x12,0x20,0xc3,0x1b,0xfd,0xda,0xf8,0x22,0xca,0x3b, +0x7e,0xb3,0x2b,0xf, 0x7a,0xb3,0x1f,0x33,0x7e,0xf3,0x2b,0x62,0x12,0x8b,0x1a,0x7c, +0xdb,0xbe,0xd0,0xff,0x68,0x64,0x6c,0xcc,0x12,0x57,0x85,0xf5,0x29,0x7e,0x73,0x2b, +0xf, 0xbe,0x71,0x29,0x68,0x36,0x7e,0x70,0x4, 0xac,0x7d,0xa, 0x2c,0x12,0x88,0x56, +0x7c,0xeb,0xbe,0xe0,0x2, 0x38,0x43,0xa, 0xe, 0x7e,0x14,0x2, 0xe0,0xad,0x10,0x2e, +0x14,0x16,0x93,0x6d,0x0, 0x7a,0xd, 0x2a,0x7e,0x70,0x1d,0xac,0x7e,0x2e,0x34,0x38, +0x45,0x6d,0x22,0x7a,0x1f,0x38,0x41,0x7c,0xbc,0x12,0x54,0x73,0xb, 0xc0,0xbe,0xc0, +0x4, 0x40,0xb5,0x7e,0x73,0x2b,0x62,0xbc,0x7f,0x68,0x6, 0x7a,0xf3,0x2b,0x62,0xd2, +0x10,0xd2,0x0, 0x7e,0xb3,0x1f,0x33,0x12,0x51,0x3e,0xda,0x3b,0x22,0x7e,0xb3,0x2a, +0x6d,0xca,0x3b,0x7c,0xdb,0x7a,0x5, 0x38,0x7d,0x71,0x7a,0x25,0x36,0x7a,0x35,0x34, +0x12,0x57,0x8e,0x50,0x7b,0x6c,0xcc,0x80,0x13,0x7e,0x73,0x2a,0x6e,0x12,0x57,0x57, +0x12,0x57,0x3d,0x7e,0x34,0x34,0x0, 0x12,0x57,0x60,0xb, 0xc0,0x12,0x57,0x75,0x38, +0xe8,0x6c,0xcc,0x80,0x55,0x7e,0xa3,0x2a,0x6e,0x7c,0x7a,0x12,0x57,0x57,0x75,0x3a, +0x0, 0x80,0x27,0x7e,0xb3,0x38,0xb2,0xbe,0xb1,0x3a,0x7e,0x70,0x4, 0x28,0x8, 0xac, +0x7c,0x49,0x43,0x3, 0x70,0x80,0x6, 0xac,0x7c,0x49,0x43,0x3, 0x72,0x7e,0x71,0x3a, +0x74,0x2, 0xac,0x7b,0x59,0x43,0x34,0x50,0x5, 0x3a,0x7e,0xb3,0x2a,0x70,0xbe,0xb1, +0x3a,0x38,0xd0,0x7e,0x34,0x10,0x0, 0x74,0x2, 0xa4,0x59,0x35,0x34,0x4e,0x12,0x57, +0x3d,0x7e,0x34,0x34,0x50,0x12,0x57,0x60,0xb, 0xc0,0xbc,0xdc,0x38,0xa7,0x80,0x2c, +0x7a,0xd3,0x25,0xb6,0x7e,0x73,0x2a,0x70,0x7a,0x73,0x25,0xb7,0xe4,0x7a,0xb3,0x25, +0xb9,0x74,0x6, 0x7a,0xb3,0x25,0xb8,0x7a,0x77,0x25,0xba,0x7a,0x77,0x25,0xbe,0x7e, +0x8, 0x25,0xb6,0x7e,0x73,0x2b,0x1f,0xa, 0x37,0x12,0xe, 0x37,0x7d,0x37,0x12,0x6f, +0xfa,0x7e,0x35,0x38,0x7a,0x37,0x25,0xbe,0xe4,0x7a,0xb3,0x25,0xb8,0x12,0x57,0x4e, +0x7a,0xd3,0x25,0xb6,0x7e,0xb3,0x2b,0x1d,0x70,0xf, 0xe4,0x7a,0xb3,0x25,0xb9,0x7a, +0x77,0x25,0xba,0x7e,0x34,0x0, 0x20,0x80,0x16,0x74,0x1, 0x7a,0xb3,0x25,0xb9,0x7e, +0x35,0x34,0x7a,0x37,0x25,0xba,0x7e,0x35,0x36,0x7a,0x37,0x25,0xbc,0x6d,0x33,0x7a, +0x37,0x25,0xc0,0x7e,0x8, 0x25,0xb6,0x12,0xd, 0x7, 0xda,0x3b,0x22,0x74,0xc, 0x7a, +0xb3,0x25,0xb8,0x74,0x1, 0x7a,0xb3,0x25,0xb6,0xe4,0x7a,0xb3,0x25,0xb9,0x7e,0x73, +0x2a,0x6e,0x7a,0x73,0x25,0xb7,0x22,0xac,0x7c,0x3e,0x34,0x7d,0xf7,0x2d,0xf3,0x22, +0x7a,0x37,0x25,0xba,0x7d,0x3f,0x7a,0x37,0x25,0xbc,0x7a,0x37,0x25,0xbe,0x7e,0x8, +0x25,0xb6,0x2, 0x7, 0x9b,0x7e,0x73,0x2a,0x6f,0xbc,0x7c,0x22,0x9, 0x75,0x26,0x33, +0x7a,0x73,0x2b,0xf, 0x22,0x74,0x5, 0xac,0xbc,0x9, 0xb5,0x26,0x33,0x22,0x7e,0xb3, +0x38,0x9, 0xb4,0x3, 0x8, 0x7e,0xb3,0x38,0xb3,0x70,0x2, 0xc3,0x22,0xd3,0x22,0x12, +0xa7,0xf9,0x6d,0x33,0x7a,0x37,0x37,0xdd,0x6c,0xaa,0x12,0xaa,0x88,0xb, 0xa0,0xbe, +0xa0,0x4, 0x40,0xf6,0xe4,0x7a,0xb3,0x37,0x72,0x22,0x7e,0xa3,0x2b,0x62,0xbc,0xab, +0x68,0x6, 0x7a,0xb3,0x2b,0x62,0xd2,0x10,0x30,0x10,0x9, 0xc2,0x10,0x12,0x57,0xd5, +0xe4,0x2, 0xa, 0x66,0x22,0x7e,0x8, 0x2a,0x6d,0x12,0x3, 0x8b,0x7e,0x8, 0x2a,0x6d, +0x74,0x3, 0x2, 0x11,0x7a,0x7e,0xa3,0x2a,0x6e,0x7e,0xb3,0x2a,0x6d,0x22,0xe4,0x7a, +0xb3,0x37,0x69,0x7a,0xb3,0x37,0x71,0x22,0x7e,0xb3,0x2b,0xf, 0xca,0x3b,0x7c,0xeb, +0x6c,0xff,0x7e,0xc4,0x1, 0xf4,0x7e,0x73,0x38,0xce,0xa, 0xb7,0x7e,0xb3,0x2b,0x10, +0xf5,0x34,0x75,0x35,0x4, 0xe4,0x7a,0xb3,0x37,0x72,0xa, 0x3e,0xad,0x3b,0x7d,0xa3, +0x2d,0xac,0x6c,0xdd,0x7e,0xa3,0x37,0x72,0xbe,0xa1,0x35,0x40,0x2, 0x80,0x19,0xbe, +0xa0,0x0, 0x28,0x19,0x74,0x5, 0xa4,0x9, 0x75,0x26,0x33,0xbc,0x7e,0x78,0xe, 0xe5, +0x35,0x14,0xbe,0xb3,0x37,0x72,0x78,0x5, 0xe4,0x7a,0xb3,0x37,0x72,0x7e,0xc3,0x37, +0x72,0x80,0x3a,0x7e,0xb3,0x37,0x72,0x4, 0x7a,0xb3,0x37,0x72,0x74,0x5, 0xac,0xbc, +0x9, 0x75,0x26,0x33,0xbc,0x7e,0x68,0x23,0xa, 0xdd,0x19,0xcd,0x37,0x76,0xa, 0x97, +0xad,0x9b,0x2d,0x9c,0x7c,0xad,0xb, 0xd0,0x7c,0xba,0x7d,0x39,0x7d,0x2a,0x7e,0x31, +0x34,0x12,0x10,0x0, 0xb, 0xf0,0xbe,0xf0,0x3, 0x50,0x8, 0xb, 0xc0,0xe5,0x35,0xbc, +0xbc,0x38,0xc0,0x7a,0xf3,0x37,0x73,0xda,0x3b,0x22,0x74,0xa, 0x7a,0xb3,0x2a,0x4d, +0x74,0x10,0x7a,0xb3,0x2a,0x4e,0x12,0x47,0xf8,0x7a,0x37,0x2a,0x55,0x74,0x14,0x7a, +0xb3,0x2a,0x59,0x12,0x5d,0xde,0x7e,0x24,0x0, 0x78,0x7a,0x27,0x2a,0x5c,0x7e,0x24, +0xff,0x6a,0x7a,0x27,0x2a,0x5e,0x7a,0x37,0x2a,0x60,0xe4,0x7a,0xb3,0x2a,0x64,0x74, +0x4, 0x7a,0xb3,0x2a,0x65,0x7e,0x34,0x0, 0x64,0x7a,0x37,0x2a,0x66,0x7e,0x34,0xa, +0x0, 0x7a,0x37,0x2a,0x62,0xe4,0x7a,0xb3,0x2a,0x6b,0x7a,0xb3,0x16,0x92,0x22,0x12, +0x5c,0x95,0x12,0x52,0x93,0x12,0x0, 0x42,0x12,0x5d,0xd5,0x7e,0x18,0x4, 0x0, 0x7a, +0x1f,0x6, 0xf8,0x7e,0xf, 0x6, 0xf8,0x7e,0x1f,0x6, 0xf4,0x12,0x65,0x54,0x7e,0x18, +0x8, 0xa, 0x7a,0x1f,0x13,0x86,0x7e,0x18,0xd, 0xc8,0x7a,0x1f,0x13,0x8a,0x7e,0xf, +0x13,0x8a,0x7e,0x1f,0x13,0x86,0x12,0x5f,0xd5,0x12,0x59,0x46,0x12,0x58,0x9a,0x12, +0x64,0xb0,0x12,0x59,0x8e,0x2, 0x59,0x38,0xe4,0x7a,0xb3,0x34,0x38,0x7a,0xb3,0x34, +0x39,0x7a,0xb3,0x34,0x3a,0x22,0x2, 0x59,0x49,0x7e,0x34,0x0, 0xfa,0x7a,0x37,0x28, +0x95,0x7e,0x34,0x2, 0x26,0x7a,0x37,0x28,0x99,0x7e,0x34,0x0, 0x96,0x7a,0x37,0x28, +0x97,0x7a,0x37,0x28,0x9b,0x7e,0x34,0x0, 0x50,0x7a,0x37,0x28,0x9d,0x7e,0x34,0x0, +0x2b,0x7a,0x37,0x28,0x9f,0x12,0x5f,0xc8,0x74,0x1, 0x7a,0xb3,0x28,0xa5,0xe4,0x7a, +0xb3,0x28,0xa8,0x7e,0x8, 0x25,0xf7,0x7e,0x34,0x0, 0x3c,0x2, 0x20,0xe8,0x7e,0x8, +0x28,0xae,0x7e,0x34,0x1, 0xe, 0x74,0xff,0x12,0x20,0xe8,0x12,0x5f,0xbc,0x7e,0x8, +0x29,0xbc,0x12,0x59,0xb1,0x7e,0x8, 0x2a,0x2, 0x7e,0x34,0x0, 0xb, 0xe4,0x2, 0x20, +0xe8,0x6c,0xaa,0x74,0x3, 0x12,0x5d,0xe7,0x7f,0x10,0x2d,0x34,0x39,0xb1,0x0, 0xa, +0x12,0x59,0xd9,0x7f,0x70,0x2d,0xf3,0x79,0x47,0x0, 0x14,0x2d,0x31,0x79,0x41,0x0, +0x28,0xb, 0xa0,0xbe,0xa0,0xa, 0x40,0xdb,0x22,0x7e,0x44,0x7f,0xff,0x7e,0x70,0x2, +0xac,0x7a,0x22,0xca,0xf8,0x7e,0x68,0x29,0xbc,0x6c,0xaa,0x7e,0x70,0xff,0x12,0x5c, +0x74,0xe4,0xa, 0x4a,0x19,0xb4,0x1f,0x34,0x74,0xff,0x19,0xb4,0x1f,0x46,0x19,0xb4, +0x1f,0x50,0xb, 0xa0,0xbe,0xa0,0xa, 0x78,0xe2,0x7e,0x73,0x2a,0x2, 0xa5,0xbf,0x0, +0x21,0x7e,0xb3,0x34,0x4f,0x70,0x2, 0x61,0xe2,0x6c,0xaa,0x7e,0x44,0x7f,0xff,0x12, +0x5c,0x7e,0x79,0x40,0x0, 0x14,0x12,0x5c,0x6b,0xb, 0xa0,0xbe,0xa0,0xa, 0x78,0xeb, +0x61,0xe2,0x7e,0xb3,0x34,0x4f,0x70,0x3d,0xbe,0x70,0x0, 0x28,0x38,0x6c,0xaa,0x80, +0x2a,0x7e,0x90,0x9, 0xac,0x9a,0x49,0x34,0x28,0xae,0x12,0x5c,0x7e,0x79,0x30,0x0, +0x14,0x49,0x34,0x28,0xb0,0x7f,0x6, 0x2d,0x12,0x79,0x30,0x0, 0x28,0x74,0x1, 0xa, +0x3a,0x19,0xb3,0x1f,0x34,0x19,0xa4,0x28,0xb2,0xb, 0xa0,0x7e,0xb3,0x2a,0x2, 0xbc, +0xba,0x38,0xce,0x61,0xe2,0x6c,0xaa,0x12,0x59,0xd9,0x3e,0x34,0x59,0x43,0x15,0x4e, +0x59,0x43,0x15,0x50,0x59,0x43,0x15,0x76,0x59,0x43,0x15,0x78,0xb, 0xa0,0xbe,0xa0, +0xa, 0x78,0xe4,0x6c,0xaa,0x80,0x3b,0x6c,0xff,0x7e,0x70,0x2, 0xac,0x7f,0x7f,0x6, +0x2d,0x13,0x69,0x30,0x0, 0x14,0xbe,0x34,0x7f,0xff,0x68,0x1d,0xa, 0x4f,0x9, 0xb4, +0x1f,0x50,0xb4,0xff,0x14,0x12,0x5c,0x63,0x59,0x32,0x15,0x4e,0x69,0x30,0x0, 0x28, +0x59,0x32,0x15,0x50,0x12,0x5c,0x88,0x80,0x7, 0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xc9, +0xb, 0xa0,0x7e,0xb3,0x34,0x4f,0xbc,0xba,0x38,0xbd,0x6c,0xaa,0xa, 0x3a,0x9, 0xb3, +0x1f,0x46,0xb4,0xff,0x17,0x6c,0xff,0xa, 0x4f,0x9, 0xb4,0x1f,0x50,0xb4,0xff,0x5, +0x12,0x5c,0x88,0x80,0x7, 0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xeb,0xb, 0xa0,0xbe,0xa0, +0xa, 0x78,0xd9,0x6c,0xaa,0x80,0x1a,0x7e,0x70,0x9, 0xac,0x7a,0x49,0x43,0x28,0xae, +0x12,0x5c,0x63,0x59,0x42,0x15,0x76,0x49,0x33,0x28,0xb0,0x59,0x32,0x15,0x78,0xb, +0xa0,0x7e,0xb3,0x2a,0x2, 0xbc,0xba,0x38,0xde,0x7e,0x34,0x15,0x4e,0x7a,0x37,0x1f, +0x40,0x7e,0x34,0x15,0x76,0x7a,0x37,0x1f,0x42,0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f, +0x44,0x7e,0x73,0x34,0x4f,0x7a,0x73,0x1f,0x3e,0x7e,0x73,0x2a,0x2, 0x7a,0x73,0x1f, +0x3f,0x7e,0x8, 0x1f,0x3e,0x12,0x4, 0xad,0x6c,0xaa,0x80,0x57,0x7e,0x70,0xff,0x6c, +0xff,0x7e,0x50,0x2, 0xac,0x5f,0x49,0x12,0x15,0x9e,0xa, 0x2a,0xbd,0x21,0x78,0x8, +0xa, 0x3f,0x9, 0x73,0x1f,0x46,0x80,0x7, 0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xe2,0xbe, +0x70,0xff,0x68,0x2d,0x12,0x5c,0x74,0x74,0x1, 0xa, 0x47,0x19,0xb4,0x1f,0x34,0x7e, +0x90,0x9, 0xac,0x9a,0x49,0x24,0x28,0xae,0x7e,0x30,0x2, 0xac,0x37,0x2d,0x1d,0x7d, +0xc, 0x79,0x20,0x0, 0x14,0x49,0x44,0x28,0xb0,0x7e,0x50,0x2, 0xac,0x57,0x12,0x5c, +0x6b,0xb, 0xa0,0x7e,0x63,0x2a,0x2, 0xbc,0x6a,0x38,0xa1,0x6c,0xaa,0xa, 0x3a,0x9, +0xb3,0x1f,0x34,0xbe,0xb0,0x1, 0x68,0x13,0x12,0x59,0xd9,0x7f,0x6, 0x2d,0x13,0x79, +0x40,0x0, 0x14,0x2d,0x3d,0x7d,0x2c,0x79,0x41,0x0, 0x28,0xb, 0xa0,0xbe,0xa0,0xa, +0x78,0xdb,0x7e,0xf3,0x2a,0x2, 0x7a,0xf3,0x34,0x4f,0x6c,0xaa,0xa, 0x3a,0x9, 0xb3, +0x1f,0x34,0xb4,0x1, 0x2c,0x12,0x5c,0x5c,0x29,0xb1,0x0, 0xa, 0xb4,0x1, 0x6, 0x74, +0x3, 0x39,0xb1,0x0, 0xa, 0x12,0x5c,0x5c,0x29,0x31,0x0, 0xa, 0xa5,0xbb,0x3, 0x6, +0xe4,0x7a,0x1b,0xb0,0x80,0x32,0xa5,0xbb,0x0, 0x2e,0x74,0x2, 0x7a,0x1b,0xb0,0x80, +0x27,0x12,0x5c,0x5c,0x29,0xb1,0x0, 0xa, 0xbe,0xb0,0x2, 0x68,0x2, 0x70,0x14,0x74, +0x1, 0x7a,0x1b,0xb0,0x7c,0x2f,0xb, 0xf0,0x7e,0x30,0x9, 0xac,0x23,0x19,0xa1,0x28, +0xb2,0x80,0x5, 0x74,0x3, 0x7a,0x1b,0xb0,0x12,0x5c,0x5c,0x7e,0x1b,0xb0,0x39,0xb1, +0x0, 0xa, 0xb, 0xa0,0xbe,0xa0,0xa, 0x40,0x93,0xda,0xf8,0x22,0xa, 0x3a,0x2d,0x3d, +0x7d,0x2c,0x22,0x7e,0x50,0x2, 0xac,0x5a,0x3e,0x24,0x22,0x7f,0x6, 0x2d,0x12,0x79, +0x40,0x0, 0x28,0x22,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x72,0x28,0xb2,0x22,0x7e,0x50, +0x2, 0xac,0x5a,0x7f,0x6, 0x2d,0x12,0x22,0xa, 0x3a,0x19,0xf3,0x1f,0x46,0x74,0x1, +0x19,0xb4,0x1f,0x50,0x22,0xe4,0x7a,0xb3,0x38,0x9d,0x7a,0xb3,0x38,0x9e,0x74,0xe, +0x7a,0xb3,0x38,0x9f,0x74,0x19,0x7a,0xb3,0x38,0xa0,0xe4,0x7a,0xb3,0x38,0xa1,0x74, +0xa, 0x7a,0xb3,0x38,0xa2,0xe4,0x7a,0xb3,0x38,0xa3,0x7a,0xb3,0x38,0xa4,0x74,0x1, +0x7a,0xb3,0x38,0xa6,0x74,0x25,0x7a,0xb3,0x38,0xaa,0x74,0x3e,0x7a,0xb3,0x38,0xab, +0x74,0x64,0x7a,0xb3,0x38,0xbc,0x74,0x4, 0x7a,0xb3,0x38,0xbd,0xe4,0x7a,0xb3,0x38, +0xa9,0x74,0x4f,0x7a,0xb3,0x38,0xbf,0x74,0x56,0x7a,0xb3,0x38,0xbe,0x74,0x3, 0x7a, +0xb3,0x38,0xc0,0x74,0x40,0x7a,0xb3,0x38,0xbb,0xe4,0x7a,0xb3,0x38,0xb6,0x74,0xfa, +0x7a,0xb3,0x38,0xb4,0x74,0x1e,0x7a,0xb3,0x38,0xb5,0x74,0x1, 0x7a,0xb3,0x38,0xb3, +0x74,0xd, 0x7a,0xb3,0x38,0xb2,0x74,0x1, 0x7a,0xb3,0x38,0xb7,0xe4,0x7a,0xb3,0x38, +0xb8,0x7a,0xb3,0x38,0xb9,0x7e,0x8, 0x38,0xc1,0x7e,0x34,0x0, 0x2c,0x12,0x20,0xe8, +0x74,0x1, 0x7a,0xb3,0x38,0xcc,0x74,0xf4,0x7a,0xb3,0x38,0xcd,0x74,0x19,0x7a,0xb3, +0x38,0xce,0x74,0x1e,0x7a,0xb3,0x38,0xcf,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,0x5d, +0xcc,0x7e,0x8, 0x38,0xdd,0x12,0x20,0xc3,0x1b,0xfd,0x74,0x5, 0x7a,0xb3,0x38,0xea, +0x74,0x1, 0x7a,0xb3,0x38,0xe1,0x7e,0x34,0x0, 0x28,0xca,0x39,0x7e,0x34,0x61,0xdb, +0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x26,0x33,0x12,0x20,0xc3,0x1b,0xfd,0x22,0x7e,0x34, +0x0, 0x4, 0xca,0x39,0x7e,0x34,0x61,0x2d,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x70, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x2a,0xe, 0x7a,0x37,0x2b,0x76,0xe4,0x7a,0xb3, +0x2b,0x74,0x7a,0xb3,0x2b,0x75,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,0x5d,0xcc,0x7e, +0x8, 0x25,0xee,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x2b,0x78,0x7a,0x37,0x25,0xf4, +0xe4,0x7a,0xb3,0x25,0xf2,0x74,0x1, 0x7a,0xb3,0x25,0xf3,0x22,0x7e,0x34,0x61,0x29, +0x7e,0x24,0x0, 0xff,0x22,0x7e,0x18,0x5, 0xf8,0x7a,0x1f,0x6, 0xf4,0x22,0x7e,0x34, +0x0, 0x96,0x7a,0x37,0x2a,0x5a,0x22,0xa, 0x4a,0x7f,0x10,0x2d,0x34,0x7a,0x1b,0xb0, +0x22,0xca,0xf8,0x7f,0x71,0x6d,0xdd,0x6c,0xaa,0x7e,0xf0,0x80,0xc2,0x0, 0x6d,0x44, +0x80,0x32,0x12,0x5e,0x92,0x12,0x5e,0xa3,0xbd,0x3d,0x48,0x26,0x12,0x5e,0x92,0xb, +0x1a,0x30,0xbe,0x34,0x0, 0x0, 0x8, 0x4, 0xd2,0x0, 0x80,0x9, 0x12,0x21,0xa, 0xbd, +0x3d,0x68,0x2, 0xc2,0x0, 0x7d,0x34,0x3e,0x34,0x2d,0x3f,0x7d,0x2e,0x12,0x5e,0xa3, +0x7d,0xd3,0xb, 0x44,0x7e,0xc5,0x34,0xbd,0xc4,0x38,0xc7,0x30,0x0, 0xc, 0x7e,0xf0, +0x7f,0x80,0x7, 0xb, 0xa0,0xbe,0xa0,0x8, 0x50,0x11,0x7c,0xba,0x7d,0x3d,0x60,0x5, +0xe, 0x34,0x14,0x78,0xfb,0xa, 0xcf,0xbd,0x3c,0x18,0xe8,0x7f,0x10,0x2e,0x35,0x34, +0x7a,0x1b,0xa0,0x6d,0x44,0x80,0x21,0x7d,0x54,0x3e,0x54,0x7f,0x17,0x2d,0x35,0xb, +0x1a,0x30,0x7f,0x60,0x2e,0xd5,0x34,0x7e,0x6b,0xb0,0x60,0x5, 0xe, 0x34,0x14,0x78, +0xfb,0x7c,0xb7,0x12,0x5d,0xe9,0xb, 0x44,0x7e,0x55,0x34,0xbd,0x54,0x38,0xd8,0xda, +0xf8,0x22,0x7d,0xc4,0x3e,0xc4,0x7f,0x17,0x2d,0x3c,0x22,0x74,0x2, 0xac,0xbe,0x7f, +0x17,0x2d,0x35,0xb, 0x1a,0x30,0x2, 0x21,0xa, 0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f, +0x70,0xc2,0x0, 0x6c,0xdd,0x6d,0xdd,0x7e,0x34,0x23,0x5, 0x7e,0x24,0x0, 0xff,0x7e, +0x14,0x1f,0x7a,0x74,0xc, 0x12,0x1f,0xad,0x6d,0x11,0x7e,0x4, 0x7f,0xff,0x6c,0xee, +0x80,0x13,0x12,0x5e,0x9b,0x7d,0xc3,0xbd,0xdc,0x50,0x2, 0x7d,0xdc,0xbd,0xc, 0x28, +0x2, 0x7d,0xc, 0xb, 0xe0,0xbc,0xfe,0x38,0xe9,0xbe,0xd4,0x0, 0x1e,0x58,0xa, 0x7e, +0xb3,0x28,0x94,0x70,0x4, 0x6d,0x33,0xe1,0xa4,0xbe,0xd4,0x4, 0xb0,0x8, 0x2, 0xd2, +0x0, 0x6c,0xee,0x74,0x4, 0xac,0xbe,0x49,0x45,0x1f,0x7a,0xbd,0x4d,0x58,0x6, 0x49, +0xd5,0x1f,0x7c,0x80,0x7, 0xb, 0xe0,0xbe,0xe0,0x3, 0x40,0xe7,0xbe,0xe0,0x3, 0x78, +0x4, 0x6d,0x33,0x80,0x7f,0xbd,0xd, 0x8, 0x5, 0x30,0x0, 0x2, 0x7d,0xd0,0x9f,0x55, +0x6c,0xee,0x80,0xb, 0x12,0x5e,0x9b,0x1a,0x26,0x1a,0x24,0x2f,0x51,0xb, 0xe0,0xbc, +0xfe,0x38,0xf1,0xa, 0x1f,0x12,0x5f,0xb2,0x9f,0x55,0x6c,0xee,0x80,0x1d,0x12,0x5f, +0xa9,0xb, 0x1a,0x90,0x7d,0x39,0x12,0x21,0xa, 0x7d,0xc3,0xbd,0x1c,0x28,0xa, 0x7d, +0x39,0x1a,0x26,0x1a,0x24,0x2f,0x51,0xb, 0xd0,0xb, 0xe0,0xbc,0xfe,0x38,0xdf,0x6d, +0x11,0xbe,0xd0,0x0, 0x28,0x5, 0xa, 0x1d,0x12,0x5f,0xb2,0xbd,0x1d,0x8, 0x4, 0x7d, +0x1d,0x80,0xa, 0x6d,0x0, 0x9d,0xd, 0xbd,0x1, 0x8, 0x2, 0x7d,0x10,0x6c,0xee,0x80, +0xd, 0x12,0x5f,0xa9,0xb, 0x1a,0x0, 0x9d,0x1, 0x1b,0x1a,0x0, 0xb, 0xe0,0xbc,0xfe, +0x38,0xef,0x7d,0x31,0xda,0x79,0xda,0xd8,0x22,0x74,0x2, 0xac,0xbe,0x7f,0x17,0x2d, +0x35,0x22,0x6d,0x0, 0x7f,0x15,0x12,0x1f,0x58,0x7d,0x13,0x22,0x7e,0x8, 0x34,0xb7, +0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x20,0xe8,0x7e,0x34,0x0, 0x4, 0x7a,0x37,0x28,0xa1, +0x7a,0x37,0x28,0xa3,0x22,0x7f,0x60,0x7e,0xa3,0x2a,0x6d,0x7e,0xb3,0x2a,0x6e,0xa4, +0x7d,0xf5,0x3e,0xf4,0x7f,0x1, 0x7d,0x3f,0xe4,0x12,0x20,0xe8,0x7f,0x6, 0x7d,0x3f, +0x12,0x20,0xe8,0x7a,0xb3,0x16,0x91,0x22,0x7e,0xb3,0x2a,0x73,0xbc,0xba,0x22,0xff, +0x70,0x8f,0x0, 0xff,0x3b,0xc4,0x5a,0xa5,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x31,0x36,0x31,0x1, 0xc6,0x1, 0x31,0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0xa, 0xf5,0x43,0x36,0x5f,0x42,0x69,0x65,0x6c,0x5f,0x57,0x0, 0x0, 0x0, 0x0, 0x0, +0xe, 0x19,0x6, 0x5, 0x4, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x3, 0x2, 0x1, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16, +0x17,0x18,0xb, 0x5, 0xa, 0x4, 0x9, 0x3, 0x8, 0x2, 0x7, 0x1, 0x6, 0x0, 0x0, 0x0, +0x0, 0x5, 0x0, 0x4, 0xff,0x23,0x1c,0x2, 0xdf,0xa, 0x1e,0xa, 0x64,0x14,0x10,0x0, +0x4, 0x0, 0x64,0xd, 0xac,0x0, 0xc8,0x3, 0x1, 0x0, 0x0, 0x18,0x2, 0x7, 0xb, 0x0, +0x0, 0x0, 0x96,0x0, 0xf0,0x1, 0xcc,0x2, 0x8a,0x3, 0x48,0x3, 0xa2,0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8,0x1, 0xf4,0x3, 0x20,0x0, 0x0, 0x0, 0x0, 0x7, +0xf8,0x0, 0x14,0x1, 0x19,0x1e,0x1, 0xf4,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x0, 0x4, 0x4f,0x20,0x1, 0x20,0x3, 0x0, 0x0, +0x0, 0x0, 0x1, 0xf4,0x56,0x40,0xe, 0x19,0x27,0x1c,0xf, 0x6, 0x60,0x1c,0xf, 0x6, +0x70,0x8, 0x10,0x4, 0x20,0x1, 0x0, 0x4, 0x38,0x44,0x44,0x2, 0x36,0x2, 0x4a,0x1, +0x39,0x1, 0x3b,0x7, 0x80,0x4a,0x4d,0x2, 0x57,0x2, 0x52,0x1, 0x44,0x1, 0x43,0x0, +0x96,0x0, 0x78,0x0, 0x96,0x0, 0xfa,0x0, 0x7d,0x0, 0xfa,0x0, 0xfa,0xa, 0x0, 0x0, +0xa8,0xa, 0x10,0x1e,0x32,0x1, 0xf, 0xb, 0x1e,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22,0x15, +0x0, 0x1, 0x54,0x1, 0x0, 0xa, 0x1, 0x3b,0x1, 0x14,0x0, 0x5a,0x1, 0x1, 0xe, 0x0, +0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55,0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, +0x2, 0x26,0x0, 0x50,0x0, 0x2b,0x0, 0x4, 0x0, 0x4, 0x1, 0x4, 0x1, 0x90,0x0, 0xc8, +0x0, 0x50,0x1, 0xf4,0x0, 0x96,0x1, 0x2c,0x1, 0x2c,0x4, 0x1e,0x3, 0x4f,0x56,0x20, +0x25,0x3, 0x51,0x5b,0x20,0x2a,0x3, 0x54,0x5e,0x20,0x3c,0x2, 0x52,0x76,0x20,0x1e, +0x3, 0x4f,0x56,0x20,0x1e,0x3, 0x4f,0x56,0x20,0x1e,0x3, 0x4f,0x56,0x20,0x1e,0x3, +0x4f,0x56,0x20,0x4, 0x5, 0xf, 0x10,0x11,0x12,0x13,0x4, 0x0, 0xbb,0x4, 0xe2,0x2d, +0x0, 0xc8,0x1, 0x5e,0x0, 0x64,0x0, 0x64,0x0, 0x96,0x0, 0x64,0xb, 0xb8,0x8, 0x5, +0x6, 0x80,0x1, 0x90,0x1, 0x2c,0x1, 0xc2,0x3, 0x20,0xf, 0xa0,0x1, 0x3, 0x20,0x4, +0xb0,0x3, 0x20,0x1, 0x2, 0x2, 0x4, 0x4, 0x6, 0x40,0x0, 0xf0,0x0, 0xc8,0x1, 0x40, +0x1, 0x40,0x1, 0x2c,0x1, 0x18,0x0, 0xfa,0x1, 0x40,0x1, 0x40,0x1, 0x7c,0x0, 0x32, +0x0, 0x28,0x0, 0x78,0x0, 0x64,0x0, 0x64,0x0, 0x78,0x0, 0x78,0x14,0xa, 0x0, 0x50, +0x3, 0xe8,0x0, 0x50,0x7, 0x30,0x0, 0x14,0x1, 0xf4,0x1, 0xf4,0x3, 0x20,0x0, 0x64, +0x0, 0x4d,0x0, 0x1e,0x0, 0x80,0x1, 0xe, 0x0, 0xf0,0x0, 0x3c,0x3, 0xe8,0x1, 0xe0, +0x0, 0x87,0x0, 0x3c,0x3, 0xe8,0x0, 0x20,0x4, 0x18,0x0, 0x0, 0x7, 0x80,0x0, 0x64, +0x0, 0xa0,0x0, 0xa0,0x13,0x88,0x1, 0x2c,0x0, 0xa0,0x0, 0xa0,0x10,0x0, 0xc, 0x0, +0xb, 0xc, 0x5, 0x6, 0x8, 0x9, 0x6, 0x6, 0xc, 0x64,0xc8,0x6d,0x33,0x6c,0xaa,0x80, +0x14,0xa, 0x2a,0x9, 0xb2,0x2a,0xdc,0x54,0x1, 0x78,0x5, 0x4e,0x70,0x1, 0x80,0x3, +0x4e,0x70,0x10,0xb, 0xa0,0x7e,0x53,0x2a,0x74,0xbc,0x5a,0x38,0xe4,0x6c,0xaa,0x80, +0x1f,0xa, 0x2a,0x9, 0xb2,0x2a,0xb9,0xbe,0xb0,0xd, 0x38,0x5, 0x4e,0x70,0xc0,0x80, +0xd, 0xbe,0xb0,0x1b,0x38,0x5, 0x4e,0x60,0x8, 0x80,0x3, 0x4e,0x60,0x50,0xb, 0xa0, +0x12,0x5f,0xf8,0x38,0xdc,0x22,0x7e,0x54,0x0, 0x54,0x7e,0x44,0x0, 0xff,0x69,0x32, +0x0, 0x4, 0x69,0x22,0x0, 0x2, 0xb, 0x2a,0x10,0x7a,0x1d,0x26,0x7a,0x15,0x24,0x7e, +0x34,0x0, 0x20,0x7e,0x8, 0x0, 0x24,0x7e,0x24,0x0, 0x6, 0x12,0x63,0x62,0x74,0x25, +0x7a,0xb3,0x37,0xe2,0x74,0x1e,0x7a,0xb3,0x37,0xe3,0x74,0xf, 0x7a,0xb3,0x37,0xe4, +0x7a,0xb3,0x37,0xe5,0x7a,0xb3,0x37,0xe6,0x74,0xa0,0x7a,0xb3,0x37,0xe7,0x7e,0x34, +0x0, 0x59,0xca,0x39,0x7e,0x34,0x61,0x65,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x37,0xe8, +0x12,0x20,0xc3,0x1b,0xfd,0xe5,0x25,0x7a,0xb3,0x38,0x13,0xe5,0x28,0x7a,0xb3,0x38, +0x2, 0x22,0x7d,0x42,0x7f,0x60,0x7d,0x3, 0x12,0x64,0x60,0x74,0x2, 0x12,0x63,0x9c, +0x7d,0xf3,0x4e,0xf4,0x0, 0x1, 0x4e,0xf4,0x0, 0xa, 0x12,0x2f,0x54,0x7a,0x45,0x36, +0x7d,0x30,0x6d,0x22,0x7f,0x6, 0x12,0x64,0x2, 0x5e,0xf4,0xff,0xfd,0x12,0x2f,0x54, +0x2, 0x63,0x93,0xa9,0xc5,0xca,0xe4,0x7a,0xb3,0x3a,0x10,0x22,0x7c,0x6b,0x6c,0x77, +0x6c,0xaa,0x7e,0xb3,0x3a,0x10,0xb4,0xa5,0x46,0x12,0x64,0x8d,0x75,0xb5,0x5, 0xa9, +0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3, +0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36, +0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0x71,0xb5,0x75, +0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0xa1,0xb5,0xa9,0xd2,0xb4,0x7c, +0x47,0x6c,0x55,0xa, 0x3a,0x4d,0x32,0x22,0x74,0x6, 0x12,0x63,0x9c,0x7d,0x3, 0x6c, +0x11,0x22,0x12,0x64,0x10,0x7e,0x35,0x36,0x12,0x64,0x94,0xa9,0xd2,0xb4,0xd3,0x22, +0x7d,0x52,0xf5,0x3a,0x7c,0xb6,0x7c,0xa5,0xa, 0x44,0xf5,0x39,0x7f,0x21,0xf5,0x38, +0xa9,0xc2,0xb4,0x74,0xb, 0x12,0x64,0x3b,0xe5,0x3a,0x12,0x64,0x3b,0xe5,0x39,0x12, +0x64,0x3b,0xe5,0x38,0x12,0x64,0x3b,0xe4,0x2, 0x64,0x3b,0xf5,0xb5,0xa9,0x36,0xb3, +0xfc,0xa9,0xc6,0xb3,0xd3,0x22,0xd2,0xc8,0x43,0xed,0xf, 0xc2,0xea,0x75,0xb3,0x13, +0xa9,0xd1,0xb4,0xa9,0xc0,0xb4,0x12,0x64,0x60,0xe4,0x12,0x64,0x70,0x2, 0x63,0x93, +0xa9,0xd5,0xca,0xa9,0xd1,0xea,0xa9,0xc1,0xea,0x74,0xa5,0x7a,0xb3,0x3a,0x10,0x22, +0xca,0xf8,0x7c,0xfb,0x74,0x2, 0x12,0x63,0x9c,0x4c,0xff,0x78,0x5, 0x5e,0x70,0xdf, +0x80,0x3, 0x4e,0x70,0x20,0x74,0x2, 0x12,0x2f,0x58,0xda,0xf8,0x22,0xa9,0xc2,0xb4, +0xa9,0xc6,0xb3,0x22,0x6d,0x22,0x80,0x13,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9, +0xc6,0xb3,0xe5,0xb5,0x7a,0xb, 0xb0,0xb, 0x14,0xb, 0x24,0xbd,0x32,0x38,0xe9,0x22, +0x7e,0x8, 0x26,0x5b,0x7e,0x34,0x2, 0x3a,0xe4,0x12,0x20,0xe8,0x7e,0x8, 0x26,0x8c, +0x7e,0x34,0x0, 0xc8,0x74,0xff,0x12,0x20,0xe8,0x7e,0x8, 0x26,0xb4,0x7e,0x34,0x0, +0xc8,0x12,0x20,0xe8,0x7e,0x8, 0x27,0x76,0x7e,0x34,0x1, 0xe, 0x2, 0x20,0xe8,0xca, +0xf8,0x7e,0x73,0x2a,0x78,0xa, 0x47,0x7e,0x73,0x2a,0x71,0xa, 0x57,0x2d,0x54,0x7e, +0xa3,0x2a,0x73,0xbc,0xab,0x28,0x2, 0x7c,0xba,0x7e,0xf3,0x2a,0x72,0x7e,0xa3,0x2a, +0x74,0xbc,0xaf,0x28,0x2, 0x7c,0xfa,0x75,0x25,0x15,0x7e,0x8, 0x2a,0xb9,0x7e,0x18, +0x2a,0x7a,0x12,0xd, 0xd9,0x75,0x25,0x15,0x7e,0x8, 0x2a,0xdc,0x7e,0x18,0x2a,0x9d, +0x7c,0xbf,0x12,0xf, 0x9c,0xda,0xf8,0x22,0x7a,0xb3,0x2b,0x0, 0x70,0xa, 0x7e,0x1f, +0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x80,0xb, 0xb4,0x1, 0xb, 0x7e,0x1f,0x25,0xf2,0x7e, +0xf, 0x25,0xee,0x12,0x30,0x2f,0x22,0x7c,0xab,0x12,0x65,0x28,0x7c,0xba,0x12,0x13, +0xc7,0x2, 0x0, 0x1e,0x7f,0x70,0x7e,0x33,0x2a,0x74,0xa, 0x43,0x7e,0x33,0x2a,0x73, +0xa, 0x53,0x2d,0x54,0x3e,0x54,0x7c,0xab,0xe4,0x7a,0xb3,0x16,0x90,0x7f,0x1, 0xa, +0x3a,0x12,0x20,0xe8,0x7f,0x7, 0xa, 0x3a,0x2, 0x20,0xe8,0x7e,0xa3,0x2f,0xa8,0x7e, +0x70,0x4, 0xac,0x7a,0xb, 0x34,0xbe,0x37,0x38,0xee,0x40,0x39,0x7e,0x37,0x38,0xee, +0xb, 0x34,0x7a,0x37,0x38,0xee,0xbe,0x34,0x0, 0x1, 0x78,0x5, 0x7e,0xb3,0x38,0x35, +0x22,0xbe,0x34,0x0, 0x2, 0x78,0x3, 0x7c,0xba,0x22,0xbe,0x34,0x0, 0x2, 0x50,0x9, +0x7d,0x23,0x1b,0x25,0x9, 0xb2,0x39,0xfc,0x22,0x9e,0x34,0x0, 0x3, 0x2e,0x37,0x2b, +0xb9,0x7e,0x39,0xb0,0x22,0x74,0xff,0x22,0x70,0x5, 0x7e,0xb3,0x38,0x9d,0x22,0xbe, +0xb0,0x3, 0x38,0x15,0x75,0x1d,0x0, 0x30,0x12,0x6, 0x7e,0x18,0x35,0x93,0x80,0x4, +0x7e,0x18,0x35,0xd1,0x7a,0x1d,0x14,0x80,0x8, 0xbe,0xb0,0x5e,0x38,0x10,0x75,0x1d, +0x0, 0xa, 0x1b,0x7e,0x1d,0x14,0x2d,0x31,0x1b,0x34,0x7e,0x1b,0xb0,0x22,0xbe,0xb0, +0xd3,0x68,0x3, 0xb4,0xd4,0x10,0xb4,0xd3,0x8, 0x6d,0x33,0x7a,0x37,0x38,0xee,0x80, +0x2, 0x15,0x1a,0x2, 0x65,0x7b,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x3, 0x2, 0x66, +0xc6,0xbe,0xb0,0x80,0x40,0xc, 0xbe,0xb0,0xdf,0x38,0x7, 0xa, 0x3b,0x9, 0xb3,0x37, +0x62,0x22,0xb4,0xfc,0x5, 0x7e,0xb3,0x38,0x9, 0x22,0xb4,0xfd,0x17,0x6c,0xaa,0x7e, +0xb3,0x28,0xa8,0x60,0x3, 0x4e,0xa0,0x1, 0x7e,0xb3,0x37,0x71,0x60,0x3, 0x4e,0xa0, +0x2, 0x7c,0xba,0x22,0xb4,0xfe,0x5, 0x7e,0xb3,0x2b,0xf, 0x22,0x74,0xff,0x22,0x7c, +0x7b,0x6c,0xaa,0x12,0x66,0xbe,0x78,0x9, 0x7c,0xb7,0x12,0x65,0xc8,0x7c,0xab,0x80, +0xa, 0xb4,0x4, 0x7, 0x7c,0xb7,0x12,0x2a,0xc6,0x7c,0xab,0x7c,0xba,0x22,0x30,0x90, +0x19,0xc2,0x90,0xe5,0x18,0x70,0x9, 0x75,0x18,0x1, 0xe5,0x91,0xf5,0x1a,0x80,0x11, +0x7e,0x71,0x91,0xe5,0x1a,0x12,0x66,0xa9,0x5, 0x1a,0x30,0x91,0xb, 0xc2,0x91,0x5, +0x1a,0xe5,0x1a,0x12,0x66,0x5f,0xf5,0x91,0x22,0x7c,0x6b,0x12,0x66,0xbe,0x78,0x5, +0x7c,0xb6,0x2, 0x66,0xf8,0xb4,0x4, 0x5, 0x7c,0xb6,0x2, 0x37,0xe7,0x22,0x7e,0xb3, +0x38,0x9d,0xc4,0x54,0x7, 0x22,0xb4,0xeb,0x5, 0xe4,0x7a,0xb3,0x38,0xf3,0x7e,0x73, +0x38,0xf3,0xa, 0x27,0x2e,0x24,0x0, 0x6, 0x12,0x67,0x47,0x7c,0xab,0x7c,0xb7,0x4, +0x7a,0xb3,0x38,0xf3,0xb4,0x3, 0xb, 0xe4,0x7a,0xb3,0x38,0xf3,0x6d,0x33,0x7a,0x37, +0x38,0xf0,0x75,0x1a,0xeb,0x7c,0xba,0x22,0x7c,0xa7,0x7c,0x3b,0xa5,0xbb,0x0, 0x7, +0x7c,0xba,0x12,0x68,0x27,0x80,0x2c,0xbe,0x30,0xeb,0x68,0x4, 0xa5,0xbb,0xec,0x9, +0x7c,0xb3,0x7c,0x7a,0x12,0x68,0x71,0x80,0x1a,0xbe,0x30,0x80,0x40,0x15,0xbe,0x30, +0xdf,0x38,0x10,0x7c,0xb3,0x24,0x80,0x7c,0x7a,0x12,0x71,0x62,0xa5,0xbb,0x8f,0x3, +0x75,0x19,0x1, 0xa5,0xbb,0xfc,0x5, 0x7c,0xba,0x2, 0x2e,0xbd,0x74,0x1, 0x7a,0xb3, +0x3, 0xff,0x22,0x2e,0x24,0x20,0x7d,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0x22, +0x7c,0xab,0x6c,0x77,0xa, 0x27,0x2e,0x24,0x60,0xac,0x12,0x67,0x47,0xbc,0xba,0x78, +0x2, 0xd3,0x22,0xb, 0x70,0xbe,0x70,0x3, 0x40,0xea,0xc3,0x22,0x6c,0x33,0x80,0x1f, +0x7c,0xb3,0x12,0x67,0x50,0x40,0x16,0x7c,0xb3,0x12,0x67,0x98,0x7d,0x43,0x6d,0x55, +0x7d,0x4, 0x3e,0x4, 0x7e,0x1f,0x13,0x8a,0x2d,0x30,0x1b,0x1a,0x50,0xb, 0x30,0x7e, +0x23,0x2a,0x75,0xbc,0x23,0x38,0xd9,0x22,0x7e,0x73,0x2a,0x6e,0xac,0x7b,0x2e,0x34, +0x0, 0x18,0x22,0x6c,0x33,0x6c,0x22,0x80,0x28,0x7c,0xb2,0x12,0x67,0x50,0x50,0x1f, +0x7c,0xb2,0x12,0x67,0x98,0x3e,0x34,0x7e,0x7f,0x13,0x8a,0x2d,0xf3,0xb, 0x7a,0x30, +0x12,0x67,0xda,0x59,0x35,0x39,0xe9,0x30,0x0, 0x5, 0x6d,0x33,0x1b,0x7a,0x30,0xb, +0x20,0x7e,0x73,0x2a,0x75,0xbc,0x72,0x38,0xd0,0x22,0x7c,0xa3,0xb, 0x30,0x74,0x2, +0xa4,0x22,0x7c,0xab,0x7c,0xb7,0xb4,0x18,0x9, 0x7c,0xba,0x12,0x67,0x50,0x50,0x2, +0xd3,0x22,0xc3,0x22,0x7e,0xa3,0x38,0x9c,0x7c,0xba,0x4, 0x7a,0xb3,0x38,0x9c,0x7a, +0xa3,0x37,0xf3,0x22,0xca,0x7b,0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,0x83,0xc0,0x82, +0x12,0x66,0x7e,0xd0,0x82,0xd0,0x83,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x7b,0x32, +0xa9,0xc0,0x93,0x75,0x18,0x0, 0x32,0x7a,0xb3,0x38,0x9d,0xc4,0x54,0x7, 0xbe,0xb0, +0x4, 0x68,0x3, 0xb4,0x2, 0x4, 0x74,0x3, 0x80,0x7, 0x60,0x3, 0xb4,0x1, 0x7, 0x74, +0x1, 0x7a,0xb3,0x38,0x9, 0x22,0x74,0x1, 0x7a,0xb3,0x38,0x9, 0xe4,0x7a,0xb3,0x38, +0x9d,0x22,0x7e,0xb3,0x38,0xf2,0x4, 0x7a,0xb3,0x38,0xf2,0xe5,0x19,0xb4,0x1, 0x8, +0xe4,0x7a,0xb3,0x38,0xf2,0x75,0x19,0x0, 0x7e,0x73,0x38,0xf2,0x7a,0x73,0x37,0xf1, +0x22,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x33,0x7e,0x27,0x38,0xf0,0x4d,0x22,0x78, +0xe, 0xa5,0xbf,0xaa,0xa, 0x7e,0x24,0x0, 0x1, 0x7a,0x27,0x38,0xf0,0x15,0x1a,0x7e, +0x27,0x38,0xf0,0xbe,0x24,0x0, 0x1, 0x78,0x10,0xa5,0xbf,0x9, 0x6, 0x7e,0x34,0x0, +0x2, 0x80,0x2, 0x6d,0x33,0x7a,0x37,0x38,0xf0,0x75,0x1a,0xea,0x22,0xe4,0x7a,0xb3, +0x38,0x9d,0x7e,0x8, 0x35,0x93,0x12,0x68,0xfc,0x7e,0x8, 0x35,0xd1,0x7e,0x34,0x0, +0x3e,0x12,0x20,0xe8,0x7e,0x18,0x35,0x93,0x7a,0x1d,0x14,0x12,0x68,0xde,0x2, 0x68, +0xd1,0x75,0x18,0x0, 0x75,0x1a,0x0, 0x7e,0xb3,0x38,0x9d,0xf5,0x91,0x22,0x2, 0x68, +0xe1,0x90,0x60,0x0, 0xe4,0x93,0x54,0xfe,0x75,0x91,0x0, 0xc2,0x90,0xc2,0x91,0xc2, +0xc9,0x54,0xfe,0xf5,0x92,0xd2,0xe8,0xc2,0xc0,0xd2,0xad,0x22,0x7e,0x34,0x0, 0x3e, +0x74,0xff,0x2, 0x20,0xe8,0x30,0x1d,0x8, 0x74,0x5, 0x7e,0x70,0x99,0x12,0x13,0x2c, +0x7e,0xb3,0x34,0x3a,0xb4,0x1, 0x4f,0x12,0x69,0x67,0x49,0x35,0x34,0x3b,0x49,0x15, +0x34,0x3d,0x6d,0x0, 0xbe,0x8, 0x0, 0x0, 0x68,0x1a,0xbe,0x70,0x0, 0x40,0x15,0xbe, +0x70,0x2, 0x38,0x10,0x74,0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0x73,0x7e,0x73,0x2a, +0x74,0x12,0x10,0xee,0x7e,0xb3,0x34,0x39,0x4, 0x7a,0xb3,0x34,0x39,0x12,0x69,0x6f, +0x28,0xe, 0x12,0x3f,0xd2,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x6, 0x74,0x3, 0x80,0x2, +0x74,0x2, 0x7a,0xb3,0x34,0x3a,0x22,0x7e,0xa3,0x34,0x39,0x74,0x4, 0xa4,0x22,0x7e, +0x73,0x34,0x38,0xbe,0x73,0x34,0x39,0x22,0x7e,0xb3,0x34,0x3a,0xb4,0x1, 0x2, 0xc3, +0x22,0xd3,0x22,0x7e,0xb3,0x2b,0x1e,0x70,0x1f,0x12,0x2f,0xe7,0x12,0x69,0x78,0x50, +0xfb,0x12,0x69,0xa9,0x12,0x6a,0xb8,0x20,0x13,0x3, 0x12,0x55,0xae,0x74,0x2, 0x7a, +0xb3,0x2b,0x1e,0xe4,0x7a,0xb3,0x16,0x91,0x22,0x7e,0xf, 0x13,0x8a,0x7e,0x18,0x8, +0xa, 0xca,0x3b,0x7a,0x1d,0x29,0x7f,0x30,0x12,0x57,0xe5,0xa4,0x7a,0x55,0x31,0x7e, +0xb3,0x2b,0x1d,0xf5,0x2e,0xe4,0x7a,0xb3,0x2b,0x1d,0x7f,0x3, 0x7e,0x1d,0x29,0x12, +0x5f,0xd5,0x12,0xc6,0xa3,0x12,0x3f,0xeb,0x75,0x2d,0x0, 0x12,0x3f,0xa5,0x30,0xf, +0xfd,0x74,0x1, 0x12,0x6a,0x73,0x7e,0x14,0x40,0x0, 0x7d,0x21,0x7d,0x7, 0x12,0x56, +0x2d,0x12,0x6a,0x2e,0x6d,0x33,0x80,0x19,0x7e,0x35,0x2f,0x3e,0x34,0x7f,0x3, 0x2d, +0x13,0xb, 0xa, 0x20,0x7e,0xd, 0x29,0x2d,0x13,0x12,0xc6,0xbf,0x7e,0x35,0x2f,0xb, +0x34,0x7a,0x35,0x2f,0x7e,0x35,0x31,0xbe,0x35,0x2f,0x38,0xdc,0x5, 0x2d,0xe5,0x2d, +0xbe,0xb0,0x1, 0x40,0xb6,0xe5,0x2e,0x7a,0xb3,0x2b,0x1d,0xda,0x3b,0x22,0x7e,0xa3, +0x2a,0x6e,0xa, 0x3a,0x3e,0x34,0x7e,0x8, 0x13,0x8e,0xe4,0x12,0x20,0xe8,0x7e,0xb3, +0x2a,0x71,0x12,0xb9,0x19,0x7d,0x43,0x6c,0x77,0x80,0x1d,0xa, 0x27,0x2d,0x24,0x12, +0x4f,0xe5,0xb, 0xa, 0x0, 0x7e,0x30,0x2, 0xac,0x37,0x2e,0x14,0x13,0x8e,0xb, 0x18, +0x20,0x2d,0x20,0x1b,0x18,0x20,0xb, 0x70,0xbc,0xa7,0x38,0xdf,0x22,0x12,0x69,0x78, +0x50,0xfb,0x22,0x12,0x0, 0xe, 0x7e,0x1f,0x13,0x86,0x22,0x7e,0x8, 0x24,0xf2,0x7e, +0x34,0x0, 0xc, 0xe4,0x12,0x20,0xe8,0x12,0xa4,0x5f,0x12,0xa4,0x56,0xa9,0xd1,0xcb, +0x12,0x6a,0x73,0x7a,0x37,0x24,0xf6,0x7e,0x1f,0x39,0xda,0x7a,0x37,0x24,0xf8,0x7e, +0x1f,0x13,0x86,0x7a,0x37,0x24,0xfa,0x6d,0x33,0x12,0xb9,0x10,0x2, 0xd, 0x7, 0x12, +0xa5,0xef,0x12,0x6a,0x7b,0x2, 0x6a,0xb8,0x12,0x57,0x8e,0x50,0x3, 0xd2,0x13,0x22, +0xc2,0x13,0x22,0x12,0x75,0xd2,0x12,0x6b,0x17,0x12,0xad,0xc9,0x12,0x6c,0x68,0x7e, +0xb3,0x38,0x7, 0xb4,0x1, 0x7, 0x7e,0x34,0x0, 0x14,0x12,0x5f,0xcc,0x7e,0xb3,0x3a, +0xe, 0x60,0x7, 0x14,0x7a,0xb3,0x3a,0xe, 0x80,0x6, 0x7e,0xb3,0x28,0xac,0x60,0xc, +0x12,0x6a,0xaf,0x12,0x57,0x9f,0x12,0xb5,0xf1,0x12,0x9e,0x4f,0x7e,0xb3,0x34,0xb6, +0x60,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x7e,0xb3,0x28,0xad,0x60,0x9, 0x12,0xbb,0x95, +0x12,0xa4,0x68,0x2, 0xaa,0x3c,0x22,0x7e,0x90,0x1, 0x12,0x5f,0xc8,0x7e,0xf4,0x0, +0x96,0xe4,0x7a,0xb3,0x28,0xac,0x12,0x6c,0x48,0x7e,0x34,0xfe,0x89,0x7e,0x27,0x7, +0xfe,0xbe,0x24,0xfd,0x12,0x58,0x1c,0x7e,0xe7,0x7, 0xfc,0xbd,0xe3,0x58,0x14,0x6d, +0xee,0x9e,0xe7,0x2a,0x5a,0xbe,0xe7,0x28,0x8e,0x8, 0x8, 0x12,0xac,0x93,0x60,0x3, +0x12,0xa6,0x2e,0x12,0xa6,0x3d,0x40,0x5, 0xe4,0x7a,0xb3,0x28,0xa8,0x12,0xc7,0x1, +0x68,0x6, 0x7e,0xb3,0x3a,0xc, 0x60,0x7, 0xe4,0x7a,0xb3,0x28,0xad,0x80,0x65,0x12, +0x6c,0x4f,0x28,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x30,0x14,0x5, 0xe4,0x7a,0xb3,0x28, +0xad,0x12,0xa6,0x7b,0x50,0xa, 0x12,0x6c,0x48,0x12,0x6c,0x85,0x7c,0x9b,0x80,0x17, +0x7e,0xb3,0x26,0x84,0x70,0x11,0x7e,0xb3,0x26,0x85,0x70,0xb, 0x12,0x6c,0x4f,0x28, +0x6, 0x7e,0x90,0x3, 0x12,0x6c,0x48,0x7e,0xe7,0x7, 0xfa,0xbe,0xe4,0x5, 0xdc,0x8, +0x17,0x12,0x6c,0x4f,0x28,0x12,0x6d,0xee,0x9d,0xef,0xbe,0xe7,0x28,0x8e,0x58,0x8, +0x12,0x6c,0x5a,0xe4,0x7a,0xb3,0x28,0xad,0x74,0x4, 0xac,0xb9,0x7a,0x57,0x28,0xa1, +0x7a,0x57,0x28,0xa3,0x12,0x6c,0x57,0x50,0xd, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x76, +0xe0,0x28,0x3, 0x12,0x6c,0x5a,0x7e,0xe7,0x28,0x8a,0xbd,0xef,0x8, 0x1f,0x7e,0x24, +0x0, 0x2, 0x7d,0x3f,0x12,0x1e,0xb9,0x6e,0x34,0xff,0xff,0xb, 0x34,0xbe,0x37,0x28, +0x8e,0x58,0xa, 0x12,0x6c,0x57,0x50,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x6c,0xe8, +0xb4,0x1, 0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0xa5,0x95,0x7e,0xb3,0x2f,0xa9,0xbe, +0xb0,0x0, 0x28,0x23,0x14,0x7a,0xb3,0x2f,0xa9,0x70,0x1c,0xe4,0x7a,0xb3,0x28,0xad, +0x74,0x1, 0x7a,0xb3,0x28,0xac,0xe4,0x7a,0xb3,0x16,0x91,0x7a,0xb3,0x16,0x90,0x7a, +0xb3,0x28,0x84,0x7a,0xb3,0x26,0x83,0x22,0x74,0x1, 0x7a,0xb3,0x28,0xad,0x22,0x7e, +0x83,0x28,0x84,0xbe,0x80,0x0, 0x22,0xa2,0x17,0x22,0xe4,0x7a,0xb3,0x2f,0xa9,0x7a, +0xb3,0x28,0xac,0x74,0x2, 0x2, 0x26,0x12,0x12,0xab,0xcd,0x60,0x17,0x12,0x6c,0x48, +0x7e,0x37,0x28,0xa1,0x3e,0x34,0x7a,0x37,0x28,0xa1,0x7e,0x37,0x28,0xa3,0x3e,0x34, +0x7a,0x37,0x28,0xa3,0x22,0x7e,0xa0,0x1, 0x7e,0x47,0x7, 0xf8,0x7e,0x4, 0x0, 0xfa, +0xbe,0x44,0xfd,0x12,0x58,0x12,0x7e,0xb3,0x28,0xac,0x60,0x7, 0xe4,0x7a,0xb3,0x28, +0xad,0x80,0x38,0x7e,0xa0,0x5, 0x80,0x33,0x7e,0x34,0xff,0xfb,0xad,0x30,0x7e,0x14, +0x0, 0x2, 0x12,0x6c,0xe0,0x8, 0x5, 0x7e,0xa0,0x4, 0x80,0x1f,0x7e,0x34,0xff,0xfc, +0x12,0x6c,0xde,0x8, 0x5, 0x7e,0xa0,0x3, 0x80,0x11,0x7e,0x34,0xff,0xfd,0x12,0x6c, +0xde,0x8, 0x5, 0x7e,0xa0,0x2, 0x80,0x3, 0x7e,0xa0,0x1, 0x7c,0xba,0x22,0xad,0x30, +0x7d,0x21,0x12,0x1e,0xb9,0xbd,0x34,0x22,0xca,0x3b,0x12,0x9a,0xbf,0x38,0x2, 0xa1, +0xab,0x7e,0xc3,0x2f,0xac,0x4c,0xcc,0x78,0x3d,0x7a,0xb3,0x2f,0xac,0xe4,0x7a,0xb3, +0x2f,0xae,0x6c,0xaa,0x80,0x26,0x12,0x6d,0xb6,0x7e,0x70,0x2, 0xac,0x7a,0x9, 0xd3, +0x26,0xfa,0x9, 0xe3,0x26,0xfb,0x7a,0x49,0xd0,0x19,0xe4,0x0, 0x1, 0x74,0x1, 0x19, +0xb4,0x0, 0x8, 0x12,0x6d,0xc0,0x59,0x34,0x0, 0x2, 0xb, 0xa0,0x7e,0xb3,0x28,0x84, +0xbc,0xba,0x38,0xd2,0x80,0x7b,0x7c,0xfc,0x6c,0xaa,0x80,0x31,0x12,0x6d,0xb6,0x7e, +0x49,0xd0,0x9, 0xe4,0x0, 0x1, 0x9, 0xb4,0x0, 0x8, 0x70,0x4, 0x1b,0xf0,0x80,0x1b, +0x12,0x6d,0xc0,0x7d,0x23,0x49,0x34,0x0, 0x2, 0x12,0xa1,0xb6,0xbe,0xf4,0x0, 0x23, +0x8, 0x9, 0x74,0x5, 0x19,0xb4,0x0, 0x8, 0x75,0x5c,0x1, 0xb, 0xa0,0xbc,0xfa,0x38, +0xcb,0x4c,0xff,0x78,0x2, 0x80,0x26,0x7e,0x73,0x2f,0xae,0xbe,0x70,0x4, 0x40,0x22, +0x6c,0xaa,0x80,0xe, 0x12,0x6d,0xb6,0x9, 0xb4,0x0, 0x8, 0xbe,0xb0,0x5, 0x68,0x6, +0xb, 0xa0,0xbc,0xfa,0x38,0xee,0xbc,0xfa,0x78,0x3, 0x75,0x5c,0x0, 0x12,0x6f,0x5d, +0x80,0xf, 0x7c,0xb7,0x4, 0x7a,0xb3,0x2f,0xae,0x80,0x6, 0x12,0x6f,0x5d,0x75,0x5c, +0x0, 0xe5,0x5c,0xda,0x3b,0x22,0x7e,0x90,0x9, 0xac,0x9a,0x2e,0x44,0x2f,0xaf,0x22, +0x7c,0xbd,0x7c,0x7e,0x2, 0x6d,0xcb,0x7c,0xba,0x7c,0x79,0x12,0x6f,0x81,0xb, 0x1a, +0x30,0x22,0x7c,0xbd,0x7c,0x7e,0x7f,0x4, 0xca,0x3b,0x7f,0x70,0x7c,0xe7,0x7c,0xdb, +0x7e,0xc0,0x4, 0x7e,0xb3,0x2a,0x6d,0xf5,0x26,0x7e,0xb3,0x2a,0x6e,0xf5,0x25,0x7e, +0xd4,0x0, 0xc8,0x6c,0xff,0x12,0x6f,0x7d,0xe5,0x26,0xa, 0x1b,0x1b,0x14,0xa, 0xcd, +0xbd,0xc1,0x58,0x14,0xe5,0x25,0xa, 0x1b,0x1b,0x14,0xa, 0xce,0xbd,0xc1,0x58,0x8, +0x4c,0xee,0x68,0x4, 0x4c,0xdd,0x78,0x3, 0x4e,0xf0,0x10,0xb, 0x1a,0xc0,0xbe,0xc4, +0x0, 0xc8,0x8, 0xc, 0x7e,0x17,0x28,0x8a,0xbe,0x14,0x3, 0x20,0x8, 0x2, 0xe1,0x1c, +0xbe,0xc4,0x0, 0x64,0x8, 0xc, 0x7e,0xc7,0x28,0x8a,0xbe,0xc4,0x3, 0x20,0x58,0x2, +0xe1,0x1c,0x6c,0xaa,0x7c,0x8d,0x80,0x1c,0x7c,0x9e,0xbe,0x80,0x0, 0x48,0x11,0x7e, +0xb3,0x2a,0x6d,0xbc,0xb8,0x8, 0x9, 0x12,0x6f,0x53,0x58,0x14,0xb, 0xa0,0x80,0x2, +0xb, 0xa0,0x1b,0x80,0x1a,0x2c,0x1a,0x3d,0x9d,0x32,0x1a,0xc8,0xbd,0xc3,0x18,0xd8, +0xbc,0xca,0x18,0x5, 0x4e,0xf0,0x1, 0xe1,0x1c,0x6c,0xaa,0x7c,0x8d,0x80,0x1c,0x7c, +0x9e,0xbe,0x80,0x0, 0x48,0x11,0x7e,0xb3,0x2a,0x6d,0xbc,0xb8,0x8, 0x9, 0x12,0x6f, +0x53,0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0xb, 0x80,0x1a,0x2c,0x1a,0x3d,0x2d, +0x32,0x1a,0xc8,0xbd,0xc3,0x48,0xd8,0xbc,0xca,0x18,0x5, 0x4e,0xf0,0x2, 0x80,0x6c, +0x6c,0xaa,0x7c,0x9e,0x80,0x1c,0x7c,0x8d,0xbe,0x90,0x0, 0x48,0x11,0x7e,0xb3,0x2a, +0x6e,0xbc,0xb9,0x8, 0x9, 0x12,0x6f,0x53,0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0, +0x1b,0x90,0x1a,0x2c,0x1a,0x3e,0x9d,0x32,0x1a,0xc9,0xbd,0xc3,0x18,0xd8,0xbc,0xca, +0x18,0x5, 0x4e,0xf0,0x4, 0x80,0x35,0x6c,0xaa,0x7c,0x9e,0x80,0x1c,0x7c,0x8d,0xbe, +0x90,0x0, 0x48,0x11,0x7e,0xb3,0x2a,0x6e,0xbc,0xb9,0x8, 0x9, 0x12,0x6f,0x53,0x58, +0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0xb, 0x90,0x1a,0x2c,0x1a,0x3e,0x2d,0x32,0x1a, +0xc9,0xbd,0xc3,0x48,0xd8,0xbc,0xca,0x18,0x3, 0x4e,0xf0,0x8, 0x4c,0xff,0x68,0x2e, +0x7e,0x7b,0xb0,0xbc,0xbd,0x40,0x3, 0x7a,0x7b,0xd0,0x29,0xb7,0x0, 0x2, 0xbc,0xbd, +0x38,0x4, 0x39,0xd7,0x0, 0x2, 0x29,0xb7,0x0, 0x1, 0xbc,0xbe,0x40,0x4, 0x39,0xe7, +0x0, 0x1, 0x29,0xb7,0x0, 0x3, 0xbc,0xbe,0x38,0x4, 0x39,0xe7,0x0, 0x3, 0x7c,0xbf, +0xda,0x3b,0x22,0x7c,0xb8,0x7c,0x79,0x12,0x6d,0xcb,0xbd,0x3d,0x22,0xe4,0x7a,0xb3, +0x2f,0xad,0x7a,0xb3,0x2f,0xac,0x7a,0xb3,0x2f,0xae,0x22,0x7c,0xab,0x7e,0x70,0x2, +0xac,0x7a,0x9, 0xb3,0x26,0xfa,0x9, 0x73,0x26,0xfb,0x2, 0x6d,0xcb,0x7c,0xbd,0x7c, +0x7e,0x7e,0x13,0x2a,0x6e,0xac,0x1b,0x3e,0x4, 0x7e,0x30,0x2, 0xac,0x37,0x2d,0x10, +0x7e,0x1f,0x13,0x8a,0x2d,0x31,0x22,0xca,0x79,0x6c,0xff,0x7e,0xd7,0x2a,0x5a,0x6c, +0xee,0x80,0x3e,0x12,0x7f,0xfc,0x50,0x4, 0x7e,0xd7,0x2a,0x5c,0x7c,0xbe,0x12,0x6f, +0x6b,0xbd,0x3d,0x48,0x2a,0x7c,0xbe,0x12,0x88,0x65,0x60,0x23,0x7e,0xc4,0x0, 0x9, +0xca,0xc9,0x7e,0x70,0x9, 0xac,0x7e,0x2e,0x34,0x27,0x76,0x6d,0x22,0x7e,0x30,0x9, +0xac,0x3f,0x2e,0x14,0x28,0xae,0x6d,0x0, 0x12,0x20,0xc3,0x1b,0xfd,0xb, 0xf0,0xb, +0xe0,0x12,0x97,0xbe,0x38,0xbd,0x7a,0x73,0x28,0x93,0x7a,0xf3,0x2a,0x2, 0xda,0x79, +0x22,0x2, 0x6f,0x97,0x7e,0x70,0x18,0x2, 0x6d,0xcb,0x7d,0xf3,0x6d,0xee,0x6c,0x99, +0x80,0x3c,0x7c,0xb9,0x12,0x67,0x98,0x7d,0xd3,0x7d,0xcd,0x3e,0xc4,0x7f,0x57,0x2d, +0xbc,0xb, 0x5a,0x10,0x1a,0x2, 0x1a,0x0, 0x7e,0x83,0x2b,0x20,0xa, 0x98,0x6d,0x88, +0x7f,0x10,0x7f,0x4, 0x12,0x1e,0xeb,0x74,0x6, 0x7f,0x1, 0x1e,0x14,0x1e,0x4, 0x50, +0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4,0x7d,0xc1,0x1b,0x5a,0xc0,0xb, 0x90,0x7e,0x83, +0x2a,0x75,0xbc,0x89,0x38,0xbc,0x22,0xca,0x79,0x7c,0x5b,0x7e,0x43,0x28,0x84,0xbe, +0x40,0x1, 0x28,0x2, 0x21,0x56,0x7e,0xa3,0x2a,0x6e,0x7e,0x70,0x2, 0xac,0x75,0x9, +0xf3,0x26,0xfa,0x9, 0xe3,0x26,0xfb,0x7c,0xbf,0x7c,0x7e,0x12,0x6f,0x81,0x7f,0x51, +0x7c,0x1e,0x7c,0x3f,0x7e,0x3, 0x2a,0x70,0x7e,0x23,0x2a,0x6f,0xa, 0x3a,0x6d,0xdd, +0x9d,0xd3,0xa, 0x9a,0xa, 0xc0,0x1b,0xc5,0xa, 0x51,0xbd,0x5c,0x58,0x2, 0x21,0x56, +0xa, 0x53,0x1b,0x54,0xbe,0x54,0x0, 0x0, 0x48,0x55,0x7c,0xb3,0x14,0x12,0x67,0x50, +0x50,0x4d,0x7c,0xb3,0x14,0x12,0x67,0x98,0x7d,0xe3,0x7d,0x5e,0x12,0x71,0x59,0xb, +0x1a,0xf0,0x7d,0x5d,0x3e,0x54,0x7f,0x15,0x2d,0x35,0xb, 0x1a,0x80,0xbe,0xf4,0x0, +0x0, 0x8, 0x11,0x9d,0x8f,0xbe,0x84,0x0, 0x0, 0x58,0x4, 0x6d,0x55,0x80,0x2, 0x7d, +0x58,0x1b,0x1a,0x50,0x7c,0xb0,0x24,0xfe,0xbc,0xb1,0x78,0x13,0x7d,0x4e,0x1b,0x44, +0x7d,0x54,0x12,0x71,0x59,0xb, 0x1a,0x50,0xbd,0x58,0x8, 0x3, 0x1b,0x1a,0x80,0xa, +0x83,0xb, 0x84,0xa, 0x52,0xbd,0x85,0x58,0x5d,0x7c,0xb3,0x4, 0x12,0x67,0x50,0x50, +0x55,0x7c,0xb3,0x4, 0x12,0x67,0x98,0x7d,0xe3,0x7d,0x1e,0x3e,0x14,0x7e,0x1f,0x13, +0x8a,0x7f,0x61,0x2d,0xd1,0xb, 0x6a,0xf0,0x7d,0x19,0x3e,0x14,0x7f,0x65,0x2d,0xd1, +0xb, 0x6a,0x10,0xbe,0xf4,0x0, 0x0, 0x8, 0x11,0x9d,0x1f,0xbe,0x14,0x0, 0x0, 0x58, +0x4, 0x6d,0x55,0x80,0x2, 0x7d,0x51,0x1b,0x6a,0x50,0x7c,0xb0,0x24,0xfe,0xbc,0xb1, +0x78,0x14,0x7d,0x4e,0x1b,0x44,0x7d,0x4, 0x3e,0x4, 0x2d,0x30,0xb, 0x1a,0x0, 0xbd, +0x1, 0x8, 0x3, 0x1b,0x1a,0x10,0xda,0x79,0x22,0x3e,0x54,0x7e,0x1f,0x13,0x8a,0x2d, +0x35,0x22,0x7c,0x6b,0x2e,0x60,0xdd,0x68,0x26,0x2e,0x60,0xfd,0x68,0x21,0x1b,0x61, +0x68,0x1d,0x1b,0x62,0x68,0x19,0x1b,0x61,0x68,0x15,0x1b,0x60,0x68,0x11,0x2e,0x60, +0xa, 0x78,0x4, 0x7a,0x73,0x37,0xe1,0xa, 0x2b,0x19,0x72,0x37,0xe2,0xd2,0x11,0x22, +0xca,0x79,0x6c,0xaa,0x6c,0xee,0x6d,0xdd,0x7e,0xe4,0x7f,0xff,0x7e,0xf0,0x1, 0x80, +0x28,0xa, 0xff,0x7e,0xb3,0x2a,0x6e,0xa, 0xcb,0x2d,0xcf,0x3e,0xc4,0x49,0xfc,0x4, +0xfc,0xbe,0xf4,0x1, 0xf4,0x8, 0x10,0xb, 0xa0,0xbd,0xfd,0x8, 0x4, 0x7d,0xdf,0x80, +0x6, 0xbd,0xfe,0x58,0x2, 0x7d,0xef,0xb, 0xf0,0x7e,0xb3,0x2a,0x6f,0xa, 0xcb,0x1b, +0xc4,0xa, 0xff,0xbd,0xfc,0x48,0xca,0x74,0x2, 0x12,0x6f,0xf4,0x7d,0xf3,0x74,0x7, +0x12,0x6f,0xf4,0x7d,0x43,0x74,0xb, 0x12,0x6f,0xf4,0xbe,0xa0,0xc, 0x78,0x1f,0x7d, +0x2d,0x9d,0x2e,0xbe,0x24,0x7, 0xd0,0x58,0x15,0xbe,0xf4,0x0, 0x50,0x8, 0xf, 0xbe, +0x44,0x0, 0x64,0x8, 0x9, 0xbe,0x34,0x0, 0x50,0x8, 0x3, 0x7e,0xe0,0x1, 0x7e,0xb3, +0x37,0xee,0xb4,0x1, 0xc, 0x74,0xc, 0x6c,0x77,0x12,0x71,0x62,0x6c,0xee,0x12,0x72, +0xfd,0xbe,0xe0,0x1, 0x78,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x7a,0xb3,0x34,0xb6,0xb4, +0x1, 0x34,0x7e,0xb3,0x34,0xc5,0xbe,0xb0,0x8, 0x50,0x1a,0x4, 0x7a,0xb3,0x34,0xc5, +0x7e,0x73,0x34,0xc5,0xbe,0x70,0x3, 0x28,0xc, 0x74,0x8, 0x7a,0xb3,0x34,0xc5,0x74, +0x1, 0x7a,0xb3,0x34,0x8b,0x7e,0x73,0x34,0xc5,0xbe,0x70,0x8, 0x40,0x8, 0x12,0x72, +0xc2,0x60,0x3, 0x12,0x73,0x12,0x7e,0x73,0x34,0xb6,0xbe,0x70,0x0, 0x38,0x5, 0x12, +0x72,0xc2,0x70,0x39,0x6c,0xff,0x80,0x30,0x7c,0xbf,0x12,0x8b,0xef,0x60,0x23,0x7e, +0xb3,0x34,0xda,0x4, 0x12,0x73,0x26,0x7e,0x73,0x34,0xda,0xbe,0x70,0x5, 0x40,0x16, +0x12,0x72,0xfd,0xe4,0x7a,0xb3,0x34,0xda,0x7a,0xb3,0x34,0xc5,0x7a,0xb3,0x34,0x8b, +0x80,0x4, 0xe4,0x12,0x73,0x26,0xb, 0xf0,0x12,0x73,0x6d,0x38,0xcb,0x12,0x72,0xc2, +0x70,0xc, 0x12,0x76,0xe0,0x28,0x4, 0x74,0x5, 0x80,0x4, 0xe4,0x80,0x1, 0xe4,0xda, +0x79,0x22,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x3, 0x74,0x1, 0x22,0x7e,0x34,0xd7,0x0, +0x12,0x72,0xf5,0x70,0x1b,0x7e,0x34,0xd7,0x1, 0x12,0x72,0xf5,0x70,0x12,0x7e,0x34, +0xd7,0x2, 0x12,0x72,0xf5,0x70,0x9, 0x7e,0x34,0xd7,0x3, 0x12,0x72,0xf5,0x60,0x2, +0xe4,0x22,0x74,0x1, 0x22,0x7e,0x24,0x0, 0xff,0x7e,0x1b,0xb0,0x22,0xe4,0x12,0x77, +0x11,0x12,0x77,0x9, 0x12,0x77,0x1, 0x2, 0x73,0xa, 0x7e,0x34,0xd7,0x3, 0x7a,0x1b, +0xb0,0x22,0x74,0x55,0x12,0x77,0x11,0x74,0xaa,0x12,0x77,0x9, 0x74,0x55,0x12,0x77, +0x1, 0x74,0xaa,0x2, 0x73,0xa, 0x7a,0xb3,0x34,0xda,0x7c,0xbf,0x6c,0x77,0x7c,0x67, +0x7c,0x7b,0xc4,0x23,0x54,0x1f,0x7c,0xab,0x7c,0xb7,0x54,0x7, 0xa, 0x2b,0x2e,0x24, +0x0, 0x5e,0x12,0x67,0x47,0x7c,0x7b,0x4c,0x66,0x68,0xf, 0xa, 0x2a,0x2e,0x24,0x27, +0x72,0x7e,0x29,0xb0,0x4c,0xb7,0x7a,0x29,0xb0,0x22,0x7c,0xb7,0x64,0xff,0xa, 0x2a, +0x2e,0x24,0x27,0x72,0x7e,0x29,0x70,0x5c,0x7b,0x7a,0x29,0x70,0x22,0x7e,0x73,0x28, +0x84,0xbc,0x7f,0x22,0xca,0xd8,0xca,0x79,0xc2,0x0, 0x6d,0x88,0x7a,0x87,0x39,0x3d, +0xe4,0x7a,0xb3,0x1f,0x58,0xe5,0x1f,0xbe,0xb0,0xff,0x50,0x2, 0x5, 0x1f,0x7e,0xb3, +0x28,0x84,0x60,0xa, 0x7e,0x87,0x7, 0xfa,0xbe,0x84,0x0, 0xfa,0x58,0xa, 0xc2,0x14, +0x6d,0x88,0x7a,0x87,0x38,0xfe,0x81,0x97,0x12,0x91,0xe1,0x60,0x10,0x7e,0x84,0x0, +0x64,0x7a,0x87,0x38,0xf4,0x7e,0x84,0x0, 0x2d,0x7a,0x87,0x38,0xfe,0x7e,0x87,0x38, +0xf4,0x4d,0x88,0x68,0x6, 0x74,0x1, 0x7a,0xb3,0x28,0xa9,0x6c,0xff,0x80,0x76,0xe4, +0xa, 0x3f,0x19,0xb3,0x1f,0x34,0x12,0x75,0x14,0x7e,0x8, 0x1f,0x52,0x7c,0xbd,0x7c, +0x7e,0x12,0x90,0x9c,0x7d,0x93,0x7e,0x87,0x38,0xfe,0xbd,0x89,0x50,0x4, 0x7a,0x97, +0x38,0xfe,0x7e,0x87,0x39,0x3d,0xbd,0x89,0x50,0x4, 0x7a,0x97,0x39,0x3d,0xe5,0x1f, +0xbe,0xb0,0x5, 0x38,0x1f,0x7e,0x8, 0x39,0x0, 0x12,0x75,0x8c,0x50,0x7, 0x12,0x75, +0xb, 0xd2,0x0, 0x80,0x2e,0x7e,0x8, 0x39,0x0, 0x7e,0x18,0x1f,0x52,0x12,0x77,0x42, +0x50,0x21,0x80,0xf, 0xbe,0x94,0x0, 0x2d,0x40,0x19,0x7e,0x8, 0x1f,0x52,0x12,0x90, +0x4d,0x50,0x10,0x12,0x75,0xb, 0x7e,0x8, 0x1f,0x58,0x7e,0x18,0x1f,0x52,0x12,0x91, +0xbb,0xd2,0x0, 0xb, 0xf0,0x12,0x73,0x6d,0x38,0x85,0x30,0x0, 0x30,0x6c,0xff,0x80, +0x1c,0x12,0x75,0x14,0x7e,0x8, 0x1f,0x58,0x12,0x75,0x8c,0x40,0x9, 0xa, 0x3f,0x9, +0xb3,0x1f,0x34,0xb4,0x1, 0x5, 0x7c,0xbf,0x12,0x74,0xeb,0xb, 0xf0,0x12,0x73,0x6d, +0x38,0xdf,0x75,0x1f,0x0, 0x7e,0x34,0x0, 0x64,0x7a,0x37,0x38,0xf4,0x7e,0x63,0x1f, +0x58,0x7e,0x70,0x6, 0xac,0x67,0xb, 0x34,0xca,0x39,0x7e,0x18,0x1f,0x58,0x7e,0x8, +0x39,0x0, 0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x37,0x38,0xf4,0x4d,0x33,0x78,0x26,0x7e, +0x37,0x38,0xfe,0xbe,0x34,0x0, 0x2d,0x40,0x30,0x7e,0x37,0x39,0x3d,0xbe,0x34,0x0, +0x16,0x40,0x26,0x7e,0x73,0x26,0xf7,0xbe,0x70,0xc, 0x28,0x1d,0x7e,0x73,0x26,0xf6, +0xbe,0x70,0x7, 0x28,0x14,0x6c,0xff,0x80,0x7, 0x7c,0xbf,0x12,0x74,0xeb,0xb, 0xf0, +0x12,0x73,0x6d,0x38,0xf4,0xd2,0x0, 0x80,0x6, 0x6d,0x33,0x7a,0x37,0x38,0xfe,0xa2, +0x0, 0x92,0x14,0x12,0x77,0x2b,0xda,0x79,0xda,0xd8,0x22,0x7c,0xab,0x7e,0xb3,0x3a, +0xc, 0x70,0x17,0x7e,0xb3,0x28,0xa8,0x70,0x11,0x12,0x4f,0xd4,0x68,0xc, 0x12,0x90, +0x35,0x68,0x7, 0x7c,0xba,0x6c,0x77,0x2, 0x73,0x2e,0x22,0x74,0x1, 0xa, 0x8f,0x19, +0xb8,0x1f,0x34,0x22,0x74,0x2, 0xac,0xbf,0x9, 0xd5,0x26,0xfa,0x9, 0xe5,0x26,0xfb, +0x22,0xca,0xf8,0x6c,0xff,0x80,0x18,0x7c,0xbf,0x12,0x6f,0x6b,0xbe,0x37,0x2a,0x5c, +0x58,0xb, 0x12,0x73,0x2a,0x7e,0x70,0x2, 0xac,0x7f,0x12,0x8f,0xa4,0xb, 0xf0,0x12, +0x73,0x6d,0x38,0xe3,0x12,0x75,0x4a,0xda,0xf8,0x22,0xca,0x79,0x6c,0xff,0x6c,0xee, +0x80,0x2e,0x7c,0xbe,0x12,0x88,0x65,0x60,0x25,0x7e,0x34,0x0, 0x2, 0xca,0x39,0xac, +0x7e,0x2e,0x34,0x26,0xfa,0x6d,0x22,0x7e,0x30,0x2, 0xac,0x3f,0x2e,0x14,0x26,0xfa, +0x6d,0x0, 0x12,0x20,0xc3,0x1b,0xfd,0x7c,0xbf,0x12,0x76,0xfb,0xb, 0xf0,0xb, 0xe0, +0x12,0x97,0xbe,0x38,0xcd,0x7a,0xf3,0x28,0x84,0xda,0x79,0x22,0x7c,0xbd,0x7c,0x7e, +0x7c,0x6b,0xc2,0x1, 0x6c,0xaa,0x80,0x30,0x7e,0x50,0x6, 0xac,0x5a,0x7f,0x70,0x2d, +0xf2,0xb, 0xf4,0x29,0xb7,0x0, 0x2, 0xbc,0xb6,0x40,0x1b,0x7e,0x7b,0xb0,0xbc,0xb6, +0x38,0x14,0x29,0xb7,0x0, 0x3, 0xbc,0xb7,0x40,0xc, 0x29,0xb7,0x0, 0x1, 0xbc,0xb7, +0x38,0x4, 0xd2,0x1, 0x80,0x9, 0xb, 0xa0,0x7e,0xb, 0xb0,0xbc,0xba,0x38,0xc9,0xa2, +0x1, 0x22,0xca,0xd8,0xca,0x79,0x7e,0xa3,0x2a,0x6e,0x7e,0x47,0x28,0x99,0xe4,0x7a, +0xb3,0x28,0xa6,0x7e,0xb3,0x26,0xf0,0xbe,0xb0,0x0, 0x28,0x48,0x12,0x9e,0x47,0x28, +0x43,0x6c,0xff,0x80,0x3b,0x7e,0x50,0x2, 0xac,0x5f,0x9, 0xd2,0x27,0x36,0x9, 0xe2, +0x27,0x37,0x7e,0x50,0x2, 0xac,0x5e,0x49,0x12,0x4, 0xfc,0x6d,0x22,0x9e,0x27,0x2a, +0x53,0xbd,0x12,0x58,0x19,0x12,0x76,0xe8,0x49,0x12,0x4, 0xfc,0x6d,0x22,0x9e,0x27, +0x2a,0x51,0xbd,0x12,0x58,0x8, 0x74,0x1, 0x7a,0xb3,0x28,0xa6,0x80,0x6, 0xb, 0xf0, +0xbc,0x7f,0x38,0xc1,0xe4,0x7a,0xb3,0x28,0xa7,0x7e,0xb3,0x26,0x83,0x70,0x40,0x12, +0x76,0xe0,0x28,0x3b,0x6c,0xff,0x80,0x33,0x7e,0x50,0x2, 0xac,0x5f,0x9, 0xd2,0x26, +0xfa,0x9, 0xe2,0x26,0xfb,0x12,0x76,0xe8,0x49,0x2, 0x5, 0x7a,0x6d,0x11,0x9d,0x14, +0xbd,0x1, 0x48,0xd, 0x7e,0x10,0x2, 0xac,0x1e,0x49,0x20,0x5, 0x7a,0xbd,0x21,0x58, +0x8, 0x74,0x1, 0x7a,0xb3,0x28,0xa7,0x80,0x6, 0xb, 0xf0,0xbc,0x7f,0x38,0xc9,0x12, +0x9c,0xbc,0xe4,0x7a,0xb3,0x28,0xa9,0x7e,0x37,0x28,0x88,0x2e,0x37,0x28,0x86,0xbe, +0x37,0x28,0x9f,0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x28,0xa9,0x74,0x1, 0x7a,0xb3,0x28, +0xaa,0x6c,0xff,0x80,0x1f,0x12,0x76,0xf1,0x49,0x25,0x25,0xf7,0x7d,0x43,0x9d,0x42, +0x7d,0x34,0x12,0x21,0xa, 0xbe,0x37,0x28,0x9d,0x8, 0x7, 0xe4,0x7a,0xb3,0x28,0xaa, +0x80,0x7, 0xb, 0xf0,0x12,0x73,0x6d,0x38,0xdc,0x6c,0xff,0x80,0x9, 0x12,0x76,0xf1, +0x59,0x35,0x25,0xf7,0xb, 0xf0,0x12,0x73,0x6d,0x38,0xf2,0xda,0x79,0xda,0xd8,0x22, +0x7e,0x73,0x28,0x84,0xbe,0x70,0x0, 0x22,0xa, 0x1d,0xa, 0x2a,0x2d,0x21,0x3e,0x24, +0x22,0x7c,0xbf,0x12,0x6f,0x6b,0x74,0x2, 0xac,0xbf,0x22,0x7e,0x70,0x1, 0x2, 0x73, +0x2e,0x7e,0x34,0xd7,0x2, 0x7a,0x1b,0xb0,0x22,0x7e,0x34,0xd7,0x1, 0x7a,0x1b,0xb0, +0x22,0x7e,0x34,0xd7,0x0, 0x7e,0x24,0x0, 0xff,0x7a,0x1b,0xb0,0x22,0x12,0x77,0x74, +0x12,0x8d,0x9b,0x12,0x71,0x90,0x7a,0xb3,0x2a,0xc, 0x22,0x30,0x14,0x13,0x12,0xc7, +0x1, 0x68,0x6, 0x7e,0xb3,0x3a,0xc, 0x60,0x8, 0x7e,0x34,0xb, 0xb8,0x7a,0x37,0x38, +0xfc,0x22,0x7f,0x61,0x7f,0x50,0x7e,0x6b,0x90,0x80,0x1f,0x29,0x86,0x0, 0x1, 0x80, +0xf, 0x7f,0x5, 0x7c,0xb9,0x7c,0x78,0x12,0x75,0x90,0x50,0x2, 0xd3,0x22,0xb, 0x80, +0x29,0x76,0x0, 0x3, 0xbc,0x78,0x50,0xe9,0xb, 0x90,0x29,0x76,0x0, 0x2, 0xbc,0x79, +0x50,0xd9,0xc3,0x22,0x7e,0xa3,0x28,0x84,0xe4,0x7a,0xb3,0x34,0xb7,0x6c,0x33,0x80, +0x3d,0x7e,0x70,0x2, 0xac,0x73,0x9, 0x23,0x26,0xfb,0x7e,0x10,0x1, 0x6c,0x0, 0x80, +0x27,0xbc,0x3, 0x68,0x21,0x7e,0x70,0x2, 0xac,0x70,0x9, 0x93,0x26,0xfb,0xa, 0x29, +0xa, 0x32,0x12,0x82,0xcd,0x18,0x2, 0xb, 0x10,0xbe,0x10,0x2, 0x40,0x8, 0x74,0x2, +0x7a,0xb3,0x34,0xb7,0x80,0x6, 0xb, 0x0, 0xbc,0xa0,0x38,0xd5,0xb, 0x30,0xbc,0xa3, +0x38,0xbf,0x2, 0x77,0xc5,0xca,0xf8,0x7e,0x33,0x28,0x84,0x6c,0x22,0x80,0x3f,0x74, +0x2, 0xac,0xb2,0x9, 0x15,0x26,0xfa,0x9, 0x5, 0x26,0xfb,0x7e,0xa0,0x1, 0x6c,0x99, +0x80,0x26,0xbc,0x92,0x68,0x20,0x12,0x8f,0xde,0x9, 0xf3,0x26,0xfb,0xa, 0x28,0xa, +0x31,0x12,0x82,0xcd,0x18,0xb, 0xa, 0x2f,0xa, 0x30,0x12,0x82,0xcd,0x8, 0x2, 0xb, +0xa0,0xbe,0xa0,0x3, 0x50,0x6, 0xb, 0x90,0xbc,0x39,0x38,0xd6,0xb, 0x20,0xbc,0x32, +0x38,0xbd,0x7e,0xb3,0x35,0x54,0xbe,0xb0,0x0, 0x28,0x12,0x14,0x7a,0xb3,0x35,0x54, +0xbe,0xb0,0x14,0x28,0x8, 0x7e,0x34,0x0, 0x8c,0x7a,0x37,0x2a,0x5a,0x7e,0xb3,0x37, +0xed,0x70,0x58,0x7e,0xb3,0x3a,0xc, 0x70,0x52,0x7e,0xb3,0x37,0x71,0x70,0x4c,0x7e, +0x37,0x38,0xfe,0xbe,0x34,0x0, 0x14,0x50,0x42,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x3, +0x20,0x58,0x38,0x7e,0xb3,0x28,0x84,0xbe,0xb0,0x3, 0x40,0x2f,0xbe,0xa0,0x3, 0x40, +0x2a,0x7e,0xb3,0x26,0x85,0xbe,0xb0,0x3, 0x50,0x9, 0x7e,0xb3,0x26,0x84,0xbe,0xb0, +0x3, 0x40,0x18,0x7e,0xb3,0x26,0xf6,0xbe,0xb0,0x8, 0x50,0x9, 0x7e,0xb3,0x26,0xf7, +0xbe,0xb0,0x8, 0x40,0x6, 0x74,0x1e,0x7a,0xb3,0x35,0x54,0xda,0xf8,0x22,0xca,0xf8, +0x7e,0xa3,0x2a,0x2, 0x4c,0xaa,0x78,0x11,0x7e,0xb3,0x2a,0x3, 0xbe,0xb0,0x0, 0x28, +0x13,0x74,0x1, 0x7a,0xb3,0x2a,0x7, 0x80,0xb, 0xbe,0xa0,0x0, 0x28,0x6, 0x74,0x1, +0x7a,0xb3,0x2a,0xb, 0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x28,0xae,0x7e,0x8, +0x29,0x8, 0x12,0x20,0xc3,0x1b,0xfd,0x6c,0xff,0x12,0x7d,0x51,0x12,0x7a,0xa2,0x74, +0x9, 0xac,0xbf,0x59,0x35,0x29,0x8, 0x49,0x35,0x28,0xb0,0x12,0x78,0xeb,0x12,0x79, +0xe0,0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xe1,0xda,0xf8,0x22,0x7d,0xf3,0x9f,0x11,0x7e, +0x44,0x7, 0x80,0x12,0x7b,0x74,0x7d,0xd5,0x1b,0xd4,0xbe,0xf4,0x0, 0x3f,0x38,0x1f, +0x7e,0x24,0x0, 0x3f,0x9d,0x2f,0x7e,0x34,0x2, 0x57,0x12,0x79,0xc5,0xbe,0x18,0x0, +0x4a,0x40,0x4, 0x7e,0x18,0x0, 0x4a,0x7e,0x8, 0x0, 0x4a,0x9f,0x1, 0x7f,0x10,0x7d, +0x5d,0x9e,0x54,0x0, 0x3f,0xbd,0x5f,0x38,0x1f,0x12,0x79,0xd7,0x40,0x1a,0x7d,0x3d, +0x9e,0x34,0x0, 0x40,0x12,0x79,0xbd,0xbe,0x18,0x0, 0x4d,0x40,0x4, 0x7e,0x18,0x0, +0x4c,0x12,0x79,0xce,0x2f,0x10,0x80,0x14,0x12,0x79,0xd7,0x50,0xf, 0x7d,0x3d,0x9e, +0x34,0x0, 0x20,0x12,0x79,0xbd,0x7d,0x14,0x6d,0x0, 0x2f,0x10,0xbe,0xf4,0x0, 0x3f, +0x28,0x5a,0xbd,0x5f,0x28,0x56,0x7d,0xed,0xb, 0xe4,0x1e,0xe4,0x7d,0x5e,0x1b,0x54, +0xbd,0x5f,0x40,0xc, 0x7d,0x35,0x9d,0x3f,0x6d,0x22,0x7e,0x14,0x1, 0x44,0x80,0xa, +0x7d,0x3f,0x9d,0x3e,0x6d,0x22,0x7e,0x14,0x1, 0x43,0x12,0x1e,0xfc,0x12,0x79,0xc7, +0xbd,0x5f,0x7d,0x14,0x40,0xc, 0x1e,0x14,0x1b,0x14,0x6d,0x0, 0x9f,0x1, 0x7f,0x10, +0x80,0x6, 0x1e,0x14,0x6d,0x0, 0x2f,0x10,0xbe,0x18,0x0, 0x4a,0x50,0x5, 0x7e,0x18, +0x0, 0x4a,0x22,0x12,0x79,0xce,0xbf,0x10,0x28,0x2, 0x7f,0x10,0x22,0x7d,0x2f,0x9d, +0x23,0x7e,0x34,0x2, 0x52,0xad,0x23,0x7c,0x76,0x7c,0x65,0x1a,0x24,0x22,0x7d,0x14, +0x6d,0x0, 0x9e,0x8, 0x0, 0x4d,0x22,0x7d,0xed,0x9e,0xe4,0x0, 0xb, 0xbd,0xef,0x22, +0x74,0x9, 0xac,0xbf,0x59,0x35,0x29,0xa, 0x22,0xca,0xd8,0xca,0x79,0x7e,0x44,0x7, +0x80,0x6c,0xff,0x7e,0x70,0x9, 0xac,0x7f,0x9, 0xe3,0x29,0xc, 0x5e,0xe0,0xf, 0x49, +0xc3,0x29,0xa, 0x7d,0x24,0x2e,0x24,0x0, 0x14,0xbd,0xc2,0x40,0x3f,0x49,0xd3,0x29, +0x8, 0x7d,0x3d,0x12,0xa4,0xe5,0x7c,0xdb,0xbe,0xd0,0x3, 0x40,0xe, 0x7d,0x34,0x1b, +0x34,0x12,0x79,0xe0,0x7c,0xbe,0x12,0x7a,0x77,0x80,0x40,0x7e,0x70,0x2, 0xac,0x7d, +0x2e,0x34,0x60,0xc5,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0xd0,0x74,0x9, 0xac,0xbf,0x59, +0xd5,0x29,0x8, 0x7e,0x34,0x7, 0xf8,0x12,0x79,0xe0,0x80,0x1f,0xbd,0xc4,0x40,0x1b, +0x7d,0x54,0x2e,0x54,0x0, 0xa, 0xbd,0xc5,0x40,0x5, 0x7c,0xbe,0x12,0x7a,0x77,0x7d, +0xc4,0x1b,0xc4,0x74,0x9, 0xac,0xbf,0x59,0xc5,0x29,0xa, 0xb, 0xf0,0xbe,0xf0,0xa, +0x40,0x81,0xda,0x79,0xda,0xd8,0x22,0x7c,0xab,0x7e,0x8, 0x29,0xbc,0xbe,0xa0,0xa, +0x50,0x1f,0xa, 0x3a,0x7f,0x70,0x2d,0xf3,0x7e,0x7b,0xb0,0xb4,0x2, 0x4, 0x74,0x1, +0x80,0x2, 0x74,0x3, 0x7a,0x7b,0xb0,0x74,0x3, 0x2d,0x31,0x7d,0x20,0x39,0xb1,0x0, +0xa, 0x22,0x7d,0xd3,0x7e,0x44,0x4, 0x38,0x7e,0xa3,0x2a,0x6f,0x74,0x40,0xa4,0x7d, +0xb5,0x1b,0xb4,0xbe,0xd4,0x0, 0x3f,0x38,0x1d,0x7e,0xe4,0x0, 0x3f,0x9d,0xed,0x7e, +0xf4,0x2, 0x36,0x12,0x7b,0x61,0x40,0x4, 0x7e,0x78,0x0, 0x44,0x7e,0x18,0x0, 0x44, +0x9f,0x17,0x7f,0x71,0x80,0x7f,0x7d,0x5b,0x9e,0x54,0x0, 0x3f,0xbd,0x5d,0x38,0x18, +0x7d,0xed,0x9d,0xe5,0x7e,0xf4,0x2, 0x4a,0x12,0x7b,0x61,0x40,0x4, 0x7e,0x78,0x0, +0x43,0x12,0x7b,0x58,0x2f,0x71,0x80,0x5d,0x7d,0xcb,0xb, 0xc4,0x1e,0xc4,0x7d,0x5c, +0x1b,0x54,0xbd,0x5d,0x40,0xc, 0x7d,0xf5,0x9d,0xfd,0x6d,0xee,0x7e,0x14,0x1, 0x39, +0x80,0xa, 0x7d,0xfd,0x9d,0xfc,0x6d,0xee,0x7e,0x14,0x1, 0x3b,0x7f,0x17,0x12,0x1e, +0xfc,0x7f,0x71,0x12,0x45,0xb1,0x7f,0x71,0xbd,0x5d,0x7d,0x34,0x40,0xc, 0x1e,0x34, +0x1b,0x34,0x6d,0x22,0x9f,0x17,0x7f,0x71,0x80,0x6, 0x1e,0x34,0x6d,0x22,0x2f,0x71, +0xbe,0x78,0x0, 0x44,0x50,0x6, 0x7e,0x78,0x0, 0x44,0x80,0x9, 0x12,0x7b,0x58,0xbf, +0x71,0x28,0x2, 0x7f,0x71,0x7d,0x3f,0x22,0x7d,0x34,0x9e,0x34,0x0, 0x44,0x6d,0x22, +0x22,0xad,0xfe,0x6d,0xee,0x7d,0x3f,0x7d,0x2e,0x7c,0x76,0x7c,0x65,0x7f,0x71,0xbe, +0x78,0x0, 0x44,0x22,0x7e,0xa3,0x2a,0x70,0x74,0x40,0xa4,0x22,0xca,0x3b,0x6d,0x0, +0x7e,0xe3,0x2a,0x2, 0x4c,0xee,0x78,0x20,0x6c,0xff,0x6d,0x11,0x74,0x2, 0xac,0xbf, +0x12,0x7d,0x46,0xac,0x3f,0x19,0xa1,0x34,0xe0,0x74,0x2, 0xa, 0x1f,0x19,0xb1,0x35, +0x4a,0xb, 0xf0,0xbe,0xf0,0xa, 0x78,0xe2,0x12,0x7d,0xb3,0x7e,0x24,0x0, 0x14,0xad, +0x32,0x7d,0x43,0x2e,0x44,0x3, 0x20,0x6c,0xff,0xa1,0x18,0x74,0x9, 0xac,0xbf,0x9, +0xd5,0x28,0xb2,0x5e,0xd0,0xf, 0xbe,0xd0,0xa, 0x40,0x2, 0xa1,0x16,0xa, 0x1d,0x9, +0xb1,0x29,0xbc,0xbe,0xb0,0x1, 0x78,0x2, 0x81,0xff,0x75,0x24,0x0, 0x7e,0x71,0x24, +0x74,0x9, 0xac,0x7b,0x9, 0xc3,0x34,0xe0,0xbc,0xcd,0x68,0x2, 0x81,0xf2,0x12,0x7b, +0x74,0x7d,0xf5,0x9e,0xf4,0x0, 0x20,0x2e,0xf4,0x0, 0x14,0x49,0x23,0x34,0xde,0xbd, +0x2f,0x28,0xe, 0x74,0x9, 0xac,0xbf,0x49,0x15,0x28,0xb0,0xbd,0x1f,0x38,0x2, 0x81, +0x9e,0x74,0x9, 0xac,0xbf,0x49,0x35,0x28,0xb0,0x9d,0x32,0x12,0x21,0xa, 0x7d,0x3, +0x7e,0xa1,0x24,0x74,0x9, 0xa4,0x49,0x25,0x34,0xdc,0x12,0x7d,0x51,0x9d,0x32,0x12, +0x21,0xa, 0x2d,0x3, 0xa, 0x1c,0x9, 0xa1,0x35,0x4a,0xbe,0xa0,0x0, 0x28,0x17,0x7e, +0x30,0x2, 0xac,0x3c,0x59,0x1, 0x35,0x36,0xa, 0x1c,0x2e,0x14,0x35,0x4a,0x7c,0xba, +0x14,0x7a,0x19,0xb0,0xa1,0x16,0x74,0x2, 0xac,0xbc,0x49,0x15,0x35,0x36,0xbe,0x14, +0x0, 0x32,0x28,0x8, 0x7d,0xe1,0x2d,0xe4,0xbd,0xe0,0x40,0x20,0xbe,0x14,0x0, 0x32, +0x28,0x8, 0xbe,0x4, 0x0, 0x32,0x28,0x2, 0x80,0x72,0x7d,0xe1,0x2e,0xe4,0x0, 0x32, +0xbd,0xe0,0x50,0x8, 0xbe,0x14,0x0, 0x32,0x28,0x2, 0x80,0x60,0xbe,0x4, 0x0, 0xa0, +0x28,0x56,0xa, 0x1d,0x9, 0xb1,0x29,0xbc,0x70,0x4, 0x74,0x3, 0x80,0x2, 0x74,0x1, +0xa, 0x1d,0x19,0xb1,0x29,0xbc,0x74,0x3, 0xa, 0x1c,0x19,0xb1,0x29,0xc6,0xbe,0xe0, +0x0, 0x28,0x63,0x1b,0xe0,0x7e,0x70,0x9, 0xac,0x7f,0x2e,0x34,0x28,0xae,0x7e,0x14, +0x1f,0x34,0x74,0x9, 0x12,0x1f,0x8c,0x7e,0x70,0x9, 0xac,0x7e,0x12,0x7f,0xa0,0xac, +0x3f,0x12,0x7d,0x3d,0x7e,0x34,0x1f,0x34,0x7e,0x30,0x9, 0xac,0x3e,0x12,0x7d,0x3d, +0x1b,0xf0,0x74,0x2, 0xac,0xbc,0x80,0x4, 0x74,0x2, 0xac,0xbc,0x59,0x5, 0x35,0x36, +0x80,0x24,0x5, 0x24,0xe5,0x24,0xbe,0xb0,0xa, 0x50,0x2, 0x61,0xdd,0x80,0x17,0x6d, +0x11,0x74,0x2, 0xac,0xbd,0x12,0x7d,0x46,0xac,0x3d,0x19,0xa1,0x34,0xe0,0x74,0x2, +0xa, 0x1d,0x19,0xb1,0x35,0x4a,0xb, 0xf0,0xbc,0xef,0x28,0x2, 0x61,0xbb,0xe4,0x7a, +0xb3,0x16,0x92,0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x28,0xae,0x7e,0x8, 0x34, +0xdc,0x12,0x20,0xc3,0x1b,0xfd,0x7a,0xe3,0x2a,0x2, 0xda,0x3b,0x22,0x2e,0x14,0x28, +0xae,0x74,0x9, 0x2, 0x1f,0x8c,0x59,0x15,0x35,0x36,0x7e,0xa0,0xff,0x7e,0x30,0x9, +0x22,0x74,0x9, 0xac,0xbf,0x49,0x35,0x28,0xae,0x22,0x7e,0xb3,0x38,0x32,0x70,0x3, +0x12,0x7b,0x7c,0x2, 0x7d,0x66,0xca,0x79,0x7e,0xf3,0x2a,0x2, 0x7e,0xe3,0x2a,0x3, +0x7c,0xbf,0x7c,0x7e,0x12,0x7e,0x9f,0x7c,0xbf,0x12,0x9e,0x59,0x4c,0xee,0x78,0x15, +0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x28,0xae,0x7e,0x8, 0x29,0x62,0x12,0x20, +0xc3,0x1b,0xfd,0x80,0xb, 0x7e,0xb3,0x2a,0x9, 0x70,0x5, 0x7c,0xbf,0x12,0x7f,0x12, +0x7c,0xbf,0x12,0x7d,0xeb,0xbe,0xf0,0x0, 0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x2a,0xb, +0xda,0x79,0x22,0x7e,0x73,0x2a,0x3, 0xbe,0x73,0x2a,0x2, 0x78,0x13,0x12,0x7f,0x98, +0x40,0xe, 0x7e,0x37,0x34,0xb4,0xbe,0x34,0x0, 0x14,0x38,0xe, 0xb, 0x34,0x80,0x6, +0x7e,0x37,0x34,0xb4,0x1e,0x34,0x7a,0x37,0x34,0xb4,0x7e,0xb3,0x2a,0x2, 0x70,0x6, +0x6d,0x33,0x7a,0x37,0x34,0xb4,0x7e,0x37,0x34,0xb4,0x22,0x6c,0xaa,0x7e,0x50,0x9, +0xac,0x5a,0x49,0x32,0x29,0x62,0x12,0x7e,0x3c,0x59,0x32,0x28,0xae,0x7e,0x50,0x9, +0xac,0x5a,0x49,0x32,0x29,0x64,0x12,0x7e,0x3c,0x59,0x32,0x28,0xb0,0x7e,0x90,0x9, +0xac,0x9a,0x9, 0xb4,0x29,0x66,0x19,0xb4,0x28,0xb2,0x7e,0x90,0x9, 0xac,0x9a,0x9, +0xb4,0x29,0x67,0x19,0xb4,0x28,0xb3,0x7e,0x90,0x9, 0xac,0x9a,0x9, 0xb4,0x29,0x68, +0x19,0xb4,0x28,0xb4,0xb, 0xa0,0xbe,0xa0,0xa, 0x40,0xb2,0x22,0x1e,0x34,0x1e,0x34, +0x1e,0x34,0x1e,0x34,0x22,0x7f,0x71,0x69,0x37,0x0, 0x2, 0x7d,0x53,0x12,0x7f,0x90, +0xb, 0x7a,0x20,0x2d,0x25,0x1b,0xa, 0x20,0x69,0x27,0x0, 0x4, 0x7d,0x52,0xc4,0x54, +0xf0,0x7c,0xab,0xe4,0x1e,0x34,0x1e,0x34,0x2d,0x35,0x79,0x30,0x0, 0x2, 0x69,0x37, +0x0, 0x6, 0x7d,0x53,0x7c,0xab,0xe4,0x3e,0x54,0x3e,0x54,0x1e,0x24,0x1e,0x24,0x1e, +0x24,0x1e,0x24,0x2d,0x25,0x79,0x20,0x0, 0x4, 0x69,0x27,0x0, 0x8, 0x7c,0x45,0x6c, +0x55,0x12,0x7e,0x3c,0x1e,0x34,0x1e,0x34,0x2d,0x32,0x79,0x30,0x0, 0x6, 0x22,0x7c, +0x67,0x7c,0x7b,0xa5,0xbf,0x0, 0x17,0xbe,0x60,0x0, 0x28,0xf, 0x74,0x1, 0x7a,0xb3, +0x2a,0x7, 0xe4,0x7a,0xb3,0x2a,0x9, 0x7a,0xb3,0x2a,0xa, 0x2, 0x7f,0xb5,0xa5,0xbe, +0x0, 0x1b,0x6c,0xaa,0x7e,0x60,0xff,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x62,0x29,0x66, +0xb, 0xa0,0xbe,0xa0,0xa, 0x78,0xf0,0x74,0x1, 0x7a,0xb3,0x2a,0x6, 0x6c,0xaa,0x80, +0x20,0x7e,0x30,0x9, 0xac,0x3a,0x2e,0x14,0x28,0xae,0x12,0x7f,0x6, 0x1b,0x18,0x20, +0x7e,0x30,0x9, 0xac,0x3a,0x2e,0x14,0x28,0xb0,0x12,0x7f,0x6, 0x1b,0x18,0x20,0xb, +0xa0,0xbc,0x7a,0x38,0xdc,0x22,0xb, 0x18,0x20,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e, +0x24,0x22,0xca,0x3b,0x7c,0xfb,0x6c,0xee,0x80,0x6c,0x6c,0xdd,0x74,0x9, 0xac,0xbd, +0x9, 0x45,0x29,0x66,0x7e,0x70,0x9, 0xac,0x7e,0x9, 0x53,0x28,0xb2,0xbc,0x45,0x68, +0x7, 0xb, 0xd0,0xbe,0xd0,0xa, 0x40,0xe4,0xbe,0xd0,0xa, 0x50,0x4d,0x74,0x9, 0xac, +0xbd,0x9, 0xc5,0x29,0x66,0x49,0x25,0x29,0x64,0x49,0x33,0x28,0xb0,0x12,0x4f,0xcc, +0x74,0x9, 0xac,0xbd,0x12,0x7f,0xa8,0x9d,0x32,0x12,0x21,0xa, 0x2d,0x31,0x7a,0x35, +0x24,0xa, 0x3c,0x9, 0xb3,0x29,0xbc,0xb4,0x1, 0xe, 0x6d,0x33,0x74,0x2, 0xac,0xbc, +0x59,0x35,0x34,0xa0,0x59,0x35,0x34,0xc6,0x7e,0x35,0x24,0x7c,0xbd,0x7c,0x5e,0x7c, +0x4c,0x12,0x7f,0x8d,0xb, 0xe0,0xbc,0xfe,0x38,0x90,0xda,0x3b,0x22,0x2, 0x47,0x36, +0x3, 0x3, 0x54,0xc0,0x7c,0xab,0xe4,0x22,0x7e,0x73,0x2a,0x2, 0xbe,0x70,0x1, 0x22, +0x2e,0x34,0x28,0xae,0x7e,0x30,0x9, 0x22,0x49,0x25,0x29,0x62,0x74,0x9, 0xac,0xbe, +0x49,0x35,0x28,0xae,0x22,0x7e,0x8, 0x34,0xc6,0x7e,0x34,0x0, 0x14,0xe4,0x12,0x20, +0xe8,0x7e,0x8, 0x34,0xa0,0x7e,0x34,0x0, 0x14,0x2, 0x20,0xe8,0x7e,0xb3,0x2a,0x9, +0x70,0x23,0x7e,0xb3,0x34,0xb7,0xb4,0x2, 0x9, 0x12,0x7f,0x98,0x28,0x4, 0x74,0x3, +0x80,0x1, 0xe4,0x7a,0xb3,0x34,0xc2,0x7e,0x73,0x34,0xc3,0xbe,0x73,0x34,0xc2,0x28, +0x4, 0x7a,0x73,0x34,0xc2,0x22,0x12,0xa0,0x50,0x2, 0x7f,0xcc,0x7e,0xb3,0x2a,0x3, +0xb4,0x1, 0x22,0x7e,0xb3,0x28,0x84,0xb4,0x1, 0x1b,0x7e,0xb3,0x28,0xa8,0x70,0x15, +0x7e,0xb3,0x26,0x83,0xb4,0x1, 0xe, 0x7e,0xb3,0x28,0x85,0x70,0x8, 0x7e,0xb3,0x2a, +0x68,0x70,0x2, 0xd3,0x22,0xc3,0x22,0x7d,0x13,0x7d,0x32,0x6d,0x22,0x74,0x6, 0x2f, +0x11,0x14,0x78,0xfb,0xb, 0x14,0x12,0x1f,0x5, 0x7d,0x53,0xbe,0x54,0x0, 0xff,0x28, +0x4, 0x7e,0x54,0x0, 0x40,0x22,0xca,0xf8,0x7e,0xf3,0x2a,0x70,0x7a,0x37,0x1f,0x3a, +0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f,0x3c,0xe4,0x7a,0xb3,0x1f,0x34,0x7a,0xb3,0x1f, +0x35,0x7e,0x73,0x2a,0x6f,0x7a,0x73,0x1f,0x36,0x7a,0xf3,0x1f,0x37,0x7a,0xb3,0x1f, +0x38,0x7a,0xb3,0x1f,0x39,0x7e,0x8, 0x1f,0x34,0x12,0x80,0x9b,0x6d,0x22,0x7d,0x3, +0x6d,0x11,0x7e,0x37,0x15,0xa0,0x2f,0x10,0x7e,0x33,0x1f,0x36,0x6d,0x0, 0x12,0x1f, +0x7, 0xa, 0x1f,0x6d,0x0, 0x12,0x1f,0x7, 0xda,0xf8,0x22,0x12,0xc, 0x29,0x7e,0x37, +0x15,0x9e,0x22,0xca,0x3b,0x7c,0xc4,0x7c,0xf6,0x7c,0xe7,0x7c,0xdb,0x74,0x9, 0xac, +0xb5,0x7d,0x95,0x2e,0x94,0x27,0x76,0x6d,0x88,0x7e,0xe7,0x2a,0x66,0xe4,0x39,0xb4, +0x0, 0x6, 0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xb3,0x26,0xfa,0xf5,0x35,0x9, 0xb3,0x26, +0xfb,0xf5,0x36,0x7e,0x73,0x2a,0x6e,0x7c,0x6e,0x7e,0x8, 0x0, 0x39,0x12,0x82,0xe6, +0xf5,0x37,0xe5,0x35,0x7e,0x73,0x2a,0x6d,0x7c,0x6d,0x7e,0x8, 0x0, 0x38,0x12,0x82, +0xe6,0x7c,0xab,0xe5,0x38,0x7e,0x71,0x39,0x12,0x6f,0x81,0x7d,0xf3,0x7a,0xf5,0x41, +0x7e,0xf4,0x15,0x9e,0x7a,0xf5,0x43,0x85,0x38,0x3b,0x85,0x39,0x3c,0x7a,0xa1,0x3d, +0x85,0x37,0x3e,0x7e,0xb3,0x2a,0x59,0xf5,0x3f,0x75,0x40,0x0, 0xbe,0xc0,0x1, 0x78, +0x8, 0xe5,0x3f,0x1e,0xb0,0x1e,0xb0,0xf5,0x3f,0x7e,0x8, 0x0, 0x3b,0x12,0x80,0x9b, +0x7d,0x23,0x6d,0x33,0x7e,0xb7,0x15,0xa0,0x6d,0xaa,0x2f,0x51,0x7e,0x37,0x15,0xa2, +0x6d,0x22,0x7d,0x3, 0x6d,0x11,0x7e,0x37,0x15,0xa4,0x2f,0x10,0x7a,0x1d,0x2c,0x7e, +0x37,0x15,0xa6,0x6d,0x22,0x7d,0x3, 0x7e,0x37,0x15,0xa8,0x2f,0x10,0x7a,0x1d,0x30, +0x7f,0x65,0xa, 0x3d,0xe5,0x35,0xa, 0xfb,0x9d,0xf3,0x7d,0x3f,0x7c,0xc7,0x41,0x48, +0xa, 0x4e,0xe5,0x36,0xa, 0x5b,0x9d,0x54,0xf5,0x34,0x41,0x32,0xbe,0xc0,0x0, 0x58, +0x2, 0x41,0x30,0x7e,0x73,0x2a,0x6d,0xbc,0x7c,0x18,0x2, 0x41,0x30,0xe5,0x34,0xbe, +0xb0,0x0, 0x58,0x2, 0x41,0x30,0x7e,0x73,0x2a,0x6e,0xbe,0x71,0x34,0x18,0x2, 0x41, +0x30,0x7c,0xbc,0x7e,0x71,0x34,0x12,0x6d,0xcb,0x7e,0x53,0x2a,0x59,0xa, 0x25,0x7d, +0xf3,0x9d,0xf2,0xbe,0xf4,0x0, 0x0, 0x8, 0x77,0xbd,0xef,0x18,0xd, 0x7f,0x14,0x2e, +0x34,0x0, 0x6, 0x7e,0x1b,0xb0,0x4, 0x7a,0x1b,0xb0,0xe5,0x35,0xa, 0x2b,0x1a,0x3c, +0x12,0x82,0xcd,0x18,0xd, 0xe5,0x36,0xa, 0x2b,0xe5,0x34,0x1a,0x3b,0x12,0x82,0xcd, +0x8, 0x4e,0x7c,0xbc,0x7e,0x71,0x34,0x7c,0x6f,0x12,0x83,0x39,0xf5,0x3a,0xb4,0x2, +0x6, 0x7d,0x3f,0xe, 0x34,0x9d,0xf3,0xe5,0x3a,0xbe,0xb0,0x2, 0x68,0x5, 0xe5,0x3a, +0xb4,0x1, 0x2d,0x12,0x82,0xbe,0x1a,0x1c,0x12,0x82,0xc5,0x7e,0x1d,0x2c,0x9f,0x10, +0x7a,0x1d,0x2c,0x12,0x82,0xbe,0xe5,0x34,0x1a,0x1b,0x12,0x82,0xc5,0x7e,0x1d,0x30, +0x9f,0x10,0x7a,0x1d,0x30,0x12,0x82,0xbe,0x9f,0x51,0x1a,0x26,0x1a,0x24,0x9f,0x61, +0x5, 0x34,0xa, 0x2e,0xe5,0x36,0xa, 0x3b,0x2d,0x32,0x1a,0x27,0xe5,0x34,0x1a,0x3b, +0xbd,0x32,0x18,0x2, 0x21,0x7c,0xb, 0xc0,0xa, 0x2d,0xe5,0x35,0xa, 0x3b,0x2d,0x32, +0x1a,0x37,0x1a,0xfc,0xbd,0xf3,0x18,0x2, 0x21,0x70,0xbe,0x58,0x0, 0x0, 0x78,0x2, +0xb, 0x5c,0xbe,0x68,0x0, 0x0, 0x78,0x2, 0xb, 0x6c,0x7e,0x1d,0x2c,0x7f,0x5, 0x12, +0x82,0xd7,0x1b,0x4a,0x30,0x7e,0x1d,0x30,0x7f,0x6, 0x12,0x82,0xd7,0x79,0x34,0x0, +0x2, 0x7e,0xb3,0x2a,0x65,0x60,0xd, 0x1e,0xd4,0x1e,0xc4,0x50,0x4, 0x4e,0xd4,0x80, +0x0, 0x14,0x78,0xf3,0xbe,0x68,0x0, 0x7f,0x28,0x4, 0x7e,0x68,0x0, 0x7f,0x7d,0x3d, +0x39,0x74,0x0, 0x5, 0x74,0x9, 0xac,0xbf,0x9, 0x75,0x27,0x7c,0x39,0x74,0x0, 0x6, +0xbe,0x70,0xf, 0x28,0x6, 0x74,0xf, 0x39,0xb4,0x0, 0x6, 0xda,0x3b,0x22,0x7d,0x3f, +0x1a,0x26,0x1a,0x24,0x22,0x1a,0x2, 0x12,0x1e,0xeb,0x7f,0x1, 0x22,0x9d,0x32,0x12, +0x21,0xa, 0xbe,0x34,0x0, 0x1, 0x22,0x74,0x6, 0x2f,0x11,0x14,0x78,0xfb,0x12,0x1f, +0x7, 0x2e,0x18,0x0, 0x20,0x22,0xca,0xf8,0x7c,0xf6,0x7c,0x87,0x7c,0x9b,0xa, 0x2f, +0x7d,0x32,0x3e,0x34,0xb, 0x34,0x7c,0xb7,0xbc,0xf9,0x38,0x14,0xa, 0xf8,0x1b,0xf4, +0xa, 0x3f,0x9d,0xf3,0xa, 0x39,0xbd,0x3f,0x18,0x6, 0x7c,0xab,0xa, 0x39,0x80,0x1d, +0xbc,0xf9,0x28,0xd, 0xa, 0x39,0xa, 0x5f,0x2d,0x53,0xb, 0x54,0x7c,0xab,0xe4,0x80, +0x10,0xa, 0x3f,0xa, 0x58,0x2d,0x53,0xa, 0x39,0x9d,0x53,0x7c,0xab,0x9d,0x32,0x7c, +0xb7,0x7a,0xb, 0xb0,0x7c,0xba,0xda,0xf8,0x22,0x7c,0xa6,0x7c,0x37,0x7c,0x2b,0xe4, +0x6c,0x11,0x80,0x46,0xbc,0xa1,0x68,0x40,0x1a,0x41,0x3e,0x44,0x9, 0x4, 0x26,0xfb, +0xa, 0x20,0xa, 0x33,0x9d,0x32,0x12,0x21,0xa, 0x7c,0x7, 0x1a,0x41,0x3e,0x44,0x9, +0x74,0x26,0xfa,0xa, 0x27,0xa, 0x32,0x9d,0x32,0x12,0x21,0xa, 0x7c,0x97,0xbe,0x90, +0x1, 0x18,0x8, 0xbe,0x0, 0x1, 0x18,0x3, 0x74,0x1, 0x22,0xbe,0x90,0x2, 0x18,0x8, +0xbe,0x0, 0x2, 0x18,0x3, 0x74,0x2, 0x22,0xb, 0x10,0x7e,0x83,0x28,0x84,0xbc,0x81, +0x18,0xb2,0x22,0x7a,0x37,0x1f,0x38,0x7e,0x34,0x15,0xa8,0x7a,0x37,0x1f,0x3c,0x7e, +0x34,0x15,0x9e,0x7a,0x37,0x1f,0x3a,0x7e,0x73,0x2a,0x6f,0x7a,0x73,0x1f,0x35,0x7e, +0x73,0x2a,0x70,0x7a,0x73,0x1f,0x34,0x7e,0x37,0x2a,0x5c,0x7a,0x37,0x1f,0x3e,0x7e, +0x37,0x2a,0x5e,0x7a,0x37,0x1f,0x40,0x7e,0x37,0x2a,0x60,0x7a,0x37,0x1f,0x42,0x74, +0x1, 0x7a,0xb3,0x1f,0x36,0x7a,0xb3,0x1f,0x37,0x7e,0x8, 0x1f,0x34,0x7e,0x18,0x1f, +0x44,0x12,0x8, 0x0, 0x7e,0x37,0x1f,0x4e,0x7e,0x27,0x1f,0x4a,0xbd,0x23,0x28,0x2, +0x7d,0x32,0x22,0xca,0x3b,0x7e,0x8, 0x1f,0x34,0x12,0x3f,0xf2,0x7e,0x1f,0x39,0xf4, +0x7a,0x1d,0x27,0x7e,0xb3,0x2a,0x74,0xf5,0x2e,0x7e,0xb3,0x39,0x87,0xb4,0x1, 0x6, +0x7e,0x38,0x39,0x89,0x80,0x4, 0x7e,0x38,0x5, 0xf8,0x6d,0x33,0x7a,0x35,0x2b,0x74, +0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x39,0x88,0x70,0xe, 0x7e,0xb3,0x39,0x86,0x70,0x8, +0x74,0x1, 0x7a,0xb3,0x39,0x88,0x81,0xb8,0x7e,0xb3,0x39,0x88,0x70,0x6, 0x74,0x1, +0x7a,0xb3,0x39,0x88,0x7e,0xb3,0x39,0x87,0xb4,0x1, 0x14,0x75,0x2d,0x0, 0x80,0x6, +0x12,0x84,0xfa,0x12,0x85,0x8, 0xe5,0x2e,0xbe,0xb1,0x2d,0x38,0xf3,0x80,0x18,0x75, +0x2d,0x0, 0x80,0xc, 0x12,0x84,0xfa,0x3e,0x24,0x3e,0x24,0x1e,0x24,0x12,0x85,0x8, +0xe5,0x2e,0xbe,0xb1,0x2d,0x38,0xed,0x7e,0x34,0x0, 0xfa,0x7a,0x35,0x2f,0x7e,0x18, +0x1f,0x34,0x7f,0x1, 0x12,0x85,0x19,0x75,0x2d,0x0, 0x80,0x10,0x12,0x84,0xed,0xbe, +0x35,0x2b,0x8, 0x6, 0x12,0x84,0xed,0x7a,0x35,0x2b,0x5, 0x2d,0xe5,0x2e,0xbe,0xb1, +0x2d,0x38,0xe9,0x12,0x84,0xe5,0x40,0x25,0x7e,0xb3,0x39,0x87,0xb4,0x1, 0x1e,0x5, +0x1e,0xe5,0x1e,0xbe,0xb0,0xa, 0x40,0x15,0x75,0x1e,0x0, 0xe5,0x2e,0xa, 0x3b,0x3e, +0x34,0xca,0x39,0x7e,0x1d,0x27,0x7f,0x3, 0x12,0x20,0xc3,0x1b,0xfd,0x74,0x2, 0x12, +0x0, 0x1e,0x12,0x84,0xe5,0x50,0xb, 0x74,0x2, 0x7a,0xb3,0x39,0xf3,0xe4,0x7a,0xb3, +0x39,0x88,0xda,0x3b,0x22,0x7e,0x37,0x2b,0x7, 0xbe,0x35,0x2b,0x22,0x7e,0xa1,0x2d, +0x74,0x2, 0xa4,0x49,0x35,0x1f,0x34,0x2, 0x21,0xa, 0x7e,0xa1,0x2d,0x74,0x2, 0xa4, +0x7f,0x13,0x2d,0x35,0xb, 0x1a,0x20,0x22,0x7e,0xd, 0x27,0x2d,0x15,0xb, 0xa, 0x30, +0x9d,0x32,0x59,0x35,0x1f,0x34,0x5, 0x2d,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e, +0x73,0x2a,0x6e,0xa, 0x37,0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x20,0xc3, +0x1b,0xfd,0x6c,0xdd,0x12,0x87,0xb8,0x7a,0xb3,0x1f,0x6c,0x6c,0xcc,0x80,0x45,0x12, +0x85,0xbf,0x78,0x3e,0x12,0x87,0xc0,0xb, 0x1a,0xe0,0x7d,0x3f,0x12,0x21,0xa, 0x7d, +0x13,0x7d,0x3e,0x12,0x21,0xa, 0xbd,0x31,0x58,0x2, 0x7d,0xfe,0xbe,0xe5,0x2f,0x8, +0x5, 0x7e,0xe5,0x2f,0x80,0xb, 0x6d,0x33,0x9e,0x35,0x2f,0xbd,0x3e,0x8, 0x2, 0x7d, +0xe3,0x7d,0x3e,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x1f,0x6c,0x4, 0x7a,0xb3, +0x1f,0x6c,0xb, 0xc0,0x7e,0x73,0x2a,0x70,0xbc,0x7c,0x38,0xb3,0x7e,0x73,0x1f,0x6c, +0x4c,0x77,0x68,0x1f,0x12,0x87,0xc9,0xbd,0x3e,0x8, 0x2, 0x7d,0x7f,0x6c,0xcc,0x80, +0xa, 0x12,0x85,0xbf,0x78,0x3, 0x12,0x87,0xde,0xb, 0xc0,0x7e,0x73,0x2a,0x70,0xbc, +0x7c,0x38,0xee,0xb, 0xd0,0xbe,0xd0,0x2, 0x50,0x2, 0xa1,0x34,0xda,0x3b,0x22,0xa, +0xec,0x9, 0x7e,0x2a,0xdc,0xa, 0x37,0x5e,0x34,0x0, 0x1, 0xa, 0xed,0xbd,0x3e,0x22, +0xca,0x3b,0x7f,0x31,0x7a,0xd, 0x24,0x7e,0x35,0x28,0x7a,0x35,0x2f,0x7e,0xd, 0x24, +0x7f,0x13,0x12,0x85,0x19,0x7e,0x35,0x28,0x7a,0x35,0x2a,0x12,0x86,0x3f,0x7e,0xd, +0x24,0x2d,0x15,0x7f,0x13,0x2d,0x35,0x12,0xa2,0x54,0xda,0x3b,0x22,0x7e,0x37,0x2a, +0x4f,0x1e,0x34,0x7a,0x35,0x28,0x7e,0x8, 0x4, 0xfc,0x7e,0x18,0x4, 0x0, 0x12,0x85, +0xd0,0x7e,0x37,0x28,0x99,0xe, 0x34,0x7a,0x35,0x28,0x7e,0x8, 0x5, 0x7a,0x7e,0x18, +0x4, 0x7e,0x12,0x85,0xd0,0x12,0xa4,0xb9,0x12,0xa3,0xb3,0x2, 0x86,0x2e,0xe4,0x7a, +0xb3,0x3, 0xfe,0x7e,0xb3,0x28,0xa8,0x60,0x5, 0xe4,0x7a,0xb3,0x3, 0xfe,0x22,0x7e, +0xa3,0x2a,0x74,0x74,0x2, 0xa4,0x22,0xca,0x3b,0x7e,0x44,0x7f,0xff,0x7d,0x14,0x7d, +0x4, 0x6d,0x22,0x7d,0x32,0x7d,0xb4,0x6c,0xee,0x6c,0xff,0x7e,0x68,0x4, 0xfc,0x7e, +0x78,0x5, 0x7a,0xe4,0x7a,0xb3,0x8, 0x8, 0x7a,0xb3,0x8, 0x9, 0x7a,0xb3,0x26,0xf6, +0x7a,0xb3,0x26,0xf8,0x7a,0xb3,0x26,0xf7,0x7a,0xb3,0x26,0xf9,0x6c,0xaa,0x80,0x5c, +0x12,0x87,0x9e,0xbd,0xa1,0x58,0x2, 0x7d,0x1a,0xbd,0xa3,0x8, 0x2, 0x7d,0x3a,0x7e, +0xd0,0x2, 0xac,0xda,0x7f,0x47,0x2d,0x96,0xb, 0x4a,0xa0,0xbd,0xab,0x58,0x2, 0x7d, +0xba,0x12,0x87,0x9e,0x7e,0x87,0x2a,0x53,0x7e,0x94,0x0, 0x3, 0xad,0x98,0xbd,0xa9, +0x8, 0x2, 0xb, 0xe0,0x12,0x87,0x9e,0xbe,0xa4,0x0, 0x64,0x8, 0xb, 0x7e,0xb3,0x26, +0xf7,0x4, 0x7a,0xb3,0x26,0xf7,0x80,0x12,0x12,0x87,0x9e,0xbe,0xa4,0xff,0x9c,0x58, +0x9, 0x7e,0xb3,0x26,0xf9,0x4, 0x7a,0xb3,0x26,0xf9,0xb, 0xa0,0x7e,0xb3,0x2a,0x74, +0xbc,0xba,0x38,0x9c,0x7a,0x17,0x7, 0xfe,0x7a,0x37,0x8, 0x2, 0x7a,0xe3,0x8, 0x9, +0x7a,0xb7,0x8, 0x6, 0x12,0x86,0x3f,0x2d,0xd5,0x6c,0xaa,0x80,0x53,0x12,0x87,0xab, +0xbd,0xb0,0x58,0x2, 0x7d,0xb, 0xbd,0xb2,0x8, 0x2, 0x7d,0x2b,0x7e,0xd0,0x2, 0xac, +0xda,0x7f,0x56,0x2d,0xb6,0xb, 0x5a,0x90,0x7e,0xa7,0x2a,0x51,0x7e,0xb4,0x0, 0x3, +0xad,0xba,0xbd,0x9b,0x8, 0x2, 0xb, 0xf0,0x12,0x87,0xab,0xbe,0xb4,0x0, 0x64,0x8, +0xb, 0x7e,0xb3,0x26,0xf6,0x4, 0x7a,0xb3,0x26,0xf6,0x80,0x12,0x12,0x87,0xab,0xbe, +0xb4,0xff,0x9c,0x58,0x9, 0x7e,0xb3,0x26,0xf8,0x4, 0x7a,0xb3,0x26,0xf8,0xb, 0xa0, +0x12,0x5f,0xf8,0x38,0xa8,0x7a,0x7, 0x7, 0xfc,0x7a,0x27,0x8, 0x0, 0x7a,0xf3,0x8, +0x8, 0x12,0x86,0x3f,0x2d,0xf5,0x6c,0xaa,0x80,0x14,0x7e,0xf0,0x2, 0xac,0xfa,0x7f, +0x67,0x2d,0xd7,0xb, 0x6a,0xd0,0xbd,0xd4,0x58,0x2, 0x7d,0x4d,0xb, 0xa0,0x12,0x5f, +0xf8,0x38,0xe7,0x7a,0x47,0x8, 0x4, 0xbd,0x1, 0x58,0x2, 0x7d,0x10,0x7a,0x17,0x7, +0xf8,0xbd,0x32,0x58,0x2, 0x7d,0x32,0x7a,0x37,0x7, 0xfa,0xda,0x3b,0x22,0x7e,0xd0, +0x2, 0xac,0xda,0x7f,0x46,0x2d,0x96,0xb, 0x4a,0xa0,0x22,0x7e,0xd0,0x2, 0xac,0xda, +0x7f,0x56,0x2d,0xb6,0xb, 0x5a,0xb0,0x22,0x7e,0xf4,0x7f,0xff,0x9f,0x44,0xe4,0x22, +0x74,0x2, 0xac,0xbc,0x7f,0x16,0x2d,0x35,0x22,0xa, 0x17,0x6d,0x0, 0x7f,0x14,0x12, +0x1f,0x58,0x7d,0x73,0x12,0x21,0xa, 0x7d,0xe3,0x7d,0x3f,0x2, 0x21,0xa, 0x74,0x2, +0xac,0xbc,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0xe0,0x9d,0xe7,0x7f,0x15,0x2d,0x35,0x1b, +0x1a,0xe0,0x22,0x7e,0x24,0x0, 0x7d,0x12,0x90,0xd, 0x50,0x8, 0x7e,0x27,0x2a,0x4f, +0x1e,0x24,0x1e,0x24,0x7d,0x32,0x22,0x7e,0xb3,0x38,0x7, 0x70,0x2e,0x7e,0x73,0x37, +0xea,0xbe,0x70,0x10,0x40,0x2, 0x6c,0x77,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x3, 0x7e, +0x70,0x6, 0xa, 0x37,0x2e,0x34,0xf, 0xf0,0x12,0x88,0x5c,0x7c,0xab,0xe5,0x5e,0xa, +0x3b,0x2e,0x37,0x39,0x84,0x7a,0x37,0x39,0x84,0x80,0xc, 0x7e,0xa3,0x37,0xeb,0xbe, +0xa0,0x7f,0x28,0x3, 0x7e,0xa0,0x7f,0x7c,0xba,0x2, 0x88,0x4c,0x75,0x5e,0x0, 0x7a, +0xb3,0x3a,0x7, 0xc2,0x1c,0x22,0x2d,0x32,0x2e,0x34,0x20,0xfa,0x7a,0x71,0x82,0x7a, +0x61,0x83,0xe4,0x93,0x22,0x7c,0x7b,0x12,0x89,0x30,0x9, 0xa2,0x27,0x72,0x7c,0xb7, +0x54,0x7, 0xa, 0x3b,0x2e,0x34,0x0, 0x5e,0x12,0x88,0x5c,0x5c,0xba,0x22,0x6c,0x0, +0x6c,0x11,0x80,0x13,0x7c,0xb1,0x12,0x88,0x65,0x60,0xa, 0x12,0x88,0xd8,0x40,0x5, +0x7e,0x0, 0x1, 0x80,0xa, 0xb, 0x10,0x7e,0x73,0x28,0x84,0xbc,0x71,0x38,0xe5,0x7c, +0xb0,0x6c,0x77,0x12,0x88,0xf1,0xbe,0x0, 0x1, 0x68,0xb, 0x7c,0xb0,0x7e,0x70,0x1, +0x12,0x88,0xf1,0xb4,0x1, 0x21,0x6c,0x11,0x80,0x15,0x7c,0xb1,0x12,0x88,0x65,0x60, +0xc, 0x12,0x88,0xd8,0x50,0x7, 0x7c,0xb1,0x6c,0x77,0x12,0x73,0x2e,0xb, 0x10,0x7e, +0x3, 0x28,0x84,0xbc,0x1, 0x38,0xe3,0x22,0x74,0x2, 0xac,0xb1,0x9, 0x25,0x26,0xfa, +0x9, 0x35,0x26,0xfb,0x7c,0xb2,0x7c,0x73,0x7c,0xb7,0xb4,0x18,0x2, 0xd3,0x22,0xc3, +0x22,0x7c,0xab,0xa5,0xbf,0x0, 0xc, 0x7e,0xb3,0x37,0x61,0x7a,0xb3,0x37,0x62,0x7a, +0xa3,0x37,0x61,0x7e,0xb3,0x37,0x62,0x60,0x4, 0x74,0x8, 0x80,0xd, 0x7e,0xb3,0x28, +0x84,0x70,0xb, 0x7e,0xb3,0x37,0x63,0x60,0x5, 0x14,0x7a,0xb3,0x37,0x63,0x7e,0x73, +0x37,0x63,0xbe,0x70,0x0, 0x28,0x3, 0x74,0x1, 0x22,0xe4,0x22,0x7c,0xa5,0x7c,0xb7, +0xc4,0x23,0x54,0x1f,0xa, 0x2b,0x22,0x7e,0x8, 0x26,0x86,0x7e,0x34,0x0, 0x3, 0xe4, +0x12,0x20,0xe8,0x7e,0x8, 0x26,0x89,0x12,0x8f,0xc7,0x7a,0xb3,0x26,0x83,0x7a,0xb3, +0x26,0x84,0x7a,0xb3,0x26,0x85,0x7a,0xb3,0x26,0xf0,0x7a,0xb3,0x26,0xf1,0x7a,0xb3, +0x26,0xf2,0x7e,0x18,0x26,0x6f,0x12,0x8a,0x92,0x6c,0x55,0x12,0x89,0xf9,0x7a,0xb3, +0x26,0x85,0x7e,0x18,0x26,0x5b,0x12,0x8a,0xa2,0x6c,0x55,0x12,0x89,0xf9,0x7a,0xb3, +0x26,0x84,0x6c,0x77,0x80,0x14,0x12,0x8a,0x7e,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb, +0x12,0x89,0x2c,0x2e,0x24,0x26,0x86,0x12,0x8a,0x87,0x7e,0x63,0x26,0x84,0xbc,0x67, +0x38,0xe4,0x6c,0x77,0x80,0x14,0x12,0x8a,0x7e,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb, +0x12,0x89,0x2c,0x2e,0x24,0x26,0x89,0x12,0x8a,0x87,0x7e,0xa3,0x26,0x85,0xbc,0xa7, +0x38,0xe4,0x7e,0xb3,0x26,0x84,0xa4,0x7a,0xb3,0x26,0x83,0x7e,0x18,0x26,0xe6,0x12, +0x8a,0x92,0x7e,0x50,0x1, 0x12,0x89,0xf9,0x7a,0xb3,0x26,0xf2,0x7e,0x18,0x26,0xdc, +0x12,0x8a,0xa2,0x7e,0x50,0x1, 0x12,0x89,0xf9,0x7c,0xab,0x7a,0xa3,0x26,0xf1,0x7e, +0xb3,0x26,0xf2,0xa4,0x7a,0xb3,0x26,0xf0,0x22,0xca,0x69,0xca,0xf8,0x7c,0x4b,0x6c, +0xaa,0x6d,0xff,0x6c,0xff,0x80,0x6c,0x7e,0xd0,0x2, 0xac,0xdf,0x7f,0x60,0x2d,0xd6, +0xb, 0x6a,0xe0,0x4c,0x55,0x68,0x6, 0x6e,0xe4,0xff,0xff,0xb, 0xe4,0xbd,0x3e,0x58, +0x50,0x4c,0xff,0x78,0x8, 0x6d,0x44,0x69,0xf0,0x0, 0x2, 0x80,0x1b,0x7c,0xb4,0x14, +0xbc,0xbf,0x7f,0x56,0x78,0x9, 0x1b,0xb5,0xb, 0x5a,0x40,0x6d,0xff,0x80,0x9, 0x1b, +0xb5,0xb, 0x5a,0x40,0x69,0xf6,0x0, 0x2, 0x4c,0x55,0x68,0xc, 0x6e,0x44,0xff,0xff, +0xb, 0x44,0x6e,0xf4,0xff,0xff,0xb, 0xf4,0xbd,0x4e,0x58,0x15,0xbd,0xfe,0x18,0x11, +0xa, 0xba,0x7e,0x6d,0x24,0x2d,0xdb,0x7a,0x6b,0xf0,0xb, 0xa0,0xbe,0xa0,0xa, 0x50, +0x6, 0xb, 0xf0,0xbc,0x4f,0x38,0x90,0x7c,0xba,0xda,0xf8,0xda,0x69,0x22,0x7c,0xb7, +0x54,0x7, 0x7e,0x24,0x0, 0x1, 0x22,0x7e,0x29,0x60,0x4c,0x6a,0x7a,0x29,0x60,0xb, +0x70,0x22,0x7a,0x1d,0x24,0x7e,0xf, 0x6, 0xf8,0x7e,0xb3,0x2a,0x6e,0x7e,0x37,0x2a, +0x53,0x22,0x7a,0x1d,0x24,0x7e,0xa3,0x2a,0x6e,0x74,0x2, 0xa4,0x7e,0xf, 0x6, 0xf8, +0x2d,0x15,0x7e,0xb3,0x2a,0x6d,0x7e,0x37,0x2a,0x51,0x22,0x7c,0x2b,0x7e,0xb3,0x1f, +0x33,0xbc,0x2b,0x68,0x50,0x12,0x8b,0x1a,0x7c,0x3b,0x7c,0xb2,0x12,0x8b,0x1a,0x7c, +0xab,0xbe,0x30,0xff,0x68,0x3f,0xbe,0xa0,0xff,0x68,0x3a,0x7e,0x70,0x4, 0xac,0x73, +0xa, 0x2a,0x12,0x88,0x56,0xbe,0xb0,0x2, 0x38,0x2b,0xa, 0x2b,0x7e,0x34,0x2, 0xe0, +0xad,0x32,0x2e,0x34,0x16,0x93,0x6d,0x22,0x30,0x1b,0x3, 0x2, 0x4f,0x93,0x7e,0xb3, +0x2b,0x1d,0xb4,0x1, 0x10,0x12,0x57,0xe5,0xa4,0x7a,0x55,0x29,0x7e,0x8, 0xd, 0xc8, +0x74,0x1, 0x2, 0x4f,0x21,0x22,0x7e,0xb3,0x2b,0xf, 0x7c,0xab,0x6c,0x77,0x7e,0x50, +0x5, 0xac,0x57,0x9, 0x62,0x26,0x33,0xbc,0x6a,0x78,0x3, 0x7c,0xb7,0x22,0xb, 0x70, +0xbe,0x70,0x4, 0x40,0xe9,0x74,0xff,0x22,0x7c,0xab,0x12,0x8f,0xce,0xd2,0x1b,0x7c, +0xba,0x12,0x8a,0xbb,0xc2,0x1b,0x22,0xca,0x3b,0x7e,0xb3,0x2a,0x74,0xf5,0x27,0x12, +0x6c,0x57,0x50,0x2, 0x61,0xd9,0x6d,0x33,0x9e,0x37,0x2a,0x4f,0x3e,0x34,0xbe,0x37, +0x7, 0xf8,0x18,0x75,0x7e,0xb3,0x16,0x92,0x70,0x6f,0x7e,0xb3,0x28,0xa8,0xb4,0x1, +0x59,0x7e,0x77,0x2a,0x51,0x7e,0x67,0x2a,0x53,0x75,0x24,0x0, 0x80,0x47,0xe5,0x24, +0x12,0x88,0x65,0x60,0x3e,0x12,0x8b,0xdc,0x12,0x8f,0xe8,0x7e,0xb3,0x2a,0x3, 0xb4, +0x1, 0x9, 0xe5,0x26,0xb4,0x18,0x4, 0xe, 0x64,0xe, 0x74,0x7e,0xa1,0x26,0x74,0x2, +0xa4,0x49,0x35,0x4, 0xfc,0xbd,0x36,0x48,0xd, 0xe5,0x25,0xa, 0x2b,0xe5,0x27,0x12, +0x8b,0xe4,0xbd,0x37,0x58,0xd, 0xe5,0x24,0x6c,0x77,0x12,0x73,0x2e,0x12,0x8b,0xdc, +0x12,0x8f,0xa4,0x5, 0x24,0x12,0x8f,0xd6,0x38,0xb4,0x7e,0xb3,0x2a,0x68,0x70,0x9, +0x7e,0xb3,0x2a,0x6b,0x70,0x3, 0x12,0x9a,0x76,0xda,0x3b,0x22,0x7e,0x71,0x24,0x74, +0x2, 0xac,0x7b,0x22,0xa, 0x3b,0x2d,0x32,0x3e,0x34,0x49,0x33,0x4, 0xfc,0x22,0xca, +0xf8,0x7c,0xfb,0x6d,0xdd,0x7c,0xbf,0x12,0x98,0x93,0x7d,0xe3,0x7c,0xbf,0x12,0x6f, +0x6b,0x7d,0xf3,0x74,0x2, 0xac,0xbf,0x9, 0x95,0x26,0xfb,0x7c,0xbf,0x12,0x8f,0x82, +0x40,0x2, 0x81,0xc0,0x74,0x2, 0xac,0xbf,0x9, 0xa5,0x26,0xfa,0xbe,0xa0,0x0, 0x28, +0xa, 0x7c,0xba,0x14,0x7c,0x79,0x12,0x6d,0xcb,0x7d,0xd3,0x12,0x8c,0xce,0x58,0x6, +0x7c,0xba,0x4, 0x12,0x8f,0x67,0x7e,0x24,0x0, 0x2, 0x12,0x8f,0x5f,0xbe,0xa0,0x0, +0x28,0x4e,0x12,0x8c,0xce,0x58,0x49,0xbe,0x90,0x0, 0x28,0x44,0xbe,0x90,0x0, 0x28, +0x3f,0xbe,0xf4,0x0, 0xc8,0x8, 0x39,0x7d,0x3d,0x3e,0x34,0x3e,0x34,0xbd,0x3f,0x8, +0x2f,0x12,0x8c,0xc4,0xbe,0x34,0x1, 0x2c,0x8, 0x26,0xa, 0x2a,0x7e,0xb3,0x2a,0x74, +0x12,0x8b,0xe4,0xbe,0x34,0x1, 0x90,0x8, 0x17,0xbe,0xf4,0x1, 0x5e,0x58,0xd, 0x7e, +0x34,0x0, 0x3, 0xad,0x3e,0xbd,0x3f,0x8, 0x3, 0xe4,0x80,0x35,0x74,0x1, 0x80,0x31, +0xbe,0x90,0x18,0x78,0x2b,0xbe,0xf4,0x0, 0xc8,0x8, 0x25,0x12,0x8c,0xc4,0xbe,0x34, +0x0, 0xc8,0x8, 0x1c,0xa, 0x2a,0x7e,0x73,0x2a,0x74,0xa, 0x37,0x12,0x8b,0xe6,0xbe, +0x34,0x0, 0xc8,0x8, 0xb, 0x7e,0xb3,0x28,0x84,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x1, +0xe4,0xda,0xf8,0x22,0x7e,0x70,0x2, 0xac,0x79,0x49,0x33,0x4, 0xfc,0x22,0x7e,0xb3, +0x2a,0x6f,0xa, 0x3b,0x1b,0x34,0xa, 0xca,0xbd,0xc3,0x22,0x12,0xa2,0x3d,0x12,0x9a, +0xed,0x12,0x8b,0x47,0x12,0x99,0xd6,0x2, 0x8c,0xea,0xca,0x3b,0x12,0x75,0x4a,0x7e, +0xb3,0x28,0x84,0x60,0x6, 0x7e,0xb3,0x36,0xe2,0x60,0x9, 0xe4,0x7a,0xb3,0x36,0xe4, +0x7a,0xb3,0x36,0x69,0x7e,0xb3,0x36,0xe2,0x70,0x5d,0x6c,0x99,0x80,0x51,0x12,0x8d, +0x92,0x9, 0xf5,0x26,0xfb,0x7c,0xb9,0x12,0x8f,0x82,0x40,0x41,0x6c,0xee,0x80,0x35, +0x74,0x2, 0xac,0xbe,0x9, 0xd5,0x36,0x6a,0x9, 0xc5,0x36,0x6b,0xa, 0x28,0xa, 0x3d, +0x12,0x8d,0x8a,0x78,0x1e,0xa, 0x2f,0xa, 0x3c,0x12,0x8d,0x8a,0x78,0x15,0x7c,0xb9, +0x12,0x6f,0x6b,0xbe,0x34,0x3, 0x20,0x58,0xa, 0x12,0x8f,0x58,0x7c,0xb8,0x7c,0x7f, +0x12,0x8f,0xac,0xb, 0xe0,0x7e,0x73,0x36,0xe4,0xbc,0x7e,0x38,0xc3,0xb, 0x90,0x7e, +0x73,0x28,0x84,0xbc,0x79,0x38,0xa7,0x7e,0x73,0x36,0x69,0x7a,0x73,0x36,0xe4,0xa, +0x37,0x3e,0x34,0xca,0x39,0x7e,0x18,0x36,0xa6,0x7e,0x8, 0x36,0x6a,0x12,0x20,0xc3, +0x1b,0xfd,0xe4,0x7a,0xb3,0x36,0xe2,0xda,0x3b,0x22,0x9d,0x32,0x12,0x21,0xa, 0x4d, +0x33,0x22,0x74,0x2, 0xac,0xb9,0x9, 0x85,0x26,0xfa,0x22,0xca,0x3b,0x7e,0xb3,0x2a, +0x6f,0xf5,0x26,0x7e,0xa3,0x2a,0x70,0x7e,0xb3,0x28,0x84,0xf5,0x24,0x70,0x2, 0xe1, +0x4c,0x7e,0x8, 0x1f,0x34,0x7e,0x34,0x3, 0xd4,0xe4,0x12,0x20,0xe8,0x7e,0x8, 0x23, +0x8, 0x7e,0x34,0x0, 0x23,0x12,0x20,0xe8,0x6c,0x99,0x80,0x5a,0x12,0x8f,0xde,0x9, +0xe3,0x26,0xfb,0x1a,0x68,0x1b,0x65,0x80,0x41,0xbe,0xd0,0x0, 0x48,0x3a,0xe5,0x26, +0xbc,0xbd,0x8, 0x34,0x74,0x1, 0x1a,0xcd,0x19,0xbc,0x23,0x8, 0x1a,0xce,0x1b,0xc5, +0x7d,0x3c,0x7c,0xf7,0x80,0x18,0xbe,0xf0,0x0, 0x48,0x11,0xbc,0xaf,0x8, 0xd, 0x74, +0x1, 0x12,0x8f,0x4f,0x1a,0xcf,0x2d,0xc3,0x19,0xbc,0x1f,0x34,0xb, 0xf0,0x1a,0x3e, +0xb, 0x35,0x1a,0xcf,0xbd,0xc3,0x8, 0xde,0xb, 0xd0,0x1a,0x38,0xb, 0x35,0x1a,0xcd, +0xbd,0xc3,0x8, 0xb5,0xb, 0x90,0xe5,0x24,0xbc,0xb9,0x38,0xa0,0x6c,0xdd,0x80,0x71, +0x1a,0xcd,0x9, 0xbc,0x23,0x8, 0x60,0x67,0x6d,0xdd,0x75,0x25,0x0, 0x7e,0xb3,0x2a, +0x6e,0xa, 0x2b,0x1a,0x3d,0xad,0x32,0x7d,0xc3,0x3e,0xc4,0x7e,0x7f,0x13,0x8a,0x6c, +0x99,0x80,0x16,0x12,0x8f,0x4f,0xa, 0xc9,0x2d,0xc3,0x9, 0xbc,0x1f,0x34,0x70,0x7, +0x7c,0xbd,0x12,0x8f,0x67,0x5, 0x25,0xb, 0x90,0xbc,0xa9,0x38,0xe6,0xe5,0x25,0x60, +0x2e,0xe5,0x25,0x1a,0x2b,0x12,0x8f,0x5f,0x6c,0xff,0x80,0x1f,0x12,0x8f,0x4f,0x1a, +0xcf,0x2d,0xc3,0x9, 0xbc,0x1f,0x34,0xb4,0x1, 0xf, 0x7c,0xbd,0x7c,0x7f,0x12,0x6f, +0x81,0xb, 0x1a,0xc0,0x9d,0xcd,0x1b,0x1a,0xc0,0xb, 0xf0,0xbc,0xaf,0x18,0xdd,0xb, +0xd0,0xe5,0x26,0xbc,0xbd,0x18,0x89,0x6c,0x99,0xe1,0x44,0x12,0x8d,0x92,0x9, 0xe5, +0x26,0xfb,0x7c,0xb8,0x7c,0x7e,0x12,0x6f,0x81,0x7f,0x71,0x4c,0x88,0x78,0xc, 0x12, +0x8f,0x78,0x2d,0x35,0x12,0x8f,0x6f,0x8, 0x62,0x80,0x51,0xe5,0x26,0x14,0xbc,0xb8, +0x78,0xc, 0x12,0x8f,0x78,0x9d,0x35,0x12,0x8f,0x6f,0x8, 0x4f,0x80,0x31,0xe5,0x26, +0xa, 0xcb,0x1b,0xc4,0x1a,0x58,0xbd,0x5c,0x58,0x41,0x7e,0xa3,0x2a,0x6e,0x7e,0x30, +0x2, 0xac,0x3a,0x7f,0x17,0x9d,0x31,0xb, 0x1a,0x30,0x74,0x2, 0xa4,0x7f,0x7, 0x2d, +0x15,0xb, 0xa, 0xc0,0xbd,0x3c,0x8, 0xd, 0xb, 0x7a,0x50,0xbd,0x35,0x8, 0x1c,0x1a, +0x58,0x1b,0x54,0x80,0xb, 0xb, 0x7a,0x50,0xbd,0xc5,0x8, 0xf, 0x1a,0x58,0xb, 0x54, +0x7c,0xab,0x7e,0x70,0x2, 0xac,0x79,0x19,0xa3,0x26,0xfa,0x12,0x8d,0x92,0x7c,0xb8, +0x7c,0x7e,0x12,0x6d,0xcb,0x7d,0xc3,0x7e,0x57,0x2a,0x5a,0xbd,0x5c,0x8, 0x3, 0x12, +0x8f,0x58,0xb, 0x90,0xe5,0x24,0xbc,0xb9,0x28,0x2, 0xc1,0xab,0xda,0x3b,0x22,0x1a, +0x2d,0x7e,0x34,0x0, 0x1c,0xad,0x32,0x22,0x7c,0xb9,0x6c,0x77,0x2, 0x73,0x2e,0x7d, +0x3d,0x12,0x1e,0xb9,0x7d,0xd3,0x22,0x7c,0x79,0x12,0x6d,0xcb,0x2d,0xd3,0x22,0xb, +0x1a,0xc0,0xb, 0x7a,0x50,0xbd,0xc5,0x22,0x7e,0xa3,0x2a,0x6e,0x74,0x2, 0xa4,0x7f, +0x17,0x22,0x7c,0x4b,0x74,0x2, 0xac,0xb4,0x9, 0x55,0x26,0xfa,0x9, 0x65,0x26,0xfb, +0x7e,0x73,0x28,0x8c,0xbc,0x75,0x78,0xa, 0x7e,0x73,0x28,0x8d,0xbc,0x76,0x78,0x2, +0xd3,0x22,0xc3,0x22,0x9, 0xb3,0x26,0xfa,0x9, 0x73,0x26,0xfb,0x7c,0x6b,0x7e,0xa3, +0x36,0x69,0x7e,0x50,0x2, 0xac,0x5a,0x19,0x62,0x36,0xa6,0x19,0x72,0x36,0xa7,0x7c, +0xba,0x4, 0x7a,0xb3,0x36,0x69,0x22,0x7e,0x34,0x0, 0x3, 0x2, 0x20,0xe8,0xa9,0xd1, +0xcb,0x74,0x1, 0x2, 0x0, 0xe, 0x7e,0x73,0x28,0x84,0xbe,0x71,0x24,0x22,0x7e,0x70, +0x2, 0xac,0x79,0x9, 0x83,0x26,0xfa,0x22,0x9, 0xb3,0x26,0xfa,0xf5,0x25,0x9, 0xb3, +0x26,0xfb,0xf5,0x26,0x22,0x12,0x90,0xd, 0x50,0x12,0x7e,0x37,0x2b,0x7, 0xbe,0x34, +0x1, 0x2c,0x28,0x8, 0x7e,0x34,0x1, 0x2c,0x7a,0x37,0x2b,0x7, 0x22,0xc2,0x0, 0x12, +0x90,0x35,0x68,0x7, 0x7e,0xb3,0x2a,0x68,0xb4,0x1, 0x17,0x7e,0xb3,0x37,0x71,0x70, +0x11,0x12,0x44,0xc4,0x40,0xa, 0x7e,0x37,0x28,0x8a,0xbe,0x34,0x1, 0x90,0x58,0x2, +0xd2,0x0, 0xa2,0x0, 0x22,0x7e,0xb3,0x2a,0x6b,0xbe,0xb0,0x1, 0x22,0x7e,0xb3,0x39, +0x87,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x7a,0xb3,0x39,0x87,0x22,0x7f,0x20,0xc2, +0x1, 0x7e,0x2b,0x60,0x29,0x72,0x0, 0x2, 0x9c,0x76,0x1a,0x37,0x12,0x21,0xa, 0x7c, +0x27,0x29,0x72,0x0, 0x1, 0x29,0x32,0x0, 0x3, 0x9c,0x37,0x1a,0x33,0x12,0x21,0xa, +0x7c,0x37,0x1a,0x23,0x1a,0x32,0x9d,0x32,0x12,0x21,0xa, 0x7c,0x67,0x7c,0x72,0xbc, +0x32,0x58,0x2, 0x7c,0x73,0xbe,0x60,0x5, 0x18,0x5, 0xbe,0x70,0x6, 0x58,0x8, 0x7e, +0x37,0x38,0xf4,0x4d,0x33,0x68,0x2, 0xd2,0x1, 0xa2,0x1, 0x22,0xca,0x3b,0x7c,0xc7, +0x7c,0xfb,0x7f,0x40,0x6d,0xbb,0x7e,0xa3,0x2a,0x6d,0x7e,0x73,0x2a,0x6e,0x4c,0xcc, +0x78,0x5, 0x7e,0xc0,0x1, 0x80,0xd, 0x7c,0xb7,0x14,0xbc,0xbc,0x78,0x6, 0xa, 0x6c, +0x1b,0x65,0x7c,0xcd,0x4c,0xff,0x78,0x5, 0x7e,0xf0,0x1, 0x80,0xb, 0x7c,0xba,0x14, +0xbc,0xbf,0x78,0x4, 0xa, 0x7f,0x1b,0x75,0x7f,0x4, 0x7e,0x34,0x0, 0x6, 0xe4,0x12, +0x20,0xe8,0x7e,0x73,0x2a,0x6d,0xa, 0x37,0x1b,0x34,0x7a,0x4b,0x70,0x7e,0x73,0x2a, +0x6e,0xa, 0x37,0x1b,0x34,0x39,0x74,0x0, 0x1, 0x7c,0xec,0x80,0x1d,0x75,0x24,0x0, +0x7c,0xdf,0x80,0xb, 0x12,0x6d,0xd2,0x70,0xb, 0x5, 0x24,0xb, 0xb4,0x1b,0xd0,0xbe, +0xd0,0x0, 0x58,0xf0,0xe5,0x24,0x60,0x7, 0x1b,0xe0,0xbe,0xe0,0x0, 0x58,0xde,0x7c, +0xec,0x80,0x26,0x75,0x24,0x0, 0x1a,0xaf,0xb, 0xa4,0x7d,0x3a,0x7c,0xd7,0x80,0xb, +0x12,0x6d,0xd2,0x70,0xe, 0x5, 0x24,0xb, 0xb4,0xb, 0xd0,0x7e,0x73,0x2a,0x6d,0xbc, +0x7d,0x18,0xed,0xe5,0x24,0x60,0x7, 0x1b,0xe0,0xbe,0xe0,0x0, 0x58,0xd5,0x12,0x91, +0xb2,0x80,0x1d,0x75,0x24,0x0, 0x7c,0xdf,0x80,0xb, 0x12,0x6d,0xd2,0x70,0xb, 0x5, +0x24,0xb, 0xb4,0x1b,0xd0,0xbe,0xd0,0x0, 0x58,0xf0,0xe5,0x24,0x60,0xa, 0xb, 0xe0, +0x7e,0x73,0x2a,0x6e,0xbc,0x7e,0x18,0xdb,0x12,0x91,0xb2,0x80,0x22,0x75,0x24,0x0, +0x1a,0x6f,0xb, 0x64,0x80,0xb, 0x12,0x6d,0xd2,0x70,0xe, 0x5, 0x24,0xb, 0xb4,0xb, +0xd0,0x7e,0x73,0x2a,0x6d,0xbc,0x7d,0x18,0xed,0xe5,0x24,0x60,0xa, 0xb, 0xe0,0x7e, +0x73,0x2a,0x6e,0xbc,0x7e,0x18,0xd6,0x7d,0x3b,0x39,0x74,0x0, 0x5, 0x7d,0x3b,0xda, +0x3b,0x22,0x1a,0xac,0xb, 0xa4,0x7d,0x3a,0x7c,0xe7,0x22,0x7f,0x60,0x7e,0x6b,0xa0, +0xbe,0xa0,0xa, 0x50,0x1b,0x7e,0x14,0x0, 0x6, 0xca,0x19,0x74,0x6, 0xa4,0x7f,0x6, +0x2d,0x15,0xb, 0x14,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x6b,0xb0,0x4, 0x7a,0x6b,0xb0, +0x22,0xe4,0x7e,0x63,0x2a,0x6e,0x7e,0x73,0x2a,0x6d,0xac,0x76,0x7d,0x13,0x1e,0x14, +0x7e,0x27,0x28,0x88,0x2e,0x27,0x28,0x86,0xbd,0x21,0x38,0xa, 0x1e,0x34,0x1e,0x34, +0xbe,0x37,0x28,0x86,0x50,0x14,0x7e,0xa3,0x26,0xf7,0xbe,0xa0,0xc, 0x28,0xb, 0x7e, +0xa3,0x26,0xf6,0xbe,0xa0,0x7, 0x28,0x2, 0x74,0x1, 0x22,0x7e,0xa3,0x2a,0x3, 0xbe, +0xa0,0x0, 0x38,0x2f,0xbe,0xa3,0x2a,0x2, 0x50,0x19,0x7e,0xb3,0x2a,0xc, 0xbe,0xb3, +0x35,0x56,0x28,0x14,0x7e,0xb3,0x35,0x56,0x4, 0x7a,0xb3,0x35,0x56,0x7a,0xa3,0x2a, +0x2, 0x80,0x5, 0xe4,0x7a,0xb3,0x35,0x56,0x7e,0xb3,0x2a,0x2, 0x70,0x5, 0xe4,0x7a, +0xb3,0x2a,0xb, 0x22,0x12,0x92,0x5a,0x2, 0x92,0x1b,0x7e,0xb3,0x2a,0x2, 0x70,0x29, +0x12,0x92,0x93,0x28,0x24,0x7e,0xb3,0x34,0xdb,0x70,0x18,0x12,0x92,0x9b,0x7e,0x73, +0x2a,0x3, 0x7a,0x73,0x2a,0x2, 0x74,0x1, 0x7a,0xb3,0x2a,0x9, 0x7e,0xb3,0x34,0xdb, +0x4, 0x80,0x1, 0xe4,0x7a,0xb3,0x34,0xdb,0x22,0xe4,0x7a,0xb3,0x34,0xdb,0x7a,0xb3, +0x2a,0x9, 0x22,0x7e,0x73,0x2a,0x3, 0xbe,0x70,0x0, 0x22,0x7e,0x34,0x0, 0x3c,0xca, +0x39,0x7e,0x18,0x36,0xe9,0x7e,0x8, 0x37,0x25,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x73, +0x28,0x94,0x7a,0x73,0x36,0xe8,0x7a,0x73,0x28,0x93,0x22,0x12,0x92,0x93,0x28,0x8, +0x7e,0xb3,0x28,0x84,0x70,0x2, 0xf5,0x1b,0x7e,0xb3,0x28,0x84,0x70,0x18,0xe5,0x1b, +0xbe,0xb0,0xfa,0x50,0x2, 0x5, 0x1b,0xe5,0x1b,0xbe,0xb0,0x5, 0x40,0x8, 0xe4,0x7a, +0xb3,0x32,0x2c,0x75,0x1b,0xfa,0x22,0xca,0x79,0xc2,0x0, 0x7e,0xf0,0x3, 0x12,0x92, +0xbb,0x7e,0xe3,0x2a,0x3, 0x7e,0x34,0x1f,0x34,0x7a,0x37,0x31,0xee,0x12,0x97,0xcc, +0x38,0x2, 0x61,0xc0,0x12,0x93,0xf5,0x92,0xd, 0x12,0x93,0xc9,0x7c,0xbf,0x12,0xae, +0x2d,0x4c,0xee,0x68,0xe, 0x7e,0xa3,0x31,0xcb,0x4c,0xaa,0x78,0xa, 0x7e,0xb3,0x31, +0xcc,0x70,0x4, 0xd2,0x0, 0x80,0x25,0xbe,0xe0,0x1, 0x28,0xb, 0xe5,0x1c,0xbe,0xb0, +0x8, 0x28,0x4, 0xd2,0x0, 0x80,0x15,0xd2,0x0, 0x7e,0xb3,0x28,0x84,0xbc,0xbe,0x78, +0xb, 0x20,0xd, 0x8, 0x4c,0xaa,0x78,0x4, 0x6c,0xff,0xc2,0x0, 0x20,0x0, 0x5, 0x7c, +0xbf,0x12,0xae,0x2d,0x7e,0x8, 0x31,0xd0,0x12,0xb4,0x20,0x7a,0xb3,0x31,0xcf,0xbe, +0xb3,0x28,0x84,0x50,0x3a,0x7e,0x33,0x31,0xcf,0x80,0x26,0x7e,0x70,0x2, 0xac,0x73, +0x9, 0x23,0x31,0xf0,0x9, 0x13,0x31,0xf1,0x2e,0x37,0x31,0xee,0xb, 0x38,0x50,0x7e, +0x93,0x2a,0x6e,0xac,0x92,0xa, 0x31,0x2d,0x43,0x12,0xc6,0x79,0x7c,0xb3,0x12,0x76, +0xfb,0x7c,0x3, 0x1b,0x30,0xa5,0xb8,0x0, 0xd2,0x74,0x1, 0x7a,0xb3,0x31,0xcd,0x7e, +0xa3,0x31,0xcf,0x7a,0xa3,0x28,0x84,0x74,0x2, 0xa4,0xca,0x59,0x7e,0x18,0x31,0xf0, +0x7e,0x8, 0x26,0xfa,0x12,0x20,0xc3,0x1b,0xfd,0x12,0x46,0xb9,0xf5,0x1c,0x80,0x6, +0x75,0x1c,0x64,0x12,0x97,0xde,0xda,0x79,0x22,0x6c,0xaa,0x12,0x97,0xea,0x12,0x93, +0xeb,0x54,0xfe,0x12,0x93,0xe8,0x54,0x7, 0x12,0x93,0xe8,0x54,0xfb,0x7a,0xb, 0xb0, +0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xe4,0x22,0x7a,0xb, 0xb0,0x7f,0x1, 0x2e,0x14,0x0, +0x5, 0x7e,0xb, 0xb0,0x22,0xca,0x3b,0x7e,0xe3,0x28,0x84,0x6c,0xdd,0x6c,0xff,0x74, +0x6, 0xac,0xbd,0x12,0x97,0x6e,0x30,0xe0,0x37,0x6c,0xcc,0x80,0x27,0x12,0x97,0xd4, +0x7a,0xb3,0x1f,0x70,0x9, 0xa3,0x26,0xfb,0x7a,0xa3,0x1f,0x71,0x7f,0x7, 0x12,0x94, +0x4b,0x50,0xf, 0x7f,0x7, 0x7e,0xb3,0x1f,0x71,0x6c,0x77,0x12,0x94,0x4e,0x50,0x2, +0xb, 0xf0,0xb, 0xc0,0xbc,0xec,0x38,0xd5,0xbe,0xf0,0x2, 0x40,0x3, 0xd3,0x80,0x8, +0xb, 0xd0,0xbe,0xd0,0x1e,0x40,0xb6,0xc3,0xda,0x3b,0x22,0x7e,0x70,0x1, 0x7c,0x87, +0x7c,0x9b,0x29,0xa0,0x0, 0x3, 0x29,0x60,0x0, 0x1, 0x7e,0x70,0x1, 0xbe,0x80,0x1, +0x78,0x7, 0x29,0xa0,0x0, 0x2, 0x7e,0xb, 0x60,0xa, 0x7, 0xa, 0x29,0x2d,0x2, 0xa, +0x16,0xbd,0x1, 0x48,0xc, 0xa, 0x17,0xa, 0x3a,0x2d,0x31,0xbd,0x23,0x18,0x2, 0xd3, +0x22,0xc3,0x22,0xca,0x3b,0x7c,0xf5,0x7c,0xe6,0x7c,0xd7,0x7c,0xcb,0x75,0x54,0x0, +0x7e,0xa1,0x54,0x74,0x6, 0xa4,0x12,0x97,0x6e,0x30,0xe1,0x2e,0x7f,0x7, 0x7c,0xbc, +0x12,0x96,0xab,0x50,0x25,0x7f,0x7, 0x7c,0xbe,0x12,0x94,0x4b,0x50,0x1c,0x7f,0x7, +0x7c,0xbd,0x6c,0x77,0x12,0x94,0x4e,0x50,0x11,0x7f,0x7, 0x7c,0xbf,0x6c,0x77,0x12, +0x94,0x4e,0x50,0x6, 0x29,0xb7,0x0, 0x4, 0x80,0xa, 0x5, 0x54,0xe5,0x54,0xbe,0xb0, +0x1e,0x40,0xbd,0xe4,0xda,0x3b,0x22,0xca,0x79,0x7f,0x70,0x7e,0xb4,0xff,0xff,0x6c, +0xee,0xc2,0x1, 0xc2,0x2, 0x29,0x67,0x0, 0x2, 0x7e,0x7b,0x70,0xbc,0x76,0x78,0xe, +0x29,0x67,0x0, 0x3, 0x29,0x77,0x0, 0x1, 0xbc,0x76,0x78,0x2, 0xd2,0x2, 0x6c,0xff, +0x12,0x96,0xbb,0x6d,0xaa,0x29,0xb6,0x0, 0x5, 0x20,0xe1,0x2, 0xa1,0x91,0x7f,0x6, +0x7e,0x7b,0xb0,0x12,0x96,0xab,0x50,0x2d,0x7f,0x6, 0x29,0xb7,0x0, 0x2, 0x12,0x96, +0xab,0x50,0x22,0x7f,0x6, 0x29,0xb7,0x0, 0x1, 0x6c,0x77,0x12,0x94,0x4e,0x50,0x15, +0x7f,0x6, 0x29,0xb7,0x0, 0x3, 0x6c,0x77,0x12,0x94,0x4e,0x50,0x8, 0x7c,0xef,0xd2, +0x1, 0x6d,0xbb,0x80,0x55,0x7e,0x6b,0x70,0xa, 0x27,0x7e,0x7b,0x70,0x12,0x96,0xa4, +0x2d,0xa3,0x29,0x76,0x0, 0x2, 0xa, 0x27,0x29,0x77,0x0, 0x2, 0x12,0x96,0xa4,0x2d, +0xa3,0x29,0x76,0x0, 0x1, 0xa, 0x27,0x29,0x77,0x0, 0x1, 0x12,0x96,0xa4,0x2d,0xa3, +0x29,0x76,0x0, 0x3, 0xa, 0x27,0x29,0x77,0x0, 0x3, 0x12,0x96,0xa4,0x2d,0xa3,0xbd, +0xab,0x50,0x4, 0x7d,0xba,0x7c,0xef,0xbe,0xa4,0x0, 0x4, 0x38,0x4, 0xd2,0x1, 0x80, +0x9, 0xb, 0xf0,0xbe,0xf0,0x1e,0x50,0x2, 0xa1,0x0, 0x20,0x1, 0xb, 0x20,0x2, 0x8, +0xbe,0xb4,0x0, 0x8, 0x50,0x2, 0xd2,0x1, 0x20,0x1, 0x2, 0xc1,0x52,0x74,0x6, 0xac, +0xbe,0x12,0x96,0xbf,0x29,0x76,0x0, 0x5, 0x7c,0xb7,0xc4,0x23,0x54,0x1f,0xbe,0xb0, +0x1f,0x50,0x16,0x7f,0x6, 0x2e,0x14,0x0, 0x5, 0x7c,0x67,0x2e,0x60,0x8, 0x5e,0x60, +0xf8,0x5e,0x70,0x7, 0x4c,0x76,0x7a,0xb, 0x70,0x20,0x2, 0x11,0x29,0xb6,0x0, 0x4, +0xbe,0xb0,0xfa,0x50,0x8, 0x7f,0x16,0xb, 0x36,0x4, 0x7a,0x1b,0xb0,0x29,0x67,0x0, +0x3, 0x29,0x76,0x0, 0x3, 0xbc,0x76,0x28,0x6, 0x29,0x76,0x0, 0x3, 0x80,0x4, 0x29, +0x77,0x0, 0x3, 0x39,0x76,0x0, 0x3, 0x29,0x67,0x0, 0x2, 0x29,0x76,0x0, 0x2, 0xbc, +0x76,0x28,0x6, 0x29,0x76,0x0, 0x2, 0x80,0x4, 0x29,0x77,0x0, 0x2, 0x39,0x76,0x0, +0x2, 0x29,0x67,0x0, 0x1, 0x29,0x76,0x0, 0x1, 0xbc,0x76,0x50,0x6, 0x29,0x76,0x0, +0x1, 0x80,0x4, 0x29,0x77,0x0, 0x1, 0x39,0x76,0x0, 0x1, 0x7e,0x7b,0x60,0x7e,0x6b, +0x70,0xbc,0x76,0x50,0x5, 0x7e,0x6b,0x70,0x80,0x3, 0x7e,0x7b,0x70,0x7a,0x6b,0x70, +0x80,0x31,0x6c,0xff,0x74,0x6, 0xac,0xbf,0x9, 0xb5,0x32,0x32,0x30,0xe1,0x7, 0xb, +0xf0,0xbe,0xf0,0x1e,0x40,0xee,0xbe,0xf0,0x1e,0x50,0x33,0x74,0x1, 0x39,0xb7,0x0, +0x4, 0x12,0x96,0xbb,0x7e,0x34,0x0, 0x6, 0xca,0x39,0x7f,0x17,0x7f,0x6, 0x12,0x20, +0xc3,0x1b,0xfd,0x12,0x96,0xb1,0x44,0x1, 0x7a,0x1b,0xb0,0x12,0x96,0xb1,0x44,0x2, +0x7a,0x1b,0xb0,0x30,0x2, 0x8, 0x12,0x96,0xb1,0x44,0x4, 0x7a,0x1b,0xb0,0xda,0x79, +0x22,0x7e,0x39,0x70,0xa, 0x37,0x9d,0x32,0x2, 0x21,0xa, 0x7e,0x70,0x1, 0x2, 0x94, +0x4e,0x7f,0x16,0x2e,0x34,0x0, 0x5, 0x7e,0x1b,0xb0,0x22,0x74,0x6, 0xac,0xbf,0x7d, +0xd5,0x2e,0xd4,0x32,0x2d,0x6d,0xcc,0x22,0xca,0xf8,0x7e,0xd4,0x0, 0x7, 0x7e,0xb3, +0x28,0x84,0x70,0x8, 0xf5,0x5a,0xc2,0xa, 0xc2,0xb, 0x80,0x7d,0xbe,0xb0,0x2, 0x38, +0x72,0xb4,0x2, 0x28,0x7e,0x73,0x26,0xfc,0xa, 0x27,0x7e,0x73,0x26,0xfa,0x12,0x96, +0xa4,0xbe,0x34,0x0, 0x5, 0x58,0x15,0x7e,0x73,0x26,0xfd,0xa, 0x27,0x7e,0x73,0x26, +0xfb,0x12,0x96,0xa4,0xbe,0x34,0x0, 0x5, 0x58,0x2, 0x80,0x5a,0x6c,0xff,0x80,0x3c, +0x7c,0xbf,0x12,0x97,0x7b,0x1a,0x4b,0x7c,0xbf,0x12,0x6f,0x6b,0x7d,0xc3,0xbe,0xc4, +0x2, 0x58,0x58,0x4, 0x7e,0xd4,0x0, 0x6, 0x7d,0x5d,0x3e,0x54,0xbd,0x54,0x58,0x4, +0xd2,0xb, 0x80,0xa, 0x7d,0x5d,0xe, 0x54,0xbd,0x54,0x48,0x2, 0xc2,0xb, 0x20,0xb, +0x4, 0xbd,0xd4,0x58,0x5, 0x75,0x5a,0x28,0x80,0xf, 0xb, 0xf0,0x12,0x73,0x6d,0x38, +0xbf,0x80,0x6, 0xe5,0x5a,0x24,0xfb,0xf5,0x5a,0xe5,0x5a,0xbe,0xb0,0x0, 0x8, 0x6, +0xd2,0xa, 0x15,0x5a,0x80,0x5, 0x75,0x5a,0x0, 0xc2,0xa, 0xda,0xf8,0x22,0x7d,0xf5, +0x2e,0xf4,0x32,0x2d,0x6d,0xee,0x29,0xb7,0x0, 0x5, 0x22,0xca,0xf8,0x7c,0xfb,0x7e, +0x70,0x2, 0x12,0x99,0xd, 0x7f,0x71,0x7c,0xbf,0x12,0x6f,0x6b,0x12,0x97,0xc5,0x7f, +0x17,0x12,0x1f,0x58,0x7c,0xb7,0xda,0xf8,0x22,0xca,0xd8,0xca,0x79,0x6c,0xff,0x6c, +0xee,0x80,0xf, 0x7c,0xbe,0x12,0x97,0x7b,0x7c,0xdb,0xbc,0xfd,0x58,0x2, 0x7c,0xfd, +0xb, 0xe0,0x12,0x97,0xbe,0x38,0xec,0x7c,0xbf,0xda,0x79,0xda,0xd8,0x22,0x7e,0x73, +0x28,0x84,0xbc,0x7e,0x22,0x7d,0x13,0x1a,0x2, 0x1a,0x0, 0x22,0x7e,0x73,0x28,0x84, +0xbe,0x70,0x1, 0x22,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x26,0xfa,0x22,0x7e,0x8, +0x32,0x2d,0x7e,0x34,0x0, 0xb4,0xe4,0x2, 0x20,0xe8,0x7e,0x70,0x6, 0xac,0x7a,0x2e, +0x34,0x32,0x2d,0x6d,0x22,0x22,0x7e,0xa3,0x2a,0x2, 0x7e,0xb3,0x38,0x32,0x70,0x5, +0x7a,0xb3,0x34,0xc4,0x22,0xe4,0x7a,0xb3,0x34,0x88,0x6c,0x77,0x80,0x78,0x7e,0x90, +0x9, 0xac,0x97,0x9, 0x64,0x29,0xc, 0x7c,0xb6,0x54,0xf, 0xa, 0x2b,0x9, 0x52,0x29, +0xbc,0x4c,0x55,0x68,0xa, 0xa5,0xbd,0x2, 0x5b,0x7e,0xb3,0x34,0xc4,0x70,0x55,0x49, +0x14,0x29,0x8, 0xbe,0x14,0x0, 0x64,0x28,0x10,0xbe,0x14,0x3, 0xd4,0x50,0xa, 0x49, +0x14,0x29,0xa, 0xbe,0x14,0x0, 0x64,0x38,0x3b,0x7e,0xb3,0x34,0x88,0xbc,0xb7,0x40, +0x5, 0x4, 0x7a,0xb3,0x34,0x88,0x7e,0xb3,0x2a,0x2, 0x14,0x7a,0xb3,0x2a,0x2, 0x7e, +0x40,0xff,0x7e,0x30,0x9, 0xac,0x37,0x19,0x41,0x29,0xc, 0x74,0x3, 0xa, 0x46,0x19, +0xb4,0x29,0xbc,0x19,0xb4,0x29,0xc6,0xa5,0xbd,0x2, 0x9, 0x7e,0xb3,0x2a,0x3, 0x14, +0x7a,0xb3,0x2a,0x3, 0xb, 0x70,0xbc,0xa7,0x38,0x84,0x7e,0x73,0x38,0x32,0x7a,0x73, +0x34,0xc4,0x22,0xca,0x79,0x7c,0x8b,0x6c,0xaa,0x9f,0x77,0x12,0x99,0xc8,0x1a,0x79, +0x1b,0x74,0x80,0x41,0x1a,0x38,0x1b,0x34,0x7c,0xe7,0x80,0x2d,0xbc,0x9f,0x78,0x4, +0xbc,0x8e,0x68,0x23,0xbe,0xf0,0x0, 0x48,0x1e,0x7e,0xb3,0x2a,0x6f,0xbc,0xbf,0x8, +0x16,0xbe,0xe0,0x0, 0x48,0x11,0x7e,0xb3,0x2a,0x70,0xbc,0xbe,0x8, 0x9, 0x7c,0xbf, +0x7c,0x7e,0x12,0x99,0x3, 0xb, 0xa0,0xb, 0xe0,0x1a,0x28,0xb, 0x24,0x1a,0x3e,0xbd, +0x32,0x8, 0xc9,0xb, 0xf0,0x1a,0x29,0xb, 0x24,0x1a,0x3f,0xbd,0x32,0x8, 0xb5,0x4c, +0xaa,0x78,0x4, 0x6d,0x33,0x80,0x9, 0xa, 0x1a,0x6d,0x0, 0x7f,0x17,0x12,0x1f,0x58, +0xda,0x79,0x22,0x12,0x6d,0xcb,0x1a,0x26,0x1a,0x24,0x2f,0x71,0x22,0xca,0x79,0x7c, +0xa7,0x7c,0x8b,0x7e,0xb3,0x2a,0x6f,0x7a,0xb3,0x1f,0x9a,0x7e,0xb3,0x2a,0x70,0x7a, +0xb3,0x1f,0x9b,0x12,0x99,0xc8,0x9f,0x77,0x1a,0x3a,0x1a,0x79,0x9d,0x73,0x21,0xb5, +0x7a,0xf1,0x58,0xbe,0xf0,0x0, 0x58,0xe, 0x1a,0x3f,0x1a,0x29,0x9d,0x23,0x1a,0x39, +0x2d,0x32,0x7c,0xb7,0xf5,0x58,0x7e,0xb3,0x1f,0x9a,0xbc,0xbf,0x18,0xe, 0x1a,0x39, +0x1a,0x2f,0x9d,0x23,0x1a,0x39,0x9d,0x32,0x7c,0xb7,0xf5,0x58,0x1a,0x2a,0x1a,0x38, +0x9d,0x32,0x7c,0xb7,0xf5,0x57,0x80,0x3d,0x85,0x57,0x59,0xe5,0x57,0xbe,0xb0,0x0, +0x58,0x10,0xe5,0x57,0x1a,0x3b,0x1a,0x28,0x9d,0x23,0x1a,0x38,0x2d,0x32,0x7c,0xb7, +0xf5,0x59,0x7e,0xb3,0x1f,0x9b,0xbe,0xb1,0x57,0x18,0x10,0x1a,0x38,0xe5,0x57,0x1a, +0x2b,0x9d,0x23,0x1a,0x38,0x9d,0x32,0x7c,0xb7,0xf5,0x59,0xe5,0x58,0x7e,0x71,0x59, +0x12,0x99,0x3, 0x5, 0x57,0x1a,0x3a,0x1a,0x28,0x2d,0x23,0xe5,0x57,0x1a,0x3b,0xbd, +0x32,0x8, 0xb5,0xb, 0xf0,0x1a,0x3a,0x1a,0x29,0x2d,0x23,0x1a,0x3f,0xbd,0x32,0x18, +0x2, 0x21,0x30,0x7f,0x17,0xda,0x79,0x22,0x7e,0x70,0x2, 0xac,0x78,0x9, 0x93,0x26, +0xfa,0x9, 0x83,0x26,0xfb,0x22,0xca,0xd8,0xca,0x79,0x7e,0xf4,0x3, 0x20,0x7d,0x7f, +0x12,0x9a,0xc7,0x50,0x2, 0x41,0x6a,0x7a,0xf5,0x2a,0x7e,0xb3,0x28,0xa8,0xb4,0x1, +0x4, 0x7e,0x74,0x4, 0xb0,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x4, 0x4c,0x8, 0x6b,0x6c, +0xdd,0x80,0x5f,0xc2,0x0, 0x7c,0xbd,0x12,0x6f,0x6b,0x7a,0x35,0x26,0x7c,0xbd,0x7e, +0x70,0x1, 0x12,0x99,0xd, 0x7a,0x35,0x24,0x9e,0x35,0x26,0x7a,0x35,0x24,0x7e,0x35, +0x26,0x3e,0x34,0x3e,0x34,0x12,0x9a,0x6f,0x7a,0x35,0x28,0xbe,0x75,0x28,0x58,0x3, +0x7a,0x75,0x28,0x7e,0x35,0x28,0xbe,0x35,0x24,0x8, 0xa, 0x7e,0x35,0x2a,0xbe,0x35, +0x26,0x8, 0x2, 0xd2,0x0, 0x7c,0xbd,0x12,0x8f,0x82,0x50,0x2, 0xc2,0x0, 0x30,0x0, +0xf, 0x7c,0xbd,0x6c,0x77,0x12,0x73,0x2e,0x7e,0x70,0x2, 0xac,0x7d,0x12,0x8f,0xa4, +0xb, 0xd0,0x7e,0x73,0x28,0x84,0xbc,0x7d,0x38,0x99,0xda,0x79,0xda,0xd8,0x22,0x7e, +0x24,0x0, 0x2, 0x2, 0x1e,0xb9,0x7e,0xa0,0x1, 0x7e,0x37,0x2a,0x4f,0x12,0x9a,0xbf, +0x28,0x35,0x6d,0x22,0x9d,0x23,0xbe,0x27,0x7, 0xf8,0x58,0x2b,0x12,0x9a,0x6f,0xbe, +0x37,0x7, 0xfa,0x8, 0x22,0xe4,0x7a,0xb3,0x28,0x84,0x7e,0xb3,0x2a,0x3, 0x70,0x17, +0x7e,0xb3,0x38,0x9, 0xb4,0x1, 0x10,0x6c,0xaa,0x5, 0x5b,0xe5,0x5b,0xbe,0xb0,0x10, +0x28,0x5, 0xd2,0x15,0x75,0x5b,0x0, 0x4c,0xaa,0x68,0x3, 0x75,0x5b,0x0, 0x22,0x7e, +0xb3,0x28,0x84,0xbe,0xb0,0x0, 0x22,0x6c,0x99,0x6c,0x88,0x80,0xf, 0x7c,0xb8,0x12, +0x6f,0x6b,0xbe,0x34,0x1, 0xf4,0x8, 0x2, 0xb, 0x90,0xb, 0x80,0x7e,0x73,0x28,0x84, +0xbc,0x78,0x38,0xe9,0xbe,0x90,0x1, 0x38,0x2, 0xc3,0x22,0xd3,0x22,0xca,0x3b,0x7e, +0x77,0x2a,0x5c,0x12,0x9b,0x83,0x7d,0x63,0x3e,0x34,0x3e,0x34,0x7e,0xe4,0x0, 0xa, +0x12,0x9b,0x7b,0x7e,0xb3,0x28,0xa8,0x60,0xf, 0x7e,0x37,0x36,0xe5,0xbd,0x36,0x48, +0x7, 0x3e,0x34,0x3e,0x34,0x12,0x9b,0x7b,0xbe,0x64,0x4, 0x4c,0x8, 0xf, 0x12,0x9a, +0xc7,0x50,0x6, 0x7e,0xb3,0x28,0xa8,0x60,0x4, 0x74,0xa, 0x80,0x13,0x7e,0xb3,0x28, +0xa8,0x60,0xc, 0x7e,0xb3,0x36,0xe3,0xbe,0xb0,0x0, 0x28,0x8, 0x14,0x80,0x1, 0xe4, +0x7a,0xb3,0x36,0xe3,0x7e,0xe7,0x2a,0x5c,0x7d,0x3e,0x12,0x46,0xab,0x7e,0x53,0x36, +0xe3,0xbe,0x50,0x0, 0x28,0x12,0xbd,0x3f,0x58,0x4, 0x7d,0xf3,0x80,0x6, 0xbd,0xef, +0x8, 0x2, 0x7d,0xfe,0x7a,0xf7,0x2a,0x5c,0x12,0x97,0xcc,0x28,0x3, 0x12,0x75,0x21, +0x7a,0x67,0x36,0xe5,0x7a,0x77,0x2a,0x5c,0xda,0x3b,0x22,0x7d,0x2e,0x12,0x1e,0xb9, +0x7d,0xf3,0x22,0xca,0x3b,0x6d,0x44,0x7e,0xf3,0x28,0x84,0x6c,0xee,0x80,0x24,0x7c, +0xbe,0x12,0x88,0x65,0x60,0x1b,0x74,0x2, 0xac,0xbe,0x9, 0xd5,0x26,0xfa,0x9, 0xc5, +0x26,0xfb,0x7c,0xbd,0x7c,0x7c,0x12,0x6d,0xcb,0x7d,0xf3,0xbd,0x4f,0x58,0x2, 0x7d, +0x4f,0xb, 0xe0,0xbc,0xfe,0x38,0xd8,0x7d,0x34,0xda,0x3b,0x22,0xca,0x79,0x6c,0xff, +0x9f,0x77,0x7f,0x67,0x6d,0xbb,0x7e,0xa3,0x2a,0x70,0x7e,0xe3,0x2a,0x6f,0x7e,0xa7, +0x28,0x97,0x7e,0x8, 0x1f,0x34,0x7e,0x34,0x0, 0x1c,0xe4,0x12,0x20,0xe8,0x7e,0x8, +0x1f,0x50,0x7e,0x34,0x0, 0x1c,0x12,0x20,0xe8,0x6c,0x99,0x80,0x41,0x7e,0x50,0x2, +0xac,0x59,0x49,0x32,0x5, 0x7a,0xbe,0x34,0x0, 0xfa,0x8, 0x12,0x49,0x12,0x4, 0xfc, +0xbd,0x1a,0x58,0xa, 0x74,0x1, 0xa, 0x19,0x19,0xb1,0x1f,0x34,0x80,0x1e,0xbe,0x34, +0x0, 0xfa,0x8, 0x18,0x49,0x32,0x4, 0xfc,0xbe,0x34,0x0, 0xfa,0x8, 0xe, 0xbd,0x3b, +0x8, 0x2, 0x7d,0xb3,0x74,0x1, 0xa, 0x39,0x19,0xb3,0x1f,0x50,0xb, 0x90,0xbc,0xa9, +0x38,0xbb,0x6c,0x99,0x80,0x27,0xa, 0xa9,0x9, 0xba,0x1f,0x34,0xb4,0x1, 0x1c,0x6c, +0x88,0x80,0x14,0x7c,0xb8,0x7c,0x79,0x12,0x6d,0xcb,0x12,0x21,0xa, 0xbe,0x34,0x0, +0xfa,0x8, 0x2, 0xb, 0xf0,0xb, 0x80,0xbc,0xe8,0x38,0xe8,0xb, 0x90,0xbc,0xa9,0x38, +0xd5,0xbe,0xf0,0x1, 0x28,0x52,0xbe,0xb4,0x3, 0xe8,0x8, 0x4, 0x74,0x1, 0x80,0x49, +0x6c,0x99,0x80,0x21,0xa, 0x39,0x9, 0xb3,0x1f,0x50,0xb4,0x1, 0x16,0x7e,0x70,0x2, +0xac,0x79,0x49,0x13,0x5, 0x7a,0x1a,0x2, 0x1a,0x0, 0x2f,0x60,0x49,0x33,0x4, 0xfc, +0x12,0x99,0x6, 0xb, 0x90,0xbc,0xa9,0x38,0xdb,0x74,0x2, 0x7f,0x16,0x1e,0x34,0xe, +0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x7e,0x14,0x0, 0x5, 0x12,0x1e,0xfc, +0xbf,0x71,0x8, 0x4, 0x74,0x1, 0x80,0x1, 0xe4,0xda,0x79,0x22,0xca,0x3b,0x6c,0xaa, +0xc2,0x0, 0x7e,0x97,0x28,0x99,0x7e,0x87,0x28,0x97,0x7e,0xb3,0x28,0xa5,0x14,0x68, +0x19,0x14,0x68,0x1e,0x24,0xc2,0x68,0x8, 0x24,0xfb,0x68,0xe, 0x24,0x45,0x78,0x26, +0x7e,0xe3,0x2a,0x6e,0x7e,0xd3,0x2a,0x6d,0x80,0x20,0x6c,0xee,0x7e,0xd3,0x2a,0x6e, +0x80,0x18,0x6c,0xee,0x7e,0xb3,0x2a,0x6d,0xa, 0x2b,0x7e,0xb3,0x2a,0x6e,0xa, 0x3b, +0x2d,0x32,0x7c,0xd7,0x80,0x4, 0x6c,0xee,0x6c,0xdd,0x6c,0xff,0x80,0xf, 0x12,0x9e, +0x3a,0x6d,0x33,0x9d,0x39,0xbd,0x23,0x58,0x2, 0xb, 0xa0,0xb, 0xf0,0xbc,0xdf,0x38, +0xed,0x4c,0xaa,0x78,0x3c,0x7e,0xb3,0x26,0x85,0x70,0x25,0x7e,0xb3,0x26,0x84,0x70, +0x1f,0x6c,0xff,0x80,0x15,0x12,0x9e,0x3a,0xbd,0x29,0x8, 0xc, 0x49,0x33,0x4, 0xfc, +0xbd,0x38,0x58,0x4, 0xd2,0x0, 0x80,0x19,0xb, 0xf0,0xbc,0xdf,0x38,0xe7,0x80,0x11, +0x12,0x9b,0xbc,0xa, 0x8b,0x4d,0x88,0x68,0x8, 0x12,0x76,0xe0,0x28,0x3, 0x12,0x9e, +0x2d,0x6c,0xcc,0x12,0x76,0xe0,0x38,0x5, 0x12,0x9e,0x47,0x28,0x69,0x7e,0xb3,0x28, +0xa7,0xb4,0x1, 0x9, 0x7e,0xb3,0x28,0xaa,0xbe,0xb0,0x1, 0x68,0x59,0x7e,0xb3,0x28, +0xa8,0xb4,0x1, 0x52,0x6c,0xff,0x80,0x1d,0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xa3,0x26, +0xfa,0x9, 0x93,0x26,0xfb,0x12,0x6d,0xc7,0xbe,0x34,0x0, 0xc8,0x8, 0x5, 0x7e,0xc0, +0x1, 0x80,0xa, 0xb, 0xf0,0x7e,0xb3,0x28,0x84,0xbc,0xbf,0x38,0xdb,0x6c,0xff,0x80, +0x1d,0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xa3,0x27,0x36,0x9, 0x93,0x27,0x37,0x12,0x6d, +0xc7,0xbe,0x34,0xff,0x38,0x58,0x5, 0x7e,0xc0,0x1, 0x80,0xa, 0xb, 0xf0,0x7e,0xb3, +0x28,0x85,0xbc,0xbf,0x38,0xdb,0x4c,0xcc,0x78,0x29,0x6c,0xff,0x80,0x21,0xa, 0x3f, +0xa, 0x2e,0x2d,0x23,0x3e,0x24,0x49,0x32,0x5, 0x7a,0xbd,0x39,0x8, 0xf, 0x49,0x82, +0x4, 0xfc,0x3e,0x84,0xbd,0x38,0x8, 0x5, 0x7e,0xc0,0x1, 0x80,0x6, 0xb, 0xf0,0xbc, +0xdf,0x38,0xdb,0x30,0x0, 0x15,0x7e,0xb3,0x3a,0xc, 0x4, 0x7a,0xb3,0x3a,0xc, 0x7e, +0x73,0x3a,0xc, 0xbe,0x70,0xa, 0x28,0x3, 0x12,0x9e,0x2d,0x4c,0xcc,0x78,0xb, 0x7e, +0xb3,0x28,0xa8,0x60,0x2, 0xd2,0x19,0x12,0x9e,0x4f,0xda,0x3b,0x22,0x74,0xa, 0x7a, +0xb3,0x3a,0xc, 0x74,0x1, 0x7a,0xb3,0x28,0xa8,0x22,0xa, 0x2f,0xa, 0x3e,0x2d,0x32, +0x3e,0x34,0x49,0x23,0x5, 0x7a,0x22,0x7e,0x73,0x28,0x85,0xbe,0x70,0x0, 0x22,0xe4, +0x7a,0xb3,0x28,0xa8,0x7a,0xb3,0x3a,0xc, 0x22,0xca,0xd8,0xca,0x79,0x7c,0xdb,0x7e, +0xf0,0xa, 0x6c,0x11,0x80,0x21,0x7e,0x0, 0xff,0x74,0x9, 0xac,0xb1,0x19,0x5, 0x1f, +0x38,0x7e,0x34,0x7f,0xff,0x74,0x9, 0xac,0xb1,0x59,0x35,0x1f,0x34,0x74,0x9, 0xac, +0xb1,0x59,0x35,0x1f,0x36,0xb, 0x10,0xbc,0xf1,0x38,0xdb,0xe4,0x6c,0x77,0x7c,0x6d, +0x12,0x9f,0xa2,0x7c,0x7d,0x7c,0x6f,0x12,0x9f,0xa2,0x6c,0x0, 0x80,0x39,0x6c,0xee, +0x80,0x16,0x74,0x9, 0xac,0xbe,0x9, 0x65,0x1f,0x38,0x74,0x9, 0xac,0xb0,0x9, 0x75, +0x28,0xb2,0xbc,0x76,0x68,0x6, 0xb, 0xe0,0xbc,0x1e,0x38,0xe6,0xbc,0x1e,0x78,0x15, +0x7e,0x70,0x9, 0xac,0x70,0x12,0x7f,0xa0,0xac,0x31,0x2e,0x14,0x1f,0x34,0x74,0x9, +0x12,0x1f,0x8c,0xb, 0x10,0xb, 0x0, 0xbc,0xf0,0x38,0xc3,0x74,0x9, 0xac,0xbf,0xca, +0x59,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x29,0x62,0x12,0x20,0xc3,0x1b,0xfd,0xda,0x79, +0xda,0xd8,0x22,0xca,0x3b,0x7c,0x46,0x7c,0xab,0x6c,0x66,0x7c,0x57,0xe1,0x84,0x7e, +0xf0,0x9, 0xac,0xf6,0x9, 0x87,0x29,0x66,0x7c,0x98,0x7e,0xd0,0x9, 0xac,0xd5,0x9, +0xb6,0x28,0xb2,0xbc,0xb9,0x78,0x6b,0xbe,0x90,0xff,0x68,0x66,0x12,0x9f,0x98,0x39, +0x87,0x0, 0x4, 0xa, 0xf9,0x9, 0xbf,0x29,0xbc,0x7e,0xf0,0x9, 0x70,0xc, 0xac,0xf5, +0x7d,0x97,0x2e,0x94,0x28,0xae,0x6d,0x88,0x80,0xa, 0xac,0xf6,0x7d,0x97,0x2e,0x94, +0x29,0x62,0x6d,0x88,0xb, 0x4a,0xd0,0x12,0x9f,0x98,0x1b,0x7a,0xd0,0x69,0xf4,0x0, +0x2, 0x7e,0xf0,0x9, 0xac,0xfa,0x7f,0x60,0x2d,0xd7,0x79,0xf6,0x0, 0x2, 0x7e,0xf0, +0x9, 0xac,0xf5,0x9, 0x87,0x28,0xb3,0x12,0x9f,0x98,0x39,0x87,0x0, 0x5, 0x7e,0xf0, +0x9, 0xac,0xf5,0x9, 0x87,0x28,0xb4,0x12,0x9f,0x98,0x39,0x87,0x0, 0x6, 0xb, 0xa0, +0x80,0x8, 0xb, 0x50,0xbc,0x45,0x28,0x2, 0xc1,0xff,0xb, 0x60,0xbe,0x60,0xa, 0x50, +0x2, 0xc1,0xfb,0x7c,0xba,0xda,0x3b,0x22,0x7e,0xf0,0x9, 0xac,0xfa,0x7f,0x70,0x2d, +0xf7,0x22,0x7e,0x8, 0x1f,0x34,0x12,0x9e,0xf3,0x7c,0x1b,0x22,0x7c,0xab,0x7e,0xb, +0xb0,0x60,0x3, 0xb4,0x2, 0x31,0xa, 0x4a,0x9, 0x74,0x34,0xb8,0xbe,0x73,0x34,0xc2, +0x50,0xe, 0x7d,0x24,0x2e,0x24,0x34,0xb8,0x7c,0xb7,0x4, 0x7a,0x29,0xb0,0xd3,0x22, +0xbe,0x73,0x34,0xc2,0x40,0x9, 0xbe,0x70,0xff,0x68,0x4, 0xe4,0x7a,0xb, 0xb0,0x74, +0xff,0x19,0xb4,0x34,0xb8,0x80,0x17,0xa, 0x3a,0x9, 0xb3,0x34,0xb8,0xbe,0xb0,0xff, +0x68,0x7, 0xe4,0x19,0xb3,0x34,0xb8,0xd3,0x22,0xe4,0x19,0xb3,0x34,0xb8,0xc3,0x22, +0xca,0xf8,0x7c,0xfb,0x7d,0xf3,0x7e,0x17,0x2a,0x62,0xbd,0x13,0x38,0x6, 0x7e,0x34, +0x1, 0x0, 0x80,0x15,0x6d,0x22,0x7c,0x56,0x7c,0x67,0x6c,0x77,0x12,0x1f,0x5, 0xbe, +0x34,0x0, 0x10,0x50,0x4, 0x7e,0x34,0x0, 0x10,0x74,0x2, 0xac,0xbf,0x49,0x25,0x34, +0xc6,0xbd,0x2f,0x28,0x6, 0x49,0x35,0x34,0xa0,0x80,0x4, 0x59,0x35,0x34,0xa0,0x59, +0xf5,0x34,0xc6,0xbe,0x34,0x1, 0x0, 0x28,0x4, 0x7e,0x34,0x1, 0x0, 0xda,0xf8,0x22, +0xca,0x69,0xca,0xf8,0x7e,0xa3,0x2a,0x2, 0x7e,0x8, 0x29,0xbc,0x4c,0xaa,0x78,0x5, +0x12,0x24,0x66,0x21,0x9d,0x6c,0x99,0x7e,0x70,0x9, 0xac,0x79,0x9, 0x83,0x29,0xc, +0xbe,0x80,0xff,0x78,0x2, 0x21,0x94,0xa, 0x28,0x9, 0xb2,0x34,0x8c,0x7a,0xb3,0x34, +0x89,0x9, 0xb2,0x34,0x96,0x7a,0xb3,0x34,0x8a,0x7f,0x60,0x2d,0xd2,0x7e,0x6b,0xf0, +0xbe,0xf0,0x2, 0x68,0x2, 0x21,0x57,0x12,0xa1,0xac,0x49,0x33,0x29,0x8, 0x12,0xa1, +0xb6,0x7e,0x70,0x4, 0xac,0x78,0x49,0x23,0x35,0x59,0x12,0xa1,0xa2,0x9d,0x32,0x12, +0x21,0xa, 0x7d,0xe3,0x7e,0x73,0x34,0x89,0xa, 0x27,0xbd,0x2f,0x28,0x55,0xbd,0x2e, +0x28,0x51,0x12,0xa1,0xac,0x7e,0xd0,0x9, 0xac,0xd9,0x59,0x26,0x29,0x8, 0x7e,0x50, +0x4, 0xac,0x58,0x49,0x22,0x35,0x59,0x7e,0xd0,0x9, 0xac,0xd9,0x59,0x26,0x29,0xa, +0xbe,0xa0,0x0, 0x28,0x2, 0x1b,0xa0,0x4c,0xaa,0x78,0x5c,0x7e,0xb3,0x34,0x8a,0x4, +0x7a,0xb3,0x34,0x8a,0x7e,0x63,0x34,0x8a,0xbe,0x60,0x32,0x40,0x4a,0x74,0x1e,0x7a, +0xb3,0x34,0x8a,0x7e,0xb3,0x34,0x89,0xbe,0xb0,0x6, 0x50,0x3b,0x4, 0x7a,0xb3,0x34, +0x89,0x80,0x34,0x7e,0x50,0x9, 0xac,0x59,0x49,0xb2,0x29,0x8, 0x7e,0xd0,0x4, 0xac, +0xd8,0x59,0xb6,0x35,0x57,0x49,0x22,0x29,0xa, 0x59,0x26,0x35,0x59,0xbe,0x70,0xa, +0x40,0x4, 0x74,0x6, 0x80,0x8, 0xbe,0x70,0x1, 0x28,0x7, 0x7c,0xb7,0x14,0x7a,0xb3, +0x34,0x89,0xe4,0x7a,0xb3,0x34,0x8a,0x7e,0xb3,0x34,0x89,0xa, 0x38,0x19,0xb3,0x34, +0x8c,0x7e,0xb3,0x34,0x8a,0x80,0x37,0x4c,0xff,0x78,0x1b,0x7e,0x70,0x9, 0xac,0x79, +0x49,0x33,0x29,0x8, 0x7e,0x50,0x4, 0xac,0x58,0x59,0x32,0x35,0x57,0x12,0xa1,0xa2, +0x59,0x32,0x35,0x59,0x80,0x1e,0x7e,0x6b,0xb0,0xb4,0x1, 0x18,0x7e,0xb3,0x2a,0x2, +0xbe,0xb0,0x0, 0x28,0xf, 0x74,0xa, 0xa, 0x38,0x19,0xb3,0x34,0x8c,0xe4,0xa, 0x38, +0x19,0xb3,0x34,0x96,0xb, 0x90,0xbe,0x90,0xa, 0x68,0x2, 0x1, 0x67,0xda,0xf8,0xda, +0x69,0x22,0x7e,0x70,0x9, 0xac,0x79,0x49,0x33,0x29,0xa, 0x22,0x7e,0x50,0x4, 0xac, +0x58,0x49,0x22,0x35,0x57,0x22,0x9d,0x32,0x12,0x21,0xa, 0x7d,0xf3,0x22,0xa2,0xa, +0x22,0xca,0x79,0x6c,0x88,0x80,0x6b,0x74,0x2, 0xac,0xb8,0x9, 0xf5,0x26,0xfa,0x9, +0x75,0x26,0xfb,0x7a,0x71,0x24,0x7c,0xbf,0x12,0x67,0xe2,0x50,0x53,0x6c,0xee,0x80, +0x4a,0xbc,0xe8,0x68,0x44,0x7e,0x70,0x2, 0xac,0x7e,0x12,0x8f,0xe8,0x6c,0x99,0x7e, +0xb3,0x2a,0x70,0x14,0xbe,0xb1,0x26,0x78,0x10,0xa, 0x2f,0xe5,0x25,0x12,0x44,0x5b, +0xbe,0x34,0x0, 0x1, 0x18,0x3, 0x7e,0x90,0x1, 0xbe,0x90,0x1, 0x78,0x1b,0x7c,0xbe, +0x12,0x6f,0x6b,0x7d,0xf3,0x7c,0xb8,0x12,0x6f,0x6b,0xbd,0x3f,0x8, 0x4, 0x7c,0xbe, +0x80,0x2, 0x7c,0xb8,0x6c,0x77,0x12,0x73,0x2e,0xb, 0xe0,0x12,0x97,0xbe,0x38,0xb1, +0xb, 0x80,0x7e,0x73,0x28,0x84,0xbc,0x78,0x38,0x8d,0xda,0x79,0x22,0xe4,0x7a,0xb3, +0x36,0x69,0x7e,0xb3,0x28,0x84,0x60,0x6, 0x7e,0xb3,0x36,0xe2,0x60,0x5, 0xe4,0x7a, +0xb3,0x36,0xe4,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x14,0x23,0x1, 0x7e,0x4, +0x0, 0xff,0x69,0x30,0x0, 0x2, 0xb, 0xa, 0x20,0x7a,0x1d,0x2c,0x7e,0x73,0x2a,0x6d, +0xa, 0x37,0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x20,0xc3,0x1b,0xfd,0x6c, +0xdd,0x12,0x87,0xb8,0x7a,0xb3,0x1f,0x34,0x6c,0xcc,0x80,0x4a,0x12,0xa3,0x2f,0x40, +0x43,0x12,0xa3,0x25,0x50,0x3e,0x12,0x87,0xc0,0xb, 0x1a,0x10,0x7d,0x3f,0x12,0x21, +0xa, 0x7d,0x3, 0x7d,0x31,0x12,0x21,0xa, 0xbd,0x30,0x58,0x2, 0x7d,0xf1,0xbe,0x15, +0x2a,0x8, 0x5, 0x7e,0x15,0x2a,0x80,0xb, 0x6d,0x0, 0x9e,0x5, 0x2a,0xbd,0x1, 0x8, +0x2, 0x7d,0x10,0x7d,0x31,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x1f,0x34,0x4, +0x7a,0xb3,0x1f,0x34,0xb, 0xc0,0x12,0x57,0x75,0x38,0xb1,0x7e,0x73,0x1f,0x34,0x4c, +0x77,0x68,0x36,0x12,0x87,0xc9,0xbd,0x3e,0x8, 0x2, 0x7d,0x7f,0xbe,0x75,0x2a,0x8, +0x5, 0x7e,0x75,0x2a,0x80,0xb, 0x6d,0xee,0x9e,0xe5,0x2a,0xbd,0xe7,0x8, 0x2, 0x7d, +0x7e,0x6c,0xcc,0x80,0xf, 0x12,0xa3,0x2f,0x40,0x8, 0x12,0xa3,0x25,0x50,0x3, 0x12, +0x87,0xde,0xb, 0xc0,0x12,0x57,0x75,0x38,0xec,0xb, 0xd0,0xbe,0xd0,0x3, 0x50,0x2, +0x41,0x81,0xda,0x3b,0x22,0x7c,0x1d,0x2e,0x10,0x2d,0xa5,0xe7,0xbc,0xab,0x22,0xa, +0xec,0x9, 0xae,0x2a,0xb9,0x7c,0x1d,0x2e,0x10,0x2c,0xa5,0xe7,0xbc,0xab,0x22,0xca, +0x79,0x7e,0xb3,0x3, 0xfd,0x60,0x5f,0x7e,0xb3,0x2a,0x68,0x60,0x59,0x7e,0xf3,0x2a, +0x6f,0x7e,0xe3,0x2a,0x70,0x7e,0x1f,0x13,0x8a,0x7a,0x1d,0x24,0x74,0x2, 0xac,0xbe, +0x2d,0x35,0x1b,0x35,0x6c,0xaa,0x80,0xf, 0xb, 0x1a,0x40,0x7e,0x30,0x2, 0xac,0x3a, +0x59,0x41,0x1f,0x34,0x12,0xa3,0xa9,0xbc,0xfa,0x38,0xed,0x7e,0x8, 0x1f,0x34,0x7c, +0xbf,0x12,0x5e,0xa9,0x74,0x2, 0xac,0xbe,0x7e,0x1d,0x24,0x2d,0x35,0x1b,0x35,0x6c, +0xaa,0x80,0xf, 0x7e,0x30,0x2, 0xac,0x3a,0x49,0x11,0x1f,0x34,0x1b,0x1a,0x10,0x12, +0xa3,0xa9,0xbc,0xfa,0x38,0xed,0xda,0x79,0x22,0x7e,0x30,0x2, 0xac,0x3e,0x2d,0x31, +0xb, 0xa0,0x22,0x7e,0x63,0x2a,0x6e,0xc2,0x16,0x6c,0x33,0x80,0x48,0x7c,0x96,0xac, +0x93,0x2e,0x44,0x0, 0x17,0x7d,0x4, 0xb, 0x4, 0x7d,0x54,0x3e,0x54,0x7e,0x7f,0x13, +0x8a,0x2d,0xf5,0xb, 0x7a,0x50,0xbe,0x57,0x2a,0x5a,0x8, 0x27,0x7c,0xb3,0x12,0x67, +0x50,0x50,0x20,0x7d,0x50,0x3e,0x54,0x7e,0x7f,0x13,0x8a,0x7f,0x67,0x2d,0xd5,0xb, +0x6a,0x20,0x7d,0x54,0x3e,0x54,0x2d,0xf5,0xb, 0x7a,0x50,0xbd,0x52,0x8, 0x4, 0xd2, +0x16,0x80,0xa, 0xb, 0x30,0x7e,0x73,0x2a,0x75,0xbc,0x73,0x38,0xb0,0x30,0x16,0x5, +0xd2,0x0, 0x2, 0x67,0xa3,0x22,0x7e,0xb3,0x2b,0x1d,0xb4,0x1, 0x31,0x12,0xa4,0x4f, +0x7e,0x1f,0x39,0xda,0x7a,0x37,0x24,0xfa,0x7e,0x34,0xd, 0xc8,0x7a,0x37,0x24,0xf6, +0x12,0xa4,0x56,0x12,0xa4,0x5f,0xe4,0x7a,0xb3,0x24,0xf5,0x7e,0x34,0x0, 0x20,0x7a, +0x37,0x24,0xfc,0x7a,0xb3,0x24,0xf4,0x7e,0x8, 0x24,0xf2,0x2, 0xd, 0x7, 0x22,0xa9, +0xd1,0xcb,0xe4,0x2, 0x0, 0xe, 0x7e,0x73,0x2a,0x6d,0x7a,0x73,0x24,0xf2,0x22,0x7e, +0x73,0x2a,0x6e,0x7a,0x73,0x24,0xf3,0x22,0x7e,0x43,0x2a,0x6e,0x7e,0x53,0x2a,0x6d, +0xac,0x54,0x7e,0x17,0x28,0xa1,0x12,0xa4,0x4f,0x6d,0x0, 0x80,0x37,0x7d,0x40,0x3e, +0x44,0x7e,0x7f,0x39,0xda,0x2d,0xf4,0xb, 0x7a,0x30,0xbd,0x13,0x58,0x10,0x7d,0xf4, +0x2e,0xf4,0x8, 0xa, 0xb, 0xf8,0x50,0x9d,0x51,0x1b,0xf8,0x50,0x80,0x14,0x6d,0x55, +0x9d,0x51,0xbd,0x53,0x8, 0xc, 0x2e,0x44,0x8, 0xa, 0xb, 0x48,0x50,0x2d,0x51,0x1b, +0x48,0x50,0xb, 0x4, 0xbd,0x20,0x38,0xc5,0x22,0xca,0x3b,0x7e,0xf3,0x2a,0x6e,0x7e, +0xe3,0x2a,0x6f,0x7e,0xd3,0x2a,0x70,0x6c,0xcc,0x80,0x13,0x7c,0x7c,0xac,0x7f,0x3e, +0x34,0x7e,0xf, 0x13,0x8a,0x2d,0x13,0x7c,0xbd,0x12,0x5e,0xa9,0xb, 0xc0,0xbc,0xec, +0x38,0xe9,0xda,0x3b,0x22,0x6c,0xaa,0x7e,0x30,0x4, 0xac,0x3a,0x7d,0xf1,0x2e,0xf4, +0x60,0xb1,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x20,0xbd,0x23,0x38,0xf, 0x2e,0x14,0x60, +0xb3,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x20,0xbd,0x23,0x50,0x7, 0xb, 0xa0,0xbe,0xa0, +0x3, 0x40,0xd4,0x7c,0xba,0x22,0x12,0xa5,0x25,0xbe,0x34,0x4, 0xe2,0x28,0x3, 0xd2, +0x17,0x22,0xc2,0x17,0x22,0x6d,0x11,0xe4,0x12,0x0, 0x1e,0x6c,0xaa,0x80,0x5b,0x7e, +0x10,0x2, 0xac,0x1a,0x7e,0x7f,0x39,0xf4,0x2d,0xf0,0x69,0x27,0x1, 0x0, 0x69,0x37, +0x0, 0x80,0x9d,0x32,0x12,0x21,0xa, 0xbd,0x31,0x28,0x16,0x7e,0x70,0x2, 0xac,0x7a, +0x7e,0xf, 0x39,0xf4,0x2d,0x13,0x69,0x20,0x1, 0x0, 0x69,0x30,0x0, 0x80,0x12,0x4f, +0xcc,0x7e,0x10,0x2, 0xac,0x1a,0x7e,0x1f,0x39,0xf4,0x2d,0x30,0x69,0x1, 0x0, 0x80, +0xbe,0x4, 0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0x69,0x1, 0x1, 0x0, 0xbe,0x4, +0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0xb, 0xa0,0x7e,0xb3,0x2a,0x74,0xbc,0xba, +0x38,0x9d,0x7d,0x31,0x22,0x7e,0x60,0x4, 0x7e,0x27,0x3a,0x5, 0xbe,0x24,0x3, 0xe8, +0x28,0x3, 0x7e,0x60,0x8, 0x7e,0xb3,0x28,0xac,0xb4,0x1, 0x1a,0x7e,0x73,0x2f,0xaa, +0xbc,0x76,0x50,0xf, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x6c,0x5a,0x7e,0xb3,0x2f,0xaa, +0x4, 0x80,0x4, 0xe4,0x80,0x1, 0xe4,0x7a,0xb3,0x2f,0xaa,0x7e,0xb3,0x28,0xad,0xb4, +0x1, 0x17,0x7e,0xa3,0x2f,0xab,0xbe,0xa0,0x5, 0x50,0xa, 0xe4,0x7a,0xb3,0x28,0xad, +0x7c,0xba,0x4, 0x80,0x5, 0x74,0x5, 0x80,0x1, 0xe4,0x7a,0xb3,0x2f,0xab,0x22,0x6c, +0xaa,0x80,0x26,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x5, 0xf8,0x49,0x32,0x4, 0x0, +0x2d,0x31,0x59,0x32,0x5, 0xf8,0x30,0x6, 0xe, 0x49,0x12,0x4, 0x7e,0x49,0x32,0x6, +0x76,0x2d,0x31,0x59,0x32,0x6, 0x76,0xb, 0xa0,0x7e,0xb3,0x2a,0x74,0xa, 0x3b,0x7e, +0xb3,0x2a,0x73,0xa, 0x2b,0x2d,0x23,0xa, 0x3a,0xbd,0x32,0x48,0xc6,0x22,0x74,0x2, +0x7a,0xb3,0x2f,0xa9,0x74,0x1, 0x7a,0xb3,0x28,0xac,0x2, 0x26,0x11,0xd2,0x0, 0x6c, +0xaa,0x6c,0x77,0x80,0x1f,0x7e,0x63,0x2a,0x6e,0xa, 0x16,0xa, 0x27,0x2d,0x21,0x7c, +0x65,0x7e,0x50,0x2, 0xac,0x56,0x49,0x22,0x5, 0x7a,0xbe,0x24,0xfe,0xc, 0x58,0x2, +0xb, 0xa0,0xb, 0x70,0x7e,0xb3,0x2a,0x6d,0xbc,0xb7,0x38,0xd9,0xa, 0x2b,0x1e,0x24, +0xa, 0x3a,0xbd,0x32,0x8, 0x2, 0xc2,0x0, 0xa2,0x0, 0x22,0x7e,0x63,0x2a,0x6f,0x7e, +0xa3,0x2a,0x70,0x7e,0x70,0x1, 0x80,0x15,0xa, 0x17,0x7e,0xb3,0x2a,0x6e,0xa, 0x2b, +0x2d,0x21,0x3e,0x24,0x12,0xa6,0xc6,0x58,0x2, 0xd3,0x22,0xb, 0x70,0xa, 0x16,0x1b, +0x14,0xa, 0x27,0xbd,0x21,0x48,0xe1,0x7e,0x70,0x2, 0x80,0xe, 0x7e,0x50,0x2, 0xac, +0x57,0x12,0xa6,0xc6,0x58,0x2, 0xd3,0x22,0xb, 0x70,0xa, 0x1a,0x1b,0x15,0xa, 0x27, +0xbd,0x21,0x48,0xe8,0xc3,0x22,0x49,0x22,0x4, 0xfc,0xbe,0x24,0xff,0x6, 0x22,0x7e, +0xb3,0x37,0x75,0xb4,0x1, 0x3, 0x2, 0xa7,0x26,0x7e,0xb3,0x37,0xdb,0x4, 0x7a,0xb3, +0x37,0xdb,0x7e,0xb3,0x37,0x69,0xb4,0x2, 0x18,0x7e,0xb3,0x37,0xda,0x4, 0x7a,0xb3, +0x37,0xda,0xb4,0x1, 0x6, 0x74,0x1, 0x7a,0xb3,0x37,0xdb,0x74,0x1, 0x7a,0xb3,0x37, +0x69,0x7e,0x73,0x37,0xda,0xbe,0x70,0x3, 0x40,0xf, 0x74,0x1, 0x7a,0xb3,0x37,0x75, +0x12,0xa7,0x26,0x12,0xa7,0xd0,0x12,0xa7,0x2d,0x7e,0x73,0x37,0xdb,0xbe,0x70,0xa, +0x28,0x3, 0x2, 0xa7,0x2d,0x22,0x74,0x2, 0x7a,0xb3,0x37,0x69,0x22,0xe4,0x7a,0xb3, +0x37,0xdb,0x7a,0xb3,0x37,0xda,0x22,0x7e,0x73,0x37,0x69,0x7a,0x73,0x37,0xdf,0x7e, +0x47,0x39,0xd7,0xbe,0x44,0x0, 0x64,0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x37,0x69,0xbe, +0x44,0x0, 0xc8,0x28,0x8, 0xe4,0x7a,0xb3,0x37,0x67,0x12,0xa7,0x26,0x7e,0x57,0x37, +0x6f,0xbd,0x54,0x50,0x4, 0x7a,0x47,0x37,0x6f,0x12,0xa7,0xc8,0x38,0xa, 0x12,0xa7, +0xc0,0x38,0x5, 0x12,0xa7,0xb8,0x28,0x34,0x12,0xa6,0xcf,0xbe,0x44,0x0, 0x32,0x50, +0x21,0x7e,0xb3,0x37,0x67,0x4, 0x7a,0xb3,0x37,0x67,0x7e,0x73,0x37,0x67,0xbe,0x70, +0x32,0x28,0x14,0x74,0x32,0x7a,0xb3,0x37,0x67,0x12,0x57,0xee,0x7a,0xb3,0x37,0xdc, +0x80,0x5, 0xe4,0x7a,0xb3,0x37,0x67,0x7d,0x34,0x2, 0xa8,0x35,0x2, 0xa7,0xaf,0x12, +0xa7,0x2d,0xe4,0x7a,0xb3,0x37,0x75,0x22,0x7e,0x73,0x26,0xf5,0xbe,0x70,0x0, 0x22, +0x7e,0x73,0x26,0xf4,0xbe,0x70,0x0, 0x22,0x7e,0x73,0x28,0x92,0xbe,0x70,0x0, 0x22, +0xe4,0x7a,0xb3,0x37,0x67,0x6d,0x33,0x6c,0xaa,0x7e,0x50,0xc, 0xac,0x5a,0x59,0x32, +0x37,0x7e,0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xf0,0xe4,0x7a,0xb3,0x37,0x68,0x6d,0x33, +0x7a,0x37,0x37,0x6f,0x7a,0x37,0x37,0x64,0x22,0x7e,0x37,0x39,0xd3,0x12,0x7e,0x3c, +0x7a,0x37,0x37,0xdd,0x6c,0xaa,0x80,0x24,0xbe,0xa0,0x4, 0x50,0x27,0xa, 0x3a,0x9, +0x63,0x37,0x76,0xbe,0x60,0x4, 0x50,0x12,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x42,0x39, +0xcd,0x7e,0x70,0xc, 0xac,0x67,0x59,0x43,0x37,0x80,0xb, 0xa0,0x7e,0xb3,0x37,0x73, +0xbc,0xba,0x38,0xd4,0x22,0xbe,0x34,0x1, 0xf4,0x28,0xd, 0x7e,0x53,0x37,0xdc,0xbe, +0x50,0x8, 0x50,0x3f,0x74,0x8, 0x80,0x37,0xbe,0x34,0x1, 0x90,0x28,0xd, 0x7e,0x53, +0x37,0xdc,0xbe,0x50,0x6, 0x50,0x2c,0x74,0x6, 0x80,0x24,0xbe,0x34,0x1, 0x2c,0x28, +0xd, 0x7e,0x53,0x37,0xdc,0xbe,0x50,0x4, 0x50,0x19,0x74,0x4, 0x80,0x11,0xbe,0x34, +0x0, 0xc8,0x28,0xf, 0x7e,0x73,0x37,0xdc,0xbe,0x70,0x2, 0x50,0x6, 0x74,0x2, 0x7a, +0xb3,0x37,0xdc,0x7e,0xb3,0x37,0xdc,0xbe,0xb0,0x0, 0x28,0x19,0x14,0x7a,0xb3,0x37, +0xdc,0x74,0x1, 0x7a,0xb3,0x16,0x92,0x7e,0x73,0x37,0xdc,0xbe,0x70,0x4, 0x28,0x5, +0xe4,0x7a,0xb3,0x16,0x91,0x22,0x7c,0x3b,0x7e,0x44,0xff,0xff,0x6c,0x22,0x80,0x2a, +0x12,0xa9,0x1f,0x68,0x23,0x7e,0x70,0xc, 0xac,0x72,0x12,0xaa,0x2f,0x7d,0x23,0x7e, +0x70,0xc, 0xac,0x72,0x59,0x23,0x37,0x82,0x49,0x3, 0x37,0x82,0x49,0x23,0x37,0x7e, +0xbd,0x20,0x50,0x4, 0x59,0x3, 0x37,0x7e,0xb, 0x20,0xbc,0x32,0x50,0xd2,0x6c,0xaa, +0x6c,0x22,0x80,0x18,0x12,0xa9,0x1f,0x68,0x11,0x7e,0x70,0xc, 0xac,0x72,0x49,0x3, +0x37,0x7e,0xbd,0x4, 0x50,0x4, 0x7d,0x40,0x7c,0xa2,0xb, 0x20,0xbc,0x32,0x50,0xe4, +0x7e,0x37,0x37,0x64,0xbe,0x37,0x37,0xdd,0x50,0x8, 0x7e,0x37,0x37,0xdd,0x7a,0x37, +0x37,0x64,0x12,0xaa,0x25,0x4d,0x33,0x78,0x3, 0x7e,0xa0,0xff,0x7c,0xba,0x22,0x7e, +0x10,0x5, 0xac,0x12,0x9, 0xb0,0x26,0x33,0xbe,0xb3,0x2b,0xf, 0x22,0xca,0x79,0x7e, +0xf0,0xff,0x12,0xaa,0x96,0x7e,0xb3,0x37,0x6b,0xb4,0x1, 0x8, 0x12,0x6a,0xaf,0xe4, +0x7a,0xb3,0x37,0x6b,0x7e,0xb3,0x37,0x6a,0x60,0x4, 0x74,0xff,0x41,0x22,0x7e,0xb3, +0x37,0x69,0xb4,0x2, 0x2, 0x80,0x2, 0x41,0x16,0x12,0xa7,0xc8,0x38,0xc, 0x12,0xa7, +0xc0,0x38,0x7, 0x12,0xa7,0xb8,0x38,0x2, 0x41,0x16,0x74,0x3, 0x12,0xa8,0xa6,0x7c, +0xeb,0x7e,0xb3,0x37,0x68,0x4, 0x7a,0xb3,0x37,0x68,0x74,0x3, 0x12,0xa8,0xa6,0x7c, +0xab,0xbe,0xa0,0xff,0x68,0x23,0xbe,0xe0,0xff,0x68,0x1c,0x7e,0x30,0xc, 0xac,0x3e, +0x49,0x21,0x37,0x7e,0xbe,0x24,0x1, 0xf4,0x28,0xf, 0x12,0xaa,0x25,0x3e,0x34,0xbd, +0x23,0x28,0x6, 0x7c,0xea,0x80,0x2, 0x7c,0xea,0xbe,0xe0,0xff,0x78,0x11,0xe4,0x7a, +0xb3,0x37,0x68,0x7a,0xb3,0x37,0x69,0x7a,0xb3,0x37,0x75,0x74,0xff,0x80,0x63,0x7e, +0x73,0x37,0x68,0xbe,0x70,0x4, 0x28,0x4e,0x74,0xc, 0xac,0xbe,0x49,0x35,0x37,0x7e, +0xbe,0x34,0x1, 0xf4,0x50,0x37,0x7e,0x37,0x37,0x64,0xbe,0x34,0x1, 0x2c,0x38,0xa, +0x7e,0x37,0x37,0x6f,0xbe,0x34,0x1, 0x2c,0x28,0x23,0x74,0x5, 0xac,0xbe,0x9, 0x75, +0x26,0x33,0xbe,0x73,0x2b,0xf, 0x68,0x15,0x7c,0xfe,0xbe,0xf0,0x4, 0x50,0x8, 0x12, +0x8b,0x16,0xbe,0xb0,0x4, 0x40,0x6, 0x74,0x1, 0x7a,0xb3,0x37,0x6b,0xe4,0x7a,0xb3, +0x37,0x75,0x7a,0xb3,0x37,0x69,0xbe,0xf0,0xff,0x68,0x5, 0xe4,0x7a,0xb3,0x37,0x68, +0x7c,0xbf,0xda,0x79,0x22,0x7e,0x70,0xc, 0xac,0x7a,0x49,0x33,0x37,0x7e,0x22,0x49, +0x23,0x37,0x84,0x49,0x33,0x37,0x80,0x9d,0x32,0x2, 0x21,0xa, 0x6c,0xaa,0x7e,0x70, +0xc, 0xac,0x7a,0x12,0xaa,0x2f,0xbe,0x34,0x3, 0xe8,0x8, 0x5, 0x12,0xaa,0x88,0x80, +0x2f,0x7e,0x50,0xc, 0xac,0x5a,0x49,0x32,0x37,0x84,0x49,0x12,0x37,0x80,0xbd,0x13, +0x28,0xf, 0x7d,0x2, 0x2e,0x4, 0x37,0x84,0x7d,0x13,0xb, 0x15,0x1b,0x8, 0x10,0x80, +0xf, 0xbe,0x34,0x0, 0x2, 0x28,0x9, 0x2e,0x24,0x37,0x84,0x1b,0x35,0x1b,0x28,0x30, +0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xb7,0x22,0x7e,0x50,0xc, 0xac,0x5a,0x49,0x32,0x37, +0x80,0x59,0x32,0x37,0x84,0x22,0x7e,0xb3,0x37,0x6a,0xb4,0x1, 0x27,0x7e,0xb3,0x37, +0xe0,0x4, 0x7a,0xb3,0x37,0xe0,0x7e,0x73,0x37,0xe0,0xbe,0x70,0x3, 0x40,0x15,0x12, +0x57,0x9f,0x7e,0x73,0x37,0xe0,0xbe,0x70,0x6, 0x40,0x9, 0xe4,0x7a,0xb3,0x37,0xe0, +0x7a,0xb3,0x37,0x6a,0x22,0x12,0x4f,0xee,0x12,0xaa,0xfe,0x7e,0x8, 0x2a,0x88,0x7e, +0xb3,0x2a,0x87,0x12,0xaa,0xf7,0x7e,0x8, 0x2b,0x2f,0x7e,0xb3,0x2b,0x2e,0x12,0xaa, +0xf7,0x7e,0x8, 0x2a,0x8a,0xe5,0x25,0x12,0x8f,0xc7,0x7e,0x8, 0x2b,0x31,0xe5,0x24, +0x7e,0x34,0x0, 0x3, 0x2, 0x20,0xe8,0x7e,0x34,0x0, 0x2, 0x2, 0x20,0xe8,0x6c,0xaa, +0xe4,0xa, 0x4b,0x9, 0x94,0x2a,0x7a,0xbc,0x9a,0x68,0x6, 0x4, 0xbe,0xb0,0xe, 0x40, +0xf0,0xbe,0xb0,0xe, 0x68,0x7, 0xb, 0xa0,0xbe,0xa0,0x23,0x40,0xe3,0x7a,0xb, 0xa0, +0x74,0x6e,0x7a,0x1b,0xb0,0x22,0x7e,0x8, 0x37,0x7a,0x7e,0x34,0x0, 0x60,0xe4,0x12, +0x20,0xe8,0x6c,0xaa,0x7e,0x44,0xff,0xff,0x7e,0x70,0xc, 0xac,0x7a,0x59,0x43,0x37, +0x7c,0x59,0x43,0x37,0x84,0xb, 0xa0,0xbe,0xa0,0x8, 0x40,0xe8,0x7e,0x8, 0x37,0x68, +0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x20,0xe8,0x12,0x47,0xe2,0x7e,0xb3,0x37,0x71,0xbe, +0xb0,0x1, 0x68,0x6, 0x7e,0xb3,0x37,0xed,0x60,0x10,0x7e,0x34,0x0, 0xf0,0x7a,0x37, +0x2a,0x5a,0x7e,0x34,0x0, 0xc8,0x7a,0x37,0x2a,0x5c,0x7e,0xb3,0x28,0xa8,0xb4,0x1, +0x24,0x7e,0x34,0x1, 0x18,0x7a,0x37,0x2a,0x5a,0x7e,0x34,0x0, 0xfa,0x7a,0x37,0x2a, +0x5c,0x7e,0x34,0x1, 0x40,0x7a,0x37,0x2a,0x4f,0x7a,0x37,0x2a,0x51,0x7e,0x34,0x1, +0x7c,0x7a,0x37,0x2a,0x53,0x7e,0xb3,0x2a,0x2, 0x70,0x21,0x7e,0x27,0x2a,0x5a,0x7d, +0x32,0x7e,0x14,0x0, 0x4, 0xad,0x13,0x7d,0x31,0x12,0x7e,0x3c,0xbe,0x34,0x0, 0x50, +0x28,0x4, 0x7e,0x34,0x0, 0x50,0x2d,0x32,0x7a,0x37,0x2a,0x5a,0x22,0x6d,0x33,0x7d, +0x23,0x7d,0x3, 0x6c,0x33,0x80,0x45,0x6c,0x22,0x80,0x37,0x7e,0xb3,0x2a,0x6e,0xac, +0xb3,0xa, 0x42,0x2d,0x54,0x7d,0x45,0x3e,0x44,0x7e,0x7f,0x13,0x8a,0x2d,0xf4,0xb, +0x7a,0x40,0xbe,0x44,0x0, 0x32,0x8, 0x8, 0xbe,0x44,0x2, 0x58,0x58,0x2, 0xb, 0x24, +0xbe,0x44,0xff,0xce,0x58,0x8, 0xbe,0x44,0xfd,0xa8,0x8, 0x2, 0xb, 0x4, 0xb, 0x34, +0xb, 0x21,0x7e,0x93,0x2a,0x6e,0xbc,0x92,0x38,0xc1,0xb, 0x31,0x7e,0xb3,0x2a,0x6d, +0xbc,0xb3,0x38,0xb3,0x7e,0x54,0x0, 0x6, 0xad,0x53,0x7d,0x15,0x1e,0x14,0x1e,0x14, +0x1e,0x14,0x12,0x7e,0x3e,0xbd,0x12,0x50,0x22,0xbd,0x30,0x28,0x1e,0xe4,0x7a,0xb3, +0x3a,0x9, 0x7e,0xb3,0x3a,0xa, 0xbe,0xb0,0x5, 0x50,0x7, 0x4, 0x7a,0xb3,0x3a,0xa, +0x80,0x3c,0xe4,0x7a,0xb3,0x3a,0xa, 0x74,0x1, 0x80,0x2f,0xbd,0x10,0x50,0x22,0xbd, +0x32,0x28,0x1e,0xe4,0x7a,0xb3,0x3a,0xa, 0x7e,0xb3,0x3a,0x9, 0xbe,0xb0,0x5, 0x50, +0x7, 0x4, 0x7a,0xb3,0x3a,0x9, 0x80,0x16,0xe4,0x7a,0xb3,0x3a,0x9, 0x74,0x2, 0x80, +0x9, 0xe4,0x7a,0xb3,0x3a,0x9, 0x7a,0xb3,0x3a,0xa, 0x7a,0xb3,0x3a,0xb, 0x7e,0xb3, +0x3a,0xb, 0x22,0x6c,0x66,0x7e,0xb3,0x28,0xa8,0xb4,0x1, 0x63,0x7e,0x73,0x26,0xf2, +0xbe,0x70,0x0, 0x28,0x5a,0x6c,0x33,0x80,0x4e,0xa, 0x23,0x9, 0x72,0x26,0xe6,0x7e, +0xb3,0x2a,0x6e,0x14,0xbc,0x7b,0x78,0x3d,0x6c,0x22,0x80,0x27,0x7c,0xb2,0x7c,0x73, +0x12,0x67,0xe2,0x50,0x1c,0xa, 0x22,0x7e,0x73,0x2a,0x6e,0xa, 0x7, 0x2d,0x2, 0x3e, +0x4, 0x49,0x20,0x4, 0xfc,0x6d,0x0, 0x9e,0x7, 0x2a,0x4f,0xbd,0x20,0x58,0x2, 0xb, +0x60,0xb, 0x20,0x7e,0x73,0x2a,0x6d,0xbc,0x72,0x38,0xd1,0xbe,0x60,0x0, 0x28,0x3, +0x74,0x1, 0x22,0xe4,0x22,0xb, 0x30,0x7e,0x73,0x26,0xf2,0xbc,0x73,0x38,0xaa,0x74, +0x1, 0x22,0x7c,0xab,0xbe,0xa0,0x0, 0x40,0x11,0x7e,0xb3,0x2a,0x6e,0xbc,0xba,0x28, +0x9, 0x74,0x2, 0xa4,0x49,0x25,0x34,0x0, 0x80,0x51,0x7e,0x13,0x2a,0x6e,0xbc,0x1a, +0x38,0x1c,0x7e,0x3, 0x2a,0x6d,0xa, 0x10,0xa, 0x21,0x2d,0x12,0xa, 0x3a,0xbd,0x31, +0x58,0xc, 0x9d,0x32,0x3e,0x34,0x3e,0x34,0x49,0x23,0x3, 0x70,0x80,0x2d,0x7e,0x3, +0x2a,0x6d,0xa, 0x20,0xa, 0x11,0x7d,0x41,0x2d,0x42,0xa, 0x3a,0xbd,0x34,0x48,0x19, +0x7e,0x10,0x2, 0xac,0x1, 0x2d,0x1, 0xbd,0x30,0x58,0xe, 0x9d,0x31,0x9d,0x32,0x3e, +0x34,0x3e,0x34,0x49,0x23,0x3, 0x72,0x80,0x2, 0xe4,0x22,0x7e,0x34,0x0, 0x64,0xad, +0x23,0x74,0xc, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x7c, +0xb7,0x22,0xca,0xf8,0x80,0x38,0x7c,0xbf,0x12,0xad,0x2, 0xa, 0x1b,0x7e,0x63,0x2a, +0x6e,0x7e,0x70,0x2, 0xac,0x67,0x7e,0x10,0x2, 0xac,0x1f,0x2d,0x3, 0x7e,0x1f,0x13, +0x8a,0x2d,0x30,0x12,0xad,0xc1,0x9d,0x35,0x1b,0x1a,0x10,0xb, 0xf0,0x12,0xad,0xc1, +0x7e,0x73,0x2a,0x6e,0xa, 0x27,0x2d,0x25,0xa, 0x3f,0xbd,0x32,0x48,0xc8,0xda,0xf8, +0x22,0x7e,0xa3,0x2a,0x6d,0x74,0x2, 0xa4,0x22,0xc2,0x0, 0x12,0x44,0xc4,0x50,0x42, +0x6c,0xaa,0x80,0x30,0x7e,0x50,0x2, 0xac,0x5a,0x9, 0x72,0x26,0xfa,0x9, 0x62,0x26, +0xfb,0xbe,0x70,0x0, 0x40,0x1c,0x7e,0xb3,0x2a,0x6f,0xa, 0x1b,0x1b,0x14,0xa, 0x27, +0xbd,0x21,0x18,0xe, 0xbe,0x60,0x0, 0x40,0x9, 0xbe,0x60,0xf, 0x38,0x4, 0xd2,0x0, +0x80,0xa, 0xb, 0xa0,0x7e,0xb3,0x28,0x84,0xbc,0xba,0x38,0xc8,0x20,0x0, 0x3, 0x12, +0x6c,0x48,0x30,0x1a,0x14,0x5, 0x5d,0xe5,0x5d,0xbe,0xb0,0x50,0x50,0x7, 0x7e,0x34, +0x0, 0x8, 0x2, 0x5f,0xcc,0xc2,0x1a,0x80,0x0, 0x75,0x5d,0x0, 0x22,0xca,0x3b,0x7c, +0xfb,0x75,0x3d,0x0, 0x7e,0xb3,0x2a,0x6f,0xf5,0x42,0x7e,0xb3,0x2a,0x70,0xf5,0x43, +0x75,0x44,0x28,0x7e,0xd3,0x28,0x84,0xe4,0x7a,0xb3,0x31,0xcf,0x7a,0xb3,0x31,0xcb, +0x7a,0xb3,0x31,0xcc,0x7e,0x8, 0x31,0xd0,0x7e,0x34,0x0, 0x1e,0x12,0x20,0xe8,0x7e, +0x8, 0x31,0xf0,0x7e,0x34,0x0, 0x3c,0x12,0x20,0xe8,0xbe,0xd0,0x2, 0x50,0x3, 0x2, +0xb2,0x15,0x6c,0xcc,0x2, 0xb2,0xe, 0x12,0x97,0xd4,0xf5,0x24,0x9, 0xb3,0x26,0xfb, +0xf5,0x25,0x4c,0xcc,0x68,0x8, 0xa, 0x3c,0x9, 0xb3,0x31,0xd0,0x70,0xa, 0xa, 0x3c, +0xb, 0x34,0xa, 0x2c,0x19,0x72,0x31,0xd0,0x7c,0xbd,0x14,0xbc,0xbc,0x78,0x3, 0x2, +0xb2,0x15,0xa, 0x5c,0xb, 0x54,0xf5,0x2e,0x2, 0xb2,0x4, 0x7e,0x71,0x2e,0x12,0xb5, +0x9e,0x7a,0xa1,0x26,0x9, 0xb3,0x26,0xfb,0xf5,0x27,0xa, 0x2a,0xe5,0x24,0x12,0x44, +0x5b,0x7c,0xb7,0xf5,0x28,0xe5,0x27,0xa, 0x2b,0xe5,0x25,0x12,0x44,0x5b,0x7c,0xb7, +0xf5,0x29,0xe5,0x28,0xbe,0xb0,0x5, 0x40,0x3, 0x2, 0xb2,0x2, 0xe5,0x29,0xbe,0xb0, +0x5, 0x40,0x3, 0x2, 0xb2,0x2, 0x12,0xb2,0x18,0x12,0x94,0x83,0x7a,0xb3,0x31,0xce, +0x85,0x25,0x54,0x85,0x26,0x55,0x85,0x27,0x56,0x7e,0x8, 0x0, 0x31,0x7e,0x18,0x0, +0x33,0xe5,0x24,0x12,0xb3,0x37,0x75,0x3d,0x0, 0x6c,0xee,0x75,0x30,0x0, 0xe5,0x24, +0x7e,0x71,0x25,0x12,0x6d,0xcb,0x7a,0x35,0x35,0xe5,0x26,0x7e,0x71,0x27,0x12,0x6d, +0xcb,0x7a,0x35,0x37,0x7e,0x35,0x35,0xbe,0x35,0x37,0x8, 0x5, 0x7e,0x35,0x37,0x80, +0x3, 0x7e,0x35,0x35,0x7a,0x35,0x3b,0xe, 0x34,0x7a,0x35,0x39,0xe5,0x28,0xbe,0xb0, +0x1, 0x38,0x2e,0xe5,0x29,0xbe,0xb0,0x1, 0x38,0x27,0x7c,0xbf,0x30,0xe1,0x22,0xe5, +0x26,0x7e,0x71,0x25,0x12,0x6d,0xcb,0x7d,0x43,0xe5,0x24,0x7e,0x71,0x27,0x12,0x6d, +0xcb,0x2d,0x34,0xbe,0x35,0x39,0x18,0x3, 0x2, 0xb1,0x99,0x75,0x30,0x1, 0x2, 0xb1, +0x99,0xe5,0x28,0xbe,0xb0,0x1, 0x38,0xa, 0xe5,0x29,0xbe,0xb0,0x1, 0x38,0x3, 0x2, +0xb1,0x99,0xe5,0x28,0xbe,0xb0,0x5, 0x40,0x3, 0x2, 0xb1,0x99,0xe5,0x29,0xbe,0xb0, +0x5, 0x40,0x3, 0x2, 0xb1,0x99,0x7c,0xbf,0x20,0xe0,0x3, 0x2, 0xb1,0x99,0x6d,0x33, +0x7a,0x35,0x4d,0x75,0x4f,0x0, 0x7a,0x35,0x50,0x75,0x52,0x0, 0xc2,0x2, 0xc2,0x3, +0xe5,0x26,0xbe,0xb1,0x24,0x28,0x4, 0xe5,0x24,0x80,0x2, 0xe5,0x26,0xf5,0x2a,0xe5, +0x26,0xbe,0xb1,0x24,0x50,0x4, 0xe5,0x24,0x80,0x2, 0xe5,0x26,0xf5,0x2c,0xe5,0x27, +0xbe,0xb1,0x25,0x28,0x4, 0xe5,0x25,0x80,0x2, 0xe5,0x27,0xf5,0x2b,0xe5,0x27,0xbe, +0xb1,0x25,0x50,0x4, 0xe5,0x25,0x80,0x2, 0xe5,0x27,0xf5,0x2d,0xe5,0x2c,0xbe,0xb1, +0x2a,0x78,0x29,0xd2,0x2, 0xe5,0x2a,0x60,0x8, 0xe5,0x42,0x14,0xbe,0xb1,0x2a,0x78, +0x2, 0xd2,0x3, 0xe5,0x2a,0xbe,0xb0,0x0, 0x28,0x2, 0x15,0x2a,0xe5,0x42,0xa, 0x2b, +0x1b,0x24,0xe5,0x2c,0xa, 0x3b,0xbd,0x32,0x58,0x2, 0x5, 0x2c,0xe5,0x2d,0xbe,0xb1, +0x2b,0x78,0x29,0xd2,0x2, 0xe5,0x2b,0x60,0x8, 0xe5,0x43,0x14,0xbe,0xb1,0x2b,0x78, +0x2, 0xd2,0x3, 0xe5,0x2b,0xbe,0xb0,0x0, 0x28,0x2, 0x15,0x2b,0xe5,0x43,0xa, 0x2b, +0x1b,0x24,0xe5,0x2d,0xa, 0x3b,0xbd,0x32,0x58,0x2, 0x5, 0x2d,0x85,0x2a,0x3e,0x80, +0x5b,0x85,0x2b,0x3f,0x80,0x4d,0xe5,0x3e,0x7e,0x71,0x3f,0x12,0x6d,0xcb,0x7a,0x35, +0x40,0xe5,0x2a,0xbe,0xb1,0x3e,0x68,0x15,0xe5,0x2c,0xbe,0xb1,0x3e,0x68,0xe, 0xe5, +0x2b,0xbe,0xb1,0x3f,0x68,0x7, 0xe5,0x2d,0xbe,0xb1,0x3f,0x78,0xd, 0x7e,0x35,0x40, +0x2e,0x35,0x4d,0x7a,0x35,0x4d,0x5, 0x4f,0x80,0x17,0x5, 0x52,0x7e,0x35,0x40,0x2e, +0x35,0x50,0x7a,0x35,0x50,0x7e,0x35,0x33,0xbe,0x35,0x40,0x58,0x2, 0x5, 0x3d,0xb, +0xe0,0x5, 0x3f,0xe5,0x2d,0xbe,0xb1,0x3f,0x50,0xac,0x5, 0x3e,0xe5,0x2c,0xbe,0xb1, +0x3e,0x50,0x9e,0xe5,0x2c,0x7e,0x71,0x2b,0x12,0x6d,0xcb,0x7e,0x45,0x4d,0x9d,0x43, +0xe5,0x2a,0x7e,0x71,0x2d,0x12,0x6d,0xcb,0x9d,0x43,0xe5,0x2a,0x7e,0x71,0x2b,0x12, +0x6d,0xcb,0x9d,0x43,0xe5,0x2c,0x7e,0x71,0x2d,0x12,0x6d,0xcb,0x7d,0x23,0x7d,0x34, +0x9d,0x32,0x7a,0x35,0x4d,0x7e,0x35,0x37,0x2e,0x35,0x35,0x7a,0x35,0x39,0x30,0x2, +0x10,0x20,0x3, 0xd, 0x7e,0x35,0x4d,0x9e,0x35,0x39,0x7a,0x35,0x4d,0x15,0x4f,0x15, +0x4f,0xe5,0x4f,0xbe,0xb0,0x4, 0x28,0x6, 0xe5,0x4f,0x24,0xfc,0xf5,0x4f,0x7e,0x35, +0x4d,0xbe,0x34,0x0, 0x0, 0x58,0x5, 0x6d,0x33,0x7a,0x35,0x4d,0x75,0x44,0x28,0xe5, +0x42,0x14,0xbe,0xb1,0x24,0x68,0xd, 0xbe,0xb1,0x26,0x68,0x8, 0xe5,0x24,0x60,0x4, +0xe5,0x26,0x70,0x8, 0x12,0xb3,0x2f,0x28,0x3, 0x75,0x44,0x2c,0x7e,0x15,0x50,0x1a, +0x2, 0x1a,0x0, 0x7e,0x35,0x4d,0x1a,0x26,0x1a,0x24,0x2f,0x10,0xe5,0x44,0xa, 0x1b, +0x6d,0x0, 0x12,0x1e,0xeb,0x7f,0x71,0x7a,0x7d,0x45,0x7e,0x15,0x39,0x1a,0x2, 0x1a, +0x0, 0x7e,0x35,0x31,0x1a,0x26,0x1a,0x24,0x12,0x1e,0xeb,0xe5,0x52,0xa, 0xdb,0x6d, +0xcc,0xe5,0x4f,0xa, 0x1b,0x6d,0x0, 0x2f,0x6, 0x12,0x1e,0xeb,0x7a,0x1d,0x49,0xbf, +0x71,0x8, 0x3, 0x75,0x30,0x2, 0xc2,0x1, 0x20,0xc, 0xe, 0x12,0xb2,0x18,0x12,0xb2, +0x24,0x92,0x1, 0x20,0x1, 0x3, 0x75,0x30,0x0, 0xe5,0x30,0xbe,0xb0,0x0, 0x28,0x62, +0xe5,0x30,0xa, 0x3b,0x2e,0x34,0x31,0xca,0x7e,0x39,0xb0,0x4, 0x7a,0x39,0xb0,0xe5, +0x2e,0xa, 0x3b,0x9, 0xa3,0x31,0xd0,0x4c,0xaa,0x78,0xc, 0xa, 0x2c,0x9, 0xb2,0x31, +0xd0,0x19,0xb3,0x31,0xd0,0x80,0x3b,0xa, 0x2c,0x9, 0xb2,0x31,0xd0,0xf5,0x53,0xbc, +0xba,0x28,0x3, 0x7a,0xa1,0x53,0x75,0x2f,0x0, 0x80,0x22,0x9, 0x33,0x31,0xd0,0xe5, +0x2f,0xa, 0x2b,0x9, 0x22,0x31,0xd0,0xbc,0x23,0x68,0xa, 0xa, 0xc, 0x9, 0x30,0x31, +0xd0,0xbc,0x23,0x78,0x6, 0xe5,0x53,0x19,0xb2,0x31,0xd0,0x5, 0x2f,0xbe,0xd1,0x2f, +0x38,0xd9,0x5, 0x2e,0xbe,0xd1,0x2e,0x28,0x3, 0x2, 0xae,0xab,0xb, 0xc0,0xbc,0xdc, +0x28,0x3, 0x2, 0xae,0x77,0xda,0x3b,0x22,0xe5,0x24,0x7e,0x71,0x25,0x7e,0x61,0x26, +0x7e,0x51,0x27,0x22,0x12,0xb2,0x50,0x92,0x4, 0x30,0x4, 0xc, 0x7e,0xb3,0x32,0x2c, +0xbe,0xb0,0xfa,0x50,0x11,0x4, 0x80,0xa, 0x7e,0xb3,0x32,0x2c,0xbe,0xb0,0x0, 0x28, +0x5, 0x14,0x7a,0xb3,0x32,0x2c,0x7e,0xb3,0x32,0x2c,0x70,0x2, 0xc3,0x22,0xd3,0x22, +0xca,0x3b,0x7c,0x45,0x7c,0x6, 0x7c,0x57,0x7c,0x1b,0x7e,0x34,0x4, 0xfc,0x7e,0xb3, +0x26,0x83,0x7e,0xf3,0x2a,0x6e,0x7c,0x31,0x7c,0xe0,0x7c,0x25,0x7c,0xa4,0xbc,0x1, +0x50,0x4, 0x7c,0x30,0x7c,0xe1,0xbc,0x45,0x50,0x4, 0x7c,0x24,0x7c,0xa5,0xbe,0xb0, +0x1, 0x50,0x2, 0x61,0x15,0x7e,0x90,0x2, 0xac,0x9f,0x7e,0x50,0x2, 0xac,0x53,0x2d, +0x24,0x2d,0x23,0xb, 0x28,0x20,0x7e,0x10,0x2, 0xac,0x1e,0x2d,0x4, 0x2d,0x3, 0xb, +0x8, 0x40,0xa, 0x3, 0xb, 0x4, 0x7c,0x31,0x80,0x28,0x7e,0xd0,0x2, 0xac,0xdf,0x7e, +0x10,0x2, 0xac,0x13,0x2d,0x6, 0x12,0xb3,0x19,0x58,0x15,0xad,0xf4,0xbd,0xdf,0x58, +0xf, 0xbe,0x24,0x0, 0x0, 0x8, 0x9, 0xbe,0x44,0x0, 0x0, 0x8, 0x3, 0xc3,0x80,0x46, +0xb, 0x30,0xbc,0xe3,0x38,0xd4,0x7e,0x50,0x2, 0xac,0x52,0x2d,0x23,0xb, 0x28,0x20, +0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x43,0xb, 0x48,0x40,0xa, 0x12,0xb, 0x14,0x80,0x21, +0x7e,0x10,0x2, 0xac,0x13,0x12,0xb3,0x19,0x58,0x15,0xad,0xf4,0xbd,0xdf,0x58,0xf, +0xbe,0x24,0x0, 0x0, 0x8, 0x9, 0xbe,0x44,0x0, 0x0, 0x8, 0x3, 0xc3,0x80,0x7, 0xb, +0x30,0xbc,0xa3,0x38,0xdb,0xd3,0xda,0x3b,0x22,0x2d,0x3, 0xb, 0x8, 0x0, 0x7e,0xf4, +0x0, 0x9, 0x7d,0xb2,0xad,0xbf,0x7e,0xd4,0x0, 0xa, 0xad,0xd0,0xbd,0xdb,0x22,0x7e, +0x73,0x31,0xce,0xbe,0x70,0x5, 0x22,0xca,0xf8,0x7c,0xfb,0x7f,0x61,0x7f,0x50,0x7e, +0x34,0x22,0xd7,0x7e,0x24,0x0, 0xff,0x7e,0x14,0x1f,0x70,0x74,0x2a,0x12,0x1f,0xad, +0x7e,0x48,0x1f,0x70,0x12,0xb3,0xc6,0x92,0xc, 0x7c,0xbf,0x7e,0x71,0x54,0x12,0x6d, +0xcb,0x7d,0x43,0xe5,0x55,0x7e,0x71,0x56,0x12,0x6d,0xcb,0x2d,0x34,0xe, 0x34,0x7f, +0x4, 0x7e,0x50,0x7, 0xb, 0xa, 0x50,0xbd,0x53,0x58,0x10,0x69,0x30,0x0, 0x2, 0x1b, +0x5a,0x30,0x69,0x30,0x0, 0x4, 0x1b,0x6a,0x30,0x80,0x8, 0x2e,0x14,0x0, 0x6, 0x1b, +0x50,0x78,0xe1,0x12,0xb3,0x2f,0x28,0x2b,0xb, 0x5a,0x20,0x7e,0x34,0x0, 0xd, 0xad, +0x32,0x7e,0x24,0x0, 0x10,0x12,0x1e,0xb9,0x1b,0x5a,0x30,0xb, 0x6a,0x30,0x1a,0x26, +0x1a,0x24,0x7e,0x14,0x0, 0xd, 0x12,0x1e,0xfc,0x7e,0x8, 0x0, 0x10,0x12,0x1f,0x58, +0x1b,0x6a,0x30,0xda,0xf8,0x22,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x2, 0x58,0x8, 0xa, +0x12,0x97,0x99,0xbe,0xb0,0x8, 0x48,0x2, 0xd3,0x22,0xc3,0x22,0x6c,0xaa,0x12,0x97, +0xea,0x29,0x81,0x0, 0x5, 0x7c,0x98,0x5e,0x90,0x1, 0x3e,0x90,0x7f,0x1, 0x2e,0x14, +0x0, 0x5, 0x7c,0xb8,0x54,0xfd,0x4c,0xb9,0x7a,0xb, 0xb0,0x29,0xb1,0x0, 0x5, 0x30, +0xe0,0x16,0x30,0xe2,0x13,0xc4,0x23,0x54,0x1f,0xb4,0x1, 0xc, 0x7f,0x1, 0xb, 0x16, +0x7e,0xb, 0xb0,0x1e,0xb0,0x7a,0xb, 0xb0,0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xbf,0x22, +0xca,0x3b,0x7f,0x40,0x7e,0xe3,0x28,0x84,0x6c,0xdd,0x7e,0xc0,0x1, 0x80,0x1a,0xa, +0x3d,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0x60,0xa, 0x2c,0x7f,0x4, 0x2d,0x12,0x7e,0xb, +0x70,0xbc,0x76,0x40,0x2, 0x7c,0xdc,0xb, 0xc0,0xbc,0xec,0x38,0xe2,0xa, 0x3d,0x2d, +0x39,0x7d,0x28,0x7e,0x1b,0xd0,0x6c,0xff,0x7e,0xc0,0x1, 0xa1,0x85,0x75,0x2d,0x0, +0x6d,0x33,0x7a,0x35,0x2e,0x7a,0x35,0x25,0x7a,0x35,0x27,0x7e,0x18,0x1f,0x70,0x7a, +0x1d,0x29,0x74,0xff,0x7e,0x34,0x1f,0x71,0x7e,0x24,0x0, 0x0, 0x7a,0x1b,0xb0,0x7e, +0x1d,0x29,0x7a,0x1b,0xb0,0xe4,0x7e,0x1d,0x29,0x39,0xb1,0x0, 0x3, 0x7e,0x1d,0x29, +0x39,0xb1,0x0, 0x2, 0x7e,0x1d,0x29,0x12,0x96,0xb3,0x44,0x1, 0x7a,0x1b,0xb0,0x75, +0x24,0x0, 0x80,0x6c,0x12,0xb5,0x9b,0x9, 0x93,0x26,0xfb,0xe5,0x24,0x12,0x44,0x62, +0xbc,0xbc,0x78,0x5a,0x5, 0x2d,0xa, 0x3a,0x2e,0x35,0x25,0x7a,0x35,0x25,0xa, 0x39, +0x2e,0x35,0x27,0x7a,0x35,0x27,0x12,0x6d,0xc7,0xbe,0x35,0x2e,0x8, 0x6, 0x12,0x6d, +0xc7,0x7a,0x35,0x2e,0x7e,0x1d,0x29,0x7e,0x1b,0xb0,0xbc,0xba,0x28,0x3, 0x7a,0x1b, +0xa0,0x7e,0x1d,0x29,0x29,0xb1,0x0, 0x2, 0xbc,0xba,0x50,0x4, 0x39,0xa1,0x0, 0x2, +0x7e,0x1d,0x29,0x29,0xb1,0x0, 0x1, 0xbc,0xb9,0x28,0x4, 0x39,0x91,0x0, 0x1, 0x7e, +0x1d,0x29,0x29,0xb1,0x0, 0x3, 0xbc,0xb9,0x50,0x4, 0x39,0x91,0x0, 0x3, 0x5, 0x24, +0xbe,0xe1,0x24,0x38,0x8f,0xe5,0x2d,0xbe,0xb0,0x0, 0x28,0x67,0x7e,0xd, 0x29,0x12, +0x94,0xd7,0xe5,0x2d,0xa, 0x2b,0x7e,0x15,0x25,0x8d,0x12,0x7a,0x15,0x25,0x7e,0x35, +0x27,0x8d,0x32,0x7a,0x35,0x27,0x7e,0x55,0x25,0x12,0xb5,0x93,0x19,0xa3,0x31,0xf0, +0x7e,0x55,0x27,0x12,0xb5,0x93,0x19,0xa3,0x31,0xf1,0x7e,0x37,0x28,0x8a,0xbe,0x35, +0x2e,0x78,0xe, 0x7e,0x35,0x25,0x7a,0x73,0x28,0x8c,0x7e,0x35,0x27,0x7a,0x73,0x28, +0x8d,0x7e,0x37,0x31,0xee,0x4d,0x33,0x68,0x18,0x7e,0x55,0x25,0x7e,0x35,0x27,0x12, +0x6d,0xcb,0x7e,0x25,0x2e,0x7e,0x70,0x2, 0xac,0x7f,0x2e,0x37,0x31,0xee,0x1b,0x38, +0x20,0xb, 0xf0,0xb, 0xc0,0xbc,0xdc,0x40,0x2, 0x81,0x5d,0x12,0xb3,0xdc,0x7c,0xbf, +0xda,0x3b,0x22,0x7c,0xab,0x7e,0x70,0x2, 0xac,0x7f,0x22,0x7e,0x71,0x24,0x74,0x2, +0xac,0x7b,0x9, 0xa3,0x26,0xfa,0x22,0x7e,0x73,0x2a,0x71,0xa, 0x17,0x2e,0x14,0x0, +0x3, 0x7e,0xa3,0x2a,0x6e,0xa, 0x3a,0xad,0x13,0x7d,0x21,0x6c,0x33,0x80,0x20,0xa, +0x3, 0x2d,0x2, 0x3e,0x4, 0x7e,0x7f,0x39,0xda,0x2d,0xf0,0xb, 0x7a,0x0, 0x7e,0x90, +0x2, 0xac,0x93,0x49,0xf4,0x13,0x8e,0x9d,0xf, 0x59,0x4, 0x25,0xb6,0xb, 0x30,0xbc, +0xa3,0x38,0xdc,0x7a,0x35,0x34,0x7e,0xf, 0x38,0x41,0x7e,0x18,0x25,0xb6,0x2, 0x5d, +0xf1,0x6c,0xaa,0x80,0x1c,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x13,0xc6,0x49,0x32, +0x13,0x8e,0xbd,0x31,0x28,0x9, 0x2e,0x24,0x13,0x8e,0x9d,0x31,0x1b,0x28,0x30,0xb, +0xa0,0x7e,0xb3,0x2a,0x6e,0xbc,0xba,0x38,0xdc,0x22,0xca,0x78,0xa9,0x31,0xe5,0x6, +0xa9,0xd5,0xea,0xa9,0xc5,0xea,0xa9,0x30,0xe5,0x19,0xa9,0xd0,0x9e,0xa9,0xd4,0x9e, +0x5, 0x5e,0x7e,0x73,0x3a,0x7, 0xbe,0x71,0x5e,0x38,0x2, 0xd2,0x1c,0xa9,0xd0,0x9e, +0xa9,0xd7,0x9e,0xa9,0x34,0xe5,0x5, 0xa9,0xc4,0xcd,0xc2,0x95,0xa9,0x32,0xe5,0x3, +0xa9,0xc2,0xcd,0xa9,0x33,0xe5,0x3, 0xa9,0xc3,0xcd,0xa9,0x37,0xe5,0x3, 0xa9,0xc7, +0xcd,0xa9,0x36,0xe5,0x3, 0xa9,0xc6,0xcd,0xda,0x78,0x32,0xc2,0x9a,0xa9,0xd4,0xa6, +0xc2,0x88,0xd2,0xa8,0x22,0x7e,0x14,0xd7,0xe8,0x7e,0x4, 0x0, 0xff,0x7e,0x34,0x47, +0x52,0x7e,0x24,0x55,0x50,0x79,0x30,0x0, 0x2, 0x1b,0xa, 0x20,0x7e,0x34,0x45,0x20, +0x7e,0x24,0x41,0x44,0x79,0x30,0x0, 0x6, 0x79,0x20,0x0, 0x4, 0x7e,0x34,0x99,0x33, +0x7e,0x24,0x66,0xcc,0x79,0x30,0x0, 0xa, 0x79,0x20,0x0, 0x8, 0x7e,0x34,0x41,0x47, +0x7e,0x24,0x46,0x4c,0x79,0x30,0x0, 0xe, 0x79,0x20,0x0, 0xc, 0x22,0xa9,0xc4,0xca, +0xa9,0xc5,0xca,0xbe,0xb0,0x8, 0x50,0x3, 0x12,0x4f,0xdc,0xa9,0xd0,0xce,0xa9,0xc0, +0xc9,0xd2,0x2, 0x12,0x2f,0xde,0xa9,0xc2,0xea,0x75,0xc1,0x6, 0x75,0xc2,0xc, 0xd2, +0x0, 0x12,0xb6,0xee,0xa9,0xc1,0xc4,0xa9,0xd2,0xc4,0xa9,0xc2,0xe1,0x22,0xa2,0x0, +0xa9,0x97,0xc1,0xa2,0x0, 0xa9,0x97,0xc2,0x22,0xa9,0xd0,0xce,0xa2,0x0, 0xa9,0x95, +0xc9,0x22,0xca,0xf8,0xa2,0xaf,0xe4,0x33,0x7c,0xfb,0xd2,0x0, 0x12,0xb6,0xf9,0xa9, +0xd0,0xcb,0xc2,0xaf,0xa9,0xd0,0x9e,0x75,0x9d,0x0, 0xa9,0xd0,0x9e,0x75,0x9c,0x20, +0xa9,0xd0,0x9e,0xa9,0xd4,0x9e,0xa9,0xd0,0xcd,0x74,0x41,0x12,0x2f,0x39,0xa9,0xd0, +0x9e,0xa9,0xd7,0x9e,0x2e,0xf0,0xff,0x92,0xaf,0xda,0xf8,0x22,0xa9,0xd5,0xcb,0x74, +0x10,0x12,0x0, 0x66,0x7c,0x7b,0x12,0x28,0xb3,0x30,0xe7,0x3, 0x7e,0x70,0x2, 0xd2, +0xcd,0x7e,0x24,0x0, 0xef,0x7e,0xf, 0x39,0xc1,0x79,0x20,0x0, 0x84,0x7e,0x24,0x20, +0x5f,0x7e,0xf, 0x39,0xc1,0x79,0x20,0x0, 0x82,0x7e,0x24,0x41,0x0, 0x7e,0xf, 0x39, +0xc1,0x79,0x20,0x0, 0x90,0x7c,0x67,0x6c,0x77,0x2e,0x34,0x0, 0xc1,0x7e,0xf, 0x39, +0xc1,0x79,0x30,0x0, 0x86,0x7e,0x34,0x29,0x90,0x7e,0xf, 0x39,0xc1,0x79,0x30,0x0, +0x8a,0x7e,0x34,0x6a,0xd1,0x7e,0xf, 0x39,0xc1,0x79,0x30,0x0, 0x8c,0x7e,0x34,0x3, +0x61,0x7e,0xf, 0x39,0xc1,0x79,0x30,0x0, 0x8e,0x22,0xa9,0xc6,0xeb,0xa9,0xd6,0xac, +0xa9,0xd6,0xec,0xd2,0x86,0xa9,0xc2,0xeb,0xa9,0xd2,0xac,0xa9,0xd2,0xec,0xd2,0x82, +0x22,0x75,0x9a,0x2f,0xa9,0xd1,0x99,0xd2,0x9c,0xa9,0xd6,0xdf,0x22,0xc2,0x8e,0x43, +0x89,0x20,0x75,0x8d,0x1, 0x75,0x8b,0x0, 0xd2,0x8e,0xd2,0xab,0x22,0x75,0xb7,0x0, +0x75,0xb8,0x0, 0x75,0xf7,0x0, 0x75,0xf8,0x0, 0xa9,0xd0,0xb7,0xd2,0xb8,0xa9,0xd5, +0xb7,0xd2,0xbd,0xa9,0xd0,0xf7,0xd2,0xf8,0xa9,0xc1,0xb7,0xc2,0xb9,0xa9,0xc3,0xb7, +0xc2,0xbb,0xa9,0xc6,0xb7,0xc2,0xbe,0x22,0x75,0xe7,0x6b,0x2, 0xb8,0xe, 0xe4,0x7e, +0x34,0xd7,0xfc,0x12,0x77,0x15,0x7e,0x34,0xd7,0xfd,0x7a,0x1b,0xb0,0x75,0xe9,0xff, +0x22,0xa9,0xd0,0x99,0xa9,0xc6,0xdf,0x22,0x7e,0x37,0x3a,0x5, 0xb, 0x34,0x7a,0x37, +0x3a,0x5, 0xbe,0x34,0xff,0x0, 0x40,0x8, 0x7e,0x34,0xff,0x0, 0x7a,0x37,0x3a,0x5, +0x22,0xd2,0xc9,0x75,0xf2,0x30,0x75,0xf3,0x80,0x75,0xf4,0xc, 0x75,0xf5,0x1, 0x6c, +0xaa,0xe5,0xf5,0x54,0x80,0xb4,0x80,0xf9,0xe5,0xf6,0x12,0x5d,0xe7,0xb, 0xa0,0xbe, +0xa0,0xd, 0x40,0xed,0xc2,0xc9,0x22,0x2, 0xb8,0x6a,0x6d,0x11,0x12,0x57,0xe5,0x12, +0xb9,0x19,0x7d,0x3, 0x7e,0x78,0x13,0x8e,0x6c,0x99,0x80,0x17,0x12,0xb8,0xb9,0x7e, +0x50,0x2, 0xac,0x59,0x7f,0x57,0x2d,0xb2,0xb, 0x5a,0x30,0x9d,0x3d,0x59,0x32,0x13, +0xc6,0xb, 0x90,0xbc,0xa9,0x38,0xe5,0x6c,0x99,0x80,0x17,0x12,0xb8,0xb9,0x7e,0x70, +0x2, 0xac,0x79,0x2d,0x3f,0x7d,0x2e,0x12,0xb9,0x24,0xbd,0x1b,0x58,0x2, 0x7d,0x1b, +0xb, 0x90,0xbc,0xa9,0x38,0xe5,0x7d,0x31,0x22,0xa, 0xd9,0x2d,0xd0,0x3e,0xd4,0x7e, +0x1f,0x39,0xda,0x2d,0x3d,0xb, 0x1a,0xd0,0x22,0x12,0x8f,0xce,0x7e,0x34,0xd, 0xc8, +0x7e,0xb3,0x2a,0x6d,0x12,0xb8,0xe5,0x12,0xb8,0x67,0x7a,0x37,0x39,0xd7,0x74,0x1, +0x7a,0xb3,0x16,0x91,0x22,0x7a,0xb3,0x24,0xf2,0x7e,0x53,0x2a,0x6e,0x7a,0x53,0x24, +0xf3,0x7a,0x37,0x24,0xfa,0xe4,0x7a,0xb3,0x24,0xf4,0x7a,0xb3,0x24,0xf5,0x7e,0x34, +0x40,0x0, 0x7a,0x37,0x24,0xf6,0x7e,0x34,0x0, 0x20,0x12,0xb9,0x10,0x2, 0xd, 0x7, +0x7a,0x37,0x24,0xfc,0x7e,0x8, 0x24,0xf2,0x22,0xa, 0x2b,0x2e,0x24,0x0, 0x3, 0xa, +0x3a,0xad,0x32,0x22,0xb, 0x1a,0xc0,0x7d,0x3d,0x9d,0x3c,0x12,0x21,0xa, 0x7d,0xb3, +0x22,0xca,0x79,0x7c,0xfb,0x7e,0x8, 0x1f,0x34,0x12,0xb9,0xa7,0x7e,0xa3,0x2a,0x73, +0x7e,0x63,0x2a,0x74,0x6c,0xee,0x80,0x1e,0xa, 0x2e,0x9, 0x72,0x2a,0xdc,0xbe,0x70, +0x1c,0x50,0x11,0xa, 0x27,0x12,0x67,0x43,0x7c,0x7b,0x7e,0xb3,0x2a,0xfb,0xa, 0x27, +0x19,0xb2,0x1f,0x34,0xb, 0xe0,0xbc,0x6e,0x38,0xde,0x6c,0xee,0x80,0x17,0xa, 0x3e, +0x9, 0x73,0x2a,0xb9,0xbe,0x70,0x23,0x50,0xa, 0x7e,0x63,0x2a,0xfb,0xa, 0x27,0x19, +0x62,0x1f,0x50,0xb, 0xe0,0xbc,0xae,0x38,0xe5,0x6c,0xee,0x7e,0x30,0xe, 0xac,0x3e, +0x2e,0x14,0x1f,0x34,0x6d,0x0, 0x7c,0xbf,0x7c,0x7e,0x12,0x11,0xf8,0xb, 0xe0,0xbe, +0xe0,0x5, 0x40,0xe7,0xda,0x79,0x22,0x7e,0x34,0x0, 0x46,0x74,0x3f,0x2, 0x20,0xe8, +0xca,0xd8,0xca,0x79,0x7c,0xf7,0x7f,0x70,0x12,0xba,0x42,0x7c,0xeb,0x6c,0xdd,0x80, +0x20,0x74,0x2, 0xac,0xbd,0x7f,0x67,0x2d,0xd5,0xb, 0x6a,0x30,0x6d,0x22,0x74,0x4, +0x2f,0x11,0x14,0x78,0xfb,0xa, 0x1e,0x6d,0x0, 0x12,0x1f,0x7, 0x1b,0x6a,0x30,0xb, +0xd0,0xbc,0xfd,0x38,0xdc,0xda,0x79,0xda,0xd8,0x22,0xca,0x79,0x7f,0x51,0x7f,0x40, +0x7e,0xa3,0x2a,0x74,0xa, 0x3a,0x7e,0xa3,0x2a,0x73,0xa, 0x7a,0x2d,0x73,0x7e,0xd, +0x29,0x7c,0x7f,0x12,0xb9,0xb0,0xa, 0x3f,0x3e,0x34,0xca,0x39,0x7e,0x1d,0x29,0x7f, +0x4, 0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xb3,0x2b,0x1, 0xb4,0x1, 0x22,0x6c,0xaa,0x80, +0x1a,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x5, 0x2d,0x13,0xb, 0xa, 0x20,0x7f,0x4, 0x2d, +0x13,0xb, 0xa, 0x30,0x9d,0x32,0x1b,0xa, 0x30,0xb, 0xa0,0xbc,0xfa,0x38,0xe2,0xda, +0x79,0x22,0x7c,0x7b,0xa5,0xbf,0x0, 0x3, 0x74,0x10,0x22,0xbe,0x70,0x4, 0x38,0x4, +0x6c,0xaa,0x80,0x21,0xbe,0x70,0x8, 0x38,0x5, 0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x70, +0x10,0x38,0x5, 0x7e,0xa0,0x2, 0x80,0xd, 0xbe,0x70,0x20,0x38,0x5, 0x7e,0xa0,0x3, +0x80,0x3, 0x7e,0xa0,0x4, 0xa, 0x47,0x3e,0x44,0x3e,0x44,0x3e,0x44,0x7c,0xba,0x60, +0x5, 0x1e,0x44,0x14,0x78,0xfb,0x7c,0xb9,0x22,0x7c,0xab,0x9f,0x11,0x30,0x0, 0x22, +0x6c,0x99,0x80,0x1a,0xa, 0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0x7e,0x78,0x0, +0x1, 0x60,0x5, 0x2f,0x77,0x14,0x78,0xfb,0x4d,0x3f,0x4d,0x2e,0xb, 0x90,0xbc,0xa9, +0x38,0xe2,0x22,0xca,0xf8,0x7e,0xf0,0x19,0x7e,0x8, 0x1f,0x34,0x12,0xbb,0x3b,0x7e, +0x8, 0x1f,0x3c,0x12,0xbb,0x43,0xd2,0x0, 0x7e,0x8, 0x2a,0xdc,0x74,0x19,0x12,0xba, +0x89,0x7e,0x8, 0x1f,0x34,0x7a,0xf, 0x1f,0x58,0x7f,0x1, 0x7a,0x17,0x1f,0x5c,0x7d, +0x32,0x7a,0x37,0x1f,0x5e,0x7e,0x18,0x1f,0x3c,0x7a,0x1f,0x1f,0x64,0x6c,0x77,0x80, +0xe, 0x12,0xbb,0x8b,0x50,0x7, 0x12,0xbb,0x82,0x19,0x51,0x1f,0x3c,0xb, 0x70,0xbc, +0xf7,0x38,0xee,0x12,0xbb,0x28,0xe4,0x12,0xbb,0x30,0xe4,0x12,0xc, 0x9b,0x6d,0x33, +0x7a,0x37,0x1f,0x5c,0x7a,0x37,0x1f,0x5e,0x12,0xbb,0x28,0x74,0x1, 0x12,0xbb,0x30, +0x74,0x1, 0x12,0xc, 0x9b,0xda,0xf8,0x22,0xa9,0xc6,0xea,0x7e,0x8, 0x1f,0x58,0x22, +0x12,0xc, 0x9b,0xa9,0xd6,0xea,0x7e,0x8, 0x1f,0x58,0x22,0x7e,0x34,0x0, 0x8, 0xe4, +0x2, 0x20,0xe8,0x7e,0x34,0x0, 0x1c,0x74,0x3f,0x2, 0x20,0xe8,0x7e,0x8, 0x1f,0x34, +0x12,0xbb,0x43,0x6c,0x77,0x80,0xe, 0x12,0xbb,0x8b,0x50,0x7, 0x12,0xbb,0x82,0x19, +0x51,0x1f,0x34,0xb, 0x70,0x7e,0x53,0x2a,0x6e,0xbc,0x57,0x38,0xea,0xa9,0xc6,0xea, +0x7e,0x8, 0x1f,0x34,0xe4,0x12,0x11,0x38,0xa9,0xd6,0xea,0x7e,0x8, 0x1f,0x34,0x2, +0x11,0x38,0xa, 0x27,0x9, 0x52,0x2b,0x44,0xa, 0x16,0x22,0xa, 0x27,0x9, 0x62,0x2a, +0xdc,0xbe,0x60,0x1c,0x22,0x7e,0x27,0x28,0xa3,0x6d,0x11,0x9d,0x12,0x6c,0xaa,0x80, +0x64,0x30,0x5, 0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x5, 0xf8,0x49,0x4, 0x4, +0x0, 0xbd,0x2, 0x8, 0x11,0x7e,0xb3,0x25,0xf6,0xb4,0x1, 0x16,0x7d,0xf2,0x2d,0xf3, +0x59,0xf4,0x5, 0xf8,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59,0x4, +0x5, 0xf8,0x30,0x7, 0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x6, 0x76,0x49,0x4, +0x4, 0x7e,0xbd,0x2, 0x8, 0x11,0x7e,0xb3,0x25,0xf6,0xb4,0x1, 0x16,0x7d,0xf2,0x2d, +0xf3,0x59,0xf4,0x6, 0x76,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59, +0x4, 0x6, 0x76,0xb, 0xa0,0x7e,0xb3,0x2a,0x74,0xa, 0xb, 0x7e,0xb3,0x2a,0x73,0xa, +0x4b,0x2d,0x40,0xa, 0xa, 0xbd,0x4, 0x48,0x88,0x22,0xe4,0x6c,0x33,0xa, 0x33,0x19, +0xb3,0x27,0x72,0xb, 0x30,0xa5,0xbb,0x4, 0xf4,0xe4,0x7a,0xb3,0x28,0x84,0x7a,0xb3, +0x28,0x85,0x6d,0x33,0x7a,0x37,0x28,0x86,0x7a,0x37,0x28,0x88,0x7a,0x37,0x28,0x8a, +0x7a,0x37,0x28,0x8e,0x7e,0xd4,0x1f,0x36,0x5e,0xd4,0xff,0xfe,0x6d,0xcc,0x7e,0x1f, +0x13,0x8a,0x7a,0x37,0x1f,0x76,0x7d,0x3d,0x7a,0x37,0x1f,0x7a,0x7e,0x34,0x15,0x9e, +0x7a,0x37,0x1f,0x78,0x7e,0x73,0x2a,0x6d,0x7a,0x73,0x1f,0x73,0x7e,0x73,0x2a,0x6e, +0x7a,0x73,0x1f,0x72,0x7e,0x37,0x2a,0x5c,0x7a,0x37,0x1f,0x7c,0x7e,0x37,0x2a,0x5e, +0x7a,0x37,0x1f,0x7e,0x7e,0x37,0x2a,0x60,0x7a,0x37,0x1f,0x80,0x74,0x1e,0x7a,0xb3, +0x1f,0x74,0x7e,0x73,0x3, 0xfe,0x7a,0x73,0x1f,0x75,0x7e,0x8, 0x1f,0x72,0x7e,0x18, +0x1f,0x82,0x12,0x8, 0x0, 0x7e,0x73,0x1f,0x82,0x7a,0x73,0x28,0x84,0x7e,0x73,0x1f, +0x83,0x7a,0x73,0x28,0x85,0x7e,0x37,0x1f,0x84,0x7a,0x37,0x28,0x86,0x7e,0x37,0x1f, +0x86,0x7a,0x37,0x28,0x88,0x7e,0x37,0x1f,0x8c,0x7a,0x37,0x28,0x8a,0x7e,0x37,0x1f, +0x8e,0x7d,0x23,0x7a,0x53,0x28,0x8c,0xa, 0x36,0x7a,0x73,0x28,0x8d,0x7e,0x37,0x1f, +0x88,0x7a,0x37,0x28,0x8e,0x7e,0x37,0x1f,0x8a,0x7d,0x23,0x7a,0x53,0x28,0x90,0xa, +0x36,0x7a,0x73,0x28,0x91,0x6c,0x33,0x80,0x1d,0x7c,0xb3,0x12,0x76,0xfb,0x74,0x2, +0xac,0xb3,0x49,0x45,0x15,0x9e,0xa, 0x38,0x7c,0x27,0x19,0x25,0x26,0xfa,0x7c,0x29, +0x19,0x25,0x26,0xfb,0xb, 0x30,0x7e,0x23,0x28,0x84,0xbc,0x23,0x38,0xdb,0x6c,0x33, +0x80,0x1b,0x74,0x2, 0xac,0xb3,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0x40,0xa, 0x38,0x7c, +0x27,0x19,0x25,0x27,0x36,0x7c,0x29,0x19,0x25,0x27,0x37,0xb, 0x30,0x7e,0x23,0x28, +0x85,0xbc,0x23,0x38,0xdd,0x22,0x7c,0x7b,0xa, 0x57,0x9e,0x54,0x0, 0x20,0xe, 0x54, +0xe, 0x54,0xe, 0x54,0xe, 0x54,0x7c,0xab,0x7c,0x67,0x5e,0x60,0xf0,0xa5,0xbe,0x20, +0x1d,0x7c,0xb7,0x54,0xf, 0x7e,0x24,0x0, 0x1, 0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb, +0x7e,0x73,0x39,0xfc,0xa, 0x47,0x5d,0x42,0x7e,0x73,0x38,0x33,0x80,0x36,0xa5,0xbe, +0x30,0x18,0x12,0xbd,0xb9,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7e,0x53,0x39,0xfd, +0xa, 0x45,0x5d,0x43,0x7e,0x73,0x38,0x34,0x80,0x1a,0x12,0xbd,0xb9,0x60,0x5, 0x3e, +0x34,0x14,0x78,0xfb,0xa, 0x2a,0x9, 0xb2,0x39,0xfc,0xa, 0x4b,0x5d,0x43,0xa, 0x5a, +0x9, 0x75,0x38,0x35,0xa, 0x57,0x5d,0x54,0x22,0x7c,0xb7,0x54,0xf, 0x7e,0x34,0x0, +0x1, 0x22,0x7e,0xb3,0x2f,0x80,0xb4,0x4, 0x2, 0xd3,0x22,0xc3,0x22,0x7d,0xf2,0x7d, +0xe3,0x7e,0x8, 0x2f,0x80,0x7e,0x34,0x0, 0x28,0xe4,0x12,0x20,0xe8,0x7e,0x8, 0x2b, +0xbf,0x7e,0x34,0x3, 0xc0,0x12,0x20,0xe8,0x7a,0xb3,0x38,0x35,0x7e,0x34,0x13,0x88, +0x7a,0x37,0x2b,0xb7,0x7a,0xe7,0x2f,0x84,0x7a,0xf7,0x2f,0x86,0x7a,0xe7,0x2f,0x88, +0x7a,0xe7,0x2f,0x8c,0x7a,0xe7,0x2f,0x90,0x7a,0xe7,0x2f,0x94,0x7a,0xf7,0x2f,0x8a, +0x7a,0xf7,0x2f,0x8e,0x7a,0xf7,0x2f,0x92,0x7a,0xf7,0x2f,0x96,0x7a,0xe7,0x2b,0xbb, +0x7a,0xf7,0x2b,0xbd,0x7a,0xb3,0x2f,0xa8,0x74,0x2, 0x7a,0xb3,0x2f,0x7f,0x22,0x74, +0xfe,0x7a,0xb3,0x38,0x35,0xe4,0x7a,0xb3,0x2f,0x80,0x22,0xca,0x3b,0xf5,0x2a,0x7f, +0x31,0x7a,0xd, 0x26,0xe4,0x7a,0xb3,0x22,0xf6,0x7a,0xb3,0x22,0xf7,0x7a,0xb3,0x22, +0xf8,0x7e,0x34,0x3, 0xe8,0x7a,0x37,0x22,0xfd,0x74,0x3c,0x7a,0xb3,0x22,0xf5,0x75, +0x2f,0x46,0x75,0x2b,0x0, 0x2, 0xc0,0x38,0x12,0xc0,0x74,0x28,0x1e,0x7e,0x34,0x0, +0x44,0xca,0x39,0x7e,0x71,0x2b,0x74,0x44,0xac,0x7b,0x2e,0x34,0x14,0x6, 0x7e,0x24, +0x0, 0xff,0x7e,0x8, 0x22,0xff,0x12,0x20,0xc3,0x1b,0xfd,0x6d,0x33,0x7a,0x37,0x22, +0xf9,0x7a,0x35,0x30,0x7a,0x37,0x22,0xfb,0x7a,0x35,0x32,0x7a,0x35,0x34,0x7e,0x34, +0x22,0xff,0x7a,0x35,0x36,0x7e,0x34,0x23,0x1f,0x7a,0x35,0x38,0x75,0x2c,0x0, 0x80, +0x59,0xe5,0x2c,0xa, 0x3b,0x7e,0xd, 0x26,0x12,0xc6,0xea,0x2e,0x35,0x36,0x12,0x96, +0xa1,0x7d,0xd3,0x7e,0xc7,0x22,0xfb,0xbd,0xcd,0x58,0x4, 0x7a,0xd7,0x22,0xfb,0xe5, +0x2c,0xa, 0x3b,0x7f,0x3, 0x12,0xc6,0xea,0x2e,0x35,0x38,0x12,0x96,0xa1,0x7d,0xc3, +0x7e,0x35,0x32,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x32,0x7e,0x37,0x22,0xf9,0x2d,0x3d, +0x7a,0x37,0x22,0xf9,0x7d,0x3c,0x2e,0x35,0x30,0x7a,0x35,0x30,0x2d,0xcd,0x7e,0x35, +0x34,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x34,0x5, 0x2c,0xe5,0x2a,0xbe,0xb1,0x2c,0x38, +0xa0,0xe5,0x2a,0xb4,0xa, 0x2d,0x7e,0x37,0x22,0xfb,0xbe,0x34,0x0, 0x40,0x48,0xc, +0x7e,0x25,0x32,0xbe,0x24,0x0, 0x40,0x48,0x3, 0x2, 0xc0,0x36,0xbe,0x34,0x0, 0x60, +0x8, 0x3, 0x2, 0xc0,0x36,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x60,0x8, 0x3, 0x2, 0xc0, +0x36,0x80,0x2b,0x7e,0x37,0x22,0xfb,0xbe,0x34,0x0, 0x20,0x8, 0xc, 0x7e,0x25,0x32, +0xbe,0x24,0x0, 0x20,0x8, 0x3, 0x2, 0xc0,0x36,0xbe,0x34,0x0, 0x30,0x8, 0x3, 0x2, +0xc0,0x36,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x30,0x8, 0x3, 0x2, 0xc0,0x36,0x7e,0xa3, +0x39,0x42,0x74,0xc, 0xa4,0xbe,0x57,0x22,0xf9,0x58,0x3, 0x2, 0xc0,0x36,0x7e,0xa3, +0x39,0x43,0x74,0xc, 0xa4,0xbe,0x55,0x30,0x58,0x3, 0x2, 0xc0,0x36,0x7e,0x15,0x36, +0x6d,0x0, 0x7e,0x1d,0x26,0xe5,0x2a,0x12,0xc0,0x7c,0x7a,0xb3,0x22,0xf4,0x7e,0x15, +0x38,0x6d,0x0, 0x7f,0x13,0xe5,0x2a,0x12,0xc0,0x7c,0xf5,0x2d,0x7e,0x73,0x22,0xf5, +0xbe,0x73,0x22,0xf4,0x28,0x3, 0x2, 0xc0,0x36,0xbe,0x71,0x2d,0x38,0x78,0xe5,0x2d, +0x7e,0x31,0x2d,0xac,0x3b,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x22,0xf4,0xac,0x77,0x1a, +0x26,0x1a,0x24,0x2f,0x10,0xe5,0x2d,0xa, 0x5b,0x6d,0x44,0x7e,0x33,0x22,0xf4,0xa, +0x13,0x6d,0x0, 0x2f,0x2, 0x12,0x1f,0x7, 0x7c,0xb7,0xf5,0x2e,0xe5,0x2f,0xbe,0xb1, +0x2e,0x38,0x43,0x7e,0x37,0x22,0xfb,0x2e,0x35,0x32,0x2e,0x35,0x34,0x7a,0x35,0x3a, +0xe5,0x2e,0xa, 0x2b,0x7e,0x34,0x0, 0x64,0x9d,0x32,0x3e,0x34,0x2e,0x35,0x3a,0x7a, +0x35,0x3a,0x7e,0x37,0x22,0xfd,0xbe,0x35,0x3a,0x8, 0x1b,0x7e,0x35,0x3a,0x7a,0x37, +0x22,0xfd,0xe5,0x2e,0x7a,0xb3,0x22,0xf7,0x7e,0x73,0x23,0x41,0x7a,0x73,0x22,0xf8, +0xe5,0x2b,0x7a,0xb3,0x22,0xf6,0x5, 0x2b,0x12,0xc0,0x74,0x28,0x3, 0x2, 0xbe,0x68, +0x7e,0xa3,0x22,0xf7,0xbe,0xa1,0x2f,0x40,0x20,0x7e,0xb3,0x22,0xf8,0xbe,0xb0,0x0, +0x28,0x17,0xbe,0xb0,0xff,0x50,0x12,0x7e,0x73,0x22,0xf6,0xa, 0x37,0xb, 0x34,0x7a, +0x73,0x39,0x3f,0x7a,0xb3,0x39,0x41,0x80,0x6, 0x74,0x7c,0x7a,0xb3,0x39,0x3f,0x7c, +0xba,0xda,0x3b,0x22,0x7e,0x73,0x3a,0x2, 0xbe,0x71,0x2b,0x22,0xca,0x3b,0x7c,0xfb, +0x7f,0x61,0x7f,0x40,0x9f,0x11,0x7f,0x51,0x7f,0x71,0x7a,0x1d,0x3c,0x7a,0x1d,0x40, +0x7a,0x1d,0x44,0xbe,0xf0,0xa, 0x78,0x6, 0x7e,0x54,0x1, 0x3c,0x80,0x4, 0x7e,0x54, +0x2, 0x35,0x7a,0x57,0x23,0x43,0x6c,0xee,0x80,0x60,0xa, 0x5e,0x7f,0x14,0x12,0xc1, +0xcd,0x7a,0x55,0x4a,0xa, 0x5e,0x7f,0x16,0x12,0xc1,0xcd,0x7a,0x55,0x48,0x7e,0x35, +0x48,0x12,0x97,0xc5,0x2f,0x50,0x7e,0x65,0x4a,0x7d,0x16,0x1a,0x2, 0x1a,0x0, 0x2f, +0x70,0x12,0x97,0xc5,0x12,0xc1,0xc3,0x7e,0x1d,0x3c,0x2f,0x10,0x7a,0x1d,0x3c,0x7d, +0x16,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x4a,0x12,0xc1,0xc3,0x7e,0x1d,0x40,0x2f,0x10, +0x7a,0x1d,0x40,0x7e,0x15,0x4a,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x48,0x12,0xc1,0xc3, +0x7e,0x1d,0x44,0x2f,0x10,0x7a,0x1d,0x44,0xb, 0xe0,0xbc,0xfe,0x38,0x9c,0xa, 0xdf, +0x6d,0xcc,0x7f,0x15,0x7f,0x6, 0x12,0x1f,0x58,0x7f,0x51,0x7f,0x17,0x7f,0x6, 0x12, +0x1f,0x58,0x7f,0x71,0x7e,0x94,0x0, 0x64,0x7e,0x1d,0x3c,0x7d,0x19,0x12,0x1e,0xfc, +0x7e,0x87,0x23,0x43,0x7d,0x18,0x7d,0xd8,0x1a,0x12,0x1a,0xc2,0x7f,0x6, 0x12,0x1f, +0x58,0x7a,0x1d,0x3c,0x7e,0x1d,0x40,0x7d,0x19,0x12,0x1e,0xfc,0x7f,0x6, 0x12,0x1f, +0x58,0x7a,0x1d,0x40,0x7e,0x1d,0x44,0x7d,0x19,0x12,0x1e,0xfc,0x7d,0x18,0x1a,0x2, +0x1a,0x0, 0x12,0x1f,0x58,0x7a,0x1d,0x44,0x7f,0x15,0x7f,0x7, 0x12,0x1e,0xeb,0x7e, +0x6d,0x44,0x9f,0x61,0x7f,0x15,0x7f,0x5, 0x12,0x1e,0xeb,0x7e,0x5d,0x3c,0x9f,0x51, +0x7f,0x17,0x7f,0x7, 0x12,0x1e,0xeb,0x7e,0x7d,0x40,0x9f,0x71,0xbe,0x58,0x0, 0x0, +0x68,0x6, 0xbe,0x78,0x0, 0x0, 0x78,0x6, 0x7e,0x44,0x0, 0x64,0x80,0x18,0x7f,0x16, +0x7d,0x19,0x12,0x1e,0xfc,0x7f,0x5, 0x12,0x1f,0x58,0x7f,0x6, 0x12,0x1e,0xeb,0x7f, +0x7, 0x12,0x1f,0x58,0x7d,0x43,0xbe,0x44,0x0, 0x0, 0x18,0x2, 0x6d,0x44,0x7c,0xb9, +0xda,0x3b,0x22,0x1a,0x26,0x1a,0x24,0x12,0x1e,0xeb,0x7f,0x1, 0x22,0x2d,0x35,0x7e, +0x1b,0x70,0xa, 0x57,0x22,0xca,0xf8,0x7f,0x51,0x7f,0x40,0x7e,0x37,0x2f,0x90,0x7a, +0x35,0x2a,0x7e,0x37,0x2f,0x8e,0x7a,0x35,0x2c,0x7e,0x37,0x2f,0x9c,0x7a,0x35,0x26, +0x7e,0x37,0x2f,0x9e,0x7a,0x35,0x28,0x6c,0xff,0x80,0x1e,0x7e,0x34,0x0, 0x26,0x7e, +0x14,0x0, 0x2f,0x74,0x9, 0x12,0x1f,0x8c,0x74,0x2, 0xac,0xbf,0x7f,0x4, 0x2d,0x15, +0x7f,0x15,0x2d,0x35,0x12,0xc2,0x24,0xb, 0xf0,0x7e,0x73,0x39,0x40,0xbc,0x7f,0x38, +0xda,0xda,0xf8,0x22,0x7f,0x71,0x7f,0x60,0x7e,0x35,0x2f,0xbe,0x34,0x0, 0x0, 0x38, +0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x2f,0x7e,0x35,0x31,0xbe,0x34,0x0, 0x0, 0x38, +0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x31,0xb, 0x6a,0x30,0x9e,0x35,0x33,0x6d,0x22, +0x7e,0x33,0x39,0x42,0x12,0xc2,0x79,0x7e,0x15,0x2f,0x12,0x1f,0x5, 0x1b,0x6a,0x30, +0xb, 0x7a,0x30,0x9e,0x35,0x35,0x6d,0x22,0x7e,0x33,0x39,0x43,0x12,0xc2,0x79,0x7e, +0x15,0x31,0x12,0x1f,0x5, 0x1b,0x7a,0x30,0x22,0xa, 0x13,0x6d,0x0, 0x2, 0x1e,0xeb, +0xca,0x79,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x7f,0x70,0x2d,0xf4,0xb, 0x7a,0xf0, +0x7d,0x7f,0x7c,0xbf,0xa, 0xfa,0x19,0xbf,0x39,0x44,0x7f,0x71,0x2d,0xf4,0xb, 0x7a, +0x40,0x7c,0xb9,0xa, 0x4a,0x19,0xb4,0x39,0x64,0xb, 0xa0,0xbe,0xa0,0x20,0x40,0xd4, +0x7e,0x8, 0x39,0x44,0x7e,0x18,0x39,0x64,0x74,0x20,0x12,0xbe,0x3b,0xda,0x79,0x22, +0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x73,0x39,0x40,0xbe,0x70,0x20,0x40,0x52,0x7e, +0xf0,0x2, 0x80,0x3c,0xa, 0x3f,0x6d,0x22,0x74,0x5, 0x2f,0x11,0x14,0x78,0xfb,0x7e, +0x33,0x39,0x40,0xa, 0x13,0x6d,0x0, 0x12,0x1f,0x7, 0x7c,0xe7,0xbe,0xe0,0x2, 0x50, +0x3, 0x7e,0xe0,0x2, 0xa, 0x6f,0x1b,0x64,0xa, 0x3e,0x1b,0x34,0x7c,0xc7,0x7f,0x5, +0x7c,0xbd,0x12,0xc3,0x2a,0x7f,0x6, 0x7c,0xbd,0x7c,0x7c,0x12,0xc3,0x2a,0xb, 0xf0, +0x7e,0x73,0x39,0x40,0xbc,0x7f,0x50,0xbc,0x7f,0x5, 0x7f,0x16,0x12,0xc2,0x80,0x80, +0x6, 0x74,0x7e,0x7a,0xb3,0x39,0x3f,0xda,0x3b,0x22,0x7c,0x97,0x7c,0xab,0x7f,0x10, +0x7e,0x30,0x2, 0xac,0x3a,0x2d,0x13,0x7d,0x2, 0xb, 0xa, 0x10,0x7e,0x10,0x2, 0xac, +0x19,0x7f,0x71,0x2d,0xf0,0xb, 0x7a,0x0, 0x7c,0x21,0xa5,0xba,0x0, 0x14,0xa, 0x3, +0x1b,0x7a,0x0, 0xbc,0x9a,0x68,0x24,0x6d,0x44,0x74,0x2, 0xa4,0x2d,0x35,0x1b,0x1a, +0x40,0x22,0xbc,0x9a,0x68,0x15,0xa, 0x2, 0xa, 0x13,0x2d,0x10,0xe, 0x14,0x1b,0x7a, +0x10,0x6d,0x11,0x74,0x2, 0xa4,0x2d,0x35,0x1b,0x1a,0x10,0x22,0xca,0x3b,0x7f,0x71, +0x7e,0x60,0x1, 0xb, 0xa, 0x20,0xb, 0x7a,0x50,0x7c,0x4b,0x7a,0x53,0x22,0xf4,0x7a, +0x43,0x23,0xe4,0x7e,0x70,0x1, 0x7e,0xa0,0x1, 0x81,0x9d,0x7e,0x90,0x2, 0xac,0x9a, +0x7f,0x60,0x2d,0xd4,0xb, 0x6a,0xd0,0x7d,0x7d,0x7c,0xbf,0xf5,0x26,0x7f,0x67,0x2d, +0xd4,0xb, 0x6a,0x40,0xa, 0xd5,0xa, 0xbb,0x7d,0xab,0x9d,0xad,0x7d,0x7a,0x7c,0x8f, +0xbe,0x80,0x0, 0x58,0x5, 0x6e,0x80,0xff,0xb, 0x80,0xa, 0xa4,0xa, 0x79,0x9d,0x7a, +0xbe,0xf0,0x0, 0x58,0x5, 0x6e,0xf0,0xff,0xb, 0xf0,0xbe,0x80,0x2, 0x58,0x7, 0xbe, +0xf0,0x2, 0x58,0x2, 0x81,0x9b,0xbe,0x60,0x0, 0x18,0x2, 0x81,0x83,0xbe,0x70,0xec, +0x28,0x2, 0x81,0xa7,0xbe,0x80,0x8, 0x58,0x5, 0xbe,0xf0,0x8, 0x48,0x61,0xa, 0xa7, +0xb, 0xa4,0x7d,0x6a,0x7c,0x7d,0xa, 0xa5,0x2d,0xab,0x12,0xc4,0xeb,0x19,0xba,0x22, +0xf4,0xa, 0xd9,0xa, 0xa4,0x2d,0xad,0x12,0xc4,0xeb,0x19,0xba,0x23,0xe4,0x9, 0xba, +0x22,0xf4,0xa, 0xdb,0xa, 0xc5,0x2d,0xcd,0xe, 0xc4,0x7d,0x6c,0x7c,0xbd,0xa, 0xc7, +0x19,0xbc,0x22,0xf3,0x9, 0xbc,0x23,0xe4,0xa, 0xcb,0xa, 0xa4,0x2d,0xac,0x12,0xc4, +0xeb,0x19,0xba,0x23,0xe3,0x2d,0xdb,0x12,0xc4,0xe2,0x19,0xbd,0x22,0xf5,0xa, 0xd9, +0x12,0xc4,0xe0,0x19,0xbd,0x23,0xe5,0xb, 0xd5,0x7d,0x6d,0x7c,0x7d,0x80,0x24,0xbe, +0x80,0x4, 0x58,0x5, 0xbe,0xf0,0x4, 0x48,0x1a,0xe5,0x26,0xa, 0xcb,0xa, 0xd5,0x12, +0xc4,0xe0,0x19,0xbd,0x22,0xf4,0xa, 0xc9,0xa, 0xd4,0x12,0xc4,0xe0,0x19,0xbd,0x23, +0xe4,0xb, 0x70,0xbe,0x70,0xf0,0x50,0x1f,0x7e,0x51,0x26,0x7c,0x49,0xe5,0x26,0xa, +0xd7,0x19,0xbd,0x22,0xf4,0x19,0x9d,0x23,0xe4,0xb, 0x70,0xb, 0xa0,0x7e,0xb3,0x39, +0x40,0xbc,0xba,0x28,0x2, 0x61,0x9b,0x7a,0x73,0x39,0x40,0x7e,0xa0,0x1, 0x80,0x25, +0xa, 0x3a,0x9, 0xb3,0x22,0xf4,0xa, 0x2b,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x60,0x2d, +0xd3,0x1b,0x6a,0x20,0xa, 0x2a,0x9, 0xb2,0x23,0xe4,0xa, 0x4b,0x2d,0x3f,0x7d,0x2e, +0x1b,0x1a,0x40,0xb, 0xa0,0x7e,0xb3,0x39,0x40,0xbc,0xba,0x38,0xd3,0xda,0x3b,0x22, +0x2d,0xdc,0xe, 0xd4,0x7d,0x6d,0x7c,0xbd,0xa, 0xd7,0x22,0xe, 0xa4,0x7d,0x6a,0x7c, +0xbd,0xa, 0xa7,0x22,0x7d,0x13,0x3e,0x14,0x3e,0x14,0x3e,0x14,0x7e,0x37,0x39,0xe3, +0x9e,0x37,0x39,0xdf,0x12,0x21,0xa, 0xbd,0x31,0x38,0x12,0x7e,0x37,0x39,0xe5,0x9e, +0x37,0x39,0xe1,0x12,0x21,0xa, 0xbd,0x31,0x38,0x3, 0x74,0x1, 0x22,0xe4,0x22,0xca, +0x79,0x6c,0xaa,0x6d,0x11,0x7d,0x41,0x7d,0x1, 0x7e,0xe3,0x2a,0x2, 0x7e,0xf3,0x2a, +0x3, 0x7e,0x73,0x39,0xde,0x4c,0x77,0x68,0x11,0x7e,0x27,0x39,0xe7,0x4d,0x22,0x78, +0x2, 0xc1,0x10,0xbe,0xe0,0x1, 0x28,0x2, 0xc1,0x10,0xbe,0xe0,0x1, 0x78,0x38,0xbe, +0x70,0x4, 0x78,0x2, 0xc1,0x10,0x7e,0x63,0x34,0x88,0x7e,0x10,0x9, 0xac,0x16,0x49, +0x40,0x29,0x8, 0x49,0x0, 0x29,0xa, 0xbe,0x44,0x0, 0x6e,0x50,0x2, 0xc1,0x10,0xbe, +0x44,0x3, 0x7a,0x28,0x2, 0xc1,0x10,0xbe,0x4, 0x0, 0x6e,0x50,0x2, 0xc1,0x10,0xbe, +0x4, 0x6, 0xc2,0x28,0x2, 0xc1,0x10,0x7c,0xb7,0x14,0x68,0x2b,0x14,0x68,0x51,0x14, +0x68,0x25,0x14,0x68,0x78,0xb, 0xb2,0x78,0x77,0xbe,0xe0,0x1, 0x68,0x2, 0xc1,0x1f, +0x4c,0xff,0x78,0x7b,0x74,0x1, 0x7a,0xb3,0x39,0xde,0x12,0xc6,0x35,0x7e,0x24,0x1, +0xf4,0x7a,0x27,0x39,0xe7,0x80,0x68,0x4c,0xee,0x78,0x17,0xa5,0xbf,0x1, 0x7, 0x74, +0x2, 0x12,0xc6,0x2c,0x80,0x41,0x74,0x4, 0x7a,0xb3,0x39,0xde,0x7e,0x34,0x0, 0x64, +0x80,0x35,0x12,0xc6,0x3e,0x7e,0x34,0x0, 0xa, 0x12,0xc6,0x24,0x68,0x32,0x80,0x3f, +0xbe,0xe0,0x1, 0x78,0x3a,0x4c,0xff,0x78,0x36,0x12,0xc6,0x3e,0x7e,0x37,0x39,0xe7, +0xbe,0x34,0x1, 0xe0,0x38,0x1a,0x7e,0x34,0x0, 0x14,0x12,0xc6,0x24,0x68,0x11,0x12, +0xc6,0x35,0x74,0x3, 0x12,0xc6,0x2c,0x7a,0x37,0x39,0xe7,0x80,0x12,0x7e,0xa0,0x24, +0xe4,0x7a,0xb3,0x39,0xde,0x6d,0x33,0x7a,0x37,0x39,0xe7,0x7c,0xba,0x80,0x2, 0x7c, +0xba,0xda,0x79,0x22,0x12,0xc4,0xf4,0xa, 0x1b,0x4d,0x11,0x22,0x7a,0xb3,0x39,0xde, +0x7e,0x34,0x1, 0xf4,0x22,0x7a,0x47,0x39,0xdf,0x7a,0x7, 0x39,0xe1,0x22,0x7a,0x47, +0x39,0xe3,0x7a,0x7, 0x39,0xe5,0x22,0x7e,0x11,0x2b,0xac,0x1f,0x3e,0x4, 0x7e,0x30, +0x2, 0xac,0x3e,0x2d,0x10,0x7e,0x1d,0x30,0x2d,0x31,0xb, 0x1a,0x20,0x7a,0x27,0x24, +0xf2,0x74,0x2, 0xac,0xbe,0x49,0x35,0x34,0x0, 0xad,0x23,0x74,0xc, 0x22,0x74,0x1, +0x7a,0xb3,0x2b,0x1, 0x7a,0xb3,0x2b,0x1d,0x22,0x3e,0x44,0x7e,0x1f,0x13,0x8a,0x2d, +0x34,0x1b,0x1a,0x50,0x22,0xa, 0x47,0x7f,0x70,0x2d,0xf4,0x7e,0x7b,0x60,0x22,0x74, +0x6, 0x7d,0x30,0x12,0x2f,0x58,0x6c,0x11,0x22,0x7e,0x70,0x2, 0xac,0x79,0x9, 0xb3, +0x1f,0x34,0x22,0x74,0x1, 0x12,0x13,0xde,0xe4,0x2, 0x0, 0x1e,0x74,0x2, 0x12,0x0, +0x1e,0x7e,0x8, 0x6, 0xfc,0x22,0x7a,0x91,0x82,0x7a,0x81,0x83,0xe4,0x93,0x22,0xb, +0xa, 0x30,0x2d,0x32,0x1b,0xa, 0x30,0x22,0x6d,0x33,0xe4,0x6c,0x55,0x2, 0x13,0x1, +0x7e,0x73,0x38,0xbe,0x7a,0x73,0x2b,0x20,0x22,0x7e,0xb3,0x38,0xe1,0x7e,0x34,0x0, +0x4, 0x22,0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0xfc,0x22,0x2d,0x13,0x7e,0xb, 0x50,0xa, +0x25,0x22,0x7e,0x8, 0x2a,0x6d,0x2, 0x0, 0x2e,0x12,0x2f,0x58,0x74,0x6, 0x7d,0x30, +0x22,0x7e,0xb3,0x28,0xa8,0xbe,0xb0,0x1, 0x22,0xe4,0x12,0x13,0xde,0x2, 0x13,0x96, +0xc7,0x10,0x38,0xef,0xa2,0x5d,0xa, 0x3b, diff --git a/drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Ofilm0x51_Ver0a_20170119_app.i b/drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Ofilm0x51_Ver0a_20170119_app.i new file mode 100644 index 000000000000..d5bf7cda4de0 --- /dev/null +++ b/drivers/input/touchscreen/ft5435/HQ_AL1512_C6_FT5435_Ofilm0x51_Ver0a_20170119_app.i @@ -0,0 +1,3186 @@ +0x2, 0x1f,0xd2,0x2, 0xb6,0x1a,0xeb,0xaa,0x8, 0x22,0x22,0x2, 0x0, 0x49,0xb4,0x2, +0x4, 0xa9,0xb7,0xea,0x22,0x24,0xff,0xa9,0x97,0xea,0x22,0x2, 0x50,0x32,0xb4,0x2, +0x4, 0xa9,0xb6,0xea,0x22,0x24,0xff,0xa9,0x96,0xea,0x22,0x2, 0x68,0x4, 0x7f,0x60, +0xa9,0xc2,0xea,0x74,0x1, 0x12,0x13,0x96,0x7f,0x6, 0x12,0x5, 0xb4,0x7f,0x6, 0x2, +0x9, 0xa1,0x22,0x2, 0x68,0x20,0x2, 0x26,0x11,0x32,0x32,0x2, 0x0, 0x4a,0x12,0x10, +0xa2,0x2, 0x13,0x79,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32,0x2, 0x0, 0x76,0x1, 0x2, +0x4, 0x8, 0x10,0x20,0x40,0x80,0xf5,0xfd,0xe5,0xfe,0x22,0x2, 0x0, 0x5a,0xd2,0x1, +0x2, 0x37,0xa6,0x2, 0x10,0x52,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b, +0xca,0x1b,0xca,0xb, 0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0xf, 0x7e,0xf, 0x39,0xc9, +0x69,0x30,0x0, 0x4, 0x7a,0x73,0x39,0xd9,0x7e,0x73,0x39,0xd9,0xa, 0x37,0x5e,0x34, +0x0, 0x4, 0x68,0x4, 0xd2,0xe, 0x80,0x2, 0xc2,0xe, 0x7e,0x34,0x0, 0x1f,0x79,0x30, +0x0, 0x4, 0xc2,0xc3,0x12,0x12,0x9e,0x12,0x69,0x5, 0x7e,0x1f,0x39,0xc9,0x69,0x31, +0x0, 0x2, 0x5e,0x34,0x0, 0x40,0x68,0x2e,0x6c,0xaa,0x7e,0x10,0x2, 0xac,0x1a,0x7e, +0x1f,0x39,0xc9,0x7f,0x71,0x2d,0xf0,0x69,0x17,0x0, 0x9c,0x59,0x10,0x39,0xcd,0xb, +0xa0,0xbe,0xa0,0x3, 0x78,0xe4,0x69,0x11,0x0, 0xa4,0x7a,0x17,0x39,0xd5,0x69,0x31, +0x0, 0xa2,0x7a,0x37,0x39,0xd3,0xa9,0xc1,0xc4,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda, +0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x7d,0x13, +0x7e,0x1f,0x39,0xf8,0x1b,0x1a,0x10,0xc2,0xc6,0xd2,0xee,0x22,0xff,0xff,0x54,0x2c, +0xca,0x79,0x7f,0x50,0x7c,0xeb,0x7e,0x34,0x0, 0x24,0x7e,0x8, 0x0, 0x2c,0x7e,0x24, +0x0, 0x2, 0x12,0x63,0x62,0xe5,0x2c,0xbe,0xb0,0x0, 0x38,0x2, 0x21,0x4a,0xe5,0x2c, +0xbe,0xb0,0x76,0x28,0x2, 0x21,0x4a,0x7e,0xe1,0x2c,0xbe,0xe0,0x76,0x38,0x2, 0x21, +0x78,0x7e,0x34,0x1e,0x45,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1e,0x29,0x79,0x35,0x0, +0x4, 0xbe,0xe0,0x81,0x68,0x2, 0x21,0x71,0x74,0x23,0x7a,0x5b,0xb0,0x74,0x1c,0x61, +0x84,0x74,0x1, 0x7a,0x5b,0xb0,0x61,0x84,0x7c,0xbe,0x14,0xbe,0xb0,0x75,0x40,0x2, +0x61,0x33,0x7e,0xa0,0x3, 0xa4,0x2e,0x54,0x1, 0x8c,0x89,0x54,0x2, 0x2, 0xfb,0x2, +0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x2, 0xed,0x2, 0x2, +0xfb,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x2, 0xfb, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x25,0x2, 0x3, 0x33,0x2, 0x3, 0x9, 0x2, +0x2, 0xfb,0x2, 0x3, 0x17,0x2, 0x3, 0x17,0x2, 0x2, 0xfb,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, +0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33, +0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, +0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x3, 0x33,0x2, 0x2, 0xfb,0x41,0xfb,0x7e,0x34,0x1e, +0x45,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1d,0xe2,0x61,0x3f,0x7e,0x34,0x1e,0x19,0x79, +0x35,0x0, 0x2, 0x7e,0x34,0x1e,0x29,0x61,0x3f,0x7e,0x34,0x1e,0x19,0x79,0x35,0x0, +0x2, 0x7e,0x34,0x1d,0xb2,0x61,0x3f,0x7e,0x34,0x1d,0x96,0x79,0x35,0x0, 0x2, 0x7e, +0x34,0x1d,0xc6,0x61,0x3f,0x7e,0x34,0x1e,0xa, 0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1d, +0xf1,0x61,0x3f,0x7e,0x34,0x1e,0x45,0x79,0x35,0x0, 0x2, 0x7e,0x34,0x1e,0x29,0x79, +0x35,0x0, 0x4, 0xbe,0xe0,0x16,0x28,0x2, 0x61,0x4e,0x7c,0xfe,0x61,0x62,0x7e,0xf0, +0x16,0xbe,0xe0,0x72,0x50,0x2, 0x61,0x62,0xa, 0x3e,0x9e,0x34,0x0, 0x72,0xb, 0x34, +0x2c,0xf7,0x7e,0x70,0x3, 0xac,0x7f,0x7d,0x23,0x2e,0x24,0x1e,0x69,0x7a,0x51,0x82, +0x7a,0x41,0x83,0xe4,0x93,0x7a,0x5b,0xb0,0x2e,0x34,0x1e,0x6a,0x7a,0x71,0x82,0x7a, +0x61,0x83,0xe4,0x93,0x39,0xb5,0x0, 0x1, 0xda,0x79,0x22,0xca,0x3b,0x7f,0x30,0x74, +0x1, 0x12,0x13,0xde,0x29,0x73,0x0, 0xf3,0x2e,0x70,0xff,0x92,0x1, 0x29,0xb3,0x0, +0xf4,0x12,0x13,0xaf,0x7f,0x3, 0x12,0xd, 0x72,0x7f,0x3, 0x12,0x6, 0xba,0x29,0x73, +0x0, 0xa, 0xa, 0x37,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x24,0x29,0x73,0x0, 0xa3, +0xa, 0x27,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24, +0x69,0x33,0x0, 0xff,0x4d,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2, 0x29,0x73, +0x0, 0xa, 0xa, 0x47,0x29,0x73,0x0, 0x5, 0xa, 0x57,0x9d,0x54,0xf5,0x34,0x29,0xb3, +0x0, 0xa5,0x70,0xb, 0x29,0xb3,0x0, 0xf8,0x29,0x73,0x0, 0xf7,0x12,0xb, 0xad,0x29, +0x73,0x0, 0xa5,0x2e,0x70,0xff,0x92,0x1, 0xe5,0x34,0x12,0xb, 0x1e,0x69,0x33,0x0, +0xfd,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x28,0x69,0x23,0x0, 0xfb,0x3e,0x24,0x3e, +0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x29,0x73,0x0, 0xfa,0xa, 0x37,0x2d, +0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2a,0x29,0x73,0x0, 0xf9,0xa, 0x37,0x7e, +0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2c,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x39,0xc9,0x79, +0x30,0x0, 0x34,0x7e,0x34,0x1, 0xb, 0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x2e,0x29, +0x73,0x0, 0x5, 0xa, 0x37,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x10,0x69,0x33,0x0, +0xa8,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x1c,0x69,0x33,0x0, 0xaa,0x7e,0xf, 0x39, +0xc9,0x79,0x30,0x0, 0x1e,0x6c,0xaa,0x7e,0x50,0x2, 0xac,0x5a,0x69,0x13,0x1, 0x1, +0x2d,0x12,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x30,0x7e,0xf, 0x39,0xc9,0x2d,0x12,0x79, +0x30,0x0, 0x44,0xb, 0xa0,0xbe,0xa0,0xc, 0x40,0xdd,0xda,0x3b,0x22,0xca,0xf8,0x7f, +0x70,0x7e,0x7b,0xf0,0x29,0x77,0x0, 0x1, 0xbc,0x7f,0x28,0x2, 0x7c,0xf7,0x69,0x17, +0x0, 0x6, 0x6d,0x0, 0x7e,0x34,0x0, 0xf2,0x74,0xff,0x12,0x20,0xe8,0x7f,0x7, 0x12, +0xe, 0xed,0xa9,0xd6,0xcb,0x6c,0xaa,0x80,0x2d,0x6c,0x77,0x80,0x1f,0x7e,0x10,0xb, +0xac,0x1a,0xa, 0x17,0x2d,0x1, 0x3e,0x4, 0x69,0x17,0x0, 0x6, 0x2d,0x10,0x6d,0x0, +0xb, 0xa, 0x20,0x6e,0x24,0xff,0xff,0x1b,0xa, 0x20,0xb, 0x70,0x29,0x67,0x0, 0x1, +0xbc,0x67,0x38,0xd9,0xb, 0xa0,0x7e,0x7b,0x60,0xbc,0x6a,0x38,0xcc,0x69,0x37,0x0, +0x6, 0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0x4, 0x7c,0x4f,0x6c,0x55,0xa, 0x3f,0x2d, +0x32,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0xc, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b, +0x1a,0x10,0x7e,0x34,0x0, 0xd0,0x12,0xf, 0x45,0x6c,0xaa,0xbe,0xa0,0x4, 0x50,0x18, +0x7e,0x70,0x4, 0xac,0x7a,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69,0x41,0x0, 0x26,0x60, +0x42,0x1e,0x44,0x14,0x78,0xfb,0x80,0x3b,0xbe,0xa0,0x8, 0x50,0x1b,0xa, 0x3a,0x1b, +0x36,0x3e,0x34,0x3e,0x34,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69,0x41,0x0, 0x28,0x60, +0x22,0x1e,0x44,0x14,0x78,0xfb,0x80,0x1b,0xa, 0x3a,0x9e,0x34,0x0, 0x8, 0x3e,0x34, +0x3e,0x34,0x7c,0xb7,0x7e,0x1f,0x33,0xfc,0x69,0x41,0x0, 0x2a,0x60,0x5, 0x1e,0x44, +0x14,0x78,0xfb,0x5e,0x44,0x0, 0xf, 0x7e,0x50,0x2, 0xac,0x5a,0x69,0x37,0x0, 0x6, +0x2d,0x32,0x6d,0x22,0x1b,0x1a,0x40,0xb, 0xa0,0xbe,0xa0,0xb, 0x40,0x8d,0xa9,0xc6, +0xcb,0xda,0xf8,0x22,0x29,0x70,0x0, 0x96,0x29,0x90,0x0, 0x98,0x29,0x60,0x0, 0x97, +0x29,0x80,0x0, 0x8d,0xbe,0x80,0x4, 0x38,0x4, 0x6c,0xaa,0x80,0x21,0xbe,0x80,0x8, +0x38,0x5, 0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x80,0x10,0x38,0x5, 0x7e,0xa0,0x2, 0x80, +0xd, 0xbe,0x80,0x20,0x38,0x5, 0x7e,0xa0,0x3, 0x80,0x3, 0x7e,0xa0,0x4, 0xbe,0x90, +0x3, 0x28,0x3, 0x7e,0x90,0x3, 0xbe,0x80,0x3f,0x28,0x3, 0x7e,0x80,0x3f,0xbe,0x60, +0x1, 0x28,0x3, 0x7e,0x60,0x1, 0xbe,0x70,0x2, 0x28,0x2, 0x6c,0x77,0xa, 0x28,0x3e, +0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x7c,0x89,0x6c,0x99,0x3e,0x44,0x3e, +0x44,0x3e,0x44,0x2d,0x42,0xa, 0x26,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d, +0x24,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x2d,0x32,0x7e,0x7f,0x39,0xf8,0x79,0x37,0x0, +0x2, 0x29,0xb0,0x0, 0x8c,0x7c,0x4b,0x6c,0x55,0x29,0xb0,0x0, 0x8b,0xa, 0x3b,0x2d, +0x32,0x7e,0x7f,0x39,0xc1,0x79,0x37,0x0, 0x80,0x69,0x30,0x0, 0xa0,0x7e,0x7f,0x39, +0xf8,0x79,0x37,0x0, 0xc, 0x69,0x30,0x0, 0x9e,0x5e,0x34,0xe0,0xf, 0x29,0xb0,0x0, +0x8c,0xa, 0x2b,0x1b,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x2d,0x32,0x7e, +0x7f,0x39,0xc1,0x79,0x37,0x0, 0x82,0xa, 0x2a,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e, +0x24,0x29,0xb0,0x0, 0x99,0xa, 0x3b,0x2d,0x32,0x7e,0x7f,0x39,0xf8,0x79,0x37,0x0, +0x6, 0x69,0x30,0x0, 0x9c,0x7e,0x7f,0x39,0xf8,0x79,0x37,0x0, 0x8, 0x69,0x30,0x0, +0x9a,0x7e,0xf, 0x39,0xf8,0x79,0x30,0x0, 0xa, 0x22,0x7f,0x60,0x74,0x1, 0x12,0x13, +0xde,0x29,0x36,0x0, 0xf5,0x29,0x26,0x0, 0xa3,0x29,0x16,0x0, 0xa4,0xbe,0x20,0x2, +0x28,0x3, 0x7e,0x20,0x2, 0xbe,0x10,0x40,0x28,0x3, 0x7e,0x10,0x40,0x7e,0x34,0x0, +0x4, 0x7c,0xb2,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7c,0x7, 0xa, 0x31,0x7e,0x2f, +0x39,0xc9,0x79,0x32,0x0, 0x12,0x7c,0x73,0xac,0x70,0xa, 0x21,0x12,0x1e,0xb9,0x7c, +0x27,0xa, 0x32,0x7e,0x2f,0x39,0xc9,0x79,0x32,0x0, 0x14,0x7c,0x73,0xac,0x70,0x29, +0x26,0x0, 0xf6,0xa, 0x22,0xad,0x32,0xa, 0x21,0x8d,0x32,0x7d,0x43,0x7c,0x73,0xac, +0x70,0xa, 0x21,0x12,0x1e,0xb9,0x7c,0xa7,0x7c,0x2a,0x7c,0xb9,0x2c,0xab,0xbe,0xa0, +0xc, 0x50,0x3, 0x7e,0xa0,0xc, 0xbe,0x20,0xc, 0x50,0x3, 0x7e,0x20,0xc, 0xa, 0x20, +0xa, 0x31,0x12,0x1e,0xb9,0x7d,0xe3,0xa, 0x3a,0xb, 0x34,0xad,0x3e,0xb, 0x34,0xbe, +0x34,0x2, 0x0, 0x40,0x4, 0x7e,0x34,0x1, 0xff,0x29,0x46,0x0, 0xf7,0x7e,0x50,0x2, +0xac,0x45,0xa, 0xf2,0xad,0xfe,0x2d,0x2f,0xb, 0x24,0xbe,0x24,0x2, 0x0, 0x40,0x4, +0x7e,0x24,0x1, 0xff,0xa, 0x13,0x7e,0x7f,0x39,0xc9,0x79,0x17,0x0, 0xa, 0x1e,0x24, +0x7c,0x45,0x6c,0x55,0x1e,0x34,0x2d,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0xc, +0xa, 0x3a,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x22,0x22,0xa9,0xd6,0xcb,0x69,0x30, +0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x6, 0x7e,0x2f, +0x33,0xfc,0x79,0x32,0x0, 0x6, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x32, +0x0, 0x8, 0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d, +0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x29,0x70,0x0, 0x2, 0xa, 0x37,0x7e, +0xf, 0x33,0xfc,0x79,0x30,0x0, 0xe, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10, +0x7e,0x34,0x0, 0xe0,0x12,0xf, 0x45,0xa9,0xc6,0xcb,0x22,0xb2,0x86,0x22,0xff,0xff, +0x7f,0x21,0xa9,0xd6,0xcb,0x69,0x30,0x0, 0x4, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, +0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x6, 0x69,0x30,0x0, +0x6, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x8, 0x29,0x70,0x0, 0x1, 0x7c,0x47,0x6c, +0x55,0x7e,0xb, 0x70,0xa, 0x37,0x2d,0x32,0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xc, +0x29,0x70,0x0, 0x2, 0xa, 0x37,0x1b,0x34,0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xa, +0x69,0x30,0x0, 0xa, 0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0xe, 0x69,0x30,0x0, 0xc, +0x7e,0x7f,0x33,0xfc,0x79,0x37,0x0, 0x10,0x69,0x30,0x0, 0xe, 0x7e,0x7f,0x33,0xfc, +0x79,0x37,0x0, 0x12,0x29,0x70,0x0, 0x3, 0x7c,0x27,0x6c,0x33,0x7e,0x1f,0x33,0xfc, +0x1b,0x1a,0x10,0x7e,0x34,0x0, 0xa0,0x12,0xf, 0x45,0x7e,0x1f,0x33,0xfc,0x69,0x11, +0x0, 0x1a,0x7a,0x2b,0x30,0x69,0x11,0x0, 0x1c,0x39,0x32,0x0, 0x1, 0x69,0x11,0x0, +0x16,0x79,0x12,0x0, 0x2, 0x69,0x11,0x0, 0x18,0x79,0x12,0x0, 0x4, 0x69,0x11,0x0, +0x22,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x24,0x79,0x12,0x0, 0x8, 0x69,0x11,0x0, +0x1e,0x79,0x12,0x0, 0xa, 0x69,0x31,0x0, 0x20,0x79,0x32,0x0, 0xc, 0xa9,0xc6,0xcb, +0x22,0xca,0x3b,0x7c,0x57,0x7c,0x4b,0x5e,0x40,0x3, 0x69,0x30,0x0, 0x4, 0x5e,0x60, +0x3f,0x6c,0xaa,0xa, 0x4a,0x69,0xf0,0x0, 0xa, 0x69,0xe0,0x0, 0x8, 0x2d,0xf4,0x7e, +0x7b,0xb0,0xa, 0xfb,0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4,0xa, 0xea,0x69,0xd0, +0x0, 0xe, 0x69,0xc0,0x0, 0xc, 0x2d,0xde,0x7e,0x6b,0xb0,0xa, 0x4b,0x2d,0x4f,0x7e, +0xd0,0x28,0xac,0xd5,0x7e,0xf0,0x2, 0xac,0xfa,0x7d,0xd7,0x2d,0xd6,0x7e,0xf0,0xf0, +0xac,0xf4,0x2d,0xd7,0x7e,0x7f,0x39,0xf4,0x2d,0xfd,0x79,0x47,0x1, 0x8c,0xb, 0xa0, +0xbe,0xa0,0xe, 0x78,0xae,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x69,0xf0,0x0, 0x2, +0xb, 0xa, 0xe0,0x2d,0xf4,0xb, 0x7a,0x40,0x7e,0xd0,0x28,0xac,0xd5,0x7e,0xf0,0x2, +0xac,0xfa,0x7d,0xd7,0x2d,0xd6,0x7e,0xf0,0xf0,0xac,0xf4,0x2d,0xd7,0x7e,0x7f,0x39, +0xf4,0x2d,0xfd,0x79,0x47,0x1, 0x80,0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xc9,0x7e,0x90, +0xf0,0xac,0x94,0x74,0x28,0xac,0xb5,0x7d,0xf5,0x2d,0xf4,0x7e,0x2f,0x39,0xf4,0x2d, +0x5f,0x79,0x32,0x1, 0x88,0x69,0x30,0x0, 0x6, 0x7e,0x30,0xf0,0xac,0x34,0x74,0x28, +0xac,0x5b,0x2d,0x21,0x7e,0xf, 0x39,0xf4,0x2d,0x12,0x79,0x30,0x1, 0x8a,0xda,0x3b, +0x22,0x29,0x60,0x0, 0xb, 0xa, 0x46,0x29,0x60,0x0, 0x4, 0xa, 0x26,0x2d,0x24,0x7c, +0x65,0x29,0xb0,0x0, 0x6, 0xbc,0xb6,0x28,0x2, 0x7c,0x6b,0x29,0x70,0x0, 0x5, 0x29, +0xb0,0x0, 0x7, 0xbc,0xb7,0x28,0x2, 0x7c,0x7b,0x6c,0xaa,0x6d,0x22,0x7e,0x90,0x2, +0xac,0x9a,0x7e,0x7f,0x39,0xc1,0x2d,0xf4,0x79,0x27,0x0, 0x2, 0xb, 0xa0,0xbe,0xa0, +0x23,0x78,0xea,0x6c,0xaa,0x80,0x55,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0x57,0x0, +0x4c,0xbe,0x50,0x23,0x50,0x23,0x29,0x47,0x0, 0xb4,0xa, 0xd4,0x7d,0x4d,0x7c,0x89, +0x6c,0x99,0x7d,0xd4,0x7e,0x90,0x2, 0xac,0x95,0x7e,0x7f,0x39,0xc1,0x2d,0xf4,0xb, +0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40,0xa, 0x4a,0x7f,0x70,0x2d,0xf4,0x29, +0x47,0x0, 0x4c,0xa, 0xd4,0x7e,0x90,0x2, 0xac,0x9a,0x7e,0x7f,0x39,0xc1,0x2d,0xf4, +0xb, 0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40,0xb, 0xa0,0xbc,0x6a,0x38,0xa7, +0x6c,0xaa,0x80,0x1d,0xa, 0x2a,0x7f,0x70,0x2d,0xf2,0x29,0x67,0x0, 0x6f,0xa, 0x46, +0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x39,0xc1,0x2d,0xf2,0x79,0x47,0x0, 0x48,0xb, +0xa0,0xbc,0x7a,0x38,0xdf,0x22,0x7c,0x7b,0x7e,0x7f,0x39,0xc9,0x69,0x47,0x0, 0xc, +0x6c,0x88,0x3e,0x44,0x69,0x7, 0x0, 0xa, 0x69,0x57,0x0, 0x2, 0x1e,0x54,0x1e,0x54, +0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x5e,0x54,0x0, 0x3, 0x7e,0x14, +0x0, 0x4, 0x70,0x2, 0x41,0x9b,0x3e,0x14,0x14,0x78,0xfb,0x7c,0xa3,0xa, 0xda,0xad, +0xd0,0x7d,0xcd,0x6d,0x11,0x79,0x17,0x0, 0x8c,0x7c,0xb7,0x70,0x2, 0x41,0xb4,0x1e, +0xd4,0x14,0x78,0xfb,0xbe,0xd4,0x1, 0x0, 0x38,0x2, 0x41,0xc2,0x7e,0xd4,0x1, 0x0, +0x41,0xce,0xbe,0xd4,0x0, 0x10,0x40,0x2, 0x41,0xce,0x7e,0xd4,0x0, 0x10,0x7d,0x3d, +0x12,0x12,0x6a,0xa, 0x1b,0x7e,0x1f,0x39,0xc9,0x79,0x11,0x0, 0x90,0x7e,0x1f,0x39, +0xc9,0x79,0xd1,0x0, 0x8e,0x7e,0x7f,0x39,0xc9,0x69,0x37,0x0, 0x8, 0xad,0x3c,0x8d, +0x3d,0x79,0x37,0x0, 0x92,0x7e,0x14,0x0, 0x6, 0x7e,0x1f,0x39,0xc9,0x79,0x11,0x0, +0x94,0x7d,0x24,0x9d,0x20,0xa, 0x3a,0xad,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, +0x96,0x7e,0x34,0x0, 0x10,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x98,0x22,0x7c,0x5b, +0x7e,0xf, 0x39,0xc9,0x69,0x40,0x0, 0x22,0x30,0x1, 0x6b,0x6d,0xff,0x7d,0x3f,0xbe, +0x50,0x10,0x28,0x2e,0x7e,0x54,0xff,0xff,0x79,0x50,0x0, 0x42,0x9e,0x50,0x10,0x6c, +0xaa,0x80,0x11,0x7e,0xe4,0x0, 0x1, 0x7c,0xba,0x60,0x5, 0x3e,0xe4,0x14,0x78,0xfb, +0x2d,0x3e,0xb, 0xa0,0xbc,0x5a,0x38,0xeb,0x7e,0x6f,0x39,0xc9,0x79,0x36,0x0, 0x40, +0x80,0x25,0x79,0xf0,0x0, 0x40,0x6c,0xaa,0x80,0x11,0x7e,0xf4,0x0, 0x1, 0x7c,0xba, +0x60,0x5, 0x3e,0xf4,0x14,0x78,0xfb,0x2d,0x3f,0xb, 0xa0,0xbc,0x5a,0x38,0xeb,0x7e, +0x7f,0x39,0xc9,0x79,0x37,0x0, 0x42,0x7d,0x34,0x2e,0x34,0x0, 0xc, 0x7e,0x7f,0x39, +0xc9,0x79,0x37,0x0, 0x16,0x22,0x6d,0x33,0x79,0x30,0x0, 0x40,0x7e,0xf, 0x39,0xc9, +0x79,0x30,0x0, 0x42,0x7e,0x1f,0x39,0xc9,0x79,0x41,0x0, 0x16,0x22,0x7c,0x17,0x7c, +0x3b,0x6d,0x33,0x7e,0x2f,0x39,0xc9,0x79,0x32,0x0, 0x40,0x7e,0x2f,0x39,0xc9,0x79, +0x32,0x0, 0x42,0x7e,0x7f,0x39,0xc9,0x69,0x57,0x0, 0x12,0x7c,0xab,0x69,0x37,0x0, +0x2, 0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x1e,0x34,0x5e, +0x34,0x0, 0x3, 0x7c,0xb7,0x7e,0x44,0x0, 0x4, 0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb, +0x7c,0x29,0xa, 0x22,0xa, 0x3a,0x12,0x1e,0xb9,0xa, 0x23,0x2d,0x32,0x7c,0xb7,0x7c, +0x61,0x6c,0x77,0xa, 0xb, 0x1e,0x4, 0x2d,0x3, 0x79,0x7, 0x0, 0xc, 0x7c,0x73,0xac, +0x72,0xa, 0x2a,0x12,0x1e,0xb9,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x16,0x6d,0x33, +0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x22,0x22,0xa9,0xd6,0xcb,0x69,0x30,0x0, 0x6, +0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33,0xfc, +0x79,0x32,0x0, 0x8, 0x29,0x70,0x0, 0x2, 0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x3, +0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x7e,0xb, 0x70,0x7c, +0x47,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, +0xa, 0x29,0x70,0x0, 0x4, 0xa, 0x37,0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0xe, 0x29, +0xb0,0x0, 0x5, 0x54,0x1, 0x7c,0x2b,0x6c,0x33,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10, +0x7e,0x34,0x0, 0xc0,0x12,0xf, 0x45,0xa9,0xc6,0xcb,0x22,0xca,0x79,0x7c,0xab,0x5e, +0xa0,0x3, 0x6c,0x77,0x7e,0x50,0x2, 0xac,0x57,0x69,0xd0,0x0, 0xe, 0x69,0xc0,0x0, +0xc, 0x2d,0xd2,0x29,0x66,0x0, 0x1, 0xa, 0xf6,0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d, +0xf4,0x7e,0x6b,0x60,0xa, 0x46,0x2d,0x4f,0x7e,0xf0,0xf0,0xac,0xfa,0x2d,0x27,0x7e, +0x7f,0x39,0xf4,0x2d,0xf2,0x79,0x47,0x2, 0x54,0xb, 0x70,0xbe,0x70,0xe, 0x40,0xc4, +0x69,0x40,0x0, 0x4, 0x7e,0xf0,0xf0,0xac,0xfa,0x7e,0x1f,0x39,0xf4,0x2d,0x37,0x79, +0x41,0x2, 0x50,0x69,0x30,0x0, 0x6, 0x74,0xf0,0xa4,0x7e,0xf, 0x39,0xf4,0x2d,0x15, +0x79,0x30,0x2, 0x52,0xda,0x79,0x22,0xa9,0xd6,0xcb,0xc2,0x1e,0x69,0x30,0x0, 0x4, +0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x4, 0x69,0x30,0x0, 0x6, 0x7e,0x2f,0x33,0xfc, +0x79,0x32,0x0, 0x6, 0x69,0x30,0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x32,0x0, 0x8, +0x7e,0xb, 0x70,0x7c,0x47,0x6c,0x55,0x29,0x70,0x0, 0x1, 0xa, 0x37,0x2d,0x32,0x7e, +0x2f,0x33,0xfc,0x79,0x32,0x0, 0xc, 0x29,0x70,0x0, 0x2, 0xa, 0x37,0x7e,0x2f,0x33, +0xfc,0x79,0x32,0x0, 0xe, 0x29,0xb0,0x0, 0x3, 0x54,0x1, 0xa, 0x5b,0x7c,0xab,0xe4, +0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x50,0x69,0x30,0x0, 0xa, 0x12,0xf, 0x45,0xa9,0xc6, +0xcb,0x22,0x69,0x30,0x0, 0xae,0x7e,0x2f,0x39,0xc9,0x79,0x32,0x0, 0x6, 0x29,0x50, +0x0, 0xa6,0xa, 0x55,0x7d,0x23,0x1e,0x24,0x9d,0x25,0x7e,0x2f,0x39,0xc9,0x79,0x22, +0x0, 0x18,0x7d,0x23,0x1e,0x24,0x1b,0x25,0x7e,0x2f,0x39,0xc9,0x79,0x22,0x0, 0x38, +0x69,0x20,0x0, 0xfd,0x1e,0x34,0x9d,0x32,0x9e,0x34,0x0, 0xa, 0x7e,0x2f,0x39,0xc9, +0x79,0x32,0x0, 0x26,0x29,0x70,0x0, 0xa7,0xa, 0x37,0x7e,0x2f,0x39,0xc9,0x79,0x32, +0x0, 0x1a,0x29,0x70,0x0, 0xb, 0xa, 0x27,0x29,0x70,0x0, 0x4, 0x2d,0x32,0x7e,0x2f, +0x39,0xc9,0x79,0x32,0x0, 0x8, 0x2, 0x9, 0xa1,0xca,0x3b,0xf5,0x24,0x7f,0x41,0x7f, +0x30,0xe5,0x25,0x7e,0x8, 0x0, 0x26,0x12,0x1, 0x20,0xe5,0x24,0xbe,0xb0,0x23,0x28, +0x3, 0x75,0x24,0x23,0x6c,0xaa,0x80,0x36,0xa, 0x3a,0x2d,0x39,0x7d,0x28,0x7e,0x1b, +0xb0,0xbe,0xb1,0x26,0x40,0xd, 0x74,0x23,0xa, 0x4a,0x7f,0x3, 0x2d,0x14,0x7a,0xb, +0xb0,0x80,0x19,0x7e,0x1b,0xb0,0xa, 0x3b,0x2e,0x35,0x28,0x7a,0x71,0x82,0x7a,0x61, +0x83,0xe4,0x93,0xa, 0x4a,0x7f,0x13,0x2d,0x34,0x7a,0x1b,0xb0,0xb, 0xa0,0xe5,0x24, +0xbc,0xba,0x38,0xc4,0xda,0x3b,0x22,0xa9,0xd6,0xcb,0x69,0x20,0x0, 0x4, 0x7e,0x2f, +0x33,0xfc,0x79,0x22,0x0, 0x4, 0x69,0x20,0x0, 0x8, 0x7e,0x2f,0x33,0xfc,0x79,0x22, +0x0, 0x8, 0x7e,0xb, 0x50,0xa, 0x55,0x7c,0xab,0xe4,0x29,0x50,0x0, 0x1, 0xa, 0x25, +0x2d,0x25,0x7e,0x2f,0x33,0xfc,0x79,0x22,0x0, 0xc, 0x29,0x50,0x0, 0x2, 0xa, 0x25, +0x7e,0xf, 0x33,0xfc,0x79,0x20,0x0, 0xe, 0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0xa, +0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0x40,0x12,0xf, 0x45, +0xa9,0xc6,0xcb,0x22,0x7c,0xab,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x39,0xf8,0x79,0x30, +0x0, 0xe, 0xc2,0x1d,0xe4,0x7a,0xb3,0x39,0xf3,0x5e,0xa0,0x3, 0xa, 0x1a,0x3e,0x14, +0x7e,0x1f,0x39,0xc1,0x1b,0x1a,0x10,0x7e,0xf, 0x39,0xc1,0x2e,0x14,0x0, 0x84,0xb, +0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x74,0x1, 0x12,0x13,0x56,0x7e,0xf, 0x39, +0xf8,0xb, 0xa, 0x30,0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xa9,0xd3,0xcd,0x7e,0xf, 0x39, +0xf8,0xb, 0x15,0xb, 0xa, 0x30,0x4e,0x70,0x1, 0x1b,0xa, 0x30,0x22,0x7f,0x10,0xa9, +0xd6,0xcb,0x69,0x11,0x0, 0x2, 0x7e,0x2f,0x33,0xfc,0x79,0x12,0x0, 0x4, 0x69,0x11, +0x0, 0x4, 0x7e,0x2f,0x33,0xfc,0x79,0x12,0x0, 0x6, 0x69,0x11,0x0, 0x6, 0x7e,0x2f, +0x33,0xfc,0x79,0x12,0x0, 0x8, 0x7e,0x1b,0x30,0xa, 0x3, 0x7e,0x14,0x1, 0x0, 0xad, +0x10,0x29,0x71,0x0, 0x1, 0xa, 0x37,0x2d,0x31,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, +0xc, 0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x7e,0x34,0x0, 0x60,0x12,0xf, +0x45,0xa9,0xc6,0xcb,0x22,0xa9,0xd7,0xcb,0x7d,0x23,0x4e,0x50,0x1, 0x7e,0xf, 0x33, +0xfc,0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, 0x30,0x80,0x1e,0x7e,0xf, 0x33,0xfc,0xb, +0xa, 0x30,0x7d,0x23,0x5e,0x24,0x0, 0x8, 0xbe,0x24,0x0, 0x8, 0x78,0xb, 0xa9,0xd7, +0xcb,0x4e,0x70,0x4, 0x1b,0xa, 0x30,0xd2,0x1e,0x7e,0xf, 0x33,0xfc,0xb, 0xa, 0x30, +0x7d,0x23,0x5e,0x24,0x80,0x0, 0xbe,0x24,0x80,0x0, 0x78,0xcf,0x4e,0x60,0x40,0x1b, +0xa, 0x30,0x6d,0x11,0x7e,0x1f,0x33,0xfc,0x1b,0x1a,0x10,0x22,0xca,0x3b,0xf5,0x24, +0x7f,0x41,0x7f,0x30,0xe5,0x25,0x7e,0x8, 0x0, 0x26,0x12,0x1, 0x20,0x6c,0xaa,0x80, +0x36,0xa, 0x3a,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0xbe,0xb1,0x27,0x40,0xd, 0x74, +0x1c,0xa, 0x4a,0x7f,0x3, 0x2d,0x14,0x7a,0xb, 0xb0,0x80,0x19,0x7e,0x1b,0xb0,0xa, +0x3b,0x2e,0x35,0x2a,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0xa, 0x4a,0x7f,0x13, +0x2d,0x34,0x7a,0x1b,0xb0,0xb, 0xa0,0xe5,0x24,0xbc,0xba,0x38,0xc4,0xda,0x3b,0x22, +0x5, 0x63,0x31,0x20,0x18,0x13,0xf, 0xd, 0xc, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, +0xca,0xf8,0x7d,0xe2,0x7d,0xd3,0x7c,0xfb,0xbe,0x30,0x1, 0x28,0x6, 0x7e,0xf4,0x0, +0x10,0x80,0xf, 0xbe,0x30,0x0, 0x28,0x6, 0x7e,0xf4,0x0, 0x8, 0x80,0x4, 0x7e,0xf4, +0x0, 0x4, 0x7d,0x1f,0x6d,0x0, 0x6d,0x33,0x7e,0x24,0x0, 0x10,0x12,0x1f,0x58,0x7f, +0x1, 0x7d,0x3d,0x6d,0x22,0x12,0x1e,0xeb,0x7d,0x1e,0x12,0x1f,0x5, 0x74,0x4, 0xac, +0xbf,0x7e,0xf, 0x39,0xc9,0x2d,0x15,0x79,0x30,0x0, 0x82,0x79,0x20,0x0, 0x80,0xda, +0xf8,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca,0xb, +0xc0,0xd0,0xc0,0x83,0xc0,0x82,0xd2,0x1d,0x7e,0xf, 0x39,0xf8,0xb, 0xa, 0x30,0x7c, +0x57,0x7a,0x53,0x39,0xf3,0x4e,0x70,0xc, 0x1b,0xa, 0x30,0xc2,0xc6,0x6d,0x33,0x7e, +0xf, 0x39,0xf8,0x79,0x30,0x0, 0xe, 0x12,0x12,0x9e,0x12,0x69,0x5, 0xd0,0x82,0xd0, +0x83,0xd0,0xd0,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda, +0x7b,0x32,0x74,0x3, 0x12,0x13,0x56,0xa9,0xd1,0xc4,0x7e,0xf, 0x39,0xc1,0x2e,0x14, +0x0, 0x84,0xb, 0xa, 0x30,0x4e,0x70,0x20,0x1b,0xa, 0x30,0x7e,0x14,0x0, 0x1, 0x7e, +0x1f,0x39,0xc1,0x1b,0x1a,0x10,0x7e,0xf, 0x39,0xc9,0xb, 0x16,0xb, 0xa, 0x30,0x4e, +0x70,0x1, 0x1b,0xa, 0x30,0xc2,0xf, 0xe4,0x7a,0xb3,0x39,0xd9,0x7e,0x1f,0x39,0xc1, +0xb, 0x1a,0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0x74,0x2, 0x2, 0x13,0x56,0x7c,0x6b, +0x6c,0xaa,0x80,0x17,0x7e,0x90,0x2, 0xac,0x9a,0x7e,0x7f,0x39,0xf4,0x2d,0xf4,0xb, +0x7a,0x20,0x7f,0x70,0x2d,0xf4,0x1b,0x7a,0x20,0xb, 0xa0,0xbc,0x7a,0x38,0xe5,0x6c, +0xaa,0x80,0x20,0x7e,0x50,0x2, 0xac,0x5a,0x7e,0x7f,0x39,0xf4,0x2d,0xf2,0x69,0x27, +0x0, 0x38,0xa, 0xf7,0xa, 0x4a,0x2d,0x4f,0x3e,0x44,0x7f,0x70,0x2d,0xf4,0x1b,0x7a, +0x20,0xb, 0xa0,0xbc,0x6a,0x38,0xdc,0x22,0xca,0x79,0x7c,0xab,0x5e,0xa0,0x3, 0x6c, +0x77,0x7e,0x50,0x2, 0xac,0x57,0x7f,0x60,0x2d,0xd2,0x29,0x66,0x0, 0x1, 0xa, 0xf6, +0x7d,0x4f,0x7c,0x89,0x6c,0x99,0x7d,0xf4,0x7e,0x6b,0x60,0xa, 0x46,0x2d,0x4f,0x7e, +0xf0,0xf0,0xac,0xfa,0x2d,0x27,0x7e,0x7f,0x39,0xf4,0x2d,0xf2,0x79,0x47,0x2, 0x54, +0xb, 0x70,0xbe,0x70,0xe, 0x40,0xca,0xda,0x79,0x22,0x29,0x50,0x0, 0xf5,0xac,0x5b, +0x7e,0xf, 0x39,0xc9,0x69,0x30,0x0, 0xc, 0xa, 0x56,0x3e,0x54,0xbe,0x24,0x2, 0x0, +0x40,0x4, 0x7e,0x24,0x1, 0xff,0xbd,0x25,0x28,0x1f,0x2e,0x14,0x0, 0xc, 0x6c,0x66, +0x1b,0xa, 0x30,0x1e,0x24,0x7c,0x45,0x6c,0x55,0x7e,0xf, 0x39,0xc9,0x2e,0x14,0x0, +0xc, 0xb, 0xa, 0x30,0x4d,0x32,0x1b,0xa, 0x30,0x22,0x7c,0x6b,0x6c,0xaa,0x7e,0x50, +0x28,0xac,0x57,0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x42,0x7e,0x50,0xf0,0xac,0x56,0x2d, +0x24,0x7e,0x7f,0x39,0xf4,0x2d,0xf2,0x69,0x27,0x1, 0x8c,0x6c,0x44,0xa, 0x4a,0x7f, +0x60,0x2d,0xd4,0x7e,0x6b,0xb0,0x7c,0x8b,0x6c,0x99,0x4d,0x24,0x79,0x27,0x1, 0x8c, +0xb, 0xa0,0xbe,0xa0,0xe, 0x40,0xc7,0x22,0x7c,0x6b,0x6c,0xaa,0x7e,0x50,0x28,0xac, +0x57,0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x42,0x7e,0x50,0xf0,0xac,0x56,0x2d,0x24,0x7e, +0x7f,0x39,0xf4,0x2d,0xf2,0x69,0x27,0x1, 0x8c,0x6c,0x55,0xa, 0x4a,0x7f,0x60,0x2d, +0xd4,0x7e,0x6b,0xb0,0xa, 0x4b,0x4d,0x24,0x79,0x27,0x1, 0x8c,0xb, 0xa0,0xbe,0xa0, +0xe, 0x40,0xc9,0x22,0xa9,0xd6,0xcb,0x54,0x3f,0x5e,0x70,0x1f,0x7c,0x2b,0x6c,0x33, +0x3e,0x14,0x3e,0x14,0x2e,0x14,0x0, 0x5, 0xa, 0x37,0x3e,0x34,0x3e,0x34,0x3e,0x34, +0x3e,0x34,0x3e,0x34,0x2d,0x31,0x7e,0xf, 0x33,0xfc,0x79,0x30,0x0, 0x2, 0x7e,0xf, +0x33,0xfc,0x79,0x20,0x0, 0x14,0xa9,0xc6,0xcb,0x22,0x7d,0x23,0x6c,0x66,0x7e,0x30, +0x2, 0xac,0x36,0x2e,0x14,0x20,0x99,0x7a,0x31,0x82,0x7a,0x21,0x83,0xe4,0x93,0xa, +0x1b,0xbd,0x12,0x28,0x7, 0xb, 0x60,0xbe,0x60,0x14,0x40,0xe2,0x7e,0x70,0x2, 0xac, +0x67,0x2e,0x34,0x20,0x9a,0x7a,0x71,0x82,0x7a,0x61,0x83,0xe4,0x93,0x22,0x7e,0xf, +0x39,0xc1,0x2e,0x14,0x0, 0x84,0xb, 0xa, 0x30,0x5e,0x70,0xdf,0x1b,0xa, 0x30,0x74, +0x3, 0x12,0x13,0x56,0x7e,0x14,0x0, 0x3, 0x7e,0x1f,0x39,0xc1,0x1b,0x1a,0x10,0x7e, +0x1f,0x39,0xc1,0xb, 0x1a,0x30,0x5e,0x34,0x0, 0x1, 0x78,0xf3,0xe4,0x2, 0x13,0x56, +0x2e,0x34,0x4, 0x0, 0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x60,0x7e,0x34,0x4, 0x0, +0x9d,0x32,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x62,0x7e,0x34,0x0, 0x1, 0x7e,0xf, +0x39,0xc9,0x79,0x30,0x0, 0x64,0xa, 0x3b,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, 0x66, +0x22,0x7c,0xa5,0xbe,0x34,0x0, 0x0, 0x28,0x10,0xa, 0x1b,0x3e,0x14,0x7d,0x23,0x7c, +0x45,0x6c,0x55,0x2d,0x21,0xa, 0x3a,0x80,0x8, 0xa, 0x2b,0x3e,0x24,0x7c,0x67,0x6c, +0x77,0x2d,0x32,0x7e,0xf, 0x39,0xf8,0x79,0x30,0x0, 0x4, 0x22,0x7c,0xa7,0x7e,0x1f, +0x39,0xc1,0x69,0x41,0x0, 0x8a,0x5e,0x44,0x10,0xf, 0xa, 0x1a,0x3e,0x14,0x3e,0x14, +0x3e,0x14,0x3e,0x14,0xa, 0x5b,0xc4,0x23,0x54,0xe0,0x7c,0xab,0xe4,0x2d,0x51,0x4d, +0x45,0x79,0x41,0x0, 0x8a,0x22,0x7e,0xf, 0x39,0xc1,0x69,0x30,0x0, 0x84,0x5e,0x70, +0xe7,0x1b,0xb1,0x68,0xc, 0x14,0x68,0xc, 0xb, 0xb1,0x78,0x5, 0x4e,0x70,0x10,0x80, +0x3, 0x4e,0x70,0x8, 0x79,0x30,0x0, 0x84,0x22,0x7e,0x34,0x0, 0x1f,0x7e,0xf, 0x39, +0xc9,0x79,0x30,0x0, 0x4, 0xa9,0xd2,0xcd,0x7e,0xf, 0x39,0xc9,0xb, 0xa, 0x30,0x4e, +0x70,0x1, 0x1b,0xa, 0x30,0x22,0xbe,0xb0,0x0, 0x28,0xa, 0xa9,0xd7,0xca,0xa9,0xd3, +0xcb,0xa9,0xd2,0xcb,0x22,0xa9,0xc7,0xca,0xa9,0xc3,0xcb,0xa9,0xc2,0xcb,0x22,0x30, +0x1, 0xa, 0x54,0x3, 0xa, 0x3b,0x2e,0x34,0x2, 0x0, 0x80,0x2, 0x6d,0x33,0x7e,0xf, +0x39,0xc9,0x79,0x30,0x0, 0x3a,0x22,0x7e,0xf, 0x39,0xc1,0x69,0x30,0x0, 0x8a,0x60, +0x5, 0x4e,0x60,0x10,0x80,0x3, 0x5e,0x60,0xef,0x79,0x30,0x0, 0x8a,0x22,0xbe,0xb0, +0x0, 0x28,0x9, 0xa9,0xd6,0xca,0xd2,0xcd,0xa9,0xd1,0xcb,0x22,0xa9,0xc6,0xca,0xc2, +0xcd,0xa9,0xc1,0xcb,0x22,0x7e,0x34,0x0, 0xf, 0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, +0x4, 0xc2,0xc3,0xd2,0xeb,0x22,0x6, 0xe, 0x15,0x1a,0x1f,0x26,0x2b,0x2d,0x2e,0x2f, +0x2c,0x2a,0x24,0x1f,0x1a,0x14,0xf, 0x8, 0x3, 0x3, 0x6, 0xb, 0x10,0x15,0x1c,0x22, +0x28,0x2d,0x34,0x39,0x3d,0x40,0xe, 0x3, 0x0, 0x0, 0x0, 0x3, 0x8, 0xc, 0x11,0x16, +0x1c,0x23,0x2b,0x32,0x37,0x3c,0x40,0x45,0x4a,0x4d,0x4c,0x4b,0x4a,0x48,0x46,0x46, +0x45,0x45,0x44,0x44,0x43,0x44,0x45,0x78,0x65,0x55,0x2, 0xd, 0x14,0x1b,0x21,0x25, +0x2b,0x31,0x37,0x36,0x33,0x2d,0x28,0x20,0x19,0x14,0xd, 0x8, 0x1, 0x2, 0x5, 0xb, +0x10,0x18,0x1e,0x23,0x2a,0x30,0x35,0x3a,0x3e,0x3f,0x0, 0x1, 0x1, 0x0, 0x0, 0x0, +0x0, 0x0, 0x1, 0x4, 0x9, 0xf, 0x15,0x1d,0x24,0x2a,0x30,0x35,0x3b,0x3e,0x3f,0x40, +0x3f,0x3e,0x3d,0x3d,0x3c,0x3c,0x3b,0x3b,0x39,0x37,0x1a,0x2d,0x65,0x55,0x1b,0x29, +0x27,0x1e,0x14,0x11,0x1a,0x26,0x2e,0x37,0x3d,0x3f,0x3d,0x37,0x2e,0x21,0x16,0xc, +0x5, 0x1, 0x0, 0x0, 0x1, 0x3, 0xa, 0x13,0x1d,0x26,0x2e,0x33,0x38,0x3a,0x16,0x21, +0x2b,0x32,0x30,0x2a,0x27,0x2a,0x2f,0x2d,0x24,0x1a,0x10,0x7, 0x1, 0x0, 0x2, 0x7, +0x10,0x19,0x23,0x2d,0x36,0x41,0x49,0x4c,0x4a,0x45,0x3c,0x34,0x2a,0x27,0x51,0x71, +0x50,0x55,0x28,0x12,0x11,0x18,0x23,0x29,0x2b,0x2a,0x2e,0x35,0x3c,0x3e,0x3f,0x39, +0x31,0x28,0x1e,0x15,0xe, 0x6, 0x3, 0x1, 0x0, 0x0, 0x3, 0xc, 0x16,0x20,0x2b,0x32, +0x37,0x39,0x20,0x29,0x32,0x37,0x31,0x28,0x21,0x2a,0x31,0x2d,0x23,0x1b,0x13,0x8, +0x1, 0x0, 0x1, 0x5, 0xc, 0x18,0x20,0x29,0x34,0x3e,0x47,0x4f,0x50,0x4d,0x45,0x3c, +0x34,0x31,0x26,0xcb,0x50,0x55,0x1d,0x2f,0x2c,0x25,0x1a,0x1b,0x20,0x29,0x31,0x31, +0x2e,0x2d,0x35,0x3d,0x3f,0x3d,0x38,0x2c,0x22,0x15,0xd, 0x6, 0x1, 0x0, 0x1, 0x6, +0x10,0x1b,0x24,0x2f,0x38,0x3d,0xd, 0x1b,0x27,0x31,0x32,0x28,0x1e,0x14,0x15,0x1d, +0x28,0x31,0x34,0x2a,0x1f,0x14,0x9, 0x1, 0x0, 0x4, 0xd, 0x17,0x21,0x2c,0x35,0x40, +0x47,0x47,0x44,0x3c,0x34,0x30,0x1b,0x82,0x50,0x55,0x19,0x2e,0x2a,0x1f,0x18,0x1b, +0x22,0x2d,0x30,0x2e,0x2e,0x35,0x3d,0x3f,0x3d,0x3a,0x2f,0x24,0x18,0xf, 0x7, 0x1, +0x0, 0x0, 0x3, 0xb, 0x16,0x1e,0x29,0x32,0x3a,0x3d,0x11,0x1f,0x28,0x32,0x30,0x26, +0x1b,0x14,0x1c,0x25,0x2e,0x35,0x2e,0x23,0x19,0x11,0x4, 0x0, 0x1, 0x8, 0x10,0x1c, +0x25,0x30,0x38,0x40,0x42,0x3f,0x39,0x32,0x2c,0x27,0xc0,0xd1,0x50,0x55,0x18,0x2c, +0x29,0x1e,0x14,0x13,0x16,0x1e,0x29,0x30,0x2e,0x2c,0x2b,0x37,0x3d,0x3f,0x3e,0x39, +0x30,0x25,0x1b,0x10,0x8, 0x1, 0x0, 0x2, 0x9, 0x13,0x1f,0x2d,0x38,0x3c,0x11,0x1a, +0x23,0x2f,0x33,0x29,0x20,0x16,0xe, 0x13,0x1d,0x28,0x32,0x31,0x28,0x1e,0x16,0xb, +0x2, 0x0, 0x1, 0x8, 0x12,0x1e,0x29,0x33,0x3b,0x3f,0x3c,0x32,0x29,0x26,0x30,0x6e, +0x50,0x55,0x16,0x2b,0x24,0x17,0xd, 0xa, 0xe, 0x15,0x24,0x28,0x25,0x23,0x2b,0x36, +0x3b,0x3d,0x3b,0x37,0x2b,0x20,0x15,0xb, 0x4, 0x0, 0x0, 0x3, 0xe, 0x19,0x27,0x33, +0x3d,0x3f,0x13,0x21,0x2e,0x37,0x3a,0x31,0x27,0x1c,0x13,0x1c,0x28,0x34,0x3e,0x37, +0x2d,0x22,0x18,0xc, 0x1, 0x0, 0x3, 0xd, 0x18,0x25,0x31,0x3c,0x47,0x48,0x42,0x38, +0x2e,0x2a,0x31,0x62,0x50,0x55,0x35,0x2e,0x27,0x22,0x1f,0x1b,0x16,0x10,0xc, 0x8, +0x6, 0x4, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x6, 0xb, 0xe, 0x12,0x17,0x1d,0x22,0x26, +0x2a,0x30,0x35,0x39,0x3d,0x3f,0x0, 0x0, 0x1, 0x4, 0x6, 0x8, 0xb, 0x10,0x16,0x1b, +0x1f,0x23,0x28,0x2d,0x32,0x36,0x3b,0x40,0x44,0x48,0x4a,0x4b,0x4c,0x4b,0x4a,0x48, +0x46,0x43,0x40,0x3e,0x3c,0x3a,0x3c,0x9c,0x34,0x55,0x9, 0x17,0x1d,0x26,0x2e,0x37, +0x3c,0x3f,0x3b,0x33,0x2b,0x22,0x1a,0x11,0xb, 0x5, 0x3, 0x1, 0x1, 0x0, 0x0, 0x0, +0x1, 0x6, 0xa, 0x11,0x19,0x22,0x2a,0x32,0x39,0x3d,0x30,0x30,0x2f,0x2c,0x26,0x1e, +0x17,0xd, 0x5, 0x0, 0x0, 0x1, 0x6, 0xe, 0x15,0x1e,0x26,0x2c,0x32,0x3a,0x41,0x48, +0x50,0x5b,0x61,0x64,0x64,0x60,0x5b,0x56,0x51,0x4f,0xd8,0x2c,0x33,0x55,0x26,0x1c, +0x19,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x17,0x17,0x15,0xf, 0x9, 0x4, 0x1, 0x0, +0x0, 0x0, 0x0, 0x1, 0x4, 0xb, 0x12,0x18,0x1f,0x28,0x31,0x37,0x3c,0x40,0x1, 0x7, +0xe, 0x14,0x1c,0x23,0x2c,0x34,0x3e,0x44,0x4c,0x54,0x5b,0x60,0x5d,0x55,0x4f,0x49, +0x43,0x3d,0x38,0x32,0x2b,0x26,0x22,0x1f,0x1e,0x1c,0x1c,0x1c,0x1c,0x1d,0x66,0x54, +0x74,0x55,0x3e,0x2c,0x21,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d, +0x1e,0x1e,0x1d,0x1a,0x11,0xc, 0x7, 0x2, 0x0, 0x0, 0x3, 0xa, 0x12,0x1c,0x23,0x2c, +0x38,0x40,0xc, 0x0, 0x6, 0xf, 0x17,0x22,0x29,0x32,0x3b,0x41,0x47,0x4f,0x55,0x5c, +0x66,0x71,0x79,0x3e,0x76,0x6d,0x64,0x5a,0x52,0x4b,0x42,0x39,0x35,0x33,0x32,0x32, +0x31,0x31,0xf3,0xdb,0x74,0x55,0x9, 0x7, 0x6, 0x6, 0x5, 0x5, 0x4, 0x4, 0x4, 0x4, +0x3, 0x2, 0x2, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xa, 0x10,0x14,0x1b,0x22, +0x28,0x2e,0x34,0x39,0x3d,0x40,0x0, 0xb, 0x11,0x16,0x1b,0x22,0x28,0x2c,0x33,0x39, +0x40,0x46,0x4d,0x52,0x56,0x5c,0x61,0x68,0x6d,0x73,0x73,0x71,0x71,0x71,0x70,0x70, +0x6f,0x6f,0x6f,0x6f,0x6d,0x6e,0x79,0x80,0x44,0x55,0x17,0x13,0x12,0x12,0x11,0x10, +0xf, 0xd, 0xc, 0xb, 0x9, 0x8, 0x7, 0x4, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x1, 0x4, +0xb, 0x10,0x16,0x1d,0x24,0x29,0x31,0x39,0x3d,0x40,0x0, 0xe, 0x16,0x1a,0x1f,0x24, +0x29,0x2e,0x33,0x38,0x3e,0x43,0x47,0x50,0x55,0x59,0x62,0x69,0x6e,0x75,0x7c,0xff, +0x7d,0x7c,0x79,0x73,0x6d,0x68,0x60,0x5a,0x57,0x56,0x5d,0x8, 0x44,0x55,0x0, 0x7, +0xb, 0xd, 0x10,0x12,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x19,0x1c,0x1e,0x20,0x22, +0x23,0x25,0x27,0x29,0x2b,0x30,0x32,0x33,0x35,0x38,0x39,0x3b,0x3d,0x3f,0x3e,0x29, +0x1f,0x18,0xf, 0x7, 0x6, 0xc, 0x12,0x1d,0x25,0x2d,0x36,0x3e,0x3b,0x35,0x2c,0x26, +0x20,0x19,0x11,0xa, 0x3, 0x3, 0x9, 0x10,0x18,0x24,0x2c,0x33,0x3a,0x3e,0x60,0x9b, +0x32,0x55,0x0, 0x5, 0x5, 0x5, 0x4, 0x3, 0x2, 0x3, 0x5, 0x7, 0xa, 0xe, 0x11,0x19, +0x1b,0x1c,0x1d,0x1c,0x1c,0x1d,0x1f,0x22,0x25,0x2a,0x31,0x33,0x35,0x37,0x38,0x39, +0x3c,0x40,0x0, 0x12,0x1c,0x24,0x2b,0x34,0x3c,0x39,0x2f,0x29,0x21,0x16,0xf, 0xd, +0x14,0x1e,0x2a,0x33,0x31,0x27,0x20,0x18,0x10,0x7, 0xa, 0x10,0x1a,0x26,0x2f,0x37, +0x3d,0x3f,0xfb,0x8f,0x32,0x55,0x2c,0x23,0x1f,0x19,0x13,0xc, 0x7, 0x3, 0x0, 0x0, +0x0, 0x1, 0x5, 0xa, 0xf, 0x16,0x1d,0x23,0x2a,0x30,0x36,0x3b,0x3e,0x40,0x3f,0x3e, +0x3b,0x38,0x33,0x2f,0x2b,0x28,0x9, 0x1, 0x0, 0x1, 0x3, 0x9, 0xe, 0x14,0x1b,0x21, +0x27,0x2e,0x36,0x3b,0x3e,0x41,0x41,0x40,0x3d,0x3a,0x36,0x2f,0x2b,0x26,0x20,0x1c, +0x16,0x10,0xc, 0xa, 0x9, 0xb, 0x36,0xdc,0x30,0x55,0x1a,0x9, 0x5, 0x1, 0x0, 0x0, +0x0, 0x2, 0x5, 0x9, 0xf, 0x16,0x1c,0x22,0x2a,0x31,0x36,0x39,0x3c,0x3e,0x3f,0x3f, +0x3d,0x38,0x30,0x27,0x1f,0x18,0x12,0xb, 0x6, 0x5, 0x7, 0x12,0x19,0x22,0x2c,0x36, +0x3f,0x49,0x53,0x5c,0x63,0x66,0x64,0x5f,0x58,0x4c,0x43,0x3d,0x34,0x2b,0x22,0x1b, +0x15,0xb, 0x4, 0x0, 0x0, 0x1, 0x4, 0xb, 0x13,0x18,0xf1,0xc, 0x30,0x55,0x18,0x2c, +0x34,0x39,0x3c,0x3d,0x3f,0x3f,0x3f,0x3d,0x3b,0x36,0x30,0x2a,0x24,0x1c,0x16,0xd, +0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x5, 0x9, 0xf, 0x17,0x1e,0x24,0x1, 0x2, +0x8, 0xe, 0x14,0x1a,0x21,0x28,0x30,0x37,0x40,0x49,0x50,0x55,0x59,0x5c,0x5c,0x58, +0x51,0x48,0x3f,0x38,0x31,0x2b,0x25,0x1d,0x17,0x11,0xa, 0x4, 0x1, 0x1, 0x9d,0xbf, +0x30,0x55,0x16,0x7, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x4, 0x8, 0xe, 0x16,0x1f,0x28, +0x30,0x38,0x3c,0x3e,0x3f,0x40,0x3f,0x3f,0x3d,0x3b,0x37,0x32,0x2c,0x25,0x1d,0x16, +0xf, 0xc, 0x53,0x46,0x3e,0x35,0x2e,0x27,0x20,0x1a,0x14,0xd, 0x6, 0x1, 0x0, 0x0, +0x3, 0xa, 0x13,0x1a,0x20,0x27,0x2d,0x33,0x3a,0x40,0x48,0x4f,0x54,0x58,0x5a,0x5a, +0x58,0x57,0xc6,0x55,0x30,0x55,0x7, 0x1, 0x4, 0xa, 0x10,0x18,0x20,0x2a,0x32,0x38, +0x3c,0x3e,0x3f,0x3e,0x3d,0x3b,0x39,0x35,0x30,0x27,0x21,0x19,0x12,0xb, 0x6, 0x3, +0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32,0x1d,0x12,0x9, 0x5, 0x1, 0x0, 0x0, 0x1, 0x5, +0xd, 0x17,0x20,0x2a,0x32,0x3b,0x45,0x4e,0x58,0x63,0x69,0x6b,0x6a,0x64,0x5d,0x57, +0x4f,0x47,0x40,0x38,0x32,0x2f,0x1a,0xb5,0x30,0x55,0x21,0x13,0xc, 0x8, 0x5, 0x2, +0x1, 0x0, 0x0, 0x1, 0x3, 0x8, 0xf, 0x17,0x1e,0x24,0x2b,0x32,0x39,0x3d,0x3e,0x3f, +0x3f,0x3d,0x3a,0x36,0x30,0x29,0x21,0x1a,0x16,0x13,0x5, 0x9, 0xe, 0x14,0x1a,0x22, +0x29,0x30,0x38,0x3f,0x47,0x4d,0x51,0x51,0x4f,0x4d,0x49,0x42,0x39,0x31,0x2b,0x25, +0x1e,0x17,0x10,0x8, 0x3, 0x0, 0x0, 0x1, 0x3, 0x5, 0xaf,0x13,0x30,0x55,0x38,0x3f, +0x3d,0x3a,0x36,0x2e,0x26,0x1f,0x14,0xb, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x2, 0x5, +0x9, 0xe, 0x14,0x1c,0x23,0x2a,0x34,0x38,0x3a,0x3b,0x3d,0x3d,0x3d,0x3d,0x29,0x1a, +0x10,0x9, 0x4, 0x0, 0x0, 0x1, 0x4, 0xc, 0x14,0x1c,0x22,0x28,0x2f,0x37,0x3f,0x47, +0x4f,0x56,0x5a,0x5b,0x59,0x56,0x4e,0x47,0x40,0x37,0x30,0x28,0x22,0x1f,0x2a,0xa9, +0x30,0x55,0x3e,0x3b,0x38,0x33,0x2b,0x24,0x1d,0x16,0x10,0x7, 0x3, 0x1, 0x0, 0x0, +0x0, 0x1, 0x1, 0x3, 0x6, 0xc, 0x15,0x1c,0x23,0x29,0x2f,0x35,0x38,0x3b,0x3c,0x3e, +0x3f,0x3f,0x1f,0x10,0xa, 0x6, 0x0, 0x0, 0x0, 0x2, 0x4, 0xc, 0x12,0x18,0x1e,0x25, +0x2c,0x35,0x3c,0x42,0x4a,0x51,0x56,0x56,0x53,0x4e,0x49,0x40,0x3a,0x33,0x2c,0x25, +0x1f,0x1c,0xf9,0xa2,0x30,0x55,0x1f,0x2b,0x31,0x35,0x38,0x3b,0x3e,0x3f,0x3f,0x3d, +0x3a,0x34,0x2d,0x27,0x23,0x1d,0x17,0x10,0x9, 0x4, 0x1, 0x0, 0x0, 0x1, 0x3, 0x6, +0xa, 0xf, 0x15,0x1b,0x20,0x23,0x45,0x42,0x3e,0x38,0x34,0x2d,0x24,0x1c,0x15,0x11, +0xb, 0x6, 0x2, 0x0, 0x0, 0x0, 0x1, 0x3, 0x7, 0xd, 0x12,0x18,0x20,0x28,0x30,0x36, +0x3c,0x42,0x47,0x48,0x49,0x4a,0x65,0x9d,0x30,0x55,0x1c,0x2a,0x33,0x39,0x3c,0x3e, +0x3f,0x3f,0x3e,0x3d,0x3a,0x35,0x2e,0x28,0x23,0x1c,0x15,0xf, 0x9, 0x4, 0x1, 0x0, +0x0, 0x1, 0x1, 0x4, 0x8, 0xd, 0x13,0x19,0x1e,0x22,0x40,0x3e,0x3a,0x33,0x2f,0x29, +0x22,0x1b,0x15,0x10,0xa, 0x5, 0x1, 0x0, 0x0, 0x1, 0x2, 0x5, 0xa, 0x11,0x17,0x1c, +0x24,0x2a,0x30,0x35,0x3b,0x40,0x43,0x44,0x45,0x45,0xcb,0xc6,0x30,0x55,0x5, 0x3, +0x4, 0x7, 0xa, 0x10,0x17,0x21,0x28,0x2e,0x33,0x38,0x3c,0x3e,0x3f,0x3f,0x3e,0x3b, +0x38,0x31,0x29,0x21,0x18,0xf, 0x9, 0x4, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26,0x35, +0x3d,0x45,0x4b,0x51,0x53,0x52,0x4f,0x4c,0x46,0x41,0x3b,0x34,0x2e,0x25,0x1e,0x17, +0x11,0x9, 0x3, 0x0, 0x0, 0x2, 0x6, 0xc, 0x12,0x18,0x1e,0x24,0x2c,0x31,0xf4,0xb6, +0x30,0x55,0xa, 0x5, 0x5, 0x5, 0x8, 0xf, 0x16,0x20,0x29,0x31,0x36,0x3a,0x3c,0x3e, +0x3f,0x3f,0x3e,0x3c,0x3a,0x33,0x2d,0x24,0x1c,0x14,0xf, 0x8, 0x4, 0x0, 0x0, 0x0, +0x1, 0x2, 0x35,0x46,0x4e,0x56,0x5d,0x65,0x68,0x66,0x60,0x57,0x4f,0x47,0x3f,0x37, +0x2e,0x25,0x1e,0x16,0x10,0x6, 0x2, 0x0, 0x1, 0x5, 0xb, 0x15,0x1d,0x28,0x2f,0x39, +0x41,0x45,0xf0,0xbc,0x30,0x55,0x7, 0x3, 0x3, 0x3, 0x4, 0x7, 0xf, 0x17,0x20,0x28, +0x30,0x36,0x3b,0x3d,0x3f,0x3f,0x3d,0x39,0x36,0x2d,0x25,0x1d,0x16,0xd, 0x8, 0x2, +0x0, 0x0, 0x1, 0x2, 0x3, 0x5, 0x2e,0x3f,0x48,0x50,0x59,0x5f,0x67,0x68,0x63,0x5d, +0x52,0x4a,0x3e,0x35,0x2b,0x20,0x18,0x10,0xa, 0x3, 0x0, 0x0, 0x1, 0x7, 0xe, 0x19, +0x22,0x2b,0x31,0x3a,0x42,0x47,0xef,0xc9,0x30,0x55,0x3b,0x3c,0x3c,0x3b,0x39,0x36, +0x2f,0x27,0x21,0x19,0x11,0xb, 0x5, 0x1, 0x0, 0x0, 0x1, 0x2, 0x4, 0x6, 0xa, 0x10, +0x16,0x1f,0x26,0x2d,0x33,0x39,0x3c,0x3e,0x3f,0x3f,0x22,0x31,0x3b,0x41,0x47,0x4d, +0x56,0x59,0x5a,0x58,0x55,0x51,0x4b,0x43,0x3d,0x35,0x29,0x20,0x18,0x11,0x9, 0x3, +0x0, 0x0, 0x1, 0x3, 0x7, 0xf, 0x15,0x1b,0x21,0x26,0x2b,0xa0,0x30,0x55,0x37,0x38, +0x37,0x34,0x2d,0x26,0x1c,0x16,0xe, 0x9, 0x4, 0x2, 0x0, 0x0, 0x0, 0x1, 0x2, 0x5, +0xa, 0x10,0x17,0x20,0x26,0x2e,0x35,0x3a,0x3c,0x3e,0x3f,0x3f,0x3e,0x3e,0x30,0x40, +0x49,0x50,0x59,0x5e,0x60,0x5d,0x56,0x50,0x47,0x41,0x39,0x33,0x2a,0x20,0x1a,0x10, +0xa, 0x5, 0x1, 0x0, 0x0, 0x3, 0x8, 0x10,0x17,0x1f,0x25,0x2f,0x38,0x3c,0x37,0xc3, +0x30,0x55,0x3b,0x3d,0x3d,0x3b,0x38,0x32,0x27,0x1c,0x13,0xe, 0x8, 0x3, 0x0, 0x0, +0x0, 0x1, 0x3, 0x7, 0xb, 0x12,0x18,0x20,0x28,0x31,0x39,0x3d,0x3f,0x40,0x3f,0x3f, +0x3e,0x3e,0x33,0x45,0x4e,0x57,0x5d,0x65,0x6c,0x6a,0x66,0x63,0x5c,0x53,0x4a,0x40, +0x38,0x2e,0x25,0x1a,0x11,0x8, 0x4, 0x0, 0x0, 0x2, 0x9, 0x10,0x19,0x21,0x2a,0x32, +0x39,0x3e,0x7, 0x90,0x30,0x55,0x39,0x2b,0x24,0x1c,0x15,0xe, 0x9, 0x6, 0x5, 0x6, +0x9, 0x10,0x19,0x22,0x27,0x2e,0x35,0x3b,0x3e,0x3f,0x3d,0x38,0x32,0x2c,0x26,0x1f, +0x19,0x13,0xb, 0x5, 0x1, 0x0, 0x6, 0x0, 0x1, 0x2, 0x6, 0xb, 0x11,0x17,0x1d,0x24, +0x2a,0x2f,0x32,0x34,0x35,0x36,0x37,0x3b,0x41,0x47,0x4e,0x56,0x5d,0x61,0x64,0x65, +0x65,0x63,0x60,0x5c,0x57,0x54,0xd1,0x4a,0x46,0x55,0x0, 0x1, 0x3, 0x5, 0x7, 0x8, +0xa, 0xb, 0xc, 0xe, 0xf, 0x11,0x12,0x14,0x16,0x1a,0x1e,0x22,0x24,0x27,0x2a,0x2c, +0x2e,0x31,0x33,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x3f,0x1, 0xe, 0x14,0x1b,0x23,0x28, +0x2e,0x35,0x3a,0x40,0x48,0x4f,0x56,0x5d,0x62,0x61,0x5a,0x53,0x4e,0x47,0x40,0x3b, +0x35,0x2d,0x29,0x22,0x1b,0x17,0x10,0x9, 0x5, 0x1, 0x6d,0x7d,0x54,0x55,0x0, 0x2, +0x3, 0x5, 0x6, 0x8, 0xb, 0x10,0x13,0x16,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x22,0x22, +0x22,0x22,0x23,0x25,0x28,0x2e,0x31,0x34,0x36,0x38,0x3a,0x3c,0x3e,0x3f,0x6, 0x17, +0x20,0x27,0x30,0x38,0x3e,0x39,0x32,0x2b,0x25,0x1e,0x18,0x10,0x9, 0x9, 0x10,0x18, +0x1f,0x26,0x2f,0x36,0x3c,0x38,0x2f,0x27,0x1f,0x18,0xf, 0x8, 0x1, 0x2, 0xc7,0x75, +0x31,0x55,0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x8, 0xd, 0x12,0x15,0x17,0x18,0x1a, +0x1b,0x1c,0x1d,0x1d,0x1e,0x1f,0x22,0x27,0x2e,0x35,0x38,0x3b,0x3d,0x3e,0x3f,0x40, +0x3f,0x3e,0x6, 0x15,0x1b,0x23,0x29,0x2f,0x37,0x3c,0x37,0x2e,0x27,0x20,0x1a,0x13, +0xe, 0x14,0x1a,0x21,0x27,0x2f,0x38,0x3f,0x3d,0x35,0x2e,0x26,0x20,0x18,0x11,0xb, +0x3, 0x0, 0x67,0x3f,0x31,0x55,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, +0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x1c,0x1d,0x1e,0x1f,0x20, +0x21,0x22,0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11, +0x12,0x13,0x14,0x15,0x16,0x17,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xe, +0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x0, 0x1, 0x2, 0x3, 0x4, 0x1c,0x1d,0x1e, +0x1f,0x20,0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, +0x18,0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11, +0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x6, 0x5, 0x4, 0x3, 0x2, 0x1, +0x0, 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x0, 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, +0x7, 0x8, 0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, +0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16, +0x17,0x18,0x19,0x1a,0x1b,0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, +0xb, 0xc, 0xd, 0xe, 0xf, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, +0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x0, 0x1, 0x1, 0x1, 0x10,0x1c,0x2, 0x10, +0x1c,0x0, 0x1, 0x1, 0x4, 0xf, 0x1c,0x0, 0x1, 0x1, 0x6, 0x1b,0xf, 0x7, 0xe, 0x1c, +0x8, 0x23,0x15,0x0, 0x1, 0x1, 0xa, 0x10,0x19,0xb, 0x14,0x1c,0xc, 0xf, 0x18,0x0, +0x1, 0x1, 0xe, 0x23,0x15,0xf, 0xd, 0x19,0x0, 0x1, 0x1, 0x11,0xd, 0x14,0x12,0x10, +0x19,0x13,0x1c,0x10,0x14,0x1a,0x10,0x15,0x10,0x19,0x16,0x23,0x1c,0x72,0x23,0x15, +0x73,0x23,0x1c,0x74,0x23,0x1c,0x75,0xe, 0x1c,0xc2,0xd5,0x7c,0xb4,0x30,0xe7,0x8, +0xb2,0xd5,0x6e,0x24,0xff,0xff,0xb, 0x24,0x7c,0xb6,0x30,0xe7,0x12,0xb2,0xd5,0x6e, +0x34,0xff,0xff,0xb, 0x34,0x8d,0x32,0x6e,0x24,0xff,0xff,0xb, 0x24,0x80,0x2, 0x8d, +0x32,0x30,0xd5,0x6, 0x6e,0x34,0xff,0xff,0xb, 0x34,0x22,0x7d,0x51,0xad,0x3, 0x7d, +0x2, 0x7d,0x21,0xad,0x5, 0x2d,0x12,0xad,0x35,0x2d,0x21,0x22,0x7d,0x2, 0xad,0x31, +0xad,0x10,0x2d,0x21,0x22,0x6d,0x0, 0x74,0x10,0x4d,0x0, 0x78,0xb, 0x4d,0x22,0x78, +0x27,0x8d,0x31,0x7d,0x12,0x6d,0x22,0x22,0x7d,0x43,0x7d,0x32,0x6d,0x22,0x2f,0x11, +0x2d,0x44,0x50,0x2, 0xa5,0xf, 0xbf,0x10,0x40,0x4, 0x9f,0x10,0xb, 0x90,0x14,0x78, +0xed,0x7f,0x1, 0x6d,0x22,0x7d,0x34,0x22,0x7d,0x41,0x7d,0x13,0x8d,0x24,0x7d,0x2, +0x2f,0x0, 0x40,0x4, 0xbd,0x4, 0x40,0x4, 0x9d,0x4, 0xb, 0x14,0x14,0x78,0xf1,0x7d, +0x23,0x7d,0x31,0x7d,0x10,0x6d,0x0, 0x22,0xc2,0xd5,0x7c,0xb0,0x30,0xe7,0x8, 0xb2, +0xd5,0x9f,0x22,0x9f,0x20,0x7f,0x2, 0x7c,0xb4,0x30,0xe7,0x13,0xb2,0xd5,0x9f,0x22, +0x9f,0x21,0x7f,0x12,0x12,0x1f,0x7, 0x9f,0x22,0x9f,0x20,0x7f,0x2, 0x80,0x3, 0x12, +0x1f,0x7, 0x30,0xd5,0x6, 0x9f,0x22,0x9f,0x21,0x7f,0x12,0x22,0x6c,0xaa,0x4d,0x11, +0x68,0x1a,0x1e,0x54,0x68,0xe, 0xb, 0x38,0x20,0x1b,0x18,0x20,0xb, 0x35,0xb, 0x15, +0x1b,0x54,0x78,0xf2,0x50,0x6, 0x7e,0x39,0x40,0x7a,0x19,0x40,0x22,0x6c,0xaa,0x4d, +0x11,0x68,0x1e,0x1e,0x54,0x50,0xc, 0x7e,0x1b,0x0, 0x7a,0x19,0x0, 0x68,0x12,0xb, +0x1c,0xb, 0x14,0xb, 0x1a,0x0, 0x1b,0x18,0x0, 0xb, 0x1d,0xb, 0x15,0x1b,0x54,0x78, +0xf2,0x22,0x75,0x84,0x1, 0x7e,0x44,0x3f,0xff,0xe4,0x7a,0x49,0xb0,0x1b,0x44,0x78, +0xf9,0x7e,0xf8,0x3a,0x10,0x75,0xc, 0x0, 0x75,0xd, 0x0, 0x75,0xe, 0x2, 0x75,0xf, +0x0, 0xc2,0x8, 0xc2,0x9, 0x75,0x1d,0x0, 0xc2,0x10,0xc2,0x11,0xc2,0x13,0x75,0x1e, +0x0, 0x75,0x1f,0x0, 0xc2,0xa, 0xc2,0xb, 0x75,0x5a,0x0, 0xc2,0x15,0x75,0x5b,0x0, +0xc2,0x17,0x75,0x5c,0x0, 0xc2,0x18,0xc2,0x19,0xc2,0x1a,0x75,0x5d,0x0, 0xc2,0xc, +0x75,0x1b,0x0, 0x75,0x1c,0x64,0xc2,0x1b,0xc2,0x1c,0x75,0x5e,0x0, 0xd2,0x5, 0xd2, +0x6, 0xd2,0x7, 0xd2,0x1d,0xc2,0xe, 0xd2,0xf, 0x7e,0x4, 0x0, 0xff,0x7e,0x14,0x21, +0x1a,0xb, 0xa, 0x40,0x5d,0x44,0x68,0x1a,0x69,0x20,0x0, 0x2, 0xb, 0xe, 0xb, 0x44, +0x80,0xa, 0x7e,0xb, 0xb0,0x7a,0x29,0xb0,0xb, 0x24,0xb, 0xc, 0x1b,0x44,0x78,0xf2, +0x80,0xdf,0x2, 0x28,0x9, 0x0, 0x0, 0x0, 0x47,0x0, 0xcb,0x1, 0x0, 0x0, 0x10,0xfd, +0xc7,0xfb,0x7e,0xfb,0xfb,0x1, 0xbb,0xc, 0x9e,0x19,0x0, 0x21,0x45,0x0, 0xe, 0x1, +0xf, 0x2, 0x10,0x3, 0x11,0x4, 0x12,0x5, 0x13,0x6, 0x14,0x7, 0x15,0x8, 0x16,0x9, +0x17,0xa, 0x18,0xb, 0x19,0xc, 0x1a,0xd, 0x1b,0xdf,0x22,0xc3,0x21,0xa9,0x20,0x94, +0x1f,0x81,0x1e,0x70,0x1d,0x62,0x1c,0x55,0x1b,0x4a,0x1a,0x41,0x19,0x38,0x18,0x31, +0x17,0x2b,0x16,0x25,0x15,0x21,0x14,0x1c,0x13,0x19,0x12,0x16,0x11,0x13,0x10,0x11, +0xf, 0x10,0xe, 0xca,0xf8,0x7f,0x20,0x80,0xa, 0x7e,0x1b,0xf0,0x7a,0x2b,0xf0,0xb, +0x34,0xb, 0x54,0x69,0xff,0xff,0xfc,0x7d,0xef,0x1b,0xe4,0x79,0xef,0xff,0xfc,0x4d, +0xff,0x78,0xe6,0x7f,0x10,0xda,0xf8,0x22,0x7d,0x43,0x7f,0x10,0x80,0x7, 0x1b,0x44, +0x7a,0xb, 0xb0,0xb, 0x14,0x4d,0x44,0x78,0xf5,0x22,0xff,0x0, 0x1, 0x2, 0x0, 0xff, +0x1, 0x2, 0x0, 0x1, 0xff,0x2, 0x0, 0x1, 0x2, 0xff,0x7d,0x23,0xbe,0x24,0x0, 0x0, +0x48,0x3, 0x7d,0x32,0x22,0x6d,0x33,0x9d,0x32,0x22,0x0, 0x4, 0x32,0xe5,0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x3, 0xff,0x1, 0x0, 0x1, 0x25,0xf6,0x1, 0x0, 0x1, 0x38,0x9c, +0x0, 0x0, 0x2, 0x38,0xee,0x0, 0x0, 0x0, 0x2, 0x38,0xf0,0x0, 0x0, 0x0, 0x1, 0x38, +0xf2,0x0, 0x0, 0x1, 0x37,0xe1,0xff,0x0, 0x1, 0x34,0x4f,0x0, 0x0, 0x1, 0x3a,0xe, +0x0, 0x0, 0x1, 0x34,0x8b,0x0, 0x0, 0x2, 0x34,0xb4,0x0, 0x0, 0x0, 0x1, 0x34,0xb6, +0x0, 0x0, 0x1, 0x34,0xc4,0x0, 0x0, 0x1, 0x34,0xc5,0x0, 0x0, 0x1, 0x34,0xda,0x0, +0x0, 0x1, 0x34,0xdb,0x0, 0x0, 0x1, 0x35,0x54,0x0, 0x0, 0x1, 0x35,0x55,0x1, 0x0, +0x1, 0x35,0x56,0x0, 0x0, 0x3c,0x36,0xe9,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x37,0x61,0x0, 0x0, 0x1, 0x37,0x62,0x0, 0x0, 0x1, +0x37,0x63,0x0, 0x0, 0x1, 0x36,0xe2,0x1, 0x0, 0x2, 0x36,0xe5,0x0, 0x0, 0x0, 0x1, +0x2f,0xa9,0x0, 0x0, 0x1, 0x2f,0xaa,0x0, 0x0, 0x1, 0x2f,0xab,0x0, 0x0, 0x1, 0x37, +0x66,0x1, 0x0, 0x1, 0x37,0xe0,0x0, 0x0, 0x1, 0x3a,0xf, 0x0, 0x0, 0x6, 0x39,0xfc, +0x3f,0x1f,0x50,0x11,0x20,0x10,0x0, 0x1, 0x3a,0x2, 0x24,0x0, 0x1, 0x3a,0x9, 0x0, +0x0, 0x1, 0x3a,0xa, 0x0, 0x0, 0x1, 0x3a,0xb, 0x0, 0x0, 0x1, 0x3a,0xc, 0x0, 0x0, +0x1, 0x3a,0xd, 0x0, 0x0, 0x1, 0x0, 0x5f,0x0, 0x0, 0x1, 0x3, 0xfc,0x0, 0x0, 0x1, +0x31,0xcd,0x0, 0x0, 0x2, 0x31,0xee,0x0, 0x0, 0x0, 0x1, 0x32,0x2c,0x0, 0x0, 0x4, +0x38,0x41,0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x3a,0x3, 0x0, 0x0, 0x1, 0x3a,0x4, 0x0, +0x0, 0x2, 0x3a,0x5, 0x0, 0x0, 0x0, 0x1, 0x3a,0x7, 0x64,0x0, 0x1, 0x3a,0x8, 0x0, +0x0, 0x1, 0x3a,0x10,0x0, 0x0, 0x1, 0x3, 0xfd,0x0, 0x0, 0x1, 0x3, 0xfe,0x0, 0x0, +0x2, 0x2b,0xb9,0x2b,0xbf,0x0, 0x1, 0x2f,0x7f,0x2, 0x0, 0x1, 0x2f,0xa8,0x0, 0x0, +0x1, 0x39,0x3f,0xff,0x0, 0x1, 0x39,0x40,0x0, 0x0, 0x1, 0x39,0x41,0x0, 0x0, 0x1, +0x39,0x42,0x40,0x0, 0x1, 0x39,0x43,0x40,0x0, 0x1, 0x39,0xde,0x0, 0x0, 0x4, 0x39, +0xf4,0x0, 0x0, 0x50,0x0, 0x0, 0x4, 0x39,0xf8,0x0, 0x0, 0x64,0x0, 0x0, 0x4, 0x39, +0xc1,0x0, 0x0, 0x6c,0x0, 0x0, 0x4, 0x39,0xc5,0x0, 0x0, 0x68,0xc0,0x0, 0x4, 0x39, +0xc9,0x0, 0x0, 0x68,0x0, 0x0, 0x4, 0x39,0xda,0x0, 0x0, 0x40,0x0, 0x0, 0x4, 0x33, +0xfc,0x0, 0x0, 0x60,0x0, 0x0, 0x0, 0x3, 0x84,0x0, 0xd, 0x1, 0xf4,0x2, 0xbc,0x0, +0xd, 0x1, 0x4a,0x2, 0x58,0x0, 0xc, 0x0, 0xc8,0x1, 0xf4,0x0, 0xb, 0x0, 0xa0,0x1, +0x90,0x0, 0x9, 0x0, 0x50,0x0, 0xc8,0x0, 0x7, 0x0, 0x1e,0x0, 0x3c,0x0, 0x14,0x0, +0x18,0x0, 0xe, 0x1c,0x23,0x5, 0xdc,0x0, 0x32,0x3, 0xe8,0x0, 0x28,0x0, 0x0, 0x0, +0x1e,0x12,0x31,0xa9,0x12,0x23,0x91,0x12,0x23,0x5c,0x12,0x24,0x36,0x2, 0x23,0x20, +0x12,0x23,0x31,0x7e,0xb3,0x2b,0xf, 0x12,0x57,0xfc,0x74,0x1, 0x7a,0xb3,0x37,0x6a, +0x22,0x12,0xab,0x26,0x74,0x1, 0x7a,0xb3,0x37,0x66,0x22,0x12,0x23,0xc8,0x12,0x28, +0x2b,0x12,0x58,0xef,0x12,0x31,0xa9,0x12,0x23,0xc8,0x12,0x23,0x91,0x12,0xc6,0x6e, +0x12,0x23,0x5c,0x12,0x24,0x36,0x12,0x24,0x66,0x2, 0x23,0x20,0x12,0x59,0x38,0x12, +0x23,0xae,0x2, 0x23,0x65,0x7e,0x34,0x0, 0x3, 0x6d,0x22,0x2, 0x23,0x6e,0x7d,0x43, +0x7e,0xa3,0x34,0x38,0xbe,0xa0,0x5, 0x50,0x16,0x7e,0x70,0x4, 0xac,0x7a,0x59,0x43, +0x34,0x3b,0x59,0x23,0x34,0x3d,0x7c,0xba,0x4, 0x7a,0xb3,0x34,0x38,0xc3,0x22,0xd3, +0x22,0x12,0x36,0xad,0x12,0x69,0x83,0x2, 0x23,0x9a,0x30,0x13,0x10,0x12,0x57,0x8e, +0x50,0x3, 0x12,0x51,0xf9,0x12,0x69,0xa9,0x12,0x55,0xae,0xc2,0x13,0x22,0x6d,0x33, +0x7e,0x24,0x6, 0xfc,0x12,0x23,0x6e,0x7e,0x34,0x0, 0x1, 0x7e,0x24,0x7, 0x7a,0x2, +0x23,0x6e,0x74,0x1, 0x7a,0xb3,0x38,0xa1,0x7e,0x34,0xd, 0xac,0x6d,0x22,0x7a,0x27, +0x33,0xeb,0x7a,0x37,0x33,0xed,0x22,0xca,0xf8,0x7e,0xf3,0x38,0xa1,0xbe,0xf0,0x5, +0x78,0xb, 0x74,0x1, 0x7a,0xb3,0x38,0xa1,0x12,0x0, 0xa, 0x80,0x40,0xbe,0xf0,0x4, +0x78,0xd, 0x12,0x23,0xc2,0xe4,0x7a,0xb3,0x2b,0x2, 0x12,0x36,0xad,0x80,0x2e,0xbe, +0xf0,0x6, 0x78,0x13,0x12,0x23,0xc2,0x12,0x3b,0xd3,0xe4,0x7a,0xb3,0x2b,0x1e,0x12, +0x69,0x83,0x12,0xc6,0xd0,0x80,0x16,0xbe,0xf0,0x7, 0x78,0x17,0x12,0x23,0xc2,0x12, +0x69,0x78,0x50,0xfb,0x12,0x6a,0xb8,0x12,0x23,0x9a,0x12,0x24,0x36,0x74,0x2, 0x7a, +0xb3,0x38,0xa1,0xda,0xf8,0x22,0xe4,0x7a,0xb3,0x34,0x3a,0x7a,0xb3,0x34,0x39,0x12, +0x3f,0xd2,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x2, 0x74,0x3, 0x7a,0xb3,0x34,0x3a,0x22, +0x12,0xc6,0x6e,0x12,0x4a,0x2e,0x7a,0x37,0x3a,0x5, 0x12,0x23,0xc8,0x12,0x23,0x91, +0x12,0x24,0x36,0x2, 0x24,0x66,0x74,0xa, 0x7a,0xb3,0x34,0x89,0xe4,0x7a,0xb3,0x34, +0x8a,0x7e,0x8, 0x34,0x8c,0x7e,0x34,0x0, 0xa, 0x74,0xa, 0x12,0x20,0xe8,0x7e,0x8, +0x34,0x96,0x7e,0x34,0x0, 0xa, 0xe4,0x2, 0x20,0xe8,0xca,0x3b,0x12,0x69,0x78,0x50, +0xfb,0x7e,0xf3,0x2b,0xf, 0x7c,0xbf,0x12,0x8b,0x38,0x12,0xb8,0xc9,0x7e,0xb3,0x2b, +0x1f,0xf5,0x28,0x7e,0xc3,0x2b,0x20,0x7e,0xb3,0x38,0x9, 0xb4,0x1, 0xf, 0x12,0x51, +0xbf,0x7e,0xb3,0x16,0x91,0x70,0x6, 0x12,0x24,0x36,0xc3,0xa1,0x86,0x12,0x25,0x89, +0x3e,0x34,0xca,0x39,0x7e,0x18,0x6, 0xfc,0x7e,0x8, 0x4, 0x7e,0x12,0x20,0xc3,0x1b, +0xfd,0x12,0x25,0x89,0x3e,0x34,0xca,0x39,0x7e,0x18,0x7, 0x7a,0x7e,0x8, 0x4, 0x0, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xb3,0x38,0x9, 0xb4,0x3, 0x7, 0x12,0xa5,0x25,0x7a, +0x37,0x38,0xe4,0x74,0x1, 0x7a,0xb3,0x16,0x90,0x12,0x23,0x91,0x12,0xa5,0x16,0x12, +0x50,0xd8,0xe4,0x12,0x13,0xde,0x12,0x24,0x36,0x7e,0x8, 0x4, 0x7e,0x7a,0xd, 0x29, +0x7e,0x18,0x6, 0x76,0x7e,0xb3,0x2b,0x72,0x12,0xb9,0xea,0x7e,0x8, 0x4, 0x0, 0x7a, +0xd, 0x29,0x7e,0x18,0x5, 0xf8,0x7e,0xb3,0x25,0xf0,0x12,0xb9,0xea,0x7e,0xd3,0x2b, +0x1f,0x7e,0xe3,0x2b,0x20,0xe5,0x28,0x7a,0xb3,0x2b,0x1f,0x7a,0xc3,0x2b,0x20,0x7e, +0x34,0x8, 0xa, 0x7e,0x4, 0xd, 0xc8,0x7d,0x20,0x7d,0x10,0x12,0x56,0x2d,0x7a,0xd3, +0x2b,0x1f,0x7a,0xe3,0x2b,0x20,0x7c,0xbf,0x12,0x8a,0xbb,0x12,0xa4,0x16,0x7e,0xb3, +0x3a,0x8, 0x4, 0x7a,0xb3,0x3a,0x8, 0x7e,0x73,0x3a,0x8, 0xbe,0x70,0xfa,0x28,0x6, +0x74,0x64,0x7a,0xb3,0x3a,0x8, 0x7e,0xb3,0x16,0x90,0x60,0x9, 0x7e,0xb3,0x16,0x91, +0x60,0x3, 0xd3,0x80,0x1, 0xc3,0xda,0x3b,0x22,0x7e,0x73,0x2a,0x74,0xa, 0x27,0x7e, +0x73,0x2a,0x73,0xa, 0x37,0x2d,0x32,0x22,0x12,0x3a,0xc6,0x7e,0xb3,0x38,0x9, 0xb4, +0x3, 0x69,0x12,0xb8,0x28,0x12,0x2f,0xe7,0x12,0x2d,0x59,0x7e,0xb3,0x38,0x9d,0x30, +0xe7,0xe9,0x12,0x24,0x8a,0x12,0x25,0x89,0x3e,0x34,0xca,0x39,0x7e,0x18,0x4, 0x0, +0x7e,0x8, 0x4, 0xfc,0x12,0x20,0xc3,0x1b,0xfd,0x12,0x25,0x89,0x3e,0x34,0xca,0x39, +0x7e,0x18,0x4, 0x7e,0x7e,0x8, 0x5, 0x7a,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xb3,0x2b, +0x1d,0xb4,0x1, 0x15,0x12,0x67,0x6c,0x12,0x85,0xfd,0x12,0x44,0xaf,0x12,0x6a,0xc3, +0x12,0x77,0x1d,0x12,0x26,0x1b,0x12,0x3f,0xfa,0x12,0x3b,0x8, 0x12,0xad,0x82,0x7e, +0xb3,0x38,0x9d,0x54,0x7f,0x7a,0xb3,0x38,0x9d,0x80,0x90,0x12,0x6a,0x6d,0x2, 0x0, +0x46,0xe4,0x7a,0xb3,0x2b,0x2, 0x7a,0xb3,0x2b,0x1e,0x22,0x12,0x73,0x74,0x12,0x75, +0x4a,0x12,0x75,0x4a,0x12,0x8c,0xdb,0x12,0xa1,0xc1,0x12,0x88,0x7e,0x12,0x75,0x4a, +0x12,0x92,0xe7,0x12,0x75,0x4a,0x12,0x96,0xc8,0x12,0x75,0x4a,0x2, 0x26,0x3f,0xca, +0x3b,0x75,0x24,0x0, 0x6c,0xcc,0x6c,0xdd,0x7e,0xc4,0x0, 0x3c,0xca,0xc9,0x7e,0x18, +0x37,0x25,0x7e,0x8, 0x36,0xe9,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xf3,0x28,0x84,0xa, +0xcf,0x3e,0xc4,0xca,0xc9,0x7e,0x18,0x26,0xfa,0x7e,0x8, 0x1f,0x34,0x12,0x20,0xc3, +0x1b,0xfd,0x6c,0x88,0x6c,0xee,0xe1,0x13,0x7e,0xc4,0x3, 0xff,0x7e,0xc0,0xff,0x6c, +0x99,0x80,0x4c,0x74,0x2, 0xac,0xb9,0x9, 0xb5,0x1f,0x34,0xbe,0xb0,0xff,0x68,0x3d, +0x7c,0xb9,0x12,0x88,0x65,0x60,0x36,0x74,0x2, 0xac,0xb9,0x9, 0x75,0x1f,0x35,0xa, +0x27,0x74,0x2, 0xac,0xbe,0x9, 0x75,0x37,0x26,0x12,0x96,0xa4,0x7d,0x13,0x74,0x2, +0xac,0xb9,0x9, 0x75,0x1f,0x34,0xa, 0x27,0x74,0x2, 0xac,0xbe,0x9, 0x75,0x37,0x25, +0x12,0x96,0xa4,0x2d,0x13,0xbd,0xc1,0x28,0x4, 0x7d,0xc1,0x7c,0xc9,0xb, 0x90,0xbc, +0xf9,0x38,0xb0,0xbe,0xc0,0xff,0x68,0x39,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x1f, +0x34,0x9, 0x73,0x1f,0x35,0x12,0x6d,0xcb,0xbe,0x37,0x2a,0x5a,0x48,0x23,0x7e,0x70, +0x2, 0xac,0x7c,0x9, 0x53,0x1f,0x34,0x74,0x2, 0xac,0xbd,0x19,0x55,0x1f,0x70,0x9, +0x53,0x1f,0x35,0x19,0x55,0x1f,0x71,0x74,0xff,0x19,0xb3,0x1f,0x34,0xb, 0x80,0xb, +0xd0,0xb, 0xe0,0x7e,0x73,0x36,0xe8,0xbc,0x7e,0x28,0x2, 0xc1,0x78,0x7c,0xe8,0x80, +0x6d,0x6d,0xdd,0x7e,0x80,0xff,0x6c,0x99,0x80,0x3c,0x7c,0xb9,0x12,0x88,0x65,0x60, +0x33,0x12,0xc6,0x99,0xbe,0xb0,0xff,0x68,0x2b,0x9, 0x73,0x1f,0x35,0x12,0x6f,0x81, +0x7f,0x71,0xb, 0x7a,0x50,0xbe,0x54,0x0, 0x0, 0x58,0x5, 0x6d,0x55,0x1b,0x7a,0x50, +0xb, 0x7a,0xc0,0xbd,0xcd,0x8, 0xd, 0x12,0xc6,0x99,0xf5,0x24,0x9, 0xc3,0x1f,0x35, +0x7d,0xdc,0x7c,0x89,0xb, 0x90,0xbc,0xf9,0x38,0xc0,0xbe,0x80,0xff,0x68,0x1d,0x7e, +0x71,0x24,0x74,0x2, 0xac,0xbd,0x19,0x75,0x1f,0x70,0x19,0xc5,0x1f,0x71,0x7e,0xa0, +0xff,0x7e,0x70,0x2, 0xac,0x78,0x19,0xa3,0x1f,0x34,0xb, 0xd0,0xb, 0xe0,0xbe,0xe0, +0xa, 0x40,0x8e,0x7e,0x34,0x0, 0x3c,0xca,0x39,0x7e,0x18,0x1f,0x70,0x7e,0x8, 0x1f, +0x34,0x12,0x20,0xc3,0x1b,0xfd,0x7c,0xfd,0x7e,0x8, 0x37,0x25,0x7e,0x34,0x0, 0x14, +0x74,0xff,0x12,0x20,0xe8,0xbe,0xf0,0x0, 0x28,0x35,0xa, 0x3f,0x3e,0x34,0xca,0x39, +0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x26,0xfa,0x12,0x20,0xc3,0x1b,0xfd,0xa, 0x3f,0x3e, +0x34,0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x37,0x25,0x12,0x20,0xc3,0x1b,0xfd, +0x6c,0xee,0x80,0x7, 0x7c,0xbe,0x12,0x76,0xfb,0xb, 0xe0,0xbc,0xfe,0x38,0xf5,0x7a, +0xf3,0x36,0xe8,0x7a,0xf3,0x28,0x84,0x7e,0x73,0x28,0x84,0xbe,0x70,0xa, 0x28,0x6, +0x74,0xa, 0x7a,0xb3,0x28,0x84,0xda,0x3b,0x22,0x12,0x28,0x2b,0x12,0x62,0xf6,0x12, +0x58,0xef,0x12,0x23,0x11,0x7e,0xb3,0x38,0x9, 0x24,0xfd,0x68,0x9, 0xb, 0xb1,0x78, +0xf4,0x12,0x40,0x98,0x80,0xef,0x12,0x25,0x98,0x80,0xea,0xe4,0x12,0xb6,0xbd,0x12, +0xb7,0xaa,0x12,0x2f,0xe7,0x12,0xb8,0x21,0x12,0x28,0x6e,0x12,0xb6,0x6b,0x12,0xb7, +0xc1,0x12,0x0, 0x9, 0x12,0xb7,0xcd,0x12,0x68,0xad,0x12,0xb7,0xdd,0xd2,0xaf,0x12, +0xb7,0x3c,0x12,0x64,0x46,0x12,0x2a,0x98,0x12,0xb7,0x2, 0x7e,0x8, 0x33,0xef,0x12, +0xb8,0x41,0x74,0xe, 0x7e,0x70,0x19,0x7e,0x24,0xff,0xff,0x2, 0x12,0x34,0xa9,0xd5, +0xcb,0x74,0x2, 0x7e,0x70,0x3f,0x12,0x28,0xba,0x74,0xf, 0x12,0x0, 0x66,0x7c,0x7b, +0x74,0xf, 0x5e,0x70,0xfe,0x12,0x28,0xba,0x74,0xc, 0x12,0x0, 0x66,0x54,0x7f,0x68, +0x8, 0x74,0xc, 0x7e,0x70,0xf8,0x12,0x28,0xba,0x7e,0x70,0x72,0x74,0xe, 0x12,0x28, +0xba,0x74,0x7, 0x12,0x0, 0x66,0x7c,0x7b,0x5e,0x70,0xfb,0x74,0x7, 0x2, 0x28,0xb0, +0x12,0x28,0xba,0x75,0xfd,0xff,0xa9,0xc5,0xcb,0x22,0xf5,0xfd,0x7a,0x71,0xfe,0x22, +0xca,0x79,0x7d,0xd3,0x7e,0x80,0xe, 0x7e,0xf0,0x28,0x12,0x2f,0xe7,0xa9,0xd0,0xc4, +0xa9,0xd5,0xcb,0x74,0x7, 0x12,0x0, 0x66,0xf5,0x24,0x74,0x7, 0x7e,0x70,0xf, 0x12, +0x28,0xb0,0x7e,0x54,0x0, 0x78,0x7e,0x1f,0x39,0xc5,0x79,0x51,0x0, 0x6, 0x7e,0x54, +0x0, 0x80,0x7e,0x1f,0x39,0xc5,0x79,0x51,0x0, 0x8, 0x7e,0x54,0x0, 0xc, 0x7e,0x1f, +0x39,0xc5,0x79,0x51,0x0, 0x10,0xbe,0xd4,0x0, 0x2, 0x78,0x7, 0x12,0x2a,0x7d,0x44, +0x1, 0x80,0x1c,0x12,0x2a,0x7d,0x44,0x8, 0x1b,0x1a,0x50,0x4d,0xdd,0x7e,0x1f,0x39, +0xc5,0x78,0x7, 0x12,0x2a,0x81,0x54,0xfb,0x80,0x5, 0x12,0x2a,0x81,0x44,0x4, 0x1b, +0x1a,0x50,0x7e,0x1f,0x39,0xc1,0x69,0xe1,0x0, 0x84,0x69,0x51,0x0, 0x90,0x7d,0xf5, +0x2e,0x34,0x0, 0x90,0x5e,0xa0,0xf6,0x1b,0x1a,0x50,0x7e,0xb3,0x38,0x13,0xbe,0xb0, +0x6, 0x40,0x3, 0xb4,0xff,0xe, 0x12,0x2a,0x8c,0x54,0xe6,0x12,0x2a,0x89,0x4e,0x54, +0x1, 0xa4,0x80,0xc, 0x12,0x2a,0x8c,0x5e,0x54,0xfe,0xe6,0x12,0x2a,0x89,0x44,0xa4, +0x1b,0x1a,0x50,0xbe,0xd4,0x0, 0x2, 0x78,0x26,0x12,0x2f,0x3, 0x5e,0x34,0x0, 0xf, +0x1b,0xa, 0x30,0x12,0x2f,0x3, 0x4e,0x70,0x50,0x1b,0xa, 0x30,0x7e,0x34,0x0, 0x2, +0x12,0x2d,0x3a,0x12,0x2d,0x13,0x12,0x2c,0xf0,0x7a,0x37,0x32,0xe9,0x41,0x3a,0x6c, +0xee,0x41,0x34,0x4c,0xee,0x78,0x4, 0x6c,0x99,0x80,0x2b,0xbc,0x8e,0x40,0x12,0xa, +0xce,0x9, 0x9c,0x2a,0xb8,0xbe,0x90,0x23,0x40,0x3, 0x7e,0x90,0x22,0xb, 0x90,0x80, +0x15,0xa, 0x38,0xa, 0xce,0x9d,0xc3,0x9, 0x9c,0x2a,0xdb,0xbe,0x90,0x1c,0x40,0x3, +0x7e,0x90,0x1b,0x2e,0x90,0x24,0x12,0x2a,0x7d,0x5e,0x54,0x0, 0xf, 0x1b,0x1a,0x50, +0xa, 0xc9,0x3e,0xc4,0x3e,0xc4,0x3e,0xc4,0x3e,0xc4,0x12,0x2a,0x7d,0x4d,0x5c,0x1b, +0x1a,0x50,0xe5,0xe, 0x60,0x7, 0xe5,0xe, 0xbe,0xb0,0x64,0x28,0x6, 0x7e,0x34,0x0, +0x2, 0x80,0x4, 0xe5,0xe, 0xa, 0x3b,0x12,0x2d,0x3a,0x12,0x2d,0x13,0xbe,0xd4,0x0, +0x1, 0x78,0x10,0x12,0x2d,0x13,0x12,0x2c,0xf0,0x74,0x2, 0xac,0xbe,0x59,0x35,0x32, +0xeb,0x80,0xf, 0x12,0x2c,0xf0,0xa, 0x5f,0xa, 0x2e,0x2d,0x25,0x3e,0x24,0x59,0x32, +0x32,0xeb,0xb, 0xe0,0xbc,0xfe,0x28,0x2, 0x21,0xa3,0xa9,0xd5,0xcb,0x74,0x7, 0x7e, +0x71,0x24,0x12,0x28,0xb0,0xa9,0xc0,0xc4,0x7e,0x1f,0x39,0xc1,0x79,0xe1,0x0, 0x84, +0x7e,0x1f,0x39,0xc1,0x79,0xf1,0x0, 0x90,0x6d,0x33,0x7e,0xf, 0x39,0xc5,0x79,0x30, +0x0, 0x6, 0x7e,0xf, 0x39,0xc5,0x79,0x30,0x0, 0x8, 0x7e,0xf, 0x39,0xc5,0x79,0x30, +0x0, 0x10,0x7e,0xf, 0x39,0xc5,0x79,0x30,0x0, 0xe, 0xda,0x79,0x22,0x7e,0x1f,0x39, +0xc5,0x2e,0x34,0x0, 0xe, 0xb, 0x1a,0x50,0x22,0x1b,0x1a,0x50,0x7e,0x1f,0x39,0xc1, +0x2e,0x34,0x0, 0x84,0xb, 0x1a,0x50,0x22,0x6d,0x33,0x7e,0x8, 0x0, 0x24,0x7e,0x24, +0x0, 0x12,0x12,0x63,0x62,0xe5,0x34,0x20,0xe7,0x1b,0xa9,0xd5,0xcb,0x74,0x3, 0x7e, +0x71,0x27,0x12,0x28,0xba,0x74,0xb, 0x7e,0x71,0x2f,0x12,0x28,0xba,0x74,0xc, 0x7e, +0x71,0x30,0x12,0x28,0xb0,0x22,0xca,0xf8,0x7c,0xab,0xbe,0xa0,0x34,0x38,0x2, 0x61, +0xd7,0xbe,0xa0,0x35,0x78,0x6, 0x7e,0xb3,0x2b,0x10,0x81,0xed,0xbe,0xa0,0x36,0x68, +0x5, 0xbe,0xa0,0x37,0x78,0x1d,0x7e,0x35,0x8, 0x7d,0x23,0xb, 0x24,0x7a,0x25,0x8, +0x2e,0x37,0x32,0xe3,0x7e,0x39,0xb0,0xbe,0xa0,0x37,0x68,0x2, 0x81,0xed,0x75,0x1a, +0x36,0x81,0xed,0xbe,0xa0,0x38,0x68,0x5, 0xbe,0xa0,0x39,0x78,0x1b,0x7e,0xf3,0x38, +0xc1,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc1,0xbe,0xa0,0x39,0x78,0x3, 0x75,0x1a,0x38, +0xa, 0x3f,0x9, 0xb3,0x2b,0x21,0x81,0xed,0xbe,0xa0,0x3a,0x68,0x5, 0xbe,0xa0,0x3b, +0x78,0x1b,0x7e,0xf3,0x38,0xc3,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc3,0xbe,0xa0,0x3b, +0x78,0x3, 0x75,0x1a,0x3a,0xa, 0x3f,0x9, 0xb3,0x2b,0x44,0x81,0xed,0xbe,0xa0,0xfb, +0x78,0x6, 0x7e,0xb3,0x2b,0x12,0x81,0xed,0xbe,0xa0,0x5e,0x78,0x26,0x7e,0xf, 0x39, +0xc1,0x69,0x30,0x0, 0x8e,0xa, 0x56,0x1e,0x54,0x1e,0x54,0x1e,0x54,0x5e,0x54,0x0, +0x1, 0x3, 0x3, 0x54,0xc0,0xa, 0x36,0x5e,0x34,0x0, 0x3, 0x7c,0xa7,0x4c,0xba,0x44, +0x80,0x81,0xed,0xbe,0xa0,0x3c,0x68,0x5, 0xbe,0xa0,0x3d,0x78,0x1b,0x7e,0xf3,0x38, +0xc5,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc5,0xbe,0xa0,0x3d,0x78,0x3, 0x75,0x1a,0x3c, +0xa, 0x3f,0x9, 0xb3,0x2a,0x7a,0x81,0xed,0xbe,0xa0,0x3e,0x68,0x5, 0xbe,0xa0,0x3f, +0x78,0x1b,0x7e,0xf3,0x38,0xc7,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc7,0xbe,0xa0,0x3f, +0x78,0x3, 0x75,0x1a,0x3e,0xa, 0x3f,0x9, 0xb3,0x2a,0x9d,0x81,0xed,0xbe,0xa0,0x40, +0x40,0xd, 0xbe,0xa0,0x4d,0x38,0x8, 0xa, 0x3a,0x9, 0xb3,0x38,0x9d,0x81,0xed,0xbe, +0xa0,0x4e,0x68,0x5, 0xbe,0xa0,0x4f,0x78,0x1e,0x7e,0xf3,0x38,0xe2,0x7c,0xbf,0x4, +0x7a,0xb3,0x38,0xe2,0xbe,0xa0,0x4f,0x78,0x3, 0x75,0x1a,0x4e,0xa, 0x3f,0x2e,0x37, +0x32,0xe1,0x7e,0x39,0xb0,0x81,0xed,0xbe,0xa0,0x51,0x68,0x5, 0xbe,0xa0,0x52,0x78, +0x28,0x7e,0x14,0x60,0x0, 0x6d,0x0, 0x2e,0x4, 0x0, 0xff,0x7e,0xb3,0x38,0xed,0xa, +0x3b,0x6d,0x22,0x2f,0x10,0x7e,0x1b,0x70,0x4, 0x7a,0xb3,0x38,0xed,0xbe,0xa0,0x52, +0x78,0x3, 0x75,0x1a,0x51,0x7c,0xb7,0x81,0xed,0xbe,0xa0,0x5c,0x68,0x5, 0xbe,0xa0, +0x5d,0x78,0x1a,0x7e,0xf3,0x38,0xb6,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xb6,0xbe,0xa0, +0x5d,0x78,0x3, 0x75,0x1a,0x5c,0x7c,0xbf,0x12,0xad,0x2, 0x81,0xed,0xbe,0xa0,0x60, +0x40,0xd, 0xbe,0xa0,0x6c,0x38,0x8, 0xa, 0x3a,0x9, 0xb3,0x33,0x8f,0x80,0x7e,0xbe, +0xa0,0x6d,0x78,0x4, 0xe5,0xe, 0x80,0x75,0xbe,0xa0,0xf4,0x68,0x5, 0xbe,0xa0,0xf5, +0x78,0x18,0x7e,0x35,0xa, 0x7d,0x23,0xb, 0x24,0x7a,0x25,0xa, 0x9, 0xb3,0x32,0xe9, +0xbe,0xa0,0xf5,0x78,0x58,0x75,0x1a,0xf4,0x80,0x53,0xbe,0xa0,0xf0,0x68,0x5, 0xbe, +0xa0,0xf1,0x78,0x9, 0x7c,0x1a,0x2e,0x10,0x20,0xa5,0xe7,0x80,0x40,0xbe,0xa0,0xf2, +0x68,0x5, 0xbe,0xa0,0xf3,0x78,0x1b,0x7e,0x15,0x10,0x3e,0x14,0x7e,0x1f,0x32,0xe5, +0x2d,0x31,0xb, 0x1a,0x30,0xbe,0xa0,0xf2,0x78,0x4, 0xa, 0x56,0x80,0x1f,0x7d,0x53, +0x80,0x1b,0xbe,0xa0,0xf6,0x78,0x4, 0xe5,0xf, 0x80,0x12,0xbe,0xa0,0xf7,0x78,0x4, +0x74,0x32,0x80,0x9, 0xbe,0xa0,0xfd,0x78,0x3, 0xe4,0x80,0x1, 0xe4,0xda,0xf8,0x22, +0x7e,0xf, 0x39,0xc5,0x69,0x30,0x0, 0xa, 0x7d,0x23,0x6d,0x33,0x69,0x10,0x0, 0xc, +0x6d,0x0, 0x2f,0x10,0x74,0x7, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14, +0x78,0xf4,0x22,0x7e,0x34,0x0, 0x1, 0x7e,0xf, 0x39,0xc5,0x79,0x30,0x0, 0x4, 0x7e, +0xf, 0x39,0xc5,0x69,0x30,0x0, 0x12,0x5e,0x34,0x0, 0x1, 0x68,0xf2,0x7e,0x34,0x0, +0x1, 0x79,0x30,0x0, 0x12,0x22,0x7e,0x34,0x0, 0x1, 0x7d,0x23,0x80,0x12,0x7e,0x30, +0x4, 0x80,0x5, 0x74,0xfa,0x12,0x2f,0x39,0x7c,0x23,0x1b,0x30,0xa5,0xba,0x0, 0xf3, +0x7d,0x32,0x1b,0x24,0x4d,0x33,0x78,0xe6,0x22,0x30,0x8, 0x3b,0xc2,0x8, 0x12,0x23, +0xd7,0x7e,0x73,0x38,0xa2,0x7a,0x73,0x2a,0x4d,0x7e,0x73,0x38,0xa3,0x7a,0x73,0x2b, +0x1d,0x7e,0x73,0x38,0xa3,0x7a,0x73,0x2b,0x1, 0x7e,0xb3,0x38,0xa4,0x60,0x18,0x7e, +0x34,0x0, 0x2, 0x12,0x28,0xc0,0x7e,0x34,0x0, 0x1, 0x12,0x28,0xc0,0x6d,0x33,0x12, +0x28,0xc0,0xe4,0x7a,0xb3,0x38,0xa4,0x12,0x36,0x2d,0x2, 0x2d,0x9d,0xe5,0xc, 0x70, +0x2, 0xc1,0xbc,0xe5,0xc, 0x30,0xe0,0x10,0x53,0xc, 0xfe,0x12,0xaa,0xc5,0x12,0x64, +0xdf,0x7e,0x8, 0x2a,0x6d,0x12,0x9, 0xa1,0xe5,0xc, 0x30,0xe1,0x6, 0x53,0xc, 0xfd, +0x12,0xbb,0x4c,0xe5,0xc, 0x30,0xe2,0x2f,0x53,0xc, 0xfb,0x7e,0xb3,0x2b,0x12,0x60, +0x9, 0x7e,0x8, 0x2a,0x6d,0x12,0x6, 0xba,0x80,0xb, 0x7e,0xb3,0x2b,0x65,0x7e,0x73, +0x2b,0x64,0x12,0xb, 0xad,0x7e,0x73,0x2b,0x12,0x2e,0x70,0xff,0x92,0x1, 0x74,0x19, +0x9e,0xb3,0x2a,0x77,0x12,0xb, 0x1e,0xe5,0xc, 0x30,0xe3,0x4a,0x53,0xc, 0xf7,0x7e, +0x73,0x38,0xcf,0x7a,0x73,0x2b,0xf, 0x12,0x8b,0x16,0x7a,0xb3,0x0, 0x5f,0xbe,0xb0, +0xff,0x68,0xb, 0x43,0xc, 0x20,0x7e,0x73,0x0, 0x5f,0x7a,0x73,0x38,0xa7,0x12,0x51, +0x36,0x12,0x3f,0xeb,0x7e,0x73,0x38,0xd0,0xbe,0x73,0x2b,0x62,0x68,0x6, 0x7a,0x73, +0x2b,0x62,0xd2,0x10,0x30,0x10,0x9, 0xc2,0x10,0x12,0x57,0xd5,0xe4,0x12,0xa, 0x66, +0x12,0x23,0x31,0x12,0x57,0xf8,0xe5,0xc, 0x30,0xe4,0xf, 0x53,0xc, 0xef,0x7e,0x43, +0x38,0xd1,0x7e,0x50,0xa, 0xac,0x45,0x12,0x3a,0xf8,0xe5,0xc, 0x30,0xe6,0x4e,0x53, +0xc, 0xbf,0x7e,0x73,0x38,0xbd,0xbe,0x70,0x7, 0x28,0x6, 0x74,0x7, 0x7a,0xb3,0x38, +0xbd,0xa9,0xd5,0xcb,0x74,0xe, 0x12,0x0, 0x66,0x7c,0x7b,0x5e,0x70,0xf, 0x7e,0x63, +0x38,0xbd,0xa, 0x26,0x2e,0x24,0x0, 0x3, 0x12,0x7f,0x9, 0x7c,0x65,0x4c,0x76,0x74, +0xe, 0x12,0x28,0xba,0x12,0x0, 0x66,0x12,0x28,0xb3,0x7e,0x73,0x38,0xc0,0x7a,0x73, +0x2b,0x14,0x7e,0x73,0x38,0xbf,0x7a,0x73,0x2b,0x1f,0x12,0xc6,0xd0,0xe5,0xc, 0x30, +0xe5,0xa, 0x53,0xc, 0xdf,0x7e,0xb3,0x38,0xa7,0x2, 0x3b,0x46,0x22,0x24,0xab,0x68, +0x10,0x24,0xef,0x68,0x1c,0x24,0xde,0x68,0x26,0x24,0xde,0x78,0x2f,0x74,0x5, 0x80, +0x2d,0x7e,0xb3,0x3, 0xff,0xb4,0x5, 0x2a,0x12,0x2d,0x36,0x12,0xb6,0x75,0x2, 0xb8, +0xe, 0x7e,0xb3,0x3, 0xff,0xb4,0x5, 0x1a,0x12,0x2d,0x36,0x75,0xe9,0xff,0x22,0x7e, +0xb3,0x3, 0xff,0xb4,0x5, 0xc, 0x12,0x2d,0x36,0x2, 0xb8,0x8, 0x74,0x1, 0x7a,0xb3, +0x3, 0xff,0x22,0x7e,0xf, 0x39,0xc5,0x2e,0x14,0x0, 0xe, 0xb, 0xa, 0x30,0x22,0x7c, +0x6b,0xa9,0xd5,0xcb,0x74,0xf, 0x12,0x28,0xba,0x7a,0x61,0xfc,0x12,0x28,0xb3,0x12, +0xb7,0x2, 0xd2,0x0, 0x12,0xb6,0xee,0x12,0x2f,0xee,0x12,0x13,0xde,0x2, 0x13,0x96, +0x74,0x4, 0x7d,0x30,0x12,0x2f,0x58,0x74,0x14,0x7c,0xab,0x80,0xe, 0x7e,0x70,0x3, +0x80,0x1, 0x0, 0x7c,0x67,0x1b,0x70,0xa5,0xbe,0x0, 0xf7,0x7c,0x6a,0x1b,0xa0,0xa5, +0xbe,0x0, 0xea,0x22,0x74,0x2, 0x7d,0x3f,0x7d,0x23,0x7c,0x6b,0xa, 0x14,0x7c,0x73, +0x7d,0x52,0x7c,0xab,0x7e,0xb3,0x3a,0x10,0xb4,0xa5,0x3c,0x12,0x64,0x8d,0x75,0xb5, +0x1, 0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9, +0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3, +0x7a,0x71,0xb5,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7a,0xa1,0xb5,0xa9,0x36,0xb3, +0xfc,0xa9,0xc6,0xb3,0xa9,0xd2,0xb4,0x22,0xa9,0xc6,0xb3,0x75,0xb5,0x0, 0x22,0x12, +0xc7,0x9, 0xc2,0x0, 0x12,0xb6,0xf9,0xc2,0x2, 0x12,0x2f,0xde,0xc2,0x0, 0x12,0xb6, +0xee,0xa9,0xd5,0xcb,0x74,0xf, 0x12,0x0, 0x66,0x7a,0x1b,0xb0,0x74,0xf, 0x6c,0x77, +0x12,0x28,0xba,0xe5,0xfc,0x7a,0xb, 0xb0,0x43,0xfc,0x10,0x2, 0x28,0xb3,0xa9,0xd0, +0xce,0xa2,0x2, 0xa9,0x91,0xc9,0x22,0x7e,0x34,0x3, 0xe8,0x2, 0x23,0xcc,0xd2,0x2, +0x12,0x2f,0xde,0x74,0x1, 0x22,0x12,0xc6,0xd9,0xb4,0x1, 0x19,0xca,0x39,0x7e,0x18, +0x38,0xdd,0x7e,0x8, 0x25,0xee,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x1f,0x25,0xf2,0x7e, +0xf, 0x25,0xee,0x80,0x17,0xca,0x39,0x7e,0x18,0x38,0xdd,0x7e,0x8, 0x2b,0x70,0x12, +0x20,0xc3,0x1b,0xfd,0x7e,0x1f,0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x2, 0x30,0x2f,0x7a, +0x1f,0x2a,0xfc,0x7a,0xf, 0x2a,0xf8,0x22,0x7a,0xb3,0x2b,0x0, 0x70,0x19,0x7e,0x1f, +0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x12,0x30,0x2f,0x7e,0x18,0x6, 0x76,0x7a,0x1f,0x6, +0xf4,0x7e,0x18,0x4, 0x7e,0x80,0x15,0xb4,0x1, 0x16,0x7e,0x1f,0x25,0xf2,0x7e,0xf, +0x25,0xee,0x12,0x30,0x2f,0x12,0x5d,0xd5,0x7e,0x18,0x4, 0x0, 0x7a,0x1f,0x6, 0xf8, +0x22,0x74,0x1, 0x12,0x0, 0x1e,0xe4,0x12,0x30,0x38,0x12,0x30,0x89,0xe4,0x12,0x0, +0x1e,0x74,0x1, 0x12,0x30,0x38,0x2, 0x30,0x89,0xca,0x3b,0x7e,0xd3,0x2a,0x73,0x7e, +0xc3,0x2a,0x74,0x7e,0x8, 0x1f,0x44,0x12,0xb9,0xa7,0x7e,0x8, 0x1f,0x8a,0x7e,0x34, +0x0, 0x46,0x12,0x20,0xe8,0x7e,0x8, 0x1f,0xd0,0x7e,0x34,0x0, 0xa, 0xe4,0x12,0x20, +0xe8,0x7e,0x8, 0x1f,0xda,0x7e,0x34,0x0, 0xa, 0x12,0x20,0xe8,0x7e,0xf3,0x2a,0xfc, +0x7e,0x18,0x2a,0xdc,0x7a,0x1d,0x24,0x7e,0x18,0x1f,0xd0,0x7a,0x1d,0x28,0x7c,0xbd, +0x7c,0x7c,0x7e,0x8, 0x2a,0xb9,0x12,0x31,0xdf,0x6c,0xee,0x80,0x2b,0xa, 0x3e,0x9, +0xa3,0x2a,0xdc,0xa, 0x3a,0x2e,0x34,0x20,0x7d,0x12,0x88,0x5c,0x7c,0xab,0xbe,0xa0, +0x1c,0x50,0x13,0xa, 0x3e,0x12,0x31,0xa1,0xa, 0x4a,0x19,0xb4,0x1f,0x44,0x7e,0xb3, +0x2a,0xfb,0x19,0xb4,0x1f,0x8a,0xb, 0xe0,0xbc,0xce,0x38,0xd1,0x6c,0xee,0x80,0x24, +0xa, 0x3e,0x9, 0xa3,0x2a,0xb9,0xbe,0xa0,0x23,0x50,0x17,0xa, 0x2e,0xa, 0x3c,0x2d, +0x32,0x12,0x31,0xa1,0xa, 0x4a,0x19,0xb4,0x1f,0x60,0x7e,0xb3,0x2a,0xfb,0x19,0xb4, +0x1f,0xa6,0xb, 0xe0,0xbc,0xde,0x38,0xd8,0x7e,0xb3,0x2a,0xfd,0x7e,0x8, 0x1f,0xe4, +0x60,0x9, 0x7e,0x18,0x1f,0xd0,0x12,0x7e,0x45,0x80,0x3, 0x12,0xbb,0x3b,0x6c,0xee, +0x7e,0x18,0x1f,0xe4,0x7a,0x1f,0x1f,0x34,0x74,0x2, 0xac,0xbe,0x49,0x35,0x1f,0xd0, +0x7a,0x37,0x1f,0x38,0x74,0x2, 0xac,0xbe,0x49,0x35,0x1f,0xda,0x7a,0x37,0x1f,0x3a, +0x7e,0x70,0xe, 0xac,0x7e,0x2e,0x34,0x1f,0x44,0x6d,0x22,0x7a,0x1f,0x1f,0x3c,0x7e, +0x70,0xe, 0xac,0x7e,0x2e,0x34,0x1f,0x8a,0x7a,0x1f,0x1f,0x40,0x7e,0x8, 0x1f,0x34, +0x7c,0xbf,0x7c,0x7e,0x12,0x8, 0xd1,0xb, 0xe0,0xbe,0xe0,0x5, 0x40,0xb2,0xda,0x3b, +0x22,0x2e,0x37,0x2a,0xfe,0x7e,0x39,0xb0,0x22,0x74,0x1, 0x7a,0xb3,0x38,0x9, 0x12, +0x57,0xd5,0x12,0x13,0xf5,0x12,0xba,0xb3,0xe4,0x12,0xa, 0x66,0x7e,0x24,0x3, 0xd4, +0x12,0x3a,0xf8,0x74,0x1, 0x12,0x30,0x38,0x12,0xc6,0xf2,0x7e,0x34,0xd0,0xc, 0x12, +0x1, 0xe, 0x12,0x30,0x71,0x7e,0x34,0x0, 0x1, 0xe4,0x6c,0x55,0x2, 0x13,0x1, 0x7c, +0x57,0x7c,0xab,0x6c,0x77,0x80,0x4b,0xa, 0x47,0x7e,0x7d,0x24,0x2d,0xf4,0x7e,0x7b, +0x60,0xa, 0x46,0x2e,0x44,0x20,0x7d,0x12,0xc6,0xb6,0x7c,0x6b,0xbe,0x60,0xd, 0x38, +0x12,0x7e,0xd4,0x0, 0x1, 0x7c,0xb6,0x60,0x5, 0x3e,0xd4,0x14,0x78,0xfb,0x7e,0x7d, +0x28,0x80,0x15,0x9e,0x60,0xe, 0x7e,0xd4,0x0, 0x1, 0x7c,0xb6,0x60,0x5, 0x3e,0xd4, +0x14,0x78,0xfb,0x7e,0x7d,0x28,0xb, 0xf5,0xb, 0x7a,0x40,0x4d,0x4d,0x1b,0x7a,0x40, +0xb, 0x70,0xbc,0x57,0x38,0xb1,0x6c,0x77,0x80,0x58,0xa, 0x27,0x7f,0x70,0x2d,0xf2, +0x7e,0x7b,0x60,0xbe,0x60,0xd, 0x38,0x11,0x12,0x32,0x97,0x60,0x5, 0x3e,0x44,0x14, +0x78,0xfb,0x7e,0x7d,0x28,0xb, 0xf6,0x80,0x2f,0xbe,0x60,0x1b,0x38,0x16,0x9e,0x60, +0xe, 0x12,0x32,0x97,0x60,0x5, 0x3e,0x44,0x14,0x78,0xfb,0x7e,0x7d,0x28,0x2e,0xf4, +0x0, 0x6, 0x80,0x14,0x9e,0x60,0x1c,0x12,0x32,0x97,0x60,0x5, 0x3e,0x44,0x14,0x78, +0xfb,0x7e,0x7d,0x28,0x2e,0xf4,0x0, 0x8, 0xb, 0x7a,0x20,0x4d,0x24,0x1b,0x7a,0x20, +0xb, 0x70,0xbc,0xa7,0x38,0xa4,0x22,0x7e,0x44,0x0, 0x1, 0x7c,0xb6,0x22,0x7c,0x96, +0x7c,0xa7,0x12,0x30,0x38,0x7c,0xba,0x12,0x13,0xc7,0x74,0xa, 0x12,0x2f,0x39,0x7c, +0xb9,0x12,0x0, 0x1e,0x2, 0x32,0xb7,0xca,0x3b,0x7e,0xe3,0x2a,0x74,0x7e,0xf3,0x2a, +0xfa,0x74,0x1, 0x7a,0xb3,0x2a,0xfa,0x12,0x35,0xfd,0x12,0xc6,0xc8,0x12,0x25,0x89, +0x7e,0x17,0x2a,0xfe,0x6d,0x0, 0x12,0x20,0xe8,0x7e,0xd0,0x7, 0x12,0x2f,0xe7,0x6c, +0xcc,0x80,0x19,0x7e,0x34,0x0, 0x1, 0x7c,0xbd,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb, +0x7c,0x67,0x12,0x36,0x98,0x4c,0x76,0x7a,0x29,0x70,0xb, 0xc0,0x12,0x34,0x64,0xa, +0x3c,0xbd,0x32,0x48,0xde,0x12,0x34,0x73,0x30,0x1d,0xfd,0x12,0xc6,0xac,0x7e,0xb3, +0x2a,0x73,0x7c,0x7e,0x12,0x37,0x66,0x6c,0xcc,0x80,0x29,0x74,0x2, 0xac,0xbc,0x49, +0x35,0x6, 0xfc,0xbe,0x34,0x15,0x40,0x50,0x19,0x7e,0x34,0x0, 0x1, 0x7c,0xbd,0x60, +0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7c,0xb7,0x64,0xff,0x12,0x36,0x98,0x5c,0x7b,0x7a, +0x29,0x70,0xb, 0xc0,0x12,0x34,0x64,0xa, 0x3c,0xbd,0x32,0x48,0xce,0x1b,0xd0,0xbe, +0xd0,0x0, 0x58,0x88,0x12,0x33,0xe6,0x74,0x2, 0x12,0xc6,0xe2,0x12,0x33,0x6e,0x74, +0x2, 0x12,0x0, 0x1e,0x7a,0xf3,0x2a,0xfa,0x12,0x35,0xfd,0xda,0x3b,0x22,0xca,0x79, +0x7c,0xfb,0x7e,0x8, 0x24,0xf2,0x12,0xb9,0xa7,0x7e,0xa3,0x2a,0x73,0x7e,0x73,0x2a, +0x74,0x6c,0xee,0x80,0x1d,0xa, 0x2e,0x9, 0x62,0x2a,0xdc,0xa, 0x26,0x12,0x67,0x43, +0x7c,0x6b,0xbe,0x60,0x1c,0x50,0x9, 0xa, 0x2e,0x12,0x36,0x8e,0x19,0xb2,0x24,0xf2, +0xb, 0xe0,0xbc,0x7e,0x38,0xdf,0x6c,0xee,0x80,0x1a,0xa, 0x2e,0x9, 0x62,0x2a,0xb9, +0xbe,0x60,0x23,0x50,0xd, 0xa, 0x1e,0xa, 0x27,0x2d,0x21,0x12,0x36,0x8e,0x19,0xb2, +0x25,0xe, 0xb, 0xe0,0xbc,0xae,0x38,0xe2,0x6c,0xee,0x7e,0x30,0xe, 0xac,0x3e,0x2e, +0x14,0x24,0xf2,0x6d,0x0, 0x7c,0xbf,0x7c,0x7e,0x12,0x11,0xba,0xb, 0xe0,0xbe,0xe0, +0x5, 0x40,0xe7,0xda,0x79,0x22,0xca,0xd8,0xca,0x79,0x7e,0xf0,0xa, 0x74,0x1, 0x7a, +0xb3,0x2a,0xfa,0x12,0x25,0x89,0x7c,0xe7,0x80,0x5d,0x12,0x2f,0xe7,0x12,0x34,0x73, +0x30,0x1d,0xfd,0x12,0xc6,0xac,0x12,0x37,0x5e,0x6c,0xdd,0x80,0x3d,0x7e,0x50,0x2, +0xac,0x5d,0x49,0x32,0x6, 0xfc,0xbe,0x34,0x14,0x78,0x50,0x14,0xa, 0x1d,0x2e,0x17, +0x2a,0xfe,0x7e,0x19,0xb0,0xbe,0xb0,0x0, 0x28,0x1e,0x14,0x7a,0x19,0xb0,0x80,0x18, +0xbe,0x34,0x19,0x28,0x28,0x10,0xa, 0x3d,0x12,0x31,0xa1,0xbe,0xb0,0xff,0x68,0x8, +0x4, 0x7a,0x39,0xb0,0x80,0x2, 0x1b,0xe0,0xb, 0xd0,0x12,0x34,0x64,0xa, 0x3d,0xbd, +0x32,0x48,0xba,0x4c,0xee,0x68,0x8, 0x7c,0xaf,0x1b,0xf0,0x4c,0xaa,0x78,0x9b,0xda, +0x79,0xda,0xd8,0x22,0x7e,0x73,0x2a,0x74,0xa, 0x37,0x7e,0x53,0x2a,0x73,0xa, 0x25, +0x2d,0x23,0x22,0x74,0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0xfc,0x12,0x33,0x6e,0x74, +0x2, 0x12,0x0, 0x1e,0x74,0x5, 0x7e,0x70,0x9b,0x12,0x13,0x2c,0x12,0x34,0x96,0x7e, +0xb3,0x2a,0xfc,0x2, 0xe, 0x94,0x6c,0xaa,0x80,0x22,0xa, 0x3a,0x9, 0x73,0x2a,0xdc, +0x2e,0x34,0x20,0x7d,0x12,0x88,0x5c,0x7c,0x7b,0xa, 0x47,0x7e,0x50,0x2, 0xac,0x5a, +0x7e,0xf, 0x39,0xc1,0x2d,0x12,0x79,0x40,0x0, 0x48,0xb, 0xa0,0x7e,0x63,0x2a,0x74, +0xbc,0x6a,0x38,0xd6,0x22,0xca,0x3b,0x7e,0xb3,0x38,0x7, 0xb4,0x1, 0x2, 0x80,0x2, +0xa1,0xfa,0x6c,0xcc,0x6c,0xdd,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x8, 0x7e,0xe0,0x10, +0x7e,0xf0,0x32,0x80,0x6, 0x7e,0xe0,0xa, 0x7e,0xf0,0x1e,0x12,0x87,0xf3,0x7d,0xf3, +0x12,0x69,0x78,0x50,0xfb,0x74,0x1, 0x7a,0xb3,0x39,0x87,0x12,0x30,0x38,0x12,0x13, +0xc7,0x12,0x0, 0x1e,0x74,0xa, 0x12,0x2f,0x39,0x12,0xc6,0xc8,0x7e,0xe7,0x2b,0xd, +0x7a,0xe5,0x25,0x7e,0xb3,0x2a,0xfa,0xf5,0x24,0x74,0x4, 0x7a,0xb3,0x2a,0xfa,0x7e, +0xe7,0x2b,0xd, 0x5e,0xe4,0x0, 0x3f,0x7a,0xe7,0x2b,0xd, 0x7e,0xb3,0x2a,0xfa,0x12, +0xba,0x42,0x7c,0x7b,0x74,0x6, 0xac,0x7b,0x7e,0x24,0x0, 0x4, 0x12,0x1e,0xb9,0x7d, +0x23,0x7d,0x3f,0x12,0x7e,0x3c,0xad,0x32,0x7a,0x37,0x2b,0x7, 0x12,0x35,0xfd,0x12, +0x8f,0xf5,0xa1,0xdb,0x12,0x2f,0xe7,0x30,0x11,0x2, 0xa1,0xe1,0x7c,0xbe,0x12,0x88, +0x4c,0x12,0x34,0x84,0x80,0xf, 0x80,0x7, 0x12,0x37,0x6e,0xe4,0x12,0x49,0xe7,0x20, +0x93,0xf6,0x12,0x37,0xb7,0x30,0x1d,0xf7,0x30,0x1c,0xf4,0xd2,0x1, 0x12,0x37,0xa6, +0xe4,0x12,0x13,0xde,0xb, 0xc0,0x12,0x83,0xf3,0x12,0x90,0x3d,0x7e,0xa3,0x39,0x86, +0x4c,0xaa,0x78,0x6, 0x74,0x1, 0x7a,0xb3,0x39,0x87,0x4c,0xaa,0x68,0xb, 0x7e,0xb3, +0x38,0x32,0x70,0x5, 0xe4,0x7a,0xb3,0x39,0x86,0x12,0x36,0xa2,0x78,0x18,0x7e,0xb3, +0x39,0x86,0x60,0x12,0xe4,0x7a,0xb3,0x39,0x86,0x7a,0xb3,0x2a,0x2, 0x7a,0xb3,0x2a, +0x3, 0x7e,0xd0,0x1, 0x80,0x1b,0x12,0x36,0xa2,0x68,0x10,0x7e,0xb3,0x39,0x86,0x70, +0xa, 0x7e,0xd0,0x1, 0xe4,0x7a,0xb3,0x38,0x7, 0x80,0x6, 0xbc,0xfc,0x28,0x2, 0xa1, +0x54,0xe4,0x7a,0xb3,0x2b,0x4, 0x7e,0x35,0x25,0x7a,0x37,0x2b,0xd, 0xe5,0x24,0x7a, +0xb3,0x2a,0xfa,0x4c,0xdd,0x68,0x3, 0x12,0x24,0x36,0xda,0x3b,0x22,0x7e,0x8, 0x2a, +0x6d,0x2, 0x5, 0xb4,0x7e,0xd7,0x2b,0xd, 0xbe,0xb0,0x1, 0x28,0x2, 0xe4,0x22,0x12, +0x65,0x47,0x12,0x35,0xfd,0x7a,0xd7,0x2b,0xd, 0x7e,0x73,0x2a,0xfa,0x12,0x46,0xb2, +0xe4,0x7e,0x50,0x1, 0x12,0x13,0x1, 0x12,0x34,0x84,0x74,0x1, 0x22,0xe5,0xd, 0x60, +0x5c,0xe5,0xd, 0x30,0xe0,0x6, 0x53,0xd, 0xfe,0x12,0x35,0xfd,0xe5,0xd, 0x30,0xe1, +0x14,0x53,0xd, 0xfd,0x7e,0xb3,0x38,0xe1,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x12, +0xc6,0xe2,0x12,0xb9,0x31,0xe5,0xd, 0x30,0xe2,0x33,0x53,0xd, 0xfb,0xe4,0x7a,0xb3, +0x38,0xe2,0x7e,0xb3,0x38,0xe1,0x70,0xf, 0x74,0x1, 0x12,0x0, 0x1e,0x7e,0x1f,0x2b, +0x74,0x7e,0xf, 0x2b,0x70,0x80,0xc, 0xe4,0x12,0x0, 0x1e,0x7e,0x1f,0x25,0xf2,0x7e, +0xf, 0x25,0xee,0x12,0x30,0x2f,0x7e,0xb3,0x2a,0xfc,0x2, 0x33,0x6e,0x22,0x2e,0x27, +0x2a,0xfe,0x7e,0x29,0xb0,0xa, 0x26,0x22,0xa, 0x2c,0x2e,0x27,0x2a,0xfe,0x7e,0x29, +0x70,0x22,0x7e,0x73,0x39,0xf3,0xa, 0x37,0x5e,0x34,0x0, 0x2, 0x22,0x7e,0xb3,0x2b, +0x2, 0x70,0x41,0x12,0x69,0x78,0x50,0xfb,0xe4,0x6c,0x77,0x6c,0x66,0x12,0x32,0x9e, +0x7e,0x8, 0x6, 0xfc,0x7e,0x1f,0x6, 0xf4,0x7e,0xb3,0x2b,0x72,0x12,0x36,0xf5,0x74, +0x1, 0x7e,0x70,0x1, 0x7e,0x60,0x1, 0x12,0x32,0x9e,0x7e,0x8, 0x7, 0x7a,0x7e,0x1f, +0x6, 0xf4,0x7e,0xb3,0x25,0xf0,0x12,0x36,0xf5,0x74,0x2, 0x7a,0xb3,0x2b,0x2, 0xe4, +0x7a,0xb3,0x16,0x90,0x22,0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f,0x51,0x7f,0x40,0x7f, +0x15,0x12,0x65,0x54,0x12,0xc6,0xf2,0x7e,0xe0,0x1, 0x12,0x34,0x84,0x30,0x1d,0xfd, +0x74,0x2, 0x12,0x0, 0x1e,0x7f,0x4, 0x12,0x37,0x5e,0x6c,0xdd,0x80,0x18,0x74,0x2, +0xac,0xbd,0x7f,0x14,0x2d,0x35,0xb, 0x1a,0x20,0x74,0x2, 0xac,0xbd,0x7f,0x5, 0x2d, +0x15,0x12,0xc6,0xbf,0xb, 0xd0,0x7e,0x73,0x2a,0x74,0xa, 0x7, 0x7e,0x63,0x2a,0x73, +0xa, 0x16,0x2d,0x10,0xa, 0x2d,0xbd,0x21,0x48,0xd4,0x1b,0xe0,0x78,0xbc,0x7f,0x5, +0x7c,0xbf,0x2e,0x73,0x2a,0x73,0x12,0xb9,0xb0,0xda,0x79,0xda,0xd8,0x22,0x7e,0xb3, +0x2a,0x73,0x7e,0x73,0x2a,0x74,0x12,0x10,0xee,0x74,0x2, 0x2, 0x0, 0x1e,0x74,0x81, +0x7a,0xb3,0x3a,0x3, 0x22,0x80,0x1d,0x12,0x37,0x6e,0x12,0x49,0x8a,0x68,0x5, 0xc2, +0x1, 0x12,0x37,0xa6,0x7e,0xb3,0x34,0x3a,0xbe,0xb0,0x2, 0x68,0x18,0x20,0x1c,0x15, +0xe4,0x12,0x49,0xe7,0x20,0x93,0xe0,0x12,0x37,0x6e,0xa9,0xd1,0xcd,0xa9,0xc5,0xea, +0x74,0x2, 0x2, 0x49,0xe7,0x22,0x30,0x1, 0x6, 0x12,0x2f,0xee,0x2, 0x13,0x96,0x12, +0xc7,0x9, 0xc2,0x2, 0x2, 0x2f,0xde,0x30,0x1d,0x5, 0xc2,0x1, 0x12,0x37,0xa6,0xa9, +0xd1,0xcd,0xa9,0xc5,0xea,0x30,0x1c,0x3, 0x20,0x1d,0x14,0x12,0x37,0x6e,0xa9,0xd0, +0xce,0xa9,0xc4,0xc9,0x74,0x2, 0x12,0x49,0xe7,0xa9,0xd0,0xce,0xa9,0xd4,0xc9,0xa9, +0xc1,0xcd,0xd2,0x1, 0x2, 0x37,0xa6,0xca,0xf8,0x7c,0x6b,0xa5,0xbe,0x0, 0xa, 0x7c, +0xb7,0x12,0x68,0x27,0xd2,0x8, 0x2, 0x3a,0x6a,0xa5,0xbe,0x1, 0x3d,0x7a,0x73,0x38, +0x9e,0xa5,0xbf,0xad,0x2, 0x80,0x2f,0xa5,0xbf,0xae,0x4, 0xd2,0x9, 0x41,0x6a,0xa5, +0xbf,0xaa,0x5, 0x12,0x3a,0xef,0x80,0x1e,0xa5,0xbf,0xab,0xa, 0x7e,0x34,0x5, 0x7a, +0x7a,0x37,0x32,0xe3,0x80,0x10,0xa5,0xbf,0xac,0x2, 0x80,0x2, 0x41,0x6a,0x7e,0x34, +0x4, 0xfc,0x7a,0x37,0x32,0xe3,0x6d,0x33,0x1, 0xe6,0xbe,0x60,0x4, 0x40,0x20,0xbe, +0x60,0x8, 0x38,0x1b,0x12,0x3a,0x6d,0xa5,0xbe,0x7, 0x7, 0x6d,0x33,0x7a,0x35,0xa, +0x41,0x6a,0xa5,0xbe,0x8, 0x2, 0x80,0x2, 0x41,0x6a,0x12,0x7, 0xfb,0x41,0x6a,0xa5, +0xbe,0xa, 0x9, 0x43,0xc, 0x20,0x7a,0x73,0x38,0xa7,0x41,0x6a,0xa5,0xbe,0xb, 0x8, +0x12,0x3a,0x6d,0x12,0x3a,0xba,0x41,0x6a,0xbe,0x60,0x1b,0x40,0x7, 0xbe,0x60,0x1c, +0x38,0x2, 0x41,0x2, 0xbe,0x60,0x1e,0x40,0xd, 0xbe,0x60,0x23,0x38,0x8, 0x12,0x3a, +0x6f,0x43,0xc, 0x40,0x41,0x6a,0xbe,0x60,0x15,0x40,0x1a,0xbe,0x60,0x18,0x38,0x15, +0x12,0x3a,0x6f,0xd2,0x8, 0xa5,0xbe,0x15,0x2, 0x80,0x2, 0x41,0x6a,0x74,0x7, 0x7a, +0xb3,0x38,0xa1,0x41,0x6a,0xa5,0xbe,0x19,0x7, 0xe4,0x7a,0xb3,0x38,0xb6,0x41,0x6a, +0xbe,0x60,0x24,0x40,0x7, 0xbe,0x60,0x2c,0x38,0x2, 0x41,0x2, 0xa5,0xbe,0x2d,0x1b, +0x12,0x3a,0x6f,0x20,0x9, 0x2, 0x41,0x6a,0x7e,0x63,0x38,0xc9,0x7c,0x46,0x6c,0x55, +0xa, 0x37,0x2d,0x32,0x3e,0x34,0x7a,0x35,0x8, 0x41,0x6a,0xbe,0x60,0x2f,0x40,0xa, +0xbe,0x60,0x33,0x38,0x5, 0x43,0xc, 0x8, 0x41,0x2, 0xa5,0xbe,0x34,0xf, 0x43,0xc, +0x10,0xbe,0x70,0x64,0x38,0x2, 0x41,0x2, 0x7e,0x70,0x64,0x41,0x2, 0xbe,0x60,0x38, +0x68,0x4, 0xa5,0xbe,0x39,0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x38,0xc2,0x7c,0xbf,0x4, +0x7a,0xb3,0x38,0xc2,0xa, 0x2f,0x19,0x72,0x2b,0x21,0xa5,0xbe,0x39,0x2, 0x80,0x2, +0x41,0x6a,0x75,0x1a,0x38,0x41,0x6a,0xbe,0x60,0x3a,0x68,0x4, 0xa5,0xbe,0x3b,0x21, +0x43,0xc, 0x2, 0x7e,0xf3,0x38,0xc4,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc4,0xa, 0x2f, +0x19,0x72,0x2b,0x44,0xa5,0xbe,0x3b,0x2, 0x80,0x2, 0x41,0x6a,0x75,0x1a,0x3a,0x41, +0x6a,0xa5,0xbe,0xfb,0x9, 0x43,0xc, 0x4, 0x7a,0x73,0x2b,0x12,0x41,0x6a,0xa5,0xbe, +0x50,0x6, 0x7a,0x73,0x38,0xed,0x41,0x6a,0xbe,0x60,0x3c,0x68,0x4, 0xa5,0xbe,0x3d, +0x21,0x43,0xc, 0x1, 0x7e,0xf3,0x38,0xc6,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc6,0xa, +0x2f,0x19,0x72,0x2a,0x7a,0xa5,0xbe,0x3d,0x2, 0x80,0x2, 0x41,0x6a,0x75,0x1a,0x3c, +0x41,0x6a,0xbe,0x60,0x3e,0x68,0x4, 0xa5,0xbe,0x3f,0x21,0x43,0xc, 0x1, 0x7e,0xf3, +0x38,0xc8,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xc8,0xa, 0x2f,0x19,0x72,0x2a,0x9d,0xa5, +0xbe,0x3f,0x2, 0x80,0x2, 0x41,0x6a,0x75,0x1a,0x3e,0x41,0x6a,0xbe,0x60,0x40,0x40, +0xd, 0xbe,0x60,0x42,0x38,0x8, 0x12,0x3a,0x6f,0x75,0xd, 0x1, 0x80,0xa, 0xa5,0xbe, +0x43,0xb, 0x12,0x3a,0x6f,0x75,0xd, 0x2, 0x12,0x2f,0xf6,0x80,0x7d,0xa5,0xbe,0x44, +0x8, 0x12,0x3a,0x6f,0x12,0x3a,0x76,0x80,0x71,0xbe,0x60,0x45,0x68,0x4, 0xa5,0xbe, +0x46,0x5, 0x12,0x3a,0x6f,0x80,0x63,0xbe,0x60,0x4e,0x68,0x4, 0xa5,0xbe,0x4f,0x20, +0x43,0xd, 0x4, 0x7e,0xf3,0x38,0xe3,0x7c,0xbf,0x4, 0x7a,0xb3,0x38,0xe3,0xa, 0x2f, +0x2e,0x27,0x32,0xe1,0x7a,0x29,0x70,0xa5,0xbe,0x4f,0x3f,0x75,0x1a,0x4e,0x80,0x3a, +0xa5,0xbe,0x6d,0x5, 0x7a,0x71,0xe, 0x80,0x31,0xbe,0x60,0xf0,0x40,0x25,0xbe,0x60, +0xf3,0x38,0x20,0x7c,0x16,0x2e,0x10,0x20,0x7c,0xb7,0xa5,0xf7,0xa5,0xbe,0xf3,0x1a, +0x7e,0x15,0x12,0x7e,0x5, 0x10,0x3e,0x4, 0x7e,0x1f,0x32,0xe5,0x2d,0x30,0x1b,0x1a, +0x10,0x80,0x7, 0xa5,0xbe,0xf6,0x3, 0x7a,0x71,0xf, 0xda,0xf8,0x22,0xd2,0x8, 0xa, +0x26,0x19,0x72,0x38,0x9d,0x22,0x12,0xc6,0xd9,0xb4,0x1, 0x1c,0xca,0x39,0x7e,0x18, +0x25,0xee,0x7e,0x8, 0x38,0xdd,0x12,0x20,0xc3,0x1b,0xfd,0x12,0x3a,0xbd,0x7e,0x1f, +0x25,0xf2,0x7e,0xf, 0x25,0xee,0x80,0x1f,0xca,0x39,0x7e,0x18,0x2b,0x70,0x7e,0x8, +0x38,0xdd,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x37,0x2b,0x76,0x7a,0x37,0x32,0xe1,0x7e, +0x1f,0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x2, 0x30,0x2f,0xb2,0x82,0x22,0x7e,0x37,0x25, +0xf4,0x7a,0x37,0x32,0xe1,0x22,0x12,0x3a,0xef,0x12,0x3a,0xbd,0x6d,0x33,0x7a,0x35, +0xa, 0x12,0x3b,0x25,0x12,0x3a,0xff,0x74,0x50,0x7a,0xb3,0x38,0xd1,0x7e,0x24,0x3, +0x20,0x12,0x3a,0xf8,0xe4,0x12,0xc6,0x70,0x6d,0x33,0x7a,0x37,0x3a,0x5, 0x22,0x7e, +0x34,0xd, 0xc8,0x7a,0x37,0x32,0xe3,0x22,0x7d,0x32,0x74,0xfa,0x2, 0x12,0xd0,0x7e, +0x73,0x2b,0x62,0x7a,0x73,0x38,0xd0,0x22,0xa2,0xe, 0xe4,0x33,0x7a,0xb3,0x38,0xcb, +0x7e,0x73,0x38,0xcf,0xbe,0x73,0x2b,0xf, 0x68,0xa, 0xe5,0xc, 0x70,0x6, 0x12,0x3b, +0x25,0x12,0x3a,0xff,0x22,0x7e,0x73,0x2b,0xf, 0x7a,0x73,0x38,0xcf,0x7e,0x73,0x2b, +0x1f,0x7a,0x73,0x38,0xbf,0x7e,0x73,0x2b,0x20,0x7a,0x73,0x38,0xbe,0x7e,0x73,0x2b, +0x14,0x7a,0x73,0x38,0xc0,0x22,0xca,0xd8,0xca,0x79,0x7c,0xdb,0x7e,0xa0,0x4, 0xbe, +0xd0,0x80,0x78,0x18,0x7e,0xe0,0xff,0x6c,0xff,0x80,0xb, 0x12,0x3b,0xae,0x38,0x4, +0x7c,0xeb,0x7c,0xdf,0xb, 0xf0,0xbc,0xaf,0x38,0xf1,0x80,0x1a,0xbe,0xd0,0x81,0x78, +0x15,0x6c,0xee,0x6c,0xff,0x80,0xb, 0x12,0x3b,0xae,0x40,0x4, 0x7c,0xeb,0x7c,0xdf, +0xb, 0xf0,0xbc,0xaf,0x38,0xf1,0xbc,0xad,0x38,0x2, 0x6c,0xdd,0x7c,0xbd,0x12,0x51, +0x89,0x12,0x3b,0x3d,0x12,0x3f,0x95,0x12,0x3b,0xca,0x7e,0x73,0x2b,0xf, 0x7a,0x73, +0x38,0xcf,0x12,0x3a,0xff,0x7a,0xd3,0x38,0xa7,0xda,0x79,0xda,0xd8,0x22,0x7e,0x90, +0x5, 0xac,0x9f,0x9, 0xb4,0x26,0x33,0xbc,0xbe,0x22,0x30,0x0, 0x3, 0x12,0x3b,0x3d, +0xa2,0x1, 0x92,0x2, 0x12,0x3c,0x88,0x2, 0x3b,0xca,0x7e,0x73,0x2b,0x20,0x7a,0x73, +0x38,0xbe,0x22,0x74,0x40,0x7a,0xb3,0x2b,0x20,0x12,0x57,0x8e,0x50,0x9, 0xd2,0x0, +0xd2,0x1, 0x12,0x3b,0xba,0x80,0x1c,0x74,0x1, 0x12,0x3c,0xc, 0x7e,0x43,0x38,0xbc, +0x7e,0x50,0x64,0xac,0x45,0x12,0x80,0x27,0x7a,0xb3,0x2b,0x1f,0x7e,0xf, 0x39,0xda, +0x12,0x3e,0xfb,0x12,0x3b,0xca,0x12,0x3f,0x95,0x2, 0x3b,0x3d,0xca,0x3b,0x7c,0xdb, +0xe4,0x7a,0xb3,0x2b,0x14,0x12,0x3f,0xeb,0x7e,0xc0,0xa, 0x12,0x3f,0xa5,0x30,0xf, +0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x1f,0x39,0xda,0x12,0x83,0x93,0x7d,0x73,0xbe, +0x74,0xff,0xff,0x78,0x9, 0x12,0x3c,0x7c,0x2e,0x34,0x0, 0x3, 0x80,0x18,0xbe,0x74, +0x80,0x0, 0x28,0x7, 0x12,0x3c,0x7c,0xb, 0x35,0x80,0xb, 0xbe,0x74,0x40,0x0, 0x28, +0xc, 0x12,0x3c,0x7c,0xb, 0x34,0x1b,0xa, 0x30,0x1b,0xc0,0x78,0xbe,0xbe,0xd0,0x1, +0x78,0x9, 0x7e,0x1f,0x39,0xda,0x12,0x80,0x46,0x7d,0x73,0x7e,0x1f,0x39,0xc9,0x69, +0x31,0x0, 0x1a,0x7a,0x73,0x2b,0x14,0x7d,0x37,0xda,0x3b,0x22,0x7e,0xf, 0x39,0xc9, +0x2e,0x14,0x0, 0x1a,0xb, 0xa, 0x30,0x22,0xca,0x3b,0x7e,0x34,0xff,0xff,0x7a,0x35, +0x34,0x7e,0xb3,0x38,0xb2,0xf5,0x29,0x7e,0xb3,0x2a,0x6d,0xf5,0x2a,0x7e,0xb3,0x2a, +0x6e,0xf5,0x2b,0x7e,0xb3,0x2a,0x70,0xf5,0x2c,0x7e,0xb3,0x2a,0x6f,0xf5,0x2d,0x7e, +0x34,0x27,0x10,0x7a,0x35,0x2e,0x7e,0x18,0x40,0x0, 0x7a,0x1d,0x30,0x12,0x3f,0x9e, +0x30,0xf, 0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e,0x8, 0x34,0x0, 0x12,0x3f,0xf2,0x6c, +0xff,0x80,0x34,0x9f,0x77,0x6c,0xee,0x80,0x19,0x7e,0x11,0x2b,0xac,0x1e,0x3e,0x4, +0x7e,0x30,0x2, 0xac,0x3f,0x2d,0x10,0x7e,0x1d,0x30,0x2d,0x31,0xb, 0x1a,0x30,0x12, +0x3e,0xf4,0xe5,0x2d,0xbc,0xbe,0x38,0xe1,0xe5,0x2d,0x12,0x3f,0x6b,0x74,0x2, 0xac, +0xbf,0x59,0x35,0x34,0x0, 0xb, 0xf0,0xe5,0x2c,0xbc,0xbf,0x38,0xc6,0x7e,0x34,0x10, +0x0, 0x7e,0xa1,0x2b,0x74,0x2, 0xa4,0x59,0x35,0x33,0xfe,0x6c,0xff,0x80,0x72,0x9f, +0x77,0x6c,0xee,0x80,0x12,0x12,0xc6,0x47,0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60, +0x80,0x14,0x78,0xf4,0x12,0x3e,0xf4,0xe5,0x29,0xbc,0xbe,0x38,0xe8,0xe5,0x29,0x12, +0x3f,0x6b,0x74,0x4, 0xac,0xbf,0x59,0x35,0x3, 0x70,0xe5,0x29,0xbe,0xb1,0x2c,0x50, +0x32,0x9f,0x77,0x7e,0xe1,0x29,0x80,0x12,0x12,0xc6,0x47,0x1e,0x34,0x1e,0x24,0x50, +0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x12,0x3e,0xf4,0xe5,0x2c,0xbc,0xbe,0x38,0xe8, +0xe5,0x29,0xa, 0x3b,0x6d,0x22,0xe5,0x2c,0xa, 0x1b,0x6d,0x0, 0x9f,0x1, 0x12,0x3f, +0x6f,0x80,0x4, 0x7e,0x34,0x10,0x0, 0x74,0x4, 0xac,0xbf,0x59,0x35,0x3, 0x72,0xb, +0xf0,0xe5,0x2d,0xbc,0xbf,0x38,0x88,0xe5,0x2c,0xa, 0x1b,0x6d,0x0, 0x7e,0x78,0x0, +0xcc,0x12,0x3f,0x8d,0x80,0x2e,0x74,0x2, 0xac,0xbf,0x49,0x25,0x34,0x0, 0xa, 0x5f, +0xad,0x53,0x7e,0x14,0x10,0x0, 0x9d,0x15,0xad,0x12,0x74,0xc, 0x1e,0x14,0x1e,0x4, +0x50,0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4,0x7d,0x21,0x74,0x2, 0xac,0xbf,0x59,0x25, +0x34,0x0, 0xb, 0xf0,0xe5,0x2c,0xbc,0xbf,0x38,0xcc,0xe5,0x2a,0xa, 0x1b,0x6d,0x0, +0x12,0x3f,0x8d,0x80,0x5c,0x74,0x4, 0xac,0xbf,0x49,0x25,0x3, 0x70,0xa, 0x1f,0xad, +0x13,0x7e,0xf4,0x10,0x0, 0x9d,0xf1,0xad,0xf2,0x74,0xc, 0x1e,0xf4,0x1e,0xe4,0x50, +0x4, 0x4e,0xf4,0x80,0x0, 0x14,0x78,0xf3,0x7d,0x2f,0x74,0x4, 0xac,0xbf,0x59,0x25, +0x3, 0x70,0xe5,0x29,0xbe,0xb1,0x2c,0x50,0x26,0x74,0x4, 0xac,0xbf,0x49,0x25,0x3, +0x72,0x2e,0x14,0x10,0x0, 0xad,0x12,0x74,0xc, 0x1e,0x14,0x1e,0x4, 0x50,0x3, 0x4e, +0x20,0x80,0x14,0x78,0xf4,0x7d,0x21,0x74,0x4, 0xac,0xbf,0x59,0x25,0x3, 0x72,0xb, +0xf0,0xe5,0x2a,0xbc,0xbf,0x38,0x9e,0x7e,0x73,0x38,0xb4,0xa, 0x37,0x6d,0x22,0x74, +0xc, 0x2f,0x11,0x14,0x78,0xfb,0x7e,0xf4,0x0, 0x64,0x7d,0x1f,0x12,0x1f,0x5, 0x7d, +0xe3,0x7a,0xe5,0x34,0x7e,0x73,0x38,0xb5,0xa, 0x37,0x6d,0x22,0x74,0xc, 0x2f,0x11, +0x14,0x78,0xfb,0x7d,0x1f,0x12,0x1f,0x5, 0x7d,0x63,0x6c,0xff,0x80,0x20,0x74,0x2, +0xac,0xbf,0x49,0x45,0x34,0x0, 0xbe,0x45,0x34,0x28,0x9, 0x7e,0x35,0x34,0x59,0x35, +0x34,0x0, 0x80,0x8, 0xbd,0x46,0x50,0x4, 0x59,0x65,0x34,0x0, 0xb, 0xf0,0xe5,0x2c, +0xbc,0xbf,0x38,0xda,0x6c,0xff,0x80,0x3a,0x74,0x4, 0xac,0xbf,0x49,0x45,0x3, 0x70, +0xbe,0x45,0x34,0x28,0x9, 0x7e,0x35,0x34,0x59,0x35,0x3, 0x70,0x80,0x8, 0xbd,0x46, +0x50,0x4, 0x59,0x65,0x3, 0x70,0x49,0x45,0x3, 0x72,0xbe,0x45,0x34,0x28,0x9, 0x7e, +0x35,0x34,0x59,0x35,0x3, 0x72,0x80,0x8, 0xbd,0x46,0x50,0x4, 0x59,0x65,0x3, 0x72, +0xb, 0xf0,0xe5,0x2a,0xbc,0xbf,0x38,0xc0,0x30,0x2, 0x6, 0x7e,0xd, 0x30,0x12,0x3e, +0xfb,0xda,0x3b,0x22,0x6d,0x22,0x2f,0x71,0xb, 0xe0,0x22,0x12,0x3f,0x5, 0xb, 0x34, +0x7a,0x73,0x2b,0x20,0x22,0xca,0x79,0x7f,0x10,0x9f,0x0, 0x6c,0xaa,0xa, 0x4a,0x2e, +0x44,0x60,0xac,0x12,0xc6,0xb6,0x7c,0x9b,0x7e,0xf3,0x2a,0x6e,0xac,0xf9,0x7e,0xb3, +0x2a,0x70,0xa, 0xfb,0x2d,0xf7,0x7d,0xef,0x3e,0xe4,0x7f,0x61,0x2d,0xde,0xb, 0x6a, +0xd0,0x6d,0xcc,0x2f,0x6, 0xb, 0xa0,0xbe,0xa0,0x3, 0x78,0xd1,0xbe,0x8, 0x0, 0x0, +0x78,0x2, 0xb, 0xc, 0x7e,0x54,0x0, 0x3, 0x7f,0x10,0x7d,0x15,0x12,0x1f,0x5, 0x7f, +0x1, 0xb, 0xc, 0x7e,0x34,0xc4,0x0, 0x7e,0x24,0x0, 0x9, 0x12,0x1f,0x7, 0xbe,0x34, +0x0, 0xfa,0x28,0x4, 0x7e,0x34,0x0, 0xfa,0xda,0x79,0x22,0xa, 0x1b,0x6d,0x0, 0x7f, +0x17,0x12,0x1f,0x7, 0x7f,0x71,0x7e,0x25,0x2e,0x74,0xc, 0x7d,0x13,0x7d,0x32,0x6d, +0x22,0x60,0x5, 0x2f,0x11,0x14,0x78,0xfb,0xb, 0x14,0x2, 0x1f,0x5, 0x7f,0x17,0x12, +0x1f,0x7, 0x6c,0xff,0x22,0x7e,0x73,0x2b,0x1f,0x7a,0x73,0x38,0xbf,0x22,0x7e,0x8, +0x2a,0x6d,0x12,0xd, 0x72,0xe4,0x12,0x0, 0xe, 0x74,0x1, 0x7e,0x70,0x99,0x12,0x13, +0x2c,0x2, 0x0, 0x4e,0xb4,0x3, 0x5, 0x12,0x3f,0xc4,0x80,0x2, 0xe4,0x22,0x12,0x3f, +0xa9,0x74,0x1, 0x22,0x12,0xc6,0xa3,0xe4,0x12,0x0, 0xe, 0x7e,0x8, 0x2a,0x6d,0x2, +0xd, 0x72,0x12,0x69,0x6f,0x38,0x2, 0xe4,0x22,0x12,0x69,0x67,0x49,0x55,0x34,0x3b, +0xbe,0xb0,0x2, 0x38,0x3, 0x2, 0x36,0x4, 0x2, 0x3f,0xb4,0x7e,0x8, 0x2a,0x6d,0x2, +0xd, 0x72,0x7e,0x34,0x0, 0x38,0xe4,0x2, 0x20,0xe8,0xca,0xd8,0xca,0x79,0x7e,0x73, +0x2a,0x6e,0x7e,0xf3,0x2a,0x6d,0xac,0xf7,0x7d,0x37,0x3e,0x34,0x7e,0x8, 0x1f,0x34, +0xe4,0x12,0x20,0xe8,0x7e,0xb3,0x38,0xb8,0xb4,0x1, 0x64,0x7e,0x73,0x38,0xb9,0xbe, +0x70,0x0, 0x28,0x5b,0x6c,0xdd,0x80,0x3c,0x12,0x2f,0xe7,0x12,0x24,0x8a,0x6d,0x33, +0x80,0x28,0x7e,0x35,0x24,0x3e,0x34,0x49,0x33,0xd, 0xc8,0x12,0x21,0xa, 0x7a,0x35, +0x26,0x7e,0x35,0x24,0x7d,0x13,0x3e,0x14,0x49,0x21,0x1f,0x34,0xbe,0x25,0x26,0x58, +0x7, 0x7e,0x25,0x26,0x59,0x21,0x1f,0x34,0xb, 0x34,0x7a,0x35,0x24,0xbe,0x75,0x24, +0x38,0xd0,0xb, 0xd0,0x7e,0x73,0x38,0xb9,0xbc,0x7d,0x38,0xbc,0x7d,0x37,0x3e,0x34, +0xca,0x39,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0xd, 0xc8,0x12,0x20,0xc3,0x1b,0xfd,0xda, +0x79,0xda,0xd8,0x22,0x7e,0xb3,0x38,0x6, 0xb4,0x1, 0x4, 0xe4,0x2, 0x40,0x90,0x22, +0x70,0x3, 0xd2,0x86,0x22,0xc2,0x86,0x22,0x12,0x24,0x50,0x12,0x67,0xf4,0x7e,0xb3, +0x38,0x9, 0xb4,0x1, 0x67,0x12,0xb8,0x28,0x12,0x4f,0xc5,0x12,0x88,0x7, 0x12,0x46, +0x4b,0x12,0x24,0x8a,0x50,0xe5,0x12,0x67,0x6c,0x12,0x85,0xfd,0x7e,0xb3,0x38,0x6, +0xb4,0x1, 0x4, 0xe4,0x12,0x40,0x90,0x12,0x44,0xaf,0x12,0x44,0x6c,0x40,0xcc,0x12, +0x6a,0xc3,0x12,0x44,0x6c,0x40,0xc4,0x12,0x77,0x1d,0x12,0x26,0x1b,0x12,0x47,0xc8, +0x12,0x44,0xdd,0x12,0x6f,0xf1,0x12,0x92,0x54,0x12,0x59,0xe3,0x12,0x7d,0x5a,0x12, +0x78,0x8e,0x12,0x7f,0xf6,0x12,0x79,0xe9,0x12,0x97,0xf6,0x12,0x4d,0x91,0x12,0x41, +0x12,0x12,0x4f,0xf7,0x12,0x49,0x92,0x12,0x48,0x28,0x80,0x8f,0x12,0x6a,0x6d,0x2, +0x40,0x84,0xca,0x3b,0x75,0x24,0x0, 0x6c,0xff,0x12,0x43,0x2a,0x75,0x28,0x3, 0x6c, +0xee,0x7e,0x48,0x29,0xbc,0x7e,0xb3,0x2a,0xb, 0x70,0xe, 0x7e,0xb3,0x2a,0x7, 0x70, +0x8, 0x7e,0xb3,0x2a,0x8, 0x70,0x2, 0x41,0xff,0x30,0x12,0x6, 0x7e,0x68,0x35,0xd1, +0x80,0x4, 0x7e,0x68,0x35,0x93,0x7f,0x6, 0x12,0x68,0xfc,0x7e,0x73,0x2a,0x4, 0x7a, +0x6b,0x70,0x6c,0xdd,0x41,0xb0,0x74,0x9, 0xac,0xbd,0x9, 0xc5,0x29,0xc, 0x7c,0xbc, +0x54,0xf, 0x12,0x44,0x62,0xf5,0x28,0x7c,0xbc,0x54,0xf0,0xbe,0xb0,0x0, 0x28,0x2, +0x41,0xae,0xe5,0x28,0xbe,0xb0,0x3, 0x78,0x2, 0x41,0xae,0x7e,0x8, 0x0, 0x28,0x7c, +0xbc,0x12,0x9f,0xac,0x50,0x2, 0x41,0xae,0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xd, +0xf5,0x25,0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xe, 0xc4,0x54,0xf0,0xf5,0x26,0x7e, +0x73,0x2a,0x4d,0xbc,0x7c,0x28,0x54,0x7e,0xb3,0x2a,0x9, 0x70,0x2a,0x75,0x29,0xf, +0x7e,0x8, 0x0, 0x25,0xa, 0x3c,0x2e,0x34,0x35,0x7f,0x6d,0x22,0x74,0x1, 0x12,0x46, +0x9, 0x75,0x29,0x20,0x7e,0x8, 0x0, 0x26,0xa, 0x3c,0x2e,0x34,0x35,0x89,0x6d,0x22, +0x74,0x10,0x12,0x46,0x9, 0x80,0xe, 0xa, 0x3c,0x9, 0xb3,0x35,0x7f,0xf5,0x25,0x9, +0xb3,0x35,0x89,0xf5,0x26,0xa, 0x3c,0x12,0x44,0x64,0xb4,0x1, 0xe, 0xe4,0xa, 0x3c, +0x19,0xb3,0x35,0x7f,0x19,0xb3,0x35,0x89,0x12,0x43,0x2a,0x7e,0xb3,0x2a,0x64,0xb4, +0xff,0x13,0x75,0x25,0x0, 0x74,0x9, 0xac,0xbd,0x9, 0xb5,0x29,0xc, 0xbe,0xb0,0xff, +0x68,0x3, 0x75,0x25,0x1, 0x7e,0x90,0x9, 0xac,0x9d,0x49,0xb4,0x29,0x8, 0x49,0xa4, +0x29,0xa, 0xe5,0x28,0xb4,0x1, 0x27,0x75,0x27,0x0, 0x7e,0x71,0x27,0x74,0x9, 0xac, +0x7b,0x9, 0xb3,0x36,0x13,0x54,0xf, 0xbc,0xbc,0x78,0xa, 0x49,0xb3,0x36,0xf, 0x49, +0xa3,0x36,0x11,0x80,0x9, 0x5, 0x27,0xe5,0x27,0xbe,0xb0,0xa, 0x40,0xdc,0x5e,0xb4, +0xf, 0xff,0x5e,0xa4,0xf, 0xff,0x9, 0x74,0x29,0xc, 0xa, 0x57,0xc4,0x54,0xf0,0x7c, +0xab,0xe4,0x2d,0xa5,0xbe,0x70,0xff,0x68,0x16,0xe5,0x28,0xbe,0xb0,0x1, 0x68,0x2, +0x5, 0x24,0xb, 0xf0,0xe5,0x28,0xa, 0x5b,0x12,0x7f,0x90,0x2d,0xb5,0x80,0x4, 0x2e, +0xb4,0xc0,0x0, 0x7e,0x70,0x6, 0xac,0x7e,0x7f,0x6, 0x2d,0x13,0x79,0xb0,0x0, 0x2, +0x7f,0x6, 0x2d,0x13,0x79,0xa0,0x0, 0x4, 0xe5,0x25,0x7f,0x6, 0x2d,0x13,0x39,0xb0, +0x0, 0x6, 0xe5,0x26,0x2d,0x3d,0x7d,0x2c,0x39,0xb1,0x0, 0x7, 0xb, 0xe0,0xb, 0xd0, +0x7e,0x73,0x2a,0x4d,0xbc,0x7d,0x28,0x2, 0x21,0x56,0xe5,0x24,0x39,0xb6,0x0, 0x1, +0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x9, 0x7e,0xb3,0x2a,0x8, 0xb4,0x1, 0x17,0x80,0xd, +0xbe,0xf0,0x0, 0x38,0x6, 0x7e,0xb3,0x2a,0x8, 0x60,0xa, 0xb2,0x12,0x12,0x68,0x52, +0x74,0x1, 0x12,0x40,0x90,0x7e,0xb3,0x2a,0x7, 0x60,0x5, 0x7f,0x4, 0x12,0x59,0xb1, +0xe4,0x7a,0xb3,0x2a,0xb, 0x7a,0xb3,0x2a,0x7, 0x7a,0xb3,0x2a,0x8, 0x80,0x4, 0xe4, +0x12,0x40,0x90,0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x29,0x8, 0x7e,0x8, 0x36, +0xf, 0x12,0x20,0xc3,0x1b,0xfd,0x4c,0xff,0x78,0xd, 0x7e,0x8, 0x36,0xf, 0x7e,0x34, +0x0, 0x5a,0x74,0xff,0x12,0x20,0xe8,0xda,0x3b,0x22,0x75,0x25,0x0, 0x75,0x26,0x0, +0x22,0xca,0x3b,0x6c,0xff,0x7e,0xb3,0x2a,0x6f,0xf5,0x29,0x7e,0xe3,0x2a,0x70,0x6c, +0xdd,0x7e,0xb3,0x16,0x91,0xbe,0xb0,0x1, 0x68,0xf, 0x60,0x2, 0x81,0x52,0x7e,0xb3, +0x28,0x84,0xb4,0x1, 0x2, 0x80,0x2, 0x81,0x52,0x6c,0xcc,0x81,0x44,0x12,0x97,0xd4, +0xf5,0x27,0x9, 0xb3,0x26,0xfb,0xf5,0x28,0x75,0x25,0x2, 0x75,0x26,0x2, 0x12,0xa1, +0xbe,0x50,0x6, 0x75,0x25,0x3, 0x75,0x26,0x3, 0x7c,0xbc,0x12,0x70,0x47,0xd2,0x0, +0x12,0x67,0xa3,0xe5,0x27,0x60,0xe, 0xe5,0x29,0xa, 0x2b,0x1b,0x24,0xe5,0x27,0xa, +0x3b,0xbd,0x32,0x48,0x3, 0x75,0x25,0x1, 0xe5,0x28,0x60,0xc, 0xa, 0x2e,0x1b,0x24, +0xe5,0x28,0xa, 0x3b,0xbd,0x32,0x48,0x3, 0x75,0x26,0x1, 0x75,0x24,0x0, 0x80,0x6a, +0xe5,0x24,0xbc,0xbc,0x68,0x62,0x12,0xb5,0x9b,0x7a,0xa1,0x2a,0x9, 0xb3,0x26,0xfb, +0xf5,0x2b,0xa, 0x2a,0xe5,0x27,0x12,0x44,0x5b,0xbe,0x34,0x0, 0x3, 0x18,0x11,0x12, +0x44,0x55,0xbe,0x34,0x0, 0x3, 0x18,0x8, 0x75,0x25,0x1, 0x75,0x26,0x1, 0x80,0x3f, +0xe5,0x2a,0xa, 0x2b,0xe5,0x27,0x12,0x44,0x5b,0xbe,0x34,0x0, 0x8, 0x18,0xf, 0xe5, +0x2a,0xa, 0x2b,0xe5,0x27,0x12,0x44,0x5b,0xbe,0x34,0x0, 0x3, 0x18,0x12,0x12,0x44, +0x55,0xbe,0x34,0x0, 0x8, 0x18,0x11,0x12,0x44,0x55,0xbe,0x34,0x0, 0x3, 0x8, 0x8, +0x75,0x25,0x2, 0x75,0x26,0x2, 0x80,0x7, 0x5, 0x24,0x12,0x8f,0xd6,0x38,0x91,0xe5, +0x27,0x7e,0x71,0x28,0x12,0x88,0xe8,0x50,0x6, 0x12,0x44,0x84,0x12,0x43,0x2a,0xe5, +0x25,0x7e,0x71,0x26,0x7c,0x6c,0x7c,0x5f,0x7c,0x4d,0x12,0x80,0xa3,0x12,0x44,0x84, +0xb, 0xf0,0xb, 0xc0,0x7e,0x73,0x28,0x84,0xbc,0x7c,0x28,0x2, 0x61,0x5d,0x7a,0xf3, +0x28,0x84,0xda,0x3b,0x22,0xe5,0x2b,0xa, 0x2b,0xe5,0x28,0xa, 0x3b,0x9d,0x32,0x2, +0x21,0xa, 0xa, 0x3b,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0xb0,0x22,0xc2,0x0, 0x7e,0xb3, +0x16,0x91,0x60,0x6, 0x7e,0xb3,0x16,0x90,0x70,0x7, 0x12,0x97,0xcc,0x28,0x2, 0xd2, +0x0, 0xa2,0x0, 0x22,0x6c,0x33,0x6c,0x22,0x80,0x1c,0x7c,0xb2,0x12,0x67,0x50,0x50, +0x13,0x7c,0xb2,0x12,0x67,0x98,0x7d,0x3, 0x12,0x67,0xda,0x49,0x55,0x39,0xe9,0x7d, +0x40,0x12,0xc6,0x79,0xb, 0x20,0x7e,0x73,0x2a,0x75,0xbc,0x72,0x38,0xdc,0x22,0x12, +0x45,0xb8,0x12,0x44,0xc1,0x12,0x44,0xcc,0x30,0x16,0x5, 0x12,0x44,0x84,0xc2,0x16, +0x22,0x2, 0x44,0xc4,0x7e,0x73,0x2a,0x6b,0x2e,0x70,0xff,0x22,0x12,0x44,0xc4,0x40, +0xb, 0x12,0xab,0x58,0xe4,0x7a,0xb3,0x3, 0xfd,0x2, 0x45,0xbe,0x22,0xca,0x3b,0x7e, +0x73,0x38,0x26,0xa, 0x37,0x6d,0x22,0x7a,0x1d,0x26,0x7e,0x33,0x38,0x28,0xa, 0xf3, +0x6d,0xee,0x7a,0x7d,0x2a,0x7e,0x33,0x38,0x27,0xa, 0x93,0x6d,0x88,0x7e,0x33,0x38, +0x29,0xa, 0x73,0x6d,0x66,0x7e,0x44,0x4, 0x38,0x7d,0x14,0x12,0x1e,0xfc,0x12,0x45, +0xb1,0x7a,0x1d,0x26,0x7e,0x54,0x7, 0x80,0x7f,0x17,0x7d,0x15,0x12,0x1e,0xfc,0x12, +0x45,0xb1,0x7a,0x1d,0x2a,0x7f,0x14,0x7d,0x14,0x12,0x1e,0xfc,0x12,0x45,0xb1,0x7f, +0x41,0x7f,0x13,0x7d,0x15,0x12,0x1e,0xfc,0x7c,0xf6,0x7c,0xe5,0xa, 0x64,0x12,0x44, +0xc4,0x50,0x60,0x7e,0xb3,0x16,0x91,0xb4,0x1, 0x59,0x75,0x2e,0x0, 0x80,0x4b,0x7e, +0xa1,0x2e,0x74,0x9, 0xa4,0x49,0x35,0x27,0x76,0x12,0x7a,0xa2,0x7a,0x35,0x24,0x7e, +0xa1,0x2e,0x74,0x9, 0xa4,0x49,0x35,0x27,0x78,0x12,0x78,0xeb,0x7d,0xa3,0x7e,0x35, +0x24,0x6d,0x22,0x7e,0xd, 0x26,0xbf,0x10,0x40,0x17,0x7d,0x5a,0x6d,0x44,0x7e,0xd, +0x2a,0xbf,0x20,0x40,0xc, 0xbf,0x14,0x38,0x8, 0x7d,0x3a,0x6d,0x22,0xbf,0x13,0x28, +0x7, 0xe5,0x2e,0x6c,0x77,0x12,0x73,0x2e,0x5, 0x2e,0x7e,0x73,0x28,0x84,0xbe,0x71, +0x2e,0x38,0xac,0xda,0x3b,0x22,0x9d,0x32,0x12,0x21,0xa, 0x7d,0x13,0x7d,0x30,0xad, +0x31,0x7c,0x76,0x7c,0x65,0xa, 0x24,0x22,0x12,0x47,0xcb,0x2, 0x45,0xbe,0xe4,0x7a, +0xb3,0x28,0x93,0x12,0xa3,0x3f,0x12,0xbc,0x1a,0x7e,0xb3,0x16,0x91,0xb4,0x1, 0x8, +0x7e,0x73,0x28,0x84,0x7a,0x73,0x28,0x92,0x7e,0x18,0x4, 0xfc,0x7a,0x1f,0x6, 0xf8, +0x12,0x5d,0xd5,0x12,0x89,0x37,0x12,0x86,0x47,0x7e,0xb3,0x16,0x90,0xb4,0x1, 0x18, +0x7e,0x73,0x26,0x83,0x7a,0x73,0x26,0xf3,0x7e,0x73,0x26,0x85,0x7a,0x73,0x26,0xf5, +0x7e,0x73,0x26,0x84,0x7a,0x73,0x26,0xf4,0x22,0x7c,0x9b,0x7f,0x71,0x7e,0x7b,0x80, +0x4c,0x88,0x78,0x7, 0x7e,0xb, 0x90,0x7a,0x7b,0x90,0x22,0xa, 0x28,0x7e,0xb, 0x80, +0xa, 0x38,0x9d,0x32,0x12,0x21,0xa, 0xe5,0x29,0xa, 0x2b,0xbd,0x32,0x8, 0x15,0x7e, +0x7b,0xa0,0x7e,0xb, 0xb0,0xbc,0xba,0x7c,0xba,0x28,0x4, 0x2c,0xb9,0x80,0x2, 0x9c, +0xb9,0x7a,0x7b,0xb0,0x7e,0x7b,0x70,0x7a,0xb, 0x70,0x22,0x7e,0x24,0x37,0xe2,0x30, +0x11,0x54,0xc2,0x11,0x9, 0x72,0x0, 0x2, 0x12,0x46,0xa7,0x7a,0x37,0x2a,0x4f,0x9, +0x72,0x0, 0x3, 0x12,0x46,0xa7,0x7a,0x37,0x2a,0x51,0x9, 0x72,0x0, 0x4, 0x12,0x46, +0xa7,0x7a,0x37,0x2a,0x53,0x7e,0x29,0x70,0x12,0x46,0xb2,0x7a,0x37,0x2a,0x5a,0x9, +0x72,0x0, 0x1, 0x12,0x46,0xb2,0x7a,0x37,0x2a,0x5c,0x9, 0x72,0x0, 0x5, 0x12,0x46, +0xa7,0x7a,0x37,0x2a,0x62,0x9, 0x72,0x0, 0x41,0xbe,0x73,0x2a,0x6b,0x68,0x7, 0x7a, +0x73,0x2a,0x6b,0x2, 0x47,0xda,0x22,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x3e,0x34,0x3e, +0x34,0x22,0xa, 0x37,0x3e,0x34,0x3e,0x34,0x22,0x7e,0x30,0x64,0x7e,0x20,0x64,0x6c, +0x11,0x80,0x4a,0xa, 0x31,0xb, 0x34,0x7c,0x7, 0x80,0x38,0x7e,0x70,0x2, 0xac,0x70, +0x9, 0xb3,0x26,0xfa,0x12,0x47,0x2e,0x9, 0xb3,0x26,0xfa,0x12,0x44,0x5b,0x7c,0x97, +0x7e,0x70,0x2, 0xac,0x70,0x9, 0xb3,0x26,0xfb,0x12,0x47,0x2e,0x9, 0xb3,0x26,0xfb, +0x12,0x44,0x5b,0x7c,0x87,0xbc,0x39,0x28,0x2, 0x7c,0x39,0xbc,0x28,0x28,0x2, 0x7c, +0x28,0xb, 0x0, 0x7e,0xb3,0x28,0x84,0xbc,0xb0,0x38,0xc0,0xb, 0x10,0x7e,0xb3,0x28, +0x84,0xbc,0xb1,0x38,0xae,0xa5,0xbb,0x64,0x2, 0x6c,0x33,0xa5,0xba,0x64,0x2, 0x6c, +0x22,0xbc,0x23,0x28,0x4, 0x7c,0xa2,0x80,0x2, 0x7c,0xa3,0x7c,0xba,0x22,0xa, 0x2b, +0x7e,0x70,0x2, 0xac,0x71,0x22,0xca,0x79,0x7c,0xe5,0x7c,0xfb,0x7e,0xe4,0xff,0xfc, +0x7c,0xb4,0x12,0xa0,0x0, 0x7d,0x3, 0x74,0x9, 0xac,0xbf,0x12,0x7f,0xa8,0x12,0x45, +0xa6,0x7d,0x13,0x5e,0x30,0xfc,0x7e,0x70,0x9, 0xac,0x7f,0x49,0xf3,0x29,0x62,0x74, +0x9, 0xac,0xbe,0x49,0x25,0x28,0xae,0xbd,0x2f,0x28,0xf, 0x7d,0x53,0x2e,0x54,0x29, +0x62,0x7d,0x2f,0x2d,0x21,0x1b,0x58,0x20,0x80,0x9, 0x2e,0x34,0x29,0x62,0x9d,0xf1, +0x1b,0x38,0xf0,0x74,0x9, 0xac,0xbf,0x49,0x25,0x29,0x64,0x74,0x9, 0xac,0xbe,0x49, +0x35,0x28,0xb0,0x12,0x45,0xa6,0x7d,0x13,0x5d,0x1e,0x7e,0x50,0x9, 0xac,0x5f,0x49, +0x32,0x29,0x64,0x74,0x9, 0xac,0xbe,0x49,0x5, 0x28,0xb0,0xbd,0x3, 0x28,0xd, 0x7d, +0x2, 0x2e,0x4, 0x29,0x64,0x2d,0x13,0x1b,0x8, 0x10,0x80,0x9, 0x2e,0x24,0x29,0x64, +0x9d,0x31,0x1b,0x28,0x30,0xda,0x79,0x22,0x2, 0x43,0x31,0x12,0x47,0xe2,0x2, 0x47, +0xd1,0x12,0x44,0xc4,0x50,0x3, 0x2, 0x48,0x9, 0x22,0x12,0x44,0xc4,0xd2,0x1a,0x2, +0x26,0x11,0x12,0x5d,0xde,0x7e,0x34,0x0, 0x78,0x7a,0x37,0x2a,0x5c,0x7e,0x34,0xff, +0x6a,0x7a,0x37,0x2a,0x5e,0x2, 0x47,0xf8,0x7e,0x34,0x0, 0xfa,0x7a,0x37,0x2a,0x4f, +0x7a,0x37,0x2a,0x51,0x7a,0x37,0x2a,0x53,0x22,0x7e,0x34,0x0, 0x32,0x7a,0x37,0x2a, +0x5a,0x7e,0x34,0x0, 0x28,0x7a,0x37,0x2a,0x5c,0x7e,0x34,0x0, 0x78,0x7a,0x37,0x2a, +0x4f,0x7e,0x34,0x0, 0x64,0x2, 0x48,0x0, 0x7e,0x8, 0x38,0xf4,0x12,0x48,0x5c,0x7e, +0x8, 0x38,0xfc,0x12,0x48,0x5c,0x12,0x48,0x71,0x12,0x48,0x78,0x2, 0x48,0x3f,0x7e, +0x37,0x38,0xf4,0xbe,0x34,0x0, 0x0, 0x28,0x12,0x7e,0x73,0x3a,0x8, 0xbe,0x70,0x5, +0x50,0x9, 0x7e,0xb3,0x38,0x32,0x70,0x3, 0x12,0x48,0x7f,0x22,0xb, 0xa, 0x30,0xe5, +0x5e,0xa, 0x2b,0xbd,0x32,0x28,0x4, 0x9d,0x32,0x80,0x2, 0x6d,0x33,0x1b,0xa, 0x30, +0x22,0x7e,0x8, 0x2b,0xb7,0x2, 0x48,0x5c,0x7e,0x8, 0x39,0xe7,0x2, 0x48,0x5c,0x6d, +0x33,0x7a,0x37,0x39,0x84,0x74,0x1, 0x7a,0xb3,0x38,0x7, 0x22,0x7e,0xb3,0x38,0x7, +0x14,0x68,0x51,0x14,0x78,0x2, 0x21,0x20,0x14,0x68,0x61,0x24,0x3, 0x78,0x79,0x12, +0x49,0x26,0x38,0x8, 0x30,0x14,0xf, 0x12,0x4f,0xd4,0x68,0xa, 0x12,0x4a,0x2e,0xe4, +0x7a,0xb3,0x39,0x86,0x80,0x6a,0x7e,0xb3,0x37,0xe8,0x30,0xe0,0x63,0x7e,0x73,0x37, +0xe9,0xa, 0x27,0x7e,0x34,0x4, 0x0, 0xad,0x32,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x4, +0x7e,0x34,0x5, 0xf4,0xbe,0x37,0x39,0x84,0x50,0x46,0x12,0x48,0x7f,0xe4,0x7a,0xb3, +0x39,0x88,0x80,0x3c,0x12,0x49,0x26,0x28,0x32,0xe4,0x7a,0xb3,0x38,0x7, 0x7e,0xb3, +0x39,0x86,0xb4,0x1, 0x3, 0x12,0x48,0x85,0xd2,0x1c,0x80,0x1f,0x74,0xff,0x7a,0xb3, +0x37,0xe1,0x12,0x4f,0xc5,0x12,0x49,0xb2,0x12,0x23,0x3b,0xe4,0x7a,0xb3,0x38,0x7, +0x7a,0xb3,0x3a,0x8, 0xd2,0x1c,0x80,0x8, 0x12,0x48,0x85,0xe4,0x7a,0xb3,0x3a,0x8, +0x12,0x49,0x2e,0x2, 0x34,0xc5,0x7e,0x73,0x2a,0x2, 0xbe,0x70,0x0, 0x22,0x74,0x1, +0x12,0x49,0x4d,0x20,0x1c,0x6, 0x12,0x49,0x70,0x12,0x0, 0x6e,0x7e,0xb3,0x34,0x3a, +0xb4,0x1, 0x6, 0x12,0x49,0x56,0x12,0x0, 0x6e,0xe4,0x2, 0x49,0x4d,0xbe,0xb0,0x8, +0x50,0x3, 0x12,0x4f,0xdc,0x22,0x74,0xc8,0x7a,0xb3,0x3a,0x7, 0xc2,0x1c,0x80,0xa, +0x12,0x37,0x75,0x30,0x1c,0x4, 0x75,0xe9,0xff,0x22,0x12,0x49,0x8a,0x68,0xf1,0x22, +0xd2,0x0, 0x80,0x12,0x30,0x0, 0xc, 0x12,0x49,0x8a,0x68,0x7, 0xc2,0x0, 0xc2,0x1, +0x12,0x37,0xa6,0x12,0x37,0x75,0x30,0x1c,0xeb,0x22,0x7e,0xb3,0x34,0x3a,0xbe,0xb0, +0x1, 0x22,0x12,0x48,0x8c,0x7e,0x73,0x37,0xe1,0xbe,0x70,0xff,0x68,0x13,0xbe,0x73, +0x38,0x7, 0x68,0xd, 0x7a,0x73,0x38,0x7, 0x74,0xff,0x7a,0xb3,0x37,0xe1,0x2, 0x48, +0x8c,0x22,0x12,0x37,0x6e,0x12,0x49,0xde,0x75,0xcd,0x0, 0xa9,0xd6,0xeb,0xa9,0xd7, +0xcd,0xc2,0xce,0x12,0x4f,0xee,0x12,0x2f,0xaf,0x74,0x1, 0x12,0x49,0xe7,0xa9,0xc6, +0xeb,0xa9,0xc7,0xcd,0xd2,0xce,0xe5,0x25,0x7e,0x71,0x24,0x2, 0x2f,0xf, 0x12,0x49, +0x8a,0x68,0xfb,0x20,0x93,0xfd,0x22,0x7c,0xab,0x7e,0xb3,0x3a,0x3, 0xb4,0x81,0x38, +0x4c,0xaa,0x78,0x5, 0xa9,0xd0,0x87,0x80,0x29,0xbe,0xa0,0x1, 0x78,0xf, 0xc2,0xaf, +0xa9,0xd0,0xce,0xa9,0xc7,0xc9,0xa9,0xd1,0x87,0xd2,0xaf,0x80,0x15,0xbe,0xa0,0x2, +0x78,0x16,0xc2,0xaf,0x20,0x93,0x9, 0xa9,0xd0,0xce,0xa9,0xd7,0xc9,0xa9,0xd1,0x87, +0xd2,0xaf,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4,0x7a,0xb3,0x3a,0x3, 0x22,0x6d,0x33, +0x7a,0x37,0x39,0x84,0x22,0xca,0xf8,0x7e,0xa3,0x2a,0x2, 0x7e,0x73,0x2a,0x3, 0xbe, +0xa0,0x1, 0x38,0x21,0xbe,0x70,0x1, 0x38,0x1c,0x7e,0x27,0x28,0x86,0xbe,0x24,0x0, +0x1e,0x28,0x2, 0x80,0x10,0x7e,0xf3,0x2f,0x80,0x4c,0xff,0x68,0x17,0x7e,0x27,0x2b, +0xb7,0x4d,0x22,0x78,0xf, 0x12,0x4a,0x2e,0x74,0x1, 0x7a,0xb3,0x39,0x86,0x7a,0xb3, +0x38,0x7, 0x80,0x36,0x4c,0xaa,0x78,0x37,0xa5,0xbf,0x1, 0x33,0x7e,0x37,0x2b,0xb7, +0x7a,0x37,0x2f,0x82,0x7e,0xb3,0x2f,0x80,0xb4,0x3, 0x1f,0x7e,0x37,0x2b,0xb7,0xbe, +0x34,0x0, 0x0, 0x28,0x15,0x74,0x4, 0x7a,0xb3,0x2f,0x80,0x7e,0x37,0x2f,0x98,0x7e, +0x27,0x2f,0x9a,0x12,0x4b,0x3e,0x61,0x37,0x80,0x0, 0x12,0xbe,0x2f,0x61,0x37,0x7e, +0x63,0x34,0x88,0x7e,0x50,0x9, 0xac,0x56,0x49,0xc2,0x29,0x8, 0x49,0xd2,0x29,0xa, +0x4c,0xff,0x78,0x1b,0xa5,0xbf,0x0, 0x43,0xbe,0xa0,0x1, 0x78,0x3e,0x7d,0x3c,0x7d, +0x2d,0x12,0xbd,0xcd,0x12,0x4b,0x3a,0x74,0x1, 0x7a,0xb3,0x2f,0x80,0x80,0x2c,0xbe, +0xf0,0x1, 0x78,0x1a,0x12,0x4c,0x76,0xbe,0x34,0x0, 0x64,0x38,0x9, 0x12,0x4c,0x1, +0xbe,0x34,0x0, 0xa0,0x28,0x15,0x74,0x3, 0x7a,0xb3,0x2f,0x80,0x80,0x5, 0xbe,0xf0, +0x3, 0x78,0x8, 0x7a,0xc7,0x2f,0x98,0x7a,0xd7,0x2f,0x9a,0x7e,0xb3,0x2f,0x80,0x60, +0x26,0x7d,0x3c,0x7d,0x2d,0x7e,0x17,0x2b,0xbb,0x7e,0x7, 0x2b,0xbd,0x12,0x4b,0xe9, +0xa, 0x2b,0x7e,0x73,0x2f,0x7f,0xa, 0x37,0xbd,0x32,0x58,0xb, 0x12,0x4b,0x3a,0x7a, +0xc7,0x2b,0xbb,0x7a,0xd7,0x2b,0xbd,0xda,0xf8,0x22,0x7d,0x3c,0x7d,0x2d,0x7d,0x42, +0x7d,0x13,0x7d,0x24,0x12,0x4f,0x6a,0x7d,0x31,0x12,0x4c,0xa, 0x2, 0x4b,0x4f,0x7e, +0x3, 0x2f,0xa8,0xbe,0x0, 0xf0,0x50,0x2, 0x61,0xe8,0x61,0xdd,0x6c,0x99,0x7e,0xb3, +0x2f,0x7f,0xbe,0xb0,0x20,0x50,0x5, 0x4, 0x7a,0xb3,0x2f,0x7f,0x7e,0x1f,0x2b,0xbf, +0x7a,0x1f,0x1f,0x34,0x7e,0x80,0x1, 0x80,0x49,0x74,0x4, 0xac,0xb8,0x49,0x35,0x2b, +0xbf,0x49,0x25,0x2b,0xc1,0x7e,0x17,0x1f,0x34,0x7e,0x7, 0x1f,0x36,0x12,0x4b,0xe9, +0x7c,0x1b,0x7e,0x3, 0x2f,0x7f,0xbc,0x1, 0x38,0x26,0xb, 0x90,0x7e,0x70,0x4, 0xac, +0x78,0x2e,0x34,0x2b,0xbf,0x7e,0x14,0x1f,0x34,0x74,0x4, 0x12,0x1f,0x8c,0x7e,0x34, +0x1f,0x34,0x7e,0x30,0x4, 0xac,0x39,0x2e,0x14,0x2b,0xbf,0x74,0x4, 0x12,0x1f,0x8c, +0xb, 0x80,0x7e,0x3, 0x2f,0xa8,0xbc,0x8, 0x38,0xaf,0xa, 0x59,0xb, 0x54,0x7c,0xb, +0x7a,0x3, 0x2f,0xa8,0x7e,0x3, 0x2f,0x7f,0xbe,0x0, 0x20,0x50,0xb, 0x7e,0x3, 0x2f, +0xa8,0xbe,0x0, 0xec,0x40,0x2, 0x61,0x5c,0x22,0x7d,0x51,0x7d,0x12,0x9d,0x35,0x12, +0x21,0xa, 0x7c,0xa7,0x12,0x4f,0xe, 0x7c,0xb7,0xbc,0xba,0x50,0x3, 0x7c,0xba,0x22, +0x22,0x7e,0x37,0x2f,0x96,0x9e,0x37,0x2f,0x8e,0x22,0x7e,0x17,0x2f,0x90,0xbd,0x13, +0x28,0xa, 0x7a,0x37,0x2f,0x90,0x7a,0x27,0x2f,0x92,0x80,0x10,0x7e,0x17,0x2f,0x88, +0xbd,0x13,0x50,0x8, 0x7a,0x37,0x2f,0x88,0x7a,0x27,0x2f,0x8a,0x7e,0x17,0x2f,0x8e, +0xbd,0x12,0x28,0xa, 0x7a,0x27,0x2f,0x8e,0x7a,0x37,0x2f,0x8c,0x80,0x10,0x7e,0x17, +0x2f,0x96,0xbd,0x12,0x50,0x8, 0x7a,0x27,0x2f,0x96,0x7a,0x37,0x2f,0x94,0x7e,0xb3, +0x2f,0xa8,0xb4,0xa, 0xf, 0x12,0x4c,0x76,0x7a,0x37,0x2f,0xa0,0x12,0x4c,0x1, 0x7a, +0x37,0x2f,0xa2,0x22,0xb4,0x14,0xe, 0x12,0x4c,0x76,0x7a,0x37,0x2f,0xa4,0x12,0x4c, +0x1, 0x7a,0x37,0x2f,0xa6,0x22,0x7e,0x37,0x2f,0x88,0x9e,0x37,0x2f,0x90,0x22,0x12, +0x4c,0x76,0x7a,0x37,0x2f,0x9c,0x12,0x4c,0x1, 0x7a,0x37,0x2f,0x9e,0x12,0x4d,0xd0, +0x60,0x1, 0x22,0x7e,0x73,0x2f,0xa8,0xa, 0x37,0x7a,0x35,0x24,0x7e,0x8, 0x2b,0xbf, +0x7e,0x18,0x2f,0x80,0x2, 0x4c,0xa7,0xca,0xf8,0x7e,0x45,0x24,0x7c,0xb9,0x7a,0xb3, +0x39,0x40,0x74,0xff,0x7a,0xb3,0x39,0x3f,0x6d,0x55,0x80,0x19,0x7d,0xf5,0x3e,0xf4, +0x12,0x4f,0x17,0x7d,0xe5,0x3e,0xe4,0x59,0xfe,0x1f,0x34,0x69,0xf6,0x0, 0x2, 0x59, +0xfe,0x21,0x14,0xb, 0x54,0xbd,0x45,0x38,0xe3,0x7e,0x33,0x39,0x40,0xbe,0x30,0x4, +0x38,0x2, 0xa1,0x69,0x69,0xf1,0x0, 0x1c,0x69,0x11,0x0, 0x1e,0xbd,0x1f,0x18,0x19, +0x4d,0x11,0x78,0x4, 0x7e,0x14,0x0, 0x1, 0x7d,0x3f,0x7d,0x21,0x12,0x1e,0xb9,0x7c, +0xf7,0x74,0x40,0x7a,0xb3,0x39,0x43,0x80,0x43,0x4d,0xff,0x78,0x4, 0x7e,0xf4,0x0, +0x1, 0x7d,0x31,0x7d,0x2f,0x12,0x1e,0xb9,0x7c,0xf7,0x74,0x80,0x7a,0xb3,0x39,0x43, +0x7d,0xf, 0x2d,0xf, 0xbd,0x1, 0x8, 0x24,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x39,0x43, +0xa, 0x37,0x6d,0x22,0x12,0x1e,0xeb,0x7d,0x5f,0x1a,0x4a,0x1a,0x48,0x7d,0x1f,0x1a, +0x2, 0x1a,0x0, 0x2f,0x2, 0x12,0x1f,0x7, 0x7a,0x73,0x39,0x43,0xbe,0xf0,0x5, 0x58, +0x14,0x12,0x4d,0x88,0x12,0xc1,0xd5,0x12,0x4d,0x88,0x12,0xc3,0x7c,0x12,0x4d,0x88, +0x12,0xc2,0xc0,0x80,0xa, 0x74,0x7d,0x80,0x2, 0x74,0x7f,0x7a,0xb3,0x39,0x3f,0xe4, +0x7a,0xb3,0x39,0x40,0x7e,0x73,0x3a,0x2, 0xbe,0x73,0x39,0x3f,0x48,0x6, 0x7e,0xb3, +0x39,0x41,0x80,0x1, 0xe4,0xda,0xf8,0x22,0x7e,0x8, 0x1f,0x34,0x7e,0x18,0x21,0x14, +0x22,0x7e,0xb3,0x38,0x32,0x70,0x6, 0x12,0x4d,0xca,0x2, 0x4f,0xbf,0x12,0x4a,0x35, +0x12,0xbd,0xc2,0x50,0xa, 0x12,0x4c,0x7f,0x7c,0x3b,0x12,0x4d,0xca,0x80,0x5, 0x12, +0xc5,0x1f,0x7c,0x3b,0x4c,0x33,0x68,0x11,0x7c,0xb3,0x12,0xbd,0x46,0x60,0xa, 0x7a, +0x33,0x38,0x35,0x74,0x1, 0x7a,0xb3,0x2a,0x8, 0x22,0xe4,0x7a,0xb3,0x2f,0x80,0x22, +0xca,0xf8,0x6c,0xff,0x7e,0xb7,0x2f,0x9c,0x7e,0xc7,0x2f,0x9e,0x7e,0x97,0x2f,0x84, +0x7e,0xd7,0x2f,0x86,0x7e,0xa7,0x2f,0x98,0x7e,0xe7,0x2f,0x9a,0xe4,0x7e,0x73,0x2f, +0xa8,0x1b,0x70,0x7d,0x2b,0x7d,0x1c,0x12,0x4e,0xc2,0x70,0x2, 0xc1,0xbd,0x7e,0x73, +0x2f,0xa8,0xbe,0x70,0xa, 0x28,0x13,0xe4,0x7e,0x70,0x9, 0x7e,0x27,0x2f,0xa0,0x7e, +0x17,0x2f,0xa2,0x12,0x4e,0xc2,0x70,0x2, 0xc1,0xbd,0x7e,0x73,0x2f,0xa8,0xbe,0x70, +0x14,0x28,0x13,0xe4,0x7e,0x70,0x13,0x7e,0x27,0x2f,0xa4,0x7e,0x17,0x2f,0xa6,0x12, +0x4e,0xc2,0x70,0x2, 0xc1,0xbd,0xbe,0xc4,0x0, 0xf0,0x50,0x2d,0xbe,0xb4,0x1, 0xe, +0x28,0x27,0x7e,0xb3,0x2f,0x81,0x70,0x21,0x12,0x4f,0x5, 0x28,0x1c,0xbe,0xf4,0x13, +0x4c,0x50,0x16,0x7d,0xfc,0x3e,0xf4,0xbd,0xfb,0x50,0x62,0xbd,0xa9,0x50,0x5, 0x7e, +0xf0,0x20,0x80,0x59,0x7e,0xf0,0x21,0x80,0x54,0xbe,0xb4,0x0, 0x87,0x50,0x4e,0xbe, +0xc4,0x1, 0xe0,0x28,0x48,0x7e,0xb3,0x2f,0x81,0x70,0x42,0x12,0x4f,0x5, 0x28,0x3d, +0xbe,0xf4,0x13,0x4c,0x50,0x37,0x7d,0xfb,0x3e,0xf4,0xbd,0xfc,0x50,0x2f,0xbd,0xed, +0x50,0x5, 0x7e,0xf0,0x22,0x80,0x26,0x12,0x4f,0x8b,0x49,0x35,0x2b,0xbb,0x49,0x15, +0x2b,0xbd,0x49,0x25,0x2b,0xab,0x49,0x5, 0x2b,0xad,0x9d,0x10,0xbe,0x14,0x0, 0x20, +0x18,0x8, 0x9d,0x32,0xbe,0x34,0x0, 0x10,0x58,0x3, 0x7e,0xf0,0x23,0x7c,0xbf,0xda, +0xf8,0x22,0x7d,0x41,0x7d,0x2, 0x7c,0x37,0x7c,0x2b,0x74,0x4, 0xac,0xb2,0x49,0x35, +0x2b,0xbf,0x49,0xf5,0x2b,0xc1,0x74,0x4, 0xac,0xb3,0x49,0x25,0x2b,0xbf,0x49,0x55, +0x2b,0xc1,0x12,0x4f,0xcc,0x7d,0x3f,0x9d,0x35,0x12,0x21,0xa, 0x9d,0x34,0x12,0x21, +0xa, 0xbe,0x34,0x0, 0x4d,0x58,0xc, 0x12,0x4f,0xe, 0xbe,0x34,0x0, 0x4d,0x58,0x3, +0x74,0x1, 0x22,0xe4,0x22,0x7e,0xf7,0x2f,0x82,0xbe,0xf4,0xf, 0xa0,0x22,0x7d,0x31, +0x9d,0x30,0x2, 0x21,0xa, 0x7d,0xf4,0x3e,0xf4,0x7f,0x60,0x2d,0xdf,0xb, 0x6a,0xf0, +0x22,0x7c,0xab,0x6d,0x44,0x80,0x29,0x4c,0xaa,0x68,0x11,0x12,0x4f,0x58,0x60,0x5, +0x3e,0xe4,0x14,0x78,0xfb,0x12,0x4f,0x15,0x2d,0xfe,0x80,0xf, 0x12,0x4f,0x58,0x60, +0x5, 0x3e,0xe4,0x14,0x78,0xfb,0x12,0x4f,0x15,0x9d,0xfe,0x1b,0x6a,0xf0,0xb, 0x44, +0x7e,0xf5,0x29,0xbd,0xf4,0x38,0xd0,0x22,0x7f,0x71,0x2d,0xf4,0x7e,0x7b,0xb0,0x1a, +0xeb,0x7f,0x61,0x2e,0xd5,0x29,0x7e,0x6b,0xb0,0x22,0x7e,0xa3,0x2f,0xa8,0xbe,0xa0, +0xf0,0x50,0x17,0x74,0x4, 0xa4,0x59,0x35,0x2b,0xbf,0x12,0x4f,0x8b,0x59,0x25,0x2b, +0xc1,0x7e,0xb3,0x2f,0xa8,0x4, 0x7a,0xb3,0x2f,0xa8,0x22,0x7e,0xa3,0x2f,0xa8,0x74, +0x4, 0xa4,0x22,0x7c,0x7b,0x7e,0x63,0x2a,0x71,0xa, 0x6, 0x2e,0x4, 0x0, 0x3, 0x7e, +0x63,0x2a,0x6e,0xa, 0x16,0xad,0x10,0x7d,0x21,0x12,0x4f,0xe5,0xa, 0x26,0x7a,0x25, +0x29,0x74,0x1d,0xac,0x7b,0x2e,0x34,0x38,0x45,0x6d,0x22,0xe4,0x2, 0x4f,0x21,0xe4, +0x7a,0xb3,0x39,0xde,0x22,0x7e,0x34,0x0, 0xc8,0x2, 0x23,0xcc,0x9d,0x32,0x12,0x21, +0xa, 0x7d,0x13,0x22,0x7e,0xb3,0x38,0x32,0xbe,0xb0,0x1, 0x22,0xa, 0x5b,0x2e,0x54, +0x0, 0x8, 0xf5,0xcc,0x22,0x3e,0x24,0x7e,0xf, 0x39,0xda,0x2d,0x12,0x22,0x7e,0x8, +0x0, 0x25,0x7e,0x18,0x0, 0x24,0x22,0x7e,0x73,0x28,0x93,0x7a,0x73,0x28,0x94,0x7e, +0x73,0x2a,0x2, 0x7a,0x73,0x2a,0x3, 0xe4,0x7a,0xb3,0x2a,0x6, 0x22,0x7e,0x37,0x33, +0xeb,0xb, 0x34,0x7a,0x37,0x33,0xeb,0x7e,0x37,0x33,0xed,0xbe,0x37,0x33,0xeb,0x28, +0x3, 0x2, 0x50,0x28,0x22,0x2, 0x50,0xd, 0xe5,0x9a,0x60,0x5, 0xd2,0x9c,0xa9,0xd6, +0xdf,0x22,0xca,0x7b,0xca,0x6b,0xca,0x5b,0xca,0x4b,0xca,0x2b,0xca,0x1b,0xca,0xb, +0xc0,0xd0,0xc0,0x83,0xc0,0x82,0x12,0x50,0x25,0xd0,0x82,0xd0,0x83,0xd0,0xd0,0xda, +0xb, 0xda,0x1b,0xda,0x2b,0xda,0x4b,0xda,0x5b,0xda,0x6b,0xda,0x7b,0x32,0x7e,0x23, +0x2b,0xf, 0x7e,0x33,0x38,0xce,0xac,0x23,0x2e,0x14,0x1, 0xf4,0xbe,0x14,0x0, 0xa, +0x50,0x4, 0x7e,0x14,0x0, 0xa, 0x7e,0x63,0x2b,0x10,0xbe,0x14,0xf, 0x3c,0x40,0x4, +0x7e,0x14,0xf, 0x3c,0xbe,0x14,0x7, 0x8, 0x40,0x3, 0xe4,0x80,0x2, 0x74,0x1, 0x7a, +0xb3,0x2b,0x10,0x7e,0x73,0x2b,0x10,0xbc,0x76,0x68,0x2, 0xd2,0x10,0x7e,0x24,0x1, +0xf4,0x7d,0x31,0x8d,0x32,0x7c,0x17,0xbe,0x10,0x7, 0x28,0x3, 0x7e,0x10,0x7, 0x7e, +0x1f,0x39,0xc1,0x69,0x51,0x0, 0x86,0x54,0x1f,0xa, 0x1, 0x3e,0x4, 0x3e,0x4, 0x3e, +0x4, 0x3e,0x4, 0x3e,0x4, 0x2d,0x5, 0x79,0x1, 0x0, 0x86,0x6d,0x0, 0x7e,0x34,0xb8, +0x0, 0x7e,0x24,0x0, 0xb, 0x2, 0x1f,0x58,0x7e,0xa3,0x0, 0x5f,0xbe,0xa0,0xff,0x68, +0x48,0xbe,0xa3,0x3, 0xfc,0x68,0x42,0x74,0x5, 0xa4,0x12,0x57,0x7c,0x12,0x51,0x2a, +0x12,0x55,0x70,0x12,0x51,0x2a,0x12,0x55,0x67,0x12,0x57,0x8e,0x50,0x9, 0x7e,0xb3, +0x0, 0x5f,0x12,0x55,0x79,0x80,0x6, 0x12,0x51,0x2a,0x12,0x54,0x6a,0x12,0x51,0x36, +0x12,0x54,0x63,0x7e,0x73,0x2b,0x14,0xa, 0x37,0x7e,0xf, 0x39,0xc9,0x79,0x30,0x0, +0x1a,0x7e,0x73,0x0, 0x5f,0x7a,0x73,0x3, 0xfc,0x22,0x7e,0xa3,0x0, 0x5f,0x74,0x5, +0xa4,0x22,0x7a,0xb3,0x2b,0xf, 0x12,0x50,0x5e,0x7a,0x37,0x2b,0x1b,0x22,0x12,0x51, +0x32,0x30,0x10,0xc, 0xc2,0x10,0x12,0x57,0xd5,0x30,0x0, 0x4, 0xe4,0x12,0xa, 0x66, +0x30,0x0, 0x9, 0x12,0xab,0x26,0x12,0x57,0xf8,0x2, 0x57,0x9f,0x22,0x7e,0xb, 0x70, +0x7a,0x73,0x2b,0xf, 0x29,0x70,0x0, 0x4, 0x7a,0x73,0x2b,0x62,0x29,0x70,0x0, 0x1, +0x7a,0x73,0x2b,0x14,0x29,0x70,0x0, 0x3, 0x7a,0x73,0x2b,0x20,0x12,0x51,0x36,0x12, +0x54,0x63,0xd2,0x0, 0xc2,0x1, 0x2, 0x3b,0xba,0xca,0xf8,0x7c,0xfb,0x74,0x5, 0xac, +0xbf,0x12,0x57,0x7c,0x12,0x55,0x70,0x12,0x54,0x6a,0x12,0x55,0x67,0x7a,0xf3,0x0, +0x5f,0x7c,0xbf,0x12,0x55,0x79,0x12,0x51,0x36,0x74,0x5, 0xac,0xbf,0x9, 0xb5,0x26, +0x37,0x12,0x57,0xba,0x12,0x23,0x23,0xe4,0x7a,0xb3,0x16,0x91,0xda,0xf8,0x22,0x7e, +0xb3,0x37,0x66,0x60,0x6, 0x14,0x7a,0xb3,0x37,0x66,0x22,0x12,0xa7,0xf9,0x7e,0xb3, +0x37,0xed,0x70,0xe, 0x7e,0xb3,0x3a,0xf, 0xb4,0x1, 0x7, 0xe4,0x12,0x51,0x89,0x12, +0x57,0xee,0x12,0x54,0x27,0x12,0xa9,0x2d,0x7e,0xa3,0x37,0xed,0x7a,0xa3,0x3a,0xf, +0xbe,0xb0,0xff,0x68,0x3, 0x2, 0x51,0x89,0x22,0xca,0xf8,0x6c,0xff,0x7e,0x73,0x0, +0x5f,0xbc,0x7f,0x68,0x2a,0x7e,0x30,0x5, 0xac,0x3f,0x12,0x52,0x6f,0xca,0x39,0x7e, +0x30,0x38,0xac,0x3f,0x12,0x52,0x88,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c, +0xca,0x39,0x7e,0x30,0x8c,0xac,0x3f,0x12,0x52,0x7d,0x12,0x20,0xc3,0x1b,0xfd,0xb, +0xf0,0xbe,0xf0,0x4, 0x40,0xc7,0x7e,0x23,0x0, 0x5f,0x7e,0x30,0x5, 0xac,0x23,0x12, +0x52,0x6f,0xca,0x39,0x7e,0x23,0x0, 0x5f,0x7e,0x30,0x38,0xac,0x23,0x12,0x52,0x88, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x23,0x0, 0x5f,0x7e, +0x30,0x8c,0xac,0x23,0x12,0x52,0x7d,0x12,0x20,0xc3,0x1b,0xfd,0xda,0xf8,0x22,0x2e, +0x14,0x26,0x33,0x6d,0x0, 0x12,0x51,0x5d,0x7e,0x34,0x0, 0x38,0x22,0x2e,0x14,0x1, +0x40,0x6d,0x0, 0x7e,0x18,0x3, 0x70,0x22,0x2e,0x14,0x0, 0x60,0x6d,0x0, 0x7e,0x18, +0x34,0x0, 0x22,0xca,0xd8,0xca,0x79,0x7e,0xd0,0xe, 0x7e,0xe0,0x19,0x7e,0x73,0x2a, +0x74,0xbe,0x70,0x19,0x28,0x4, 0x7c,0xf7,0x80,0x2, 0x7c,0xfe,0x7a,0xd3,0x2a,0x6d, +0x7a,0xe3,0x2a,0x6e,0x7a,0xd3,0x2a,0x71,0x7a,0xe3,0x2a,0x72,0x7a,0xd3,0x2a,0x73, +0x7a,0xe3,0x2a,0x74,0x74,0x1, 0x7a,0xb3,0x2a,0x77,0x7a,0xd3,0x2a,0x6f,0xa, 0x3e, +0x1b,0x34,0x7a,0x73,0x2a,0x70,0x74,0x5, 0x7a,0xb3,0x2a,0x78,0x74,0xff,0x7a,0xb3, +0x2a,0x79,0xa, 0x3d,0xca,0x39,0x7e,0x34,0x60,0x52,0x7e,0x24,0x0, 0xff,0x7e,0x8, +0x2a,0x7a,0x12,0x20,0xc3,0x1b,0xfd,0xa, 0x3f,0xca,0x39,0x7e,0x34,0x60,0x75,0x7e, +0x24,0x0, 0xff,0x7e,0x8, 0x2a,0x9d,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x23, +0xca,0x39,0x7e,0x34,0x60,0xd8,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x21,0x12,0x20, +0xc3,0x1b,0xfd,0x12,0xaa,0xc5,0x12,0x64,0xdf,0x7a,0xd3,0x2a,0x75,0x7a,0xe3,0x2a, +0x76,0x12,0x5d,0x7e,0x74,0x1, 0x12,0x30,0x38,0xe4,0x7a,0xb3,0x2b,0x1, 0x7a,0xb3, +0x2b,0x2, 0x12,0x62,0xab,0x7a,0x37,0x2b,0xd, 0x74,0x3, 0x7a,0xb3,0x2b,0x3, 0xe4, +0x7a,0xb3,0x2b,0x4, 0x74,0x2, 0x7a,0xb3,0x2b,0x5, 0x7e,0x34,0x0, 0xfa,0x7a,0x37, +0x2b,0x7, 0x74,0x4, 0x7a,0xb3,0x2b,0x6, 0x7e,0x34,0x0, 0xf, 0x7a,0x37,0x2b,0x9, +0x7e,0x34,0x20,0x5f,0x7a,0x37,0x2b,0xb, 0x74,0x20,0x7a,0xb3,0x2b,0x62,0x74,0x1, +0x7a,0xb3,0x2b,0x10,0x74,0x20,0x7a,0xb3,0x2b,0x11,0x74,0x4, 0x7a,0xb3,0x2b,0x13, +0x74,0x1e,0x12,0x51,0x32,0xe4,0x7a,0xb3,0x2b,0x1d,0x7a,0xb3,0x2b,0x1e,0x7e,0x34, +0x1, 0xf4,0x7a,0x37,0x2b,0x19,0x74,0x1, 0x7a,0xb3,0x2b,0x12,0x74,0x54,0x7a,0xb3, +0x2b,0x20,0x74,0x4f,0x7a,0xb3,0x2b,0x1f,0x6d,0x33,0x7a,0x37,0x2b,0x15,0x7a,0x37, +0x2b,0x17,0x74,0x3, 0x7a,0xb3,0x2b,0x14,0x7e,0x34,0x0, 0x30,0x7a,0x37,0x2b,0x6a, +0x7a,0xb3,0x2b,0x67,0x7e,0x34,0x0, 0x5, 0x7a,0x37,0x2b,0x68,0xe4,0x7a,0xb3,0x2b, +0x66,0x7e,0x34,0x4, 0x6d,0x7a,0x37,0x2b,0x6c,0x74,0x1, 0x7a,0xb3,0x2b,0x63,0x74, +0x4, 0x7a,0xb3,0x2b,0x64,0xe4,0x7a,0xb3,0x2b,0x65,0x74,0x1, 0x7a,0xb3,0x2b,0x60, +0xe4,0x7a,0xb3,0x2b,0x61,0x7e,0x34,0x20,0x65,0x7a,0x37,0x2b,0x6e,0xa, 0x3e,0xca, +0x39,0x7e,0x34,0x60,0xfb,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x44,0x12,0x20,0xc3, +0x1b,0xfd,0xda,0x79,0xda,0xd8,0x22,0x12,0xa7,0x37,0x2, 0x54,0x2d,0x7e,0xb3,0x37, +0x69,0x60,0xf, 0x74,0x1, 0x7a,0xb3,0x37,0x71,0x7e,0xb3,0x37,0xdf,0x70,0x3, 0x12, +0xa7,0xd0,0x7e,0xb3,0x37,0x71,0xb4,0x1, 0xc, 0x74,0x3, 0x7a,0xb3,0x34,0xc3,0x7e, +0x34,0x14,0x0, 0x80,0x9, 0xe4,0x7a,0xb3,0x34,0xc3,0x7e,0x34,0xa, 0x0, 0x7a,0x37, +0x2a,0x62,0x22,0x7e,0x8, 0x2a,0x6d,0x2, 0x3, 0x8b,0x9, 0x75,0x26,0x35,0x7a,0x73, +0x2b,0x1f,0x22,0xca,0x3b,0x7a,0xd, 0x2e,0x7c,0xcb,0x7e,0xb3,0x2b,0x1d,0xf5,0x32, +0x7e,0xb3,0x2b,0xf, 0xf5,0x33,0x7e,0xd3,0x2b,0x14,0x7e,0xe3,0x2b,0x1f,0x7e,0xf3, +0x2b,0x20,0x7e,0x34,0x0, 0x38,0xca,0x39,0x7e,0x18,0x34,0x0, 0x7e,0x8, 0x24,0xf2, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x18,0x3, 0x70,0x7e, +0x8, 0x25,0x2a,0x12,0x20,0xc3,0x1b,0xfd,0x7c,0xbc,0x12,0x55,0x79,0x74,0x1, 0x7a, +0xb3,0x2b,0x1d,0x74,0x5, 0xac,0xbc,0x12,0x55,0x70,0x74,0x5, 0xac,0xbc,0x12,0x54, +0x6a,0x74,0x5, 0xac,0xbc,0x12,0x55,0x67,0x74,0x5, 0xac,0xbc,0x9, 0x75,0x26,0x37, +0xbe,0x73,0x2b,0x62,0x68,0x6, 0x7a,0x73,0x2b,0x62,0xd2,0x10,0xc2,0x0, 0x12,0x57, +0x85,0x12,0x51,0x3e,0x12,0x3f,0x9e,0x30,0xf, 0xfd,0x74,0x1, 0x12,0x0, 0xe, 0x7e, +0x14,0x40,0x0, 0x7d,0x31,0x7e,0x2f,0x13,0x86,0x7d,0x25,0x7e,0x4, 0xd, 0xc8,0x12, +0x56,0x2d,0x12,0x57,0xe5,0xa4,0x7a,0x55,0x34,0x7e,0xd, 0x2e,0x7e,0x18,0xd, 0xc8, +0x12,0x5d,0xf1,0x12,0xb5,0xa7,0xe5,0x32,0x7a,0xb3,0x2b,0x1d,0xe5,0x33,0x7a,0xb3, +0x2b,0xf, 0x7a,0xd3,0x2b,0x14,0x7a,0xe3,0x2b,0x1f,0x7a,0xf3,0x2b,0x20,0x7e,0x34, +0x0, 0x38,0xca,0x39,0x7e,0x18,0x24,0xf2,0x7e,0x8, 0x34,0x0, 0x12,0x20,0xc3,0x1b, +0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0x7e,0x18,0x25,0x2a,0x7e,0x8, 0x3, 0x70,0x12, +0x20,0xc3,0x1b,0xfd,0xda,0x3b,0x22,0x9, 0x75,0x26,0x36,0x7a,0x73,0x2b,0x20,0x22, +0x9, 0x75,0x26,0x34,0x7a,0x73,0x2b,0x14,0x22,0xca,0xf8,0x7c,0xfb,0x7e,0x34,0x0, +0x38,0xca,0x39,0xac,0x7f,0x2e,0x34,0x0, 0x60,0x6d,0x22,0x7e,0x8, 0x34,0x0, 0x12, +0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x0, 0x8c,0xca,0x39,0xac,0x7f,0x2e,0x34,0x1, 0x40, +0x6d,0x22,0x7e,0x8, 0x3, 0x70,0x12,0x20,0xc3,0x1b,0xfd,0xda,0xf8,0x22,0xca,0x3b, +0x7e,0xb3,0x2b,0xf, 0x7a,0xb3,0x1f,0x33,0x7e,0xf3,0x2b,0x62,0x12,0x8b,0x1a,0x7c, +0xdb,0xbe,0xd0,0xff,0x68,0x64,0x6c,0xcc,0x12,0x57,0x85,0xf5,0x29,0x7e,0x73,0x2b, +0xf, 0xbe,0x71,0x29,0x68,0x36,0x7e,0x70,0x4, 0xac,0x7d,0xa, 0x2c,0x12,0x88,0x56, +0x7c,0xeb,0xbe,0xe0,0x2, 0x38,0x43,0xa, 0xe, 0x7e,0x14,0x2, 0xe0,0xad,0x10,0x2e, +0x14,0x16,0x93,0x6d,0x0, 0x7a,0xd, 0x2a,0x7e,0x70,0x1d,0xac,0x7e,0x2e,0x34,0x38, +0x45,0x6d,0x22,0x7a,0x1f,0x38,0x41,0x7c,0xbc,0x12,0x54,0x73,0xb, 0xc0,0xbe,0xc0, +0x4, 0x40,0xb5,0x7e,0x73,0x2b,0x62,0xbc,0x7f,0x68,0x6, 0x7a,0xf3,0x2b,0x62,0xd2, +0x10,0xd2,0x0, 0x7e,0xb3,0x1f,0x33,0x12,0x51,0x3e,0xda,0x3b,0x22,0x7e,0xb3,0x2a, +0x6d,0xca,0x3b,0x7c,0xdb,0x7a,0x5, 0x38,0x7d,0x71,0x7a,0x25,0x36,0x7a,0x35,0x34, +0x12,0x57,0x8e,0x50,0x7b,0x6c,0xcc,0x80,0x13,0x7e,0x73,0x2a,0x6e,0x12,0x57,0x57, +0x12,0x57,0x3d,0x7e,0x34,0x34,0x0, 0x12,0x57,0x60,0xb, 0xc0,0x12,0x57,0x75,0x38, +0xe8,0x6c,0xcc,0x80,0x55,0x7e,0xa3,0x2a,0x6e,0x7c,0x7a,0x12,0x57,0x57,0x75,0x3a, +0x0, 0x80,0x27,0x7e,0xb3,0x38,0xb2,0xbe,0xb1,0x3a,0x7e,0x70,0x4, 0x28,0x8, 0xac, +0x7c,0x49,0x43,0x3, 0x70,0x80,0x6, 0xac,0x7c,0x49,0x43,0x3, 0x72,0x7e,0x71,0x3a, +0x74,0x2, 0xac,0x7b,0x59,0x43,0x34,0x50,0x5, 0x3a,0x7e,0xb3,0x2a,0x70,0xbe,0xb1, +0x3a,0x38,0xd0,0x7e,0x34,0x10,0x0, 0x74,0x2, 0xa4,0x59,0x35,0x34,0x4e,0x12,0x57, +0x3d,0x7e,0x34,0x34,0x50,0x12,0x57,0x60,0xb, 0xc0,0xbc,0xdc,0x38,0xa7,0x80,0x2c, +0x7a,0xd3,0x25,0xb6,0x7e,0x73,0x2a,0x70,0x7a,0x73,0x25,0xb7,0xe4,0x7a,0xb3,0x25, +0xb9,0x74,0x6, 0x7a,0xb3,0x25,0xb8,0x7a,0x77,0x25,0xba,0x7a,0x77,0x25,0xbe,0x7e, +0x8, 0x25,0xb6,0x7e,0x73,0x2b,0x1f,0xa, 0x37,0x12,0xe, 0x37,0x7d,0x37,0x12,0x6f, +0xfa,0x7e,0x35,0x38,0x7a,0x37,0x25,0xbe,0xe4,0x7a,0xb3,0x25,0xb8,0x12,0x57,0x4e, +0x7a,0xd3,0x25,0xb6,0x7e,0xb3,0x2b,0x1d,0x70,0xf, 0xe4,0x7a,0xb3,0x25,0xb9,0x7a, +0x77,0x25,0xba,0x7e,0x34,0x0, 0x20,0x80,0x16,0x74,0x1, 0x7a,0xb3,0x25,0xb9,0x7e, +0x35,0x34,0x7a,0x37,0x25,0xba,0x7e,0x35,0x36,0x7a,0x37,0x25,0xbc,0x6d,0x33,0x7a, +0x37,0x25,0xc0,0x7e,0x8, 0x25,0xb6,0x12,0xd, 0x7, 0xda,0x3b,0x22,0x74,0xc, 0x7a, +0xb3,0x25,0xb8,0x74,0x1, 0x7a,0xb3,0x25,0xb6,0xe4,0x7a,0xb3,0x25,0xb9,0x7e,0x73, +0x2a,0x6e,0x7a,0x73,0x25,0xb7,0x22,0xac,0x7c,0x3e,0x34,0x7d,0xf7,0x2d,0xf3,0x22, +0x7a,0x37,0x25,0xba,0x7d,0x3f,0x7a,0x37,0x25,0xbc,0x7a,0x37,0x25,0xbe,0x7e,0x8, +0x25,0xb6,0x2, 0x7, 0x9b,0x7e,0x73,0x2a,0x6f,0xbc,0x7c,0x22,0x9, 0x75,0x26,0x33, +0x7a,0x73,0x2b,0xf, 0x22,0x74,0x5, 0xac,0xbc,0x9, 0xb5,0x26,0x33,0x22,0x7e,0xb3, +0x38,0x9, 0xb4,0x3, 0x8, 0x7e,0xb3,0x38,0xb3,0x70,0x2, 0xc3,0x22,0xd3,0x22,0x12, +0xa7,0xf9,0x6d,0x33,0x7a,0x37,0x37,0xdd,0x6c,0xaa,0x12,0xaa,0x88,0xb, 0xa0,0xbe, +0xa0,0x4, 0x40,0xf6,0xe4,0x7a,0xb3,0x37,0x72,0x22,0x7e,0xa3,0x2b,0x62,0xbc,0xab, +0x68,0x6, 0x7a,0xb3,0x2b,0x62,0xd2,0x10,0x30,0x10,0x9, 0xc2,0x10,0x12,0x57,0xd5, +0xe4,0x2, 0xa, 0x66,0x22,0x7e,0x8, 0x2a,0x6d,0x12,0x3, 0x8b,0x7e,0x8, 0x2a,0x6d, +0x74,0x3, 0x2, 0x11,0x7a,0x7e,0xa3,0x2a,0x6e,0x7e,0xb3,0x2a,0x6d,0x22,0xe4,0x7a, +0xb3,0x37,0x69,0x7a,0xb3,0x37,0x71,0x22,0x7e,0xb3,0x2b,0xf, 0xca,0x3b,0x7c,0xeb, +0x6c,0xff,0x7e,0xc4,0x1, 0xf4,0x7e,0x73,0x38,0xce,0xa, 0xb7,0x7e,0xb3,0x2b,0x10, +0xf5,0x34,0x75,0x35,0x4, 0xe4,0x7a,0xb3,0x37,0x72,0xa, 0x3e,0xad,0x3b,0x7d,0xa3, +0x2d,0xac,0x6c,0xdd,0x7e,0xa3,0x37,0x72,0xbe,0xa1,0x35,0x40,0x2, 0x80,0x19,0xbe, +0xa0,0x0, 0x28,0x19,0x74,0x5, 0xa4,0x9, 0x75,0x26,0x33,0xbc,0x7e,0x78,0xe, 0xe5, +0x35,0x14,0xbe,0xb3,0x37,0x72,0x78,0x5, 0xe4,0x7a,0xb3,0x37,0x72,0x7e,0xc3,0x37, +0x72,0x80,0x3a,0x7e,0xb3,0x37,0x72,0x4, 0x7a,0xb3,0x37,0x72,0x74,0x5, 0xac,0xbc, +0x9, 0x75,0x26,0x33,0xbc,0x7e,0x68,0x23,0xa, 0xdd,0x19,0xcd,0x37,0x76,0xa, 0x97, +0xad,0x9b,0x2d,0x9c,0x7c,0xad,0xb, 0xd0,0x7c,0xba,0x7d,0x39,0x7d,0x2a,0x7e,0x31, +0x34,0x12,0x10,0x0, 0xb, 0xf0,0xbe,0xf0,0x3, 0x50,0x8, 0xb, 0xc0,0xe5,0x35,0xbc, +0xbc,0x38,0xc0,0x7a,0xf3,0x37,0x73,0xda,0x3b,0x22,0x74,0xa, 0x7a,0xb3,0x2a,0x4d, +0x74,0x10,0x7a,0xb3,0x2a,0x4e,0x12,0x47,0xf8,0x7a,0x37,0x2a,0x55,0x74,0x14,0x7a, +0xb3,0x2a,0x59,0x12,0x5d,0xde,0x7e,0x24,0x0, 0x78,0x7a,0x27,0x2a,0x5c,0x7e,0x24, +0xff,0x6a,0x7a,0x27,0x2a,0x5e,0x7a,0x37,0x2a,0x60,0xe4,0x7a,0xb3,0x2a,0x64,0x74, +0x4, 0x7a,0xb3,0x2a,0x65,0x7e,0x34,0x0, 0x64,0x7a,0x37,0x2a,0x66,0x7e,0x34,0xa, +0x0, 0x7a,0x37,0x2a,0x62,0xe4,0x7a,0xb3,0x2a,0x6b,0x7a,0xb3,0x16,0x92,0x22,0x12, +0x5c,0x95,0x12,0x52,0x93,0x12,0x0, 0x42,0x12,0x5d,0xd5,0x7e,0x18,0x4, 0x0, 0x7a, +0x1f,0x6, 0xf8,0x7e,0xf, 0x6, 0xf8,0x7e,0x1f,0x6, 0xf4,0x12,0x65,0x54,0x7e,0x18, +0x8, 0xa, 0x7a,0x1f,0x13,0x86,0x7e,0x18,0xd, 0xc8,0x7a,0x1f,0x13,0x8a,0x7e,0xf, +0x13,0x8a,0x7e,0x1f,0x13,0x86,0x12,0x5f,0xd5,0x12,0x59,0x46,0x12,0x58,0x9a,0x12, +0x64,0xb0,0x12,0x59,0x8e,0x2, 0x59,0x38,0xe4,0x7a,0xb3,0x34,0x38,0x7a,0xb3,0x34, +0x39,0x7a,0xb3,0x34,0x3a,0x22,0x2, 0x59,0x49,0x7e,0x34,0x0, 0xfa,0x7a,0x37,0x28, +0x95,0x7e,0x34,0x2, 0x26,0x7a,0x37,0x28,0x99,0x7e,0x34,0x0, 0x96,0x7a,0x37,0x28, +0x97,0x7a,0x37,0x28,0x9b,0x7e,0x34,0x0, 0x50,0x7a,0x37,0x28,0x9d,0x7e,0x34,0x0, +0x2b,0x7a,0x37,0x28,0x9f,0x12,0x5f,0xc8,0x74,0x1, 0x7a,0xb3,0x28,0xa5,0xe4,0x7a, +0xb3,0x28,0xa8,0x7e,0x8, 0x25,0xf7,0x7e,0x34,0x0, 0x3c,0x2, 0x20,0xe8,0x7e,0x8, +0x28,0xae,0x7e,0x34,0x1, 0xe, 0x74,0xff,0x12,0x20,0xe8,0x12,0x5f,0xbc,0x7e,0x8, +0x29,0xbc,0x12,0x59,0xb1,0x7e,0x8, 0x2a,0x2, 0x7e,0x34,0x0, 0xb, 0xe4,0x2, 0x20, +0xe8,0x6c,0xaa,0x74,0x3, 0x12,0x5d,0xe7,0x7f,0x10,0x2d,0x34,0x39,0xb1,0x0, 0xa, +0x12,0x59,0xd9,0x7f,0x70,0x2d,0xf3,0x79,0x47,0x0, 0x14,0x2d,0x31,0x79,0x41,0x0, +0x28,0xb, 0xa0,0xbe,0xa0,0xa, 0x40,0xdb,0x22,0x7e,0x44,0x7f,0xff,0x7e,0x70,0x2, +0xac,0x7a,0x22,0xca,0xf8,0x7e,0x68,0x29,0xbc,0x6c,0xaa,0x7e,0x70,0xff,0x12,0x5c, +0x74,0xe4,0xa, 0x4a,0x19,0xb4,0x1f,0x34,0x74,0xff,0x19,0xb4,0x1f,0x46,0x19,0xb4, +0x1f,0x50,0xb, 0xa0,0xbe,0xa0,0xa, 0x78,0xe2,0x7e,0x73,0x2a,0x2, 0xa5,0xbf,0x0, +0x21,0x7e,0xb3,0x34,0x4f,0x70,0x2, 0x61,0xe2,0x6c,0xaa,0x7e,0x44,0x7f,0xff,0x12, +0x5c,0x7e,0x79,0x40,0x0, 0x14,0x12,0x5c,0x6b,0xb, 0xa0,0xbe,0xa0,0xa, 0x78,0xeb, +0x61,0xe2,0x7e,0xb3,0x34,0x4f,0x70,0x3d,0xbe,0x70,0x0, 0x28,0x38,0x6c,0xaa,0x80, +0x2a,0x7e,0x90,0x9, 0xac,0x9a,0x49,0x34,0x28,0xae,0x12,0x5c,0x7e,0x79,0x30,0x0, +0x14,0x49,0x34,0x28,0xb0,0x7f,0x6, 0x2d,0x12,0x79,0x30,0x0, 0x28,0x74,0x1, 0xa, +0x3a,0x19,0xb3,0x1f,0x34,0x19,0xa4,0x28,0xb2,0xb, 0xa0,0x7e,0xb3,0x2a,0x2, 0xbc, +0xba,0x38,0xce,0x61,0xe2,0x6c,0xaa,0x12,0x59,0xd9,0x3e,0x34,0x59,0x43,0x15,0x4e, +0x59,0x43,0x15,0x50,0x59,0x43,0x15,0x76,0x59,0x43,0x15,0x78,0xb, 0xa0,0xbe,0xa0, +0xa, 0x78,0xe4,0x6c,0xaa,0x80,0x3b,0x6c,0xff,0x7e,0x70,0x2, 0xac,0x7f,0x7f,0x6, +0x2d,0x13,0x69,0x30,0x0, 0x14,0xbe,0x34,0x7f,0xff,0x68,0x1d,0xa, 0x4f,0x9, 0xb4, +0x1f,0x50,0xb4,0xff,0x14,0x12,0x5c,0x63,0x59,0x32,0x15,0x4e,0x69,0x30,0x0, 0x28, +0x59,0x32,0x15,0x50,0x12,0x5c,0x88,0x80,0x7, 0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xc9, +0xb, 0xa0,0x7e,0xb3,0x34,0x4f,0xbc,0xba,0x38,0xbd,0x6c,0xaa,0xa, 0x3a,0x9, 0xb3, +0x1f,0x46,0xb4,0xff,0x17,0x6c,0xff,0xa, 0x4f,0x9, 0xb4,0x1f,0x50,0xb4,0xff,0x5, +0x12,0x5c,0x88,0x80,0x7, 0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xeb,0xb, 0xa0,0xbe,0xa0, +0xa, 0x78,0xd9,0x6c,0xaa,0x80,0x1a,0x7e,0x70,0x9, 0xac,0x7a,0x49,0x43,0x28,0xae, +0x12,0x5c,0x63,0x59,0x42,0x15,0x76,0x49,0x33,0x28,0xb0,0x59,0x32,0x15,0x78,0xb, +0xa0,0x7e,0xb3,0x2a,0x2, 0xbc,0xba,0x38,0xde,0x7e,0x34,0x15,0x4e,0x7a,0x37,0x1f, +0x40,0x7e,0x34,0x15,0x76,0x7a,0x37,0x1f,0x42,0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f, +0x44,0x7e,0x73,0x34,0x4f,0x7a,0x73,0x1f,0x3e,0x7e,0x73,0x2a,0x2, 0x7a,0x73,0x1f, +0x3f,0x7e,0x8, 0x1f,0x3e,0x12,0x4, 0xad,0x6c,0xaa,0x80,0x57,0x7e,0x70,0xff,0x6c, +0xff,0x7e,0x50,0x2, 0xac,0x5f,0x49,0x12,0x15,0x9e,0xa, 0x2a,0xbd,0x21,0x78,0x8, +0xa, 0x3f,0x9, 0x73,0x1f,0x46,0x80,0x7, 0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xe2,0xbe, +0x70,0xff,0x68,0x2d,0x12,0x5c,0x74,0x74,0x1, 0xa, 0x47,0x19,0xb4,0x1f,0x34,0x7e, +0x90,0x9, 0xac,0x9a,0x49,0x24,0x28,0xae,0x7e,0x30,0x2, 0xac,0x37,0x2d,0x1d,0x7d, +0xc, 0x79,0x20,0x0, 0x14,0x49,0x44,0x28,0xb0,0x7e,0x50,0x2, 0xac,0x57,0x12,0x5c, +0x6b,0xb, 0xa0,0x7e,0x63,0x2a,0x2, 0xbc,0x6a,0x38,0xa1,0x6c,0xaa,0xa, 0x3a,0x9, +0xb3,0x1f,0x34,0xbe,0xb0,0x1, 0x68,0x13,0x12,0x59,0xd9,0x7f,0x6, 0x2d,0x13,0x79, +0x40,0x0, 0x14,0x2d,0x3d,0x7d,0x2c,0x79,0x41,0x0, 0x28,0xb, 0xa0,0xbe,0xa0,0xa, +0x78,0xdb,0x7e,0xf3,0x2a,0x2, 0x7a,0xf3,0x34,0x4f,0x6c,0xaa,0xa, 0x3a,0x9, 0xb3, +0x1f,0x34,0xb4,0x1, 0x2c,0x12,0x5c,0x5c,0x29,0xb1,0x0, 0xa, 0xb4,0x1, 0x6, 0x74, +0x3, 0x39,0xb1,0x0, 0xa, 0x12,0x5c,0x5c,0x29,0x31,0x0, 0xa, 0xa5,0xbb,0x3, 0x6, +0xe4,0x7a,0x1b,0xb0,0x80,0x32,0xa5,0xbb,0x0, 0x2e,0x74,0x2, 0x7a,0x1b,0xb0,0x80, +0x27,0x12,0x5c,0x5c,0x29,0xb1,0x0, 0xa, 0xbe,0xb0,0x2, 0x68,0x2, 0x70,0x14,0x74, +0x1, 0x7a,0x1b,0xb0,0x7c,0x2f,0xb, 0xf0,0x7e,0x30,0x9, 0xac,0x23,0x19,0xa1,0x28, +0xb2,0x80,0x5, 0x74,0x3, 0x7a,0x1b,0xb0,0x12,0x5c,0x5c,0x7e,0x1b,0xb0,0x39,0xb1, +0x0, 0xa, 0xb, 0xa0,0xbe,0xa0,0xa, 0x40,0x93,0xda,0xf8,0x22,0xa, 0x3a,0x2d,0x3d, +0x7d,0x2c,0x22,0x7e,0x50,0x2, 0xac,0x5a,0x3e,0x24,0x22,0x7f,0x6, 0x2d,0x12,0x79, +0x40,0x0, 0x28,0x22,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x72,0x28,0xb2,0x22,0x7e,0x50, +0x2, 0xac,0x5a,0x7f,0x6, 0x2d,0x12,0x22,0xa, 0x3a,0x19,0xf3,0x1f,0x46,0x74,0x1, +0x19,0xb4,0x1f,0x50,0x22,0xe4,0x7a,0xb3,0x38,0x9d,0x7a,0xb3,0x38,0x9e,0x74,0xe, +0x7a,0xb3,0x38,0x9f,0x74,0x19,0x7a,0xb3,0x38,0xa0,0xe4,0x7a,0xb3,0x38,0xa1,0x74, +0xa, 0x7a,0xb3,0x38,0xa2,0xe4,0x7a,0xb3,0x38,0xa3,0x7a,0xb3,0x38,0xa4,0x74,0x1, +0x7a,0xb3,0x38,0xa6,0x74,0x25,0x7a,0xb3,0x38,0xaa,0x74,0x3e,0x7a,0xb3,0x38,0xab, +0x74,0x64,0x7a,0xb3,0x38,0xbc,0x74,0x4, 0x7a,0xb3,0x38,0xbd,0xe4,0x7a,0xb3,0x38, +0xa9,0x74,0x4f,0x7a,0xb3,0x38,0xbf,0x74,0x54,0x7a,0xb3,0x38,0xbe,0x74,0x3, 0x7a, +0xb3,0x38,0xc0,0x74,0x40,0x7a,0xb3,0x38,0xbb,0xe4,0x7a,0xb3,0x38,0xb6,0x74,0xfa, +0x7a,0xb3,0x38,0xb4,0x74,0x1e,0x7a,0xb3,0x38,0xb5,0x74,0x1, 0x7a,0xb3,0x38,0xb3, +0x74,0xb, 0x7a,0xb3,0x38,0xb2,0x74,0x1, 0x7a,0xb3,0x38,0xb7,0xe4,0x7a,0xb3,0x38, +0xb8,0x7a,0xb3,0x38,0xb9,0x7e,0x8, 0x38,0xc1,0x7e,0x34,0x0, 0x2c,0x12,0x20,0xe8, +0x74,0x1, 0x7a,0xb3,0x38,0xcc,0x74,0xf4,0x7a,0xb3,0x38,0xcd,0x74,0x19,0x7a,0xb3, +0x38,0xce,0x74,0x1e,0x7a,0xb3,0x38,0xcf,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,0x5d, +0xcc,0x7e,0x8, 0x38,0xdd,0x12,0x20,0xc3,0x1b,0xfd,0x74,0x5, 0x7a,0xb3,0x38,0xea, +0x74,0x1, 0x7a,0xb3,0x38,0xe1,0x7e,0x34,0x0, 0x28,0xca,0x39,0x7e,0x34,0x61,0xdb, +0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x26,0x33,0x12,0x20,0xc3,0x1b,0xfd,0x22,0x7e,0x34, +0x0, 0x4, 0xca,0x39,0x7e,0x34,0x61,0x2d,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x2b,0x70, +0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x2a,0xe, 0x7a,0x37,0x2b,0x76,0xe4,0x7a,0xb3, +0x2b,0x74,0x7a,0xb3,0x2b,0x75,0x7e,0x34,0x0, 0x4, 0xca,0x39,0x12,0x5d,0xcc,0x7e, +0x8, 0x25,0xee,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x34,0x2b,0x78,0x7a,0x37,0x25,0xf4, +0xe4,0x7a,0xb3,0x25,0xf2,0x74,0x1, 0x7a,0xb3,0x25,0xf3,0x22,0x7e,0x34,0x61,0x29, +0x7e,0x24,0x0, 0xff,0x22,0x7e,0x18,0x5, 0xf8,0x7a,0x1f,0x6, 0xf4,0x22,0x7e,0x34, +0x0, 0x96,0x7a,0x37,0x2a,0x5a,0x22,0xa, 0x4a,0x7f,0x10,0x2d,0x34,0x7a,0x1b,0xb0, +0x22,0xca,0xf8,0x7f,0x71,0x6d,0xdd,0x6c,0xaa,0x7e,0xf0,0x80,0xc2,0x0, 0x6d,0x44, +0x80,0x32,0x12,0x5e,0x92,0x12,0x5e,0xa3,0xbd,0x3d,0x48,0x26,0x12,0x5e,0x92,0xb, +0x1a,0x30,0xbe,0x34,0x0, 0x0, 0x8, 0x4, 0xd2,0x0, 0x80,0x9, 0x12,0x21,0xa, 0xbd, +0x3d,0x68,0x2, 0xc2,0x0, 0x7d,0x34,0x3e,0x34,0x2d,0x3f,0x7d,0x2e,0x12,0x5e,0xa3, +0x7d,0xd3,0xb, 0x44,0x7e,0xc5,0x34,0xbd,0xc4,0x38,0xc7,0x30,0x0, 0xc, 0x7e,0xf0, +0x7f,0x80,0x7, 0xb, 0xa0,0xbe,0xa0,0x8, 0x50,0x11,0x7c,0xba,0x7d,0x3d,0x60,0x5, +0xe, 0x34,0x14,0x78,0xfb,0xa, 0xcf,0xbd,0x3c,0x18,0xe8,0x7f,0x10,0x2e,0x35,0x34, +0x7a,0x1b,0xa0,0x6d,0x44,0x80,0x21,0x7d,0x54,0x3e,0x54,0x7f,0x17,0x2d,0x35,0xb, +0x1a,0x30,0x7f,0x60,0x2e,0xd5,0x34,0x7e,0x6b,0xb0,0x60,0x5, 0xe, 0x34,0x14,0x78, +0xfb,0x7c,0xb7,0x12,0x5d,0xe9,0xb, 0x44,0x7e,0x55,0x34,0xbd,0x54,0x38,0xd8,0xda, +0xf8,0x22,0x7d,0xc4,0x3e,0xc4,0x7f,0x17,0x2d,0x3c,0x22,0x74,0x2, 0xac,0xbe,0x7f, +0x17,0x2d,0x35,0xb, 0x1a,0x30,0x2, 0x21,0xa, 0xca,0xd8,0xca,0x79,0x7c,0xfb,0x7f, +0x70,0xc2,0x0, 0x6c,0xdd,0x6d,0xdd,0x7e,0x34,0x23,0x5, 0x7e,0x24,0x0, 0xff,0x7e, +0x14,0x1f,0x7a,0x74,0xc, 0x12,0x1f,0xad,0x6d,0x11,0x7e,0x4, 0x7f,0xff,0x6c,0xee, +0x80,0x13,0x12,0x5e,0x9b,0x7d,0xc3,0xbd,0xdc,0x50,0x2, 0x7d,0xdc,0xbd,0xc, 0x28, +0x2, 0x7d,0xc, 0xb, 0xe0,0xbc,0xfe,0x38,0xe9,0xbe,0xd4,0x0, 0x1e,0x58,0xa, 0x7e, +0xb3,0x28,0x94,0x70,0x4, 0x6d,0x33,0xe1,0xa4,0xbe,0xd4,0x4, 0xb0,0x8, 0x2, 0xd2, +0x0, 0x6c,0xee,0x74,0x4, 0xac,0xbe,0x49,0x45,0x1f,0x7a,0xbd,0x4d,0x58,0x6, 0x49, +0xd5,0x1f,0x7c,0x80,0x7, 0xb, 0xe0,0xbe,0xe0,0x3, 0x40,0xe7,0xbe,0xe0,0x3, 0x78, +0x4, 0x6d,0x33,0x80,0x7f,0xbd,0xd, 0x8, 0x5, 0x30,0x0, 0x2, 0x7d,0xd0,0x9f,0x55, +0x6c,0xee,0x80,0xb, 0x12,0x5e,0x9b,0x1a,0x26,0x1a,0x24,0x2f,0x51,0xb, 0xe0,0xbc, +0xfe,0x38,0xf1,0xa, 0x1f,0x12,0x5f,0xb2,0x9f,0x55,0x6c,0xee,0x80,0x1d,0x12,0x5f, +0xa9,0xb, 0x1a,0x90,0x7d,0x39,0x12,0x21,0xa, 0x7d,0xc3,0xbd,0x1c,0x28,0xa, 0x7d, +0x39,0x1a,0x26,0x1a,0x24,0x2f,0x51,0xb, 0xd0,0xb, 0xe0,0xbc,0xfe,0x38,0xdf,0x6d, +0x11,0xbe,0xd0,0x0, 0x28,0x5, 0xa, 0x1d,0x12,0x5f,0xb2,0xbd,0x1d,0x8, 0x4, 0x7d, +0x1d,0x80,0xa, 0x6d,0x0, 0x9d,0xd, 0xbd,0x1, 0x8, 0x2, 0x7d,0x10,0x6c,0xee,0x80, +0xd, 0x12,0x5f,0xa9,0xb, 0x1a,0x0, 0x9d,0x1, 0x1b,0x1a,0x0, 0xb, 0xe0,0xbc,0xfe, +0x38,0xef,0x7d,0x31,0xda,0x79,0xda,0xd8,0x22,0x74,0x2, 0xac,0xbe,0x7f,0x17,0x2d, +0x35,0x22,0x6d,0x0, 0x7f,0x15,0x12,0x1f,0x58,0x7d,0x13,0x22,0x7e,0x8, 0x34,0xb7, +0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x20,0xe8,0x7e,0x34,0x0, 0x4, 0x7a,0x37,0x28,0xa1, +0x7a,0x37,0x28,0xa3,0x22,0x7f,0x60,0x7e,0xa3,0x2a,0x6d,0x7e,0xb3,0x2a,0x6e,0xa4, +0x7d,0xf5,0x3e,0xf4,0x7f,0x1, 0x7d,0x3f,0xe4,0x12,0x20,0xe8,0x7f,0x6, 0x7d,0x3f, +0x12,0x20,0xe8,0x7a,0xb3,0x16,0x91,0x22,0x7e,0xb3,0x2a,0x73,0xbc,0xba,0x22,0xff, +0x70,0x8f,0x0, 0xff,0x51,0xae,0x5a,0xa5,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x34,0x35,0x31,0x1, 0xc6,0x1, 0x34,0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0xa, 0xf5,0x43,0x36,0x5f,0x4f,0x66,0x69,0x6c,0x6d,0x5f,0x57,0x0, 0x0, 0x0, 0x0, +0xe, 0x19,0x3, 0x2, 0x7, 0x6, 0x5, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0x4, 0x1, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x11,0x4, 0x10,0x3, 0xf, 0x2, 0xe, 0x1, 0xd, 0x0, 0xc, +0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x0, 0x0, +0x0, 0x5, 0x0, 0x4, 0xff,0x23,0x1c,0x2, 0xdf,0xa, 0x1e,0xa, 0x64,0x14,0x10,0x0, +0x4, 0x0, 0x64,0xd, 0xac,0x0, 0xc8,0x3, 0x1, 0x0, 0x0, 0x18,0x2, 0x6, 0xb, 0x0, +0x0, 0x0, 0x96,0x0, 0xf0,0x1, 0xcc,0x2, 0x26,0x3, 0x48,0x3, 0xa2,0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8,0x1, 0xf4,0x3, 0x20,0x0, 0x0, 0x0, 0x0, 0x7, +0xf8,0x0, 0x14,0x1, 0x19,0x1e,0x1, 0xf4,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x0, 0x4, 0x4f,0x20,0x1, 0x20,0x3, 0x0, 0x0, +0x0, 0x0, 0x1, 0xf4,0x54,0x40,0xe, 0x19,0x27,0x1c,0xf, 0x6, 0x60,0x1c,0xf, 0x6, +0x70,0x8, 0x10,0x4, 0x20,0x1, 0x0, 0x4, 0x38,0x44,0x44,0x2, 0x36,0x2, 0x4a,0x1, +0x39,0x1, 0x3b,0x7, 0x80,0x4a,0x4d,0x2, 0x57,0x2, 0x52,0x1, 0x44,0x1, 0x43,0x0, +0x96,0x0, 0x78,0x0, 0x96,0x0, 0xfa,0x0, 0x7d,0x0, 0xfa,0x0, 0xfa,0xa, 0x0, 0x0, +0xa8,0xa, 0x10,0x1e,0x32,0x1, 0xf, 0xb, 0x1e,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22,0x15, +0x0, 0x1, 0x54,0x1, 0x0, 0xa, 0x1, 0x51,0x1, 0x14,0x0, 0x5a,0x1, 0x1, 0xe, 0x0, +0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55,0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, +0x2, 0x26,0x0, 0x50,0x0, 0x2b,0x0, 0x4, 0x0, 0x4, 0x1, 0x4, 0x1, 0x90,0x0, 0xc8, +0x0, 0x50,0x1, 0xf4,0x0, 0x96,0x1, 0x2c,0x1, 0x2c,0x4, 0x1e,0x3, 0x4f,0x54,0x20, +0x22,0x3, 0x51,0x56,0x20,0x2c,0x3, 0x55,0x5c,0x20,0x36,0x2, 0x52,0x69,0x20,0x1e, +0x3, 0x4f,0x54,0x20,0x1e,0x3, 0x4f,0x54,0x20,0x1e,0x3, 0x4f,0x54,0x20,0x1e,0x3, +0x4f,0x54,0x20,0x4, 0x5, 0xf, 0x10,0x11,0x12,0x13,0x4, 0x0, 0xbb,0x4, 0xe2,0x2d, +0x0, 0xc8,0x1, 0x5e,0x0, 0x64,0x0, 0x64,0x0, 0x96,0x0, 0x64,0xb, 0xb8,0x8, 0x5, +0x6, 0x80,0x1, 0x90,0x1, 0x2c,0x1, 0xc2,0x3, 0x20,0xf, 0xa0,0x1, 0x3, 0x20,0x4, +0xb0,0x3, 0x20,0x1, 0x2, 0x2, 0x4, 0x4, 0x6, 0x40,0x0, 0xf0,0x0, 0xc8,0x1, 0x40, +0x1, 0x40,0x1, 0x2c,0x1, 0x18,0x0, 0xfa,0x1, 0x40,0x1, 0x40,0x1, 0x7c,0x0, 0x32, +0x0, 0x28,0x0, 0x78,0x0, 0x64,0x0, 0x64,0x0, 0x78,0x0, 0x78,0x14,0xa, 0x0, 0x50, +0x3, 0xe8,0x0, 0x50,0x7, 0x30,0x0, 0x14,0x1, 0xf4,0x1, 0xf4,0x3, 0x20,0x0, 0x64, +0x0, 0x4d,0x0, 0x1e,0x0, 0x80,0x1, 0xe, 0x0, 0xf0,0x0, 0x3c,0x3, 0xe8,0x1, 0xe0, +0x0, 0x87,0x0, 0x3c,0x3, 0xe8,0x0, 0x20,0x4, 0x18,0x0, 0x0, 0x7, 0x80,0x0, 0x64, +0x0, 0xa0,0x0, 0xa0,0x13,0x88,0x1, 0x2c,0x0, 0xa0,0x0, 0xa0,0x10,0x0, 0xc, 0x0, +0xb, 0xc, 0x5, 0x6, 0x8, 0x9, 0x6, 0x6, 0xc, 0x64,0xc8,0x6d,0x33,0x6c,0xaa,0x80, +0x14,0xa, 0x2a,0x9, 0xb2,0x2a,0xdc,0x54,0x1, 0x78,0x5, 0x4e,0x70,0x1, 0x80,0x3, +0x4e,0x70,0x10,0xb, 0xa0,0x7e,0x53,0x2a,0x74,0xbc,0x5a,0x38,0xe4,0x6c,0xaa,0x80, +0x1f,0xa, 0x2a,0x9, 0xb2,0x2a,0xb9,0xbe,0xb0,0xd, 0x38,0x5, 0x4e,0x70,0xc0,0x80, +0xd, 0xbe,0xb0,0x1b,0x38,0x5, 0x4e,0x60,0x8, 0x80,0x3, 0x4e,0x60,0x50,0xb, 0xa0, +0x12,0x5f,0xf8,0x38,0xdc,0x22,0x7e,0x54,0x0, 0x54,0x7e,0x44,0x0, 0xff,0x69,0x32, +0x0, 0x4, 0x69,0x22,0x0, 0x2, 0xb, 0x2a,0x10,0x7a,0x1d,0x26,0x7a,0x15,0x24,0x7e, +0x34,0x0, 0x20,0x7e,0x8, 0x0, 0x24,0x7e,0x24,0x0, 0x6, 0x12,0x63,0x62,0x74,0x25, +0x7a,0xb3,0x37,0xe2,0x74,0x1e,0x7a,0xb3,0x37,0xe3,0x74,0xf, 0x7a,0xb3,0x37,0xe4, +0x7a,0xb3,0x37,0xe5,0x7a,0xb3,0x37,0xe6,0x74,0xa0,0x7a,0xb3,0x37,0xe7,0x7e,0x34, +0x0, 0x59,0xca,0x39,0x7e,0x34,0x61,0x65,0x7e,0x24,0x0, 0xff,0x7e,0x8, 0x37,0xe8, +0x12,0x20,0xc3,0x1b,0xfd,0xe5,0x25,0x7a,0xb3,0x38,0x13,0xe5,0x28,0x7a,0xb3,0x38, +0x2, 0x22,0x7d,0x42,0x7f,0x60,0x7d,0x3, 0x12,0x64,0x60,0x74,0x2, 0x12,0x63,0x9c, +0x7d,0xf3,0x4e,0xf4,0x0, 0x1, 0x4e,0xf4,0x0, 0xa, 0x12,0x2f,0x54,0x7a,0x45,0x36, +0x7d,0x30,0x6d,0x22,0x7f,0x6, 0x12,0x64,0x2, 0x5e,0xf4,0xff,0xfd,0x12,0x2f,0x54, +0x2, 0x63,0x93,0xa9,0xc5,0xca,0xe4,0x7a,0xb3,0x3a,0x10,0x22,0x7c,0x6b,0x6c,0x77, +0x6c,0xaa,0x7e,0xb3,0x3a,0x10,0xb4,0xa5,0x46,0x12,0x64,0x8d,0x75,0xb5,0x5, 0xa9, +0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3, +0xfc,0xa9,0xc6,0xb3,0x7a,0x61,0xb5,0xa9,0x36,0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36, +0xb3,0xfc,0x12,0x2f,0xa8,0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0x71,0xb5,0x75, +0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9,0xc6,0xb3,0x7e,0xa1,0xb5,0xa9,0xd2,0xb4,0x7c, +0x47,0x6c,0x55,0xa, 0x3a,0x4d,0x32,0x22,0x74,0x6, 0x12,0x63,0x9c,0x7d,0x3, 0x6c, +0x11,0x22,0x12,0x64,0x10,0x7e,0x35,0x36,0x12,0x64,0x94,0xa9,0xd2,0xb4,0xd3,0x22, +0x7d,0x52,0xf5,0x3a,0x7c,0xb6,0x7c,0xa5,0xa, 0x44,0xf5,0x39,0x7f,0x21,0xf5,0x38, +0xa9,0xc2,0xb4,0x74,0xb, 0x12,0x64,0x3b,0xe5,0x3a,0x12,0x64,0x3b,0xe5,0x39,0x12, +0x64,0x3b,0xe5,0x38,0x12,0x64,0x3b,0xe4,0x2, 0x64,0x3b,0xf5,0xb5,0xa9,0x36,0xb3, +0xfc,0xa9,0xc6,0xb3,0xd3,0x22,0xd2,0xc8,0x43,0xed,0xf, 0xc2,0xea,0x75,0xb3,0x13, +0xa9,0xd1,0xb4,0xa9,0xc0,0xb4,0x12,0x64,0x60,0xe4,0x12,0x64,0x70,0x2, 0x63,0x93, +0xa9,0xd5,0xca,0xa9,0xd1,0xea,0xa9,0xc1,0xea,0x74,0xa5,0x7a,0xb3,0x3a,0x10,0x22, +0xca,0xf8,0x7c,0xfb,0x74,0x2, 0x12,0x63,0x9c,0x4c,0xff,0x78,0x5, 0x5e,0x70,0xdf, +0x80,0x3, 0x4e,0x70,0x20,0x74,0x2, 0x12,0x2f,0x58,0xda,0xf8,0x22,0xa9,0xc2,0xb4, +0xa9,0xc6,0xb3,0x22,0x6d,0x22,0x80,0x13,0x75,0xb5,0x0, 0xa9,0x36,0xb3,0xfc,0xa9, +0xc6,0xb3,0xe5,0xb5,0x7a,0xb, 0xb0,0xb, 0x14,0xb, 0x24,0xbd,0x32,0x38,0xe9,0x22, +0x7e,0x8, 0x26,0x5b,0x7e,0x34,0x2, 0x3a,0xe4,0x12,0x20,0xe8,0x7e,0x8, 0x26,0x8c, +0x7e,0x34,0x0, 0xc8,0x74,0xff,0x12,0x20,0xe8,0x7e,0x8, 0x26,0xb4,0x7e,0x34,0x0, +0xc8,0x12,0x20,0xe8,0x7e,0x8, 0x27,0x76,0x7e,0x34,0x1, 0xe, 0x2, 0x20,0xe8,0xca, +0xf8,0x7e,0x73,0x2a,0x78,0xa, 0x47,0x7e,0x73,0x2a,0x71,0xa, 0x57,0x2d,0x54,0x7e, +0xa3,0x2a,0x73,0xbc,0xab,0x28,0x2, 0x7c,0xba,0x7e,0xf3,0x2a,0x72,0x7e,0xa3,0x2a, +0x74,0xbc,0xaf,0x28,0x2, 0x7c,0xfa,0x75,0x25,0x15,0x7e,0x8, 0x2a,0xb9,0x7e,0x18, +0x2a,0x7a,0x12,0xd, 0xd9,0x75,0x25,0x15,0x7e,0x8, 0x2a,0xdc,0x7e,0x18,0x2a,0x9d, +0x7c,0xbf,0x12,0xf, 0x9c,0xda,0xf8,0x22,0x7a,0xb3,0x2b,0x0, 0x70,0xa, 0x7e,0x1f, +0x2b,0x74,0x7e,0xf, 0x2b,0x70,0x80,0xb, 0xb4,0x1, 0xb, 0x7e,0x1f,0x25,0xf2,0x7e, +0xf, 0x25,0xee,0x12,0x30,0x2f,0x22,0x7c,0xab,0x12,0x65,0x28,0x7c,0xba,0x12,0x13, +0xc7,0x2, 0x0, 0x1e,0x7f,0x70,0x7e,0x33,0x2a,0x74,0xa, 0x43,0x7e,0x33,0x2a,0x73, +0xa, 0x53,0x2d,0x54,0x3e,0x54,0x7c,0xab,0xe4,0x7a,0xb3,0x16,0x90,0x7f,0x1, 0xa, +0x3a,0x12,0x20,0xe8,0x7f,0x7, 0xa, 0x3a,0x2, 0x20,0xe8,0x7e,0xa3,0x2f,0xa8,0x7e, +0x70,0x4, 0xac,0x7a,0xb, 0x34,0xbe,0x37,0x38,0xee,0x40,0x39,0x7e,0x37,0x38,0xee, +0xb, 0x34,0x7a,0x37,0x38,0xee,0xbe,0x34,0x0, 0x1, 0x78,0x5, 0x7e,0xb3,0x38,0x35, +0x22,0xbe,0x34,0x0, 0x2, 0x78,0x3, 0x7c,0xba,0x22,0xbe,0x34,0x0, 0x2, 0x50,0x9, +0x7d,0x23,0x1b,0x25,0x9, 0xb2,0x39,0xfc,0x22,0x9e,0x34,0x0, 0x3, 0x2e,0x37,0x2b, +0xb9,0x7e,0x39,0xb0,0x22,0x74,0xff,0x22,0x70,0x5, 0x7e,0xb3,0x38,0x9d,0x22,0xbe, +0xb0,0x3, 0x38,0x15,0x75,0x1d,0x0, 0x30,0x12,0x6, 0x7e,0x18,0x35,0x93,0x80,0x4, +0x7e,0x18,0x35,0xd1,0x7a,0x1d,0x14,0x80,0x8, 0xbe,0xb0,0x5e,0x38,0x10,0x75,0x1d, +0x0, 0xa, 0x1b,0x7e,0x1d,0x14,0x2d,0x31,0x1b,0x34,0x7e,0x1b,0xb0,0x22,0xbe,0xb0, +0xd3,0x68,0x3, 0xb4,0xd4,0x10,0xb4,0xd3,0x8, 0x6d,0x33,0x7a,0x37,0x38,0xee,0x80, +0x2, 0x15,0x1a,0x2, 0x65,0x7b,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x3, 0x2, 0x66, +0xc6,0xbe,0xb0,0x80,0x40,0xc, 0xbe,0xb0,0xdf,0x38,0x7, 0xa, 0x3b,0x9, 0xb3,0x37, +0x62,0x22,0xb4,0xfc,0x5, 0x7e,0xb3,0x38,0x9, 0x22,0xb4,0xfd,0x17,0x6c,0xaa,0x7e, +0xb3,0x28,0xa8,0x60,0x3, 0x4e,0xa0,0x1, 0x7e,0xb3,0x37,0x71,0x60,0x3, 0x4e,0xa0, +0x2, 0x7c,0xba,0x22,0xb4,0xfe,0x5, 0x7e,0xb3,0x2b,0xf, 0x22,0x74,0xff,0x22,0x7c, +0x7b,0x6c,0xaa,0x12,0x66,0xbe,0x78,0x9, 0x7c,0xb7,0x12,0x65,0xc8,0x7c,0xab,0x80, +0xa, 0xb4,0x4, 0x7, 0x7c,0xb7,0x12,0x2a,0xc6,0x7c,0xab,0x7c,0xba,0x22,0x30,0x90, +0x19,0xc2,0x90,0xe5,0x18,0x70,0x9, 0x75,0x18,0x1, 0xe5,0x91,0xf5,0x1a,0x80,0x11, +0x7e,0x71,0x91,0xe5,0x1a,0x12,0x66,0xa9,0x5, 0x1a,0x30,0x91,0xb, 0xc2,0x91,0x5, +0x1a,0xe5,0x1a,0x12,0x66,0x5f,0xf5,0x91,0x22,0x7c,0x6b,0x12,0x66,0xbe,0x78,0x5, +0x7c,0xb6,0x2, 0x66,0xf8,0xb4,0x4, 0x5, 0x7c,0xb6,0x2, 0x37,0xe7,0x22,0x7e,0xb3, +0x38,0x9d,0xc4,0x54,0x7, 0x22,0xb4,0xeb,0x5, 0xe4,0x7a,0xb3,0x38,0xf3,0x7e,0x73, +0x38,0xf3,0xa, 0x27,0x2e,0x24,0x0, 0x6, 0x12,0x67,0x47,0x7c,0xab,0x7c,0xb7,0x4, +0x7a,0xb3,0x38,0xf3,0xb4,0x3, 0xb, 0xe4,0x7a,0xb3,0x38,0xf3,0x6d,0x33,0x7a,0x37, +0x38,0xf0,0x75,0x1a,0xeb,0x7c,0xba,0x22,0x7c,0xa7,0x7c,0x3b,0xa5,0xbb,0x0, 0x7, +0x7c,0xba,0x12,0x68,0x27,0x80,0x2c,0xbe,0x30,0xeb,0x68,0x4, 0xa5,0xbb,0xec,0x9, +0x7c,0xb3,0x7c,0x7a,0x12,0x68,0x71,0x80,0x1a,0xbe,0x30,0x80,0x40,0x15,0xbe,0x30, +0xdf,0x38,0x10,0x7c,0xb3,0x24,0x80,0x7c,0x7a,0x12,0x71,0x62,0xa5,0xbb,0x8f,0x3, +0x75,0x19,0x1, 0xa5,0xbb,0xfc,0x5, 0x7c,0xba,0x2, 0x2e,0xbd,0x74,0x1, 0x7a,0xb3, +0x3, 0xff,0x22,0x2e,0x24,0x20,0x7d,0x7a,0x51,0x82,0x7a,0x41,0x83,0xe4,0x93,0x22, +0x7c,0xab,0x6c,0x77,0xa, 0x27,0x2e,0x24,0x60,0xac,0x12,0x67,0x47,0xbc,0xba,0x78, +0x2, 0xd3,0x22,0xb, 0x70,0xbe,0x70,0x3, 0x40,0xea,0xc3,0x22,0x6c,0x33,0x80,0x1f, +0x7c,0xb3,0x12,0x67,0x50,0x40,0x16,0x7c,0xb3,0x12,0x67,0x98,0x7d,0x43,0x6d,0x55, +0x7d,0x4, 0x3e,0x4, 0x7e,0x1f,0x13,0x8a,0x2d,0x30,0x1b,0x1a,0x50,0xb, 0x30,0x7e, +0x23,0x2a,0x75,0xbc,0x23,0x38,0xd9,0x22,0x7e,0x73,0x2a,0x6e,0xac,0x7b,0x2e,0x34, +0x0, 0x18,0x22,0x6c,0x33,0x6c,0x22,0x80,0x28,0x7c,0xb2,0x12,0x67,0x50,0x50,0x1f, +0x7c,0xb2,0x12,0x67,0x98,0x3e,0x34,0x7e,0x7f,0x13,0x8a,0x2d,0xf3,0xb, 0x7a,0x30, +0x12,0x67,0xda,0x59,0x35,0x39,0xe9,0x30,0x0, 0x5, 0x6d,0x33,0x1b,0x7a,0x30,0xb, +0x20,0x7e,0x73,0x2a,0x75,0xbc,0x72,0x38,0xd0,0x22,0x7c,0xa3,0xb, 0x30,0x74,0x2, +0xa4,0x22,0x7c,0xab,0x7c,0xb7,0xb4,0x18,0x9, 0x7c,0xba,0x12,0x67,0x50,0x50,0x2, +0xd3,0x22,0xc3,0x22,0x7e,0xa3,0x38,0x9c,0x7c,0xba,0x4, 0x7a,0xb3,0x38,0x9c,0x7a, +0xa3,0x37,0xf3,0x22,0xca,0x7b,0xca,0x2b,0xca,0x1b,0xca,0xb, 0xc0,0x83,0xc0,0x82, +0x12,0x66,0x7e,0xd0,0x82,0xd0,0x83,0xda,0xb, 0xda,0x1b,0xda,0x2b,0xda,0x7b,0x32, +0xa9,0xc0,0x93,0x75,0x18,0x0, 0x32,0x7a,0xb3,0x38,0x9d,0xc4,0x54,0x7, 0xbe,0xb0, +0x4, 0x68,0x3, 0xb4,0x2, 0x4, 0x74,0x3, 0x80,0x7, 0x60,0x3, 0xb4,0x1, 0x7, 0x74, +0x1, 0x7a,0xb3,0x38,0x9, 0x22,0x74,0x1, 0x7a,0xb3,0x38,0x9, 0xe4,0x7a,0xb3,0x38, +0x9d,0x22,0x7e,0xb3,0x38,0xf2,0x4, 0x7a,0xb3,0x38,0xf2,0xe5,0x19,0xb4,0x1, 0x8, +0xe4,0x7a,0xb3,0x38,0xf2,0x75,0x19,0x0, 0x7e,0x73,0x38,0xf2,0x7a,0x73,0x37,0xf1, +0x22,0xbe,0xb0,0xeb,0x68,0x3, 0xb4,0xec,0x33,0x7e,0x27,0x38,0xf0,0x4d,0x22,0x78, +0xe, 0xa5,0xbf,0xaa,0xa, 0x7e,0x24,0x0, 0x1, 0x7a,0x27,0x38,0xf0,0x15,0x1a,0x7e, +0x27,0x38,0xf0,0xbe,0x24,0x0, 0x1, 0x78,0x10,0xa5,0xbf,0x9, 0x6, 0x7e,0x34,0x0, +0x2, 0x80,0x2, 0x6d,0x33,0x7a,0x37,0x38,0xf0,0x75,0x1a,0xea,0x22,0xe4,0x7a,0xb3, +0x38,0x9d,0x7e,0x8, 0x35,0x93,0x12,0x68,0xfc,0x7e,0x8, 0x35,0xd1,0x7e,0x34,0x0, +0x3e,0x12,0x20,0xe8,0x7e,0x18,0x35,0x93,0x7a,0x1d,0x14,0x12,0x68,0xde,0x2, 0x68, +0xd1,0x75,0x18,0x0, 0x75,0x1a,0x0, 0x7e,0xb3,0x38,0x9d,0xf5,0x91,0x22,0x2, 0x68, +0xe1,0x90,0x60,0x0, 0xe4,0x93,0x54,0xfe,0x75,0x91,0x0, 0xc2,0x90,0xc2,0x91,0xc2, +0xc9,0x54,0xfe,0xf5,0x92,0xd2,0xe8,0xc2,0xc0,0xd2,0xad,0x22,0x7e,0x34,0x0, 0x3e, +0x74,0xff,0x2, 0x20,0xe8,0x30,0x1d,0x8, 0x74,0x5, 0x7e,0x70,0x99,0x12,0x13,0x2c, +0x7e,0xb3,0x34,0x3a,0xb4,0x1, 0x4f,0x12,0x69,0x67,0x49,0x35,0x34,0x3b,0x49,0x15, +0x34,0x3d,0x6d,0x0, 0xbe,0x8, 0x0, 0x0, 0x68,0x1a,0xbe,0x70,0x0, 0x40,0x15,0xbe, +0x70,0x2, 0x38,0x10,0x74,0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0x73,0x7e,0x73,0x2a, +0x74,0x12,0x10,0xee,0x7e,0xb3,0x34,0x39,0x4, 0x7a,0xb3,0x34,0x39,0x12,0x69,0x6f, +0x28,0xe, 0x12,0x3f,0xd2,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x6, 0x74,0x3, 0x80,0x2, +0x74,0x2, 0x7a,0xb3,0x34,0x3a,0x22,0x7e,0xa3,0x34,0x39,0x74,0x4, 0xa4,0x22,0x7e, +0x73,0x34,0x38,0xbe,0x73,0x34,0x39,0x22,0x7e,0xb3,0x34,0x3a,0xb4,0x1, 0x2, 0xc3, +0x22,0xd3,0x22,0x7e,0xb3,0x2b,0x1e,0x70,0x1f,0x12,0x2f,0xe7,0x12,0x69,0x78,0x50, +0xfb,0x12,0x69,0xa9,0x12,0x6a,0xb8,0x20,0x13,0x3, 0x12,0x55,0xae,0x74,0x2, 0x7a, +0xb3,0x2b,0x1e,0xe4,0x7a,0xb3,0x16,0x91,0x22,0x7e,0xf, 0x13,0x8a,0x7e,0x18,0x8, +0xa, 0xca,0x3b,0x7a,0x1d,0x29,0x7f,0x30,0x12,0x57,0xe5,0xa4,0x7a,0x55,0x31,0x7e, +0xb3,0x2b,0x1d,0xf5,0x2e,0xe4,0x7a,0xb3,0x2b,0x1d,0x7f,0x3, 0x7e,0x1d,0x29,0x12, +0x5f,0xd5,0x12,0xc6,0xa3,0x12,0x3f,0xeb,0x75,0x2d,0x0, 0x12,0x3f,0xa5,0x30,0xf, +0xfd,0x74,0x1, 0x12,0x6a,0x73,0x7e,0x14,0x40,0x0, 0x7d,0x21,0x7d,0x7, 0x12,0x56, +0x2d,0x12,0x6a,0x2e,0x6d,0x33,0x80,0x19,0x7e,0x35,0x2f,0x3e,0x34,0x7f,0x3, 0x2d, +0x13,0xb, 0xa, 0x20,0x7e,0xd, 0x29,0x2d,0x13,0x12,0xc6,0xbf,0x7e,0x35,0x2f,0xb, +0x34,0x7a,0x35,0x2f,0x7e,0x35,0x31,0xbe,0x35,0x2f,0x38,0xdc,0x5, 0x2d,0xe5,0x2d, +0xbe,0xb0,0x1, 0x40,0xb6,0xe5,0x2e,0x7a,0xb3,0x2b,0x1d,0xda,0x3b,0x22,0x7e,0xa3, +0x2a,0x6e,0xa, 0x3a,0x3e,0x34,0x7e,0x8, 0x13,0x8e,0xe4,0x12,0x20,0xe8,0x7e,0xb3, +0x2a,0x71,0x12,0xb9,0x19,0x7d,0x43,0x6c,0x77,0x80,0x1d,0xa, 0x27,0x2d,0x24,0x12, +0x4f,0xe5,0xb, 0xa, 0x0, 0x7e,0x30,0x2, 0xac,0x37,0x2e,0x14,0x13,0x8e,0xb, 0x18, +0x20,0x2d,0x20,0x1b,0x18,0x20,0xb, 0x70,0xbc,0xa7,0x38,0xdf,0x22,0x12,0x69,0x78, +0x50,0xfb,0x22,0x12,0x0, 0xe, 0x7e,0x1f,0x13,0x86,0x22,0x7e,0x8, 0x24,0xf2,0x7e, +0x34,0x0, 0xc, 0xe4,0x12,0x20,0xe8,0x12,0xa4,0x5f,0x12,0xa4,0x56,0xa9,0xd1,0xcb, +0x12,0x6a,0x73,0x7a,0x37,0x24,0xf6,0x7e,0x1f,0x39,0xda,0x7a,0x37,0x24,0xf8,0x7e, +0x1f,0x13,0x86,0x7a,0x37,0x24,0xfa,0x6d,0x33,0x12,0xb9,0x10,0x2, 0xd, 0x7, 0x12, +0xa5,0xef,0x12,0x6a,0x7b,0x2, 0x6a,0xb8,0x12,0x57,0x8e,0x50,0x3, 0xd2,0x13,0x22, +0xc2,0x13,0x22,0x12,0x75,0xd2,0x12,0x6b,0x17,0x12,0xad,0xc9,0x12,0x6c,0x68,0x7e, +0xb3,0x38,0x7, 0xb4,0x1, 0x7, 0x7e,0x34,0x0, 0x14,0x12,0x5f,0xcc,0x7e,0xb3,0x3a, +0xe, 0x60,0x7, 0x14,0x7a,0xb3,0x3a,0xe, 0x80,0x6, 0x7e,0xb3,0x28,0xac,0x60,0xc, +0x12,0x6a,0xaf,0x12,0x57,0x9f,0x12,0xb5,0xf1,0x12,0x9e,0x4f,0x7e,0xb3,0x34,0xb6, +0x60,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x7e,0xb3,0x28,0xad,0x60,0x9, 0x12,0xbb,0x95, +0x12,0xa4,0x68,0x2, 0xaa,0x3c,0x22,0x7e,0x90,0x1, 0x12,0x5f,0xc8,0x7e,0xf4,0x0, +0x96,0xe4,0x7a,0xb3,0x28,0xac,0x12,0x6c,0x48,0x7e,0x34,0xfe,0x89,0x7e,0x27,0x7, +0xfe,0xbe,0x24,0xfd,0x12,0x58,0x1c,0x7e,0xe7,0x7, 0xfc,0xbd,0xe3,0x58,0x14,0x6d, +0xee,0x9e,0xe7,0x2a,0x5a,0xbe,0xe7,0x28,0x8e,0x8, 0x8, 0x12,0xac,0x93,0x60,0x3, +0x12,0xa6,0x2e,0x12,0xa6,0x3d,0x40,0x5, 0xe4,0x7a,0xb3,0x28,0xa8,0x12,0xc7,0x1, +0x68,0x6, 0x7e,0xb3,0x3a,0xc, 0x60,0x7, 0xe4,0x7a,0xb3,0x28,0xad,0x80,0x65,0x12, +0x6c,0x4f,0x28,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x30,0x14,0x5, 0xe4,0x7a,0xb3,0x28, +0xad,0x12,0xa6,0x7b,0x50,0xa, 0x12,0x6c,0x48,0x12,0x6c,0x85,0x7c,0x9b,0x80,0x17, +0x7e,0xb3,0x26,0x84,0x70,0x11,0x7e,0xb3,0x26,0x85,0x70,0xb, 0x12,0x6c,0x4f,0x28, +0x6, 0x7e,0x90,0x3, 0x12,0x6c,0x48,0x7e,0xe7,0x7, 0xfa,0xbe,0xe4,0x5, 0xdc,0x8, +0x17,0x12,0x6c,0x4f,0x28,0x12,0x6d,0xee,0x9d,0xef,0xbe,0xe7,0x28,0x8e,0x58,0x8, +0x12,0x6c,0x5a,0xe4,0x7a,0xb3,0x28,0xad,0x74,0x4, 0xac,0xb9,0x7a,0x57,0x28,0xa1, +0x7a,0x57,0x28,0xa3,0x12,0x6c,0x57,0x50,0xd, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x76, +0xe0,0x28,0x3, 0x12,0x6c,0x5a,0x7e,0xe7,0x28,0x8a,0xbd,0xef,0x8, 0x1f,0x7e,0x24, +0x0, 0x2, 0x7d,0x3f,0x12,0x1e,0xb9,0x6e,0x34,0xff,0xff,0xb, 0x34,0xbe,0x37,0x28, +0x8e,0x58,0xa, 0x12,0x6c,0x57,0x50,0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x6c,0xe8, +0xb4,0x1, 0x5, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0xa5,0x95,0x7e,0xb3,0x2f,0xa9,0xbe, +0xb0,0x0, 0x28,0x23,0x14,0x7a,0xb3,0x2f,0xa9,0x70,0x1c,0xe4,0x7a,0xb3,0x28,0xad, +0x74,0x1, 0x7a,0xb3,0x28,0xac,0xe4,0x7a,0xb3,0x16,0x91,0x7a,0xb3,0x16,0x90,0x7a, +0xb3,0x28,0x84,0x7a,0xb3,0x26,0x83,0x22,0x74,0x1, 0x7a,0xb3,0x28,0xad,0x22,0x7e, +0x83,0x28,0x84,0xbe,0x80,0x0, 0x22,0xa2,0x17,0x22,0xe4,0x7a,0xb3,0x2f,0xa9,0x7a, +0xb3,0x28,0xac,0x74,0x2, 0x2, 0x26,0x12,0x12,0xab,0xcd,0x60,0x17,0x12,0x6c,0x48, +0x7e,0x37,0x28,0xa1,0x3e,0x34,0x7a,0x37,0x28,0xa1,0x7e,0x37,0x28,0xa3,0x3e,0x34, +0x7a,0x37,0x28,0xa3,0x22,0x7e,0xa0,0x1, 0x7e,0x47,0x7, 0xf8,0x7e,0x4, 0x0, 0xfa, +0xbe,0x44,0xfd,0x12,0x58,0x12,0x7e,0xb3,0x28,0xac,0x60,0x7, 0xe4,0x7a,0xb3,0x28, +0xad,0x80,0x38,0x7e,0xa0,0x5, 0x80,0x33,0x7e,0x34,0xff,0xfb,0xad,0x30,0x7e,0x14, +0x0, 0x2, 0x12,0x6c,0xe0,0x8, 0x5, 0x7e,0xa0,0x4, 0x80,0x1f,0x7e,0x34,0xff,0xfc, +0x12,0x6c,0xde,0x8, 0x5, 0x7e,0xa0,0x3, 0x80,0x11,0x7e,0x34,0xff,0xfd,0x12,0x6c, +0xde,0x8, 0x5, 0x7e,0xa0,0x2, 0x80,0x3, 0x7e,0xa0,0x1, 0x7c,0xba,0x22,0xad,0x30, +0x7d,0x21,0x12,0x1e,0xb9,0xbd,0x34,0x22,0xca,0x3b,0x12,0x9a,0xbf,0x38,0x2, 0xa1, +0xab,0x7e,0xc3,0x2f,0xac,0x4c,0xcc,0x78,0x3d,0x7a,0xb3,0x2f,0xac,0xe4,0x7a,0xb3, +0x2f,0xae,0x6c,0xaa,0x80,0x26,0x12,0x6d,0xb6,0x7e,0x70,0x2, 0xac,0x7a,0x9, 0xd3, +0x26,0xfa,0x9, 0xe3,0x26,0xfb,0x7a,0x49,0xd0,0x19,0xe4,0x0, 0x1, 0x74,0x1, 0x19, +0xb4,0x0, 0x8, 0x12,0x6d,0xc0,0x59,0x34,0x0, 0x2, 0xb, 0xa0,0x7e,0xb3,0x28,0x84, +0xbc,0xba,0x38,0xd2,0x80,0x7b,0x7c,0xfc,0x6c,0xaa,0x80,0x31,0x12,0x6d,0xb6,0x7e, +0x49,0xd0,0x9, 0xe4,0x0, 0x1, 0x9, 0xb4,0x0, 0x8, 0x70,0x4, 0x1b,0xf0,0x80,0x1b, +0x12,0x6d,0xc0,0x7d,0x23,0x49,0x34,0x0, 0x2, 0x12,0xa1,0xb6,0xbe,0xf4,0x0, 0x23, +0x8, 0x9, 0x74,0x5, 0x19,0xb4,0x0, 0x8, 0x75,0x5c,0x1, 0xb, 0xa0,0xbc,0xfa,0x38, +0xcb,0x4c,0xff,0x78,0x2, 0x80,0x26,0x7e,0x73,0x2f,0xae,0xbe,0x70,0x4, 0x40,0x22, +0x6c,0xaa,0x80,0xe, 0x12,0x6d,0xb6,0x9, 0xb4,0x0, 0x8, 0xbe,0xb0,0x5, 0x68,0x6, +0xb, 0xa0,0xbc,0xfa,0x38,0xee,0xbc,0xfa,0x78,0x3, 0x75,0x5c,0x0, 0x12,0x6f,0x5d, +0x80,0xf, 0x7c,0xb7,0x4, 0x7a,0xb3,0x2f,0xae,0x80,0x6, 0x12,0x6f,0x5d,0x75,0x5c, +0x0, 0xe5,0x5c,0xda,0x3b,0x22,0x7e,0x90,0x9, 0xac,0x9a,0x2e,0x44,0x2f,0xaf,0x22, +0x7c,0xbd,0x7c,0x7e,0x2, 0x6d,0xcb,0x7c,0xba,0x7c,0x79,0x12,0x6f,0x81,0xb, 0x1a, +0x30,0x22,0x7c,0xbd,0x7c,0x7e,0x7f,0x4, 0xca,0x3b,0x7f,0x70,0x7c,0xe7,0x7c,0xdb, +0x7e,0xc0,0x4, 0x7e,0xb3,0x2a,0x6d,0xf5,0x26,0x7e,0xb3,0x2a,0x6e,0xf5,0x25,0x7e, +0xd4,0x0, 0xc8,0x6c,0xff,0x12,0x6f,0x7d,0xe5,0x26,0xa, 0x1b,0x1b,0x14,0xa, 0xcd, +0xbd,0xc1,0x58,0x14,0xe5,0x25,0xa, 0x1b,0x1b,0x14,0xa, 0xce,0xbd,0xc1,0x58,0x8, +0x4c,0xee,0x68,0x4, 0x4c,0xdd,0x78,0x3, 0x4e,0xf0,0x10,0xb, 0x1a,0xc0,0xbe,0xc4, +0x0, 0xc8,0x8, 0xc, 0x7e,0x17,0x28,0x8a,0xbe,0x14,0x3, 0x20,0x8, 0x2, 0xe1,0x1c, +0xbe,0xc4,0x0, 0x64,0x8, 0xc, 0x7e,0xc7,0x28,0x8a,0xbe,0xc4,0x3, 0x20,0x58,0x2, +0xe1,0x1c,0x6c,0xaa,0x7c,0x8d,0x80,0x1c,0x7c,0x9e,0xbe,0x80,0x0, 0x48,0x11,0x7e, +0xb3,0x2a,0x6d,0xbc,0xb8,0x8, 0x9, 0x12,0x6f,0x53,0x58,0x14,0xb, 0xa0,0x80,0x2, +0xb, 0xa0,0x1b,0x80,0x1a,0x2c,0x1a,0x3d,0x9d,0x32,0x1a,0xc8,0xbd,0xc3,0x18,0xd8, +0xbc,0xca,0x18,0x5, 0x4e,0xf0,0x1, 0xe1,0x1c,0x6c,0xaa,0x7c,0x8d,0x80,0x1c,0x7c, +0x9e,0xbe,0x80,0x0, 0x48,0x11,0x7e,0xb3,0x2a,0x6d,0xbc,0xb8,0x8, 0x9, 0x12,0x6f, +0x53,0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0xb, 0x80,0x1a,0x2c,0x1a,0x3d,0x2d, +0x32,0x1a,0xc8,0xbd,0xc3,0x48,0xd8,0xbc,0xca,0x18,0x5, 0x4e,0xf0,0x2, 0x80,0x6c, +0x6c,0xaa,0x7c,0x9e,0x80,0x1c,0x7c,0x8d,0xbe,0x90,0x0, 0x48,0x11,0x7e,0xb3,0x2a, +0x6e,0xbc,0xb9,0x8, 0x9, 0x12,0x6f,0x53,0x58,0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0, +0x1b,0x90,0x1a,0x2c,0x1a,0x3e,0x9d,0x32,0x1a,0xc9,0xbd,0xc3,0x18,0xd8,0xbc,0xca, +0x18,0x5, 0x4e,0xf0,0x4, 0x80,0x35,0x6c,0xaa,0x7c,0x9e,0x80,0x1c,0x7c,0x8d,0xbe, +0x90,0x0, 0x48,0x11,0x7e,0xb3,0x2a,0x6e,0xbc,0xb9,0x8, 0x9, 0x12,0x6f,0x53,0x58, +0x14,0xb, 0xa0,0x80,0x2, 0xb, 0xa0,0xb, 0x90,0x1a,0x2c,0x1a,0x3e,0x2d,0x32,0x1a, +0xc9,0xbd,0xc3,0x48,0xd8,0xbc,0xca,0x18,0x3, 0x4e,0xf0,0x8, 0x4c,0xff,0x68,0x2e, +0x7e,0x7b,0xb0,0xbc,0xbd,0x40,0x3, 0x7a,0x7b,0xd0,0x29,0xb7,0x0, 0x2, 0xbc,0xbd, +0x38,0x4, 0x39,0xd7,0x0, 0x2, 0x29,0xb7,0x0, 0x1, 0xbc,0xbe,0x40,0x4, 0x39,0xe7, +0x0, 0x1, 0x29,0xb7,0x0, 0x3, 0xbc,0xbe,0x38,0x4, 0x39,0xe7,0x0, 0x3, 0x7c,0xbf, +0xda,0x3b,0x22,0x7c,0xb8,0x7c,0x79,0x12,0x6d,0xcb,0xbd,0x3d,0x22,0xe4,0x7a,0xb3, +0x2f,0xad,0x7a,0xb3,0x2f,0xac,0x7a,0xb3,0x2f,0xae,0x22,0x7c,0xab,0x7e,0x70,0x2, +0xac,0x7a,0x9, 0xb3,0x26,0xfa,0x9, 0x73,0x26,0xfb,0x2, 0x6d,0xcb,0x7c,0xbd,0x7c, +0x7e,0x7e,0x13,0x2a,0x6e,0xac,0x1b,0x3e,0x4, 0x7e,0x30,0x2, 0xac,0x37,0x2d,0x10, +0x7e,0x1f,0x13,0x8a,0x2d,0x31,0x22,0xca,0x79,0x6c,0xff,0x7e,0xd7,0x2a,0x5a,0x6c, +0xee,0x80,0x3e,0x12,0x7f,0xfc,0x50,0x4, 0x7e,0xd7,0x2a,0x5c,0x7c,0xbe,0x12,0x6f, +0x6b,0xbd,0x3d,0x48,0x2a,0x7c,0xbe,0x12,0x88,0x65,0x60,0x23,0x7e,0xc4,0x0, 0x9, +0xca,0xc9,0x7e,0x70,0x9, 0xac,0x7e,0x2e,0x34,0x27,0x76,0x6d,0x22,0x7e,0x30,0x9, +0xac,0x3f,0x2e,0x14,0x28,0xae,0x6d,0x0, 0x12,0x20,0xc3,0x1b,0xfd,0xb, 0xf0,0xb, +0xe0,0x12,0x97,0xbe,0x38,0xbd,0x7a,0x73,0x28,0x93,0x7a,0xf3,0x2a,0x2, 0xda,0x79, +0x22,0x2, 0x6f,0x97,0x7e,0x70,0x18,0x2, 0x6d,0xcb,0x7d,0xf3,0x6d,0xee,0x6c,0x99, +0x80,0x3c,0x7c,0xb9,0x12,0x67,0x98,0x7d,0xd3,0x7d,0xcd,0x3e,0xc4,0x7f,0x57,0x2d, +0xbc,0xb, 0x5a,0x10,0x1a,0x2, 0x1a,0x0, 0x7e,0x83,0x2b,0x20,0xa, 0x98,0x6d,0x88, +0x7f,0x10,0x7f,0x4, 0x12,0x1e,0xeb,0x74,0x6, 0x7f,0x1, 0x1e,0x14,0x1e,0x4, 0x50, +0x3, 0x4e,0x20,0x80,0x14,0x78,0xf4,0x7d,0xc1,0x1b,0x5a,0xc0,0xb, 0x90,0x7e,0x83, +0x2a,0x75,0xbc,0x89,0x38,0xbc,0x22,0xca,0x79,0x7c,0x5b,0x7e,0x43,0x28,0x84,0xbe, +0x40,0x1, 0x28,0x2, 0x21,0x56,0x7e,0xa3,0x2a,0x6e,0x7e,0x70,0x2, 0xac,0x75,0x9, +0xf3,0x26,0xfa,0x9, 0xe3,0x26,0xfb,0x7c,0xbf,0x7c,0x7e,0x12,0x6f,0x81,0x7f,0x51, +0x7c,0x1e,0x7c,0x3f,0x7e,0x3, 0x2a,0x70,0x7e,0x23,0x2a,0x6f,0xa, 0x3a,0x6d,0xdd, +0x9d,0xd3,0xa, 0x9a,0xa, 0xc0,0x1b,0xc5,0xa, 0x51,0xbd,0x5c,0x58,0x2, 0x21,0x56, +0xa, 0x53,0x1b,0x54,0xbe,0x54,0x0, 0x0, 0x48,0x55,0x7c,0xb3,0x14,0x12,0x67,0x50, +0x50,0x4d,0x7c,0xb3,0x14,0x12,0x67,0x98,0x7d,0xe3,0x7d,0x5e,0x12,0x71,0x59,0xb, +0x1a,0xf0,0x7d,0x5d,0x3e,0x54,0x7f,0x15,0x2d,0x35,0xb, 0x1a,0x80,0xbe,0xf4,0x0, +0x0, 0x8, 0x11,0x9d,0x8f,0xbe,0x84,0x0, 0x0, 0x58,0x4, 0x6d,0x55,0x80,0x2, 0x7d, +0x58,0x1b,0x1a,0x50,0x7c,0xb0,0x24,0xfe,0xbc,0xb1,0x78,0x13,0x7d,0x4e,0x1b,0x44, +0x7d,0x54,0x12,0x71,0x59,0xb, 0x1a,0x50,0xbd,0x58,0x8, 0x3, 0x1b,0x1a,0x80,0xa, +0x83,0xb, 0x84,0xa, 0x52,0xbd,0x85,0x58,0x5d,0x7c,0xb3,0x4, 0x12,0x67,0x50,0x50, +0x55,0x7c,0xb3,0x4, 0x12,0x67,0x98,0x7d,0xe3,0x7d,0x1e,0x3e,0x14,0x7e,0x1f,0x13, +0x8a,0x7f,0x61,0x2d,0xd1,0xb, 0x6a,0xf0,0x7d,0x19,0x3e,0x14,0x7f,0x65,0x2d,0xd1, +0xb, 0x6a,0x10,0xbe,0xf4,0x0, 0x0, 0x8, 0x11,0x9d,0x1f,0xbe,0x14,0x0, 0x0, 0x58, +0x4, 0x6d,0x55,0x80,0x2, 0x7d,0x51,0x1b,0x6a,0x50,0x7c,0xb0,0x24,0xfe,0xbc,0xb1, +0x78,0x14,0x7d,0x4e,0x1b,0x44,0x7d,0x4, 0x3e,0x4, 0x2d,0x30,0xb, 0x1a,0x0, 0xbd, +0x1, 0x8, 0x3, 0x1b,0x1a,0x10,0xda,0x79,0x22,0x3e,0x54,0x7e,0x1f,0x13,0x8a,0x2d, +0x35,0x22,0x7c,0x6b,0x2e,0x60,0xdd,0x68,0x26,0x2e,0x60,0xfd,0x68,0x21,0x1b,0x61, +0x68,0x1d,0x1b,0x62,0x68,0x19,0x1b,0x61,0x68,0x15,0x1b,0x60,0x68,0x11,0x2e,0x60, +0xa, 0x78,0x4, 0x7a,0x73,0x37,0xe1,0xa, 0x2b,0x19,0x72,0x37,0xe2,0xd2,0x11,0x22, +0xca,0x79,0x6c,0xaa,0x6c,0xee,0x6d,0xdd,0x7e,0xe4,0x7f,0xff,0x7e,0xf0,0x1, 0x80, +0x28,0xa, 0xff,0x7e,0xb3,0x2a,0x6e,0xa, 0xcb,0x2d,0xcf,0x3e,0xc4,0x49,0xfc,0x4, +0xfc,0xbe,0xf4,0x1, 0xf4,0x8, 0x10,0xb, 0xa0,0xbd,0xfd,0x8, 0x4, 0x7d,0xdf,0x80, +0x6, 0xbd,0xfe,0x58,0x2, 0x7d,0xef,0xb, 0xf0,0x7e,0xb3,0x2a,0x6f,0xa, 0xcb,0x1b, +0xc4,0xa, 0xff,0xbd,0xfc,0x48,0xca,0x74,0x2, 0x12,0x6f,0xf4,0x7d,0xf3,0x74,0x6, +0x12,0x6f,0xf4,0x7d,0x43,0x74,0xb, 0x12,0x6f,0xf4,0xbe,0xa0,0xc, 0x78,0x1f,0x7d, +0x2d,0x9d,0x2e,0xbe,0x24,0x7, 0xd0,0x58,0x15,0xbe,0xf4,0x0, 0x50,0x8, 0xf, 0xbe, +0x44,0x0, 0x64,0x8, 0x9, 0xbe,0x34,0x0, 0x50,0x8, 0x3, 0x7e,0xe0,0x1, 0x7e,0xb3, +0x37,0xee,0xb4,0x1, 0xc, 0x74,0xc, 0x6c,0x77,0x12,0x71,0x62,0x6c,0xee,0x12,0x72, +0xfd,0xbe,0xe0,0x1, 0x78,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x7a,0xb3,0x34,0xb6,0xb4, +0x1, 0x34,0x7e,0xb3,0x34,0xc5,0xbe,0xb0,0x8, 0x50,0x1a,0x4, 0x7a,0xb3,0x34,0xc5, +0x7e,0x73,0x34,0xc5,0xbe,0x70,0x3, 0x28,0xc, 0x74,0x8, 0x7a,0xb3,0x34,0xc5,0x74, +0x1, 0x7a,0xb3,0x34,0x8b,0x7e,0x73,0x34,0xc5,0xbe,0x70,0x8, 0x40,0x8, 0x12,0x72, +0xc2,0x60,0x3, 0x12,0x73,0x12,0x7e,0x73,0x34,0xb6,0xbe,0x70,0x0, 0x38,0x5, 0x12, +0x72,0xc2,0x70,0x39,0x6c,0xff,0x80,0x30,0x7c,0xbf,0x12,0x8b,0xef,0x60,0x23,0x7e, +0xb3,0x34,0xda,0x4, 0x12,0x73,0x26,0x7e,0x73,0x34,0xda,0xbe,0x70,0x5, 0x40,0x16, +0x12,0x72,0xfd,0xe4,0x7a,0xb3,0x34,0xda,0x7a,0xb3,0x34,0xc5,0x7a,0xb3,0x34,0x8b, +0x80,0x4, 0xe4,0x12,0x73,0x26,0xb, 0xf0,0x12,0x73,0x6d,0x38,0xcb,0x12,0x72,0xc2, +0x70,0xc, 0x12,0x76,0xe0,0x28,0x4, 0x74,0x5, 0x80,0x4, 0xe4,0x80,0x1, 0xe4,0xda, +0x79,0x22,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x3, 0x74,0x1, 0x22,0x7e,0x34,0xd7,0x0, +0x12,0x72,0xf5,0x70,0x1b,0x7e,0x34,0xd7,0x1, 0x12,0x72,0xf5,0x70,0x12,0x7e,0x34, +0xd7,0x2, 0x12,0x72,0xf5,0x70,0x9, 0x7e,0x34,0xd7,0x3, 0x12,0x72,0xf5,0x60,0x2, +0xe4,0x22,0x74,0x1, 0x22,0x7e,0x24,0x0, 0xff,0x7e,0x1b,0xb0,0x22,0xe4,0x12,0x77, +0x11,0x12,0x77,0x9, 0x12,0x77,0x1, 0x2, 0x73,0xa, 0x7e,0x34,0xd7,0x3, 0x7a,0x1b, +0xb0,0x22,0x74,0x55,0x12,0x77,0x11,0x74,0xaa,0x12,0x77,0x9, 0x74,0x55,0x12,0x77, +0x1, 0x74,0xaa,0x2, 0x73,0xa, 0x7a,0xb3,0x34,0xda,0x7c,0xbf,0x6c,0x77,0x7c,0x67, +0x7c,0x7b,0xc4,0x23,0x54,0x1f,0x7c,0xab,0x7c,0xb7,0x54,0x7, 0xa, 0x2b,0x2e,0x24, +0x0, 0x5e,0x12,0x67,0x47,0x7c,0x7b,0x4c,0x66,0x68,0xf, 0xa, 0x2a,0x2e,0x24,0x27, +0x72,0x7e,0x29,0xb0,0x4c,0xb7,0x7a,0x29,0xb0,0x22,0x7c,0xb7,0x64,0xff,0xa, 0x2a, +0x2e,0x24,0x27,0x72,0x7e,0x29,0x70,0x5c,0x7b,0x7a,0x29,0x70,0x22,0x7e,0x73,0x28, +0x84,0xbc,0x7f,0x22,0xca,0xd8,0xca,0x79,0xc2,0x0, 0x6d,0x88,0x7a,0x87,0x39,0x3d, +0xe4,0x7a,0xb3,0x1f,0x58,0xe5,0x1f,0xbe,0xb0,0xff,0x50,0x2, 0x5, 0x1f,0x7e,0xb3, +0x28,0x84,0x60,0xa, 0x7e,0x87,0x7, 0xfa,0xbe,0x84,0x0, 0xfa,0x58,0xa, 0xc2,0x14, +0x6d,0x88,0x7a,0x87,0x38,0xfe,0x81,0x97,0x12,0x91,0xe1,0x60,0x10,0x7e,0x84,0x0, +0x64,0x7a,0x87,0x38,0xf4,0x7e,0x84,0x0, 0x2d,0x7a,0x87,0x38,0xfe,0x7e,0x87,0x38, +0xf4,0x4d,0x88,0x68,0x6, 0x74,0x1, 0x7a,0xb3,0x28,0xa9,0x6c,0xff,0x80,0x76,0xe4, +0xa, 0x3f,0x19,0xb3,0x1f,0x34,0x12,0x75,0x14,0x7e,0x8, 0x1f,0x52,0x7c,0xbd,0x7c, +0x7e,0x12,0x90,0x9c,0x7d,0x93,0x7e,0x87,0x38,0xfe,0xbd,0x89,0x50,0x4, 0x7a,0x97, +0x38,0xfe,0x7e,0x87,0x39,0x3d,0xbd,0x89,0x50,0x4, 0x7a,0x97,0x39,0x3d,0xe5,0x1f, +0xbe,0xb0,0x5, 0x38,0x1f,0x7e,0x8, 0x39,0x0, 0x12,0x75,0x8c,0x50,0x7, 0x12,0x75, +0xb, 0xd2,0x0, 0x80,0x2e,0x7e,0x8, 0x39,0x0, 0x7e,0x18,0x1f,0x52,0x12,0x77,0x42, +0x50,0x21,0x80,0xf, 0xbe,0x94,0x0, 0x2d,0x40,0x19,0x7e,0x8, 0x1f,0x52,0x12,0x90, +0x4d,0x50,0x10,0x12,0x75,0xb, 0x7e,0x8, 0x1f,0x58,0x7e,0x18,0x1f,0x52,0x12,0x91, +0xbb,0xd2,0x0, 0xb, 0xf0,0x12,0x73,0x6d,0x38,0x85,0x30,0x0, 0x30,0x6c,0xff,0x80, +0x1c,0x12,0x75,0x14,0x7e,0x8, 0x1f,0x58,0x12,0x75,0x8c,0x40,0x9, 0xa, 0x3f,0x9, +0xb3,0x1f,0x34,0xb4,0x1, 0x5, 0x7c,0xbf,0x12,0x74,0xeb,0xb, 0xf0,0x12,0x73,0x6d, +0x38,0xdf,0x75,0x1f,0x0, 0x7e,0x34,0x0, 0x64,0x7a,0x37,0x38,0xf4,0x7e,0x63,0x1f, +0x58,0x7e,0x70,0x6, 0xac,0x67,0xb, 0x34,0xca,0x39,0x7e,0x18,0x1f,0x58,0x7e,0x8, +0x39,0x0, 0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x37,0x38,0xf4,0x4d,0x33,0x78,0x26,0x7e, +0x37,0x38,0xfe,0xbe,0x34,0x0, 0x2d,0x40,0x30,0x7e,0x37,0x39,0x3d,0xbe,0x34,0x0, +0x16,0x40,0x26,0x7e,0x73,0x26,0xf7,0xbe,0x70,0xc, 0x28,0x1d,0x7e,0x73,0x26,0xf6, +0xbe,0x70,0x7, 0x28,0x14,0x6c,0xff,0x80,0x7, 0x7c,0xbf,0x12,0x74,0xeb,0xb, 0xf0, +0x12,0x73,0x6d,0x38,0xf4,0xd2,0x0, 0x80,0x6, 0x6d,0x33,0x7a,0x37,0x38,0xfe,0xa2, +0x0, 0x92,0x14,0x12,0x77,0x2b,0xda,0x79,0xda,0xd8,0x22,0x7c,0xab,0x7e,0xb3,0x3a, +0xc, 0x70,0x17,0x7e,0xb3,0x28,0xa8,0x70,0x11,0x12,0x4f,0xd4,0x68,0xc, 0x12,0x90, +0x35,0x68,0x7, 0x7c,0xba,0x6c,0x77,0x2, 0x73,0x2e,0x22,0x74,0x1, 0xa, 0x8f,0x19, +0xb8,0x1f,0x34,0x22,0x74,0x2, 0xac,0xbf,0x9, 0xd5,0x26,0xfa,0x9, 0xe5,0x26,0xfb, +0x22,0xca,0xf8,0x6c,0xff,0x80,0x18,0x7c,0xbf,0x12,0x6f,0x6b,0xbe,0x37,0x2a,0x5c, +0x58,0xb, 0x12,0x73,0x2a,0x7e,0x70,0x2, 0xac,0x7f,0x12,0x8f,0xa4,0xb, 0xf0,0x12, +0x73,0x6d,0x38,0xe3,0x12,0x75,0x4a,0xda,0xf8,0x22,0xca,0x79,0x6c,0xff,0x6c,0xee, +0x80,0x2e,0x7c,0xbe,0x12,0x88,0x65,0x60,0x25,0x7e,0x34,0x0, 0x2, 0xca,0x39,0xac, +0x7e,0x2e,0x34,0x26,0xfa,0x6d,0x22,0x7e,0x30,0x2, 0xac,0x3f,0x2e,0x14,0x26,0xfa, +0x6d,0x0, 0x12,0x20,0xc3,0x1b,0xfd,0x7c,0xbf,0x12,0x76,0xfb,0xb, 0xf0,0xb, 0xe0, +0x12,0x97,0xbe,0x38,0xcd,0x7a,0xf3,0x28,0x84,0xda,0x79,0x22,0x7c,0xbd,0x7c,0x7e, +0x7c,0x6b,0xc2,0x1, 0x6c,0xaa,0x80,0x30,0x7e,0x50,0x6, 0xac,0x5a,0x7f,0x70,0x2d, +0xf2,0xb, 0xf4,0x29,0xb7,0x0, 0x2, 0xbc,0xb6,0x40,0x1b,0x7e,0x7b,0xb0,0xbc,0xb6, +0x38,0x14,0x29,0xb7,0x0, 0x3, 0xbc,0xb7,0x40,0xc, 0x29,0xb7,0x0, 0x1, 0xbc,0xb7, +0x38,0x4, 0xd2,0x1, 0x80,0x9, 0xb, 0xa0,0x7e,0xb, 0xb0,0xbc,0xba,0x38,0xc9,0xa2, +0x1, 0x22,0xca,0xd8,0xca,0x79,0x7e,0xa3,0x2a,0x6e,0x7e,0x47,0x28,0x99,0xe4,0x7a, +0xb3,0x28,0xa6,0x7e,0xb3,0x26,0xf0,0xbe,0xb0,0x0, 0x28,0x48,0x12,0x9e,0x47,0x28, +0x43,0x6c,0xff,0x80,0x3b,0x7e,0x50,0x2, 0xac,0x5f,0x9, 0xd2,0x27,0x36,0x9, 0xe2, +0x27,0x37,0x7e,0x50,0x2, 0xac,0x5e,0x49,0x12,0x4, 0xfc,0x6d,0x22,0x9e,0x27,0x2a, +0x53,0xbd,0x12,0x58,0x19,0x12,0x76,0xe8,0x49,0x12,0x4, 0xfc,0x6d,0x22,0x9e,0x27, +0x2a,0x51,0xbd,0x12,0x58,0x8, 0x74,0x1, 0x7a,0xb3,0x28,0xa6,0x80,0x6, 0xb, 0xf0, +0xbc,0x7f,0x38,0xc1,0xe4,0x7a,0xb3,0x28,0xa7,0x7e,0xb3,0x26,0x83,0x70,0x40,0x12, +0x76,0xe0,0x28,0x3b,0x6c,0xff,0x80,0x33,0x7e,0x50,0x2, 0xac,0x5f,0x9, 0xd2,0x26, +0xfa,0x9, 0xe2,0x26,0xfb,0x12,0x76,0xe8,0x49,0x2, 0x5, 0x7a,0x6d,0x11,0x9d,0x14, +0xbd,0x1, 0x48,0xd, 0x7e,0x10,0x2, 0xac,0x1e,0x49,0x20,0x5, 0x7a,0xbd,0x21,0x58, +0x8, 0x74,0x1, 0x7a,0xb3,0x28,0xa7,0x80,0x6, 0xb, 0xf0,0xbc,0x7f,0x38,0xc9,0x12, +0x9c,0xbc,0xe4,0x7a,0xb3,0x28,0xa9,0x7e,0x37,0x28,0x88,0x2e,0x37,0x28,0x86,0xbe, +0x37,0x28,0x9f,0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x28,0xa9,0x74,0x1, 0x7a,0xb3,0x28, +0xaa,0x6c,0xff,0x80,0x1f,0x12,0x76,0xf1,0x49,0x25,0x25,0xf7,0x7d,0x43,0x9d,0x42, +0x7d,0x34,0x12,0x21,0xa, 0xbe,0x37,0x28,0x9d,0x8, 0x7, 0xe4,0x7a,0xb3,0x28,0xaa, +0x80,0x7, 0xb, 0xf0,0x12,0x73,0x6d,0x38,0xdc,0x6c,0xff,0x80,0x9, 0x12,0x76,0xf1, +0x59,0x35,0x25,0xf7,0xb, 0xf0,0x12,0x73,0x6d,0x38,0xf2,0xda,0x79,0xda,0xd8,0x22, +0x7e,0x73,0x28,0x84,0xbe,0x70,0x0, 0x22,0xa, 0x1d,0xa, 0x2a,0x2d,0x21,0x3e,0x24, +0x22,0x7c,0xbf,0x12,0x6f,0x6b,0x74,0x2, 0xac,0xbf,0x22,0x7e,0x70,0x1, 0x2, 0x73, +0x2e,0x7e,0x34,0xd7,0x2, 0x7a,0x1b,0xb0,0x22,0x7e,0x34,0xd7,0x1, 0x7a,0x1b,0xb0, +0x22,0x7e,0x34,0xd7,0x0, 0x7e,0x24,0x0, 0xff,0x7a,0x1b,0xb0,0x22,0x12,0x77,0x74, +0x12,0x8d,0x9b,0x12,0x71,0x90,0x7a,0xb3,0x2a,0xc, 0x22,0x30,0x14,0x13,0x12,0xc7, +0x1, 0x68,0x6, 0x7e,0xb3,0x3a,0xc, 0x60,0x8, 0x7e,0x34,0xb, 0xb8,0x7a,0x37,0x38, +0xfc,0x22,0x7f,0x61,0x7f,0x50,0x7e,0x6b,0x90,0x80,0x1f,0x29,0x86,0x0, 0x1, 0x80, +0xf, 0x7f,0x5, 0x7c,0xb9,0x7c,0x78,0x12,0x75,0x90,0x50,0x2, 0xd3,0x22,0xb, 0x80, +0x29,0x76,0x0, 0x3, 0xbc,0x78,0x50,0xe9,0xb, 0x90,0x29,0x76,0x0, 0x2, 0xbc,0x79, +0x50,0xd9,0xc3,0x22,0x7e,0xa3,0x28,0x84,0xe4,0x7a,0xb3,0x34,0xb7,0x6c,0x33,0x80, +0x3d,0x7e,0x70,0x2, 0xac,0x73,0x9, 0x23,0x26,0xfb,0x7e,0x10,0x1, 0x6c,0x0, 0x80, +0x27,0xbc,0x3, 0x68,0x21,0x7e,0x70,0x2, 0xac,0x70,0x9, 0x93,0x26,0xfb,0xa, 0x29, +0xa, 0x32,0x12,0x82,0xcd,0x18,0x2, 0xb, 0x10,0xbe,0x10,0x2, 0x40,0x8, 0x74,0x2, +0x7a,0xb3,0x34,0xb7,0x80,0x6, 0xb, 0x0, 0xbc,0xa0,0x38,0xd5,0xb, 0x30,0xbc,0xa3, +0x38,0xbf,0x2, 0x77,0xc5,0xca,0xf8,0x7e,0x33,0x28,0x84,0x6c,0x22,0x80,0x3f,0x74, +0x2, 0xac,0xb2,0x9, 0x15,0x26,0xfa,0x9, 0x5, 0x26,0xfb,0x7e,0xa0,0x1, 0x6c,0x99, +0x80,0x26,0xbc,0x92,0x68,0x20,0x12,0x8f,0xde,0x9, 0xf3,0x26,0xfb,0xa, 0x28,0xa, +0x31,0x12,0x82,0xcd,0x18,0xb, 0xa, 0x2f,0xa, 0x30,0x12,0x82,0xcd,0x8, 0x2, 0xb, +0xa0,0xbe,0xa0,0x3, 0x50,0x6, 0xb, 0x90,0xbc,0x39,0x38,0xd6,0xb, 0x20,0xbc,0x32, +0x38,0xbd,0x7e,0xb3,0x35,0x54,0xbe,0xb0,0x0, 0x28,0x12,0x14,0x7a,0xb3,0x35,0x54, +0xbe,0xb0,0x14,0x28,0x8, 0x7e,0x34,0x0, 0x8c,0x7a,0x37,0x2a,0x5a,0x7e,0xb3,0x37, +0xed,0x70,0x58,0x7e,0xb3,0x3a,0xc, 0x70,0x52,0x7e,0xb3,0x37,0x71,0x70,0x4c,0x7e, +0x37,0x38,0xfe,0xbe,0x34,0x0, 0x14,0x50,0x42,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x3, +0x20,0x58,0x38,0x7e,0xb3,0x28,0x84,0xbe,0xb0,0x3, 0x40,0x2f,0xbe,0xa0,0x3, 0x40, +0x2a,0x7e,0xb3,0x26,0x85,0xbe,0xb0,0x3, 0x50,0x9, 0x7e,0xb3,0x26,0x84,0xbe,0xb0, +0x3, 0x40,0x18,0x7e,0xb3,0x26,0xf6,0xbe,0xb0,0x8, 0x50,0x9, 0x7e,0xb3,0x26,0xf7, +0xbe,0xb0,0x8, 0x40,0x6, 0x74,0x1e,0x7a,0xb3,0x35,0x54,0xda,0xf8,0x22,0xca,0xf8, +0x7e,0xa3,0x2a,0x2, 0x4c,0xaa,0x78,0x11,0x7e,0xb3,0x2a,0x3, 0xbe,0xb0,0x0, 0x28, +0x13,0x74,0x1, 0x7a,0xb3,0x2a,0x7, 0x80,0xb, 0xbe,0xa0,0x0, 0x28,0x6, 0x74,0x1, +0x7a,0xb3,0x2a,0xb, 0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x28,0xae,0x7e,0x8, +0x29,0x8, 0x12,0x20,0xc3,0x1b,0xfd,0x6c,0xff,0x12,0x7d,0x51,0x12,0x7a,0xa2,0x74, +0x9, 0xac,0xbf,0x59,0x35,0x29,0x8, 0x49,0x35,0x28,0xb0,0x12,0x78,0xeb,0x12,0x79, +0xe0,0xb, 0xf0,0xbe,0xf0,0xa, 0x40,0xe1,0xda,0xf8,0x22,0x7d,0xf3,0x9f,0x11,0x7e, +0x44,0x7, 0x80,0x12,0x7b,0x74,0x7d,0xd5,0x1b,0xd4,0xbe,0xf4,0x0, 0x3f,0x38,0x1f, +0x7e,0x24,0x0, 0x3f,0x9d,0x2f,0x7e,0x34,0x2, 0x57,0x12,0x79,0xc5,0xbe,0x18,0x0, +0x4a,0x40,0x4, 0x7e,0x18,0x0, 0x4a,0x7e,0x8, 0x0, 0x4a,0x9f,0x1, 0x7f,0x10,0x7d, +0x5d,0x9e,0x54,0x0, 0x3f,0xbd,0x5f,0x38,0x1f,0x12,0x79,0xd7,0x40,0x1a,0x7d,0x3d, +0x9e,0x34,0x0, 0x40,0x12,0x79,0xbd,0xbe,0x18,0x0, 0x4d,0x40,0x4, 0x7e,0x18,0x0, +0x4c,0x12,0x79,0xce,0x2f,0x10,0x80,0x14,0x12,0x79,0xd7,0x50,0xf, 0x7d,0x3d,0x9e, +0x34,0x0, 0x20,0x12,0x79,0xbd,0x7d,0x14,0x6d,0x0, 0x2f,0x10,0xbe,0xf4,0x0, 0x3f, +0x28,0x5a,0xbd,0x5f,0x28,0x56,0x7d,0xed,0xb, 0xe4,0x1e,0xe4,0x7d,0x5e,0x1b,0x54, +0xbd,0x5f,0x40,0xc, 0x7d,0x35,0x9d,0x3f,0x6d,0x22,0x7e,0x14,0x1, 0x44,0x80,0xa, +0x7d,0x3f,0x9d,0x3e,0x6d,0x22,0x7e,0x14,0x1, 0x43,0x12,0x1e,0xfc,0x12,0x79,0xc7, +0xbd,0x5f,0x7d,0x14,0x40,0xc, 0x1e,0x14,0x1b,0x14,0x6d,0x0, 0x9f,0x1, 0x7f,0x10, +0x80,0x6, 0x1e,0x14,0x6d,0x0, 0x2f,0x10,0xbe,0x18,0x0, 0x4a,0x50,0x5, 0x7e,0x18, +0x0, 0x4a,0x22,0x12,0x79,0xce,0xbf,0x10,0x28,0x2, 0x7f,0x10,0x22,0x7d,0x2f,0x9d, +0x23,0x7e,0x34,0x2, 0x52,0xad,0x23,0x7c,0x76,0x7c,0x65,0x1a,0x24,0x22,0x7d,0x14, +0x6d,0x0, 0x9e,0x8, 0x0, 0x4d,0x22,0x7d,0xed,0x9e,0xe4,0x0, 0xb, 0xbd,0xef,0x22, +0x74,0x9, 0xac,0xbf,0x59,0x35,0x29,0xa, 0x22,0xca,0xd8,0xca,0x79,0x7e,0x44,0x7, +0x80,0x6c,0xff,0x7e,0x70,0x9, 0xac,0x7f,0x9, 0xe3,0x29,0xc, 0x5e,0xe0,0xf, 0x49, +0xc3,0x29,0xa, 0x7d,0x24,0x2e,0x24,0x0, 0x14,0xbd,0xc2,0x40,0x3f,0x49,0xd3,0x29, +0x8, 0x7d,0x3d,0x12,0xa4,0xe5,0x7c,0xdb,0xbe,0xd0,0x3, 0x40,0xe, 0x7d,0x34,0x1b, +0x34,0x12,0x79,0xe0,0x7c,0xbe,0x12,0x7a,0x77,0x80,0x40,0x7e,0x70,0x2, 0xac,0x7d, +0x2e,0x34,0x60,0xc5,0x7e,0x24,0x0, 0xff,0xb, 0x1a,0xd0,0x74,0x9, 0xac,0xbf,0x59, +0xd5,0x29,0x8, 0x7e,0x34,0x7, 0xf8,0x12,0x79,0xe0,0x80,0x1f,0xbd,0xc4,0x40,0x1b, +0x7d,0x54,0x2e,0x54,0x0, 0xa, 0xbd,0xc5,0x40,0x5, 0x7c,0xbe,0x12,0x7a,0x77,0x7d, +0xc4,0x1b,0xc4,0x74,0x9, 0xac,0xbf,0x59,0xc5,0x29,0xa, 0xb, 0xf0,0xbe,0xf0,0xa, +0x40,0x81,0xda,0x79,0xda,0xd8,0x22,0x7c,0xab,0x7e,0x8, 0x29,0xbc,0xbe,0xa0,0xa, +0x50,0x1f,0xa, 0x3a,0x7f,0x70,0x2d,0xf3,0x7e,0x7b,0xb0,0xb4,0x2, 0x4, 0x74,0x1, +0x80,0x2, 0x74,0x3, 0x7a,0x7b,0xb0,0x74,0x3, 0x2d,0x31,0x7d,0x20,0x39,0xb1,0x0, +0xa, 0x22,0x7d,0xd3,0x7e,0x44,0x4, 0x38,0x7e,0xa3,0x2a,0x6f,0x74,0x40,0xa4,0x7d, +0xb5,0x1b,0xb4,0xbe,0xd4,0x0, 0x3f,0x38,0x1d,0x7e,0xe4,0x0, 0x3f,0x9d,0xed,0x7e, +0xf4,0x2, 0x36,0x12,0x7b,0x61,0x40,0x4, 0x7e,0x78,0x0, 0x44,0x7e,0x18,0x0, 0x44, +0x9f,0x17,0x7f,0x71,0x80,0x7f,0x7d,0x5b,0x9e,0x54,0x0, 0x3f,0xbd,0x5d,0x38,0x18, +0x7d,0xed,0x9d,0xe5,0x7e,0xf4,0x2, 0x4a,0x12,0x7b,0x61,0x40,0x4, 0x7e,0x78,0x0, +0x43,0x12,0x7b,0x58,0x2f,0x71,0x80,0x5d,0x7d,0xcb,0xb, 0xc4,0x1e,0xc4,0x7d,0x5c, +0x1b,0x54,0xbd,0x5d,0x40,0xc, 0x7d,0xf5,0x9d,0xfd,0x6d,0xee,0x7e,0x14,0x1, 0x39, +0x80,0xa, 0x7d,0xfd,0x9d,0xfc,0x6d,0xee,0x7e,0x14,0x1, 0x3b,0x7f,0x17,0x12,0x1e, +0xfc,0x7f,0x71,0x12,0x45,0xb1,0x7f,0x71,0xbd,0x5d,0x7d,0x34,0x40,0xc, 0x1e,0x34, +0x1b,0x34,0x6d,0x22,0x9f,0x17,0x7f,0x71,0x80,0x6, 0x1e,0x34,0x6d,0x22,0x2f,0x71, +0xbe,0x78,0x0, 0x44,0x50,0x6, 0x7e,0x78,0x0, 0x44,0x80,0x9, 0x12,0x7b,0x58,0xbf, +0x71,0x28,0x2, 0x7f,0x71,0x7d,0x3f,0x22,0x7d,0x34,0x9e,0x34,0x0, 0x44,0x6d,0x22, +0x22,0xad,0xfe,0x6d,0xee,0x7d,0x3f,0x7d,0x2e,0x7c,0x76,0x7c,0x65,0x7f,0x71,0xbe, +0x78,0x0, 0x44,0x22,0x7e,0xa3,0x2a,0x70,0x74,0x40,0xa4,0x22,0xca,0x3b,0x6d,0x0, +0x7e,0xe3,0x2a,0x2, 0x4c,0xee,0x78,0x20,0x6c,0xff,0x6d,0x11,0x74,0x2, 0xac,0xbf, +0x12,0x7d,0x46,0xac,0x3f,0x19,0xa1,0x34,0xe0,0x74,0x2, 0xa, 0x1f,0x19,0xb1,0x35, +0x4a,0xb, 0xf0,0xbe,0xf0,0xa, 0x78,0xe2,0x12,0x7d,0xb3,0x7e,0x24,0x0, 0x14,0xad, +0x32,0x7d,0x43,0x2e,0x44,0x3, 0x20,0x6c,0xff,0xa1,0x18,0x74,0x9, 0xac,0xbf,0x9, +0xd5,0x28,0xb2,0x5e,0xd0,0xf, 0xbe,0xd0,0xa, 0x40,0x2, 0xa1,0x16,0xa, 0x1d,0x9, +0xb1,0x29,0xbc,0xbe,0xb0,0x1, 0x78,0x2, 0x81,0xff,0x75,0x24,0x0, 0x7e,0x71,0x24, +0x74,0x9, 0xac,0x7b,0x9, 0xc3,0x34,0xe0,0xbc,0xcd,0x68,0x2, 0x81,0xf2,0x12,0x7b, +0x74,0x7d,0xf5,0x9e,0xf4,0x0, 0x20,0x2e,0xf4,0x0, 0x14,0x49,0x23,0x34,0xde,0xbd, +0x2f,0x28,0xe, 0x74,0x9, 0xac,0xbf,0x49,0x15,0x28,0xb0,0xbd,0x1f,0x38,0x2, 0x81, +0x9e,0x74,0x9, 0xac,0xbf,0x49,0x35,0x28,0xb0,0x9d,0x32,0x12,0x21,0xa, 0x7d,0x3, +0x7e,0xa1,0x24,0x74,0x9, 0xa4,0x49,0x25,0x34,0xdc,0x12,0x7d,0x51,0x9d,0x32,0x12, +0x21,0xa, 0x2d,0x3, 0xa, 0x1c,0x9, 0xa1,0x35,0x4a,0xbe,0xa0,0x0, 0x28,0x17,0x7e, +0x30,0x2, 0xac,0x3c,0x59,0x1, 0x35,0x36,0xa, 0x1c,0x2e,0x14,0x35,0x4a,0x7c,0xba, +0x14,0x7a,0x19,0xb0,0xa1,0x16,0x74,0x2, 0xac,0xbc,0x49,0x15,0x35,0x36,0xbe,0x14, +0x0, 0x32,0x28,0x8, 0x7d,0xe1,0x2d,0xe4,0xbd,0xe0,0x40,0x20,0xbe,0x14,0x0, 0x32, +0x28,0x8, 0xbe,0x4, 0x0, 0x32,0x28,0x2, 0x80,0x72,0x7d,0xe1,0x2e,0xe4,0x0, 0x32, +0xbd,0xe0,0x50,0x8, 0xbe,0x14,0x0, 0x32,0x28,0x2, 0x80,0x60,0xbe,0x4, 0x0, 0xa0, +0x28,0x56,0xa, 0x1d,0x9, 0xb1,0x29,0xbc,0x70,0x4, 0x74,0x3, 0x80,0x2, 0x74,0x1, +0xa, 0x1d,0x19,0xb1,0x29,0xbc,0x74,0x3, 0xa, 0x1c,0x19,0xb1,0x29,0xc6,0xbe,0xe0, +0x0, 0x28,0x63,0x1b,0xe0,0x7e,0x70,0x9, 0xac,0x7f,0x2e,0x34,0x28,0xae,0x7e,0x14, +0x1f,0x34,0x74,0x9, 0x12,0x1f,0x8c,0x7e,0x70,0x9, 0xac,0x7e,0x12,0x7f,0xa0,0xac, +0x3f,0x12,0x7d,0x3d,0x7e,0x34,0x1f,0x34,0x7e,0x30,0x9, 0xac,0x3e,0x12,0x7d,0x3d, +0x1b,0xf0,0x74,0x2, 0xac,0xbc,0x80,0x4, 0x74,0x2, 0xac,0xbc,0x59,0x5, 0x35,0x36, +0x80,0x24,0x5, 0x24,0xe5,0x24,0xbe,0xb0,0xa, 0x50,0x2, 0x61,0xdd,0x80,0x17,0x6d, +0x11,0x74,0x2, 0xac,0xbd,0x12,0x7d,0x46,0xac,0x3d,0x19,0xa1,0x34,0xe0,0x74,0x2, +0xa, 0x1d,0x19,0xb1,0x35,0x4a,0xb, 0xf0,0xbc,0xef,0x28,0x2, 0x61,0xbb,0xe4,0x7a, +0xb3,0x16,0x92,0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x28,0xae,0x7e,0x8, 0x34, +0xdc,0x12,0x20,0xc3,0x1b,0xfd,0x7a,0xe3,0x2a,0x2, 0xda,0x3b,0x22,0x2e,0x14,0x28, +0xae,0x74,0x9, 0x2, 0x1f,0x8c,0x59,0x15,0x35,0x36,0x7e,0xa0,0xff,0x7e,0x30,0x9, +0x22,0x74,0x9, 0xac,0xbf,0x49,0x35,0x28,0xae,0x22,0x7e,0xb3,0x38,0x32,0x70,0x3, +0x12,0x7b,0x7c,0x2, 0x7d,0x66,0xca,0x79,0x7e,0xf3,0x2a,0x2, 0x7e,0xe3,0x2a,0x3, +0x7c,0xbf,0x7c,0x7e,0x12,0x7e,0x9f,0x7c,0xbf,0x12,0x9e,0x59,0x4c,0xee,0x78,0x15, +0x7e,0x34,0x0, 0x5a,0xca,0x39,0x7e,0x18,0x28,0xae,0x7e,0x8, 0x29,0x62,0x12,0x20, +0xc3,0x1b,0xfd,0x80,0xb, 0x7e,0xb3,0x2a,0x9, 0x70,0x5, 0x7c,0xbf,0x12,0x7f,0x12, +0x7c,0xbf,0x12,0x7d,0xeb,0xbe,0xf0,0x0, 0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x2a,0xb, +0xda,0x79,0x22,0x7e,0x73,0x2a,0x3, 0xbe,0x73,0x2a,0x2, 0x78,0x13,0x12,0x7f,0x98, +0x40,0xe, 0x7e,0x37,0x34,0xb4,0xbe,0x34,0x0, 0x14,0x38,0xe, 0xb, 0x34,0x80,0x6, +0x7e,0x37,0x34,0xb4,0x1e,0x34,0x7a,0x37,0x34,0xb4,0x7e,0xb3,0x2a,0x2, 0x70,0x6, +0x6d,0x33,0x7a,0x37,0x34,0xb4,0x7e,0x37,0x34,0xb4,0x22,0x6c,0xaa,0x7e,0x50,0x9, +0xac,0x5a,0x49,0x32,0x29,0x62,0x12,0x7e,0x3c,0x59,0x32,0x28,0xae,0x7e,0x50,0x9, +0xac,0x5a,0x49,0x32,0x29,0x64,0x12,0x7e,0x3c,0x59,0x32,0x28,0xb0,0x7e,0x90,0x9, +0xac,0x9a,0x9, 0xb4,0x29,0x66,0x19,0xb4,0x28,0xb2,0x7e,0x90,0x9, 0xac,0x9a,0x9, +0xb4,0x29,0x67,0x19,0xb4,0x28,0xb3,0x7e,0x90,0x9, 0xac,0x9a,0x9, 0xb4,0x29,0x68, +0x19,0xb4,0x28,0xb4,0xb, 0xa0,0xbe,0xa0,0xa, 0x40,0xb2,0x22,0x1e,0x34,0x1e,0x34, +0x1e,0x34,0x1e,0x34,0x22,0x7f,0x71,0x69,0x37,0x0, 0x2, 0x7d,0x53,0x12,0x7f,0x90, +0xb, 0x7a,0x20,0x2d,0x25,0x1b,0xa, 0x20,0x69,0x27,0x0, 0x4, 0x7d,0x52,0xc4,0x54, +0xf0,0x7c,0xab,0xe4,0x1e,0x34,0x1e,0x34,0x2d,0x35,0x79,0x30,0x0, 0x2, 0x69,0x37, +0x0, 0x6, 0x7d,0x53,0x7c,0xab,0xe4,0x3e,0x54,0x3e,0x54,0x1e,0x24,0x1e,0x24,0x1e, +0x24,0x1e,0x24,0x2d,0x25,0x79,0x20,0x0, 0x4, 0x69,0x27,0x0, 0x8, 0x7c,0x45,0x6c, +0x55,0x12,0x7e,0x3c,0x1e,0x34,0x1e,0x34,0x2d,0x32,0x79,0x30,0x0, 0x6, 0x22,0x7c, +0x67,0x7c,0x7b,0xa5,0xbf,0x0, 0x17,0xbe,0x60,0x0, 0x28,0xf, 0x74,0x1, 0x7a,0xb3, +0x2a,0x7, 0xe4,0x7a,0xb3,0x2a,0x9, 0x7a,0xb3,0x2a,0xa, 0x2, 0x7f,0xb5,0xa5,0xbe, +0x0, 0x1b,0x6c,0xaa,0x7e,0x60,0xff,0x7e,0x50,0x9, 0xac,0x5a,0x19,0x62,0x29,0x66, +0xb, 0xa0,0xbe,0xa0,0xa, 0x78,0xf0,0x74,0x1, 0x7a,0xb3,0x2a,0x6, 0x6c,0xaa,0x80, +0x20,0x7e,0x30,0x9, 0xac,0x3a,0x2e,0x14,0x28,0xae,0x12,0x7f,0x6, 0x1b,0x18,0x20, +0x7e,0x30,0x9, 0xac,0x3a,0x2e,0x14,0x28,0xb0,0x12,0x7f,0x6, 0x1b,0x18,0x20,0xb, +0xa0,0xbc,0x7a,0x38,0xdc,0x22,0xb, 0x18,0x20,0x3e,0x24,0x3e,0x24,0x3e,0x24,0x3e, +0x24,0x22,0xca,0x3b,0x7c,0xfb,0x6c,0xee,0x80,0x6c,0x6c,0xdd,0x74,0x9, 0xac,0xbd, +0x9, 0x45,0x29,0x66,0x7e,0x70,0x9, 0xac,0x7e,0x9, 0x53,0x28,0xb2,0xbc,0x45,0x68, +0x7, 0xb, 0xd0,0xbe,0xd0,0xa, 0x40,0xe4,0xbe,0xd0,0xa, 0x50,0x4d,0x74,0x9, 0xac, +0xbd,0x9, 0xc5,0x29,0x66,0x49,0x25,0x29,0x64,0x49,0x33,0x28,0xb0,0x12,0x4f,0xcc, +0x74,0x9, 0xac,0xbd,0x12,0x7f,0xa8,0x9d,0x32,0x12,0x21,0xa, 0x2d,0x31,0x7a,0x35, +0x24,0xa, 0x3c,0x9, 0xb3,0x29,0xbc,0xb4,0x1, 0xe, 0x6d,0x33,0x74,0x2, 0xac,0xbc, +0x59,0x35,0x34,0xa0,0x59,0x35,0x34,0xc6,0x7e,0x35,0x24,0x7c,0xbd,0x7c,0x5e,0x7c, +0x4c,0x12,0x7f,0x8d,0xb, 0xe0,0xbc,0xfe,0x38,0x90,0xda,0x3b,0x22,0x2, 0x47,0x36, +0x3, 0x3, 0x54,0xc0,0x7c,0xab,0xe4,0x22,0x7e,0x73,0x2a,0x2, 0xbe,0x70,0x1, 0x22, +0x2e,0x34,0x28,0xae,0x7e,0x30,0x9, 0x22,0x49,0x25,0x29,0x62,0x74,0x9, 0xac,0xbe, +0x49,0x35,0x28,0xae,0x22,0x7e,0x8, 0x34,0xc6,0x7e,0x34,0x0, 0x14,0xe4,0x12,0x20, +0xe8,0x7e,0x8, 0x34,0xa0,0x7e,0x34,0x0, 0x14,0x2, 0x20,0xe8,0x7e,0xb3,0x2a,0x9, +0x70,0x23,0x7e,0xb3,0x34,0xb7,0xb4,0x2, 0x9, 0x12,0x7f,0x98,0x28,0x4, 0x74,0x3, +0x80,0x1, 0xe4,0x7a,0xb3,0x34,0xc2,0x7e,0x73,0x34,0xc3,0xbe,0x73,0x34,0xc2,0x28, +0x4, 0x7a,0x73,0x34,0xc2,0x22,0x12,0xa0,0x50,0x2, 0x7f,0xcc,0x7e,0xb3,0x2a,0x3, +0xb4,0x1, 0x22,0x7e,0xb3,0x28,0x84,0xb4,0x1, 0x1b,0x7e,0xb3,0x28,0xa8,0x70,0x15, +0x7e,0xb3,0x26,0x83,0xb4,0x1, 0xe, 0x7e,0xb3,0x28,0x85,0x70,0x8, 0x7e,0xb3,0x2a, +0x68,0x70,0x2, 0xd3,0x22,0xc3,0x22,0x7d,0x13,0x7d,0x32,0x6d,0x22,0x74,0x6, 0x2f, +0x11,0x14,0x78,0xfb,0xb, 0x14,0x12,0x1f,0x5, 0x7d,0x53,0xbe,0x54,0x0, 0xff,0x28, +0x4, 0x7e,0x54,0x0, 0x40,0x22,0xca,0xf8,0x7e,0xf3,0x2a,0x70,0x7a,0x37,0x1f,0x3a, +0x7e,0x34,0x15,0x9e,0x7a,0x37,0x1f,0x3c,0xe4,0x7a,0xb3,0x1f,0x34,0x7a,0xb3,0x1f, +0x35,0x7e,0x73,0x2a,0x6f,0x7a,0x73,0x1f,0x36,0x7a,0xf3,0x1f,0x37,0x7a,0xb3,0x1f, +0x38,0x7a,0xb3,0x1f,0x39,0x7e,0x8, 0x1f,0x34,0x12,0x80,0x9b,0x6d,0x22,0x7d,0x3, +0x6d,0x11,0x7e,0x37,0x15,0xa0,0x2f,0x10,0x7e,0x33,0x1f,0x36,0x6d,0x0, 0x12,0x1f, +0x7, 0xa, 0x1f,0x6d,0x0, 0x12,0x1f,0x7, 0xda,0xf8,0x22,0x12,0xc, 0x29,0x7e,0x37, +0x15,0x9e,0x22,0xca,0x3b,0x7c,0xc4,0x7c,0xf6,0x7c,0xe7,0x7c,0xdb,0x74,0x9, 0xac, +0xb5,0x7d,0x95,0x2e,0x94,0x27,0x76,0x6d,0x88,0x7e,0xe7,0x2a,0x66,0xe4,0x39,0xb4, +0x0, 0x6, 0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xb3,0x26,0xfa,0xf5,0x35,0x9, 0xb3,0x26, +0xfb,0xf5,0x36,0x7e,0x73,0x2a,0x6e,0x7c,0x6e,0x7e,0x8, 0x0, 0x39,0x12,0x82,0xe6, +0xf5,0x37,0xe5,0x35,0x7e,0x73,0x2a,0x6d,0x7c,0x6d,0x7e,0x8, 0x0, 0x38,0x12,0x82, +0xe6,0x7c,0xab,0xe5,0x38,0x7e,0x71,0x39,0x12,0x6f,0x81,0x7d,0xf3,0x7a,0xf5,0x41, +0x7e,0xf4,0x15,0x9e,0x7a,0xf5,0x43,0x85,0x38,0x3b,0x85,0x39,0x3c,0x7a,0xa1,0x3d, +0x85,0x37,0x3e,0x7e,0xb3,0x2a,0x59,0xf5,0x3f,0x75,0x40,0x0, 0xbe,0xc0,0x1, 0x78, +0x8, 0xe5,0x3f,0x1e,0xb0,0x1e,0xb0,0xf5,0x3f,0x7e,0x8, 0x0, 0x3b,0x12,0x80,0x9b, +0x7d,0x23,0x6d,0x33,0x7e,0xb7,0x15,0xa0,0x6d,0xaa,0x2f,0x51,0x7e,0x37,0x15,0xa2, +0x6d,0x22,0x7d,0x3, 0x6d,0x11,0x7e,0x37,0x15,0xa4,0x2f,0x10,0x7a,0x1d,0x2c,0x7e, +0x37,0x15,0xa6,0x6d,0x22,0x7d,0x3, 0x7e,0x37,0x15,0xa8,0x2f,0x10,0x7a,0x1d,0x30, +0x7f,0x65,0xa, 0x3d,0xe5,0x35,0xa, 0xfb,0x9d,0xf3,0x7d,0x3f,0x7c,0xc7,0x41,0x48, +0xa, 0x4e,0xe5,0x36,0xa, 0x5b,0x9d,0x54,0xf5,0x34,0x41,0x32,0xbe,0xc0,0x0, 0x58, +0x2, 0x41,0x30,0x7e,0x73,0x2a,0x6d,0xbc,0x7c,0x18,0x2, 0x41,0x30,0xe5,0x34,0xbe, +0xb0,0x0, 0x58,0x2, 0x41,0x30,0x7e,0x73,0x2a,0x6e,0xbe,0x71,0x34,0x18,0x2, 0x41, +0x30,0x7c,0xbc,0x7e,0x71,0x34,0x12,0x6d,0xcb,0x7e,0x53,0x2a,0x59,0xa, 0x25,0x7d, +0xf3,0x9d,0xf2,0xbe,0xf4,0x0, 0x0, 0x8, 0x77,0xbd,0xef,0x18,0xd, 0x7f,0x14,0x2e, +0x34,0x0, 0x6, 0x7e,0x1b,0xb0,0x4, 0x7a,0x1b,0xb0,0xe5,0x35,0xa, 0x2b,0x1a,0x3c, +0x12,0x82,0xcd,0x18,0xd, 0xe5,0x36,0xa, 0x2b,0xe5,0x34,0x1a,0x3b,0x12,0x82,0xcd, +0x8, 0x4e,0x7c,0xbc,0x7e,0x71,0x34,0x7c,0x6f,0x12,0x83,0x39,0xf5,0x3a,0xb4,0x2, +0x6, 0x7d,0x3f,0xe, 0x34,0x9d,0xf3,0xe5,0x3a,0xbe,0xb0,0x2, 0x68,0x5, 0xe5,0x3a, +0xb4,0x1, 0x2d,0x12,0x82,0xbe,0x1a,0x1c,0x12,0x82,0xc5,0x7e,0x1d,0x2c,0x9f,0x10, +0x7a,0x1d,0x2c,0x12,0x82,0xbe,0xe5,0x34,0x1a,0x1b,0x12,0x82,0xc5,0x7e,0x1d,0x30, +0x9f,0x10,0x7a,0x1d,0x30,0x12,0x82,0xbe,0x9f,0x51,0x1a,0x26,0x1a,0x24,0x9f,0x61, +0x5, 0x34,0xa, 0x2e,0xe5,0x36,0xa, 0x3b,0x2d,0x32,0x1a,0x27,0xe5,0x34,0x1a,0x3b, +0xbd,0x32,0x18,0x2, 0x21,0x7c,0xb, 0xc0,0xa, 0x2d,0xe5,0x35,0xa, 0x3b,0x2d,0x32, +0x1a,0x37,0x1a,0xfc,0xbd,0xf3,0x18,0x2, 0x21,0x70,0xbe,0x58,0x0, 0x0, 0x78,0x2, +0xb, 0x5c,0xbe,0x68,0x0, 0x0, 0x78,0x2, 0xb, 0x6c,0x7e,0x1d,0x2c,0x7f,0x5, 0x12, +0x82,0xd7,0x1b,0x4a,0x30,0x7e,0x1d,0x30,0x7f,0x6, 0x12,0x82,0xd7,0x79,0x34,0x0, +0x2, 0x7e,0xb3,0x2a,0x65,0x60,0xd, 0x1e,0xd4,0x1e,0xc4,0x50,0x4, 0x4e,0xd4,0x80, +0x0, 0x14,0x78,0xf3,0xbe,0x68,0x0, 0x7f,0x28,0x4, 0x7e,0x68,0x0, 0x7f,0x7d,0x3d, +0x39,0x74,0x0, 0x5, 0x74,0x9, 0xac,0xbf,0x9, 0x75,0x27,0x7c,0x39,0x74,0x0, 0x6, +0xbe,0x70,0xf, 0x28,0x6, 0x74,0xf, 0x39,0xb4,0x0, 0x6, 0xda,0x3b,0x22,0x7d,0x3f, +0x1a,0x26,0x1a,0x24,0x22,0x1a,0x2, 0x12,0x1e,0xeb,0x7f,0x1, 0x22,0x9d,0x32,0x12, +0x21,0xa, 0xbe,0x34,0x0, 0x1, 0x22,0x74,0x6, 0x2f,0x11,0x14,0x78,0xfb,0x12,0x1f, +0x7, 0x2e,0x18,0x0, 0x20,0x22,0xca,0xf8,0x7c,0xf6,0x7c,0x87,0x7c,0x9b,0xa, 0x2f, +0x7d,0x32,0x3e,0x34,0xb, 0x34,0x7c,0xb7,0xbc,0xf9,0x38,0x14,0xa, 0xf8,0x1b,0xf4, +0xa, 0x3f,0x9d,0xf3,0xa, 0x39,0xbd,0x3f,0x18,0x6, 0x7c,0xab,0xa, 0x39,0x80,0x1d, +0xbc,0xf9,0x28,0xd, 0xa, 0x39,0xa, 0x5f,0x2d,0x53,0xb, 0x54,0x7c,0xab,0xe4,0x80, +0x10,0xa, 0x3f,0xa, 0x58,0x2d,0x53,0xa, 0x39,0x9d,0x53,0x7c,0xab,0x9d,0x32,0x7c, +0xb7,0x7a,0xb, 0xb0,0x7c,0xba,0xda,0xf8,0x22,0x7c,0xa6,0x7c,0x37,0x7c,0x2b,0xe4, +0x6c,0x11,0x80,0x46,0xbc,0xa1,0x68,0x40,0x1a,0x41,0x3e,0x44,0x9, 0x4, 0x26,0xfb, +0xa, 0x20,0xa, 0x33,0x9d,0x32,0x12,0x21,0xa, 0x7c,0x7, 0x1a,0x41,0x3e,0x44,0x9, +0x74,0x26,0xfa,0xa, 0x27,0xa, 0x32,0x9d,0x32,0x12,0x21,0xa, 0x7c,0x97,0xbe,0x90, +0x1, 0x18,0x8, 0xbe,0x0, 0x1, 0x18,0x3, 0x74,0x1, 0x22,0xbe,0x90,0x2, 0x18,0x8, +0xbe,0x0, 0x2, 0x18,0x3, 0x74,0x2, 0x22,0xb, 0x10,0x7e,0x83,0x28,0x84,0xbc,0x81, +0x18,0xb2,0x22,0x7a,0x37,0x1f,0x38,0x7e,0x34,0x15,0xa8,0x7a,0x37,0x1f,0x3c,0x7e, +0x34,0x15,0x9e,0x7a,0x37,0x1f,0x3a,0x7e,0x73,0x2a,0x6f,0x7a,0x73,0x1f,0x35,0x7e, +0x73,0x2a,0x70,0x7a,0x73,0x1f,0x34,0x7e,0x37,0x2a,0x5c,0x7a,0x37,0x1f,0x3e,0x7e, +0x37,0x2a,0x5e,0x7a,0x37,0x1f,0x40,0x7e,0x37,0x2a,0x60,0x7a,0x37,0x1f,0x42,0x74, +0x1, 0x7a,0xb3,0x1f,0x36,0x7a,0xb3,0x1f,0x37,0x7e,0x8, 0x1f,0x34,0x7e,0x18,0x1f, +0x44,0x12,0x8, 0x0, 0x7e,0x37,0x1f,0x4e,0x7e,0x27,0x1f,0x4a,0xbd,0x23,0x28,0x2, +0x7d,0x32,0x22,0xca,0x3b,0x7e,0x8, 0x1f,0x34,0x12,0x3f,0xf2,0x7e,0x1f,0x39,0xf4, +0x7a,0x1d,0x27,0x7e,0xb3,0x2a,0x74,0xf5,0x2e,0x7e,0xb3,0x39,0x87,0xb4,0x1, 0x6, +0x7e,0x38,0x39,0x89,0x80,0x4, 0x7e,0x38,0x5, 0xf8,0x6d,0x33,0x7a,0x35,0x2b,0x74, +0x2, 0x12,0x0, 0x1e,0x7e,0xb3,0x39,0x88,0x70,0xe, 0x7e,0xb3,0x39,0x86,0x70,0x8, +0x74,0x1, 0x7a,0xb3,0x39,0x88,0x81,0xb8,0x7e,0xb3,0x39,0x88,0x70,0x6, 0x74,0x1, +0x7a,0xb3,0x39,0x88,0x7e,0xb3,0x39,0x87,0xb4,0x1, 0x14,0x75,0x2d,0x0, 0x80,0x6, +0x12,0x84,0xfa,0x12,0x85,0x8, 0xe5,0x2e,0xbe,0xb1,0x2d,0x38,0xf3,0x80,0x18,0x75, +0x2d,0x0, 0x80,0xc, 0x12,0x84,0xfa,0x3e,0x24,0x3e,0x24,0x1e,0x24,0x12,0x85,0x8, +0xe5,0x2e,0xbe,0xb1,0x2d,0x38,0xed,0x7e,0x34,0x0, 0xfa,0x7a,0x35,0x2f,0x7e,0x18, +0x1f,0x34,0x7f,0x1, 0x12,0x85,0x19,0x75,0x2d,0x0, 0x80,0x10,0x12,0x84,0xed,0xbe, +0x35,0x2b,0x8, 0x6, 0x12,0x84,0xed,0x7a,0x35,0x2b,0x5, 0x2d,0xe5,0x2e,0xbe,0xb1, +0x2d,0x38,0xe9,0x12,0x84,0xe5,0x40,0x25,0x7e,0xb3,0x39,0x87,0xb4,0x1, 0x1e,0x5, +0x1e,0xe5,0x1e,0xbe,0xb0,0xa, 0x40,0x15,0x75,0x1e,0x0, 0xe5,0x2e,0xa, 0x3b,0x3e, +0x34,0xca,0x39,0x7e,0x1d,0x27,0x7f,0x3, 0x12,0x20,0xc3,0x1b,0xfd,0x74,0x2, 0x12, +0x0, 0x1e,0x12,0x84,0xe5,0x50,0xb, 0x74,0x2, 0x7a,0xb3,0x39,0xf3,0xe4,0x7a,0xb3, +0x39,0x88,0xda,0x3b,0x22,0x7e,0x37,0x2b,0x7, 0xbe,0x35,0x2b,0x22,0x7e,0xa1,0x2d, +0x74,0x2, 0xa4,0x49,0x35,0x1f,0x34,0x2, 0x21,0xa, 0x7e,0xa1,0x2d,0x74,0x2, 0xa4, +0x7f,0x13,0x2d,0x35,0xb, 0x1a,0x20,0x22,0x7e,0xd, 0x27,0x2d,0x15,0xb, 0xa, 0x30, +0x9d,0x32,0x59,0x35,0x1f,0x34,0x5, 0x2d,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e, +0x73,0x2a,0x6e,0xa, 0x37,0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x20,0xc3, +0x1b,0xfd,0x6c,0xdd,0x12,0x87,0xb8,0x7a,0xb3,0x1f,0x6c,0x6c,0xcc,0x80,0x45,0x12, +0x85,0xbf,0x78,0x3e,0x12,0x87,0xc0,0xb, 0x1a,0xe0,0x7d,0x3f,0x12,0x21,0xa, 0x7d, +0x13,0x7d,0x3e,0x12,0x21,0xa, 0xbd,0x31,0x58,0x2, 0x7d,0xfe,0xbe,0xe5,0x2f,0x8, +0x5, 0x7e,0xe5,0x2f,0x80,0xb, 0x6d,0x33,0x9e,0x35,0x2f,0xbd,0x3e,0x8, 0x2, 0x7d, +0xe3,0x7d,0x3e,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x1f,0x6c,0x4, 0x7a,0xb3, +0x1f,0x6c,0xb, 0xc0,0x7e,0x73,0x2a,0x70,0xbc,0x7c,0x38,0xb3,0x7e,0x73,0x1f,0x6c, +0x4c,0x77,0x68,0x1f,0x12,0x87,0xc9,0xbd,0x3e,0x8, 0x2, 0x7d,0x7f,0x6c,0xcc,0x80, +0xa, 0x12,0x85,0xbf,0x78,0x3, 0x12,0x87,0xde,0xb, 0xc0,0x7e,0x73,0x2a,0x70,0xbc, +0x7c,0x38,0xee,0xb, 0xd0,0xbe,0xd0,0x2, 0x50,0x2, 0xa1,0x34,0xda,0x3b,0x22,0xa, +0xec,0x9, 0x7e,0x2a,0xdc,0xa, 0x37,0x5e,0x34,0x0, 0x1, 0xa, 0xed,0xbd,0x3e,0x22, +0xca,0x3b,0x7f,0x31,0x7a,0xd, 0x24,0x7e,0x35,0x28,0x7a,0x35,0x2f,0x7e,0xd, 0x24, +0x7f,0x13,0x12,0x85,0x19,0x7e,0x35,0x28,0x7a,0x35,0x2a,0x12,0x86,0x3f,0x7e,0xd, +0x24,0x2d,0x15,0x7f,0x13,0x2d,0x35,0x12,0xa2,0x54,0xda,0x3b,0x22,0x7e,0x37,0x2a, +0x4f,0x1e,0x34,0x7a,0x35,0x28,0x7e,0x8, 0x4, 0xfc,0x7e,0x18,0x4, 0x0, 0x12,0x85, +0xd0,0x7e,0x37,0x28,0x99,0xe, 0x34,0x7a,0x35,0x28,0x7e,0x8, 0x5, 0x7a,0x7e,0x18, +0x4, 0x7e,0x12,0x85,0xd0,0x12,0xa4,0xb9,0x12,0xa3,0xb3,0x2, 0x86,0x2e,0xe4,0x7a, +0xb3,0x3, 0xfe,0x7e,0xb3,0x28,0xa8,0x60,0x5, 0xe4,0x7a,0xb3,0x3, 0xfe,0x22,0x7e, +0xa3,0x2a,0x74,0x74,0x2, 0xa4,0x22,0xca,0x3b,0x7e,0x44,0x7f,0xff,0x7d,0x14,0x7d, +0x4, 0x6d,0x22,0x7d,0x32,0x7d,0xb4,0x6c,0xee,0x6c,0xff,0x7e,0x68,0x4, 0xfc,0x7e, +0x78,0x5, 0x7a,0xe4,0x7a,0xb3,0x8, 0x8, 0x7a,0xb3,0x8, 0x9, 0x7a,0xb3,0x26,0xf6, +0x7a,0xb3,0x26,0xf8,0x7a,0xb3,0x26,0xf7,0x7a,0xb3,0x26,0xf9,0x6c,0xaa,0x80,0x5c, +0x12,0x87,0x9e,0xbd,0xa1,0x58,0x2, 0x7d,0x1a,0xbd,0xa3,0x8, 0x2, 0x7d,0x3a,0x7e, +0xd0,0x2, 0xac,0xda,0x7f,0x47,0x2d,0x96,0xb, 0x4a,0xa0,0xbd,0xab,0x58,0x2, 0x7d, +0xba,0x12,0x87,0x9e,0x7e,0x87,0x2a,0x53,0x7e,0x94,0x0, 0x3, 0xad,0x98,0xbd,0xa9, +0x8, 0x2, 0xb, 0xe0,0x12,0x87,0x9e,0xbe,0xa4,0x0, 0x64,0x8, 0xb, 0x7e,0xb3,0x26, +0xf7,0x4, 0x7a,0xb3,0x26,0xf7,0x80,0x12,0x12,0x87,0x9e,0xbe,0xa4,0xff,0x9c,0x58, +0x9, 0x7e,0xb3,0x26,0xf9,0x4, 0x7a,0xb3,0x26,0xf9,0xb, 0xa0,0x7e,0xb3,0x2a,0x74, +0xbc,0xba,0x38,0x9c,0x7a,0x17,0x7, 0xfe,0x7a,0x37,0x8, 0x2, 0x7a,0xe3,0x8, 0x9, +0x7a,0xb7,0x8, 0x6, 0x12,0x86,0x3f,0x2d,0xd5,0x6c,0xaa,0x80,0x53,0x12,0x87,0xab, +0xbd,0xb0,0x58,0x2, 0x7d,0xb, 0xbd,0xb2,0x8, 0x2, 0x7d,0x2b,0x7e,0xd0,0x2, 0xac, +0xda,0x7f,0x56,0x2d,0xb6,0xb, 0x5a,0x90,0x7e,0xa7,0x2a,0x51,0x7e,0xb4,0x0, 0x3, +0xad,0xba,0xbd,0x9b,0x8, 0x2, 0xb, 0xf0,0x12,0x87,0xab,0xbe,0xb4,0x0, 0x64,0x8, +0xb, 0x7e,0xb3,0x26,0xf6,0x4, 0x7a,0xb3,0x26,0xf6,0x80,0x12,0x12,0x87,0xab,0xbe, +0xb4,0xff,0x9c,0x58,0x9, 0x7e,0xb3,0x26,0xf8,0x4, 0x7a,0xb3,0x26,0xf8,0xb, 0xa0, +0x12,0x5f,0xf8,0x38,0xa8,0x7a,0x7, 0x7, 0xfc,0x7a,0x27,0x8, 0x0, 0x7a,0xf3,0x8, +0x8, 0x12,0x86,0x3f,0x2d,0xf5,0x6c,0xaa,0x80,0x14,0x7e,0xf0,0x2, 0xac,0xfa,0x7f, +0x67,0x2d,0xd7,0xb, 0x6a,0xd0,0xbd,0xd4,0x58,0x2, 0x7d,0x4d,0xb, 0xa0,0x12,0x5f, +0xf8,0x38,0xe7,0x7a,0x47,0x8, 0x4, 0xbd,0x1, 0x58,0x2, 0x7d,0x10,0x7a,0x17,0x7, +0xf8,0xbd,0x32,0x58,0x2, 0x7d,0x32,0x7a,0x37,0x7, 0xfa,0xda,0x3b,0x22,0x7e,0xd0, +0x2, 0xac,0xda,0x7f,0x46,0x2d,0x96,0xb, 0x4a,0xa0,0x22,0x7e,0xd0,0x2, 0xac,0xda, +0x7f,0x56,0x2d,0xb6,0xb, 0x5a,0xb0,0x22,0x7e,0xf4,0x7f,0xff,0x9f,0x44,0xe4,0x22, +0x74,0x2, 0xac,0xbc,0x7f,0x16,0x2d,0x35,0x22,0xa, 0x17,0x6d,0x0, 0x7f,0x14,0x12, +0x1f,0x58,0x7d,0x73,0x12,0x21,0xa, 0x7d,0xe3,0x7d,0x3f,0x2, 0x21,0xa, 0x74,0x2, +0xac,0xbc,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0xe0,0x9d,0xe7,0x7f,0x15,0x2d,0x35,0x1b, +0x1a,0xe0,0x22,0x7e,0x24,0x0, 0x7d,0x12,0x90,0xd, 0x50,0x8, 0x7e,0x27,0x2a,0x4f, +0x1e,0x24,0x1e,0x24,0x7d,0x32,0x22,0x7e,0xb3,0x38,0x7, 0x70,0x2e,0x7e,0x73,0x37, +0xea,0xbe,0x70,0x10,0x40,0x2, 0x6c,0x77,0x7e,0xb3,0x38,0x32,0xb4,0x1, 0x3, 0x7e, +0x70,0x6, 0xa, 0x37,0x2e,0x34,0xf, 0xf0,0x12,0x88,0x5c,0x7c,0xab,0xe5,0x5e,0xa, +0x3b,0x2e,0x37,0x39,0x84,0x7a,0x37,0x39,0x84,0x80,0xc, 0x7e,0xa3,0x37,0xeb,0xbe, +0xa0,0x7f,0x28,0x3, 0x7e,0xa0,0x7f,0x7c,0xba,0x2, 0x88,0x4c,0x75,0x5e,0x0, 0x7a, +0xb3,0x3a,0x7, 0xc2,0x1c,0x22,0x2d,0x32,0x2e,0x34,0x20,0xfa,0x7a,0x71,0x82,0x7a, +0x61,0x83,0xe4,0x93,0x22,0x7c,0x7b,0x12,0x89,0x30,0x9, 0xa2,0x27,0x72,0x7c,0xb7, +0x54,0x7, 0xa, 0x3b,0x2e,0x34,0x0, 0x5e,0x12,0x88,0x5c,0x5c,0xba,0x22,0x6c,0x0, +0x6c,0x11,0x80,0x13,0x7c,0xb1,0x12,0x88,0x65,0x60,0xa, 0x12,0x88,0xd8,0x40,0x5, +0x7e,0x0, 0x1, 0x80,0xa, 0xb, 0x10,0x7e,0x73,0x28,0x84,0xbc,0x71,0x38,0xe5,0x7c, +0xb0,0x6c,0x77,0x12,0x88,0xf1,0xbe,0x0, 0x1, 0x68,0xb, 0x7c,0xb0,0x7e,0x70,0x1, +0x12,0x88,0xf1,0xb4,0x1, 0x21,0x6c,0x11,0x80,0x15,0x7c,0xb1,0x12,0x88,0x65,0x60, +0xc, 0x12,0x88,0xd8,0x50,0x7, 0x7c,0xb1,0x6c,0x77,0x12,0x73,0x2e,0xb, 0x10,0x7e, +0x3, 0x28,0x84,0xbc,0x1, 0x38,0xe3,0x22,0x74,0x2, 0xac,0xb1,0x9, 0x25,0x26,0xfa, +0x9, 0x35,0x26,0xfb,0x7c,0xb2,0x7c,0x73,0x7c,0xb7,0xb4,0x18,0x2, 0xd3,0x22,0xc3, +0x22,0x7c,0xab,0xa5,0xbf,0x0, 0xc, 0x7e,0xb3,0x37,0x61,0x7a,0xb3,0x37,0x62,0x7a, +0xa3,0x37,0x61,0x7e,0xb3,0x37,0x62,0x60,0x4, 0x74,0x8, 0x80,0xd, 0x7e,0xb3,0x28, +0x84,0x70,0xb, 0x7e,0xb3,0x37,0x63,0x60,0x5, 0x14,0x7a,0xb3,0x37,0x63,0x7e,0x73, +0x37,0x63,0xbe,0x70,0x0, 0x28,0x3, 0x74,0x1, 0x22,0xe4,0x22,0x7c,0xa5,0x7c,0xb7, +0xc4,0x23,0x54,0x1f,0xa, 0x2b,0x22,0x7e,0x8, 0x26,0x86,0x7e,0x34,0x0, 0x3, 0xe4, +0x12,0x20,0xe8,0x7e,0x8, 0x26,0x89,0x12,0x8f,0xc7,0x7a,0xb3,0x26,0x83,0x7a,0xb3, +0x26,0x84,0x7a,0xb3,0x26,0x85,0x7a,0xb3,0x26,0xf0,0x7a,0xb3,0x26,0xf1,0x7a,0xb3, +0x26,0xf2,0x7e,0x18,0x26,0x6f,0x12,0x8a,0x92,0x6c,0x55,0x12,0x89,0xf9,0x7a,0xb3, +0x26,0x85,0x7e,0x18,0x26,0x5b,0x12,0x8a,0xa2,0x6c,0x55,0x12,0x89,0xf9,0x7a,0xb3, +0x26,0x84,0x6c,0x77,0x80,0x14,0x12,0x8a,0x7e,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb, +0x12,0x89,0x2c,0x2e,0x24,0x26,0x86,0x12,0x8a,0x87,0x7e,0x63,0x26,0x84,0xbc,0x67, +0x38,0xe4,0x6c,0x77,0x80,0x14,0x12,0x8a,0x7e,0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb, +0x12,0x89,0x2c,0x2e,0x24,0x26,0x89,0x12,0x8a,0x87,0x7e,0xa3,0x26,0x85,0xbc,0xa7, +0x38,0xe4,0x7e,0xb3,0x26,0x84,0xa4,0x7a,0xb3,0x26,0x83,0x7e,0x18,0x26,0xe6,0x12, +0x8a,0x92,0x7e,0x50,0x1, 0x12,0x89,0xf9,0x7a,0xb3,0x26,0xf2,0x7e,0x18,0x26,0xdc, +0x12,0x8a,0xa2,0x7e,0x50,0x1, 0x12,0x89,0xf9,0x7c,0xab,0x7a,0xa3,0x26,0xf1,0x7e, +0xb3,0x26,0xf2,0xa4,0x7a,0xb3,0x26,0xf0,0x22,0xca,0x69,0xca,0xf8,0x7c,0x4b,0x6c, +0xaa,0x6d,0xff,0x6c,0xff,0x80,0x6c,0x7e,0xd0,0x2, 0xac,0xdf,0x7f,0x60,0x2d,0xd6, +0xb, 0x6a,0xe0,0x4c,0x55,0x68,0x6, 0x6e,0xe4,0xff,0xff,0xb, 0xe4,0xbd,0x3e,0x58, +0x50,0x4c,0xff,0x78,0x8, 0x6d,0x44,0x69,0xf0,0x0, 0x2, 0x80,0x1b,0x7c,0xb4,0x14, +0xbc,0xbf,0x7f,0x56,0x78,0x9, 0x1b,0xb5,0xb, 0x5a,0x40,0x6d,0xff,0x80,0x9, 0x1b, +0xb5,0xb, 0x5a,0x40,0x69,0xf6,0x0, 0x2, 0x4c,0x55,0x68,0xc, 0x6e,0x44,0xff,0xff, +0xb, 0x44,0x6e,0xf4,0xff,0xff,0xb, 0xf4,0xbd,0x4e,0x58,0x15,0xbd,0xfe,0x18,0x11, +0xa, 0xba,0x7e,0x6d,0x24,0x2d,0xdb,0x7a,0x6b,0xf0,0xb, 0xa0,0xbe,0xa0,0xa, 0x50, +0x6, 0xb, 0xf0,0xbc,0x4f,0x38,0x90,0x7c,0xba,0xda,0xf8,0xda,0x69,0x22,0x7c,0xb7, +0x54,0x7, 0x7e,0x24,0x0, 0x1, 0x22,0x7e,0x29,0x60,0x4c,0x6a,0x7a,0x29,0x60,0xb, +0x70,0x22,0x7a,0x1d,0x24,0x7e,0xf, 0x6, 0xf8,0x7e,0xb3,0x2a,0x6e,0x7e,0x37,0x2a, +0x53,0x22,0x7a,0x1d,0x24,0x7e,0xa3,0x2a,0x6e,0x74,0x2, 0xa4,0x7e,0xf, 0x6, 0xf8, +0x2d,0x15,0x7e,0xb3,0x2a,0x6d,0x7e,0x37,0x2a,0x51,0x22,0x7c,0x2b,0x7e,0xb3,0x1f, +0x33,0xbc,0x2b,0x68,0x50,0x12,0x8b,0x1a,0x7c,0x3b,0x7c,0xb2,0x12,0x8b,0x1a,0x7c, +0xab,0xbe,0x30,0xff,0x68,0x3f,0xbe,0xa0,0xff,0x68,0x3a,0x7e,0x70,0x4, 0xac,0x73, +0xa, 0x2a,0x12,0x88,0x56,0xbe,0xb0,0x2, 0x38,0x2b,0xa, 0x2b,0x7e,0x34,0x2, 0xe0, +0xad,0x32,0x2e,0x34,0x16,0x93,0x6d,0x22,0x30,0x1b,0x3, 0x2, 0x4f,0x93,0x7e,0xb3, +0x2b,0x1d,0xb4,0x1, 0x10,0x12,0x57,0xe5,0xa4,0x7a,0x55,0x29,0x7e,0x8, 0xd, 0xc8, +0x74,0x1, 0x2, 0x4f,0x21,0x22,0x7e,0xb3,0x2b,0xf, 0x7c,0xab,0x6c,0x77,0x7e,0x50, +0x5, 0xac,0x57,0x9, 0x62,0x26,0x33,0xbc,0x6a,0x78,0x3, 0x7c,0xb7,0x22,0xb, 0x70, +0xbe,0x70,0x4, 0x40,0xe9,0x74,0xff,0x22,0x7c,0xab,0x12,0x8f,0xce,0xd2,0x1b,0x7c, +0xba,0x12,0x8a,0xbb,0xc2,0x1b,0x22,0xca,0x3b,0x7e,0xb3,0x2a,0x74,0xf5,0x27,0x12, +0x6c,0x57,0x50,0x2, 0x61,0xd9,0x6d,0x33,0x9e,0x37,0x2a,0x4f,0x3e,0x34,0xbe,0x37, +0x7, 0xf8,0x18,0x75,0x7e,0xb3,0x16,0x92,0x70,0x6f,0x7e,0xb3,0x28,0xa8,0xb4,0x1, +0x59,0x7e,0x77,0x2a,0x51,0x7e,0x67,0x2a,0x53,0x75,0x24,0x0, 0x80,0x47,0xe5,0x24, +0x12,0x88,0x65,0x60,0x3e,0x12,0x8b,0xdc,0x12,0x8f,0xe8,0x7e,0xb3,0x2a,0x3, 0xb4, +0x1, 0x9, 0xe5,0x26,0xb4,0x18,0x4, 0xe, 0x64,0xe, 0x74,0x7e,0xa1,0x26,0x74,0x2, +0xa4,0x49,0x35,0x4, 0xfc,0xbd,0x36,0x48,0xd, 0xe5,0x25,0xa, 0x2b,0xe5,0x27,0x12, +0x8b,0xe4,0xbd,0x37,0x58,0xd, 0xe5,0x24,0x6c,0x77,0x12,0x73,0x2e,0x12,0x8b,0xdc, +0x12,0x8f,0xa4,0x5, 0x24,0x12,0x8f,0xd6,0x38,0xb4,0x7e,0xb3,0x2a,0x68,0x70,0x9, +0x7e,0xb3,0x2a,0x6b,0x70,0x3, 0x12,0x9a,0x76,0xda,0x3b,0x22,0x7e,0x71,0x24,0x74, +0x2, 0xac,0x7b,0x22,0xa, 0x3b,0x2d,0x32,0x3e,0x34,0x49,0x33,0x4, 0xfc,0x22,0xca, +0xf8,0x7c,0xfb,0x6d,0xdd,0x7c,0xbf,0x12,0x98,0x93,0x7d,0xe3,0x7c,0xbf,0x12,0x6f, +0x6b,0x7d,0xf3,0x74,0x2, 0xac,0xbf,0x9, 0x95,0x26,0xfb,0x7c,0xbf,0x12,0x8f,0x82, +0x40,0x2, 0x81,0xc0,0x74,0x2, 0xac,0xbf,0x9, 0xa5,0x26,0xfa,0xbe,0xa0,0x0, 0x28, +0xa, 0x7c,0xba,0x14,0x7c,0x79,0x12,0x6d,0xcb,0x7d,0xd3,0x12,0x8c,0xce,0x58,0x6, +0x7c,0xba,0x4, 0x12,0x8f,0x67,0x7e,0x24,0x0, 0x2, 0x12,0x8f,0x5f,0xbe,0xa0,0x0, +0x28,0x4e,0x12,0x8c,0xce,0x58,0x49,0xbe,0x90,0x0, 0x28,0x44,0xbe,0x90,0x0, 0x28, +0x3f,0xbe,0xf4,0x0, 0xc8,0x8, 0x39,0x7d,0x3d,0x3e,0x34,0x3e,0x34,0xbd,0x3f,0x8, +0x2f,0x12,0x8c,0xc4,0xbe,0x34,0x1, 0x2c,0x8, 0x26,0xa, 0x2a,0x7e,0xb3,0x2a,0x74, +0x12,0x8b,0xe4,0xbe,0x34,0x1, 0x90,0x8, 0x17,0xbe,0xf4,0x1, 0x5e,0x58,0xd, 0x7e, +0x34,0x0, 0x3, 0xad,0x3e,0xbd,0x3f,0x8, 0x3, 0xe4,0x80,0x35,0x74,0x1, 0x80,0x31, +0xbe,0x90,0x18,0x78,0x2b,0xbe,0xf4,0x0, 0xc8,0x8, 0x25,0x12,0x8c,0xc4,0xbe,0x34, +0x0, 0xc8,0x8, 0x1c,0xa, 0x2a,0x7e,0x73,0x2a,0x74,0xa, 0x37,0x12,0x8b,0xe6,0xbe, +0x34,0x0, 0xc8,0x8, 0xb, 0x7e,0xb3,0x28,0x84,0xb4,0x1, 0x4, 0x74,0x1, 0x80,0x1, +0xe4,0xda,0xf8,0x22,0x7e,0x70,0x2, 0xac,0x79,0x49,0x33,0x4, 0xfc,0x22,0x7e,0xb3, +0x2a,0x6f,0xa, 0x3b,0x1b,0x34,0xa, 0xca,0xbd,0xc3,0x22,0x12,0xa2,0x3d,0x12,0x9a, +0xed,0x12,0x8b,0x47,0x12,0x99,0xd6,0x2, 0x8c,0xea,0xca,0x3b,0x12,0x75,0x4a,0x7e, +0xb3,0x28,0x84,0x60,0x6, 0x7e,0xb3,0x36,0xe2,0x60,0x9, 0xe4,0x7a,0xb3,0x36,0xe4, +0x7a,0xb3,0x36,0x69,0x7e,0xb3,0x36,0xe2,0x70,0x5d,0x6c,0x99,0x80,0x51,0x12,0x8d, +0x92,0x9, 0xf5,0x26,0xfb,0x7c,0xb9,0x12,0x8f,0x82,0x40,0x41,0x6c,0xee,0x80,0x35, +0x74,0x2, 0xac,0xbe,0x9, 0xd5,0x36,0x6a,0x9, 0xc5,0x36,0x6b,0xa, 0x28,0xa, 0x3d, +0x12,0x8d,0x8a,0x78,0x1e,0xa, 0x2f,0xa, 0x3c,0x12,0x8d,0x8a,0x78,0x15,0x7c,0xb9, +0x12,0x6f,0x6b,0xbe,0x34,0x3, 0x20,0x58,0xa, 0x12,0x8f,0x58,0x7c,0xb8,0x7c,0x7f, +0x12,0x8f,0xac,0xb, 0xe0,0x7e,0x73,0x36,0xe4,0xbc,0x7e,0x38,0xc3,0xb, 0x90,0x7e, +0x73,0x28,0x84,0xbc,0x79,0x38,0xa7,0x7e,0x73,0x36,0x69,0x7a,0x73,0x36,0xe4,0xa, +0x37,0x3e,0x34,0xca,0x39,0x7e,0x18,0x36,0xa6,0x7e,0x8, 0x36,0x6a,0x12,0x20,0xc3, +0x1b,0xfd,0xe4,0x7a,0xb3,0x36,0xe2,0xda,0x3b,0x22,0x9d,0x32,0x12,0x21,0xa, 0x4d, +0x33,0x22,0x74,0x2, 0xac,0xb9,0x9, 0x85,0x26,0xfa,0x22,0xca,0x3b,0x7e,0xb3,0x2a, +0x6f,0xf5,0x26,0x7e,0xa3,0x2a,0x70,0x7e,0xb3,0x28,0x84,0xf5,0x24,0x70,0x2, 0xe1, +0x4c,0x7e,0x8, 0x1f,0x34,0x7e,0x34,0x3, 0xd4,0xe4,0x12,0x20,0xe8,0x7e,0x8, 0x23, +0x8, 0x7e,0x34,0x0, 0x23,0x12,0x20,0xe8,0x6c,0x99,0x80,0x5a,0x12,0x8f,0xde,0x9, +0xe3,0x26,0xfb,0x1a,0x68,0x1b,0x65,0x80,0x41,0xbe,0xd0,0x0, 0x48,0x3a,0xe5,0x26, +0xbc,0xbd,0x8, 0x34,0x74,0x1, 0x1a,0xcd,0x19,0xbc,0x23,0x8, 0x1a,0xce,0x1b,0xc5, +0x7d,0x3c,0x7c,0xf7,0x80,0x18,0xbe,0xf0,0x0, 0x48,0x11,0xbc,0xaf,0x8, 0xd, 0x74, +0x1, 0x12,0x8f,0x4f,0x1a,0xcf,0x2d,0xc3,0x19,0xbc,0x1f,0x34,0xb, 0xf0,0x1a,0x3e, +0xb, 0x35,0x1a,0xcf,0xbd,0xc3,0x8, 0xde,0xb, 0xd0,0x1a,0x38,0xb, 0x35,0x1a,0xcd, +0xbd,0xc3,0x8, 0xb5,0xb, 0x90,0xe5,0x24,0xbc,0xb9,0x38,0xa0,0x6c,0xdd,0x80,0x71, +0x1a,0xcd,0x9, 0xbc,0x23,0x8, 0x60,0x67,0x6d,0xdd,0x75,0x25,0x0, 0x7e,0xb3,0x2a, +0x6e,0xa, 0x2b,0x1a,0x3d,0xad,0x32,0x7d,0xc3,0x3e,0xc4,0x7e,0x7f,0x13,0x8a,0x6c, +0x99,0x80,0x16,0x12,0x8f,0x4f,0xa, 0xc9,0x2d,0xc3,0x9, 0xbc,0x1f,0x34,0x70,0x7, +0x7c,0xbd,0x12,0x8f,0x67,0x5, 0x25,0xb, 0x90,0xbc,0xa9,0x38,0xe6,0xe5,0x25,0x60, +0x2e,0xe5,0x25,0x1a,0x2b,0x12,0x8f,0x5f,0x6c,0xff,0x80,0x1f,0x12,0x8f,0x4f,0x1a, +0xcf,0x2d,0xc3,0x9, 0xbc,0x1f,0x34,0xb4,0x1, 0xf, 0x7c,0xbd,0x7c,0x7f,0x12,0x6f, +0x81,0xb, 0x1a,0xc0,0x9d,0xcd,0x1b,0x1a,0xc0,0xb, 0xf0,0xbc,0xaf,0x18,0xdd,0xb, +0xd0,0xe5,0x26,0xbc,0xbd,0x18,0x89,0x6c,0x99,0xe1,0x44,0x12,0x8d,0x92,0x9, 0xe5, +0x26,0xfb,0x7c,0xb8,0x7c,0x7e,0x12,0x6f,0x81,0x7f,0x71,0x4c,0x88,0x78,0xc, 0x12, +0x8f,0x78,0x2d,0x35,0x12,0x8f,0x6f,0x8, 0x62,0x80,0x51,0xe5,0x26,0x14,0xbc,0xb8, +0x78,0xc, 0x12,0x8f,0x78,0x9d,0x35,0x12,0x8f,0x6f,0x8, 0x4f,0x80,0x31,0xe5,0x26, +0xa, 0xcb,0x1b,0xc4,0x1a,0x58,0xbd,0x5c,0x58,0x41,0x7e,0xa3,0x2a,0x6e,0x7e,0x30, +0x2, 0xac,0x3a,0x7f,0x17,0x9d,0x31,0xb, 0x1a,0x30,0x74,0x2, 0xa4,0x7f,0x7, 0x2d, +0x15,0xb, 0xa, 0xc0,0xbd,0x3c,0x8, 0xd, 0xb, 0x7a,0x50,0xbd,0x35,0x8, 0x1c,0x1a, +0x58,0x1b,0x54,0x80,0xb, 0xb, 0x7a,0x50,0xbd,0xc5,0x8, 0xf, 0x1a,0x58,0xb, 0x54, +0x7c,0xab,0x7e,0x70,0x2, 0xac,0x79,0x19,0xa3,0x26,0xfa,0x12,0x8d,0x92,0x7c,0xb8, +0x7c,0x7e,0x12,0x6d,0xcb,0x7d,0xc3,0x7e,0x57,0x2a,0x5a,0xbd,0x5c,0x8, 0x3, 0x12, +0x8f,0x58,0xb, 0x90,0xe5,0x24,0xbc,0xb9,0x28,0x2, 0xc1,0xab,0xda,0x3b,0x22,0x1a, +0x2d,0x7e,0x34,0x0, 0x1c,0xad,0x32,0x22,0x7c,0xb9,0x6c,0x77,0x2, 0x73,0x2e,0x7d, +0x3d,0x12,0x1e,0xb9,0x7d,0xd3,0x22,0x7c,0x79,0x12,0x6d,0xcb,0x2d,0xd3,0x22,0xb, +0x1a,0xc0,0xb, 0x7a,0x50,0xbd,0xc5,0x22,0x7e,0xa3,0x2a,0x6e,0x74,0x2, 0xa4,0x7f, +0x17,0x22,0x7c,0x4b,0x74,0x2, 0xac,0xb4,0x9, 0x55,0x26,0xfa,0x9, 0x65,0x26,0xfb, +0x7e,0x73,0x28,0x8c,0xbc,0x75,0x78,0xa, 0x7e,0x73,0x28,0x8d,0xbc,0x76,0x78,0x2, +0xd3,0x22,0xc3,0x22,0x9, 0xb3,0x26,0xfa,0x9, 0x73,0x26,0xfb,0x7c,0x6b,0x7e,0xa3, +0x36,0x69,0x7e,0x50,0x2, 0xac,0x5a,0x19,0x62,0x36,0xa6,0x19,0x72,0x36,0xa7,0x7c, +0xba,0x4, 0x7a,0xb3,0x36,0x69,0x22,0x7e,0x34,0x0, 0x3, 0x2, 0x20,0xe8,0xa9,0xd1, +0xcb,0x74,0x1, 0x2, 0x0, 0xe, 0x7e,0x73,0x28,0x84,0xbe,0x71,0x24,0x22,0x7e,0x70, +0x2, 0xac,0x79,0x9, 0x83,0x26,0xfa,0x22,0x9, 0xb3,0x26,0xfa,0xf5,0x25,0x9, 0xb3, +0x26,0xfb,0xf5,0x26,0x22,0x12,0x90,0xd, 0x50,0x12,0x7e,0x37,0x2b,0x7, 0xbe,0x34, +0x1, 0x2c,0x28,0x8, 0x7e,0x34,0x1, 0x2c,0x7a,0x37,0x2b,0x7, 0x22,0xc2,0x0, 0x12, +0x90,0x35,0x68,0x7, 0x7e,0xb3,0x2a,0x68,0xb4,0x1, 0x17,0x7e,0xb3,0x37,0x71,0x70, +0x11,0x12,0x44,0xc4,0x40,0xa, 0x7e,0x37,0x28,0x8a,0xbe,0x34,0x1, 0x90,0x58,0x2, +0xd2,0x0, 0xa2,0x0, 0x22,0x7e,0xb3,0x2a,0x6b,0xbe,0xb0,0x1, 0x22,0x7e,0xb3,0x39, +0x87,0x70,0x4, 0x74,0x1, 0x80,0x1, 0xe4,0x7a,0xb3,0x39,0x87,0x22,0x7f,0x20,0xc2, +0x1, 0x7e,0x2b,0x60,0x29,0x72,0x0, 0x2, 0x9c,0x76,0x1a,0x37,0x12,0x21,0xa, 0x7c, +0x27,0x29,0x72,0x0, 0x1, 0x29,0x32,0x0, 0x3, 0x9c,0x37,0x1a,0x33,0x12,0x21,0xa, +0x7c,0x37,0x1a,0x23,0x1a,0x32,0x9d,0x32,0x12,0x21,0xa, 0x7c,0x67,0x7c,0x72,0xbc, +0x32,0x58,0x2, 0x7c,0x73,0xbe,0x60,0x5, 0x18,0x5, 0xbe,0x70,0x6, 0x58,0x8, 0x7e, +0x37,0x38,0xf4,0x4d,0x33,0x68,0x2, 0xd2,0x1, 0xa2,0x1, 0x22,0xca,0x3b,0x7c,0xc7, +0x7c,0xfb,0x7f,0x40,0x6d,0xbb,0x7e,0xa3,0x2a,0x6d,0x7e,0x73,0x2a,0x6e,0x4c,0xcc, +0x78,0x5, 0x7e,0xc0,0x1, 0x80,0xd, 0x7c,0xb7,0x14,0xbc,0xbc,0x78,0x6, 0xa, 0x6c, +0x1b,0x65,0x7c,0xcd,0x4c,0xff,0x78,0x5, 0x7e,0xf0,0x1, 0x80,0xb, 0x7c,0xba,0x14, +0xbc,0xbf,0x78,0x4, 0xa, 0x7f,0x1b,0x75,0x7f,0x4, 0x7e,0x34,0x0, 0x6, 0xe4,0x12, +0x20,0xe8,0x7e,0x73,0x2a,0x6d,0xa, 0x37,0x1b,0x34,0x7a,0x4b,0x70,0x7e,0x73,0x2a, +0x6e,0xa, 0x37,0x1b,0x34,0x39,0x74,0x0, 0x1, 0x7c,0xec,0x80,0x1d,0x75,0x24,0x0, +0x7c,0xdf,0x80,0xb, 0x12,0x6d,0xd2,0x70,0xb, 0x5, 0x24,0xb, 0xb4,0x1b,0xd0,0xbe, +0xd0,0x0, 0x58,0xf0,0xe5,0x24,0x60,0x7, 0x1b,0xe0,0xbe,0xe0,0x0, 0x58,0xde,0x7c, +0xec,0x80,0x26,0x75,0x24,0x0, 0x1a,0xaf,0xb, 0xa4,0x7d,0x3a,0x7c,0xd7,0x80,0xb, +0x12,0x6d,0xd2,0x70,0xe, 0x5, 0x24,0xb, 0xb4,0xb, 0xd0,0x7e,0x73,0x2a,0x6d,0xbc, +0x7d,0x18,0xed,0xe5,0x24,0x60,0x7, 0x1b,0xe0,0xbe,0xe0,0x0, 0x58,0xd5,0x12,0x91, +0xb2,0x80,0x1d,0x75,0x24,0x0, 0x7c,0xdf,0x80,0xb, 0x12,0x6d,0xd2,0x70,0xb, 0x5, +0x24,0xb, 0xb4,0x1b,0xd0,0xbe,0xd0,0x0, 0x58,0xf0,0xe5,0x24,0x60,0xa, 0xb, 0xe0, +0x7e,0x73,0x2a,0x6e,0xbc,0x7e,0x18,0xdb,0x12,0x91,0xb2,0x80,0x22,0x75,0x24,0x0, +0x1a,0x6f,0xb, 0x64,0x80,0xb, 0x12,0x6d,0xd2,0x70,0xe, 0x5, 0x24,0xb, 0xb4,0xb, +0xd0,0x7e,0x73,0x2a,0x6d,0xbc,0x7d,0x18,0xed,0xe5,0x24,0x60,0xa, 0xb, 0xe0,0x7e, +0x73,0x2a,0x6e,0xbc,0x7e,0x18,0xd6,0x7d,0x3b,0x39,0x74,0x0, 0x5, 0x7d,0x3b,0xda, +0x3b,0x22,0x1a,0xac,0xb, 0xa4,0x7d,0x3a,0x7c,0xe7,0x22,0x7f,0x60,0x7e,0x6b,0xa0, +0xbe,0xa0,0xa, 0x50,0x1b,0x7e,0x14,0x0, 0x6, 0xca,0x19,0x74,0x6, 0xa4,0x7f,0x6, +0x2d,0x15,0xb, 0x14,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x6b,0xb0,0x4, 0x7a,0x6b,0xb0, +0x22,0xe4,0x7e,0x63,0x2a,0x6e,0x7e,0x73,0x2a,0x6d,0xac,0x76,0x7d,0x13,0x1e,0x14, +0x7e,0x27,0x28,0x88,0x2e,0x27,0x28,0x86,0xbd,0x21,0x38,0xa, 0x1e,0x34,0x1e,0x34, +0xbe,0x37,0x28,0x86,0x50,0x14,0x7e,0xa3,0x26,0xf7,0xbe,0xa0,0xc, 0x28,0xb, 0x7e, +0xa3,0x26,0xf6,0xbe,0xa0,0x7, 0x28,0x2, 0x74,0x1, 0x22,0x7e,0xa3,0x2a,0x3, 0xbe, +0xa0,0x0, 0x38,0x2f,0xbe,0xa3,0x2a,0x2, 0x50,0x19,0x7e,0xb3,0x2a,0xc, 0xbe,0xb3, +0x35,0x56,0x28,0x14,0x7e,0xb3,0x35,0x56,0x4, 0x7a,0xb3,0x35,0x56,0x7a,0xa3,0x2a, +0x2, 0x80,0x5, 0xe4,0x7a,0xb3,0x35,0x56,0x7e,0xb3,0x2a,0x2, 0x70,0x5, 0xe4,0x7a, +0xb3,0x2a,0xb, 0x22,0x12,0x92,0x5a,0x2, 0x92,0x1b,0x7e,0xb3,0x2a,0x2, 0x70,0x29, +0x12,0x92,0x93,0x28,0x24,0x7e,0xb3,0x34,0xdb,0x70,0x18,0x12,0x92,0x9b,0x7e,0x73, +0x2a,0x3, 0x7a,0x73,0x2a,0x2, 0x74,0x1, 0x7a,0xb3,0x2a,0x9, 0x7e,0xb3,0x34,0xdb, +0x4, 0x80,0x1, 0xe4,0x7a,0xb3,0x34,0xdb,0x22,0xe4,0x7a,0xb3,0x34,0xdb,0x7a,0xb3, +0x2a,0x9, 0x22,0x7e,0x73,0x2a,0x3, 0xbe,0x70,0x0, 0x22,0x7e,0x34,0x0, 0x3c,0xca, +0x39,0x7e,0x18,0x36,0xe9,0x7e,0x8, 0x37,0x25,0x12,0x20,0xc3,0x1b,0xfd,0x7e,0x73, +0x28,0x94,0x7a,0x73,0x36,0xe8,0x7a,0x73,0x28,0x93,0x22,0x12,0x92,0x93,0x28,0x8, +0x7e,0xb3,0x28,0x84,0x70,0x2, 0xf5,0x1b,0x7e,0xb3,0x28,0x84,0x70,0x18,0xe5,0x1b, +0xbe,0xb0,0xfa,0x50,0x2, 0x5, 0x1b,0xe5,0x1b,0xbe,0xb0,0x5, 0x40,0x8, 0xe4,0x7a, +0xb3,0x32,0x2c,0x75,0x1b,0xfa,0x22,0xca,0x79,0xc2,0x0, 0x7e,0xf0,0x3, 0x12,0x92, +0xbb,0x7e,0xe3,0x2a,0x3, 0x7e,0x34,0x1f,0x34,0x7a,0x37,0x31,0xee,0x12,0x97,0xcc, +0x38,0x2, 0x61,0xc0,0x12,0x93,0xf5,0x92,0xd, 0x12,0x93,0xc9,0x7c,0xbf,0x12,0xae, +0x2d,0x4c,0xee,0x68,0xe, 0x7e,0xa3,0x31,0xcb,0x4c,0xaa,0x78,0xa, 0x7e,0xb3,0x31, +0xcc,0x70,0x4, 0xd2,0x0, 0x80,0x25,0xbe,0xe0,0x1, 0x28,0xb, 0xe5,0x1c,0xbe,0xb0, +0x8, 0x28,0x4, 0xd2,0x0, 0x80,0x15,0xd2,0x0, 0x7e,0xb3,0x28,0x84,0xbc,0xbe,0x78, +0xb, 0x20,0xd, 0x8, 0x4c,0xaa,0x78,0x4, 0x6c,0xff,0xc2,0x0, 0x20,0x0, 0x5, 0x7c, +0xbf,0x12,0xae,0x2d,0x7e,0x8, 0x31,0xd0,0x12,0xb4,0x20,0x7a,0xb3,0x31,0xcf,0xbe, +0xb3,0x28,0x84,0x50,0x3a,0x7e,0x33,0x31,0xcf,0x80,0x26,0x7e,0x70,0x2, 0xac,0x73, +0x9, 0x23,0x31,0xf0,0x9, 0x13,0x31,0xf1,0x2e,0x37,0x31,0xee,0xb, 0x38,0x50,0x7e, +0x93,0x2a,0x6e,0xac,0x92,0xa, 0x31,0x2d,0x43,0x12,0xc6,0x79,0x7c,0xb3,0x12,0x76, +0xfb,0x7c,0x3, 0x1b,0x30,0xa5,0xb8,0x0, 0xd2,0x74,0x1, 0x7a,0xb3,0x31,0xcd,0x7e, +0xa3,0x31,0xcf,0x7a,0xa3,0x28,0x84,0x74,0x2, 0xa4,0xca,0x59,0x7e,0x18,0x31,0xf0, +0x7e,0x8, 0x26,0xfa,0x12,0x20,0xc3,0x1b,0xfd,0x12,0x46,0xb9,0xf5,0x1c,0x80,0x6, +0x75,0x1c,0x64,0x12,0x97,0xde,0xda,0x79,0x22,0x6c,0xaa,0x12,0x97,0xea,0x12,0x93, +0xeb,0x54,0xfe,0x12,0x93,0xe8,0x54,0x7, 0x12,0x93,0xe8,0x54,0xfb,0x7a,0xb, 0xb0, +0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xe4,0x22,0x7a,0xb, 0xb0,0x7f,0x1, 0x2e,0x14,0x0, +0x5, 0x7e,0xb, 0xb0,0x22,0xca,0x3b,0x7e,0xe3,0x28,0x84,0x6c,0xdd,0x6c,0xff,0x74, +0x6, 0xac,0xbd,0x12,0x97,0x6e,0x30,0xe0,0x37,0x6c,0xcc,0x80,0x27,0x12,0x97,0xd4, +0x7a,0xb3,0x1f,0x70,0x9, 0xa3,0x26,0xfb,0x7a,0xa3,0x1f,0x71,0x7f,0x7, 0x12,0x94, +0x4b,0x50,0xf, 0x7f,0x7, 0x7e,0xb3,0x1f,0x71,0x6c,0x77,0x12,0x94,0x4e,0x50,0x2, +0xb, 0xf0,0xb, 0xc0,0xbc,0xec,0x38,0xd5,0xbe,0xf0,0x2, 0x40,0x3, 0xd3,0x80,0x8, +0xb, 0xd0,0xbe,0xd0,0x1e,0x40,0xb6,0xc3,0xda,0x3b,0x22,0x7e,0x70,0x1, 0x7c,0x87, +0x7c,0x9b,0x29,0xa0,0x0, 0x3, 0x29,0x60,0x0, 0x1, 0x7e,0x70,0x1, 0xbe,0x80,0x1, +0x78,0x7, 0x29,0xa0,0x0, 0x2, 0x7e,0xb, 0x60,0xa, 0x7, 0xa, 0x29,0x2d,0x2, 0xa, +0x16,0xbd,0x1, 0x48,0xc, 0xa, 0x17,0xa, 0x3a,0x2d,0x31,0xbd,0x23,0x18,0x2, 0xd3, +0x22,0xc3,0x22,0xca,0x3b,0x7c,0xf5,0x7c,0xe6,0x7c,0xd7,0x7c,0xcb,0x75,0x54,0x0, +0x7e,0xa1,0x54,0x74,0x6, 0xa4,0x12,0x97,0x6e,0x30,0xe1,0x2e,0x7f,0x7, 0x7c,0xbc, +0x12,0x96,0xab,0x50,0x25,0x7f,0x7, 0x7c,0xbe,0x12,0x94,0x4b,0x50,0x1c,0x7f,0x7, +0x7c,0xbd,0x6c,0x77,0x12,0x94,0x4e,0x50,0x11,0x7f,0x7, 0x7c,0xbf,0x6c,0x77,0x12, +0x94,0x4e,0x50,0x6, 0x29,0xb7,0x0, 0x4, 0x80,0xa, 0x5, 0x54,0xe5,0x54,0xbe,0xb0, +0x1e,0x40,0xbd,0xe4,0xda,0x3b,0x22,0xca,0x79,0x7f,0x70,0x7e,0xb4,0xff,0xff,0x6c, +0xee,0xc2,0x1, 0xc2,0x2, 0x29,0x67,0x0, 0x2, 0x7e,0x7b,0x70,0xbc,0x76,0x78,0xe, +0x29,0x67,0x0, 0x3, 0x29,0x77,0x0, 0x1, 0xbc,0x76,0x78,0x2, 0xd2,0x2, 0x6c,0xff, +0x12,0x96,0xbb,0x6d,0xaa,0x29,0xb6,0x0, 0x5, 0x20,0xe1,0x2, 0xa1,0x91,0x7f,0x6, +0x7e,0x7b,0xb0,0x12,0x96,0xab,0x50,0x2d,0x7f,0x6, 0x29,0xb7,0x0, 0x2, 0x12,0x96, +0xab,0x50,0x22,0x7f,0x6, 0x29,0xb7,0x0, 0x1, 0x6c,0x77,0x12,0x94,0x4e,0x50,0x15, +0x7f,0x6, 0x29,0xb7,0x0, 0x3, 0x6c,0x77,0x12,0x94,0x4e,0x50,0x8, 0x7c,0xef,0xd2, +0x1, 0x6d,0xbb,0x80,0x55,0x7e,0x6b,0x70,0xa, 0x27,0x7e,0x7b,0x70,0x12,0x96,0xa4, +0x2d,0xa3,0x29,0x76,0x0, 0x2, 0xa, 0x27,0x29,0x77,0x0, 0x2, 0x12,0x96,0xa4,0x2d, +0xa3,0x29,0x76,0x0, 0x1, 0xa, 0x27,0x29,0x77,0x0, 0x1, 0x12,0x96,0xa4,0x2d,0xa3, +0x29,0x76,0x0, 0x3, 0xa, 0x27,0x29,0x77,0x0, 0x3, 0x12,0x96,0xa4,0x2d,0xa3,0xbd, +0xab,0x50,0x4, 0x7d,0xba,0x7c,0xef,0xbe,0xa4,0x0, 0x4, 0x38,0x4, 0xd2,0x1, 0x80, +0x9, 0xb, 0xf0,0xbe,0xf0,0x1e,0x50,0x2, 0xa1,0x0, 0x20,0x1, 0xb, 0x20,0x2, 0x8, +0xbe,0xb4,0x0, 0x8, 0x50,0x2, 0xd2,0x1, 0x20,0x1, 0x2, 0xc1,0x52,0x74,0x6, 0xac, +0xbe,0x12,0x96,0xbf,0x29,0x76,0x0, 0x5, 0x7c,0xb7,0xc4,0x23,0x54,0x1f,0xbe,0xb0, +0x1f,0x50,0x16,0x7f,0x6, 0x2e,0x14,0x0, 0x5, 0x7c,0x67,0x2e,0x60,0x8, 0x5e,0x60, +0xf8,0x5e,0x70,0x7, 0x4c,0x76,0x7a,0xb, 0x70,0x20,0x2, 0x11,0x29,0xb6,0x0, 0x4, +0xbe,0xb0,0xfa,0x50,0x8, 0x7f,0x16,0xb, 0x36,0x4, 0x7a,0x1b,0xb0,0x29,0x67,0x0, +0x3, 0x29,0x76,0x0, 0x3, 0xbc,0x76,0x28,0x6, 0x29,0x76,0x0, 0x3, 0x80,0x4, 0x29, +0x77,0x0, 0x3, 0x39,0x76,0x0, 0x3, 0x29,0x67,0x0, 0x2, 0x29,0x76,0x0, 0x2, 0xbc, +0x76,0x28,0x6, 0x29,0x76,0x0, 0x2, 0x80,0x4, 0x29,0x77,0x0, 0x2, 0x39,0x76,0x0, +0x2, 0x29,0x67,0x0, 0x1, 0x29,0x76,0x0, 0x1, 0xbc,0x76,0x50,0x6, 0x29,0x76,0x0, +0x1, 0x80,0x4, 0x29,0x77,0x0, 0x1, 0x39,0x76,0x0, 0x1, 0x7e,0x7b,0x60,0x7e,0x6b, +0x70,0xbc,0x76,0x50,0x5, 0x7e,0x6b,0x70,0x80,0x3, 0x7e,0x7b,0x70,0x7a,0x6b,0x70, +0x80,0x31,0x6c,0xff,0x74,0x6, 0xac,0xbf,0x9, 0xb5,0x32,0x32,0x30,0xe1,0x7, 0xb, +0xf0,0xbe,0xf0,0x1e,0x40,0xee,0xbe,0xf0,0x1e,0x50,0x33,0x74,0x1, 0x39,0xb7,0x0, +0x4, 0x12,0x96,0xbb,0x7e,0x34,0x0, 0x6, 0xca,0x39,0x7f,0x17,0x7f,0x6, 0x12,0x20, +0xc3,0x1b,0xfd,0x12,0x96,0xb1,0x44,0x1, 0x7a,0x1b,0xb0,0x12,0x96,0xb1,0x44,0x2, +0x7a,0x1b,0xb0,0x30,0x2, 0x8, 0x12,0x96,0xb1,0x44,0x4, 0x7a,0x1b,0xb0,0xda,0x79, +0x22,0x7e,0x39,0x70,0xa, 0x37,0x9d,0x32,0x2, 0x21,0xa, 0x7e,0x70,0x1, 0x2, 0x94, +0x4e,0x7f,0x16,0x2e,0x34,0x0, 0x5, 0x7e,0x1b,0xb0,0x22,0x74,0x6, 0xac,0xbf,0x7d, +0xd5,0x2e,0xd4,0x32,0x2d,0x6d,0xcc,0x22,0xca,0xf8,0x7e,0xd4,0x0, 0x7, 0x7e,0xb3, +0x28,0x84,0x70,0x8, 0xf5,0x5a,0xc2,0xa, 0xc2,0xb, 0x80,0x7d,0xbe,0xb0,0x2, 0x38, +0x72,0xb4,0x2, 0x28,0x7e,0x73,0x26,0xfc,0xa, 0x27,0x7e,0x73,0x26,0xfa,0x12,0x96, +0xa4,0xbe,0x34,0x0, 0x5, 0x58,0x15,0x7e,0x73,0x26,0xfd,0xa, 0x27,0x7e,0x73,0x26, +0xfb,0x12,0x96,0xa4,0xbe,0x34,0x0, 0x5, 0x58,0x2, 0x80,0x5a,0x6c,0xff,0x80,0x3c, +0x7c,0xbf,0x12,0x97,0x7b,0x1a,0x4b,0x7c,0xbf,0x12,0x6f,0x6b,0x7d,0xc3,0xbe,0xc4, +0x2, 0x58,0x58,0x4, 0x7e,0xd4,0x0, 0x6, 0x7d,0x5d,0x3e,0x54,0xbd,0x54,0x58,0x4, +0xd2,0xb, 0x80,0xa, 0x7d,0x5d,0xe, 0x54,0xbd,0x54,0x48,0x2, 0xc2,0xb, 0x20,0xb, +0x4, 0xbd,0xd4,0x58,0x5, 0x75,0x5a,0x28,0x80,0xf, 0xb, 0xf0,0x12,0x73,0x6d,0x38, +0xbf,0x80,0x6, 0xe5,0x5a,0x24,0xfb,0xf5,0x5a,0xe5,0x5a,0xbe,0xb0,0x0, 0x8, 0x6, +0xd2,0xa, 0x15,0x5a,0x80,0x5, 0x75,0x5a,0x0, 0xc2,0xa, 0xda,0xf8,0x22,0x7d,0xf5, +0x2e,0xf4,0x32,0x2d,0x6d,0xee,0x29,0xb7,0x0, 0x5, 0x22,0xca,0xf8,0x7c,0xfb,0x7e, +0x70,0x2, 0x12,0x99,0xd, 0x7f,0x71,0x7c,0xbf,0x12,0x6f,0x6b,0x12,0x97,0xc5,0x7f, +0x17,0x12,0x1f,0x58,0x7c,0xb7,0xda,0xf8,0x22,0xca,0xd8,0xca,0x79,0x6c,0xff,0x6c, +0xee,0x80,0xf, 0x7c,0xbe,0x12,0x97,0x7b,0x7c,0xdb,0xbc,0xfd,0x58,0x2, 0x7c,0xfd, +0xb, 0xe0,0x12,0x97,0xbe,0x38,0xec,0x7c,0xbf,0xda,0x79,0xda,0xd8,0x22,0x7e,0x73, +0x28,0x84,0xbc,0x7e,0x22,0x7d,0x13,0x1a,0x2, 0x1a,0x0, 0x22,0x7e,0x73,0x28,0x84, +0xbe,0x70,0x1, 0x22,0x7e,0x70,0x2, 0xac,0x7c,0x9, 0xb3,0x26,0xfa,0x22,0x7e,0x8, +0x32,0x2d,0x7e,0x34,0x0, 0xb4,0xe4,0x2, 0x20,0xe8,0x7e,0x70,0x6, 0xac,0x7a,0x2e, +0x34,0x32,0x2d,0x6d,0x22,0x22,0x7e,0xa3,0x2a,0x2, 0x7e,0xb3,0x38,0x32,0x70,0x5, +0x7a,0xb3,0x34,0xc4,0x22,0xe4,0x7a,0xb3,0x34,0x88,0x6c,0x77,0x80,0x78,0x7e,0x90, +0x9, 0xac,0x97,0x9, 0x64,0x29,0xc, 0x7c,0xb6,0x54,0xf, 0xa, 0x2b,0x9, 0x52,0x29, +0xbc,0x4c,0x55,0x68,0xa, 0xa5,0xbd,0x2, 0x5b,0x7e,0xb3,0x34,0xc4,0x70,0x55,0x49, +0x14,0x29,0x8, 0xbe,0x14,0x0, 0x64,0x28,0x10,0xbe,0x14,0x3, 0xd4,0x50,0xa, 0x49, +0x14,0x29,0xa, 0xbe,0x14,0x0, 0x64,0x38,0x3b,0x7e,0xb3,0x34,0x88,0xbc,0xb7,0x40, +0x5, 0x4, 0x7a,0xb3,0x34,0x88,0x7e,0xb3,0x2a,0x2, 0x14,0x7a,0xb3,0x2a,0x2, 0x7e, +0x40,0xff,0x7e,0x30,0x9, 0xac,0x37,0x19,0x41,0x29,0xc, 0x74,0x3, 0xa, 0x46,0x19, +0xb4,0x29,0xbc,0x19,0xb4,0x29,0xc6,0xa5,0xbd,0x2, 0x9, 0x7e,0xb3,0x2a,0x3, 0x14, +0x7a,0xb3,0x2a,0x3, 0xb, 0x70,0xbc,0xa7,0x38,0x84,0x7e,0x73,0x38,0x32,0x7a,0x73, +0x34,0xc4,0x22,0xca,0x79,0x7c,0x8b,0x6c,0xaa,0x9f,0x77,0x12,0x99,0xc8,0x1a,0x79, +0x1b,0x74,0x80,0x41,0x1a,0x38,0x1b,0x34,0x7c,0xe7,0x80,0x2d,0xbc,0x9f,0x78,0x4, +0xbc,0x8e,0x68,0x23,0xbe,0xf0,0x0, 0x48,0x1e,0x7e,0xb3,0x2a,0x6f,0xbc,0xbf,0x8, +0x16,0xbe,0xe0,0x0, 0x48,0x11,0x7e,0xb3,0x2a,0x70,0xbc,0xbe,0x8, 0x9, 0x7c,0xbf, +0x7c,0x7e,0x12,0x99,0x3, 0xb, 0xa0,0xb, 0xe0,0x1a,0x28,0xb, 0x24,0x1a,0x3e,0xbd, +0x32,0x8, 0xc9,0xb, 0xf0,0x1a,0x29,0xb, 0x24,0x1a,0x3f,0xbd,0x32,0x8, 0xb5,0x4c, +0xaa,0x78,0x4, 0x6d,0x33,0x80,0x9, 0xa, 0x1a,0x6d,0x0, 0x7f,0x17,0x12,0x1f,0x58, +0xda,0x79,0x22,0x12,0x6d,0xcb,0x1a,0x26,0x1a,0x24,0x2f,0x71,0x22,0xca,0x79,0x7c, +0xa7,0x7c,0x8b,0x7e,0xb3,0x2a,0x6f,0x7a,0xb3,0x1f,0x9a,0x7e,0xb3,0x2a,0x70,0x7a, +0xb3,0x1f,0x9b,0x12,0x99,0xc8,0x9f,0x77,0x1a,0x3a,0x1a,0x79,0x9d,0x73,0x21,0xb5, +0x7a,0xf1,0x58,0xbe,0xf0,0x0, 0x58,0xe, 0x1a,0x3f,0x1a,0x29,0x9d,0x23,0x1a,0x39, +0x2d,0x32,0x7c,0xb7,0xf5,0x58,0x7e,0xb3,0x1f,0x9a,0xbc,0xbf,0x18,0xe, 0x1a,0x39, +0x1a,0x2f,0x9d,0x23,0x1a,0x39,0x9d,0x32,0x7c,0xb7,0xf5,0x58,0x1a,0x2a,0x1a,0x38, +0x9d,0x32,0x7c,0xb7,0xf5,0x57,0x80,0x3d,0x85,0x57,0x59,0xe5,0x57,0xbe,0xb0,0x0, +0x58,0x10,0xe5,0x57,0x1a,0x3b,0x1a,0x28,0x9d,0x23,0x1a,0x38,0x2d,0x32,0x7c,0xb7, +0xf5,0x59,0x7e,0xb3,0x1f,0x9b,0xbe,0xb1,0x57,0x18,0x10,0x1a,0x38,0xe5,0x57,0x1a, +0x2b,0x9d,0x23,0x1a,0x38,0x9d,0x32,0x7c,0xb7,0xf5,0x59,0xe5,0x58,0x7e,0x71,0x59, +0x12,0x99,0x3, 0x5, 0x57,0x1a,0x3a,0x1a,0x28,0x2d,0x23,0xe5,0x57,0x1a,0x3b,0xbd, +0x32,0x8, 0xb5,0xb, 0xf0,0x1a,0x3a,0x1a,0x29,0x2d,0x23,0x1a,0x3f,0xbd,0x32,0x18, +0x2, 0x21,0x30,0x7f,0x17,0xda,0x79,0x22,0x7e,0x70,0x2, 0xac,0x78,0x9, 0x93,0x26, +0xfa,0x9, 0x83,0x26,0xfb,0x22,0xca,0xd8,0xca,0x79,0x7e,0xf4,0x3, 0x20,0x7d,0x7f, +0x12,0x9a,0xc7,0x50,0x2, 0x41,0x6a,0x7a,0xf5,0x2a,0x7e,0xb3,0x28,0xa8,0xb4,0x1, +0x4, 0x7e,0x74,0x4, 0xb0,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x4, 0x4c,0x8, 0x6b,0x6c, +0xdd,0x80,0x5f,0xc2,0x0, 0x7c,0xbd,0x12,0x6f,0x6b,0x7a,0x35,0x26,0x7c,0xbd,0x7e, +0x70,0x1, 0x12,0x99,0xd, 0x7a,0x35,0x24,0x9e,0x35,0x26,0x7a,0x35,0x24,0x7e,0x35, +0x26,0x3e,0x34,0x3e,0x34,0x12,0x9a,0x6f,0x7a,0x35,0x28,0xbe,0x75,0x28,0x58,0x3, +0x7a,0x75,0x28,0x7e,0x35,0x28,0xbe,0x35,0x24,0x8, 0xa, 0x7e,0x35,0x2a,0xbe,0x35, +0x26,0x8, 0x2, 0xd2,0x0, 0x7c,0xbd,0x12,0x8f,0x82,0x50,0x2, 0xc2,0x0, 0x30,0x0, +0xf, 0x7c,0xbd,0x6c,0x77,0x12,0x73,0x2e,0x7e,0x70,0x2, 0xac,0x7d,0x12,0x8f,0xa4, +0xb, 0xd0,0x7e,0x73,0x28,0x84,0xbc,0x7d,0x38,0x99,0xda,0x79,0xda,0xd8,0x22,0x7e, +0x24,0x0, 0x2, 0x2, 0x1e,0xb9,0x7e,0xa0,0x1, 0x7e,0x37,0x2a,0x4f,0x12,0x9a,0xbf, +0x28,0x35,0x6d,0x22,0x9d,0x23,0xbe,0x27,0x7, 0xf8,0x58,0x2b,0x12,0x9a,0x6f,0xbe, +0x37,0x7, 0xfa,0x8, 0x22,0xe4,0x7a,0xb3,0x28,0x84,0x7e,0xb3,0x2a,0x3, 0x70,0x17, +0x7e,0xb3,0x38,0x9, 0xb4,0x1, 0x10,0x6c,0xaa,0x5, 0x5b,0xe5,0x5b,0xbe,0xb0,0x10, +0x28,0x5, 0xd2,0x15,0x75,0x5b,0x0, 0x4c,0xaa,0x68,0x3, 0x75,0x5b,0x0, 0x22,0x7e, +0xb3,0x28,0x84,0xbe,0xb0,0x0, 0x22,0x6c,0x99,0x6c,0x88,0x80,0xf, 0x7c,0xb8,0x12, +0x6f,0x6b,0xbe,0x34,0x1, 0xf4,0x8, 0x2, 0xb, 0x90,0xb, 0x80,0x7e,0x73,0x28,0x84, +0xbc,0x78,0x38,0xe9,0xbe,0x90,0x1, 0x38,0x2, 0xc3,0x22,0xd3,0x22,0xca,0x3b,0x7e, +0x77,0x2a,0x5c,0x12,0x9b,0x83,0x7d,0x63,0x3e,0x34,0x3e,0x34,0x7e,0xe4,0x0, 0xa, +0x12,0x9b,0x7b,0x7e,0xb3,0x28,0xa8,0x60,0xf, 0x7e,0x37,0x36,0xe5,0xbd,0x36,0x48, +0x7, 0x3e,0x34,0x3e,0x34,0x12,0x9b,0x7b,0xbe,0x64,0x4, 0x4c,0x8, 0xf, 0x12,0x9a, +0xc7,0x50,0x6, 0x7e,0xb3,0x28,0xa8,0x60,0x4, 0x74,0xa, 0x80,0x13,0x7e,0xb3,0x28, +0xa8,0x60,0xc, 0x7e,0xb3,0x36,0xe3,0xbe,0xb0,0x0, 0x28,0x8, 0x14,0x80,0x1, 0xe4, +0x7a,0xb3,0x36,0xe3,0x7e,0xe7,0x2a,0x5c,0x7d,0x3e,0x12,0x46,0xab,0x7e,0x53,0x36, +0xe3,0xbe,0x50,0x0, 0x28,0x12,0xbd,0x3f,0x58,0x4, 0x7d,0xf3,0x80,0x6, 0xbd,0xef, +0x8, 0x2, 0x7d,0xfe,0x7a,0xf7,0x2a,0x5c,0x12,0x97,0xcc,0x28,0x3, 0x12,0x75,0x21, +0x7a,0x67,0x36,0xe5,0x7a,0x77,0x2a,0x5c,0xda,0x3b,0x22,0x7d,0x2e,0x12,0x1e,0xb9, +0x7d,0xf3,0x22,0xca,0x3b,0x6d,0x44,0x7e,0xf3,0x28,0x84,0x6c,0xee,0x80,0x24,0x7c, +0xbe,0x12,0x88,0x65,0x60,0x1b,0x74,0x2, 0xac,0xbe,0x9, 0xd5,0x26,0xfa,0x9, 0xc5, +0x26,0xfb,0x7c,0xbd,0x7c,0x7c,0x12,0x6d,0xcb,0x7d,0xf3,0xbd,0x4f,0x58,0x2, 0x7d, +0x4f,0xb, 0xe0,0xbc,0xfe,0x38,0xd8,0x7d,0x34,0xda,0x3b,0x22,0xca,0x79,0x6c,0xff, +0x9f,0x77,0x7f,0x67,0x6d,0xbb,0x7e,0xa3,0x2a,0x70,0x7e,0xe3,0x2a,0x6f,0x7e,0xa7, +0x28,0x97,0x7e,0x8, 0x1f,0x34,0x7e,0x34,0x0, 0x1c,0xe4,0x12,0x20,0xe8,0x7e,0x8, +0x1f,0x50,0x7e,0x34,0x0, 0x1c,0x12,0x20,0xe8,0x6c,0x99,0x80,0x41,0x7e,0x50,0x2, +0xac,0x59,0x49,0x32,0x5, 0x7a,0xbe,0x34,0x0, 0xfa,0x8, 0x12,0x49,0x12,0x4, 0xfc, +0xbd,0x1a,0x58,0xa, 0x74,0x1, 0xa, 0x19,0x19,0xb1,0x1f,0x34,0x80,0x1e,0xbe,0x34, +0x0, 0xfa,0x8, 0x18,0x49,0x32,0x4, 0xfc,0xbe,0x34,0x0, 0xfa,0x8, 0xe, 0xbd,0x3b, +0x8, 0x2, 0x7d,0xb3,0x74,0x1, 0xa, 0x39,0x19,0xb3,0x1f,0x50,0xb, 0x90,0xbc,0xa9, +0x38,0xbb,0x6c,0x99,0x80,0x27,0xa, 0xa9,0x9, 0xba,0x1f,0x34,0xb4,0x1, 0x1c,0x6c, +0x88,0x80,0x14,0x7c,0xb8,0x7c,0x79,0x12,0x6d,0xcb,0x12,0x21,0xa, 0xbe,0x34,0x0, +0xfa,0x8, 0x2, 0xb, 0xf0,0xb, 0x80,0xbc,0xe8,0x38,0xe8,0xb, 0x90,0xbc,0xa9,0x38, +0xd5,0xbe,0xf0,0x1, 0x28,0x52,0xbe,0xb4,0x3, 0xe8,0x8, 0x4, 0x74,0x1, 0x80,0x49, +0x6c,0x99,0x80,0x21,0xa, 0x39,0x9, 0xb3,0x1f,0x50,0xb4,0x1, 0x16,0x7e,0x70,0x2, +0xac,0x79,0x49,0x13,0x5, 0x7a,0x1a,0x2, 0x1a,0x0, 0x2f,0x60,0x49,0x33,0x4, 0xfc, +0x12,0x99,0x6, 0xb, 0x90,0xbc,0xa9,0x38,0xdb,0x74,0x2, 0x7f,0x16,0x1e,0x34,0xe, +0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x7e,0x14,0x0, 0x5, 0x12,0x1e,0xfc, +0xbf,0x71,0x8, 0x4, 0x74,0x1, 0x80,0x1, 0xe4,0xda,0x79,0x22,0xca,0x3b,0x6c,0xaa, +0xc2,0x0, 0x7e,0x97,0x28,0x99,0x7e,0x87,0x28,0x97,0x7e,0xb3,0x28,0xa5,0x14,0x68, +0x19,0x14,0x68,0x1e,0x24,0xc2,0x68,0x8, 0x24,0xfb,0x68,0xe, 0x24,0x45,0x78,0x26, +0x7e,0xe3,0x2a,0x6e,0x7e,0xd3,0x2a,0x6d,0x80,0x20,0x6c,0xee,0x7e,0xd3,0x2a,0x6e, +0x80,0x18,0x6c,0xee,0x7e,0xb3,0x2a,0x6d,0xa, 0x2b,0x7e,0xb3,0x2a,0x6e,0xa, 0x3b, +0x2d,0x32,0x7c,0xd7,0x80,0x4, 0x6c,0xee,0x6c,0xdd,0x6c,0xff,0x80,0xf, 0x12,0x9e, +0x3a,0x6d,0x33,0x9d,0x39,0xbd,0x23,0x58,0x2, 0xb, 0xa0,0xb, 0xf0,0xbc,0xdf,0x38, +0xed,0x4c,0xaa,0x78,0x3c,0x7e,0xb3,0x26,0x85,0x70,0x25,0x7e,0xb3,0x26,0x84,0x70, +0x1f,0x6c,0xff,0x80,0x15,0x12,0x9e,0x3a,0xbd,0x29,0x8, 0xc, 0x49,0x33,0x4, 0xfc, +0xbd,0x38,0x58,0x4, 0xd2,0x0, 0x80,0x19,0xb, 0xf0,0xbc,0xdf,0x38,0xe7,0x80,0x11, +0x12,0x9b,0xbc,0xa, 0x8b,0x4d,0x88,0x68,0x8, 0x12,0x76,0xe0,0x28,0x3, 0x12,0x9e, +0x2d,0x6c,0xcc,0x12,0x76,0xe0,0x38,0x5, 0x12,0x9e,0x47,0x28,0x69,0x7e,0xb3,0x28, +0xa7,0xb4,0x1, 0x9, 0x7e,0xb3,0x28,0xaa,0xbe,0xb0,0x1, 0x68,0x59,0x7e,0xb3,0x28, +0xa8,0xb4,0x1, 0x52,0x6c,0xff,0x80,0x1d,0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xa3,0x26, +0xfa,0x9, 0x93,0x26,0xfb,0x12,0x6d,0xc7,0xbe,0x34,0x0, 0xc8,0x8, 0x5, 0x7e,0xc0, +0x1, 0x80,0xa, 0xb, 0xf0,0x7e,0xb3,0x28,0x84,0xbc,0xbf,0x38,0xdb,0x6c,0xff,0x80, +0x1d,0x7e,0x70,0x2, 0xac,0x7f,0x9, 0xa3,0x27,0x36,0x9, 0x93,0x27,0x37,0x12,0x6d, +0xc7,0xbe,0x34,0xff,0x38,0x58,0x5, 0x7e,0xc0,0x1, 0x80,0xa, 0xb, 0xf0,0x7e,0xb3, +0x28,0x85,0xbc,0xbf,0x38,0xdb,0x4c,0xcc,0x78,0x29,0x6c,0xff,0x80,0x21,0xa, 0x3f, +0xa, 0x2e,0x2d,0x23,0x3e,0x24,0x49,0x32,0x5, 0x7a,0xbd,0x39,0x8, 0xf, 0x49,0x82, +0x4, 0xfc,0x3e,0x84,0xbd,0x38,0x8, 0x5, 0x7e,0xc0,0x1, 0x80,0x6, 0xb, 0xf0,0xbc, +0xdf,0x38,0xdb,0x30,0x0, 0x15,0x7e,0xb3,0x3a,0xc, 0x4, 0x7a,0xb3,0x3a,0xc, 0x7e, +0x73,0x3a,0xc, 0xbe,0x70,0xa, 0x28,0x3, 0x12,0x9e,0x2d,0x4c,0xcc,0x78,0xb, 0x7e, +0xb3,0x28,0xa8,0x60,0x2, 0xd2,0x19,0x12,0x9e,0x4f,0xda,0x3b,0x22,0x74,0xa, 0x7a, +0xb3,0x3a,0xc, 0x74,0x1, 0x7a,0xb3,0x28,0xa8,0x22,0xa, 0x2f,0xa, 0x3e,0x2d,0x32, +0x3e,0x34,0x49,0x23,0x5, 0x7a,0x22,0x7e,0x73,0x28,0x85,0xbe,0x70,0x0, 0x22,0xe4, +0x7a,0xb3,0x28,0xa8,0x7a,0xb3,0x3a,0xc, 0x22,0xca,0xd8,0xca,0x79,0x7c,0xdb,0x7e, +0xf0,0xa, 0x6c,0x11,0x80,0x21,0x7e,0x0, 0xff,0x74,0x9, 0xac,0xb1,0x19,0x5, 0x1f, +0x38,0x7e,0x34,0x7f,0xff,0x74,0x9, 0xac,0xb1,0x59,0x35,0x1f,0x34,0x74,0x9, 0xac, +0xb1,0x59,0x35,0x1f,0x36,0xb, 0x10,0xbc,0xf1,0x38,0xdb,0xe4,0x6c,0x77,0x7c,0x6d, +0x12,0x9f,0xa2,0x7c,0x7d,0x7c,0x6f,0x12,0x9f,0xa2,0x6c,0x0, 0x80,0x39,0x6c,0xee, +0x80,0x16,0x74,0x9, 0xac,0xbe,0x9, 0x65,0x1f,0x38,0x74,0x9, 0xac,0xb0,0x9, 0x75, +0x28,0xb2,0xbc,0x76,0x68,0x6, 0xb, 0xe0,0xbc,0x1e,0x38,0xe6,0xbc,0x1e,0x78,0x15, +0x7e,0x70,0x9, 0xac,0x70,0x12,0x7f,0xa0,0xac,0x31,0x2e,0x14,0x1f,0x34,0x74,0x9, +0x12,0x1f,0x8c,0xb, 0x10,0xb, 0x0, 0xbc,0xf0,0x38,0xc3,0x74,0x9, 0xac,0xbf,0xca, +0x59,0x7e,0x18,0x1f,0x34,0x7e,0x8, 0x29,0x62,0x12,0x20,0xc3,0x1b,0xfd,0xda,0x79, +0xda,0xd8,0x22,0xca,0x3b,0x7c,0x46,0x7c,0xab,0x6c,0x66,0x7c,0x57,0xe1,0x84,0x7e, +0xf0,0x9, 0xac,0xf6,0x9, 0x87,0x29,0x66,0x7c,0x98,0x7e,0xd0,0x9, 0xac,0xd5,0x9, +0xb6,0x28,0xb2,0xbc,0xb9,0x78,0x6b,0xbe,0x90,0xff,0x68,0x66,0x12,0x9f,0x98,0x39, +0x87,0x0, 0x4, 0xa, 0xf9,0x9, 0xbf,0x29,0xbc,0x7e,0xf0,0x9, 0x70,0xc, 0xac,0xf5, +0x7d,0x97,0x2e,0x94,0x28,0xae,0x6d,0x88,0x80,0xa, 0xac,0xf6,0x7d,0x97,0x2e,0x94, +0x29,0x62,0x6d,0x88,0xb, 0x4a,0xd0,0x12,0x9f,0x98,0x1b,0x7a,0xd0,0x69,0xf4,0x0, +0x2, 0x7e,0xf0,0x9, 0xac,0xfa,0x7f,0x60,0x2d,0xd7,0x79,0xf6,0x0, 0x2, 0x7e,0xf0, +0x9, 0xac,0xf5,0x9, 0x87,0x28,0xb3,0x12,0x9f,0x98,0x39,0x87,0x0, 0x5, 0x7e,0xf0, +0x9, 0xac,0xf5,0x9, 0x87,0x28,0xb4,0x12,0x9f,0x98,0x39,0x87,0x0, 0x6, 0xb, 0xa0, +0x80,0x8, 0xb, 0x50,0xbc,0x45,0x28,0x2, 0xc1,0xff,0xb, 0x60,0xbe,0x60,0xa, 0x50, +0x2, 0xc1,0xfb,0x7c,0xba,0xda,0x3b,0x22,0x7e,0xf0,0x9, 0xac,0xfa,0x7f,0x70,0x2d, +0xf7,0x22,0x7e,0x8, 0x1f,0x34,0x12,0x9e,0xf3,0x7c,0x1b,0x22,0x7c,0xab,0x7e,0xb, +0xb0,0x60,0x3, 0xb4,0x2, 0x31,0xa, 0x4a,0x9, 0x74,0x34,0xb8,0xbe,0x73,0x34,0xc2, +0x50,0xe, 0x7d,0x24,0x2e,0x24,0x34,0xb8,0x7c,0xb7,0x4, 0x7a,0x29,0xb0,0xd3,0x22, +0xbe,0x73,0x34,0xc2,0x40,0x9, 0xbe,0x70,0xff,0x68,0x4, 0xe4,0x7a,0xb, 0xb0,0x74, +0xff,0x19,0xb4,0x34,0xb8,0x80,0x17,0xa, 0x3a,0x9, 0xb3,0x34,0xb8,0xbe,0xb0,0xff, +0x68,0x7, 0xe4,0x19,0xb3,0x34,0xb8,0xd3,0x22,0xe4,0x19,0xb3,0x34,0xb8,0xc3,0x22, +0xca,0xf8,0x7c,0xfb,0x7d,0xf3,0x7e,0x17,0x2a,0x62,0xbd,0x13,0x38,0x6, 0x7e,0x34, +0x1, 0x0, 0x80,0x15,0x6d,0x22,0x7c,0x56,0x7c,0x67,0x6c,0x77,0x12,0x1f,0x5, 0xbe, +0x34,0x0, 0x10,0x50,0x4, 0x7e,0x34,0x0, 0x10,0x74,0x2, 0xac,0xbf,0x49,0x25,0x34, +0xc6,0xbd,0x2f,0x28,0x6, 0x49,0x35,0x34,0xa0,0x80,0x4, 0x59,0x35,0x34,0xa0,0x59, +0xf5,0x34,0xc6,0xbe,0x34,0x1, 0x0, 0x28,0x4, 0x7e,0x34,0x1, 0x0, 0xda,0xf8,0x22, +0xca,0x69,0xca,0xf8,0x7e,0xa3,0x2a,0x2, 0x7e,0x8, 0x29,0xbc,0x4c,0xaa,0x78,0x5, +0x12,0x24,0x66,0x21,0x9d,0x6c,0x99,0x7e,0x70,0x9, 0xac,0x79,0x9, 0x83,0x29,0xc, +0xbe,0x80,0xff,0x78,0x2, 0x21,0x94,0xa, 0x28,0x9, 0xb2,0x34,0x8c,0x7a,0xb3,0x34, +0x89,0x9, 0xb2,0x34,0x96,0x7a,0xb3,0x34,0x8a,0x7f,0x60,0x2d,0xd2,0x7e,0x6b,0xf0, +0xbe,0xf0,0x2, 0x68,0x2, 0x21,0x57,0x12,0xa1,0xac,0x49,0x33,0x29,0x8, 0x12,0xa1, +0xb6,0x7e,0x70,0x4, 0xac,0x78,0x49,0x23,0x35,0x59,0x12,0xa1,0xa2,0x9d,0x32,0x12, +0x21,0xa, 0x7d,0xe3,0x7e,0x73,0x34,0x89,0xa, 0x27,0xbd,0x2f,0x28,0x55,0xbd,0x2e, +0x28,0x51,0x12,0xa1,0xac,0x7e,0xd0,0x9, 0xac,0xd9,0x59,0x26,0x29,0x8, 0x7e,0x50, +0x4, 0xac,0x58,0x49,0x22,0x35,0x59,0x7e,0xd0,0x9, 0xac,0xd9,0x59,0x26,0x29,0xa, +0xbe,0xa0,0x0, 0x28,0x2, 0x1b,0xa0,0x4c,0xaa,0x78,0x5c,0x7e,0xb3,0x34,0x8a,0x4, +0x7a,0xb3,0x34,0x8a,0x7e,0x63,0x34,0x8a,0xbe,0x60,0x32,0x40,0x4a,0x74,0x1e,0x7a, +0xb3,0x34,0x8a,0x7e,0xb3,0x34,0x89,0xbe,0xb0,0x6, 0x50,0x3b,0x4, 0x7a,0xb3,0x34, +0x89,0x80,0x34,0x7e,0x50,0x9, 0xac,0x59,0x49,0xb2,0x29,0x8, 0x7e,0xd0,0x4, 0xac, +0xd8,0x59,0xb6,0x35,0x57,0x49,0x22,0x29,0xa, 0x59,0x26,0x35,0x59,0xbe,0x70,0xa, +0x40,0x4, 0x74,0x6, 0x80,0x8, 0xbe,0x70,0x1, 0x28,0x7, 0x7c,0xb7,0x14,0x7a,0xb3, +0x34,0x89,0xe4,0x7a,0xb3,0x34,0x8a,0x7e,0xb3,0x34,0x89,0xa, 0x38,0x19,0xb3,0x34, +0x8c,0x7e,0xb3,0x34,0x8a,0x80,0x37,0x4c,0xff,0x78,0x1b,0x7e,0x70,0x9, 0xac,0x79, +0x49,0x33,0x29,0x8, 0x7e,0x50,0x4, 0xac,0x58,0x59,0x32,0x35,0x57,0x12,0xa1,0xa2, +0x59,0x32,0x35,0x59,0x80,0x1e,0x7e,0x6b,0xb0,0xb4,0x1, 0x18,0x7e,0xb3,0x2a,0x2, +0xbe,0xb0,0x0, 0x28,0xf, 0x74,0xa, 0xa, 0x38,0x19,0xb3,0x34,0x8c,0xe4,0xa, 0x38, +0x19,0xb3,0x34,0x96,0xb, 0x90,0xbe,0x90,0xa, 0x68,0x2, 0x1, 0x67,0xda,0xf8,0xda, +0x69,0x22,0x7e,0x70,0x9, 0xac,0x79,0x49,0x33,0x29,0xa, 0x22,0x7e,0x50,0x4, 0xac, +0x58,0x49,0x22,0x35,0x57,0x22,0x9d,0x32,0x12,0x21,0xa, 0x7d,0xf3,0x22,0xa2,0xa, +0x22,0xca,0x79,0x6c,0x88,0x80,0x6b,0x74,0x2, 0xac,0xb8,0x9, 0xf5,0x26,0xfa,0x9, +0x75,0x26,0xfb,0x7a,0x71,0x24,0x7c,0xbf,0x12,0x67,0xe2,0x50,0x53,0x6c,0xee,0x80, +0x4a,0xbc,0xe8,0x68,0x44,0x7e,0x70,0x2, 0xac,0x7e,0x12,0x8f,0xe8,0x6c,0x99,0x7e, +0xb3,0x2a,0x70,0x14,0xbe,0xb1,0x26,0x78,0x10,0xa, 0x2f,0xe5,0x25,0x12,0x44,0x5b, +0xbe,0x34,0x0, 0x1, 0x18,0x3, 0x7e,0x90,0x1, 0xbe,0x90,0x1, 0x78,0x1b,0x7c,0xbe, +0x12,0x6f,0x6b,0x7d,0xf3,0x7c,0xb8,0x12,0x6f,0x6b,0xbd,0x3f,0x8, 0x4, 0x7c,0xbe, +0x80,0x2, 0x7c,0xb8,0x6c,0x77,0x12,0x73,0x2e,0xb, 0xe0,0x12,0x97,0xbe,0x38,0xb1, +0xb, 0x80,0x7e,0x73,0x28,0x84,0xbc,0x78,0x38,0x8d,0xda,0x79,0x22,0xe4,0x7a,0xb3, +0x36,0x69,0x7e,0xb3,0x28,0x84,0x60,0x6, 0x7e,0xb3,0x36,0xe2,0x60,0x5, 0xe4,0x7a, +0xb3,0x36,0xe4,0x22,0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x14,0x23,0x1, 0x7e,0x4, +0x0, 0xff,0x69,0x30,0x0, 0x2, 0xb, 0xa, 0x20,0x7a,0x1d,0x2c,0x7e,0x73,0x2a,0x6d, +0xa, 0x37,0x3e,0x34,0xca,0x39,0x7f,0x16,0x7f,0x5, 0x12,0x20,0xc3,0x1b,0xfd,0x6c, +0xdd,0x12,0x87,0xb8,0x7a,0xb3,0x1f,0x34,0x6c,0xcc,0x80,0x4a,0x12,0xa3,0x2f,0x40, +0x43,0x12,0xa3,0x25,0x50,0x3e,0x12,0x87,0xc0,0xb, 0x1a,0x10,0x7d,0x3f,0x12,0x21, +0xa, 0x7d,0x3, 0x7d,0x31,0x12,0x21,0xa, 0xbd,0x30,0x58,0x2, 0x7d,0xf1,0xbe,0x15, +0x2a,0x8, 0x5, 0x7e,0x15,0x2a,0x80,0xb, 0x6d,0x0, 0x9e,0x5, 0x2a,0xbd,0x1, 0x8, +0x2, 0x7d,0x10,0x7d,0x31,0x1a,0x26,0x1a,0x24,0x2f,0x41,0x7e,0xb3,0x1f,0x34,0x4, +0x7a,0xb3,0x1f,0x34,0xb, 0xc0,0x12,0x57,0x75,0x38,0xb1,0x7e,0x73,0x1f,0x34,0x4c, +0x77,0x68,0x36,0x12,0x87,0xc9,0xbd,0x3e,0x8, 0x2, 0x7d,0x7f,0xbe,0x75,0x2a,0x8, +0x5, 0x7e,0x75,0x2a,0x80,0xb, 0x6d,0xee,0x9e,0xe5,0x2a,0xbd,0xe7,0x8, 0x2, 0x7d, +0x7e,0x6c,0xcc,0x80,0xf, 0x12,0xa3,0x2f,0x40,0x8, 0x12,0xa3,0x25,0x50,0x3, 0x12, +0x87,0xde,0xb, 0xc0,0x12,0x57,0x75,0x38,0xec,0xb, 0xd0,0xbe,0xd0,0x3, 0x50,0x2, +0x41,0x81,0xda,0x3b,0x22,0x7c,0x1d,0x2e,0x10,0x2d,0xa5,0xe7,0xbc,0xab,0x22,0xa, +0xec,0x9, 0xae,0x2a,0xb9,0x7c,0x1d,0x2e,0x10,0x2c,0xa5,0xe7,0xbc,0xab,0x22,0xca, +0x79,0x7e,0xb3,0x3, 0xfd,0x60,0x5f,0x7e,0xb3,0x2a,0x68,0x60,0x59,0x7e,0xf3,0x2a, +0x6f,0x7e,0xe3,0x2a,0x70,0x7e,0x1f,0x13,0x8a,0x7a,0x1d,0x24,0x74,0x2, 0xac,0xbe, +0x2d,0x35,0x1b,0x35,0x6c,0xaa,0x80,0xf, 0xb, 0x1a,0x40,0x7e,0x30,0x2, 0xac,0x3a, +0x59,0x41,0x1f,0x34,0x12,0xa3,0xa9,0xbc,0xfa,0x38,0xed,0x7e,0x8, 0x1f,0x34,0x7c, +0xbf,0x12,0x5e,0xa9,0x74,0x2, 0xac,0xbe,0x7e,0x1d,0x24,0x2d,0x35,0x1b,0x35,0x6c, +0xaa,0x80,0xf, 0x7e,0x30,0x2, 0xac,0x3a,0x49,0x11,0x1f,0x34,0x1b,0x1a,0x10,0x12, +0xa3,0xa9,0xbc,0xfa,0x38,0xed,0xda,0x79,0x22,0x7e,0x30,0x2, 0xac,0x3e,0x2d,0x31, +0xb, 0xa0,0x22,0x7e,0x63,0x2a,0x6e,0xc2,0x16,0x6c,0x33,0x80,0x48,0x7c,0x96,0xac, +0x93,0x2e,0x44,0x0, 0x17,0x7d,0x4, 0xb, 0x4, 0x7d,0x54,0x3e,0x54,0x7e,0x7f,0x13, +0x8a,0x2d,0xf5,0xb, 0x7a,0x50,0xbe,0x57,0x2a,0x5a,0x8, 0x27,0x7c,0xb3,0x12,0x67, +0x50,0x50,0x20,0x7d,0x50,0x3e,0x54,0x7e,0x7f,0x13,0x8a,0x7f,0x67,0x2d,0xd5,0xb, +0x6a,0x20,0x7d,0x54,0x3e,0x54,0x2d,0xf5,0xb, 0x7a,0x50,0xbd,0x52,0x8, 0x4, 0xd2, +0x16,0x80,0xa, 0xb, 0x30,0x7e,0x73,0x2a,0x75,0xbc,0x73,0x38,0xb0,0x30,0x16,0x5, +0xd2,0x0, 0x2, 0x67,0xa3,0x22,0x7e,0xb3,0x2b,0x1d,0xb4,0x1, 0x31,0x12,0xa4,0x4f, +0x7e,0x1f,0x39,0xda,0x7a,0x37,0x24,0xfa,0x7e,0x34,0xd, 0xc8,0x7a,0x37,0x24,0xf6, +0x12,0xa4,0x56,0x12,0xa4,0x5f,0xe4,0x7a,0xb3,0x24,0xf5,0x7e,0x34,0x0, 0x20,0x7a, +0x37,0x24,0xfc,0x7a,0xb3,0x24,0xf4,0x7e,0x8, 0x24,0xf2,0x2, 0xd, 0x7, 0x22,0xa9, +0xd1,0xcb,0xe4,0x2, 0x0, 0xe, 0x7e,0x73,0x2a,0x6d,0x7a,0x73,0x24,0xf2,0x22,0x7e, +0x73,0x2a,0x6e,0x7a,0x73,0x24,0xf3,0x22,0x7e,0x43,0x2a,0x6e,0x7e,0x53,0x2a,0x6d, +0xac,0x54,0x7e,0x17,0x28,0xa1,0x12,0xa4,0x4f,0x6d,0x0, 0x80,0x37,0x7d,0x40,0x3e, +0x44,0x7e,0x7f,0x39,0xda,0x2d,0xf4,0xb, 0x7a,0x30,0xbd,0x13,0x58,0x10,0x7d,0xf4, +0x2e,0xf4,0x8, 0xa, 0xb, 0xf8,0x50,0x9d,0x51,0x1b,0xf8,0x50,0x80,0x14,0x6d,0x55, +0x9d,0x51,0xbd,0x53,0x8, 0xc, 0x2e,0x44,0x8, 0xa, 0xb, 0x48,0x50,0x2d,0x51,0x1b, +0x48,0x50,0xb, 0x4, 0xbd,0x20,0x38,0xc5,0x22,0xca,0x3b,0x7e,0xf3,0x2a,0x6e,0x7e, +0xe3,0x2a,0x6f,0x7e,0xd3,0x2a,0x70,0x6c,0xcc,0x80,0x13,0x7c,0x7c,0xac,0x7f,0x3e, +0x34,0x7e,0xf, 0x13,0x8a,0x2d,0x13,0x7c,0xbd,0x12,0x5e,0xa9,0xb, 0xc0,0xbc,0xec, +0x38,0xe9,0xda,0x3b,0x22,0x6c,0xaa,0x7e,0x30,0x4, 0xac,0x3a,0x7d,0xf1,0x2e,0xf4, +0x60,0xb1,0x7e,0xe4,0x0, 0xff,0xb, 0x7a,0x20,0xbd,0x23,0x38,0xf, 0x2e,0x14,0x60, +0xb3,0x7e,0x4, 0x0, 0xff,0xb, 0xa, 0x20,0xbd,0x23,0x50,0x7, 0xb, 0xa0,0xbe,0xa0, +0x3, 0x40,0xd4,0x7c,0xba,0x22,0x12,0xa5,0x25,0xbe,0x34,0x4, 0xe2,0x28,0x3, 0xd2, +0x17,0x22,0xc2,0x17,0x22,0x6d,0x11,0xe4,0x12,0x0, 0x1e,0x6c,0xaa,0x80,0x5b,0x7e, +0x10,0x2, 0xac,0x1a,0x7e,0x7f,0x39,0xf4,0x2d,0xf0,0x69,0x27,0x1, 0x0, 0x69,0x37, +0x0, 0x80,0x9d,0x32,0x12,0x21,0xa, 0xbd,0x31,0x28,0x16,0x7e,0x70,0x2, 0xac,0x7a, +0x7e,0xf, 0x39,0xf4,0x2d,0x13,0x69,0x20,0x1, 0x0, 0x69,0x30,0x0, 0x80,0x12,0x4f, +0xcc,0x7e,0x10,0x2, 0xac,0x1a,0x7e,0x1f,0x39,0xf4,0x2d,0x30,0x69,0x1, 0x0, 0x80, +0xbe,0x4, 0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0x69,0x1, 0x1, 0x0, 0xbe,0x4, +0x7f,0xff,0x78,0x4, 0x7e,0x14,0x7f,0xff,0xb, 0xa0,0x7e,0xb3,0x2a,0x74,0xbc,0xba, +0x38,0x9d,0x7d,0x31,0x22,0x7e,0x60,0x4, 0x7e,0x27,0x3a,0x5, 0xbe,0x24,0x3, 0xe8, +0x28,0x3, 0x7e,0x60,0x8, 0x7e,0xb3,0x28,0xac,0xb4,0x1, 0x1a,0x7e,0x73,0x2f,0xaa, +0xbc,0x76,0x50,0xf, 0xe4,0x7a,0xb3,0x28,0xad,0x12,0x6c,0x5a,0x7e,0xb3,0x2f,0xaa, +0x4, 0x80,0x4, 0xe4,0x80,0x1, 0xe4,0x7a,0xb3,0x2f,0xaa,0x7e,0xb3,0x28,0xad,0xb4, +0x1, 0x17,0x7e,0xa3,0x2f,0xab,0xbe,0xa0,0x5, 0x50,0xa, 0xe4,0x7a,0xb3,0x28,0xad, +0x7c,0xba,0x4, 0x80,0x5, 0x74,0x5, 0x80,0x1, 0xe4,0x7a,0xb3,0x2f,0xab,0x22,0x6c, +0xaa,0x80,0x26,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x5, 0xf8,0x49,0x32,0x4, 0x0, +0x2d,0x31,0x59,0x32,0x5, 0xf8,0x30,0x6, 0xe, 0x49,0x12,0x4, 0x7e,0x49,0x32,0x6, +0x76,0x2d,0x31,0x59,0x32,0x6, 0x76,0xb, 0xa0,0x7e,0xb3,0x2a,0x74,0xa, 0x3b,0x7e, +0xb3,0x2a,0x73,0xa, 0x2b,0x2d,0x23,0xa, 0x3a,0xbd,0x32,0x48,0xc6,0x22,0x74,0x2, +0x7a,0xb3,0x2f,0xa9,0x74,0x1, 0x7a,0xb3,0x28,0xac,0x2, 0x26,0x11,0xd2,0x0, 0x6c, +0xaa,0x6c,0x77,0x80,0x1f,0x7e,0x63,0x2a,0x6e,0xa, 0x16,0xa, 0x27,0x2d,0x21,0x7c, +0x65,0x7e,0x50,0x2, 0xac,0x56,0x49,0x22,0x5, 0x7a,0xbe,0x24,0xfe,0xc, 0x58,0x2, +0xb, 0xa0,0xb, 0x70,0x7e,0xb3,0x2a,0x6d,0xbc,0xb7,0x38,0xd9,0xa, 0x2b,0x1e,0x24, +0xa, 0x3a,0xbd,0x32,0x8, 0x2, 0xc2,0x0, 0xa2,0x0, 0x22,0x7e,0x63,0x2a,0x6f,0x7e, +0xa3,0x2a,0x70,0x7e,0x70,0x1, 0x80,0x15,0xa, 0x17,0x7e,0xb3,0x2a,0x6e,0xa, 0x2b, +0x2d,0x21,0x3e,0x24,0x12,0xa6,0xc6,0x58,0x2, 0xd3,0x22,0xb, 0x70,0xa, 0x16,0x1b, +0x14,0xa, 0x27,0xbd,0x21,0x48,0xe1,0x7e,0x70,0x2, 0x80,0xe, 0x7e,0x50,0x2, 0xac, +0x57,0x12,0xa6,0xc6,0x58,0x2, 0xd3,0x22,0xb, 0x70,0xa, 0x1a,0x1b,0x15,0xa, 0x27, +0xbd,0x21,0x48,0xe8,0xc3,0x22,0x49,0x22,0x4, 0xfc,0xbe,0x24,0xff,0x6, 0x22,0x7e, +0xb3,0x37,0x75,0xb4,0x1, 0x3, 0x2, 0xa7,0x26,0x7e,0xb3,0x37,0xdb,0x4, 0x7a,0xb3, +0x37,0xdb,0x7e,0xb3,0x37,0x69,0xb4,0x2, 0x18,0x7e,0xb3,0x37,0xda,0x4, 0x7a,0xb3, +0x37,0xda,0xb4,0x1, 0x6, 0x74,0x1, 0x7a,0xb3,0x37,0xdb,0x74,0x1, 0x7a,0xb3,0x37, +0x69,0x7e,0x73,0x37,0xda,0xbe,0x70,0x3, 0x40,0xf, 0x74,0x1, 0x7a,0xb3,0x37,0x75, +0x12,0xa7,0x26,0x12,0xa7,0xd0,0x12,0xa7,0x2d,0x7e,0x73,0x37,0xdb,0xbe,0x70,0xa, +0x28,0x3, 0x2, 0xa7,0x2d,0x22,0x74,0x2, 0x7a,0xb3,0x37,0x69,0x22,0xe4,0x7a,0xb3, +0x37,0xdb,0x7a,0xb3,0x37,0xda,0x22,0x7e,0x73,0x37,0x69,0x7a,0x73,0x37,0xdf,0x7e, +0x47,0x39,0xd7,0xbe,0x44,0x0, 0x64,0x28,0x6, 0x74,0x1, 0x7a,0xb3,0x37,0x69,0xbe, +0x44,0x0, 0xc8,0x28,0x8, 0xe4,0x7a,0xb3,0x37,0x67,0x12,0xa7,0x26,0x7e,0x57,0x37, +0x6f,0xbd,0x54,0x50,0x4, 0x7a,0x47,0x37,0x6f,0x12,0xa7,0xc8,0x38,0xa, 0x12,0xa7, +0xc0,0x38,0x5, 0x12,0xa7,0xb8,0x28,0x34,0x12,0xa6,0xcf,0xbe,0x44,0x0, 0x32,0x50, +0x21,0x7e,0xb3,0x37,0x67,0x4, 0x7a,0xb3,0x37,0x67,0x7e,0x73,0x37,0x67,0xbe,0x70, +0x32,0x28,0x14,0x74,0x32,0x7a,0xb3,0x37,0x67,0x12,0x57,0xee,0x7a,0xb3,0x37,0xdc, +0x80,0x5, 0xe4,0x7a,0xb3,0x37,0x67,0x7d,0x34,0x2, 0xa8,0x35,0x2, 0xa7,0xaf,0x12, +0xa7,0x2d,0xe4,0x7a,0xb3,0x37,0x75,0x22,0x7e,0x73,0x26,0xf5,0xbe,0x70,0x0, 0x22, +0x7e,0x73,0x26,0xf4,0xbe,0x70,0x0, 0x22,0x7e,0x73,0x28,0x92,0xbe,0x70,0x0, 0x22, +0xe4,0x7a,0xb3,0x37,0x67,0x6d,0x33,0x6c,0xaa,0x7e,0x50,0xc, 0xac,0x5a,0x59,0x32, +0x37,0x7e,0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xf0,0xe4,0x7a,0xb3,0x37,0x68,0x6d,0x33, +0x7a,0x37,0x37,0x6f,0x7a,0x37,0x37,0x64,0x22,0x7e,0x37,0x39,0xd3,0x12,0x7e,0x3c, +0x7a,0x37,0x37,0xdd,0x6c,0xaa,0x80,0x24,0xbe,0xa0,0x4, 0x50,0x27,0xa, 0x3a,0x9, +0x63,0x37,0x76,0xbe,0x60,0x4, 0x50,0x12,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x42,0x39, +0xcd,0x7e,0x70,0xc, 0xac,0x67,0x59,0x43,0x37,0x80,0xb, 0xa0,0x7e,0xb3,0x37,0x73, +0xbc,0xba,0x38,0xd4,0x22,0xbe,0x34,0x1, 0xf4,0x28,0xd, 0x7e,0x53,0x37,0xdc,0xbe, +0x50,0x8, 0x50,0x3f,0x74,0x8, 0x80,0x37,0xbe,0x34,0x1, 0x90,0x28,0xd, 0x7e,0x53, +0x37,0xdc,0xbe,0x50,0x6, 0x50,0x2c,0x74,0x6, 0x80,0x24,0xbe,0x34,0x1, 0x2c,0x28, +0xd, 0x7e,0x53,0x37,0xdc,0xbe,0x50,0x4, 0x50,0x19,0x74,0x4, 0x80,0x11,0xbe,0x34, +0x0, 0xc8,0x28,0xf, 0x7e,0x73,0x37,0xdc,0xbe,0x70,0x2, 0x50,0x6, 0x74,0x2, 0x7a, +0xb3,0x37,0xdc,0x7e,0xb3,0x37,0xdc,0xbe,0xb0,0x0, 0x28,0x19,0x14,0x7a,0xb3,0x37, +0xdc,0x74,0x1, 0x7a,0xb3,0x16,0x92,0x7e,0x73,0x37,0xdc,0xbe,0x70,0x4, 0x28,0x5, +0xe4,0x7a,0xb3,0x16,0x91,0x22,0x7c,0x3b,0x7e,0x44,0xff,0xff,0x6c,0x22,0x80,0x2a, +0x12,0xa9,0x1f,0x68,0x23,0x7e,0x70,0xc, 0xac,0x72,0x12,0xaa,0x2f,0x7d,0x23,0x7e, +0x70,0xc, 0xac,0x72,0x59,0x23,0x37,0x82,0x49,0x3, 0x37,0x82,0x49,0x23,0x37,0x7e, +0xbd,0x20,0x50,0x4, 0x59,0x3, 0x37,0x7e,0xb, 0x20,0xbc,0x32,0x50,0xd2,0x6c,0xaa, +0x6c,0x22,0x80,0x18,0x12,0xa9,0x1f,0x68,0x11,0x7e,0x70,0xc, 0xac,0x72,0x49,0x3, +0x37,0x7e,0xbd,0x4, 0x50,0x4, 0x7d,0x40,0x7c,0xa2,0xb, 0x20,0xbc,0x32,0x50,0xe4, +0x7e,0x37,0x37,0x64,0xbe,0x37,0x37,0xdd,0x50,0x8, 0x7e,0x37,0x37,0xdd,0x7a,0x37, +0x37,0x64,0x12,0xaa,0x25,0x4d,0x33,0x78,0x3, 0x7e,0xa0,0xff,0x7c,0xba,0x22,0x7e, +0x10,0x5, 0xac,0x12,0x9, 0xb0,0x26,0x33,0xbe,0xb3,0x2b,0xf, 0x22,0xca,0x79,0x7e, +0xf0,0xff,0x12,0xaa,0x96,0x7e,0xb3,0x37,0x6b,0xb4,0x1, 0x8, 0x12,0x6a,0xaf,0xe4, +0x7a,0xb3,0x37,0x6b,0x7e,0xb3,0x37,0x6a,0x60,0x4, 0x74,0xff,0x41,0x22,0x7e,0xb3, +0x37,0x69,0xb4,0x2, 0x2, 0x80,0x2, 0x41,0x16,0x12,0xa7,0xc8,0x38,0xc, 0x12,0xa7, +0xc0,0x38,0x7, 0x12,0xa7,0xb8,0x38,0x2, 0x41,0x16,0x74,0x3, 0x12,0xa8,0xa6,0x7c, +0xeb,0x7e,0xb3,0x37,0x68,0x4, 0x7a,0xb3,0x37,0x68,0x74,0x3, 0x12,0xa8,0xa6,0x7c, +0xab,0xbe,0xa0,0xff,0x68,0x23,0xbe,0xe0,0xff,0x68,0x1c,0x7e,0x30,0xc, 0xac,0x3e, +0x49,0x21,0x37,0x7e,0xbe,0x24,0x1, 0xf4,0x28,0xf, 0x12,0xaa,0x25,0x3e,0x34,0xbd, +0x23,0x28,0x6, 0x7c,0xea,0x80,0x2, 0x7c,0xea,0xbe,0xe0,0xff,0x78,0x11,0xe4,0x7a, +0xb3,0x37,0x68,0x7a,0xb3,0x37,0x69,0x7a,0xb3,0x37,0x75,0x74,0xff,0x80,0x63,0x7e, +0x73,0x37,0x68,0xbe,0x70,0x4, 0x28,0x4e,0x74,0xc, 0xac,0xbe,0x49,0x35,0x37,0x7e, +0xbe,0x34,0x1, 0xf4,0x50,0x37,0x7e,0x37,0x37,0x64,0xbe,0x34,0x1, 0x2c,0x38,0xa, +0x7e,0x37,0x37,0x6f,0xbe,0x34,0x1, 0x2c,0x28,0x23,0x74,0x5, 0xac,0xbe,0x9, 0x75, +0x26,0x33,0xbe,0x73,0x2b,0xf, 0x68,0x15,0x7c,0xfe,0xbe,0xf0,0x4, 0x50,0x8, 0x12, +0x8b,0x16,0xbe,0xb0,0x4, 0x40,0x6, 0x74,0x1, 0x7a,0xb3,0x37,0x6b,0xe4,0x7a,0xb3, +0x37,0x75,0x7a,0xb3,0x37,0x69,0xbe,0xf0,0xff,0x68,0x5, 0xe4,0x7a,0xb3,0x37,0x68, +0x7c,0xbf,0xda,0x79,0x22,0x7e,0x70,0xc, 0xac,0x7a,0x49,0x33,0x37,0x7e,0x22,0x49, +0x23,0x37,0x84,0x49,0x33,0x37,0x80,0x9d,0x32,0x2, 0x21,0xa, 0x6c,0xaa,0x7e,0x70, +0xc, 0xac,0x7a,0x12,0xaa,0x2f,0xbe,0x34,0x3, 0xe8,0x8, 0x5, 0x12,0xaa,0x88,0x80, +0x2f,0x7e,0x50,0xc, 0xac,0x5a,0x49,0x32,0x37,0x84,0x49,0x12,0x37,0x80,0xbd,0x13, +0x28,0xf, 0x7d,0x2, 0x2e,0x4, 0x37,0x84,0x7d,0x13,0xb, 0x15,0x1b,0x8, 0x10,0x80, +0xf, 0xbe,0x34,0x0, 0x2, 0x28,0x9, 0x2e,0x24,0x37,0x84,0x1b,0x35,0x1b,0x28,0x30, +0xb, 0xa0,0xbe,0xa0,0x4, 0x40,0xb7,0x22,0x7e,0x50,0xc, 0xac,0x5a,0x49,0x32,0x37, +0x80,0x59,0x32,0x37,0x84,0x22,0x7e,0xb3,0x37,0x6a,0xb4,0x1, 0x27,0x7e,0xb3,0x37, +0xe0,0x4, 0x7a,0xb3,0x37,0xe0,0x7e,0x73,0x37,0xe0,0xbe,0x70,0x3, 0x40,0x15,0x12, +0x57,0x9f,0x7e,0x73,0x37,0xe0,0xbe,0x70,0x6, 0x40,0x9, 0xe4,0x7a,0xb3,0x37,0xe0, +0x7a,0xb3,0x37,0x6a,0x22,0x12,0x4f,0xee,0x12,0xaa,0xfe,0x7e,0x8, 0x2a,0x88,0x7e, +0xb3,0x2a,0x87,0x12,0xaa,0xf7,0x7e,0x8, 0x2b,0x2f,0x7e,0xb3,0x2b,0x2e,0x12,0xaa, +0xf7,0x7e,0x8, 0x2a,0x8a,0xe5,0x25,0x12,0x8f,0xc7,0x7e,0x8, 0x2b,0x31,0xe5,0x24, +0x7e,0x34,0x0, 0x3, 0x2, 0x20,0xe8,0x7e,0x34,0x0, 0x2, 0x2, 0x20,0xe8,0x6c,0xaa, +0xe4,0xa, 0x4b,0x9, 0x94,0x2a,0x7a,0xbc,0x9a,0x68,0x6, 0x4, 0xbe,0xb0,0xe, 0x40, +0xf0,0xbe,0xb0,0xe, 0x68,0x7, 0xb, 0xa0,0xbe,0xa0,0x23,0x40,0xe3,0x7a,0xb, 0xa0, +0x74,0x6e,0x7a,0x1b,0xb0,0x22,0x7e,0x8, 0x37,0x7a,0x7e,0x34,0x0, 0x60,0xe4,0x12, +0x20,0xe8,0x6c,0xaa,0x7e,0x44,0xff,0xff,0x7e,0x70,0xc, 0xac,0x7a,0x59,0x43,0x37, +0x7c,0x59,0x43,0x37,0x84,0xb, 0xa0,0xbe,0xa0,0x8, 0x40,0xe8,0x7e,0x8, 0x37,0x68, +0x7e,0x34,0x0, 0xd, 0xe4,0x2, 0x20,0xe8,0x12,0x47,0xe2,0x7e,0xb3,0x37,0x71,0xbe, +0xb0,0x1, 0x68,0x6, 0x7e,0xb3,0x37,0xed,0x60,0x10,0x7e,0x34,0x0, 0xf0,0x7a,0x37, +0x2a,0x5a,0x7e,0x34,0x0, 0xc8,0x7a,0x37,0x2a,0x5c,0x7e,0xb3,0x28,0xa8,0xb4,0x1, +0x24,0x7e,0x34,0x1, 0x18,0x7a,0x37,0x2a,0x5a,0x7e,0x34,0x0, 0xfa,0x7a,0x37,0x2a, +0x5c,0x7e,0x34,0x1, 0x40,0x7a,0x37,0x2a,0x4f,0x7a,0x37,0x2a,0x51,0x7e,0x34,0x1, +0x7c,0x7a,0x37,0x2a,0x53,0x7e,0xb3,0x2a,0x2, 0x70,0x21,0x7e,0x27,0x2a,0x5a,0x7d, +0x32,0x7e,0x14,0x0, 0x4, 0xad,0x13,0x7d,0x31,0x12,0x7e,0x3c,0xbe,0x34,0x0, 0x50, +0x28,0x4, 0x7e,0x34,0x0, 0x50,0x2d,0x32,0x7a,0x37,0x2a,0x5a,0x22,0x6d,0x33,0x7d, +0x23,0x7d,0x3, 0x6c,0x33,0x80,0x45,0x6c,0x22,0x80,0x37,0x7e,0xb3,0x2a,0x6e,0xac, +0xb3,0xa, 0x42,0x2d,0x54,0x7d,0x45,0x3e,0x44,0x7e,0x7f,0x13,0x8a,0x2d,0xf4,0xb, +0x7a,0x40,0xbe,0x44,0x0, 0x32,0x8, 0x8, 0xbe,0x44,0x2, 0x58,0x58,0x2, 0xb, 0x24, +0xbe,0x44,0xff,0xce,0x58,0x8, 0xbe,0x44,0xfd,0xa8,0x8, 0x2, 0xb, 0x4, 0xb, 0x34, +0xb, 0x21,0x7e,0x93,0x2a,0x6e,0xbc,0x92,0x38,0xc1,0xb, 0x31,0x7e,0xb3,0x2a,0x6d, +0xbc,0xb3,0x38,0xb3,0x7e,0x54,0x0, 0x6, 0xad,0x53,0x7d,0x15,0x1e,0x14,0x1e,0x14, +0x1e,0x14,0x12,0x7e,0x3e,0xbd,0x12,0x50,0x22,0xbd,0x30,0x28,0x1e,0xe4,0x7a,0xb3, +0x3a,0x9, 0x7e,0xb3,0x3a,0xa, 0xbe,0xb0,0x5, 0x50,0x7, 0x4, 0x7a,0xb3,0x3a,0xa, +0x80,0x3c,0xe4,0x7a,0xb3,0x3a,0xa, 0x74,0x1, 0x80,0x2f,0xbd,0x10,0x50,0x22,0xbd, +0x32,0x28,0x1e,0xe4,0x7a,0xb3,0x3a,0xa, 0x7e,0xb3,0x3a,0x9, 0xbe,0xb0,0x5, 0x50, +0x7, 0x4, 0x7a,0xb3,0x3a,0x9, 0x80,0x16,0xe4,0x7a,0xb3,0x3a,0x9, 0x74,0x2, 0x80, +0x9, 0xe4,0x7a,0xb3,0x3a,0x9, 0x7a,0xb3,0x3a,0xa, 0x7a,0xb3,0x3a,0xb, 0x7e,0xb3, +0x3a,0xb, 0x22,0x6c,0x66,0x7e,0xb3,0x28,0xa8,0xb4,0x1, 0x63,0x7e,0x73,0x26,0xf2, +0xbe,0x70,0x0, 0x28,0x5a,0x6c,0x33,0x80,0x4e,0xa, 0x23,0x9, 0x72,0x26,0xe6,0x7e, +0xb3,0x2a,0x6e,0x14,0xbc,0x7b,0x78,0x3d,0x6c,0x22,0x80,0x27,0x7c,0xb2,0x7c,0x73, +0x12,0x67,0xe2,0x50,0x1c,0xa, 0x22,0x7e,0x73,0x2a,0x6e,0xa, 0x7, 0x2d,0x2, 0x3e, +0x4, 0x49,0x20,0x4, 0xfc,0x6d,0x0, 0x9e,0x7, 0x2a,0x4f,0xbd,0x20,0x58,0x2, 0xb, +0x60,0xb, 0x20,0x7e,0x73,0x2a,0x6d,0xbc,0x72,0x38,0xd1,0xbe,0x60,0x0, 0x28,0x3, +0x74,0x1, 0x22,0xe4,0x22,0xb, 0x30,0x7e,0x73,0x26,0xf2,0xbc,0x73,0x38,0xaa,0x74, +0x1, 0x22,0x7c,0xab,0xbe,0xa0,0x0, 0x40,0x11,0x7e,0xb3,0x2a,0x6e,0xbc,0xba,0x28, +0x9, 0x74,0x2, 0xa4,0x49,0x25,0x34,0x0, 0x80,0x51,0x7e,0x13,0x2a,0x6e,0xbc,0x1a, +0x38,0x1c,0x7e,0x3, 0x2a,0x6d,0xa, 0x10,0xa, 0x21,0x2d,0x12,0xa, 0x3a,0xbd,0x31, +0x58,0xc, 0x9d,0x32,0x3e,0x34,0x3e,0x34,0x49,0x23,0x3, 0x70,0x80,0x2d,0x7e,0x3, +0x2a,0x6d,0xa, 0x20,0xa, 0x11,0x7d,0x41,0x2d,0x42,0xa, 0x3a,0xbd,0x34,0x48,0x19, +0x7e,0x10,0x2, 0xac,0x1, 0x2d,0x1, 0xbd,0x30,0x58,0xe, 0x9d,0x31,0x9d,0x32,0x3e, +0x34,0x3e,0x34,0x49,0x23,0x3, 0x72,0x80,0x2, 0xe4,0x22,0x7e,0x34,0x0, 0x64,0xad, +0x23,0x74,0xc, 0x1e,0x34,0x1e,0x24,0x50,0x3, 0x4e,0x60,0x80,0x14,0x78,0xf4,0x7c, +0xb7,0x22,0xca,0xf8,0x80,0x38,0x7c,0xbf,0x12,0xad,0x2, 0xa, 0x1b,0x7e,0x63,0x2a, +0x6e,0x7e,0x70,0x2, 0xac,0x67,0x7e,0x10,0x2, 0xac,0x1f,0x2d,0x3, 0x7e,0x1f,0x13, +0x8a,0x2d,0x30,0x12,0xad,0xc1,0x9d,0x35,0x1b,0x1a,0x10,0xb, 0xf0,0x12,0xad,0xc1, +0x7e,0x73,0x2a,0x6e,0xa, 0x27,0x2d,0x25,0xa, 0x3f,0xbd,0x32,0x48,0xc8,0xda,0xf8, +0x22,0x7e,0xa3,0x2a,0x6d,0x74,0x2, 0xa4,0x22,0xc2,0x0, 0x12,0x44,0xc4,0x50,0x42, +0x6c,0xaa,0x80,0x30,0x7e,0x50,0x2, 0xac,0x5a,0x9, 0x72,0x26,0xfa,0x9, 0x62,0x26, +0xfb,0xbe,0x70,0x0, 0x40,0x1c,0x7e,0xb3,0x2a,0x6f,0xa, 0x1b,0x1b,0x14,0xa, 0x27, +0xbd,0x21,0x18,0xe, 0xbe,0x60,0x0, 0x40,0x9, 0xbe,0x60,0xf, 0x38,0x4, 0xd2,0x0, +0x80,0xa, 0xb, 0xa0,0x7e,0xb3,0x28,0x84,0xbc,0xba,0x38,0xc8,0x20,0x0, 0x3, 0x12, +0x6c,0x48,0x30,0x1a,0x14,0x5, 0x5d,0xe5,0x5d,0xbe,0xb0,0x50,0x50,0x7, 0x7e,0x34, +0x0, 0x8, 0x2, 0x5f,0xcc,0xc2,0x1a,0x80,0x0, 0x75,0x5d,0x0, 0x22,0xca,0x3b,0x7c, +0xfb,0x75,0x3d,0x0, 0x7e,0xb3,0x2a,0x6f,0xf5,0x42,0x7e,0xb3,0x2a,0x70,0xf5,0x43, +0x75,0x44,0x28,0x7e,0xd3,0x28,0x84,0xe4,0x7a,0xb3,0x31,0xcf,0x7a,0xb3,0x31,0xcb, +0x7a,0xb3,0x31,0xcc,0x7e,0x8, 0x31,0xd0,0x7e,0x34,0x0, 0x1e,0x12,0x20,0xe8,0x7e, +0x8, 0x31,0xf0,0x7e,0x34,0x0, 0x3c,0x12,0x20,0xe8,0xbe,0xd0,0x2, 0x50,0x3, 0x2, +0xb2,0x15,0x6c,0xcc,0x2, 0xb2,0xe, 0x12,0x97,0xd4,0xf5,0x24,0x9, 0xb3,0x26,0xfb, +0xf5,0x25,0x4c,0xcc,0x68,0x8, 0xa, 0x3c,0x9, 0xb3,0x31,0xd0,0x70,0xa, 0xa, 0x3c, +0xb, 0x34,0xa, 0x2c,0x19,0x72,0x31,0xd0,0x7c,0xbd,0x14,0xbc,0xbc,0x78,0x3, 0x2, +0xb2,0x15,0xa, 0x5c,0xb, 0x54,0xf5,0x2e,0x2, 0xb2,0x4, 0x7e,0x71,0x2e,0x12,0xb5, +0x9e,0x7a,0xa1,0x26,0x9, 0xb3,0x26,0xfb,0xf5,0x27,0xa, 0x2a,0xe5,0x24,0x12,0x44, +0x5b,0x7c,0xb7,0xf5,0x28,0xe5,0x27,0xa, 0x2b,0xe5,0x25,0x12,0x44,0x5b,0x7c,0xb7, +0xf5,0x29,0xe5,0x28,0xbe,0xb0,0x5, 0x40,0x3, 0x2, 0xb2,0x2, 0xe5,0x29,0xbe,0xb0, +0x5, 0x40,0x3, 0x2, 0xb2,0x2, 0x12,0xb2,0x18,0x12,0x94,0x83,0x7a,0xb3,0x31,0xce, +0x85,0x25,0x54,0x85,0x26,0x55,0x85,0x27,0x56,0x7e,0x8, 0x0, 0x31,0x7e,0x18,0x0, +0x33,0xe5,0x24,0x12,0xb3,0x37,0x75,0x3d,0x0, 0x6c,0xee,0x75,0x30,0x0, 0xe5,0x24, +0x7e,0x71,0x25,0x12,0x6d,0xcb,0x7a,0x35,0x35,0xe5,0x26,0x7e,0x71,0x27,0x12,0x6d, +0xcb,0x7a,0x35,0x37,0x7e,0x35,0x35,0xbe,0x35,0x37,0x8, 0x5, 0x7e,0x35,0x37,0x80, +0x3, 0x7e,0x35,0x35,0x7a,0x35,0x3b,0xe, 0x34,0x7a,0x35,0x39,0xe5,0x28,0xbe,0xb0, +0x1, 0x38,0x2e,0xe5,0x29,0xbe,0xb0,0x1, 0x38,0x27,0x7c,0xbf,0x30,0xe1,0x22,0xe5, +0x26,0x7e,0x71,0x25,0x12,0x6d,0xcb,0x7d,0x43,0xe5,0x24,0x7e,0x71,0x27,0x12,0x6d, +0xcb,0x2d,0x34,0xbe,0x35,0x39,0x18,0x3, 0x2, 0xb1,0x99,0x75,0x30,0x1, 0x2, 0xb1, +0x99,0xe5,0x28,0xbe,0xb0,0x1, 0x38,0xa, 0xe5,0x29,0xbe,0xb0,0x1, 0x38,0x3, 0x2, +0xb1,0x99,0xe5,0x28,0xbe,0xb0,0x5, 0x40,0x3, 0x2, 0xb1,0x99,0xe5,0x29,0xbe,0xb0, +0x5, 0x40,0x3, 0x2, 0xb1,0x99,0x7c,0xbf,0x20,0xe0,0x3, 0x2, 0xb1,0x99,0x6d,0x33, +0x7a,0x35,0x4d,0x75,0x4f,0x0, 0x7a,0x35,0x50,0x75,0x52,0x0, 0xc2,0x2, 0xc2,0x3, +0xe5,0x26,0xbe,0xb1,0x24,0x28,0x4, 0xe5,0x24,0x80,0x2, 0xe5,0x26,0xf5,0x2a,0xe5, +0x26,0xbe,0xb1,0x24,0x50,0x4, 0xe5,0x24,0x80,0x2, 0xe5,0x26,0xf5,0x2c,0xe5,0x27, +0xbe,0xb1,0x25,0x28,0x4, 0xe5,0x25,0x80,0x2, 0xe5,0x27,0xf5,0x2b,0xe5,0x27,0xbe, +0xb1,0x25,0x50,0x4, 0xe5,0x25,0x80,0x2, 0xe5,0x27,0xf5,0x2d,0xe5,0x2c,0xbe,0xb1, +0x2a,0x78,0x29,0xd2,0x2, 0xe5,0x2a,0x60,0x8, 0xe5,0x42,0x14,0xbe,0xb1,0x2a,0x78, +0x2, 0xd2,0x3, 0xe5,0x2a,0xbe,0xb0,0x0, 0x28,0x2, 0x15,0x2a,0xe5,0x42,0xa, 0x2b, +0x1b,0x24,0xe5,0x2c,0xa, 0x3b,0xbd,0x32,0x58,0x2, 0x5, 0x2c,0xe5,0x2d,0xbe,0xb1, +0x2b,0x78,0x29,0xd2,0x2, 0xe5,0x2b,0x60,0x8, 0xe5,0x43,0x14,0xbe,0xb1,0x2b,0x78, +0x2, 0xd2,0x3, 0xe5,0x2b,0xbe,0xb0,0x0, 0x28,0x2, 0x15,0x2b,0xe5,0x43,0xa, 0x2b, +0x1b,0x24,0xe5,0x2d,0xa, 0x3b,0xbd,0x32,0x58,0x2, 0x5, 0x2d,0x85,0x2a,0x3e,0x80, +0x5b,0x85,0x2b,0x3f,0x80,0x4d,0xe5,0x3e,0x7e,0x71,0x3f,0x12,0x6d,0xcb,0x7a,0x35, +0x40,0xe5,0x2a,0xbe,0xb1,0x3e,0x68,0x15,0xe5,0x2c,0xbe,0xb1,0x3e,0x68,0xe, 0xe5, +0x2b,0xbe,0xb1,0x3f,0x68,0x7, 0xe5,0x2d,0xbe,0xb1,0x3f,0x78,0xd, 0x7e,0x35,0x40, +0x2e,0x35,0x4d,0x7a,0x35,0x4d,0x5, 0x4f,0x80,0x17,0x5, 0x52,0x7e,0x35,0x40,0x2e, +0x35,0x50,0x7a,0x35,0x50,0x7e,0x35,0x33,0xbe,0x35,0x40,0x58,0x2, 0x5, 0x3d,0xb, +0xe0,0x5, 0x3f,0xe5,0x2d,0xbe,0xb1,0x3f,0x50,0xac,0x5, 0x3e,0xe5,0x2c,0xbe,0xb1, +0x3e,0x50,0x9e,0xe5,0x2c,0x7e,0x71,0x2b,0x12,0x6d,0xcb,0x7e,0x45,0x4d,0x9d,0x43, +0xe5,0x2a,0x7e,0x71,0x2d,0x12,0x6d,0xcb,0x9d,0x43,0xe5,0x2a,0x7e,0x71,0x2b,0x12, +0x6d,0xcb,0x9d,0x43,0xe5,0x2c,0x7e,0x71,0x2d,0x12,0x6d,0xcb,0x7d,0x23,0x7d,0x34, +0x9d,0x32,0x7a,0x35,0x4d,0x7e,0x35,0x37,0x2e,0x35,0x35,0x7a,0x35,0x39,0x30,0x2, +0x10,0x20,0x3, 0xd, 0x7e,0x35,0x4d,0x9e,0x35,0x39,0x7a,0x35,0x4d,0x15,0x4f,0x15, +0x4f,0xe5,0x4f,0xbe,0xb0,0x4, 0x28,0x6, 0xe5,0x4f,0x24,0xfc,0xf5,0x4f,0x7e,0x35, +0x4d,0xbe,0x34,0x0, 0x0, 0x58,0x5, 0x6d,0x33,0x7a,0x35,0x4d,0x75,0x44,0x28,0xe5, +0x42,0x14,0xbe,0xb1,0x24,0x68,0xd, 0xbe,0xb1,0x26,0x68,0x8, 0xe5,0x24,0x60,0x4, +0xe5,0x26,0x70,0x8, 0x12,0xb3,0x2f,0x28,0x3, 0x75,0x44,0x2c,0x7e,0x15,0x50,0x1a, +0x2, 0x1a,0x0, 0x7e,0x35,0x4d,0x1a,0x26,0x1a,0x24,0x2f,0x10,0xe5,0x44,0xa, 0x1b, +0x6d,0x0, 0x12,0x1e,0xeb,0x7f,0x71,0x7a,0x7d,0x45,0x7e,0x15,0x39,0x1a,0x2, 0x1a, +0x0, 0x7e,0x35,0x31,0x1a,0x26,0x1a,0x24,0x12,0x1e,0xeb,0xe5,0x52,0xa, 0xdb,0x6d, +0xcc,0xe5,0x4f,0xa, 0x1b,0x6d,0x0, 0x2f,0x6, 0x12,0x1e,0xeb,0x7a,0x1d,0x49,0xbf, +0x71,0x8, 0x3, 0x75,0x30,0x2, 0xc2,0x1, 0x20,0xc, 0xe, 0x12,0xb2,0x18,0x12,0xb2, +0x24,0x92,0x1, 0x20,0x1, 0x3, 0x75,0x30,0x0, 0xe5,0x30,0xbe,0xb0,0x0, 0x28,0x62, +0xe5,0x30,0xa, 0x3b,0x2e,0x34,0x31,0xca,0x7e,0x39,0xb0,0x4, 0x7a,0x39,0xb0,0xe5, +0x2e,0xa, 0x3b,0x9, 0xa3,0x31,0xd0,0x4c,0xaa,0x78,0xc, 0xa, 0x2c,0x9, 0xb2,0x31, +0xd0,0x19,0xb3,0x31,0xd0,0x80,0x3b,0xa, 0x2c,0x9, 0xb2,0x31,0xd0,0xf5,0x53,0xbc, +0xba,0x28,0x3, 0x7a,0xa1,0x53,0x75,0x2f,0x0, 0x80,0x22,0x9, 0x33,0x31,0xd0,0xe5, +0x2f,0xa, 0x2b,0x9, 0x22,0x31,0xd0,0xbc,0x23,0x68,0xa, 0xa, 0xc, 0x9, 0x30,0x31, +0xd0,0xbc,0x23,0x78,0x6, 0xe5,0x53,0x19,0xb2,0x31,0xd0,0x5, 0x2f,0xbe,0xd1,0x2f, +0x38,0xd9,0x5, 0x2e,0xbe,0xd1,0x2e,0x28,0x3, 0x2, 0xae,0xab,0xb, 0xc0,0xbc,0xdc, +0x28,0x3, 0x2, 0xae,0x77,0xda,0x3b,0x22,0xe5,0x24,0x7e,0x71,0x25,0x7e,0x61,0x26, +0x7e,0x51,0x27,0x22,0x12,0xb2,0x50,0x92,0x4, 0x30,0x4, 0xc, 0x7e,0xb3,0x32,0x2c, +0xbe,0xb0,0xfa,0x50,0x11,0x4, 0x80,0xa, 0x7e,0xb3,0x32,0x2c,0xbe,0xb0,0x0, 0x28, +0x5, 0x14,0x7a,0xb3,0x32,0x2c,0x7e,0xb3,0x32,0x2c,0x70,0x2, 0xc3,0x22,0xd3,0x22, +0xca,0x3b,0x7c,0x45,0x7c,0x6, 0x7c,0x57,0x7c,0x1b,0x7e,0x34,0x4, 0xfc,0x7e,0xb3, +0x26,0x83,0x7e,0xf3,0x2a,0x6e,0x7c,0x31,0x7c,0xe0,0x7c,0x25,0x7c,0xa4,0xbc,0x1, +0x50,0x4, 0x7c,0x30,0x7c,0xe1,0xbc,0x45,0x50,0x4, 0x7c,0x24,0x7c,0xa5,0xbe,0xb0, +0x1, 0x50,0x2, 0x61,0x15,0x7e,0x90,0x2, 0xac,0x9f,0x7e,0x50,0x2, 0xac,0x53,0x2d, +0x24,0x2d,0x23,0xb, 0x28,0x20,0x7e,0x10,0x2, 0xac,0x1e,0x2d,0x4, 0x2d,0x3, 0xb, +0x8, 0x40,0xa, 0x3, 0xb, 0x4, 0x7c,0x31,0x80,0x28,0x7e,0xd0,0x2, 0xac,0xdf,0x7e, +0x10,0x2, 0xac,0x13,0x2d,0x6, 0x12,0xb3,0x19,0x58,0x15,0xad,0xf4,0xbd,0xdf,0x58, +0xf, 0xbe,0x24,0x0, 0x0, 0x8, 0x9, 0xbe,0x44,0x0, 0x0, 0x8, 0x3, 0xc3,0x80,0x46, +0xb, 0x30,0xbc,0xe3,0x38,0xd4,0x7e,0x50,0x2, 0xac,0x52,0x2d,0x23,0xb, 0x28,0x20, +0x7e,0x90,0x2, 0xac,0x9a,0x2d,0x43,0xb, 0x48,0x40,0xa, 0x12,0xb, 0x14,0x80,0x21, +0x7e,0x10,0x2, 0xac,0x13,0x12,0xb3,0x19,0x58,0x15,0xad,0xf4,0xbd,0xdf,0x58,0xf, +0xbe,0x24,0x0, 0x0, 0x8, 0x9, 0xbe,0x44,0x0, 0x0, 0x8, 0x3, 0xc3,0x80,0x7, 0xb, +0x30,0xbc,0xa3,0x38,0xdb,0xd3,0xda,0x3b,0x22,0x2d,0x3, 0xb, 0x8, 0x0, 0x7e,0xf4, +0x0, 0x9, 0x7d,0xb2,0xad,0xbf,0x7e,0xd4,0x0, 0xa, 0xad,0xd0,0xbd,0xdb,0x22,0x7e, +0x73,0x31,0xce,0xbe,0x70,0x5, 0x22,0xca,0xf8,0x7c,0xfb,0x7f,0x61,0x7f,0x50,0x7e, +0x34,0x22,0xd7,0x7e,0x24,0x0, 0xff,0x7e,0x14,0x1f,0x70,0x74,0x2a,0x12,0x1f,0xad, +0x7e,0x48,0x1f,0x70,0x12,0xb3,0xc6,0x92,0xc, 0x7c,0xbf,0x7e,0x71,0x54,0x12,0x6d, +0xcb,0x7d,0x43,0xe5,0x55,0x7e,0x71,0x56,0x12,0x6d,0xcb,0x2d,0x34,0xe, 0x34,0x7f, +0x4, 0x7e,0x50,0x7, 0xb, 0xa, 0x50,0xbd,0x53,0x58,0x10,0x69,0x30,0x0, 0x2, 0x1b, +0x5a,0x30,0x69,0x30,0x0, 0x4, 0x1b,0x6a,0x30,0x80,0x8, 0x2e,0x14,0x0, 0x6, 0x1b, +0x50,0x78,0xe1,0x12,0xb3,0x2f,0x28,0x2b,0xb, 0x5a,0x20,0x7e,0x34,0x0, 0xd, 0xad, +0x32,0x7e,0x24,0x0, 0x10,0x12,0x1e,0xb9,0x1b,0x5a,0x30,0xb, 0x6a,0x30,0x1a,0x26, +0x1a,0x24,0x7e,0x14,0x0, 0xd, 0x12,0x1e,0xfc,0x7e,0x8, 0x0, 0x10,0x12,0x1f,0x58, +0x1b,0x6a,0x30,0xda,0xf8,0x22,0x7e,0x37,0x28,0x8a,0xbe,0x34,0x2, 0x58,0x8, 0xa, +0x12,0x97,0x99,0xbe,0xb0,0x8, 0x48,0x2, 0xd3,0x22,0xc3,0x22,0x6c,0xaa,0x12,0x97, +0xea,0x29,0x81,0x0, 0x5, 0x7c,0x98,0x5e,0x90,0x1, 0x3e,0x90,0x7f,0x1, 0x2e,0x14, +0x0, 0x5, 0x7c,0xb8,0x54,0xfd,0x4c,0xb9,0x7a,0xb, 0xb0,0x29,0xb1,0x0, 0x5, 0x30, +0xe0,0x16,0x30,0xe2,0x13,0xc4,0x23,0x54,0x1f,0xb4,0x1, 0xc, 0x7f,0x1, 0xb, 0x16, +0x7e,0xb, 0xb0,0x1e,0xb0,0x7a,0xb, 0xb0,0xb, 0xa0,0xbe,0xa0,0x1e,0x40,0xbf,0x22, +0xca,0x3b,0x7f,0x40,0x7e,0xe3,0x28,0x84,0x6c,0xdd,0x7e,0xc0,0x1, 0x80,0x1a,0xa, +0x3d,0x2d,0x39,0x7d,0x28,0x7e,0x1b,0x60,0xa, 0x2c,0x7f,0x4, 0x2d,0x12,0x7e,0xb, +0x70,0xbc,0x76,0x40,0x2, 0x7c,0xdc,0xb, 0xc0,0xbc,0xec,0x38,0xe2,0xa, 0x3d,0x2d, +0x39,0x7d,0x28,0x7e,0x1b,0xd0,0x6c,0xff,0x7e,0xc0,0x1, 0xa1,0x85,0x75,0x2d,0x0, +0x6d,0x33,0x7a,0x35,0x2e,0x7a,0x35,0x25,0x7a,0x35,0x27,0x7e,0x18,0x1f,0x70,0x7a, +0x1d,0x29,0x74,0xff,0x7e,0x34,0x1f,0x71,0x7e,0x24,0x0, 0x0, 0x7a,0x1b,0xb0,0x7e, +0x1d,0x29,0x7a,0x1b,0xb0,0xe4,0x7e,0x1d,0x29,0x39,0xb1,0x0, 0x3, 0x7e,0x1d,0x29, +0x39,0xb1,0x0, 0x2, 0x7e,0x1d,0x29,0x12,0x96,0xb3,0x44,0x1, 0x7a,0x1b,0xb0,0x75, +0x24,0x0, 0x80,0x6c,0x12,0xb5,0x9b,0x9, 0x93,0x26,0xfb,0xe5,0x24,0x12,0x44,0x62, +0xbc,0xbc,0x78,0x5a,0x5, 0x2d,0xa, 0x3a,0x2e,0x35,0x25,0x7a,0x35,0x25,0xa, 0x39, +0x2e,0x35,0x27,0x7a,0x35,0x27,0x12,0x6d,0xc7,0xbe,0x35,0x2e,0x8, 0x6, 0x12,0x6d, +0xc7,0x7a,0x35,0x2e,0x7e,0x1d,0x29,0x7e,0x1b,0xb0,0xbc,0xba,0x28,0x3, 0x7a,0x1b, +0xa0,0x7e,0x1d,0x29,0x29,0xb1,0x0, 0x2, 0xbc,0xba,0x50,0x4, 0x39,0xa1,0x0, 0x2, +0x7e,0x1d,0x29,0x29,0xb1,0x0, 0x1, 0xbc,0xb9,0x28,0x4, 0x39,0x91,0x0, 0x1, 0x7e, +0x1d,0x29,0x29,0xb1,0x0, 0x3, 0xbc,0xb9,0x50,0x4, 0x39,0x91,0x0, 0x3, 0x5, 0x24, +0xbe,0xe1,0x24,0x38,0x8f,0xe5,0x2d,0xbe,0xb0,0x0, 0x28,0x67,0x7e,0xd, 0x29,0x12, +0x94,0xd7,0xe5,0x2d,0xa, 0x2b,0x7e,0x15,0x25,0x8d,0x12,0x7a,0x15,0x25,0x7e,0x35, +0x27,0x8d,0x32,0x7a,0x35,0x27,0x7e,0x55,0x25,0x12,0xb5,0x93,0x19,0xa3,0x31,0xf0, +0x7e,0x55,0x27,0x12,0xb5,0x93,0x19,0xa3,0x31,0xf1,0x7e,0x37,0x28,0x8a,0xbe,0x35, +0x2e,0x78,0xe, 0x7e,0x35,0x25,0x7a,0x73,0x28,0x8c,0x7e,0x35,0x27,0x7a,0x73,0x28, +0x8d,0x7e,0x37,0x31,0xee,0x4d,0x33,0x68,0x18,0x7e,0x55,0x25,0x7e,0x35,0x27,0x12, +0x6d,0xcb,0x7e,0x25,0x2e,0x7e,0x70,0x2, 0xac,0x7f,0x2e,0x37,0x31,0xee,0x1b,0x38, +0x20,0xb, 0xf0,0xb, 0xc0,0xbc,0xdc,0x40,0x2, 0x81,0x5d,0x12,0xb3,0xdc,0x7c,0xbf, +0xda,0x3b,0x22,0x7c,0xab,0x7e,0x70,0x2, 0xac,0x7f,0x22,0x7e,0x71,0x24,0x74,0x2, +0xac,0x7b,0x9, 0xa3,0x26,0xfa,0x22,0x7e,0x73,0x2a,0x71,0xa, 0x17,0x2e,0x14,0x0, +0x3, 0x7e,0xa3,0x2a,0x6e,0xa, 0x3a,0xad,0x13,0x7d,0x21,0x6c,0x33,0x80,0x20,0xa, +0x3, 0x2d,0x2, 0x3e,0x4, 0x7e,0x7f,0x39,0xda,0x2d,0xf0,0xb, 0x7a,0x0, 0x7e,0x90, +0x2, 0xac,0x93,0x49,0xf4,0x13,0x8e,0x9d,0xf, 0x59,0x4, 0x25,0xb6,0xb, 0x30,0xbc, +0xa3,0x38,0xdc,0x7a,0x35,0x34,0x7e,0xf, 0x38,0x41,0x7e,0x18,0x25,0xb6,0x2, 0x5d, +0xf1,0x6c,0xaa,0x80,0x1c,0x7e,0x50,0x2, 0xac,0x5a,0x49,0x12,0x13,0xc6,0x49,0x32, +0x13,0x8e,0xbd,0x31,0x28,0x9, 0x2e,0x24,0x13,0x8e,0x9d,0x31,0x1b,0x28,0x30,0xb, +0xa0,0x7e,0xb3,0x2a,0x6e,0xbc,0xba,0x38,0xdc,0x22,0xca,0x78,0xa9,0x31,0xe5,0x6, +0xa9,0xd5,0xea,0xa9,0xc5,0xea,0xa9,0x30,0xe5,0x19,0xa9,0xd0,0x9e,0xa9,0xd4,0x9e, +0x5, 0x5e,0x7e,0x73,0x3a,0x7, 0xbe,0x71,0x5e,0x38,0x2, 0xd2,0x1c,0xa9,0xd0,0x9e, +0xa9,0xd7,0x9e,0xa9,0x34,0xe5,0x5, 0xa9,0xc4,0xcd,0xc2,0x95,0xa9,0x32,0xe5,0x3, +0xa9,0xc2,0xcd,0xa9,0x33,0xe5,0x3, 0xa9,0xc3,0xcd,0xa9,0x37,0xe5,0x3, 0xa9,0xc7, +0xcd,0xa9,0x36,0xe5,0x3, 0xa9,0xc6,0xcd,0xda,0x78,0x32,0xc2,0x9a,0xa9,0xd4,0xa6, +0xc2,0x88,0xd2,0xa8,0x22,0x7e,0x14,0xd7,0xe8,0x7e,0x4, 0x0, 0xff,0x7e,0x34,0x47, +0x52,0x7e,0x24,0x55,0x50,0x79,0x30,0x0, 0x2, 0x1b,0xa, 0x20,0x7e,0x34,0x45,0x20, +0x7e,0x24,0x41,0x44,0x79,0x30,0x0, 0x6, 0x79,0x20,0x0, 0x4, 0x7e,0x34,0x99,0x33, +0x7e,0x24,0x66,0xcc,0x79,0x30,0x0, 0xa, 0x79,0x20,0x0, 0x8, 0x7e,0x34,0x41,0x47, +0x7e,0x24,0x46,0x4c,0x79,0x30,0x0, 0xe, 0x79,0x20,0x0, 0xc, 0x22,0xa9,0xc4,0xca, +0xa9,0xc5,0xca,0xbe,0xb0,0x8, 0x50,0x3, 0x12,0x4f,0xdc,0xa9,0xd0,0xce,0xa9,0xc0, +0xc9,0xd2,0x2, 0x12,0x2f,0xde,0xa9,0xc2,0xea,0x75,0xc1,0x6, 0x75,0xc2,0xc, 0xd2, +0x0, 0x12,0xb6,0xee,0xa9,0xc1,0xc4,0xa9,0xd2,0xc4,0xa9,0xc2,0xe1,0x22,0xa2,0x0, +0xa9,0x97,0xc1,0xa2,0x0, 0xa9,0x97,0xc2,0x22,0xa9,0xd0,0xce,0xa2,0x0, 0xa9,0x95, +0xc9,0x22,0xca,0xf8,0xa2,0xaf,0xe4,0x33,0x7c,0xfb,0xd2,0x0, 0x12,0xb6,0xf9,0xa9, +0xd0,0xcb,0xc2,0xaf,0xa9,0xd0,0x9e,0x75,0x9d,0x0, 0xa9,0xd0,0x9e,0x75,0x9c,0x20, +0xa9,0xd0,0x9e,0xa9,0xd4,0x9e,0xa9,0xd0,0xcd,0x74,0x41,0x12,0x2f,0x39,0xa9,0xd0, +0x9e,0xa9,0xd7,0x9e,0x2e,0xf0,0xff,0x92,0xaf,0xda,0xf8,0x22,0xa9,0xd5,0xcb,0x74, +0x10,0x12,0x0, 0x66,0x7c,0x7b,0x12,0x28,0xb3,0x30,0xe7,0x3, 0x7e,0x70,0x2, 0xd2, +0xcd,0x7e,0x24,0x0, 0xef,0x7e,0xf, 0x39,0xc1,0x79,0x20,0x0, 0x84,0x7e,0x24,0x20, +0x5f,0x7e,0xf, 0x39,0xc1,0x79,0x20,0x0, 0x82,0x7e,0x24,0x41,0x0, 0x7e,0xf, 0x39, +0xc1,0x79,0x20,0x0, 0x90,0x7c,0x67,0x6c,0x77,0x2e,0x34,0x0, 0xc1,0x7e,0xf, 0x39, +0xc1,0x79,0x30,0x0, 0x86,0x7e,0x34,0x29,0x90,0x7e,0xf, 0x39,0xc1,0x79,0x30,0x0, +0x8a,0x7e,0x34,0x6a,0xd1,0x7e,0xf, 0x39,0xc1,0x79,0x30,0x0, 0x8c,0x7e,0x34,0x3, +0x61,0x7e,0xf, 0x39,0xc1,0x79,0x30,0x0, 0x8e,0x22,0xa9,0xc6,0xeb,0xa9,0xd6,0xac, +0xa9,0xd6,0xec,0xd2,0x86,0xa9,0xc2,0xeb,0xa9,0xd2,0xac,0xa9,0xd2,0xec,0xd2,0x82, +0x22,0x75,0x9a,0x2f,0xa9,0xd1,0x99,0xd2,0x9c,0xa9,0xd6,0xdf,0x22,0xc2,0x8e,0x43, +0x89,0x20,0x75,0x8d,0x1, 0x75,0x8b,0x0, 0xd2,0x8e,0xd2,0xab,0x22,0x75,0xb7,0x0, +0x75,0xb8,0x0, 0x75,0xf7,0x0, 0x75,0xf8,0x0, 0xa9,0xd0,0xb7,0xd2,0xb8,0xa9,0xd5, +0xb7,0xd2,0xbd,0xa9,0xd0,0xf7,0xd2,0xf8,0xa9,0xc1,0xb7,0xc2,0xb9,0xa9,0xc3,0xb7, +0xc2,0xbb,0xa9,0xc6,0xb7,0xc2,0xbe,0x22,0x75,0xe7,0x6b,0x2, 0xb8,0xe, 0xe4,0x7e, +0x34,0xd7,0xfc,0x12,0x77,0x15,0x7e,0x34,0xd7,0xfd,0x7a,0x1b,0xb0,0x75,0xe9,0xff, +0x22,0xa9,0xd0,0x99,0xa9,0xc6,0xdf,0x22,0x7e,0x37,0x3a,0x5, 0xb, 0x34,0x7a,0x37, +0x3a,0x5, 0xbe,0x34,0xff,0x0, 0x40,0x8, 0x7e,0x34,0xff,0x0, 0x7a,0x37,0x3a,0x5, +0x22,0xd2,0xc9,0x75,0xf2,0x30,0x75,0xf3,0x80,0x75,0xf4,0xc, 0x75,0xf5,0x1, 0x6c, +0xaa,0xe5,0xf5,0x54,0x80,0xb4,0x80,0xf9,0xe5,0xf6,0x12,0x5d,0xe7,0xb, 0xa0,0xbe, +0xa0,0xd, 0x40,0xed,0xc2,0xc9,0x22,0x2, 0xb8,0x6a,0x6d,0x11,0x12,0x57,0xe5,0x12, +0xb9,0x19,0x7d,0x3, 0x7e,0x78,0x13,0x8e,0x6c,0x99,0x80,0x17,0x12,0xb8,0xb9,0x7e, +0x50,0x2, 0xac,0x59,0x7f,0x57,0x2d,0xb2,0xb, 0x5a,0x30,0x9d,0x3d,0x59,0x32,0x13, +0xc6,0xb, 0x90,0xbc,0xa9,0x38,0xe5,0x6c,0x99,0x80,0x17,0x12,0xb8,0xb9,0x7e,0x70, +0x2, 0xac,0x79,0x2d,0x3f,0x7d,0x2e,0x12,0xb9,0x24,0xbd,0x1b,0x58,0x2, 0x7d,0x1b, +0xb, 0x90,0xbc,0xa9,0x38,0xe5,0x7d,0x31,0x22,0xa, 0xd9,0x2d,0xd0,0x3e,0xd4,0x7e, +0x1f,0x39,0xda,0x2d,0x3d,0xb, 0x1a,0xd0,0x22,0x12,0x8f,0xce,0x7e,0x34,0xd, 0xc8, +0x7e,0xb3,0x2a,0x6d,0x12,0xb8,0xe5,0x12,0xb8,0x67,0x7a,0x37,0x39,0xd7,0x74,0x1, +0x7a,0xb3,0x16,0x91,0x22,0x7a,0xb3,0x24,0xf2,0x7e,0x53,0x2a,0x6e,0x7a,0x53,0x24, +0xf3,0x7a,0x37,0x24,0xfa,0xe4,0x7a,0xb3,0x24,0xf4,0x7a,0xb3,0x24,0xf5,0x7e,0x34, +0x40,0x0, 0x7a,0x37,0x24,0xf6,0x7e,0x34,0x0, 0x20,0x12,0xb9,0x10,0x2, 0xd, 0x7, +0x7a,0x37,0x24,0xfc,0x7e,0x8, 0x24,0xf2,0x22,0xa, 0x2b,0x2e,0x24,0x0, 0x3, 0xa, +0x3a,0xad,0x32,0x22,0xb, 0x1a,0xc0,0x7d,0x3d,0x9d,0x3c,0x12,0x21,0xa, 0x7d,0xb3, +0x22,0xca,0x79,0x7c,0xfb,0x7e,0x8, 0x1f,0x34,0x12,0xb9,0xa7,0x7e,0xa3,0x2a,0x73, +0x7e,0x63,0x2a,0x74,0x6c,0xee,0x80,0x1e,0xa, 0x2e,0x9, 0x72,0x2a,0xdc,0xbe,0x70, +0x1c,0x50,0x11,0xa, 0x27,0x12,0x67,0x43,0x7c,0x7b,0x7e,0xb3,0x2a,0xfb,0xa, 0x27, +0x19,0xb2,0x1f,0x34,0xb, 0xe0,0xbc,0x6e,0x38,0xde,0x6c,0xee,0x80,0x17,0xa, 0x3e, +0x9, 0x73,0x2a,0xb9,0xbe,0x70,0x23,0x50,0xa, 0x7e,0x63,0x2a,0xfb,0xa, 0x27,0x19, +0x62,0x1f,0x50,0xb, 0xe0,0xbc,0xae,0x38,0xe5,0x6c,0xee,0x7e,0x30,0xe, 0xac,0x3e, +0x2e,0x14,0x1f,0x34,0x6d,0x0, 0x7c,0xbf,0x7c,0x7e,0x12,0x11,0xf8,0xb, 0xe0,0xbe, +0xe0,0x5, 0x40,0xe7,0xda,0x79,0x22,0x7e,0x34,0x0, 0x46,0x74,0x3f,0x2, 0x20,0xe8, +0xca,0xd8,0xca,0x79,0x7c,0xf7,0x7f,0x70,0x12,0xba,0x42,0x7c,0xeb,0x6c,0xdd,0x80, +0x20,0x74,0x2, 0xac,0xbd,0x7f,0x67,0x2d,0xd5,0xb, 0x6a,0x30,0x6d,0x22,0x74,0x4, +0x2f,0x11,0x14,0x78,0xfb,0xa, 0x1e,0x6d,0x0, 0x12,0x1f,0x7, 0x1b,0x6a,0x30,0xb, +0xd0,0xbc,0xfd,0x38,0xdc,0xda,0x79,0xda,0xd8,0x22,0xca,0x79,0x7f,0x51,0x7f,0x40, +0x7e,0xa3,0x2a,0x74,0xa, 0x3a,0x7e,0xa3,0x2a,0x73,0xa, 0x7a,0x2d,0x73,0x7e,0xd, +0x29,0x7c,0x7f,0x12,0xb9,0xb0,0xa, 0x3f,0x3e,0x34,0xca,0x39,0x7e,0x1d,0x29,0x7f, +0x4, 0x12,0x20,0xc3,0x1b,0xfd,0x7e,0xb3,0x2b,0x1, 0xb4,0x1, 0x22,0x6c,0xaa,0x80, +0x1a,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x5, 0x2d,0x13,0xb, 0xa, 0x20,0x7f,0x4, 0x2d, +0x13,0xb, 0xa, 0x30,0x9d,0x32,0x1b,0xa, 0x30,0xb, 0xa0,0xbc,0xfa,0x38,0xe2,0xda, +0x79,0x22,0x7c,0x7b,0xa5,0xbf,0x0, 0x3, 0x74,0x10,0x22,0xbe,0x70,0x4, 0x38,0x4, +0x6c,0xaa,0x80,0x21,0xbe,0x70,0x8, 0x38,0x5, 0x7e,0xa0,0x1, 0x80,0x17,0xbe,0x70, +0x10,0x38,0x5, 0x7e,0xa0,0x2, 0x80,0xd, 0xbe,0x70,0x20,0x38,0x5, 0x7e,0xa0,0x3, +0x80,0x3, 0x7e,0xa0,0x4, 0xa, 0x47,0x3e,0x44,0x3e,0x44,0x3e,0x44,0x7c,0xba,0x60, +0x5, 0x1e,0x44,0x14,0x78,0xfb,0x7c,0xb9,0x22,0x7c,0xab,0x9f,0x11,0x30,0x0, 0x22, +0x6c,0x99,0x80,0x1a,0xa, 0xf9,0x2d,0xf1,0x7d,0xe0,0x7e,0x7b,0xb0,0x7e,0x78,0x0, +0x1, 0x60,0x5, 0x2f,0x77,0x14,0x78,0xfb,0x4d,0x3f,0x4d,0x2e,0xb, 0x90,0xbc,0xa9, +0x38,0xe2,0x22,0xca,0xf8,0x7e,0xf0,0x19,0x7e,0x8, 0x1f,0x34,0x12,0xbb,0x3b,0x7e, +0x8, 0x1f,0x3c,0x12,0xbb,0x43,0xd2,0x0, 0x7e,0x8, 0x2a,0xdc,0x74,0x19,0x12,0xba, +0x89,0x7e,0x8, 0x1f,0x34,0x7a,0xf, 0x1f,0x58,0x7f,0x1, 0x7a,0x17,0x1f,0x5c,0x7d, +0x32,0x7a,0x37,0x1f,0x5e,0x7e,0x18,0x1f,0x3c,0x7a,0x1f,0x1f,0x64,0x6c,0x77,0x80, +0xe, 0x12,0xbb,0x8b,0x50,0x7, 0x12,0xbb,0x82,0x19,0x51,0x1f,0x3c,0xb, 0x70,0xbc, +0xf7,0x38,0xee,0x12,0xbb,0x28,0xe4,0x12,0xbb,0x30,0xe4,0x12,0xc, 0x9b,0x6d,0x33, +0x7a,0x37,0x1f,0x5c,0x7a,0x37,0x1f,0x5e,0x12,0xbb,0x28,0x74,0x1, 0x12,0xbb,0x30, +0x74,0x1, 0x12,0xc, 0x9b,0xda,0xf8,0x22,0xa9,0xc6,0xea,0x7e,0x8, 0x1f,0x58,0x22, +0x12,0xc, 0x9b,0xa9,0xd6,0xea,0x7e,0x8, 0x1f,0x58,0x22,0x7e,0x34,0x0, 0x8, 0xe4, +0x2, 0x20,0xe8,0x7e,0x34,0x0, 0x1c,0x74,0x3f,0x2, 0x20,0xe8,0x7e,0x8, 0x1f,0x34, +0x12,0xbb,0x43,0x6c,0x77,0x80,0xe, 0x12,0xbb,0x8b,0x50,0x7, 0x12,0xbb,0x82,0x19, +0x51,0x1f,0x34,0xb, 0x70,0x7e,0x53,0x2a,0x6e,0xbc,0x57,0x38,0xea,0xa9,0xc6,0xea, +0x7e,0x8, 0x1f,0x34,0xe4,0x12,0x11,0x38,0xa9,0xd6,0xea,0x7e,0x8, 0x1f,0x34,0x2, +0x11,0x38,0xa, 0x27,0x9, 0x52,0x2b,0x44,0xa, 0x16,0x22,0xa, 0x27,0x9, 0x62,0x2a, +0xdc,0xbe,0x60,0x1c,0x22,0x7e,0x27,0x28,0xa3,0x6d,0x11,0x9d,0x12,0x6c,0xaa,0x80, +0x64,0x30,0x5, 0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x5, 0xf8,0x49,0x4, 0x4, +0x0, 0xbd,0x2, 0x8, 0x11,0x7e,0xb3,0x25,0xf6,0xb4,0x1, 0x16,0x7d,0xf2,0x2d,0xf3, +0x59,0xf4,0x5, 0xf8,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59,0x4, +0x5, 0xf8,0x30,0x7, 0x2e,0x7e,0x90,0x2, 0xac,0x9a,0x49,0x34,0x6, 0x76,0x49,0x4, +0x4, 0x7e,0xbd,0x2, 0x8, 0x11,0x7e,0xb3,0x25,0xf6,0xb4,0x1, 0x16,0x7d,0xf2,0x2d, +0xf3,0x59,0xf4,0x6, 0x76,0x80,0xc, 0xbd,0x1, 0x58,0x8, 0x7d,0x3, 0x9d,0x2, 0x59, +0x4, 0x6, 0x76,0xb, 0xa0,0x7e,0xb3,0x2a,0x74,0xa, 0xb, 0x7e,0xb3,0x2a,0x73,0xa, +0x4b,0x2d,0x40,0xa, 0xa, 0xbd,0x4, 0x48,0x88,0x22,0xe4,0x6c,0x33,0xa, 0x33,0x19, +0xb3,0x27,0x72,0xb, 0x30,0xa5,0xbb,0x4, 0xf4,0xe4,0x7a,0xb3,0x28,0x84,0x7a,0xb3, +0x28,0x85,0x6d,0x33,0x7a,0x37,0x28,0x86,0x7a,0x37,0x28,0x88,0x7a,0x37,0x28,0x8a, +0x7a,0x37,0x28,0x8e,0x7e,0xd4,0x1f,0x36,0x5e,0xd4,0xff,0xfe,0x6d,0xcc,0x7e,0x1f, +0x13,0x8a,0x7a,0x37,0x1f,0x76,0x7d,0x3d,0x7a,0x37,0x1f,0x7a,0x7e,0x34,0x15,0x9e, +0x7a,0x37,0x1f,0x78,0x7e,0x73,0x2a,0x6d,0x7a,0x73,0x1f,0x73,0x7e,0x73,0x2a,0x6e, +0x7a,0x73,0x1f,0x72,0x7e,0x37,0x2a,0x5c,0x7a,0x37,0x1f,0x7c,0x7e,0x37,0x2a,0x5e, +0x7a,0x37,0x1f,0x7e,0x7e,0x37,0x2a,0x60,0x7a,0x37,0x1f,0x80,0x74,0x1e,0x7a,0xb3, +0x1f,0x74,0x7e,0x73,0x3, 0xfe,0x7a,0x73,0x1f,0x75,0x7e,0x8, 0x1f,0x72,0x7e,0x18, +0x1f,0x82,0x12,0x8, 0x0, 0x7e,0x73,0x1f,0x82,0x7a,0x73,0x28,0x84,0x7e,0x73,0x1f, +0x83,0x7a,0x73,0x28,0x85,0x7e,0x37,0x1f,0x84,0x7a,0x37,0x28,0x86,0x7e,0x37,0x1f, +0x86,0x7a,0x37,0x28,0x88,0x7e,0x37,0x1f,0x8c,0x7a,0x37,0x28,0x8a,0x7e,0x37,0x1f, +0x8e,0x7d,0x23,0x7a,0x53,0x28,0x8c,0xa, 0x36,0x7a,0x73,0x28,0x8d,0x7e,0x37,0x1f, +0x88,0x7a,0x37,0x28,0x8e,0x7e,0x37,0x1f,0x8a,0x7d,0x23,0x7a,0x53,0x28,0x90,0xa, +0x36,0x7a,0x73,0x28,0x91,0x6c,0x33,0x80,0x1d,0x7c,0xb3,0x12,0x76,0xfb,0x74,0x2, +0xac,0xb3,0x49,0x45,0x15,0x9e,0xa, 0x38,0x7c,0x27,0x19,0x25,0x26,0xfa,0x7c,0x29, +0x19,0x25,0x26,0xfb,0xb, 0x30,0x7e,0x23,0x28,0x84,0xbc,0x23,0x38,0xdb,0x6c,0x33, +0x80,0x1b,0x74,0x2, 0xac,0xb3,0x7f,0x16,0x2d,0x35,0xb, 0x1a,0x40,0xa, 0x38,0x7c, +0x27,0x19,0x25,0x27,0x36,0x7c,0x29,0x19,0x25,0x27,0x37,0xb, 0x30,0x7e,0x23,0x28, +0x85,0xbc,0x23,0x38,0xdd,0x22,0x7c,0x7b,0xa, 0x57,0x9e,0x54,0x0, 0x20,0xe, 0x54, +0xe, 0x54,0xe, 0x54,0xe, 0x54,0x7c,0xab,0x7c,0x67,0x5e,0x60,0xf0,0xa5,0xbe,0x20, +0x1d,0x7c,0xb7,0x54,0xf, 0x7e,0x24,0x0, 0x1, 0x60,0x5, 0x3e,0x24,0x14,0x78,0xfb, +0x7e,0x73,0x39,0xfc,0xa, 0x47,0x5d,0x42,0x7e,0x73,0x38,0x33,0x80,0x36,0xa5,0xbe, +0x30,0x18,0x12,0xbd,0xb9,0x60,0x5, 0x3e,0x34,0x14,0x78,0xfb,0x7e,0x53,0x39,0xfd, +0xa, 0x45,0x5d,0x43,0x7e,0x73,0x38,0x34,0x80,0x1a,0x12,0xbd,0xb9,0x60,0x5, 0x3e, +0x34,0x14,0x78,0xfb,0xa, 0x2a,0x9, 0xb2,0x39,0xfc,0xa, 0x4b,0x5d,0x43,0xa, 0x5a, +0x9, 0x75,0x38,0x35,0xa, 0x57,0x5d,0x54,0x22,0x7c,0xb7,0x54,0xf, 0x7e,0x34,0x0, +0x1, 0x22,0x7e,0xb3,0x2f,0x80,0xb4,0x4, 0x2, 0xd3,0x22,0xc3,0x22,0x7d,0xf2,0x7d, +0xe3,0x7e,0x8, 0x2f,0x80,0x7e,0x34,0x0, 0x28,0xe4,0x12,0x20,0xe8,0x7e,0x8, 0x2b, +0xbf,0x7e,0x34,0x3, 0xc0,0x12,0x20,0xe8,0x7a,0xb3,0x38,0x35,0x7e,0x34,0x13,0x88, +0x7a,0x37,0x2b,0xb7,0x7a,0xe7,0x2f,0x84,0x7a,0xf7,0x2f,0x86,0x7a,0xe7,0x2f,0x88, +0x7a,0xe7,0x2f,0x8c,0x7a,0xe7,0x2f,0x90,0x7a,0xe7,0x2f,0x94,0x7a,0xf7,0x2f,0x8a, +0x7a,0xf7,0x2f,0x8e,0x7a,0xf7,0x2f,0x92,0x7a,0xf7,0x2f,0x96,0x7a,0xe7,0x2b,0xbb, +0x7a,0xf7,0x2b,0xbd,0x7a,0xb3,0x2f,0xa8,0x74,0x2, 0x7a,0xb3,0x2f,0x7f,0x22,0x74, +0xfe,0x7a,0xb3,0x38,0x35,0xe4,0x7a,0xb3,0x2f,0x80,0x22,0xca,0x3b,0xf5,0x2a,0x7f, +0x31,0x7a,0xd, 0x26,0xe4,0x7a,0xb3,0x22,0xf6,0x7a,0xb3,0x22,0xf7,0x7a,0xb3,0x22, +0xf8,0x7e,0x34,0x3, 0xe8,0x7a,0x37,0x22,0xfd,0x74,0x3c,0x7a,0xb3,0x22,0xf5,0x75, +0x2f,0x46,0x75,0x2b,0x0, 0x2, 0xc0,0x38,0x12,0xc0,0x74,0x28,0x1e,0x7e,0x34,0x0, +0x44,0xca,0x39,0x7e,0x71,0x2b,0x74,0x44,0xac,0x7b,0x2e,0x34,0x14,0x6, 0x7e,0x24, +0x0, 0xff,0x7e,0x8, 0x22,0xff,0x12,0x20,0xc3,0x1b,0xfd,0x6d,0x33,0x7a,0x37,0x22, +0xf9,0x7a,0x35,0x30,0x7a,0x37,0x22,0xfb,0x7a,0x35,0x32,0x7a,0x35,0x34,0x7e,0x34, +0x22,0xff,0x7a,0x35,0x36,0x7e,0x34,0x23,0x1f,0x7a,0x35,0x38,0x75,0x2c,0x0, 0x80, +0x59,0xe5,0x2c,0xa, 0x3b,0x7e,0xd, 0x26,0x12,0xc6,0xea,0x2e,0x35,0x36,0x12,0x96, +0xa1,0x7d,0xd3,0x7e,0xc7,0x22,0xfb,0xbd,0xcd,0x58,0x4, 0x7a,0xd7,0x22,0xfb,0xe5, +0x2c,0xa, 0x3b,0x7f,0x3, 0x12,0xc6,0xea,0x2e,0x35,0x38,0x12,0x96,0xa1,0x7d,0xc3, +0x7e,0x35,0x32,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x32,0x7e,0x37,0x22,0xf9,0x2d,0x3d, +0x7a,0x37,0x22,0xf9,0x7d,0x3c,0x2e,0x35,0x30,0x7a,0x35,0x30,0x2d,0xcd,0x7e,0x35, +0x34,0xbd,0x3c,0x58,0x3, 0x7a,0xc5,0x34,0x5, 0x2c,0xe5,0x2a,0xbe,0xb1,0x2c,0x38, +0xa0,0xe5,0x2a,0xb4,0xa, 0x2d,0x7e,0x37,0x22,0xfb,0xbe,0x34,0x0, 0x40,0x48,0xc, +0x7e,0x25,0x32,0xbe,0x24,0x0, 0x40,0x48,0x3, 0x2, 0xc0,0x36,0xbe,0x34,0x0, 0x60, +0x8, 0x3, 0x2, 0xc0,0x36,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x60,0x8, 0x3, 0x2, 0xc0, +0x36,0x80,0x2b,0x7e,0x37,0x22,0xfb,0xbe,0x34,0x0, 0x20,0x8, 0xc, 0x7e,0x25,0x32, +0xbe,0x24,0x0, 0x20,0x8, 0x3, 0x2, 0xc0,0x36,0xbe,0x34,0x0, 0x30,0x8, 0x3, 0x2, +0xc0,0x36,0x7e,0x35,0x32,0xbe,0x34,0x0, 0x30,0x8, 0x3, 0x2, 0xc0,0x36,0x7e,0xa3, +0x39,0x42,0x74,0xc, 0xa4,0xbe,0x57,0x22,0xf9,0x58,0x3, 0x2, 0xc0,0x36,0x7e,0xa3, +0x39,0x43,0x74,0xc, 0xa4,0xbe,0x55,0x30,0x58,0x3, 0x2, 0xc0,0x36,0x7e,0x15,0x36, +0x6d,0x0, 0x7e,0x1d,0x26,0xe5,0x2a,0x12,0xc0,0x7c,0x7a,0xb3,0x22,0xf4,0x7e,0x15, +0x38,0x6d,0x0, 0x7f,0x13,0xe5,0x2a,0x12,0xc0,0x7c,0xf5,0x2d,0x7e,0x73,0x22,0xf5, +0xbe,0x73,0x22,0xf4,0x28,0x3, 0x2, 0xc0,0x36,0xbe,0x71,0x2d,0x38,0x78,0xe5,0x2d, +0x7e,0x31,0x2d,0xac,0x3b,0x1a,0x2, 0x1a,0x0, 0x7e,0x73,0x22,0xf4,0xac,0x77,0x1a, +0x26,0x1a,0x24,0x2f,0x10,0xe5,0x2d,0xa, 0x5b,0x6d,0x44,0x7e,0x33,0x22,0xf4,0xa, +0x13,0x6d,0x0, 0x2f,0x2, 0x12,0x1f,0x7, 0x7c,0xb7,0xf5,0x2e,0xe5,0x2f,0xbe,0xb1, +0x2e,0x38,0x43,0x7e,0x37,0x22,0xfb,0x2e,0x35,0x32,0x2e,0x35,0x34,0x7a,0x35,0x3a, +0xe5,0x2e,0xa, 0x2b,0x7e,0x34,0x0, 0x64,0x9d,0x32,0x3e,0x34,0x2e,0x35,0x3a,0x7a, +0x35,0x3a,0x7e,0x37,0x22,0xfd,0xbe,0x35,0x3a,0x8, 0x1b,0x7e,0x35,0x3a,0x7a,0x37, +0x22,0xfd,0xe5,0x2e,0x7a,0xb3,0x22,0xf7,0x7e,0x73,0x23,0x41,0x7a,0x73,0x22,0xf8, +0xe5,0x2b,0x7a,0xb3,0x22,0xf6,0x5, 0x2b,0x12,0xc0,0x74,0x28,0x3, 0x2, 0xbe,0x68, +0x7e,0xa3,0x22,0xf7,0xbe,0xa1,0x2f,0x40,0x20,0x7e,0xb3,0x22,0xf8,0xbe,0xb0,0x0, +0x28,0x17,0xbe,0xb0,0xff,0x50,0x12,0x7e,0x73,0x22,0xf6,0xa, 0x37,0xb, 0x34,0x7a, +0x73,0x39,0x3f,0x7a,0xb3,0x39,0x41,0x80,0x6, 0x74,0x7c,0x7a,0xb3,0x39,0x3f,0x7c, +0xba,0xda,0x3b,0x22,0x7e,0x73,0x3a,0x2, 0xbe,0x71,0x2b,0x22,0xca,0x3b,0x7c,0xfb, +0x7f,0x61,0x7f,0x40,0x9f,0x11,0x7f,0x51,0x7f,0x71,0x7a,0x1d,0x3c,0x7a,0x1d,0x40, +0x7a,0x1d,0x44,0xbe,0xf0,0xa, 0x78,0x6, 0x7e,0x54,0x1, 0x3c,0x80,0x4, 0x7e,0x54, +0x2, 0x35,0x7a,0x57,0x23,0x43,0x6c,0xee,0x80,0x60,0xa, 0x5e,0x7f,0x14,0x12,0xc1, +0xcd,0x7a,0x55,0x4a,0xa, 0x5e,0x7f,0x16,0x12,0xc1,0xcd,0x7a,0x55,0x48,0x7e,0x35, +0x48,0x12,0x97,0xc5,0x2f,0x50,0x7e,0x65,0x4a,0x7d,0x16,0x1a,0x2, 0x1a,0x0, 0x2f, +0x70,0x12,0x97,0xc5,0x12,0xc1,0xc3,0x7e,0x1d,0x3c,0x2f,0x10,0x7a,0x1d,0x3c,0x7d, +0x16,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x4a,0x12,0xc1,0xc3,0x7e,0x1d,0x40,0x2f,0x10, +0x7a,0x1d,0x40,0x7e,0x15,0x4a,0x1a,0x2, 0x1a,0x0, 0x7e,0x35,0x48,0x12,0xc1,0xc3, +0x7e,0x1d,0x44,0x2f,0x10,0x7a,0x1d,0x44,0xb, 0xe0,0xbc,0xfe,0x38,0x9c,0xa, 0xdf, +0x6d,0xcc,0x7f,0x15,0x7f,0x6, 0x12,0x1f,0x58,0x7f,0x51,0x7f,0x17,0x7f,0x6, 0x12, +0x1f,0x58,0x7f,0x71,0x7e,0x94,0x0, 0x64,0x7e,0x1d,0x3c,0x7d,0x19,0x12,0x1e,0xfc, +0x7e,0x87,0x23,0x43,0x7d,0x18,0x7d,0xd8,0x1a,0x12,0x1a,0xc2,0x7f,0x6, 0x12,0x1f, +0x58,0x7a,0x1d,0x3c,0x7e,0x1d,0x40,0x7d,0x19,0x12,0x1e,0xfc,0x7f,0x6, 0x12,0x1f, +0x58,0x7a,0x1d,0x40,0x7e,0x1d,0x44,0x7d,0x19,0x12,0x1e,0xfc,0x7d,0x18,0x1a,0x2, +0x1a,0x0, 0x12,0x1f,0x58,0x7a,0x1d,0x44,0x7f,0x15,0x7f,0x7, 0x12,0x1e,0xeb,0x7e, +0x6d,0x44,0x9f,0x61,0x7f,0x15,0x7f,0x5, 0x12,0x1e,0xeb,0x7e,0x5d,0x3c,0x9f,0x51, +0x7f,0x17,0x7f,0x7, 0x12,0x1e,0xeb,0x7e,0x7d,0x40,0x9f,0x71,0xbe,0x58,0x0, 0x0, +0x68,0x6, 0xbe,0x78,0x0, 0x0, 0x78,0x6, 0x7e,0x44,0x0, 0x64,0x80,0x18,0x7f,0x16, +0x7d,0x19,0x12,0x1e,0xfc,0x7f,0x5, 0x12,0x1f,0x58,0x7f,0x6, 0x12,0x1e,0xeb,0x7f, +0x7, 0x12,0x1f,0x58,0x7d,0x43,0xbe,0x44,0x0, 0x0, 0x18,0x2, 0x6d,0x44,0x7c,0xb9, +0xda,0x3b,0x22,0x1a,0x26,0x1a,0x24,0x12,0x1e,0xeb,0x7f,0x1, 0x22,0x2d,0x35,0x7e, +0x1b,0x70,0xa, 0x57,0x22,0xca,0xf8,0x7f,0x51,0x7f,0x40,0x7e,0x37,0x2f,0x90,0x7a, +0x35,0x2a,0x7e,0x37,0x2f,0x8e,0x7a,0x35,0x2c,0x7e,0x37,0x2f,0x9c,0x7a,0x35,0x26, +0x7e,0x37,0x2f,0x9e,0x7a,0x35,0x28,0x6c,0xff,0x80,0x1e,0x7e,0x34,0x0, 0x26,0x7e, +0x14,0x0, 0x2f,0x74,0x9, 0x12,0x1f,0x8c,0x74,0x2, 0xac,0xbf,0x7f,0x4, 0x2d,0x15, +0x7f,0x15,0x2d,0x35,0x12,0xc2,0x24,0xb, 0xf0,0x7e,0x73,0x39,0x40,0xbc,0x7f,0x38, +0xda,0xda,0xf8,0x22,0x7f,0x71,0x7f,0x60,0x7e,0x35,0x2f,0xbe,0x34,0x0, 0x0, 0x38, +0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x2f,0x7e,0x35,0x31,0xbe,0x34,0x0, 0x0, 0x38, +0x7, 0x7e,0x34,0x0, 0x1, 0x7a,0x35,0x31,0xb, 0x6a,0x30,0x9e,0x35,0x33,0x6d,0x22, +0x7e,0x33,0x39,0x42,0x12,0xc2,0x79,0x7e,0x15,0x2f,0x12,0x1f,0x5, 0x1b,0x6a,0x30, +0xb, 0x7a,0x30,0x9e,0x35,0x35,0x6d,0x22,0x7e,0x33,0x39,0x43,0x12,0xc2,0x79,0x7e, +0x15,0x31,0x12,0x1f,0x5, 0x1b,0x7a,0x30,0x22,0xa, 0x13,0x6d,0x0, 0x2, 0x1e,0xeb, +0xca,0x79,0x6c,0xaa,0x7e,0x90,0x2, 0xac,0x9a,0x7f,0x70,0x2d,0xf4,0xb, 0x7a,0xf0, +0x7d,0x7f,0x7c,0xbf,0xa, 0xfa,0x19,0xbf,0x39,0x44,0x7f,0x71,0x2d,0xf4,0xb, 0x7a, +0x40,0x7c,0xb9,0xa, 0x4a,0x19,0xb4,0x39,0x64,0xb, 0xa0,0xbe,0xa0,0x20,0x40,0xd4, +0x7e,0x8, 0x39,0x44,0x7e,0x18,0x39,0x64,0x74,0x20,0x12,0xbe,0x3b,0xda,0x79,0x22, +0xca,0x3b,0x7f,0x61,0x7f,0x50,0x7e,0x73,0x39,0x40,0xbe,0x70,0x20,0x40,0x52,0x7e, +0xf0,0x2, 0x80,0x3c,0xa, 0x3f,0x6d,0x22,0x74,0x5, 0x2f,0x11,0x14,0x78,0xfb,0x7e, +0x33,0x39,0x40,0xa, 0x13,0x6d,0x0, 0x12,0x1f,0x7, 0x7c,0xe7,0xbe,0xe0,0x2, 0x50, +0x3, 0x7e,0xe0,0x2, 0xa, 0x6f,0x1b,0x64,0xa, 0x3e,0x1b,0x34,0x7c,0xc7,0x7f,0x5, +0x7c,0xbd,0x12,0xc3,0x2a,0x7f,0x6, 0x7c,0xbd,0x7c,0x7c,0x12,0xc3,0x2a,0xb, 0xf0, +0x7e,0x73,0x39,0x40,0xbc,0x7f,0x50,0xbc,0x7f,0x5, 0x7f,0x16,0x12,0xc2,0x80,0x80, +0x6, 0x74,0x7e,0x7a,0xb3,0x39,0x3f,0xda,0x3b,0x22,0x7c,0x97,0x7c,0xab,0x7f,0x10, +0x7e,0x30,0x2, 0xac,0x3a,0x2d,0x13,0x7d,0x2, 0xb, 0xa, 0x10,0x7e,0x10,0x2, 0xac, +0x19,0x7f,0x71,0x2d,0xf0,0xb, 0x7a,0x0, 0x7c,0x21,0xa5,0xba,0x0, 0x14,0xa, 0x3, +0x1b,0x7a,0x0, 0xbc,0x9a,0x68,0x24,0x6d,0x44,0x74,0x2, 0xa4,0x2d,0x35,0x1b,0x1a, +0x40,0x22,0xbc,0x9a,0x68,0x15,0xa, 0x2, 0xa, 0x13,0x2d,0x10,0xe, 0x14,0x1b,0x7a, +0x10,0x6d,0x11,0x74,0x2, 0xa4,0x2d,0x35,0x1b,0x1a,0x10,0x22,0xca,0x3b,0x7f,0x71, +0x7e,0x60,0x1, 0xb, 0xa, 0x20,0xb, 0x7a,0x50,0x7c,0x4b,0x7a,0x53,0x22,0xf4,0x7a, +0x43,0x23,0xe4,0x7e,0x70,0x1, 0x7e,0xa0,0x1, 0x81,0x9d,0x7e,0x90,0x2, 0xac,0x9a, +0x7f,0x60,0x2d,0xd4,0xb, 0x6a,0xd0,0x7d,0x7d,0x7c,0xbf,0xf5,0x26,0x7f,0x67,0x2d, +0xd4,0xb, 0x6a,0x40,0xa, 0xd5,0xa, 0xbb,0x7d,0xab,0x9d,0xad,0x7d,0x7a,0x7c,0x8f, +0xbe,0x80,0x0, 0x58,0x5, 0x6e,0x80,0xff,0xb, 0x80,0xa, 0xa4,0xa, 0x79,0x9d,0x7a, +0xbe,0xf0,0x0, 0x58,0x5, 0x6e,0xf0,0xff,0xb, 0xf0,0xbe,0x80,0x2, 0x58,0x7, 0xbe, +0xf0,0x2, 0x58,0x2, 0x81,0x9b,0xbe,0x60,0x0, 0x18,0x2, 0x81,0x83,0xbe,0x70,0xec, +0x28,0x2, 0x81,0xa7,0xbe,0x80,0x8, 0x58,0x5, 0xbe,0xf0,0x8, 0x48,0x61,0xa, 0xa7, +0xb, 0xa4,0x7d,0x6a,0x7c,0x7d,0xa, 0xa5,0x2d,0xab,0x12,0xc4,0xeb,0x19,0xba,0x22, +0xf4,0xa, 0xd9,0xa, 0xa4,0x2d,0xad,0x12,0xc4,0xeb,0x19,0xba,0x23,0xe4,0x9, 0xba, +0x22,0xf4,0xa, 0xdb,0xa, 0xc5,0x2d,0xcd,0xe, 0xc4,0x7d,0x6c,0x7c,0xbd,0xa, 0xc7, +0x19,0xbc,0x22,0xf3,0x9, 0xbc,0x23,0xe4,0xa, 0xcb,0xa, 0xa4,0x2d,0xac,0x12,0xc4, +0xeb,0x19,0xba,0x23,0xe3,0x2d,0xdb,0x12,0xc4,0xe2,0x19,0xbd,0x22,0xf5,0xa, 0xd9, +0x12,0xc4,0xe0,0x19,0xbd,0x23,0xe5,0xb, 0xd5,0x7d,0x6d,0x7c,0x7d,0x80,0x24,0xbe, +0x80,0x4, 0x58,0x5, 0xbe,0xf0,0x4, 0x48,0x1a,0xe5,0x26,0xa, 0xcb,0xa, 0xd5,0x12, +0xc4,0xe0,0x19,0xbd,0x22,0xf4,0xa, 0xc9,0xa, 0xd4,0x12,0xc4,0xe0,0x19,0xbd,0x23, +0xe4,0xb, 0x70,0xbe,0x70,0xf0,0x50,0x1f,0x7e,0x51,0x26,0x7c,0x49,0xe5,0x26,0xa, +0xd7,0x19,0xbd,0x22,0xf4,0x19,0x9d,0x23,0xe4,0xb, 0x70,0xb, 0xa0,0x7e,0xb3,0x39, +0x40,0xbc,0xba,0x28,0x2, 0x61,0x9b,0x7a,0x73,0x39,0x40,0x7e,0xa0,0x1, 0x80,0x25, +0xa, 0x3a,0x9, 0xb3,0x22,0xf4,0xa, 0x2b,0x7e,0x70,0x2, 0xac,0x7a,0x7f,0x60,0x2d, +0xd3,0x1b,0x6a,0x20,0xa, 0x2a,0x9, 0xb2,0x23,0xe4,0xa, 0x4b,0x2d,0x3f,0x7d,0x2e, +0x1b,0x1a,0x40,0xb, 0xa0,0x7e,0xb3,0x39,0x40,0xbc,0xba,0x38,0xd3,0xda,0x3b,0x22, +0x2d,0xdc,0xe, 0xd4,0x7d,0x6d,0x7c,0xbd,0xa, 0xd7,0x22,0xe, 0xa4,0x7d,0x6a,0x7c, +0xbd,0xa, 0xa7,0x22,0x7d,0x13,0x3e,0x14,0x3e,0x14,0x3e,0x14,0x7e,0x37,0x39,0xe3, +0x9e,0x37,0x39,0xdf,0x12,0x21,0xa, 0xbd,0x31,0x38,0x12,0x7e,0x37,0x39,0xe5,0x9e, +0x37,0x39,0xe1,0x12,0x21,0xa, 0xbd,0x31,0x38,0x3, 0x74,0x1, 0x22,0xe4,0x22,0xca, +0x79,0x6c,0xaa,0x6d,0x11,0x7d,0x41,0x7d,0x1, 0x7e,0xe3,0x2a,0x2, 0x7e,0xf3,0x2a, +0x3, 0x7e,0x73,0x39,0xde,0x4c,0x77,0x68,0x11,0x7e,0x27,0x39,0xe7,0x4d,0x22,0x78, +0x2, 0xc1,0x10,0xbe,0xe0,0x1, 0x28,0x2, 0xc1,0x10,0xbe,0xe0,0x1, 0x78,0x38,0xbe, +0x70,0x4, 0x78,0x2, 0xc1,0x10,0x7e,0x63,0x34,0x88,0x7e,0x10,0x9, 0xac,0x16,0x49, +0x40,0x29,0x8, 0x49,0x0, 0x29,0xa, 0xbe,0x44,0x0, 0x6e,0x50,0x2, 0xc1,0x10,0xbe, +0x44,0x3, 0x7a,0x28,0x2, 0xc1,0x10,0xbe,0x4, 0x0, 0x6e,0x50,0x2, 0xc1,0x10,0xbe, +0x4, 0x6, 0xc2,0x28,0x2, 0xc1,0x10,0x7c,0xb7,0x14,0x68,0x2b,0x14,0x68,0x51,0x14, +0x68,0x25,0x14,0x68,0x78,0xb, 0xb2,0x78,0x77,0xbe,0xe0,0x1, 0x68,0x2, 0xc1,0x1f, +0x4c,0xff,0x78,0x7b,0x74,0x1, 0x7a,0xb3,0x39,0xde,0x12,0xc6,0x35,0x7e,0x24,0x1, +0xf4,0x7a,0x27,0x39,0xe7,0x80,0x68,0x4c,0xee,0x78,0x17,0xa5,0xbf,0x1, 0x7, 0x74, +0x2, 0x12,0xc6,0x2c,0x80,0x41,0x74,0x4, 0x7a,0xb3,0x39,0xde,0x7e,0x34,0x0, 0x64, +0x80,0x35,0x12,0xc6,0x3e,0x7e,0x34,0x0, 0xa, 0x12,0xc6,0x24,0x68,0x32,0x80,0x3f, +0xbe,0xe0,0x1, 0x78,0x3a,0x4c,0xff,0x78,0x36,0x12,0xc6,0x3e,0x7e,0x37,0x39,0xe7, +0xbe,0x34,0x1, 0xe0,0x38,0x1a,0x7e,0x34,0x0, 0x14,0x12,0xc6,0x24,0x68,0x11,0x12, +0xc6,0x35,0x74,0x3, 0x12,0xc6,0x2c,0x7a,0x37,0x39,0xe7,0x80,0x12,0x7e,0xa0,0x24, +0xe4,0x7a,0xb3,0x39,0xde,0x6d,0x33,0x7a,0x37,0x39,0xe7,0x7c,0xba,0x80,0x2, 0x7c, +0xba,0xda,0x79,0x22,0x12,0xc4,0xf4,0xa, 0x1b,0x4d,0x11,0x22,0x7a,0xb3,0x39,0xde, +0x7e,0x34,0x1, 0xf4,0x22,0x7a,0x47,0x39,0xdf,0x7a,0x7, 0x39,0xe1,0x22,0x7a,0x47, +0x39,0xe3,0x7a,0x7, 0x39,0xe5,0x22,0x7e,0x11,0x2b,0xac,0x1f,0x3e,0x4, 0x7e,0x30, +0x2, 0xac,0x3e,0x2d,0x10,0x7e,0x1d,0x30,0x2d,0x31,0xb, 0x1a,0x20,0x7a,0x27,0x24, +0xf2,0x74,0x2, 0xac,0xbe,0x49,0x35,0x34,0x0, 0xad,0x23,0x74,0xc, 0x22,0x74,0x1, +0x7a,0xb3,0x2b,0x1, 0x7a,0xb3,0x2b,0x1d,0x22,0x3e,0x44,0x7e,0x1f,0x13,0x8a,0x2d, +0x34,0x1b,0x1a,0x50,0x22,0xa, 0x47,0x7f,0x70,0x2d,0xf4,0x7e,0x7b,0x60,0x22,0x74, +0x6, 0x7d,0x30,0x12,0x2f,0x58,0x6c,0x11,0x22,0x7e,0x70,0x2, 0xac,0x79,0x9, 0xb3, +0x1f,0x34,0x22,0x74,0x1, 0x12,0x13,0xde,0xe4,0x2, 0x0, 0x1e,0x74,0x2, 0x12,0x0, +0x1e,0x7e,0x8, 0x6, 0xfc,0x22,0x7a,0x91,0x82,0x7a,0x81,0x83,0xe4,0x93,0x22,0xb, +0xa, 0x30,0x2d,0x32,0x1b,0xa, 0x30,0x22,0x6d,0x33,0xe4,0x6c,0x55,0x2, 0x13,0x1, +0x7e,0x73,0x38,0xbe,0x7a,0x73,0x2b,0x20,0x22,0x7e,0xb3,0x38,0xe1,0x7e,0x34,0x0, +0x4, 0x22,0x12,0x0, 0x1e,0x7e,0xb3,0x2a,0xfc,0x22,0x2d,0x13,0x7e,0xb, 0x50,0xa, +0x25,0x22,0x7e,0x8, 0x2a,0x6d,0x2, 0x0, 0x2e,0x12,0x2f,0x58,0x74,0x6, 0x7d,0x30, +0x22,0x7e,0xb3,0x28,0xa8,0xbe,0xb0,0x1, 0x22,0xe4,0x12,0x13,0xde,0x2, 0x13,0x96, +0xc7,0x10,0x38,0xef,0x79,0x86,0xa, 0x51, diff --git a/drivers/input/touchscreen/ft5435/Makefile b/drivers/input/touchscreen/ft5435/Makefile new file mode 100644 index 000000000000..c161cc3a8a8f --- /dev/null +++ b/drivers/input/touchscreen/ft5435/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_TOUCHSCREEN_FT5435) += ft5435_ts.o +# for focaltech tp firmware power on upgrade + #EXTRA_CFLAGS += -DFOCALTECH_PWRON_UPGRADE + #EXTRA_CFLAGS += -DFOCALTECH_TP_GESTURE + #EXTRA_CFLAGS += -DFOCALTECH_FAE_MOD + #EXTRA_CFLAGS += -DFOCALTECH_FW_COMPAT + diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.c b/drivers/input/touchscreen/ft5435/ft5435_ts.c new file mode 100644 index 000000000000..5138fc1523f8 --- /dev/null +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.c @@ -0,0 +1,4292 @@ +/* + * + * FocalTech ft5435 TouchScreen driver. + * + * Copyright (c) 2010 Focal tech Ltd. + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ft5435_ts.h" + + +#include +#include + +#if defined(CONFIG_FB) +#include +#include + +#elif defined(CONFIG_HAS_EARLYSUSPEND) +#include +#include +/* Early-suspend level */ +#define FT_SUSPEND_LEVEL 1 +#endif + +#if defined(FOCALTECH_AUTO_UPGRADE) +#define FTS_VENDOR_1 0x3b +#define FTS_VENDOR_2 0x51 +static unsigned char firmware_data_vendor1[] = { + #include "HQ_AL1512_C6_FT5435_Biel0x3b_Ver0a_20170119_app.i" +}; + +static unsigned char firmware_data_vendor2[] = { + + #include "HQ_AL1512_C6_FT5435_Ofilm0x51_Ver0a_20170119_app.i" +}; +#endif +#define TCT_KEY_BACK 158 +#define TCT_KEY_HOME 172 +#define TCT_KEY_MENU 139 + + + +#define TCT_KEY_BACK_POS_X 100 +#define TCT_KEY_BACK_POS_Y 1321 + +#define TCT_KEY_HOME_POS_X 360 +#define TCT_KEY_HOME_POS_Y 1321 + +#define TCT_KEY_MENU_POS_X 620 +#define TCT_KEY_MENU_POS_Y 1321 + +#define TX_NUM_MAX 50 +#define RX_NUM_MAX 50 + + + +/* [PLATFORM]-Mod-BEGIN by TCTNB.ZXZ, PR-814306, 2014/10/24, add for rawdata test */ +#define CONFIG_TCT_TP_FTDEBUG + +/* [PLATFORM]-Mod-END by TCTNB.ZXZ */ + +#define FT_DRIVER_VERSION 0x02 + +#define TRULY 0x79 +#define CHAOSHENG 0x57 + +#define FT_META_REGS 3 +#define FT_ONE_TCH_LEN 6 +#define FT_TCH_LEN(x) (FT_META_REGS + FT_ONE_TCH_LEN * x) + +#define FT_PRESS 0x7F +#define FT_MAX_ID 0x0F +#define FT_TOUCH_X_H_POS 3 +#define FT_TOUCH_X_L_POS 4 +#define FT_TOUCH_Y_H_POS 5 +#define FT_TOUCH_Y_L_POS 6 +#define FT_TD_STATUS 2 +#define FT_TOUCH_EVENT_POS 3 +#define FT_TOUCH_ID_POS 5 +#define FT_TOUCH_DOWN 0 +#define FT_TOUCH_CONTACT 2 + +/*register address*/ +#define FT_REG_DEV_MODE 0x00 +#define FT_DEV_MODE_REG_CAL 0x02 +#define FT_REG_ID 0xA3 +#define FT_REG_PMODE 0xA5 +#define FT_REG_FW_VER 0xA6 +#define FT_REG_FW_VENDOR_ID 0xA8 +#define FT_REG_POINT_RATE 0x88 +#define FT_REG_THGROUP 0x80 +#define FT_REG_ECC 0xCC +#define FT_REG_RESET_FW 0x07 +#define FT_REG_FW_MIN_VER 0xB2 +#define FT_REG_FW_SUB_MIN_VER 0xB3 + +/* power register bits*/ +#define FT_PMODE_ACTIVE 0x00 +#define FT_PMODE_MONITOR 0x01 +#define FT_PMODE_STANDBY 0x02 +#define FT_PMODE_HIBERNATE 0x03 +#define FT_FACTORYMODE_VALUE 0x40 +#define FT_WORKMODE_VALUE 0x00 +#define FT_RST_CMD_REG1 0xFC +#define FT_RST_CMD_REG2 0xBC +#define FT_READ_ID_REG 0x90 +#define FT_ERASE_APP_REG 0x61 +#define FT_ERASE_PANEL_REG 0x63 +#define FT_FW_START_REG 0xBF + +#define FT_STATUS_NUM_TP_MASK 0x0F + +#define FT_VTG_MIN_UV 2600000 +#define FT_VTG_MAX_UV 3300000 +#define FT_I2C_VTG_MIN_UV 1800000 +#define FT_I2C_VTG_MAX_UV 1800000 + +#define FT_COORDS_ARR_SIZE 4 +#define MAX_BUTTONS 4 + +#define FT_8BIT_SHIFT 8 +#define FT_4BIT_SHIFT 4 +#define FT_FW_NAME_MAX_LEN 50 + +#define FT5316_ID 0x0A +#define FT5306I_ID 0x55 +#define FT6X06_ID 0x06 +#define FT6X36_ID 0x36 +#define FT5X46_ID 0x54 + +#define FT_UPGRADE_AA 0xAA +#define FT_UPGRADE_55 0x55 + +#define FT_FW_MIN_SIZE 8 +#define FT_FW_MAX_SIZE 65536 + +/* Firmware file is not supporting minor and sub minor so use 0 */ +#define FT_FW_FILE_MAJ_VER(x) ((x)->data[(x)->size - 2]) +#define FT_FW_FILE_MIN_VER(x) 0 +#define FT_FW_FILE_SUB_MIN_VER(x) 0 +#define FT_FW_FILE_VENDOR_ID(x) ((x)->data[(x)->size - 1]) + +#define FT_FW_FILE_MAJ_VER_FT6X36(x) ((x)->data[0x10a]) +#define FT_FW_FILE_VENDOR_ID_FT6X36(x) ((x)->data[0x108]) + +/** +* Application data verification will be run before upgrade flow. +* Firmware image stores some flags with negative and positive value +* in corresponding addresses, we need pick them out do some check to +* make sure the application data is valid. +*/ +#define FT_FW_CHECK(x, ts_data) \ + (ts_data->family_id == FT6X36_ID ? \ + (((x)->data[0x104] ^ (x)->data[0x105]) == 0xFF \ + && ((x)->data[0x106] ^ (x)->data[0x107]) == 0xFF) : \ + (((x)->data[(x)->size - 8] ^ (x)->data[(x)->size - 6]) == 0xFF \ + && ((x)->data[(x)->size - 7] ^ (x)->data[(x)->size - 5]) == 0xFF \ + && ((x)->data[(x)->size - 3] ^ (x)->data[(x)->size - 4]) == 0xFF)) + +#define FT_MAX_TRIES 5 +#define FT_RETRY_DLY 20 + +#define FT_MAX_WR_BUF 10 +#define FT_MAX_RD_BUF 2 +#define FT_FW_PKT_LEN 128 +#define FT_FW_PKT_META_LEN 6 +#define FT_FW_PKT_DLY_MS 20 +#define FT_FW_LAST_PKT 0x6ffa +#define FT_EARSE_DLY_MS 100 +#define FT_55_AA_DLY_NS 5000 + +#define FT_UPGRADE_LOOP 30 +#define FT_CAL_START 0x04 +#define FT_CAL_FIN 0x00 +#define FT_CAL_STORE 0x05 +#define FT_CAL_RETRY 100 +#define FT_REG_CAL 0x00 +#define FT_CAL_MASK 0x70 + +#define FT_INFO_MAX_LEN 512 + +#define FT_BLOADER_SIZE_OFF 12 +#define FT_BLOADER_NEW_SIZE 30 +#define FT_DATA_LEN_OFF_OLD_FW 8 +#define FT_DATA_LEN_OFF_NEW_FW 14 +#define FT_FINISHING_PKT_LEN_OLD_FW 6 +#define FT_FINISHING_PKT_LEN_NEW_FW 12 +#define FT_MAGIC_BLOADER_Z7 0x7bfa +#define FT_MAGIC_BLOADER_LZ4 0x6ffa +#define FT_MAGIC_BLOADER_GZF_30 0x7ff4 +#define FT_MAGIC_BLOADER_GZF 0x7bf4 + +enum { + FT_BLOADER_VERSION_LZ4 = 0, + FT_BLOADER_VERSION_Z7 = 1, + FT_BLOADER_VERSION_GZF = 2, +}; + +enum { + FT_FT5336_FAMILY_ID_0x11 = 0x11, + FT_FT5336_FAMILY_ID_0x12 = 0x12, + FT_FT5336_FAMILY_ID_0x13 = 0x13, + FT_FT5336_FAMILY_ID_0x14 = 0x14, +}; + +enum proximity_sensor_vendor { + TAOS = 1, + STK, + TOTAL, +}; + +extern int set_usb_charge_mode_par; +extern int TX_NUM; +extern int RX_NUM; +extern int SCab_1; +extern int SCab_2; +extern int SCab_3; +extern int SCab_4; +extern int SCab_5; +extern int SCab_6; +extern int SCab_7; +extern int SCab_8; +extern int Save_rawData1[TX_NUM_MAX][RX_NUM_MAX]; + + +#define FTS_FACTORYMODE_VALUE 0x40 +#define FTS_WORKMODE_VALUE 0x00 +static struct i2c_client *ft_g_client; + +#define FT_STORE_TS_INFO(buf, id, name, max_tch, group_id, fw_vkey_support, \ + fw_name, fw_maj, fw_min, fw_sub_min) \ + snprintf(buf, FT_INFO_MAX_LEN, \ + "controller\t= focaltech\n" \ + "model\t\t= 0x%x\n" \ + "name\t\t= %s\n" \ + "max_touches\t= %d\n" \ + "drv_ver\t\t= 0x%x\n" \ + "group_id\t= 0x%x\n" \ + "fw_vkey_support\t= %s\n" \ + "fw_name\t\t= %s\n" \ + "fw_ver\t\t= %d.%d.%d\n", id, name, \ + max_tch, FT_DRIVER_VERSION, group_id, \ + fw_vkey_support, fw_name, fw_maj, fw_min, \ + fw_sub_min) + +#define FT_DEBUG_DIR_NAME "ts_debug" + + u8 fts_fw_vendor_id; + +struct ft5435_ts_data { + struct i2c_client *client; + struct input_dev *input_dev; + const struct ft5435_ts_platform_data *pdata; + struct regulator *vdd; + struct regulator *vcc_i2c; + char fw_name[FT_FW_NAME_MAX_LEN]; + bool loading_fw; + u8 family_id; + struct dentry *dir; + u16 addr; + bool suspended; + char *ts_info; + u8 *tch_data; + u32 tch_data_len; + u8 fw_ver[3]; + int touch_log_switch; +#if defined(FOCALTECH_FW_COMPAT) + u8 fw_compat; +#endif +#if defined(FOCALTECH_PWRON_UPGRADE) + struct delayed_work focaltech_update_work; +#endif + u8 fw_vendor_id; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif + + struct pinctrl *ts_pinctrl; + struct pinctrl_state *gpio_state_active; + struct pinctrl_state *gpio_state_suspend; + +#if defined(FOCALTECH_TP_GLOVE) + u8 glove_id; +#endif + +#if defined(USB_CHARGE_DETECT) +struct work_struct work; +u8 charger_in; +#endif +#if defined(LEATHER_COVER) +struct work_struct work_cover; +u8 cover_on; +#endif +#if defined(VR_GLASS) +struct work_struct work_vr; +u8 vr_on; +#endif +}; +bool is_ft5435 = false; +struct wake_lock ft5436_wakelock; + +static int ft5435_i2c_read(struct i2c_client *client, char *writebuf, + int writelen, char *readbuf, int readlen); +static int ft5x0x_read_reg(struct i2c_client *client, u8 addr, u8 *val); + +#ifdef CONFIG_TOUCHPANEL_PROXIMITY_SENSOR +struct virtualpsensor { + char const *name; + struct input_dev *proximity_dev; + int proximity_function; + int vps_enabled; + struct sensors_classdev vps_cdev; + int value; +}; + +struct virtualpsensor *vps_ft5436; + +#define VPS_NAME "virtual-proximity" + +struct sensors_classdev virtual_sensors_proximity_cdev2 = { + .name = VPS_NAME, + .vendor = "NULL", + .version = 1, + .handle = SENSORS_PROXIMITY_HANDLE, + .type = SENSOR_TYPE_PROXIMITY, + .max_range = "5", + .resolution = "5.0", + .sensor_power = "3", + .min_delay = 0, /* in microseconds */ + .fifo_reserved_event_count = 0, + .fifo_max_event_count = 0, + .enabled = 0, + .delay_msec = 100, + .sensors_enable = NULL, + .sensors_poll_delay = NULL, +}; + +static int vps_set_enable(struct sensors_classdev *sensors_cdev, unsigned int enable); + +static void tp_prox_sensor_enable(struct i2c_client *client, int enable); +#endif +static int ft5435_i2c_write(struct i2c_client *client, char *writebuf, int writelen); +static struct workqueue_struct *ft5435_wq_cover; +#if defined(VR_GLASS) +static struct workqueue_struct *ft5435_wq_vr; +#endif +static struct workqueue_struct *ft5435_wq; +static struct ft5435_ts_data *g_ft5435_ts_data; + +static int init_ok; +module_param_named(init_ok, init_ok, int, 0644); + + + +static void ft5435_update_fw_ver(struct ft5435_ts_data *data) +{ + struct i2c_client *client = data->client; + u8 reg_addr; + int err; + + reg_addr = FT_REG_FW_VER; + err = ft5435_i2c_read(client, ®_addr, 1, &data->fw_ver[0], 1); + if (err < 0) + dev_err(&client->dev, "fw major version read failed"); + + reg_addr = FT_REG_FW_MIN_VER; + err = ft5435_i2c_read(client, ®_addr, 1, &data->fw_ver[1], 1); + if (err < 0) + dev_err(&client->dev, "fw minor version read failed"); + + reg_addr = FT_REG_FW_SUB_MIN_VER; + err = ft5435_i2c_read(client, ®_addr, 1, &data->fw_ver[2], 1); + if (err < 0) + dev_err(&client->dev, "fw sub minor version read failed"); + + dev_info(&client->dev, "Firmware version = %d.%d.%d\n", + data->fw_ver[0], data->fw_ver[1], data->fw_ver[2]); +} + +static struct mutex g_device_mutex; + +#if defined(FOCALTECH_TP_GESTURE) + +/* [PLATFORM]-Mod-BEGIN by TCTNB.YQJ, FR797197, 2014/11/28 modify for 5x36 tp register of gesture */ +#define FT5435_REG_GESTURE_SET 0xd0 +#define FT5435_REG_GESTURE_STATE 0xd3 + +#define GESTURE_DB 0x24 + +/* [PLATFORM]-Mod-END by TCTNB.YQJ */ +static int ft_tp_suspend(struct ft5435_ts_data *data); +#endif +static int ft5435_i2c_read(struct i2c_client *client, char *writebuf, + int writelen, char *readbuf, int readlen) +{ + int ret; + if (writelen > 0) { + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = writelen, + .buf = writebuf, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = readlen, + .buf = readbuf, + }, + }; + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret < 0) + dev_err(&client->dev, "%s: i2c read error.\n", + __func__); + } else { + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = readlen, + .buf = readbuf, + }, + }; + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) + dev_err(&client->dev, "%s:i2c read error.\n", __func__); + } + return ret; +} + +static int ft5435_i2c_write(struct i2c_client *client, char *writebuf, + int writelen) +{ + int ret; + + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = writelen, + .buf = writebuf, + }, + }; + ret = i2c_transfer(client->adapter, msgs, 1); + if (ret < 0) + dev_err(&client->dev, "%s: i2c write error.\n", __func__); + return ret; +} + +#if defined(FOCALTECH_TP_GLOVE) + +#define FOCALTECH_TP_GLOVE_SET 0xc0 +#define FOCALTECH_TP_GLOVE_ENABLE 0x01 + +static struct device *tp_glove_dev; + +/* + u8 glove_id; 0: close glove function, 1: open glove function +*/ +static ssize_t tp_glove_id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ft5435_ts_data *data = NULL; + int ret; + + data = dev_get_drvdata(dev); + + ret = snprintf(buf, 50, "glove_id show:%d\n", data->glove_id); + + return ret; +} + +static ssize_t tp_glove_id_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ft5435_ts_data *data = NULL; + unsigned long val = 0; + char val_read = 0; + ssize_t ret = -EINVAL; + char txbuf[2]; + txbuf[0] = FOCALTECH_TP_GLOVE_SET; + + + data = dev_get_drvdata(dev); + + if (data->suspended) + return ret; + + ret = kstrtoul(buf, 10, &val); + if (ret) + return ret; + + + if (0 == val) { + data->glove_id = 0x00; + txbuf[1] = 0x00; + ft5435_i2c_write(data->client, txbuf, sizeof(txbuf)); + } else + if (1 == val) { + data->glove_id = 0x01; + txbuf[1] = FOCALTECH_TP_GLOVE_ENABLE; + ft5435_i2c_write(data->client, txbuf, sizeof(txbuf)); + } else { + pr_err("invalid command! \n"); + return -EPERM; + } + printk("set glove_id = %d \n", data->glove_id); + ft5435_i2c_read(data->client, &txbuf[0], 1, &val_read, 1); + printk("read glove_id = %d\n", val_read); + + return size; +} +static DEVICE_ATTR(glove_enable, 0644, tp_glove_id_show, tp_glove_id_store); + +void tp_glove_register (struct ft5435_ts_data *data) +{ + int rc = 0; + + tp_glove_dev = device_create(tp_device_class, NULL, 0, NULL, "tp_glove"); + if (IS_ERR(tp_glove_dev)) + pr_err("Failed to create device(glove_ctrl)!\n"); + + + rc = device_create_file(tp_glove_dev, &dev_attr_glove_enable); + if (rc < 0) + pr_err("Failed to create device file(%s)!\n", dev_attr_glove_enable.attr.name); + dev_set_drvdata(tp_glove_dev, data); + + printk("~~~~~ %s enable!!!!!\n", __func__); + +} +#endif + + + +static int ft5x0x_write_reg(struct i2c_client *client, u8 addr, const u8 val) +{ + u8 buf[2] = {0}; + + buf[0] = addr; + buf[1] = val; + + return ft5435_i2c_write(client, buf, sizeof(buf)); +} + +static int ft5x0x_read_reg(struct i2c_client *client, u8 addr, u8 *val) +{ + return ft5435_i2c_read(client, &addr, 1, val, 1); +} +#ifdef CONFIG_TOUCHPANEL_PROXIMITY_SENSOR +int virtual_psensor_input_register2(struct i2c_client *pClient) +{ + s32 nRetVal = 0; + + pr_err("*** %s() ***\n", __func__); + + vps_ft5436->proximity_dev = input_allocate_device(); + if (vps_ft5436->proximity_dev == NULL) { + pr_err("*** input device allocation failed ***\n"); + return -ENOMEM; + } + + vps_ft5436->proximity_dev->name = "proximity"; + vps_ft5436->proximity_dev->id.bustype = BUS_I2C; + + /* set the supported event type for input device */ + set_bit(EV_ABS, vps_ft5436->proximity_dev->evbit); + set_bit(ABS_DISTANCE, vps_ft5436->proximity_dev->absbit); + input_set_abs_params(vps_ft5436->proximity_dev, ABS_DISTANCE, 0, 1, 0, 0); + + nRetVal = input_register_device(vps_ft5436->proximity_dev); + if (nRetVal < 0) { + pr_err("*** Unable to register virtual P-sensor input device ***\n"); + return nRetVal; + } + + vps_ft5436->vps_cdev = virtual_sensors_proximity_cdev2; + vps_ft5436->vps_cdev.sensors_enable = vps_set_enable; + vps_ft5436->vps_cdev.sensors_poll_delay = NULL; + + nRetVal = sensors_classdev_register(&pClient->dev, &vps_ft5436->vps_cdev); + if (nRetVal) { + pr_err("%s: Unable to register to sensors class: %d\n", __func__, nRetVal); + return nRetVal; + } + + return 0; +} +static void tp_prox_sensor_enable(struct i2c_client *client, int enable) +{ + u8 state; + int ret = -1; + + if (client == NULL) + return; + + if (gpio_is_valid(g_ft5435_ts_data->pdata->reset_gpio)) { + gpio_set_value_cansleep(g_ft5435_ts_data->pdata->reset_gpio, 0); + printk("reset tp ~~~ \n"); + msleep(g_ft5435_ts_data->pdata->hard_rst_dly); + gpio_set_value_cansleep(g_ft5435_ts_data->pdata->reset_gpio, 1); + } + msleep(g_ft5435_ts_data->pdata->soft_rst_dly); + + if (enable) { + state = 0x01; + } else{ + state = 0x00; + } + ret = ft5x0x_write_reg(client, 0xB0, state); + if (ret < 0) + printk("[proxi_5206]write psensor switch command failed\n"); + ft5x0x_read_reg(client, 0xB0, &state); + printk(" proximity function status[0x%x]\n", state); + if ((!enable) && (g_ft5435_ts_data->suspended) && (g_ft5435_ts_data->gesture_id > 0)) { + printk("double click function enable again \n"); + ft_tp_suspend(g_ft5435_ts_data); + } + + return; +} +static int vps_set_enable(struct sensors_classdev *sensors_cdev, unsigned int enable) +{ + u8 status, reg_value; + + printk("FT vps_set_enable in. enable[%d]\n", enable); + vps_ft5436->vps_enabled = enable ? 1 : 0; + if (enable == 1) { + ft5x0x_read_reg(g_ft5435_ts_data->client, 0xB0, ®_value); + printk("FT proxi_fts 0xB0 state value is0x%02X\n", reg_value); + if (!(reg_value&0x01)) + tp_prox_sensor_enable(g_ft5435_ts_data->client, 1); + ft5x0x_read_reg(g_ft5435_ts_data->client, 0x01, &status); + printk("FT 0x01 reg status[0x%x]\n", status); + if (status == 0xC0) { + input_report_abs(vps_ft5436->proximity_dev, ABS_DISTANCE, 0); + input_sync(vps_ft5436->proximity_dev); + } else if (status == 0xE0) { + input_report_abs(vps_ft5436->proximity_dev, ABS_DISTANCE, 1); + input_sync(vps_ft5436->proximity_dev); + } + } + + return 0; +} + +ssize_t ft_virtual_proximity_enable_show(struct device *pDevice, struct device_attribute *pAttr, char *pBuf) +{ + return sprintf(pBuf, "%d", vps_ft5436->vps_enabled); +} +ssize_t ft_virtual_proximity_enable_store(struct device *pDevice, struct device_attribute *pAttr, const char *pBuf, size_t nSize) +{ + int enable; + if (pBuf != NULL) { + sscanf(pBuf, "%d\n", &enable); + vps_set_enable(&vps_ft5436->vps_cdev, enable); + if (g_ft5435_ts_data->gesture_id == 0) { + if (enable) + device_init_wakeup(&g_ft5435_ts_data->client->dev, 1); + else + device_init_wakeup(&g_ft5435_ts_data->client->dev, 0); + } + } + return nSize; +} + +static DEVICE_ATTR(enable, 0664, ft_virtual_proximity_enable_show, ft_virtual_proximity_enable_store); + +ssize_t ft_proximity_function_enable_show(struct device *pDevice, struct device_attribute *pAttr, char *pBuf) +{ + return sprintf(pBuf, "%x", vps_ft5436->proximity_function); +} + +ssize_t ft_proximity_function_enable_store(struct device *pDevice, struct device_attribute *pAttr, const char *pBuf, size_t nSize) +{ + u32 nProximityMode; + if (pBuf != NULL) { + sscanf(pBuf, "%x", &nProximityMode); + printk("nProximityMode = 0x%x\n", nProximityMode); + vps_ft5436->proximity_function = nProximityMode; + tp_prox_sensor_enable(g_ft5435_ts_data->client, nProximityMode); + } + return nSize; +} + +static DEVICE_ATTR(proximity, 0664, ft_proximity_function_enable_show, ft_proximity_function_enable_store); + +static int sys_device_create(void) +{ + struct class *virtual_proximity = NULL; + struct device *virtual_proximity_device = NULL; + + virtual_proximity = class_create(THIS_MODULE, "virtual-proximity"); + if (IS_ERR(virtual_proximity)) + printk("Failed to create class(virtual_proximity)!\n"); + + virtual_proximity_device = device_create(virtual_proximity, NULL, 0, NULL, "device"); + if (IS_ERR(virtual_proximity_device)) + printk("Failed to create device(virtual_proximity_device)!\n"); + + if (device_create_file(virtual_proximity_device, &dev_attr_enable) < 0) + printk("Failed to create device file(%s)!\n", dev_attr_enable.attr.name); + + if (device_create_file(virtual_proximity_device, &dev_attr_proximity) < 0) + printk("Failed to create device file(%s)!\n", dev_attr_enable.attr.name); + + return 0; +} + +#endif +#if defined(LEATHER_COVER) +void ft5435_enable_leather_cover(void) +{ + struct ft5435_ts_data *data; + + if (!ft_g_client) + return ; + if (init_ok == 0) + return; + printk("[wxc]%s\n", __func__); + data = g_ft5435_ts_data; + + data->cover_on = 1; + + queue_work(ft5435_wq_cover, &data->work_cover); +} +EXPORT_SYMBOL(ft5435_enable_leather_cover); +void ft5435_disable_leather_cover(void) +{ + struct ft5435_ts_data *data; + + + if (!ft_g_client) + return ; + if (init_ok == 0) + return; + printk("[wxc]%s\n", __func__); + data = g_ft5435_ts_data; + + data->cover_on = 0; + + queue_work(ft5435_wq_cover, &data->work_cover); +} +EXPORT_SYMBOL(ft5435_disable_leather_cover); +void ft5435_change_leather_cover_switch(struct work_struct *work) +{ + u8 cover_flag = 0; + struct ft5435_ts_data *data; + + + data = g_ft5435_ts_data; + + if (data->suspended) { + printk(KERN_ERR"data->suspended, data->cover_on = %d \n", data->cover_on); + return ; + } + if (ft_g_client == NULL) + return ; + ft5x0x_read_reg(ft_g_client, 0xc1, &cover_flag); + printk("[Fu]%s cover_flag=%d, data->cover_on=%d\n", __func__, cover_flag, data->cover_on); + if (cover_flag != data->cover_on) { + printk(KERN_ERR"[Fu]%s: Write %d to 0xc1\n", __FUNCTION__, data->cover_on); + ft5x0x_write_reg(ft_g_client, 0xc1, data->cover_on); + } +} + +#endif +#if defined(VR_GLASS) +void ft5435_enable_vr(void) +{ + struct ft5435_ts_data *data; + + if (!ft_g_client) + return ; + if (init_ok == 0) + return; + printk("[wxc]%s\n", __func__); + data = g_ft5435_ts_data; + + data->vr_on = 1; + + queue_work(ft5435_wq_vr, &data->work_vr); +} +EXPORT_SYMBOL(ft5435_enable_vr); +void ft5435_disable_vr(void) +{ + struct ft5435_ts_data *data; + + if (!ft_g_client) + return ; + if (init_ok == 0) + return; + printk("[wxc]%s\n", __func__); + data = g_ft5435_ts_data; + + data->vr_on = 0; + + queue_work(ft5435_wq_vr, &data->work_vr); +} +EXPORT_SYMBOL(ft5435_disable_vr); +void ft5435_change_vr_switch(struct work_struct *work) +{ + u8 vr_flag = 0; + struct ft5435_ts_data *data; + + + data = g_ft5435_ts_data; + + if (data->suspended) { + printk(KERN_ERR"data->suspended, data->vr_on = %d \n", data->vr_on); + return ; + } + if (ft_g_client == NULL) + return ; + ft5x0x_read_reg(ft_g_client, 0xc1, &vr_flag); + printk("[wxc]%s cover_flag=%d, data->vr_on=%d\n", __func__, vr_flag, data->vr_on); + if (vr_flag != data->vr_on) { + printk(KERN_ERR"[wxc]%s: Write %d to 0xc1\n", __FUNCTION__, data->vr_on); + ft5x0x_write_reg(ft_g_client, 0xc1, data->vr_on); + } +} + +#endif +#if defined(USB_CHARGE_DETECT) +void ft5435_enable_change_scanning_frq(void) +{ + struct ft5435_ts_data *data; + + if (!ft_g_client) + return ; + if (init_ok == 0) + return; + + data = g_ft5435_ts_data; + + data->charger_in = 1; + pr_debug("%s \n", __func__); + + queue_work(ft5435_wq, &data->work); +} +EXPORT_SYMBOL(ft5435_enable_change_scanning_frq); +void ft5435_disable_change_scanning_frq(void) +{ + struct ft5435_ts_data *data; + + + if (!ft_g_client) + return ; + if (init_ok == 0) + return; + + data = g_ft5435_ts_data; + + data->charger_in = 0; + pr_debug("%s \n", __func__); + + queue_work(ft5435_wq, &data->work); +} +EXPORT_SYMBOL(ft5435_disable_change_scanning_frq); +void ft5435_change_scanning_frq_switch(struct work_struct *work) +{ + u8 charger_in_flag = 0; + struct ft5435_ts_data *data; + + + data = container_of(work, struct ft5435_ts_data, work); + + if (data->suspended) { + printk(KERN_ERR"changer_in = %d \n", data->charger_in); + return ; + } + if (ft_g_client == NULL) + return ; + ft5x0x_read_reg(ft_g_client, 0x8b, &charger_in_flag); + + if (charger_in_flag != data->charger_in) { + printk(KERN_ERR"[ft5435]%s: Write %d to 0x8b\n", __FUNCTION__, data->charger_in); + ft5x0x_write_reg(ft_g_client, 0x8b, data->charger_in); + } +} + +void tpd_usb_plugin(bool mode) +{ + struct ft5435_ts_data *data = g_ft5435_ts_data; + int ret = -1; + if (data->suspended) + return ; + if (ft_g_client == NULL) + return ; + ret = ft5x0x_write_reg(ft_g_client, 0x8b, mode); + if (ret < 0) + pr_err("usb detect write err: %s %d.\n", __FUNCTION__, mode); +} + +#else +void ft5435_enable_change_scanning_frq(void) +{ +} +EXPORT_SYMBOL(ft5435_enable_change_scanning_frq); +void ft5435_disable_change_scanning_frq(void) +{ +} +EXPORT_SYMBOL(ft5435_disable_change_scanning_frq); +#endif +static void ft5435_update_fw_vendor_id(struct ft5435_ts_data *data) +{ + struct i2c_client *client = data->client; + u8 reg_addr; + int err; + + reg_addr = FT_REG_FW_VENDOR_ID; + err = ft5435_i2c_read(client, ®_addr, 1, &data->fw_vendor_id, 1); + if (err < 0) + dev_err(&client->dev, "fw vendor id read failed"); + printk("[Fu]fw_vendor_id=0x%x\n", data->fw_vendor_id); +} + + +int fts_ctpm_auto_clb(struct i2c_client *client) +{ + unsigned char uc_temp = 0x00; + unsigned char i = 0; + + /*start auto CLB */ + msleep(200); + + ft5x0x_write_reg(client, 0, FTS_FACTORYMODE_VALUE); + /*make sure already enter factory mode */ + msleep(100); + /*write command to start calibration */ + ft5x0x_write_reg(client, 2, 0x4); + msleep(300); + for (i = 0; i < 100; i++) { + ft5x0x_read_reg(client, 0, &uc_temp); + /*return to normal mode, calibration finish */ + if (0x0 == ((uc_temp & 0x70) >> 4)) + break; + } + + msleep(200); + /*calibration OK */ + msleep(300); + ft5x0x_write_reg(client, 0, FTS_FACTORYMODE_VALUE); /*goto factory mode for store */ + msleep(100); /*make sure already enter factory mode */ + ft5x0x_write_reg(client, 2, 0x5); /*store CLB result */ + msleep(300); + ft5x0x_write_reg(client, 0, FTS_WORKMODE_VALUE); /*return to normal mode */ + msleep(300); + + /*store CLB result OK */ + return 0; +} + + +/* [PLATFORM]-Mod-BEGIN by TCTNB.ZXZ, PR-814306, 2014/10/24, add for alto5 premium firmware version*/ +#ifdef CONFIG_TCT_8X16_ALTO5_PREMIUM +static struct class *firm_ver_class; +static struct device *firm_ver_dev; + +static ssize_t firm_ver_show (struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 reg_ver; + u8 reg_vendor; + u8 ver_value, vendor_value; + int err; + reg_ver = FT_REG_FW_VER; + err = ft5435_i2c_read(ft_g_client, ®_ver, 1, &ver_value, 1); + if (err < 0) { + pr_err("TP FW version read failure\n"); + return sprintf (buf, "can't read firmware version \n"); + } + pr_err("0xA6=0x%x\n", ver_value); + reg_vendor = 0xA8; + err = ft5435_i2c_read(ft_g_client, ®_vendor, 1, &vendor_value, 1); + if (err < 0) { + pr_err("TP FW version read failure\n"); + return sprintf (buf, "ft irmware version(0xA6) is 0x%x\n can't read tp moudule version \n" , ver_value); + } + pr_err("0xA8=0x%x\n", vendor_value); + + return sprintf (buf, "ft TP module (0xA8)is 0x%x , fimware version(0xA6) is 0x%x\n", vendor_value, ver_value); +} + +static DEVICE_ATTR(firm_ver, 0664, firm_ver_show, NULL); + + +static void firm_ver_attr_create(void) +{ + firm_ver_class = class_create(THIS_MODULE, "firmware_ver"); + if (IS_ERR(firm_ver_class)) + pr_err("Failed to create class(firm_ver_class)!\n"); + firm_ver_dev = device_create(firm_ver_class, + NULL, 0, NULL, "device"); + if (IS_ERR(firm_ver_dev)) + pr_err("Failed to create device(gt_dclick_dev)!\n"); + + + if (device_create_file(firm_ver_dev, &dev_attr_firm_ver) < 0) + pr_err("Failed to create device file(%s)!\n", dev_attr_firm_ver.attr.name); +} +#endif +/* [PLATFORM]-Mod-END by TCTNB.ZXZ*/ + +#if defined(FOCALTECH_TP_GESTURE) +#define WAKEUP_OFF 4 +#define WAKEUP_ON 5 +static bool gesture_func_on = true; +static int ft5435_gesture_switch(struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + if (type == EV_SYN && code == SYN_CONFIG) { + if (value == WAKEUP_OFF) { + gesture_func_on = false; + } else if (value == WAKEUP_ON) { + gesture_func_on = true; + } + } + return 0; +} + +static int ft_tp_interrupt(struct ft5435_ts_data *data) +{ + int rc = 0; + u8 reg_value, reg = 0x00; + printk("[FTS]%s start\n", __func__); + reg = FT5435_REG_GESTURE_STATE; + rc = ft5435_i2c_read(data->client, ®, 1, ®_value, 1); + if (rc < 0) { + dev_err(&data->client->dev, "%s: read data fail\n", __func__); + return rc; + } + + if (GESTURE_DB == reg_value) { + input_report_key(data->input_dev, KEY_WAKEUP, 1); + input_sync(data->input_dev); + input_report_key(data->input_dev, KEY_WAKEUP, 0); + input_sync(data->input_dev); + printk("[FTS]gesture KEY_POWER\n"); + } else { + printk("[FTS]gesture_id, reg_value=0x%x \n", reg_value); + } + + return rc; +} +#endif +static irqreturn_t ft5435_ts_interrupt(int irq, void *dev_id) +{ +#if 1 + struct ft5435_ts_data *data = dev_id; + struct input_dev *ip_dev; + int rc, i, j; + u32 id, x, y, status, num_touches; + u8 reg = 0x00, *buf; + bool update_input = false; + + #ifdef CONFIG_TOUCHPANEL_PROXIMITY_SENSOR + u8 reg_value; + u8 proximity_status; + #endif + #ifdef FOCALTECH_TP_GESTURE + int ret = 0; + u8 state = 0; + #endif + + if (!data) { + pr_err("%s: Invalid data\n", __func__); + return IRQ_HANDLED; + } +#if defined(FOCALTECH_TP_GESTURE) + if (gesture_func_on) { + ret = ft5x0x_read_reg(data->client, 0xd0, &state); + if (ret < 0) + printk("[FTS]read value fail\n"); + + if (state == 1) { + ft_tp_interrupt(data); + return IRQ_HANDLED; + } + } +#endif + + ip_dev = data->input_dev; + buf = data->tch_data; +#ifdef CONFIG_TOUCHPANEL_PROXIMITY_SENSOR + if (vps_ft5436->vps_enabled) { + ft5x0x_read_reg(data->client, 0xB0, ®_value); + printk("proxi_fts 0xB0 state value is0x%02X\n", reg_value); + if (!(reg_value&0x01)) + tp_prox_sensor_enable(data->client, 1); + ft5x0x_read_reg(data->client, 0x01, &proximity_status); + printk("FT 0x01 reg proximity_status[0x%x]--%s\n", proximity_status, __FUNCTION__); + if (proximity_status == 0xC0) { + input_report_abs(vps_ft5436->proximity_dev, ABS_DISTANCE, 0); + input_sync(vps_ft5436->proximity_dev); + printk("[Fu]close\n"); + } else if (proximity_status == 0xE0) { + wake_lock_timeout(&ft5436_wakelock, 1*HZ); + input_report_abs(vps_ft5436->proximity_dev, ABS_DISTANCE, 1); + input_sync(vps_ft5436->proximity_dev); + printk("[Fu]leave\n"); + } + } +#endif + + + + rc = ft5435_i2c_read(data->client, ®, 1, + buf, data->tch_data_len); + if (rc < 0) { + dev_err(&data->client->dev, "%s: read data fail\n", __func__); + return IRQ_HANDLED; + } + + for (i = 0; i < data->pdata->num_max_touches; i++) { + id = (buf[FT_TOUCH_ID_POS + FT_ONE_TCH_LEN * i]) >> 4; + if (id >= FT_MAX_ID) + break; + + update_input = true; + + x = (buf[FT_TOUCH_X_H_POS + FT_ONE_TCH_LEN * i] & 0x0F) << 8 | + (buf[FT_TOUCH_X_L_POS + FT_ONE_TCH_LEN * i]); + y = (buf[FT_TOUCH_Y_H_POS + FT_ONE_TCH_LEN * i] & 0x0F) << 8 | + (buf[FT_TOUCH_Y_L_POS + FT_ONE_TCH_LEN * i]); + + status = buf[FT_TOUCH_EVENT_POS + FT_ONE_TCH_LEN * i] >> 6; + + num_touches = buf[FT_TD_STATUS] & FT_STATUS_NUM_TP_MASK; + + /* invalid combination */ + if (!num_touches && !status && !id) + break; + input_mt_slot(ip_dev, id); + + if (status == FT_TOUCH_DOWN) + printk("[FTS]Down pid[%d]:[%d, %d]\n", id, x, y); + else if (status == 1) + printk("[FTS]Up pid[%d]:[%d, %d]\n", id, x, y); + + if (x < data->pdata->panel_maxx && y < data->pdata->panel_maxy) { + if (status == FT_TOUCH_DOWN || status == FT_TOUCH_CONTACT) { + input_mt_report_slot_state(ip_dev, MT_TOOL_FINGER, 1); + input_report_abs(ip_dev, ABS_MT_POSITION_X, x); + input_report_abs(ip_dev, ABS_MT_POSITION_Y, y); + } else { + input_mt_report_slot_state(ip_dev, MT_TOOL_FINGER, 0); + } + } else{ + if (data->pdata->fw_vkey_support) { + for (j = 0; j < data->pdata->num_virkey; j++) { + if (x == data->pdata->vkeys[j].x) { + if (status == FT_TOUCH_DOWN || status == FT_TOUCH_CONTACT) + input_report_key(data->input_dev, data->pdata->vkeys[j].keycode, true); + else { + input_report_key(data->input_dev, data->pdata->vkeys[j].keycode, false); + } + } + } + } + } + } + + if (update_input) { +#if defined(FOCALTECH_FAE_MOD) + if (num_touches == 0) { /* release all touches */ + for (i = 0; i < data->pdata->num_max_touches; i++) { + input_mt_slot(data->input_dev, i); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, 0); + } + } +#endif + input_mt_report_pointer_emulation(ip_dev, false); + input_sync(ip_dev); + } + #endif + return IRQ_HANDLED; +} + +static int ft5435_power_on(struct ft5435_ts_data *data, bool on) +{ + int rc; + + if (!on) + goto power_off; + + rc = regulator_enable(data->vdd); + if (rc) { + dev_err(&data->client->dev, + "Regulator vdd enable failed rc=%d\n", rc); + return rc; + } + +#if 1 + rc = regulator_enable(data->vcc_i2c); + if (rc) { + dev_err(&data->client->dev, + "Regulator vcc_i2c enable failed rc=%d\n", rc); + regulator_disable(data->vdd); + } +#endif + + + return rc; + +power_off: +#if 1 + rc = regulator_disable(data->vdd); + if (rc) { + dev_err(&data->client->dev, + "Regulator vdd disable failed rc=%d\n", rc); + return rc; + } +#endif + +#if 1 + rc = regulator_disable(data->vcc_i2c); + if (rc) { + dev_err(&data->client->dev, + "Regulator vcc_i2c disable failed rc=%d\n", rc); + rc = regulator_enable(data->vdd); + if (rc) { + dev_err(&data->client->dev, + "Regulator vdd enable failed rc=%d\n", rc); + } + } +#endif + + + return rc; +} + +static int ft5435_power_init(struct ft5435_ts_data *data, bool on) +{ + int rc; + + if (!on) + goto pwr_deinit; + + data->vdd = regulator_get(&data->client->dev, "vdd"); + if (IS_ERR(data->vdd)) { + rc = PTR_ERR(data->vdd); + dev_err(&data->client->dev, + "Regulator get failed vdd rc=%d\n", rc); + return rc; + } + + if (regulator_count_voltages(data->vdd) > 0) { + rc = regulator_set_voltage(data->vdd, FT_VTG_MIN_UV, + FT_VTG_MAX_UV); + if (rc) { + dev_err(&data->client->dev, + "Regulator set_vtg failed vdd rc=%d\n", rc); + goto reg_vdd_put; + } + } + +#if 1 + data->vcc_i2c = regulator_get(&data->client->dev, "vcc_i2c"); + if (IS_ERR(data->vcc_i2c)) { + rc = PTR_ERR(data->vcc_i2c); + dev_err(&data->client->dev, + "Regulator get failed vcc_i2c rc=%d\n", rc); + goto reg_vdd_set_vtg; + } + + if (regulator_count_voltages(data->vcc_i2c) > 0) { + rc = regulator_set_voltage(data->vcc_i2c, FT_I2C_VTG_MIN_UV, + FT_I2C_VTG_MAX_UV); + if (rc) { + dev_err(&data->client->dev, + "Regulator set_vtg failed vcc_i2c rc=%d\n", rc); + goto reg_vcc_i2c_put; + } + } +#endif + + + return 0; + +#if 1 +reg_vcc_i2c_put: + regulator_put(data->vcc_i2c); + +reg_vdd_set_vtg: + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, FT_VTG_MAX_UV); +#endif + +reg_vdd_put: + regulator_put(data->vdd); + return rc; + +pwr_deinit: + if (regulator_count_voltages(data->vdd) > 0) + regulator_set_voltage(data->vdd, 0, FT_VTG_MAX_UV); + + regulator_put(data->vdd); + + return 0; +} + +static int ft5435_ts_pinctrl_init(struct ft5435_ts_data *ft5435_data) +{ + int retval; + + /* Get pinctrl if target uses pinctrl */ + ft5435_data->ts_pinctrl = devm_pinctrl_get(&(ft5435_data->client->dev)); + if (IS_ERR_OR_NULL(ft5435_data->ts_pinctrl)) { + dev_dbg(&ft5435_data->client->dev, + "Target does not use pinctrl\n"); + retval = PTR_ERR(ft5435_data->ts_pinctrl); + ft5435_data->ts_pinctrl = NULL; + goto err_pinctrl_get; + } + + ft5435_data->gpio_state_active + = pinctrl_lookup_state(ft5435_data->ts_pinctrl, + "pmx_ts_active"); + if (IS_ERR_OR_NULL(ft5435_data->gpio_state_active)) { + dev_dbg(&ft5435_data->client->dev, + "Can not get ts default pinstate\n"); + retval = PTR_ERR(ft5435_data->gpio_state_active); + ft5435_data->ts_pinctrl = NULL; + goto err_pinctrl_lookup; + } + + ft5435_data->gpio_state_suspend + = pinctrl_lookup_state(ft5435_data->ts_pinctrl, + "pmx_ts_suspend"); + if (IS_ERR_OR_NULL(ft5435_data->gpio_state_suspend)) { + dev_err(&ft5435_data->client->dev, + "Can not get ts sleep pinstate\n"); + retval = PTR_ERR(ft5435_data->gpio_state_suspend); + ft5435_data->ts_pinctrl = NULL; + goto err_pinctrl_lookup; + } + + return 0; +err_pinctrl_lookup: + devm_pinctrl_put(ft5435_data->ts_pinctrl); +err_pinctrl_get: + ft5435_data->ts_pinctrl = NULL; + return retval; +} + +static int ft5435_ts_pinctrl_select(struct ft5435_ts_data *ft5435_data, + bool on) +{ + struct pinctrl_state *pins_state; + int ret; + pins_state = on ? ft5435_data->gpio_state_active + : ft5435_data->gpio_state_suspend; + if (!IS_ERR_OR_NULL(pins_state)) { + ret = pinctrl_select_state(ft5435_data->ts_pinctrl, pins_state); + if (ret) { + dev_err(&ft5435_data->client->dev, + "can not set %s pins\n", + on ? "pmx_ts_active" : "pmx_ts_suspend"); + return ret; + } + } else { + dev_err(&ft5435_data->client->dev, + "not a valid '%s' pinstate\n", + on ? "pmx_ts_active" : "pmx_ts_suspend"); + } + return 0; +} + +#if defined(FOCALTECH_TP_GESTURE) +static int ft_tp_suspend(struct ft5435_ts_data *data) +{ + int i = 0; + u8 state = 0; + + printk("[FTS] FTS_GESTRUE suspend\n"); + ft5x0x_write_reg(data->client, 0xd0, 0x01); + ft5x0x_write_reg(data->client, 0xd1, 0xff); + ft5x0x_write_reg(data->client, 0xd2, 0xff); + ft5x0x_write_reg(data->client, 0xd5, 0xff); + ft5x0x_write_reg(data->client, 0xd6, 0xff); + ft5x0x_write_reg(data->client, 0xd7, 0xff); + ft5x0x_write_reg(data->client, 0xd8, 0xff); + msleep(10); + + for (i = 0; i < 10; i++) { + printk("[FTS]tpd_suspend4 %d\t", i); + ft5x0x_read_reg(data->client, 0xd0, &state); + + if (state == 1) { + printk("[FTS]TPD gesture write 0x01 OK\n"); + break; + } else { + ft5x0x_write_reg(data->client, 0xd0, 0x01); + ft5x0x_write_reg(data->client, 0xd1, 0xff); + ft5x0x_write_reg(data->client, 0xd2, 0xff); + ft5x0x_write_reg(data->client, 0xd5, 0xff); + ft5x0x_write_reg(data->client, 0xd6, 0xff); + ft5x0x_write_reg(data->client, 0xd7, 0xff); + ft5x0x_write_reg(data->client, 0xd8, 0xff); + msleep(10); + } + } + + if (i >= 9) + { + printk("[FTS]TPD gesture write 0x01 to d0 fail \n"); + } + + data->suspended = true; + printk("[FTS] FTS_GESTRUE suspend end\n"); + return 0; +} +#endif + +#ifdef CONFIG_PM +static int ft5435_ts_suspend(struct device *dev) +{ + struct ft5435_ts_data *data = g_ft5435_ts_data; + char i; + + u8 state = -1; + if (data->loading_fw) { + dev_info(dev, "Firmware loading in process...\n"); + return 0; + } + + if (data->suspended) { + dev_info(dev, "Already in suspend state\n"); + return 0; + } + + disable_irq(data->client->irq); + + /* release all touches */ + for (i = 0; i < data->pdata->num_max_touches; i++) { + input_mt_slot(data->input_dev, i); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, 0); + } + input_mt_report_pointer_emulation(data->input_dev, false); + input_sync(data->input_dev); + +#if defined(FOCALTECH_TP_GESTURE) + { + if (gesture_func_on) { + enable_irq(data->client->irq); + ft_tp_suspend(data); + return 0; + } + } +#endif + if (gpio_is_valid(data->pdata->reset_gpio)) { + gpio_set_value_cansleep(data->pdata->reset_gpio, 1); + msleep(300); + } + if (gpio_is_valid(data->pdata->reset_gpio)) { + for (i = 0; i < 10; i++) { + ft5x0x_write_reg(data->client, 0xa5, 0x03); + ft5x0x_read_reg(data->client, 0xa5, &state); + + if ((state != 0) && (state != 1)) { + printk("[FTS]Ft5435 TPDwrite OK [%d]\n", i); + break; + } else { + printk("[FTS]Ft5435 TPDwrite Error[%d]\n", i); + } + } + } + + data->suspended = true; + return 0; +} + +static int ft5435_ts_resume(struct device *dev) +{ + struct ft5435_ts_data *data = g_ft5435_ts_data; + + + + if (!data->suspended) { + dev_dbg(dev, "Already in awake state\n"); + return 0; + } + + /* release all touches */ + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, 0); + input_sync(data->input_dev); + +/*hw rst*/ + if (gpio_is_valid(data->pdata->reset_gpio)) { + gpio_set_value_cansleep(data->pdata->reset_gpio, 0); + msleep(2); + gpio_set_value_cansleep(data->pdata->reset_gpio, 1); + } + + msleep(data->pdata->soft_rst_dly); + + + ft5x0x_write_reg(data->client, 0x8c, 0x01); + enable_irq(data->client->irq); + data->suspended = false; + +#if defined(USB_CHARGE_DETECT) + queue_work(ft5435_wq, &data->work); +#endif + +#if defined(LEATHER_COVER) + queue_work(ft5435_wq_cover, &data->work_cover); +#endif +#if defined(VR_GLASS) + queue_work(ft5435_wq_vr, &data->work_vr); +#endif + return 0; +} + +static const struct dev_pm_ops ft5435_ts_pm_ops = { +#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND)) + .suspend = ft5435_ts_suspend, + .resume = ft5435_ts_resume, +#endif +}; + +#else +static int ft5435_ts_suspend(struct device *dev) +{ + return 0; +} + +static int ft5435_ts_resume(struct device *dev) +{ + return 0; +} + +#endif + +#if 1 +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct ft5435_ts_data *ft5435_data = + container_of(self, struct ft5435_ts_data, fb_notif); + + if (evdata && evdata->data && event == FB_EVENT_BLANK && + ft5435_data && ft5435_data->client) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) + ft5435_ts_resume(&ft5435_data->client->dev); + else if (*blank == FB_BLANK_POWERDOWN) + ft5435_ts_suspend(&ft5435_data->client->dev); + } + return 0; +} +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void ft5435_ts_early_suspend(struct early_suspend *handler) +{ + struct ft5435_ts_data *data = container_of(handler, + struct ft5435_ts_data, + early_suspend); + + ft5435_ts_suspend(&data->client->dev); +} + +static void ft5435_ts_late_resume(struct early_suspend *handler) +{ + struct ft5435_ts_data *data = container_of(handler, + struct ft5435_ts_data, + early_suspend); + + ft5435_ts_resume(&data->client->dev); +} +#endif +#else +#if defined(CONFIG_FB) +static void fb_notify_resume_work(struct work_struct *work) +{ + struct ft5435_ts_data *ft5435_data = + container_of(work, struct ft5435_ts_data, fb_notify_work); + ft5435_ts_resume(&ft5435_data->client->dev); +} + +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct ft5435_ts_data *ft5435_data = + container_of(self, struct ft5435_ts_data, fb_notif); + + if (evdata && evdata->data && ft5435_data && ft5435_data->client) { + blank = evdata->data; + if (ft5435_data->pdata->resume_in_workqueue) { + if (event == FB_EARLY_EVENT_BLANK && + *blank == FB_BLANK_UNBLANK) + schedule_work(&ft5435_data->fb_notify_work); + else if (event == FB_EVENT_BLANK && + *blank == FB_BLANK_POWERDOWN) { + flush_work(&ft5435_data->fb_notify_work); + ft5435_ts_suspend(&ft5435_data->client->dev); + } + } else { + if (event == FB_EVENT_BLANK) { + if (*blank == FB_BLANK_UNBLANK) + ft5435_ts_resume( + &ft5435_data->client->dev); + else if (*blank == FB_BLANK_POWERDOWN) + ft5435_ts_suspend( + &ft5435_data->client->dev); + } + } + } + + return 0; +} +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void ftft5346_ts_early_suspend(struct early_suspend *handler) +{ + struct ftft5346_ts_data *data = container_of(handler, + struct ft5435_ts_data, + early_suspend); + + /* + * During early suspend/late resume, the driver doesn't access xPU/SMMU + * protected HW resources. So, there is no compelling need to block, + * but notifying the userspace that a power event has occurred is + * enough. Hence 'blocking' variable can be set to false. + */ + ft5435_secure_touch_stop(data, false); + ft5435_ts_suspend(&data->client->dev); +} + +static void ft5435_ts_late_resume(struct early_suspend *handler) +{ + struct ft5435_ts_data *data = container_of(handler, + struct ft5435_ts_data, + early_suspend); + + ft5435_secure_touch_stop(data, false); + ft5435_ts_resume(&data->client->dev); +} +#endif + +#endif + +static int ft5435_auto_cal(struct i2c_client *client) +{ + struct ft5435_ts_data *data = i2c_get_clientdata(client); + u8 temp = 0, i; + + /* set to factory mode */ + msleep(2 * data->pdata->soft_rst_dly); + ft5x0x_write_reg(client, FT_REG_DEV_MODE, FT_FACTORYMODE_VALUE); + msleep(data->pdata->soft_rst_dly); + + /* start calibration */ + ft5x0x_write_reg(client, FT_DEV_MODE_REG_CAL, FT_CAL_START); + msleep(2 * data->pdata->soft_rst_dly); + for (i = 0; i < FT_CAL_RETRY; i++) { + ft5x0x_read_reg(client, FT_REG_CAL, &temp); + /*return to normal mode, calibration finish */ + if (((temp & FT_CAL_MASK) >> FT_4BIT_SHIFT) == FT_CAL_FIN) + break; + } + + /*calibration OK */ + msleep(2 * data->pdata->soft_rst_dly); + ft5x0x_write_reg(client, FT_REG_DEV_MODE, FT_FACTORYMODE_VALUE); + msleep(data->pdata->soft_rst_dly); + + /* store calibration data */ + ft5x0x_write_reg(client, FT_DEV_MODE_REG_CAL, FT_CAL_STORE); + msleep(2 * data->pdata->soft_rst_dly); + + /* set to normal mode */ + ft5x0x_write_reg(client, FT_REG_DEV_MODE, FT_WORKMODE_VALUE); + msleep(2 * data->pdata->soft_rst_dly); + + return 0; +} + +int hid_to_i2c(struct i2c_client *client) +{ + u8 auc_i2c_write_buf[5] = {0}; + int bRet = 0; + + auc_i2c_write_buf[0] = 0xeb; + auc_i2c_write_buf[1] = 0xaa; + auc_i2c_write_buf[2] = 0x09; + + ft5435_i2c_write(client, auc_i2c_write_buf, 3); + + msleep(10); + + auc_i2c_write_buf[0] = auc_i2c_write_buf[1] = auc_i2c_write_buf[2] = 0; + + ft5435_i2c_read(client, auc_i2c_write_buf, 0, auc_i2c_write_buf, 3); + + + if (1) + bRet = 1; + else bRet = 0; + return bRet; +} + + +static int ft5435_fw_upgrade_start(struct i2c_client *client, + const u8 *data, u32 data_len) +{ + struct ft5435_ts_data *ts_data = i2c_get_clientdata(client); + struct fw_upgrade_info info = ts_data->pdata->info; + u8 reset_reg; + u8 w_buf[FT_MAX_WR_BUF] = {0}, r_buf[FT_MAX_RD_BUF] = {0}; + u8 pkt_buf[FT_FW_PKT_LEN + FT_FW_PKT_META_LEN]; + int i, j; + u32 pkt_num, pkt_len, temp; + + u8 is_5336_fwsize_30 = false; + u8 fw_ecc; + hid_to_i2c(client); + /* determine firmware size */ + if (*(data + data_len - FT_BLOADER_SIZE_OFF) == FT_BLOADER_NEW_SIZE) + is_5336_fwsize_30 = true; + else + is_5336_fwsize_30 = false; + + for (i = 0, j = 0; i < FT_UPGRADE_LOOP; i++) { + msleep(FT_EARSE_DLY_MS); + /* reset - write 0xaa and 0x55 to reset register */ + if (ts_data->family_id == FT6X06_ID + || ts_data->family_id == FT6X36_ID) + reset_reg = FT_RST_CMD_REG1; + else + reset_reg = FT_RST_CMD_REG1; + + ft5x0x_write_reg(client, reset_reg, FT_UPGRADE_AA); + msleep(info.delay_aa); + + ft5x0x_write_reg(client, reset_reg, FT_UPGRADE_55); + if (i <= (FT_UPGRADE_LOOP / 2)) + msleep(info.delay_55 + i * 3); + else + msleep(info.delay_55 - (i - (FT_UPGRADE_LOOP / 2)) * 2); + hid_to_i2c(client); + msleep(10); + w_buf[0] = 0x55; + w_buf[1] = 0xaa; + temp = 0; + do { + temp++; + ft5435_i2c_write(client, w_buf, 2); + msleep(5); + } while (temp < 1); + + /* check READ_ID */ + msleep(info.delay_readid); + w_buf[0] = FT_READ_ID_REG; + w_buf[1] = 0x00; + w_buf[2] = 0x00; + w_buf[3] = 0x00; + + ft5435_i2c_read(client, w_buf, 4, r_buf, 2); + + if (r_buf[0] != info.upgrade_id_1 + || r_buf[1] != info.upgrade_id_2) { + dev_err(&client->dev, "Upgrade ID mismatch(%d), IC=0x%x 0x%x, info=0x%x 0x%x\n", + i, r_buf[0], r_buf[1], + info.upgrade_id_1, info.upgrade_id_2); + } else + break; + } + + if (i >= FT_UPGRADE_LOOP) { + dev_err(&client->dev, "Abort upgrade\n"); + return -EIO; + } + /* erase app and panel paramenter area */ + w_buf[0] = FT_ERASE_APP_REG; + ft5435_i2c_write(client, w_buf, 1); + msleep(info.delay_erase_flash); + + for (i = 0; i < 15; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + printk("1~~~~1 r_buf[0] =%x r_buf[1] = %x \n ", r_buf[0], r_buf[1]); + if (0xF0 == r_buf[0] && 0xAA == r_buf[1]) + break; + msleep(50); + } + + w_buf[0] = 0xB0; + w_buf[1] = (u8) ((data_len >> 16) & 0xFF); + w_buf[2] = (u8) ((data_len >> 8) & 0xFF); + w_buf[3] = (u8) (data_len & 0xFF); + printk("data_len = %d \n", data_len); + ft5435_i2c_write(client, w_buf, 4); + + +/*********Step 5:write firmware(FW) to ctpm flash*********/ + fw_ecc = 0; + printk("Step 5:write firmware(FW) to ctpm flash\n"); + temp = 0; + pkt_num = (data_len) / FT_FW_PKT_LEN; + pkt_buf[0] = 0xbf; + pkt_buf[1] = 0x00; + printk("@@@@@pkt_num = %x \n", pkt_num); + for (j = 0; j < pkt_num; j++) { + temp = j * FT_FW_PKT_LEN; + pkt_buf[2] = (u8) (temp >> 8); + pkt_buf[3] = (u8) temp; + pkt_len = FT_FW_PKT_LEN; + pkt_buf[4] = (u8) (pkt_len >> 8); + pkt_buf[5] = (u8) pkt_len; + for (i = 0; i < FT_FW_PKT_LEN; i++) { + pkt_buf[6 + i] = data[j * FT_FW_PKT_LEN + i]; + fw_ecc ^= pkt_buf[6 + i]; + } + ft5435_i2c_write(client, pkt_buf, FT_FW_PKT_LEN + 6); + + for (i = 0; i < 30; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + + if ((j + 0x1000) == (((r_buf[0]) << 8) | r_buf[1])) + break; + msleep(1); + } + } + + if ((data_len) % FT_FW_PKT_LEN > 0) { + temp = pkt_num * FT_FW_PKT_LEN; + pkt_buf[2] = (u8) (temp >> 8); + pkt_buf[3] = (u8) temp; + temp = (data_len) % FT_FW_PKT_LEN; + pkt_buf[4] = (u8) (temp >> 8); + pkt_buf[5] = (u8) temp; + + for (i = 0; i < temp; i++) { + pkt_buf[6 + i] = data[pkt_num * FT_FW_PKT_LEN + i]; + fw_ecc ^= pkt_buf[6 + i]; + } + ft5435_i2c_write(client, pkt_buf, temp + 6); + + for (i = 0; i < 30; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + printk("@~~~~@ r_buf[0] =%x r_buf[1] = %x j =%x \n ", r_buf[0], r_buf[1], j); + if ((j + 0x1000) == (((r_buf[0]) << 8) | r_buf[1])) + break; + msleep(1); + } + } + + msleep(50); + + /*********Step 6: read out checksum***********************/ + /*send the opration head */ + printk("Step 6: read out checksum\n"); + w_buf[0] = 0x64; + ft5435_i2c_write(client, w_buf, 1); + msleep(300); + + temp = 0; + w_buf[0] = 0x65; + w_buf[1] = (u8)(temp >> 16); + w_buf[2] = (u8)(temp >> 8); + w_buf[3] = (u8)(temp); + temp = data_len; + w_buf[4] = (u8)(temp >> 8); + w_buf[5] = (u8)(temp); + ft5435_i2c_write(client, w_buf, 6); + msleep(data_len/256); + + for (i = 0; i < 100; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + printk("~~~~ r_buf[0] =%x r_buf[1] = %x \n ", r_buf[0], r_buf[1]); + if (0xF0 == r_buf[0] && 0x55 == r_buf[1]) + break; + msleep(1); + } + w_buf[0] = 0x66; + ft5435_i2c_read(client, w_buf, 1, r_buf, 1); + if (r_buf[0] != fw_ecc) + { + dev_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n", + r_buf[0], + fw_ecc); + + return -EIO; + } + printk(KERN_WARNING "checksum %x %x \n", r_buf[0], fw_ecc); + /* reset */ + w_buf[0] = FT_REG_RESET_FW; + ft5435_i2c_write(client, w_buf, 1); + msleep(ts_data->pdata->soft_rst_dly); + + dev_info(&client->dev, "Firmware upgrade successful\n"); + + return 0; +} +#if defined(FOCALTECH_AUTO_UPGRADE) + +static int ft5x46_fw_upgrade_start(struct i2c_client *client, + const u8 *data, u32 data_len) +{ + struct ft5435_ts_data *ts_data = i2c_get_clientdata(client); + struct fw_upgrade_info info = ts_data->pdata->info; + u8 w_buf[FT_MAX_WR_BUF] = {0}, r_buf[FT_MAX_RD_BUF] = {0}; + u8 pkt_buf[FT_FW_PKT_LEN + FT_FW_PKT_META_LEN]; + int i, j, temp; + u32 pkt_num, pkt_len; + u8 fw_ecc; + int i_ret; + + printk("%s\n", __func__); + i_ret = hid_to_i2c(client); + + if (i_ret == 0) + printk("[FTS] hid1 change to i2c fail ! \n"); + + for (i = 0, j = 0; i < FT_UPGRADE_LOOP; i++) { + msleep(FT_EARSE_DLY_MS); + + /*********Step 1:Reset CTPM *****/ + /*write 0xaa to register 0xfc */ + ft5x0x_write_reg(client, 0xfc, FT_UPGRADE_AA); + msleep(2); + + ft5x0x_write_reg(client, 0xfc, FT_UPGRADE_55); + + msleep(200); + + i_ret = hid_to_i2c(client); + + if (i_ret == 0) + printk("[FTS] hid%d change to i2c fail ! \n", i); + + msleep(10); + + /*********Step 2:Enter upgrade mode *****/ + w_buf[0] = FT_UPGRADE_55; + w_buf[1] = FT_UPGRADE_AA; + i_ret = ft5435_i2c_write(client, w_buf, 2); + + if (i_ret < 0) { + printk("[FTS] failed writing 0x55 and 0xaa ! \n"); + continue; + } + + /*********Step 3:check READ-ID***********************/ + msleep(1); + w_buf[0] = FT_READ_ID_REG; + w_buf[1] = 0x00; + w_buf[2] = 0x00; + w_buf[3] = 0x00; + + r_buf[0] = r_buf[1] = 0x00; + + ft5435_i2c_read(client, w_buf, 4, r_buf, 2); + + if (r_buf[0] == 0x54 && r_buf[1] == 0x2c) { + printk("Upgrade ID mismatch(%d), IC=0x%x 0x%x, info=0x%x 0x%x\n", + i, r_buf[0], r_buf[1], info.upgrade_id_1, info.upgrade_id_2); + break; + } else{ + printk("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", + r_buf[0], r_buf[1]); + continue; + } + } + + if (i >= FT_UPGRADE_LOOP) { + dev_err(&client->dev, "Abort upgrade\n"); + return -EIO; + } + + /******Step 4:erase app and panel paramenter area******/ + printk("Step 4:erase app and panel paramenter area\n"); + w_buf[0] = 0x61; + ft5435_i2c_write(client, w_buf, 1); + msleep(1350); + + for (i = 0; i < 15; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + + if (0xF0 == r_buf[0] && 0xAA == r_buf[1]) + break; + msleep(50); + + } + + w_buf[0] = 0xB0; + w_buf[1] = (u8) ((data_len >> 16) & 0xFF); + w_buf[2] = (u8) ((data_len >> 8) & 0xFF); + w_buf[3] = (u8) (data_len & 0xFF); + + ft5435_i2c_write(client, w_buf, 4); + + /*********Step 5:write firmware(FW) to ctpm flash*********/ + fw_ecc = 0; + printk("Step 5:write firmware(FW) to ctpm flash\n"); + temp = 0; + pkt_num = (data_len) / FT_FW_PKT_LEN; + pkt_buf[0] = 0xbf; + pkt_buf[1] = 0x00; + + for (j = 0; j < pkt_num; j++) { + temp = j * FT_FW_PKT_LEN; + pkt_buf[2] = (u8) (temp >> 8); + pkt_buf[3] = (u8) temp; + pkt_len = FT_FW_PKT_LEN; + pkt_buf[4] = (u8) (pkt_len >> 8); + pkt_buf[5] = (u8) pkt_len; + + for (i = 0; i < FT_FW_PKT_LEN; i++) { + pkt_buf[6 + i] = data[j * FT_FW_PKT_LEN + i]; + fw_ecc ^= pkt_buf[6 + i]; + } + ft5435_i2c_write(client, pkt_buf, FT_FW_PKT_LEN + 6); + + for (i = 0; i < 30; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + + if ((j + 0x1000) == (((r_buf[0]) << 8) | r_buf[1])) + break; + msleep(1); + + } + } + + if ((data_len) % FT_FW_PKT_LEN > 0) { + temp = pkt_num * FT_FW_PKT_LEN; + pkt_buf[2] = (u8) (temp >> 8); + pkt_buf[3] = (u8) temp; + temp = (data_len) % FT_FW_PKT_LEN; + pkt_buf[4] = (u8) (temp >> 8); + pkt_buf[5] = (u8) temp; + + for (i = 0; i < temp; i++) { + pkt_buf[6 + i] = data[pkt_num* FT_FW_PKT_LEN + i]; + fw_ecc ^= pkt_buf[6 + i]; + } + ft5435_i2c_write(client, pkt_buf, temp + 6); + + for (i = 0; i < 30; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + + if ((j + 0x1000) == (((r_buf[0]) << 8) | r_buf[1])) + break; + msleep(1); + + } + } + + msleep(50); + +/*********Step 6: read out checksum***********************/ + /*send the opration head */ + printk("Step 6: read out checksum\n"); + w_buf[0] = 0x64; + ft5435_i2c_write(client, w_buf, 1); + msleep(300); + + temp = 0; + w_buf[0] = 0x65; + w_buf[1] = (u8)(temp >> 16); + w_buf[2] = (u8)(temp >> 8); + w_buf[3] = (u8)(temp); + temp = data_len; + w_buf[4] = (u8)(temp >> 8); + w_buf[5] = (u8)(temp); + i_ret = ft5435_i2c_write(client, w_buf, 6); + msleep(data_len/256); + + for (i = 0; i < 100; i++) { + w_buf[0] = 0x6a; + r_buf[0] = r_buf[1] = 0x00; + ft5435_i2c_read(client, w_buf, 1, r_buf, 2); + + if (0xF0 == r_buf[0] && 0x55 == r_buf[1]) + break; + msleep(1); + + } + w_buf[0] = 0x66; + ft5435_i2c_read(client, w_buf, 1, r_buf, 1); + if (r_buf[0] != fw_ecc) { + dev_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n", + r_buf[0], fw_ecc); + + return -EIO; + } + printk(KERN_WARNING "checksum %X %X \n", r_buf[0], fw_ecc); + + /*********Step 7: reset the new FW***********************/ + printk("Step 7: reset the new FW\n"); + w_buf[0] = 0x07; + ft5435_i2c_write(client, w_buf, 1); + msleep(130); + + return 0; +} +#endif +#if defined(FOCALTECH_FW_COMPAT) +static int ft5435_fw_upgrade_arbitrate(struct i2c_client *client) +{ + struct ft5435_ts_data *ts_data = i2c_get_clientdata(client); + struct fw_upgrade_info info = ts_data->pdata->info; + u8 reset_reg; + u8 w_buf[FT_MAX_WR_BUF] = {0}, r_buf[FT_MAX_RD_BUF] = {0}; + int i; + + for (i = 0; i < FT_UPGRADE_LOOP; i++) { + msleep(FT_EARSE_DLY_MS); + /* reset - write 0xaa and 0x55 to reset register */ + if (ts_data->family_id == FT6X06_ID + || ts_data->family_id == FT6X36_ID) + reset_reg = FT_RST_CMD_REG2; + else + reset_reg = FT_RST_CMD_REG1; + + ft5x0x_write_reg(client, reset_reg, FT_UPGRADE_AA); + msleep(info.delay_aa); + + ft5x0x_write_reg(client, reset_reg, FT_UPGRADE_55); + if (i <= (FT_UPGRADE_LOOP / 2)) + msleep(info.delay_55 + i * 3); + else + msleep(info.delay_55 - (i - (FT_UPGRADE_LOOP / 2)) * 2); + + /* Enter upgrade mode */ + w_buf[0] = FT_UPGRADE_55; + ft5435_i2c_write(client, w_buf, 1); + usleep(FT_55_AA_DLY_NS); + w_buf[0] = FT_UPGRADE_AA; + ft5435_i2c_write(client, w_buf, 1); + + /* check READ_ID */ + msleep(info.delay_readid); + w_buf[0] = FT_READ_ID_REG; + w_buf[1] = 0x00; + w_buf[2] = 0x00; + w_buf[3] = 0x00; + + ft5435_i2c_read(client, w_buf, 4, r_buf, 2); + + if (r_buf[0] != info.upgrade_id_1 + || r_buf[1] != info.upgrade_id_2) { + dev_err(&client->dev, "Upgrade ID mismatch(%d), IC=0x%x 0x%x, info=0x%x 0x%x\n", + i, r_buf[0], r_buf[1], + info.upgrade_id_1, info.upgrade_id_2); + } else + break; + } + + if (i >= FT_UPGRADE_LOOP) { + dev_err(&client->dev, "Abort upgrade\n"); + return -EIO; + } + +/* get tp vid */ + + w_buf[0] = 0x03; + w_buf[1] = 0x00; + w_buf[2] = 0x78; + w_buf[3] = 0x40; + ft5435_i2c_read(client, w_buf, 4, r_buf, 1); + ts_data->fw_compat = r_buf[0]; + printk("%s line=%d, fw_compat=%x \n", __func__, __LINE__, ts_data->fw_compat); + + /* reset */ + w_buf[0] = FT_REG_RESET_FW; + ft5435_i2c_write(client, w_buf, 1); + msleep(ts_data->pdata->soft_rst_dly); + +/* New TP with fw_version >= 0x30 */ + if (ts_data->fw_compat >= 0x30) { + strlcpy(ts_data->fw_name, "ft_fw3.bin", strlen("ft_fw3.bin") + 1); + } + + return 0; +} +#endif + +static unsigned int booting_into_recovery; +static int __init get_boot_mode(char *str) +{ + if (strcmp("boot_with_recovery", str) == 0) + booting_into_recovery = 1; + + printk("zakk: booting_into_recovery=%d\n", booting_into_recovery); + return 0; +} +__setup("androidboot.boot_reason=", get_boot_mode); + +static int ft5435_fw_upgrade(struct device *dev, bool force) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + const struct firmware *fw = NULL; + int rc; + u8 fw_file_maj, fw_file_min, fw_file_sub_min, fw_file_vendor_id; + bool fw_upgrade = false; + + if (data->suspended) { + dev_err(dev, "Device is in suspend state: Exit FW upgrade\n"); + return -EBUSY; + } + +#if defined(FOCALTECH_FW_COMPAT) + rc = ft5435_fw_upgrade_arbitrate(data->client); + if (rc < 0) { + printk(">>-- distinguish tp failed ! \n"); + return rc; + } +#endif + + ft5435_update_fw_vendor_id(data); + + printk("[Fu]%s, booting_into_recovery=%d\n", __func__, booting_into_recovery); + + rc = request_firmware(&fw, data->fw_name, dev); + + + if (rc < 0) { + dev_err(dev, "[Fu]Request firmware failed - %s (%d)\n", + data->fw_name, rc); + return rc; + } + + if (fw->size < FT_FW_MIN_SIZE || fw->size > FT_FW_MAX_SIZE) { + dev_err(dev, "Invalid firmware size (%zu)\n", fw->size); + rc = -EIO; + goto rel_fw; + } + + if (data->family_id == FT6X36_ID) { + fw_file_maj = FT_FW_FILE_MAJ_VER_FT6X36(fw); + fw_file_vendor_id = FT_FW_FILE_VENDOR_ID_FT6X36(fw); + } else { + fw_file_maj = FT_FW_FILE_MAJ_VER(fw); + fw_file_vendor_id = FT_FW_FILE_VENDOR_ID(fw); + } + fw_file_min = FT_FW_FILE_MIN_VER(fw); + fw_file_sub_min = FT_FW_FILE_SUB_MIN_VER(fw); + + printk("[Fu]Current firmware: %d.%d.%d", data->fw_ver[0], + data->fw_ver[1], data->fw_ver[2]); + printk("[Fu]New firmware: %d.%d.%d", fw_file_maj, + fw_file_min, fw_file_sub_min); + + if (force) + fw_upgrade = true; + + else if (fw_file_maj == 18 && data->fw_ver[0] != 18) { + fw_upgrade = true; + printk("\n[wxc]roll back firmware to v12 for temp\n"); + } + + else if ((data->fw_ver[0] < fw_file_maj) && + (data->pdata->ignore_id_check || (data->fw_vendor_id == fw_file_vendor_id))) + fw_upgrade = true; + + if (!fw_upgrade) { + dev_info(dev, "Exiting fw upgrade...\n"); + rc = -EFAULT; + goto rel_fw; + } + + /* start firmware upgrade */ + if (FT_FW_CHECK(fw, data)) { + rc = ft5435_fw_upgrade_start(data->client, fw->data, fw->size); + if (rc < 0) + dev_err(dev, "update failed (%d). try later...\n", rc); + else if (data->pdata->info.auto_cal) + ft5435_auto_cal(data->client); + } else { + dev_err(dev, "FW format error\n"); + rc = -EIO; + } + + ft5435_update_fw_ver(data); + + FT_STORE_TS_INFO(data->ts_info, data->family_id, data->pdata->name, + data->pdata->num_max_touches, data->pdata->group_id, + data->pdata->fw_vkey_support ? "yes" : "no", + data->pdata->fw_name, data->fw_ver[0], + data->fw_ver[1], data->fw_ver[2]); +rel_fw: + release_firmware(fw); + return rc; +} +#if defined(FOCALTECH_AUTO_UPGRADE) +static unsigned char ft5435_fw_Vid_get_from_boot(struct i2c_client *client) +{ + unsigned char auc_i2c_write_buf[10]; + u8 w_buf[FT_MAX_WR_BUF] = {0}, r_buf[FT_MAX_RD_BUF] = {0}; + unsigned char i = 0; + unsigned char vid = 0xFF; + int i_ret; + + i_ret = hid_to_i2c(client); + + for (i = 0; i < FT_UPGRADE_LOOP; i++) { + msleep(FT_EARSE_DLY_MS); + + /*********Step 1:Reset CTPM *****/ + /*write 0xaa to register 0xfc */ + ft5x0x_write_reg(client, 0xfc, FT_UPGRADE_AA); + msleep(2); + + ft5x0x_write_reg(client, 0xfc, FT_UPGRADE_55); + + msleep(200); + + i_ret = hid_to_i2c(client); + + if (i_ret == 0) + printk("[FTS] hid%d change to i2c fail ! \n", i); + + msleep(10); + + /*********Step 2:Enter upgrade mode *****/ + w_buf[0] = FT_UPGRADE_55; + w_buf[1] = FT_UPGRADE_AA; + + i_ret = ft5435_i2c_write(client, w_buf, 2); + + if (i_ret < 0) { + printk("[FTS] failed writing 0x55 and 0xaa ! \n"); + continue; + } + + /*********Step 3:check READ-ID***********************/ + msleep(1); + w_buf[0] = FT_READ_ID_REG; + w_buf[1] = 0x00; + w_buf[2] = 0x00; + w_buf[3] = 0x00; + + r_buf[0] = r_buf[1] = 0x00; + + ft5435_i2c_read(client, w_buf, 4, r_buf, 2); + + if (r_buf[0] == 0x54 && r_buf[1] == 0x2c) { + /* + printk("Upgrade ID mismatch(%d), IC=0x%x 0x%x, info=0x%x 0x%x\n", + i, r_buf[0], r_buf[1],info.upgrade_id_1, info.upgrade_id_2); + */ + break; + } else{ + printk("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", + r_buf[0], r_buf[1]); + continue; + } + } + + if (i >= FT_UPGRADE_LOOP) { + dev_err(&client->dev, "Abort upgrade\n"); + return -EIO; + } + + printk("FTS_UPGRADE_LOOP ok is i = %d \n", i); + + msleep(10); + auc_i2c_write_buf[0] = 0x03; + auc_i2c_write_buf[1] = 0x00; + for (i = 0; i < FT_UPGRADE_LOOP; i++) { + auc_i2c_write_buf[2] = 0xd7; + auc_i2c_write_buf[3] = 0x83; + i_ret = ft5435_i2c_write(client, auc_i2c_write_buf, 4); + if (i_ret < 0) { + printk("[FTS] Step 4: read lcm id from flash error when i2c write, i_ret = %d\n", i_ret); + continue; + } + i_ret = ft5435_i2c_read(client, auc_i2c_write_buf, 0, r_buf, 2); + if (i_ret < 0) { + printk("[FTS] Step 4: read lcm id from flash error when i2c write, i_ret = %d\n", i_ret); + continue; + } + + vid = r_buf[1]; + + printk("%s: REG VAL ID1 = 0x%x, ID2 = 0x%x\n", __func__, r_buf[0], r_buf[1]); + break; + } + + printk("%s: reset the tp\n", __func__); + auc_i2c_write_buf[0] = 0x07; + ft5435_i2c_write(client, auc_i2c_write_buf, 1); + msleep(300); + return vid; +} + +static int ft5435_fw_upgrade_by_array_data(struct device *dev, char *fw_data, int size, bool force) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + struct firmware *fw = NULL; + int rc; + u8 fw_file_maj, fw_file_min, fw_file_sub_min, fw_file_vendor_id; + bool fw_upgrade = false; + char *pfw_data = fw_data; + int fw_size = size; + + printk("%s, suspended=%d\n", __func__, data->suspended); + if (data->suspended) { + dev_err(dev, "Device is in suspend state: Exit FW upgrade\n"); + return -EBUSY; + } + + fw = kzalloc(sizeof(struct firmware), GFP_KERNEL); + fw->size = fw_size; + fw->data = pfw_data; + + if (fw->size < FT_FW_MIN_SIZE || fw->size > FT_FW_MAX_SIZE) { + dev_err(dev, "Invalid firmware size (%zu)\n", fw->size); + rc = -EIO; + goto rel_fw; + } + + if (data->family_id == FT6X36_ID) { + fw_file_maj = FT_FW_FILE_MAJ_VER_FT6X36(fw); + fw_file_vendor_id = FT_FW_FILE_VENDOR_ID_FT6X36(fw); + } else { + fw_file_maj = FT_FW_FILE_MAJ_VER(fw); + fw_file_vendor_id = FT_FW_FILE_VENDOR_ID(fw); + } + fw_file_min = FT_FW_FILE_MIN_VER(fw); + fw_file_sub_min = FT_FW_FILE_SUB_MIN_VER(fw); + + dev_info(dev, "Current firmware: 0x%02x.%d.%d", data->fw_ver[0], + data->fw_ver[1], data->fw_ver[2]); + dev_info(dev, "New firmware: 0x%02x.%d.%d", fw_file_maj, + fw_file_min, fw_file_sub_min); + + if (force) + fw_upgrade = true; + + + else if (data->fw_ver[0] != fw_file_maj) + fw_upgrade = true; + + if (!fw_upgrade) { + dev_info(dev, "Exiting fw upgrade...\n"); + rc = -EFAULT; + goto rel_fw; + } + + /* start firmware upgrade */ + if (data->family_id == FT5X46_ID) { + rc = ft5x46_fw_upgrade_start(data->client, fw->data, fw->size); + if (rc < 0) + dev_err(dev, "update failed (%d). try later...\n", rc); + } else if (FT_FW_CHECK(fw, data)) { + rc = ft5435_fw_upgrade_start(data->client, fw->data, fw->size); + if (rc < 0) + dev_err(dev, "update failed (%d). try later...\n", rc); + else if (data->pdata->info.auto_cal) + ft5435_auto_cal(data->client); + } else { + dev_err(dev, "FW format error\n"); + rc = -EIO; + } + + ft5435_update_fw_ver(data); + +rel_fw: + kfree(fw); + printk("%s done\n", __func__); + return rc; +} + +#endif +#if defined(FOCALTECH_LOCK_DOWN_INFO) +#define CTP_PROC_LOCKDOWN_FILE "tp_lockdown_info" +static struct proc_dir_entry *ctp_lockdown_status_proc; +static char tp_lockdown_info[128]; + +static int ctp_lockdown_proc_show(struct seq_file *file, void *data) +{ + char temp[40] = {0}; + + sprintf(temp, "%s\n", tp_lockdown_info); + seq_printf(file, "%s\n", temp); + + return 0; +} + +static int ctp_lockdown_proc_open (struct inode *inode, struct file *file) +{ + return single_open(file, ctp_lockdown_proc_show, inode->i_private); +} + +static const struct file_operations ctp_lockdown_proc_fops = { + .open = ctp_lockdown_proc_open, + .read = seq_read, +}; + +static unsigned char ft5435_fw_LockDownInfo_get_from_boot(struct i2c_client *client, char *pProjectCode) +{ + unsigned char auc_i2c_write_buf[10]; + u8 w_buf[FT_MAX_WR_BUF] = {0}, r_buf[10] = {0}; + unsigned char i = 0, j = 0; + + + int i_ret; + + printk("[fts]%s, fw_vendor_id=0x%02x\n", __func__, fts_fw_vendor_id); + i_ret = hid_to_i2c(client); + + for (i = 0; i < FT_UPGRADE_LOOP; i++) { + msleep(FT_EARSE_DLY_MS); + + /*********Step 1:Reset CTPM *****/ + /*write 0xaa to register 0xfc */ + ft5x0x_write_reg(client, 0xfc, FT_UPGRADE_AA); + msleep(2); + + ft5x0x_write_reg(client, 0xfc, FT_UPGRADE_55); + + msleep(200); + + i_ret = hid_to_i2c(client); + + if (i_ret == 0) + printk("[FTS] hid%d change to i2c fail ! \n", i); + + msleep(10); + + /*********Step 2:Enter upgrade mode *****/ + w_buf[0] = FT_UPGRADE_55; + w_buf[1] = FT_UPGRADE_AA; + i_ret = ft5435_i2c_write(client, w_buf, 2); + + if (i_ret < 0) { + printk("[FTS] failed writing 0x55 and 0xaa ! \n"); + continue; + } + + /*********Step 3:check READ-ID***********************/ + msleep(10); + w_buf[0] = FT_READ_ID_REG; + w_buf[1] = 0x00; + w_buf[2] = 0x00; + w_buf[3] = 0x00; + + r_buf[0] = r_buf[1] = 0x00; + + ft5435_i2c_read(client, w_buf, 4, r_buf, 2); + + if (r_buf[0] == 0x54 && r_buf[1] == 0x2c) { + /* + printk("Upgrade ID mismatch(%d), IC=0x%x 0x%x, info=0x%x 0x%x\n", + i, r_buf[0], r_buf[1],info.upgrade_id_1, info.upgrade_id_2); + */ + break; + } else{ + printk("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", + r_buf[0], r_buf[1]); + continue; + } + } + + if (i >= FT_UPGRADE_LOOP) { + dev_err(&client->dev, "Abort upgrade\n"); + return -EIO; + } + + printk("%s, FTS_UPGRADE_LOOP ok is i = %d \n", __func__, i); + + /********* Step 4: read project code from app param area ***********************/ + msleep(10); + auc_i2c_write_buf[0] = 0x03; + auc_i2c_write_buf[1] = 0x00; + for (i = 0; i < FT_UPGRADE_LOOP; i++) { + auc_i2c_write_buf[2] = 0xd7; + auc_i2c_write_buf[3] = 0xa0; + i_ret = ft5435_i2c_write(client, auc_i2c_write_buf, 4); + if (i_ret < 0) { + printk("[FTS] Step 4: read lcm id from flash error when i2c write, i_ret = %d\n", i_ret); + continue; + } + msleep(10); + i_ret = ft5435_i2c_read(client, auc_i2c_write_buf, 0, r_buf, 8); + if (i_ret < 0) { + printk("[FTS] Step 4: read lcm id from flash error when i2c write, i_ret = %d\n", i_ret); + continue; + } + + for (j = 0; j < 8; j++) { + printk("%s: REG VAL = 0x%02x, j=%d\n", __func__, r_buf[j], j); + } + sprintf(pProjectCode, "%02x%02x%02x%02x%02x%02x%02x%02x", \ + r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]); + break; + } + + printk("%s: reset the tp\n", __func__); + auc_i2c_write_buf[0] = 0x07; + ft5435_i2c_write(client, auc_i2c_write_buf, 1); + msleep(300); + return 0; +} +#endif + + +static ssize_t ft5435_update_fw_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + return snprintf(buf, 2, "%d\n", data->loading_fw); +} + +static ssize_t ft5435_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + unsigned long val; + int rc; + + if (size > 2) + return -EINVAL; + + rc = kstrtoul(buf, 10, &val); + if (rc != 0) + return rc; + + if (data->suspended) { + dev_info(dev, "In suspend state, try again later...\n"); + return size; + } + + mutex_lock(&data->input_dev->mutex); + if (!data->loading_fw && val) { + data->loading_fw = true; + ft5435_fw_upgrade(dev, false); + data->loading_fw = false; + } + mutex_unlock(&data->input_dev->mutex); + + return size; +} + +static DEVICE_ATTR(update_fw, 0664, ft5435_update_fw_show, + ft5435_update_fw_store); + +static ssize_t ft5435_force_update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + unsigned long val; + int rc; + + if (size > 2) + return -EINVAL; + + rc = kstrtoul(buf, 10, &val); + if (rc != 0) + return rc; + + mutex_lock(&data->input_dev->mutex); + if (!data->loading_fw && val) { + data->loading_fw = true; + ft5435_fw_upgrade(dev, true); + data->loading_fw = false; + } + mutex_unlock(&data->input_dev->mutex); + + return size; +} + +static DEVICE_ATTR(force_update_fw, 0664, ft5435_update_fw_show, + ft5435_force_update_fw_store); + +#ifdef SET_COVER_MODE +static int set_cover_mode_buf; +static ssize_t fts_set_cover_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = 0; + struct ft5435_ts_data *data = dev_get_drvdata(dev); + sscanf(buf, "%d\n", &set_cover_mode_buf) ; + switch (set_cover_mode_buf) { + case 1: + ret = ft5x0x_write_reg(data->client, 0xC1, 0x01); + ft5x0x_write_reg(data->client, 0xC4, 0x00); + ft5x0x_write_reg(data->client, 0xC5, 0xff); + ft5x0x_write_reg(data->client, 0xC6, 0x00); + ft5x0x_write_reg(data->client, 0xC7, 0xa0); + break; + case 2: + ret = ft5x0x_write_reg(data->client, 0xC1, 0x01); + ft5x0x_write_reg(data->client, 0xC4, 0x00); + ft5x0x_write_reg(data->client, 0xC5, 0xff); + ft5x0x_write_reg(data->client, 0xc6, 0x00); + ft5x0x_write_reg(data->client, 0xC7, 0xff); + break; + case 0: + ret = ft5x0x_write_reg(data->client, 0xC1, 0x00); + break; + } + return ret; +} +static DEVICE_ATTR(set_cover_mode, 0664, NULL, + fts_set_cover_mode); + +#endif +static ssize_t ft5435_fw_name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + return snprintf(buf, FT_FW_NAME_MAX_LEN - 1, "%s\n", data->fw_name); +} + +static ssize_t ft5435_fw_name_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + + if (size > FT_FW_NAME_MAX_LEN - 1) + return -EINVAL; + + strlcpy(data->fw_name, buf, size); + if (data->fw_name[size-1] == '\n') + data->fw_name[size-1] = 0; + + return size; +} + +static DEVICE_ATTR(fw_name, 0664, ft5435_fw_name_show, ft5435_fw_name_store); + +static ssize_t ft5435_fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ft5435_ts_data *data = dev_get_drvdata(dev); + return sprintf(buf, "v%d.%d.%d\n", data->fw_ver[0], data->fw_ver[1], data->fw_ver[2]); +} + +static ssize_t ft5435_fw_version_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + return 0; +} + +static DEVICE_ATTR(fw_version, 0664, ft5435_fw_version_show, ft5435_fw_version_store); + + +static bool ft5435_debug_addr_is_valid(int addr) +{ + if (addr < 0 || addr > 0xFF) { + pr_err("FT reg address is invalid: 0x%x\n", addr); + return false; + } + + return true; +} + +static int ft5435_debug_data_set(void *_data, u64 val) +{ + struct ft5435_ts_data *data = _data; + + mutex_lock(&data->input_dev->mutex); + + if (ft5435_debug_addr_is_valid(data->addr)) + dev_info(&data->client->dev, + "Writing into FT registers not supported\n"); + + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +static int ft5435_debug_data_get(void *_data, u64 *val) +{ + struct ft5435_ts_data *data = _data; + int rc; + u8 reg; + + mutex_lock(&data->input_dev->mutex); + + if (ft5435_debug_addr_is_valid(data->addr)) { + rc = ft5x0x_read_reg(data->client, data->addr, ®); + if (rc < 0) + dev_err(&data->client->dev, + "FT read register 0x%x failed (%d)\n", + data->addr, rc); + else + *val = reg; + } + + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_data_fops, ft5435_debug_data_get, + ft5435_debug_data_set, "0x%02llX\n"); + +static int ft5435_debug_addr_set(void *_data, u64 val) +{ + struct ft5435_ts_data *data = _data; + + if (ft5435_debug_addr_is_valid(val)) { + mutex_lock(&data->input_dev->mutex); + data->addr = val; + mutex_unlock(&data->input_dev->mutex); + } + + return 0; +} + +static int ft5435_debug_addr_get(void *_data, u64 *val) +{ + struct ft5435_ts_data *data = _data; + + mutex_lock(&data->input_dev->mutex); + + if (ft5435_debug_addr_is_valid(data->addr)) + *val = data->addr; + + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_addr_fops, ft5435_debug_addr_get, + ft5435_debug_addr_set, "0x%02llX\n"); + +static int ft5435_debug_suspend_set(void *_data, u64 val) +{ + struct ft5435_ts_data *data = _data; + + mutex_lock(&data->input_dev->mutex); + + if (val) + ft5435_ts_suspend(&data->client->dev); + else + ft5435_ts_resume(&data->client->dev); + + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +static int ft5435_debug_suspend_get(void *_data, u64 *val) +{ + struct ft5435_ts_data *data = _data; + + mutex_lock(&data->input_dev->mutex); + *val = data->suspended; + mutex_unlock(&data->input_dev->mutex); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_suspend_fops, ft5435_debug_suspend_get, + ft5435_debug_suspend_set, "%lld\n"); + +static int ft5435_debug_dump_info(struct seq_file *m, void *v) +{ + struct ft5435_ts_data *data = m->private; + + seq_printf(m, "%s\n", data->ts_info); + + return 0; +} + +static int debugfs_dump_info_open(struct inode *inode, struct file *file) +{ + return single_open(file, ft5435_debug_dump_info, inode->i_private); +} + +static const struct file_operations debug_dump_info_fops = { + .owner = THIS_MODULE, + .open = debugfs_dump_info_open, + .read = seq_read, + .release = single_release, +}; + +#ifdef CONFIG_OF +static int ft5435_get_dt_coords(struct device *dev, char *name, + struct ft5435_ts_platform_data *pdata) +{ + u32 coords[FT_COORDS_ARR_SIZE]; + struct property *prop; + struct device_node *np = dev->of_node; + int coords_size, rc; + + prop = of_find_property(np, name, NULL); + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + + coords_size = prop->length / sizeof(u32); + if (coords_size != FT_COORDS_ARR_SIZE) { + dev_err(dev, "invalid %s\n", name); + return -EINVAL; + } + + rc = of_property_read_u32_array(np, name, coords, coords_size); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read %s\n", name); + return rc; + } + + if (!strcmp(name, "focaltech,panel-coords")) { + pdata->panel_minx = coords[0]; + pdata->panel_miny = coords[1]; + pdata->panel_maxx = coords[2]; + pdata->panel_maxy = coords[3]; + } else if (!strcmp(name, "focaltech,display-coords")) { + pdata->x_min = coords[0]; + pdata->y_min = coords[1]; + pdata->x_max = coords[2]; + pdata->y_max = coords[3]; + } else { + dev_err(dev, "unsupported property %s\n", name); + return -EINVAL; + } + + return 0; +} +static int ft5435_get_dt_vkey(struct device *dev, struct ft5435_ts_platform_data *pdata) +{ + u32 coords[FOCALTECH_MAX_VKEY_NUM]; + struct property *prop; + struct device_node *np = dev->of_node; + int coords_size, rc, i; + char name[128]; + memset(name, 0, sizeof(name)); + + sprintf(name, "focal,virtual_key_1"); + prop = of_find_property(np, name, NULL); + printk("[%s]000\n", __FUNCTION__); + if (!prop) + return -EINVAL; + printk("[%s]111\n", __FUNCTION__); + if (!prop->value) + return -ENODATA; + printk("[%s]222\n", __FUNCTION__); + coords_size = prop->length / sizeof(u32); + if (coords_size != pdata->num_virkey) { + printk("[%s]invalid %s\n", __FUNCTION__, name); + return -EINVAL; + } + printk("[%s]333\n", __FUNCTION__); + for (i = 0; i < pdata->num_virkey; i++) { + sprintf(name, "focal,virtual_key_%d", i+1); + rc = of_property_read_u32_array(np, name, coords, coords_size); + if (rc && (rc != -EINVAL)) { + printk("[%s]Unable to read %s\n", __FUNCTION__, name); + return rc; + } + + pdata->vkeys[i].keycode = coords[0]; + pdata->vkeys[i].x = coords[1]; + pdata->vkeys[i].y = coords[2]; + printk("[FTS]keycode = %d, x= %d, y=%d \n", pdata->vkeys[i].keycode, + pdata->vkeys[i].x, pdata->vkeys[i].y); + } + printk("[%s]5555\n", __FUNCTION__); + return 0; + + +} + +static int ft5435_parse_dt(struct device *dev, + struct ft5435_ts_platform_data *pdata) +{ + int rc; + struct device_node *np = dev->of_node; + u32 temp_val; + + pdata->name = "focaltech"; + rc = of_property_read_string(np, "focaltech,name", &pdata->name); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read name\n"); + return rc; + } + + rc = ft5435_get_dt_coords(dev, "focaltech,panel-coords", pdata); + if (rc && (rc != -EINVAL)) + return rc; + + rc = ft5435_get_dt_coords(dev, "focaltech,display-coords", pdata); + if (rc) + return rc; + + pdata->i2c_pull_up = of_property_read_bool(np, + "focaltech,i2c-pull-up"); + + pdata->no_force_update = of_property_read_bool(np, + "focaltech,no-force-update"); + /* reset, irq gpio info */ + pdata->reset_gpio = of_get_named_gpio_flags(np, "focaltech,reset-gpio", + 0, &pdata->reset_gpio_flags); + if (pdata->reset_gpio < 0) + return pdata->reset_gpio; + + pdata->irq_gpio = of_get_named_gpio_flags(np, "focaltech,irq-gpio", + 0, &pdata->irq_gpio_flags); + if (pdata->irq_gpio < 0) + return pdata->irq_gpio; + + pdata->fw_name = "ft_fw.bin"; + rc = of_property_read_string(np, "focaltech,fw-name", &pdata->fw_name); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw name\n"); + return rc; + } + + rc = of_property_read_u32(np, "focaltech,group-id", &temp_val); + if (!rc) + pdata->group_id = temp_val; + else + return rc; + + rc = of_property_read_u32(np, "focaltech,hard-reset-delay-ms", + &temp_val); + if (!rc) + pdata->hard_rst_dly = temp_val; + else + return rc; + + rc = of_property_read_u32(np, "focaltech,soft-reset-delay-ms", + &temp_val); + if (!rc) + pdata->soft_rst_dly = temp_val; + else + return rc; + + rc = of_property_read_u32(np, "focaltech,num-max-touches", &temp_val); + if (!rc) + pdata->num_max_touches = temp_val; + else + return rc; + + rc = of_property_read_u32(np, "focaltech,fw-delay-aa-ms", &temp_val); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw delay aa\n"); + return rc; + } else if (rc != -EINVAL) + pdata->info.delay_aa = temp_val; + + rc = of_property_read_u32(np, "focaltech,fw-delay-55-ms", &temp_val); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw delay 55\n"); + return rc; + } else if (rc != -EINVAL) + pdata->info.delay_55 = temp_val; + + rc = of_property_read_u32(np, "focaltech,fw-upgrade-id1", &temp_val); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw upgrade id1\n"); + return rc; + } else if (rc != -EINVAL) + pdata->info.upgrade_id_1 = temp_val; + + rc = of_property_read_u32(np, "focaltech,fw-upgrade-id2", &temp_val); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw upgrade id2\n"); + return rc; + } else if (rc != -EINVAL) + pdata->info.upgrade_id_2 = temp_val; + + rc = of_property_read_u32(np, "focaltech,fw-delay-readid-ms", + &temp_val); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw delay read id\n"); + return rc; + } else if (rc != -EINVAL) + pdata->info.delay_readid = temp_val; + + rc = of_property_read_u32(np, "focaltech,fw-delay-era-flsh-ms", + &temp_val); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read fw delay erase flash\n"); + return rc; + } else if (rc != -EINVAL) + pdata->info.delay_erase_flash = temp_val; + + pdata->info.auto_cal = of_property_read_bool(np, + "focaltech,fw-auto-cal"); + + pdata->resume_in_workqueue = of_property_read_bool(np, + "focaltech,resume-in-workqueue"); + + + pdata->fw_vkey_support = of_property_read_bool(np, + "focaltech,fw-vkey-support"); + + pdata->ignore_id_check = of_property_read_bool(np, + "focaltech,ignore-id-check"); + + rc = of_property_read_u32(np, "focaltech,num-virtual-key", &temp_val); + if (rc && (rc != -EINVAL)) { + printk("[%s]focaltech,num-virtual-key,dts parase failed\n", __FUNCTION__); + return rc; + } else if (rc != -EINVAL) { + pdata->num_virkey = temp_val; + } + rc = ft5435_get_dt_vkey(dev, pdata); + if (rc) { + printk("[%s]focaltech,ft5435_get_dt_vkey failed\n", __FUNCTION__); + return rc; + } + + rc = of_property_read_u32(np, "focaltech,family-id", &temp_val); + if (!rc) + pdata->family_id = temp_val; + else + return rc; + + return 0; +} +#else +static int ft5435_parse_dt(struct device *dev, + struct ft5435_ts_platform_data *pdata) +{ + return -ENODEV; +} +#endif + +#if defined(FOCALTECH_PWRON_UPGRADE) +static void ft_init_update_work(struct work_struct *work) +{ + struct delayed_work *delay_work; + struct ft5435_ts_data *ts; + struct device *dev; + + delay_work = to_delayed_work(work); + ts = container_of(delay_work, struct ft5435_ts_data, focaltech_update_work); + dev = &ts->input_dev->dev; + + mutex_lock(&ts->input_dev->mutex); + ft5435_fw_upgrade(dev, false); + + mutex_unlock(&ts->input_dev->mutex); +} + +u8 ft_init_update_proc(struct ft5435_ts_data *ts) +{ + dev_dbg(&ts->client->dev, "Ready to run update work."); + + INIT_DELAYED_WORK(&ts->focaltech_update_work, ft_init_update_work); + schedule_delayed_work(&ts->focaltech_update_work, + msecs_to_jiffies(3000)); + + return 0; +} +#endif + +#if defined(FOCALTECH_TP_GESTURE) +void keyset_for_tp_gesture(struct input_dev *input_dev) +{ + input_set_capability(input_dev, EV_KEY, KEY_WAKEUP); + +} +#endif + + +#if defined(RAWDATA_INTERFACE) +extern struct ft5435_rawdata_test_result ft5436_rawdata_test_result; +extern int rawdata_fail_num; +#define FTS_TX_MAX 40 +#define FTS_RX_MAX 40 +#define FTS_DEVICE_MODE_REG 0x00 +#define FTS_RAW_READ_REG 0x01 +#define FTS_RAW_BEGIN_REG 0x10 + +static int ft5x0x_enter_factory(void) +{ + u8 regval; + + ft5x0x_write_reg(ft_g_client, 0, 0x40); + mdelay(100); + if (ft5x0x_read_reg(ft_g_client, 0x00, ®val) < 0) { + pr_err("%s ERROR: could not read register\n", __FUNCTION__); + return -EPERM; + } + + if ((regval & 0x70) != 0x40) { + pr_err("%s ERROR:Touch Panel put in Factory Mode err. Mode reg: 0x%02X\n", __func__, regval); + return -EPERM; + } + + return 0; +} + +static int ft5x0x_enter_work(void) +{ + u8 regval; + ft5x0x_write_reg(ft_g_client, 0x00, 0x00); + msleep(100); + + if (ft5x0x_read_reg(ft_g_client, 0x00, ®val) < 0) { + pr_err("%s ERROR: could not read register\n", __FUNCTION__); + return -EPERM; + } + + if ((regval & 0x70) != 0x00) { + pr_err("%s ERROR:Touch Panel put in Work Mode err. Mode reg: 0x%02X\n", __func__, regval); + return -EPERM; + } + + return 0; +} + + +static int ft5x0x_read_rawdata(u16 rawdata[][FTS_RX_MAX], + u8 tx, u8 rx) +{ + u8 i = 0, j = 0, k = 0; + int err = 0; + u8 regvalue = 0x00; + u8 regaddr = 0x00; + u16 dataval = 0x0000; + u8 writebuf[2] = {0}; + u8 read_buffer[FTS_RX_MAX * 2]; + /*scan*/ + err = ft5x0x_read_reg(ft_g_client, FTS_DEVICE_MODE_REG, ®value); + if (err < 0) + return err; + + regvalue |= 0x80; + err = ft5x0x_write_reg(ft_g_client, FTS_DEVICE_MODE_REG, regvalue); + if (err < 0) + return err; + + for (i = 0; i < 20; i++) { + msleep(8); + err = ft5x0x_read_reg(ft_g_client, FTS_DEVICE_MODE_REG, + ®value); + if (err < 0) + return err; + + if (0 == (regvalue >> 7)) + break; + } + + /*get rawdata*/ + + for (i = 0; i < tx; i++) { + memset(read_buffer, 0x00, (FTS_RX_MAX * 2)); + writebuf[0] = FTS_RAW_READ_REG; + writebuf[1] = i; + err = ft5435_i2c_write(ft_g_client, writebuf, 2); + if (err < 0) { + return err; + } + /* Read the data for this row */ + regaddr = FTS_RAW_BEGIN_REG; + err = ft5435_i2c_read(ft_g_client, ®addr, 1, read_buffer, rx*2); + if (err < 0) { + return err; + } + + k = 0; + for (j = 0; j < rx*2; j += 2) { + dataval = read_buffer[j]; + dataval = (dataval << 8); + dataval |= read_buffer[j+1]; + rawdata[i][k] = dataval; + k++; + } + } + + return 0; +} + +static int fts_get_channel_info(u8 *rx, u8 *tx) +{ + /*get rx and tx num*/ + if (ft5x0x_read_reg(ft_g_client, 0x02, tx) < 0) { + printk("%s: get tx info err!\n", __func__); + return -EPERM; + } + + if (ft5x0x_read_reg(ft_g_client, 0x03, rx) < 0) { + printk("%s: get rx info err!\n", __func__); + return -EPERM; + } + + return 0; +} + +static u16 g_rawdata[FTS_TX_MAX][FTS_RX_MAX]; +static ssize_t ft5435_rawdata_register(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct ft5435_ts_data *data = i2c_get_clientdata(ft_g_client); + int i, j, p = 0; + u8 rx, tx; + int ret; + +printk("ft5435_rawdata_register: start\n"); + mutex_lock(&data->input_dev->mutex); + if (data->loading_fw) { + p = sprintf(buf+p, "loading fw!!!"); + goto RAW_ERROR; + } + + data->loading_fw = true; + if (ft5x0x_enter_factory()) { + p = sprintf(buf+p, "enter factory mode err!!!"); + goto RAW_ERROR; + } + + if (fts_get_channel_info(&rx, &tx)) { + p = sprintf(buf+p, "read channel info error!!\n"); + goto RAW_ERROR; + } + +/*[BUGFIX] ADD BEGIN - hui.wang,2014/03/17 PR-618021 To get the params*/ + p += sprintf(buf+p, "tp channel: tx = %u, rx = %u\n", tx, rx); +/*[BUGFIX] ADD END - hui.wang,2014/03/17 PR-618021 To get the params*/ + + ret = ft5x0x_read_rawdata(g_rawdata, tx, rx); + + if (ret < 0) { + p = sprintf(buf+p, "rawdata read error!\n"); + goto RAW_ERROR; + } + + for (i = 0; i < tx; i++) { + for (j = 0; j < rx; j++) { + p += sprintf(buf+p, "%u ", g_rawdata[i][j]); + } + p += sprintf(buf+p, "\n"); + } + +RAW_ERROR: + /*enter work mode*/ + data->loading_fw = false; + if (ft5x0x_enter_work()) + p = sprintf(buf+p, "enter work mode error!!\n"); + msleep(100); + mutex_unlock(&data->input_dev->mutex); + return p; +} +static ssize_t rd_result_show (struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + char *s = buf; + int i; + + + s += sprintf(s, "**************************\nAA Zone:"); + + if (rawdata_fail_num == 0) { + s += sprintf(s, "PASS\n"); + } else { + s += sprintf(s, "NG\n"); + for (i = 0; i < rawdata_fail_num; i++) { + if (ft5436_rawdata_test_result.index[i][1] < 25) { + s += sprintf(s, "X%dY%d(%u)\n", ft5436_rawdata_test_result.index[i][0], + ft5436_rawdata_test_result.index[i][1], + ft5436_rawdata_test_result.index[i][2]); + } + } + } + s += sprintf(s, "Min: %u Max: %u\n", ft5436_rawdata_test_result.min_value, ft5436_rawdata_test_result.max_value); + s += sprintf(s, "Spec Min: %u Max: %u\n", ft5436_rawdata_test_result.min_limited_value, ft5436_rawdata_test_result.max_limited_value); + + + s += sprintf(s, "**************************\nKey Zone:"); + if (rawdata_fail_num == 0) { + s += sprintf(s, "PASS\n"); + } else { + s += sprintf(s, "NG\n"); + } + s += sprintf(s, "Spec Min: %u Max: %u\n", ft5436_rawdata_test_result.min_limited_value, ft5436_rawdata_test_result.max_limited_value); + s += sprintf(s, "**************************\n"); + + return (s-buf); +} + + +static ssize_t jrd_ic_info_show (struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + u8 reg_ver; + u8 reg_vendor; + u8 ver_value, vendor_value; + int err; + char *ret = buf; + + reg_ver = FT_REG_FW_VER; + err = ft5435_i2c_read(ft_g_client, ®_ver, 1, &ver_value, 1); + if (err < 0) { + pr_err("TP FW version read failure\n"); + return sprintf (buf, "can't read firmware version \n"); + } + pr_err("0xA6=0x%x\n", ver_value); + reg_vendor = 0xA8; + err = ft5435_i2c_read(ft_g_client, ®_vendor, 1, &vendor_value, 1); + if (err < 0) { + pr_err("TP FW version read failure\n"); + return sprintf (buf, "ft irmware version(0xA6) is 0x%x\n can't read tp moudule version \n" , ver_value); + } + pr_err("0xA8=0x%x\n", vendor_value); + + ret += sprintf(ret, "%s", "TP IC: FT5436\n"); + ret += sprintf(ret, "TP module (0xA8) is 0x%x\n", vendor_value); + ret += sprintf(ret, "fimware version (0xA6) is 0x%x\n", ver_value); + return (ret - buf); +} + +static struct kobj_attribute ft5435_rawdata_attr = { + .attr = { + .name = "ft5435_rawdata", + .mode = S_IRUGO, + }, + .show = &ft5435_rawdata_register, +}; + +static struct kobj_attribute rd_result = { + .attr = { + .name = "rd_result", + .mode = S_IRUGO, + }, + .show = &rd_result_show, +}; + +static struct kobj_attribute ft5435_ic_info_attr = { + .attr = { + .name = "jrd_tp_ic_info", + .mode = S_IRUGO, + }, + .show = &jrd_ic_info_show, +}; + +static struct attribute *ft5435_rawdata_properties_attrs[] = { + &ft5435_rawdata_attr.attr, + &rd_result.attr, + &ft5435_ftsscaptest_attr.attr, + &ft5435_ic_info_attr.attr, + NULL, +}; +static struct attribute_group ft5435_rawdata_properties_attr_group = { + .attrs = ft5435_rawdata_properties_attrs, +}; +#endif + +#if defined(CONFIG_TCT_TP_FTDEBUG) +#define FTS_PACKET_LENGTH 128 +#define PROC_UPGRADE 0 +#define PROC_READ_REGISTER 1 +#define PROC_WRITE_REGISTER 2 +#define PROC_AUTOCLB 4 +#define PROC_UPGRADE_INFO 5 +#define PROC_WRITE_DATA 6 +#define PROC_READ_DATA 7 + +#define PROC_NAME "ft5x0x-debug" +static unsigned char proc_operate_mode = PROC_UPGRADE; +static struct proc_dir_entry *ft5x0x_proc_entry; + + +/*interface of write proc*/ +static ssize_t ft5x0x_debug_write(struct file *filp, const char __user *buffer, size_t count, loff_t *off) +{ + struct i2c_client *client = ft_g_client; + unsigned char writebuf[FTS_PACKET_LENGTH]; + int buflen = count; + int writelen = 0; + int ret = 0; + + if (copy_from_user(writebuf, (void __user *)buffer, buflen)) { + dev_err(&client->dev, "%s:copy from user error\n", __func__); + return -EFAULT; + } + + proc_operate_mode = writebuf[0]; + printk("proc_operate_mode = %d\n", proc_operate_mode); + switch (proc_operate_mode) { + case PROC_READ_REGISTER: + printk("%s, %d:PROC_READ_REGISTER\n", __func__, __LINE__); + writelen = 1; + ret = ft5435_i2c_write(client, writebuf + 1, writelen); + if (ret < 0) { + dev_err(&client->dev, "%s:write iic error\n", __func__); + return ret; + } + break; + case PROC_WRITE_REGISTER: + printk("%s, %d:PROC_WRITE_REGISTER\n", __func__, __LINE__); + writelen = 2; + ret = ft5435_i2c_write(client, writebuf + 1, writelen); + if (ret < 0) { + dev_err(&client->dev, "%s:write iic error\n", __func__); + return ret; + } + break; + case PROC_AUTOCLB: + printk("%s, %d:PROC_AUTOCLB\n", __func__, __LINE__); + printk("%s: autoclb\n", __func__); + fts_ctpm_auto_clb(client); + break; + case PROC_READ_DATA: + case PROC_WRITE_DATA: + printk("%s, %d:PROC_READ_DATA, PROC_WRITE_DATA\n", __func__, __LINE__); + writelen = count - 1; + ret = ft5435_i2c_write(client, writebuf + 1, writelen); + if (ret < 0) { + dev_err(&client->dev, "%s:write iic error\n", __func__); + return ret; + } + break; + default: + printk("%s, %d:default\n", __func__, __LINE__); + break; + } + + return count; +} + +/*interface of read proc*/ +static ssize_t ft5x0x_debug_read(struct file *file, char __user *page, size_t size, loff_t *ppos) +{ + struct i2c_client *client = ft_g_client; + int ret = 0; + unsigned char buf[1000]; + int num_read_chars = 0; + int readlen = 0; + u8 regvalue = 0x00, regaddr = 0x00; + + switch (proc_operate_mode) { + case PROC_UPGRADE: + /*after calling ft5x0x_debug_write to upgrade*/ + printk("%s, %d:PROC_UPGRADE\n", __func__, __LINE__); + regaddr = 0xA6; + ret = ft5x0x_read_reg(client, regaddr, ®value); + if (ret < 0) + num_read_chars = sprintf(buf, "%s", "get fw version failed.\n"); + else + num_read_chars = sprintf(buf, "current fw version:0x%02x\n", regvalue); + break; + case PROC_READ_REGISTER: + readlen = 1; + ret = ft5435_i2c_read(client, NULL, 0, buf, readlen); + if (ret < 0) { + dev_err(&client->dev, "%s:read iic error\n", __func__); + return ret; + } + printk("%s, %d:PROC_READ_REGISTER, buf = %c\n", __func__, __LINE__, *buf); + num_read_chars = 1; + break; + case PROC_READ_DATA: + printk("%s, %d:PROC_READ_DATA\n", __func__, __LINE__); + readlen = size; + ret = ft5435_i2c_read(client, NULL, 0, buf, readlen); + if (ret < 0) { + dev_err(&client->dev, "%s:read iic error\n", __func__); + return ret; + } + + num_read_chars = readlen; + break; + case PROC_WRITE_DATA: + printk("%s, %d:PROC_WRITE_DATA\n", __func__, __LINE__); + break; + default: + printk("%s, %d:default\n", __func__, __LINE__); + break; + } + + memcpy(page, buf, num_read_chars); + + return num_read_chars; +} + +static const struct file_operations ft5x0x_debug_ops = { + .owner = THIS_MODULE, + .read = ft5x0x_debug_read, + .write = ft5x0x_debug_write, +}; + +static int ft5x0x_create_apk_debug_channel(struct i2c_client *client) +{ + ft5x0x_proc_entry = proc_create(PROC_NAME, 0777, NULL, &ft5x0x_debug_ops); + + if (NULL == ft5x0x_proc_entry) { + dev_err(&client->dev, "Couldn't create proc entry!\n"); + return -ENOMEM; + } else { + dev_info(&client->dev, "Create proc entry success!\n"); + } + return 0; +} + +static void ft5x0x_release_apk_debug_channel(void) +{ + if (ft5x0x_proc_entry) + remove_proc_entry(PROC_NAME, NULL); +} +#endif + +static char tp_info_summary[80] = ""; + +static int ft5435_ts_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ft5435_ts_platform_data *pdata; + struct ft5435_ts_data *data; + struct input_dev *input_dev; + struct dentry *temp; + u8 reg_value; + u8 reg_addr; + int err, len; + u8 w_buf[FT_MAX_WR_BUF] = {0}; + int i; + int retry = 3; + char tp_temp_info[80]; + printk("~~~~~ ft5435_ts_probe start\n"); + +#if defined(CONFIG_FB) + printk("[%s]CONFIG_FB is defined\n", __FUNCTION__); +#endif +#if defined(CONFIG_PM) + printk("[%s]CONFIG_PM is defined\n", __FUNCTION__); +#endif + + if (client->dev.of_node) { + pdata = devm_kzalloc(&client->dev, + sizeof(struct ft5435_ts_platform_data), GFP_KERNEL); + if (!pdata) { + dev_err(&client->dev, "Failed to allocate memory\n"); + return -ENOMEM; + } + + err = ft5435_parse_dt(&client->dev, pdata); + if (err) { + dev_err(&client->dev, "DT parsing failed\n"); + return err; + } + } else + pdata = client->dev.platform_data; + + if (!pdata) { + dev_err(&client->dev, "Invalid pdata\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "I2C not supported\n"); + return -ENODEV; + } + + data = devm_kzalloc(&client->dev, + sizeof(struct ft5435_ts_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "Not enough memory\n"); + return -ENOMEM; + } + + if (pdata->fw_name) { + len = strlen(pdata->fw_name); + if (len > FT_FW_NAME_MAX_LEN - 1) { + dev_err(&client->dev, "Invalid firmware name\n"); + return -EINVAL; + } + + strlcpy(data->fw_name, pdata->fw_name, len + 1); + } + + data->tch_data_len = FT_TCH_LEN(pdata->num_max_touches); + data->tch_data = devm_kzalloc(&client->dev, + data->tch_data_len, GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "Not enough memory\n"); + return -ENOMEM; + } + + input_dev = input_allocate_device(); + if (!input_dev) { + dev_err(&client->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + ft_g_client = client; + data->input_dev = input_dev; + data->client = client; + data->pdata = pdata; + + input_dev->name = "ft5435_ts"; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = &client->dev; + + input_set_drvdata(input_dev, data); + i2c_set_clientdata(client, data); + + __set_bit(EV_KEY, input_dev->evbit); + __set_bit(EV_ABS, input_dev->evbit); + __set_bit(BTN_TOUCH, input_dev->keybit); + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + + for (i = 0; i < pdata->num_virkey; i++) { + input_set_capability(input_dev, EV_KEY, + pdata->vkeys[i].keycode); + } + input_mt_init_slots(input_dev, pdata->num_max_touches, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, pdata->x_min, + pdata->x_max, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, pdata->y_min, + pdata->y_max, 0, 0); +#if defined(USB_CHARGE_DETECT) +INIT_WORK(&data->work, ft5435_change_scanning_frq_switch); +#endif + +#if defined(LEATHER_COVER) +INIT_WORK(&data->work_cover, ft5435_change_leather_cover_switch); +#endif +#if defined(VR_GLASS) +INIT_WORK(&data->work_vr, ft5435_change_vr_switch); +#endif + +#if defined(FOCALTECH_TP_GESTURE) + keyset_for_tp_gesture(input_dev); + input_dev->event = ft5435_gesture_switch; +#endif + err = input_register_device(input_dev); + if (err) { + dev_err(&client->dev, "Input device registration failed\n"); + goto free_inputdev; + } + + if (gpio_is_valid(pdata->reset_gpio)) { + err = gpio_request(pdata->reset_gpio, "ft5435_reset_gpio"); + if (err) { + dev_err(&client->dev, "reset gpio request failed"); + goto unreg_inputdev; + } + + err = gpio_direction_output(pdata->reset_gpio, 0); + if (err) { + dev_err(&client->dev, + "set_direction for reset gpio failed\n"); + goto free_reset_gpio; + } + msleep(2); + } + + if (pdata->power_init) { + err = pdata->power_init(true); + if (err) { + dev_err(&client->dev, "power init failed"); + goto free_reset_gpio; + } + } else { + err = ft5435_power_init(data, true); + if (err) { + dev_err(&client->dev, "power init failed"); + goto free_reset_gpio; + } + } + + if (pdata->power_on) { + err = pdata->power_on(true); + if (err) { + dev_err(&client->dev, "power on failed"); + goto pwr_deinit; + } + } else { + err = ft5435_power_on(data, true); + if (err) { + dev_err(&client->dev, "power on failed"); + goto pwr_deinit; + } + } + + msleep(2); + + err = ft5435_ts_pinctrl_init(data); + if (!err && data->ts_pinctrl) { + err = ft5435_ts_pinctrl_select(data, true); + if (err < 0) + goto pwr_off; + } + + if (gpio_is_valid(pdata->irq_gpio)) { + err = gpio_request(pdata->irq_gpio, "ft5435_irq_gpio"); + if (err) { + dev_err(&client->dev, "irq gpio request failed"); + goto pwr_off; + } + err = gpio_direction_input(pdata->irq_gpio); + if (err) { + dev_err(&client->dev, + "set_direction for irq gpio failed\n"); + goto free_irq_gpio; + } + } + + if (gpio_is_valid(pdata->reset_gpio)) { + gpio_set_value_cansleep(data->pdata->reset_gpio, 1); + } + + /* make sure CTP already finish startup process */ + msleep(data->pdata->soft_rst_dly); + + /* check the controller id */ + reg_addr = FT_REG_ID; + while (retry--) { + err = ft5435_i2c_read(client, ®_addr, 1, ®_value, 1); + if (!(err < 0)) { + set_usb_charge_mode_par = 2; + dev_info(&client->dev, "Device ID = 0x%x\n", reg_value); + break; + } + if (gpio_is_valid(pdata->reset_gpio)) { + gpio_set_value_cansleep(data->pdata->reset_gpio, 0); + msleep(10); + gpio_set_value_cansleep(data->pdata->reset_gpio, 1); + msleep(200); + } + if (retry == 0) { + dev_err(&client->dev, "version read failed"); + goto free_irq_gpio; + } + } + data->family_id = pdata->family_id; + + +#ifdef CONFIG_TOUCHPANEL_PROXIMITY_SENSOR + vps_ft5436 = kzalloc(sizeof(struct virtualpsensor), GFP_KERNEL); + if (!vps_ft5436) { + dev_err(&client->dev, "Not enough memory\n"); + return -ENOMEM; + } + virtual_psensor_input_register2(client) ; + sys_device_create(); +#endif + + + mutex_init(&g_device_mutex); + +#if defined(FOCALTECH_PWRON_UPGRADE) + err = ft_init_update_proc(data); + if (err < 0) { + dev_err(&client->dev, + "GTP Create firmware update thread error.\n"); + + } +#endif + err = request_threaded_irq(client->irq, NULL, + ft5435_ts_interrupt, + pdata->irqflags | IRQF_ONESHOT|IRQF_TRIGGER_FALLING, + client->dev.driver->name, data); + if (err) { + dev_err(&client->dev, "request irq failed\n"); + goto free_reset_gpio; + } + + err = device_create_file(&client->dev, &dev_attr_fw_name); + if (err) { + dev_err(&client->dev, "sys file creation failed\n"); + goto irq_free; + } + + err = device_create_file(&client->dev, &dev_attr_fw_version); + if (err) { + dev_err(&client->dev, "sys file creation failed\n"); + goto free_fw_name_sys; + } + + err = device_create_file(&client->dev, &dev_attr_update_fw); + if (err) { + dev_err(&client->dev, "sys file creation failed\n"); + goto free_fw_version_sys; + } + + err = device_create_file(&client->dev, &dev_attr_force_update_fw); + if (err) { + dev_err(&client->dev, "sys file creation failed\n"); + goto free_update_fw_sys; + } +#ifdef SET_COVER_MODE + err = device_create_file(&client->dev, &dev_attr_set_cover_mode); + if (err) { + dev_err(&client->dev, "sys file creation failed\n"); + goto free_set_cover_mode; + } +#endif + data->dir = debugfs_create_dir(FT_DEBUG_DIR_NAME, NULL); + if (data->dir == NULL || IS_ERR(data->dir)) { + pr_err("debugfs_create_dir failed(%ld)\n", PTR_ERR(data->dir)); + err = PTR_ERR(data->dir); + goto free_force_update_fw_sys; + } + + temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, data->dir, data, + &debug_addr_fops); + if (temp == NULL || IS_ERR(temp)) { + pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp)); + err = PTR_ERR(temp); + goto free_debug_dir; + } + + temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, data->dir, data, + &debug_data_fops); + if (temp == NULL || IS_ERR(temp)) { + pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp)); + err = PTR_ERR(temp); + goto free_debug_dir; + } + + temp = debugfs_create_file("suspend", S_IRUSR | S_IWUSR, data->dir, + data, &debug_suspend_fops); + if (temp == NULL || IS_ERR(temp)) { + pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp)); + err = PTR_ERR(temp); + goto free_debug_dir; + } + + temp = debugfs_create_file("dump_info", S_IRUSR | S_IWUSR, data->dir, + data, &debug_dump_info_fops); + if (temp == NULL || IS_ERR(temp)) { + pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp)); + err = PTR_ERR(temp); + goto free_debug_dir; + } + + data->ts_info = devm_kzalloc(&client->dev, + FT_INFO_MAX_LEN, GFP_KERNEL); + if (!data->ts_info) { + dev_err(&client->dev, "Not enough memory\n"); + goto free_debug_dir; + } + + /*get some register information */ + reg_addr = FT_REG_POINT_RATE; + ft5435_i2c_read(client, ®_addr, 1, ®_value, 1); + if (err < 0) + dev_err(&client->dev, "report rate read failed"); + + dev_info(&client->dev, "report rate = %dHz\n", reg_value * 10); + + reg_addr = FT_REG_THGROUP; + err = ft5435_i2c_read(client, ®_addr, 1, ®_value, 1); + if (err < 0) + dev_err(&client->dev, "threshold read failed"); + + dev_dbg(&client->dev, "touch threshold = %d\n", reg_value * 4); + + ft5435_update_fw_ver(data); + ft5435_update_fw_vendor_id(data); + fts_fw_vendor_id = data->fw_vendor_id; + printk("upgrade,fts_fw_vendor_id=0x%02x\n", data->fw_vendor_id); +#if defined(FOCALTECH_AUTO_UPGRADE) + if ((fts_fw_vendor_id != FTS_VENDOR_1) && (fts_fw_vendor_id != FTS_VENDOR_2)) { + fts_fw_vendor_id = ft5435_fw_Vid_get_from_boot(client); + printk("get_Vid_from_boot, fw_vendor_id=0x%02x\n", fts_fw_vendor_id); + } + + mutex_lock(&data->input_dev->mutex); + if (!data->loading_fw) { + data->loading_fw = true; + if (fts_fw_vendor_id == FTS_VENDOR_1) + ft5435_fw_upgrade_by_array_data(&client->dev, firmware_data_vendor1, sizeof(firmware_data_vendor1), !data->pdata->no_force_update); + else if (fts_fw_vendor_id == FTS_VENDOR_2) + ft5435_fw_upgrade_by_array_data(&client->dev, firmware_data_vendor2, sizeof(firmware_data_vendor2), !data->pdata->no_force_update); + else + printk("[FTS] FW unmatched,stop upgrade\n"); + data->loading_fw = false; + } + mutex_unlock(&data->input_dev->mutex); + +#endif + + FT_STORE_TS_INFO(data->ts_info, data->family_id, data->pdata->name, + data->pdata->num_max_touches, data->pdata->group_id, + data->pdata->fw_vkey_support ? "yes" : "no", + data->pdata->fw_name, data->fw_ver[0], + data->fw_ver[1], data->fw_ver[2]); + +#if defined(CONFIG_FB) + + data->fb_notif.notifier_call = fb_notifier_callback; + + err = fb_register_client(&data->fb_notif); + + if (err) + dev_err(&client->dev, "Unable to register fb_notifier: %d\n", + err); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + + FT_SUSPEND_LEVEL; + data->early_suspend.suspend = ft5435_ts_early_suspend; + data->early_suspend.resume = ft5435_ts_late_resume; + register_early_suspend(&data->early_suspend); +#endif + + +/* [PLATFORM]-Mod-BEGIN by TCTNB.ZXZ, PR-814306, 2014/10/24, add for alto5 premium firmware version*/ +#ifdef CONFIG_TCT_8X16_ALTO5_PREMIUM +firm_ver_attr_create(); +#endif +/* [PLATFORM]-Mod-END by TCTNB.ZXZ*/ + +#ifdef FOCALTECH_TP_GLOVE + tp_glove_register(data); +#endif + + +g_ft5435_ts_data = data; + + +#if defined(RAWDATA_INTERFACE) +{ + static struct kobject *ft5435_rawdata_properties_kobj; + static struct kobject *ft5435_CTP_properties_kobj; + int rc = 0; + + ft5435_rawdata_properties_kobj = + kobject_create_and_add("rawdata", NULL); + + if (ft5435_rawdata_properties_kobj) + rc = sysfs_create_group(ft5435_rawdata_properties_kobj, + &ft5435_rawdata_properties_attr_group); + + if (!ft5435_rawdata_properties_kobj || rc) + pr_err("%s: failed to create rawdata\n", __func__); + + ft5435_CTP_properties_kobj = + kobject_create_and_add("CTP", NULL); + + if (ft5435_CTP_properties_kobj) + rc = sysfs_create_group(ft5435_CTP_properties_kobj, + &ft5435_rawdata_properties_attr_group); + + if (!ft5435_CTP_properties_kobj || rc) + pr_err("%s: failed to create rawdata\n", __func__); +} +#endif +#ifdef FOCALTECH_LOCK_DOWN_INFO + ft5435_fw_LockDownInfo_get_from_boot(client, tp_lockdown_info); + printk("tpd_probe, ft5x46_ctpm_LockDownInfo_get_from_boot, tp_lockdown_info=%s\n", tp_lockdown_info); + ctp_lockdown_status_proc = proc_create(CTP_PROC_LOCKDOWN_FILE, 0644, NULL, &ctp_lockdown_proc_fops); + if (ctp_lockdown_status_proc == NULL) + printk("tpd, create_proc_entry ctp_lockdown_status_proc failed\n"); +#endif + +#if defined(CONFIG_TCT_TP_FTDEBUG) + if (ft5x0x_create_apk_debug_channel(client) < 0) + ft5x0x_release_apk_debug_channel(); +#endif + + w_buf[0] = FT_REG_RESET_FW; + ft5435_i2c_write(client, w_buf, 1); + init_ok = 1; + wake_lock_init(&ft5436_wakelock, WAKE_LOCK_SUSPEND, "ft5436"); + if (fts_fw_vendor_id == FTS_VENDOR_1) { + strcpy(tp_info_summary, "[Vendor]Biel, [IC]FT5435, [FW]Ver"); + } else if (fts_fw_vendor_id == FTS_VENDOR_2) { + strcpy(tp_info_summary, "[Vendor]Ofilm, [IC]FT5435, [FW]Ver"); + } else{ + strcpy(tp_info_summary, "[Vendor]Unknown, [IC]FT5435, [FW]Ver"); + } + sprintf(tp_temp_info, "%d", data->fw_ver[0]); + strcat(tp_info_summary, tp_temp_info); + strcat(tp_info_summary, "\0"); + printk("~~~~~ ft5435_ts_probe end\n"); + return 0; + +free_debug_dir: + debugfs_remove_recursive(data->dir); +free_force_update_fw_sys: + device_remove_file(&client->dev, &dev_attr_force_update_fw); +free_update_fw_sys: + device_remove_file(&client->dev, &dev_attr_update_fw); + +#ifdef SET_COVER_MODE +free_set_cover_mode: + device_remove_file(&client->dev, &dev_attr_set_cover_mode); +#endif + +free_fw_version_sys: + device_remove_file(&client->dev, &dev_attr_fw_version); + +free_fw_name_sys: + device_remove_file(&client->dev, &dev_attr_fw_name); +irq_free: + free_irq(client->irq, data); + +free_irq_gpio: + if (gpio_is_valid(pdata->irq_gpio)) + gpio_free(pdata->irq_gpio); + if (data->ts_pinctrl) { + err = ft5435_ts_pinctrl_select(data, false); + if (err < 0) + pr_err("Cannot get idle pinctrl state\n"); + } + if (data->ts_pinctrl) { + devm_pinctrl_put(data->ts_pinctrl); + data->ts_pinctrl = NULL; + } + if (gpio_is_valid(pdata->reset_gpio)) { + gpio_direction_output(pdata->reset_gpio, 0); + mdelay(2); + } +pwr_off: + if (pdata->power_on) + pdata->power_on(false); + else + ft5435_power_on(data, false); +pwr_deinit: + if (pdata->power_init) + pdata->power_init(false); + else + ft5435_power_init(data, false); +free_reset_gpio: + if (gpio_is_valid(pdata->reset_gpio)) { + gpio_direction_output(pdata->reset_gpio, 0); + mdelay(5); + gpio_free(pdata->reset_gpio); + } +unreg_inputdev: + input_unregister_device(input_dev); + input_dev = NULL; +free_inputdev: + input_free_device(input_dev); + return err; +} + +static int ft5435_ts_remove(struct i2c_client *client) +{ + struct ft5435_ts_data *data = i2c_get_clientdata(client); + int retval; + + debugfs_remove_recursive(data->dir); + device_remove_file(&client->dev, &dev_attr_force_update_fw); + device_remove_file(&client->dev, &dev_attr_update_fw); + device_remove_file(&client->dev, &dev_attr_fw_name); + +#if defined(CONFIG_FB) + if (fb_unregister_client(&data->fb_notif)) + dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n"); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&data->early_suspend); +#endif + free_irq(client->irq, data); + + if (gpio_is_valid(data->pdata->reset_gpio)) + gpio_free(data->pdata->reset_gpio); + + if (gpio_is_valid(data->pdata->irq_gpio)) + gpio_free(data->pdata->irq_gpio); + + if (data->ts_pinctrl) { + retval = ft5435_ts_pinctrl_select(data, false); + if (retval < 0) + pr_err("Cannot get idle pinctrl state\n"); + devm_pinctrl_put(data->ts_pinctrl); + data->ts_pinctrl = NULL; + } + + if (data->pdata->power_on) + data->pdata->power_on(false); + else + ft5435_power_on(data, false); + + if (data->pdata->power_init) + data->pdata->power_init(false); + else + ft5435_power_init(data, false); + + +#if defined(CONFIG_TCT_TP_FTDEBUG) + ft5x0x_release_apk_debug_channel(); +#endif + + input_unregister_device(data->input_dev); + wake_lock_destroy(&ft5436_wakelock); + + return 0; +} + +static const struct i2c_device_id ft5435_ts_id[] = { + {"ft5435_ts", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, ft5435_ts_id); + +#ifdef CONFIG_OF +static struct of_device_id ft5435_match_table[] = { + { .compatible = "focaltech,5435",}, + { }, +}; +#else +#define ft5435_match_table NULL +#endif + +static struct i2c_driver ft5435_ts_driver = { + .probe = ft5435_ts_probe, + .remove = ft5435_ts_remove, + .driver = { + .name = "ft5435_ts", + .owner = THIS_MODULE, + .of_match_table = ft5435_match_table, +#ifdef CONFIG_PM + .pm = &ft5435_ts_pm_ops, +#endif + }, + .id_table = ft5435_ts_id, +}; + +static int __init ft5435_ts_init(void) +{ + printk("tony_test:[%s]\n", __FUNCTION__); + ft5435_wq = create_singlethread_workqueue("ft5435_wq"); + if (!ft5435_wq) { + printk("Creat ft5435 workqueue failed. \n"); + return -ENOMEM; + } + ft5435_wq_cover = create_singlethread_workqueue("ft5435_wq_cover"); + if (!ft5435_wq_cover) { + printk("Creat ft5435_wq_cover workqueue failed. \n"); + return -ENOMEM; + } +#if defined(VR_GLASS) + ft5435_wq_vr = create_singlethread_workqueue("ft5435_wq_vr"); + if (!ft5435_wq_vr) { + printk("Creat ft5435_wq_vr workqueue failed. \n"); + return -ENOMEM; + } +#endif + return i2c_add_driver(&ft5435_ts_driver); +} +module_init(ft5435_ts_init); + +static void __exit ft5435_ts_exit(void) +{ + if (ft5435_wq) { + destroy_workqueue(ft5435_wq); + } + i2c_del_driver(&ft5435_ts_driver); +} +module_exit(ft5435_ts_exit); + +MODULE_DESCRIPTION("FocalTech ft5435 TouchScreen driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.h b/drivers/input/touchscreen/ft5435/ft5435_ts.h new file mode 100644 index 000000000000..986359e0a254 --- /dev/null +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.h @@ -0,0 +1,93 @@ +/* + * + * FocalTech ft5435 TouchScreen driver header file. + * + * Copyright (c) 2010 Focal tech Ltd. + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_FT5435_TS_H__ +#define __LINUX_FT5435_TS_H__ + +#define FT5435_ID 0x55 +#define FT5X16_ID 0x0A +#define FT5X36_ID 0x14 +#define FT6X06_ID 0x06 +#define FT6X36_ID 0x36 +/* [PLATFORM]-Mod-BEGIN by TCTNB.YQJ, FR797197, 2014/11/28 add for tp gesture */ + +#define SET_COVER_MODE +#define FOCALTECH_AUTO_UPGRADE 1 +#define FOCALTECH_LOCK_DOWN_INFO 1 +#define FOCALTECH_TP_GESTURE +#define FOCALTECH_FAE_MOD + +#define USB_CHARGE_DETECT +#define FOCALTECH_ITO_TEST 1 +#define FOCALTECH_MAX_VKEY_NUM 3 + +struct fw_upgrade_info { + bool auto_cal; + u16 delay_aa; + u16 delay_55; + u8 upgrade_id_1; + u8 upgrade_id_2; + u16 delay_readid; + u16 delay_erase_flash; +}; +struct virkey{ + int keycode; + int x; + int y; +}; +struct ft5435_ts_platform_data { + struct fw_upgrade_info info; + const char *name; + const char *fw_name; + u32 irqflags; + u32 irq_gpio; + u32 irq_gpio_flags; + u32 reset_gpio; + u32 reset_gpio_flags; + u32 family_id; + u32 x_max; + u32 y_max; + u32 x_min; + u32 y_min; + u32 panel_minx; + u32 panel_miny; + u32 panel_maxx; + u32 panel_maxy; + u32 group_id; + u32 hard_rst_dly; + u32 soft_rst_dly; + u32 num_max_touches; + bool fw_vkey_support; + bool no_force_update; + bool i2c_pull_up; + bool ignore_id_check; + bool resume_in_workqueue; + int (*power_init) (bool); + int (*power_on) (bool); + int num_virkey; + struct virkey vkeys[FOCALTECH_MAX_VKEY_NUM]; +}; +struct ft5435_rawdata_test_result { + int result; + int min_limited_value; + int max_limited_value; + int min_value; + int max_value; + int index[350][3]; +}; +#endif diff --git a/drivers/input/touchscreen/ft5435/mcap_test_lib.h b/drivers/input/touchscreen/ft5435/mcap_test_lib.h new file mode 100644 index 000000000000..c7ab8258a659 --- /dev/null +++ b/drivers/input/touchscreen/ft5435/mcap_test_lib.h @@ -0,0 +1,26 @@ +#ifndef _FOCAL_MCAPTESTLIB_H +#define _FOCAL_MCAPTESTLIB_H + +#define boolean unsigned char +#define bool unsigned char +#define BYTE unsigned char +#define false 0 +#define true 1 + +typedef int (*FTS_I2C_READ_FUNCTION)(unsigned char *, int , unsigned char *, int); +typedef int (*FTS_I2C_WRITE_FUNCTION)(unsigned char *, int); + +extern FTS_I2C_READ_FUNCTION fts_i2c_read_test; +extern FTS_I2C_WRITE_FUNCTION fts_i2c_write_test; + +extern int init_i2c_read_func(FTS_I2C_READ_FUNCTION fpI2C_Read); +extern int init_i2c_write_func(FTS_I2C_WRITE_FUNCTION fpI2C_Write); + +int set_param_data(char *TestParamData); +boolean start_test_tp(void); +int get_test_data(char *pTestData); + +void free_test_param_data(void); +int show_lib_ver(char *pLibVer); + +#endif diff --git a/drivers/input/touchscreen/ist3038c/IST3038C1_00000C6GFF_VER000007.h b/drivers/input/touchscreen/ist3038c/IST3038C1_00000C6GFF_VER000007.h new file mode 100644 index 000000000000..253dd8aee6cd --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/IST3038C1_00000C6GFF_VER000007.h @@ -0,0 +1,4054 @@ + +#ifndef __IST30XXC_FW_H__ +#define __IST30XXC_FW_H__ + + + + + + + +static unsigned char ist30xxc_fw[] = { + 0x80, 0x00, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x94, 0x0D, 0x00, 0x80, 0xFC, 0x00, 0x00, 0x80, + 0x04, 0x01, 0x00, 0x80, 0x18, 0x0E, 0x00, 0x80, 0xC8, 0x0D, 0x00, 0x80, 0xF0, 0x0D, 0x00, 0x80, + 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x60, 0x0E, 0x00, 0x80, + 0x84, 0x0E, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x10, 0x00, 0x27, 0x08, 0x80, 0x00, 0x80, 0x2C, 0x80, 0xEC, 0x9C, 0xAB, 0x0B, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0x04, 0x61, 0x99, 0x67, 0x10, 0x00, 0x91, 0x67, 0x08, 0x70, 0x0F, 0x00, + 0x11, 0x17, 0x0C, 0x70, 0xC0, 0x17, 0x0C, 0x60, 0xC0, 0x17, 0xC6, 0x76, 0xB2, 0x04, 0xB1, 0x07, + 0x24, 0x74, 0xF2, 0xFC, 0x08, 0x30, 0x00, 0x80, 0x04, 0x70, 0x0C, 0x40, 0xC0, 0x17, 0x0C, 0x50, + 0x64, 0x19, 0x2C, 0x30, 0x24, 0xA2, 0x2F, 0x64, 0x07, 0x00, 0xC6, 0x65, 0xB2, 0x07, 0x2F, 0x23, + 0x07, 0x00, 0x30, 0x22, 0x24, 0x74, 0xB1, 0x26, 0xF2, 0xF7, 0x0C, 0x70, 0x64, 0x19, 0x0C, 0x60, + 0xD0, 0x1B, 0xC6, 0x76, 0xB2, 0x04, 0xB1, 0x07, 0x24, 0x74, 0xF2, 0xFC, 0x4B, 0x10, 0x00, 0x00, + 0x4B, 0xE6, 0x04, 0x00, 0xB9, 0x20, 0x88, 0x27, 0x04, 0x22, 0xF2, 0x0D, 0xB9, 0x20, 0x88, 0x27, + 0x04, 0x23, 0xF2, 0x09, 0xB9, 0x20, 0x88, 0x27, 0x04, 0x24, 0xF2, 0x05, 0xB9, 0x20, 0x88, 0x27, + 0x04, 0x21, 0xF2, 0x01, 0xB9, 0x10, 0x84, 0x27, 0xB9, 0x30, 0x8C, 0x27, 0x08, 0x30, 0x00, 0x50, + 0xB9, 0x03, 0x00, 0x10, 0xD9, 0x40, 0x90, 0x27, 0xD9, 0x80, 0xA0, 0x27, 0xD9, 0xC0, 0xB0, 0x27, + 0x01, 0x40, 0x01, 0x51, 0xC9, 0x40, 0xC0, 0x27, 0x99, 0x20, 0x80, 0x27, 0x08, 0x20, 0x01, 0x00, + 0xB1, 0x23, 0x98, 0x40, 0x80, 0x27, 0x92, 0xFE, 0x09, 0x00, 0x01, 0x00, 0x04, 0x23, 0xB9, 0x23, + 0x00, 0x10, 0xF2, 0x01, 0x48, 0x40, 0xC0, 0x27, 0x11, 0x15, 0x11, 0x04, 0x58, 0xC0, 0xB0, 0x27, + 0x58, 0x80, 0xA0, 0x27, 0x58, 0x40, 0x90, 0x27, 0x48, 0x20, 0x88, 0x27, 0x38, 0x10, 0x84, 0x27, + 0x61, 0x00, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x2B, 0xEF, 0x00, 0x00, + 0x0B, 0xF6, 0x00, 0x00, 0x2B, 0xF7, 0x00, 0x00, 0xCB, 0xCD, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0xFC, 0x00, 0x00, 0xAB, 0x0A, 0x01, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xCB, 0x0D, 0x01, 0x00, + 0x4B, 0xFF, 0x00, 0x00, 0x6B, 0xFE, 0x00, 0x00, 0x2B, 0xFD, 0x00, 0x00, 0x8B, 0x00, 0x01, 0x00, + 0x4B, 0x01, 0x01, 0x00, 0xAB, 0x03, 0x01, 0x00, 0x2B, 0x29, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0x11, 0x01, 0x00, 0xAB, 0xF1, 0x00, 0x00, + 0x4B, 0xA4, 0x04, 0x00, 0xAB, 0x0A, 0x01, 0x00, 0x8B, 0x16, 0x01, 0x00, 0x4B, 0x82, 0x00, 0x00, + 0x6B, 0xA0, 0x00, 0x00, 0x28, 0x20, 0x80, 0x1B, 0x54, 0x24, 0xA3, 0x22, 0x92, 0x03, 0x6B, 0x35, + 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0xAB, 0xE9, + 0x00, 0x00, 0xAB, 0xEE, 0x00, 0x00, 0xCB, 0x13, 0x00, 0x00, 0xCB, 0x0B, 0x00, 0x00, 0xAB, 0x0C, + 0x00, 0x00, 0x4B, 0x0D, 0x00, 0x00, 0x4B, 0xE4, 0x00, 0x00, 0x8B, 0x8D, 0x01, 0x00, 0xAB, 0x0E, + 0x00, 0x00, 0x8B, 0x8C, 0x01, 0x00, 0x8B, 0x16, 0x01, 0x00, 0x98, 0x70, 0xA9, 0x1B, 0x92, 0xFA, + 0x18, 0x70, 0xA0, 0x1B, 0xC4, 0x71, 0x82, 0xF6, 0x98, 0x70, 0x9F, 0x1B, 0x82, 0x04, 0x6B, 0xDE, + 0x04, 0x00, 0xF2, 0xF0, 0x2B, 0x8B, 0x01, 0x00, 0xCB, 0x31, 0x00, 0x00, 0x2B, 0x4A, 0x01, 0x00, + 0x6B, 0x32, 0x00, 0x00, 0x4B, 0x89, 0x01, 0x00, 0x6B, 0x8A, 0x01, 0x00, 0xAB, 0x8B, 0x01, 0x00, + 0x6B, 0x3C, 0x01, 0x00, 0xF2, 0xDF, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x04, 0x61, 0xB9, 0x67, + 0x00, 0x80, 0xB9, 0x07, 0x0C, 0x80, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x80, 0xC6, 0x27, 0x34, 0x14, + 0xB1, 0xF1, 0x82, 0x03, 0xC6, 0x37, 0x92, 0x04, 0x6B, 0x1B, 0x00, 0x00, 0xF2, 0x09, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x27, 0x04, 0x80, 0xB9, 0x37, 0x08, 0x80, 0x38, 0x27, 0x10, 0x80, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x80, 0xB9, 0x37, 0x1C, 0x80, + 0x06, 0x67, 0x38, 0x76, 0x28, 0x80, 0xD4, 0x71, 0x82, 0xFD, 0x38, 0x26, 0x20, 0x80, 0xE1, 0xF0, + 0x04, 0x50, 0xC6, 0x25, 0x32, 0x03, 0x16, 0x22, 0x04, 0x51, 0x04, 0x60, 0xC6, 0x36, 0x32, 0x03, + 0x16, 0x33, 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x80, 0xB9, 0x37, 0x1C, 0x80, + 0x06, 0x47, 0x38, 0x74, 0x28, 0x80, 0xD4, 0x71, 0x82, 0xFD, 0xC6, 0x56, 0x38, 0x24, 0x20, 0x80, + 0x82, 0x02, 0x16, 0x22, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x80, + 0xB9, 0x37, 0x1C, 0x80, 0x06, 0x67, 0x38, 0x76, 0x28, 0x80, 0xD4, 0x71, 0x82, 0xFD, 0x38, 0x26, + 0x24, 0x80, 0xE1, 0xF0, 0x04, 0x50, 0xC6, 0x25, 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE2, 0x32, 0x03, + 0x16, 0xE2, 0x04, 0x51, 0x04, 0x60, 0xC6, 0x36, 0x32, 0x03, 0x16, 0x33, 0x04, 0x61, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0xE7, 0x18, 0x80, 0xB9, 0x37, 0x1C, 0x80, 0x06, 0x47, 0x38, 0x74, 0x28, 0x80, + 0xD4, 0x71, 0x82, 0xFD, 0xC6, 0x56, 0x38, 0x24, 0x20, 0x80, 0x82, 0x02, 0x16, 0x22, 0x4B, 0x14, + 0x00, 0x00, 0x3F, 0x22, 0x0E, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0xC4, 0x30, 0x04, 0x40, + 0x04, 0x50, 0x0C, 0x60, 0x20, 0x00, 0x52, 0x03, 0xA6, 0x42, 0x25, 0x50, 0xB4, 0x61, 0x02, 0x06, + 0xA6, 0x44, 0x25, 0x55, 0xA6, 0x33, 0x42, 0xF9, 0xF2, 0xFA, 0x06, 0x24, 0x06, 0x35, 0xE1, 0xF0, + 0x04, 0x40, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9E, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x9D, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9C, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9B, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x9A, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x99, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x98, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x97, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x96, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x95, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x94, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x93, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x92, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x91, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x90, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8F, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8E, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x8D, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8C, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8B, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x8A, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x89, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x88, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x87, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x86, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x85, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x84, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x83, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x82, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x81, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x80, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x7F, + 0x00, 0x00, 0xE1, 0xF0, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x62, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x63, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x64, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x65, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x66, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x67, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x68, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x69, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6A, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x6B, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6C, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x6D, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6E, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x6F, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x70, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x71, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x72, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x73, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x74, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x75, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x76, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x77, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x78, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x79, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7A, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x7B, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7C, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x7D, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7E, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xFA, 0x7F, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x80, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x04, 0x70, 0x6C, 0x70, 0x40, 0x00, + 0x66, 0x72, 0xB9, 0x76, 0x04, 0x70, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x60, 0x71, + 0x08, 0x50, 0x40, 0x00, 0x66, 0x75, 0xB9, 0x76, 0x60, 0x71, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x60, 0x71, 0x08, 0x50, 0x40, 0x00, 0x66, 0x75, 0xB9, 0x76, + 0x60, 0x71, 0x0C, 0x20, 0x64, 0x00, 0x2B, 0xED, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x08, 0x50, 0x00, 0x40, 0x38, 0x75, 0x60, 0x71, 0x08, 0x60, 0xBF, 0xFF, 0x2C, 0x60, 0xFF, 0xFF, + 0x56, 0x76, 0xB9, 0x75, 0x60, 0x71, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0x00, 0x60, 0xB1, 0xF1, + 0x2B, 0x60, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xA0, 0x1B, + 0x34, 0x14, 0xB1, 0xF1, 0x92, 0x05, 0x0C, 0x20, 0x00, 0x60, 0x0B, 0x61, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0x00, 0x60, 0xB1, 0xF1, 0x2B, 0x60, 0x00, 0x00, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x60, 0x71, 0x08, 0x50, 0x40, 0x00, 0x66, 0x75, 0xB9, 0x76, + 0x60, 0x71, 0x0C, 0x20, 0x64, 0x00, 0x2B, 0xED, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x04, 0x70, 0x1C, 0x50, 0x1D, 0x00, 0x56, 0x75, 0x66, 0x72, + 0xB9, 0x76, 0x04, 0x70, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x04, 0x35, + 0x06, 0xE2, 0x04, 0x21, 0xCB, 0x78, 0x00, 0x00, 0x04, 0x24, 0x04, 0x30, 0xCB, 0x5E, 0x00, 0x00, + 0x08, 0xD0, 0x00, 0x40, 0x38, 0x7D, 0x08, 0x70, 0xD6, 0x7E, 0x92, 0x0A, 0x04, 0x21, 0x4B, 0x77, + 0x00, 0x00, 0xCB, 0x5A, 0x00, 0x00, 0x04, 0x21, 0x0B, 0x78, 0x00, 0x00, 0xF2, 0xF4, 0x04, 0x24, + 0x04, 0x31, 0xCB, 0x5E, 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x18, 0x70, 0x9C, 0x1B, 0x34, 0x14, 0x93, 0x07, 0xB1, 0xF1, 0x92, 0x02, 0x51, 0x00, 0x08, 0x60, + 0x00, 0x40, 0x38, 0x76, 0x04, 0x70, 0x1C, 0x50, 0x41, 0x70, 0x56, 0x75, 0xB9, 0x76, 0x04, 0x70, + 0x04, 0x24, 0x04, 0x31, 0xCB, 0x5E, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0x38, 0x67, 0x08, 0x70, 0xB9, 0x67, 0x08, 0x70, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE2, 0x0B, 0x39, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0xE7, + 0x00, 0x70, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, + 0x06, 0xD3, 0x0B, 0x39, 0x00, 0x00, 0x04, 0x24, 0x04, 0x30, 0xCB, 0x5E, 0x00, 0x00, 0x06, 0x2D, + 0xAB, 0x2E, 0x00, 0x00, 0x99, 0x00, 0x9C, 0x1B, 0x08, 0x70, 0x00, 0x40, 0xB9, 0xE7, 0x00, 0x70, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x80, 0x18, 0x67, 0x67, 0xDC, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x7C, 0x70, 0x38, 0x67, 0x70, 0x70, 0x64, 0x62, 0xB9, 0x67, + 0x70, 0x70, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x70, 0x70, 0x64, 0x71, 0xB9, 0x76, + 0x70, 0x70, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x70, 0x70, 0x14, 0x52, 0x56, 0x75, + 0xB9, 0x76, 0x70, 0x70, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0xE0, 0x70, + 0x5C, 0x20, 0xFF, 0x7F, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0xE4, 0x70, + 0x5C, 0x20, 0xFF, 0x01, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0xEC, 0x70, + 0x5C, 0x20, 0xFF, 0x0F, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0x5C, 0x70, + 0x5C, 0x20, 0x7F, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x08, 0x60, 0x00, 0x40, 0x82, 0x08, + 0x08, 0x70, 0x0F, 0xC0, 0x2C, 0x70, 0xFF, 0xFF, 0xB9, 0x76, 0x3C, 0x71, 0xF2, 0x03, 0xB9, 0x06, + 0x3C, 0x71, 0xE1, 0xF0, 0x08, 0x20, 0x00, 0x40, 0x08, 0x30, 0x00, 0x80, 0x34, 0x18, 0x2C, 0x20, + 0x08, 0x70, 0x2C, 0x30, 0x08, 0xE2, 0x0C, 0x40, 0xBE, 0x00, 0xC1, 0xE1, 0x0C, 0xF0, 0x5C, 0x01, + 0xF1, 0xF0, 0x0C, 0x20, 0x00, 0x40, 0x08, 0xE0, 0x00, 0x30, 0x08, 0x30, 0x00, 0x80, 0x26, 0x2E, + 0x2C, 0x30, 0x00, 0xE5, 0x0C, 0x40, 0x40, 0x02, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x0C, 0x20, + 0xC4, 0x52, 0x08, 0x30, 0x00, 0x80, 0x26, 0x2E, 0x2C, 0x30, 0x00, 0xEE, 0x0C, 0x40, 0x54, 0x00, + 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x08, 0x70, 0x00, 0x80, 0x28, 0x77, 0x28, 0xDC, 0x0C, 0x20, + 0x00, 0x49, 0x06, 0x37, 0x57, 0x38, 0x26, 0x2E, 0x66, 0x37, 0x0C, 0x40, 0x69, 0x01, 0x0C, 0xF0, + 0xD8, 0x01, 0xF1, 0xF0, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x7F, 0x56, 0x72, + 0xC4, 0x71, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x92, 0x04, 0x38, 0x70, 0x68, 0x1A, 0xF2, 0x03, + 0x38, 0x70, 0x6C, 0x1A, 0xC4, 0x28, 0x38, 0x67, 0x50, 0x00, 0x38, 0x57, 0x74, 0x00, 0x38, 0x37, + 0x68, 0x00, 0x38, 0xF7, 0x8C, 0x00, 0x38, 0x47, 0x94, 0x00, 0x82, 0x49, 0xC4, 0x28, 0xD2, 0x07, + 0xC4, 0x22, 0x82, 0x16, 0xC4, 0x23, 0x82, 0x38, 0xC4, 0x21, 0xF2, 0x09, 0xCC, 0x20, 0x82, 0x00, + 0x82, 0x13, 0xCC, 0x20, 0x82, 0x00, 0xD2, 0x05, 0xCC, 0x20, 0x81, 0x00, 0x92, 0x7B, 0xF2, 0x3F, + 0xCC, 0x20, 0x83, 0x00, 0x82, 0x29, 0xCC, 0x20, 0x88, 0x00, 0x82, 0x31, 0xF2, 0x73, 0x98, 0x20, + 0xB0, 0x1B, 0x82, 0x35, 0xF2, 0x1C, 0x98, 0x20, 0xB0, 0x1B, 0x82, 0x31, 0x08, 0x50, 0x00, 0x80, + 0x2C, 0x50, 0x0C, 0xDC, 0x28, 0x60, 0x0E, 0x0B, 0x18, 0x25, 0x73, 0x00, 0xC6, 0x26, 0xD2, 0x06, + 0x38, 0x67, 0x60, 0x00, 0x38, 0x57, 0x84, 0x00, 0xF2, 0x22, 0x18, 0x55, 0x74, 0x00, 0xC6, 0x56, + 0xD2, 0x06, 0x38, 0x67, 0x64, 0x00, 0x38, 0x57, 0x88, 0x00, 0xF2, 0x19, 0x38, 0x67, 0x5C, 0x00, + 0x38, 0x57, 0x80, 0x00, 0xF2, 0x14, 0x38, 0x67, 0x54, 0x00, 0x38, 0x57, 0x78, 0x00, 0x38, 0x37, + 0x6C, 0x00, 0x38, 0xF7, 0x90, 0x00, 0x38, 0x47, 0x98, 0x00, 0xF2, 0x09, 0x38, 0x67, 0x58, 0x00, + 0x38, 0x57, 0x7C, 0x00, 0x38, 0x37, 0x70, 0x00, 0x38, 0x47, 0x9C, 0x00, 0x98, 0x70, 0xA1, 0x1B, + 0x82, 0x05, 0x08, 0x60, 0x22, 0x00, 0x2C, 0x60, 0x20, 0x20, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, + 0x34, 0x70, 0xB9, 0x57, 0x64, 0x70, 0xB9, 0x37, 0x54, 0x70, 0xB9, 0xF7, 0x6C, 0x70, 0xB9, 0x47, + 0x1C, 0x71, 0x06, 0x65, 0x0C, 0x60, 0xFC, 0x0A, 0x38, 0x66, 0x0C, 0x00, 0x08, 0x40, 0x10, 0x00, + 0xD6, 0x64, 0x06, 0xD5, 0x82, 0x0C, 0xB8, 0x60, 0x8C, 0x19, 0x92, 0x09, 0x08, 0x60, 0x00, 0x8E, + 0x2C, 0x60, 0x80, 0x0F, 0xB9, 0x67, 0x6C, 0x70, 0xAB, 0x3C, 0x00, 0x00, 0xB8, 0x70, 0x8C, 0x19, + 0x82, 0x11, 0x38, 0x70, 0xFC, 0x0A, 0x08, 0x60, 0x00, 0x40, 0xCC, 0x70, 0xC7, 0x00, 0xD2, 0x04, + 0x08, 0x70, 0x00, 0x8E, 0xF2, 0x03, 0x08, 0x70, 0x80, 0x8F, 0x2C, 0x70, 0x80, 0x0F, 0xB9, 0x76, + 0x6C, 0x70, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x54, 0x2F, 0xC4, 0x21, + 0x92, 0x04, 0x38, 0x70, 0x68, 0x1A, 0xF2, 0x03, 0x38, 0x70, 0x6C, 0x1A, 0x38, 0x57, 0x4C, 0x00, + 0x98, 0x70, 0xB0, 0x1B, 0x08, 0x70, 0x00, 0x80, 0x82, 0x06, 0x2C, 0x70, 0xBC, 0xDC, 0x38, 0x77, + 0x04, 0x00, 0xF2, 0x03, 0x38, 0x77, 0xBC, 0xDC, 0xB8, 0x60, 0x8C, 0x19, 0x82, 0x03, 0x0C, 0x70, + 0xFF, 0x3F, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x56, 0x30, 0x70, 0xB9, 0x76, 0x58, 0x70, 0xE1, 0xF0, + 0x54, 0x2F, 0xC4, 0x21, 0x92, 0x04, 0x38, 0x60, 0x68, 0x1A, 0xF2, 0x03, 0x38, 0x60, 0x6C, 0x1A, + 0x38, 0x56, 0x08, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x57, 0xB4, 0x70, 0x38, 0x56, 0x0C, 0x00, + 0x08, 0x40, 0xDF, 0xFF, 0xB9, 0x57, 0xB8, 0x70, 0x38, 0x56, 0x10, 0x00, 0x2C, 0x40, 0xFF, 0xFF, + 0x56, 0x54, 0xB9, 0x57, 0xC0, 0x70, 0x38, 0x56, 0x14, 0x00, 0xB9, 0x57, 0xC4, 0x70, 0x98, 0x50, + 0xA2, 0x1B, 0x82, 0x0C, 0x08, 0x60, 0x01, 0x00, 0x2C, 0x60, 0x81, 0x11, 0xB9, 0x67, 0xAC, 0x70, + 0x08, 0x60, 0x10, 0x00, 0x2C, 0x60, 0x10, 0x00, 0xF2, 0x06, 0x30, 0x56, 0xB9, 0x57, 0xAC, 0x70, + 0x38, 0x66, 0x04, 0x00, 0xB9, 0x67, 0xB0, 0x70, 0x28, 0x70, 0x80, 0x1B, 0xD4, 0x74, 0x82, 0x1D, + 0x08, 0x60, 0x01, 0x00, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x40, 0x82, 0xB9, 0x67, 0xAC, 0x70, + 0xB9, 0x07, 0xB0, 0x70, 0x08, 0x60, 0x08, 0x00, 0xB9, 0x67, 0xB4, 0x70, 0x08, 0x60, 0x88, 0x00, + 0xB9, 0x07, 0xB8, 0x70, 0x2C, 0x60, 0x00, 0x10, 0xB9, 0x67, 0xC0, 0x70, 0x08, 0x60, 0x10, 0x1F, + 0x2C, 0x60, 0x10, 0x1F, 0xB9, 0x67, 0xC4, 0x70, 0xE1, 0xF0, 0x00, 0x00, 0x54, 0x2F, 0xC4, 0x21, + 0x92, 0x04, 0x38, 0x60, 0x68, 0x1A, 0xF2, 0x03, 0x38, 0x60, 0x6C, 0x1A, 0x38, 0x56, 0x2C, 0x00, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x57, 0x8C, 0x70, 0x38, 0x56, 0x30, 0x00, 0xB9, 0x57, 0x90, 0x70, + 0x38, 0x56, 0x34, 0x00, 0xB9, 0x57, 0x94, 0x70, 0x38, 0x56, 0x38, 0x00, 0xB9, 0x57, 0x98, 0x70, + 0x38, 0x56, 0x3C, 0x00, 0xB9, 0x57, 0x9C, 0x70, 0x38, 0x56, 0x40, 0x00, 0xB9, 0x57, 0xA0, 0x70, + 0x38, 0x56, 0x44, 0x00, 0xB9, 0x57, 0xA4, 0x70, 0x38, 0x66, 0x48, 0x00, 0xB9, 0x67, 0xA8, 0x70, + 0x28, 0x60, 0x80, 0x1B, 0xD4, 0x64, 0x82, 0x18, 0x08, 0x60, 0x01, 0x80, 0xB9, 0x67, 0x8C, 0x70, + 0x08, 0x50, 0x01, 0x00, 0x0C, 0x60, 0x20, 0x00, 0x26, 0x65, 0xB9, 0x67, 0x90, 0x70, 0xB9, 0x07, + 0x94, 0x70, 0xB9, 0x07, 0x98, 0x70, 0xB9, 0x57, 0x9C, 0x70, 0xB9, 0x67, 0xA0, 0x70, 0xB9, 0x07, + 0xA4, 0x70, 0xB9, 0x07, 0xA8, 0x70, 0xE1, 0xF0, 0x51, 0x00, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, + 0xC4, 0x20, 0x38, 0x67, 0x34, 0x10, 0x82, 0x03, 0x64, 0x63, 0xF2, 0x03, 0x14, 0x54, 0x56, 0x65, + 0xB9, 0x67, 0x34, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0xAD, 0xDE, 0x2C, 0x70, 0x8C, 0x03, + 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x00, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0xAD, 0xDE, + 0x08, 0x60, 0x00, 0x40, 0x2C, 0x70, 0x8C, 0x03, 0xB9, 0x76, 0x00, 0x10, 0xB9, 0x26, 0x6C, 0x10, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, + 0xB9, 0x67, 0x00, 0x10, 0x0C, 0x50, 0x10, 0x00, 0xB9, 0x57, 0x20, 0x10, 0x08, 0x50, 0x38, 0x03, + 0xB9, 0x67, 0x00, 0x10, 0x2C, 0x50, 0x80, 0x88, 0xB9, 0x57, 0x24, 0x10, 0xB9, 0x67, 0x00, 0x10, + 0xB9, 0x07, 0x28, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, + 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, 0xC4, 0x30, 0x38, 0x67, 0x50, 0x10, 0x82, 0x05, + 0x66, 0x62, 0xB9, 0x67, 0x50, 0x10, 0xF2, 0x05, 0x15, 0x22, 0x56, 0x26, 0xB9, 0x27, 0x50, 0x10, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, + 0xB9, 0x67, 0x00, 0x10, 0x38, 0x67, 0x54, 0x10, 0x66, 0x62, 0xB9, 0x67, 0x54, 0x10, 0xE1, 0xF0, + 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, + 0x38, 0x67, 0x54, 0x10, 0x15, 0x22, 0x56, 0x26, 0xB9, 0x27, 0x54, 0x10, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, + 0x38, 0x57, 0x58, 0x10, 0xCC, 0x20, 0xFF, 0x00, 0x1C, 0x40, 0x00, 0x01, 0x56, 0x54, 0x92, 0x0A, + 0xB9, 0x57, 0x58, 0x10, 0xB9, 0x67, 0x00, 0x10, 0x38, 0x67, 0x4C, 0x10, 0x14, 0x52, 0x56, 0x65, + 0xF2, 0x09, 0x66, 0x52, 0xB9, 0x57, 0x58, 0x10, 0xB9, 0x67, 0x00, 0x10, 0x38, 0x67, 0x4C, 0x10, + 0x64, 0x61, 0xB9, 0x67, 0x4C, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, + 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, 0xC4, 0x30, 0x38, 0x67, 0x4C, 0x10, 0x82, 0x05, + 0x66, 0x62, 0xB9, 0x67, 0x4C, 0x10, 0xF2, 0x05, 0x15, 0x22, 0x56, 0x26, 0xB9, 0x27, 0x4C, 0x10, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0xAD, 0xDE, 0x08, 0x60, 0x00, 0x40, 0x2C, 0x70, 0x8C, 0x03, + 0xB9, 0x76, 0x00, 0x10, 0x04, 0x73, 0xB9, 0x76, 0x44, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x08, 0x10, 0x66, 0x72, 0xB9, 0x76, 0x08, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x64, 0x10, 0x66, 0x72, 0xB9, 0x76, 0x64, 0x10, 0xE1, 0xF0, 0x04, 0x62, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x14, 0x10, 0xE1, 0xF0, 0x23, 0x22, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, + 0x10, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x14, 0x10, 0x1C, 0x50, 0x11, 0x00, + 0x56, 0x75, 0x64, 0x71, 0xB9, 0x76, 0x14, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x14, 0x10, 0x14, 0x52, 0x56, 0x75, 0x6C, 0x70, 0x10, 0x00, + 0xB9, 0x76, 0x14, 0x10, 0x0C, 0x20, 0x28, 0x00, 0x8B, 0xEA, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x04, 0x7F, 0x82, 0x03, 0x0C, 0x70, 0x9C, 0x00, 0x6C, 0x70, + 0x00, 0x01, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x74, 0x10, 0xE1, 0xF0, 0x04, 0x61, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x70, 0x10, 0xE1, 0xF0, 0xC4, 0x20, 0x08, 0x70, 0x00, 0x40, 0x82, 0x04, + 0x04, 0x61, 0xB1, 0x67, 0xF2, 0x02, 0xB1, 0x07, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x30, 0x57, 0x21, + 0x08, 0x70, 0x00, 0x40, 0x26, 0x72, 0x82, 0x04, 0x04, 0x61, 0xB1, 0x67, 0xF2, 0x02, 0xB1, 0x07, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0xCB, 0xB9, 0x00, 0x00, 0x08, 0x70, + 0x1C, 0xE1, 0x08, 0x60, 0x00, 0x30, 0x2C, 0x70, 0x04, 0xE9, 0xB9, 0x76, 0x04, 0x01, 0x08, 0xE0, + 0x00, 0x40, 0xB9, 0x76, 0x08, 0x01, 0x2C, 0xE0, 0x70, 0x10, 0x04, 0xD1, 0xB1, 0xDE, 0x04, 0x2A, + 0xAB, 0xED, 0x00, 0x00, 0xF2, 0xFC, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, + 0x01, 0x70, 0xC9, 0x61, 0x08, 0x00, 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x14, 0x40, + 0x48, 0x61, 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, 0x40, 0x61, 0x2C, 0x10, 0x10, 0x00, 0x61, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, 0x08, 0x00, 0x04, 0x61, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x14, 0x50, 0x48, 0x61, 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, + 0x40, 0x61, 0x2C, 0x10, 0x10, 0x00, 0x61, 0x00, 0x3C, 0x10, 0x24, 0x00, 0xD9, 0x41, 0x08, 0x00, + 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, 0x1C, 0x00, 0xC1, 0x21, 0x04, 0x61, 0x0C, 0x20, 0x28, 0x00, + 0xB9, 0xF1, 0x18, 0x00, 0x99, 0x60, 0x9D, 0x1B, 0x8B, 0xEA, 0x00, 0x00, 0x04, 0x61, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x78, 0x10, 0x48, 0x61, 0x1C, 0x00, 0x38, 0xF1, 0x18, 0x00, 0x40, 0x21, + 0x11, 0x16, 0x11, 0x07, 0x58, 0x41, 0x08, 0x00, 0x2C, 0x10, 0x24, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, 0x08, 0x00, 0x04, 0x61, + 0x99, 0x60, 0x9C, 0x1B, 0x48, 0x61, 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, 0x40, 0x61, 0x2C, 0x10, + 0x10, 0x00, 0x61, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, + 0x08, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x67, 0x08, 0x70, 0xB9, 0x67, 0x08, 0x70, 0x48, 0x61, + 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, 0x40, 0x61, 0x2C, 0x10, 0x10, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x08, 0x70, 0x04, 0x00, 0x24, 0x74, 0x26, 0x27, 0x08, 0x70, 0xFF, 0xBF, 0x57, 0x26, 0x2C, 0x70, + 0x00, 0xC0, 0xB1, 0x42, 0x26, 0x27, 0x0C, 0x40, 0x04, 0x40, 0x08, 0x70, 0x00, 0x40, 0x26, 0x47, + 0x26, 0x42, 0xB1, 0x34, 0x0C, 0x40, 0x10, 0x40, 0x26, 0x47, 0x26, 0x42, 0x2C, 0x70, 0x08, 0x40, + 0xB1, 0x54, 0x26, 0x27, 0xB1, 0x62, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x70, 0x08, 0x40, + 0x57, 0x26, 0x26, 0x27, 0x30, 0x72, 0x6C, 0x70, 0x00, 0x01, 0xB1, 0x72, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0x2C, 0x70, 0x08, 0x40, 0x57, 0x26, 0x26, 0x27, 0x30, 0x72, 0x1C, 0x60, + 0x01, 0x01, 0x56, 0x76, 0xB1, 0x72, 0xE1, 0xF0, 0x08, 0x70, 0x04, 0x00, 0x24, 0x74, 0x26, 0x27, + 0x57, 0x26, 0xB1, 0x32, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x57, 0x26, 0x2C, 0x70, + 0x0C, 0x40, 0x26, 0x72, 0x30, 0x27, 0xE1, 0xF0, 0x08, 0x70, 0x0F, 0x00, 0xD6, 0x72, 0x3C, 0x10, + 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x06, 0xC3, 0x82, 0x04, 0x1C, 0x70, 0x01, 0x10, 0x56, 0xE7, + 0x08, 0xD0, 0x00, 0x30, 0xCB, 0xB9, 0x00, 0x00, 0xB9, 0xED, 0x04, 0x01, 0xEB, 0x6A, 0x00, 0x00, + 0x0C, 0x20, 0xE8, 0x03, 0xAB, 0xED, 0x00, 0x00, 0xC4, 0xC0, 0x92, 0xF5, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x34, 0x18, 0x08, 0x50, 0x00, 0x80, 0xB9, 0xF1, 0x04, 0x00, 0xB1, 0x01, + 0x04, 0x70, 0x2C, 0x50, 0xAC, 0x9D, 0xC6, 0x73, 0x82, 0x0F, 0x04, 0x63, 0x56, 0x67, 0x26, 0x61, + 0x2F, 0x47, 0x02, 0x00, 0x10, 0xF6, 0x10, 0x44, 0x24, 0x71, 0x76, 0x4F, 0x13, 0x44, 0x26, 0x45, + 0x10, 0x44, 0x91, 0x46, 0xF2, 0xF1, 0x38, 0xF1, 0x04, 0x00, 0x30, 0x21, 0x24, 0x18, 0xE1, 0xF0, + 0x34, 0x18, 0x08, 0x70, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0xC1, 0xE1, 0x2C, 0x40, 0x5C, 0x04, + 0x06, 0xE2, 0x06, 0x27, 0x2C, 0x20, 0x80, 0x02, 0x36, 0x42, 0x08, 0x30, 0x00, 0x80, 0x2C, 0x30, + 0x48, 0xA0, 0x77, 0x41, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x98, 0x01, 0x04, 0x30, + 0x0C, 0x40, 0x80, 0x04, 0x0C, 0x50, 0x00, 0x01, 0x04, 0x61, 0x0C, 0xF0, 0x98, 0x03, 0xF1, 0xF0, + 0xC4, 0x20, 0x82, 0x26, 0x04, 0x21, 0xCB, 0x3F, 0x00, 0x00, 0x0C, 0x50, 0x80, 0x04, 0x0C, 0x70, + 0x88, 0x04, 0x06, 0x2E, 0x2C, 0x50, 0xC8, 0x01, 0x30, 0x67, 0x5C, 0x60, 0xFF, 0x03, 0x57, 0x61, + 0xB1, 0x62, 0x30, 0x67, 0x77, 0x64, 0x5C, 0x60, 0xFC, 0x0F, 0xB9, 0x62, 0x04, 0x00, 0x30, 0x67, + 0x24, 0x74, 0x77, 0x69, 0xC6, 0x75, 0x5C, 0x60, 0xFC, 0x0F, 0xB9, 0x62, 0x08, 0x00, 0x24, 0x2C, + 0x92, 0xEC, 0x04, 0x20, 0xCB, 0x3F, 0x00, 0x00, 0x38, 0x20, 0x84, 0x04, 0xF2, 0x03, 0x08, 0x20, + 0x01, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x08, 0x20, 0x00, 0x30, 0x34, 0x18, 0x2C, 0x20, + 0x00, 0x40, 0xC1, 0xE1, 0x8B, 0x7D, 0x00, 0x00, 0x08, 0x70, 0x00, 0xFF, 0x2C, 0x70, 0xFF, 0x00, + 0x08, 0x60, 0x00, 0xAA, 0x0C, 0x50, 0x55, 0x00, 0x56, 0x72, 0x26, 0x56, 0xC6, 0x75, 0x06, 0xE2, + 0x92, 0x19, 0x0C, 0x70, 0x00, 0x10, 0xD6, 0x72, 0x82, 0x18, 0x0C, 0x20, 0x98, 0x01, 0x04, 0x34, + 0x0C, 0x40, 0xC4, 0x01, 0x0C, 0xF0, 0x04, 0x04, 0xF1, 0xF0, 0x38, 0x70, 0x80, 0x04, 0xC6, 0x27, + 0x82, 0x05, 0x08, 0x70, 0x02, 0x00, 0x66, 0xE7, 0xF2, 0x08, 0x04, 0x61, 0x99, 0x60, 0x9E, 0x1B, + 0xF2, 0x08, 0x06, 0xE6, 0x2C, 0xE0, 0x55, 0x01, 0x06, 0x2E, 0x04, 0x30, 0xCB, 0x79, 0x00, 0x00, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0x40, + 0x00, 0x00, 0x06, 0xC2, 0x08, 0x20, 0x00, 0x00, 0x2C, 0x20, 0x80, 0x02, 0x2C, 0x40, 0x5C, 0x04, + 0x06, 0xE3, 0x36, 0x42, 0x08, 0x30, 0x00, 0x80, 0x2C, 0x30, 0x48, 0xA0, 0x77, 0x41, 0x0C, 0xF0, + 0x5C, 0x01, 0xF1, 0xF0, 0x0C, 0xF0, 0xA4, 0x02, 0xF1, 0xF0, 0x04, 0x30, 0x0C, 0x20, 0x98, 0x01, + 0x0C, 0x40, 0x80, 0x04, 0x0C, 0x50, 0x00, 0x01, 0x06, 0x63, 0x0C, 0xF0, 0x98, 0x03, 0xF1, 0xF0, + 0xC4, 0x20, 0x82, 0x4B, 0x0C, 0xD0, 0x00, 0x10, 0x66, 0xDE, 0x0C, 0xF0, 0x80, 0x04, 0xB9, 0xD0, + 0x84, 0x04, 0x06, 0x6C, 0x0C, 0x40, 0x88, 0x04, 0x2C, 0xF0, 0xC8, 0x01, 0x78, 0x76, 0x02, 0x00, + 0x78, 0x56, 0x04, 0x00, 0x77, 0x71, 0x77, 0x51, 0x57, 0x5A, 0x57, 0x75, 0x66, 0x75, 0x70, 0x56, + 0x24, 0x66, 0x77, 0x51, 0x66, 0x75, 0xB1, 0x74, 0x24, 0x44, 0xC6, 0x4F, 0x92, 0xF0, 0x0C, 0x30, + 0xC0, 0x01, 0x0C, 0x20, 0x84, 0x04, 0xAB, 0x7B, 0x00, 0x00, 0xB9, 0x20, 0x80, 0x04, 0x04, 0x30, + 0x0C, 0x20, 0x38, 0x00, 0x0C, 0xF0, 0xE8, 0x02, 0xF1, 0xF0, 0x0C, 0x20, 0x58, 0x01, 0x04, 0x30, + 0x0C, 0x40, 0x80, 0x04, 0x0C, 0x50, 0x00, 0x01, 0x0C, 0xF0, 0x34, 0x03, 0xF1, 0xF0, 0x0C, 0xF0, + 0xC0, 0x02, 0xF1, 0xF0, 0x0C, 0x20, 0x98, 0x01, 0x04, 0x34, 0x0C, 0x40, 0xC4, 0x01, 0x0C, 0xF0, + 0x04, 0x04, 0xF1, 0xF0, 0x38, 0x70, 0x80, 0x04, 0xC6, 0x27, 0x82, 0x0A, 0x08, 0x20, 0x02, 0x00, + 0x2C, 0x20, 0x00, 0x10, 0x66, 0x2E, 0xF2, 0x05, 0x08, 0x20, 0x01, 0x00, 0xF2, 0x02, 0x06, 0x2D, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x18, 0x70, + 0xB2, 0x1B, 0x1C, 0x60, 0x10, 0x00, 0x56, 0x76, 0x06, 0x43, 0x64, 0x78, 0xF7, 0x40, 0x04, 0x30, + 0x99, 0x70, 0xB2, 0x1B, 0x06, 0xD2, 0x0C, 0xF0, 0xC4, 0x01, 0xF1, 0xF0, 0x18, 0x20, 0xB2, 0x1B, + 0x6B, 0x44, 0x00, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0xEB, 0x4E, 0x00, 0x00, 0xAB, 0x0A, 0x01, 0x00, + 0x2B, 0x33, 0x00, 0x00, 0x0C, 0xE0, 0x15, 0x00, 0xB4, 0xE1, 0x82, 0x09, 0x04, 0x21, 0x0C, 0x30, + 0x00, 0x20, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0xF2, 0xF7, 0x08, 0x60, 0x00, 0x30, + 0x0C, 0x70, 0x00, 0x49, 0x0C, 0x50, 0x40, 0x4E, 0x06, 0x2D, 0x26, 0x76, 0x26, 0x56, 0x30, 0x67, + 0x24, 0x74, 0xC6, 0x75, 0x5C, 0x60, 0xFF, 0x0F, 0xA1, 0x62, 0x24, 0x22, 0x92, 0xF9, 0x50, 0xC1, + 0x08, 0x20, 0x00, 0xAA, 0x2C, 0x20, 0x55, 0x00, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x2D, 0x0C, 0x20, 0x80, 0x02, 0x0C, 0x30, 0xD2, 0x02, + 0x4B, 0x8D, 0x00, 0x00, 0x08, 0x70, 0x00, 0xAA, 0x2C, 0x70, 0x55, 0x00, 0xD6, 0x72, 0x06, 0xE2, + 0x06, 0x2D, 0x82, 0x03, 0x6C, 0xE0, 0x00, 0x20, 0x0C, 0x70, 0x00, 0x20, 0xD6, 0x7E, 0x82, 0x07, + 0x06, 0x3E, 0x0C, 0x20, 0x80, 0x02, 0xCB, 0x85, 0x00, 0x00, 0x66, 0xE2, 0x06, 0x2E, 0x04, 0x31, + 0xB9, 0x00, 0x68, 0x19, 0xCB, 0x79, 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0xA0, 0x01, 0x06, 0x21, 0x04, 0x30, 0x0C, 0x40, 0x69, 0x01, 0xD9, 0x81, 0x80, 0x01, + 0xD9, 0xC1, 0x90, 0x01, 0xAB, 0xE5, 0x04, 0x00, 0x08, 0x90, 0x00, 0x30, 0x0C, 0x70, 0x00, 0x49, + 0x26, 0x79, 0x08, 0xB0, 0xFF, 0xC0, 0x0C, 0xA0, 0x15, 0x00, 0xB9, 0x71, 0x6C, 0x01, 0x2C, 0x90, + 0x00, 0x40, 0x2C, 0xB0, 0xFF, 0xFF, 0xCB, 0x3B, 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, + 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x04, 0xE0, 0x06, 0xDE, 0x06, 0xCE, 0x57, 0xC1, + 0x04, 0x80, 0x2F, 0xFE, 0x01, 0x00, 0x26, 0xF8, 0x90, 0x4F, 0x92, 0x60, 0x38, 0x71, 0x6C, 0x01, + 0x1C, 0x20, 0xAC, 0x0D, 0x26, 0x7C, 0x30, 0x37, 0x5C, 0x30, 0xFF, 0x0F, 0x26, 0x23, 0xC3, 0x22, + 0x02, 0x2C, 0x2F, 0x69, 0x0C, 0x00, 0x30, 0x56, 0x08, 0x70, 0x00, 0x3F, 0x56, 0x75, 0x77, 0x7C, + 0xC4, 0x70, 0x82, 0x23, 0x34, 0x71, 0x1C, 0x30, 0x90, 0x01, 0xB9, 0x51, 0x74, 0x01, 0xB9, 0x61, + 0x7C, 0x01, 0xB9, 0x41, 0x70, 0x01, 0xB9, 0x71, 0x78, 0x01, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x71, + 0x78, 0x01, 0x38, 0x41, 0x70, 0x01, 0x26, 0x27, 0x43, 0x22, 0x06, 0x34, 0x0C, 0xF0, 0xBC, 0x00, + 0xF1, 0xF0, 0x38, 0x51, 0x74, 0x01, 0x38, 0x61, 0x7C, 0x01, 0x5C, 0x20, 0x3F, 0x00, 0x57, 0x2C, + 0x56, 0x5B, 0x66, 0x25, 0xB1, 0x26, 0xF2, 0x25, 0x0C, 0x70, 0x2C, 0x01, 0x3F, 0x33, 0x07, 0x00, + 0xC4, 0x30, 0x02, 0x22, 0x2F, 0x79, 0x0C, 0x00, 0x30, 0x67, 0x08, 0x20, 0x00, 0x3F, 0x56, 0x26, + 0x77, 0x2C, 0xCC, 0x20, 0x3F, 0x00, 0x82, 0x18, 0x24, 0x21, 0x0C, 0x30, 0x3F, 0x00, 0xB9, 0x61, + 0x7C, 0x01, 0xB9, 0x71, 0x78, 0x01, 0x0C, 0xF0, 0x98, 0x00, 0xF1, 0xF0, 0x38, 0x61, 0x7C, 0x01, + 0x38, 0x71, 0x78, 0x01, 0x5C, 0x20, 0x3F, 0x00, 0x57, 0x2C, 0x56, 0x6B, 0x66, 0x26, 0xB1, 0x27, + 0x24, 0xD1, 0x23, 0xDD, 0xF2, 0x03, 0x04, 0x71, 0x91, 0x7F, 0x24, 0x81, 0xCC, 0x80, 0x13, 0x00, + 0x24, 0xC4, 0x92, 0x98, 0x2C, 0xE0, 0x13, 0x00, 0xCC, 0xE0, 0xBE, 0x00, 0x92, 0x90, 0xC4, 0xD0, + 0x82, 0x05, 0x34, 0xA1, 0xA3, 0xAA, 0x9A, 0x80, 0xFF, 0xFF, 0x58, 0xC1, 0x90, 0x01, 0x58, 0x81, + 0x80, 0x01, 0x2C, 0x10, 0xA0, 0x01, 0xE1, 0xF0, 0x2F, 0x72, 0x02, 0x00, 0x26, 0x72, 0xD7, 0x71, + 0xCC, 0x30, 0x16, 0x00, 0x26, 0x73, 0xB1, 0x74, 0xC2, 0x13, 0x06, 0x65, 0x0C, 0x60, 0x74, 0x1A, + 0x28, 0x50, 0x74, 0x1A, 0xC6, 0x75, 0x82, 0x10, 0x28, 0x56, 0x02, 0x00, 0xC6, 0x75, 0x82, 0x0C, + 0x28, 0x66, 0x04, 0x00, 0x04, 0x21, 0xC6, 0x76, 0x82, 0x08, 0x04, 0x20, 0xF2, 0x06, 0xC4, 0x2D, + 0xD2, 0xED, 0x04, 0x22, 0xF2, 0x02, 0x04, 0x21, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0xA4, 0x01, + 0x06, 0x21, 0x04, 0x30, 0x0C, 0x40, 0x69, 0x01, 0xD9, 0xC1, 0x94, 0x01, 0xD9, 0x81, 0x84, 0x01, + 0xAB, 0xE5, 0x04, 0x00, 0xB8, 0x70, 0x8C, 0x19, 0x9A, 0xBA, 0x00, 0x00, 0xCB, 0x31, 0x00, 0x00, + 0x04, 0x23, 0x6B, 0x44, 0x00, 0x00, 0x04, 0x23, 0xEB, 0x4E, 0x00, 0x00, 0xAB, 0x3C, 0x00, 0x00, + 0x4B, 0x2F, 0x00, 0x00, 0x0C, 0x70, 0x15, 0x00, 0xB9, 0x71, 0x70, 0x01, 0x08, 0xA0, 0x00, 0x30, + 0x0C, 0x70, 0x00, 0x49, 0x26, 0x7A, 0x08, 0xB0, 0xFF, 0xC0, 0xB9, 0x71, 0x74, 0x01, 0x2C, 0xB0, + 0xFF, 0xFF, 0xCB, 0x3B, 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x04, 0x80, 0x4B, 0x3A, + 0x00, 0x00, 0x06, 0xD8, 0x8B, 0x37, 0x00, 0x00, 0x06, 0xE1, 0x04, 0xC0, 0x2F, 0x7C, 0x0E, 0x00, + 0x90, 0x97, 0x92, 0x73, 0x0C, 0x40, 0x6C, 0x01, 0x06, 0x28, 0x06, 0x3C, 0x26, 0x41, 0x4B, 0x9E, + 0x00, 0x00, 0xC4, 0x20, 0x82, 0x6A, 0x38, 0xF1, 0x6C, 0x01, 0x38, 0x71, 0x74, 0x01, 0x06, 0x3F, + 0x57, 0x31, 0x26, 0x73, 0x30, 0x67, 0x1C, 0x20, 0xAC, 0x0D, 0x5C, 0x60, 0xFF, 0x0F, 0x26, 0x26, + 0xC3, 0x22, 0x02, 0x2A, 0x0C, 0x50, 0x00, 0x40, 0x26, 0x5A, 0x26, 0x53, 0x30, 0x45, 0x08, 0x70, + 0x00, 0x3F, 0x56, 0x74, 0x77, 0x7C, 0xC4, 0x70, 0x82, 0x1F, 0x34, 0x71, 0x1C, 0x30, 0xC8, 0x00, + 0xB9, 0x41, 0x78, 0x01, 0xB9, 0x51, 0x7C, 0x01, 0xB9, 0x71, 0x80, 0x01, 0x8B, 0x16, 0x00, 0x00, + 0x38, 0x71, 0x80, 0x01, 0x06, 0x39, 0x26, 0x27, 0x43, 0x22, 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, + 0x38, 0x41, 0x78, 0x01, 0x38, 0x51, 0x7C, 0x01, 0x5C, 0x20, 0x3F, 0x00, 0x57, 0x2C, 0x56, 0x4B, + 0x66, 0x24, 0xB1, 0x25, 0xF2, 0x2C, 0x0C, 0x20, 0x2C, 0x01, 0x36, 0x26, 0xC4, 0x20, 0x02, 0x2A, + 0x0C, 0x90, 0x00, 0x40, 0x26, 0x9A, 0x26, 0x93, 0x30, 0x79, 0x08, 0x50, 0x00, 0x3F, 0x56, 0x57, + 0x77, 0x5C, 0xCC, 0x50, 0x3F, 0x00, 0x82, 0x1E, 0x24, 0x51, 0x0C, 0x30, 0xC8, 0x00, 0xB9, 0x71, + 0x80, 0x01, 0xB9, 0x51, 0x7C, 0x01, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x51, 0x7C, 0x01, 0x0C, 0x30, + 0x3F, 0x00, 0x26, 0x25, 0x43, 0x22, 0x0C, 0xF0, 0x98, 0x00, 0xF1, 0xF0, 0x38, 0x71, 0x80, 0x01, + 0x5C, 0x20, 0x3F, 0x00, 0x57, 0x2C, 0x56, 0x7B, 0x66, 0x27, 0xB1, 0x29, 0x24, 0xD1, 0x23, 0xDD, + 0xF2, 0x04, 0x26, 0xF1, 0x04, 0x71, 0x91, 0x7F, 0x24, 0xC1, 0xCC, 0xC0, 0x18, 0x00, 0x92, 0x87, + 0x24, 0x81, 0xC4, 0x8E, 0x2C, 0xE0, 0x18, 0x00, 0x9A, 0x81, 0xFF, 0xFF, 0xC4, 0xD0, 0x82, 0x09, + 0x38, 0x71, 0x70, 0x01, 0x34, 0x71, 0xA3, 0x77, 0xB9, 0x71, 0x70, 0x01, 0x9A, 0x6B, 0xFF, 0xFF, + 0x0B, 0x31, 0x00, 0x00, 0x2B, 0x3D, 0x00, 0x00, 0x6B, 0x32, 0x00, 0x00, 0x58, 0xC1, 0x94, 0x01, + 0x58, 0x81, 0x84, 0x01, 0x2C, 0x10, 0xA4, 0x01, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0xA4, 0x01, + 0x06, 0x21, 0x04, 0x30, 0x0C, 0x40, 0x69, 0x01, 0xD9, 0x81, 0x84, 0x01, 0xD9, 0xC1, 0x94, 0x01, + 0xAB, 0xE5, 0x04, 0x00, 0x0C, 0x70, 0x15, 0x00, 0xB9, 0x71, 0x70, 0x01, 0x08, 0x90, 0x00, 0x30, + 0x0C, 0x70, 0x00, 0x49, 0x26, 0x79, 0x08, 0xA0, 0xFF, 0xC0, 0xB9, 0x71, 0x74, 0x01, 0x2C, 0xA0, + 0xFF, 0xFF, 0xCB, 0x3B, 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x04, 0xB0, 0x4B, 0x3A, + 0x00, 0x00, 0x06, 0xDB, 0x8B, 0x37, 0x00, 0x00, 0x06, 0xE1, 0x04, 0xC0, 0x2F, 0x7C, 0x0E, 0x00, + 0x90, 0x87, 0x9A, 0x7F, 0x00, 0x00, 0x0C, 0x40, 0x6C, 0x01, 0x06, 0x2B, 0x06, 0x3C, 0x26, 0x41, + 0x4B, 0x9E, 0x00, 0x00, 0xC4, 0x20, 0x82, 0x75, 0x38, 0x61, 0x6C, 0x01, 0x0C, 0x30, 0x18, 0x00, + 0x06, 0x26, 0xB9, 0x61, 0x78, 0x01, 0x4B, 0x18, 0x00, 0x00, 0xC4, 0x2E, 0x38, 0x61, 0x78, 0x01, + 0xD2, 0x68, 0x38, 0x71, 0x74, 0x01, 0x06, 0xF6, 0x57, 0xF1, 0x26, 0x7F, 0x30, 0x37, 0x1C, 0x20, + 0xAC, 0x0D, 0x5C, 0x30, 0xFF, 0x0F, 0x26, 0x23, 0xC3, 0x22, 0x02, 0x2A, 0x0C, 0x50, 0x00, 0x40, + 0x26, 0x59, 0x26, 0x5F, 0x30, 0x45, 0x08, 0x70, 0x00, 0x3F, 0x56, 0x74, 0x77, 0x7C, 0xC4, 0x70, + 0x82, 0x1F, 0x34, 0x71, 0x1C, 0x30, 0x90, 0x01, 0xB9, 0x41, 0x78, 0x01, 0xB9, 0x51, 0x80, 0x01, + 0xB9, 0x71, 0x7C, 0x01, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x71, 0x7C, 0x01, 0x06, 0x38, 0x26, 0x27, + 0x43, 0x22, 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0x38, 0x41, 0x78, 0x01, 0x38, 0x51, 0x80, 0x01, + 0x5C, 0x20, 0x3F, 0x00, 0x57, 0x2C, 0x56, 0x4A, 0x66, 0x24, 0xB1, 0x25, 0xF2, 0x2C, 0x0C, 0x20, + 0xF4, 0x01, 0x36, 0x23, 0xC4, 0x20, 0x02, 0x2A, 0x0C, 0x80, 0x00, 0x40, 0x26, 0x89, 0x26, 0x8F, + 0x30, 0x58, 0x08, 0x70, 0x00, 0x3F, 0x56, 0x75, 0x77, 0x7C, 0xCC, 0x70, 0x3F, 0x00, 0x82, 0x1E, + 0x24, 0x71, 0x0C, 0x30, 0x90, 0x01, 0xB9, 0x51, 0x80, 0x01, 0xB9, 0x71, 0x7C, 0x01, 0x8B, 0x16, + 0x00, 0x00, 0x38, 0x71, 0x7C, 0x01, 0x0C, 0x30, 0x3F, 0x00, 0x26, 0x27, 0x43, 0x22, 0x0C, 0xF0, + 0x98, 0x00, 0xF1, 0xF0, 0x38, 0x51, 0x80, 0x01, 0x5C, 0x20, 0x3F, 0x00, 0x57, 0x2C, 0x56, 0x5A, + 0x66, 0x25, 0xB1, 0x28, 0x24, 0xD1, 0x23, 0xDD, 0xF2, 0x04, 0x26, 0x61, 0x04, 0x71, 0x91, 0x76, + 0x24, 0xC1, 0xCC, 0xC0, 0x18, 0x00, 0x9A, 0x7B, 0xFF, 0xFF, 0x24, 0xB1, 0xC4, 0xBE, 0x2C, 0xE0, + 0x18, 0x00, 0x9A, 0x74, 0xFF, 0xFF, 0xC4, 0xD0, 0x82, 0x09, 0x38, 0x71, 0x70, 0x01, 0x34, 0x71, + 0xA3, 0x77, 0xB9, 0x71, 0x70, 0x01, 0x9A, 0x5E, 0xFF, 0xFF, 0x58, 0xC1, 0x94, 0x01, 0x58, 0x81, + 0x84, 0x01, 0x2C, 0x10, 0xA4, 0x01, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x30, 0x38, 0x76, 0x28, 0x00, + 0xD4, 0x74, 0x92, 0xFD, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0x00, 0x30, 0x38, 0x76, 0x40, 0x01, + 0x23, 0x77, 0xB9, 0x76, 0x40, 0x01, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x30, 0x38, 0x27, 0x28, 0x00, + 0x54, 0x22, 0xE1, 0xF0, 0x04, 0x62, 0x08, 0x70, 0x00, 0x30, 0xB9, 0x67, 0x28, 0x00, 0xE1, 0xF0, + 0x08, 0x70, 0x00, 0x30, 0x38, 0x27, 0x40, 0x01, 0xF7, 0x2F, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x8B, 0xBB, 0x00, 0x00, 0x04, 0x70, 0xC6, 0x27, 0x82, 0x0D, 0xCB, 0xB9, 0x00, 0x00, 0x08, 0x70, + 0x00, 0x30, 0x08, 0x60, 0x00, 0x80, 0xB9, 0x67, 0x40, 0x01, 0x38, 0x77, 0x3C, 0x01, 0xB9, 0x70, + 0x68, 0x19, 0x30, 0xF1, 0x06, 0x27, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x06, 0x72, 0x77, 0x78, + 0xCC, 0x70, 0x15, 0x00, 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0xB1, 0xB1, 0x0C, 0xE0, + 0xFF, 0xFF, 0x56, 0xE2, 0x82, 0x52, 0xCC, 0x70, 0x15, 0x00, 0xD2, 0x1B, 0xCC, 0x70, 0x10, 0x00, + 0x82, 0x3C, 0xCC, 0x70, 0x10, 0x00, 0xD2, 0x08, 0xC4, 0x71, 0x82, 0x33, 0xC4, 0x72, 0x92, 0x55, + 0x99, 0xE0, 0xA9, 0x1B, 0xF2, 0x77, 0xCC, 0x70, 0x13, 0x00, 0x82, 0x33, 0xCC, 0x70, 0x13, 0x00, + 0xD2, 0x34, 0xCC, 0x70, 0x12, 0x00, 0x92, 0x49, 0x99, 0xE0, 0x9F, 0x1B, 0xFA, 0xA8, 0x00, 0x00, + 0xCC, 0x70, 0x23, 0x00, 0x82, 0x39, 0xCC, 0x70, 0x23, 0x00, 0xD2, 0x0E, 0xCC, 0x70, 0x21, 0x00, + 0x82, 0x28, 0xCC, 0x70, 0x21, 0x00, 0xD2, 0x2D, 0xCC, 0x70, 0x20, 0x00, 0x92, 0x36, 0xA9, 0xE0, + 0x82, 0x1B, 0xFA, 0xA3, 0x00, 0x00, 0xCC, 0x70, 0x81, 0x00, 0x82, 0x29, 0xCC, 0x70, 0xE0, 0x00, + 0x82, 0x29, 0xCC, 0x70, 0x80, 0x00, 0x92, 0x29, 0x99, 0xE0, 0xA1, 0x1B, 0xFA, 0x8E, 0x00, 0x00, + 0x99, 0x70, 0xAA, 0x1B, 0xFA, 0x92, 0x00, 0x00, 0x99, 0xE0, 0xA8, 0x1B, 0xFA, 0x8E, 0x00, 0x00, + 0x99, 0xE0, 0xA6, 0x1B, 0xFA, 0x8A, 0x00, 0x00, 0x99, 0xE0, 0xA5, 0x1B, 0xFA, 0x86, 0x00, 0x00, + 0xA9, 0xE0, 0x84, 0x1B, 0xFA, 0x82, 0x00, 0x00, 0x99, 0xE0, 0xA4, 0x1B, 0xFA, 0x7E, 0x00, 0x00, + 0xA9, 0xE0, 0x80, 0x1B, 0xF2, 0x78, 0xA9, 0xE0, 0x7E, 0x1B, 0xF2, 0x77, 0x99, 0xE0, 0xA2, 0x1B, + 0xF2, 0x74, 0x99, 0xE0, 0xA0, 0x1B, 0xF2, 0x71, 0xCC, 0x70, 0x30, 0x00, 0x82, 0x43, 0xCC, 0x70, + 0x30, 0x00, 0xD2, 0x0A, 0xCC, 0x70, 0x12, 0x00, 0x82, 0x5A, 0xCC, 0x70, 0x22, 0x00, 0x82, 0x63, + 0xC4, 0x72, 0x92, 0x63, 0xF2, 0x17, 0xCC, 0x70, 0x80, 0x00, 0x82, 0x57, 0xCC, 0x70, 0x80, 0x00, + 0xD2, 0x07, 0xCC, 0x70, 0x33, 0x00, 0x92, 0x59, 0x8B, 0x91, 0x00, 0x00, 0xF2, 0x56, 0xCC, 0x70, + 0x90, 0x00, 0x82, 0x4E, 0xCC, 0x70, 0xE1, 0x00, 0x92, 0x50, 0x13, 0x2E, 0xAB, 0x90, 0x01, 0x00, + 0xF2, 0x4C, 0xCB, 0x5B, 0x00, 0x00, 0xC4, 0xE0, 0x82, 0x0E, 0x08, 0x50, 0x00, 0x40, 0x38, 0x75, + 0x54, 0x10, 0x08, 0x40, 0x00, 0x80, 0x66, 0x74, 0xB9, 0x70, 0x64, 0x19, 0x14, 0x71, 0xB9, 0x75, + 0x54, 0x10, 0xF2, 0x3B, 0xB8, 0x50, 0x64, 0x19, 0x32, 0x0A, 0x08, 0x70, 0xFF, 0x7F, 0x2C, 0x70, + 0xFF, 0xFF, 0x56, 0x75, 0x08, 0x50, 0x00, 0x40, 0xB9, 0x75, 0x54, 0x10, 0xB9, 0x00, 0x64, 0x19, + 0xF2, 0x2C, 0x04, 0x20, 0x4B, 0x6B, 0x00, 0x00, 0x0C, 0xB0, 0x40, 0x01, 0x08, 0xE0, 0x00, 0x30, + 0x08, 0xD0, 0x30, 0x00, 0x06, 0xCE, 0x26, 0xBE, 0x24, 0xD1, 0x08, 0x60, 0x00, 0x80, 0xB8, 0x7E, + 0x40, 0x01, 0x32, 0xFE, 0x38, 0x7E, 0x28, 0x00, 0xD4, 0x74, 0x92, 0xFD, 0xB1, 0x6B, 0x38, 0x7C, + 0x3C, 0x01, 0xC6, 0x7D, 0x92, 0xF5, 0x04, 0x74, 0xF1, 0x70, 0xF2, 0xF0, 0x98, 0x70, 0x9F, 0x1B, + 0x82, 0x0C, 0x6B, 0xDB, 0x04, 0x00, 0xF2, 0x09, 0x6B, 0x13, 0x01, 0x00, 0xF2, 0x06, 0xEB, 0x6A, + 0x00, 0x00, 0xF2, 0x03, 0xAB, 0x11, 0x01, 0x00, 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, + 0x14, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0xE0, 0x00, 0x30, 0x0C, 0xD0, + 0x00, 0x01, 0x26, 0xDE, 0xCB, 0xB9, 0x00, 0x00, 0x06, 0x2D, 0x04, 0x30, 0x0C, 0x40, 0x10, 0x00, + 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x38, 0x7E, 0x28, 0x00, 0xD4, 0x72, 0x82, 0x05, 0x04, 0x72, + 0xB9, 0x7E, 0x28, 0x00, 0xF2, 0xF0, 0x38, 0x7E, 0x40, 0x01, 0xB9, 0x7E, 0x40, 0x01, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0x0C, 0x20, 0x00, 0x00, 0x04, 0x30, + 0x0C, 0x40, 0x20, 0x00, 0xC1, 0xE1, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x06, 0x2E, 0x0C, 0x20, + 0x00, 0x27, 0x04, 0x30, 0x0C, 0x40, 0x20, 0x00, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x08, 0x70, + 0x00, 0x80, 0x2C, 0x70, 0x00, 0xFA, 0x38, 0x67, 0xF8, 0x01, 0xB9, 0x60, 0x00, 0x00, 0x38, 0x67, + 0xFC, 0x01, 0xB9, 0x60, 0x04, 0x00, 0x08, 0x60, 0x00, 0x80, 0x38, 0x66, 0x04, 0xDC, 0xB9, 0x60, + 0x08, 0x00, 0x38, 0x67, 0xF0, 0x01, 0xB9, 0x60, 0x0C, 0x00, 0x38, 0x67, 0xF4, 0x01, 0x38, 0x77, + 0xCC, 0x01, 0xC4, 0x60, 0xB9, 0x70, 0x1C, 0x00, 0x08, 0x70, 0x35, 0x45, 0x2C, 0x70, 0x01, 0x32, + 0xB9, 0x70, 0x24, 0x00, 0x08, 0x70, 0x01, 0xC6, 0x2C, 0x70, 0x01, 0x45, 0xB9, 0x60, 0x10, 0x00, + 0xB9, 0x70, 0x28, 0x00, 0x82, 0x04, 0x08, 0x70, 0x02, 0x64, 0xF2, 0x03, 0x08, 0x70, 0x02, 0x07, + 0xB9, 0x70, 0x2C, 0x00, 0x04, 0x71, 0xB9, 0x70, 0x34, 0x00, 0x08, 0x70, 0x80, 0x07, 0x2C, 0x70, + 0x38, 0x04, 0xB9, 0x70, 0x40, 0x00, 0x08, 0x70, 0x18, 0x00, 0x24, 0x7E, 0xB9, 0x70, 0x44, 0x00, + 0x08, 0x70, 0x03, 0x01, 0x2C, 0x70, 0x02, 0x17, 0xB9, 0x70, 0x48, 0x00, 0x08, 0x70, 0x06, 0x17, + 0x2C, 0x70, 0x0B, 0x17, 0xB9, 0x70, 0x4C, 0x00, 0x08, 0x70, 0xFF, 0xFF, 0xB9, 0x70, 0x50, 0x00, + 0x08, 0x70, 0x17, 0x00, 0x24, 0x7E, 0xB9, 0x70, 0x54, 0x00, 0x08, 0x60, 0x00, 0x80, 0x08, 0x70, + 0xFF, 0x00, 0x2C, 0x60, 0x0C, 0xDC, 0x2C, 0x70, 0x00, 0xFF, 0xB9, 0x70, 0x58, 0x00, 0x18, 0x76, + 0x2D, 0x00, 0xB9, 0x00, 0x30, 0x00, 0x0C, 0xE0, 0x00, 0x27, 0xB9, 0x70, 0x5C, 0x00, 0x18, 0x76, + 0x2C, 0x00, 0xB9, 0xE0, 0x70, 0x00, 0xB9, 0x70, 0x60, 0x00, 0x28, 0x76, 0x1E, 0x00, 0x28, 0x66, + 0x1C, 0x00, 0x57, 0x78, 0x66, 0x76, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x44, 0xDF, 0xB9, 0x70, + 0x64, 0x00, 0x28, 0x76, 0x32, 0x00, 0x28, 0x66, 0x2C, 0x00, 0x57, 0x78, 0x66, 0x76, 0xB9, 0x70, + 0x68, 0x00, 0x0C, 0x60, 0x00, 0x49, 0x08, 0x70, 0x00, 0x30, 0x26, 0x67, 0x2C, 0x70, 0x00, 0xA0, + 0xB9, 0x70, 0x6C, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0xB9, 0x70, 0x78, 0x00, 0xB9, 0x60, 0x74, 0x00, + 0x0C, 0x70, 0xE8, 0x19, 0x08, 0x60, 0x00, 0x80, 0x66, 0x76, 0xB9, 0x70, 0x38, 0x00, 0x04, 0x72, + 0xB9, 0x70, 0x18, 0x00, 0xAB, 0xCB, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x7E, 0x74, 0x0C, 0x06, 0x43, + 0x04, 0x30, 0xC6, 0x73, 0x06, 0xD2, 0x82, 0x1B, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x38, 0x7E, + 0x3C, 0x0C, 0x0C, 0x50, 0x74, 0x0C, 0xB1, 0x7D, 0x0C, 0x70, 0x3C, 0x17, 0x26, 0x5E, 0x04, 0x61, + 0xB0, 0x37, 0x82, 0x06, 0x06, 0x46, 0x57, 0x41, 0x26, 0x4D, 0xB1, 0x34, 0x24, 0x61, 0x24, 0x74, + 0xC6, 0x75, 0x92, 0xF7, 0x18, 0x3E, 0x74, 0x0C, 0x99, 0x0E, 0x74, 0x0C, 0x50, 0xC1, 0x06, 0x23, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x70, 0x06, 0x67, 0x3F, 0x57, 0x03, 0x00, + 0xC4, 0x50, 0x02, 0x08, 0x2F, 0x57, 0x02, 0x00, 0x10, 0x55, 0x24, 0x71, 0x26, 0x65, 0x13, 0x66, + 0xF2, 0xF6, 0x06, 0x26, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x30, 0xE2, + 0x08, 0x70, 0xFF, 0x00, 0x2C, 0x70, 0xFF, 0xFF, 0x56, 0xE7, 0x6C, 0xE0, 0x00, 0x0C, 0xB1, 0xE2, + 0x57, 0x31, 0x06, 0xD2, 0xCB, 0xDB, 0x00, 0x00, 0x57, 0x2C, 0x66, 0x2E, 0xB1, 0x2D, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x50, 0x00, 0xD9, 0xC1, 0x40, 0x00, + 0x4B, 0xE5, 0x00, 0x00, 0x06, 0x21, 0x0C, 0x30, 0x10, 0x00, 0x0B, 0xD9, 0x00, 0x00, 0x86, 0xE2, + 0x82, 0x25, 0x06, 0x21, 0x06, 0x3E, 0xCB, 0xDC, 0x00, 0x00, 0x98, 0x70, 0xA3, 0x1B, 0x82, 0x07, + 0x6B, 0xE5, 0x00, 0x00, 0x06, 0x7E, 0x57, 0x71, 0x26, 0x71, 0xB1, 0x27, 0x08, 0xD0, 0x00, 0x30, + 0x0C, 0xC0, 0x04, 0x01, 0x26, 0xCD, 0xCB, 0xB9, 0x00, 0x00, 0x06, 0x2C, 0x06, 0x31, 0x04, 0x4B, + 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x38, 0x7D, 0x28, 0x00, 0xD4, 0x72, 0x82, 0x05, 0x04, 0x72, + 0xB9, 0x7D, 0x28, 0x00, 0xF2, 0xF1, 0x4B, 0xBA, 0x00, 0x00, 0x18, 0x70, 0xBB, 0x1B, 0xC4, 0x71, + 0x92, 0x11, 0x2B, 0xA8, 0x01, 0x00, 0x98, 0x70, 0xB6, 0x1B, 0x82, 0x05, 0xC4, 0x71, 0x92, 0x0A, + 0xC4, 0xE0, 0x92, 0x08, 0x08, 0x60, 0xDB, 0xDB, 0x08, 0x70, 0x00, 0x30, 0xB9, 0x67, 0x04, 0x01, + 0x04, 0xE1, 0x18, 0x60, 0xA0, 0x1B, 0xC4, 0x62, 0x92, 0x12, 0x04, 0x61, 0x99, 0x60, 0xA0, 0x1B, + 0x18, 0x70, 0xB6, 0x1B, 0x04, 0x21, 0xC4, 0x70, 0x92, 0x0B, 0x08, 0x70, 0xA0, 0x8C, 0x2C, 0x70, + 0x0E, 0xD0, 0x08, 0x60, 0x00, 0x30, 0xB9, 0x76, 0x04, 0x01, 0xF2, 0x02, 0x06, 0x2E, 0x58, 0xC1, + 0x40, 0x00, 0x2C, 0x10, 0x50, 0x00, 0xE1, 0xF0, 0x0C, 0x50, 0x00, 0x00, 0x0C, 0x70, 0x78, 0x00, + 0x34, 0x54, 0x04, 0x60, 0x30, 0x47, 0x34, 0x74, 0xC6, 0x75, 0x26, 0x64, 0x92, 0xFC, 0xB9, 0x60, + 0x7C, 0x00, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x0C, 0x70, 0xFC, 0x0A, 0x38, 0x27, 0x3C, 0x0C, 0x08, 0x60, 0xE0, 0x00, 0xD6, 0x26, 0x92, 0x17, + 0xA8, 0x77, 0x14, 0x03, 0x82, 0x34, 0xCC, 0x70, 0xFF, 0x0F, 0x82, 0x31, 0x26, 0x77, 0x06, 0x27, + 0x57, 0x22, 0x36, 0x27, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x2C, 0x20, 0x90, 0x01, + 0xCC, 0x20, 0x58, 0x02, 0xC2, 0x24, 0x0C, 0x20, 0x58, 0x02, 0xF2, 0x21, 0x28, 0x27, 0x18, 0x03, + 0x1C, 0x70, 0xA5, 0x01, 0x26, 0x72, 0xCC, 0x70, 0xE8, 0x03, 0xD2, 0x0F, 0x3C, 0x20, 0x8D, 0x05, + 0x06, 0x32, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0xE9, 0x03, 0xAB, 0x15, 0x00, 0x00, 0x0C, 0x70, + 0x8D, 0x05, 0x3F, 0x22, 0x07, 0x00, 0xF2, 0x0B, 0xCC, 0x20, 0x8D, 0x05, 0xC2, 0x08, 0x3C, 0x20, + 0x8D, 0x05, 0x04, 0x33, 0xAB, 0x15, 0x00, 0x00, 0x2C, 0x20, 0x8D, 0x05, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x01, 0x00, 0x34, 0x14, 0x2C, 0x70, 0xF8, 0x24, 0xB1, 0x71, + 0x30, 0x71, 0x14, 0x61, 0xC4, 0x70, 0x26, 0x67, 0xB1, 0x61, 0x92, 0xFB, 0x24, 0x14, 0xE1, 0xF0, + 0x06, 0x72, 0x57, 0x71, 0x26, 0x27, 0x34, 0x14, 0xF7, 0x20, 0xB1, 0x21, 0x30, 0x71, 0x14, 0x61, + 0xC4, 0x70, 0x26, 0x67, 0xB1, 0x61, 0x92, 0xFB, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x04, 0x3A, + 0xB1, 0xF1, 0xAB, 0x15, 0x00, 0x00, 0x23, 0x32, 0x04, 0x21, 0xCB, 0x78, 0x00, 0x00, 0x04, 0x21, + 0x4B, 0x77, 0x00, 0x00, 0x04, 0x24, 0x04, 0x30, 0xCB, 0x5E, 0x00, 0x00, 0xCB, 0x5A, 0x00, 0x00, + 0x04, 0x24, 0x04, 0x31, 0xCB, 0x5E, 0x00, 0x00, 0x04, 0x21, 0x0B, 0x78, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x6B, 0xEB, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x06, 0x72, 0x06, 0x62, 0xD7, 0x63, 0x57, 0x71, 0x3F, 0x77, 0x06, 0x00, + 0x26, 0x27, 0x34, 0x14, 0xD7, 0x21, 0xB1, 0xF1, 0x6B, 0xEB, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x20, 0xB1, 0xF1, 0x6B, 0x5C, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x2C, 0x60, 0x80, 0x00, + 0x2C, 0x70, 0x1C, 0x02, 0x36, 0x76, 0xC4, 0x70, 0x34, 0x14, 0xB1, 0xF1, 0x32, 0x02, 0x24, 0x73, + 0x06, 0x47, 0x08, 0x50, 0x00, 0x80, 0x67, 0x41, 0x04, 0x70, 0x2C, 0x50, 0xAC, 0x9E, 0x14, 0x21, + 0xC6, 0x74, 0x04, 0x34, 0x26, 0x36, 0x32, 0x05, 0x30, 0xF5, 0x24, 0x54, 0xB1, 0xF6, 0xF2, 0x02, + 0xB1, 0x26, 0x24, 0x71, 0xCC, 0x70, 0x80, 0x00, 0x82, 0x03, 0x06, 0x63, 0xF2, 0xF2, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x28, 0x60, 0x82, 0x1B, 0xCC, 0x60, 0xFF, 0xFF, 0x92, 0x10, 0x38, 0x60, + 0x08, 0x0B, 0xD4, 0x61, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x0C, 0xDC, 0x82, 0x04, 0x38, 0x66, + 0x40, 0x00, 0xF2, 0x03, 0x38, 0x66, 0x3C, 0x00, 0xA9, 0x60, 0x82, 0x1B, 0x28, 0x60, 0x84, 0x1B, + 0xCC, 0x60, 0xFF, 0xFF, 0x92, 0x07, 0x08, 0x60, 0x00, 0x80, 0x38, 0x66, 0x44, 0xDC, 0xA9, 0x60, + 0x84, 0x1B, 0xE1, 0xF0, 0x08, 0x40, 0x00, 0x80, 0x34, 0x14, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x40, + 0x0C, 0xDC, 0xB1, 0xF1, 0x2C, 0x70, 0x1A, 0xDC, 0x0C, 0x60, 0x7A, 0x1A, 0x24, 0x4A, 0x14, 0x21, + 0x10, 0x57, 0xCC, 0x50, 0xFF, 0x00, 0x82, 0x0D, 0x18, 0x37, 0x04, 0x00, 0xCC, 0x30, 0xFF, 0x00, + 0x82, 0x08, 0x2F, 0xF5, 0x05, 0x00, 0x26, 0x5F, 0xD7, 0x51, 0x26, 0x53, 0xA1, 0x56, 0xF2, 0x02, + 0xA1, 0x26, 0x34, 0x71, 0xC6, 0x74, 0x34, 0x62, 0x92, 0xEC, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x34, 0x14, 0x0C, 0x20, 0xFC, 0x0A, 0x04, 0x30, 0x0C, 0x40, 0xC4, 0x0C, 0xB1, 0xF1, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0xAB, 0xF3, 0x00, 0x00, 0x2B, 0xF8, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x0C, 0x60, 0xF4, 0x01, 0xB9, 0x60, 0x80, 0x19, 0x99, 0x00, 0xB6, 0x1B, + 0x14, 0x61, 0x99, 0x60, 0xB5, 0x1B, 0xA9, 0x00, 0x86, 0x1B, 0xB9, 0x00, 0x7C, 0x19, 0xB9, 0x00, + 0x78, 0x19, 0x99, 0x00, 0xB4, 0x1B, 0xB9, 0x00, 0x74, 0x19, 0xB9, 0x00, 0x70, 0x19, 0x99, 0x00, + 0xB3, 0x1B, 0x04, 0x63, 0x99, 0x60, 0xB2, 0x1B, 0x99, 0x00, 0xAA, 0x1B, 0x99, 0x00, 0xA9, 0x1B, + 0x04, 0x71, 0x99, 0x70, 0xA8, 0x1B, 0x99, 0x00, 0xA7, 0x1B, 0x99, 0x70, 0xA6, 0x1B, 0x99, 0x00, + 0xA5, 0x1B, 0x14, 0x61, 0xA9, 0x60, 0x84, 0x1B, 0xA9, 0x60, 0x82, 0x1B, 0x08, 0x60, 0x00, 0x80, + 0x2C, 0x60, 0x00, 0xDC, 0x18, 0x46, 0x09, 0x00, 0x99, 0x40, 0xA4, 0x1B, 0x18, 0x56, 0x08, 0x00, + 0xA9, 0x50, 0x80, 0x1B, 0xA9, 0x00, 0x7E, 0x1B, 0x99, 0x00, 0xA3, 0x1B, 0x99, 0x00, 0xA2, 0x1B, + 0x99, 0x00, 0xA1, 0x1B, 0x0C, 0x50, 0xFC, 0x0A, 0xB9, 0x00, 0x6C, 0x19, 0x99, 0x70, 0xB0, 0x1B, + 0x38, 0x65, 0x0C, 0x00, 0x64, 0x64, 0xB9, 0x65, 0x0C, 0x00, 0x99, 0x00, 0xAF, 0x1B, 0x08, 0x60, + 0x00, 0x80, 0x18, 0x56, 0x79, 0xDC, 0x99, 0x50, 0xAE, 0x1B, 0x99, 0x00, 0xAD, 0x1B, 0x99, 0x70, + 0xBA, 0x1B, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0x40, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x2B, 0x5D, 0x00, 0x00, 0x04, 0x20, 0x2B, 0x6A, + 0x00, 0x00, 0xAB, 0xAC, 0x01, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x77, 0x10, 0x20, 0x30, 0xF1, + 0xF7, 0x70, 0xB9, 0x70, 0x20, 0x00, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, + 0x11, 0x00, 0xB1, 0xF1, 0x8B, 0x34, 0x00, 0x00, 0x04, 0x2B, 0x04, 0x31, 0xEB, 0x6B, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x21, 0xB1, 0xF1, 0xEB, 0x66, + 0x00, 0x00, 0x04, 0x24, 0xEB, 0x66, 0x00, 0x00, 0x0C, 0x20, 0x40, 0x00, 0xEB, 0x66, 0x00, 0x00, + 0x0C, 0x20, 0x10, 0x00, 0x6B, 0x66, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x14, 0xB1, 0xF1, 0x6B, 0x67, 0x00, 0x00, 0x04, 0x25, 0x04, 0x31, 0xEB, 0x6B, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, 0x00, 0x01, 0xB1, 0xF1, + 0x2B, 0x60, 0x00, 0x00, 0x0C, 0x20, 0x80, 0x00, 0x2B, 0x60, 0x00, 0x00, 0x04, 0x20, 0x06, 0x52, + 0x0C, 0x30, 0x27, 0x00, 0x0C, 0x40, 0xFF, 0xFF, 0x0C, 0x60, 0x01, 0x02, 0x8B, 0x75, 0x00, 0x00, + 0x04, 0x21, 0x0C, 0x30, 0x8F, 0x01, 0x0C, 0x40, 0xFF, 0xFF, 0x04, 0x50, 0x0C, 0x60, 0x01, 0x02, + 0x8B, 0x75, 0x00, 0x00, 0x04, 0x27, 0x04, 0x31, 0xEB, 0x6B, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x21, 0xB1, 0xF1, 0x4B, 0x6B, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0x60, 0x00, 0x40, 0x38, 0xE6, + 0x70, 0x60, 0x06, 0x72, 0x23, 0xEE, 0xCC, 0xE0, 0x00, 0xC9, 0x06, 0xC3, 0xC2, 0x05, 0x08, 0x60, + 0x04, 0x00, 0x66, 0xE6, 0xF7, 0xE1, 0x06, 0x37, 0x06, 0x2E, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, + 0xA0, 0x0F, 0xAB, 0x15, 0x00, 0x00, 0x24, 0x25, 0x04, 0x3A, 0xAB, 0x15, 0x00, 0x00, 0x08, 0x70, + 0x00, 0x40, 0x38, 0x77, 0xCC, 0x71, 0x06, 0xD2, 0x77, 0x7C, 0x24, 0x72, 0xC6, 0x27, 0xB2, 0x02, + 0x06, 0xD7, 0xC4, 0xC0, 0x82, 0x18, 0x06, 0x7E, 0xD7, 0x71, 0x2F, 0x2E, 0x0E, 0x00, 0x26, 0x27, + 0x06, 0x3D, 0xAB, 0x15, 0x00, 0x00, 0x3C, 0xE0, 0xB0, 0x9A, 0xCC, 0xE0, 0x20, 0x03, 0x04, 0x71, + 0xD2, 0x02, 0x04, 0x70, 0xD7, 0x7F, 0x66, 0x72, 0x0C, 0x60, 0x00, 0x00, 0xB9, 0x76, 0x3C, 0x00, + 0x4B, 0xE4, 0x00, 0x00, 0x06, 0x2D, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x38, 0x70, 0x70, 0x1A, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x38, 0xE7, 0x04, 0x00, 0x18, 0x27, + 0x05, 0x00, 0x04, 0x30, 0x0C, 0xC0, 0xFF, 0x00, 0x2B, 0x04, 0x01, 0x00, 0x56, 0xCE, 0x06, 0xD2, + 0x04, 0x30, 0x06, 0x2C, 0x2B, 0x04, 0x01, 0x00, 0x08, 0x70, 0xFF, 0xFF, 0x56, 0x7E, 0x57, 0xD4, + 0x66, 0x72, 0x66, 0x7D, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x6C, 0x72, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x38, 0x70, 0x70, 0x1A, 0x34, 0x14, 0xB1, 0xF1, 0x18, 0x27, 0x08, 0x00, + 0x04, 0x31, 0x2B, 0x04, 0x01, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x70, 0x8B, 0x08, + 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0x38, 0x57, 0x64, 0x71, + 0x38, 0x77, 0x9C, 0x60, 0x06, 0x65, 0xC4, 0x71, 0x77, 0x6A, 0x54, 0x6F, 0x02, 0x14, 0x34, 0x78, + 0x26, 0x76, 0xC4, 0x7C, 0x02, 0x02, 0x04, 0x7C, 0x86, 0x67, 0x32, 0x02, 0x04, 0x60, 0x08, 0x70, + 0x0F, 0xFF, 0x2C, 0x70, 0xFF, 0xFF, 0x56, 0x75, 0x57, 0x6A, 0x66, 0x67, 0x08, 0x70, 0x00, 0x40, + 0xB9, 0x67, 0x64, 0x71, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0x65, 0x00, 0x00, + 0x04, 0x31, 0x0C, 0x20, 0x20, 0x00, 0x4B, 0x64, 0x00, 0x00, 0x0C, 0x20, 0xFF, 0x00, 0x0B, 0x62, + 0x00, 0x00, 0x04, 0x31, 0x04, 0x24, 0xCB, 0x5E, 0x00, 0x00, 0x04, 0x21, 0xEB, 0x5A, 0x00, 0x00, + 0xCB, 0x0B, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xAA, 0x1B, + 0x82, 0x09, 0xC4, 0x20, 0x82, 0x05, 0x04, 0x61, 0x99, 0x60, 0xB8, 0x1B, 0xF2, 0x03, 0x99, 0x00, + 0xB8, 0x1B, 0xE1, 0xF0, 0xC4, 0x20, 0x34, 0x18, 0xC1, 0xE1, 0x82, 0x0A, 0x04, 0x21, 0x6B, 0xFD, + 0x03, 0x00, 0x18, 0x60, 0xB2, 0x1B, 0x1C, 0x70, 0x80, 0x00, 0x66, 0x76, 0xF2, 0x07, 0x6B, 0xFD, + 0x03, 0x00, 0x18, 0x70, 0xB2, 0x1B, 0x5C, 0x70, 0x7F, 0x00, 0x99, 0x70, 0xB2, 0x1B, 0x40, 0xE1, + 0x24, 0x18, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x80, 0x98, 0x77, 0x68, 0xDC, 0x34, 0x18, 0xC1, 0xE1, + 0x82, 0x04, 0x28, 0xE0, 0x80, 0x1B, 0xF2, 0x05, 0x08, 0x70, 0x00, 0x80, 0x18, 0xE7, 0x08, 0xDC, + 0x04, 0x21, 0x56, 0x2E, 0x2B, 0x10, 0x01, 0x00, 0x54, 0xE4, 0xA3, 0x2E, 0x82, 0x02, 0x04, 0x21, + 0x6B, 0x0F, 0x01, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x21, + 0xB1, 0xF1, 0x2B, 0x6A, 0x00, 0x00, 0x98, 0x70, 0xA1, 0x1B, 0x82, 0x27, 0x5C, 0x70, 0xF0, 0x00, + 0xCC, 0x70, 0x80, 0x00, 0x82, 0x08, 0xCC, 0x70, 0xC0, 0x00, 0x92, 0x1F, 0x04, 0x61, 0x99, 0x60, + 0xA3, 0x1B, 0xF2, 0x1B, 0x04, 0x71, 0x99, 0x70, 0xA3, 0x1B, 0x99, 0x70, 0xA5, 0x1B, 0x99, 0x00, + 0xA6, 0x1B, 0x08, 0x60, 0x00, 0x80, 0x98, 0x66, 0xA9, 0xDC, 0x92, 0x04, 0x99, 0x00, 0xA2, 0x1B, + 0xF2, 0x03, 0x99, 0x70, 0xA2, 0x1B, 0x04, 0x20, 0x6B, 0xFD, 0x03, 0x00, 0x18, 0x60, 0xB2, 0x1B, + 0x5C, 0x60, 0x7F, 0x00, 0x99, 0x60, 0xB2, 0x1B, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x98, 0x70, 0xB8, 0x1B, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x8A, 0xDD, 0x00, 0x00, 0xB8, 0xD0, + 0x8C, 0x19, 0x9A, 0x1D, 0x01, 0x00, 0x14, 0x61, 0x99, 0x00, 0xB6, 0x1B, 0x99, 0x60, 0xB5, 0x1B, + 0xA9, 0x00, 0x86, 0x1B, 0xB9, 0x00, 0x7C, 0x19, 0xB9, 0x00, 0x78, 0x19, 0x99, 0x00, 0xB4, 0x1B, + 0xB9, 0x00, 0x74, 0x19, 0xB9, 0x00, 0x70, 0x19, 0x99, 0x00, 0xB3, 0x1B, 0x0B, 0x31, 0x00, 0x00, + 0x6B, 0x32, 0x00, 0x00, 0xCB, 0x31, 0x00, 0x00, 0xAB, 0x40, 0x00, 0x00, 0x08, 0xC0, 0x00, 0x30, + 0x0C, 0x20, 0x00, 0x40, 0x06, 0x3D, 0x0C, 0x40, 0x40, 0x02, 0x26, 0x2C, 0x0C, 0xF0, 0xD8, 0x01, + 0xF1, 0xF0, 0x18, 0x20, 0xB2, 0x1B, 0x5C, 0x20, 0xF0, 0x00, 0x64, 0x23, 0x99, 0x20, 0xB2, 0x1B, + 0x6B, 0x44, 0x00, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0xEB, 0x4E, 0x00, 0x00, 0x08, 0x60, 0x00, 0x8E, + 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x80, 0x0F, 0xB9, 0x67, 0x6C, 0x70, 0x08, 0x60, 0x20, 0x00, + 0x2C, 0x60, 0x40, 0x26, 0xB9, 0x67, 0xEC, 0x71, 0x08, 0x60, 0x0E, 0x18, 0x2C, 0x60, 0x0E, 0x18, + 0xB9, 0x67, 0x0C, 0x70, 0x08, 0x60, 0xA8, 0x00, 0x2C, 0x60, 0x04, 0x62, 0xB9, 0x67, 0x64, 0x71, + 0x0C, 0x60, 0xFF, 0x3F, 0xB9, 0x67, 0x58, 0x70, 0x04, 0x68, 0xB9, 0x67, 0x2C, 0x70, 0x0C, 0x60, + 0x40, 0x03, 0xB9, 0x67, 0x28, 0x71, 0x0C, 0x50, 0x40, 0x82, 0x08, 0x60, 0x01, 0x00, 0x26, 0x56, + 0xB9, 0x57, 0xAC, 0x70, 0xB9, 0x07, 0xB0, 0x70, 0x08, 0x50, 0x08, 0x00, 0xB9, 0x57, 0xB4, 0x70, + 0x08, 0x50, 0x88, 0x00, 0xB9, 0x07, 0xB8, 0x70, 0x2C, 0x50, 0x00, 0x10, 0xB9, 0x57, 0xC0, 0x70, + 0x08, 0x50, 0x10, 0x1F, 0x2C, 0x50, 0x10, 0x1F, 0xB9, 0x57, 0xC4, 0x70, 0x0C, 0x50, 0x80, 0x00, + 0xB9, 0x57, 0xC8, 0x70, 0x08, 0x50, 0x02, 0x01, 0xB9, 0x57, 0xCC, 0x70, 0x04, 0x51, 0xB9, 0x57, + 0xD4, 0x70, 0x08, 0x50, 0x01, 0x80, 0xB9, 0x57, 0x8C, 0x70, 0x0C, 0x50, 0x20, 0x00, 0x26, 0x56, + 0xB9, 0x57, 0x90, 0x70, 0xB9, 0x07, 0x94, 0x70, 0xB9, 0x07, 0x98, 0x70, 0xB9, 0x67, 0x9C, 0x70, + 0xB9, 0x57, 0xA0, 0x70, 0xB9, 0x07, 0xA4, 0x70, 0xB9, 0x07, 0xA8, 0x70, 0x0C, 0x70, 0x00, 0x40, + 0x08, 0x30, 0xFF, 0x00, 0x26, 0x7C, 0x0C, 0x40, 0xC0, 0x17, 0x2C, 0x30, 0xFF, 0xFF, 0x2C, 0xC0, + 0x40, 0x45, 0x30, 0x57, 0x56, 0x53, 0xB1, 0x57, 0x10, 0x64, 0x24, 0x41, 0x57, 0x6C, 0x66, 0x65, + 0xB1, 0x67, 0x24, 0x74, 0xC6, 0x7C, 0x92, 0xF6, 0x4B, 0x2F, 0x00, 0x00, 0x04, 0xC5, 0xAB, 0x3C, + 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, + 0xB4, 0xC1, 0x92, 0xF8, 0x6B, 0xAD, 0x00, 0x00, 0xEB, 0xAF, 0x01, 0x00, 0x0B, 0x31, 0x00, 0x00, + 0x2B, 0x3D, 0x00, 0x00, 0x38, 0x70, 0x08, 0x0B, 0xD4, 0x71, 0x18, 0x70, 0xB2, 0x1B, 0x82, 0x07, + 0x5C, 0x70, 0x70, 0x00, 0x1C, 0x60, 0x7F, 0x00, 0x66, 0x76, 0xF2, 0x05, 0x1C, 0x60, 0x10, 0x00, + 0x56, 0x76, 0x64, 0x71, 0x99, 0x70, 0xB2, 0x1B, 0x6B, 0x32, 0x00, 0x00, 0x04, 0x71, 0xB9, 0x70, + 0x8C, 0x19, 0xF2, 0x45, 0xB8, 0x70, 0x8C, 0x19, 0x82, 0x42, 0x99, 0x00, 0xB6, 0x1B, 0x14, 0x61, + 0x99, 0x60, 0xB5, 0x1B, 0xA9, 0x00, 0x86, 0x1B, 0xB9, 0x00, 0x7C, 0x19, 0xB9, 0x00, 0x78, 0x19, + 0x99, 0x00, 0xB4, 0x1B, 0xB9, 0x00, 0x74, 0x19, 0xB9, 0x00, 0x70, 0x19, 0x99, 0x00, 0xB3, 0x1B, + 0xCB, 0x31, 0x00, 0x00, 0xAB, 0x40, 0x00, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0x5C, 0x20, 0xF0, 0x00, + 0x64, 0x23, 0x99, 0x20, 0xB2, 0x1B, 0x6B, 0x44, 0x00, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0x04, 0xD5, + 0xEB, 0x4E, 0x00, 0x00, 0xAB, 0x3C, 0x00, 0x00, 0x4B, 0x2F, 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, + 0x00, 0x20, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0xB4, 0xD1, 0x92, 0xF8, 0xEB, 0xAF, + 0x01, 0x00, 0x0B, 0x31, 0x00, 0x00, 0x2B, 0x3D, 0x00, 0x00, 0x6B, 0x32, 0x00, 0x00, 0x98, 0x70, + 0x9F, 0x1B, 0xB9, 0x00, 0x8C, 0x19, 0x82, 0x03, 0x6B, 0xDB, 0x04, 0x00, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x08, 0x20, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x2C, 0x20, 0x80, 0x02, + 0x2C, 0x40, 0x5C, 0x04, 0x36, 0x42, 0x08, 0x30, 0x00, 0x80, 0x3C, 0x10, 0x10, 0x00, 0x2C, 0x30, + 0x48, 0xA0, 0x77, 0x41, 0xD1, 0xC1, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x08, 0x40, 0x00, 0x80, + 0x0C, 0x20, 0x90, 0x01, 0x04, 0x30, 0x2C, 0x40, 0x00, 0xF0, 0x0C, 0xF0, 0x04, 0x04, 0xF1, 0xF0, + 0xB9, 0x20, 0x14, 0x00, 0x08, 0x70, 0x00, 0x80, 0x38, 0xD7, 0xD0, 0xFB, 0x06, 0xE2, 0xCC, 0xD0, + 0xFF, 0x00, 0x82, 0x17, 0xC6, 0xD2, 0x82, 0x15, 0xCB, 0xB9, 0x00, 0x00, 0x08, 0x60, 0x1C, 0xE1, + 0x08, 0x70, 0x00, 0x30, 0x2C, 0x60, 0x01, 0xE9, 0xB9, 0x67, 0x04, 0x01, 0xB9, 0xD7, 0x08, 0x01, + 0xB9, 0xE7, 0x0C, 0x01, 0xEB, 0x6A, 0x00, 0x00, 0x04, 0x2A, 0xAB, 0xED, 0x00, 0x00, 0xF2, 0xFB, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x98, 0x60, 0xAE, 0x1B, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x82, 0x0F, 0x34, 0x61, 0x93, 0x66, 0x99, 0x60, 0xAE, 0x1B, 0x92, 0x67, 0x0C, 0x60, + 0xFC, 0x0A, 0x99, 0x00, 0xB0, 0x1B, 0x38, 0x76, 0x0C, 0x00, 0x14, 0x45, 0x56, 0x74, 0xF2, 0x5C, + 0xDC, 0x20, 0x80, 0x00, 0x08, 0xE0, 0x00, 0x80, 0x2C, 0xE0, 0x0C, 0xDC, 0x82, 0x04, 0x18, 0xDE, + 0x6F, 0x00, 0xF2, 0x03, 0x18, 0xDE, 0x6E, 0x00, 0x4B, 0x3F, 0x00, 0x00, 0xC6, 0x2D, 0xA2, 0x0A, + 0x38, 0x50, 0x78, 0x19, 0x18, 0x60, 0xAF, 0x1B, 0x34, 0x53, 0xC6, 0x65, 0xB2, 0x1A, 0x24, 0x61, + 0xF2, 0x16, 0x98, 0x60, 0xAF, 0x1B, 0x82, 0x15, 0x98, 0x50, 0xB6, 0x1B, 0x82, 0x04, 0xB8, 0x50, + 0x7C, 0x19, 0x92, 0x0F, 0x18, 0x5E, 0x70, 0x00, 0x36, 0xD5, 0xC6, 0x2D, 0xD2, 0x0A, 0x18, 0x40, + 0xAD, 0x1B, 0x28, 0x5E, 0x76, 0x00, 0xC6, 0x45, 0xD2, 0x04, 0x34, 0x61, 0x99, 0x60, 0xAF, 0x1B, + 0x98, 0x50, 0xB0, 0x1B, 0x18, 0x50, 0xAF, 0x1B, 0x92, 0x0E, 0x18, 0x7E, 0x71, 0x00, 0xC6, 0x57, + 0xA2, 0x18, 0x04, 0x71, 0x0C, 0x50, 0xFC, 0x0A, 0x99, 0x70, 0xB0, 0x1B, 0x38, 0x75, 0x0C, 0x00, + 0x64, 0x74, 0xF2, 0x0D, 0x18, 0x7E, 0x72, 0x00, 0xC6, 0x57, 0xD2, 0x0B, 0x0C, 0x50, 0xFC, 0x0A, + 0x38, 0x75, 0x0C, 0x00, 0x99, 0x00, 0xB0, 0x1B, 0x14, 0x45, 0x56, 0x74, 0xB9, 0x75, 0x0C, 0x00, + 0xB8, 0x70, 0x8C, 0x19, 0x82, 0x0B, 0x04, 0x71, 0x99, 0x70, 0xB0, 0x1B, 0x0C, 0x60, 0xFC, 0x0A, + 0x38, 0x76, 0x0C, 0x00, 0x64, 0x74, 0xB9, 0x76, 0x0C, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE2, 0x6B, 0x56, 0x00, 0x00, 0x06, 0x2E, + 0x0B, 0x51, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x14, 0x00, + 0xD9, 0xC1, 0x04, 0x00, 0xB1, 0xB1, 0x06, 0xD2, 0xCB, 0x31, 0x00, 0x00, 0x18, 0x20, 0xB2, 0x1B, + 0x5C, 0x20, 0xF0, 0x00, 0x64, 0x23, 0x99, 0x20, 0xB2, 0x1B, 0x6B, 0x44, 0x00, 0x00, 0x18, 0x20, + 0xB2, 0x1B, 0xEB, 0x4E, 0x00, 0x00, 0x4B, 0x2F, 0x00, 0x00, 0x04, 0x20, 0xAB, 0x39, 0x04, 0x00, + 0xAB, 0x3C, 0x00, 0x00, 0xC4, 0xD0, 0x92, 0x08, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x3A, + 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0xCB, 0x3B, 0x00, 0x00, 0x08, 0x70, 0x00, 0x80, 0x18, 0xB7, + 0x66, 0xDC, 0x04, 0xE0, 0xC6, 0xBE, 0x82, 0x16, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x3A, + 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0xC4, 0xD0, 0x92, 0x09, 0xB8, 0x70, 0x8C, 0x19, 0x92, 0x1B, + 0x0C, 0x20, 0xD0, 0x07, 0x6B, 0xEB, 0x00, 0x00, 0xF2, 0x16, 0x8B, 0xBB, 0x00, 0x00, 0xC4, 0x20, + 0x82, 0xF5, 0xEB, 0xAF, 0x01, 0x00, 0x0B, 0x31, 0x00, 0x00, 0x2B, 0x3D, 0x00, 0x00, 0x04, 0x61, + 0x99, 0x60, 0xB3, 0x1B, 0x6B, 0x32, 0x00, 0x00, 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, + 0x14, 0x00, 0xE1, 0xF0, 0x24, 0xE1, 0xF2, 0xD7, 0x34, 0x18, 0xC1, 0xE1, 0x08, 0x70, 0x00, 0x40, + 0x38, 0x77, 0x14, 0x10, 0xDC, 0x70, 0x00, 0x01, 0x92, 0x0F, 0x99, 0x00, 0x9D, 0x1B, 0xCB, 0x67, + 0x00, 0x00, 0x2B, 0x68, 0x00, 0x00, 0x18, 0x70, 0x9D, 0x1B, 0x93, 0x07, 0x92, 0x03, 0xCB, 0x5A, + 0x00, 0x00, 0xEB, 0x68, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x98, 0x70, 0xA3, 0x1B, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x92, 0x0A, 0x0C, 0x70, 0xFC, 0x0A, 0xA8, 0x67, + 0x10, 0x00, 0x82, 0x05, 0x34, 0x61, 0xA9, 0x67, 0x10, 0x00, 0xF2, 0x4C, 0x18, 0x70, 0xB6, 0x1B, + 0xC4, 0x71, 0x92, 0x07, 0x98, 0x60, 0xB5, 0x1B, 0x92, 0x04, 0xA9, 0x70, 0x0C, 0x0B, 0xF2, 0x42, + 0x38, 0x50, 0x6C, 0x19, 0xCC, 0x50, 0xE8, 0x03, 0xC2, 0x04, 0x0C, 0x50, 0xE9, 0x03, 0xF2, 0x02, + 0x24, 0x51, 0xC4, 0x70, 0xB9, 0x50, 0x6C, 0x19, 0x82, 0x04, 0x28, 0x70, 0x82, 0x1B, 0xF2, 0x18, + 0x08, 0xD0, 0x00, 0x80, 0x38, 0xC0, 0x70, 0x19, 0x2C, 0xD0, 0x0C, 0xDC, 0x38, 0x2D, 0x48, 0x00, + 0x38, 0x3D, 0x38, 0x00, 0x04, 0x61, 0x26, 0x6C, 0xB9, 0x60, 0x70, 0x19, 0xAB, 0x15, 0x00, 0x00, + 0xC6, 0xC2, 0xA2, 0x04, 0x38, 0x7D, 0x4C, 0x00, 0xF2, 0x03, 0x28, 0x70, 0x84, 0x1B, 0xC6, 0x7E, + 0xC2, 0x19, 0x3F, 0xEE, 0x07, 0x00, 0x06, 0x2E, 0x06, 0x7E, 0xD7, 0x72, 0xD7, 0x21, 0x26, 0x27, + 0x36, 0x2E, 0xD7, 0x21, 0x0C, 0x30, 0x10, 0x27, 0xAB, 0x15, 0x00, 0x00, 0xC4, 0x2A, 0xC2, 0x0A, + 0x98, 0x70, 0xA4, 0x1B, 0x82, 0x04, 0xCB, 0x3A, 0x01, 0x00, 0xF2, 0x04, 0x06, 0x2E, 0x8B, 0xEA, + 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xA2, 0x1B, + 0x82, 0x06, 0x08, 0x70, 0x00, 0x80, 0x28, 0x47, 0xAE, 0xDC, 0xF2, 0x05, 0x38, 0x70, 0x70, 0x1A, + 0x28, 0x47, 0x28, 0x00, 0x98, 0x60, 0xAC, 0x1B, 0x82, 0x06, 0x34, 0x61, 0x99, 0x60, 0xAC, 0x1B, + 0x04, 0x21, 0xF2, 0x33, 0x0C, 0x70, 0xFC, 0x0A, 0x38, 0x57, 0x0C, 0x00, 0x08, 0x60, 0x08, 0x00, + 0xD6, 0x65, 0x82, 0x08, 0x08, 0x60, 0xF7, 0xFF, 0x2C, 0x60, 0xFF, 0xFF, 0x56, 0x65, 0xB9, 0x67, + 0x0C, 0x00, 0x28, 0x67, 0x12, 0x03, 0x26, 0x46, 0x28, 0x67, 0x18, 0x03, 0xC6, 0x46, 0x02, 0x1A, + 0x98, 0x67, 0x8D, 0x06, 0x92, 0x17, 0x98, 0x67, 0xA2, 0x06, 0x92, 0x14, 0x38, 0x77, 0x0C, 0x00, + 0xDC, 0x70, 0x00, 0xF0, 0x92, 0x0F, 0x38, 0x60, 0x74, 0x19, 0x04, 0x21, 0x24, 0x61, 0xB9, 0x60, + 0x74, 0x19, 0x38, 0x50, 0x70, 0x1A, 0x18, 0x55, 0x2A, 0x00, 0xC6, 0x65, 0xD2, 0x06, 0x06, 0x27, + 0xF2, 0x04, 0xB9, 0x00, 0x74, 0x19, 0x04, 0x20, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x07, 0xF0, 0x70, 0xB9, 0x07, 0xF4, 0x70, 0xC4, 0x21, 0xB9, 0x07, + 0xF8, 0x70, 0xB9, 0x07, 0x34, 0x71, 0x08, 0x60, 0x01, 0x00, 0x92, 0x05, 0x66, 0x63, 0xB9, 0x67, + 0xF0, 0x70, 0xF2, 0x15, 0xC4, 0x22, 0x92, 0x05, 0x66, 0x63, 0xB9, 0x67, 0xF4, 0x70, 0xF2, 0x0F, + 0xC4, 0x23, 0x92, 0x05, 0x66, 0x63, 0xB9, 0x67, 0xF8, 0x70, 0xF2, 0x09, 0x0C, 0x50, 0x80, 0x02, + 0x66, 0x56, 0xB9, 0x57, 0xF0, 0x70, 0x66, 0x63, 0xB9, 0x67, 0x34, 0x71, 0x0C, 0x20, 0x10, 0x00, + 0x0C, 0x30, 0x00, 0x50, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x18, 0x00, 0xD9, 0xC1, 0x08, 0x00, 0x18, 0xD0, 0xB6, 0x1B, + 0x18, 0x60, 0xB5, 0x1B, 0xC1, 0xA1, 0xC6, 0x6D, 0x82, 0x61, 0x99, 0xD0, 0xB5, 0x1B, 0xC4, 0xD0, + 0x18, 0x70, 0xB2, 0x1B, 0x1C, 0x60, 0x10, 0x00, 0x56, 0x76, 0x82, 0x05, 0x64, 0x72, 0x99, 0x70, + 0xB2, 0x1B, 0xF2, 0x48, 0x64, 0x71, 0x99, 0x70, 0xB2, 0x1B, 0x4B, 0xFD, 0x01, 0x00, 0xCB, 0xFB, + 0x01, 0x00, 0xA9, 0x00, 0x86, 0x1B, 0xB9, 0x00, 0x7C, 0x19, 0xB9, 0x00, 0x74, 0x19, 0xA9, 0x00, + 0x88, 0x1B, 0x14, 0x61, 0x99, 0x00, 0xC6, 0x1B, 0x99, 0x60, 0x60, 0x19, 0x06, 0x6D, 0x06, 0x7D, + 0x0C, 0xA0, 0x38, 0x19, 0x1C, 0x40, 0x64, 0x00, 0x0C, 0xB0, 0x10, 0x19, 0x0C, 0xD0, 0xC4, 0x1A, + 0x14, 0x51, 0x0C, 0xF0, 0xB0, 0x1A, 0x0C, 0x20, 0x88, 0x1A, 0x2F, 0x3A, 0x07, 0x00, 0xB1, 0x43, + 0x2F, 0x3B, 0x07, 0x00, 0xB1, 0x43, 0x2F, 0x3D, 0x06, 0x00, 0xA1, 0x53, 0x2F, 0x3F, 0x06, 0x00, + 0xA1, 0x53, 0x2F, 0x32, 0x07, 0x00, 0x24, 0x74, 0xCC, 0x70, 0x28, 0x00, 0xB1, 0x03, 0x24, 0x62, + 0x92, 0xED, 0x38, 0x70, 0x70, 0x1A, 0x04, 0x50, 0x18, 0x27, 0x47, 0x00, 0x18, 0x37, 0x90, 0x00, + 0x18, 0x47, 0x8F, 0x00, 0x18, 0x67, 0x2A, 0x00, 0x0C, 0xF0, 0xE0, 0x00, 0xF1, 0xF0, 0xB9, 0x20, + 0x78, 0x19, 0x98, 0x70, 0xB6, 0x1B, 0x82, 0x06, 0x04, 0x20, 0x0C, 0x30, 0x54, 0x05, 0xEB, 0x46, + 0x01, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0xAB, 0x34, 0x01, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0x6B, 0x44, + 0x00, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0x4B, 0x2D, 0x01, 0x00, 0x18, 0x20, 0xB2, 0x1B, 0xEB, 0x4E, + 0x00, 0x00, 0xCB, 0xAF, 0x01, 0x00, 0x58, 0xC1, 0x08, 0x00, 0x40, 0xA1, 0x2C, 0x10, 0x18, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x24, 0xB1, 0xF1, 0x8B, 0x34, 0x00, 0x00, 0x04, 0x24, + 0x0C, 0x30, 0x00, 0x30, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x0C, 0x20, 0x11, 0x00, + 0x8B, 0x34, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x28, + 0x0C, 0x30, 0x00, 0x40, 0xB1, 0xF1, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x04, 0x62, 0xB1, 0xF1, 0x99, 0x60, 0xB3, 0x1B, 0xCB, 0x31, + 0x00, 0x00, 0xAB, 0x3C, 0x00, 0x00, 0x4B, 0x2F, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x20, 0x04, 0x21, + 0x4B, 0x3A, 0x00, 0x00, 0x2B, 0x07, 0x02, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x6B, 0xA4, 0x04, 0x00, + 0x2B, 0x52, 0x01, 0x00, 0x6B, 0x53, 0x01, 0x00, 0xCB, 0x92, 0x01, 0x00, 0x0B, 0x93, 0x03, 0x00, + 0x93, 0x22, 0x92, 0x0C, 0x18, 0x70, 0xA1, 0x1B, 0x5C, 0x70, 0xF0, 0x00, 0xCC, 0x70, 0x40, 0x00, + 0x82, 0x0D, 0x04, 0x61, 0x99, 0x60, 0xB6, 0x1B, 0xF2, 0x09, 0xCB, 0x39, 0x04, 0x00, 0x04, 0x20, + 0x06, 0x32, 0x4B, 0xB3, 0x01, 0x00, 0x0B, 0x92, 0x01, 0x00, 0x0B, 0x31, 0x00, 0x00, 0x6B, 0x32, + 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0xB8, 0x70, 0x8C, 0x19, 0x3C, 0x10, 0x48, 0x00, + 0xD9, 0xC1, 0x38, 0x00, 0xD9, 0x81, 0x28, 0x00, 0x9A, 0x92, 0x02, 0x00, 0x38, 0x80, 0x08, 0x0B, + 0xD4, 0x81, 0x9A, 0x8D, 0x02, 0x00, 0x08, 0x40, 0x00, 0x30, 0xB9, 0x81, 0x10, 0x00, 0x06, 0xC8, + 0x06, 0xD8, 0xB9, 0x81, 0x0C, 0x00, 0xB9, 0x81, 0x08, 0x00, 0x06, 0xA8, 0x06, 0xE8, 0xB9, 0x81, + 0x04, 0x00, 0xB1, 0x81, 0x06, 0x98, 0x06, 0xB8, 0xB9, 0x81, 0x14, 0x00, 0x2C, 0x40, 0x00, 0x49, + 0x06, 0x78, 0x57, 0x71, 0x26, 0x74, 0x30, 0x77, 0xB9, 0x41, 0x24, 0x00, 0x0C, 0x60, 0xFF, 0x0F, + 0x23, 0x58, 0x56, 0x67, 0x77, 0x78, 0x5C, 0x70, 0xFF, 0x0F, 0x06, 0x25, 0x0C, 0x30, 0x18, 0x00, + 0xB9, 0x51, 0x20, 0x00, 0xB9, 0x61, 0x18, 0x00, 0xB9, 0x71, 0x1C, 0x00, 0x4B, 0x18, 0x00, 0x00, + 0x23, 0x22, 0xC4, 0x2A, 0x38, 0x41, 0x24, 0x00, 0x38, 0x51, 0x20, 0x00, 0x38, 0x61, 0x18, 0x00, + 0x38, 0x71, 0x1C, 0x00, 0xD2, 0x31, 0xCC, 0x50, 0xA7, 0x00, 0xD2, 0x1A, 0x3F, 0x57, 0x06, 0x00, + 0xCC, 0x50, 0x14, 0x00, 0x02, 0x0A, 0x38, 0x61, 0x14, 0x00, 0x04, 0x71, 0x26, 0x65, 0x26, 0x79, + 0xB9, 0x61, 0x14, 0x00, 0x23, 0x97, 0xF2, 0x57, 0x36, 0x76, 0xCC, 0x70, 0x14, 0x00, 0x02, 0x53, + 0x38, 0x71, 0x0C, 0x00, 0x24, 0x71, 0x23, 0x77, 0xB9, 0x71, 0x0C, 0x00, 0xF2, 0x4C, 0xCC, 0x50, + 0xD7, 0x00, 0xC2, 0x49, 0x3F, 0x57, 0x06, 0x00, 0xCC, 0x50, 0x14, 0x00, 0x02, 0x06, 0x30, 0x71, + 0x24, 0x71, 0x23, 0x77, 0xB1, 0x71, 0xF2, 0x3F, 0x36, 0x76, 0xC4, 0x7A, 0x02, 0x3C, 0x24, 0xD1, + 0x26, 0xA7, 0x23, 0xDD, 0xF2, 0x38, 0xCC, 0x50, 0xA7, 0x00, 0xD2, 0x1C, 0xCC, 0x20, 0x17, 0x00, + 0x82, 0x32, 0x3F, 0x57, 0x06, 0x00, 0xCC, 0x50, 0x14, 0x00, 0x02, 0x08, 0x38, 0x71, 0x04, 0x00, + 0x24, 0x71, 0x23, 0x77, 0xB9, 0x71, 0x04, 0x00, 0xF2, 0x26, 0x36, 0x76, 0xCC, 0x70, 0x14, 0x00, + 0x02, 0x22, 0x38, 0x61, 0x08, 0x00, 0x24, 0xC1, 0x26, 0x67, 0xB9, 0x61, 0x08, 0x00, 0x23, 0xCC, + 0xF2, 0x1A, 0xCC, 0x50, 0xD7, 0x00, 0xC2, 0x17, 0xCC, 0x20, 0x17, 0x00, 0x82, 0x14, 0x3F, 0x57, + 0x06, 0x00, 0xCC, 0x50, 0x14, 0x00, 0x02, 0x05, 0x24, 0xE1, 0x26, 0xB5, 0x23, 0xEE, 0xF2, 0x0B, + 0x36, 0x76, 0xCC, 0x70, 0x14, 0x00, 0x02, 0x07, 0x38, 0x71, 0x10, 0x00, 0x24, 0x71, 0x23, 0x77, + 0xB9, 0x71, 0x10, 0x00, 0x24, 0x81, 0xCC, 0x80, 0x50, 0x01, 0x9A, 0x73, 0xFF, 0xFF, 0x18, 0x20, + 0xAC, 0x1B, 0x04, 0x70, 0x08, 0x30, 0x00, 0x30, 0x06, 0x67, 0x0C, 0x80, 0x74, 0x1A, 0x2C, 0x30, + 0x00, 0x49, 0x0C, 0x50, 0x84, 0x19, 0x2F, 0x48, 0x07, 0x00, 0x20, 0x44, 0x0C, 0xF0, 0xFF, 0x0F, + 0x57, 0x41, 0x26, 0x43, 0x30, 0x44, 0x56, 0xF4, 0x77, 0x48, 0x5C, 0x40, 0xFF, 0x0F, 0xC6, 0x4F, + 0xC2, 0x18, 0x36, 0x4F, 0xCC, 0x40, 0x64, 0x00, 0x02, 0x08, 0xCC, 0x40, 0x78, 0x00, 0x12, 0x03, + 0x24, 0x61, 0xF2, 0x02, 0x24, 0x62, 0x23, 0x66, 0xC4, 0x62, 0xC2, 0x0A, 0x30, 0x45, 0x24, 0x41, + 0xC4, 0x4A, 0xB1, 0x45, 0x02, 0x06, 0xB1, 0x05, 0x0C, 0x20, 0x96, 0x00, 0xF2, 0x02, 0xB1, 0x05, + 0x24, 0x72, 0xC4, 0x76, 0x92, 0xD9, 0x99, 0x20, 0xAC, 0x1B, 0x38, 0x21, 0x14, 0x00, 0x04, 0x31, + 0x26, 0x39, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x18, 0x00, 0x06, 0x82, 0x02, 0x2E, 0xCC, 0x90, + 0x10, 0x00, 0xC2, 0x31, 0x04, 0x31, 0x06, 0x2A, 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, + 0x18, 0x00, 0x02, 0x26, 0xCC, 0xD0, 0x20, 0x00, 0xC2, 0x23, 0x30, 0x61, 0xC4, 0x6F, 0xD2, 0x20, + 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, 0x26, 0x3C, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x50, 0x00, + 0x02, 0x17, 0xCC, 0xC0, 0x30, 0x00, 0xC2, 0x14, 0x38, 0x71, 0x04, 0x00, 0xC4, 0x7F, 0xD2, 0x10, + 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x40, 0x00, 0x02, 0x08, + 0xCC, 0xE0, 0x20, 0x00, 0xD2, 0x64, 0xF2, 0x04, 0xCC, 0x20, 0x10, 0x00, 0x02, 0x32, 0xCC, 0x90, + 0x14, 0x00, 0xD2, 0x2F, 0x38, 0x61, 0x0C, 0x00, 0xCC, 0x60, 0x15, 0x00, 0xC2, 0x5D, 0x04, 0x31, + 0x06, 0x2A, 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x40, 0x00, 0x02, 0x22, 0xCC, 0xD0, + 0x30, 0x00, 0xC2, 0x1F, 0x30, 0x71, 0xC4, 0x7F, 0xD2, 0x1C, 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, + 0x26, 0x3C, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x40, 0x00, 0x02, 0x13, 0xCC, 0xC0, 0x40, 0x00, + 0xC2, 0x10, 0x38, 0x61, 0x04, 0x00, 0xC4, 0x6F, 0xD2, 0x0C, 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, + 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x50, 0x00, 0x02, 0x04, 0xCC, 0xE0, 0x30, 0x00, 0xD2, 0x2F, + 0x38, 0x71, 0x0C, 0x00, 0xCC, 0x70, 0x30, 0x00, 0xC2, 0x2F, 0x04, 0x31, 0x06, 0x2A, 0x26, 0x3D, + 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x50, 0x00, 0x02, 0x27, 0xCC, 0xD0, 0x30, 0x00, 0xC2, 0x24, + 0x30, 0x61, 0xC4, 0x6F, 0xD2, 0x21, 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, 0x26, 0x3C, 0x8B, 0x16, + 0x00, 0x00, 0xCC, 0x20, 0x80, 0x00, 0x02, 0x18, 0xCC, 0xC0, 0x40, 0x00, 0xC2, 0x15, 0x38, 0x71, + 0x04, 0x00, 0xC4, 0x7F, 0xD2, 0x11, 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, 0x8B, 0x16, 0x00, 0x00, + 0xCC, 0x20, 0x40, 0x00, 0x02, 0x09, 0xCC, 0xE0, 0x30, 0x00, 0xC2, 0x06, 0x38, 0x61, 0x10, 0x00, + 0xC4, 0x6F, 0xCA, 0x05, 0x01, 0x00, 0xCC, 0x80, 0x14, 0x00, 0x0A, 0xA9, 0x00, 0x00, 0xC4, 0x90, + 0x82, 0x6D, 0x38, 0x71, 0x0C, 0x00, 0xCC, 0x70, 0x1F, 0x00, 0xD2, 0x2F, 0x04, 0x31, 0x06, 0x2A, + 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x20, 0x00, 0x02, 0x27, 0xCC, 0xD0, 0x30, 0x00, + 0xC2, 0x24, 0x30, 0x61, 0xC4, 0x61, 0xD2, 0x21, 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, 0x26, 0x3C, + 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x30, 0x00, 0x02, 0x18, 0xCC, 0xC0, 0x40, 0x00, 0xC2, 0x15, + 0x38, 0x71, 0x04, 0x00, 0xC4, 0x71, 0xD2, 0x11, 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, 0x8B, 0x16, + 0x00, 0x00, 0xCC, 0x20, 0x20, 0x00, 0x02, 0x09, 0xCC, 0xE0, 0x20, 0x00, 0xC2, 0x06, 0x38, 0x61, + 0x10, 0x00, 0xC4, 0x61, 0xCA, 0xCC, 0x00, 0x00, 0xCC, 0x80, 0x30, 0x00, 0x02, 0x3B, 0xCC, 0x90, + 0x20, 0x00, 0xC2, 0x3B, 0x38, 0x71, 0x0C, 0x00, 0xC4, 0x79, 0xD2, 0x37, 0x04, 0x31, 0x06, 0x2A, + 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x1A, 0x00, 0x02, 0x2F, 0xCC, 0xD0, 0x20, 0x00, + 0xC2, 0x2C, 0x30, 0x61, 0xC4, 0x61, 0xD2, 0x29, 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, 0x26, 0x3C, + 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x1A, 0x00, 0x02, 0x20, 0xCC, 0xC0, 0x20, 0x00, 0xC2, 0x1D, + 0x38, 0x71, 0x04, 0x00, 0xC4, 0x79, 0xD2, 0x19, 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, 0x8B, 0x16, + 0x00, 0x00, 0xCC, 0x20, 0x50, 0x00, 0x02, 0x11, 0xCC, 0xE0, 0x26, 0x00, 0xC2, 0x0E, 0x38, 0x61, + 0x10, 0x00, 0xC4, 0x61, 0xD2, 0x0A, 0xFA, 0x93, 0x00, 0x00, 0xCC, 0x80, 0x30, 0x00, 0x1A, 0x9D, + 0x00, 0x00, 0xCC, 0x80, 0x20, 0x00, 0x02, 0x33, 0xCC, 0x90, 0x10, 0x00, 0xC2, 0x33, 0x38, 0x71, + 0x0C, 0x00, 0xC4, 0x79, 0xD2, 0x31, 0x04, 0x31, 0x06, 0x2A, 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, + 0xC4, 0x2A, 0x02, 0x2A, 0xC4, 0xD7, 0xC2, 0x28, 0x30, 0x61, 0xC4, 0x61, 0xD2, 0x25, 0x38, 0x21, + 0x08, 0x00, 0x04, 0x31, 0x26, 0x3C, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x10, 0x00, 0x02, 0x1C, + 0xC4, 0xC8, 0xC2, 0x1A, 0x38, 0x71, 0x04, 0x00, 0xC4, 0x79, 0xD2, 0x16, 0x04, 0x31, 0x06, 0x2B, + 0x26, 0x3E, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x2A, 0x00, 0x02, 0x0E, 0xCC, 0xE0, 0x20, 0x00, + 0xC2, 0x0B, 0x38, 0x61, 0x10, 0x00, 0xC4, 0x61, 0xD2, 0x07, 0xF2, 0x59, 0xCC, 0x80, 0x18, 0x00, + 0x02, 0x64, 0xC4, 0x96, 0xC2, 0x31, 0x38, 0x71, 0x0C, 0x00, 0xC4, 0x74, 0xD2, 0x2F, 0x04, 0x31, + 0x06, 0x2A, 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, 0xC4, 0x26, 0x02, 0x28, 0xC4, 0xD8, 0xC2, 0x26, + 0x30, 0x61, 0xC4, 0x61, 0xD2, 0x23, 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, 0x26, 0x3C, 0x8B, 0x16, + 0x00, 0x00, 0xCC, 0x20, 0x14, 0x00, 0x02, 0x1A, 0xCC, 0xC0, 0x10, 0x00, 0xC2, 0x17, 0x38, 0x71, + 0x04, 0x00, 0xC4, 0x71, 0xD2, 0x13, 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, 0x8B, 0x16, 0x00, 0x00, + 0xCC, 0x20, 0x16, 0x00, 0x02, 0x0B, 0xCC, 0xE0, 0x28, 0x00, 0xC2, 0x08, 0x38, 0x61, 0x10, 0x00, + 0xC4, 0x61, 0xD2, 0x04, 0xF2, 0x24, 0xC4, 0x94, 0xC2, 0x30, 0xB8, 0x71, 0x0C, 0x00, 0x92, 0x2D, + 0x04, 0x31, 0x06, 0x2A, 0x26, 0x3D, 0x8B, 0x16, 0x00, 0x00, 0xC4, 0x26, 0x02, 0x26, 0xC4, 0xD2, + 0xC2, 0x24, 0xB0, 0x61, 0x92, 0x22, 0xC4, 0xC0, 0x92, 0x20, 0xB8, 0x71, 0x04, 0x00, 0x92, 0x1D, + 0x04, 0x31, 0x06, 0x2B, 0x26, 0x3E, 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x16, 0x00, 0x02, 0x15, + 0xCC, 0xE0, 0x10, 0x00, 0xC2, 0x12, 0xB8, 0x61, 0x10, 0x00, 0x92, 0x0F, 0x38, 0x70, 0x88, 0x19, + 0x24, 0x71, 0xC4, 0x7A, 0xB9, 0x70, 0x88, 0x19, 0x02, 0x0A, 0x1C, 0x60, 0x6A, 0x00, 0x99, 0x60, + 0xAC, 0x1B, 0x99, 0x00, 0xC6, 0x1B, 0xF2, 0x03, 0xB9, 0x00, 0x88, 0x19, 0x58, 0xC1, 0x38, 0x00, + 0x58, 0x81, 0x28, 0x00, 0x2C, 0x10, 0x48, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0x04, 0x63, + 0xC1, 0xE1, 0x99, 0x60, 0xB3, 0x1B, 0xCB, 0x31, 0x00, 0x00, 0x6B, 0x42, 0x01, 0x00, 0xC4, 0x20, + 0x82, 0x09, 0xAB, 0x3C, 0x00, 0x00, 0x04, 0x20, 0x0C, 0x30, 0x54, 0x05, 0xEB, 0x46, 0x01, 0x00, + 0xF2, 0x03, 0x2B, 0x3D, 0x00, 0x00, 0x4B, 0x2F, 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, 0x80, 0x02, + 0xEB, 0x46, 0x01, 0x00, 0x0C, 0x30, 0x28, 0x08, 0x04, 0x23, 0xEB, 0x46, 0x01, 0x00, 0x04, 0x21, + 0x8B, 0x39, 0x00, 0x00, 0xAB, 0x07, 0x02, 0x00, 0x06, 0xE2, 0x04, 0x21, 0x4B, 0x35, 0x00, 0x00, + 0x6B, 0xA4, 0x04, 0x00, 0x0B, 0x31, 0x00, 0x00, 0xCB, 0x57, 0x01, 0x00, 0x2B, 0x52, 0x01, 0x00, + 0x4B, 0xFD, 0x03, 0x00, 0x6B, 0x53, 0x01, 0x00, 0x06, 0x2E, 0xEB, 0x0A, 0x02, 0x00, 0xCB, 0x92, + 0x01, 0x00, 0xEB, 0x99, 0x01, 0x00, 0xAB, 0xA4, 0x01, 0x00, 0x6B, 0x32, 0x00, 0x00, 0x98, 0x70, + 0x19, 0x0E, 0x82, 0x0E, 0xB9, 0x00, 0x70, 0x19, 0x28, 0x60, 0x86, 0x1B, 0xB9, 0x00, 0x7C, 0x19, + 0xCC, 0x60, 0xEF, 0x00, 0xD2, 0x0A, 0x24, 0x61, 0xA9, 0x60, 0x86, 0x1B, 0xF2, 0x06, 0x38, 0x60, + 0x7C, 0x19, 0x24, 0x61, 0xB9, 0x60, 0x7C, 0x19, 0x38, 0x60, 0x78, 0x19, 0x38, 0x70, 0x7C, 0x19, + 0x24, 0x63, 0xC6, 0x76, 0xA2, 0x05, 0x99, 0x00, 0xB6, 0x1B, 0x99, 0x00, 0xAD, 0x1B, 0x98, 0x60, + 0xB4, 0x1B, 0x82, 0x10, 0x18, 0x50, 0xB7, 0x1B, 0x99, 0x00, 0xB4, 0x1B, 0x04, 0x20, 0x24, 0x51, + 0x99, 0x50, 0xB7, 0x1B, 0x99, 0x00, 0xB6, 0x1B, 0x0B, 0x78, 0x00, 0x00, 0x04, 0x21, 0x6B, 0x35, + 0x01, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x98, 0x70, 0xB6, 0x1B, 0x34, 0x14, 0xB1, 0xF1, + 0x92, 0x04, 0x98, 0x70, 0xB1, 0x1B, 0x82, 0x04, 0xEB, 0x81, 0x01, 0x00, 0xF2, 0x03, 0x2B, 0x54, + 0x01, 0x00, 0x0B, 0xF5, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x4B, 0xDE, 0x00, 0x00, 0xC4, 0x20, 0x82, 0x03, 0xEB, 0x6A, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x20, 0xB1, 0xF1, 0x4B, 0x77, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x18, 0x04, 0x20, 0xC1, 0xE1, 0x4B, 0x79, 0x00, 0x00, 0x06, 0xE2, + 0x04, 0x20, 0x0B, 0x78, 0x00, 0x00, 0x06, 0x2E, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x18, 0xC1, 0xE1, 0xEB, 0xBB, 0x00, 0x00, 0xC4, 0x20, 0x82, 0x07, 0x38, 0x20, 0x68, 0x19, + 0x6B, 0xBD, 0x00, 0x00, 0xB9, 0x00, 0x68, 0x19, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x18, 0x04, 0x21, 0xC1, 0xE1, 0x4B, 0x77, 0x00, 0x00, 0xEB, 0xBB, 0x00, 0x00, 0xC4, 0x20, + 0x92, 0x03, 0x2B, 0xE5, 0x00, 0x00, 0x08, 0xE0, 0x07, 0x00, 0x2C, 0xE0, 0x20, 0xA1, 0x8B, 0x8C, + 0x01, 0x00, 0x98, 0x70, 0xAA, 0x1B, 0x92, 0x14, 0x04, 0x21, 0x4B, 0x79, 0x00, 0x00, 0x26, 0x22, + 0x06, 0x72, 0x57, 0x71, 0x26, 0x27, 0xC6, 0x2E, 0xC2, 0xF3, 0x98, 0x70, 0xA9, 0x1B, 0x82, 0x08, + 0x04, 0x21, 0x0B, 0x78, 0x00, 0x00, 0x04, 0x21, 0x4B, 0x77, 0x00, 0x00, 0xF2, 0xE9, 0x04, 0x21, + 0x0B, 0x78, 0x00, 0x00, 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x14, 0x50, 0x40, 0xE1, + 0x24, 0x18, 0xE1, 0xF0, 0xC4, 0x20, 0x34, 0x14, 0xB1, 0xF1, 0x82, 0x05, 0x04, 0x61, 0x99, 0x60, + 0xBB, 0x1B, 0xF2, 0x03, 0x99, 0x00, 0xBB, 0x1B, 0x0C, 0x20, 0xE8, 0x19, 0x04, 0x30, 0x0C, 0x40, + 0x80, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x98, 0x70, 0xBB, 0x1B, 0x82, 0x08, 0x98, 0x70, 0xBA, 0x1B, 0x82, 0x05, 0xB9, 0x00, 0xE0, 0x19, + 0xB9, 0x00, 0xDC, 0x19, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xBB, 0x1B, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x82, 0x68, 0xB9, 0x00, 0xE4, 0x19, 0x4B, 0x3F, 0x00, 0x00, 0x38, 0x70, 0xE4, 0x19, + 0x1C, 0x60, 0x80, 0x00, 0x56, 0x76, 0x18, 0x60, 0xB0, 0x1B, 0x5C, 0x20, 0x7F, 0x00, 0x08, 0x50, + 0xFD, 0xFF, 0x2C, 0x50, 0xFF, 0xFF, 0x66, 0x72, 0x54, 0x61, 0xD7, 0x68, 0x56, 0x75, 0x66, 0x76, + 0x18, 0x60, 0xB6, 0x1B, 0x08, 0x50, 0xFB, 0xFF, 0x2C, 0x50, 0xFF, 0xFF, 0x54, 0x61, 0x57, 0x69, + 0x56, 0x75, 0x66, 0x76, 0xB9, 0x70, 0xE4, 0x19, 0x04, 0xD0, 0x08, 0x70, 0x00, 0x30, 0x08, 0x50, + 0x07, 0x00, 0x2C, 0x70, 0x00, 0x49, 0x06, 0x6D, 0x2C, 0x50, 0xFF, 0xFF, 0x30, 0x47, 0x0C, 0x30, + 0xFF, 0x0F, 0x56, 0x34, 0x77, 0x48, 0x5C, 0x40, 0xFF, 0x0F, 0x36, 0x34, 0x38, 0x40, 0xE4, 0x19, + 0x23, 0x23, 0x06, 0xF4, 0xF7, 0xF9, 0xC6, 0x3F, 0x02, 0x08, 0x06, 0x32, 0xD7, 0x39, 0x56, 0x45, + 0x66, 0x43, 0xB9, 0x40, 0xE4, 0x19, 0x43, 0xD6, 0x24, 0x61, 0xCC, 0x60, 0x50, 0x01, 0x24, 0x74, + 0x92, 0xE6, 0xC4, 0xD0, 0x82, 0x1F, 0x0C, 0x30, 0x18, 0x00, 0x06, 0x2D, 0x2B, 0x19, 0x00, 0x00, + 0x38, 0xE0, 0xE4, 0x19, 0x1C, 0x70, 0x81, 0x0F, 0x5C, 0x20, 0x1F, 0x00, 0x56, 0xE7, 0xD7, 0x23, + 0x66, 0xE2, 0x0C, 0x30, 0x18, 0x00, 0x06, 0x2D, 0x8B, 0x16, 0x00, 0x00, 0x08, 0x70, 0xFE, 0xFF, + 0x5C, 0x20, 0x1F, 0x00, 0x2C, 0x70, 0xFF, 0x0F, 0x57, 0x26, 0x56, 0x7E, 0x66, 0x72, 0xB9, 0x70, + 0xE4, 0x19, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x80, + 0x28, 0x67, 0x28, 0xDC, 0x98, 0x70, 0xBB, 0x1B, 0x3C, 0x10, 0x38, 0x00, 0xD9, 0xC1, 0x28, 0x00, + 0xD9, 0x81, 0x18, 0x00, 0x8A, 0x99, 0x00, 0x00, 0xF7, 0x60, 0x08, 0xC0, 0x00, 0x30, 0x08, 0xB0, + 0xC0, 0xFF, 0xB1, 0x61, 0x99, 0x00, 0xB9, 0x1B, 0x0C, 0xE0, 0x94, 0x0F, 0x04, 0x80, 0x2C, 0xC0, + 0x00, 0x49, 0x2C, 0xB0, 0xFF, 0x07, 0x0C, 0x60, 0xFC, 0x0A, 0x18, 0x76, 0x8C, 0x06, 0xC6, 0x78, + 0xCA, 0x83, 0x00, 0x00, 0x98, 0x7E, 0x1E, 0x00, 0x82, 0x04, 0x04, 0x71, 0x26, 0x78, 0x13, 0x87, + 0x06, 0x2E, 0x0B, 0xED, 0x01, 0x00, 0xC4, 0x20, 0x92, 0x08, 0x2C, 0xE0, 0x26, 0x00, 0x0C, 0x70, + 0x82, 0x11, 0xC6, 0xE7, 0x92, 0xE9, 0xF2, 0x70, 0x18, 0x7E, 0x1E, 0x00, 0xC4, 0x71, 0x92, 0x09, + 0x18, 0x60, 0xB9, 0x1B, 0x64, 0x61, 0x99, 0x60, 0xB9, 0x1B, 0x0C, 0x70, 0xB8, 0x19, 0xF2, 0x0A, + 0xC4, 0x72, 0x92, 0xEC, 0x18, 0x60, 0xB9, 0x1B, 0x64, 0x62, 0x99, 0x60, 0xB9, 0x1B, 0x0C, 0x70, + 0x94, 0x19, 0x18, 0x6E, 0x15, 0x00, 0x08, 0x90, 0x3F, 0x00, 0x34, 0x61, 0x2F, 0x56, 0x06, 0x00, + 0x26, 0x56, 0x2C, 0x90, 0xFF, 0xFF, 0xD7, 0x51, 0x04, 0x40, 0xB9, 0x61, 0x0C, 0x00, 0xB9, 0x91, + 0x10, 0x00, 0x38, 0x61, 0x0C, 0x00, 0x26, 0x64, 0xC4, 0x6D, 0xD2, 0x40, 0x18, 0x6E, 0x14, 0x00, + 0x04, 0x30, 0x2F, 0x26, 0x05, 0x00, 0x57, 0x21, 0x34, 0x24, 0x34, 0x61, 0x26, 0x2C, 0xB9, 0x61, + 0x08, 0x00, 0x38, 0x61, 0x08, 0x00, 0x26, 0x63, 0xCC, 0x60, 0x16, 0x00, 0xD2, 0x2B, 0x30, 0xA1, + 0x30, 0xD2, 0x1C, 0x90, 0x00, 0x08, 0x36, 0xDA, 0x5C, 0xD0, 0xFF, 0x07, 0x23, 0xFD, 0xB9, 0xF1, + 0x14, 0x00, 0x30, 0x67, 0x56, 0x69, 0x66, 0x6F, 0xB1, 0x67, 0x28, 0xF2, 0x02, 0x00, 0x56, 0x6B, + 0x36, 0xFA, 0x5C, 0xF0, 0xFF, 0x07, 0x23, 0xAF, 0x06, 0x9A, 0xD7, 0x95, 0x66, 0x69, 0xB1, 0x67, + 0x38, 0x91, 0x14, 0x00, 0x04, 0x60, 0xC6, 0x9A, 0x02, 0x05, 0x3F, 0x6F, 0x0D, 0x00, 0x5C, 0x60, + 0xFF, 0x03, 0x30, 0xF7, 0x38, 0xA1, 0x10, 0x00, 0x57, 0x6B, 0x56, 0xFA, 0x66, 0xF6, 0xB1, 0xF7, + 0x24, 0x74, 0x24, 0x31, 0xC4, 0x33, 0x24, 0x24, 0x92, 0xCD, 0x24, 0x41, 0xC4, 0x43, 0x2C, 0x50, + 0x18, 0x00, 0x92, 0xB8, 0xF2, 0x8B, 0x58, 0xC1, 0x28, 0x00, 0x58, 0x81, 0x18, 0x00, 0x2C, 0x10, + 0x38, 0x00, 0xE1, 0xF0, 0x98, 0x70, 0xBB, 0x1B, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x82, 0x2F, + 0x06, 0xED, 0x0C, 0xE0, 0x90, 0x19, 0xB9, 0x00, 0x90, 0x19, 0x4B, 0x3E, 0x00, 0x00, 0x18, 0x70, + 0xB6, 0x1B, 0xC4, 0x71, 0x92, 0x24, 0x98, 0x70, 0x19, 0x0E, 0x82, 0x21, 0x23, 0xC2, 0xCB, 0x3D, + 0x00, 0x00, 0xA9, 0x2E, 0x02, 0x00, 0x0C, 0x30, 0x18, 0x00, 0x06, 0x2C, 0x4B, 0x18, 0x00, 0x00, + 0x38, 0xE0, 0x90, 0x19, 0x1C, 0x70, 0x20, 0x00, 0x56, 0xE7, 0x5C, 0x20, 0x1F, 0x00, 0x66, 0xE2, + 0x0C, 0x30, 0x18, 0x00, 0x06, 0x2C, 0xAB, 0x15, 0x00, 0x00, 0x5C, 0x20, 0x1F, 0x00, 0x1C, 0x70, + 0xE1, 0x03, 0xD7, 0x22, 0x56, 0xE7, 0x66, 0xE2, 0xB9, 0xE0, 0x90, 0x19, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x38, 0x60, 0xE4, 0x19, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x7E, + 0x0C, 0x70, 0xE8, 0x19, 0xB9, 0x67, 0x08, 0x00, 0x38, 0x60, 0xE0, 0x19, 0xB9, 0x67, 0x0C, 0x00, + 0x38, 0x60, 0xDC, 0x19, 0x06, 0xD7, 0xB9, 0x67, 0x10, 0x00, 0x38, 0x60, 0x90, 0x19, 0x0C, 0x20, + 0x00, 0x1A, 0xB9, 0x67, 0x14, 0x00, 0x18, 0x30, 0xB9, 0x1B, 0x06, 0xC6, 0xD4, 0x31, 0x82, 0x08, + 0x0C, 0x30, 0xB8, 0x19, 0x04, 0x49, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0xF2, 0x05, 0x04, 0x49, + 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x18, 0x30, 0xB9, 0x1B, 0x54, 0x32, 0x93, 0x33, 0x0C, 0x20, + 0x24, 0x1A, 0x82, 0x08, 0x0C, 0x30, 0x94, 0x19, 0x04, 0x49, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, + 0xF2, 0x05, 0x04, 0x49, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x38, 0x70, 0x08, 0x0B, 0xB9, 0x7D, + 0x04, 0x00, 0x38, 0x70, 0xE8, 0x19, 0x24, 0x71, 0xB9, 0x70, 0xE8, 0x19, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0x0C, 0x60, 0xFE, 0x00, 0xB9, 0x67, 0x0C, 0x20, + 0xB9, 0x07, 0x18, 0x20, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x04, 0x30, + 0xB9, 0x37, 0x08, 0x30, 0xB9, 0x47, 0x00, 0x30, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x00, 0x30, 0x64, 0x71, 0xB9, 0x76, 0x00, 0x30, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x00, 0x30, 0x14, 0x52, 0x56, 0x75, 0xB9, 0x76, 0x00, 0x30, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x08, 0x30, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, + 0x38, 0x27, 0x0C, 0x30, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x14, 0x00, + 0x08, 0x70, 0x00, 0x80, 0xD9, 0xC1, 0x04, 0x00, 0x18, 0xC7, 0x67, 0xDC, 0xB1, 0xB1, 0x28, 0xB0, + 0x80, 0x1B, 0x08, 0xE0, 0x00, 0x30, 0x54, 0xB4, 0x23, 0xBB, 0x06, 0x5C, 0x2C, 0xE0, 0x00, 0x49, + 0x04, 0xD0, 0xC4, 0xB0, 0x82, 0x0A, 0x06, 0x2D, 0x0C, 0x30, 0x18, 0x00, 0x4B, 0x18, 0x00, 0x00, + 0xC4, 0x2E, 0x04, 0x50, 0xD2, 0x02, 0x06, 0x5C, 0x30, 0x7E, 0x5C, 0x70, 0xFF, 0x0F, 0x2F, 0x67, + 0x05, 0x00, 0xCC, 0x60, 0xFF, 0x0F, 0xC2, 0x03, 0x0C, 0x60, 0xFF, 0x0F, 0x24, 0xD1, 0x57, 0x68, + 0xCC, 0xD0, 0x50, 0x01, 0x66, 0x67, 0xB1, 0x6E, 0x24, 0xE4, 0x92, 0xE4, 0x58, 0xC1, 0x04, 0x00, + 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, 0x2F, 0x72, 0x02, 0x00, + 0x26, 0x27, 0x57, 0x21, 0x0C, 0x60, 0xFC, 0x0A, 0x34, 0x18, 0x2C, 0x20, 0xB8, 0x09, 0xC1, 0xE1, + 0x26, 0x26, 0x14, 0x71, 0xA1, 0x72, 0xA9, 0x72, 0x02, 0x00, 0xA9, 0x72, 0x04, 0x00, 0xA9, 0x72, + 0x06, 0x00, 0xA9, 0x02, 0x08, 0x00, 0xA9, 0x02, 0x0A, 0x00, 0x38, 0xE6, 0x3C, 0x0C, 0xDC, 0xE0, + 0xFF, 0x03, 0x92, 0x10, 0x0C, 0x20, 0x56, 0x15, 0x06, 0x3E, 0x04, 0x48, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x0C, 0x20, 0x5E, 0x15, 0x06, 0x3E, 0x0C, 0x40, 0x1A, 0x00, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x04, 0xE0, 0x06, 0x2E, + 0x6B, 0xB3, 0x01, 0x00, 0x24, 0xE1, 0xC4, 0xED, 0x92, 0xFB, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xB1, 0x21, 0x28, 0x71, 0x02, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xC9, 0xA1, + 0x08, 0x00, 0xC6, 0x47, 0x13, 0xD2, 0x06, 0xC4, 0x18, 0x21, 0x01, 0x00, 0x23, 0x33, 0x22, 0x03, + 0x43, 0x23, 0xF2, 0x1F, 0xC6, 0x4D, 0x43, 0xA2, 0x43, 0xDD, 0x32, 0x0C, 0x04, 0xE0, 0xC6, 0x2E, + 0x06, 0xBD, 0x82, 0x05, 0x04, 0x3A, 0xAB, 0x15, 0x00, 0x00, 0x13, 0xE2, 0x06, 0x3A, 0x04, 0xD0, + 0xF2, 0x04, 0x43, 0xB7, 0x06, 0xEA, 0x43, 0x33, 0x36, 0x3E, 0x3F, 0x2D, 0x0C, 0x00, 0x4B, 0x14, + 0x00, 0x00, 0x43, 0x22, 0x3F, 0x3D, 0x0B, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x26, 0x2E, 0x43, 0x22, + 0x58, 0xC1, 0x10, 0x00, 0x48, 0xA1, 0x08, 0x00, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x64, 0x00, 0xD9, 0xC1, 0x54, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0xD9, 0x81, 0x44, 0x00, + 0x98, 0x67, 0x74, 0x0C, 0x06, 0xE7, 0x92, 0x0F, 0x98, 0x67, 0xB0, 0x0C, 0x9A, 0x12, 0x03, 0x00, + 0x38, 0x77, 0x3C, 0x0C, 0xDC, 0x70, 0xFF, 0x03, 0x9A, 0x0C, 0x03, 0x00, 0x4B, 0xB6, 0x01, 0x00, + 0xFA, 0x08, 0x03, 0x00, 0x98, 0x70, 0xB0, 0x1B, 0x38, 0x6E, 0x0C, 0x00, 0x28, 0x7E, 0x12, 0x00, + 0x08, 0xB0, 0x00, 0x80, 0x2C, 0xB0, 0x0C, 0xDC, 0x92, 0x36, 0xD4, 0x61, 0x18, 0x6B, 0x74, 0x00, + 0x82, 0x21, 0xC6, 0x67, 0xC2, 0x0E, 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x60, + 0x46, 0x00, 0x0C, 0x70, 0x78, 0x00, 0xA9, 0x7E, 0x56, 0x0A, 0x99, 0x6E, 0x55, 0x0A, 0xF2, 0x79, + 0x18, 0x6B, 0x73, 0x00, 0xC6, 0x67, 0xC2, 0x04, 0x0C, 0x70, 0x1E, 0x00, 0xF2, 0x24, 0x0C, 0x70, + 0x28, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, 0x78, 0x00, 0xA9, 0x7E, 0x56, 0x0A, 0x04, 0x75, + 0xF2, 0x64, 0xC6, 0x67, 0xD2, 0xE1, 0x18, 0x6B, 0x73, 0x00, 0xC6, 0x67, 0xC2, 0xF1, 0x0C, 0x70, + 0x1E, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, 0x78, 0x00, 0xA9, 0x7E, 0x56, 0x0A, 0x0C, 0x70, + 0x46, 0x00, 0xF2, 0x24, 0xD4, 0x61, 0x18, 0x6B, 0x74, 0x00, 0x82, 0x30, 0xC6, 0x67, 0xC2, 0x10, + 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, 0x78, 0x00, 0xA9, 0x7E, 0x56, 0x0A, + 0x0C, 0x70, 0x32, 0x00, 0x99, 0x7E, 0x55, 0x0A, 0x0C, 0x70, 0x6E, 0x00, 0xF2, 0x42, 0x18, 0x6B, + 0x73, 0x00, 0xC6, 0x67, 0xC2, 0x10, 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, + 0x78, 0x00, 0xA9, 0x7E, 0x56, 0x0A, 0x0C, 0x70, 0x28, 0x00, 0x99, 0x7E, 0x55, 0x0A, 0x0C, 0x70, + 0x64, 0x00, 0xF2, 0x2F, 0x0C, 0x70, 0x1E, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, 0x78, 0x00, + 0xA9, 0x7E, 0x56, 0x0A, 0x0C, 0x70, 0x14, 0x00, 0xF2, 0x11, 0xC6, 0x67, 0xD2, 0xD2, 0x18, 0x6B, + 0x73, 0x00, 0xC6, 0x67, 0xC2, 0x10, 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, + 0x78, 0x00, 0xA9, 0x7E, 0x56, 0x0A, 0x0C, 0x70, 0x28, 0x00, 0x99, 0x7E, 0x55, 0x0A, 0x0C, 0x70, + 0x5A, 0x00, 0xF2, 0x0F, 0x0C, 0x70, 0x1E, 0x00, 0x99, 0x7E, 0x54, 0x0A, 0x0C, 0x70, 0x78, 0x00, + 0xA9, 0x7E, 0x56, 0x0A, 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x55, 0x0A, 0x0C, 0x70, 0x50, 0x00, + 0x28, 0x6E, 0x12, 0x00, 0xA9, 0x7E, 0x58, 0x0A, 0x04, 0x50, 0xA9, 0x60, 0x88, 0x1B, 0xB9, 0x51, + 0x04, 0x00, 0xB9, 0x51, 0x18, 0x00, 0xB9, 0x51, 0x14, 0x00, 0xB9, 0x51, 0x30, 0x00, 0xB9, 0x51, + 0x2C, 0x00, 0xB9, 0x51, 0x20, 0x00, 0x08, 0x50, 0x00, 0xFF, 0x0C, 0x70, 0x5F, 0x15, 0x2C, 0x50, + 0xFF, 0x0F, 0xB9, 0x71, 0x10, 0x00, 0x0C, 0xD0, 0xB4, 0x14, 0xB9, 0x51, 0x1C, 0x00, 0x18, 0x7E, + 0x74, 0x0C, 0x38, 0x51, 0x20, 0x00, 0xC6, 0x75, 0xCA, 0x3C, 0x02, 0x00, 0x38, 0x7E, 0x3C, 0x0C, + 0x38, 0x61, 0x04, 0x00, 0x5C, 0x70, 0xFF, 0x03, 0x63, 0x76, 0xD4, 0x71, 0x92, 0x06, 0x06, 0x26, + 0x6B, 0xB3, 0x01, 0x00, 0xFA, 0x20, 0x02, 0x00, 0x38, 0x81, 0x04, 0x00, 0xF0, 0x5D, 0x24, 0x81, + 0x06, 0x78, 0x57, 0x71, 0x26, 0x7E, 0x38, 0x67, 0x3C, 0x0C, 0x06, 0x76, 0x77, 0x76, 0x5C, 0x70, + 0xFF, 0x0F, 0x5C, 0x60, 0xFF, 0x0F, 0x32, 0x0C, 0x38, 0x41, 0x10, 0x00, 0x38, 0x21, 0x10, 0x00, + 0xA1, 0x7D, 0xA9, 0x6D, 0x02, 0x00, 0x04, 0x51, 0x34, 0x41, 0x91, 0x54, 0x91, 0x52, 0x70, 0x5D, + 0x36, 0x75, 0xB9, 0x71, 0x08, 0x00, 0x78, 0x7D, 0x02, 0x00, 0x38, 0x51, 0x08, 0x00, 0x36, 0x67, + 0xB9, 0x61, 0x0C, 0x00, 0x86, 0x65, 0xB9, 0x51, 0x24, 0x00, 0x32, 0x04, 0x16, 0x76, 0xB9, 0x71, + 0x24, 0x00, 0x38, 0x51, 0x0C, 0x00, 0x86, 0x65, 0xB9, 0x51, 0x28, 0x00, 0x32, 0x04, 0x16, 0x76, + 0xB9, 0x71, 0x28, 0x00, 0x38, 0x51, 0x24, 0x00, 0x38, 0x61, 0x28, 0x00, 0x43, 0x25, 0x43, 0x36, + 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0x98, 0x70, 0xB0, 0x1B, 0x06, 0xC2, 0x92, 0x0B, 0x38, 0x2E, + 0x54, 0x0A, 0x38, 0x3E, 0x58, 0x0A, 0x06, 0x4C, 0x0B, 0xB7, 0x01, 0x00, 0x06, 0xA2, 0x06, 0x92, + 0xF2, 0x2D, 0x28, 0x7E, 0x12, 0x00, 0x18, 0x6B, 0x74, 0x00, 0xC6, 0x67, 0xC2, 0x04, 0x26, 0x22, + 0x04, 0x33, 0xF2, 0x08, 0x18, 0x6B, 0x73, 0x00, 0xC6, 0x67, 0xC2, 0x0C, 0x26, 0x22, 0x26, 0x2C, + 0x04, 0x35, 0x8B, 0x16, 0x00, 0x00, 0x43, 0x42, 0x38, 0x3E, 0x58, 0x0A, 0x38, 0x2E, 0x54, 0x0A, + 0xF2, 0x0A, 0x06, 0x42, 0xF7, 0x4F, 0x26, 0x42, 0x38, 0x3E, 0x58, 0x0A, 0x38, 0x2E, 0x54, 0x0A, + 0xE7, 0x40, 0x43, 0x44, 0x0B, 0xB7, 0x01, 0x00, 0x06, 0x92, 0x38, 0x3E, 0x58, 0x0A, 0x38, 0x2E, + 0x54, 0x0A, 0x06, 0x4C, 0x0B, 0xB7, 0x01, 0x00, 0x06, 0xA2, 0x18, 0x7E, 0x8E, 0x06, 0xC4, 0x72, + 0xD2, 0x0F, 0x38, 0x70, 0x70, 0x1A, 0x78, 0x57, 0xBC, 0x00, 0xA9, 0x5E, 0x5C, 0x0A, 0xA9, 0x5E, + 0x5A, 0x0A, 0x78, 0x77, 0xBE, 0x00, 0xA9, 0x7E, 0x60, 0x0A, 0xA9, 0x7E, 0x5E, 0x0A, 0x57, 0x81, + 0x26, 0x8E, 0x38, 0x78, 0x3C, 0x0C, 0x77, 0x7E, 0x34, 0x71, 0x06, 0x47, 0x06, 0x57, 0x57, 0x41, + 0x57, 0x52, 0x26, 0x54, 0x3F, 0x77, 0x05, 0x00, 0x26, 0x77, 0x26, 0x7E, 0x28, 0x77, 0xAE, 0x04, + 0xCC, 0x70, 0x64, 0x00, 0x38, 0x70, 0x70, 0x1A, 0xC2, 0x2D, 0x18, 0x67, 0xB9, 0x00, 0x18, 0x87, + 0xB8, 0x00, 0x18, 0x77, 0xBA, 0x00, 0x26, 0x86, 0x26, 0x87, 0x28, 0x6E, 0x5E, 0x0A, 0x28, 0x7E, + 0x5A, 0x0A, 0x06, 0x29, 0x26, 0x76, 0x26, 0x77, 0x06, 0x67, 0x57, 0x62, 0xD7, 0x92, 0xD7, 0x21, + 0x3F, 0x77, 0x06, 0x00, 0x26, 0x29, 0x26, 0x27, 0x43, 0x22, 0x06, 0x38, 0x8B, 0x16, 0x00, 0x00, + 0x28, 0x6E, 0x60, 0x0A, 0x28, 0x7E, 0x5C, 0x0A, 0x43, 0x92, 0x26, 0x76, 0x26, 0x77, 0x06, 0x2A, + 0x06, 0x67, 0xD7, 0x21, 0xD7, 0xA2, 0x57, 0x62, 0x26, 0x2A, 0x3F, 0x77, 0x06, 0x00, 0x26, 0x27, + 0xF2, 0x51, 0x18, 0x57, 0xB9, 0x00, 0x18, 0x67, 0xB8, 0x00, 0x28, 0x3E, 0x5E, 0x0A, 0x18, 0x77, + 0xBA, 0x00, 0xB9, 0x51, 0x3C, 0x00, 0x2F, 0x85, 0x06, 0x00, 0x06, 0x25, 0x26, 0x87, 0xB9, 0x71, + 0x40, 0x00, 0xB9, 0x61, 0x38, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x61, 0x38, 0x00, 0x28, 0x3E, + 0x5A, 0x0A, 0x06, 0x42, 0x06, 0x26, 0xB9, 0x41, 0x34, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x71, + 0x40, 0x00, 0x38, 0x41, 0x34, 0x00, 0x06, 0x39, 0x26, 0x42, 0x06, 0x27, 0xB9, 0x41, 0x34, 0x00, + 0x4B, 0x14, 0x00, 0x00, 0x38, 0x41, 0x34, 0x00, 0x06, 0x38, 0x26, 0x24, 0x43, 0x22, 0x8B, 0x16, + 0x00, 0x00, 0x38, 0x51, 0x3C, 0x00, 0x28, 0x3E, 0x60, 0x0A, 0x43, 0x92, 0x06, 0x25, 0x4B, 0x14, + 0x00, 0x00, 0x38, 0x61, 0x38, 0x00, 0x28, 0x3E, 0x5C, 0x0A, 0x06, 0x52, 0x06, 0x26, 0xB9, 0x51, + 0x3C, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x51, 0x3C, 0x00, 0x38, 0x71, 0x40, 0x00, 0x26, 0x52, + 0x06, 0x3A, 0x06, 0x27, 0xB9, 0x51, 0x3C, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x51, 0x3C, 0x00, + 0x26, 0x25, 0x06, 0x38, 0x43, 0x22, 0x8B, 0x16, 0x00, 0x00, 0x43, 0x72, 0x38, 0x21, 0x24, 0x00, + 0xB9, 0x71, 0x40, 0x00, 0x06, 0x39, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x8B, 0x16, + 0x00, 0x00, 0x38, 0x71, 0x40, 0x00, 0x06, 0x82, 0x38, 0x21, 0x28, 0x00, 0x06, 0x37, 0x4B, 0x14, + 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x51, 0x18, 0x00, 0x38, 0x71, + 0x40, 0x00, 0xC6, 0x95, 0x06, 0xA2, 0x06, 0x69, 0x32, 0x02, 0x06, 0x65, 0x38, 0x51, 0x14, 0x00, + 0x43, 0x66, 0xC6, 0x75, 0xB9, 0x61, 0x18, 0x00, 0x06, 0x67, 0x32, 0x02, 0x06, 0x65, 0x38, 0x51, + 0x0C, 0x00, 0x43, 0x66, 0x15, 0x95, 0x38, 0x51, 0x10, 0x00, 0xB9, 0x61, 0x14, 0x00, 0x38, 0x61, + 0x08, 0x00, 0x34, 0x51, 0x15, 0x76, 0x60, 0x35, 0xF7, 0x7F, 0x33, 0x47, 0xC6, 0x34, 0xF7, 0x9F, + 0x33, 0x69, 0x92, 0x04, 0x04, 0x21, 0xB9, 0x21, 0x2C, 0x00, 0x38, 0x21, 0x10, 0x00, 0x60, 0x32, + 0xC6, 0x36, 0x92, 0x04, 0x04, 0x31, 0xB9, 0x31, 0x30, 0x00, 0x91, 0x45, 0x38, 0x51, 0x10, 0x00, + 0x06, 0x3D, 0x91, 0x65, 0x04, 0x44, 0x06, 0x21, 0xB9, 0x71, 0x40, 0x00, 0xEB, 0xE4, 0x04, 0x00, + 0xCB, 0x3D, 0x00, 0x00, 0x18, 0x6E, 0x8F, 0x06, 0x38, 0x71, 0x40, 0x00, 0xC4, 0x61, 0xD2, 0x16, + 0x28, 0x6E, 0x06, 0x03, 0x23, 0x22, 0xC6, 0x62, 0xC2, 0x11, 0x78, 0x6D, 0x08, 0x00, 0xC6, 0x68, + 0x02, 0x05, 0xB8, 0x51, 0x2C, 0x00, 0x82, 0x02, 0x06, 0x86, 0x78, 0x6D, 0x0A, 0x00, 0xC6, 0x6A, + 0x02, 0x05, 0xB8, 0x51, 0x30, 0x00, 0x82, 0x02, 0x06, 0xA6, 0xC4, 0x70, 0x20, 0x61, 0x92, 0x02, + 0x16, 0x88, 0x23, 0x88, 0x26, 0x86, 0xC4, 0x90, 0x23, 0x88, 0xA1, 0x81, 0x28, 0x71, 0x02, 0x00, + 0x92, 0x02, 0x16, 0xAA, 0x23, 0xAA, 0x26, 0xA7, 0xC4, 0xC0, 0x23, 0xAA, 0xA9, 0xA1, 0x02, 0x00, + 0x02, 0x16, 0xB8, 0x71, 0x08, 0x00, 0x04, 0x61, 0x12, 0x05, 0x16, 0x67, 0x66, 0x67, 0xE7, 0x6F, + 0x23, 0x66, 0xB8, 0x51, 0x0C, 0x00, 0x26, 0x68, 0xA1, 0x61, 0x04, 0x71, 0x12, 0x05, 0x16, 0x75, + 0x66, 0x75, 0xE7, 0x7F, 0x23, 0x77, 0x26, 0x7A, 0xA9, 0x71, 0x02, 0x00, 0x06, 0x21, 0xEB, 0x39, + 0x04, 0x00, 0x70, 0x7D, 0x70, 0xA1, 0x3F, 0x77, 0x0A, 0x00, 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, + 0xA9, 0x7D, 0x08, 0x00, 0x78, 0xC1, 0x02, 0x00, 0x78, 0x7D, 0x02, 0x00, 0x3F, 0x77, 0x0C, 0x00, + 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, 0x04, 0x24, 0x06, 0x3D, 0x04, 0x44, 0x26, 0x2D, 0xA9, 0x7D, + 0x0A, 0x00, 0xEB, 0xE4, 0x04, 0x00, 0x06, 0x2D, 0x06, 0x31, 0x04, 0x44, 0xEB, 0xE4, 0x04, 0x00, + 0x18, 0x7B, 0x2D, 0x00, 0x04, 0x62, 0xD6, 0x67, 0x82, 0x06, 0x0C, 0x60, 0x7F, 0x07, 0x3F, 0xAA, + 0x06, 0x00, 0x43, 0xAA, 0x04, 0x64, 0xD6, 0x67, 0x82, 0x06, 0x0C, 0x60, 0x37, 0x04, 0x3F, 0xCC, + 0x06, 0x00, 0x43, 0xCC, 0x38, 0x61, 0x04, 0x00, 0xD4, 0x71, 0x24, 0x61, 0x57, 0x61, 0x23, 0xAA, + 0x23, 0xCC, 0x26, 0x6E, 0x82, 0x11, 0x38, 0x76, 0x3C, 0x0C, 0x38, 0x51, 0x1C, 0x00, 0x1C, 0x20, + 0x00, 0x10, 0x5C, 0xA0, 0xFF, 0x0F, 0x56, 0x72, 0x66, 0x7A, 0x5C, 0xC0, 0xFF, 0x0F, 0x57, 0xC6, + 0x56, 0x75, 0x66, 0x7C, 0xF2, 0x10, 0x38, 0x76, 0x3C, 0x0C, 0x38, 0x51, 0x1C, 0x00, 0x1C, 0x20, + 0x00, 0x10, 0x5C, 0xC0, 0xFF, 0x0F, 0x56, 0x72, 0x66, 0x7C, 0x5C, 0xA0, 0xFF, 0x0F, 0x57, 0xA6, + 0x56, 0x75, 0x66, 0x7A, 0xB9, 0x76, 0x3C, 0x0C, 0x38, 0x71, 0x20, 0x00, 0x24, 0x71, 0x13, 0x77, + 0xB9, 0x71, 0x20, 0x00, 0x38, 0x61, 0x04, 0x00, 0x38, 0x71, 0x10, 0x00, 0x24, 0x61, 0xC4, 0x6D, + 0x24, 0x72, 0xB9, 0x61, 0x04, 0x00, 0xB9, 0x71, 0x10, 0x00, 0x24, 0xDC, 0x9A, 0xC1, 0xFD, 0xFF, + 0x0C, 0x20, 0x5E, 0x0A, 0x26, 0x2E, 0x14, 0x34, 0x26, 0x32, 0x04, 0x44, 0xEB, 0xE4, 0x04, 0x00, + 0x38, 0x61, 0x18, 0x00, 0x38, 0x71, 0x14, 0x00, 0xA9, 0x6E, 0x5A, 0x0A, 0xA9, 0x7E, 0x5C, 0x0A, + 0x58, 0xC1, 0x54, 0x00, 0x58, 0x81, 0x44, 0x00, 0x2C, 0x10, 0x64, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x98, 0x50, 0xED, 0x0B, 0x38, 0x60, 0x70, 0x1A, 0x34, 0x14, 0xB1, 0xF1, 0x18, 0x46, 0x8E, 0x00, + 0x18, 0x66, 0x8D, 0x00, 0x06, 0x72, 0x92, 0x05, 0x18, 0x50, 0xEE, 0x0B, 0x26, 0x65, 0x13, 0x66, + 0x98, 0x50, 0xB0, 0x1B, 0x82, 0x11, 0xB8, 0x50, 0x8C, 0x19, 0x92, 0x0E, 0x08, 0x50, 0x00, 0x80, + 0x2C, 0x50, 0x0C, 0xDC, 0x18, 0x35, 0x7A, 0x00, 0x18, 0x55, 0x7B, 0x00, 0x26, 0x63, 0x26, 0x54, + 0x13, 0x66, 0x13, 0x55, 0xF2, 0x02, 0x06, 0x54, 0x18, 0x37, 0x22, 0x00, 0xD4, 0x31, 0x18, 0x37, + 0x20, 0x00, 0x92, 0x14, 0x98, 0x67, 0x23, 0x00, 0x92, 0x10, 0xC4, 0x31, 0xC2, 0x0E, 0xC6, 0x45, + 0x92, 0x0C, 0x28, 0x67, 0x1C, 0x00, 0xCC, 0x60, 0x28, 0x00, 0xD2, 0x07, 0x28, 0x60, 0x0E, 0x0B, + 0xC4, 0x66, 0xD2, 0x03, 0x24, 0x52, 0x13, 0x55, 0x06, 0x65, 0xC6, 0x36, 0xB2, 0x06, 0x18, 0x67, + 0x23, 0x00, 0x04, 0x20, 0xC4, 0x61, 0x92, 0x1F, 0x04, 0x61, 0x99, 0x67, 0x23, 0x00, 0xF8, 0x67, + 0x0C, 0x00, 0x22, 0x13, 0xF8, 0x57, 0x0E, 0x00, 0x22, 0x10, 0xCC, 0x60, 0x31, 0x00, 0x12, 0x0D, + 0x70, 0x57, 0x2C, 0x60, 0x1D, 0x00, 0xC6, 0x65, 0x32, 0x08, 0x04, 0x3C, 0x06, 0x27, 0x26, 0x37, + 0x04, 0x44, 0xEB, 0xE4, 0x04, 0x00, 0x06, 0x72, 0x14, 0x61, 0xA9, 0x67, 0x0C, 0x00, 0xA9, 0x67, + 0x0E, 0x00, 0x04, 0x21, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x60, 0xB0, 0x1B, + 0x38, 0x70, 0x70, 0x1A, 0x18, 0x77, 0x8E, 0x00, 0x82, 0x0A, 0xB8, 0x60, 0x8C, 0x19, 0x92, 0x07, + 0x08, 0x60, 0x00, 0x80, 0x18, 0x66, 0x87, 0xDC, 0x26, 0x76, 0x13, 0x77, 0x18, 0x52, 0x01, 0x00, + 0x04, 0x61, 0xC6, 0x57, 0xB2, 0x02, 0x04, 0x60, 0x04, 0x21, 0x56, 0x26, 0xE1, 0xF0, 0x00, 0x00, + 0x0C, 0x50, 0xFC, 0x0A, 0x18, 0x60, 0x1A, 0x0E, 0x30, 0x75, 0x16, 0x66, 0x24, 0x71, 0xB1, 0x75, + 0xF7, 0x6F, 0xD7, 0x7A, 0x57, 0x6A, 0x6C, 0x70, 0x75, 0x00, 0x66, 0x76, 0x08, 0x60, 0x00, 0x30, + 0xB9, 0x76, 0x00, 0x01, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, 0x80, 0x02, 0x04, 0x30, + 0x0C, 0x40, 0xD2, 0x02, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x54, 0x05, + 0x04, 0x30, 0x0C, 0x40, 0xD2, 0x02, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x28, 0x08, + 0x04, 0x30, 0x0C, 0x40, 0xD2, 0x02, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x80, 0x28, 0x77, 0x6A, 0xDC, 0x34, 0x14, 0xB1, 0xF1, + 0xA9, 0x70, 0x0C, 0x0B, 0x4B, 0xF6, 0x01, 0x00, 0x08, 0x70, 0x00, 0x80, 0x18, 0x27, 0x08, 0xDC, + 0x6B, 0xFD, 0x03, 0x00, 0xEB, 0x7C, 0x02, 0x00, 0x0C, 0x20, 0x5F, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0xCB, 0x3E, 0x04, 0x00, 0x2B, 0x83, 0x02, 0x00, 0x4B, 0xB6, 0x01, 0x00, 0x8B, 0x7C, 0x02, 0x00, + 0xAB, 0x7C, 0x02, 0x00, 0x38, 0x70, 0x70, 0x1A, 0x04, 0x61, 0x30, 0x77, 0xD6, 0x67, 0x82, 0x04, + 0x0C, 0x50, 0x28, 0x08, 0xF2, 0x03, 0x0C, 0x50, 0x80, 0x02, 0xD4, 0x72, 0xB9, 0x50, 0x80, 0x1A, + 0x82, 0x04, 0x0C, 0x60, 0x28, 0x08, 0xF2, 0x03, 0x0C, 0x60, 0x80, 0x02, 0x30, 0xF1, 0xB9, 0x60, + 0x7C, 0x1A, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x8B, 0x7A, 0x04, 0x00, + 0xEB, 0xCA, 0x03, 0x00, 0x6B, 0x0C, 0x02, 0x00, 0x8B, 0x00, 0x04, 0x00, 0xEB, 0x0D, 0x02, 0x00, + 0xAB, 0xFB, 0x02, 0x00, 0x30, 0xF1, 0x99, 0x00, 0xD8, 0x0B, 0xA9, 0x00, 0xB0, 0x17, 0x99, 0x00, + 0xBC, 0x17, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x4B, 0x5A, 0x04, 0x00, + 0x30, 0xF1, 0x99, 0x00, 0xDA, 0x0B, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x0B, 0x37, 0x03, 0x00, 0xCB, 0x7C, 0x02, 0x00, 0x8B, 0xDF, 0x02, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x50, 0x19, 0x0E, 0x34, 0x14, 0xB1, 0xF1, 0x92, 0x08, 0x98, 0x70, + 0x88, 0x11, 0x92, 0x05, 0xB8, 0x70, 0x7C, 0x19, 0x82, 0x0D, 0xF2, 0x14, 0x18, 0x70, 0x8A, 0x11, + 0xCC, 0x70, 0xC7, 0x00, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x70, 0x8A, 0x11, 0xC4, 0x50, 0x92, 0x15, + 0xF2, 0xF2, 0x98, 0x70, 0x88, 0x11, 0x92, 0x03, 0xAB, 0x0D, 0x02, 0x00, 0xEB, 0x3E, 0x04, 0x00, + 0xF2, 0x0C, 0xC4, 0x72, 0x92, 0x04, 0x99, 0x00, 0xBC, 0x17, 0xF2, 0x07, 0xC4, 0x74, 0x92, 0x05, + 0xEB, 0x0D, 0x02, 0x00, 0x8B, 0x00, 0x04, 0x00, 0x18, 0x70, 0xDA, 0x0B, 0xCC, 0x70, 0xF9, 0x00, + 0xD2, 0x04, 0x24, 0x71, 0x99, 0x70, 0xDA, 0x0B, 0x38, 0x50, 0x38, 0x17, 0x06, 0x75, 0x18, 0x40, + 0x8B, 0x11, 0x77, 0x76, 0x54, 0x7F, 0xC6, 0x47, 0x32, 0x04, 0x99, 0x70, 0x8B, 0x11, 0xF2, 0x0A, + 0x06, 0x75, 0xDC, 0x70, 0x00, 0xF0, 0x92, 0x06, 0x98, 0x70, 0x88, 0x11, 0x92, 0x03, 0x99, 0x00, + 0x8B, 0x11, 0x98, 0x70, 0xAC, 0x17, 0x82, 0x0A, 0x18, 0x70, 0xD8, 0x0B, 0xCC, 0x70, 0xFF, 0x00, + 0x82, 0x07, 0x24, 0x71, 0x99, 0x70, 0xD8, 0x0B, 0xF2, 0x03, 0x99, 0x00, 0xD8, 0x0B, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x18, 0x70, 0xB4, 0x1B, 0x34, 0x14, 0xC4, 0x70, 0xB1, 0xF1, 0x04, 0x21, + 0x82, 0x15, 0x38, 0x70, 0x08, 0x0B, 0x1C, 0x60, 0x01, 0xF0, 0x56, 0x76, 0xB9, 0x70, 0x08, 0x0B, + 0x6B, 0x0C, 0x02, 0x00, 0xEB, 0xFD, 0x01, 0x00, 0xAB, 0x5B, 0x04, 0x00, 0x2B, 0x5E, 0x04, 0x00, + 0x99, 0x00, 0x52, 0x0C, 0x99, 0x00, 0x1A, 0x0E, 0x04, 0x20, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0x71, 0x04, 0x00, 0xC4, 0x21, 0x92, 0x09, 0x2B, 0x5E, 0x04, 0x00, + 0x2B, 0xAB, 0x02, 0x00, 0x8B, 0xBA, 0x01, 0x00, 0xCB, 0x76, 0x04, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x6B, 0x8E, 0x03, 0x00, 0x30, 0xF1, 0x04, 0x20, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0xEB, 0xFD, 0x01, 0x00, 0x0B, 0x01, 0x04, 0x00, + 0xEB, 0x45, 0x03, 0x00, 0x4B, 0xF7, 0x03, 0x00, 0xCB, 0x7F, 0x04, 0x00, 0xC4, 0x20, 0x92, 0x03, + 0x4B, 0x7B, 0x04, 0x00, 0x2B, 0x04, 0x02, 0x00, 0xC4, 0x21, 0x92, 0x1D, 0x98, 0x70, 0xDB, 0x0B, + 0x82, 0x04, 0x98, 0x70, 0xDC, 0x0B, 0x92, 0x0E, 0x8B, 0xF9, 0x03, 0x00, 0x18, 0x70, 0xB1, 0x1B, + 0xC4, 0x71, 0x92, 0x04, 0xCB, 0x45, 0x03, 0x00, 0xF2, 0x05, 0x4B, 0x88, 0x03, 0x00, 0x2B, 0x06, + 0x03, 0x00, 0x8B, 0x7B, 0x02, 0x00, 0xC4, 0x21, 0x92, 0x06, 0x98, 0x70, 0xDC, 0x0B, 0x92, 0x03, + 0x0B, 0x06, 0x02, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x34, 0x14, + 0xB1, 0xF1, 0x82, 0x10, 0x2B, 0xA3, 0x04, 0x00, 0x18, 0x70, 0xDC, 0x0B, 0xC4, 0x71, 0x92, 0x0A, + 0x38, 0x70, 0x08, 0x0B, 0x1C, 0x60, 0x01, 0x03, 0x56, 0x76, 0xB9, 0x70, 0x08, 0x0B, 0x0B, 0x06, + 0x02, 0x00, 0xAB, 0xFE, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, + 0x94, 0x0F, 0x04, 0x30, 0x0C, 0x40, 0xFC, 0x01, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, + 0x0C, 0x20, 0x90, 0x11, 0x04, 0x30, 0x04, 0x4F, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x99, 0x00, 0x8A, 0x11, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, + 0xE4, 0x0B, 0x04, 0x30, 0x04, 0x4C, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x04, 0x70, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x06, 0x2F, 0x67, 0x03, 0x00, + 0x24, 0x7C, 0xCC, 0x70, 0x9C, 0x00, 0x91, 0x06, 0x92, 0xF7, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, + 0x04, 0x71, 0x99, 0x32, 0x01, 0x00, 0x91, 0x72, 0x20, 0x75, 0x06, 0xE2, 0xA9, 0x72, 0x02, 0x00, + 0x28, 0x75, 0x02, 0x00, 0x06, 0x34, 0xA9, 0x72, 0x04, 0x00, 0x06, 0x24, 0x4B, 0x14, 0x00, 0x00, + 0xB9, 0x2E, 0x08, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0xB9, 0x20, 0x84, 0x1A, + 0x99, 0x30, 0xBD, 0x1B, 0x99, 0x40, 0xBC, 0x1B, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x34, 0x00, + 0xD9, 0x81, 0x14, 0x00, 0xD9, 0xC1, 0x24, 0x00, 0x06, 0xB2, 0xB1, 0x31, 0xB9, 0x41, 0x04, 0x00, + 0x04, 0x70, 0x2F, 0x67, 0x0B, 0x00, 0x24, 0x78, 0xCC, 0x70, 0x48, 0x05, 0xB1, 0x06, 0x92, 0xFA, + 0x30, 0xE1, 0x04, 0xD0, 0x06, 0x9D, 0x06, 0xAD, 0x90, 0x7E, 0x92, 0x07, 0x04, 0xE0, 0x06, 0xCE, + 0x06, 0x9E, 0x06, 0x8E, 0xFA, 0x98, 0x00, 0x00, 0x30, 0x61, 0xB8, 0x76, 0x08, 0x00, 0x82, 0x05, + 0x38, 0x7E, 0x08, 0x00, 0xB9, 0x70, 0x84, 0x1A, 0x38, 0xC1, 0x04, 0x00, 0x04, 0x80, 0x90, 0x7C, + 0x82, 0x63, 0x98, 0x70, 0xBD, 0x1B, 0x92, 0x03, 0xC6, 0x98, 0x82, 0x59, 0x78, 0x7C, 0x02, 0x00, + 0x78, 0x2E, 0x02, 0x00, 0x78, 0x6E, 0x04, 0x00, 0x36, 0x27, 0x78, 0x7C, 0x04, 0x00, 0xB9, 0x51, + 0x10, 0x00, 0x06, 0x32, 0x3F, 0x77, 0x06, 0x00, 0xB9, 0x71, 0x08, 0x00, 0x4B, 0x14, 0x00, 0x00, + 0x38, 0x71, 0x08, 0x00, 0x06, 0x62, 0x06, 0x37, 0x06, 0x27, 0xB9, 0x61, 0x0C, 0x00, 0x4B, 0x14, + 0x00, 0x00, 0x38, 0x51, 0x10, 0x00, 0x38, 0x61, 0x0C, 0x00, 0x38, 0x70, 0x84, 0x1A, 0x26, 0x62, + 0xC6, 0x76, 0xA2, 0x35, 0x06, 0x7B, 0x04, 0x40, 0xC6, 0x4D, 0x04, 0x21, 0x26, 0x24, 0x82, 0x07, + 0x24, 0x78, 0x14, 0x38, 0x26, 0x37, 0x30, 0x33, 0xC6, 0x36, 0xC2, 0x27, 0xD7, 0x21, 0x14, 0x78, + 0x26, 0x72, 0x26, 0x7B, 0x3F, 0x44, 0x0D, 0x00, 0x06, 0x37, 0x26, 0x2B, 0xD7, 0x41, 0xB9, 0x51, + 0x10, 0x00, 0xB9, 0x61, 0x0C, 0x00, 0xB9, 0x71, 0x08, 0x00, 0x0C, 0xF0, 0x00, 0x01, 0xF1, 0xF0, + 0x38, 0x61, 0x0C, 0x00, 0x38, 0x71, 0x08, 0x00, 0x24, 0xD1, 0xB1, 0x67, 0x18, 0x6E, 0x01, 0x00, + 0x24, 0xA1, 0x99, 0x67, 0x04, 0x00, 0x18, 0x6C, 0x01, 0x00, 0x13, 0xDD, 0x99, 0x67, 0x05, 0x00, + 0x13, 0xAA, 0x38, 0x51, 0x10, 0x00, 0xF2, 0x03, 0x13, 0x42, 0xF2, 0xCF, 0x24, 0x81, 0x13, 0x88, + 0xC4, 0x8D, 0x24, 0xCC, 0x92, 0x9D, 0x24, 0x91, 0x13, 0x99, 0xC4, 0x9D, 0x24, 0xEC, 0x92, 0x85, + 0xF2, 0x86, 0x06, 0x39, 0xD7, 0x31, 0x2F, 0x23, 0x0B, 0x00, 0x18, 0x42, 0x04, 0x00, 0x04, 0x71, + 0x06, 0xF7, 0x53, 0xF4, 0x06, 0x4F, 0x06, 0xFC, 0xD6, 0xF4, 0x82, 0x18, 0x34, 0xA1, 0x3F, 0x49, + 0x0A, 0x00, 0x24, 0x38, 0x26, 0x3B, 0xD7, 0x41, 0xB9, 0x51, 0x10, 0x00, 0xB9, 0x61, 0x0C, 0x00, + 0x0C, 0xF0, 0x28, 0x01, 0xF1, 0xF0, 0x38, 0x51, 0x10, 0x00, 0x38, 0x61, 0x0C, 0x00, 0x13, 0xAA, + 0x24, 0x81, 0x13, 0x88, 0xC6, 0x8D, 0x92, 0xDE, 0xF2, 0x14, 0x18, 0xF2, 0x05, 0x00, 0x53, 0x7F, + 0x06, 0xFE, 0xD6, 0xF7, 0x92, 0xE4, 0x98, 0x30, 0xBC, 0x1B, 0x92, 0x02, 0x66, 0xC4, 0x98, 0x30, + 0xBD, 0x1B, 0x66, 0xE7, 0x92, 0x03, 0x66, 0x74, 0x66, 0xC7, 0x24, 0x91, 0x13, 0x99, 0xF2, 0xE9, + 0x58, 0xC1, 0x24, 0x00, 0x06, 0x2A, 0x58, 0x81, 0x14, 0x00, 0x2C, 0x10, 0x34, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x30, 0x00, 0xD9, 0xC1, 0x20, 0x00, 0xD9, 0x81, 0x10, 0x00, 0x0C, 0xE0, 0xFC, 0x0A, + 0x18, 0x4E, 0x8C, 0x06, 0x04, 0x60, 0xC4, 0x49, 0xDA, 0xC1, 0x00, 0x00, 0x0C, 0x50, 0xB2, 0x0F, + 0x06, 0xD6, 0x90, 0x75, 0x82, 0x07, 0x24, 0xD1, 0x13, 0xDD, 0xC4, 0xDD, 0x2C, 0x50, 0x26, 0x00, + 0x92, 0xF9, 0x06, 0x72, 0xD7, 0x72, 0x2F, 0x97, 0x0E, 0x00, 0x28, 0x69, 0x5C, 0x01, 0x0C, 0x50, + 0x28, 0x08, 0x26, 0x66, 0x26, 0x65, 0x70, 0x36, 0x28, 0x5E, 0x08, 0x03, 0x04, 0x60, 0xC6, 0x35, + 0x2A, 0xA5, 0x00, 0x00, 0x04, 0x61, 0x06, 0xAD, 0x06, 0xBD, 0x26, 0x6D, 0x57, 0xA1, 0x57, 0xB2, + 0x13, 0x66, 0x2F, 0xCB, 0x0A, 0x00, 0xB1, 0x61, 0x36, 0xCD, 0x30, 0x51, 0x26, 0xCC, 0x26, 0xCE, + 0x0C, 0x60, 0x1C, 0x00, 0x26, 0x6C, 0x99, 0x56, 0x9A, 0x04, 0x0C, 0x80, 0x98, 0x04, 0x0C, 0x50, + 0x70, 0x01, 0x26, 0x8C, 0x26, 0x59, 0x24, 0x41, 0x99, 0x4E, 0x8C, 0x06, 0x06, 0x35, 0x04, 0x44, + 0x06, 0x28, 0xB9, 0x61, 0x0C, 0x00, 0xB9, 0x71, 0x08, 0x00, 0xB9, 0x51, 0x04, 0x00, 0xEB, 0xE4, + 0x04, 0x00, 0x38, 0x51, 0x04, 0x00, 0x0C, 0x20, 0xA8, 0x04, 0x06, 0x35, 0x26, 0x2C, 0x04, 0x44, + 0xEB, 0xE4, 0x04, 0x00, 0x0C, 0x20, 0x9C, 0x04, 0x26, 0x2C, 0x06, 0x38, 0x04, 0x44, 0xEB, 0xE4, + 0x04, 0x00, 0x0C, 0x20, 0xA0, 0x04, 0x26, 0x2C, 0x06, 0x38, 0x04, 0x44, 0xEB, 0xE4, 0x04, 0x00, + 0x38, 0x61, 0x0C, 0x00, 0x28, 0x59, 0x78, 0x01, 0x2C, 0xC0, 0x20, 0x00, 0x99, 0x56, 0x9B, 0x04, + 0x98, 0x6E, 0x8D, 0x06, 0x38, 0x71, 0x08, 0x00, 0x92, 0x0C, 0x04, 0x62, 0x99, 0x6C, 0x9A, 0x04, + 0x38, 0x6E, 0x0C, 0x00, 0x08, 0x50, 0x00, 0x01, 0x66, 0x65, 0xB9, 0x6E, 0x0C, 0x00, 0xF2, 0x04, + 0x04, 0x61, 0x99, 0x6C, 0x9A, 0x04, 0x2F, 0xCB, 0x0A, 0x00, 0x36, 0xCD, 0x26, 0xCC, 0x26, 0x7E, + 0x26, 0xCE, 0x28, 0x77, 0x5E, 0x01, 0x0C, 0x60, 0x20, 0x00, 0x26, 0x6C, 0x04, 0x51, 0x0C, 0x90, + 0x14, 0x00, 0x99, 0x06, 0x9B, 0x04, 0x99, 0x56, 0x98, 0x04, 0x99, 0x06, 0x99, 0x04, 0x26, 0x9C, + 0xA9, 0x79, 0x98, 0x04, 0x0C, 0x70, 0xF4, 0x01, 0xA9, 0x7C, 0xB4, 0x04, 0x0C, 0x70, 0x18, 0x00, + 0x26, 0x7C, 0xA9, 0x09, 0x9A, 0x04, 0x0C, 0x20, 0xA4, 0x04, 0x0C, 0x30, 0x98, 0x04, 0xA9, 0x07, + 0x98, 0x04, 0xA9, 0x07, 0x9A, 0x04, 0x26, 0x2C, 0x26, 0x3C, 0x04, 0x44, 0xEB, 0xE4, 0x04, 0x00, + 0x18, 0x79, 0x98, 0x04, 0xC4, 0x71, 0xD2, 0x0B, 0x18, 0x79, 0x99, 0x04, 0x34, 0x72, 0x13, 0x77, + 0xC4, 0x7A, 0xD2, 0x05, 0x04, 0x75, 0x99, 0x7C, 0xBC, 0x04, 0xF2, 0x08, 0x26, 0xBA, 0x36, 0xBD, + 0x26, 0xBB, 0x26, 0xBE, 0x04, 0x71, 0x99, 0x7B, 0xBC, 0x04, 0x38, 0x6E, 0x88, 0x06, 0x04, 0x71, + 0x53, 0x7D, 0x66, 0x76, 0x30, 0x61, 0xB9, 0x7E, 0x88, 0x06, 0x58, 0xC1, 0x20, 0x00, 0x58, 0x81, + 0x10, 0x00, 0x06, 0x26, 0x2C, 0x10, 0x30, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x60, 0x06, 0x52, + 0x63, 0x56, 0xD4, 0x51, 0x13, 0x76, 0x92, 0x05, 0x24, 0x61, 0xC4, 0x64, 0x92, 0xF9, 0x06, 0x76, + 0x0C, 0x60, 0xFC, 0x0A, 0x18, 0x56, 0xA1, 0x06, 0x04, 0x41, 0x24, 0x51, 0x99, 0x56, 0xA1, 0x06, + 0x2F, 0x57, 0x07, 0x00, 0x26, 0x57, 0x26, 0x56, 0x26, 0x47, 0x99, 0x45, 0x94, 0x06, 0x04, 0x41, + 0x99, 0x45, 0x95, 0x06, 0x99, 0x05, 0x96, 0x06, 0x04, 0x51, 0x53, 0x57, 0x18, 0x76, 0xA0, 0x06, + 0x66, 0x57, 0x99, 0x56, 0xA0, 0x06, 0xE1, 0xF0, 0x38, 0x70, 0x70, 0x1A, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x18, 0xF7, 0x8F, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0x18, 0xA7, + 0x24, 0x03, 0x18, 0x37, 0xA2, 0x06, 0xC4, 0xA0, 0x06, 0xE7, 0x92, 0x12, 0xC4, 0x30, 0x92, 0x1A, + 0x18, 0x67, 0x8D, 0x06, 0x06, 0x23, 0xC4, 0x60, 0x9A, 0x9E, 0x00, 0x00, 0xF8, 0x67, 0xB4, 0x0C, + 0x0A, 0x9A, 0x00, 0x00, 0x34, 0x61, 0xA9, 0x67, 0xB4, 0x0C, 0xFA, 0x95, 0x00, 0x00, 0xC4, 0xA1, + 0x92, 0x09, 0xC4, 0x30, 0x92, 0x07, 0x18, 0x77, 0x8C, 0x06, 0x06, 0x23, 0xC4, 0x71, 0x8A, 0x8B, + 0x00, 0x00, 0xC4, 0x30, 0x99, 0x0E, 0xA1, 0x06, 0x06, 0x2E, 0x82, 0x0B, 0x04, 0xC0, 0x04, 0xDC, + 0x26, 0xDE, 0x06, 0x7E, 0x06, 0x5C, 0x06, 0x4C, 0x04, 0xB1, 0x1C, 0x90, 0x10, 0x00, 0xF2, 0x12, + 0x0C, 0x20, 0x90, 0x11, 0x04, 0x4C, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x2E, 0x23, 0x03, + 0xEB, 0x2B, 0x02, 0x00, 0xF2, 0x68, 0x98, 0x87, 0x94, 0x06, 0x92, 0x07, 0x24, 0x73, 0xC6, 0x7D, + 0x82, 0x21, 0xC6, 0x43, 0xA2, 0xF9, 0xF2, 0x1E, 0x18, 0x6E, 0x23, 0x03, 0x34, 0x81, 0x63, 0x68, + 0xD4, 0x61, 0x82, 0x15, 0x98, 0x67, 0x96, 0x06, 0x82, 0x06, 0x99, 0x07, 0x96, 0x06, 0x99, 0x97, + 0x95, 0x06, 0xF2, 0x09, 0x18, 0x67, 0x95, 0x06, 0xCC, 0x60, 0xEF, 0x00, 0xD2, 0x04, 0x24, 0x61, + 0x99, 0x67, 0x95, 0x06, 0x06, 0x6B, 0x53, 0x68, 0x66, 0x56, 0x66, 0xC6, 0x24, 0x41, 0x13, 0x44, + 0xF2, 0xDE, 0x04, 0x60, 0x99, 0x3E, 0xA1, 0x06, 0x06, 0x72, 0x06, 0x46, 0x04, 0xD1, 0xC6, 0x63, + 0xB2, 0x22, 0x98, 0x27, 0x94, 0x06, 0x82, 0x1B, 0x06, 0x2D, 0x53, 0x24, 0xD6, 0x25, 0x92, 0x15, + 0x18, 0x27, 0x96, 0x06, 0xC6, 0x2F, 0xB2, 0x05, 0x24, 0x21, 0x99, 0x27, 0x96, 0x06, 0xF2, 0x0D, + 0x98, 0x2E, 0xA1, 0x06, 0x82, 0x04, 0x34, 0x21, 0x99, 0x2E, 0xA1, 0x06, 0x99, 0x07, 0x94, 0x06, + 0x99, 0x07, 0x95, 0x06, 0x99, 0x07, 0x96, 0x06, 0x24, 0x61, 0x13, 0x66, 0x24, 0x41, 0xC4, 0x44, + 0x24, 0x73, 0x92, 0xDE, 0x04, 0xB0, 0x06, 0xDB, 0x04, 0x91, 0xC6, 0xBA, 0xB2, 0x14, 0x18, 0x7E, + 0x23, 0x03, 0x63, 0x7D, 0xD4, 0x71, 0x82, 0x0C, 0x06, 0x7C, 0x73, 0x7D, 0xD4, 0x71, 0x92, 0x06, + 0x06, 0x29, 0x53, 0x2D, 0x13, 0x22, 0xEB, 0x2B, 0x02, 0x00, 0x24, 0xB1, 0x13, 0xBB, 0x24, 0xD1, + 0xC4, 0xD4, 0x92, 0xEC, 0x78, 0x7E, 0xB4, 0x0C, 0x04, 0x21, 0xC4, 0x70, 0x02, 0x04, 0x26, 0x72, + 0xA9, 0x7E, 0xB4, 0x0C, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x06, 0xE2, 0x78, 0x7E, 0x04, 0x00, + 0x70, 0x22, 0x36, 0x27, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x78, 0xDE, 0x02, 0x00, 0x78, 0x7E, + 0x06, 0x00, 0x36, 0xD7, 0xC4, 0xD0, 0x32, 0x02, 0x16, 0xDD, 0x06, 0x32, 0x4B, 0x14, 0x00, 0x00, + 0x06, 0x3D, 0x06, 0xC2, 0x06, 0x2D, 0x4B, 0x14, 0x00, 0x00, 0x26, 0x2C, 0x0C, 0x30, 0x00, 0x01, + 0x0C, 0xF0, 0xE8, 0x01, 0xF1, 0xF0, 0x86, 0xD2, 0x8A, 0xE3, 0x00, 0x00, 0x0C, 0xA0, 0xFC, 0x0A, + 0x38, 0x6A, 0x0C, 0x00, 0x08, 0x70, 0x02, 0x00, 0x2C, 0x70, 0x00, 0x03, 0xD6, 0x67, 0x82, 0x05, + 0x0C, 0x70, 0xF4, 0x01, 0xFA, 0xD3, 0x00, 0x00, 0x98, 0x3E, 0x21, 0x00, 0x82, 0x0F, 0x28, 0x7E, + 0x1A, 0x00, 0xC4, 0x7A, 0xCA, 0xCD, 0x00, 0x00, 0x28, 0x2E, 0x1C, 0x00, 0x24, 0x31, 0x4B, 0x14, + 0x00, 0x00, 0xA9, 0x2E, 0x1C, 0x00, 0xFA, 0xC4, 0x00, 0x00, 0x78, 0x2E, 0x18, 0x00, 0x04, 0x31, + 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0xA8, 0x8E, 0x16, 0x00, 0x06, 0xC2, 0x2F, 0xBD, 0x0D, 0x00, + 0x92, 0x04, 0xA9, 0xDE, 0x16, 0x00, 0xF2, 0x14, 0x2F, 0x7D, 0x0B, 0x00, 0x06, 0x67, 0x57, 0x62, + 0x3F, 0x27, 0x06, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x26, 0x22, 0xAB, 0x15, 0x00, 0x00, 0x06, 0x92, + 0x04, 0x3A, 0x06, 0x28, 0x8B, 0x16, 0x00, 0x00, 0x26, 0x29, 0xA9, 0x2E, 0x16, 0x00, 0xA8, 0x7E, + 0x16, 0x00, 0x92, 0x04, 0x04, 0x71, 0xA9, 0x7E, 0x16, 0x00, 0x06, 0x2D, 0xD7, 0x21, 0x0C, 0x30, + 0x64, 0x00, 0x26, 0x2B, 0xAB, 0x15, 0x00, 0x00, 0x28, 0x7E, 0x1A, 0x00, 0x06, 0x92, 0x2F, 0x67, + 0x07, 0x00, 0x26, 0x76, 0x06, 0x67, 0x57, 0x62, 0x3F, 0x27, 0x06, 0x00, 0x26, 0x22, 0x0C, 0x30, + 0x64, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x26, 0x29, 0xA3, 0x22, 0x82, 0x04, 0xA9, 0x2E, 0x1A, 0x00, + 0xF2, 0x04, 0x04, 0x71, 0xA9, 0x7E, 0x1A, 0x00, 0x26, 0xBD, 0xD7, 0xB1, 0x2F, 0x2D, 0x0B, 0x00, + 0x26, 0x22, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x28, 0x7E, 0x18, 0x00, 0xE7, 0x70, + 0x26, 0x27, 0xA3, 0x72, 0x92, 0x02, 0x04, 0x71, 0xA9, 0x7E, 0x18, 0x00, 0x28, 0xDE, 0x18, 0x00, + 0xC6, 0xDC, 0xA2, 0x0B, 0x2F, 0x7D, 0x0D, 0x00, 0x26, 0x7D, 0x06, 0x67, 0xD7, 0x62, 0x2F, 0x26, + 0x07, 0x00, 0x26, 0x2D, 0x06, 0x3C, 0xF2, 0x0A, 0x2F, 0x7C, 0x0C, 0x00, 0x26, 0x7C, 0x06, 0x67, + 0xD7, 0x62, 0x2F, 0x26, 0x07, 0x00, 0x26, 0x2C, 0x06, 0x3D, 0xAB, 0x15, 0x00, 0x00, 0x06, 0x3D, + 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x28, 0xCE, 0x1A, 0x00, + 0x28, 0x7E, 0x16, 0x00, 0x26, 0xCD, 0x26, 0xC7, 0x26, 0xC2, 0x06, 0x3D, 0x06, 0x2D, 0x4B, 0x14, + 0x00, 0x00, 0x06, 0x3C, 0x4B, 0x14, 0x00, 0x00, 0x08, 0x30, 0x03, 0x00, 0x2C, 0x30, 0x90, 0xD0, + 0xAB, 0x15, 0x00, 0x00, 0x2F, 0xBC, 0x0D, 0x00, 0xB8, 0x60, 0x8C, 0x19, 0x3F, 0x22, 0x0B, 0x00, + 0x23, 0x22, 0xA9, 0x2E, 0x1C, 0x00, 0x82, 0x07, 0xCC, 0x20, 0x77, 0x00, 0x0C, 0x60, 0x78, 0x00, + 0xC2, 0x07, 0xF2, 0x08, 0xCC, 0x20, 0x27, 0x00, 0xD2, 0x05, 0x0C, 0x60, 0x28, 0x00, 0xA9, 0x6E, + 0x1C, 0x00, 0xB8, 0x60, 0x8C, 0x19, 0x92, 0x0D, 0x98, 0x60, 0xBE, 0x1B, 0x82, 0x0A, 0x28, 0x6E, + 0x1C, 0x00, 0xCC, 0x60, 0x9F, 0x00, 0xD2, 0x05, 0x0C, 0x60, 0xA0, 0x00, 0xA9, 0x6E, 0x1C, 0x00, + 0xB8, 0x70, 0x8C, 0x19, 0x92, 0x0D, 0x98, 0x7A, 0xE0, 0x00, 0x92, 0x0A, 0x28, 0x7E, 0x1C, 0x00, + 0xCC, 0x70, 0xC7, 0x00, 0xD2, 0x05, 0x0C, 0x70, 0xC8, 0x00, 0xA9, 0x7E, 0x1C, 0x00, 0x58, 0xC1, + 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0x04, 0xC4, 0x06, 0xE2, 0x26, 0xC2, 0x04, 0x28, 0x06, 0xD3, 0x04, 0x44, + 0x06, 0x3C, 0x26, 0x2E, 0xD1, 0x81, 0xEB, 0xE4, 0x04, 0x00, 0x06, 0x2C, 0x06, 0x3E, 0x04, 0x44, + 0x0C, 0xC0, 0x14, 0x00, 0xEB, 0xE4, 0x04, 0x00, 0x26, 0xCD, 0x06, 0x2E, 0x06, 0x3C, 0x04, 0x44, + 0xEB, 0xE4, 0x04, 0x00, 0x0C, 0xB0, 0xFC, 0x0A, 0x18, 0x7B, 0x8C, 0x06, 0xC4, 0x71, 0x92, 0x49, + 0x18, 0x7E, 0x24, 0x00, 0xC4, 0x73, 0xD2, 0x45, 0x70, 0x2E, 0x78, 0x7E, 0x04, 0x00, 0x36, 0x27, + 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x78, 0x6E, 0x02, 0x00, 0x78, 0x7E, 0x06, 0x00, 0x43, 0x22, + 0x3F, 0x77, 0x06, 0x00, 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, 0x06, 0x32, 0x43, 0x97, 0x4B, 0x14, + 0x00, 0x00, 0x06, 0xA2, 0x06, 0x39, 0x06, 0x29, 0x4B, 0x14, 0x00, 0x00, 0x26, 0x2A, 0x0C, 0x30, + 0x00, 0x01, 0x0C, 0xF0, 0xE8, 0x01, 0xF1, 0xF0, 0x18, 0x7E, 0x24, 0x00, 0xCC, 0x20, 0x19, 0x00, + 0x24, 0x71, 0x13, 0x77, 0x99, 0x7E, 0x24, 0x00, 0xD2, 0x1C, 0xC4, 0x74, 0x92, 0x1D, 0x70, 0x2E, + 0x78, 0x7E, 0x04, 0x00, 0x04, 0x33, 0x26, 0x27, 0x78, 0x7E, 0x08, 0x00, 0x26, 0x27, 0x8B, 0x16, + 0x00, 0x00, 0xA1, 0x2E, 0x78, 0x7E, 0x06, 0x00, 0x78, 0x2E, 0x02, 0x00, 0x04, 0x33, 0x26, 0x27, + 0x78, 0x7E, 0x0A, 0x00, 0x26, 0x27, 0x8B, 0x16, 0x00, 0x00, 0xA9, 0x2E, 0x02, 0x00, 0xF2, 0x04, + 0x04, 0x75, 0x99, 0x7E, 0x24, 0x00, 0x0C, 0x20, 0x10, 0x00, 0x26, 0x2E, 0x06, 0x3C, 0x04, 0x44, + 0xEB, 0xE4, 0x04, 0x00, 0x28, 0x7D, 0x1C, 0x00, 0x99, 0x7E, 0x1F, 0x00, 0x98, 0x7E, 0x21, 0x00, + 0x82, 0x04, 0x99, 0x0E, 0x21, 0x00, 0xF2, 0x15, 0x18, 0x7E, 0x20, 0x00, 0xCC, 0x70, 0xEF, 0x00, + 0xD2, 0x15, 0x06, 0x2E, 0x0B, 0xED, 0x01, 0x00, 0xC4, 0x20, 0x92, 0x0B, 0x20, 0x7D, 0x0C, 0x60, + 0x28, 0x08, 0x26, 0x77, 0x26, 0x76, 0x70, 0x67, 0x28, 0x7B, 0x08, 0x03, 0xC6, 0x67, 0x02, 0x06, + 0x18, 0x7E, 0x20, 0x00, 0x24, 0x71, 0x99, 0x7E, 0x20, 0x00, 0x06, 0x2E, 0x0B, 0x3A, 0x02, 0x00, + 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0xB8, 0x06, + 0xD9, 0xC1, 0xA8, 0x06, 0xD9, 0x81, 0x98, 0x06, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0xCE, 0x8D, 0x06, + 0x38, 0x70, 0x70, 0x1A, 0xC4, 0xC2, 0x18, 0x87, 0x8F, 0x00, 0x92, 0x2C, 0x78, 0x5E, 0xE8, 0x00, + 0x78, 0x6E, 0xEC, 0x00, 0x3F, 0x66, 0x05, 0x00, 0xC4, 0x60, 0x32, 0x02, 0x16, 0x66, 0x99, 0x0E, + 0xF2, 0x00, 0x28, 0x47, 0x92, 0x00, 0x78, 0x5E, 0xEE, 0x00, 0x43, 0x36, 0xC6, 0x34, 0x78, 0x6E, + 0xEA, 0x00, 0x32, 0x18, 0x36, 0x65, 0xC4, 0x60, 0x32, 0x02, 0x16, 0x66, 0x28, 0x57, 0x94, 0x00, + 0x43, 0x66, 0xC6, 0x65, 0x32, 0x04, 0x18, 0x67, 0x99, 0x00, 0xF2, 0x0A, 0x28, 0x57, 0x96, 0x00, + 0xC6, 0x65, 0x32, 0x04, 0x18, 0x67, 0x9A, 0x00, 0xF2, 0x03, 0x18, 0x67, 0x9B, 0x00, 0x99, 0x6E, + 0xF2, 0x00, 0x18, 0x6E, 0x8E, 0x06, 0x18, 0x77, 0x98, 0x00, 0xC6, 0x67, 0xB2, 0x07, 0x98, 0x7E, + 0xF0, 0x00, 0x82, 0x04, 0x04, 0x71, 0x99, 0x7E, 0xF1, 0x00, 0x98, 0x70, 0xB0, 0x1B, 0x82, 0x0C, + 0x08, 0x70, 0x00, 0x80, 0x18, 0x77, 0x88, 0xDC, 0xB8, 0x60, 0x8C, 0x19, 0x26, 0x87, 0x13, 0x88, + 0x82, 0x03, 0x26, 0x87, 0x13, 0x88, 0x38, 0x7E, 0x0C, 0x00, 0xDC, 0x70, 0x00, 0xF0, 0x82, 0x06, + 0x6B, 0x0C, 0x02, 0x00, 0x04, 0xC0, 0xFA, 0x04, 0x02, 0x00, 0x98, 0xAE, 0x1F, 0x03, 0x92, 0x0C, + 0xC4, 0xC0, 0x92, 0x0A, 0xF8, 0x7E, 0xB4, 0x0C, 0x0A, 0xFB, 0x01, 0x00, 0x34, 0x71, 0xA9, 0x7E, + 0xB4, 0x0C, 0xFA, 0xF6, 0x01, 0x00, 0xC4, 0xC0, 0x99, 0x0E, 0x8C, 0x06, 0x92, 0x10, 0x0C, 0x20, + 0x94, 0x0F, 0x06, 0x3C, 0x0C, 0x40, 0xEE, 0x01, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0xC6, 0xCA, + 0x32, 0x58, 0x13, 0x2C, 0x8B, 0x1E, 0x02, 0x00, 0x24, 0xC1, 0xF2, 0xFA, 0x04, 0xD0, 0x04, 0x62, + 0x06, 0xBD, 0x06, 0x7D, 0xB9, 0x61, 0x80, 0x06, 0xC6, 0xA7, 0xC2, 0x1C, 0x38, 0x61, 0x80, 0x06, + 0xC4, 0xA1, 0x34, 0x61, 0x13, 0x66, 0xB9, 0x61, 0x80, 0x06, 0x9A, 0xAC, 0x00, 0x00, 0xC4, 0xC1, + 0x9A, 0xA9, 0x00, 0x00, 0x18, 0x6E, 0xDF, 0x00, 0xC4, 0x61, 0x92, 0x4D, 0x18, 0x6E, 0xE0, 0x00, + 0xC4, 0x61, 0x92, 0x49, 0x38, 0xBE, 0x88, 0x06, 0x06, 0xDA, 0x06, 0x7A, 0xB8, 0x61, 0x80, 0x06, + 0x92, 0xE4, 0x04, 0x90, 0x99, 0xCE, 0x8C, 0x06, 0x06, 0x79, 0x04, 0x51, 0xC6, 0x7A, 0x32, 0x14, + 0x06, 0x6D, 0x73, 0x67, 0xD4, 0x61, 0x9A, 0x65, 0x01, 0x00, 0x13, 0x27, 0xB9, 0x51, 0x8C, 0x06, + 0xB9, 0x71, 0x94, 0x06, 0x8B, 0x1E, 0x02, 0x00, 0x86, 0x22, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x71, + 0x94, 0x06, 0x9A, 0x51, 0x01, 0x00, 0x04, 0x70, 0x08, 0x60, 0xFF, 0xFE, 0x0C, 0xD0, 0x94, 0x0F, + 0x06, 0xA7, 0x2C, 0x60, 0xFF, 0xFF, 0x2F, 0x59, 0x0C, 0x00, 0xC6, 0x75, 0x32, 0x0A, 0x98, 0x5D, + 0x1E, 0x00, 0x9A, 0x4A, 0x01, 0x00, 0x24, 0xA1, 0xC4, 0xAD, 0x2C, 0xD0, 0x26, 0x00, 0x92, 0xF4, + 0x98, 0x7E, 0x8C, 0x06, 0x92, 0x08, 0x0C, 0x70, 0x14, 0x00, 0xA9, 0x7E, 0xB4, 0x0C, 0x04, 0xC1, + 0xFA, 0x87, 0x01, 0x00, 0x04, 0xC1, 0xC6, 0x7C, 0xCA, 0x83, 0x01, 0x00, 0x4B, 0x7B, 0x04, 0x00, + 0xFA, 0x7F, 0x01, 0x00, 0x38, 0x2E, 0x88, 0x06, 0xB9, 0x71, 0x94, 0x06, 0x0C, 0xF0, 0x80, 0x00, + 0xF1, 0xF0, 0x06, 0x92, 0x06, 0x62, 0x57, 0x62, 0x57, 0x91, 0x26, 0x96, 0x3F, 0x22, 0x09, 0x00, + 0x26, 0x22, 0x2F, 0x92, 0x0E, 0x00, 0x2C, 0x90, 0x98, 0x04, 0x78, 0x59, 0x10, 0x00, 0x78, 0x6E, + 0x70, 0x01, 0x38, 0x71, 0x94, 0x06, 0x3F, 0x66, 0x05, 0x00, 0xC4, 0x60, 0x32, 0x02, 0x16, 0x66, + 0x78, 0x29, 0x12, 0x00, 0x78, 0x5E, 0x72, 0x01, 0x36, 0x25, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, + 0x28, 0x59, 0x1C, 0x00, 0xB9, 0x71, 0x94, 0x06, 0x06, 0x32, 0xB9, 0x51, 0x8C, 0x06, 0xB9, 0x61, + 0x90, 0x06, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x61, 0x90, 0x06, 0x06, 0x42, 0x06, 0x36, 0x06, 0x26, + 0xB9, 0x41, 0x88, 0x06, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x41, 0x88, 0x06, + 0x06, 0x35, 0x26, 0x42, 0x06, 0x25, 0xB9, 0x41, 0x88, 0x06, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x41, + 0x88, 0x06, 0x38, 0x71, 0x94, 0x06, 0xC6, 0x42, 0xBA, 0x72, 0xFF, 0xFF, 0x06, 0x29, 0x0C, 0x30, + 0x58, 0x0C, 0xEB, 0x4A, 0x02, 0x00, 0x04, 0xD1, 0x38, 0xBE, 0x88, 0x06, 0x06, 0x7D, 0xFA, 0x67, + 0xFF, 0xFF, 0x0C, 0x20, 0xE4, 0x05, 0x0C, 0x30, 0x48, 0x05, 0x26, 0x21, 0x26, 0x31, 0xAB, 0x0E, + 0x02, 0x00, 0x04, 0x70, 0x0C, 0x90, 0x94, 0x0F, 0x0C, 0x40, 0xA4, 0x0F, 0x06, 0x57, 0x06, 0x67, + 0xC6, 0x7C, 0xB2, 0x58, 0x98, 0x39, 0x1E, 0x00, 0x82, 0x4E, 0x04, 0x31, 0x53, 0x36, 0xD6, 0x3B, + 0x92, 0x48, 0x06, 0x29, 0xB9, 0x41, 0x88, 0x06, 0xB9, 0x51, 0x8C, 0x06, 0xB9, 0x61, 0x90, 0x06, + 0xB9, 0x71, 0x94, 0x06, 0x0B, 0xED, 0x01, 0x00, 0x38, 0x31, 0x80, 0x06, 0x38, 0x41, 0x88, 0x06, + 0x38, 0x51, 0x8C, 0x06, 0x38, 0x61, 0x90, 0x06, 0x38, 0x71, 0x94, 0x06, 0xC6, 0x23, 0x92, 0x31, + 0x2F, 0x35, 0x05, 0x00, 0x04, 0x21, 0x26, 0x25, 0x26, 0x53, 0x0C, 0x30, 0xE4, 0x05, 0x26, 0x31, + 0x57, 0x51, 0x26, 0x53, 0x04, 0x31, 0x91, 0x35, 0x20, 0x34, 0xB9, 0x21, 0x84, 0x06, 0x28, 0x29, + 0x1C, 0x00, 0xA9, 0x35, 0x02, 0x00, 0x28, 0x34, 0x02, 0x00, 0x99, 0x65, 0x01, 0x00, 0xA9, 0x35, + 0x04, 0x00, 0x06, 0x32, 0xB9, 0x41, 0x88, 0x06, 0xB9, 0x51, 0x8C, 0x06, 0xB9, 0x61, 0x90, 0x06, + 0xB9, 0x71, 0x94, 0x06, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x71, 0x94, 0x06, + 0x38, 0x61, 0x90, 0x06, 0xB9, 0x25, 0x08, 0x00, 0x38, 0x41, 0x88, 0x06, 0x38, 0x51, 0x84, 0x06, + 0x24, 0x71, 0x13, 0x77, 0x24, 0x61, 0xC4, 0x6D, 0x2C, 0x90, 0x26, 0x00, 0x2C, 0x40, 0x26, 0x00, + 0x92, 0xA8, 0x04, 0x70, 0x06, 0x4E, 0x06, 0x67, 0x04, 0x31, 0xC6, 0x6A, 0x32, 0x1F, 0x06, 0x53, + 0x53, 0x56, 0xD6, 0x5D, 0x92, 0x17, 0x2F, 0x57, 0x07, 0x00, 0x26, 0x57, 0x0C, 0x20, 0x48, 0x05, + 0x26, 0x21, 0x57, 0x51, 0x26, 0x52, 0x28, 0x24, 0x70, 0x01, 0x91, 0x35, 0x99, 0x65, 0x01, 0x00, + 0xA9, 0x25, 0x02, 0x00, 0x28, 0x24, 0x72, 0x01, 0xB9, 0x05, 0x08, 0x00, 0x24, 0x71, 0xA9, 0x25, + 0x04, 0x00, 0x24, 0x61, 0x2C, 0x40, 0x20, 0x00, 0xF2, 0xE1, 0x04, 0x61, 0xB9, 0x00, 0x84, 0x1A, + 0x0C, 0x30, 0xE4, 0x05, 0x0C, 0x40, 0x48, 0x05, 0x99, 0x60, 0xBD, 0x1B, 0x06, 0x21, 0x26, 0x31, + 0x26, 0x41, 0x99, 0x00, 0xBC, 0x1B, 0x04, 0x94, 0x6B, 0x11, 0x02, 0x00, 0x06, 0x72, 0x26, 0x91, + 0x04, 0x60, 0x04, 0x51, 0xC6, 0x67, 0x3A, 0xC3, 0xFE, 0xFF, 0x10, 0x49, 0x06, 0x24, 0x06, 0x34, + 0x57, 0x21, 0x57, 0x32, 0x26, 0x32, 0x3F, 0x44, 0x03, 0x00, 0x18, 0x39, 0x01, 0x00, 0xB9, 0x51, + 0x8C, 0x06, 0x26, 0x44, 0xD7, 0x32, 0x2F, 0x24, 0x0E, 0x00, 0x26, 0x3E, 0x2C, 0x20, 0x98, 0x04, + 0x2C, 0x30, 0x5C, 0x01, 0xB9, 0x61, 0x90, 0x06, 0xB9, 0x71, 0x94, 0x06, 0xEB, 0x4A, 0x02, 0x00, + 0x38, 0x51, 0x8C, 0x06, 0x10, 0x49, 0x38, 0x61, 0x90, 0x06, 0x38, 0x71, 0x94, 0x06, 0x06, 0x35, + 0x53, 0x34, 0x18, 0x49, 0x01, 0x00, 0x06, 0x25, 0x53, 0x24, 0x66, 0xB3, 0x66, 0xD2, 0x24, 0x61, + 0x24, 0x98, 0xF2, 0xD1, 0x34, 0x21, 0x06, 0x65, 0x53, 0x62, 0x24, 0x91, 0x66, 0xB6, 0x13, 0x99, + 0x24, 0x71, 0xFA, 0x95, 0xFE, 0xFF, 0x06, 0x5B, 0x73, 0x5A, 0xD4, 0x51, 0x92, 0x45, 0x18, 0x5D, + 0x21, 0x00, 0xC6, 0x58, 0xB2, 0x1F, 0x06, 0x2D, 0xB9, 0x61, 0x90, 0x06, 0xB9, 0x71, 0x94, 0x06, + 0x0B, 0xED, 0x01, 0x00, 0xC4, 0x21, 0x38, 0x61, 0x90, 0x06, 0x38, 0x71, 0x94, 0x06, 0x92, 0x12, + 0x18, 0x5D, 0x21, 0x00, 0x06, 0x2D, 0x24, 0x51, 0x99, 0x5D, 0x21, 0x00, 0xB9, 0x61, 0x90, 0x06, + 0xB9, 0x71, 0x94, 0x06, 0x0B, 0x3A, 0x02, 0x00, 0x38, 0x61, 0x90, 0x06, 0x38, 0x71, 0x94, 0x06, + 0xF2, 0x23, 0x98, 0x5E, 0x8C, 0x06, 0x82, 0x04, 0x34, 0x51, 0x99, 0x5E, 0x8C, 0x06, 0x04, 0x41, + 0x38, 0x3E, 0x88, 0x06, 0x06, 0x54, 0x53, 0x5A, 0x15, 0x55, 0x56, 0x53, 0xB9, 0x5E, 0x88, 0x06, + 0x99, 0x0D, 0x1E, 0x00, 0x99, 0x0D, 0x20, 0x00, 0x99, 0x0D, 0x21, 0x00, 0x99, 0x0D, 0x23, 0x00, + 0x99, 0x4E, 0xF0, 0x00, 0x18, 0x5D, 0x22, 0x00, 0xC4, 0x52, 0x92, 0x06, 0x38, 0x5E, 0x0C, 0x00, + 0x56, 0x56, 0xB9, 0x5E, 0x0C, 0x00, 0x24, 0x71, 0x13, 0x77, 0xFA, 0x6E, 0xFE, 0xFF, 0x06, 0x2C, + 0x58, 0xC1, 0xA8, 0x06, 0x58, 0x81, 0x98, 0x06, 0x2C, 0x10, 0xB8, 0x06, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x18, 0xC1, 0xE1, 0xEB, 0x54, 0x02, 0x00, 0xC4, 0x21, 0x06, 0xE2, 0x92, 0x03, 0xAB, 0xF1, + 0x02, 0x00, 0x4B, 0x2E, 0x02, 0x00, 0x66, 0x2E, 0x40, 0xE1, 0x13, 0x22, 0x24, 0x18, 0xE1, 0xF0, + 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x08, 0xD0, 0x06, 0x00, 0x0C, 0xC0, 0x14, 0x0B, 0x04, 0xE0, 0x2C, 0xD0, 0x00, 0xBD, + 0x06, 0x2E, 0x0C, 0x30, 0x17, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x2C, 0xE0, 0x00, 0x4B, 0xC6, 0xED, + 0x2C, 0x20, 0xA1, 0x01, 0xB1, 0x2C, 0x24, 0xC4, 0x92, 0xF4, 0x08, 0xD0, 0x02, 0x00, 0x0C, 0xC0, + 0x74, 0x0B, 0x04, 0xE0, 0x2C, 0xD0, 0xA0, 0x4E, 0x06, 0x2E, 0x04, 0x3E, 0xAB, 0x15, 0x00, 0x00, + 0x2C, 0xE0, 0x30, 0x2A, 0xC6, 0xED, 0x2C, 0x20, 0x81, 0x01, 0xB1, 0x2C, 0x24, 0xC4, 0x92, 0xF5, + 0x50, 0xC1, 0x0C, 0x60, 0x2B, 0x00, 0xB9, 0x60, 0xD4, 0x0B, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0x2F, 0x72, 0x02, 0x00, 0x34, 0x18, 0x26, 0x72, 0xC1, 0xE1, 0x06, 0xE7, 0x57, 0xE2, 0x26, 0x7E, + 0x26, 0x27, 0x2C, 0x20, 0xA4, 0x06, 0x0C, 0xE0, 0xFC, 0x0A, 0x26, 0xE2, 0x14, 0x71, 0x04, 0x26, + 0xA1, 0x7E, 0xA9, 0x7E, 0x02, 0x00, 0x26, 0x2E, 0x04, 0x30, 0x0C, 0x40, 0x24, 0x00, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x04, 0x71, 0x99, 0x7E, 0x04, 0x00, 0x38, 0x70, 0x70, 0x1A, 0xA9, 0x0E, + 0x2A, 0x00, 0x0C, 0x20, 0x2E, 0x00, 0x18, 0x77, 0x9D, 0x00, 0x26, 0x2E, 0x99, 0x7E, 0x2C, 0x00, + 0x04, 0x30, 0x04, 0x46, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x99, 0x0E, 0x2D, 0x00, 0x40, 0xE1, + 0x24, 0x18, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x04, 0xE0, 0x06, 0x2E, 0x0B, 0x80, 0x02, 0x00, + 0x24, 0xE1, 0xC4, 0xED, 0x92, 0xFB, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x06, 0xE2, 0x06, 0x93, 0x06, 0x25, 0x06, 0x36, 0x06, 0xC4, + 0x06, 0xA5, 0x18, 0x81, 0x20, 0x00, 0x28, 0xD1, 0x24, 0x00, 0x28, 0xB1, 0x28, 0x00, 0x0C, 0xF0, + 0x98, 0x00, 0xF1, 0xF0, 0x06, 0x32, 0x06, 0x2E, 0x8B, 0x16, 0x00, 0x00, 0x06, 0xE2, 0x06, 0x38, + 0x06, 0x2A, 0x0C, 0xF0, 0x98, 0x00, 0xF1, 0xF0, 0xC6, 0xCD, 0x06, 0x32, 0x32, 0x03, 0x43, 0x2E, + 0xF2, 0x14, 0x06, 0x29, 0x8B, 0x16, 0x00, 0x00, 0xC6, 0xCB, 0x06, 0x32, 0x32, 0x0D, 0x36, 0x3E, + 0x3F, 0x2D, 0x0C, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x3F, 0x3D, 0x0B, 0x00, 0x8B, 0x16, 0x00, 0x00, + 0x26, 0x2E, 0x43, 0x22, 0xF2, 0x02, 0x43, 0x22, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, + 0x20, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x28, 0xD4, 0x0E, 0x00, 0x38, 0xF1, + 0x10, 0x00, 0x78, 0xE1, 0x14, 0x00, 0xC6, 0x5D, 0x04, 0x75, 0x12, 0x11, 0x28, 0xD4, 0x0A, 0x00, + 0x04, 0x74, 0xC6, 0x5D, 0x12, 0x0C, 0x28, 0xD4, 0x06, 0x00, 0x04, 0x73, 0xC6, 0x5D, 0x12, 0x07, + 0x28, 0x44, 0x02, 0x00, 0x04, 0x71, 0xC6, 0x54, 0x02, 0x02, 0x04, 0x72, 0x10, 0x56, 0x36, 0x75, + 0xB3, 0x57, 0x70, 0x7F, 0x02, 0x05, 0xC6, 0x7E, 0x92, 0x0F, 0xA1, 0x0F, 0xF2, 0x0F, 0xC4, 0x50, + 0x82, 0x05, 0x16, 0x5E, 0xC6, 0x75, 0x92, 0x04, 0xF2, 0xF9, 0xC4, 0x70, 0x02, 0x03, 0x34, 0x71, + 0xF2, 0x04, 0xC4, 0x70, 0x82, 0x03, 0x24, 0x71, 0xA1, 0x7F, 0x70, 0x5F, 0x10, 0x76, 0xC6, 0x5E, + 0x92, 0x05, 0xC4, 0x74, 0xD2, 0x0A, 0x24, 0x71, 0xF2, 0x07, 0x16, 0xEE, 0xC6, 0x5E, 0x92, 0x05, + 0xC4, 0x71, 0xC2, 0x03, 0x34, 0x71, 0x91, 0x76, 0x10, 0x76, 0x6B, 0xE6, 0x04, 0x00, 0x01, 0x00, + 0x05, 0x00, 0x30, 0x00, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x04, 0x79, + 0x91, 0x72, 0x04, 0x77, 0xF2, 0x10, 0x04, 0x77, 0x91, 0x72, 0x04, 0x75, 0xF2, 0x0C, 0x04, 0x75, + 0x91, 0x72, 0x04, 0x73, 0xF2, 0x08, 0x04, 0x73, 0x91, 0x72, 0x04, 0x72, 0xF2, 0x04, 0x04, 0x72, + 0x91, 0x72, 0x04, 0x71, 0x50, 0xC1, 0x91, 0x73, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x2F, 0x72, 0x02, 0x00, 0x26, 0x72, 0x06, 0x67, 0x3C, 0x10, 0x40, 0x00, 0x57, 0x62, 0xD9, 0xC1, + 0x30, 0x00, 0x26, 0x76, 0x04, 0xC1, 0x26, 0xC2, 0x26, 0x27, 0x0C, 0xE0, 0xFC, 0x0A, 0x57, 0xC1, + 0x2C, 0x20, 0xA4, 0x06, 0xD9, 0x81, 0x20, 0x00, 0x26, 0xCE, 0x26, 0xE2, 0x18, 0x7E, 0x04, 0x00, + 0x99, 0x01, 0x0D, 0x00, 0x99, 0x01, 0x0C, 0x00, 0xC4, 0x71, 0x06, 0xB3, 0x0C, 0xD0, 0x64, 0x00, + 0xC2, 0x17, 0x78, 0x2E, 0x06, 0x00, 0x78, 0x7E, 0x0A, 0x00, 0x36, 0x27, 0xC4, 0x20, 0x32, 0x02, + 0x16, 0x22, 0x78, 0x3E, 0x08, 0x00, 0x78, 0x7E, 0x0C, 0x00, 0x43, 0x22, 0x36, 0x37, 0xC4, 0x30, + 0x32, 0x02, 0x16, 0x33, 0x43, 0x33, 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0x06, 0xD2, 0x78, 0x7E, + 0x2E, 0x00, 0x78, 0x2E, 0x30, 0x00, 0x18, 0x3E, 0x2D, 0x00, 0xA9, 0x7E, 0x30, 0x00, 0xA9, 0x2E, + 0x32, 0x00, 0x26, 0x27, 0x24, 0x31, 0x26, 0x2D, 0x8B, 0x16, 0x00, 0x00, 0x99, 0xD0, 0xAD, 0x1B, + 0x0C, 0x70, 0x2A, 0x00, 0xA9, 0xDE, 0x2E, 0x00, 0x26, 0x7E, 0xB1, 0x71, 0x38, 0x70, 0x70, 0x1A, + 0x06, 0x52, 0x18, 0x77, 0x9C, 0x00, 0x04, 0x2D, 0x04, 0x3C, 0x0C, 0x60, 0x2C, 0x00, 0xB9, 0x71, + 0x04, 0x00, 0x26, 0x21, 0x26, 0x31, 0x06, 0x4B, 0x26, 0x6E, 0xAB, 0x87, 0x02, 0x00, 0x18, 0x7E, + 0x2C, 0x00, 0x68, 0x61, 0x0D, 0x00, 0x04, 0x5C, 0x26, 0x51, 0x60, 0x55, 0x34, 0x71, 0x26, 0x77, + 0x33, 0x77, 0x14, 0x41, 0x26, 0x46, 0xB9, 0x71, 0x10, 0x00, 0xB9, 0x51, 0x14, 0x00, 0x04, 0x70, + 0x34, 0x51, 0xB9, 0x41, 0x18, 0x00, 0xB9, 0x51, 0x1C, 0x00, 0x06, 0xA7, 0x06, 0x5E, 0x06, 0x37, + 0x06, 0x97, 0x06, 0x27, 0x06, 0xF7, 0x06, 0x47, 0x78, 0x85, 0x06, 0x00, 0x26, 0x48, 0x78, 0x85, + 0x08, 0x00, 0x26, 0xF8, 0x38, 0x81, 0x18, 0x00, 0xC6, 0x78, 0x82, 0x08, 0x38, 0x81, 0x1C, 0x00, + 0xC6, 0x78, 0x92, 0x06, 0x06, 0xAF, 0x06, 0x34, 0xF2, 0x03, 0x06, 0x9F, 0x06, 0x24, 0x24, 0x71, + 0xC4, 0x79, 0x24, 0x54, 0x92, 0xEA, 0x38, 0x71, 0x10, 0x00, 0x38, 0x41, 0x14, 0x00, 0x18, 0x5E, + 0x04, 0x00, 0x26, 0x77, 0x2F, 0x87, 0x0B, 0x00, 0x24, 0x72, 0x26, 0xB7, 0x13, 0x74, 0xB1, 0x71, + 0x20, 0x78, 0x06, 0x4D, 0xB9, 0x71, 0x04, 0x00, 0x20, 0x7B, 0x13, 0x66, 0xB9, 0x71, 0x08, 0x00, + 0xEB, 0x83, 0x02, 0x00, 0x38, 0x7C, 0x3C, 0x0C, 0x08, 0x60, 0x00, 0xFF, 0x2C, 0x60, 0xFF, 0x0F, + 0x5C, 0x20, 0xFF, 0x0F, 0x57, 0x26, 0x56, 0x76, 0x66, 0x72, 0xB9, 0x7C, 0x3C, 0x0C, 0x18, 0x71, + 0x0C, 0x00, 0x18, 0x5E, 0x04, 0x00, 0x18, 0x61, 0x0D, 0x00, 0xB1, 0x71, 0x20, 0x78, 0x06, 0x29, + 0xB9, 0x71, 0x04, 0x00, 0x20, 0x7B, 0x06, 0x3A, 0xB9, 0x71, 0x08, 0x00, 0x06, 0x4D, 0xEB, 0x83, + 0x02, 0x00, 0x38, 0x7C, 0x3C, 0x0C, 0x1C, 0x50, 0x00, 0x10, 0x5C, 0x20, 0xFF, 0x0F, 0x56, 0x75, + 0x66, 0x72, 0xB9, 0x7C, 0x3C, 0x0C, 0x58, 0xC1, 0x30, 0x00, 0x58, 0x81, 0x20, 0x00, 0x2C, 0x10, + 0x40, 0x00, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x0C, 0x60, 0xFC, 0x0A, 0x18, 0xF6, 0xC0, 0x0C, + 0x06, 0x52, 0xC4, 0xF0, 0x04, 0x72, 0x82, 0x05, 0x38, 0x70, 0x70, 0x1A, 0x28, 0x77, 0xB4, 0x00, + 0x3F, 0x24, 0x03, 0x00, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0xC4, 0xF0, 0x23, 0x22, 0x92, 0x06, + 0xC4, 0x22, 0xC2, 0x04, 0x04, 0xF1, 0x99, 0xF6, 0xC0, 0x0C, 0x18, 0xF6, 0x1E, 0x03, 0xC4, 0xF2, + 0x92, 0x10, 0xCC, 0x50, 0x14, 0x00, 0x92, 0x09, 0x38, 0x66, 0x0C, 0x00, 0x0C, 0x70, 0x28, 0x00, + 0xD4, 0x61, 0x82, 0x2B, 0x06, 0x75, 0xF2, 0x29, 0xC4, 0x51, 0x92, 0x27, 0x06, 0x7F, 0xF2, 0x25, + 0xC4, 0xF1, 0x92, 0x23, 0xCC, 0x50, 0x14, 0x00, 0x92, 0x1D, 0x38, 0x76, 0x0C, 0x00, 0x28, 0x66, + 0x12, 0x00, 0xD4, 0x71, 0x82, 0x09, 0xC4, 0x60, 0x06, 0x75, 0x82, 0x17, 0x2F, 0x76, 0x06, 0x00, + 0x26, 0x76, 0x23, 0x77, 0xF2, 0x12, 0xC4, 0x60, 0x0C, 0x70, 0x1E, 0x00, 0x82, 0x0E, 0x06, 0x76, + 0x57, 0x71, 0x26, 0x76, 0x23, 0x77, 0xCC, 0x70, 0x1D, 0x00, 0xD2, 0x07, 0x0C, 0x70, 0x1E, 0x00, + 0xF2, 0x04, 0xC4, 0x51, 0x92, 0x02, 0x04, 0x72, 0xC6, 0x27, 0xC2, 0x08, 0xC6, 0x34, 0xC2, 0x04, + 0x3F, 0x77, 0x03, 0x00, 0xF2, 0x02, 0x26, 0x73, 0x23, 0x47, 0x30, 0xF1, 0x06, 0x24, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x86, 0x22, 0x34, 0x14, 0xB1, 0xF1, 0x32, 0x02, 0x16, 0x22, 0x43, 0x72, + 0xC4, 0x72, 0x04, 0x20, 0x02, 0x08, 0x14, 0x22, 0x26, 0x27, 0x57, 0x21, 0x04, 0x36, 0x8B, 0x16, + 0x00, 0x00, 0x43, 0x22, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x0C, 0xE0, 0xFC, 0x0A, 0x98, 0x7E, 0xDC, 0x00, 0x92, 0x74, + 0x38, 0x7E, 0x3C, 0x0C, 0xDC, 0x70, 0x00, 0xF0, 0x82, 0x6F, 0x38, 0xDE, 0x40, 0x0C, 0x38, 0xAE, + 0xB8, 0x0C, 0x38, 0x7E, 0xBC, 0x0C, 0x06, 0xBD, 0x77, 0xB6, 0x5C, 0xB0, 0xFF, 0x0F, 0x0C, 0x40, + 0xFF, 0x0F, 0x56, 0x4B, 0x06, 0xCA, 0x08, 0x60, 0x00, 0xFF, 0x2C, 0x60, 0xFF, 0x0F, 0x06, 0x54, + 0x77, 0xC6, 0x57, 0x56, 0x56, 0x76, 0x5C, 0xC0, 0xFF, 0x0F, 0x66, 0x75, 0x36, 0xBC, 0x5C, 0xD0, + 0xFF, 0x0F, 0x0C, 0x50, 0xFF, 0x0F, 0x1C, 0x60, 0x00, 0x10, 0x56, 0x5D, 0x56, 0x76, 0xC4, 0xB0, + 0x66, 0x75, 0xB9, 0x7E, 0xBC, 0x0C, 0x5C, 0xA0, 0xFF, 0x0F, 0x06, 0x7B, 0x32, 0x02, 0x16, 0x7B, + 0x23, 0x77, 0xC4, 0x78, 0xD2, 0x32, 0x36, 0xDA, 0xC4, 0xD0, 0x06, 0x7D, 0x32, 0x02, 0x16, 0x7D, + 0x23, 0x77, 0xC4, 0x78, 0xD2, 0x2A, 0x06, 0x2B, 0xAB, 0xA1, 0x02, 0x00, 0x06, 0x92, 0x06, 0x2D, + 0xAB, 0xA1, 0x02, 0x00, 0xC4, 0xB0, 0x22, 0x03, 0x26, 0xC9, 0xF2, 0x02, 0x36, 0xC9, 0x38, 0x7E, + 0x40, 0x0C, 0x08, 0x60, 0x00, 0xFF, 0x5C, 0xC0, 0xFF, 0x0F, 0x2C, 0x60, 0xFF, 0x0F, 0x57, 0xC6, + 0x56, 0x76, 0xC4, 0xD0, 0x66, 0x7C, 0xB9, 0x7E, 0x40, 0x0C, 0x22, 0x03, 0x26, 0xA2, 0xF2, 0x02, + 0x36, 0xA2, 0x38, 0x7E, 0x40, 0x0C, 0x1C, 0x60, 0x00, 0x10, 0x5C, 0xA0, 0xFF, 0x0F, 0x56, 0x76, + 0x66, 0x7A, 0xB9, 0x7E, 0x40, 0x0C, 0xF2, 0x10, 0x38, 0x7E, 0xB8, 0x0C, 0x08, 0x60, 0x00, 0xFF, + 0x2C, 0x60, 0xFF, 0x0F, 0x56, 0x76, 0x57, 0x46, 0x66, 0x74, 0x1C, 0x60, 0x00, 0x10, 0x56, 0x76, + 0x66, 0x75, 0xB9, 0x7E, 0xB8, 0x0C, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x38, 0x30, 0x70, 0x1A, 0x3C, 0x10, 0x7C, 0x00, 0x0C, 0x50, 0xB2, 0x00, + 0xD9, 0xC1, 0x6C, 0x00, 0xD9, 0x81, 0x5C, 0x00, 0x26, 0x53, 0x10, 0x55, 0x06, 0x21, 0x2C, 0x30, + 0x9E, 0x00, 0x04, 0x4A, 0xB9, 0x51, 0x38, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, 0x0C, 0xF0, 0x40, 0x01, + 0xF1, 0xF0, 0x98, 0x7D, 0x8C, 0x06, 0x92, 0x05, 0x2B, 0x83, 0x02, 0x00, 0xFA, 0x23, 0x03, 0x00, + 0x18, 0xCD, 0xE5, 0x00, 0x2F, 0x7C, 0x0C, 0x00, 0x2F, 0x6C, 0x07, 0x00, 0x06, 0x56, 0x57, 0x52, + 0x26, 0x65, 0x26, 0x6C, 0x0C, 0x20, 0xB0, 0x1A, 0x2F, 0x8D, 0x06, 0x00, 0x06, 0x67, 0x26, 0x72, + 0xB9, 0x71, 0x18, 0x00, 0x06, 0x7C, 0xD7, 0x71, 0x0C, 0x40, 0x28, 0x1B, 0x06, 0x97, 0x26, 0x74, + 0xB9, 0x71, 0x30, 0x00, 0x06, 0xAC, 0x06, 0x7C, 0x57, 0xA1, 0x57, 0x72, 0x26, 0x7A, 0x36, 0x7C, + 0x26, 0x77, 0xB9, 0xA1, 0x28, 0x00, 0x0C, 0xF0, 0xC4, 0x1A, 0x26, 0x7D, 0x26, 0x6F, 0x2C, 0x70, + 0xB8, 0x04, 0x0C, 0x50, 0x38, 0x19, 0x38, 0xB1, 0x28, 0x00, 0x38, 0xE1, 0x28, 0x00, 0xB9, 0x61, + 0x1C, 0x00, 0x26, 0xA5, 0xB9, 0x71, 0x34, 0x00, 0x0C, 0x70, 0x88, 0x1A, 0xB9, 0xA1, 0x44, 0x00, + 0x0C, 0x60, 0x10, 0x19, 0x38, 0xA1, 0x28, 0x00, 0x26, 0xB6, 0x26, 0xE7, 0x0C, 0x30, 0xD8, 0x1A, + 0x0C, 0x70, 0x40, 0x0C, 0x26, 0x93, 0xB9, 0xB1, 0x40, 0x00, 0x26, 0x7D, 0x08, 0xB0, 0x00, 0xFF, + 0xB9, 0x91, 0x24, 0x00, 0x26, 0xA7, 0x04, 0x90, 0x2C, 0xB0, 0xFF, 0x0F, 0xB9, 0xE1, 0x48, 0x00, + 0xB9, 0x91, 0x20, 0x00, 0xB9, 0xA1, 0x4C, 0x00, 0xB9, 0xB1, 0x2C, 0x00, 0x18, 0x7D, 0xE6, 0x00, + 0xC6, 0xC7, 0x3A, 0x89, 0x02, 0x00, 0x38, 0x61, 0x20, 0x00, 0x38, 0x51, 0x4C, 0x00, 0x26, 0x56, + 0x30, 0x75, 0x08, 0x60, 0x00, 0xF0, 0xD6, 0x76, 0x06, 0xE5, 0x92, 0x06, 0x06, 0x2C, 0x0B, 0x80, + 0x02, 0x00, 0xFA, 0x55, 0x02, 0x00, 0x0C, 0xA0, 0xA4, 0x06, 0x26, 0xA8, 0x04, 0x98, 0x06, 0xBA, + 0x0C, 0x20, 0x26, 0x00, 0x0C, 0x30, 0x22, 0x00, 0x26, 0x2A, 0x26, 0x3A, 0x04, 0x44, 0xEB, 0xE4, + 0x04, 0x00, 0x34, 0x91, 0xC4, 0x90, 0x34, 0xA4, 0x92, 0xF4, 0x30, 0x7E, 0x13, 0x2C, 0x77, 0x76, + 0x5C, 0x70, 0xFF, 0x0F, 0xA9, 0x78, 0xAA, 0x06, 0x30, 0x7E, 0x06, 0x31, 0x5C, 0x70, 0xFF, 0x0F, + 0xA9, 0x78, 0xAC, 0x06, 0x0B, 0x8E, 0x02, 0x00, 0xF8, 0x28, 0xA4, 0x06, 0x30, 0xAE, 0x22, 0x4E, + 0xF8, 0x78, 0xA6, 0x06, 0x22, 0x4B, 0x38, 0x51, 0x38, 0x00, 0x0C, 0x90, 0x64, 0x00, 0x06, 0x79, + 0x36, 0x75, 0x06, 0x37, 0xB9, 0x71, 0x54, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x31, 0x38, 0x00, + 0x06, 0x62, 0x06, 0x2A, 0x77, 0x26, 0x5C, 0x20, 0xFF, 0x0F, 0xB9, 0x61, 0x50, 0x00, 0x4B, 0x14, + 0x00, 0x00, 0x38, 0x61, 0x50, 0x00, 0x06, 0x39, 0x26, 0x26, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x61, + 0x2C, 0x00, 0x5C, 0x20, 0xFF, 0x0F, 0x56, 0xA6, 0x57, 0x26, 0x66, 0xA2, 0xB1, 0xAE, 0x38, 0x71, + 0x54, 0x00, 0x78, 0x28, 0xA6, 0x06, 0x06, 0x37, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x31, 0x38, 0x00, + 0x06, 0x72, 0x0C, 0x20, 0xFF, 0x0F, 0x56, 0x2A, 0xB9, 0x71, 0x54, 0x00, 0x4B, 0x14, 0x00, 0x00, + 0x38, 0x71, 0x54, 0x00, 0x06, 0x39, 0x26, 0x27, 0x8B, 0x16, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x10, + 0x5C, 0x20, 0xFF, 0x0F, 0x56, 0xA7, 0x66, 0xA2, 0x0C, 0x20, 0x14, 0x00, 0xB1, 0xAE, 0x26, 0x21, + 0x06, 0x3B, 0x04, 0x44, 0xEB, 0xE4, 0x04, 0x00, 0xF2, 0x0B, 0x06, 0x7A, 0x77, 0x76, 0x5C, 0x70, + 0xFF, 0x0F, 0x5C, 0xA0, 0xFF, 0x0F, 0xA9, 0x71, 0x14, 0x00, 0xA9, 0xA1, 0x16, 0x00, 0x18, 0x78, + 0xA8, 0x06, 0xC4, 0x78, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x78, 0xA8, 0x06, 0x18, 0x78, 0xD1, 0x06, + 0xC4, 0x71, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x78, 0xD1, 0x06, 0x30, 0x7E, 0x77, 0x76, 0x5C, 0x70, + 0xFF, 0x0F, 0xA9, 0x78, 0xA4, 0x06, 0x30, 0x7E, 0x5C, 0x70, 0xFF, 0x0F, 0xA9, 0x78, 0xA6, 0x06, + 0x18, 0x70, 0xA6, 0x1B, 0xC4, 0x71, 0x92, 0x25, 0x30, 0x6E, 0x0C, 0x20, 0x14, 0x00, 0x06, 0x76, + 0x77, 0x76, 0x5C, 0x70, 0xFF, 0x0F, 0x5C, 0x60, 0xFF, 0x0F, 0x26, 0x21, 0x06, 0x3C, 0xA9, 0x71, + 0x14, 0x00, 0xA9, 0x61, 0x16, 0x00, 0x0B, 0x3F, 0x04, 0x00, 0x28, 0x61, 0x14, 0x00, 0x30, 0x7E, + 0x38, 0x91, 0x2C, 0x00, 0x5C, 0x60, 0xFF, 0x0F, 0x57, 0x66, 0x56, 0x79, 0x66, 0x76, 0x28, 0x61, + 0x16, 0x00, 0x1C, 0xA0, 0x00, 0x10, 0x5C, 0x60, 0xFF, 0x0F, 0x56, 0x7A, 0x66, 0x76, 0xB1, 0x7E, + 0x38, 0x7D, 0x0C, 0x00, 0x38, 0xB1, 0x34, 0x00, 0xD4, 0x71, 0x10, 0x3B, 0x82, 0x06, 0x0C, 0x50, + 0x1E, 0x00, 0x0C, 0xF0, 0x14, 0x00, 0xF2, 0x04, 0x0C, 0x50, 0x28, 0x00, 0x06, 0xF5, 0x0C, 0x40, + 0x1E, 0x03, 0x26, 0x4D, 0x10, 0x44, 0x06, 0x74, 0x34, 0x71, 0xC4, 0x71, 0xB9, 0x41, 0x3C, 0x00, + 0xDA, 0xEC, 0x00, 0x00, 0x38, 0x91, 0x24, 0x00, 0x38, 0x61, 0x30, 0x00, 0x38, 0xB1, 0x30, 0x00, + 0x38, 0x79, 0x04, 0x00, 0x38, 0x46, 0x04, 0x00, 0xB1, 0x79, 0x04, 0x71, 0x26, 0x7C, 0x57, 0x71, + 0x0C, 0xA0, 0xFC, 0x0A, 0xB1, 0x46, 0x26, 0x7A, 0x38, 0x67, 0x3C, 0x0C, 0xC4, 0x31, 0x06, 0x76, + 0x77, 0x76, 0x5C, 0x70, 0xFF, 0x0F, 0x5C, 0x60, 0xFF, 0x0F, 0xB9, 0x7B, 0x04, 0x00, 0xB9, 0x69, + 0x04, 0x00, 0xCA, 0xFD, 0x00, 0x00, 0x38, 0x21, 0x44, 0x00, 0x38, 0x91, 0x20, 0x00, 0x1C, 0x30, + 0x64, 0x00, 0x26, 0x29, 0x30, 0xA2, 0xC6, 0xA3, 0x92, 0x04, 0x5C, 0x40, 0xFF, 0x0F, 0xF2, 0x04, + 0x0C, 0x40, 0xFF, 0x0F, 0x56, 0x4A, 0xC6, 0x47, 0x02, 0x06, 0x38, 0xB1, 0x1C, 0x00, 0x36, 0x47, + 0xA1, 0x4B, 0xF2, 0x06, 0x38, 0x91, 0x1C, 0x00, 0x3F, 0x44, 0x07, 0x00, 0xA1, 0x49, 0x38, 0xB1, + 0x20, 0x00, 0x38, 0x31, 0x40, 0x00, 0x1C, 0x40, 0x64, 0x00, 0x26, 0x3B, 0x30, 0xB3, 0xC6, 0xB4, + 0x92, 0x07, 0x38, 0x91, 0x24, 0x00, 0x30, 0x49, 0x5C, 0x40, 0xFF, 0x0F, 0xF2, 0x04, 0x0C, 0x40, + 0xFF, 0x0F, 0x56, 0x4B, 0xC6, 0x46, 0x02, 0x03, 0x36, 0x46, 0xF2, 0x03, 0x3F, 0x44, 0x06, 0x00, + 0x38, 0x91, 0x18, 0x00, 0xA1, 0x49, 0x0C, 0x40, 0x60, 0x19, 0x60, 0x44, 0x14, 0x91, 0xC6, 0x49, + 0xB9, 0x41, 0x58, 0x00, 0x82, 0x2B, 0xC6, 0x4C, 0x92, 0x27, 0x36, 0x7A, 0xC4, 0x70, 0x32, 0x02, + 0x16, 0x77, 0xC6, 0x75, 0x12, 0x07, 0x36, 0x6B, 0xC4, 0x60, 0x32, 0x02, 0x16, 0x66, 0xC6, 0x65, + 0x02, 0x18, 0x04, 0x70, 0x1C, 0x60, 0x64, 0x00, 0x0C, 0x50, 0x38, 0x19, 0x26, 0x57, 0xB1, 0x65, + 0x0C, 0x50, 0x10, 0x19, 0x26, 0x57, 0x24, 0x74, 0xCC, 0x70, 0x28, 0x00, 0xB1, 0x65, 0x92, 0xF5, + 0x04, 0x61, 0x99, 0x60, 0x61, 0x19, 0x14, 0x71, 0x99, 0x70, 0x60, 0x19, 0xFA, 0x96, 0x00, 0x00, + 0x0C, 0x60, 0x14, 0x00, 0xF2, 0x02, 0x04, 0x61, 0xF2, 0x4E, 0x38, 0x91, 0x1C, 0x00, 0xF0, 0xB9, + 0x22, 0x09, 0xC6, 0xBF, 0x32, 0x07, 0x38, 0xA1, 0x18, 0x00, 0xF0, 0xBA, 0x22, 0x03, 0xC6, 0xBF, + 0x22, 0x05, 0x04, 0x70, 0x1C, 0x60, 0x64, 0x00, 0xF2, 0x43, 0x38, 0xB1, 0x20, 0x00, 0x38, 0xF1, + 0x48, 0x00, 0x26, 0xFB, 0xB0, 0xBF, 0x92, 0x03, 0xB1, 0x72, 0xB1, 0x63, 0x38, 0x41, 0x3C, 0x00, + 0x24, 0xB1, 0xC4, 0x41, 0xB1, 0xBF, 0x04, 0xFA, 0x92, 0x02, 0x04, 0xF5, 0xC6, 0xBF, 0xC2, 0x6F, + 0x30, 0xF2, 0xC6, 0x7F, 0x02, 0x0B, 0x36, 0x7F, 0xC6, 0x75, 0x32, 0x05, 0x04, 0x71, 0x99, 0x70, + 0xC0, 0x1B, 0xF2, 0x07, 0x99, 0x00, 0xC0, 0x1B, 0xF2, 0x04, 0x3F, 0x77, 0x0F, 0x00, 0xF2, 0xF5, + 0x30, 0x33, 0xC6, 0x63, 0x02, 0x0B, 0x36, 0x63, 0xC6, 0x65, 0x32, 0x05, 0x04, 0x61, 0x99, 0x60, + 0xBF, 0x1B, 0xF2, 0x07, 0x99, 0x00, 0xBF, 0x1B, 0xF2, 0x04, 0x3F, 0x66, 0x03, 0x00, 0xF2, 0xF5, + 0x18, 0x60, 0xC0, 0x1B, 0x18, 0x70, 0xBF, 0x1B, 0xD6, 0x76, 0x82, 0x08, 0x99, 0xC0, 0x60, 0x19, + 0x0C, 0x60, 0x14, 0x00, 0x99, 0x60, 0x61, 0x19, 0xF2, 0x42, 0x04, 0x61, 0xF2, 0xFC, 0x0C, 0x50, + 0x38, 0x19, 0x26, 0x57, 0xB1, 0x65, 0x0C, 0x50, 0x10, 0x19, 0x26, 0x57, 0x24, 0x74, 0xCC, 0x70, + 0x28, 0x00, 0xB1, 0x65, 0x92, 0xF5, 0xF2, 0x2E, 0x04, 0x50, 0x0C, 0x30, 0x28, 0x1B, 0x0C, 0x40, + 0xD8, 0x1A, 0x06, 0x75, 0x14, 0x61, 0x1C, 0x20, 0x64, 0x00, 0x0C, 0xF0, 0x38, 0x19, 0x26, 0xF7, + 0xB1, 0x2F, 0x0C, 0xF0, 0x10, 0x19, 0x26, 0xF7, 0xB1, 0x2F, 0x0C, 0xF0, 0xC4, 0x1A, 0x26, 0xF5, + 0xA1, 0x6F, 0x0C, 0xF0, 0xB0, 0x1A, 0x26, 0xF5, 0xA1, 0x6F, 0x0C, 0xF0, 0x88, 0x1A, 0x26, 0xF7, + 0x24, 0x74, 0xCC, 0x70, 0x28, 0x00, 0xB1, 0x63, 0xB9, 0x63, 0x04, 0x00, 0xB1, 0x64, 0xB9, 0x64, + 0x04, 0x00, 0xB1, 0x0F, 0x24, 0x38, 0x24, 0x48, 0x24, 0x52, 0x92, 0xE0, 0x14, 0x61, 0x99, 0x60, + 0x60, 0x19, 0x04, 0x61, 0x99, 0x60, 0x61, 0x19, 0x99, 0x00, 0xBE, 0x1B, 0x18, 0x20, 0x61, 0x19, + 0xCC, 0x20, 0x14, 0x00, 0x92, 0x04, 0x04, 0x61, 0x99, 0x60, 0xBE, 0x1B, 0x38, 0x61, 0x28, 0x00, + 0x38, 0x71, 0x20, 0x00, 0x0C, 0xB0, 0xFC, 0x0A, 0x2C, 0xB0, 0x7C, 0x0C, 0x26, 0xB6, 0x26, 0xB7, + 0x30, 0x4B, 0x08, 0x70, 0x00, 0xF0, 0xD6, 0x74, 0x82, 0x48, 0x08, 0x70, 0x00, 0x80, 0x18, 0x77, + 0x39, 0xDC, 0x28, 0x31, 0x14, 0x00, 0xD4, 0x71, 0x82, 0x1F, 0x5C, 0x40, 0xFF, 0x0F, 0xAB, 0x9B, + 0x02, 0x00, 0x30, 0x7E, 0x38, 0x91, 0x2C, 0x00, 0x5C, 0x20, 0xFF, 0x0F, 0x57, 0x26, 0x56, 0x79, + 0x66, 0x72, 0xB1, 0x7E, 0x30, 0x4B, 0x18, 0x20, 0x61, 0x19, 0x28, 0x31, 0x16, 0x00, 0x77, 0x46, + 0x5C, 0x40, 0xFF, 0x0F, 0xAB, 0x9B, 0x02, 0x00, 0x30, 0x7E, 0x1C, 0xA0, 0x00, 0x10, 0x5C, 0x20, + 0xFF, 0x0F, 0x56, 0x7A, 0xF2, 0x20, 0x18, 0x28, 0xD0, 0x06, 0x77, 0x46, 0x5C, 0x40, 0xFF, 0x0F, + 0xAB, 0x9B, 0x02, 0x00, 0x30, 0x7E, 0x38, 0x51, 0x2C, 0x00, 0x5C, 0x20, 0xFF, 0x0F, 0x57, 0x26, + 0x56, 0x75, 0x66, 0x72, 0xB1, 0x7E, 0x30, 0x4B, 0x18, 0x28, 0xD0, 0x06, 0x28, 0x31, 0x16, 0x00, + 0x5C, 0x40, 0xFF, 0x0F, 0xAB, 0x9B, 0x02, 0x00, 0x30, 0x7E, 0x1C, 0x60, 0x00, 0x10, 0x5C, 0x20, + 0xFF, 0x0F, 0x56, 0x76, 0x66, 0x72, 0xB1, 0x7E, 0xEB, 0xA2, 0x02, 0x00, 0x38, 0x71, 0x20, 0x00, + 0x38, 0x91, 0x1C, 0x00, 0x38, 0xA1, 0x18, 0x00, 0x38, 0xB1, 0x24, 0x00, 0x38, 0xE1, 0x30, 0x00, + 0x38, 0x51, 0x34, 0x00, 0x24, 0x74, 0x24, 0x92, 0x24, 0xA2, 0x24, 0xB8, 0x24, 0xE8, 0x2C, 0x50, + 0x26, 0x00, 0x24, 0xC1, 0xB9, 0x71, 0x20, 0x00, 0x2C, 0x80, 0x34, 0x00, 0xB9, 0x91, 0x1C, 0x00, + 0xB9, 0xA1, 0x18, 0x00, 0xB9, 0xB1, 0x24, 0x00, 0xB9, 0xE1, 0x30, 0x00, 0xB9, 0x51, 0x34, 0x00, + 0xFA, 0x76, 0xFD, 0xFF, 0x0C, 0x60, 0xFC, 0x0A, 0x18, 0xF6, 0x8C, 0x06, 0xC4, 0xF2, 0xD2, 0x3A, + 0x78, 0x26, 0xE8, 0x00, 0x78, 0x36, 0xEA, 0x00, 0x78, 0x56, 0xEC, 0x00, 0x78, 0x66, 0xEE, 0x00, + 0x04, 0x40, 0x0C, 0x70, 0xFC, 0x0A, 0x06, 0xE4, 0xC6, 0x4F, 0xB2, 0x24, 0x24, 0xE1, 0x06, 0xCE, + 0x57, 0xC1, 0x26, 0xCD, 0x38, 0xCC, 0x3C, 0x0C, 0x77, 0xCE, 0xC4, 0xC0, 0x82, 0x17, 0xC4, 0xF1, + 0x92, 0x08, 0x78, 0x67, 0xA6, 0x06, 0x78, 0x57, 0xA4, 0x06, 0x06, 0x36, 0x06, 0x25, 0xF2, 0x0C, + 0xC4, 0x40, 0x92, 0x06, 0x78, 0x37, 0xA6, 0x06, 0x78, 0x27, 0xA4, 0x06, 0xF2, 0x05, 0x78, 0x67, + 0xA6, 0x06, 0x78, 0x57, 0xA4, 0x06, 0x24, 0x41, 0x13, 0x44, 0xC4, 0xED, 0x2C, 0x70, 0x34, 0x00, + 0x92, 0xDC, 0xA9, 0x2D, 0xE8, 0x00, 0xA9, 0x3D, 0xEA, 0x00, 0xA9, 0x5D, 0xEC, 0x00, 0xA9, 0x6D, + 0xEE, 0x00, 0x58, 0xC1, 0x6C, 0x00, 0x58, 0x81, 0x5C, 0x00, 0x2C, 0x10, 0x7C, 0x00, 0xE1, 0xF0, + 0xA9, 0x00, 0x0E, 0x0B, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0xC0, 0x06, 0xD9, 0xC1, 0xB0, 0x06, + 0x0C, 0x60, 0xFC, 0x0A, 0xD9, 0x81, 0xA0, 0x06, 0x38, 0x76, 0x0C, 0x00, 0x08, 0x50, 0x02, 0x00, + 0xD6, 0x57, 0x06, 0xD6, 0x82, 0x05, 0x1C, 0x30, 0x01, 0x01, 0x56, 0x73, 0xF2, 0x08, 0x18, 0x56, + 0x1F, 0x03, 0xC4, 0x51, 0xD2, 0x08, 0x1C, 0x40, 0x01, 0x01, 0x56, 0x74, 0xB9, 0x76, 0x0C, 0x00, + 0xFA, 0xFB, 0x00, 0x00, 0xDC, 0x70, 0x00, 0x01, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x0C, 0xDC, + 0x82, 0x0B, 0x28, 0x56, 0x82, 0x00, 0x28, 0x76, 0x7E, 0x00, 0x28, 0xE6, 0x80, 0x00, 0x2F, 0x25, + 0x07, 0x00, 0x26, 0xE5, 0xF2, 0x05, 0x28, 0x26, 0x7E, 0x00, 0x28, 0xE6, 0x80, 0x00, 0x98, 0x60, + 0xBE, 0x1B, 0x82, 0x02, 0x26, 0x22, 0x06, 0x32, 0x4B, 0x14, 0x00, 0x00, 0x06, 0x3E, 0x06, 0x92, + 0x06, 0x2E, 0x4B, 0x14, 0x00, 0x00, 0x26, 0x92, 0x0C, 0x30, 0x48, 0x05, 0x0C, 0x20, 0xE4, 0x05, + 0x26, 0x21, 0x26, 0x31, 0xAB, 0x0E, 0x02, 0x00, 0x06, 0xAD, 0x04, 0xE0, 0x18, 0x7D, 0x1F, 0x03, + 0xC6, 0x7E, 0xC2, 0x1F, 0x06, 0xCE, 0x2F, 0xBE, 0x0E, 0x00, 0xD7, 0xC2, 0x26, 0xBE, 0x26, 0xCA, + 0x0C, 0x20, 0xE4, 0x05, 0x2C, 0xC0, 0x70, 0x01, 0x57, 0xB1, 0x26, 0x21, 0x06, 0x3E, 0x26, 0x2B, + 0x04, 0x40, 0x06, 0x5C, 0x6B, 0x0F, 0x02, 0x00, 0x0C, 0x20, 0x48, 0x05, 0x26, 0x21, 0x06, 0x3E, + 0x26, 0x2B, 0x04, 0x40, 0x06, 0x5C, 0x6B, 0x0F, 0x02, 0x00, 0x24, 0xE1, 0x13, 0xEE, 0xF2, 0xDF, + 0x06, 0x29, 0x04, 0x30, 0x04, 0x41, 0xEB, 0x10, 0x02, 0x00, 0x0C, 0x30, 0xE4, 0x05, 0x0C, 0x40, + 0x48, 0x05, 0x06, 0x21, 0x26, 0x31, 0x26, 0x41, 0x6B, 0x11, 0x02, 0x00, 0x86, 0x22, 0xB9, 0x21, + 0x88, 0x06, 0x82, 0x07, 0x04, 0xA4, 0x04, 0x60, 0x26, 0xA1, 0xB9, 0x61, 0x80, 0x06, 0xF2, 0x0A, + 0x38, 0x7A, 0x0C, 0x00, 0x1C, 0xF0, 0x01, 0x01, 0x56, 0x7F, 0xB9, 0x7A, 0x0C, 0x00, 0xFA, 0x8C, + 0x00, 0x00, 0x10, 0x5A, 0x0C, 0xC0, 0x5C, 0x01, 0x06, 0x75, 0xD7, 0x72, 0x26, 0x7D, 0x26, 0xC7, + 0xB9, 0x51, 0x84, 0x06, 0x38, 0x67, 0x60, 0x01, 0x38, 0x97, 0x64, 0x01, 0x38, 0x57, 0x68, 0x01, + 0x38, 0x8C, 0x10, 0x00, 0x06, 0xE1, 0x04, 0xB0, 0x18, 0x7E, 0x04, 0x00, 0x38, 0xF1, 0x84, 0x06, + 0xC6, 0x7F, 0x92, 0x45, 0xB0, 0x7E, 0x82, 0x43, 0x18, 0x7E, 0x05, 0x00, 0x0C, 0x20, 0x5C, 0x01, + 0xD7, 0x72, 0x26, 0x7D, 0x38, 0x47, 0x60, 0x01, 0x26, 0x27, 0x26, 0x64, 0x38, 0x47, 0x64, 0x01, + 0x26, 0x94, 0x38, 0x47, 0x68, 0x01, 0x0C, 0x30, 0x28, 0x08, 0x26, 0x54, 0x38, 0x42, 0x10, 0x00, + 0x26, 0x84, 0x20, 0x42, 0x06, 0xF4, 0x26, 0xF4, 0x26, 0x3F, 0xB9, 0x31, 0x94, 0x06, 0x20, 0x3C, + 0xB9, 0x41, 0x9C, 0x06, 0x26, 0x33, 0x0C, 0x40, 0x28, 0x08, 0x26, 0x43, 0xB9, 0x41, 0x98, 0x06, + 0x38, 0xF1, 0x98, 0x06, 0x38, 0x41, 0x94, 0x06, 0x70, 0x3F, 0x70, 0x44, 0xC6, 0x43, 0x02, 0x08, + 0x28, 0x77, 0x5E, 0x01, 0x38, 0x31, 0x9C, 0x06, 0xA9, 0x7C, 0x02, 0x00, 0xA1, 0x3C, 0x04, 0x30, + 0x0C, 0x40, 0x20, 0x00, 0xB9, 0x51, 0x8C, 0x06, 0xB9, 0x61, 0x90, 0x06, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0xB1, 0x0E, 0x38, 0x61, 0x90, 0x06, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x71, 0x88, 0x06, + 0x24, 0xB1, 0x13, 0xBB, 0xC6, 0xB7, 0x24, 0xE8, 0x92, 0xB0, 0x06, 0x36, 0x06, 0x25, 0x8B, 0x16, + 0x00, 0x00, 0x04, 0x3A, 0x43, 0x22, 0x8B, 0x16, 0x00, 0x00, 0xA9, 0x2C, 0x14, 0x00, 0x06, 0x39, + 0x06, 0x28, 0x8B, 0x16, 0x00, 0x00, 0x43, 0x22, 0x04, 0x3A, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x71, + 0x80, 0x06, 0xA9, 0x2C, 0x16, 0x00, 0x24, 0xA8, 0x24, 0x71, 0x13, 0x77, 0xC6, 0x7B, 0xB9, 0x71, + 0x80, 0x06, 0x9A, 0x80, 0xFF, 0xFF, 0x38, 0x7D, 0x0C, 0x00, 0x6C, 0x70, 0x00, 0x01, 0xB9, 0x7D, + 0x0C, 0x00, 0x2B, 0x8A, 0x03, 0x00, 0x58, 0xC1, 0xB0, 0x06, 0x58, 0x81, 0xA0, 0x06, 0x2C, 0x10, + 0xC0, 0x06, 0xE1, 0xF0, 0x3C, 0x10, 0x18, 0x00, 0xD9, 0xC1, 0x08, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, + 0xC1, 0xA1, 0x18, 0x7D, 0x8C, 0x06, 0x06, 0xED, 0xC4, 0x72, 0x92, 0x05, 0x18, 0x7D, 0x8F, 0x06, + 0xC4, 0x72, 0x82, 0x3D, 0x14, 0x71, 0xB9, 0x7E, 0x34, 0x0C, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, + 0x0C, 0xDC, 0x28, 0x67, 0x82, 0x00, 0x28, 0xC7, 0x7E, 0x00, 0x28, 0xD7, 0x80, 0x00, 0xA9, 0x0E, + 0x38, 0x0C, 0x26, 0xC6, 0x0C, 0x20, 0x14, 0x00, 0x26, 0x2C, 0x26, 0xD6, 0x06, 0x32, 0x0C, 0xA0, + 0x14, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x26, 0xAD, 0x06, 0xB2, 0x06, 0x3A, 0x06, 0x2A, 0x4B, 0x14, + 0x00, 0x00, 0x26, 0x2B, 0xB9, 0x2E, 0x2C, 0x0C, 0x0C, 0x20, 0x78, 0x00, 0x26, 0x2C, 0x06, 0x32, + 0x4B, 0x14, 0x00, 0x00, 0x2C, 0xD0, 0x78, 0x00, 0x06, 0xC2, 0x06, 0x3D, 0x06, 0x2D, 0x4B, 0x14, + 0x00, 0x00, 0x38, 0x7E, 0x0C, 0x00, 0x08, 0x60, 0xFD, 0xFF, 0x2C, 0x60, 0xFF, 0xFF, 0x26, 0x2C, + 0x56, 0x76, 0xB9, 0x2E, 0x30, 0x0C, 0xB9, 0x7E, 0x0C, 0x00, 0xF2, 0x4E, 0x38, 0xCD, 0x0C, 0x00, + 0x08, 0x70, 0x02, 0x00, 0xD6, 0x7C, 0x92, 0x48, 0x98, 0x7D, 0xB6, 0x04, 0x82, 0x45, 0x98, 0x7D, + 0xDC, 0x04, 0x82, 0x42, 0x78, 0x7D, 0xBE, 0x04, 0x78, 0x2D, 0x98, 0x04, 0x78, 0xAD, 0x9A, 0x04, + 0x36, 0x27, 0x78, 0x7D, 0xC0, 0x04, 0x06, 0x32, 0x36, 0xA7, 0x4B, 0x14, 0x00, 0x00, 0x06, 0xB2, + 0x06, 0x3A, 0x06, 0x2A, 0x4B, 0x14, 0x00, 0x00, 0xF8, 0x7D, 0x38, 0x0C, 0x26, 0x2B, 0x02, 0x22, + 0x38, 0x6D, 0x34, 0x0C, 0xC6, 0x62, 0xC2, 0x13, 0xCC, 0x70, 0x13, 0x00, 0x12, 0x04, 0x24, 0x71, + 0xA9, 0x7D, 0x38, 0x0C, 0x38, 0x7E, 0x2C, 0x0C, 0xC6, 0x72, 0xC2, 0x06, 0x08, 0x70, 0x02, 0x00, + 0x66, 0x7C, 0xB9, 0x7E, 0x0C, 0x00, 0xB9, 0x2E, 0x34, 0x0C, 0xF2, 0x16, 0x34, 0x71, 0xC3, 0x77, + 0xA9, 0x7D, 0x38, 0x0C, 0x92, 0x11, 0x14, 0x71, 0xB9, 0x7D, 0x34, 0x0C, 0xA9, 0x0D, 0x38, 0x0C, + 0xF2, 0x0B, 0x38, 0x7D, 0x30, 0x0C, 0xC6, 0x72, 0xB2, 0x07, 0x04, 0x73, 0xA9, 0x7D, 0x38, 0x0C, + 0x14, 0x71, 0xB9, 0x7D, 0x34, 0x0C, 0x58, 0xC1, 0x08, 0x00, 0x40, 0xA1, 0x2C, 0x10, 0x18, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, 0x0C, 0x60, 0xFC, 0x0A, 0x38, 0x56, 0x0C, 0x00, + 0x0C, 0x20, 0x50, 0x01, 0x54, 0x51, 0x26, 0x26, 0x06, 0x76, 0x0C, 0xF0, 0x32, 0x00, 0x0C, 0xE0, + 0x3C, 0x00, 0x04, 0x40, 0xC4, 0x50, 0x2F, 0x34, 0x06, 0x00, 0x82, 0x04, 0x99, 0xE3, 0x28, 0x03, + 0xF2, 0x03, 0x99, 0xF3, 0x28, 0x03, 0x24, 0x41, 0xCC, 0x40, 0x17, 0x00, 0x92, 0xF4, 0x2C, 0x60, + 0x18, 0x00, 0xC6, 0x62, 0x92, 0xEF, 0xC4, 0x50, 0x0C, 0x60, 0x32, 0x00, 0x99, 0x67, 0x91, 0x04, + 0x0C, 0x60, 0x1E, 0x00, 0x92, 0x03, 0x0C, 0x60, 0x14, 0x00, 0x99, 0x67, 0x92, 0x04, 0x04, 0x62, + 0x99, 0x67, 0x93, 0x04, 0x04, 0x65, 0x99, 0x67, 0x94, 0x04, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0x0C, 0xE0, 0xFC, 0x0A, 0x2F, 0xDE, 0x04, 0x00, + 0x26, 0x44, 0xD1, 0x81, 0x2F, 0xC4, 0x05, 0x00, 0xF0, 0x7C, 0x06, 0x92, 0x06, 0xA3, 0x92, 0x05, + 0x18, 0x7E, 0x91, 0x04, 0x99, 0x7D, 0x28, 0x03, 0x28, 0x7E, 0x14, 0x00, 0x68, 0xBD, 0x28, 0x03, + 0x28, 0x2E, 0x14, 0x03, 0x06, 0x3B, 0x26, 0x27, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0x8B, 0x16, 0x00, 0x00, 0x70, 0x7C, 0x0C, 0x60, 0xFF, 0xFF, 0x56, 0x62, 0xC6, 0x76, 0x23, 0x52, + 0x22, 0x13, 0x38, 0x7E, 0x0C, 0x00, 0xDC, 0x70, 0x00, 0x02, 0x18, 0x7E, 0x94, 0x04, 0x36, 0xB7, + 0x82, 0x02, 0x34, 0xB3, 0x99, 0xBD, 0x28, 0x03, 0x18, 0x7E, 0x92, 0x04, 0x68, 0x6D, 0x28, 0x03, + 0xC6, 0x67, 0x32, 0x32, 0xF2, 0x2F, 0x18, 0x7E, 0x92, 0x04, 0xC6, 0xB7, 0x92, 0x21, 0xC4, 0x90, + 0x02, 0x0A, 0x14, 0x72, 0x26, 0x7C, 0x70, 0x47, 0x04, 0x20, 0xC6, 0x46, 0x12, 0x26, 0xCC, 0x90, + 0x15, 0x00, 0x12, 0x06, 0x78, 0x4C, 0x02, 0x00, 0x04, 0x20, 0xC6, 0x46, 0x12, 0x1E, 0xC4, 0xA0, + 0x02, 0x0A, 0x1C, 0x70, 0x30, 0x00, 0x26, 0x7C, 0x70, 0x47, 0x04, 0x20, 0xC6, 0x46, 0x12, 0x15, + 0xC4, 0xAC, 0x12, 0x06, 0x78, 0x4C, 0x30, 0x00, 0x04, 0x20, 0xC6, 0x46, 0x12, 0x0E, 0x18, 0x7E, + 0x93, 0x04, 0x26, 0xB7, 0x33, 0xBB, 0x99, 0xBD, 0x28, 0x03, 0x18, 0x7E, 0x91, 0x04, 0xC6, 0xB7, + 0x02, 0x03, 0x99, 0x7D, 0x28, 0x03, 0x06, 0x25, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, + 0x20, 0x00, 0xE1, 0xF0, 0x38, 0x70, 0x70, 0x1A, 0x3C, 0x10, 0x34, 0x02, 0x0C, 0x60, 0x7A, 0x00, + 0xD9, 0xC1, 0x24, 0x02, 0xD9, 0x81, 0x14, 0x02, 0x26, 0x67, 0x10, 0x66, 0x18, 0xE7, 0x79, 0x00, + 0x18, 0x77, 0x7C, 0x00, 0xB9, 0x61, 0xDC, 0x01, 0x0C, 0xD0, 0xFC, 0x0A, 0x38, 0x6D, 0x0C, 0x00, + 0x04, 0x51, 0xD6, 0x56, 0x28, 0x5D, 0x18, 0x03, 0x82, 0x0B, 0xCC, 0x50, 0xF3, 0x01, 0xD2, 0x11, + 0x04, 0xF6, 0x04, 0x71, 0xB9, 0xF1, 0xDC, 0x01, 0x0C, 0xE0, 0x28, 0x00, 0xF2, 0x0A, 0xCC, 0x50, + 0xC1, 0x01, 0xD2, 0x07, 0x04, 0x23, 0x04, 0x71, 0xB9, 0x21, 0xDC, 0x01, 0x0C, 0xE0, 0x14, 0x00, + 0x98, 0x5D, 0x1F, 0x03, 0x92, 0x0C, 0xAB, 0xFB, 0x02, 0x00, 0x38, 0x7D, 0x0C, 0x00, 0x1C, 0x30, + 0x01, 0x02, 0x56, 0x73, 0xB9, 0x7D, 0x0C, 0x00, 0xFA, 0xBF, 0x02, 0x00, 0x0C, 0x40, 0x00, 0x02, + 0xD6, 0x46, 0x82, 0x0B, 0x38, 0x41, 0xDC, 0x01, 0xC6, 0x47, 0xC2, 0x04, 0x36, 0x47, 0x13, 0x74, + 0xF2, 0x02, 0x04, 0x71, 0xB9, 0x71, 0xDC, 0x01, 0xC4, 0x51, 0x92, 0x0E, 0x18, 0x7D, 0x25, 0x03, + 0x38, 0xF1, 0xDC, 0x01, 0xC6, 0x7F, 0xB2, 0x08, 0x1C, 0x20, 0x01, 0x02, 0x56, 0x62, 0xB9, 0x6D, + 0x0C, 0x00, 0xFA, 0xA2, 0x02, 0x00, 0x38, 0x30, 0x80, 0x1A, 0x0C, 0x60, 0x20, 0x01, 0x26, 0x61, + 0x06, 0x26, 0xB9, 0x31, 0xEC, 0x01, 0x0C, 0x40, 0xB5, 0x00, 0x04, 0x30, 0xB9, 0x61, 0xD8, 0x01, + 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x40, 0x20, 0x01, 0x06, 0x21, 0x04, 0x30, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x28, 0x7D, 0x14, 0x00, 0x28, 0x2D, 0x14, 0x03, 0x06, 0x3E, 0x26, 0x27, + 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x0C, 0x70, 0x74, 0x0B, + 0xB9, 0x71, 0x00, 0x02, 0x04, 0x70, 0xB9, 0x71, 0xE8, 0x01, 0xB9, 0x71, 0xE4, 0x01, 0x04, 0x71, + 0x23, 0x52, 0xB9, 0x71, 0xE0, 0x01, 0x04, 0xC0, 0x18, 0x7D, 0x8F, 0x06, 0x38, 0xA1, 0xE8, 0x01, + 0xC4, 0x71, 0x26, 0xAC, 0x23, 0xAA, 0xC2, 0x0B, 0x38, 0x61, 0xE4, 0x01, 0x38, 0x51, 0xEC, 0x01, + 0x43, 0x2C, 0x43, 0x36, 0x43, 0x4A, 0x0B, 0xFF, 0x02, 0x00, 0x06, 0x52, 0x38, 0x61, 0xEC, 0x01, + 0xB9, 0xA1, 0xF0, 0x01, 0x2F, 0x7A, 0x0A, 0x00, 0x26, 0x76, 0x70, 0x77, 0xC6, 0x75, 0x2A, 0x5B, + 0x01, 0x00, 0x04, 0x71, 0x26, 0x7C, 0x38, 0xE1, 0xE0, 0x01, 0x04, 0x80, 0x23, 0x77, 0xB9, 0x81, + 0xF4, 0x01, 0xB9, 0x81, 0xF8, 0x01, 0xB9, 0x81, 0xFC, 0x01, 0x06, 0x98, 0xB9, 0x71, 0x04, 0x02, + 0x18, 0x4D, 0x8F, 0x06, 0x23, 0xB8, 0xC4, 0x41, 0x2F, 0x6A, 0x0B, 0x00, 0x2F, 0x7C, 0x0B, 0x00, + 0x23, 0x66, 0x23, 0x77, 0xC2, 0x13, 0x38, 0xF1, 0xE4, 0x01, 0x38, 0x51, 0xEC, 0x01, 0xB9, 0x61, + 0x10, 0x02, 0x43, 0x27, 0x43, 0x46, 0x43, 0x3F, 0xB9, 0x71, 0x08, 0x02, 0x0B, 0xFF, 0x02, 0x00, + 0x38, 0x71, 0x08, 0x02, 0x38, 0x61, 0x10, 0x02, 0x06, 0x52, 0x38, 0x21, 0xEC, 0x01, 0x26, 0x66, + 0x26, 0x62, 0x70, 0x36, 0xC6, 0x35, 0x2A, 0xC1, 0x00, 0x00, 0x38, 0x4D, 0x0C, 0x00, 0x0C, 0x60, + 0x64, 0x00, 0xDC, 0x40, 0x00, 0x02, 0x92, 0x02, 0x23, 0x63, 0x04, 0x46, 0x26, 0x47, 0x57, 0x41, + 0x26, 0x4D, 0x30, 0x34, 0xB9, 0x51, 0x0C, 0x02, 0x06, 0x26, 0xB9, 0x71, 0x08, 0x02, 0xB9, 0x61, + 0x10, 0x02, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x31, 0xF4, 0x01, 0x38, 0x41, 0x00, 0x02, 0x38, 0x61, + 0x10, 0x02, 0x26, 0x32, 0xB9, 0x31, 0xF4, 0x01, 0x30, 0x34, 0x06, 0x26, 0x4B, 0x14, 0x00, 0x00, + 0x38, 0xF1, 0xF8, 0x01, 0x38, 0x61, 0x10, 0x02, 0x38, 0x51, 0x0C, 0x02, 0x38, 0x71, 0x08, 0x02, + 0x26, 0xF2, 0x38, 0x21, 0xFC, 0x01, 0xB9, 0xF1, 0xF8, 0x01, 0x04, 0x31, 0x26, 0x26, 0xB8, 0x61, + 0xE4, 0x01, 0xB9, 0x21, 0xFC, 0x01, 0x26, 0x3B, 0x23, 0x33, 0x82, 0x7A, 0x1C, 0x60, 0x18, 0x00, + 0xC4, 0x90, 0x26, 0x6A, 0x26, 0x6B, 0x23, 0x66, 0x92, 0x2F, 0x06, 0x46, 0x0C, 0xF0, 0x20, 0x01, + 0xF7, 0x40, 0x26, 0xF1, 0x26, 0x4F, 0x10, 0x44, 0x04, 0x21, 0x56, 0x26, 0x57, 0x21, 0x63, 0x42, + 0xD4, 0x4F, 0x82, 0x03, 0x13, 0xE4, 0xF2, 0x63, 0xC4, 0x70, 0x82, 0x0F, 0x14, 0x41, 0x26, 0x46, + 0x06, 0x74, 0x0C, 0x20, 0x20, 0x01, 0xE7, 0x70, 0x26, 0x21, 0x26, 0x72, 0x10, 0x77, 0x54, 0x41, + 0x57, 0x41, 0x63, 0x74, 0xD4, 0x7F, 0x92, 0x0E, 0x24, 0x61, 0x06, 0x76, 0x0C, 0x40, 0x20, 0x01, + 0xE7, 0x70, 0x26, 0x41, 0x26, 0x74, 0x10, 0x77, 0x54, 0x61, 0x57, 0x61, 0x63, 0x76, 0xD4, 0x7F, + 0x82, 0x47, 0x13, 0xE7, 0xF2, 0x44, 0x04, 0x21, 0x26, 0x26, 0x06, 0x42, 0x0C, 0xF0, 0x20, 0x01, + 0xE7, 0x40, 0x26, 0xF1, 0x26, 0x4F, 0x10, 0x44, 0x54, 0x21, 0x57, 0x21, 0x63, 0x42, 0xD4, 0x4F, + 0x82, 0x03, 0xC6, 0x4E, 0x92, 0x10, 0x06, 0x46, 0x0C, 0x20, 0x20, 0x01, 0x26, 0x21, 0xF7, 0x40, + 0x26, 0x42, 0x10, 0x44, 0x04, 0x21, 0x56, 0x26, 0x57, 0x21, 0x63, 0x42, 0xD4, 0x4F, 0x82, 0x05, + 0xC6, 0x4E, 0x82, 0x03, 0x13, 0x44, 0xF2, 0x14, 0xC4, 0x70, 0x82, 0x21, 0x34, 0x61, 0x06, 0x76, + 0x0C, 0x40, 0x20, 0x01, 0xE7, 0x70, 0x26, 0x41, 0x26, 0x74, 0x10, 0x77, 0x54, 0x61, 0x57, 0x61, + 0x63, 0x76, 0xD4, 0x7F, 0x04, 0x91, 0x82, 0x14, 0xC6, 0x7E, 0x82, 0x12, 0x13, 0x47, 0xC6, 0x4E, + 0x06, 0x64, 0xC2, 0x02, 0x06, 0x6E, 0x34, 0x41, 0x14, 0x71, 0x57, 0x42, 0x26, 0x7E, 0x26, 0x41, + 0x57, 0x72, 0x99, 0x64, 0x0E, 0x00, 0x26, 0x71, 0x99, 0x67, 0x0E, 0x00, 0x04, 0x91, 0x38, 0x61, + 0x04, 0x02, 0x24, 0x81, 0x26, 0xB6, 0x2F, 0x68, 0x0C, 0x00, 0x23, 0x66, 0xCC, 0x60, 0x16, 0x00, + 0x23, 0x7B, 0xCA, 0x1F, 0xFF, 0xFF, 0x06, 0xB3, 0xC4, 0x90, 0x06, 0xC7, 0x92, 0x07, 0x38, 0x71, + 0xE0, 0x01, 0x24, 0x71, 0x13, 0x77, 0xB9, 0x71, 0xE0, 0x01, 0x04, 0x71, 0xD6, 0x7A, 0x06, 0x3E, + 0x57, 0x32, 0x82, 0x11, 0x06, 0x7A, 0x0C, 0xF0, 0x20, 0x01, 0xF7, 0x70, 0x26, 0xF1, 0x26, 0x7F, + 0x10, 0x67, 0x24, 0xA1, 0xB9, 0xA1, 0xF0, 0x01, 0x14, 0xA1, 0x66, 0x63, 0x26, 0xAB, 0x91, 0x67, + 0x23, 0xAA, 0xF2, 0x02, 0x06, 0xAB, 0x38, 0x21, 0xF0, 0x01, 0xB9, 0x51, 0x0C, 0x02, 0x0C, 0x40, + 0x20, 0x01, 0x26, 0x41, 0xF7, 0x20, 0x26, 0x24, 0x06, 0x4A, 0x66, 0x3E, 0xF7, 0x40, 0x33, 0x33, + 0x23, 0x44, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x04, 0x71, 0xD6, 0x7A, 0x38, 0x51, 0x0C, 0x02, + 0x82, 0x12, 0x38, 0x71, 0xF0, 0x01, 0x34, 0x71, 0x26, 0xA7, 0x06, 0x6A, 0x0C, 0x70, 0x20, 0x01, + 0x26, 0x71, 0xF7, 0x60, 0x26, 0x67, 0x10, 0x46, 0x54, 0xA1, 0x57, 0xA1, 0x06, 0x7E, 0x53, 0x7A, + 0x66, 0x74, 0x91, 0x76, 0x34, 0xE1, 0x57, 0xE2, 0x26, 0xE1, 0x30, 0x7E, 0x38, 0x61, 0xF4, 0x01, + 0x26, 0x76, 0xB1, 0x7E, 0x38, 0x61, 0xF8, 0x01, 0x38, 0x7E, 0x04, 0x00, 0x26, 0x76, 0xB9, 0x7E, + 0x04, 0x00, 0x38, 0x61, 0xFC, 0x01, 0x38, 0x7E, 0x08, 0x00, 0x26, 0x76, 0xB9, 0x7E, 0x08, 0x00, + 0x28, 0x7E, 0x0C, 0x00, 0x26, 0xB7, 0x38, 0x71, 0xE0, 0x01, 0xA9, 0xBE, 0x0C, 0x00, 0xCC, 0x70, + 0x10, 0x00, 0xD2, 0x1F, 0x24, 0xC1, 0x23, 0xCC, 0xCC, 0xC0, 0x16, 0x00, 0xCA, 0x86, 0xFE, 0xFF, + 0x38, 0x71, 0xE4, 0x01, 0x38, 0x61, 0x00, 0x02, 0x24, 0x71, 0x23, 0x77, 0xB9, 0x71, 0xE4, 0x01, + 0x38, 0x71, 0xE8, 0x01, 0x24, 0x64, 0x2C, 0x70, 0x18, 0x00, 0x23, 0x77, 0xB9, 0x71, 0xE8, 0x01, + 0x38, 0x71, 0xE4, 0x01, 0xB9, 0x61, 0x00, 0x02, 0xC4, 0x7E, 0x9A, 0x6E, 0xFE, 0xFF, 0xF2, 0x05, + 0x0C, 0x60, 0x11, 0x00, 0xB9, 0x61, 0xE0, 0x01, 0x06, 0xE1, 0x04, 0x60, 0x38, 0x21, 0xE0, 0x01, + 0x13, 0x76, 0xC6, 0x72, 0xB2, 0x36, 0x18, 0x3E, 0x0E, 0x00, 0x14, 0x71, 0x26, 0x73, 0xC6, 0x67, + 0x0C, 0x40, 0x10, 0x00, 0x06, 0x56, 0x26, 0x4E, 0x92, 0x29, 0x06, 0x74, 0x38, 0xF1, 0xE0, 0x01, + 0x24, 0x51, 0xC6, 0x5F, 0x32, 0x23, 0x68, 0x27, 0x0E, 0x00, 0xC6, 0x32, 0x92, 0x1C, 0x28, 0xF7, + 0x0C, 0x00, 0x28, 0x2E, 0x0C, 0x00, 0x26, 0x2F, 0xA9, 0x2E, 0x0C, 0x00, 0x30, 0xFE, 0x30, 0x27, + 0x26, 0x2F, 0xB1, 0x2E, 0x38, 0xFE, 0x04, 0x00, 0x38, 0x27, 0x04, 0x00, 0x26, 0x2F, 0xB9, 0x2E, + 0x04, 0x00, 0x38, 0xFE, 0x08, 0x00, 0x38, 0x27, 0x08, 0x00, 0x26, 0x2F, 0xB9, 0x2E, 0x08, 0x00, + 0xA9, 0x07, 0x0C, 0x00, 0x2C, 0x70, 0x10, 0x00, 0xF2, 0xDA, 0x24, 0x61, 0x06, 0xE4, 0xF2, 0xC7, + 0x04, 0x90, 0x06, 0xB9, 0x06, 0xCD, 0x04, 0x61, 0x0C, 0x80, 0x28, 0x08, 0x18, 0x7D, 0x1F, 0x03, + 0xC6, 0x7B, 0xC2, 0x7A, 0x06, 0x4B, 0xD7, 0x42, 0x26, 0x4C, 0x28, 0x74, 0x5C, 0x01, 0x0C, 0x30, + 0x20, 0x01, 0x06, 0x57, 0xF7, 0x50, 0x26, 0x31, 0x26, 0x53, 0x10, 0xE5, 0x04, 0x51, 0x56, 0x57, + 0x57, 0x51, 0x63, 0xE5, 0xD4, 0xEF, 0x0C, 0xA0, 0x5C, 0x01, 0x26, 0xA4, 0x82, 0x5A, 0x34, 0xE1, + 0x57, 0xE2, 0x26, 0xE1, 0xE8, 0x5E, 0x0E, 0x00, 0x82, 0x05, 0x14, 0xE1, 0x26, 0xE5, 0x57, 0xE2, + 0x26, 0xE1, 0xA8, 0x5E, 0x0C, 0x00, 0x92, 0x1A, 0x18, 0x5E, 0x0F, 0x00, 0x2F, 0x27, 0x07, 0x00, + 0xD7, 0x52, 0x26, 0x5D, 0x28, 0x35, 0x5C, 0x01, 0x26, 0x28, 0x26, 0x33, 0x26, 0x38, 0x70, 0x22, + 0x70, 0x33, 0xC6, 0x23, 0x02, 0x07, 0x28, 0x44, 0x5E, 0x01, 0xA9, 0x75, 0x5C, 0x01, 0xA9, 0x45, + 0x5E, 0x01, 0xA9, 0x0A, 0x1C, 0x00, 0x24, 0x91, 0xF2, 0x34, 0x38, 0x71, 0xDC, 0x01, 0xA9, 0x5A, + 0x1C, 0x00, 0xC6, 0x57, 0xA2, 0x2E, 0xB8, 0x7E, 0x08, 0x00, 0x92, 0x03, 0xB9, 0x6E, 0x08, 0x00, + 0x38, 0x7E, 0x08, 0x00, 0x38, 0x2E, 0x04, 0x00, 0xB9, 0x61, 0x10, 0x02, 0x06, 0x37, 0xB9, 0x71, + 0x08, 0x02, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x71, 0x08, 0x02, 0x43, 0x52, 0x30, 0x2E, 0xB9, 0x51, + 0x0C, 0x02, 0x06, 0x37, 0xAB, 0x15, 0x00, 0x00, 0x04, 0x3A, 0x43, 0x22, 0x8B, 0x16, 0x00, 0x00, + 0x38, 0x51, 0x0C, 0x02, 0xA9, 0x2A, 0x14, 0x00, 0x04, 0x3A, 0x06, 0x25, 0x8B, 0x16, 0x00, 0x00, + 0x99, 0xBE, 0x0F, 0x00, 0x38, 0x61, 0x10, 0x02, 0xA9, 0x2A, 0x16, 0x00, 0xA9, 0x0E, 0x0C, 0x00, + 0x28, 0x7A, 0x1C, 0x00, 0x28, 0x5D, 0x12, 0x00, 0xC6, 0x57, 0xB2, 0x03, 0xA9, 0x7C, 0x12, 0x00, + 0x24, 0xB1, 0x13, 0xBB, 0xF2, 0x84, 0x38, 0x7C, 0x0C, 0x00, 0x08, 0x60, 0x02, 0x00, 0xD6, 0x67, + 0x82, 0x07, 0x1C, 0xF0, 0x01, 0x02, 0x56, 0x7F, 0xB9, 0x7C, 0x0C, 0x00, 0xF2, 0x0D, 0xC4, 0x90, + 0x82, 0x04, 0x6C, 0x70, 0x00, 0x02, 0xF2, 0x04, 0x1C, 0x20, 0x01, 0x02, 0x56, 0x72, 0xB9, 0x7C, + 0x0C, 0x00, 0x2B, 0x8A, 0x03, 0x00, 0x58, 0xC1, 0x24, 0x02, 0x58, 0x81, 0x14, 0x02, 0x2C, 0x10, + 0x34, 0x02, 0xE1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, 0x14, 0x61, 0x99, 0x07, 0x1C, 0x03, 0x99, 0x07, + 0x1F, 0x03, 0x99, 0x07, 0x24, 0x03, 0x99, 0x67, 0x22, 0x03, 0x99, 0x07, 0x23, 0x03, 0xE1, 0xF0, + 0x34, 0x18, 0xC1, 0xE1, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x7E, 0xDF, 0x00, 0x04, 0x4D, 0x06, 0x27, + 0xD7, 0x22, 0x36, 0x47, 0x26, 0x2E, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x30, 0xD7, 0x42, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x98, 0x7E, 0xDF, 0x00, 0x92, 0x03, 0x2B, 0x36, 0x03, 0x00, 0xB9, 0x0E, + 0xFC, 0x02, 0xB9, 0x0E, 0x00, 0x03, 0x99, 0x0E, 0x25, 0x03, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0x2F, 0x75, 0x05, 0x00, 0xC4, 0x50, 0x3C, 0x10, 0x18, 0x00, 0x26, 0x75, 0xD7, 0x71, 0xD9, 0xC1, + 0x08, 0x00, 0xC1, 0xA1, 0x2F, 0x64, 0x07, 0x00, 0x82, 0x06, 0xC4, 0x5D, 0x14, 0x71, 0x04, 0xC0, + 0x82, 0x04, 0xF2, 0x02, 0x06, 0x75, 0x04, 0xC1, 0xC4, 0x40, 0x82, 0x07, 0xCC, 0x40, 0x16, 0x00, + 0x14, 0xD1, 0x04, 0xB0, 0x82, 0x04, 0xF2, 0x02, 0x06, 0xD4, 0x04, 0xB1, 0x26, 0x66, 0x26, 0x63, + 0x70, 0xF6, 0x2F, 0x67, 0x05, 0x00, 0x2F, 0xE6, 0x06, 0x00, 0x26, 0xE6, 0xD7, 0xE1, 0x06, 0x6D, + 0x2F, 0xA6, 0x04, 0x00, 0x26, 0xAE, 0x26, 0xAA, 0x26, 0xA3, 0x70, 0xAA, 0xC6, 0xAF, 0x12, 0x11, + 0x24, 0x61, 0x43, 0x66, 0xC6, 0x6B, 0x02, 0xF5, 0x24, 0x71, 0x43, 0x77, 0xC6, 0x7C, 0x02, 0xEA, + 0x28, 0x60, 0x16, 0x0E, 0x04, 0x70, 0xC6, 0xF6, 0x22, 0x05, 0xA1, 0xF2, 0x04, 0x71, 0xF2, 0x02, + 0x04, 0x70, 0x58, 0xC1, 0x08, 0x00, 0x40, 0xA1, 0x06, 0x27, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x28, 0x00, 0xD9, 0x81, 0x08, 0x00, 0x86, 0xB6, 0xD9, 0xC1, 0x18, 0x00, 0x06, 0xA3, + 0x06, 0xD2, 0x06, 0xE4, 0x06, 0xC5, 0x92, 0x13, 0x30, 0x74, 0x38, 0xB4, 0x04, 0x00, 0x26, 0xB7, + 0x38, 0x74, 0x08, 0x00, 0x26, 0xB7, 0x38, 0x74, 0x0C, 0x00, 0x26, 0xB7, 0x38, 0x74, 0x10, 0x00, + 0xA6, 0xB7, 0x92, 0x05, 0x38, 0xE5, 0x08, 0x00, 0x04, 0xB1, 0xF2, 0x35, 0x30, 0x3C, 0x30, 0x2E, + 0x4B, 0x14, 0x00, 0x00, 0xB1, 0x2E, 0x06, 0x72, 0x38, 0x3C, 0x04, 0x00, 0x38, 0x2E, 0x04, 0x00, + 0xB9, 0x71, 0x04, 0x00, 0x4B, 0x14, 0x00, 0x00, 0xB9, 0x2E, 0x04, 0x00, 0x06, 0x62, 0x38, 0x3C, + 0x08, 0x00, 0x38, 0x2E, 0x08, 0x00, 0xB1, 0x61, 0x4B, 0x14, 0x00, 0x00, 0xB9, 0x2E, 0x08, 0x00, + 0x38, 0x3C, 0x0C, 0x00, 0x06, 0x82, 0x38, 0x2E, 0x0C, 0x00, 0x4B, 0x14, 0x00, 0x00, 0xB9, 0x2E, + 0x0C, 0x00, 0x06, 0x92, 0x38, 0x3C, 0x10, 0x00, 0x38, 0x2E, 0x10, 0x00, 0x4B, 0x14, 0x00, 0x00, + 0x30, 0x61, 0x38, 0x71, 0x04, 0x00, 0xB9, 0x2E, 0x10, 0x00, 0x2F, 0xE7, 0x06, 0x00, 0x26, 0xE8, + 0x26, 0xE9, 0x26, 0xE2, 0x06, 0x3B, 0x06, 0x2E, 0xAB, 0x15, 0x00, 0x00, 0x04, 0x3A, 0xAB, 0x15, + 0x00, 0x00, 0xC4, 0xA0, 0x92, 0x08, 0xB9, 0xBD, 0x04, 0x00, 0xB9, 0xED, 0x0C, 0x00, 0xA9, 0x2D, + 0x14, 0x00, 0xF2, 0x11, 0xC4, 0xA1, 0x92, 0x08, 0xB9, 0xBD, 0x08, 0x00, 0xB9, 0xED, 0x10, 0x00, + 0xA9, 0x2D, 0x16, 0x00, 0xF2, 0x08, 0xC4, 0xA2, 0x92, 0x04, 0xA9, 0x2D, 0x18, 0x00, 0xF2, 0x03, + 0xA9, 0x2D, 0x1A, 0x00, 0x58, 0xC1, 0x18, 0x00, 0x58, 0x81, 0x08, 0x00, 0x2C, 0x10, 0x28, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x0B, 0xCB, 0x03, 0x00, 0x30, 0xF1, 0x16, 0x22, + 0xF7, 0x2F, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x7E, 0x8D, 0x06, 0xC4, 0x72, 0xC2, 0x06, 0x38, 0x70, + 0x70, 0x1A, 0x28, 0x77, 0x30, 0x00, 0xF2, 0x14, 0xC4, 0x72, 0x92, 0x06, 0x38, 0x70, 0x70, 0x1A, + 0x28, 0x77, 0x2E, 0x00, 0xF2, 0x0D, 0x98, 0x70, 0xA2, 0x1B, 0x82, 0x06, 0x08, 0x70, 0x00, 0x80, + 0x28, 0x77, 0xB0, 0xDC, 0xF2, 0x05, 0x38, 0x70, 0x70, 0x1A, 0x28, 0x77, 0x2C, 0x00, 0xA9, 0x7E, + 0x04, 0x03, 0x28, 0x7E, 0x04, 0x03, 0x28, 0x5E, 0x12, 0x03, 0x26, 0x57, 0x38, 0x70, 0x70, 0x1A, + 0x23, 0x55, 0xA9, 0x5E, 0x06, 0x03, 0x28, 0x67, 0x32, 0x00, 0x98, 0x70, 0xB0, 0x1B, 0xA9, 0x6E, + 0x20, 0x03, 0x82, 0x0C, 0x38, 0x7E, 0x0C, 0x00, 0xD4, 0x71, 0x82, 0x08, 0x08, 0x70, 0x00, 0x80, + 0x28, 0x77, 0x84, 0xDC, 0x26, 0x57, 0xA9, 0x5E, 0x06, 0x03, 0x98, 0x70, 0xCD, 0x1B, 0x92, 0x04, + 0x98, 0x70, 0xC1, 0x1B, 0x82, 0x0B, 0xB8, 0x70, 0x8C, 0x19, 0x92, 0x08, 0x28, 0x7E, 0x06, 0x03, + 0x2F, 0x57, 0x07, 0x00, 0x26, 0x75, 0xA9, 0x7E, 0x06, 0x03, 0x18, 0x70, 0xCC, 0x1B, 0x93, 0x07, + 0x92, 0x05, 0x18, 0x70, 0xCB, 0x1B, 0x93, 0x07, 0x82, 0x0C, 0xB8, 0x70, 0x8C, 0x19, 0x92, 0x09, + 0x28, 0x7E, 0x06, 0x03, 0xD7, 0x61, 0xD7, 0x71, 0xA9, 0x7E, 0x06, 0x03, 0xA9, 0x6E, 0x20, 0x03, + 0x4B, 0x3E, 0x00, 0x00, 0x23, 0x22, 0x0C, 0x30, 0x18, 0x00, 0x4B, 0x18, 0x00, 0x00, 0xA3, 0x22, + 0x82, 0x04, 0xCC, 0x20, 0x16, 0x00, 0x92, 0x0A, 0x38, 0x70, 0x70, 0x1A, 0x28, 0x67, 0x34, 0x00, + 0x28, 0x7E, 0x06, 0x03, 0x26, 0x76, 0xA9, 0x7E, 0x06, 0x03, 0x28, 0x2E, 0x06, 0x03, 0x38, 0x70, + 0x70, 0x1A, 0xA9, 0x2E, 0x08, 0x03, 0x18, 0x37, 0x8C, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, + 0x64, 0x00, 0x8B, 0x16, 0x00, 0x00, 0xA9, 0x2E, 0x06, 0x03, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x50, 0x01, 0x0C, 0x20, 0x68, 0x00, + 0x0C, 0x40, 0x2E, 0x00, 0x26, 0x21, 0x04, 0x30, 0xD9, 0xC1, 0x40, 0x01, 0xD9, 0x81, 0x30, 0x01, + 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, 0x0C, 0x60, 0xFF, 0x0F, 0xA9, 0x67, + 0x14, 0x03, 0x38, 0x40, 0x80, 0x1A, 0xA9, 0x07, 0x16, 0x03, 0x38, 0x50, 0x7C, 0x1A, 0xA9, 0x07, + 0x18, 0x03, 0x18, 0xD7, 0xE2, 0x00, 0xB9, 0x41, 0x10, 0x01, 0x06, 0x87, 0x0C, 0x70, 0x66, 0x00, + 0x26, 0x71, 0xB9, 0x51, 0x14, 0x01, 0xB9, 0x71, 0xFC, 0x00, 0x18, 0x78, 0xE4, 0x00, 0xC6, 0x7D, + 0xCA, 0x9C, 0x01, 0x00, 0x38, 0x78, 0x00, 0x03, 0x73, 0x7D, 0xD4, 0x71, 0x8A, 0x39, 0x02, 0x00, + 0x2F, 0x7D, 0x0D, 0x00, 0x0C, 0x90, 0x1C, 0x00, 0x26, 0x7D, 0x26, 0x9D, 0xD7, 0x71, 0x57, 0x91, + 0x18, 0xC8, 0xE1, 0x00, 0xB9, 0x71, 0x04, 0x01, 0xB9, 0x91, 0x0C, 0x01, 0xF2, 0x08, 0x18, 0x68, + 0x8D, 0x06, 0xC4, 0x62, 0x8A, 0x8C, 0x01, 0x00, 0x24, 0xC1, 0x13, 0xCC, 0x18, 0x78, 0xE3, 0x00, + 0xC6, 0x7C, 0xCA, 0x1E, 0x02, 0x00, 0x38, 0x78, 0xFC, 0x02, 0x73, 0x7C, 0xD4, 0x71, 0x82, 0xF5, + 0x38, 0xE1, 0x04, 0x01, 0x26, 0xEC, 0xB9, 0xE1, 0x08, 0x01, 0x43, 0xEE, 0x2F, 0xBE, 0x0E, 0x00, + 0x0C, 0x70, 0x28, 0x08, 0x26, 0x7B, 0x70, 0x67, 0x78, 0x78, 0x06, 0x03, 0xC6, 0x67, 0x22, 0xE5, + 0x06, 0x9E, 0x0C, 0x70, 0x68, 0x00, 0xF7, 0x91, 0x26, 0x71, 0x38, 0xA1, 0x08, 0x01, 0x26, 0x79, + 0x10, 0x77, 0x54, 0xA7, 0x63, 0x7A, 0xD4, 0x71, 0x92, 0xD8, 0x43, 0x7C, 0x43, 0x6D, 0x0C, 0x20, + 0xFA, 0x00, 0x06, 0x47, 0x26, 0x21, 0x0C, 0x30, 0x28, 0x08, 0x06, 0x56, 0xB9, 0x71, 0x28, 0x01, + 0xA9, 0x01, 0xFA, 0x00, 0xB9, 0x61, 0x00, 0x01, 0x0B, 0x39, 0x03, 0x00, 0xC4, 0x20, 0x38, 0x71, + 0x28, 0x01, 0x82, 0xBE, 0x06, 0x2C, 0x06, 0x3D, 0x2B, 0x45, 0x03, 0x00, 0xC4, 0x20, 0x92, 0xBD, + 0x78, 0x71, 0xFA, 0x00, 0x28, 0x68, 0x18, 0x03, 0xC6, 0x76, 0x22, 0x03, 0xA9, 0x78, 0x18, 0x03, + 0x0C, 0x70, 0x68, 0x00, 0x26, 0x71, 0x26, 0x97, 0x10, 0x59, 0x04, 0x71, 0x06, 0x67, 0x53, 0x6A, + 0xCC, 0xC0, 0x17, 0x00, 0x66, 0x65, 0x91, 0x69, 0x82, 0x0E, 0x06, 0x57, 0x26, 0x5E, 0x06, 0x65, + 0x0C, 0x90, 0x68, 0x00, 0xE7, 0x61, 0x26, 0x91, 0x26, 0x69, 0x54, 0x57, 0x53, 0x75, 0x10, 0x56, + 0x66, 0x75, 0x91, 0x76, 0xC4, 0xDD, 0x9A, 0x32, 0x01, 0x00, 0x38, 0xE1, 0x14, 0x01, 0x38, 0x70, + 0x70, 0x1A, 0x26, 0xBE, 0x28, 0x37, 0x3E, 0x00, 0x70, 0x2B, 0x14, 0xB1, 0x4B, 0x14, 0x00, 0x00, + 0x0C, 0x30, 0x64, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x0C, 0x40, 0x14, 0x00, 0x26, 0x48, 0x20, 0x44, + 0x13, 0x22, 0xB9, 0x41, 0x00, 0x01, 0x04, 0x40, 0x06, 0x74, 0x14, 0x62, 0xB9, 0x21, 0x1C, 0x01, + 0x2F, 0xA6, 0x0D, 0x00, 0x13, 0xAA, 0x33, 0x5A, 0x2F, 0xF5, 0x05, 0x00, 0x26, 0x5F, 0x0C, 0x20, + 0x34, 0x00, 0xD7, 0x51, 0x23, 0x55, 0x26, 0x21, 0xB9, 0x51, 0x18, 0x01, 0x2F, 0x34, 0x01, 0x00, + 0x26, 0x24, 0x14, 0x52, 0xC4, 0xAD, 0xCA, 0x38, 0x01, 0x00, 0xA1, 0x02, 0xA1, 0x03, 0x24, 0x51, + 0x43, 0x55, 0xC4, 0x53, 0x24, 0x22, 0x24, 0x32, 0x92, 0xF6, 0x24, 0x4A, 0xCC, 0x40, 0x32, 0x00, + 0x24, 0x61, 0x43, 0x66, 0x92, 0xDE, 0x78, 0x61, 0x4C, 0x00, 0x28, 0x58, 0x14, 0x03, 0xA9, 0x61, + 0xFA, 0x00, 0xC6, 0x56, 0x02, 0x03, 0xA9, 0x68, 0x14, 0x03, 0x28, 0x58, 0x16, 0x03, 0xC6, 0x56, + 0x32, 0x03, 0xA9, 0x68, 0x16, 0x03, 0x0C, 0x50, 0x34, 0x00, 0x04, 0x42, 0x04, 0x34, 0x04, 0x28, + 0x56, 0x47, 0x56, 0x37, 0x56, 0x27, 0x26, 0x51, 0x5C, 0x70, 0x10, 0x00, 0x06, 0x65, 0x13, 0x44, + 0x13, 0x33, 0x13, 0x22, 0x13, 0x77, 0xC4, 0x40, 0x92, 0x02, 0xA1, 0x05, 0xC4, 0x30, 0x92, 0x03, + 0xA9, 0x05, 0x28, 0x00, 0xC4, 0x20, 0x92, 0x02, 0xA1, 0x06, 0xC4, 0x70, 0x92, 0x03, 0xA9, 0x06, + 0x08, 0x00, 0x38, 0xE1, 0xFC, 0x00, 0x24, 0x6A, 0xC6, 0x6E, 0x24, 0x52, 0x92, 0xED, 0x0C, 0x60, + 0x34, 0x00, 0x26, 0x61, 0x06, 0xE1, 0x06, 0x41, 0x06, 0x56, 0x04, 0x70, 0x78, 0x25, 0x0A, 0x00, + 0x70, 0xF5, 0x0C, 0x30, 0xD4, 0x00, 0x26, 0xF2, 0x78, 0x25, 0x14, 0x00, 0x26, 0x31, 0x26, 0xF2, + 0x78, 0x25, 0x1E, 0x00, 0x26, 0x37, 0x26, 0xF2, 0x78, 0x25, 0x28, 0x00, 0x24, 0x42, 0x26, 0x2F, + 0xB1, 0x23, 0x70, 0xF6, 0x78, 0x26, 0x02, 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x26, 0xF2, 0x78, 0x26, + 0x04, 0x00, 0x26, 0x31, 0x26, 0xF2, 0x78, 0x26, 0x06, 0x00, 0x26, 0x37, 0x26, 0xF2, 0x78, 0x26, + 0x08, 0x00, 0x24, 0x52, 0x26, 0x2F, 0xB1, 0x23, 0x78, 0xF4, 0x08, 0x00, 0x78, 0x24, 0x12, 0x00, + 0x0C, 0x30, 0xAC, 0x00, 0x26, 0xF2, 0x78, 0x24, 0x1C, 0x00, 0x26, 0x31, 0x26, 0x37, 0x26, 0x2F, + 0xB1, 0x23, 0x78, 0xFE, 0x02, 0x00, 0x78, 0x2E, 0x04, 0x00, 0x0C, 0x30, 0x98, 0x00, 0x26, 0xF2, + 0x26, 0x31, 0x78, 0x2E, 0x06, 0x00, 0x26, 0x37, 0x24, 0x74, 0xCC, 0x70, 0x14, 0x00, 0x26, 0x2F, + 0xB1, 0x23, 0x24, 0x6A, 0x24, 0xEA, 0x92, 0xBB, 0x18, 0x28, 0x1F, 0x03, 0x38, 0xE1, 0x0C, 0x01, + 0xD7, 0x22, 0x26, 0xE8, 0x26, 0x28, 0x0C, 0x40, 0xC0, 0x00, 0x06, 0x5E, 0x2C, 0x20, 0x5C, 0x01, + 0x04, 0x31, 0x26, 0x41, 0x04, 0x60, 0x8B, 0x3D, 0x03, 0x00, 0x18, 0x28, 0x1F, 0x03, 0x0C, 0x40, + 0x98, 0x00, 0xD7, 0x22, 0x26, 0x28, 0x06, 0x5E, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x33, 0x26, 0x41, + 0x04, 0x60, 0x8B, 0x3D, 0x03, 0x00, 0x18, 0x28, 0x1F, 0x03, 0x04, 0xE4, 0x26, 0xEC, 0x57, 0xE1, + 0xD7, 0x22, 0x26, 0xE8, 0x04, 0x30, 0x26, 0x28, 0x0C, 0x40, 0xD4, 0x00, 0x06, 0x63, 0x2C, 0x20, + 0x5C, 0x01, 0x26, 0x41, 0x06, 0x5E, 0x8B, 0x3D, 0x03, 0x00, 0x18, 0x28, 0x1F, 0x03, 0x0C, 0x40, + 0xAC, 0x00, 0xD7, 0x22, 0x26, 0x28, 0x06, 0x5E, 0x04, 0x60, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x32, + 0x26, 0x41, 0x8B, 0x3D, 0x03, 0x00, 0x18, 0x68, 0x1F, 0x03, 0x38, 0xF1, 0x08, 0x01, 0x18, 0x58, + 0x25, 0x03, 0x06, 0x76, 0xD7, 0x72, 0x26, 0x78, 0x99, 0xC7, 0x5E, 0x01, 0x99, 0xD7, 0x5F, 0x01, + 0xA9, 0xF7, 0x5C, 0x01, 0xA9, 0x57, 0x78, 0x01, 0x04, 0x71, 0x26, 0x76, 0x13, 0x77, 0xC4, 0x7D, + 0x99, 0x78, 0x1F, 0x03, 0x9A, 0x82, 0xFE, 0xFF, 0x18, 0x68, 0x1F, 0x03, 0x98, 0x78, 0xDD, 0x00, + 0x99, 0x68, 0x1D, 0x03, 0x9A, 0xA1, 0x00, 0x00, 0xFA, 0xA4, 0x00, 0x00, 0x38, 0x31, 0x10, 0x01, + 0x38, 0x51, 0x00, 0x01, 0x0C, 0x20, 0xFA, 0x00, 0x26, 0x21, 0x06, 0x47, 0x0B, 0x39, 0x03, 0x00, + 0xC4, 0x20, 0x8A, 0x6B, 0xFE, 0xFF, 0xFA, 0xA7, 0xFE, 0xFF, 0x0C, 0x70, 0x18, 0x00, 0x26, 0x7E, + 0x0C, 0x50, 0x68, 0x00, 0xE7, 0x71, 0x26, 0x51, 0x26, 0x57, 0x04, 0x67, 0x04, 0x71, 0x56, 0x6E, + 0x10, 0x45, 0x06, 0xF7, 0x53, 0xF6, 0x06, 0x6F, 0xC4, 0xC0, 0x66, 0x64, 0x91, 0x65, 0x92, 0x11, + 0x2C, 0xE0, 0x19, 0x00, 0x06, 0x6E, 0x0C, 0x40, 0x68, 0x00, 0xE7, 0x61, 0x26, 0x41, 0x26, 0x64, + 0x10, 0x56, 0x54, 0xE7, 0x04, 0x71, 0x53, 0x7E, 0x66, 0x75, 0x91, 0x76, 0xFA, 0xAF, 0xFE, 0xFF, + 0x0C, 0x50, 0x17, 0x00, 0x26, 0x5E, 0x06, 0x65, 0x0C, 0x90, 0x68, 0x00, 0xE7, 0x61, 0x26, 0x91, + 0x26, 0x69, 0x54, 0x57, 0x53, 0x75, 0x10, 0x56, 0xCC, 0xC0, 0x17, 0x00, 0x66, 0x75, 0x91, 0x76, + 0x8A, 0x9D, 0xFE, 0xFF, 0xF2, 0xDE, 0x2F, 0xF5, 0x0C, 0x00, 0x13, 0xFF, 0xCC, 0xF0, 0x16, 0x00, + 0xDA, 0xC5, 0xFE, 0xFF, 0x38, 0x91, 0x18, 0x01, 0x38, 0xE1, 0x10, 0x01, 0x33, 0xFF, 0x26, 0xF9, + 0x43, 0xFF, 0x26, 0xFF, 0x26, 0xEF, 0x20, 0x9E, 0x06, 0xE9, 0x38, 0x91, 0x00, 0x01, 0x36, 0xE9, + 0xB9, 0xE1, 0x2C, 0x01, 0x06, 0x9E, 0xC3, 0xEE, 0x32, 0x02, 0x04, 0x90, 0x0C, 0xE0, 0x28, 0x08, + 0x26, 0xEF, 0xA1, 0x92, 0x20, 0x9E, 0x06, 0xE9, 0x38, 0x91, 0x00, 0x01, 0x36, 0xE9, 0xB9, 0xE1, + 0x2C, 0x01, 0x06, 0x9E, 0xC3, 0xEE, 0x32, 0x02, 0x04, 0x90, 0xA1, 0x93, 0x14, 0x92, 0xC6, 0x69, + 0x8A, 0x9F, 0xFE, 0xFF, 0xC4, 0x62, 0x8A, 0x9C, 0xFE, 0xFF, 0xC6, 0x59, 0x8A, 0x99, 0xFE, 0xFF, + 0xC4, 0x52, 0x8A, 0x96, 0xFE, 0xFF, 0x38, 0xE1, 0x14, 0x01, 0x38, 0x91, 0x1C, 0x01, 0x26, 0xFE, + 0x70, 0xFF, 0xC6, 0xF9, 0x0A, 0x8D, 0xFE, 0xFF, 0xC6, 0x6B, 0x92, 0x03, 0x64, 0x72, 0xF2, 0x04, + 0xC4, 0x61, 0x92, 0x02, 0x64, 0x74, 0xC6, 0x5B, 0x92, 0x04, 0x64, 0x78, 0xFA, 0x81, 0xFE, 0xFF, + 0xC4, 0x51, 0x9A, 0x7E, 0xFE, 0xFF, 0x6C, 0x70, 0x10, 0x00, 0xFA, 0x7A, 0xFE, 0xFF, 0x24, 0xD1, + 0x13, 0xDD, 0xFA, 0xBC, 0xFD, 0xFF, 0xCC, 0x70, 0xF9, 0x00, 0xD2, 0x08, 0x24, 0x71, 0xF2, 0x04, + 0xC4, 0x60, 0x82, 0x04, 0x04, 0x71, 0x99, 0x78, 0xDD, 0x00, 0x0C, 0x20, 0xE8, 0x00, 0x0C, 0x40, + 0x12, 0x00, 0x26, 0x21, 0x04, 0x30, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x98, 0x1F, 0x03, + 0x14, 0x41, 0x26, 0x49, 0x08, 0xB0, 0xE4, 0xFF, 0x08, 0xA0, 0xA9, 0x00, 0xB9, 0x41, 0x04, 0x01, + 0x04, 0xE0, 0x2C, 0xB0, 0xDC, 0x30, 0x2C, 0xA0, 0xDC, 0xF1, 0x04, 0x71, 0x38, 0x41, 0x04, 0x01, + 0x06, 0x6E, 0xC6, 0xE4, 0x32, 0x44, 0x06, 0xCE, 0xD7, 0xC2, 0x24, 0xE1, 0x0C, 0xF0, 0xE8, 0x00, + 0x26, 0xC8, 0x43, 0xEE, 0x26, 0xF1, 0x2C, 0xC0, 0x5C, 0x01, 0x06, 0xDE, 0x26, 0x6F, 0xC6, 0xD9, + 0x32, 0xEE, 0x06, 0x5D, 0xD7, 0x52, 0x26, 0x58, 0x78, 0x45, 0x70, 0x01, 0x78, 0x2C, 0x14, 0x00, + 0x2C, 0x50, 0x5C, 0x01, 0x78, 0x55, 0x16, 0x00, 0x36, 0x24, 0x78, 0x4C, 0x16, 0x00, 0xB9, 0x61, + 0x24, 0x01, 0x06, 0x32, 0x36, 0x45, 0xB9, 0x71, 0x28, 0x01, 0xB9, 0x41, 0x20, 0x01, 0x4B, 0x14, + 0x00, 0x00, 0x38, 0x41, 0x20, 0x01, 0x06, 0x52, 0x06, 0x34, 0x06, 0x24, 0xB9, 0x51, 0x20, 0x01, + 0x4B, 0x14, 0x00, 0x00, 0x38, 0x51, 0x20, 0x01, 0x38, 0x61, 0x24, 0x01, 0x38, 0x71, 0x28, 0x01, + 0x26, 0x25, 0x2F, 0x5B, 0x02, 0x00, 0xC6, 0x5A, 0xD2, 0x07, 0x0C, 0x50, 0xE8, 0x00, 0x26, 0x51, + 0x91, 0x76, 0x26, 0x5D, 0x91, 0x75, 0x24, 0xD1, 0x43, 0xDD, 0xF2, 0xCA, 0x04, 0x60, 0x06, 0x58, + 0x18, 0x78, 0x1F, 0x03, 0xC6, 0x67, 0x32, 0x16, 0x0C, 0x70, 0xE8, 0x00, 0x26, 0x71, 0x26, 0x76, + 0x10, 0x77, 0xC4, 0x71, 0x92, 0x0C, 0x06, 0x76, 0xD7, 0x72, 0x26, 0x75, 0x28, 0x47, 0x74, 0x01, + 0xA9, 0x47, 0x70, 0x01, 0x28, 0x47, 0x76, 0x01, 0xA9, 0x47, 0x72, 0x01, 0x24, 0x61, 0x43, 0x66, + 0xF2, 0xE8, 0x58, 0xC1, 0x40, 0x01, 0x58, 0x81, 0x30, 0x01, 0x2C, 0x10, 0x50, 0x01, 0xE1, 0xF0, + 0x0C, 0x70, 0xFC, 0x0A, 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0x28, 0xD7, 0x20, 0x03, + 0x68, 0xF7, 0x1F, 0x03, 0xD1, 0x81, 0x04, 0x60, 0x14, 0x41, 0x99, 0x07, 0x24, 0x03, 0x43, 0x9D, + 0x23, 0x30, 0x06, 0x26, 0x06, 0x54, 0x0C, 0xC0, 0x74, 0x1A, 0x0C, 0xB0, 0x80, 0x02, 0x2F, 0xE6, + 0x06, 0x00, 0x26, 0xEC, 0x70, 0xEE, 0x06, 0xAB, 0x26, 0xEE, 0x26, 0xEB, 0x70, 0xEE, 0xC6, 0xE9, + 0x22, 0x0B, 0xC6, 0x3E, 0x32, 0x09, 0x04, 0x81, 0x26, 0x8F, 0x24, 0x21, 0x06, 0x5F, 0x33, 0x46, + 0x13, 0x22, 0x23, 0x3E, 0x33, 0xF8, 0x24, 0x61, 0xC4, 0x63, 0x92, 0xEA, 0xA9, 0x37, 0x1A, 0x03, + 0x99, 0x20, 0xC1, 0x1B, 0x43, 0x33, 0x04, 0x60, 0x2F, 0x26, 0x06, 0x00, 0x0C, 0xF0, 0x74, 0x1A, + 0x26, 0x2F, 0x20, 0x22, 0x26, 0x22, 0x26, 0x2A, 0xF0, 0x22, 0x02, 0x06, 0x43, 0xF6, 0xC6, 0x4F, + 0x82, 0x03, 0x36, 0x32, 0x43, 0x33, 0x24, 0x61, 0xC4, 0x63, 0x92, 0xEF, 0xC6, 0x3D, 0x32, 0x04, + 0xA9, 0x07, 0x1A, 0x03, 0xF2, 0x1D, 0x14, 0x61, 0xC6, 0x56, 0x82, 0x1A, 0x98, 0x67, 0xA2, 0x06, + 0x82, 0x0B, 0x18, 0x67, 0xA0, 0x06, 0x99, 0x57, 0x22, 0x03, 0x99, 0x67, 0x23, 0x03, 0x04, 0x61, + 0x99, 0x67, 0x24, 0x03, 0xF2, 0x0D, 0x04, 0x31, 0x06, 0x63, 0x53, 0x64, 0x18, 0x47, 0x23, 0x03, + 0x99, 0x57, 0x22, 0x03, 0x99, 0x37, 0x24, 0x03, 0x66, 0x64, 0x99, 0x67, 0x23, 0x03, 0x58, 0xC1, + 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, + 0x0C, 0xE0, 0xFC, 0x0A, 0x98, 0x6E, 0x1F, 0x03, 0x06, 0x7E, 0x82, 0x24, 0x98, 0x5E, 0x24, 0x03, + 0x82, 0x21, 0x28, 0x4E, 0x18, 0x03, 0x28, 0x5E, 0x1A, 0x03, 0xC6, 0x45, 0xD2, 0x03, 0xC4, 0x61, + 0xC2, 0x0B, 0x14, 0x51, 0x99, 0x57, 0x22, 0x03, 0x99, 0x07, 0x23, 0x03, 0x99, 0x67, 0x1C, 0x03, + 0x99, 0x07, 0x24, 0x03, 0xF2, 0x0F, 0x0C, 0x20, 0x58, 0x0C, 0x04, 0x30, 0x0C, 0x40, 0x20, 0x00, + 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x7E, 0x24, 0x03, 0x99, 0x0E, 0x1F, 0x03, 0x99, 0x7E, + 0x1C, 0x03, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x8B, 0x7E, 0x03, 0x00, + 0xCB, 0x4E, 0x03, 0x00, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x6E, 0x1F, 0x03, 0x18, 0x7E, 0x24, 0x03, + 0x26, 0x76, 0x13, 0x77, 0x99, 0x7E, 0x1C, 0x03, 0x99, 0x7E, 0x1D, 0x03, 0x6B, 0x85, 0x03, 0x00, + 0xCB, 0xDF, 0x02, 0x00, 0x18, 0x7E, 0x1C, 0x03, 0x99, 0x7E, 0x1E, 0x03, 0x40, 0xE1, 0x24, 0x18, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x18, 0x00, 0xC1, 0xA1, 0x0C, 0xB0, 0xFC, 0x0A, 0x18, 0xAB, + 0x1F, 0x03, 0xD9, 0xC1, 0x08, 0x00, 0x04, 0xE0, 0x06, 0xCE, 0x06, 0xDB, 0x18, 0x4B, 0x1F, 0x03, + 0xC6, 0xC4, 0xB2, 0x1A, 0x06, 0x3C, 0xD7, 0x32, 0x26, 0x3D, 0x2C, 0x30, 0x5C, 0x01, 0xA8, 0x73, + 0x1C, 0x00, 0x82, 0x0F, 0xC6, 0xCE, 0x82, 0x0B, 0x06, 0x2E, 0xD7, 0x22, 0x26, 0x2D, 0x2C, 0x20, + 0x5C, 0x01, 0x0C, 0x40, 0x20, 0x00, 0x0C, 0xF0, 0x28, 0x01, 0xF1, 0xF0, 0x24, 0xE1, 0x13, 0xEE, + 0x24, 0xC1, 0x13, 0xCC, 0xF2, 0xE4, 0x06, 0x2E, 0xD7, 0x22, 0x26, 0x2D, 0x36, 0x4E, 0x2C, 0x20, + 0x5C, 0x01, 0x04, 0x30, 0xD7, 0x42, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x7D, 0x1C, 0x03, + 0x99, 0xED, 0x1F, 0x03, 0x3F, 0xAA, 0x07, 0x00, 0x26, 0xEA, 0x99, 0xED, 0x1C, 0x03, 0x58, 0xC1, + 0x08, 0x00, 0x40, 0xA1, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x38, 0x70, 0x70, 0x1A, 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x28, 0x47, + 0x32, 0x00, 0x06, 0xD4, 0x18, 0x50, 0xCD, 0x1B, 0xD7, 0xD1, 0x04, 0x70, 0x08, 0x30, 0x00, 0x30, + 0x23, 0xDD, 0x06, 0x27, 0x0C, 0xC0, 0x74, 0x1A, 0x2C, 0x30, 0x00, 0x49, 0x2F, 0x6C, 0x07, 0x00, + 0x20, 0x66, 0x0C, 0x80, 0xFF, 0x0F, 0x57, 0x61, 0x26, 0x63, 0x30, 0x66, 0x04, 0x90, 0x56, 0x86, + 0x77, 0x68, 0x5C, 0x60, 0xFF, 0x0F, 0xC6, 0x86, 0x02, 0x03, 0x3F, 0x96, 0x08, 0x00, 0x18, 0x60, + 0xCC, 0x1B, 0x93, 0x06, 0x92, 0x05, 0x18, 0x60, 0xCB, 0x1B, 0x93, 0x06, 0x82, 0x04, 0xB8, 0x60, + 0x8C, 0x19, 0x82, 0x03, 0x06, 0x64, 0xF2, 0x02, 0x06, 0x6D, 0xC6, 0x96, 0x22, 0x03, 0x04, 0x51, + 0x06, 0x25, 0x24, 0x72, 0xC4, 0x76, 0x92, 0xDB, 0xC4, 0x20, 0x99, 0x50, 0xCD, 0x1B, 0x92, 0x03, + 0x99, 0x00, 0xCD, 0x1B, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, + 0x98, 0x70, 0xA2, 0x1B, 0x3C, 0x10, 0x50, 0x00, 0xD9, 0xC1, 0x40, 0x00, 0xD9, 0x81, 0x30, 0x00, + 0x82, 0x06, 0x08, 0x70, 0x00, 0x80, 0x28, 0xE7, 0xAE, 0xDC, 0xF2, 0x05, 0x38, 0x70, 0x70, 0x1A, + 0x28, 0xE7, 0x28, 0x00, 0xB8, 0x70, 0x8C, 0x19, 0x82, 0x08, 0x2F, 0x2E, 0x0E, 0x00, 0x26, 0x2E, + 0x04, 0x35, 0xAB, 0x15, 0x00, 0x00, 0x06, 0xE2, 0x4B, 0x3E, 0x00, 0x00, 0xB8, 0x70, 0x8C, 0x19, + 0x82, 0x0D, 0xA3, 0x22, 0x82, 0x0B, 0x0C, 0x30, 0x18, 0x00, 0xAB, 0x15, 0x00, 0x00, 0xA3, 0x22, + 0x82, 0x03, 0xC4, 0x2D, 0x92, 0x03, 0x2C, 0xE0, 0x90, 0x01, 0xB8, 0xD0, 0x8C, 0x19, 0x9A, 0x12, + 0x02, 0x00, 0x08, 0xB0, 0x00, 0x30, 0xB9, 0xD1, 0x1C, 0x00, 0x06, 0xCD, 0xB1, 0xD1, 0xB9, 0xD1, + 0x18, 0x00, 0xB9, 0xD1, 0x14, 0x00, 0x06, 0x6D, 0xB9, 0xD1, 0x10, 0x00, 0x06, 0x4D, 0xB9, 0xD1, + 0x0C, 0x00, 0x06, 0xAD, 0x06, 0x9D, 0xB9, 0xD1, 0x08, 0x00, 0xB9, 0xD1, 0x04, 0x00, 0x2C, 0xB0, + 0x00, 0x49, 0x06, 0x7D, 0x57, 0x71, 0x26, 0x7B, 0x30, 0x87, 0xB9, 0x41, 0x20, 0x00, 0x23, 0x5D, + 0x0C, 0x70, 0xFF, 0x0F, 0x56, 0x78, 0x06, 0x25, 0x0C, 0x30, 0x18, 0x00, 0xB9, 0x51, 0x2C, 0x00, + 0xB9, 0x61, 0x24, 0x00, 0xB9, 0x71, 0x28, 0x00, 0x4B, 0x18, 0x00, 0x00, 0x23, 0x22, 0xC4, 0x2A, + 0x77, 0x88, 0x5C, 0x80, 0xFF, 0x0F, 0x38, 0x41, 0x20, 0x00, 0x38, 0x51, 0x2C, 0x00, 0x38, 0x61, + 0x24, 0x00, 0x38, 0x71, 0x28, 0x00, 0xD2, 0x28, 0xCC, 0x50, 0xA7, 0x00, 0x3F, 0x38, 0x07, 0x00, + 0xD2, 0x0B, 0xC4, 0x3A, 0x12, 0x5C, 0x3F, 0x57, 0x08, 0x00, 0xC4, 0x5A, 0x02, 0x58, 0x24, 0x61, + 0x26, 0x45, 0x23, 0x66, 0xF2, 0x54, 0xCC, 0x50, 0xD7, 0x00, 0xC2, 0x51, 0xC4, 0x3A, 0x02, 0x09, + 0x38, 0x51, 0x04, 0x00, 0x24, 0x91, 0x26, 0x53, 0xB9, 0x51, 0x04, 0x00, 0x23, 0x99, 0xF2, 0x47, + 0x3F, 0x57, 0x08, 0x00, 0xC4, 0x5A, 0x02, 0x43, 0x38, 0x51, 0x14, 0x00, 0x24, 0x51, 0x23, 0x55, + 0xB9, 0x51, 0x14, 0x00, 0xF2, 0x3C, 0xCC, 0x50, 0xA7, 0x00, 0xD2, 0x1B, 0xCC, 0x20, 0x17, 0x00, + 0x82, 0x36, 0x3F, 0x58, 0x07, 0x00, 0xC4, 0x5A, 0x02, 0x09, 0x38, 0x31, 0x08, 0x00, 0x24, 0xA1, + 0x26, 0x35, 0xB9, 0x31, 0x08, 0x00, 0x23, 0xAA, 0xF2, 0x2A, 0x3F, 0x57, 0x08, 0x00, 0xC4, 0x5A, + 0x02, 0x26, 0x38, 0x51, 0x18, 0x00, 0x24, 0x51, 0x23, 0x55, 0xB9, 0x51, 0x18, 0x00, 0xF2, 0x1F, + 0xCC, 0x50, 0xD7, 0x00, 0xC2, 0x1C, 0xCC, 0x20, 0x17, 0x00, 0x82, 0x19, 0x3F, 0x58, 0x07, 0x00, + 0xC4, 0x5A, 0x02, 0x08, 0x38, 0x51, 0x0C, 0x00, 0x24, 0x51, 0x23, 0x55, 0xB9, 0x51, 0x0C, 0x00, + 0xF2, 0x0E, 0x3F, 0x57, 0x08, 0x00, 0xC4, 0x5A, 0x02, 0x0A, 0x38, 0x31, 0x10, 0x00, 0x26, 0x35, + 0x30, 0x51, 0xB9, 0x31, 0x10, 0x00, 0x24, 0x51, 0x23, 0x55, 0xB1, 0x51, 0x3F, 0x58, 0x07, 0x00, + 0xC4, 0x50, 0x02, 0x04, 0xC6, 0x5C, 0x02, 0x02, 0x23, 0xC5, 0x36, 0x87, 0xC4, 0x80, 0x02, 0x08, + 0x38, 0x51, 0x1C, 0x00, 0xC6, 0x85, 0x02, 0x04, 0x23, 0x88, 0xB9, 0x81, 0x1C, 0x00, 0x24, 0xD1, + 0xCC, 0xD0, 0x50, 0x01, 0x9A, 0x67, 0xFF, 0xFF, 0x04, 0x31, 0x26, 0x36, 0x06, 0x24, 0xB9, 0x61, + 0x24, 0x00, 0x8B, 0x16, 0x00, 0x00, 0xC4, 0x25, 0x06, 0xB7, 0x0C, 0xB0, 0xFC, 0x0A, 0x38, 0x61, + 0x24, 0x00, 0x02, 0x44, 0xC4, 0x60, 0x82, 0x42, 0x38, 0x21, 0x04, 0x00, 0x04, 0x31, 0x26, 0x39, + 0x8B, 0x16, 0x00, 0x00, 0xCC, 0x20, 0x80, 0x00, 0x02, 0x39, 0xCC, 0x90, 0x2F, 0x00, 0xD2, 0x36, + 0xB8, 0x71, 0x14, 0x00, 0x92, 0x33, 0x38, 0x21, 0x08, 0x00, 0x04, 0x31, 0x26, 0x3A, 0x8B, 0x16, + 0x00, 0x00, 0xCC, 0x20, 0x10, 0x00, 0x02, 0x2A, 0xCC, 0xA0, 0x3F, 0x00, 0xD2, 0x27, 0xB8, 0x91, + 0x18, 0x00, 0x92, 0x24, 0x30, 0x31, 0x38, 0x21, 0x10, 0x00, 0x24, 0x31, 0x8B, 0x16, 0x00, 0x00, + 0xCC, 0x20, 0x40, 0x00, 0x02, 0x1B, 0x30, 0x51, 0xCC, 0x50, 0x30, 0x00, 0xC2, 0x17, 0xB8, 0x71, + 0x0C, 0x00, 0x92, 0x14, 0x38, 0x5B, 0x0C, 0x00, 0x04, 0x61, 0xD6, 0x65, 0x92, 0x0F, 0xCC, 0xC0, + 0x6F, 0x02, 0xD2, 0x0C, 0x08, 0x60, 0x40, 0x00, 0x66, 0x65, 0xB9, 0x6B, 0x0C, 0x00, 0x04, 0x61, + 0x99, 0x60, 0xCC, 0x1B, 0xA9, 0x00, 0x8A, 0x1B, 0xF2, 0x1C, 0x18, 0x60, 0xCC, 0x1B, 0x93, 0x06, + 0x82, 0x06, 0x28, 0x60, 0x8A, 0x1B, 0x24, 0x61, 0xA9, 0x60, 0x8A, 0x1B, 0x28, 0x60, 0x8A, 0x1B, + 0xCC, 0x60, 0x32, 0x00, 0xC2, 0x0E, 0xA9, 0x00, 0x8A, 0x1B, 0x38, 0x6B, 0x0C, 0x00, 0x99, 0x00, + 0xCC, 0x1B, 0x08, 0x50, 0xBF, 0xFF, 0x2C, 0x50, 0xFF, 0xFF, 0x56, 0x65, 0xB9, 0x6B, 0x0C, 0x00, + 0xCB, 0x3D, 0x00, 0x00, 0x23, 0x62, 0x23, 0x22, 0x2C, 0x20, 0x20, 0x00, 0xC6, 0xC2, 0xA9, 0x6B, + 0x18, 0x03, 0x02, 0x04, 0x04, 0x21, 0xFA, 0x8E, 0x01, 0x00, 0x38, 0x5B, 0x0C, 0x00, 0x04, 0x41, + 0xD6, 0x45, 0x92, 0x04, 0xCC, 0xC0, 0xFF, 0x03, 0xD2, 0xF6, 0xCC, 0x60, 0xFE, 0x0F, 0xD2, 0xF3, + 0x18, 0x60, 0xCC, 0x1B, 0x93, 0x06, 0x92, 0x0A, 0x38, 0x81, 0x1C, 0x00, 0xCC, 0x80, 0x78, 0x00, + 0xC2, 0x05, 0x08, 0x60, 0x10, 0x00, 0x66, 0x65, 0xF2, 0x06, 0x08, 0x60, 0xEF, 0xFF, 0x2C, 0x60, + 0xFF, 0xFF, 0x56, 0x65, 0xB9, 0x6B, 0x0C, 0x00, 0x38, 0x7B, 0x0C, 0x00, 0x0C, 0xF0, 0x50, 0x00, + 0xD4, 0x71, 0x82, 0x03, 0x0C, 0xF0, 0x60, 0x00, 0x1C, 0x90, 0x1F, 0x00, 0x18, 0x70, 0xC7, 0x1B, + 0x04, 0x60, 0x08, 0xC0, 0x00, 0x30, 0x26, 0x9F, 0x06, 0x26, 0x06, 0x36, 0x0C, 0xA0, 0x74, 0x1A, + 0x2C, 0xC0, 0x00, 0x49, 0xB1, 0x91, 0x2F, 0x5A, 0x06, 0x00, 0x20, 0x55, 0x57, 0x51, 0x26, 0x5C, + 0x30, 0x95, 0x0C, 0x50, 0xFF, 0x0F, 0x56, 0x59, 0x77, 0x98, 0x5C, 0x90, 0xFF, 0x0F, 0xC6, 0x59, + 0xC2, 0x10, 0x3F, 0x99, 0x05, 0x00, 0xC6, 0x9F, 0x02, 0x06, 0xCC, 0x90, 0xFF, 0x00, 0x12, 0x03, + 0x24, 0x31, 0x23, 0x33, 0xC4, 0x32, 0xC2, 0x06, 0x04, 0x81, 0x99, 0x80, 0xCB, 0x1B, 0xF2, 0x02, + 0x36, 0x95, 0xCC, 0x90, 0x00, 0x04, 0x02, 0x04, 0x99, 0x70, 0xC7, 0x1B, 0xF2, 0xA4, 0xC4, 0x70, + 0x82, 0x17, 0x0C, 0x90, 0x78, 0x1B, 0x26, 0x96, 0x20, 0x99, 0xC6, 0x95, 0xC2, 0x11, 0x18, 0x80, + 0xCB, 0x1B, 0x93, 0x08, 0x82, 0x0D, 0x3F, 0x55, 0x09, 0x00, 0x30, 0x91, 0xC6, 0x95, 0x12, 0x08, + 0x24, 0x21, 0x23, 0x22, 0xC4, 0x21, 0xC2, 0x04, 0x99, 0x00, 0xCB, 0x1B, 0x04, 0x70, 0x24, 0x62, + 0xC4, 0x66, 0x92, 0xC2, 0x18, 0x60, 0xCB, 0x1B, 0x99, 0x70, 0xC7, 0x1B, 0x93, 0x06, 0x82, 0x1F, + 0xC4, 0x70, 0x92, 0x1D, 0x08, 0x30, 0x00, 0x30, 0x0C, 0xF0, 0x78, 0x1B, 0x2C, 0x30, 0x00, 0x49, + 0x0C, 0x60, 0x74, 0x1A, 0x26, 0x67, 0x20, 0x66, 0x2F, 0x2F, 0x07, 0x00, 0x57, 0x61, 0x26, 0x63, + 0x30, 0x66, 0x24, 0x72, 0xC4, 0x76, 0x5C, 0x60, 0xFF, 0x0F, 0xA1, 0x62, 0x92, 0xF2, 0x18, 0x70, + 0xCB, 0x1B, 0x93, 0x07, 0x82, 0x04, 0x04, 0x71, 0x99, 0x70, 0xC7, 0x1B, 0x18, 0x70, 0xCC, 0x1B, + 0x93, 0x07, 0x92, 0x05, 0x18, 0x30, 0xCB, 0x1B, 0x93, 0x03, 0x82, 0x07, 0xD7, 0xE1, 0xA9, 0x00, + 0x8C, 0x1B, 0x99, 0x00, 0xC8, 0x1B, 0xF2, 0x2E, 0x98, 0x30, 0xC8, 0x1B, 0x92, 0x0E, 0x18, 0x30, + 0xC9, 0x1B, 0x93, 0x03, 0x82, 0x0A, 0x18, 0x20, 0xC9, 0x1B, 0x18, 0x30, 0xCB, 0x1B, 0xC6, 0x23, + 0x82, 0x04, 0x04, 0x31, 0x99, 0x30, 0xC8, 0x1B, 0x98, 0x30, 0xC8, 0x1B, 0x92, 0x0E, 0x18, 0x30, + 0xCA, 0x1B, 0x93, 0x03, 0x82, 0x0A, 0x18, 0x20, 0xCA, 0x1B, 0x18, 0x30, 0xCC, 0x1B, 0xC6, 0x23, + 0x82, 0x04, 0x04, 0x21, 0x99, 0x20, 0xC8, 0x1B, 0x98, 0x70, 0xC8, 0x1B, 0x82, 0x13, 0x28, 0x30, + 0x8C, 0x1B, 0x24, 0x31, 0x23, 0x33, 0xCC, 0x30, 0x31, 0x00, 0xA9, 0x30, 0x8C, 0x1B, 0xD2, 0x06, + 0xD7, 0xE1, 0x04, 0x31, 0x99, 0x30, 0xC6, 0x1B, 0xF2, 0x05, 0xA9, 0x00, 0x8C, 0x1B, 0x99, 0x00, + 0xC8, 0x1B, 0x18, 0x70, 0xCB, 0x1B, 0x99, 0x70, 0xC9, 0x1B, 0x18, 0x70, 0xCC, 0x1B, 0x99, 0x70, + 0xCA, 0x1B, 0x0C, 0xA0, 0xFC, 0x0A, 0x38, 0xDA, 0x0C, 0x00, 0xD4, 0xD1, 0x9A, 0x90, 0x00, 0x00, + 0x08, 0xC0, 0x00, 0x30, 0x2C, 0xC0, 0x00, 0x49, 0x06, 0x8D, 0x06, 0xBD, 0x06, 0x9D, 0x30, 0x7C, + 0x38, 0x5C, 0x04, 0x00, 0x06, 0x29, 0x0C, 0x30, 0x18, 0x00, 0xB9, 0x51, 0x2C, 0x00, 0xB9, 0x71, + 0x28, 0x00, 0x4B, 0x18, 0x00, 0x00, 0x3C, 0x20, 0x16, 0x00, 0x23, 0x22, 0xC4, 0x21, 0x38, 0x51, + 0x2C, 0x00, 0x38, 0x71, 0x28, 0x00, 0xC2, 0x2F, 0x0C, 0x40, 0xFF, 0x0F, 0x56, 0x47, 0x77, 0x78, + 0x5C, 0x70, 0xFF, 0x0F, 0x3F, 0x37, 0x04, 0x00, 0x23, 0x33, 0x43, 0x63, 0x0C, 0x20, 0xFF, 0x0F, + 0xC4, 0x60, 0x56, 0x25, 0x77, 0x58, 0x5C, 0x50, 0xFF, 0x0F, 0x3F, 0x55, 0x02, 0x00, 0x02, 0x06, + 0xC4, 0x50, 0x32, 0x0E, 0x3F, 0x55, 0x06, 0x00, 0xF2, 0x06, 0xC4, 0x60, 0x82, 0x09, 0xC4, 0x50, + 0x02, 0x07, 0x36, 0x56, 0xCC, 0x50, 0x1E, 0x00, 0x02, 0x03, 0x24, 0xB1, 0x23, 0xBB, 0xC6, 0x47, + 0xC2, 0x05, 0xC6, 0x86, 0x32, 0x08, 0x06, 0x83, 0xF2, 0x06, 0x36, 0x74, 0xC6, 0x7D, 0x23, 0x67, + 0x02, 0x02, 0x06, 0xD6, 0x24, 0x91, 0x23, 0x99, 0xCC, 0x90, 0x50, 0x01, 0x24, 0xC4, 0x92, 0xB8, + 0x3C, 0x80, 0x29, 0x00, 0xCC, 0x80, 0x6C, 0x00, 0xD2, 0x1B, 0x34, 0xD6, 0xCC, 0xD0, 0x39, 0x00, + 0xD2, 0x17, 0xC4, 0xB6, 0xC2, 0x15, 0x18, 0x70, 0xCC, 0x1B, 0x93, 0x07, 0x92, 0x11, 0x18, 0x70, + 0xCB, 0x1B, 0x93, 0x07, 0x92, 0x0D, 0xB8, 0x70, 0x8C, 0x19, 0x92, 0x29, 0x04, 0x61, 0x99, 0x60, + 0xC5, 0x1B, 0x99, 0x00, 0xC4, 0x1B, 0xD7, 0xE1, 0x99, 0x00, 0xC3, 0x1B, 0xF2, 0x20, 0x99, 0x00, + 0xC5, 0x1B, 0x98, 0x70, 0xC3, 0x1B, 0x92, 0x07, 0x98, 0x50, 0xC2, 0x1B, 0x82, 0x04, 0x04, 0x51, + 0x99, 0x50, 0xC3, 0x1B, 0x98, 0x60, 0xC3, 0x1B, 0x82, 0x10, 0x18, 0x50, 0xC4, 0x1B, 0x24, 0x51, + 0x13, 0x55, 0xCC, 0x50, 0x31, 0x00, 0xD2, 0x05, 0x99, 0x50, 0xC4, 0x1B, 0xD7, 0xE1, 0xF2, 0x05, + 0x99, 0x00, 0xC4, 0x1B, 0x99, 0x00, 0xC3, 0x1B, 0x99, 0x00, 0xC2, 0x1B, 0xCB, 0x3D, 0x00, 0x00, + 0xA9, 0x2A, 0x18, 0x03, 0x23, 0x22, 0xC6, 0x2E, 0xA2, 0x05, 0x8B, 0x8E, 0x03, 0x00, 0x04, 0xE0, + 0xF2, 0x06, 0x8B, 0x8E, 0x03, 0x00, 0x14, 0xE1, 0x26, 0xE2, 0xF7, 0xEF, 0x6B, 0xE2, 0x04, 0x00, + 0x06, 0x2E, 0x58, 0xC1, 0x40, 0x00, 0x58, 0x81, 0x30, 0x00, 0x2C, 0x10, 0x50, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x24, 0x00, 0xD9, 0xC1, 0x14, 0x00, 0x38, 0xE0, 0x70, 0x1A, 0xD9, 0x81, 0x04, 0x00, + 0x06, 0xC2, 0x04, 0x30, 0x06, 0x2D, 0x0C, 0x20, 0xF0, 0x0B, 0x0C, 0x40, 0x62, 0x00, 0x0C, 0x90, + 0xFC, 0x0A, 0x0C, 0x80, 0x22, 0x01, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0xD0, 0xF0, 0x0B, + 0x26, 0x89, 0x06, 0xBC, 0x38, 0x3B, 0xC4, 0x00, 0x18, 0x2E, 0x13, 0x00, 0x4B, 0x14, 0x00, 0x00, + 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x06, 0x62, 0x30, 0x3B, 0x18, 0x2E, 0x12, 0x00, + 0xB1, 0x61, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x28, 0x7E, + 0x1A, 0x00, 0x30, 0x61, 0xC6, 0x27, 0x06, 0xA2, 0x02, 0x02, 0x06, 0xA7, 0x06, 0x26, 0x04, 0x3E, + 0x8B, 0x16, 0x00, 0x00, 0x28, 0x7E, 0x1C, 0x00, 0xC6, 0x27, 0x02, 0x02, 0x06, 0x27, 0x18, 0x3E, + 0x15, 0x00, 0x3F, 0x22, 0x0A, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x8B, 0x16, + 0x00, 0x00, 0xA1, 0x2D, 0x24, 0xD2, 0xC6, 0xD8, 0x24, 0xB4, 0x92, 0xCD, 0x06, 0xB9, 0x0C, 0xD0, + 0x20, 0x0C, 0x2C, 0xB0, 0x40, 0x01, 0x38, 0x3C, 0x24, 0x01, 0x18, 0x2E, 0x11, 0x00, 0x4B, 0x14, + 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x3C, 0x60, 0x00, 0x06, 0x92, + 0x18, 0x2E, 0x10, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, + 0x28, 0x7E, 0x16, 0x00, 0x06, 0xA2, 0xC6, 0x27, 0x02, 0x02, 0x06, 0xA7, 0x06, 0x29, 0x0C, 0x30, + 0x17, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x28, 0x7E, 0x18, 0x00, 0xC6, 0x27, 0x02, 0x02, 0x06, 0x27, + 0x18, 0x3E, 0x14, 0x00, 0x3F, 0x22, 0x0A, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0x8B, 0x16, 0x00, 0x00, 0xA1, 0x2D, 0x24, 0xD2, 0xC6, 0xDB, 0x24, 0xC4, 0x92, 0xCD, 0x58, 0xC1, + 0x14, 0x00, 0x58, 0x81, 0x04, 0x00, 0x2C, 0x10, 0x24, 0x00, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, + 0x04, 0x20, 0xE1, 0xF0, 0x38, 0x50, 0x70, 0x1A, 0x3C, 0x10, 0x50, 0x00, 0xD9, 0xC1, 0x40, 0x00, + 0xD9, 0x81, 0x30, 0x00, 0x28, 0xC5, 0xC0, 0x00, 0xB8, 0x70, 0x8C, 0x19, 0x18, 0x95, 0x79, 0x00, + 0xB9, 0x51, 0x08, 0x00, 0x06, 0xD2, 0xB9, 0x03, 0x0C, 0x00, 0x2F, 0x2C, 0x0C, 0x00, 0xB9, 0x03, + 0x08, 0x00, 0xB9, 0x03, 0x04, 0x00, 0xB1, 0x03, 0x06, 0xE3, 0x23, 0xB2, 0x82, 0x0D, 0x26, 0x2C, + 0x04, 0x35, 0x8B, 0x16, 0x00, 0x00, 0x23, 0xC2, 0x2F, 0x2B, 0x0B, 0x00, 0x26, 0x2B, 0x04, 0x35, + 0x8B, 0x16, 0x00, 0x00, 0x23, 0xB2, 0x0C, 0xA0, 0xFC, 0x0A, 0x28, 0x2A, 0x14, 0x03, 0x06, 0x39, + 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x0C, 0x60, 0x06, 0x03, + 0x26, 0x6A, 0x20, 0x66, 0x04, 0x30, 0x0C, 0x80, 0x28, 0x08, 0x23, 0x22, 0xB1, 0x61, 0x06, 0x7D, + 0x06, 0x43, 0x3C, 0x80, 0x30, 0x00, 0xB9, 0x21, 0x14, 0x00, 0x04, 0x91, 0x0C, 0xA0, 0x80, 0x02, + 0x0C, 0xF0, 0x54, 0x05, 0x53, 0x94, 0x26, 0xA3, 0x26, 0xF3, 0xB9, 0x91, 0x04, 0x00, 0x2F, 0x53, + 0x08, 0x00, 0x06, 0x2D, 0x04, 0x60, 0xB9, 0xA1, 0x0C, 0x00, 0xB9, 0xF1, 0x10, 0x00, 0x38, 0xA1, + 0x0C, 0x00, 0x38, 0x91, 0x10, 0x00, 0x2F, 0xF6, 0x06, 0x00, 0x26, 0xAF, 0x26, 0xF9, 0x20, 0xFF, + 0x20, 0xAA, 0x36, 0xAF, 0x23, 0xAA, 0xC3, 0xFA, 0x02, 0x51, 0x78, 0xA5, 0x30, 0x00, 0x30, 0x91, + 0xC6, 0xA9, 0x02, 0x2A, 0xC4, 0x60, 0x82, 0x05, 0x78, 0x95, 0x2E, 0x00, 0xC6, 0x9A, 0x12, 0x24, + 0x78, 0x95, 0x32, 0x00, 0xC6, 0x9A, 0x32, 0x20, 0xC4, 0x40, 0x82, 0x06, 0x70, 0x95, 0xC6, 0x9A, + 0x12, 0x1B, 0xC4, 0x4D, 0x82, 0x05, 0x78, 0x95, 0x60, 0x00, 0xC6, 0x9A, 0x32, 0x15, 0x0C, 0x90, + 0xFC, 0x0A, 0x38, 0x99, 0xFC, 0x02, 0x04, 0xA1, 0x53, 0xA6, 0x66, 0xA9, 0x0C, 0x90, 0xFC, 0x0A, + 0xB9, 0xA9, 0xFC, 0x02, 0x38, 0xA9, 0x00, 0x03, 0x38, 0x91, 0x04, 0x00, 0x66, 0xA9, 0x0C, 0x90, + 0xFC, 0x0A, 0xB9, 0xA9, 0x00, 0x03, 0x30, 0xA2, 0x26, 0xAF, 0xB1, 0xA2, 0x38, 0xA7, 0x60, 0x00, + 0x26, 0xAF, 0xB9, 0xA7, 0x60, 0x00, 0x38, 0xA1, 0x14, 0x00, 0xC6, 0xFA, 0x02, 0x08, 0x0C, 0x90, + 0xFC, 0x0A, 0x18, 0xA9, 0x25, 0x03, 0x24, 0xA1, 0x99, 0xA9, 0x25, 0x03, 0xC6, 0xFC, 0x02, 0x26, + 0x38, 0xAE, 0x08, 0x00, 0xC6, 0xFB, 0x24, 0xA1, 0xB9, 0xAE, 0x08, 0x00, 0x02, 0x1F, 0x38, 0xFE, + 0x0C, 0x00, 0x24, 0xF1, 0xB9, 0xFE, 0x0C, 0x00, 0xF2, 0x19, 0x16, 0xFA, 0x38, 0xA2, 0xC4, 0x00, + 0x43, 0xFF, 0x26, 0xAF, 0xB9, 0xA2, 0xC4, 0x00, 0x38, 0xA7, 0x24, 0x01, 0xC6, 0xFC, 0x26, 0xAF, + 0xB9, 0xA7, 0x24, 0x01, 0x02, 0x0B, 0x30, 0xAE, 0xC6, 0xFB, 0x24, 0xA1, 0xB1, 0xAE, 0x02, 0x06, + 0x38, 0xFE, 0x04, 0x00, 0x24, 0xF1, 0xB9, 0xFE, 0x04, 0x00, 0x24, 0x61, 0xCC, 0x60, 0x17, 0x00, + 0x24, 0x24, 0x24, 0x52, 0x92, 0x85, 0x38, 0x67, 0x60, 0x00, 0x38, 0x5D, 0xC0, 0x00, 0x24, 0x41, + 0x26, 0x65, 0xB9, 0x6D, 0xC0, 0x00, 0x38, 0x67, 0x24, 0x01, 0x38, 0x5D, 0x84, 0x01, 0xC4, 0x4E, + 0x26, 0x65, 0xB9, 0x6D, 0x84, 0x01, 0x24, 0x74, 0x2C, 0x30, 0x30, 0x00, 0x9A, 0x5F, 0xFF, 0xFF, + 0x0C, 0xA0, 0xFC, 0x0A, 0x38, 0x8A, 0x0C, 0x00, 0x04, 0xE1, 0xD6, 0xE8, 0x9A, 0xD8, 0x00, 0x00, + 0x0C, 0x90, 0x80, 0x02, 0x0C, 0xA0, 0x54, 0x05, 0x06, 0xDE, 0x06, 0xCE, 0x06, 0xBE, 0x70, 0x49, + 0x78, 0x69, 0x02, 0x00, 0x70, 0x5A, 0x78, 0x7A, 0x02, 0x00, 0xB9, 0x41, 0x20, 0x00, 0x06, 0x2B, + 0x0C, 0x30, 0x18, 0x00, 0xB9, 0x51, 0x1C, 0x00, 0xB9, 0x61, 0x24, 0x00, 0xB9, 0x71, 0x28, 0x00, + 0x4B, 0x18, 0x00, 0x00, 0x3C, 0x20, 0x16, 0x00, 0x23, 0x22, 0xC4, 0x21, 0x38, 0x41, 0x20, 0x00, + 0x38, 0x51, 0x1C, 0x00, 0x38, 0x61, 0x24, 0x00, 0x38, 0x71, 0x28, 0x00, 0xC2, 0x2B, 0x5C, 0x40, + 0xFF, 0x0F, 0x5C, 0x50, 0xFF, 0x0F, 0x3F, 0x25, 0x04, 0x00, 0x23, 0x22, 0xC3, 0x32, 0x5C, 0x60, + 0xFF, 0x0F, 0x5C, 0x70, 0xFF, 0x0F, 0x36, 0x67, 0x02, 0x06, 0xC4, 0x60, 0x32, 0x0E, 0x3F, 0x66, + 0x03, 0x00, 0xF2, 0x06, 0xC4, 0x30, 0x82, 0x09, 0xC4, 0x60, 0x02, 0x07, 0x36, 0x63, 0xCC, 0x60, + 0x14, 0x00, 0x02, 0x03, 0x24, 0xC1, 0x23, 0xCC, 0xC6, 0x45, 0xC2, 0x05, 0xC6, 0xD3, 0x32, 0x0A, + 0x06, 0xD2, 0xF2, 0x08, 0x36, 0x54, 0x23, 0x55, 0xC6, 0x5E, 0x06, 0x75, 0xB2, 0x02, 0x06, 0x7E, + 0x23, 0xE7, 0x24, 0xB1, 0x23, 0xBB, 0xCC, 0xB0, 0x50, 0x01, 0x24, 0x92, 0x24, 0xA2, 0x92, 0xB0, + 0xCC, 0xD0, 0x2C, 0x01, 0xC2, 0x05, 0x04, 0x61, 0xA9, 0x60, 0x8E, 0x1B, 0xF2, 0x03, 0xA9, 0x00, + 0x8E, 0x1B, 0x28, 0x40, 0x76, 0x1A, 0x26, 0x44, 0x0C, 0x70, 0x54, 0x05, 0x0C, 0xF0, 0x80, 0x02, + 0x26, 0x74, 0x26, 0x4F, 0x20, 0x57, 0x20, 0x64, 0x5C, 0x50, 0xFF, 0x0F, 0x5C, 0x60, 0xFF, 0x0F, + 0xC6, 0x56, 0x04, 0x70, 0x02, 0x04, 0x3F, 0x76, 0x05, 0x00, 0x23, 0x77, 0x98, 0x50, 0xC5, 0x1B, + 0x06, 0x46, 0x82, 0x09, 0x0C, 0x50, 0x20, 0x00, 0x04, 0x35, 0x0C, 0x20, 0xFA, 0x00, 0x0C, 0x60, + 0x14, 0x00, 0xF2, 0x08, 0x0C, 0x50, 0x30, 0x00, 0x04, 0x3A, 0x0C, 0x20, 0x2C, 0x01, 0x0C, 0x60, + 0x19, 0x00, 0xC6, 0xD6, 0xC2, 0x4A, 0xC6, 0xD2, 0xB2, 0x0E, 0xC6, 0xC3, 0xC2, 0x0C, 0xC6, 0x75, + 0xC2, 0x0A, 0x28, 0x50, 0x96, 0x1B, 0xCC, 0x50, 0x1F, 0x00, 0xD2, 0x05, 0x28, 0x50, 0x94, 0x1B, + 0xC4, 0x54, 0xC2, 0x18, 0xC6, 0xD6, 0xC2, 0x39, 0xCC, 0xD0, 0x5F, 0x00, 0xD2, 0x36, 0xC4, 0xC1, + 0xC2, 0x34, 0xC4, 0x76, 0xC2, 0x32, 0xA8, 0x70, 0x96, 0x1B, 0x92, 0x2F, 0x28, 0x70, 0x94, 0x1B, + 0xC4, 0x72, 0xD2, 0x2B, 0xA8, 0x70, 0x9A, 0x1B, 0x92, 0x28, 0x28, 0x70, 0x98, 0x1B, 0xC4, 0x72, + 0xD2, 0x24, 0xCC, 0xE0, 0x9F, 0x00, 0xD2, 0x21, 0x38, 0x70, 0xFC, 0x0A, 0xCC, 0x70, 0x64, 0x00, + 0xC2, 0x1C, 0xB8, 0x70, 0x8C, 0x19, 0x92, 0x1B, 0x28, 0x50, 0x90, 0x1B, 0x24, 0x51, 0x23, 0x55, + 0xC4, 0x55, 0xA9, 0x50, 0x90, 0x1B, 0xC2, 0x13, 0x1C, 0x50, 0x6A, 0x00, 0x99, 0x50, 0xAC, 0x1B, + 0xA9, 0x00, 0x90, 0x1B, 0x08, 0x70, 0x08, 0x00, 0x66, 0x78, 0x0C, 0x50, 0xFC, 0x0A, 0xB9, 0x75, + 0x0C, 0x00, 0x99, 0x00, 0xC5, 0x1B, 0xF2, 0x03, 0xA9, 0x00, 0x90, 0x1B, 0xB8, 0x70, 0x8C, 0x19, + 0x8A, 0xCF, 0x00, 0x00, 0x04, 0xC0, 0x0C, 0xD0, 0x50, 0x02, 0x0C, 0xE0, 0x24, 0x05, 0xB9, 0xC1, + 0x04, 0x00, 0xB1, 0xC1, 0x06, 0xBC, 0x0C, 0x50, 0x60, 0x00, 0x26, 0x5D, 0x70, 0x55, 0x70, 0x4E, + 0x78, 0xAE, 0x2E, 0x00, 0xB9, 0x51, 0x14, 0x00, 0x0C, 0x60, 0x30, 0x00, 0x0C, 0x70, 0x30, 0x00, + 0x26, 0x6D, 0x26, 0x7E, 0x70, 0x66, 0x70, 0x77, 0x78, 0x8E, 0x32, 0x00, 0xB9, 0x61, 0x0C, 0x00, + 0x0C, 0x50, 0x60, 0x00, 0x26, 0x5E, 0x78, 0x6D, 0x2E, 0x00, 0x70, 0x55, 0xB9, 0x71, 0x10, 0x00, + 0x78, 0x7D, 0x32, 0x00, 0x70, 0x9D, 0xB9, 0x51, 0x18, 0x00, 0x06, 0x2B, 0x0C, 0x30, 0x18, 0x00, + 0xB9, 0x41, 0x20, 0x00, 0xB9, 0x61, 0x24, 0x00, 0xB9, 0x71, 0x28, 0x00, 0x4B, 0x18, 0x00, 0x00, + 0x34, 0x21, 0x23, 0x22, 0xCC, 0x20, 0x14, 0x00, 0x38, 0x41, 0x20, 0x00, 0x38, 0x61, 0x24, 0x00, + 0x38, 0x71, 0x28, 0x00, 0xD2, 0x61, 0x1C, 0x50, 0x18, 0x00, 0x26, 0x5B, 0xCC, 0x50, 0x1F, 0x01, + 0xD2, 0x5B, 0x0C, 0x20, 0xFF, 0x0F, 0x0C, 0x50, 0xFF, 0x0F, 0x56, 0x28, 0x56, 0x59, 0x38, 0x81, + 0x0C, 0x00, 0x38, 0x91, 0x10, 0x00, 0x5C, 0x80, 0xFF, 0x0F, 0x5C, 0x90, 0xFF, 0x0F, 0x0C, 0xF0, + 0xFF, 0x0F, 0x0C, 0x30, 0xFF, 0x0F, 0x3F, 0x99, 0x08, 0x00, 0x56, 0xF6, 0x56, 0x37, 0x38, 0x61, + 0x18, 0x00, 0x38, 0x71, 0x14, 0x00, 0xC4, 0x90, 0x5C, 0xA0, 0xFF, 0x0F, 0x5C, 0x40, 0xFF, 0x0F, + 0x5C, 0x70, 0xFF, 0x0F, 0x5C, 0x60, 0xFF, 0x0F, 0x02, 0x1D, 0x36, 0xFA, 0x3C, 0xF0, 0x15, 0x00, + 0xCC, 0xF0, 0x30, 0x00, 0xD2, 0x31, 0x36, 0x32, 0xCC, 0x30, 0x14, 0x00, 0x02, 0x2D, 0x36, 0x54, + 0xCC, 0x50, 0x14, 0x00, 0x02, 0x29, 0x36, 0x76, 0xCC, 0x70, 0x14, 0x00, 0x02, 0x25, 0x30, 0x71, + 0xCC, 0x90, 0x46, 0x00, 0x24, 0x71, 0x23, 0x77, 0xB1, 0x71, 0x02, 0x1E, 0x24, 0xC1, 0x23, 0xCC, + 0xF2, 0x1B, 0x3F, 0xFF, 0x0A, 0x00, 0xCC, 0xF0, 0x1E, 0x00, 0x02, 0x16, 0x3F, 0x33, 0x02, 0x00, + 0xCC, 0x30, 0x1E, 0x00, 0x02, 0x11, 0x3F, 0x55, 0x04, 0x00, 0xCC, 0x50, 0x1E, 0x00, 0x02, 0x0C, + 0x3F, 0x77, 0x06, 0x00, 0xCC, 0x70, 0x1E, 0x00, 0x02, 0x07, 0x38, 0x71, 0x04, 0x00, 0x24, 0x71, + 0x23, 0x77, 0xB9, 0x71, 0x04, 0x00, 0x24, 0xB1, 0x23, 0xBB, 0xCC, 0xB0, 0x50, 0x01, 0x24, 0xD2, + 0x24, 0xE2, 0x9A, 0x62, 0xFF, 0xFF, 0x30, 0x61, 0xC4, 0x64, 0xD2, 0x20, 0x38, 0x71, 0x04, 0x00, + 0x3C, 0x70, 0x11, 0x00, 0xCC, 0x70, 0x3E, 0x00, 0xD2, 0x19, 0xC4, 0xC1, 0xD2, 0x17, 0x98, 0x70, + 0xAC, 0x1B, 0x92, 0x14, 0x38, 0x70, 0xFC, 0x0A, 0xCC, 0x70, 0x64, 0x00, 0xC2, 0x11, 0x28, 0x50, + 0x92, 0x1B, 0x24, 0x51, 0x23, 0x55, 0xCC, 0x50, 0x32, 0x00, 0xA9, 0x50, 0x92, 0x1B, 0xC2, 0x08, + 0x0C, 0x50, 0x64, 0x00, 0x99, 0x50, 0xAC, 0x1B, 0xF2, 0x01, 0xA9, 0x00, 0x92, 0x1B, 0xCB, 0xE4, + 0x04, 0x00, 0x38, 0x91, 0x08, 0x00, 0x28, 0x79, 0x38, 0x00, 0x0C, 0xA0, 0xFC, 0x0A, 0xA9, 0x7A, + 0x14, 0x00, 0x58, 0xC1, 0x40, 0x00, 0x58, 0x81, 0x30, 0x00, 0x2C, 0x10, 0x50, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0xE0, 0x17, 0x00, 0x0C, 0xD0, 0x80, 0x02, 0x06, 0x2E, + 0xEB, 0xE0, 0x04, 0x00, 0xC4, 0x20, 0x92, 0x05, 0x2F, 0x7E, 0x0E, 0x00, 0x26, 0x7D, 0xA1, 0x07, + 0x2C, 0xE0, 0x18, 0x00, 0xCC, 0xE0, 0x67, 0x01, 0x92, 0xF3, 0x6B, 0xE2, 0x04, 0x00, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x18, 0x00, 0xC9, 0xE1, 0x10, 0x00, + 0x0C, 0x40, 0x88, 0x01, 0x06, 0x2E, 0x0C, 0x20, 0x78, 0x15, 0x04, 0x30, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x06, 0x31, 0x06, 0x2E, 0x0C, 0x20, 0x78, 0x15, 0x2B, 0xCB, 0x03, 0x00, 0x8B, 0xF5, + 0x03, 0x00, 0x06, 0x2E, 0x0C, 0x20, 0x78, 0x15, 0x0B, 0xC2, 0x03, 0x00, 0x38, 0x20, 0xFC, 0x16, + 0x06, 0x31, 0x6B, 0x03, 0x04, 0x00, 0x48, 0xE1, 0x10, 0x00, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x0C, 0x30, 0x20, 0x0C, 0x04, 0x60, + 0x0C, 0xC0, 0x80, 0x02, 0x0C, 0xE0, 0x54, 0x05, 0x0C, 0xA0, 0xFC, 0x0A, 0x70, 0xB3, 0x04, 0x70, + 0x06, 0x57, 0x2F, 0xDC, 0x06, 0x00, 0x2F, 0xFE, 0x06, 0x00, 0x2F, 0x27, 0x0D, 0x00, 0x2F, 0x47, + 0x0F, 0x00, 0x70, 0x92, 0x70, 0x44, 0xCC, 0x50, 0x17, 0x00, 0x3F, 0x44, 0x09, 0x00, 0x36, 0x4B, + 0x82, 0x06, 0x2F, 0x9A, 0x07, 0x00, 0x78, 0x99, 0xF4, 0x00, 0x36, 0x49, 0x86, 0x44, 0x32, 0x02, + 0x04, 0x40, 0x24, 0x51, 0xCC, 0x50, 0x18, 0x00, 0xA1, 0x42, 0x24, 0x72, 0x92, 0xE7, 0x2C, 0x60, + 0x30, 0x00, 0xCC, 0x60, 0xA0, 0x02, 0x24, 0x32, 0x92, 0xDA, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, + 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x0C, 0x70, + 0xFC, 0x0A, 0x38, 0x67, 0x0C, 0x00, 0x82, 0x15, 0x64, 0x61, 0xB9, 0x67, 0x0C, 0x00, 0x08, 0x70, + 0x00, 0x80, 0x2C, 0x70, 0x20, 0xE0, 0xB9, 0x70, 0x70, 0x1A, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, + 0x04, 0xDE, 0xB9, 0x70, 0x6C, 0x1A, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0xC4, 0xDC, 0xF2, 0x15, + 0x14, 0x22, 0x56, 0x62, 0xB9, 0x67, 0x0C, 0x00, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0x44, 0xDF, + 0xB9, 0x70, 0x70, 0x1A, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0xA4, 0xDE, 0xB9, 0x70, 0x6C, 0x1A, + 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0x64, 0xDD, 0xB9, 0x70, 0x68, 0x1A, 0xE1, 0xF0, 0x00, 0x00, + 0x0C, 0x70, 0xFC, 0x0A, 0x99, 0x07, 0x59, 0x01, 0x99, 0x07, 0x58, 0x01, 0xE1, 0xF0, 0x00, 0x00, + 0x38, 0x60, 0x70, 0x1A, 0x0C, 0x70, 0xFC, 0x0A, 0x18, 0x57, 0x56, 0x01, 0x18, 0x66, 0xC2, 0x00, + 0xC6, 0x56, 0xA2, 0x15, 0x38, 0x60, 0x6C, 0x19, 0xCC, 0x60, 0x1F, 0x03, 0xD2, 0x17, 0x38, 0x67, + 0x0C, 0x00, 0x6C, 0x60, 0x00, 0x04, 0xB9, 0x67, 0x0C, 0x00, 0x04, 0x61, 0x99, 0x60, 0xB4, 0x1B, + 0x18, 0x60, 0xAB, 0x1B, 0x24, 0x61, 0x99, 0x60, 0xAB, 0x1B, 0xF2, 0x08, 0x38, 0x67, 0x0C, 0x00, + 0x1C, 0x50, 0x01, 0x04, 0x56, 0x65, 0xB9, 0x67, 0x0C, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x34, 0x00, + 0xD9, 0x81, 0x14, 0x00, 0x06, 0xB3, 0x38, 0x30, 0x70, 0x1A, 0xD9, 0xC1, 0x24, 0x00, 0x06, 0xC2, + 0xB1, 0x31, 0x4B, 0x3E, 0x00, 0x00, 0x0C, 0x30, 0x18, 0x00, 0x4B, 0x18, 0x00, 0x00, 0x23, 0x82, + 0x4B, 0x3E, 0x00, 0x00, 0x0C, 0x30, 0x18, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x06, 0x74, 0x0C, 0x70, + 0xFC, 0x0A, 0x38, 0x97, 0x0C, 0x00, 0x23, 0x52, 0xD4, 0x91, 0x82, 0x05, 0x04, 0x6A, 0x0C, 0xD0, + 0xFA, 0x00, 0xF2, 0x04, 0x04, 0x68, 0x0C, 0xD0, 0x64, 0x00, 0x38, 0xEB, 0x08, 0x00, 0xB9, 0x41, + 0x0C, 0x00, 0x06, 0x2C, 0x0C, 0x30, 0x42, 0x01, 0xB9, 0x51, 0x08, 0x00, 0xB9, 0x61, 0x04, 0x00, + 0xB9, 0x71, 0x10, 0x00, 0xAB, 0x15, 0x00, 0x00, 0xC6, 0x2D, 0x30, 0xCB, 0x38, 0xDB, 0x04, 0x00, + 0x38, 0x41, 0x0C, 0x00, 0x38, 0xBB, 0x0C, 0x00, 0x38, 0x51, 0x08, 0x00, 0x38, 0x61, 0x04, 0x00, + 0x38, 0x71, 0x10, 0x00, 0x06, 0xA2, 0xDA, 0xE4, 0x01, 0x00, 0xCC, 0xD0, 0x14, 0x00, 0x02, 0x0B, + 0xCC, 0xC0, 0x40, 0x00, 0x02, 0x08, 0xC4, 0xB3, 0x12, 0x06, 0xCC, 0xE0, 0x1F, 0x00, 0x0A, 0xD8, + 0x01, 0x00, 0xF2, 0x03, 0xC4, 0xE0, 0x02, 0x1A, 0x2F, 0x3E, 0x0E, 0x00, 0xC6, 0xC3, 0x02, 0x0B, + 0xC4, 0xD3, 0x02, 0x14, 0xCC, 0xE0, 0x1F, 0x00, 0x12, 0x11, 0xC6, 0xB6, 0x2A, 0xC9, 0x01, 0x00, + 0xFA, 0xE4, 0x02, 0x00, 0xCC, 0xC0, 0x19, 0x00, 0x02, 0x09, 0xC4, 0xD3, 0x02, 0x07, 0xCC, 0xE0, + 0x1F, 0x00, 0x12, 0x04, 0xC6, 0xB6, 0x2A, 0xBC, 0x01, 0x00, 0xC6, 0xD6, 0x02, 0x1D, 0xCC, 0xC0, + 0x14, 0x00, 0x02, 0x0A, 0xCC, 0xE0, 0x13, 0x00, 0x12, 0x07, 0xC4, 0xB2, 0x12, 0x05, 0xCC, 0xA0, + 0x13, 0x00, 0xDA, 0xAE, 0x01, 0x00, 0xC4, 0xDA, 0x02, 0x11, 0x14, 0x31, 0x26, 0x3B, 0xC4, 0x32, + 0xD2, 0x0D, 0xCC, 0xC0, 0x1E, 0x00, 0x02, 0x0A, 0xCC, 0xE0, 0x1D, 0x00, 0x12, 0x07, 0xC4, 0xAF, + 0xDA, 0x9F, 0x01, 0x00, 0xF2, 0x03, 0xC4, 0xD3, 0x02, 0x0F, 0xC4, 0xB2, 0x02, 0x0D, 0xCC, 0xE0, + 0x13, 0x00, 0x12, 0x0A, 0xC6, 0xB6, 0x32, 0x08, 0xC6, 0xCE, 0x02, 0x06, 0xC6, 0xDB, 0x02, 0x04, + 0xC6, 0xA6, 0xBA, 0x8E, 0x01, 0x00, 0xCC, 0xC0, 0x70, 0x00, 0x02, 0x0B, 0xCC, 0xD0, 0x40, 0x00, + 0x02, 0x08, 0xCC, 0xE0, 0x2F, 0x00, 0x12, 0x05, 0xCC, 0xA0, 0x20, 0x00, 0xDA, 0x81, 0x01, 0x00, + 0x38, 0x60, 0xFC, 0x0A, 0xCC, 0x60, 0xF3, 0x01, 0xD2, 0x11, 0xCC, 0xC0, 0x40, 0x00, 0x02, 0x0E, + 0xCC, 0xD0, 0x20, 0x00, 0x02, 0x0B, 0xCC, 0xE0, 0x2F, 0x00, 0x12, 0x08, 0xCC, 0xB0, 0x15, 0x00, + 0x12, 0x05, 0xCC, 0xA0, 0x10, 0x00, 0xDA, 0x6C, 0x01, 0x00, 0xC4, 0x90, 0x92, 0x6A, 0xC4, 0x85, + 0xC2, 0x11, 0xC4, 0x59, 0xD2, 0x0F, 0xCC, 0xC0, 0x10, 0x00, 0x02, 0x1A, 0xC4, 0xDA, 0x02, 0x0A, + 0xCC, 0xE0, 0x1F, 0x00, 0x12, 0x07, 0xC4, 0xB5, 0x12, 0x05, 0xCC, 0xA0, 0x30, 0x00, 0xDA, 0x5C, + 0x01, 0x00, 0xCC, 0xC0, 0x40, 0x00, 0x02, 0x0C, 0xCC, 0xD0, 0x30, 0x00, 0x02, 0x09, 0x14, 0x61, + 0x26, 0x6B, 0xC4, 0x6E, 0xD2, 0x05, 0xCC, 0xA0, 0x30, 0x00, 0xDA, 0x4E, 0x01, 0x00, 0xC6, 0xDB, + 0x02, 0x48, 0xCC, 0xD0, 0x26, 0x00, 0x02, 0x08, 0xCC, 0xB0, 0x21, 0x00, 0x12, 0x05, 0xCC, 0xA0, + 0x38, 0x00, 0xDA, 0x42, 0x01, 0x00, 0xC4, 0xDE, 0x02, 0x13, 0xC6, 0xCE, 0x0A, 0x5C, 0x02, 0x00, + 0xCC, 0xE0, 0x29, 0x00, 0x1A, 0x5E, 0x02, 0x00, 0x14, 0x61, 0x26, 0x6B, 0xC4, 0x66, 0xDA, 0x59, + 0x02, 0x00, 0xCC, 0xA0, 0x22, 0x00, 0xDA, 0x30, 0x01, 0x00, 0xFA, 0x53, 0x02, 0x00, 0xCC, 0xD0, + 0x15, 0x00, 0x02, 0x0D, 0xC6, 0xCE, 0x12, 0x04, 0xCC, 0xC0, 0x30, 0x00, 0x02, 0x17, 0xCC, 0xB0, + 0x11, 0x00, 0x12, 0x05, 0xCC, 0xA0, 0x27, 0x00, 0xDA, 0x1F, 0x01, 0x00, 0xCC, 0xD0, 0x10, 0x00, + 0x02, 0x0D, 0xC6, 0xCE, 0x02, 0x16, 0xCC, 0xE0, 0x35, 0x00, 0x1A, 0x41, 0x02, 0x00, 0xCC, 0xA0, + 0x27, 0x00, 0xDA, 0x12, 0x01, 0x00, 0xFA, 0x3B, 0x02, 0x00, 0xCC, 0xD0, 0x13, 0x00, 0x02, 0x09, + 0xC6, 0xCE, 0x02, 0x07, 0xC4, 0xB7, 0x12, 0x05, 0xCC, 0xA0, 0x20, 0x00, 0xDA, 0x05, 0x01, 0x00, + 0xCC, 0xC0, 0x70, 0x00, 0x02, 0x0F, 0xCC, 0xD0, 0x40, 0x00, 0x02, 0x0F, 0xCC, 0xE0, 0x4F, 0x00, + 0x12, 0x0E, 0xCC, 0xB0, 0x29, 0x00, 0x12, 0x0B, 0xCC, 0xA0, 0x50, 0x00, 0xDA, 0xF1, 0x00, 0x00, + 0xF2, 0x06, 0xCC, 0xC0, 0x20, 0x00, 0x02, 0x3C, 0xC4, 0xDA, 0x02, 0x0A, 0x1C, 0x60, 0x17, 0x00, + 0x26, 0x6E, 0xCC, 0x60, 0x28, 0x00, 0xD2, 0x04, 0xC4, 0xBF, 0x0A, 0xE2, 0x00, 0x00, 0xCC, 0xC0, + 0x40, 0x00, 0x02, 0x0F, 0xCC, 0xD0, 0x18, 0x00, 0x02, 0x20, 0xCC, 0xE0, 0x40, 0x00, 0x02, 0x0C, + 0xCC, 0xB0, 0x1F, 0x00, 0x12, 0x09, 0xCC, 0xA0, 0x28, 0x00, 0xDA, 0xD2, 0x00, 0x00, 0xF2, 0x04, + 0xCC, 0xC0, 0x30, 0x00, 0x02, 0x0F, 0xCC, 0xD0, 0x20, 0x00, 0x02, 0x0F, 0xCC, 0xE0, 0xC0, 0x00, + 0x02, 0x45, 0xCC, 0xB0, 0x7F, 0x00, 0x12, 0x42, 0xCC, 0xA0, 0x28, 0x00, 0xDA, 0xC1, 0x00, 0x00, + 0xF2, 0x3D, 0xCC, 0xC0, 0x20, 0x00, 0x02, 0x0C, 0xC4, 0xD1, 0x12, 0x38, 0xC4, 0xEF, 0x12, 0x0D, + 0xC4, 0xB2, 0x12, 0x0B, 0xCC, 0xA0, 0x1A, 0x00, 0xDA, 0xB3, 0x00, 0x00, 0xF2, 0x06, 0xCC, 0xC0, + 0x18, 0x00, 0x02, 0x21, 0xC4, 0xD1, 0x12, 0x2A, 0x2F, 0x6E, 0x0E, 0x00, 0x26, 0x6E, 0x06, 0x26, + 0x57, 0x22, 0x36, 0x26, 0x57, 0x21, 0x0C, 0x30, 0x64, 0x00, 0xB9, 0x41, 0x0C, 0x00, 0xB9, 0x51, + 0x08, 0x00, 0xB9, 0x71, 0x10, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x23, 0x22, 0xC6, 0xC2, 0x38, 0x41, + 0x0C, 0x00, 0x38, 0x51, 0x08, 0x00, 0x38, 0x71, 0x10, 0x00, 0x02, 0x10, 0xC4, 0xB2, 0x0A, 0x90, + 0x00, 0x00, 0xF2, 0x0C, 0xC4, 0xCF, 0x12, 0x0A, 0xC4, 0xD4, 0x12, 0x08, 0xCC, 0xE0, 0x80, 0x00, + 0x02, 0x05, 0xCC, 0xB0, 0x40, 0x00, 0x1A, 0x84, 0x00, 0x00, 0x18, 0x67, 0x8C, 0x06, 0xC4, 0x62, + 0xC2, 0x0B, 0xCC, 0xC0, 0x10, 0x00, 0x02, 0x0A, 0xC4, 0xD4, 0x12, 0x08, 0xC4, 0xEF, 0x12, 0x06, + 0xC4, 0xB4, 0x02, 0x76, 0xF2, 0x05, 0xC4, 0x62, 0x92, 0x10, 0xC6, 0xCE, 0x02, 0x0E, 0xC6, 0xDB, + 0x02, 0x0C, 0xCC, 0xC0, 0x20, 0x00, 0x02, 0x12, 0xC4, 0xD8, 0x02, 0x0A, 0xCC, 0xE0, 0x20, 0x00, + 0x02, 0x07, 0xC4, 0xB8, 0x12, 0x65, 0xF2, 0x04, 0xCC, 0xC0, 0x20, 0x00, 0x02, 0x07, 0xC4, 0xD4, + 0x12, 0x05, 0xC4, 0xE4, 0x12, 0x03, 0xC4, 0xB4, 0x02, 0x5B, 0x04, 0x60, 0xC6, 0x96, 0x9A, 0xEE, + 0x00, 0x00, 0xCC, 0x80, 0x16, 0x00, 0x06, 0x69, 0x8A, 0xE9, 0x00, 0x00, 0xC4, 0x80, 0x8A, 0xE6, + 0x00, 0x00, 0xC4, 0x5D, 0x8A, 0xE3, 0x00, 0x00, 0xC4, 0x50, 0x8A, 0xE0, 0x00, 0x00, 0xC4, 0xC5, + 0x02, 0x31, 0xC4, 0xD1, 0x02, 0x07, 0xC4, 0xE0, 0x12, 0x05, 0xC4, 0xB0, 0x12, 0x03, 0xC4, 0xA4, + 0xD2, 0x43, 0xC4, 0xCE, 0x02, 0x19, 0xC4, 0xD0, 0x02, 0x08, 0xC4, 0xE6, 0x12, 0x06, 0xC4, 0xB9, + 0x12, 0x04, 0xCC, 0xA0, 0x10, 0x00, 0xD2, 0x38, 0xCC, 0xC0, 0x40, 0x00, 0x02, 0x0D, 0xCC, 0xD0, + 0x14, 0x00, 0x02, 0x0D, 0xCC, 0xE0, 0x2F, 0x00, 0x12, 0x0C, 0xC4, 0xB6, 0x12, 0x0A, 0xCC, 0xA0, + 0x2A, 0x00, 0xD2, 0x2A, 0xF2, 0x06, 0xCC, 0xC0, 0x20, 0x00, 0x02, 0x0C, 0xC4, 0xDA, 0x02, 0x0F, + 0xCC, 0xE0, 0x1F, 0x00, 0x12, 0x10, 0xC4, 0xB9, 0x12, 0x0E, 0xCC, 0xA0, 0x18, 0x00, 0xD2, 0x1C, + 0xF2, 0x0A, 0xCC, 0xC0, 0x1A, 0x00, 0x04, 0x60, 0x0A, 0xA9, 0x00, 0x00, 0xC4, 0xD8, 0x04, 0x60, + 0x0A, 0xA5, 0x00, 0x00, 0xCC, 0xE0, 0x19, 0x00, 0x04, 0x60, 0x1A, 0xA0, 0x00, 0x00, 0xC4, 0xB4, + 0x1A, 0x9D, 0x00, 0x00, 0xCC, 0xA0, 0x10, 0x00, 0xCA, 0x99, 0x00, 0x00, 0xF2, 0x05, 0xC4, 0x90, + 0x04, 0x61, 0x9A, 0x94, 0x00, 0x00, 0x14, 0x66, 0x26, 0x6E, 0xC4, 0x69, 0xD2, 0x0A, 0x14, 0x61, + 0x26, 0x6B, 0xC4, 0x63, 0xD2, 0x17, 0xC4, 0xCF, 0x04, 0x60, 0x0A, 0x88, 0x00, 0x00, 0xF2, 0x12, + 0xC4, 0xE1, 0x12, 0x10, 0xC4, 0xB0, 0x12, 0x0E, 0x1C, 0x60, 0x11, 0x00, 0x26, 0x6C, 0xC4, 0x6E, + 0xD2, 0x09, 0x14, 0x63, 0x26, 0x6D, 0xC4, 0x6C, 0xD2, 0x05, 0xCC, 0xA0, 0x1F, 0x00, 0x04, 0x60, + 0xC2, 0x75, 0xC4, 0x8B, 0xD2, 0x42, 0xC4, 0x58, 0xC2, 0x40, 0xCC, 0xC0, 0x35, 0x00, 0x12, 0x0A, + 0xC4, 0xDF, 0x12, 0x08, 0xCC, 0xE0, 0x13, 0x00, 0x02, 0x05, 0xCC, 0xA0, 0x23, 0x00, 0x04, 0x60, + 0xC2, 0x65, 0xC4, 0x59, 0xC2, 0x10, 0xCC, 0xC0, 0x3F, 0x00, 0x12, 0x0D, 0xCC, 0xD0, 0x19, 0x00, + 0x12, 0x0A, 0xCC, 0xE0, 0x1A, 0x00, 0x02, 0x07, 0xC4, 0xB0, 0x02, 0x05, 0xCC, 0xA0, 0x27, 0x00, + 0x04, 0x60, 0xC2, 0x54, 0xCC, 0xC0, 0x25, 0x00, 0x12, 0x15, 0xC4, 0xD3, 0x12, 0x07, 0xC4, 0xED, + 0x02, 0x05, 0xCC, 0xA0, 0x19, 0x00, 0x04, 0x60, 0xC2, 0x49, 0xCC, 0xC0, 0x19, 0x00, 0x12, 0x0A, + 0xC4, 0xD2, 0x12, 0x0B, 0xC4, 0xE5, 0x02, 0x09, 0xCC, 0xA0, 0x2F, 0x00, 0x04, 0x60, 0xC2, 0x3E, + 0xF2, 0x04, 0xCC, 0xC0, 0x2F, 0x00, 0x12, 0x09, 0xC4, 0xD9, 0x12, 0x07, 0xC4, 0xED, 0x02, 0x05, + 0xCC, 0xA0, 0x1F, 0x00, 0x04, 0x60, 0xC2, 0x32, 0xCC, 0xC0, 0x45, 0x00, 0x12, 0x0D, 0xCC, 0xD0, + 0x1F, 0x00, 0x12, 0x0A, 0xCC, 0xE0, 0x30, 0x00, 0x02, 0x07, 0xC4, 0xB4, 0x02, 0x05, 0xCC, 0xA0, + 0x2F, 0x00, 0x04, 0x60, 0xC2, 0x23, 0x18, 0x67, 0x8C, 0x06, 0xC4, 0x62, 0xD2, 0x0E, 0xCC, 0xC0, + 0x14, 0x00, 0x12, 0x0B, 0xC4, 0xD5, 0x12, 0x09, 0xC4, 0xE3, 0x02, 0x0B, 0xC4, 0xB0, 0x02, 0x05, + 0xCC, 0xA0, 0x29, 0x00, 0x04, 0x60, 0xC2, 0x12, 0xCC, 0xE0, 0x13, 0x00, 0x04, 0x61, 0x12, 0x0E, + 0x04, 0x61, 0xC6, 0xB6, 0x12, 0x0B, 0xCC, 0xC0, 0x13, 0x00, 0x12, 0x08, 0xC6, 0xD6, 0x12, 0x06, + 0xCC, 0xA0, 0x13, 0x00, 0xD2, 0x02, 0x04, 0x60, 0x23, 0x66, 0xB8, 0x30, 0x8C, 0x19, 0x82, 0x4E, + 0x38, 0x40, 0xFC, 0x0A, 0x04, 0x60, 0xCC, 0x40, 0x32, 0x00, 0xC2, 0x48, 0xCC, 0xC0, 0x50, 0x00, + 0x02, 0x1B, 0xCC, 0xD0, 0x10, 0x00, 0x02, 0x09, 0xC4, 0xE9, 0x12, 0x07, 0xC6, 0xB6, 0x12, 0x05, + 0xCC, 0xA0, 0x20, 0x00, 0x04, 0x61, 0xD2, 0x3A, 0xCC, 0xC0, 0x80, 0x00, 0x02, 0x0F, 0xCC, 0xD0, + 0x30, 0x00, 0x02, 0x0C, 0xC4, 0xEF, 0x12, 0x0A, 0xC4, 0xB0, 0x12, 0x08, 0xCC, 0xA0, 0x20, 0x00, + 0x04, 0x61, 0xD2, 0x2C, 0xF2, 0x03, 0xC4, 0xC4, 0x02, 0x0A, 0xC4, 0xD0, 0x92, 0x08, 0xC4, 0xE2, + 0x12, 0x06, 0xC4, 0xB0, 0x12, 0x04, 0xC4, 0xA8, 0x04, 0x61, 0xD2, 0x20, 0x04, 0x60, 0xC6, 0x96, + 0x92, 0x1D, 0xCC, 0xC0, 0x1A, 0x00, 0x02, 0x0B, 0xC4, 0xD3, 0x12, 0x0C, 0xC4, 0xE4, 0x12, 0x0A, + 0xC6, 0xB6, 0x12, 0x08, 0xC4, 0xA8, 0x04, 0x61, 0xD2, 0x11, 0xF2, 0x04, 0xC4, 0xC2, 0x06, 0x69, + 0x02, 0x0D, 0x04, 0x60, 0xC6, 0xD6, 0x12, 0x0A, 0xC6, 0xE6, 0x12, 0x08, 0xC6, 0xB6, 0x12, 0x06, + 0xC4, 0xAB, 0x04, 0x41, 0xD2, 0x02, 0x06, 0x46, 0x23, 0x64, 0xA9, 0xC0, 0x9A, 0x1B, 0xA9, 0xD0, + 0x98, 0x1B, 0xA9, 0xE0, 0x96, 0x1B, 0xA9, 0xB0, 0x94, 0x1B, 0x98, 0x40, 0xB0, 0x1B, 0x82, 0x07, + 0xC4, 0x90, 0x92, 0x05, 0xB8, 0x50, 0x8C, 0x19, 0x92, 0x02, 0x06, 0x69, 0x38, 0x50, 0x6C, 0x19, + 0xCC, 0x50, 0x1F, 0x03, 0xD2, 0x38, 0xC4, 0x60, 0x82, 0x10, 0x18, 0x67, 0x56, 0x01, 0xCC, 0x60, + 0xFF, 0x00, 0x82, 0x04, 0x24, 0x61, 0x99, 0x67, 0x56, 0x01, 0x98, 0x67, 0x57, 0x01, 0x82, 0x2B, + 0x34, 0x61, 0x99, 0x67, 0x57, 0x01, 0xF2, 0x27, 0x18, 0x67, 0x57, 0x01, 0x30, 0x41, 0x99, 0x07, + 0x56, 0x01, 0x24, 0x61, 0x13, 0x66, 0x99, 0x67, 0x57, 0x01, 0x18, 0x54, 0xC3, 0x00, 0xC6, 0x56, + 0x92, 0x1A, 0x99, 0x07, 0x57, 0x01, 0xF2, 0x17, 0xCC, 0xC0, 0x19, 0x00, 0x1A, 0x24, 0xFD, 0xFF, + 0xFA, 0x25, 0xFD, 0xFF, 0xCC, 0xD0, 0x15, 0x00, 0x1A, 0xB8, 0xFD, 0xFF, 0xFA, 0xC0, 0xFD, 0xFF, + 0xCC, 0xD0, 0x15, 0x00, 0x1A, 0xB5, 0xFD, 0xFF, 0xFA, 0xBA, 0xFD, 0xFF, 0xCC, 0xD0, 0x13, 0x00, + 0xFA, 0xC9, 0xFD, 0xFF, 0x58, 0xC1, 0x24, 0x00, 0x58, 0x81, 0x14, 0x00, 0x2C, 0x10, 0x34, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x18, 0x60, 0xA6, 0x1B, + 0x04, 0x70, 0xC4, 0x61, 0x92, 0x05, 0x08, 0x70, 0x00, 0x80, 0x18, 0x77, 0x3B, 0xDC, 0x70, 0x52, + 0xC6, 0x57, 0x32, 0x03, 0xA1, 0x72, 0xF2, 0x07, 0x0C, 0x60, 0x7F, 0x07, 0x36, 0x67, 0xC6, 0x56, + 0x02, 0x02, 0xA1, 0x62, 0x78, 0x62, 0x02, 0x00, 0xC6, 0x67, 0x22, 0x07, 0x0C, 0x50, 0x37, 0x04, + 0x3F, 0x77, 0x05, 0x00, 0xC6, 0x67, 0x02, 0x03, 0xA9, 0x72, 0x02, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x18, 0x60, 0xA6, 0x1B, 0x04, 0x70, 0xC4, 0x61, 0x92, 0x0C, 0x08, 0x70, 0x00, 0x80, 0x18, 0x67, + 0x3B, 0xDC, 0x2F, 0x76, 0x06, 0x00, 0x26, 0x76, 0x06, 0x57, 0xD7, 0x52, 0x26, 0x75, 0x26, 0x76, + 0x30, 0x52, 0xC6, 0x57, 0x32, 0x03, 0xB1, 0x72, 0xF2, 0x09, 0x08, 0x60, 0x02, 0x00, 0x2C, 0x60, + 0xFF, 0xED, 0x36, 0x67, 0xC6, 0x56, 0x02, 0x02, 0xB1, 0x62, 0x38, 0x52, 0x04, 0x00, 0xC6, 0x57, + 0x22, 0x09, 0x08, 0x60, 0x01, 0x00, 0x2C, 0x60, 0xDF, 0xA5, 0x3F, 0x77, 0x06, 0x00, 0xC6, 0x57, + 0x02, 0x03, 0xB9, 0x72, 0x04, 0x00, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x3C, 0x00, 0xD9, 0x81, 0x1C, 0x00, 0x0C, 0xA0, 0x10, 0x03, 0x26, 0xA3, 0x0C, 0x90, + 0xFC, 0x0A, 0x57, 0xA1, 0xD9, 0xC1, 0x2C, 0x00, 0x26, 0xA9, 0x30, 0xEA, 0x98, 0x70, 0xA2, 0x1B, + 0x77, 0xEE, 0x2C, 0x30, 0x1F, 0x03, 0x2C, 0xE0, 0x29, 0x01, 0x57, 0x31, 0xD7, 0xE1, 0x08, 0x70, + 0x00, 0x80, 0x06, 0xD2, 0x26, 0x39, 0x26, 0xE9, 0x2C, 0x70, 0x0C, 0xDC, 0x82, 0x0C, 0x28, 0x87, + 0xA6, 0x00, 0x78, 0x47, 0xA8, 0x00, 0x78, 0x57, 0xAA, 0x00, 0x78, 0x67, 0xAC, 0x00, 0x78, 0x77, + 0xAE, 0x00, 0xF2, 0x0B, 0x18, 0x87, 0x2E, 0x00, 0x78, 0x47, 0x30, 0x00, 0x78, 0x57, 0x32, 0x00, + 0x78, 0x67, 0x34, 0x00, 0x78, 0x77, 0x36, 0x00, 0x2F, 0xC4, 0x04, 0x00, 0x26, 0xC4, 0x06, 0x2C, + 0xD7, 0x22, 0x2F, 0xB5, 0x05, 0x00, 0x26, 0xB5, 0x26, 0xC2, 0x26, 0xC4, 0x06, 0x4B, 0xD7, 0x42, + 0x26, 0xB4, 0x26, 0xB5, 0x2F, 0x56, 0x06, 0x00, 0x26, 0x56, 0x06, 0x45, 0xD7, 0x42, 0x26, 0x54, + 0x26, 0x56, 0x2F, 0x67, 0x07, 0x00, 0x26, 0x67, 0xB9, 0x51, 0x0C, 0x00, 0x06, 0x56, 0xD7, 0x52, + 0x26, 0x65, 0x26, 0x67, 0x70, 0x7D, 0xB9, 0x61, 0x10, 0x00, 0x06, 0x21, 0x2F, 0x67, 0x07, 0x00, + 0x26, 0x67, 0x06, 0x56, 0xD7, 0x52, 0x26, 0x65, 0x26, 0x76, 0x26, 0x7C, 0xB1, 0x71, 0x78, 0x7D, + 0x02, 0x00, 0xB9, 0x31, 0x14, 0x00, 0x2F, 0x67, 0x07, 0x00, 0x26, 0x67, 0x06, 0x56, 0xD7, 0x52, + 0x26, 0x65, 0x26, 0x76, 0x26, 0x7B, 0xB9, 0x71, 0x04, 0x00, 0x0B, 0x3C, 0x04, 0x00, 0x38, 0x31, + 0x14, 0x00, 0x30, 0x5A, 0x70, 0x6D, 0x30, 0x73, 0xB9, 0x61, 0x08, 0x00, 0x76, 0x75, 0x08, 0x50, + 0x00, 0xF0, 0xD6, 0x75, 0x78, 0x6D, 0x02, 0x00, 0x0C, 0xA0, 0x32, 0x00, 0x82, 0x06, 0xB1, 0x0E, + 0xB9, 0x0E, 0x04, 0x00, 0x0C, 0xA0, 0x64, 0x00, 0x04, 0x72, 0xD6, 0x78, 0x82, 0x6B, 0x26, 0x66, + 0x06, 0x76, 0x57, 0x71, 0x26, 0x67, 0x23, 0x66, 0x43, 0x56, 0xCC, 0x50, 0x41, 0x04, 0x12, 0x16, + 0x0C, 0x70, 0x47, 0x04, 0x36, 0x76, 0x43, 0x27, 0x2F, 0x62, 0x02, 0x00, 0x26, 0x62, 0x06, 0x56, + 0xD7, 0x52, 0x26, 0x65, 0x38, 0x59, 0x78, 0x00, 0x0C, 0x30, 0x42, 0x04, 0x36, 0x35, 0x26, 0x26, + 0x43, 0x33, 0x8B, 0x16, 0x00, 0x00, 0x16, 0x72, 0xF2, 0x18, 0xCC, 0x50, 0x66, 0x26, 0x04, 0x70, + 0x02, 0x14, 0x1C, 0x70, 0x61, 0x26, 0x26, 0x76, 0x23, 0x27, 0x2F, 0x62, 0x02, 0x00, 0x26, 0x62, + 0x38, 0x39, 0xAC, 0x00, 0x06, 0x56, 0xD7, 0x52, 0x26, 0x65, 0x3C, 0x30, 0x66, 0x26, 0x26, 0x26, + 0x43, 0x33, 0x8B, 0x16, 0x00, 0x00, 0x06, 0x72, 0x06, 0x37, 0x06, 0x27, 0xB9, 0x71, 0x18, 0x00, + 0x4B, 0x14, 0x00, 0x00, 0x38, 0x71, 0x18, 0x00, 0x06, 0x32, 0x06, 0x27, 0x4B, 0x14, 0x00, 0x00, + 0x38, 0x3E, 0x04, 0x00, 0x0C, 0x70, 0x64, 0x00, 0x06, 0x52, 0x3F, 0x2A, 0x07, 0x00, 0xB9, 0x51, + 0x14, 0x00, 0xB9, 0x71, 0x18, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x71, 0x18, 0x00, 0x06, 0x37, + 0x8B, 0x16, 0x00, 0x00, 0x38, 0x51, 0x14, 0x00, 0x06, 0x62, 0x0C, 0x30, 0x10, 0x27, 0x06, 0x25, + 0xB9, 0x61, 0x14, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x06, 0x3A, 0x4B, 0x14, 0x00, 0x00, 0x38, 0x71, + 0x18, 0x00, 0x06, 0x37, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x61, 0x14, 0x00, 0x26, 0x26, 0xB9, 0x2E, + 0x04, 0x00, 0xD4, 0x81, 0x82, 0x5D, 0x38, 0x71, 0x08, 0x00, 0x26, 0x77, 0x06, 0x67, 0x57, 0x61, + 0x26, 0x76, 0x23, 0x77, 0x43, 0x67, 0xCC, 0x60, 0xAB, 0x03, 0x12, 0x17, 0x0C, 0x60, 0xB1, 0x03, + 0x3F, 0x77, 0x06, 0x00, 0x43, 0x27, 0x2F, 0x62, 0x02, 0x00, 0x26, 0x62, 0x06, 0x56, 0xD7, 0x52, + 0x26, 0x65, 0x38, 0x59, 0x18, 0x00, 0x0C, 0x30, 0xAC, 0x03, 0x36, 0x35, 0x26, 0x26, 0x43, 0x33, + 0x8B, 0x16, 0x00, 0x00, 0x16, 0x82, 0xF2, 0x17, 0xCC, 0x60, 0x3C, 0x46, 0x04, 0x80, 0x02, 0x13, + 0x3C, 0x70, 0x37, 0x46, 0x23, 0x27, 0x2F, 0x62, 0x02, 0x00, 0x26, 0x62, 0x38, 0x39, 0x70, 0x00, + 0x06, 0x56, 0xD7, 0x52, 0x26, 0x65, 0x3C, 0x30, 0x3C, 0x46, 0x26, 0x26, 0x43, 0x33, 0x8B, 0x16, + 0x00, 0x00, 0x06, 0x82, 0x06, 0x38, 0x06, 0x28, 0x4B, 0x14, 0x00, 0x00, 0x06, 0x32, 0x06, 0x28, + 0x4B, 0x14, 0x00, 0x00, 0x30, 0x3E, 0x0C, 0x90, 0x64, 0x00, 0x06, 0x72, 0x3F, 0x2A, 0x09, 0x00, + 0xB9, 0x71, 0x18, 0x00, 0x4B, 0x14, 0x00, 0x00, 0x06, 0x39, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x71, + 0x18, 0x00, 0x06, 0x82, 0x0C, 0x30, 0x10, 0x27, 0x06, 0x27, 0x8B, 0x16, 0x00, 0x00, 0x06, 0x3A, + 0x4B, 0x14, 0x00, 0x00, 0x06, 0x39, 0x8B, 0x16, 0x00, 0x00, 0x26, 0x28, 0xB1, 0x2E, 0x30, 0x2E, + 0x0C, 0x30, 0x11, 0x0F, 0x4B, 0x14, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x8B, 0x16, 0x00, 0x00, + 0x30, 0xA1, 0x0C, 0x30, 0x4D, 0x10, 0x26, 0xA2, 0x38, 0x2E, 0x04, 0x00, 0xB1, 0xA1, 0x4B, 0x14, + 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x8B, 0x16, 0x00, 0x00, 0x38, 0x71, 0x04, 0x00, 0xC4, 0xB0, + 0x26, 0x27, 0x06, 0x7B, 0x32, 0x02, 0x16, 0x7B, 0x38, 0x61, 0x10, 0x00, 0xC4, 0xB0, 0x26, 0x76, + 0x22, 0x08, 0xC6, 0x27, 0x22, 0x0E, 0xC4, 0xB0, 0x82, 0x04, 0xB9, 0x21, 0x04, 0x00, 0xF2, 0x0B, + 0x08, 0x60, 0x01, 0x00, 0x2C, 0x60, 0xE0, 0xA5, 0x3F, 0x77, 0x06, 0x00, 0xC6, 0x27, 0x02, 0xF6, + 0xB9, 0x71, 0x04, 0x00, 0xC4, 0xC0, 0x06, 0x7C, 0x32, 0x02, 0x16, 0x7C, 0x38, 0x61, 0x0C, 0x00, + 0xC4, 0xC0, 0x26, 0x76, 0x22, 0x05, 0xC6, 0xA7, 0x22, 0x0B, 0xC4, 0xC0, 0x92, 0x0A, 0x08, 0x60, + 0x02, 0x00, 0x2C, 0x60, 0x00, 0xEE, 0x3F, 0x77, 0x06, 0x00, 0xC6, 0xA7, 0x02, 0x02, 0xB1, 0x71, + 0x06, 0x21, 0x0B, 0x3C, 0x04, 0x00, 0x30, 0x21, 0x0C, 0x30, 0x64, 0x00, 0x2C, 0x20, 0x32, 0x00, + 0x8B, 0x16, 0x00, 0x00, 0xA1, 0x2D, 0x38, 0x21, 0x04, 0x00, 0x0C, 0x30, 0x64, 0x00, 0x2C, 0x20, + 0x32, 0x00, 0x8B, 0x16, 0x00, 0x00, 0xA9, 0x2D, 0x02, 0x00, 0x58, 0xC1, 0x2C, 0x00, 0x58, 0x81, + 0x1C, 0x00, 0x2C, 0x10, 0x3C, 0x00, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0x38, 0x17, 0x04, 0x30, + 0x0C, 0x40, 0x3C, 0x00, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x74, 0x17, + 0x04, 0x30, 0x0C, 0x40, 0x3C, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, 0x0C, 0xE0, 0xFC, 0x0A, 0x98, 0x7E, 0xB0, 0x0C, + 0x82, 0x1A, 0x0C, 0x20, 0x78, 0x17, 0x04, 0x30, 0x0C, 0x40, 0x34, 0x00, 0x99, 0x0E, 0xB0, 0x0C, + 0xB9, 0x0E, 0x78, 0x0C, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x04, 0x71, 0x99, 0x7E, 0x74, 0x0C, + 0xB9, 0x0E, 0x3C, 0x0C, 0x0C, 0x20, 0x3C, 0x17, 0x04, 0x30, 0x0C, 0x40, 0x34, 0x00, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x2B, 0x83, 0x02, 0x00, 0x4B, 0xB6, 0x01, 0x00, 0x40, 0xE1, 0x24, 0x18, + 0xE1, 0xF0, 0x00, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0x18, 0x67, 0x8C, 0x06, 0x99, 0x67, 0x8D, 0x06, + 0x18, 0x67, 0xA1, 0x06, 0x99, 0x67, 0xA2, 0x06, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x28, 0x00, + 0xD9, 0xC1, 0x18, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, 0x18, 0xCD, 0xE5, 0x00, 0xD9, 0x81, 0x08, 0x00, + 0x04, 0xB0, 0x06, 0xEC, 0x06, 0x7C, 0x57, 0xE1, 0x57, 0x72, 0x26, 0xE7, 0x36, 0xEC, 0x26, 0xEE, + 0x2C, 0xE0, 0x98, 0x04, 0x08, 0x90, 0x00, 0xFF, 0x08, 0x80, 0xFF, 0xF0, 0x26, 0xED, 0x06, 0xAB, + 0x2C, 0x90, 0xFF, 0x0F, 0x2C, 0x80, 0xFF, 0xFF, 0x08, 0x50, 0xFF, 0x0F, 0x18, 0x7D, 0xE6, 0x00, + 0x2F, 0x6C, 0x0B, 0x00, 0xC6, 0x67, 0x32, 0x73, 0x18, 0x7D, 0x8C, 0x06, 0xC6, 0x7A, 0xC2, 0x6F, + 0x98, 0x7E, 0x1E, 0x00, 0x82, 0x68, 0x06, 0x2E, 0xB9, 0x51, 0x04, 0x00, 0xB1, 0x61, 0x0B, 0xED, + 0x01, 0x00, 0xC4, 0x20, 0x24, 0xA1, 0x13, 0xAA, 0x38, 0x51, 0x04, 0x00, 0x30, 0x61, 0x82, 0x5B, + 0x98, 0x7E, 0x21, 0x00, 0x82, 0x0B, 0x18, 0x7E, 0x24, 0x00, 0xC4, 0x74, 0xD2, 0x03, 0x99, 0x0E, + 0x21, 0x00, 0x04, 0x75, 0x99, 0x7E, 0x24, 0x00, 0xF2, 0x09, 0x18, 0x7E, 0x20, 0x00, 0xC4, 0x73, + 0xD2, 0x05, 0x18, 0x7E, 0x24, 0x00, 0xC4, 0x73, 0xC2, 0x46, 0x98, 0x7E, 0x21, 0x00, 0x92, 0x43, + 0x24, 0x61, 0x57, 0x61, 0x26, 0x6D, 0x20, 0x4E, 0x38, 0x76, 0x3C, 0x0C, 0x5C, 0x40, 0xFF, 0x0F, + 0x57, 0x46, 0x56, 0x79, 0x66, 0x74, 0xB9, 0x76, 0x3C, 0x0C, 0x28, 0x4E, 0x02, 0x00, 0x1C, 0x30, + 0x00, 0x10, 0x5C, 0x40, 0xFF, 0x0F, 0x56, 0x73, 0x66, 0x74, 0xB9, 0x76, 0x3C, 0x0C, 0x18, 0x4E, + 0x1F, 0x00, 0x56, 0x78, 0x54, 0x4F, 0x57, 0x4C, 0x66, 0x74, 0xB9, 0x76, 0x3C, 0x0C, 0x18, 0x3E, + 0x1E, 0x00, 0x0C, 0x40, 0xFF, 0xFF, 0x26, 0x45, 0x57, 0x3E, 0x56, 0x47, 0x66, 0x43, 0xB9, 0x46, + 0x3C, 0x0C, 0x18, 0x6E, 0x1E, 0x00, 0x04, 0x71, 0x34, 0x61, 0x53, 0x76, 0x38, 0x6D, 0x3C, 0x0C, + 0x1C, 0x40, 0x00, 0x04, 0x66, 0x76, 0x5C, 0x70, 0xFF, 0x03, 0x56, 0x64, 0x66, 0x67, 0x06, 0x76, + 0x77, 0x76, 0x24, 0x71, 0x54, 0x7F, 0x1C, 0x30, 0x01, 0xF0, 0x57, 0x76, 0x56, 0x63, 0x66, 0x67, + 0xB9, 0x6D, 0x3C, 0x0C, 0x24, 0xB1, 0x2C, 0xE0, 0x26, 0x00, 0xF2, 0x89, 0x58, 0xC1, 0x18, 0x00, + 0x58, 0x81, 0x08, 0x00, 0x2C, 0x10, 0x28, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, 0x38, 0x7D, 0x3C, 0x0C, 0xD1, 0x81, 0xDC, 0x70, + 0x00, 0xF0, 0x92, 0x3A, 0xF8, 0x6D, 0xB4, 0x0C, 0x12, 0x37, 0x0C, 0xE0, 0x90, 0x11, 0x04, 0x9C, + 0x08, 0xB0, 0xE0, 0xFF, 0x08, 0xA0, 0x1F, 0xFF, 0x26, 0x9E, 0x06, 0xC7, 0x04, 0x81, 0x2C, 0xB0, + 0xFF, 0xFF, 0x2C, 0xA0, 0xFF, 0xFF, 0x18, 0x7D, 0xA1, 0x06, 0xC6, 0x7C, 0xC2, 0x25, 0x90, 0x7E, + 0x82, 0x03, 0x24, 0xC1, 0x13, 0xCC, 0x06, 0x2E, 0x6B, 0xF3, 0x01, 0x00, 0xC4, 0x20, 0x82, 0x19, + 0x10, 0x7E, 0x06, 0x68, 0x34, 0x71, 0x53, 0x67, 0x06, 0x76, 0x38, 0x6D, 0x3C, 0x0C, 0x06, 0x56, + 0x77, 0x58, 0x66, 0x75, 0x5C, 0x70, 0x1F, 0x00, 0x57, 0x78, 0x56, 0x6B, 0x66, 0x67, 0x06, 0x76, + 0xF7, 0x7A, 0x24, 0x71, 0x54, 0x77, 0xD7, 0x7A, 0x56, 0x6A, 0x66, 0x67, 0xB9, 0x6D, 0x3C, 0x0C, + 0x24, 0xE3, 0xC6, 0xE9, 0x92, 0xD9, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0x50, 0xFC, 0x0A, 0x38, 0x45, + 0x3C, 0x0C, 0x06, 0x64, 0x77, 0x66, 0x54, 0x6F, 0xC4, 0x6A, 0x02, 0x30, 0x38, 0xF5, 0x78, 0x0C, + 0x14, 0x3A, 0x26, 0x36, 0x13, 0x33, 0x5C, 0xF0, 0xFF, 0x03, 0x5C, 0x40, 0xFF, 0x03, 0x0C, 0x20, + 0x6C, 0x17, 0x04, 0x7C, 0x04, 0xD1, 0x14, 0xC1, 0xC4, 0x30, 0x82, 0x16, 0x06, 0xEF, 0x63, 0xE7, + 0xD4, 0xE1, 0x92, 0x0E, 0x06, 0xE4, 0x63, 0xE7, 0xD4, 0xE1, 0x82, 0x0A, 0x06, 0xED, 0x53, 0xE7, + 0x15, 0xEE, 0x24, 0x6F, 0x34, 0x31, 0xB1, 0x02, 0x13, 0x33, 0x54, 0x6F, 0x56, 0x4E, 0x34, 0x71, + 0xC6, 0x7C, 0x34, 0x24, 0x92, 0xEA, 0x38, 0x75, 0x3C, 0x0C, 0x1C, 0x30, 0x00, 0xF4, 0x56, 0x73, + 0x57, 0x66, 0x66, 0x74, 0x66, 0x76, 0xB9, 0x75, 0x3C, 0x0C, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0xCE, + 0xB0, 0x0C, 0x0C, 0x20, 0x74, 0x17, 0x06, 0x3D, 0x0C, 0x30, 0x38, 0x17, 0x0C, 0x40, 0x3C, 0x00, + 0x0C, 0xF0, 0x28, 0x01, 0xF1, 0xF0, 0x06, 0x2D, 0x0C, 0x20, 0x38, 0x17, 0x04, 0x30, 0x0C, 0x40, + 0x3C, 0x00, 0x99, 0xCE, 0xB0, 0x0C, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0xEB, 0x5E, 0x04, 0x00, + 0xEB, 0x68, 0x04, 0x00, 0xAB, 0x6D, 0x04, 0x00, 0x38, 0x6E, 0x3C, 0x0C, 0x0C, 0x70, 0x00, 0xF0, + 0xD6, 0x76, 0x06, 0x7E, 0x82, 0x05, 0x77, 0x66, 0x54, 0x6F, 0x24, 0x61, 0xF2, 0x06, 0x08, 0x50, + 0xE0, 0x00, 0xD6, 0x56, 0x82, 0x05, 0x04, 0x61, 0x99, 0x67, 0x74, 0x0C, 0xF2, 0x03, 0x99, 0x0E, + 0x74, 0x0C, 0x98, 0x67, 0x74, 0x0C, 0x82, 0x05, 0x99, 0x67, 0xB0, 0x0C, 0x04, 0x21, 0xF2, 0x10, + 0x18, 0x67, 0xB0, 0x0C, 0x04, 0x21, 0xC4, 0x60, 0x82, 0x0B, 0x98, 0xE7, 0x8C, 0x06, 0x92, 0x08, + 0x99, 0x27, 0xB0, 0x0C, 0x6B, 0x0C, 0x02, 0x00, 0xAB, 0x5B, 0x04, 0x00, 0x06, 0x2E, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x18, 0x70, 0xA5, 0x1B, 0x34, 0x18, 0xC4, 0x70, + 0xC1, 0xE1, 0x04, 0x21, 0x92, 0x33, 0x0C, 0x60, 0xFC, 0x0A, 0x38, 0x76, 0x78, 0x0C, 0x38, 0x36, + 0x3C, 0x0C, 0x08, 0x40, 0xFF, 0x00, 0x0C, 0x50, 0xFF, 0xF3, 0x76, 0x73, 0x26, 0x54, 0xD6, 0x75, + 0x06, 0xF6, 0x92, 0x24, 0x77, 0x36, 0x54, 0x3F, 0x0C, 0x50, 0x3C, 0x17, 0x06, 0x67, 0x2C, 0x40, + 0xFF, 0xFF, 0xC6, 0x73, 0xB2, 0x16, 0x04, 0xE1, 0x26, 0xE6, 0x06, 0x6E, 0x57, 0x61, 0x26, 0x6F, + 0x38, 0x26, 0x3C, 0x0C, 0x77, 0x2E, 0xC4, 0x20, 0x82, 0x08, 0x38, 0x65, 0x3C, 0x00, 0x30, 0x25, + 0x76, 0x62, 0xD6, 0x64, 0x92, 0x0A, 0x24, 0x71, 0xC4, 0xED, 0x06, 0x6E, 0x24, 0x54, 0x92, 0xEA, + 0x99, 0x0F, 0x74, 0x0C, 0x04, 0x20, 0xF2, 0x02, 0x04, 0x21, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0x34, 0x14, 0x0C, 0x20, 0xDB, 0x0B, 0x04, 0x30, 0x04, 0x48, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, 0x0C, 0x60, 0x18, 0x00, + 0x99, 0x67, 0xE3, 0x00, 0x04, 0x6E, 0x34, 0x14, 0x99, 0x67, 0xE4, 0x00, 0x04, 0x6D, 0xB1, 0xF1, + 0x99, 0x07, 0xE0, 0x00, 0x99, 0x07, 0xE1, 0x00, 0x99, 0x07, 0xE2, 0x00, 0x99, 0x07, 0xE5, 0x00, + 0x99, 0x67, 0xE6, 0x00, 0x2B, 0x36, 0x03, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x04, 0x70, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xC7, 0x06, 0xF7, 0x06, 0xD7, 0x13, 0xE7, + 0xC6, 0xE4, 0xB2, 0x1B, 0x06, 0x65, 0x73, 0x67, 0x54, 0x61, 0x26, 0xD6, 0x13, 0xDD, 0xC4, 0xD2, + 0xD2, 0x16, 0xC4, 0xF0, 0x92, 0x05, 0xC4, 0x61, 0x92, 0x0E, 0x91, 0xE2, 0xF2, 0x0B, 0xC4, 0xC0, + 0x92, 0x07, 0xC4, 0x60, 0x04, 0xF1, 0x92, 0x07, 0x91, 0xE3, 0x06, 0xCF, 0xF2, 0x04, 0xC4, 0x61, + 0x82, 0x06, 0x04, 0xF1, 0x24, 0x71, 0xF2, 0xE4, 0x04, 0x21, 0xF2, 0x02, 0x04, 0x20, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0xE0, + 0xFC, 0x0A, 0x98, 0x7E, 0xDF, 0x00, 0x92, 0x03, 0x4B, 0x7B, 0x04, 0x00, 0x18, 0x7E, 0x8D, 0x06, + 0xC4, 0x71, 0xC2, 0x03, 0x04, 0x20, 0xF2, 0x3B, 0xB8, 0x5E, 0xFC, 0x02, 0x82, 0xFC, 0xB8, 0x7E, + 0x00, 0x03, 0x82, 0xF9, 0x38, 0x7E, 0x0C, 0x00, 0xD4, 0x76, 0x92, 0xF5, 0x78, 0x4E, 0x20, 0x03, + 0x0C, 0x30, 0x74, 0x1A, 0x0C, 0x20, 0x80, 0x02, 0x0C, 0xF0, 0x54, 0x05, 0x2F, 0x63, 0x07, 0x00, + 0x20, 0x66, 0x26, 0x66, 0x2F, 0xD6, 0x02, 0x00, 0x26, 0x6F, 0x70, 0xDD, 0x70, 0x66, 0x3F, 0x66, + 0x0D, 0x00, 0xC6, 0x64, 0x12, 0xE0, 0x24, 0x72, 0xC4, 0x76, 0x92, 0xF1, 0x04, 0x71, 0x99, 0x7E, + 0xE0, 0x00, 0x0C, 0x20, 0xDD, 0x0B, 0x0C, 0x30, 0xDF, 0x0B, 0x0C, 0x40, 0x18, 0x00, 0x0B, 0x7D, + 0x04, 0x00, 0xC4, 0x20, 0x82, 0xD0, 0x38, 0x5E, 0x00, 0x03, 0x0C, 0x20, 0xDE, 0x0B, 0x0C, 0x30, + 0xE0, 0x0B, 0x04, 0x4E, 0x0B, 0x7D, 0x04, 0x00, 0x16, 0x22, 0xF7, 0x2F, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x2F, 0x73, 0x03, 0x00, 0x26, 0x37, 0x3C, 0x10, 0x10, 0x00, 0xD7, 0x31, + 0xD1, 0xC1, 0x2F, 0xF3, 0x02, 0x00, 0x08, 0xE0, 0x00, 0x30, 0x04, 0x20, 0x06, 0x62, 0x2C, 0xE0, + 0x00, 0x49, 0xC6, 0x65, 0xB2, 0x15, 0x06, 0x7F, 0x57, 0x71, 0x26, 0x7E, 0x30, 0xD7, 0x30, 0x77, + 0x5C, 0xD0, 0xFF, 0x0F, 0x77, 0x78, 0x5C, 0x70, 0xFF, 0x0F, 0x3F, 0x77, 0x0D, 0x00, 0xC4, 0x70, + 0x02, 0x02, 0x26, 0x27, 0x24, 0x61, 0x26, 0xF4, 0x23, 0x66, 0x23, 0xFF, 0xF2, 0xEB, 0x06, 0x35, + 0xAB, 0x15, 0x00, 0x00, 0x50, 0xC1, 0x23, 0x22, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x84, 0x00, 0xD9, 0xC1, 0x74, 0x00, 0xD9, 0x81, 0x64, 0x00, 0x0C, 0xE0, 0xFC, 0x0A, + 0x28, 0xBE, 0x06, 0x03, 0xA9, 0x0E, 0x18, 0x03, 0xCB, 0x3D, 0x00, 0x00, 0x23, 0xD2, 0xC6, 0xDB, + 0x04, 0xC0, 0x06, 0x8E, 0xCA, 0x3C, 0x01, 0x00, 0x0C, 0x20, 0x14, 0x00, 0x26, 0x21, 0x06, 0x3C, + 0x04, 0x45, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x04, 0x45, 0x06, 0x3C, 0x06, 0x21, 0x0C, 0xF0, + 0xD8, 0x01, 0xF1, 0xF0, 0xA9, 0xDE, 0x18, 0x03, 0x4B, 0x3E, 0x00, 0x00, 0x23, 0xD2, 0xA9, 0xDE, + 0x5C, 0x01, 0x06, 0x2D, 0x0C, 0x30, 0x18, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x13, 0xE2, 0x99, 0xE8, + 0x5F, 0x01, 0x06, 0x2D, 0x0C, 0x30, 0x18, 0x00, 0x4B, 0x18, 0x00, 0x00, 0x13, 0x22, 0x14, 0x62, + 0x26, 0x62, 0x33, 0x66, 0xB9, 0x61, 0x40, 0x00, 0x14, 0x62, 0x26, 0x6E, 0x99, 0x28, 0x5E, 0x01, + 0x24, 0xE2, 0x24, 0x22, 0x33, 0x66, 0x33, 0x7E, 0x33, 0x22, 0x08, 0xE0, 0x00, 0x30, 0xB9, 0x21, + 0x54, 0x00, 0xB9, 0x61, 0x44, 0x00, 0xB9, 0x71, 0x58, 0x00, 0x06, 0xA6, 0x06, 0xDC, 0x2C, 0xE0, + 0x00, 0x49, 0x38, 0x71, 0x58, 0x00, 0xC6, 0xA7, 0x1A, 0xAE, 0x00, 0x00, 0x13, 0x7A, 0xC4, 0x7D, + 0xB9, 0x71, 0x48, 0x00, 0xDA, 0xA2, 0x00, 0x00, 0x38, 0x71, 0x44, 0x00, 0x38, 0x31, 0x48, 0x00, + 0x06, 0xBA, 0x04, 0x20, 0x04, 0x41, 0x0C, 0x50, 0x17, 0x00, 0x36, 0xB7, 0xAB, 0x84, 0x04, 0x00, + 0x2F, 0x6B, 0x0B, 0x00, 0x26, 0x61, 0xA9, 0x26, 0x28, 0x00, 0x2F, 0x6A, 0x0A, 0x00, 0x26, 0xA6, + 0x06, 0x7B, 0xD7, 0xA1, 0x57, 0x71, 0x38, 0x61, 0x40, 0x00, 0xB9, 0x21, 0x4C, 0x00, 0x23, 0xAA, + 0x26, 0x71, 0xB9, 0xA1, 0x5C, 0x00, 0xB9, 0x71, 0x50, 0x00, 0x38, 0x71, 0x54, 0x00, 0xC6, 0x67, + 0x12, 0x77, 0x13, 0xA6, 0xCC, 0xA0, 0x16, 0x00, 0xD2, 0x70, 0x38, 0x71, 0x40, 0x00, 0xC4, 0xC0, + 0x06, 0x96, 0x36, 0x97, 0x92, 0x11, 0x04, 0x5E, 0x06, 0x2A, 0x06, 0x3C, 0x0C, 0x40, 0x18, 0x00, + 0xB9, 0x61, 0x60, 0x00, 0xAB, 0x84, 0x04, 0x00, 0x2F, 0x59, 0x09, 0x00, 0x38, 0x61, 0x60, 0x00, + 0x26, 0x51, 0xA9, 0x25, 0x34, 0x00, 0x38, 0x71, 0x5C, 0x00, 0x28, 0x28, 0x14, 0x00, 0x26, 0x67, + 0x23, 0x36, 0x06, 0x43, 0x57, 0x41, 0x2F, 0x5E, 0x04, 0x00, 0x30, 0x65, 0x30, 0x55, 0x38, 0x71, + 0x4C, 0x00, 0x77, 0x58, 0x5C, 0x50, 0xFF, 0x0F, 0x5C, 0x60, 0xFF, 0x0F, 0x36, 0x65, 0x18, 0x58, + 0x5F, 0x01, 0x36, 0x67, 0xC4, 0x5A, 0x36, 0x62, 0x92, 0x0B, 0x18, 0x58, 0x5E, 0x01, 0x3C, 0x50, + 0x10, 0x00, 0x13, 0x55, 0xC4, 0x51, 0xD2, 0x2B, 0xCC, 0x30, 0x02, 0x01, 0xF2, 0x0C, 0xC4, 0x53, + 0x92, 0x26, 0x18, 0x58, 0x5E, 0x01, 0x3C, 0x50, 0x10, 0x00, 0x13, 0x55, 0xC4, 0x51, 0xD2, 0x1F, + 0xCC, 0x30, 0x5A, 0x00, 0x92, 0x1C, 0x34, 0x44, 0x26, 0x4E, 0x30, 0x34, 0x30, 0x54, 0x5C, 0x30, + 0xFF, 0x0F, 0x77, 0x58, 0x5C, 0x50, 0xFF, 0x0F, 0xC6, 0x35, 0xC2, 0x11, 0x30, 0x24, 0x30, 0x54, + 0xB9, 0x61, 0x60, 0x00, 0x5C, 0x20, 0xFF, 0x0F, 0x77, 0x58, 0x5C, 0x50, 0xFF, 0x0F, 0x36, 0x25, + 0x04, 0x36, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x61, 0x60, 0x00, 0x26, 0x62, 0xC4, 0x60, 0x22, 0x0D, + 0x57, 0x91, 0x26, 0x91, 0x38, 0x59, 0x14, 0x00, 0x38, 0x71, 0x50, 0x00, 0x26, 0x56, 0xB9, 0x59, + 0x14, 0x00, 0x30, 0x57, 0x26, 0x65, 0xB1, 0x67, 0x24, 0xA1, 0x33, 0x6A, 0xF2, 0x87, 0x57, 0xB1, + 0x26, 0xB1, 0x30, 0x6B, 0x04, 0xC1, 0x26, 0xD6, 0x38, 0xA1, 0x48, 0x00, 0x24, 0xA1, 0x33, 0xAA, + 0xFA, 0x51, 0xFF, 0xFF, 0x28, 0x58, 0x5C, 0x01, 0x28, 0x41, 0x38, 0x00, 0x08, 0x60, 0x00, 0x30, + 0x57, 0x51, 0x2C, 0x60, 0x00, 0x49, 0x26, 0x65, 0x30, 0x56, 0x30, 0x66, 0x5C, 0x50, 0xFF, 0x0F, + 0x77, 0x68, 0x5C, 0x60, 0xFF, 0x0F, 0x3F, 0x66, 0x05, 0x00, 0x36, 0x64, 0x28, 0x41, 0x2C, 0x00, + 0x38, 0x51, 0x40, 0x00, 0x36, 0x64, 0x28, 0x48, 0x14, 0x00, 0x24, 0x56, 0x36, 0x64, 0x23, 0x66, + 0x57, 0x51, 0x0C, 0x40, 0x14, 0x00, 0xA9, 0x68, 0x14, 0x03, 0xA9, 0x68, 0x16, 0x03, 0x06, 0x2E, + 0x0C, 0x20, 0x58, 0x0C, 0x04, 0x30, 0x26, 0x41, 0x26, 0x58, 0x06, 0x6D, 0x8B, 0x3D, 0x03, 0x00, + 0x38, 0x51, 0x44, 0x00, 0x06, 0x6D, 0x2C, 0x50, 0x1E, 0x00, 0x57, 0x51, 0x06, 0x2E, 0x0C, 0x20, + 0x58, 0x0C, 0x04, 0x31, 0x06, 0x41, 0x26, 0x58, 0x8B, 0x3D, 0x03, 0x00, 0x18, 0x68, 0x25, 0x03, + 0x04, 0xC1, 0xA9, 0x68, 0x78, 0x01, 0xA9, 0x68, 0x12, 0x00, 0x04, 0x61, 0x99, 0x68, 0x1D, 0x03, + 0x99, 0x68, 0x1E, 0x03, 0x99, 0x68, 0x1F, 0x03, 0x99, 0x68, 0x1C, 0x03, 0xAB, 0x4E, 0x03, 0x00, + 0x06, 0x2C, 0x58, 0xC1, 0x74, 0x00, 0x58, 0x81, 0x64, 0x00, 0x2C, 0x10, 0x84, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x18, 0x00, 0xD9, 0xC1, 0x08, 0x00, 0xC1, 0xA1, 0x0C, 0xE0, 0xFC, 0x0A, 0x38, 0x2E, + 0x88, 0x06, 0x04, 0x70, 0xC6, 0x27, 0x82, 0x4F, 0x0C, 0xF0, 0x80, 0x00, 0xF1, 0xF0, 0x04, 0x61, + 0x06, 0x42, 0x06, 0x52, 0x26, 0x62, 0x57, 0x41, 0x57, 0x52, 0x99, 0x6E, 0xE6, 0x00, 0x2F, 0x65, + 0x04, 0x00, 0x36, 0x62, 0x26, 0x66, 0x26, 0x6E, 0x78, 0xDE, 0x70, 0x01, 0x78, 0x66, 0xA8, 0x04, + 0x99, 0x2E, 0xE5, 0x00, 0x06, 0x72, 0x36, 0xD6, 0xC4, 0xD0, 0x32, 0x02, 0x16, 0xDD, 0x2F, 0x35, + 0x04, 0x00, 0x36, 0x37, 0x26, 0x33, 0x26, 0x3E, 0x78, 0x2E, 0x72, 0x01, 0x78, 0x63, 0xAA, 0x04, + 0x36, 0x26, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x26, 0x54, 0x3F, 0x77, 0x05, 0x00, 0x26, 0x77, + 0x2F, 0xC7, 0x0E, 0x00, 0x06, 0x32, 0x4B, 0x14, 0x00, 0x00, 0x28, 0xBC, 0xB4, 0x04, 0x06, 0x3D, + 0x06, 0xA2, 0x06, 0x2D, 0x4B, 0x14, 0x00, 0x00, 0x2F, 0xD2, 0x0A, 0x00, 0x06, 0x3B, 0x06, 0x2B, + 0x4B, 0x14, 0x00, 0x00, 0xC6, 0xD2, 0xB2, 0x0D, 0x04, 0xD1, 0x0C, 0x20, 0x98, 0x04, 0x99, 0xDE, + 0xDF, 0x00, 0x26, 0x2C, 0x0C, 0x30, 0x58, 0x0C, 0xEB, 0x4A, 0x02, 0x00, 0x99, 0xDE, 0x8C, 0x06, + 0x18, 0x7E, 0xDF, 0x00, 0x58, 0xC1, 0x08, 0x00, 0x40, 0xA1, 0x06, 0x27, 0x2C, 0x10, 0x18, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x0C, 0x70, 0xFC, 0x0A, 0x99, 0x07, 0xDF, 0x00, + 0x98, 0x77, 0xE0, 0x00, 0x82, 0x07, 0x8B, 0x87, 0x04, 0x00, 0xC4, 0x20, 0x82, 0x03, 0x0B, 0x9D, + 0x04, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0xD0, 0x00, 0x08, 0x30, 0x00, 0x80, 0xD9, 0xC1, 0xC0, 0x00, 0x0C, 0x40, 0xBE, 0x00, + 0x2C, 0x30, 0xEC, 0x9C, 0x06, 0xD2, 0x06, 0x21, 0xEB, 0xE4, 0x04, 0x00, 0x0C, 0x20, 0x40, 0x00, + 0x2B, 0x60, 0x00, 0x00, 0x04, 0x28, 0x04, 0x30, 0xEB, 0x6B, 0x00, 0x00, 0x04, 0x30, 0x04, 0x48, + 0x0C, 0x20, 0x1E, 0x00, 0x4B, 0xAD, 0x01, 0x00, 0xEB, 0xAD, 0x01, 0x00, 0x0C, 0x20, 0x60, 0xEA, + 0x0B, 0xAF, 0x01, 0x00, 0xCB, 0x31, 0x00, 0x00, 0x08, 0x70, 0x0A, 0x13, 0x08, 0xE0, 0x00, 0x40, + 0x2C, 0x70, 0x0A, 0x13, 0xB9, 0x7E, 0x0C, 0x70, 0x0C, 0x70, 0x0A, 0x13, 0xB9, 0x7E, 0x88, 0x70, + 0xB9, 0x7E, 0x30, 0x71, 0x08, 0x70, 0x12, 0x00, 0x2C, 0x70, 0x08, 0x08, 0xB9, 0x7E, 0x34, 0x70, + 0x0C, 0x70, 0x88, 0x08, 0xB9, 0x7E, 0x3C, 0x70, 0x04, 0x71, 0xB9, 0x7E, 0x64, 0x70, 0x0C, 0x70, + 0xFF, 0x3F, 0xB9, 0x7E, 0x58, 0x70, 0x04, 0x20, 0xEB, 0x5A, 0x00, 0x00, 0x08, 0x70, 0x1B, 0x1A, + 0x2C, 0x70, 0x1D, 0x1C, 0xB9, 0x7E, 0x80, 0x71, 0x08, 0x70, 0x17, 0x16, 0x2C, 0x70, 0x19, 0x18, + 0xB9, 0x7E, 0x84, 0x71, 0x0C, 0x70, 0x13, 0x12, 0xB9, 0x7E, 0x88, 0x71, 0xB9, 0x0E, 0x8C, 0x71, + 0xB9, 0x0E, 0x90, 0x71, 0xB9, 0x0E, 0x94, 0x71, 0xB9, 0x0E, 0x98, 0x71, 0xB9, 0x0E, 0x9C, 0x71, + 0x08, 0x70, 0x12, 0x11, 0xB9, 0x7E, 0xA8, 0x71, 0x08, 0x70, 0x0E, 0x00, 0x2C, 0x70, 0x10, 0x0F, + 0xB9, 0x7E, 0xAC, 0x71, 0x08, 0x70, 0x0D, 0x0C, 0xB9, 0x7E, 0xB0, 0x71, 0x08, 0x70, 0x09, 0x00, + 0x2C, 0x70, 0x0B, 0x0A, 0xB9, 0x7E, 0xB4, 0x71, 0x08, 0x70, 0x01, 0x02, 0xB9, 0x7E, 0xB8, 0x71, + 0x08, 0x70, 0x00, 0x03, 0xB9, 0x7E, 0xBC, 0x71, 0x08, 0x70, 0x06, 0x07, 0x2C, 0x70, 0x04, 0x05, + 0xB9, 0x7E, 0xC0, 0x71, 0x04, 0x78, 0xB9, 0x7E, 0xC4, 0x71, 0x08, 0x70, 0x8E, 0x9F, 0x2C, 0x70, + 0x7C, 0x7C, 0xB9, 0x7E, 0x78, 0x71, 0x0C, 0x60, 0x00, 0x40, 0x08, 0x70, 0x00, 0x30, 0x08, 0x30, + 0x0F, 0x00, 0x0C, 0x20, 0xF8, 0x42, 0x06, 0xE1, 0x26, 0x67, 0x2C, 0x30, 0xFF, 0xFF, 0x26, 0x27, + 0x10, 0x5E, 0x30, 0x46, 0x57, 0x5C, 0x56, 0x43, 0x66, 0x54, 0xB1, 0x56, 0x24, 0x64, 0xC6, 0x62, + 0x24, 0xE1, 0x92, 0xF7, 0x08, 0x60, 0xF0, 0x3F, 0x0C, 0x50, 0x00, 0x90, 0x26, 0x56, 0xB9, 0x57, + 0xC4, 0x52, 0x0C, 0x50, 0x21, 0xB0, 0x26, 0x56, 0xB9, 0x57, 0xC8, 0x52, 0x0C, 0x50, 0x42, 0xB0, + 0x26, 0x56, 0xB9, 0x57, 0xCC, 0x52, 0x0C, 0x50, 0x63, 0xB0, 0x26, 0x56, 0xB9, 0x57, 0xD0, 0x52, + 0x0C, 0x50, 0x84, 0xB0, 0x26, 0x56, 0xB9, 0x57, 0xD4, 0x52, 0x0C, 0x50, 0xA5, 0xB0, 0x26, 0x56, + 0xB9, 0x57, 0xD8, 0x52, 0x0C, 0x50, 0xC6, 0xB0, 0x26, 0x56, 0xB9, 0x57, 0xDC, 0x52, 0x0C, 0x50, + 0xE7, 0xB0, 0x26, 0x56, 0xB9, 0x57, 0xE0, 0x52, 0x0C, 0x50, 0x08, 0xB1, 0x26, 0x56, 0xB9, 0x57, + 0xE4, 0x52, 0x0C, 0x50, 0x29, 0xA1, 0x26, 0x56, 0xB9, 0x57, 0xE8, 0x52, 0x2C, 0x60, 0x00, 0x80, + 0xB9, 0x67, 0xEC, 0x52, 0xB9, 0x67, 0xF0, 0x52, 0xB9, 0x67, 0xF4, 0x52, 0xB9, 0x67, 0xF8, 0x52, + 0xB9, 0x67, 0xFC, 0x52, 0x08, 0x60, 0xF1, 0x3F, 0x2C, 0x60, 0x00, 0xC0, 0xB9, 0x67, 0x00, 0x53, + 0xB9, 0x67, 0x04, 0x53, 0xB9, 0x67, 0x08, 0x53, 0xB9, 0x67, 0x0C, 0x53, 0xB9, 0x67, 0x10, 0x53, + 0xB9, 0x67, 0x14, 0x53, 0xB9, 0x67, 0x18, 0x53, 0xB9, 0x67, 0x1C, 0x53, 0xB9, 0x67, 0x20, 0x53, + 0xB9, 0x67, 0x24, 0x53, 0xB9, 0x67, 0x28, 0x53, 0xB9, 0x67, 0x2C, 0x53, 0xB9, 0x67, 0x30, 0x53, + 0xB9, 0x67, 0x34, 0x53, 0xB9, 0x67, 0x38, 0x53, 0x08, 0x70, 0x00, 0x40, 0x0C, 0x60, 0x70, 0x01, + 0xB9, 0x67, 0x28, 0x71, 0x08, 0x60, 0x01, 0x00, 0x2C, 0x60, 0x40, 0x62, 0xB9, 0x67, 0xAC, 0x70, + 0x08, 0x60, 0x08, 0x00, 0xB9, 0x67, 0xB4, 0x70, 0x08, 0x60, 0x88, 0x00, 0x2C, 0x60, 0x00, 0x10, + 0xB9, 0x07, 0xB8, 0x70, 0xB9, 0x67, 0xC0, 0x70, 0x08, 0x60, 0x10, 0x1F, 0x2C, 0x60, 0x10, 0x1F, + 0xB9, 0x67, 0xC4, 0x70, 0x0C, 0x60, 0x80, 0x00, 0xB9, 0x67, 0xC8, 0x70, 0x08, 0x60, 0x02, 0x01, + 0xB9, 0x67, 0xCC, 0x70, 0x04, 0x61, 0xB9, 0x67, 0xD4, 0x70, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, + 0x00, 0xA0, 0xB9, 0x67, 0x8C, 0x70, 0x0C, 0x60, 0x14, 0xA0, 0xB9, 0x67, 0x90, 0x70, 0xB9, 0x07, + 0x94, 0x70, 0xB9, 0x07, 0x98, 0x70, 0x0C, 0x50, 0x00, 0xA0, 0xB9, 0x57, 0x9C, 0x70, 0xB9, 0x67, + 0xA0, 0x70, 0xB9, 0x07, 0xA4, 0x70, 0x08, 0x60, 0x80, 0x0F, 0xB9, 0x07, 0xA8, 0x70, 0x2C, 0x60, + 0x80, 0x0F, 0xB9, 0x67, 0x6C, 0x70, 0xEB, 0x2F, 0x00, 0x00, 0xEB, 0xAF, 0x01, 0x00, 0x04, 0xEA, + 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x0C, 0x20, + 0xD0, 0x07, 0x6B, 0xEB, 0x00, 0x00, 0x34, 0xE1, 0xA3, 0xEE, 0x92, 0xF3, 0x0B, 0x94, 0x00, 0x00, + 0xEB, 0xAF, 0x01, 0x00, 0x0B, 0x31, 0x00, 0x00, 0x6B, 0x32, 0x00, 0x00, 0x38, 0x7D, 0x18, 0x00, + 0x06, 0x2D, 0x04, 0x32, 0xF1, 0x70, 0x06, 0x2E, 0x58, 0xC1, 0xC0, 0x00, 0x2C, 0x10, 0xD0, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0x08, 0xE0, 0x70, 0x41, + 0xB1, 0xB1, 0x06, 0xD2, 0x08, 0xC0, 0x00, 0x30, 0x2C, 0xE0, 0x22, 0xCF, 0xCB, 0xB9, 0x00, 0x00, + 0xB9, 0xEC, 0x04, 0x01, 0xCB, 0xBA, 0x00, 0x00, 0x86, 0xB2, 0x82, 0x04, 0x2B, 0xBB, 0x00, 0x00, + 0xF2, 0xF6, 0x4B, 0xBA, 0x00, 0x00, 0xEB, 0x6A, 0x00, 0x00, 0x38, 0x7D, 0x18, 0x00, 0x06, 0x2D, + 0x04, 0x35, 0xF1, 0x70, 0x58, 0xC1, 0x04, 0x00, 0x06, 0x2B, 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x06, 0xD3, 0xCB, 0x31, + 0x00, 0x00, 0xC4, 0xD2, 0x82, 0x0C, 0xC4, 0xD3, 0x82, 0x15, 0xC4, 0xD1, 0x92, 0x22, 0x0C, 0x20, + 0x11, 0x00, 0x8B, 0x34, 0x00, 0x00, 0xAB, 0x3C, 0x00, 0x00, 0xF2, 0x1B, 0x0C, 0x20, 0x11, 0x00, + 0x8B, 0x34, 0x00, 0x00, 0xAB, 0x3C, 0x00, 0x00, 0x99, 0x0E, 0x24, 0x00, 0x99, 0x0E, 0x1C, 0x00, + 0xF2, 0x10, 0x0C, 0x20, 0x1D, 0x00, 0x8B, 0x34, 0x00, 0x00, 0x2B, 0x3D, 0x00, 0x00, 0x04, 0x71, + 0x99, 0x7E, 0x1C, 0x00, 0x99, 0x7E, 0x24, 0x00, 0x6B, 0xAF, 0x01, 0x00, 0xB9, 0x2E, 0x20, 0x00, + 0x6B, 0x32, 0x00, 0x00, 0x91, 0xDE, 0x50, 0xC1, 0x04, 0x20, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0x34, 0x18, 0xC1, 0xE1, 0x18, 0x72, 0x25, 0x00, 0x04, 0x61, 0xC4, 0x79, 0x26, 0x67, 0x99, 0x62, + 0x25, 0x00, 0x06, 0xE2, 0xD2, 0x0B, 0x0C, 0x20, 0xF4, 0x01, 0xAB, 0xED, 0x00, 0x00, 0x38, 0x7E, + 0x18, 0x00, 0x06, 0x2E, 0x04, 0x32, 0xF1, 0x70, 0xF2, 0x09, 0x6B, 0xAE, 0x01, 0x00, 0x0C, 0x20, + 0x40, 0x00, 0x0B, 0x61, 0x00, 0x00, 0x99, 0x00, 0x9F, 0x1B, 0x40, 0xE1, 0x04, 0x20, 0x24, 0x18, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x4B, 0x3E, 0x00, 0x00, + 0x0C, 0x30, 0x13, 0x00, 0x06, 0xD2, 0xAB, 0x15, 0x00, 0x00, 0x99, 0x2E, 0x01, 0x00, 0x0C, 0x30, + 0x13, 0x00, 0x06, 0x2D, 0x4B, 0x18, 0x00, 0x00, 0x91, 0x2E, 0x50, 0xC1, 0x04, 0x21, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE2, 0xCB, 0x31, 0x00, 0x00, 0xEB, 0x2F, + 0x00, 0x00, 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, + 0x0B, 0x31, 0x00, 0x00, 0xCB, 0x3E, 0x00, 0x00, 0x38, 0x70, 0x08, 0x0B, 0x0C, 0x60, 0x46, 0x00, + 0xD4, 0x71, 0x82, 0x03, 0x0C, 0x60, 0x64, 0x00, 0xC6, 0x26, 0xB2, 0x06, 0x6B, 0x32, 0x00, 0x00, + 0x0C, 0x20, 0x40, 0x9C, 0xF2, 0x19, 0x04, 0x2C, 0x8B, 0x34, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x40, + 0x04, 0x24, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x0C, 0x20, 0x1D, 0x00, 0x26, 0x2E, + 0xAB, 0xC3, 0x04, 0x00, 0x6B, 0x32, 0x00, 0x00, 0x38, 0x7E, 0x18, 0x00, 0x06, 0x2E, 0x04, 0x33, + 0xF1, 0x70, 0x0C, 0x20, 0x20, 0x4E, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x24, 0x00, + 0xD9, 0xC1, 0x14, 0x00, 0x06, 0xE2, 0xD9, 0x81, 0x04, 0x00, 0xCB, 0x3D, 0x00, 0x00, 0x06, 0xB2, + 0x6B, 0xAF, 0x01, 0x00, 0x18, 0xDE, 0x1C, 0x00, 0x14, 0x73, 0x26, 0x7D, 0xC4, 0x71, 0x06, 0xC2, + 0xD2, 0x18, 0xCC, 0xB0, 0x50, 0x00, 0xC2, 0x06, 0x6B, 0xAF, 0x01, 0x00, 0xB9, 0x2E, 0x20, 0x00, + 0xF2, 0x0D, 0x38, 0x7E, 0x20, 0x00, 0x3F, 0xC2, 0x07, 0x00, 0xC4, 0xC0, 0x32, 0x02, 0x16, 0xCC, + 0xCC, 0xC0, 0xF4, 0x01, 0x04, 0x75, 0x1A, 0x8E, 0x00, 0x00, 0x06, 0x7D, 0xFA, 0x8B, 0x00, 0x00, + 0xCC, 0xB0, 0x50, 0x00, 0x04, 0x72, 0xC2, 0x7B, 0x06, 0x21, 0xAB, 0xC3, 0x04, 0x00, 0x18, 0x6E, + 0x1D, 0x00, 0x10, 0x71, 0x3F, 0x77, 0x06, 0x00, 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, 0xC4, 0x71, + 0x02, 0x03, 0x04, 0x73, 0xF2, 0x6C, 0x18, 0x6E, 0x1E, 0x00, 0x18, 0x71, 0x01, 0x00, 0x3F, 0x77, + 0x06, 0x00, 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, 0xC4, 0x71, 0x12, 0xF4, 0x04, 0x60, 0x08, 0xF0, + 0x00, 0x30, 0x06, 0xB6, 0x06, 0x56, 0x06, 0xD6, 0x04, 0x21, 0x2C, 0xF0, 0xFC, 0x9F, 0x06, 0xA2, + 0x53, 0xAD, 0x06, 0x76, 0x04, 0x40, 0x08, 0x30, 0x00, 0x30, 0x2C, 0x30, 0x00, 0xA0, 0x26, 0x37, + 0x30, 0x93, 0xCC, 0x90, 0x50, 0x00, 0xC2, 0x2F, 0xC4, 0x40, 0x82, 0x0A, 0x2F, 0x9F, 0x07, 0x00, + 0x30, 0x89, 0x30, 0x93, 0xC6, 0x89, 0xD2, 0x27, 0xCC, 0x40, 0x12, 0x00, 0x82, 0x0A, 0x08, 0x90, + 0x00, 0x30, 0x2C, 0x90, 0x04, 0xA0, 0x26, 0x97, 0x30, 0x89, 0x30, 0x93, 0xC6, 0x89, 0xB2, 0x1B, + 0xC4, 0xD0, 0x82, 0x0C, 0x08, 0x90, 0x00, 0x30, 0x2C, 0x90, 0xB4, 0x9F, 0x26, 0x97, 0x30, 0x89, + 0x30, 0x93, 0xC6, 0x89, 0xD2, 0x10, 0xC4, 0xD9, 0x82, 0x0A, 0x08, 0x90, 0x00, 0x30, 0x2C, 0x90, + 0x4C, 0xA0, 0x26, 0x97, 0x30, 0x99, 0x30, 0x33, 0xC6, 0x93, 0xB2, 0x05, 0x06, 0x32, 0x53, 0x34, + 0x66, 0x53, 0x66, 0xBA, 0x24, 0x41, 0xCC, 0x40, 0x13, 0x00, 0x24, 0x74, 0x92, 0xC5, 0x24, 0xD1, + 0xC4, 0xDA, 0x2C, 0x60, 0x4C, 0x00, 0x92, 0xBC, 0x04, 0x31, 0x06, 0x21, 0x26, 0x31, 0x0B, 0x7D, + 0x04, 0x00, 0xC4, 0x20, 0x82, 0x9F, 0x04, 0x31, 0x06, 0x21, 0x26, 0x31, 0x06, 0x4D, 0x06, 0x5B, + 0x0B, 0x7D, 0x04, 0x00, 0xC4, 0x20, 0x04, 0x73, 0x82, 0x02, 0x04, 0x71, 0x38, 0x6E, 0x20, 0x00, + 0x3F, 0xCC, 0x06, 0x00, 0xC4, 0xC0, 0x32, 0x02, 0x16, 0xCC, 0xCC, 0xC0, 0xE8, 0x03, 0x02, 0x02, + 0x04, 0x74, 0x18, 0x6E, 0x1C, 0x00, 0xC6, 0x67, 0x92, 0x02, 0x04, 0x70, 0x58, 0xC1, 0x14, 0x00, + 0x58, 0x81, 0x04, 0x00, 0x06, 0x27, 0x2C, 0x10, 0x24, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x06, 0xE2, 0xCB, 0x31, 0x00, 0x00, 0xEB, 0x2F, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x40, + 0x04, 0x21, 0x4B, 0x3A, 0x00, 0x00, 0x8B, 0x37, 0x00, 0x00, 0x0B, 0x31, 0x00, 0x00, 0x06, 0x2E, + 0xEB, 0xC8, 0x04, 0x00, 0x06, 0xD2, 0x6B, 0x32, 0x00, 0x00, 0x06, 0x7D, 0x6B, 0xE6, 0x04, 0x00, + 0x01, 0x00, 0x05, 0x00, 0x4C, 0x00, 0x10, 0x00, 0x10, 0x00, 0x34, 0x00, 0x34, 0x00, 0x42, 0x00, + 0x6B, 0xAF, 0x01, 0x00, 0x18, 0x3E, 0x24, 0x00, 0xB9, 0x2E, 0x20, 0x00, 0x99, 0xDE, 0x1C, 0x00, + 0x24, 0x31, 0x13, 0x33, 0xC4, 0x34, 0x99, 0x3E, 0x24, 0x00, 0x92, 0x11, 0x38, 0x7E, 0x18, 0x00, + 0x06, 0x2E, 0xF2, 0x0C, 0x6B, 0xAF, 0x01, 0x00, 0xB9, 0x2E, 0x20, 0x00, 0x99, 0xDE, 0x1C, 0x00, + 0xF2, 0x06, 0x38, 0x7E, 0x18, 0x00, 0x06, 0x2E, 0x04, 0x32, 0xF1, 0x70, 0x50, 0xC1, 0x0C, 0x20, + 0x20, 0x4E, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x10, 0x72, 0x6B, 0xE6, + 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x30, 0x00, 0x10, 0x00, 0x16, 0x00, 0x1C, 0x00, 0x22, 0x00, + 0x28, 0x00, 0x38, 0x72, 0x04, 0x00, 0xF2, 0x0C, 0x38, 0x72, 0x0C, 0x00, 0xF2, 0x09, 0x38, 0x72, + 0x10, 0x00, 0xF2, 0x06, 0x38, 0x72, 0x14, 0x00, 0xF2, 0x03, 0x38, 0x72, 0x08, 0x00, 0xF1, 0x70, + 0xF2, 0x02, 0x04, 0x20, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x0C, 0x70, 0xFC, 0x0A, + 0x04, 0x61, 0x99, 0x67, 0x04, 0x0C, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x90, 0x94, 0xB9, 0x67, + 0x08, 0x0C, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x30, 0x98, 0xB9, 0x67, 0x0C, 0x0C, 0x08, 0x60, + 0x00, 0x80, 0x2C, 0x60, 0xA4, 0x98, 0xB9, 0x67, 0x10, 0x0C, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, + 0x9C, 0x9A, 0xB9, 0x67, 0x14, 0x0C, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x74, 0x97, 0xB9, 0x67, + 0x18, 0x0C, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0xC4, 0x97, 0x99, 0x07, 0x20, 0x0C, 0x99, 0x07, + 0x28, 0x0C, 0x99, 0x07, 0x29, 0x0C, 0xB9, 0x67, 0x1C, 0x0C, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, + 0x2B, 0x8B, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x17, 0x4B, 0xD9, 0x04, 0x00, 0x06, 0xE2, 0xAB, 0x8B, + 0x01, 0x00, 0xC6, 0xE2, 0xC2, 0x18, 0x36, 0xE2, 0x06, 0x2E, 0x06, 0x7E, 0xD7, 0x72, 0xD7, 0x21, + 0x26, 0x27, 0x36, 0x2E, 0xD7, 0x21, 0x0C, 0x30, 0x10, 0x27, 0xAB, 0x15, 0x00, 0x00, 0xC4, 0x2A, + 0xC2, 0x0A, 0x98, 0x70, 0xA4, 0x1B, 0x82, 0x04, 0xCB, 0x3A, 0x01, 0x00, 0xF2, 0x04, 0x06, 0x2E, + 0x8B, 0xEA, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x06, 0x65, 0x0C, 0x60, + 0x74, 0x1A, 0x28, 0x50, 0x74, 0x1A, 0x06, 0x72, 0xC6, 0x25, 0x82, 0x0C, 0x28, 0x56, 0x02, 0x00, + 0xC6, 0x25, 0x82, 0x0A, 0x28, 0x66, 0x04, 0x00, 0x04, 0x20, 0xC6, 0x76, 0x92, 0x07, 0x04, 0x22, + 0xF2, 0x04, 0x04, 0x20, 0xF2, 0x02, 0x04, 0x21, 0x24, 0x21, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x08, 0x50, 0x00, 0x30, 0x18, 0x30, 0xB6, 0x1B, 0x0C, 0x60, 0x00, 0x0B, 0x04, 0x70, 0x0C, 0x20, + 0x74, 0x1A, 0x0C, 0xF0, 0x28, 0x08, 0x2C, 0x50, 0x00, 0xA0, 0xC4, 0x30, 0x2F, 0x42, 0x07, 0x00, + 0x20, 0x44, 0x92, 0x07, 0x57, 0x41, 0x26, 0x45, 0x30, 0x44, 0x5C, 0x40, 0xFF, 0x7F, 0xF2, 0x04, + 0x26, 0x44, 0x26, 0x4F, 0x20, 0x44, 0x24, 0x72, 0xC4, 0x76, 0xA1, 0x46, 0x24, 0x62, 0x92, 0xEE, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x70, 0xC6, 0x74, + 0x82, 0x09, 0x2F, 0x67, 0x03, 0x00, 0x60, 0x56, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x56, 0x24, 0x71, + 0xF2, 0xF7, 0xE1, 0xF0, 0x04, 0x70, 0xC6, 0x74, 0x82, 0x06, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x36, + 0x24, 0x71, 0xF2, 0xFA, 0xE1, 0xF0, 0x00, 0x00, 0x71, 0x00, 0xF2, 0xFF, 0x70, 0x6F, 0x36, 0x76, + 0x78, 0x6F, 0x02, 0x00, 0xC6, 0x76, 0xB2, 0x07, 0x26, 0x77, 0x26, 0x7F, 0x78, 0x77, 0x06, 0x00, + 0x26, 0x7F, 0xE1, 0x70, 0x78, 0x7F, 0x04, 0x00, 0x26, 0x7F, 0xE1, 0x70, 0x0B, 0x0C, 0x0D, 0x0C, + 0x0C, 0x0D, 0x0C, 0x0C, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0B, + 0x0D, 0x0E, 0x0C, 0x0C, 0x0D, 0x0D, 0x0C, 0x0B, 0x0A, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x09, 0x0A, 0x0D, 0x0D, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0B, 0x0A, 0x0A, 0x0A, 0x09, 0x09, + 0x09, 0x09, 0x0A, 0x09, 0x09, 0x0A, 0x0C, 0x0D, 0x0B, 0x0B, 0x0C, 0x0C, 0x0B, 0x0A, 0x0A, 0x0B, + 0x0A, 0x09, 0x0A, 0x09, 0x09, 0x0A, 0x0A, 0x09, 0x0A, 0x0B, 0x0C, 0x0A, 0x0B, 0x0C, 0x0B, 0x0B, + 0x09, 0x0A, 0x0B, 0x0A, 0x09, 0x0A, 0x09, 0x09, 0x0A, 0x0A, 0x09, 0x09, 0x0B, 0x0C, 0x0A, 0x0A, + 0x0B, 0x0B, 0x0A, 0x09, 0x0B, 0x0B, 0x0A, 0x0A, 0x0B, 0x0A, 0x0A, 0x0B, 0x0B, 0x0A, 0x09, 0x0B, + 0x0B, 0x0A, 0x0A, 0x0B, 0x0B, 0x0A, 0x09, 0x0C, 0x0C, 0x0B, 0x0B, 0x0B, 0x0B, 0x0A, 0x0B, 0x0B, + 0x0A, 0x09, 0x0A, 0x0B, 0x0A, 0x0A, 0x0B, 0x0A, 0x0A, 0x08, 0x0C, 0x0C, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0C, 0x0C, 0x0A, 0x09, 0x0B, 0x0B, 0x09, 0x0A, 0x0B, 0x0A, 0x09, 0x08, 0x0C, 0x0D, 0x0C, + 0x0C, 0x0C, 0x0B, 0x0B, 0x0D, 0x0C, 0x0B, 0x09, 0x09, 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x0C, 0x0C, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0B, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x09, + 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, + 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, + 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, 0x90, 0x97, 0x9E, 0x99, + 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, + 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, + 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, 0x27, 0x20, 0x29, 0x2E, + 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, + 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, + 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, 0xF9, 0xFE, 0xF7, 0xF0, + 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, + 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, + 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, 0x4E, 0x49, 0x40, 0x47, + 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, + 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, + 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, + 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3, 0x04, 0x70, 0x06, 0x62, + 0x73, 0x67, 0xD4, 0x61, 0x04, 0x51, 0x26, 0x57, 0x13, 0x55, 0x92, 0x03, 0x06, 0x75, 0xF2, 0xF8, + 0x06, 0x27, 0xE1, 0xF0, 0xC6, 0x23, 0x06, 0x72, 0x02, 0x02, 0x06, 0x73, 0x43, 0x27, 0xE1, 0xF0, + 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE4, 0xCB, 0x04, 0x00, 0x00, 0x06, 0x3E, 0xCB, 0x04, 0x00, 0x00, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x24, 0x00, 0xC6, 0x32, 0x06, 0x73, 0x32, 0x02, 0x06, 0x72, + 0x43, 0x27, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE4, 0xEB, 0x05, 0x00, 0x00, 0x06, 0x3E, + 0xEB, 0x05, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x24, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x06, 0xE5, 0x06, 0xD6, 0x4B, 0x06, 0x00, 0x00, 0x06, 0x3E, 0x06, 0x4D, 0x4B, 0x06, + 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x24, 0x00, 0x14, 0x71, 0x26, 0x74, + 0x26, 0x27, 0x16, 0x64, 0x26, 0x37, 0x2F, 0x76, 0x03, 0x00, 0x26, 0x62, 0xC4, 0x40, 0x82, 0x09, + 0x2F, 0x54, 0x07, 0x00, 0x60, 0x35, 0x2F, 0x54, 0x06, 0x00, 0x91, 0x35, 0x34, 0x41, 0xF2, 0xF7, + 0xE1, 0xF0, 0x24, 0x00, 0x04, 0x70, 0xC6, 0x74, 0x82, 0x09, 0x2F, 0x67, 0x03, 0x00, 0x60, 0x56, + 0x2F, 0x67, 0x02, 0x00, 0x91, 0x56, 0x24, 0x71, 0xF2, 0xF7, 0xE1, 0xF0, 0x04, 0x70, 0xC6, 0x74, + 0x82, 0x0A, 0x2F, 0x67, 0x07, 0x00, 0x2F, 0x56, 0x03, 0x00, 0x20, 0x55, 0x26, 0x62, 0xA1, 0x56, + 0x24, 0x71, 0xF2, 0xF6, 0xE1, 0xF0, 0x24, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x04, 0x70, 0x14, 0x61, + 0x34, 0x41, 0xC6, 0x46, 0x82, 0x09, 0x2F, 0x57, 0x03, 0x00, 0x30, 0xF5, 0x2F, 0x57, 0x02, 0x00, + 0xB1, 0xF5, 0x24, 0x74, 0xF2, 0xF6, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x04, 0x70, 0x14, 0xF1, 0x34, 0x51, 0xC6, 0x5F, 0x82, 0x0D, 0x2F, 0x67, 0x03, 0x00, + 0x30, 0xD6, 0x2F, 0xE7, 0x02, 0x00, 0xB1, 0xDE, 0x2F, 0xE7, 0x04, 0x00, 0x30, 0xEE, 0x24, 0x74, + 0xB1, 0xE6, 0xF2, 0xF2, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x04, 0x70, 0xC6, 0x74, + 0x82, 0x06, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x36, 0x24, 0x71, 0xF2, 0xFA, 0xE1, 0xF0, 0x24, 0x00, + 0x04, 0x70, 0xC6, 0x74, 0x82, 0x07, 0x2F, 0x67, 0x07, 0x00, 0x26, 0x62, 0xA1, 0x36, 0x24, 0x71, + 0xF2, 0xF9, 0xE1, 0xF0, 0x14, 0x71, 0x34, 0x41, 0xC6, 0x47, 0x82, 0x04, 0xB1, 0x32, 0x24, 0x24, + 0xF2, 0xFB, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xC2, 0x06, 0xD3, 0x06, 0xE3, + 0x06, 0x2E, 0x06, 0x3E, 0x08, 0xF0, 0x00, 0x80, 0x2C, 0xF0, 0x88, 0x02, 0xF1, 0xF0, 0xC6, 0x2C, + 0xC2, 0x02, 0x76, 0xED, 0xF7, 0xD0, 0xC4, 0xD0, 0x82, 0x03, 0x66, 0xED, 0xF2, 0xF2, 0x06, 0x2E, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x38, 0x60, 0x68, 0x19, 0x08, 0x70, 0xFD, 0xFF, + 0x2C, 0x70, 0xFF, 0xFF, 0x56, 0x76, 0x08, 0x50, 0x31, 0x00, 0xC6, 0x75, 0x82, 0x05, 0x08, 0x70, + 0x32, 0x00, 0xC6, 0x67, 0x92, 0x03, 0xB1, 0x32, 0xE1, 0xF0, 0xF2, 0x00, 0x08, 0x20, 0x00, 0x40, + 0x34, 0x14, 0x2C, 0x20, 0x10, 0x60, 0x0C, 0x30, 0x00, 0xDE, 0xB1, 0xF1, 0x0B, 0x14, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x24, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x07, 0x10, 0x60, + 0xE1, 0xF0, 0x24, 0x00, 0x34, 0x14, 0x0C, 0x70, 0x1E, 0x00, 0xB1, 0x71, 0x30, 0x71, 0x14, 0x61, + 0xC4, 0x70, 0x26, 0x67, 0xB1, 0x61, 0x92, 0xFB, 0x24, 0x14, 0xE1, 0xF0, 0xE1, 0xF0, 0x24, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x72, 0x08, 0xE0, 0x00, 0x40, 0x0C, 0x20, 0x00, 0x60, + 0x06, 0xD3, 0x26, 0x2E, 0x06, 0x37, 0xB9, 0x0E, 0x90, 0x60, 0x0B, 0x14, 0x00, 0x00, 0x0C, 0x20, + 0x08, 0x60, 0xB9, 0xDE, 0x04, 0x60, 0x26, 0x2E, 0x04, 0x30, 0x0B, 0x14, 0x00, 0x00, 0x38, 0x7E, + 0x90, 0x60, 0xD4, 0x71, 0x82, 0xFD, 0x0C, 0x70, 0x00, 0x81, 0xB9, 0x7E, 0x00, 0x60, 0x6B, 0x16, + 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x24, 0x00, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0x06, 0x72, 0x08, 0xD0, 0x00, 0x40, 0x0C, 0x20, 0x00, 0x60, 0xD1, 0x81, + 0x06, 0xE3, 0x06, 0xB5, 0x26, 0x2D, 0x06, 0x37, 0x0C, 0xA0, 0x08, 0x60, 0x06, 0xC4, 0x26, 0xBE, + 0x0B, 0x14, 0x00, 0x00, 0x26, 0xAD, 0xC6, 0xEB, 0x82, 0x10, 0xB9, 0xED, 0x04, 0x60, 0x30, 0x3C, + 0x04, 0x91, 0x06, 0x2A, 0x26, 0x9E, 0x0B, 0x14, 0x00, 0x00, 0x38, 0x7D, 0x90, 0x60, 0xD4, 0x72, + 0x82, 0xFD, 0x24, 0xC4, 0x06, 0xE9, 0xF2, 0xF0, 0x0C, 0x70, 0x00, 0x81, 0xB9, 0x7D, 0x00, 0x60, + 0x6B, 0x16, 0x00, 0x00, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0x86, 0xD6, 0x08, 0x70, 0x00, 0x40, 0x82, 0x05, + 0x0C, 0x60, 0x00, 0xDE, 0xB9, 0x67, 0x10, 0x60, 0xB9, 0x27, 0x00, 0x60, 0xB9, 0x37, 0x04, 0x60, + 0x04, 0x61, 0x04, 0x70, 0x08, 0x20, 0x00, 0x40, 0xC6, 0x75, 0x82, 0x0E, 0xB1, 0x61, 0x30, 0x31, + 0x14, 0xF1, 0xC4, 0x30, 0x26, 0xF3, 0xB1, 0xF1, 0x92, 0xFB, 0x38, 0x32, 0x0C, 0x60, 0x24, 0x71, + 0xB1, 0x34, 0x24, 0x44, 0xF2, 0xF2, 0x08, 0xE0, 0x00, 0x40, 0x0C, 0x70, 0x00, 0x81, 0xB9, 0x7E, + 0x00, 0x60, 0x6B, 0x16, 0x00, 0x00, 0xC4, 0xD0, 0x82, 0x03, 0xB9, 0x0E, 0x10, 0x60, 0x58, 0xC1, + 0x04, 0x00, 0x04, 0x21, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0x24, 0x00, 0x34, 0x18, 0xC1, 0xE1, + 0x08, 0x70, 0x00, 0x40, 0x0C, 0x60, 0x00, 0xDE, 0xB9, 0x67, 0x10, 0x60, 0x77, 0x41, 0xB9, 0x27, + 0x00, 0x60, 0x77, 0x31, 0x34, 0x41, 0x08, 0x60, 0x00, 0x13, 0xB9, 0x37, 0x04, 0x60, 0x66, 0x46, + 0xB9, 0x47, 0x14, 0x60, 0x08, 0x50, 0x00, 0x10, 0x38, 0x67, 0x14, 0x60, 0x0C, 0x40, 0x14, 0x60, + 0xD6, 0x65, 0x26, 0x47, 0x92, 0xFA, 0x38, 0xE7, 0x18, 0x60, 0xB1, 0x04, 0x0C, 0x60, 0x00, 0x81, + 0xB9, 0x67, 0x00, 0x60, 0xB9, 0x07, 0x10, 0x60, 0x6B, 0x16, 0x00, 0x00, 0x06, 0x2E, 0x40, 0xE1, + 0x24, 0x18, 0xE1, 0xF0, 0x29, 0x2A, 0x27, 0x26, 0x29, 0x26, 0x26, 0x2A, 0x29, 0x29, 0x27, 0x1F, + 0x21, 0x1D, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x28, 0x25, 0x23, + 0x26, 0x24, 0x24, 0x27, 0x26, 0x26, 0x23, 0x1F, 0x21, 0x1E, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0x27, 0x23, 0x23, 0x25, 0x22, 0x23, 0x26, 0x25, 0x26, 0x29, 0x1F, + 0x21, 0x1D, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x26, 0x23, 0x23, + 0x25, 0x23, 0x22, 0x25, 0x24, 0x23, 0x20, 0x20, 0x21, 0x1E, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x26, 0x23, 0x22, 0x25, 0x22, 0x21, 0x24, 0x23, 0x23, 0x1F, 0x20, + 0x22, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x26, 0x22, 0x21, + 0x24, 0x21, 0x20, 0x23, 0x22, 0x22, 0x1F, 0x20, 0x22, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x24, 0x21, 0x20, 0x22, 0x20, 0x20, 0x23, 0x22, 0x23, 0x26, 0x20, + 0x22, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x24, 0x21, 0x20, + 0x22, 0x20, 0x1F, 0x22, 0x21, 0x21, 0x1D, 0x21, 0x24, 0x20, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x24, 0x20, 0x1F, 0x22, 0x1F, 0x1E, 0x21, 0x21, 0x20, 0x1D, 0x22, + 0x24, 0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x24, 0x20, 0x1F, + 0x22, 0x1F, 0x1E, 0x21, 0x21, 0x20, 0x1C, 0x23, 0x25, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x24, 0x20, 0x1E, 0x21, 0x1F, 0x1F, 0x22, 0x20, 0x20, 0x1C, 0x24, + 0x26, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x23, 0x1F, 0x1E, + 0x21, 0x1E, 0x1E, 0x21, 0x20, 0x20, 0x23, 0x24, 0x26, 0x23, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x23, 0x20, 0x1F, 0x21, 0x1F, 0x1E, 0x21, 0x20, 0x1F, 0x1C, 0x26, + 0x28, 0x25, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x23, 0x20, 0x1E, + 0x21, 0x1E, 0x1E, 0x21, 0x1F, 0x1F, 0x1B, 0x2A, 0x2C, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x18, 0x0E, 0x17, 0x0E, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0x02, 0x06, 0x0B, 0xFF, 0x17, 0x17, 0x17, 0xFF, 0x00, + 0x80, 0x07, 0x38, 0x04, 0xFF, 0x1F, 0xFF, 0x11, 0x40, 0x06, 0x40, 0x06, 0x01, 0xFA, 0xFA, 0x00, + 0x00, 0x02, 0x01, 0x46, 0x00, 0x01, 0x00, 0x02, 0x0A, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x00, + 0xA0, 0x86, 0x01, 0x00, 0xC0, 0xE1, 0xE4, 0x00, 0x00, 0x7D, 0x00, 0x00, 0xC8, 0x00, 0xC8, 0x00, + 0xC8, 0x00, 0xC8, 0x00, 0x6E, 0x50, 0x14, 0x28, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5A, 0x00, + 0x01, 0x00, 0x0A, 0x00, 0xA0, 0x0F, 0x64, 0x64, 0x64, 0x01, 0x38, 0x32, 0x02, 0x04, 0x02, 0x09, + 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3C, 0x00, + 0x05, 0x05, 0x08, 0x0E, 0x11, 0x17, 0x17, 0x17, 0x17, 0x02, 0x03, 0x04, 0x02, 0x01, 0x00, 0x04, + 0x00, 0x06, 0x01, 0x03, 0x08, 0x04, 0x10, 0x03, 0x03, 0x00, 0x90, 0x01, 0x00, 0x00, 0x32, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0x01, 0x00, + 0xFF, 0x3F, 0x01, 0x00, 0x42, 0x22, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x80, 0x40, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x00, 0x32, 0x16, 0x22, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x32, 0x16, 0x22, 0x00, 0x32, 0x16, 0x22, 0x00, 0x32, 0x16, 0x22, 0x00, 0x51, 0x06, 0x03, 0x00, + 0x63, 0x87, 0x02, 0x00, 0x63, 0x87, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x40, 0x0F, 0xB0, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x65, 0x32, 0x00, 0x03, 0x66, 0x7F, 0xF0, 0x07, + 0x66, 0x7F, 0xF0, 0x07, 0x42, 0x22, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x80, 0x40, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x40, 0x28, 0x22, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x40, 0x28, 0x22, 0x00, 0x40, 0x28, 0x22, 0x00, 0x40, 0x28, 0x22, 0x00, 0x51, 0x06, 0x03, 0x00, + 0x63, 0x87, 0x02, 0x00, 0x63, 0x87, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x40, 0x0F, 0xB0, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x65, 0x30, 0x00, 0x03, 0x66, 0x7F, 0xF0, 0x07, + 0x66, 0x7F, 0xF0, 0x07, 0x42, 0x22, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x80, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x00, 0x32, 0x16, 0x22, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x32, 0x32, 0x22, 0x00, 0x32, 0x32, 0x22, 0x00, 0x32, 0x32, 0x22, 0x00, 0x51, 0x06, 0x03, 0x00, + 0x63, 0x87, 0x02, 0x00, 0x63, 0x87, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x40, 0x0F, 0xB0, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x65, 0x32, 0x00, 0x03, 0x66, 0x7F, 0xF0, 0x07, + 0x66, 0x7F, 0xF0, 0x07, 0x42, 0x22, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x80, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x80, 0x40, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x40, 0x28, 0x22, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x40, 0x28, 0x22, 0x00, 0x40, 0x28, 0x22, 0x00, 0x40, 0x28, 0x22, 0x00, 0x51, 0x06, 0x03, 0x00, + 0x63, 0x87, 0x02, 0x00, 0x63, 0x87, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x40, 0x0F, 0xB0, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x65, 0x30, 0x00, 0x03, 0x66, 0x7F, 0xF0, 0x07, + 0x66, 0x7F, 0xF0, 0x07, 0x02, 0x00, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0x55, 0x07, 0x05, 0x50, + 0xC8, 0x00, 0x90, 0x01, 0x32, 0x00, 0x32, 0x00, 0x19, 0x19, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, + 0x00, 0x00, 0x64, 0x64, 0xC8, 0x00, 0x14, 0x00, 0x01, 0x00, 0x32, 0x00, 0x46, 0x00, 0x14, 0x00, + 0x64, 0x00, 0x78, 0x00, 0x96, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x14, 0x00, 0x64, 0x00, + 0x00, 0x00, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x1E, 0x00, 0x64, 0x00, 0x20, 0x03, 0x64, 0x00, 0x64, 0x00, 0x14, 0x00, 0x96, 0x00, + 0x00, 0x05, 0x04, 0x0A, 0x05, 0x06, 0xC8, 0x00, 0x05, 0x32, 0x0A, 0x17, 0x19, 0x17, 0x19, 0x1B, + 0x19, 0x19, 0x16, 0x19, 0x1E, 0x1E, 0x1E, 0x19, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3C, 0x0F, 0x64, + 0x05, 0x1E, 0x20, 0x03, 0xDC, 0x05, 0xC8, 0x00, 0x14, 0x00, 0x28, 0x00, 0x14, 0x00, 0x0A, 0x00, + 0x46, 0x02, 0x01, 0x01, 0x01, 0x00, 0x1E, 0x00, 0x32, 0x00, 0x64, 0x00, 0x14, 0x01, 0x02, 0x03, + 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14, 0x00, 0x19, 0x00, + 0x32, 0x00, 0x4B, 0x00, 0x64, 0x00, 0x64, 0x00, 0x02, 0x00, 0x64, 0x00, 0x2D, 0x2D, 0x0A, 0x00, + 0x0A, 0x00, 0x28, 0x00, 0x64, 0x00, 0x0A, 0x0A, 0x1E, 0x00, 0x05, 0x0A, 0x01, 0x00, 0x3C, 0x00, + 0x50, 0x00, 0x05, 0x00, 0x1E, 0x00, 0xC8, 0x00, 0x05, 0x05, 0x14, 0x00, 0x32, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x55, 0x55, 0x05, 0x00, 0x55, 0x07, 0x05, 0x50, 0xC8, 0x00, 0x90, 0x01, + 0x32, 0x00, 0x32, 0x00, 0x19, 0x19, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x64, 0x64, + 0xC8, 0x00, 0x14, 0x00, 0x01, 0x00, 0x32, 0x00, 0x46, 0x00, 0x14, 0x00, 0x64, 0x00, 0x78, 0x00, + 0x96, 0x00, 0x64, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x64, 0x00, 0x00, 0x00, 0x50, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1E, 0x00, + 0x1E, 0x00, 0x20, 0x03, 0x64, 0x00, 0x64, 0x00, 0x14, 0x00, 0x96, 0x00, 0x00, 0x05, 0x04, 0x0A, + 0x05, 0x06, 0xDC, 0x00, 0x05, 0x32, 0x0A, 0x17, 0x19, 0x17, 0x19, 0x1B, 0x19, 0x19, 0x16, 0x19, + 0x1E, 0x1E, 0x1E, 0x19, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3C, 0x0F, 0x64, 0x02, 0x14, 0x20, 0x03, + 0xDC, 0x05, 0xC8, 0x00, 0x14, 0x00, 0x28, 0x00, 0x1E, 0x00, 0x0A, 0x00, 0x46, 0x02, 0x01, 0x01, + 0x01, 0x00, 0x1E, 0x00, 0x32, 0x00, 0x64, 0x00, 0x14, 0x01, 0x02, 0x03, 0x02, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14, 0x00, 0x19, 0x00, 0x32, 0x00, 0x4B, 0x00, + 0x64, 0x00, 0x64, 0x00, 0x02, 0x00, 0x64, 0x00, 0x2D, 0x2D, 0x0A, 0x00, 0x0A, 0x00, 0x28, 0x00, + 0x64, 0x00, 0x0A, 0x0A, 0x3C, 0x00, 0x05, 0x0A, 0x01, 0x00, 0x3C, 0x00, 0x50, 0x00, 0x05, 0x00, + 0x3C, 0x00, 0xC8, 0x00, 0x05, 0x05, 0x1E, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x0E, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x00, 0x32, 0x16, 0x22, 0x00, 0x54, 0xFF, 0x0F, 0x00, 0x10, 0x90, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF4, 0x01, 0xC8, 0x00, 0x16, 0x32, 0x10, 0x10, 0x01, 0x00, 0x08, 0x00, + 0x32, 0x00, 0x64, 0x10, 0x51, 0x06, 0x03, 0x00, 0xFF, 0x3F, 0x01, 0x00, 0x18, 0x08, 0x00, 0x00, + 0x64, 0xC0, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0F, 0xB0, 0x0F, + 0x01, 0x01, 0x80, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x80, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, + 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, + 0x40, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x30, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x22, 0x01, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x16, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x64, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x08, 0x82, + 0x00, 0x00, 0xFF, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xC8, 0x00, 0xF0, 0x0F, + 0x3C, 0x00, 0x08, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x3F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xAC, 0x0D, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x65, 0x32, 0x00, 0x03, + 0xD5, 0xC6, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xE9, 0x05, 0x00, + 0x1B, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x04, 0x40, 0x00, 0x04, 0x22, 0xC8, 0x00, 0x00, 0xFF, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x7F, 0xFC, 0x8F, 0xBF, 0x01, 0x20, 0x00, 0x00, + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x13, 0x12, 0x11, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x00, + 0x00, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x17, 0x00, 0x00, 0xFF, 0x00, 0x20, 0x86, 0x00, 0x00, 0x00, 0x4D, + 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x26, 0x18, 0x00, + 0x3E, 0x26, 0x19, 0x01, 0x3F, 0x27, 0x19, 0x01, 0x3F, 0x27, 0x1A, 0x02, 0x40, 0x28, 0x1A, 0x02, + 0x40, 0x28, 0x1B, 0x03, 0x41, 0x29, 0x1B, 0x03, 0x41, 0x29, 0x1C, 0x04, 0x42, 0x2A, 0x1C, 0x04, + 0x42, 0x2A, 0x1D, 0x05, 0x43, 0x2B, 0x1D, 0x05, 0x43, 0x2B, 0x1E, 0x06, 0x44, 0x2C, 0x1E, 0x06, + 0x44, 0x2C, 0x1F, 0x07, 0x45, 0x2D, 0x1F, 0x07, 0x36, 0x26, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x07, 0x13, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4F, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x10, 0x23, 0x98, 0x07, 0x10, 0x23, 0x0C, 0x00, 0x20, 0x1E, 0xFC, 0x0F, 0x20, 0x1E, + 0xFC, 0x0F, 0x30, 0x1A, 0xFC, 0x0F, 0x30, 0x1A, 0x54, 0x06, 0x40, 0x17, 0x1C, 0x00, 0x40, 0x1B, + 0x34, 0x00, 0x50, 0x18, 0xC4, 0x05, 0x50, 0x19, 0x9C, 0x05, 0x50, 0x19, 0x08, 0x00, 0x70, 0x19, + 0x30, 0x00, 0x90, 0x1A, 0xC4, 0x07, 0x90, 0x17, 0x98, 0x03, 0x90, 0x17, 0xB0, 0x02, 0xA0, 0x17, + 0xEC, 0x00, 0xA0, 0x15, 0xFC, 0x0F, 0xA0, 0x16, 0x08, 0x00, 0xB0, 0x18, 0x08, 0x00, 0xB0, 0x18, + 0x34, 0x04, 0xB0, 0x18, 0x2C, 0x00, 0xC0, 0x18, 0x18, 0x00, 0xC0, 0x16, 0x1C, 0x00, 0xF0, 0xBF, + 0x00, 0x0E, 0x10, 0x1D, 0xF4, 0x0F, 0x00, 0x22, 0xFC, 0x0F, 0x10, 0x1D, 0x00, 0x00, 0x10, 0x1E, + 0x30, 0x01, 0x20, 0x20, 0xFC, 0x0F, 0x20, 0x1E, 0xE0, 0x00, 0x30, 0x1A, 0xFC, 0x0F, 0x30, 0x1E, + 0xFC, 0x0F, 0x40, 0x1A, 0x00, 0x00, 0x50, 0x18, 0xB8, 0x07, 0x60, 0x13, 0x10, 0x00, 0x70, 0x19, + 0xE0, 0x00, 0x80, 0x1C, 0xFC, 0x0F, 0x80, 0x19, 0xFC, 0x0F, 0x80, 0x18, 0x0C, 0x00, 0x90, 0x17, + 0x1C, 0x00, 0x90, 0x16, 0xB0, 0x01, 0x90, 0x17, 0x30, 0x01, 0xA0, 0x19, 0x1C, 0x01, 0xA0, 0x19, + 0xDC, 0x00, 0xA0, 0x19, 0x24, 0x07, 0xA0, 0x18, 0xB8, 0x01, 0xC0, 0x15, 0x98, 0x0B, 0xF0, 0xBF, + 0x24, 0x04, 0x10, 0x20, 0xE4, 0x00, 0x00, 0x22, 0xFC, 0x0F, 0x10, 0x1E, 0x24, 0x00, 0x10, 0x1E, + 0x3C, 0x00, 0x20, 0x21, 0x14, 0x00, 0x30, 0x1B, 0xD0, 0x01, 0x30, 0x1C, 0xF4, 0x0F, 0x30, 0x1E, + 0xFC, 0x0F, 0x40, 0x1C, 0x00, 0x00, 0x40, 0x1C, 0x1C, 0x00, 0x50, 0x1C, 0x08, 0x00, 0x70, 0x18, + 0x04, 0x03, 0x80, 0x1B, 0xF4, 0x0F, 0x80, 0x18, 0xFC, 0x0F, 0x80, 0x17, 0xB8, 0x0E, 0x90, 0x17, + 0x90, 0x00, 0x90, 0x15, 0x18, 0x04, 0x90, 0x17, 0x00, 0x00, 0x90, 0x19, 0x0C, 0x00, 0xA0, 0x18, + 0x08, 0x00, 0xA0, 0x19, 0xB8, 0x0E, 0xA0, 0x17, 0xF4, 0x0F, 0xB0, 0x15, 0xFC, 0x0F, 0xF0, 0x2E, + 0x04, 0x00, 0x10, 0x21, 0x0C, 0x04, 0x00, 0x23, 0x04, 0x00, 0x10, 0x1E, 0x38, 0x0E, 0x10, 0x1E, + 0x9C, 0x00, 0x20, 0x22, 0xDC, 0x01, 0x30, 0x1C, 0x80, 0x0D, 0x30, 0x1A, 0xFC, 0x0F, 0x30, 0x1E, + 0xFC, 0x0F, 0x40, 0x1C, 0xB8, 0x0E, 0x40, 0x1C, 0x1C, 0x00, 0x40, 0x19, 0x78, 0x06, 0x70, 0x18, + 0x00, 0x00, 0x70, 0x1C, 0x50, 0x01, 0x80, 0x18, 0xFC, 0x0F, 0x80, 0x17, 0x10, 0x00, 0x90, 0x17, + 0xE0, 0x00, 0x90, 0x16, 0xFC, 0x0F, 0x90, 0x15, 0x3C, 0x00, 0x90, 0x18, 0x24, 0x00, 0x90, 0x19, + 0xD8, 0x01, 0x90, 0x1A, 0x10, 0x00, 0x90, 0x19, 0x04, 0x02, 0xA0, 0x16, 0x1C, 0x00, 0xF0, 0xBF, + 0x00, 0x00, 0x10, 0x21, 0x1C, 0x00, 0x10, 0x23, 0x08, 0x00, 0x20, 0x1E, 0xD0, 0x01, 0x20, 0x1D, + 0xE4, 0x0F, 0x30, 0x1E, 0xFC, 0x0F, 0x30, 0x1A, 0x24, 0x0D, 0x30, 0x1A, 0x0C, 0x07, 0x40, 0x1D, + 0x0C, 0x00, 0x40, 0x1C, 0x08, 0x00, 0x40, 0x1C, 0x1C, 0x04, 0x40, 0x18, 0xF4, 0x0F, 0x70, 0x18, + 0x08, 0x04, 0x70, 0x1B, 0x04, 0x00, 0x80, 0x18, 0x24, 0x0D, 0x80, 0x17, 0xC4, 0x0B, 0x90, 0x17, + 0xF8, 0x0F, 0x90, 0x15, 0xFC, 0x0F, 0x90, 0x16, 0x04, 0x00, 0x90, 0x19, 0x38, 0x0C, 0x90, 0x19, + 0x0C, 0x01, 0x90, 0x19, 0x04, 0x0A, 0x90, 0x18, 0x2C, 0x0E, 0xA0, 0x16, 0xEC, 0x0F, 0xF0, 0xBF, + 0x00, 0x00, 0x10, 0x21, 0x38, 0x0D, 0x10, 0x22, 0x9C, 0x00, 0x20, 0x1E, 0xD4, 0x02, 0x20, 0x1D, + 0x9C, 0x0D, 0x30, 0x1E, 0xFC, 0x0F, 0x30, 0x1C, 0x04, 0x09, 0x40, 0x1A, 0xF8, 0x0F, 0x40, 0x1D, + 0xFC, 0x0F, 0x40, 0x1C, 0x00, 0x01, 0x40, 0x1C, 0xF8, 0x0F, 0x40, 0x19, 0xFC, 0x0F, 0x70, 0x18, + 0x68, 0x06, 0x70, 0x1A, 0x04, 0x00, 0x70, 0x17, 0x58, 0x01, 0x80, 0x16, 0x10, 0x00, 0x80, 0x17, + 0x50, 0x01, 0x80, 0x15, 0xEC, 0x0F, 0x80, 0x16, 0x20, 0x00, 0x90, 0x18, 0xE0, 0x00, 0x90, 0x18, + 0xFC, 0x0F, 0x90, 0x19, 0x14, 0x00, 0x80, 0x19, 0xD8, 0x01, 0x90, 0x16, 0xF4, 0x0F, 0xF0, 0xBF, + 0x84, 0x06, 0x10, 0x21, 0xFC, 0x0F, 0x10, 0x21, 0xFC, 0x0F, 0x20, 0x1C, 0x80, 0x05, 0x20, 0x1B, + 0x0C, 0x00, 0x30, 0x1C, 0x18, 0x0E, 0x30, 0x1A, 0xB8, 0x07, 0x40, 0x19, 0x18, 0x00, 0x40, 0x1C, + 0xB8, 0x07, 0x40, 0x1C, 0x00, 0x00, 0x40, 0x1C, 0xB8, 0x07, 0x40, 0x1E, 0x0C, 0x00, 0x70, 0x18, + 0x04, 0x01, 0x70, 0x1A, 0x1C, 0x00, 0x80, 0x15, 0x1C, 0x00, 0x80, 0x16, 0x00, 0x00, 0x80, 0x17, + 0xD4, 0x05, 0x80, 0x15, 0x9C, 0x0E, 0x80, 0x16, 0xB0, 0x01, 0x90, 0x18, 0x38, 0x01, 0x90, 0x17, + 0x1C, 0x01, 0x90, 0x18, 0xC4, 0x00, 0x80, 0x18, 0x2C, 0x03, 0x90, 0x17, 0xFC, 0x0F, 0xF0, 0x2D, + 0x90, 0x0B, 0x20, 0x20, 0xFC, 0x0F, 0x20, 0x20, 0xFC, 0x0F, 0x30, 0x1A, 0x24, 0x01, 0x30, 0x19, + 0xBC, 0x04, 0x40, 0x1B, 0x2C, 0x04, 0x40, 0x19, 0xF0, 0x02, 0x40, 0x19, 0xFC, 0x0F, 0x40, 0x1C, + 0xFC, 0x0F, 0x50, 0x1A, 0x0C, 0x00, 0x50, 0x1B, 0x1C, 0x01, 0x40, 0x1A, 0xF8, 0x0F, 0x60, 0x17, + 0x00, 0x00, 0x70, 0x18, 0x78, 0x06, 0x80, 0x15, 0x04, 0x00, 0x70, 0x17, 0xC4, 0x00, 0x80, 0x17, + 0xF4, 0x0F, 0x80, 0x15, 0xFC, 0x0F, 0x80, 0x17, 0x10, 0x00, 0x90, 0x18, 0x58, 0x01, 0x90, 0x18, + 0xF4, 0x0F, 0x90, 0x18, 0x04, 0x01, 0x80, 0x18, 0x2C, 0x00, 0x90, 0x16, 0x14, 0x00, 0xF0, 0xBF, + 0xE0, 0x00, 0x20, 0x1E, 0xFC, 0x0F, 0x20, 0x1F, 0xFC, 0x0F, 0x30, 0x1A, 0xC0, 0x01, 0x30, 0x19, + 0xF8, 0x0F, 0x40, 0x1C, 0xFC, 0x0F, 0x40, 0x1A, 0x0C, 0x00, 0x40, 0x19, 0x18, 0x0E, 0x40, 0x1C, + 0xFC, 0x0F, 0x50, 0x1A, 0x10, 0x00, 0x50, 0x1B, 0x7C, 0x01, 0x40, 0x19, 0xB8, 0x07, 0x60, 0x17, + 0x00, 0x00, 0x70, 0x17, 0x7C, 0x01, 0x70, 0x16, 0x3C, 0x01, 0x70, 0x17, 0x08, 0x00, 0x80, 0x16, + 0x18, 0x03, 0x80, 0x14, 0xBC, 0x07, 0x80, 0x16, 0x04, 0x00, 0x90, 0x17, 0x7C, 0x06, 0x90, 0x17, + 0xB8, 0x07, 0x90, 0x18, 0x14, 0x00, 0x80, 0x19, 0x18, 0x00, 0x90, 0x16, 0x14, 0x00, 0xF0, 0xBF, + 0x38, 0x07, 0x20, 0x1E, 0x1C, 0x00, 0x20, 0x1F, 0x1C, 0x00, 0x30, 0x1B, 0x14, 0x00, 0x30, 0x1A, + 0xDC, 0x05, 0x40, 0x1C, 0x3C, 0x07, 0x40, 0x1A, 0x90, 0x0A, 0x40, 0x1A, 0xFC, 0x0F, 0x40, 0x1C, + 0xFC, 0x0F, 0x50, 0x1A, 0xB0, 0x04, 0x50, 0x1B, 0x0C, 0x00, 0x40, 0x19, 0x18, 0x01, 0x70, 0x15, + 0xB8, 0x07, 0x70, 0x16, 0x18, 0x00, 0x70, 0x15, 0xB8, 0x07, 0x70, 0x16, 0x10, 0x00, 0x80, 0x15, + 0x78, 0x06, 0x80, 0x14, 0x04, 0x00, 0x80, 0x16, 0x04, 0x0E, 0x90, 0x16, 0x48, 0x01, 0x90, 0x16, + 0xFC, 0x0F, 0x90, 0x17, 0xE0, 0x00, 0x80, 0x18, 0xFC, 0x0F, 0x90, 0x16, 0xFC, 0x0F, 0xF0, 0xBF, + 0x68, 0x07, 0x30, 0x1E, 0xE4, 0x06, 0x20, 0x1F, 0x74, 0x07, 0x40, 0x1A, 0x04, 0x08, 0x40, 0x19, + 0xF8, 0x06, 0x40, 0x1C, 0x34, 0x07, 0x40, 0x1B, 0x64, 0x07, 0x40, 0x18, 0xDC, 0x06, 0x50, 0x1C, + 0xFC, 0x06, 0x50, 0x1A, 0x20, 0x07, 0x50, 0x1B, 0x2C, 0x08, 0x60, 0x18, 0x18, 0x08, 0x60, 0x15, + 0x54, 0x06, 0x60, 0x17, 0xF0, 0x07, 0x60, 0x17, 0x7C, 0x07, 0x70, 0x16, 0xD4, 0x06, 0x80, 0x15, + 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x80, 0x14, 0x54, 0x00, 0x80, 0x17, 0x0C, 0x0A, 0x80, 0x18, + 0xEC, 0x0F, 0x80, 0x19, 0x34, 0x00, 0x80, 0x18, 0xFC, 0x0F, 0x90, 0x16, 0xFC, 0x0F, 0xF0, 0xBF, + 0x94, 0x0D, 0x30, 0x1E, 0xD4, 0x00, 0x30, 0x1E, 0x70, 0x0D, 0x40, 0x1B, 0x24, 0x00, 0x40, 0x1A, + 0xFC, 0x0F, 0x40, 0x1C, 0xFC, 0x0F, 0x40, 0x19, 0xAC, 0x0C, 0x40, 0x19, 0xF8, 0x0F, 0x50, 0x1A, + 0xFC, 0x0F, 0x50, 0x1A, 0xD0, 0x00, 0x50, 0x1C, 0x1C, 0x08, 0x60, 0x1F, 0x74, 0x00, 0x60, 0x14, + 0x80, 0x07, 0x60, 0x16, 0xFC, 0x0F, 0x60, 0x16, 0xFC, 0x0F, 0x60, 0x17, 0xF0, 0x0F, 0x70, 0x16, + 0xFC, 0x0F, 0x80, 0x13, 0xFC, 0x0F, 0x80, 0x14, 0x00, 0x08, 0x80, 0x17, 0xEC, 0x0F, 0x80, 0x17, + 0xFC, 0x0F, 0x80, 0x18, 0xFC, 0x0F, 0x80, 0x18, 0x1C, 0x0C, 0x80, 0x18, 0xC4, 0x06, 0xF0, 0x2A, + 0x4C, 0x0C, 0x40, 0x20, 0x74, 0x03, 0x40, 0x1F, 0xF8, 0x0F, 0x40, 0x1B, 0x60, 0x0E, 0x40, 0x19, + 0xF8, 0x0F, 0x40, 0x1B, 0xFC, 0x0F, 0x40, 0x1A, 0x08, 0x0C, 0x40, 0x19, 0x5C, 0x00, 0x40, 0x1B, + 0x74, 0x04, 0x50, 0x1A, 0xFC, 0x0F, 0x50, 0x1B, 0xEC, 0x0F, 0x60, 0x18, 0xFC, 0x0F, 0x50, 0x17, + 0xC0, 0x04, 0x60, 0x15, 0xFC, 0x0F, 0x50, 0x17, 0xFC, 0x0F, 0x60, 0x17, 0x60, 0x00, 0x60, 0x18, + 0x14, 0x0C, 0x60, 0x17, 0x20, 0x00, 0x70, 0x17, 0xAC, 0x07, 0x70, 0x1A, 0xFC, 0x0F, 0x70, 0x1A, + 0xFC, 0x0F, 0x80, 0x19, 0x14, 0x00, 0x80, 0x17, 0x8C, 0x0F, 0x80, 0x15, 0xF4, 0x0F, 0xF0, 0x3F, + 0x60, 0x0F, 0x40, 0x1C, 0xFC, 0x0F, 0x40, 0x20, 0xFC, 0x0F, 0x40, 0x1B, 0xE0, 0x09, 0x40, 0x1A, + 0x14, 0x00, 0x40, 0x1B, 0xF4, 0x0F, 0x40, 0x19, 0x04, 0x00, 0x40, 0x19, 0xF8, 0x0F, 0x50, 0x1A, + 0xFC, 0x0F, 0x60, 0x19, 0x60, 0x07, 0x60, 0x18, 0x04, 0x04, 0x60, 0x18, 0x70, 0x00, 0x60, 0x15, + 0x00, 0x0C, 0x60, 0x16, 0x24, 0x00, 0x60, 0x16, 0xF4, 0x0F, 0x70, 0x15, 0xFC, 0x0F, 0x70, 0x17, + 0xFC, 0x0F, 0x70, 0x16, 0xFC, 0x0F, 0x80, 0x16, 0x00, 0x0C, 0x80, 0x19, 0xD4, 0x0F, 0x80, 0x1A, + 0xFC, 0x0F, 0x80, 0x1B, 0x90, 0x04, 0x80, 0x1B, 0xFC, 0x0F, 0x80, 0x1B, 0xFC, 0x0F, 0xF0, 0x3F, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x90, 0xF0, 0x3F, 0x21, 0xB0, 0xF0, 0x3F, 0x42, 0xB0, 0xF0, 0x7F, 0x63, 0xB0, 0xF0, 0x3F, + 0x84, 0xB0, 0xF0, 0x3F, 0xA5, 0xB0, 0xF0, 0x3F, 0xC6, 0xB0, 0xF0, 0x7F, 0xE7, 0xB0, 0xF0, 0x3F, + 0x08, 0xB1, 0xF0, 0x3F, 0x29, 0xB1, 0xF0, 0x3F, 0x4A, 0xB1, 0xF0, 0x3F, 0x6B, 0xB1, 0xF0, 0x7F, + 0x8C, 0xB1, 0xF0, 0x3F, 0xAD, 0xA1, 0xF0, 0x3F, 0x00, 0x80, 0xF0, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3B, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x7F, 0xFC, 0x8F, 0x1F, 0x7F, 0xFC, 0x8F, 0x3F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, + 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, + 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, + 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, 0x0C, 0xC3, 0x30, 0x0C, + 0x10, 0x04, 0x41, 0x10, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x30, 0x30, 0x30, 0x30, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x30, 0x00, 0x49, 0x00, 0x30, 0x00, 0xA0, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x35, 0x45, 0x1D, 0x01, 0xC6, 0x9A, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x49, 0x53, 0x54, 0x56, 0x32, 0x54, 0x41, 0x47, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xDC, 0x00, 0x00, + 0x00, 0xDC, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0xE2, 0x00, 0x80, 0x00, 0x0E, 0x00, 0x00, + 0x00, 0xF0, 0x00, 0x80, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0xFC, 0x0A, 0x00, 0x00, + 0x00, 0x49, 0x00, 0x30, 0x00, 0xA0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8C, 0xA9, 0xC4, 0xBB, 0xF5, 0x43, 0x36, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x0C, 0xE0, 0x07, 0x15, 0x09, 0x23, 0x00, 0x49, 0x53, 0x54, 0x56, 0x32, 0x54, 0x41, 0x47 +}; + +#endif \ No newline at end of file diff --git a/drivers/input/touchscreen/ist3038c/Makefile b/drivers/input/touchscreen/ist3038c/Makefile new file mode 100644 index 000000000000..c8927f5ac3dd --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the Imagis touch driver +# + +# Each configuration option enables a list of files. + +obj-$(CONFIG_TOUCHSCREEN_IST3038C) += ist30xxc.o ist30xxc_misc.o ist30xxc_sys.o ist30xxc_update.o ist30xxc_tracking.o ist30xxc_cmcs.o diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc.c b/drivers/input/touchscreen/ist3038c/ist30xxc.c new file mode 100644 index 000000000000..b485ab5ea1be --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc.c @@ -0,0 +1,2341 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_OF +#include +#include +#include +#endif + +#if defined(CONFIG_FB) +#include +#include +#endif + + + +#include "ist30xxc.h" +#include "ist30xxc_update.h" + +#ifdef IST30XX_TRACKING_MODE +#include "ist30xxc_tracking.h" +#endif + +#ifdef IST30XX_DEBUG +#include "ist30xxc_misc.h" +#endif + +#ifdef IST30XX_CMCS_TEST +#include "ist30xxc_cmcs.h" +#endif + +#ifdef IST30XX_USE_KEY +int ist30xx_key_code[] = IST30XX_KEY_CODES; +#ifdef IST30XX_USE_KEY_COORD +int ist30xx_key_x[] = KEY_COORD_X; +#endif +#endif + +struct ist30xx_data *ts_data; +extern int set_usb_charge_mode_par; +int ist30xx_log_level = IST30XX_LOG_LEVEL; + +void tsp_printk(int level, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + if (ist30xx_log_level < level) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + printk("%s %pV", IST30XX_LOG_TAG, &vaf); + + va_end(args); +} + +long get_milli_second(struct ist30xx_data *data) +{ + ktime_get_ts(&data->t_current); + + return data->t_current.tv_sec * 1000 + data->t_current.tv_nsec / 1000000; +} + +void ist30xx_delay(unsigned int ms) +{ + if (ms < 20) + usleep_range(ms * 1000, ms * 1000); + else + msleep(ms); +} + +int ist30xx_intr_wait(struct ist30xx_data *data, long ms) +{ + long start_ms = get_milli_second(data); + long curr_ms = 0; + + while (1) { + if (!data->irq_working) + break; + + curr_ms = get_milli_second(data); + if ((curr_ms < 0) || (start_ms < 0) || (curr_ms - start_ms > ms)) { + tsp_info("%s() timeout(%dms)\n", __func__, ms); + return -EPERM; + } + + ist30xx_delay(2); + } + return 0; +} + +void ist30xx_disable_irq(struct ist30xx_data *data) +{ + if (likely(data->irq_enabled)) { +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_INTR_DISABLE); +#endif + disable_irq(data->client->irq); + data->irq_enabled = false; + data->status.event_mode = false; + } +} + +void ist30xx_enable_irq(struct ist30xx_data *data) +{ + if (likely(!data->irq_enabled)) { +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_INTR_ENABLE); +#endif + enable_irq(data->client->irq); + ist30xx_delay(10); + data->irq_enabled = true; + data->status.event_mode = true; + } +} + +void ist30xx_scheduled_reset(struct ist30xx_data *data) +{ + if (likely(data->initialized)) + schedule_delayed_work(&data->work_reset_check, 0); +} + +static void ist30xx_request_reset(struct ist30xx_data *data) +{ + data->irq_err_cnt++; + if (unlikely(data->irq_err_cnt >= data->max_irq_err_cnt)) { + tsp_info("%s()\n", __func__); + ist30xx_scheduled_reset(data); + data->irq_err_cnt = 0; + } +} + +#define NOISE_MODE_TA (0) +#define NOISE_MODE_CALL (1) +#define NOISE_MODE_COVER (2) +#define NOISE_MODE_EDGE (4) +#define NOISE_MODE_POWER (8) +void ist30xx_start(struct ist30xx_data *data) +{ + if (data->initialized) { + data->scan_count = 0; + data->scan_retry = 0; + mod_timer(&data->event_timer, + get_jiffies_64() + EVENT_TIMER_INTERVAL * 2); + } + + data->ignore_delay = true; + + /* TA mode */ + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_MODE_SPECIAL << 16) | (data->noise_mode & 0xFFFF))); + + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_LOCAL_MODEL << 16) | (TSP_LOCAL_CODE & 0xFFFF))); + + if (data->report_rate >= 0) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_TIME_ACTIVE << 16) | (data->report_rate & 0xFFFF))); + tsp_info("%s: active rate : %dus\n", __func__, data->report_rate); + } + + if (data->idle_rate >= 0) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_TIME_IDLE << 16) | (data->idle_rate & 0xFFFF))); + tsp_info("%s: idle rate : %dus\n", __func__, data->idle_rate); + } + + if (data->rec_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (IST30XX_ENABLE & 0xFFFF)); + tsp_info("%s: rec mode start\n", __func__); + } + + if (data->debugging_mode) { + data->debugging_scancnt = 0; + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_DBG_MODE << 16) | (IST30XX_ENABLE & 0xFFFF)); + tsp_info("%s: debugging mode start\n", __func__); + } + + if (data->debug_mode || data->rec_mode || data->debugging_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_DISABLE & 0xFFFF)); + tsp_info("%s: nosleep mode start\n", __func__); + } + + ist30xx_cmd_start_scan(data); + + data->ignore_delay = false; + + if (data->rec_mode) { + ist30xx_delay(100); + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (IST30XX_START_SCAN & 0xFFFF)); + } + + tsp_info("%s, local : %d, mode : 0x%x\n", __func__, TSP_LOCAL_CODE & 0xFFFF, + data->noise_mode & 0xFFFF); +} + +int ist30xx_get_ver_info(struct ist30xx_data *data) +{ + int ret; + + data->fw.prev.main_ver = data->fw.cur.main_ver; + data->fw.prev.fw_ver = data->fw.cur.fw_ver; + data->fw.prev.core_ver = data->fw.cur.core_ver; + data->fw.prev.test_ver = data->fw.cur.test_ver; +#ifdef XIAOMI_PRODUCT + data->fw.prev.lockdown[0] = data->fw.cur.lockdown[0]; + data->fw.prev.lockdown[1] = data->fw.cur.lockdown[1]; + data->fw.prev.config[0] = data->fw.cur.config[0]; + data->fw.prev.config[1] = data->fw.cur.config[1]; +#endif + data->fw.cur.main_ver = 0; + data->fw.cur.fw_ver = 0; + data->fw.cur.core_ver = 0; + data->fw.cur.test_ver = 0; +#ifdef XIAOMI_PRODUCT + data->fw.cur.lockdown[0] = 0; + data->fw.cur.lockdown[1] = 0; + data->fw.cur.config[0] = 0; + data->fw.cur.config[1] = 0; +#endif + + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret)) + return ret; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_VER_MAIN), + &data->fw.cur.main_ver); + if (unlikely(ret)) + goto err_get_ver; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_VER_FW), + &data->fw.cur.fw_ver); + if (unlikely(ret)) + goto err_get_ver; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_VER_CORE), + &data->fw.cur.core_ver); + if (unlikely(ret)) + goto err_get_ver; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_VER_TEST), + &data->fw.cur.test_ver); + if (unlikely(ret)) + goto err_get_ver; + +#ifdef XIAOMI_PRODUCT + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_LOCKDOWN_1), + &data->fw.cur.lockdown[0]); + if (unlikely(ret)) + goto err_get_ver; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_LOCKDOWN_2), + &data->fw.cur.lockdown[1]); + if (unlikely(ret)) + goto err_get_ver; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_CONFIG_1), + &data->fw.cur.config[0]); + if (unlikely(ret)) + goto err_get_ver; + + ret = ist30xx_read_reg(data->client, IST30XX_DA_ADDR(eHCOM_GET_CONFIG_2), + &data->fw.cur.config[1]); + if (unlikely(ret)) + goto err_get_ver; +#endif + + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (unlikely(ret)) + goto err_get_ver; + + tsp_info("IC version main: %x, fw: %x, test: %x, core: %x\n", + data->fw.cur.main_ver, data->fw.cur.fw_ver, data->fw.cur.test_ver, + data->fw.cur.core_ver); +#ifdef XIAOMI_PRODUCT + if (data->lockdown_upper != 0) + data->fw.cur.lockdown[0] = data->lockdown_upper; + + tsp_info("lockdown: %08X%08X, config: %08X%08X\n", + data->fw.cur.lockdown[0], data->fw.cur.lockdown[1], + data->fw.cur.config[0], data->fw.cur.config[1]); +#endif + + return 0; + +err_get_ver: + ist30xx_reset(data, false); + + return ret; +} + +#if defined(IST30XX_GESTURE) +#define WAKEUP_OFF 4 +#define WAKEUP_ON 5 +bool ist30xx_gesture_func_on = true; +static int ist30xx_gesture_switch(struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + if (type == EV_SYN && code == SYN_CONFIG) { + if (value == WAKEUP_OFF) { + ist30xx_gesture_func_on = false; + } else if (value == WAKEUP_ON) { + ist30xx_gesture_func_on = true; + } + } + return 0; +} +#endif + +int ist30xx_set_input_device(struct ist30xx_data *data) +{ + int ret; + data->input_dev->name = "ist30xx_ts_input"; + data->input_dev->id.bustype = BUS_I2C; + data->input_dev->dev.parent = &data->client->dev; + + input_mt_init_slots(data->input_dev, IST30XX_MAX_FINGERS, 0); + + set_bit(EV_ABS, data->input_dev->evbit); + set_bit(INPUT_PROP_DIRECT, data->input_dev->propbit); + + input_set_abs_params(data->input_dev, ABS_MT_POSITION_X, 0, + data->tsp_info.width - 1, 0, 0); + input_set_abs_params(data->input_dev, ABS_MT_POSITION_Y, 0, + data->tsp_info.height - 1, 0, 0); +#ifdef IST30XX_USE_3D_TOUCH + input_set_abs_params(data->input_dev, ABS_MT_PRESSURE, 0, + IST30XX_MAX_3D_VALUE, 0, 0); +#else + input_set_abs_params(data->input_dev, ABS_MT_TOUCH_MAJOR, 0, + IST30XX_MAX_W, 0, 0); +#endif + +#if (defined(IST30XX_USE_KEY) || defined(IST30XX_GESTURE) || \ + defined(IST30XX_SURFACE_TOUCH) || defined(IST30XX_BLADE_TOUCH)) + set_bit(EV_KEY, data->input_dev->evbit); + set_bit(EV_SYN, data->input_dev->evbit); +#endif +#ifdef IST30XX_USE_KEY + { + int i; + for (i = 0; i < ARRAY_SIZE(ist30xx_key_code); i++) + set_bit(ist30xx_key_code[i], data->input_dev->keybit); + } +#endif +#ifdef IST30XX_GESTURE + input_set_capability(data->input_dev, EV_KEY, KEY_WAKEUP); + tsp_info("regist gesture key!\n"); + data->input_dev->event = ist30xx_gesture_switch; +#endif +#ifdef IST30XX_SURFACE_TOUCH + input_set_capability(data->input_dev, EV_KEY, KEY_MUTE); +#endif +#ifdef IST30XX_BLADE_TOUCH + input_set_capability(data->input_dev, EV_KEY, KEY_SYSRQ); +#endif + + input_set_drvdata(data->input_dev, data); + ret = input_register_device(data->input_dev); + + tsp_info("%s: input register device:%d\n", __func__, ret); + + return ret; +} + +#define CALIB_MSG_MASK (0xF0000FFF) +#define CALIB_MSG_VALID (0x80000CAB) +#define CAL_REF_MSG_MASK (0xFF0000FF) +#define CAL_REF_MSG_VALID (0xAA000055) +#define TRACKING_INTR_VALID (0x127EA597) +#define TRACKING_INTR_DEBUG1_VALID (0x127A6E81) +#define TRACKING_INTR_DEBUG2_VALID (0x127A6E82) +#define TRACKING_INTR_DEBUG3_VALID (0x127A6E83) +int ist30xx_get_info(struct ist30xx_data *data) +{ + int ret; + u32 calib_msg; +#ifdef IST30XX_TRACKING_MODE + u32 tracking_value; + u32 ms; +#endif + + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + +#ifdef IST30XX_INTERNAL_BIN + ist30xx_get_tsp_info(data); +#else + ret = ist30xx_get_ver_info(data); + if (unlikely(ret)) + goto err_get_info; + + ret = ist30xx_get_tsp_info(data); + if (unlikely(ret)) + goto err_get_info; +#endif /* IST30XX_INTERNAL_BIN */ + + ret = ist30xx_set_input_device(data); + if (unlikely(ret)) + goto err_get_info; + + ist30xx_print_info(data); + +#ifndef IST30XX_UPDATE_NO_CAL + if (data->fw_mode == IST30XX_CAL_MODE) { + ret = ist30xx_read_cmd(data, eHCOM_GET_CAL_RESULT, &calib_msg); + if (likely(ret == 0)) { + tsp_info("calib status: 0x%08x\n", calib_msg); +#ifdef IST30XX_TRACKING_MODE + ms = get_milli_second(data); + tracking_value = TRACKING_INTR_VALID; + ist30xx_put_track_ms(ms); + ist30xx_put_track(&tracking_value, 1); + ist30xx_put_track(&calib_msg, 1); +#endif + if ((calib_msg & CALIB_MSG_MASK) != CALIB_MSG_VALID || + CALIB_TO_STATUS(calib_msg) > 0) { + ist30xx_calibrate(data, IST30XX_MAX_RETRY_CNT); + } + } + } +#endif + +#ifdef IST30XX_CHECK_CALIB + if (data->fw_mode == IST30XX_CAL_MODE) { + if ((!data->status.update) && (!data->status.calib != 1)) { + ret = ist30xx_cmd_check_calib(data); + if (likely(!ret)) { + data->status.calib = 2; + data->status.calib_msg = 0; + data->event_ms = (u32)get_milli_second(data); + data->status.event_mode = true; + } + } + } +#endif + + ist30xx_enable_irq(data); + mutex_unlock(&data->lock); + + return 0; + +err_get_info: + mutex_unlock(&data->lock); + + return ret; +} + +#if (defined(IST30XX_GESTURE) || defined(IST30XX_SURFACE_TOUCH) || \ + defined(IST30XX_BLADE_TOUCH)) +#define SPECIAL_MAGIC_STRING (0x4170CF00) +#define SPECIAL_MAGIC_MASK (0xFFFFFF00) +#define SPECIAL_MESSAGE_MASK (~SPECIAL_MAGIC_MASK) +#define PARSE_SPECIAL_MESSAGE(n) \ + ((n & SPECIAL_MAGIC_MASK) == SPECIAL_MAGIC_STRING ? \ + (n & SPECIAL_MESSAGE_MASK) : -EINVAL) +#define SPECIAL_START_MASK (0x80) +#define SPECIAL_SUCCESS_MASK (0x0F) +#define MAX_LK_KEYCODE_NUM (256) +static unsigned short lk_keycode[MAX_LK_KEYCODE_NUM] = { + [0x01] = KEY_WAKEUP, + [0x02] = KEY_PLAYPAUSE, + [0x03] = KEY_NEXTSONG, + [0x04] = KEY_PREVIOUSSONG, + [0x05] = KEY_VOLUMEUP, + [0x06] = KEY_VOLUMEDOWN, + [0x07] = KEY_MUTE, + [0x21] = KEY_MUTE, + [0x11] = KEY_SYSRQ, + [0x12] = KEY_SYSRQ, + [0x13] = KEY_SYSRQ, + [0x14] = KEY_SYSRQ, + [0x41] = KEY_A, + [0x42] = KEY_B, + [0x43] = KEY_C, + [0x44] = KEY_D, + [0x45] = KEY_E, + [0x46] = KEY_F, + [0x47] = KEY_G, + [0x48] = KEY_H, + [0x49] = KEY_I, + [0x4A] = KEY_J, + [0x4B] = KEY_K, + [0x4C] = KEY_L, + [0x4D] = KEY_M, + [0x4E] = KEY_N, + [0x4F] = KEY_O, + [0x50] = KEY_P, + [0x51] = KEY_Q, + [0x52] = KEY_R, + [0x53] = KEY_S, + [0x54] = KEY_T, + [0x55] = KEY_U, + [0x56] = KEY_V, + [0x57] = KEY_W, + [0x58] = KEY_X, + [0x59] = KEY_Y, + [0x5A] = KEY_Z, + [0x91] = KEY_KP1, + [0x92] = KEY_VOLUMEDOWN, + [0x93] = KEY_KP3, + [0x94] = KEY_PREVIOUSSONG, + [0x95] = KEY_KP5, + [0x96] = KEY_NEXTSONG, + [0x97] = KEY_KP7, + [0x98] = KEY_VOLUMEUP, + [0x99] = KEY_KP9, +}; + +void ist30xx_special_cmd(struct ist30xx_data *data, int cmd) +{ +#ifdef IST30XX_GESTURE + if (cmd == 0x22) { + tsp_info("Double Tap Gesture\n"); + input_report_key(data->input_dev, KEY_WAKEUP, 1); + input_sync(data->input_dev); + input_report_key(data->input_dev, KEY_WAKEUP, 0); + input_sync(data->input_dev); + + return; + } + if (((cmd > 0x40) && (cmd < 0x5B)) || ((cmd > 0x90) && (cmd < 0x9A))) { + tsp_info("Gesture touch: 0x%02X\n", cmd); + + if ((cmd != 0x92) && (cmd != 0x94) && (cmd != 0x96) && (cmd != 0x98)) { + input_report_key(data->input_dev, KEY_WAKEUP, 1); + input_sync(data->input_dev); + input_report_key(data->input_dev, KEY_WAKEUP, 0); + input_sync(data->input_dev); + + ist30xx_delay(500); + } + + input_report_key(data->input_dev, lk_keycode[cmd], 1); + input_sync(data->input_dev); + input_report_key(data->input_dev, lk_keycode[cmd], 0); + input_sync(data->input_dev); + + return; + } +#endif +#ifdef IST30XX_SURFACE_TOUCH + if (((cmd & (~SPECIAL_START_MASK)) >= 0x20) && + ((cmd & (~SPECIAL_START_MASK)) <= 0x21)) { + if (cmd & SPECIAL_START_MASK) { + tsp_info("Surface touch start: 0x%02X\n", cmd); + } else { + if ((cmd & SPECIAL_SUCCESS_MASK) > 0) { + tsp_info("Surface touch stop: 0x%02X\n", cmd); + input_report_key(data->input_dev, lk_keycode[cmd], 1); + input_sync(data->input_dev); + input_report_key(data->input_dev, lk_keycode[cmd], 0); + input_sync(data->input_dev); + } else { + tsp_info("Surface touch cancel: 0x%02X\n", cmd); + } + } + + return; + } +#endif +#ifdef IST30XX_BLADE_TOUCH + if (((cmd & (~SPECIAL_START_MASK)) >= 0x10) && + ((cmd & (~SPECIAL_START_MASK)) <= 0x14)) { + if (cmd & SPECIAL_START_MASK) { + tsp_info("Blade touch start: 0x%02X\n", cmd); + } else { + if ((cmd & SPECIAL_SUCCESS_MASK) > 0) { + tsp_info("Blade touch stop: 0x%02X\n", cmd); + input_report_key(data->input_dev, lk_keycode[cmd], 1); + input_sync(data->input_dev); + input_report_key(data->input_dev, lk_keycode[cmd], 0); + input_sync(data->input_dev); + } else { + tsp_info("Blade touch cancel: 0x%02X\n", cmd); + } + } + + return; + } +#endif + + tsp_warn("Not support gesture cmd: 0x%02X\n", cmd); +} +#endif + +#define PRESS_MSG_MASK (0x01) +#define MULTI_MSG_MASK (0x02) +#define TOUCH_DOWN_MESSAGE ("p") +#define TOUCH_UP_MESSAGE ("r") +#define TOUCH_MOVE_MESSAGE (" ") +void print_tsp_event(struct ist30xx_data *data, int id, finger_info *finger) +{ + bool press; + + press = PRESSED_FINGER(data->t_status, id); + + if (press) { + if (data->tsp_touched[id] == false) { + /* touch down */ +#ifdef IST30XX_USE_3D_TOUCH + tsp_noti("%s%d (%d, %d)(f:%d)\n", TOUCH_DOWN_MESSAGE, id + 1, + finger->bit_field.x, finger->bit_field.y, + finger->bit_field.f); +#else + tsp_noti("%s%d (%d, %d)\n", TOUCH_DOWN_MESSAGE, id + 1, + finger->bit_field.x, finger->bit_field.y); +#endif + data->tsp_touched[id] = true; + } else { + /* touch move */ +#ifdef IST30XX_USE_3D_TOUCH + tsp_debug("%s%d (%d, %d)(f:%d)\n", TOUCH_MOVE_MESSAGE, id + 1, + finger->bit_field.x, finger->bit_field.y, + finger->bit_field.f); +#else + tsp_debug("%s%d (%d, %d)\n", TOUCH_MOVE_MESSAGE, id + 1, + finger->bit_field.x, finger->bit_field.y); +#endif + } + } else { + if (data->tsp_touched[id] == true) { + /* touch up */ + tsp_noti("%s%d\n", TOUCH_UP_MESSAGE, id + 1); + data->tsp_touched[id] = false; + } + } +} +#ifdef IST30XX_USE_KEY +#define PRESS_MSG_KEY (0x06) +void print_tkey_event(struct ist30xx_data *data, int id) +{ + bool press = PRESSED_KEY(data->t_status, id); + + if (press) { + if (data->tkey_pressed[id] == false) { + /* tkey down */ + tsp_noti("k %s%d\n", TOUCH_DOWN_MESSAGE, id + 1); + data->tkey_pressed[id] = true; + } + } else { + if (data->tkey_pressed[id] == true) { + /* tkey up */ + tsp_noti("k %s%d\n", TOUCH_UP_MESSAGE, id + 1); + data->tkey_pressed[id] = false; + } + } +} +#endif +static void release_finger(struct ist30xx_data *data, int id) +{ + input_mt_slot(data->input_dev, id); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false); + +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_POS_FINGER + id + 1); +#endif + tsp_info("forced touch release: %d\n", id + 1); + + data->tsp_touched[id] = false; + if (data->debugging_mode && (id < 2)) + data->t_frame[id] = 0; + + input_sync(data->input_dev); +} + +#ifdef IST30XX_USE_KEY +static void release_key(struct ist30xx_data *data, int id) +{ + input_report_key(data->input_dev, ist30xx_key_code[id], false); + +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_POS_KEY + id + 1); +#endif + tsp_info("forced key release: %d\n", id + 1); + + data->tkey_pressed[id] = false; + + input_sync(data->input_dev); +} +#endif +static void clear_input_data(struct ist30xx_data *data) +{ + int id = 0; + u32 status; + + status = PARSE_FINGER_STATUS(data->t_status); + while (status) { + if (status & 1) + release_finger(data, id); + status >>= 1; + id++; + } +#ifdef IST30XX_USE_KEY + id = 0; + status = PARSE_KEY_STATUS(data->t_status); + while (status) { + if (status & 1) + release_key(data, id); + status >>= 1; + id++; + } +#endif + + data->t_status = 0; +} + +static int check_valid_coord(u32 *msg, int cnt) +{ + u8 *buf = (u8 *)msg; + u8 chksum1 = msg[0] >> 24; + u8 chksum2 = 0; + u32 tmp = msg[0]; + + msg[0] &= 0x00FFFFFF; + + cnt *= IST30XX_DATA_LEN; + + while (cnt--) + chksum2 += *buf++; + + msg[0] = tmp; + + if (chksum1 != chksum2) { + tsp_err("intr chksum: %02x, %02x\n", chksum1, chksum2); + return -EPERM; + } + + return 0; +} + +static void report_input_data(struct ist30xx_data *data, int finger_counts, + int key_counts) +{ + int id; + bool press = false; + finger_info *fingers = (finger_info *)data->fingers; + + int idx = 0; + u32 status; + + memset(data->t_frame, 0, sizeof(data->t_frame)); + + status = PARSE_FINGER_STATUS(data->t_status); + for (id = 0; id < IST30XX_MAX_FINGERS; id++) { + press = (status & (1 << id)) ? true : false; + + input_mt_slot(data->input_dev, id); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, press); + + print_tsp_event(data, id, &fingers[idx]); + + if (press == false) + continue; + + if (data->debugging_mode && (id < 2)) + data->t_frame[id] = fingers[idx].full_field; + + input_report_abs(data->input_dev, ABS_MT_POSITION_X, + fingers[idx].bit_field.x); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, + fingers[idx].bit_field.y); +#ifdef IST30XX_USE_3D_TOUCH + input_report_abs(data->input_dev, ABS_MT_PRESSURE, + fingers[idx].bit_field.f); +#else + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, + fingers[idx].bit_field.w); +#endif + idx++; + } + +#ifdef IST30XX_USE_KEY + status = PARSE_KEY_STATUS(data->t_status); + for (id = 0; id < ARRAY_SIZE(ist30xx_key_code); id++) { + press = (status & (1 << id)) ? true : false; + + input_report_key(data->input_dev, ist30xx_key_code[id], press); + + print_tkey_event(data, id); + } +#endif + + data->irq_err_cnt = 0; + data->scan_retry = 0; + + input_sync(data->input_dev); +} + +void recording_data(struct ist30xx_data *data, bool idle) +{ + int ret; + int i; + int count = 0; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + u32 addr = 0; + u32 len; + u32 *buf32; + const int msg_len = 128; + char msg[msg_len]; + char *buf; + TSP_INFO *tsp = &data->tsp_info; + + if (idle && (data->rec_mode > 1)) + goto state_idle; + + ist30xx_delay(data->rec_delay); + + buf32 = kzalloc(IST30XX_MAX_NODE_NUM * sizeof(u32), GFP_KERNEL); + buf = kzalloc(IST30XX_MAX_NODE_NUM * 20, GFP_KERNEL); + + for (i = data->rec_start_ch.tx; i <= data->rec_stop_ch.tx; i++) { + addr = ((i * tsp->ch_num.rx + data->rec_start_ch.rx) * IST30XX_DATA_LEN) + + IST30XX_DA_ADDR(data->raw_addr); + len = data->rec_stop_ch.rx - data->rec_start_ch.rx + 1; + ret = ist30xx_burst_read(data->client, addr, + buf32 + (i * tsp->ch_num.rx + data->rec_start_ch.rx), len, + true); + if (ret) + goto err_rec_fail; + } + + for (i = 0; i < IST30XX_MAX_NODE_NUM; i++) { + count += snprintf(msg, msg_len, "%08x ", buf32[i]); + strncat(buf, msg, msg_len); + } + + for (i = 0; i < IST30XX_MAX_NODE_NUM; i++) { + count += snprintf(msg, msg_len, "%08x ", 0); + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + + old_fs = get_fs(); + set_fs(get_ds()); + + fp = filp_open(data->rec_file_name, O_CREAT|O_WRONLY|O_APPEND, 0); + if (IS_ERR(fp)) { + tsp_err("file %s open error:%d\n", data->rec_file_name, PTR_ERR(fp)); + goto err_file_open; + } + + fp->f_op->write(fp, buf, count, &fp->f_pos); + fput(fp); + + filp_close(fp, NULL); + +err_file_open: + set_fs(old_fs); + +err_rec_fail: + kfree(buf32); + kfree(buf); + +state_idle: + data->ignore_delay = true; + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (IST30XX_START_SCAN & 0xFFFF)); + data->ignore_delay = false; +} + +static void cal_ref_work_func(struct work_struct *work) +{ + struct delayed_work *delayed_work = to_delayed_work(work); + struct ist30xx_data *data = container_of(delayed_work, struct ist30xx_data, + work_cal_reference); + + mutex_lock(&data->lock); + ist30xx_reset(data, false); + ist30xx_cal_reference(data); + mutex_unlock(&data->lock); + + data->cal_ref_count++; +} + +void ist30xx_scheduled_cal_ref(struct ist30xx_data *data) +{ + if (data->initialized) + schedule_delayed_work(&data->work_cal_reference, 0); +} + +/* + * CMD : CMD_GET_COORD + * + * 1st [31:24] [23:21] [20:16] [15:12] [11:10] [9:0] + * Checksum KeyCnt KeyStatus FingerCnt Rsvd. FingerStatus + * 2nd [31:28] [27:24] [23:12] [11:0] + * ID Area X Y + */ +static irqreturn_t ist30xx_irq_thread(int irq, void *ptr) +{ + int i, ret; + int key_cnt, finger_cnt, read_cnt; + struct ist30xx_data *data = (struct ist30xx_data *)ptr; + int offset = 1; + u32 t_status; + u32 msg[IST30XX_MAX_FINGERS * 2 + offset]; + u32 *buf32; + u32 debugBuf32[IST30XX_MAX_DEBUGINFO / IST30XX_DATA_LEN]; +#ifdef IST30XX_TRACKING_MODE + u32 tracking_value; +#endif + u32 ms; + u32 touch[2]; + u32 result; + bool idle = false; + + data->irq_working = true; + + if (unlikely(!data->irq_enabled)) + goto irq_ignore; + + ms = get_milli_second(data); + + if (data->debugging_mode) { + ist30xx_burst_read(data->client, + IST30XX_DA_ADDR(data->debugging_addr), debugBuf32, + data->debugging_size / IST30XX_DATA_LEN, true); + } + +#ifdef IST30XX_DEBUG + if (data->intr_debug1_size > 0) { + buf32 = kzalloc(data->intr_debug1_size * sizeof(u32), GFP_KERNEL); + tsp_debug("Intr_debug1 (addr: 0x%08x)\n", data->intr_debug1_addr); + ist30xx_burst_read(data->client, + IST30XX_DA_ADDR(data->intr_debug1_addr), buf32, + data->intr_debug1_size, true); + + for (i = 0; i < data->intr_debug1_size; i++) + tsp_debug("\t%08x\n", buf32[i]); +#ifdef IST30XX_TRACKING_MODE + tracking_value = TRACKING_INTR_DEBUG1_VALID; + ist30xx_put_track_ms(ms); + ist30xx_put_track(&tracking_value, 1); + ist30xx_put_track(buf32, data->intr_debug1_size); +#endif + kfree(buf32); + } + + if (data->intr_debug2_size > 0) { + buf32 = kzalloc(data->intr_debug2_size * sizeof(u32), GFP_KERNEL); + tsp_debug("Intr_debug2 (addr: 0x%08x)\n", data->intr_debug2_addr); + ist30xx_burst_read(data->client, + IST30XX_DA_ADDR(data->intr_debug2_addr), buf32, + data->intr_debug2_size, true); + + for (i = 0; i < data->intr_debug2_size; i++) + tsp_debug("\t%08x\n", buf32[i]); +#ifdef IST30XX_TRACKING_MODE + tracking_value = TRACKING_INTR_DEBUG2_VALID; + ist30xx_put_track_ms(ms); + ist30xx_put_track(&tracking_value, 1); + ist30xx_put_track(buf32, data->intr_debug2_size); +#endif + kfree(buf32); + } +#endif + memset(msg, 0, sizeof(msg)); + + ret = ist30xx_read_reg(data->client, IST30XX_HIB_INTR_MSG, msg); + if (unlikely(ret)) + goto irq_err; + + tsp_verb("intr msg: 0x%08x\n", *msg); + + /* TSP End Initial */ + if (unlikely(*msg == IST30XX_INITIAL_VALUE)) { + tsp_debug("End Initial\n"); + goto irq_event; + } + + /* TSP Recording */ + if (unlikely(*msg == IST30XX_REC_VALUE)) { + idle = true; + goto irq_end; + } + + /* TSP Debugging */ + if (unlikely(*msg == IST30XX_DEBUGGING_VALUE)) + goto irq_end; + + /* TSP IC Exception */ + if (unlikely((*msg & IST30XX_EXCEPT_MASK) == IST30XX_EXCEPT_VALUE)) { + tsp_err("Occured IC exception(0x%02X)\n", *msg & 0xFF); + ret = ist30xx_burst_read(data->client, IST30XX_HIB_COORD, + &msg[offset], IST30XX_MAX_EXCEPT_SIZE, true); + if (unlikely(ret)) + tsp_err(" exception value read error(%d)\n", ret); + else + tsp_err(" exception value : 0x%08X, 0x%08X\n", msg[1], msg[2]); + + goto irq_ic_err; + } + + if (unlikely(*msg == 0 || *msg == 0xFFFFFFFF)) /* Unknown CMD */ + goto irq_err; + +#ifdef IST30XX_TRACKING_MODE + tracking_value = TRACKING_INTR_VALID; + ist30xx_put_track_ms(ms); + ist30xx_put_track(&tracking_value, 1); + ist30xx_put_track(msg, 1); +#endif + + if (unlikely((*msg & CALIB_MSG_MASK) == CALIB_MSG_VALID)) { + data->status.calib_msg = *msg; + tsp_info("calib status: 0x%08X\n", data->status.calib_msg); + + goto irq_event; + } + + if (unlikely((*msg & CAL_REF_MSG_MASK) == CAL_REF_MSG_VALID)) { + data->status.cal_ref_msg = *msg; + tsp_info("cal ref status: 0x%08X\n", data->status.cal_ref_msg); + if ((data->status.update != 1) && (data->status.calib == 0)) { + if (data->cal_ref_count < IST30XX_MAX_CAL_REF_CNT) { + result = CAL_REF_TO_STATUS(data->status.cal_ref_msg); + if ((result & CAL_REF_NONE) || + (result & CAL_REF_FAIL_UNKNOWN) || + (result & CAL_REF_FAIL_CRC) || + (result & CAL_REF_FAIL_VERIFY)) + ist30xx_scheduled_cal_ref(data); + } + } + + goto irq_event; + } + +#ifdef IST30XX_CMCS_TEST + if (((*msg & CMCS_MSG_MASK) == CM_MSG_VALID) || + ((*msg & CMCS_MSG_MASK) == CM2_MSG_VALID) || + ((*msg & CMCS_MSG_MASK) == CS_MSG_VALID) || + ((*msg & CMCS_MSG_MASK) == CMJIT_MSG_VALID) || + ((*msg & CMCS_MSG_MASK) == INT_MSG_VALID)) { + data->status.cmcs = *msg; + tsp_info("CMCS notify: 0x%08X\n", *msg); + + goto irq_event; + } +#endif + +#if (defined(IST30XX_GESTURE) || defined(IST30XX_SURFACE_TOUCH) || \ + defined(IST30XX_BLADE_TOUCH)) + if (ist30xx_gesture_func_on) { + ret = PARSE_SPECIAL_MESSAGE(*msg); + if (unlikely(ret > 0)) { + tsp_verb("special cmd: %d (0x%08X)\n", ret, *msg); + ist30xx_special_cmd(data, ret); + + goto irq_event; + } + } +#endif + + memset(data->fingers, 0, sizeof(data->fingers)); + + /* Unknown interrupt data for extend coordinate */ + if (unlikely(!CHECK_INTR_STATUS(*msg))) + goto irq_err; + + t_status = *msg; + key_cnt = PARSE_KEY_CNT(t_status); + finger_cnt = PARSE_FINGER_CNT(t_status); + + if (unlikely((finger_cnt > data->max_fingers) || + (key_cnt > data->max_keys))) { + tsp_warn("Invalid touch count - finger: %d(%d), key: %d(%d)\n", + finger_cnt, data->max_fingers, key_cnt, data->max_keys); + goto irq_err; + } + + if (finger_cnt > 0) { + ret = ist30xx_burst_read(data->client, IST30XX_HIB_COORD, &msg[offset], + finger_cnt, true); + if (unlikely(ret)) + goto irq_err; + + for (i = 0; i < finger_cnt; i++) + data->fingers[i].full_field = msg[i + offset]; + +#ifdef IST30XX_TRACKING_MODE + ist30xx_put_track(msg + offset, finger_cnt); +#endif + for (i = 0; i < finger_cnt; i++) { + tsp_verb("intr msg(%d): 0x%08x, %d\n", + i + offset, msg[i + offset], data->z_values[i]); + } + } + + read_cnt = finger_cnt + 1; + + ret = check_valid_coord(&msg[0], read_cnt); + if (unlikely(ret)) + goto irq_err; + + data->t_status = t_status; + report_input_data(data, finger_cnt, key_cnt); + +#ifdef IST30XX_DEBUG + if (data->intr_debug3_size > 0) { + buf32 = kzalloc(data->intr_debug3_size * sizeof(u32), GFP_KERNEL); + tsp_debug("Intr_debug3 (addr: 0x%08x)\n", data->intr_debug3_addr); + ist30xx_burst_read(data->client, + IST30XX_DA_ADDR(data->intr_debug3_addr), buf32, + data->intr_debug3_size, true); + + for (i = 0; i < data->intr_debug3_size; i++) + tsp_debug("\t%08x\n", buf32[i]); +#ifdef IST30XX_TRACKING_MODE + tracking_value = TRACKING_INTR_DEBUG3_VALID; + ist30xx_put_track_ms(ms); + ist30xx_put_track(&tracking_value, 1); + ist30xx_put_track(buf32, data->intr_debug3_size); +#endif + kfree(buf32); + } +#endif + + goto irq_end; + +irq_err: + tsp_err("intr msg: 0x%08x, ret: %d\n", msg[0], ret); +#ifdef IST30XX_GESTURE + if (!data->suspend) +#endif + ist30xx_request_reset(data); + goto irq_event; +irq_end: + if (data->rec_mode) + recording_data(data, idle); + if (data->debugging_mode) { + if ((data->debugging_scancnt == debugBuf32[0]) && data->debugging_noise) + goto irq_event; + + memset(touch, 0, sizeof(touch)); + touch[0] = data->t_frame[0]; + touch[1] = data->t_frame[1]; + +#ifdef IST30XX_DEBUG + ist30xx_put_frame(data, ms, touch, debugBuf32, + data->debugging_size / IST30XX_DATA_LEN); + data->debugging_scancnt = debugBuf32[0]; +#endif + } +irq_event: +irq_ignore: + data->irq_working = false; + data->event_ms = (u32)get_milli_second(data); + if (data->initialized) + mod_timer(&data->event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); + return IRQ_HANDLED; + +irq_ic_err: + ist30xx_scheduled_reset(data); + data->irq_working = false; + data->event_ms = (u32)get_milli_second(data); + if (data->initialized) + mod_timer(&data->event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); + return IRQ_HANDLED; +} + +static int ist30xx_power_init(struct ist30xx_data *data) +{ + int ret; + + data->vdd = regulator_get(&data->client->dev, "vdd"); + if (IS_ERR(data->vdd)) { + ret = PTR_ERR(data->vdd); + tsp_err("Regulator get failed vdd ret=%d\n", ret); + return ret; + } + + ret = regulator_set_voltage(data->vdd, 2850000, 2850000); + if (ret) { + tsp_err("Regulator set_vtg failed vdd ret=%d\n", ret); + return ret; + } + + data->vddio = regulator_get(&data->client->dev, "vcc_i2c"); + if (IS_ERR(data->vddio)) { + ret = PTR_ERR(data->vddio); + tsp_err("Regulator get failed vcc_i2c ret=%d\n", ret); + return ret; + } + + ret = regulator_set_voltage(data->vddio, 1800000, 1800000); + if (ret) { + tsp_err("Regulator set_vtg failed vcc_i2c ret=%d\n", ret); + return ret; + } + + ret = regulator_enable(data->vdd); + if (ret) { + tsp_err("Regulator vdd enable failed rc=%d\n", ret); + return ret; + } + + ret = regulator_enable(data->vddio); + if (ret) { + tsp_err("Regulator vddio enable failed rc=%d\n", ret); + return ret; + } + + return 0; +} + +static int ist30xx_pinctrl_init(struct ist30xx_data *data) +{ + int ret; + + /* Get pinctrl if target uses pinctrl */ + data->pinctrl = devm_pinctrl_get(&(data->client->dev)); + if (IS_ERR_OR_NULL(data->pinctrl)) { + ret = PTR_ERR(data->pinctrl); + tsp_err("target does not use pinctrl %d\n", ret); + goto err_pinctrl_get; + } + + data->pinctrl_state_active = pinctrl_lookup_state(data->pinctrl, + "pmx_ts_active"); + if (IS_ERR_OR_NULL(data->pinctrl_state_active)) { + ret = PTR_ERR(data->pinctrl_state_active); + tsp_err("can't lookup %s pinstate %d\n", "pmx_ts_active", ret); + goto err_pinctrl_lookup; + } + + data->pinctrl_state_suspend = pinctrl_lookup_state(data->pinctrl, + "pmx_ts_suspend"); + if (IS_ERR_OR_NULL(data->pinctrl_state_suspend)) { + ret = PTR_ERR(data->pinctrl_state_suspend); + tsp_err("can't lookup %s pinstate %d\n", "pmx_ts_suspend", ret); + goto err_pinctrl_lookup; + } + + data->pinctrl_state_release = pinctrl_lookup_state(data->pinctrl, + "pmx_ts_release"); + if (IS_ERR_OR_NULL(data->pinctrl_state_release)) { + ret = PTR_ERR(data->pinctrl_state_release); + tsp_err("can't lookup %s pinstate %d\n", "pmx_ts_release", ret); + goto err_pinctrl_lookup; + } + + return 0; + +err_pinctrl_lookup: + devm_pinctrl_put(data->pinctrl); +err_pinctrl_get: + data->pinctrl = NULL; + + return ret; +} + +static int ist30xx_suspend(struct device *dev) +{ + int ret; + struct i2c_client *client = to_i2c_client(dev); + struct ist30xx_data *data = i2c_get_clientdata(client); + + if (data->debugging_mode) + return 0; + + del_timer(&data->event_timer); + cancel_delayed_work_sync(&data->work_reset_check); +#ifdef IST30XX_NOISE_MODE + cancel_delayed_work_sync(&data->work_noise_protect); +#else +#ifdef IST30XX_FORCE_RELEASE + cancel_delayed_work_sync(&data->work_force_release); +#endif +#endif +#ifdef IST30XX_ALGORITHM_MODE + cancel_delayed_work_sync(&data->work_debug_algorithm); +#endif + cancel_delayed_work_sync(&data->work_cal_reference); + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + ist30xx_internal_suspend(data); + clear_input_data(data); +#ifdef IST30XX_GESTURE + if (ist30xx_gesture_func_on) { + if (data->gesture) { + ist30xx_enable_irq(data); + ist30xx_start(data); + data->status.noise_mode = false; + if (device_may_wakeup(&data->client->dev)) + enable_irq_wake(data->client->irq); + } + } else { +#endif + + if (data->pinctrl) { + ret = pinctrl_select_state(data->pinctrl, data->pinctrl_state_suspend); + if (ret < 0) + tsp_err("cannot get suspend pinctrl state\n"); + } +#ifdef IST30XX_GESTURE + } +#endif + mutex_unlock(&data->lock); + + return 0; +} + +static int ist30xx_resume(struct device *dev) +{ + int ret; + struct i2c_client *client = to_i2c_client(dev); + struct ist30xx_data *data = i2c_get_clientdata(client); + + data->noise_mode |= (1 << NOISE_MODE_POWER); + + if (data->debugging_mode && data->status.power) + return 0; + + mutex_lock(&data->lock); +#ifdef IST30XX_GESTURE + if (ist30xx_gesture_func_on) { + if (data->gesture) { + ist30xx_disable_irq(data); + } + } +#endif + ist30xx_internal_resume(data); + ist30xx_enable_irq(data); + ist30xx_start(data); + +#ifdef IST30XX_GESTURE + + if (ist30xx_gesture_func_on) { + if (data->gesture) { + if (device_may_wakeup(&data->client->dev)) + disable_irq_wake(data->client->irq); + + } + } else { +#endif + + if (data->pinctrl) { + ret = pinctrl_select_state(data->pinctrl, data->pinctrl_state_active); + if (ret < 0) + tsp_err("cannot get active pinctrl state\n"); + } +#ifdef IST30XX_GESTURE + } +#endif + + mutex_unlock(&data->lock); + + return 0; +} + +#ifdef USE_OPEN_CLOSE +static void ist30xx_ts_close(struct input_dev *dev) +{ + struct ist30xx_data *data = input_get_drvdata(dev); + + ist30xx_suspend(&data->client->dev); +} + +static int ist30xx_ts_open(struct input_dev *dev) +{ + struct ist30xx_data *data = input_get_drvdata(dev); + + return ist30xx_resume(&data->client->dev); +} +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void ist30xx_early_suspend(struct early_suspend *h) +{ + struct ist30xx_data *data = container_of(h, struct ist30xx_data, + early_suspend); + + ist30xx_suspend(&data->client->dev); +} + +static void ist30xx_late_resume(struct early_suspend *h) +{ + struct ist30xx_data *data = container_of(h, struct ist30xx_data, + early_suspend); + + ist30xx_resume(&data->client->dev); +} +#endif + +void ist30xx_set_ta_mode(bool mode) +{ + struct ist30xx_data *data = ts_data; + + if (unlikely(mode == ((data->noise_mode >> NOISE_MODE_TA) & 1))) + return; + + pr_err("%s(), mode = %d\n", __func__, mode); + + if (mode) + data->noise_mode |= (1 << NOISE_MODE_TA); + else + data->noise_mode &= ~(1 << NOISE_MODE_TA); + +#ifdef IST30XX_TA_RESET + if (data->initialized) + ist30xx_scheduled_reset(data); +#else + if (data->initialized && data->status.power) + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_MODE_SPECIAL << 16) | (data->noise_mode & 0xFFFF))); +#endif +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(mode ? TRACK_CMD_TACON : TRACK_CMD_TADISCON); +#endif +} +EXPORT_SYMBOL(ist30xx_set_ta_mode); + +void ist30xx_set_edge_mode(int mode) +{ + struct ist30xx_data *data = ts_data; + + tsp_info("%s(), mode = %d\n", __func__, mode); + + if (mode) + data->noise_mode |= (1 << NOISE_MODE_EDGE); + else + data->noise_mode &= ~(1 << NOISE_MODE_EDGE); + + if (data->status.power) + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_MODE_SPECIAL << 16) | (data->noise_mode & 0xFFFF))); +} +EXPORT_SYMBOL(ist30xx_set_edge_mode); + +void ist30xx_set_call_mode(int mode) +{ + struct ist30xx_data *data = ts_data; + + if (unlikely(mode == ((data->noise_mode >> NOISE_MODE_CALL) & 1))) + return; + + tsp_info("%s(), mode = %d\n", __func__, mode); + + if (mode) + data->noise_mode |= (1 << NOISE_MODE_CALL); + else + data->noise_mode &= ~(1 << NOISE_MODE_CALL); + +#ifdef IST30XX_TA_RESET + if (data->initialized) + ist30xx_scheduled_reset(data); +#else + if (data->initialized && data->status.power) + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_MODE_SPECIAL << 16) | (data->noise_mode & 0xFFFF))); +#endif +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(mode ? TRACK_CMD_CALL : TRACK_CMD_NOTCALL); +#endif +} +EXPORT_SYMBOL(ist30xx_set_call_mode); + +void ist30xx_set_cover_mode(int mode) +{ + struct ist30xx_data *data = ts_data; + + if (unlikely(mode == ((data->noise_mode >> NOISE_MODE_COVER) & 1))) + return; + + tsp_info("%s(), mode = %d\n", __func__, mode); + + if (mode) + data->noise_mode |= (1 << NOISE_MODE_COVER); + else + data->noise_mode &= ~(1 << NOISE_MODE_COVER); + +#ifdef IST30XX_TA_RESET + if (data->initialized) + ist30xx_scheduled_reset(data); +#else + if (data->initialized && data->status.power) + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_MODE_SPECIAL << 16) | (data->noise_mode & 0xFFFF))); +#endif +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(mode ? TRACK_CMD_COVER : TRACK_CMD_NOTCOVER); +#endif +} +EXPORT_SYMBOL(ist30xx_set_cover_mode); + +#ifdef USE_TSP_TA_CALLBACKS +void charger_enable(struct tsp_callbacks *cb, int enable) +{ + bool charging = enable ? true : false; + + ist30xx_set_ta_mode(charging); +} + +static void ist30xx_register_callback(struct tsp_callbacks *cb) +{ + charger_callbacks = cb; + pr_info("%s\n", __func__); +} +#endif + +static void reset_work_func(struct work_struct *work) +{ + struct delayed_work *delayed_work = to_delayed_work(work); + struct ist30xx_data *data = container_of(delayed_work, struct ist30xx_data, + work_reset_check); + + if (unlikely((data == NULL) || (data->client == NULL))) + return; + + tsp_info("Request reset function\n"); + + if (likely((data->initialized == 1) && (data->status.power == 1) && + (data->status.update != 1) && (data->status.calib != 1 && + (data->status.calib != 2)))) { + mutex_lock(&data->lock); + ist30xx_disable_irq(data); +#ifdef IST30XX_GESTURE + if (data->suspend) + ist30xx_internal_suspend(data); + else +#endif + ist30xx_reset(data, false); + clear_input_data(data); + ist30xx_enable_irq(data); + ist30xx_start(data); +#ifdef IST30XX_GESTURE + if (data->gesture && data->suspend) + data->status.noise_mode = false; +#endif + mutex_unlock(&data->lock); + } +} + +#ifdef IST30XX_INTERNAL_BIN +#ifdef IST30XX_UPDATE_BY_WORKQUEUE +static void fw_update_func(struct work_struct *work) +{ + int ret; + struct delayed_work *delayed_work = to_delayed_work(work); + struct ist30xx_data *data = container_of(delayed_work, + struct ist30xx_data, work_fw_update); + + if (unlikely((data == NULL) || (data->client == NULL))) + return; + + tsp_info("FW update function\n"); + + if (likely(ist30xx_auto_bin_update(data))) { + ist30xx_disable_irq(data); + } else { + ret = ist30xx_get_info(data); + tsp_info("Get info: %s\n", (ret == 0 ? "success" : "fail")); + + ist30xx_start(data); + data->initialized = true; + } +} +#endif +#endif + +#if (defined(IST30XX_NOISE_MODE) || defined(IST30XX_FORCE_RELEASE)) +#define TOUCH_STATUS_MAGIC (0x00000075) +#define TOUCH_STATUS_MASK (0x000000FF) +#define FINGER_ENABLE_MASK (0x00100000) +#define SCAN_CNT_MASK (0xFFE00000) +#define GET_FINGER_ENABLE(n) ((n & FINGER_ENABLE_MASK) >> 20) +#define GET_SCAN_CNT(n) ((n & SCAN_CNT_MASK) >> 21) +#endif +#ifdef IST30XX_NOISE_MODE +static void noise_work_func(struct work_struct *work) +{ + int ret; + u32 touch_status = 0; + u32 scan_count = 0; + struct delayed_work *delayed_work = to_delayed_work(work); + struct ist30xx_data *data = container_of(delayed_work, struct ist30xx_data, + work_noise_protect); + + ret = ist30xx_read_reg(data->client, IST30XX_HIB_TOUCH_STATUS, + &touch_status); + if (unlikely(ret)) { + tsp_warn("Touch status read fail!\n"); + goto retry_timer; + } + +#ifdef IST30XX_TRACKING_MODE + ist30xx_put_track_ms(data->timer_ms); + ist30xx_put_track(&touch_status, 1); +#endif + tsp_verb("Touch Info: 0x%08x\n", touch_status); + + /* Check valid scan count */ + if (unlikely((touch_status & TOUCH_STATUS_MASK) != TOUCH_STATUS_MAGIC)) { + tsp_warn("Touch status is not corrected! (0x%08x)\n", touch_status); + goto retry_timer; + } + + /* Status of IC is idle */ + if (GET_FINGER_ENABLE(touch_status) == 0) { + if ((PARSE_FINGER_CNT(data->t_status) > 0) || + (PARSE_KEY_CNT(data->t_status) > 0)) + clear_input_data(data); + } + + scan_count = GET_SCAN_CNT(touch_status); + + /* Status of IC is lock-up */ + if (unlikely(scan_count == data->scan_count)) { + tsp_warn("TSP IC is not responded! (0x%08x)\n", scan_count); + goto retry_timer; + } + + data->scan_retry = 0; + data->scan_count = scan_count; + return; + +retry_timer: + data->scan_retry++; + tsp_warn("Retry touch status!(%d)\n", data->scan_retry); + + if (unlikely(data->scan_retry == data->max_scan_retry)) { + ist30xx_scheduled_reset(data); + data->scan_retry = 0; + } +} +#else +#ifdef IST30XX_FORCE_RELEASE +static void release_work_func(struct work_struct *work) +{ + int ret; + u32 touch_status = 0; + struct delayed_work *delayed_work = to_delayed_work(work); + struct ist30xx_data *data = container_of(delayed_work, struct ist30xx_data, + work_force_release); + + if ((PARSE_FINGER_CNT(data->t_status) == 0) && + (PARSE_KEY_CNT(data->t_status) == 0)) + return; + + ret = ist30xx_read_reg(data->client, IST30XX_HIB_TOUCH_STATUS, + &touch_status); + if (unlikely(ret)) { + tsp_warn("Touch status read fail!\n"); + return; + } + +#ifdef IST30XX_TRACKING_MODE + ist30xx_put_track_ms(data->timer_ms); + ist30xx_put_track(&touch_status, 1); +#endif + tsp_verb("Touch Info: 0x%08x\n", touch_status); + + /* Check valid scan count */ + if (unlikely((touch_status & TOUCH_STATUS_MASK) != TOUCH_STATUS_MAGIC)) { + tsp_warn("Touch status is not corrected! (0x%08x)\n", touch_status); + return; + } + + /* Status of IC is idle */ + if (GET_FINGER_ENABLE(touch_status) == 0) + clear_input_data(data); +} +#endif +#endif + +#ifdef IST30XX_ALGORITHM_MODE +static void debug_work_func(struct work_struct *work) +{ + int ret = -EPERM; + int i; + u32 *buf32; + + struct delayed_work *delayed_work = to_delayed_work(work); + struct ist30xx_data *data = container_of(delayed_work, + struct ist30xx_data, work_debug_algorithm); + + buf32 = kzalloc(data->algr_size * sizeof(u32), GFP_KERNEL); + ret = ist30xx_burst_read(data->client, IST30XX_DA_ADDR(data->algr_addr), + buf32, data->algr_size, true); + if (ret) { + tsp_warn("Algorithm mem addr read fail!\n"); + return; + } + +#ifdef IST30XX_TRACKING_MODE + ist30xx_put_track(buf32, data->algr_size); +#endif + tsp_info("algorithm struct\n"); + for (i = 0; i < data->algr_size; i++) + tsp_info(" 0x%08x\n", buf32[i]); + + kfree(buf32); +} +#endif + +void timer_handler(unsigned long timer_data) +{ + struct ist30xx_data *data = (struct ist30xx_data *)timer_data; + struct ist30xx_status *status = &data->status; + + if (data->irq_working || !data->initialized || data->rec_mode) + goto restart_timer; + + if (status->event_mode) { + if (likely((status->power == 1) && (status->update != 1) && + (status->calib != 1))) { + data->timer_ms = (u32)get_milli_second(data); + if (unlikely(status->calib == 2)) { + /* Check calibration */ + if ((status->calib_msg & CALIB_MSG_MASK) == CALIB_MSG_VALID) { + tsp_info("Calibration check OK!!\n"); + schedule_delayed_work(&data->work_reset_check, 0); + status->calib = 0; + } else if (data->timer_ms - data->event_ms >= 3000) { + /* over 3 second */ + tsp_info("calibration timeout over 3sec\n"); + schedule_delayed_work(&data->work_reset_check, 0); + status->calib = 0; + } +#ifdef IST30XX_NOISE_MODE + } else if (likely(status->noise_mode)) { + /* 100ms after last interrupt */ + if (data->timer_ms - data->event_ms > 100) + schedule_delayed_work(&data->work_noise_protect, 0); +#else +#ifdef IST30XX_FORCE_RELEASE + } else if (likely(status->noise_mode)) { + /* 100ms after last interrupt */ + if (data->timer_ms - data->event_ms > 100) + schedule_delayed_work(&data->work_force_release, 0); +#endif +#endif + } +#ifdef IST30XX_ALGORITHM_MODE + if (data->algr_size > 0) { + /* 100ms after last interrupt */ + if (data->timer_ms - data->event_ms > 100) + schedule_delayed_work(&data->work_debug_algorithm, 0); + } +#endif + } + } + +restart_timer: + mod_timer(&data->event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); +} + +#ifdef CONFIG_OF +static int ist30xx_request_gpio(struct ist30xx_data *data) +{ + int ret; + + tsp_info("%s\n", __func__); + + if (gpio_is_valid(data->dt_data->reset_gpio)) { + ret = gpio_request(data->dt_data->reset_gpio, "imagis,reset_gpio"); + if (ret) { + tsp_err("unable to request reset gpio: %d\n", + data->dt_data->reset_gpio); + return ret; + } + + ret = gpio_direction_output(data->dt_data->reset_gpio, 0); + if (ret) + tsp_err("unable to set direction for reset gpio: %d\n", + data->dt_data->reset_gpio); + + gpio_set_value_cansleep(data->dt_data->reset_gpio, 0); + } + + if (gpio_is_valid(data->dt_data->irq_gpio)) { + ret = gpio_request(data->dt_data->irq_gpio, "imagis,irq_gpio"); + if (ret) { + tsp_err("unable to request irq gpio: %d\n", + data->dt_data->irq_gpio); + return ret; + } + + ret = gpio_direction_input(data->dt_data->irq_gpio); + if (ret) + tsp_err("unable to set direction for irq gpio: %d\n", + data->dt_data->irq_gpio); + + gpio_set_value_cansleep(data->dt_data->reset_gpio, 0); + + data->client->irq = gpio_to_irq(data->dt_data->irq_gpio); + } + return 0; +} + +static void ist30xx_free_gpio(struct ist30xx_data *data) +{ + tsp_info("%s\n", __func__); + + if (gpio_is_valid(data->dt_data->reset_gpio)) + gpio_free(data->dt_data->reset_gpio); + + if (gpio_is_valid(data->dt_data->irq_gpio)) + gpio_free(data->dt_data->irq_gpio); +} + +static int ist30xx_parse_dt(struct device *dev, struct ist30xx_data *data) +{ + struct device_node *np = dev->of_node; + + data->dt_data->irq_gpio = of_get_named_gpio(np, "imagis,irq-gpio", 0); + data->dt_data->reset_gpio = of_get_named_gpio(np, "imagis,reset-gpio", 0); + + tsp_info("##### Device tree #####\n"); + tsp_info(" reset gpio: %d\n", data->dt_data->reset_gpio); + tsp_info(" irq gpio: %d\n", data->dt_data->irq_gpio); + + return 0; +} +#endif +#ifdef XIAOMI_PRODUCT +#define CTP_PROC_LOCKDOWN_FILE "tp_lockdown_info" +static struct proc_dir_entry *ctp_lockdown_status_proc; +static char tp_lockdown_info[128]; + +static int ctp_lockdown_proc_show(struct seq_file *file, void *data) +{ + char temp[40] = {0}; + + sprintf(temp, "%s\n", tp_lockdown_info); + seq_printf(file, "%s\n", temp); + return 0; +} + +static int ctp_lockdown_proc_open (struct inode *inode, struct file *file) +{ + return single_open(file, ctp_lockdown_proc_show, inode->i_private); +} + +static const struct file_operations ctp_lockdown_proc_fops = { + .open = ctp_lockdown_proc_open, + .read = seq_read, +}; +#endif +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct ist30xx_data *ist_data = + container_of(self, struct ist30xx_data, fb_notif); + + if (evdata && evdata->data && event == FB_EVENT_BLANK && + ist_data && ist_data->client) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) + ist30xx_resume(&ist_data->client->dev); + else if (*blank == FB_BLANK_POWERDOWN) + ist30xx_suspend(&ist_data->client->dev); + } + return 0; +} +#endif + +static char tp_info_summary[80] = ""; + +static int ist30xx_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + int i; + int retry = 3; + struct ist30xx_data *data; + struct input_dev *input_dev; + char tp_temp_info[80]; +#ifdef XIAOMI_PRODUCT + u32 info_data[2]; +#endif + + tsp_info("### IMAGIS probe(ver:%s, addr:0x%02X) ###\n", + IMAGIS_TSP_DD_VERSION, client->addr); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + printk(KERN_INFO "i2c_check_functionality error\n"); + return -EIO; + } + + data = kzalloc(sizeof(struct ist30xx_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + data->client = client; +#ifdef CONFIG_OF + data->dt_data = NULL; + if (client->dev.of_node) { + data->dt_data = kzalloc(sizeof(struct ist30xx_dt_data), GFP_KERNEL); + if (unlikely(!data->dt_data)) { + tsp_err("failed to allocate dt data\n"); + goto err_alloc_dev; + } + + ret = ist30xx_parse_dt(&client->dev, data); + if (unlikely(ret)) + goto err_alloc_dev; + } else { + data->dt_data = NULL; + tsp_err("don't exist of_node\n"); + goto err_alloc_dev; + } + + if (data->dt_data) + ret = ist30xx_request_gpio(data); + if (ret) { + goto err_alloc_dev; + } +#endif + + ret = ist30xx_pinctrl_init(data); + if (!ret && data->pinctrl) { + /* + * Pinctrl handle is optional. If pinctrl handle is found + * let pins to be configured in active state. If not + * found continue further without error. + */ + ret = pinctrl_select_state(data->pinctrl, data->pinctrl_state_active); + if (ret < 0) + tsp_err("failed to select %s pinatate %d\n", "pmx_ts_active", ret); + } + + input_dev = input_allocate_device(); + if (unlikely(!input_dev)) { + tsp_err("input_allocate_device failed\n"); + goto err_alloc_dt; + } + + tsp_info("client->irq : %d\n", client->irq); + + data->input_dev = input_dev; + i2c_set_clientdata(client, data); + +#ifdef USE_OPEN_CLOSE + data->input_dev->open = ist30xx_ts_open; + data->input_dev->close = ist30xx_ts_close; +#else +#ifdef CONFIG_HAS_EARLYSUSPEND + data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + data->early_suspend.suspend = ist30xx_early_suspend; + data->early_suspend.resume = ist30xx_late_resume; + register_early_suspend(&data->early_suspend); +#endif +#endif + + data->max_fingers = IST30XX_MAX_FINGERS; + data->max_keys = IST30XX_MAX_KEYS; + data->irq_enabled = false; + data->status.event_mode = false; + mutex_init(&data->lock); + ts_data = data; + + /* initialize data variable */ + data->ignore_delay = false; + data->irq_working = false; + data->cal_ref_count = 0; + data->max_scan_retry = 2; + data->max_irq_err_cnt = IST30XX_MAX_ERR_CNT; + data->report_rate = -1; + data->idle_rate = -1; + data->timer_period_ms = 500; +#ifdef IST30XX_GESTURE + data->suspend = false; + data->gesture = true; +#endif + data->fw_mode = IST30XX_CAL_MODE; + data->rec_mode = 0; + data->rec_file_name = kzalloc(IST30XX_REC_FILENAME_SIZE, GFP_KERNEL); + data->debug_mode = 0; + data->debugging_mode = 0; + data->debugging_noise = 1; + for (i = 0; i < IST30XX_MAX_FINGERS; i++) + data->tsp_touched[i] = false; +#ifdef IST30XX_USE_KEY + for (i = 0; i < IST30XX_MAX_KEYS; i++) + data->tkey_pressed[i] = false; +#endif + + ret = ist30xx_power_init(data); + if (ret) + goto err_init_drv; + + /* system power init */ + ret = ist30xx_init_system(data); + if (unlikely(ret)) { + tsp_err("chip initialization failed\n"); + goto err_init_drv; + } + +#ifdef XIAOMI_PRODUCT + retry = 1; + while (retry-- > 0) { + ret = ist30xxc_isp_info_read(data, XIAOMI_INFO_ADDR, info_data, + XIAOMI_INFO_SIZE); + if (ret == 0) { + if ((info_data[XIAOMI_PID_INDEX] & XIAOMI_INFO_MASK) + == XIAOMI_INFO_VALUE) { + data->pid = XIAOMI_GET_PID(info_data[XIAOMI_PID_INDEX]); + data->lockdown_upper = info_data[XIAOMI_LOCKDOWN_INDEX]; + break; + } + } + + if (retry == 0) { + data->pid = 0; + tsp_err("read isp info failed\n"); + } + } + +#endif + + retry = IST30XX_MAX_RETRY_CNT; + while (retry-- > 0) { + ret = ist30xx_read_reg(data->client, IST30XX_REG_CHIPID, + &data->chip_id); + data->chip_id &= 0xFFFF; + if (unlikely(ret == 0)) { + set_usb_charge_mode_par = 1; + if ((data->chip_id == IST30XX_CHIP_ID) || + (data->chip_id == IST30XXC_DEFAULT_CHIP_ID) || + (data->chip_id == IST3048C_DEFAULT_CHIP_ID)) { + break; + } + } else if (unlikely(retry == 0)) { + goto err_init_drv; + } + + ist30xx_reset(data, false); + } + tsp_info("TSP IC: %x\n", data->chip_id); + + /* init irq thread */ + ret = request_threaded_irq(client->irq, NULL, ist30xx_irq_thread, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_DISABLED , "ist30xx_ts", + data); + if (unlikely(ret)) + goto err_init_drv; + +#ifdef IST30XX_INTERNAL_BIN +#ifdef XIAOMI_PRODUCT + if (data->pid != 0) { +#endif +#ifdef IST30XX_UPDATE_BY_WORKQUEUE + INIT_DELAYED_WORK(&data->work_fw_update, fw_update_func); + schedule_delayed_work(&data->work_fw_update, IST30XX_UPDATE_DELAY); +#else + + ret = ist30xx_auto_bin_update(data); + if (unlikely(ret != 0)) + goto err_irq; +#endif +#ifdef XIAOMI_PRODUCT + } +#endif +#endif + + ret = ist30xx_init_update_sysfs(data); + if (unlikely(ret)) + goto err_sysfs; + +#ifdef IST30XX_DEBUG + ret = ist30xx_init_misc_sysfs(data); + if (unlikely(ret)) + goto err_sysfs; +#endif + +#ifdef IST30XX_CMCS_TEST + ret = ist30xx_init_cmcs_sysfs(data); + if (unlikely(ret)) + goto err_sysfs; +#endif + +#ifdef IST30XX_TRACKING_MODE + ret = ist30xx_init_tracking_sysfs(data); + if (unlikely(ret)) + goto err_sysfs; +#endif + + tsp_info("Create sysfs!!\n"); + +#if defined(CONFIG_FB) + data->fb_notif.notifier_call = fb_notifier_callback; + + ret = fb_register_client(&data->fb_notif); + + if (ret) { + goto err_sysfs; + tsp_err("Unable to register fb_notifier\n"); + } +#endif +#ifndef IST30XX_UPDATE_BY_WORKQUEUE + ret = ist30xx_get_info(data); + tsp_info("Get info: %s\n", (ret == 0 ? "success" : "fail")); + if (unlikely(ret)) + goto err_read_info; +#endif + + +#ifdef XIAOMI_PRODUCT + memset(tp_lockdown_info, 0, sizeof(tp_lockdown_info)); + sprintf(tp_lockdown_info, "%08X%08X", data->fw.cur.lockdown[0], data->fw.cur.lockdown[1]); + tsp_info("[%s]lockdowninfo:%s\n", __FUNCTION__, tp_lockdown_info); + ctp_lockdown_status_proc = proc_create(CTP_PROC_LOCKDOWN_FILE, 0644, NULL, &ctp_lockdown_proc_fops); + if (ctp_lockdown_status_proc == NULL) + tsp_err("tpd, create_proc_entry ctp_lockdown_status_proc failed\n"); +#endif + + INIT_DELAYED_WORK(&data->work_reset_check, reset_work_func); +#ifdef IST30XX_NOISE_MODE + INIT_DELAYED_WORK(&data->work_noise_protect, noise_work_func); +#else +#ifdef IST30XX_FORCE_RELEASE + INIT_DELAYED_WORK(&data->work_force_release, release_work_func); +#endif +#endif +#ifdef IST30XX_ALGORITHM_MODE + INIT_DELAYED_WORK(&data->work_debug_algorithm, debug_work_func); +#endif + INIT_DELAYED_WORK(&data->work_cal_reference, cal_ref_work_func); + + init_timer(&data->event_timer); + data->event_timer.data = (unsigned long)data; + data->event_timer.function = timer_handler; + data->event_timer.expires = jiffies_64 + EVENT_TIMER_INTERVAL; + mod_timer(&data->event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL * 2); + +#ifdef USE_TSP_TA_CALLBACKS + data->callbacks.inform_charger = charger_enable; + ist30xx_register_callback(&data->callbacks); +#endif + +#ifndef IST30XX_UPDATE_BY_WORKQUEUE + ist30xx_start(data); + data->initialized = true; +#endif + strcpy(tp_info_summary, "[Vendor]Dongshan, [IC]IST3038C, [FW]Ver"); + sprintf(tp_temp_info, "%x", data->fw.bin.fw_ver); + strcat(tp_info_summary, tp_temp_info); + strcat(tp_info_summary, "\0"); + tsp_info("### IMAGIS probe success ###\n"); + + return 0; + +#ifndef IST30XX_UPDATE_BY_WORKQUEUE +err_read_info: +#endif +err_sysfs: + class_destroy(ist30xx_class); +#ifndef IST30XX_UPDATE_BY_WORKQUEUE +err_irq: +#endif + ist30xx_disable_irq(data); + free_irq(client->irq, data); +err_init_drv: + input_free_device(input_dev); + data->status.event_mode = false; + ist30xx_power_off(data); +#if (defined(CONFIG_HAS_EARLYSUSPEND) && !defined(USE_OPEN_CLOSE)) + unregister_early_suspend(&data->early_suspend); +#endif +err_alloc_dt: + if (data->pinctrl) { + if (IS_ERR_OR_NULL(data->pinctrl_state_release)) { + devm_pinctrl_put(data->pinctrl); + data->pinctrl = NULL; + } else { + ret = pinctrl_select_state(data->pinctrl, + data->pinctrl_state_release); + if (ret < 0) + tsp_err("cannot get release pinctrl state\n"); + } + } + if (data->dt_data) { + tsp_err("Error, ist30xx mem free\n"); + ist30xx_free_gpio(data); + kfree(data->dt_data); + } +#ifdef CONFIG_OF +err_alloc_dev: +#endif + kfree(data); + tsp_err("Error, ist30xx init driver\n"); + return -ENODEV; +} + + +static int ist30xx_remove(struct i2c_client *client) +{ + int ret; + struct ist30xx_data *data = i2c_get_clientdata(client); + +#if (defined(CONFIG_HAS_EARLYSUSPEND) && !defined(USE_OPEN_CLOSE)) + unregister_early_suspend(&data->early_suspend); +#endif + + ist30xx_disable_irq(data); + free_irq(client->irq, data); + ist30xx_power_off(data); + if (data->dt_data) { + ist30xx_free_gpio(data); + kfree(data->dt_data); + } + +#if defined(CONFIG_FB) + fb_unregister_client(&data->fb_notif); +#endif + if (data->pinctrl) { + if (IS_ERR_OR_NULL(data->pinctrl_state_release)) { + devm_pinctrl_put(data->pinctrl); + data->pinctrl = NULL; + } else { + ret = pinctrl_select_state(data->pinctrl, + data->pinctrl_state_release); + if (ret < 0) + tsp_err("cannot get release pinctrl state\n"); + } + } + input_unregister_device(data->input_dev); + input_free_device(data->input_dev); + kfree(data); + + return 0; +} + +static void ist30xx_shutdown(struct i2c_client *client) +{ + struct ist30xx_data *data = i2c_get_clientdata(client); + + del_timer(&data->event_timer); + cancel_delayed_work_sync(&data->work_reset_check); +#ifdef IST30XX_NOISE_MODE + cancel_delayed_work_sync(&data->work_noise_protect); +#else +#ifdef IST30XX_FORCE_RELEASE + cancel_delayed_work_sync(&data->work_force_release); +#endif +#endif +#ifdef IST30XX_ALGORITHM_MODE + cancel_delayed_work_sync(&data->work_debug_algorithm); +#endif + cancel_delayed_work_sync(&data->work_cal_reference); + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + ist30xx_internal_suspend(data); + clear_input_data(data); + mutex_unlock(&data->lock); +} + +static struct i2c_device_id ist30xx_idtable[] = { + { IST30XX_DEV_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, ist30xx_idtable); + +#ifdef CONFIG_OF +static struct of_device_id ist30xx_match_table[] = { + { .compatible = "imagis,ist30xx-ts", }, + { }, +}; +#else +#define ist30xx_match_table NULL +#endif + +static struct i2c_driver ist30xx_i2c_driver = { + .id_table = ist30xx_idtable, + .probe = ist30xx_probe, + .remove = ist30xx_remove, + .shutdown = ist30xx_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = IST30XX_DEV_NAME, + .of_match_table = ist30xx_match_table, + }, +}; + +static int __init ist30xx_init(void) +{ + tsp_info("%s()\n", __func__); + return i2c_add_driver(&ist30xx_i2c_driver); +} + + +static void __exit ist30xx_exit(void) +{ + tsp_info("%s()\n", __func__); + i2c_del_driver(&ist30xx_i2c_driver); +} + +module_init(ist30xx_init); +module_exit(ist30xx_exit); + +MODULE_DESCRIPTION("Imagis IST30XX touch driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc.h b/drivers/input/touchscreen/ist3038c/ist30xxc.h new file mode 100644 index 000000000000..62d746ed53cf --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc.h @@ -0,0 +1,606 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XXC_H__ +#define __IST30XXC_H__ + +/* + * Support F/W ver : ~ IST30xxC v3.0.0.0 + * Support CmCs ver : v5.2 + * Support IC : IST3026C, IST3032C, IST3038C, IST3038C1, IST3044C, IST3048C + * Release : 2015.09.18 by Drake + */ + +#define IMAGIS_TSP_DD_VERSION ("3.0.0.0") + +#define IMAGIS_IST3026C (1) /* 3026C */ +#define IMAGIS_IST3032C (2) /* 3032C */ +#define IMAGIS_IST3038C (3) /* 3038C/3038C1 */ +#define IMAGIS_IST3044C (4) /* 3044C */ +#define IMAGIS_IST3048C (5) /* 3048C */ + +#define IMAGIS_TSP_IC IMAGIS_IST3038C +#define TSP_CHIP_VENDOR ("IMAGIS") + +/* IST30XX FUNCTION ENABLE & DISABLE */ +#define XIAOMI_PRODUCT + + + +#define IST30XX_INTERNAL_BIN +#ifdef IST30XX_INTERNAL_BIN + +#ifdef IST30XX_UPDATE_BY_WORKQUEUE +#define IST30XX_UPDATE_DELAY (3 * HZ) +#endif +#endif +#define IST30XX_TRACKING_MODE +#define IST30XX_NOISE_MODE + +#define IST30XX_ALGORITHM_MODE +#define IST30XX_USE_KEY +#ifdef IST30XX_USE_KEY +#define IST30XX_KEY_CODES { KEY_MENU, KEY_HOMEPAGE, KEY_BACK } +#endif +#define IST30XX_DEBUG +#define IST30XX_CMCS_TEST + + +#define IST30XX_GESTURE + + + + +/* IST30XX FUNCTION ENABLE & DISABLE */ +#ifdef XIAOMI_PRODUCT +#define XIAOMI_INFO_ADDR (0xFE) +#define XIAOMI_INFO_SIZE (2) +#define XIAOMI_LOCKDOWN_INDEX (0) +#define XIAOMI_PID_INDEX (1) +#define XIAOMI_INFO_MASK (0xFF0000FF) +#define XIAOMI_INFO_VALUE (0x9A00001D) +#define C6_PID (0xC601) +#define XIAOMI_GET_PID(n) ((n & ~(XIAOMI_INFO_MASK)) >> 8) +#endif + +#define IST30XXC_DEFAULT_CHIP_ID (0x300C) +#define IST3048C_DEFAULT_CHIP_ID (0x3048) +#if (IMAGIS_TSP_IC == IMAGIS_IST3026C) +#define TSP_CHIP_NAME ("IST3026C") +#define IST30XX_CHIP_ID (0x026C) +#define IST30XX_MAX_NODE_NUM (16 * 16) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3032C) +#define TSP_CHIP_NAME ("IST3032C") +#define IST30XX_CHIP_ID (0x032C) +#define IST30XX_MAX_NODE_NUM (16 * 16) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3038C) +#define TSP_CHIP_NAME ("IST3038C") +#define IST30XX_CHIP_ID (0x038C) +#define IST30XX_MAX_NODE_NUM (24 * 24) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3044C) +#define TSP_CHIP_NAME ("IST3044C") +#define IST30XX_CHIP_ID (0x044C) +#define IST30XX_MAX_NODE_NUM (24 * 24) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3048C) +#define TSP_CHIP_NAME ("IST3048C") +#define IST30XX_CHIP_ID (0x048C) +#define IST30XX_MAX_NODE_NUM (24 * 24) +#else +#define TSP_CHIP_NAME ("IST30XXC") +#define IST30XX_CHIP_ID (0x300C) +#define IST30XX_MAX_NODE_NUM (24 * 24) +#endif + +#define IST30XX_MAX_FINGERS (10) +#define IST30XX_MAX_KEYS (5) +#define IST30XX_MAX_W (15) +#define IST30XX_MAX_3D_VALUE (255) + +#define IST30XX_INITIAL_VALUE (0x8EAD8EAD) +#define IST30XX_REC_VALUE (0x8CA0D00E) +#define IST30XX_REC_FILENAME_SIZE (128) +#define IST30XX_DEBUGGING_VALUE (0xDBDB0000) +#define IST30XX_MAX_DEBUGINFO (512) +#define IST30XX_EXCEPT_MASK (0xFFFFFF00) +#define IST30XX_EXCEPT_VALUE (0xE11CE900) +#define IST30XX_MAX_EXCEPT_SIZE (2) + +#define IST30XX_JIG_TOUCH (0xC0) +#define IST30XX_START_SCAN (2) +#define IST30XX_ENABLE (1) +#define IST30XX_DISABLE (0) + +#define IST30XX_CAL_MODE (1) +#define IST30XX_NON_CAL_MODE (2) + +/* retry count */ +#define IST30XX_MAX_RETRY_CNT (3) +#define IST30XX_MAX_CAL_REF_CNT (3) + +/* Local */ +#define TSP_LOCAL_EU (0) +#define TSP_LOCAL_EEU (1) +#define TSP_LOCAL_TD (11) +#define TSP_LOCAL_CMCC (12) +#define TSP_LOCAL_CU (13) +#define TSP_LOCAL_SPRD (14) +#define TSP_LOCAL_CTC (15) +#define TSP_LOCAL_INDIA (21) +#define TSP_LOCAL_SWASIA (22) +#define TSP_LOCAL_NA (31) +#define TSP_LOCAL_LA (32) +#define TSP_LOCAL_CODE TSP_LOCAL_EU + +/* Log message */ +#define DEV_ERR (1) +#define DEV_WARN (2) +#define DEV_INFO (3) +#define DEV_NOTI (4) +#define DEV_DEBUG (5) +#define DEV_VERB (6) + +#define IST30XX_LOG_TAG "[ TSP ]" +#define IST30XX_LOG_LEVEL DEV_NOTI + +#define tsp_err(fmt, ...) tsp_printk(DEV_ERR, fmt, ## __VA_ARGS__) +#define tsp_warn(fmt, ...) tsp_printk(DEV_WARN, fmt, ## __VA_ARGS__) +#define tsp_info(fmt, ...) tsp_printk(DEV_INFO, fmt, ## __VA_ARGS__) +#define tsp_noti(fmt, ...) tsp_printk(DEV_NOTI, fmt, ## __VA_ARGS__) +#define tsp_debug(fmt, ...) tsp_printk(DEV_DEBUG, fmt, ## __VA_ARGS__) +#define tsp_verb(fmt, ...) tsp_printk(DEV_VERB, fmt, ## __VA_ARGS__) + +/* timer & err cnt */ +#define IST30XX_MAX_ERR_CNT (100) +#define EVENT_TIMER_INTERVAL (HZ * data->timer_period_ms / 1000) + +/* i2c setting */ +/* I2C Device info */ +#define IST30XX_DEV_NAME "IST30XX" +#define IST30XX_DEV_ID (0xA0 >> 1) + +/* I2C transfer msg number */ +#define WRITE_CMD_MSG_LEN (1) +#define READ_CMD_MSG_LEN (2) + +/* I2C address/Data length */ +#define IST30XX_ADDR_LEN (4) /* bytes */ +#define IST30XX_DATA_LEN (4) /* bytes */ + +/* I2C transaction size */ +#define I2C_MAX_WRITE_SIZE (256) /* bytes */ +#define I2C_MAX_READ_SIZE (128) /* bytes */ + +/* I2C access mode */ +#define IST30XX_DIRECT_ACCESS (1 << 31) +#define IST30XX_BURST_ACCESS (1 << 27) +#define IST30XX_HIB_ACCESS (0x800B << 16) +#define IST30XX_DA_ADDR(n) (n | IST30XX_DIRECT_ACCESS) +#define IST30XX_BA_ADDR(n) (n | IST30XX_BURST_ACCESS) +#define IST30XX_HA_ADDR(n) (n | IST30XX_HIB_ACCESS) + +/* register */ +/* Info register */ +#define IST30XX_REG_CHIPID IST30XX_DA_ADDR(0x40001000) +#define IST30XX_REG_TSPTYPE IST30XX_DA_ADDR(0x40002010) + +/* HIB register */ +#define IST30XX_HIB_BASE (0x30000100) +#define IST30XX_HIB_TOUCH_STATUS IST30XX_HA_ADDR(IST30XX_HIB_BASE | 0x00) +#define IST30XX_HIB_INTR_MSG IST30XX_HA_ADDR(IST30XX_HIB_BASE | 0x04) +#define IST30XX_HIB_COORD IST30XX_HA_ADDR(IST30XX_HIB_BASE | 0x08) +#define IST30XX_HIB_CMD IST30XX_HA_ADDR(IST30XX_HIB_BASE | 0x3C) +#define IST30XX_HIB_RW_STATUS IST30XX_HA_ADDR(IST30XX_HIB_BASE | 0x40) + +/* interrupt macro */ +#define IST30XX_INTR_STATUS (0x00000C00) +#define CHECK_INTR_STATUS(n) (((n & IST30XX_INTR_STATUS) \ + == IST30XX_INTR_STATUS) ? 1 : 0) +#define PARSE_FINGER_CNT(n) ((n >> 12) & 0xF) +#define PARSE_KEY_CNT(n) ((n >> 21) & 0x7) +/* Finger status: [9:0] */ +#define PARSE_FINGER_STATUS(n) (n & 0x3FF) +/* Key status: [20:16] */ +#define PARSE_KEY_STATUS(n) ((n >> 16) & 0x1F) +#define PRESSED_FINGER(s, id) ((s & (1 << id)) ? true : false) +#define PRESSED_KEY(s, id) ((s & (1 << (16 + id))) ? true : false) + +#define IST30XX_MAX_CMD_SIZE (0x20) +#define IST30XX_CMD_ADDR(n) (n * 4) +#define IST30XX_CMD_VALUE(n) (n / 4) +enum ist30xx_read_commands { + eHCOM_GET_CHIP_ID = IST30XX_CMD_ADDR(0x00), + eHCOM_GET_VER_MAIN = IST30XX_CMD_ADDR(0x01), + eHCOM_GET_VER_FW = IST30XX_CMD_ADDR(0x02), + eHCOM_GET_VER_CORE = IST30XX_CMD_ADDR(0x03), + eHCOM_GET_VER_TEST = IST30XX_CMD_ADDR(0x04), + eHCOM_GET_CRC32 = IST30XX_CMD_ADDR(0x05), + eHCOM_GET_FW_MODE = IST30XX_CMD_ADDR(0x06), + eHCOM_GET_CAL_RESULT = IST30XX_CMD_ADDR(0x07), + eHCOM_GET_TSP_VENDOR = IST30XX_CMD_ADDR(0x08), +#ifdef XIAOMI_PRODUCT + eHCOM_GET_LOCKDOWN_1 = IST30XX_CMD_ADDR(0x09), + eHCOM_GET_LOCKDOWN_2 = IST30XX_CMD_ADDR(0x0A), + eHCOM_GET_CONFIG_1 = IST30XX_CMD_ADDR(0x0B), + eHCOM_GET_CONFIG_2 = IST30XX_CMD_ADDR(0x0C), +#endif + eHCOM_GET_DBG_INFO_BASE = IST30XX_CMD_ADDR(0x0E), + + eHCOM_GET_LCD_INFO = IST30XX_CMD_ADDR(0x10), + eHCOM_GET_TSP_INFO = IST30XX_CMD_ADDR(0x11), + eHCOM_GET_KEY_INFO_0 = IST30XX_CMD_ADDR(0x12), + eHCOM_GET_KEY_INFO_1 = IST30XX_CMD_ADDR(0x13), + eHCOM_GET_KEY_INFO_2 = IST30XX_CMD_ADDR(0x14), + eHCOM_GET_SCR_INFO = IST30XX_CMD_ADDR(0x15), + eHCOM_GET_GTX_INFO = IST30XX_CMD_ADDR(0x16), + eHCOM_GET_SWAP_INFO = IST30XX_CMD_ADDR(0x17), + eHCOM_GET_FINGER_INFO = IST30XX_CMD_ADDR(0x18), + eHCOM_GET_BASELINE = IST30XX_CMD_ADDR(0x19), + eHCOM_GET_TOUCH_TH = IST30XX_CMD_ADDR(0x1A), + + eHCOM_GET_FILTER_BASE = IST30XX_CMD_ADDR(0x1B), + eHCOM_GET_ZVALUE_BASE = IST30XX_CMD_ADDR(0x1C), + eHCOM_GET_RAW_BASE = IST30XX_CMD_ADDR(0x1D), + eHCOM_GET_ALGO_BASE = IST30XX_CMD_ADDR(0x1E), + eHCOM_GET_COM_CHECKSUM = IST30XX_CMD_ADDR(0x1F), +}; + +enum ist30xx_write_commands { + eHCOM_FW_START = 0x01, + eHCOM_FW_HOLD = 0x02, + + eHCOM_CP_CORRECT_EN = 0x10, + eHCOM_WDT_EN = 0x11, + eHCOM_GESTURE_EN = 0x12, + eHCOM_SCALE_EN = 0x13, + eHCOM_NEW_POSITION_DIS = 0x14, + eHCOM_SLEEP_MODE_EN = 0x15, + + eHCOM_SET_TIME_ACTIVE = 0x20, + eHCOM_SET_TIME_IDLE = 0x21, + eHCOM_SET_MODE_SPECIAL = 0x22, + eHCOM_SET_LOCAL_MODEL = 0x23, + + eHCOM_RUN_RAMCODE = 0x30, + eHCOM_RUN_CAL_AUTO = 0x31, + eHCOM_RUN_CAL_PARAM = 0x32, + eHCOM_RUN_CAL_REF = 0x33, + + eHCOM_SET_JIG_MODE = 0x80, + eHCOM_SET_JIG_SENSITI = 0x81, + + eHCOM_SET_REC_MODE = 0xE0, + eHCOM_SET_DBG_MODE = 0xE1, + + eHCOM_DEFAULT = 0xFF, +}; + +#define IST30XX_RINGBUF_NO_ERR (0) +#define IST30XX_RINGBUF_NOT_ENOUGH (1) +#define IST30XX_RINGBUF_EMPTY (2) +#define IST30XX_RINGBUF_FULL (3) +#define IST30XX_RINGBUF_TIMEOUT (4) +#define IST30XX_MAX_RINGBUF_SIZE (4 * 100 * 1024) +typedef struct _IST30XX_RINGBUF { + u32 RingBufCtr; + u32 RingBufInIdx; + u32 RingBufOutIdx; + u8 LogBuf[IST30XX_MAX_RINGBUF_SIZE]; +} IST30XX_RING_BUF; + +typedef union { + struct { + u32 y:12; + u32 x:12; +#ifdef IST30XX_USE_3D_TOUCH + u32 f:8; +#else + u32 w:4; + u32 id:4; +#endif + } bit_field; + u32 full_field; +} finger_info; + +struct ist30xx_status { + int power; + int update; + int update_result; + int calib; + int calib_msg; + u32 cal_ref_msg; + u32 cmcs; + bool event_mode; + bool noise_mode; +}; + +struct ist30xx_version { + u32 main_ver; + u32 fw_ver; + u32 core_ver; + u32 test_ver; +#ifdef XIAOMI_PRODUCT + u32 lockdown[2]; + u32 config[2]; +#endif +}; + +struct ist30xx_fw { + struct ist30xx_version prev; + struct ist30xx_version cur; + struct ist30xx_version bin; + u32 index; + u32 size; + u32 chksum; + u32 buf_size; + u8 *buf; +}; + +#define IST30XX_TAG_MAGIC "ISTV2TAG" +struct ist30xx_tags { + char magic1[8]; + u32 rom_base; + u32 ram_base; + u32 reserved0; + u32 reserved1; + + u32 fw_addr; + u32 fw_size; + u32 cfg_addr; + u32 cfg_size; + u32 sensor_addr; + u32 sensor_size; + u32 cp_addr; + u32 cp_size; + u32 flag_addr; + u32 flag_size; + u32 reserved2; + u32 reserved3; + + u32 zvalue_base; + u32 algr_base; + u32 raw_base; + u32 filter_base; + u32 reserved4; + u32 reserved5; + + u32 chksum; + u32 chksum_all; + u32 reserved6; + u32 reserved7; + + u8 day; + u8 month; + u16 year; + u8 hour; + u8 min; + u8 sec; + u8 reserved8; + char magic2[8]; +}; + +struct CH_NUM { + u8 tx; + u8 rx; +}; + +struct GTX_INFO { + u8 num; + u8 ch_num[4]; +}; + +struct TSP_NODE_BUF { + u16 raw[IST30XX_MAX_NODE_NUM]; + u16 base[IST30XX_MAX_NODE_NUM]; + u16 filter[IST30XX_MAX_NODE_NUM]; + u16 cp_lower[IST30XX_MAX_NODE_NUM]; + u16 cp_upper[IST30XX_MAX_NODE_NUM]; + u16 len; +}; + +struct TSP_DIRECTION { + bool swap_xy; + bool flip_x; + bool flip_y; +}; + +typedef struct _TSP_INFO { + struct CH_NUM ch_num; + struct CH_NUM screen; + struct GTX_INFO gtx; + struct TSP_DIRECTION dir; + struct TSP_NODE_BUF node; + int height; + int width; + int finger_num; + u16 baseline; +} TSP_INFO; + +typedef struct _TKEY_INFO { + int key_num; + bool enable; + struct CH_NUM ch_num[IST30XX_MAX_KEYS]; + u16 baseline; +} TKEY_INFO; + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#ifdef IST30XX_TA_CALLBACK +#include +#endif +struct ist30xx_dt_data { + u32 reset_gpio; + u32 irq_gpio; + const char *vdd_name; + const char *vddio_name; +}; + +struct ist30xx_data { + struct mutex lock; + struct i2c_client *client; + struct input_dev *input_dev; + struct ist30xx_dt_data *dt_data; + TSP_INFO tsp_info; + TKEY_INFO tkey_info; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + struct ist30xx_status status; + struct ist30xx_fw fw; + struct ist30xx_tags tags; + u32 chip_id; + u32 fw_mode; + u32 max_fingers; + u32 max_keys; + u32 t_status; + finger_info fingers[IST30XX_MAX_FINGERS]; + bool tsp_touched[IST30XX_MAX_FINGERS]; +#ifdef IST30XX_USE_KEY + bool tkey_pressed[IST30XX_MAX_KEYS]; +#endif +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#endif + + u32 raw_addr; + u32 filter_addr; + u32 zvalue_addr; + u32 algorithm_addr; + volatile bool irq_working; + bool irq_enabled; + bool initialized; + bool ignore_delay; + u32 noise_mode; + u32 debug_mode; + u32 jig_mode; + u32 z_values[IST30XX_MAX_FINGERS]; + int report_rate; + int idle_rate; +#ifdef IST30XX_GESTURE + bool suspend; + bool gesture; +#endif + int scan_count; + int scan_retry; + int max_scan_retry; + int timer_period_ms; + struct timer_list event_timer; + struct timespec t_current; /* nano seconds */ + u32 event_ms; + u32 timer_ms; + int cal_ref_count; + int irq_err_cnt; + int max_irq_err_cnt; + u32 intr_debug1_addr; + u32 intr_debug1_size; + u32 intr_debug2_addr; + u32 intr_debug2_size; + u32 intr_debug3_addr; + u32 intr_debug3_size; + u32 rec_mode; + struct CH_NUM rec_start_ch; + struct CH_NUM rec_stop_ch; + int rec_delay; + char *rec_file_name; + u32 debugging_mode; + u32 debugging_addr; + u8 debugging_size; + u32 debugging_scancnt; + u32 debugging_noise; + u32 t_frame[2]; + struct delayed_work work_reset_check; +#ifdef IST30XX_NOISE_MODE + struct delayed_work work_noise_protect; +#else +#ifdef IST30XX_FORCE_RELEASE + struct delayed_work work_force_release; +#endif +#endif +#ifdef IST30XX_ALGORITHM_MODE + struct delayed_work work_debug_algorithm; + u32 algr_addr; + u32 algr_size; +#endif + struct delayed_work work_cal_reference; +#ifdef IST30XX_INTERNAL_BIN +#ifdef IST30XX_UPDATE_BY_WORKQUEUE + struct delayed_work work_fw_update; +#endif +#endif +#ifdef USE_TSP_TA_CALLBACKS + struct tsp_callbacks callbacks; +#endif + +#ifdef S_IRWXUGO +#undef S_IRWXUGO +#define S_IRWXUGO 0664 +#endif + +#ifdef XIAOMI_PRODUCT + u32 pid; + u32 lockdown_upper; +#endif + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_state_active; + struct pinctrl_state *pinctrl_state_suspend; + struct pinctrl_state *pinctrl_state_release; + struct regulator *vdd; + struct regulator *vddio; +}; + +extern int ist30xx_log_level; +extern struct class *ist30xx_class; +extern bool ist30xx_gesture_func_on; + +void tsp_printk(int level, const char *fmt, ...); +void ist30xx_delay(unsigned int ms); +int ist30xx_intr_wait(struct ist30xx_data *data, long ms); + +void ist30xx_enable_irq(struct ist30xx_data *data); +void ist30xx_disable_irq(struct ist30xx_data *data); +void ist30xx_set_ta_mode(bool charging); +void ist30xx_set_edge_mode(int mode); +void ist30xx_set_cover_mode(int mode); +void ist30xx_start(struct ist30xx_data *data); +int ist30xx_get_ver_info(struct ist30xx_data *data); + +int ist30xx_read_reg(struct i2c_client *client, u32 reg, u32 *buf); +int ist30xx_read_cmd(struct ist30xx_data *data, u32 cmd, u32 *buf); +int ist30xx_write_cmd(struct ist30xx_data *data, u32 cmd, u32 val); +int ist30xx_read_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len); +int ist30xx_write_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len); +int ist30xx_burst_read(struct i2c_client *client, u32 addr, + u32 *buf32, u16 len, bool bit_en); +int ist30xx_burst_write(struct i2c_client *client, u32 addr, + u32 *buf32, u16 len); + +int ist30xx_cmd_start_scan(struct ist30xx_data *data); +int ist30xx_cmd_calibrate(struct ist30xx_data *data); +int ist30xx_cmd_cal_reference(struct ist30xx_data *data); +int ist30xx_cmd_check_calib(struct ist30xx_data *data); +int ist30xx_cmd_update(struct ist30xx_data *data, int cmd); +int ist30xx_cmd_hold(struct ist30xx_data *data, int enable); + +int ist30xx_power_on(struct ist30xx_data *data, bool download); +int ist30xx_power_off(struct ist30xx_data *data); +int ist30xx_reset(struct ist30xx_data *data, bool download); + +int ist30xx_internal_suspend(struct ist30xx_data *data); +int ist30xx_internal_resume(struct ist30xx_data *data); + +int ist30xx_init_system(struct ist30xx_data *data); + +#endif /* __IST30XXC_H__ */ diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.c b/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.c new file mode 100644 index 000000000000..35133248a27d --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.c @@ -0,0 +1,2106 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ist30xxc.h" +#include "ist30xxc_cmcs.h" + +#ifdef IST30XX_CMCS_TEST + +#ifdef INTERNAL_CMCS_BIN +#include "ist30xxc_cmcs_bin.h" +#endif + +#define TSP_CH_UNUSED (0) +#define TSP_CH_SCREEN (1) +#define TSP_CH_GTX (2) +#define TSP_CH_KEY (3) +#define TSP_CH_UNKNOWN (-1) + +#define CMCS_FLAG_CM (1 << 0) +#define CMCS_FLAG_CM_SPEC (1 << 1) +#define CMCS_FLAG_CM_SLOPE0 (1 << 2) +#define CMCS_FLAG_CM_SLOPE1 (1 << 3) +#define CMCS_FLAG_CMJIT (1 << 4) +#define CMCS_FLAG_CM2 (1 << 5) +#define CMCS_FLAG_CS (1 << 6) +#define CMCS_FLAG_INT (1 << 7) + +#define CMCS_ENABLE_CM (1 << 0) +#define CMCS_ENABLE_CM2 (1 << 1) +#define CMCS_ENABLE_CS (1 << 8) +#define CMCS_ENABLE_INT (1 << 16) +#define CMCS_ENABLE_CMJIT (1 << 24) + +#define CMCS_READY (0) +#define CMCS_NOT_READY (-1) + +#define CMCS_TIMEOUT (10000) + +#define CMCS_CMJIT ("CMJIT") +#define CMCS_CM ("CM") +#define CMCS_CM2 ("CM2") +#define CMCS_CS ("CS") + +#define CMCS_PARSING_DEBUG (0) +#define CMCS_TAGS_PARSE_OK (0) + +int cmcs_ready = CMCS_READY; +u8 *ts_cmcs_bin = NULL; +u32 ts_cmcs_bin_size = 0; +CMCS_BIN_INFO ist30xx_cmcs_bin; +CMCS_BIN_INFO *ts_cmcs = (CMCS_BIN_INFO *)&ist30xx_cmcs_bin; +CMCS_BUF ist30xx_cmcs_buf; +CMCS_BUF *ts_cmcs_buf = (CMCS_BUF *)&ist30xx_cmcs_buf; + +int ist30xx_parse_cmcs_bin(const u8 *buf, const u32 size) +{ + int ret = -EPERM; + int i; + int node_spec_cnt; + + memcpy(ts_cmcs->magic1, buf, sizeof(ts_cmcs->magic1)); + memcpy(ts_cmcs->magic2, &buf[size - sizeof(ts_cmcs->magic2)], + sizeof(ts_cmcs->magic2)); + + if (!strncmp(ts_cmcs->magic1, IST30XX_CMCS_MAGIC, sizeof(ts_cmcs->magic1)) + && !strncmp(ts_cmcs->magic2, IST30XX_CMCS_MAGIC, + sizeof(ts_cmcs->magic2))) { + int idx; + + idx = sizeof(ts_cmcs->magic1); + + memcpy(&ts_cmcs->items.cnt, &buf[idx], sizeof(ts_cmcs->items.cnt)); + idx += sizeof(ts_cmcs->items.cnt); + ts_cmcs->items.item = kmalloc( + sizeof(struct CMCS_ITEM_INFO) * ts_cmcs->items.cnt, GFP_KERNEL); + for (i = 0; i < ts_cmcs->items.cnt; i++) { + memcpy(&ts_cmcs->items.item[i], &buf[idx], + sizeof(struct CMCS_ITEM_INFO)); + idx += sizeof(struct CMCS_ITEM_INFO); + } + + memcpy(&ts_cmcs->cmds.cnt, &buf[idx], sizeof(ts_cmcs->cmds.cnt)); + idx += sizeof(ts_cmcs->cmds.cnt); + ts_cmcs->cmds.cmd = kmalloc( + sizeof(struct CMCS_CMD_INFO) * ts_cmcs->cmds.cnt, GFP_KERNEL); + for (i = 0; i < ts_cmcs->cmds.cnt; i++) { + memcpy(&ts_cmcs->cmds.cmd[i], &buf[idx], + sizeof(struct CMCS_CMD_INFO)); + idx += sizeof(struct CMCS_CMD_INFO); + } + + memcpy(&ts_cmcs->spec_slope, &buf[idx], sizeof(ts_cmcs->spec_slope)); + idx += sizeof(ts_cmcs->spec_slope); + + memcpy(&ts_cmcs->spec_cr, &buf[idx], sizeof(ts_cmcs->spec_cr)); + idx += sizeof(ts_cmcs->spec_cr); + + memcpy(&ts_cmcs->param, &buf[idx], sizeof(ts_cmcs->param)); + idx += sizeof(ts_cmcs->param); + + ts_cmcs->spec_item = kmalloc( + sizeof(struct CMCS_SPEC_TOTAL) * ts_cmcs->items.cnt, GFP_KERNEL); + for (i = 0; i < ts_cmcs->items.cnt; i++) { + if (!strcmp(ts_cmcs->items.item[i].spec_type, "N")) { + memcpy(&node_spec_cnt, &buf[idx], sizeof(node_spec_cnt)); + ts_cmcs->spec_item[i].spec_node.node_cnt = node_spec_cnt; + idx += sizeof(node_spec_cnt); + ts_cmcs->spec_item[i].spec_node.buf_min = (u16 *)&buf[idx]; + idx += node_spec_cnt * sizeof(s16); + ts_cmcs->spec_item[i].spec_node.buf_max = (u16 *)&buf[idx]; + idx += node_spec_cnt * sizeof(s16); + } else if (!strcmp(ts_cmcs->items.item[i].spec_type, "T")) { + memcpy(&ts_cmcs->spec_item[i].spec_total, &buf[idx], + sizeof(struct CMCS_SPEC_TOTAL)); + idx += sizeof(struct CMCS_SPEC_TOTAL); + } + } + + ts_cmcs->buf_cmcs = (u8 *)&buf[idx]; + idx += ts_cmcs->param.cmcs_size; + + ts_cmcs->buf_cm_sensor = (u32 *)&buf[idx]; + idx += ts_cmcs->param.cm_sensor1_size + ts_cmcs->param.cm_sensor2_size + + ts_cmcs->param.cm_sensor3_size; + + ts_cmcs->buf_cs_sensor = (u32 *)&buf[idx]; + idx += ts_cmcs->param.cs_sensor1_size + ts_cmcs->param.cs_sensor2_size + + ts_cmcs->param.cs_sensor3_size; + + ts_cmcs->buf_jit_sensor = (u32 *)&buf[idx]; + idx += ts_cmcs->param.jit_sensor1_size + ts_cmcs->param.jit_sensor2_size + + ts_cmcs->param.jit_sensor3_size; + + ts_cmcs->version = *((u32 *)&buf[idx]); + + ret = 0; + } + + tsp_verb("Magic1: %s, Magic2: %s\n", ts_cmcs->magic1, ts_cmcs->magic2); + tsp_verb("CmCs ver: %08X\n", ts_cmcs->version); + tsp_verb(" item(%d)\n", ts_cmcs->items.cnt); + for (i = 0; i < ts_cmcs->items.cnt; i++) { + tsp_verb(" (%d): %s, 0x%08x, %d, %s, %s\n", + i, ts_cmcs->items.item[i].name, ts_cmcs->items.item[i].addr, + ts_cmcs->items.item[i].size, ts_cmcs->items.item[i].data_type, + ts_cmcs->items.item[i].spec_type); + } + tsp_verb(" cmd(%d)\n", ts_cmcs->cmds.cnt); + for (i = 0; i < ts_cmcs->cmds.cnt; i++) + tsp_verb(" (%d): 0x%08x, 0x%08x\n", + i, ts_cmcs->cmds.cmd[i].addr, ts_cmcs->cmds.cmd[i].value); + tsp_verb(" param\n"); + tsp_verb(" fw: 0x%08x, %d\n", ts_cmcs->param.cmcs_size_addr, + ts_cmcs->param.cmcs_size); + tsp_verb(" enable: 0x%08x\n", ts_cmcs->param.enable_addr); + tsp_verb(" checksum: 0x%08x\n", ts_cmcs->param.checksum_addr); + tsp_verb(" endnotify: 0x%08x\n", ts_cmcs->param.end_notify_addr); + tsp_verb(" cm sensor1: 0x%08x, %d\n", ts_cmcs->param.sensor1_addr, + ts_cmcs->param.cm_sensor1_size); + tsp_verb(" cm sensor2: 0x%08x, %d\n", ts_cmcs->param.sensor2_addr, + ts_cmcs->param.cm_sensor2_size); + tsp_verb(" cm sensor3: 0x%08x, %d\n", ts_cmcs->param.sensor3_addr, + ts_cmcs->param.cm_sensor3_size); + tsp_verb(" cs sensor1: 0x%08x, %d\n", ts_cmcs->param.sensor1_addr, + ts_cmcs->param.cs_sensor1_size); + tsp_verb(" cs sensor2: 0x%08x, %d\n", ts_cmcs->param.sensor2_addr, + ts_cmcs->param.cs_sensor2_size); + tsp_verb(" cs sensor3: 0x%08x, %d\n", ts_cmcs->param.sensor3_addr, + ts_cmcs->param.cs_sensor3_size); + tsp_verb(" jit sensor1: 0x%08x, %d\n", ts_cmcs->param.sensor1_addr, + ts_cmcs->param.jit_sensor1_size); + tsp_verb(" jit sensor2: 0x%08x, %d\n", ts_cmcs->param.sensor2_addr, + ts_cmcs->param.jit_sensor2_size); + tsp_verb(" jit sensor3: 0x%08x, %d\n", ts_cmcs->param.sensor3_addr, + ts_cmcs->param.jit_sensor3_size); + tsp_verb(" chksum: 0x%08x\n, 0x%08x\n, 0x%08x, 0x%08x\n", + ts_cmcs->param.cmcs_chksum, ts_cmcs->param.cm_sensor_chksum, + ts_cmcs->param.cs_sensor_chksum, ts_cmcs->param.jit_sensor_chksum); + tsp_verb(" cs result addr(tx, rx): 0x%08x, 0x%08x\n", + ts_cmcs->param.cs_tx_result_addr, ts_cmcs->param.cs_rx_result_addr); + tsp_verb(" slope(%s)\n", ts_cmcs->spec_slope.name); + tsp_verb(" x(%d,%d),y(%d,%d),gtx_x(%d,%d),gtx_y(%d,%d),key(%d,%d)\n", + ts_cmcs->spec_slope.x_min, ts_cmcs->spec_slope.x_max, + ts_cmcs->spec_slope.y_min, ts_cmcs->spec_slope.y_max, + ts_cmcs->spec_slope.gtx_x_min, ts_cmcs->spec_slope.gtx_x_max, + ts_cmcs->spec_slope.gtx_y_min, ts_cmcs->spec_slope.gtx_y_max, + ts_cmcs->spec_slope.key_min, ts_cmcs->spec_slope.key_max); + tsp_verb(" cr: screen(%4d, %4d), gtx(%4d, %4d), key(%4d, %4d)\n", + ts_cmcs->spec_cr.screen_min, ts_cmcs->spec_cr.screen_max, + ts_cmcs->spec_cr.gtx_min, ts_cmcs->spec_cr.gtx_max, + ts_cmcs->spec_cr.key_min, ts_cmcs->spec_cr.key_max); + for (i = 0; i < ts_cmcs->items.cnt; i++) { + if (!strcmp(ts_cmcs->items.item[i].spec_type, "N")) { + tsp_verb(" %s\n", ts_cmcs->items.item[i].name); + tsp_verb(" min: %x, %x, %x, %x\n", + ts_cmcs->spec_item[i].spec_node.buf_min[0], + ts_cmcs->spec_item[i].spec_node.buf_min[1], + ts_cmcs->spec_item[i].spec_node.buf_min[2], + ts_cmcs->spec_item[i].spec_node.buf_min[3]); + tsp_verb(" max: %x, %x, %x, %x\n", + ts_cmcs->spec_item[i].spec_node.buf_max[0], + ts_cmcs->spec_item[i].spec_node.buf_max[1], + ts_cmcs->spec_item[i].spec_node.buf_max[2], + ts_cmcs->spec_item[i].spec_node.buf_max[3]); + } else if (!strcmp(ts_cmcs->items.item[i].spec_type, "T")) { + tsp_verb(" %s: screen(%4d, %4d), gtx(%4d, %4d), key(%4d, %4d)\n", + ts_cmcs->items.item[i].name, + ts_cmcs->spec_item[i].spec_total.screen_min, + ts_cmcs->spec_item[i].spec_total.screen_max, + ts_cmcs->spec_item[i].spec_total.gtx_min, + ts_cmcs->spec_item[i].spec_total.gtx_max, + ts_cmcs->spec_item[i].spec_total.key_min, + ts_cmcs->spec_item[i].spec_total.key_max); + } + } + tsp_verb(" cmcs: %x, %x, %x, %x\n", ts_cmcs->buf_cmcs[0], + ts_cmcs->buf_cmcs[1], ts_cmcs->buf_cmcs[2], ts_cmcs->buf_cmcs[3]); + tsp_verb(" cm sensor: %x, %x, %x, %x\n", + ts_cmcs->buf_cm_sensor[0], ts_cmcs->buf_cm_sensor[1], + ts_cmcs->buf_cm_sensor[2], ts_cmcs->buf_cm_sensor[3]); + tsp_verb(" cs sensor: %x, %x, %x, %x\n", + ts_cmcs->buf_cs_sensor[0], ts_cmcs->buf_cs_sensor[1], + ts_cmcs->buf_cs_sensor[2], ts_cmcs->buf_cs_sensor[3]); + tsp_verb(" jit sensor: %x, %x, %x, %x\n", + ts_cmcs->buf_jit_sensor[0], ts_cmcs->buf_jit_sensor[1], + ts_cmcs->buf_jit_sensor[2], ts_cmcs->buf_jit_sensor[3]); + + return ret; +} + +int ist30xx_get_cmcs_info(const u8 *buf, const u32 size) +{ + int ret; + + cmcs_ready = CMCS_NOT_READY; + + ret = ist30xx_parse_cmcs_bin(buf, size); + if (unlikely(ret != CMCS_TAGS_PARSE_OK)) + tsp_warn("Cannot find tags of CMCS, make a bin by 'cmcs2bin.exe'\n"); + + return ret; +} + +int ist30xx_set_cmcs_fw(struct ist30xx_data *data, CMCS_PARAM param, u32 *buf32) +{ + int ret; + int len; + u32 waddr; + u32 val; + + len = param.cmcs_size / IST30XX_DATA_LEN; + waddr = IST30XX_DA_ADDR(data->tags.ram_base); + tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + waddr = IST30XX_DA_ADDR(param.cmcs_size_addr); + val = param.cmcs_size; + tsp_verb("size(0x%08x): 0x%08x\n", waddr, val); + ret = ist30xx_write_cmd(data, waddr, val); + if (ret) + return ret; + + tsp_info("cmcs code loaded!\n"); + + return 0; +} + +int ist30xx_set_cmcs_sensor(struct ist30xx_data *data, CMCS_PARAM param, + u32 *buf32, int mode) +{ + int ret; + int len = 0; + u32 waddr; + + if ((mode == CMCS_FLAG_CM) || (mode == CMCS_FLAG_CM2)) { + waddr = IST30XX_DA_ADDR(param.sensor1_addr); + len = (param.cm_sensor1_size / IST30XX_DATA_LEN) - 2; + buf32 += 2; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("cm sensor reg1 loaded!\n"); + } + + buf32 += len; + waddr = IST30XX_DA_ADDR(param.sensor2_addr); + len = param.cm_sensor2_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("cm sensor reg2 loaded!\n"); + } + + buf32 += len; + waddr = IST30XX_DA_ADDR(param.sensor3_addr); + len = param.cm_sensor3_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("cm sensor reg3 loaded!\n"); + } + } else if (mode == CMCS_FLAG_CS) { + waddr = IST30XX_DA_ADDR(param.sensor1_addr); + len = (param.cs_sensor1_size / IST30XX_DATA_LEN) - 2; + buf32 += 2; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("cs sensor reg1 loaded!\n"); + } + + buf32 += len; + waddr = IST30XX_DA_ADDR(param.sensor2_addr); + len = param.cs_sensor2_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("cs sensor reg2 loaded!\n"); + } + + buf32 += len; + waddr = IST30XX_DA_ADDR(param.sensor3_addr); + len = param.cs_sensor3_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("cs sensor reg3 loaded!\n"); + } + } else if (mode == CMCS_FLAG_CMJIT) { + waddr = IST30XX_DA_ADDR(param.sensor1_addr); + len = (param.jit_sensor1_size / IST30XX_DATA_LEN) - 2; + buf32 += 2; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("jit sensor reg1 loaded!\n"); + } + + buf32 += len; + waddr = IST30XX_DA_ADDR(param.sensor2_addr); + len = param.jit_sensor2_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("jit sensor reg2 loaded!\n"); + } + + buf32 += len; + waddr = IST30XX_DA_ADDR(param.sensor3_addr); + len = param.jit_sensor3_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", + buf32[0], buf32[1], buf32[2], buf32[3]); + tsp_verb("%08x(%d)\n", waddr, len); + + if (len > 0) { + ret = ist30xx_burst_write(data->client, waddr, buf32, len); + if (ret) + return ret; + + tsp_info("jit sensor reg3 loaded!\n"); + } + } + + return 0; +} + +int ist30xx_set_cmcs_cmd(struct ist30xx_data *data, CMCS_CMD cmds) +{ + int ret; + int i; + u32 val; + u32 waddr; + + for (i = 0; i < cmds.cnt; i++) { + waddr = IST30XX_DA_ADDR(cmds.cmd[i].addr); + val = cmds.cmd[i].value; + ret = ist30xx_write_cmd(data, waddr, val); + if (ret) + return ret; + tsp_verb("cmd%d(0x%08x): 0x%08x\n", i, waddr, val); + } + + tsp_info("cmcs command loaded!\n"); + + return 0; +} + +int ist30xx_parse_cmcs_buf(struct ist30xx_data *data, s16 *buf) +{ + int i, j; + TSP_INFO *tsp = &data->tsp_info; + + tsp_info(" %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + tsp_info(" "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%5d ", buf[i * tsp->ch_num.rx + j]); + printk("\n"); + } + + return 0; +} + +int ist30xx_apply_cmcs_slope(struct ist30xx_data *data, CMCS_BUF *cmcs_buf) +{ + int i, j, k; + int idx1, idx2, gtx_idx, key_idx; + int type; + int success = false; + TSP_INFO *tsp = &data->tsp_info; + int width = tsp->screen.rx; + int height = tsp->screen.tx; + s16 *presult; +#ifdef IST30XX_SDC_SLOPE + s16 slope_x = 0; + s16 slope_y = 0; +#else + s16 *pspec_min = (s16 *)cmcs_buf->spec_min; + s16 *pspec_max = (s16 *)cmcs_buf->spec_max; +#endif + s16 *pslope0 = (s16 *)cmcs_buf->slope0; + s16 *pslope1 = (s16 *)cmcs_buf->slope1; + + memset(cmcs_buf->slope0, 0, sizeof(cmcs_buf->slope0)); + memset(cmcs_buf->slope1, 0, sizeof(cmcs_buf->slope1)); + + if (!strcmp(ts_cmcs->spec_slope.name, CMCS_CS)) + presult = (s16 *)&cmcs_buf->cs; + else + presult = (s16 *)&cmcs_buf->cm; + + for (i = 0; i < ts_cmcs->items.cnt; i++) { + if (!strcmp(ts_cmcs->spec_slope.name, ts_cmcs->items.item[i].name)) { + idx1 = idx2 = gtx_idx = key_idx = 0; + gtx_idx = tsp->screen.tx * tsp->screen.rx; + key_idx = gtx_idx + (tsp->gtx.num * tsp->screen.rx); + for (j = 0; j < tsp->ch_num.tx; j++) { + for (k = 0; k < tsp->ch_num.rx; k++) { + type = check_tsp_type(data, j, k); + idx1 = (j * tsp->ch_num.rx) + k; + if (type == TSP_CH_UNKNOWN) { + continue; + } else if (type == TSP_CH_UNUSED) { + cmcs_buf->spec_min[idx1] = 0; + cmcs_buf->spec_max[idx1] = 0; + } else if (type == TSP_CH_GTX) { + cmcs_buf->spec_min[idx1] = + ts_cmcs->spec_item[i].spec_node.buf_min[gtx_idx]; + cmcs_buf->spec_max[idx1] = + ts_cmcs->spec_item[i].spec_node.buf_max[gtx_idx]; + gtx_idx++; + } else if (type == TSP_CH_KEY) { + cmcs_buf->spec_min[idx1] = + ts_cmcs->spec_item[i].spec_node.buf_min[key_idx]; + cmcs_buf->spec_max[idx1] = + ts_cmcs->spec_item[i].spec_node.buf_max[key_idx]; + key_idx++; + } else { + cmcs_buf->spec_min[idx1] = + ts_cmcs->spec_item[i].spec_node.buf_min[idx2]; + cmcs_buf->spec_max[idx1] = + ts_cmcs->spec_item[i].spec_node.buf_max[idx2]; + idx2++; + } + } + } + success = true; + } + } + + if (success == false) + return -EPERM; + +#if CMCS_PARSING_DEBUG + idx1 = 0; + tsp_info("# Node min specific\n"); + for (i = 0; i < tsp->ch_num.tx; i++) { + tsp_info(" "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%5d ", cmcs_buf->spec_min[idx1++]); + printk("\n"); + } + + idx1 = 0; + tsp_info("# Node max specific\n"); + for (i = 0; i < tsp->ch_num.tx; i++) { + tsp_info(" "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%5d ", cmcs_buf->spec_max[idx1++]); + printk("\n"); + } +#endif + +#ifdef IST30XX_SDC_SLOPE + tsp_verb("# Apply slope\n"); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + idx1 = (i * tsp->ch_num.rx) + j; + + idx2 = idx1 + 1; + if (j == (width - 1)) { + slope_x = 0; + } else { + slope_x = 100 - ((presult[idx1] * 100) / presult[idx2]); + if (slope_x < 0) + slope_x *= -1; + } + + idx2 = idx1 + tsp->ch_num.rx; + if (i == (height - 1)) { + slope_y = 0; + } else { + slope_y = 100 - ((presult[idx1] * 100) / presult[idx2]); + if (slope_y < 0) + slope_y *= -1; + } + + if (slope_x > slope_y) { + pslope0[idx1] = (s16)slope_x; + pslope1[idx1] = (s16)slope_x; + } else { + pslope0[idx1] = (s16)slope_y; + pslope1[idx1] = (s16)slope_y; + } + } + } + + tsp_verb("# Apply slope_gtx\n"); + for (i = 0; i < tsp->gtx.num; i++) { + if (tsp->gtx.ch_num[i] > height) { + for (j = 0; j < width; j++) { + idx1 = (tsp->gtx.ch_num[i] * tsp->ch_num.rx) + j; + + idx2 = idx1 + 1; + if (j == (width - 1)) { + slope_x = 0; + } else { + slope_x = 100 - ((presult[idx1] * 100) / presult[idx2]); + if (slope_x < 0) + slope_x *= -1; + } + + idx2 = idx1 + tsp->ch_num.rx; + if (i == (tsp->gtx.num - 1)) { + slope_y = 0; + } else { + slope_y = 100 - ((presult[idx1] * 100) / presult[idx2]); + if (slope_y < 0) + slope_y *= -1; + } + + if (slope_x > slope_y) { + pslope0[idx1] = (s16)slope_x; + pslope1[idx1] = (s16)slope_x; + } else { + pslope0[idx1] = (s16)slope_y; + pslope1[idx1] = (s16)slope_y; + } + } + } + } +#else + tsp_verb("# Apply slope0\n"); + for (i = 0; i < height; i++) { + for (j = 0; j < width - 1; j++) { + idx1 = (i * tsp->ch_num.rx) + j; + idx2 = idx1 + 1; + + pslope0[idx1] = (presult[idx2] - presult[idx1]); + pslope0[idx1] += + (((pspec_min[idx1] + pspec_max[idx1]) / 2) - + ((pspec_min[idx2] + pspec_max[idx2]) / 2)); + } + } + + tsp_verb("# Apply slope1\n"); + for (i = 0; i < height - 1; i++) { + for (j = 0; j < width; j++) { + idx1 = (i * tsp->ch_num.rx) + j; + idx2 = idx1 + tsp->ch_num.rx; + + pslope1[idx1] = (presult[idx2] - presult[idx1]); + pslope1[idx1] += + (((pspec_min[idx1] + pspec_max[idx1]) / 2) - + ((pspec_min[idx2] + pspec_max[idx2]) / 2)); + } + } + + tsp_verb("# Apply slope0 gtx\n"); + for (i = 0; i < tsp->gtx.num; i++) { + if (tsp->gtx.ch_num[i] > height) { + for (j = 0; j < width - 1; j++) { + idx1 = (tsp->gtx.ch_num[i] * tsp->ch_num.rx) + j; + idx2 = idx1 + 1; + + pslope0[idx1] = (presult[idx2] - presult[idx1]); + pslope0[idx1] += + (((pspec_min[idx1] + pspec_max[idx1]) / 2) - + ((pspec_min[idx2] + pspec_max[idx2]) / 2)); + } + } + } + + tsp_verb("# Apply slope1 gtx\n"); + for (i = 0; i < (tsp->gtx.num - 1); i++) { + if (tsp->gtx.ch_num[i] > height) { + for (j = 0; j < width; j++) { + idx1 = (tsp->gtx.ch_num[i] * tsp->ch_num.rx) + j; + idx2 = idx1 + tsp->ch_num.rx; + + pslope1[idx1] = (presult[idx2] - presult[idx1]); + pslope1[idx1] += + (((pspec_min[idx1] + pspec_max[idx1]) / 2) - + ((pspec_min[idx2] + pspec_max[idx2]) / 2)); + } + } + } +#endif + +#if CMCS_PARSING_DEBUG + tsp_info("# slope0_x\n"); + for (i = 0; i < height; i++) { + tsp_info(" "); + for (j = 0; j < width; j++) { + idx1 = (i * tsp->ch_num.rx) + j; + printk("%5d ", pslope0[idx1]); + } + printk("\n"); + } + + tsp_info("# slope1_y\n"); + for (i = 0; i < height; i++) { + tsp_info(" "); + for (j = 0; j < width; j++) { + idx1 = (i * tsp->ch_num.rx) + j; + printk("%5d ", pslope1[idx1]); + } + printk("\n"); + } + + tsp_info("# slope0_gtx_x\n"); + for (i = 0; i < tsp->gtx.num; i++) { + tsp_info(" "); + for (j = 0; j < width; j++) { + idx1 = (tsp->gtx.ch_num[i] * tsp->ch_num.rx) + j; + printk("%5d ", pslope0[idx1]); + } + printk("\n"); + } + + tsp_info("# slope1_gtx_y\n"); + for (i = 0; i < tsp->gtx.num; i++) { + tsp_info(" "); + for (j = 0; j < width; j++) { + idx1 = (tsp->gtx.ch_num[i] * tsp->ch_num.rx) + j; + printk("%5d ", pslope1[idx1]); + } + printk("\n"); + } +#endif + + return 0; +} + +int ist30xx_get_cmcs_buf(struct ist30xx_data *data, const char *mode, + CMCS_ITEM items, s16 *buf) +{ + int ret = 0; + int i; + bool success = false; + u32 waddr; + u16 len; + + for (i = 0; i < items.cnt; i++) { + if (!strcmp(items.item[i].name, mode)) { + waddr = IST30XX_DA_ADDR(items.item[i].addr); + len = items.item[i].size / IST30XX_DATA_LEN; + ret = ist30xx_burst_read(data->client, + waddr, (u32 *)buf, len, true); + if (unlikely(ret)) + return ret; + tsp_verb("%s, 0x%08x, %d\n", __func__, waddr, len); + success = true; + } + } + + if (success == false) { + tsp_info("item(%s) dosen't exist!\n", mode); + return ret; + } + +#if CMCS_PARSING_DEBUG + ret = ist30xx_parse_cmcs_buf(data, buf); +#endif + + return ret; +} + +int ist30xx_cmcs_wait(struct ist30xx_data *data, int mode) +{ + u32 waddr; + u32 val; + int ret; + int cnt = CMCS_TIMEOUT / 100; + + data->status.cmcs = 0; + + waddr = IST30XX_DA_ADDR(ts_cmcs->param.enable_addr); + if (mode == CMCS_FLAG_CM) + val = CMCS_ENABLE_CM; + else if (mode == CMCS_FLAG_CM2) + val = CMCS_ENABLE_CM2; + else if (mode == CMCS_FLAG_CS) + val = CMCS_ENABLE_CS; + else if (mode == CMCS_FLAG_CMJIT) + val = CMCS_ENABLE_CMJIT; + else if (mode == CMCS_FLAG_INT) + val = CMCS_ENABLE_INT; + else + return -EPERM; + + ret = ist30xx_write_cmd(data, waddr, val); + if (ret) + return -EPERM; + + while (cnt-- > 0) { + ist30xx_delay(100); + + if (data->status.cmcs) { + if (mode == CMCS_FLAG_CM) + goto cm_end; + else if (mode == CMCS_FLAG_CM2) + goto cm2_end; + else if (mode == CMCS_FLAG_CS) + goto cs_end; + else if (mode == CMCS_FLAG_CMJIT) + goto cmjit_end; + else if (mode == CMCS_FLAG_INT) + goto int_end; + else + return -EPERM; + } + } + tsp_warn("cmcs time out\n"); + + return -EPERM; + +cm_end: + if ((data->status.cmcs & CMCS_MSG_MASK) == CM_MSG_VALID) + if (!(data->status.cmcs & 0x1)) + return 0; + + tsp_warn("CM test fail\n"); + + return -EPERM; + +cm2_end: + if ((data->status.cmcs & CMCS_MSG_MASK) == CM2_MSG_VALID) + if (!(data->status.cmcs & 0x1)) + return 0; + + tsp_warn("CM2 test fail\n"); + + return -EPERM; + +cs_end: + if ((data->status.cmcs & CMCS_MSG_MASK) == CS_MSG_VALID) + if (!(data->status.cmcs & 0x1)) + return 0; + + tsp_warn("CS test fail\n"); + + return -EPERM; + +cmjit_end: + if ((data->status.cmcs & CMCS_MSG_MASK) == CMJIT_MSG_VALID) + if (!(data->status.cmcs & 0x1)) + return 0; + + tsp_warn("CMJIT test fail\n"); + + return -EPERM; + +int_end: + if ((data->status.cmcs & CMCS_MSG_MASK) == INT_MSG_VALID) + if (!(data->status.cmcs & 0x1)) + return 0; + + tsp_warn("INT test fail\n"); + + return -EPERM; +} + +int ist30xx_item_test(struct ist30xx_data *data, CMCS_ITEM items, + CMCS_PARAM param, const char *mode, u32 flag, u32 *buf32, s16 *buf) +{ + int i; + int ret; + + for (i = 0; i < items.cnt; i++) { + if (!strcmp(items.item[i].name, mode)) { + ret = ist30xx_set_cmcs_sensor(data, param, buf32, flag); + if (ret) { + tsp_info("%s test not ready!!\n", mode); + return ret; + } + tsp_info("%s test!!\n", mode); + + /* 6-2. write Start CM enable & wait CM complete interrupt */ + ist30xx_enable_irq(data); + if (ist30xx_cmcs_wait(data, flag)) { + tsp_info("%s test fail!\n", mode); + ret = -ENOEXEC; + return ret; + } + ist30xx_disable_irq(data); + + /* 6-3. read CM data */ + ret = ist30xx_get_cmcs_buf(data, mode, items, buf); + if (ret) { + tsp_info("fail to read %s data\n", mode); + return ret; + } + + tsp_info("read %s data\n", mode); + } + } + + return 0; +} + +#define cmcs_next_step(ret) { if (unlikely(ret)) goto end; ist30xx_delay(20); } +int ist30xx_cmcs_test(struct ist30xx_data *data, const u8 *buf, int size) +{ + int ret; + u32 waddr; + u32 chksum = 0; + u32 *buf32; + + tsp_info("*** CM/CS test ***\n"); + + ist30xx_disable_irq(data); + ist30xx_reset(data, false); + + /* 1. set CmCsFW write mode */ + ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_RUN_RAMCODE << 16) | 0); + cmcs_next_step(ret); + + /* 2. write CmCsFW */ + buf32 = (u32 *)ts_cmcs->buf_cmcs; + ret = ist30xx_set_cmcs_fw(data, ts_cmcs->param, buf32); + cmcs_next_step(ret); + + /* 3. write cmds */ + ret = ist30xx_set_cmcs_cmd(data, ts_cmcs->cmds); + cmcs_next_step(ret); + + /* 4. start CmCsFW */ + ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_RUN_RAMCODE << 16) | 1); + cmcs_next_step(ret); + + /* 5. read & compare checksum */ + waddr = IST30XX_DA_ADDR(ts_cmcs->param.checksum_addr); + ret = ist30xx_read_reg(data->client, waddr, &chksum); + cmcs_next_step(ret); + if (chksum != ts_cmcs->param.cmcs_chksum) + goto end; + + /* 6. CM Test */ + buf32 = ts_cmcs->buf_cm_sensor; + memset(ts_cmcs_buf->cm, 0, sizeof(ts_cmcs_buf->cm)); + ret = ist30xx_item_test(data, ts_cmcs->items, ts_cmcs->param, CMCS_CM, + CMCS_FLAG_CM, buf32, ts_cmcs_buf->cm); + cmcs_next_step(ret); + + /* 7. CM2 Test */ + buf32 = ts_cmcs->buf_cm_sensor; + memset(ts_cmcs_buf->cm2, 0, sizeof(ts_cmcs_buf->cm2)); + ret = ist30xx_item_test(data, ts_cmcs->items, ts_cmcs->param, CMCS_CM2, + CMCS_FLAG_CM2, buf32, ts_cmcs_buf->cm2); + cmcs_next_step(ret); + + /* 8. CMJIT Test */ + buf32 = ts_cmcs->buf_jit_sensor; + memset(ts_cmcs_buf->cm_jit, 0, sizeof(ts_cmcs_buf->cm_jit)); + ret = ist30xx_item_test(data, ts_cmcs->items, ts_cmcs->param, CMCS_CMJIT, + CMCS_FLAG_CMJIT, buf32, ts_cmcs_buf->cm_jit); + cmcs_next_step(ret); + + /* 9. CS Test */ + buf32 = ts_cmcs->buf_cs_sensor; + memset(ts_cmcs_buf->cs, 0, sizeof(ts_cmcs_buf->cs)); + ret = ist30xx_item_test(data, ts_cmcs->items, ts_cmcs->param, CMCS_CS, + CMCS_FLAG_CS, buf32, ts_cmcs_buf->cs); + cmcs_next_step(ret); + + /* 10. calculate slope value */ + ret = ist30xx_apply_cmcs_slope(data, ts_cmcs_buf); + cmcs_next_step(ret); + + cmcs_ready = CMCS_READY; +end: + if (unlikely(ret)) { + tsp_warn("CmCs test Fail!, ret=%d\n", ret); + } else if (unlikely(chksum != ts_cmcs->param.cmcs_chksum)) { + tsp_warn("Error CheckSum: %x(%x)\n", + chksum, ts_cmcs->param.cmcs_chksum); + ret = -ENOEXEC; + } + + ist30xx_reset(data, false); + ist30xx_enable_irq(data); + ist30xx_start(data); + + return ret; +} + + +int check_tsp_type(struct ist30xx_data *data, int tx, int rx) +{ + int i; + TSP_INFO *tsp = &data->tsp_info; + TKEY_INFO *tkey = &data->tkey_info; + + if ((tx >= tsp->ch_num.tx) || (tx < 0) || + (rx >= tsp->ch_num.rx) || (rx < 0)) { + tsp_warn("TSP channel is not correct!! (%d * %d)\n", tx, rx); + return TSP_CH_UNKNOWN; + } + + if ((tx >= tsp->screen.tx) || (rx >= tsp->screen.rx)) { + for (i = 0; i < tsp->gtx.num; i++) + if ((tx == tsp->gtx.ch_num[i]) && (rx < tsp->screen.rx)) + return TSP_CH_GTX; + + for (i = 0; i < tkey->key_num; i++) { + if ((tx == tkey->ch_num[i].tx) && + (rx == tkey->ch_num[i].rx)) + return TSP_CH_KEY; + } + } else { + return TSP_CH_SCREEN; + } + + return TSP_CH_UNUSED; +} + +int print_cmcs(struct ist30xx_data *data, s16 *buf16, char *buf) +{ + int i, j; + int idx; + int type; + int count = 0; + char msg[128]; + + TSP_INFO *tsp = &data->tsp_info; + + int tx_num = tsp->ch_num.tx; + int rx_num = tsp->ch_num.rx; + + for (i = 0; i < tx_num; i++) { + for (j = 0; j < rx_num; j++) { + type = check_tsp_type(data, i, j); + idx = (i * rx_num) + j; + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + count += sprintf(msg, "%5d ", 0); + else + count += sprintf(msg, "%5d ", buf16[idx]); + strcat(buf, msg); + } + + count += sprintf(msg, "\n"); + strcat(buf, msg); + } + + return count; +} + +int print_line_cmcs(struct ist30xx_data *data, int mode, s16 *buf16, char *buf) +{ + int i, j; + int idx; + int type; + int count = 0; + int key_index[5] = { 0, }; + int key_cnt = 0; + char msg[128]; + + TSP_INFO *tsp = &data->tsp_info; + + int tx_num = tsp->ch_num.tx; + int rx_num = tsp->ch_num.rx; + + for (i = 0; i < tx_num; i++) { + for (j = 0; j < rx_num; j++) { + type = check_tsp_type(data, i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; + + if ((mode == CMCS_FLAG_CM_SLOPE0) && + (j == (tsp->screen.rx - 1))) + continue; + else if ((mode == CMCS_FLAG_CM_SLOPE1) && + (i == (tsp->screen.tx - 1))) + continue; + + if ((mode == CMCS_FLAG_CM_SLOPE0) && (type == TSP_CH_GTX) && + (j == (tsp->screen.rx - 1))) + continue; + else if ((mode == CMCS_FLAG_CM_SLOPE1) && + (type == TSP_CH_GTX) && + (i == tsp->gtx.ch_num[tsp->gtx.num - 1])) + continue; + + idx = (i * rx_num) + j; + + if (type == TSP_CH_KEY) { + key_index[key_cnt++] = idx; + continue; + } + + count += sprintf(msg, "%5d ", buf16[idx]); + strcat(buf, msg); + } + } + + if ((mode != CMCS_FLAG_CM_SLOPE0) && (mode != CMCS_FLAG_CM_SLOPE1)) { + tsp_debug("key cnt: %d\n", key_cnt); + for (i = 0; i < key_cnt; i++) { + count += sprintf(msg, "%5d ", buf16[key_index[i]]); + strcat(buf, msg); + } + } + + count += sprintf(msg, "\n"); + strcat(buf, msg); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/info */ +ssize_t ist30xx_cmcs_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i; + int count; + char msg[128]; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + TKEY_INFO *tkey = &data->tkey_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + /* Channel */ + count = sprintf(msg, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ", + tsp->ch_num.tx, tsp->ch_num.rx, tsp->screen.tx, tsp->screen.rx, + tsp->gtx.num, tsp->gtx.ch_num[0], tsp->gtx.ch_num[1], + tsp->gtx.ch_num[2], tsp->gtx.ch_num[3], tkey->key_num, + tkey->ch_num[0].tx, tkey->ch_num[0].rx, tkey->ch_num[1].tx, + tkey->ch_num[1].rx, tkey->ch_num[2].tx, tkey->ch_num[2].rx, + tkey->ch_num[3].tx, tkey->ch_num[3].rx, tkey->ch_num[4].tx, + tkey->ch_num[4].rx); + strcat(buf, msg); + + /* Slope */ + count += sprintf(msg, "%d %d %d %d %d %d %d %d %d %d ", + ts_cmcs->spec_slope.x_min, ts_cmcs->spec_slope.x_max, + ts_cmcs->spec_slope.y_min, ts_cmcs->spec_slope.y_max, + ts_cmcs->spec_slope.gtx_x_min, ts_cmcs->spec_slope.gtx_x_max, + ts_cmcs->spec_slope.gtx_y_min, ts_cmcs->spec_slope.gtx_y_max, + ts_cmcs->spec_slope.key_min, ts_cmcs->spec_slope.key_max); + strcat(buf, msg); + + /* CS */ + for (i = 0; i < ts_cmcs->items.cnt; i++) { + if (!strcmp(ts_cmcs->items.item[i].name, CMCS_CS)) { + if (!strcmp(ts_cmcs->items.item[i].spec_type, "T")) { + count += sprintf(msg, "%d %d %d %d %d %d ", + ts_cmcs->spec_item[i].spec_total.screen_min, + ts_cmcs->spec_item[i].spec_total.screen_max, + ts_cmcs->spec_item[i].spec_total.gtx_min, + ts_cmcs->spec_item[i].spec_total.gtx_max, + ts_cmcs->spec_item[i].spec_total.key_min, + ts_cmcs->spec_item[i].spec_total.key_max); + strcat(buf, msg); + } + } + } + + /* CR */ + count += sprintf(msg, "%d %d %d %d %d %d ", + ts_cmcs->spec_cr.screen_min, ts_cmcs->spec_cr.screen_max, + ts_cmcs->spec_cr.gtx_min, ts_cmcs->spec_cr.gtx_max, + ts_cmcs->spec_cr.key_min, ts_cmcs->spec_cr.key_max); + strcat(buf, msg); + + /* CMJIT */ + for (i = 0; i < ts_cmcs->items.cnt; i++) { + if (!strcmp(ts_cmcs->items.item[i].name, CMCS_CMJIT)) { + if (!strcmp(ts_cmcs->items.item[i].spec_type, "T")) { + count += sprintf(msg, "%d %d %d %d %d %d ", + ts_cmcs->spec_item[i].spec_total.screen_min, + ts_cmcs->spec_item[i].spec_total.screen_max, + ts_cmcs->spec_item[i].spec_total.gtx_min, + ts_cmcs->spec_item[i].spec_total.gtx_max, + ts_cmcs->spec_item[i].spec_total.key_min, + ts_cmcs->spec_item[i].spec_total.key_max); + strcat(buf, msg); + } + } + } + + tsp_verb("%s\n", buf); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/cmcs_binary */ +ssize_t ist30xx_cmcs_binary_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct ist30xx_data *data = dev_get_drvdata(dev); + + if ((ts_cmcs_bin == NULL) || (ts_cmcs_bin_size == 0)) + return sprintf(buf, "Binary is not correct(%d)\n", ts_cmcs_bin_size); + + ret = ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); + if (ret) + goto binary_end; + + mutex_lock(&data->lock); + ret = ist30xx_cmcs_test(data, ts_cmcs_bin, ts_cmcs_bin_size); + mutex_unlock(&data->lock); + +binary_end: + return sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n")); +} + +/* sysfs: /sys/class/touch/cmcs/cmcs_custom */ +ssize_t ist30xx_cmcs_custom_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + int bin_size = 0; + u8 *bin = NULL; + const struct firmware *req_bin = NULL; + struct ist30xx_data *data = dev_get_drvdata(dev); + + ret = request_firmware(&req_bin, IST30XX_CMCS_NAME, &data->client->dev); + if (ret) + return sprintf(buf, "File not found, %s\n", IST30XX_CMCS_NAME); + + bin = (u8 *)req_bin->data; + bin_size = (u32)req_bin->size; + + ret = ist30xx_get_cmcs_info(bin, bin_size); + if (ret) + goto custom_end; + + mutex_lock(&data->lock); + ret = ist30xx_cmcs_test(data, bin, bin_size); + mutex_unlock(&data->lock); + +custom_end: + release_firmware(req_bin); + + return sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n")); +} + +#define MAX_FILE_PATH 255 +/* sysfs: /sys/class/touch/cmcs/cmcs_sdcard */ +ssize_t ist30xx_cmcs_sdcard_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + int bin_size = 0; + u8 *bin = NULL; + const u8 *buff = 0; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + long fsize = 0, nread = 0; + char fw_path[MAX_FILE_PATH]; + struct ist30xx_data *data = dev_get_drvdata(dev); + + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/%s", + IST30XX_CMCS_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + tsp_info("file %s open error:%d\n", fw_path, PTR_ERR(fp)); + ret = -ENOENT; + goto err_file_open; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + + buff = kzalloc((size_t)fsize, GFP_KERNEL); + if (!buff) { + tsp_info("fail to alloc buffer\n"); + ret = -ENOMEM; + goto err_alloc; + } + + nread = vfs_read(fp, (char __user *)buff, fsize, &fp->f_pos); + if (nread != fsize) { + tsp_info("mismatch fw size\n"); + + goto err_fw_size; + } + + bin = (u8 *)buff; + bin_size = (u32)fsize; + + filp_close(fp, current->files); + set_fs(old_fs); + tsp_info("firmware is loaded!!\n"); + + ret = ist30xx_get_cmcs_info(bin, bin_size); + if (ret) + goto sdcard_end; + + mutex_lock(&data->lock); + ret = ist30xx_cmcs_test(data, bin, bin_size); + mutex_unlock(&data->lock); + +err_fw_size: + if (buff) + kfree(buff); +err_alloc: + if (fp) + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + +sdcard_end: + tsp_info("size: %d\n", sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n"))); + + return sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n")); +} + +/* sysfs: /sys/class/touch/cmcs/cm_jit */ +ssize_t ist30xx_cm_jit_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CMJIT (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->cm_jit, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm */ +ssize_t ist30xx_cm_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CM (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->cm, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_spec_min */ +ssize_t ist30xx_cm_spec_min_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CM Spec Min (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->spec_min, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_spec_max */ +ssize_t ist30xx_cm_spec_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CM Spec Max (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->spec_max, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope0 */ +ssize_t ist30xx_cm_slope0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CM Slope0_X (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->slope0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope1 */ +ssize_t ist30xx_cm_slope1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CM Slope1_Y (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->slope1, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm2 */ +ssize_t ist30xx_cm2_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CM2 (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->cm2, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cs */ +ssize_t ist30xx_cs_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + tsp_verb("CS (%d * %d)\n", tsp->ch_num.tx, tsp->ch_num.rx); + + return print_cmcs(data, ts_cmcs_buf->cs, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cs_tx */ +ssize_t ist30xx_cs_tx_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i; + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + char msg[8]; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + for (i = 0; i < tsp->ch_num.tx; i++) { + count += sprintf(msg, "%5d ", (ts_cmcs_buf->cs_tx_result >> i) & 1); + strcat(buf, msg); + } + + count += sprintf(msg, "\n"); + strcat(buf, msg); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/cs_rx */ +ssize_t ist30xx_cs_rx_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i; + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + char msg[8]; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + for (i = 0; i < tsp->ch_num.rx; i++) { + count += sprintf(msg, "%5d ", (ts_cmcs_buf->cs_rx_result >> i) & 1); + strcat(buf, msg); + } + + count += sprintf(msg, "\n"); + strcat(buf, msg); + + return count; +} + +int print_cm_slope_result(struct ist30xx_data *data, u8 flag, s16 *buf16, + char *buf, bool fail_list) +{ + int i, j; + int type, idx; + int count = 0, err_cnt = 0; + int min_spec, max_spec, gtx_min_spec, gtx_max_spec; + + char msg[128]; + + TSP_INFO *tsp = &data->tsp_info; + struct CMCS_SPEC_SLOPE *spec = + (struct CMCS_SPEC_SLOPE *)&ts_cmcs->spec_slope; + + if (flag == CMCS_FLAG_CM_SLOPE0) { + min_spec = spec->x_min; + max_spec = spec->x_max; + gtx_min_spec = spec->gtx_x_min; + gtx_max_spec = spec->gtx_x_max; + } else if (flag == CMCS_FLAG_CM_SLOPE1) { + min_spec = spec->y_min; + max_spec = spec->y_max; + gtx_min_spec = spec->gtx_y_min; + gtx_max_spec = spec->gtx_y_max; + } else { + count = sprintf(msg, "Unknown flag: %d\n", flag); + strcat(buf, msg); + return count; + } + + if (fail_list) { + count = sprintf(msg, "Spec: screen(%d~%d), GTx(%d~%d)\n", + min_spec, max_spec, gtx_min_spec, gtx_max_spec); + strcat(buf, msg); + } + + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + idx = (i * tsp->ch_num.rx) + j; + + type = check_tsp_type(data, i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED) || + (type == TSP_CH_KEY)) + continue; + + if (type == TSP_CH_SCREEN) { + if ((buf16[idx] >= min_spec) && (buf16[idx] <= max_spec)) + continue; + } else if (type == TSP_CH_GTX) { + if ((buf16[idx] >= gtx_min_spec) && + (buf16[idx] <= gtx_max_spec)) + continue; + } + + if (fail_list) { + count += sprintf(msg, "%2d,%2d:%4d\n", i, j, buf16[idx]); + strcat(buf, msg); + } + + err_cnt++; + } + } + + /* Check error count */ + if (err_cnt == 0) + count += sprintf(msg, "OK\n"); + else + count += sprintf(msg, "Fail, node count: %d\n", err_cnt); + strcat(buf, msg); + + return count; +} + +int print_cm_key_slope_result(struct ist30xx_data *data, s16 *buf16, char *buf, + bool print) +{ + int i, j; + int type, idx; + int count = 0; + int min_spec, max_spec; + int key_num = 0; + s16 key_cm[5] = { 0, }; + s16 slope_result; + + char msg[128]; + + TSP_INFO *tsp = &data->tsp_info; + struct CMCS_SPEC_SLOPE *spec = + (struct CMCS_SPEC_SLOPE *)&ts_cmcs->spec_slope; + + min_spec = spec->key_min; + max_spec = spec->key_max; + + if (print) { + count = sprintf(msg, "Spec: %d ~ %d\n", min_spec, max_spec); + strcat(buf, msg); + } + + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + idx = (i * tsp->ch_num.rx) + j; + + type = check_tsp_type(data, i, j); + if (type == TSP_CH_KEY) + key_cm[key_num++] = buf16[idx]; + } + } + + /* Check key slope */ + slope_result = key_cm[0] - key_cm[1]; + + if (print) { + if ((slope_result >= min_spec) && (slope_result <= max_spec)) + count += sprintf(msg, "OK (%d)\n", slope_result); + else + count += sprintf(msg, "Fail (%d)\n", slope_result); + } else { + count += sprintf(msg, "%d\n", + (slope_result >= 0 ? slope_result : -slope_result)); + } + + strcat(buf, msg); + + return count; +} + +int print_cm_result(struct ist30xx_data *data, char *buf, bool fail_list) +{ + int i, j; + int type, idx, err_cnt = 0; + int min_spec, max_spec; + int count = 0; + short cm; + char msg[128]; + TSP_INFO *tsp = &data->tsp_info; + + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + idx = (i * tsp->ch_num.rx) + j; + + type = check_tsp_type(data, i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; + + min_spec = ts_cmcs_buf->spec_min[idx]; + max_spec = ts_cmcs_buf->spec_max[idx]; + + cm = ts_cmcs_buf->cm[idx]; + if ((cm >= min_spec) && (cm <= max_spec)) + continue; + + if (fail_list) { + count += sprintf(msg, "%2d,%2d:%4d (%4d~%4d)\n", + i, j, cm, min_spec, max_spec); + strcat(buf, msg); + } + + err_cnt++; + } + } + + /* Check error count */ + if (err_cnt == 0) + count += sprintf(msg, "OK\n"); + else + count += sprintf(msg, "Fail, node count: %d\n", err_cnt); + strcat(buf, msg); + + return count; +} + +int print_total_result(struct ist30xx_data *data, s16 *buf16, char *buf, + const char *mode, bool fail_list) +{ + int i, j; + bool success = false; + int type, idx; + int count = 0, err_cnt = 0; + int min_spec, max_spec; + char msg[128]; + + TSP_INFO *tsp = &data->tsp_info; + struct CMCS_SPEC_TOTAL *spec; + + for (i = 0; i < ts_cmcs->items.cnt; i++) { + if (!strcmp(ts_cmcs->items.item[i].name, mode)) { + if (!strcmp(ts_cmcs->items.item[i].spec_type, "T")) { + spec = + (struct CMCS_SPEC_TOTAL *)&ts_cmcs->spec_item[i].spec_total; + success = true; + break; + } + } + } + + if (success == false) + return 0; + + if (fail_list) { + count = sprintf(msg, "Spec: screen(%d~%d), gtx(%d~%d), key(%d~%d)\n", + spec->screen_min, spec->screen_max, spec->gtx_min, + spec->gtx_max, spec->key_min, spec->key_max); + strcat(buf, msg); + } + + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + idx = (i * tsp->ch_num.rx) + j; + + type = check_tsp_type(data, i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; + + if (type == TSP_CH_SCREEN) { + min_spec = spec->screen_min; + max_spec = spec->screen_max; + } else if (type == TSP_CH_GTX) { + min_spec = spec->gtx_min; + max_spec = spec->gtx_max; + } else { + min_spec = spec->key_min; + max_spec = spec->key_max; + } + + if ((buf16[idx] >= min_spec) && (buf16[idx] <= max_spec)) + continue; + + if (fail_list) { + count += sprintf(msg, "%2d,%2d:%4d\n", i, j, buf16[idx]); + strcat(buf, msg); + } + + err_cnt++; + } + } + + /* Check error count */ + if (err_cnt == 0) + count += sprintf(msg, "OK\n"); + else + count += sprintf(msg, "Fail, node count: %d\n", err_cnt); + strcat(buf, msg); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/cm_jit_result */ +ssize_t ist30xx_cm_jit_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_total_result(data, ts_cmcs_buf->cm_jit, buf, CMCS_CMJIT, true); +} + +/* sysfs: /sys/class/touch/cmcs/cm_result */ +ssize_t ist30xx_cm_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_cm_result(data, buf, true); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope0_result */ +ssize_t ist30xx_cm_slope0_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_cm_slope_result(data, CMCS_FLAG_CM_SLOPE0, + ts_cmcs_buf->slope0, buf, true); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope1_result */ +ssize_t ist30xx_cm_slope1_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_cm_slope_result(data, CMCS_FLAG_CM_SLOPE1, + ts_cmcs_buf->slope1, buf, true); +} + +/* sysfs: /sys/class/touch/cmcs/cm_key_slope_result */ +ssize_t ist30xx_cm_key_slope_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_cm_key_slope_result(data, ts_cmcs_buf->cm, buf, true); +} + +/* sysfs: /sys/class/touch/cmcs/cs_result */ +ssize_t ist30xx_cs_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_total_result(data, ts_cmcs_buf->cs, buf, CMCS_CS, true); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm_jit */ +ssize_t ist30xx_line_cm_jit_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_line_cmcs(data, CMCS_FLAG_CMJIT, ts_cmcs_buf->cm_jit, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm */ +ssize_t ist30xx_line_cm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_line_cmcs(data, CMCS_FLAG_CM, ts_cmcs_buf->cm, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm_slope0 */ +ssize_t ist30xx_line_cm_slope0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_line_cmcs(data, CMCS_FLAG_CM_SLOPE0, ts_cmcs_buf->slope0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm_slope1 */ +ssize_t ist30xx_line_cm_slope1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_line_cmcs(data, CMCS_FLAG_CM_SLOPE1, ts_cmcs_buf->slope1, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm2 */ +ssize_t ist30xx_line_cm2_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_line_cmcs(data, CMCS_FLAG_CM2, ts_cmcs_buf->cm2, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cs */ +ssize_t ist30xx_line_cs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + return print_line_cmcs(data, CMCS_FLAG_CS, ts_cmcs_buf->cs, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_key_slope_value */ +ssize_t ist30xx_cm_key_slope_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + struct ist30xx_data *data = dev_get_drvdata(dev); + + if ((ts_cmcs_bin == NULL) || (ts_cmcs_bin_size == 0)) + goto err_key_slope; + + ret = ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); + if (ret) + goto err_key_slope; + + mutex_lock(&data->lock); + ret = ist30xx_cmcs_test(data, ts_cmcs_bin, ts_cmcs_bin_size); + mutex_unlock(&data->lock); + + if (ret) + goto err_key_slope; + + if (cmcs_ready == CMCS_NOT_READY) + goto err_key_slope; + + return print_cm_key_slope_result(data, ts_cmcs_buf->cm, buf, false); + +err_key_slope: + return sprintf(buf, "%s", "FFFF"); +} + +int cmcs_test_result(struct ist30xx_data *data) +{ + int ret; + int result = 0; + char *msg = NULL; + + msg = kzalloc(sizeof(char) * 4096, GFP_KERNEL); + if (!msg) { + tsp_err("Memory allocation failed\n"); + return 0; + } + + /* CMCS binary */ + if ((ts_cmcs_bin == NULL) || (ts_cmcs_bin_size == 0)) { + tsp_err("Binary is not correct(%d)\n", ts_cmcs_bin_size); + goto out; + } + + ret = ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); + if (ret) { + kfree(msg); + tsp_err("Getting CMCS Binary info failed!\n"); + goto out; + } + + mutex_lock(&data->lock); + ret = ist30xx_cmcs_test(data, ts_cmcs_bin, ts_cmcs_bin_size); + mutex_unlock(&data->lock); + + if (ret) { + kfree(msg); + tsp_err("CMCS Binary test failed!\n"); + goto out; + } + + /* CM result */ + memset(msg, 0, 4096); + print_cm_result(data, msg, false); + if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { + tsp_info("CM result: pass\n"); + } else { + result = -1; + tsp_err("CM result: fail\n"); + } + + /* CM slope0 result */ + memset(msg, 0, 4096); + print_cm_slope_result(data, CMCS_FLAG_CM_SLOPE0, ts_cmcs_buf->slope0, msg, + false); + if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { + tsp_info("Slope0 result: pass\n"); + } else { + result = -1; + tsp_err("Slope0 result: fail\n"); + } + + /* CM slope0 result */ + memset(msg, 0, 4096); + print_cm_slope_result(data, CMCS_FLAG_CM_SLOPE1, ts_cmcs_buf->slope1, msg, + false); + if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { + tsp_info("Slope1 result: pass\n"); + } else { + result = -1; + tsp_err("Slope1 result: fail\n"); + } + + /* CS Result */ + memset(msg, 0, 4096); + print_total_result(data, ts_cmcs_buf->cs, msg, CMCS_CS, false); + if (strncmp(msg, "OK\n", strlen("OK\n")) == 0) { + tsp_info("CS result: pass\n"); + } else { + result = -1; + tsp_debug("CS result: fail\n"); + } + + if (result) + goto out; + + kfree(msg); + return 1; + +out: + kfree(msg); + return 0; +} + +/* sysfs: /sys/class/touch/cmcs/cmcs_test_all */ +ssize_t ist30xx_cmcs_test_all_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int result = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + result = cmcs_test_result(data); + + return sprintf(buf, "%d\n", result); +} + +/* sysfs : cmcs */ +static DEVICE_ATTR(info, S_IRUGO, ist30xx_cmcs_info_show, NULL); +static DEVICE_ATTR(cmcs_binary, S_IRUGO, ist30xx_cmcs_binary_show, NULL); +static DEVICE_ATTR(cmcs_custom, S_IRUGO, ist30xx_cmcs_custom_show, NULL); +static DEVICE_ATTR(cmcs_sdcard, S_IRUGO, ist30xx_cmcs_sdcard_show, NULL); +static DEVICE_ATTR(cm_jit, S_IRUGO, ist30xx_cm_jit_show, NULL); +static DEVICE_ATTR(cm, S_IRUGO, ist30xx_cm_show, NULL); +static DEVICE_ATTR(cm_spec_min, S_IRUGO, ist30xx_cm_spec_min_show, NULL); +static DEVICE_ATTR(cm_spec_max, S_IRUGO, ist30xx_cm_spec_max_show, NULL); +static DEVICE_ATTR(cm_slope0, S_IRUGO, ist30xx_cm_slope0_show, NULL); +static DEVICE_ATTR(cm_slope1, S_IRUGO, ist30xx_cm_slope1_show, NULL); +static DEVICE_ATTR(cm2, S_IRUGO, ist30xx_cm2_show, NULL); +static DEVICE_ATTR(cs, S_IRUGO, ist30xx_cs_show, NULL); +static DEVICE_ATTR(cs_tx, S_IRUGO, ist30xx_cs_tx_show, NULL); +static DEVICE_ATTR(cs_rx, S_IRUGO, ist30xx_cs_rx_show, NULL); +static DEVICE_ATTR(cm_jit_result, S_IRUGO, ist30xx_cm_jit_result_show, NULL); +static DEVICE_ATTR(cm_result, S_IRUGO, ist30xx_cm_result_show, NULL); +static DEVICE_ATTR(cm_slope0_result, S_IRUGO, ist30xx_cm_slope0_result_show, + NULL); +static DEVICE_ATTR(cm_slope1_result, S_IRUGO, ist30xx_cm_slope1_result_show, + NULL); +static DEVICE_ATTR(cm_key_slope_result, S_IRUGO, + ist30xx_cm_key_slope_result_show, NULL); +static DEVICE_ATTR(cs_result, S_IRUGO, ist30xx_cs_result_show, NULL); +static DEVICE_ATTR(line_cm_jit, S_IRUGO, ist30xx_line_cm_jit_show, NULL); +static DEVICE_ATTR(line_cm, S_IRUGO, ist30xx_line_cm_show, NULL); +static DEVICE_ATTR(line_cm_slope0, S_IRUGO, ist30xx_line_cm_slope0_show, NULL); +static DEVICE_ATTR(line_cm_slope1, S_IRUGO, ist30xx_line_cm_slope1_show, NULL); +static DEVICE_ATTR(line_cm2, S_IRUGO, ist30xx_line_cm2_show, NULL); +static DEVICE_ATTR(line_cs, S_IRUGO, ist30xx_line_cs_show, NULL); +static DEVICE_ATTR(cm_key_slope_value, S_IRUGO, ist30xx_cm_key_slope_value_show, + NULL); +static DEVICE_ATTR(cmcs_test_all, S_IRUGO, ist30xx_cmcs_test_all_show, NULL); + +static struct attribute *cmcs_attributes[] = { + &dev_attr_info.attr, + &dev_attr_cmcs_binary.attr, + &dev_attr_cmcs_custom.attr, + &dev_attr_cmcs_sdcard.attr, + &dev_attr_cm_jit.attr, + &dev_attr_cm.attr, + &dev_attr_cm_spec_min.attr, + &dev_attr_cm_spec_max.attr, + &dev_attr_cm_slope0.attr, + &dev_attr_cm_slope1.attr, + &dev_attr_cm2.attr, + &dev_attr_cs.attr, + &dev_attr_cs_tx.attr, + &dev_attr_cs_rx.attr, + &dev_attr_cm_jit_result.attr, + &dev_attr_cm_result.attr, + &dev_attr_cm_slope0_result.attr, + &dev_attr_cm_slope1_result.attr, + &dev_attr_cm_key_slope_result.attr, + &dev_attr_cs_result.attr, + &dev_attr_line_cm_jit.attr, + &dev_attr_line_cm.attr, + &dev_attr_line_cm_slope0.attr, + &dev_attr_line_cm_slope1.attr, + &dev_attr_line_cm2.attr, + &dev_attr_line_cs.attr, + &dev_attr_cm_key_slope_value.attr, + &dev_attr_cmcs_test_all.attr, + NULL, +}; + +static struct attribute_group cmcs_attr_group = { + .attrs = cmcs_attributes, +}; + +extern struct class *ist30xx_class; +struct device *ist30xx_cmcs_dev; + +int ist30xx_init_cmcs_sysfs(struct ist30xx_data *data) +{ + int ret = 0; + + /* /sys/class/touch/cmcs */ + ist30xx_cmcs_dev = device_create(ist30xx_class, NULL, 0, data, "cmcs"); + + /* /sys/class/touch/cmcs/... */ + if (unlikely(sysfs_create_group(&ist30xx_cmcs_dev->kobj, + &cmcs_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "cmcs"); + +#ifdef INTERNAL_CMCS_BIN + ts_cmcs_bin = (u8 *)ist30xx_cmcs; + ts_cmcs_bin_size = sizeof(ist30xx_cmcs); + + ret = ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); +#endif + + return ret; +} +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.h b/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.h new file mode 100644 index 000000000000..13f7254cd89e --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XXC_CMCS_H__ +#define __IST30XXC_CMCS_H__ + +#define INTERNAL_CMCS_BIN + +#define CMCS_MSG_MASK (0xFFFFFFF0) +#define CM_MSG_VALID (0x0E7DC770) +#define CM2_MSG_VALID (0x0E7DC770) +#define CS_MSG_VALID (0x0E7DC500) +#define CMJIT_MSG_VALID (0x0E7D2170) +#define INT_MSG_VALID (0x14709970) + +#define IST30XX_CMCS_NAME "ist30xxc.cms" +#define IST30XX_CMCS_MAGIC "CMCS2TAG" + +struct CMCS_SPEC_NODE { + u32 node_cnt; + u16 *buf_min; + u16 *buf_max; +}; + +struct CMCS_SPEC_TOTAL { + s16 screen_min; + s16 screen_max; + s16 gtx_min; + s16 gtx_max; + s16 key_min; + s16 key_max; +}; + +struct CMCS_ITEM_INFO { + char name[8]; + u32 addr; + u32 size; + char data_type[2]; + char spec_type[2]; +}; + +typedef struct _CMCS_ITEM { + u32 cnt; + struct CMCS_ITEM_INFO *item; +} CMCS_ITEM; + +struct CMCS_CMD_INFO { + u32 addr; + u32 value; +}; + +typedef struct _CMCS_CMD { + u32 cnt; + struct CMCS_CMD_INFO *cmd; +} CMCS_CMD; + +union CMCS_SPEC_ITEM { + struct CMCS_SPEC_NODE spec_node; + struct CMCS_SPEC_TOTAL spec_total; +}; + +struct CMCS_SPEC_SLOPE { + char name[8]; + s16 x_min; + s16 x_max; + s16 gtx_x_min; + s16 gtx_x_max; + s16 y_min; + s16 y_max; + s16 gtx_y_min; + s16 gtx_y_max; + s16 key_min; + s16 key_max; +}; + +struct CMCS_REG_INFO { + char name[8]; + u32 addr; + u32 size; +}; + +typedef struct _CMCS_PARAM { + u32 cmcs_size_addr; + u32 cmcs_size; + u32 enable_addr; + u32 checksum_addr; + u32 end_notify_addr; + u32 sensor1_addr; + u32 sensor2_addr; + u32 sensor3_addr; + u32 cm_sensor1_size; + u32 cm_sensor2_size; + u32 cm_sensor3_size; + u32 cs_sensor1_size; + u32 cs_sensor2_size; + u32 cs_sensor3_size; + u32 jit_sensor1_size; + u32 jit_sensor2_size; + u32 jit_sensor3_size; + u32 cmcs_chksum; + u32 cm_sensor_chksum; + u32 cs_sensor_chksum; + u32 jit_sensor_chksum; + u32 cs_tx_result_addr; + u32 cs_rx_result_addr; +} CMCS_PARAM; + +typedef struct _CMCS_BIN_INFO { + char magic1[8]; + CMCS_ITEM items; + CMCS_CMD cmds; + struct CMCS_SPEC_SLOPE spec_slope; + struct CMCS_SPEC_TOTAL spec_cr; + CMCS_PARAM param; + union CMCS_SPEC_ITEM *spec_item; + u8 *buf_cmcs; + u32 *buf_cm_sensor; + u32 *buf_cs_sensor; + u32 *buf_jit_sensor; + u32 version; + char magic2[8]; +} CMCS_BIN_INFO; + +typedef struct _CMCS_BUF { + s16 cm[IST30XX_MAX_NODE_NUM]; + s16 cm2[IST30XX_MAX_NODE_NUM]; + s16 cm_jit[IST30XX_MAX_NODE_NUM]; + s16 spec_min[IST30XX_MAX_NODE_NUM]; + s16 spec_max[IST30XX_MAX_NODE_NUM]; + s16 slope0[IST30XX_MAX_NODE_NUM]; + s16 slope1[IST30XX_MAX_NODE_NUM]; + s16 cs[IST30XX_MAX_NODE_NUM]; + u32 cs_tx_result; + u32 cs_rx_result; +} CMCS_BUF; + +int check_tsp_type(struct ist30xx_data *data, int tx, int rx); +int ist30xx_get_cmcs_info(const u8 *buf, const u32 size); +int ist30xx_cmcs_test(struct ist30xx_data *data, const u8 *buf, int size); +int ist30xx_init_cmcs_sysfs(struct ist30xx_data *data); +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs_bin.h b/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs_bin.h new file mode 100644 index 000000000000..f3848b1787af --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_cmcs_bin.h @@ -0,0 +1,756 @@ +#ifndef __IST30XXC_CMCS_BIN_H__ +#define __IST30XXC_CMCS_BIN_H__ + +/* ################################# */ +/* ### CmCs Version : 05020000 ### */ +/* ### Cheksum : 1D436CA3 ### */ +/* ################################# */ + +/* ist30xx cmcs binary: model( ) */ +static unsigned char ist30xx_cmcs[] = { + 0x43, 0x4D, 0x43, 0x53, 0x32, 0x54, 0x41, 0x47, 0x02, 0x00, 0x00, 0x00, 0x43, 0x4D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x4E, 0x00, 0x4E, 0x00, + 0x43, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, + 0x4E, 0x00, 0x54, 0x00, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x19, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xC8, 0x19, 0x00, 0x00, 0x18, 0x0E, 0x17, 0x0E, 0xCC, 0x19, 0x00, 0x00, 0x17, 0x02, 0x17, 0x06, + 0xD0, 0x19, 0x00, 0x00, 0x17, 0x0B, 0xFF, 0xFF, 0xD4, 0x19, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xD8, 0x19, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xDC, 0x19, 0x00, 0x00, 0xAC, 0x0D, 0xAC, 0x0D, + 0xE0, 0x19, 0x00, 0x00, 0x80, 0x0C, 0xD8, 0x0E, 0x43, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6A, 0xFF, 0x96, 0x00, 0x6A, 0xFF, 0x96, 0x00, 0x6A, 0xFF, 0x96, 0x00, 0x6A, 0xFF, 0x96, 0x00, + 0x6A, 0xFF, 0x96, 0x00, 0x01, 0x00, 0xFF, 0x0F, 0xEC, 0x04, 0x24, 0x09, 0x01, 0x00, 0xFF, 0x0F, + 0xC0, 0x19, 0x00, 0x00, 0xA4, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x08, 0x01, 0x00, 0x30, + 0x04, 0x01, 0x00, 0x30, 0x08, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x30, 0xC4, 0x52, 0x00, 0x30, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xA3, 0x6C, 0x43, 0x1D, 0xFC, 0x86, 0xBB, 0xB0, 0x08, 0xFD, 0x99, 0x72, + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x22, 0x00, 0x00, 0xFC, 0x22, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, + 0x6A, 0x03, 0x4D, 0x03, 0x50, 0x03, 0x54, 0x03, 0x3A, 0x03, 0x35, 0x03, 0x28, 0x03, 0x18, 0x03, + 0xFE, 0x02, 0xFD, 0x02, 0xE5, 0x02, 0x26, 0x02, 0x14, 0x02, 0x12, 0x02, 0x07, 0x02, 0xF5, 0x01, + 0xF4, 0x01, 0xE6, 0x01, 0xDD, 0x01, 0xD6, 0x01, 0xD1, 0x01, 0xBA, 0x01, 0xC2, 0x01, 0x2F, 0x03, + 0x19, 0x03, 0x1A, 0x03, 0x1B, 0x03, 0x00, 0x03, 0xFB, 0x02, 0xEC, 0x02, 0xDD, 0x02, 0xC3, 0x02, + 0xC1, 0x02, 0xA6, 0x02, 0x33, 0x02, 0x21, 0x02, 0x21, 0x02, 0x16, 0x02, 0x06, 0x02, 0x04, 0x02, + 0xF7, 0x01, 0xEE, 0x01, 0xE7, 0x01, 0xE2, 0x01, 0xCB, 0x01, 0xD5, 0x01, 0x1C, 0x03, 0x04, 0x03, + 0xFF, 0x02, 0xFF, 0x02, 0xE2, 0x02, 0xDA, 0x02, 0xCA, 0x02, 0xBA, 0x02, 0x9E, 0x02, 0x9C, 0x02, + 0x87, 0x02, 0x2C, 0x02, 0x1A, 0x02, 0x19, 0x02, 0x0C, 0x02, 0xFE, 0x01, 0xFB, 0x01, 0xEB, 0x01, + 0xE4, 0x01, 0xDB, 0x01, 0xD5, 0x01, 0xBE, 0x01, 0xC7, 0x01, 0x11, 0x03, 0xF7, 0x02, 0xF2, 0x02, + 0xF2, 0x02, 0xD7, 0x02, 0xCE, 0x02, 0xBD, 0x02, 0xAD, 0x02, 0x92, 0x02, 0x8F, 0x02, 0x72, 0x02, + 0x44, 0x02, 0x33, 0x02, 0x34, 0x02, 0x28, 0x02, 0x1B, 0x02, 0x19, 0x02, 0x0A, 0x02, 0x04, 0x02, + 0xFC, 0x01, 0xF7, 0x01, 0xE1, 0x01, 0xEB, 0x01, 0x02, 0x03, 0xE7, 0x02, 0xE1, 0x02, 0xDF, 0x02, + 0xC3, 0x02, 0xB9, 0x02, 0xA9, 0x02, 0x97, 0x02, 0x7C, 0x02, 0x79, 0x02, 0x5A, 0x02, 0x4F, 0x02, + 0x3F, 0x02, 0x41, 0x02, 0x34, 0x02, 0x26, 0x02, 0x27, 0x02, 0x17, 0x02, 0x10, 0x02, 0x0B, 0x02, + 0x04, 0x02, 0xEE, 0x01, 0xFA, 0x01, 0xF8, 0x02, 0xDA, 0x02, 0xD4, 0x02, 0xD1, 0x02, 0xB4, 0x02, + 0xA8, 0x02, 0x96, 0x02, 0x84, 0x02, 0x69, 0x02, 0x65, 0x02, 0x46, 0x02, 0x5E, 0x02, 0x4D, 0x02, + 0x4F, 0x02, 0x43, 0x02, 0x35, 0x02, 0x36, 0x02, 0x25, 0x02, 0x1F, 0x02, 0x1A, 0x02, 0x13, 0x02, + 0xFC, 0x01, 0x0A, 0x02, 0xE6, 0x02, 0xC9, 0x02, 0xC2, 0x02, 0xBC, 0x02, 0x9C, 0x02, 0x8F, 0x02, + 0x7B, 0x02, 0x67, 0x02, 0x4B, 0x02, 0x45, 0x02, 0x2C, 0x02, 0x5F, 0x02, 0x4D, 0x02, 0x4E, 0x02, + 0x41, 0x02, 0x32, 0x02, 0x32, 0x02, 0x22, 0x02, 0x19, 0x02, 0x12, 0x02, 0x0C, 0x02, 0xF5, 0x01, + 0x03, 0x02, 0xDC, 0x02, 0xC1, 0x02, 0xBA, 0x02, 0xB5, 0x02, 0x95, 0x02, 0x88, 0x02, 0x75, 0x02, + 0x61, 0x02, 0x45, 0x02, 0x3E, 0x02, 0x1F, 0x02, 0x82, 0x02, 0x72, 0x02, 0x75, 0x02, 0x69, 0x02, + 0x5B, 0x02, 0x5D, 0x02, 0x4D, 0x02, 0x46, 0x02, 0x3F, 0x02, 0x3A, 0x02, 0x24, 0x02, 0x35, 0x02, + 0xD1, 0x02, 0xB5, 0x02, 0xAD, 0x02, 0xA8, 0x02, 0x87, 0x02, 0x79, 0x02, 0x67, 0x02, 0x52, 0x02, + 0x34, 0x02, 0x2E, 0x02, 0x0E, 0x02, 0x95, 0x02, 0x85, 0x02, 0x8B, 0x02, 0x7D, 0x02, 0x6F, 0x02, + 0x73, 0x02, 0x61, 0x02, 0x5A, 0x02, 0x54, 0x02, 0x50, 0x02, 0x3A, 0x02, 0x4D, 0x02, 0xC8, 0x02, + 0xAC, 0x02, 0xA4, 0x02, 0x9D, 0x02, 0x7C, 0x02, 0x6D, 0x02, 0x59, 0x02, 0x45, 0x02, 0x28, 0x02, + 0x20, 0x02, 0x01, 0x02, 0xAD, 0x02, 0x9D, 0x02, 0xA2, 0x02, 0x94, 0x02, 0x87, 0x02, 0x8C, 0x02, + 0x7A, 0x02, 0x73, 0x02, 0x6D, 0x02, 0x69, 0x02, 0x54, 0x02, 0x68, 0x02, 0xC1, 0x02, 0xA4, 0x02, + 0x9B, 0x02, 0x93, 0x02, 0x71, 0x02, 0x62, 0x02, 0x4D, 0x02, 0x39, 0x02, 0x1D, 0x02, 0x13, 0x02, + 0xF3, 0x01, 0xC8, 0x02, 0xB6, 0x02, 0xBB, 0x02, 0xB0, 0x02, 0xA1, 0x02, 0xA6, 0x02, 0x95, 0x02, + 0x8E, 0x02, 0x89, 0x02, 0x86, 0x02, 0x6F, 0x02, 0x84, 0x02, 0xB5, 0x02, 0x98, 0x02, 0x8E, 0x02, + 0x83, 0x02, 0x62, 0x02, 0x51, 0x02, 0x3A, 0x02, 0x25, 0x02, 0x08, 0x02, 0xFF, 0x01, 0xE4, 0x01, + 0xD2, 0x02, 0xBE, 0x02, 0xC4, 0x02, 0xB7, 0x02, 0xA9, 0x02, 0xAD, 0x02, 0x9B, 0x02, 0x95, 0x02, + 0x8E, 0x02, 0x8B, 0x02, 0x73, 0x02, 0x89, 0x02, 0xB2, 0x02, 0x95, 0x02, 0x8C, 0x02, 0x82, 0x02, + 0x60, 0x02, 0x50, 0x02, 0x39, 0x02, 0x25, 0x02, 0x08, 0x02, 0xFF, 0x01, 0xDD, 0x01, 0x00, 0x03, + 0xEC, 0x02, 0xF3, 0x02, 0xE8, 0x02, 0xDB, 0x02, 0xE1, 0x02, 0xD0, 0x02, 0xCA, 0x02, 0xC5, 0x02, + 0xC2, 0x02, 0xAB, 0x02, 0xC4, 0x02, 0xAC, 0x02, 0x8F, 0x02, 0x84, 0x02, 0x78, 0x02, 0x54, 0x02, + 0x43, 0x02, 0x2B, 0x02, 0x16, 0x02, 0xF9, 0x01, 0xED, 0x01, 0xCB, 0x01, 0x5B, 0x03, 0x36, 0x03, + 0x3A, 0x03, 0x2E, 0x03, 0x20, 0x03, 0x26, 0x03, 0x11, 0x03, 0x0C, 0x03, 0x06, 0x03, 0x03, 0x03, + 0xEB, 0x02, 0x13, 0x03, 0x8C, 0x02, 0x9C, 0x02, 0x7F, 0x02, 0xB0, 0x05, 0x81, 0x05, 0x86, 0x05, + 0x8C, 0x05, 0x60, 0x05, 0x59, 0x05, 0x42, 0x05, 0x29, 0x05, 0xFD, 0x04, 0xFC, 0x04, 0xD4, 0x04, + 0x94, 0x03, 0x76, 0x03, 0x74, 0x03, 0x61, 0x03, 0x44, 0x03, 0x41, 0x03, 0x29, 0x03, 0x1B, 0x03, + 0x0F, 0x03, 0x06, 0x03, 0xE0, 0x02, 0xED, 0x02, 0x4F, 0x05, 0x2A, 0x05, 0x2B, 0x05, 0x2D, 0x05, + 0x00, 0x05, 0xF8, 0x04, 0xDF, 0x04, 0xC5, 0x04, 0x9A, 0x04, 0x98, 0x04, 0x6A, 0x04, 0xAA, 0x03, + 0x8D, 0x03, 0x8C, 0x03, 0x7A, 0x03, 0x5F, 0x03, 0x5D, 0x03, 0x46, 0x03, 0x38, 0x03, 0x2C, 0x03, + 0x23, 0x03, 0xFD, 0x02, 0x0D, 0x03, 0x2E, 0x05, 0x06, 0x05, 0xFE, 0x04, 0xFF, 0x04, 0xCE, 0x04, + 0xC0, 0x04, 0xA6, 0x04, 0x8B, 0x04, 0x5D, 0x04, 0x59, 0x04, 0x36, 0x04, 0x9F, 0x03, 0x80, 0x03, + 0x80, 0x03, 0x6A, 0x03, 0x52, 0x03, 0x4D, 0x03, 0x32, 0x03, 0x26, 0x03, 0x18, 0x03, 0x0D, 0x03, + 0xE7, 0x02, 0xF6, 0x02, 0x1C, 0x05, 0xF1, 0x04, 0xE8, 0x04, 0xE9, 0x04, 0xBB, 0x04, 0xAD, 0x04, + 0x91, 0x04, 0x76, 0x04, 0x49, 0x04, 0x43, 0x04, 0x14, 0x04, 0xC6, 0x03, 0xAB, 0x03, 0xAD, 0x03, + 0x98, 0x03, 0x82, 0x03, 0x80, 0x03, 0x65, 0x03, 0x5C, 0x03, 0x4F, 0x03, 0x46, 0x03, 0x21, 0x03, + 0x33, 0x03, 0x04, 0x05, 0xD7, 0x04, 0xCC, 0x04, 0xCA, 0x04, 0x9B, 0x04, 0x8A, 0x04, 0x6E, 0x04, + 0x50, 0x04, 0x24, 0x04, 0x1F, 0x04, 0xEB, 0x03, 0xDA, 0x03, 0xBE, 0x03, 0xC1, 0x03, 0xAC, 0x03, + 0x94, 0x03, 0x96, 0x03, 0x7B, 0x03, 0x71, 0x03, 0x67, 0x03, 0x5D, 0x03, 0x37, 0x03, 0x4B, 0x03, + 0xF2, 0x04, 0xC0, 0x04, 0xB7, 0x04, 0xB1, 0x04, 0x81, 0x04, 0x6E, 0x04, 0x4F, 0x04, 0x32, 0x04, + 0x04, 0x04, 0xFE, 0x03, 0xC9, 0x03, 0xF2, 0x03, 0xD5, 0x03, 0xD9, 0x03, 0xC4, 0x03, 0xAE, 0x03, + 0xAF, 0x03, 0x94, 0x03, 0x88, 0x03, 0x80, 0x03, 0x75, 0x03, 0x4F, 0x03, 0x66, 0x03, 0xD4, 0x04, + 0xA4, 0x04, 0x98, 0x04, 0x8F, 0x04, 0x59, 0x04, 0x44, 0x04, 0x22, 0x04, 0x02, 0x04, 0xD2, 0x03, + 0xC8, 0x03, 0x9E, 0x03, 0xF3, 0x03, 0xD6, 0x03, 0xD8, 0x03, 0xC2, 0x03, 0xA9, 0x03, 0xA9, 0x03, + 0x8E, 0x03, 0x80, 0x03, 0x74, 0x03, 0x69, 0x03, 0x44, 0x03, 0x5A, 0x03, 0xC5, 0x04, 0x96, 0x04, + 0x8B, 0x04, 0x83, 0x04, 0x4D, 0x04, 0x37, 0x04, 0x18, 0x04, 0xF7, 0x03, 0xC8, 0x03, 0xBD, 0x03, + 0x89, 0x03, 0x2F, 0x04, 0x13, 0x04, 0x18, 0x04, 0x04, 0x04, 0xEC, 0x03, 0xF0, 0x03, 0xD6, 0x03, + 0xC9, 0x03, 0xBF, 0x03, 0xB6, 0x03, 0x92, 0x03, 0xAE, 0x03, 0xB2, 0x04, 0x82, 0x04, 0x75, 0x04, + 0x6E, 0x04, 0x37, 0x04, 0x1F, 0x04, 0x00, 0x04, 0xDE, 0x03, 0xAC, 0x03, 0xA1, 0x03, 0x6D, 0x03, + 0x4E, 0x04, 0x33, 0x04, 0x3C, 0x04, 0x26, 0x04, 0x0F, 0x04, 0x15, 0x04, 0xF8, 0x03, 0xEB, 0x03, + 0xE2, 0x03, 0xDA, 0x03, 0xB7, 0x03, 0xD6, 0x03, 0xA3, 0x04, 0x74, 0x04, 0x66, 0x04, 0x5C, 0x04, + 0x24, 0x04, 0x0B, 0x04, 0xEA, 0x03, 0xC8, 0x03, 0x98, 0x03, 0x8A, 0x03, 0x57, 0x03, 0x76, 0x04, + 0x5A, 0x04, 0x63, 0x04, 0x4D, 0x04, 0x36, 0x04, 0x3E, 0x04, 0x20, 0x04, 0x15, 0x04, 0x0C, 0x04, + 0x05, 0x04, 0xE1, 0x03, 0x03, 0x04, 0x97, 0x04, 0x66, 0x04, 0x58, 0x04, 0x4A, 0x04, 0x12, 0x04, + 0xF9, 0x03, 0xD5, 0x03, 0xB5, 0x03, 0x85, 0x03, 0x76, 0x03, 0x40, 0x03, 0xA3, 0x04, 0x85, 0x04, + 0x8E, 0x04, 0x7A, 0x04, 0x62, 0x04, 0x6B, 0x04, 0x4D, 0x04, 0x43, 0x04, 0x39, 0x04, 0x34, 0x04, + 0x0F, 0x04, 0x31, 0x04, 0x83, 0x04, 0x52, 0x04, 0x42, 0x04, 0x30, 0x04, 0xF8, 0x03, 0xDC, 0x03, + 0xB6, 0x03, 0x94, 0x03, 0x63, 0x03, 0x53, 0x03, 0x27, 0x03, 0xB3, 0x04, 0x93, 0x04, 0x9C, 0x04, + 0x87, 0x04, 0x6F, 0x04, 0x76, 0x04, 0x58, 0x04, 0x4D, 0x04, 0x43, 0x04, 0x3D, 0x04, 0x15, 0x04, + 0x39, 0x04, 0x7F, 0x04, 0x4E, 0x04, 0x3F, 0x04, 0x2E, 0x04, 0xF6, 0x03, 0xDB, 0x03, 0xB5, 0x03, + 0x94, 0x03, 0x63, 0x03, 0x53, 0x03, 0x1B, 0x03, 0x00, 0x05, 0xDF, 0x04, 0xEB, 0x04, 0xD8, 0x04, + 0xC2, 0x04, 0xCD, 0x04, 0xAF, 0x04, 0xA6, 0x04, 0x9E, 0x04, 0x98, 0x04, 0x72, 0x04, 0x9B, 0x04, + 0x74, 0x04, 0x43, 0x04, 0x32, 0x04, 0x1E, 0x04, 0xE2, 0x03, 0xC5, 0x03, 0x9C, 0x03, 0x79, 0x03, + 0x49, 0x03, 0x35, 0x03, 0xFD, 0x02, 0x97, 0x05, 0x59, 0x05, 0x61, 0x05, 0x4D, 0x05, 0x35, 0x05, + 0x3F, 0x05, 0x1C, 0x05, 0x14, 0x05, 0x0B, 0x05, 0x05, 0x05, 0xDD, 0x04, 0x1F, 0x05, 0x3F, 0x04, + 0x5A, 0x04, 0x29, 0x04, 0x80, 0x0C, 0xD8, 0x0E, 0x80, 0x0C, 0xD8, 0x0E, 0x80, 0x0C, 0xD8, 0x0E, + 0x04, 0x00, 0x00, 0x00, 0x0C, 0x10, 0xBC, 0x19, 0x0C, 0x80, 0x9C, 0x0D, 0x0B, 0x17, 0x00, 0x00, + 0xF2, 0xFE, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x67, 0x08, 0x70, 0xB9, 0x67, 0x08, 0x70, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x08, 0x70, 0xD6, 0x72, 0x82, 0xFD, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x08, 0xD0, 0x00, 0x40, + 0x04, 0xC1, 0xC4, 0xE0, 0x82, 0x0A, 0xAB, 0x00, 0x00, 0x00, 0x04, 0x21, 0xB9, 0xCD, 0x00, 0x70, + 0x2B, 0x01, 0x00, 0x00, 0x34, 0xE1, 0xF2, 0xF6, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0x04, 0x70, 0xC6, 0x27, 0x82, 0x05, 0x08, 0x70, 0x0F, 0xC0, 0x2C, 0x70, 0xFF, 0xFF, 0x08, 0x60, + 0x00, 0x40, 0xB9, 0x76, 0x3C, 0x71, 0xE1, 0xF0, 0x77, 0x41, 0x14, 0x71, 0x34, 0x41, 0xC6, 0x47, + 0x82, 0x04, 0xB1, 0x32, 0x24, 0x24, 0xF2, 0xFB, 0xE1, 0xF0, 0x00, 0x00, 0xF7, 0x40, 0x04, 0x70, + 0xC6, 0x74, 0x82, 0x07, 0x2F, 0x67, 0x07, 0x00, 0x26, 0x62, 0xA1, 0x36, 0x24, 0x71, 0xF2, 0xF9, + 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x70, 0xC6, 0x74, 0x82, 0x06, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x36, + 0x24, 0x71, 0xF2, 0xFA, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x77, 0x41, 0x04, 0x70, + 0x14, 0x61, 0x34, 0x41, 0xC6, 0x46, 0x82, 0x09, 0x2F, 0x57, 0x03, 0x00, 0x30, 0xF5, 0x2F, 0x57, + 0x02, 0x00, 0xB1, 0xF5, 0x24, 0x74, 0xF2, 0xF6, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x04, 0x70, 0xC6, 0x74, 0x82, 0x09, 0x2F, 0x67, 0x03, 0x00, 0x10, 0x56, 0x2F, 0x67, 0x02, 0x00, + 0x91, 0x56, 0x24, 0x71, 0xF2, 0xF7, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x30, 0x38, 0x76, 0x28, 0x00, + 0xD4, 0x74, 0x92, 0xFD, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, + 0x06, 0xD3, 0xCB, 0x07, 0x00, 0x00, 0x38, 0x70, 0xA8, 0x0D, 0x57, 0xE1, 0x26, 0xE7, 0xB1, 0xDE, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x77, 0x31, 0x04, 0x70, 0x14, 0x61, 0x34, 0x31, + 0xC6, 0x36, 0x82, 0x05, 0x30, 0x52, 0x24, 0x24, 0x26, 0x75, 0xF2, 0xFA, 0x06, 0x27, 0xE1, 0xF0, + 0x3C, 0x10, 0x10, 0x00, 0x08, 0x60, 0xFF, 0xCF, 0xD1, 0xC1, 0x08, 0x50, 0x00, 0x30, 0x0C, 0x70, + 0x6C, 0x53, 0x0C, 0xE0, 0x94, 0xAC, 0x0C, 0x20, 0xA4, 0xAC, 0x0C, 0x40, 0x7C, 0x53, 0x26, 0xE6, + 0x26, 0x26, 0x26, 0x75, 0x0C, 0xD0, 0xB0, 0x0D, 0x14, 0x61, 0x26, 0x45, 0x30, 0xF7, 0x2F, 0x5D, + 0x07, 0x00, 0x2F, 0x3E, 0x05, 0x00, 0xB1, 0xF3, 0x38, 0x37, 0x10, 0x00, 0x26, 0x52, 0xB1, 0x35, + 0xB1, 0x67, 0xB9, 0x67, 0x10, 0x00, 0x24, 0x74, 0xC6, 0x74, 0x92, 0xF1, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x34, 0x18, 0x08, 0x60, 0x00, 0x30, 0x08, 0x50, 0xFF, 0xCF, 0xC1, 0xE1, + 0x0C, 0x70, 0x6C, 0x53, 0x0C, 0xF0, 0x94, 0xAC, 0x26, 0x76, 0x26, 0xF5, 0x0C, 0x30, 0xB0, 0x0D, + 0x34, 0x21, 0x2C, 0x50, 0xA4, 0xAC, 0x2C, 0x60, 0x7C, 0x53, 0x2F, 0x43, 0x07, 0x00, 0x2F, 0xEF, + 0x04, 0x00, 0x30, 0xEE, 0xC4, 0x21, 0xB1, 0xE7, 0xD2, 0x05, 0x26, 0x45, 0x30, 0x44, 0xB9, 0x47, + 0x10, 0x00, 0x24, 0x74, 0xC6, 0x76, 0x92, 0xF2, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x08, 0xC0, 0x00, 0x30, 0x06, 0xA2, + 0x04, 0xD0, 0x0C, 0xB0, 0xAC, 0x0D, 0x2C, 0xC0, 0x00, 0x49, 0x30, 0x7B, 0x06, 0x9B, 0x18, 0x77, + 0x09, 0x00, 0xC6, 0xD7, 0x32, 0x19, 0x04, 0xE0, 0x30, 0x79, 0x18, 0x37, 0x08, 0x00, 0xC6, 0xE3, + 0x32, 0x11, 0x06, 0x2D, 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2E, 0x06, 0x72, 0x57, 0x71, 0x26, 0x7C, + 0x30, 0x77, 0x2F, 0x62, 0x02, 0x00, 0x26, 0x6A, 0x5C, 0x70, 0xFF, 0x0F, 0xA1, 0x76, 0x24, 0xE1, + 0xF2, 0xEC, 0x24, 0xD1, 0xF2, 0xE3, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0x38, 0xC0, 0xAC, 0x0D, + 0xD1, 0x81, 0x04, 0x9C, 0x26, 0x9C, 0x04, 0xE0, 0x0C, 0xA0, 0xB0, 0x0D, 0x2F, 0xDE, 0x09, 0x00, + 0x18, 0x2D, 0x01, 0x00, 0x18, 0x3C, 0x08, 0x00, 0x2F, 0xBA, 0x0E, 0x00, 0xBB, 0x6B, 0x00, 0x00, + 0x10, 0x7D, 0x24, 0xE2, 0xC4, 0xEA, 0x26, 0x27, 0xA9, 0x2B, 0x20, 0x00, 0x92, 0xF0, 0x58, 0xC1, + 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, + 0x38, 0x57, 0x98, 0x60, 0x08, 0x60, 0x48, 0x30, 0x2C, 0x60, 0xE0, 0x00, 0xC6, 0x56, 0x92, 0x0E, + 0xCC, 0x20, 0x70, 0x00, 0xC2, 0x03, 0x0C, 0x20, 0x70, 0x00, 0x0C, 0x60, 0x00, 0xDE, 0xB9, 0x67, + 0x10, 0x60, 0xB9, 0x27, 0x40, 0x60, 0xB9, 0x07, 0x10, 0x60, 0xE1, 0xF0, 0x34, 0x14, 0x66, 0x32, + 0x04, 0x21, 0xB1, 0xF1, 0x4B, 0x08, 0x00, 0x00, 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0x04, 0x20, + 0xB9, 0x67, 0x70, 0x10, 0x06, 0x32, 0x4B, 0x08, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0x08, 0x70, 0x00, 0x30, 0xD9, 0xC1, 0x10, 0x00, 0x2C, 0x70, 0x00, 0x01, + 0xB9, 0x70, 0xA8, 0x0D, 0xD1, 0x81, 0x0C, 0x70, 0xC0, 0x19, 0x0C, 0x60, 0x9C, 0x01, 0xB9, 0x70, + 0xAC, 0x0D, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x74, 0x10, 0xCB, 0x07, 0x00, 0x00, 0x38, 0x70, + 0xAC, 0x0D, 0x38, 0xE0, 0xA8, 0x0D, 0x20, 0x37, 0x04, 0x20, 0x4B, 0x09, 0x00, 0x00, 0xB9, 0x2E, + 0x08, 0x00, 0x38, 0x6E, 0x08, 0x00, 0xB9, 0x60, 0x00, 0x23, 0x08, 0x70, 0x02, 0x05, 0xB9, 0x7E, + 0x0C, 0x00, 0x08, 0xB0, 0x70, 0x14, 0x2B, 0x12, 0x00, 0x00, 0x2C, 0xB0, 0x70, 0x99, 0x04, 0xE0, + 0x0C, 0xD0, 0xA8, 0x0D, 0x08, 0x90, 0x01, 0x00, 0x08, 0xA0, 0x7D, 0x0E, 0x30, 0x7D, 0x30, 0x77, + 0xD6, 0x79, 0x82, 0x05, 0x06, 0x2B, 0x04, 0x30, 0xEB, 0x15, 0x00, 0x00, 0x30, 0x7D, 0x08, 0x60, + 0x00, 0x01, 0x30, 0x77, 0xD6, 0x76, 0x82, 0x1D, 0x08, 0x70, 0x00, 0x40, 0x38, 0xC7, 0x40, 0x60, + 0x0C, 0x20, 0x1D, 0x00, 0x5C, 0xC0, 0x7F, 0x00, 0x26, 0x2C, 0x6B, 0x14, 0x00, 0x00, 0x38, 0x70, + 0xAC, 0x0D, 0xA8, 0x77, 0x18, 0x00, 0x82, 0x04, 0xAB, 0x63, 0x00, 0x00, 0x06, 0xE2, 0x0C, 0x20, + 0x70, 0x21, 0x26, 0x2A, 0x06, 0x3E, 0xEB, 0x15, 0x00, 0x00, 0x06, 0x2C, 0x6B, 0x14, 0x00, 0x00, + 0x30, 0x6D, 0x30, 0x76, 0xD4, 0x71, 0x92, 0x04, 0x30, 0x76, 0xD4, 0x72, 0x82, 0x1B, 0x08, 0x70, + 0x00, 0x40, 0x38, 0xC7, 0x40, 0x60, 0x0C, 0x20, 0x1D, 0x00, 0x5C, 0xC0, 0x7F, 0x00, 0x26, 0x2C, + 0x6B, 0x14, 0x00, 0x00, 0x30, 0x7D, 0x30, 0x27, 0x54, 0x23, 0x0B, 0x38, 0x00, 0x00, 0x06, 0xE2, + 0x0C, 0x20, 0x70, 0xC7, 0x26, 0x2A, 0x06, 0x3E, 0xEB, 0x15, 0x00, 0x00, 0x06, 0x2C, 0x6B, 0x14, + 0x00, 0x00, 0x30, 0x7D, 0x30, 0x77, 0xDC, 0x70, 0x00, 0x01, 0x82, 0xB1, 0xEB, 0x61, 0x00, 0x00, + 0x06, 0xE2, 0x06, 0x3E, 0x08, 0x20, 0x7D, 0x0E, 0x2C, 0x20, 0x00, 0xC5, 0xEB, 0x15, 0x00, 0x00, + 0xF2, 0xA6, 0x00, 0x00, 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0xB1, 0xB1, 0x08, 0x50, + 0x00, 0x40, 0x38, 0x65, 0x0C, 0x70, 0xC4, 0x21, 0xB9, 0x63, 0x18, 0x01, 0x06, 0xC2, 0x06, 0xE3, + 0x92, 0x0D, 0x08, 0x70, 0xFF, 0xE0, 0x2C, 0x70, 0xFF, 0xE0, 0x56, 0x76, 0x08, 0x60, 0x00, 0x01, + 0x2C, 0x60, 0x00, 0x01, 0x66, 0x76, 0xB9, 0x75, 0x0C, 0x70, 0x08, 0xD0, 0x00, 0x40, 0x0C, 0x30, + 0xA8, 0x71, 0x06, 0x2E, 0x26, 0x3D, 0x0C, 0x40, 0x20, 0x00, 0x0B, 0x07, 0x00, 0x00, 0x0C, 0x20, + 0x20, 0x00, 0x08, 0xB0, 0x00, 0x30, 0x0C, 0x30, 0x00, 0x40, 0x26, 0x2E, 0x26, 0x3B, 0x0C, 0x40, + 0xF0, 0x00, 0xCB, 0x05, 0x00, 0x00, 0x38, 0x7D, 0x78, 0x71, 0xC4, 0xC1, 0xB9, 0x7E, 0x10, 0x01, + 0x92, 0x0A, 0x38, 0x7B, 0x8C, 0x53, 0xB9, 0x7E, 0x14, 0x01, 0x0C, 0x70, 0xFF, 0x03, 0xB9, 0x7B, + 0x8C, 0x53, 0xF2, 0x0F, 0xC4, 0xC2, 0x92, 0x0D, 0x38, 0x7D, 0x2C, 0x72, 0xB9, 0x7E, 0x1C, 0x01, + 0x38, 0x7D, 0x30, 0x72, 0xB9, 0x7E, 0x20, 0x01, 0xB9, 0x0D, 0x2C, 0x72, 0xB9, 0x0D, 0x30, 0x72, + 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x14, 0x00, + 0xD9, 0xC1, 0x04, 0x00, 0x06, 0xE3, 0x06, 0xC2, 0x04, 0x21, 0xB1, 0xB1, 0xAB, 0x0C, 0x00, 0x00, + 0x38, 0x7E, 0x18, 0x01, 0x08, 0xD0, 0x00, 0x40, 0x0C, 0x20, 0xA8, 0x71, 0xB9, 0x7D, 0x0C, 0x70, + 0x26, 0x2D, 0x06, 0x3E, 0x0C, 0x40, 0x20, 0x00, 0xCB, 0x05, 0x00, 0x00, 0x08, 0xB0, 0x00, 0x30, + 0x0C, 0x20, 0x00, 0x40, 0x0C, 0x30, 0x20, 0x00, 0x26, 0x2B, 0x26, 0x3E, 0x0C, 0x40, 0xF0, 0x00, + 0xCB, 0x05, 0x00, 0x00, 0x38, 0x7E, 0x10, 0x01, 0xC4, 0xC1, 0xB9, 0x7D, 0x78, 0x71, 0x92, 0x06, + 0x38, 0x7E, 0x14, 0x01, 0xB9, 0x7B, 0x8C, 0x53, 0xF2, 0x0B, 0xC4, 0xC2, 0x92, 0x09, 0x38, 0x7E, + 0x1C, 0x01, 0xB9, 0x7D, 0x2C, 0x72, 0x38, 0x7E, 0x20, 0x01, 0xB9, 0x7D, 0x30, 0x72, 0x58, 0xC1, + 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x28, 0x00, + 0xD9, 0x81, 0x08, 0x00, 0x06, 0xB2, 0x08, 0x20, 0x00, 0x40, 0x2C, 0x20, 0xA8, 0x71, 0x04, 0x30, + 0x0C, 0x40, 0x20, 0x00, 0xD9, 0xC1, 0x18, 0x00, 0x0C, 0xA0, 0xAC, 0x0D, 0x2B, 0x05, 0x00, 0x00, + 0x14, 0xE1, 0x24, 0xE1, 0xCC, 0xE0, 0x1F, 0x00, 0x8A, 0x90, 0x00, 0x00, 0x04, 0x21, 0x38, 0x7B, + 0x10, 0x01, 0x06, 0x62, 0x53, 0x6E, 0xD6, 0x76, 0x82, 0xF5, 0x08, 0x70, 0x00, 0x80, 0x66, 0x76, + 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x78, 0x71, 0x2F, 0x7E, 0x0B, 0x00, 0x10, 0xD7, 0xAB, 0x0C, + 0x00, 0x00, 0x04, 0x78, 0x26, 0x7D, 0x57, 0x71, 0x26, 0x7B, 0x30, 0x77, 0x08, 0x60, 0x00, 0x30, + 0xB9, 0x76, 0x00, 0x40, 0x30, 0x7A, 0x0C, 0x90, 0x08, 0x40, 0x18, 0x77, 0x08, 0x00, 0x26, 0x96, + 0x26, 0x7D, 0x24, 0x78, 0x57, 0x71, 0x26, 0x7B, 0x30, 0x77, 0x04, 0xC2, 0xB9, 0x76, 0x04, 0x40, + 0x06, 0x8A, 0x2C, 0x60, 0x00, 0x40, 0x30, 0x78, 0x18, 0x57, 0x09, 0x00, 0xC6, 0xC5, 0x32, 0x10, + 0x18, 0x37, 0x08, 0x00, 0xB1, 0x61, 0x06, 0x2C, 0xBB, 0x6B, 0x00, 0x00, 0x30, 0x61, 0x26, 0x2D, + 0x57, 0x21, 0x26, 0x26, 0x30, 0x72, 0x24, 0xC1, 0xB1, 0x79, 0x24, 0x94, 0xF2, 0xED, 0x04, 0x25, + 0xAB, 0x01, 0x00, 0x00, 0x30, 0x8A, 0x08, 0xC0, 0x00, 0x30, 0x2C, 0xC0, 0x00, 0x49, 0x04, 0x90, + 0x0C, 0x60, 0x00, 0x23, 0x18, 0x78, 0x09, 0x00, 0xC6, 0x97, 0x32, 0x12, 0x18, 0x38, 0x08, 0x00, + 0xB1, 0x61, 0x06, 0x29, 0xBB, 0x6B, 0x00, 0x00, 0x30, 0x7C, 0x30, 0x61, 0x26, 0x2D, 0x26, 0x22, + 0x26, 0x26, 0x5C, 0x70, 0xFF, 0x0F, 0xA1, 0x72, 0x24, 0x91, 0x24, 0xC4, 0xF2, 0xEC, 0x0B, 0x0A, + 0x00, 0x00, 0x04, 0x25, 0xAB, 0x01, 0x00, 0x00, 0x30, 0x7A, 0x08, 0xC0, 0x00, 0x30, 0x2C, 0xC0, + 0x00, 0x49, 0x04, 0x90, 0x0C, 0x50, 0x00, 0x23, 0x18, 0x67, 0x09, 0x00, 0xC6, 0x96, 0x32, 0x8A, + 0x18, 0x37, 0x08, 0x00, 0x30, 0x8C, 0xB9, 0x51, 0x04, 0x00, 0x06, 0x29, 0xB1, 0x71, 0xBB, 0x6B, + 0x00, 0x00, 0x38, 0x51, 0x04, 0x00, 0x30, 0x71, 0x26, 0x2D, 0x26, 0x22, 0x26, 0x25, 0x20, 0x62, + 0x5C, 0x80, 0xFF, 0x0F, 0xC6, 0x86, 0xC2, 0x03, 0xA1, 0x02, 0xF2, 0x04, 0x3F, 0x88, 0x06, 0x00, + 0xA1, 0x82, 0x24, 0x91, 0x24, 0xC4, 0xF2, 0xE1, 0x58, 0xC1, 0x18, 0x00, 0x58, 0x81, 0x08, 0x00, + 0x2C, 0x10, 0x28, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x20, 0x00, 0xD1, 0x81, 0x06, 0xB2, + 0x04, 0x25, 0xD9, 0xC1, 0x10, 0x00, 0xAB, 0x01, 0x00, 0x00, 0x38, 0xA0, 0xAC, 0x0D, 0x08, 0xC0, + 0x00, 0x30, 0x04, 0xD0, 0x2C, 0xC0, 0x00, 0x49, 0x0C, 0x90, 0x00, 0x23, 0x18, 0x7A, 0x09, 0x00, + 0xC6, 0xD7, 0xB2, 0x20, 0x04, 0xE0, 0x18, 0x3A, 0x08, 0x00, 0xC6, 0xE3, 0xB2, 0x19, 0x06, 0x2D, + 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2E, 0x06, 0x72, 0x57, 0x71, 0x2F, 0x62, 0x02, 0x00, 0x26, 0x7C, + 0x2F, 0x56, 0x0B, 0x00, 0x30, 0x77, 0x20, 0x55, 0x5C, 0x70, 0xFF, 0x0F, 0xC6, 0x75, 0x26, 0x69, + 0xB2, 0x03, 0xA1, 0x06, 0xF2, 0x03, 0x36, 0x75, 0xA1, 0x76, 0x24, 0xE1, 0xF2, 0xE5, 0x24, 0xD1, + 0xF2, 0xDE, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x34, 0x01, 0xD9, 0xC1, 0x24, 0x01, 0x06, 0xE2, 0x0B, 0x0A, 0x00, 0x00, 0x04, 0x25, + 0xAB, 0x01, 0x00, 0x00, 0xC4, 0xE2, 0x92, 0x06, 0x06, 0x2D, 0x0C, 0x20, 0x00, 0x1A, 0x0B, 0x0F, + 0x00, 0x00, 0x06, 0x2E, 0xAB, 0x0C, 0x00, 0x00, 0x06, 0x2E, 0x06, 0x31, 0x2B, 0x20, 0x00, 0x00, + 0xC4, 0xE2, 0x92, 0x07, 0x06, 0x2D, 0x0C, 0x20, 0x00, 0x1A, 0x4B, 0x34, 0x00, 0x00, 0xF2, 0x07, + 0x06, 0x21, 0x06, 0x3D, 0x0C, 0x30, 0x00, 0x1A, 0x6B, 0x29, 0x00, 0x00, 0x06, 0x2E, 0x06, 0x31, + 0x6B, 0x25, 0x00, 0x00, 0x58, 0xC1, 0x24, 0x01, 0x04, 0x20, 0x2C, 0x10, 0x34, 0x01, 0xE1, 0xF0, + 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0x38, 0xE0, 0xAC, 0x0D, 0xB1, 0xB1, 0x06, 0xC3, + 0x18, 0x3E, 0x08, 0x00, 0x06, 0xB4, 0x06, 0xD2, 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2C, 0xB1, 0x2B, + 0x18, 0x7E, 0x0A, 0x00, 0xC6, 0xC7, 0xB2, 0x11, 0x18, 0x7E, 0x0B, 0x00, 0xC6, 0xD7, 0xA2, 0x0A, + 0x18, 0x7E, 0x16, 0x00, 0xC6, 0xD7, 0x82, 0x06, 0x18, 0x7E, 0x17, 0x00, 0x04, 0x20, 0xC6, 0xD7, + 0x92, 0x1E, 0x28, 0x2E, 0x1C, 0x00, 0xF2, 0x1B, 0x18, 0x6E, 0x04, 0x00, 0x2F, 0x76, 0x06, 0x00, + 0x0C, 0x30, 0xB0, 0x0D, 0x26, 0x37, 0x34, 0x61, 0x04, 0x70, 0x14, 0x51, 0x2F, 0x47, 0x06, 0x00, + 0xC6, 0x45, 0x82, 0x0C, 0x2F, 0x47, 0x07, 0x00, 0x26, 0x43, 0x28, 0x44, 0x1E, 0x00, 0x34, 0x71, + 0xC6, 0x24, 0x92, 0xF5, 0x28, 0x2E, 0x1E, 0x00, 0xF2, 0x02, 0x04, 0x20, 0x58, 0xC1, 0x04, 0x00, + 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xC2, + 0x06, 0xE4, 0x04, 0x21, 0x06, 0xD3, 0x0B, 0x03, 0x00, 0x00, 0x08, 0x70, 0x00, 0x30, 0x2C, 0x70, + 0x00, 0x40, 0x57, 0xC1, 0x2F, 0x27, 0x0C, 0x00, 0x30, 0x72, 0xC4, 0xE0, 0x0C, 0x60, 0xFF, 0x03, + 0x56, 0x67, 0x77, 0x75, 0x5C, 0x70, 0xFF, 0x03, 0x82, 0x09, 0xC4, 0xD0, 0x82, 0x04, 0x26, 0x6E, + 0x26, 0x7E, 0xF2, 0x11, 0x36, 0x7E, 0x36, 0x6E, 0xF2, 0x0E, 0xC4, 0xD0, 0x82, 0x07, 0xC6, 0x76, + 0x02, 0x03, 0x24, 0x61, 0xF2, 0x0D, 0x24, 0x71, 0xF2, 0x06, 0xC6, 0x76, 0x02, 0x03, 0x34, 0x71, + 0xF2, 0x02, 0x34, 0x61, 0xC4, 0x60, 0x02, 0x06, 0xCC, 0x60, 0xFF, 0x03, 0x12, 0x06, 0x04, 0xE0, + 0xF2, 0x07, 0x14, 0xE1, 0x04, 0x61, 0xF2, 0x04, 0x14, 0xE1, 0x0C, 0x60, 0xFF, 0x03, 0xC4, 0x70, + 0x02, 0x08, 0xCC, 0x70, 0xFF, 0x03, 0x02, 0x07, 0x14, 0xE1, 0x0C, 0x70, 0xFF, 0x03, 0xF2, 0x03, + 0x14, 0xE1, 0x04, 0x71, 0x57, 0x75, 0x66, 0x76, 0xB1, 0x72, 0x04, 0x20, 0x0B, 0x03, 0x00, 0x00, + 0x06, 0x2E, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x28, 0x00, + 0xD9, 0xC1, 0x18, 0x00, 0x38, 0xE0, 0xAC, 0x0D, 0xD9, 0x81, 0x08, 0x00, 0x06, 0xD2, 0x18, 0x7E, + 0x05, 0x00, 0x18, 0x2E, 0x0B, 0x00, 0x18, 0x3E, 0x0A, 0x00, 0x26, 0x27, 0xBB, 0x6B, 0x00, 0x00, + 0x18, 0xAE, 0x04, 0x00, 0x18, 0x3E, 0x08, 0x00, 0x26, 0x2A, 0xB9, 0x21, 0x04, 0x00, 0x18, 0x2E, + 0x09, 0x00, 0x23, 0xDD, 0xBB, 0x6B, 0x00, 0x00, 0x2F, 0x42, 0x02, 0x00, 0x06, 0x3D, 0x0C, 0x20, + 0x00, 0x1A, 0x6B, 0x04, 0x00, 0x00, 0x18, 0x3E, 0x08, 0x00, 0x18, 0x2E, 0x09, 0x00, 0xBB, 0x6B, + 0x00, 0x00, 0x06, 0x42, 0x04, 0x30, 0x06, 0x2D, 0x0C, 0x20, 0x80, 0x1E, 0x2B, 0x05, 0x00, 0x00, + 0x18, 0x3E, 0x08, 0x00, 0x18, 0x2E, 0x09, 0x00, 0xBB, 0x6B, 0x00, 0x00, 0x06, 0x42, 0x04, 0x31, + 0x06, 0x29, 0x0C, 0x20, 0xC0, 0x20, 0x08, 0xB0, 0x00, 0x30, 0x2B, 0x05, 0x00, 0x00, 0x0C, 0xC0, + 0x82, 0x00, 0x2C, 0xB0, 0x00, 0x49, 0x04, 0x21, 0x04, 0x80, 0xAB, 0x01, 0x00, 0x00, 0x06, 0xD8, + 0x18, 0x7E, 0x09, 0x00, 0xC6, 0x87, 0x32, 0x46, 0x04, 0xA0, 0x18, 0x6E, 0x08, 0x00, 0xC6, 0xA6, + 0x32, 0x3F, 0x06, 0x41, 0x06, 0x28, 0x06, 0x3A, 0x0B, 0x3B, 0x00, 0x00, 0x86, 0x42, 0x82, 0x36, + 0x30, 0x21, 0x06, 0x62, 0x57, 0x61, 0x26, 0x6B, 0x30, 0x66, 0x0C, 0x50, 0x80, 0x1E, 0x5C, 0x60, + 0xFF, 0x0F, 0x26, 0x52, 0x3F, 0x44, 0x06, 0x00, 0x90, 0x65, 0x82, 0x04, 0xCC, 0x40, 0x46, 0x00, + 0x02, 0x24, 0x06, 0x69, 0x0C, 0x60, 0xC0, 0x20, 0x26, 0x62, 0x10, 0x36, 0xC4, 0x31, 0x0C, 0xF0, + 0x00, 0x1A, 0x2F, 0x32, 0x02, 0x00, 0x92, 0x05, 0xC4, 0x40, 0x22, 0x0E, 0x91, 0x06, 0xF2, 0x0C, + 0xC4, 0x40, 0x12, 0x0A, 0x04, 0x41, 0x91, 0x46, 0x2F, 0x43, 0x0F, 0x00, 0xA0, 0x44, 0x92, 0x04, + 0x10, 0x45, 0x24, 0x41, 0x91, 0x45, 0x26, 0x3F, 0x20, 0x43, 0xF7, 0x40, 0xA1, 0x43, 0x10, 0x36, + 0x4B, 0x3F, 0x00, 0x00, 0xC4, 0x20, 0x32, 0x02, 0x24, 0xD1, 0x24, 0xA1, 0xF2, 0xBF, 0x24, 0x81, + 0xF2, 0xB8, 0x38, 0x71, 0x04, 0x00, 0xC6, 0xD7, 0xB2, 0x03, 0xB4, 0xC1, 0x92, 0xAD, 0x58, 0xC1, + 0x18, 0x00, 0x58, 0x81, 0x08, 0x00, 0x2C, 0x10, 0x28, 0x00, 0xE1, 0xF0, 0x34, 0x14, 0x04, 0x21, + 0xB1, 0xF1, 0x0B, 0x03, 0x00, 0x00, 0x08, 0x20, 0x00, 0x30, 0x08, 0x30, 0x06, 0x00, 0x2C, 0x30, + 0x80, 0x01, 0x0C, 0x40, 0x00, 0x09, 0x2C, 0x20, 0x00, 0x40, 0xCB, 0x03, 0x00, 0x00, 0x04, 0x20, + 0x0B, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00, 0x02, 0x6B, 0x44, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x24, 0x00, 0xD9, 0x81, 0x04, 0x00, 0x38, 0xB0, 0xAC, 0x0D, + 0xD9, 0xC1, 0x14, 0x00, 0x04, 0xE0, 0x06, 0xA2, 0x06, 0x93, 0x06, 0xCE, 0x04, 0x51, 0x18, 0x7B, + 0x09, 0x00, 0xC6, 0xC7, 0x32, 0x22, 0x04, 0xD0, 0x18, 0x3B, 0x08, 0x00, 0xC6, 0xD3, 0x32, 0x1B, + 0x06, 0x2C, 0xB1, 0x51, 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2D, 0x38, 0x40, 0xAC, 0x0D, 0x30, 0x51, + 0x2F, 0x72, 0x02, 0x00, 0x2F, 0x67, 0x0A, 0x00, 0x20, 0x66, 0x28, 0x34, 0x22, 0x00, 0xC6, 0x36, + 0xA2, 0x05, 0x28, 0x44, 0x20, 0x00, 0xC6, 0x46, 0xC2, 0x04, 0x26, 0x79, 0xA1, 0x57, 0x24, 0xE1, + 0x24, 0xD1, 0xF2, 0xE3, 0x24, 0xC1, 0xF2, 0xDC, 0x06, 0x2E, 0x58, 0xC1, 0x14, 0x00, 0x58, 0x81, + 0x04, 0x00, 0x2C, 0x10, 0x24, 0x00, 0xE1, 0xF0, 0x38, 0x70, 0xAC, 0x0D, 0x04, 0x60, 0x18, 0x37, + 0x09, 0x00, 0x18, 0x77, 0x08, 0x00, 0x14, 0x41, 0x26, 0x37, 0x06, 0x76, 0xC6, 0x73, 0x32, 0x0D, + 0x2F, 0x57, 0x07, 0x00, 0x26, 0x52, 0x20, 0x55, 0xC6, 0x56, 0xD2, 0x03, 0x06, 0x56, 0xF2, 0x02, + 0x06, 0x47, 0x24, 0x71, 0x06, 0x65, 0xF2, 0xF3, 0x06, 0x24, 0xE1, 0xF0, 0x3C, 0x10, 0x14, 0x00, + 0xD9, 0xC1, 0x04, 0x00, 0x38, 0xD0, 0xAC, 0x0D, 0xB1, 0xB1, 0x06, 0xC2, 0x18, 0x7D, 0x09, 0x00, + 0xC6, 0x37, 0x32, 0x0F, 0x18, 0xED, 0x08, 0x00, 0x06, 0x23, 0x06, 0x3E, 0xBB, 0x6B, 0x00, 0x00, + 0x26, 0x22, 0x26, 0x2C, 0x04, 0x30, 0x2F, 0x4E, 0x0E, 0x00, 0x6B, 0x04, 0x00, 0x00, 0xF2, 0x13, + 0x3F, 0xB7, 0x03, 0x00, 0x04, 0xE0, 0x18, 0x7D, 0x09, 0x00, 0xC6, 0xE7, 0x32, 0x0C, 0x18, 0x3D, + 0x08, 0x00, 0x06, 0x2E, 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2B, 0x26, 0x22, 0x26, 0x2C, 0xA1, 0x02, + 0x24, 0xE1, 0xF2, 0xF2, 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0x38, 0xE0, 0xAC, 0x0D, 0xD1, 0x81, 0x06, 0xA3, + 0x18, 0x4E, 0x09, 0x00, 0x18, 0x7E, 0x08, 0x00, 0x06, 0x92, 0x26, 0x47, 0x06, 0x23, 0x26, 0x44, + 0x04, 0x30, 0x6B, 0x04, 0x00, 0x00, 0x06, 0xBA, 0x04, 0xC0, 0x18, 0x7E, 0x09, 0x00, 0xC6, 0xC7, + 0x32, 0x1F, 0x04, 0xD0, 0x18, 0x3E, 0x08, 0x00, 0xC6, 0xD3, 0x32, 0x17, 0x06, 0x2C, 0xBB, 0x6B, + 0x00, 0x00, 0x26, 0x2D, 0x26, 0x22, 0x26, 0x29, 0x20, 0x72, 0xC4, 0x71, 0x92, 0x0C, 0x20, 0x7B, + 0x24, 0x71, 0xA1, 0x7B, 0x18, 0x7E, 0x09, 0x00, 0x26, 0x7D, 0x26, 0x77, 0x26, 0x7A, 0x20, 0x67, + 0x24, 0x61, 0xA1, 0x67, 0x24, 0xD1, 0xF2, 0xE7, 0x24, 0xC1, 0x24, 0xB2, 0xF2, 0xDF, 0x58, 0xC1, + 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x20, 0x00, + 0xD9, 0xC1, 0x10, 0x00, 0x06, 0xC2, 0x04, 0x30, 0x06, 0x2E, 0x0C, 0x20, 0x00, 0x1A, 0x0C, 0x40, + 0x80, 0x04, 0x38, 0xD0, 0xAC, 0x0D, 0xD1, 0x81, 0x6B, 0x04, 0x00, 0x00, 0x06, 0x2B, 0x0C, 0x20, + 0x80, 0x1E, 0x04, 0x30, 0x0C, 0x40, 0x80, 0x04, 0x6B, 0x04, 0x00, 0x00, 0x06, 0x2C, 0x06, 0x3E, + 0x0C, 0x30, 0x00, 0x1A, 0x2B, 0x50, 0x00, 0x00, 0x04, 0x70, 0xC6, 0x27, 0x06, 0xCE, 0x02, 0x31, + 0x06, 0x9E, 0x0C, 0x90, 0x00, 0x1A, 0x18, 0x5D, 0x08, 0x00, 0x18, 0x6D, 0x09, 0x00, 0x04, 0xA1, + 0x26, 0x65, 0xC6, 0x76, 0x26, 0xA7, 0x32, 0x25, 0x06, 0x2C, 0x0C, 0x20, 0x00, 0x1A, 0x06, 0x3B, + 0x0C, 0x30, 0x80, 0x1E, 0x8B, 0x58, 0x00, 0x00, 0x06, 0x2B, 0x0C, 0x20, 0x80, 0x1E, 0xCB, 0x53, + 0x00, 0x00, 0x86, 0xE2, 0x22, 0x16, 0x06, 0x29, 0x06, 0x3E, 0x6B, 0x55, 0x00, 0x00, 0x18, 0x7D, + 0x09, 0x00, 0xC6, 0xE7, 0x32, 0x04, 0x38, 0x50, 0xA0, 0x0D, 0xF2, 0x04, 0x38, 0x50, 0x9C, 0x0D, + 0x36, 0xE7, 0x30, 0x75, 0x04, 0x61, 0x53, 0x6E, 0x66, 0x76, 0xB1, 0x75, 0x06, 0x7A, 0xF2, 0xD4, + 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, + 0x0B, 0x0A, 0x00, 0x00, 0x6B, 0x4E, 0x00, 0x00, 0x0C, 0x20, 0x00, 0x01, 0xAB, 0x0C, 0x00, 0x00, + 0x04, 0x2A, 0xAB, 0x01, 0x00, 0x00, 0x06, 0x2E, 0x0C, 0x20, 0x00, 0x23, 0x0B, 0x0F, 0x00, 0x00, + 0x06, 0x2E, 0x0C, 0x20, 0x00, 0x23, 0x6B, 0x5C, 0x00, 0x00, 0x40, 0xE1, 0x04, 0x20, 0x24, 0x18, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x28, 0x00, 0xD9, 0x81, 0x08, 0x00, 0x06, 0x2B, 0x0C, 0x20, + 0x00, 0x1A, 0x0C, 0x30, 0xFF, 0x0F, 0x0C, 0x40, 0x80, 0x04, 0xD9, 0xC1, 0x18, 0x00, 0x6B, 0x04, + 0x00, 0x00, 0x06, 0x2A, 0x0C, 0x20, 0x80, 0x1E, 0x04, 0x30, 0x0C, 0x40, 0x80, 0x04, 0x6B, 0x04, + 0x00, 0x00, 0x04, 0x2A, 0x08, 0x80, 0x00, 0x30, 0xAB, 0x01, 0x00, 0x00, 0x04, 0x90, 0x2C, 0x80, + 0x00, 0x49, 0x38, 0xE0, 0xAC, 0x0D, 0x28, 0x7E, 0x18, 0x00, 0xC6, 0x97, 0x22, 0x07, 0x04, 0xC0, + 0x0C, 0xA0, 0x80, 0x1E, 0x0C, 0xB0, 0x00, 0x1A, 0xF2, 0x37, 0x04, 0xD0, 0x06, 0x5A, 0x0C, 0x50, + 0x80, 0x1E, 0x06, 0x6B, 0x0C, 0x60, 0x00, 0x1A, 0x18, 0x7E, 0x09, 0x00, 0xC6, 0xD7, 0x32, 0x26, + 0x04, 0xC0, 0x18, 0x3E, 0x08, 0x00, 0xC6, 0xC3, 0x32, 0x1F, 0x06, 0x2D, 0xB1, 0x51, 0xB9, 0x61, + 0x04, 0x00, 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2C, 0x06, 0x72, 0x30, 0x51, 0x38, 0x61, 0x04, 0x00, + 0x57, 0x71, 0x26, 0x78, 0x26, 0x22, 0x30, 0x77, 0x2F, 0x45, 0x02, 0x00, 0x20, 0x34, 0x5C, 0x70, + 0xFF, 0x0F, 0xC6, 0x37, 0xB2, 0x02, 0xA1, 0x74, 0x26, 0x26, 0x20, 0x42, 0xC6, 0x47, 0xC2, 0x02, + 0xA1, 0x72, 0x24, 0xC1, 0xF2, 0xDF, 0x24, 0xD1, 0xF2, 0xD8, 0x04, 0x21, 0xAB, 0x01, 0x00, 0x00, + 0x24, 0x91, 0xF2, 0xC0, 0x24, 0xC1, 0x18, 0x7E, 0x09, 0x00, 0xC6, 0xC7, 0x32, 0x15, 0x04, 0xD0, + 0x18, 0x3E, 0x08, 0x00, 0xC6, 0xD3, 0x32, 0xF7, 0x06, 0x2C, 0xBB, 0x6B, 0x00, 0x00, 0x26, 0x2D, + 0x26, 0x22, 0x2F, 0x7A, 0x02, 0x00, 0x26, 0x2B, 0x20, 0x57, 0x20, 0x62, 0x24, 0xD1, 0x3F, 0x66, + 0x05, 0x00, 0xA1, 0x67, 0xF2, 0xEE, 0x58, 0xC1, 0x18, 0x00, 0x58, 0x81, 0x08, 0x00, 0x04, 0x20, + 0x2C, 0x10, 0x28, 0x00, 0xE1, 0xF0, 0xC4, 0x30, 0x04, 0x40, 0x04, 0x50, 0x0C, 0x60, 0x20, 0x00, + 0x52, 0x03, 0xA6, 0x42, 0x25, 0x50, 0xB4, 0x61, 0x02, 0x06, 0xA6, 0x44, 0x25, 0x55, 0xA6, 0x33, + 0x42, 0xF9, 0xF2, 0xFA, 0x06, 0x24, 0x06, 0x35, 0xE1, 0xF0, 0x00, 0x00, 0xFC, 0x22, 0x00, 0x00, + 0xF8, 0x22, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0E, 0x18, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x10, 0x08, 0x12, 0x00, 0x54, 0xFF, 0x0F, 0x00, + 0x10, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x32, 0x00, 0x16, 0x32, 0x10, 0x10, + 0x01, 0x00, 0x08, 0x00, 0x32, 0x00, 0x64, 0x10, 0x61, 0xC7, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x64, 0xC0, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x0F, 0x40, 0x0F, 0x01, 0x01, 0x80, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x80, 0x00, 0x80, + 0x0A, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x0E, 0x18, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x80, 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x64, 0x3C, 0x10, 0x00, + 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0xFF, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, + 0xC8, 0x00, 0x00, 0x02, 0x05, 0x00, 0x08, 0x1F, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x0D, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x10, 0xB0, 0x00, 0xD5, 0xC6, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x01, 0x03, 0x00, 0x1B, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFB, 0x07, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x7F, 0xFC, 0x8F, 0xBF, + 0x01, 0x20, 0x00, 0x00, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x13, 0x12, + 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x16, 0x15, 0x14, 0x13, + 0x12, 0x11, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x17, 0x00, 0x00, 0xFF, 0x00, 0x20, 0x86, + 0x00, 0x00, 0x00, 0x4C, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3A, 0x26, 0x14, 0x00, 0x38, 0x26, 0x10, 0x01, 0x45, 0x26, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x2D, 0x28, 0x08, 0x03, 0x2E, 0x28, 0x0B, 0x02, 0x28, 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x07, 0x13, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x4E, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x02, 0x50, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0xD0, 0xF1, 0x7F, 0x21, 0xF0, 0xF1, 0x7F, 0x42, 0xF0, 0xF1, 0x7F, + 0x63, 0xF0, 0xF1, 0x7F, 0x84, 0xF0, 0xF1, 0x7F, 0xA5, 0xF0, 0xF1, 0x7F, 0xC6, 0xF0, 0xF1, 0x7F, + 0xE7, 0xF0, 0xF1, 0x7F, 0x08, 0xF1, 0xF1, 0x7F, 0x29, 0xF1, 0xF1, 0x7F, 0x4A, 0xF1, 0xF1, 0x7F, + 0x6B, 0xF1, 0xF1, 0x7F, 0x8C, 0xF1, 0xF1, 0x7F, 0xAD, 0xE1, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7B, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x7F, 0xFC, 0x8F, 0x1F, + 0x7F, 0xFC, 0x8F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x00, 0x30, 0x30, 0x30, 0x30, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x04, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x05, 0x58, 0x00, 0x00, + 0x0E, 0x18, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x10, 0x08, 0x12, 0x00, 0x54, 0xFF, 0x0F, 0x00, + 0x10, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x32, 0x00, 0x16, 0x32, 0x10, 0x10, + 0x01, 0x00, 0x08, 0x00, 0x32, 0x00, 0x64, 0x10, 0x61, 0xC7, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x64, 0xC0, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x0F, 0x40, 0x0F, 0x01, 0x01, 0x80, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x80, 0x00, 0x80, + 0x0A, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x0E, 0x18, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x80, 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x64, 0x3C, 0x10, 0x00, + 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0xFF, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, + 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2B, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0x0D, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0x28, 0x00, 0x02, 0xD5, 0xC6, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2A, 0x3A, 0x02, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFB, 0xF7, 0x43, 0x00, 0x05, 0xA3, 0xA8, 0x00, 0x00, 0xFF, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x7F, 0xFC, 0x8F, 0xBF, + 0x01, 0x20, 0x00, 0x00, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x13, 0x12, + 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x16, 0x15, 0x14, 0x13, + 0x12, 0x11, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x17, 0x00, 0x00, 0xFF, 0x00, 0x20, 0x86, + 0x00, 0x00, 0x00, 0x4C, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x26, 0x12, 0x01, 0x38, 0x26, 0x10, 0x01, 0x45, 0x26, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x2D, 0x28, 0x08, 0x03, 0x2E, 0x28, 0x09, 0x03, 0x28, 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x07, 0x13, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x4E, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0xFE, 0x08, 0x30, + 0x45, 0x16, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0xFE, 0x08, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x43, 0x0E, 0x59, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0x02, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0xFE, 0x08, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x43, 0x0E, 0x59, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0x02, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x43, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0x02, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x43, 0x0E, 0x59, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, + 0x3F, 0x02, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x43, 0x12, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x3E, 0xFE, 0x08, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x45, 0x1A, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFA, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, + 0x3F, 0x02, 0x09, 0x30, 0x43, 0x12, 0x09, 0x30, 0x43, 0x0E, 0x09, 0x30, 0x3F, 0x02, 0x09, 0x30, + 0x45, 0x1A, 0x09, 0x30, 0x42, 0x0E, 0x09, 0x30, 0x3E, 0xFE, 0x08, 0x30, 0x43, 0x12, 0x09, 0x30, + 0x00, 0x02, 0x58, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xF1, 0x7F, 0x21, 0xF0, 0xF1, 0x7F, 0x42, 0xF0, 0xF1, 0x7F, + 0x63, 0xF0, 0xF1, 0x7F, 0x84, 0xF0, 0xF1, 0x7F, 0xA5, 0xF0, 0xF1, 0x7F, 0xC6, 0xF0, 0xF1, 0x7F, + 0xE7, 0xF0, 0xF1, 0x7F, 0x08, 0xF1, 0xF1, 0x7F, 0x29, 0xF1, 0xF1, 0x7F, 0x4A, 0xF1, 0xF1, 0x7F, + 0x6B, 0xF1, 0xF1, 0x7F, 0x8C, 0xF1, 0xF1, 0x7F, 0xAD, 0xE1, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7B, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, + 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0xC0, 0xF1, 0x7F, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x26, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x8F, 0x1F, + 0x7F, 0xFC, 0x8F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x82, 0x20, 0x08, + 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, + 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, + 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, 0x08, 0x82, 0x20, 0x08, + 0x08, 0x82, 0x20, 0x08, 0x41, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x00, 0x30, 0x30, 0x30, 0x30, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x04, 0x41, 0x10, 0x00, 0x00, 0x00, 0x02, 0x05, 0x43, 0x4D, 0x43, 0x53, 0x32, 0x54, 0x41, 0x47 +}; + +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_fw_v02_t1.h b/drivers/input/touchscreen/ist3038c/ist30xxc_fw_v02_t1.h new file mode 100644 index 000000000000..776712a2ff03 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_fw_v02_t1.h @@ -0,0 +1,4054 @@ + +#ifndef __IST30XXC_FW_H__ +#define __IST30XXC_FW_H__ + + + + + + + +static unsigned char ist30xxc_fw[] = { + 0x80, 0x00, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x74, 0x0C, 0x00, 0x80, 0xFC, 0x00, 0x00, 0x80, + 0x04, 0x01, 0x00, 0x80, 0xF8, 0x0C, 0x00, 0x80, 0xA8, 0x0C, 0x00, 0x80, 0xD0, 0x0C, 0x00, 0x80, + 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x40, 0x0D, 0x00, 0x80, + 0x64, 0x0D, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, 0x0C, 0x01, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x10, 0x00, 0x27, 0x08, 0x80, 0x00, 0x80, 0x2C, 0x80, 0xB8, 0x6E, 0xAB, 0x0B, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0x04, 0x61, 0x99, 0x67, 0x10, 0x00, 0x91, 0x67, 0x08, 0x70, 0x0F, 0x00, + 0x11, 0x17, 0x0C, 0x70, 0xB0, 0x15, 0x0C, 0x60, 0xB0, 0x15, 0xC6, 0x76, 0xB2, 0x04, 0xB1, 0x07, + 0x24, 0x74, 0xF2, 0xFC, 0x08, 0x30, 0x00, 0x80, 0x04, 0x70, 0x0C, 0x40, 0xB0, 0x15, 0x0C, 0x50, + 0xB0, 0x15, 0x2C, 0x30, 0x30, 0x73, 0x2F, 0x64, 0x07, 0x00, 0xC6, 0x65, 0xB2, 0x07, 0x2F, 0x23, + 0x07, 0x00, 0x30, 0x22, 0x24, 0x74, 0xB1, 0x26, 0xF2, 0xF7, 0x0C, 0x70, 0xB0, 0x15, 0x0C, 0x60, + 0xF0, 0x16, 0xC6, 0x76, 0xB2, 0x04, 0xB1, 0x07, 0x24, 0x74, 0xF2, 0xFC, 0xEB, 0x0F, 0x00, 0x00, + 0xAB, 0x74, 0x03, 0x00, 0xB9, 0x20, 0x88, 0x27, 0x04, 0x22, 0xF2, 0x0D, 0xB9, 0x20, 0x88, 0x27, + 0x04, 0x23, 0xF2, 0x09, 0xB9, 0x20, 0x88, 0x27, 0x04, 0x24, 0xF2, 0x05, 0xB9, 0x20, 0x88, 0x27, + 0x04, 0x21, 0xF2, 0x01, 0xB9, 0x10, 0x84, 0x27, 0xB9, 0x30, 0x8C, 0x27, 0x08, 0x30, 0x00, 0x50, + 0xB9, 0x03, 0x00, 0x10, 0xD9, 0x40, 0x90, 0x27, 0xD9, 0x80, 0xA0, 0x27, 0xD9, 0xC0, 0xB0, 0x27, + 0x01, 0x40, 0x01, 0x51, 0xC9, 0x40, 0xC0, 0x27, 0x99, 0x20, 0x80, 0x27, 0x08, 0x20, 0x01, 0x00, + 0xB1, 0x23, 0x98, 0x40, 0x80, 0x27, 0x92, 0xFE, 0x09, 0x00, 0x01, 0x00, 0x04, 0x23, 0xB9, 0x23, + 0x00, 0x10, 0xF2, 0x01, 0x48, 0x40, 0xC0, 0x27, 0x11, 0x15, 0x11, 0x04, 0x58, 0xC0, 0xB0, 0x27, + 0x58, 0x80, 0xA0, 0x27, 0x58, 0x40, 0x90, 0x27, 0x48, 0x20, 0x88, 0x27, 0x38, 0x10, 0x84, 0x27, + 0x61, 0x00, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x2B, 0xC2, 0x00, 0x00, + 0x0B, 0xC9, 0x00, 0x00, 0x2B, 0xCA, 0x00, 0x00, 0xCB, 0xA0, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0xCF, 0x00, 0x00, 0xAB, 0xDD, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xCB, 0xE0, 0x00, 0x00, + 0x4B, 0xD2, 0x00, 0x00, 0x6B, 0xD1, 0x00, 0x00, 0x2B, 0xD0, 0x00, 0x00, 0x8B, 0xD3, 0x00, 0x00, + 0x4B, 0xD4, 0x00, 0x00, 0xAB, 0xD6, 0x00, 0x00, 0x4B, 0xE8, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xEB, 0xE3, 0x00, 0x00, 0xAB, 0xC4, 0x00, 0x00, + 0x0B, 0x36, 0x03, 0x00, 0xAB, 0xDD, 0x00, 0x00, 0x2B, 0x8B, 0x00, 0x00, 0x4B, 0x79, 0x00, 0x00, + 0x04, 0x20, 0x4B, 0xF3, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0xAB, 0xBC, 0x00, 0x00, 0xAB, 0xC1, 0x00, 0x00, 0xEB, 0x12, 0x00, 0x00, 0xCB, 0x0B, + 0x00, 0x00, 0xAB, 0x0C, 0x00, 0x00, 0x4B, 0x0D, 0x00, 0x00, 0x4B, 0xB7, 0x00, 0x00, 0xCB, 0x1B, + 0x01, 0x00, 0xAB, 0x0E, 0x00, 0x00, 0xCB, 0x1A, 0x01, 0x00, 0x98, 0x70, 0xDE, 0x16, 0x92, 0xFC, + 0x18, 0x70, 0xD5, 0x16, 0xC4, 0x71, 0x82, 0xF8, 0x6B, 0x19, 0x01, 0x00, 0xCB, 0x2F, 0x00, 0x00, + 0xCB, 0x05, 0x01, 0x00, 0x6B, 0x30, 0x00, 0x00, 0x8B, 0x17, 0x01, 0x00, 0xAB, 0x18, 0x01, 0x00, + 0xEB, 0x19, 0x01, 0x00, 0x6B, 0xF9, 0x00, 0x00, 0xF2, 0xE7, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, + 0x04, 0x61, 0xB9, 0x67, 0x00, 0x80, 0xB9, 0x07, 0x0C, 0x80, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x80, + 0xC6, 0x27, 0x34, 0x14, 0xB1, 0xF1, 0x82, 0x03, 0xC6, 0x37, 0x92, 0x04, 0x8B, 0x1A, 0x00, 0x00, + 0xF2, 0x09, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x04, 0x80, 0xB9, 0x37, 0x08, 0x80, 0x38, 0x27, + 0x10, 0x80, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x80, + 0xB9, 0x37, 0x1C, 0x80, 0x06, 0x67, 0x38, 0x76, 0x28, 0x80, 0xD4, 0x71, 0x82, 0xFD, 0x38, 0x26, + 0x20, 0x80, 0xE1, 0xF0, 0x04, 0x50, 0xC6, 0x25, 0x32, 0x03, 0x16, 0x22, 0x04, 0x51, 0x04, 0x60, + 0xC6, 0x36, 0x32, 0x03, 0x16, 0x33, 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x80, + 0xB9, 0x37, 0x1C, 0x80, 0x06, 0x47, 0x38, 0x74, 0x28, 0x80, 0xD4, 0x71, 0x82, 0xFD, 0xC6, 0x56, + 0x38, 0x24, 0x20, 0x80, 0x82, 0x02, 0x16, 0x22, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, + 0xB9, 0x27, 0x18, 0x80, 0xB9, 0x37, 0x1C, 0x80, 0x06, 0x67, 0x38, 0x76, 0x28, 0x80, 0xD4, 0x71, + 0x82, 0xFD, 0x38, 0x26, 0x24, 0x80, 0xE1, 0xF0, 0x04, 0x50, 0xC6, 0x25, 0x34, 0x18, 0xC1, 0xE1, + 0x06, 0xE2, 0x32, 0x03, 0x16, 0xE2, 0x04, 0x51, 0x04, 0x60, 0xC6, 0x36, 0x32, 0x03, 0x16, 0x33, + 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0xB9, 0xE7, 0x18, 0x80, 0xB9, 0x37, 0x1C, 0x80, 0x06, 0x47, + 0x38, 0x74, 0x28, 0x80, 0xD4, 0x71, 0x82, 0xFD, 0xC6, 0x56, 0x38, 0x24, 0x20, 0x80, 0x82, 0x02, + 0x16, 0x22, 0x6B, 0x13, 0x00, 0x00, 0x3F, 0x22, 0x0E, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0xC4, 0x30, 0x04, 0x40, 0x04, 0x50, 0x0C, 0x60, 0x20, 0x00, 0x52, 0x03, 0xA6, 0x42, 0x25, 0x50, + 0xB4, 0x61, 0x02, 0x06, 0xA6, 0x44, 0x25, 0x55, 0xA6, 0x33, 0x42, 0xF9, 0xF2, 0xFA, 0x06, 0x24, + 0x06, 0x35, 0xE1, 0xF0, 0x04, 0x40, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9E, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9D, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x9C, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9B, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x9A, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x99, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x98, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x97, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x96, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x95, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x94, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x93, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x92, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x91, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x90, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x8F, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8E, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8D, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x8C, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8B, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x8A, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x89, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x88, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x87, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x86, 0x00, 0x00, + 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x85, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, + 0xBA, 0x84, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x83, 0x00, 0x00, 0xA6, 0x22, + 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x82, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x81, + 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, 0xC6, 0x43, 0xBA, 0x80, 0x00, 0x00, 0xA6, 0x22, 0x25, 0x44, + 0xC6, 0x43, 0xBA, 0x7F, 0x00, 0x00, 0xE1, 0xF0, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x62, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x63, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x64, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x65, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x66, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x67, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x68, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x69, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6A, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6B, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6C, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6D, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6E, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x6F, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x70, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x71, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x72, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x73, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x74, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x75, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x76, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x77, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x78, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x79, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7A, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7B, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7C, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7D, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7E, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xFA, 0x7F, 0xFF, 0xFF, 0x36, 0x43, 0x24, 0x21, 0xFA, 0x80, 0xFF, 0xFF, + 0x36, 0x43, 0x24, 0x21, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x04, 0x70, + 0x6C, 0x70, 0x40, 0x00, 0x66, 0x72, 0xB9, 0x76, 0x04, 0x70, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x60, 0x71, 0x08, 0x50, 0x40, 0x00, 0x66, 0x75, 0xB9, 0x76, 0x60, 0x71, 0xE1, 0xF0, + 0x08, 0x50, 0x00, 0x40, 0x38, 0x75, 0x60, 0x71, 0x08, 0x60, 0xBF, 0xFF, 0x2C, 0x60, 0xFF, 0xFF, + 0x56, 0x76, 0xB9, 0x75, 0x60, 0x71, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0x00, 0x60, 0xB1, 0xF1, + 0x2B, 0x57, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xD5, 0x16, + 0x34, 0x14, 0xB1, 0xF1, 0x92, 0x05, 0x0C, 0x20, 0x00, 0x60, 0x0B, 0x58, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0x00, 0x60, 0xB1, 0xF1, 0x2B, 0x57, 0x00, 0x00, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x60, 0x71, 0x08, 0x50, 0x40, 0x00, 0x66, 0x75, 0xB9, 0x76, + 0x60, 0x71, 0x0C, 0x20, 0x64, 0x00, 0x2B, 0xC0, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x04, 0x70, 0x1C, 0x50, 0x1D, 0x00, 0x56, 0x75, 0x66, 0x72, + 0xB9, 0x76, 0x04, 0x70, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x04, 0x35, + 0x06, 0xE2, 0x04, 0x21, 0xCB, 0x6F, 0x00, 0x00, 0x04, 0x24, 0x04, 0x30, 0xCB, 0x55, 0x00, 0x00, + 0x08, 0xD0, 0x00, 0x40, 0x38, 0x7D, 0x08, 0x70, 0xD6, 0x7E, 0x92, 0x0A, 0x04, 0x21, 0x4B, 0x6E, + 0x00, 0x00, 0xCB, 0x51, 0x00, 0x00, 0x04, 0x21, 0x0B, 0x6F, 0x00, 0x00, 0xF2, 0xF4, 0x04, 0x24, + 0x04, 0x31, 0xCB, 0x55, 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x18, 0x70, 0xD2, 0x16, 0x34, 0x14, 0x93, 0x07, 0xB1, 0xF1, 0x92, 0x02, 0x51, 0x00, 0x08, 0x60, + 0x00, 0x40, 0x38, 0x76, 0x04, 0x70, 0x1C, 0x50, 0x41, 0x70, 0x56, 0x75, 0xB9, 0x76, 0x04, 0x70, + 0x04, 0x24, 0x04, 0x31, 0xCB, 0x55, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0x38, 0x67, 0x08, 0x70, 0xB9, 0x67, 0x08, 0x70, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE2, 0x0B, 0x37, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0xE7, + 0x00, 0x70, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, + 0x06, 0xD3, 0x0B, 0x37, 0x00, 0x00, 0x04, 0x24, 0x04, 0x30, 0xCB, 0x55, 0x00, 0x00, 0x06, 0x2D, + 0xCB, 0x2D, 0x00, 0x00, 0x99, 0x00, 0xD2, 0x16, 0x08, 0x70, 0x00, 0x40, 0xB9, 0xE7, 0x00, 0x70, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x80, 0x18, 0x67, 0x6B, 0xDC, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x7C, 0x70, 0x38, 0x67, 0x70, 0x70, 0x64, 0x62, 0xB9, 0x67, + 0x70, 0x70, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x70, 0x70, 0x64, 0x71, 0xB9, 0x76, + 0x70, 0x70, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x70, 0x70, 0x14, 0x52, 0x56, 0x75, + 0xB9, 0x76, 0x70, 0x70, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0xE0, 0x70, + 0x5C, 0x20, 0xFF, 0x7F, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0xE4, 0x70, + 0x5C, 0x20, 0xFF, 0x01, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x27, 0x5C, 0x70, + 0x5C, 0x20, 0x7F, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x08, 0x60, 0x00, 0x40, 0x82, 0x08, + 0x08, 0x70, 0x0F, 0xC0, 0x2C, 0x70, 0xFF, 0xFF, 0xB9, 0x76, 0x3C, 0x71, 0xF2, 0x03, 0xB9, 0x06, + 0x3C, 0x71, 0xE1, 0xF0, 0x08, 0x20, 0x00, 0x40, 0x08, 0x30, 0x00, 0x80, 0x34, 0x18, 0x2C, 0x20, + 0x08, 0x70, 0x2C, 0x30, 0x08, 0xE2, 0x0C, 0x40, 0xBE, 0x00, 0xC1, 0xE1, 0x0C, 0xF0, 0x5C, 0x01, + 0xF1, 0xF0, 0x0C, 0x20, 0x00, 0x40, 0x08, 0xE0, 0x00, 0x30, 0x08, 0x30, 0x00, 0x80, 0x26, 0x2E, + 0x2C, 0x30, 0x00, 0xE5, 0x0C, 0x40, 0x40, 0x02, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x0C, 0x20, + 0xC4, 0x52, 0x08, 0x30, 0x00, 0x80, 0x26, 0x2E, 0x2C, 0x30, 0x00, 0xEE, 0x0C, 0x40, 0x54, 0x00, + 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x08, 0x70, 0x00, 0x80, 0x28, 0x77, 0x28, 0xDC, 0x0C, 0x20, + 0x00, 0x49, 0x06, 0x37, 0x57, 0x38, 0x26, 0x2E, 0x66, 0x37, 0x0C, 0x40, 0x69, 0x01, 0x0C, 0xF0, + 0xD8, 0x01, 0xF1, 0xF0, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x7F, 0x56, 0x72, + 0xC4, 0x71, 0x34, 0x14, 0xB1, 0xF1, 0x92, 0x04, 0x38, 0x70, 0xA8, 0x16, 0xF2, 0x03, 0x38, 0x70, + 0xAC, 0x16, 0xC4, 0x28, 0x38, 0x67, 0x50, 0x00, 0x38, 0x57, 0x74, 0x00, 0x38, 0x37, 0x68, 0x00, + 0x38, 0xF7, 0x8C, 0x00, 0x38, 0x47, 0x94, 0x00, 0x82, 0x49, 0xC4, 0x28, 0xD2, 0x07, 0xC4, 0x22, + 0x82, 0x16, 0xC4, 0x23, 0x82, 0x38, 0xC4, 0x21, 0xF2, 0x09, 0xCC, 0x20, 0x82, 0x00, 0x82, 0x13, + 0xCC, 0x20, 0x82, 0x00, 0xD2, 0x05, 0xCC, 0x20, 0x81, 0x00, 0x92, 0x53, 0xF2, 0x3F, 0xCC, 0x20, + 0x83, 0x00, 0x82, 0x29, 0xCC, 0x20, 0x88, 0x00, 0x82, 0x31, 0xF2, 0x4B, 0x98, 0x20, 0xE4, 0x16, + 0x82, 0x35, 0xF2, 0x1C, 0x98, 0x20, 0xE4, 0x16, 0x82, 0x31, 0x08, 0x50, 0x00, 0x80, 0x2C, 0x50, + 0x0C, 0xDC, 0x28, 0x60, 0x0E, 0x0B, 0x18, 0x25, 0x77, 0x00, 0xC6, 0x26, 0xD2, 0x06, 0x38, 0x67, + 0x60, 0x00, 0x38, 0x57, 0x84, 0x00, 0xF2, 0x22, 0x18, 0x55, 0x78, 0x00, 0xC6, 0x56, 0xD2, 0x06, + 0x38, 0x67, 0x64, 0x00, 0x38, 0x57, 0x88, 0x00, 0xF2, 0x19, 0x38, 0x67, 0x5C, 0x00, 0x38, 0x57, + 0x80, 0x00, 0xF2, 0x14, 0x38, 0x67, 0x54, 0x00, 0x38, 0x57, 0x78, 0x00, 0x38, 0x37, 0x6C, 0x00, + 0x38, 0xF7, 0x90, 0x00, 0x38, 0x47, 0x98, 0x00, 0xF2, 0x09, 0x38, 0x67, 0x58, 0x00, 0x38, 0x57, + 0x7C, 0x00, 0x38, 0x37, 0x70, 0x00, 0x38, 0x47, 0x9C, 0x00, 0x98, 0x70, 0xD6, 0x16, 0x82, 0x05, + 0x08, 0x60, 0x22, 0x00, 0x2C, 0x60, 0x20, 0x20, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x34, 0x70, + 0xB9, 0x57, 0x64, 0x70, 0xB9, 0x37, 0x54, 0x70, 0xB9, 0xF7, 0x6C, 0x70, 0xB9, 0x47, 0x1C, 0x71, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x54, 0x2F, 0xC4, 0x21, 0x92, 0x04, 0x38, 0x70, + 0xA8, 0x16, 0xF2, 0x03, 0x38, 0x70, 0xAC, 0x16, 0x38, 0x57, 0x4C, 0x00, 0x98, 0x70, 0xE4, 0x16, + 0x08, 0x70, 0x00, 0x80, 0x82, 0x06, 0x2C, 0x70, 0xC0, 0xDC, 0x38, 0x67, 0x04, 0x00, 0xF2, 0x03, + 0x38, 0x67, 0xC0, 0xDC, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x57, 0x30, 0x70, 0xB9, 0x67, 0x58, 0x70, + 0xE1, 0xF0, 0x00, 0x00, 0x54, 0x2F, 0xC4, 0x21, 0x92, 0x04, 0x38, 0x60, 0xA8, 0x16, 0xF2, 0x03, + 0x38, 0x60, 0xAC, 0x16, 0x38, 0x56, 0x08, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x57, 0xB4, 0x70, + 0x38, 0x56, 0x0C, 0x00, 0x08, 0x40, 0xDF, 0xFF, 0xB9, 0x57, 0xB8, 0x70, 0x38, 0x56, 0x10, 0x00, + 0x2C, 0x40, 0xFF, 0xFF, 0x56, 0x54, 0xB9, 0x57, 0xC0, 0x70, 0x38, 0x56, 0x14, 0x00, 0xB9, 0x57, + 0xC4, 0x70, 0x98, 0x50, 0xD7, 0x16, 0x82, 0x0C, 0x08, 0x60, 0x01, 0x00, 0x2C, 0x60, 0x81, 0x11, + 0xB9, 0x67, 0xAC, 0x70, 0x08, 0x60, 0x10, 0x00, 0x2C, 0x60, 0x10, 0x00, 0xF2, 0x06, 0x30, 0x56, + 0xB9, 0x57, 0xAC, 0x70, 0x38, 0x66, 0x04, 0x00, 0xB9, 0x67, 0xB0, 0x70, 0xE1, 0xF0, 0x00, 0x00, + 0x54, 0x2F, 0xC4, 0x21, 0x92, 0x04, 0x38, 0x70, 0xA8, 0x16, 0xF2, 0x03, 0x38, 0x70, 0xAC, 0x16, + 0x38, 0x57, 0x2C, 0x00, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x56, 0x8C, 0x70, 0x38, 0x57, 0x30, 0x00, + 0xB9, 0x56, 0x90, 0x70, 0x38, 0x57, 0x34, 0x00, 0xB9, 0x56, 0x94, 0x70, 0x38, 0x57, 0x38, 0x00, + 0xB9, 0x56, 0x98, 0x70, 0x38, 0x57, 0x3C, 0x00, 0xB9, 0x56, 0x9C, 0x70, 0x38, 0x57, 0x40, 0x00, + 0xB9, 0x56, 0xA0, 0x70, 0x38, 0x57, 0x44, 0x00, 0xB9, 0x56, 0xA4, 0x70, 0x38, 0x77, 0x48, 0x00, + 0xB9, 0x76, 0xA8, 0x70, 0xE1, 0xF0, 0x00, 0x00, 0x51, 0x00, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, + 0xC4, 0x20, 0x38, 0x67, 0x34, 0x10, 0x82, 0x03, 0x64, 0x63, 0xF2, 0x03, 0x14, 0x54, 0x56, 0x65, + 0xB9, 0x67, 0x34, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0xAD, 0xDE, 0x2C, 0x70, 0x8C, 0x03, + 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x00, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0xAD, 0xDE, + 0x08, 0x60, 0x00, 0x40, 0x2C, 0x70, 0x8C, 0x03, 0xB9, 0x76, 0x00, 0x10, 0xB9, 0x26, 0x6C, 0x10, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, + 0xB9, 0x67, 0x00, 0x10, 0x0C, 0x50, 0x10, 0x00, 0xB9, 0x57, 0x20, 0x10, 0x08, 0x50, 0x38, 0x03, + 0xB9, 0x67, 0x00, 0x10, 0x2C, 0x50, 0x80, 0x88, 0xB9, 0x57, 0x24, 0x10, 0xB9, 0x67, 0x00, 0x10, + 0xB9, 0x07, 0x28, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, + 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, 0xC4, 0x30, 0x38, 0x67, 0x50, 0x10, 0x82, 0x05, + 0x66, 0x62, 0xB9, 0x67, 0x50, 0x10, 0xF2, 0x05, 0x15, 0x22, 0x56, 0x26, 0xB9, 0x27, 0x50, 0x10, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, + 0xB9, 0x67, 0x00, 0x10, 0x38, 0x67, 0x54, 0x10, 0x66, 0x62, 0xB9, 0x67, 0x54, 0x10, 0xE1, 0xF0, + 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, + 0x38, 0x67, 0x54, 0x10, 0x15, 0x22, 0x56, 0x26, 0xB9, 0x27, 0x54, 0x10, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, + 0x38, 0x57, 0x58, 0x10, 0xCC, 0x20, 0xFF, 0x00, 0x1C, 0x40, 0x00, 0x01, 0x56, 0x54, 0x92, 0x0A, + 0xB9, 0x57, 0x58, 0x10, 0xB9, 0x67, 0x00, 0x10, 0x38, 0x67, 0x4C, 0x10, 0x14, 0x52, 0x56, 0x65, + 0xF2, 0x09, 0x66, 0x52, 0xB9, 0x57, 0x58, 0x10, 0xB9, 0x67, 0x00, 0x10, 0x38, 0x67, 0x4C, 0x10, + 0x64, 0x61, 0xB9, 0x67, 0x4C, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0xAD, 0xDE, 0x08, 0x70, 0x00, 0x40, + 0x2C, 0x60, 0x8C, 0x03, 0xB9, 0x67, 0x00, 0x10, 0xC4, 0x30, 0x38, 0x67, 0x4C, 0x10, 0x82, 0x05, + 0x66, 0x62, 0xB9, 0x67, 0x4C, 0x10, 0xF2, 0x05, 0x15, 0x22, 0x56, 0x26, 0xB9, 0x27, 0x4C, 0x10, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0xAD, 0xDE, 0x08, 0x60, 0x00, 0x40, 0x2C, 0x70, 0x8C, 0x03, + 0xB9, 0x76, 0x00, 0x10, 0x04, 0x73, 0xB9, 0x76, 0x44, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x08, 0x10, 0x66, 0x72, 0xB9, 0x76, 0x08, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, + 0x38, 0x76, 0x64, 0x10, 0x66, 0x72, 0xB9, 0x76, 0x64, 0x10, 0xE1, 0xF0, 0x04, 0x62, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x14, 0x10, 0xE1, 0xF0, 0x23, 0x22, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, + 0x10, 0x10, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x14, 0x10, 0x1C, 0x50, 0x11, 0x00, + 0x56, 0x75, 0x64, 0x71, 0xB9, 0x76, 0x14, 0x10, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x08, 0x60, 0x00, 0x40, 0x38, 0x76, 0x14, 0x10, 0x14, 0x52, 0x56, 0x75, 0x6C, 0x70, 0x10, 0x00, + 0xB9, 0x76, 0x14, 0x10, 0x0C, 0x20, 0x28, 0x00, 0x8B, 0xBD, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x04, 0x7F, 0x82, 0x03, 0x0C, 0x70, 0x9C, 0x00, 0x6C, 0x70, + 0x00, 0x01, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x74, 0x10, 0xE1, 0xF0, 0x04, 0x61, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x70, 0x10, 0xE1, 0xF0, 0xC4, 0x20, 0x08, 0x70, 0x00, 0x40, 0x82, 0x04, + 0x04, 0x61, 0xB1, 0x67, 0xF2, 0x02, 0xB1, 0x07, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x30, 0x57, 0x21, + 0x08, 0x70, 0x00, 0x40, 0x26, 0x72, 0x82, 0x04, 0x04, 0x61, 0xB1, 0x67, 0xF2, 0x02, 0xB1, 0x07, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x8B, 0x8E, 0x00, 0x00, 0x08, 0x70, + 0x1C, 0xE1, 0x08, 0x60, 0x00, 0x30, 0x2C, 0x70, 0x04, 0xE9, 0xB9, 0x76, 0x04, 0x01, 0x08, 0xE0, + 0x00, 0x40, 0xB9, 0x76, 0x08, 0x01, 0x2C, 0xE0, 0x70, 0x10, 0x04, 0xD1, 0xB1, 0xDE, 0x04, 0x2A, + 0xAB, 0xC0, 0x00, 0x00, 0xF2, 0xFC, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, + 0x01, 0x70, 0xC9, 0x61, 0x08, 0x00, 0x04, 0x61, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x14, 0x40, + 0x48, 0x61, 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, 0x40, 0x61, 0x2C, 0x10, 0x10, 0x00, 0x61, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, 0x08, 0x00, 0x04, 0x61, + 0x08, 0x70, 0x00, 0x40, 0xB9, 0x67, 0x14, 0x50, 0x48, 0x61, 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, + 0x40, 0x61, 0x2C, 0x10, 0x10, 0x00, 0x61, 0x00, 0x3C, 0x10, 0x24, 0x00, 0xD9, 0x41, 0x08, 0x00, + 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, 0x1C, 0x00, 0xC1, 0x21, 0x04, 0x61, 0x0C, 0x20, 0x28, 0x00, + 0xB9, 0xF1, 0x18, 0x00, 0x99, 0x60, 0xD3, 0x16, 0x8B, 0xBD, 0x00, 0x00, 0x04, 0x61, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x78, 0x10, 0x48, 0x61, 0x1C, 0x00, 0x38, 0xF1, 0x18, 0x00, 0x40, 0x21, + 0x11, 0x16, 0x11, 0x07, 0x58, 0x41, 0x08, 0x00, 0x2C, 0x10, 0x24, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, 0x08, 0x00, 0x04, 0x61, + 0x99, 0x60, 0xD2, 0x16, 0x48, 0x61, 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, 0x40, 0x61, 0x2C, 0x10, + 0x10, 0x00, 0x61, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xC1, 0x61, 0x01, 0x61, 0x01, 0x70, 0xC9, 0x61, + 0x08, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x67, 0x08, 0x70, 0xB9, 0x67, 0x08, 0x70, 0x48, 0x61, + 0x08, 0x00, 0x11, 0x16, 0x11, 0x07, 0x40, 0x61, 0x2C, 0x10, 0x10, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x08, 0x70, 0x04, 0x00, 0x24, 0x74, 0x26, 0x27, 0x08, 0x70, 0xFF, 0xBF, 0x57, 0x26, 0x2C, 0x70, + 0x00, 0xC0, 0xB1, 0x42, 0x26, 0x27, 0x0C, 0x40, 0x04, 0x40, 0x08, 0x70, 0x00, 0x40, 0x26, 0x47, + 0x26, 0x42, 0xB1, 0x34, 0x0C, 0x40, 0x10, 0x40, 0x26, 0x47, 0x26, 0x42, 0x2C, 0x70, 0x08, 0x40, + 0xB1, 0x54, 0x26, 0x27, 0xB1, 0x62, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0x2C, 0x70, 0x08, 0x40, + 0x57, 0x26, 0x26, 0x27, 0x30, 0x72, 0x6C, 0x70, 0x00, 0x01, 0xB1, 0x72, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x70, 0x00, 0x40, 0x2C, 0x70, 0x08, 0x40, 0x57, 0x26, 0x26, 0x27, 0x30, 0x72, 0x1C, 0x60, + 0x01, 0x01, 0x56, 0x76, 0xB1, 0x72, 0xE1, 0xF0, 0x08, 0x70, 0x04, 0x00, 0x24, 0x74, 0x26, 0x27, + 0x57, 0x26, 0xB1, 0x32, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0x57, 0x26, 0x2C, 0x70, + 0x0C, 0x40, 0x26, 0x72, 0x30, 0x27, 0xE1, 0xF0, 0x08, 0x70, 0x0F, 0x00, 0xD6, 0x72, 0x3C, 0x10, + 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x06, 0xC3, 0x82, 0x04, 0x1C, 0x70, 0x01, 0x10, 0x56, 0xE7, + 0x08, 0xD0, 0x00, 0x30, 0x8B, 0x8E, 0x00, 0x00, 0xB9, 0xED, 0x04, 0x01, 0xEB, 0x61, 0x00, 0x00, + 0x0C, 0x20, 0xE8, 0x03, 0xAB, 0xC0, 0x00, 0x00, 0xC4, 0xC0, 0x92, 0xF5, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x34, 0x18, 0x08, 0x50, 0x00, 0x80, 0xB9, 0xF1, 0x04, 0x00, 0xB1, 0x01, + 0x04, 0x70, 0x2C, 0x50, 0xB8, 0x6E, 0xC6, 0x73, 0x82, 0x0F, 0x04, 0x63, 0x56, 0x67, 0x26, 0x61, + 0x2F, 0x47, 0x02, 0x00, 0x10, 0xF6, 0x10, 0x44, 0x24, 0x71, 0x76, 0x4F, 0x13, 0x44, 0x26, 0x45, + 0x10, 0x44, 0x91, 0x46, 0xF2, 0xF1, 0x38, 0xF1, 0x04, 0x00, 0x30, 0x21, 0x24, 0x18, 0xE1, 0xF0, + 0x34, 0x18, 0x08, 0x70, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0xC1, 0xE1, 0x2C, 0x40, 0x5C, 0x04, + 0x06, 0xE2, 0x06, 0x27, 0x2C, 0x20, 0x80, 0x02, 0x36, 0x42, 0x08, 0x30, 0x00, 0x80, 0x2C, 0x30, + 0x54, 0x71, 0x77, 0x41, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x98, 0x01, 0x04, 0x30, + 0x0C, 0x40, 0x80, 0x04, 0x0C, 0x50, 0x00, 0x01, 0x04, 0x61, 0x0C, 0xF0, 0x98, 0x03, 0xF1, 0xF0, + 0xC4, 0x20, 0x82, 0x26, 0x04, 0x21, 0x4B, 0x3D, 0x00, 0x00, 0x0C, 0x50, 0x80, 0x04, 0x0C, 0x70, + 0x88, 0x04, 0x06, 0x2E, 0x2C, 0x50, 0xC8, 0x01, 0x30, 0x67, 0x5C, 0x60, 0xFF, 0x03, 0x57, 0x61, + 0xB1, 0x62, 0x30, 0x67, 0x77, 0x64, 0x5C, 0x60, 0xFC, 0x0F, 0xB9, 0x62, 0x04, 0x00, 0x30, 0x67, + 0x24, 0x74, 0x77, 0x69, 0xC6, 0x75, 0x5C, 0x60, 0xFC, 0x0F, 0xB9, 0x62, 0x08, 0x00, 0x24, 0x2C, + 0x92, 0xEC, 0x04, 0x20, 0x4B, 0x3D, 0x00, 0x00, 0x38, 0x20, 0x84, 0x04, 0xF2, 0x03, 0x08, 0x20, + 0x01, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x08, 0x20, 0x00, 0x30, 0x34, 0x18, 0x2C, 0x20, + 0x00, 0x40, 0xC1, 0xE1, 0x8B, 0x74, 0x00, 0x00, 0x08, 0x70, 0x00, 0xFF, 0x2C, 0x70, 0xFF, 0x00, + 0x08, 0x60, 0x00, 0xAA, 0x0C, 0x50, 0x55, 0x00, 0x56, 0x72, 0x26, 0x56, 0xC6, 0x75, 0x06, 0xE2, + 0x92, 0x19, 0x0C, 0x70, 0x00, 0x10, 0xD6, 0x72, 0x82, 0x18, 0x0C, 0x20, 0x98, 0x01, 0x04, 0x34, + 0x0C, 0x40, 0xC4, 0x01, 0x0C, 0xF0, 0x04, 0x04, 0xF1, 0xF0, 0x38, 0x70, 0x80, 0x04, 0xC6, 0x27, + 0x82, 0x05, 0x08, 0x70, 0x02, 0x00, 0x66, 0xE7, 0xF2, 0x08, 0x04, 0x61, 0x99, 0x60, 0xD4, 0x16, + 0xF2, 0x08, 0x06, 0xE6, 0x2C, 0xE0, 0x55, 0x01, 0x06, 0x2E, 0x04, 0x30, 0xCB, 0x70, 0x00, 0x00, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0x40, + 0x00, 0x00, 0x06, 0xC2, 0x08, 0x20, 0x00, 0x00, 0x2C, 0x20, 0x80, 0x02, 0x2C, 0x40, 0x5C, 0x04, + 0x06, 0xE3, 0x36, 0x42, 0x08, 0x30, 0x00, 0x80, 0x2C, 0x30, 0x54, 0x71, 0x77, 0x41, 0x0C, 0xF0, + 0x5C, 0x01, 0xF1, 0xF0, 0x0C, 0xF0, 0xA4, 0x02, 0xF1, 0xF0, 0x04, 0x30, 0x0C, 0x20, 0x98, 0x01, + 0x0C, 0x40, 0x80, 0x04, 0x0C, 0x50, 0x00, 0x01, 0x06, 0x63, 0x0C, 0xF0, 0x98, 0x03, 0xF1, 0xF0, + 0xC4, 0x20, 0x82, 0x4B, 0x0C, 0xD0, 0x00, 0x10, 0x66, 0xDE, 0x0C, 0xF0, 0x80, 0x04, 0xB9, 0xD0, + 0x84, 0x04, 0x06, 0x6C, 0x0C, 0x40, 0x88, 0x04, 0x2C, 0xF0, 0xC8, 0x01, 0x78, 0x76, 0x02, 0x00, + 0x78, 0x56, 0x04, 0x00, 0x77, 0x71, 0x77, 0x51, 0x57, 0x5A, 0x57, 0x75, 0x66, 0x75, 0x70, 0x56, + 0x24, 0x66, 0x77, 0x51, 0x66, 0x75, 0xB1, 0x74, 0x24, 0x44, 0xC6, 0x4F, 0x92, 0xF0, 0x0C, 0x30, + 0xC0, 0x01, 0x0C, 0x20, 0x84, 0x04, 0xAB, 0x72, 0x00, 0x00, 0xB9, 0x20, 0x80, 0x04, 0x04, 0x30, + 0x0C, 0x20, 0x38, 0x00, 0x0C, 0xF0, 0xE8, 0x02, 0xF1, 0xF0, 0x0C, 0x20, 0x58, 0x01, 0x04, 0x30, + 0x0C, 0x40, 0x80, 0x04, 0x0C, 0x50, 0x00, 0x01, 0x0C, 0xF0, 0x34, 0x03, 0xF1, 0xF0, 0x0C, 0xF0, + 0xC0, 0x02, 0xF1, 0xF0, 0x0C, 0x20, 0x98, 0x01, 0x04, 0x34, 0x0C, 0x40, 0xC4, 0x01, 0x0C, 0xF0, + 0x04, 0x04, 0xF1, 0xF0, 0x38, 0x70, 0x80, 0x04, 0xC6, 0x27, 0x82, 0x0A, 0x08, 0x20, 0x02, 0x00, + 0x2C, 0x20, 0x00, 0x10, 0x66, 0x2E, 0xF2, 0x05, 0x08, 0x20, 0x01, 0x00, 0xF2, 0x02, 0x06, 0x2D, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x18, 0x70, + 0xE6, 0x16, 0x1C, 0x60, 0x10, 0x00, 0x56, 0x76, 0x06, 0x43, 0x64, 0x78, 0xF7, 0x40, 0x04, 0x30, + 0x99, 0x70, 0xE6, 0x16, 0x06, 0xD2, 0x0C, 0xF0, 0xC4, 0x01, 0xF1, 0xF0, 0x18, 0x20, 0xE6, 0x16, + 0xEB, 0x41, 0x00, 0x00, 0x18, 0x20, 0xE6, 0x16, 0xCB, 0x49, 0x00, 0x00, 0xAB, 0xDD, 0x00, 0x00, + 0x2B, 0x31, 0x00, 0x00, 0x0C, 0xE0, 0x15, 0x00, 0xB4, 0xE1, 0x82, 0x09, 0x04, 0x21, 0x0C, 0x30, + 0x00, 0x20, 0x4B, 0x38, 0x00, 0x00, 0x8B, 0x35, 0x00, 0x00, 0xF2, 0xF7, 0x08, 0x60, 0x00, 0x30, + 0x0C, 0x70, 0x00, 0x49, 0x0C, 0x50, 0x40, 0x4E, 0x06, 0x2D, 0x26, 0x76, 0x26, 0x56, 0x30, 0x67, + 0x24, 0x74, 0xC6, 0x75, 0x5C, 0x60, 0xFF, 0x0F, 0xA1, 0x62, 0x24, 0x22, 0x92, 0xF9, 0x50, 0xC1, + 0x08, 0x20, 0x00, 0xAA, 0x2C, 0x20, 0x55, 0x00, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x2D, 0x0C, 0x20, 0x80, 0x02, 0x0C, 0x30, 0xD2, 0x02, + 0x4B, 0x84, 0x00, 0x00, 0x08, 0x70, 0x00, 0xAA, 0x2C, 0x70, 0x55, 0x00, 0xD6, 0x72, 0x06, 0xE2, + 0x06, 0x2D, 0x82, 0x03, 0x6C, 0xE0, 0x00, 0x20, 0x0C, 0x70, 0x00, 0x20, 0xD6, 0x7E, 0x82, 0x07, + 0x06, 0x3E, 0x0C, 0x20, 0x80, 0x02, 0xCB, 0x7C, 0x00, 0x00, 0x66, 0xE2, 0x06, 0x2E, 0x04, 0x31, + 0xB9, 0x00, 0xB4, 0x15, 0xCB, 0x70, 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0x08, 0xE0, 0x00, 0x80, + 0x2C, 0xE0, 0x0C, 0xDC, 0x28, 0x7E, 0x1C, 0x00, 0x28, 0x6E, 0x56, 0x00, 0x28, 0xDE, 0x1E, 0x00, + 0x28, 0x3E, 0x5A, 0x00, 0xB1, 0xB1, 0x28, 0xBE, 0x54, 0x00, 0x3F, 0x26, 0x07, 0x00, 0x3F, 0x33, + 0x0D, 0x00, 0x43, 0x33, 0x43, 0x22, 0x26, 0xB7, 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0x28, 0x7E, + 0x58, 0x00, 0x23, 0xBB, 0x2F, 0x37, 0x0D, 0x00, 0x06, 0xC2, 0x43, 0x33, 0x43, 0x2B, 0x0C, 0xF0, + 0x98, 0x00, 0xF1, 0xF0, 0x23, 0xCC, 0x57, 0x28, 0x66, 0x2C, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x26, + 0x84, 0x70, 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x60, 0x00, 0x30, 0x38, 0x76, 0x28, 0x00, 0xD4, 0x74, 0x92, 0xFD, 0xE1, 0xF0, 0x00, 0x00, + 0x08, 0x60, 0x00, 0x30, 0x38, 0x76, 0x40, 0x01, 0x23, 0x77, 0xB9, 0x76, 0x40, 0x01, 0xE1, 0xF0, + 0x08, 0x70, 0x00, 0x30, 0x38, 0x27, 0x40, 0x01, 0xF7, 0x2F, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x8B, 0x8F, 0x00, 0x00, 0x04, 0x70, 0xC6, 0x27, 0x82, 0x0D, 0x8B, 0x8E, 0x00, 0x00, 0x08, 0x70, + 0x00, 0x30, 0x08, 0x60, 0x00, 0x80, 0xB9, 0x67, 0x40, 0x01, 0x38, 0x77, 0x3C, 0x01, 0xB9, 0x70, + 0xB4, 0x15, 0x30, 0xF1, 0x06, 0x27, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x06, 0x72, 0x77, 0x78, + 0xCC, 0x70, 0x15, 0x00, 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0xB1, 0xB1, 0x0C, 0xE0, + 0xFF, 0xFF, 0x56, 0xE2, 0x82, 0x4E, 0xCC, 0x70, 0x15, 0x00, 0xD2, 0x1B, 0xCC, 0x70, 0x10, 0x00, + 0x82, 0x3B, 0xCC, 0x70, 0x10, 0x00, 0xD2, 0x08, 0xC4, 0x71, 0x82, 0x32, 0xC4, 0x72, 0x92, 0x50, + 0x99, 0xE0, 0xDE, 0x16, 0xF2, 0x66, 0xCC, 0x70, 0x13, 0x00, 0x82, 0x32, 0xCC, 0x70, 0x13, 0x00, + 0xD2, 0x32, 0xCC, 0x70, 0x12, 0x00, 0x92, 0x44, 0x99, 0xE0, 0xDC, 0x16, 0xFA, 0xA6, 0x00, 0x00, + 0xCC, 0x70, 0x23, 0x00, 0x82, 0x34, 0xCC, 0x70, 0x23, 0x00, 0xD2, 0x0E, 0xCC, 0x70, 0x21, 0x00, + 0x82, 0x25, 0xCC, 0x70, 0x21, 0x00, 0xD2, 0x28, 0xCC, 0x70, 0x20, 0x00, 0x92, 0x31, 0xA9, 0xE0, + 0xCC, 0x16, 0xFA, 0x93, 0x00, 0x00, 0xCC, 0x70, 0x81, 0x00, 0x82, 0x24, 0xCC, 0x70, 0xE0, 0x00, + 0x82, 0x24, 0xCC, 0x70, 0x80, 0x00, 0x92, 0x24, 0x99, 0xE0, 0xD6, 0x16, 0xF2, 0x7A, 0x99, 0x70, + 0xDF, 0x16, 0xFA, 0x83, 0x00, 0x00, 0x99, 0xE0, 0xDD, 0x16, 0xFA, 0x7F, 0x00, 0x00, 0x99, 0xE0, + 0xDB, 0x16, 0xF2, 0x7B, 0x99, 0xE0, 0xDA, 0x16, 0xF2, 0x78, 0xA9, 0xE0, 0xCE, 0x16, 0xF2, 0x75, + 0x99, 0xE0, 0xD9, 0x16, 0xF2, 0x72, 0xA9, 0xE0, 0xCA, 0x16, 0xF2, 0x69, 0xA9, 0xE0, 0xC8, 0x16, + 0xF2, 0x6C, 0x99, 0xE0, 0xD7, 0x16, 0xF2, 0x69, 0x99, 0xE0, 0xD5, 0x16, 0xF2, 0x66, 0xCC, 0x70, + 0x33, 0x00, 0x82, 0x37, 0xCC, 0x70, 0x33, 0x00, 0xD2, 0x0A, 0xCC, 0x70, 0x22, 0x00, 0x82, 0x57, + 0xCC, 0x70, 0x30, 0x00, 0x82, 0x31, 0xC4, 0x72, 0x92, 0x58, 0xF2, 0x0B, 0xCC, 0x70, 0x90, 0x00, + 0x82, 0x4B, 0xCC, 0x70, 0xE1, 0x00, 0x82, 0x4E, 0xCC, 0x70, 0x80, 0x00, 0x92, 0x4E, 0xF2, 0x41, + 0xCB, 0x52, 0x00, 0x00, 0xC4, 0xE0, 0x82, 0x0E, 0x08, 0x50, 0x00, 0x40, 0x38, 0x75, 0x54, 0x10, + 0x08, 0x40, 0x00, 0x80, 0x66, 0x74, 0xB9, 0x70, 0xB0, 0x15, 0x14, 0x71, 0xB9, 0x75, 0x54, 0x10, + 0xF2, 0x3C, 0xB8, 0x50, 0xB0, 0x15, 0x32, 0x0A, 0x08, 0x70, 0xFF, 0x7F, 0x2C, 0x70, 0xFF, 0xFF, + 0x56, 0x75, 0x08, 0x50, 0x00, 0x40, 0xB9, 0x75, 0x54, 0x10, 0xB9, 0x00, 0xB0, 0x15, 0xF2, 0x2D, + 0x8B, 0x88, 0x00, 0x00, 0xF2, 0x2A, 0x04, 0x20, 0x4B, 0x62, 0x00, 0x00, 0x0C, 0xB0, 0x40, 0x01, + 0x08, 0xE0, 0x00, 0x30, 0x08, 0xD0, 0x30, 0x00, 0x06, 0xCE, 0x26, 0xBE, 0x24, 0xD1, 0x08, 0x60, + 0x00, 0x80, 0xB8, 0x7E, 0x40, 0x01, 0x32, 0xFE, 0x38, 0x7E, 0x28, 0x00, 0xD4, 0x74, 0x92, 0xFD, + 0xB1, 0x6B, 0x38, 0x7C, 0x3C, 0x01, 0xC6, 0x7D, 0x92, 0xF5, 0x04, 0x74, 0xF1, 0x70, 0xF2, 0xF0, + 0x2B, 0xE5, 0x00, 0x00, 0xF2, 0x0A, 0xEB, 0x61, 0x00, 0x00, 0xF2, 0x07, 0xEB, 0xE3, 0x00, 0x00, + 0xF2, 0x04, 0x13, 0x2E, 0xEB, 0x1E, 0x01, 0x00, 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x2C, 0x10, + 0x14, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0xE0, 0x00, 0x30, 0x0C, 0xD0, + 0x00, 0x01, 0x26, 0xDE, 0x8B, 0x8E, 0x00, 0x00, 0x06, 0x2D, 0x04, 0x30, 0x0C, 0x40, 0x10, 0x00, + 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x38, 0x7E, 0x28, 0x00, 0xD4, 0x72, 0x82, 0x05, 0x04, 0x72, + 0xB9, 0x7E, 0x28, 0x00, 0xF2, 0xF0, 0x38, 0x7E, 0x40, 0x01, 0xB9, 0x7E, 0x40, 0x01, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0x0C, 0x20, 0x00, 0x00, 0x04, 0x30, + 0x0C, 0x40, 0x20, 0x00, 0xC1, 0xE1, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x06, 0x2E, 0x0C, 0x20, + 0x00, 0x27, 0x04, 0x30, 0x0C, 0x40, 0x20, 0x00, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x08, 0x70, + 0x00, 0x80, 0x2C, 0x70, 0x00, 0xFA, 0x38, 0x67, 0xF8, 0x01, 0xB9, 0x60, 0x00, 0x00, 0x38, 0x67, + 0xFC, 0x01, 0xB9, 0x60, 0x04, 0x00, 0x08, 0x60, 0x00, 0x80, 0x38, 0x66, 0x04, 0xDC, 0xB9, 0x60, + 0x08, 0x00, 0x38, 0x67, 0xF0, 0x01, 0xB9, 0x60, 0x0C, 0x00, 0x38, 0x67, 0xF4, 0x01, 0x38, 0x77, + 0xCC, 0x01, 0xC4, 0x60, 0xB9, 0x70, 0x1C, 0x00, 0x08, 0x70, 0x35, 0x45, 0x2C, 0x70, 0x01, 0x32, + 0xB9, 0x70, 0x24, 0x00, 0x08, 0x70, 0x01, 0xC6, 0x2C, 0x70, 0x01, 0x45, 0xB9, 0x60, 0x10, 0x00, + 0xB9, 0x70, 0x28, 0x00, 0x82, 0x04, 0x08, 0x70, 0x02, 0x65, 0xF2, 0x03, 0x08, 0x70, 0x02, 0x02, + 0xB9, 0x70, 0x2C, 0x00, 0x04, 0x71, 0xB9, 0x70, 0x34, 0x00, 0x08, 0x70, 0x80, 0x07, 0x2C, 0x70, + 0x38, 0x04, 0xB9, 0x70, 0x40, 0x00, 0x08, 0x70, 0x18, 0x00, 0x24, 0x7E, 0xB9, 0x70, 0x44, 0x00, + 0x08, 0x70, 0x03, 0x01, 0x2C, 0x70, 0x02, 0x17, 0xB9, 0x70, 0x48, 0x00, 0x08, 0x70, 0x06, 0x17, + 0x2C, 0x70, 0x0B, 0x17, 0xB9, 0x70, 0x4C, 0x00, 0x08, 0x70, 0xFF, 0xFF, 0xB9, 0x70, 0x50, 0x00, + 0x08, 0x70, 0x17, 0x00, 0x24, 0x7E, 0xB9, 0x70, 0x54, 0x00, 0x08, 0x60, 0x00, 0x80, 0x08, 0x70, + 0xFF, 0x00, 0x2C, 0x60, 0x0C, 0xDC, 0x2C, 0x70, 0x00, 0xFF, 0xB9, 0x70, 0x58, 0x00, 0x18, 0x76, + 0x2D, 0x00, 0xB9, 0x00, 0x30, 0x00, 0x0C, 0xE0, 0x00, 0x27, 0xB9, 0x70, 0x5C, 0x00, 0x18, 0x76, + 0x2C, 0x00, 0xB9, 0xE0, 0x70, 0x00, 0xB9, 0x70, 0x60, 0x00, 0x28, 0x76, 0x1E, 0x00, 0x28, 0x66, + 0x1C, 0x00, 0x57, 0x78, 0x66, 0x76, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x48, 0xDF, 0xB9, 0x70, + 0x64, 0x00, 0x28, 0x76, 0x32, 0x00, 0x28, 0x66, 0x2C, 0x00, 0x57, 0x78, 0x66, 0x76, 0xB9, 0x70, + 0x68, 0x00, 0x0C, 0x60, 0x00, 0x49, 0x08, 0x70, 0x00, 0x30, 0x26, 0x67, 0x2C, 0x70, 0x00, 0xA0, + 0xB9, 0x70, 0x6C, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0xB9, 0x70, 0x78, 0x00, 0xB9, 0x60, 0x74, 0x00, + 0x0C, 0x70, 0x28, 0x16, 0x08, 0x60, 0x00, 0x80, 0x66, 0x76, 0xB9, 0x70, 0x38, 0x00, 0x04, 0x72, + 0xB9, 0x70, 0x18, 0x00, 0xAB, 0x9E, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x7E, 0x70, 0x0A, 0x06, 0x43, + 0x04, 0x30, 0xC6, 0x73, 0x06, 0xD2, 0x82, 0x1B, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x38, 0x7E, + 0x38, 0x0A, 0x0C, 0x50, 0x70, 0x0A, 0xB1, 0x7D, 0x0C, 0x70, 0x38, 0x15, 0x26, 0x5E, 0x04, 0x61, + 0xB0, 0x37, 0x82, 0x06, 0x06, 0x46, 0x57, 0x41, 0x26, 0x4D, 0xB1, 0x34, 0x24, 0x61, 0x24, 0x74, + 0xC6, 0x75, 0x92, 0xF7, 0x18, 0x3E, 0x70, 0x0A, 0x99, 0x0E, 0x70, 0x0A, 0x50, 0xC1, 0x06, 0x23, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x70, 0x06, 0x67, 0x3F, 0x57, 0x03, 0x00, + 0xC4, 0x50, 0x02, 0x08, 0x2F, 0x57, 0x02, 0x00, 0x10, 0x55, 0x24, 0x71, 0x26, 0x65, 0x13, 0x66, + 0xF2, 0xF6, 0x06, 0x26, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x30, 0xE2, + 0x08, 0x70, 0xFF, 0x00, 0x2C, 0x70, 0xFF, 0xFF, 0x56, 0xE7, 0x6C, 0xE0, 0x00, 0x0C, 0xB1, 0xE2, + 0x57, 0x31, 0x06, 0xD2, 0xCB, 0xAE, 0x00, 0x00, 0x57, 0x2C, 0x66, 0x2E, 0xB1, 0x2D, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x50, 0x00, 0xD9, 0xC1, 0x40, 0x00, + 0x4B, 0xB8, 0x00, 0x00, 0x06, 0x21, 0x0C, 0x30, 0x10, 0x00, 0x0B, 0xAC, 0x00, 0x00, 0x86, 0xE2, + 0x82, 0x25, 0x06, 0x21, 0x06, 0x3E, 0xCB, 0xAF, 0x00, 0x00, 0x98, 0x70, 0xD8, 0x16, 0x82, 0x07, + 0x6B, 0xB8, 0x00, 0x00, 0x06, 0x7E, 0x57, 0x71, 0x26, 0x71, 0xB1, 0x27, 0x08, 0xD0, 0x00, 0x30, + 0x0C, 0xC0, 0x04, 0x01, 0x26, 0xCD, 0x8B, 0x8E, 0x00, 0x00, 0x06, 0x2C, 0x06, 0x31, 0x04, 0x4B, + 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0x38, 0x7D, 0x28, 0x00, 0xD4, 0x72, 0x82, 0x05, 0x04, 0x72, + 0xB9, 0x7D, 0x28, 0x00, 0xF2, 0xF1, 0x0B, 0x8F, 0x00, 0x00, 0x18, 0x70, 0xED, 0x16, 0xC4, 0x71, + 0x92, 0x11, 0x6B, 0x36, 0x01, 0x00, 0x98, 0x70, 0xEA, 0x16, 0x82, 0x05, 0xC4, 0x71, 0x92, 0x0A, + 0xC4, 0xE0, 0x92, 0x08, 0x08, 0x60, 0xDB, 0xDB, 0x08, 0x70, 0x00, 0x30, 0xB9, 0x67, 0x04, 0x01, + 0x04, 0xE1, 0x18, 0x60, 0xD5, 0x16, 0xC4, 0x62, 0x92, 0x12, 0x04, 0x61, 0x99, 0x60, 0xD5, 0x16, + 0x18, 0x70, 0xEA, 0x16, 0x04, 0x21, 0xC4, 0x70, 0x92, 0x0B, 0x08, 0x70, 0xA0, 0x8C, 0x2C, 0x70, + 0x0E, 0xD0, 0x08, 0x60, 0x00, 0x30, 0xB9, 0x76, 0x04, 0x01, 0xF2, 0x02, 0x06, 0x2E, 0x58, 0xC1, + 0x40, 0x00, 0x2C, 0x10, 0x50, 0x00, 0xE1, 0xF0, 0x0C, 0x50, 0x00, 0x00, 0x0C, 0x70, 0x78, 0x00, + 0x34, 0x54, 0x04, 0x60, 0x30, 0x47, 0x34, 0x74, 0xC6, 0x75, 0x26, 0x64, 0x92, 0xFC, 0xB9, 0x60, + 0x7C, 0x00, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x0C, 0x70, 0xFC, 0x0A, 0x38, 0x27, 0x38, 0x0A, 0x08, 0x60, 0xE0, 0x00, 0xD6, 0x26, 0x92, 0x17, + 0xA8, 0x77, 0x14, 0x03, 0x82, 0x34, 0xCC, 0x70, 0xFF, 0x0F, 0x82, 0x31, 0x26, 0x77, 0x06, 0x27, + 0x57, 0x22, 0x36, 0x27, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, 0x00, 0x00, 0x2C, 0x20, 0x90, 0x01, + 0xCC, 0x20, 0x58, 0x02, 0xC2, 0x24, 0x0C, 0x20, 0x58, 0x02, 0xF2, 0x21, 0x28, 0x27, 0x18, 0x03, + 0x1C, 0x70, 0xA5, 0x01, 0x26, 0x72, 0xCC, 0x70, 0xE8, 0x03, 0xD2, 0x0F, 0x3C, 0x20, 0x8D, 0x05, + 0x06, 0x32, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0xE9, 0x03, 0xCB, 0x14, 0x00, 0x00, 0x0C, 0x70, + 0x8D, 0x05, 0x3F, 0x22, 0x07, 0x00, 0xF2, 0x0B, 0xCC, 0x20, 0x8D, 0x05, 0xC2, 0x08, 0x3C, 0x20, + 0x8D, 0x05, 0x04, 0x33, 0xCB, 0x14, 0x00, 0x00, 0x2C, 0x20, 0x8D, 0x05, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x01, 0x00, 0x34, 0x14, 0x2C, 0x70, 0xF8, 0x24, 0xB1, 0x71, + 0x30, 0x71, 0x14, 0x61, 0xC4, 0x70, 0x26, 0x67, 0xB1, 0x61, 0x92, 0xFB, 0x24, 0x14, 0xE1, 0xF0, + 0x06, 0x72, 0x57, 0x71, 0x26, 0x27, 0x34, 0x14, 0xF7, 0x20, 0xB1, 0x21, 0x30, 0x71, 0x14, 0x61, + 0xC4, 0x70, 0x26, 0x67, 0xB1, 0x61, 0x92, 0xFB, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x04, 0x3A, + 0xB1, 0xF1, 0xCB, 0x14, 0x00, 0x00, 0x23, 0x32, 0x04, 0x21, 0xCB, 0x6F, 0x00, 0x00, 0x04, 0x21, + 0x4B, 0x6E, 0x00, 0x00, 0x04, 0x24, 0x04, 0x30, 0xCB, 0x55, 0x00, 0x00, 0xCB, 0x51, 0x00, 0x00, + 0x04, 0x24, 0x04, 0x31, 0xCB, 0x55, 0x00, 0x00, 0x04, 0x21, 0x0B, 0x6F, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x6B, 0xBE, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x06, 0x72, 0x06, 0x62, 0xD7, 0x63, 0x57, 0x71, 0x3F, 0x77, 0x06, 0x00, + 0x26, 0x27, 0x34, 0x14, 0xD7, 0x21, 0xB1, 0xF1, 0x6B, 0xBE, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x20, 0xB1, 0xF1, 0x6B, 0x53, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x08, 0x60, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x2C, 0x60, 0x80, 0x00, + 0x2C, 0x70, 0x1C, 0x02, 0x36, 0x76, 0xC4, 0x70, 0x34, 0x14, 0xB1, 0xF1, 0x32, 0x02, 0x24, 0x73, + 0x06, 0x47, 0x08, 0x50, 0x00, 0x80, 0x67, 0x41, 0x04, 0x70, 0x2C, 0x50, 0xB8, 0x6F, 0x14, 0x21, + 0xC6, 0x74, 0x04, 0x34, 0x26, 0x36, 0x32, 0x05, 0x30, 0xF5, 0x24, 0x54, 0xB1, 0xF6, 0xF2, 0x02, + 0xB1, 0x26, 0x24, 0x71, 0xCC, 0x70, 0x80, 0x00, 0x82, 0x03, 0x06, 0x63, 0xF2, 0xF2, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x28, 0x60, 0xCC, 0x16, 0xCC, 0x60, 0xFF, 0xFF, 0x92, 0x10, 0x38, 0x60, + 0x08, 0x0B, 0xD4, 0x61, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x0C, 0xDC, 0x82, 0x04, 0x38, 0x66, + 0x44, 0x00, 0xF2, 0x03, 0x38, 0x66, 0x40, 0x00, 0xA9, 0x60, 0xCC, 0x16, 0x28, 0x60, 0xCE, 0x16, + 0xCC, 0x60, 0xFF, 0xFF, 0x92, 0x07, 0x08, 0x60, 0x00, 0x80, 0x38, 0x66, 0x48, 0xDC, 0xA9, 0x60, + 0xCE, 0x16, 0xE1, 0xF0, 0x08, 0x40, 0x00, 0x80, 0x34, 0x14, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x40, + 0x0C, 0xDC, 0xB1, 0xF1, 0x2C, 0x70, 0x1A, 0xDC, 0x0C, 0x60, 0xBA, 0x16, 0x24, 0x4A, 0x14, 0x21, + 0x10, 0x57, 0xCC, 0x50, 0xFF, 0x00, 0x82, 0x0D, 0x18, 0x37, 0x04, 0x00, 0xCC, 0x30, 0xFF, 0x00, + 0x82, 0x08, 0x2F, 0xF5, 0x05, 0x00, 0x26, 0x5F, 0xD7, 0x51, 0x26, 0x53, 0xA1, 0x56, 0xF2, 0x02, + 0xA1, 0x26, 0x34, 0x71, 0xC6, 0x74, 0x34, 0x62, 0x92, 0xEC, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x34, 0x14, 0x0C, 0x20, 0xFC, 0x0A, 0x04, 0x30, 0x0C, 0x40, 0xB4, 0x0A, 0xB1, 0xF1, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0xAB, 0xC6, 0x00, 0x00, 0x2B, 0x43, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x0C, 0x60, 0xF4, 0x01, 0xB9, 0x60, 0xCC, 0x15, 0x99, 0x00, 0xEA, 0x16, + 0x14, 0x61, 0x99, 0x60, 0xE9, 0x16, 0xA9, 0x00, 0xD0, 0x16, 0xB9, 0x00, 0xC8, 0x15, 0xB9, 0x00, + 0xC4, 0x15, 0x99, 0x00, 0xE8, 0x16, 0xB9, 0x00, 0xC0, 0x15, 0xB9, 0x00, 0xBC, 0x15, 0x99, 0x00, + 0xE7, 0x16, 0x04, 0x63, 0x99, 0x60, 0xE6, 0x16, 0x99, 0x00, 0xDF, 0x16, 0x99, 0x00, 0xDE, 0x16, + 0x04, 0x71, 0x99, 0x70, 0xDD, 0x16, 0x99, 0x00, 0xDC, 0x16, 0x99, 0x70, 0xDB, 0x16, 0x99, 0x00, + 0xDA, 0x16, 0x14, 0x61, 0xA9, 0x60, 0xCE, 0x16, 0xA9, 0x60, 0xCC, 0x16, 0x08, 0x60, 0x00, 0x80, + 0x2C, 0x60, 0x00, 0xDC, 0x18, 0x46, 0x09, 0x00, 0x99, 0x40, 0xD9, 0x16, 0x18, 0x56, 0x08, 0x00, + 0xA9, 0x50, 0xCA, 0x16, 0xA9, 0x00, 0xC8, 0x16, 0x99, 0x00, 0xD8, 0x16, 0x99, 0x00, 0xD7, 0x16, + 0x99, 0x00, 0xD6, 0x16, 0x0C, 0x50, 0xFC, 0x0A, 0xB9, 0x00, 0xB8, 0x15, 0x99, 0x70, 0xE4, 0x16, + 0x38, 0x65, 0x0C, 0x00, 0x64, 0x64, 0xB9, 0x65, 0x0C, 0x00, 0x99, 0x00, 0xE3, 0x16, 0x08, 0x60, + 0x00, 0x80, 0x18, 0x56, 0x7D, 0xDC, 0x99, 0x50, 0xE2, 0x16, 0x99, 0x00, 0xE1, 0x16, 0x99, 0x70, + 0xEC, 0x16, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x2B, 0x3E, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x2B, 0x54, 0x00, 0x00, 0x04, 0x20, 0x2B, 0x61, + 0x00, 0x00, 0xEB, 0x3A, 0x01, 0x00, 0x08, 0x70, 0x00, 0x40, 0x38, 0x77, 0x10, 0x20, 0x30, 0xF1, + 0xF7, 0x70, 0xB9, 0x70, 0x20, 0x00, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, + 0x11, 0x00, 0xB1, 0xF1, 0x8B, 0x32, 0x00, 0x00, 0x04, 0x2B, 0x04, 0x31, 0xEB, 0x62, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x21, 0xB1, 0xF1, 0xEB, 0x5D, + 0x00, 0x00, 0x04, 0x24, 0xEB, 0x5D, 0x00, 0x00, 0x0C, 0x20, 0x40, 0x00, 0xEB, 0x5D, 0x00, 0x00, + 0x0C, 0x20, 0x10, 0x00, 0x6B, 0x5D, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x14, 0xB1, 0xF1, 0x6B, 0x5E, 0x00, 0x00, 0x04, 0x25, 0x04, 0x31, 0xEB, 0x62, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, 0x00, 0x01, 0xB1, 0xF1, + 0x2B, 0x57, 0x00, 0x00, 0x0C, 0x20, 0x80, 0x00, 0x2B, 0x57, 0x00, 0x00, 0x04, 0x20, 0x06, 0x52, + 0x0C, 0x30, 0x27, 0x00, 0x0C, 0x40, 0xFF, 0xFF, 0x0C, 0x60, 0x01, 0x02, 0x8B, 0x6C, 0x00, 0x00, + 0x04, 0x21, 0x0C, 0x30, 0x8F, 0x01, 0x0C, 0x40, 0xFF, 0xFF, 0x04, 0x50, 0x0C, 0x60, 0x01, 0x02, + 0x8B, 0x6C, 0x00, 0x00, 0x04, 0x27, 0x04, 0x31, 0xEB, 0x62, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x21, 0xB1, 0xF1, 0x4B, 0x62, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0x60, 0x00, 0x40, 0x38, 0xE6, + 0x70, 0x60, 0x06, 0x72, 0x23, 0xEE, 0xCC, 0xE0, 0x00, 0xC9, 0x06, 0xC3, 0xC2, 0x05, 0x08, 0x60, + 0x04, 0x00, 0x66, 0xE6, 0xF7, 0xE1, 0x06, 0x37, 0x06, 0x2E, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, + 0xA0, 0x0F, 0xCB, 0x14, 0x00, 0x00, 0x24, 0x25, 0x04, 0x3A, 0xCB, 0x14, 0x00, 0x00, 0x08, 0x70, + 0x00, 0x40, 0x38, 0x77, 0xCC, 0x71, 0x06, 0xD2, 0x77, 0x7C, 0x24, 0x72, 0xC6, 0x27, 0xB2, 0x02, + 0x06, 0xD7, 0xC4, 0xC0, 0x82, 0x18, 0x06, 0x7E, 0xD7, 0x71, 0x2F, 0x2E, 0x0E, 0x00, 0x26, 0x27, + 0x06, 0x3D, 0xCB, 0x14, 0x00, 0x00, 0x3C, 0xE0, 0xB0, 0x9A, 0xCC, 0xE0, 0x20, 0x03, 0x04, 0x71, + 0xD2, 0x02, 0x04, 0x70, 0xD7, 0x7F, 0x66, 0x72, 0x0C, 0x60, 0x00, 0x00, 0xB9, 0x76, 0x3C, 0x00, + 0x4B, 0xB7, 0x00, 0x00, 0x06, 0x2D, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x38, 0x70, 0xB0, 0x16, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x38, 0xE7, 0x04, 0x00, 0x18, 0x27, + 0x05, 0x00, 0x04, 0x30, 0x0C, 0xC0, 0xFF, 0x00, 0x2B, 0xD7, 0x00, 0x00, 0x56, 0xCE, 0x06, 0xD2, + 0x04, 0x30, 0x06, 0x2C, 0x2B, 0xD7, 0x00, 0x00, 0x08, 0x70, 0xFF, 0xFF, 0x56, 0x7E, 0x57, 0xD4, + 0x66, 0x72, 0x66, 0x7D, 0x08, 0x60, 0x00, 0x40, 0xB9, 0x76, 0x6C, 0x72, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x38, 0x70, 0xB0, 0x16, 0x34, 0x14, 0xB1, 0xF1, 0x18, 0x27, 0x08, 0x00, + 0x04, 0x31, 0x2B, 0xD7, 0x00, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x27, 0x18, 0x70, 0x8B, 0xDB, + 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, 0x38, 0x57, 0x64, 0x71, + 0x38, 0x77, 0x9C, 0x60, 0x06, 0x65, 0xC4, 0x71, 0x77, 0x6A, 0x54, 0x6F, 0x02, 0x14, 0x34, 0x78, + 0x26, 0x76, 0xC4, 0x7F, 0x02, 0x02, 0x04, 0x7F, 0x86, 0x67, 0x32, 0x02, 0x04, 0x60, 0x08, 0x70, + 0x0F, 0xFF, 0x2C, 0x70, 0xFF, 0xFF, 0x56, 0x75, 0x57, 0x6A, 0x66, 0x67, 0x08, 0x70, 0x00, 0x40, + 0xB9, 0x67, 0x64, 0x71, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0x5C, 0x00, 0x00, + 0x04, 0x31, 0x0C, 0x20, 0x20, 0x00, 0x4B, 0x5B, 0x00, 0x00, 0x0C, 0x20, 0xFF, 0x00, 0x0B, 0x59, + 0x00, 0x00, 0x04, 0x31, 0x04, 0x24, 0xCB, 0x55, 0x00, 0x00, 0x04, 0x21, 0xEB, 0x51, 0x00, 0x00, + 0xCB, 0xDE, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x34, 0x18, + 0xC1, 0xE1, 0x82, 0x0A, 0x04, 0x21, 0x6B, 0xBB, 0x02, 0x00, 0x18, 0x60, 0xE6, 0x16, 0x1C, 0x70, + 0x80, 0x00, 0x66, 0x76, 0xF2, 0x07, 0x6B, 0xBB, 0x02, 0x00, 0x18, 0x70, 0xE6, 0x16, 0x5C, 0x70, + 0x7F, 0x00, 0x99, 0x70, 0xE6, 0x16, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x80, + 0x98, 0x77, 0x6C, 0xDC, 0x34, 0x14, 0xB1, 0xF1, 0x82, 0x04, 0x28, 0x20, 0xCA, 0x16, 0xF2, 0x05, + 0x08, 0x70, 0x00, 0x80, 0x18, 0x27, 0x08, 0xDC, 0x54, 0x21, 0x6B, 0xE2, 0x00, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x04, 0x21, 0xB1, 0xF1, 0x2B, 0x61, 0x00, 0x00, 0x98, 0x70, + 0xD6, 0x16, 0x82, 0x27, 0x5C, 0x70, 0xF0, 0x00, 0xCC, 0x70, 0x80, 0x00, 0x82, 0x08, 0xCC, 0x70, + 0xC0, 0x00, 0x92, 0x1F, 0x04, 0x61, 0x99, 0x60, 0xD8, 0x16, 0xF2, 0x1B, 0x04, 0x71, 0x99, 0x70, + 0xD8, 0x16, 0x99, 0x70, 0xDA, 0x16, 0x99, 0x00, 0xDB, 0x16, 0x08, 0x60, 0x00, 0x80, 0x98, 0x66, + 0xAD, 0xDC, 0x92, 0x04, 0x99, 0x00, 0xD7, 0x16, 0xF2, 0x03, 0x99, 0x70, 0xD7, 0x16, 0x04, 0x20, + 0x6B, 0xBB, 0x02, 0x00, 0x18, 0x60, 0xE6, 0x16, 0x5C, 0x60, 0x7F, 0x00, 0x99, 0x60, 0xE6, 0x16, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, + 0x2C, 0x20, 0x80, 0x02, 0x2C, 0x40, 0x5C, 0x04, 0x36, 0x42, 0x08, 0x30, 0x00, 0x80, 0x3C, 0x10, + 0x10, 0x00, 0x2C, 0x30, 0x54, 0x71, 0x77, 0x41, 0xD1, 0xC1, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, + 0x08, 0x40, 0x00, 0x80, 0x0C, 0x20, 0x90, 0x01, 0x04, 0x30, 0x2C, 0x40, 0x00, 0xF0, 0x0C, 0xF0, + 0x04, 0x04, 0xF1, 0xF0, 0xB9, 0x20, 0x14, 0x00, 0x08, 0x70, 0x00, 0x80, 0x38, 0xD7, 0xD0, 0xFB, + 0x06, 0xE2, 0xCC, 0xD0, 0xFF, 0x00, 0x82, 0x17, 0xC6, 0xD2, 0x82, 0x15, 0x8B, 0x8E, 0x00, 0x00, + 0x08, 0x60, 0x1C, 0xE1, 0x08, 0x70, 0x00, 0x30, 0x2C, 0x60, 0x01, 0xE9, 0xB9, 0x67, 0x04, 0x01, + 0xB9, 0xD7, 0x08, 0x01, 0xB9, 0xE7, 0x0C, 0x01, 0xEB, 0x61, 0x00, 0x00, 0x04, 0x2A, 0xAB, 0xC0, + 0x00, 0x00, 0xF2, 0xFB, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x98, 0x60, 0xE2, 0x16, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x82, 0x09, 0x34, 0x61, 0x93, 0x66, 0x99, 0x60, 0xE2, 0x16, + 0x92, 0x54, 0x99, 0x00, 0xE4, 0x16, 0xF2, 0x49, 0xDC, 0x20, 0x80, 0x00, 0x08, 0xE0, 0x00, 0x80, + 0x2C, 0xE0, 0x0C, 0xDC, 0x82, 0x04, 0x18, 0xDE, 0x73, 0x00, 0xF2, 0x03, 0x18, 0xDE, 0x72, 0x00, + 0xCB, 0x3C, 0x00, 0x00, 0xC6, 0x2D, 0xA2, 0x0A, 0x38, 0x50, 0xC4, 0x15, 0x18, 0x60, 0xE3, 0x16, + 0x34, 0x53, 0xC6, 0x65, 0xB2, 0x1A, 0x24, 0x61, 0xF2, 0x16, 0x98, 0x60, 0xE3, 0x16, 0x82, 0x15, + 0x98, 0x50, 0xEA, 0x16, 0x82, 0x04, 0xB8, 0x50, 0xC8, 0x15, 0x92, 0x0F, 0x18, 0x5E, 0x74, 0x00, + 0x36, 0xD5, 0xC6, 0x2D, 0xD2, 0x0A, 0x18, 0x40, 0xE1, 0x16, 0x28, 0x5E, 0x7A, 0x00, 0xC6, 0x45, + 0xD2, 0x04, 0x34, 0x61, 0x99, 0x60, 0xE3, 0x16, 0x98, 0x50, 0xE4, 0x16, 0x18, 0x50, 0xE3, 0x16, + 0x92, 0x0E, 0x18, 0x7E, 0x75, 0x00, 0xC6, 0x57, 0xA2, 0x18, 0x04, 0x71, 0x99, 0x70, 0xE4, 0x16, + 0x0C, 0x60, 0xFC, 0x0A, 0x38, 0x76, 0x0C, 0x00, 0x64, 0x74, 0xF2, 0x0D, 0x18, 0x7E, 0x76, 0x00, + 0xC6, 0x57, 0xD2, 0x0B, 0x99, 0x00, 0xE4, 0x16, 0x0C, 0x60, 0xFC, 0x0A, 0x38, 0x76, 0x0C, 0x00, + 0x14, 0x55, 0x56, 0x75, 0xB9, 0x76, 0x0C, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE2, 0x0B, 0x4F, 0x00, 0x00, 0x06, 0x2E, 0xAB, 0x4B, 0x00, 0x00, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xD2, + 0xCB, 0x2F, 0x00, 0x00, 0x18, 0x20, 0xE6, 0x16, 0x5C, 0x20, 0xF0, 0x00, 0x64, 0x23, 0x99, 0x20, + 0xE6, 0x16, 0xEB, 0x41, 0x00, 0x00, 0x18, 0x20, 0xE6, 0x16, 0xCB, 0x49, 0x00, 0x00, 0x6B, 0x2E, + 0x00, 0x00, 0x04, 0x20, 0x6B, 0xCA, 0x02, 0x00, 0xAB, 0x3A, 0x00, 0x00, 0xC4, 0xD0, 0x92, 0x08, + 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x38, 0x00, 0x00, 0x8B, 0x35, 0x00, 0x00, 0xCB, 0x39, + 0x00, 0x00, 0x08, 0x70, 0x00, 0x80, 0x18, 0xC7, 0x6A, 0xDC, 0x04, 0xE0, 0xC6, 0xCE, 0x82, 0x0E, + 0x04, 0x21, 0x0C, 0x30, 0x00, 0x20, 0x4B, 0x38, 0x00, 0x00, 0x8B, 0x35, 0x00, 0x00, 0xC4, 0xD0, + 0x82, 0x12, 0x8B, 0x8F, 0x00, 0x00, 0xC4, 0x20, 0x82, 0x0E, 0x0B, 0x2F, 0x00, 0x00, 0x2B, 0x3B, + 0x00, 0x00, 0x04, 0x61, 0x99, 0x60, 0xE7, 0x16, 0x6B, 0x30, 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x24, 0xE1, 0xF2, 0xE3, 0x34, 0x18, 0xC1, 0xE1, 0x08, 0x70, 0x00, 0x40, + 0x38, 0x77, 0x14, 0x10, 0xDC, 0x70, 0x00, 0x01, 0x92, 0x0F, 0x99, 0x00, 0xD3, 0x16, 0xCB, 0x5E, + 0x00, 0x00, 0x2B, 0x5F, 0x00, 0x00, 0x18, 0x70, 0xD3, 0x16, 0x93, 0x07, 0x92, 0x03, 0xCB, 0x51, + 0x00, 0x00, 0xEB, 0x5F, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x98, 0x70, 0xD8, 0x16, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, 0x92, 0x0A, 0x0C, 0x70, 0xFC, 0x0A, 0xA8, 0x67, + 0x10, 0x00, 0x82, 0x05, 0x34, 0x61, 0xA9, 0x67, 0x10, 0x00, 0xF2, 0x4C, 0x18, 0x70, 0xEA, 0x16, + 0xC4, 0x71, 0x92, 0x07, 0x98, 0x60, 0xE9, 0x16, 0x92, 0x04, 0xA9, 0x70, 0x0C, 0x0B, 0xF2, 0x42, + 0x38, 0x50, 0xB8, 0x15, 0xCC, 0x50, 0xE8, 0x03, 0xC2, 0x04, 0x0C, 0x50, 0xE9, 0x03, 0xF2, 0x02, + 0x24, 0x51, 0xC4, 0x70, 0xB9, 0x50, 0xB8, 0x15, 0x82, 0x04, 0x28, 0x70, 0xCC, 0x16, 0xF2, 0x18, + 0x08, 0xD0, 0x00, 0x80, 0x38, 0xC0, 0xBC, 0x15, 0x2C, 0xD0, 0x0C, 0xDC, 0x38, 0x2D, 0x4C, 0x00, + 0x38, 0x3D, 0x3C, 0x00, 0x04, 0x61, 0x26, 0x6C, 0xB9, 0x60, 0xBC, 0x15, 0xCB, 0x14, 0x00, 0x00, + 0xC6, 0xC2, 0xA2, 0x04, 0x38, 0x7D, 0x50, 0x00, 0xF2, 0x03, 0x28, 0x70, 0xCE, 0x16, 0xC6, 0x7E, + 0xC2, 0x19, 0x3F, 0xEE, 0x07, 0x00, 0x06, 0x2E, 0x06, 0x7E, 0xD7, 0x72, 0xD7, 0x21, 0x26, 0x27, + 0x36, 0x2E, 0xD7, 0x21, 0x0C, 0x30, 0x10, 0x27, 0xCB, 0x14, 0x00, 0x00, 0xC4, 0x2A, 0xC2, 0x0A, + 0x98, 0x70, 0xD9, 0x16, 0x82, 0x04, 0xCB, 0xF7, 0x00, 0x00, 0xF2, 0x04, 0x06, 0x2E, 0x8B, 0xBD, + 0x00, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xD7, 0x16, + 0x82, 0x06, 0x08, 0x70, 0x00, 0x80, 0x28, 0x67, 0xB2, 0xDC, 0xF2, 0x05, 0x38, 0x70, 0xB0, 0x16, + 0x28, 0x67, 0x28, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0x28, 0x57, 0x12, 0x03, 0x26, 0x65, 0x28, 0x57, + 0x18, 0x03, 0xC6, 0x65, 0x02, 0x1A, 0x98, 0x67, 0x99, 0x04, 0x92, 0x17, 0x98, 0x67, 0xAA, 0x04, + 0x92, 0x14, 0x38, 0x77, 0x0C, 0x00, 0xDC, 0x70, 0x00, 0xF0, 0x92, 0x0F, 0x38, 0x60, 0xC0, 0x15, + 0x04, 0x21, 0x24, 0x61, 0xB9, 0x60, 0xC0, 0x15, 0x38, 0x50, 0xB0, 0x16, 0x18, 0x55, 0x2A, 0x00, + 0xC6, 0x65, 0xD2, 0x06, 0x06, 0x27, 0xF2, 0x04, 0xB9, 0x00, 0xC0, 0x15, 0x04, 0x20, 0xE1, 0xF0, + 0x34, 0x14, 0xB1, 0xF1, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x07, 0xF0, 0x70, 0xB9, 0x07, 0xF4, 0x70, + 0xC4, 0x21, 0xB9, 0x07, 0xF8, 0x70, 0xB9, 0x07, 0x34, 0x71, 0x08, 0x60, 0x01, 0x00, 0x92, 0x05, + 0x66, 0x63, 0xB9, 0x67, 0xF0, 0x70, 0xF2, 0x15, 0xC4, 0x22, 0x92, 0x05, 0x66, 0x63, 0xB9, 0x67, + 0xF4, 0x70, 0xF2, 0x0F, 0xC4, 0x23, 0x92, 0x05, 0x66, 0x63, 0xB9, 0x67, 0xF8, 0x70, 0xF2, 0x09, + 0x0C, 0x50, 0x80, 0x02, 0x66, 0x56, 0xB9, 0x57, 0xF0, 0x70, 0x66, 0x63, 0xB9, 0x67, 0x34, 0x71, + 0x0C, 0x20, 0x10, 0x00, 0x0C, 0x30, 0x00, 0x50, 0x4B, 0x38, 0x00, 0x00, 0x8B, 0x35, 0x00, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x18, 0xD0, + 0xEA, 0x16, 0x18, 0x60, 0xE9, 0x16, 0xC6, 0x6D, 0x82, 0x37, 0x99, 0xD0, 0xE9, 0x16, 0xC4, 0xD0, + 0x18, 0x70, 0xE6, 0x16, 0x1C, 0x60, 0x10, 0x00, 0x56, 0x76, 0x82, 0x05, 0x64, 0x72, 0x99, 0x70, + 0xE6, 0x16, 0xF2, 0x1E, 0x64, 0x71, 0x99, 0x70, 0xE6, 0x16, 0xCB, 0x48, 0x01, 0x00, 0x8B, 0x47, + 0x01, 0x00, 0xA9, 0x00, 0xD0, 0x16, 0xB9, 0x00, 0xC8, 0x15, 0xB9, 0x00, 0xC0, 0x15, 0x38, 0x70, + 0xB0, 0x16, 0x06, 0x5D, 0x18, 0x27, 0x47, 0x00, 0x18, 0x37, 0x90, 0x00, 0x18, 0x47, 0x8F, 0x00, + 0x18, 0x67, 0x2A, 0x00, 0x0C, 0xF0, 0xE0, 0x00, 0xF1, 0xF0, 0xB9, 0x20, 0xC4, 0x15, 0x98, 0x70, + 0xEA, 0x16, 0x82, 0x06, 0x04, 0x20, 0x0C, 0x30, 0x54, 0x05, 0x8B, 0x02, 0x01, 0x00, 0x18, 0x20, + 0xE6, 0x16, 0x8B, 0xF2, 0x00, 0x00, 0x18, 0x20, 0xE6, 0x16, 0xEB, 0x41, 0x00, 0x00, 0x18, 0x20, + 0xE6, 0x16, 0x6B, 0xEC, 0x00, 0x00, 0x18, 0x20, 0xE6, 0x16, 0xCB, 0x49, 0x00, 0x00, 0x8B, 0x3B, + 0x01, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x24, + 0xB1, 0xF1, 0x8B, 0x32, 0x00, 0x00, 0x04, 0x24, 0x0C, 0x30, 0x00, 0x30, 0x4B, 0x38, 0x00, 0x00, + 0x8B, 0x35, 0x00, 0x00, 0x0C, 0x20, 0x11, 0x00, 0x8B, 0x32, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x28, 0x0C, 0x30, 0x00, 0x40, 0xB1, 0xF1, 0x4B, 0x38, + 0x00, 0x00, 0x8B, 0x35, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x04, 0x62, + 0xB1, 0xF1, 0x99, 0x60, 0xE7, 0x16, 0xCB, 0x2F, 0x00, 0x00, 0xAB, 0x3A, 0x00, 0x00, 0x6B, 0x2E, + 0x00, 0x00, 0x0C, 0x30, 0x00, 0x20, 0x04, 0x21, 0x4B, 0x38, 0x00, 0x00, 0x6B, 0x52, 0x01, 0x00, + 0x8B, 0x35, 0x00, 0x00, 0x2B, 0x36, 0x03, 0x00, 0xEB, 0x0A, 0x01, 0x00, 0x2B, 0x0C, 0x01, 0x00, + 0x0B, 0x21, 0x01, 0x00, 0xEB, 0x8C, 0x02, 0x00, 0x93, 0x22, 0x92, 0x0C, 0x18, 0x70, 0xD6, 0x16, + 0x5C, 0x70, 0xF0, 0x00, 0xCC, 0x70, 0x40, 0x00, 0x82, 0x0D, 0x04, 0x61, 0x99, 0x60, 0xEA, 0x16, + 0xF2, 0x09, 0x8B, 0xCA, 0x02, 0x00, 0x04, 0x20, 0x06, 0x32, 0x0B, 0x8B, 0x00, 0x00, 0x4B, 0x20, + 0x01, 0x00, 0x0B, 0x2F, 0x00, 0x00, 0x6B, 0x30, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x34, 0x18, 0x04, 0x63, 0xC1, 0xE1, 0x99, 0x60, 0xE7, 0x16, 0xCB, 0x2F, 0x00, 0x00, 0x6B, 0xFF, + 0x00, 0x00, 0xC4, 0x20, 0x82, 0x09, 0xAB, 0x3A, 0x00, 0x00, 0x04, 0x20, 0x0C, 0x30, 0x54, 0x05, + 0x8B, 0x02, 0x01, 0x00, 0xF2, 0x03, 0x2B, 0x3B, 0x00, 0x00, 0x6B, 0x2E, 0x00, 0x00, 0x04, 0x21, + 0x0C, 0x30, 0x80, 0x02, 0x8B, 0x02, 0x01, 0x00, 0x0C, 0x30, 0x28, 0x08, 0x04, 0x23, 0x8B, 0x02, + 0x01, 0x00, 0x04, 0x21, 0x8B, 0x37, 0x00, 0x00, 0xEB, 0x52, 0x01, 0x00, 0x06, 0xE2, 0x04, 0x21, + 0x4B, 0x33, 0x00, 0x00, 0x2B, 0x36, 0x03, 0x00, 0x0B, 0x2F, 0x00, 0x00, 0xEB, 0x0A, 0x01, 0x00, + 0x4B, 0xBB, 0x02, 0x00, 0x2B, 0x0C, 0x01, 0x00, 0x06, 0x2E, 0x4B, 0x56, 0x01, 0x00, 0x0B, 0x21, + 0x01, 0x00, 0x2B, 0x28, 0x01, 0x00, 0xEB, 0x32, 0x01, 0x00, 0x6B, 0x30, 0x00, 0x00, 0x98, 0x70, + 0x19, 0x0E, 0x82, 0x0E, 0xB9, 0x00, 0xBC, 0x15, 0x28, 0x60, 0xD0, 0x16, 0xB9, 0x00, 0xC8, 0x15, + 0xCC, 0x60, 0xEF, 0x00, 0xD2, 0x0A, 0x24, 0x61, 0xA9, 0x60, 0xD0, 0x16, 0xF2, 0x06, 0x38, 0x60, + 0xC8, 0x15, 0x24, 0x61, 0xB9, 0x60, 0xC8, 0x15, 0x38, 0x60, 0xC4, 0x15, 0x38, 0x70, 0xC8, 0x15, + 0x24, 0x63, 0xC6, 0x76, 0xA2, 0x05, 0x99, 0x00, 0xEA, 0x16, 0x99, 0x00, 0xE1, 0x16, 0x98, 0x60, + 0xE8, 0x16, 0x82, 0x0B, 0x04, 0x20, 0x99, 0x00, 0xEA, 0x16, 0x99, 0x00, 0xE8, 0x16, 0x0B, 0x6F, + 0x00, 0x00, 0x04, 0x21, 0x4B, 0xF3, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, + 0x98, 0x70, 0xEA, 0x16, 0x34, 0x14, 0xB1, 0xF1, 0x92, 0x04, 0x98, 0x70, 0xE5, 0x16, 0x82, 0x04, + 0x8B, 0x10, 0x01, 0x00, 0xF2, 0x03, 0xEB, 0x0C, 0x01, 0x00, 0x0B, 0x40, 0x01, 0x00, 0x30, 0xF1, + 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x4B, 0xB1, 0x00, 0x00, 0xC4, 0x20, 0x82, 0x03, + 0xEB, 0x61, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x04, 0x20, + 0xB1, 0xF1, 0x4B, 0x6E, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x18, 0x04, 0x20, + 0xC1, 0xE1, 0x4B, 0x70, 0x00, 0x00, 0x06, 0xE2, 0x04, 0x20, 0x0B, 0x6F, 0x00, 0x00, 0x06, 0x2E, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, 0xEB, 0x8F, 0x00, 0x00, + 0xC4, 0x20, 0x82, 0x07, 0x38, 0x20, 0xB4, 0x15, 0x6B, 0x91, 0x00, 0x00, 0xB9, 0x00, 0xB4, 0x15, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0x04, 0x21, 0xC1, 0xE1, 0x4B, 0x6E, + 0x00, 0x00, 0xEB, 0x8F, 0x00, 0x00, 0xC4, 0x20, 0x92, 0x03, 0x2B, 0xB8, 0x00, 0x00, 0x08, 0xE0, + 0x07, 0x00, 0x2C, 0xE0, 0x20, 0xA1, 0xCB, 0x1A, 0x01, 0x00, 0x98, 0x70, 0xDF, 0x16, 0x92, 0x14, + 0x04, 0x21, 0x4B, 0x70, 0x00, 0x00, 0x26, 0x22, 0x06, 0x72, 0x57, 0x71, 0x26, 0x27, 0xC6, 0x2E, + 0xC2, 0xF3, 0x98, 0x70, 0xDE, 0x16, 0x82, 0x08, 0x04, 0x21, 0x0B, 0x6F, 0x00, 0x00, 0x04, 0x21, + 0x4B, 0x6E, 0x00, 0x00, 0xF2, 0xE9, 0x04, 0x21, 0x0B, 0x6F, 0x00, 0x00, 0x04, 0x61, 0x08, 0x70, + 0x00, 0x40, 0xB9, 0x67, 0x14, 0x50, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0xC4, 0x20, 0x34, 0x14, + 0xB1, 0xF1, 0x82, 0x05, 0x04, 0x61, 0x99, 0x60, 0xED, 0x16, 0xF2, 0x03, 0x99, 0x00, 0xED, 0x16, + 0x0C, 0x20, 0x28, 0x16, 0x04, 0x30, 0x0C, 0x40, 0x80, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xED, 0x16, 0x82, 0x08, 0x98, 0x70, + 0xEC, 0x16, 0x82, 0x05, 0xB9, 0x00, 0x20, 0x16, 0xB9, 0x00, 0x1C, 0x16, 0xE1, 0xF0, 0x00, 0x00, + 0x98, 0x70, 0xED, 0x16, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x82, 0x68, 0xB9, 0x00, 0x24, 0x16, + 0xCB, 0x3C, 0x00, 0x00, 0x38, 0x70, 0x24, 0x16, 0x1C, 0x60, 0x80, 0x00, 0x56, 0x76, 0x18, 0x60, + 0xE4, 0x16, 0x5C, 0x20, 0x7F, 0x00, 0x08, 0x50, 0xFD, 0xFF, 0x2C, 0x50, 0xFF, 0xFF, 0x66, 0x72, + 0x54, 0x61, 0xD7, 0x68, 0x56, 0x75, 0x66, 0x76, 0x18, 0x60, 0xEA, 0x16, 0x08, 0x50, 0xFB, 0xFF, + 0x2C, 0x50, 0xFF, 0xFF, 0x54, 0x61, 0x57, 0x69, 0x56, 0x75, 0x66, 0x76, 0xB9, 0x70, 0x24, 0x16, + 0x04, 0xD0, 0x08, 0x70, 0x00, 0x30, 0x08, 0x50, 0x07, 0x00, 0x2C, 0x70, 0x00, 0x49, 0x06, 0x6D, + 0x2C, 0x50, 0xFF, 0xFF, 0x30, 0x47, 0x0C, 0x30, 0xFF, 0x0F, 0x56, 0x34, 0x77, 0x48, 0x5C, 0x40, + 0xFF, 0x0F, 0x36, 0x34, 0x38, 0x40, 0x24, 0x16, 0x23, 0x23, 0x06, 0xF4, 0xF7, 0xF9, 0xC6, 0x3F, + 0x02, 0x08, 0x06, 0x32, 0xD7, 0x39, 0x56, 0x45, 0x66, 0x43, 0xB9, 0x40, 0x24, 0x16, 0x43, 0xD6, + 0x24, 0x61, 0xCC, 0x60, 0x50, 0x01, 0x24, 0x74, 0x92, 0xE6, 0xC4, 0xD0, 0x82, 0x1F, 0x0C, 0x30, + 0x18, 0x00, 0x06, 0x2D, 0x4B, 0x18, 0x00, 0x00, 0x38, 0xE0, 0x24, 0x16, 0x1C, 0x70, 0x81, 0x0F, + 0x5C, 0x20, 0x1F, 0x00, 0x56, 0xE7, 0xD7, 0x23, 0x66, 0xE2, 0x0C, 0x30, 0x18, 0x00, 0x06, 0x2D, + 0xAB, 0x15, 0x00, 0x00, 0x08, 0x70, 0xFE, 0xFF, 0x5C, 0x20, 0x1F, 0x00, 0x2C, 0x70, 0xFF, 0x0F, + 0x57, 0x26, 0x56, 0x7E, 0x66, 0x72, 0xB9, 0x70, 0x24, 0x16, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x08, 0x70, 0x00, 0x80, 0x28, 0x67, 0x28, 0xDC, 0x98, 0x70, 0xED, 0x16, + 0x3C, 0x10, 0x38, 0x00, 0xD9, 0xC1, 0x28, 0x00, 0xD9, 0x81, 0x18, 0x00, 0x8A, 0x99, 0x00, 0x00, + 0xF7, 0x60, 0x08, 0xC0, 0x00, 0x30, 0x08, 0xB0, 0xC0, 0xFF, 0xB1, 0x61, 0x99, 0x00, 0xEB, 0x16, + 0x0C, 0xE0, 0x24, 0x0E, 0x04, 0x80, 0x2C, 0xC0, 0x00, 0x49, 0x2C, 0xB0, 0xFF, 0x07, 0x0C, 0x60, + 0xFC, 0x0A, 0x18, 0x76, 0x98, 0x04, 0xC6, 0x78, 0xCA, 0x83, 0x00, 0x00, 0x98, 0x7E, 0x16, 0x00, + 0x82, 0x04, 0x04, 0x71, 0x26, 0x78, 0x13, 0x87, 0x06, 0x2E, 0xAB, 0x3B, 0x01, 0x00, 0xC4, 0x20, + 0x92, 0x08, 0x2C, 0xE0, 0x1C, 0x00, 0x0C, 0x70, 0x90, 0x0F, 0xC6, 0xE7, 0x92, 0xE9, 0xF2, 0x70, + 0x18, 0x7E, 0x16, 0x00, 0xC4, 0x71, 0x92, 0x09, 0x18, 0x60, 0xEB, 0x16, 0x64, 0x61, 0x99, 0x60, + 0xEB, 0x16, 0x0C, 0x70, 0xF8, 0x15, 0xF2, 0x0A, 0xC4, 0x72, 0x92, 0xEC, 0x18, 0x60, 0xEB, 0x16, + 0x64, 0x62, 0x99, 0x60, 0xEB, 0x16, 0x0C, 0x70, 0xD4, 0x15, 0x18, 0x6E, 0x0D, 0x00, 0x08, 0x90, + 0x3F, 0x00, 0x34, 0x61, 0x2F, 0x56, 0x06, 0x00, 0x26, 0x56, 0x2C, 0x90, 0xFF, 0xFF, 0xD7, 0x51, + 0x04, 0x40, 0xB9, 0x61, 0x0C, 0x00, 0xB9, 0x91, 0x10, 0x00, 0x38, 0x61, 0x0C, 0x00, 0x26, 0x64, + 0xC4, 0x6D, 0xD2, 0x40, 0x18, 0x6E, 0x0C, 0x00, 0x04, 0x30, 0x2F, 0x26, 0x05, 0x00, 0x57, 0x21, + 0x34, 0x24, 0x34, 0x61, 0x26, 0x2C, 0xB9, 0x61, 0x08, 0x00, 0x38, 0x61, 0x08, 0x00, 0x26, 0x63, + 0xCC, 0x60, 0x16, 0x00, 0xD2, 0x2B, 0x30, 0xA1, 0x30, 0xD2, 0x1C, 0x90, 0x00, 0x08, 0x36, 0xDA, + 0x5C, 0xD0, 0xFF, 0x07, 0x23, 0xFD, 0xB9, 0xF1, 0x14, 0x00, 0x30, 0x67, 0x56, 0x69, 0x66, 0x6F, + 0xB1, 0x67, 0x28, 0xF2, 0x02, 0x00, 0x56, 0x6B, 0x36, 0xFA, 0x5C, 0xF0, 0xFF, 0x07, 0x23, 0xAF, + 0x06, 0x9A, 0xD7, 0x95, 0x66, 0x69, 0xB1, 0x67, 0x38, 0x91, 0x14, 0x00, 0x04, 0x60, 0xC6, 0x9A, + 0x02, 0x05, 0x3F, 0x6F, 0x0D, 0x00, 0x5C, 0x60, 0xFF, 0x03, 0x30, 0xF7, 0x38, 0xA1, 0x10, 0x00, + 0x57, 0x6B, 0x56, 0xFA, 0x66, 0xF6, 0xB1, 0xF7, 0x24, 0x74, 0x24, 0x31, 0xC4, 0x33, 0x24, 0x24, + 0x92, 0xCD, 0x24, 0x41, 0xC4, 0x43, 0x2C, 0x50, 0x18, 0x00, 0x92, 0xB8, 0xF2, 0x8B, 0x58, 0xC1, + 0x28, 0x00, 0x58, 0x81, 0x18, 0x00, 0x2C, 0x10, 0x38, 0x00, 0xE1, 0xF0, 0x98, 0x70, 0xED, 0x16, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x82, 0x2F, 0x06, 0xED, 0x0C, 0xE0, 0xD0, 0x15, 0xB9, 0x00, + 0xD0, 0x15, 0x4B, 0x3C, 0x00, 0x00, 0x18, 0x70, 0xEA, 0x16, 0xC4, 0x71, 0x92, 0x24, 0x98, 0x70, + 0x19, 0x0E, 0x82, 0x21, 0x23, 0xC2, 0xCB, 0x3B, 0x00, 0x00, 0xA9, 0x2E, 0x02, 0x00, 0x0C, 0x30, + 0x18, 0x00, 0x06, 0x2C, 0x6B, 0x17, 0x00, 0x00, 0x38, 0xE0, 0xD0, 0x15, 0x1C, 0x70, 0x20, 0x00, + 0x56, 0xE7, 0x5C, 0x20, 0x1F, 0x00, 0x66, 0xE2, 0x0C, 0x30, 0x18, 0x00, 0x06, 0x2C, 0xCB, 0x14, + 0x00, 0x00, 0x5C, 0x20, 0x1F, 0x00, 0x1C, 0x70, 0xE1, 0x03, 0xD7, 0x22, 0x56, 0xE7, 0x66, 0xE2, + 0xB9, 0xE0, 0xD0, 0x15, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x38, 0x60, 0x24, 0x16, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x7E, 0x0C, 0x70, 0x28, 0x16, 0xB9, 0x67, 0x08, 0x00, + 0x38, 0x60, 0x20, 0x16, 0xB9, 0x67, 0x0C, 0x00, 0x38, 0x60, 0x1C, 0x16, 0x06, 0xD7, 0xB9, 0x67, + 0x10, 0x00, 0x38, 0x60, 0xD0, 0x15, 0x0C, 0x20, 0x40, 0x16, 0xB9, 0x67, 0x14, 0x00, 0x18, 0x30, + 0xEB, 0x16, 0x06, 0xC6, 0xD4, 0x31, 0x82, 0x08, 0x0C, 0x30, 0xF8, 0x15, 0x04, 0x49, 0x0C, 0xF0, + 0x5C, 0x01, 0xF1, 0xF0, 0xF2, 0x05, 0x04, 0x49, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x18, 0x30, + 0xEB, 0x16, 0x54, 0x32, 0x93, 0x33, 0x0C, 0x20, 0x64, 0x16, 0x82, 0x08, 0x0C, 0x30, 0xD4, 0x15, + 0x04, 0x49, 0x0C, 0xF0, 0x5C, 0x01, 0xF1, 0xF0, 0xF2, 0x05, 0x04, 0x49, 0x0C, 0xF0, 0xD8, 0x01, + 0xF1, 0xF0, 0x38, 0x70, 0x08, 0x0B, 0xB9, 0x7D, 0x04, 0x00, 0x38, 0x70, 0x28, 0x16, 0x24, 0x71, + 0xB9, 0x70, 0x28, 0x16, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x08, 0x70, 0x00, 0x40, + 0x0C, 0x60, 0xFE, 0x00, 0xB9, 0x67, 0x0C, 0x20, 0xB9, 0x07, 0x18, 0x20, 0xE1, 0xF0, 0x00, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x40, 0xED, 0x0B, 0x38, 0x70, 0xB0, 0x16, 0x06, 0x62, 0x18, 0x57, + 0x8E, 0x00, 0x18, 0x77, 0x8D, 0x00, 0x92, 0x05, 0x18, 0x40, 0xEE, 0x0B, 0x26, 0x74, 0x13, 0x77, + 0x98, 0x40, 0xE4, 0x16, 0x82, 0x0D, 0x08, 0x40, 0x00, 0x80, 0x2C, 0x40, 0x0C, 0xDC, 0x18, 0x34, + 0x7E, 0x00, 0x18, 0x44, 0x7F, 0x00, 0x26, 0x73, 0x26, 0x54, 0x13, 0x77, 0x13, 0x55, 0x18, 0x46, + 0x1A, 0x00, 0xD4, 0x41, 0x82, 0x02, 0x06, 0x57, 0x18, 0x76, 0x18, 0x00, 0xC6, 0x75, 0xB2, 0x06, + 0x18, 0x76, 0x1B, 0x00, 0x04, 0x20, 0xC4, 0x71, 0x92, 0x05, 0x04, 0x71, 0x99, 0x76, 0x1B, 0x00, + 0x04, 0x21, 0xE1, 0xF0, 0x98, 0x60, 0xE4, 0x16, 0x38, 0x70, 0xB0, 0x16, 0x18, 0x77, 0x8E, 0x00, + 0x82, 0x07, 0x08, 0x60, 0x00, 0x80, 0x18, 0x66, 0x8B, 0xDC, 0x26, 0x76, 0x13, 0x77, 0x18, 0x52, + 0x01, 0x00, 0x04, 0x61, 0xC6, 0x57, 0xB2, 0x02, 0x04, 0x60, 0x04, 0x21, 0x56, 0x26, 0xE1, 0xF0, + 0x0C, 0x50, 0xFC, 0x0A, 0x18, 0x60, 0x1A, 0x0E, 0x30, 0x75, 0x16, 0x66, 0x24, 0x71, 0xB1, 0x75, + 0xF7, 0x6F, 0xD7, 0x7A, 0x57, 0x6A, 0x6C, 0x70, 0x75, 0x00, 0x66, 0x76, 0x08, 0x60, 0x00, 0x30, + 0xB9, 0x76, 0x00, 0x01, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, 0x80, 0x02, 0x04, 0x30, + 0x0C, 0x40, 0xD2, 0x02, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x54, 0x05, + 0x04, 0x30, 0x0C, 0x40, 0xD2, 0x02, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x28, 0x08, + 0x04, 0x30, 0x0C, 0x40, 0xD2, 0x02, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x1C, 0xC9, 0xE1, 0x04, 0x00, 0x08, 0xE0, 0x00, 0x80, 0x2C, 0xE0, + 0x0C, 0xDC, 0x28, 0x7E, 0x62, 0x00, 0xA9, 0x70, 0x0C, 0x0B, 0x4B, 0x41, 0x01, 0x00, 0x08, 0x70, + 0x00, 0x80, 0x18, 0x27, 0x08, 0xDC, 0x6B, 0xBB, 0x02, 0x00, 0x4B, 0xBB, 0x01, 0x00, 0x78, 0x2E, + 0x38, 0x00, 0x78, 0x3E, 0x3A, 0x00, 0x0C, 0x70, 0x64, 0x00, 0xB1, 0x71, 0x0C, 0x60, 0x69, 0x00, + 0x0C, 0x40, 0x41, 0x00, 0x0C, 0x50, 0x3C, 0x00, 0x8B, 0xCD, 0x02, 0x00, 0x8B, 0xC1, 0x01, 0x00, + 0x2B, 0x39, 0x03, 0x00, 0xEB, 0xB7, 0x01, 0x00, 0x0B, 0xB8, 0x01, 0x00, 0x38, 0x70, 0xB0, 0x16, + 0x04, 0x61, 0x30, 0x77, 0xD6, 0x67, 0x82, 0x04, 0x0C, 0x50, 0x28, 0x08, 0xF2, 0x03, 0x0C, 0x50, + 0x80, 0x02, 0xD4, 0x72, 0xB9, 0x50, 0xC0, 0x16, 0x82, 0x04, 0x0C, 0x60, 0x28, 0x08, 0xF2, 0x03, + 0x0C, 0x60, 0x80, 0x02, 0x48, 0xE1, 0x04, 0x00, 0xB9, 0x60, 0xBC, 0x16, 0x24, 0x1C, 0xE1, 0xF0, + 0x34, 0x14, 0xB1, 0xF1, 0xAB, 0x0F, 0x03, 0x00, 0x6B, 0x99, 0x02, 0x00, 0xCB, 0x57, 0x01, 0x00, + 0x8B, 0xBE, 0x02, 0x00, 0x4B, 0x59, 0x01, 0x00, 0x30, 0xF1, 0x99, 0x00, 0xD8, 0x0B, 0xA9, 0x00, + 0xAC, 0x15, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x8B, 0xF4, 0x02, 0x00, + 0x30, 0xF1, 0x99, 0x00, 0xDA, 0x0B, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x6B, 0x37, 0x02, 0x00, 0x2B, 0xB8, 0x01, 0x00, 0x6B, 0xF2, 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x50, 0x19, 0x0E, 0x34, 0x14, 0xB1, 0xF1, 0x92, 0x08, 0x98, 0x70, + 0x94, 0x0F, 0x92, 0x05, 0xB8, 0x70, 0xC8, 0x15, 0x82, 0x0D, 0xF2, 0x14, 0x18, 0x70, 0x96, 0x0F, + 0xCC, 0x70, 0xC7, 0x00, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x70, 0x96, 0x0F, 0xC4, 0x50, 0x92, 0x10, + 0xF2, 0xF2, 0x98, 0x70, 0x94, 0x0F, 0x92, 0x03, 0x0B, 0x59, 0x01, 0x00, 0xCB, 0xCC, 0x02, 0x00, + 0xF2, 0x07, 0xC4, 0x74, 0x92, 0x05, 0x4B, 0x59, 0x01, 0x00, 0x8B, 0xBE, 0x02, 0x00, 0x18, 0x70, + 0xDA, 0x0B, 0xCC, 0x70, 0xF9, 0x00, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x70, 0xDA, 0x0B, 0x38, 0x50, + 0x34, 0x15, 0x06, 0x75, 0x18, 0x40, 0x97, 0x0F, 0x77, 0x76, 0x54, 0x7F, 0xC6, 0x47, 0x32, 0x04, + 0x99, 0x70, 0x97, 0x0F, 0xF2, 0x0A, 0x06, 0x75, 0xDC, 0x70, 0x00, 0xF0, 0x92, 0x06, 0x98, 0x70, + 0x94, 0x0F, 0x92, 0x03, 0x99, 0x00, 0x97, 0x0F, 0x98, 0x70, 0xA8, 0x15, 0x82, 0x0A, 0x18, 0x70, + 0xD8, 0x0B, 0xCC, 0x70, 0xFF, 0x00, 0x82, 0x07, 0x24, 0x71, 0x99, 0x70, 0xD8, 0x0B, 0xF2, 0x03, + 0x99, 0x00, 0xD8, 0x0B, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x18, 0x70, 0xE8, 0x16, + 0x34, 0x14, 0xC4, 0x70, 0xB1, 0xF1, 0x04, 0x21, 0x82, 0x15, 0x38, 0x70, 0x08, 0x0B, 0x1C, 0x60, + 0x01, 0xF0, 0x56, 0x76, 0xB9, 0x70, 0x08, 0x0B, 0xCB, 0x57, 0x01, 0x00, 0x6B, 0x49, 0x01, 0x00, + 0xEB, 0xF5, 0x02, 0x00, 0x6B, 0xF8, 0x02, 0x00, 0x99, 0x00, 0x52, 0x0C, 0x99, 0x00, 0x1A, 0x0E, + 0x04, 0x20, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, 0x6B, 0x0A, 0x03, 0x00, + 0xC4, 0x21, 0x92, 0x09, 0x6B, 0xF8, 0x02, 0x00, 0x6B, 0xDB, 0x01, 0x00, 0x6B, 0x3D, 0x03, 0x00, + 0x8B, 0x0F, 0x03, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0xB1, 0xF1, + 0x6B, 0x8A, 0x02, 0x00, 0x30, 0xF1, 0x04, 0x20, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x6B, 0x49, 0x01, 0x00, 0x0B, 0xBF, 0x02, 0x00, 0x4B, 0x46, 0x02, 0x00, 0x6B, 0xB5, 0x02, 0x00, + 0xEB, 0x14, 0x03, 0x00, 0xC4, 0x20, 0x92, 0x03, 0x6B, 0x10, 0x03, 0x00, 0x6B, 0x4F, 0x01, 0x00, + 0xC4, 0x21, 0x92, 0x1F, 0x98, 0x70, 0xDB, 0x0B, 0x82, 0x04, 0x98, 0x70, 0xDC, 0x0B, 0x92, 0x10, + 0x8B, 0xB7, 0x02, 0x00, 0x18, 0x70, 0xE5, 0x16, 0xC4, 0x71, 0x92, 0x04, 0x2B, 0x46, 0x02, 0x00, + 0xF2, 0x05, 0x4B, 0x84, 0x02, 0x00, 0xAB, 0xF2, 0x01, 0x00, 0x4B, 0xB8, 0x01, 0x00, 0xEB, 0xB6, + 0x01, 0x00, 0xC4, 0x21, 0x92, 0x06, 0x98, 0x70, 0xDC, 0x0B, 0x92, 0x03, 0x4B, 0x51, 0x01, 0x00, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x34, 0x14, 0xB1, 0xF1, 0x82, 0x10, + 0xEB, 0x34, 0x03, 0x00, 0x18, 0x70, 0xDC, 0x0B, 0xC4, 0x71, 0x92, 0x0A, 0x38, 0x70, 0x08, 0x0B, + 0x1C, 0x60, 0x01, 0x03, 0x56, 0x76, 0xB9, 0x70, 0x08, 0x0B, 0x4B, 0x51, 0x01, 0x00, 0x2B, 0x4A, + 0x01, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0x24, 0x0E, 0x04, 0x30, + 0x0C, 0x40, 0x74, 0x01, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x98, 0x0F, + 0x04, 0x30, 0x04, 0x4F, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x99, 0x00, 0x96, 0x0F, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x20, 0xE4, 0x0B, 0x04, 0x30, + 0x04, 0x4C, 0xB1, 0xF1, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0x04, 0x70, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x06, 0x2F, 0x67, 0x03, 0x00, 0x24, 0x7C, 0xCC, 0x70, + 0x9C, 0x00, 0x91, 0x06, 0x92, 0xF7, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x04, 0x71, 0x99, 0x32, + 0x01, 0x00, 0x91, 0x72, 0x20, 0x75, 0x06, 0xE2, 0xA9, 0x72, 0x02, 0x00, 0x28, 0x75, 0x02, 0x00, + 0x06, 0x34, 0xA9, 0x72, 0x04, 0x00, 0x06, 0x24, 0x6B, 0x13, 0x00, 0x00, 0xB9, 0x2E, 0x08, 0x00, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0xB9, 0x20, 0xC4, 0x16, 0x99, 0x30, 0xEF, 0x16, + 0x99, 0x40, 0xEE, 0x16, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x34, 0x00, 0xD9, 0x81, 0x14, 0x00, + 0xD9, 0xC1, 0x24, 0x00, 0x06, 0xB2, 0xB1, 0x31, 0xB9, 0x41, 0x04, 0x00, 0x04, 0x70, 0x2F, 0x67, + 0x0B, 0x00, 0x24, 0x78, 0xCC, 0x70, 0x48, 0x05, 0xB1, 0x06, 0x92, 0xFA, 0x30, 0xE1, 0x04, 0xD0, + 0x06, 0x9D, 0x06, 0xAD, 0x90, 0x7E, 0x92, 0x07, 0x04, 0xE0, 0x06, 0xCE, 0x06, 0x9E, 0x06, 0x8E, + 0xFA, 0x98, 0x00, 0x00, 0x30, 0x61, 0xB8, 0x76, 0x08, 0x00, 0x82, 0x05, 0x38, 0x7E, 0x08, 0x00, + 0xB9, 0x70, 0xC4, 0x16, 0x38, 0xC1, 0x04, 0x00, 0x04, 0x80, 0x90, 0x7C, 0x82, 0x63, 0x98, 0x70, + 0xEF, 0x16, 0x92, 0x03, 0xC6, 0x98, 0x82, 0x59, 0x78, 0x7C, 0x02, 0x00, 0x78, 0x2E, 0x02, 0x00, + 0x78, 0x6E, 0x04, 0x00, 0x36, 0x27, 0x78, 0x7C, 0x04, 0x00, 0xB9, 0x51, 0x10, 0x00, 0x06, 0x32, + 0x3F, 0x77, 0x06, 0x00, 0xB9, 0x71, 0x08, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x71, 0x08, 0x00, + 0x06, 0x62, 0x06, 0x37, 0x06, 0x27, 0xB9, 0x61, 0x0C, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x51, + 0x10, 0x00, 0x38, 0x61, 0x0C, 0x00, 0x38, 0x70, 0xC4, 0x16, 0x26, 0x62, 0xC6, 0x76, 0xA2, 0x35, + 0x06, 0x7B, 0x04, 0x40, 0xC6, 0x4D, 0x04, 0x21, 0x26, 0x24, 0x82, 0x07, 0x24, 0x78, 0x14, 0x38, + 0x26, 0x37, 0x30, 0x33, 0xC6, 0x36, 0xC2, 0x27, 0xD7, 0x21, 0x14, 0x78, 0x26, 0x72, 0x26, 0x7B, + 0x3F, 0x44, 0x0D, 0x00, 0x06, 0x37, 0x26, 0x2B, 0xD7, 0x41, 0xB9, 0x51, 0x10, 0x00, 0xB9, 0x61, + 0x0C, 0x00, 0xB9, 0x71, 0x08, 0x00, 0x0C, 0xF0, 0x00, 0x01, 0xF1, 0xF0, 0x38, 0x61, 0x0C, 0x00, + 0x38, 0x71, 0x08, 0x00, 0x24, 0xD1, 0xB1, 0x67, 0x18, 0x6E, 0x01, 0x00, 0x24, 0xA1, 0x99, 0x67, + 0x04, 0x00, 0x18, 0x6C, 0x01, 0x00, 0x13, 0xDD, 0x99, 0x67, 0x05, 0x00, 0x13, 0xAA, 0x38, 0x51, + 0x10, 0x00, 0xF2, 0x03, 0x13, 0x42, 0xF2, 0xCF, 0x24, 0x81, 0x13, 0x88, 0xC4, 0x8D, 0x24, 0xCC, + 0x92, 0x9D, 0x24, 0x91, 0x13, 0x99, 0xC4, 0x9D, 0x24, 0xEC, 0x92, 0x85, 0xF2, 0x86, 0x06, 0x39, + 0xD7, 0x31, 0x2F, 0x23, 0x0B, 0x00, 0x18, 0x42, 0x04, 0x00, 0x04, 0x71, 0x06, 0xF7, 0x53, 0xF4, + 0x06, 0x4F, 0x06, 0xFC, 0xD6, 0xF4, 0x82, 0x18, 0x34, 0xA1, 0x3F, 0x49, 0x0A, 0x00, 0x24, 0x38, + 0x26, 0x3B, 0xD7, 0x41, 0xB9, 0x51, 0x10, 0x00, 0xB9, 0x61, 0x0C, 0x00, 0x0C, 0xF0, 0x28, 0x01, + 0xF1, 0xF0, 0x38, 0x51, 0x10, 0x00, 0x38, 0x61, 0x0C, 0x00, 0x13, 0xAA, 0x24, 0x81, 0x13, 0x88, + 0xC6, 0x8D, 0x92, 0xDE, 0xF2, 0x14, 0x18, 0xF2, 0x05, 0x00, 0x53, 0x7F, 0x06, 0xFE, 0xD6, 0xF7, + 0x92, 0xE4, 0x98, 0x30, 0xEE, 0x16, 0x92, 0x02, 0x66, 0xC4, 0x98, 0x30, 0xEF, 0x16, 0x66, 0xE7, + 0x92, 0x03, 0x66, 0x74, 0x66, 0xC7, 0x24, 0x91, 0x13, 0x99, 0xF2, 0xE9, 0x58, 0xC1, 0x24, 0x00, + 0x06, 0x2A, 0x58, 0x81, 0x14, 0x00, 0x2C, 0x10, 0x34, 0x00, 0xE1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, + 0x18, 0x47, 0x98, 0x04, 0x3C, 0x10, 0x10, 0x00, 0xC4, 0x49, 0xD1, 0xC1, 0x04, 0x60, 0xD2, 0x63, + 0x0C, 0x50, 0x3A, 0x0E, 0x90, 0x35, 0x82, 0x07, 0x24, 0x61, 0x13, 0x66, 0xC4, 0x6D, 0x2C, 0x50, + 0x1C, 0x00, 0x92, 0xF9, 0x06, 0x56, 0x06, 0xF6, 0x24, 0x41, 0x57, 0x51, 0xD7, 0xF2, 0xD7, 0x22, + 0x2F, 0xD2, 0x07, 0x00, 0x99, 0x47, 0x98, 0x04, 0x04, 0x31, 0x3F, 0x45, 0x0F, 0x00, 0x26, 0x47, + 0x38, 0xCD, 0x70, 0x01, 0x28, 0xDD, 0x78, 0x01, 0x26, 0x36, 0x0C, 0xE0, 0x14, 0x00, 0x26, 0xE4, + 0x13, 0x33, 0x99, 0x3E, 0x2A, 0x03, 0xB9, 0xC4, 0x28, 0x03, 0xB9, 0xC4, 0x30, 0x03, 0x99, 0xDE, + 0x2B, 0x03, 0x98, 0xE7, 0x99, 0x04, 0x2C, 0x40, 0x18, 0x00, 0x92, 0x0C, 0x04, 0xE2, 0x99, 0xE4, + 0x2A, 0x03, 0x38, 0x47, 0x0C, 0x00, 0x08, 0xE0, 0x00, 0x01, 0x66, 0x4E, 0xB9, 0x47, 0x0C, 0x00, + 0xF2, 0x04, 0x04, 0xE1, 0x99, 0xE4, 0x2A, 0x03, 0x3F, 0x55, 0x0F, 0x00, 0x26, 0x57, 0x0C, 0x40, + 0x18, 0x00, 0x26, 0x27, 0x26, 0x45, 0x28, 0x22, 0x5E, 0x01, 0x99, 0x04, 0x2B, 0x03, 0x04, 0xF1, + 0x99, 0xF4, 0x28, 0x03, 0x99, 0x04, 0x29, 0x03, 0x04, 0x4C, 0x26, 0x45, 0xA9, 0x24, 0x28, 0x03, + 0x0C, 0x20, 0x2C, 0x01, 0xA9, 0x25, 0x3C, 0x03, 0xA9, 0x04, 0x2A, 0x03, 0xA9, 0x05, 0x38, 0x03, + 0xA9, 0x05, 0x3A, 0x03, 0x04, 0x51, 0x53, 0x56, 0x38, 0x67, 0x94, 0x04, 0x66, 0x56, 0xB9, 0x57, + 0x94, 0x04, 0x06, 0x63, 0x50, 0xC1, 0x06, 0x26, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x04, 0x60, 0x06, 0x52, 0x63, 0x56, 0xD4, 0x51, 0x13, 0x76, 0x92, 0x05, 0x24, 0x61, 0xC4, 0x64, + 0x92, 0xF9, 0x06, 0x76, 0x0C, 0x60, 0xFC, 0x0A, 0x18, 0x56, 0xA9, 0x04, 0x04, 0x41, 0x24, 0x51, + 0x99, 0x56, 0xA9, 0x04, 0x2F, 0x57, 0x07, 0x00, 0x26, 0x57, 0x26, 0x56, 0x26, 0x47, 0x99, 0x45, + 0x9C, 0x04, 0x04, 0x41, 0x99, 0x45, 0x9D, 0x04, 0x99, 0x05, 0x9E, 0x04, 0x04, 0x51, 0x53, 0x57, + 0x18, 0x76, 0xA8, 0x04, 0x66, 0x57, 0x99, 0x56, 0xA8, 0x04, 0xE1, 0xF0, 0x38, 0x70, 0xB0, 0x16, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x18, 0xF7, 0x8F, 0x00, 0x0C, 0x70, + 0xFC, 0x0A, 0x18, 0xA7, 0x24, 0x03, 0x18, 0x37, 0xAA, 0x04, 0xC4, 0xA0, 0x06, 0xE7, 0x92, 0x12, + 0xC4, 0x30, 0x92, 0x10, 0x18, 0x67, 0x99, 0x04, 0x06, 0x23, 0xC4, 0x60, 0x9A, 0x94, 0x00, 0x00, + 0xF8, 0x67, 0xB0, 0x0A, 0x0A, 0x90, 0x00, 0x00, 0x34, 0x61, 0xA9, 0x67, 0xB0, 0x0A, 0xFA, 0x8B, + 0x00, 0x00, 0xC4, 0x30, 0x99, 0x0E, 0xA9, 0x04, 0x06, 0x2E, 0x82, 0x0B, 0x04, 0xC0, 0x04, 0xDC, + 0x26, 0xDE, 0x06, 0x7E, 0x06, 0x5C, 0x06, 0x4C, 0x04, 0xB1, 0x1C, 0x90, 0x10, 0x00, 0xF2, 0x12, + 0x0C, 0x20, 0x98, 0x0F, 0x04, 0x4C, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x2E, 0x23, 0x03, + 0x0B, 0x71, 0x01, 0x00, 0xF2, 0x68, 0x98, 0x87, 0x9C, 0x04, 0x92, 0x07, 0x24, 0x73, 0xC6, 0x7D, + 0x82, 0x21, 0xC6, 0x43, 0xA2, 0xF9, 0xF2, 0x1E, 0x18, 0x6E, 0x23, 0x03, 0x34, 0x81, 0x63, 0x68, + 0xD4, 0x61, 0x82, 0x15, 0x98, 0x67, 0x9E, 0x04, 0x82, 0x06, 0x99, 0x07, 0x9E, 0x04, 0x99, 0x97, + 0x9D, 0x04, 0xF2, 0x09, 0x18, 0x67, 0x9D, 0x04, 0xCC, 0x60, 0xEF, 0x00, 0xD2, 0x04, 0x24, 0x61, + 0x99, 0x67, 0x9D, 0x04, 0x06, 0x6B, 0x53, 0x68, 0x66, 0x56, 0x66, 0xC6, 0x24, 0x41, 0x13, 0x44, + 0xF2, 0xDE, 0x04, 0x60, 0x99, 0x3E, 0xA9, 0x04, 0x06, 0x72, 0x06, 0x46, 0x04, 0xD1, 0xC6, 0x63, + 0xB2, 0x22, 0x98, 0x27, 0x9C, 0x04, 0x82, 0x1B, 0x06, 0x2D, 0x53, 0x24, 0xD6, 0x25, 0x92, 0x15, + 0x18, 0x27, 0x9E, 0x04, 0xC6, 0x2F, 0xB2, 0x05, 0x24, 0x21, 0x99, 0x27, 0x9E, 0x04, 0xF2, 0x0D, + 0x98, 0x2E, 0xA9, 0x04, 0x82, 0x04, 0x34, 0x21, 0x99, 0x2E, 0xA9, 0x04, 0x99, 0x07, 0x9C, 0x04, + 0x99, 0x07, 0x9D, 0x04, 0x99, 0x07, 0x9E, 0x04, 0x24, 0x61, 0x13, 0x66, 0x24, 0x41, 0xC4, 0x44, + 0x24, 0x73, 0x92, 0xDE, 0x04, 0xB0, 0x06, 0xDB, 0x04, 0x91, 0xC6, 0xBA, 0xB2, 0x14, 0x18, 0x7E, + 0x23, 0x03, 0x63, 0x7D, 0xD4, 0x71, 0x82, 0x0C, 0x06, 0x7C, 0x73, 0x7D, 0xD4, 0x71, 0x92, 0x06, + 0x06, 0x29, 0x53, 0x2D, 0x13, 0x22, 0x0B, 0x71, 0x01, 0x00, 0x24, 0xB1, 0x13, 0xBB, 0x24, 0xD1, + 0xC4, 0xD4, 0x92, 0xEC, 0x78, 0x7E, 0xB0, 0x0A, 0x04, 0x21, 0xC4, 0x70, 0x02, 0x04, 0x26, 0x72, + 0xA9, 0x7E, 0xB0, 0x0A, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x06, 0xE2, 0x78, 0x7E, 0x04, 0x00, + 0x70, 0x22, 0x36, 0x27, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x78, 0xDE, 0x02, 0x00, 0x78, 0x7E, + 0x06, 0x00, 0x36, 0xD7, 0xC4, 0xD0, 0x32, 0x02, 0x16, 0xDD, 0x06, 0x32, 0x6B, 0x13, 0x00, 0x00, + 0x06, 0x3D, 0x06, 0xC2, 0x06, 0x2D, 0x6B, 0x13, 0x00, 0x00, 0x26, 0x2C, 0x0C, 0x30, 0x00, 0x01, + 0x0C, 0xF0, 0xE8, 0x01, 0xF1, 0xF0, 0x86, 0xD2, 0x8A, 0xB9, 0x00, 0x00, 0x38, 0x60, 0x08, 0x0B, + 0x08, 0x70, 0x02, 0x00, 0x2C, 0x70, 0x00, 0x03, 0xD6, 0x67, 0x82, 0x05, 0x0C, 0x70, 0x2C, 0x01, + 0xFA, 0xAB, 0x00, 0x00, 0x98, 0x3E, 0x19, 0x00, 0x82, 0x0D, 0x28, 0x7E, 0x12, 0x00, 0xC4, 0x7A, + 0xCA, 0xA5, 0x00, 0x00, 0x28, 0x2E, 0x14, 0x00, 0x24, 0x31, 0x6B, 0x13, 0x00, 0x00, 0xFA, 0x99, + 0x00, 0x00, 0x78, 0x2E, 0x10, 0x00, 0x04, 0x31, 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0xA8, 0x9E, + 0x0E, 0x00, 0x06, 0xC2, 0x2F, 0xBD, 0x0D, 0x00, 0x92, 0x04, 0xA9, 0xDE, 0x0E, 0x00, 0xF2, 0x14, + 0x2F, 0x7D, 0x0B, 0x00, 0x06, 0x67, 0x57, 0x62, 0x3F, 0x27, 0x06, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0x26, 0x22, 0xCB, 0x14, 0x00, 0x00, 0x06, 0xA2, 0x04, 0x3A, 0x06, 0x29, 0xAB, 0x15, 0x00, 0x00, + 0x26, 0x2A, 0xA9, 0x2E, 0x0E, 0x00, 0xA8, 0x7E, 0x0E, 0x00, 0x92, 0x04, 0x04, 0x71, 0xA9, 0x7E, + 0x0E, 0x00, 0x06, 0x2D, 0xD7, 0x21, 0x0C, 0x30, 0x64, 0x00, 0x26, 0x2B, 0xCB, 0x14, 0x00, 0x00, + 0x28, 0x7E, 0x12, 0x00, 0x06, 0xA2, 0x2F, 0x67, 0x07, 0x00, 0x26, 0x76, 0x06, 0x67, 0x57, 0x62, + 0x3F, 0x27, 0x06, 0x00, 0x26, 0x22, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x26, 0x2A, + 0xA3, 0x22, 0x82, 0x04, 0xA9, 0x2E, 0x12, 0x00, 0xF2, 0x04, 0x04, 0x71, 0xA9, 0x7E, 0x12, 0x00, + 0x26, 0xBD, 0xD7, 0xB1, 0x2F, 0x2D, 0x0B, 0x00, 0x26, 0x22, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, + 0x00, 0x00, 0x28, 0x7E, 0x10, 0x00, 0xE7, 0x70, 0x26, 0x27, 0xA3, 0x72, 0x92, 0x02, 0x04, 0x71, + 0xA9, 0x7E, 0x10, 0x00, 0x28, 0xDE, 0x10, 0x00, 0xC6, 0xDC, 0xA2, 0x0B, 0x2F, 0x7D, 0x0D, 0x00, + 0x26, 0x7D, 0x06, 0x67, 0xD7, 0x62, 0x2F, 0x26, 0x07, 0x00, 0x26, 0x2D, 0x06, 0x3C, 0xF2, 0x0A, + 0x2F, 0x7C, 0x0C, 0x00, 0x26, 0x7C, 0x06, 0x67, 0xD7, 0x62, 0x2F, 0x26, 0x07, 0x00, 0x26, 0x2C, + 0x06, 0x3D, 0xCB, 0x14, 0x00, 0x00, 0x06, 0x3D, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0xCB, 0x14, 0x00, 0x00, 0x28, 0xCE, 0x12, 0x00, 0x28, 0x7E, 0x0E, 0x00, 0x26, 0xCD, 0x26, 0xC7, + 0x26, 0xC2, 0x06, 0x3D, 0x06, 0x2D, 0x6B, 0x13, 0x00, 0x00, 0x06, 0x3C, 0x6B, 0x13, 0x00, 0x00, + 0x08, 0x30, 0x01, 0x00, 0x2C, 0x30, 0x90, 0x5F, 0xCB, 0x14, 0x00, 0x00, 0x2F, 0xBC, 0x0D, 0x00, + 0x3F, 0x22, 0x0B, 0x00, 0x23, 0x22, 0xCC, 0x20, 0x3B, 0x00, 0x0C, 0x70, 0x3C, 0x00, 0xC2, 0x04, + 0xA9, 0x2E, 0x14, 0x00, 0xF2, 0x03, 0xA9, 0x7E, 0x14, 0x00, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, + 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE2, + 0x04, 0x24, 0x06, 0xD3, 0x04, 0x44, 0x06, 0x3E, 0x26, 0x2E, 0x0C, 0xC0, 0x14, 0x00, 0xEB, 0x73, + 0x03, 0x00, 0x26, 0xCD, 0x06, 0x3C, 0x04, 0x44, 0x06, 0x2E, 0xEB, 0x73, 0x03, 0x00, 0x04, 0x28, + 0x26, 0x2E, 0x06, 0x3C, 0x04, 0x44, 0xEB, 0x73, 0x03, 0x00, 0x28, 0x7D, 0x02, 0x00, 0xA9, 0x7E, + 0x0C, 0x00, 0x28, 0x7D, 0x1C, 0x00, 0x99, 0x7E, 0x17, 0x00, 0x98, 0x7E, 0x19, 0x00, 0x82, 0x09, + 0x18, 0x7E, 0x18, 0x00, 0x99, 0x0E, 0x19, 0x00, 0x24, 0x71, 0x99, 0x7E, 0x18, 0x00, 0xF2, 0x22, + 0x18, 0x6E, 0x18, 0x00, 0xCC, 0x60, 0xEF, 0x00, 0xD2, 0x1D, 0x18, 0x50, 0x95, 0x0F, 0xC4, 0x52, + 0x38, 0x70, 0xB0, 0x16, 0xC2, 0x04, 0x28, 0x77, 0x30, 0x00, 0xF2, 0x08, 0xC4, 0x52, 0x92, 0x04, + 0x28, 0x77, 0x2E, 0x00, 0xF2, 0x03, 0x28, 0x77, 0x2C, 0x00, 0x20, 0x5D, 0x26, 0x55, 0x0C, 0x40, + 0x28, 0x08, 0x26, 0x54, 0x70, 0x55, 0xF7, 0x70, 0xC6, 0x57, 0x02, 0x04, 0x24, 0x61, 0x99, 0x6E, + 0x18, 0x00, 0x06, 0x2E, 0x8B, 0x7E, 0x01, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0xB8, 0x06, 0xD9, 0xC1, 0xA8, 0x06, 0x38, 0x70, 0xB0, 0x16, 0xD9, 0x81, 0x98, 0x06, + 0x0C, 0xE0, 0xFC, 0x0A, 0x0C, 0x50, 0x8F, 0x00, 0x18, 0xCE, 0x99, 0x04, 0x26, 0x57, 0x10, 0x55, + 0xC4, 0xC2, 0xB9, 0x51, 0x80, 0x06, 0x92, 0x2C, 0x78, 0x5E, 0xE8, 0x00, 0x78, 0x6E, 0xEC, 0x00, + 0x3F, 0x66, 0x05, 0x00, 0xC4, 0x60, 0x32, 0x02, 0x16, 0x66, 0x99, 0x0E, 0xF2, 0x00, 0x28, 0x47, + 0x92, 0x00, 0x78, 0x5E, 0xEE, 0x00, 0x43, 0x36, 0xC6, 0x34, 0x78, 0x6E, 0xEA, 0x00, 0x32, 0x18, + 0x36, 0x65, 0xC4, 0x60, 0x32, 0x02, 0x16, 0x66, 0x28, 0x57, 0x94, 0x00, 0x43, 0x66, 0xC6, 0x65, + 0x32, 0x04, 0x18, 0x67, 0x99, 0x00, 0xF2, 0x0A, 0x28, 0x57, 0x96, 0x00, 0xC6, 0x65, 0x32, 0x04, + 0x18, 0x67, 0x9A, 0x00, 0xF2, 0x03, 0x18, 0x67, 0x9B, 0x00, 0x99, 0x6E, 0xF2, 0x00, 0x18, 0x6E, + 0x9A, 0x04, 0x18, 0x77, 0x98, 0x00, 0xC6, 0x67, 0xB2, 0x07, 0x98, 0x7E, 0xF0, 0x00, 0x82, 0x04, + 0x04, 0x71, 0x99, 0x7E, 0xF1, 0x00, 0x98, 0x70, 0xE4, 0x16, 0x82, 0x0B, 0x08, 0x70, 0x00, 0x80, + 0x38, 0x61, 0x80, 0x06, 0x18, 0x77, 0x8C, 0xDC, 0x26, 0x76, 0x13, 0x77, 0xB9, 0x71, 0x80, 0x06, + 0x38, 0x7E, 0x0C, 0x00, 0xDC, 0x70, 0x00, 0xF0, 0x82, 0x06, 0xCB, 0x57, 0x01, 0x00, 0x04, 0xC0, + 0xFA, 0xE5, 0x01, 0x00, 0x98, 0xAE, 0x1F, 0x03, 0x92, 0x0C, 0xC4, 0xC0, 0x92, 0x0A, 0xF8, 0x7E, + 0xB0, 0x0A, 0x0A, 0xDC, 0x01, 0x00, 0x34, 0x71, 0xA9, 0x7E, 0xB0, 0x0A, 0xFA, 0xD7, 0x01, 0x00, + 0xC4, 0xC0, 0x99, 0x0E, 0x98, 0x04, 0x92, 0x10, 0x0C, 0x20, 0x24, 0x0E, 0x06, 0x3C, 0x0C, 0x40, + 0x6C, 0x01, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0xC6, 0xCA, 0x32, 0x4D, 0x13, 0x2C, 0xEB, 0x69, + 0x01, 0x00, 0x24, 0xC1, 0xF2, 0xFA, 0x04, 0xD0, 0x06, 0xBD, 0x06, 0x9D, 0x04, 0x82, 0xC6, 0xA9, + 0xC2, 0x17, 0xC4, 0xA1, 0x34, 0x81, 0x13, 0x88, 0x9A, 0x9F, 0x00, 0x00, 0xC4, 0xC1, 0x9A, 0x9C, + 0x00, 0x00, 0x18, 0x7E, 0xDF, 0x00, 0xC4, 0x71, 0x92, 0x48, 0x18, 0x7E, 0xE0, 0x00, 0xC4, 0x71, + 0x92, 0x44, 0x38, 0xBE, 0x94, 0x04, 0x06, 0xDA, 0x06, 0x9A, 0xC4, 0x80, 0x92, 0xE9, 0x04, 0x90, + 0x99, 0xCE, 0x98, 0x04, 0x06, 0x89, 0x04, 0x61, 0xC6, 0x8A, 0x32, 0x10, 0x06, 0x7D, 0x73, 0x78, + 0xD4, 0x71, 0x9A, 0x53, 0x01, 0x00, 0x13, 0x28, 0xB9, 0x61, 0x94, 0x06, 0xEB, 0x69, 0x01, 0x00, + 0x86, 0x22, 0x38, 0x61, 0x94, 0x06, 0x9A, 0x43, 0x01, 0x00, 0x04, 0x80, 0x08, 0x70, 0xFF, 0xFE, + 0x0C, 0xD0, 0x24, 0x0E, 0x06, 0xA8, 0x2C, 0x70, 0xFF, 0xFF, 0x2F, 0x69, 0x0C, 0x00, 0xC6, 0x86, + 0x32, 0x0A, 0x98, 0x6D, 0x16, 0x00, 0x9A, 0x3C, 0x01, 0x00, 0x24, 0xA1, 0xC4, 0xAD, 0x2C, 0xD0, + 0x1C, 0x00, 0x92, 0xF4, 0x98, 0x7E, 0x98, 0x04, 0x92, 0x08, 0x0C, 0x70, 0x14, 0x00, 0xA9, 0x7E, + 0xB0, 0x0A, 0x04, 0xC1, 0xFA, 0x73, 0x01, 0x00, 0x04, 0xC1, 0xC6, 0x7C, 0xCA, 0x6F, 0x01, 0x00, + 0x6B, 0x10, 0x03, 0x00, 0xFA, 0x6B, 0x01, 0x00, 0x38, 0x2E, 0x94, 0x04, 0x0C, 0xF0, 0x80, 0x00, + 0xF1, 0xF0, 0x06, 0x72, 0x57, 0x71, 0xD7, 0x22, 0x36, 0x27, 0x26, 0x2E, 0x78, 0x52, 0x30, 0x03, + 0x78, 0x7E, 0x70, 0x01, 0x0C, 0x60, 0x28, 0x03, 0x3F, 0x77, 0x05, 0x00, 0xC4, 0x70, 0x26, 0x62, + 0x32, 0x02, 0x16, 0x77, 0x78, 0x22, 0x32, 0x03, 0x78, 0x5E, 0x72, 0x01, 0x36, 0x25, 0xC4, 0x20, + 0x32, 0x02, 0x16, 0x22, 0x28, 0x56, 0x14, 0x00, 0xB9, 0x61, 0x94, 0x06, 0x06, 0x32, 0xB9, 0x51, + 0x8C, 0x06, 0xB9, 0x71, 0x90, 0x06, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x71, 0x90, 0x06, 0x06, 0x42, + 0x06, 0x37, 0x06, 0x27, 0xB9, 0x41, 0x88, 0x06, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x51, 0x8C, 0x06, + 0x38, 0x41, 0x88, 0x06, 0x06, 0x35, 0x26, 0x42, 0x06, 0x25, 0xB9, 0x41, 0x88, 0x06, 0x6B, 0x13, + 0x00, 0x00, 0x38, 0x41, 0x88, 0x06, 0x38, 0x61, 0x94, 0x06, 0xC6, 0x42, 0xBA, 0x7F, 0xFF, 0xFF, + 0x06, 0x26, 0x0C, 0x30, 0x58, 0x0C, 0x04, 0xD1, 0xCB, 0x8C, 0x01, 0x00, 0x06, 0x9D, 0x38, 0xBE, + 0x94, 0x04, 0xFA, 0x74, 0xFF, 0xFF, 0x0C, 0x20, 0xE4, 0x05, 0x0C, 0x30, 0x48, 0x05, 0x26, 0x21, + 0x26, 0x31, 0x0B, 0x5A, 0x01, 0x00, 0x04, 0x70, 0x0C, 0x90, 0x24, 0x0E, 0x0C, 0x40, 0x2C, 0x0E, + 0x06, 0x57, 0x06, 0x67, 0xC6, 0x7C, 0xB2, 0x56, 0x98, 0x39, 0x16, 0x00, 0x82, 0x4C, 0x04, 0x31, + 0x53, 0x36, 0xD6, 0x3B, 0x92, 0x46, 0x06, 0x29, 0xB9, 0x41, 0x88, 0x06, 0xB9, 0x51, 0x8C, 0x06, + 0xB9, 0x61, 0x94, 0x06, 0xB9, 0x71, 0x90, 0x06, 0xAB, 0x3B, 0x01, 0x00, 0xC6, 0x28, 0x38, 0x41, + 0x88, 0x06, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x61, 0x94, 0x06, 0x38, 0x71, 0x90, 0x06, 0x92, 0x31, + 0x2F, 0x35, 0x05, 0x00, 0x04, 0x21, 0x26, 0x25, 0x26, 0x53, 0x0C, 0x30, 0xE4, 0x05, 0x26, 0x31, + 0x57, 0x51, 0x26, 0x53, 0x04, 0x31, 0x91, 0x35, 0x20, 0x34, 0xB9, 0x21, 0x84, 0x06, 0x28, 0x29, + 0x14, 0x00, 0xA9, 0x35, 0x02, 0x00, 0x28, 0x34, 0x02, 0x00, 0x99, 0x65, 0x01, 0x00, 0xA9, 0x35, + 0x04, 0x00, 0x06, 0x32, 0xB9, 0x41, 0x88, 0x06, 0xB9, 0x51, 0x8C, 0x06, 0xB9, 0x61, 0x94, 0x06, + 0xB9, 0x71, 0x90, 0x06, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x71, 0x90, 0x06, + 0x38, 0x61, 0x94, 0x06, 0xB9, 0x25, 0x08, 0x00, 0x38, 0x41, 0x88, 0x06, 0x38, 0x51, 0x84, 0x06, + 0x24, 0x71, 0x13, 0x77, 0x24, 0x61, 0xC4, 0x6D, 0x2C, 0x90, 0x1C, 0x00, 0x2C, 0x40, 0x1C, 0x00, + 0x92, 0xAA, 0x04, 0x70, 0x06, 0x4E, 0x06, 0x67, 0x04, 0x31, 0xC6, 0x6A, 0x32, 0x1F, 0x06, 0x53, + 0x53, 0x56, 0xD6, 0x5D, 0x92, 0x17, 0x2F, 0x57, 0x07, 0x00, 0x26, 0x57, 0x0C, 0x20, 0x48, 0x05, + 0x26, 0x21, 0x57, 0x51, 0x26, 0x52, 0x28, 0x24, 0x70, 0x01, 0x91, 0x35, 0x99, 0x65, 0x01, 0x00, + 0xA9, 0x25, 0x02, 0x00, 0x28, 0x24, 0x72, 0x01, 0xB9, 0x05, 0x08, 0x00, 0x24, 0x71, 0xA9, 0x25, + 0x04, 0x00, 0x24, 0x61, 0x2C, 0x40, 0x20, 0x00, 0xF2, 0xE1, 0x04, 0x61, 0xB9, 0x00, 0xC4, 0x16, + 0x0C, 0x30, 0xE4, 0x05, 0x0C, 0x40, 0x48, 0x05, 0x99, 0x60, 0xEF, 0x16, 0x06, 0x21, 0x26, 0x31, + 0x26, 0x41, 0x99, 0x00, 0xEE, 0x16, 0xCB, 0x5C, 0x01, 0x00, 0x04, 0x74, 0x06, 0x92, 0x26, 0x71, + 0x04, 0x60, 0x04, 0x51, 0xC6, 0x69, 0x3A, 0xD2, 0xFE, 0xFF, 0x10, 0x47, 0x06, 0x34, 0x57, 0x31, + 0xD7, 0x42, 0x3F, 0x23, 0x04, 0x00, 0x18, 0x37, 0x01, 0x00, 0xB9, 0x51, 0x8C, 0x06, 0x26, 0x2E, + 0xD7, 0x32, 0x26, 0x3E, 0x2C, 0x20, 0x28, 0x03, 0x2C, 0x30, 0x5C, 0x01, 0xB9, 0x61, 0x94, 0x06, + 0xB9, 0x71, 0x90, 0x06, 0xCB, 0x8C, 0x01, 0x00, 0x38, 0x71, 0x90, 0x06, 0x38, 0x51, 0x8C, 0x06, + 0x38, 0x61, 0x94, 0x06, 0x10, 0x47, 0x06, 0x35, 0x53, 0x34, 0x18, 0x47, 0x01, 0x00, 0x06, 0x25, + 0x53, 0x24, 0x66, 0xB3, 0x66, 0xD2, 0x24, 0x61, 0x24, 0x78, 0xF2, 0xD5, 0x34, 0x21, 0x06, 0x76, + 0x53, 0x72, 0x24, 0x91, 0x66, 0xB7, 0x13, 0x99, 0x24, 0x81, 0xFA, 0xA7, 0xFE, 0xFF, 0x06, 0x6B, + 0x73, 0x6A, 0xD4, 0x61, 0x92, 0x3F, 0x18, 0x6D, 0x19, 0x00, 0x38, 0x51, 0x80, 0x06, 0xC6, 0x65, + 0xB2, 0x17, 0x06, 0x2D, 0xB9, 0x71, 0x90, 0x06, 0xAB, 0x3B, 0x01, 0x00, 0xC4, 0x21, 0x38, 0x71, + 0x90, 0x06, 0x92, 0x0E, 0x18, 0x6D, 0x19, 0x00, 0x06, 0x2D, 0x24, 0x61, 0x99, 0x6D, 0x19, 0x00, + 0xB9, 0x71, 0x90, 0x06, 0x8B, 0x7E, 0x01, 0x00, 0x38, 0x71, 0x90, 0x06, 0xF2, 0x23, 0x98, 0x6E, + 0x98, 0x04, 0x82, 0x04, 0x34, 0x61, 0x99, 0x6E, 0x98, 0x04, 0x04, 0x51, 0x38, 0x4E, 0x94, 0x04, + 0x06, 0x65, 0x53, 0x6A, 0x15, 0x66, 0x56, 0x64, 0xB9, 0x6E, 0x94, 0x04, 0x99, 0x0D, 0x16, 0x00, + 0x99, 0x0D, 0x18, 0x00, 0x99, 0x0D, 0x19, 0x00, 0x99, 0x0D, 0x1B, 0x00, 0x99, 0x5E, 0xF0, 0x00, + 0x18, 0x6D, 0x1A, 0x00, 0xC4, 0x62, 0x92, 0x06, 0x38, 0x6E, 0x0C, 0x00, 0x56, 0x67, 0xB9, 0x6E, + 0x0C, 0x00, 0x24, 0x81, 0x13, 0x88, 0xFA, 0x82, 0xFE, 0xFF, 0x06, 0x2C, 0x58, 0xC1, 0xA8, 0x06, + 0x58, 0x81, 0x98, 0x06, 0x2C, 0x10, 0xB8, 0x06, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, + 0x0B, 0x92, 0x01, 0x00, 0xC4, 0x21, 0x06, 0xE2, 0x92, 0x03, 0x8B, 0x2C, 0x02, 0x00, 0x6B, 0x73, + 0x01, 0x00, 0x66, 0x2E, 0x40, 0xE1, 0x13, 0x22, 0x24, 0x18, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x14, 0x0C, 0x70, 0xFC, 0x0A, 0xB1, 0xF1, + 0x98, 0x47, 0x1F, 0x03, 0x06, 0x67, 0x82, 0x07, 0x38, 0x30, 0xB0, 0x16, 0x0C, 0x50, 0x74, 0x0C, + 0x04, 0x70, 0xF2, 0x0A, 0x38, 0x67, 0x0C, 0x00, 0x1C, 0x50, 0x01, 0x80, 0x56, 0x65, 0xB9, 0x67, + 0x0C, 0x00, 0xF2, 0x18, 0x24, 0x71, 0xC6, 0x74, 0x32, 0x15, 0x20, 0x25, 0x18, 0xF3, 0x7B, 0x00, + 0x2C, 0x50, 0x20, 0x00, 0xC6, 0xF2, 0xB2, 0xF7, 0x38, 0x76, 0x0C, 0x00, 0x99, 0x06, 0x1C, 0x03, + 0x1C, 0x50, 0x01, 0x03, 0x56, 0x75, 0x6C, 0x70, 0x00, 0x80, 0x99, 0x06, 0x1F, 0x03, 0xB9, 0x76, + 0x0C, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x08, 0xD0, + 0x06, 0x00, 0x0C, 0xC0, 0x14, 0x0B, 0x04, 0xE0, 0x2C, 0xD0, 0x00, 0xBD, 0x06, 0x2E, 0x0C, 0x30, + 0x17, 0x00, 0xCB, 0x14, 0x00, 0x00, 0x2C, 0xE0, 0x00, 0x4B, 0xC6, 0xED, 0x2C, 0x20, 0xA1, 0x01, + 0xB1, 0x2C, 0x24, 0xC4, 0x92, 0xF4, 0x08, 0xD0, 0x02, 0x00, 0x0C, 0xC0, 0x74, 0x0B, 0x04, 0xE0, + 0x2C, 0xD0, 0xA0, 0x4E, 0x06, 0x2E, 0x04, 0x3E, 0xCB, 0x14, 0x00, 0x00, 0x2C, 0xE0, 0x30, 0x2A, + 0xC6, 0xED, 0x2C, 0x20, 0x81, 0x01, 0xB1, 0x2C, 0x24, 0xC4, 0x92, 0xF5, 0x50, 0xC1, 0x0C, 0x60, + 0x2B, 0x00, 0xB9, 0x60, 0xD4, 0x0B, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x2F, 0x72, 0x02, 0x00, + 0x34, 0x18, 0x26, 0x72, 0xC1, 0xE1, 0x06, 0xE7, 0x57, 0xE2, 0x26, 0x7E, 0x26, 0x27, 0x2C, 0x20, + 0xAC, 0x04, 0x0C, 0xE0, 0xFC, 0x0A, 0x26, 0xE2, 0x14, 0x71, 0x04, 0x26, 0xA1, 0x7E, 0xA9, 0x7E, + 0x02, 0x00, 0x26, 0x2E, 0x04, 0x30, 0x0C, 0x40, 0x24, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, + 0x04, 0x71, 0x99, 0x7E, 0x04, 0x00, 0x38, 0x70, 0xB0, 0x16, 0xA9, 0x0E, 0x2A, 0x00, 0x0C, 0x20, + 0x2E, 0x00, 0x18, 0x77, 0x9D, 0x00, 0x26, 0x2E, 0x99, 0x7E, 0x2C, 0x00, 0x04, 0x30, 0x04, 0x46, + 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x99, 0x0E, 0x2D, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0x34, 0x18, 0xC1, 0xE1, 0x04, 0xE0, 0x06, 0x2E, 0x6B, 0xBE, 0x01, 0x00, 0x24, 0xE1, 0xC4, 0xED, + 0x92, 0xFB, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, + 0xD1, 0x81, 0x06, 0xE2, 0x06, 0x93, 0x06, 0x25, 0x06, 0x36, 0x06, 0xC4, 0x06, 0xA5, 0x18, 0x81, + 0x20, 0x00, 0x28, 0xD1, 0x24, 0x00, 0x28, 0xB1, 0x28, 0x00, 0x0C, 0xF0, 0x98, 0x00, 0xF1, 0xF0, + 0x06, 0x32, 0x06, 0x2E, 0xAB, 0x15, 0x00, 0x00, 0x06, 0xE2, 0x06, 0x38, 0x06, 0x2A, 0x0C, 0xF0, + 0x98, 0x00, 0xF1, 0xF0, 0xC6, 0xCD, 0x06, 0x32, 0x32, 0x03, 0x43, 0x2E, 0xF2, 0x14, 0x06, 0x29, + 0xAB, 0x15, 0x00, 0x00, 0xC6, 0xCB, 0x06, 0x32, 0x32, 0x0D, 0x36, 0x3E, 0x3F, 0x2D, 0x0C, 0x00, + 0x6B, 0x13, 0x00, 0x00, 0x3F, 0x3D, 0x0B, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x26, 0x2E, 0x43, 0x22, + 0xF2, 0x02, 0x43, 0x22, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x28, 0xD4, 0x0E, 0x00, 0x38, 0xF1, 0x10, 0x00, 0x78, 0xE1, + 0x14, 0x00, 0xC6, 0x5D, 0x04, 0x75, 0x12, 0x11, 0x28, 0xD4, 0x0A, 0x00, 0x04, 0x74, 0xC6, 0x5D, + 0x12, 0x0C, 0x28, 0xD4, 0x06, 0x00, 0x04, 0x73, 0xC6, 0x5D, 0x12, 0x07, 0x28, 0x44, 0x02, 0x00, + 0x04, 0x71, 0xC6, 0x54, 0x02, 0x02, 0x04, 0x72, 0x10, 0x56, 0x36, 0x75, 0xB3, 0x57, 0x70, 0x7F, + 0x02, 0x05, 0xC6, 0x7E, 0x92, 0x0F, 0xA1, 0x0F, 0xF2, 0x0F, 0xC4, 0x50, 0x82, 0x05, 0x16, 0x5E, + 0xC6, 0x75, 0x92, 0x04, 0xF2, 0xF9, 0xC4, 0x70, 0x02, 0x03, 0x34, 0x71, 0xF2, 0x04, 0xC4, 0x70, + 0x82, 0x03, 0x24, 0x71, 0xA1, 0x7F, 0x70, 0x5F, 0x10, 0x76, 0xC6, 0x5E, 0x92, 0x05, 0xC4, 0x74, + 0xD2, 0x0A, 0x24, 0x71, 0xF2, 0x07, 0x16, 0xEE, 0xC6, 0x5E, 0x92, 0x05, 0xC4, 0x71, 0xC2, 0x03, + 0x34, 0x71, 0x91, 0x76, 0x10, 0x76, 0xCB, 0x74, 0x03, 0x00, 0x01, 0x00, 0x05, 0x00, 0x30, 0x00, + 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x04, 0x79, 0x91, 0x72, 0x04, 0x77, + 0xF2, 0x10, 0x04, 0x77, 0x91, 0x72, 0x04, 0x75, 0xF2, 0x0C, 0x04, 0x75, 0x91, 0x72, 0x04, 0x73, + 0xF2, 0x08, 0x04, 0x73, 0x91, 0x72, 0x04, 0x72, 0xF2, 0x04, 0x04, 0x72, 0x91, 0x72, 0x04, 0x71, + 0x50, 0xC1, 0x91, 0x73, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x2F, 0x72, 0x02, 0x00, + 0x26, 0x72, 0x06, 0x67, 0x3C, 0x10, 0x40, 0x00, 0x57, 0x62, 0xD9, 0xC1, 0x30, 0x00, 0x26, 0x76, + 0x04, 0xC1, 0x26, 0xC2, 0x26, 0x27, 0x0C, 0xE0, 0xFC, 0x0A, 0x57, 0xC1, 0x2C, 0x20, 0xAC, 0x04, + 0xD9, 0x81, 0x20, 0x00, 0x26, 0xCE, 0x26, 0xE2, 0x18, 0x7E, 0x04, 0x00, 0x99, 0x01, 0x0D, 0x00, + 0x99, 0x01, 0x0C, 0x00, 0xC4, 0x71, 0x06, 0xB3, 0x0C, 0xD0, 0x64, 0x00, 0xC2, 0x17, 0x78, 0x2E, + 0x06, 0x00, 0x78, 0x7E, 0x0A, 0x00, 0x36, 0x27, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x78, 0x3E, + 0x08, 0x00, 0x78, 0x7E, 0x0C, 0x00, 0x43, 0x22, 0x36, 0x37, 0xC4, 0x30, 0x32, 0x02, 0x16, 0x33, + 0x43, 0x33, 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0x06, 0xD2, 0x78, 0x7E, 0x2E, 0x00, 0x78, 0x2E, + 0x30, 0x00, 0x18, 0x3E, 0x2D, 0x00, 0xA9, 0x7E, 0x30, 0x00, 0xA9, 0x2E, 0x32, 0x00, 0x26, 0x27, + 0x24, 0x31, 0x26, 0x2D, 0xAB, 0x15, 0x00, 0x00, 0x99, 0xD0, 0xE1, 0x16, 0x0C, 0x70, 0x2A, 0x00, + 0xA9, 0xDE, 0x2E, 0x00, 0x26, 0x7E, 0xB1, 0x71, 0x38, 0x70, 0xB0, 0x16, 0x06, 0x52, 0x18, 0x77, + 0x9C, 0x00, 0x04, 0x2D, 0x04, 0x3C, 0x0C, 0x60, 0x2C, 0x00, 0xB9, 0x71, 0x04, 0x00, 0x26, 0x21, + 0x26, 0x31, 0x06, 0x4B, 0x26, 0x6E, 0x0B, 0xC6, 0x01, 0x00, 0x18, 0x7E, 0x2C, 0x00, 0x68, 0x61, + 0x0D, 0x00, 0x04, 0x5C, 0x26, 0x51, 0x60, 0x55, 0x34, 0x71, 0x26, 0x77, 0x33, 0x77, 0x14, 0x41, + 0x26, 0x46, 0xB9, 0x71, 0x10, 0x00, 0xB9, 0x51, 0x14, 0x00, 0x04, 0x70, 0x34, 0x51, 0xB9, 0x41, + 0x18, 0x00, 0xB9, 0x51, 0x1C, 0x00, 0x06, 0xA7, 0x06, 0x5E, 0x06, 0x37, 0x06, 0x97, 0x06, 0x27, + 0x06, 0xF7, 0x06, 0x47, 0x78, 0x85, 0x06, 0x00, 0x26, 0x48, 0x78, 0x85, 0x08, 0x00, 0x26, 0xF8, + 0x38, 0x81, 0x18, 0x00, 0xC6, 0x78, 0x82, 0x08, 0x38, 0x81, 0x1C, 0x00, 0xC6, 0x78, 0x92, 0x06, + 0x06, 0xAF, 0x06, 0x34, 0xF2, 0x03, 0x06, 0x9F, 0x06, 0x24, 0x24, 0x71, 0xC4, 0x79, 0x24, 0x54, + 0x92, 0xEA, 0x38, 0x71, 0x10, 0x00, 0x38, 0x41, 0x14, 0x00, 0x18, 0x5E, 0x04, 0x00, 0x26, 0x77, + 0x2F, 0x87, 0x0B, 0x00, 0x24, 0x72, 0x26, 0xB7, 0x13, 0x74, 0xB1, 0x71, 0x20, 0x78, 0x06, 0x4D, + 0xB9, 0x71, 0x04, 0x00, 0x20, 0x7B, 0x13, 0x66, 0xB9, 0x71, 0x08, 0x00, 0x4B, 0xC2, 0x01, 0x00, + 0x38, 0x7C, 0x38, 0x0A, 0x08, 0x60, 0x00, 0xFF, 0x2C, 0x60, 0xFF, 0x0F, 0x5C, 0x20, 0xFF, 0x0F, + 0x57, 0x26, 0x56, 0x76, 0x66, 0x72, 0xB9, 0x7C, 0x38, 0x0A, 0x18, 0x71, 0x0C, 0x00, 0x18, 0x5E, + 0x04, 0x00, 0x18, 0x61, 0x0D, 0x00, 0xB1, 0x71, 0x20, 0x78, 0x06, 0x29, 0xB9, 0x71, 0x04, 0x00, + 0x20, 0x7B, 0x06, 0x3A, 0xB9, 0x71, 0x08, 0x00, 0x06, 0x4D, 0x4B, 0xC2, 0x01, 0x00, 0x38, 0x7C, + 0x38, 0x0A, 0x1C, 0x50, 0x00, 0x10, 0x5C, 0x20, 0xFF, 0x0F, 0x56, 0x75, 0x66, 0x72, 0xB9, 0x7C, + 0x38, 0x0A, 0x58, 0xC1, 0x30, 0x00, 0x58, 0x81, 0x20, 0x00, 0x2C, 0x10, 0x40, 0x00, 0xE1, 0xF0, + 0x38, 0x70, 0xB0, 0x16, 0x28, 0x67, 0xB4, 0x00, 0x3F, 0x74, 0x03, 0x00, 0xC4, 0x70, 0x32, 0x02, + 0x16, 0x77, 0x23, 0x77, 0xC6, 0x76, 0xC2, 0x09, 0xC6, 0x34, 0xC2, 0x04, 0x3F, 0x46, 0x03, 0x00, + 0xF2, 0x03, 0x2F, 0x46, 0x03, 0x00, 0x23, 0x44, 0x06, 0x24, 0xE1, 0xF0, 0x38, 0x30, 0xB0, 0x16, + 0x3C, 0x10, 0x48, 0x00, 0xD9, 0xC1, 0x38, 0x00, 0xD9, 0x81, 0x28, 0x00, 0x18, 0x83, 0xB2, 0x00, + 0x06, 0x21, 0x2C, 0x30, 0x9E, 0x00, 0x04, 0x4A, 0x0C, 0xF0, 0x40, 0x01, 0xF1, 0xF0, 0x0C, 0xD0, + 0xFC, 0x0A, 0x98, 0x7D, 0x98, 0x04, 0x92, 0x05, 0x8B, 0xC1, 0x01, 0x00, 0xFA, 0x50, 0x01, 0x00, + 0x18, 0xBD, 0xE5, 0x00, 0x08, 0x90, 0x00, 0xFF, 0x2F, 0xEB, 0x0B, 0x00, 0x26, 0xEB, 0x06, 0x7E, + 0x57, 0x72, 0x26, 0xE7, 0x26, 0xEB, 0x2C, 0xE0, 0xAC, 0x04, 0x26, 0xED, 0x06, 0xAD, 0x2C, 0x90, + 0xFF, 0x0F, 0x18, 0x7D, 0xE6, 0x00, 0xC6, 0xB7, 0x3A, 0xFF, 0x00, 0x00, 0x06, 0xCB, 0x57, 0xC1, + 0x0C, 0x50, 0x38, 0x15, 0x26, 0xC5, 0x30, 0x7C, 0x08, 0x60, 0x00, 0xF0, 0xD6, 0x76, 0x92, 0x06, + 0x06, 0x2B, 0x6B, 0xBE, 0x01, 0x00, 0xFA, 0xEB, 0x00, 0x00, 0x06, 0x7E, 0x04, 0x68, 0x0C, 0x20, + 0x26, 0x00, 0x0C, 0x30, 0x22, 0x00, 0x26, 0x27, 0x26, 0x37, 0x04, 0x44, 0xB9, 0x61, 0x20, 0x00, + 0xB9, 0x71, 0x24, 0x00, 0xEB, 0x73, 0x03, 0x00, 0x38, 0x61, 0x20, 0x00, 0x38, 0x71, 0x24, 0x00, + 0x34, 0x61, 0xC4, 0x60, 0x34, 0x74, 0x92, 0xEC, 0x30, 0x7C, 0x13, 0x2B, 0x77, 0x76, 0x5C, 0x70, + 0xFF, 0x0F, 0xA9, 0x7E, 0x06, 0x00, 0x30, 0x7C, 0x06, 0x31, 0x5C, 0x70, 0xFF, 0x0F, 0xA9, 0x7E, + 0x08, 0x00, 0x6B, 0xCC, 0x01, 0x00, 0xF0, 0x2E, 0x30, 0x7C, 0x22, 0x5A, 0xF8, 0x6E, 0x02, 0x00, + 0x22, 0x57, 0x0C, 0x60, 0x64, 0x00, 0x3F, 0x58, 0x06, 0x00, 0x06, 0x35, 0xB9, 0x51, 0x1C, 0x00, + 0xB9, 0x61, 0x20, 0x00, 0xB9, 0x71, 0x24, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x71, 0x24, 0x00, + 0x06, 0x42, 0x06, 0x27, 0x77, 0x26, 0x06, 0x38, 0x5C, 0x20, 0xFF, 0x0F, 0xB9, 0x41, 0x18, 0x00, + 0x6B, 0x13, 0x00, 0x00, 0x38, 0x41, 0x18, 0x00, 0x38, 0x61, 0x20, 0x00, 0x26, 0x24, 0x06, 0x36, + 0xAB, 0x15, 0x00, 0x00, 0x38, 0x71, 0x24, 0x00, 0x5C, 0x20, 0xFF, 0x0F, 0x57, 0x26, 0x56, 0x79, + 0x66, 0x72, 0xB1, 0x7C, 0x38, 0x51, 0x1C, 0x00, 0x78, 0x2E, 0x02, 0x00, 0xB9, 0x71, 0x24, 0x00, + 0x06, 0x35, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x71, 0x24, 0x00, 0x06, 0x52, 0x0C, 0x20, 0xFF, 0x0F, + 0x56, 0x27, 0x06, 0x38, 0xB9, 0x51, 0x1C, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x51, 0x1C, 0x00, + 0x38, 0x61, 0x20, 0x00, 0x26, 0x25, 0x06, 0x36, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x71, 0x24, 0x00, + 0x1C, 0x50, 0x00, 0x10, 0x5C, 0x20, 0xFF, 0x0F, 0x56, 0x75, 0x66, 0x72, 0x0C, 0x20, 0x14, 0x00, + 0xB1, 0x7C, 0x26, 0x21, 0x06, 0x3E, 0x04, 0x44, 0xEB, 0x73, 0x03, 0x00, 0xF2, 0x0B, 0x06, 0x67, + 0x77, 0x66, 0x5C, 0x60, 0xFF, 0x0F, 0x5C, 0x70, 0xFF, 0x0F, 0xA9, 0x61, 0x14, 0x00, 0xA9, 0x71, + 0x16, 0x00, 0x18, 0x7E, 0x04, 0x00, 0xC4, 0x78, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x7E, 0x04, 0x00, + 0x18, 0x7E, 0x2D, 0x00, 0xC4, 0x71, 0xD2, 0x04, 0x24, 0x71, 0x99, 0x7E, 0x2D, 0x00, 0x30, 0x3C, + 0x18, 0x2E, 0x2C, 0x00, 0x28, 0x41, 0x14, 0x00, 0x77, 0x36, 0x5C, 0x30, 0xFF, 0x0F, 0xA1, 0x3E, + 0x30, 0x7C, 0x5C, 0x70, 0xFF, 0x0F, 0xA9, 0x7E, 0x02, 0x00, 0x0B, 0xDA, 0x01, 0x00, 0x30, 0x7C, + 0x0C, 0x60, 0xFF, 0x0F, 0x56, 0x62, 0x06, 0x56, 0x57, 0x56, 0x56, 0x79, 0x66, 0x75, 0xB1, 0x7C, + 0x28, 0x3E, 0x02, 0x00, 0x18, 0x2E, 0x2C, 0x00, 0x28, 0x41, 0x16, 0x00, 0xB9, 0x61, 0x20, 0x00, + 0xB9, 0x71, 0x24, 0x00, 0x0B, 0xDA, 0x01, 0x00, 0x38, 0x71, 0x24, 0x00, 0x1C, 0x30, 0x00, 0x10, + 0x5C, 0x20, 0xFF, 0x0F, 0x56, 0x37, 0x66, 0x32, 0xB1, 0x3C, 0x18, 0x50, 0xDB, 0x16, 0x38, 0x61, + 0x20, 0x00, 0xC4, 0x51, 0x92, 0x1C, 0xA9, 0x21, 0x16, 0x00, 0x0C, 0x20, 0x14, 0x00, 0x26, 0x21, + 0x77, 0x3E, 0xA9, 0x61, 0x14, 0x00, 0xEB, 0xDC, 0x02, 0x00, 0x28, 0x61, 0x14, 0x00, 0x30, 0x7C, + 0x5C, 0x60, 0xFF, 0x0F, 0x57, 0x66, 0x56, 0x79, 0x66, 0x76, 0x28, 0x61, 0x16, 0x00, 0x1C, 0x50, + 0x00, 0x10, 0x5C, 0x60, 0xFF, 0x0F, 0x56, 0x75, 0x66, 0x76, 0xB1, 0x7C, 0x24, 0xB1, 0x2C, 0xE0, + 0x34, 0x00, 0xFA, 0x00, 0xFF, 0xFF, 0x18, 0x2A, 0x98, 0x04, 0xC4, 0x22, 0xD2, 0x38, 0x78, 0x3A, + 0xE8, 0x00, 0x78, 0x4A, 0xEA, 0x00, 0x78, 0x6A, 0xEC, 0x00, 0x78, 0x7A, 0xEE, 0x00, 0x04, 0x50, + 0x06, 0xF5, 0xC6, 0x52, 0xB2, 0x24, 0x24, 0xF1, 0x06, 0xEF, 0x57, 0xE1, 0x26, 0xED, 0x38, 0xEE, + 0x38, 0x0A, 0x77, 0xEE, 0xC4, 0xE0, 0x82, 0x17, 0xC4, 0x21, 0x92, 0x08, 0x78, 0x7A, 0xAE, 0x04, + 0x78, 0x6A, 0xAC, 0x04, 0x06, 0x47, 0x06, 0x36, 0xF2, 0x0C, 0xC4, 0x50, 0x92, 0x06, 0x78, 0x4A, + 0xAE, 0x04, 0x78, 0x3A, 0xAC, 0x04, 0xF2, 0x05, 0x78, 0x7A, 0xAE, 0x04, 0x78, 0x6A, 0xAC, 0x04, + 0x24, 0x51, 0x13, 0x55, 0xC4, 0xFD, 0x2C, 0xA0, 0x34, 0x00, 0x92, 0xDC, 0xA9, 0x3D, 0xE8, 0x00, + 0xA9, 0x4D, 0xEA, 0x00, 0xA9, 0x6D, 0xEC, 0x00, 0xA9, 0x7D, 0xEE, 0x00, 0x58, 0xC1, 0x38, 0x00, + 0x58, 0x81, 0x28, 0x00, 0x2C, 0x10, 0x48, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xA9, 0x00, 0x0E, 0x0B, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x2C, 0x02, 0xD9, 0xC1, 0x1C, 0x02, 0x0C, 0xD0, 0xFC, 0x0A, + 0x98, 0x4D, 0x1F, 0x03, 0x38, 0x70, 0xB0, 0x16, 0xD9, 0x81, 0x0C, 0x02, 0x18, 0xE7, 0x79, 0x00, + 0x18, 0x87, 0x7A, 0x00, 0x18, 0x57, 0x7C, 0x00, 0x92, 0x0A, 0x38, 0x7D, 0x0C, 0x00, 0x1C, 0x20, + 0x01, 0x02, 0x56, 0x72, 0xB9, 0x7D, 0x0C, 0x00, 0xFA, 0x62, 0x02, 0x00, 0x38, 0x6D, 0x0C, 0x00, + 0xDC, 0x60, 0x00, 0x02, 0x82, 0x07, 0xC6, 0x85, 0xC2, 0x04, 0x36, 0x85, 0x13, 0x88, 0xF2, 0x02, + 0x04, 0x81, 0xC4, 0x41, 0x92, 0x05, 0x18, 0x5D, 0x25, 0x03, 0xC6, 0x58, 0xA2, 0xE7, 0xC4, 0x60, + 0x82, 0x07, 0x18, 0x77, 0x7D, 0x00, 0x36, 0xE7, 0xC4, 0xE0, 0x12, 0x02, 0x04, 0xE1, 0x38, 0x30, + 0xC0, 0x16, 0x0C, 0xB0, 0x20, 0x01, 0x26, 0xB1, 0xB9, 0x31, 0xF4, 0x01, 0x06, 0x2B, 0x04, 0x30, + 0x0C, 0x40, 0xB5, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x40, 0x20, 0x01, 0x06, 0x21, + 0x04, 0x30, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x28, 0x2D, 0x14, 0x03, 0x06, 0x3E, 0x6B, 0x13, + 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, 0x00, 0x00, 0x28, 0x7D, 0x14, 0x00, 0x04, 0x50, + 0x26, 0x27, 0x23, 0x22, 0x0C, 0x70, 0x74, 0x0B, 0xB9, 0x21, 0xF8, 0x01, 0xB9, 0x71, 0xF0, 0x01, + 0xB9, 0x51, 0xDC, 0x01, 0xB9, 0x51, 0xE0, 0x01, 0x04, 0x91, 0x04, 0xC0, 0x38, 0x61, 0xDC, 0x01, + 0x38, 0x51, 0xF4, 0x01, 0x26, 0x6C, 0x23, 0x66, 0x2F, 0x76, 0x06, 0x00, 0x26, 0x75, 0x70, 0x77, + 0x38, 0x51, 0xF8, 0x01, 0xB9, 0x61, 0xE4, 0x01, 0xC6, 0x75, 0x2A, 0x14, 0x01, 0x00, 0x04, 0x70, + 0x06, 0x56, 0x06, 0xE9, 0xB9, 0x71, 0xE8, 0x01, 0xB9, 0x71, 0xEC, 0x01, 0x06, 0xA7, 0xB9, 0x71, + 0xD8, 0x01, 0x38, 0xF1, 0xF4, 0x01, 0x38, 0x21, 0xF8, 0x01, 0x2F, 0x45, 0x05, 0x00, 0x26, 0x4F, + 0x70, 0x44, 0xC6, 0x42, 0x2A, 0xA5, 0x00, 0x00, 0x04, 0x36, 0x26, 0x3C, 0x57, 0x31, 0x26, 0x3D, + 0x30, 0x33, 0xB9, 0x51, 0x08, 0x02, 0x23, 0x44, 0x06, 0x24, 0xB9, 0x61, 0x04, 0x02, 0xB9, 0x41, + 0xFC, 0x01, 0xB9, 0x71, 0x00, 0x02, 0x6B, 0x13, 0x00, 0x00, 0x38, 0xF1, 0xF0, 0x01, 0x38, 0x41, + 0xFC, 0x01, 0x38, 0x71, 0x00, 0x02, 0x30, 0x3F, 0x26, 0x72, 0x06, 0x24, 0xB9, 0x71, 0x00, 0x02, + 0x6B, 0x13, 0x00, 0x00, 0x38, 0x41, 0xFC, 0x01, 0x38, 0xF1, 0xEC, 0x01, 0x38, 0x31, 0xE8, 0x01, + 0x38, 0x51, 0x08, 0x02, 0x38, 0x61, 0x04, 0x02, 0x38, 0x71, 0x00, 0x02, 0x26, 0xF4, 0x38, 0x41, + 0xD8, 0x01, 0xB9, 0xF1, 0xEC, 0x01, 0x26, 0x32, 0xB8, 0x21, 0xE0, 0x01, 0xB9, 0x31, 0xE8, 0x01, + 0x24, 0x41, 0x23, 0x44, 0xB9, 0x41, 0xD8, 0x01, 0x82, 0x63, 0xC4, 0xA0, 0x1C, 0x40, 0x18, 0x00, + 0x26, 0x45, 0x23, 0x44, 0x92, 0x24, 0x06, 0x34, 0xF7, 0x30, 0x26, 0x3B, 0x10, 0x33, 0x04, 0x21, + 0x56, 0x24, 0x57, 0x21, 0x63, 0x32, 0xD4, 0x3F, 0x92, 0x18, 0xC4, 0xC0, 0x82, 0x0C, 0x14, 0x21, + 0x26, 0x24, 0x06, 0x32, 0xE7, 0x30, 0x26, 0x3B, 0x10, 0x33, 0x54, 0x21, 0x57, 0x21, 0x63, 0x32, + 0xD4, 0x3F, 0x92, 0x0B, 0x24, 0x41, 0x06, 0x34, 0xE7, 0x30, 0x26, 0x3B, 0x10, 0x33, 0x54, 0x41, + 0x57, 0x41, 0x63, 0x34, 0xD4, 0x3F, 0x82, 0x3C, 0x13, 0xE3, 0xF2, 0x39, 0x04, 0x21, 0x26, 0x24, + 0x06, 0x32, 0xE7, 0x30, 0x26, 0x3B, 0x10, 0x33, 0x54, 0x21, 0x57, 0x21, 0x63, 0x32, 0xD4, 0x3F, + 0x82, 0x03, 0xC6, 0x3E, 0x92, 0x1C, 0x06, 0x34, 0xF7, 0x30, 0x26, 0x3B, 0x10, 0x33, 0x04, 0x21, + 0x56, 0x24, 0x57, 0x21, 0x63, 0x32, 0xD4, 0x3F, 0x82, 0x03, 0xC6, 0x3E, 0x92, 0x10, 0xC4, 0xC0, + 0x82, 0x1E, 0x34, 0x41, 0x06, 0x34, 0xE7, 0x30, 0x26, 0x3B, 0x10, 0x33, 0x54, 0x41, 0x57, 0x41, + 0x63, 0x34, 0xD4, 0x3F, 0x04, 0xA1, 0x82, 0x14, 0xC6, 0x3E, 0x82, 0x12, 0x13, 0x33, 0xC6, 0x3E, + 0x06, 0x43, 0xC2, 0x02, 0x06, 0x4E, 0x34, 0x31, 0x57, 0x32, 0x26, 0x31, 0x99, 0x43, 0x0E, 0x00, + 0x14, 0x31, 0x26, 0x3E, 0x57, 0x32, 0x26, 0x31, 0x99, 0x43, 0x0E, 0x00, 0x04, 0xA1, 0x24, 0xC1, + 0x23, 0xCC, 0xCC, 0xC0, 0x16, 0x00, 0x24, 0x51, 0x23, 0x55, 0xCA, 0x54, 0xFF, 0xFF, 0xC4, 0xA0, + 0x92, 0x03, 0x24, 0x91, 0x13, 0x99, 0x04, 0x51, 0xD6, 0x56, 0x82, 0x11, 0x06, 0x46, 0xF7, 0x40, + 0x26, 0x4B, 0x10, 0x34, 0x38, 0xA1, 0xD8, 0x01, 0x06, 0x5E, 0x57, 0x52, 0x66, 0x53, 0x24, 0x61, + 0x34, 0xA1, 0x91, 0x54, 0xB9, 0x61, 0xE4, 0x01, 0x23, 0xAA, 0xF2, 0x03, 0x38, 0xA1, 0xD8, 0x01, + 0x38, 0x21, 0xE4, 0x01, 0xB9, 0x71, 0x00, 0x02, 0x06, 0x3E, 0x57, 0x32, 0x06, 0x4A, 0x66, 0x3E, + 0xF7, 0x20, 0xF7, 0x40, 0x26, 0x2B, 0x33, 0x33, 0x23, 0x44, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, + 0x04, 0x61, 0xD6, 0x6A, 0x38, 0x71, 0x00, 0x02, 0x82, 0x0F, 0x38, 0x61, 0xE4, 0x01, 0x34, 0x61, + 0x26, 0xA6, 0x06, 0x5A, 0xF7, 0x50, 0x26, 0x5B, 0x10, 0x45, 0x54, 0xA1, 0x57, 0xA1, 0x06, 0x6E, + 0x53, 0x6A, 0x66, 0x64, 0x91, 0x65, 0x34, 0xE1, 0x57, 0xE2, 0x26, 0xE1, 0x30, 0x6E, 0x38, 0x51, + 0xE8, 0x01, 0x26, 0x76, 0xB1, 0x7E, 0x38, 0x7E, 0x04, 0x00, 0x38, 0x61, 0xEC, 0x01, 0x26, 0x75, + 0xB9, 0x7E, 0x04, 0x00, 0x38, 0x7E, 0x08, 0x00, 0x38, 0x51, 0xD8, 0x01, 0x26, 0x76, 0xB9, 0x7E, + 0x08, 0x00, 0x28, 0x7E, 0x0C, 0x00, 0xCC, 0x90, 0x10, 0x00, 0x26, 0x75, 0xA9, 0x7E, 0x0C, 0x00, + 0xD2, 0x1F, 0x24, 0xC1, 0x23, 0xCC, 0xCC, 0xC0, 0x16, 0x00, 0xCA, 0xD9, 0xFE, 0xFF, 0x38, 0x71, + 0xE0, 0x01, 0x38, 0x61, 0xF0, 0x01, 0x24, 0x71, 0x23, 0x77, 0xB9, 0x71, 0xE0, 0x01, 0x38, 0x71, + 0xDC, 0x01, 0x24, 0x64, 0x2C, 0x70, 0x18, 0x00, 0x23, 0x77, 0xB9, 0x71, 0xDC, 0x01, 0x38, 0x71, + 0xE0, 0x01, 0xB9, 0x61, 0xF0, 0x01, 0xC4, 0x7E, 0x9A, 0xC1, 0xFE, 0xFF, 0xF2, 0x03, 0x0C, 0x90, + 0x11, 0x00, 0x06, 0xE1, 0x04, 0x60, 0x13, 0x76, 0xC6, 0x79, 0xB2, 0x34, 0x18, 0x3E, 0x0E, 0x00, + 0x14, 0x71, 0x26, 0x73, 0xC6, 0x67, 0x0C, 0x40, 0x10, 0x00, 0x06, 0x56, 0x26, 0x4E, 0x92, 0x27, + 0x06, 0x74, 0x24, 0x51, 0xC6, 0x59, 0x32, 0x23, 0x68, 0x27, 0x0E, 0x00, 0xC6, 0x32, 0x92, 0x1C, + 0x28, 0xF7, 0x0C, 0x00, 0x28, 0x2E, 0x0C, 0x00, 0x26, 0x2F, 0xA9, 0x2E, 0x0C, 0x00, 0x30, 0xFE, + 0x30, 0x27, 0x26, 0x2F, 0xB1, 0x2E, 0x38, 0xFE, 0x04, 0x00, 0x38, 0x27, 0x04, 0x00, 0x26, 0x2F, + 0xB9, 0x2E, 0x04, 0x00, 0x38, 0xFE, 0x08, 0x00, 0x38, 0x27, 0x08, 0x00, 0x26, 0x2F, 0xB9, 0x2E, + 0x08, 0x00, 0xA9, 0x07, 0x0C, 0x00, 0x2C, 0x70, 0x10, 0x00, 0xF2, 0xDC, 0x24, 0x61, 0x06, 0xE4, + 0xF2, 0xCB, 0x04, 0x90, 0x06, 0xB9, 0x06, 0xCD, 0x04, 0x51, 0x0C, 0x60, 0x28, 0x08, 0x18, 0x7D, + 0x1F, 0x03, 0xC6, 0x7B, 0xC2, 0x7C, 0x06, 0x3B, 0xD7, 0x32, 0x26, 0x3C, 0x28, 0x73, 0x5C, 0x01, + 0x0C, 0xF0, 0x20, 0x01, 0x06, 0x47, 0xF7, 0x40, 0x26, 0xF1, 0x26, 0x4F, 0x10, 0xE4, 0x04, 0x41, + 0x56, 0x47, 0x57, 0x41, 0x63, 0xE4, 0xD4, 0xEF, 0x0C, 0xA0, 0x5C, 0x01, 0x26, 0xA3, 0x82, 0x5C, + 0x34, 0xE1, 0x57, 0xE2, 0x26, 0xE1, 0xE8, 0x4E, 0x0E, 0x00, 0x82, 0x05, 0x14, 0xE1, 0x26, 0xE4, + 0x57, 0xE2, 0x26, 0xE1, 0xA8, 0x4E, 0x0C, 0x00, 0x92, 0x1A, 0x18, 0x4E, 0x0F, 0x00, 0x2F, 0xF7, + 0x07, 0x00, 0xD7, 0x42, 0x26, 0x4D, 0x28, 0x24, 0x5C, 0x01, 0x26, 0xF6, 0x26, 0x22, 0x26, 0x26, + 0x70, 0xFF, 0x70, 0x22, 0xC6, 0xF2, 0x02, 0x07, 0x28, 0x33, 0x5E, 0x01, 0xA9, 0x74, 0x5C, 0x01, + 0xA9, 0x34, 0x5E, 0x01, 0xA9, 0x0A, 0x1C, 0x00, 0x24, 0x91, 0xF2, 0x36, 0xC6, 0x48, 0xA9, 0x4A, + 0x1C, 0x00, 0xA2, 0x32, 0xB8, 0x7E, 0x08, 0x00, 0x92, 0x03, 0xB9, 0x5E, 0x08, 0x00, 0x38, 0x7E, + 0x08, 0x00, 0x38, 0x2E, 0x04, 0x00, 0xB9, 0x51, 0x08, 0x02, 0x06, 0x37, 0xB9, 0x61, 0x04, 0x02, + 0xB9, 0x71, 0x00, 0x02, 0xCB, 0x14, 0x00, 0x00, 0x38, 0x71, 0x00, 0x02, 0x43, 0x42, 0x30, 0x2E, + 0xB9, 0x41, 0xFC, 0x01, 0x06, 0x37, 0xCB, 0x14, 0x00, 0x00, 0x04, 0x3A, 0x43, 0x22, 0xAB, 0x15, + 0x00, 0x00, 0x38, 0x41, 0xFC, 0x01, 0xA9, 0x2A, 0x14, 0x00, 0x04, 0x3A, 0x06, 0x24, 0xAB, 0x15, + 0x00, 0x00, 0x99, 0xBE, 0x0F, 0x00, 0x38, 0x61, 0x04, 0x02, 0x38, 0x51, 0x08, 0x02, 0xA9, 0x2A, + 0x16, 0x00, 0xA9, 0x0E, 0x0C, 0x00, 0x28, 0x7A, 0x1C, 0x00, 0x28, 0x4D, 0x12, 0x00, 0xC6, 0x47, + 0xB2, 0x03, 0xA9, 0x7C, 0x12, 0x00, 0x24, 0xB1, 0x13, 0xBB, 0xF2, 0x82, 0x38, 0x7C, 0x0C, 0x00, + 0x08, 0x60, 0x02, 0x00, 0xD6, 0x67, 0x82, 0x07, 0x1C, 0x20, 0x01, 0x02, 0x56, 0x72, 0xB9, 0x7C, + 0x0C, 0x00, 0xF2, 0x0D, 0xC4, 0x90, 0x82, 0x04, 0x6C, 0x70, 0x00, 0x02, 0xF2, 0x04, 0x1C, 0x30, + 0x01, 0x02, 0x56, 0x73, 0xB9, 0x7C, 0x0C, 0x00, 0x2B, 0x86, 0x02, 0x00, 0x58, 0xC1, 0x1C, 0x02, + 0x58, 0x81, 0x0C, 0x02, 0x2C, 0x10, 0x2C, 0x02, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0xC0, 0x06, + 0xD9, 0xC1, 0xB0, 0x06, 0x0C, 0x60, 0xFC, 0x0A, 0xD9, 0x81, 0xA0, 0x06, 0x38, 0x76, 0x0C, 0x00, + 0x08, 0x50, 0x02, 0x00, 0xD6, 0x57, 0x06, 0xD6, 0x82, 0x05, 0x1C, 0x30, 0x01, 0x01, 0x56, 0x73, + 0xF2, 0x08, 0x18, 0x56, 0x1F, 0x03, 0xC4, 0x51, 0xD2, 0x08, 0x1C, 0x40, 0x01, 0x01, 0x56, 0x74, + 0xB9, 0x76, 0x0C, 0x00, 0xFA, 0xF6, 0x00, 0x00, 0xDC, 0x70, 0x00, 0x01, 0x08, 0x70, 0x00, 0x80, + 0x2C, 0x70, 0x0C, 0xDC, 0x82, 0x0A, 0x28, 0x67, 0x86, 0x00, 0x28, 0x27, 0x82, 0x00, 0x28, 0xE7, + 0x84, 0x00, 0x26, 0x26, 0x26, 0xE6, 0xF2, 0x05, 0x28, 0x27, 0x82, 0x00, 0x28, 0xE7, 0x84, 0x00, + 0x06, 0x32, 0x6B, 0x13, 0x00, 0x00, 0x06, 0x3E, 0x06, 0x92, 0x06, 0x2E, 0x6B, 0x13, 0x00, 0x00, + 0x26, 0x92, 0x0C, 0x30, 0x48, 0x05, 0x0C, 0x20, 0xE4, 0x05, 0x26, 0x21, 0x26, 0x31, 0x0B, 0x5A, + 0x01, 0x00, 0x06, 0xAD, 0x04, 0xE0, 0x18, 0x7D, 0x1F, 0x03, 0xC6, 0x7E, 0xC2, 0x1F, 0x06, 0xCE, + 0x2F, 0xBE, 0x0E, 0x00, 0xD7, 0xC2, 0x26, 0xBE, 0x26, 0xCA, 0x0C, 0x20, 0xE4, 0x05, 0x2C, 0xC0, + 0x70, 0x01, 0x57, 0xB1, 0x26, 0x21, 0x06, 0x3E, 0x26, 0x2B, 0x04, 0x40, 0x06, 0x5C, 0xCB, 0x5A, + 0x01, 0x00, 0x0C, 0x20, 0x48, 0x05, 0x26, 0x21, 0x06, 0x3E, 0x26, 0x2B, 0x04, 0x40, 0x06, 0x5C, + 0xCB, 0x5A, 0x01, 0x00, 0x24, 0xE1, 0x13, 0xEE, 0xF2, 0xDF, 0x06, 0x29, 0x04, 0x30, 0x04, 0x41, + 0x4B, 0x5C, 0x01, 0x00, 0x0C, 0x30, 0xE4, 0x05, 0x0C, 0x40, 0x48, 0x05, 0x06, 0x21, 0x26, 0x31, + 0x26, 0x41, 0xCB, 0x5C, 0x01, 0x00, 0x86, 0x22, 0xB9, 0x21, 0x88, 0x06, 0x82, 0x07, 0x04, 0xA4, + 0x04, 0x60, 0x26, 0xA1, 0xB9, 0x61, 0x80, 0x06, 0xF2, 0x0A, 0x38, 0x7A, 0x0C, 0x00, 0x1C, 0xF0, + 0x01, 0x01, 0x56, 0x7F, 0xB9, 0x7A, 0x0C, 0x00, 0xFA, 0x8C, 0x00, 0x00, 0x10, 0x5A, 0x0C, 0xC0, + 0x5C, 0x01, 0x06, 0x75, 0xD7, 0x72, 0x26, 0x7D, 0x26, 0xC7, 0xB9, 0x51, 0x84, 0x06, 0x38, 0x67, + 0x60, 0x01, 0x38, 0x97, 0x64, 0x01, 0x38, 0x57, 0x68, 0x01, 0x38, 0x8C, 0x10, 0x00, 0x06, 0xE1, + 0x04, 0xB0, 0x18, 0x7E, 0x04, 0x00, 0x38, 0xF1, 0x84, 0x06, 0xC6, 0x7F, 0x92, 0x45, 0xB0, 0x7E, + 0x82, 0x43, 0x18, 0x7E, 0x05, 0x00, 0x0C, 0x20, 0x5C, 0x01, 0xD7, 0x72, 0x26, 0x7D, 0x38, 0x47, + 0x60, 0x01, 0x26, 0x27, 0x26, 0x64, 0x38, 0x47, 0x64, 0x01, 0x26, 0x94, 0x38, 0x47, 0x68, 0x01, + 0x0C, 0x30, 0x28, 0x08, 0x26, 0x54, 0x38, 0x42, 0x10, 0x00, 0x26, 0x84, 0x20, 0x42, 0x06, 0xF4, + 0x26, 0xF4, 0x26, 0x3F, 0xB9, 0x31, 0x94, 0x06, 0x20, 0x3C, 0xB9, 0x41, 0x9C, 0x06, 0x26, 0x33, + 0x0C, 0x40, 0x28, 0x08, 0x26, 0x43, 0xB9, 0x41, 0x98, 0x06, 0x38, 0xF1, 0x98, 0x06, 0x38, 0x41, + 0x94, 0x06, 0x70, 0x3F, 0x70, 0x44, 0xC6, 0x43, 0x02, 0x08, 0x28, 0x77, 0x5E, 0x01, 0x38, 0x31, + 0x9C, 0x06, 0xA9, 0x7C, 0x02, 0x00, 0xA1, 0x3C, 0x04, 0x30, 0x0C, 0x40, 0x20, 0x00, 0xB9, 0x51, + 0x8C, 0x06, 0xB9, 0x61, 0x90, 0x06, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0xB1, 0x0E, 0x38, 0x61, + 0x90, 0x06, 0x38, 0x51, 0x8C, 0x06, 0x38, 0x71, 0x88, 0x06, 0x24, 0xB1, 0x13, 0xBB, 0xC6, 0xB7, + 0x24, 0xE8, 0x92, 0xB0, 0x06, 0x36, 0x06, 0x25, 0xAB, 0x15, 0x00, 0x00, 0x04, 0x3A, 0x43, 0x22, + 0xAB, 0x15, 0x00, 0x00, 0xA9, 0x2C, 0x14, 0x00, 0x06, 0x39, 0x06, 0x28, 0xAB, 0x15, 0x00, 0x00, + 0x43, 0x22, 0x04, 0x3A, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x71, 0x80, 0x06, 0xA9, 0x2C, 0x16, 0x00, + 0x24, 0xA8, 0x24, 0x71, 0x13, 0x77, 0xC6, 0x7B, 0xB9, 0x71, 0x80, 0x06, 0x9A, 0x80, 0xFF, 0xFF, + 0x38, 0x7D, 0x0C, 0x00, 0x6C, 0x70, 0x00, 0x01, 0xB9, 0x7D, 0x0C, 0x00, 0x2B, 0x86, 0x02, 0x00, + 0x58, 0xC1, 0xB0, 0x06, 0x58, 0x81, 0xA0, 0x06, 0x2C, 0x10, 0xC0, 0x06, 0xE1, 0xF0, 0x00, 0x00, + 0x3C, 0x10, 0x18, 0x00, 0xD9, 0xC1, 0x08, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, 0xC1, 0xA1, 0x18, 0x7D, + 0x98, 0x04, 0x06, 0xED, 0xC4, 0x72, 0x92, 0x05, 0x18, 0x7D, 0x9B, 0x04, 0xC4, 0x72, 0x82, 0x3D, + 0x14, 0x71, 0xB9, 0x7E, 0x30, 0x0A, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0x0C, 0xDC, 0x28, 0x67, + 0x86, 0x00, 0x28, 0xC7, 0x82, 0x00, 0x28, 0xD7, 0x84, 0x00, 0xA9, 0x0E, 0x34, 0x0A, 0x26, 0xC6, + 0x0C, 0x20, 0x14, 0x00, 0x26, 0x2C, 0x26, 0xD6, 0x06, 0x32, 0x0C, 0xA0, 0x14, 0x00, 0x6B, 0x13, + 0x00, 0x00, 0x26, 0xAD, 0x06, 0xB2, 0x06, 0x3A, 0x06, 0x2A, 0x6B, 0x13, 0x00, 0x00, 0x26, 0x2B, + 0xB9, 0x2E, 0x28, 0x0A, 0x0C, 0x20, 0x78, 0x00, 0x26, 0x2C, 0x06, 0x32, 0x6B, 0x13, 0x00, 0x00, + 0x2C, 0xD0, 0x78, 0x00, 0x06, 0xC2, 0x06, 0x3D, 0x06, 0x2D, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x7E, + 0x0C, 0x00, 0x08, 0x60, 0xFD, 0xFF, 0x2C, 0x60, 0xFF, 0xFF, 0x26, 0x2C, 0x56, 0x76, 0xB9, 0x2E, + 0x2C, 0x0A, 0xB9, 0x7E, 0x0C, 0x00, 0xF2, 0x4E, 0x38, 0xCD, 0x0C, 0x00, 0x08, 0x70, 0x02, 0x00, + 0xD6, 0x7C, 0x92, 0x48, 0x98, 0x7D, 0x3E, 0x03, 0x82, 0x45, 0x98, 0x7D, 0x5A, 0x03, 0x82, 0x42, + 0x78, 0x7D, 0x44, 0x03, 0x78, 0x2D, 0x28, 0x03, 0x78, 0xAD, 0x2A, 0x03, 0x36, 0x27, 0x78, 0x7D, + 0x46, 0x03, 0x06, 0x32, 0x36, 0xA7, 0x6B, 0x13, 0x00, 0x00, 0x06, 0xB2, 0x06, 0x3A, 0x06, 0x2A, + 0x6B, 0x13, 0x00, 0x00, 0xF8, 0x7D, 0x34, 0x0A, 0x26, 0x2B, 0x02, 0x22, 0x38, 0x6D, 0x30, 0x0A, + 0xC6, 0x62, 0xC2, 0x13, 0xCC, 0x70, 0x13, 0x00, 0x12, 0x04, 0x24, 0x71, 0xA9, 0x7D, 0x34, 0x0A, + 0x38, 0x7E, 0x28, 0x0A, 0xC6, 0x72, 0xC2, 0x06, 0x08, 0x70, 0x02, 0x00, 0x66, 0x7C, 0xB9, 0x7E, + 0x0C, 0x00, 0xB9, 0x2E, 0x30, 0x0A, 0xF2, 0x16, 0x34, 0x71, 0xC3, 0x77, 0xA9, 0x7D, 0x34, 0x0A, + 0x92, 0x11, 0x14, 0x71, 0xB9, 0x7D, 0x30, 0x0A, 0xA9, 0x0D, 0x34, 0x0A, 0xF2, 0x0B, 0x38, 0x7D, + 0x2C, 0x0A, 0xC6, 0x72, 0xB2, 0x07, 0x04, 0x73, 0xA9, 0x7D, 0x34, 0x0A, 0x14, 0x71, 0xB9, 0x7D, + 0x30, 0x0A, 0x58, 0xC1, 0x08, 0x00, 0x40, 0xA1, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x0C, 0x70, 0xFC, 0x0A, 0x14, 0x61, 0x99, 0x07, 0x1C, 0x03, 0x99, 0x07, 0x1F, 0x03, 0x99, 0x07, + 0x24, 0x03, 0x99, 0x67, 0x22, 0x03, 0x99, 0x07, 0x23, 0x03, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, + 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x7E, 0xDF, 0x00, 0x04, 0x4D, 0x06, 0x27, 0xD7, 0x22, 0x36, 0x47, + 0x26, 0x2E, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x30, 0xD7, 0x42, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, + 0x98, 0x7E, 0xDF, 0x00, 0x92, 0x03, 0x8B, 0x36, 0x02, 0x00, 0xB9, 0x0E, 0xFC, 0x02, 0xB9, 0x0E, + 0x00, 0x03, 0x99, 0x0E, 0x25, 0x03, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x2F, 0x75, 0x05, 0x00, + 0xC4, 0x50, 0x3C, 0x10, 0x18, 0x00, 0x26, 0x75, 0xD7, 0x71, 0xD9, 0xC1, 0x08, 0x00, 0xC1, 0xA1, + 0x2F, 0x64, 0x07, 0x00, 0x82, 0x06, 0xC4, 0x5D, 0x14, 0x71, 0x04, 0xC0, 0x82, 0x04, 0xF2, 0x02, + 0x06, 0x75, 0x04, 0xC1, 0xC4, 0x40, 0x82, 0x07, 0xCC, 0x40, 0x16, 0x00, 0x14, 0xD1, 0x04, 0xB0, + 0x82, 0x04, 0xF2, 0x02, 0x06, 0xD4, 0x04, 0xB1, 0x26, 0x66, 0x26, 0x63, 0x70, 0xF6, 0x2F, 0x67, + 0x05, 0x00, 0x2F, 0xE6, 0x06, 0x00, 0x26, 0xE6, 0xD7, 0xE1, 0x06, 0x6D, 0x2F, 0xA6, 0x04, 0x00, + 0x26, 0xAE, 0x26, 0xAA, 0x26, 0xA3, 0x70, 0xAA, 0xC6, 0xAF, 0x12, 0x11, 0x24, 0x61, 0x43, 0x66, + 0xC6, 0x6B, 0x02, 0xF5, 0x24, 0x71, 0x43, 0x77, 0xC6, 0x7C, 0x02, 0xEA, 0x28, 0x60, 0x16, 0x0E, + 0x04, 0x70, 0xC6, 0xF6, 0x22, 0x05, 0xA1, 0xF2, 0x04, 0x71, 0xF2, 0x02, 0x04, 0x70, 0x58, 0xC1, + 0x08, 0x00, 0x40, 0xA1, 0x06, 0x27, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x28, 0x00, + 0xD9, 0x81, 0x08, 0x00, 0x86, 0xB6, 0xD9, 0xC1, 0x18, 0x00, 0x06, 0xA3, 0x06, 0xD2, 0x06, 0xE4, + 0x06, 0xC5, 0x92, 0x13, 0x30, 0x74, 0x38, 0xB4, 0x04, 0x00, 0x26, 0xB7, 0x38, 0x74, 0x08, 0x00, + 0x26, 0xB7, 0x38, 0x74, 0x0C, 0x00, 0x26, 0xB7, 0x38, 0x74, 0x10, 0x00, 0xA6, 0xB7, 0x92, 0x05, + 0x38, 0xE5, 0x08, 0x00, 0x04, 0xB1, 0xF2, 0x35, 0x30, 0x3C, 0x30, 0x2E, 0x6B, 0x13, 0x00, 0x00, + 0xB1, 0x2E, 0x06, 0x72, 0x38, 0x3C, 0x04, 0x00, 0x38, 0x2E, 0x04, 0x00, 0xB9, 0x71, 0x04, 0x00, + 0x6B, 0x13, 0x00, 0x00, 0xB9, 0x2E, 0x04, 0x00, 0x06, 0x62, 0x38, 0x3C, 0x08, 0x00, 0x38, 0x2E, + 0x08, 0x00, 0xB1, 0x61, 0x6B, 0x13, 0x00, 0x00, 0xB9, 0x2E, 0x08, 0x00, 0x38, 0x3C, 0x0C, 0x00, + 0x06, 0x82, 0x38, 0x2E, 0x0C, 0x00, 0x6B, 0x13, 0x00, 0x00, 0xB9, 0x2E, 0x0C, 0x00, 0x06, 0x92, + 0x38, 0x3C, 0x10, 0x00, 0x38, 0x2E, 0x10, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x30, 0x61, 0x38, 0x71, + 0x04, 0x00, 0xB9, 0x2E, 0x10, 0x00, 0x2F, 0xE7, 0x06, 0x00, 0x26, 0xE8, 0x26, 0xE9, 0x26, 0xE2, + 0x06, 0x3B, 0x06, 0x2E, 0xCB, 0x14, 0x00, 0x00, 0x04, 0x3A, 0xCB, 0x14, 0x00, 0x00, 0xC4, 0xA0, + 0x92, 0x08, 0xB9, 0xBD, 0x04, 0x00, 0xB9, 0xED, 0x0C, 0x00, 0xA9, 0x2D, 0x14, 0x00, 0xF2, 0x11, + 0xC4, 0xA1, 0x92, 0x08, 0xB9, 0xBD, 0x08, 0x00, 0xB9, 0xED, 0x10, 0x00, 0xA9, 0x2D, 0x16, 0x00, + 0xF2, 0x08, 0xC4, 0xA2, 0x92, 0x04, 0xA9, 0x2D, 0x18, 0x00, 0xF2, 0x03, 0xA9, 0x2D, 0x1A, 0x00, + 0x58, 0xC1, 0x18, 0x00, 0x58, 0x81, 0x08, 0x00, 0x2C, 0x10, 0x28, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x34, 0x14, 0xB1, 0xF1, 0x8B, 0x99, 0x02, 0x00, 0x30, 0xF1, 0x16, 0x22, 0xF7, 0x2F, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xD7, 0x16, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x0C, 0xE0, 0xFC, 0x0A, 0x82, 0x06, 0x08, 0x70, 0x00, 0x80, 0x28, 0x77, 0xB4, 0xDC, + 0xF2, 0x05, 0x38, 0x70, 0xB0, 0x16, 0x28, 0x77, 0x2C, 0x00, 0xA9, 0x7E, 0x04, 0x03, 0x28, 0x7E, + 0x04, 0x03, 0x28, 0x6E, 0x12, 0x03, 0x26, 0x67, 0x38, 0x70, 0xB0, 0x16, 0x23, 0x66, 0xA9, 0x6E, + 0x06, 0x03, 0x28, 0x77, 0x32, 0x00, 0xA9, 0x7E, 0x20, 0x03, 0x98, 0x70, 0xE4, 0x16, 0x82, 0x0C, + 0x38, 0x7E, 0x0C, 0x00, 0xD4, 0x71, 0x82, 0x08, 0x08, 0x70, 0x00, 0x80, 0x28, 0x77, 0x88, 0xDC, + 0x26, 0x67, 0xA9, 0x6E, 0x06, 0x03, 0x4B, 0x3C, 0x00, 0x00, 0x23, 0x22, 0x0C, 0x30, 0x18, 0x00, + 0x6B, 0x17, 0x00, 0x00, 0xA3, 0x22, 0x82, 0x04, 0xCC, 0x20, 0x16, 0x00, 0x92, 0x0A, 0x38, 0x70, + 0xB0, 0x16, 0x28, 0x67, 0x34, 0x00, 0x28, 0x7E, 0x06, 0x03, 0x26, 0x76, 0xA9, 0x7E, 0x06, 0x03, + 0x28, 0x7E, 0x06, 0x03, 0xA9, 0x7E, 0x08, 0x03, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x50, 0x01, 0x0C, 0x20, 0x68, 0x00, 0x0C, 0x40, 0x2E, 0x00, + 0x26, 0x21, 0x04, 0x30, 0xD9, 0xC1, 0x40, 0x01, 0xD9, 0x81, 0x30, 0x01, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, 0x0C, 0x60, 0xFF, 0x0F, 0xA9, 0x67, 0x14, 0x03, 0x38, 0x40, + 0xC0, 0x16, 0xA9, 0x07, 0x16, 0x03, 0x38, 0x50, 0xBC, 0x16, 0xA9, 0x07, 0x18, 0x03, 0x18, 0xD7, + 0xE2, 0x00, 0xB9, 0x41, 0x10, 0x01, 0x06, 0x87, 0x0C, 0x70, 0x66, 0x00, 0x26, 0x71, 0xB9, 0x51, + 0x14, 0x01, 0xB9, 0x71, 0xFC, 0x00, 0x18, 0x78, 0xE4, 0x00, 0xC6, 0x7D, 0xCA, 0x9C, 0x01, 0x00, + 0x38, 0x78, 0x00, 0x03, 0x73, 0x7D, 0xD4, 0x71, 0x8A, 0x39, 0x02, 0x00, 0x2F, 0x7D, 0x0D, 0x00, + 0x0C, 0x90, 0x1C, 0x00, 0x26, 0x7D, 0x26, 0x9D, 0xD7, 0x71, 0x57, 0x91, 0x18, 0xC8, 0xE1, 0x00, + 0xB9, 0x71, 0x04, 0x01, 0xB9, 0x91, 0x0C, 0x01, 0xF2, 0x08, 0x18, 0x68, 0x99, 0x04, 0xC4, 0x62, + 0x8A, 0x8C, 0x01, 0x00, 0x24, 0xC1, 0x13, 0xCC, 0x18, 0x78, 0xE3, 0x00, 0xC6, 0x7C, 0xCA, 0x1E, + 0x02, 0x00, 0x38, 0x78, 0xFC, 0x02, 0x73, 0x7C, 0xD4, 0x71, 0x82, 0xF5, 0x38, 0xE1, 0x04, 0x01, + 0x26, 0xEC, 0xB9, 0xE1, 0x08, 0x01, 0x43, 0xEE, 0x2F, 0xBE, 0x0E, 0x00, 0x0C, 0x70, 0x28, 0x08, + 0x26, 0x7B, 0x70, 0x67, 0x78, 0x78, 0x06, 0x03, 0xC6, 0x67, 0x22, 0xE5, 0x06, 0x9E, 0x0C, 0x70, + 0x68, 0x00, 0xF7, 0x91, 0x26, 0x71, 0x38, 0xA1, 0x08, 0x01, 0x26, 0x79, 0x10, 0x77, 0x54, 0xA7, + 0x63, 0x7A, 0xD4, 0x71, 0x92, 0xD8, 0x43, 0x7C, 0x43, 0x6D, 0x0C, 0x20, 0xFA, 0x00, 0x06, 0x47, + 0x26, 0x21, 0x0C, 0x30, 0x28, 0x08, 0x06, 0x56, 0xB9, 0x71, 0x28, 0x01, 0xA9, 0x01, 0xFA, 0x00, + 0xB9, 0x61, 0x00, 0x01, 0x6B, 0x39, 0x02, 0x00, 0xC4, 0x20, 0x38, 0x71, 0x28, 0x01, 0x82, 0xBE, + 0x06, 0x2C, 0x06, 0x3D, 0x8B, 0x45, 0x02, 0x00, 0xC4, 0x20, 0x92, 0xBD, 0x78, 0x71, 0xFA, 0x00, + 0x28, 0x68, 0x18, 0x03, 0xC6, 0x76, 0x22, 0x03, 0xA9, 0x78, 0x18, 0x03, 0x0C, 0x70, 0x68, 0x00, + 0x26, 0x71, 0x26, 0x97, 0x10, 0x59, 0x04, 0x71, 0x06, 0x67, 0x53, 0x6A, 0xCC, 0xC0, 0x17, 0x00, + 0x66, 0x65, 0x91, 0x69, 0x82, 0x0E, 0x06, 0x57, 0x26, 0x5E, 0x06, 0x65, 0x0C, 0x90, 0x68, 0x00, + 0xE7, 0x61, 0x26, 0x91, 0x26, 0x69, 0x54, 0x57, 0x53, 0x75, 0x10, 0x56, 0x66, 0x75, 0x91, 0x76, + 0xC4, 0xDD, 0x9A, 0x32, 0x01, 0x00, 0x38, 0xE1, 0x14, 0x01, 0x38, 0x70, 0xB0, 0x16, 0x26, 0xBE, + 0x28, 0x37, 0x3E, 0x00, 0x70, 0x2B, 0x14, 0xB1, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0xAB, 0x15, 0x00, 0x00, 0x0C, 0x40, 0x14, 0x00, 0x26, 0x48, 0x20, 0x44, 0x13, 0x22, 0xB9, 0x41, + 0x00, 0x01, 0x04, 0x40, 0x06, 0x74, 0x14, 0x62, 0xB9, 0x21, 0x1C, 0x01, 0x2F, 0xA6, 0x0D, 0x00, + 0x13, 0xAA, 0x33, 0x5A, 0x2F, 0xF5, 0x05, 0x00, 0x26, 0x5F, 0x0C, 0x20, 0x34, 0x00, 0xD7, 0x51, + 0x23, 0x55, 0x26, 0x21, 0xB9, 0x51, 0x18, 0x01, 0x2F, 0x34, 0x01, 0x00, 0x26, 0x24, 0x14, 0x52, + 0xC4, 0xAD, 0xCA, 0x38, 0x01, 0x00, 0xA1, 0x02, 0xA1, 0x03, 0x24, 0x51, 0x43, 0x55, 0xC4, 0x53, + 0x24, 0x22, 0x24, 0x32, 0x92, 0xF6, 0x24, 0x4A, 0xCC, 0x40, 0x32, 0x00, 0x24, 0x61, 0x43, 0x66, + 0x92, 0xDE, 0x78, 0x61, 0x4C, 0x00, 0x28, 0x58, 0x14, 0x03, 0xA9, 0x61, 0xFA, 0x00, 0xC6, 0x56, + 0x02, 0x03, 0xA9, 0x68, 0x14, 0x03, 0x28, 0x58, 0x16, 0x03, 0xC6, 0x56, 0x32, 0x03, 0xA9, 0x68, + 0x16, 0x03, 0x0C, 0x50, 0x34, 0x00, 0x04, 0x42, 0x04, 0x34, 0x04, 0x28, 0x56, 0x47, 0x56, 0x37, + 0x56, 0x27, 0x26, 0x51, 0x5C, 0x70, 0x10, 0x00, 0x06, 0x65, 0x13, 0x44, 0x13, 0x33, 0x13, 0x22, + 0x13, 0x77, 0xC4, 0x40, 0x92, 0x02, 0xA1, 0x05, 0xC4, 0x30, 0x92, 0x03, 0xA9, 0x05, 0x28, 0x00, + 0xC4, 0x20, 0x92, 0x02, 0xA1, 0x06, 0xC4, 0x70, 0x92, 0x03, 0xA9, 0x06, 0x08, 0x00, 0x38, 0xE1, + 0xFC, 0x00, 0x24, 0x6A, 0xC6, 0x6E, 0x24, 0x52, 0x92, 0xED, 0x0C, 0x60, 0x34, 0x00, 0x26, 0x61, + 0x06, 0xE1, 0x06, 0x41, 0x06, 0x56, 0x04, 0x70, 0x78, 0x25, 0x0A, 0x00, 0x70, 0xF5, 0x0C, 0x30, + 0xD4, 0x00, 0x26, 0xF2, 0x78, 0x25, 0x14, 0x00, 0x26, 0x31, 0x26, 0xF2, 0x78, 0x25, 0x1E, 0x00, + 0x26, 0x37, 0x26, 0xF2, 0x78, 0x25, 0x28, 0x00, 0x24, 0x42, 0x26, 0x2F, 0xB1, 0x23, 0x70, 0xF6, + 0x78, 0x26, 0x02, 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x26, 0xF2, 0x78, 0x26, 0x04, 0x00, 0x26, 0x31, + 0x26, 0xF2, 0x78, 0x26, 0x06, 0x00, 0x26, 0x37, 0x26, 0xF2, 0x78, 0x26, 0x08, 0x00, 0x24, 0x52, + 0x26, 0x2F, 0xB1, 0x23, 0x78, 0xF4, 0x08, 0x00, 0x78, 0x24, 0x12, 0x00, 0x0C, 0x30, 0xAC, 0x00, + 0x26, 0xF2, 0x78, 0x24, 0x1C, 0x00, 0x26, 0x31, 0x26, 0x37, 0x26, 0x2F, 0xB1, 0x23, 0x78, 0xFE, + 0x02, 0x00, 0x78, 0x2E, 0x04, 0x00, 0x0C, 0x30, 0x98, 0x00, 0x26, 0xF2, 0x26, 0x31, 0x78, 0x2E, + 0x06, 0x00, 0x26, 0x37, 0x24, 0x74, 0xCC, 0x70, 0x14, 0x00, 0x26, 0x2F, 0xB1, 0x23, 0x24, 0x6A, + 0x24, 0xEA, 0x92, 0xBB, 0x18, 0x28, 0x1F, 0x03, 0x38, 0xE1, 0x0C, 0x01, 0xD7, 0x22, 0x26, 0xE8, + 0x26, 0x28, 0x0C, 0x40, 0xC0, 0x00, 0x06, 0x5E, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x31, 0x26, 0x41, + 0x04, 0x60, 0xEB, 0x3D, 0x02, 0x00, 0x18, 0x28, 0x1F, 0x03, 0x0C, 0x40, 0x98, 0x00, 0xD7, 0x22, + 0x26, 0x28, 0x06, 0x5E, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x33, 0x26, 0x41, 0x04, 0x60, 0xEB, 0x3D, + 0x02, 0x00, 0x18, 0x28, 0x1F, 0x03, 0x04, 0xE4, 0x26, 0xEC, 0x57, 0xE1, 0xD7, 0x22, 0x26, 0xE8, + 0x04, 0x30, 0x26, 0x28, 0x0C, 0x40, 0xD4, 0x00, 0x06, 0x63, 0x2C, 0x20, 0x5C, 0x01, 0x26, 0x41, + 0x06, 0x5E, 0xEB, 0x3D, 0x02, 0x00, 0x18, 0x28, 0x1F, 0x03, 0x0C, 0x40, 0xAC, 0x00, 0xD7, 0x22, + 0x26, 0x28, 0x06, 0x5E, 0x04, 0x60, 0x2C, 0x20, 0x5C, 0x01, 0x04, 0x32, 0x26, 0x41, 0xEB, 0x3D, + 0x02, 0x00, 0x18, 0x68, 0x1F, 0x03, 0x38, 0xF1, 0x08, 0x01, 0x18, 0x58, 0x25, 0x03, 0x06, 0x76, + 0xD7, 0x72, 0x26, 0x78, 0x99, 0xC7, 0x5E, 0x01, 0x99, 0xD7, 0x5F, 0x01, 0xA9, 0xF7, 0x5C, 0x01, + 0xA9, 0x57, 0x78, 0x01, 0x04, 0x71, 0x26, 0x76, 0x13, 0x77, 0xC4, 0x7D, 0x99, 0x78, 0x1F, 0x03, + 0x9A, 0x82, 0xFE, 0xFF, 0x18, 0x68, 0x1F, 0x03, 0x98, 0x78, 0xDD, 0x00, 0x99, 0x68, 0x1D, 0x03, + 0x9A, 0xA1, 0x00, 0x00, 0xFA, 0xA4, 0x00, 0x00, 0x38, 0x31, 0x10, 0x01, 0x38, 0x51, 0x00, 0x01, + 0x0C, 0x20, 0xFA, 0x00, 0x26, 0x21, 0x06, 0x47, 0x6B, 0x39, 0x02, 0x00, 0xC4, 0x20, 0x8A, 0x6B, + 0xFE, 0xFF, 0xFA, 0xA7, 0xFE, 0xFF, 0x0C, 0x70, 0x18, 0x00, 0x26, 0x7E, 0x0C, 0x50, 0x68, 0x00, + 0xE7, 0x71, 0x26, 0x51, 0x26, 0x57, 0x04, 0x67, 0x04, 0x71, 0x56, 0x6E, 0x10, 0x45, 0x06, 0xF7, + 0x53, 0xF6, 0x06, 0x6F, 0xC4, 0xC0, 0x66, 0x64, 0x91, 0x65, 0x92, 0x11, 0x2C, 0xE0, 0x19, 0x00, + 0x06, 0x6E, 0x0C, 0x40, 0x68, 0x00, 0xE7, 0x61, 0x26, 0x41, 0x26, 0x64, 0x10, 0x56, 0x54, 0xE7, + 0x04, 0x71, 0x53, 0x7E, 0x66, 0x75, 0x91, 0x76, 0xFA, 0xAF, 0xFE, 0xFF, 0x0C, 0x50, 0x17, 0x00, + 0x26, 0x5E, 0x06, 0x65, 0x0C, 0x90, 0x68, 0x00, 0xE7, 0x61, 0x26, 0x91, 0x26, 0x69, 0x54, 0x57, + 0x53, 0x75, 0x10, 0x56, 0xCC, 0xC0, 0x17, 0x00, 0x66, 0x75, 0x91, 0x76, 0x8A, 0x9D, 0xFE, 0xFF, + 0xF2, 0xDE, 0x2F, 0xF5, 0x0C, 0x00, 0x13, 0xFF, 0xCC, 0xF0, 0x16, 0x00, 0xDA, 0xC5, 0xFE, 0xFF, + 0x38, 0x91, 0x18, 0x01, 0x38, 0xE1, 0x10, 0x01, 0x33, 0xFF, 0x26, 0xF9, 0x43, 0xFF, 0x26, 0xFF, + 0x26, 0xEF, 0x20, 0x9E, 0x06, 0xE9, 0x38, 0x91, 0x00, 0x01, 0x36, 0xE9, 0xB9, 0xE1, 0x2C, 0x01, + 0x06, 0x9E, 0xC3, 0xEE, 0x32, 0x02, 0x04, 0x90, 0x0C, 0xE0, 0x28, 0x08, 0x26, 0xEF, 0xA1, 0x92, + 0x20, 0x9E, 0x06, 0xE9, 0x38, 0x91, 0x00, 0x01, 0x36, 0xE9, 0xB9, 0xE1, 0x2C, 0x01, 0x06, 0x9E, + 0xC3, 0xEE, 0x32, 0x02, 0x04, 0x90, 0xA1, 0x93, 0x14, 0x92, 0xC6, 0x69, 0x8A, 0x9F, 0xFE, 0xFF, + 0xC4, 0x62, 0x8A, 0x9C, 0xFE, 0xFF, 0xC6, 0x59, 0x8A, 0x99, 0xFE, 0xFF, 0xC4, 0x52, 0x8A, 0x96, + 0xFE, 0xFF, 0x38, 0xE1, 0x14, 0x01, 0x38, 0x91, 0x1C, 0x01, 0x26, 0xFE, 0x70, 0xFF, 0xC6, 0xF9, + 0x0A, 0x8D, 0xFE, 0xFF, 0xC6, 0x6B, 0x92, 0x03, 0x64, 0x72, 0xF2, 0x04, 0xC4, 0x61, 0x92, 0x02, + 0x64, 0x74, 0xC6, 0x5B, 0x92, 0x04, 0x64, 0x78, 0xFA, 0x81, 0xFE, 0xFF, 0xC4, 0x51, 0x9A, 0x7E, + 0xFE, 0xFF, 0x6C, 0x70, 0x10, 0x00, 0xFA, 0x7A, 0xFE, 0xFF, 0x24, 0xD1, 0x13, 0xDD, 0xFA, 0xBC, + 0xFD, 0xFF, 0xCC, 0x70, 0xF9, 0x00, 0xD2, 0x08, 0x24, 0x71, 0xF2, 0x04, 0xC4, 0x60, 0x82, 0x04, + 0x04, 0x71, 0x99, 0x78, 0xDD, 0x00, 0x0C, 0x20, 0xE8, 0x00, 0x0C, 0x40, 0x12, 0x00, 0x26, 0x21, + 0x04, 0x30, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x98, 0x1F, 0x03, 0x14, 0x41, 0x26, 0x49, + 0x08, 0xB0, 0xE4, 0xFF, 0x08, 0xA0, 0xA9, 0x00, 0xB9, 0x41, 0x04, 0x01, 0x04, 0xE0, 0x2C, 0xB0, + 0xDC, 0x30, 0x2C, 0xA0, 0xDC, 0xF1, 0x04, 0x71, 0x38, 0x41, 0x04, 0x01, 0x06, 0x6E, 0xC6, 0xE4, + 0x32, 0x44, 0x06, 0xCE, 0xD7, 0xC2, 0x24, 0xE1, 0x0C, 0xF0, 0xE8, 0x00, 0x26, 0xC8, 0x43, 0xEE, + 0x26, 0xF1, 0x2C, 0xC0, 0x5C, 0x01, 0x06, 0xDE, 0x26, 0x6F, 0xC6, 0xD9, 0x32, 0xEE, 0x06, 0x5D, + 0xD7, 0x52, 0x26, 0x58, 0x78, 0x45, 0x70, 0x01, 0x78, 0x2C, 0x14, 0x00, 0x2C, 0x50, 0x5C, 0x01, + 0x78, 0x55, 0x16, 0x00, 0x36, 0x24, 0x78, 0x4C, 0x16, 0x00, 0xB9, 0x61, 0x24, 0x01, 0x06, 0x32, + 0x36, 0x45, 0xB9, 0x71, 0x28, 0x01, 0xB9, 0x41, 0x20, 0x01, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x41, + 0x20, 0x01, 0x06, 0x52, 0x06, 0x34, 0x06, 0x24, 0xB9, 0x51, 0x20, 0x01, 0x6B, 0x13, 0x00, 0x00, + 0x38, 0x51, 0x20, 0x01, 0x38, 0x61, 0x24, 0x01, 0x38, 0x71, 0x28, 0x01, 0x26, 0x25, 0x2F, 0x5B, + 0x02, 0x00, 0xC6, 0x5A, 0xD2, 0x07, 0x0C, 0x50, 0xE8, 0x00, 0x26, 0x51, 0x91, 0x76, 0x26, 0x5D, + 0x91, 0x75, 0x24, 0xD1, 0x43, 0xDD, 0xF2, 0xCA, 0x04, 0x60, 0x06, 0x58, 0x18, 0x78, 0x1F, 0x03, + 0xC6, 0x67, 0x32, 0x16, 0x0C, 0x70, 0xE8, 0x00, 0x26, 0x71, 0x26, 0x76, 0x10, 0x77, 0xC4, 0x71, + 0x92, 0x0C, 0x06, 0x76, 0xD7, 0x72, 0x26, 0x75, 0x28, 0x47, 0x74, 0x01, 0xA9, 0x47, 0x70, 0x01, + 0x28, 0x47, 0x76, 0x01, 0xA9, 0x47, 0x72, 0x01, 0x24, 0x61, 0x43, 0x66, 0xF2, 0xE8, 0x58, 0xC1, + 0x40, 0x01, 0x58, 0x81, 0x30, 0x01, 0x2C, 0x10, 0x50, 0x01, 0xE1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0x28, 0xE7, 0x20, 0x03, 0x68, 0x27, 0x1F, 0x03, + 0xD1, 0x81, 0x04, 0x60, 0x14, 0x41, 0x99, 0x07, 0x24, 0x03, 0x43, 0x9E, 0x06, 0x36, 0x06, 0x54, + 0x0C, 0xB0, 0xB4, 0x16, 0x0C, 0xA0, 0x80, 0x02, 0x2F, 0xF6, 0x06, 0x00, 0x26, 0xFB, 0x70, 0xFF, + 0x06, 0xDB, 0x26, 0xFF, 0x26, 0xFA, 0x70, 0xFF, 0x06, 0xCA, 0xC6, 0xF9, 0x22, 0x09, 0xC6, 0x3F, + 0x32, 0x07, 0x04, 0x81, 0x26, 0x82, 0x06, 0x52, 0x33, 0x46, 0x23, 0x3F, 0x33, 0x28, 0x24, 0x61, + 0xC4, 0x63, 0x92, 0xEB, 0xA9, 0x37, 0x1A, 0x03, 0x04, 0x60, 0x43, 0x33, 0x2F, 0x26, 0x06, 0x00, + 0x26, 0x2D, 0x20, 0x22, 0x26, 0x22, 0x26, 0x2C, 0xF0, 0x22, 0x02, 0x06, 0x43, 0xF6, 0xC6, 0x4F, + 0x82, 0x03, 0x36, 0x32, 0x43, 0x33, 0x24, 0x61, 0xC4, 0x63, 0x92, 0xF1, 0xC6, 0x3E, 0x32, 0x04, + 0xA9, 0x07, 0x1A, 0x03, 0xF2, 0x1D, 0x14, 0x61, 0xC6, 0x56, 0x82, 0x1A, 0x98, 0x67, 0xAA, 0x04, + 0x82, 0x0B, 0x18, 0x67, 0xA8, 0x04, 0x99, 0x57, 0x22, 0x03, 0x99, 0x67, 0x23, 0x03, 0x04, 0x61, + 0x99, 0x67, 0x24, 0x03, 0xF2, 0x0D, 0x04, 0x31, 0x06, 0x63, 0x53, 0x64, 0x18, 0x47, 0x23, 0x03, + 0x99, 0x57, 0x22, 0x03, 0x99, 0x37, 0x24, 0x03, 0x66, 0x64, 0x99, 0x67, 0x23, 0x03, 0x58, 0xC1, + 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, + 0x0C, 0xE0, 0xFC, 0x0A, 0x98, 0x6E, 0x1F, 0x03, 0x06, 0x7E, 0x82, 0x24, 0x98, 0x5E, 0x24, 0x03, + 0x82, 0x21, 0x28, 0x4E, 0x18, 0x03, 0x28, 0x5E, 0x1A, 0x03, 0xC6, 0x45, 0xD2, 0x03, 0xC4, 0x61, + 0xC2, 0x0B, 0x14, 0x51, 0x99, 0x57, 0x22, 0x03, 0x99, 0x07, 0x23, 0x03, 0x99, 0x67, 0x1C, 0x03, + 0x99, 0x07, 0x24, 0x03, 0xF2, 0x0F, 0x0C, 0x20, 0x58, 0x0C, 0x04, 0x30, 0x0C, 0x40, 0x20, 0x00, + 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x7E, 0x24, 0x03, 0x99, 0x0E, 0x1F, 0x03, 0x99, 0x7E, + 0x1C, 0x03, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0xEB, 0x7A, 0x02, 0x00, + 0x2B, 0x4B, 0x02, 0x00, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0x6E, 0x1F, 0x03, 0x18, 0x7E, 0x24, 0x03, + 0x26, 0x76, 0x13, 0x77, 0x99, 0x7E, 0x1C, 0x03, 0x99, 0x7E, 0x1D, 0x03, 0x6B, 0x81, 0x02, 0x00, + 0xEB, 0x1A, 0x02, 0x00, 0x18, 0x7E, 0x1C, 0x03, 0x99, 0x7E, 0x1E, 0x03, 0x40, 0xE1, 0x24, 0x18, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x18, 0x00, 0xC1, 0xA1, 0x0C, 0xB0, 0xFC, 0x0A, 0x18, 0xAB, + 0x1F, 0x03, 0xD9, 0xC1, 0x08, 0x00, 0x04, 0xE0, 0x06, 0xCE, 0x06, 0xDB, 0x18, 0x4B, 0x1F, 0x03, + 0xC6, 0xC4, 0xB2, 0x1A, 0x06, 0x3C, 0xD7, 0x32, 0x26, 0x3D, 0x2C, 0x30, 0x5C, 0x01, 0xA8, 0x73, + 0x1C, 0x00, 0x82, 0x0F, 0xC6, 0xCE, 0x82, 0x0B, 0x06, 0x2E, 0xD7, 0x22, 0x26, 0x2D, 0x2C, 0x20, + 0x5C, 0x01, 0x0C, 0x40, 0x20, 0x00, 0x0C, 0xF0, 0x28, 0x01, 0xF1, 0xF0, 0x24, 0xE1, 0x13, 0xEE, + 0x24, 0xC1, 0x13, 0xCC, 0xF2, 0xE4, 0x06, 0x2E, 0xD7, 0x22, 0x26, 0x2D, 0x36, 0x4E, 0x2C, 0x20, + 0x5C, 0x01, 0x04, 0x30, 0xD7, 0x42, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x18, 0x7D, 0x1C, 0x03, + 0x99, 0xED, 0x1F, 0x03, 0x3F, 0xAA, 0x07, 0x00, 0x26, 0xEA, 0x99, 0xED, 0x1C, 0x03, 0x58, 0xC1, + 0x08, 0x00, 0x40, 0xA1, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x38, 0x70, 0xB0, 0x16, 0x34, 0x14, 0xB1, 0xF1, 0x28, 0x47, 0x32, 0x00, 0x04, 0x70, 0x08, 0x60, + 0x00, 0x30, 0x06, 0x27, 0x0C, 0x30, 0xB4, 0x16, 0x2C, 0x60, 0x00, 0x49, 0x2F, 0x53, 0x07, 0x00, + 0x20, 0x55, 0x0C, 0xF0, 0xFF, 0x0F, 0x57, 0x51, 0x26, 0x56, 0x30, 0x55, 0x56, 0xF5, 0x77, 0x58, + 0x5C, 0x50, 0xFF, 0x0F, 0x3F, 0x55, 0x0F, 0x00, 0xC6, 0x54, 0x22, 0x02, 0x04, 0x21, 0x24, 0x72, + 0xC4, 0x76, 0x92, 0xED, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x98, 0x70, 0xD7, 0x16, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x82, 0x06, 0x08, 0x70, 0x00, 0x80, 0x28, 0xD7, 0xB2, 0xDC, + 0xF2, 0x05, 0x38, 0x70, 0xB0, 0x16, 0x28, 0xD7, 0x28, 0x00, 0xCB, 0x3B, 0x00, 0x00, 0xA9, 0x20, + 0x14, 0x0E, 0x23, 0x22, 0xC6, 0x2D, 0x04, 0xE0, 0xB2, 0x06, 0x8B, 0x8A, 0x02, 0x00, 0x14, 0xE1, + 0x26, 0xE2, 0xF7, 0xEF, 0x6B, 0x71, 0x03, 0x00, 0x06, 0x2E, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x24, 0x00, 0xD9, 0xC1, 0x14, 0x00, 0x38, 0xE0, 0xB0, 0x16, + 0xD9, 0x81, 0x04, 0x00, 0x06, 0xD2, 0x04, 0x30, 0x06, 0x2C, 0x0C, 0x20, 0xF0, 0x0B, 0x0C, 0x40, + 0x62, 0x00, 0x0C, 0x90, 0xFC, 0x0A, 0x0C, 0x80, 0x22, 0x01, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, + 0x0C, 0xC0, 0xF0, 0x0B, 0x26, 0x89, 0x06, 0xBD, 0x06, 0xAD, 0x30, 0x3A, 0x18, 0x2E, 0x12, 0x00, + 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, 0x00, 0x00, 0x06, 0x72, 0x38, 0x3A, + 0xC4, 0x00, 0x18, 0x2E, 0x13, 0x00, 0xB1, 0x71, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, + 0xCB, 0x14, 0x00, 0x00, 0x98, 0x3B, 0x88, 0x01, 0x30, 0x71, 0x06, 0x52, 0x82, 0x07, 0x06, 0x27, + 0xB1, 0x51, 0xAB, 0x15, 0x00, 0x00, 0x30, 0x51, 0x06, 0x72, 0x28, 0x6E, 0x1A, 0x00, 0xC6, 0x76, + 0x02, 0x02, 0x06, 0x76, 0x06, 0x25, 0x04, 0x3E, 0xB1, 0x71, 0xAB, 0x15, 0x00, 0x00, 0x28, 0x6E, + 0x1C, 0x00, 0x30, 0x71, 0xC6, 0x26, 0x02, 0x02, 0x06, 0x26, 0x18, 0x3E, 0x15, 0x00, 0x3F, 0x22, + 0x07, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0xA1, 0x2C, + 0x24, 0xC2, 0xC6, 0xC8, 0x24, 0xA4, 0x24, 0xB1, 0x92, 0xC1, 0x06, 0xA9, 0x0C, 0xC0, 0x20, 0x0C, + 0x2C, 0xA0, 0x40, 0x01, 0x06, 0xBD, 0x38, 0x3B, 0x60, 0x00, 0x18, 0x2E, 0x10, 0x00, 0x6B, 0x13, + 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, 0x00, 0x00, 0x38, 0x3B, 0x24, 0x01, 0x06, 0x92, + 0x18, 0x2E, 0x11, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, 0x00, 0x00, + 0x98, 0x3D, 0xA0, 0x01, 0x06, 0x82, 0x82, 0x05, 0x06, 0x29, 0xAB, 0x15, 0x00, 0x00, 0x06, 0x92, + 0x28, 0x7E, 0x16, 0x00, 0xC6, 0x97, 0x02, 0x02, 0x06, 0x97, 0x06, 0x28, 0x0C, 0x30, 0x17, 0x00, + 0xAB, 0x15, 0x00, 0x00, 0x28, 0x7E, 0x18, 0x00, 0xC6, 0x27, 0x02, 0x02, 0x06, 0x27, 0x18, 0x3E, + 0x14, 0x00, 0x3F, 0x22, 0x09, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, + 0x00, 0x00, 0xA1, 0x2C, 0x24, 0xC2, 0xC6, 0xCA, 0x24, 0xB4, 0x24, 0xD1, 0x92, 0xC5, 0x58, 0xC1, + 0x14, 0x00, 0x58, 0x81, 0x04, 0x00, 0x2C, 0x10, 0x24, 0x00, 0xE1, 0xF0, 0xE1, 0xF0, 0x00, 0x00, + 0x04, 0x20, 0xE1, 0xF0, 0x3C, 0x10, 0x5C, 0x00, 0xD9, 0x81, 0x3C, 0x00, 0x38, 0x40, 0xB0, 0x16, + 0xD9, 0xC1, 0x4C, 0x00, 0x0C, 0x60, 0xC0, 0x00, 0x26, 0x64, 0x20, 0x66, 0x18, 0xA4, 0x79, 0x00, + 0xB9, 0x03, 0x0C, 0x00, 0x0C, 0xC0, 0xFC, 0x0A, 0x06, 0xD2, 0x28, 0x2C, 0x06, 0x03, 0xB9, 0x03, + 0x08, 0x00, 0x06, 0x76, 0x26, 0x76, 0xB9, 0x03, 0x04, 0x00, 0xB1, 0x03, 0x23, 0x77, 0x06, 0xE3, + 0x26, 0x22, 0x04, 0x33, 0xB9, 0x61, 0x04, 0x00, 0xB9, 0x71, 0x18, 0x00, 0xB9, 0x41, 0x10, 0x00, + 0x99, 0x0C, 0x5B, 0x01, 0xAB, 0x15, 0x00, 0x00, 0xB9, 0x21, 0x1C, 0x00, 0x28, 0x2C, 0x14, 0x03, + 0x06, 0x3A, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xCB, 0x14, 0x00, 0x00, 0x0C, 0x70, + 0x28, 0x08, 0x38, 0xB0, 0xB0, 0x16, 0xB9, 0xD1, 0x08, 0x00, 0x04, 0x30, 0x3C, 0x70, 0x30, 0x00, + 0x23, 0x22, 0x06, 0xFD, 0x06, 0x63, 0x06, 0x53, 0x06, 0xA3, 0xB9, 0x71, 0x14, 0x00, 0xB9, 0x21, + 0x30, 0x00, 0x38, 0x81, 0x14, 0x00, 0xB9, 0xD1, 0x0C, 0x00, 0x26, 0x83, 0x04, 0x71, 0xB1, 0x81, + 0x0C, 0x20, 0x80, 0x02, 0x0C, 0x40, 0x54, 0x05, 0x14, 0x8C, 0x53, 0x7A, 0x26, 0x23, 0x26, 0x43, + 0x26, 0x8A, 0xB9, 0x71, 0x20, 0x00, 0x06, 0x9D, 0x04, 0x70, 0xB9, 0x21, 0x24, 0x00, 0xB9, 0x41, + 0x28, 0x00, 0xB9, 0x81, 0x2C, 0x00, 0x38, 0x21, 0x24, 0x00, 0x38, 0x81, 0x28, 0x00, 0x2F, 0x47, + 0x07, 0x00, 0x26, 0x24, 0x26, 0x48, 0x20, 0x44, 0x20, 0x22, 0xC4, 0xA1, 0x36, 0x24, 0x23, 0x22, + 0x43, 0x42, 0xB9, 0x41, 0x38, 0x00, 0x16, 0x22, 0x43, 0x22, 0x12, 0x1A, 0xC4, 0x71, 0x12, 0x07, + 0x28, 0x8B, 0xCA, 0x00, 0xC6, 0x48, 0x22, 0x45, 0x64, 0x51, 0xF2, 0x43, 0xCC, 0x70, 0x14, 0x00, + 0x02, 0x09, 0x28, 0x8B, 0xCA, 0x00, 0x38, 0x41, 0x38, 0x00, 0xC6, 0x48, 0x22, 0x3A, 0x64, 0x52, + 0xF2, 0x38, 0x28, 0x8B, 0xCC, 0x00, 0xC6, 0x28, 0x22, 0x34, 0x64, 0x61, 0xF2, 0x32, 0x38, 0x81, + 0x2C, 0x00, 0xC4, 0x81, 0xD2, 0x1E, 0xC4, 0x71, 0x12, 0x09, 0x28, 0x8B, 0xCA, 0x00, 0x38, 0x41, + 0x38, 0x00, 0xC6, 0x48, 0x22, 0x26, 0x64, 0x54, 0xF2, 0x24, 0x1C, 0x80, 0x15, 0x00, 0x26, 0x87, + 0xC4, 0x81, 0xD2, 0x09, 0x28, 0x8B, 0xCA, 0x00, 0x38, 0x41, 0x38, 0x00, 0xC6, 0x48, 0x22, 0x19, + 0x64, 0x58, 0xF2, 0x17, 0x28, 0x8B, 0xCC, 0x00, 0xC6, 0x28, 0x22, 0x13, 0x64, 0x62, 0xF2, 0x11, + 0xC4, 0x71, 0x12, 0x07, 0x28, 0x8B, 0xCC, 0x00, 0xC6, 0x28, 0x22, 0x0B, 0x64, 0x64, 0xF2, 0x09, + 0xCC, 0x70, 0x14, 0x00, 0x02, 0x06, 0x28, 0x8B, 0xCC, 0x00, 0xC6, 0x28, 0x22, 0x02, 0x64, 0x68, + 0xB8, 0x81, 0x38, 0x00, 0x02, 0x76, 0x30, 0x41, 0x38, 0x81, 0x1C, 0x00, 0x78, 0x24, 0x30, 0x00, + 0xC6, 0x28, 0x02, 0x37, 0x38, 0x8D, 0xC0, 0x00, 0x38, 0x41, 0x38, 0x00, 0x26, 0x84, 0xB9, 0x8D, + 0xC0, 0x00, 0x28, 0x8C, 0x06, 0x03, 0xC6, 0x28, 0x02, 0x44, 0xC4, 0x70, 0x82, 0x07, 0x30, 0x41, + 0x2C, 0x40, 0x2E, 0x00, 0x70, 0x44, 0xC6, 0x42, 0x12, 0x3C, 0x30, 0x41, 0x2C, 0x40, 0x32, 0x00, + 0x70, 0x44, 0xC6, 0x42, 0x32, 0x36, 0xC4, 0xA0, 0x82, 0x07, 0x30, 0x41, 0x70, 0x44, 0xC6, 0x42, + 0x12, 0x30, 0xC4, 0xAD, 0x82, 0x07, 0x30, 0x41, 0x2C, 0x40, 0x60, 0x00, 0x70, 0x44, 0xC6, 0x42, + 0x32, 0x28, 0x38, 0x8C, 0xFC, 0x02, 0x04, 0x21, 0x53, 0x27, 0x66, 0x28, 0xB9, 0x2C, 0xFC, 0x02, + 0x38, 0x81, 0x20, 0x00, 0x38, 0x2C, 0x00, 0x03, 0x66, 0x28, 0xB9, 0x2C, 0x00, 0x03, 0xF2, 0x19, + 0x38, 0x41, 0x0C, 0x00, 0x38, 0x81, 0x08, 0x00, 0x18, 0x24, 0x88, 0x01, 0x24, 0x21, 0x99, 0x24, + 0x88, 0x01, 0x18, 0x28, 0xA0, 0x01, 0x38, 0x41, 0x38, 0x00, 0x24, 0x21, 0x99, 0x28, 0xA0, 0x01, + 0x30, 0x29, 0x26, 0x24, 0xB1, 0x29, 0x38, 0x2F, 0x60, 0x00, 0x26, 0x24, 0xB9, 0x2F, 0x60, 0x00, + 0x38, 0x81, 0x38, 0x00, 0x38, 0x21, 0x30, 0x00, 0xC6, 0x82, 0x02, 0x06, 0x18, 0x2C, 0x25, 0x03, + 0x24, 0x21, 0x99, 0x2C, 0x25, 0x03, 0x38, 0x41, 0x38, 0x00, 0x38, 0x81, 0x04, 0x00, 0xC6, 0x48, + 0x02, 0x2A, 0x38, 0x81, 0x18, 0x00, 0x38, 0x2E, 0x08, 0x00, 0xC6, 0x48, 0x24, 0x21, 0xB9, 0x2E, + 0x08, 0x00, 0x02, 0x21, 0x38, 0x4E, 0x0C, 0x00, 0x24, 0x41, 0xB9, 0x4E, 0x0C, 0x00, 0xF2, 0x1B, + 0x38, 0x49, 0xC4, 0x00, 0x26, 0x42, 0xB9, 0x49, 0xC4, 0x00, 0x38, 0x4F, 0x24, 0x01, 0x26, 0x42, + 0xB9, 0x4F, 0x24, 0x01, 0x38, 0x41, 0x04, 0x00, 0xC6, 0x24, 0x02, 0x0D, 0x38, 0x81, 0x18, 0x00, + 0x30, 0x4E, 0xC6, 0x28, 0x24, 0x41, 0xB1, 0x4E, 0x02, 0x06, 0x38, 0x4E, 0x04, 0x00, 0x24, 0x41, + 0xB9, 0x4E, 0x04, 0x00, 0x38, 0x21, 0x0C, 0x00, 0x30, 0x41, 0x24, 0x71, 0xCC, 0x70, 0x17, 0x00, + 0x24, 0x21, 0x24, 0x42, 0xB9, 0x21, 0x0C, 0x00, 0xB1, 0x41, 0x24, 0x94, 0x9A, 0x05, 0xFF, 0xFF, + 0x38, 0x7F, 0x60, 0x00, 0x38, 0x4D, 0xC0, 0x00, 0x24, 0xA1, 0x26, 0x74, 0xB9, 0x7D, 0xC0, 0x00, + 0x38, 0x7F, 0x24, 0x01, 0x38, 0x4D, 0x84, 0x01, 0xC4, 0xAE, 0x26, 0x74, 0xB9, 0x7D, 0x84, 0x01, + 0x38, 0x71, 0x08, 0x00, 0x24, 0xF4, 0x24, 0x71, 0xB9, 0x71, 0x08, 0x00, 0x2C, 0x30, 0x30, 0x00, + 0x9A, 0xD1, 0xFE, 0xFF, 0x04, 0x71, 0xD6, 0x75, 0x82, 0x08, 0x54, 0x65, 0xC4, 0x60, 0x82, 0x13, + 0x04, 0x71, 0x99, 0x7C, 0x5B, 0x01, 0xF2, 0x0F, 0x04, 0x72, 0xD6, 0x75, 0x82, 0x03, 0x54, 0x69, + 0xF2, 0xF6, 0x04, 0x74, 0xD6, 0x75, 0x82, 0x03, 0x54, 0x66, 0xF2, 0xF1, 0xD4, 0x58, 0x82, 0x03, + 0x54, 0x6A, 0xF2, 0xED, 0xCB, 0x73, 0x03, 0x00, 0x38, 0x81, 0x10, 0x00, 0x28, 0x78, 0x38, 0x00, + 0x58, 0x81, 0x3C, 0x00, 0xA9, 0x7C, 0x14, 0x00, 0x58, 0xC1, 0x4C, 0x00, 0x2C, 0x10, 0x5C, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x0C, 0xE0, 0x17, 0x00, 0x0C, 0xD0, + 0x80, 0x02, 0x06, 0x2E, 0xEB, 0x6F, 0x03, 0x00, 0xC4, 0x20, 0x92, 0x05, 0x2F, 0x7E, 0x0E, 0x00, + 0x26, 0x7D, 0xA1, 0x07, 0x2C, 0xE0, 0x18, 0x00, 0xCC, 0xE0, 0x67, 0x01, 0x92, 0xF3, 0x6B, 0x71, + 0x03, 0x00, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0xCC, 0x01, + 0x0C, 0x40, 0xB8, 0x01, 0x06, 0x21, 0x04, 0x30, 0xB9, 0xF1, 0xC8, 0x01, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x0C, 0x30, 0xB8, 0x01, 0x26, 0x31, 0x06, 0x21, 0xAB, 0x99, 0x02, 0x00, 0xAB, 0xB3, + 0x02, 0x00, 0x06, 0x21, 0x2B, 0x8F, 0x02, 0x00, 0x38, 0x21, 0x84, 0x01, 0x0C, 0x30, 0xB8, 0x01, + 0x26, 0x31, 0xCB, 0xC2, 0x02, 0x00, 0x38, 0xF1, 0xC8, 0x01, 0x2C, 0x10, 0xCC, 0x01, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xD1, 0x81, 0x0C, 0x30, 0x20, 0x0C, 0x04, 0x60, + 0x0C, 0xC0, 0x80, 0x02, 0x0C, 0xE0, 0x54, 0x05, 0x0C, 0xA0, 0xFC, 0x0A, 0x70, 0xB3, 0x04, 0x70, + 0x06, 0x57, 0x2F, 0xDC, 0x06, 0x00, 0x2F, 0xFE, 0x06, 0x00, 0x2F, 0x27, 0x0D, 0x00, 0x2F, 0x47, + 0x0F, 0x00, 0x70, 0x92, 0x70, 0x44, 0xCC, 0x50, 0x17, 0x00, 0x3F, 0x44, 0x09, 0x00, 0x36, 0x4B, + 0x82, 0x06, 0x2F, 0x9A, 0x07, 0x00, 0x78, 0x99, 0xF4, 0x00, 0x36, 0x49, 0x86, 0x44, 0x32, 0x02, + 0x04, 0x40, 0x24, 0x51, 0xCC, 0x50, 0x18, 0x00, 0xA1, 0x42, 0x24, 0x72, 0x92, 0xE7, 0x2C, 0x60, + 0x30, 0x00, 0xCC, 0x60, 0xA0, 0x02, 0x24, 0x32, 0x92, 0xDA, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, + 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xC4, 0x20, 0x0C, 0x70, + 0xFC, 0x0A, 0x38, 0x67, 0x0C, 0x00, 0x82, 0x15, 0x64, 0x61, 0xB9, 0x67, 0x0C, 0x00, 0x08, 0x70, + 0x00, 0x80, 0x2C, 0x70, 0x24, 0xE0, 0xB9, 0x70, 0xB0, 0x16, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, + 0x08, 0xDE, 0xB9, 0x70, 0xAC, 0x16, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0xC8, 0xDC, 0xF2, 0x15, + 0x14, 0x22, 0x56, 0x62, 0xB9, 0x67, 0x0C, 0x00, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0x48, 0xDF, + 0xB9, 0x70, 0xB0, 0x16, 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0xA8, 0xDE, 0xB9, 0x70, 0xAC, 0x16, + 0x08, 0x70, 0x00, 0x80, 0x2C, 0x70, 0x68, 0xDD, 0xB9, 0x70, 0xA8, 0x16, 0xE1, 0xF0, 0x00, 0x00, + 0x0C, 0x70, 0xFC, 0x0A, 0x99, 0x07, 0x59, 0x01, 0x99, 0x07, 0x58, 0x01, 0xE1, 0xF0, 0x00, 0x00, + 0x38, 0x60, 0xB0, 0x16, 0x0C, 0x70, 0xFC, 0x0A, 0x18, 0x56, 0xCE, 0x00, 0x18, 0x37, 0xDD, 0x00, + 0x18, 0x46, 0xC2, 0x00, 0xC6, 0x35, 0x04, 0x60, 0xD2, 0x0E, 0x98, 0x57, 0x5B, 0x01, 0x82, 0x0B, + 0x98, 0x50, 0xD6, 0x16, 0x92, 0x08, 0x38, 0x67, 0x0C, 0x00, 0x6C, 0x60, 0x00, 0x08, 0xB9, 0x67, + 0x0C, 0x00, 0x04, 0x61, 0x18, 0x57, 0x56, 0x01, 0xC6, 0x54, 0xB2, 0x03, 0xC4, 0x60, 0x82, 0x15, + 0x38, 0x60, 0xB8, 0x15, 0xCC, 0x60, 0x1F, 0x03, 0xD2, 0x17, 0x98, 0x50, 0xE0, 0x16, 0x92, 0x14, + 0x38, 0x57, 0x0C, 0x00, 0x6C, 0x50, 0x00, 0x04, 0xB9, 0x57, 0x0C, 0x00, 0x04, 0x71, 0x99, 0x70, + 0xE8, 0x16, 0x99, 0x70, 0xE0, 0x16, 0xF2, 0x08, 0x38, 0x67, 0x0C, 0x00, 0x1C, 0x50, 0x01, 0x04, + 0x56, 0x65, 0xB9, 0x67, 0x0C, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x28, 0x00, 0xD9, 0xC1, 0x18, 0x00, + 0xD9, 0x81, 0x08, 0x00, 0x0C, 0xE0, 0xFC, 0x0A, 0x38, 0xDE, 0x0C, 0x00, 0xD4, 0xD1, 0x06, 0xC3, + 0x38, 0x90, 0xB0, 0x16, 0x82, 0x0A, 0x04, 0x62, 0x04, 0x80, 0x0C, 0xA0, 0x14, 0x00, 0x0C, 0xB0, + 0x23, 0x00, 0x0C, 0x50, 0xFA, 0x00, 0xF2, 0x08, 0x04, 0x8A, 0x04, 0x61, 0x06, 0xA8, 0x0C, 0xB0, + 0x14, 0x00, 0x0C, 0x50, 0x96, 0x00, 0x0C, 0x30, 0x42, 0x01, 0xB1, 0x51, 0xB9, 0x61, 0x04, 0x00, + 0xCB, 0x14, 0x00, 0x00, 0x30, 0x51, 0x38, 0x61, 0x04, 0x00, 0xC6, 0x25, 0x04, 0x71, 0xD2, 0x19, + 0x38, 0x5C, 0x04, 0x00, 0xC6, 0x5B, 0x02, 0x05, 0x38, 0x5C, 0x0C, 0x00, 0xC6, 0x5B, 0x22, 0x11, + 0x38, 0x3C, 0x08, 0x00, 0x30, 0xBC, 0x06, 0x26, 0x6B, 0x13, 0x00, 0x00, 0xC6, 0xB2, 0x02, 0x04, + 0xC6, 0xB8, 0x04, 0x71, 0x12, 0x06, 0xC6, 0xBA, 0x04, 0x71, 0x12, 0x02, 0x04, 0x70, 0x23, 0x77, + 0x98, 0x60, 0xE4, 0x16, 0x82, 0x04, 0xC4, 0xD0, 0x92, 0x02, 0x06, 0x7D, 0x38, 0x60, 0xB8, 0x15, + 0xCC, 0x60, 0x1F, 0x03, 0xD2, 0x24, 0xC4, 0x70, 0x82, 0x10, 0x18, 0x7E, 0x56, 0x01, 0xCC, 0x70, + 0xFF, 0x00, 0x82, 0x04, 0x24, 0x71, 0x99, 0x7E, 0x56, 0x01, 0x98, 0x7E, 0x57, 0x01, 0x82, 0x17, + 0x34, 0x71, 0x99, 0x7E, 0x57, 0x01, 0xF2, 0x13, 0x18, 0x7E, 0x57, 0x01, 0x24, 0x71, 0x13, 0x77, + 0x99, 0x7E, 0x57, 0x01, 0x18, 0x69, 0xC3, 0x00, 0xC6, 0x67, 0x92, 0x09, 0x98, 0x7E, 0x56, 0x01, + 0x99, 0x0E, 0x57, 0x01, 0x82, 0x04, 0x34, 0x71, 0x99, 0x7E, 0x56, 0x01, 0x58, 0xC1, 0x18, 0x00, + 0x58, 0x81, 0x08, 0x00, 0x2C, 0x10, 0x28, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x18, 0x60, 0xDB, 0x16, 0x04, 0x70, 0xC4, 0x61, 0x92, 0x05, 0x08, 0x70, + 0x00, 0x80, 0x18, 0x77, 0x3B, 0xDC, 0x70, 0x52, 0xC6, 0x57, 0x32, 0x03, 0xA1, 0x72, 0xF2, 0x07, + 0x0C, 0x60, 0x7F, 0x07, 0x36, 0x67, 0xC6, 0x56, 0x02, 0x02, 0xA1, 0x62, 0x78, 0x62, 0x02, 0x00, + 0xC6, 0x67, 0x22, 0x07, 0x0C, 0x50, 0x37, 0x04, 0x3F, 0x77, 0x05, 0x00, 0xC6, 0x67, 0x02, 0x03, + 0xA9, 0x72, 0x02, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0x0C, 0x60, 0xD4, 0x01, + 0x26, 0x67, 0x99, 0x07, 0x6C, 0x07, 0x2C, 0x70, 0x24, 0x00, 0xC6, 0x76, 0x92, 0xFB, 0xE1, 0xF0, + 0x3C, 0x10, 0x20, 0x00, 0xD1, 0x81, 0x06, 0x74, 0x06, 0x92, 0x06, 0x24, 0xD7, 0x72, 0xD7, 0x21, + 0xD9, 0xC1, 0x10, 0x00, 0x26, 0x27, 0x0C, 0xE0, 0xFC, 0x0A, 0x26, 0x24, 0x06, 0xA3, 0x0C, 0x30, + 0x64, 0x00, 0x06, 0x86, 0x06, 0xB5, 0x06, 0xD4, 0xAB, 0x15, 0x00, 0x00, 0xB9, 0x2E, 0x54, 0x07, + 0x06, 0x7B, 0x06, 0x2B, 0x57, 0x72, 0x57, 0x21, 0x26, 0x27, 0x36, 0x2B, 0x0C, 0x30, 0x64, 0x00, + 0x26, 0x22, 0xAB, 0x15, 0x00, 0x00, 0xB9, 0x2E, 0x58, 0x07, 0x06, 0x78, 0x06, 0x28, 0xD7, 0x72, + 0xD7, 0x21, 0x78, 0xC1, 0x20, 0x00, 0x26, 0x27, 0x0C, 0x30, 0x64, 0x00, 0x26, 0x28, 0xAB, 0x15, + 0x00, 0x00, 0xB9, 0x2E, 0x5C, 0x07, 0x06, 0x7C, 0x06, 0x2C, 0x57, 0x72, 0x57, 0x21, 0x26, 0x27, + 0x36, 0x2C, 0x26, 0x22, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0xB9, 0x2E, 0x60, 0x07, + 0x3F, 0x2D, 0x08, 0x00, 0xC4, 0x20, 0x06, 0xDE, 0x32, 0x02, 0x16, 0x22, 0x04, 0x33, 0xAB, 0x15, + 0x00, 0x00, 0x99, 0x2E, 0x50, 0x07, 0x3F, 0x2B, 0x0C, 0x00, 0xC4, 0x20, 0x06, 0xED, 0x32, 0x02, + 0x16, 0x22, 0x04, 0x33, 0xAB, 0x15, 0x00, 0x00, 0xC4, 0x90, 0x99, 0x2E, 0x51, 0x07, 0x92, 0x06, + 0x0C, 0x70, 0xA6, 0x00, 0xB9, 0x7D, 0x64, 0x07, 0xF2, 0x03, 0xB9, 0x9D, 0x64, 0x07, 0xC4, 0xA0, + 0x92, 0x06, 0x0C, 0x70, 0x9A, 0x00, 0xB9, 0x7D, 0x68, 0x07, 0xF2, 0x03, 0xB9, 0xAD, 0x68, 0x07, + 0xCB, 0xCC, 0x02, 0x00, 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x72, 0x70, 0x63, 0x38, 0x22, 0x0C, 0x00, 0x06, 0xE4, + 0x36, 0x26, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x38, 0x57, 0x04, 0x00, 0x43, 0x22, 0xC6, 0x65, + 0x0C, 0x60, 0xFC, 0x0A, 0x32, 0x06, 0x28, 0xD7, 0x14, 0x00, 0x28, 0x37, 0x1C, 0x00, 0xF2, 0x05, + 0x28, 0xD7, 0x16, 0x00, 0x28, 0x37, 0x1E, 0x00, 0x36, 0x3D, 0xC4, 0x30, 0x32, 0x02, 0x16, 0x33, + 0x18, 0xC6, 0x50, 0x07, 0x43, 0x33, 0xC6, 0x2C, 0x32, 0x07, 0x6B, 0x13, 0x00, 0x00, 0x06, 0x3C, + 0xAB, 0x15, 0x00, 0x00, 0x43, 0x32, 0x26, 0x3D, 0xA1, 0x3E, 0x50, 0xC1, 0x04, 0x21, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0x72, 0x78, 0x63, 0x02, 0x00, + 0x38, 0x22, 0x10, 0x00, 0x06, 0xE4, 0x36, 0x26, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x38, 0x57, + 0x08, 0x00, 0x43, 0x22, 0xC6, 0x65, 0x0C, 0x60, 0xFC, 0x0A, 0x32, 0x06, 0x28, 0xD7, 0x18, 0x00, + 0x28, 0x37, 0x20, 0x00, 0xF2, 0x05, 0x28, 0xD7, 0x1A, 0x00, 0x28, 0x37, 0x22, 0x00, 0x36, 0x3D, + 0xC4, 0x30, 0x32, 0x02, 0x16, 0x33, 0x18, 0xC6, 0x51, 0x07, 0x43, 0x33, 0xC6, 0x2C, 0x32, 0x07, + 0x6B, 0x13, 0x00, 0x00, 0x06, 0x3C, 0xAB, 0x15, 0x00, 0x00, 0x43, 0x32, 0x26, 0x3D, 0xA1, 0x3E, + 0x50, 0xC1, 0x04, 0x21, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x70, 0xD2, 0x06, 0xC2, 0xC6, 0xD3, 0x06, 0xE3, 0x22, 0x04, 0x3F, 0x23, 0x0D, 0x00, + 0xF2, 0x03, 0x3F, 0x2D, 0x03, 0x00, 0x06, 0x34, 0x43, 0x22, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, + 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0xC6, 0xDE, 0x22, 0x03, 0x26, 0xE2, 0xF2, 0x02, 0x36, 0xE2, + 0xA1, 0xEC, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x50, 0x00, + 0xD9, 0xC1, 0x40, 0x00, 0x06, 0xD3, 0x57, 0xD1, 0xD7, 0x32, 0x98, 0x60, 0xD7, 0x16, 0xD9, 0x81, + 0x30, 0x00, 0x26, 0xD3, 0x0C, 0x70, 0xFC, 0x0A, 0x2C, 0xD0, 0x1C, 0x00, 0x26, 0xD7, 0x0C, 0xC0, + 0x50, 0x07, 0x08, 0x60, 0x00, 0x80, 0x06, 0xE2, 0x26, 0xCD, 0x06, 0x97, 0x2C, 0x60, 0x0C, 0xDC, + 0x82, 0x1E, 0x0C, 0x50, 0xAA, 0x00, 0x26, 0x56, 0x20, 0x55, 0x0C, 0x70, 0xAC, 0x00, 0x26, 0x76, + 0x70, 0x77, 0xB9, 0x51, 0x0C, 0x00, 0x0C, 0x50, 0xAE, 0x00, 0x26, 0x56, 0x70, 0x55, 0xB9, 0x71, + 0x04, 0x00, 0x0C, 0x70, 0xB0, 0x00, 0x26, 0x76, 0x70, 0x77, 0xB9, 0x51, 0x08, 0x00, 0x0C, 0x50, + 0xB2, 0x00, 0x26, 0x56, 0xB9, 0x71, 0x10, 0x00, 0x70, 0x65, 0xF2, 0x1D, 0x0C, 0x70, 0x2E, 0x00, + 0x26, 0x76, 0x10, 0x77, 0x0C, 0x50, 0x30, 0x00, 0x26, 0x56, 0xB9, 0x71, 0x0C, 0x00, 0x0C, 0x70, + 0x32, 0x00, 0x70, 0x55, 0x26, 0x76, 0x70, 0x77, 0xB9, 0x51, 0x04, 0x00, 0x0C, 0x50, 0x34, 0x00, + 0x26, 0x56, 0xB9, 0x71, 0x08, 0x00, 0x0C, 0x70, 0x36, 0x00, 0x70, 0x55, 0x26, 0x76, 0x70, 0x67, + 0xB9, 0x51, 0x10, 0x00, 0x38, 0x51, 0x04, 0x00, 0xB9, 0x61, 0x14, 0x00, 0x20, 0x6E, 0x38, 0x71, + 0x08, 0x00, 0x23, 0xA5, 0x26, 0x6A, 0xA1, 0x6E, 0x28, 0x6E, 0x02, 0x00, 0x23, 0xB7, 0x26, 0x6B, + 0xA9, 0x6E, 0x02, 0x00, 0x06, 0x2E, 0xAB, 0xCA, 0x02, 0x00, 0x98, 0x6D, 0x50, 0x07, 0x9A, 0xAF, + 0x00, 0x00, 0x04, 0x61, 0x99, 0x6D, 0x50, 0x07, 0x38, 0x69, 0x64, 0x07, 0x70, 0x5E, 0x26, 0x6A, + 0x43, 0x66, 0xC6, 0x56, 0x22, 0x07, 0x0C, 0x40, 0x80, 0x07, 0x3F, 0x66, 0x04, 0x00, 0xC6, 0x56, + 0x02, 0x04, 0xB9, 0x6D, 0x54, 0x07, 0xF2, 0x03, 0xB9, 0x5D, 0x54, 0x07, 0x38, 0x49, 0x68, 0x07, + 0x78, 0x6E, 0x02, 0x00, 0x26, 0x4B, 0x43, 0x44, 0xC6, 0x64, 0x22, 0x07, 0x0C, 0x30, 0x38, 0x04, + 0x3F, 0x44, 0x03, 0x00, 0xC6, 0x64, 0x02, 0x04, 0xB9, 0x4D, 0x58, 0x07, 0xF2, 0x03, 0xB9, 0x6D, + 0x58, 0x07, 0x38, 0xAD, 0x54, 0x07, 0xB9, 0x5D, 0x5C, 0x07, 0xB9, 0x6C, 0x10, 0x00, 0x2F, 0x6A, + 0x0A, 0x00, 0x26, 0x6A, 0x06, 0x56, 0x38, 0xB9, 0x54, 0x07, 0xD7, 0x52, 0x26, 0x65, 0x26, 0x6A, + 0x3F, 0x3B, 0x0A, 0x00, 0x06, 0x26, 0xB9, 0x61, 0x18, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x0C, 0x60, + 0x80, 0x07, 0x36, 0x6A, 0x2F, 0x56, 0x06, 0x00, 0x26, 0x56, 0x06, 0x45, 0xD7, 0x42, 0x26, 0x54, + 0x2F, 0x76, 0x05, 0x00, 0x3F, 0x3B, 0x06, 0x00, 0xA9, 0x2C, 0x14, 0x00, 0x06, 0x27, 0xB9, 0x61, + 0x24, 0x00, 0xB9, 0x71, 0x28, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x38, 0xBD, 0x58, 0x07, 0xA9, 0x2C, + 0x16, 0x00, 0x0C, 0x80, 0x38, 0x04, 0x2F, 0x5B, 0x0B, 0x00, 0x26, 0x5B, 0x06, 0x45, 0xD7, 0x42, + 0x26, 0x54, 0x38, 0x49, 0x58, 0x07, 0x26, 0x5B, 0x3F, 0x34, 0x0B, 0x00, 0x06, 0x25, 0x36, 0x8B, + 0xB9, 0x51, 0x1C, 0x00, 0xB9, 0x41, 0x20, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x2F, 0x58, 0x08, 0x00, + 0x26, 0x58, 0x06, 0x35, 0x38, 0x41, 0x20, 0x00, 0xA9, 0x2C, 0x18, 0x00, 0xD7, 0x32, 0x26, 0x53, + 0x26, 0x58, 0x06, 0x25, 0x3F, 0x34, 0x08, 0x00, 0xB9, 0x51, 0x2C, 0x00, 0xAB, 0x15, 0x00, 0x00, + 0x38, 0x49, 0x5C, 0x07, 0xA9, 0x2C, 0x1A, 0x00, 0x38, 0x21, 0x18, 0x00, 0xB9, 0x41, 0x20, 0x00, + 0x3F, 0x34, 0x0A, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x71, 0x28, 0x00, 0x38, 0x41, 0x20, 0x00, + 0x38, 0x61, 0x24, 0x00, 0xA9, 0x2C, 0x1C, 0x00, 0x06, 0x27, 0x3F, 0x34, 0x06, 0x00, 0xAB, 0x15, + 0x00, 0x00, 0x38, 0xA9, 0x60, 0x07, 0xA9, 0x2C, 0x1E, 0x00, 0x38, 0x21, 0x1C, 0x00, 0x3F, 0x3A, + 0x0B, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x51, 0x2C, 0x00, 0xA9, 0x2C, 0x20, 0x00, 0x3F, 0x3A, + 0x08, 0x00, 0x06, 0x25, 0xAB, 0x15, 0x00, 0x00, 0xA9, 0x2C, 0x22, 0x00, 0x38, 0x71, 0x0C, 0x00, + 0xD4, 0x71, 0x82, 0x28, 0x04, 0x42, 0x06, 0x3E, 0x26, 0x41, 0x06, 0x2C, 0x8B, 0xD4, 0x02, 0x00, + 0x78, 0x3D, 0x54, 0x07, 0x28, 0x41, 0x02, 0x00, 0x06, 0x2E, 0xEB, 0xDA, 0x02, 0x00, 0xB8, 0x61, + 0x04, 0x00, 0x32, 0x02, 0x16, 0x66, 0x38, 0x51, 0x10, 0x00, 0x70, 0x4E, 0x26, 0x65, 0xB8, 0x51, + 0x04, 0x00, 0x23, 0x66, 0x43, 0x76, 0x22, 0x05, 0xC6, 0x47, 0x32, 0x0C, 0xA1, 0x7E, 0xF2, 0x0A, + 0x0C, 0x50, 0x80, 0x07, 0x3F, 0x77, 0x05, 0x00, 0xC6, 0x47, 0x02, 0x04, 0x3F, 0x66, 0x05, 0x00, + 0xA1, 0x6E, 0x38, 0x71, 0x0C, 0x00, 0xD4, 0x72, 0x82, 0x2A, 0x06, 0x3E, 0x06, 0x41, 0x06, 0x2C, + 0xAB, 0xD7, 0x02, 0x00, 0x78, 0x3D, 0x58, 0x07, 0x20, 0x41, 0x04, 0x22, 0x26, 0x2E, 0xEB, 0xDA, + 0x02, 0x00, 0xB8, 0x61, 0x08, 0x00, 0x32, 0x02, 0x16, 0x66, 0x38, 0x71, 0x14, 0x00, 0xB8, 0x51, + 0x08, 0x00, 0x78, 0x4E, 0x02, 0x00, 0x26, 0x67, 0x23, 0x66, 0x43, 0x76, 0x22, 0x06, 0xC6, 0x47, + 0x32, 0x0E, 0xA9, 0x7E, 0x02, 0x00, 0xF2, 0x0B, 0x0C, 0x50, 0x38, 0x04, 0x3F, 0x77, 0x05, 0x00, + 0xC6, 0x47, 0x02, 0x05, 0x3F, 0x66, 0x05, 0x00, 0xA9, 0x6E, 0x02, 0x00, 0x06, 0x2E, 0xAB, 0xCA, + 0x02, 0x00, 0x58, 0xC1, 0x40, 0x00, 0x58, 0x81, 0x30, 0x00, 0x2C, 0x10, 0x50, 0x00, 0xE1, 0xF0, + 0x34, 0x14, 0x0C, 0x20, 0x34, 0x15, 0x04, 0x30, 0x0C, 0x40, 0x3C, 0x00, 0xB1, 0xF1, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, 0x70, 0x15, 0x04, 0x30, 0x0C, 0x40, 0x3C, 0x00, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, + 0x0C, 0xE0, 0xFC, 0x0A, 0x98, 0x7E, 0xAC, 0x0A, 0x82, 0x1A, 0x0C, 0x20, 0x74, 0x15, 0x04, 0x30, + 0x0C, 0x40, 0x34, 0x00, 0x99, 0x0E, 0xAC, 0x0A, 0xB9, 0x0E, 0x74, 0x0A, 0x0C, 0xF0, 0xB0, 0x01, + 0xF1, 0xF0, 0x04, 0x71, 0x99, 0x7E, 0x70, 0x0A, 0xB9, 0x0E, 0x38, 0x0A, 0x0C, 0x20, 0x38, 0x15, + 0x04, 0x30, 0x0C, 0x40, 0x34, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x8B, 0xC1, 0x01, 0x00, + 0x2B, 0x39, 0x03, 0x00, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x00, 0x00, 0x0C, 0x70, 0xFC, 0x0A, + 0x18, 0x67, 0x98, 0x04, 0x99, 0x67, 0x99, 0x04, 0x18, 0x67, 0xA9, 0x04, 0x99, 0x67, 0xAA, 0x04, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x28, 0x00, 0xD9, 0xC1, 0x18, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, + 0xD9, 0x81, 0x08, 0x00, 0x18, 0xBD, 0xE5, 0x00, 0x04, 0xC0, 0x06, 0x7B, 0x06, 0xEB, 0x57, 0x71, + 0xD7, 0xE2, 0x36, 0xE7, 0x2C, 0xE0, 0x28, 0x03, 0x08, 0x90, 0x00, 0xFF, 0x08, 0x80, 0xFF, 0xF0, + 0x26, 0xED, 0x06, 0xAC, 0x2C, 0x90, 0xFF, 0x0F, 0x2C, 0x80, 0xFF, 0xFF, 0x08, 0x50, 0xFF, 0x0F, + 0x18, 0x7D, 0xE6, 0x00, 0x2F, 0x6B, 0x0C, 0x00, 0xC6, 0x67, 0x32, 0x5E, 0x18, 0x7D, 0x98, 0x04, + 0xC6, 0x7A, 0xC2, 0x5A, 0x98, 0x7E, 0x16, 0x00, 0x82, 0x53, 0x06, 0x2E, 0xB9, 0x51, 0x04, 0x00, + 0xB1, 0x61, 0xAB, 0x3B, 0x01, 0x00, 0xC4, 0x20, 0x24, 0xA1, 0x13, 0xAA, 0x38, 0x51, 0x04, 0x00, + 0x30, 0x61, 0x82, 0x46, 0x98, 0x7E, 0x19, 0x00, 0x92, 0x43, 0x24, 0x61, 0x57, 0x61, 0x26, 0x6D, + 0x20, 0x4E, 0x38, 0x76, 0x38, 0x0A, 0x5C, 0x40, 0xFF, 0x0F, 0x57, 0x46, 0x56, 0x79, 0x66, 0x74, + 0xB9, 0x76, 0x38, 0x0A, 0x28, 0x4E, 0x02, 0x00, 0x1C, 0x30, 0x00, 0x10, 0x5C, 0x40, 0xFF, 0x0F, + 0x56, 0x73, 0x66, 0x74, 0xB9, 0x76, 0x38, 0x0A, 0x18, 0x4E, 0x17, 0x00, 0x56, 0x78, 0x54, 0x4F, + 0x57, 0x4C, 0x66, 0x74, 0xB9, 0x76, 0x38, 0x0A, 0x18, 0x3E, 0x16, 0x00, 0x0C, 0x40, 0xFF, 0xFF, + 0x26, 0x45, 0x57, 0x3E, 0x56, 0x47, 0x66, 0x43, 0xB9, 0x46, 0x38, 0x0A, 0x18, 0x6E, 0x16, 0x00, + 0x04, 0x71, 0x34, 0x61, 0x53, 0x76, 0x38, 0x6D, 0x38, 0x0A, 0x1C, 0x40, 0x00, 0x04, 0x66, 0x76, + 0x5C, 0x70, 0xFF, 0x03, 0x56, 0x64, 0x66, 0x67, 0x06, 0x76, 0x77, 0x76, 0x24, 0x71, 0x54, 0x7F, + 0x1C, 0x30, 0x01, 0xF0, 0x57, 0x76, 0x56, 0x63, 0x66, 0x67, 0xB9, 0x6D, 0x38, 0x0A, 0x24, 0xC1, + 0x2C, 0xE0, 0x1C, 0x00, 0xF2, 0x9E, 0x58, 0xC1, 0x18, 0x00, 0x58, 0x81, 0x08, 0x00, 0x2C, 0x10, + 0x28, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0x0C, 0xD0, 0xFC, 0x0A, + 0x38, 0x7D, 0x38, 0x0A, 0xD1, 0x81, 0xDC, 0x70, 0x00, 0xF0, 0x92, 0x3A, 0xF8, 0x6D, 0xB0, 0x0A, + 0x12, 0x37, 0x0C, 0xE0, 0x98, 0x0F, 0x04, 0x9C, 0x08, 0xB0, 0xE0, 0xFF, 0x08, 0xA0, 0x1F, 0xFF, + 0x26, 0x9E, 0x06, 0xC7, 0x04, 0x81, 0x2C, 0xB0, 0xFF, 0xFF, 0x2C, 0xA0, 0xFF, 0xFF, 0x18, 0x7D, + 0xA9, 0x04, 0xC6, 0x7C, 0xC2, 0x25, 0x90, 0x7E, 0x82, 0x03, 0x24, 0xC1, 0x13, 0xCC, 0x06, 0x2E, + 0xAB, 0x3E, 0x01, 0x00, 0xC4, 0x20, 0x82, 0x19, 0x10, 0x7E, 0x06, 0x68, 0x34, 0x71, 0x53, 0x67, + 0x06, 0x76, 0x38, 0x6D, 0x38, 0x0A, 0x06, 0x56, 0x77, 0x58, 0x66, 0x75, 0x5C, 0x70, 0x1F, 0x00, + 0x57, 0x78, 0x56, 0x6B, 0x66, 0x67, 0x06, 0x76, 0xF7, 0x7A, 0x24, 0x71, 0x54, 0x77, 0xD7, 0x7A, + 0x56, 0x6A, 0x66, 0x67, 0xB9, 0x6D, 0x38, 0x0A, 0x24, 0xE3, 0xC6, 0xE9, 0x92, 0xD9, 0x58, 0xC1, + 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x0C, 0x50, 0xFC, 0x0A, 0x38, 0x45, 0x38, 0x0A, 0x06, 0x64, 0x77, 0x66, 0x54, 0x6F, + 0xC4, 0x6A, 0x02, 0x30, 0x38, 0xF5, 0x74, 0x0A, 0x14, 0x3A, 0x26, 0x36, 0x13, 0x33, 0x5C, 0xF0, + 0xFF, 0x03, 0x5C, 0x40, 0xFF, 0x03, 0x0C, 0x20, 0x68, 0x15, 0x04, 0x7C, 0x04, 0xD1, 0x14, 0xC1, + 0xC4, 0x30, 0x82, 0x16, 0x06, 0xEF, 0x63, 0xE7, 0xD4, 0xE1, 0x92, 0x0E, 0x06, 0xE4, 0x63, 0xE7, + 0xD4, 0xE1, 0x82, 0x0A, 0x06, 0xED, 0x53, 0xE7, 0x15, 0xEE, 0x24, 0x6F, 0x34, 0x31, 0xB1, 0x02, + 0x13, 0x33, 0x54, 0x6F, 0x56, 0x4E, 0x34, 0x71, 0xC6, 0x7C, 0x34, 0x24, 0x92, 0xEA, 0x38, 0x75, + 0x38, 0x0A, 0x1C, 0x30, 0x00, 0xF4, 0x56, 0x73, 0x57, 0x66, 0x66, 0x74, 0x66, 0x76, 0xB9, 0x75, + 0x38, 0x0A, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x0C, 0xE0, 0xFC, 0x0A, 0x18, 0xCE, 0xAC, 0x0A, 0x0C, 0x20, 0x70, 0x15, 0x06, 0x3D, + 0x0C, 0x30, 0x34, 0x15, 0x0C, 0x40, 0x3C, 0x00, 0x0C, 0xF0, 0x28, 0x01, 0xF1, 0xF0, 0x06, 0x2D, + 0x0C, 0x20, 0x34, 0x15, 0x04, 0x30, 0x0C, 0x40, 0x3C, 0x00, 0x99, 0xCE, 0xAC, 0x0A, 0x0C, 0xF0, + 0xB0, 0x01, 0xF1, 0xF0, 0x2B, 0xF9, 0x02, 0x00, 0xAB, 0x01, 0x03, 0x00, 0x6B, 0x06, 0x03, 0x00, + 0x38, 0x6E, 0x38, 0x0A, 0x0C, 0x70, 0x00, 0xF0, 0xD6, 0x76, 0x06, 0x7E, 0x82, 0x05, 0x77, 0x66, + 0x54, 0x6F, 0x24, 0x61, 0xF2, 0x06, 0x08, 0x50, 0xE0, 0x00, 0xD6, 0x56, 0x82, 0x05, 0x04, 0x61, + 0x99, 0x67, 0x70, 0x0A, 0xF2, 0x03, 0x99, 0x0E, 0x70, 0x0A, 0x98, 0x67, 0x70, 0x0A, 0x82, 0x05, + 0x99, 0x67, 0xAC, 0x0A, 0x04, 0x21, 0xF2, 0x10, 0x18, 0x67, 0xAC, 0x0A, 0x04, 0x21, 0xC4, 0x60, + 0x82, 0x0B, 0x98, 0xE7, 0x98, 0x04, 0x92, 0x08, 0x99, 0x27, 0xAC, 0x0A, 0xCB, 0x57, 0x01, 0x00, + 0xEB, 0xF5, 0x02, 0x00, 0x06, 0x2E, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, + 0x04, 0x21, 0xE1, 0xF0, 0x34, 0x14, 0x0C, 0x20, 0xDB, 0x0B, 0x04, 0x30, 0x04, 0x48, 0xB1, 0xF1, + 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x0C, 0x70, 0xFC, 0x0A, + 0x0C, 0x60, 0x18, 0x00, 0x99, 0x67, 0xE3, 0x00, 0x04, 0x6E, 0x34, 0x14, 0x99, 0x67, 0xE4, 0x00, + 0x04, 0x6D, 0xB1, 0xF1, 0x99, 0x07, 0xE0, 0x00, 0x99, 0x07, 0xE1, 0x00, 0x99, 0x07, 0xE2, 0x00, + 0x99, 0x07, 0xE5, 0x00, 0x99, 0x67, 0xE6, 0x00, 0x8B, 0x36, 0x02, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x70, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xC7, 0x06, 0xF7, + 0x06, 0xD7, 0x13, 0xE7, 0xC6, 0xE4, 0xB2, 0x1B, 0x06, 0x65, 0x73, 0x67, 0x54, 0x61, 0x26, 0xD6, + 0x13, 0xDD, 0xC4, 0xD2, 0xD2, 0x16, 0xC4, 0xF0, 0x92, 0x05, 0xC4, 0x61, 0x92, 0x0E, 0x91, 0xE2, + 0xF2, 0x0B, 0xC4, 0xC0, 0x92, 0x07, 0xC4, 0x60, 0x04, 0xF1, 0x92, 0x07, 0x91, 0xE3, 0x06, 0xCF, + 0xF2, 0x04, 0xC4, 0x61, 0x82, 0x06, 0x04, 0xF1, 0x24, 0x71, 0xF2, 0xE4, 0x04, 0x21, 0xF2, 0x02, + 0x04, 0x20, 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x34, 0x18, 0xC1, 0xE1, + 0x0C, 0xE0, 0xFC, 0x0A, 0x98, 0x7E, 0xDF, 0x00, 0x92, 0x03, 0x6B, 0x10, 0x03, 0x00, 0x18, 0x7E, + 0x99, 0x04, 0xC4, 0x71, 0xC2, 0x03, 0x04, 0x20, 0xF2, 0x23, 0xB8, 0x5E, 0xFC, 0x02, 0x82, 0xFC, + 0xB8, 0x7E, 0x00, 0x03, 0x82, 0xF9, 0x38, 0x7E, 0x0C, 0x00, 0xD4, 0x76, 0x92, 0xF5, 0x04, 0x71, + 0x99, 0x7E, 0xE0, 0x00, 0x0C, 0x20, 0xDD, 0x0B, 0x0C, 0x30, 0xDF, 0x0B, 0x0C, 0x40, 0x18, 0x00, + 0x2B, 0x12, 0x03, 0x00, 0xC4, 0x20, 0x82, 0xE8, 0x38, 0x5E, 0x00, 0x03, 0x0C, 0x20, 0xDE, 0x0B, + 0x0C, 0x30, 0xE0, 0x0B, 0x04, 0x4E, 0x2B, 0x12, 0x03, 0x00, 0x16, 0x22, 0xF7, 0x2F, 0x40, 0xE1, + 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x14, 0x00, 0xD9, 0xC1, 0x04, 0x00, 0x06, 0xD2, 0x28, 0x20, + 0x02, 0x0E, 0xB1, 0xB1, 0x06, 0xE3, 0x26, 0x22, 0x04, 0x33, 0x06, 0xC4, 0x06, 0xB5, 0xAB, 0x15, + 0x00, 0x00, 0x2F, 0x7E, 0x0E, 0x00, 0x26, 0xE7, 0x08, 0x60, 0x00, 0x30, 0x04, 0x70, 0x06, 0x52, + 0xD7, 0xE1, 0x0C, 0x40, 0x00, 0xA0, 0x0C, 0x20, 0x00, 0x49, 0x26, 0xED, 0x06, 0x37, 0x06, 0xF7, + 0x26, 0x46, 0x26, 0x26, 0xC6, 0xFB, 0xB2, 0x1C, 0x06, 0x6E, 0x57, 0x61, 0x2F, 0xD4, 0x06, 0x00, + 0x30, 0xDD, 0xC6, 0xD5, 0xB2, 0x10, 0x26, 0x62, 0x30, 0xD6, 0x30, 0x66, 0x5C, 0xD0, 0xFF, 0x0F, + 0x77, 0x68, 0x5C, 0x60, 0xFF, 0x0F, 0x3F, 0x66, 0x0D, 0x00, 0xC4, 0x60, 0x02, 0x02, 0x26, 0x76, + 0x24, 0x31, 0x23, 0x33, 0x24, 0xF1, 0x26, 0xEC, 0x23, 0xFF, 0x23, 0xEE, 0xF2, 0xE4, 0x06, 0x27, + 0xCB, 0x14, 0x00, 0x00, 0x58, 0xC1, 0x04, 0x00, 0x30, 0xB1, 0x23, 0x22, 0x2C, 0x10, 0x14, 0x00, + 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x84, 0x00, 0xD9, 0xC1, 0x74, 0x00, 0xD9, 0x81, 0x64, 0x00, + 0x0C, 0xE0, 0xFC, 0x0A, 0x28, 0xCE, 0x06, 0x03, 0xA9, 0x0E, 0x18, 0x03, 0xCB, 0x3B, 0x00, 0x00, + 0x23, 0xD2, 0xC6, 0xDC, 0x04, 0xA0, 0xCA, 0x0F, 0x01, 0x00, 0x0C, 0x20, 0x14, 0x00, 0x26, 0x21, + 0x06, 0x3A, 0x04, 0x45, 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0x04, 0x45, 0x06, 0x3A, 0x06, 0x21, + 0x0C, 0xF0, 0xD8, 0x01, 0xF1, 0xF0, 0xA9, 0xDE, 0x18, 0x03, 0x4B, 0x3C, 0x00, 0x00, 0x23, 0xC2, + 0x0C, 0x30, 0x18, 0x00, 0xA9, 0xCE, 0x5C, 0x01, 0x06, 0x2C, 0xCB, 0x14, 0x00, 0x00, 0x13, 0xD2, + 0x99, 0xDE, 0x5F, 0x01, 0x06, 0x2C, 0x0C, 0x30, 0x18, 0x00, 0x6B, 0x17, 0x00, 0x00, 0x13, 0x22, + 0x14, 0x72, 0x26, 0x72, 0x33, 0x77, 0xB9, 0x71, 0x40, 0x00, 0x14, 0x72, 0x26, 0x7D, 0x24, 0xD2, + 0x33, 0x77, 0x33, 0xDD, 0x99, 0x2E, 0x5E, 0x01, 0xB9, 0x71, 0x44, 0x00, 0x24, 0x22, 0xB9, 0xD1, + 0x54, 0x00, 0x06, 0xD7, 0x08, 0x70, 0x00, 0x30, 0x33, 0x22, 0x2C, 0x70, 0x00, 0x49, 0xB9, 0x21, + 0x50, 0x00, 0x06, 0xBA, 0xB9, 0x71, 0x4C, 0x00, 0x38, 0x71, 0x54, 0x00, 0xC6, 0xD7, 0x1A, 0x7F, + 0x00, 0x00, 0x13, 0x7D, 0xC4, 0x7D, 0xB9, 0x71, 0x48, 0x00, 0xD2, 0x73, 0x38, 0x71, 0x44, 0x00, + 0x38, 0x31, 0x48, 0x00, 0x06, 0x9D, 0x36, 0x97, 0x04, 0x20, 0x04, 0x41, 0x0C, 0x50, 0x17, 0x00, + 0x2B, 0x18, 0x03, 0x00, 0x23, 0x99, 0x2F, 0x69, 0x09, 0x00, 0x26, 0x61, 0xA9, 0x26, 0x28, 0x00, + 0x2F, 0x6D, 0x0D, 0x00, 0x26, 0xD6, 0xD7, 0xD1, 0x23, 0xDD, 0xB9, 0xD1, 0x58, 0x00, 0x06, 0x69, + 0x38, 0xD1, 0x40, 0x00, 0x57, 0x61, 0x06, 0x72, 0x26, 0x61, 0x38, 0x51, 0x50, 0x00, 0xC6, 0xD5, + 0x12, 0x4B, 0x13, 0x8D, 0xCC, 0x80, 0x16, 0x00, 0xD2, 0x43, 0x38, 0x51, 0x40, 0x00, 0xC4, 0xA0, + 0x06, 0xCD, 0x36, 0xC5, 0x23, 0xCC, 0x92, 0x15, 0x04, 0x5E, 0x06, 0x28, 0x06, 0x3A, 0x0C, 0x40, + 0x18, 0x00, 0xB9, 0x61, 0x60, 0x00, 0xB9, 0x71, 0x5C, 0x00, 0x2B, 0x18, 0x03, 0x00, 0x2F, 0x5C, + 0x0C, 0x00, 0x38, 0x71, 0x5C, 0x00, 0x38, 0x61, 0x60, 0x00, 0x26, 0x51, 0xA9, 0x25, 0x34, 0x00, + 0x38, 0x51, 0x58, 0x00, 0x26, 0xD5, 0x38, 0x51, 0x4C, 0x00, 0x23, 0xDD, 0x57, 0xD1, 0x26, 0xD5, + 0x30, 0x4D, 0x30, 0x5D, 0x5C, 0x40, 0xFF, 0x0F, 0x77, 0x58, 0x5C, 0x50, 0xFF, 0x0F, 0x3F, 0x55, + 0x04, 0x00, 0x2F, 0x4C, 0x0C, 0x00, 0x26, 0x41, 0x28, 0x34, 0x34, 0x00, 0x36, 0x53, 0x28, 0x3E, + 0x14, 0x00, 0x36, 0x57, 0x36, 0x53, 0xC4, 0x50, 0x22, 0x0B, 0x57, 0xC1, 0x26, 0xC1, 0x38, 0x4C, + 0x14, 0x00, 0x26, 0x45, 0xB9, 0x4C, 0x14, 0x00, 0x30, 0x46, 0x26, 0x54, 0xB1, 0x56, 0x04, 0xD1, + 0x26, 0xD8, 0x33, 0xDD, 0xF2, 0xB3, 0x57, 0x91, 0x26, 0x91, 0x30, 0x79, 0x04, 0xA1, 0x26, 0xB7, + 0x38, 0xD1, 0x48, 0x00, 0x24, 0xD1, 0x33, 0xDD, 0xFA, 0x80, 0xFF, 0xFF, 0x28, 0x6E, 0x5C, 0x01, + 0x28, 0x51, 0x38, 0x00, 0x08, 0x70, 0x00, 0x30, 0x57, 0x61, 0x2C, 0x70, 0x00, 0x49, 0x26, 0x76, + 0x30, 0x67, 0x30, 0x77, 0x5C, 0x60, 0xFF, 0x0F, 0x77, 0x78, 0x5C, 0x70, 0xFF, 0x0F, 0x3F, 0x77, + 0x06, 0x00, 0x36, 0x75, 0x28, 0x51, 0x2C, 0x00, 0x36, 0x75, 0x28, 0x5E, 0x14, 0x00, 0x0C, 0x40, + 0x14, 0x00, 0x36, 0x75, 0x38, 0x51, 0x40, 0x00, 0x23, 0x77, 0x24, 0x56, 0x57, 0x51, 0x06, 0x2D, + 0x0C, 0x20, 0x58, 0x0C, 0x04, 0x30, 0x26, 0x41, 0x26, 0x5E, 0x06, 0x6B, 0xA9, 0x7E, 0x14, 0x03, + 0xA9, 0x7E, 0x16, 0x03, 0xEB, 0x3D, 0x02, 0x00, 0x38, 0x51, 0x44, 0x00, 0x06, 0x2D, 0x0C, 0x20, + 0x58, 0x0C, 0x2C, 0x50, 0x1E, 0x00, 0x57, 0x51, 0x04, 0x31, 0x06, 0x41, 0x26, 0x5E, 0x06, 0x6B, + 0xEB, 0x3D, 0x02, 0x00, 0x18, 0x7E, 0x25, 0x03, 0x04, 0xA1, 0xA9, 0x7E, 0x78, 0x01, 0xA9, 0x7E, + 0x12, 0x00, 0x04, 0x71, 0x99, 0x7E, 0x1D, 0x03, 0x99, 0x7E, 0x1E, 0x03, 0x99, 0x7E, 0x1F, 0x03, + 0x99, 0x7E, 0x1C, 0x03, 0x0B, 0x4B, 0x02, 0x00, 0x58, 0xC1, 0x74, 0x00, 0x06, 0x2A, 0x58, 0x81, + 0x64, 0x00, 0x2C, 0x10, 0x84, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x18, 0x00, 0xD9, 0xC1, 0x08, 0x00, + 0xC1, 0xA1, 0x0C, 0xE0, 0xFC, 0x0A, 0x38, 0x2E, 0x94, 0x04, 0x04, 0x70, 0xC6, 0x27, 0x82, 0x48, + 0x0C, 0xF0, 0x80, 0x00, 0xF1, 0xF0, 0x06, 0x62, 0x04, 0x71, 0x26, 0x72, 0x99, 0x2E, 0xE5, 0x00, + 0x57, 0x61, 0xD7, 0x22, 0x99, 0x7E, 0xE6, 0x00, 0x3F, 0x76, 0x02, 0x00, 0x26, 0x7E, 0x78, 0xDE, + 0x70, 0x01, 0x78, 0x77, 0x30, 0x03, 0x36, 0xD7, 0xC4, 0xD0, 0x32, 0x02, 0x16, 0xDD, 0x3F, 0x76, + 0x02, 0x00, 0x26, 0x7E, 0x78, 0x5E, 0x72, 0x01, 0x78, 0x77, 0x32, 0x03, 0x3F, 0x77, 0x05, 0x00, + 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, 0x36, 0x26, 0x06, 0x37, 0x2F, 0xC2, 0x0E, 0x00, 0x06, 0x27, + 0x6B, 0x13, 0x00, 0x00, 0x28, 0xBC, 0x3C, 0x03, 0x06, 0x3D, 0x06, 0xA2, 0x06, 0x2D, 0x6B, 0x13, + 0x00, 0x00, 0x2F, 0xD2, 0x0A, 0x00, 0x06, 0x3B, 0x06, 0x2B, 0x6B, 0x13, 0x00, 0x00, 0xC6, 0xD2, + 0xB2, 0x0D, 0x04, 0xD1, 0x0C, 0x20, 0x28, 0x03, 0x99, 0xDE, 0xDF, 0x00, 0x26, 0x2C, 0x0C, 0x30, + 0x58, 0x0C, 0xCB, 0x8C, 0x01, 0x00, 0x99, 0xDE, 0x98, 0x04, 0x18, 0x7E, 0xDF, 0x00, 0x58, 0xC1, + 0x08, 0x00, 0x40, 0xA1, 0x06, 0x27, 0x2C, 0x10, 0x18, 0x00, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x0C, 0x70, 0xFC, 0x0A, 0x99, 0x07, 0xDF, 0x00, 0x98, 0x77, 0xE0, 0x00, 0x82, 0x07, 0xAB, 0x1C, + 0x03, 0x00, 0xC4, 0x20, 0x82, 0x03, 0x4B, 0x2F, 0x03, 0x00, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, + 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x2F, 0x72, 0x02, 0x00, 0x26, 0x27, 0x57, 0x21, + 0x0C, 0x60, 0xFC, 0x0A, 0x34, 0x18, 0x2C, 0x20, 0x64, 0x09, 0xC1, 0xE1, 0x26, 0x26, 0x14, 0x71, + 0xA1, 0x72, 0xA9, 0x72, 0x02, 0x00, 0xA9, 0x72, 0x04, 0x00, 0xA9, 0x72, 0x06, 0x00, 0xA9, 0x02, + 0x08, 0x00, 0xA9, 0x02, 0x0A, 0x00, 0x38, 0xE6, 0x38, 0x0A, 0xDC, 0xE0, 0xFF, 0x03, 0x92, 0x10, + 0x0C, 0x20, 0x02, 0x15, 0x06, 0x3E, 0x04, 0x48, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x0C, 0x20, + 0x0A, 0x15, 0x06, 0x3E, 0x0C, 0x40, 0x1A, 0x00, 0x0C, 0xF0, 0xB0, 0x01, 0xF1, 0xF0, 0x40, 0xE1, + 0x24, 0x18, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, 0x04, 0xE0, 0x06, 0x2E, 0x4B, 0x36, 0x03, 0x00, + 0x24, 0xE1, 0xC4, 0xED, 0x92, 0xFB, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x3C, 0x10, 0x20, 0x00, + 0xB1, 0x21, 0x28, 0x71, 0x02, 0x00, 0xD9, 0xC1, 0x10, 0x00, 0xC9, 0xA1, 0x08, 0x00, 0xC6, 0x47, + 0x13, 0xD2, 0x06, 0xC4, 0x18, 0x21, 0x01, 0x00, 0x23, 0x33, 0x22, 0x03, 0x43, 0x23, 0xF2, 0x1F, + 0xC6, 0x4D, 0x43, 0xA2, 0x43, 0xDD, 0x32, 0x0C, 0x04, 0xE0, 0xC6, 0x2E, 0x06, 0xBD, 0x82, 0x05, + 0x04, 0x3A, 0xCB, 0x14, 0x00, 0x00, 0x13, 0xE2, 0x06, 0x3A, 0x04, 0xD0, 0xF2, 0x04, 0x43, 0xB7, + 0x06, 0xEA, 0x43, 0x33, 0x36, 0x3E, 0x3F, 0x2D, 0x0C, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x43, 0x22, + 0x3F, 0x3D, 0x0B, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x26, 0x2E, 0x43, 0x22, 0x58, 0xC1, 0x10, 0x00, + 0x48, 0xA1, 0x08, 0x00, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x3C, 0x10, 0x74, 0x00, + 0xD9, 0xC1, 0x64, 0x00, 0x0C, 0x70, 0xFC, 0x0A, 0xD9, 0x81, 0x54, 0x00, 0x98, 0x67, 0x70, 0x0A, + 0x06, 0xE7, 0x92, 0x0F, 0x98, 0x67, 0xAC, 0x0A, 0x9A, 0x13, 0x03, 0x00, 0x38, 0x77, 0x38, 0x0A, + 0xDC, 0x70, 0xFF, 0x03, 0x9A, 0x0D, 0x03, 0x00, 0x2B, 0x39, 0x03, 0x00, 0xFA, 0x09, 0x03, 0x00, + 0x98, 0x70, 0xE4, 0x16, 0x38, 0x7E, 0x0C, 0x00, 0x92, 0x73, 0x0C, 0x60, 0x00, 0x03, 0xD6, 0x67, + 0x82, 0x09, 0x0C, 0x70, 0x1E, 0x00, 0x99, 0x7E, 0x00, 0x0A, 0x0C, 0x70, 0x64, 0x00, 0xFA, 0x91, + 0x00, 0x00, 0xD4, 0x71, 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x0C, 0xDC, 0x28, 0x7E, 0x12, 0x00, + 0x18, 0x56, 0x78, 0x00, 0x82, 0x3D, 0xC6, 0x57, 0xC2, 0x05, 0x04, 0x7A, 0x99, 0x7E, 0x00, 0x0A, + 0xF2, 0x09, 0x18, 0x66, 0x77, 0x00, 0xC6, 0x67, 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x00, 0x0A, + 0xC2, 0x25, 0x0C, 0x70, 0x64, 0x00, 0xA9, 0x7E, 0x02, 0x0A, 0x0C, 0x70, 0x50, 0x00, 0x99, 0x7E, + 0x01, 0x0A, 0x0C, 0x70, 0x82, 0x00, 0xA9, 0x7E, 0x04, 0x0A, 0x08, 0x50, 0x00, 0xFF, 0x04, 0xC0, + 0x0C, 0x70, 0x0B, 0x15, 0x2C, 0x50, 0xFF, 0x0F, 0xB9, 0x71, 0x04, 0x00, 0x0C, 0xD0, 0x60, 0x14, + 0xB9, 0xC1, 0x18, 0x00, 0xB9, 0xC1, 0x14, 0x00, 0xB9, 0xC1, 0x30, 0x00, 0xB9, 0xC1, 0x2C, 0x00, + 0xB9, 0xC1, 0x28, 0x00, 0xB9, 0x51, 0x24, 0x00, 0xF2, 0x6F, 0x0C, 0x70, 0x46, 0x00, 0xA9, 0x7E, + 0x02, 0x0A, 0x04, 0x7A, 0x99, 0x7E, 0x01, 0x0A, 0x0C, 0x70, 0x64, 0x00, 0xF2, 0xDD, 0xC6, 0x57, + 0xD2, 0xC5, 0x18, 0x66, 0x77, 0x00, 0xC6, 0x67, 0x0C, 0x70, 0x14, 0x00, 0x99, 0x7E, 0x00, 0x0A, + 0xC2, 0x14, 0x0C, 0x60, 0x50, 0x00, 0x99, 0x6E, 0x01, 0x0A, 0x0C, 0x60, 0x82, 0x00, 0xA9, 0x6E, + 0x04, 0x0A, 0x18, 0x6E, 0x1D, 0x03, 0x0C, 0x70, 0x64, 0x00, 0xC4, 0x61, 0xA9, 0x7E, 0x02, 0x0A, + 0xC2, 0xC5, 0x99, 0x0E, 0x01, 0x0A, 0xF2, 0xC0, 0x0C, 0x70, 0x78, 0x00, 0xF2, 0x2A, 0x08, 0x60, + 0x00, 0x80, 0x2C, 0x60, 0x0C, 0xDC, 0x28, 0x7E, 0x12, 0x00, 0x18, 0x56, 0x78, 0x00, 0xC6, 0x57, + 0xC2, 0x0C, 0x04, 0x7F, 0x99, 0x7E, 0x00, 0x0A, 0x04, 0x65, 0x0C, 0x70, 0x64, 0x00, 0xA9, 0x7E, + 0x02, 0x0A, 0x99, 0x6E, 0x01, 0x0A, 0xF2, 0xA8, 0x18, 0x66, 0x77, 0x00, 0xC6, 0x67, 0x0C, 0x70, + 0x14, 0x00, 0x99, 0x7E, 0x00, 0x0A, 0xC2, 0x0B, 0x0C, 0x70, 0x64, 0x00, 0xA9, 0x7E, 0x02, 0x0A, + 0x04, 0x75, 0x99, 0x7E, 0x01, 0x0A, 0x0C, 0x70, 0x5A, 0x00, 0xF2, 0x96, 0x0C, 0x70, 0x96, 0x00, + 0xA9, 0x7E, 0x02, 0x0A, 0x99, 0x0E, 0x01, 0x0A, 0x0C, 0x70, 0x50, 0x00, 0xF2, 0x8D, 0x38, 0x7E, + 0x38, 0x0A, 0x5C, 0x70, 0xFF, 0x03, 0x63, 0x7C, 0xD4, 0x71, 0x92, 0x16, 0x06, 0x2C, 0x4B, 0x36, + 0x03, 0x00, 0x38, 0x61, 0x04, 0x00, 0x24, 0xC1, 0xC4, 0xCD, 0x24, 0x62, 0xB9, 0x61, 0x04, 0x00, + 0x24, 0xDC, 0x8A, 0x3E, 0x02, 0x00, 0x18, 0x7E, 0x70, 0x0A, 0x38, 0x51, 0x28, 0x00, 0xC6, 0x75, + 0xD2, 0xE7, 0xFA, 0x36, 0x02, 0x00, 0x04, 0x71, 0x26, 0x7C, 0x57, 0x71, 0x26, 0x7E, 0x38, 0x77, + 0x38, 0x0A, 0x06, 0xA7, 0x5C, 0x70, 0xFF, 0x0F, 0xB9, 0x71, 0x0C, 0x00, 0xF0, 0x7D, 0x77, 0xA6, + 0x5C, 0xA0, 0xFF, 0x0F, 0x32, 0x0E, 0x38, 0x61, 0x0C, 0x00, 0x38, 0x51, 0x04, 0x00, 0xA1, 0xAD, + 0xA9, 0x6D, 0x02, 0x00, 0x38, 0x61, 0x04, 0x00, 0x04, 0x71, 0x34, 0x61, 0x91, 0x76, 0x91, 0x75, + 0x70, 0x7D, 0x38, 0x51, 0x0C, 0x00, 0x06, 0x6A, 0x36, 0x67, 0x78, 0x7D, 0x02, 0x00, 0xB9, 0x61, + 0x08, 0x00, 0xB9, 0x61, 0x1C, 0x00, 0x36, 0x57, 0x86, 0x76, 0xB9, 0x51, 0x10, 0x00, 0x32, 0x04, + 0x16, 0x57, 0xB9, 0x51, 0x1C, 0x00, 0x38, 0x61, 0x10, 0x00, 0x86, 0x76, 0xB9, 0x61, 0x20, 0x00, + 0x32, 0x04, 0x16, 0x57, 0xB9, 0x51, 0x20, 0x00, 0x38, 0x61, 0x1C, 0x00, 0x38, 0x71, 0x20, 0x00, + 0x43, 0x66, 0x43, 0x77, 0x06, 0x37, 0x06, 0x26, 0xB9, 0x71, 0x38, 0x00, 0xB9, 0x61, 0x34, 0x00, + 0x0C, 0xF0, 0xBC, 0x00, 0xF1, 0xF0, 0x98, 0x70, 0xE4, 0x16, 0x06, 0xB2, 0xB9, 0x71, 0x40, 0x00, + 0x92, 0x1B, 0x38, 0x7E, 0x0C, 0x00, 0xDC, 0x70, 0x00, 0x03, 0x82, 0x0C, 0x86, 0xB2, 0x32, 0x02, + 0x24, 0xB3, 0x06, 0x4B, 0x67, 0x41, 0x38, 0x2E, 0x00, 0x0A, 0x38, 0x3E, 0x04, 0x0A, 0x43, 0x44, + 0xF2, 0x06, 0x38, 0x2E, 0x00, 0x0A, 0x38, 0x3E, 0x04, 0x0A, 0x06, 0x4B, 0xEB, 0x39, 0x03, 0x00, + 0x06, 0xB2, 0x06, 0x92, 0xF2, 0x35, 0x08, 0x40, 0x00, 0x80, 0x2C, 0x40, 0x0C, 0xDC, 0x28, 0x7E, + 0x12, 0x00, 0x18, 0x64, 0x78, 0x00, 0xC6, 0x67, 0xC2, 0x04, 0x26, 0x22, 0x04, 0x33, 0xF2, 0x0C, + 0x08, 0x50, 0x00, 0x80, 0x2C, 0x50, 0x0C, 0xDC, 0x18, 0x65, 0x77, 0x00, 0xC6, 0x67, 0xC2, 0x0C, + 0x26, 0x22, 0x26, 0x2B, 0x04, 0x35, 0xAB, 0x15, 0x00, 0x00, 0x43, 0x42, 0x38, 0x3E, 0x04, 0x0A, + 0x38, 0x2E, 0x00, 0x0A, 0xF2, 0x0A, 0x06, 0x42, 0xF7, 0x4F, 0x26, 0x42, 0x38, 0x3E, 0x04, 0x0A, + 0x38, 0x2E, 0x00, 0x0A, 0xE7, 0x40, 0x43, 0x44, 0xEB, 0x39, 0x03, 0x00, 0x06, 0x92, 0x38, 0x3E, + 0x04, 0x0A, 0x38, 0x2E, 0x00, 0x0A, 0x06, 0x4B, 0xEB, 0x39, 0x03, 0x00, 0x06, 0xB2, 0x18, 0x7E, + 0x9A, 0x04, 0xC4, 0x72, 0xD2, 0x0F, 0x38, 0x60, 0xB0, 0x16, 0x78, 0x56, 0xBC, 0x00, 0xA9, 0x5E, + 0x08, 0x0A, 0xA9, 0x5E, 0x06, 0x0A, 0x78, 0x66, 0xBE, 0x00, 0xA9, 0x6E, 0x0C, 0x0A, 0xA9, 0x6E, + 0x0A, 0x0A, 0x38, 0x70, 0xB0, 0x16, 0x28, 0x3E, 0x0A, 0x0A, 0x18, 0x57, 0xB9, 0x00, 0x18, 0x67, + 0xB8, 0x00, 0x18, 0x77, 0xBA, 0x00, 0xB9, 0x51, 0x50, 0x00, 0x2F, 0x85, 0x06, 0x00, 0x06, 0x25, + 0x26, 0x87, 0xB9, 0x71, 0x4C, 0x00, 0xB9, 0x61, 0x48, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x61, + 0x48, 0x00, 0x28, 0x3E, 0x06, 0x0A, 0x06, 0x42, 0x06, 0x26, 0xB9, 0x41, 0x44, 0x00, 0x6B, 0x13, + 0x00, 0x00, 0x38, 0x71, 0x4C, 0x00, 0x38, 0x41, 0x44, 0x00, 0x06, 0x39, 0x26, 0x42, 0x06, 0x27, + 0xB9, 0x41, 0x44, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x41, 0x44, 0x00, 0x06, 0x38, 0x26, 0x24, + 0x43, 0x22, 0xAB, 0x15, 0x00, 0x00, 0x38, 0x51, 0x50, 0x00, 0x28, 0x3E, 0x0C, 0x0A, 0x43, 0x42, + 0x06, 0x92, 0x06, 0x25, 0xB9, 0x41, 0x3C, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x61, 0x48, 0x00, + 0x28, 0x3E, 0x08, 0x0A, 0x06, 0x52, 0x06, 0x26, 0xB9, 0x51, 0x50, 0x00, 0x6B, 0x13, 0x00, 0x00, + 0x38, 0x71, 0x4C, 0x00, 0x38, 0x51, 0x50, 0x00, 0x06, 0x3B, 0x26, 0x52, 0x06, 0x27, 0xB9, 0x51, + 0x50, 0x00, 0x6B, 0x13, 0x00, 0x00, 0x38, 0x51, 0x50, 0x00, 0x06, 0x38, 0x26, 0x25, 0x43, 0x22, + 0xAB, 0x15, 0x00, 0x00, 0x06, 0x82, 0x43, 0xB2, 0x38, 0x21, 0x1C, 0x00, 0x06, 0x39, 0x6B, 0x13, + 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0x06, 0x92, 0x38, 0x21, 0x20, 0x00, + 0x06, 0x38, 0x6B, 0x13, 0x00, 0x00, 0x0C, 0x30, 0x64, 0x00, 0xAB, 0x15, 0x00, 0x00, 0xB8, 0x51, + 0x40, 0x00, 0x06, 0x82, 0x92, 0x47, 0xC4, 0x90, 0x70, 0x2D, 0x78, 0x3D, 0x04, 0x00, 0x78, 0x5D, + 0x02, 0x00, 0x78, 0x6D, 0x06, 0x00, 0x92, 0x21, 0xB8, 0x71, 0x1C, 0x00, 0x82, 0x1E, 0x38, 0x4E, + 0x64, 0x07, 0xC6, 0xA4, 0x22, 0x07, 0x0C, 0xF0, 0x80, 0x07, 0x3F, 0x44, 0x0F, 0x00, 0xC6, 0xA4, + 0x02, 0x14, 0x36, 0x23, 0xC4, 0x20, 0x32, 0x02, 0x16, 0x22, 0x38, 0x31, 0x34, 0x00, 0xB9, 0x51, + 0x50, 0x00, 0x43, 0x22, 0xB9, 0x61, 0x48, 0x00, 0x0C, 0xF0, 0x98, 0x00, 0xF1, 0xF0, 0x38, 0x61, + 0x48, 0x00, 0x38, 0x51, 0x50, 0x00, 0x06, 0x92, 0xC4, 0x80, 0x92, 0x1C, 0xB8, 0x71, 0x20, 0x00, + 0x82, 0x19, 0x38, 0x4E, 0x68, 0x07, 0x38, 0x71, 0x0C, 0x00, 0xC6, 0x74, 0x22, 0x07, 0x0C, 0x30, + 0x38, 0x04, 0x3F, 0x44, 0x03, 0x00, 0xC6, 0x74, 0x02, 0x0D, 0x3F, 0x26, 0x05, 0x00, 0xC4, 0x20, + 0x32, 0x02, 0x16, 0x22, 0x38, 0x31, 0x38, 0x00, 0x43, 0x22, 0x0C, 0xF0, 0x98, 0x00, 0xF1, 0xF0, + 0x06, 0x82, 0x38, 0x41, 0x3C, 0x00, 0x38, 0x51, 0x18, 0x00, 0x06, 0x64, 0xC6, 0x45, 0x32, 0x02, + 0x06, 0x65, 0x38, 0x71, 0x14, 0x00, 0x43, 0x66, 0xC6, 0xB7, 0xB9, 0x61, 0x18, 0x00, 0x06, 0x6B, + 0x32, 0x02, 0x06, 0x67, 0x38, 0x51, 0x08, 0x00, 0x43, 0x66, 0x15, 0xB5, 0x38, 0x51, 0x04, 0x00, + 0xB9, 0x61, 0x14, 0x00, 0xF7, 0xBF, 0x34, 0x51, 0x60, 0x35, 0x38, 0x61, 0x10, 0x00, 0x33, 0x4B, + 0xC6, 0x34, 0x15, 0xA6, 0xF7, 0xAF, 0x33, 0x6A, 0x92, 0x04, 0x04, 0x71, 0xB9, 0x71, 0x2C, 0x00, + 0x38, 0x71, 0x04, 0x00, 0x60, 0x37, 0xC6, 0x36, 0x92, 0x04, 0x04, 0x71, 0xB9, 0x71, 0x30, 0x00, + 0x91, 0x45, 0x38, 0x51, 0x04, 0x00, 0x06, 0x3D, 0x91, 0x65, 0x04, 0x44, 0x06, 0x21, 0xEB, 0x73, + 0x03, 0x00, 0xCB, 0x3B, 0x00, 0x00, 0x18, 0x6E, 0x9B, 0x04, 0xC4, 0x61, 0xD2, 0x16, 0x28, 0x6E, + 0x06, 0x03, 0x23, 0x22, 0xC6, 0x62, 0xC2, 0x11, 0x78, 0x6D, 0x08, 0x00, 0xC6, 0x69, 0x02, 0x05, + 0xB8, 0x71, 0x2C, 0x00, 0x82, 0x02, 0x06, 0x96, 0x78, 0x6D, 0x0A, 0x00, 0xC6, 0x68, 0x02, 0x05, + 0xB8, 0x51, 0x30, 0x00, 0x82, 0x02, 0x06, 0x86, 0xC4, 0xB0, 0x20, 0x61, 0x82, 0x03, 0x23, 0x79, + 0xF2, 0x03, 0x16, 0x79, 0x23, 0x77, 0xC4, 0xA0, 0x26, 0x76, 0xA1, 0x71, 0x28, 0x71, 0x02, 0x00, + 0x92, 0x02, 0x16, 0x88, 0x23, 0x88, 0x26, 0x87, 0x06, 0x21, 0xA9, 0x81, 0x02, 0x00, 0xAB, 0xCA, + 0x02, 0x00, 0x70, 0x7D, 0x70, 0xA1, 0x3F, 0x77, 0x0A, 0x00, 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, + 0xA9, 0x7D, 0x08, 0x00, 0x78, 0xB1, 0x02, 0x00, 0x78, 0x7D, 0x02, 0x00, 0x3F, 0x77, 0x0B, 0x00, + 0xC4, 0x70, 0x32, 0x02, 0x16, 0x77, 0x04, 0x24, 0x06, 0x3D, 0x04, 0x44, 0x26, 0x2D, 0xA9, 0x7D, + 0x0A, 0x00, 0xEB, 0x73, 0x03, 0x00, 0x06, 0x2D, 0x06, 0x31, 0x04, 0x44, 0xEB, 0x73, 0x03, 0x00, + 0x08, 0x60, 0x00, 0x80, 0x2C, 0x60, 0x0C, 0xDC, 0x18, 0x76, 0x2D, 0x00, 0x04, 0x62, 0xD6, 0x67, + 0x82, 0x06, 0x0C, 0x60, 0x7F, 0x07, 0x3F, 0xAA, 0x06, 0x00, 0x43, 0xAA, 0x04, 0x64, 0xD6, 0x67, + 0x82, 0x06, 0x0C, 0x60, 0x37, 0x04, 0x3F, 0xBB, 0x06, 0x00, 0x43, 0xBB, 0x04, 0x61, 0xD4, 0x71, + 0x26, 0x6C, 0x57, 0x61, 0x23, 0xAA, 0x23, 0xBB, 0x26, 0x6E, 0x82, 0x11, 0x38, 0x76, 0x38, 0x0A, + 0x38, 0x51, 0x24, 0x00, 0x1C, 0x40, 0x00, 0x10, 0x5C, 0xA0, 0xFF, 0x0F, 0x56, 0x74, 0x66, 0x7A, + 0x5C, 0xB0, 0xFF, 0x0F, 0x57, 0xB6, 0x56, 0x75, 0x66, 0x7B, 0xF2, 0x10, 0x38, 0x76, 0x38, 0x0A, + 0x38, 0x51, 0x24, 0x00, 0x1C, 0x40, 0x00, 0x10, 0x5C, 0xB0, 0xFF, 0x0F, 0x56, 0x74, 0x66, 0x7B, + 0x5C, 0xA0, 0xFF, 0x0F, 0x57, 0xA6, 0x56, 0x75, 0x66, 0x7A, 0xB9, 0x76, 0x38, 0x0A, 0x38, 0x71, + 0x28, 0x00, 0x24, 0x71, 0x13, 0x77, 0xB9, 0x71, 0x28, 0x00, 0xFA, 0xBC, 0xFD, 0xFF, 0x0C, 0x20, + 0x0A, 0x0A, 0x26, 0x2E, 0x14, 0x34, 0x26, 0x32, 0x04, 0x44, 0xEB, 0x73, 0x03, 0x00, 0x38, 0x61, + 0x18, 0x00, 0x38, 0x71, 0x14, 0x00, 0xA9, 0x6E, 0x06, 0x0A, 0xA9, 0x7E, 0x08, 0x0A, 0x58, 0xC1, + 0x64, 0x00, 0x58, 0x81, 0x54, 0x00, 0x2C, 0x10, 0x74, 0x00, 0xE1, 0xF0, 0x06, 0x65, 0x0C, 0x60, + 0xB4, 0x16, 0x28, 0x50, 0xB4, 0x16, 0x06, 0x72, 0xC6, 0x25, 0x82, 0x0C, 0x28, 0x56, 0x02, 0x00, + 0xC6, 0x25, 0x82, 0x0A, 0x28, 0x66, 0x04, 0x00, 0x04, 0x20, 0xC6, 0x76, 0x92, 0x07, 0x04, 0x22, + 0xF2, 0x04, 0x04, 0x20, 0xF2, 0x02, 0x04, 0x21, 0x24, 0x21, 0xE1, 0xF0, 0x34, 0x14, 0xB1, 0xF1, + 0x08, 0x50, 0x00, 0x30, 0x18, 0x30, 0xEA, 0x16, 0x0C, 0x60, 0x00, 0x0B, 0x04, 0x70, 0x0C, 0x20, + 0xB4, 0x16, 0x0C, 0xF0, 0x28, 0x08, 0x2C, 0x50, 0x00, 0xA0, 0xC4, 0x30, 0x2F, 0x42, 0x07, 0x00, + 0x20, 0x44, 0x92, 0x07, 0x57, 0x41, 0x26, 0x45, 0x30, 0x44, 0x5C, 0x40, 0xFF, 0x7F, 0xF2, 0x04, + 0x26, 0x44, 0x26, 0x4F, 0x20, 0x44, 0x24, 0x72, 0xC4, 0x76, 0xA1, 0x46, 0x24, 0x62, 0x92, 0xEE, + 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0x00, 0x00, 0x04, 0x70, 0xC6, 0x74, + 0x82, 0x09, 0x2F, 0x67, 0x03, 0x00, 0x60, 0x56, 0x2F, 0x67, 0x02, 0x00, 0x91, 0x56, 0x24, 0x71, + 0xF2, 0xF7, 0xE1, 0xF0, 0x71, 0x00, 0xF2, 0xFF, 0x70, 0x6F, 0x36, 0x76, 0x78, 0x6F, 0x02, 0x00, + 0xC6, 0x76, 0xB2, 0x07, 0x26, 0x77, 0x26, 0x7F, 0x78, 0x77, 0x06, 0x00, 0x26, 0x7F, 0xE1, 0x70, + 0x78, 0x7F, 0x04, 0x00, 0x26, 0x7F, 0xE1, 0x70, 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, + 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, + 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, + 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, + 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, + 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, + 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, + 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, + 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, + 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, + 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, + 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, + 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, + 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, + 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, + 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, + 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3, 0x04, 0x70, 0x06, 0x62, 0x73, 0x67, 0xD4, 0x61, + 0x04, 0x51, 0x26, 0x57, 0x13, 0x55, 0x92, 0x03, 0x06, 0x75, 0xF2, 0xF8, 0x06, 0x27, 0xE1, 0xF0, + 0xC6, 0x23, 0x06, 0x72, 0x02, 0x02, 0x06, 0x73, 0x43, 0x27, 0xE1, 0xF0, 0x34, 0x18, 0xC1, 0xE1, + 0x06, 0xE4, 0xCB, 0x04, 0x00, 0x00, 0x06, 0x3E, 0xCB, 0x04, 0x00, 0x00, 0x40, 0xE1, 0x24, 0x18, + 0xE1, 0xF0, 0x24, 0x00, 0xC6, 0x32, 0x06, 0x73, 0x32, 0x02, 0x06, 0x72, 0x43, 0x27, 0xE1, 0xF0, + 0x34, 0x18, 0xC1, 0xE1, 0x06, 0xE4, 0xEB, 0x05, 0x00, 0x00, 0x06, 0x3E, 0xEB, 0x05, 0x00, 0x00, + 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, 0x24, 0x00, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xE5, + 0x06, 0xD6, 0x4B, 0x06, 0x00, 0x00, 0x06, 0x3E, 0x06, 0x4D, 0x4B, 0x06, 0x00, 0x00, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x24, 0x00, 0x14, 0x71, 0x26, 0x74, 0x26, 0x27, 0x16, 0x64, + 0x26, 0x37, 0x2F, 0x76, 0x03, 0x00, 0x26, 0x62, 0xC4, 0x40, 0x82, 0x09, 0x2F, 0x54, 0x07, 0x00, + 0x60, 0x35, 0x2F, 0x54, 0x06, 0x00, 0x91, 0x35, 0x34, 0x41, 0xF2, 0xF7, 0xE1, 0xF0, 0x24, 0x00, + 0x04, 0x70, 0xC6, 0x74, 0x82, 0x09, 0x2F, 0x67, 0x03, 0x00, 0x60, 0x56, 0x2F, 0x67, 0x02, 0x00, + 0x91, 0x56, 0x24, 0x71, 0xF2, 0xF7, 0xE1, 0xF0, 0x04, 0x70, 0xC6, 0x74, 0x82, 0x0A, 0x2F, 0x67, + 0x07, 0x00, 0x2F, 0x56, 0x03, 0x00, 0x20, 0x55, 0x26, 0x62, 0xA1, 0x56, 0x24, 0x71, 0xF2, 0xF6, + 0xE1, 0xF0, 0x24, 0x00, 0x34, 0x14, 0xB1, 0xF1, 0x04, 0x70, 0x14, 0x61, 0x34, 0x41, 0xC6, 0x46, + 0x82, 0x09, 0x2F, 0x57, 0x03, 0x00, 0x30, 0xF5, 0x2F, 0x57, 0x02, 0x00, 0xB1, 0xF5, 0x24, 0x74, + 0xF2, 0xF6, 0x30, 0xF1, 0x24, 0x14, 0xE1, 0xF0, 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x04, 0x70, + 0x14, 0xF1, 0x34, 0x51, 0xC6, 0x5F, 0x82, 0x0D, 0x2F, 0x67, 0x03, 0x00, 0x30, 0xD6, 0x2F, 0xE7, + 0x02, 0x00, 0xB1, 0xDE, 0x2F, 0xE7, 0x04, 0x00, 0x30, 0xEE, 0x24, 0x74, 0xB1, 0xE6, 0xF2, 0xF2, + 0x50, 0xC1, 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x04, 0x70, 0xC6, 0x74, 0x82, 0x06, 0x2F, 0x67, + 0x02, 0x00, 0x91, 0x36, 0x24, 0x71, 0xF2, 0xFA, 0xE1, 0xF0, 0x24, 0x00, 0x04, 0x70, 0xC6, 0x74, + 0x82, 0x07, 0x2F, 0x67, 0x07, 0x00, 0x26, 0x62, 0xA1, 0x36, 0x24, 0x71, 0xF2, 0xF9, 0xE1, 0xF0, + 0x14, 0x71, 0x34, 0x41, 0xC6, 0x47, 0x82, 0x04, 0xB1, 0x32, 0x24, 0x24, 0xF2, 0xFB, 0xE1, 0xF0, + 0x3C, 0x10, 0x10, 0x00, 0xD1, 0xC1, 0x06, 0xC2, 0x06, 0xD3, 0x06, 0xE3, 0x06, 0x2E, 0x06, 0x3E, + 0x08, 0xF0, 0x00, 0x80, 0x2C, 0xF0, 0x6C, 0x02, 0xF1, 0xF0, 0xC6, 0x2C, 0xC2, 0x02, 0x76, 0xED, + 0xF7, 0xD0, 0xC4, 0xD0, 0x82, 0x03, 0x66, 0xED, 0xF2, 0xF2, 0x06, 0x2E, 0x50, 0xC1, 0x2C, 0x10, + 0x10, 0x00, 0xE1, 0xF0, 0x38, 0x60, 0xB4, 0x15, 0x08, 0x70, 0xFD, 0xFF, 0x2C, 0x70, 0xFF, 0xFF, + 0x56, 0x76, 0x08, 0x50, 0x31, 0x00, 0xC6, 0x75, 0x82, 0x05, 0x08, 0x70, 0x32, 0x00, 0xC6, 0x67, + 0x92, 0x03, 0xB1, 0x32, 0xE1, 0xF0, 0xF2, 0x00, 0x08, 0x20, 0x00, 0x40, 0x34, 0x14, 0x2C, 0x20, + 0x10, 0x60, 0x0C, 0x30, 0x00, 0xDE, 0xB1, 0xF1, 0x0B, 0x14, 0x00, 0x00, 0x30, 0xF1, 0x24, 0x14, + 0xE1, 0xF0, 0x24, 0x00, 0x08, 0x70, 0x00, 0x40, 0xB9, 0x07, 0x10, 0x60, 0xE1, 0xF0, 0x24, 0x00, + 0x34, 0x14, 0x0C, 0x70, 0x1E, 0x00, 0xB1, 0x71, 0x30, 0x71, 0x14, 0x61, 0xC4, 0x70, 0x26, 0x67, + 0xB1, 0x61, 0x92, 0xFB, 0x24, 0x14, 0xE1, 0xF0, 0xE1, 0xF0, 0x24, 0x00, 0x3C, 0x10, 0x10, 0x00, + 0xD1, 0xC1, 0x06, 0x72, 0x08, 0xE0, 0x00, 0x40, 0x0C, 0x20, 0x00, 0x60, 0x06, 0xD3, 0x26, 0x2E, + 0x06, 0x37, 0xB9, 0x0E, 0x90, 0x60, 0x0B, 0x14, 0x00, 0x00, 0x0C, 0x20, 0x08, 0x60, 0xB9, 0xDE, + 0x04, 0x60, 0x26, 0x2E, 0x04, 0x30, 0x0B, 0x14, 0x00, 0x00, 0x38, 0x7E, 0x90, 0x60, 0xD4, 0x71, + 0x82, 0xFD, 0x0C, 0x70, 0x00, 0x81, 0xB9, 0x7E, 0x00, 0x60, 0x6B, 0x16, 0x00, 0x00, 0x50, 0xC1, + 0x2C, 0x10, 0x10, 0x00, 0xE1, 0xF0, 0x24, 0x00, 0x3C, 0x10, 0x20, 0x00, 0xD9, 0xC1, 0x10, 0x00, + 0x06, 0x72, 0x08, 0xD0, 0x00, 0x40, 0x0C, 0x20, 0x00, 0x60, 0xD1, 0x81, 0x06, 0xE3, 0x06, 0xB5, + 0x26, 0x2D, 0x06, 0x37, 0x0C, 0xA0, 0x08, 0x60, 0x06, 0xC4, 0x26, 0xBE, 0x0B, 0x14, 0x00, 0x00, + 0x26, 0xAD, 0xC6, 0xEB, 0x82, 0x10, 0xB9, 0xED, 0x04, 0x60, 0x30, 0x3C, 0x04, 0x91, 0x06, 0x2A, + 0x26, 0x9E, 0x0B, 0x14, 0x00, 0x00, 0x38, 0x7D, 0x90, 0x60, 0xD4, 0x72, 0x82, 0xFD, 0x24, 0xC4, + 0x06, 0xE9, 0xF2, 0xF0, 0x0C, 0x70, 0x00, 0x81, 0xB9, 0x7D, 0x00, 0x60, 0x6B, 0x16, 0x00, 0x00, + 0x58, 0xC1, 0x10, 0x00, 0x50, 0x81, 0x2C, 0x10, 0x20, 0x00, 0xE1, 0xF0, 0x3C, 0x10, 0x14, 0x00, + 0xD9, 0xC1, 0x04, 0x00, 0x86, 0xD6, 0x08, 0x70, 0x00, 0x40, 0x82, 0x05, 0x0C, 0x60, 0x00, 0xDE, + 0xB9, 0x67, 0x10, 0x60, 0xB9, 0x27, 0x00, 0x60, 0xB9, 0x37, 0x04, 0x60, 0x04, 0x61, 0x04, 0x70, + 0x08, 0x20, 0x00, 0x40, 0xC6, 0x75, 0x82, 0x0E, 0xB1, 0x61, 0x30, 0x31, 0x14, 0xF1, 0xC4, 0x30, + 0x26, 0xF3, 0xB1, 0xF1, 0x92, 0xFB, 0x38, 0x32, 0x0C, 0x60, 0x24, 0x71, 0xB1, 0x34, 0x24, 0x44, + 0xF2, 0xF2, 0x08, 0xE0, 0x00, 0x40, 0x0C, 0x70, 0x00, 0x81, 0xB9, 0x7E, 0x00, 0x60, 0x6B, 0x16, + 0x00, 0x00, 0xC4, 0xD0, 0x82, 0x03, 0xB9, 0x0E, 0x10, 0x60, 0x58, 0xC1, 0x04, 0x00, 0x04, 0x21, + 0x2C, 0x10, 0x14, 0x00, 0xE1, 0xF0, 0x24, 0x00, 0x34, 0x18, 0xC1, 0xE1, 0x08, 0x70, 0x00, 0x40, + 0x0C, 0x60, 0x00, 0xDE, 0xB9, 0x67, 0x10, 0x60, 0x77, 0x41, 0xB9, 0x27, 0x00, 0x60, 0x77, 0x31, + 0x34, 0x41, 0x08, 0x60, 0x00, 0x13, 0xB9, 0x37, 0x04, 0x60, 0x66, 0x46, 0xB9, 0x47, 0x14, 0x60, + 0x08, 0x50, 0x00, 0x10, 0x38, 0x67, 0x14, 0x60, 0x0C, 0x40, 0x14, 0x60, 0xD6, 0x65, 0x26, 0x47, + 0x92, 0xFA, 0x38, 0xE7, 0x18, 0x60, 0xB1, 0x04, 0x0C, 0x60, 0x00, 0x81, 0xB9, 0x67, 0x00, 0x60, + 0xB9, 0x07, 0x10, 0x60, 0x6B, 0x16, 0x00, 0x00, 0x06, 0x2E, 0x40, 0xE1, 0x24, 0x18, 0xE1, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x18, 0x0E, 0x17, 0x0E, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0x02, 0x06, 0x0B, 0xFF, 0x17, 0x17, 0x17, 0xFF, 0x00, + 0x80, 0x07, 0x38, 0x04, 0xFF, 0x1F, 0xFF, 0x11, 0xD0, 0x07, 0xD0, 0x07, 0x01, 0xFA, 0xFA, 0x00, + 0x00, 0x02, 0x01, 0x46, 0x00, 0x01, 0x00, 0x02, 0x0A, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x4E, 0x00, 0x00, 0xE0, 0x2E, 0x00, 0x00, + 0xE0, 0x2E, 0x00, 0x00, 0xA0, 0x86, 0x01, 0x00, 0x00, 0x24, 0xF4, 0x00, 0x50, 0xC3, 0x00, 0x00, + 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0xC8, 0x00, 0x6E, 0x50, 0x0A, 0x14, 0x01, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x5A, 0x00, 0x01, 0x00, 0x0A, 0x00, 0xA0, 0x0F, 0x64, 0x64, 0x64, 0x01, 0x0E, 0x20, + 0x02, 0x04, 0x02, 0x07, 0x03, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x50, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x05, 0x05, 0x08, 0x0E, 0x11, 0x17, 0x17, 0x17, 0x17, 0x02, 0x03, 0x04, + 0x02, 0x01, 0x00, 0x04, 0x00, 0x06, 0x01, 0x03, 0x08, 0x04, 0x10, 0x03, 0x03, 0x00, 0x90, 0x01, + 0x00, 0x00, 0x32, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x42, 0x22, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, + 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x08, 0x82, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x28, 0x18, 0x14, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x28, 0x18, 0x14, 0x00, 0x28, 0x18, 0x14, 0x00, 0x28, 0x18, 0x14, 0x00, + 0x51, 0x06, 0x02, 0x00, 0x63, 0x07, 0x02, 0x00, 0x63, 0x07, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x40, 0x0F, 0x40, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x54, 0x28, 0x00, 0x02, + 0x66, 0x7F, 0xF0, 0x07, 0x66, 0x7F, 0xF0, 0x07, 0x42, 0x22, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, + 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x08, 0x82, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x12, 0x0A, 0x12, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x12, 0x0A, 0x12, 0x00, 0x12, 0x0A, 0x12, 0x00, 0x12, 0x0A, 0x12, 0x00, + 0x51, 0xE6, 0x00, 0x00, 0x63, 0x07, 0x02, 0x00, 0x63, 0x07, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x40, 0x0F, 0x40, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x54, 0x10, 0xB0, 0x00, + 0x66, 0x7F, 0xF0, 0x07, 0x66, 0x7F, 0xF0, 0x07, 0x42, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, + 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x08, 0x82, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x00, 0x28, 0x18, 0x14, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x28, 0x18, 0x14, 0x00, 0x28, 0x18, 0x14, 0x00, 0x28, 0x18, 0x14, 0x00, + 0x61, 0x07, 0x02, 0x00, 0x63, 0x07, 0x02, 0x00, 0x63, 0x07, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x40, 0x0F, 0x40, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x54, 0x28, 0x00, 0x02, + 0x66, 0x7F, 0xF0, 0x07, 0x66, 0x7F, 0xF0, 0x07, 0x42, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, + 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x64, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x08, 0x82, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x64, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x12, 0x0A, 0x12, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x12, 0x0A, 0x12, 0x00, 0x12, 0x0A, 0x12, 0x00, 0x12, 0x0A, 0x12, 0x00, + 0x61, 0xE7, 0x00, 0x00, 0x63, 0x07, 0x02, 0x00, 0x63, 0x07, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x40, 0x0F, 0x40, 0x0F, 0x00, 0x0E, 0x00, 0x0E, 0x54, 0x10, 0xB0, 0x00, + 0x66, 0x7F, 0xF0, 0x07, 0x66, 0x7F, 0xF0, 0x07, 0x02, 0x00, 0x00, 0x00, 0x80, 0x40, 0x05, 0x00, + 0x50, 0x07, 0x05, 0x50, 0xC8, 0x00, 0x90, 0x01, 0x32, 0x00, 0x32, 0x00, 0x19, 0x19, 0x32, 0x00, + 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x64, 0x64, 0xC8, 0x00, 0x14, 0x00, 0x01, 0x00, 0x32, 0x00, + 0x3C, 0x00, 0x14, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x64, 0x00, 0x00, 0x00, 0x3C, 0x00, + 0x14, 0x00, 0x64, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1E, 0x00, 0x64, 0x00, 0x20, 0x03, 0x64, 0x00, 0x64, 0x00, + 0x14, 0x00, 0x96, 0x00, 0x00, 0x05, 0x04, 0x0A, 0x05, 0x06, 0xC8, 0x00, 0x05, 0x32, 0x0A, 0x17, + 0x19, 0x17, 0x19, 0x1B, 0x19, 0x19, 0x16, 0x19, 0x1E, 0x1E, 0x1E, 0x19, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x3C, 0x06, 0x64, 0x02, 0x28, 0x20, 0x03, 0xDC, 0x05, 0xC8, 0x00, 0x14, 0x00, 0x28, 0x00, + 0x14, 0x00, 0x0A, 0x00, 0x46, 0x02, 0x02, 0x01, 0x01, 0x00, 0x1E, 0x00, 0x32, 0x00, 0x64, 0x00, + 0x14, 0x01, 0x02, 0x03, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x19, 0x00, 0x32, 0x00, 0x5A, 0x00, 0x02, 0x00, 0x64, 0x00, + 0x32, 0x32, 0x14, 0x00, 0x00, 0x00, 0x32, 0x00, 0x3C, 0x00, 0x0A, 0x0A, 0x1E, 0x00, 0x05, 0x0A, + 0x01, 0x00, 0x3C, 0x00, 0x50, 0x00, 0x05, 0x00, 0x82, 0x00, 0xC8, 0x00, 0x05, 0x05, 0x14, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x40, 0x05, 0x00, 0x50, 0x07, 0x05, 0x50, + 0xC8, 0x00, 0x90, 0x01, 0x32, 0x00, 0x32, 0x00, 0x19, 0x19, 0x64, 0x00, 0x00, 0x00, 0x32, 0x00, + 0x00, 0x00, 0x64, 0x64, 0xC8, 0x00, 0x14, 0x00, 0x01, 0x00, 0x32, 0x00, 0x3C, 0x00, 0x14, 0x00, + 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x64, 0x00, 0x00, 0x00, 0xC4, 0xFF, 0x14, 0x00, 0x64, 0x00, + 0x00, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x1E, 0x00, 0x1E, 0x00, 0x20, 0x03, 0x64, 0x00, 0x64, 0x00, 0x14, 0x00, 0x96, 0x00, + 0x00, 0x05, 0x04, 0x0A, 0x05, 0x06, 0xDC, 0x00, 0x05, 0x32, 0x0A, 0x17, 0x19, 0x17, 0x19, 0x1B, + 0x19, 0x19, 0x16, 0x19, 0x1E, 0x1E, 0x1E, 0x19, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3C, 0x0A, 0x64, + 0x03, 0x0A, 0x20, 0x03, 0xDC, 0x05, 0xC8, 0x00, 0x14, 0x00, 0x28, 0x00, 0x1E, 0x00, 0x0A, 0x00, + 0x46, 0x02, 0x02, 0x01, 0x01, 0x00, 0x1E, 0x00, 0x32, 0x00, 0x64, 0x00, 0x14, 0x01, 0x02, 0x03, + 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x0F, 0x00, 0x19, 0x00, 0x32, 0x00, 0x5A, 0x00, 0x02, 0x00, 0x64, 0x00, 0x32, 0x32, 0x14, 0x00, + 0x00, 0x00, 0x32, 0x00, 0x64, 0x00, 0x0A, 0x0A, 0x3C, 0x00, 0x05, 0x0A, 0x01, 0x00, 0x3C, 0x00, + 0x50, 0x00, 0x05, 0x00, 0x82, 0x00, 0xC8, 0x00, 0x05, 0x05, 0x1E, 0x00, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0E, 0x18, 0x0E, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0x00, 0x10, 0x08, 0x12, 0x00, 0x54, 0xFF, 0x0F, 0x00, 0x10, 0x90, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x64, 0x00, 0x16, 0x32, 0x10, 0x10, 0x01, 0x00, 0x08, 0x00, + 0x32, 0x00, 0x64, 0x10, 0x51, 0xC6, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x64, 0xC0, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0F, 0x40, 0x0F, + 0x01, 0x01, 0x80, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x80, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, + 0xE0, 0x0F, 0x00, 0x00, 0x08, 0x07, 0x98, 0x08, 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, + 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x22, 0x01, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x88, 0x00, 0x10, 0x1F, 0x10, 0x1F, 0x64, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x08, 0x82, + 0x00, 0x00, 0xFF, 0x0F, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xAC, 0x0D, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x10, 0xB0, 0x00, + 0xD5, 0xC6, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0E, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x21, 0x50, 0x06, 0x00, 0x2F, 0x01, 0x03, 0x00, + 0x1B, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0x04, 0x40, 0x00, 0x04, 0x22, 0x88, 0x00, 0x00, 0xFF, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x7F, 0xFC, 0x8F, 0xBF, 0x01, 0x20, 0x00, 0x00, + 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x13, 0x12, 0x11, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x00, + 0x00, 0x00, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x17, 0x00, 0x00, 0xFF, 0x00, 0x20, 0x86, 0x00, 0x00, 0x00, 0x4C, + 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x26, 0x18, 0x00, + 0x38, 0x26, 0x10, 0x01, 0x45, 0x26, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x28, 0x08, 0x03, + 0x30, 0x26, 0x0A, 0x00, 0x28, 0x26, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x26, 0x07, 0x13, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4E, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x25, 0xDC, 0x05, 0x00, 0x27, 0x0C, 0x00, 0x00, 0x25, 0xFC, 0x0F, 0x00, 0x25, + 0xFC, 0x0F, 0x00, 0x27, 0xFC, 0x0F, 0x00, 0x25, 0x54, 0x06, 0x00, 0x25, 0x1C, 0x00, 0x00, 0x27, + 0x34, 0x00, 0x00, 0x25, 0xC4, 0x05, 0x00, 0x25, 0x9C, 0x05, 0x00, 0x23, 0x08, 0x00, 0x00, 0x1B, + 0x30, 0x00, 0x00, 0x1C, 0xC4, 0x07, 0x00, 0x1A, 0x98, 0x03, 0x00, 0x1A, 0xB0, 0x02, 0x00, 0x1B, + 0xEC, 0x00, 0x00, 0x18, 0xFC, 0x0F, 0x00, 0x19, 0x08, 0x00, 0x00, 0x1B, 0x08, 0x00, 0x00, 0x1B, + 0x34, 0x04, 0x00, 0x1B, 0x2C, 0x00, 0x00, 0x1B, 0x18, 0x00, 0x00, 0x17, 0x1C, 0x00, 0x50, 0xBF, + 0x00, 0x0E, 0x00, 0x23, 0xF4, 0x0F, 0x00, 0x25, 0xFC, 0x0F, 0x00, 0x23, 0x00, 0x00, 0x00, 0x23, + 0x30, 0x01, 0x00, 0x25, 0xFC, 0x0F, 0x00, 0x23, 0xE0, 0x00, 0x00, 0x23, 0xFC, 0x0F, 0x00, 0x25, + 0xFC, 0x0F, 0x00, 0x23, 0x00, 0x00, 0x00, 0x23, 0xB8, 0x07, 0x00, 0x21, 0x10, 0x00, 0x00, 0x1C, + 0xE0, 0x00, 0x00, 0x1D, 0xFC, 0x0F, 0x00, 0x1B, 0xFC, 0x0F, 0x00, 0x1B, 0x0C, 0x00, 0x00, 0x1C, + 0x1C, 0x00, 0x00, 0x19, 0xB0, 0x01, 0x00, 0x1A, 0x30, 0x01, 0x00, 0x1C, 0x1C, 0x01, 0x00, 0x1C, + 0xDC, 0x00, 0x00, 0x1C, 0x24, 0x07, 0x00, 0x1C, 0xB8, 0x01, 0x00, 0x18, 0x98, 0x0B, 0x50, 0xBF, + 0x24, 0x04, 0x00, 0x22, 0xE4, 0x00, 0x00, 0x24, 0xFC, 0x0F, 0x00, 0x22, 0x24, 0x00, 0x00, 0x22, + 0x3C, 0x00, 0x00, 0x24, 0x14, 0x00, 0x00, 0x22, 0xD0, 0x01, 0x00, 0x22, 0xF4, 0x0F, 0x00, 0x24, + 0xFC, 0x0F, 0x00, 0x22, 0x00, 0x00, 0x00, 0x22, 0x1C, 0x00, 0x00, 0x23, 0x08, 0x00, 0x00, 0x1D, + 0x04, 0x03, 0x00, 0x1E, 0xF4, 0x0F, 0x00, 0x1C, 0xFC, 0x0F, 0x00, 0x1C, 0xB8, 0x0E, 0x00, 0x1D, + 0x90, 0x00, 0x00, 0x1A, 0x18, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1D, 0x0C, 0x00, 0x00, 0x1D, + 0x08, 0x00, 0x00, 0x1D, 0xB8, 0x0E, 0x00, 0x1D, 0xF4, 0x0F, 0x00, 0x19, 0xFC, 0x0F, 0x50, 0x20, + 0x04, 0x00, 0x00, 0x22, 0x0C, 0x04, 0x00, 0x24, 0x04, 0x00, 0x00, 0x22, 0x38, 0x0E, 0x00, 0x22, + 0x9C, 0x00, 0x00, 0x24, 0xDC, 0x01, 0x00, 0x22, 0x80, 0x0D, 0x00, 0x22, 0xFC, 0x0F, 0x00, 0x24, + 0xFC, 0x0F, 0x00, 0x22, 0xB8, 0x0E, 0x00, 0x22, 0x1C, 0x00, 0x00, 0x20, 0x78, 0x06, 0x00, 0x1E, + 0x00, 0x00, 0x00, 0x1F, 0x50, 0x01, 0x00, 0x1D, 0xFC, 0x0F, 0x00, 0x1D, 0x10, 0x00, 0x00, 0x1E, + 0xE0, 0x00, 0x00, 0x1B, 0xFC, 0x0F, 0x00, 0x1C, 0x3C, 0x00, 0x00, 0x1E, 0x24, 0x00, 0x00, 0x1E, + 0xD8, 0x01, 0x00, 0x1E, 0x10, 0x00, 0x00, 0x1E, 0x04, 0x02, 0x00, 0x1A, 0x1C, 0x00, 0x50, 0xBF, + 0x00, 0x00, 0x00, 0x21, 0x1C, 0x00, 0x00, 0x23, 0x08, 0x00, 0x00, 0x21, 0xD0, 0x01, 0x00, 0x21, + 0xE4, 0x0F, 0x00, 0x23, 0xFC, 0x0F, 0x00, 0x21, 0x24, 0x0D, 0x00, 0x21, 0x0C, 0x07, 0x00, 0x23, + 0x0C, 0x00, 0x00, 0x21, 0x08, 0x00, 0x00, 0x21, 0x1C, 0x04, 0x00, 0x1F, 0xF4, 0x0F, 0x00, 0x1F, + 0x08, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x1E, 0x24, 0x0D, 0x00, 0x1E, 0xC4, 0x0B, 0x00, 0x1F, + 0xF8, 0x0F, 0x00, 0x1C, 0xFC, 0x0F, 0x00, 0x1D, 0x04, 0x00, 0x00, 0x1F, 0x38, 0x0C, 0x00, 0x1F, + 0x0C, 0x01, 0x00, 0x1F, 0x04, 0x0A, 0x00, 0x1F, 0x2C, 0x0E, 0x00, 0x1B, 0xEC, 0x0F, 0x50, 0xBF, + 0x00, 0x00, 0x00, 0x21, 0x38, 0x0D, 0x00, 0x23, 0x9C, 0x00, 0x00, 0x21, 0xD4, 0x02, 0x00, 0x21, + 0x9C, 0x0D, 0x00, 0x23, 0xFC, 0x0F, 0x00, 0x21, 0x04, 0x09, 0x00, 0x21, 0xF8, 0x0F, 0x00, 0x23, + 0xFC, 0x0F, 0x00, 0x21, 0x00, 0x01, 0x00, 0x21, 0xF8, 0x0F, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x1F, + 0x68, 0x06, 0x00, 0x20, 0x04, 0x00, 0x00, 0x1E, 0x58, 0x01, 0x00, 0x1E, 0x10, 0x00, 0x00, 0x1F, + 0x50, 0x01, 0x00, 0x1C, 0xEC, 0x0F, 0x00, 0x1D, 0x20, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x1F, + 0xFC, 0x0F, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x1F, 0xD8, 0x01, 0x00, 0x1B, 0xF4, 0x0F, 0x50, 0xBF, + 0x84, 0x06, 0x00, 0x20, 0xFC, 0x0F, 0x00, 0x22, 0xFC, 0x0F, 0x00, 0x20, 0x80, 0x05, 0x00, 0x20, + 0x0C, 0x00, 0x00, 0x22, 0x18, 0x0E, 0x00, 0x20, 0xB8, 0x07, 0x00, 0x20, 0x18, 0x00, 0x00, 0x22, + 0xB8, 0x07, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0xB8, 0x07, 0x00, 0x21, 0x0C, 0x00, 0x00, 0x20, + 0x04, 0x01, 0x00, 0x21, 0x1C, 0x00, 0x00, 0x1F, 0x1C, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x20, + 0xD4, 0x05, 0x00, 0x1D, 0x9C, 0x0E, 0x00, 0x1E, 0xB0, 0x01, 0x00, 0x20, 0x38, 0x01, 0x00, 0x20, + 0x1C, 0x01, 0x00, 0x20, 0xC4, 0x00, 0x00, 0x20, 0x2C, 0x03, 0x00, 0x1C, 0xFC, 0x0F, 0x50, 0x20, + 0x90, 0x0B, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x21, 0xFC, 0x0F, 0x00, 0x1F, 0x24, 0x01, 0x00, 0x1F, + 0xBC, 0x04, 0x00, 0x21, 0x2C, 0x04, 0x00, 0x1F, 0xF0, 0x02, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x21, + 0xFC, 0x0F, 0x00, 0x1F, 0x0C, 0x00, 0x00, 0x1F, 0x1C, 0x01, 0x00, 0x1D, 0xF8, 0x0F, 0x00, 0x21, + 0x00, 0x00, 0x00, 0x22, 0x78, 0x06, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0xC4, 0x00, 0x00, 0x21, + 0xF4, 0x0F, 0x00, 0x1E, 0xFC, 0x0F, 0x00, 0x1F, 0x10, 0x00, 0x00, 0x21, 0x58, 0x01, 0x00, 0x21, + 0xF4, 0x0F, 0x00, 0x21, 0x04, 0x01, 0x00, 0x21, 0x2C, 0x00, 0x00, 0x1D, 0x14, 0x00, 0x50, 0xBF, + 0xE0, 0x00, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x21, 0xFC, 0x0F, 0x00, 0x1F, 0xC0, 0x01, 0x00, 0x1F, + 0xF8, 0x0F, 0x00, 0x21, 0xFC, 0x0F, 0x00, 0x1F, 0x0C, 0x00, 0x00, 0x1F, 0x18, 0x0E, 0x00, 0x21, + 0xFC, 0x0F, 0x00, 0x1F, 0x10, 0x00, 0x00, 0x1F, 0x7C, 0x01, 0x00, 0x1D, 0xB8, 0x07, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x23, 0x7C, 0x01, 0x00, 0x21, 0x3C, 0x01, 0x00, 0x21, 0x08, 0x00, 0x00, 0x22, + 0x18, 0x03, 0x00, 0x1F, 0xBC, 0x07, 0x00, 0x20, 0x04, 0x00, 0x00, 0x22, 0x7C, 0x06, 0x00, 0x22, + 0xB8, 0x07, 0x00, 0x22, 0x14, 0x00, 0x00, 0x22, 0x18, 0x00, 0x00, 0x1E, 0x14, 0x00, 0x50, 0xBF, + 0x38, 0x07, 0x00, 0x1E, 0x1C, 0x00, 0x00, 0x20, 0x1C, 0x00, 0x00, 0x1E, 0x14, 0x00, 0x00, 0x1E, + 0xDC, 0x05, 0x00, 0x20, 0x3C, 0x07, 0x00, 0x1E, 0x90, 0x0A, 0x00, 0x1E, 0xFC, 0x0F, 0x00, 0x20, + 0xFC, 0x0F, 0x00, 0x1E, 0xB0, 0x04, 0x00, 0x1E, 0x0C, 0x00, 0x00, 0x1C, 0x18, 0x01, 0x00, 0x23, + 0xB8, 0x07, 0x00, 0x24, 0x18, 0x00, 0x00, 0x22, 0xB8, 0x07, 0x00, 0x22, 0x10, 0x00, 0x00, 0x23, + 0x78, 0x06, 0x00, 0x20, 0x04, 0x00, 0x00, 0x21, 0x04, 0x0E, 0x00, 0x23, 0x48, 0x01, 0x00, 0x23, + 0xFC, 0x0F, 0x00, 0x23, 0xE0, 0x00, 0x00, 0x23, 0xFC, 0x0F, 0x00, 0x1F, 0xFC, 0x0F, 0x50, 0xBF, + 0x90, 0x05, 0x00, 0x1E, 0x48, 0x05, 0x00, 0x20, 0xE0, 0x05, 0x00, 0x1E, 0x30, 0x07, 0x00, 0x1E, + 0x38, 0x06, 0x00, 0x20, 0x40, 0x06, 0x00, 0x1E, 0x50, 0x06, 0x00, 0x1E, 0xBC, 0x06, 0x00, 0x20, + 0x6C, 0x07, 0x00, 0x1E, 0x10, 0x08, 0x00, 0x1E, 0x4C, 0x08, 0x00, 0x1C, 0xCC, 0x06, 0x00, 0x24, + 0x14, 0x06, 0x00, 0x25, 0xE0, 0x06, 0x00, 0x23, 0x08, 0x07, 0x00, 0x23, 0x0C, 0x07, 0x00, 0x24, + 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x54, 0x00, 0x00, 0x24, 0x0C, 0x0A, 0x00, 0x24, + 0xEC, 0x0F, 0x00, 0x24, 0x34, 0x00, 0x00, 0x24, 0xFC, 0x0F, 0x00, 0x20, 0xFC, 0x0F, 0x50, 0xBF, + 0x94, 0x0D, 0x00, 0x1D, 0xD4, 0x00, 0x00, 0x1F, 0x70, 0x0D, 0x00, 0x1D, 0x24, 0x00, 0x00, 0x1D, + 0xFC, 0x0F, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x1D, 0xAC, 0x0C, 0x00, 0x1D, 0xF8, 0x0F, 0x00, 0x1F, + 0xFC, 0x0F, 0x00, 0x1D, 0xD0, 0x00, 0x00, 0x1D, 0x1C, 0x08, 0x00, 0x1E, 0x74, 0x00, 0x00, 0x25, + 0x80, 0x07, 0x00, 0x26, 0xFC, 0x0F, 0x00, 0x24, 0xFC, 0x0F, 0x00, 0x24, 0xF0, 0x0F, 0x00, 0x25, + 0xFC, 0x0F, 0x00, 0x22, 0xFC, 0x0F, 0x00, 0x23, 0x00, 0x08, 0x00, 0x25, 0xEC, 0x0F, 0x00, 0x25, + 0xFC, 0x0F, 0x00, 0x25, 0xFC, 0x0F, 0x00, 0x25, 0x1C, 0x0C, 0x00, 0x21, 0xC4, 0x06, 0x50, 0x1D, + 0x4C, 0x0C, 0x00, 0x1D, 0x74, 0x03, 0x00, 0x1F, 0xF8, 0x0F, 0x00, 0x1D, 0x60, 0x0E, 0x00, 0x1D, + 0xF8, 0x0F, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x1D, 0x08, 0x0C, 0x00, 0x1D, 0x5C, 0x00, 0x00, 0x1F, + 0x74, 0x04, 0x00, 0x1D, 0xFC, 0x0F, 0x00, 0x1D, 0xEC, 0x0F, 0x00, 0x1B, 0xFC, 0x0F, 0x00, 0x27, + 0xC0, 0x04, 0x00, 0x28, 0xFC, 0x0F, 0x00, 0x26, 0xFC, 0x0F, 0x00, 0x26, 0x60, 0x00, 0x00, 0x27, + 0x14, 0x0C, 0x00, 0x24, 0x20, 0x00, 0x00, 0x25, 0xAC, 0x07, 0x00, 0x27, 0xFC, 0x0F, 0x00, 0x27, + 0xFC, 0x0F, 0x00, 0x27, 0x14, 0x00, 0x00, 0x27, 0x8C, 0x0F, 0x00, 0x23, 0xF4, 0x0F, 0x50, 0x3F, + 0x60, 0x0F, 0x00, 0x1D, 0xFC, 0x0F, 0x00, 0x1F, 0xFC, 0x0F, 0x00, 0x1D, 0xE0, 0x09, 0x00, 0x1D, + 0x14, 0x00, 0x00, 0x1F, 0xF4, 0x0F, 0x00, 0x1D, 0x04, 0x00, 0x00, 0x1D, 0xF8, 0x0F, 0x00, 0x1F, + 0xFC, 0x0F, 0x00, 0x1D, 0x60, 0x07, 0x00, 0x1D, 0x04, 0x04, 0x00, 0x1B, 0x70, 0x00, 0x00, 0x29, + 0x00, 0x0C, 0x00, 0x2A, 0x24, 0x00, 0x00, 0x28, 0xF4, 0x0F, 0x00, 0x28, 0xFC, 0x0F, 0x00, 0x29, + 0xFC, 0x0F, 0x00, 0x26, 0xFC, 0x0F, 0x00, 0x27, 0x00, 0x0C, 0x00, 0x29, 0xD4, 0x0F, 0x00, 0x29, + 0xFC, 0x0F, 0x00, 0x29, 0x90, 0x04, 0x00, 0x29, 0xFC, 0x0F, 0x00, 0x25, 0xFC, 0x0F, 0x50, 0x3F, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x90, 0xF0, 0x3F, 0x21, 0xB0, 0xF0, 0x3F, 0x42, 0xB0, 0xF0, 0x7F, 0x63, 0xB0, 0xF0, 0x3F, + 0x84, 0xB0, 0xF0, 0x3F, 0xA5, 0xB0, 0xF0, 0x3F, 0xC6, 0xB0, 0xF0, 0x7F, 0xE7, 0xB0, 0xF0, 0x3F, + 0x08, 0xB1, 0xF0, 0x3F, 0x29, 0xB1, 0xF0, 0x3F, 0x4A, 0xB1, 0xF0, 0x3F, 0x6B, 0xB1, 0xF0, 0x7F, + 0x8C, 0xB1, 0xF0, 0x3F, 0xAD, 0xA1, 0xF0, 0x3F, 0x00, 0x80, 0xF0, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3B, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, + 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0xC0, 0xF1, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x7F, 0xFC, 0x8F, 0x1F, 0x7F, 0xFC, 0x8F, 0x3F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, + 0x30, 0x30, 0x30, 0x30, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, 0x04, 0x41, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0A, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x30, 0x00, 0x49, 0x00, 0x30, 0x00, 0xA0, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x35, 0x45, 0x1D, 0x01, 0xC6, 0x9A, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x8C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x49, 0x53, 0x54, 0x56, 0x32, 0x54, 0x41, 0x47, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xDC, 0x00, 0x00, + 0x00, 0xDC, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x00, 0xE2, 0x00, 0x80, 0x00, 0x0E, 0x00, 0x00, + 0x00, 0xF0, 0x00, 0x80, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0xFC, 0x0A, 0x00, 0x00, + 0x00, 0x49, 0x00, 0x30, 0x00, 0xA0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xBE, 0xE7, 0x10, 0x5B, 0x69, 0x8C, 0x96, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x07, 0xE0, 0x07, 0x0C, 0x19, 0x03, 0x00, 0x49, 0x53, 0x54, 0x56, 0x32, 0x54, 0x41, 0x47 +}; + +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_misc.c b/drivers/input/touchscreen/ist3038c/ist30xxc_misc.c new file mode 100644 index 000000000000..d29b50d318b3 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_misc.c @@ -0,0 +1,2325 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ist30xxc.h" +#include "ist30xxc_update.h" +#include "ist30xxc_misc.h" + +#define TSP_CH_UNUSED (0) +#define TSP_CH_SCREEN (1) +#define TSP_CH_GTX (2) +#define TSP_CH_KEY (3) +#define TSP_CH_UNKNOWN (-1) + +#define TOUCH_NODE_PARSING_DEBUG (1) + +static u32 ist30xx_frame_buf[IST30XX_MAX_NODE_NUM]; +static u32 ist30xx_frame_rawbuf[IST30XX_MAX_NODE_NUM]; +static u32 ist30xx_frame_fltbuf[IST30XX_MAX_NODE_NUM]; +static u32 ist30xx_frame_cpbuf[IST30XX_MAX_NODE_NUM]; +int ist30xx_check_valid_ch(struct ist30xx_data *data, int ch_tx, int ch_rx) +{ + int i; + TKEY_INFO *tkey = &data->tkey_info; + TSP_INFO *tsp = &data->tsp_info; + + if (unlikely((ch_tx >= tsp->ch_num.tx) || (ch_rx >= tsp->ch_num.rx))) + return TSP_CH_UNKNOWN; + + if ((ch_tx >= tsp->screen.tx) || (ch_rx >= tsp->screen.rx)) { + if (tsp->gtx.num) { + for (i = 0; i < tsp->gtx.num; i++) { + if ((ch_tx == tsp->gtx.ch_num[i]) && (ch_rx < tsp->screen.rx)) + return TSP_CH_GTX; + } + } + + if (tkey->enable) { + for (i = 0; i < tkey->key_num; i++) { + if ((ch_tx == tkey->ch_num[i].tx) && + (ch_rx == tkey->ch_num[i].rx)) + return TSP_CH_KEY; + } + } + } else { + return TSP_CH_SCREEN; + } + + return TSP_CH_UNUSED; +} + +int ist30xx_parse_touch_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node) +{ +#if TOUCH_NODE_PARSING_DEBUG + int j; + TSP_INFO *tsp = &data->tsp_info; +#endif + int i; + u16 *raw = (u16 *)&node->raw; + u16 *base = (u16 *)&node->base; + u16 *filter = (u16 *)&node->filter; + u32 *tmp_rawbuf = ist30xx_frame_rawbuf; + u32 *tmp_fltbuf = ist30xx_frame_fltbuf; + + for (i = 0; i < node->len; i++) { + if (flag & (NODE_FLAG_RAW | NODE_FLAG_BASE)) { + *raw++ = *tmp_rawbuf & 0xFFF; + *base++ = (*tmp_rawbuf >> 16) & 0xFFF; + + tmp_rawbuf++; + } + + if (flag & NODE_FLAG_FILTER) + *filter++ = *tmp_fltbuf++ & 0xFFF; + } + +#if TOUCH_NODE_PARSING_DEBUG + tsp_info("RAW - %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + printk("\n[ TSP ] "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%4d ", node->raw[(i * tsp->ch_num.rx) + j]); + } + printk("\n"); + tsp_info("BASE - %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + printk("\n[ TSP ] "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%4d ", node->base[(i * tsp->ch_num.rx) + j]); + } + printk("\n"); + tsp_info("FILTER - %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + printk("\n[ TSP ] "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%4d ", node->filter[(i * tsp->ch_num.rx) + j]); + } + printk("\n"); +#endif + + return 0; +} + +int print_touch_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node, char *buf) +{ + int i, j; + int count = 0; + int val = 0; + const int msg_len = 128; + char msg[msg_len]; + TSP_INFO *tsp = &data->tsp_info; + + if (tsp->dir.swap_xy) { + for (i = 0; i < tsp->ch_num.rx; i++) { + for (j = 0; j < tsp->ch_num.tx; j++) { + if (flag == NODE_FLAG_RAW) { + val = (int)node->raw[(j * tsp->ch_num.rx) + i]; + if (val < 0) + val = 0; + } else if (flag == NODE_FLAG_BASE) { + val = (int)node->base[(j * tsp->ch_num.rx) + i]; + if (val < 0) + val = 0; + } else if (flag == NODE_FLAG_FILTER) { + val = (int)node->filter[(j * tsp->ch_num.rx) + i]; + if (val < 0) + val = 0; + } else if (flag == NODE_FLAG_DIFF) { + val = (int)(node->raw[(j * tsp->ch_num.rx) + i] + - node->base[(j * tsp->ch_num.rx) + i]); + } else { + return 0; + } + + if (ist30xx_check_valid_ch(data, j, i) == TSP_CH_UNUSED) + count += snprintf(msg, msg_len, "%4d ", 0); + else + count += snprintf(msg, msg_len, "%4d ", val); + + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } else { + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + if (flag == NODE_FLAG_RAW) { + val = (int)node->raw[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + } else if (flag == NODE_FLAG_BASE) { + val = (int)node->base[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + } else if (flag == NODE_FLAG_FILTER) { + val = (int)node->filter[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + } else if (flag == NODE_FLAG_DIFF) { + val = (int)(node->raw[(i * tsp->ch_num.rx) + j] + - node->base[(i * tsp->ch_num.rx) + j]); + } else { + return 0; + } + + if (ist30xx_check_valid_ch(data, i, j) == TSP_CH_UNUSED) + count += snprintf(msg, msg_len, "%4d ", 0); + else + count += snprintf(msg, msg_len, "%4d ", val); + + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } + + return count; +} + +int parse_tsp_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node, s16 *buf16, int mode) +{ + int i, j; + s16 val = 0; + TSP_INFO *tsp = &data->tsp_info; + + if (unlikely((flag != NODE_FLAG_RAW) && (flag != NODE_FLAG_BASE) && + (flag != NODE_FLAG_FILTER) && (flag != NODE_FLAG_DIFF))) + return -EPERM; + + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + if (mode & TSP_RAW_SCREEN) { + if (ist30xx_check_valid_ch(data, i, j) != TSP_CH_SCREEN) + continue; + } else if (mode & TSP_RAW_KEY) { + if (ist30xx_check_valid_ch(data, i, j) != TSP_CH_KEY) + continue; + } + switch (flag) { + case NODE_FLAG_RAW: + val = (s16)node->raw[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + break; + case NODE_FLAG_BASE: + val = (s16)node->base[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + break; + case NODE_FLAG_FILTER: + val = (s16)node->filter[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + break; + case NODE_FLAG_DIFF: + val = (s16)(node->raw[(i * tsp->ch_num.rx) + j] + - node->base[(i * tsp->ch_num.rx) + j]); + break; + default: + val = 0; + break; + } + + if (ist30xx_check_valid_ch(data, i, j) == TSP_CH_UNUSED) + val = 0; + + *buf16++ = val; + } + } + + return 0; +} + +int ist30xx_read_touch_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node) +{ + int ret; + u32 addr; + u32 *tmp_rawbuf = ist30xx_frame_rawbuf; + u32 *tmp_fltbuf = ist30xx_frame_fltbuf; + + ist30xx_disable_irq(data); + + if (flag & NODE_FLAG_NO_CCP) { + ist30xx_reset(data, false); + + ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_CP_CORRECT_EN << 16) | (IST30XX_DISABLE & 0xFFFF))); + if (unlikely(ret)) + goto read_tsp_node_end; + + ist30xx_delay(1000); + } + + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret)) + goto read_tsp_node_end; + + addr = IST30XX_DA_ADDR(data->raw_addr); + if (flag & (NODE_FLAG_RAW | NODE_FLAG_BASE)) { + tsp_info("Reg addr: %x, size: %d\n", addr, node->len); + ret = ist30xx_burst_read(data->client, addr, tmp_rawbuf, node->len, + true); + if (unlikely(ret)) + goto reg_access_end; + } + + addr = IST30XX_DA_ADDR(data->filter_addr); + if (flag & NODE_FLAG_FILTER) { + tsp_info("Reg addr: %x, size: %d\n", addr, node->len); + ret = ist30xx_burst_read(data->client, addr, tmp_fltbuf, node->len, + true); + if (unlikely(ret)) + goto reg_access_end; + } + +reg_access_end: + if (flag & NODE_FLAG_NO_CCP) { + ist30xx_reset(data, false); + ist30xx_start(data); + } else { + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (ret) { + ist30xx_reset(data, false); + ist30xx_start(data); + } + } + +read_tsp_node_end: + ist30xx_enable_irq(data); + + return ret; +} + +int ist30xx_parse_cp_node(struct ist30xx_data *data, struct TSP_NODE_BUF *node) +{ + int i; + int len; + u16 *cp_lower = (u16 *)&node->cp_lower; + u16 *cp_upper = (u16 *)&node->cp_upper; + u32 *tmp_cpbuf = ist30xx_frame_cpbuf; + +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) + len = node->len / 2; + if (node->len % 2) + len += 1; +#else + len = node->len; +#endif + + for (i = 0; i < len; i++) { +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) + *cp_lower++ = *tmp_cpbuf & 0xFF; + *cp_upper++ = (*tmp_cpbuf >> 8) & 0xFF; + *cp_lower++ = (*tmp_cpbuf >> 16) & 0xFF; + *cp_upper++ = (*tmp_cpbuf >> 24) & 0xFF; +#else + *cp_lower++ = *tmp_cpbuf & 0x3FF; + *cp_upper++ = (*tmp_cpbuf >> 10) & 0x3FF; +#endif + tmp_cpbuf++; + } + + return 0; +} + +int parse_cp_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node, s16 *buf16, int mode) +{ + int i, j; + s16 val = 0; + TSP_INFO *tsp = &data->tsp_info; + + if (unlikely((flag != NODE_FLAG_CP_LOWER) && (flag != NODE_FLAG_CP_UPPER))) + return -EPERM; + + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + if (mode & TSP_RAW_SCREEN) { + if (ist30xx_check_valid_ch(data, i, j) != TSP_CH_SCREEN) + continue; + } else if (mode & TSP_RAW_KEY) { + if (ist30xx_check_valid_ch(data, i, j) != TSP_CH_KEY) + continue; + } + switch (flag) { + case NODE_FLAG_CP_LOWER: + val = (s16)node->cp_lower[(i * tsp->ch_num.rx) + j]; + break; + case NODE_FLAG_CP_UPPER: + val = (s16)node->cp_upper[(i * tsp->ch_num.rx) + j]; + break; + } + + if (val < 0) + val = 0; + + if (ist30xx_check_valid_ch(data, i, j) == TSP_CH_UNUSED) + val = 0; + + *buf16++ = val; + } + } + + return 0; +} + +int print_cp_node(struct ist30xx_data *data, u8 flag, struct TSP_NODE_BUF *node, + char *buf) +{ + int i, j; + int count = 0; + u32 val = 0; + const int msg_len = 128; + char msg[msg_len]; + TSP_INFO *tsp = &data->tsp_info; + + if (tsp->dir.swap_xy) { + if (flag & NODE_FLAG_CP_LOWER) { + for (i = 0; i < tsp->ch_num.rx; i++) { + for (j = 0; j < tsp->ch_num.tx; j++) { + val = node->cp_lower[(j * tsp->ch_num.rx) + i]; + if (val < 0) + val = 0; + + if (ist30xx_check_valid_ch(data, j, i) == TSP_CH_UNUSED) + count += snprintf(msg, msg_len, "%4d ", 0); + else + count += snprintf(msg, msg_len, "%4d ", val); + + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } else if (flag & NODE_FLAG_CP_UPPER) { + for (i = 0; i < tsp->ch_num.rx; i++) { + for (j = 0; j < tsp->ch_num.tx; j++) { + val = node->cp_upper[(j * tsp->ch_num.rx) + i]; + if (val < 0) + val = 0; + + if (ist30xx_check_valid_ch(data, j, i) == TSP_CH_UNUSED) + count += snprintf(msg, msg_len, "%4d ", 0); + else + count += snprintf(msg, msg_len, "%4d ", val); + + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } + } else { + if (flag & NODE_FLAG_CP_LOWER) { + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + val = node->cp_lower[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + + if (ist30xx_check_valid_ch(data, i, j) == TSP_CH_UNUSED) + count += snprintf(msg, msg_len, "%4d ", 0); + else + count += snprintf(msg, msg_len, "%4d ", val); + + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } else if (flag & NODE_FLAG_CP_UPPER) { + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + val = node->cp_upper[(i * tsp->ch_num.rx) + j]; + if (val < 0) + val = 0; + + if (ist30xx_check_valid_ch(data, i, j) == TSP_CH_UNUSED) + count += snprintf(msg, msg_len, "%4d ", 0); + else + count += snprintf(msg, msg_len, "%4d ", val); + + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } + } + + return count; +} + +#define IST30XX_CP_ADDRESS 0x30004000 +int ist30xx_read_cp_node(struct ist30xx_data *data, struct TSP_NODE_BUF *node) +{ + int ret = 0; + u32 addr; + u32 len; + u32 *tmp_cpbuf = ist30xx_frame_cpbuf; + + ist30xx_disable_irq(data); + + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret)) + goto read_cp_node_end; + + addr = IST30XX_DA_ADDR(IST30XX_CP_ADDRESS); +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) + len = node->len / 2; + if (node->len % 2) + len += 1; +#else + len = node->len; +#endif + ret = ist30xx_burst_read(data->client, addr, tmp_cpbuf, node->len, true); + if (unlikely(ret)) + goto reg_access_end; + +reg_access_end: + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (ret) { + ist30xx_reset(data, false); + ist30xx_start(data); + } + +read_cp_node_end: + ist30xx_enable_irq(data); + + return ret; + +} + +/* sysfs: /sys/class/touch/node/cp */ +ssize_t ist30xx_cp_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + tsp_info("Read CP\n"); + mutex_lock(&data->lock); + ret = ist30xx_read_cp_node(data, &tsp->node); + if (unlikely(ret)) { + mutex_unlock(&data->lock); + tsp_err("cmd 1frame cp update fail\n"); + return sprintf(buf, "FAIL\n"); + } + mutex_unlock(&data->lock); + + ist30xx_parse_cp_node(data, &tsp->node); + + return sprintf(buf, "OK\n"); +} + +/* sysfs: /sys/class/touch/node/cp_lower */ +ssize_t ist30xx_cp_lower_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xx cp lower(%d)\n", tsp->node.len); + + count += print_cp_node(data, NODE_FLAG_CP_LOWER, &tsp->node, buf); + + return count; +} + +/* sysfs: /sys/class/touch/node/cp_upper */ +ssize_t ist30xx_cp_upper_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xx cp upper(%d)\n", tsp->node.len); + + count += print_cp_node(data, NODE_FLAG_CP_UPPER, &tsp->node, buf); + + return count; +} + +/* sysfs: /sys/class/touch/node/rawbase */ +ssize_t ist30xx_frame_rawbase(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i; + int ret = 0; + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + u8 flag = NODE_FLAG_RAW | NODE_FLAG_BASE; + u32 *tmp_rawbuf = ist30xx_frame_rawbuf; + const int msg_len = 128; + char msg[msg_len]; + char header[128]; + char *buf8; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + TKEY_INFO *tkey = &data->tkey_info; + TSP_INFO *tsp = &data->tsp_info; + + old_fs = get_fs(); + set_fs(get_ds()); + + if (!strcmp(data->rec_file_name, "")) + snprintf(data->rec_file_name, 128, "/sdcard/%s", IST30XX_REC_FILENAME); + + fp = filp_open(data->rec_file_name, O_WRONLY, 0); + if (IS_ERR(fp)) + ret = PTR_ERR(fp); + + fp = filp_open(data->rec_file_name, O_CREAT|O_WRONLY|O_APPEND, 0); + if (IS_ERR(fp)) { + tsp_err("file %s open error:%d\n", data->rec_file_name, PTR_ERR(fp)); + goto err_file_open; + } + + if (ret) { + count = snprintf(header, 128, "%d %d %d %d %d %d %d %d %d %d %d %d %d " + "%d %d %d %d %d\n", 2, tsp->ch_num.rx, tsp->ch_num.tx, + tsp->ch_num.rx, tsp->ch_num.tx, tsp->screen.rx, tsp->screen.tx, + tkey->key_num, tkey->ch_num[0].rx, tkey->ch_num[0].tx, + tkey->ch_num[1].tx, tkey->ch_num[1].rx, tkey->ch_num[2].tx, + tkey->ch_num[2].rx, tkey->ch_num[3].tx, tkey->ch_num[3].rx, + tkey->ch_num[4].tx, tkey->ch_num[4].rx); + + fp->f_op->write(fp, header, count, &fp->f_pos); + fput(fp); + } + + mutex_lock(&data->lock); + ret = ist30xx_read_touch_node(data, flag, &tsp->node); + if (unlikely(ret)) { + mutex_unlock(&data->lock); + tsp_err("fail to read frame\n"); + goto err_read_node; + } + mutex_unlock(&data->lock); + + buf8 = kzalloc(IST30XX_MAX_NODE_NUM * 20, GFP_KERNEL); + count = 0; + for (i = 0; i < IST30XX_MAX_NODE_NUM; i++) { + count += snprintf(msg, msg_len, "%08x ", *tmp_rawbuf); + strncat(buf8, msg, msg_len); + tmp_rawbuf++; + } + + for (i = 0; i < IST30XX_MAX_NODE_NUM; i++) { + count += snprintf(msg, msg_len, "%08x ", 0); + strncat(buf8, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf8, msg, msg_len); + + fp->f_op->write(fp, buf8, count, &fp->f_pos); + fput(fp); + + kfree(buf8); + +err_read_node: + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + + return 0; +} + +/* sysfs: /sys/class/touch/node/refresh */ +ssize_t ist30xx_frame_refresh(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + u8 flag = NODE_FLAG_RAW | NODE_FLAG_BASE | NODE_FLAG_FILTER; + + tsp_info("refresh\n"); + mutex_lock(&data->lock); + ret = ist30xx_read_touch_node(data, flag, &tsp->node); + if (unlikely(ret)) { + mutex_unlock(&data->lock); + tsp_err("cmd 1frame raw update fail\n"); + return sprintf(buf, "FAIL\n"); + } + mutex_unlock(&data->lock); + + ist30xx_parse_touch_node(data, flag, &tsp->node); + + return sprintf(buf, "OK\n"); +} + + +/* sysfs: /sys/class/touch/node/read_nocp */ +ssize_t ist30xx_frame_nocp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + u8 flag = NODE_FLAG_RAW | NODE_FLAG_BASE | NODE_FLAG_FILTER | + NODE_FLAG_NO_CCP; + + mutex_lock(&data->lock); + ret = ist30xx_read_touch_node(data, flag, &tsp->node); + if (unlikely(ret)) { + mutex_unlock(&data->lock); + tsp_err("cmd 1frame raw update fail\n"); + return sprintf(buf, "FAIL\n"); + } + mutex_unlock(&data->lock); + + ist30xx_parse_touch_node(data, flag, &tsp->node); + + return sprintf(buf, "OK\n"); +} + + +/* sysfs: /sys/class/touch/node/base */ +ssize_t ist30xx_base_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xx baseline(%d)\n", tsp->node.len); + + count += print_touch_node(data, NODE_FLAG_BASE, &tsp->node, buf); + + return count; +} + + +/* sysfs: /sys/class/touch/node/raw */ +ssize_t ist30xx_raw_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xx raw(%d)\n", tsp->node.len); + + count += print_touch_node(data, NODE_FLAG_RAW, &tsp->node, buf); + + return count; +} + + +/* sysfs: /sys/class/touch/node/diff */ +ssize_t ist30xx_diff_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xx difference (%d)\n", tsp->node.len); + + count += print_touch_node(data, NODE_FLAG_DIFF, &tsp->node, buf); + + return count; +} + + +/* sysfs: /sys/class/touch/node/filter */ +ssize_t ist30xx_filter_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xx filter (%d)\n", tsp->node.len); + + count += print_touch_node(data, NODE_FLAG_FILTER, &tsp->node, buf); + + return count; +} + +/* sysfs: /sys/class/touch/sys/debug_mode */ +ssize_t ist30xx_debug_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret = 0; + int enable; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &enable); + + if (unlikely((enable != 0) && (enable != 1))) { + tsp_err("input data error(%d)\n", enable); + return size; + } + + data->debug_mode = enable; + + if (data->status.power) { + ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (data->debug_mode & 0xFFFF)); + } + + tsp_info("debug mode %s\n", enable ? "start" : "stop"); + + return size; +} + +/* sysfs: /sys/class/touch/sys/jig_mode */ +ssize_t ist30xx_jig_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int enable; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &enable); + + if (unlikely((enable != 0) && (enable != 1))) { + tsp_err("input data error(%d)\n", enable); + return size; + } + + data->jig_mode = enable; + tsp_info("set jig mode: %s\n", enable ? "start" : "stop"); + + mutex_lock(&data->lock); + ist30xx_reset(data, false); + ist30xx_start(data); + mutex_unlock(&data->lock); + + return size; +} + +extern int calib_ms_delay; +/* sysfs: /sys/class/touch/sys/clb_time */ +ssize_t ist30xx_calib_time_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ms_delay; + + sscanf(buf, "%d", &ms_delay); + + if (ms_delay > 10 && ms_delay < 1000) + calib_ms_delay = ms_delay; + + tsp_info("Calibration wait time %dsec\n", calib_ms_delay / 10); + + return size; +} + +/* sysfs: /sys/class/touch/sys/clb */ +ssize_t ist30xx_calib_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + + ist30xx_reset(data, false); + ist30xx_calibrate(data, 1); + + mutex_unlock(&data->lock); + ist30xx_start(data); + + return 0; +} + +/* sysfs: /sys/class/touch/sys/clb_result */ +ssize_t ist30xx_calib_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + int count = 0; + u32 value; + struct ist30xx_data *data = dev_get_drvdata(dev); + + ret = ist30xx_read_cmd(data, eHCOM_GET_CAL_RESULT, &value); + if (unlikely(ret)) { + mutex_lock(&data->lock); + ist30xx_reset(data, false); + ist30xx_start(data); + mutex_unlock(&data->lock); + tsp_warn("Error Read Calibration Result\n"); + count = sprintf(buf, "Error Read Calibration Result\n"); + goto calib_show_end; + } + + count = sprintf(buf, + "Calibration Status : %d, Max raw gap : %d - (raw: %08x)\n", + CALIB_TO_STATUS(value), CALIB_TO_GAP(value), value); + +calib_show_end: + + return count; +} + +/* sysfs: /sys/class/touch/sys/cal_ref */ +ssize_t ist30xx_cal_ref_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + + ist30xx_reset(data, false); + ist30xx_cal_reference(data); + + mutex_unlock(&data->lock); + ist30xx_start(data); + + data->cal_ref_count = 0; + + return 0; +} + +/* sysfs: /sys/class/touch/sys/power_on */ +ssize_t ist30xx_power_on_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("Power enable: %d\n", true); + + mutex_lock(&data->lock); + ist30xx_internal_resume(data); + ist30xx_enable_irq(data); + mutex_unlock(&data->lock); + + ist30xx_start(data); + + return 0; +} + +/* sysfs: /sys/class/touch/sys/power_off */ +ssize_t ist30xx_power_off_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("Power enable: %d\n", false); + + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + ist30xx_internal_suspend(data); + mutex_unlock(&data->lock); + + return 0; +} + +/* sysfs: /sys/class/touch/sys/errcnt */ +ssize_t ist30xx_errcnt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int err_cnt; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &err_cnt); + + if (unlikely(err_cnt < 0)) + return size; + + tsp_info("Request reset error count: %d\n", err_cnt); + + data->max_irq_err_cnt = err_cnt; + + return size; +} + +/* sysfs: /sys/class/touch/sys/scancnt */ +ssize_t ist30xx_scancnt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int retry; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &retry); + + if (unlikely(retry < 0)) + return size; + + tsp_info("Timer scan count retry: %d\n", retry); + + data->max_scan_retry = retry; + + return size; +} + +/* sysfs: /sys/class/touch/sys/timerms */ +ssize_t ist30xx_timerms_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ms; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &ms); + + if (unlikely((ms < 0) || (ms > 10000))) + return size; + + tsp_info("Timer period ms: %dms\n", ms); + + data->timer_period_ms = ms; + + return size; +} + +extern int ist30xx_log_level; +/* sysfs: /sys/class/touch/sys/printk */ +ssize_t ist30xx_printk_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int level; + + sscanf(buf, "%d", &level); + + if (unlikely((level < DEV_ERR) || (level > DEV_VERB))) + return size; + + tsp_info("prink log level: %d\n", level); + + ist30xx_log_level = level; + + return size; +} + +ssize_t ist30xx_printk_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "prink log level: %d\n", ist30xx_log_level); +} + +/* sysfs: /sys/class/touch/sys/printk5 */ +ssize_t ist30xx_printk5_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + tsp_info("prink log level:%d\n", DEV_DEBUG); + + ist30xx_log_level = DEV_DEBUG; + + return 0; +} + +/* sysfs: /sys/class/touch/sys/printk6 */ +ssize_t ist30xx_printk6_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + tsp_info("prink log level:%d\n", DEV_VERB); + + ist30xx_log_level = DEV_VERB; + + return 0; +} + +#ifdef IST30XX_GESTURE +/* sysfs: /sys/class/touch/sys/gesture */ +ssize_t ist30xx_gesture_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int gesture; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &gesture); + + tsp_info("gesture enable : %s\n", (gesture == 0) ? "disable" : "enable"); + + data->gesture = (gesture == 0) ? false : true; + if (data->gesture) + device_init_wakeup(&data->client->dev, 1); + else + device_init_wakeup(&data->client->dev, 0); + + return size; +} +#endif + +/* sysfs: /sys/class/touch/sys/report_rate */ +ssize_t ist30xx_report_rate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int rate; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &rate); + + if (unlikely(rate > 0xFFFF)) + return size; + + data->report_rate = rate; + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_TIME_ACTIVE << 16) | (data->report_rate & 0xFFFF))); + tsp_info(" active rate : %dus\n", data->report_rate); + + return size; +} + +/* sysfs: /sys/class/touch/sys/idle_rate */ +ssize_t ist30xx_idle_scan_rate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int rate; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d", &rate); + + if (unlikely(rate > 0xFFFF)) + return size; + + data->idle_rate = rate; + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + ((eHCOM_SET_TIME_IDLE << 16) | (data->idle_rate & 0xFFFF))); + tsp_info(" idle rate : %dus\n", data->idle_rate); + + return size; +} + +extern void ist30xx_set_ta_mode(bool charging); +/* sysfs: /sys/class/touch/sys/mode_ta */ +ssize_t ist30xx_ta_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int mode; + + sscanf(buf, "%d", &mode); + + if (unlikely((mode != 0) && (mode != 1))) + return size; + + ist30xx_set_ta_mode(mode); + + return size; +} + +extern void ist30xx_set_call_mode(int mode); +/* sysfs: /sys/class/touch/sys/mode_call */ +ssize_t ist30xx_call_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int mode; + + sscanf(buf, "%d", &mode); + + if (unlikely((mode != 0) && (mode != 1))) + return size; + + ist30xx_set_call_mode(mode); + + return size; +} + +extern void ist30xx_set_cover_mode(int mode); +/* sysfs: /sys/class/touch/sys/mode_cover */ +ssize_t ist30xx_cover_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int mode; + + sscanf(buf, "%d", &mode); + + if (unlikely((mode != 0) && (mode != 1))) + return size; + + ist30xx_set_cover_mode(mode); + + return size; +} + +/* sysfs: /sys/class/touch/sys/ic_inform */ +ssize_t ist30xx_read_ic_inform(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + ist30xx_print_info(data); + + return 0; +} + +#define TUNES_CMD_WRITE (1) +#define TUNES_CMD_READ (2) +#define TUNES_CMD_REG_ENTER (3) +#define TUNES_CMD_REG_EXIT (4) +#define TUNES_CMD_UPDATE_PARAM (5) +#define TUNES_CMD_UPDATE_FW (6) + +#define DIRECT_ADDR(n) (IST30XX_DA_ADDR(n)) +#define DIRECT_CMD_WRITE ('w') +#define DIRECT_CMD_READ ('r') +#define DIRECT_BUF_COUNT (4) + +#pragma pack(1) +typedef struct { + u8 cmd; + u32 addr; + u16 len; +} TUNES_INFO; +#pragma pack() +#pragma pack(1) +typedef struct { + char cmd; + u32 addr; + u32 val; + u32 size; +} DIRECT_INFO; +#pragma pack() + +static TUNES_INFO ist30xx_tunes; +static DIRECT_INFO ist30xx_direct; +static bool tunes_cmd_done; +static bool ist30xx_reg_mode; + +/* sysfs: /sys/class/touch/sys/direct */ +ssize_t ist30xx_direct_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = -EPERM; + struct ist30xx_data *data = dev_get_drvdata(dev); + DIRECT_INFO *direct = (DIRECT_INFO *)&ist30xx_direct; + + sscanf(buf, "%c %x %x %d", &direct->cmd, &direct->addr, &direct->val, + &direct->size); + + if (direct->size == 0) + direct->size = DIRECT_BUF_COUNT; + + tsp_debug("Direct cmd: %c, addr: %x, val: %x\n", + direct->cmd, direct->addr, direct->val); + + if (unlikely((direct->cmd != DIRECT_CMD_WRITE) && + (direct->cmd != DIRECT_CMD_READ))) { + tsp_warn("Direct cmd is not correct!\n"); + return size; + } + + if (ist30xx_intr_wait(data, 30) < 0) + return size; + + data->status.event_mode = false; + if (direct->cmd == DIRECT_CMD_WRITE) { + ist30xx_cmd_hold(data, IST30XX_ENABLE); + ist30xx_write_cmd(data, DIRECT_ADDR(direct->addr), direct->val); + ist30xx_read_reg(data->client, DIRECT_ADDR(direct->addr), &direct->val); + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (ret) + tsp_debug("Direct write fail\n"); + else + tsp_debug("Direct write addr: %x, val: %x\n", direct->addr, + direct->val); + + } + data->status.event_mode = true; + + return size; +} + +ssize_t ist30xx_direct_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i, count = 0; + int ret = 0; + int len; + u32 addr; + u32 *buf32; + const int msg_len = 256; + char msg[msg_len]; + struct ist30xx_data *data = dev_get_drvdata(dev); + DIRECT_INFO *direct = (DIRECT_INFO *)&ist30xx_direct; + int max_len = direct->size; + + if (unlikely(direct->cmd != DIRECT_CMD_READ)) + return sprintf(buf, "ex) echo r addr len size(display) > direct\n"); + + len = direct->val; + addr = DIRECT_ADDR(direct->addr); + + if (ist30xx_intr_wait(data, 30) < 0) + return 0; + + if (!data->status.power) + return 0; + + data->status.event_mode = false; + ist30xx_cmd_hold(data, IST30XX_ENABLE); + + buf32 = kzalloc(max_len * sizeof(u32), GFP_KERNEL); + while (len > 0) { + if (len < max_len) + max_len = len; + + memset(buf32, 0, sizeof(*buf32)); + ret = ist30xx_burst_read(data->client, addr, buf32, max_len, true); + if (unlikely(ret)) { + count = sprintf(buf, "I2C Burst read fail\n"); + break; + } + addr += (max_len * IST30XX_DATA_LEN); + + for (i = 0; i < max_len; i++) { + count += snprintf(msg, msg_len, "0x%08x ", buf32[i]); + strncat(buf, msg, msg_len); + } + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + + len -= max_len; + } + kfree(buf32); + + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (ret) + tsp_err("Hold disable fail\n"); + data->status.event_mode = true; + + return count; +} + +/* sysfs: /sys/class/touch/tunes/node_info */ +ssize_t tunes_node_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + TKEY_INFO *tkey = &data->tkey_info; + + size = sprintf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d " + "%d %d %d %d %d %d %d %d %d", + data->chip_id, tsp->dir.swap_xy, tsp->ch_num.tx, + tsp->ch_num.rx, tsp->screen.tx, tsp->screen.rx, + tsp->gtx.num, tsp->gtx.ch_num[0], tsp->gtx.ch_num[1], + tsp->gtx.ch_num[2], tsp->gtx.ch_num[3], tsp->baseline, + tkey->enable, tkey->baseline, tkey->key_num, tkey->ch_num[0].tx, + tkey->ch_num[0].rx, tkey->ch_num[1].tx, tkey->ch_num[1].rx, + tkey->ch_num[2].tx, tkey->ch_num[2].rx, tkey->ch_num[3].tx, + tkey->ch_num[3].rx, 255, 255, data->raw_addr, data->filter_addr); + + return size; +} + +/* sysfs: /sys/class/touch/tunes/regcmd */ +ssize_t tunes_regcmd_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = -1; + u32 *buf32; + struct ist30xx_data *data = dev_get_drvdata(dev); + + memcpy(&ist30xx_tunes, buf, sizeof(ist30xx_tunes)); + buf += sizeof(ist30xx_tunes); + buf32 = (u32 *)buf; + + tunes_cmd_done = false; + + switch (ist30xx_tunes.cmd) { + case TUNES_CMD_WRITE: + break; + case TUNES_CMD_READ: + break; + case TUNES_CMD_REG_ENTER: + ist30xx_disable_irq(data); + /* enter reg access mode */ + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret)) + goto regcmd_fail; + + ist30xx_reg_mode = true; + break; + case TUNES_CMD_REG_EXIT: + /* exit reg access mode */ + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (unlikely(ret)) { + ist30xx_reset(data, false); + ist30xx_start(data); + goto regcmd_fail; + } + + ist30xx_reg_mode = false; + ist30xx_enable_irq(data); + break; + default: + ist30xx_enable_irq(data); + return size; + } + tunes_cmd_done = true; + + return size; + +regcmd_fail: + tsp_err("Tunes regcmd i2c_fail, ret=%d\n", ret); + return size; +} + +ssize_t tunes_regcmd_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int size; + + size = sprintf(buf, "cmd: 0x%02x, addr: 0x%08x, len: 0x%04x\n", + ist30xx_tunes.cmd, ist30xx_tunes.addr, ist30xx_tunes.len); + + return size; +} + +#define MAX_WRITE_LEN (1) +/* sysfs: /sys/class/touch/tunes/reg */ +ssize_t tunes_reg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + u32 *buf32 = (u32 *)buf; + int waddr, wcnt = 0, len = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (unlikely(ist30xx_tunes.cmd != TUNES_CMD_WRITE)) { + tsp_err("error, IST30XX_REG_CMD is not correct!\n"); + return size; + } + + if (unlikely(!ist30xx_reg_mode)) { + tsp_err("error, IST30XX_REG_CMD is not ready!\n"); + return size; + } + + if (unlikely(!tunes_cmd_done)) { + tsp_err("error, IST30XX_REG_CMD is not ready!\n"); + return size; + } + + waddr = ist30xx_tunes.addr; + if (ist30xx_tunes.len >= MAX_WRITE_LEN) + len = MAX_WRITE_LEN; + else + len = ist30xx_tunes.len; + + while (wcnt < ist30xx_tunes.len) { + ret = ist30xx_write_buf(data->client, waddr, buf32, len); + if (unlikely(ret)) { + tsp_err("Tunes regstore i2c_fail, ret=%d\n", ret); + return size; + } + + wcnt += len; + + if ((ist30xx_tunes.len - wcnt) < MAX_WRITE_LEN) + len = ist30xx_tunes.len - wcnt; + + buf32 += MAX_WRITE_LEN; + waddr += MAX_WRITE_LEN * IST30XX_DATA_LEN; + } + + tunes_cmd_done = false; + + return size; +} + +ssize_t tunes_reg_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + int size = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (unlikely(ist30xx_tunes.cmd != TUNES_CMD_READ)) { + tsp_err("error, IST30XX_REG_CMD is not correct!\n"); + return 0; + } + + if (unlikely(!tunes_cmd_done)) { + tsp_err("error, IST30XX_REG_CMD is not ready!\n"); + return 0; + } + + ret = ist30xx_burst_read(data->client, ist30xx_tunes.addr, (u32 *)buf, + ist30xx_tunes.len, false); + if (unlikely(ret)) { + tsp_err("Tunes regshow i2c_fail, ret=%d\n", ret); + return size; + } + + size = ist30xx_tunes.len * IST30XX_DATA_LEN; + + tunes_cmd_done = false; + + return size; +} + +/* sysfs: /sys/class/touch/tunes/adb */ +ssize_t tunes_adb_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + char *tmp, *ptr; + char token[9]; + u32 cmd, addr, len, val; + int write_len; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%x %x %x", &cmd, &addr, &len); + + switch (cmd) { + case TUNES_CMD_WRITE: /* write cmd */ + write_len = 0; + ptr = (char *)(buf + 15); + + while (write_len < len) { + memcpy(token, ptr, 8); + token[8] = 0; + val = simple_strtoul(token, &tmp, 16); + ret = ist30xx_write_buf(data->client, addr, &val, 1); + if (unlikely(ret)) { + tsp_err("Tunes regstore i2c_fail, ret=%d\n", ret); + return size; + } + + ptr += 8; + write_len++; + addr += 4; + } + break; + + case TUNES_CMD_READ: /* read cmd */ + ist30xx_tunes.cmd = cmd; + ist30xx_tunes.addr = addr; + ist30xx_tunes.len = len; + break; + + case TUNES_CMD_REG_ENTER: /* enter */ + ist30xx_disable_irq(data); + + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret < 0)) + goto cmd_fail; + + ist30xx_reg_mode = true; + break; + + case TUNES_CMD_REG_EXIT: /* exit */ + if (ist30xx_reg_mode == true) { + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (unlikely(ret < 0)) { + ist30xx_reset(data, false); + ist30xx_start(data); + goto cmd_fail; + } + + ist30xx_reg_mode = false; + ist30xx_enable_irq(data); + } + break; + + default: + break; + } + + return size; + +cmd_fail: + tsp_err("Tunes adb i2c_fail\n"); + return size; +} + +ssize_t tunes_adb_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + int i, len, size = 0; + char reg_val[10]; + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("tunes_adb_show,%08x,%d\n", ist30xx_tunes.addr, ist30xx_tunes.len); + + ret = ist30xx_burst_read(data->client, ist30xx_tunes.addr, + ist30xx_frame_buf, ist30xx_tunes.len, false); + if (unlikely(ret)) { + tsp_err("Tunes adbshow i2c_fail, ret=%d\n", ret); + return size; + } + + size = 0; + buf[0] = 0; + len = sprintf(reg_val, "%08x", ist30xx_tunes.addr); + strcat(buf, reg_val); + size += len; + for (i = 0; i < ist30xx_tunes.len; i++) { + len = sprintf(reg_val, "%08x", ist30xx_frame_buf[i]); + strcat(buf, reg_val); + size += len; + } + + return size; +} + +/* sysfs: /sys/class/touch/sys/rec_mode */ +ssize_t ist30xx_rec_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int count; + int mode; + int start_ch_rx; + int stop_ch_rx; + int start_ch_tx; + int stop_ch_tx; + int delay; + char header[128]; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + TKEY_INFO *tkey = &data->tkey_info; + + start_ch_rx = 0; + stop_ch_rx = tsp->ch_num.rx - 1; + start_ch_tx = 0; + stop_ch_tx = tsp->ch_num.tx - 1; + delay = 0; + data->rec_file_name = "/data/ist30xxc.res"; + + sscanf(buf, "%d %d %d %d %d %d", &mode, &delay, &start_ch_rx, &stop_ch_rx, + &start_ch_tx, &stop_ch_tx); + + if ((start_ch_rx > stop_ch_rx) || (start_ch_tx > stop_ch_tx) || + (stop_ch_rx >= tsp->ch_num.rx) || (stop_ch_tx >= tsp->ch_num.tx)) { + tsp_err("input data error(%d, %d, %d, %d)\n", start_ch_rx, stop_ch_rx, + start_ch_tx, stop_ch_tx); + return size; + } + + old_fs = get_fs(); + set_fs(get_ds()); + + if (mode) { + if (!strcmp(data->rec_file_name, "")) + snprintf(data->rec_file_name, 128, "/data/%s", + IST30XX_REC_FILENAME); + + fp = filp_open(data->rec_file_name, O_CREAT|O_WRONLY|O_TRUNC, 0); + if (IS_ERR(fp)) { + tsp_err("file %s open error:%d\n", data->rec_file_name, + PTR_ERR(fp)); + goto err_file_open; + } + + count = snprintf(header, 128, "%d %d %d %d %d %d %d %d %d %d %d %d %d " + "%d %d %d %d %d\n", 2, tsp->ch_num.rx, tsp->ch_num.tx, + tsp->ch_num.rx, tsp->ch_num.tx, tsp->screen.rx, tsp->screen.tx, + tkey->key_num, tkey->ch_num[0].rx, tkey->ch_num[0].tx, + tkey->ch_num[1].tx, tkey->ch_num[1].rx, tkey->ch_num[2].tx, + tkey->ch_num[2].rx, tkey->ch_num[3].tx, tkey->ch_num[3].rx, + 255, 255); + + fp->f_op->write(fp, header, count, &fp->f_pos); + fput(fp); + + filp_close(fp, NULL); + } + + data->rec_mode = mode; + tsp_info("rec mode: %s\n", mode ? "start" : "stop"); + if (mode) { + data->rec_start_ch.rx = start_ch_rx; + data->rec_stop_ch.rx = stop_ch_rx; + data->rec_start_ch.tx = start_ch_tx; + data->rec_stop_ch.tx = stop_ch_tx; + tsp_info("rec channel: %d, %d, %d, %d\n", data->rec_start_ch.rx, + data->rec_stop_ch.rx, data->rec_start_ch.tx, + data->rec_stop_ch.tx); + data->rec_delay = delay; + tsp_info("rec delay: %dms\n", data->rec_delay); + } + + if (data->status.power) { + if (data->debug_mode || data->jig_mode || data->rec_mode || + data->debugging_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_DISABLE & 0xFFFF)); + } else { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_ENABLE & 0xFFFF)); + } + + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (data->rec_mode & 0xFFFF)); + + if (data->rec_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (IST30XX_START_SCAN & 0xFFFF)); + } + } + +err_file_open: + set_fs(old_fs); + + return size; +} + +ssize_t ist30xx_rec_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count; + int start_ch_rx; + int stop_ch_rx; + int start_ch_tx; + int stop_ch_tx; + int delay; + char header[128]; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + struct ist30xx_data *data = dev_get_drvdata(dev); + TSP_INFO *tsp = &data->tsp_info; + TKEY_INFO *tkey = &data->tkey_info; + + start_ch_rx = 0; + stop_ch_rx = tsp->ch_num.rx - 1; + start_ch_tx = 0; + stop_ch_tx = tsp->ch_num.tx - 1; + delay = 20; + + if (data->rec_mode) { + data->rec_mode = 0; + } else { + old_fs = get_fs(); + set_fs(get_ds()); + + if (!strcmp(data->rec_file_name, "")) + snprintf(data->rec_file_name, 128, "/data/%s", + IST30XX_REC_FILENAME); + + fp = filp_open(data->rec_file_name, O_CREAT|O_WRONLY|O_TRUNC, 0); + if (IS_ERR(fp)) { + tsp_err("file %s open error:%d\n", data->rec_file_name, + PTR_ERR(fp)); + goto err_file_open; + } + + count = snprintf(header, 128, "%d %d %d %d %d %d %d %d %d %d %d %d %d " + "%d %d %d %d %d\n", 2, tsp->ch_num.rx, tsp->ch_num.tx, + tsp->ch_num.rx, tsp->ch_num.tx, tsp->screen.rx, tsp->screen.tx, + tkey->key_num, tkey->ch_num[0].rx, tkey->ch_num[0].tx, + tkey->ch_num[1].tx, tkey->ch_num[1].rx, tkey->ch_num[2].tx, + tkey->ch_num[2].rx, tkey->ch_num[3].tx, tkey->ch_num[3].rx, + 255, 255); + + fp->f_op->write(fp, header, count, &fp->f_pos); + fput(fp); + + filp_close(fp, NULL); + + data->rec_mode = 2; + } + + tsp_info("rec mode: %s\n", data->rec_mode ? "start" : "stop"); + if (data->rec_mode) { + data->rec_start_ch.rx = start_ch_rx; + data->rec_stop_ch.rx = stop_ch_rx; + data->rec_start_ch.tx = start_ch_tx; + data->rec_stop_ch.tx = stop_ch_tx; + tsp_info("rec channel: %d, %d, %d, %d\n", data->rec_start_ch.rx, + data->rec_stop_ch.rx, data->rec_start_ch.tx, + data->rec_stop_ch.tx); + data->rec_delay = delay; + tsp_info("rec delay: %dms\n", data->rec_delay); + } + + if (data->status.power) { + if (data->debug_mode || data->jig_mode || data->rec_mode || + data->debugging_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_DISABLE & 0xFFFF)); + } else { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_ENABLE & 0xFFFF)); + } + + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (data->rec_mode & 0xFFFF)); + + if (data->rec_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_REC_MODE << 16) | (IST30XX_START_SCAN & 0xFFFF)); + } + } + +err_file_open: + set_fs(old_fs); + + return 0; +} + +#ifdef IST30XX_ALGORITHM_MODE +/* sysfs: /sys/class/touch/tunes/algorithm */ +ssize_t ist30xx_algr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%x %d", &data->algr_addr, &data->algr_size); + tsp_info("algorithm addr: 0x%x, count: %d\n", data->algr_addr, + data->algr_size); + + return size; +} + +ssize_t ist30xx_algr_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + u32 algr_addr; + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + ret = ist30xx_read_cmd(data, eHCOM_GET_ALGO_BASE, &algr_addr); + if (unlikely(ret)) { + mutex_lock(&data->lock); + ist30xx_reset(data, false); + ist30xx_start(data); + mutex_unlock(&data->lock); + tsp_warn("algorithm mem addr read fail!\n"); + return 0; + } + + tsp_info("algr_addr(0x%x): 0x%x\n", eHCOM_GET_ALGO_BASE, algr_addr); + count = sprintf(buf, "algorithm addr : 0x%x\n", algr_addr); + + return count; +} +#endif + +/* sysfs: /sys/class/touch/tunes/intr_debug */ +ssize_t intr_debug_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%x %d", &data->intr_debug1_addr, &data->intr_debug1_size); + tsp_info("intr debug1 addr: 0x%x, count: %d\n", data->intr_debug1_addr, + data->intr_debug1_size); + + return size; +} + +ssize_t intr_debug_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("intr debug1 addr: 0x%x, count: %d\n", data->intr_debug1_addr, + data->intr_debug1_size); + + count = sprintf(buf, "intr debug1 addr: 0x%x, count: %d\n", + data->intr_debug1_addr, data->intr_debug1_size); + + return count; +} + +/* sysfs: /sys/class/touch/tunes/intr_debug2 */ +ssize_t intr_debug2_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%x %d", &data->intr_debug2_addr, &data->intr_debug2_size); + tsp_info("intr debug2 addr: 0x%x, count: %d\n", data->intr_debug2_addr, + data->intr_debug2_size); + + return size; +} + +ssize_t intr_debug2_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("intr debug2 addr: 0x%x, count: %d\n", data->intr_debug2_addr, + data->intr_debug2_size); + + count = sprintf(buf, "intr debug2 addr: 0x%x, count: %d\n", + data->intr_debug2_addr, data->intr_debug2_size); + + return count; +} + +/* sysfs: /sys/class/touch/tunes/intr_debug3 */ +ssize_t intr_debug3_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%x %d", &data->intr_debug3_addr, &data->intr_debug3_size); + tsp_info("intr debug3 addr: 0x%x, count: %d\n", data->intr_debug3_addr, + data->intr_debug3_size); + + return size; +} + +ssize_t intr_debug3_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("intr debug3 addr: 0x%x, count: %d\n", data->intr_debug3_addr, + data->intr_debug2_size); + + count = sprintf(buf, "intr debug3 addr: 0x%x, count: %d\n", + data->intr_debug3_addr, data->intr_debug3_size); + + return count; +} + +#define IST30XX_DEBUGGING_MAGIC 0xDEBC0000 +#define MAX_FRAME_COUNT 1024 +IST30XX_RING_BUF DebugBuf; +IST30XX_RING_BUF *pDebugBuf; +bool debugging_initialize = false; +void ist30xx_debugging_init(struct ist30xx_data *data) +{ + if (!debugging_initialize) + pDebugBuf = &DebugBuf; + + pDebugBuf->RingBufCtr = 0; + pDebugBuf->RingBufInIdx = 0; + pDebugBuf->RingBufOutIdx = 0; + + data->debugging_scancnt = 0; + + debugging_initialize = true; +} + +u32 ist30xx_get_debugging_cnt(void) +{ + return pDebugBuf->RingBufCtr; +} + +int ist30xx_get_frame(struct ist30xx_data *data, u32 *frame, u32 cnt) +{ + int i; + u8 *buf = (u8 *)frame; + + cnt *= IST30XX_DATA_LEN; + + if (pDebugBuf->RingBufCtr < cnt) + return IST30XX_RINGBUF_NOT_ENOUGH; + + for (i = 0; i < cnt; i++) { + if (pDebugBuf->RingBufOutIdx == IST30XX_MAX_RINGBUF_SIZE) + pDebugBuf->RingBufOutIdx = 0; + + *buf++ = (u8)pDebugBuf->LogBuf[pDebugBuf->RingBufOutIdx++]; + pDebugBuf->RingBufCtr--; + } + + return IST30XX_RINGBUF_NO_ERR; +} + +int ist30xx_put_frame(struct ist30xx_data *data, u32 ms, u32 *touch, u32 *frame, + int frame_cnt) +{ + int i; + int size = 0; + u32 *buf32; + u8 *buf; + + buf32 = kzalloc((frame_cnt + 3) * sizeof(u32), GFP_KERNEL); + + /* Header & Time */ + ms &= 0x0000FFFF; + ms |= IST30XX_DEBUGGING_MAGIC; + buf32[size++] = ms; + + buf32[size++] = *touch; + buf32[size++] = *(touch + 1); + + for (i = 0; i < frame_cnt; i++) { + buf32[i + 3] = frame[i]; + size++; + } + + buf = (u8 *)buf32; + size *= IST30XX_DATA_LEN; + + pDebugBuf->RingBufCtr += size; + if (pDebugBuf->RingBufCtr > IST30XX_MAX_RINGBUF_SIZE) { + pDebugBuf->RingBufOutIdx += + (pDebugBuf->RingBufCtr - IST30XX_MAX_RINGBUF_SIZE); + if (pDebugBuf->RingBufOutIdx >= IST30XX_MAX_RINGBUF_SIZE) + pDebugBuf->RingBufOutIdx -= IST30XX_MAX_RINGBUF_SIZE; + + pDebugBuf->RingBufCtr = IST30XX_MAX_RINGBUF_SIZE; + } + + for (i = 0; i < size; i++) { + if (pDebugBuf->RingBufInIdx == IST30XX_MAX_RINGBUF_SIZE) + pDebugBuf->RingBufInIdx = 0; + pDebugBuf->LogBuf[pDebugBuf->RingBufInIdx++] = *buf++; + } + + kfree(buf32); + + return IST30XX_RINGBUF_NO_ERR; +} + +/* sysfs: /sys/class/touch/tunes/debugging_mode */ +ssize_t debugging_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int enable; + int noise = 1; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d %d", &enable, &noise); + + if (enable == data->debugging_mode) + return size; + + if (data->debugging_addr == 0x0) { + tsp_err("check feature in firmware\n"); + return size; + } + + if (unlikely((enable != 0) && (enable != 1))) { + tsp_err("input data error(%d)\n", enable); + return size; + } + + ist30xx_debugging_init(data); + data->debugging_noise = noise; + data->debugging_mode = enable; + tsp_info("set debugging mode: %s\n", enable ? "start" : "stop"); + + if (data->status.power) { + if (data->debug_mode || data->jig_mode || data->rec_mode || + data->debugging_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_DISABLE & 0xFFFF)); + } else { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_ENABLE & 0xFFFF)); + } + + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_DBG_MODE << 16) | (data->debugging_mode & 0xFFFF)); + } + + return size; +} + +ssize_t debugging_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + if (data->debugging_addr == 0x0) { + tsp_err("check feature in firmware\n"); + return sprintf(buf, "%s", "FAIL"); + } + + ist30xx_debugging_init(data); + data->debugging_noise = 1; + data->debugging_mode = (data->debugging_mode ? 0 : 1); + tsp_info("set debugging mode: %s\n", + data->debugging_mode ? "start" : "stop"); + + if (data->status.power) { + if (data->debug_mode || data->jig_mode || data->rec_mode || + data->debugging_mode) { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_DISABLE & 0xFFFF)); + } else { + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SLEEP_MODE_EN << 16) | (IST30XX_ENABLE & 0xFFFF)); + } + + ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_SET_DBG_MODE << 16) | (data->debugging_mode & 0xFFFF)); + } + + return sprintf(buf, "%s", data->debugging_mode ? "ENABLE" : "DISABLE"); +} + +/* sysfs: /sys/class/touch/tunes/debugging_status */ +ssize_t debugging_status_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%s", data->debugging_mode ? "ENABLE" : "DISABLE"); +} + +/* sysfs: /sys/class/touch/tunes/debugging_cnt */ +ssize_t debugging_cnt_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + u32 cnt = (u32)ist30xx_get_debugging_cnt(); + + tsp_verb("debugging cnt: %d\n", cnt); + + return sprintf(buf, "%08x", cnt); +} + +/* sysfs: /sys/class/touch/tunes/debugging_frame */ +ssize_t debugging_frame_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i; + int count = 0; + u32 *frame_data = NULL; + char msg[10]; + struct ist30xx_data *data = dev_get_drvdata(dev); + u32 frame_cnt = MAX_FRAME_COUNT; + + frame_data = kzalloc(MAX_FRAME_COUNT, GFP_KERNEL); + + buf[0] = '\0'; + + if (frame_cnt > ist30xx_get_debugging_cnt()) + frame_cnt = ist30xx_get_debugging_cnt(); + + tsp_verb("num: %d of %d\n", frame_cnt, ist30xx_get_debugging_cnt()); + + frame_cnt /= IST30XX_DATA_LEN; + + if (ist30xx_get_frame(data, frame_data, frame_cnt)) + return count; + + for (i = 0; i < frame_cnt; i++) { + tsp_verb("%08X\n", frame_data[i]); + + count += sprintf(msg, "%08x", frame_data[i]); + strcat(buf, msg); + } + + return count; +} + +/* sysfs: /sys/class/touch/tunes/tbase */ +ssize_t target_baseline_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + return sprintf(buf, "%08x", data->tsp_info.baseline); +} + +/* sysfs : node */ +static DEVICE_ATTR(cp, S_IRWXUGO, ist30xx_cp_show, NULL); +static DEVICE_ATTR(cp_lower, S_IRWXUGO, ist30xx_cp_lower_show, NULL); +static DEVICE_ATTR(cp_upper, S_IRWXUGO, ist30xx_cp_upper_show, NULL); +static DEVICE_ATTR(rawbase, S_IRWXUGO, ist30xx_frame_rawbase, NULL); +static DEVICE_ATTR(refresh, S_IRWXUGO, ist30xx_frame_refresh, NULL); +static DEVICE_ATTR(nocp, S_IRWXUGO, ist30xx_frame_nocp, NULL); +static DEVICE_ATTR(filter, S_IRWXUGO, ist30xx_filter_show, NULL); +static DEVICE_ATTR(raw, S_IRWXUGO, ist30xx_raw_show, NULL); +static DEVICE_ATTR(base, S_IRWXUGO, ist30xx_base_show, NULL); +static DEVICE_ATTR(diff, S_IRWXUGO, ist30xx_diff_show, NULL); + +/* sysfs : sys */ +static DEVICE_ATTR(debug_mode, S_IRWXUGO, NULL, ist30xx_debug_mode_store); +static DEVICE_ATTR(rec_mode, S_IRWXUGO, ist30xx_rec_mode_show, + ist30xx_rec_mode_store); +static DEVICE_ATTR(jig_mode, S_IRWXUGO, NULL, ist30xx_jig_mode_store); +static DEVICE_ATTR(printk, S_IRWXUGO, ist30xx_printk_show, + ist30xx_printk_store); +static DEVICE_ATTR(printk5, S_IRWXUGO, ist30xx_printk5_show, NULL); +static DEVICE_ATTR(printk6, S_IRWXUGO, ist30xx_printk6_show, NULL); +#ifdef IST30XX_GESTURE +static DEVICE_ATTR(gesture, S_IRWXUGO, NULL, ist30xx_gesture_store); +#endif +static DEVICE_ATTR(direct, S_IRWXUGO, ist30xx_direct_show, + ist30xx_direct_store); +static DEVICE_ATTR(clb_time, S_IRWXUGO, NULL, ist30xx_calib_time_store); +static DEVICE_ATTR(clb, S_IRWXUGO, ist30xx_calib_show, NULL); +static DEVICE_ATTR(clb_result, S_IRWXUGO, ist30xx_calib_result_show, NULL); +static DEVICE_ATTR(cal_ref, S_IRWXUGO, ist30xx_cal_ref_show, NULL); +static DEVICE_ATTR(tsp_power_on, S_IRWXUGO, ist30xx_power_on_show, NULL); +static DEVICE_ATTR(tsp_power_off, S_IRWXUGO, ist30xx_power_off_show, NULL); +static DEVICE_ATTR(errcnt, S_IRWXUGO, NULL, ist30xx_errcnt_store); +static DEVICE_ATTR(scancnt, S_IRWXUGO, NULL, ist30xx_scancnt_store); +static DEVICE_ATTR(timerms, S_IRWXUGO, NULL, ist30xx_timerms_store); +static DEVICE_ATTR(report_rate, S_IRWXUGO, NULL, ist30xx_report_rate_store); +static DEVICE_ATTR(idle_rate, S_IRWXUGO, NULL, ist30xx_idle_scan_rate_store); +static DEVICE_ATTR(mode_ta, S_IRWXUGO, NULL, ist30xx_ta_mode_store); +static DEVICE_ATTR(mode_call, S_IRWXUGO, NULL, ist30xx_call_mode_store); +static DEVICE_ATTR(mode_cover, S_IRWXUGO, NULL, ist30xx_cover_mode_store); +static DEVICE_ATTR(ic_inform, S_IRUGO, ist30xx_read_ic_inform, NULL); +#ifdef IST30XX_TAU +static DEVICE_ATTR(tau, S_IRUGO, ist30xx_tau_show, NULL); +#endif + +/* sysfs : tunes */ +static DEVICE_ATTR(node_info, S_IRWXUGO, tunes_node_info_show, NULL); +static DEVICE_ATTR(regcmd, S_IRWXUGO, tunes_regcmd_show, tunes_regcmd_store); +static DEVICE_ATTR(reg, S_IRWXUGO, tunes_reg_show, tunes_reg_store); +static DEVICE_ATTR(adb, S_IRWXUGO, tunes_adb_show, tunes_adb_store); +#ifdef IST30XX_ALGORITHM_MODE +static DEVICE_ATTR(algorithm, S_IRWXUGO, ist30xx_algr_show, ist30xx_algr_store); +#endif +static DEVICE_ATTR(intr_debug, S_IRWXUGO, intr_debug_show, intr_debug_store); +static DEVICE_ATTR(intr_debug2, S_IRWXUGO, intr_debug2_show, intr_debug2_store); +static DEVICE_ATTR(intr_debug3, S_IRWXUGO, intr_debug3_show, intr_debug3_store); +static DEVICE_ATTR(debugging_mode, S_IRWXUGO, debugging_mode_show, + debugging_mode_store); +static DEVICE_ATTR(debugging_status, S_IRWXUGO, debugging_status_show, NULL); +static DEVICE_ATTR(debugging_cnt, S_IRWXUGO, debugging_cnt_show, NULL); +static DEVICE_ATTR(debugging_frame, S_IRWXUGO, debugging_frame_show, NULL); +static DEVICE_ATTR(tbase, S_IRWXUGO, target_baseline_show, NULL); + +static struct attribute *node_attributes[] = { + &dev_attr_cp.attr, + &dev_attr_cp_lower.attr, + &dev_attr_cp_upper.attr, + &dev_attr_rawbase.attr, + &dev_attr_refresh.attr, + &dev_attr_nocp.attr, + &dev_attr_filter.attr, + &dev_attr_raw.attr, + &dev_attr_base.attr, + &dev_attr_diff.attr, + NULL, +}; + +static struct attribute *sys_attributes[] = { + &dev_attr_debug_mode.attr, + &dev_attr_rec_mode.attr, + &dev_attr_jig_mode.attr, + &dev_attr_printk.attr, + &dev_attr_printk5.attr, + &dev_attr_printk6.attr, +#ifdef IST30XX_GESTURE + &dev_attr_gesture.attr, +#endif + &dev_attr_direct.attr, + &dev_attr_clb_time.attr, + &dev_attr_clb.attr, + &dev_attr_clb_result.attr, + &dev_attr_cal_ref.attr, + &dev_attr_tsp_power_on.attr, + &dev_attr_tsp_power_off.attr, + &dev_attr_errcnt.attr, + &dev_attr_scancnt.attr, + &dev_attr_timerms.attr, + &dev_attr_report_rate.attr, + &dev_attr_idle_rate.attr, + &dev_attr_mode_ta.attr, + &dev_attr_mode_call.attr, + &dev_attr_mode_cover.attr, + &dev_attr_ic_inform.attr, + NULL, +}; + +static struct attribute *tunes_attributes[] = { + &dev_attr_node_info.attr, + &dev_attr_regcmd.attr, + &dev_attr_reg.attr, + &dev_attr_adb.attr, +#ifdef IST30XX_ALGORITHM_MODE + &dev_attr_algorithm.attr, +#endif + &dev_attr_intr_debug.attr, + &dev_attr_intr_debug2.attr, + &dev_attr_intr_debug3.attr, + &dev_attr_debugging_mode.attr, + &dev_attr_debugging_cnt.attr, + &dev_attr_debugging_frame.attr, + &dev_attr_debugging_status.attr, + &dev_attr_tbase.attr, + NULL, +}; + +static struct attribute_group node_attr_group = { + .attrs = node_attributes, +}; + +static struct attribute_group sys_attr_group = { + .attrs = sys_attributes, +}; + +static struct attribute_group tunes_attr_group = { + .attrs = tunes_attributes, +}; + +extern struct class *ist30xx_class; +struct device *ist30xx_sys_dev; +struct device *ist30xx_tunes_dev; +struct device *ist30xx_node_dev; + +int ist30xx_init_misc_sysfs(struct ist30xx_data *data) +{ + /* /sys/class/touch/sys */ + ist30xx_sys_dev = device_create(ist30xx_class, NULL, 0, data, "sys"); + + /* /sys/class/touch/sys/... */ + if (unlikely(sysfs_create_group(&ist30xx_sys_dev->kobj, + &sys_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "sys"); + + /* /sys/class/touch/tunes */ + ist30xx_tunes_dev = device_create(ist30xx_class, NULL, 0, data, "tunes"); + + /* /sys/class/touch/tunes/... */ + if (unlikely(sysfs_create_group(&ist30xx_tunes_dev->kobj, + &tunes_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "tunes"); + + /* /sys/class/touch/node */ + ist30xx_node_dev = device_create(ist30xx_class, NULL, 0, data, "node"); + + /* /sys/class/touch/node/... */ + if (unlikely(sysfs_create_group(&ist30xx_node_dev->kobj, + &node_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "node"); + + ist30xx_debugging_init(data); + + return 0; +} diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_misc.h b/drivers/input/touchscreen/ist3038c/ist30xxc_misc.h new file mode 100644 index 000000000000..70a5320cdc78 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_misc.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XXC_MISC_H__ +#define __IST30XXC_MISC_H__ + +#define NODE_FLAG_RAW (1 << 0) +#define NODE_FLAG_BASE (1 << 1) +#define NODE_FLAG_FILTER (1 << 2) +#define NODE_FLAG_DIFF (1 << 3) +#define NODE_FLAG_ALL (0xF) +#define NODE_FLAG_NO_CCP (1 << 7) + +#define NODE_FLAG_CP_LOWER (1 << 0) +#define NODE_FLAG_CP_UPPER (1 << 1) + +#define TSP_RAW_ALL (0) +#define TSP_RAW_SCREEN (1 << 0) +#define TSP_RAW_KEY (1 << 1) + +#define IST30XX_REC_FILENAME "ist30xxc.res" + +int ist30xx_check_valid_ch(struct ist30xx_data *data, int ch_tx, int ch_rx); +int ist30xx_parse_cp_node(struct ist30xx_data *data, struct TSP_NODE_BUF *node); +int parse_cp_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node, s16 *buf16, int mode); +int ist30xx_read_cp_node(struct ist30xx_data *data, struct TSP_NODE_BUF *node); +int ist30xx_parse_touch_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node); +int parse_tsp_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node, s16 *buf16, int mode); +int ist30xx_read_touch_node(struct ist30xx_data *data, u8 flag, + struct TSP_NODE_BUF *node); + +int ist30xx_put_frame(struct ist30xx_data *data, u32 ms, u32 *touch, u32 *frame, + int frame_cnt); + +int ist30xx_init_misc_sysfs(struct ist30xx_data *data); + +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_sys.c b/drivers/input/touchscreen/ist3038c/ist30xxc_sys.c new file mode 100644 index 000000000000..52303ff9de13 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_sys.c @@ -0,0 +1,493 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ist30xxc.h" +#include "ist30xxc_update.h" +#ifdef IST30XX_TRACKING_MODE +#include "ist30xxc_tracking.h" +#endif + +/****************************************************************************** + * Return value of Error + * EPERM : 1 (Operation not permitted) + * ENOENT : 2 (No such file or directory) + * EIO : 5 (I/O error) + * ENXIO : 6 (No such device or address) + * EINVAL : 22 (Invalid argument) + *****************************************************************************/ +int ist30xx_cmd_gesture(struct ist30xx_data *data, int value) +{ + int ret = -EIO; + + if (value > 3) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_GESTURE_EN << 16) | (value & 0xFFFF)); + + return ret; +} + +int ist30xx_cmd_start_scan(struct ist30xx_data *data) +{ + int ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_FW_START << 16) | (IST30XX_ENABLE & 0xFFFF)); + +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_CMD_SCAN); +#endif + data->status.noise_mode = true; + + return ret; +} + +int ist30xx_cmd_calibrate(struct ist30xx_data *data) +{ + int ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_RUN_CAL_AUTO << 16)); + +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_CMD_CALIB); +#endif + tsp_info("%s\n", __func__); + + return ret; +} + +int ist30xx_cmd_cal_reference(struct ist30xx_data *data) +{ + int ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_RUN_CAL_REF << 16)); + +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_CMD_CALIB); +#endif + tsp_info("%s\n", __func__); + + return ret; +} + +int ist30xx_cmd_check_calib(struct ist30xx_data *data) +{ + int ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_RUN_CAL_PARAM << 16) | (IST30XX_ENABLE & 0xFFFF)); + +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_CMD_CHECK_CALIB); +#endif + tsp_info("*** Check Calibration cmd ***\n"); + + return ret; +} + +int ist30xx_cmd_hold(struct ist30xx_data *data, int enable) +{ + int ret; + + if (!data->initialized && (data->status.update != 1)) + return 0; + + ret = ist30xx_write_cmd(data, IST30XX_HIB_CMD, + (eHCOM_FW_HOLD << 16) | (enable & 0xFFFF)); + tsp_info("%s: FW HOLDE %s\n", __func__, enable ? "Enable" : "Disable"); + +#ifdef IST30XX_TRACKING_MODE + if (enable) + ist30xx_tracking(TRACK_CMD_ENTER_REG); + else + ist30xx_tracking(TRACK_CMD_EXIT_REG); +#endif + + return ret; +} + +int ist30xx_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int msg_num, u8 *cmd_buf) +{ + int ret = 0; + int idx = msg_num - 1; + int size = msgs[idx].len; + u8 *msg_buf = NULL; + u8 *pbuf = NULL; + int trans_size, max_size = 0; + + if (msg_num == WRITE_CMD_MSG_LEN) + max_size = I2C_MAX_WRITE_SIZE; + else if (msg_num == READ_CMD_MSG_LEN) + max_size = I2C_MAX_READ_SIZE; + + if (unlikely(max_size == 0)) { + tsp_err("%s() : transaction size(%d)\n", __func__, max_size); + return -EINVAL; + } + + if (msg_num == WRITE_CMD_MSG_LEN) { + msg_buf = kmalloc(max_size + IST30XX_ADDR_LEN, GFP_KERNEL); + if (!msg_buf) + return -ENOMEM; + memcpy(msg_buf, cmd_buf, IST30XX_ADDR_LEN); + pbuf = msgs[idx].buf; + } + + while (size > 0) { + trans_size = (size >= max_size ? max_size : size); + + msgs[idx].len = trans_size; + if (msg_num == WRITE_CMD_MSG_LEN) { + memcpy(&msg_buf[IST30XX_ADDR_LEN], pbuf, trans_size); + msgs[idx].buf = msg_buf; + msgs[idx].len += IST30XX_ADDR_LEN; + } + ret = i2c_transfer(adap, msgs, msg_num); + if (unlikely(ret != msg_num)) { + tsp_err("%s() : i2c_transfer failed(%d), num=%d\n", + __func__, ret, msg_num); + break; + } + + if (msg_num == WRITE_CMD_MSG_LEN) + pbuf += trans_size; + else + msgs[idx].buf += trans_size; + + size -= trans_size; + } + + if (msg_num == WRITE_CMD_MSG_LEN) + kfree(msg_buf); + + return ret; +} + +int ist30xx_read_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len) +{ + int ret, i; + u32 le_reg = cpu_to_be32(cmd); + + struct i2c_msg msg[READ_CMD_MSG_LEN] = { + { + .addr = client->addr, + .flags = 0, + .len = IST30XX_ADDR_LEN, + .buf = (u8 *)&le_reg, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = len * IST30XX_DATA_LEN, + .buf = (u8 *)buf, + }, + }; + + ret = ist30xx_i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN, NULL); + if (unlikely(ret != READ_CMD_MSG_LEN)) + return -EIO; + + for (i = 0; i < len; i++) + buf[i] = cpu_to_be32(buf[i]); + + return 0; +} + +int ist30xx_write_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len) +{ + int i; + int ret; + struct i2c_msg msg; + u8 cmd_buf[IST30XX_ADDR_LEN]; + u8 msg_buf[IST30XX_DATA_LEN * (len + 1)]; + + put_unaligned_be32(cmd, cmd_buf); + + if (likely(len > 0)) { + for (i = 0; i < len; i++) + put_unaligned_be32(buf[i], msg_buf + (i * IST30XX_DATA_LEN)); + } else { + /* then add dummy data(4byte) */ + put_unaligned_be32(0, msg_buf); + len = 1; + } + + msg.addr = client->addr; + msg.flags = 0; + msg.len = len * IST30XX_DATA_LEN; + msg.buf = msg_buf; + + ret = ist30xx_i2c_transfer(client->adapter, &msg, WRITE_CMD_MSG_LEN, + cmd_buf); + if (unlikely(ret != WRITE_CMD_MSG_LEN)) + return -EIO; + + return 0; +} + +int ist30xx_read_reg(struct i2c_client *client, u32 reg, u32 *buf) +{ + int ret; + u32 le_reg = cpu_to_be32(reg); + + struct i2c_msg msg[READ_CMD_MSG_LEN] = { + { + .addr = client->addr, + .flags = 0, + .len = IST30XX_ADDR_LEN, + .buf = (u8 *)&le_reg, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = IST30XX_DATA_LEN, + .buf = (u8 *)buf, + }, + }; + + ret = i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN); + if (ret != READ_CMD_MSG_LEN) { + tsp_err("%s: i2c failed (%d), cmd: %x\n", __func__, ret, reg); + return -EIO; + } + *buf = cpu_to_be32(*buf); + + return 0; +} + +int ist30xx_read_cmd(struct ist30xx_data *data, u32 cmd, u32 *buf) +{ + int ret; + + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret)) + return ret; + + ist30xx_read_reg(data->client, IST30XX_DA_ADDR(cmd), buf); + + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (unlikely(ret)) { + ist30xx_reset(data, false); + return ret; + } + + return ret; +} + +int ist30xx_write_cmd(struct ist30xx_data *data, u32 cmd, u32 val) +{ + int ret; + u8 msg_buf[IST30XX_ADDR_LEN + IST30XX_DATA_LEN]; + struct i2c_msg msg; + + put_unaligned_be32(cmd, msg_buf); + put_unaligned_be32(val, msg_buf + IST30XX_ADDR_LEN); + + msg.addr = data->client->addr; + msg.flags = 0; + msg.len = IST30XX_ADDR_LEN + IST30XX_DATA_LEN; + msg.buf = msg_buf; + + ret = i2c_transfer(data->client->adapter, &msg, WRITE_CMD_MSG_LEN); + if (ret != WRITE_CMD_MSG_LEN) { + tsp_err("%s: i2c failed (%d), cmd: %x(%x)\n", __func__, ret, cmd, val); + return -EIO; + } + + if (data->initialized && !data->ignore_delay) + ist30xx_delay(40); + + return 0; +} + +int ist30xx_burst_read(struct i2c_client *client, u32 addr, + u32 *buf32, u16 len, bool bit_en) +{ + int ret = 0; + int i; + u16 max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN; + u16 remain_len = len; + + if (bit_en) + addr = IST30XX_BA_ADDR(addr); + + for (i = 0; i < len; i += max_len) { + if (remain_len < max_len) + max_len = remain_len; + + ret = ist30xx_read_buf(client, addr, buf32, max_len); + if (unlikely(ret)) { + tsp_err("Burst fail, addr: %x\n", __func__, addr); + return ret; + } + + addr += max_len * IST30XX_DATA_LEN; + buf32 += max_len; + remain_len -= max_len; + } + + return 0; +} + +int ist30xx_burst_write(struct i2c_client *client, u32 addr, + u32 *buf32, u16 len) +{ + int ret = 0; + int i; + u16 max_len = I2C_MAX_WRITE_SIZE / IST30XX_DATA_LEN; + u16 remain_len = len; + + addr = IST30XX_BA_ADDR(addr); + + for (i = 0; i < len; i += max_len) { + if (remain_len < max_len) + max_len = remain_len; + + ret = ist30xx_write_buf(client, addr, buf32, max_len); + if (unlikely(ret)) { + tsp_err("Burst fail, addr: %x\n", __func__, addr); + return ret; + } + + addr += max_len * IST30XX_DATA_LEN; + buf32 += max_len; + remain_len -= max_len; + } + + return 0; +} + +static void ts_power_enable(struct ist30xx_data *data, int en) +{ + + if (en) { + + gpio_direction_output(data->dt_data->reset_gpio, 1); + + } else { + + gpio_direction_output(data->dt_data->reset_gpio, 0); + } +} + +int ist30xx_power_on(struct ist30xx_data *data, bool download) +{ + if (data->status.power != 1) { + tsp_info("%s()\n", __func__); +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_PWR_ON); +#endif + /* VDD enable */ + /* VDDIO enable */ + ts_power_enable(data, 1); + if (download) + ist30xx_delay(30); + else + ist30xx_delay(60); + + data->status.power = 1; + } + + return 0; +} + +int ist30xx_power_off(struct ist30xx_data *data) +{ + if (data->status.power != 0) { + tsp_info("%s()\n", __func__); +#ifdef IST30XX_TRACKING_MODE + ist30xx_tracking(TRACK_PWR_OFF); +#endif + data->ignore_delay = true; + ist30xxc_isp_enable(data, true); + data->ignore_delay = false; + /* VDDIO disable */ + /* VDD disable */ + ts_power_enable(data, 0); + data->status.power = 0; + data->status.noise_mode = false; + } + + return 0; +} + +int ist30xx_reset(struct ist30xx_data *data, bool download) +{ + tsp_info("%s()\n", __func__); + ist30xx_power_off(data); + ist30xx_delay(30); + ist30xx_power_on(data, download); + + return 0; +} + +int ist30xx_internal_suspend(struct ist30xx_data *data) +{ +#ifdef IST30XX_GESTURE + data->suspend = true; + if (ist30xx_gesture_func_on) { + if (data->gesture) { + ist30xx_reset(data, false); + ist30xx_cmd_gesture(data, 3); + } + } else { + ist30xx_power_off(data); + } +#else + ist30xx_power_off(data); +#endif + + return 0; +} + +int ist30xx_internal_resume(struct ist30xx_data *data) +{ +#ifdef IST30XX_GESTURE + data->suspend = false; + if (ist30xx_gesture_func_on) { + if (data->gesture) + ist30xx_reset(data, false); + } else + ist30xx_power_on(data, false); +#else + ist30xx_power_on(data, false); +#endif + + return 0; +} + +int ist30xx_init_system(struct ist30xx_data *data) +{ + int ret; + + + ret = ist30xx_power_on(data, false); + if (ret) { + tsp_err("%s: ist30xx_init_system failed (%d)\n", __func__, ret); + return -EIO; + } + + return 0; +} + diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_tracking.c b/drivers/input/touchscreen/ist3038c/ist30xxc_tracking.c new file mode 100644 index 000000000000..9eaab6e81211 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_tracking.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include + +#include "ist30xxc.h" +#ifdef IST30XX_TRACKING_MODE +#include "ist30xxc_tracking.h" +#endif + +#ifdef IST30XX_TRACKING_MODE +IST30XX_RING_BUF TrackBuf; +IST30XX_RING_BUF *pTrackBuf; + +bool tracking_initialize = false; + +void ist30xx_tracking_init(void) +{ + if (tracking_initialize) + return; + + pTrackBuf = &TrackBuf; + + pTrackBuf->RingBufCtr = 0; + pTrackBuf->RingBufInIdx = 0; + pTrackBuf->RingBufOutIdx = 0; + + tracking_initialize = true; +} + +void ist30xx_tracking_deinit(void) +{ +} + +static spinlock_t mr_lock = __SPIN_LOCK_UNLOCKED(); +int ist30xx_get_track(u32 *track, int cnt) +{ + int i; + u8 *buf = (u8 *)track; + unsigned long flags; + + cnt *= sizeof(track[0]); + + spin_lock_irqsave(&mr_lock, flags); + + if (pTrackBuf->RingBufCtr < (u16)cnt) { + spin_unlock_irqrestore(&mr_lock, flags); + return IST30XX_RINGBUF_NOT_ENOUGH; + } + + for (i = 0; i < cnt; i++) { + if (pTrackBuf->RingBufOutIdx == IST30XX_MAX_RINGBUF_SIZE) + pTrackBuf->RingBufOutIdx = 0; + + *buf++ = (u8)pTrackBuf->LogBuf[pTrackBuf->RingBufOutIdx++]; + pTrackBuf->RingBufCtr--; + } + + spin_unlock_irqrestore(&mr_lock, flags); + + return IST30XX_RINGBUF_NO_ERR; +} + +u32 ist30xx_get_track_cnt(void) +{ + return pTrackBuf->RingBufCtr; +} + +int ist30xx_put_track(u32 *track, int cnt) +{ + int i; + u8 *buf = (u8 *)track; + unsigned long flags; + + spin_lock_irqsave(&mr_lock, flags); + + cnt *= sizeof(track[0]); + + pTrackBuf->RingBufCtr += cnt; + if (pTrackBuf->RingBufCtr > IST30XX_MAX_RINGBUF_SIZE) { + pTrackBuf->RingBufOutIdx += + (pTrackBuf->RingBufCtr - IST30XX_MAX_RINGBUF_SIZE); + if (pTrackBuf->RingBufOutIdx >= IST30XX_MAX_RINGBUF_SIZE) + pTrackBuf->RingBufOutIdx -= IST30XX_MAX_RINGBUF_SIZE; + + pTrackBuf->RingBufCtr = IST30XX_MAX_RINGBUF_SIZE; + } + + for (i = 0; i < cnt; i++) { + if (pTrackBuf->RingBufInIdx == IST30XX_MAX_RINGBUF_SIZE) + pTrackBuf->RingBufInIdx = 0; + pTrackBuf->LogBuf[pTrackBuf->RingBufInIdx++] = *buf++; + } + + spin_unlock_irqrestore(&mr_lock, flags); + + return IST30XX_RINGBUF_NO_ERR; +} + +int ist30xx_put_track_ms(u32 ms) +{ + ms &= 0x0000FFFF; + ms |= IST30XX_TRACKING_MAGIC; + + return ist30xx_put_track(&ms, 1); +} + +static struct timespec t_track; +int ist30xx_tracking(u32 status) +{ + u32 ms; + + if (!tracking_initialize) + ist30xx_tracking_init(); + + ktime_get_ts(&t_track); + ms = t_track.tv_sec * 1000 + t_track.tv_nsec / 1000000; + + ist30xx_put_track_ms(ms); + ist30xx_put_track(&status, 1); + + return 0; +} + +#define MAX_TRACKING_COUNT (1024) +/* sysfs: /sys/class/touch/tracking/track_frame */ +ssize_t ist30xx_track_frame_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, buf_cnt = 0; + u32 track_cnt = MAX_TRACKING_COUNT; + u32 track; + char msg[10]; + struct ist30xx_data *data = dev_get_drvdata(dev); + + mutex_lock(&data->lock); + + buf[0] = '\0'; + + if (track_cnt > ist30xx_get_track_cnt()) + track_cnt = ist30xx_get_track_cnt(); + + track_cnt /= sizeof(track); + + tsp_verb("num: %d of %d\n", track_cnt, ist30xx_get_track_cnt()); + + for (i = 0; i < track_cnt; i++) { + ist30xx_get_track(&track, 1); + + tsp_verb("%08X\n", track); + + buf_cnt += sprintf(msg, "%08x", track); + strcat(buf, msg); + } + + mutex_unlock(&data->lock); + + return buf_cnt; +} + +/* sysfs: /sys/class/touch/tracking/track_cnt */ +ssize_t ist30xx_track_cnt_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 val = (u32)ist30xx_get_track_cnt(); + + tsp_verb("tracking cnt: %d\n", val); + + return sprintf(buf, "%08x", val); +} + + +/* sysfs */ +static DEVICE_ATTR(track_frame, 0664, ist30xx_track_frame_show, NULL); +static DEVICE_ATTR(track_cnt, 0664, ist30xx_track_cnt_show, NULL); + +static struct attribute *tracking_attributes[] = { + &dev_attr_track_frame.attr, + &dev_attr_track_cnt.attr, + NULL, +}; + +static struct attribute_group tracking_attr_group = { + .attrs = tracking_attributes, +}; + +extern struct class *ist30xx_class; +struct device *ist30xx_tracking_dev; + +int ist30xx_init_tracking_sysfs(struct ist30xx_data *data) +{ + /* /sys/class/touch/tracking */ + ist30xx_tracking_dev = device_create(ist30xx_class, NULL, 0, data, + "tracking"); + + dev_set_drvdata(ist30xx_tracking_dev, data); + /* /sys/class/touch/tracking/... */ + if (sysfs_create_group(&ist30xx_tracking_dev->kobj, &tracking_attr_group)) + tsp_err("[ TSP ] Failed to create sysfs group(%s)!\n", "tracking"); + + ist30xx_tracking_init(); + + return 0; +} +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_tracking.h b/drivers/input/touchscreen/ist3038c/ist30xxc_tracking.h new file mode 100644 index 000000000000..f8447ccd17a4 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_tracking.h @@ -0,0 +1,44 @@ +#ifndef __IST30XXC_TRACKING_H__ +#define __IST30XXC_TRACKING_H__ + +#define TRACK_PWR_ON (0x1) +#define TRACK_PWR_OFF (0x2) +#define TRACK_PWR_RESET (0x3) +#define TRACK_INTR_ENABLE (0x4) +#define TRACK_INTR_DISABLE (0x5) +#define TRACK_CMD_RUN_DEVICE (0x10) +#define TRACK_CMD_SCAN (0x11) +#define TRACK_CMD_TACON (0x12) +#define TRACK_CMD_TADISCON (0x13) +#define TRACK_CMD_FWUPDATE (0x14) +#define TRACK_CMD_PRUPDATE (0x15) +#define TRACK_CMD_CALIB (0x16) +#define TRACK_CMD_CHECK_CALIB (0x17) +#define TRACK_CMD_CHKSUM (0x18) +#define TRACK_CMD_CHKSUM_ALL (0x19) +#define TRACK_CMD_ENTER_REG (0x1A) +#define TRACK_CMD_EXIT_REG (0x1B) +#define TRACK_CMD_CALL (0x1C) +#define TRACK_CMD_NOTCALL (0x1D) +#define TRACK_CMD_COVER (0x1E) +#define TRACK_CMD_NOTCOVER (0x1F) +#define TRACK_POS_FINGER (0x20) +#define TRACK_POS_KEY (0x30) +#define TRACK_POS_UNKNOWN (0x3F) + +#define IST30XX_TRACKING_MAGIC (0x7750 << 16) + +void ist30xx_tracking_init(void); +void ist30xx_tracking_deinit(void); + +int ist30xx_get_track(u32 *track, int cnt); +int ist30xx_put_track(u32 *track, int cnt); +int ist30xx_put_track_ms(u32 ms); + +u32 ist30xx_get_track_cnt(void); + +int ist30xx_tracking(u32 status); + +int ist30xx_init_tracking_sysfs(struct ist30xx_data *data); + +#endif diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_update.c b/drivers/input/touchscreen/ist3038c/ist30xxc_update.c new file mode 100644 index 000000000000..534bf0a4259b --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_update.c @@ -0,0 +1,1623 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ist30xxc.h" +#include "ist30xxc_update.h" +#include "ist30xxc_tracking.h" + +#ifdef IST30XX_INTERNAL_BIN + + +#include "IST3038C1_00000C6GFF_VER000007.h" +#endif + +#define TAGS_PARSE_OK (0) + + + +int ist30xx_isp_read_burst(struct i2c_client *client, u32 addr, u32 *buf32, + u16 len) +{ + int ret = 0; + int i; + u16 max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN; + u16 remain_len = len; + + for (i = 0; i < len; i += max_len) { + if (remain_len < max_len) + max_len = remain_len; + ret = ist30xx_read_buf(client, addr, buf32, max_len); + if (unlikely(ret)) { + tsp_err("Burst fail, addr: %x\n", __func__, addr); + return ret; + } + + buf32 += max_len; + remain_len -= max_len; + } + + return 0; +} + +int ist30xx_isp_write_burst(struct i2c_client *client, u32 addr, u32 *buf32, + u16 len) +{ + int ret = 0; + int i; + u16 max_len = I2C_MAX_WRITE_SIZE / IST30XX_DATA_LEN; + u16 remain_len = len; + + for (i = 0; i < len; i += max_len) { + if (remain_len < max_len) + max_len = remain_len; + ret = ist30xx_write_buf(client, addr, buf32, max_len); + if (unlikely(ret)) { + tsp_err("Burst fail, addr: %x\n", addr); + return ret; + } + + buf32 += max_len; + remain_len -= max_len; + } + + return 0; +} + +#define IST30XX_ISP_READ_TOTAL_S (0x01) +#define IST30XX_ISP_READ_TOTAL_B (0x11) +#define IST30XX_ISP_READ_MAIN_S (0x02) +#define IST30XX_ISP_READ_MAIN_B (0x12) +#define IST30XX_ISP_READ_INFO_S (0x03) +#define IST30XX_ISP_READ_INFO_B (0x13) +#define IST30XX_ISP_PROG_TOTAL_S (0x04) +#define IST30XX_ISP_PROG_TOTAL_B (0x14) +#define IST30XX_ISP_PROG_MAIN_S (0x05) +#define IST30XX_ISP_PROG_MAIN_B (0x15) +#define IST30XX_ISP_PROG_INFO_S (0x06) +#define IST30XX_ISP_PROG_INFO_B (0x16) +#define IST30XX_ISP_ERASE_BLOCK (0x07) +#define IST30XX_ISP_ERASE_SECTOR (0x08) +#define IST30XX_ISP_ERASE_PAGE (0x09) +#define IST30XX_ISP_ERASE_INFO (0x0A) +#define IST30XX_ISP_READ_TOTAL_CRC (0x1B) +#define IST30XX_ISP_READ_MAIN_CRC (0x1C) +#define IST30XX_ISP_READ_INFO_CRC (0x1D) +int ist30xxc_isp_enable(struct ist30xx_data *data, bool enable) +{ + int ret = 0; + + if (enable) { + ret = ist30xx_write_cmd(data, IST30XX_FLASH_ISPEN, 0xDE01); + if (unlikely(ret)) + return ret; + +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) + ret = ist30xx_write_cmd(data, IST30XX_FLASH_MODE, 0x4100); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_TEST_MODE1, 0x38); + if (unlikely(ret)) + return ret; +#endif + } else { + ret = ist30xx_write_cmd(data, IST30XX_FLASH_ISPEN, 0x2); + if (unlikely(ret)) + return ret; + } + + ist30xx_delay(1); + + return ret; +} + +int ist30xxc_isp_mode(struct ist30xx_data *data, int mode) +{ + int ret = 0; + u32 val = 0; + + switch (mode) { + case IST30XX_ISP_READ_TOTAL_S: + val = 0x8090; + break; + case IST30XX_ISP_READ_TOTAL_B: + case IST30XX_ISP_READ_TOTAL_CRC: + val = 0x8190; + break; + case IST30XX_ISP_READ_MAIN_S: + val = 0x0090; + break; + case IST30XX_ISP_READ_MAIN_B: + case IST30XX_ISP_READ_MAIN_CRC: + val = 0x0190; + break; + case IST30XX_ISP_READ_INFO_S: + val = 0x0098; + break; + case IST30XX_ISP_READ_INFO_B: + case IST30XX_ISP_READ_INFO_CRC: + val = 0x0198; + break; + case IST30XX_ISP_PROG_TOTAL_S: + val = 0x8050; + break; + case IST30XX_ISP_PROG_TOTAL_B: + val = 0x8150; + break; + case IST30XX_ISP_PROG_MAIN_S: + val = 0x0050; + break; + case IST30XX_ISP_PROG_MAIN_B: + val = 0x0150; + break; + case IST30XX_ISP_PROG_INFO_S: + val = 0x0058; + break; + case IST30XX_ISP_PROG_INFO_B: + val = 0x0158; + break; + case IST30XX_ISP_ERASE_BLOCK: + val = 0x0031; + break; + case IST30XX_ISP_ERASE_SECTOR: + val = 0x0032; + break; + case IST30XX_ISP_ERASE_PAGE: + val = 0x0030; + break; + case IST30XX_ISP_ERASE_INFO: + val = 0x0038; + break; + default: + tsp_err("ISP fail, unknown mode\n"); + return -EINVAL; + } + +#if (IMAGIS_TSP_IC > IMAGIS_IST3032C) + val &= ~(0x8000); +#endif + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_MODE, val); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_MODE\n"); + return ret; + } + + return 0; +} + +int ist30xxc_isp_erase(struct ist30xx_data *data, int mode, u32 index) +{ + int ret = 0; + + tsp_info("%s\n", __func__); + + ret = ist30xxc_isp_mode(data, mode); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_DIN, index); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_DIN\n"); + return ret; + } + + ist30xx_delay(40); + + return ret; +} +#ifdef FLASH_USE_PAGE_CONTROL +int ist30xxc_isp_page_erase(struct ist30xx_data *data, u32 addr, u32 index) +{ + int ret = 0; + + tsp_info("%s\n", __func__); + + ret = ist30xxc_isp_mode(data, IST30XX_ISP_ERASE_PAGE); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_ADDR, addr / 4); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_ADDR\n"); + return ret; + } + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_DIN, index); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_DIN\n"); + return ret; + } + + tsp_info("%s delay 0\n", __func__); + ist30xx_delay(40); + tsp_info("%s delay 1\n", __func__); + + return ret; +} +#endif +int ist30xxc_isp_program(struct ist30xx_data *data, u32 addr, int mode, + const u32 *buf32, int len) +{ + int ret = 0; + + tsp_info("%s\n", __func__); + + ret = ist30xxc_isp_mode(data, mode); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_ADDR, addr); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_ADDR\n"); + return ret; + } + + if (mode & 0x10) + ret = ist30xx_isp_write_burst(data->client, IST30XX_FLASH_DIN, + (u32 *)buf32, len); + else + ret = ist30xx_write_buf(data->client, IST30XX_FLASH_DIN, (u32 *)buf32, + len); + + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_DIN\n"); + return ret; + } + + return ret; +} + +int ist30xxc_isp_read(struct ist30xx_data *data, u32 addr, int mode, u32 *buf32, + int len) +{ + int ret = 0; + + tsp_info("%s\n", __func__); + + ret = ist30xxc_isp_mode(data, mode); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_ADDR, addr); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_ADDR\n"); + return ret; + } + + if (mode & 0x10) + ret = ist30xx_isp_read_burst(data->client, IST30XX_FLASH_DOUT, buf32, + len); + else + ret = ist30xx_read_buf(data->client, IST30XX_FLASH_DOUT, buf32, len); + + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_DOUT\n"); + return ret; + } + + return 0; +} + +int ist30xxc_cmd_read_chksum(struct ist30xx_data *data, int mode, + u32 start_addr, u32 end_addr, u32 *chksum) +{ + int ret = 0; + u32 val = (1 << 28) | (1 << 25) | (1 << 24) | (1 << 20) | (1 << 16); + + val |= (end_addr / IST30XX_ADDR_LEN) - 1; + + ret = ist30xxc_isp_mode(data, mode); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_ADDR, start_addr); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_ADDR (%x)\n", val); + return ret; + } + + ret = ist30xx_write_cmd(data, IST30XX_FLASH_AUTO_READ, val); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_AUTO_READ (%x)\n", val); + return ret; + } + + ist30xx_delay(100); + + ret = ist30xx_read_reg(data->client, IST30XX_FLASH_CRC, chksum); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XX_FLASH_CRC (%x)\n", chksum); + return ret; + } + + return 0; +} + +int ist30xxc_read_chksum(struct ist30xx_data *data, u32 *chksum) +{ + int ret = 0; + u32 start_addr, end_addr; + + start_addr = data->tags.fw_addr; + end_addr = data->tags.sensor_addr + data->tags.sensor_size; + ret = ist30xxc_cmd_read_chksum(data, IST30XX_ISP_READ_TOTAL_CRC, start_addr, + end_addr, chksum); + if (unlikely(ret)) + return ret; + + tsp_info("chksum: %x(%x~%x)\n", *chksum, start_addr, end_addr); + + return 0; +} + +int ist30xxc_read_chksum_all(struct ist30xx_data *data, u32 *chksum) +{ + int ret = 0; + u32 start_addr, end_addr; + + start_addr = IST30XX_FLASH_BASE_ADDR; + end_addr = IST30XX_FLASH_BASE_ADDR + IST30XX_FLASH_TOTAL_SIZE; + ret = ist30xxc_cmd_read_chksum(data, IST30XX_ISP_READ_TOTAL_CRC, start_addr, + end_addr, chksum); + if (unlikely(ret)) + return ret; + + tsp_info("chksum: %x(%x~%x)\n", *chksum, start_addr, end_addr); + + return 0; +} + +int ist30xxc_isp_info_read(struct ist30xx_data *data, u32 addr, u32 *buf32, + u32 len) +{ + int ret = 0; + int retry = IST30XX_MAX_RETRY_CNT; + +isp_info_read_retry: + if (retry-- == 0) + goto isp_info_read_end; + + ist30xx_reset(data, true); + + ret = ist30xxc_isp_enable(data, true); + if (unlikely(ret)) + goto isp_info_read_retry; + + ret = ist30xxc_isp_read(data, addr, IST30XX_ISP_READ_INFO_B, buf32, len); + if (unlikely(ret)) + goto isp_info_read_retry; + +isp_info_read_end: + ist30xxc_isp_enable(data, false); + ist30xx_reset(data, false); + + return ret; +} + +int ist30xxc_isp_fw_read(struct ist30xx_data *data, u32 *buf32) +{ + int ret = 0; + int i; + int len; + u32 addr = IST30XX_FLASH_BASE_ADDR; + + ist30xx_reset(data, true); + data->ignore_delay = true; + + ret = ist30xxc_isp_enable(data, true); + if (unlikely(ret)) + return ret; + + for (i = 0; i < IST30XX_FLASH_TOTAL_SIZE; i += I2C_MAX_READ_SIZE) { + len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN; + if ((IST30XX_FLASH_TOTAL_SIZE - i) < I2C_MAX_READ_SIZE) + len = (IST30XX_FLASH_TOTAL_SIZE - i) / IST30XX_DATA_LEN; + + ret = ist30xxc_isp_read(data, addr, IST30XX_ISP_READ_TOTAL_B, + buf32, len); + if (unlikely(ret)) + goto isp_fw_read_end; + + addr += len; + buf32 += len; + } + +isp_fw_read_end: + data->ignore_delay = false; + ist30xxc_isp_enable(data, false); + ist30xx_reset(data, false); + return ret; +} + +int ist30xxc_isp_fw_update(struct ist30xx_data *data, const u8 *buf) +{ +#ifdef FLASH_USE_PAGE_CONTROL + int i; +#endif + int ret = 0; + int size = 0; +#ifdef FLASH_USE_PAGE_CONTROL + int page_cnt = IST30XX_FLASH_TOTAL_SIZE / IST30XX_FLASH_PAGE_SIZE; +#endif + u32 addr = IST30XX_FLASH_BASE_ADDR; + + tsp_info("%s\n", __func__); + + ist30xx_reset(data, true); + data->ignore_delay = true; + + ret = ist30xxc_isp_enable(data, true); + if (unlikely(ret)) + goto isp_fw_update_end; +#ifdef FLASH_USE_PAGE_CONTROL + for (i = 0; i < (page_cnt - 2); i++) { + ret = ist30xxc_isp_page_erase(data, addr, 0); + if (unlikely(ret)) + goto isp_fw_update_end; + + addr += IST30XX_FLASH_PAGE_SIZE; + } +#else + ret = ist30xxc_isp_erase(data, IST30XX_ISP_ERASE_BLOCK, 0); + if (unlikely(ret)) + goto isp_fw_update_end; +#endif + +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) + ret = ist30xxc_isp_erase(data, IST30XX_ISP_ERASE_INFO, 0); + if (unlikely(ret)) + goto isp_fw_update_end; +#endif + + ist30xx_reset(data, true); + + ret = ist30xxc_isp_enable(data, true); + if (unlikely(ret)) + goto isp_fw_update_end; + +#ifdef FLASH_USE_PAGE_CONTROL + addr = IST30XX_FLASH_BASE_ADDR; + size = IST30XX_FLASH_TOTAL_SIZE - (IST30XX_FLASH_PAGE_SIZE * 2); +#else + size = IST30XX_FLASH_TOTAL_SIZE; +#endif + ret = ist30xxc_isp_program(data, addr, IST30XX_ISP_PROG_TOTAL_B, (u32 *)buf, + size / IST30XX_DATA_LEN); + if (unlikely(ret)) + goto isp_fw_update_end; + +isp_fw_update_end: + data->ignore_delay = false; + ist30xxc_isp_enable(data, false); + ist30xx_reset(data, false); + msleep(100); + return ret; +} + +u32 ist30xx_parse_ver(struct ist30xx_data *data, int flag, const u8 *buf) +{ + u32 ver = 0; + u32 *buf32 = (u32 *)buf; + + if (flag == FLAG_MAIN) + ver = (u32)buf32[(data->tags.flag_addr + 0x1FC) >> 2]; + else if (flag == FLAG_TEST) + ver = (u32)buf32[(data->tags.flag_addr + 0x1F4) >> 2]; + else if (flag == FLAG_FW) + ver = (u32)(buf32[(data->tags.cfg_addr + 0x4) >> 2] & 0xFFFF); + else if (flag == FLAG_CORE) + ver = (u32)buf32[(data->tags.flag_addr + 0x1F0) >> 2]; + else + tsp_warn("Parsing ver's flag is not corrent!\n"); + + return ver; +} + +int calib_ms_delay = CALIB_WAIT_TIME; +int ist30xx_calib_wait(struct ist30xx_data *data) +{ + int cnt = calib_ms_delay; + + data->status.calib_msg = 0; + while (cnt-- > 0) { + ist30xx_delay(100); + + if (data->status.calib_msg) { + tsp_info("Calibration status : %d, Max raw gap : %d - (%08x)\n", + CALIB_TO_STATUS(data->status.calib_msg), + CALIB_TO_GAP(data->status.calib_msg), + data->status.calib_msg); + if (CALIB_TO_STATUS(data->status.calib_msg) == 0) + return 0; + else + return -EAGAIN; + } + } + tsp_warn("Calibration time out\n"); + + return -EPERM; +} + +int ist30xx_calibrate(struct ist30xx_data *data, int wait_cnt) +{ + int ret = -ENOEXEC; + + tsp_info("*** Calibrate %ds ***\n", calib_ms_delay / 10); + + data->status.calib = 1; + ist30xx_disable_irq(data); + while (1) { + ret = ist30xx_cmd_calibrate(data); + if (unlikely(ret)) + continue; + + ist30xx_enable_irq(data); + ret = ist30xx_calib_wait(data); + if (likely(!ret)) + break; + + ist30xx_disable_irq(data); + + if (--wait_cnt == 0) + break; + + ist30xx_reset(data, false); + } + + ist30xx_disable_irq(data); + ist30xx_reset(data, false); + msleep(100); + data->status.calib = 0; + ist30xx_enable_irq(data); + + return ret; +} + +int ist30xx_cal_ref_wait(struct ist30xx_data *data) +{ + int cnt = calib_ms_delay; + u32 result; + + data->status.cal_ref_msg = 0; + while (cnt-- > 0) { + ist30xx_delay(100); + + if (data->status.cal_ref_msg) { + result = CAL_REF_TO_STATUS(data->status.cal_ref_msg); + tsp_info("Cal reference status : %04X - (%08x)\n", result, + data->status.cal_ref_msg); + if (result & CAL_REF_NONE) { + tsp_warn("Cal reference time out\n"); + return 1; + } else if (result & CAL_REF_OK) { + tsp_warn("Cal reference success\n"); + return 0; + } else { + tsp_warn("Cal reference error\n"); + return -EAGAIN; + } + } + } + tsp_warn("Cal reference time out\n"); + + return -EPERM; +} + +int ist30xx_cal_reference(struct ist30xx_data *data) +{ + int ret = -ENOEXEC; + + tsp_info("*** Cal Reference %ds ***\n", calib_ms_delay / 10); + + data->status.calib = 1; + ist30xx_disable_irq(data); + ret = ist30xx_cmd_cal_reference(data); + if (ret) + goto err_cal_ref; + + ist30xx_enable_irq(data); + ret = ist30xx_cal_ref_wait(data); + +err_cal_ref: + ist30xx_reset(data, false); + msleep(100); + data->status.calib = 0; + ist30xx_enable_irq(data); + + return ret; +} + +int ist30xx_parse_tags(struct ist30xx_data *data, const u8 *buf, const u32 size) +{ + int ret = -EPERM; + struct ist30xx_tags *tags; + + tags = (struct ist30xx_tags *)(&buf[size - sizeof(struct ist30xx_tags)]); + + if (!strncmp(tags->magic1, IST30XX_TAG_MAGIC, sizeof(tags->magic1)) + && !strncmp(tags->magic2, IST30XX_TAG_MAGIC, sizeof(tags->magic2))) { + data->tags = *tags; + + data->tags.fw_addr -= data->tags.rom_base; + data->tags.cfg_addr -= data->tags.rom_base; + data->tags.sensor_addr -= data->tags.rom_base; + data->tags.cp_addr -= data->tags.rom_base; + data->tags.flag_addr -= data->tags.rom_base; + + data->fw.index = data->tags.fw_addr; + data->fw.size = tags->flag_addr - tags->fw_addr + + tags->flag_size; + data->fw.chksum = tags->chksum; + + data->zvalue_addr = data->tags.zvalue_base; + data->raw_addr = data->tags.raw_base; + data->filter_addr = data->tags.filter_base; + data->algorithm_addr = data->tags.algr_base; + + tsp_verb("Tagts magic1: %s, magic2: %s\n", + data->tags.magic1, data->tags.magic2); + tsp_verb(" rom: %x\n", data->tags.rom_base); + tsp_verb(" ram: %x\n", data->tags.ram_base); + tsp_verb(" fw: %x(%x)\n", data->tags.fw_addr, data->tags.fw_size); + tsp_verb(" cfg: %x(%x)\n", data->tags.cfg_addr, data->tags.cfg_size); + tsp_verb(" sensor: %x(%x)\n", + data->tags.sensor_addr, data->tags.sensor_size); + tsp_verb(" cp: %x(%x)\n", data->tags.cp_addr, data->tags.cp_size); + tsp_verb(" flag: %x(%x)\n", data->tags.flag_addr, data->tags.flag_size); + tsp_verb(" zvalue: %x\n", data->tags.zvalue_base); + tsp_verb(" algo: %x\n", data->tags.algr_base); + tsp_verb(" raw: %x\n", data->tags.raw_base); + tsp_verb(" filter: %x\n", data->tags.filter_base); + tsp_verb(" chksum: %x\n", data->tags.chksum); + tsp_verb(" chksum_all: %x\n", data->tags.chksum_all); + tsp_verb(" build time: %04d/%02d/%02d (%02d:%02d:%02d)\n", + data->tags.year, data->tags.month, data->tags.day, + data->tags.hour, data->tags.min, data->tags.sec); + + ret = 0; + } + + return ret; +} + +int ist30xx_get_update_info(struct ist30xx_data *data, const u8 *buf, + const u32 size) +{ + int ret; + + ret = ist30xx_parse_tags(data, buf, size); + if (unlikely(ret != TAGS_PARSE_OK)) + tsp_warn("Cannot find tags of F/W\n"); + + return ret; +} + +#define TSP_INFO_SWAP_XY (1 << 0) +#define TSP_INFO_FLIP_X (1 << 1) +#define TSP_INFO_FLIP_Y (1 << 2) +u32 ist30xx_info_cal_crc(u32 *buf) +{ + int i; + u32 chksum32 = 0; + + for (i = 0; i < IST30XX_MAX_CMD_SIZE - 1; i++) + chksum32 += *buf++; + + return chksum32; +} + +int ist30xx_tsp_update_info(struct ist30xx_data *data) +{ + int ret = 0; + u32 chksum; + u32 info[IST30XX_MAX_CMD_SIZE]; + u32 fw_mode; + u32 tsp_lcd, tsp_swap, tsp_scr, tsp_gtx, tsp_ch; + u32 tkey_info0, tkey_info1, tkey_info2; + u32 finger_info, baseline, threshold; + u32 debugging_info; + TSP_INFO *tsp = &data->tsp_info; +#ifdef IST30XX_USE_KEY + TKEY_INFO *tkey = &data->tkey_info; +#endif + + ret = ist30xx_cmd_hold(data, IST30XX_ENABLE); + if (unlikely(ret)) + return ret; + + ret = ist30xx_burst_read(data->client, IST30XX_DA_ADDR(eHCOM_GET_CHIP_ID), + &info[0], IST30XX_MAX_CMD_SIZE, true); + if (unlikely(ret)) + return ret; + + ret = ist30xx_cmd_hold(data, IST30XX_DISABLE); + if (unlikely(ret)) { + ist30xx_reset(data, false); + return ret; + } + + ret = ist30xx_read_cmd(data, IST30XX_REG_CHIPID, &data->chip_id); + if (unlikely(ret)) + return ret; + + if ((info[IST30XX_CMD_VALUE(eHCOM_GET_CHIP_ID)] != data->chip_id) || + (info[IST30XX_CMD_VALUE(eHCOM_GET_CHIP_ID)] == 0) || + (info[IST30XX_CMD_VALUE(eHCOM_GET_CHIP_ID)] == 0xFFFF)) + return -EINVAL; + + chksum = ist30xx_info_cal_crc((u32 *)info); + if (chksum != info[IST30XX_MAX_CMD_SIZE - 1]) { + tsp_err("info checksum : %08X, %08X\n", chksum, + info[IST30XX_MAX_CMD_SIZE - 1]); + return -EINVAL; + } + tsp_info("info read success\n"); + + fw_mode = info[IST30XX_CMD_VALUE(eHCOM_GET_FW_MODE)]; + tsp_lcd = info[IST30XX_CMD_VALUE(eHCOM_GET_LCD_INFO)]; + tsp_ch = info[IST30XX_CMD_VALUE(eHCOM_GET_TSP_INFO)]; + tkey_info0 = info[IST30XX_CMD_VALUE(eHCOM_GET_KEY_INFO_0)]; + tkey_info1 = info[IST30XX_CMD_VALUE(eHCOM_GET_KEY_INFO_1)]; + tkey_info2 = info[IST30XX_CMD_VALUE(eHCOM_GET_KEY_INFO_2)]; + tsp_scr = info[IST30XX_CMD_VALUE(eHCOM_GET_SCR_INFO)]; + tsp_gtx = info[IST30XX_CMD_VALUE(eHCOM_GET_GTX_INFO)]; + tsp_swap = info[IST30XX_CMD_VALUE(eHCOM_GET_SWAP_INFO)]; + finger_info = info[IST30XX_CMD_VALUE(eHCOM_GET_FINGER_INFO)]; + baseline = info[IST30XX_CMD_VALUE(eHCOM_GET_BASELINE)]; + threshold = info[IST30XX_CMD_VALUE(eHCOM_GET_TOUCH_TH)]; + debugging_info = info[IST30XX_CMD_VALUE(eHCOM_GET_DBG_INFO_BASE)]; + data->raw_addr = info[IST30XX_CMD_VALUE(eHCOM_GET_RAW_BASE)]; + data->filter_addr = info[IST30XX_CMD_VALUE(eHCOM_GET_FILTER_BASE)]; + data->zvalue_addr = info[IST30XX_CMD_VALUE(eHCOM_GET_ZVALUE_BASE)]; + data->algorithm_addr = info[IST30XX_CMD_VALUE(eHCOM_GET_ALGO_BASE)]; + + if (fw_mode == IST30XX_NON_CAL_MODE) + data->fw_mode = IST30XX_NON_CAL_MODE; + else + data->fw_mode = IST30XX_CAL_MODE; + + data->debugging_addr = debugging_info & 0x00FFFFFF; + data->debugging_size = (debugging_info >> 24) & 0xFF; + + tsp->ch_num.rx = (tsp_ch >> 16) & 0xFFFF; + tsp->ch_num.tx = tsp_ch & 0xFFFF; + + tsp->node.len = tsp->ch_num.tx * tsp->ch_num.rx; + + tsp->gtx.num = (tsp_gtx >> 24) & 0xFF; + tsp->gtx.ch_num[0] = (tsp_gtx >> 16) & 0xFF; + tsp->gtx.ch_num[1] = (tsp_gtx >> 8) & 0xFF; + tsp->gtx.ch_num[2] = 0xFF; + tsp->gtx.ch_num[3] = 0xFF; + + tsp->finger_num = finger_info; + tsp->dir.swap_xy = (tsp_swap & TSP_INFO_SWAP_XY ? true : false); + tsp->dir.flip_x = (tsp_swap & TSP_INFO_FLIP_X ? true : false); + tsp->dir.flip_y = (tsp_swap & TSP_INFO_FLIP_Y ? true : false); + + tsp->baseline = baseline & 0xFFFF; + + tsp->screen.rx = (tsp_scr >> 16) & 0xFFFF; + tsp->screen.tx = tsp_scr & 0xFFFF; + + if (tsp->dir.swap_xy) { + tsp->width = tsp_lcd & 0xFFFF; + tsp->height = (tsp_lcd >> 16) & 0xFFFF; + } else { + tsp->width = (tsp_lcd >> 16) & 0xFFFF; + tsp->height = tsp_lcd & 0xFFFF; + } + +#ifdef IST30XX_USE_KEY + tkey->enable = (((tkey_info0 >> 24) & 0xFF) ? true : false); + tkey->key_num = (tkey_info0 >> 16) & 0xFF; + tkey->ch_num[0].tx = tkey_info0 & 0xFF; + tkey->ch_num[0].rx = (tkey_info0 >> 8) & 0xFF; + tkey->ch_num[1].tx = (tkey_info1 >> 16) & 0xFF; + tkey->ch_num[1].rx = (tkey_info1 >> 24) & 0xFF; + tkey->ch_num[2].tx = tkey_info1 & 0xFF; + tkey->ch_num[2].rx = (tkey_info1 >> 8) & 0xFF; + tkey->ch_num[3].tx = (tkey_info2 >> 16) & 0xFF; + tkey->ch_num[3].rx = (tkey_info2 >> 24) & 0xFF; + tkey->baseline = (baseline >> 16) & 0xFFFF; +#endif + + return ret; +} + +int ist30xx_get_tsp_info(struct ist30xx_data *data) +{ + int ret = 0; + int retry = 3; +#ifdef IST30XX_INTERNAL_BIN + TSP_INFO *tsp = &data->tsp_info; +#ifdef IST30XX_USE_KEY + TKEY_INFO *tkey = &data->tkey_info; +#endif + u8 *cfg_buf; +#endif + + while (retry--) { + ret = ist30xx_tsp_update_info(data); + if (ret == 0) { + tsp_info("tsp update info success!\n"); + return ret; + } + } + +#ifdef IST30XX_INTERNAL_BIN + cfg_buf = (u8 *)&data->fw.buf[data->tags.cfg_addr]; + + tsp->ch_num.rx = (u8)cfg_buf[0x0C]; + tsp->ch_num.tx = (u8)cfg_buf[0x0D]; + tsp->screen.rx = (u8)cfg_buf[0x0E]; + tsp->screen.tx = (u8)cfg_buf[0x0F]; + tsp->node.len = tsp->ch_num.tx * tsp->ch_num.rx; + + tsp->gtx.num = (u8)cfg_buf[0x10]; + tsp->gtx.ch_num[0] = (u8)cfg_buf[0x11]; + tsp->gtx.ch_num[1] = (u8)cfg_buf[0x12]; + tsp->gtx.ch_num[2] = (u8)cfg_buf[0x13]; + tsp->gtx.ch_num[3] = (u8)cfg_buf[0x14]; + + tsp->finger_num = (u8)cfg_buf[0x38]; + tsp->dir.swap_xy = (bool)(cfg_buf[0x39] & TSP_INFO_SWAP_XY ? true : false); + tsp->dir.flip_x = (bool)(cfg_buf[0x39] & TSP_INFO_FLIP_X ? true : false); + tsp->dir.flip_y = (bool)(cfg_buf[0x39] & TSP_INFO_FLIP_Y ? true : false); + + tsp->baseline = (u16)((cfg_buf[0x29] << 8) | cfg_buf[0x28]); + + if (tsp->dir.swap_xy) { + tsp->width = (u16)((cfg_buf[0x23] << 8) | cfg_buf[0x22]); + tsp->height = (u16)((cfg_buf[0x21] << 8) | cfg_buf[0x20]); + } else { + tsp->width = (u16)((cfg_buf[0x21] << 8) | cfg_buf[0x20]); + tsp->height = (u16)((cfg_buf[0x23] << 8) | cfg_buf[0x22]); + } + +#ifdef IST30XX_USE_KEY + tkey->enable = (bool)(cfg_buf[0x15] & 1); + tkey->key_num = (u8)cfg_buf[0x16]; + tkey->ch_num[0].tx = (u8)cfg_buf[0x17]; + tkey->ch_num[0].rx = (u8)cfg_buf[0x1B]; + tkey->ch_num[1].tx = (u8)cfg_buf[0x18]; + tkey->ch_num[1].rx = (u8)cfg_buf[0x1C]; + tkey->ch_num[2].tx = (u8)cfg_buf[0x19]; + tkey->ch_num[2].rx = (u8)cfg_buf[0x1D]; + tkey->ch_num[3].tx = (u8)cfg_buf[0x1A]; + tkey->ch_num[3].rx = (u8)cfg_buf[0x1E]; + + tkey->baseline = (u16)((cfg_buf[0x2B] << 8) | cfg_buf[0x2A]); +#endif +#endif + + return ret; +} + +void ist30xx_print_info(struct ist30xx_data *data) +{ + TSP_INFO *tsp = &data->tsp_info; + TKEY_INFO *tkey = &data->tkey_info; + + tsp_info("*** TSP/TKEY info ***\n"); + if (data->fw_mode == IST30XX_CAL_MODE) + tsp_info("FW Mode : Cal Mode\n"); + else + tsp_info("FW Mode : Non Cal Mode\n"); + tsp_info("TSP info: \n"); + tsp_info(" finger num: %d\n", tsp->finger_num); + tsp_info(" dir swap: %d, flip x: %d, y: %d\n", + tsp->dir.swap_xy, tsp->dir.flip_x, tsp->dir.flip_y); + tsp_info(" baseline: %d\n", tsp->baseline); + tsp_info(" ch_num tx: %d, rx: %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + tsp_info(" screen tx: %d, rx: %d\n", tsp->screen.tx, tsp->screen.rx); + tsp_info(" width: %d, height: %d\n", tsp->width, tsp->height); + tsp_info(" gtx num: %d\n", tsp->gtx.num); + tsp_info(" [1]: %d, [2]: %d, [3]: %d, [4]: %d\n", tsp->gtx.ch_num[0], + tsp->gtx.ch_num[1], tsp->gtx.ch_num[2], tsp->gtx.ch_num[3]); + tsp_info(" node len: %d\n", tsp->node.len); + tsp_info("TKEY info: \n"); + tsp_info(" enable: %d, key num: %d\n", tkey->enable, tkey->key_num); + tsp_info(" [1]: %d,%d [2]: %d,%d [3]: %d,%d [4]: %d,%d\n", + tkey->ch_num[0].tx, tkey->ch_num[0].rx, tkey->ch_num[1].tx, + tkey->ch_num[1].rx, tkey->ch_num[2].tx, tkey->ch_num[2].rx, + tkey->ch_num[3].tx, tkey->ch_num[3].rx); + tsp_info(" baseline : %d\n", tkey->baseline); +} + +#define update_next_step(ret) { if (unlikely(ret)) goto end; } +int ist30xx_fw_update(struct ist30xx_data *data, const u8 *buf, int size) +{ + int ret = 0; + u32 chksum = 0; + struct ist30xx_fw *fw = &data->fw; + + tsp_info("*** Firmware update ***\n"); + tsp_info(" main: %x, fw: %x, test: %x, core: %x(addr: 0x%x ~ 0x%x)\n", + fw->bin.main_ver, fw->bin.fw_ver, fw->bin.test_ver, fw->bin.core_ver, + fw->index, (fw->index + fw->size)); + + data->status.update = 1; + data->status.update_result = 0; + + ist30xx_disable_irq(data); + + ret = ist30xxc_isp_fw_update(data, buf); + update_next_step(ret); + + ret = ist30xx_read_cmd(data, eHCOM_GET_CRC32, &chksum); + if (unlikely((ret) || (chksum != fw->chksum))) { + if (unlikely(ret)) + ist30xx_reset(data, false); + + goto end; + } + + ret = ist30xx_get_ver_info(data); + update_next_step(ret); + +end: + if (unlikely(ret)) { + data->status.update_result = 1; + tsp_warn("Firmware update Fail!, ret=%d\n", ret); + } else if (unlikely(chksum != fw->chksum)) { + data->status.update_result = 1; + tsp_warn("Error CheckSum: %x(%x)\n", chksum, fw->chksum); + ret = -ENOEXEC; + } + + ist30xx_enable_irq(data); + + data->status.update = 2; + + return ret; +} + +int ist30xx_fw_recovery(struct ist30xx_data *data) +{ + int ret = -EPERM; + u8 *fw = data->fw.buf; + int fw_size = data->fw.buf_size; + + ret = ist30xx_get_update_info(data, fw, fw_size); + if (ret) { + data->status.update_result = 1; + return ret; + } + + data->fw.bin.main_ver = ist30xx_parse_ver(data, FLAG_MAIN, fw); + data->fw.bin.fw_ver = ist30xx_parse_ver(data, FLAG_FW, fw); + data->fw.bin.test_ver = ist30xx_parse_ver(data, FLAG_TEST, fw); + data->fw.bin.core_ver = ist30xx_parse_ver(data, FLAG_CORE, fw); + + mutex_lock(&data->lock); + ret = ist30xx_fw_update(data, fw, fw_size); + if (ret == 0) { + ist30xx_get_tsp_info(data); + ist30xx_print_info(data); +#ifndef IST30XX_UPDATE_NO_CAL + if (data->fw_mode == IST30XX_CAL_MODE) + ist30xx_calibrate(data, 1); +#endif + } + mutex_unlock(&data->lock); + + ist30xx_start(data); + + return ret; +} + +#ifdef IST30XX_INTERNAL_BIN +int ist30xx_check_fw(struct ist30xx_data *data) +{ + int ret; + u32 chksum; + + ret = ist30xx_read_cmd(data, eHCOM_GET_CRC32, &chksum); + if (unlikely(ret)) { + ist30xx_reset(data, false); + return ret; + } + + if (unlikely(chksum != data->fw.chksum)) { + tsp_warn("Checksum compare error, (IC: %08x, Bin: %08x)\n", + chksum, data->fw.chksum); + return -EPERM; + } + + return 0; +} + +#define MAIN_VER_MASK 0xFF000000 +int ist30xx_check_auto_update(struct ist30xx_data *data) +{ + int ret = 0; + int retry = IST30XX_MAX_RETRY_CNT; + u32 chip_id = 0; + bool tsp_check = false; + u32 chksum; + struct ist30xx_fw *fw = &data->fw; + + while (retry--) { + ret = ist30xx_read_cmd(data, eHCOM_GET_CHIP_ID, &chip_id); + if (likely(ret == 0)) { + if (likely(chip_id == IST30XX_CHIP_ID)) + tsp_check = true; + + break; + } + + ist30xx_reset(data, false); + } + + if (unlikely(!tsp_check)) + goto fw_check_end; + + ist30xx_get_ver_info(data); + + if (likely((fw->cur.fw_ver > 0) && (fw->cur.fw_ver <= 0xFFFF))) { + if (unlikely(((fw->cur.main_ver & MAIN_VER_MASK) == MAIN_VER_MASK) || + ((fw->cur.main_ver & MAIN_VER_MASK) == 0))) + goto fw_check_end; + + tsp_info("Version compare IC: %x(%x), BIN: %x(%x)\n", fw->cur.fw_ver, + fw->cur.main_ver, fw->bin.fw_ver, fw->bin.main_ver); + + /* If FW version is same, check FW checksum */ + if (likely((fw->cur.main_ver == fw->bin.main_ver) && + (fw->cur.fw_ver == fw->bin.fw_ver) && + (fw->cur.test_ver == 0))) { + ret = ist30xx_read_cmd(data, eHCOM_GET_CRC32, &chksum); + if (unlikely((ret) || (chksum != fw->chksum))) { + tsp_warn("Checksum error, IC: %x, Bin: %x (ret: %d)\n", + chksum, fw->chksum, ret); + goto fw_check_end; + } + } + + /* + * fw->cur.main_ver : Main version in TSP IC + * fw->cur.fw_ver : FW version if TSP IC + * fw->bin.main_ver : Main version in FW Binary + * fw->bin.fw_ver : FW version in FW Binary + */ + /* If the ver of binary is higher than ver of IC, FW update operate. */ + + if (likely((fw->cur.main_ver >= fw->bin.main_ver) && + (fw->cur.fw_ver >= fw->bin.fw_ver))) + return 0; + } + +fw_check_end: + return -EAGAIN; +} + +int ist30xx_auto_bin_update(struct ist30xx_data *data) +{ + int ret = 0; + int retry = IST30XX_MAX_RETRY_CNT; + u32 fw_mode = 0; + struct ist30xx_fw *fw = &data->fw; + +#ifdef XIAOMI_PRODUCT + if (data->pid == C6_PID) { + fw->buf = (u8 *)ist30xxc_fw; + fw->buf_size = sizeof(ist30xxc_fw); + } else { + fw->buf = (u8 *)ist30xxc_fw; + fw->buf_size = sizeof(ist30xxc_fw); + } +#else + fw->buf = (u8 *)ist30xxc_fw; + fw->buf_size = sizeof(ist30xxc_fw); +#endif + + ret = ist30xx_get_update_info(data, fw->buf, fw->buf_size); + if (unlikely(ret)) + return 1; + + fw->bin.main_ver = ist30xx_parse_ver(data, FLAG_MAIN, fw->buf); + fw->bin.fw_ver = ist30xx_parse_ver(data, FLAG_FW, fw->buf); + fw->bin.test_ver = ist30xx_parse_ver(data, FLAG_TEST, fw->buf); + fw->bin.core_ver = ist30xx_parse_ver(data, FLAG_CORE, fw->buf); + + tsp_info("IC: %x, Binary ver main: %x, fw: %x, test: %x, core: %x\n", + data->chip_id, fw->bin.main_ver, fw->bin.fw_ver, fw->bin.test_ver, + fw->bin.core_ver); + + mutex_lock(&data->lock); + ret = ist30xx_check_auto_update(data); + mutex_unlock(&data->lock); + + if (likely(ret >= 0)) + return ret; + +update_bin: + tsp_info("Update version. fw(main, test, core): %x(%x, %x, %x) -> " + "%x(%x, %x, %x)\n", fw->cur.fw_ver, fw->cur.main_ver, + fw->cur.test_ver, fw->cur.core_ver, fw->bin.fw_ver, + fw->bin.main_ver, fw->bin.test_ver, fw->bin.core_ver); + + mutex_lock(&data->lock); + while (retry--) { + ret = ist30xx_fw_update(data, fw->buf, fw->buf_size); + if (unlikely(!ret)) + break; + } + mutex_unlock(&data->lock); + + if (unlikely(ret)) + goto end_update; + + if (unlikely(retry > 0 && ist30xx_check_fw(data))) + goto update_bin; + + ret = ist30xx_read_cmd(data, eHCOM_GET_FW_MODE, &fw_mode); + if (unlikely(ret)) { + data->fw_mode = IST30XX_CAL_MODE; + } else { + if (fw_mode == IST30XX_NON_CAL_MODE) + data->fw_mode = IST30XX_NON_CAL_MODE; + else + data->fw_mode = IST30XX_CAL_MODE; + } + +#ifndef IST30XX_UPDATE_NO_CAL + if (data->fw_mode == IST30XX_CAL_MODE) { + mutex_lock(&data->lock); + ist30xx_calibrate(data, IST30XX_MAX_RETRY_CNT); + mutex_unlock(&data->lock); + } +#endif + +end_update: + return ret; +} +#endif + +#define MAX_FILE_PATH 255 +const u8 fwbuf[IST30XX_FLASH_TOTAL_SIZE + sizeof(struct ist30xx_tags)]; +/* sysfs: /sys/class/touch/firmware/firmware */ +ssize_t ist30xx_fw_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + int fw_size = 0; + u8 *fw = NULL; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + long fsize = 0, nread = 0; + char fw_path[MAX_FILE_PATH]; + const struct firmware *request_fw = NULL; + int mode = 0; + int calib = 1; + struct ist30xx_data *data = dev_get_drvdata(dev); + + sscanf(buf, "%d %d", &mode, &calib); + + switch (mode) { + case MASK_UPDATE_INTERNAL: +#ifdef IST30XX_INTERNAL_BIN + fw = data->fw.buf; + fw_size = data->fw.buf_size; +#else + data->status.update_result = 1; + tsp_warn("Not support internal bin!!\n"); + return size; +#endif + break; + + case MASK_UPDATE_FW: + ret = request_firmware(&request_fw, IST30XX_FW_NAME, + &data->client->dev); + if (ret) { + data->status.update_result = 1; + tsp_warn("File not found, %s\n", IST30XX_FW_NAME); + return size; + } + + fw = (u8 *)request_fw->data; + fw_size = (u32)request_fw->size; + tsp_info("firmware is loaded!!\n"); + break; + + case MASK_UPDATE_SDCARD: + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/%s", IST30XX_FW_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + data->status.update_result = 1; + tsp_info("file %s open error:%d\n", fw_path, PTR_ERR(fp)); + goto err_file_open; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + + if (sizeof(fwbuf) != fsize) { + data->status.update_result = 1; + tsp_info("mismatch fw size\n"); + goto err_fw_size; + } + + nread = vfs_read(fp, (char __user *)fwbuf, fsize, &fp->f_pos); + if (nread != fsize) { + data->status.update_result = 1; + tsp_info("mismatch fw size\n"); + goto err_fw_size; + } + + fw = (u8 *)fwbuf; + fw_size = (u32)fsize; + + filp_close(fp, current->files); + tsp_info("firmware is loaded!!\n"); + break; + + case MASK_UPDATE_ERASE: + tsp_info("EEPROM all erase!!\n"); + + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + ist30xx_reset(data, true); + data->ignore_delay = true; + ist30xxc_isp_enable(data, true); + ist30xxc_isp_erase(data, IST30XX_ISP_ERASE_BLOCK, 0); +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) + ist30xxc_isp_erase(data, IST30XX_ISP_ERASE_INFO, 0); +#endif + ist30xxc_isp_enable(data, false); + data->ignore_delay = false; + ist30xx_reset(data, false); + ist30xx_start(data); + ist30xx_enable_irq(data); + mutex_unlock(&data->lock); + + default: + return size; + } + + ret = ist30xx_get_update_info(data, fw, fw_size); + if (ret) { + data->status.update_result = 1; + goto err_get_info; + } + + data->fw.bin.main_ver = ist30xx_parse_ver(data, FLAG_MAIN, fw); + data->fw.bin.fw_ver = ist30xx_parse_ver(data, FLAG_FW, fw); + data->fw.bin.test_ver = ist30xx_parse_ver(data, FLAG_TEST, fw); + data->fw.bin.core_ver = ist30xx_parse_ver(data, FLAG_CORE, fw); + + mutex_lock(&data->lock); + ret = ist30xx_fw_update(data, fw, fw_size); + if (ret == 0) { + ist30xx_get_tsp_info(data); + ist30xx_print_info(data); + if (calib) { + if (data->fw_mode == IST30XX_CAL_MODE) + ist30xx_calibrate(data, 1); + else if (data->fw_mode == IST30XX_NON_CAL_MODE) + ist30xx_cal_reference(data); + } + } + mutex_unlock(&data->lock); + + ist30xx_start(data); + +err_get_info: + if (request_fw != NULL) + release_firmware(request_fw); + + if (fp) { +err_fw_size: + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + } + + return size; +} + +/* sysfs: /sys/class/touch/firmware/fw_sdcard */ +ssize_t ist30xx_fw_sdcard_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + long fsize = 0, nread = 0; + char fw_path[MAX_FILE_PATH]; + struct ist30xx_data *data = dev_get_drvdata(dev); + + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/%s", + IST30XX_FW_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + data->status.update_result = 1; + tsp_info("file %s open error:%d\n", fw_path, PTR_ERR(fp)); + goto err_file_open; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + + if (sizeof(fwbuf) != fsize) { + data->status.update_result = 1; + tsp_info("mismatch fw size\n"); + goto err_fw_size; + } + + nread = vfs_read(fp, (char __user *)fwbuf, fsize, &fp->f_pos); + if (nread != fsize) { + data->status.update_result = 1; + tsp_info("mismatch fw size\n"); + goto err_fw_size; + } + + filp_close(fp, current->files); + tsp_info("firmware is loaded!!\n"); + + ret = ist30xx_get_update_info(data, fwbuf, fsize); + if (ret) { + data->status.update_result = 1; + goto err_get_info; + } + + data->fw.bin.main_ver = ist30xx_parse_ver(data, FLAG_MAIN, fwbuf); + data->fw.bin.fw_ver = ist30xx_parse_ver(data, FLAG_FW, fwbuf); + data->fw.bin.test_ver = ist30xx_parse_ver(data, FLAG_TEST, fwbuf); + data->fw.bin.core_ver = ist30xx_parse_ver(data, FLAG_CORE, fwbuf); + + mutex_lock(&data->lock); + ret = ist30xx_fw_update(data, fwbuf, fsize); + if (ret == 0) { + ist30xx_get_tsp_info(data); + ist30xx_print_info(data); + } + mutex_unlock(&data->lock); + + ist30xx_start(data); + +err_get_info: +err_fw_size: + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + + return 0; +} + +/* sysfs: /sys/class/touch/firmware/firmware */ +ssize_t ist30xx_fw_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count; + struct ist30xx_data *data = dev_get_drvdata(dev); + + switch (data->status.update) { + case 1: + count = sprintf(buf, "Downloading\n"); + break; + case 2: + if (data->status.update_result) { + count = sprintf(buf, "Update fail\n"); + } else { + count = sprintf(buf, "Update success, " + "ver %x(%x, %x, %x)-> %x(%x, %x, %x), " + "status : %d, gap : %d\n", + data->fw.prev.fw_ver, data->fw.prev.main_ver, + data->fw.prev.test_ver, data->fw.prev.core_ver, + data->fw.cur.fw_ver, data->fw.cur.main_ver, + data->fw.cur.test_ver, data->fw.cur.core_ver, + CALIB_TO_STATUS(data->status.calib_msg), + CALIB_TO_GAP(data->status.calib_msg)); + } + break; + default: + if (data->status.update_result) + count = sprintf(buf, "Update fail\n"); + else + count = sprintf(buf, "Pass\n"); + } + + return count; +} + +/* sysfs: /sys/class/touch/firmware/fw_read */ +u32 buf32_flash[IST30XX_FLASH_TOTAL_SIZE / IST30XX_DATA_LEN]; +ssize_t ist30xx_fw_read_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i; + int ret; + int count; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + char fw_path[MAX_FILE_PATH]; + u8 *buf8 = (u8 *)buf32_flash; + struct ist30xx_data *data = dev_get_drvdata(dev); + + mutex_lock(&data->lock); + ist30xx_disable_irq(data); + + ret = ist30xxc_isp_fw_read(data, buf32_flash); + if (ret) { + count = sprintf(buf, "Fail\n"); + tsp_err("isp fw read fail\n"); + goto err_file_open; + } + + for (i = 0; i < IST30XX_FLASH_TOTAL_SIZE; i += 16) { + tsp_debug("%07x: %02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", i, + buf8[i], buf8[i + 1], buf8[i + 2], buf8[i + 3], + buf8[i + 4], buf8[i + 5], buf8[i + 6], buf8[i + 7], + buf8[i + 8], buf8[i + 9], buf8[i + 10], buf8[i + 11], + buf8[i + 12], buf8[i + 13], buf8[i + 14], buf8[i + 15]); + } + + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/%s", IST30XX_BIN_NAME); + fp = filp_open(fw_path, O_CREAT|O_WRONLY|O_TRUNC, 0); + if (IS_ERR(fp)) { + count = sprintf(buf, "Fail\n"); + tsp_err("file %s open error:%d\n", fw_path, PTR_ERR(fp)); + goto err_file_open; + } + + fp->f_op->write(fp, buf8, IST30XX_FLASH_TOTAL_SIZE, &fp->f_pos); + fput(fp); + + filp_close(fp, NULL); + set_fs(old_fs); + + count = sprintf(buf, "OK\n"); + +err_file_open: + ist30xx_enable_irq(data); + mutex_unlock(&data->lock); + + ist30xx_start(data); + + return count; +} + +/* sysfs: /sys/class/touch/firmware/version */ +ssize_t ist30xx_fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count; + struct ist30xx_data *data = dev_get_drvdata(dev); + + count = sprintf(buf, "ID: %x, main: %x, fw: %x, test: %x, core: %x\n", + data->chip_id, data->fw.cur.main_ver, data->fw.cur.fw_ver, + data->fw.cur.test_ver, data->fw.cur.core_ver); + +#ifdef IST30XX_INTERNAL_BIN + { + char msg[128]; + int ret = 0; + + ret = ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size); + if (ret == 0) { + count += sprintf(msg, + " Header - main: %x, fw: %x, test: %x, core: %x\n", + ist30xx_parse_ver(data, FLAG_MAIN, data->fw.buf), + ist30xx_parse_ver(data, FLAG_FW, data->fw.buf), + ist30xx_parse_ver(data, FLAG_TEST, data->fw.buf), + ist30xx_parse_ver(data, FLAG_CORE, data->fw.buf)); + strcat(buf, msg); + } + } +#endif + + return count; +} + +#ifdef XIAOMI_PRODUCT +/* sysfs: /sys/class/touch/firmware/lockdown */ +ssize_t ist30xx_lockdown_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("lockdown : %08X%08X\n", data->fw.cur.lockdown[0], + data->fw.cur.lockdown[1]); + + return sprintf(buf, "%08X%08X\n", data->fw.cur.lockdown[0], + data->fw.cur.lockdown[1]); +} + +/* sysfs: /sys/class/touch/firmware/config */ +ssize_t ist30xx_config_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + + tsp_info("config : %08X%08X\n", data->fw.cur.config[0], + data->fw.cur.config[1]); + + return sprintf(buf, "%08X%08X", data->fw.cur.config[0], + data->fw.cur.config[1]); +} +#endif + +/* sysfs */ +static DEVICE_ATTR(fw_read, S_IRWXUGO, ist30xx_fw_read_show, NULL); +static DEVICE_ATTR(firmware, S_IRWXUGO, ist30xx_fw_status_show, + ist30xx_fw_store); +static DEVICE_ATTR(fw_sdcard, S_IRWXUGO, ist30xx_fw_sdcard_show, NULL); +static DEVICE_ATTR(version, S_IRWXUGO, ist30xx_fw_version_show, NULL); +#ifdef XIAOMI_PRODUCT +static DEVICE_ATTR(lockdown, S_IRWXUGO, ist30xx_lockdown_show, NULL); +static DEVICE_ATTR(config, S_IRWXUGO, ist30xx_config_show, NULL); +#endif + +struct class *ist30xx_class; +struct device *ist30xx_fw_dev; + +static struct attribute *fw_attributes[] = { + &dev_attr_fw_read.attr, + &dev_attr_firmware.attr, + &dev_attr_fw_sdcard.attr, + &dev_attr_version.attr, +#ifdef XIAOMI_PRODUCT + &dev_attr_lockdown.attr, + &dev_attr_config.attr, +#endif + NULL, +}; + +static struct attribute_group fw_attr_group = { + .attrs = fw_attributes, +}; + +int ist30xx_init_update_sysfs(struct ist30xx_data *data) +{ + /* /sys/class/touch */ + ist30xx_class = class_create(THIS_MODULE, "touch"); + + /* /sys/class/touch/firmware */ + ist30xx_fw_dev = device_create(ist30xx_class, NULL, 0, data, "firmware"); + + /* /sys/class/touch/firmware/... */ + if (unlikely(sysfs_create_group(&ist30xx_fw_dev->kobj, &fw_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "firmware"); + + data->status.update = 0; + data->status.calib = 0; + data->status.update_result = 0; + + return 0; +} diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc_update.h b/drivers/input/touchscreen/ist3038c/ist30xxc_update.h new file mode 100644 index 000000000000..004082b74ef6 --- /dev/null +++ b/drivers/input/touchscreen/ist3038c/ist30xxc_update.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XXC_UPDATE_H__ +#define __IST30XXC_UPDATE_H__ + + +#define IST30XX_FLASH_BASE_ADDR (0x0) +#if (IMAGIS_TSP_IC < IMAGIS_IST3038C) +#define IST30XX_FLASH_TOTAL_SIZE (0x8400) +#else +#define IST30XX_FLASH_TOTAL_SIZE (0xFC00) +#define IST30XX_FLASH_PAGE_SIZE (0x0400) +#endif + + +#define IST30XX_FLASH_BASE (0x40006000) +#define IST30XX_FLASH_MODE IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x00) +#define IST30XX_FLASH_ADDR IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x04) +#define IST30XX_FLASH_DIN IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x08) +#define IST30XX_FLASH_DOUT IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x0C) +#define IST30XX_FLASH_ISPEN IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x10) +#define IST30XX_FLASH_AUTO_READ IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x14) +#define IST30XX_FLASH_CRC IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x18) +#define IST30XX_FLASH_TEST_MODE1 IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x30) +#define IST30XX_FLASH_STATUS IST30XX_DA_ADDR(IST30XX_FLASH_BASE | 0x90) + + +#define IST30XX_FW_NAME "ist30xxc.fw" +#define IST30XX_BIN_NAME "ist30xxc.bin" + + +#define CALIB_WAIT_TIME (50) /* unit : 100msec */ +#define CALIB_TO_GAP(n) ((n >> 16) & 0xFFF) +#define CALIB_TO_STATUS(n) ((n >> 12) & 0xF) +#define CALIB_TO_OS_VALUE(n) ((n >> 12) & 0xFFFF) + + +#define CAL_REF_TO_STATUS(n) ((n >> 8) & 0xFFFF) +#define CAL_REF_NONE (1 << 0) +#define CAL_REF_OK (1 << 4) +#define CAL_REF_OK_VERIFY (1 << 5) +#define CAL_REF_FAIL_UNKNOWN (1 << 8) +#define CAL_REF_FAIL_CRC (1 << 9) +#define CAL_REF_FAIL_VERIFY (1 << 10) + + +#define MASK_UPDATE_INTERNAL (1) +#define MASK_UPDATE_FW (2) +#define MASK_UPDATE_SDCARD (3) +#define MASK_UPDATE_ERASE (4) + + +#define FLAG_MAIN (1) +#define FLAG_FW (2) +#define FLAG_CORE (3) +#define FLAG_TEST (4) + +int ist30xxc_read_chksum(struct ist30xx_data *data, u32 *chksum); +int ist30xxc_read_chksum_all(struct ist30xx_data *data, u32 *chksum); + +int ist30xxc_isp_enable(struct ist30xx_data *data, bool enable); +int ist30xxc_isp_info_read(struct ist30xx_data *data, u32 addr, u32 *buf32, + u32 len); + +int ist30xx_get_update_info(struct ist30xx_data *data, const u8 *buf, + const u32 size); +int ist30xx_get_tsp_info(struct ist30xx_data *data); +void ist30xx_print_info(struct ist30xx_data *data); +u32 ist30xx_parse_ver(struct ist30xx_data *data, int flag, const u8 *buf); + +int ist30xx_fw_update(struct ist30xx_data *data, const u8 *buf, int size); +int ist30xx_fw_recovery(struct ist30xx_data *data); + +int ist30xx_auto_bin_update(struct ist30xx_data *data); + +int ist30xx_calibrate(struct ist30xx_data *data, int wait_cnt); +int ist30xx_cal_reference(struct ist30xx_data *data); + +int ist30xx_init_update_sysfs(struct ist30xx_data *data); + +#endif diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c index 328877a87951..43e82455335a 100644 --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -4889,12 +4889,18 @@ static int smbchg_restricted_charging(struct smbchg_chip *chip, bool enable) return rc; } - +extern void ist30xx_set_ta_mode(bool mode); +extern void tpd_usb_plugin(bool mode); +int set_usb_charge_mode_par = 0; static void handle_usb_removal(struct smbchg_chip *chip) { struct power_supply *parallel_psy = get_parallel_psy(chip); int rc; - + if (set_usb_charge_mode_par == 1) { + ist30xx_set_ta_mode(0); + } else if (set_usb_charge_mode_par == 2) { + tpd_usb_plugin(0); + } pr_smb(PR_STATUS, "triggered\n"); smbchg_aicl_deglitch_wa_check(chip); /* Clear the OV detected status set before */ @@ -4970,7 +4976,11 @@ static void handle_usb_insertion(struct smbchg_chip *chip) enum power_supply_type usb_supply_type; int rc; char *usb_type_name = "null"; - + if (set_usb_charge_mode_par == 1) { + ist30xx_set_ta_mode(1); + } else if (set_usb_charge_mode_par == 2) { + tpd_usb_plugin(1); + } pr_smb(PR_STATUS, "triggered\n"); /* usb inserted */ read_usb_type(chip, &usb_type_name, &usb_supply_type); From 9bdf7d685bbfd1e20d2e7ce74cd469895ff6ac73 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 07:41:10 +0000 Subject: [PATCH 44/86] drivers: input: fingerprint: Import Fingerprint Drivers --- drivers/input/Kconfig | 2 + drivers/input/Makefile | 1 + drivers/input/fingerprint/Kconfig | 6 + drivers/input/fingerprint/Makefile | 2 + drivers/input/fingerprint/fpc/Kconfig | 5 + drivers/input/fingerprint/fpc/Makefile | 1 + drivers/input/fingerprint/fpc/fpc1020_tee.c | 636 ++++++++++++++ drivers/input/fingerprint/goodix/Kconfig | 5 + drivers/input/fingerprint/goodix/Makefile | 2 + drivers/input/fingerprint/goodix/gf_spi.c | 906 ++++++++++++++++++++ drivers/input/fingerprint/goodix/gf_spi.h | 106 +++ drivers/input/fingerprint/goodix/netlink.c | 87 ++ drivers/input/fingerprint/goodix/platform.c | 202 +++++ 13 files changed, 1961 insertions(+) create mode 100644 drivers/input/fingerprint/Kconfig create mode 100644 drivers/input/fingerprint/Makefile create mode 100644 drivers/input/fingerprint/fpc/Kconfig create mode 100644 drivers/input/fingerprint/fpc/Makefile create mode 100644 drivers/input/fingerprint/fpc/fpc1020_tee.c create mode 100644 drivers/input/fingerprint/goodix/Kconfig create mode 100644 drivers/input/fingerprint/goodix/Makefile create mode 100644 drivers/input/fingerprint/goodix/gf_spi.c create mode 100644 drivers/input/fingerprint/goodix/gf_spi.h create mode 100644 drivers/input/fingerprint/goodix/netlink.c create mode 100644 drivers/input/fingerprint/goodix/platform.c diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 2a4c51377f86..0b4148ca34a7 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -201,6 +201,8 @@ source "drivers/input/touchscreen/Kconfig" source "drivers/input/misc/Kconfig" +source "drivers/input/fingerprint/Kconfig" + endif menu "Hardware I/O ports" diff --git a/drivers/input/Makefile b/drivers/input/Makefile index ee4c06520bb4..c5139fbc2cea 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_INPUT_MOUSE) += mouse/ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/ obj-$(CONFIG_INPUT_TABLET) += tablet/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ +obj-$(CONFIG_INPUT_FINGERPRINT) += fingerprint/ obj-$(CONFIG_INPUT_MISC) += misc/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o diff --git a/drivers/input/fingerprint/Kconfig b/drivers/input/fingerprint/Kconfig new file mode 100644 index 000000000000..3ca9ed2573bf --- /dev/null +++ b/drivers/input/fingerprint/Kconfig @@ -0,0 +1,6 @@ +config INPUT_FINGERPRINT + tristate "Fingerprint driver support" + help + Say Y here to enable goodix fingerprint driver support! +source "drivers/input/fingerprint/goodix/Kconfig" +source "drivers/input/fingerprint/fpc/Kconfig" diff --git a/drivers/input/fingerprint/Makefile b/drivers/input/fingerprint/Makefile new file mode 100644 index 000000000000..28d1360d2205 --- /dev/null +++ b/drivers/input/fingerprint/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_FINGERPRINT_GOODIX_GF3208) += goodix/ +obj-$(CONFIG_FINGERPRINT_FPC1020) += fpc/ diff --git a/drivers/input/fingerprint/fpc/Kconfig b/drivers/input/fingerprint/fpc/Kconfig new file mode 100644 index 000000000000..749075beb7ca --- /dev/null +++ b/drivers/input/fingerprint/fpc/Kconfig @@ -0,0 +1,5 @@ +config FINGERPRINT_FPC1020 + tristate "FingerPrint Cards fingerprint drvier support" + depends on INPUT_FINGERPRINT + help + Say Y here to enable goodix fingerprint driver support! diff --git a/drivers/input/fingerprint/fpc/Makefile b/drivers/input/fingerprint/fpc/Makefile new file mode 100644 index 000000000000..2a107b89704d --- /dev/null +++ b/drivers/input/fingerprint/fpc/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_FINGERPRINT_FPC1020) += fpc1020_tee.o diff --git a/drivers/input/fingerprint/fpc/fpc1020_tee.c b/drivers/input/fingerprint/fpc/fpc1020_tee.c new file mode 100644 index 000000000000..19f9fbbd842e --- /dev/null +++ b/drivers/input/fingerprint/fpc/fpc1020_tee.c @@ -0,0 +1,636 @@ +/* + * FPC1020 Fingerprint sensor device driver + * + * This driver will control the platform resources that the FPC fingerprint + * sensor needs to operate. The major things are probing the sensor to check + * that it is actually connected and let the Kernel know this and with that also + * enabling and disabling of regulators, enabling and disabling of platform + * clocks, controlling GPIOs such as SPI chip select, sensor reset line, sensor + * IRQ line, MISO and MOSI lines. + * + * The driver will expose most of its available functionality in sysfs which + * enables dynamic control of these features from eg. a user space process. + * + * The sensor's IRQ events will be pushed to Kernel's event handling system and + * are exposed in the drivers event node. This makes it possible for a user + * space process to poll the input node and receive IRQ events easily. Usually + * this node is available under /dev/input/eventX where 'X' is a number given by + * the event system. A user space process will need to traverse all the event + * nodes and ask for its parent's name (through EVIOCGNAME) which should match + * the value in device tree named input-device-name. + * + * This driver will NOT send any SPI commands to the sensor it only controls the + * electrical parts. + * + * + * Copyright (c) 2015 Fingerprint Cards AB + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License Version 2 + * as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FPC1020_RESET_LOW_US 1000 +#define FPC1020_RESET_HIGH1_US 100 +#define FPC1020_RESET_HIGH2_US 1250 +#define PWR_ON_STEP_SLEEP 100 +#define PWR_ON_STEP_RANGE1 100 +#define PWR_ON_STEP_RANGE2 900 +#define FPC_TTW_HOLD_TIME 1000 +#define NUM_PARAMS_REG_ENABLE_SET 2 + +static const char * const pctl_names[] = { + + "fpc1020_reset_reset", + "fpc1020_reset_active", + "fpc1020_irq_active", +}; + +struct fpc1020_data { + struct device *dev; + struct pinctrl *fingerprint_pinctrl; + struct pinctrl_state *pinctrl_state[ARRAY_SIZE(pctl_names)]; +#ifdef LINUX_CONTROL_SPI_CLK + u32 max_speed_hz; + struct clk *iface_clk; + struct clk *core_clk; +#endif + + struct wake_lock ttw_wl; + int irq_gpio; + int rst_gpio; + struct mutex lock; + bool prepared; + bool wakeup_enabled; + bool compatible_enabled; +#ifdef LINUX_CONTROL_SPI_CLK + bool clocks_enabled; + bool clocks_suspended; +#endif +}; + +static irqreturn_t fpc1020_irq_handler(int irq, void *handle); +static int fpc1020_request_named_gpio(struct fpc1020_data *fpc1020, + const char *label, int *gpio); +static int hw_reset(struct fpc1020_data *fpc1020); + +#ifdef LINUX_CONTROL_SPI_CLK +static int set_clks(struct fpc1020_data *fpc1020, bool enable) +{ + int rc = 0; + mutex_lock(&fpc1020->lock); + + if (enable == fpc1020->clocks_enabled) + goto out; + + if (enable) { + rc = clk_set_rate(fpc1020->core_clk, fpc1020->max_speed_hz); + if (rc) { + dev_err(fpc1020->dev, + "%s: Error setting clk_rate: %u, %d\n", + __func__, fpc1020->max_speed_hz, + rc); + goto out; + } + rc = clk_prepare_enable(fpc1020->core_clk); + if (rc) { + dev_err(fpc1020->dev, + "%s: Error enabling core clk: %d\n", + __func__, rc); + goto out; + } + + rc = clk_prepare_enable(fpc1020->iface_clk); + if (rc) { + dev_err(fpc1020->dev, + "%s: Error enabling iface clk: %d\n", + __func__, rc); + clk_disable_unprepare(fpc1020->core_clk); + goto out; + } + dev_dbg(fpc1020->dev, "%s ok. clk rate %u hz\n", __func__, + fpc1020->max_speed_hz); + + fpc1020->clocks_enabled = true; + } else { + clk_disable_unprepare(fpc1020->iface_clk); + clk_disable_unprepare(fpc1020->core_clk); + fpc1020->clocks_enabled = false; + } + +out: + mutex_unlock(&fpc1020->lock); + return rc; +} + +static ssize_t clk_enable_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + return set_clks(fpc1020, (*buf == '1')) ? : count; +} + +static DEVICE_ATTR(clk_enable, S_IWUSR, NULL, clk_enable_set); +#endif +/** + * Will try to select the set of pins (GPIOS) defined in a pin control node of + * the device tree named @p name. + * + * The node can contain several eg. GPIOs that is controlled when selecting it. + * The node may activate or deactivate the pins it contains, the action is + * defined in the device tree node itself and not here. The states used + * internally is fetched at probe time. + * + * @see pctl_names + * @see fpc1020_probe + */ +static int select_pin_ctl(struct fpc1020_data *fpc1020, const char *name) +{ + size_t i; + int rc; + struct device *dev = fpc1020->dev; + for (i = 0; i < ARRAY_SIZE(fpc1020->pinctrl_state); i++) { + const char *n = pctl_names[i]; + if (!strncmp(n, name, strlen(n))) { + rc = pinctrl_select_state(fpc1020->fingerprint_pinctrl, + fpc1020->pinctrl_state[i]); + if (rc) + dev_err(dev, "cannot select '%s'\n", name); + else + dev_dbg(dev, "Selected '%s'\n", name); + goto exit; + } + } + rc = -EINVAL; + dev_err(dev, "%s:'%s' not found\n", __func__, name); +exit: + return rc; +} + +static ssize_t pinctl_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + int rc = select_pin_ctl(fpc1020, buf); + return rc ? rc : count; +} +static DEVICE_ATTR(pinctl_set, S_IWUSR, NULL, pinctl_set); + +static int hw_reset(struct fpc1020_data *fpc1020) +{ + int irq_gpio; + struct device *dev = fpc1020->dev; + + int rc = select_pin_ctl(fpc1020, "fpc1020_reset_active"); + if (rc) + goto exit; + usleep_range(FPC1020_RESET_HIGH1_US, FPC1020_RESET_HIGH1_US + 100); + + rc = select_pin_ctl(fpc1020, "fpc1020_reset_reset"); + if (rc) + goto exit; + usleep_range(FPC1020_RESET_LOW_US, FPC1020_RESET_LOW_US + 100); + + rc = select_pin_ctl(fpc1020, "fpc1020_reset_active"); + if (rc) + goto exit; + usleep_range(FPC1020_RESET_HIGH1_US, FPC1020_RESET_HIGH1_US + 100); + + irq_gpio = gpio_get_value(fpc1020->irq_gpio); + dev_info(dev, "IRQ after reset %d\n", irq_gpio); +exit: + return rc; +} + +static ssize_t hw_reset_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int rc; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (!strncmp(buf, "reset", strlen("reset"))) + rc = hw_reset(fpc1020); + else + return -EINVAL; + return rc ? rc : count; +} +static DEVICE_ATTR(hw_reset, S_IWUSR, NULL, hw_reset_set); + +/** + * Will setup clocks, GPIOs, and regulators to correctly initialize the touch + * sensor to be ready for work. + * + * In the correct order according to the sensor spec this function will + * enable/disable regulators, SPI platform clocks, and reset line, all to set + * the sensor in a correct power on or off state "electrical" wise. + * + * @see spi_prepare_set + * @note This function will not send any commands to the sensor it will only + * control it "electrically". + */ +static int device_prepare(struct fpc1020_data *fpc1020, bool enable) +{ + int rc; + + mutex_lock(&fpc1020->lock); + if (enable && !fpc1020->prepared) { + fpc1020->prepared = true; + select_pin_ctl(fpc1020, "fpc1020_reset_reset"); + + usleep_range(PWR_ON_STEP_SLEEP, PWR_ON_STEP_RANGE2); + + (void)select_pin_ctl(fpc1020, "fpc1020_reset_active"); + usleep_range(PWR_ON_STEP_SLEEP, PWR_ON_STEP_RANGE1); + } else if (!enable && fpc1020->prepared) { + rc = 0; + + (void)select_pin_ctl(fpc1020, "fpc1020_reset_reset"); + usleep_range(PWR_ON_STEP_SLEEP, PWR_ON_STEP_RANGE2); + + fpc1020->prepared = false; + } else { + rc = 0; + } + mutex_unlock(&fpc1020->lock); + return rc; +} + +static ssize_t spi_prepare_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int rc; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (!strncmp(buf, "enable", strlen("enable"))) + rc = device_prepare(fpc1020, true); + else if (!strncmp(buf, "disable", strlen("disable"))) + rc = device_prepare(fpc1020, false); + else + return -EINVAL; + return rc ? rc : count; +} +static DEVICE_ATTR(spi_prepare, S_IWUSR, NULL, spi_prepare_set); + +/** + * sysfs node for controlling whether the driver is allowed + * to wake up the platform on interrupt. + */ +static ssize_t wakeup_enable_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (!strncmp(buf, "enable", strlen("enable"))) { + fpc1020->wakeup_enabled = true; + smp_wmb(); + } else if (!strncmp(buf, "disable", strlen("disable"))) { + fpc1020->wakeup_enabled = false; + smp_wmb(); + } else + return -EINVAL; + + return count; +} +static DEVICE_ATTR(wakeup_enable, S_IWUSR, NULL, wakeup_enable_set); + + +/** + * sysf node to check the interrupt status of the sensor, the interrupt + * handler should perform sysf_notify to allow userland to poll the node. + */ +static ssize_t irq_get(struct device *device, + struct device_attribute *attribute, + char *buffer) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(device); + int irq = gpio_get_value(fpc1020->irq_gpio); + return scnprintf(buffer, PAGE_SIZE, "%i\n", irq); +} + + +/** + * writing to the irq node will just drop a printk message + * and return success, used for latency measurement. + */ +static ssize_t irq_ack(struct device *device, + struct device_attribute *attribute, + const char *buffer, size_t count) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(device); + dev_dbg(fpc1020->dev, "%s\n", __func__); + return count; +} + +static DEVICE_ATTR(irq, S_IRUSR | S_IWUSR, irq_get, irq_ack); + +static ssize_t compatible_all_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int rc; + int i; + int irqf; + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + dev_err(dev, "compatible all enter %d\n", fpc1020->compatible_enabled); + if (!strncmp(buf, "enable", strlen("enable")) && fpc1020->compatible_enabled != 1) { + rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_irq", + &fpc1020->irq_gpio); + if (rc) + goto exit; + + rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_rst", + &fpc1020->rst_gpio); + if (rc) + goto exit; + fpc1020->fingerprint_pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(fpc1020->fingerprint_pinctrl)) { + if (PTR_ERR(fpc1020->fingerprint_pinctrl) == -EPROBE_DEFER) { + dev_info(dev, "pinctrl not ready\n"); + rc = -EPROBE_DEFER; + goto exit; + } + dev_err(dev, "Target does not use pinctrl\n"); + fpc1020->fingerprint_pinctrl = NULL; + rc = -EINVAL; + goto exit; + } + + for (i = 0; i < ARRAY_SIZE(fpc1020->pinctrl_state); i++) { + const char *n = pctl_names[i]; + struct pinctrl_state *state = + pinctrl_lookup_state(fpc1020->fingerprint_pinctrl, n); + if (IS_ERR(state)) { + dev_err(dev, "cannot find '%s'\n", n); + rc = -EINVAL; + goto exit; + } + dev_info(dev, "found pin control %s\n", n); + fpc1020->pinctrl_state[i] = state; + } + rc = select_pin_ctl(fpc1020, "fpc1020_reset_reset"); + if (rc) + goto exit; + rc = select_pin_ctl(fpc1020, "fpc1020_irq_active"); + if (rc) + goto exit; + irqf = IRQF_TRIGGER_RISING | IRQF_ONESHOT; + if (of_property_read_bool(dev->of_node, "fpc,enable-wakeup")) { + irqf |= IRQF_NO_SUSPEND; + device_init_wakeup(dev, 1); + } + rc = devm_request_threaded_irq(dev, gpio_to_irq(fpc1020->irq_gpio), + NULL, fpc1020_irq_handler, irqf, + dev_name(dev), fpc1020); + if (rc) { + dev_err(dev, "could not request irq %d\n", + gpio_to_irq(fpc1020->irq_gpio)); + goto exit; + } + dev_dbg(dev, "requested irq %d\n", gpio_to_irq(fpc1020->irq_gpio)); + + /* Request that the interrupt should be wakeable */ + enable_irq_wake(gpio_to_irq(fpc1020->irq_gpio)); + fpc1020->compatible_enabled = 1; + if (of_property_read_bool(dev->of_node, "fpc,enable-on-boot")) { + dev_info(dev, "Enabling hardware\n"); + (void)device_prepare(fpc1020, true); +#ifdef LINUX_CONTROL_SPI_CLK + (void)set_clks(fpc1020, false); +#endif + } + } else if (!strncmp(buf, "disable", strlen("disable")) && fpc1020->compatible_enabled != 0) { + if (gpio_is_valid(fpc1020->irq_gpio)) { + devm_gpio_free(dev, fpc1020->irq_gpio); + pr_info("remove irq_gpio success\n"); + } + if (gpio_is_valid(fpc1020->rst_gpio)) { + devm_gpio_free(dev, fpc1020->rst_gpio); + pr_info("remove rst_gpio success\n"); + } + devm_free_irq(dev, gpio_to_irq(fpc1020->irq_gpio), fpc1020); + fpc1020->compatible_enabled = 0; + } + hw_reset(fpc1020); + return count; +exit: + return -EINVAL; +} +static DEVICE_ATTR(compatible_all, S_IWUSR, NULL, compatible_all_set); + +static struct attribute *attributes[] = { + &dev_attr_pinctl_set.attr, + &dev_attr_spi_prepare.attr, + &dev_attr_hw_reset.attr, + &dev_attr_wakeup_enable.attr, + &dev_attr_compatible_all.attr, +#ifdef LINUX_CONTROL_SPI_CLK + &dev_attr_clk_enable.attr, +#endif + &dev_attr_irq.attr, + NULL +}; + +static const struct attribute_group attribute_group = { + .attrs = attributes, +}; + +static irqreturn_t fpc1020_irq_handler(int irq, void *handle) +{ + struct fpc1020_data *fpc1020 = handle; + dev_dbg(fpc1020->dev, "%s\n", __func__); + + /* Make sure 'wakeup_enabled' is updated before using it + ** since this is interrupt context (other thread...) */ + smp_rmb(); + + if (fpc1020->wakeup_enabled) { + wake_lock_timeout(&fpc1020->ttw_wl, + msecs_to_jiffies(FPC_TTW_HOLD_TIME)); + } + + sysfs_notify(&fpc1020->dev->kobj, NULL, dev_attr_irq.attr.name); + + return IRQ_HANDLED; +} + +static int fpc1020_request_named_gpio(struct fpc1020_data *fpc1020, + const char *label, int *gpio) +{ + struct device *dev = fpc1020->dev; + struct device_node *np = dev->of_node; + int rc = of_get_named_gpio(np, label, 0); + if (rc < 0) { + dev_err(dev, "failed to get '%s'\n", label); + return rc; + } + *gpio = rc; + rc = devm_gpio_request(dev, *gpio, label); + if (rc) { + dev_err(dev, "failed to request gpio %d\n", *gpio); + return rc; + } + dev_dbg(dev, "%s %d\n", label, *gpio); + return 0; +} + +static int fpc1020_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int rc = 0; + + struct device_node *np = dev->of_node; + + struct fpc1020_data *fpc1020 = devm_kzalloc(dev, sizeof(*fpc1020), + GFP_KERNEL); + if (!fpc1020) { + dev_err(dev, + "failed to allocate memory for struct fpc1020_data\n"); + rc = -ENOMEM; + goto exit; + } + + fpc1020->dev = dev; + dev_set_drvdata(dev, fpc1020); + + if (!np) { + dev_err(dev, "no of node found\n"); + rc = -EINVAL; + goto exit; + } + + +#ifdef LINUX_CONTROL_SPI_CLK + if (of_property_read_u32(dev->of_node, "fpc,spi-max-frequency", &fpc1020->max_speed_hz)) { + fpc1020->max_speed_hz = 4800000; + dev_err(dev, "%s: Failed to get spi-max-frequency\n", __func__); + } + + fpc1020->iface_clk = clk_get(dev, "iface_clk"); + if (IS_ERR(fpc1020->iface_clk)) { + dev_err(dev, "%s: Failed to get iface_clk\n", __func__); + rc = -EINVAL; + goto exit; + } + + fpc1020->core_clk = clk_get(dev, "core_clk"); + if (IS_ERR(fpc1020->core_clk)) { + dev_err(dev, "%s: Failed to get core_clk\n", __func__); + rc = -EINVAL; + goto exit; + } +#endif + + fpc1020->wakeup_enabled = false; +#ifdef LINUX_CONTROL_SPI_CLK + fpc1020->clocks_enabled = false; + fpc1020->clocks_suspended = false; +#endif + + mutex_init(&fpc1020->lock); + + wake_lock_init(&fpc1020->ttw_wl, WAKE_LOCK_SUSPEND, "fpc_ttw_wl"); + + rc = sysfs_create_group(&dev->kobj, &attribute_group); + if (rc) { + dev_err(dev, "could not create sysfs\n"); + goto exit; + } + + dev_info(dev, "%s: ok\n", __func__); +exit: + return rc; +} + +static int fpc1020_remove(struct platform_device *pdev) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(&pdev->dev); + + sysfs_remove_group(&pdev->dev.kobj, &attribute_group); + mutex_destroy(&fpc1020->lock); + wake_lock_destroy(&fpc1020->ttw_wl); + dev_info(&pdev->dev, "%s\n", __func__); + return 0; +} + +#ifdef LINUX_CONTROL_SPI_CLK +static int fpc1020_suspend(struct device *dev) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + fpc1020->clocks_suspended = fpc1020->clocks_enabled; + set_clks(fpc1020, false); + return 0; +} + +static int fpc1020_resume(struct device *dev) +{ + struct fpc1020_data *fpc1020 = dev_get_drvdata(dev); + + if (fpc1020->clocks_suspended) + set_clks(fpc1020, true); + + return 0; +} + +static const struct dev_pm_ops fpc1020_pm_ops = { + .suspend = fpc1020_suspend, + .resume = fpc1020_resume, +}; +#endif + +static struct of_device_id fpc1020_of_match[] = { + { .compatible = "fpc,fpc1020", }, + {} +}; +MODULE_DEVICE_TABLE(of, fpc1020_of_match); + +static struct platform_driver fpc1020_driver = { + .driver = { + .name = "fpc1020", + .owner = THIS_MODULE, + .of_match_table = fpc1020_of_match, +#ifdef LINUX_CONTROL_SPI_CLK + .pm = &fpc1020_pm_ops, +#endif + }, + .probe = fpc1020_probe, + .remove = fpc1020_remove, +}; + +static int __init fpc1020_init(void) +{ + int rc = platform_driver_register(&fpc1020_driver); + if (!rc) + pr_info("%s OK\n", __func__); + else + pr_err("%s %d\n", __func__, rc); + return rc; +} + +static void __exit fpc1020_exit(void) +{ + pr_info("%s\n", __func__); + platform_driver_unregister(&fpc1020_driver); +} + +module_init(fpc1020_init); +module_exit(fpc1020_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Aleksej Makarov"); +MODULE_AUTHOR("Henrik Tillman "); +MODULE_DESCRIPTION("FPC1020 Fingerprint sensor device driver."); diff --git a/drivers/input/fingerprint/goodix/Kconfig b/drivers/input/fingerprint/goodix/Kconfig new file mode 100644 index 000000000000..a6db85ab371b --- /dev/null +++ b/drivers/input/fingerprint/goodix/Kconfig @@ -0,0 +1,5 @@ +config FINGERPRINT_GOODIX_GF3208 + tristate "Goodix GF3208 fingerprint drvier support" + depends on INPUT_FINGERPRINT + help + Say Y here to enable goodix fingerprint driver support! diff --git a/drivers/input/fingerprint/goodix/Makefile b/drivers/input/fingerprint/goodix/Makefile new file mode 100644 index 000000000000..feb24f7d2276 --- /dev/null +++ b/drivers/input/fingerprint/goodix/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_FINGERPRINT_GOODIX_GF3208) += gf_spi.o platform.o netlink.o +#obj-y += gf_spi.o platform.o netlink.o diff --git a/drivers/input/fingerprint/goodix/gf_spi.c b/drivers/input/fingerprint/goodix/gf_spi.c new file mode 100644 index 000000000000..49e5a2a0844c --- /dev/null +++ b/drivers/input/fingerprint/goodix/gf_spi.c @@ -0,0 +1,906 @@ + /*Simple synchronous userspace interface to SPI devices + * + * Copyright (C) 2006 SWAPP + * Andrea Paterniani + * Copyright (C) 2007 David Brownell (simplification, cleanup) + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gf_spi.h" + +#if defined(USE_SPI_BUS) +#include +#include +#elif defined(USE_PLATFORM_BUS) +#include +#endif + +#define GF_SPIDEV_NAME "goodix,fingerprint" +/*device name after register in charater*/ +#define GF_DEV_NAME "goodix_fp" +#define GF_INPUT_NAME "gf3208" /*"goodix_fp" */ + +#define CHRD_DRIVER_NAME "goodix_fp_spi" +#define CLASS_NAME "goodix_fp" +#define SPIDEV_MAJOR 225 /* assigned */ +#define N_SPI_MINORS 32 /* ... up to 256 */ + + +struct gf_key_map key_map[] = { + { "POWER", KEY_POWER }, + { "HOME" , KEY_HOME }, + { "MENU" , KEY_MENU }, + { "BACK" , KEY_BACK }, + { "UP" , KEY_UP }, + { "DOWN" , KEY_DOWN }, + { "LEFT" , KEY_LEFT }, + { "RIGHT", KEY_RIGHT }, + { "FORCE", KEY_F9 }, + { "CLICK", KEY_F19 }, + { "CAMERA", KEY_CAMERA }, +}; + +/**************************debug******************************/ +#define GF_DEBUG +/*#undef GF_DEBUG*/ + +#ifdef GF_DEBUG +#define gf_dbg(fmt, args...) do { \ + pr_warn("gf:" fmt, ##args);\ + } while (0) +#define FUNC_ENTRY() pr_warn("gf:%s, entry\n", __func__) +#define FUNC_EXIT() pr_warn("gf:%s, exit\n", __func__) +#else +#define gf_dbg(fmt, args...) +#define FUNC_ENTRY() +#define FUNC_EXIT() +#endif + +/*Global variables*/ +/*static MODE g_mode = GF_IMAGE_MODE;*/ +static DECLARE_BITMAP(minors, N_SPI_MINORS); +static LIST_HEAD(device_list); +static DEFINE_MUTEX(device_list_lock); +static struct gf_dev gf; +static struct class *gf_class; +static int driver_init_partial(struct gf_dev *gf_dev); + +static void gf_enable_irq(struct gf_dev *gf_dev) +{ + if (gf_dev->irq_enabled) { + pr_warn("IRQ has been enabled.\n"); + } else { + enable_irq(gf_dev->irq); + gf_dev->irq_enabled = 1; + } +} + +static void gf_disable_irq(struct gf_dev *gf_dev) +{ + if (gf_dev->irq_enabled) { + gf_dev->irq_enabled = 0; + disable_irq(gf_dev->irq); + } else { + pr_warn("IRQ has been disabled.\n"); + } +} + +#ifdef AP_CONTROL_CLK +static long spi_clk_max_rate(struct clk *clk, unsigned long rate) +{ + long lowest_available, nearest_low, step_size, cur; + long step_direction = -1; + long guess = rate; + int max_steps = 10; + + cur = clk_round_rate(clk, rate); + if (cur == rate) + return rate; + + /* if we got here then: cur > rate */ + lowest_available = clk_round_rate(clk, 0); + if (lowest_available > rate) + return -EINVAL; + + step_size = (rate - lowest_available) >> 1; + nearest_low = lowest_available; + + while (max_steps-- && step_size) { + guess += step_size * step_direction; + cur = clk_round_rate(clk, guess); + + if ((cur < rate) && (cur > nearest_low)) + nearest_low = cur; + /* + * if we stepped too far, then start stepping in the other + * direction with half the step size + */ + if (((cur > rate) && (step_direction > 0)) + || ((cur < rate) && (step_direction < 0))) { + step_direction = -step_direction; + step_size >>= 1; + } + } + return nearest_low; +} + +static void spi_clock_set(struct gf_dev *gf_dev, int speed) +{ + long rate; + int rc; + + rate = spi_clk_max_rate(gf_dev->core_clk, speed); + if (rate < 0) { + pr_info("%s: no match found for requested clock frequency:%d", + __func__, speed); + return; + } + + rc = clk_set_rate(gf_dev->core_clk, rate); +} + +static int gfspi_ioctl_clk_init(struct gf_dev *data) +{ + pr_debug("%s: enter\n", __func__); + + data->clk_enabled = 0; + data->core_clk = clk_get(&data->spi->dev, "core_clk"); + if (IS_ERR_OR_NULL(data->core_clk)) { + pr_err("%s: fail to get core_clk\n", __func__); + return -EPERM; + } + data->iface_clk = clk_get(&data->spi->dev, "iface_clk"); + if (IS_ERR_OR_NULL(data->iface_clk)) { + pr_err("%s: fail to get iface_clk\n", __func__); + clk_put(data->core_clk); + data->core_clk = NULL; + return -ENOENT; + } + return 0; +} + +static int gfspi_ioctl_clk_enable(struct gf_dev *data) +{ + int err; + + pr_debug("%s: enter\n", __func__); + + if (data->clk_enabled) + return 0; + + err = clk_prepare_enable(data->core_clk); + if (err) { + pr_err("%s: fail to enable core_clk\n", __func__); + return -EPERM; + } + + err = clk_prepare_enable(data->iface_clk); + if (err) { + pr_err("%s: fail to enable iface_clk\n", __func__); + clk_disable_unprepare(data->core_clk); + return -ENOENT; + } + + data->clk_enabled = 1; + + return 0; +} + +static int gfspi_ioctl_clk_disable(struct gf_dev *data) +{ + pr_debug("%s: enter\n", __func__); + + if (!data->clk_enabled) + return 0; + + clk_disable_unprepare(data->core_clk); + clk_disable_unprepare(data->iface_clk); + data->clk_enabled = 0; + + return 0; +} + +static int gfspi_ioctl_clk_uninit(struct gf_dev *data) +{ + pr_debug("%s: enter\n", __func__); + + if (data->clk_enabled) + gfspi_ioctl_clk_disable(data); + + if (!IS_ERR_OR_NULL(data->core_clk)) { + clk_put(data->core_clk); + data->core_clk = NULL; + } + + if (!IS_ERR_OR_NULL(data->iface_clk)) { + clk_put(data->iface_clk); + data->iface_clk = NULL; + } + + return 0; +} +#endif + +static long gf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct gf_dev *gf_dev = &gf; + struct gf_key gf_key = { 0 }; + int retval = 0; + int i; +#ifdef AP_CONTROL_CLK + unsigned int speed = 0; +#endif + FUNC_ENTRY(); + if (_IOC_TYPE(cmd) != GF_IOC_MAGIC) + return -ENODEV; + + if (_IOC_DIR(cmd) & _IOC_READ) + retval = + !access_ok(VERIFY_WRITE, (void __user *)arg, + _IOC_SIZE(cmd)); + if ((retval == 0) && (_IOC_DIR(cmd) & _IOC_WRITE)) + retval = + !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (retval) + return -EFAULT; + + if (gf_dev->device_available == 0) { + if ((cmd == GF_IOC_POWER_ON) || (cmd == GF_IOC_POWER_OFF) || (cmd == GF_IOC_ENABLE_GPIO)) + pr_info("power cmd\n"); + else { + pr_info("Sensor is power off currently. \n"); + return -ENODEV; + } + } + + switch (cmd) { + case GF_IOC_ENABLE_GPIO: + driver_init_partial(gf_dev); + break; + case GF_IOC_RELEASE_GPIO: + gf_cleanup(gf_dev); + break; + case GF_IOC_DISABLE_IRQ: + gf_disable_irq(gf_dev); + break; + case GF_IOC_ENABLE_IRQ: + gf_enable_irq(gf_dev); + break; + case GF_IOC_SETSPEED: +#ifdef AP_CONTROL_CLK + retval = __get_user(speed, (u32 __user *) arg); + if (retval == 0) { + if (speed > 8 * 1000 * 1000) { + pr_warn("Set speed:%d is larger than 8Mbps.\n", speed); + } else { + spi_clock_set(gf_dev, speed); + } + } else { + pr_warn("Failed to get speed from user. retval = %d\n", retval); + } +#else + pr_info("This kernel doesn't support control clk in AP\n"); +#endif + break; + case GF_IOC_RESET: + gf_hw_reset(gf_dev, 3); + break; + case GF_IOC_COOLBOOT: + gf_power_off(gf_dev); + mdelay(5); + gf_power_on(gf_dev); + break; + case GF_IOC_SENDKEY: + if (copy_from_user + (&gf_key, (struct gf_key *)arg, sizeof(struct gf_key))) { + pr_warn("Failed to copy data from user space.\n"); + retval = -EFAULT; + break; + } + + for (i = 0; i < ARRAY_SIZE(key_map); i++) { + if (key_map[i].val == gf_key.key) { + if (KEY_CAMERA == gf_key.key) { + printk("lihao send camera key!\n"); + input_report_key(gf_dev->input, KEY_SELECT, gf_key.value); + input_sync(gf_dev->input); + } else { + input_report_key(gf_dev->input, gf_key.key, gf_key.value); + input_sync(gf_dev->input); + } + break; + } + } + + if (i == ARRAY_SIZE(key_map)) { + pr_warn("key %d not support yet \n", gf_key.key); + retval = -EFAULT; + } + + break; + case GF_IOC_CLK_READY: +#ifdef AP_CONTROL_CLK + gfspi_ioctl_clk_enable(gf_dev); +#else + pr_info("Doesn't support control clock.\n"); +#endif + break; + case GF_IOC_CLK_UNREADY: +#ifdef AP_CONTROL_CLK + gfspi_ioctl_clk_disable(gf_dev); +#else + pr_info("Doesn't support control clock.\n"); +#endif + break; + case GF_IOC_PM_FBCABCK: + __put_user(gf_dev->fb_black, (u8 __user *) arg); + break; + case GF_IOC_POWER_ON: + if (gf_dev->device_available == 1) + pr_info("Sensor has already powered-on.\n"); + else + gf_power_on(gf_dev); + gf_dev->device_available = 1; + break; + case GF_IOC_POWER_OFF: + if (gf_dev->device_available == 0) + pr_info("Sensor has already powered-off.\n"); + else + gf_power_off(gf_dev); + gf_dev->device_available = 0; + break; + default: + gf_dbg("Unsupport cmd:0x%x\n", cmd); + break; + } + + FUNC_EXIT(); + return retval; +} + +#ifdef CONFIG_COMPAT +static long +gf_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + return gf_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); +} +#endif /*CONFIG_COMPAT*/ + +static irqreturn_t gf_irq(int irq, void *handle) +{ + +#if defined(GF_NETLINK_ENABLE) + + struct gf_dev *gf_dev = &gf; + char temp = GF_NET_EVENT_IRQ; + gf_dbg("enter irq %s\n", __func__); + + wake_lock_timeout(&gf_dev->ttw_wl, msecs_to_jiffies(1000)); + + sendnlmsg(&temp); +#elif defined (GF_FASYNC) + + struct gf_dev *gf_dev = &gf; + if (gf_dev->async) + kill_fasync(&gf_dev->async, SIGIO, POLL_IN); +#endif + + return IRQ_HANDLED; + +} + +static int driver_init_partial(struct gf_dev *gf_dev) +{ + int ret = 0; + FUNC_ENTRY(); + pr_warn("--------driver_init_partial start.--------\n"); + + gf_dev->device_available = 1; + + if (gf_parse_dts(gf_dev)) + goto error; + + gf_dev->irq = gf_irq_num(gf_dev); + ret = devm_request_threaded_irq(&gf_dev->spi->dev, + gf_dev->irq, + NULL, + gf_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "gf", gf_dev); + if (ret) { + pr_err("Could not request irq %d\n", gpio_to_irq(gf_dev->irq_gpio)); + goto error; + } + if (!ret) { + enable_irq_wake(gf_dev->irq); + gf_enable_irq(gf_dev); + gf_disable_irq(gf_dev); + } + gf_hw_reset(gf_dev, 360); + + FUNC_EXIT(); + return 0; + +error: + + gf_cleanup(gf_dev); + + gf_dev->device_available = 0; + + return -EPERM; + + +} +static int gf_open(struct inode *inode, struct file *filp) +{ + struct gf_dev *gf_dev; + int status = -ENXIO; + + FUNC_ENTRY(); + mutex_lock(&device_list_lock); + + list_for_each_entry(gf_dev, &device_list, device_entry) { + if (gf_dev->devt == inode->i_rdev) { + gf_dbg("Found\n"); + status = 0; + break; + } + } + + if (status == 0) { + if (status == 0) { + gf_dev->users++; + filp->private_data = gf_dev; + nonseekable_open(inode, filp); + gf_dbg("Succeed to open device. irq = %d\n", + gf_dev->irq); + /*power the sensor*/ + gf_dev->device_available = 1; + } + } else { + gf_dbg("No device for minor %d\n", iminor(inode)); + } + mutex_unlock(&device_list_lock); + FUNC_EXIT(); + return status; +} + +#ifdef GF_FASYNC +static int gf_fasync(int fd, struct file *filp, int mode) +{ + struct gf_dev *gf_dev = filp->private_data; + int ret; + + FUNC_ENTRY(); + ret = fasync_helper(fd, filp, mode, &gf_dev->async); + FUNC_EXIT(); + gf_dbg("ret = %d\n", ret); + return ret; +} +#endif + +static int gf_release(struct inode *inode, struct file *filp) +{ + struct gf_dev *gf_dev; + int status = 0; + + FUNC_ENTRY(); + mutex_lock(&device_list_lock); + gf_dev = filp->private_data; + filp->private_data = NULL; + + gf_dev->users--; + if (!gf_dev->users) { + + gf_dbg("disble_irq. irq = %d\n", gf_dev->irq); + gf_disable_irq(gf_dev); + + + devm_free_irq(&gf_dev->spi->dev, gf_dev->irq, gf_dev); + + + + /*power off the sensor*/ + gf_dev->device_available = 0; + gf_power_off(gf_dev); + } + mutex_unlock(&device_list_lock); + FUNC_EXIT(); + + return status; +} + +static const struct file_operations gf_fops = { + .owner = THIS_MODULE, + /* REVISIT switch to aio primitives, so that userspace + * gets more complete API coverage. It'll simplify things + * too, except for the locking. + */ + .unlocked_ioctl = gf_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gf_compat_ioctl, +#endif /*CONFIG_COMPAT*/ + .open = gf_open, + .release = gf_release, +#ifdef GF_FASYNC + .fasync = gf_fasync, +#endif +}; + +static int goodix_fb_state_chg_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct gf_dev *gf_dev; + struct fb_event *evdata = data; + unsigned int blank; + +#if defined(GF_NETLINK_ENABLE) + char temp = 0; +#endif + + if (val != FB_EARLY_EVENT_BLANK) + return 0; + pr_info("[info] %s go to the goodix_fb_state_chg_callback value = %d\n", + __func__, (int)val); + gf_dev = container_of(nb, struct gf_dev, notifier); + if (evdata && evdata->data && val == FB_EARLY_EVENT_BLANK && gf_dev) { + blank = *(int *)(evdata->data); + switch (blank) { + case FB_BLANK_POWERDOWN: + if (gf_dev->device_available == 1) { + gf_dev->fb_black = 1; +#if defined(GF_NETLINK_ENABLE) + temp = GF_NET_EVENT_FB_BLACK; + sendnlmsg(&temp); +#elif defined (GF_FASYNC) + if (gf_dev->async) { + kill_fasync(&gf_dev->async, SIGIO, + POLL_IN); + } +#endif + /*device unavailable */ + + } + break; + case FB_BLANK_UNBLANK: + if (gf_dev->device_available == 1) { + gf_dev->fb_black = 0; +#if defined(GF_NETLINK_ENABLE) + temp = GF_NET_EVENT_FB_UNBLACK; + sendnlmsg(&temp); +#elif defined (GF_FASYNC) + if (gf_dev->async) { + kill_fasync(&gf_dev->async, SIGIO, + POLL_IN); + } +#endif + /*device available */ + + } + break; + default: + pr_info("%s defalut\n", __func__); + break; + } + } + return NOTIFY_OK; +} + +static struct notifier_block goodix_noti_block = { + .notifier_call = goodix_fb_state_chg_callback, +}; + +static void gf_reg_key_kernel(struct gf_dev *gf_dev) +{ + int i; + + set_bit(EV_KEY, gf_dev->input->evbit); + for (i = 0; i < ARRAY_SIZE(key_map); i++) { + set_bit(key_map[i].val, gf_dev->input->keybit); + } + set_bit(KEY_SELECT, gf_dev->input->keybit); + gf_dev->input->name = GF_INPUT_NAME; + if (input_register_device(gf_dev->input)) + pr_warn("Failed to register GF as input device.\n"); +} + + +#if defined(USE_SPI_BUS) +static int gf_probe(struct spi_device *spi) +#elif defined(USE_PLATFORM_BUS) +static int gf_probe(struct platform_device *pdev) +#endif +{ + struct gf_dev *gf_dev = &gf; + int status = -EINVAL; + unsigned long minor; + + FUNC_ENTRY(); + + pr_warn("--------gf_probe start.--------\n"); + /* Initialize the driver data */ + INIT_LIST_HEAD(&gf_dev->device_entry); + +#if defined(USE_SPI_BUS) + gf_dev->spi = spi; +#elif defined(USE_PLATFORM_BUS) + gf_dev->spi = pdev; +#endif + + gf_dev->irq_gpio = -EINVAL; + gf_dev->reset_gpio = -EINVAL; + gf_dev->pwr_gpio = -EINVAL; + gf_dev->device_available = 0; + gf_dev->fb_black = 0; + gf_dev->irq_enabled = 0; + gf_dev->fingerprint_pinctrl = NULL; + + /* If we can allocate a minor number, hook up this device. + * Reusing minors is fine so long as udev or mdev is working. + */ + mutex_lock(&device_list_lock); + minor = find_first_zero_bit(minors, N_SPI_MINORS); + if (minor < N_SPI_MINORS) { + struct device *dev; + + gf_dev->devt = MKDEV(SPIDEV_MAJOR, minor); + dev = device_create(gf_class, &gf_dev->spi->dev, gf_dev->devt, + gf_dev, GF_DEV_NAME); + status = IS_ERR(dev) ? PTR_ERR(dev) : 0; + } else { + dev_dbg(&gf_dev->spi->dev, "no minor number available!\n"); + status = -ENODEV; + } + + if (status == 0) { + set_bit(minor, minors); + list_add(&gf_dev->device_entry, &device_list); + } else { + gf_dev->devt = 0; + } + mutex_unlock(&device_list_lock); + + if (status == 0) { + /*input device subsystem */ + gf_dev->input = input_allocate_device(); + if (gf_dev->input == NULL) { + dev_dbg(&gf_dev->input->dev, + "Faile to allocate input device.\n"); + status = -ENOMEM; + goto error; + } +#ifdef AP_CONTROL_CLK + pr_info("Get the clk resource.\n"); + /* Enable spi clock */ + if (gfspi_ioctl_clk_init(gf_dev)) + goto gfspi_probe_clk_init_failed; + + + if (gfspi_ioctl_clk_enable(gf_dev)) + goto gfspi_probe_clk_enable_failed; + + spi_clock_set(gf_dev, 4.8*1000*1000); +#endif + + gf_dev->notifier = goodix_noti_block; + fb_register_client(&gf_dev->notifier); + gf_reg_key_kernel(gf_dev); + + wake_lock_init(&gf_dev->ttw_wl, WAKE_LOCK_SUSPEND, "goodix_ttw_wl"); + } + + pr_warn("--------gf_probe end---OK.--------\n"); + return status; + +error: + gf_cleanup(gf_dev); + gf_dev->device_available = 0; + if (gf_dev->devt != 0) { + pr_info("Err: status = %d\n", status); + mutex_lock(&device_list_lock); + list_del(&gf_dev->device_entry); + device_destroy(gf_class, gf_dev->devt); + clear_bit(MINOR(gf_dev->devt), minors); + mutex_unlock(&device_list_lock); + +#ifdef AP_CONTROL_CLK +gfspi_probe_clk_enable_failed: + gfspi_ioctl_clk_uninit(gf_dev); +gfspi_probe_clk_init_failed: +#endif + if (gf_dev->input != NULL) + input_unregister_device(gf_dev->input); + } + + FUNC_EXIT(); + return status; +} + +#if defined(USE_SPI_BUS) +static int gf_remove(struct spi_device *spi) +#elif defined(USE_PLATFORM_BUS) +static int gf_remove(struct platform_device *pdev) +#endif +{ + struct gf_dev *gf_dev = &gf; + FUNC_ENTRY(); + + /* make sure ops on existing fds can abort cleanly */ + if (gf_dev->irq) + free_irq(gf_dev->irq, gf_dev); + + if (gf_dev->input != NULL) + input_unregister_device(gf_dev->input); + input_free_device(gf_dev->input); + + /* prevent new opens */ + mutex_lock(&device_list_lock); + list_del(&gf_dev->device_entry); + device_destroy(gf_class, gf_dev->devt); + clear_bit(MINOR(gf_dev->devt), minors); + if (gf_dev->users == 0) + kfree(gf_dev); + + mutex_unlock(&device_list_lock); + + wake_lock_destroy(&gf_dev->ttw_wl); + + FUNC_EXIT(); + return 0; +} + +#if defined(USE_SPI_BUS) +static int gf_suspend(struct spi_device *spi, pm_message_t mesg) +#elif defined(USE_PLATFORM_BUS) +static int gf_suspend(struct platform_device *pdev, pm_message_t state) +#endif +{ + + gf_dbg("gf_suspend_test.\n"); + return 0; +} + +#if defined(USE_SPI_BUS) +static int gf_resume(struct spi_device *spi) +#elif defined(USE_PLATFORM_BUS) +static int gf_resume(struct platform_device *pdev) +#endif +{ + gf_dbg("gf_resume_test.\n"); + return 0; +} + +static struct of_device_id gx_match_table[] = { + {.compatible = GF_SPIDEV_NAME,}, + {}, +}; + +#if defined(USE_SPI_BUS) +static struct spi_driver gf_driver = { +#elif defined(USE_PLATFORM_BUS) +static struct platform_driver gf_driver = { +#endif + .driver = { + .name = GF_DEV_NAME, + .owner = THIS_MODULE, +#if defined(USE_SPI_BUS) + +#endif + .of_match_table = gx_match_table, + }, + .probe = gf_probe, + .remove = gf_remove, + .suspend = gf_suspend, + .resume = gf_resume, +}; + +static int __init gf_init(void) +{ + int status; + FUNC_ENTRY(); + + pr_warn("--------gf_init start.--------\n"); + /* Claim our 256 reserved device numbers. Then register a class + * that will key udev/mdev to add/remove /dev nodes. Last, register + * the driver which manages those device numbers. + */ + + BUILD_BUG_ON(N_SPI_MINORS > 256); + status = register_chrdev(SPIDEV_MAJOR, CHRD_DRIVER_NAME, &gf_fops); + if (status < 0) { + pr_warn("Failed to register char device!\n"); + FUNC_EXIT(); + return status; + } + gf_class = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(gf_class)) { + unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name); + pr_warn("Failed to create class.\n"); + FUNC_EXIT(); + return PTR_ERR(gf_class); + } +#if defined(USE_PLATFORM_BUS) + status = platform_driver_register(&gf_driver); +#elif defined(USE_SPI_BUS) + status = spi_register_driver(&gf_driver); +#endif + if (status < 0) { + class_destroy(gf_class); + unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name); + pr_warn("Failed to register SPI driver.\n"); + } + +#ifdef GF_NETLINK_ENABLE + netlink_init(); +#endif + pr_info(" status = 0x%x\n", status); + FUNC_EXIT(); + + pr_warn("--------gf_init end---OK.--------\n"); + return 0; +} + +module_init(gf_init); + +static void __exit gf_exit(void) +{ + FUNC_ENTRY(); +#ifdef GF_NETLINK_ENABLE + netlink_exit(); +#endif +#if defined(USE_PLATFORM_BUS) + platform_driver_unregister(&gf_driver); +#elif defined(USE_SPI_BUS) + spi_unregister_driver(&gf_driver); +#endif + class_destroy(gf_class); + unregister_chrdev(SPIDEV_MAJOR, gf_driver.driver.name); + FUNC_EXIT(); +} + +module_exit(gf_exit); + +MODULE_AUTHOR("Jiangtao Yi, "); +MODULE_DESCRIPTION("User mode SPI device interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:gf-spi"); diff --git a/drivers/input/fingerprint/goodix/gf_spi.h b/drivers/input/fingerprint/goodix/gf_spi.h new file mode 100644 index 000000000000..577e88444b64 --- /dev/null +++ b/drivers/input/fingerprint/goodix/gf_spi.h @@ -0,0 +1,106 @@ +#ifndef __GF_SPI_H +#define __GF_SPI_H + +#include +#include +#include +/**********************************************************/ +enum FP_MODE{ + GF_IMAGE_MODE = 0, + GF_KEY_MODE, + GF_SLEEP_MODE, + GF_FF_MODE, + GF_DEBUG_MODE = 0x56 +}; + +struct gf_key { + unsigned int key; + int value; +}; + + +struct gf_key_map { + char *name; + unsigned short val; +}; + +#define GF_IOC_MAGIC 'G' +#define GF_IOC_DISABLE_IRQ _IO(GF_IOC_MAGIC, 0) +#define GF_IOC_ENABLE_IRQ _IO(GF_IOC_MAGIC, 1) +#define GF_IOC_SETSPEED _IOW(GF_IOC_MAGIC, 2, unsigned int) +#define GF_IOC_RESET _IO(GF_IOC_MAGIC, 3) +#define GF_IOC_COOLBOOT _IO(GF_IOC_MAGIC, 4) +#define GF_IOC_SENDKEY _IOW(GF_IOC_MAGIC, 5, struct gf_key) +#define GF_IOC_CLK_READY _IO(GF_IOC_MAGIC, 6) +#define GF_IOC_CLK_UNREADY _IO(GF_IOC_MAGIC, 7) +#define GF_IOC_PM_FBCABCK _IO(GF_IOC_MAGIC, 8) +#define GF_IOC_POWER_ON _IO(GF_IOC_MAGIC, 9) +#define GF_IOC_POWER_OFF _IO(GF_IOC_MAGIC, 10) +#define GF_IOC_ENABLE_GPIO _IO(GF_IOC_MAGIC, 11) +#define GF_IOC_RELEASE_GPIO _IO(GF_IOC_MAGIC, 12) + +#define GF_IOC_MAXNR 13 + + +#define USE_PLATFORM_BUS 1 + + +#define GF_NETLINK_ENABLE 1 +#define GF_NET_EVENT_IRQ 0 +#define GF_NET_EVENT_FB_BLACK 1 +#define GF_NET_EVENT_FB_UNBLACK 2 + + +static const char * const pctl_names[] = { + + "goodixfp_reset_reset", + "goodixfp_reset_active", + "goodixfp_irq_active", +}; + + +struct gf_dev { + dev_t devt; + struct list_head device_entry; +#if defined(USE_SPI_BUS) + struct spi_device *spi; +#elif defined(USE_PLATFORM_BUS) + struct platform_device *spi; +#endif + struct clk *core_clk; + struct clk *iface_clk; + + struct pinctrl *fingerprint_pinctrl; + struct pinctrl_state *pinctrl_state[ARRAY_SIZE(pctl_names)]; + + struct input_dev *input; + /* buffer is NULL unless this device is open (users > 0) */ + unsigned users; + signed irq_gpio; + signed reset_gpio; + signed pwr_gpio; + int irq; + int irq_enabled; + int clk_enabled; +#ifdef GF_FASYNC + struct fasync_struct *async; +#endif + struct notifier_block notifier; + char device_available; + char fb_black; + struct wake_lock ttw_wl; +}; + +int gf_parse_dts(struct gf_dev *gf_dev); +void gf_cleanup(struct gf_dev *gf_dev); + +int gf_power_on(struct gf_dev *gf_dev); +int gf_power_off(struct gf_dev *gf_dev); + +int gf_hw_reset(struct gf_dev *gf_dev, unsigned int delay_ms); +int gf_irq_num(struct gf_dev *gf_dev); + +void sendnlmsg(char *message); +int netlink_init(void); +void netlink_exit(void); +#endif /*__GF_SPI_H*/ diff --git a/drivers/input/fingerprint/goodix/netlink.c b/drivers/input/fingerprint/goodix/netlink.c new file mode 100644 index 000000000000..24b03024c5b9 --- /dev/null +++ b/drivers/input/fingerprint/goodix/netlink.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include + +#define NETLINK_TEST 25 +#define MAX_MSGSIZE 4 * 1024 +int stringlength(char *s); +void sendnlmsg(char *message); +int pid; +int err; +struct sock *nl_sk = NULL; +int flag = 0; + +struct gf_uk_channel { + int channel_id; + int reserved; + char buf[3*1024]; + int len; +}; + +void sendnlmsg(char *message) +{ + struct sk_buff *skb_1; + struct nlmsghdr *nlh; + int len = NLMSG_SPACE(MAX_MSGSIZE); + int slen = 0; + if (!message || !nl_sk) + return ; + skb_1 = alloc_skb(len, GFP_KERNEL); + if (!skb_1) + printk(KERN_ERR "my_net_link:alloc_skb_1 error\n"); + slen = strlen(message); + nlh = nlmsg_put(skb_1, 0, 0, 0, MAX_MSGSIZE, 0); + + NETLINK_CB(skb_1).portid = 0; + NETLINK_CB(skb_1).dst_group = 0; + + message[slen] = '\0'; + memcpy(NLMSG_DATA(nlh), message, slen+1); + + netlink_unicast(nl_sk, skb_1, pid, MSG_DONTWAIT); +} + +void nl_data_ready(struct sk_buff *__skb) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + char str[100]; + skb = skb_get (__skb); + if (skb->len >= NLMSG_SPACE(0)) { + nlh = nlmsg_hdr(skb); + memcpy(str, NLMSG_DATA(nlh), sizeof(str)); + pid = nlh->nlmsg_pid; + kfree_skb(skb); + } +} + +int netlink_init(void) +{ + struct netlink_kernel_cfg netlink_cfg; + netlink_cfg.groups = 0; + netlink_cfg.flags = 0; + netlink_cfg.input = nl_data_ready; + netlink_cfg.cb_mutex = NULL; + + nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &netlink_cfg); + + if (!nl_sk) { + printk(KERN_ERR "my_net_link: create netlink socket error.\n"); + return 1; + } + + return 0; +} + +void netlink_exit(void) +{ + if (nl_sk != NULL) { + sock_release(nl_sk->sk_socket); + } + + printk("my_net_link: self module exited\n"); +} diff --git a/drivers/input/fingerprint/goodix/platform.c b/drivers/input/fingerprint/goodix/platform.c new file mode 100644 index 000000000000..a5b39e4eaac9 --- /dev/null +++ b/drivers/input/fingerprint/goodix/platform.c @@ -0,0 +1,202 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gf_spi.h" + +#if defined(USE_SPI_BUS) +#include +#include +#elif defined(USE_PLATFORM_BUS) +#include +#endif + +#define gf_dbg(fmt, args...) do { \ + pr_warn("gf:" fmt, ##args);\ + } while (0) + + +static int gf3208_request_named_gpio(struct gf_dev *gf_dev, const char *label, int *gpio) +{ + struct device *dev = &gf_dev->spi->dev; + struct device_node *np = dev->of_node; + int rc = of_get_named_gpio(np, label, 0); + if (rc < 0) { + dev_err(dev, "failed to get '%s'\n", label); + return rc; + } + *gpio = rc; + rc = devm_gpio_request(dev, *gpio, label); + if (rc) { + dev_err(dev, "failed to request gpio %d\n", *gpio); + return rc; + } + dev_err(dev, "%s %d\n", label, *gpio); + return 0; +} + +static int select_pin_ctl(struct gf_dev *gf_dev, const char *name) +{ + size_t i; + int rc; + struct device *dev = &gf_dev->spi->dev; + + for (i = 0; i < ARRAY_SIZE(gf_dev->pinctrl_state); i++) { + const char *n = pctl_names[i]; + if (!strncmp(n, name, strlen(n))) { + rc = pinctrl_select_state(gf_dev->fingerprint_pinctrl, gf_dev->pinctrl_state[i]); + + if (rc) + dev_err(dev, "cannot select '%s'\n", name); + else + dev_err(dev, "Selected '%s'\n", name); + goto exit; + } + } + rc = -EINVAL; + dev_err(dev, "%s:'%s' not found\n", __func__, name); +exit: + return rc; +} + + +/*GPIO pins reference.*/ +int gf_parse_dts(struct gf_dev *gf_dev) +{ + int rc = 0; + int i = 0; + pr_warn("--------gf_parse_dts start.--------\n"); + + /*get reset resource*/ + rc = gf3208_request_named_gpio(gf_dev, "goodix,gpio_reset", &gf_dev->reset_gpio); + if (rc) { + gf_dbg("Failed to request RESET GPIO. rc = %d\n", rc); + return -EPERM; + } + + /*get irq resourece*/ + rc = gf3208_request_named_gpio(gf_dev, "goodix,gpio_irq", &gf_dev->irq_gpio); + if (rc) { + + gf_dbg("Failed to request IRQ GPIO. rc = %d\n", rc); + return -EPERM; + } + + + gf_dev->fingerprint_pinctrl = devm_pinctrl_get(&gf_dev->spi->dev); + for (i = 0; i < ARRAY_SIZE(gf_dev->pinctrl_state); i++) { + const char *n = pctl_names[i]; + struct pinctrl_state *state = + pinctrl_lookup_state(gf_dev->fingerprint_pinctrl, n); + if (IS_ERR(state)) { + pr_err("cannot find '%s'\n", n); + rc = -EINVAL; + } + pr_info("found pin control %s\n", n); + gf_dev->pinctrl_state[i] = state; + } + + rc = select_pin_ctl(gf_dev, "goodixfp_reset_active"); + if (rc) + goto exit; + rc = select_pin_ctl(gf_dev, "goodixfp_irq_active"); + if (rc) + goto exit; + + pr_warn("--------gf_parse_dts end---OK.--------\n"); + +exit: + return rc; + +} + +void gf_cleanup(struct gf_dev *gf_dev) +{ + gf_dbg("[info] enter%s\n", __func__); + + if (gpio_is_valid(gf_dev->irq_gpio)) { + devm_gpio_free(&gf_dev->spi->dev, gf_dev->irq_gpio); + gf_dbg("remove irq_gpio success\n"); + } + + if (gpio_is_valid(gf_dev->reset_gpio)) { + + devm_gpio_free(&gf_dev->spi->dev, gf_dev->reset_gpio); + gf_dbg("remove reset_gpio success\n"); + } + + if (gf_dev->fingerprint_pinctrl != NULL) { + devm_pinctrl_put(gf_dev->fingerprint_pinctrl); + gf_dev->fingerprint_pinctrl = NULL; + + gf_dbg("gx fingerprint_pinctrl release success\n"); + } +} + +/*power management*/ +int gf_power_on(struct gf_dev *gf_dev) +{ + int rc = 0; + msleep(10); + pr_info("---- power on ok ----\n"); + + return rc; +} + +int gf_power_off(struct gf_dev *gf_dev) +{ + int rc = 0; + pr_info("---- power off ----\n"); + return rc; +} + +static int hw_reset(struct gf_dev *gf_dev) +{ + int irq_gpio; + struct device *dev = &gf_dev->spi->dev; + + int rc = select_pin_ctl(gf_dev, "goodixfp_reset_reset"); + if (rc) + goto exit; + mdelay(3); + + rc = select_pin_ctl(gf_dev, "goodixfp_reset_active"); + if (rc) + goto exit; + + irq_gpio = gpio_get_value(gf_dev->irq_gpio); + dev_info(dev, "IRQ after reset %d\n", irq_gpio); +exit: + return rc; +} + + +/******************************************************************** + *CPU output low level in RST pin to reset GF. This is the MUST action for GF. + *Take care of this function. IO Pin driver strength / glitch and so on. + ********************************************************************/ +int gf_hw_reset(struct gf_dev *gf_dev, unsigned int delay_ms) +{ + if (gf_dev == NULL) { + pr_info("Input buff is NULL.\n"); + return -EPERM; + } + hw_reset(gf_dev); + mdelay(delay_ms); + return 0; +} + +int gf_irq_num(struct gf_dev *gf_dev) +{ + if (gf_dev == NULL) { + pr_info("Input buff is NULL.\n"); + return -EPERM; + } else { + return gpio_to_irq(gf_dev->irq_gpio); + } +} + From 5e6ab4f742d74dba9ed54cd534c840d9d905ab3a Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 19 May 2017 13:09:25 +0800 Subject: [PATCH 45/86] drivers: leds: leds-aw2013: Fix dtsi driver loading Change-Id: I2973678c623e48b9dd316d444e0448501575eca4 --- arch/arm/boot/dts/qcom/msm8953-qrd.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi index 62347ec23fe3..35fcd50b1527 100644 --- a/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi @@ -177,7 +177,7 @@ i2c@78b6000 { /* BLSP1 QUP3 */ aw2013@45 { - compatible = "awinic"; + compatible = "awinic,aw2013"; reg = <0x45>; vdd-supply = <&pm8953_l10>; vcc-supply = <&pm8953_l5>; From f2fcecc7702269daebfaeb99897debb8e5eea9a7 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 08:00:32 +0000 Subject: [PATCH 46/86] drivers: power: Import power changes Change-Id: Ie76fd74b3e25ffcb044531f46646b6ca9714e994 --- drivers/of/of_batterydata.c | 16 +++++++++--- drivers/power/qpnp-fg.c | 12 +++------ drivers/power/qpnp-smbcharger.c | 44 ++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/drivers/of/of_batterydata.c b/drivers/of/of_batterydata.c index 4fddbdefce5b..ff84ab833e0f 100644 --- a/drivers/of/of_batterydata.c +++ b/drivers/of/of_batterydata.c @@ -1,4 +1,5 @@ /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -316,13 +317,14 @@ struct device_node *of_batterydata_get_best_profile( { struct batt_ids batt_ids; struct device_node *node, *best_node = NULL; + struct device_node *default_node = NULL; struct power_supply *psy; const char *battery_type = NULL; union power_supply_propval ret = {0, }; int delta = 0, best_delta = 0, best_id_kohm = 0, id_range_pct, batt_id_kohm = 0, i = 0, rc = 0, limit = 0; bool in_range = false; - + int checknum = 0, match = 0; psy = power_supply_get_by_name(psy_name); if (!psy) { pr_err("%s supply not found. defer\n", psy_name); @@ -372,11 +374,15 @@ struct device_node *of_batterydata_get_best_profile( delta = abs(batt_ids.kohm[i] - batt_id_kohm); limit = (batt_ids.kohm[i] * id_range_pct) / 100; in_range = (delta <= limit); + if (in_range != 0) + match = 1; /* * Check if the delta is the lowest one * and also if the limits are in range * before selecting the best node. */ + if (batt_ids.kohm[i] == 82) + default_node = node; if ((delta < best_delta || !best_node) && in_range) { best_node = node; @@ -386,14 +392,18 @@ struct device_node *of_batterydata_get_best_profile( } } } - + checknum = abs(best_id_kohm - batt_id_kohm); + if (match == 0) { + best_node = default_node; + checknum = 0; + } if (best_node == NULL) { pr_err("No battery data found\n"); return best_node; } /* check that profile id is in range of the measured batt_id */ - if (abs(best_id_kohm - batt_id_kohm) > + if (checknum > ((best_id_kohm * id_range_pct) / 100)) { pr_err("out of range: profile id %d batt id %d pct %d", best_id_kohm, batt_id_kohm, id_range_pct); diff --git a/drivers/power/qpnp-fg.c b/drivers/power/qpnp-fg.c index 7b110598681d..b037eb7a135d 100644 --- a/drivers/power/qpnp-fg.c +++ b/drivers/power/qpnp-fg.c @@ -248,7 +248,7 @@ static struct fg_mem_setting settings[FG_MEM_SETTING_MAX] = { SETTING(CHG_TERM_CURRENT, 0x4F8, 2, 250), SETTING(IRQ_VOLT_EMPTY, 0x458, 3, 3100), SETTING(CUTOFF_VOLTAGE, 0x40C, 0, 3200), - SETTING(VBAT_EST_DIFF, 0x000, 0, 30), + SETTING(VBAT_EST_DIFF, 0x000, 0, 200), SETTING(DELTA_SOC, 0x450, 3, 1), SETTING(BATT_LOW, 0x458, 0, 4200), SETTING(THERM_DELAY, 0x4AC, 3, 0), @@ -330,7 +330,7 @@ module_param_named( battery_type, fg_batt_type, charp, S_IRUSR | S_IWUSR ); -static int fg_sram_update_period_ms = 30000; +static int fg_sram_update_period_ms = 3000; module_param_named( sram_update_period_ms, fg_sram_update_period_ms, int, S_IRUSR | S_IWUSR ); @@ -2026,11 +2026,6 @@ static void fg_handle_battery_insertion(struct fg_chip *chip) } -static int soc_to_setpoint(int soc) -{ - return DIV_ROUND_CLOSEST(soc * 255, 100); -} - static void batt_to_setpoint_adc(int vbatt_mv, u8 *data) { int val; @@ -8043,8 +8038,7 @@ static int fg_common_hw_init(struct fg_chip *chip) } } - rc = fg_mem_masked_write(chip, settings[FG_MEM_DELTA_SOC].address, 0xFF, - soc_to_setpoint(settings[FG_MEM_DELTA_SOC].value), + rc = fg_mem_masked_write(chip, settings[FG_MEM_DELTA_SOC].address, 0xFF, 1, settings[FG_MEM_DELTA_SOC].offset); if (rc) { pr_err("failed to write delta soc rc=%d\n", rc); diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c index 43e82455335a..75c0f1b6dea5 100644 --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -1,4 +1,5 @@ /* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1076,6 +1077,21 @@ static int get_prop_batt_capacity(struct smbchg_chip *chip) return capacity; } +static int get_prop_battery_charge_full_design(struct smbchg_chip *chip) +{ + union power_supply_propval ret = {0,}; + + if (chip->bms_psy) { + chip->bms_psy->get_property(chip->bms_psy, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, &ret); + return ret.intval; + } else { + pr_debug("No BMS supply registered return 0\n"); + } + + return 0; +} + #define DEFAULT_BATT_TEMP 200 static int get_prop_batt_temp(struct smbchg_chip *chip) { @@ -4896,11 +4912,13 @@ static void handle_usb_removal(struct smbchg_chip *chip) { struct power_supply *parallel_psy = get_parallel_psy(chip); int rc; + if (set_usb_charge_mode_par == 1) { ist30xx_set_ta_mode(0); } else if (set_usb_charge_mode_par == 2) { tpd_usb_plugin(0); } +printk("set_usb_charge_mode_par off = %d\n", set_usb_charge_mode_par); pr_smb(PR_STATUS, "triggered\n"); smbchg_aicl_deglitch_wa_check(chip); /* Clear the OV detected status set before */ @@ -4970,6 +4988,7 @@ static bool is_usbin_uv_high(struct smbchg_chip *chip) return reg &= USBIN_UV_BIT; } +static int rerun_apsd(struct smbchg_chip *chip); #define HVDCP_NOTIFY_MS 2500 static void handle_usb_insertion(struct smbchg_chip *chip) { @@ -4984,6 +5003,10 @@ static void handle_usb_insertion(struct smbchg_chip *chip) pr_smb(PR_STATUS, "triggered\n"); /* usb inserted */ read_usb_type(chip, &usb_type_name, &usb_supply_type); + if (usb_supply_type == POWER_SUPPLY_TYPE_USB_CDP || usb_supply_type == POWER_SUPPLY_TYPE_USB) { + rc = rerun_apsd(chip); + read_usb_type(chip, &usb_type_name, &usb_supply_type); + } pr_smb(PR_STATUS, "inserted type = %d (%s)", usb_supply_type, usb_type_name); @@ -6139,6 +6162,7 @@ static enum power_supply_property smbchg_battery_properties[] = { POWER_SUPPLY_PROP_CHARGING_ENABLED, POWER_SUPPLY_PROP_CHARGE_TYPE, POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL, @@ -6319,7 +6343,7 @@ static int smbchg_battery_get_property(struct power_supply *psy, val->intval = get_prop_batt_health(chip); break; case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; break; case POWER_SUPPLY_PROP_FLASH_CURRENT_MAX: val->intval = smbchg_calc_max_flash_current(chip); @@ -6343,6 +6367,9 @@ static int smbchg_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_CAPACITY: val->intval = get_prop_batt_capacity(chip); break; + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + val->intval = get_prop_battery_charge_full_design(chip); + break; case POWER_SUPPLY_PROP_CURRENT_NOW: val->intval = get_prop_batt_current_now(chip); break; @@ -7612,6 +7639,20 @@ static int smbchg_hw_init(struct smbchg_chip *chip) if (rc < 0) dev_err(chip->dev, "Couldn't set OTG OC config rc = %d\n", rc); + + rc = smbchg_sec_masked_write(chip, chip->otg_base + OTG_CFG, 0x0c, 0x8); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set SMBCHGL_OTG_CFG rc=%d\n", + rc); + } + + rc = smbchg_read(chip, ®, chip->otg_base + OTG_CFG, 1); + printk("%s:read OTG_CFG=%2x\n", __func__, reg); + if (rc < 0) { + dev_err(chip->dev, "Couldn't set SMBCHGL_OTG_CFG rc=%d\n", + rc); + } + } if (chip->otg_pinctrl) { @@ -8602,6 +8643,7 @@ static int smbchg_probe(struct spmi_device *spmi) goto votables_cleanup; } + chip->hvdcp_not_supported = true; rc = smbchg_check_chg_version(chip); if (rc) { pr_err("Unable to check schg version rc=%d\n", rc); From 05ec631eb5126464db923b7a7868d161a18a71e1 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 08:05:12 +0000 Subject: [PATCH 47/86] sound: soc: Import Sound changes Change-Id: I37142404971ef236c05195fc521feb05f1c66952 --- sound/soc/codecs/msm8x16-wcd.c | 7 +++-- sound/soc/codecs/wcd-mbhc-v2.c | 23 +++++++++++++-- sound/soc/msm/msm8952.c | 53 +++++++++++++++------------------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c index 91e8257222b8..750331ab3dd7 100644 --- a/sound/soc/codecs/msm8x16-wcd.c +++ b/sound/soc/codecs/msm8x16-wcd.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -4236,6 +4237,7 @@ static int msm8x16_wcd_lo_dac_event(struct snd_soc_dapm_widget *w, MSM8X16_WCD_A_ANALOG_RX_LO_DAC_CTL, 0x08, 0x08); snd_soc_update_bits(codec, MSM8X16_WCD_A_ANALOG_RX_LO_DAC_CTL, 0x40, 0x40); + msleep(5); break; case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(codec, @@ -4461,7 +4463,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"LINEOUT PA", NULL, "LINE_OUT"}, {"LINE_OUT", "Switch", "LINEOUT DAC"}, {"LINEOUT DAC", NULL, "RX3 CHAIN"}, - + { "Ext Spk", NULL, "LINEOUT PA"}, /* lineout to WSA */ {"WSA_SPK OUT", NULL, "LINEOUT PA"}, @@ -6173,7 +6175,8 @@ static int msm8x16_wcd_spmi_probe(struct spmi_device *spmi) dev_dbg(&spmi->dev, "%s(%d):slave ID = 0x%x\n", __func__, __LINE__, spmi->sid); - + printk("%s(%d):slave ID = 0x%x\n", + __func__, __LINE__, spmi->sid); adsp_state = apr_get_subsys_state(); if (adsp_state != APR_SUBSYS_LOADED) { dev_dbg(&spmi->dev, "Adsp is not loaded yet %d\n", diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 42ea423662d6..02e91737eea0 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include "wcd-mbhc-v2.h" @@ -42,7 +44,7 @@ #define OCP_ATTEMPT 1 #define HS_DETECT_PLUG_TIME_MS (3 * 1000) #define SPECIAL_HS_DETECT_TIME_MS (2 * 1000) -#define MBHC_BUTTON_PRESS_THRESHOLD_MIN 250 +#define MBHC_BUTTON_PRESS_THRESHOLD_MIN 750 #define GND_MIC_SWAP_THRESHOLD 4 #define WCD_FAKE_REMOVAL_MIN_PERIOD_MS 100 #define HS_VREF_MIN_VAL 1400 @@ -67,9 +69,17 @@ enum wcd_mbhc_cs_mb_en_flag { WCD_MBHC_EN_NONE, }; +static struct switch_dev accdet_data; + static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask) { + printk("[%s]===========status[%d]type[%d]\n", __FUNCTION__, status, jack->jack->type); + if (!status && (jack->jack->type&WCD_MBHC_JACK_MASK)) { + switch_set_state(&accdet_data, 0); + } else if (jack->jack->type&WCD_MBHC_JACK_MASK) { + switch_set_state(&accdet_data, status); + } snd_soc_jack_report(jack, status, mask); } @@ -2377,7 +2387,14 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, const char *gnd_switch = "qcom,msm-mbhc-gnd-swh"; pr_debug("%s: enter\n", __func__); - + accdet_data.name = "h2w"; + accdet_data.index = 0; + accdet_data.state = 0; + ret = switch_dev_register(&accdet_data); + if (ret) { + dev_err(card->dev, "[Accdet]switch_dev_register returned:%d!\n", ret); + return -EPERM; + } ret = of_property_read_u32(card->dev->of_node, hph_switch, &hph_swh); if (ret) { dev_err(card->dev, @@ -2574,6 +2591,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec, mbhc->mbhc_cb->register_notifier(codec, &mbhc->nblock, false); mutex_destroy(&mbhc->codec_resource_lock); err: + switch_dev_unregister(&accdet_data); pr_debug("%s: leave ret %d\n", __func__, ret); return ret; } @@ -2595,6 +2613,7 @@ void wcd_mbhc_deinit(struct wcd_mbhc *mbhc) if (mbhc->mbhc_cb && mbhc->mbhc_cb->register_notifier) mbhc->mbhc_cb->register_notifier(codec, &mbhc->nblock, false); mutex_destroy(&mbhc->codec_resource_lock); + switch_dev_unregister(&accdet_data); } EXPORT_SYMBOL(wcd_mbhc_deinit); diff --git a/sound/soc/msm/msm8952.c b/sound/soc/msm/msm8952.c index f504885dc2f2..a1e95d4922d4 100644 --- a/sound/soc/msm/msm8952.c +++ b/sound/soc/msm/msm8952.c @@ -1,4 +1,5 @@ /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -9,7 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - #include #include #include @@ -52,6 +52,7 @@ #define WCD_MBHC_DEF_RLOADS 5 #define MAX_WSA_CODEC_NAME_LENGTH 80 #define MSM_DT_MAX_PROP_SIZE 80 +#define EXT_PA_MODE 5 enum btsco_rates { RATE_8KHZ_ID, @@ -94,9 +95,9 @@ static struct wcd_mbhc_config mbhc_cfg = { .swap_gnd_mic = NULL, .hs_ext_micbias = false, .key_code[0] = KEY_MEDIA, - .key_code[1] = KEY_VOICECOMMAND, - .key_code[2] = KEY_VOLUMEUP, - .key_code[3] = KEY_VOLUMEDOWN, + .key_code[1] = BTN_1, + .key_code[2] = BTN_2, + .key_code[3] = 0, .key_code[4] = 0, .key_code[5] = 0, .key_code[6] = 0, @@ -257,6 +258,7 @@ int is_ext_spk_gpio_support(struct platform_device *pdev, return -EINVAL; } } + gpio_direction_output(pdata->spk_ext_pa_gpio, 0); return 0; } @@ -264,8 +266,7 @@ static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) { struct snd_soc_card *card = codec->component.card; struct msm8916_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card); - int ret; - + int pa_mode = EXT_PA_MODE; if (!gpio_is_valid(pdata->spk_ext_pa_gpio)) { pr_err("%s: Invalid gpio: %d\n", __func__, pdata->spk_ext_pa_gpio); @@ -276,21 +277,15 @@ static int enable_spk_ext_pa(struct snd_soc_codec *codec, int enable) enable ? "Enable" : "Disable"); if (enable) { - ret = msm_gpioset_activate(CLIENT_WCD_INT, "ext_spk_gpio"); - if (ret) { - pr_err("%s: gpio set cannot be de-activated %s\n", - __func__, "ext_spk_gpio"); - return ret; + while (pa_mode > 0) { + gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, 0); + udelay(2); + gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); + udelay(2); + pa_mode--; } - gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); } else { gpio_set_value_cansleep(pdata->spk_ext_pa_gpio, enable); - ret = msm_gpioset_suspend(CLIENT_WCD_INT, "ext_spk_gpio"); - if (ret) { - pr_err("%s: gpio set cannot be de-activated %s\n", - __func__, "ext_spk_gpio"); - return ret; - } } return 0; } @@ -1545,7 +1540,7 @@ static void *def_msm8952_wcd_mbhc_cal(void) return NULL; #define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(msm8952_wcd_cal)->X) = (Y)) - S(v_hs_max, 1500); + S(v_hs_max, 1600); #undef S #define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(msm8952_wcd_cal)->X) = (Y)) S(num_btn, WCD_MBHC_DEF_BUTTONS); @@ -1568,17 +1563,17 @@ static void *def_msm8952_wcd_mbhc_cal(void) * 210-290 == Button 2 * 360-680 == Button 3 */ - btn_low[0] = 75; - btn_high[0] = 75; - btn_low[1] = 150; - btn_high[1] = 150; - btn_low[2] = 225; - btn_high[2] = 225; - btn_low[3] = 450; - btn_high[3] = 450; - btn_low[4] = 500; - btn_high[4] = 500; + btn_low[0] = 73; + btn_high[0] = 73; + btn_low[1] = 233; + btn_high[1] = 233; + btn_low[2] = 438; + btn_high[2] = 438; + btn_low[3] = 438; + btn_high[3] = 438; + btn_low[4] = 438; + btn_high[4] = 438; return msm8952_wcd_cal; } From 6ca01e814a41caea67375f924a8578696026e33c Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 08:08:11 +0000 Subject: [PATCH 48/86] fs: pstore: Import pstore Changes --- fs/pstore/ram.c | 6 +++--- fs/pstore/ram_core.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 273f06370dc1..e689c9e7a2e2 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -43,7 +43,7 @@ module_param(record_size, ulong, 0400); MODULE_PARM_DESC(record_size, "size of each dump done on oops/panic"); -static ulong ramoops_console_size = MIN_MEM_SIZE; +static ulong ramoops_console_size = 256*1024UL; module_param_named(console_size, ramoops_console_size, ulong, 0400); MODULE_PARM_DESC(console_size, "size of kernel console log"); @@ -55,12 +55,12 @@ static ulong ramoops_pmsg_size = MIN_MEM_SIZE; module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400); MODULE_PARM_DESC(pmsg_size, "size of user space message log"); -static ulong mem_address; +static ulong mem_address = 0x9ff00000; module_param(mem_address, ulong, 0400); MODULE_PARM_DESC(mem_address, "start of reserved RAM used to store oops/panic logs"); -static ulong mem_size; +static ulong mem_size = 0x100000; module_param(mem_size, ulong, 0400); MODULE_PARM_DESC(mem_size, "size of reserved RAM used to store oops/panic logs"); diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 982d333f5685..6e5c2777aa9a 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -298,11 +298,21 @@ ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz, return ret; } +static void *memcpy_pstore(void *dest, const void *src, size_t count) +{ + char *tmp = dest; + const char *s = src; + + while (count--) + *tmp++ = *s++; + return dest; +} + static void notrace persistent_ram_update(struct persistent_ram_zone *prz, const void *s, unsigned int start, unsigned int count) { struct persistent_ram_buffer *buffer = prz->buffer; - memcpy(buffer->data + start, s, count); + memcpy_pstore(buffer->data + start, s, count); persistent_ram_update_ecc(prz, start, count); } From 838d5bd210a611cd5fa43e820f761f8c91011fd5 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 08:12:57 +0000 Subject: [PATCH 49/86] drivers: soc: qcom: Add serial_num driver Change-Id: I6ac4681d8e57472c8c5f008cc3ed1d481ca8d57f --- drivers/soc/qcom/Kconfig | 5 ++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/serial_num.c | 121 ++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 drivers/soc/qcom/serial_num.c diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index c0d99ba847d8..58707c05758c 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -901,6 +901,11 @@ config WCD_DSP_GLINK between MSM and WCD DSP over glink transport protocol. This driver provides read and write interface via char device. +config SERIAL_NUM + bool "Enable Serial Number Proc Interface" + help + Provide a interface for reading CPU serial number + source "drivers/soc/qcom/memshare/Kconfig" endif # ARCH_MSM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index fb0ae9187ab7..9be6bdbe10cb 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -108,3 +108,4 @@ obj-$(CONFIG_MSM_REMOTEQDSS) += remoteqdss.o obj-$(CONFIG_QCOM_SMCINVOKE) += smcinvoke.o obj-$(CONFIG_QCOM_EARLY_RANDOM) += early_random.o obj-$(CONFIG_MSM_HAB) += hab/ +obj-$(CONFIG_SERIAL_NUM) += serial_num.o diff --git a/drivers/soc/qcom/serial_num.c b/drivers/soc/qcom/serial_num.c new file mode 100644 index 000000000000..01e90d1f45c8 --- /dev/null +++ b/drivers/soc/qcom/serial_num.c @@ -0,0 +1,121 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define sn_readl(drvdata, off) __raw_readl(drvdata->base + off) + +#define SERIAL_NUM (0x000) + +static uint32_t sn; + +struct sn_drvdata { + void __iomem *base; + struct device *dev; +}; + +static struct sn_drvdata *sndrvdata; + +static int sn_read(struct seq_file *m, void *v) +{ + struct sn_drvdata *drvdata = sndrvdata; + + if (!drvdata) + return false; + + if (sn == 0) + sn = sn_readl(drvdata, SERIAL_NUM); + + dev_dbg(drvdata->dev, "serial num: %x\n", sn); + + seq_printf(m, "0x%x\n", sn); + + return 0; + +} + +static int sn_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, sn_read, NULL); +} + +static const struct file_operations sn_fops = { + .open = sn_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void sn_create_proc(void) +{ + struct proc_dir_entry *entry; + entry = proc_create("serial_num", 0 /* default mode */, + NULL /* parent dir */, &sn_fops); +} + +static int sn_fuse_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct sn_drvdata *drvdata; + struct resource *res; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + /* Store the driver data pointer for use in exported functions */ + sndrvdata = drvdata; + drvdata->dev = &pdev->dev; + platform_set_drvdata(pdev, drvdata); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sn-base"); + if (!res) + return -ENODEV; + + drvdata->base = devm_ioremap(dev, res->start, resource_size(res)); + if (!drvdata->base) + return -ENOMEM; + + sn_create_proc(); + dev_info(dev, "SN interface initialized\n"); + return 0; +} + +static int sn_fuse_remove(struct platform_device *pdev) +{ + return 0; +} + +static struct of_device_id sn_fuse_match[] = { + {.compatible = "qcom,sn-fuse"}, + {} +}; + +static struct platform_driver sn_fuse_driver = { + .probe = sn_fuse_probe, + .remove = sn_fuse_remove, + .driver = { + .name = "msm-sn-fuse", + .owner = THIS_MODULE, + .of_match_table = sn_fuse_match, + }, +}; + +static int __init sn_fuse_init(void) +{ + return platform_driver_register(&sn_fuse_driver); +} +arch_initcall(sn_fuse_init); + +static void __exit sn_fuse_exit(void) +{ + platform_driver_unregister(&sn_fuse_driver); +} +module_exit(sn_fuse_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("JTag Fuse driver"); From acf817669859b95736517b7cd8ecf23f2871faa3 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 19 May 2017 13:10:18 +0800 Subject: [PATCH 50/86] arch: arm: boot: dts: update qcom,mdss-dsi-panel-timings tag * this fixes black screen issue on boot --- arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi index 59b29ea35972..20016bf0b121 100644 --- a/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-mdss-panels.dtsi @@ -55,7 +55,7 @@ /* Rain bow lcd nt35532 */ &dsi_nt35532_fhd_vid { - qcom,mdss-dsi-panel-timings-8996 = [24 1f 08 09 05 03 04 a0 + qcom,mdss-dsi-panel-timings-phy-v2 = [24 1f 08 09 05 03 04 a0 24 1f 08 09 05 03 04 a0 24 1f 08 09 05 03 04 a0 24 1f 08 09 05 03 04 a0 @@ -63,7 +63,7 @@ }; &dsi_nt35596_fhd_vid { - qcom,mdss-dsi-panel-timings-8996 = [24 1f 08 09 05 03 04 a0 + qcom,mdss-dsi-panel-timings-phy-v2 = [24 1f 08 09 05 03 04 a0 24 1f 08 09 05 03 04 a0 24 1f 08 09 05 03 04 a0 24 1f 08 09 05 03 04 a0 @@ -71,7 +71,7 @@ }; &dsi_nt35596_tianma_fhd_vid { - qcom,mdss-dsi-panel-timings-8996 = [23 1e 08 09 05 03 04 a0 + qcom,mdss-dsi-panel-timings-phy-v2 = [23 1e 08 09 05 03 04 a0 23 1e 08 09 05 03 04 a0 23 1e 08 09 05 03 04 a0 23 1e 08 09 05 03 04 a0 From ea4e7c523ea00e0e8e4a953c6ac38a1f673d705b Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 07:51:40 +0000 Subject: [PATCH 51/86] drivers: media: Import lirc driver --- drivers/media/rc/Kconfig | 30 ++ drivers/media/rc/Makefile | 4 +- drivers/media/rc/gpio-ir.c | 762 +++++++++++++++++++++++++++++ drivers/media/rc/ir-dump-decoder.c | 86 ++++ drivers/media/rc/ir-lirc-codec.c | 45 +- drivers/media/rc/lirc_dev.c | 3 +- drivers/media/rc/pwm-ir.c | 391 +++++++++++++++ drivers/media/rc/rc-ir-raw.c | 11 +- drivers/media/rc/rc-main.c | 22 +- include/media/gpio-ir.h | 34 ++ include/media/pwm-ir.h | 25 + include/media/rc-core.h | 3 + 12 files changed, 1398 insertions(+), 18 deletions(-) create mode 100644 drivers/media/rc/gpio-ir.c create mode 100644 drivers/media/rc/ir-dump-decoder.c create mode 100644 drivers/media/rc/pwm-ir.c create mode 100644 include/media/gpio-ir.h create mode 100644 include/media/pwm-ir.h diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 8ce08107a69d..dc247a7bfaa5 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -123,11 +123,22 @@ config IR_XMP_DECODER ---help--- Enable this option if you have IR with XMP protocol, and if the IR is decoded in software + +config IR_DUMP_DECODER + tristate "Enable IR dump decoder for debugging purpose" + depends on RC_CORE + default n + + ---help--- + Enable this option if you have an infrared remote control which + you want to dump the IR signal. + endif #RC_DECODERS menuconfig RC_DEVICES bool "Remote Controller devices" depends on RC_CORE + default y if RC_DEVICES @@ -341,6 +352,25 @@ config IR_GPIO_CIR To compile this driver as a module, choose M here: the module will be called gpio-ir-recv. + +config IR_GPIO + tristate "GPIO IR remote control" + depends on RC_CORE + ---help--- + Say Y if you want to use GPIO based IR. + + To compile this driver as a module, choose M here: the module will + be called gpio-ir. + +config IR_PWM + tristate "PWM IR remote control" + depends on RC_CORE + ---help--- + Say Y if you want to use PWM based IR. + + To compile this driver as a module, choose M here: the module will + be called pwm-ir. + config RC_ST tristate "ST remote control receiver" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index 0989f940e9cf..9aa02868cd86 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -14,7 +14,9 @@ obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o - +obj-$(CONFIG_IR_DUMP_DECODER) += ir-dump-decoder.o +obj-$(CONFIG_IR_GPIO) += gpio-ir.o +obj-$(CONFIG_IR_PWM) += pwm-ir.o # stand-alone IR receivers/transmitters obj-$(CONFIG_RC_ATI_REMOTE) += ati_remote.o obj-$(CONFIG_IR_HIX5HD2) += ir-hix5hd2.o diff --git a/drivers/media/rc/gpio-ir.c b/drivers/media/rc/gpio-ir.c new file mode 100644 index 000000000000..82e591d22907 --- /dev/null +++ b/drivers/media/rc/gpio-ir.c @@ -0,0 +1,762 @@ +/* Copyright (C) 2012 by Xiang Xiao + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct gpio_ir_dev { + struct mutex lock; + struct platform_device *pdev; + struct rc_dev *rdev; + struct regulator *tx_reg; + u32 tx_carrier; + u32 tx_duty_cycle; + struct regulator *rx_reg; + struct hrtimer rx_timer; + ktime_t rx_carrier_last; + u32 rx_carrier_count; + bool rx_carrier_report; +}; + +struct gpio_ir_tx_packet { + struct completion done; + struct hrtimer timer; + unsigned int gpio_nr; + bool high_active; + u32 pulse; + u32 space; + bool abort; + unsigned int *buffer; + unsigned int length; + unsigned int next; + bool on; +}; + +#define GPIO_IR_TX_NAME (GPIO_IR_NAME "-tx") +#define GPIO_IR_RX_NAME (GPIO_IR_NAME "-rx") + +#define GPIO_IR_MIN_CARRIER_HZ 10000 +#define GPIO_IR_DEF_CARRIER_HZ 38000 + +#define GPIO_IR_DEF_CARRIER_NS (NSEC_PER_SEC / GPIO_IR_DEF_CARRIER_HZ) +#define GPIO_IR_MAX_CARRIER_NS (NSEC_PER_SEC / GPIO_IR_MIN_CARRIER_HZ) + +/* code for open and close */ +static int gpio_ir_rx_enable(struct gpio_ir_dev *gdev) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + int rc = 0; + + if (gdev->rx_reg) + rc = regulator_enable(gdev->rx_reg); + if (rc == 0 && gpio_is_valid(gdata->rx_gpio_nr)) + enable_irq(gpio_to_irq(gdata->rx_gpio_nr)); + + return rc; +} + +static void gpio_ir_rx_disable(struct gpio_ir_dev *gdev) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + + if (gpio_is_valid(gdata->rx_gpio_nr)) + disable_irq(gpio_to_irq(gdata->rx_gpio_nr)); + hrtimer_cancel(&gdev->rx_timer); + if (gdev->rx_reg) + regulator_disable(gdev->rx_reg); +} + +static int gpio_ir_open(struct rc_dev *rdev) +{ + struct gpio_ir_dev *gdev = rdev->priv; + int rc = 0; + + mutex_lock(&gdev->lock); + rc = gpio_ir_rx_enable(gdev); + mutex_unlock(&gdev->lock); + + return rc; +} + +static void gpio_ir_close(struct rc_dev *rdev) +{ + struct gpio_ir_dev *gdev = rdev->priv; + + mutex_lock(&gdev->lock); + gpio_ir_rx_disable(gdev); + mutex_unlock(&gdev->lock); +} + +/* code for ir transmit */ +static int gpio_ir_tx_carrier(struct rc_dev *rdev, u32 carrier) +{ + struct gpio_ir_dev *gdev = rdev->priv; + + mutex_lock(&gdev->lock); + gdev->tx_carrier = carrier; + mutex_unlock(&gdev->lock); + + return 0; +} + +static int gpio_ir_tx_duty_cycle(struct rc_dev *rdev, u32 duty_cycle) +{ + struct gpio_ir_dev *gdev = rdev->priv; + + mutex_lock(&gdev->lock); + gdev->tx_duty_cycle = duty_cycle; + mutex_unlock(&gdev->lock); + + return 0; +} + +static void gpio_ir_tx_set(struct gpio_ir_tx_packet *gpkt, bool on) +{ + if (gpkt->high_active) + gpio_set_value(gpkt->gpio_nr, on); + else + gpio_set_value(gpkt->gpio_nr, !on); +} + +static enum hrtimer_restart gpio_ir_tx_timer(struct hrtimer *timer) +{ + struct gpio_ir_tx_packet *gpkt = container_of(timer, struct gpio_ir_tx_packet, timer); + enum hrtimer_restart restart = HRTIMER_RESTART; + + if (!gpkt->abort && gpkt->next < gpkt->length) { + if (gpkt->next & 0x01) { /* space */ + gpio_ir_tx_set(gpkt, false); + + hrtimer_forward_now(&gpkt->timer, + ns_to_ktime(gpkt->buffer[gpkt->next++])); + } else if (!gpkt->pulse || !gpkt->space) { + gpio_ir_tx_set(gpkt, true); + + hrtimer_forward_now(&gpkt->timer, + ns_to_ktime(gpkt->buffer[gpkt->next++])); + } else { /* pulse with soft carrier */ + unsigned int nsecs; + + nsecs = gpkt->on ? gpkt->pulse : gpkt->space; + nsecs = min(nsecs, gpkt->buffer[gpkt->next]); + + gpio_ir_tx_set(gpkt, gpkt->on); + hrtimer_forward_now(&gpkt->timer, ns_to_ktime(nsecs)); + + gpkt->buffer[gpkt->next] -= nsecs; + gpkt->on = !gpkt->on; + + if (!gpkt->buffer[gpkt->next]) + gpkt->next++; + } + } else { + restart = HRTIMER_NORESTART; + gpio_ir_tx_set(gpkt, false); + complete(&gpkt->done); + } + + return restart; +} + +static int gpio_ir_tx_transmit_with_timer(struct gpio_ir_tx_packet *gpkt) +{ + int rc = 0; + + init_completion(&gpkt->done); + + hrtimer_init(&gpkt->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + gpkt->timer.function = gpio_ir_tx_timer; + + hrtimer_start(&gpkt->timer, ns_to_ktime(0), HRTIMER_MODE_REL); + + rc = wait_for_completion_interruptible(&gpkt->done); + if (rc != 0) { /* signal exit immediately */ + gpkt->abort = true; + wait_for_completion(&gpkt->done); + } + + return gpkt->next ? : -ERESTARTSYS; +} + +static void gpio_ir_tx_ndelay(unsigned long nsecs) +{ + unsigned long max_delay_ns = NSEC_PER_MSEC * MAX_UDELAY_MS; + + while (nsecs > max_delay_ns) { + ndelay(max_delay_ns); + nsecs -= max_delay_ns; + } + ndelay(nsecs); +} + +static int gpio_ir_tx_transmit_with_delay(struct gpio_ir_tx_packet *gpkt) +{ + unsigned long flags; + + /* disable irq for acurracy timing */ + local_irq_save(flags); + + for (; gpkt->next < gpkt->length; gpkt->next++) { + if (signal_pending(current)) + break; + if (gpkt->next & 0x01) { /* space */ + gpio_ir_tx_set(gpkt, false); + gpio_ir_tx_ndelay(gpkt->buffer[gpkt->next]); + } else if (!gpkt->pulse || !gpkt->space) { + gpio_ir_tx_set(gpkt, true); + gpio_ir_tx_ndelay(gpkt->buffer[gpkt->next]); + } else { /* pulse with soft carrier */ + while (gpkt->buffer[gpkt->next]) { + unsigned int nsecs; + + nsecs = gpkt->on ? gpkt->pulse : gpkt->space; + nsecs = min(nsecs, gpkt->buffer[gpkt->next]); + + gpio_ir_tx_set(gpkt, gpkt->on); + gpio_ir_tx_ndelay(nsecs); + + gpkt->buffer[gpkt->next] -= nsecs; + gpkt->on = !gpkt->on; + } + } + } + + gpio_ir_tx_set(gpkt, false); + local_irq_restore(flags); + + return gpkt->next ? : -ERESTARTSYS; +} + +static int gpio_ir_tx_transmit(struct rc_dev *rdev, unsigned *txbuf, unsigned n) +{ + struct gpio_ir_dev *gdev = rdev->priv; + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + struct gpio_ir_tx_packet gpkt = {}; + int i, rc = 0; + + for (i = 0; i < n; i++) + txbuf[i] *= NSEC_PER_USEC; + + mutex_lock(&gdev->lock); + + if (gdata->tx_disable_rx) + gpio_ir_rx_disable(gdev); + + if (gdev->tx_reg) { + rc = regulator_enable(gdev->tx_reg); + if (rc != 0) + goto err_regulator_enable; + } + + if (gdata->tx_soft_carrier) { + u32 carrier = gdev->tx_carrier ?: GPIO_IR_DEF_CARRIER_HZ; + u32 duty_cycle = gdev->tx_duty_cycle ?: 50; + u32 period = NSEC_PER_SEC / carrier; + + gpkt.pulse = period * duty_cycle / 100; + gpkt.space = period - gpkt.pulse; + } + + gpkt.gpio_nr = gdata->tx_gpio_nr; + gpkt.high_active = gdata->tx_high_active; + gpkt.buffer = txbuf; + gpkt.length = n; + + if (gdata->tx_with_timer) + rc = gpio_ir_tx_transmit_with_timer(&gpkt); + else + rc = gpio_ir_tx_transmit_with_delay(&gpkt); + + if (gdev->tx_reg) + regulator_disable(gdev->tx_reg); +err_regulator_enable: + if (gdata->tx_disable_rx) + gpio_ir_rx_enable(gdev); + mutex_unlock(&gdev->lock); + return rc; +} + +static int __devinit gpio_ir_tx_probe(struct gpio_ir_dev *gdev) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + int rc = 0; + + if (gdata->tx_reg_id) { + gdev->tx_reg = regulator_get(&gdev->pdev->dev, gdata->tx_reg_id); + if (IS_ERR(gdev->tx_reg)) { + dev_err(&gdev->pdev->dev, + "failed to regulator_get(%s)\n", + gdata->tx_reg_id); + return PTR_ERR(gdev->tx_reg); + } + } + + if (gpio_is_valid(gdata->tx_gpio_nr)) { + rc = gpio_request(gdata->tx_gpio_nr, GPIO_IR_TX_NAME); + if (rc < 0) { + dev_err(&gdev->pdev->dev, + "failed to gpio_request(%u)\n", + gdata->tx_gpio_nr); + goto err_gpio_request; + } + + rc = gpio_direction_output( + gdata->tx_gpio_nr, + !gdata->tx_high_active); + if (rc < 0) { + dev_err(&gdev->pdev->dev, + "failed to gpio_direction_output(%u)\n", + gdata->tx_gpio_nr); + goto err_gpio_direction_output; + } + + if (gdata->tx_soft_carrier) { + gdev->rdev->s_tx_carrier = gpio_ir_tx_carrier; + gdev->rdev->s_tx_duty_cycle = gpio_ir_tx_duty_cycle; + } + gdev->rdev->tx_ir = gpio_ir_tx_transmit; + } + + return rc; + +err_gpio_direction_output: + gpio_free(gdata->tx_gpio_nr); +err_gpio_request: + if (gdev->tx_reg) + regulator_put(gdev->tx_reg); + return rc; +} + +static void gpio_ir_tx_remove(struct gpio_ir_dev *gdev) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + + if (gpio_is_valid(gdata->tx_gpio_nr)) + gpio_free(gdata->tx_gpio_nr); + + if (gdev->tx_reg) + regulator_put(gdev->tx_reg); +} + +/* code for ir receive */ +static int gpio_ir_rx_carrier_report(struct rc_dev *rdev, int enable) +{ + struct gpio_ir_dev *gdev = rdev->priv; + + mutex_lock(&gdev->lock); + gdev->rx_carrier_report = enable; + mutex_unlock(&gdev->lock); + + return 0; +} + +static u32 gpio_ir_rx_carrier_period(struct gpio_ir_dev *gdev, s32 adjust) +{ + ktime_t now; + s64 delta; + u32 period; + + now = ktime_add_ns(ktime_get(), adjust); + delta = ktime_to_ns(ktime_sub(now, gdev->rx_carrier_last)); + period = (u32)(2 * delta) / gdev->rx_carrier_count; + + return period; +} + +static enum hrtimer_restart gpio_ir_rx_timer(struct hrtimer *timer) +{ + struct gpio_ir_dev *gdev = container_of(timer, struct gpio_ir_dev, rx_timer); + u32 period = gpio_ir_rx_carrier_period(gdev, -GPIO_IR_MAX_CARRIER_NS); + int rc = -ENOENT; + + if (gdev->rx_carrier_report) { + DEFINE_IR_RAW_EVENT(ev); + + ev.carrier = NSEC_PER_SEC / period; + ev.duty_cycle = 50; + ev.carrier_report = 1; + + rc = ir_raw_event_store(gdev->rdev, &ev); + if (rc != 0) { + dev_err(&gdev->pdev->dev, + "failed to ir_raw_event_store(%d)\n", rc); + } + } else { + rc = ir_raw_event_store_edge_with_adjust(gdev->rdev, + IR_SPACE, period - GPIO_IR_MAX_CARRIER_NS); + if (rc != 0) { + dev_err(&gdev->pdev->dev, "failed to " + "ir_raw_event_store_edge_with_adjust(%d)\n", rc); + } + } + + if (rc == 0) + ir_raw_event_handle(gdev->rdev); + + return HRTIMER_NORESTART; +} + +static bool gpio_ir_rx_get(struct gpio_ir_data *gdata) +{ + if (gdata->rx_high_active) + return gpio_get_value(gdata->rx_gpio_nr); + else + return !gpio_get_value(gdata->rx_gpio_nr); +} + +static irqreturn_t gpio_ir_rx_irq(int irq, void *dev) +{ + struct gpio_ir_dev *gdev = dev; + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + int rc = -ENOENT; + + if (gdata->rx_soft_carrier) { + if (!hrtimer_active(&gdev->rx_timer)) { + gdev->rx_carrier_last = ktime_get(); + gdev->rx_carrier_count = 0; + if (!gdev->rx_carrier_report) { + rc = ir_raw_event_store_edge(gdev->rdev, IR_PULSE); + if (rc != 0) { + dev_err(&gdev->pdev->dev, "failed to " + "ir_raw_event_store_edge(%d, %d)\n", + IR_PULSE, rc); + } + } + } + + gdev->rx_carrier_count++; + hrtimer_start(&gdev->rx_timer, + ns_to_ktime(GPIO_IR_MAX_CARRIER_NS), + HRTIMER_MODE_REL); + } else { + enum raw_event_type type; + + type = gpio_ir_rx_get(gdata) ? IR_PULSE : IR_SPACE; + rc = ir_raw_event_store_edge(gdev->rdev, type); + if (rc != 0) { + dev_err(&gdev->pdev->dev, "failed to " + "ir_raw_event_store_edge(%d, %d)\n", + type, rc); + } + } + + if (rc == 0) + ir_raw_event_handle(gdev->rdev); + + return IRQ_HANDLED; +} + +static int __devinit gpio_ir_rx_probe(struct gpio_ir_dev *gdev) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + unsigned long flags; + int rc = 0; + + hrtimer_init(&gdev->rx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + gdev->rx_timer.function = gpio_ir_rx_timer; + + if (gdata->rx_reg_id) { + gdev->rx_reg = regulator_get(&gdev->pdev->dev, gdata->rx_reg_id); + if (IS_ERR(gdev->rx_reg)) { + dev_err(&gdev->pdev->dev, + "failed to regulator_get(%s)\n", + gdata->rx_reg_id); + return PTR_ERR(gdev->rx_reg); + } + } + + if (gpio_is_valid(gdata->rx_gpio_nr)) { + rc = gpio_request(gdata->rx_gpio_nr, GPIO_IR_RX_NAME); + if (rc < 0) { + dev_err(&gdev->pdev->dev, + "failed to gpio_request(%u)\n", + gdata->rx_gpio_nr); + goto err_gpio_request; + } + + rc = gpio_direction_input(gdata->rx_gpio_nr); + if (rc < 0) { + dev_err(&gdev->pdev->dev, + "failed to gpio_direction_input(%u)\n", + gdata->rx_gpio_nr); + goto err_gpio_direction_input; + } + + flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_DISABLED; + rc = request_irq(gpio_to_irq(gdata->rx_gpio_nr), + gpio_ir_rx_irq, flags, GPIO_IR_RX_NAME, gdev); + if (rc < 0) { + dev_err(&gdev->pdev->dev, + "failed to request_irq(%d)\n", + gpio_to_irq(gdata->rx_gpio_nr)); + goto err_request_irq; + } + + rc = device_init_wakeup(&gdev->pdev->dev, gdata->rx_can_wakeup); + if (rc < 0) { + dev_err(&gdev->pdev->dev, + "failed to device_init_wakeup(%d)\n", + gdata->rx_can_wakeup); + goto err_device_init_wakeup; + } + + if (gdata->rx_soft_carrier) + gdev->rdev->s_carrier_report = gpio_ir_rx_carrier_report; + } + + return rc; + +err_device_init_wakeup: + free_irq(gpio_to_irq(gdata->rx_gpio_nr), gdev); +err_request_irq: +err_gpio_direction_input: + gpio_free(gdata->rx_gpio_nr); +err_gpio_request: + if (gdev->rx_reg) + regulator_put(gdev->rx_reg); + return rc; +} + +static void gpio_ir_rx_remove(struct gpio_ir_dev *gdev) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + + if (gpio_is_valid(gdata->rx_gpio_nr)) { + free_irq(gpio_to_irq(gdata->rx_gpio_nr), gdev); + gpio_free(gdata->rx_gpio_nr); + } + + hrtimer_cancel(&gdev->rx_timer); + if (gdev->rx_reg) + regulator_put(gdev->rx_reg); +} + +/* code for power management */ +#ifdef CONFIG_PM +static int gpio_ir_rx_wake(struct gpio_ir_dev *gdev, bool enable) +{ + struct gpio_ir_data *gdata = gdev->pdev->dev.platform_data; + int rc = 0; + + if (gpio_is_valid(gdata->rx_gpio_nr)) { + int irq = gpio_to_irq(gdata->rx_gpio_nr); + + if (enable) + rc = enable_irq_wake(irq); + else + rc = disable_irq_wake(irq); + } + + return rc; +} + +static int gpio_ir_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct gpio_ir_dev *gdev = platform_get_drvdata(pdev); + int rc = 0; + + mutex_lock(&gdev->lock); + if (gdev->rdev->open_count) { + if (device_may_wakeup(dev)) + rc = gpio_ir_rx_wake(gdev, true); + else + gpio_ir_rx_disable(gdev); + } + mutex_unlock(&gdev->lock); + + return rc; +} + +static int gpio_ir_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct gpio_ir_dev *gdev = platform_get_drvdata(pdev); + int rc = 0; + + mutex_lock(&gdev->lock); + if (gdev->rdev->open_count) { + if (device_may_wakeup(dev)) + rc = gpio_ir_rx_wake(gdev, false); + else + rc = gpio_ir_rx_enable(gdev); + } + mutex_unlock(&gdev->lock); + + return rc; +} + +static const struct dev_pm_ops gpio_ir_pm_ops = { + .suspend = gpio_ir_suspend, + .resume = gpio_ir_resume, +}; +#endif + +/* code for probe and remove */ +static int __devinit gpio_ir_probe(struct platform_device *pdev) +{ + struct gpio_ir_data *gdata; + struct gpio_ir_dev *gdev; + int rc = -ENOMEM; + + gdata = pdev->dev.platform_data; + if (!gdata) { + gdata = devm_kzalloc(&pdev->dev, sizeof(*gdata), GFP_KERNEL); + if (gdata) { + pdev->dev.platform_data = gdata; + if (pdev->dev.of_node) { + of_property_read_string(pdev->dev.of_node, "tx-reg-id", &gdata->tx_reg_id); + of_property_read_u32(pdev->dev.of_node, "tx-gpio-nr", (u32 *)&gdata->tx_gpio_nr); + gdata->tx_high_active = of_property_read_bool(pdev->dev.of_node, "tx-high-active"); + gdata->tx_soft_carrier = of_property_read_bool(pdev->dev.of_node, "tx-soft-carrier"); + gdata->tx_disable_rx = of_property_read_bool(pdev->dev.of_node, "tx-disable-rx"); + gdata->tx_with_timer = of_property_read_bool(pdev->dev.of_node, "tx-with-timer"); + + of_property_read_string(pdev->dev.of_node, "rx-reg-id", &gdata->rx_reg_id); + of_property_read_u32(pdev->dev.of_node, "rx-gpio-nr", (u32 *)&gdata->rx_gpio_nr); + gdata->rx_high_active = of_property_read_bool(pdev->dev.of_node, "rx-high-active"); + gdata->rx_soft_carrier = of_property_read_bool(pdev->dev.of_node, "rx-soft-carrier"); + of_property_read_u64(pdev->dev.of_node, "rx-init-protos", &gdata->rx_init_protos); + gdata->rx_can_wakeup = of_property_read_bool(pdev->dev.of_node, "rx-can-wakeup"); + of_property_read_string(pdev->dev.of_node, "rx-map-name", &gdata->rx_map_name); + + dev_info(&pdev->dev, + "tx-reg-id = %s, tx-gpio-nr = %d, tx-high-active = %d, " + "tx-soft-carrier = %d, tx-disable-rx = %d, tx-with-timer = %d\n", + gdata->tx_reg_id, gdata->tx_gpio_nr, gdata->tx_high_active, + gdata->tx_soft_carrier, gdata->tx_disable_rx, gdata->tx_with_timer); + + dev_info(&pdev->dev, + "rx-reg-id = %s, rx-gpio-nr = %d, rx-high-active = %d, rx-soft-carrier = %d, " + "rx-init-protos = %d, rx-can-wakeup = %d, rx-map-name = %d\n", + gdata->rx_reg_id, gdata->rx_gpio_nr, gdata->rx_high_active, gdata->rx_soft_carrier, + gdata->rx_init_protos, gdata->rx_can_wakeup, gdata->rx_map_name); + } + } else { + dev_err(&pdev->dev, "failed to alloc platform data\n"); + return -ENOMEM; + } + } + + gdev = kzalloc(sizeof(*gdev), GFP_KERNEL); + if (!gdev) { + dev_err(&pdev->dev, "failed to alloc gdev\n"); + return rc; + } + + mutex_init(&gdev->lock); + + gdev->pdev = pdev; + platform_set_drvdata(pdev, gdev); + + gdev->rdev = rc_allocate_device(); + if (!gdev->rdev) { + dev_err(&pdev->dev, "failed to alloc rdev\n"); + goto err_rc_allocate_device; + } + + gdev->rdev->dev.parent = &pdev->dev; + gdev->rdev->input_name = GPIO_IR_NAME; + gdev->rdev->input_phys = GPIO_IR_NAME; + gdev->rdev->input_id.bustype = BUS_HOST; + gdev->rdev->driver_name = GPIO_IR_NAME; + gdev->rdev->map_name = gdata->rx_map_name; + gdev->rdev->driver_type = RC_DRIVER_IR_RAW; + gdev->rdev->allowed_protos = gdata->rx_init_protos; + gdev->rdev->priv = gdev; + gdev->rdev->open = gpio_ir_open; + gdev->rdev->close = gpio_ir_close; + + rc = gpio_ir_tx_probe(gdev); + if (rc != 0) + goto err_gpio_ir_tx_probe; + + rc = gpio_ir_rx_probe(gdev); + if (rc != 0) + goto err_gpio_ir_rx_probe; + + rc = rc_register_device(gdev->rdev); + if (rc < 0) { + dev_err(&pdev->dev, "failed to register rdev\n"); + goto err_rc_register_device; + } + + return rc; + +err_rc_register_device: + gpio_ir_rx_remove(gdev); +err_gpio_ir_rx_probe: + gpio_ir_tx_remove(gdev); +err_gpio_ir_tx_probe: + rc_free_device(gdev->rdev); +err_rc_allocate_device: + kfree(gdev); + return rc; +} + +static int __devexit gpio_ir_remove(struct platform_device *pdev) +{ + struct gpio_ir_dev *gdev = platform_get_drvdata(pdev); + + rc_unregister_device(gdev->rdev); + gpio_ir_rx_remove(gdev); + gpio_ir_tx_remove(gdev); + kfree(gdev); + + return 0; +} + +/* code for init and exit */ +static const struct of_device_id of_gpio_ir_match[] = { + {.compatible = GPIO_IR_NAME,}, + {}, +}; + +static struct platform_driver gpio_ir_driver = { + .probe = gpio_ir_probe, + .remove = __devexit_p(gpio_ir_remove), + .driver = { + .name = GPIO_IR_NAME, + .owner = THIS_MODULE, + .of_match_table = of_gpio_ir_match, +#ifdef CONFIG_PM + .pm = &gpio_ir_pm_ops, +#endif + }, +}; + +static int __init gpio_ir_init(void) +{ + return platform_driver_register(&gpio_ir_driver); +} +module_init(gpio_ir_init); + +static void __exit gpio_ir_exit(void) +{ + platform_driver_unregister(&gpio_ir_driver); +} +module_exit(gpio_ir_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Xiang Xiao "); +MODULE_DESCRIPTION("GPIO IR driver"); diff --git a/drivers/media/rc/ir-dump-decoder.c b/drivers/media/rc/ir-dump-decoder.c new file mode 100644 index 000000000000..986847e7a49f --- /dev/null +++ b/drivers/media/rc/ir-dump-decoder.c @@ -0,0 +1,86 @@ +/* ir-dump-decoder.c - dump IR pulse/space signal + * + * Copyright (C) 2012 by Xiang Xiao + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "rc-core-priv.h" + +/** + * ir_dump_decode() - Dump one pulse or space signal + * @dev: the struct rc_dev descriptor of the device + * @duration: the struct ir_raw_event descriptor of the pulse/space + */ +static int ir_dump_decode(struct rc_dev *dev, struct ir_raw_event ev) +{ + const char *n = dev_name(&dev->dev) ?: "unknown"; + + if (ev.reset) + pr_info("%s: reset\n", n); + else if (ev.timeout) + pr_info("%s: timeout\t%uus\n", n, TO_US(ev.duration)); + else if (ev.carrier_report) + pr_info("%s: carrier\t%uHz(%u%%)\n", n, ev.carrier, ev.duty_cycle); + else + pr_info("%s: %s\t%uus\n", n, TO_STR(ev.pulse), TO_US(ev.duration)); + + return 0; +} + +static int ir_dump_register(struct rc_dev *dev) +{ + pr_info("%s: register(%s %s %s %s)\n", + dev_name(&dev->dev) ?: "unknown", + dev->driver_name ?: "unknown", + dev->map_name ?: "unknown", + dev->input_name ?: "unknown", + dev->input_phys ?: "unknown"); + return 0; +} + +static int ir_dump_unregister(struct rc_dev *dev) +{ + pr_info("%s: unregister(%s %s %s %s)\n", + dev_name(&dev->dev) ?: "unknown", + dev->driver_name ?: "unknown", + dev->map_name ?: "unknown", + dev->input_name ?: "unknown", + dev->input_phys ?: "unknown"); + return 0; +} + +static struct ir_raw_handler dump_handler = { + .protocols = RC_TYPE_OTHER, + .decode = ir_dump_decode, + .raw_register = ir_dump_register, + .raw_unregister = ir_dump_unregister, +}; + +static int __init ir_dump_decode_init(void) +{ + ir_raw_handler_register(&dump_handler); + pr_info("ir dump protocol handler initialized\n"); + return 0; +} + +static void __exit ir_dump_decode_exit(void) +{ + ir_raw_handler_unregister(&dump_handler); +} + +module_init(ir_dump_decode_init); +module_exit(ir_dump_decode_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Xiang Xiao "); +MODULE_DESCRIPTION("ir dump protocol decoder"); diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 98893a8332c7..b9d8c68b19d3 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -1,6 +1,7 @@ /* ir-lirc-codec.c - rc-core to classic lirc interface bridge * * Copyright (C) 2010 by Jarod Wilson + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +21,7 @@ #include #include "rc-core-priv.h" -#define LIRCBUF_SIZE 256 +#define LIRCBUF_SIZE 1024 /** * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the @@ -113,13 +114,14 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, unsigned int *txbuf; /* buffer with values to transmit */ ssize_t ret = -EINVAL; size_t count; +#ifndef CONFIG_IR_PWM ktime_t start; s64 towait; unsigned int duration = 0; /* signal duration in us */ int i; start = ktime_get(); - +#endif lirc = lirc_get_pdata(file); if (!lirc) return -EFAULT; @@ -145,7 +147,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, ret = -ENOSYS; goto out; } - +#ifndef CONFIG_IR_PWM for (i = 0; i < count; i++) { if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) { ret = -EINVAL; @@ -154,16 +156,16 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, duration += txbuf[i]; } - +#endif ret = dev->tx_ir(dev, txbuf, count); if (ret < 0) goto out; - +#ifndef CONFIG_IR_PWM for (duration = i = 0; i < ret; i++) duration += txbuf[i]; - +#endif ret *= sizeof(unsigned int); - +#ifndef CONFIG_IR_PWM /* * The lircd gap calculation expects the write function to * wait for the actual IR signal to be transmitted before @@ -174,7 +176,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(usecs_to_jiffies(towait)); } - +#endif out: kfree(txbuf); return ret; @@ -314,12 +316,31 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, static int ir_lirc_open(void *data) { - return 0; + + struct lirc_codec *lirc = data; + struct rc_dev *dev = lirc->dev; + int ret = 0; + + mutex_lock(&dev->lock); + if (!dev->open_count++ && dev->open) + ret = dev->open(dev); + if (ret < 0) + dev->open_count--; + mutex_unlock(&dev->lock); + + return ret; } static void ir_lirc_close(void *data) { - return; + + struct lirc_codec *lirc = data; + struct rc_dev *dev = lirc->dev; + + mutex_lock(&dev->lock); + if (!--dev->open_count && dev->close) + dev->close(dev); + mutex_unlock(&dev->lock); } static const struct file_operations lirc_fops = { @@ -387,7 +408,7 @@ static int ir_lirc_register(struct rc_dev *dev) drv->rbuf = rbuf; drv->set_use_inc = &ir_lirc_open; drv->set_use_dec = &ir_lirc_close; - drv->code_length = sizeof(struct ir_raw_event) * 8; + drv->code_length = sizeof(int) * 8; drv->fops = &lirc_fops; drv->dev = &dev->dev; drv->rdev = dev; @@ -404,6 +425,7 @@ static int ir_lirc_register(struct rc_dev *dev) return 0; lirc_register_failed: + lirc_buffer_free(rbuf); rbuf_init_failed: kfree(rbuf); rbuf_alloc_failed: @@ -418,6 +440,7 @@ static int ir_lirc_unregister(struct rc_dev *dev) lirc_unregister_driver(lirc->drv->minor); lirc_buffer_free(lirc->drv->rbuf); + kfree(lirc->drv->rbuf); kfree(lirc->drv); return 0; diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 249d2fbc8f37..59851cf3d98e 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -314,8 +314,7 @@ int lirc_register_driver(struct lirc_driver *d) /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; - bytes_in_key = BITS_TO_LONGS(d->code_length) + - (d->code_length % 8 ? 1 : 0); + bytes_in_key = (d->code_length + 7)/8; buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; diff --git a/drivers/media/rc/pwm-ir.c b/drivers/media/rc/pwm-ir.c new file mode 100644 index 000000000000..0b006a35cbd4 --- /dev/null +++ b/drivers/media/rc/pwm-ir.c @@ -0,0 +1,391 @@ +/* Copyright (C) 2013 by Xiang Xiao + * Copyright (C) 2017 XiaoMi, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +struct pwm_ir_dev { + struct mutex lock; + struct platform_device *pdev; + struct rc_dev *rdev; + struct regulator *reg; + struct pwm_device *pwm; + u32 carrier; + u32 duty_cycle; +}; + +struct pwm_ir_packet { + struct completion done; + struct hrtimer timer; + struct pwm_device *pwm; + bool abort; + unsigned int *buffer; + unsigned int length; + unsigned int next; +}; + +#define __devexit +#define __devinitdata +#define __devinit +#define __devexit_p + +/* code for ir transmit */ +static int pwm_ir_tx_config(struct pwm_ir_dev *dev, u32 carrier, u32 duty_cycle) +{ + int period_ns, duty_ns, rc; + + period_ns = NSEC_PER_SEC / carrier; + duty_ns = period_ns * duty_cycle / 100; + + rc = pwm_config(dev->pwm, duty_ns, period_ns); + if (rc == 0) { + dev->carrier = carrier; + dev->duty_cycle = duty_cycle; + } + + return rc; +} + +static int pwm_ir_tx_carrier(struct rc_dev *rdev, u32 carrier) +{ + struct pwm_ir_dev *dev = rdev->priv; + int rc; + + mutex_lock(&dev->lock); + rc = pwm_ir_tx_config(dev, carrier, dev->duty_cycle); + mutex_unlock(&dev->lock); + + return rc; +} + +static int pwm_ir_tx_duty_cycle(struct rc_dev *rdev, u32 duty_cycle) +{ + struct pwm_ir_dev *dev = rdev->priv; + int rc; + + mutex_lock(&dev->lock); + rc = pwm_ir_tx_config(dev, dev->carrier, duty_cycle); + mutex_unlock(&dev->lock); + + return rc; +} + +static enum hrtimer_restart pwm_ir_tx_timer(struct hrtimer *timer) +{ + struct pwm_ir_packet *pkt = container_of(timer, struct pwm_ir_packet, timer); + enum hrtimer_restart restart = HRTIMER_RESTART; + + if (!pkt->abort && pkt->next < pkt->length) { + u64 orun = hrtimer_forward_now(&pkt->timer, + ns_to_ktime(pkt->buffer[pkt->next++])); + if (orun > 1) + pr_warn("pwm-ir: lost %llu hrtimer callback\n", orun - 1); + + if (pkt->next & 0x01) + pwm_disable(pkt->pwm); + else /* pulse */ + pwm_enable(pkt->pwm); + } else { + restart = HRTIMER_NORESTART; + pwm_disable(pkt->pwm); + complete(&pkt->done); + } + + return restart; +} + +static int pwm_ir_tx_transmit_with_timer(struct pwm_ir_packet *pkt) +{ + int rc = 0; + + init_completion(&pkt->done); + + hrtimer_init(&pkt->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pkt->timer.function = pwm_ir_tx_timer; + + hrtimer_start(&pkt->timer, ns_to_ktime(0), HRTIMER_MODE_REL); + + rc = wait_for_completion_interruptible(&pkt->done); + if (rc != 0) { /* signal exit immediately */ + pkt->abort = true; + wait_for_completion(&pkt->done); + } + + return pkt->next ? : -ERESTARTSYS; +} + + +static long pwm_ir_tx_work(void *arg) +{ + struct pwm_ir_packet *pkt = arg; + unsigned long flags; + + /* disable irq for acurracy timing */ + local_irq_save(flags); + + for (; pkt->next < pkt->length; pkt->next++) { + if (signal_pending(current)) + break; + if (pkt->next & 0x01) + pwm_disable(pkt->pwm); + else /* pulse */ + pwm_enable(pkt->pwm); + + ndelay(pkt->buffer[pkt->next]%1000); + udelay(pkt->buffer[pkt->next]/1000); + } + + pwm_disable(pkt->pwm); + local_irq_restore(flags); + + return pkt->next ? : -ERESTARTSYS; +} + +static int pwm_ir_tx_transmit_with_delay(struct pwm_ir_packet *pkt) +{ + int cpu, rc = -ENODEV; + + for_each_online_cpu(cpu) { + /* select one auxilliary cpu to run */ + if (cpu != 0) { + rc = work_on_cpu(cpu, pwm_ir_tx_work, pkt); + break; + } + } + + if (rc == -ENODEV) { + pr_warn("pwm-ir: can't run on the auxilliary cpu\n"); + rc = pwm_ir_tx_work(pkt); + } + + return rc; +} + +static int pwm_ir_tx_transmit(struct rc_dev *rdev, unsigned *txbuf, unsigned n) +{ + struct pwm_ir_dev *dev = rdev->priv; + struct pwm_ir_data *data = dev->pdev->dev.platform_data; + struct pwm_ir_packet pkt = {}; + int i, rc = 0; + + for (i = 0; i < n; i++) + txbuf[i] *= NSEC_PER_USEC; + + mutex_lock(&dev->lock); + + if (dev->reg) { + rc = regulator_enable(dev->reg); + if (rc != 0) + goto err_regulator_enable; + } + + pkt.pwm = dev->pwm; + pkt.buffer = txbuf; + pkt.length = n; + + if (data->use_timer) + rc = pwm_ir_tx_transmit_with_timer(&pkt); + else + rc = pwm_ir_tx_transmit_with_delay(&pkt); + + if (dev->reg) + regulator_disable(dev->reg); +err_regulator_enable: + mutex_unlock(&dev->lock); + return rc; +} + +static int __devinit pwm_ir_tx_probe(struct pwm_ir_dev *dev) +{ + struct pwm_ir_data *data = dev->pdev->dev.platform_data; + struct platform_device *pdev = dev->pdev; + int rc = 0; + + if (data->reg_id) { + dev->reg = regulator_get(&dev->pdev->dev, data->reg_id); + if (IS_ERR(dev->reg)) { + dev_err(&dev->pdev->dev, + "failed to regulator_get(%s)\n", + data->reg_id); + return PTR_ERR(dev->reg); + } + } + + + dev->pwm = of_pwm_get(pdev->dev.of_node, NULL); + if (IS_ERR(dev->pwm)) { + dev_err(&dev->pdev->dev, + "failed to of_pwm_get()\n"); + rc = PTR_ERR(dev->pwm); + dev_err(&dev->pdev->dev, "Cannot get PWM device rc:(%d)\n", rc); + dev->pwm = NULL; + goto err_regulator_put; + } + + if (data->low_active) { + rc = -ENOSYS; + if (rc != 0) { + dev_err(&dev->pdev->dev, "failed to change polarity\n"); + goto err_pwm_free; + } + } + rc = pwm_ir_tx_config(dev, 38000, 50); + if (rc != 0) { + dev_err(&dev->pdev->dev, "failed to change carrier and duty\n"); + goto err_pwm_free; + } + dev->rdev->tx_ir = pwm_ir_tx_transmit; + dev->rdev->s_tx_carrier = pwm_ir_tx_carrier; + dev->rdev->s_tx_duty_cycle = pwm_ir_tx_duty_cycle; + + return rc; + +err_pwm_free: + pwm_free(dev->pwm); +err_regulator_put: + if (dev->reg) + regulator_put(dev->reg); + return rc; +} + +static void pwm_ir_tx_remove(struct pwm_ir_dev *dev) +{ + if (dev->reg) + regulator_put(dev->reg); + pwm_free(dev->pwm); +} + +/* code for probe and remove */ +static int __devinit pwm_ir_probe(struct platform_device *pdev) +{ + struct pwm_ir_dev *dev; + int rc = -ENOMEM; + + if (!pdev->dev.platform_data) { + pdev->dev.platform_data = devm_kzalloc(&pdev->dev, sizeof(struct pwm_ir_data), GFP_KERNEL); + if (pdev->dev.platform_data) { + if (pdev->dev.of_node) { + struct pwm_ir_data *data = pdev->dev.platform_data; + + of_property_read_string(pdev->dev.of_node, "reg-id", &data->reg_id); + + data->low_active = of_property_read_bool(pdev->dev.of_node, "low-active"); + data->use_timer = of_property_read_bool(pdev->dev.of_node, "use-timer"); + + dev_info(&pdev->dev, + "reg-id = %s, low-active = %d, use-timer = %d\n", + data->reg_id, data->low_active, data->use_timer); + } + } else { + dev_err(&pdev->dev, "failed to alloc platform data\n"); + return -ENOMEM; + } + } + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + dev_err(&pdev->dev, "failed to alloc dev\n"); + return rc; + } + + mutex_init(&dev->lock); + + dev->pdev = pdev; + platform_set_drvdata(pdev, dev); + + dev->rdev = rc_allocate_device(); + if (!dev->rdev) { + dev_err(&pdev->dev, "failed to alloc rdev\n"); + goto err_rc_allocate_device; + } + + dev->rdev->dev.parent = &pdev->dev; + dev->rdev->input_name = PWM_IR_NAME; + dev->rdev->input_phys = PWM_IR_NAME; + dev->rdev->input_id.bustype = BUS_HOST; + dev->rdev->driver_name = PWM_IR_NAME; + dev->rdev->map_name = RC_MAP_LIRC; + dev->rdev->driver_type = RC_DRIVER_IR_RAW; + dev->rdev->priv = dev; + + rc = pwm_ir_tx_probe(dev); + if (rc != 0) + goto err_pwm_ir_tx_probe; + + rc = rc_register_device(dev->rdev); + if (rc < 0) { + dev_err(&pdev->dev, "failed to register rdev\n"); + goto err_rc_register_device; + } + + return rc; + +err_rc_register_device: + pwm_ir_tx_remove(dev); +err_pwm_ir_tx_probe: + rc_free_device(dev->rdev); +err_rc_allocate_device: + kfree(dev); + return rc; +} + +static int __devexit pwm_ir_remove(struct platform_device *pdev) +{ + struct pwm_ir_dev *dev = platform_get_drvdata(pdev); + + rc_unregister_device(dev->rdev); + pwm_ir_tx_remove(dev); + kfree(dev); + + return 0; +} + +/* code for init and exit */ +static const struct of_device_id of_pwm_ir_match[] = { + {.compatible = PWM_IR_NAME,}, + {}, +}; + +static struct platform_driver pwm_ir_driver = { + .probe = pwm_ir_probe, + .remove = __devexit_p(pwm_ir_remove), + .driver = { + .name = PWM_IR_NAME, + .owner = THIS_MODULE, + .of_match_table = of_pwm_ir_match, + }, +}; + +static int __init pwm_ir_init(void) +{ + return platform_driver_register(&pwm_ir_driver); +} +late_initcall(pwm_ir_init); + +static void __exit pwm_ir_exit(void) +{ + platform_driver_unregister(&pwm_ir_driver); +} +module_exit(pwm_ir_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Xiang Xiao "); +MODULE_DESCRIPTION("PWM IR driver"); diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index b732ac6a26d8..d50a954b7619 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -1,6 +1,7 @@ /* rc-ir-raw.c - handle IR pulse/space events * * Copyright (C) 2010 by Mauro Carvalho Chehab + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -104,6 +105,12 @@ EXPORT_SYMBOL_GPL(ir_raw_event_store); * (or similar events) on state change. */ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) +{ + return ir_raw_event_store_edge_with_adjust(dev, type, 0); +} +EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); + +int ir_raw_event_store_edge_with_adjust(struct rc_dev *dev, enum raw_event_type type, s32 ns) { ktime_t now; s64 delta; /* ns */ @@ -114,7 +121,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) if (!dev->raw) return -EINVAL; - now = ktime_get(); + now = ktime_add_ns(ktime_get(), ns); delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]); @@ -142,7 +149,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) dev->raw->last_type = type; return rc; } -EXPORT_SYMBOL_GPL(ir_raw_event_store_edge); +EXPORT_SYMBOL_GPL(ir_raw_event_store_edge_with_adjust); /** * ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b4ceda856939..5f4c87ffb42b 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1,6 +1,7 @@ /* rc-main.c - Remote Controller core module * * Copyright (C) 2009-2010 by Mauro Carvalho Chehab + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -738,7 +739,17 @@ static int ir_open(struct input_dev *idev) { struct rc_dev *rdev = input_get_drvdata(idev); - return rc_open(rdev); + + int rc = 0; + + mutex_lock(&rdev->lock); + if (!rdev->open_count++) + rc = rdev->open(rdev); + if (rc < 0) + rdev->open_count--; + mutex_unlock(&rdev->lock); + + return rc; } void rc_close(struct rc_dev *rdev) @@ -757,7 +768,14 @@ EXPORT_SYMBOL_GPL(rc_close); static void ir_close(struct input_dev *idev) { struct rc_dev *rdev = input_get_drvdata(idev); - rc_close(rdev); + + + if (rdev) { + mutex_lock(&rdev->lock); + if (!--rdev->open_count) + rdev->close(rdev); + mutex_unlock(&rdev->lock); + } } /* class for /sys/class/rc */ diff --git a/include/media/gpio-ir.h b/include/media/gpio-ir.h new file mode 100644 index 000000000000..c986439930bf --- /dev/null +++ b/include/media/gpio-ir.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2012 by Xiang Xiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __GPIO_IR_H__ +#define __GPIO_IR_H__ + +#define GPIO_IR_NAME "gpio-ir" + +struct gpio_ir_data { + const char *tx_reg_id; + unsigned int tx_gpio_nr; + bool tx_high_active; + bool tx_soft_carrier; + bool tx_disable_rx; + bool tx_with_timer; + const char *rx_reg_id; + unsigned int rx_gpio_nr; + bool rx_high_active; + bool rx_soft_carrier; + u64 rx_init_protos; + bool rx_can_wakeup; + const char *rx_map_name; +}; + +#endif /* __GPIO_IR_H__ */ diff --git a/include/media/pwm-ir.h b/include/media/pwm-ir.h new file mode 100644 index 000000000000..8df893d8319c --- /dev/null +++ b/include/media/pwm-ir.h @@ -0,0 +1,25 @@ +/* Copyright (C) 2013 by Xiang Xiao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __PWM_IR_H__ +#define __PWM_IR_H__ + +#define PWM_IR_NAME "pwm-ir" + +struct pwm_ir_data { + const char *reg_id; + int pwm_id; + bool low_active; + bool use_timer; +}; + +#endif /* __PWM_IR_H__ */ diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 2c7fbca40b69..d00dbd8cc388 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -156,6 +156,7 @@ struct rc_dev { u32 max_timeout; u32 rx_resolution; u32 tx_resolution; + u32 open_count; int (*change_protocol)(struct rc_dev *dev, u64 *rc_type); int (*change_wakeup_protocol)(struct rc_dev *dev, u64 *rc_type); int (*open)(struct rc_dev *dev); @@ -247,6 +248,8 @@ static inline void init_ir_raw_event(struct ir_raw_event *ev) void ir_raw_event_handle(struct rc_dev *dev); int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type); +int ir_raw_event_store_edge_with_adjust(struct rc_dev *dev, + enum raw_event_type type, s32 ns); int ir_raw_event_store_with_filter(struct rc_dev *dev, struct ir_raw_event *ev); void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); From 7ea8984bdf55eddc53261346514a8917a3a13480 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 09:05:47 +0000 Subject: [PATCH 52/86] mido: Initial Lineage Defconfig --- arch/arm64/configs/mido_defconfig | 4583 +++++++++++++++++++++++++++++ 1 file changed, 4583 insertions(+) create mode 100644 arch/arm64/configs/mido_defconfig diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig new file mode 100644 index 000000000000..df7fe26cbde5 --- /dev/null +++ b/arch/arm64/configs/mido_defconfig @@ -0,0 +1,4583 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm64 3.18.31 Kernel Configuration +# +CONFIG_ARM64=y +CONFIG_64BIT=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=18 +CONFIG_ARCH_MMAP_RND_BITS_MAX=24 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CSUM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y +CONFIG_HAVE_GENERIC_RCU_GUP=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_ARM64_DMA_USE_IOMMU=y +CONFIG_ARM64_DMA_IOMMU_ALIGNMENT=8 +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_KERNEL_MODE_NEON=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_PGTABLE_LEVELS=3 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="-perf" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +# CONFIG_FHANDLE is not set +CONFIG_USELIB=y +CONFIG_AUDIT=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_WATCH=y +CONFIG_AUDIT_TREE=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_SPARSE_IRQ=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +# CONFIG_TICK_CPU_ACCOUNTING is not set +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +CONFIG_IRQ_TIME_ACCOUNTING=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +# CONFIG_RCU_USER_QS is not set +CONFIG_RCU_FANOUT=64 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +CONFIG_RCU_FAST_NO_HZ=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +CONFIG_RCU_NOCB_CPU=y +# CONFIG_RCU_NOCB_CPU_NONE is not set +# CONFIG_RCU_NOCB_CPU_ZERO is not set +CONFIG_RCU_NOCB_CPU_ALL=y +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +# CONFIG_IKCONFIG_PROC is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_CONSOLE_FLUSH_ON_HOTPLUG is not set +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=y +# CONFIG_MEMCG_KMEM is not set +# CONFIG_CGROUP_PERF is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +# CONFIG_BLK_CGROUP is not set +CONFIG_SCHED_HMP=y +# CONFIG_SCHED_HMP_CSTATE_AWARE is not set +# CONFIG_SCHED_CORE_CTL is not set +# CONFIG_SCHED_QHMP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_BPF=y +CONFIG_EXPERT=y +CONFIG_UID16=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +# CONFIG_BPF_SYSCALL is not set +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_PCI_QUIRKS=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR_NONE is not set +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +CONFIG_CC_STACKPROTECTOR_STRONG=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_ARCH_MMAP_RND_BITS=18 +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y +CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=y +CONFIG_MODULE_SIG_ALL=y +# CONFIG_MODULE_SIG_SHA1 is not set +# CONFIG_MODULE_SIG_SHA224 is not set +# CONFIG_MODULE_SIG_SHA256 is not set +# CONFIG_MODULE_SIG_SHA384 is not set +CONFIG_MODULE_SIG_SHA512=y +CONFIG_MODULE_SIG_HASH="sha512" +# CONFIG_MODULE_COMPRESS is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_CMDLINE_PARSER is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_TEST=m +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_ASN1=y +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Platform selection +# +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_XGENE is not set +CONFIG_ARCH_MSM=y +CONFIG_ARCH_MSM8916=y +# CONFIG_ARCH_MSM8917 is not set +# CONFIG_ARCH_MSM8920 is not set +CONFIG_ARCH_MSM8940=y +CONFIG_ARCH_MSM8953=y +CONFIG_ARCH_MSM8937=y +# CONFIG_ARCH_MSM8996 is not set +CONFIG_ARCH_MSMCOBALT=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set +CONFIG_PCI_MSM=y +CONFIG_PCI_LABEL=y + +# +# PCI host controller drivers +# +# CONFIG_PCI_HOST_GENERIC is not set +# CONFIG_PCIEPORTBUS is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# Kernel Features +# + +# +# ARM errata workarounds via the alternatives framework +# +CONFIG_ARM64_ERRATUM_826319=y +CONFIG_ARM64_ERRATUM_827319=y +CONFIG_ARM64_ERRATUM_824069=y +CONFIG_ARM64_ERRATUM_819472=y +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_845719=y +CONFIG_ARM64_4K_PAGES=y +# CONFIG_ARM64_64K_PAGES is not set +# CONFIG_ARM64_DCACHE_DISABLE is not set +# CONFIG_ARM64_ICACHE_DISABLE is not set +CONFIG_ARCH_MSM8953_SOC_SETTINGS=y +CONFIG_ARM64_VA_BITS_39=y +CONFIG_ARM64_VA_BITS=39 +CONFIG_ARM64_PGTABLE_LEVELS=3 +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_ARM64_SEV_IN_LOCK_UNLOCK is not set +CONFIG_SMP=y +CONFIG_SCHED_MC=y +# CONFIG_SCHED_SMT is not set +CONFIG_NR_CPUS=8 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_NR_GPIO=1024 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HW_PERF_EVENTS=y +# CONFIG_PERF_EVENTS_USERMODE is not set +# CONFIG_PERF_EVENTS_RESET_PMU_DEBUGFS is not set +# CONFIG_ARM64_REG_REBALANCE_ON_CTX_SW is not set +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_TRANSPARENT_HUGEPAGE is not set +CONFIG_CLEANCACHE=y +# CONFIG_FRONTSWAP is not set +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +CONFIG_CMA_DEBUGFS=y +CONFIG_CMA_AREAS=7 +# CONFIG_ZPOOL is not set +CONFIG_ZBUD=y +CONFIG_ZSMALLOC=y +# CONFIG_PGTABLE_MAPPING is not set +# CONFIG_ZSMALLOC_STAT is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_ZCACHE=y +# CONFIG_BALANCE_ANON_FILE_RECLAIM is not set +CONFIG_KSWAPD_CPU_AFFINITY_MASK="" +# CONFIG_FORCE_ALLOC_FROM_DMA_ZONE is not set +CONFIG_PROCESS_RECLAIM=y +CONFIG_SECCOMP=y +# CONFIG_XEN is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ARM64_PAN=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y + +# +# Boot options +# +CONFIG_CMDLINE="" +CONFIG_EFI_STUB=y +CONFIG_EFI=y +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y +CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES="" +CONFIG_DMI=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y +CONFIG_COMPAT=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_WAKELOCK=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PM_WAKELOCKS_LIMIT=0 +# CONFIG_PM_WAKELOCKS_GC is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_DPM_WATCHDOG is not set +CONFIG_PM_OPP=y +CONFIG_PM_CLK=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_CPU_PM=y +CONFIG_SUSPEND_TIME=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM64_CPU_SUSPEND=y + +# +# CPU Power Management +# + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# ARM64 CPU Idle Drivers +# +# CONFIG_ARM64_CPUIDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_SCHED_FREQ_INPUT=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPUFREQ_DT is not set +# CONFIG_CPU_BOOST is not set + +# +# ARM CPU frequency scaling drivers +# +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set +CONFIG_CPU_FREQ_MSM=y +CONFIG_ARM64_ERRATUM_843419=y +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y +# CONFIG_DISABLE_NET_SKB_FRAG_CACHE is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=y +# CONFIG_IP_MROUTE is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_NET_IPVTI is not set +CONFIG_NET_UDP_TUNNEL=y +# CONFIG_NET_FOU is not set +# CONFIG_GENEVE is not set +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_XFRM_TUNNEL=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +CONFIG_INET_DIAG_DESTROY=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_VTI is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_GRE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETLABEL is not set +CONFIG_ANDROID_PARANOID_NETWORK=y +CONFIG_NET_ACTIVITY_STATS=y +CONFIG_NETWORK_SECMARK=y +# CONFIG_NET_PTP_CLASSIFY is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_LOG_COMMON=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +# CONFIG_NF_CONNTRACK_ZONES is not set +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_BROADCAST=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +# CONFIG_NF_CONNTRACK_SNMP is not set +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PROTO_DCCP=y +CONFIG_NF_NAT_PROTO_UDPLITE=y +CONFIG_NF_NAT_PROTO_SCTP=y +CONFIG_NF_NAT_AMANDA=y +CONFIG_NF_NAT_FTP=y +CONFIG_NF_NAT_IRC=y +# CONFIG_NF_NAT_SIP is not set +CONFIG_NF_NAT_TFTP=y +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_CT=y +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y +# CONFIG_NETFILTER_XT_TARGET_LED is not set +CONFIG_NETFILTER_XT_TARGET_LOG=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_NAT=y +CONFIG_NETFILTER_XT_TARGET_NETMAP=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_NOTRACK=y +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +CONFIG_NETFILTER_XT_TARGET_REDIRECT=y +CONFIG_NETFILTER_XT_TARGET_TEE=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +CONFIG_NETFILTER_XT_MATCH_DSCP=y +CONFIG_NETFILTER_XT_MATCH_ECN=y +CONFIG_NETFILTER_XT_MATCH_ESP=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_HL=y +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_L2TP=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=y +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_QTAGUID=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2=y +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_LOG_ARP is not set +CONFIG_NF_LOG_IPV4=y +CONFIG_NF_REJECT_IPV4=y +CONFIG_NF_NAT_IPV4=y +CONFIG_NF_NAT_MASQUERADE_IPV4=y +CONFIG_NF_NAT_PROTO_GRE=y +CONFIG_NF_NAT_PPTP=y +CONFIG_NF_NAT_H323=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NATTYPE_MODULE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_NF_REJECT_IPV6=y +CONFIG_NF_LOG_IPV6=y +# CONFIG_NF_NAT_IPV6 is not set +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +# CONFIG_IP6_NF_SECURITY is not set +# CONFIG_IP6_NF_NAT is not set +CONFIG_BRIDGE_NF_EBTABLES=y +CONFIG_BRIDGE_EBT_BROUTE=y +# CONFIG_BRIDGE_EBT_T_FILTER is not set +# CONFIG_BRIDGE_EBT_T_NAT is not set +# CONFIG_BRIDGE_EBT_802_3 is not set +# CONFIG_BRIDGE_EBT_AMONG is not set +# CONFIG_BRIDGE_EBT_ARP is not set +# CONFIG_BRIDGE_EBT_IP is not set +# CONFIG_BRIDGE_EBT_IP6 is not set +# CONFIG_BRIDGE_EBT_LIMIT is not set +# CONFIG_BRIDGE_EBT_MARK is not set +# CONFIG_BRIDGE_EBT_PKTTYPE is not set +# CONFIG_BRIDGE_EBT_STP is not set +# CONFIG_BRIDGE_EBT_VLAN is not set +# CONFIG_BRIDGE_EBT_ARPREPLY is not set +# CONFIG_BRIDGE_EBT_DNAT is not set +# CONFIG_BRIDGE_EBT_MARK_T is not set +# CONFIG_BRIDGE_EBT_REDIRECT is not set +# CONFIG_BRIDGE_EBT_SNAT is not set +# CONFIG_BRIDGE_EBT_LOG is not set +# CONFIG_BRIDGE_EBT_NFLOG is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_L2TP=y +CONFIG_L2TP_DEBUGFS=y +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=y +CONFIG_L2TP_ETH=y +CONFIG_STP=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_HAVE_NET_DSA=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +CONFIG_NET_SCH_HTB=y +# CONFIG_NET_SCH_HFSC is not set +CONFIG_NET_SCH_PRIO=y +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +# CONFIG_NET_SCH_CODEL is not set +# CONFIG_NET_SCH_FQ_CODEL is not set +# CONFIG_NET_SCH_FQ is not set +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_PIE is not set +# CONFIG_NET_SCH_INGRESS is not set +# CONFIG_NET_SCH_PLUG is not set + +# +# Classification +# +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +CONFIG_NET_CLS_FW=y +CONFIG_NET_CLS_U32=y +# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_MARK=y +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +CONFIG_NET_CLS_FLOW=y +# CONFIG_NET_CLS_CGROUP is not set +# CONFIG_NET_CLS_BPF is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=y +CONFIG_NET_EMATCH_NBYTE=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_EMATCH_META=y +CONFIG_NET_EMATCH_TEXT=y +CONFIG_NET_CLS_ACT=y +# CONFIG_NET_ACT_POLICE is not set +# CONFIG_NET_ACT_GACT is not set +# CONFIG_NET_ACT_MIRRED is not set +# CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +# CONFIG_NET_ACT_CSUM is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +# CONFIG_DNS_RESOLVER is not set +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_MMAP is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_NET_MPLS_GSO is not set +# CONFIG_HSR is not set +CONFIG_RMNET_DATA=y +CONFIG_RMNET_DATA_FC=y +CONFIG_RMNET_DATA_DEBUG_PKT=y +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y +CONFIG_SOCKEV_NLMCAST=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +# CONFIG_BT_HCIUART is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +CONFIG_MSM_BT_POWER=y +# CONFIG_BTFM_SLIM is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_INTERNAL_REGDB=y +# CONFIG_CFG80211_WEXT is not set +# CONFIG_LIB80211 is not set +# CONFIG_MAC80211 is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +CONFIG_NFC_NQ=y +CONFIG_IPC_ROUTER=y +CONFIG_IPC_ROUTER_SECURITY=y +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_HAVE_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_SOC_BUS=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_SWR=y +CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_FENCE_TRACE is not set +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 + +# +# Bus devices +# +# CONFIG_ARM_CCN is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_DTC=y +CONFIG_OF=y + +# +# Device Tree and Open Firmware support +# +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_ADDRESS_PCI=y +CONFIG_OF_IRQ=y +CONFIG_OF_NET=y +CONFIG_OF_MDIO=y +CONFIG_OF_PCI=y +CONFIG_OF_PCI_IRQ=y +CONFIG_OF_SPMI=y +CONFIG_OF_RESERVED_MEM=y +CONFIG_OF_SLIMBUS=y +CONFIG_OF_CORESIGHT=y +CONFIG_OF_BATTERYDATA=y +# CONFIG_OF_OVERLAY is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +CONFIG_ZRAM=y +# CONFIG_ZRAM_LZ4_COMPRESS is not set +# CONFIG_ZRAM_DEBUG is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_NVME is not set +# CONFIG_BLK_DEV_SKD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set + +# +# Misc devices +# +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +CONFIG_UID_STAT=y +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +CONFIG_QSEECOM=y +CONFIG_HDCP_QSEECOM=y +CONFIG_UID_CPUTIME=y +CONFIG_USB_EXT_TYPE_C_PERICOM=y +# CONFIG_USB_EXT_TYPE_C_TI is not set +# CONFIG_TI_DRV2667 is not set +# CONFIG_QPNP_MISC is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +CONFIG_MSM_QDSP6V2_CODECS=y +CONFIG_MSM_ULTRASOUND=y + +# +# Intel MIC Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# +# CONFIG_GENWQE is not set +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +CONFIG_HQ_SYSFS_SUPPORT=y + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +CONFIG_SCSI_UFSHCD=y +# CONFIG_SCSI_UFSHCD_PCI is not set +CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_QCOM=y +CONFIG_SCSI_UFS_QCOM_ICE=y +CONFIG_SCSI_UFS_TEST=m +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_HAVE_PATA_PLATFORM=y +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_BUFIO=y +CONFIG_DM_CRYPT=y +CONFIG_DM_REQ_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_CACHE is not set +# CONFIG_DM_ERA is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +# CONFIG_DM_FLAKEY is not set +CONFIG_DM_VERITY=y +# CONFIG_DM_ANDROID_VERITY is not set +CONFIG_DM_VERITY_FEC=y +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +# CONFIG_I2O is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +CONFIG_DUMMY=y +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_VXLAN is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_TUN=y +CONFIG_VETH=y +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +# CONFIG_NET_DSA_MV88E6123_61_65 is not set +# CONFIG_NET_DSA_MV88E6171 is not set +# CONFIG_NET_DSA_BCM_SF2 is not set +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +# CONFIG_AMD_XGBE is not set +# CONFIG_NET_XGENE is not set +CONFIG_NET_VENDOR_ARC=y +# CONFIG_ARC_EMAC is not set +# CONFIG_EMAC_ROCKCHIP is not set +CONFIG_NET_VENDOR_ATHEROS=y +# CONFIG_ATL2 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BCMGENET is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2X is not set +# CONFIG_SYSTEMPORT is not set +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EXAR=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_FM10K is not set +CONFIG_NET_VENDOR_I825XX=y +# CONFIG_IP1000 is not set +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MLX5_CORE is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_ECM_IPA is not set +CONFIG_RNDIS_IPA=y +# CONFIG_MSM_RMNET_BAM is not set +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_8390=y +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_PACKET_ENGINE=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +CONFIG_NET_VENDOR_QUALCOMM=y +# CONFIG_QCA7000 is not set +# CONFIG_QCOM_EMAC is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R8169 is not set +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +# CONFIG_SFC is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_AMD_XGBE_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM7XXX_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MDIO_BUS_MUX_GPIO is not set +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=y +CONFIG_PPPOL2TP=y +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y +CONFIG_USB_NET_DRIVERS=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_CDC_EEM is not set +CONFIG_USB_NET_CDC_NCM=y +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set +# CONFIG_USB_NET_CDC_MBIM is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9700 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=y +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +CONFIG_USB_NET_CDC_SUBSET=y +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +# CONFIG_USB_EPSON2888 is not set +# CONFIG_USB_KC2190 is not set +CONFIG_USB_NET_ZAURUS=y +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +# CONFIG_USBNET_IPA_BRIDGE is not set +CONFIG_WLAN=y +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_WIFI_CONTROL_FUNC is not set +CONFIG_WCNSS_CORE=y +CONFIG_WCNSS_CORE_PRONTO=y +CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y +CONFIG_WCNSS_MEM_PRE_ALLOC=y +# CONFIG_WCNSS_SKB_PRE_ALLOC is not set +CONFIG_CNSS_CRYPTO=y +CONFIG_ATH_CARDS=y +# CONFIG_ATH_DEBUG is not set +# CONFIG_ATH5K_PCI is not set +# CONFIG_ATH6KL is not set +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +CONFIG_WIL6210_TRACING=y +# CONFIG_WIL6210_WRITE_IOCTL is not set +CONFIG_WIL6210_PLATFORM_MSM=y +# CONFIG_BRCMFMAC is not set +# CONFIG_HOSTAP is not set +# CONFIG_IPW2100 is not set +# CONFIG_LIBERTAS is not set +# CONFIG_WL_TI is not set +# CONFIG_MWIFIEX is not set +# CONFIG_CNSS is not set +# CONFIG_CLD_DEBUG is not set +# CONFIG_CLD_HL_SDIO_CORE is not set +CONFIG_CLD_LL_CORE=y +# CONFIG_CNSS_LOGGER is not set +# CONFIG_WLAN_FEATURE_RX_WAKELOCK is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_KEYRESET=y +CONFIG_INPUT_KEYCOMBO=y + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_CAP1106 is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=y +# CONFIG_JOYSTICK_XPAD_FF is not set +# CONFIG_JOYSTICK_XPAD_LEDS is not set +CONFIG_INPUT_TABLET=y +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_SERIAL_WACOM4 is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v21=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21=y +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_SPI_v21 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 is not set +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v26=y +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C_v26=y +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_SPI_v26 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_HID_I2C_v26 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26 is not set +# CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26 is not set +CONFIG_OF_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH_TS is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_SUR40 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZFORCE is not set +# CONFIG_TOUCHSCREEN_MSTAR21XX is not set +# CONFIG_SECURE_TOUCH is not set +# CONFIG_TOUCHSCREEN_IT7260_I2C is not set +# CONFIG_TOUCHSCREEN_GEN_VKEYS is not set +# CONFIG_TOUCHSCREEN_FT5X06 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +CONFIG_TOUCHSCREEN_FT5435=y +CONFIG_TOUCHSCREEN_IST3038C=y +CONFIG_TOUCHSCREEN_GT9XX=y +# CONFIG_TOUCHSCREEN_MAXIM_STI is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +CONFIG_INPUT_HBTP_INPUT=y +# CONFIG_HBTP_INPUT_SECURE_TOUCH is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_BEEPER is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +CONFIG_INPUT_KEYCHORD=y +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +# CONFIG_INPUT_DRV260X_HAPTICS is not set +# CONFIG_INPUT_DRV2667_HAPTICS is not set +CONFIG_INPUT_FINGERPRINT=y +CONFIG_FINGERPRINT_GOODIX_GF3208=y +CONFIG_FINGERPRINT_FPC1020=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_SERIO_APBPS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +# CONFIG_DEVMEM is not set +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +# CONFIG_SERIAL_AMBA_PL011 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_MFD_HSU is not set +CONFIG_SERIAL_CORE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_MSM_HS=y +# CONFIG_SERIAL_MSM_HSL is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +CONFIG_SERIAL_MSM_SMD=y +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set + +# +# Diag Support +# +CONFIG_DIAG_CHAR=y + +# +# DIAG traffic over USB +# +CONFIG_DIAG_OVER_USB=y + +# +# HSIC/SMUX support for DIAG +# +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_MSM_LEGACY=y +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# PCMCIA character devices +# +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_MSM_SMD_PKT=y +# CONFIG_XILLYBUS is not set +CONFIG_MSM_ADSPRPC=y +# CONFIG_MSM_MDSP_TS is not set +CONFIG_MSM_RDBG=m + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +# CONFIG_I2C_MUX_PINCTRL is not set +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set +# CONFIG_I2C_MSM_QUP is not set +CONFIG_I2C_MSM_V2=y + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SLIMBUS=y +# CONFIG_SLIMBUS_MSM_CTRL is not set +CONFIG_SLIMBUS_MSM_NGD=y +CONFIG_SOUNDWIRE=y +CONFIG_SOUNDWIRE_WCD_CTRL=y +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_ROCKCHIP is not set +CONFIG_SPI_QUP=y +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +# CONFIG_PTP_1588_CLOCK is not set + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_MSM=y +# CONFIG_PINCTRL_APQ8064 is not set +# CONFIG_PINCTRL_MDM9607 is not set +# CONFIG_PINCTRL_MDM9640 is not set +# CONFIG_PINCTRL_MDMCALIFORNIUM is not set +# CONFIG_PINCTRL_APQ8084 is not set +# CONFIG_PINCTRL_IPQ8064 is not set +# CONFIG_PINCTRL_MSM8960 is not set +# CONFIG_PINCTRL_MSM8X74 is not set +CONFIG_PINCTRL_MSM8952=y +CONFIG_PINCTRL_MSM8937=y +CONFIG_PINCTRL_MSMCOBALT=y +CONFIG_PINCTRL_MSM8940=y +CONFIG_PINCTRL_MSM8953=y +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_OF_GPIO=y +CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_PL061 is not set +CONFIG_GPIO_QPNP_PIN=y +# CONFIG_GPIO_QPNP_PIN_DEBUG is not set +# CONFIG_GPIO_SCH311X is not set +# CONFIG_GPIO_XGENE is not set +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_GRGPIO is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set + +# +# PCI GPIO expanders: +# +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# LPC GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# + +# +# USB GPIO expanders: +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_SMB349_USB_CHARGER is not set +# CONFIG_SMB349_DUAL_CHARGER is not set +CONFIG_SMB1351_USB_CHARGER=y +# CONFIG_SMB350_CHARGER is not set +CONFIG_SMB135X_CHARGER=y +# CONFIG_SMB1360_CHARGER_FG is not set +# CONFIG_SMB358_CHARGER is not set +# CONFIG_SMB23X_CHARGER is not set +# CONFIG_BATTERY_BQ28400 is not set +# CONFIG_QPNP_CHARGER is not set +CONFIG_QPNP_SMBCHARGER=y +# CONFIG_FUELGAUGE_STC3117 is not set +CONFIG_QPNP_FG=y +CONFIG_BATTERY_BCL=y +# CONFIG_QPNP_VM_BMS is not set +# CONFIG_QPNP_BMS is not set +# CONFIG_QPNP_LINEAR_CHARGER is not set +CONFIG_QPNP_TYPEC=y +CONFIG_MSM_BCL_CTL=y +CONFIG_MSM_BCL_PERIPHERAL_CTL=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_GPIO is not set +# CONFIG_POWER_RESET_GPIO_RESTART is not set +# CONFIG_POWER_RESET_LTC2952 is not set +CONFIG_POWER_RESET_MSM=y +# CONFIG_MSM_DLOAD_MODE is not set +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_POWER_RESET_SYSCON is not set +# CONFIG_POWER_AVS is not set +CONFIG_MSM_PM=y +CONFIG_APSS_CORE_EA=y +CONFIG_MSM_APM=y +CONFIG_MSM_IDLE_STATS=y +CONFIG_MSM_IDLE_STATS_FIRST_BUCKET=62500 +CONFIG_MSM_IDLE_STATS_BUCKET_SHIFT=2 +CONFIG_MSM_IDLE_STATS_BUCKET_COUNT=10 +CONFIG_MSM_SUSPEND_STATS_FIRST_BUCKET=1000000000 +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_POWR1220 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4222 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4260 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_NCT6683 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_PCF8591 is not set +CONFIG_SENSORS_EPM_ADC=y +CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y +CONFIG_SENSORS_QPNP_ADC_CURRENT=y +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_PWM_FAN is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SHTC1 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_ADC128D818 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +# CONFIG_THERMAL_GOV_BANG_BANG is not set +# CONFIG_THERMAL_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set +# CONFIG_CPU_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +CONFIG_THERMAL_TSENS8974=y +CONFIG_LIMITS_MONITOR=y +CONFIG_LIMITS_LITE_HW=y +CONFIG_THERMAL_MONITOR=y +CONFIG_THERMAL_QPNP=y +CONFIG_THERMAL_QPNP_ADC_TM=y + +# +# Texas Instruments thermal drivers +# +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_AXP20X is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_INTEL_SOC_PMIC is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_I2C_PMIC is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RTSX_PCI is not set +# CONFIG_MFD_RTSX_USB is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK808 is not set +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_SYSCON is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_WCD9306_CODEC is not set +# CONFIG_WCD9320_CODEC is not set +# CONFIG_WCD9330_CODEC is not set +CONFIG_WCD9335_CODEC=y +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_PROXY_CONSUMER is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +CONFIG_REGULATOR_STUB=y +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_MSM_GFX_LDO=y +# CONFIG_REGULATOR_GPIO is not set +# CONFIG_REGULATOR_ISL9305 is not set +CONFIG_REGULATOR_MEM_ACC=y +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PWM is not set +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS6524X is not set +CONFIG_REGULATOR_RPM_SMD=y +CONFIG_REGULATOR_QPNP=y +CONFIG_REGULATOR_QPNP_LABIBB=y +CONFIG_REGULATOR_SPM=y +CONFIG_REGULATOR_CPR=y +# CONFIG_REGULATOR_CPR2_GFX is not set +CONFIG_REGULATOR_CPR3=y +CONFIG_REGULATOR_CPR3_HMSS=y +CONFIG_REGULATOR_CPR3_MMSS=y +CONFIG_REGULATOR_CPR4_APSS=y +CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_KRYO=y +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +CONFIG_MEDIA_RADIO_SUPPORT=y +# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_V4L2_MEM2MEM_DEV=y +CONFIG_VIDEOBUF_GEN=y +CONFIG_VIDEOBUF2_CORE=y +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_RC_CORE=y +CONFIG_RC_MAP=y +CONFIG_RC_DECODERS=y +CONFIG_LIRC=y +CONFIG_IR_LIRC_CODEC=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +CONFIG_IR_SANYO_DECODER=y +CONFIG_IR_SHARP_DECODER=y +# CONFIG_IR_MCE_KBD_DECODER is not set +CONFIG_IR_XMP_DECODER=y +# CONFIG_IR_DUMP_DECODER is not set +CONFIG_RC_DEVICES=y +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_IR_IMG is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set +# CONFIG_IR_GPIO is not set +CONFIG_IR_PWM=y +# CONFIG_MEDIA_USB_SUPPORT is not set +# CONFIG_MEDIA_PCI_SUPPORT is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_CAFE_CCIC is not set +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set +CONFIG_MSM_VIDC_V4L2=y +CONFIG_MSM_VIDC_VMEM=y +CONFIG_MSM_VIDC_GOVERNORS=y + +# +# Qualcomm MSM Camera And Video +# +CONFIG_MSM_CAMERA=y +# CONFIG_MSM_CAMERA_DEBUG is not set +# CONFIG_MSM_CAMERA_AUTOMOTIVE is not set +CONFIG_MSMB_CAMERA=y +# CONFIG_MSMB_CAMERA_DEBUG is not set +CONFIG_MSM_CAMERA_SENSOR=y +CONFIG_MSM_CPP=y +CONFIG_MSM_CCI=y +CONFIG_MSM_CSI20_HEADER=y +CONFIG_MSM_CSI22_HEADER=y +CONFIG_MSM_CSI30_HEADER=y +CONFIG_MSM_CSI31_HEADER=y +CONFIG_MSM_CSIPHY=y +CONFIG_MSM_CSID=y +CONFIG_MSM_EEPROM=y +CONFIG_MSM_ISPIF=y +# CONFIG_MSM_ISPIF_V1 is not set +# CONFIG_MSM_ISPIF_V2 is not set +CONFIG_IMX134=y +CONFIG_IMX132=y +CONFIG_OV9724=y +CONFIG_OV5648=y +CONFIG_GC0339=y +CONFIG_OV8825=y +CONFIG_OV8865=y +CONFIG_s5k4e1=y +CONFIG_OV12830=y +CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y +CONFIG_MSMB_JPEG=y +CONFIG_MSM_FD=y +# CONFIG_MSM_JPEGDMA is not set +# CONFIG_TSPP is not set +CONFIG_MSM_SDE_ROTATOR=y + +# +# Supported MMC/SDIO adapters +# +CONFIG_RADIO_ADAPTERS=y +# CONFIG_RADIO_SI470X is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_USB_MR800 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_SHARK is not set +# CONFIG_RADIO_SHARK2 is not set +# CONFIG_USB_KEENE is not set +# CONFIG_USB_RAREMONO is not set +# CONFIG_USB_MA901 is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_TEF6862 is not set +# CONFIG_RADIO_WL1273 is not set + +# +# Texas Instruments WL128x FM driver (ST based) +# +# CONFIG_RADIO_WL128X is not set +CONFIG_RADIO_IRIS=y +CONFIG_RADIO_IRIS_TRANSPORT=y +CONFIG_RADIO_SILABS=y +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_ATTACH=y +CONFIG_VIDEO_IR_I2C=y + +# +# Audio decoders, processors and mixers +# + +# +# RDS decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# Video encoders +# + +# +# Camera sensor devices +# + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Audio/Video compression chips +# + +# +# Miscellaneous helper chips +# + +# +# Sensors used on soc_camera driver +# + +# +# soc_camera sensor drivers +# +# CONFIG_SOC_CAMERA_IMX074 is not set +# CONFIG_SOC_CAMERA_MT9M001 is not set +# CONFIG_SOC_CAMERA_MT9M111 is not set +# CONFIG_SOC_CAMERA_MT9T031 is not set +# CONFIG_SOC_CAMERA_MT9T112 is not set +# CONFIG_SOC_CAMERA_MT9V022 is not set +# CONFIG_SOC_CAMERA_OV2640 is not set +# CONFIG_SOC_CAMERA_OV5642 is not set +# CONFIG_SOC_CAMERA_OV6650 is not set +# CONFIG_SOC_CAMERA_OV772X is not set +# CONFIG_SOC_CAMERA_OV9640 is not set +# CONFIG_SOC_CAMERA_OV9740 is not set +# CONFIG_SOC_CAMERA_RJ54N1 is not set +# CONFIG_SOC_CAMERA_TW9910 is not set +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA827X=y +CONFIG_MEDIA_TUNER_TDA18271=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_MEDIA_TUNER_XC4000=y +CONFIG_MEDIA_TUNER_MC44S803=y + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set + +# +# Graphics support +# +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_MSM_KGSL=y +# CONFIG_MSM_KGSL_CFF_DUMP is not set +CONFIG_MSM_ADRENO_DEFAULT_GOVERNOR="msm-adreno-tz" +CONFIG_MSM_KGSL_IOMMU=y + +# +# Direct Rendering Manager +# +# CONFIG_DRM is not set + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_ARMCLCD is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_OPENCORES is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +CONFIG_FB_MSM=y +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_MSM_BA_V4L2 is not set +CONFIG_MSM_DBA=y +CONFIG_MSM_DBA_ADV7533=y +CONFIG_FB_MSM_MDSS_COMMON=y +# CONFIG_FB_MSM_MDP is not set +CONFIG_FB_MSM_MDSS=y +# CONFIG_FB_MSM_MDP_NONE is not set +# CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL is not set +# CONFIG_FB_MSM_QPIC_PANEL_DETECT is not set +CONFIG_FB_MSM_MDSS_WRITEBACK=y +CONFIG_FB_MSM_MDSS_HDMI_PANEL=y +# CONFIG_FB_MSM_MDSS_HDMI_MHL_SII8334 is not set +# CONFIG_FB_MSM_MDSS_MHL3 is not set +# CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS is not set +# CONFIG_FB_MSM_MDSS_EDP_PANEL is not set +# CONFIG_FB_MSM_MDSS_MDP3 is not set +CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y +# CONFIG_FB_SSD1307 is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_LD9040 is not set +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_HX8357 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +CONFIG_BACKLIGHT_GENERIC=m +# CONFIG_BACKLIGHT_PWM is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630A is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_ADF is not set +# CONFIG_VGASTATE is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_COMPRESS_OFFLOAD=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# HD-Audio +# +# CONFIG_SND_HDA_INTEL is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_AUDIO_QMI is not set +CONFIG_SND_SOC=y +# CONFIG_SND_ATMEL_SOC is not set +# CONFIG_SND_DESIGNWARE_I2S is not set + +# +# SoC Audio for Freescale CPUs +# + +# +# Common SoC Audio options for Freescale CPUs: +# +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set + +# +# MSM SoC Audio support +# +CONFIG_SND_SOC_MSM_HOSTLESS_PCM=y +CONFIG_SND_SOC_MSM_QDSP6V2_INTF=y +CONFIG_SND_SOC_QDSP6V2=y +# CONFIG_SND_SOC_QDSP_DEBUG is not set +CONFIG_DOLBY_DAP=y +CONFIG_DOLBY_DS2=y +CONFIG_DTS_EAGLE=y +CONFIG_DTS_SRS_TM=y +CONFIG_QTI_PP=y +CONFIG_SND_SOC_CPE=y +CONFIG_SND_SOC_MSM8X16=y +CONFIG_SND_SOC_I2C_AND_SPI=y + +# +# CODEC drivers +# +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_AK4104 is not set +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271 is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set +# CONFIG_SND_SOC_HDMI_CODEC is not set +# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_PCM1681 is not set +# CONFIG_SND_SOC_PCM1792A is not set +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +# CONFIG_SND_SOC_SPDIF is not set +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_WCD9330=y +CONFIG_SND_SOC_WCD9335=y +CONFIG_SND_SOC_WSA881X_SENSORS=y +CONFIG_SND_SOC_WSA881X=y +CONFIG_SND_SOC_WSA881X_ANALOG=y +CONFIG_SND_SOC_MSM8X16_WCD=y +CONFIG_SND_SOC_WCD9XXX=y +CONFIG_SND_SOC_WCD9XXX_V2=y +CONFIG_SND_SOC_WCD_CPE=y +CONFIG_AUDIO_EXT_CLK=y +CONFIG_SND_SOC_WCD_MBHC=y +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set +# CONFIG_SND_SOC_WM8804 is not set +# CONFIG_SND_SOC_WM8903 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SOC_MSM_STUB=y +CONFIG_SND_SOC_MSM_HDMI_DBA_CODEC_RX=y +# CONFIG_SND_SIMPLE_CARD is not set +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CP2112 is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +CONFIG_HID_ELECOM=y +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_GT683R is not set +# CONFIG_HID_HUION is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO is not set +# CONFIG_HID_LOGITECH is not set +CONFIG_HID_MAGICMOUSE=y +CONFIG_HID_MICROSOFT=y +# CONFIG_HID_MONTEREY is not set +CONFIG_HID_MULTITOUCH=y +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PENMOUNT is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_RMI is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +# CONFIG_I2C_HID is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_FSM is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_MSM=y +CONFIG_USB_EHCI_MSM_HSIC=y +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FUSBH200_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +# CONFIG_USB_MAX3421_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_UAS is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_HOST is not set +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_DWC3_DUAL_ROLE=y + +# +# Platform Glue Driver Support +# +CONFIG_USB_DWC3_PCI=y +CONFIG_USB_DWC3_MSM=y + +# +# Debugging features +# +# CONFIG_USB_DWC3_DEBUG is not set +# CONFIG_DWC3_HOST_USB3_LPM_ENABLE is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_CHIPIDEA is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=y +# CONFIG_USB_SERIAL_CONSOLE is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MXUPORT is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +CONFIG_USB_EHSET_TEST_FIXTURE=y +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_EZUSB_FX2 is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +# CONFIG_USB_OTG_WAKELOCK is not set +CONFIG_NOP_USB_XCEIV=y +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +CONFIG_USB_MSM_OTG=y +CONFIG_USB_MSM_HSPHY=y +# CONFIG_USB_MSM_SSPHY is not set +CONFIG_USB_MSM_SSPHY_QMP=y +CONFIG_MSM_QUSB_PHY=y +# CONFIG_USB_ULPI is not set +CONFIG_DUAL_ROLE_USB_INTF=y +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_DEBUG_FS=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 + +# +# USB Peripheral Controller +# +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_AMD5536UDC is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_NET2280 is not set +# CONFIG_USB_GOKU is not set +# CONFIG_USB_EG20T is not set +# CONFIG_USB_GADGET_XILINX is not set +CONFIG_USB_CI13XXX_MSM=y +# CONFIG_USB_CI13XXX_MSM_HSIC is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_F_ACM=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_F_SERIAL=y +CONFIG_USB_F_NCM=y +CONFIG_USB_F_ECM=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_F_FS=y +CONFIG_USB_F_UAC1=y +CONFIG_USB_F_AUDIO_SRC=y +# CONFIG_USB_CONFIGFS is not set +CONFIG_USB_G_ANDROID=y +# CONFIG_USB_ANDROID_RNDIS_DWORD_ALIGNED is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set +# CONFIG_USB_LED_TRIG is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_PERF_PROFILING=y +CONFIG_MMC_CLKGATE=y +# CONFIG_MMC_EMBEDDED_SDIO is not set +CONFIG_MMC_PARANOID_SD_INIT=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +CONFIG_MMC_TEST=m +CONFIG_MMC_FFU=y +CONFIG_MMC_BLOCK_TEST=m + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_ARMMMCI is not set +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MMC_SDHCI_MSM_ICE=y +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MMC_USDHI6ROL0 is not set +CONFIG_MMC_CQ_HCI=y +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_INTEL_SS4200 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_LM355x is not set + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +# CONFIG_LEDS_BLINKM is not set +CONFIG_LEDS_QPNP=y +CONFIG_LEDS_QPNP_FLASH=y +CONFIG_LEDS_QPNP_WLED=y +CONFIG_LEDS_AW2013=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_CPU is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +CONFIG_SWITCH=y +# CONFIG_SWITCH_GPIO is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_MM_EDAC=y +CONFIG_EDAC_CORTEX_ARM64=y +# CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_CE is not set +CONFIG_EDAC_CORTEX_ARM64_DBE_IRQ_ONLY=y +CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_UE=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set +# CONFIG_RTC_DRV_MCP795 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS2404 is not set +# CONFIG_RTC_DRV_EFI is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PL030 is not set +# CONFIG_RTC_DRV_PL031 is not set +# CONFIG_RTC_DRV_SNVS is not set +CONFIG_RTC_DRV_QPNP=y +# CONFIG_RTC_DRV_XGENE is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +# CONFIG_ESOC is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_AMBA_PL08X is not set +# CONFIG_DW_DMAC_CORE is not set +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set +CONFIG_QCOM_SPS_DMA=y +# CONFIG_PL330_DMA is not set +# CONFIG_FSL_EDMA is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=y +# CONFIG_UIO_CIF is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_DMEM_GENIRQ is not set +# CONFIG_UIO_AEC is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_UIO_PCI_GENERIC is not set +# CONFIG_UIO_NETX is not set +# CONFIG_UIO_MF624 is not set +CONFIG_UIO_MSM_SHAREDMEM=y +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTLLIB is not set +# CONFIG_R8712U is not set +# CONFIG_R8188EU is not set +# CONFIG_R8723AU is not set +# CONFIG_RTS5208 is not set +# CONFIG_LINE6_USB is not set +# CONFIG_VT6655 is not set +# CONFIG_FB_XGI is not set +# CONFIG_BCM_WIMAX is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set +# CONFIG_STAGING_MEDIA is not set + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ASHMEM=y +# CONFIG_ANDROID_LOGGER is not set +CONFIG_ANDROID_TIMED_OUTPUT=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +CONFIG_SW_SYNC_USER=y +CONFIG_ONESHOT_SYNC=y +# CONFIG_ONESHOT_SYNC_USER is not set +CONFIG_SWAPAGING=y +CONFIG_ANDROID_WHETSTONE=y +CONFIG_ION=y +# CONFIG_ION_TEST is not set +# CONFIG_ION_DUMMY is not set +CONFIG_ION_MSM=y +# CONFIG_ALLOC_BUFFERS_IN_4K_CHUNKS is not set +# CONFIG_FIQ_DEBUGGER is not set +# CONFIG_FIQ_WATCHDOG is not set +# CONFIG_USB_WPAN_HCD is not set +# CONFIG_WIMAX_GDM72XX is not set +# CONFIG_LTE_GDM724X is not set +# CONFIG_LUSTRE_FS is not set +# CONFIG_DGNC is not set +# CONFIG_DGAP is not set +# CONFIG_GS_FPGABOOT is not set +# CONFIG_GOLDFISH is not set + +# +# Qualcomm MSM specific device drivers +# +CONFIG_MSM_AVTIMER=y +CONFIG_MSM_BUS_SCALING=y +CONFIG_BUS_TOPOLOGY_ADHOC=y +# CONFIG_DEBUG_BUS_VOTER is not set +CONFIG_QPNP_POWER_ON=y +CONFIG_QPNP_REVID=y +CONFIG_QPNP_COINCELL=y +CONFIG_SPS=y +# CONFIG_EP_PCIE is not set +CONFIG_USB_BAM=y +# CONFIG_SPS_SUPPORT_BAMDMA is not set +CONFIG_SPS_SUPPORT_NDP_BAM=y +# CONFIG_QPNP_VIBRATOR is not set +CONFIG_IPA=y +# CONFIG_IPA3 is not set +# CONFIG_GSI is not set +CONFIG_RMNET_IPA=y +# CONFIG_SSM is not set +# CONFIG_MSM_MHI is not set +# CONFIG_PFT is not set +# CONFIG_I2C_MSM_PROF_DBG is not set +# CONFIG_SEEMP_CORE is not set +CONFIG_QPNP_HAPTIC=y +# CONFIG_GPIO_USB_DETECT is not set +CONFIG_MSM_11AD=y +# CONFIG_BW_MONITOR is not set +CONFIG_MSM_SPMI=y +CONFIG_MSM_SPMI_PMIC_ARB=y +CONFIG_MSM_QPNP_INT=y + +# +# SOC (System On Chip) specific Drivers +# +CONFIG_CP_ACCESS64=y +# CONFIG_MSM_INRUSH_CURRENT_MITIGATION is not set +CONFIG_MSM_QDSP6_APRV2=y +# CONFIG_MSM_GLADIATOR_ERP is not set +# CONFIG_MSM_GLADIATOR_ERP_V2 is not set +# CONFIG_MSM_QDSP6_APRV3 is not set +# CONFIG_MSM_QDSP6_APRV2_GLINK is not set +# CONFIG_MSM_QDSP6_APRV3_GLINK is not set +CONFIG_MSM_ADSP_LOADER=y +# CONFIG_MSM_MEMORY_DUMP is not set +CONFIG_MSM_MEMORY_DUMP_V2=y +# CONFIG_MSM_DEBUG_LAR_UNLOCK is not set +# CONFIG_MSM_JTAG is not set +# CONFIG_MSM_JTAG_MM is not set +# CONFIG_MSM_JTAGV8 is not set +CONFIG_MSM_BOOT_STATS=y +# CONFIG_MSM_BOOT_TIME_MARKER is not set +CONFIG_MSM_CPUSS_DUMP=y +CONFIG_MSM_COMMON_LOG=y +CONFIG_MSM_DDR_HEALTH=y +# CONFIG_MSM_HYP_DEBUG is not set +CONFIG_MSM_WATCHDOG_V2=y +CONFIG_MSM_FORCE_WDOG_BITE_ON_PANIC=y +# CONFIG_MSM_CORE_HANG_DETECT is not set +# CONFIG_MSM_GLADIATOR_HANG_DETECT is not set +CONFIG_MSM_CPU_PWR_CTL=y +# CONFIG_MSM_L2_IA_DEBUG is not set +CONFIG_MSM_RPM_SMD=y +CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y +CONFIG_MSM_RPM_LOG=y +CONFIG_MSM_RPM_STATS_LOG=y +CONFIG_MSM_RUN_QUEUE_STATS=y +CONFIG_MSM_SCM=y +CONFIG_MSM_SCM_XPU=y +CONFIG_MSM_XPU_ERR_FATAL=y +# CONFIG_MSM_XPU_ERR_NONFATAL is not set +# CONFIG_MSM_SCM_ERRATA is not set +# CONFIG_MSM_PFE_WA is not set +CONFIG_MSM_MPM_OF=y +CONFIG_MSM_SMEM=y +CONFIG_MSM_SMD=y +CONFIG_MSM_SMD_DEBUG=y +CONFIG_MSM_GLINK=y +CONFIG_MSM_GLINK_LOOPBACK_SERVER=y +CONFIG_MSM_GLINK_SMD_XPRT=y +CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y +CONFIG_MSM_SPCOM=y +CONFIG_MSM_SMEM_LOGGING=y +CONFIG_MSM_SMP2P=y +CONFIG_MSM_SMP2P_TEST=y +CONFIG_MSM_SPM=y +CONFIG_MSM_L2_SPM=y +CONFIG_MSM_QMI_INTERFACE=y +# CONFIG_MSM_DCC is not set +# CONFIG_MSM_HVC is not set +CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y +CONFIG_MSM_EVENT_TIMER=y +# CONFIG_MSM_SYSMON_GLINK_COMM is not set +# CONFIG_MSM_IPC_ROUTER_GLINK_XPRT is not set +# CONFIG_MSM_SYSTEM_HEALTH_MONITOR is not set +# CONFIG_MSM_GLINK_PKT is not set +CONFIG_MSM_TZ_SMMU=y +CONFIG_MSM_SUBSYSTEM_RESTART=y +CONFIG_MSM_SYSMON_COMM=y +CONFIG_MSM_PIL=y +CONFIG_MSM_PIL_SSR_GENERIC=y +CONFIG_MSM_PIL_MSS_QDSP6V5=y +# CONFIG_MSM_SHARED_HEAP_ACCESS is not set +# CONFIG_TRACER_PKT is not set +CONFIG_MSM_SECURE_BUFFER=y +CONFIG_ICNSS=y +CONFIG_MSM_BAM_DMUX=y +CONFIG_MSM_PERFORMANCE=y +CONFIG_MSM_PERFORMANCE_HOTPLUG_ON=y +# CONFIG_MSM_POWER is not set +# CONFIG_MSM_SERVICE_LOCATOR is not set +# CONFIG_MSM_QBT1000 is not set +# CONFIG_MSM_PACMAN is not set +# CONFIG_MSM_REMOTEQDSS is not set +CONFIG_SERIAL_NUM=y +CONFIG_MEM_SHARE_QMI_SERVICE=y +# CONFIG_SOC_TI is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_MSM_CLK_CONTROLLER_V2=y +CONFIG_MSM_MDSS_PLL=y +CONFIG_HWSPINLOCK=y + +# +# Hardware Spinlock drivers +# +CONFIG_REMOTE_SPINLOCK_MSM=y + +# +# Clock Source drivers +# +CONFIG_CLKSRC_OF=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +# CONFIG_CLKSRC_VERSATILE is not set +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_LPAE=y +# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_FAST is not set +CONFIG_OF_IOMMU=y +CONFIG_MSM_IOMMU=y +CONFIG_MSM_IOMMU_V1=y +# CONFIG_IOMMU_LPAE is not set +# CONFIG_IOMMU_AARCH64 is not set +# CONFIG_MSM_IOMMU_VBIF_CHECK is not set +# CONFIG_IOMMU_NON_SECURE is not set +# CONFIG_IOMMU_FORCE_4K_MAPPINGS is not set +CONFIG_ARM_SMMU=y +CONFIG_IOMMU_DEBUG=y +# CONFIG_IOMMU_DEBUG_TRACKING is not set +CONFIG_IOMMU_TESTS=y + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_CPUFREQ=y +CONFIG_DEVFREQ_GOV_MSM_ADRENO_TZ=y +CONFIG_MSM_BIMC_BWMON=y +CONFIG_DEVFREQ_GOV_MSM_GPUBW_MON=y +# CONFIG_ARMBW_HWMON is not set +CONFIG_ARM_MEMLAT_MON=y +CONFIG_MSMCCI_HWMON=y +CONFIG_MSM_M4M_HWMON=y +CONFIG_DEVFREQ_GOV_MSM_BW_HWMON=y +CONFIG_DEVFREQ_GOV_MSM_CACHE_HWMON=y +CONFIG_DEVFREQ_GOV_SPDM_HYP=y +CONFIG_DEVFREQ_GOV_MEMLAT=y + +# +# DEVFREQ Drivers +# +CONFIG_DEVFREQ_SIMPLE_DEV=y +CONFIG_MSM_DEVFREQ_DEVBW=y +CONFIG_SPDM_SCM=y +CONFIG_DEVFREQ_SPDM=y +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +# CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_PCA9685 is not set +CONFIG_PWM_QPNP=y +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_V2M=y +CONFIG_ARM_GIC_V3=y +CONFIG_ARM_GIC_PANIC_HANDLER=y +CONFIG_ARM_GIC_V3_ITS=y +CONFIG_ARM_GIC_V3_ACL=y +# CONFIG_ARM_GIC_V3_NO_ACCESS_CONTROL is not set +CONFIG_MSM_SHOW_RESUME_IRQ=y +CONFIG_MSM_IRQ=y +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_FMC is not set +CONFIG_CORESIGHT=y +CONFIG_CORESIGHT_EVENT=y +CONFIG_HAVE_CORESIGHT_SINK=y +CONFIG_CORESIGHT_FUSE=y +CONFIG_CORESIGHT_CTI=y +CONFIG_CORESIGHT_CTI_SAVE_DISABLE=y +CONFIG_CORESIGHT_CSR=y +CONFIG_CORESIGHT_TMC=y +CONFIG_CORESIGHT_TPIU=y +CONFIG_CORESIGHT_FUNNEL=y +CONFIG_CORESIGHT_REPLICATOR=y +# CONFIG_CORESIGHT_TPDA is not set +# CONFIG_CORESIGHT_TPDM is not set +# CONFIG_CORESIGHT_DBGUI is not set +CONFIG_CORESIGHT_STM=y +# CONFIG_CORESIGHT_STM_DEFAULT_ENABLE is not set +CONFIG_CORESIGHT_HWEVENT=y +# CONFIG_CORESIGHT_ETM is not set +# CONFIG_CORESIGHT_ETMV4 is not set +# CONFIG_CORESIGHT_REMOTE_ETM is not set +# CONFIG_CORESIGHT_QPDI is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +# CONFIG_BCM_KONA_USB2_PHY is not set +# CONFIG_PHY_XGENE is not set +CONFIG_PHY_QCOM_UFS=y +# CONFIG_POWERCAP is not set +# CONFIG_MCB is not set +CONFIG_RAS=y +# CONFIG_THUNDERBOLT is not set +CONFIG_SENSORS_SSC=y + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_DMIID=y +# CONFIG_DMI_SYSFS is not set + +# +# EFI (Extensible Firmware Interface) Support +# +# CONFIG_EFI_VARS is not set +CONFIG_EFI_PARAMS_FROM_FDT=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_ARMSTUB=y +CONFIG_MSM_TZ_LOG=y +# CONFIG_BIF is not set +# CONFIG_MOBICORE_DRIVER is not set + +# +# Firmware Drivers +# + +# +# EFI (Extensible Firmware Interface) Support +# + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +CONFIG_QUOTA=y +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +# CONFIG_PRINT_QUOTA_WARNING is not set +# CONFIG_QUOTA_DEBUG is not set +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set +# CONFIG_OVERLAY_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_EXFAT_FS=y +CONFIG_EXFAT_DISCARD=y +CONFIG_EXFAT_DELAYED_SYNC=y +# CONFIG_EXFAT_KERNEL_DEBUG is not set +CONFIG_EXFAT_DEBUG_MSG=y +CONFIG_EXFAT_DEFAULT_CODEPAGE=437 +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_ECRYPT_FS=y +# CONFIG_ECRYPT_FS_MESSAGING is not set +# CONFIG_SDCARD_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +# CONFIG_PSTORE_PMSG is not set +CONFIG_PSTORE_FTRACE=y +CONFIG_PSTORE_RAM=y +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_F2FS_FS is not set +# CONFIG_EFIVAR_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_SMB2 is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=y +# CONFIG_DLM is not set +# CONFIG_FILE_TABLE_DEBUG is not set +# CONFIG_VIRTUALIZATION is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +# CONFIG_LOG_BUF_MAGIC is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_DYNAMIC_DEBUG is not set + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_INFO_SPLIT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_HAVE_ARCH_KASAN=y +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=5 +CONFIG_PANIC_ON_RECURSIVE_FAULT=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_PANIC_ON_SCHED_BUG is not set +# CONFIG_PANIC_ON_RT_THROTTLING is not set +CONFIG_SCHEDSTATS=y +# CONFIG_SCHED_STACK_END_CHECK is not set +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_PREEMPT=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_HAVE_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_CPU_STALL_VERBOSE=y +# CONFIG_RCU_CPU_STALL_INFO is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_MSM_RTB is not set +CONFIG_IPC_LOGGING=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_PROBE_EVENTS is not set +CONFIG_DYNAMIC_FTRACE=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_CPU_FREQ_SWITCH_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set + +# +# Runtime Testing +# +# CONFIG_LKDTM is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_PERCPU_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_PANIC_ON_DATA_CORRUPTION is not set +# CONFIG_MEMTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +# CONFIG_ARM64_PTDUMP is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set +CONFIG_DEBUG_SET_MODULE_RONX=y +# CONFIG_FREE_PAGES_RDONLY is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_ALIGN_RODATA is not set +# CONFIG_CORESIGHT_LINKS_AND_SINKS is not set +# CONFIG_CORESIGHT_SOURCE_ETM4X is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +CONFIG_ENCRYPTED_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set + +# +# Qualcomm Technologies, Inc Per File Encryption security device drivers +# +# CONFIG_PFK is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY_PERF_EVENTS_RESTRICT is not set +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_PATH is not set +CONFIG_LSM_MMAP_MIN_ADDR=4096 +CONFIG_SECURITY_SELINUX=y +# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set +# CONFIG_SECURITY_SELINUX_DISABLE is not set +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_YAMA is not set +CONFIG_INTEGRITY=y +# CONFIG_INTEGRITY_SIGNATURE is not set +CONFIG_INTEGRITY_AUDIT=y +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_SELINUX=y +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_DEFAULT_SECURITY="selinux" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +# CONFIG_CRYPTO_MCRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_ABLK_HELPER=y + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +CONFIG_CRYPTO_SEQIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +CONFIG_CRYPTO_XTS=y + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=y +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRCT10DIF is not set +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_DRBG_MENU is not set +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_QCE50=y +# CONFIG_FIPS_ENABLE is not set +CONFIG_CRYPTO_DEV_QCRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y +CONFIG_CRYPTO_DEV_QCEDEV=y +CONFIG_CRYPTO_DEV_OTA_CRYPTO=y +CONFIG_CRYPTO_DEV_QCOM_ICE=y +# CONFIG_CRYPTO_DEV_CCP is not set +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_PUBLIC_KEY_ALGO_RSA=y +CONFIG_X509_CERTIFICATE_PARSER=y +# CONFIG_PKCS7_MESSAGE_PARSER is not set +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y +CONFIG_AUDIT_COMPAT_GENERIC=y +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=y +CONFIG_TEXTSEARCH_BM=y +CONFIG_TEXTSEARCH_FSM=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +# CONFIG_AVERAGE is not set +CONFIG_CLZ_TAB=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_MPILIB=y +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_ARCH_HAS_SG_CHAIN=y +CONFIG_QMI_ENCDEC=y +# CONFIG_QMI_ENCDEC_DEBUG is not set +# CONFIG_STRICT_MEMORY_RWX is not set From 0bf306e0dc7883547e104dae519239ed9478e762 Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Fri, 27 Feb 2015 18:31:48 -0800 Subject: [PATCH 53/86] power: reset: Allow device to preserve memory on restart * Always perform a soft reset as this preserves memory contents, including pstore and other persistent memory. Change-Id: Ideca44c9f38d2ebcd437ff289f8e036922eafcd2 --- drivers/power/reset/Kconfig | 9 +++++++++ drivers/power/reset/msm-poweroff.c | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index db933765d38d..7008160eb079 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -94,6 +94,15 @@ config MSM_DLOAD_MODE make the kernel reboot on a kernel panic - that must be enabled via another mechanism. +config MSM_PRESERVE_MEM + bool "Always preserve memory on restart" + depends on POWER_RESET_MSM + help + If crash to download mode is disabled and restart reason is null + the system will always perform a hard reset, which wipes out + persistent memory contents. Select this option to always perform + a soft reset that preserves memory contents. + config POWER_RESET_QNAP bool "QNAP power-off driver" depends on OF_GPIO && PLAT_ORION diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index ee3e72b3537a..d9626a903d59 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -290,6 +290,10 @@ static void msm_restart_prepare(const char *cmd) (cmd != NULL && cmd[0] != '\0')); } +#ifdef CONFIG_MSM_PRESERVE_MEM + need_warm_reset = true; +#endif + /* Hard reset the PMIC unless memory contents must be maintained. */ if (need_warm_reset) { qpnp_pon_system_pwr_off(PON_POWER_OFF_WARM_RESET); From 34b7f6c505a164c288cab31e10efea7a8410da9f Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Sat, 20 May 2017 18:45:41 +0000 Subject: [PATCH 54/86] mido: Enable CONFIG_IP6_NF_MATCH_RPFILTER --- arch/arm64/configs/mido_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index df7fe26cbde5..58398ec6e3eb 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -828,7 +828,7 @@ CONFIG_IP6_NF_IPTABLES=y # CONFIG_IP6_NF_MATCH_HL is not set # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set # CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set +CONFIG_IP6_NF_MATCH_RPFILTER=y # CONFIG_IP6_NF_MATCH_RT is not set # CONFIG_IP6_NF_TARGET_HL is not set CONFIG_IP6_NF_FILTER=y From 1bd029b4f851c19036fe9703278959a834f71718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Triszka?= Date: Sat, 20 May 2017 19:06:14 +0000 Subject: [PATCH 55/86] drivers : usb: Increase charge current Change-Id: I547af7ddc93256fdce716d9fbe1e49530698d112 --- drivers/usb/dwc3/dwc3-msm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 08b19abb4595..e8c97bc25b8f 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -52,8 +52,8 @@ #include "debug.h" #include "xhci.h" -#define DWC3_IDEV_CHG_MAX 1500 -#define DWC3_HVDCP_CHG_MAX 1800 +#define DWC3_IDEV_CHG_MAX 2000 +#define DWC3_HVDCP_CHG_MAX 2000 #define DWC3_WAKEUP_SRC_TIMEOUT 5000 /* AHB2PHY register offsets */ From a77bc4e0deb3066fb114f1a8ad1190560fa61d57 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 19 May 2017 19:55:08 +0800 Subject: [PATCH 56/86] mido: config enable MSM_PRESERVE_MEM and store reboot reason --- arch/arm/boot/dts/qcom/msm-pm8953.dtsi | 1 + arch/arm64/configs/mido_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/qcom/msm-pm8953.dtsi b/arch/arm/boot/dts/qcom/msm-pm8953.dtsi index 62ffb0be9a8a..990590a420da 100644 --- a/arch/arm/boot/dts/qcom/msm-pm8953.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm8953.dtsi @@ -35,6 +35,7 @@ interrupt-names = "kpdpwr", "resin", "resin-bark", "kpdpwr-resin-bark"; qcom,pon-dbc-delay = <15625>; + qcom,store-hard-reset-reason; qcom,system-reset; qcom,pon_1 { diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index 58398ec6e3eb..5efdf5dcda22 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -4083,6 +4083,7 @@ CONFIG_PSTORE_CONSOLE=y # CONFIG_PSTORE_PMSG is not set CONFIG_PSTORE_FTRACE=y CONFIG_PSTORE_RAM=y +CONFIG_MSM_PRESERVE_MEM=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set # CONFIG_F2FS_FS is not set From 5733e6e882df1d5be1c57f8a61b6f4f9cbdaba27 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Sun, 21 May 2017 13:00:47 +0000 Subject: [PATCH 57/86] mido: Disable modules support Change-Id: Ib7ac72bb63b7c25cbf6de8f9d95a115e8a7f1511 --- arch/arm64/configs/mido_defconfig | 83 ++++--------------------------- 1 file changed, 11 insertions(+), 72 deletions(-) diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index 5efdf5dcda22..5e089b3374e9 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -249,22 +249,7 @@ CONFIG_COMPAT_OLD_SIGACTION=y CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_MODULE_SIG=y -CONFIG_MODULE_SIG_FORCE=y -CONFIG_MODULE_SIG_ALL=y -# CONFIG_MODULE_SIG_SHA1 is not set -# CONFIG_MODULE_SIG_SHA224 is not set -# CONFIG_MODULE_SIG_SHA256 is not set -# CONFIG_MODULE_SIG_SHA384 is not set -CONFIG_MODULE_SIG_SHA512=y -CONFIG_MODULE_SIG_HASH="sha512" -# CONFIG_MODULE_COMPRESS is not set +# CONFIG_MODULES is not set CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y @@ -301,7 +286,7 @@ CONFIG_BLOCK_COMPAT=y # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_TEST=m +# CONFIG_IOSCHED_TEST is not set CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y # CONFIG_DEFAULT_DEADLINE is not set @@ -546,7 +531,6 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y # # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set CONFIG_CPU_FREQ_MSM=y -CONFIG_ARM64_ERRATUM_843419=y CONFIG_NET=y CONFIG_COMPAT_NETLINK_MESSAGES=y # CONFIG_DISABLE_NET_SKB_FRAG_CACHE is not set @@ -636,7 +620,7 @@ CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=m +CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration @@ -968,7 +952,6 @@ CONFIG_XPS=y # CONFIG_CGROUP_NET_CLASSID is not set CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y -# CONFIG_BPF_JIT is not set CONFIG_NET_FLOW_LIMIT=y CONFIG_SOCKEV_NLMCAST=y @@ -1215,7 +1198,6 @@ CONFIG_MSM_ULTRASOUND=y # CONFIG_GENWQE is not set # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set -CONFIG_HQ_SYSFS_SUPPORT=y # # SCSI device support @@ -1280,7 +1262,6 @@ CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_QCOM=y CONFIG_SCSI_UFS_QCOM_ICE=y -CONFIG_SCSI_UFS_TEST=m # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -1619,7 +1600,7 @@ CONFIG_ATH_CARDS=y # CONFIG_ATH_DEBUG is not set # CONFIG_ATH5K_PCI is not set # CONFIG_ATH6KL is not set -CONFIG_WIL6210=m +CONFIG_WIL6210=y CONFIG_WIL6210_ISR_COR=y CONFIG_WIL6210_TRACING=y # CONFIG_WIL6210_WRITE_IOCTL is not set @@ -1662,7 +1643,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_EVBUG=m +# CONFIG_INPUT_EVBUG is not set CONFIG_INPUT_KEYRESET=y CONFIG_INPUT_KEYCOMBO=y @@ -1913,7 +1894,7 @@ CONFIG_MSM_SMD_PKT=y # CONFIG_XILLYBUS is not set CONFIG_MSM_ADSPRPC=y # CONFIG_MSM_MDSP_TS is not set -CONFIG_MSM_RDBG=m +# CONFIG_MSM_RDBG is not set # # I2C support @@ -1985,7 +1966,6 @@ CONFIG_I2C_MSM_V2=y # # Other I2C/SMBus bus drivers # -# CONFIG_I2C_STUB is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -2019,7 +1999,7 @@ CONFIG_SPI_QUP=y # # SPI Protocol Masters # -CONFIG_SPI_SPIDEV=m +CONFIG_SPI_SPIDEV=y # CONFIG_SPI_TLE62X0 is not set # CONFIG_SPMI is not set # CONFIG_HSI is not set @@ -2620,7 +2600,6 @@ CONFIG_RADIO_SILABS=y # Media ancillary drivers (tuners, sensors, i2c, frontends) # CONFIG_MEDIA_SUBDRV_AUTOSELECT=y -CONFIG_MEDIA_ATTACH=y CONFIG_VIDEO_IR_I2C=y # @@ -2798,32 +2777,7 @@ CONFIG_FB_MSM_MDSS_HDMI_PANEL=y # CONFIG_FB_MSM_MDSS_MDP3 is not set CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y # CONFIG_FB_SSD1307 is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -# CONFIG_LCD_PLATFORM is not set -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_LD9040 is not set -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_HX8357 is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=m -CONFIG_BACKLIGHT_GENERIC=m -# CONFIG_BACKLIGHT_PWM is not set -# CONFIG_BACKLIGHT_ADP8860 is not set -# CONFIG_BACKLIGHT_ADP8870 is not set -# CONFIG_BACKLIGHT_LM3630A is not set -# CONFIG_BACKLIGHT_LM3639 is not set -# CONFIG_BACKLIGHT_LP855X is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_LV5207LP is not set -# CONFIG_BACKLIGHT_BD6107 is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_ADF is not set # CONFIG_VGASTATE is not set # CONFIG_LOGO is not set @@ -3395,9 +3349,7 @@ CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_BLOCK_BOUNCE=y # CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set # CONFIG_SDIO_UART is not set -CONFIG_MMC_TEST=m -CONFIG_MMC_FFU=y -CONFIG_MMC_BLOCK_TEST=m +# CONFIG_MMC_TEST is not set # # MMC/SD/SDIO Host Controller Drivers @@ -3624,15 +3576,11 @@ CONFIG_UIO_MSM_SHAREDMEM=y # CONFIG_STAGING=y # CONFIG_PRISM2_USB is not set -# CONFIG_COMEDI is not set -# CONFIG_RTL8192U is not set -# CONFIG_RTLLIB is not set # CONFIG_R8712U is not set # CONFIG_R8188EU is not set # CONFIG_R8723AU is not set # CONFIG_RTS5208 is not set # CONFIG_LINE6_USB is not set -# CONFIG_VT6655 is not set # CONFIG_FB_XGI is not set # CONFIG_BCM_WIMAX is not set # CONFIG_FT1000 is not set @@ -3670,8 +3618,6 @@ CONFIG_ION_MSM=y # CONFIG_FIQ_WATCHDOG is not set # CONFIG_USB_WPAN_HCD is not set # CONFIG_WIMAX_GDM72XX is not set -# CONFIG_LTE_GDM724X is not set -# CONFIG_LUSTRE_FS is not set # CONFIG_DGNC is not set # CONFIG_DGAP is not set # CONFIG_GS_FPGABOOT is not set @@ -4079,11 +4025,11 @@ CONFIG_ECRYPT_FS=y # CONFIG_QNX6FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_PSTORE=y +CONFIG_MSM_PRESERVE_MEM=y CONFIG_PSTORE_CONSOLE=y # CONFIG_PSTORE_PMSG is not set CONFIG_PSTORE_FTRACE=y CONFIG_PSTORE_RAM=y -CONFIG_MSM_PRESERVE_MEM=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set # CONFIG_F2FS_FS is not set @@ -4310,16 +4256,11 @@ CONFIG_FTRACE_MCOUNT_RECORD=y # CONFIG_TEST_LIST_SORT is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set -# CONFIG_INTERVAL_TREE_TEST is not set -# CONFIG_PERCPU_TEST is not set # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_TEST_STRING_HELPERS is not set # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_RHASHTABLE is not set # CONFIG_DMA_API_DEBUG is not set -# CONFIG_TEST_LKM is not set -# CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set # CONFIG_PANIC_ON_DATA_CORRUPTION is not set @@ -4333,7 +4274,6 @@ CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y # CONFIG_STRICT_DEVMEM is not set # CONFIG_PID_IN_CONTEXTIDR is not set # CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -CONFIG_DEBUG_SET_MODULE_RONX=y # CONFIG_FREE_PAGES_RDONLY is not set CONFIG_DEBUG_RODATA=y # CONFIG_DEBUG_ALIGN_RODATA is not set @@ -4407,7 +4347,6 @@ CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_CRYPTD=y # CONFIG_CRYPTO_MCRYPTD is not set CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set CONFIG_CRYPTO_ABLK_HELPER=y # @@ -4488,7 +4427,7 @@ CONFIG_CRYPTO_LZO=y # # Random Number Generation # -CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_ANSI_CPRNG=y # CONFIG_CRYPTO_DRBG_MENU is not set # CONFIG_CRYPTO_USER_API_HASH is not set # CONFIG_CRYPTO_USER_API_SKCIPHER is not set From 409dd94dd661e1cbe06aa08593f04253c8064341 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Sun, 21 May 2017 18:27:46 +0000 Subject: [PATCH 58/86] arch: arm: build device specific dtsi Change-Id: I052050a2787278d86535bba6c4aba55efa9879ee --- arch/arm/boot/dts/qcom/Makefile | 4 ++++ arch/arm64/configs/mido_defconfig | 18 +++++++++++------- drivers/platform/Kconfig | 1 + drivers/platform/xiaomi/Kconfig | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 drivers/platform/xiaomi/Kconfig diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 6a476dbaca86..b8f2e0558ae8 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -251,6 +251,9 @@ dtb-$(CONFIG_ARCH_MSM8940) += msm8940-pmi8937-cdp.dtb \ msm8940-pmi8940-rcm.dtb \ msm8940-pmi8940-qrd-sku7.dtb +ifeq ($(CONFIG_MACH_XIAOMI_MSM8953),y) +dtb-$(CONFIG_MACH_XIAOMI_MIDO) += msm8953-qrd-sku3.dtb +else dtb-$(CONFIG_ARCH_MSM8953) += msm8953-sim.dtb \ msm8953-rumi.dtb \ msm8953-cdp.dtb \ @@ -282,6 +285,7 @@ dtb-$(CONFIG_ARCH_SDM450) += sdm450-rcm.dtb \ sdm450-qrd.dtb \ sdm450-pmi8940-mtp.dtb \ sdm450-pmi8937-mtp.dtb +endif dtb-$(CONFIG_ARCH_MDM9607) += mdm9607-rumi.dtb \ mdm9607-cdp.dtb \ diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index 5e089b3374e9..cbf59d3f8e4c 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -310,11 +310,11 @@ CONFIG_ARCH_MSM=y CONFIG_ARCH_MSM8916=y # CONFIG_ARCH_MSM8917 is not set # CONFIG_ARCH_MSM8920 is not set -CONFIG_ARCH_MSM8940=y +# CONFIG_ARCH_MSM8940 is not set CONFIG_ARCH_MSM8953=y -CONFIG_ARCH_MSM8937=y +# CONFIG_ARCH_MSM8937 is not set # CONFIG_ARCH_MSM8996 is not set -CONFIG_ARCH_MSMCOBALT=y +# CONFIG_ARCH_MSMCOBALT is not set # # Bus support @@ -2040,10 +2040,7 @@ CONFIG_PINCTRL_MSM=y # CONFIG_PINCTRL_IPQ8064 is not set # CONFIG_PINCTRL_MSM8960 is not set # CONFIG_PINCTRL_MSM8X74 is not set -CONFIG_PINCTRL_MSM8952=y -CONFIG_PINCTRL_MSM8937=y -CONFIG_PINCTRL_MSMCOBALT=y -CONFIG_PINCTRL_MSM8940=y +# CONFIG_PINCTRL_MSM8952 is not set CONFIG_PINCTRL_MSM8953=y CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y @@ -3655,6 +3652,13 @@ CONFIG_MSM_11AD=y CONFIG_MSM_SPMI=y CONFIG_MSM_SPMI_PMIC_ARB=y CONFIG_MSM_QPNP_INT=y +# CONFIG_MSM_SPMI_DEBUGFS_RO is not set +CONFIG_MACH_XIAOMI_MSM8953=y + +# +# Xiaomi board selection +# +CONFIG_MACH_XIAOMI_MIDO=y # # SOC (System On Chip) specific Drivers diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig index b9b5ac01a0bf..832b358d5ee8 100644 --- a/drivers/platform/Kconfig +++ b/drivers/platform/Kconfig @@ -7,4 +7,5 @@ source "drivers/platform/chrome/Kconfig" if ARCH_MSM source "drivers/platform/msm/Kconfig" +source "drivers/platform/xiaomi/Kconfig" endif diff --git a/drivers/platform/xiaomi/Kconfig b/drivers/platform/xiaomi/Kconfig new file mode 100644 index 000000000000..671a4c19048e --- /dev/null +++ b/drivers/platform/xiaomi/Kconfig @@ -0,0 +1,17 @@ +# Xiaomi configuration options + +config MACH_XIAOMI_MSM8953 + bool "Xiaomi MSM8953" + depends on ARCH_MSM8953 + help + Support for MSM8953 Xiaomi variants + +menu "Xiaomi board selection" + +config MACH_XIAOMI_MIDO + bool "Mido board" + select MACH_XIAOMI_MSM8953 + help + Support for Redmi Note 4 SD Mido + +endmenu From 013c981dddac0de04a88b61ac22a185a08033c1c Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Tue, 23 May 2017 14:14:00 +0000 Subject: [PATCH 59/86] mido: Enable f2fs --- arch/arm64/configs/mido_defconfig | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index cbf59d3f8e4c..05d39403fbdc 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -3948,6 +3948,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_NILFS2_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_FILE_LOCKING=y +CONFIG_FS_ENCRYPTION=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y @@ -4036,7 +4037,15 @@ CONFIG_PSTORE_FTRACE=y CONFIG_PSTORE_RAM=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_F2FS_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_FS_POSIX_ACL=y +CONFIG_F2FS_FS_SECURITY=y +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_F2FS_FS_ENCRYPTION=y +# CONFIG_F2FS_IO_TRACE is not set +# CONFIG_F2FS_FAULT_INJECTION is not set # CONFIG_EFIVAR_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set @@ -4365,7 +4374,7 @@ CONFIG_CRYPTO_SEQIV=y # CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTR=y -# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_PCBC is not set @@ -4383,7 +4392,7 @@ CONFIG_CRYPTO_XCBC=y # Digest # CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_CRC32 is not set +CONFIG_CRYPTO_CRC32=y # CONFIG_CRYPTO_CRCT10DIF is not set # CONFIG_CRYPTO_GHASH is not set CONFIG_CRYPTO_MD4=y From 1cbdb3049b4f50f62c281f3beebe91803743f109 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Tue, 23 May 2017 00:28:29 +0800 Subject: [PATCH 60/86] drivers: input: touchscreen: ft5435_ts: Create shared procfs nodes * Creates sysfs nodes and procfs symlinks to it to easy handle disable_keys and dt2w functions from userspace --- drivers/input/touchscreen/ft5435/ft5435_ts.c | 116 ++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.c b/drivers/input/touchscreen/ft5435/ft5435_ts.c index 5138fc1523f8..eec02d2d37bf 100644 --- a/drivers/input/touchscreen/ft5435/ft5435_ts.c +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.c @@ -324,6 +324,7 @@ struct work_struct work_vr; u8 vr_on; #endif }; +static bool disable_keys_function = false; bool is_ft5435 = false; struct wake_lock ft5436_wakelock; @@ -1176,7 +1177,7 @@ static irqreturn_t ft5435_ts_interrupt(int irq, void *dev_id) input_mt_report_slot_state(ip_dev, MT_TOOL_FINGER, 0); } } else{ - if (data->pdata->fw_vkey_support) { + if (data->pdata->fw_vkey_support && !disable_keys_function) { for (j = 0; j < data->pdata->num_virkey; j++) { if (x == data->pdata->vkeys[j].x) { if (status == FT_TOUCH_DOWN || status == FT_TOUCH_CONTACT) @@ -3645,6 +3646,112 @@ static void ft5x0x_release_apk_debug_channel(void) } #endif +static ssize_t ft5435_ts_disable_keys_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const char c = disable_keys_function ? '1' : '0'; + return sprintf(buf, "%c\n", c); +} + +static ssize_t ft5435_ts_disable_keys_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int i; + + if (sscanf(buf, "%u", &i) == 1 && i < 2) { + disable_keys_function = (i == 1); + return count; + } else { + dev_dbg(dev, "disable_keys write error\n"); + return -EINVAL; + } +} + + +static DEVICE_ATTR(disable_keys, S_IWUSR | S_IRUSR, ft5435_ts_disable_keys_show, + ft5435_ts_disable_keys_store); + + + +static ssize_t ft5435_ts_enable_dt2w_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const char c = gesture_func_on ? '1' : '0'; + return sprintf(buf, "%c\n", c); +} + +static ssize_t ft5435_ts_enable_dt2w_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int i; + + if (sscanf(buf, "%u", &i) == 1 && i < 2) { + gesture_func_on = (i == 1); + return count; + } else { + dev_dbg(dev, "enable_dt2w write error\n"); + return -EINVAL; + } +} + + +static DEVICE_ATTR(enable_dt2w, S_IWUSR | S_IRUSR, ft5435_ts_enable_dt2w_show, + ft5435_ts_enable_dt2w_store); + +static struct attribute *ft5435_ts_attrs[] = { + &dev_attr_disable_keys.attr, + &dev_attr_enable_dt2w.attr, + NULL +}; + + +static const struct attribute_group ft5435_ts_attr_group = { + .attrs = ft5435_ts_attrs, +}; + +static int ft5435_proc_init(struct kernfs_node *sysfs_node_parent) +{ + int ret = 0; + char *buf, *path = NULL; + char *key_disabler_sysfs_node, *double_tap_sysfs_node; + struct proc_dir_entry *proc_entry_tp = NULL; + struct proc_dir_entry *proc_symlink_tmp = NULL; + buf = kzalloc(PATH_MAX, GFP_KERNEL); + if (buf) + path = kernfs_path(sysfs_node_parent, buf, PATH_MAX); + + proc_entry_tp = proc_mkdir("touchpanel", NULL); + if (proc_entry_tp == NULL) { + pr_err("%s: Couldn't create touchpanel dir in procfs\n", __func__); + ret = -ENOMEM; + } + + key_disabler_sysfs_node = kzalloc(PATH_MAX, GFP_KERNEL); + if (key_disabler_sysfs_node) + sprintf(key_disabler_sysfs_node, "/sys%s/%s", path, "disable_keys"); + proc_symlink_tmp = proc_symlink("capacitive_keys_disable", + proc_entry_tp, key_disabler_sysfs_node); + if (proc_symlink_tmp == NULL) { + pr_err("%s: Couldn't create capacitive_keys_enable symlink\n", __func__); + ret = -ENOMEM; + } + + double_tap_sysfs_node = kzalloc(PATH_MAX, GFP_KERNEL); + if (double_tap_sysfs_node) + sprintf(double_tap_sysfs_node, "/sys%s/%s", path, "enable_dt2w"); + proc_symlink_tmp = proc_symlink("enable_dt2w", + proc_entry_tp, double_tap_sysfs_node); + if (proc_symlink_tmp == NULL) { + ret = -ENOMEM; + pr_err("%s: Couldn't create double_tap_enable symlink\n", __func__); + } + + kfree(buf); + kfree(key_disabler_sysfs_node); + kfree(double_tap_sysfs_node); + return ret; +} + static char tp_info_summary[80] = ""; static int ft5435_ts_probe(struct i2c_client *client, @@ -4094,6 +4201,13 @@ g_ft5435_ts_data = data; if (ft5x0x_create_apk_debug_channel(client) < 0) ft5x0x_release_apk_debug_channel(); #endif + err = sysfs_create_group(&client->dev.kobj, &ft5435_ts_attr_group); + if (err) { + dev_err(&client->dev, "Failure %d creating sysfs group\n", + err); + goto free_reset_gpio; + } + ft5435_proc_init(client->dev.kobj.sd); w_buf[0] = FT_REG_RESET_FW; ft5435_i2c_write(client, w_buf, 1); From 445b6027a8060906fce4a1377cb1ee54b7ec6523 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Tue, 23 May 2017 12:41:55 +0800 Subject: [PATCH 61/86] drivers: input: touchscreen: ist30xxc: Create shared procfs nodes * Creates sysfs nodes and procfs symlinks to it to easy handle disable_keys and dt2w functions from userspace --- drivers/input/touchscreen/ist3038c/ist30xxc.c | 131 +++++++++++++++++- 1 file changed, 126 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/ist3038c/ist30xxc.c b/drivers/input/touchscreen/ist3038c/ist30xxc.c index b485ab5ea1be..c752b1859da4 100644 --- a/drivers/input/touchscreen/ist3038c/ist30xxc.c +++ b/drivers/input/touchscreen/ist3038c/ist30xxc.c @@ -76,6 +76,8 @@ struct ist30xx_data *ts_data; extern int set_usb_charge_mode_par; int ist30xx_log_level = IST30XX_LOG_LEVEL; +static bool disable_keys_function = false; + void tsp_printk(int level, const char *fmt, ...) { struct va_format vaf; @@ -814,13 +816,15 @@ static void report_input_data(struct ist30xx_data *data, int finger_counts, } #ifdef IST30XX_USE_KEY - status = PARSE_KEY_STATUS(data->t_status); - for (id = 0; id < ARRAY_SIZE(ist30xx_key_code); id++) { - press = (status & (1 << id)) ? true : false; + if(!disable_keys_function) { + status = PARSE_KEY_STATUS(data->t_status); + for (id = 0; id < ARRAY_SIZE(ist30xx_key_code); id++) { + press = (status & (1 << id)) ? true : false; - input_report_key(data->input_dev, ist30xx_key_code[id], press); + input_report_key(data->input_dev, ist30xx_key_code[id], press); - print_tkey_event(data, id); + print_tkey_event(data, id); + } } #endif @@ -1903,6 +1907,115 @@ static int fb_notifier_callback(struct notifier_block *self, } #endif + +static ssize_t ist30xx_ts_disable_keys_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const char c = disable_keys_function ? '1' : '0'; + return sprintf(buf, "%c\n", c); +} + +static ssize_t ist30xx_ts_disable_keys_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int i; + + if (sscanf(buf, "%u", &i) == 1 && i < 2) { + disable_keys_function = (i == 1); + return count; + } else { + dev_dbg(dev, "disable_keys write error\n"); + return -EINVAL; + } +} + + +static DEVICE_ATTR(disable_keys, S_IWUSR | S_IRUSR, ist30xx_ts_disable_keys_show, + ist30xx_ts_disable_keys_store); + + + +static ssize_t ist30xx_ts_enable_dt2w_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + const char c = ist30xx_gesture_func_on ? '1' : '0'; + return sprintf(buf, "%c\n", c); +} + +static ssize_t ist30xx_ts_enable_dt2w_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int i; + + if (sscanf(buf, "%u", &i) == 1 && i < 2) { + ist30xx_gesture_func_on = (i == 1); + return count; + } else { + dev_dbg(dev, "enable_dt2w write error\n"); + return -EINVAL; + } +} + + +static DEVICE_ATTR(enable_dt2w, S_IWUSR | S_IRUSR, ist30xx_ts_enable_dt2w_show, + ist30xx_ts_enable_dt2w_store); + +static struct attribute *ist30xx_ts_attrs[] = { + &dev_attr_disable_keys.attr, + &dev_attr_enable_dt2w.attr, + NULL +}; + + +static const struct attribute_group ist30xx_ts_attr_group = { + .attrs = ist30xx_ts_attrs, +}; + +static int ist30xx_proc_init(struct kernfs_node *sysfs_node_parent) +{ + int ret = 0; + char *buf, *path = NULL; + char *key_disabler_sysfs_node, *double_tap_sysfs_node; + struct proc_dir_entry *proc_entry_tp = NULL; + struct proc_dir_entry *proc_symlink_tmp = NULL; + buf = kzalloc(PATH_MAX, GFP_KERNEL); + if (buf) + path = kernfs_path(sysfs_node_parent, buf, PATH_MAX); + + proc_entry_tp = proc_mkdir("touchpanel", NULL); + if (proc_entry_tp == NULL) { + pr_err("%s: Couldn't create touchpanel dir in procfs\n", __func__); + ret = -ENOMEM; + } + + key_disabler_sysfs_node = kzalloc(PATH_MAX, GFP_KERNEL); + if (key_disabler_sysfs_node) + sprintf(key_disabler_sysfs_node, "/sys%s/%s", path, "disable_keys"); + proc_symlink_tmp = proc_symlink("capacitive_keys_disable", + proc_entry_tp, key_disabler_sysfs_node); + if (proc_symlink_tmp == NULL) { + pr_err("%s: Couldn't create capacitive_keys_enable symlink\n", __func__); + ret = -ENOMEM; + } + + double_tap_sysfs_node = kzalloc(PATH_MAX, GFP_KERNEL); + if (double_tap_sysfs_node) + sprintf(double_tap_sysfs_node, "/sys%s/%s", path, "enable_dt2w"); + proc_symlink_tmp = proc_symlink("enable_dt2w", + proc_entry_tp, double_tap_sysfs_node); + if (proc_symlink_tmp == NULL) { + ret = -ENOMEM; + pr_err("%s: Couldn't create double_tap_enable symlink\n", __func__); + } + + kfree(buf); + kfree(key_disabler_sysfs_node); + kfree(double_tap_sysfs_node); + return ret; +} + + + static char tp_info_summary[80] = ""; static int ist30xx_probe(struct i2c_client *client, @@ -2180,6 +2293,14 @@ static int ist30xx_probe(struct i2c_client *client, ist30xx_start(data); data->initialized = true; #endif + + ret = sysfs_create_group(&client->dev.kobj, &ist30xx_ts_attr_group); + if (ret) { + dev_err(&client->dev, "Failure %d creating sysfs group\n",ret); + goto err_alloc_dt; + } + ist30xx_proc_init(client->dev.kobj.sd); + strcpy(tp_info_summary, "[Vendor]Dongshan, [IC]IST3038C, [FW]Ver"); sprintf(tp_temp_info, "%x", data->fw.bin.fw_ver); strcat(tp_info_summary, tp_temp_info); From 6bed0cea3cfb7c922389907c5c6f5c0f5bf02135 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Tue, 23 May 2017 17:45:10 +0800 Subject: [PATCH 62/86] drivers: input: touchscreen: ft5435: enable glove mode sysfs node --- drivers/input/touchscreen/ft5435/ft5435_ts.c | 10 ++++------ drivers/input/touchscreen/ft5435/ft5435_ts.h | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.c b/drivers/input/touchscreen/ft5435/ft5435_ts.c index eec02d2d37bf..9d824784878b 100644 --- a/drivers/input/touchscreen/ft5435/ft5435_ts.c +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.c @@ -491,13 +491,10 @@ static ssize_t tp_glove_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ft5435_ts_data *data = NULL; - int ret; data = dev_get_drvdata(dev); - ret = snprintf(buf, 50, "glove_id show:%d\n", data->glove_id); - - return ret; + return sprintf(buf, "%d", data->glove_id); } static ssize_t tp_glove_id_store(struct device *dev, @@ -546,8 +543,9 @@ static DEVICE_ATTR(glove_enable, 0644, tp_glove_id_show, tp_glove_id_store); void tp_glove_register (struct ft5435_ts_data *data) { int rc = 0; - - tp_glove_dev = device_create(tp_device_class, NULL, 0, NULL, "tp_glove"); + struct class *tp_device_class = NULL; + tp_device_class = class_create(THIS_MODULE, "tp_glove"); + tp_glove_dev = device_create(tp_device_class, NULL, 0, NULL, "device"); if (IS_ERR(tp_glove_dev)) pr_err("Failed to create device(glove_ctrl)!\n"); diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.h b/drivers/input/touchscreen/ft5435/ft5435_ts.h index 986359e0a254..75c76ccb27fe 100644 --- a/drivers/input/touchscreen/ft5435/ft5435_ts.h +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.h @@ -31,6 +31,7 @@ #define FOCALTECH_LOCK_DOWN_INFO 1 #define FOCALTECH_TP_GESTURE #define FOCALTECH_FAE_MOD +#define FOCALTECH_TP_GLOVE #define USB_CHARGE_DETECT #define FOCALTECH_ITO_TEST 1 From 12a7527d563290be740d5a4962e1dc13cc50e021 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 25 May 2017 12:36:18 +0000 Subject: [PATCH 63/86] arch: dtsi: Increase max led brightness --- arch/arm/boot/dts/qcom/msm8953-qrd.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi index 35fcd50b1527..b23bf270f88b 100644 --- a/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953-qrd.dtsi @@ -185,7 +185,7 @@ aw2013,red { aw2013,name = "red"; aw2013,id = <0>; - aw2013,max-brightness = <150>; + aw2013,max-brightness = <255>; aw2013,max-current = <1>; aw2013,rise-time-ms = <3>; aw2013,hold-time-ms = <1>; @@ -196,7 +196,7 @@ aw2013,green { aw2013,name = "green"; aw2013,id = <1>; - aw2013,max-brightness = <150>; + aw2013,max-brightness = <255>; aw2013,max-current = <1>; aw2013,rise-time-ms = <3>; aw2013,hold-time-ms = <1>; @@ -207,7 +207,7 @@ aw2013,blue { aw2013,name = "blue"; aw2013,id = <2>; - aw2013,max-brightness = <150>; + aw2013,max-brightness = <255>; aw2013,max-current = <1>; aw2013,rise-time-ms = <3>; aw2013,hold-time-ms = <1>; From d8bd3af3c7255cdc21a7c196ab5327d6d39c9a95 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 25 May 2017 13:00:49 +0000 Subject: [PATCH 64/86] drivers: input: Stop ft5435 spam --- drivers/input/touchscreen/ft5435/ft5435_ts.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.c b/drivers/input/touchscreen/ft5435/ft5435_ts.c index 9d824784878b..9ab6371a399d 100644 --- a/drivers/input/touchscreen/ft5435/ft5435_ts.c +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.c @@ -1161,11 +1161,6 @@ static irqreturn_t ft5435_ts_interrupt(int irq, void *dev_id) break; input_mt_slot(ip_dev, id); - if (status == FT_TOUCH_DOWN) - printk("[FTS]Down pid[%d]:[%d, %d]\n", id, x, y); - else if (status == 1) - printk("[FTS]Up pid[%d]:[%d, %d]\n", id, x, y); - if (x < data->pdata->panel_maxx && y < data->pdata->panel_maxy) { if (status == FT_TOUCH_DOWN || status == FT_TOUCH_CONTACT) { input_mt_report_slot_state(ip_dev, MT_TOOL_FINGER, 1); From a3b43aece8cdce85a08ae3f8c37b91af0886872f Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 25 May 2017 13:07:50 +0000 Subject: [PATCH 65/86] driver: input: fingerprint: undef goodix debug --- drivers/input/fingerprint/goodix/gf_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/fingerprint/goodix/gf_spi.c b/drivers/input/fingerprint/goodix/gf_spi.c index 49e5a2a0844c..8c315a8ad546 100644 --- a/drivers/input/fingerprint/goodix/gf_spi.c +++ b/drivers/input/fingerprint/goodix/gf_spi.c @@ -81,8 +81,8 @@ struct gf_key_map key_map[] = { }; /**************************debug******************************/ -#define GF_DEBUG -/*#undef GF_DEBUG*/ +/*#define GF_DEBUG*/ +#undef GF_DEBUG #ifdef GF_DEBUG #define gf_dbg(fmt, args...) do { \ From 0b6b922d0dafe1b1bad60b68165af2336f10ddb2 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 25 May 2017 13:17:35 +0000 Subject: [PATCH 66/86] drivers: input: touchscreen: Set set_cover_mode permission to 0220 Fixes: [ 1.140622] Attribute set_cover_mode: read permission without 'show' --- drivers/input/touchscreen/ft5435/ft5435_ts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/ft5435/ft5435_ts.c b/drivers/input/touchscreen/ft5435/ft5435_ts.c index 9ab6371a399d..31466e9fc35c 100644 --- a/drivers/input/touchscreen/ft5435/ft5435_ts.c +++ b/drivers/input/touchscreen/ft5435/ft5435_ts.c @@ -2738,7 +2738,7 @@ static ssize_t fts_set_cover_mode(struct device *dev, } return ret; } -static DEVICE_ATTR(set_cover_mode, 0664, NULL, +static DEVICE_ATTR(set_cover_mode, 0220, NULL, fts_set_cover_mode); #endif From b07de28af2414c09c9d1bad15c25962531719d20 Mon Sep 17 00:00:00 2001 From: Willi Ye Date: Sun, 13 Sep 2015 12:24:59 +0200 Subject: [PATCH 67/86] qpnp-haptic: Add sysfs interface to control intensity Change-Id: Ib8ad562c5e847a8511bf1e2dbda7c0f863ea25dd --- drivers/platform/msm/qpnp-haptic.c | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c index b31cd841e43b..1e4f484c9ad9 100644 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -1379,6 +1379,44 @@ static ssize_t qpnp_hap_ramp_test_data_show(struct device *dev, } +static ssize_t qpnp_hap_vmax_mv_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vmax_mv); +} + +static ssize_t qpnp_hap_vmax_mv_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + u32 data; + int rc; + + if (sscanf(buf, "%d", &data) != 1) + return -EINVAL; + + if (data < QPNP_HAP_VMAX_MIN_MV) { + pr_err("%s: mv %d not in range (%d - %d), using min.", __func__, data, QPNP_HAP_VMAX_MIN_MV, QPNP_HAP_VMAX_MAX_MV); + data = QPNP_HAP_VMAX_MIN_MV; + } else if (data > QPNP_HAP_VMAX_MAX_MV) { + pr_err("%s: mv %d not in range (%d - %d), using max.", __func__, data, QPNP_HAP_VMAX_MIN_MV, QPNP_HAP_VMAX_MAX_MV); + data = QPNP_HAP_VMAX_MAX_MV; + } + + hap->vmax_mv = data; + rc = qpnp_hap_vmax_config(hap); + if (rc) + pr_info("qpnp: error while writing vibration control register\n"); + + return strnlen(buf, count); +} + /* sysfs attributes */ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(wf_s0, (S_IRUGO | S_IWUSR | S_IWGRP), @@ -1426,6 +1464,9 @@ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(min_max_test, (S_IRUGO | S_IWUSR | S_IWGRP), qpnp_hap_min_max_test_data_show, qpnp_hap_min_max_test_data_store), + __ATTR(vmax_mv, (S_IRUGO | S_IWUSR | S_IWGRP), + qpnp_hap_vmax_mv_show, + qpnp_hap_vmax_mv_store), }; static int calculate_lra_code(struct qpnp_hap *hap) From 6eee8ffcf33a4fd94c589eeca5fb8cee69997a1b Mon Sep 17 00:00:00 2001 From: dianlujitao Date: Fri, 1 Jul 2016 22:17:42 +0800 Subject: [PATCH 68/86] msm: qpnp-haptic: set up sysfs interface for common cmhw implementation * Rename vmax_mv to vtg_level * Add min/max/default voltage sysfs entries Change-Id: Iefa3accdb75fcef9bcb2d4c730ca0a72763994f3 --- drivers/platform/msm/qpnp-haptic.c | 98 ++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 12 deletions(-) diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c index 1e4f484c9ad9..c7afbb65b3ac 100644 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -357,6 +357,9 @@ struct qpnp_hap { u32 timeout_ms; u32 time_required_to_generate_back_emf_us; u32 vmax_mv; + u32 vtg_min; + u32 vtg_max; + u32 vtg_default; u32 ilim_ma; u32 sc_deb_cycles; u32 int_pwm_freq_khz; @@ -785,16 +788,16 @@ static int qpnp_hap_vmax_config(struct qpnp_hap *hap) u8 reg = 0; int rc, temp; - if (hap->vmax_mv < QPNP_HAP_VMAX_MIN_MV) - hap->vmax_mv = QPNP_HAP_VMAX_MIN_MV; - else if (hap->vmax_mv > QPNP_HAP_VMAX_MAX_MV) - hap->vmax_mv = QPNP_HAP_VMAX_MAX_MV; + if (hap->vmax_mv < hap->vtg_min) + hap->vmax_mv = hap->vtg_min; + else if (hap->vmax_mv > hap->vtg_max) + hap->vmax_mv = hap->vtg_max; rc = qpnp_hap_read_reg(hap, ®, QPNP_HAP_VMAX_REG(hap->base)); if (rc < 0) return rc; reg &= QPNP_HAP_VMAX_MASK; - temp = hap->vmax_mv / QPNP_HAP_VMAX_MIN_MV; + temp = hap->vmax_mv / hap->vtg_min; reg |= (temp << QPNP_HAP_VMAX_SHIFT); rc = qpnp_hap_write_reg(hap, ®, QPNP_HAP_VMAX_REG(hap->base)); if (rc) @@ -1401,12 +1404,14 @@ static ssize_t qpnp_hap_vmax_mv_store(struct device *dev, if (sscanf(buf, "%d", &data) != 1) return -EINVAL; - if (data < QPNP_HAP_VMAX_MIN_MV) { - pr_err("%s: mv %d not in range (%d - %d), using min.", __func__, data, QPNP_HAP_VMAX_MIN_MV, QPNP_HAP_VMAX_MAX_MV); - data = QPNP_HAP_VMAX_MIN_MV; - } else if (data > QPNP_HAP_VMAX_MAX_MV) { - pr_err("%s: mv %d not in range (%d - %d), using max.", __func__, data, QPNP_HAP_VMAX_MIN_MV, QPNP_HAP_VMAX_MAX_MV); - data = QPNP_HAP_VMAX_MAX_MV; + if (data < hap->vtg_min) { + pr_err("%s: mv %d not in range (%d - %d), using min.", __func__, data, + hap->vtg_min, hap->vtg_max); + data = hap->vtg_min; + } else if (data > hap->vtg_max) { + pr_err("%s: mv %d not in range (%d - %d), using max.", __func__, data, + hap->vtg_min, hap->vtg_max); + data = hap->vtg_max; } hap->vmax_mv = data; @@ -1417,6 +1422,39 @@ static ssize_t qpnp_hap_vmax_mv_store(struct device *dev, return strnlen(buf, count); } +static ssize_t qpnp_hap_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", hap->vtg_min); +} + +static ssize_t qpnp_hap_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", hap->vtg_max); +} + +static ssize_t qpnp_hap_default_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", hap->vtg_default); +} + /* sysfs attributes */ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(wf_s0, (S_IRUGO | S_IWUSR | S_IWGRP), @@ -1464,9 +1502,18 @@ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(min_max_test, (S_IRUGO | S_IWUSR | S_IWGRP), qpnp_hap_min_max_test_data_show, qpnp_hap_min_max_test_data_store), - __ATTR(vmax_mv, (S_IRUGO | S_IWUSR | S_IWGRP), + __ATTR(vtg_level, (S_IRUGO | S_IWUSR | S_IWGRP), qpnp_hap_vmax_mv_show, qpnp_hap_vmax_mv_store), + __ATTR(vtg_min, S_IRUGO, + qpnp_hap_min_show, + NULL), + __ATTR(vtg_max, S_IRUGO, + qpnp_hap_max_show, + NULL), + __ATTR(vtg_default, S_IRUGO, + qpnp_hap_default_show, + NULL), }; static int calculate_lra_code(struct qpnp_hap *hap) @@ -2431,6 +2478,33 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap) return rc; } + hap->vtg_min = QPNP_HAP_VMAX_MIN_MV; + rc = of_property_read_u32(spmi->dev.of_node, + "qcom,hap-vtg-min-mv", &temp); + if (!rc) { + hap->vtg_min = temp; + } else if (rc != -EINVAL) { + dev_err(&spmi->dev, "Unable to read vtg_min\n"); + return rc; + } + + hap->vtg_max = QPNP_HAP_VMAX_MAX_MV; + rc = of_property_read_u32(spmi->dev.of_node, + "qcom,hap-vtg-max-mv", &temp); + if (!rc) { + hap->vtg_max = temp; + } else if (rc != -EINVAL) { + dev_err(&spmi->dev, "Unable to read vtg_max\n"); + return rc; + } + + if (hap->vmax_mv < hap->vtg_min) + hap->vmax_mv = hap->vtg_min; + else if (hap->vmax_mv > hap->vtg_max) + hap->vmax_mv = hap->vtg_max; + + hap->vtg_default = hap->vmax_mv; + hap->ilim_ma = QPNP_HAP_ILIM_MIN_MV; rc = of_property_read_u32(spmi->dev.of_node, "qcom,ilim-ma", &temp); From 583e4268d206d3ddb368c197d998c0e839a18161 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 20 Jul 2016 12:48:01 -0700 Subject: [PATCH 69/86] qpnp-haptic: Dejank the haptics * Add mutexes and call hap_set without the workqueue for direct mode Change-Id: I98f5b8ddea572def2706ad2cfa18f9dd460757ed --- drivers/platform/msm/qpnp-haptic.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c index c7afbb65b3ac..5ad3b66e9cdc 100644 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -343,6 +343,7 @@ struct qpnp_hap { struct qpnp_pwm_info pwm_info; struct mutex lock; struct mutex wf_lock; + struct mutex set_lock; struct completion completion; enum qpnp_hap_mode play_mode; enum qpnp_hap_high_z lra_high_z; @@ -1679,6 +1680,8 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on) unsigned long timeout_ns = POLL_TIME_AUTO_RES_ERR_NS; u32 back_emf_delay_us = hap->time_required_to_generate_back_emf_us; + mutex_lock(&hap->set_lock); + if (hap->play_mode == QPNP_HAP_PWM) { if (on) rc = pwm_enable(hap->pwm_info.pwm_dev); @@ -1712,8 +1715,10 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on) qpnp_hap_auto_res_enable(hap, 0); rc = qpnp_hap_mod_enable(hap, on); - if (rc < 0) + if (rc < 0) { + mutex_unlock(&hap->set_lock); return rc; + } rc = qpnp_hap_play(hap, on); @@ -1723,8 +1728,10 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on) usleep_range(back_emf_delay_us, back_emf_delay_us + 1); rc = qpnp_hap_auto_res_enable(hap, 1); - if (rc < 0) + if (rc < 0) { + mutex_unlock(&hap->set_lock); return rc; + } } if (hap->act_type == QPNP_HAP_LRA && hap->correct_lra_drive_freq && @@ -1741,8 +1748,10 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on) } } else { rc = qpnp_hap_play(hap, on); - if (rc < 0) + if (rc < 0) { + mutex_unlock(&hap->set_lock); return rc; + } if (hap->act_type == QPNP_HAP_LRA && hap->correct_lra_drive_freq && @@ -1759,6 +1768,7 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on) } } + mutex_unlock(&hap->set_lock); return rc; } @@ -1767,6 +1777,7 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) { struct qpnp_hap *hap = container_of(dev, struct qpnp_hap, timed_dev); + flush_work(&hap->work); mutex_lock(&hap->lock); @@ -1792,7 +1803,10 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) HRTIMER_MODE_REL); } mutex_unlock(&hap->lock); - schedule_work(&hap->work); + if (hap->play_mode == QPNP_HAP_DIRECT) + qpnp_hap_set(hap, hap->state); + else + schedule_work(&hap->work); } /* play pwm bytes */ @@ -2675,6 +2689,8 @@ static int qpnp_haptic_probe(struct spmi_device *spmi) mutex_init(&hap->lock); mutex_init(&hap->wf_lock); + mutex_init(&hap->set_lock); + INIT_WORK(&hap->work, qpnp_hap_worker); INIT_DELAYED_WORK(&hap->sc_work, qpnp_handle_sc_irq); init_completion(&hap->completion); From c3e40f19acb31f0f5034c246d00ed0aa916239b6 Mon Sep 17 00:00:00 2001 From: Sultanxda Date: Tue, 2 Aug 2016 23:59:42 -0700 Subject: [PATCH 70/86] msm: qpnp-haptic: Process haptics asynchronously Blocking the timed_output sysfs node due to mutex contention causes severe device wake-up latency, as a process crucial to system resume writes to the timed_output vibrator node every time the device is resumed via the fingerprint reader (fingerprint reader triggers a haptic response on success). By processing haptics asynchronously via a worker, the timed_output sysfs won't get stalled for long periods of time (>30ms), and thus the device will consistently wake from sleep faster. Signed-off-by: Sultanxda msm: qpnp-haptic: Prevent redundant calls to disable vibrator A redundant call to disable the vibrator right before something wants to enable it results in lack of vibration. Avoid re-disabling haptics to fix this. Signed-off-by: Sultanxda msm: qpnp-haptic: Start shutoff timer after haptics actually start qpnp_hap_set() sometimes lags when enabling haptics, causing the shutoff timer to kill the haptics prematurely. Start the shutoff timer after haptics are enabled so that the requested duration is actually carried out. Change-Id: I91bad94d18415476b5b05c1e1a4a60ae180947df Signed-off-by: Sultanxda --- drivers/platform/msm/qpnp-haptic.c | 47 +++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c index 5ad3b66e9cdc..5ddd841a609e 100644 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -344,6 +344,8 @@ struct qpnp_hap { struct mutex lock; struct mutex wf_lock; struct mutex set_lock; + spinlock_t td_lock; + struct work_struct td_work; struct completion completion; enum qpnp_hap_mode play_mode; enum qpnp_hap_high_z lra_high_z; @@ -397,6 +399,7 @@ struct qpnp_hap { bool correct_lra_drive_freq; bool misc_trim_error_rc19p2_clk_reg_present; bool perform_lra_auto_resonance_search; + int td_value; }; static struct qpnp_hap *ghap; @@ -1772,11 +1775,20 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on) return rc; } -/* enable interface from timed output class */ -static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) +static void qpnp_timed_enable_worker(struct work_struct *work) { - struct qpnp_hap *hap = container_of(dev, struct qpnp_hap, - timed_dev); + struct qpnp_hap *hap = container_of(work, struct qpnp_hap, + td_work); + int value; + + spin_lock(&hap->td_lock); + value = hap->td_value; + spin_unlock(&hap->td_lock); + + /* Vibrator already disabled */ + if (!value && !hap->state) + return; + flush_work(&hap->work); mutex_lock(&hap->lock); @@ -1798,15 +1810,30 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) value = (value > hap->timeout_ms ? hap->timeout_ms : value); hap->state = 1; - hrtimer_start(&hap->hap_timer, - ktime_set(value / 1000, (value % 1000) * 1000000), - HRTIMER_MODE_REL); } mutex_unlock(&hap->lock); if (hap->play_mode == QPNP_HAP_DIRECT) qpnp_hap_set(hap, hap->state); else schedule_work(&hap->work); + + if (value) + hrtimer_start(&hap->hap_timer, + ktime_set(value / 1000, (value % 1000) * 1000000), + HRTIMER_MODE_REL); +} + +/* enable interface from timed output class */ +static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) +{ + struct qpnp_hap *hap = container_of(dev, struct qpnp_hap, + timed_dev); + + spin_lock(&hap->td_lock); + hap->td_value = value; + spin_unlock(&hap->td_lock); + + schedule_work(&hap->td_work); } /* play pwm bytes */ @@ -1925,6 +1952,10 @@ static enum hrtimer_restart qpnp_hap_timer(struct hrtimer *timer) struct qpnp_hap *hap = container_of(timer, struct qpnp_hap, hap_timer); + /* Vibrator already disabled */ + if (!hap->state) + return HRTIMER_NORESTART; + hap->state = 0; schedule_work(&hap->work); @@ -2690,10 +2721,12 @@ static int qpnp_haptic_probe(struct spmi_device *spmi) mutex_init(&hap->lock); mutex_init(&hap->wf_lock); mutex_init(&hap->set_lock); + spin_lock_init(&hap->td_lock); INIT_WORK(&hap->work, qpnp_hap_worker); INIT_DELAYED_WORK(&hap->sc_work, qpnp_handle_sc_irq); init_completion(&hap->completion); + INIT_WORK(&hap->td_work, qpnp_timed_enable_worker); hrtimer_init(&hap->hap_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hap->hap_timer.function = qpnp_hap_timer; From b3dc0505feafa2fe40929281ea494b1d63ff10f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Rivotti=20Casimiro?= Date: Mon, 15 May 2017 17:27:25 +0000 Subject: [PATCH 71/86] ASoC: wcd-mbhc: correct lineout detection Change-Id: I9b352b69872e9fb185404457f349c6abef923a4f --- sound/soc/codecs/wcd-mbhc-v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 02e91737eea0..4d1be88a3bc8 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -1237,7 +1237,8 @@ static void wcd_correct_swch_plug(struct work_struct *work) if ((plug_type == MBHC_PLUG_TYPE_HEADSET || plug_type == MBHC_PLUG_TYPE_HEADPHONE) && - (!wcd_swch_level_remove(mbhc))) { + (!wcd_swch_level_remove(mbhc)) && + (!mbhc->btn_press_intr)) { WCD_MBHC_RSC_LOCK(mbhc); wcd_mbhc_find_plug_and_report(mbhc, plug_type); WCD_MBHC_RSC_UNLOCK(mbhc); From 36ddab0241aa60c91c8b29b5596d2272ad26d01e Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Thu, 12 Nov 2015 16:03:00 -0200 Subject: [PATCH 72/86] bz#75751: Move internal header file lirc.h to uapi/ The file include/media/lirc.h describes a public interface and should thus be a public header. See kernel bug https://bugzilla.kernel.org/show_bug.cgi?id=75751 which has a manpage describing the interface + an acknowledgment that this info belongs to uapi. Change-Id: I968947c59914bc4353902de552c7079453d6e1de Signed-off-by: Mauro Carvalho Chehab --- include/media/lirc.h | 169 +------------------------------------- include/uapi/linux/lirc.h | 168 +++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 168 deletions(-) create mode 100644 include/uapi/linux/lirc.h diff --git a/include/media/lirc.h b/include/media/lirc.h index 4b3ab2966b5a..554988c860c1 100644 --- a/include/media/lirc.h +++ b/include/media/lirc.h @@ -1,168 +1 @@ -/* - * lirc.h - linux infrared remote control header file - * last modified 2010/07/13 by Jarod Wilson - */ - -#ifndef _LINUX_LIRC_H -#define _LINUX_LIRC_H - -#include -#include - -#define PULSE_BIT 0x01000000 -#define PULSE_MASK 0x00FFFFFF - -#define LIRC_MODE2_SPACE 0x00000000 -#define LIRC_MODE2_PULSE 0x01000000 -#define LIRC_MODE2_FREQUENCY 0x02000000 -#define LIRC_MODE2_TIMEOUT 0x03000000 - -#define LIRC_VALUE_MASK 0x00FFFFFF -#define LIRC_MODE2_MASK 0xFF000000 - -#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE) -#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE) -#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY) -#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT) - -#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK) -#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK) - -#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE) -#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE) -#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY) -#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT) - -/* used heavily by lirc userspace */ -#define lirc_t int - -/*** lirc compatible hardware features ***/ - -#define LIRC_MODE2SEND(x) (x) -#define LIRC_SEND2MODE(x) (x) -#define LIRC_MODE2REC(x) ((x) << 16) -#define LIRC_REC2MODE(x) ((x) >> 16) - -#define LIRC_MODE_RAW 0x00000001 -#define LIRC_MODE_PULSE 0x00000002 -#define LIRC_MODE_MODE2 0x00000004 -#define LIRC_MODE_LIRCCODE 0x00000010 - - -#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) -#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) -#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) -#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) - -#define LIRC_CAN_SEND_MASK 0x0000003f - -#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 -#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 -#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 - -#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) -#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) -#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) -#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) - -#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) - -#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) -#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) - -#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 -#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 -#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 -#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 -#define LIRC_CAN_SET_REC_FILTER 0x08000000 - -#define LIRC_CAN_MEASURE_CARRIER 0x02000000 -#define LIRC_CAN_USE_WIDEBAND_RECEIVER 0x04000000 - -#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) -#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) - -#define LIRC_CAN_NOTIFY_DECODE 0x01000000 - -/*** IOCTL commands for lirc driver ***/ - -#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32) - -#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) -#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) -#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) -#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) -#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) -#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) -#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) - -#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32) -#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32) - -#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32) -#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32) -#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32) -#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32) - -/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ -#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) - -#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32) -#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32) -/* Note: these can reset the according pulse_width */ -#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) -#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) -#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) -#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) -#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) - -/* - * when a timeout != 0 is set the driver will send a - * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is - * never sent, timeout is disabled by default - */ -#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32) - -/* 1 enables, 0 disables timeout reports in MODE2 */ -#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32) - -/* - * pulses shorter than this are filtered out by hardware (software - * emulation in lirc_dev?) - */ -#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32) -/* - * spaces shorter than this are filtered out by hardware (software - * emulation in lirc_dev?) - */ -#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32) -/* - * if filter cannot be set independently for pulse/space, this should - * be used - */ -#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32) - -/* - * if enabled from the next key press on the driver will send - * LIRC_MODE2_FREQUENCY packets - */ -#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32) - -/* - * to set a range use - * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the - * lower bound first and later - * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound - */ - -#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) -#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) - -#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) - -#define LIRC_SETUP_START _IO('i', 0x00000021) -#define LIRC_SETUP_END _IO('i', 0x00000022) - -#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) - -#endif +#include diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h new file mode 100644 index 000000000000..4b3ab2966b5a --- /dev/null +++ b/include/uapi/linux/lirc.h @@ -0,0 +1,168 @@ +/* + * lirc.h - linux infrared remote control header file + * last modified 2010/07/13 by Jarod Wilson + */ + +#ifndef _LINUX_LIRC_H +#define _LINUX_LIRC_H + +#include +#include + +#define PULSE_BIT 0x01000000 +#define PULSE_MASK 0x00FFFFFF + +#define LIRC_MODE2_SPACE 0x00000000 +#define LIRC_MODE2_PULSE 0x01000000 +#define LIRC_MODE2_FREQUENCY 0x02000000 +#define LIRC_MODE2_TIMEOUT 0x03000000 + +#define LIRC_VALUE_MASK 0x00FFFFFF +#define LIRC_MODE2_MASK 0xFF000000 + +#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE) +#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE) +#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY) +#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT) + +#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK) +#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK) + +#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE) +#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE) +#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY) +#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT) + +/* used heavily by lirc userspace */ +#define lirc_t int + +/*** lirc compatible hardware features ***/ + +#define LIRC_MODE2SEND(x) (x) +#define LIRC_SEND2MODE(x) (x) +#define LIRC_MODE2REC(x) ((x) << 16) +#define LIRC_REC2MODE(x) ((x) >> 16) + +#define LIRC_MODE_RAW 0x00000001 +#define LIRC_MODE_PULSE 0x00000002 +#define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_LIRCCODE 0x00000010 + + +#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) +#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) +#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) + +#define LIRC_CAN_SEND_MASK 0x0000003f + +#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 +#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 + +#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) +#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) +#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) + +#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) + +#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) +#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) + +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 +#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 +#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 +#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 +#define LIRC_CAN_SET_REC_FILTER 0x08000000 + +#define LIRC_CAN_MEASURE_CARRIER 0x02000000 +#define LIRC_CAN_USE_WIDEBAND_RECEIVER 0x04000000 + +#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) +#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) + +#define LIRC_CAN_NOTIFY_DECODE 0x01000000 + +/*** IOCTL commands for lirc driver ***/ + +#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32) + +#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) +#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) +#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) +#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) +#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) +#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) +#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) + +#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32) +#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32) + +#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32) +#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32) +#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32) +#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32) + +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ +#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) + +#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32) +#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32) +/* Note: these can reset the according pulse_width */ +#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) +#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) +#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) +#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) +#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) + +/* + * when a timeout != 0 is set the driver will send a + * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is + * never sent, timeout is disabled by default + */ +#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32) + +/* 1 enables, 0 disables timeout reports in MODE2 */ +#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32) + +/* + * pulses shorter than this are filtered out by hardware (software + * emulation in lirc_dev?) + */ +#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32) +/* + * spaces shorter than this are filtered out by hardware (software + * emulation in lirc_dev?) + */ +#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32) +/* + * if filter cannot be set independently for pulse/space, this should + * be used + */ +#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32) + +/* + * if enabled from the next key press on the driver will send + * LIRC_MODE2_FREQUENCY packets + */ +#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32) + +/* + * to set a range use + * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the + * lower bound first and later + * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound + */ + +#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) +#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) + +#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) + +#define LIRC_SETUP_START _IO('i', 0x00000021) +#define LIRC_SETUP_END _IO('i', 0x00000022) + +#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) + +#endif From fce4a89b4be675f0ae299c8a158a8a342bbd32b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Jul 2016 09:45:32 -0300 Subject: [PATCH 73/86] lirc.h: remove several unused ioctls While reviewing the documentation gaps on LIRC, it was noticed that several ioctls aren't used by any LIRC drivers (nor at staging or mainstream). It doesn't make sense to document them, as they're not used anywhere. So, let's remove those from the lirc header. Change-Id: Iaa49ec4d89612a0c9fb08ef5bd4489d20a0d66ed Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/lirc.h | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index 4b3ab2966b5a..991ab4570b8e 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h @@ -90,20 +90,11 @@ #define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) #define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) -#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) -#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) -#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) -#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) #define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) #define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32) #define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32) -#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32) -#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32) -#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32) -#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32) - /* code length in bits, currently only for LIRC_MODE_LIRCCODE */ #define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) @@ -113,7 +104,6 @@ #define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) #define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) #define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) -#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) #define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) /* @@ -126,22 +116,6 @@ /* 1 enables, 0 disables timeout reports in MODE2 */ #define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32) -/* - * pulses shorter than this are filtered out by hardware (software - * emulation in lirc_dev?) - */ -#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32) -/* - * spaces shorter than this are filtered out by hardware (software - * emulation in lirc_dev?) - */ -#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32) -/* - * if filter cannot be set independently for pulse/space, this should - * be used - */ -#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32) - /* * if enabled from the next key press on the driver will send * LIRC_MODE2_FREQUENCY packets @@ -149,20 +123,11 @@ #define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32) /* - * to set a range use - * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the - * lower bound first and later - * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound + * to set a range use LIRC_SET_REC_CARRIER_RANGE with the + * lower bound first and later LIRC_SET_REC_CARRIER with the upper bound */ - -#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) #define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) -#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) - -#define LIRC_SETUP_START _IO('i', 0x00000021) -#define LIRC_SETUP_END _IO('i', 0x00000022) - #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) #endif From 49034345983008b34536b9b77abd22d3cdcd227e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Jul 2016 12:07:15 -0700 Subject: [PATCH 74/86] uapi: export lirc.h header This header contains the userspace API for lirc. This is a fixup for commit b7be755733dc ("[media] bz#75751: Move internal header file lirc.h to uapi/"). It moved the header to the right place, but it forgot to add it at Kbuild. So, despite being at uapi, it is not copied to the right place. Change-Id: I348f9ba4207504393ae8ab64406dd6e4522d0acb Fixes: b7be755733dc44c72 ("[media] bz#75751: Move internal header file lirc.h to uapi/") Link: http://lkml.kernel.org/r/320c765d32bfc82c582e336d52ffe1026c73c644.1468439021.git.mchehab@s-opensource.com Signed-off-by: Mauro Carvalho Chehab Cc: Alec Leamas Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/uapi/linux/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 06a5fb00642e..7988972777aa 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -246,6 +246,7 @@ endif header-y += l2tp.h header-y += libc-compat.h +header-y += lirc.h header-y += limits.h header-y += llc.h header-y += loop.h From 9591ce3fb78dd13e0e41f8948c1af1ed0cd8bff2 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Sun, 30 Jul 2017 13:43:50 +0200 Subject: [PATCH 75/86] mido: enable sdcardfs Change-Id: I0cb0e3d930ac569e2f516aac6f86179dac78baa2 Signed-off-by: TheScarastic --- arch/arm64/configs/mido_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index 05d39403fbdc..8a033ade08b6 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -4013,7 +4013,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_AFFS_FS is not set CONFIG_ECRYPT_FS=y # CONFIG_ECRYPT_FS_MESSAGING is not set -# CONFIG_SDCARD_FS is not set +CONFIG_SDCARD_FS=y # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set From f177f9c9d6009a7b179ea41aa619bb9355a448ef Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Fri, 25 Aug 2017 01:10:14 +0530 Subject: [PATCH 76/86] mido: Enable CONFIG_ANDROID_BINDER_DEVICES --- arch/arm64/configs/mido_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index 8a033ade08b6..ec2c1e4526d1 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -3593,6 +3593,7 @@ CONFIG_STAGING=y # CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDER_DEVICES=y CONFIG_ASHMEM=y # CONFIG_ANDROID_LOGGER is not set CONFIG_ANDROID_TIMED_OUTPUT=y From 59af1b565800e06b21f55d767ed4edb7aa93cce6 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Fri, 29 Sep 2017 16:17:29 +0800 Subject: [PATCH 77/86] mido: config: remove obsolete CONFIG_MSM_SPCOM Change-Id: I02a83bb9c91ce8d54f4c142412c6ac3b0cd7e61a --- arch/arm64/configs/mido_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index ec2c1e4526d1..b2b738ebe452 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -3710,7 +3710,6 @@ CONFIG_MSM_GLINK=y CONFIG_MSM_GLINK_LOOPBACK_SERVER=y CONFIG_MSM_GLINK_SMD_XPRT=y CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y -CONFIG_MSM_SPCOM=y CONFIG_MSM_SMEM_LOGGING=y CONFIG_MSM_SMP2P=y CONFIG_MSM_SMP2P_TEST=y From 22b45299923015ce3e2f3d6dc525e964671ee74e Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Sat, 30 Sep 2017 00:07:09 +0800 Subject: [PATCH 78/86] arch: arm: boot: dts: Do not mount /vendor from dts mido doesnt have /vendor Change-Id: Ic4d984cd8d5748efb86018560a89beb670511a76 --- arch/arm/boot/dts/qcom/msm8953.dtsi | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm8953.dtsi b/arch/arm/boot/dts/qcom/msm8953.dtsi index de6bc38ba3fb..6b6585362ab0 100644 --- a/arch/arm/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm/boot/dts/qcom/msm8953.dtsi @@ -32,14 +32,6 @@ compatible = "android,firmware"; fstab { compatible = "android,fstab"; - vendor { - compatible = "android,vendor"; - dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; - type = "ext4"; - mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait"; - status = "ok"; - }; system { compatible = "android,system"; dev = "/dev/block/platform/soc/7824900.sdhci/by-name/system"; From fc693fd470b600e5a8350739814d81a26d6b7de8 Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Sat, 30 Sep 2017 22:37:33 +0800 Subject: [PATCH 79/86] drivers: staging: Import prima * caf tag LA.UM.6.6.r1-03000-89xx.0 Change-Id: Ib8ab580c6dc1aad533b2c5aa462c7394d7a0a9aa --- arch/arm64/configs/mido_defconfig | 15 + drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 2 + drivers/staging/prima/Android.mk | 156 + drivers/staging/prima/CORE/BAP/inc/bapApi.h | 2950 + drivers/staging/prima/CORE/BAP/inc/btampHCI.h | 2129 + .../staging/prima/CORE/BAP/src/bapApiData.c | 1274 + .../staging/prima/CORE/BAP/src/bapApiDebug.c | 204 + .../staging/prima/CORE/BAP/src/bapApiExt.c | 181 + .../staging/prima/CORE/BAP/src/bapApiExt.h | 164 + .../staging/prima/CORE/BAP/src/bapApiHCBB.c | 1698 + .../staging/prima/CORE/BAP/src/bapApiInfo.c | 608 + .../prima/CORE/BAP/src/bapApiLinkCntl.c | 1941 + .../CORE/BAP/src/bapApiLinkSupervision.c | 636 + .../staging/prima/CORE/BAP/src/bapApiStatus.c | 854 + .../staging/prima/CORE/BAP/src/bapApiTimer.c | 1037 + .../staging/prima/CORE/BAP/src/bapApiTimer.h | 243 + .../staging/prima/CORE/BAP/src/bapInternal.h | 1314 + .../staging/prima/CORE/BAP/src/bapModule.c | 1401 + .../prima/CORE/BAP/src/bapRsn8021xAuthFsm.c | 1619 + .../prima/CORE/BAP/src/bapRsn8021xAuthFsm.h | 88 + .../prima/CORE/BAP/src/bapRsn8021xFsm.h | 457 + .../prima/CORE/BAP/src/bapRsn8021xPrf.c | 273 + .../prima/CORE/BAP/src/bapRsn8021xPrf.h | 172 + .../CORE/BAP/src/bapRsn8021xSuppRsnFsm.c | 1164 + .../CORE/BAP/src/bapRsn8021xSuppRsnFsm.h | 64 + .../prima/CORE/BAP/src/bapRsnAsfPacket.c | 1020 + .../prima/CORE/BAP/src/bapRsnAsfPacket.h | 612 + .../staging/prima/CORE/BAP/src/bapRsnErrors.h | 283 + .../prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.c | 399 + .../prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.h | 104 + .../prima/CORE/BAP/src/bapRsnSsmEapol.c | 1129 + .../prima/CORE/BAP/src/bapRsnSsmEapol.h | 333 + .../prima/CORE/BAP/src/bapRsnSsmReplayCtr.c | 249 + .../prima/CORE/BAP/src/bapRsnSsmReplayCtr.h | 156 + .../prima/CORE/BAP/src/bapRsnSsmServices.h | 300 + .../staging/prima/CORE/BAP/src/bapRsnTxRx.c | 275 + .../staging/prima/CORE/BAP/src/bapRsnTxRx.h | 87 + drivers/staging/prima/CORE/BAP/src/btampFsm.c | 2697 + drivers/staging/prima/CORE/BAP/src/btampFsm.h | 89 + .../staging/prima/CORE/BAP/src/btampFsm_ext.h | 64 + drivers/staging/prima/CORE/BAP/src/btampHCI.c | 9312 ++++ drivers/staging/prima/CORE/BAP/src/fsmDefs.h | 40 + .../staging/prima/CORE/DXE/inc/wlan_qct_dxe.h | 474 + .../staging/prima/CORE/DXE/src/wlan_qct_dxe.c | 5980 ++ .../prima/CORE/DXE/src/wlan_qct_dxe_cfg_i.c | 729 + .../prima/CORE/DXE/src/wlan_qct_dxe_i.h | 814 + .../staging/prima/CORE/HDD/inc/bap_hdd_main.h | 88 + .../staging/prima/CORE/HDD/inc/bap_hdd_misc.h | 139 + .../staging/prima/CORE/HDD/inc/qc_sap_ioctl.h | 207 + .../prima/CORE/HDD/inc/wlan_hdd_assoc.h | 248 + .../staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h | 3817 ++ .../prima/CORE/HDD/inc/wlan_hdd_cfg80211.h | 1665 + .../prima/CORE/HDD/inc/wlan_hdd_debugfs.h | 44 + .../prima/CORE/HDD/inc/wlan_hdd_dev_pwr.h | 109 + .../prima/CORE/HDD/inc/wlan_hdd_dp_utils.h | 118 + .../prima/CORE/HDD/inc/wlan_hdd_ether.h | 90 + .../staging/prima/CORE/HDD/inc/wlan_hdd_ftm.h | 224 + .../CORE/HDD/inc/wlan_hdd_host_offload.h | 74 + .../prima/CORE/HDD/inc/wlan_hdd_hostapd.h | 149 + .../prima/CORE/HDD/inc/wlan_hdd_includes.h | 74 + .../prima/CORE/HDD/inc/wlan_hdd_keep_alive.h | 60 + .../prima/CORE/HDD/inc/wlan_hdd_main.h | 2229 + .../staging/prima/CORE/HDD/inc/wlan_hdd_mib.h | 228 + .../prima/CORE/HDD/inc/wlan_hdd_oemdata.h | 165 + .../staging/prima/CORE/HDD/inc/wlan_hdd_p2p.h | 201 + .../CORE/HDD/inc/wlan_hdd_packet_filtering.h | 115 + .../prima/CORE/HDD/inc/wlan_hdd_power.h | 145 + .../CORE/HDD/inc/wlan_hdd_softap_tx_rx.h | 350 + .../prima/CORE/HDD/inc/wlan_hdd_tdls.h | 544 + .../prima/CORE/HDD/inc/wlan_hdd_trace.h | 121 + .../prima/CORE/HDD/inc/wlan_hdd_tx_rx.h | 413 + .../prima/CORE/HDD/inc/wlan_hdd_version.h | 97 + .../prima/CORE/HDD/inc/wlan_hdd_wext.h | 468 + .../staging/prima/CORE/HDD/inc/wlan_hdd_wmm.h | 426 + .../prima/CORE/HDD/inc/wlan_hdd_wowl.h | 205 + .../prima/CORE/HDD/inc/wlan_qct_driver.h | 81 + .../staging/prima/CORE/HDD/src/bap_hdd_main.c | 4542 ++ .../prima/CORE/HDD/src/wlan_hdd_assoc.c | 5876 ++ .../staging/prima/CORE/HDD/src/wlan_hdd_cfg.c | 6882 +++ .../prima/CORE/HDD/src/wlan_hdd_cfg80211.c | 20804 +++++++ .../prima/CORE/HDD/src/wlan_hdd_debugfs.c | 568 + .../prima/CORE/HDD/src/wlan_hdd_dev_pwr.c | 774 + .../prima/CORE/HDD/src/wlan_hdd_dp_utils.c | 222 + .../CORE/HDD/src/wlan_hdd_early_suspend.c | 2857 + .../staging/prima/CORE/HDD/src/wlan_hdd_ftm.c | 5967 ++ .../prima/CORE/HDD/src/wlan_hdd_hostapd.c | 5404 ++ .../prima/CORE/HDD/src/wlan_hdd_main.c | 17039 ++++++ .../staging/prima/CORE/HDD/src/wlan_hdd_mib.c | 217 + .../prima/CORE/HDD/src/wlan_hdd_oemdata.c | 1011 + .../staging/prima/CORE/HDD/src/wlan_hdd_p2p.c | 2894 + .../prima/CORE/HDD/src/wlan_hdd_scan.c | 1332 + .../CORE/HDD/src/wlan_hdd_softap_tx_rx.c | 2229 + .../prima/CORE/HDD/src/wlan_hdd_tdls.c | 3685 ++ .../prima/CORE/HDD/src/wlan_hdd_trace.c | 199 + .../prima/CORE/HDD/src/wlan_hdd_tx_rx.c | 3247 ++ .../prima/CORE/HDD/src/wlan_hdd_wext.c | 12050 ++++ .../staging/prima/CORE/HDD/src/wlan_hdd_wmm.c | 3215 ++ .../prima/CORE/HDD/src/wlan_hdd_wowl.c | 611 + .../staging/prima/CORE/MAC/inc/aniCompiler.h | 145 + .../staging/prima/CORE/MAC/inc/aniDbgTest.h | 1588 + .../staging/prima/CORE/MAC/inc/aniGlobal.h | 1116 + drivers/staging/prima/CORE/MAC/inc/aniParam.h | 87 + .../prima/CORE/MAC/inc/aniSystemDefs.h | 273 + drivers/staging/prima/CORE/MAC/inc/logDump.h | 88 + .../staging/prima/CORE/MAC/inc/macInitApi.h | 51 + drivers/staging/prima/CORE/MAC/inc/macTrace.h | 84 + .../prima/CORE/MAC/inc/qwlan_version.h | 51 + drivers/staging/prima/CORE/MAC/inc/sirApi.h | 6330 +++ .../prima/CORE/MAC/inc/sirMacPropExts.h | 328 + .../prima/CORE/MAC/inc/sirMacProtDef.h | 2922 + drivers/staging/prima/CORE/MAC/inc/sirTypes.h | 210 + drivers/staging/prima/CORE/MAC/inc/wniApi.h | 720 + drivers/staging/prima/CORE/MAC/inc/wniCfg.h | 1956 + drivers/staging/prima/CORE/MAC/inc/wniStat.h | 80 + .../staging/prima/CORE/MAC/src/cfg/cfgApi.c | 1198 + .../staging/prima/CORE/MAC/src/cfg/cfgDebug.c | 58 + .../staging/prima/CORE/MAC/src/cfg/cfgDebug.h | 52 + .../staging/prima/CORE/MAC/src/cfg/cfgDef.h | 77 + .../prima/CORE/MAC/src/cfg/cfgParamName.c | 378 + .../staging/prima/CORE/MAC/src/cfg/cfgPriv.h | 109 + .../prima/CORE/MAC/src/cfg/cfgProcMsg.c | 2791 + .../prima/CORE/MAC/src/cfg/cfgSendMsg.c | 155 + .../prima/CORE/MAC/src/cfg/cfgUtil/cfg.txt | 5031 ++ .../CORE/MAC/src/cfg/cfgUtil/dot11f.frms | 4277 ++ .../staging/prima/CORE/MAC/src/cfg/polFile.h | 175 + .../prima/CORE/MAC/src/dph/dphHashTable.c | 485 + .../prima/CORE/MAC/src/dph/dphHashTable.h | 93 + .../prima/CORE/MAC/src/include/cfgApi.h | 139 + .../prima/CORE/MAC/src/include/cfgGlobal.h | 94 + .../prima/CORE/MAC/src/include/dot11f.h | 7938 +++ .../prima/CORE/MAC/src/include/dphGlobal.h | 708 + .../prima/CORE/MAC/src/include/parserApi.h | 1017 + .../prima/CORE/MAC/src/include/phyGlobal.h | 105 + .../prima/CORE/MAC/src/include/sirCommon.h | 55 + .../prima/CORE/MAC/src/include/sirDebug.h | 137 + .../prima/CORE/MAC/src/include/sirParams.h | 985 + .../prima/CORE/MAC/src/include/sysGlobal.h | 56 + .../prima/CORE/MAC/src/include/utilsApi.h | 739 + .../prima/CORE/MAC/src/include/utilsGlobal.h | 57 + .../CORE/MAC/src/pe/include/limAdmitControl.h | 108 + .../prima/CORE/MAC/src/pe/include/limApi.h | 259 + .../prima/CORE/MAC/src/pe/include/limFT.h | 75 + .../prima/CORE/MAC/src/pe/include/limFTDefs.h | 132 + .../prima/CORE/MAC/src/pe/include/limGlobal.h | 720 + .../CORE/MAC/src/pe/include/limSession.h | 508 + .../prima/CORE/MAC/src/pe/include/limTrace.h | 111 + .../prima/CORE/MAC/src/pe/include/lim_mbb.h | 48 + .../prima/CORE/MAC/src/pe/include/pmmApi.h | 149 + .../prima/CORE/MAC/src/pe/include/pmmGlobal.h | 197 + .../prima/CORE/MAC/src/pe/include/rrmApi.h | 104 + .../prima/CORE/MAC/src/pe/include/rrmGlobal.h | 231 + .../prima/CORE/MAC/src/pe/include/schApi.h | 104 + .../prima/CORE/MAC/src/pe/include/schGlobal.h | 223 + .../prima/CORE/MAC/src/pe/include/wmmApsd.h | 74 + .../prima/CORE/MAC/src/pe/lim/limAIDmgmt.c | 193 + .../CORE/MAC/src/pe/lim/limAdmitControl.c | 1265 + .../prima/CORE/MAC/src/pe/lim/limApi.c | 2860 + .../prima/CORE/MAC/src/pe/lim/limAssocUtils.c | 4828 ++ .../prima/CORE/MAC/src/pe/lim/limAssocUtils.h | 194 + .../prima/CORE/MAC/src/pe/lim/limDebug.c | 58 + .../prima/CORE/MAC/src/pe/lim/limDebug.h | 61 + .../staging/prima/CORE/MAC/src/pe/lim/limFT.c | 1755 + .../CORE/MAC/src/pe/lim/limIbssPeerMgmt.c | 1913 + .../CORE/MAC/src/pe/lim/limIbssPeerMgmt.h | 54 + .../MAC/src/pe/lim/limLinkMonitoringAlgo.c | 569 + .../prima/CORE/MAC/src/pe/lim/limLogDump.c | 2594 + .../prima/CORE/MAC/src/pe/lim/limP2P.c | 1289 + .../MAC/src/pe/lim/limProcessActionFrame.c | 2786 + .../MAC/src/pe/lim/limProcessAssocReqFrame.c | 1809 + .../MAC/src/pe/lim/limProcessAssocRspFrame.c | 1037 + .../CORE/MAC/src/pe/lim/limProcessAuthFrame.c | 2021 + .../MAC/src/pe/lim/limProcessBeaconFrame.c | 319 + .../MAC/src/pe/lim/limProcessCfgUpdates.c | 800 + .../MAC/src/pe/lim/limProcessDeauthFrame.c | 542 + .../MAC/src/pe/lim/limProcessDisassocFrame.c | 355 + .../MAC/src/pe/lim/limProcessLmmMessages.c | 53 + .../MAC/src/pe/lim/limProcessMessageQueue.c | 2800 + .../MAC/src/pe/lim/limProcessMlmReqMessages.c | 5215 ++ .../MAC/src/pe/lim/limProcessMlmRspMessages.c | 5324 ++ .../MAC/src/pe/lim/limProcessProbeReqFrame.c | 851 + .../MAC/src/pe/lim/limProcessProbeRspFrame.c | 508 + .../MAC/src/pe/lim/limProcessSmeReqMessages.c | 5998 ++ .../CORE/MAC/src/pe/lim/limProcessTdls.c | 3963 ++ .../CORE/MAC/src/pe/lim/limPropExtsUtils.c | 302 + .../CORE/MAC/src/pe/lim/limPropExtsUtils.h | 68 + .../prima/CORE/MAC/src/pe/lim/limRMC.c | 1382 + .../prima/CORE/MAC/src/pe/lim/limRMC.h | 113 + .../CORE/MAC/src/pe/lim/limRoamingAlgo.c | 321 + .../CORE/MAC/src/pe/lim/limScanResultUtils.c | 1306 + .../CORE/MAC/src/pe/lim/limScanResultUtils.h | 76 + .../CORE/MAC/src/pe/lim/limSecurityUtils.c | 1386 + .../CORE/MAC/src/pe/lim/limSecurityUtils.h | 108 + .../MAC/src/pe/lim/limSendManagementFrames.c | 7205 +++ .../CORE/MAC/src/pe/lim/limSendMessages.c | 1010 + .../CORE/MAC/src/pe/lim/limSendMessages.h | 104 + .../MAC/src/pe/lim/limSendSmeRspMessages.c | 2993 + .../MAC/src/pe/lim/limSendSmeRspMessages.h | 124 + .../CORE/MAC/src/pe/lim/limSerDesUtils.c | 2917 + .../CORE/MAC/src/pe/lim/limSerDesUtils.h | 129 + .../prima/CORE/MAC/src/pe/lim/limSession.c | 558 + .../CORE/MAC/src/pe/lim/limSessionUtils.c | 492 + .../CORE/MAC/src/pe/lim/limSessionUtils.h | 257 + .../CORE/MAC/src/pe/lim/limSmeReqUtils.c | 1155 + .../CORE/MAC/src/pe/lim/limSmeReqUtils.h | 61 + .../prima/CORE/MAC/src/pe/lim/limStaHashApi.c | 78 + .../prima/CORE/MAC/src/pe/lim/limStaHashApi.h | 54 + .../prima/CORE/MAC/src/pe/lim/limTimerUtils.c | 2468 + .../prima/CORE/MAC/src/pe/lim/limTimerUtils.h | 141 + .../prima/CORE/MAC/src/pe/lim/limTrace.c | 556 + .../prima/CORE/MAC/src/pe/lim/limTypes.h | 1088 + .../prima/CORE/MAC/src/pe/lim/limUtils.c | 9253 ++++ .../prima/CORE/MAC/src/pe/lim/limUtils.h | 587 + .../prima/CORE/MAC/src/pe/lim/lim_mbb.c | 1754 + .../staging/prima/CORE/MAC/src/pe/pmm/pmmAP.c | 102 + .../prima/CORE/MAC/src/pe/pmm/pmmApi.c | 3092 ++ .../prima/CORE/MAC/src/pe/pmm/pmmDebug.c | 58 + .../prima/CORE/MAC/src/pe/pmm/pmmDebug.h | 55 + .../prima/CORE/MAC/src/pe/rrm/rrmApi.c | 1360 + .../prima/CORE/MAC/src/pe/sch/schApi.c | 596 + .../prima/CORE/MAC/src/pe/sch/schBeaconGen.c | 891 + .../CORE/MAC/src/pe/sch/schBeaconProcess.c | 915 + .../prima/CORE/MAC/src/pe/sch/schDebug.c | 64 + .../prima/CORE/MAC/src/pe/sch/schDebug.h | 56 + .../prima/CORE/MAC/src/pe/sch/schMessage.c | 616 + .../prima/CORE/MAC/src/pe/sch/schSysParams.h | 107 + drivers/staging/prima/CORE/SAP/inc/sapApi.h | 1627 + .../prima/CORE/SAP/src/sapApiLinkCntl.c | 1600 + .../staging/prima/CORE/SAP/src/sapChSelect.c | 2338 + .../staging/prima/CORE/SAP/src/sapChSelect.h | 157 + drivers/staging/prima/CORE/SAP/src/sapFsm.c | 2147 + .../staging/prima/CORE/SAP/src/sapFsm_ext.h | 58 + .../staging/prima/CORE/SAP/src/sapInternal.h | 919 + .../staging/prima/CORE/SAP/src/sapModule.c | 2461 + drivers/staging/prima/CORE/SME/inc/btcApi.h | 399 + drivers/staging/prima/CORE/SME/inc/ccmApi.h | 119 + drivers/staging/prima/CORE/SME/inc/csrApi.h | 1782 + .../staging/prima/CORE/SME/inc/csrInternal.h | 1517 + .../staging/prima/CORE/SME/inc/csrLinkList.h | 120 + .../prima/CORE/SME/inc/csrNeighborRoam.h | 328 + .../staging/prima/CORE/SME/inc/csrSupport.h | 839 + .../staging/prima/CORE/SME/inc/csr_roam_mbb.h | 41 + drivers/staging/prima/CORE/SME/inc/nan_Api.h | 109 + .../staging/prima/CORE/SME/inc/oemDataApi.h | 170 + .../prima/CORE/SME/inc/oemDataInternal.h | 76 + drivers/staging/prima/CORE/SME/inc/p2p_Api.h | 539 + drivers/staging/prima/CORE/SME/inc/pmc.h | 268 + drivers/staging/prima/CORE/SME/inc/pmcApi.h | 556 + .../staging/prima/CORE/SME/inc/smeInside.h | 366 + .../staging/prima/CORE/SME/inc/smeInternal.h | 199 + .../prima/CORE/SME/inc/smeQosInternal.h | 253 + .../prima/CORE/SME/inc/smeRrmInternal.h | 116 + drivers/staging/prima/CORE/SME/inc/sme_Api.h | 4012 ++ .../staging/prima/CORE/SME/inc/sme_FTApi.h | 104 + .../staging/prima/CORE/SME/inc/sme_QosApi.h | 408 + .../staging/prima/CORE/SME/inc/sme_RrmApi.h | 71 + .../staging/prima/CORE/SME/inc/sme_Trace.h | 161 + drivers/staging/prima/CORE/SME/inc/smsDebug.h | 54 + .../prima/CORE/SME/inc/wlan_ps_wow_diag.h | 146 + .../staging/prima/CORE/SME/src/QoS/sme_Qos.c | 8390 +++ .../staging/prima/CORE/SME/src/btc/btcApi.c | 2142 + .../staging/prima/CORE/SME/src/ccm/ccmApi.c | 830 + .../prima/CORE/SME/src/ccm/ccmLogDump.c | 55 + .../prima/CORE/SME/src/csr/csrApiRoam.c | 19650 +++++++ .../prima/CORE/SME/src/csr/csrApiScan.c | 9507 ++++ .../prima/CORE/SME/src/csr/csrCmdProcess.c | 149 + .../prima/CORE/SME/src/csr/csrInsideApi.h | 1122 + .../prima/CORE/SME/src/csr/csrLinkList.c | 663 + .../prima/CORE/SME/src/csr/csrLogDump.c | 136 + .../prima/CORE/SME/src/csr/csrNeighborRoam.c | 5749 ++ .../prima/CORE/SME/src/csr/csrTdlsProcess.c | 967 + .../staging/prima/CORE/SME/src/csr/csrUtil.c | 6992 +++ .../prima/CORE/SME/src/csr/csr_roam_mbb.c | 890 + .../staging/prima/CORE/SME/src/nan/nan_Api.c | 167 + .../prima/CORE/SME/src/oemData/oemDataApi.c | 406 + .../staging/prima/CORE/SME/src/p2p/p2p_Api.c | 2282 + drivers/staging/prima/CORE/SME/src/pmc/pmc.c | 2586 + .../staging/prima/CORE/SME/src/pmc/pmcApi.c | 3622 ++ .../prima/CORE/SME/src/pmc/pmcLogDump.c | 414 + .../staging/prima/CORE/SME/src/rrm/sme_rrm.c | 1613 + .../prima/CORE/SME/src/sme_common/sme_Api.c | 15092 +++++ .../prima/CORE/SME/src/sme_common/sme_FTApi.c | 539 + .../prima/CORE/SME/src/sme_common/sme_Trace.c | 289 + .../CORE/SVC/external/wlan_nlink_common.h | 126 + .../staging/prima/CORE/SVC/inc/wlan_btc_svc.h | 40 + .../CORE/SVC/inc/wlan_logging_sock_svc.h | 107 + .../prima/CORE/SVC/inc/wlan_nlink_srv.h | 66 + .../prima/CORE/SVC/inc/wlan_ptt_sock_svc.h | 128 + .../prima/CORE/SVC/src/btc/wlan_btc_svc.c | 268 + .../SVC/src/logging/wlan_logging_sock_svc.c | 2178 + .../prima/CORE/SVC/src/nlink/wlan_nlink_srv.c | 413 + .../CORE/SVC/src/ptt/wlan_ptt_sock_svc.c | 335 + .../prima/CORE/SYS/common/inc/wlan_qct_sys.h | 429 + .../prima/CORE/SYS/common/src/wlan_qct_sys.c | 788 + .../CORE/SYS/legacy/src/pal/inc/palApi.h | 762 + .../CORE/SYS/legacy/src/pal/inc/palTimer.h | 85 + .../CORE/SYS/legacy/src/pal/src/palApiComm.c | 401 + .../CORE/SYS/legacy/src/pal/src/palTimer.c | 238 + .../SYS/legacy/src/platform/inc/VossWrapper.h | 179 + .../SYS/legacy/src/platform/src/VossWrapper.c | 533 + .../CORE/SYS/legacy/src/system/inc/sysDebug.h | 47 + .../CORE/SYS/legacy/src/system/inc/sysDef.h | 171 + .../SYS/legacy/src/system/inc/sysEntryFunc.h | 53 + .../SYS/legacy/src/system/inc/sysStartup.h | 55 + .../SYS/legacy/src/system/src/macInitApi.c | 356 + .../SYS/legacy/src/system/src/sysEntryFunc.c | 212 + .../SYS/legacy/src/system/src/sysWinStartup.c | 54 + .../SYS/legacy/src/utils/inc/dot11fdefs.h | 101 + .../SYS/legacy/src/utils/inc/utilsParser.h | 79 + .../CORE/SYS/legacy/src/utils/src/dot11f.c | 46067 ++++++++++++++++ .../CORE/SYS/legacy/src/utils/src/logApi.c | 207 + .../CORE/SYS/legacy/src/utils/src/logDump.c | 454 + .../CORE/SYS/legacy/src/utils/src/macTrace.c | 1121 + .../legacy/src/utils/src/parsemactrace.cmm | 973 + .../CORE/SYS/legacy/src/utils/src/parserApi.c | 5620 ++ .../CORE/SYS/legacy/src/utils/src/utilsApi.c | 100 + .../SYS/legacy/src/utils/src/utilsParser.c | 807 + drivers/staging/prima/CORE/TL/inc/tlDebug.h | 86 + .../staging/prima/CORE/TL/inc/wlan_qct_tl.h | 3430 ++ .../prima/CORE/TL/inc/wlan_qct_tl_trace.h | 63 + .../staging/prima/CORE/TL/src/wlan_qct_tl.c | 14993 +++++ .../prima/CORE/TL/src/wlan_qct_tl_ba.c | 1929 + .../prima/CORE/TL/src/wlan_qct_tl_hosupport.c | 2131 + .../prima/CORE/TL/src/wlan_qct_tl_hosupport.h | 328 + .../prima/CORE/TL/src/wlan_qct_tl_trace.c | 78 + .../staging/prima/CORE/TL/src/wlan_qct_tli.h | 1964 + .../prima/CORE/TL/src/wlan_qct_tli_ba.h | 397 + .../staging/prima/CORE/VOSS/inc/event_defs.h | 1925 + .../CORE/VOSS/inc/i_vos_diag_core_event.h | 106 + .../prima/CORE/VOSS/inc/i_vos_diag_core_log.h | 143 + .../staging/prima/CORE/VOSS/inc/i_vos_event.h | 74 + .../staging/prima/CORE/VOSS/inc/i_vos_list.h | 77 + .../staging/prima/CORE/VOSS/inc/i_vos_lock.h | 90 + .../prima/CORE/VOSS/inc/i_vos_packet.h | 276 + .../staging/prima/CORE/VOSS/inc/i_vos_timer.h | 81 + .../staging/prima/CORE/VOSS/inc/i_vos_trace.h | 154 + .../staging/prima/CORE/VOSS/inc/i_vos_types.h | 206 + .../staging/prima/CORE/VOSS/inc/log_codes.h | 2084 + drivers/staging/prima/CORE/VOSS/inc/vos_api.h | 537 + .../prima/CORE/VOSS/inc/vos_diag_core_event.h | 464 + .../prima/CORE/VOSS/inc/vos_diag_core_log.h | 478 + .../staging/prima/CORE/VOSS/inc/vos_event.h | 277 + .../staging/prima/CORE/VOSS/inc/vos_getBin.h | 143 + .../staging/prima/CORE/VOSS/inc/vos_list.h | 585 + .../staging/prima/CORE/VOSS/inc/vos_lock.h | 310 + .../staging/prima/CORE/VOSS/inc/vos_memory.h | 351 + drivers/staging/prima/CORE/VOSS/inc/vos_mq.h | 273 + .../staging/prima/CORE/VOSS/inc/vos_nvitem.h | 810 + .../prima/CORE/VOSS/inc/vos_pack_align.h | 112 + .../staging/prima/CORE/VOSS/inc/vos_packet.h | 1185 + .../staging/prima/CORE/VOSS/inc/vos_status.h | 135 + .../staging/prima/CORE/VOSS/inc/vos_threads.h | 113 + .../staging/prima/CORE/VOSS/inc/vos_timer.h | 363 + .../staging/prima/CORE/VOSS/inc/vos_trace.h | 206 + .../staging/prima/CORE/VOSS/inc/vos_types.h | 507 + .../staging/prima/CORE/VOSS/inc/vos_utils.h | 344 + .../prima/CORE/VOSS/inc/wlan_hdd_misc.h | 80 + .../prima/CORE/VOSS/inc/wlan_nv_parser.h | 35 + .../CORE/VOSS/inc/wlan_nv_parser_internal.h | 93 + .../prima/CORE/VOSS/inc/wlan_nv_stream.h | 56 + .../CORE/VOSS/inc/wlan_nv_template_api.h | 48 + .../CORE/VOSS/inc/wlan_nv_template_builtin.h | 178 + .../CORE/VOSS/inc/wlan_nv_template_internal.h | 331 + .../prima/CORE/VOSS/inc/wlan_nv_types.h | 48 + drivers/staging/prima/CORE/VOSS/src/vos_api.c | 3893 ++ .../staging/prima/CORE/VOSS/src/vos_diag.c | 332 + .../staging/prima/CORE/VOSS/src/vos_event.c | 502 + .../staging/prima/CORE/VOSS/src/vos_getBin.c | 197 + .../staging/prima/CORE/VOSS/src/vos_list.c | 932 + .../staging/prima/CORE/VOSS/src/vos_lock.c | 622 + .../staging/prima/CORE/VOSS/src/vos_memory.c | 697 + drivers/staging/prima/CORE/VOSS/src/vos_mq.c | 290 + .../staging/prima/CORE/VOSS/src/vos_nvitem.c | 4832 ++ .../staging/prima/CORE/VOSS/src/vos_packet.c | 3214 ++ .../staging/prima/CORE/VOSS/src/vos_sched.c | 2228 + .../staging/prima/CORE/VOSS/src/vos_sched.h | 544 + .../staging/prima/CORE/VOSS/src/vos_threads.c | 134 + .../staging/prima/CORE/VOSS/src/vos_timer.c | 1091 + .../staging/prima/CORE/VOSS/src/vos_trace.c | 703 + .../staging/prima/CORE/VOSS/src/vos_types.c | 188 + .../staging/prima/CORE/VOSS/src/vos_utils.c | 1576 + .../prima/CORE/VOSS/src/wlan_nv_parser.c | 2147 + .../prima/CORE/VOSS/src/wlan_nv_stream_read.c | 119 + .../CORE/VOSS/src/wlan_nv_template_builtin.c | 848 + .../prima/CORE/WDA/inc/legacy/halMsgApi.h | 1449 + .../prima/CORE/WDA/inc/legacy/halTypes.h | 451 + .../prima/CORE/WDA/inc/legacy/palTypes.h | 219 + .../prima/CORE/WDA/inc/legacy/wlan_qct_hal.h | 572 + .../staging/prima/CORE/WDA/inc/wlan_qct_wda.h | 2217 + .../prima/CORE/WDA/inc/wlan_qct_wda_msg.h | 98 + drivers/staging/prima/CORE/WDA/src/wlan_nv.c | 10481 ++++ .../staging/prima/CORE/WDA/src/wlan_qct_wda.c | 23524 ++++++++ .../prima/CORE/WDA/src/wlan_qct_wda_debug.c | 63 + .../prima/CORE/WDA/src/wlan_qct_wda_debug.h | 84 + .../prima/CORE/WDA/src/wlan_qct_wda_ds.c | 1282 + .../prima/CORE/WDA/src/wlan_qct_wda_legacy.c | 236 + .../prima/CORE/WDI/CP/inc/qwlanfw_defs.h | 75 + .../prima/CORE/WDI/CP/inc/wlan_qct_wdi.h | 12510 +++++ .../prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h | 1322 + .../prima/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h | 336 + .../prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h | 544 + .../prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h | 6833 +++ .../prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h | 376 + .../prima/CORE/WDI/CP/src/wlan_qct_wdi.c | 39610 +++++++++++++ .../prima/CORE/WDI/CP/src/wlan_qct_wdi_dp.c | 1104 + .../prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c | 751 + .../prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h | 489 + .../prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h | 266 + .../prima/CORE/WDI/DP/src/wlan_qct_wdi_bd.c | 426 + .../prima/CORE/WDI/DP/src/wlan_qct_wdi_ds.c | 566 + .../CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h | 268 + .../CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c | 1003 + .../CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h | 308 + .../CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c | 1486 + .../CORE/WDI/WPAL/inc/wlan_qct_os_list.h | 450 + .../CORE/WDI/WPAL/inc/wlan_qct_os_status.h | 85 + .../CORE/WDI/WPAL/inc/wlan_qct_os_sync.h | 50 + .../CORE/WDI/WPAL/inc/wlan_qct_os_timer.h | 50 + .../CORE/WDI/WPAL/inc/wlan_qct_os_trace.h | 114 + .../CORE/WDI/WPAL/inc/wlan_qct_os_type.h | 68 + .../CORE/WDI/WPAL/inc/wlan_qct_pack_align.h | 112 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_api.h | 394 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_device.h | 315 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_list.h | 45 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h | 98 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h | 497 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_status.h | 95 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h | 132 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h | 142 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_trace.h | 135 + .../CORE/WDI/WPAL/inc/wlan_qct_pal_type.h | 128 + .../CORE/WDI/WPAL/src/wlan_qct_pal_api.c | 555 + .../CORE/WDI/WPAL/src/wlan_qct_pal_device.c | 850 + .../CORE/WDI/WPAL/src/wlan_qct_pal_msg.c | 169 + .../CORE/WDI/WPAL/src/wlan_qct_pal_packet.c | 1095 + .../CORE/WDI/WPAL/src/wlan_qct_pal_sync.c | 246 + .../CORE/WDI/WPAL/src/wlan_qct_pal_timer.c | 254 + .../CORE/WDI/WPAL/src/wlan_qct_pal_trace.c | 341 + drivers/staging/prima/Kbuild | 725 + drivers/staging/prima/Kconfig | 60 + drivers/staging/prima/Makefile | 17 + .../staging/prima/firmware_bin/WCNSS_cfg.dat | Bin 0 -> 11514 bytes .../prima/firmware_bin/WCNSS_qcom_cfg.ini | 529 + drivers/staging/prima/riva/inc/halCompiler.h | 177 + .../prima/riva/inc/halLegacyPalTypes.h | 60 + drivers/staging/prima/riva/inc/pttFrameGen.h | 96 + drivers/staging/prima/riva/inc/pttModule.h | 182 + drivers/staging/prima/riva/inc/pttMsgApi.h | 964 + drivers/staging/prima/riva/inc/wlan_hal_cfg.h | 1116 + drivers/staging/prima/riva/inc/wlan_hal_msg.h | 9705 ++++ drivers/staging/prima/riva/inc/wlan_nv.h | 845 + drivers/staging/prima/riva/inc/wlan_nv2.h | 237 + drivers/staging/prima/riva/inc/wlan_phy.h | 919 + .../prima/riva/inc/wlan_qct_dev_defs.h | 380 + .../staging/prima/riva/inc/wlan_status_code.h | 179 + 455 files changed, 671455 insertions(+) create mode 100644 drivers/staging/prima/Android.mk create mode 100644 drivers/staging/prima/CORE/BAP/inc/bapApi.h create mode 100644 drivers/staging/prima/CORE/BAP/inc/btampHCI.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiData.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiDebug.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiExt.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiExt.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiHCBB.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiInfo.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiLinkCntl.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiLinkSupervision.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiStatus.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiTimer.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapApiTimer.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapInternal.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapModule.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xFsm.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnErrors.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnSsmServices.h create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.c create mode 100644 drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.h create mode 100644 drivers/staging/prima/CORE/BAP/src/btampFsm.c create mode 100644 drivers/staging/prima/CORE/BAP/src/btampFsm.h create mode 100644 drivers/staging/prima/CORE/BAP/src/btampFsm_ext.h create mode 100644 drivers/staging/prima/CORE/BAP/src/btampHCI.c create mode 100644 drivers/staging/prima/CORE/BAP/src/fsmDefs.h create mode 100644 drivers/staging/prima/CORE/DXE/inc/wlan_qct_dxe.h create mode 100644 drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe.c create mode 100644 drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_cfg_i.c create mode 100644 drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_i.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/bap_hdd_main.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/bap_hdd_misc.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_debugfs.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dev_pwr.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dp_utils.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ether.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ftm.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_host_offload.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_includes.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_keep_alive.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_mib.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_p2p.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_packet_filtering.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_power.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_trace.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_version.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wmm.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wowl.h create mode 100644 drivers/staging/prima/CORE/HDD/inc/wlan_qct_driver.h create mode 100644 drivers/staging/prima/CORE/HDD/src/bap_hdd_main.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_debugfs.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_dp_utils.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_ftm.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_mib.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_scan.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_trace.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_wmm.c create mode 100644 drivers/staging/prima/CORE/HDD/src/wlan_hdd_wowl.c create mode 100644 drivers/staging/prima/CORE/MAC/inc/aniCompiler.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/aniDbgTest.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/aniGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/aniParam.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/aniSystemDefs.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/logDump.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/macInitApi.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/macTrace.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/qwlan_version.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/sirApi.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/sirMacPropExts.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/sirTypes.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/wniApi.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/wniCfg.h create mode 100644 drivers/staging/prima/CORE/MAC/inc/wniStat.h create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.c create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.h create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgDef.h create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgParamName.c create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgPriv.h create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgSendMsg.c create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/cfg.txt create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms create mode 100644 drivers/staging/prima/CORE/MAC/src/cfg/polFile.h create mode 100644 drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.c create mode 100644 drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/cfgApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/cfgGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/dot11f.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/parserApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/phyGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/sirCommon.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/sirDebug.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/sirParams.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/sysGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/utilsApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/include/utilsGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limAdmitControl.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/limTrace.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/pmmApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/pmmGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/rrmApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/rrmGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/schApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/schGlobal.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/include/wmmApsd.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limAIDmgmt.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limAdmitControl.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limP2P.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessLmmMessages.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessTdls.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limRoamingAlgo.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmAP.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/rrm/rrmApi.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schApi.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.h create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schMessage.c create mode 100644 drivers/staging/prima/CORE/MAC/src/pe/sch/schSysParams.h create mode 100644 drivers/staging/prima/CORE/SAP/inc/sapApi.h create mode 100644 drivers/staging/prima/CORE/SAP/src/sapApiLinkCntl.c create mode 100644 drivers/staging/prima/CORE/SAP/src/sapChSelect.c create mode 100644 drivers/staging/prima/CORE/SAP/src/sapChSelect.h create mode 100644 drivers/staging/prima/CORE/SAP/src/sapFsm.c create mode 100644 drivers/staging/prima/CORE/SAP/src/sapFsm_ext.h create mode 100644 drivers/staging/prima/CORE/SAP/src/sapInternal.h create mode 100644 drivers/staging/prima/CORE/SAP/src/sapModule.c create mode 100644 drivers/staging/prima/CORE/SME/inc/btcApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/ccmApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/csrApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/csrInternal.h create mode 100644 drivers/staging/prima/CORE/SME/inc/csrLinkList.h create mode 100644 drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h create mode 100644 drivers/staging/prima/CORE/SME/inc/csrSupport.h create mode 100644 drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h create mode 100644 drivers/staging/prima/CORE/SME/inc/nan_Api.h create mode 100644 drivers/staging/prima/CORE/SME/inc/oemDataApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/oemDataInternal.h create mode 100644 drivers/staging/prima/CORE/SME/inc/p2p_Api.h create mode 100644 drivers/staging/prima/CORE/SME/inc/pmc.h create mode 100644 drivers/staging/prima/CORE/SME/inc/pmcApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/smeInside.h create mode 100644 drivers/staging/prima/CORE/SME/inc/smeInternal.h create mode 100644 drivers/staging/prima/CORE/SME/inc/smeQosInternal.h create mode 100644 drivers/staging/prima/CORE/SME/inc/smeRrmInternal.h create mode 100644 drivers/staging/prima/CORE/SME/inc/sme_Api.h create mode 100644 drivers/staging/prima/CORE/SME/inc/sme_FTApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/sme_QosApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/sme_RrmApi.h create mode 100644 drivers/staging/prima/CORE/SME/inc/sme_Trace.h create mode 100644 drivers/staging/prima/CORE/SME/inc/smsDebug.h create mode 100644 drivers/staging/prima/CORE/SME/inc/wlan_ps_wow_diag.h create mode 100644 drivers/staging/prima/CORE/SME/src/QoS/sme_Qos.c create mode 100644 drivers/staging/prima/CORE/SME/src/btc/btcApi.c create mode 100644 drivers/staging/prima/CORE/SME/src/ccm/ccmApi.c create mode 100644 drivers/staging/prima/CORE/SME/src/ccm/ccmLogDump.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrLinkList.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrLogDump.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrTdlsProcess.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csrUtil.c create mode 100644 drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c create mode 100644 drivers/staging/prima/CORE/SME/src/nan/nan_Api.c create mode 100644 drivers/staging/prima/CORE/SME/src/oemData/oemDataApi.c create mode 100644 drivers/staging/prima/CORE/SME/src/p2p/p2p_Api.c create mode 100644 drivers/staging/prima/CORE/SME/src/pmc/pmc.c create mode 100644 drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c create mode 100644 drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c create mode 100644 drivers/staging/prima/CORE/SME/src/rrm/sme_rrm.c create mode 100644 drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c create mode 100644 drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c create mode 100644 drivers/staging/prima/CORE/SME/src/sme_common/sme_Trace.c create mode 100644 drivers/staging/prima/CORE/SVC/external/wlan_nlink_common.h create mode 100644 drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h create mode 100644 drivers/staging/prima/CORE/SVC/inc/wlan_logging_sock_svc.h create mode 100644 drivers/staging/prima/CORE/SVC/inc/wlan_nlink_srv.h create mode 100644 drivers/staging/prima/CORE/SVC/inc/wlan_ptt_sock_svc.h create mode 100644 drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c create mode 100644 drivers/staging/prima/CORE/SVC/src/logging/wlan_logging_sock_svc.c create mode 100644 drivers/staging/prima/CORE/SVC/src/nlink/wlan_nlink_srv.c create mode 100644 drivers/staging/prima/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c create mode 100644 drivers/staging/prima/CORE/SYS/common/inc/wlan_qct_sys.h create mode 100644 drivers/staging/prima/CORE/SYS/common/src/wlan_qct_sys.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palApi.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palTimer.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palApiComm.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palTimer.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/platform/inc/VossWrapper.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/platform/src/VossWrapper.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDebug.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDef.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysStartup.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/src/macInitApi.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysEntryFunc.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysWinStartup.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/utilsParser.h create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logApi.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logDump.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parsemactrace.cmm create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsApi.c create mode 100644 drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsParser.c create mode 100644 drivers/staging/prima/CORE/TL/inc/tlDebug.h create mode 100644 drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h create mode 100644 drivers/staging/prima/CORE/TL/inc/wlan_qct_tl_trace.h create mode 100755 drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c create mode 100644 drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c create mode 100644 drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.c create mode 100644 drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.h create mode 100644 drivers/staging/prima/CORE/TL/src/wlan_qct_tl_trace.c create mode 100644 drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h create mode 100644 drivers/staging/prima/CORE/TL/src/wlan_qct_tli_ba.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/event_defs.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_diag_core_event.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_diag_core_log.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_event.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_list.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_lock.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_packet.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_timer.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_trace.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/i_vos_types.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/log_codes.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_api.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_log.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_event.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_getBin.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_list.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_lock.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_memory.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_mq.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_nvitem.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_pack_align.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_packet.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_status.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_threads.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_timer.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_trace.h create mode 100755 drivers/staging/prima/CORE/VOSS/inc/vos_types.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/vos_utils.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_hdd_misc.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser_internal.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_stream.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_api.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_builtin.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_internal.h create mode 100644 drivers/staging/prima/CORE/VOSS/inc/wlan_nv_types.h create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_api.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_diag.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_event.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_getBin.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_list.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_lock.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_memory.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_mq.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_nvitem.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_packet.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_sched.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_sched.h create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_threads.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_timer.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_trace.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_types.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/vos_utils.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/wlan_nv_parser.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/wlan_nv_stream_read.c create mode 100644 drivers/staging/prima/CORE/VOSS/src/wlan_nv_template_builtin.c create mode 100644 drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h create mode 100644 drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h create mode 100644 drivers/staging/prima/CORE/WDA/inc/legacy/palTypes.h create mode 100644 drivers/staging/prima/CORE/WDA/inc/legacy/wlan_qct_hal.h create mode 100644 drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h create mode 100644 drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda_msg.h create mode 100644 drivers/staging/prima/CORE/WDA/src/wlan_nv.c create mode 100644 drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c create mode 100644 drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.c create mode 100644 drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.h create mode 100644 drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_ds.c create mode 100644 drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_legacy.c create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/qwlanfw_defs.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h create mode 100644 drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c create mode 100644 drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_dp.c create mode 100644 drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c create mode 100644 drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h create mode 100644 drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h create mode 100644 drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_bd.c create mode 100644 drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_ds.c create mode 100644 drivers/staging/prima/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h create mode 100644 drivers/staging/prima/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c create mode 100644 drivers/staging/prima/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h create mode 100644 drivers/staging/prima/CORE/WDI/TRP/DTS/src/wlan_qct_wdi_dts.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_list.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_status.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_trace.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_type.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_trace.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_device.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_msg.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_sync.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_timer.c create mode 100644 drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_trace.c create mode 100644 drivers/staging/prima/Kbuild create mode 100644 drivers/staging/prima/Kconfig create mode 100644 drivers/staging/prima/Makefile create mode 100644 drivers/staging/prima/firmware_bin/WCNSS_cfg.dat create mode 100644 drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini create mode 100644 drivers/staging/prima/riva/inc/halCompiler.h create mode 100644 drivers/staging/prima/riva/inc/halLegacyPalTypes.h create mode 100644 drivers/staging/prima/riva/inc/pttFrameGen.h create mode 100644 drivers/staging/prima/riva/inc/pttModule.h create mode 100644 drivers/staging/prima/riva/inc/pttMsgApi.h create mode 100644 drivers/staging/prima/riva/inc/wlan_hal_cfg.h create mode 100644 drivers/staging/prima/riva/inc/wlan_hal_msg.h create mode 100644 drivers/staging/prima/riva/inc/wlan_nv.h create mode 100644 drivers/staging/prima/riva/inc/wlan_nv2.h create mode 100644 drivers/staging/prima/riva/inc/wlan_phy.h create mode 100644 drivers/staging/prima/riva/inc/wlan_qct_dev_defs.h create mode 100644 drivers/staging/prima/riva/inc/wlan_status_code.h diff --git a/arch/arm64/configs/mido_defconfig b/arch/arm64/configs/mido_defconfig index b2b738ebe452..8de95669f571 100644 --- a/arch/arm64/configs/mido_defconfig +++ b/arch/arm64/configs/mido_defconfig @@ -3619,6 +3619,21 @@ CONFIG_ION_MSM=y # CONFIG_DGNC is not set # CONFIG_DGAP is not set # CONFIG_GS_FPGABOOT is not set + +# +# Qualcomm Atheros Prima WLAN module +# +# CONFIG_PRIMA_WLAN is not set +CONFIG_PRONTO_WLAN=y +# CONFIG_PRIMA_WLAN_BTAMP is not set +CONFIG_PRIMA_WLAN_LFR=y +CONFIG_PRIMA_WLAN_OKC=y +CONFIG_PRIMA_WLAN_11AC_HIGH_TP=y +CONFIG_WLAN_FEATURE_11W=y +CONFIG_QCOM_VOWIFI_11R=y +CONFIG_ENABLE_LINUX_REG=y +CONFIG_WLAN_OFFLOAD_PACKETS=y +CONFIG_QCOM_TDLS=y # CONFIG_GOLDFISH is not set # diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4690ae9a267f..10f93517b08f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -108,4 +108,6 @@ source "drivers/staging/skein/Kconfig" source "drivers/staging/unisys/Kconfig" +source "drivers/staging/prima/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 53503056d747..22f095d3c33a 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -45,3 +45,5 @@ obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/ obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/ obj-$(CONFIG_CRYPTO_SKEIN) += skein/ obj-$(CONFIG_UNISYSSPAR) += unisys/ +obj-$(CONFIG_PRIMA_WLAN) += prima/ +obj-$(CONFIG_PRONTO_WLAN) += prima/ diff --git a/drivers/staging/prima/Android.mk b/drivers/staging/prima/Android.mk new file mode 100644 index 000000000000..de0c7354aea9 --- /dev/null +++ b/drivers/staging/prima/Android.mk @@ -0,0 +1,156 @@ +# Android makefile for the WLAN Module + +# Assume no targets will be supported +WLAN_CHIPSET := + +# Build/Package options for 8960 target +ifeq ($(TARGET_BOARD_PLATFORM),msm8960) +WLAN_CHIPSET := prima +WLAN_SELECT := CONFIG_PRIMA_WLAN=m +endif + +# Build/Package options for 8916, 8974, 8226, 8610, 8909, 8952, 8937, 8953 targets +ifneq (,$(filter msm8916 msm8974 msm8226 msm8610 msm8909 msm8952 msm8937 msm8953 titanium,$(TARGET_BOARD_PLATFORM))) +WLAN_CHIPSET := pronto +WLAN_SELECT := CONFIG_PRONTO_WLAN=m +endif + +# Build/Package only in case of supported target +ifneq ($(WLAN_CHIPSET),) + +LOCAL_PATH := $(call my-dir) + +ifeq ($(TARGET_SUPPORTS_WEARABLES),true) +ifneq ($(findstring device,$(LOCAL_PATH)),) + WLAN_DLKM := 1 +else + WLAN_DLKM := 0 +endif # findstring device +else +ifneq ($(findstring vendor,$(LOCAL_PATH)),) + WLAN_DLKM := 1 +else + WLAN_DLKM := 0 +endif # findstring vendor +endif # TARGET_SUPPORTS_WEARABLES + +# This makefile is only for DLKM +ifeq ($(WLAN_DLKM),1) + +# Determine if we are Proprietary or Open Source +ifneq ($(findstring opensource,$(LOCAL_PATH)),) + WLAN_PROPRIETARY := 0 +else + WLAN_PROPRIETARY := 1 +endif + +ifeq ($(WLAN_PROPRIETARY),1) + WLAN_BLD_DIR := vendor/qcom/proprietary/wlan +else +ifneq ($(TARGET_SUPPORTS_WEARABLES),true) + WLAN_BLD_DIR := vendor/qcom/opensource/wlan +else + WLAN_BLD_DIR := device/qcom/msm8909w/opensource/wlan +endif +endif + +# DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16) +ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 16 ))" ))) +ifneq ($(TARGET_SUPPORTS_WEARABLES),true) + DLKM_DIR := $(TOP)/device/qcom/common/dlkm +else + DLKM_DIR := $(BOARD_DLKM_DIR) +endif +else + DLKM_DIR := build/dlkm +endif + +# Copy WCNSS_cfg.dat file from firmware_bin/ folder to target out directory. +ifeq ($(WLAN_PROPRIETARY),0) + +$(shell mkdir -p $(TARGET_OUT_ETC)/firmware/wlan/prima) +$(shell rm -f $(TARGET_OUT_ETC)/firmware/wlan/prima/WCNSS_cfg.dat) +$(shell cp $(LOCAL_PATH)/firmware_bin/WCNSS_cfg.dat $(TARGET_OUT_ETC)/firmware/wlan/prima) + +else + +include $(CLEAR_VARS) +LOCAL_MODULE := WCNSS_qcom_wlan_nv.bin +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(PRODUCT_OUT)/persist +LOCAL_SRC_FILES := firmware_bin/$(LOCAL_MODULE) +include $(BUILD_PREBUILT) + +include $(CLEAR_VARS) +LOCAL_MODULE := WCNSS_cfg.dat +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware/wlan/prima +LOCAL_SRC_FILES := firmware_bin/$(LOCAL_MODULE) +include $(BUILD_PREBUILT) + +include $(CLEAR_VARS) +LOCAL_MODULE := WCNSS_qcom_cfg.ini +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(PRODUCT_OUT)/persist +LOCAL_SRC_FILES := firmware_bin/$(LOCAL_MODULE) +include $(BUILD_PREBUILT) + +endif + +ifeq ($(TARGET_KERNEL_VERSION),) +$(info "WLAN: TARGET_KERNEL_VERSION is not defined, assuming default") +TARGET_KERNEL_SOURCE := kernel +KERNEL_TO_BUILD_ROOT_OFFSET := ../ +endif + +ifeq ($(KERNEL_TO_BUILD_ROOT_OFFSET),) +$(info "WLAN: KERNEL_TO_BUILD_ROOT_OFFSET is not defined, assuming default") +KERNEL_TO_BUILD_ROOT_OFFSET := ../ +endif + +# Build wlan.ko as either prima_wlan.ko or pronto_wlan.ko +########################################################### + +# This is set once per LOCAL_PATH, not per (kernel) module +KBUILD_OPTIONS := WLAN_ROOT=$(KERNEL_TO_BUILD_ROOT_OFFSET)$(WLAN_BLD_DIR)/prima +# We are actually building wlan.ko here, as per the +# requirement we are specifying _wlan.ko as LOCAL_MODULE. +# This means we need to rename the module to _wlan.ko +# after wlan.ko is built. +KBUILD_OPTIONS += MODNAME=wlan +KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM) +KBUILD_OPTIONS += $(WLAN_SELECT) + + +VERSION=$(shell grep -w "VERSION =" $(TOP)/kernel/Makefile | sed 's/^VERSION = //' ) +PATCHLEVEL=$(shell grep -w "PATCHLEVEL =" $(TOP)/kernel/Makefile | sed 's/^PATCHLEVEL = //' ) + +include $(CLEAR_VARS) +LOCAL_MODULE := $(WLAN_CHIPSET)_wlan.ko +LOCAL_MODULE_KBUILD_NAME := wlan.ko +LOCAL_MODULE_TAGS := debug +LOCAL_MODULE_DEBUG_ENABLE := true +ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true) +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET) +else +LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules/$(WLAN_CHIPSET) +endif # PRODUCT_VENDOR_MOVE_ENABLED +include $(DLKM_DIR)/AndroidKernelModule.mk +########################################################### + +#Create symbolic link +ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true) +$(shell mkdir -p $(TARGET_OUT_VENDOR)/lib/modules; \ + ln -sf /$(TARGET_COPY_OUT_VENDOR)/lib/modules/$(WLAN_CHIPSET)/$(WLAN_CHIPSET)_wlan.ko \ + $(TARGET_OUT_VENDOR)/lib/modules/wlan.ko) +else +$(shell mkdir -p $(TARGET_OUT)/lib/modules; \ + ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(WLAN_CHIPSET)_wlan.ko \ + $(TARGET_OUT)/lib/modules/wlan.ko) +endif # PRODUCT_VENDOR_MOVE_ENABLED +endif # DLKM check + +endif # supported target check diff --git a/drivers/staging/prima/CORE/BAP/inc/bapApi.h b/drivers/staging/prima/CORE/BAP/inc/bapApi.h new file mode 100644 index 000000000000..ea0ca07cd9f2 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/inc/bapApi.h @@ -0,0 +1,2950 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_H +#define WLAN_QCT_WLANBAP_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan BT-AMP PAL layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/BAP/inc/bapApi.h,v 1.21 2009/03/09 08:58:26 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +07/01/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" +//I need the TL types and API +#include "wlan_qct_tl.h" + +/* BT-AMP PAL API structure types - FramesC generated */ +#include "btampHCI.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * HCI Interface supported + * + * Here we list the HCI Commands and Events which our 802.11 BT-AMP PAL + * supports. + * + * -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Supported HCI Commands +---------------------------------------------------------------------------*/ +#if 0 +/** BT v3.0 Link Control commands */ + BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD, + BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD, + BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD, + BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD, + BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD, + BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD, + BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD, + BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD, +/* +Host Controller and Baseband Commands +*/ + BTAMP_TLV_HCI_RESET_CMD, + BTAMP_TLV_HCI_SET_EVENT_MASK_CMD, + BTAMP_TLV_HCI_FLUSH_CMD, + BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD, + BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD, +/* v3.0 Host Controller and Baseband Commands */ + BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD, + BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD, + BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD, + BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD, + BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD, + BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD, + BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TO_CMD, + BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TO_CMD, +/** opcode definition for this command from AMP HCI CR D9r4 markup */ + BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD, +/* End of v3.0 Host Controller and Baseband Commands */ +/* +Informational Parameters +*/ + BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFORMATION_CMD, + BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_COMMANDS_CMD, + BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD, +/* v3.0 Informational commands */ + BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD, +/* +Status Parameters +*/ + BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD, + BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD, + BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD, + BTAMP_TLV_HCI_READ_RSSI_CMD, + BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD, + BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD, + BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD, +/* +Debug Commands +*/ + BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD, + BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD, +#endif + +/*--------------------------------------------------------------------------- + Supported HCI Events +---------------------------------------------------------------------------*/ +#if 0 +/** BT events */ + BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT, + BTAMP_TLV_HCI_COMMAND_STATUS_EVENT, + BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT, + BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT, + BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT, + BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT, + BTAMP_TLV_HCI_QOS_VIOLATION_EVENT, +/** BT v3.0 events */ + BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT, + BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT , + BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT , + BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT , + BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT , + BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT , + BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT , +#endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + Packet type defines for the AMP to PAL packet encapsulation. +---------------------------------------------------------------------------*/ +#define WLANBAP_HCI_COMMAND_PACKET 0x01 /**< HCI command packet type, characterizing packet types over the + UART and RS232 transports */ +#define WLANBAP_HCI_ACL_DATA_PACKET 0x02 /**< HCI ACL data packet type, characterizing packet types over the + UART and RS232 transports */ +#define WLANBAP_HCI_SCO_DATA_PACKET 0x03 /**< HCI SCO data packet type, characterizing packet types over the + UART and RS232 transports */ +#define WLANBAP_HCI_EVENT_PACKET 0x04 /**< HCI event packet type, characterizing packet types over the + UART and RS232 transports */ +/*--------------------------------------------------------------------------- + HCI Data packet size limitation. +---------------------------------------------------------------------------*/ +#define WLANBAP_MAX_80211_PAL_PDU_SIZE 1492 + +/*--------------------------------------------------------------------------- + HCI Flow Control Modes. +---------------------------------------------------------------------------*/ +#define WLANBAP_FLOW_CONTROL_MODE_PACKET_BASED 0x00 +#define WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED 0x01 + +/*--------------------------------------------------------------------------- + BT "assigned numbers" +---------------------------------------------------------------------------*/ +// Qualcomm Company ID +#define WLANBAP_QUALCOMM_COMPANY_ID 29 + +// HCI Interface version +// Parameter Name Assigned Values +// HCI_Version 0 => Bluetooth HCI Specification 1.0B +// 1 => Bluetooth HCI Specification 1.1 +// 2 => Bluetooth HCI Specification 1.2 +// 3 => Bluetooth HCI Specification 2.0 +// 4 => Bluetooth HCI Specification 2.1 +// 5 => Bluetooth HCI Specification 3.0 +#define WLANBAP_HCI_VERSION 5 +#define WLANBAP_HCI_REVISION 0 +#define WLANBAP_PAL_VERSION 0x01 +#define WLANBAP_PAL_SUBVERSION 0x00 + +// AMP device status +#define WLANBAP_HCI_AMP_STATUS_POWERED_DOWN 0x00 +#define WLANBAP_HCI_AMP_STATUS_NOT_SHARED 0x01 +#define WLANBAP_HCI_AMP_STATUS_SHARED 0x02 +#define WLANBAP_HCI_AMP_STATUS_RESERVED 0x03 + +// ACL Packet types (AMP only uses 0x03) +#define WLANBAP_HCI_PKT_START_NON_FLUSH 0x00 +#define WLANBAP_HCI_PKT_CONT 0x01 +#define WLANBAP_HCI_PKT_START_FLUSH 0x02 +#define WLANBAP_HCI_PKT_AMP 0x03 + +/*--------------------------------------------------------------------------- + BT-AMP PAL supported commands defines + + The Supported Commands configuration parameter lists which HCI commands the +local controller supports. It is implied that if a command is listed as +supported, the feature underlying that command is also supported. + The Supported Commands is a 64 octet bit field. If a bit is set to 1, then +this command is supported. + +---------------------------------------------------------------------------*/ +// 0 1 2 3 4 5 6 7 + +#define WLANBAP_PAL_SUPPORTED_HCI_CMDS { \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x0c, \ + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x88, 0x3c, \ + 0x00, 0x00, 0x00, 0x40, 0x00, 0xff, 0xff, 0x07, \ + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ +} + +/*--------------------------------------------------------------------------- + BT-AMP PAL "status" and "reason" error code defines +---------------------------------------------------------------------------*/ +#define WLANBAP_STATUS_SUCCESS (0x00) /* Success. Section 3.1.7 */ + +#define WLANBAP_ERROR_UNKNOWN_HCI_CMND (0x01) +#define WLANBAP_ERROR_NO_CNCT (0x02) /* AMP HCI Section 7.1.39 */ +#define WLANBAP_ERROR_HARDWARE_FAILURE (0x03) +#define WLANBAP_ERROR_PAGE_TIMEOUT (0x04) +/* Section 3.1.10 has this mis-identified as 0x08 */ +#define WLANBAP_ERROR_AUTHENT_FAILURE (0x05) +#define WLANBAP_ERROR_KEY_MISSING (0x06) +#define WLANBAP_ERROR_MEMORY_FULL (0x07) +#define WLANBAP_ERROR_CNCT_TIMEOUT (0x08) /* Section 3.1.8 */ +#define WLANBAP_ERROR_MAX_NUM_CNCTS (0x09) /* Section 3.1.8 */ +#define WLANBAP_ERROR_MAX_NUM_SCO_CNCTS (0x0a) +#define WLANBAP_ERROR_MAX_NUM_ACL_CNCTS (0x0b) +#define WLANBAP_ERROR_CMND_DISALLOWED (0x0c) /* Section 4.1 */ +#define WLANBAP_ERROR_HOST_REJ_RESOURCES (0x0d) /* Section 3.1.7 */ +#define WLANBAP_ERROR_HOST_REJ_SECURITY (0x0e) +#define WLANBAP_ERROR_HOST_REJ_PERSONAL_DEV (0x0f) +#define WLANBAP_ERROR_HOST_TIMEOUT (0x10) +#define WLANBAP_ERROR_UNSUPPORT_FEAT_PARAM (0x11) +#define WLANBAP_ERROR_INVALID_HCI_CMND_PARAM (0x12) +#define WLANBAP_ERROR_TERM_CNCT_USER_ENDED (0x13) +#define WLANBAP_ERROR_TERM_CNCT_LOW_RESOURCE (0x14) +#define WLANBAP_ERROR_TERM_CNCT_POWER_OFF (0x15) +/* Section 3.1.9 has a contradictory semantics of "failed connection" */ +#define WLANBAP_ERROR_TERM_BY_LOCAL_HOST (0x16) /* Section 3.1.8 */ +#define WLANBAP_ERROR_REPEATED_ATTEMPTS (0x17) +#define WLANBAP_ERROR_PAIRING_NOT_ALLOWED (0x18) +#define WLANBAP_ERROR_UNKNOWN_LMP_PDU (0x19) +#define WLANBAP_ERROR_UNSUPPORTED_REMOTE_FEAT (0x1a) +#define WLANBAP_ERROR_SCO_REJ (0x1b) +#define WLANBAP_ERROR_SCO_INTERVAL_REJ (0x1c) +#define WLANBAP_ERROR_SCO_AIR_MODE_REJ (0x1d) +#define WLANBAP_ERROR_INVALID_LMP_PARAMETER (0x1e) +#define WLANBAP_ERROR_UNSPECIFIED_ERROR (0x1f) +#define WLANBAP_ERROR_UNSUPPORTED_LMP_PARAM (0x20) +#define WLANBAP_ERROR_ROLE_CHANGE_NOT_ALLOWED (0x21) +#define WLANBAP_ERROR_LMP_RESPONSE_TIMEOUT (0x22) +#define WLANBAP_ERROR_LMP_ERROR_TRANS_COLLISION (0x23) +#define WLANBAP_ERROR_LMP_PDU_NOT_ALLOWED (0x24) +#define WLANBAP_ERROR_ENCRYPTION_MODE_NOT_ACCEPTABLE (0x25) +#define WLANBAP_ERROR_UNIT_KEY_USED (0x26) +#define WLANBAP_ERROR_QOS_IS_NOT_SUPPORTED (0x27) +#define WLANBAP_ERROR_INSTANT_PASSED (0x28) +#define WLANBAP_ERROR_UNIT_KEY_PAIRING_UNSUPPORTED (0x29) + +#define WLANBAP_ERROR_DIFFERENT_TRANS_COLLISION (0x2A) + +/* reserved (0x2B) */ + +#define WLANBAP_ERROR_QOS_UNACCEPTABLE_PARAMETER (0x2C) +#define WLANBAP_ERROR_QOS_REJECTED (0x2D) +#define WLANBAP_ERROR_CHANNEL_CLASSIFICATION_NS (0x2E) +#define WLANBAP_ERROR_INSUFFICIENT_SECURITY (0x2F) +#define WLANBAP_ERROR_PARM_OUT_OF_MANDATORY_RANGE (0x30) + +/* reserved (0x31) */ + +#define WLANBAP_ERROR_ROLE_SWITCH_PENDING (0x32) + +/* reserved (0x33) */ + +#define WLANBAP_ERROR_RESERVED_SLOT_VIOLATION (0x34) +#define WLANBAP_ERROR_ROLE_SWITCH_FAILED (0x35) +#define WLANBAP_ERROR_EIR_TOO_LARGE (0x36) +#define WLANBAP_ERROR_SSP_NOT_SUPPORTED_BY_HOST (0x37) +#define WLANBAP_ERROR_HOST_BUSY_PAIRING (0x38) +#define WLANBAP_ERROR_NO_SUITABLE_CHANNEL (0x39) +#define WLANBAP_ERROR_CONTROLLER_BUSY (0x3A) + +/*---------------------------------------------------------------------------- + * Event_Mask_Page_2 defines for events + * -------------------------------------------------------------------------*/ +#define WLANBAP_EVENT_MASK_NONE 0x0000000000000000 //No events specified (default) +#define WLANBAP_EVENT_MASK_PHY_LINK_COMPLETE_EVENT 0x0000000000000001 //Physical Link Complete Event +#define WLANBAP_EVENT_MASK_CHANNEL_SELECTED_EVENT 0x0000000000000002 //Channel Selected Event +#define WLANBAP_EVENT_MASK_DISC_PHY_LINK_EVENT 0x0000000000000004 //Disconnection Physical Link Event +#define WLANBAP_EVENT_MASK_PHY_LINK_LOSS_EARLY_WARNING_EVENT 0x0000000000000008 //Physical Link Loss Early Warning Event +#define WLANBAP_EVENT_MASK_PHY_LINK_RECOVERY_EVENT 0x0000000000000010 //Physical Link Recovery Event +#define WLANBAP_EVENT_MASK_LOG_LINK_COMPLETE_EVENT 0x0000000000000020 //Logical Link Complete Event +#define WLANBAP_EVENT_MASK_DISC_LOG_LINK_COMPLETE_EVENT 0x0000000000000040 //Disconnection Logical Link Complete Event +#define WLANBAP_EVENT_MASK_FLOW_SPEC_MOD_COMPLETE_EVENT 0x0000000000000080 //Flow Spec Modify Complete Event +#define WLANBAP_EVENT_MASK_NUM_COMPLETED_DATA_BLOCKS_EVENT 0x0000000000000100 //Number of Completed Data Blocks Event +#define WLANBAP_EVENT_MASK_AMP_START_TEST_EVENT 0x0000000000000200 //AMP Start Test Event +#define WLANBAP_EVENT_MASK_AMP_TEST_END_EVENT 0x0000000000000400 //AMP Test End Event +#define WLANBAP_EVENT_MASK_AMP_RCVR_REPORT_EVENT 0x0000000000000800 //AMP Receiver Report Event +#define WLANBAP_EVENT_MASK_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT 0x0000000000001000 //Short Range Mode Change Complete Event +#define WLANBAP_EVENT_MASK_AMP_STATUS_CHANGE_EVENT 0x0000000000002000 //AMP Status Change Event +#define WLANBAP_EVENT_MASK_RESERVED 0xFFFFFFFFFFFFC000 //Reserved for future use + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Opaque BAP handle Type Declaration + * -------------------------------------------------------------------------*/ +typedef v_PVOID_t tBtampHandle, *ptBtampHandle; + +/*---------------------------------------------------------------------------- + * BAP per-session Context Data Type Declaration + * -------------------------------------------------------------------------*/ +// Move this to bapInternal.h, where it belongs. +// For now, it is just the same thing as the per application context. +//typedef struct sBtampContext tBtampSessCtx; + + +/*--------------------------------------------------------------------------- + HCI Event union +---------------------------------------------------------------------------*/ +typedef struct sBtampHCI_Event { + v_U8_t bapHCIEventCode; /* The event code. To dis-ambiguate. */ + union { + tBtampTLVHCI_Channel_Selected_Event btampChannelSelectedEvent; + tBtampTLVHCI_Command_Complete_Event btampCommandCompleteEvent ; + tBtampTLVHCI_Command_Status_Event btampCommandStatusEvent ; + tBtampTLVHCI_Data_Buffer_Overflow_Event btampDataBufferOverflowEvent ; + tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event btampDisconnectLogicalLinkCompleteEvent ; + tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event btampDisconnectPhysicalLinkCompleteEvent ; + /* Flow_Spec_Modify_Complete_Event is generated after the flow spec modify cmd completes */ + tBtampTLVHCI_Flow_Spec_Modify_Complete_Event btampFlowSpecModifyCompleteEvent ; + /* Asynchronous Flush_Occurred Event CAN ALSO BE generated after the flush cmd completes */ + tBtampTLVHCI_Flush_Occurred_Event btampFlushOccurredEvent ; + tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event btampGenericAMPLinkKeyNotificationEvent ; + tBtampTLVHCI_Hardware_Error_Event btampHardwareErrorEvent ; + tBtampTLVHCI_Logical_Link_Complete_Event btampLogicalLinkCompleteEvent ; + tBtampTLVHCI_Loopback_Command_Event btampLoopbackCommandEvent ; + tBtampTLVHCI_Physical_Link_Complete_Event btampPhysicalLinkCompleteEvent ; + tBtampTLVHCI_Physical_Link_Loss_Warning_Event btampPhysicalLinkLossWarningEvent ; + tBtampTLVHCI_Physical_Link_Recovery_Event btampPhysicalLinkRecoveryEvent ; + tBtampTLVHCI_Qos_Violation_Event btampQosViolationEvent ; + tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event btampShortRangeModeChangeCompleteEvent ; + tBtampTLVHCI_Num_Completed_Pkts_Event btampNumOfCompletedPktsEvent; + tBtampTLVHCI_Num_Completed_Data_Blocks_Event btampNumOfCompletedDataBlocksEvent; + tBtampTLVHCI_Enhanced_Flush_Complete_Event btampEnhancedFlushCompleteEvent ; + } u; +} tBtampHCI_Event, *tpBtampHCI_Event; + +/* 802.3 header */ +typedef struct +{ + /* Destination address field */ + v_U8_t vDA[VOS_MAC_ADDR_SIZE]; + + /* Source address field */ + v_U8_t vSA[VOS_MAC_ADDR_SIZE]; + + /* Length field */ + v_U16_t usLenType; /* Num bytes in info field (i.e., exclude 802.3 hdr) */ + /* Max length 1500 (0x5dc) (What about 0x5ee? That + * includes 802.3 Header and FCS.) */ +}WLANBAP_8023HeaderType; + + +/* + * A list of Command Complete event msgs which will be + * signalled by the Event Callback + */ +#if 0 +/* The tBtampTLVHCI_Command_Complete_Event structure includes each of these*/ +/* HCI Reset: status */ +/* HCI Flush: status, log_link_handle */ + +#endif + +/* + * Command Complete event msgs which will be formed by the caller + * Now an invocation of btampPackTlvHCI_Command_Complete_Event() + * supports generating command complete event messages for all commands... + */ +/* The tBtampTLVHCI_Command_Complete_Event structure includes each of these*/ +#if 0 +/* HCI Cancel Logical Link: status, phy_link_handle, tx_flow_spec_id */ +/* HCI Set Event Mask: status */ +/* HCI Read Connection Accept Timeout: status, connection_accept_timeout */ +/* HCI Write Connection Accept Timeout: status */ +/* HCI Read Link Supervision Timeout: status, log_link_handle (8 sig bits only), link_supervision_timeout */ +/* HCI Write Link Supervision Timeout: status, log_link_handle (8 bits sig only) */ +/* HCI Read Logical Link Accept Timeout: status, logical_link_accept_timeout */ +/* HCI Write Logical Link Accept Timeout: status */ +/* HCI Set Event Mask Page 2: status */ +/* HCI Read Location Data: status, loc_domain_aware, loc_domain, loc_options */ +/* HCI Write Location Data: status */ +/* HCI Read Flow Control Mode: status, flow_control_mode */ +/* HCI Write Flow Control Mode: status */ +/* HCI Read Best Effort Flush Timeout: status, (logical_link_handle ? No!), best_effort_flush_timeout */ +/* HCI Write Best Effort Flush Timeout: status */ +/* HCI Set Short Range Mode: status */ +/* HCI Read Local Version Info: status, HC_HCI_Version, HC_HCI_Revision, HC_PAL_Version, HC_Manufac_Name, HC_PAL_Sub_Version */ +/* HCI Read Local supported commands: status, HC_Support_Cmds */ +/* HCI Read Buffer Size: status, HC_ACL_Data_Packet_Length, HC_SCO_Packet_Length, HC_Total_Num_ACL_Packets, HC_Total_Num_SCO_Packets */ +/* HCI Read Data Block Size: status, HC_Max_ACL_Data_Packet_Length, HC_Data_Block_Length, HC_Total_Num_Data_Blocks */ +/* HCI Read Failed Contact Counter: status, log_link_handle, *pFailedContactCounter */ +/* HCI Reset Failed Contact Counter: status, log_link_handle */ +/* HCI Read Link Quality: status, log_link_handle(?Yes!?), link_quality */ +/* HCI Read RSSI: status, phy_link_handle, rssi */ +/* HCI Read Local AMP Info: status, HC_AMP_Status, HC_Total_BW, HC_Max_Guaranteed_BW, HC_Min_Latency, HC_Max_PDU_Size, HC_Controller_Type, HC_PAL_Capabilities, HC_AMP_Assoc_Length, HC_Max_Flush_Timeout, HC_BE_Flush_Timeout */ +/* HCI Read Local AMP Assoc: status, phy_link_handle, AMP ASSOC remaining length (just actual length, in practice), AMP ASSOC fragment (byte string) */ +/* where AMP Assoc consists of: HC_mac_addr, pref channel (HC_pref_country, HC_pref_triplets), Cnct channel (HC_cnct_country, HC_cnct_triplets), HC_pal_capabilities, HC_pal_version */ +/* HCI Write Remote AMP Assoc: status, phy_link_handle */ +/* HCI Read Loopback Mode: status, loopback_mode */ +/* HCI Write Loopback Mode: status */ + +#endif + +/* BT AMP configuration items */ +typedef struct +{ + /* user preferred channel on which we start the link */ + v_U8_t ucPreferredChannel; + +}WLANBAP_ConfigType; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + VOSS interfaces - Device initialization + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). BAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Open +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). BAP will + use this call to register with TL as the BAP entity for + BT-AMP RSN frames. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Start +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in BAP, before close. BAP will suspend all + BT-AMP Protocol Adaption Layer operation and will wait for the close + request to clean up its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Stop +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. BAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Close +( + v_PVOID_t pvosGCtx +); + +/*---------------------------------------------------------------------------- + HDD interfaces - Per instance initialization + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetNewHndl + + DESCRIPTION + Called by HDD at driver open (BSL_Open). BAP will initialize + allocate a per-instance "file handle" equivalent for this specific + open call. + + There should only ever be one call to BSL_Open. Since + the open app user is the BT stack. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle to return btampHandle value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetNewHndl +( + ptBtampHandle *hBtampHandle /* Handle to return btampHandle value in */ +); + +/*========================================================================== + + FUNCTION WLANBAP_ReleaseHndl + + DESCRIPTION + Called by HDD at driver close (BSL_Close). BAP will reclaim (invalidate) + the "file handle" passed into this call. + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: btampHandle value to invalidate. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to btampHandle is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_ReleaseHndl +( + ptBtampHandle btampHandle /* btamp handle value to release */ +); + +/*---------------------------------------------------------------------------- + HDD interfaces - Data plane + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + HDD Data callbacks + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION (*WLANBAP_STAFetchPktCBType)() + + DESCRIPTION + Type of the fetch packet callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STAFetchPktCBType routine being called. Which is called by + TL when the scheduling algorithms allows for transmission of another + packet to the module. + + This function is here to "wrap" or abstract WLANTL_STAFetchPktCBType. + Because the BAP-specific HDD "shim" layer (BSL) doesn't know anything + about STAIds, or other parameters required by TL. + + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STAFetchCBType + to retreive this value. + + IN/OUT + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ + +typedef VOS_STATUS (*WLANBAP_STAFetchPktCBType)( + v_PVOID_t pHddHdl, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo); + + + +/*---------------------------------------------------------------------------- + + FUNCTION (*WLANBAP_STARxCBType)( ) + + DESCRIPTION + Type of the receive callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STARxCBType routine being called. Which is called by + TL to notify when a packet was received for a registered STA. + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STARxCBType + to retrieve this value. + + vosDataBuff: pointer to the VOSS data buffer that was received + (it may be a linked list) + pRxMetaInfo: Rx meta info related to the data frame + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANBAP_STARxCBType)( v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + WLANTL_RxMetaInfoType* pRxMetaInfo); + + + +/*---------------------------------------------------------------------------- + + FUNCTION (*WLANBAP_TxCompCBType)() + + DESCRIPTION + Type of the tx complete callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_TxCompCBType routine being called. Which is called by + TL to notify when a transmission for a packet has ended. + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + <> + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANBAP_TxCompCBType)( v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus ); + +/*---------------------------------------------------------------------------- + HDD Data plane API + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_RegisterDataPlane + + DESCRIPTION + The HDD calls this routine to register the "data plane" routines + for Tx, Rx, and Tx complete with BT-AMP. For now, with only one + physical association supported at a time, this COULD be called + by HDD at the same time as WLANBAP_GetNewHndl. But, in general + it needs to be called upon each new physical link establishment. + + This registration is really two part. The routines themselves are + registered here. But, the mapping between the BSL context and the + actual physical link takes place during WLANBAP_PhysicalLinkCreate. + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RegisterDataPlane +( + ptBtampHandle btampHandle, /* BTAMP context */ + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB, + WLANBAP_STARxCBType pfnBtamp_STARxCB, + WLANBAP_TxCompCBType pfnBtampTxCompCB, + // phy_link_handle, of course, doesn't come until much later. At Physical Link create. + v_PVOID_t pHddHdl /* BSL specific context */ +); +//#endif + +/*=========================================================================== + + FUNCTION WLANBAP_XlateTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet and it wants + to translate it into a 802.3 LLC frame - ready to send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the BT-AMP packet to be + translated to an 802.3 LLC frame + tlMetaInfo: return meta info gleaned from the outgoing frame, here. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here */ + WLANTL_MetaInfoType *tlMetaInfo, /* Return the MetaInfo here. An assist to WLANBAP_STAFetchPktCBType */ + vos_pkt_t *vosDataBuff +); + +/*=========================================================================== + + FUNCTION WLANBAP_XlateRxDataPkt + + DESCRIPTION + + HDD will call this API when it has received a 802.3 (TL/UMA has + Xlated from 802.11) frame from TL and it wants to form a + BT HCI Data Packet - ready to signal up to the BT stack application. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateRxDataPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here. I don't think this is needed */ + vos_pkt_t *vosDataBuff +); + +/*=========================================================================== + + FUNCTION WLANBAP_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. HDD uses this instead of WLANTL_STAPktPending because he is + not aware of the mapping from session to STA ID. + + DEPENDENCIES + + HDD must have called WLANBAP_GetNewHndl before calling this API. + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + BSL can obtain this from the physical handle value in the + downgoing HCI Data Packet. He, after all, was there + when the PhysicalLink was created. He knew the btampHandle + value returned by WLANBAP_GetNewHndl. He knows as well, his + own pHddHdl (see next). + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + ucAc: The access category for the pending frame + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_STAPktPending +( + ptBtampHandle btampHandle, /* Used by BAP to identify the app context and VOSS ctx (!?) */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType ucAc /* This is the first instance of a TL type in bapApi.h */ +); + +/*---------------------------------------------------------------------------- + * BT-AMP PAL HCI Event callback types + *--------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION (*tpWLAN_BAPEventCB)() + + DESCRIPTION + Implements the callback for ALL asynchronous events. + Including Events resulting from: + * HCI Create Physical Link, + * Disconnect Physical Link, + * Create Logical Link, + * Flow Spec Modify, + * HCI Reset, + * HCI Flush,... + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pHddHdl: The HDD(BSL) specific context for this association. + BSL gets this from the downgoing packets Physical handle + value. + pBapHCIEvent: pointer to the union of "HCI Event" structures. Contains all info + needed for HCI event. + assoc_specific_event: flag indicates assoc-specific (1) or global (0) event + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*tpWLAN_BAPEventCB) +( + v_PVOID_t pHddHdl, /* this could refer to either the BSL per + association context which got passed in during + register data plane OR the BSL per application + context passed in during register BAP callbacks + based on setting of the Boolean flag below */ + /* It's like each of us is using the other */ + /* guys reference when invoking him. */ + tpBtampHCI_Event pBapHCIEvent, /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ + v_BOOL_t assoc_specific_event /* Flag to indicate global or assoc-specific event */ +); + + +/*---------------------------------------------------------------------------- + HCI Event Callback Registration routine + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPRegisterBAPCallbacks() + + DESCRIPTION + Register the BAP "Event" callbacks. + Return the per instance handle. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pBapHCIEventCB: pointer to the Event callback + pAppHdl: The context passed in by caller. (I.E., BSL app specific context.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEventCB is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPRegisterBAPCallbacks +( + ptBtampHandle btampHandle, /* BSL uses my handle to talk to me */ + /* Returned from WLANBAP_GetNewHndl() */ + /* It's like each of us is using the other */ + /* guys reference when invoking him. */ + tpWLAN_BAPEventCB pBapHCIEventCB, /*Implements the callback for ALL asynchronous events. */ + v_PVOID_t pAppHdl // Per-app BSL context +); + + + +/*---------------------------------------------------------------------------- + Host Controller Interface Procedural API + ---------------------------------------------------------------------------*/ + +/** BT v3.0 Link Control commands */ + +/*---------------------------------------------------------------------------- + Each of the next eight command result in asynchronous events (e.g., + HCI_PHYSICAL_LINK_COMPLETE_EVENT, HCI_LOGICAL_LINK_COMPLETE_EVENT, etc...) + These are signalled thru the event callback. (I.E., (*tpWLAN_BAPEventCB).) + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + WLANBAP_GetNewHndl has to be called before every call to + WLAN_BAPPhysicalLinkCreate. Since the context is per + physical link. + pBapHCIPhysLinkCreate: pointer to the "HCI Create Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Physical_Link_Cmd *pBapHCIPhysLinkCreate, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkAccept: pointer to the "HCI Accept Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Physical_Link_Cmd *pBapHCIPhysLinkAccept, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkDisconnect: pointer to the "HCI Disconnect Physical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pBapHCIPhysLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCreate: pointer to the "HCI Create Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Logical_Link_Cmd *pBapHCILogLinkCreate, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkAccept: pointer to the "HCI Accept Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Logical_Link_Cmd *pBapHCILogLinkAccept, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkDisconnect: pointer to the "HCI Disconnect Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pBapHCILogLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCancel() + + DESCRIPTION + Implements the actual HCI Cancel Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCancel: pointer to the "HCI Cancel Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + (BTW, the required "HCI Logical Link Complete Event" + will be generated by the BAP state machine and sent up + via the (*tpWLAN_BAPEventCB).) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCancel is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCancel +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Logical_Link_Cancel_Cmd *pBapHCILogLinkCancel, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlowSpecModify() + + DESCRIPTION + Implements the actual HCI Modify Logical Link command + Produces an asynchronous flow spec modify complete event. Through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlowSpecModify: pointer to the "HCI Flow Spec Modify" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlowSpecModify is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlowSpecModify +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flow_Spec_Modify_Cmd *pBapHCIFlowSpecModify, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* Host Controller and Baseband Commands */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReset() + + DESCRIPTION + Implements the actual HCI Reset command. + Produces an asynchronous command complete event. Through the + command complete callback. (I.E., (*tpWLAN_BAPEventCB).) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReset +( + ptBtampHandle btampHandle +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMask() + + DESCRIPTION + Implements the actual HCI Set Event Mask command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMask: pointer to the "HCI Set Event Mask" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMask is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMask +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Cmd *pBapHCISetEventMask, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlush() + + DESCRIPTION + Implements the actual HCI Flush command + Produces an asynchronous command complete event. Through the + event callback. And an asynchronous Flush occurred event. Also through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Flush" Structure. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flush_Cmd *pBapHCIFlush +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_EnhancedBAPFlush() + + DESCRIPTION + Implements the actual HCI Enhanced Flush command + Produces an asynchronous command complete event. Through the command status + event callback. And an asynchronous Enhanced Flush Complete event. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Enhanced Flush" Structure. + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_EnhancedBAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Enhanced_Flush_Cmd *pBapHCIFlush, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ + +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete */ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteConnectionAcceptTimeout: pointer to the "HCI Connection Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pBapHCIWriteConnectionAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Read Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + /* Only 8 bits (phy_link_handle) of this log_link_handle are valid. */ + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pBapHCIReadLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Write Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLinkSupervisionTimeout: pointer to the "HCI Link Supervision Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pBapHCIWriteLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* v3.0 Host Controller and Baseband Commands */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLogicalLinkAcceptTimeout: pointer to the "HCI Logical Link Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pBapHCIWriteLogicalLinkAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMaskPage2() + + DESCRIPTION + Implements the actual HCI Set Event Mask Page 2 command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMaskPage2: pointer to the "HCI Set Event Mask Page 2" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMaskPage2 is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMaskPage2 +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pBapHCISetEventMaskPage2, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocationData() + + DESCRIPTION + Implements the actual HCI Read Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocationData +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLocationData() + + DESCRIPTION + Implements the actual HCI Write Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLocationData: pointer to the "HCI Write Location Data" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLocationData +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Location_Data_Cmd *pBapHCIWriteLocationData, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFlowControlMode() + + DESCRIPTION + Implements the actual HCI Read Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFlowControlMode +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteFlowControlMode() + + DESCRIPTION + Implements the actual HCI Write Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteFlowControlMode: pointer to the "HCI Write Flow Control Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteFlowControlMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pBapHCIWriteFlowControlMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Read Best Effort Flush Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + /* The log_link_hanlde identifies which logical link's BE TO*/ + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pBapHCIReadBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Write Best Effort Flush TO command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteBEFlushTO: pointer to the "HCI Write BE Flush TO" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pBapHCIWriteBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetShortRangeMode() + + DESCRIPTION + Implements the actual HCI Set Short Range Mode command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIShortRangeMode: pointer to the "HCI Set Short Range Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIShortRangeMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetShortRangeMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pBapHCIShortRangeMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd0() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 0 (OGF 0x3f, OCF 0x0000). + There is no need for a callback because when this call returns the action has + been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd0 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd1() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 1 (OGF 0x3f, OCF 0x0001). + There is no need for a callback because when this call returns the action has + been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd1 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* End of v3.0 Host Controller and Baseband Commands */ + + +/* Informational Parameters */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalVersionInfo() + + DESCRIPTION + Implements the actual HCI Read Local Version Info command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalVersionInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalVersionInfo +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalSupportedCmds() + + DESCRIPTION + Implements the actual HCI Read Local Supported Commands. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalSupportedCmds is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalSupportedCmds +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBufferSize() + + DESCRIPTION + Implements the actual HCI Read Buffer Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBufferSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBufferSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadDataBlockSize() + + DESCRIPTION + Implements the actual HCI Read Data Block Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadDataBlockSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadDataBlockSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/* +Status Parameters +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Read Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadFailedContactCounter: pointer to the "HCI Read Failed Contact Counter" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFailedContactCounter or + pFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pBapHCIReadFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPResetFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Reset Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIResetFailedContactCounter: pointer to the "HCI Reset Failed Contact Counter" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIResetFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPResetFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pBapHCIResetFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkQuality() + + DESCRIPTION + Implements the actual HCI Read Link Quality command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLinkQuality: pointer to the "HCI Read Link Quality" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkQuality or + pBapHCILinkQuality is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkQuality +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Link_Quality_Cmd *pBapHCIReadLinkQuality, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadRSSI() + + DESCRIPTION + Implements the actual HCI Read RSSI command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadRSSI or + pBapHCIRSSI is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadRSSI +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_RSSI_Cmd *pBapHCIReadRSSI, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPInfo() + + DESCRIPTION + Implements the actual HCI Read Local AMP Information command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPInfo: pointer to the "HCI Read Local AMP Info" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPInfo or + pBapHCILocalAMPInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPInfo +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pBapHCIReadLocalAMPInfo, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPAssoc() + + DESCRIPTION + Implements the actual HCI Read Local AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPAssoc: pointer to the "HCI Read Local AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPAssoc + (or pBapHCILocalAMPAssoc) is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pBapHCIReadLocalAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteRemoteAMPAssoc() + + DESCRIPTION + Implements the actual HCI Write Remote AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteRemoteAMPAssoc: pointer to the "HCI Write Remote AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteRemoteAMPAssoc is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteRemoteAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pBapHCIWriteRemoteAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/* +Debug Commands +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLoopbackMode() + + DESCRIPTION + Implements the actual HCI Read Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLoopbackMode: pointer to the "HCI Read Loopback Mode". + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLoopbackMode or + pBapHCILoopbackMode is NULL. + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Loopback_Mode_Cmd *pBapHCIReadLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLoopbackMode() + + DESCRIPTION + Implements the actual HCI Write Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLoopbackMode: pointer to the "HCI Write Loopback Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLoopbackMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Loopback_Mode_Cmd *pBapHCIWriteLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetConfig() + + DESCRIPTION + The function updates some configuration for BAP module in SME during SMEs + close -> open sequence. + + BAP applies the new configuration at the next transaction. + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + + IN + pConfig: a pointer to a caller allocated object of typedef struct WLANBAP_ConfigType. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pConfig or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetConfig +( + ptBtampHandle btampHandle, + WLANBAP_ConfigType *pConfig +); + +/*=========================================================================== + + FUNCTION WLANBAP_GetAcFromTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet (SKB) and it wants + to find AC type of the data frame from the HCI header on the data pkt + - to be send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + pHciData: Pointer to the HCI data frame + + pucAC: Pointer to return the access category + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetAcFromTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + void *pHciData, /* Pointer to the HCI data frame */ + WLANTL_ACEnumType *pucAC /* Return the AC here */ +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPGetMask() + + DESCRIPTION + The function gets the updated event mask from BAP core. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + IN + pEvent_mask_page_2: a pointer to a caller allocated object of 8 bytes. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pEvent_mask_page_2 or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPGetMask( ptBtampHandle btampHandle, + v_U8_t *pEvent_mask_page_2); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPDisconnect() + + DESCRIPTION + The function to request to BAP core to disconnect currecnt AMP connection. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPDisconnect +( + ptBtampHandle btampHandle +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSessionOn() + + DESCRIPTION + The function to check from BAP core if AMP connection is up right now. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_TRUE: AMP connection is on + VOS_FALSE: AMP connection is not on + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +v_BOOL_t WLAN_BAPSessionOn +( + ptBtampHandle btampHandle +); + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_H */ + diff --git a/drivers/staging/prima/CORE/BAP/inc/btampHCI.h b/drivers/staging/prima/CORE/BAP/inc/btampHCI.h new file mode 100644 index 000000000000..edaeccacb6bb --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/inc/btampHCI.h @@ -0,0 +1,2129 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef BTAMPHCI_H +#define BTAMPHCI_H + +/** + * \file btampHCI.h + * + * \brief Structures, function prototypes & definitions + * for working with 802.11 Frames + * + * + + * + * + * This file was automatically generated by 'framesc' + * Mon Mar 02 14:06:14 2009 from the following file(s): + * + * btampHCI.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * Instead, please update the input files & re-run + * 'framesc' For more information on 'framesc' & the + * frames language, run 'framesc --help'. + * + * + */ + + +#define WLANBAP_MAX_LOG_LINKS 16 /* Logical links are assigned by BAP */ + + +#if 0 + +/* Calling conventions: The General format of the Unpack and Pack routines */ + +/*========================================================================== + + FUNCTION Unpack_XxxMessage + + DESCRIPTION + Unpack from a Message buffer into a structured type. + + + DEPENDENCIES + + + PARAMETERS + + + IN + void * : halHandle (passed down to the MAC layer and below) + v_U8_t* : Pointer to the source message buffer + v_U16_t : Length in bytes of the contents of the message buffer. + tXxxMessage* : Pointer to the structure in which to return the unpacked values. + + RETURN VALUE + + The result code associated with performing the operation + + + SIDE EFFECTS + +============================================================================*/ +v_U32_t Unpack_XxxMessage(void *, v_U8_t*,v_U16_t, tXxxMessage*); + + +/*========================================================================== + + FUNCTION Pack_XxxMessage + + DESCRIPTION + Pack the data from a structure into a Message buffer. + + + DEPENDENCIES + + + PARAMETERS + + + IN + void * : halHandle (passed down to the MAC layer and below) + tXxxMessage* : Pointer to the structure from which to obtain values. + v_U8_t* : Pointer to the destination message buffer. + v_U32_t : Length in bytes of the destination message buffer. + v_U32_t* : Pointer to return the actual length of the encoded message buffer in. + + + RETURN VALUE + + The result code associated with performing the operation + + SIDE EFFECTS + + +============================================================================*/ +v_U32_t Pack_XxxMessage(void *, tXxxMessage*, v_U8_t*, v_U32_t, v_U32_t*); + +#endif + + +typedef v_U32_t tBTAMP_U64[2]; + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4214) /* nonstandard extension used */ +#endif /* Microsoft C/C++ bit field types other than int */ + +/* + * Frames Return Codes: + * + * Success is indicated by a return value of zero. Failure is indicated + * by the presence of the high bit. Warnings encountered in the course + * of a successful parse are indicated by various bits in the lower 31 + * being turned on. + * + * For instance, a return value of 0x0000000a would indicate that the + * parse succeeded, but that a mandatory IE wasn't present, and some IE + * was found to be corrupt. + * + * + */ + +#define BTAMP_PARSE_SUCCESS ( 0x00000000 ) +#define BTAMP_UNKNOWN_IES ( 0x00000001 ) +#define BTAMP_MANDATORY_IE_MISSING ( 0x00000002 ) +#define BTAMP_INCOMPLETE_IE ( 0x00000004 ) +#define BTAMP_SKIPPED_BAD_IE ( 0x00000008 ) +#define BTAMP_LAST_IE_TOO_LONG ( 0x00000010 ) +#define BTAMP_DUPLICATE_IE ( 0x00000020 ) +#define BTAMP_BAD_FIXED_VALUE ( 0x00000040 ) +#define BTAMP_INCOMPLETE_TLV ( 0x00000080 ) +#define BTAMP_INVALID_TLV_LENGTH ( 0x00000100 ) +#define BTAMP_SKIPPED_BAD_TLV ( 0x00000200 ) +#define BTAMP_UNKNOWN_TLVS ( 0x00000400 ) +#define BTAMP_LAST_TLV_TOO_LONG ( 0x00000800 ) +#define BTAMP_INTERNAL_ERROR ( 0x10000001 ) +#define BTAMP_MISSING_FIXED_FIELD ( 0x10000002 ) +#define BTAMP_BAD_INPUT_BUFFER ( 0x10000003 ) +#define BTAMP_BAD_OUTPUT_BUFFER ( 0x10000004 ) +#define BTAMP_BUFFER_OVERFLOW ( 0x10000005 ) +#define BTAMP_MANDATORY_TLV_MISSING ( 0x00001000 ) +#define BTAMP_FAILED(code) ( (code) & 0x10000000 ) +#define BTAMP_WARNED(code) ( ( ( 0 == (code) ) & 0x10000000 ) && code) +#define BTAMP_SUCCEEDED(code) ( (code) == 0 ) + +/********************************************************************* + * Fixed Fields * + ********************************************************************/ + +/********************************************************************* + * TLVs * + ********************************************************************/ + +// ID 3 (0x0003) +typedef struct sBtampTLVAMP_Assoc_Connected_Channel { + v_U8_t present; + v_U8_t country[3]; + v_U8_t num_triplets; + v_U8_t triplets[5][3]; +} tBtampTLVAMP_Assoc_Connected_Channel; + +#define BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL ( 3 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL_MIN_LEN ( 5 ) + +#define BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL_MAX_LEN ( 11 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_Connected_Channel(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_Connected_Channel*); + +v_U32_t btampPackTlvAMP_Assoc_Connected_Channel(void *, tBtampTLVAMP_Assoc_Connected_Channel*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_Connected_Channel(void *, tBtampTLVAMP_Assoc_Connected_Channel*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1 (0x0001) +typedef struct sBtampTLVAMP_Assoc_MAC_Addr { + v_U8_t present; + v_U8_t mac_addr[6]; +} tBtampTLVAMP_Assoc_MAC_Addr; + +#define BTAMP_TLV_AMP_ASSOC_MAC_ADDR ( 1 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_MAC_ADDR_MIN_LEN ( 8 ) + +#define BTAMP_TLV_AMP_ASSOC_MAC_ADDR_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_MAC_Addr(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_MAC_Addr*); + +v_U32_t btampPackTlvAMP_Assoc_MAC_Addr(void *, tBtampTLVAMP_Assoc_MAC_Addr*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_MAC_Addr(void *, tBtampTLVAMP_Assoc_MAC_Addr*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4 (0x0004) +typedef struct sBtampTLVAMP_Assoc_PAL_Capabilities { + v_U8_t present; + v_U32_t pal_capabilities; +} tBtampTLVAMP_Assoc_PAL_Capabilities; + +#define BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES ( 4 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES_MIN_LEN ( 6 ) + +#define BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Capabilities(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_PAL_Capabilities*); + +v_U32_t btampPackTlvAMP_Assoc_PAL_Capabilities(void *, tBtampTLVAMP_Assoc_PAL_Capabilities*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Capabilities(void *, tBtampTLVAMP_Assoc_PAL_Capabilities*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5 (0x0005) +typedef struct sBtampTLVAMP_Assoc_PAL_Version { + v_U8_t present; + v_U8_t pal_version; + v_U16_t pal_CompanyID; + v_U16_t pal_subversion; +} tBtampTLVAMP_Assoc_PAL_Version; + +#define BTAMP_TLV_AMP_ASSOC_PAL_VERSION ( 5 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_PAL_VERSION_MIN_LEN ( 7 ) + +#define BTAMP_TLV_AMP_ASSOC_PAL_VERSION_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Version(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_PAL_Version*); + +v_U32_t btampPackTlvAMP_Assoc_PAL_Version(void *, tBtampTLVAMP_Assoc_PAL_Version*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Version(void *, tBtampTLVAMP_Assoc_PAL_Version*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 2 (0x0002) +typedef struct sBtampTLVAMP_Assoc_Preferred_Channel_List { + v_U8_t present; + v_U8_t country[3]; + v_U8_t num_triplets; + v_U8_t triplets[5][3]; +} tBtampTLVAMP_Assoc_Preferred_Channel_List; + +#define BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST ( 2 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST_MIN_LEN ( 5 ) + +#define BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST_MAX_LEN ( 20 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvAMP_Assoc_Preferred_Channel_List(void *, v_U8_t*,v_U16_t, tBtampTLVAMP_Assoc_Preferred_Channel_List*); + +v_U32_t btampPackTlvAMP_Assoc_Preferred_Channel_List(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvAMP_Assoc_Preferred_Channel_List(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6 (0x0006) +typedef struct sBtampTLVFlow_Spec { + v_U8_t present; + v_U8_t flow_spec_id; + v_U8_t service_type; + v_U16_t max_sdu; + v_U32_t sdu_inter_arrival; + v_U32_t access_latency; + v_U32_t flush_timeout; +} tBtampTLVFlow_Spec; + +#define BTAMP_TLV_FLOW_SPEC ( 6 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_FLOW_SPEC_MIN_LEN ( 18 ) + +#define BTAMP_TLV_FLOW_SPEC_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvFlow_Spec(void *, v_U8_t*,v_U16_t, tBtampTLVFlow_Spec*); + +v_U32_t btampPackTlvFlow_Spec(void *, tBtampTLVFlow_Spec*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvFlow_Spec(void *, tBtampTLVFlow_Spec*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1081 (0x0439) +typedef struct sBtampTLVHCI_Accept_Logical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec[18]; + v_U8_t rx_flow_spec[18]; +} tBtampTLVHCI_Accept_Logical_Link_Cmd; + +#define BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD ( 1081 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD_MIN_LEN ( 39 ) + +#define BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Accept_Logical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Accept_Logical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Accept_Logical_Link_Cmd(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Accept_Logical_Link_Cmd(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1078 (0x0436) +typedef struct sBtampTLVHCI_Accept_Physical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t key_length; + v_U8_t key_type; + v_U8_t key_material[32]; +} tBtampTLVHCI_Accept_Physical_Link_Cmd; + +#define BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD ( 1078 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD_MAX_LEN ( 37 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Accept_Physical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Accept_Physical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Accept_Physical_Link_Cmd(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Accept_Physical_Link_Cmd(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 65 (0x0041) +typedef struct sBtampTLVHCI_Channel_Selected_Event { + v_U8_t present; + v_U8_t phy_link_handle; +} tBtampTLVHCI_Channel_Selected_Event; + +#define BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT ( 65 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Channel_Selected_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Channel_Selected_Event*); + +v_U32_t btampPackTlvHCI_Channel_Selected_Event(void *, tBtampTLVHCI_Channel_Selected_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Channel_Selected_Event(void *, tBtampTLVHCI_Channel_Selected_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 14 (0x000e) +typedef struct sBtampTLVHCI_Command_Complete_Event { + v_U8_t present; + v_U8_t num_hci_command_packets; + v_U16_t command_opcode; + union + { + struct + { + v_U8_t status; + } Reset; /* command_opcode = c03 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + } Flush; /* command_opcode = c08 */ + struct + { + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec_id; + } Logical_Link_Cancel; /* command_opcode = 43b */ + struct + { + v_U8_t status; + } Set_Event_Mask; /* command_opcode = c05 */ + struct + { + v_U8_t status; + v_U16_t connection_accept_timeout; + } Read_Connection_Accept_TO; /* command_opcode = c15 */ + struct + { + v_U8_t status; + } Write_Connection_Accept_TO; /* command_opcode = c16 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + v_U16_t link_supervision_timeout; + } Read_Link_Supervision_TO; /* command_opcode = c36 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + } Write_Link_Supervision_TO; /* command_opcode = c37 */ + struct + { + v_U8_t status; + v_U16_t logical_link_accept_timeout; + } Read_Logical_Link_Accept_TO; /* command_opcode = c61 */ + struct + { + v_U8_t status; + } Write_Logical_Link_Accept_TO; /* command_opcode = c62 */ + struct + { + v_U8_t status; + } Set_Event_Mask_Page_2; /* command_opcode = c63 */ + struct + { + v_U8_t status; + v_U8_t loc_domain_aware; + v_U8_t loc_domain[3]; + v_U8_t loc_options; + } Read_Location_Data; /* command_opcode = 3172 */ + struct + { + v_U8_t status; + } Write_Location_Data; /* command_opcode = 3173 */ + struct + { + v_U8_t status; + v_U8_t flow_control_mode; + } Read_Flow_Control_Mode; /* command_opcode = 3174 */ + struct + { + v_U8_t status; + } Write_Flow_Control_Mode; /* command_opcode = 3175 */ + struct + { + v_U8_t status; + v_U32_t best_effort_flush_timeout; + } Read_BE_Flush_TO; /* command_opcode = 3177 */ + struct + { + v_U8_t status; + } Write_BE_Flush_TO; /* command_opcode = 3178 */ + struct + { + v_U8_t status; + } Set_Short_Range_Mode; /* command_opcode = 3179 */ + struct + { + v_U8_t status; + v_U8_t HC_HCI_Version; + v_U16_t HC_HCI_Revision; + v_U8_t HC_PAL_Version; + v_U16_t HC_Manufac_Name; + v_U16_t HC_PAL_Sub_Version; + } Read_Local_Version_Info; /* command_opcode = 4097 */ + struct + { + v_U8_t status; + v_U8_t HC_Support_Cmds[64]; + } Read_Local_Supported_Cmds; /* command_opcode = 4098 */ + struct + { + v_U8_t status; + v_U16_t HC_ACL_Data_Packet_Length; + v_U8_t HC_SCO_Packet_Length; + v_U16_t HC_Total_Num_ACL_Packets; + v_U16_t HC_Total_Num_SCO_Packets; + } Read_Buffer_Size; /* command_opcode = 4101 */ + struct + { + v_U8_t status; + v_U16_t HC_Max_ACL_Data_Packet_Length; + v_U16_t HC_Data_Block_Length; + v_U16_t HC_Total_Num_Data_Blocks; + } Read_Data_Block_Size; /* command_opcode = 4106 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + v_U16_t failed_contact_counter; + } Read_Failed_Contact_Counter; /* command_opcode = 5121 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + } Reset_Failed_Contact_Counter; /* command_opcode = 5122 */ + struct + { + v_U8_t status; + v_U16_t log_link_handle; + v_U8_t link_quality; + } Read_Link_Quality; /* command_opcode = 5123 */ + struct + { + v_U8_t status; + /* 2 bytes handle to comply with spec, (lower byte valid) */ + v_U16_t phy_link_handle; + v_S7_t rssi; + } Read_RSSI; /* command_opcode = 5125 */ + struct + { + v_U8_t status; + v_U8_t HC_AMP_Status; + v_U32_t HC_Total_BW; + v_U32_t HC_Max_Guaranteed_BW; + v_U32_t HC_Min_Latency; + v_U32_t HC_Max_PDU_Size; + v_U8_t HC_Controller_Type; + v_U16_t HC_PAL_Capabilities; + v_U16_t HC_AMP_Assoc_Length; + v_U32_t HC_Max_Flush_Timeout; + v_U32_t HC_BE_Flush_Timeout; + } Read_Local_AMP_Info; /* command_opcode = 5129 */ + struct + { + v_U8_t status; + v_U8_t phy_link_handle; + v_U16_t remaining_length; + v_U8_t AMP_assoc_fragment[248]; + } Read_Read_Local_AMP_Assoc; /* command_opcode = 5130 */ + struct + { + v_U8_t status; + v_U8_t phy_link_handle; + } Write_Remote_AMP_Assoc; /* command_opcode = 5131 */ + struct + { + v_U8_t status; + v_U8_t loopback_mode; + } Read_Loopback_Mode; /* command_opcode = 6145 */ + struct + { + v_U8_t status; + } Write_Loopback_Mode; /* command_opcode = 6146 */ + struct + { + v_U8_t status; + } Vendor_Specific_Cmd_0; /* command_opcode = fc00 */ + struct + { + v_U8_t status; + } Vendor_Specific_Cmd_1; /* command_opcode = fc01 */ + } cc_event; +} tBtampTLVHCI_Command_Complete_Event; + +#define BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT ( 14 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT_MAX_LEN ( 257 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Command_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Command_Complete_Event*); + +v_U32_t btampPackTlvHCI_Command_Complete_Event(void *, tBtampTLVHCI_Command_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Command_Complete_Event(void *, tBtampTLVHCI_Command_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 15 (0x000f) +typedef struct sBtampTLVHCI_Command_Status_Event { + v_U8_t present; + v_U8_t status; + v_U8_t num_hci_command_packets; + v_U16_t command_opcode; +} tBtampTLVHCI_Command_Status_Event; + +#define BTAMP_TLV_HCI_COMMAND_STATUS_EVENT ( 15 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_COMMAND_STATUS_EVENT_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_COMMAND_STATUS_EVENT_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Command_Status_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Command_Status_Event*); + +v_U32_t btampPackTlvHCI_Command_Status_Event(void *, tBtampTLVHCI_Command_Status_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Command_Status_Event(void *, tBtampTLVHCI_Command_Status_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1080 (0x0438) +typedef struct sBtampTLVHCI_Create_Logical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec[18]; + v_U8_t rx_flow_spec[18]; +} tBtampTLVHCI_Create_Logical_Link_Cmd; + +#define BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD ( 1080 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD_MIN_LEN ( 39 ) + +#define BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Create_Logical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Create_Logical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Create_Logical_Link_Cmd(void *, tBtampTLVHCI_Create_Logical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Create_Logical_Link_Cmd(void *, tBtampTLVHCI_Create_Logical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1077 (0x0435) +typedef struct sBtampTLVHCI_Create_Physical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t key_length; + v_U8_t key_type; + v_U8_t key_material[32]; +} tBtampTLVHCI_Create_Physical_Link_Cmd; + +#define BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD ( 1077 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD_MAX_LEN ( 37 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Create_Physical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Create_Physical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Create_Physical_Link_Cmd(void *, tBtampTLVHCI_Create_Physical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Create_Physical_Link_Cmd(void *, tBtampTLVHCI_Create_Physical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 26 (0x001a) +typedef struct sBtampTLVHCI_Data_Buffer_Overflow_Event { + v_U8_t present; + v_U8_t link_type; +} tBtampTLVHCI_Data_Buffer_Overflow_Event; + +#define BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT ( 26 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Data_Buffer_Overflow_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Data_Buffer_Overflow_Event*); + +v_U32_t btampPackTlvHCI_Data_Buffer_Overflow_Event(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Data_Buffer_Overflow_Event(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1082 (0x043a) +typedef struct sBtampTLVHCI_Disconnect_Logical_Link_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Disconnect_Logical_Link_Cmd; + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD ( 1082 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 70 (0x0046) +typedef struct sBtampTLVHCI_Disconnect_Logical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U16_t log_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT ( 70 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1079 (0x0437) +typedef struct sBtampTLVHCI_Disconnect_Physical_Link_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Disconnect_Physical_Link_Cmd; + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD ( 1079 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*); + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Cmd(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 66 (0x0042) +typedef struct sBtampTLVHCI_Disconnect_Physical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT ( 66 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1084 (0x043c) +typedef struct sBtampTLVHCI_Flow_Spec_Modify_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U8_t be_aggr_counter; + v_U8_t tx_flow_spec[18]; + v_U8_t rx_flow_spec[18]; +} tBtampTLVHCI_Flow_Spec_Modify_Cmd; + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD ( 1084 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD_MIN_LEN ( 41 ) + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD_MAX_LEN ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Cmd*); + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Cmd(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Cmd(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 71 (0x0047) +typedef struct sBtampTLVHCI_Flow_Spec_Modify_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U16_t log_link_handle; +} tBtampTLVHCI_Flow_Spec_Modify_Complete_Event; + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT ( 71 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*); + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Complete_Event(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Complete_Event(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3080 (0x0c08) +typedef struct sBtampTLVHCI_Flush_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Flush_Cmd; + +#define BTAMP_TLV_HCI_FLUSH_CMD ( 3080 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLUSH_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_FLUSH_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flush_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flush_Cmd*); + +v_U32_t btampPackTlvHCI_Flush_Cmd(void *, tBtampTLVHCI_Flush_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flush_Cmd(void *, tBtampTLVHCI_Flush_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 17 (0x0011) +typedef struct sBtampTLVHCI_Flush_Occurred_Event { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Flush_Occurred_Event; + +#define BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT ( 17 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Flush_Occurred_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Flush_Occurred_Event*); + +v_U32_t btampPackTlvHCI_Flush_Occurred_Event(void *, tBtampTLVHCI_Flush_Occurred_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Flush_Occurred_Event(void *, tBtampTLVHCI_Flush_Occurred_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3167 (0x0C5F) +typedef struct sBtampTLVHCI_Enhanced_Flush_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U8_t packet_type; +} tBtampTLVHCI_Enhanced_Flush_Cmd; + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD ( 3167 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Enhanced_Flush_Cmd*); + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Cmd(void *, tBtampTLVHCI_Enhanced_Flush_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Cmd(void *, tBtampTLVHCI_Enhanced_Flush_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 57 (0x0039) +typedef struct sBtampTLVHCI_Enhanced_Flush_Complete_Event { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Enhanced_Flush_Complete_Event; + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT ( 57 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Enhanced_Flush_Complete_Event*); + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Complete_Event(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Complete_Event(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ + +// ID 62 (0x003e) +typedef struct sBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event { + v_U8_t present; + v_U8_t bd_addr[6]; + v_U8_t generic_amp_link_key[32]; + v_U8_t key_type; +} tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event; + +#define BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT ( 62 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT_MIN_LEN ( 41 ) + +#define BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT_MAX_LEN ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*); + +v_U32_t btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Generic_AMP_Link_Key_Notification_Event(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 16 (0x0010) +typedef struct sBtampTLVHCI_Hardware_Error_Event { + v_U8_t present; + v_U8_t hardware_code; +} tBtampTLVHCI_Hardware_Error_Event; + +#define BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT ( 16 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Hardware_Error_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Hardware_Error_Event*); + +v_U32_t btampPackTlvHCI_Hardware_Error_Event(void *, tBtampTLVHCI_Hardware_Error_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Hardware_Error_Event(void *, tBtampTLVHCI_Hardware_Error_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1083 (0x043b) +typedef struct sBtampTLVHCI_Logical_Link_Cancel_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t tx_flow_spec_id; +} tBtampTLVHCI_Logical_Link_Cancel_Cmd; + +#define BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD ( 1083 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Logical_Link_Cancel_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Logical_Link_Cancel_Cmd*); + +v_U32_t btampPackTlvHCI_Logical_Link_Cancel_Cmd(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Cancel_Cmd(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 69 (0x0045) +typedef struct sBtampTLVHCI_Logical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U16_t log_link_handle; + v_U8_t phy_link_handle; + v_U8_t flow_spec_id; +} tBtampTLVHCI_Logical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT ( 69 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Logical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Logical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Logical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Complete_Event(void *, tBtampTLVHCI_Logical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 25 (0x0019) +typedef struct sBtampTLVHCI_Loopback_Command_Event { + v_U8_t present; + v_U8_t hci_command_packet[64]; +} tBtampTLVHCI_Loopback_Command_Event; + +#define BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT ( 25 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT_MIN_LEN ( 66 ) + +#define BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT_MAX_LEN ( 66 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Loopback_Command_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Loopback_Command_Event*); + +v_U32_t btampPackTlvHCI_Loopback_Command_Event(void *, tBtampTLVHCI_Loopback_Command_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Loopback_Command_Event(void *, tBtampTLVHCI_Loopback_Command_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 64 (0x0040) +typedef struct sBtampTLVHCI_Physical_Link_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t ch_number; +} tBtampTLVHCI_Physical_Link_Complete_Event; + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT ( 64 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Physical_Link_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Physical_Link_Complete_Event*); + +v_U32_t btampPackTlvHCI_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Physical_Link_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Complete_Event(void *, tBtampTLVHCI_Physical_Link_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 67 (0x0043) +typedef struct sBtampTLVHCI_Physical_Link_Loss_Warning_Event { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t reason; +} tBtampTLVHCI_Physical_Link_Loss_Warning_Event; + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT ( 67 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Physical_Link_Loss_Warning_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*); + +v_U32_t btampPackTlvHCI_Physical_Link_Loss_Warning_Event(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Loss_Warning_Event(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 68 (0x0044) +typedef struct sBtampTLVHCI_Physical_Link_Recovery_Event { + v_U8_t present; + v_U8_t phy_link_handle; +} tBtampTLVHCI_Physical_Link_Recovery_Event; + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT ( 68 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Physical_Link_Recovery_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Physical_Link_Recovery_Event*); + +v_U32_t btampPackTlvHCI_Physical_Link_Recovery_Event(void *, tBtampTLVHCI_Physical_Link_Recovery_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Recovery_Event(void *, tBtampTLVHCI_Physical_Link_Recovery_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 30 (0x001e) +typedef struct sBtampTLVHCI_Qos_Violation_Event { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Qos_Violation_Event; + +#define BTAMP_TLV_HCI_QOS_VIOLATION_EVENT ( 30 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_QOS_VIOLATION_EVENT_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_QOS_VIOLATION_EVENT_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Qos_Violation_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Qos_Violation_Event*); + +v_U32_t btampPackTlvHCI_Qos_Violation_Event(void *, tBtampTLVHCI_Qos_Violation_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Qos_Violation_Event(void *, tBtampTLVHCI_Qos_Violation_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3177 (0x0c69) +typedef struct sBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD ( 3177 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4101 (0x1005) +typedef struct sBtampTLVHCI_Read_Buffer_Size_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Buffer_Size_Cmd; + +#define BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD ( 4101 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Buffer_Size_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Buffer_Size_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Buffer_Size_Cmd(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Buffer_Size_Cmd(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3093 (0x0c15) +typedef struct sBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD ( 3093 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4106 (0x100a) +typedef struct sBtampTLVHCI_Read_Data_Block_Size_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Data_Block_Size_Cmd; + +#define BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD ( 4106 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Data_Block_Size_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Data_Block_Size_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Data_Block_Size_Cmd(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Data_Block_Size_Cmd(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5121 (0x1401) +typedef struct sBtampTLVHCI_Read_Failed_Contact_Counter_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd; + +#define BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD ( 5121 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3174 (0x0c66) +typedef struct sBtampTLVHCI_Read_Flow_Control_Mode_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Flow_Control_Mode_Cmd; + +#define BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD ( 3174 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Flow_Control_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5123 (0x1403) +typedef struct sBtampTLVHCI_Read_Link_Quality_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Link_Quality_Cmd; + +#define BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD ( 5123 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Link_Quality_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Link_Quality_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Link_Quality_Cmd(void *, tBtampTLVHCI_Read_Link_Quality_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Link_Quality_Cmd(void *, tBtampTLVHCI_Read_Link_Quality_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3126 (0x0c36) +typedef struct sBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD ( 3126 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5130 (0x140a) +typedef struct sBtampTLVHCI_Read_Local_AMP_Assoc_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U16_t length_so_far; + v_U16_t max_remote_amp_assoc_length; +} tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD ( 5130 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Assoc_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Assoc_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5129 (0x1409) +typedef struct sBtampTLVHCI_Read_Local_AMP_Information_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Local_AMP_Information_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD ( 5129 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Information_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Information_Cmd(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4098 (0x1002) +typedef struct sBtampTLVHCI_Read_Local_Supported_Cmds_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD ( 4098 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_Supported_Cmds_Cmd(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_Supported_Cmds_Cmd(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4097 (0x1001) +typedef struct sBtampTLVHCI_Read_Local_Version_Info_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Local_Version_Info_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD ( 4097 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Local_Version_Info_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Local_Version_Info_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Local_Version_Info_Cmd(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Local_Version_Info_Cmd(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3172 (0x0c64) +typedef struct sBtampTLVHCI_Read_Location_Data_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Location_Data_Cmd; + +#define BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD ( 3172 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Location_Data_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Location_Data_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Location_Data_Cmd(void *, tBtampTLVHCI_Read_Location_Data_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Location_Data_Cmd(void *, tBtampTLVHCI_Read_Location_Data_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3169 (0x0c61) +typedef struct sBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD ( 3169 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6145 (0x1801) +typedef struct sBtampTLVHCI_Read_Loopback_Mode_Cmd { + v_U8_t present; +} tBtampTLVHCI_Read_Loopback_Mode_Cmd; + +#define BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD ( 6145 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_Loopback_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_Loopback_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Read_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5125 (0x1405) +typedef struct sBtampTLVHCI_Read_RSSI_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Read_RSSI_Cmd; + +#define BTAMP_TLV_HCI_READ_RSSI_CMD ( 5125 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_READ_RSSI_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_READ_RSSI_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Read_RSSI_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Read_RSSI_Cmd*); + +v_U32_t btampPackTlvHCI_Read_RSSI_Cmd(void *, tBtampTLVHCI_Read_RSSI_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Read_RSSI_Cmd(void *, tBtampTLVHCI_Read_RSSI_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3075 (0x0c03) +typedef struct sBtampTLVHCI_Reset_Cmd { + v_U8_t present; +} tBtampTLVHCI_Reset_Cmd; + +#define BTAMP_TLV_HCI_RESET_CMD ( 3075 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_RESET_CMD_MIN_LEN ( 2 ) + +#define BTAMP_TLV_HCI_RESET_CMD_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Reset_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Reset_Cmd*); + +v_U32_t btampPackTlvHCI_Reset_Cmd(void *, tBtampTLVHCI_Reset_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Reset_Cmd(void *, tBtampTLVHCI_Reset_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5122 (0x1402) +typedef struct sBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd { + v_U8_t present; + v_U16_t log_link_handle; +} tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd; + +#define BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD ( 5122 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*); + +v_U32_t btampPackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Reset_Failed_Contact_Counter_Cmd(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3077 (0x0c05) +typedef struct sBtampTLVHCI_Set_Event_Mask_Cmd { + v_U8_t present; + v_U8_t event_mask[8]; +} tBtampTLVHCI_Set_Event_Mask_Cmd; + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_CMD ( 3077 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SET_EVENT_MASK_CMD_MIN_LEN ( 10 ) + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_CMD_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Set_Event_Mask_Cmd*); + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3171 (0x0c63) +typedef struct sBtampTLVHCI_Set_Event_Mask_Page_2_Cmd { + v_U8_t present; + v_U8_t event_mask_page_2[8]; +} tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd; + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD ( 3171 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD_MIN_LEN ( 10 ) + +#define BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*); + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Page_2_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Page_2_Cmd(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3179 (0x0c6b) +typedef struct sBtampTLVHCI_Set_Short_Range_Mode_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U8_t short_range_mode; +} tBtampTLVHCI_Set_Short_Range_Mode_Cmd; + +#define BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD ( 3179 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Set_Short_Range_Mode_Cmd(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Set_Short_Range_Mode_Cmd(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 76 (0x004c) +typedef struct sBtampTLVHCI_Short_Range_Mode_Change_Complete_Event { + v_U8_t present; + v_U8_t status; + v_U8_t phy_link_handle; + v_U8_t short_range_mode; +} tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event; + +#define BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT ( 76 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT_MIN_LEN ( 5 ) + +#define BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*); + +v_U32_t btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Short_Range_Mode_Change_Complete_Event(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3178 (0x0c6a) +typedef struct sBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U32_t best_effort_flush_timeout; +} tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD ( 3178 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MIN_LEN ( 8 ) + +#define BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3094 (0x0c16) +typedef struct sBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd { + v_U8_t present; + v_U16_t connection_accept_timeout; +} tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD ( 3094 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Connection_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3175 (0x0c67) +typedef struct sBtampTLVHCI_Write_Flow_Control_Mode_Cmd { + v_U8_t present; + v_U8_t flow_control_mode; +} tBtampTLVHCI_Write_Flow_Control_Mode_Cmd; + +#define BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD ( 3175 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Flow_Control_Mode_Cmd(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3127 (0x0c37) +typedef struct sBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd { + v_U8_t present; + v_U16_t log_link_handle; + v_U16_t link_supervision_timeout; +} tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD ( 3127 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD_MIN_LEN ( 6 ) + +#define BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Link_Supervision_Timeout_Cmd(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3173 (0x0c65) +typedef struct sBtampTLVHCI_Write_Location_Data_Cmd { + v_U8_t present; + v_U8_t loc_domain_aware; + v_U8_t loc_domain[3]; + v_U8_t loc_options; +} tBtampTLVHCI_Write_Location_Data_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD ( 3173 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Location_Data_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Location_Data_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Location_Data_Cmd(void *, tBtampTLVHCI_Write_Location_Data_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Location_Data_Cmd(void *, tBtampTLVHCI_Write_Location_Data_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3170 (0x0c62) +typedef struct sBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd { + v_U8_t present; + v_U16_t logical_link_accept_timeout; +} tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD ( 3170 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MIN_LEN ( 4 ) + +#define BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6146 (0x1802) +typedef struct sBtampTLVHCI_Write_Loopback_Mode_Cmd { + v_U8_t present; + v_U8_t loopback_mode; +} tBtampTLVHCI_Write_Loopback_Mode_Cmd; + +#define BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD ( 6146 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD_MIN_LEN ( 3 ) + +#define BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Loopback_Mode_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Loopback_Mode_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Loopback_Mode_Cmd(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5131 (0x140b) +typedef struct sBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd { + v_U8_t present; + v_U8_t phy_link_handle; + v_U16_t length_so_far; + v_U16_t amp_assoc_remaining_length; + v_U8_t amp_assoc_fragment[248]; +} tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd; + +#define BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD ( 5131 ) + +// N.B. These #defines do *not* include the ID & length +#define BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD_MIN_LEN ( 7 ) + +#define BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +v_U32_t btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void *, v_U8_t*,v_U16_t, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*); + +v_U32_t btampPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*, v_U32_t*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 64512 (0xfc00) +typedef struct sBtampTLVHCI_Vendor_Specific_Cmd_0 { + v_U8_t present; +} tBtampTLVHCI_Vendor_Specific_0_Cmd; + +#define BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0 ( 64512 ) + +// ID 64513 (0xfc01) +typedef struct sBtampTLVHCI_Vendor_Specific_Cmd_1 { + v_U8_t present; +} tBtampTLVHCI_Vendor_Specific_1_Cmd; + +#define BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_1 ( 64513 ) + +/********************************************************************* + * Information Elements * + ********************************************************************/ + +/************************************************************************ + * Frames + **********************************************************************/ + +typedef struct sBtampAMP_ASSOC{ + tBtampTLVAMP_Assoc_MAC_Addr AMP_Assoc_MAC_Addr; + tBtampTLVAMP_Assoc_Preferred_Channel_List AMP_Assoc_Preferred_Channel_List; + tBtampTLVAMP_Assoc_Connected_Channel AMP_Assoc_Connected_Channel; + tBtampTLVAMP_Assoc_PAL_Capabilities AMP_Assoc_PAL_Capabilities; + tBtampTLVAMP_Assoc_PAL_Version AMP_Assoc_PAL_Version; +} tBtampAMP_ASSOC; + +#define BTAMP_AMP_ASSOC ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +v_U32_t btampUnpackAMP_ASSOC(void * pCtx, v_U8_t *pBuf, v_U32_t nBuf, tBtampAMP_ASSOC *pFrm); +v_U32_t btampPackAMP_ASSOC(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U8_t *pBuf, v_U32_t nBuf, v_U32_t *pnConsumed); +v_U32_t btampGetPackedAMP_ASSOCSize(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U32_t *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +/* HCI Number of Completed Packets Event*/ +typedef struct sBtampTLVHCI_Num_Completed_Pkts_Event +{ + v_U8_t present; + /* + The number of Connection Handles and Num_Data_Packets + parameters pairs contained in this event.Range: 0-255 + */ + + v_U8_t num_handles; + + /* + Size , Number of Handles * 2 Octets,Range: 0x0000-0x0EFF + */ + v_U16_t conn_handles[WLANBAP_MAX_LOG_LINKS]; + + /* + The number of HCI Data Packets that have been completed (transmitted + or flushed) for the associated Connection Handle since the previous time + the event was returned.Range for N: 0x0000-0xFFFF + */ + v_U16_t num_completed_pkts[WLANBAP_MAX_LOG_LINKS]; +} tBtampTLVHCI_Num_Completed_Pkts_Event; + +#define BTAMP_TLV_HCI_NUM_OF_COMPLETED_PKTS_EVENT ( 19 ) + +v_U32_t btampPackTlvHCI_Num_Completed_Pkts_Event(void *, tBtampTLVHCI_Num_Completed_Pkts_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Pkts_Event(void *, tBtampTLVHCI_Num_Completed_Pkts_Event*, v_U32_t*); + +/*Length of the value field expected in a TLV of type Flow SPec*/ +#define WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN 16 + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +/* HCI Number of Completed Data Blocks Event*/ +typedef struct sBtampTLVHCI_Num_Completed_Data_Blocks_Event +{ + v_U8_t present; + /* + Total number of data block buffers available in the Controller for the + storage of data packets scheduled for transmission. This indicates + the existing value is unchanged, or increased, or reduced by up to + the sum of the Num_Of_Completed_Blocks values in this command + */ + + v_U16_t total_num_data_blocks; + + /* + The number of Connection Handles and Num_Data_Packets + parameters pairs contained in this event.Range: 0-255 + */ + + v_U8_t num_handles; + + /* + Size , Number of Handles * 2 Octets,Range: 0x0000-0x0EFF + */ + v_U16_t conn_handles[WLANBAP_MAX_LOG_LINKS]; + + /* + The number of HCI Data Packets that have been completed (transmitted + or flushed) for the associated Connection Handle since the previous time + the event was returned.Range for N: 0x0000-0xFFFF + */ + v_U16_t num_completed_pkts[WLANBAP_MAX_LOG_LINKS]; + + /* + The number of data blocks that have been freed for the associated + Handle since the previous time that a Number Of Completed Data + Blocks event provided information about this Handle. + Range for N: 0x0000-0xFFFF + */ + v_U16_t num_completed_blocks[WLANBAP_MAX_LOG_LINKS]; + +} tBtampTLVHCI_Num_Completed_Data_Blocks_Event; + +#define BTAMP_TLV_HCI_NUM_OF_COMPLETED_DATA_BLOCKS_EVENT ( 72 ) + +v_U32_t btampPackTlvHCI_Num_Completed_Data_Blocks_Event(void *, tBtampTLVHCI_Num_Completed_Data_Blocks_Event*, v_U8_t*, v_U32_t, v_U32_t*); + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Data_Blocks_Event(void *, tBtampTLVHCI_Num_Completed_Data_Blocks_Event*, v_U32_t*); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +#endif /* BTAMPHCI_H */ + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiData.c b/drivers/staging/prima/CORE/BAP/src/bapApiData.c new file mode 100644 index 000000000000..1a1e67dbc27f --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiData.c @@ -0,0 +1,1274 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i D a t a . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + "platform independent" Data path functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiData.c,v 1.4 2008/11/10 22:34:22 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +//I need the TL types and API +#include "wlan_qct_tl.h" + +#include "wlan_qct_hal.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" +#include "bapApiTimer.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +/*Endian-ness definitions*/ + +#undef BAP_LITTLE_BIT_ENDIAN +#define BAP_LITTLE_BIT_ENDIAN + +/*LLC header definitions*/ + +/* Length of the LLC header*/ +#define WLANBAP_LLC_HEADER_LEN 8 +#if 0 +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_OFFSET 3 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_SIZE 3 + +/*Offset of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_OFFSET (WLANBAP_LLC_OUI_OFFSET + WLANBAP_LLC_OUI_SIZE) + +/*Size of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_SIZE 2 +#endif + +/*BT-AMP protocol type values*/ +/*BT-AMP packet of type data*/ +#define WLANBAP_BT_AMP_TYPE_DATA 0x0001 + +/*BT-AMP packet of type activity report*/ +#define WLANBAP_BT_AMP_TYPE_AR 0x0002 + +/*BT-AMP packet of type security frame*/ +#define WLANBAP_BT_AMP_TYPE_SEC 0x0003 + +/*802.3 header definitions*/ +#define WLANBAP_802_3_HEADER_LEN 14 + +/* Offset of DA field in a 802.3 header*/ +#define WLANBAP_802_3_HEADER_DA_OFFSET 0 + +//*BT-AMP packet LLC OUI value*/ +const v_U8_t WLANBAP_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +/*LLC header value*/ +static v_U8_t WLANBAP_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; + +/* HCI header definitions*/ + +// Define the length of the ACL data packet HCI header +#define WLANBAP_HCI_ACL_HEADER_LEN 4 + +// Debug related defines +//#define DBGLOG printf +#define DUMPLOG_ON +#ifdef DUMPLOG_ON +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif + +#if 0 +// Debug related defines +#define DBGLOG printf +#define DUMPLOG +#if defined DUMPLOG +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + DBGLOG("%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + DBGLOG("%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + DBGLOG("\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif +#endif + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +// Don't we have this type defined somewhere? +#if 0 +/* 802.3 header */ +typedef struct +{ + /* Destination address field */ + v_U8_t vDA[VOS_MAC_ADDR_SIZE]; + + /* Source address field */ + v_U8_t vSA[VOS_MAC_ADDR_SIZE]; + + /* Length field */ + v_U16_t usLenType; /* Num bytes in info field (i.e., exclude 802.3 hdr) */ + /* Max length 1500 (0x5dc) (What about 0x5ee? That + * includes 802.3 Header and FCS.) */ +}WLANBAP_8023HeaderType; +#endif + +/** + * \brief HCI ACL Data packet format + * + * 0 7 8 15 16 23 24 31 + * +--------+----+----+--------+--------+ + * | phy_ |log_| PB/| Data Total | + * | link_ |lnk_| BC | Length | + * | handle |hndl|Flag| | + * +--------+----+----+--------+--------+ + * | | + * | Data | + * ~ ~ + * +--------+---------+--------+--------+ + * + * NB: + * This is in little-endian + * 1) phy_link_handle is the first 8 bits + * 2) log_link_handle is the next 4 bits + * 3) PB flag is the next 2 bits + * 4) BC flags is the next 2 bits + * 5) Total length of the data field is the next 16 bits + * + */ + +typedef struct +{ + +#ifndef BAP_LITTLE_BIT_ENDIAN + + v_U8_t phyLinkHandle; /* do I have to reverse the byte? I think so... */ + + v_U8_t BCFlag :2; + v_U8_t PBFlag :2; + v_U8_t logLinkHandle :4; + + v_U16_t dataLength; /* do I have to reverse each byte? and then reverse the two bytes? I think so... */ + +#else + + v_U8_t phyLinkHandle; + + v_U8_t logLinkHandle :4; + v_U8_t PBFlag :2; + v_U8_t BCFlag :2; + + v_U16_t dataLength; /* Max length WLANBAP_MAX_80211_PAL_PDU_SIZE (1492) */ + +#endif + +} WLANBAP_HCIACLHeaderType; + + + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +#define WLANBAP_DEBUG_FRAME_BYTE_PER_LINE 16 +#define WLANBAP_DEBUG_FRAME_BYTE_PER_BYTE 4 + +/*=========================================================================== + + FUNCTION WLANBAP_XlateTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet and it wants + to translate it into a 802.3 LLC frame - ready to send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the BT-AMP packet to be + translated to an 802.3 LLC frame + tlMetaInfo: return meta info gleaned from the outgoing frame, here. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here */ + WLANTL_MetaInfoType *tlMetaInfo, /* Return the MetaInfo here. An assist to WLANBAP_STAFetchPktCBType */ + vos_pkt_t *vosDataBuff +) +{ + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + tpBtampLogLinkCtx pLogLinkContext; + WLANBAP_8023HeaderType w8023Header; + WLANBAP_HCIACLHeaderType hciACLHeader; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + VOS_STATUS vosStatus; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_U16_t headerLength; /* The 802.3 frame length*/ + v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ + uintptr_t value = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + // Here, I have to make the assumption that this is an + // HCI ACL Data packet that I am being handed. + vosStatus = vos_pkt_pop_head( vosDataBuff, &hciACLHeader, WLANBAP_HCI_ACL_HEADER_LEN); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Failed to pop HCI ACL header from packet %d", + vosStatus); + + return vosStatus; + } + + // JEZ081003: Remove this after debugging + // Sanity check the phy_link_handle value + + if ( phy_link_handle != hciACLHeader.phyLinkHandle ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: phy_link_handle mismatch in %s phy_link_handle=%d hciACLHeader.phyLinkHandle=%d", + __func__, phy_link_handle, hciACLHeader.phyLinkHandle); + return VOS_STATUS_E_INVAL; + } + + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + // JEZ081003: Remove this after debugging + // Sanity check the log_link_handle value + if (!BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link handle (%d) in %s. Corrected.", + hciACLHeader.logLinkHandle, + __func__); + + // JEZ090123: Insure that the logical link value is good + hciACLHeader.logLinkHandle = 1; + //return VOS_STATUS_E_INVAL; + } + + /* Use the log_link_handle to retrieve the logical link context */ + /* JEZ081006: abstract this with a proc. So you can change the impl later */ + pLogLinkContext = &(pBtampCtx->btampLogLinkCtx[ hciACLHeader.logLinkHandle ]); + + // JEZ081003: Remove this after debugging + // Sanity check the log_link_handle value + // JEZ081113: I changed this to fail on an UNOCCUPIED entry + if ( pLogLinkContext->present != VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link entry in %s", + __func__); + + return VOS_STATUS_E_INVAL; + } + + // Return the AC and MetaInfo + + // Now copy the AC values from the Logical Link context + *pucAC = pLogLinkContext->btampAC; + // Now copy the values from the Logical Link context to the MetaInfo + tlMetaInfo->ac = *pucAC; + tlMetaInfo->ucTID = pLogLinkContext->ucTID; + tlMetaInfo->ucUP = pLogLinkContext->ucUP; + tlMetaInfo->ucIsEapol = VOS_FALSE; + tlMetaInfo->ucDisableFrmXtl = VOS_FALSE; + tlMetaInfo->ucBcast = VOS_FALSE; /* hciACLHeader.BCFlag; */ /* Don't I want to use the BCFlag? */ + tlMetaInfo->ucMcast = VOS_FALSE; + tlMetaInfo->ucType = 0x00; /* What is this really ?? */ +// tlMetaInfo->usTimeStamp = 0x00; /* Ravi, shouldn't you be setting this? It's in the VOS packet. */ + + // Form the 802.3 header + + vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); + + /* Now this length passed down in HCI...is in little-endian */ + headerLength = vos_le16_to_cpu(hciACLHeader.dataLength); + headerLength += WLANBAP_LLC_HEADER_LEN; + /* Now the 802.3 length field is big-endian?! */ + w8023Header.usLenType = vos_cpu_to_be16(headerLength); + + /* Now adjust the protocol type bytes*/ + protoType = vos_cpu_to_be16( protoType); + + /* Now form the LLC header */ + vos_mem_copy(aucLLCHeader, + WLANBAP_LLC_HEADER, + sizeof(WLANBAP_LLC_HEADER)); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], + WLANBAP_BT_AMP_OUI, + WLANBAP_LLC_OUI_SIZE); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], + &protoType, //WLANBAP_BT_AMP_TYPE_DATA + WLANBAP_LLC_PROTO_TYPE_SIZE); + + /* Push on the LLC header */ + vos_pkt_push_head(vosDataBuff, + aucLLCHeader, + WLANBAP_LLC_HEADER_LEN); + + /* Push on the 802.3 header */ + vos_pkt_push_head(vosDataBuff, &w8023Header, sizeof(w8023Header)); + + + /*Set the logical link handle as user data so that we can retrieve it on + Tx Complete */ + value = (uintptr_t)hciACLHeader.logLinkHandle; + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, + (v_VOID_t *)value); + + return VOS_STATUS_SUCCESS; +}/*WLANBAP_XlateTxDataPkt*/ + +/*=========================================================================== + + FUNCTION WLANBAP_GetAcFromTxDataPkt + + DESCRIPTION + + HDD will call this API when it has a HCI Data Packet (SKB) and it wants + to find AC type of the data frame from the HCI header on the data pkt + - to be send using TL. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + pHciData: Pointer to the HCI data frame + + pucAC: Pointer to return the access category + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetAcFromTxDataPkt +( + ptBtampHandle btampHandle, /* Used by BAP to identify the actual session + and therefore addresses */ + void *pHciData, /* Pointer to the HCI data frame */ + WLANTL_ACEnumType *pucAC /* Return the AC here */ +) +{ + ptBtampContext pBtampCtx; + tpBtampLogLinkCtx pLogLinkContext; + WLANBAP_HCIACLHeaderType hciACLHeader; + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if (( NULL == btampHandle) || (NULL == pHciData) || (NULL == pucAC)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid params in %s", __func__); + return VOS_STATUS_E_FAULT; + } + pBtampCtx = (ptBtampContext) btampHandle; + + vos_mem_copy( &hciACLHeader, pHciData, WLANBAP_HCI_ACL_HEADER_LEN); + // Sanity check the log_link_handle value + if (!BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link handle (%d) in %s", + hciACLHeader.logLinkHandle, + __func__); + + return VOS_STATUS_E_INVAL; + } + + /* Use the log_link_handle to retrieve the logical link context */ + /* JEZ081006: abstract this with a proc. So you can change the impl later */ + pLogLinkContext = &(pBtampCtx->btampLogLinkCtx[ hciACLHeader.logLinkHandle ]); + + // Sanity check the log_link_handle value + // JEZ081113: I changed this to fail on an UNOCCUPIED entry + if ( pLogLinkContext->present != VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Invalid logical link entry in %s", + __func__); + + return VOS_STATUS_E_INVAL; + } + + // Return the AC + + // Now copy the AC values from the Logical Link context + *pucAC = pLogLinkContext->btampAC; + + return VOS_STATUS_SUCCESS; +} + +/*=========================================================================== + + FUNCTION WLANBAP_XlateRxDataPkt + + DESCRIPTION + + HDD will call this API when it has received a 802.3 (TL/UMA has + Xlated from 802.11) frame from TL and it wants to form a + BT HCI Data Packet - ready to signal up to the BT stack application. + + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_XlateRxDataPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType *pucAC, /* Return the AC here. I don't think this is needed */ + vos_pkt_t *vosDataBuff +) +{ + WLANBAP_8023HeaderType w8023Header; + WLANBAP_HCIACLHeaderType hciACLHeader; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + VOS_STATUS vosStatus; + //v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_U16_t hciDataLength; /* The HCI packet data length*/ + v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + // Here, I have to make the assumption that this is an + // 802.3 header followed by an LLC/SNAP packet. + vos_mem_set( &w8023Header, sizeof(w8023Header), 0 ); + vosStatus = vos_pkt_pop_head( vosDataBuff, &w8023Header, sizeof(w8023Header)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Failed to pop 802.3 header from packet %d", + vosStatus); + + return vosStatus; + } + + // Here, is that LLC/SNAP header. + // With the BT SIG OUI that I am being handed. + vos_mem_set( aucLLCHeader, WLANBAP_LLC_HEADER_LEN, 0 ); + vosStatus = vos_pkt_pop_head( vosDataBuff, aucLLCHeader, WLANBAP_LLC_HEADER_LEN); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Failed to pop LLC/SNAP header from packet %d", + vosStatus); + + return vosStatus; + } + +#ifdef BAP_DEBUG + // JEZ081003: Remove this after debugging + // Should I double check that I am getting the BT SIG OUI ? + if ( !(vos_mem_compare( aucLLCHeader, + WLANBAP_LLC_HEADER, + sizeof(WLANBAP_LLC_HEADER) + - WLANBAP_LLC_OUI_SIZE) /* Don't check the last three bytes here */ + && vos_mem_compare( &aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], + (v_VOID_t*)WLANBAP_BT_AMP_OUI, + WLANBAP_LLC_OUI_SIZE))) /* check them here */ + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid LLC header for BT-AMP packet in %s", __func__); + return VOS_STATUS_E_FAULT; + } +#endif //BAP_DEBUG + + /* Now adjust the protocol type bytes*/ + protoType = vos_cpu_to_be16( protoType); + // check if this is a data frame or other, internal to BAP, type... + // we are only handling data frames in here... + // The others (Security and AR) are handled by TLs BAP client API. + // (Verify with TL) + if ( !(vos_mem_compare( &aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], + &protoType, //WLANBAP_BT_AMP_TYPE_DATA + WLANBAP_LLC_PROTO_TYPE_SIZE))) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid (non-data) frame type in %s", __func__); + return VOS_STATUS_E_FAULT; + } + +#ifdef BAP_DEBUG + // JEZ081003: Remove this after debugging + /*------------------------------------------------------------------------ + Sanity check the MAC address in the physical link context + against the value in the incoming Rx Frame. + ------------------------------------------------------------------------*/ + if ( !(vos_mem_compare( w8023Header.vDA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE) + && vos_mem_compare( w8023Header.vSA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE))) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "MAC address mismatch in %s", __func__); + return VOS_STATUS_E_FAULT; + } +#endif //BAP_DEBUG + + /* No lookup is needed. Because TL has already told WLANBAP_STARxCB + * the StaId. And I told WLANBAP_STARxCBType the corresponding BSL context + * Which he used to lookup the phy_link_handle value. + */ + + + // Start filling in the HCI header + hciACLHeader.phyLinkHandle = phy_link_handle; + + // Continue filling in the HCI header + //JEZ100913: On Rx the Logical Link is ALWAYS 0. See Vol 2, Sec E, 5.4.2 of spec. + hciACLHeader.logLinkHandle = 0; + hciACLHeader.PBFlag = WLANBAP_HCI_PKT_AMP; + hciACLHeader.BCFlag = 0; + + /* Now the length field is big-endian?! */ + hciDataLength = vos_be16_to_cpu(w8023Header.usLenType); + /* Max length WLANBAP_MAX_80211_PAL_PDU_SIZE (1492) */ + hciDataLength -= WLANBAP_LLC_HEADER_LEN; + /* The HCI packet data length is Little-endian */ + hciACLHeader.dataLength = vos_cpu_to_le16(hciDataLength); + + /* Return the AC here. + * (I can't because there is no way to figure out what it is.) + */ + *pucAC = 0; + + /* Push on the HCI header */ + vos_pkt_push_head(vosDataBuff, &hciACLHeader, WLANBAP_HCI_ACL_HEADER_LEN); + + return VOS_STATUS_SUCCESS; +} /* WLANBAP_XlateRxDataPkt */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STAFetchPktCB + + DESCRIPTION + The fetch packet callback registered with TL. + + It is called by the TL when the scheduling algorithms allows for + transmission of another packet to the module. + It will be called in the context of the BAL fetch transmit packet + function, initiated by the bus lower layer. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle + to TL's or HDD's control block can be extracted + from its context + + IN/OUT + pucSTAId: the Id of the station for which TL is requesting a + packet, in case HDD does not maintain per station + queues it can give the next packet in its queue + and put in the right value for the + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STAFetchPktCB +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + v_U8_t ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +) +{ + VOS_STATUS vosStatus; + ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ + ptBtampContext bapContext; /* Holds the btampContext value returned */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + + /* Lookup the BSL and BAP contexts using the StaId */ + + vosStatus = WLANBAP_GetCtxFromStaId ( + *pucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &bapHdl, /* "handle" to return ptBtampHandle value in */ + &bapContext, /* "handle" to return ptBtampContext value in */ + &pHddHdl); /* "handle" to return BSL context in */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve BSL or BAP context from STA Id in WLANBAP_STAFetchPktCB"); + return VOS_STATUS_E_FAULT; + } + + /* Invoke the callback that BSL registered with me */ + vosStatus = (*bapContext->pfnBtampFetchPktCB)( + pHddHdl, + (WLANTL_ACEnumType) ucAC, /* typecast it for now */ + vosDataBuff, + tlMetaInfo); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Callback registered by BSL failed to fetch pkt in WLANNBAP_STAFetchPktCB"); + return VOS_STATUS_E_FAULT; + } + + return vosStatus; +} /* WLANBAP_STAFetchPktCB */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STARxCB + + DESCRIPTION + The receive callback registered with TL. + + TL will call this to notify the client when a packet was received + for a registered STA. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's or HDD's control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was received + (it may be a linked list) + ucSTAId: station id + pRxMetaInfo: meta info for the received packet(s) + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STARxCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + v_U8_t ucSTAId, + WLANTL_RxMetaInfoType* pRxMetaInfo +) +{ + VOS_STATUS vosStatus; + ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ + ptBtampContext bapContext; /* Holds the btampContext value returned */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + ptBtampHandle btampHandle; + WLANBAP_8023HeaderType w8023Header; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + v_U16_t protoType ; + v_SIZE_t llcHeaderLen = WLANBAP_LLC_HEADER_LEN ; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "In WLANBAP_STARxCB"); + + /* Lookup the BSL and BAP contexts using the StaId */ + + vosStatus = WLANBAP_GetCtxFromStaId ( + ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &bapHdl, /* "handle" to return ptBtampHandle value in */ + &bapContext, /* "handle" to return ptBtampContext value in */ + &pHddHdl); /* "handle" to return BSL context in */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve BSL or BAP context from STA Id in WLANBAP_STARxCB"); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_E_FAULT; + } + + + vosStatus = vos_pkt_extract_data( vosDataBuff, sizeof(w8023Header), (v_VOID_t *)aucLLCHeader, + &llcHeaderLen); + + if ( NULL == aucLLCHeader/*LLC Header*/ ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_STARxCB:Cannot extract LLC header"); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_E_FAULT; + } + + vos_mem_copy(&protoType,&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET],WLANBAP_LLC_PROTO_TYPE_SIZE); + protoType = vos_be16_to_cpu(protoType); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: received : %d, => BAP",__func__, + protoType); + + if(WLANBAP_BT_AMP_TYPE_DATA == protoType) + { + if (bapContext->bapLinkSupervisionTimerInterval) + { + /* Reset Link Supervision timer */ + //vosStatus = WLANBAP_StopLinkSupervisionTimer(bapContext); + //vosStatus = WLANBAP_StartLinkSupervisionTimer(bapContext,7000); + bapContext->dataPktPending = VOS_TRUE;//Indication for LinkSupervision module that data is pending + /* Invoke the callback that BSL registered with me */ + vosStatus = (*bapContext->pfnBtamp_STARxCB)( + pHddHdl, + vosDataBuff, + pRxMetaInfo); + } + else + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLANBAP_STARxCB:bapLinkSupervisionTimerInterval is 0"); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: link Supervision packet received over TL: %d, => BAP", + __func__,protoType); + btampHandle = (ptBtampHandle)bapContext; + vosStatus = WLANBAP_RxProcLsPkt( + btampHandle, + bapContext->phy_link_handle, + protoType, + vosDataBuff + ); + } + + return vosStatus; +} /* WLANBAP_STARxCB */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_TxCompCB + + DESCRIPTION + The tx complete callback registered with TL. + + TL will call this to notify the client when a transmission for a + packet has ended. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_TxCompCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +) +{ + VOS_STATUS vosStatus; + ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ + ptBtampContext bapContext; /* Holds the btampContext value returned */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + v_PVOID_t pvlogLinkHandle = NULL; + uintptr_t value; + + WLANBAP_HCIACLHeaderType hciACLHeader; + + /* retrieve the BSL and BAP contexts */ + + /* I don't really know how to do this - in the general case. */ + /* So, for now, I will just use something that works. */ + /* (In general, I will have to keep a list of the outstanding transmit */ + /* buffers, in order to determine which assoc they are with.) */ + //vosStatus = WLANBAP_GetCtxFromStaId ( + // ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + // &bapHdl, /* "handle" to return ptBtampHandle value in */ + // &bapContext, /* "handle" to return ptBtampContext value in */ + // &pHddHdl); /* "handle" to return BSL context in */ + /* Temporarily we do the following*/ + //bapHdl = &btampCtx; + bapHdl = (v_PVOID_t)gpBtampCtx; + /* Typecast the handle into a context. Works as we have only one link*/ + bapContext = ((ptBtampContext) bapHdl); + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == vosDataBuff) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid vosDataBuff value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == bapContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid bapContext value in %s", __func__); + vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAULT; + } + + pHddHdl = bapContext->pHddHdl; + vosStatus = VOS_STATUS_SUCCESS; + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve BSL or BAP context from STA Id in WLANBAP_TxCompCB"); + vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAULT; + } + + /*Get the logical link handle from the vos user data*/ + vos_pkt_get_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, + &pvlogLinkHandle); + + value = (uintptr_t)pvlogLinkHandle; + hciACLHeader.logLinkHandle = value; + +#ifdef BAP_DEBUG + /* Trace the bapContext referenced. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: bapContext value = %p in %s:%d. vosDataBuff=%p", bapContext, __func__, __LINE__, vosDataBuff ); +#endif //BAP_DEBUG + + // Sanity check the log_link_handle value +// JEZ100722: Temporary changes. + if (BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) + { + vos_atomic_increment_U32( + &bapContext->btampLogLinkCtx[hciACLHeader.logLinkHandle].uTxPktCompleted); +// &bapContext->btampLogLinkCtx[0].uTxPktCompleted); +// vos_atomic_increment_U32( +// &bapContext->btampLogLinkCtx[1].uTxPktCompleted); + } else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In %s:%d: Invalid logical link handle: %d", __func__, __LINE__, hciACLHeader.logLinkHandle); + } + + /* Invoke the callback that BSL registered with me */ + vosStatus = (*bapContext->pfnBtampTxCompCB)( + pHddHdl, + vosDataBuff, + wTxSTAtus); + + return vosStatus; +} /* WLANBAP_TxCompCB */ + +/*========================================================================== + + FUNCTION WLANBAP_RegisterDataPlane + + DESCRIPTION + The HDD calls this routine to register the "data plane" routines + for Tx, Rx, and Tx complete with BT-AMP. For now, with only one + physical association supported at a time, this COULD be called + by HDD at the same time as WLANBAP_GetNewHndl. But, in general + it needs to be called upon each new physical link establishment. + + This registration is really two part. The routines themselves are + registered here. But, the mapping between the BSL context and the + actual physical link takes place during WLANBAP_PhysicalLinkCreate. + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RegisterDataPlane +( + ptBtampHandle btampHandle, /* BTAMP context */ + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB, + WLANBAP_STARxCBType pfnBtamp_STARxCB, + WLANBAP_TxCompCBType pfnBtampTxCompCB, + // phy_link_handle, of course, doesn't come until much later. At Physical Link create. + v_PVOID_t pHddHdl /* BSL specific context */ +) +{ + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLANBAP_RegisterDataPlane"); + return VOS_STATUS_E_FAULT; + } + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + pBtampCtx->pfnBtampFetchPktCB = pfnBtampFetchPktCB; + pBtampCtx->pfnBtamp_STARxCB = pfnBtamp_STARxCB; + pBtampCtx->pfnBtampTxCompCB = pfnBtampTxCompCB; + + // (Right now, there is only one) + pBtampCtx->pHddHdl = pHddHdl; + /* Set the default data transfer mode */ + pBtampCtx->ucDataTrafficMode = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED; + + return VOS_STATUS_SUCCESS; +} /* WLANBAP_RegisterDataPlane */ + + +/*=========================================================================== + + FUNCTION WLANBAP_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. HDD uses this instead of WLANTL_STAPktPending because he is + not aware of the mapping from session to STA ID. + + DEPENDENCIES + + HDD must have called WLANBAP_GetNewHndl before calling this API. + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + BSL can obtain this from the physical handle value in the + downgoing HCI Data Packet. He, after all, was there + when the PhysicalLink was created. He knew the btampHandle + value returned by WLANBAP_GetNewHndl. He knows as well, his + own pHddHdl (see next). + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + ucAc: The access category for the pending frame + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_STAPktPending +( + ptBtampHandle btampHandle, /* Used by BAP to identify the app context and VOSS ctx (!?) */ + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + WLANTL_ACEnumType ucAc /* This is the first instance of a TL type in bapApi.h */ +) +{ + VOS_STATUS vosStatus; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + v_PVOID_t pvosGCtx; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampCtx value = %p in %s:%d", pBtampCtx, __func__, __LINE__ ); +#endif //BAP_DEBUG + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLANBAP_STAPktPending"); + return VOS_STATUS_E_FAULT; + } + + // Retrieve the VOSS context + pvosGCtx = pBtampCtx->pvosGCtx; + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in WLANBAP_STAPktPending"); + return VOS_STATUS_E_FAULT; + } + + + // Let TL know we have a packet to send... + vosStatus = WLANTL_STAPktPending( + pvosGCtx, + ucSTAId, + ucAc); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Tx: Packet rejected by TL in WLANBAP_STAPktPending"); + return vosStatus; + } + pBtampCtx->dataPktPending = VOS_TRUE;//Indication for LinkSupervision module that data is pending + return VOS_STATUS_SUCCESS; +} /* WLANBAP_STAPktPending */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPRegisterBAPCallbacks() + + DESCRIPTION + Register the BAP "Event" callbacks. + Return the per instance handle. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pBapHCIEventCB: pointer to the Event callback + pAppHdl: The context passed in by caller. (I.E., BSL app specific context.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEventCB is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPRegisterBAPCallbacks +( + ptBtampHandle btampHandle, /* BSL uses my handle to talk to me */ + /* Returned from WLANBAP_GetNewHndl() */ + /* It's like each of us is using the other */ + /* guys reference when invoking him. */ + tpWLAN_BAPEventCB pBapHCIEventCB, /*Implements the callback for ALL asynchronous events. */ + v_PVOID_t pAppHdl // Per-app BSL context +) +{ + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLAN_BAPRegisterBAPCallbacks"); + return VOS_STATUS_E_FAULT; + } + + // Save the Event callback + pBtampCtx->pBapHCIEventCB = pBapHCIEventCB; + + // (Right now, there is only one) + pBtampCtx->pAppHdl = pAppHdl; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPRegisterBAPCallbacks */ + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiDebug.c b/drivers/staging/prima/CORE/BAP/src/bapApiDebug.c new file mode 100644 index 000000000000..f812f2c1b222 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiDebug.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i D e b u g . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Debug functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiDebug.c,v 1.2 2008/11/10 22:37:58 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +// +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/* +Debug Commands +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLoopbackMode() + + DESCRIPTION + Implements the actual HCI Read Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLoopbackMode: pointer to the "HCI Read Loopback Mode". + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLoopbackMode or + pBapHCILoopbackMode is NULL. + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Loopback_Mode_Cmd *pBapHCIReadLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLoopbackMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLoopbackMode() + + DESCRIPTION + Implements the actual HCI Write Loopback Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLoopbackMode: pointer to the "HCI Write Loopback Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLoopbackMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLoopbackMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Loopback_Mode_Cmd *pBapHCIWriteLoopbackMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLoopbackMode */ + + + + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiExt.c b/drivers/staging/prima/CORE/BAP/src/bapApiExt.c new file mode 100644 index 000000000000..b0d2ea57d7d7 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiExt.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i E x t . C + + OVERVIEW: + + This software unit holds the implementation of the external interfaces + required by the WLAN BAP module. It is currently a temporary + respository for API routines which should be furnished by CSR + or TL, but aren't yet implemented. + + The functions provide by this module are called by the rest of + the BT-AMP PAL module. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiExt.c,v 1.1 2008/11/21 20:28:18 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-10-22 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// I think this pulls in everything +#include "bapApiExt.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetCurrentChannel + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + channel: current configured channel number. + activeFlag: flag indicating whether there is an active link. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to return channel is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCurrentChannel +( + ptBtampContext pBtampCtx, + v_U32_t *channel, // return current channel here + v_U32_t *activeFlag // return active flag here +) +{ + //v_U32_t cb_enabled; + tHalHandle halHandle; + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if (( NULL == pBtampCtx ) || (NULL == channel) || (NULL == activeFlag)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + halHandle = VOS_GET_HAL_CB(pBtampCtx->pvosGCtx); + + if(NULL == halHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "halHandle is NULL in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + if (ccmCfgGetInt(halHandle, WNI_CFG_CURRENT_CHANNEL, channel) + != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Get CFG failed in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + *activeFlag = FALSE; // return active flag here + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_GetCurrentChannel */ + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiExt.h b/drivers/staging/prima/CORE/BAP/src/bapApiExt.h new file mode 100644 index 000000000000..6293e6519f0f --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiExt.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_API_EXT_H +#define WLAN_QCT_WLANBAP_API_EXT_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external APIs used by the wlan BT-AMP PAL layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiExt.h,v 1.1 2008/11/21 20:29:13 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/22/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// Pick up all the BT-AMP internal definitions +// And underlying supporting types. (Including VOSS, CSR, and...) +#include "bapInternal.h" + +/* Pick up the SIRIUS and HAL types */ +// Already taken care of, above +//#include "sirApi.h" +//#include "halTypes.h" + +/* Pick up the CCM API def'n */ +#include "ccmApi.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +// Temporary +//#define BAP_DEBUG + +// How do I get BAP context from voss context? +//#define VOS_GET_BAP_CB(ctx) vos_get_context( VOS_MODULE_ID_BAP, ctx) +// How do I get halHandle from voss context? +//#define VOS_GET_HAL_CB(ctx) vos_get_context( VOS_MODULE_ID_HAL, ctx) + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Function prototypes + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function prototypes + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetCurrentChannel + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + channel: current configured channel number. + activeFlag: flag indicating whether there is an active link. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to return channel is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCurrentChannel +( + ptBtampContext pBtampCtx, + v_U32_t *channel, // return current channel here + v_U32_t *activeFlag // return active flag here +); + + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_API_EXT_H */ + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiHCBB.c b/drivers/staging/prima/CORE/BAP/src/bapApiHCBB.c new file mode 100644 index 000000000000..7fc780050516 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiHCBB.c @@ -0,0 +1,1698 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i H C B B . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Host Controller and Baseband functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /prj/qct/asw/engbuilds/scl/users02/jzmuda/Android/ampBlueZ_6/CORE/BAP/src/bapApiHCBB.c,v 1.7 2011/05/06 00:59:27 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_trace.h" + +// Pick up the sme callback registration API +#include "sme_Api.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + + +/* Host Controller and Baseband Commands */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReset() + + DESCRIPTION + Implements the actual HCI Reset command. + Produces an asynchronous command complete event. Through the + command complete callback. (I.E., (*tpWLAN_BAPEventCB).) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReset +( + ptBtampHandle btampHandle +) +{ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tHalHandle hHal = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampHandle is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + /* Perform a "reset" */ + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //csrRoamDisconnect(); + /* To avoid sending Disassoc on STA interface */ + if( TRUE == btampContext->isBapSessionOpen ) + { + sme_RoamDisconnect(hHal, + btampContext->sessionId, + // Danlin, where are the richer reason codes? + // I want to be able to convey everything 802.11 supports... + eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + + /* Need to reset the timers as well*/ + /* Connection Accept Timer interval*/ + btampContext->bapConnectionAcceptTimerInterval = WLANBAP_CONNECTION_ACCEPT_TIMEOUT; + /* Link Supervision Timer interval*/ + btampContext->bapLinkSupervisionTimerInterval = WLANBAP_LINK_SUPERVISION_TIMEOUT; + /* Logical Link Accept Timer interval*/ + btampContext->bapLogicalLinkAcceptTimerInterval = WLANBAP_LOGICAL_LINK_ACCEPT_TIMEOUT; + /* Best Effort Flush timer interval*/ + btampContext->bapBEFlushTimerInterval = WLANBAP_BE_FLUSH_TIMEOUT; + + + /* Form and immediately return the command complete event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + bapHCIEvent.u.btampCommandCompleteEvent.present = 1; + bapHCIEvent.u.btampCommandCompleteEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_RESET_CMD; + bapHCIEvent.u.btampCommandCompleteEvent.cc_event.Reset.status + = WLANBAP_STATUS_SUCCESS; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + //btampContext->pHddHdl, /* this refers to the BSL per connection context */ + btampContext->pAppHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* WLAN_BAPReset */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMask() + + DESCRIPTION + Implements the actual HCI Set Event Mask command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMask: pointer to the "HCI Set Event Mask" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMask is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMask +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Cmd *pBapHCISetEventMask, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPSetEventMask */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlush() + + DESCRIPTION + Implements the actual HCI Flush command + Produces an asynchronous command complete event. Through the + event callback. And an asynchronous Flush occurred event. Also through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Flush" Structure. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flush_Cmd *pBapHCIFlush +) +{ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Form and immediately return the command complete event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + bapHCIEvent.u.btampCommandCompleteEvent.present = 1; + bapHCIEvent.u.btampCommandCompleteEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_FLUSH_CMD; + bapHCIEvent.u.btampCommandCompleteEvent.cc_event.Flush.status + = WLANBAP_STATUS_SUCCESS; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + //btampContext->pHddHdl, /* this refers to the BSL per connection context */ + btampContext->pAppHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* WLAN_BAPFlush */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_EnhancedBAPFlush() + + DESCRIPTION + Implements the actual HCI Enhanced Flush command + Produces an asynchronous command complete event. Through the command status + event callback. And an asynchronous Enhanced Flush Complete event. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlush: pointer to the "HCI Enhanced Flush" Structure. + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlush is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_EnhancedBAPFlush +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Enhanced_Flush_Cmd *pBapHCIFlush, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ + +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + /* Form and return the command status event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + /* Form and immediately return the command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT; + pBapHCIEvent->u.btampEnhancedFlushCompleteEvent.present = 1; + pBapHCIEvent->u.btampEnhancedFlushCompleteEvent.log_link_handle = + pBapHCIFlush->log_link_handle; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + //btampContext->pHddHdl, /* this refers to the BSL per connection context */ + btampContext->pAppHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* WLAN_EnhancedBAPFlush */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete */ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Connection_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Connection_Accept_TO.connection_accept_timeout + = btampContext->bapConnectionAcceptTimerInterval; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadConnectionAcceptTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteConnectionAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Connection Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteConnectionAcceptTimeout: pointer to the "HCI Connection Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteConnectionAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteConnectionAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pBapHCIWriteConnectionAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteConnectionAcceptTimeout) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the allowed timeout interval range */ + if ((pBapHCIWriteConnectionAcceptTimeout->connection_accept_timeout > + WLANBAP_CON_ACCEPT_TIMEOUT_MAX_RANGE) || + (pBapHCIWriteConnectionAcceptTimeout->connection_accept_timeout < + WLANBAP_CON_ACCEPT_TIMEOUT_MIN_RANGE)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Out of range for connection accept timeout parameters in %s", + __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Connection_Accept_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Save the Physical link connection accept timeout value */ + btampContext->bapConnectionAcceptTimerInterval = + pBapHCIWriteConnectionAcceptTimeout->connection_accept_timeout; + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Connection_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteConnectionAcceptTimeout */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Read Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + /* Only 8 bits (phy_link_handle) of this log_link_handle are valid. */ + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pBapHCIReadLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIReadLinkSupervisionTimeout) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the phyiscal link handle extracted from + logical link handle (lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIReadLinkSupervisionTimeout->log_link_handle; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.link_supervision_timeout + = 0x00; /* Invalid value */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.log_link_handle + = pBapHCIReadLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.link_supervision_timeout + = btampContext->bapLinkSupervisionTimerInterval; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.log_link_handle + = pBapHCIReadLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Supervision_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLinkSupervisionTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLinkSupervisionTimeout() + + DESCRIPTION + Implements the actual HCI Write Link Supervision Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLinkSupervisionTimeout: pointer to the "HCI Link Supervision Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLinkSupervisionTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLinkSupervisionTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pBapHCIWriteLinkSupervisionTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteLinkSupervisionTimeout) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the phyiscal link handle extracted from + logical link handle (lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIWriteLinkSupervisionTimeout->log_link_handle; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.log_link_handle + = pBapHCIWriteLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Save the LS timeout interval */ + btampContext->bapLinkSupervisionTimerInterval = + pBapHCIWriteLinkSupervisionTimeout->link_supervision_timeout; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.log_link_handle + = pBapHCIWriteLinkSupervisionTimeout->log_link_handle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Link_Supervision_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLinkSupervisionTimeout */ + +/* v3.0 Host Controller and Baseband Commands */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Read Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Logical_Link_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Logical_Link_Accept_TO.logical_link_accept_timeout + = btampContext->bapLogicalLinkAcceptTimerInterval; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLogicalLinkAcceptTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLogicalLinkAcceptTimeout() + + DESCRIPTION + Implements the actual HCI Write Logical Link Accept Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLogicalLinkAcceptTimeout: pointer to the "HCI Logical Link Accept Timeout" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLogicalLinkAcceptTimeout is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLogicalLinkAcceptTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pBapHCIWriteLogicalLinkAcceptTimeout, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteLogicalLinkAcceptTimeout) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the allowed timeout interval range */ + if ((pBapHCIWriteLogicalLinkAcceptTimeout->logical_link_accept_timeout > + WLANBAP_CON_ACCEPT_TIMEOUT_MAX_RANGE) || + (pBapHCIWriteLogicalLinkAcceptTimeout->logical_link_accept_timeout < + WLANBAP_CON_ACCEPT_TIMEOUT_MIN_RANGE)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Out of range for logical connection accept timeout parameters in %s", + __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Logical_Link_Accept_TO.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Save the Physical link connection accept timeout value */ + btampContext->bapLogicalLinkAcceptTimerInterval = + pBapHCIWriteLogicalLinkAcceptTimeout->logical_link_accept_timeout; + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Logical_Link_Accept_TO.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLogicalLinkAcceptTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetEventMaskPage2() + + DESCRIPTION + Implements the actual HCI Set Event Mask Page 2 command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCISetEventMaskPage2: pointer to the "HCI Set Event Mask Page 2" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCISetEventMaskPage2 is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetEventMaskPage2 +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pBapHCISetEventMaskPage2, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCISetEventMaskPage2) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + + /* Save away the event mask */ + vos_mem_copy( + btampContext->event_mask_page_2, + pBapHCISetEventMaskPage2->event_mask_page_2, + 8 ); + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Set_Event_Mask_Page_2.status + = WLANBAP_STATUS_SUCCESS; + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPSetEventMaskPage2 */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocationData() + + DESCRIPTION + Implements the actual HCI Read Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocationData +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + ptBtampContext btampContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.loc_domain_aware + = btampContext->btamp_Location_Data_Info.loc_domain_aware; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.loc_options + = btampContext->btamp_Location_Data_Info.loc_options; + + vos_mem_copy( + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.loc_domain, + btampContext->btamp_Location_Data_Info.loc_domain, + 3 ); + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Location_Data.status + = WLANBAP_STATUS_SUCCESS; + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocationData */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteLocationData() + + DESCRIPTION + Implements the actual HCI Write Location Data command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteLocationData: pointer to the "HCI Write Location Data" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteLocationData is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteLocationData +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Location_Data_Cmd *pBapHCIWriteLocationData, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIWriteLocationData) + || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + + btampContext->btamp_Location_Data_Info.loc_domain_aware = + pBapHCIWriteLocationData->loc_domain_aware; + + btampContext->btamp_Location_Data_Info.loc_options = + pBapHCIWriteLocationData->loc_options; + + vos_mem_copy( + btampContext->btamp_Location_Data_Info.loc_domain, + pBapHCIWriteLocationData->loc_domain, + 3 ); + + /* Return status for command complete event */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Location_Data.status + = WLANBAP_STATUS_SUCCESS; + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteLocationData */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFlowControlMode() + + DESCRIPTION + Implements the actual HCI Read Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFlowControlMode +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Flow_Control_Mode.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Flow_Control_Mode.flow_control_mode + = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadFlowControlMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteFlowControlMode() + + DESCRIPTION + Implements the actual HCI Write Flow Control Mode command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteFlowControlMode: pointer to the "HCI Write Flow Control Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteFlowControlMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteFlowControlMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pBapHCIWriteFlowControlMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteFlowControlMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Read Best Effort Flush Timeout command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + /* The log_link_hanlde identifies which logical link's BE TO*/ + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pBapHCIReadBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadBestEffortFlushTimeout */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteBestEffortFlushTimeout() + + DESCRIPTION + Implements the actual HCI Write Best Effort Flush TO command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteBEFlushTO: pointer to the "HCI Write BE Flush TO" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteBEFlushTO is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteBestEffortFlushTimeout +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pBapHCIWriteBEFlushTO, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteBestEffortFlushTimeout */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetShortRangeMode() + + DESCRIPTION + Implements the actual HCI Set Short Range Mode command. There is no need for + a callback because when this call returns the action has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIShortRangeMode: pointer to the "HCI Set Short Range Mode" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIShortRangeMode is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetShortRangeMode +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pBapHCIShortRangeMode, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the BAP state to accept the Short Range Mode set request; + SRM set requests are allowed only in CONNECTED state */ + + /* Form and return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD; + + if (CONNECTED != instanceVar->stateVar) + { + /* Short Range Mode request in invalid state */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + return VOS_STATUS_SUCCESS; + } + else if (pBapHCIShortRangeMode->phy_link_handle != btampContext->phy_link_handle) + { + /* Invalid Physical link handle */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_NO_CNCT; + return VOS_STATUS_SUCCESS; + } + else if (pBapHCIShortRangeMode->short_range_mode > 0x01) + { + /* Invalid mode requested */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + return VOS_STATUS_SUCCESS; + } + + pBapHCIEvent->u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + /* Send the Command Status event (success) here, since Change Complete is next */ + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + pBapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + /* Format the Short Range Mode Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT; + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.present = 1; + + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.status = + WLANBAP_STATUS_SUCCESS; /* Assumption for now */ + + /* The input parameters will go out in the CC Event */ + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.phy_link_handle = + pBapHCIShortRangeMode->phy_link_handle; + + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.short_range_mode = + pBapHCIShortRangeMode->short_range_mode; /* Assumption for now */ + + /* If the requested setting is different from the current setting... */ + if (pBapHCIShortRangeMode->short_range_mode != btampContext->phy_link_srm) + { + /* ... then change the SRM according to the requested value. + * If the attempt fails, the assumptions above need to be corrected. + */ + #if 0 + // Suggested API, needs to be created + if (VOS_STATUS_SUCCESS != HALSetShortRangeMode(pBapHCIShortRangeMode->short_range_mode)) + #else + if (0) + #endif + { + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.status = + WLANBAP_ERROR_HARDWARE_FAILURE; + pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent.short_range_mode = + btampContext->phy_link_srm; /* Switch back to current value */ + } + else + { + /* Update the SRM setting for this physical link, since it worked */ + btampContext->phy_link_srm = pBapHCIShortRangeMode->short_range_mode; + } + } + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPSetShortRangeMode */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd0() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 0 (OGF 0x3f, OCF 0x0000). + There is no need for a callback because when this call returns the action has + been completed. + + The command is received when: + - The A2MP Create Phy Link Response has been rx'd by the Bluetooth stack (initiator) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd0 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the BAP state to accept the Vendor Specific Cmd 0: + this is only allowed for the BT_INITIATOR in the CONNECTING state */ + + /* Form and return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0; + + if ( (BT_INITIATOR != btampContext->BAPDeviceRole) || + (CONNECTING != instanceVar->stateVar) ) + { + /* Vendor Specific Command 0 happened in invalid state */ + pBapHCIEvent->u.btampCommandStatusEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + return VOS_STATUS_SUCCESS; + } + + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority(btampContext, 1); + + pBapHCIEvent->u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + /* Send the Command Status event (success) here, since Command Complete is next */ + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + pBapHCIEvent, /* This now encodes ALL event types */ + VOS_FALSE /* Flag to indicate assoc-specific event */ + ); + + /* Format the Vendor Specific Command 0 Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Vendor_Specific_Cmd_0.status + = WLANBAP_STATUS_SUCCESS; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPVendorSpecificCmd0 */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPVendorSpecificCmd1() + + DESCRIPTION + Implements the actual HCI Vendor Specific Command 1 (OGF 0x3f, OCF 0x0001). + There is no need for a callback because when this call returns the action has + been completed. + + The command is received when: + - HCI wants to enable testability + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPVendorSpecificCmd1 +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + + btampContext->btamp_async_logical_link_create = TRUE; + + + /* Format the Vendor Specific Command 1 Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_1; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Vendor_Specific_Cmd_1.status + = WLANBAP_STATUS_SUCCESS; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPVendorSpecificCmd1 */ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Callback registered with TL for BAP, this is required in order for + TL to inform BAP, that the flush operation requested has been completed. + + The registered reception callback is being triggered by TL whenever a + frame SIR_TL_HAL_FLUSH_AC_RSP is received by TL from HAL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucStaId: station identifier for the requested value + ucTid: identifier of the tspec + status: status of the Flush operation + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_TLFlushCompCallback +( + v_PVOID_t pvosGCtx, + v_U8_t ucStaId, + v_U8_t ucTID, + v_U8_t status +) +{ + + return VOS_STATUS_SUCCESS; +} // WLANBAP_TLFlushCompCallback + + +/* End of v3.0 Host Controller and Baseband Commands */ + + + + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiInfo.c b/drivers/staging/prima/CORE/BAP/src/bapApiInfo.c new file mode 100644 index 000000000000..0463c4858f8d --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiInfo.c @@ -0,0 +1,608 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i I n f o . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Information functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/c/Dropbox/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_PAL/CORE/BAP/src/bapApiInfo.c,v 1.2 2008/11/10 22:55:24 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +#include "sme_Api.h" +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + + +/* Informational Parameters */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalVersionInfo() + + DESCRIPTION + Implements the actual HCI Read Local Version Info command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalVersionInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalVersionInfo +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_HCI_Version + = WLANBAP_HCI_VERSION; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_HCI_Revision + = WLANBAP_HCI_REVISION; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_PAL_Version + = WLANBAP_PAL_VERSION; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_Manufac_Name + = WLANBAP_QUALCOMM_COMPANY_ID; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Version_Info.HC_PAL_Sub_Version + = WLANBAP_PAL_SUBVERSION; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalVersionInfo */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalSupportedCmds() + + DESCRIPTION + Implements the actual HCI Read Local Supported Commands. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + // There are really no input parameters in this command. + // Just the command opcode itself is sufficient. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalSupportedCmds is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalSupportedCmds +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + v_U8_t supportedCmds[] = WLANBAP_PAL_SUPPORTED_HCI_CMDS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Supported_Cmds.status + = WLANBAP_STATUS_SUCCESS; + /* Return the supported commands bitmask */ + vos_mem_copy( + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_Supported_Cmds.HC_Support_Cmds, + supportedCmds, + sizeof( supportedCmds)); + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalSupportedCmds */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadBufferSize() + + DESCRIPTION + Implements the actual HCI Read Buffer Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadBufferSize: pointer to the "HCI Read Buffer Size" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadBufferSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadBufferSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.status + = WLANBAP_STATUS_SUCCESS; + /* Return the supported Buffer sizes */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_ACL_Data_Packet_Length + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_SCO_Packet_Length + = 0; /* Invalid assignment to Uint8, makes 0 */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_Total_Num_ACL_Packets + = 16; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Buffer_Size.HC_Total_Num_SCO_Packets + = 0; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadBufferSize */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadDataBlockSize() + + DESCRIPTION + Implements the actual HCI Read Data Block Size command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadDataBlockSize is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadDataBlockSize +( + ptBtampHandle btampHandle, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + /* Validate params */ + if ((btampHandle == NULL) || (NULL == pBapHCIEvent)) + { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.status + = WLANBAP_STATUS_SUCCESS; + /* Return the supported Block sizes */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.HC_Data_Block_Length + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.HC_Max_ACL_Data_Packet_Length + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Data_Block_Size.HC_Total_Num_Data_Blocks + = 16; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadDataBlockSize */ + + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSetConfig() + + DESCRIPTION + The function updates some configuration for BAP module in SME during SMEs + close -> open sequence. + + BAP applies the new configuration at the next transaction. + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + + IN + pConfig: a pointer to a caller allocated object of typedef struct WLANBAP_ConfigType. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pConfig or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPSetConfig +( + ptBtampHandle btampHandle, + WLANBAP_ConfigType *pConfig +) +{ + ptBtampContext btampContext; + /* Validate params */ + if ((NULL == btampHandle)|| (NULL == pConfig)) + { + return VOS_STATUS_E_FAULT; + } + btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + + btampContext->config.ucPreferredChannel = pConfig->ucPreferredChannel; + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPGetMask() + + DESCRIPTION + The function gets the updated event mask from BAP core. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + IN + pEvent_mask_page_2: a pointer to a caller allocated object of 8 bytes. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pEvent_mask_page_2 or btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPGetMask( ptBtampHandle btampHandle, + v_U8_t *pEvent_mask_page_2) +{ + ptBtampContext btampContext; + /* Validate params */ + if ((NULL == btampHandle)|| (NULL == pEvent_mask_page_2)) + { + return VOS_STATUS_E_FAULT; + } + btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + + vos_mem_copy( pEvent_mask_page_2, + btampContext->event_mask_page_2, + 8 ); + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPDisconnect() + + DESCRIPTION + The function to request to BAP core to disconnect currecnt AMP connection. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: btampHandle is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPDisconnect +( + ptBtampHandle btampHandle +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tWLAN_BAPEvent bapEvent; /* State machine event */ + v_U8_t status; /* return the BT-AMP status here */ + VOS_STATUS vosStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, + "btampHandle is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION; + bapEvent.params = NULL; + + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPSessionOn() + + DESCRIPTION + The function to check from BAP core if AMP connection is up right now. + + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_TRUE: AMP connection is on + VOS_FALSE: AMP connection is not on + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +v_BOOL_t WLAN_BAPSessionOn +( + ptBtampHandle btampHandle +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if (btampHandle == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampHandle is NULL in %s", __func__); + + //?? shall we say true or false + return VOS_FALSE; + } + + return btampContext->btamp_session_on; +} diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiLinkCntl.c b/drivers/staging/prima/CORE/BAP/src/bapApiLinkCntl.c new file mode 100644 index 000000000000..e8efab2f2724 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiLinkCntl.c @@ -0,0 +1,1941 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i L i n k C n t l . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Link Control functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/ampBlueZ_2/CORE/BAP/src/bapApiLinkCntl.c,v 1.1 2010/10/23 23:40:28 labuser Exp labuser $$DateTime$$Author: labuser $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +// Pick up the CSR callback definition +#include "csrApi.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" +#include "btampFsm.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext: is the pContext passed in with the roam request + pCsrRoamInfo: is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: for detail valid members. It may be NULL + roamId: is to identify the callback related roam request. 0 means unsolicited + roamStatus: is a flag indicating the status of the callback + roamResult: is the result + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +#if 0 +eCSR_ROAM_RESULT_WDS_STARTED +#define eWLAN_BAP_MAC_START_BSS_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ + +eCSR_ROAM_RESULT_FAILURE +eCSR_ROAM_RESULT_NOT_ASSOCIATED +#define eWLAN_BAP_MAC_START_FAILS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + +eCSR_ROAM_RESULT_WDS_ASSOCIATED +#define eWLAN_BAP_MAC_CONNECT_COMPLETED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATED */ + + +eCSR_ROAM_RESULT_FAILURE +eCSR_ROAM_RESULT_NOT_ASSOCIATED +#define eWLAN_BAP_MAC_CONNECT_FAILED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + + +eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND +#define eWLAN_BAP_MAC_CONNECT_INDICATION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND */ + + +eCSR_ROAM_RESULT_KEY_SET +#define eWLAN_BAP_MAC_KEY_SET_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_KEY_SET */ + + +eCSR_ROAM_RESULT_WDS_DISASSOC_IND +#define eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_DISASSOC_IND */ + + +eCSR_ROAM_RESULT_WDS_STOPPED +#define eWLAN_BAP_MAC_READY_FOR_CONNECTIONS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STOPPED */ + +#endif //0 + + +eHalStatus +WLANBAP_RoamCallback +( + void *pContext, + tCsrRoamInfo *pCsrRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + /* btampContext value */ + ptBtampContext btampContext = (ptBtampContext) pContext; + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U8_t status; /* return the BT-AMP status here */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on roamStatus = %d", __func__, roamStatus); + + switch (roamStatus) { + //JEZ081110: For testing purposes, with Infra STA as BT STA, this + //actually takes care of the "eCSR_ROAM_RESULT_WDS_STARTED" case, + //below, better than "eCSR_ROAM_RESULT_IBSS_STARTED". + //case eCSR_ROAM_ROAMING_START: + case eCSR_ROAM_ASSOCIATION_START: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_ROAMING_START", roamResult); + // This only gets called when CSR decides to roam on its own - due to lostlink. +#if 0 + if ((pCsrRoamInfo) && (pCsrRoamInfo->pConnectedProfile) && (pCsrRoamInfo->pConnectedProfile->pBssDesc)) + { + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pConnectedProfile->pBssDesc->bssId, + sizeof(tSirMacAddr)); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: willRoam returns\n", __func__); + } +#endif //0 + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_START_BSS_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + case eCSR_ROAM_SET_KEY_COMPLETE: + /* bapRoamCompleteCallback with eCSR_ROAM_SET_KEY_COMPLETE */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)", __func__, "eCSR_ROAM_SET_KEY_COMPLETE", roamStatus); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_KEY_SET_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + case eCSR_ROAM_DISASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_DISASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)", __func__, "eCSR_ROAM_DISASSOCIATED", roamStatus); + case eCSR_ROAM_LOSTLINK: + /* bapRoamCompleteCallback with eCSR_ROAM_LOSTLINK */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamStatus = %s (%d)", __func__, "eCSR_ROAM_LOSTLINK", roamStatus); + + if (roamResult != eCSR_ROAM_RESULT_NONE) { + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + } + + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, unsupported CSR roamStatus = %d", __func__, roamStatus); + + break; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, before switch on roamResult = %d", __func__, roamResult); + + switch (roamResult) { + //JEZ081110: Commented out for testing. Test relies upon IBSS. + case eCSR_ROAM_RESULT_IBSS_STARTED: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_STARTED", roamResult); + case eCSR_ROAM_RESULT_WDS_STARTED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_STARTED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_START_BSS_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + //JEZ081110: But I cannot rely upon IBSS for the initial testing. + case eCSR_ROAM_RESULT_FAILURE: + //case eCSR_ROAM_RESULT_NOT_ASSOCIATED: + //case eCSR_ROAM_RESULT_IBSS_START_FAILED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_FAILURE", roamResult); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + break; +#endif + case eCSR_ROAM_RESULT_WDS_START_FAILED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_START_FAILED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_START_FAILED", roamResult); + + /* Fill in the event structure */ + /* I don't think I should signal a eCSR_ROAM_RESULT_FAILURE + * as a eWLAN_BAP_MAC_START_FAILS + */ + bapEvent.event = eWLAN_BAP_MAC_START_FAILS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. This handles both Infra STA and IBSS STA. + case eCSR_ROAM_RESULT_IBSS_CONNECT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT", roamResult); + case eCSR_ROAM_RESULT_ASSOCIATED: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_ASSOCIATED", roamResult); + case eCSR_ROAM_RESULT_WDS_ASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_ASSOCIATED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_CONNECT_COMPLETED; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + //JEZ081110: But I cannot rely upon IBSS for the initial testing. + //case eCSR_ROAM_RESULT_FAILURE: + case eCSR_ROAM_RESULT_IBSS_START_FAILED: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_START_FAILED", roamResult); + case eCSR_ROAM_RESULT_NOT_ASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_NOT_ASSOCIATED", roamResult); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + break; +#endif + case eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_CONNECT_FAILED; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: I think I have to check for the bssType to + //differentiate between IBSS Start and IBSS Join success. + //case eCSR_ROAM_RESULT_IBSS_CONNECT: + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT", roamResult); + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + // No longer commented out. + case eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_CONNECT_INDICATION; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* If BAP doesn't like the incoming association, signal SME/CSR */ + if ( status != WLANBAP_STATUS_SUCCESS) + halStatus = eHAL_STATUS_FAILURE; + + break; + + //JEZ081110: Not supported in SME and CSR, yet. +#if 0 + case eCSR_ROAM_RESULT_KEY_SET: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_KEY_SET */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_KEY_SET", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_KEY_SET_SUCCESS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; +#endif //0 + + case eCSR_ROAM_RESULT_DISASSOC_IND: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_DISASSOC_IND", roamResult); + case eCSR_ROAM_RESULT_WDS_DISASSOCIATED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_DISASSOCIATED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_DISASSOCIATED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + //JEZ081110: Commented out for testing. Test relies upon IBSS. + case eCSR_ROAM_RESULT_IBSS_INACTIVE: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_IBSS_INACTIVE", roamResult); + case eCSR_ROAM_RESULT_WDS_STOPPED: + /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STOPPED */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, CSR roamResult = %s (%d)", __func__, "eCSR_ROAM_RESULT_WDS_STOPPED", roamResult); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pCsrRoamInfo; + bapEvent.u1 = roamStatus; + bapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, unsupported CSR roamResult = %d", __func__, roamResult); + + break; + } + +#if 0 + switch (roamResult) { + case eCSR_ROAM_RESULT_IBSS_CONNECT: + // we have an IBSS connection... + + // update our state + btampContext->mAssociatedStatus = WLANBAP_STATUS_SUCCESS; + btampContext->mAssociated = VOS_TRUE; + // update "assocBssid" with the BSSID of the IBSS + if (pCsrRoamInfo) + memcpy(btampContext->assocBssid, pCsrRoamInfo->peerMacOrBssidForIBSS, 6); + + // We must update the system role to match that of the + // lower layers in case the upper layers decided to try + // joining the network in infrastructure mode if the + // initial join in IBSS mode fails. Andreas Wolf + // (awolf@apple.com) explains the behavior as follows: + // "If the client attempts to join an open network and it fails + // on the first attempt, it reverts back to b-only mode. This + // workaround was specifically put in place to allow the client + // to associate to some third party b-only infrastructure APs. + // It did not take IBSS into account, it seems that the fallback + // always forces infrastructure." + + btampContext->systemRole = eSYSTEM_STA_IN_IBSS_ROLE; + + if (mLinkStatus == 0) + { + // enable the flow of data + DBGLOG("%s: marking link as up in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT"); + mLinkStatus = 1; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkUp); + outputQueue->setCapacity(TRANSMIT_QUEUE_SIZE); + outputQueue->start(); + // Let them know we are ready + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_ASSOC_DONE); + } + else + { + DBGLOG("%s: link is already up in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_CONNECT"); + } + break; + + case eCSR_ROAM_RESULT_IBSS_INACTIVE: + // we have no more IBSS peers, so disable the flow of data + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_INACTIVE"); + mLinkStatus = (tANI_U8) 0; + // JEZ070627: Revisit ? + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + outputQueue->stop(); + outputQueue->setCapacity(0); + + // update our state + btampContext->mAssociated = false; + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_IBSS_INACTIVE"); + } + + break; + + case eCSR_ROAM_RESULT_ASSOCIATED: + btampContext->mAssociatedStatus = APPLE80211_STATUS_SUCCESS; + btampContext->mAssociated = true; + + if ((pCsrRoamInfo) && (pCsrRoamInfo->pBssDesc)) { + ccpCsrToAppleScanResult(mPMacObject, pCsrRoamInfo->pBssDesc, &scanResult); + + /* Save away the IEs used by the AP */ + ccpCsrToAssocApiedata( mPMacObject, pCsrRoamInfo->pBssDesc, &(btampContext->apiedata)); + + if (BssidChanged((tCsrBssid*) btampContext->assocBssid, (ether_addr*) scanResult.asr_bssid)) { + memcpy(btampContext->assocBssid, scanResult.asr_bssid, 6); + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_BSSID_CHANGED ); + } + } + + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_ASSOC_DONE); + + if (mLinkStatus == 0) + { + mLinkStatus = (tANI_U8) 1; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkUp); + DBGLOG("%s: marking link as up in %s\n", __func__, "eCSR_ROAM_RESULT_ASSOCIATED"); + outputQueue->setCapacity(TRANSMIT_QUEUE_SIZE); + outputQueue->start(); + } + else + { + DBGLOG("%s: link is already up in %s\n", __func__, "eCSR_ROAM_RESULT_ASSOCIATED"); + } + break; + case eCSR_ROAM_RESULT_NOT_ASSOCIATED: + btampContext->mAssociatedStatus = APPLE80211_STATUS_UNAVAILABLE; + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_NOT_ASSOCIATED"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_NOT_ASSOCIATED"); + } + break; + + case eCSR_ROAM_RESULT_FAILURE: + btampContext->mAssociatedStatus = APPLE80211_STATUS_UNSPECIFIED_FAILURE; + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_FAILURE"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_FAILURE"); + } + break; + + case eCSR_ROAM_RESULT_DISASSOC_IND: + { + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_DISASSOC_IND"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_DISASSOC_IND"); + } + + //if (pCsrRoamInfo) // For now, leave this commented out. Until CSR changes integrated. + { + // Now set the reason and status codes. + // Actually, the "result code" field in the tSirSmeDisassocInd should be named reasonCode and NOT statusCode. + // "Reason Codes" are found in DisAssoc or DeAuth Ind. "Status Code" fields are found in Rsp Mgmt Frame. + // For now, we are going to have to (painfully) map the only "result code" type information we have + // available at ALL from LIM/CSR. And that is the statusCode field of type tSirResultCodes + // BTW, tSirResultCodes is the COMPLETELY WRONG TYPE for this "result code" field. It SHOULD be + // of type tSirMacReasonCodes. + // Right now, we don't even have that. So, I have to just make up some "reason code" that I will + // pretend I found in the incoming DisAssoc Indication. + //btampContext->statusCode = ((tpSirSmeDisassocInd) pCallbackInfo)->statusCode; // tSirResultCodes + //btampContext->reasonCode = ((tpSirSmeDisassocInd) pCallbackInfo)->statusCode; // tSirResultCodes + btampContext->reasonCode = (tANI_U16) eSIR_MAC_UNSPEC_FAILURE_REASON; //tANI_U16 // tSirMacReasonCodes + btampContext->deAuthReasonCode = 0; // tANI_U16 // eSIR_SME_DEAUTH_FROM_PEER + // Shouldn't the next line really use a tANI_U16? //0; // tANI_U16 // eSIR_SME_DISASSOC_FROM_PEER + btampContext->disassocReasonCode = btampContext->reasonCode; // tSirMacReasonCodes + // Let's remember the peer who just disassoc'd us + //memcpy(btampContext->peerMacAddr, pCsrRoamInfo->peerMacOrBssidForIBSS, 6); + } + } + break; + + case eCSR_ROAM_RESULT_DEAUTH_IND: + { + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_RESULT_DEAUTH_IND"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_RESULT_DEAUTH_IND"); + } + + //if (pCsrRoamInfo) // For now, leave this commented out. Until CSR changes integrated. + { + // Now set the reason and status codes. + // Actually, the "result code" field in the tSirSmeDeauthInd should be named reasonCode and NOT statusCode. + // "Reason Codes" are found in DisAssoc or DeAuth Ind. "Status Code" fields are found in Rsp Mgmt Frame. + // For now, we are going to have to (painfully) map the only "result code" type information we have + // available at ALL from LIM/CSR. And that is the statusCode field of type tSirResultCodes + // BTW, tSirResultCodes is the COMPLETELY WRONG TYPE for this "result code" field. It SHOULD be + // of type tSirMacReasonCodes. + // Right now, we don't even have that. So, I have to just make up some "reason code" that I will + // pretend I found in the incoming DeAuth Indication. + //btampContext->statusCode = ((tpSirSmeDeauthInd) pCallbackInfo)->statusCode; // tSirResultCodes + //btampContext->reasonCode = ((tpSirSmeDeauthInd) pCallbackInfo)->statusCode; // tSirResultCodes + btampContext->reasonCode = (tANI_U16) eSIR_MAC_UNSPEC_FAILURE_REASON; //tANI_U16 // tSirMacReasonCodes + btampContext->disassocReasonCode = 0; // tANI_U16 // eSIR_SME_DISASSOC_FROM_PEER + // Shouldn't the next line really use a tANI_U16? //0; // tANI_U16 // eSIR_SME_DEAUTH_FROM_PEER + btampContext->deAuthReasonCode = btampContext->reasonCode; // tSirMacReasonCodes + // Let's remember the peer who just de-auth'd us + //memcpy(btampContext->peerMacAddr, ((tpSirSmeDeauthInd) pCallbackInfo)->peerMacAddr, 6); + } + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST: + + //if (eCSR_ROAM_MIC_ERROR_IND == roamStatus) // Make sure + { + if (btampContext->mTKIPCounterMeasures) + { + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_MIC_ERROR_UCAST); + DBGLOG("%s: TKIP Countermeasures in effect in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST"); + } + else + { + DBGLOG("%s: TKIP Countermeasures disabled in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST"); + } + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_GROUP: + + //if (eCSR_ROAM_MIC_ERROR_IND == roamStatus) // Make sure + { + if (btampContext->mTKIPCounterMeasures) + { + ((IO80211Interface*) mNetworkIF)->postMessage(APPLE80211_M_MIC_ERROR_MCAST); + DBGLOG("%s: TKIP Countermeasures in effect in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_GROUP"); + } + else + { + DBGLOG("%s: TKIP Countermeasures disabled in %s\n", __func__, "eCSR_ROAM_RESULT_MIC_ERROR_GROUP"); + } + } + break; + + default: + break; + } + switch (roamStatus) { + case eCSR_ROAM_ROAMING_START: + DBGLOG("%s: In %s\n", __func__, "eCSR_ROAM_ROAMING_START"); + // This only gets called when CSR decides to roam on its own - due to lostlink. + // Apple still needs to be told. + if ((pCsrRoamInfo) && (pCsrRoamInfo->pConnectedProfile) && (pCsrRoamInfo->pConnectedProfile->pBssDesc)) + { + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pConnectedProfile->pBssDesc->bssId, + sizeof(tSirMacAddr)); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + DBGLOG("%s: willRoam returns\n", __func__); + } + break; + + case eCSR_ROAM_SHOULD_ROAM: + if ((pCsrRoamInfo) && (pCsrRoamInfo->pBssDesc)) { + // pCallbackInfo points to the BSS desc. Convert to Apple Scan Result. + halStatus = ccpCsrToAppleScanResult( + mPMacObject, + pCsrRoamInfo->pBssDesc, + &scanResult); + if ( halStatus != 0 ) + return eHAL_STATUS_FAILURE; + roamAccepted = apple80211Interface->shouldRoam(&scanResult); // Return result is crucial + if (roamAccepted == true) { + // If the roam is acceptable, return SUCCESS + DBGLOG("%s: shouldRoam returns \"acceptable\"\n", __func__); +//#if 0 + // Actually, before returning, immediately signal willRoam + // This is a workaround for a CSR bug. Eventually, when + // eCSR_ROAM_ASSOCIATION_START gets called WITH callback param p1 + // pointing to a tBssDescription, this work-around can be removed. + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pBssDesc->bssId, sizeof(tSirMacAddr)); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + DBGLOG("%s: willRoam (called out of order) returns\n", __func__); + DBGLOG(" with BSSID = " MAC_ADDR_STRING(bssid.ether_addr_octet)); +//#endif + return eHAL_STATUS_SUCCESS; + } else { + // If the roam is NOT acceptable, return FAILURE + DBGLOG("%s: shouldRoam returns \"NOT acceptable\"\n", __func__); + return eHAL_STATUS_FAILURE; + } + } + break; + + case eCSR_ROAM_DISASSOCIATED: + //if (eCSR_ROAM_RESULT_FORCED == roamResult || eCSR_ROAM_RESULT_MIC_ERROR == roamResult) + { + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_DISASSOCIATED"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_DISASSOCIATED"); + } + } + break; + + case eCSR_ROAM_LOSTLINK: + btampContext->mAssociatedStatus = APPLE80211_STATUS_UNSPECIFIED_FAILURE; + btampContext->mAssociated = false; + + if (mLinkStatus != 0) + { + DBGLOG("%s: marking link as down in %s\n", __func__, "eCSR_ROAM_LOSTLINK"); + mLinkStatus = (tANI_U8) 0; + ((IO80211Interface*) mNetworkIF)->setLinkState(kIO80211NetworkLinkDown); + } + else + { + DBGLOG("%s: link already down in %s\n", __func__, "eCSR_ROAM_LOSTLINK"); + } + break; + + case eCSR_ROAM_ASSOCIATION_START: + DBGLOG("%s: In %s\n", __func__, "eCSR_ROAM_ASSOCIATION_START"); +#if 0 + // This is the right place to call willRoam - for an "initial" association. + // But, unfortunately, when eCSR_ROAM_ASSOCIATION_START gets called, + // it doesn't have a pointer to the tBssDescription in the roaming callback + // routines parameter p1 (pCallbackInfo in SetWextState). So, don't use this code, yet. + if ((pCsrRoamInfo) && (pCsrRoamInfo->pBssDesc) { + memcpy(bssid.ether_addr_octet, pCsrRoamInfo->pBssDesc->bssId, 6); + apple80211Interface->willRoam(&bssid); // Return result isn't significant + DBGLOG("%s: willRoam returns\n", __func__); + DBGLOG(" with BSSID = " MAC_ADDR_STRING(bssid.ether_addr_octet)); + } +#endif //0 + break; + + case eCSR_ROAM_ASSOCIATION_COMPLETION: + DBGLOG("%s: In %s\n", __func__, "eCSR_ROAM_ASSOCIATION_COMPLETION"); + break; + + case eCSR_ROAM_MIC_ERROR_IND: // Handled in eCSR_ROAM_RESULT_MIC_ERROR_UNICAST and GROUP, above + case eCSR_ROAM_CANCELLED: + case eCSR_ROAM_ROAMING_COMPLETION: + case eCSR_ROAM_SCAN_FOUND_NEW_BSS: + default: + break; + } +#endif //0 + + return halStatus; +} + +/*---------------------------------------------------------------------------- + Host Controller Interface Procedural API + ---------------------------------------------------------------------------*/ + +/** BT v3.0 Link Control commands */ + +/*---------------------------------------------------------------------------- + Each of the next eight command result in asynchronous events (e.g., + HCI_PHYSICAL_LINK_COMPLETE_EVENT, HCI_LOGICAL_LINK_COMPLETE_EVENT, etc...) + These are signalled thru the event callback. (I.E., (*tpWLAN_BAPEventCB).) + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + WLANBAP_GetNewHndl has to be called before every call to + WLAN_BAPPhysicalLinkCreate. Since the context is per + physical link. + pBapHCIPhysLinkCreate: pointer to the "HCI Create Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Physical_Link_Cmd *pBapHCIPhysLinkCreate, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + + /* Validate params */ + if ((pBapHCIPhysLinkCreate == NULL) || (NULL == btampContext)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: btampHandle value: %p, pBapHCIPhysLinkCreate is %p", + __func__, btampHandle, pBapHCIPhysLinkCreate); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + if(DISCONNECTED != instanceVar->stateVar) + { + /* Create/Accept Phy link request in invalid state */ + status = WLANBAP_ERROR_MAX_NUM_CNCTS; + + } + else + { + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_PHYSICAL_LINK_CREATE; + bapEvent.params = pBapHCIPhysLinkCreate; + //bapEvent.callback = pBapHCIPhysLinkCreateCB; + + /* Allocate a new state machine instance */ + /* There will only ever be one of these (NB: Don't assume this.) */ + /* So for now this returns a pointer to a static structure */ + /* (With all state set to initial values) */ + vosStatus = WLANBAP_CreateNewPhyLinkCtx ( + btampHandle, + pBapHCIPhysLinkCreate->phy_link_handle, /* I get phy_link_handle from the Command */ + pHddHdl, /* BSL passes in its specific context */ + &btampContext, /* Handle to return per assoc btampContext value in */ + BT_INITIATOR); /* BT_INITIATOR */ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + } + + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = status; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD; + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPPhysicalLinkCreate */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkAccept: pointer to the "HCI Accept Physical Link" Structure. + pHddHdl: The context passed in by the caller. (e.g., BSL specific context) + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Physical_Link_Cmd *pBapHCIPhysLinkAccept, + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + /* And I get phy_link_handle from the Command */ + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + BTAMPFSM_INSTANCEDATA_T *instanceVar; + + /* Validate params */ + if ((pBapHCIPhysLinkAccept == NULL) || (NULL == btampContext)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: btampHandle value: %p, pBapHCIPhysLinkAccept is %p", + __func__, btampHandle, pBapHCIPhysLinkAccept); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + instanceVar = &(btampContext->bapPhysLinkMachine); + if(DISCONNECTED != instanceVar->stateVar) + { + /* Create/Accept Phy link request in invalid state */ + status = WLANBAP_ERROR_MAX_NUM_CNCTS; + + } + else + { + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_PHYSICAL_LINK_ACCEPT; + bapEvent.params = pBapHCIPhysLinkAccept; + //bapEvent.callback = pBapHCIPhysLinkAcceptCB; + + /* Allocate a new state machine instance */ + /* There will only ever be one of these (NB: Don't assume this.) */ + /* So for now this returns a pointer to a static structure */ + /* (With all state set to initial values) */ + vosStatus = WLANBAP_CreateNewPhyLinkCtx ( + btampHandle, + pBapHCIPhysLinkAccept->phy_link_handle, /* I get phy_link_handle from the Command */ + pHddHdl, /* BSL passes in its specific context */ + &btampContext, /* Handle to return per assoc btampContext value in */ + BT_RESPONDER); /* BT_RESPONDER */ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + } + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = status; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD; + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPPhysicalLinkAccept */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPPhysicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Physical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIPhysLinkDisconnect: pointer to the "HCI Disconnect Physical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIPhysLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPPhysicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pBapHCIPhysLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + + /* Validate params */ + if (pBapHCIPhysLinkDisconnect == NULL) { + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate the Physical link handle */ + if (pBapHCIPhysLinkDisconnect->phy_link_handle != btampContext->phy_link_handle) + { + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD; + return VOS_STATUS_SUCCESS; + } + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT; + bapEvent.params = pBapHCIPhysLinkDisconnect; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = pBapHCIPhysLinkDisconnect; + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + + /* Format the command status event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + pBapHCIEvent->u.btampCommandStatusEvent.present = 1; + pBapHCIEvent->u.btampCommandStatusEvent.status = status; + pBapHCIEvent->u.btampCommandStatusEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD; + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPPhysicalLinkDisconnect */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCreate() + + DESCRIPTION + Implements the actual HCI Create Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCreate: pointer to the "HCI Create Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCreate is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCreate +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Create_Logical_Link_Cmd *pBapHCILogLinkCreate, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U16_t log_link_index = 0; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + VOS_STATUS retval; + v_U16_t index_for_logLinkCtx = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Validate params */ + if (pBapHCILogLinkCreate == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate the BAP state to accept the logical link request + Logical Link create/accept requests are allowed only in + CONNECTED state */ + /* Form and immediately return the command status event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD; + + retval = VOS_STATUS_E_FAILURE; + if(DISCONNECTED == instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + + } + else if (CONNECTED != instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_CMND_DISALLOWED; + } + else if (pBapHCILogLinkCreate->phy_link_handle != btampContext->phy_link_handle) + { + /* Invalid Physical link handle */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkInProgress; + + if( TRUE == btampContext->btamp_logical_link_cancel_pending ) + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_NO_CNCT; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + btampContext->btamp_logical_link_cancel_pending = FALSE; + } + else + { + /* If btamp_async_logical_link_create is set, we will seralize the req + on MC thread & handle it there after; If the above flag is not set + respond to HCI the sync way as before */ + if(FALSE == btampContext->btamp_async_logical_link_create) + { + /* Allocate a logical link index for these flow specs */ + vosStatus = WLANBAP_CreateNewLogLinkCtx( + btampContext, /* per assoc btampContext value */ + pBapHCILogLinkCreate->phy_link_handle, /* I get phy_link_handle from the Command */ + pBapHCILogLinkCreate->tx_flow_spec, /* I get tx_flow_spec from the Command */ + pBapHCILogLinkCreate->rx_flow_spec, /* I get rx_flow_spec from the Command */ + &log_link_index /* Return the logical link index here */ + ); + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Invalid flow spec format */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + else + { + retval = VOS_STATUS_SUCCESS; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = WLANBAP_STATUS_SUCCESS; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkOpen; + } + } + else + { + btampContext->btamp_logical_link_req_info.phyLinkHandle = + pBapHCILogLinkCreate->phy_link_handle; + vos_mem_copy(btampContext->btamp_logical_link_req_info.txFlowSpec, + pBapHCILogLinkCreate->tx_flow_spec, 18); + vos_mem_copy(btampContext->btamp_logical_link_req_info.rxFlowSpec, + pBapHCILogLinkCreate->rx_flow_spec, 18); + btampContext->btamp_async_logical_link_create = FALSE; + vosStatus = btampEstablishLogLink(btampContext); + if(VOS_STATUS_SUCCESS == vosStatus) + { + retval = VOS_STATUS_E_BUSY;//this will make sure event complete is not sent to HCI + } + else + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + + } + } + } + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + index_for_logLinkCtx = log_link_index >> 8; + /* Format the Logical Link Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.present = 1; + + /* Return the logical link index here */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.log_link_handle + = log_link_index; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.phy_link_handle + = pBapHCILogLinkCreate->phy_link_handle; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.flow_spec_id + = btampContext->btampLogLinkCtx[index_for_logLinkCtx].btampFlowSpec.flow_spec_id; + + /* ... */ + + return retval; +} /* WLAN_BAPLogicalLinkCreate */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkAccept() + + DESCRIPTION + Implements the actual HCI Accept Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkAccept: pointer to the "HCI Accept Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkAccept is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkAccept +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Accept_Logical_Link_Cmd *pBapHCILogLinkAccept, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U16_t log_link_index = 0; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &(btampContext->bapPhysLinkMachine); + VOS_STATUS retval; + v_U16_t index_for_logLinkCtx; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Validate params */ + if (pBapHCILogLinkAccept == NULL) { + return VOS_STATUS_E_FAULT; + } + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate the BAP state to accept the logical link request + Logical Link create/accept requests are allowed only in + CONNECTED state */ + /* Form and immediately return the command status event... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD; + + retval = VOS_STATUS_E_FAILURE; + if(DISCONNECTED == instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + + } + else if (CONNECTED != instanceVar->stateVar) + { + /* Create Logical link request in invalid state */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_CMND_DISALLOWED; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_CMND_DISALLOWED; + } + else if (pBapHCILogLinkAccept->phy_link_handle != btampContext->phy_link_handle) + { + /* Invalid Physical link handle */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkInProgress; + if( TRUE == btampContext->btamp_logical_link_cancel_pending ) + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_NO_CNCT; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + btampContext->btamp_logical_link_cancel_pending = FALSE; + } + else + { + /* If btamp_async_logical_link_create is set, we will seralize the req + on MC thread & handle it there after; If the above flag is not set + respond to HCI the sync way as before */ + if(FALSE == btampContext->btamp_async_logical_link_create) + { + /* Allocate a logical link index for these flow specs */ + vosStatus = WLANBAP_CreateNewLogLinkCtx( + btampContext, /* per assoc btampContext value */ + pBapHCILogLinkAccept->phy_link_handle, /* I get phy_link_handle from the Command */ + pBapHCILogLinkAccept->tx_flow_spec, /* I get tx_flow_spec from the Command */ + pBapHCILogLinkAccept->rx_flow_spec, /* I get rx_flow_spec from the Command */ + &log_link_index /* Return the logical link index here */ + ); + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Invalid flow spec format */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + else + { + retval = VOS_STATUS_SUCCESS; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = WLANBAP_STATUS_SUCCESS; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkOpen; + } + } + else + { + btampContext->btamp_logical_link_req_info.phyLinkHandle = + pBapHCILogLinkAccept->phy_link_handle; + vos_mem_copy(btampContext->btamp_logical_link_req_info.txFlowSpec, + pBapHCILogLinkAccept->tx_flow_spec, 18); + vos_mem_copy(btampContext->btamp_logical_link_req_info.rxFlowSpec, + pBapHCILogLinkAccept->rx_flow_spec, 18); + btampContext->btamp_async_logical_link_create = FALSE; + vosStatus = btampEstablishLogLink(btampContext); + if(VOS_STATUS_SUCCESS == vosStatus) + { + retval = VOS_STATUS_E_BUSY;//this will make sure event complete is not sent to HCI + } + else + { + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + + } + } + } + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + index_for_logLinkCtx = log_link_index >> 8; + + /* Format the Logical Link Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.present = 1; + /* Return the logical link index here */ + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.log_link_handle + = log_link_index; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.phy_link_handle + = pBapHCILogLinkAccept->phy_link_handle; + pBapHCIEvent->u.btampLogicalLinkCompleteEvent.flow_spec_id + = btampContext->btampLogLinkCtx[index_for_logLinkCtx].btampFlowSpec.flow_spec_id; + + /* ... */ + + return retval; +} /* WLAN_BAPLogicalLinkAccept */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkDisconnect() + + DESCRIPTION + Implements the actual HCI Disconnect Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkDisconnect: pointer to the "HCI Disconnect Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkDisconnect is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkDisconnect +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pBapHCILogLinkDisconnect, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tpBtampLogLinkCtx pLogLinkContext; + VOS_STATUS retval = VOS_STATUS_SUCCESS; + v_U8_t log_link_index; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pBapHCILogLinkDisconnect ) || + ( NULL == btampContext)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Critical error: Invalid input parameter on %s", + __func__); + return VOS_STATUS_E_FAULT; + } + + /* Derive logical link index from handle */ + log_link_index = ((pBapHCILogLinkDisconnect->log_link_handle) >> 8); + + if( log_link_index >= WLANBAP_MAX_LOG_LINKS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Critical error: Invalid input parameter on %s", + __func__); + /* Fill in the event code to propagate the event notification to BRM + BRM generates the Command status Event based on this.*/ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.present = 1; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + return VOS_STATUS_E_INVAL; + + } + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: btampContext value = %p in %s:%d", btampContext, __func__, __LINE__ ); +#endif //BAP_DEBUG + + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD; + + /*------------------------------------------------------------------------ + FIXME: Validate the Logical Link handle, Generation and freeing... + Here the Logical link is not validated and assumed that it is correct to. + get the Logical link context. . + ------------------------------------------------------------------------*/ + pLogLinkContext = + &(btampContext->btampLogLinkCtx[log_link_index]); + + // Validate whether the context is active. + if ((VOS_FALSE == pLogLinkContext->present) || + (pBapHCILogLinkDisconnect->log_link_handle != pLogLinkContext->log_link_handle)) + { + /* If status is failed, the platform specific layer generates the + command status event with proper status */ + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + retval = VOS_STATUS_E_FAILURE; +#ifdef BAP_DEBUG + /* Log the error. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s:%d Invalid Logical Link handle(should be) = %d(%d)", __func__, __LINE__, + pBapHCILogLinkDisconnect->log_link_handle, pLogLinkContext->log_link_handle); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " Logical Link index = %d", log_link_index); +#endif //BAP_DEBUG + } + else + { + /* Form and return the command status event... */ + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.status + = WLANBAP_STATUS_SUCCESS; + + + pLogLinkContext->present = VOS_FALSE; + pLogLinkContext->uTxPktCompleted = 0; + pLogLinkContext->log_link_handle = 0; + /* Decrement the total logical link count */ + btampContext->total_log_link_index--; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + + /* Notify the Command status Event */ + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + /* Format the Logical Link Complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.present = 1; + /* Return the logical link index here */ + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.log_link_handle + = pBapHCILogLinkDisconnect->log_link_handle; + pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent.reason + = WLANBAP_ERROR_TERM_BY_LOCAL_HOST; + + return retval; +} /* WLAN_BAPLogicalLinkDisconnect */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPLogicalLinkCancel() + + DESCRIPTION + Implements the actual HCI Cancel Logical Link command + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCILogLinkCancel: pointer to the "HCI Cancel Logical Link" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + (BTW, the required "HCI Logical Link Complete Event" + will be generated by the BAP state machine and sent up + via the (*tpWLAN_BAPEventCB).) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCILogLinkCancel is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPLogicalLinkCancel +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Logical_Link_Cancel_Cmd *pBapHCILogLinkCancel, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext; + BTAMPFSM_INSTANCEDATA_T *instanceVar; + /* Validate params */ + if ((btampHandle == NULL) || (pBapHCILogLinkCancel == NULL) || + (pBapHCIEvent == NULL)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Null Parameters Not allowed", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + instanceVar = &(btampContext->bapPhysLinkMachine); + + /* Form and immediately return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode = + BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + + if (pBapHCILogLinkCancel->phy_link_handle != btampContext->phy_link_handle) + { + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_NO_CNCT; + } + else + { + /* As the logical link create is returned immediately, the logical link is + created and so cancel can not return success. + And it returns WLANBAP_ERROR_NO_CNCT if not connected or + WLANBAP_ERROR_MAX_NUM_ACL_CNCTS if connected */ + if(WLAN_BAPLogLinkClosed == btampContext->btamp_logical_link_state ) + { + /* Cancel Logical link request in invalid state */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_NO_CNCT; + } + else if(WLAN_BAPLogLinkOpen == btampContext->btamp_logical_link_state ) + { + /* Cancel Logical link request in conected state */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_MAX_NUM_ACL_CNCTS; + } + else if(WLAN_BAPLogLinkInProgress == btampContext->btamp_logical_link_state ) + { + /* Cancel Logical link request in progress state, need to fail logical link + creation as well */ + btampContext->btamp_logical_link_cancel_pending = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_STATUS_SUCCESS; + } + else + { + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.status = + WLANBAP_ERROR_NO_CNCT; + } + } + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.phy_link_handle = + pBapHCILogLinkCancel->phy_link_handle; + /* Since the status is not success, the Tx flow spec Id is not meaningful and + filling with 0 */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Logical_Link_Cancel.tx_flow_spec_id = + pBapHCILogLinkCancel->tx_flow_spec_id; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPLogicalLinkCancel */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPFlowSpecModify() + + DESCRIPTION + Implements the actual HCI Modify Logical Link command + Produces an asynchronous flow spec modify complete event. Through the + event callback. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIFlowSpecModify: pointer to the "HCI Flow Spec Modify" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command status event. + (The caller of this routine is responsible for sending + the Command Status event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIFlowSpecModify is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPFlowSpecModify +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Flow_Spec_Modify_Cmd *pBapHCIFlowSpecModify, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + v_U16_t index_for_logLinkHandle = 0; + ptBtampContext btampContext; + tpBtampLogLinkCtx pLogLinkContext; + v_U32_t retval; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Validate params */ + if ((btampHandle == NULL) || (pBapHCIFlowSpecModify == NULL) || + (pBapHCIEvent == NULL)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Null Parameters Not allowed", __func__); + return VOS_STATUS_E_FAULT; + } + + btampContext = (ptBtampContext) btampHandle; + + index_for_logLinkHandle = pBapHCIFlowSpecModify->log_link_handle >> 8; /* Return the logical link index here */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " %s:index_for_logLinkHandle=%d", __func__,index_for_logLinkHandle); + + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + bapHCIEvent.u.btampCommandStatusEvent.present = 1; + bapHCIEvent.u.btampCommandStatusEvent.num_hci_command_packets = 1; + bapHCIEvent.u.btampCommandStatusEvent.command_opcode + = BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD; + + /*------------------------------------------------------------------------ + Evaluate the Tx and Rx Flow specification for this logical link. + ------------------------------------------------------------------------*/ + // Currently we only support flow specs with service types of BE (0x01) + + /*------------------------------------------------------------------------ + Now configure the Logical Link context. + ------------------------------------------------------------------------*/ + pLogLinkContext = &(btampContext->btampLogLinkCtx[index_for_logLinkHandle]); + + /* Extract Tx flow spec into the context structure */ + retval = btampUnpackTlvFlow_Spec((void *)btampContext, pBapHCIFlowSpecModify->tx_flow_spec, + WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN, + &pLogLinkContext->btampFlowSpec); + if (retval != BTAMP_PARSE_SUCCESS) + { + /* Flow spec parsing failed, return failure */ + vosStatus = VOS_STATUS_E_FAILURE; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.status = + WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.status + = WLANBAP_STATUS_SUCCESS; + + } + /* Notify the Command status Event */ + vosStatus = + (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + /* Form and immediately return the command status event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.present = 1; + pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent.log_link_handle = + pBapHCIFlowSpecModify->log_link_handle; + + return vosStatus; +} /* WLAN_BAPFlowSpecModify */ + + +void WLAN_BAPEstablishLogicalLink(ptBtampContext btampContext) +{ + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U16_t log_link_index = 0; + v_U16_t index_for_logLinkCtx = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (btampContext == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Null Parameters Not allowed", __func__); + return; + } + + if( TRUE == btampContext->btamp_logical_link_cancel_pending ) + { + bapHCIEvent.u.btampCommandStatusEvent.status = WLANBAP_ERROR_NO_CNCT; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + btampContext->btamp_logical_link_cancel_pending = FALSE; + } + else + { + /* Allocate a logical link index for these flow specs */ + vosStatus = WLANBAP_CreateNewLogLinkCtx( + btampContext, /* per assoc btampContext value */ + btampContext->btamp_logical_link_req_info.phyLinkHandle, /* I get phy_link_handle from the Command */ + btampContext->btamp_logical_link_req_info.txFlowSpec, /* I get tx_flow_spec from the Command */ + btampContext->btamp_logical_link_req_info.rxFlowSpec, /* I get rx_flow_spec from the Command */ + &log_link_index /* Return the logical link index here */ + ); + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Invalid flow spec format */ + bapHCIEvent.u.btampLogicalLinkCompleteEvent.status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkClosed; + } + else + { + bapHCIEvent.u.btampLogicalLinkCompleteEvent.status = WLANBAP_STATUS_SUCCESS; + btampContext->btamp_logical_link_state = WLAN_BAPLogLinkOpen; + } + } + + index_for_logLinkCtx = log_link_index >> 8; + /* Format the Logical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampLogicalLinkCompleteEvent.present = 1; + + /* Return the logical link index here */ + bapHCIEvent.u.btampLogicalLinkCompleteEvent.log_link_handle + = log_link_index; + bapHCIEvent.u.btampLogicalLinkCompleteEvent.phy_link_handle + = btampContext->btamp_logical_link_req_info.phyLinkHandle; + bapHCIEvent.u.btampLogicalLinkCompleteEvent.flow_spec_id + = btampContext->btampLogLinkCtx[index_for_logLinkCtx].btampFlowSpec.flow_spec_id; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers to the BSL per connection context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + return; +} + + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiLinkSupervision.c b/drivers/staging/prima/CORE/BAP/src/bapApiLinkSupervision.c new file mode 100644 index 000000000000..0dcd4c29a65e --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiLinkSupervision.c @@ -0,0 +1,636 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i LinkSupervision . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + "platform independent" Data path functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-03-25 arulv Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" +//I need the TL types and API +#include "wlan_qct_tl.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" +#include "bapApiTimer.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +#if 1 +//*BT-AMP packet LLC OUI value*/ +static const v_U8_t WLANBAP_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +/*LLC header value*/ +static v_U8_t WLANBAP_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; +#endif + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_AcquireLSPacket( ptBtampContext pBtampCtx, vos_pkt_t **ppPacket, v_U16_t size, tANI_BOOLEAN isLsReq ) +{ + VOS_STATUS vosStatus; + vos_pkt_t *pPacket; + WLANBAP_8023HeaderType w8023Header; + v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; + v_U16_t headerLength; /* The 802.3 frame length*/ + v_U16_t protoType; + v_U8_t *pData = NULL; + + + if(isLsReq) + { + protoType = WLANTL_BT_AMP_TYPE_LS_REQ; + } + else + { + protoType = WLANTL_BT_AMP_TYPE_LS_REP; + } + + //If success, vosTxLsPacket is the packet and pData points to the head. + vosStatus = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT,size, 1, + VOS_TRUE, NULL, NULL ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + vosStatus = vos_pkt_reserve_head( pPacket, (v_VOID_t *)&pData, size ); + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: failed to reserve size = %d\n",__func__, size ); + vos_pkt_return_packet( pPacket ); + } + } + + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_LinkSupervisionTimerHandler failed to get vos_pkt\n" ); + return vosStatus; + } + + // Form the 802.3 header + vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); + + headerLength = WLANBAP_LLC_HEADER_LEN; + /* Now the 802.3 length field is big-endian?! */ + w8023Header.usLenType = vos_cpu_to_be16(headerLength); + + /* Now adjust the protocol type bytes*/ + protoType = vos_cpu_to_be16( protoType); + /* Now form the LLC header */ + vos_mem_copy(aucLLCHeader, + WLANBAP_LLC_HEADER, + sizeof(WLANBAP_LLC_HEADER)); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], + WLANBAP_BT_AMP_OUI, + WLANBAP_LLC_OUI_SIZE); + vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], + &protoType, //WLANBAP_BT_AMP_TYPE_LS_REQ + WLANBAP_LLC_PROTO_TYPE_SIZE); + + /* Push on the LLC header */ + vos_pkt_push_head(pPacket, + aucLLCHeader, + WLANBAP_LLC_HEADER_LEN); + + /* Push on the 802.3 header */ + vos_pkt_push_head(pPacket, &w8023Header, sizeof(w8023Header)); + *ppPacket = pPacket; + return vosStatus; +} + + + +/*=========================================================================== + + FUNCTION WLANBAP_InitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be initialized when connected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +#define TX_LS_DATALEN 32 + +VOS_STATUS +WLANBAP_InitLinkSupervision +( + ptBtampHandle btampHandle +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + vos_pkt_t *pLSReqPacket; + vos_pkt_t *pLSRepPacket; + v_U16_t lsPktln; + + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + +#if 0 + /* Initialize Link supervision data structure */ + vos_mem_set(pLsInfo, sizeof(tBtampLS),0); + + /* Allocate memory for Static Tx Data */ + pLsInfo->pTxPktData = vos_mem_malloc(sizeof(tBtampLsPktData)+TX_LS_DATALEN); + + /* Initialize Static data for LS pkt Tx */ + pLsInfo->pTxPktData->BufLen = TX_LS_DATALEN; + vos_mem_copy (&pLsInfo->pTxPktData->pBuf, LsTxData, pLsInfo->pTxPktData->BufLen); +#endif + pBtampCtx->lsReqPktPending = VOS_FALSE; + pBtampCtx->retries = 0; + + vosStatus = WLANBAP_AcquireLSPacket( pBtampCtx, &pLSReqPacket,32, TRUE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + pBtampCtx->lsReqPacket = pLSReqPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + pBtampCtx->lsReqPacket = NULL; + return vosStatus; + } + + vosStatus = WLANBAP_AcquireLSPacket( pBtampCtx, &pLSRepPacket,32,FALSE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + pBtampCtx->lsRepPacket = pLSRepPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + pBtampCtx->lsRepPacket = NULL; + return vosStatus; + } + + vosStatus = vos_pkt_get_packet_length(pBtampCtx->lsRepPacket,&lsPktln); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:vos_pkt_get_length error",__func__); + return VOS_STATUS_E_FAULT; + } + pBtampCtx->lsPktln = lsPktln; + + /* Start Link Supervision Timer if not configured for infinite */ + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:No LS configured for infinite",__func__); + } + + return vosStatus; +} + +/*=========================================================================== + + FUNCTION WLANBAP_DeInitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be stopped after disconnected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeInitLinkSupervision +( + ptBtampHandle btampHandle +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In: %s", __func__); + + vosStatus = WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + + + /*Free the vos packet*/ + if ( pBtampCtx->lsRepPacket ) + { + vosStatus = vos_pkt_return_packet(pBtampCtx->lsRepPacket); + pBtampCtx->lsRepPacket = NULL; + } + + if ( pBtampCtx->lsReqPacket ) + { + vosStatus = vos_pkt_return_packet(pBtampCtx->lsReqPacket); + pBtampCtx->lsReqPacket = NULL; + } + + + return vosStatus; +} + +/*=========================================================================== + + FUNCTION WLANBAP_RxProcLsPkt + + DESCRIPTION + + This API will be called when Link Supervision frames are received at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RxProcLsPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + v_U16_t RxProtoType, /* Protocol Type from the frame received */ + vos_pkt_t *vosRxLsBuff +) +{ + VOS_STATUS vosStatus; + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + WLANBAP_8023HeaderType w8023Header; + v_SIZE_t HeaderLen = sizeof(w8023Header); + + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In %s Received RxProtoType=%x", __func__,RxProtoType); + + vos_pkt_extract_data(vosRxLsBuff,0,(v_VOID_t*)&w8023Header,&HeaderLen); + if ( !(vos_mem_compare( w8023Header.vDA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE) + && vos_mem_compare( w8023Header.vSA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE))) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "MAC address mismatch in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Free the vos packet*/ + vosStatus = vos_pkt_return_packet( vosRxLsBuff ); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Failed to free VOS packet in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + + /* Reset Link Supervision timer */ + if (RxProtoType == WLANTL_BT_AMP_TYPE_LS_REP) + { + pBtampCtx->lsReqPktPending = FALSE; + pBtampCtx->retries = 0; + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + /* Restart the LS timer */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + } + else if(RxProtoType == WLANTL_BT_AMP_TYPE_LS_REQ) + { + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + /* Restart the LS timer */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + pBtampCtx->pPacket = pBtampCtx->lsRepPacket; + // Handle LS rep frame + vosStatus = WLANBAP_TxLinkSupervision( btampHandle, phy_link_handle, pBtampCtx->pPacket, WLANTL_BT_AMP_TYPE_LS_REP); + } + + return vosStatus; + +} + +/* Tx callback function for LS packet */ +static VOS_STATUS WLANBAP_TxLinkSupervisionCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pPacket, + VOS_STATUS retStatus +) +{ + VOS_STATUS vosStatus; + ptBtampContext bapContext; /* Holds the btampContext value returned */ + vos_pkt_t *pLSPacket; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "TxCompCB reached for LS Pkt"); + + /* Get the BT AMP context from the global */ + bapContext = gpBtampCtx; + + if (!VOS_IS_STATUS_SUCCESS (retStatus)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "TxCompCB:Transmit status Failure"); + } + + if ( pPacket == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_TxCompCB bad input\n" ); + return VOS_STATUS_E_FAILURE; + } + + + /* Return the packet & reallocate */ + + if( pPacket == bapContext->lsReqPacket ) + { + vosStatus = WLANBAP_AcquireLSPacket( bapContext, &pLSPacket,32, TRUE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + bapContext->lsReqPacket = pLSPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + bapContext->lsReqPacket = NULL; + return vosStatus; + } + } + else + { + vosStatus = WLANBAP_AcquireLSPacket( bapContext, &pLSPacket,32, FALSE ); + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + bapContext->lsRepPacket = pLSPacket; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:AcquireLSPacket failed\n",__func__); + bapContext->lsRepPacket = NULL; + return vosStatus; + } + } + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "%s:Returned Vos Packet:%p\n", __func__, pPacket ); + + vos_pkt_return_packet( pPacket ); + + return (VOS_STATUS_SUCCESS ); +} + +/*=========================================================================== + + FUNCTION WLANBAP_TxLinkSupervision + + DESCRIPTION + + This API will be called to process Link Supervision Request received + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_TxLinkSupervision +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + vos_pkt_t *pPacket, + v_U16_t protoType +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)btampHandle; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + v_PVOID_t pvosGCtx; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + WLANTL_MetaInfoType metaInfo; + + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "In : %s protoType=%x", __func__,protoType); + + // Retrieve the VOSS context + pvosGCtx = pBtampCtx->pvosGCtx; + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unable to retrieve STA Id from BAP context and phy_link_handle in WLANBAP_TxLinKSupervisionReq"); + return VOS_STATUS_E_FAULT; + } + + vos_mem_zero( &metaInfo, sizeof( WLANTL_MetaInfoType ) ); + + metaInfo.ucTID = 0x00 ; + metaInfo.ucUP = 0x00; + metaInfo.ucIsEapol = VOS_FALSE;//Notify TL that this is NOT an EAPOL frame + metaInfo.ucDisableFrmXtl = VOS_FALSE; + metaInfo.ucType = 0x00; + pBtampCtx->metaInfo = metaInfo; + + vosStatus = WLANTL_TxBAPFrm( pvosGCtx, pPacket, &metaInfo, WLANBAP_TxLinkSupervisionCB ); + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Tx: Packet rejected by TL in WLANBAP_TxLinkSupervisionReq"); + return vosStatus; + } + + if(protoType == WLANTL_BT_AMP_TYPE_LS_REQ) + { + pBtampCtx->lsReqPktPending = TRUE; + pBtampCtx->retries++; + } + + if (pBtampCtx->bapLinkSupervisionTimerInterval) + { + /* Restart the LS timer */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + } + + if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLANBAP_TxLinkSupervisionReq failed to Start LinkSupervision Timer\n" ); + return vosStatus; + } + + return vosStatus; +} /* WLANBAP_RxLinkSupervisionReq */ + + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiStatus.c b/drivers/staging/prima/CORE/BAP/src/bapApiStatus.c new file mode 100644 index 000000000000..27bb5dfd5bd5 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiStatus.c @@ -0,0 +1,854 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i S t a t u s . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Status functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) that properly register with the BAP Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/BAP/src/bapApiStatus.c,v 1.7 2009/03/09 08:45:04 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +//#include "wlan_qct_tl.h" +#include "vos_trace.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/* +Status Parameters +*/ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Read Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadFailedContactCounter: pointer to the "HCI Read Failed Contact Counter" structure. + pFailedContactCounter: pointer to return value for the "Failed Contact Counter" + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadFailedContactCounter or + pFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pBapHCIReadFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including "Read" Command Complete*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadFailedContactCounter */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPResetFailedContactCounter() + + DESCRIPTION + Implements the actual HCI Reset Failed Contact Counter command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIResetFailedContactCounter: pointer to the "HCI Reset Failed Contact Counter" structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIResetFailedContactCounter is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPResetFailedContactCounter +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pBapHCIResetFailedContactCounter, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPResetFailedContactCounter */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLinkQuality() + + DESCRIPTION + Implements the actual HCI Read Link Quality command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLinkQuality: pointer to the "HCI Read Link Quality" structure. + pBapHCILinkQuality: pointer to return value for the "Link Quality" + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLinkQuality or + pBapHCILinkQuality is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLinkQuality +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Link_Quality_Cmd *pBapHCIReadLinkQuality, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIReadLinkQuality) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the physical link handle extracted from + input parameter. This parameter has 2 bytes for physical handle + (only lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIReadLinkQuality->log_link_handle; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.log_link_handle + = phyLinkHandle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.link_quality = 0; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Get the Link quality indication status from control block. + Link quality value is being updated on the SME callback */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.link_quality + = btampContext->link_quality; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Link_Quality.status + = WLANBAP_STATUS_SUCCESS; + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLinkQuality */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadRSSI() + + DESCRIPTION + Implements the actual HCI Read RSSI command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadRSSI: pointer to the "HCI Read RSSI" structure. + pBapHCIRSSI: pointer to return value for the "RSSI". + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadRSSI or + pBapHCIRSSI is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadRSSI +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_RSSI_Cmd *pBapHCIReadRSSI, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; + v_U8_t phyLinkHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: btampHandle value: %p", __func__, btampHandle); + + /* Validate params */ + if ((NULL == btampHandle) || (NULL == pBapHCIReadRSSI) || + (NULL == pBapHCIEvent)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid input parameters in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Validate the physical link handle extracted from + input parameter. This parameter has 2 bytes for physical handle + (only lower byte valid) */ + phyLinkHandle = (v_U8_t) pBapHCIReadRSSI->log_link_handle; + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.phy_link_handle + = phyLinkHandle; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.rssi = 0; + + if (phyLinkHandle != btampContext->phy_link_handle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid Physical link handle in %s", __func__); + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.status + = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + } + else + { + /* Get the RSSI value for this station (physical link) */ + vosStatus = WLANTL_GetRssi(btampContext->pvosGCtx, btampContext->ucSTAId, + &pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.rssi); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + /* GetRssi success, indicate the to upper layer */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.status + = WLANBAP_STATUS_SUCCESS; + } + else + { + /* API failed, indicate unspecified error to upper layer */ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_RSSI.status + = WLANBAP_ERROR_UNSPECIFIED_ERROR; + } + } + + /* Fill in the parameters for command complete event... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = TRUE; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_RSSI_CMD; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadRSSI */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPInfo() + + DESCRIPTION + Implements the actual HCI Read Local AMP Information command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPInfo: pointer to the "HCI Read Local AMP Info" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPInfo or + pBapHCILocalAMPInfo is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPInfo +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pBapHCIReadLocalAMPInfo, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + /* Validate params */ + if (btampHandle == NULL) { + return VOS_STATUS_E_FAULT; + } + + /* Validate params */ + if (pBapHCIReadLocalAMPInfo == NULL) { + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_AMP_Status + = WLANBAP_HCI_AMP_STATUS_NOT_SHARED; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Total_BW + = 24000; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Max_Guaranteed_BW + = 12000; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Min_Latency + = 100; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Max_PDU_Size + = WLANBAP_MAX_80211_PAL_PDU_SIZE; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Controller_Type + = 1; +#if 0 +AMP Info PAL_Capabilities: Size: 2 Octets + +Value Parameter Description +0xXXXX Bit 0: "Service Type = Guaranteed" is not supported by PAL = 0 + "Service Type = Guaranteed" is supported by PAL = 1 + Bits 15-1: Reserved (shall be set to 0) + (See EFS in Generic AMP FIPD [1]) +#endif //0 + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_PAL_Capabilities + = 0x00; // was 0x03. Completely wrong. + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_AMP_Assoc_Length + = 248; + //= 40; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_Max_Flush_Timeout + = 10000; //10; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Local_AMP_Info.HC_BE_Flush_Timeout + = 10000; //8; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalAMPInfo */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPReadLocalAMPAssoc() + + DESCRIPTION + Implements the actual HCI Read Local AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIReadLocalAMPAssoc: pointer to the "HCI Read Local AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIReadLocalAMPAssoc + (or pBapHCILocalAMPAssoc) is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPReadLocalAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pBapHCIReadLocalAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + VOS_STATUS vosStatus; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + tHalHandle hHal; + tBtampAMP_ASSOC btamp_ASSOC; + v_U32_t nConsumed = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /* Validate params */ + if ((pBapHCIReadLocalAMPAssoc == NULL) || (NULL == btampHandle)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, phy_link_handle = %d", __func__, + pBapHCIReadLocalAMPAssoc->phy_link_handle); + + /* Update the MAC address and SSID if in case the Read Local AMP Assoc + * Request is made before Create Physical Link creation. + */ + WLANBAP_ReadMacConfig (btampContext); + + /* Fill in the contents of an AMP_Assoc structure in preparation + * for Packing it into the AMP_assoc_fragment field of the Read + * Local AMP Assoc Command Complete Event + */ + /* Return the local MAC address */ + btamp_ASSOC.AMP_Assoc_MAC_Addr.present = 1; + vos_mem_copy( + btamp_ASSOC.AMP_Assoc_MAC_Addr.mac_addr, + btampContext->self_mac_addr, + sizeof(btampContext->self_mac_addr)); + + /*Save the local AMP assoc info*/ + vos_mem_copy(btampContext->btamp_AMP_Assoc.HC_mac_addr, + btampContext->self_mac_addr, + sizeof(btampContext->self_mac_addr)); + + + /* JEZ090303: This logic should return a single channel list with the */ + /* selected channel, if we have one. */ + //if (btampContext->channel) + if (1) + { + /* Return the local Preferred Channel List */ + /* Return both the Regulatory Info and one channel list */ + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.present = 1; + vos_mem_copy (btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.country, "XXX", 3); + /*Save the local AMP assoc info*/ + vos_mem_copy(btampContext->btamp_AMP_Assoc.HC_pref_country, "XXX", 3); + + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets = 2; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][0] = 201; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][1] = 254; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][2] = 0; + + if (( BT_INITIATOR == btampContext->BAPDeviceRole ) && + ( 0 != btampContext->channel )) + { + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0] = btampContext->channel; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1] = 0x01; //we are AP - we start on their 1st preferred channel + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][2] = 0x11; + } + else + { + if (btampContext->config.ucPreferredChannel) + { + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0] = btampContext->config.ucPreferredChannel; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1] = + 0x0B - btampContext->config.ucPreferredChannel + 1; + } + else + { + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0] = 0x01; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1] = 0x0B; //all channels for 1 to 11 + } + + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][2] = 0x11; + } + } else + { + /* Return the local Preferred Channel List */ + /* Return only the Regulatory Info */ + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.present = 1; + vos_mem_copy (btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.country, "XXX", 3); + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets = 1; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][0] = 201; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][1] = 254; + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][2] = 0; + + } + + /*Save the local AMP assoc info*/ + btampContext->btamp_AMP_Assoc.HC_pref_num_triplets = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[0][0] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][0]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[0][1] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][1]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[0][2] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[0][2]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][0]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][1] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][1]; + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][2] = btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets[1][2]; + + /* Also, at this point, lie and tell the other side we are connected on */ + /* the one channel we support. I hope this convinces the peer as BT-AMP AP */ + /* We really want him to use our channel. Since we only support one.*/ + /* Return the local Connected Channel */ + btamp_ASSOC.AMP_Assoc_Connected_Channel.present = 1; + vos_mem_copy (btamp_ASSOC.AMP_Assoc_Connected_Channel.country, "XXX", 3); + btamp_ASSOC.AMP_Assoc_Connected_Channel.num_triplets = 2; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[0][0] = 201; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[0][1] = 254; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[0][2] = 0; + //btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][0] = 0x01; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][0] = (0 != btampContext->channel)?btampContext->channel:0x01; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][1] = 0x01; + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets[1][2] = 0x11; + + + /* Return the local PAL Capabilities */ + btamp_ASSOC.AMP_Assoc_PAL_Capabilities.present = 1; + +#if 0 +AMP ASSOC Pal Capabilities: Size: 4 Octets + + Value Description + 4 TypeID for 802.11 PAL Capabilities + + 4 Length + + 0xXXXXXXXX Bit 0: + 0 signifies the PAL is not capable of utilizing + received Activity Reports + 1 signifies the PAL is capable of utilizing + received Activity Reports + Bit 1: + 0 signifies the PAL is not capable of utilizing + scheduling information sent in an Activity Report + 1 signifies the PAL is capable of utilizing + scheduling information sent in an Activity Report + Bits 2..31 Reserved + +#endif //0 + + btamp_ASSOC.AMP_Assoc_PAL_Capabilities.pal_capabilities +// = btampContext->btamp_Remote_AMP_Assoc.HC_pal_capabilities; + //= 0x03; + = 0x00; + + /* Return the local PAL Version */ + btamp_ASSOC.AMP_Assoc_PAL_Version.present = 1; + + /* Return the version and company ID data */ + btamp_ASSOC.AMP_Assoc_PAL_Version.pal_version = WLANBAP_PAL_VERSION; + btamp_ASSOC.AMP_Assoc_PAL_Version.pal_CompanyID = WLANBAP_QUALCOMM_COMPANY_ID; // Qualcomm Company ID + btamp_ASSOC.AMP_Assoc_PAL_Version.pal_subversion = WLANBAP_PAL_SUBVERSION; + + //Pack the AMP Assoc structure + vosStatus = btampPackAMP_ASSOC( + hHal, + &btamp_ASSOC, + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.AMP_assoc_fragment, + 248, + &nConsumed); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: nConsumed value: %d", __func__, nConsumed); + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD; + /*Validate the Physical handle*/ + if(pBapHCIReadLocalAMPAssoc->phy_link_handle != + btampContext->phy_link_handle) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Wrong Physical Link handle in Read Local AMP Assoc cmd: current: %x, new: %x", __func__, + btampContext->phy_link_handle, + pBapHCIReadLocalAMPAssoc->phy_link_handle); + + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.status + = WLANBAP_ERROR_NO_CNCT; + } else + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.status + = WLANBAP_STATUS_SUCCESS; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.phy_link_handle + = pBapHCIReadLocalAMPAssoc->phy_link_handle; + /* We will fit in one fragment, so remaining is exactly equal to encoded size*/ + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Read_Read_Local_AMP_Assoc.remaining_length + = nConsumed; + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPReadLocalAMPAssoc */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLAN_BAPWriteRemoteAMPAssoc() + + DESCRIPTION + Implements the actual HCI Write Remote AMP Assoc command. There + is no need for a callback because when this call returns the action + has been completed. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + pBapHCIWriteRemoteAMPAssoc: pointer to the "HCI Write Remote AMP Assoc" Structure. + + IN/OUT + pBapHCIEvent: Return event value for the command complete event. + (The caller of this routine is responsible for sending + the Command Complete event up the HCI interface.) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIWriteRemoteAMPAssoc is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLAN_BAPWriteRemoteAMPAssoc +( + ptBtampHandle btampHandle, + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pBapHCIWriteRemoteAMPAssoc, + tpBtampHCI_Event pBapHCIEvent /* This now encodes ALL event types */ + /* Including Command Complete and Command Status*/ +) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; + + /* I am using btampContext, instead of pBapPhysLinkMachine */ + //tWLAN_BAPbapPhysLinkMachine *pBapPhysLinkMachine; + ptBtampContext btampContext = (ptBtampContext) btampHandle; /* btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + + /* Validate params */ + if (pBapHCIWriteRemoteAMPAssoc == NULL) { + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampHandle value: %p", __func__, btampHandle); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC; + bapEvent.params = pBapHCIWriteRemoteAMPAssoc; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Handle event */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Format the command complete event to return... */ + pBapHCIEvent->bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT; + pBapHCIEvent->u.btampCommandCompleteEvent.present = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.num_hci_command_packets = 1; + pBapHCIEvent->u.btampCommandCompleteEvent.command_opcode + = BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Remote_AMP_Assoc.status + = status; + pBapHCIEvent->u.btampCommandCompleteEvent.cc_event.Write_Remote_AMP_Assoc.phy_link_handle + = pBapHCIWriteRemoteAMPAssoc->phy_link_handle; + + if(WLANBAP_ERROR_NO_SUITABLE_CHANNEL == status) + { + /* Format the Physical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.phy_link_handle + = btampContext->phy_link_handle; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.ch_number + = 0; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + } + + /* ... */ + + return VOS_STATUS_SUCCESS; +} /* WLAN_BAPWriteRemoteAMPAssoc */ + + + + + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiTimer.c b/drivers/staging/prima/CORE/BAP/src/bapApiTimer.c new file mode 100644 index 000000000000..c27db4681e5a --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiTimer.c @@ -0,0 +1,1037 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p A p i T i m e r . C + + OVERVIEW: + + This software unit holds the implementation of the timer routines + required by the WLAN BAP module. + + The functions provide by this module are called by the rest of + the BT-AMP PAL module. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/btamp-label9/CORE/BAP/src/bapApiTimer.c,v 1.5 2010/09/04 00:14:37 labuser Exp labuser $$DateTime$$Author: labuser $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-10-23 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// I think this pulls in everything +#include "vos_types.h" +#include "bapApiTimer.h" + +//#define BAP_DEBUG + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WLAN_BAP_TX_PKT_MONITOR_TIME 100 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +#if 1 +//*BT-AMP packet LLC OUI value*/ +static const v_U8_t WLANBAP_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +#endif + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_InitConnectionAcceptTimer + + DESCRIPTION + Initialize the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_InitConnectionAcceptTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize the timer */ + vosStatus = vos_timer_init( + &pBtampCtx->bapConnectionAcceptTimer, + VOS_TIMER_TYPE_SW, /* use this type */ + WLANBAP_ConnectionAcceptTimerHandler, + pBtampCtx); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_InitConnectionAcceptTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_DeinitConnectionAcceptTimer + + DESCRIPTION + Destroy the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeinitConnectionAcceptTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize and then Start the timer */ + vosStatus = vos_timer_destroy ( + &pBtampCtx->bapConnectionAcceptTimer ); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_DeinitConnectionAcceptTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_StartConnectionAcceptTimer + + DESCRIPTION + Start the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartConnectionAcceptTimer +( + ptBtampContext pBtampCtx, + v_U32_t interval +) +{ + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Start the connection accept timer*/ + vos_timer_start( + &pBtampCtx->bapConnectionAcceptTimer, + interval); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StartConnectionAcceptTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_StopConnectionAcceptTimer + + DESCRIPTION + Stop the Connection Accept Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StopConnectionAcceptTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Stop the timer */ + vosStatus = vos_timer_stop( + &pBtampCtx->bapConnectionAcceptTimer); + + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StopConnectionAcceptTimer */ + + + +/*========================================================================== + + FUNCTION WLANBAP_ConnectionAcceptTimerHandler + + DESCRIPTION + Callback function registered with vos timer for the Connection + Accept timer + + DEPENDENCIES + + PARAMETERS + + IN + userData: pointer can be used to retrive the BT-AMP context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_ConnectionAcceptTimerHandler +( + v_PVOID_t userData +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)userData; + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U8_t status; /* return the BT-AMP status here */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Fatal error in %s", __func__ ); + VOS_ASSERT(0); + return; + } + + /*--------------------------------------------------------------------- + Feed this timeout to the BTAMP FSM + ---------------------------------------------------------------------*/ + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(pBtampCtx, &bapEvent, &status); + + /* Now transition to fully disconnected and notify phy link disconnect*/ + bapEvent.event = eWLAN_BAP_MAC_READY_FOR_CONNECTIONS; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(pBtampCtx, &bapEvent, &status); + + +}/*WLANBAP_ConnectionAcceptTimerHandler*/ + +/*========================================================================== + + FUNCTION WLANBAP_InitLinkSupervisionTimer + + DESCRIPTION + Initialize the Link Supervision Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_InitLinkSupervisionTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize the timer */ + vosStatus = vos_timer_init( + &pBtampCtx->bapLinkSupervisionTimer, + VOS_TIMER_TYPE_SW, /* use this type */ + WLANBAP_LinkSupervisionTimerHandler, + pBtampCtx); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_InitLinkSupervisionTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_DeinitLinkSupervisionTimer + + DESCRIPTION + Destroy the Link Supervision Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeinitLinkSupervisionTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Initialize and then Start the timer */ + vosStatus = vos_timer_destroy ( + &pBtampCtx->bapLinkSupervisionTimer ); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_DeinitLinkSupervisionTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_StartLinkSupervisionTimer + + DESCRIPTION + Start the LinkSupervisionTimer Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartLinkSupervisionTimer +( + ptBtampContext pBtampCtx, + v_U32_t interval +) +{ + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + vos_timer_start( + &pBtampCtx->bapLinkSupervisionTimer, + interval); + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StartLinkSupervisionTimer */ + +/*========================================================================== + + FUNCTION WLANBAP_StopLinkSupervisionTimer + + DESCRIPTION + Stop the LinkSupervision Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StopLinkSupervisionTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Stop the timer */ + vosStatus = vos_timer_stop( + &pBtampCtx->bapLinkSupervisionTimer); + + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_StopLinkSupervisionTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_LinkSupervisionTimerHandler + + DESCRIPTION + Callback function registered with vos timer for the LinkSupervision timer + + DEPENDENCIES + + PARAMETERS + + IN + userData: pointer can be used to retrive the BT-AMP context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_LinkSupervisionTimerHandler +( + v_PVOID_t userData +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)userData; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampHandle btampHandle = (ptBtampHandle)userData; + tWLAN_BAPEvent bapEvent; /* State machine event */ + v_U8_t phy_link_handle; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Fatal error in %s", __func__ ); + VOS_ASSERT(0); + return; + } + + phy_link_handle = pBtampCtx->phy_link_handle; + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP:In LinkSupervision Timer handler %s", __func__ ); + + if(pBtampCtx->dataPktPending == VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Data seen. Do nothing", __func__ ); + + pBtampCtx->dataPktPending = VOS_FALSE; + pBtampCtx->lsReqPktPending = VOS_FALSE; + pBtampCtx->retries = 0; + vosStatus = WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + vosStatus = WLANBAP_StartLinkSupervisionTimer (pBtampCtx, + pBtampCtx->bapLinkSupervisionTimerInterval * WLANBAP_BREDR_BASEBAND_SLOT_TIME); + + //Data is seen. or our previous packet is not yet fetched by TL.Don't do any thing.Just return; + return; + } + else if((pBtampCtx->lsReqPktPending == VOS_TRUE ) + && (pBtampCtx->retries == WLANBAP_LINK_SUPERVISION_RETRIES)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "#########WLAN BAP: LinkSupervision Timed OUT######## %s", __func__ ); + + /*--------------------------------------------------------------------- + Feed this timeout to the BTAMP FSM + ---------------------------------------------------------------------*/ + /* Fill in the event structure */ + /* JEZ110307: Which should this be? */ + //bapEvent.event =eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT; + bapEvent.event =eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION; + bapEvent.params = NULL; + + /* Handle event */ + vosStatus = btampFsm(pBtampCtx, &bapEvent, (v_U8_t *)&vosStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Resend the LS packet", __func__ ); + + /* If we have transmit pkt pending and the time out occurred,resend the ls packet */ + WLANBAP_StopLinkSupervisionTimer(pBtampCtx); + pBtampCtx->pPacket = pBtampCtx->lsReqPacket; + vosStatus = WLANBAP_TxLinkSupervision( btampHandle, + phy_link_handle, + pBtampCtx->pPacket , + WLANTL_BT_AMP_TYPE_LS_REQ); + } + +}/*WLANBAP_LinkSupervisionTimerHandler*/ + +/*========================================================================== + + FUNCTION WLANBAP_StartTxPacketMonitorTimer + + DESCRIPTION + Start the Tx Packet Monitor Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t uInterval = WLAN_BAP_TX_PKT_MONITOR_TIME; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Start the timer */ + vosStatus = vos_timer_start( &pBtampCtx->bapTxPktMonitorTimer, + uInterval); + + return vosStatus; +}/* WLANBAP_StartTxPacketMonitorTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_StopTxPacketMonitorTimer + + DESCRIPTION + Stop the Tx Packet Monitor Timer. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StopTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /*Stop the timer */ + vosStatus = vos_timer_stop( &pBtampCtx->bapTxPktMonitorTimer); + + + return vosStatus; +}/* WLANBAP_StopTxPacketMonitorTimer */ + + +/*========================================================================== + + FUNCTION WLANBAP_SendCompletedPktsEvent + + DESCRIPTION + Utility function for sending the NUM_OF_COMPLETED_PKTS_EVENT to HCI + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_SendCompletedPktsEvent +( + ptBtampContext pBtampCtx +) +{ + v_U8_t i, j; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U32_t uTxCompleted = 0; + tpBtampLogLinkCtx pLogLinkContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Format the Number of completed packets event */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_NUM_OF_COMPLETED_PKTS_EVENT; + bapHCIEvent.u.btampNumOfCompletedPktsEvent.num_handles = 0; + + /*--------------------------------------------------------------------- + Check if LL still exists, if TRUE generate num_pkt_event and + restart the timer + ---------------------------------------------------------------------*/ + for (i = 0, j = 0; i < WLANBAP_MAX_LOG_LINKS ; i++) + { + pLogLinkContext = &pBtampCtx->btampLogLinkCtx[i]; + if ( pLogLinkContext->present ) + { + uTxCompleted = pLogLinkContext->uTxPktCompleted; + bapHCIEvent.u.btampNumOfCompletedPktsEvent.conn_handles[j] = + pLogLinkContext->log_link_handle; + bapHCIEvent.u.btampNumOfCompletedPktsEvent.num_completed_pkts[j] = + uTxCompleted; + + j++; + + vos_atomic_decrement_U32_by_value((v_U32_t *) &pLogLinkContext->uTxPktCompleted, + (v_U32_t) uTxCompleted); + + if (uTxCompleted) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "wlan bap: %s Log Link handle - %d No Of Pkts - %d", __func__, + pLogLinkContext->log_link_handle, uTxCompleted); + } + } + } + + /* Indicate only if at least one logical link is present and number of + completed packets is non zero */ + if (j && uTxCompleted) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Indicating Num Completed packets Event"); + + /*issue num_pkt_event for uTxCompleted*/ + bapHCIEvent.u.btampNumOfCompletedPktsEvent.num_handles = j; + (*pBtampCtx->pBapHCIEventCB) + ( + pBtampCtx->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + } + +} + +/*========================================================================== + + FUNCTION WLANBAP_SendCompletedDataBlksEvent + + DESCRIPTION + Utility function for sending the NUM_OF_COMPLETED_DATA_BLOCKS_EVENT to HCI + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_SendCompletedDataBlksEvent +( + ptBtampContext pBtampCtx +) +{ + v_U8_t i, j; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U32_t uTxCompleted = 0; + tpBtampLogLinkCtx pLogLinkContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Format the Number of completed data blocks event */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_NUM_OF_COMPLETED_DATA_BLOCKS_EVENT; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_handles = 0; + + /*--------------------------------------------------------------------- + Check if LL still exists, if TRUE generate num_data_blocks_event and + restart the timer + ---------------------------------------------------------------------*/ + for (i = 0, j = 0; i < WLANBAP_MAX_LOG_LINKS ; i++) + { + pLogLinkContext = &pBtampCtx->btampLogLinkCtx[i]; + if ( pLogLinkContext->present ) + { + uTxCompleted = pLogLinkContext->uTxPktCompleted; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.conn_handles[j] = + pLogLinkContext->log_link_handle; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_completed_pkts[j] = + uTxCompleted; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_completed_blocks[j] = + uTxCompleted; + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.total_num_data_blocks = 16; + + j++; + + vos_atomic_decrement_U32_by_value((v_U32_t *) &pLogLinkContext->uTxPktCompleted, + (v_U32_t) uTxCompleted); + + if (uTxCompleted) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "wlan bap: %s Log Link handle - %d No Of Pkts - %d", __func__, + pLogLinkContext->log_link_handle, uTxCompleted); + } + } + } + + /* Indicate only if at least one logical link is present and number of + completed data blocks is non zero */ + if (j && uTxCompleted) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Indicating Num Completed Data Blocks Event"); + + /*issue num_data_blocks_event for uTxCompleted*/ + bapHCIEvent.u.btampNumOfCompletedDataBlocksEvent.num_handles = j; + (*pBtampCtx->pBapHCIEventCB) + ( + pBtampCtx->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + } + +} + +/*========================================================================== + + FUNCTION WLANBAP_TxPacketMonitorHandler + + DESCRIPTION + Callback function registered with vos timer for the Tx Packet Monitor + Timer. + + DEPENDENCIES + + PARAMETERS + + IN + userData: pointer can be used to retrive the BT-AMP context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANBAP_TxPacketMonitorHandler +( + v_PVOID_t userData +) +{ + ptBtampContext pBtampCtx = (ptBtampContext)userData; + BTAMPFSM_INSTANCEDATA_T *instanceVar = &pBtampCtx->bapPhysLinkMachine; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------------*/ + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Fatal error in %s", __func__ ); + VOS_ASSERT(0); + return; + } + +#if 0 //BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampCtx value = %x in %s:%d", pBtampCtx, __func__, __LINE__ ); +#endif //BAP_DEBUG + + if(WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED == pBtampCtx->ucDataTrafficMode) + { + WLANBAP_SendCompletedDataBlksEvent(pBtampCtx); + } + else + { + WLANBAP_SendCompletedPktsEvent(pBtampCtx); + } + + /* Restart the Packet monitoring timer if still Physical link + * is present. + * It is possible that when the physical link is tear down, + * timer start request is in Q and could start again. + */ + if (CONNECTED == instanceVar->stateVar) + { + WLANBAP_StartTxPacketMonitorTimer(pBtampCtx); + } +}/*WLANBAP_TxPacketMonitorHandler*/ + diff --git a/drivers/staging/prima/CORE/BAP/src/bapApiTimer.h b/drivers/staging/prima/CORE/BAP/src/bapApiTimer.h new file mode 100644 index 000000000000..2c6a101b7641 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapApiTimer.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_API_TIMER_H +#define WLAN_QCT_WLANBAP_API_TIMER_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + T I M E R S E R V I C E S A P I + + +DESCRIPTION + This file contains the timer APIs used by the wlan BT-AMP PAL layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiTimer.h,v 1.1 2008/11/21 20:30:20 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/23/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// Pick up all the BT-AMP internal definitions +// And underlying supporting types. (Including VOSS, CSR, and...) +#include "bapInternal.h" + +/* Pick up the SIRIUS and HAL types */ +// Already taken care of, above +//#include "sirApi.h" +//#include "halTypes.h" + +/* Pick up the CCM API def'n */ +#include "ccmApi.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +// Temporary +//#define BAP_DEBUG + + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Function prototypes + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Utility Function prototypes + * -------------------------------------------------------------------------*/ + +#if 0 +/*========================================================================== + + FUNCTION WLANBAP_StartConnectionAcceptTimer + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + interval: time interval. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_StartConnectionAcceptTimer +( + ptBtampContext pBtampCtx, + v_U32_t interval +); +#endif // 0 + +/* Connection Accept timer*/ +VOS_STATUS WLANBAP_InitConnectionAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitConnectionAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartConnectionAcceptTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopConnectionAcceptTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_ConnectionAcceptTimerHandler + ( v_PVOID_t userData ); + +/* Link Supervision timer*/ +VOS_STATUS WLANBAP_InitLinkSupervisionTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitLinkSupervisionTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartLinkSupervisionTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopLinkSupervisionTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_LinkSupervisionTimerHandler + ( v_PVOID_t userData ); + +/* Logical Link Accept timer*/ +VOS_STATUS WLANBAP_InitLogicalLinkAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitLogicalLinkAcceptTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartLogicalLinkAcceptTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopLogicalLinkAcceptTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_LogicalLinkAcceptTimerHandler + ( v_PVOID_t userData ); + +/* Best Effort Flush timer*/ +VOS_STATUS WLANBAP_InitBEFlushTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_DeinitBEFlushTimer + ( ptBtampContext pBtampCtx); + +VOS_STATUS WLANBAP_StartBEFlushTimer + (ptBtampContext pBtampCtx, v_U32_t interval); + +VOS_STATUS WLANBAP_StopBEFlushTimer + ( ptBtampContext pBtampCtx); + +v_VOID_t WLANBAP_BEFlushTimerHandler + ( v_PVOID_t userData ); + +/* Tx Packet monitor timer handler */ +v_VOID_t +WLANBAP_TxPacketMonitorHandler +( + v_PVOID_t userData +); + +/* Tx Packet monitor start timer */ +VOS_STATUS +WLANBAP_StartTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +); + +/* Tx Packet monitor stop timer */ +VOS_STATUS +WLANBAP_StopTxPacketMonitorTimer +( + ptBtampContext pBtampCtx +); + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_API_TIMER_H */ + diff --git a/drivers/staging/prima/CORE/BAP/src/bapInternal.h b/drivers/staging/prima/CORE/BAP/src/bapInternal.h new file mode 100644 index 000000000000..31b673464c76 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapInternal.h @@ -0,0 +1,1314 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANBAP_INTERNAL_H +#define WLAN_QCT_WLANBAP_INTERNAL_H + +/*=========================================================================== + + W L A N B T - A M P P A L L A Y E R + I N T E R N A L A P I + + +DESCRIPTION + This file contains the internal API exposed by the wlan BT-AMP PAL layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/ampBlueZ_2/CORE/BAP/src/bapInternal.h,v 1.3 2010/07/12 20:40:18 labuser Exp labuser $ $DateTime: $ $Author: labuser $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +09/15/08 jez Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" + +// Pick up the CSR API definitions +#include "csrApi.h" + +/* BT-AMP PAL API structure types - FramesC generated */ +#include "btampHCI.h" +#include "bapApi.h" + +// Pick up the BTAMP FSM definitions +#include "fsmDefs.h" +//#include "btampFsm.h" +#include "btampFsm_ext.h" +#include "bapRsn8021xFsm.h" +#include "bapRsnErrors.h" + +#include "csrApi.h" +#include "sirApi.h" +#include "wniApi.h" +#include "palApi.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +// Temporary so that I can compile +//#define VOS_MODULE_ID_BAP 9 +// Temporary +//#define BAP_DEBUG + +// Used to enable or disable security on the BT-AMP link +#define WLANBAP_SECURITY_ENABLED_STATE VOS_TRUE + +// How do I get BAP context from voss context? +#define VOS_GET_BAP_CB(ctx) vos_get_context( VOS_MODULE_ID_BAP, ctx) +// How do I get halHandle from voss context? +#define VOS_GET_HAL_CB(ctx) vos_get_context( VOS_MODULE_ID_SME, ctx) + +// Default timeout values (in BR/EDR baseband slots) +// Physical Link Connection Accept Timer interval (0x1FA0 * 0.625 = 5.06 sec) +/* chose to double it to 3FFF as we saw conn timeout in lab*/ +//#define WLANBAP_CONNECTION_ACCEPT_TIMEOUT 0xFFFF +// Set default to 0x1F40. Which is ~5 secs. +#define WLANBAP_CONNECTION_ACCEPT_TIMEOUT 0x1F40 + +/* Link Supervision Timer interval (0x7D00 * 0.625 = 20 sec) */ +#ifdef FEATURE_WLAN_BTAMP_UT +#define WLANBAP_LINK_SUPERVISION_TIMEOUT 0x7D00 +#else +#define WLANBAP_LINK_SUPERVISION_TIMEOUT 0x3E80 // 10 seconds +#endif +#define WLANBAP_LINK_SUPERVISION_RETRIES 2 + +/* Logical Link Accept Timer interval (0x1FA0 * 0.625 = 5.06 sec)*/ +#define WLANBAP_LOGICAL_LINK_ACCEPT_TIMEOUT 0x1F40 + +/* BR/EDR baseband 1 slot time period */ +#define WLANBAP_BREDR_BASEBAND_SLOT_TIME 1 // 0.625 + +/* Maximum allowed range for connection accept timeout interval */ +#define WLANBAP_CON_ACCEPT_TIMEOUT_MAX_RANGE 0xB540 + +/* Minimum allowed range for connection accept timeout interval */ +#define WLANBAP_CON_ACCEPT_TIMEOUT_MIN_RANGE 0x01 + +/* Best Effort Flush timer interval*/ +#define WLANBAP_BE_FLUSH_TIMEOUT 10 + +/* Length of the LLC header*/ +#define WLANBAP_LLC_HEADER_LEN 8 + +/*Size of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_SIZE 2 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_SIZE 3 + +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_OUI_OFFSET 3 + +/*Offset of the protocol type field inside the LLC/SNAP header*/ +#define WLANBAP_LLC_PROTO_TYPE_OFFSET (WLANBAP_LLC_OUI_OFFSET + WLANBAP_LLC_OUI_SIZE) + +#define WLANBAP_MAX_NUM_TRIPLETS 5 + +#define WLANBAP_MAX_SIZE_TRIPLETS 3 +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Type Declarations - For internal BAP context information + * -------------------------------------------------------------------------*/ +typedef struct sBtampHCI_Buffer_Size { +// v_U8_t present; + /* D9r14 says Max80211PALPDUSize 1492 */ + v_U16_t HC_ACL_Data_Packet_Length; + v_U8_t HC_SCO_Packet_Length; + v_U16_t HC_Total_Num_ACL_Packets; + v_U16_t HC_Total_Num_SCO_Packets; +} tBtampHCI_Buffer_Size; + +typedef struct sBtampHCI_Data_Block_Size { +// v_U8_t present; + v_U8_t status; + /* D9r14 says Max80211PALPDUSize 1492 */ + v_U16_t HC_Max_ACL_Data_Packet_Length; + v_U16_t HC_Data_Block_Length; + v_U16_t HC_Total_Num_Data_Blocks; +} tBtampHCI_Data_Block_Size; + +typedef struct sBtampHCI_Version_Info { +// v_U8_t present; + v_U8_t HC_HCI_Version; + v_U16_t HC_HCI_Revision; + v_U8_t HC_PAL_Version; /* for 802.11 AMP: 0x01 */ + v_U16_t HC_PAL_Sub_Version; /* for 802.11 AMP: Vendor specific */ + v_U16_t HC_Manufac_Name; /* See BT assigned numbers */ +} tBtampHCI_Version_Info; + +typedef struct sBtampHCI_Supported_Cmds { +// v_U8_t present; + v_U8_t HC_Support_Cmds[64]; /* a bitmask of cmds */ +} tBtampHCI_Supported_Cmds; + +typedef struct sBtampHCI_AMP_Info { +// v_U8_t present; + v_U8_t HC_AMP_Status; + v_U32_t HC_Total_BW; /* combined uplink and downlink */ + v_U32_t HC_Max_Guaranteed_BW; /* upper bound */ + v_U32_t HC_Min_Latency; /* AMP HCI latency + DIFS + CWMin */ + v_U32_t HC_Max_PDU_Size; /* Equal to Max80211PALPDUSize */ + v_U8_t HC_Controller_Type; /* 0x01 for 802.11 BT-AMP PAL */ + v_U16_t HC_PAL_Capabilities; /* Bit 0: 0 = No Guarantee; 1 = Guarantee */ + v_U16_t HC_AMP_Assoc_Length; /* Length of AMP Assoc Info */ + /* Equal to Max80211AMPASSOCLen (672) */ + v_U16_t HC_Max_Flush_Timeout; /* Maximum time Tx attempted. 0 is inf retry */ + v_U16_t HC_BE_Flush_Timeout; /* Maximum time BE Tx attempted. 0 is inf retry */ +} tBtampHCI_AMP_Info; + +typedef struct sBtampHCI_AMP_Assoc { +// v_U8_t present; + v_U8_t HC_cnct_country[3]; /* Connected channel */ + v_U8_t HC_cnct_num_triplets; + v_U8_t HC_cnct_triplets[WLANBAP_MAX_NUM_TRIPLETS][WLANBAP_MAX_SIZE_TRIPLETS]; + v_U8_t HC_mac_addr[6]; + v_U32_t HC_pal_capabilities; + v_U8_t HC_pref_country[3]; /* Preferred channels */ + v_U8_t HC_pref_num_triplets; + v_U8_t HC_pref_triplets[WLANBAP_MAX_NUM_TRIPLETS][WLANBAP_MAX_SIZE_TRIPLETS]; + v_U8_t HC_pal_version; + v_U16_t HC_pal_CompanyID; + v_U16_t HC_pal_subversion; +} tBtampHCI_AMP_Assoc, *tpBtampHCI_AMP_Assoc ; + +typedef struct sBtampTLVHCI_Location_Data_Info { + v_U8_t loc_domain_aware; + v_U8_t loc_domain[3]; + v_U8_t loc_options; +} tBtampTLVHCI_Location_Data_Info; + +/*---------------------------------------------------------------------------- + * Type Declarations - For BAP logical link context information + * -------------------------------------------------------------------------*/ +typedef struct sBtampLogLinkCtx { + v_U8_t present; /* In use? */ + + v_U8_t log_link_index; /* small integer (<16) value assigned by us */ + v_U16_t log_link_handle; /* 8 bits of phy_link_handle and our index */ + + /* The flow spec (From section 5.6 of Generic AMP spec) */ + tBtampTLVFlow_Spec btampFlowSpec; + + /* The Access category */ + WLANTL_ACEnumType btampAC; + + /* The TID */ + v_U8_t ucTID; + + /* UP of the packet being sent */ + v_U8_t ucUP; + + /*Number of packets completed since the last time num pkt complete event + was issued*/ + v_U32_t uTxPktCompleted; + +} tBtampLogLinkCtx, *tpBtampLogLinkCtx ; + +/*---------------------------------------------------------------------------- + * Type Declarations - QOS related + * -------------------------------------------------------------------------*/ +/* BT-AMP QOS config */ +typedef struct sBtampQosCfg { + v_U8_t bWmmIsEnabled; +} tBtampQosCfg; + +/*---------------------------------------------------------------------------- + * Opaque BAP context Type Declaration + * -------------------------------------------------------------------------*/ +// We were only using this syntax, when this was truly opaque. +// (I.E., it was defined in a different file.) +//typedef struct sBtampContext tBtampContext, *ptBtampContext; + + +// Validity check the logical link value +#define BTAMP_VALID_LOG_LINK(a) ( a > 0 && a < WLANBAP_MAX_LOG_LINKS ? 1 : 0) + +/* Instance data definition of state machine */ +// Moved here from the BTAMP FSM definitions in btampFsm.h +typedef struct{ + BTAMPFSM_ENTRY_FLAG_T disconnectedEntry; + BTAMPFSM_STATEVAR_T stateVar; + BTAMPFSM_INST_ID_T inst_id; +} BTAMPFSM_INSTANCEDATA_T; + +/* BT-AMP device role */ +typedef enum{ + BT_RESPONDER, + BT_INITIATOR +} tWLAN_BAPRole; + +/* BT-AMP device role */ +typedef enum{ + WLAN_BAPLogLinkClosed, + WLAN_BAPLogLinkOpen, + WLAN_BAPLogLinkInProgress, +} tWLAN_BAPLogLinkState; + +typedef struct{ + v_U8_t phyLinkHandle; + v_U8_t txFlowSpec[18]; + v_U8_t rxFlowSpec[18]; +} tBtampLogLinkReqInfo; + +/*---------------------------------------------------------------------------- + * BAP context Data Type Declaration + * -------------------------------------------------------------------------*/ +#undef BTAMP_MULTIPLE_PHY_LINKS +typedef struct sBtampContext { +#ifndef BTAMP_MULTIPLE_PHY_LINKS + + // Include the enclosing VOSS context here + v_PVOID_t pvosGCtx; + + // include the phy link state machine structure here + tWLAN_BAPbapPhysLinkMachine bapPhysLinkMachine; + + // BAP device role + tWLAN_BAPRole BAPDeviceRole; + // Include the SME(CSR) sessionId here + v_U8_t sessionId; + + // Actual storage for AP and self (STA) SSID + //tSirMacSSid SSID[2]; + tCsrSSIDInfo SSIDList[2]; + // Actual storage for AP bssid + tCsrBssid bssid; + // Include the SME(CSR) context here + tCsrRoamProfile csrRoamProfile; + tANI_U32 csrRoamId; + + // QOS config + tBtampQosCfg bapQosCfg; + + /*Flag for signaling if security is enabled*/ + v_U8_t ucSecEnabled; + + // associated boolean flag + v_U8_t mAssociated; + // associated status + v_U8_t mAssociatedStatus; + tCsrBssid assocBssid; + tBssSystemRole systemRole; + + // own SSID + v_U8_t ownSsid[32]; + v_U32_t ownSsidLen; + + // incoming Assoc SSID + v_U8_t assocSsid[32]; + v_U32_t assocSsidLen; + + // gNeedPhysLinkCompEvent + v_U8_t gNeedPhysLinkCompEvent; + // gPhysLinkStatus + v_U8_t gPhysLinkStatus; + // gDiscRequested + v_U8_t gDiscRequested; + // gDiscReason + v_U8_t gDiscReason; + + // Include the BSL per-application context here + v_PVOID_t pAppHdl; // Per-app BSL context + // Include the BSL per-association contexts here. + // (Right now, there is only one) + v_PVOID_t pHddHdl; + /* 8 bits of phy_link_handle identifies this association */ + v_U8_t phy_link_handle; + // Short Range Mode setting for this physical link + v_U8_t phy_link_srm; + + // Include the key material for this physical link + v_U8_t key_type; + v_U8_t key_length; + v_U8_t key_material[32]; + + /* Physical link quality status + After the physical link is up, SME indicates the link quality through + callback. This value is returned to upper layer on request. + */ + v_U8_t link_quality; + + /* Connection Accept timer*/ + vos_timer_t bapConnectionAcceptTimer; + /* Link Supervision timer*/ + vos_timer_t bapLinkSupervisionTimer; + /* Logical Link Accept timer*/ + vos_timer_t bapLogicalLinkAcceptTimer; + /* Best Effort Flush timer*/ + vos_timer_t bapBEFlushTimer; + + /* TX Packet Monitoring timer*/ + vos_timer_t bapTxPktMonitorTimer; + + /* Connection Accept Timer interval (in BR/EDR baseband slots) + * Interval length = N * 0.625 msec (1 BR/EDR baseband slot) + */ + v_U16_t bapConnectionAcceptTimerInterval; + + /* Link Supervision Timer interval (in BR/EDR baseband slots) */ + v_U16_t bapLinkSupervisionTimerInterval; + + /* Logical Link Accept Timer interval (in BR/EDR baseband slots) */ + v_U16_t bapLogicalLinkAcceptTimerInterval; + + /* Best Effort Flush timer interval*/ + v_U32_t bapBEFlushTimerInterval; + + // Include the current channel here + v_U32_t channel; + + // Include the associations STA Id + v_U8_t ucSTAId; + + // Include the associations MAC addresses + v_U8_t self_mac_addr[6]; + v_U8_t peer_mac_addr[6]; + + // The array of logical links + /* the last small integer (<16) value assigned by us */ + v_U8_t current_log_link_index; /* assigned mod 16 */ + v_U8_t total_log_link_index; /* should never be >16 */ + /* The actual array */ + tBtampLogLinkCtx btampLogLinkCtx[WLANBAP_MAX_LOG_LINKS]; + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB; + WLANBAP_STARxCBType pfnBtamp_STARxCB; + WLANBAP_TxCompCBType pfnBtampTxCompCB; + + /* Implements the callback for ALL asynchronous events. */ + tpWLAN_BAPEventCB pBapHCIEventCB; + + // Save Page2 of the event mask. + v_U8_t event_mask_page_2[8]; + + // Include the Local Assoc structure. + // (This gets filled during initialization. It is used, for example, to + // obtain the local MAC address for forming the 802.3 frame.) + // <> + tBtampHCI_AMP_Assoc btamp_AMP_Assoc; + + // Remote AMP Assoc + tBtampHCI_AMP_Assoc btamp_Remote_AMP_Assoc; + + tBtampTLVHCI_Location_Data_Info btamp_Location_Data_Info; + + union + { + tAuthRsnFsm authFsm; + tSuppRsnFsm suppFsm; + }uFsm; + //LinkSupervision packet + tANI_BOOLEAN lsReqPktPending; + tANI_BOOLEAN dataPktPending; + tANI_U8 retries; + vos_pkt_t *pPacket; + vos_pkt_t *lsReqPacket; + vos_pkt_t *lsRepPacket; + v_U16_t lsPktln; + v_U16_t lsPending; + WLANTL_MetaInfoType metaInfo; + tANI_BOOLEAN isBapSessionOpen; + + tWLAN_BAPLogLinkState btamp_logical_link_state; + + tBtampLogLinkReqInfo btamp_logical_link_req_info; + + tANI_BOOLEAN btamp_async_logical_link_create; + + tANI_BOOLEAN btamp_logical_link_cancel_pending; + + tANI_BOOLEAN btamp_session_on; + +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + + // Include the enclosing VOSS context here + v_PVOID_t pvosGCtx; + + // include the state machine structure here + + // Include the BSL per-application context here + v_PVOID_t pAppHdl; // Per-app BSL context + // Include the BSL per-association contexts here. + // (Right now, there is only one) + v_PVOID_t pHddHdl; + /* 8 bits of phy_link_handle identifies this association */ + v_U8_t phy_link_handle; + // Short Range Mode setting for this physical link + v_U8_t phy_link_srm; + + // Include the associations STA Id + v_U8_t ucSTAId; + + // Include the associations MAC addresses + v_U8_t self_mac_addr[6]; + v_U8_t peer_mac_addr[6]; + + // The array of logical links + /* the last small integer (<16) value assigned by us */ + v_U8_t current_log_link_index; /* assigned mod 16 */ + v_U8_t total_log_link_index; /* should never be >16 */ + /* The actual array */ + tBtampLogLinkCtx btampLogLinkCtx[WLANBAP_MAX_LOG_LINKS]; + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB; + WLANBAP_STARxCBType pfnBtamp_STARxCB; + WLANBAP_TxCompCBType pfnBtampTxCompCB; + + /* Implements the callback for ALL asynchronous events. */ + tpWLAN_BAPEventCB pBapHCIEventCB; + + // Include the Local Assoc structure. + // (This gets filled during initialization. It is used, for example, to + // obtain the local MAC address for forming the 802.3 frame.) + // <> + tBtampHCI_AMP_Assoc btamp_AMP_Assoc; + //LinkSupervision packet + tANI_BOOLEAN lsReqPktPending; + tANI_U8 retries; + vos_pkt_t *pPacket; + vos_pkt_t *lsReqPacket; + vos_pkt_t *lsRepPacket; + v_U16_t lsPktln; + WLANTL_MetaInfoType* metaInfo; + tANI_BOOLEAN isBapSessionOpen; + //End of LinkSupervision packet +#endif //BTAMP_MULTIPLE_PHY_LINKS + WLANBAP_ConfigType config; + /*multiple data structures getting accessed/written from both north & south + bound entities. To avoid multiple access, need a lock*/ + vos_lock_t bapLock; + // Either Block mode or Pkt mode + v_U8_t ucDataTrafficMode; +}*ptBtampContext; +//tBtampContext, *ptBtampContext; + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +typedef struct sBtampLsPktData { + v_U32_t BufLen; + v_U8_t pBuf[1]; // ptr to Data Buffer +}tBtampLsPktData, *ptBtampLsPktData; + +typedef struct sBtampLsPkt { + v_U8_t SrcMac[6]; + v_U8_t DstMac[6]; + tBtampLsPktData Data; +} tBtampLsPkt, *ptBtampLsPkt; + +/*---------------------------------------------------------------------------- + * BAP per-session Context Data Type Declaration + * -------------------------------------------------------------------------*/ +// For now, it is just the same thing as the per application context. +typedef struct sBtampContext tBtampSessCtx; + +/*---------------------------------------------------------------------------- + * BAP state machine event definition + * -------------------------------------------------------------------------*/ +/* The event structure */ +typedef struct sWLAN_BAPEvent { + v_U32_t event; /* State machine input event message */ + v_PVOID_t params; /* A VOID pointer type for all possible inputs */ + v_U32_t u1; /* introduced to handle csrRoamCompleteCallback roamStatus */ + v_U32_t u2; /* introduced to handle csrRoamCompleteCallback roamResult */ +} tWLAN_BAPEvent, *ptWLAN_BAPEvent; + +// Pick up the BTAMP FSM definitions +#include "btampFsm.h" + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// The main per-Physical Link (per WLAN association) context. +//extern tBtampContext btampCtx; +extern ptBtampContext gpBtampCtx; + +// Include the Local AMP Info structure. +extern tBtampHCI_AMP_Info btampHCI_AMP_Info; +// Include the Local Data Block Size info structure. +extern tBtampHCI_Data_Block_Size btampHCI_Data_Block_Size; +// Include the Local Version info structure. +extern tBtampHCI_Version_Info btampHCI_Version_Info; +// Include the Local Supported Cmds info structure. +extern tBtampHCI_Supported_Cmds btampHCI_Supported_Cmds; + + +/*---------------------------------------------------------------------------- + * Function prototypes + * -------------------------------------------------------------------------*/ + +/* I don't think any of this is needed */ + +/* TL data path callbacks passed into WLANTL_RegisterSTAClient */ + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STAFetchPktCB + + DESCRIPTION + The fetch packet callback registered with TL. + + It is called by the TL when the scheduling algorithms allows for + transmission of another packet to the module. + It will be called in the context of the BAL fetch transmit packet + function, initiated by the bus lower layer. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle + to TL's or HDD's control block can be extracted + from its context + + IN/OUT + pucSTAId: the Id of the station for which TL is requesting a + packet, in case HDD does not maintain per station + queues it can give the next packet in its queue + and put in the right value for the + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STAFetchPktCB +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + v_U8_t ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_STARxCB + + DESCRIPTION + The receive callback registered with TL. + + TL will call this to notify the client when a packet was received + for a registered STA. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's or HDD's control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was received + (it may be a linked list) + ucSTAId: station id + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_STARxCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + v_U8_t ucSTAId, + WLANTL_RxMetaInfoType* pRxMetaInfo +); + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_TxCompCB + + DESCRIPTION + The tx complete callback registered with TL. + + TL will call this to notify the client when a transmission for a + packet has ended. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_TxCompCB +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +); + +/* Callbacks Registered with TL by WLANTL_RegisterBAPClient */ + +/* RSN Callback */ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + The receive callback registered with TL for BAP. + + The registered reception callback is being triggered by TL whenever a + frame was received and it was filtered as a non-data BT AMP packet. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the received packet; + no chaining will be done on this path + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +WLANTL_BAPRxCBType WLANBAP_TLRsnRxCallback +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff +); + +/* Flush complete Callback */ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Callback registered with TL for BAP, this is required inorder for + TL to inform BAP, that the flush operation requested has been completed. + + The registered reception callback is being triggered by TL whenever a + frame SIR_TL_HAL_FLUSH_AC_RSP is received by TL from HAL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucStaId: station identifier for the requested value + ucTid: identifier of the tspec + status: status of the Flush operation + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_TLFlushCompCallback +( + v_PVOID_t pvosGCtx, + v_U8_t ucStaId, + v_U8_t ucTID, + v_U8_t status +); + +/*---------------------------------------------------------------------------- + * CSR Roam (Connection Status) callback + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext: is the pContext passed in with the roam request + pParam: is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: for detail valid members. It may be NULL + roamId: is to identify the callback related roam request. 0 means unsolicited + roamStatus: is a flag indicating the status of the callback + roamResult: is the result + + RETURN VALUE + The result code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +eHalStatus +WLANBAP_RoamCallback +( + void *pContext, + tCsrRoamInfo *pCsrRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +); + +/*---------------------------------------------------------------------------- + * Utility Function prototypes + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_CleanCB + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + freeFlag: flag indicating whether to free any allocations. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CleanCB +( + ptBtampContext pBtampCtx, + v_U32_t freeFlag // 0 /*do not empty*/); +); + +/*========================================================================== + + FUNCTION WLANBAP_GetCtxFromStaId + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need either the + BSL context or the BTAMP context from the StaId. + + + DEPENDENCIES + + PARAMETERS + + IN + ucSTAId: The StaId (used by TL, PE, and HAL) + + OUT + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCtxFromStaId +( + v_U8_t ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + ptBtampHandle *hBtampHandle, /* Handle to return per app btampHandle value in */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + v_PVOID_t *hHddHdl /* Handle to return BSL context in */ +); + +/*========================================================================== + + FUNCTION WLANBAP_GetStaIdFromLinkCtx + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need the + StaId (or hHddHdl) from the BTAMP context and phy_link_handle. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + phy_link_handle: physical link handle value. Unique per assoc. + + OUT + pucSTAId: The StaId (used by TL, PE, and HAL) + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetStaIdFromLinkCtx +( + ptBtampHandle btampHandle, /* btampHandle value in */ + v_U8_t phy_link_handle, /* phy_link_handle value in */ + v_U8_t *pucSTAId, /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t *hHddHdl /* Handle to return BSL context */ +); + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewPhyLinkCtx + + DESCRIPTION + Called in order to create (or update) a BAP Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: BAP app context handle + phy_link_handle: phy_link_handle from the Command + pHddHdl: BSL passes in its specific context + + OUT + hBtampContext: Handle (pointer to a pointer) to return the + per "Phy Link" ptBtampContext value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewPhyLinkCtx +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + tWLAN_BAPRole BAPDeviceRole /* Needed to determine which MAC address to use for self MAC */ +); + +/*========================================================================== + + FUNCTION WLANBAP_UpdatePhyLinkCtxStaId + + DESCRIPTION + Called to update the STAId value associated with Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: ptBtampContext to update. + ucSTAId: The StaId (used by TL, PE, and HAL) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_UpdatePhyLinkCtxStaId +( + ptBtampContext pBtampContext, /* btampContext value in */ + v_U8_t ucSTAId +); + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewLogLinkCtx + + DESCRIPTION + Called in order to allocate a BAP Logical Link "context" and "index" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: Pointer to the ptBtampContext value in. + phy_link_handle: phy_link_handle involved + + OUT + pLog_link_handle: return the log_link_handle here + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewLogLinkCtx +( + ptBtampContext pBtampContext, /* pointer to the per assoc btampContext value */ + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_U8_t tx_flow_spec[18], + v_U8_t rx_flow_spec[18], + v_U16_t *pLog_link_handle /* Return the logical link index here */ +); + + /*========================================================================== + + FUNCTION WLANBAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +); + +/*=========================================================================== + + FUNCTION WLANBAP_RxProcLsPkt + + DESCRIPTION + + This API will be called when Link Supervision frames are received at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + pucAC: Pointer to return the access category + RxProtoType: Protocol type of Received Packet + vosDataBuff: The data buffer containing the 802.3 frame to be + translated to BT HCI Data Packet + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_RxProcLsPkt +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + v_U16_t RxProtoType, /* Protocol Type from the frame received */ + vos_pkt_t *vosRxLsBuff +); + + +/*---------------------------------------------------------------------------- + + FUNCTION WLANBAP_TxLinkSupervisionReq() + + DESCRIPTION + Implements the LinkSupervision Tx Request procedure.This will be called by APIs that want + to transmit LinkSupervision Packets + Calls PktPending CB to indicate a packet is pending for transmission + + + DEPENDENCIES + NA. + + PARAMETERS + + IN + btampHandle: pointer to the BAP handle. Returned from WLANBAP_GetNewHndl. + phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) + vosDataBuff:The actual packet being sent in Tx request + protoType : specifies if it is a LS REQ or LS REP packet + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Failure of Transmit procedure + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS + +----------------------------------------------------------------------------*/ +VOS_STATUS +WLANBAP_TxLinkSupervision +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ + vos_pkt_t *vosDataBuff, + v_U16_t protoType +); + +/*========================================================================== + + FUNCTION WLANBAP_ReadMacConfig + + DESCRIPTION + This function sets the MAC config (Address and SSID to BT-AMP context + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_ReadMacConfig +( + ptBtampContext pBtampCtx +); + +/*========================================================================== + + FUNCTION WLANBAP_NeedBTCoexPriority + + DESCRIPTION + This function will cause a message to be sent to BTC firmware + if a change in priority has occurred. (From AMP's point-of-view.) + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to HAL's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_NeedBTCoexPriority +( + ptBtampContext pBtampCtx, + v_U32_t needCoexPriority +); + + +/*========================================================================== + + FUNCTION WLANBAP_RxCallback + + DESCRIPTION + This function is called by TL call this function for all frames except for Data frames + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + pPacket Vos packet + frameType Frame type + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANBAP_RxCallback +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pPacket, + WLANTL_BAPFrameEnumType frameType +); + + +/*=========================================================================== + + FUNCTION WLANBAP_InitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be initialized when connected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +#define TX_LS_DATALEN 32 + +VOS_STATUS +WLANBAP_InitLinkSupervision +( + ptBtampHandle btampHandle +); + + +/*=========================================================================== + + FUNCTION WLANBAP_DeInitLinkSupervision + + DESCRIPTION + + This API will be called when Link Supervision module is to be stopped after disconnected at BAP + + PARAMETERS + + btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: BAP handle is NULL + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_DeInitLinkSupervision +( + ptBtampHandle btampHandle +); + +void WLAN_BAPEstablishLogicalLink(ptBtampContext btampContext); + + #ifdef __cplusplus + } + + +#endif + + +#endif /* #ifndef WLAN_QCT_WLANBAP_INTERNAL_H */ + diff --git a/drivers/staging/prima/CORE/BAP/src/bapModule.c b/drivers/staging/prima/CORE/BAP/src/bapModule.c new file mode 100644 index 000000000000..5cda7f5ac0be --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapModule.c @@ -0,0 +1,1401 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b a p M o d u l e . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN BAP modules + Module support functions. It is also where the global BAP module + context, and per-instance (returned in BAP_Open device open) contexts. + + The functions externalized by this module are to be called by the device + specific BAP Shim Layer (BSL) (in HDD) which implements a stream device on a + particular platform. + + DEPENDENCIES: + + Are listed for each API below. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /home/labuser/ampBlueZ_2/CORE/BAP/src/bapModule.c,v 1.1 2010/07/12 19:05:35 labuser Exp labuser $$DateTime$$Author: labuser $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-09-15 jez Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +// Pull in some message types used by BTC +#include "sirParams.h" +//#include "halFwApi.h" + +#include "wlan_qct_tl.h" +#include "vos_trace.h" +// Pick up the sme callback registration API +#include "sme_Api.h" +#include "ccmApi.h" + +/* BT-AMP PAL API header file */ +#include "bapApi.h" +#include "bapInternal.h" + +// Pick up the BTAMP RSN definitions +#include "bapRsnTxRx.h" +//#include "assert.h" +#include "bapApiTimer.h" + +#if defined(ANI_OS_TYPE_ANDROID) +#include "bap_hdd_main.h" +#endif + +//#define BAP_DEBUG +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +//#define VOS_GET_BAP_CB(ctx) vos_get_context( VOS_MODULE_ID_BAP, ctx) + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +// include the phy link state machine structure here +static tWLAN_BAPbapPhysLinkMachine bapPhysLinkMachineInitial + = BTAMPFSM_INSTANCEDATA_INIT; + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// No! Get this from VOS. +// The main per-Physical Link (per WLAN association) context. +//tBtampContext btampCtx; +ptBtampContext gpBtampCtx; + +// Include the Local AMP Info structure. +tBtampHCI_AMP_Info btampHCI_AMP_Info; +// Include the Local Data Block Size info structure. +tBtampHCI_Data_Block_Size btampHCI_Data_Block_Size; +// Include the Local Version info structure. +tBtampHCI_Version_Info btampHCI_Version_Info; +// Include the Local Supported Cmds info structure. +tBtampHCI_Supported_Cmds btampHCI_Supported_Cmds; + +static unsigned char pBtStaOwnMacAddr[WNI_CFG_BSSID_LEN]; + + /*BT-AMP SSID; per spec should have this format: "AMP-00-0a-f5-04-05-08" */ +#define WLAN_BAP_SSID_MAX_LEN 21 +static char pBtStaOwnSsid[WLAN_BAP_SSID_MAX_LEN]; + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). BAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Open +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Allocate (and sanity check?!) BAP control block + ------------------------------------------------------------------------*/ + vos_alloc_context(pvosGCtx, VOS_MODULE_ID_BAP, (v_VOID_t**)&pBtampCtx, sizeof(tBtampContext)); + + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Open"); + //"Failed to allocate BAP pointer from pvosGCtx on WLANBAP_Open"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up BAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Open"); + + WLANBAP_CleanCB(pBtampCtx, 0 /*do not empty*/); + + // Setup the "link back" to the VOSS context + pBtampCtx->pvosGCtx = pvosGCtx; + + // Store a pointer to the BAP context provided by VOSS + gpBtampCtx = pBtampCtx; + + /*------------------------------------------------------------------------ + Allocate internal resources + ------------------------------------------------------------------------*/ + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_Open */ + + +/*========================================================================== + + FUNCTION WLANBAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). BAP will + use this call to register with TL as the BAP entity for + BT-AMP RSN frames. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Start +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + VOS_STATUS vosStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract BAP control block + ------------------------------------------------------------------------*/ + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Start"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Register with TL as an BT-AMP RSN client + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Start TL register"); + + /*------------------------------------------------------------------------ + Register with CSR for Roam (connection status) Events + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Start CSR Register"); + + + /* Initialize the BAP Tx packet monitor timer */ + WLANBAP_InitConnectionAcceptTimer (pBtampCtx ); + WLANBAP_InitLinkSupervisionTimer(pBtampCtx); + + vosStatus = vos_timer_init( + &pBtampCtx->bapTxPktMonitorTimer, + VOS_TIMER_TYPE_SW, /* use this type */ + WLANBAP_TxPacketMonitorHandler, + pBtampCtx); + + vosStatus = vos_lock_init(&pBtampCtx->bapLock); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"Lock Init Fail"); + } + + return vosStatus; +}/* WLANBAP_Start */ + +/*========================================================================== + + FUNCTION WLANBAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in BAP, before close. BAP will suspend all + BT-AMP Protocol Adaption Layer operation and will wait for the close + request to clean up its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Stop +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract BAP control block + ------------------------------------------------------------------------*/ + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Stop"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Stop BAP (de-register RSN handler!?) + ------------------------------------------------------------------------*/ + vosStatus = WLANBAP_DeinitConnectionAcceptTimer(pBtampCtx); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Couldn't destroy bapConnectionAcceptTimer"); + } + + vosStatus = WLANBAP_DeinitLinkSupervisionTimer(pBtampCtx); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Couldn't destroy bapLinkSupervisionTimer"); + } + + vosStatus = vos_timer_destroy ( + &pBtampCtx->bapTxPktMonitorTimer ); + if ( VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Couldn't destroy bapTxPktMonitorTimer"); + } + vos_lock_destroy(&pBtampCtx->bapLock); + return VOS_STATUS_SUCCESS; +}/* WLANBAP_Stop */ + +/*========================================================================== + + FUNCTION WLANBAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. BAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_Close +( + v_PVOID_t pvosGCtx +) +{ + ptBtampContext pBtampCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract BAP control block + ------------------------------------------------------------------------*/ + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Close"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Cleanup BAP control block. + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_Close"); + WLANBAP_CleanCB(pBtampCtx, 1 /* empty queues/lists/pkts if any*/); +#if defined(ANI_OS_TYPE_ANDROID) && defined(WLAN_BTAMP_FEATURE) + BSL_Deinit(pvosGCtx); +#endif + /*------------------------------------------------------------------------ + Free BAP context from VOSS global + ------------------------------------------------------------------------*/ + vos_free_context(pvosGCtx, VOS_MODULE_ID_BAP, pBtampCtx); + return VOS_STATUS_SUCCESS; +}/* WLANBAP_Close */ + +/*---------------------------------------------------------------------------- + HDD interfaces - Per instance initialization + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_GetNewHndl + + DESCRIPTION + Called by HDD at driver open (BSL_Open). BAP will initialize + allocate a per-instance "file handle" equivalent for this specific + open call. + + There should only ever be one call to BSL_Open. Since + the open app user is the BT stack. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle to return btampHandle value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANBAP_GetNewHndl +( + ptBtampHandle *hBtampHandle /* Handle to return btampHandle value in */ +) +{ + ptBtampContext btampContext = NULL; + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == hBtampHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle pointer in WLANBAP_GetNewHndl"); + return VOS_STATUS_E_FAULT; + } + +#ifndef BTAMP_MULTIPLE_PHY_LINKS + /*------------------------------------------------------------------------ + Sanity check the BAP control block pointer + ------------------------------------------------------------------------*/ + if ( NULL == gpBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in WLANBAP_GetNewHndl"); + return VOS_STATUS_E_FAULT; + } + + //*hBtampHandle = (ptBtampHandle) &btampCtx; + /* return a pointer to the tBtampContext structure - allocated by VOS for us */ + *hBtampHandle = (ptBtampHandle) gpBtampCtx; + btampContext = gpBtampCtx; + + /* Update the MAC address and SSID if in case the Read Local AMP Assoc + * Request is made before Create Physical Link creation. + */ + WLANBAP_ReadMacConfig (btampContext); + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_GetNewHndl */ + + +/*========================================================================== + + FUNCTION WLANBAP_ReleaseHndl + + DESCRIPTION + Called by HDD at driver open (BSL_Close). BAP will reclaim (invalidate) + the "file handle" passed into this call. + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: btampHandle value to invalidate. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: btampHandle is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_ReleaseHndl +( + ptBtampHandle btampHandle /* btamp handle value to release */ +) +{ + /* obtain btamp Context */ + ptBtampContext btampContext = (ptBtampContext) btampHandle; + tHalHandle halHandle; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == btampHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in WLANBAP_ReleaseHndl"); + return VOS_STATUS_E_FAULT; + } + + /* JEZ081001: TODO: Major: */ + /* Check to see if any wireless associations are still active */ + /* ...if so, I have to call + * sme_RoamDisconnect(VOS_GET_HAL_CB(btampHandle->pvosGCtx), + * btampHandle->sessionId, + * eCSR_DISCONNECT_REASON_UNSPECIFIED); + * on all of them */ + + halHandle = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if(NULL == halHandle) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "halHandle is NULL in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + if( btampContext->isBapSessionOpen == TRUE ) + { + halStatus = sme_CloseSession(halHandle, + btampContext->sessionId, FALSE, VOS_TRUE, NULL, NULL); + if(eHAL_STATUS_SUCCESS == halStatus) + { + btampContext->isBapSessionOpen = FALSE; + } + } + + /* release the btampHandle */ + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_ReleaseHndl */ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANBAP_CleanCB + + DESCRIPTION + Clear out all fields in the BAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pBtampCtx: pointer to the BAP control block + freeFlag: flag indicating whether to free any allocations. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to BAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CleanCB +( + ptBtampContext pBtampCtx, + v_U32_t freeFlag // 0 /*do not empty*/); +) +{ + v_U16_t i; /* Logical Link index */ + tpBtampLogLinkCtx pLogLinkContext = NULL; + + /*------------------------------------------------------------------------ + Sanity check BAP control block + ------------------------------------------------------------------------*/ + + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer in WLANBAP_CleanCB"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up BAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_CleanCB"); + + // First, clear out EVERYTHING in the BT-AMP context + vos_mem_set( pBtampCtx, sizeof( *pBtampCtx), 0); + + pBtampCtx->pvosGCtx = NULL; + + // Initialize physical link state machine to DISCONNECTED state + //pBtampCtx->bapPhysLinkMachine = BTAMPFSM_INSTANCEDATA_INIT; + + // Initialize physical link state machine to DISCONNECTED state + vos_mem_copy( + &pBtampCtx->bapPhysLinkMachine, + &bapPhysLinkMachineInitial, /* BTAMPFSM_INSTANCEDATA_INIT; */ + sizeof( pBtampCtx->bapPhysLinkMachine)); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Initializing State: %d", __func__, bapPhysLinkMachineInitial.stateVar); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Initialized State: %d", __func__, pBtampCtx->bapPhysLinkMachine.stateVar); + + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %x", __func__, pBtampCtx); +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampCtx value = %x in %s:%d", pBtampCtx, __func__, __LINE__ ); +#endif //BAP_DEBUG + + + pBtampCtx->sessionId = 0; + pBtampCtx->pAppHdl = NULL; // Per-app BSL context + pBtampCtx->pHddHdl = NULL; // Per-app BSL context + /* 8 bits of phy_link_handle identifies this association */ + pBtampCtx->phy_link_handle = 0; + pBtampCtx->channel = 0; + pBtampCtx->BAPDeviceRole = BT_RESPONDER; + pBtampCtx->ucSTAId = 0; + + // gNeedPhysLinkCompEvent + pBtampCtx->gNeedPhysLinkCompEvent = VOS_FALSE; + // gPhysLinkStatus + pBtampCtx->gPhysLinkStatus = WLANBAP_STATUS_SUCCESS; + // gDiscRequested + pBtampCtx->gDiscRequested = VOS_FALSE; + // gDiscReason + pBtampCtx->gDiscReason = WLANBAP_STATUS_SUCCESS; + + /* Connection Accept Timer interval*/ + pBtampCtx->bapConnectionAcceptTimerInterval = WLANBAP_CONNECTION_ACCEPT_TIMEOUT; + /* Link Supervision Timer interval*/ + pBtampCtx->bapLinkSupervisionTimerInterval = WLANBAP_LINK_SUPERVISION_TIMEOUT; + /* Logical Link Accept Timer interval*/ + pBtampCtx->bapLogicalLinkAcceptTimerInterval = WLANBAP_LOGICAL_LINK_ACCEPT_TIMEOUT; + /* Best Effort Flush timer interval*/ + pBtampCtx->bapBEFlushTimerInterval = WLANBAP_BE_FLUSH_TIMEOUT; + + // Include the associations MAC addresses + vos_mem_copy( + pBtampCtx->self_mac_addr, + pBtStaOwnMacAddr, /* Where do I get the current MAC address? */ + sizeof(pBtampCtx->self_mac_addr)); + + vos_mem_set( + pBtampCtx->peer_mac_addr, + sizeof(pBtampCtx->peer_mac_addr), + 0); + + // The array of logical links + pBtampCtx->current_log_link_index = 0; /* assigned mod 16 */ + pBtampCtx->total_log_link_index = 0; /* should never be >16 */ + + // Clear up the array of logical links + for (i = 0; i < WLANBAP_MAX_LOG_LINKS ; i++) + { + pLogLinkContext = &pBtampCtx->btampLogLinkCtx[i]; + pLogLinkContext->present = 0; + pLogLinkContext->uTxPktCompleted = 0; + pLogLinkContext->log_link_handle = 0; + } + + + // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt + pBtampCtx->pfnBtampFetchPktCB = NULL; + pBtampCtx->pfnBtamp_STARxCB = NULL; + pBtampCtx->pfnBtampTxCompCB = NULL; + /* Implements the callback for ALL asynchronous events. */ + pBtampCtx->pBapHCIEventCB = NULL; + + /* Set the default for event mask */ + vos_mem_set( + pBtampCtx->event_mask_page_2, + sizeof(pBtampCtx->event_mask_page_2), + 0); + + /* Set the default for location data. */ + pBtampCtx->btamp_Location_Data_Info.loc_options = 0x58; + /* Set the default data transfer mode */ + pBtampCtx->ucDataTrafficMode = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED; + + return VOS_STATUS_SUCCESS; +}/* WLANBAP_CleanCB */ + +/*========================================================================== + + FUNCTION WLANBAP_GetCtxFromStaId + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need either the + BSL context or the BTAMP context from the StaId. + + + DEPENDENCIES + + PARAMETERS + + IN + ucSTAId: The StaId (used by TL, PE, and HAL) + + OUT + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetCtxFromStaId +( + v_U8_t ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + ptBtampHandle *hBtampHandle, /* Handle to return per app btampHandle value in */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + v_PVOID_t *hHddHdl /* Handle to return BSL context in */ +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + + /* For now, we know there is only one application context */ + /* ...and only one physical link context */ + //*hBtampHandle = &((ptBtampContext) btampCtx); + //*hBtampHandle = &btampCtx; + *hBtampHandle = (v_VOID_t*)gpBtampCtx; + + //*hBtampContext = &btampCtx; + *hBtampContext = gpBtampCtx; + + /* Handle to return BSL context in */ + //*hHddHdl = btampCtx.pHddHdl; + *hHddHdl = gpBtampCtx->pHddHdl; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_GetCtxFromStaId */ + +/*========================================================================== + + FUNCTION WLANBAP_GetStaIdFromLinkCtx + + DESCRIPTION + Called inside the BT-AMP PAL (BAP) layer whenever we need the + StaId (or hHddHdl) from the BTAMP context and phy_link_handle. + + + DEPENDENCIES + + PARAMETERS + + IN + hBtampHandle: Handle (pointer to a pointer) to return the + btampHandle value in. + phy_link_handle: physical link handle value. Unique per assoc. + + OUT + pucSTAId: The StaId (used by TL, PE, and HAL) + hHddHdl: Handle to return the BSL context pointer in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_GetStaIdFromLinkCtx +( + ptBtampHandle btampHandle, /* btampHandle value in */ + v_U8_t phy_link_handle, /* phy_link_handle value in */ + v_U8_t *pucSTAId, /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t *hHddHdl /* Handle to return BSL context */ +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Since there is only one physical link...we have stored all + * the physical link specific context in the application context + */ + /* The StaId (used by TL, PE, and HAL) */ + *pucSTAId = pBtampCtx->ucSTAId; + + /* Handle to return BSL context */ + *hHddHdl = pBtampCtx->pHddHdl; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_GetStaIdFromLinkCtx */ + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewPhyLinkCtx + + DESCRIPTION + Called in order to create (or update) a BAP Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + btampHandle: BAP app context handle + phy_link_handle: phy_link_handle from the Command + pHddHdl: BSL passes in its specific context + + OUT + hBtampContext: Handle (pointer to a pointer) to return the + per "Phy Link" ptBtampContext value in. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewPhyLinkCtx +( + ptBtampHandle btampHandle, + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_PVOID_t pHddHdl, /* BSL passes in its specific context */ + ptBtampContext *hBtampContext, /* Handle to return per assoc btampContext value in */ + tWLAN_BAPRole BAPDeviceRole +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + ptBtampContext pBtampCtx = gpBtampCtx; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Read and Set MAC address and SSID to BT-AMP context */ + WLANBAP_ReadMacConfig (pBtampCtx); + + /*------------------------------------------------------------------------ + For now, presume security is not enabled. + ------------------------------------------------------------------------*/ + pBtampCtx->ucSecEnabled = WLANBAP_SECURITY_ENABLED_STATE; + + /*------------------------------------------------------------------------ + Initial Short Range Mode for this physical link is 'disabled' + ------------------------------------------------------------------------*/ + pBtampCtx->phy_link_srm = 0; + + /*------------------------------------------------------------------------ + Clear out the logical links. + ------------------------------------------------------------------------*/ + pBtampCtx->current_log_link_index = 0; + pBtampCtx->total_log_link_index = 0; + + /*------------------------------------------------------------------------ + Now configure the roaming profile links. To SSID and bssid. + ------------------------------------------------------------------------*/ + // We have room for two SSIDs. + pBtampCtx->csrRoamProfile.SSIDs.numOfSSIDs = 1; // This is true for now. + pBtampCtx->csrRoamProfile.SSIDs.SSIDList = pBtampCtx->SSIDList; //Array of two + pBtampCtx->csrRoamProfile.SSIDs.SSIDList[0].SSID.length = 0; + pBtampCtx->csrRoamProfile.SSIDs.SSIDList[0].handoffPermitted = VOS_FALSE; + pBtampCtx->csrRoamProfile.SSIDs.SSIDList[0].ssidHidden = VOS_FALSE; + + pBtampCtx->csrRoamProfile.BSSIDs.numOfBSSIDs = 1; // This is true for now. + pBtampCtx->csrRoamProfile.BSSIDs.bssid = &pBtampCtx->bssid; + + // Now configure the auth type in the roaming profile. To open. + //pBtampCtx->csrRoamProfile.AuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; // open is the default + //pBtampCtx->csrRoamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; // open is the default + pBtampCtx->csrRoamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_RSN_PSK; + pBtampCtx->csrRoamProfile.negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_AES; + + pBtampCtx->phy_link_handle = phy_link_handle; + /* For now, we know there is only one physical link context */ + //*hBtampContext = &btampCtx; + + pBtampCtx->pHddHdl = pHddHdl; + + *hBtampContext = pBtampCtx; + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Btamp Ctxt = %p", pBtampCtx); + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_CreateNewPhyLinkCtx */ + +/*========================================================================== + + FUNCTION WLANBAP_UpdatePhyLinkCtxStaId + + DESCRIPTION + Called to update the STAId value associated with Physical Link "context" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: ptBtampContext to update. + ucSTAId: The StaId (used by TL, PE, and HAL) + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_UpdatePhyLinkCtxStaId +( + ptBtampContext pBtampContext, /* btampContext value in */ + v_U8_t ucSTAId +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + + /*------------------------------------------------------------------------ + Sanity check params + ------------------------------------------------------------------------*/ + if ( NULL == pBtampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP handle value in %s", __func__); + return VOS_STATUS_E_FAULT; + } + + /* The StaId (used by TL, PE, and HAL) */ + pBtampContext->ucSTAId = ucSTAId; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_UpdatePhyLinkCtxStaId */ + +v_U8_t +bapAllocNextLogLinkIndex +( + ptBtampContext pBtampContext, /* Pointer to the per assoc btampContext value */ + v_U8_t phy_link_handle /* I get phy_link_handle from the Command */ +) +{ + return ++(pBtampContext->current_log_link_index) % WLANBAP_MAX_LOG_LINKS; +}/* bapAllocNextLogLinkIndex */ + +/*========================================================================== + + FUNCTION WLANBAP_CreateNewLogLinkCtx + + DESCRIPTION + Called in order to allocate a BAP Logical Link "context" and "index" + + + DEPENDENCIES + + PARAMETERS + + IN + pBtampContext: Pointer to the ptBtampContext value in. + phy_link_handle: phy_link_handle involved + + OUT + pLog_link_handle: return the log_link_handle here + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: NULL pointer; access would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANBAP_CreateNewLogLinkCtx +( + ptBtampContext pBtampContext, /* Pointer to the per assoc btampContext value */ + v_U8_t phy_link_handle, /* I get phy_link_handle from the Command */ + v_U8_t tx_flow_spec[18], + v_U8_t rx_flow_spec[18], + v_U16_t *pLog_link_handle /* Return the logical link index here */ +) +{ +#ifndef BTAMP_MULTIPLE_PHY_LINKS + v_U16_t i; /* Logical Link index */ + tpBtampLogLinkCtx pLogLinkContext; + v_U32_t retval; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + For now, allocate the logical links serially. + ------------------------------------------------------------------------*/ + i = pBtampContext->current_log_link_index + = bapAllocNextLogLinkIndex(pBtampContext, phy_link_handle); + pBtampContext->total_log_link_index++; + + *pLog_link_handle = (i << 8) + ( v_U16_t ) phy_link_handle ; /* Return the logical link index here */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " %s:*pLog_link_handle=%x", __func__,*pLog_link_handle); + + /*------------------------------------------------------------------------ + Evaluate the Tx and Rx Flow specification for this logical link. + ------------------------------------------------------------------------*/ + // Currently we only support flow specs with service types of BE (0x01) + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: pBtampContext value = %p in %s:%d", pBtampContext, __func__, __LINE__ ); +#endif //BAP_DEBUG + + /*------------------------------------------------------------------------ + Now configure the Logical Link context. + ------------------------------------------------------------------------*/ + pLogLinkContext = &(pBtampContext->btampLogLinkCtx[i]); + + /* Extract Tx flow spec into the context structure */ + retval = btampUnpackTlvFlow_Spec((void *)pBtampContext, tx_flow_spec, + WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN, + &pLogLinkContext->btampFlowSpec); + if (retval != BTAMP_PARSE_SUCCESS) + { + /* Flow spec parsing failed, return failure */ + return VOS_STATUS_E_BADMSG; + } + + /* Save the Logical link handle in the logical link context + As of now, only the index is saved as logical link handle since + same is returned in the event. + FIXME: Decide whether this index has to be combined with physical + link handle to generate the Logical link handle. + */ + pLogLinkContext->log_link_handle = *pLog_link_handle; + + // Mark this entry as OCCUPIED + pLogLinkContext->present = VOS_TRUE; + // Now initialize the Logical Link context + pLogLinkContext->btampAC = 1; + // Now initialize the values in the Logical Link context + pLogLinkContext->ucTID = 0; // Currently we only support BE TID (0x00) + pLogLinkContext->ucUP = 0; + pLogLinkContext->uTxPktCompleted = 0; + + return VOS_STATUS_SUCCESS; +#else // defined(BTAMP_MULTIPLE_PHY_LINKS) + +#endif //BTAMP_MULTIPLE_PHY_LINKS +}/* WLANBAP_CreateNewLogLinkCtx */ + +/*========================================================================== + + FUNCTION WLANBAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +) +{ + +}/* WLANBAP_pmcFullPwrReqCB */ + + +/*========================================================================== + + FUNCTION WLANBAP_ReadMacConfig + + DESCRIPTION + This function sets the MAC config (Address and SSID to BT-AMP context + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANBAP_ReadMacConfig +( + ptBtampContext pBtampCtx +) +{ + tANI_U32 len = WNI_CFG_BSSID_LEN; + tHalHandle pMac = NULL; + + /*------------------------------------------------------------------------ + Temporary method to get the self MAC address + ------------------------------------------------------------------------*/ + if (NULL == pBtampCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pBtampCtx is NULL in %s", __func__); + + return; + } + + pMac = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pBtampCtx->pvosGCtx); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pMac is NULL in %s", __func__); + + return; + } + + ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pBtStaOwnMacAddr, &len ); + + VOS_ASSERT( WNI_CFG_BSSID_LEN == len ); + + /* Form the SSID from Mac address */ + VOS_SNPRINTF( pBtStaOwnSsid, WLAN_BAP_SSID_MAX_LEN, + "AMP-%02x-%02x-%02x-%02x-%02x-%02x", + pBtStaOwnMacAddr[0], pBtStaOwnMacAddr[1], pBtStaOwnMacAddr[2], + pBtStaOwnMacAddr[3], pBtStaOwnMacAddr[4], pBtStaOwnMacAddr[5]); + + /*------------------------------------------------------------------------ + Set the MAC address for this instance + ------------------------------------------------------------------------*/ + vos_mem_copy( + pBtampCtx->self_mac_addr, + pBtStaOwnMacAddr, + sizeof(pBtampCtx->self_mac_addr)); + + /*------------------------------------------------------------------------ + Set our SSID value + ------------------------------------------------------------------------*/ + pBtampCtx->ownSsidLen = 21; + vos_mem_copy( + pBtampCtx->ownSsid, + pBtStaOwnSsid, + pBtampCtx->ownSsidLen); +} + +/*========================================================================== + + FUNCTION WLANBAP_NeedBTCoexPriority + + DESCRIPTION + This function will cause a message to be sent to BTC firmware + if a change in priority has occurred. (From AMP's point-of-view.) + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to HAL's + control block can be extracted from its context + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +// Global +static int gBapCoexPriority; + +void +WLANBAP_NeedBTCoexPriority +( + ptBtampContext pBtampCtx, + v_U32_t needCoexPriority +) +{ + tHalHandle pMac = NULL; + tSmeBtAmpEvent btAmpEvent; + + + /*------------------------------------------------------------------------ + Retrieve the pMac (HAL context) + ------------------------------------------------------------------------*/ + pMac = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pBtampCtx->pvosGCtx); + + // Is re-entrancy protection needed for this? + if (needCoexPriority != gBapCoexPriority) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Calling %s with needCoexPriority=%d.", __func__, needCoexPriority); + + gBapCoexPriority = needCoexPriority; + switch ( needCoexPriority) + { + case 0: /* Idle */ + btAmpEvent.btAmpEventType = BTAMP_EVENT_CONNECTION_TERMINATED; + pBtampCtx->btamp_session_on = FALSE; + sme_sendBTAmpEvent(pMac, btAmpEvent); + + break; + + case 1: /* Associating */ + btAmpEvent.btAmpEventType = BTAMP_EVENT_CONNECTION_START; + pBtampCtx->btamp_session_on = TRUE; + sme_sendBTAmpEvent(pMac, btAmpEvent); + + break; + + case 2: /* Post-assoc */ + btAmpEvent.btAmpEventType = BTAMP_EVENT_CONNECTION_STOP; + sme_sendBTAmpEvent(pMac, btAmpEvent); + + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Coexistence priority request: %d", + __func__, needCoexPriority); + } + + } +} + + +/*========================================================================== + + FUNCTION WLANBAP_RxCallback + + DESCRIPTION + This function is called by TL call this function for all frames except for Data frames + + DEPENDENCIES + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to BAP's + control block can be extracted from its context + pPacket Vos packet + frameType Frame type + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANBAP_RxCallback +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pPacket, + WLANTL_BAPFrameEnumType frameType +) +{ + ptBtampContext pBtampCtx = NULL; + + pBtampCtx = VOS_GET_BAP_CB(pvosGCtx); + if ( NULL == pBtampCtx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on WLANBAP_Start"); + return VOS_STATUS_E_FAULT; + } + + switch (frameType) + { + case WLANTL_BT_AMP_TYPE_LS_REQ: /* Fall through */ + case WLANTL_BT_AMP_TYPE_LS_REP: + { + /* Link supervision frame, process this frame */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: link Supervision packet received over TL: %d, => BAP", + __func__, frameType); + WLANBAP_RxProcLsPkt((ptBtampHandle)pBtampCtx, + pBtampCtx->phy_link_handle, + frameType, + pPacket); + break; + } + + case WLANTL_BT_AMP_TYPE_AR: /* Fall through */ + case WLANTL_BT_AMP_TYPE_SEC: + { + /* Call the RSN callback handler */ + bapRsnRxCallback (pvosGCtx, pPacket); + break; + } + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid frametype from TL: %d, => BAP", + __func__, frameType); + } + + return ( VOS_STATUS_SUCCESS ); +} diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.c b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.c new file mode 100644 index 000000000000..fcbc6e494a2b --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.c @@ -0,0 +1,1619 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xAuthRsnFsm.c $ + * + * Contains definitions for the RSN EAPOL-Key FSM on the + * authenticator side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_types.h" +#include "bapRsnSsmServices.h" +#include "bapRsnSsmEapol.h" +#include "bapRsnErrors.h" +#include "bapInternal.h" +#include "bapRsn8021xFsm.h" +#include "bapRsn8021xAuthFsm.h" +#include "vos_utils.h" +#include "vos_memory.h" +#include "vos_timer.h" +#include "bapRsnTxRx.h" +#include "bapRsnSsmAesKeyWrap.h" +#include "btampFsm.h" + +// The different states that this FSM transitions through +#define DISCONNECT 0 +#define DISCONNECTED 1 +#define INITIALIZE 2 +#define AUTHENTICATION 3 +#define AUTHENTICATION_2 4 +#define GET_PSK 5 +#define GET_EAP_KEY 6 +#define PTK_START 7 +#define PTK_INIT_NEGO 8 +#define PTK_INIT_NEGO_TX 9 +#define PTK_INIT_DONE 10 +#define UPDATE_KEYS_REQ 11 +#define INTEG_FAILURE 12 +#define KEY_UPDATE 13 +#define NUM_STATES (KEY_UPDATE + 1) + + + +static tAuthRsnFsmConsts authConsts = { 2000, 3 }; //timeout, retry limit +static v_U8_t aniSsmIeRsnOui[] = ANI_SSM_IE_RSN_OUI; + + +/************************************** + * Static functions in this module + **************************************/ + +static +int zeroOutPtk(tAuthRsnFsm *fsm); +static +int stopAllTimers(tAuthRsnFsm *fsm); + +static +int checkMic(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int checkLocalReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); +static +int checkPeerReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static int checkInfoElement(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int derivePtk(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + + +static int checkTransition(tAuthRsnFsm *fsm, void *arg); + +static int +gotoStateInit(tAuthRsnFsm *fsm); + +static void msg2TimerCallback( void * ); +static void msg4TimerCallback( void * ); + +static int authRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ); +static int authRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ); + +/******************************** + * Functions Forward Declarations + ********************************/ + +int authRsnAuthStartEventHandler( tAuthRsnFsm *fsm ); +int authRsnAuthDisconEventHandler( tAuthRsnFsm *fsm ); + +/************************* + * The exported functions + *************************/ + +/** + * authRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param consts the various constant values needed by this FSM + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmInit(tAuthRsnFsmConsts *constsIn) +{ + // TODO: Read the constants in from config + // authConsts = *constsIn; + authConsts.timeoutPeriod = 2000; //ms + authConsts.maxTries = 3; + + return ANI_OK; +} + +/** + * authRsnFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an RSN key FSM instance for + * the given STA context. + * + * @parm staCtx the STA context whose instance is being created + * @param pskBased pass in eANI_BOOLEAN_TRUE is this STA is to be + * authenticated based on a pre-shared key as opposed to EAP. + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmCreate(tBtampContext *ctx) +{ + int retVal = ANI_OK; + tAuthRsnFsm *fsm = &ctx->uFsm.authFsm; + + // First, clear everything out + vos_mem_zero( fsm, sizeof(tAuthRsnFsm)); + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterTxRxCallbacks( authRsnTxCompleteHandler, + authRsnRxFrameHandler ) ) ) + { + return ANI_ERROR; + } + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterRxCallback( ctx->pvosGCtx ) ) ) + { + return ANI_ERROR; + } + + // Allocate the station context + fsm->staCtx = (tStaContext *)vos_mem_malloc( sizeof(tStaContext) ); + if (fsm->staCtx == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + // Clear out the station context + vos_mem_zero( fsm->staCtx, sizeof(tStaContext) ); + + fsm->ctx = ctx; + fsm->staCtx->authRsnFsm = fsm; + //Only support CCMP + fsm->staCtx->pwCipherType = eCSR_ENCRYPT_TYPE_AES; + + if( !VOS_IS_STATUS_SUCCESS( vos_timer_init( &fsm->msg2Timer, VOS_TIMER_TYPE_SW, msg2TimerCallback, fsm ) ) ) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + if( !VOS_IS_STATUS_SUCCESS( vos_timer_init( &fsm->msg4Timer, VOS_TIMER_TYPE_SW, msg4TimerCallback, fsm ) ) ) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE ); + if (retVal != ANI_OK) + { + VOS_ASSERT( 0 ); + goto error; + } + + aniAsfPacketAllocate(&fsm->staCtx->pmk); + if (fsm->staCtx->pmk == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + aniAsfPacketAllocateExplicit(&fsm->staCtx->ieSta, + RSN_IE_MAX_PACKET_SIZE, + RSN_IE_HEADER_SIZE ); + if (fsm->staCtx->ieSta == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + fsm->cryptHandle = 0; + if( !VOS_IS_STATUS_SUCCESS( vos_crypto_init( &fsm->cryptHandle ) ) ) + { + retVal = ANI_E_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + fsm->currentState = INITIALIZE; + gotoStateInit(fsm); + + //We can call this function here because it is connected at this time + authRsnFsmProcessEvent( fsm, RSN_FSM_AUTH_START, NULL ); + + return ANI_OK; + + error: + authRsnFsmFree(ctx); + + return retVal; + +} + +/** + * authRsnFsmFree + * + * FUNCTION + * Frees a previously allocated RSN Key FSM in a STA context. If the + * RSN Key FSM is not yet allocated, then this is an error. + * + * @param ctx the STA context whose FSM instance is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmFree(tBtampContext *ctx) +{ + tAuthRsnFsm *fsm = &ctx->uFsm.authFsm; + + VOS_ASSERT(fsm); + + if( fsm->cryptHandle) + { + vos_crypto_deinit( fsm->cryptHandle ); + } + + bapRsnClearTxRxCallbacks(); + + if ( fsm->staCtx ) + { + fsm->staCtx->authRsnFsm = NULL; + } + + if ( VOS_TIMER_STATE_UNUSED != fsm->msg2Timer.state ) vos_timer_destroy( &fsm->msg2Timer ); + if ( VOS_TIMER_STATE_UNUSED != fsm->msg4Timer.state ) vos_timer_destroy( &fsm->msg4Timer ); + + if (fsm->lastEapol) + { + aniAsfPacketFree(fsm->lastEapol); + fsm->lastEapol = NULL; + } + + if( fsm->staCtx ) + { + if( fsm->staCtx->pmk ) + { + aniAsfPacketFree( fsm->staCtx->pmk ); + fsm->staCtx->pmk = NULL; + } + vos_mem_free(fsm->staCtx); + fsm->staCtx = NULL; + } + + vos_mem_zero( fsm, sizeof(tAuthRsnFsm) ); + + return ANI_OK; +} + +/** + * authRsnFsmProcessEvent + * + * FUNCTION + * Passes an event to the RSN key FSM instance for immediate processing. + * + * @param fsm the RSN Key FSM instance + * @param eventId the AAG event to process + * @param arg an optional argument for this event + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmProcessEvent(tAuthRsnFsm *fsm, tRsnFsmEvent eventId, void *arg) +{ + VOS_ASSERT(fsm); + + switch (eventId) { + case RSN_FSM_TIMER_EXPIRED: + // Proceed straight to checkTransition + break; + case RSN_FSM_AUTH_START: + fsm->authReq = eANI_BOOLEAN_TRUE; + authRsnAuthStartEventHandler(fsm); + break; + case RSN_FSM_EAPOL_FRAME_AVAILABLE: + fsm->eapolAvail = eANI_BOOLEAN_TRUE; + break; + case RSN_FSM_DISCONNECT: + fsm->disconnect = eANI_BOOLEAN_TRUE; + authRsnAuthDisconEventHandler(fsm); + break; + case RSN_FSM_INTEG_FAILED: + fsm->integFailed = eANI_BOOLEAN_TRUE; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unknown event for Auth RSN Key Fsm: %d\n", eventId); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + break; + } + + checkTransition(fsm, arg); + + return ANI_OK; +} + + +int +authRsnAuthStartEventHandler(tAuthRsnFsm *fsm) +{ + static v_U8_t btampStaRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 }; + // Copy required info + vos_mem_copy( &fsm->staCtx->authMac, fsm->ctx->self_mac_addr, 6); + vos_mem_copy( &fsm->staCtx->suppMac, fsm->ctx->peer_mac_addr, 6); + aniAsfPacketAppendBuffer( fsm->staCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length); + + aniAsfPacketAppendBuffer( fsm->staCtx->ieSta, btampStaRSNIE, sizeof(btampStaRSNIE)); + return ANI_OK; +} + +int +authRsnAuthDisconEventHandler(tAuthRsnFsm *fsm) +{ + // Free Stactx .? + return ANI_OK; +} + +/*********************** + * The static functions + ***********************/ + +static int +gotoStateInit(tAuthRsnFsm *fsm) +{ + fsm->currentState = INITIALIZE; + + // TODO: Move this to a global position which applies to WEP as + // well + //initGlobalKeys = eANI_BOOLEAN_FALSE; + + fsm->authReq = eANI_BOOLEAN_FALSE; + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + fsm->disconnect = eANI_BOOLEAN_FALSE; + fsm->integFailed = eANI_BOOLEAN_FALSE; + + fsm->numTries = 0; + + // Create two replay counter's..one for our requests, and another + // for STA's requests. Initialize the first one randomly. + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->staCtx->localReplayCtr, + ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->staCtx->peerReplayCtr, + ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + + return ANI_OK; +} + +static int +gotoStateAuthentication(tAuthRsnFsm *fsm) +{ + fsm->currentState = AUTHENTICATION; + + zeroOutPtk(fsm); + fsm->authReq = eANI_BOOLEAN_FALSE; + + checkTransition(fsm, NULL); // UCT rule + + return ANI_OK; +} + +static int +gotoStateAuthentication2(tAuthRsnFsm *fsm) +{ + fsm->currentState = AUTHENTICATION_2; + + if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( fsm->cryptHandle, fsm->aNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "gotoStateAuthentication2 fail to get random number. Disconnect\n" ); + bapAuthDisconnect( fsm->ctx ); + return ANI_ERROR; + } + fsm->numTries = 0; + + checkTransition(fsm, NULL); // UCT rule + + return ANI_OK; +} + + +static int +gotoStateGetPsk(tAuthRsnFsm *fsm) +{ + //This is simply a transaction because we already have the PMK. We always do. + fsm->currentState = GET_PSK; + + fsm->numTries = 0; + + checkTransition(fsm, NULL); + + return ANI_OK; +} + +static int +gotoStatePtkStart(tAuthRsnFsm *fsm) +{ + tAniEapolRsnKeyDesc txDesc; + int retVal; + + fsm->msg2TimeOut = VOS_FALSE; + fsm->currentState = PTK_START; + + // Create a new packet if we don't have one to retransmit + //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) +#if 0 + if( fsm->lastEapol ) + { + aniAsfPacketFree( fsm->lastEapol ); + fsm->lastEapol = NULL; + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE ); +#endif + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE); + //} + // if (1) + //{ + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + else { + return ANI_E_ILLEGAL_ARG; + } + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.ackFlag = eANI_BOOLEAN_TRUE; + + // The other fields... + txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType); + aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter); + vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce)); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->staCtx->suppMac, + fsm->staCtx->authMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + NULL, 0); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } +#if 0 + } + else { + retransmit = eANI_BOOLEAN_TRUE; + } +#endif + + if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_OK; + } + else + { + //we fail to send the eapol frame disconnect + bapAuthDisconnect( fsm->ctx ); + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStatePtkInitNego(tAuthRsnFsm *fsm, void *arg) +{ + fsm->currentState = PTK_INIT_NEGO; + + // Replay counter will be automatically updated when we create a + // new packet + + fsm->numTries = 0; + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE); + + checkTransition(fsm, arg); + + return ANI_OK; +} + +// Use this only with trusted IE like the one we generated locally +static int +getRsnIeFromAdvertizedIes(tAuthRsnFsm *fsm, v_U8_t **rsnIe) +{ + int retVal = ANI_E_ILLEGAL_ARG; + v_U8_t *ptr = fsm->advertizedRsnIe; + + if (*ptr == ANI_SSM_IE_RSN_ELEM_ID) + { + retVal = *(ptr + 1) + 2; // The L field from the TLV + 2B TL + *rsnIe = ptr; + } + + return retVal; +} + +// Use this only with trusted IE like the one we generated locally +static void +addPad( + v_U8_t *dataBytes, + int dataLen, + int padLen) +{ + int i; + + // The first byte of padding is 0xdd. The rest are 0x00's + // See 802.11i section 8.5.2 subsection "Key Data Encapsulation" + + for ( i=dataLen ; i < dataLen+padLen; i++) + { + if ( i == dataLen ) + { + dataBytes[i] = 0xdd; + } + else { + dataBytes[i] = 0x00; + } + } + + return; +} + +/** + * aagAppendGroupKeyForRsn + * + * Appends the group key to the packet in the RSN key encapulation format. + * + * @param packet - the packet to append to + * @param radioId - the radio whose group key needs to be appended + * + * @return ANI_OK if the operation succeeds + */ +#define STATIC_WEP_KEY_LEN 16 +#define GROUP_KEY_ID 0 +#define ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID 0xDD +#define ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID 1 + +int +aagAppendGroupKeyForRsn(tAniPacket *packet) +{ +#if 0 + tAniPacket *groupKey = NULL; +#else + tANI_U8 groupKey[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; +#endif + tANI_U8 *groupKeyBytes = NULL; + tANI_U8 *lenPtr = NULL; + tANI_U8 *endPtr = NULL; + int groupKeyLen; + int retVal; + +#if 0 + groupKey = AAG_GROUP_KEY(radioId); + if (groupKey == NULL) { + ANI_AAG_LOG_E("Group key is not yet set on radio %d, id %d!", + radioId, AAG_GROUP_KEY_ID(radioId)); + assert(0 && "Group key is still NULL!"); + return ANI_E_FAILED; + } + + groupKeyLen = aniAsfPacketGetBytes(groupKey, &groupKeyBytes); + CHECK_NO_ERROR(groupKeyLen); + + if (aagConfig.logLevel >= LOG_INFO) { + ANI_AAG_LOG_D("Will encapsulate group key bytes %s", + aniAsfHexStr(groupKeyBytes, groupKeyLen)); + } +#else + groupKeyBytes = groupKey; + + groupKeyLen = STATIC_WEP_KEY_LEN; +#endif + + /* + * Add the key data encapsulation needed for RSN/WPA2 + */ + + // The IE ID + retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID); + //CHECK_NO_ERROR(retVal); + + // Obtain the position for the length + aniAsfPacketGetBytesFromTail(packet, &lenPtr); + + // Write out a dummy length - we'll fill this in later. It will be + // 6 bytes more than the length of the GTK + retVal = aniAsfPacketAppend8(packet, 0); + //CHECK_NO_ERROR(retVal); + + // Copy the RSN OUI + retVal = aniAsfPacketAppendBuffer(packet, aniSsmIeRsnOui, sizeof(aniSsmIeRsnOui)); + //CHECK_NO_ERROR(retVal); + + // Indicate that the key type is group key + retVal = aniAsfPacketAppend8(packet, ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID); + //CHECK_NO_ERROR(retVal); + + // Copy the key-id to the first two bits of the next byte + // Copy the Tx bit the third bit of the same byte + // (Here, I assume the Group Key is to be used for both STA Tx and Rx) + retVal = aniAsfPacketAppend8( + packet, + GROUP_KEY_ID ); + //AAG_GROUP_KEY_ID(radioId) ); + //CHECK_NO_ERROR(retVal); + + retVal = aniAsfPacketMoveRight(packet, 1); // Reserved bits (1 byte) + //CHECK_NO_ERROR(retVal); + + // Copy the real key bytes + retVal = aniAsfPacketAppendBuffer(packet, groupKeyBytes, groupKeyLen); + //CHECK_NO_ERROR(retVal); + + // Calculate and enter the length of the entire encoding + aniAsfPacketGetBytesFromTail(packet, &endPtr); + *lenPtr = endPtr - (lenPtr + 1) ; // subtract one to avoid tail + + return retVal; +} + +static int +gotoStatePtkInitNegoTx(tAuthRsnFsm *fsm) +{ + tAniEapolRsnKeyDesc txDesc; + v_BOOL_t retransmit = eANI_BOOLEAN_FALSE; + v_U8_t *rsnWpaIe = NULL; + int rsnWpaIeLen; + static tAniPacket *keyData; + // The longest length...the extra 8 bytes account for RSN key data + // encapsulation + v_U8_t paddedGroupKeyEncaps[1024]; + int padLen = 0; + v_U8_t *groupKeyBytes; + int groupKeyLen; + v_U8_t *wrappedKey = NULL; + // Variables used for RC4 GTK wrap + //v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE]; + //v_U32_t keyIvLsb; + int retVal = 0; + + //invalidate this + fsm->msg4TimeOut = VOS_FALSE; + fsm->currentState = PTK_INIT_NEGO_TX ; + + if (keyData == NULL) + { + // Allocate the packet the first time around that you enter + retVal = aniAsfPacketAllocateExplicit(&keyData, 1024, 10); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + } + else { + // Just empty out the packet + aniAsfPacketEmptyExplicit(keyData, 10); + } + + do + { + // Create a new EAPOL frame if we don't have one to retransmit + //if (aniAsfPacketGetLen(fsm->lastEapol) == 0) +#if 0 + if( fsm->lastEapol ) + { + aniAsfPacketFree( fsm->lastEapol ); + fsm->lastEapol = NULL; + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE ); +#endif + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE); + // } + + if (1) + { + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + else { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_RC4; + } + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.installFlag = eANI_BOOLEAN_TRUE; + txDesc.info.ackFlag = eANI_BOOLEAN_TRUE; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + + txDesc.keyLen = aagGetKeyMaterialLen(fsm->staCtx->pwCipherType); + aniSsmReplayCtrNext(fsm->staCtx->localReplayCtr, txDesc.replayCounter); + vos_mem_copy(txDesc.keyNonce, fsm->aNonce, sizeof(txDesc.keyNonce)); + + // Add the RSN IE (but not any WPA IE) + rsnWpaIeLen = getRsnIeFromAdvertizedIes(fsm, &rsnWpaIe); + + if( !ANI_IS_STATUS_SUCCESS( rsnWpaIeLen) ) break; + + retVal = aniAsfPacketAppendBuffer(keyData, rsnWpaIe, rsnWpaIeLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + // Add the RSN group key encapsulation + retVal = aagAppendGroupKeyForRsn ( keyData ); + + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + groupKeyLen = aniAsfPacketGetBytes(keyData, &groupKeyBytes); + if( !ANI_IS_STATUS_SUCCESS( groupKeyLen ) ) + { + retVal = ANI_E_FAILED; + break; + } + + txDesc.info.secureFlag = eANI_BOOLEAN_TRUE; + txDesc.info.encKeyDataFlag = eANI_BOOLEAN_TRUE; + + if ( fsm->staCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES ) + { + /* + * Use the AES key wrap algorithm if either one of the pairwise + * key or the group key is an AES key. + * + * If the key being sent is not a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then pad it with + * zeroes. e.g., if we are sending a WEP key of 5 or 13 + * bytes. + */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "AES Key Wrap invoked. groupKeyLen = %d", groupKeyLen); + + padLen = groupKeyLen % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + if (padLen != 0) { + padLen = ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - padLen; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Before AES Key Wrap: padLen = %d", padLen); + + if (groupKeyLen + padLen > sizeof(paddedGroupKeyEncaps)) { +#if 0 + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Cannot encode group key encapsulation of len %d and cipher type %s " + "to send to %s %s (aid %d, radio %d, user %s)", + groupKeyLen, + aniSsmIntGetCipherStr(AAG_GROUP_CIPHER(fsm->ctx->radioId)), + (fsm->ctx->bpIndicator ? "BP" : "STA"), + aniAsfHexStr(fsm->ctx->suppMac, sizeof(tAniMacAddr)), + fsm->ctx->aid, + fsm->ctx->radioId, + aagGetStaUserId(fsm->ctx)); +#endif + retVal = ANI_E_FAILED; + } + // OK, after you compute the pad length, you need to + // add the padding - 0xdd followed by 0x00's + addPad( groupKeyBytes , groupKeyLen , padLen ); + // add the padding length + groupKeyLen += padLen; + // IMMEDIATELY adjust the packet size to reflect the pad + aniAsfPacketMoveRight(keyData, padLen); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) break; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Before AES Key Wrap: padded groupKeyLen = %d", groupKeyLen); + + retVal = aniSsmAesKeyWrap(fsm->cryptHandle, groupKeyBytes, groupKeyLen, + fsm->staCtx->ptk + ANI_EAPOL_KEY_RSN_MIC_SIZE, + ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE, + &wrappedKey); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) break; + // This doesn't work... + //groupKeyBytes = wrappedKey; + //groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + // ...here is the right way to do it + // Add the length of the prepended IV A[0] + if (NULL == wrappedKey) + { + break; + } + groupKeyLen += ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + vos_mem_copy( groupKeyBytes, wrappedKey, groupKeyLen); + // Free the array used to hold the wrapped key + if (wrappedKey) vos_mem_free( wrappedKey); + // IMMEDIATELY adjust the packet size to reflect the IV + aniAsfPacketMoveRight(keyData, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + } + else { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth RC4 Key Wrap invoked. groupKeyLen = %d", groupKeyLen); + } + txDesc.keyDataLen = aniAsfPacketGetBytes(keyData, &txDesc.keyData); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->staCtx->suppMac, + fsm->staCtx->authMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->staCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) break; + } + else { + retransmit = eANI_BOOLEAN_TRUE; + } + + if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_OK; + } + else + { + //we fail to send the eapol frame disconnect + bapAuthDisconnect( fsm->ctx ); + retVal = ANI_ERROR; + } + + }while( 0 ); + + return retVal; +} + +static int +gotoStatePtkInitDone(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + int retVal; + tAniEapolRsnKeyDesc *rxDesc; + tCsrRoamSetKey setKeyInfo; + + fsm->currentState = PTK_INIT_DONE; + + rxDesc = data->keyDesc; + + vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) ); + setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES; + setKeyInfo.keyDirection = eSIR_TX_RX; + vos_mem_copy( setKeyInfo.peerMac, fsm->staCtx->suppMac, sizeof( tAniMacAddr ) ); + setKeyInfo.paeRole = 0; //this is a supplicant + setKeyInfo.keyId = 0; //always + setKeyInfo.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->staCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN ); + //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one. + if( VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) ) + { + //Done + aniAsfPacketEmptyExplicit(fsm->lastEapol, EAPOL_TX_HEADER_SIZE); + retVal = ANI_OK; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Auth: gotoStatePtkInitDone fail to set key\n" ); + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStateUpdateKeysReq(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + tAniEapolRsnKeyDesc *rxDesc; + + fsm->currentState = UPDATE_KEYS_REQ; + + rxDesc = data->keyDesc; + + aniSsmReplayCtrUpdate(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter); + + checkTransition(fsm, data); + + return ANI_OK; +} + +static int +gotoStateIntegFailure(tAuthRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo) +{ + fsm->currentState = INTEG_FAILURE; + + fsm->integFailed = eANI_BOOLEAN_FALSE; + + checkTransition(fsm, NULL); // UCT + + return ANI_OK; +} + +static int +gotoStateKeyUpdate(tAuthRsnFsm *fsm) +{ + fsm->currentState = KEY_UPDATE; + + if( VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes(fsm->cryptHandle, fsm->aNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) ) ) + { + + // Replay counter will be automatically updated when we create a + // new packet + + checkTransition(fsm, NULL); // UCT + + return ANI_OK; + } + return ANI_ERROR; +} + +static int +gotoStateDisconnect(tAuthRsnFsm *fsm) +{ + fsm->currentState = DISCONNECT; + + //What else do we need to clean up? Or BAP will call our vleanup function? + + // FSM does not exist after this... + bapAuthDisconnect( fsm->ctx ); + + return ANI_OK; +} + +static +int zeroOutPtk(tAuthRsnFsm *fsm) +{ + return ANI_OK; +} + +static +int stopAllTimers(tAuthRsnFsm *fsm) +{ + vos_timer_stop( &fsm->msg2Timer ); + vos_timer_stop( &fsm->msg4Timer ); + + return ANI_OK; +} + +static +int derivePtk(tAuthRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + v_U32_t prfLen; + tAniEapolRsnKeyDesc *rxDesc; + + VOS_ASSERT(fsm->staCtx->pmk); + + switch (fsm->staCtx->pwCipherType) + { + case eCSR_ENCRYPT_TYPE_AES: + prfLen = AAG_RSN_PTK_PRF_LEN_CCMP; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth cannot generate PTK for invalid algorithm %d\n", + fsm->staCtx->pwCipherType); + return ANI_E_ILLEGAL_ARG; + break; + }; + + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + return aagPtkPrf(fsm->cryptHandle, + fsm->staCtx->ptk, + prfLen, + fsm->staCtx->pmk, + fsm->staCtx->authMac, + fsm->staCtx->suppMac, + fsm->aNonce, + rxDesc->keyNonce); +} + +static int +checkMic(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal; + + retVal = aniEapolKeyCheckMic(fsm->cryptHandle, + data->eapolFrame, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + data->keyDesc, + fsm->staCtx->ptk, + CSR_AES_KEY_LEN); + + if (retVal == ANI_E_MIC_FAILED) + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth failed EAPOL-MIC check in pairwise key exchange!\n"); + } + + return retVal; +} + +static int +checkLocalReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal = ANI_E_NULL_VALUE; + int cmp; + tAniEapolRsnKeyDesc *rxDesc; + + rxDesc = data->keyDesc; + if( rxDesc ) + { + cmp = aniSsmReplayCtrCmp(fsm->staCtx->localReplayCtr, rxDesc->replayCounter); + + // The STA should have sent back the same replay ctr as in our request + if (cmp != 0) + { + retVal = ANI_E_REPLAY_CHECK_FAILED; + } + else + { + retVal = ANI_OK; + } + } + + return retVal; +} + +static +int checkPeerReplayCounter(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal = ANI_E_NULL_VALUE; + int cmp; + tAniEapolRsnKeyDesc *rxDesc; + + rxDesc = data->keyDesc; + if( rxDesc ) + { + cmp = aniSsmReplayCtrCmp(fsm->staCtx->peerReplayCtr, rxDesc->replayCounter); + + // The STA should have sent a newer replay ctr than its old + // request. The first message is exempted from the check. + if (fsm->staCtx->pastFirstPeerRequest && cmp >= 0) + { + retVal = ANI_E_REPLAY_CHECK_FAILED; + } + + fsm->staCtx->pastFirstPeerRequest = eANI_BOOLEAN_TRUE; + } + + return retVal; +} + +static int checkInfoElement(tAuthRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + tAniEapolRsnKeyDesc *desc; + v_U8_t *ieStaBytes; + int ieStaLen; + + desc = (tAniEapolRsnKeyDesc *) data->keyDesc; + if( desc ) + { + ieStaLen = aniAsfPacketGetBytes(fsm->staCtx->ieSta, &ieStaBytes); + if( !ANI_IS_STATUS_SUCCESS( ieStaLen ) ) + { + return ieStaLen; + } + + if ((desc->keyDataLen != ieStaLen) || + ( !vos_mem_compare(desc->keyData, ieStaBytes, ieStaLen-2) )) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth STA sent inconsistent RSN IE!\n"); + return ANI_E_FAILED; + } + // Copy RSN IE + //vos_mem_copy(fsm->advertizedRsnIe, desc->keyData, ieStaLen); + vos_mem_copy(fsm->advertizedRsnIe, ieStaBytes, ieStaLen); + + return ANI_OK; + } + else + { + return ANI_E_NULL_VALUE; + } + +} + +static +int checkTransition(tAuthRsnFsm *fsm, void *arg) +{ + int retVal; + tAniEapolKeyAvailEventData *data; + tAniEapolRsnKeyDesc *rxDesc; + tSirMicFailureInfo *micFailureInfo; + + if (fsm->disconnect) + { + stopAllTimers(fsm); + gotoStateDisconnect(fsm); + return ANI_OK; + } + + if (fsm->authReq) + { + stopAllTimers(fsm); + gotoStateAuthentication(fsm); + return ANI_OK; + } + + switch (fsm->currentState) + { + case INITIALIZE: + break; + case AUTHENTICATION: + gotoStateAuthentication2(fsm); + break; + case AUTHENTICATION_2: + gotoStateGetPsk( fsm ); + break; + case GET_PSK: + //We always have PMK otherwise BAP won't let us here + gotoStatePtkStart(fsm); + break; + case PTK_START: + if ( fsm->eapolAvail ) + { + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + retVal = checkLocalReplayCounter(fsm, data); + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + retVal = derivePtk(fsm, data); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth derivePtk failed with code %d!\n", retVal); + return retVal; + } + retVal = checkMic(fsm, data); + if (retVal != ANI_OK) + { + bapAuthDisconnect( fsm->ctx ); + return retVal; + } + retVal = gotoStatePtkInitNego(fsm, arg); + } + else if ( fsm->msg2TimeOut ) + { + if (fsm->numTries <= authConsts.maxTries) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth Retransmitting EAPOL-Key Msg1\n"); + // Stay in the same state but repeat actions + gotoStatePtkStart(fsm); + } + else { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth failed to recv EAPOL-Key Msg2 " + "Disconnecting...\n"); + + gotoStateDisconnect(fsm); + } + } + break; + case PTK_INIT_NEGO: + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + retVal = checkInfoElement(fsm, data); + if (retVal != ANI_OK) + { + gotoStateDisconnect(fsm); + } + else { + gotoStatePtkInitNegoTx(fsm); + } + break; + case PTK_INIT_NEGO_TX: + if (fsm->eapolAvail) + { + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + retVal = checkLocalReplayCounter(fsm, data); + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + retVal = checkMic(fsm, data); + if (retVal != ANI_OK) + { + bapAuthDisconnect( fsm->ctx ); + return retVal; + } + retVal = gotoStatePtkInitDone(fsm, data); + } else if ( fsm->msg4TimeOut ) + { + if (fsm->numTries <= authConsts.maxTries) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth retransmitting EAPOL-Key Msg3 \n"); + // Stay in the same state but repeat actions + gotoStatePtkInitNegoTx(fsm); + } + else { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth failed to recv EAPOL-Key Msg4 " + "Disconnecting...\n" ); + + gotoStateDisconnect(fsm); + } + } + break; + case PTK_INIT_DONE: + if (fsm->eapolAvail) { + + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.requestFlag) + { + + retVal = checkPeerReplayCounter(fsm, data); + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + + retVal = checkMic(fsm, data); + if (retVal != ANI_OK) + { + bapAuthDisconnect( fsm->ctx->pvosGCtx ); + return retVal; + } + + retVal = gotoStateUpdateKeysReq(fsm, arg); + } + } + else if (fsm->integFailed) { + + micFailureInfo = (tSirMicFailureInfo *) arg; + gotoStateIntegFailure(fsm, arg); + + } + break; + case UPDATE_KEYS_REQ: + + if (NULL == arg) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "arg is NULL, exiting checkTransition()"); + return ANI_E_FAILED; + } + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.errorFlag) + { + + /* + * This was generated by a unicast packet sent from the AP to the STA/BP. + * The TX address is the AP's address. The src address is lost. + * If the STA is a BP, then the true dst is lost. We will treat + * the dst field as the address of the reporter of the MIC failure. + */ + + micFailureInfo = (tSirMicFailureInfo *) vos_mem_malloc( sizeof(tSirMicFailureInfo) ); + if( NULL == micFailureInfo ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Fail to allocate memory for AuthRsnFsm: %d\n", + fsm->currentState); + return ANI_E_MALLOC_FAILED; + } + + vos_mem_copy(micFailureInfo->taMacAddr, fsm->staCtx->authMac, sizeof(tAniMacAddr)); + vos_mem_copy(micFailureInfo->dstMacAddr, fsm->staCtx->suppMac, sizeof(tAniMacAddr)); + micFailureInfo->multicast = eANI_BOOLEAN_FALSE; + // Copy whatever sequence number came in the EAPOL-key message + vos_mem_copy(micFailureInfo->TSC, rxDesc->keyRecvSeqCounter, SIR_CIPHER_SEQ_CTR_SIZE); + gotoStateIntegFailure(fsm, micFailureInfo); + vos_mem_free(micFailureInfo); + } + else { + // TBD: Untested. Why are local aNonce and local replyCtr not incremented in spec? + gotoStatePtkStart(fsm); + } + break; + case INTEG_FAILURE: + gotoStateKeyUpdate(fsm); + break; + case KEY_UPDATE: + gotoStatePtkStart(fsm); + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Nothing to do in this state for AuthRsnFsm: %d\n", + fsm->currentState); + // Catch all for states that need no change: + // assert(eANI_BOOLEAN_FALSE && "Illegal AuthRsnFsm state!"); + return ANI_E_FAILED; + } + + return ANI_OK; +} + + +static void msg2TimerCallback( void *pv ) +{ + tAuthRsnFsm *fsm = (tAuthRsnFsm *)pv; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return; + } + + //Only when waiting for msg2 + if( PTK_START == fsm->currentState ) + { + fsm->msg2TimeOut = eANI_BOOLEAN_TRUE; + } + //We may need to synchronize this call + authRsnFsmProcessEvent( fsm, RSN_FSM_TIMER_EXPIRED, NULL ); +} + +static void msg4TimerCallback( void *pv ) +{ + tAuthRsnFsm *fsm = (tAuthRsnFsm *)pv; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return; + } + + //Only when we are waiting for msg4 + if( PTK_INIT_NEGO_TX == fsm->currentState ) + { + fsm->msg4TimeOut = eANI_BOOLEAN_TRUE; + } + //We may need to synchronize this call + authRsnFsmProcessEvent( fsm, RSN_FSM_TIMER_EXPIRED, NULL ); +} + + +// +//This function alwasy assume the incoming vos_packet is 802_3 frame. +static int authRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ) +{ + int retVal = ANI_ERROR; + tAniPacket *pAniPacket; + tBtampContext *ctx; + tAuthRsnFsm *fsm; + + /* Validate params */ + if ((pvosGCtx == NULL) || (NULL == pPacket)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return retVal; + } + + ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return retVal; + } + + fsm = &ctx->uFsm.authFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return retVal; + } + + do + { + //ToDO: We need to synchronize this. For now, use the simplest form, drop the packet comes later. + if( fsm->fReceiving ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " ******authRsnRxFrameHandler receive eapol packet while processing. Drop the new comer\n" ); + break; + } + fsm->fReceiving = VOS_TRUE; + retVal = bapRsnFormPktFromVosPkt( &pAniPacket, pPacket ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + //Now we can process the eapol frame + //handler will free the pAniPacket + bapRsnEapolHandler( fsm, pAniPacket, VOS_TRUE ); + }while( 0 ); + + fsm->fReceiving = VOS_FALSE; + vos_pkt_return_packet( pPacket ); + + return retVal; +} + + +static int authRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) +{ + tBtampContext *ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + tAuthRsnFsm *fsm; + + vos_pkt_return_packet( pPacket ); + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return ANI_ERROR; + } + + fsm = &ctx->uFsm.authFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return ANI_ERROR; + } + + if(!VOS_IS_STATUS_SUCCESS( retStatus ) ) + { + //No need to do anything. Retransmit is handled by timeout + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth: TL Tx complete with error %d current state is %d \n", retStatus, fsm->currentState ); + } + if( PTK_START == fsm->currentState ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " Auth: start msg2 timer\n" ); + //Start msg2Timer + fsm->numTries++; + vos_timer_stop( &fsm->msg2Timer ); + vos_timer_start(&fsm->msg2Timer, authConsts.timeoutPeriod); + } + else if( ( PTK_INIT_NEGO == fsm->currentState ) || + ( PTK_INIT_NEGO_TX == fsm->currentState ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + " Auth: start msg4 timer\n" ); + fsm->numTries++; + vos_timer_stop( &fsm->msg4Timer ); + vos_timer_start(&fsm->msg4Timer, authConsts.timeoutPeriod); + } + + return ANI_OK; +} + + +static int +authEapolKeyHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, tAniMacAddr staMac ) +{ + int retVal; + + int descType; + void *keyDesc; + tAniEapolRsnKeyDesc *rsnDesc; + tAniEapolKeyAvailEventData data; + + do + { + retVal = aniEapolParseKey(eapolFrame, &descType, &keyDesc); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) + { + rsnDesc = (tAniEapolRsnKeyDesc *) keyDesc; + data.keyDesc = keyDesc; + data.eapolFrame = eapolFrame; + // Pass on the event to the RSN FSM only if it is for a pairwise key + if (rsnDesc->info.unicastFlag) + { + retVal = authRsnFsmProcessEvent(fsm, + RSN_FSM_EAPOL_FRAME_AVAILABLE, + &data); + } + else { + //Not worry about GTK stuff + } + } + else { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Got unexpected legacy 802.1x RC4 Key message \n" ); + retVal = ANI_E_FAILED; + break; + } + }while( 0 ); + + aniEapolKeyFreeDesc(descType, keyDesc); + return retVal; +} + + +void authEapolHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type) +{ + switch (*type) + { + case ANI_EAPOL_TYPE_START: + //No doing anything because we only support WPA2-PSK + break; + case ANI_EAPOL_TYPE_LOGOFF: + //ignore + break; + case ANI_EAPOL_TYPE_KEY: + authEapolKeyHandler(fsm, eapolFrame, srcMac); + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Auth: EAPOL type not implemented: 0x%.2x\n", *type); + break; + } +} diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.h b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.h new file mode 100644 index 000000000000..7f9df9d903e6 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xAuthFsm.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xAuthRsnFsm.h $ + * + * Contains declarations for the RSN EAPOL-Key FSM on the + * authenticator side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef __AAG_AUTH_RSN_FSM_H +#define __AAG_AUTH_RSN_FSM_H + +#include "vos_types.h" +#include "vos_timer.h" + +#include "bapInternal.h" +#include "bapRsn8021xFsm.h" + + + +/** + * authRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param consts the various constant values needed by this FSM + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmInit(tAuthRsnFsmConsts *consts); + +/** + * authRsnFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an RSN key FSM instance for + * the given STA context. + * + * @parm ctx the STA context whose instance is being created + * @param pskBased pass in eANI_BOOLEAN_TRUE is this STA is to be + * authenticated based on a pre-shared key as opposed to EAP. + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmCreate(tBtampContext *ctx); + + + +int +authRsnFsmSetPmk(tStaContext *ctx, v_U8_t *pmk); + +#endif //__AAG_AUTH_RSN_FSM_H diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xFsm.h b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xFsm.h new file mode 100644 index 000000000000..de39bd7ee274 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xFsm.h @@ -0,0 +1,457 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xFsm.h $ + * Contains the declarations for the Auth Agent's FSM's to work. + * + * Author: Mayank D. Upadhyay + * Date: 21-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef __AAG_FSM_H_ +#define __AAG_FSM_H_ + +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_timer.h" +#include +#include +#include +#include "bapRsn8021xPrf.h" +//#include "bapInternal.h" +#include "csrApi.h" + +typedef struct sBtampContext tBtampContext; +typedef struct tStaContext tStaContext; +typedef struct tSuppContext tSuppContext; + +#define RSN_MAX_PACKET_SIZE 512 +#define RSN_80211_KEY_LEN 16 +#define RSN_IE_MAX_PACKET_SIZE 256 +#define RSN_IE_HEADER_SIZE 0 +#define ACCTG_SESSION_ID_SIZE 8 +#define ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE 8 // Bytes + +#define BAP_SET_RSN_KEY 1 +#define BAP_RESET_RSN_KEY 0 + + +#define AAG_ACL_LOOKUP_NEEDED(ctx) \ + ((ctx)->authType == eANI_SSM_AT_NONE || \ + (ctx)->authType == eANI_SSM_AT_RSN_PSK || \ + (ctx)->authType == eANI_SSM_AT_SHARED_KEY) + +#define AAG_ACL_LOOKUP_PENDING(ctx) \ + ((ctx)->aclLookupFsm != NULL && (ctx)->radiusInfo.req != NULL) + +#define AAG_STA_AWAITING_CLEANUP(ctx) \ + ((ctx)->ssid == NULL) + +#define AAG_MARK_STA_AS_AWAITING_CLEANUP(ctx) \ + ((ctx)->ssid = NULL) + +/************************ + * AuthRsnFsm structure: + *************************/ +typedef struct tagAuthRsnFsm +{ + v_U8_t currentState; + + tBtampContext *ctx; + tStaContext *staCtx; + + // Variables used for EAPOL-Key messages + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + + // Flags set by external events + v_U8_t authReq; + v_U8_t eapolAvail; + v_U8_t disconnect; + v_U8_t integFailed; + v_U8_t pmkAvailable; + + // Variables maintained internally + v_U8_t numTries; + tAniPacket *lastEapol; //Tx + v_BOOL_t fReceiving; + v_U32_t cryptHandle; + + // Timers used..alternate them in different states + vos_timer_t msg2Timer; + vos_timer_t msg4Timer; + v_BOOL_t msg2TimeOut; + v_BOOL_t msg4TimeOut; + v_U8_t advertizedRsnIe[256]; +} tAuthRsnFsm; + +/************************ + * SuppRsnFsm structure: + *************************/ + +typedef struct tagSuppRsnFsm { + + v_U8_t currentState; + + tBtampContext *ctx; + tSuppContext *suppCtx; + + // Variables used for EAPOL-Key messages + tAniSsmReplayCtr *localReplayCtr; + tAniSsmReplayCtr *peerReplayCtr; + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + + // Flags set by external events + v_U8_t authReq; + v_U8_t pmkAvail; + v_U8_t eapolAvail; + v_U8_t integFailed; + v_U8_t updateKeys; + + // Variables maintained internally + int numTries; + tAniPacket *lastEapol; + v_BOOL_t fReceiving; + v_U32_t cryptHandle; +} tSuppRsnFsm; + + +typedef struct sAagZoneEntry tAagZoneEntry; +typedef struct sAagSsidEntry tAagSsidEntry; + +typedef enum +{ + //Internal to RSN + //This event is triggered by RSN’s timers + RSN_FSM_TIMER_EXPIRED, + //BAP use this event to inform auth/supp to start processing + //authentication. When BAP send this event to RSN, it is presumed + //that the PMK is available. + RSN_FSM_AUTH_START, + //Internal to RSN + //This event is triggered by the Rx routine when called by TL + RSN_FSM_EAPOL_FRAME_AVAILABLE, + //BAP use this event to inform RSN that the connection is lost + RSN_FSM_DISCONNECT, + //Internal to RSN + //This event hannpens when RSN detect key integraty check fails + RSN_FSM_INTEG_FAILED, + +}tRsnFsmEvent; + +/** + * Stores information about an EAP message that was last received or + * EAPOL messages that were last sent. + * + * 1. EAP messages last received are stripped out of their outer + * encapsulation which may be either EAPOL or RADIUS, and are + * preserved within this structure for the lifetime of one event: + * - EAPOL_MESSAGE_AVAILABLE => process and send to RADIUS + * - RADIUS_MESSAGE_AVAILABLE => process and send to STA + * When the event is fully handled, the incoming packet is freed, + * therefore, the contents of this structure are no longer valid. + * + * 2. EAPOL messages last sent are stored in their entirety. They are + * created and delete a little differently on the AP and BP sides: + * - AP side: The EAPOL message contains the last EAP message + * that was sent to the STA. As soon as a new EAP message arrives + * from RADIUS, this EAPOL mesage is freed because a new one will + * be generated. + * - BP side: The EAPOL message contains the last EAP message + * generated by the local supplicant. As soon as a new EAPOL + * message is generated, this one is freed and the new one is + * stored. + */ +typedef struct tEapInfo + +{ + tAniPacket *message; + v_U8_t id; +} tEapInfo; + + +typedef enum eAniSsmAuthState { + eANI_SSM_AUTH_STATE_INIT = 0, + eANI_SSM_AS_PW_KEY_CONF_AWAITED, + eANI_SSM_AS_PW_KEY_SET, +} tAniSsmAuthState; + + +/** + * The Station's context is stored in this structure. It contains + * pointers to the FSM's used by the STA (which in turn point back to + * the context). It also contains the transient event data like + * EAP-Message and RADIUS state that is obtained from various network + * packets. + */ +struct tStaContext { + + // STA identification information + tAniMacAddr suppMac; + v_BOOL_t bpIndicator; + + // Local association point + tAniMacAddr authMac; + v_U8_t ssidName[SIR_MAC_MAX_SSID_LENGTH + 1]; + tAagSsidEntry *ssid; + + // The different FSM's that can be instantiated for the STA + tAuthRsnFsm *authRsnFsm; + + // Keys derived for STA + v_U8_t ptk[AAG_PRF_MAX_OUTPUT_SIZE]; + tAniPacket *pmk; // MS-MPPE-Recv-Key + tAniPacket *serverKey; // MS-MPPE-Send-Key + v_U8_t keyId; + + // STA context timers + v_U32_t sessionTimeout; + vos_timer_t reAuthTimer; + vos_timer_t sessionCleanupTimer; + + // Radius Authentication attributes + v_U8_t *authClassAttr; + + // Misc. authentication related state + eCsrAuthType authType; + eCsrEncryptionType pwCipherType; + tAniPacket *ieSta; + tAniSsmAuthState authState; + v_BOOL_t prmLookupInProgress; + v_BOOL_t firstTimeAuth; + v_BOOL_t secureLink; // 4-way h/s requries this to be 0 at startup or on MIC failures + tAniSsmReplayCtr *localReplayCtr; + tAniSsmReplayCtr *peerReplayCtr; // Goes hand in hand with flag below + v_BOOL_t pastFirstPeerRequest; // For use with peer replay counter + + tAniPacket *cachedPmk; // MS-MPPE-Recv-Key + tAniPacket *cachedServerKey; // MS-MPPE-Send-Key + v_U8_t cachedKeyId; + +}; + + +struct tSuppContext { + + // AP (peer) identification information + tAniMacAddr authMac; + v_U8_t *ssidStr; + + // Local association point + tAniMacAddr suppMac; + + // Keys derived on supplicant + v_U8_t ptk[AAG_PRF_MAX_OUTPUT_SIZE]; + v_U8_t pwKeyLen; // # of bytes of PTK to send to LIM + tAniPacket *pmk; // MS-MPPE-Recv-Key + tAniPacket *serverKey; // MS-MPPE-Send-Key + + // Misc. authentication related state + eCsrAuthType authType; + eCsrEncryptionType pwCipherType; + eCsrEncryptionType grpCipherType; + tAniPacket *ieBp; + tAniPacket *ieAp; + v_BOOL_t firstTimeAuth; + +}; + +typedef struct tAniEapolKeyAvailEventData { + void *keyDesc; + tAniPacket *eapolFrame; +} tAniEapolKeyAvailEventData; + +typedef struct tAniAagTimerEventData { + vos_timer_t timer; + void *appData; +} tAniAagTimerEventData; + + +/** + * Callback funtion that sets some status for a given STA context, + * e.g., the status of the controlled port. + */ +#if 0 +typedef int (*tAagSetStatus)(tStaContext *ctx); + +typedef int (*tAagTxEapolSupp)(tSuppContext *ctx); +typedef int (*tAagSetStatusSupp)(tSuppContext *ctx); +typedef int (*tAagSendEventToFsmSupp)(tSuppContext *ctx); +#endif + +/** + * Callback function that posts a XXX_TIMER_EXPIRED event when a timer + * goes off. XXX represents the kind of timer that caused the event. + */ +typedef void (*tAagTimerCallback)(void *data); + +/** + * Callbacks provided to the GroupKeyFsm module from the FSM Manager + * module so that it can access procedures needed for network + * transmission, inter-FSM signalling, and communication with the main + * application. + */ +/*typedef struct tGroupKeyFsmCallbacks { + int (*getDefaultWepKeyId)(v_U32_t radioId); + int (*copyDefaultWepKey)(v_U32_t radioId); + int (*updateAllSta)(v_U32_t radioId); +} tGroupKeyFsmCallbacks;*/ + +/** + * This structure stores contants used by the AuthFsm as defined in + * [802.1X]. + */ +typedef struct tAuthFsmConsts { + // Amount of time to ignore a misbehaving STA + v_U16_t quietPeriod; + // Number of reauthentication attempts allowed before ignoring STA + v_U8_t reAuthMax; + // Amount of time to wait for response from STA + v_U16_t txPeriod; +} tAuthFsmConsts; + + + +/** + * This structure stores constants used by the AuthRsnFsm as defined in + * [802.11i]. + */ +typedef struct tAuthRsnFsmConsts { + v_U32_t timeoutPeriod; + v_U32_t maxTries; +} tAuthRsnFsmConsts; + + +/** + * This structure stores contants used by the SuppFsm as defined in + * [802.1X]. + */ +typedef struct tSuppFsmConsts { + v_U16_t authPeriod; + v_U16_t heldPeriod; + v_U16_t startPeriod; + v_U8_t maxStart; +} tSuppFsmConsts; + +/** + * This structure stores constants used by the SuppRsnFsm as defined in + * [802.11i]. + */ +typedef struct tSuppRsnFsmConsts { + v_U32_t timeoutPeriod; + v_U32_t maxTries; +} tSuppRsnFsmConsts; + + +/** + * This structure stores constants used by the AuthRsnGroupKeyFsm as + * defined in [802.11i]. + */ +typedef struct tAuthRsnGroupKeyFsmConsts { + v_U32_t timeoutPeriod; + v_U32_t maxTries; +} tAuthRsnGroupKeyFsmConsts; + +/** + * authRsnFsmFree + * + * FUNCTION + * Frees a previously allocated RSN Key FSM in a STA context. If the + * RSN Key FSM is not yet allocated, then this is an error. + * + * @param ctx the STA context whose FSM instance is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmFree(tBtampContext *ctx); + +/** + * authRsnFsmProcessEvent + * + * FUNCTION + * Passes an event to the RSN key FSM instance for immediate processing. + * + * @param fsm the RSN Key FSM instance + * @param eventId the AAG event to process + * @param arg an optional argument for this event + * + * @return ANI_OK if the operation succeeds + */ +int +authRsnFsmProcessEvent(tAuthRsnFsm *fsm, tRsnFsmEvent eventId, void *arg); + + +/** + * suppFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an SuppFsm instance for the + * given STA context. + * + * @parm ctx the supplicant context whose SuppFsm is being created + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmCreate(tBtampContext *ctx); + +/** + * suppFsmFree + * + * FUNCTION + * Frees a previously allocated SuppFsm. + * + * @param suppCtx the supplicant context whose suppFsm is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmFree(tBtampContext *ctx); + +/** + * suppFsmProcessEvent + * + * FUNCTION + * Passes an event to the suppFsm for immediate processing. + * + * Note: The pertinent event data is already stored in the context. + * + * @param suppFsm the suppFsm + * @param eventId the AAG event to process + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmProcessEvent(tSuppRsnFsm *fsm, tRsnFsmEvent eventId, void *arg); + +#endif // __AAG_FSM_H_ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.c b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.c new file mode 100644 index 000000000000..9b25443f330c --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xPrf.c $ + * + * Contains definitions for routines to calculate the 802.11i PRF + * functions. + * + * Author: Mayank D. Upadhyay + * Date: 19-March-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + */ + +/*#include +#include +#include +*/ +#include "vos_utils.h" +#include "vos_memory.h" +#include "bapRsn8021xPrf.h" +#include "bapRsnErrors.h" +//#include "ani8021xUtils.h" + +#define AAG_PTK_PRF_ADD_PARAM 159 +#define AAG_PTK_PRF_DIV_PARAM 160 + +#define AAG_PTK_PRF_CONST "Pairwise key expansion" +#define AAG_PTK_PRF_CONST_LEN 22 + +#define AAG_PTK_PRF_LM_POS 0 +#define AAG_PTK_PRF_HM_POS 6 +#define AAG_PTK_PRF_LN_POS 12 +#define AAG_PTK_PRF_HN_POS (AAG_PTK_PRF_LN_POS + ANI_EAPOL_KEY_RSN_NONCE_SIZE) + +#define AAG_PTK_PRF_TEXT_LEN (AAG_PTK_PRF_HN_POS + ANI_EAPOL_KEY_RSN_NONCE_SIZE) + +#define AAG_GTK_PRF_CONST "Group key expansion" +#define AAG_GTK_PRF_CONST_LEN 19 + +#define AAG_GTK_PRF_MAC_POS 0 +#define AAG_GTK_PRF_NONCE_POS 6 + +#define AAG_GTK_PRF_TEXT_LEN (AAG_GTK_PRF_NONCE_POS + ANI_EAPOL_KEY_RSN_NONCE_SIZE) + +/** + * aagGetKeyMaterialLen + * + * Returns the number of bytes of the PTK that have to be provided to + * the MAC layer for a given cipher type. + * + * @param cipherType the cipher-type + * + * @return the number of bytes of key material for this cipher type, + * or 0 for invalid cipher types. + */ +int +aagGetKeyMaterialLen(eCsrEncryptionType cipherType) +{ + switch (cipherType) { + case eCSR_ENCRYPT_TYPE_AES: + return AAG_RSN_KEY_MATERIAL_LEN_CCMP; + break; + default: + return 0; + break; + }; +} + +/** + * aagPtkPrf + * + * The PRF used for calculating the pairwise temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param pmk the pairwise master-key + * @param authAddr the MAC address of the authenticator + * @param suppAddr the MAC address of the supplicant + * @param aNonce the nonce generated by the authenticator + * @param sNonce the nonce generated by the supplicant + * + * @return ANI_OK if the operation succeeds + */ +int +aagPtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + tAniPacket *pmk, + tAniMacAddr authAddr, + tAniMacAddr suppAddr, + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE], + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]) +{ + v_U8_t *lowMac; + v_U8_t *highMac; + v_U8_t *lowNonce; + v_U8_t *highNonce; + + v_U8_t *keyBytes; + int keyLen; + + v_U8_t text[AAG_PTK_PRF_TEXT_LEN]; + + //Cannot use voss function here because vos_mem_compare doesn't tell whihc is larger + if (vos_mem_compare2(authAddr, suppAddr, sizeof(tAniMacAddr)) < 0) { + lowMac = authAddr; + highMac = suppAddr; + } else { + lowMac = suppAddr; + highMac = authAddr; + } + + if (vos_mem_compare2(aNonce, sNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE) < 0) { + lowNonce = aNonce; + highNonce = sNonce; + } else { + lowNonce = sNonce; + highNonce = aNonce; + } + + vos_mem_copy(text + AAG_PTK_PRF_LM_POS, lowMac, sizeof(tAniMacAddr)); + vos_mem_copy(text + AAG_PTK_PRF_HM_POS, highMac, sizeof(tAniMacAddr)); + vos_mem_copy(text + AAG_PTK_PRF_LN_POS, lowNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); + vos_mem_copy(text + AAG_PTK_PRF_HN_POS, highNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); + + keyLen = aniAsfPacketGetBytes(pmk, &keyBytes); + if( !ANI_IS_STATUS_SUCCESS( keyLen ) ) + { + return keyLen; + } + + return aagPrf(cryptHandle, + result, + keyBytes, keyLen, + (v_U8_t *)AAG_PTK_PRF_CONST, AAG_PTK_PRF_CONST_LEN, + text, sizeof(text), + prfLen); +} + +/** + * aagGtkPrf + * + * The PRF used for calculating the group temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param gmk the group master-key + * @param authAddr the MAC address of the authenticator + * @param gNonce the nonce generated by the authenticator for this purpose + * + * @return ANI_OK if the operation succeeds + */ +int +aagGtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + v_U8_t gmk[AAG_RSN_GMK_SIZE], + tAniMacAddr authAddr, + v_U8_t gNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]) +{ + v_U8_t text[AAG_GTK_PRF_TEXT_LEN]; + + vos_mem_copy(text + AAG_GTK_PRF_MAC_POS, authAddr, sizeof(tAniMacAddr)); + vos_mem_copy(text + AAG_GTK_PRF_NONCE_POS, gNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE); + + return aagPrf(cryptHandle, + result, + gmk, AAG_RSN_GMK_SIZE, + (v_U8_t *)AAG_GTK_PRF_CONST, AAG_GTK_PRF_CONST_LEN, + text, sizeof(text), + prfLen); + +} + +/** + * aagPrf + * + * The raw PRF function that is used in IEEE 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param key the key to use in the PRF + * @param keyLen the length of the key + * @param a the parameter A which is usually a unique label + * @param aLen the length of the parameter A + * @ param b the parameter B + * @param bLen the length of parameter B + * @param prfLen the number to BITS desired from the PRF result + * + * @return ANI_OK if the operation succeeds + */ +int +aagPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U8_t *key, v_U8_t keyLen, + v_U8_t *a, v_U8_t aLen, + v_U8_t *b, v_U8_t bLen, + v_U32_t prfLen) +{ + static v_U8_t y; + + v_U8_t *hmacText = NULL; + v_U8_t *resultOffset = result; + int numLoops; + int loopCtrPos; + int i, retVal=0; + + hmacText = vos_mem_malloc( aLen + bLen + 2 ); + if( NULL == hmacText ) + { + return ANI_E_NULL_VALUE; + } + + vos_mem_copy(hmacText + 0, a, aLen); + hmacText[aLen] = y; + vos_mem_copy(hmacText + aLen + 1, b, bLen); + loopCtrPos = aLen + 1 + bLen; + + numLoops = prfLen + AAG_PTK_PRF_ADD_PARAM; + numLoops /= AAG_PTK_PRF_DIV_PARAM; + + for (i = 0; i < numLoops; i++) + { + VOS_ASSERT((resultOffset - result + VOS_DIGEST_SHA1_SIZE) + <= AAG_PRF_MAX_OUTPUT_SIZE); + hmacText[loopCtrPos] = i; + if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, hmacText, loopCtrPos + 1, key, keyLen, resultOffset) ) ) + { + resultOffset += VOS_DIGEST_SHA1_SIZE; + retVal = ANI_OK; + } + else + { + retVal = ANI_ERROR; + } + } + + vos_mem_free(hmacText); + + return retVal; +} + diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.h b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.h new file mode 100644 index 000000000000..c5ea9aefb402 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xPrf.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xPrf.h $ + * + * Contains declarations for routines to calculate the 802.11i PRF + * functions. + * + * Author: Mayank D. Upadhyay + * Date: 19-March-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + */ + +#ifndef __AAG_PRF_H_ +#define __AAG_PRF_H_ + +#include "vos_types.h" +#include +#include +#include "csrApi.h" + + +/* + * Define the maximum size needed for the result array so that SHA-1 + * overflow is accounted for. + */ +#define AAG_PRF_MAX_OUTPUT_SIZE 80 + +#define AAG_RSN_PTK_TK1_OFFSET \ + (AAG_RSN_EAPOL_MIC_KEY_LEN + AAG_RSN_EAPOL_ENC_KEY_LEN) + +// Pairwise key related definitions... + +#define AAG_RSN_PTK_PRF_LEN_TKIP 512 //bits +#define AAG_RSN_PTK_PRF_LEN_CCMP 384 //bits +#define AAG_RSN_PTK_PRF_LEN_WEP104 384 //bits +#define AAG_RSN_PTK_PRF_LEN_WEP40 384 //bits + +// Group key related definitions... + +#define AAG_RSN_GMK_SIZE 16 + +#define AAG_RSN_GTK_PRF_LEN_TKIP 256 //bits +#define AAG_RSN_GTK_PRF_LEN_CCMP 128 //bits +#define AAG_RSN_GTK_PRF_LEN_WEP104 128 //bits +#define AAG_RSN_GTK_PRF_LEN_WEP40 128 //bits + +// Key material length that is sent to the MAC layer... + +#define AAG_RSN_KEY_MATERIAL_LEN_CCMP 16 +#define AAG_RSN_KEY_MATERIAL_LEN_TKIP 32 +#define AAG_RSN_KEY_MATERIAL_LEN_WEP104 13 +#define AAG_RSN_KEY_MATERIAL_LEN_WEP40 5 + +/** + * aagGetKeyMaterialLen + * + * Returns the number of bytes of the PTK that have to be provided to + * the MAC layer for a given cipher type. + * + * @param cipherType the cipher-type + * + * @return the number of bytes of key material for this cipher type, + * or 0 for invalid cipher types. + */ +int +aagGetKeyMaterialLen(eCsrEncryptionType cipherType); + +/** + * aagPtkPrf + * + * The PRF used for calculating the pairwise temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param pmk the pairwise master-key + * @param authAddr the MAC address of the authenticator + * @param suppAddr the MAC address of the supplicant + * @param aNonce the nonce generated by the authenticator + * @param sNonce the nonce generated by the supplicant + * + * @return ANI_OK if the operation succeeds + */ +int +aagPtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + tAniPacket *pmk, + tAniMacAddr authAddr, + tAniMacAddr suppAddr, + v_U8_t aNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE], + v_U8_t sNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]); + + +/** + * aagGtkPrf + * + * The PRF used for calculating the group temporal key under IEEE + * 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param prfLen the number of BITS desired from the PRF result + * @param gmk the group master-key + * @param authAddr the MAC address of the authenticator + * @param gNonce the nonce generated by the authenticator for this purpose + * + * @return ANI_OK if the operation succeeds + */ +int +aagGtkPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U32_t prfLen, + v_U8_t gmk[AAG_RSN_GMK_SIZE], + tAniMacAddr authAddr, + v_U8_t gNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]); + +/** + * aagPrf + * + * The raw PRF function that is used in IEEE 802.11i. + * + * @param result a fixed size array where the outputis stored. Should + * have enough place for the SHA-1 overflow. + * @param key the key to use in the PRF + * @param keyLen the length of the key + * @param a the parameter A which is usually a unique label + * @param aLen the length of the parameter A + * @ param b the parameter B + * @param bLen the length of parameter B + * @param prfLen the number to BITS desired from the PRF result + * + * @return ANI_OK if the operation succeeds + */ +int +aagPrf(v_U32_t cryptHandle, + v_U8_t result[AAG_PRF_MAX_OUTPUT_SIZE], + v_U8_t *key, v_U8_t keyLen, + v_U8_t *a, v_U8_t aLen, + v_U8_t *b, v_U8_t bLen, + v_U32_t prfLen); + +#endif //__AAG_PRF_H_ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c new file mode 100644 index 000000000000..1d3dd23a1810 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.c @@ -0,0 +1,1164 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xSuppRsnFsm.c $ + * + * Contains definitions for the RSN EAPOL-Key FSM on the + * supplicant side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "bapRsnSsmServices.h" +#include "bapRsnSsmEapol.h" +#include "bapRsnErrors.h" +#include "bapRsn8021xSuppRsnFsm.h" +#include "vos_utils.h" +#include "bapRsnTxRx.h" +#include "btampFsm.h" + +// The different states that this FSM transitions through +#define INITIALIZE 0 +#define AUTHENTICATION 1 +#define GOT_PMK 2 +#define STA_KEY_START 3 +#define STA_KEY_SET 4 +#define KEY_UPDATE 5 +#define REKEY_MSG 6 +#define GROUP_KEY_SET 7 +#define NUM_STATES (GROUP_KEY_SET + 1) + + +static tSuppRsnFsmConsts suppConsts = { 2000, 3 }; //timeout, retry limit + +int gReadToSetKey; + +/************************************** + * Static functions in this module + **************************************/ + +static +int zeroOutPtk(tSuppRsnFsm *fsm); + +static +int checkMic(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t pwKeyExchange); + +static int checkInfoElement(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int checkPeerReplayCounter(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t *retransmit, + v_BOOL_t actualMicFlag, + v_BOOL_t reTxMicFlag + ); + +static +int derivePtk(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data); + +static +int checkTransition(tSuppRsnFsm *fsm, void *arg); + +static int +gotoStateInit(tSuppRsnFsm *fsm); + +static int suppRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ); +static int suppRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ); + +/************************* + * Internal Functions + *************************/ +int suppRsnAuthStartEventHandler(tSuppRsnFsm *fsm); + +/************************* + * The exported functions + *************************/ + +/** + * suppRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmInit(void) +{ + // TODO: Read the constants in from config + // consts = constsIn; + suppConsts.timeoutPeriod = 2000; + suppConsts.maxTries = 3; + + return ANI_OK; +} + +/** + * suppRsnFsmCreate + * + * FUNCTION + * Allocates and initializes the state of an RSN key FSM instance for + * the given BP context. + * + * @parm ctx the BP context whose instance is being created + * @param pskBased pass in eANI_BOOLEAN_TRUE is this BP is to be + * authenticated based on a pre-shared key as opposed to EAP. + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmCreate(tBtampContext *ctx) +{ + int retVal = ANI_OK; + tSuppRsnFsm *fsm = &ctx->uFsm.suppFsm; + + // First, clear everything out + vos_mem_zero( fsm, sizeof(tSuppRsnFsm)); + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterTxRxCallbacks( suppRsnTxCompleteHandler, + suppRsnRxFrameHandler ) ) ) + { + return ANI_ERROR; + } + + if( !VOS_IS_STATUS_SUCCESS( bapRsnRegisterRxCallback( ctx->pvosGCtx ) ) ) + { + return ANI_ERROR; + } + + // Allocate the supplicant context + fsm->suppCtx = (tSuppContext *)vos_mem_malloc( sizeof(tSuppContext) ); + if (fsm->suppCtx == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + // Clear out the supplicant context + vos_mem_zero( fsm->suppCtx, sizeof(tSuppContext)); + + fsm->ctx = ctx; + //Only support CCMP + fsm->suppCtx->pwCipherType = eCSR_ENCRYPT_TYPE_AES; + + retVal = aniAsfPacketAllocateExplicit(&fsm->lastEapol, + RSN_MAX_PACKET_SIZE, + EAPOL_TX_HEADER_SIZE); + if (retVal != ANI_OK) + { + VOS_ASSERT( 0 ); + goto error; + } + + aniAsfPacketAllocate(&fsm->suppCtx->pmk); + if (fsm->suppCtx->pmk == NULL) + { + retVal = ANI_E_MALLOC_FAILED; + VOS_ASSERT( 0 ); + goto error; + } + + fsm->suppCtx->ieAp = NULL; + + fsm->cryptHandle = 0; + if( !VOS_IS_STATUS_SUCCESS( vos_crypto_init( &fsm->cryptHandle ) ) ) + { + retVal = ANI_E_FAILED; + VOS_ASSERT( 0 ); + } + + fsm->currentState = INITIALIZE; + gotoStateInit(fsm); + + suppRsnFsmProcessEvent( fsm, RSN_FSM_AUTH_START, NULL ); + + return ANI_OK; + + error: + suppRsnFsmFree( ctx ); + + return retVal; + +} + +/** + * suppRsnFsmFree + * + * FUNCTION + * Frees a previously allocated RSN Key FSM in a BP context. If the + * RSN Key FSM is not yet allocated, then this is an error. + * + * @param ctx the BP context whose FSM instance is to be freed + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmFree(tBtampContext *ctx) +{ + tSuppRsnFsm *fsm; + + fsm = &ctx->uFsm.suppFsm; + + if( fsm->cryptHandle ) + { + vos_crypto_deinit( fsm->cryptHandle ); + } + + bapRsnClearTxRxCallbacks(); + + if (fsm->lastEapol) + aniAsfPacketFree(fsm->lastEapol); + + if( fsm->suppCtx ) + { + if ( fsm->suppCtx->pmk ) + { + aniAsfPacketFree(fsm->suppCtx->pmk); + } + vos_mem_free( fsm->suppCtx ); + } + + // Finally, clear everything out + vos_mem_zero( fsm, sizeof(tSuppRsnFsm)); + + return ANI_OK; +} + +/** + * suppRsnFsmProcessEvent + * + * FUNCTION + * Passes an event to the RSN key FSM instance for immediate processing. + * + * @param fsm the RSN Key FSM instance + * @param eventId the AAG event to process + * @param arg an optional argument for this event + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmProcessEvent(tSuppRsnFsm *fsm, tRsnFsmEvent eventId, void *arg) +{ + + switch (eventId) + { + case RSN_FSM_TIMER_EXPIRED: + // Proceed straight to checkTransition + break; + case RSN_FSM_AUTH_START: + fsm->authReq = eANI_BOOLEAN_TRUE; + suppRsnAuthStartEventHandler(fsm); + break; + case RSN_FSM_EAPOL_FRAME_AVAILABLE: + fsm->eapolAvail = eANI_BOOLEAN_TRUE; + break; + case RSN_FSM_INTEG_FAILED: + fsm->integFailed = eANI_BOOLEAN_TRUE; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp unknown event for SuppFsm: %d\n", + eventId); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + break; + } + + checkTransition(fsm, arg); + + return ANI_OK; +} + +int +suppRsnAuthStartEventHandler(tSuppRsnFsm *fsm) +{ + // Copy required info + vos_mem_copy( &fsm->suppCtx->authMac, fsm->ctx->peer_mac_addr, 6); + vos_mem_copy( &fsm->suppCtx->suppMac, fsm->ctx->self_mac_addr, 6); + aniAsfPacketAppendBuffer( fsm->suppCtx->pmk, fsm->ctx->key_material, fsm->ctx->key_length); + + return ANI_OK; +} + +/*********************** + * The static functions + ***********************/ + +static int +gotoStateInit(tSuppRsnFsm *fsm) +{ + fsm->currentState = INITIALIZE; + + fsm->authReq = eANI_BOOLEAN_FALSE; + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + fsm->integFailed = eANI_BOOLEAN_FALSE; + fsm->pmkAvail = eANI_BOOLEAN_FALSE; + + // Create two replay counter's..one for our requests, and another + // for STA's requests. Initialize the first one randomly. + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->localReplayCtr, ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + aniSsmReplayCtrCreate(fsm->cryptHandle, &fsm->peerReplayCtr, ANI_EAPOL_KEY_RSN_RSC_SIZE, 0); + + return ANI_OK; +} + +static int +gotoStateAuthentication(tSuppRsnFsm *fsm) +{ + fsm->currentState = AUTHENTICATION; + + if( VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( fsm->cryptHandle, fsm->sNonce, ANI_EAPOL_KEY_RSN_NONCE_SIZE ) ) ) + { + zeroOutPtk(fsm); + // TODO: Zero out all GTK's + fsm->authReq = eANI_BOOLEAN_FALSE; + /////getPmk(fsm->suppCtx); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp fail to random number\n" ); + return ANI_ERROR; + } + + return ANI_OK; +} + +static int +gotoStateGotPmk(tSuppRsnFsm *fsm) +{ + fsm->currentState = GOT_PMK; + + return ANI_OK; +} + +static int +gotoStateStaKeyStart(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t retransmit) +{ + int retVal; + tAniEapolRsnKeyDesc txDesc; + tAniEapolRsnKeyDesc *rxDesc; + static v_U8_t btampRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 }; + + fsm->currentState = STA_KEY_START; + + // Create a new EAPOL frame if we don't have to retransmit + // if (!retransmit) + //{ + + rxDesc = data->keyDesc; + if( NULL == rxDesc) + { + return ANI_E_NULL_VALUE; + } + aniAsfPacketEmptyExplicit( fsm->lastEapol, EAPOL_TX_HEADER_SIZE ); + retVal = derivePtk(fsm, data); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp derivePtk failed with code %d!\n", retVal); + return retVal; + } + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + txDesc.keyLen = 0; //RSN_80211_KEY_LEN; + + // Send back the same replayCtr that the authenticator sent + vos_mem_copy(txDesc.replayCounter, + rxDesc->replayCounter, + sizeof(txDesc.replayCounter)); + + vos_mem_copy(txDesc.keyNonce, fsm->sNonce, sizeof(txDesc.keyNonce)); + txDesc.keyDataLen = sizeof(btampRSNIE);//aniAsfPacketGetBytes(fsm->suppCtx->ieBp, + //&txDesc.keyData); + txDesc.keyData = btampRSNIE; + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp gotoStateStaKeyStart fail to write key %d\n", + retVal); + return retVal; + } + //} + + if( VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_OK; + } + else + { + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStateStaKeySet(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t retransmit) +{ + int retVal=0; + tAniEapolRsnKeyDesc txDesc; + tAniEapolRsnKeyDesc *rxDesc = NULL; + + fsm->currentState = STA_KEY_SET; + + if (data == NULL) + { + // We don't need to do anything + return ANI_OK; + } + + // Create a new EAPOL frame if we don't have to retransmit + if (!retransmit) + { + // First check the IE that the AP sent + retVal = checkInfoElement(fsm, data); + if (retVal != ANI_OK) + { + //FIX_RSN aagSetSuppFailureAndCleanup(fsm->suppCtx); + + // FSM does not exist after this... + + return retVal; + } + + // Create a new EAPOL frame + + rxDesc = data->keyDesc; + if( NULL == rxDesc ) + return ANI_E_NULL_VALUE; + + aniAsfPacketEmptyExplicit(fsm->lastEapol, + EAPOL_TX_HEADER_SIZE ); + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->suppCtx->pwCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + + txDesc.info.unicastFlag = eANI_BOOLEAN_TRUE; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + txDesc.info.secureFlag = eANI_BOOLEAN_TRUE; + txDesc.keyLen = 0; //RSN_80211_KEY_LEN; + + // Send back the same replayCtr that the authenticator sent + vos_mem_copy(txDesc.replayCounter, + rxDesc->replayCounter, + sizeof(txDesc.replayCounter)); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + } + gReadToSetKey = BAP_SET_RSN_KEY; + if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + /* making it global to access in bapTxRx file */ +#if 0 + tCsrRoamSetKey setKeyInfo; + + + vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) ); + setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES; + setKeyInfo.keyDirection = eSIR_TX_RX; + vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, sizeof( tAniMacAddr ) ); + setKeyInfo.paeRole = 0; //this is a supplicant + setKeyInfo.keyId = 0; //always + setKeyInfo.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN ); + //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one. + /* + We will move the Set key to EAPOL Completion handler. We found a race condition betweem + sending EAPOL frame and setting Key */ + + + if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" ); + retVal = ANI_ERROR; + } +#endif + gReadToSetKey = BAP_RESET_RSN_KEY; + retVal = ANI_ERROR; + } + + return retVal; +} + +static int +gotoStateGroupKeySet(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + int retVal; + tAniEapolRsnKeyDesc txDesc; + tAniEapolRsnKeyDesc *rxDesc; + + int groupKeyLen; + + fsm->currentState = GROUP_KEY_SET; + + do + { + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + if( NULL == rxDesc) + { + retVal = ANI_E_NULL_VALUE; + break; + } + + if (rxDesc->keyDataLen == 0 || rxDesc->keyData == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: AP sent no group key in group EAPOL-Key message!\n" ); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + + if ( rxDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES ) + { + groupKeyLen = rxDesc->keyDataLen - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + if( groupKeyLen <= 0 ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: AP sent GTK too short\n" ); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: AP sent unsupported keyDescVer %d!\n", rxDesc->info.keyDescVers ); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + + // Always create a new EAPOL frame + + aniAsfPacketEmptyExplicit( fsm->lastEapol, + EAPOL_TX_HEADER_SIZE ); + + vos_mem_zero( &txDesc, sizeof(txDesc) ); + + // The Key Information bits... + if (fsm->suppCtx->grpCipherType == eCSR_ENCRYPT_TYPE_AES) + { + txDesc.info.keyDescVers = ANI_EAPOL_KEY_DESC_VERS_AES; + } + + txDesc.info.unicastFlag = eANI_BOOLEAN_FALSE; + txDesc.info.keyId = rxDesc->info.keyId; + txDesc.info.micFlag = eANI_BOOLEAN_TRUE; + txDesc.info.secureFlag = eANI_BOOLEAN_TRUE; + txDesc.keyLen = RSN_80211_KEY_LEN; + + // Send back the same replayCtr that the authenticator sent + vos_mem_copy(txDesc.replayCounter, + rxDesc->replayCounter, + sizeof(txDesc.replayCounter)); + + retVal = aniEapolWriteKey(fsm->cryptHandle, + fsm->lastEapol, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + &txDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + retVal = ANI_ERROR; + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Supp could not send eapol. Disconnect\n" ); + break; + } + + //FIX_RSN there is no need to set GTK retVal = setGtk(fsm->suppCtx, rxDesc->keyRecvSeqCounter); + + // This is never retransmitted + aniAsfPacketEmptyExplicit( fsm->lastEapol, + EAPOL_TX_HEADER_SIZE ); + + checkTransition(fsm, NULL); // UCT rule + }while( 0 ); + + return retVal; +} + +static int +gotoStateKeyUpdate(tSuppRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo) +{ + //we don't update keys + bapSuppDisconnect( fsm->ctx ); + + return ANI_OK; +} + +static int +gotoStateRekeyMsg(tSuppRsnFsm *fsm, tSirMicFailureInfo *micFailureInfo) +{ + //We don't support rekey, simply disconnect + bapSuppDisconnect( fsm->ctx ); + + return ANI_OK; +} + +static +int zeroOutPtk(tSuppRsnFsm *fsm) +{ + return ANI_OK; +} + +static +int derivePtk(tSuppRsnFsm *fsm, tAniEapolKeyAvailEventData *data) +{ + v_U32_t prfLen; + tAniEapolRsnKeyDesc *rxDesc; + + switch (fsm->suppCtx->pwCipherType) + { + case eCSR_ENCRYPT_TYPE_AES: + prfLen = AAG_RSN_PTK_PRF_LEN_CCMP; + fsm->suppCtx->pwKeyLen = AAG_RSN_KEY_MATERIAL_LEN_CCMP; + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Cannot generate PTK for BP for invalid algorithm %d\n", + fsm->suppCtx->pwCipherType); + return ANI_E_ILLEGAL_ARG; + break; + }; + + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + return aagPtkPrf(fsm->cryptHandle, + fsm->suppCtx->ptk, + prfLen, + fsm->suppCtx->pmk, + fsm->suppCtx->authMac, + fsm->suppCtx->suppMac, + rxDesc->keyNonce, + fsm->sNonce); +} + +static +int checkMic(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t pwKeyExchange) +{ + int retVal; + + retVal = aniEapolKeyCheckMic(fsm->cryptHandle, + data->eapolFrame, + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW, + data->keyDesc, + fsm->suppCtx->ptk, + CSR_AES_KEY_LEN); + + return retVal; +} + + +static int checkInfoElement(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data) +{ + tAniEapolRsnKeyDesc *desc; + v_U8_t *ieApBytes; + int ieApLen; + + desc = (tAniEapolRsnKeyDesc *) data->keyDesc; + if( NULL == desc ) + { + return ANI_E_NULL_VALUE; + } + + ieApLen = aniAsfPacketGetBytes(fsm->suppCtx->ieAp, &ieApBytes); + if( ANI_IS_STATUS_SUCCESS( ieApLen ) ) + { + + if ((desc->keyDataLen != ieApLen) || + ( vos_mem_compare(desc->keyData, ieApBytes, ieApLen) )) + { + // TODO: Send a fault here + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp AP sent inconsistent RSN IE!\n" ); + return ANI_E_FAILED; + } + } + + return ANI_OK; +} + +static +int checkPeerReplayCounter(tSuppRsnFsm *fsm, + tAniEapolKeyAvailEventData *data, + v_BOOL_t *retransmit, + v_BOOL_t actualMicFlag, + v_BOOL_t reTxMicFlag) +{ + int retVal = ANI_OK; + int cmp; + tAniEapolRsnKeyDesc *rxDesc; + + rxDesc = data->keyDesc; + if( NULL == rxDesc ) + { + return ANI_E_NULL_VALUE; + } + + *retransmit = eANI_BOOLEAN_FALSE; + + cmp = aniSsmReplayCtrCmp(fsm->peerReplayCtr, rxDesc->replayCounter); + + // The AP should send us a replay counter greater than or equal to + // the last one it sent + /*Unless we are forgiving with this we will have interop issues with some vendros like CSR*/ + if (cmp > 0) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "BP got old EAPOL replay counter from AP" ); + retVal = ANI_E_REPLAY_CHECK_FAILED; + + } + else if (cmp <= 0) + { + if ( actualMicFlag == reTxMicFlag ) + { + *retransmit = eANI_BOOLEAN_TRUE; + } + } + + return retVal; +} + +static +int checkTransition(tSuppRsnFsm *fsm, void *arg) +{ + tAniEapolKeyAvailEventData *data; + tAniEapolRsnKeyDesc *rxDesc; + v_BOOL_t retransmit; + int retVal; + + if (fsm->authReq) + { + gotoStateAuthentication(fsm); + return ANI_OK; + } + + switch (fsm->currentState) + { + case INITIALIZE: + break; + case AUTHENTICATION: + gotoStateGotPmk(fsm); + checkTransition(fsm, arg); + break; + case GOT_PMK: + if (fsm->eapolAvail) { + + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.ackFlag) + { + + aniSsmReplayCtrUpdate(fsm->peerReplayCtr, + rxDesc->replayCounter); + + // Going from one state to another cannot be a retransmit + retVal = gotoStateStaKeyStart(fsm, data, eANI_BOOLEAN_FALSE); + + } + } + break; + case STA_KEY_START: + if (fsm->eapolAvail) { + + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + if (rxDesc->info.ackFlag) { + + retVal = checkPeerReplayCounter( + fsm, + data, + &retransmit, + rxDesc->info.micFlag, + 0); // MIC not set means check for re-Tx M1. + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + + if (retransmit) { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Resending EAPOL-Key Msg2 from " + "supplicant to AP" ); + retVal = gotoStateStaKeyStart(fsm, data, eANI_BOOLEAN_TRUE); + + } + else { + retVal = checkMic(fsm, data, rxDesc->info.unicastFlag); + if (retVal != ANI_OK) + { + bapSuppDisconnect( fsm->ctx ); + return retVal; + } + + aniSsmReplayCtrUpdate(fsm->peerReplayCtr, + rxDesc->replayCounter); + + gotoStateStaKeySet(fsm, data, eANI_BOOLEAN_FALSE); + + } + } + } + break; + case STA_KEY_SET: + if (fsm->eapolAvail) + { + fsm->eapolAvail = eANI_BOOLEAN_FALSE; + data = (tAniEapolKeyAvailEventData *) arg; + rxDesc = (tAniEapolRsnKeyDesc *) data->keyDesc; + + retVal = checkPeerReplayCounter( + fsm, + data, + &retransmit, + rxDesc->info.micFlag, + 1); // MIC set means check for re-Tx M3. + if (retVal != ANI_OK) + return ANI_OK; // Caller should not fail + + if (!retransmit) + { + retVal = checkMic(fsm, data, rxDesc->info.unicastFlag); + if (retVal != ANI_OK) + { + bapSuppDisconnect( fsm->ctx ); + return retVal; + } + aniSsmReplayCtrUpdate(fsm->peerReplayCtr, + rxDesc->replayCounter); + + } + + if (rxDesc->info.unicastFlag) + { + /* + * Handle pairwise key message...in this state + * pairwise key messages can only be for retransmissions. + */ + if (retransmit) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Resending EAPOL-Key Msg4 from " + "supplicant \n" ); + retVal = gotoStateStaKeySet(fsm, data, eANI_BOOLEAN_TRUE); + } + } + else + { + /* + * Handle group key message...with group key messages, + * the replay counter has to change on + * retransmissions. + */ + if (!retransmit) + { + retVal = gotoStateGroupKeySet(fsm, data); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + bapSuppDisconnect( fsm->ctx ); + return retVal; + } + } + } + } + else { + if (fsm->integFailed) + { + gotoStateKeyUpdate(fsm, arg); + } + } + break; + case GROUP_KEY_SET: + gotoStateStaKeySet(fsm, NULL, eANI_BOOLEAN_FALSE); + break; + case KEY_UPDATE: + gotoStateRekeyMsg(fsm, arg); + break; + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Illegal state for SuppRsnFsm: %d", + fsm->currentState); + VOS_ASSERT( 0 ); + return ANI_E_FAILED; + } + + return ANI_OK; +} + + + +static int +suppEapolKeyHandler( tSuppRsnFsm *fsm, + tAniPacket *eapolFrame, + tAniMacAddr suppMac) +{ + int retVal; + + int descType; + void *keyDesc; + tAniEapolRsnKeyDesc *rsnDesc; + tAniEapolKeyAvailEventData data; + + do + { + retVal = aniEapolParseKey(eapolFrame, &descType, &keyDesc); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + + if (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + { + rsnDesc = (tAniEapolRsnKeyDesc *) keyDesc; + /* + * Pass on the event to the RSN FSM irrespective if it is + * pairwise or not. + */ + data.keyDesc = keyDesc; + data.eapolFrame = eapolFrame; + retVal = suppRsnFsmProcessEvent(fsm, + RSN_FSM_EAPOL_FRAME_AVAILABLE, + &data); + } + else { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: Got unexpected 802.1x RC4 Key message \n" ); + retVal = ANI_E_FAILED; + break; + } + }while( 0 ); + + aniEapolKeyFreeDesc(descType, keyDesc); + return retVal; +} + + + +// +//This function alwasy assume the incoming vos_packet is 802_3 frame. +static int suppRsnRxFrameHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ) +{ + int retVal = ANI_ERROR; + tAniPacket *pAniPacket; + tBtampContext *ctx; + tSuppRsnFsm *fsm; + /* Validate params */ + if ((pvosGCtx == NULL) || (NULL == pPacket)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return retVal; + } + ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return retVal; + } + + fsm = &ctx->uFsm.suppFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return retVal; + } + + do + { + //ToDO: We need to synchronize this. For now, use the simplest form, drop the packet comes later. + if( fsm->fReceiving ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " ******suppRsnRxFrameHandler receive eapol packet while processing. Drop the new comer\n" ); + break; + } + fsm->fReceiving = VOS_TRUE; + retVal = bapRsnFormPktFromVosPkt( &pAniPacket, pPacket ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + //Now we can process the eapol frame + //handler will free the pAniPacket + bapRsnEapolHandler( fsm, pAniPacket, VOS_FALSE ); + }while( 0 ); + + fsm->fReceiving = VOS_FALSE; + vos_pkt_return_packet( pPacket ); + + return retVal; +} + + +static int suppRsnTxCompleteHandler( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) +{ + tBtampContext *ctx = (tBtampContext *)VOS_GET_BAP_CB( pvosGCtx ); + tAuthRsnFsm *fsm; + + vos_pkt_return_packet( pPacket ); + if (pvosGCtx == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "param is NULL in %s", __func__); + + return ANI_ERROR; + } + + if (NULL == ctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "ctx is NULL in %s", __func__); + + return ANI_ERROR; + } + + fsm = &ctx->uFsm.authFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return ANI_ERROR; + } + + //Synchronization needed + + if(!VOS_IS_STATUS_SUCCESS( retStatus ) ) + { + //This is bad. + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: TL Tx complete with error %d current state is %d\n", retStatus, fsm->currentState ); + if( fsm->numTries <= suppConsts.maxTries ) + { + //retransmit + fsm->numTries++; + if( !VOS_IS_STATUS_SUCCESS( bapRsnSendEapolFrame( fsm->ctx->pvosGCtx, fsm->lastEapol ) ) ) + { + bapSuppDisconnect( fsm->ctx->pvosGCtx ); + } + } + else + { + bapSuppDisconnect( fsm->ctx->pvosGCtx ); + } + } + + return ANI_OK; +} + + +/** + * suppEapolHandler + * + * Handles an incoming EAPOL frame on the supplicant side. + * + * @param eapolFrame the packet containing the EAPOL frame, with the + * head of the packet still at the start of the EAPOL frame + * @param dstMac the dstMac pointing inside the frame + * @param srcMac the srcMac pointing inside the frame + * @param type the type pointing inside the frame at the type field + * + * @return ANI_OK if the operation succeeds + */ +void suppEapolHandler( tSuppRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type ) +{ + switch (*type) + { + case ANI_EAPOL_TYPE_PACKET: + // Ignore EAP becasue it is only WPA2-PSK + break; + case ANI_EAPOL_TYPE_KEY: + suppEapolKeyHandler( fsm, eapolFrame, dstMac ); + break; + case ANI_EAPOL_TYPE_ASF_ALERT: + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp: EAPOL type not implemented: %.2x\n", *type); + break; + } +} diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h new file mode 100644 index 000000000000..7c4eeaf9ed97 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsn8021xSuppRsnFsm.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/auth8021x/ani8021xSuppRsnFsm.h $ + * + * Contains declarations for the RSN EAPOL-Key FSM on the + * supplicant side. This is based on 802.11i. + * + * Author: Mayank D. Upadhyay + * Date: 19-December-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef __AAG_SUPP_RSN_FSM_H +#define __AAG_SUPP_RSN_FSM_H + +#include "bapRsn8021xFsm.h" +#include "bapInternal.h" + +/** + * suppRsnFsmInit + * + * FUNCTION: + * Initializes the constants and the callbacks needed by this FSM + * module. + * + * @param cb callbacks to the various procedures needed by this FSM + * + * @return ANI_OK if the operation succeeds + */ +int +suppRsnFsmInit(void); + +int +suppRsnFsmSetPmk(tSuppContext *ctx, v_U8_t *pmk); + +#endif //__AAG_SUPP_RSN_FSM_H diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.c b/drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.c new file mode 100644 index 000000000000..0b3174298751 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.c @@ -0,0 +1,1020 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $File: //depot/software/projects/feature_branches/nova_phase1/ap/apps/asf/aniAsfPacket.c $ + * Contains definitions for packet manipulation routines that make it + * easy to create and parse multi-layered network frames. This module + * minimizes buffer copies while adding or removing headers, and + * adding or removing payload. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_types.h" +#include "vos_trace.h" +#include +#include +#include "vos_memory.h" +#include "vos_packet.h" + +/* + * Allocate one more than required because the last bytes is waste. We + * waste the last byte because in the adopted model, the tail always + * points to the next location where data should be stored. In a full + * buffer we don't want to position the tail to memory we haven't + * allocated ourself. + */ +#define ANI_INTERNAL_DEFAULT_PACKET_SIZE (ANI_DEFAULT_PACKET_SIZE + 4) + +#define TAIL_SPACE(packet) \ + ((packet)->buf + (packet)->size - (packet)->tail) + +#define HEAD_SPACE(packet) \ + ((packet)->head - (packet)->buf) + +#define ANI_CHECK_RANGE(x , upper) \ + ( (x) <= (upper) ) + +/** + * Opaque packet structure with internal storage for raw bytes. + * Conceptually, a tAniPacket is a pre-allocated buffer that contains + * data in the middle and free space on either side. The start of the + * data is called the head. Routines are provided to add data at the + * front or at the rear. The length of the packet is the total number + * of valid data bytes contained in it. The size of the packet is the + * total number of preallocated bytes. + */ +struct tAniPacket { + v_U8_t *buf; + v_U32_t size; + v_U8_t *head; + v_U8_t *tail; + v_U8_t *recordHeader; + v_U32_t len; +}; + +/** + * aniAsfPacketAllocate + * + * FUNCTION: + * Create a packet of size 2*ANI_DEFAULT_PACKET_SIZE and positions the + * head of the packet in the center. The allocated storage can be free + * with a call to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tAniPacket and its internal raw data + * buffer. Positions the head and tail pointers in the middle of the + * raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tAniPacket if the operation succeeds. + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocate(tAniPacket **packetPtr) +{ + return aniAsfPacketAllocateExplicit(packetPtr, + ANI_INTERNAL_DEFAULT_PACKET_SIZE, + ANI_INTERNAL_DEFAULT_PACKET_SIZE/2); +} + +/** + * aniAsfPacketAllocateExplicit + * + * FUNCTION: + * Create a packet of the desired size and position the head of the + * packet at the desired offset in the internal raw data buffer. An + * application would normally set this offset to the expected length + * of the protocol header, then append the payload, and finally, + * prepend the header. The allocated storage can be free with a call + * to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tAniPacket and its internal raw data + * buffer. Positions the head and tail pointers at the given offset in + * the internal raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tAniPacket if the operation succeeds. + * @param size the size of the internal raw data buffer + * @param offset the offset in the internal raw data buffer where the + * head of the packet will be positioned initially + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocateExplicit(tAniPacket **packetPtr, + v_U32_t size, + v_U32_t offset) +{ + tAniPacket *packet = NULL; + v_U32_t maxHead = size; + + *packetPtr = NULL; + if (size == 0) + return ANI_E_ILLEGAL_ARG; + + VOS_ASSERT(ANI_CHECK_RANGE(offset, maxHead)); + if (!ANI_CHECK_RANGE(offset, maxHead)) + return ANI_E_ILLEGAL_ARG; + + packet = (tAniPacket *) vos_mem_malloc( sizeof(tAniPacket) ); + + if (packet == NULL) + { + VOS_ASSERT( 0 ); + return ANI_E_MALLOC_FAILED; + } + + // transparently add one to the size since last byte is wasted + size = (size + 4) & 0xfffffffc; + + packet->buf = (v_U8_t *)vos_mem_malloc( sizeof(v_U8_t) * size ); + if (packet->buf == NULL) + { + vos_mem_free( packet ); + VOS_ASSERT( 0 ); + return ANI_E_MALLOC_FAILED; + } + + packet->size = size; // Should not be visible to the user + packet->head = packet->buf + offset; + packet->tail = packet->head; + packet->len = 0; + + *packetPtr = packet; + return ANI_OK; +} + +/** + * aniAsfPacketDuplicate + * + * Duplicates a given packet exactly. That is, the contents, the size + * of the packet, and the positions of the pointers are maintained in + * the new copy. + * + * @param newPacketPtr is set to a newly allocated packet that is a + * duplicate of oldPacket + * @param oldPacket the original packet that should be duplicated + * + * @return ANI_OK if the operation succeeds; ANI_E_NULL if oldPacket + * is NULL; + */ +int +aniAsfPacketDuplicate(tAniPacket **newPacketPtr, tAniPacket *oldPacket) +{ + int retVal; + int recordPos; + tAniPacket *packet = NULL; + + if (oldPacket == NULL) + return ANI_E_NULL_VALUE; + + retVal = aniAsfPacketAllocateExplicit(&packet, + oldPacket->size, + oldPacket->head - oldPacket->buf); + if (retVal != ANI_OK) + return retVal; + + retVal = aniAsfPacketAppendBuffer(packet, + oldPacket->head, + oldPacket->len); + if (retVal != ANI_OK) + { + VOS_ASSERT( 0 ); + aniAsfPacketFree(packet); + return ANI_E_FAILED; + } + + if (oldPacket->recordHeader != NULL) + { + recordPos = oldPacket->recordHeader - oldPacket->buf; + packet->recordHeader = packet->buf + recordPos; + } + *newPacketPtr = packet; + + return ANI_OK; +} + +/** + * aniAsfPacketFree + * + * FUNCTION: + * Free a previously allocated tAniPacket and its internal raw data + * buffer. + * + * @param packet the packet to free + * + * @return ANI_OK if the operation succeeds; ANI_E_NULL_VALUE if an + * unexpected NULL pointer is encountered + */ +int +aniAsfPacketFree(tAniPacket *packet) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (packet->buf != NULL) + vos_mem_free( packet->buf ); + + vos_mem_free( packet ); + + return ANI_OK; +} + + +/** + * aniAsfPacketAppendBuffer + * + * FUNCTION: + * Appends the data contained in buf to the end of the data in + * destAniPacket. The head of destAniPacket remains unchanged, while its + * length increases by len. + * + * If there isn't enough free space in destAniPacket for all len bytes + * then the routine fails and the length of destAniPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to append the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to append to + * @param buf the buffer containing data to be appended to the packet + * @param len the number of bytes to append + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketPrependBuffer + */ +int +aniAsfPacketAppendBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len) +{ + if (aniAsfPacketCanAppendBuffer(destPacket, len) != ANI_OK) + return ANI_E_FAILED; + + if (buf == NULL) + return ANI_E_NULL_VALUE; + + vos_mem_copy(destPacket->tail, buf, len); + destPacket->tail += len; + destPacket->len += len; + return ANI_OK; +} + +/** + * aniAsfPacketPrependBuffer + * + * FUNCTION: + * Prepends the data contained in buf to the start of the data in + * destPacket. The head of destPacket is repositioned and the length + * of destPacket increases by len. + * + * If there isn't enough free space in destPacket for all len bytes + * then the routine fails and the length of destPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to prepend the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to prepend to + * @param buf the buffer containing data to be prepended to the packet + * @param len the number of bytes to prepend + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketAppendBuffer + */ +int +aniAsfPacketPrependBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len) +{ + if (aniAsfPacketCanPrependBuffer(destPacket, len) != ANI_OK) + return ANI_E_FAILED; + + if (buf == NULL) + return ANI_E_NULL_VALUE; + + destPacket->head -= len; + destPacket->len += len; + vos_mem_copy(destPacket->head, buf, len); + return ANI_OK; + +} + +/** + * aniAsfPacketCanAppendBuffer + * + * FUNCTION: + * Determines if len bytes can be safely appended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet tail plus len of buffer should not exceed packet + * start plus packet size + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to append to + * @param len the number of bytes to append + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanAppendBuffer(tAniPacket *destPacket, + v_U32_t len) +{ + if (destPacket == NULL) + return ANI_E_FAILED; + + if ((int)len <= TAIL_SPACE(destPacket)) + return ANI_OK; + else + return ANI_E_FAILED; +} + +/** + * aniAsfPacketCanPrependBuffer + * + * FUNCTION: + * Determines if len bytes can be safely prepended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet head minus len of buffer should not be less than + * start of packet. + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to prepend to + * @param len the number of bytes to prepend + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanPrependBuffer(tAniPacket *destPacket, + v_U32_t len) +{ + if (destPacket == NULL) + return ANI_E_FAILED; + + if (!(len > 0)) + return ANI_E_FAILED; + + if ((int)len <= HEAD_SPACE(destPacket)) + return ANI_OK; + else + return ANI_E_FAILED; +} + +/** + * aniAsfPacketTruncateFromFront + * + * FUNCTION: + * Removes len bytes from the front of the packet by moving its + * head. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the front + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromFront(tAniPacket *packet, + v_U32_t len) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (!ANI_CHECK_RANGE(len, packet->len)) + return ANI_E_FAILED; + + packet->head += len; + packet->len -= len; + + return ANI_OK; +} + +/** + * aniAsfPacketTruncateFromRear + * + * FUNCTION: + * Removes len bytes from the rear of the packet by moving its + * tail. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the rear + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromRear(tAniPacket *packet, + v_U32_t len) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (!ANI_CHECK_RANGE(len, packet->len)) + return ANI_E_FAILED; + + packet->tail -= len; + packet->len -= len; + + return ANI_OK; +} + +/** + * aniAsfPacketGetLen + * + * FUNCTION: + * Returns the number of valid data bytes stored in the packet. + * + * @param packet the packet whose len we need + * + * @return the non-negative number of bytes stored in the packet + */ +int +aniAsfPacketGetLen(tAniPacket *packet) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + return packet->len; +} + +/** + * aniAsfPacketGetBytes + * + * FUNCTION: + * Returns a pointer to the head of the valid data stored in the + * packet. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytes(tAniPacket *packet, v_U8_t **rawBytesPtr) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + *rawBytesPtr = packet->head; + return packet->len; +} + +/** + * aniAsfPacketGetN + * + * Returns N bytes from the packet and moves the head of the packet + * beyond those bytes. + * + * @param packet the packet to read from + * @param n the number of bytes to read + * @param bytesPtr is set to the start of the octets + * + * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the + * packet does not have n bytes. + */ +int +aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr) +{ + int retVal; + v_U8_t *bytes = NULL; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + retVal = aniAsfPacketGetBytes(packet, &bytes); + if (retVal < n) + return ANI_E_SHORT_PACKET; + + aniAsfPacketTruncateFromFront(packet, n); + + *bytesPtr = bytes; + + return ANI_OK; +} + +/** + * aniAsfPacketEmpty + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the middle and + * setting the length to zero. + * + * @param packet the packet to empty + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmpty(tAniPacket *packet) +{ + return aniAsfPacketEmptyExplicit(packet, packet->size/2); +} + +/** + * aniAsfPacketEmptyExplicit + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the desired + * offset and setting the length to zero. + * + * @param packet the packet to empty + * @param offset the offset that the head of the packet should be set + * to. An application will be able to prepend and append data relative + * to this offset. + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmptyExplicit(tAniPacket *packet, + v_U32_t offset) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + VOS_ASSERT(ANI_CHECK_RANGE(offset, packet->size)); + if (!ANI_CHECK_RANGE(offset, packet->size)) + return ANI_E_ILLEGAL_ARG; + + packet->head = packet->buf + offset; + packet->tail = packet->head; + packet->len = 0; + + return ANI_OK; +} + + + +/** + * aniAsfPacketPrependHdr + * + * FUNCTION: + * Prepends a tAniHdr at the start of the packet. All host to network + * byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param msgType the message type to write as part of the header + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrependHdr(tAniPacket *packet, v_U16_t msgType) +{ + int retVal; + int length; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + length = 4; + + length = 2 + 2 + packet->len; + + retVal = aniAsfPacketPrepend16(packet, length); + if (retVal < 0) + return retVal; + + retVal = aniAsfPacketPrepend16(packet, msgType); + if (retVal < 0) + return retVal; + + return ANI_OK; +} + +/** + * aniAsfPacketGet32 + * + * FUNCTION: + * Reads a ANI_U32 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet32(tAniPacket *packet, v_U32_t *val) +{ + v_U8_t u32Arr[4]; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (val == NULL) + return ANI_E_NULL_VALUE; + + if (packet->len < 4) + return ANI_E_SHORT_PACKET; + + //packet is in network order, make sure it is align + u32Arr[0] = packet->head[0]; + u32Arr[1] = packet->head[1]; + u32Arr[2] = packet->head[2]; + u32Arr[3] = packet->head[3]; + *val = vos_be32_to_cpu( *(v_U32_t *)u32Arr ); + aniAsfPacketTruncateFromFront(packet, 4); + + return ANI_OK; +} + +/** + * aniAsfPacketAppend32 + * + * FUNCTION: + * Appends a ANI_U32 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend32(tAniPacket *packet, v_U32_t val) +{ + v_U8_t *p8; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (TAIL_SPACE(packet) < 4) + return ANI_E_FAILED; + + val = vos_cpu_to_be32( val ); + p8 = (v_U8_t *)&val; + packet->tail[0] = p8[0]; + packet->tail[1] = p8[1]; + packet->tail[2] = p8[2]; + packet->tail[3] = p8[3]; + aniAsfPacketMoveRight(packet, 4); + + return ANI_OK; +} + +/** + * aniAsfPacketGet16 + * + * FUNCTION: + * Reads a ANI_U16 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet16(tAniPacket *packet, v_U16_t *val) +{ + v_U8_t u16Arr[2]; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (val == NULL) + return ANI_E_NULL_VALUE; + + if (packet->len < 2) + return ANI_E_SHORT_PACKET; + + u16Arr[0] = packet->head[0]; + u16Arr[1] = packet->head[1]; + *val = vos_be16_to_cpu( *(v_U16_t *)u16Arr ); + aniAsfPacketTruncateFromFront(packet, 2); + + return ANI_OK; +} + +/** + * aniAsfPacketPrepend16 + * + * FUNCTION: + * Prepends a ANI_U16 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend16(tAniPacket *packet, v_U16_t val) +{ + v_U8_t *p8; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (HEAD_SPACE(packet) < 2) + return ANI_E_FAILED; + + aniAsfPacketMoveLeft(packet, 2); + val = vos_cpu_to_be16( val ); + p8 = (v_U8_t *)&val; + packet->head[0] = p8[0]; + packet->head[1] = p8[1]; + + return ANI_OK; +} + +/** + * aniAsfPacketAppend16 + * + * FUNCTION: + * Appends a ANI_U16 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend16(tAniPacket *packet, v_U16_t val) +{ + v_U8_t *p8; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (TAIL_SPACE(packet) < 2) + return ANI_E_FAILED; + + val = vos_cpu_to_be16( val ); + p8 = (v_U8_t *)&val; + packet->tail[0] = p8[0]; + packet->tail[1] = p8[1]; + aniAsfPacketMoveRight(packet, 2); + + return ANI_OK; +} + +/** + * aniAsfPacketGet8 + * + * FUNCTION: + * Reads a ANI_U8 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet8(tAniPacket *packet, v_U8_t *val) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (val == NULL) + return ANI_E_NULL_VALUE; + + if (packet->len < 1) + return ANI_E_SHORT_PACKET; + + *val = *(packet->head); + aniAsfPacketTruncateFromFront(packet, 1); + + return ANI_OK; +} + +/** + * aniAsfPacketPrepend8 + * + * FUNCTION: + * Prepends a ANI_U8 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend8(tAniPacket *packet, v_U8_t val) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + VOS_ASSERT(HEAD_SPACE(packet) >= 1); + if (HEAD_SPACE(packet) < 1) + return ANI_E_FAILED; + + aniAsfPacketMoveLeft(packet, 1); + *(packet->head) = val; + + return ANI_OK; +} + +/** + * aniAsfPacketAppend8 + * + * FUNCTION: + * Appends a ANI_U8 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend8(tAniPacket *packet, v_U8_t val) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + if (TAIL_SPACE(packet) < 1) + return ANI_E_FAILED; + + *(packet->tail) = val; + aniAsfPacketMoveRight(packet, 1); + + return ANI_OK; +} + +/** + * aniAsfPacketGetMac + * + * FUNCTION: + * Returns a tAniMacAddr from the start of the packet. + * + * @param packet the packet to read from + * @param macAddr the destination to copy the MAC address to + * + * @return ANI_OK if the operation succeeds. Also, the packet head + * pointer is advanced past the MAC address. + */ +int +aniAsfPacketGetMac(tAniPacket *packet, tAniMacAddr macAddr) +{ + if (packet->len < sizeof(tAniMacAddr)) + return ANI_E_SHORT_PACKET; + + vos_mem_copy(macAddr, packet->head, sizeof(tAniMacAddr)); + + packet->head += sizeof(tAniMacAddr); + packet->len -= sizeof(tAniMacAddr); + + return ANI_OK; +} + +/** + * aniAsfPacketMoveLeft + * + * FUNCTION: + * Pretends that a certain number of bytes have been prepended to the + * packet, without actually copying any bytes in. The packet head and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move head and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveLeft(tAniPacket *packet, v_U32_t count) +{ + if (aniAsfPacketCanPrependBuffer(packet, count) != ANI_OK) + return ANI_E_FAILED; + + packet->head -= count; + packet->len += count; + + return ANI_OK; +} + +/** + * aniAsfPacketMoveRight + * + * FUNCTION: + * Pretends that a certain number of bytes have been appended to the + * packet, without actually copying any bytes in. The packet tail and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move tail and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveRight(tAniPacket *packet, v_U32_t count) +{ + if (aniAsfPacketCanAppendBuffer(packet, count) != ANI_OK) + return ANI_E_FAILED; + + packet->tail += count; + packet->len += count; + + return ANI_OK; +} + +/** + * aniAsfPacketGetBytesFromTail + * + * FUNCTION: + * Returns a pointer to the tail of the valid data stored + * in the packet. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a three-step process - one: call this + * routine to obtain a pointer to the current tail of the packet. + * two: treat this returned pointer like a simple array and copy + * some bytes to the packet's internal buffer, and finally + * three: move tail and length. This violates the encapsulation + * the packet library aims to provide. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytesFromTail(tAniPacket *packet, v_U8_t **rawBytesPtr) +{ + if (packet == NULL) + return ANI_E_NULL_VALUE; + + *rawBytesPtr = packet->tail; + return 0; // The length of used bytes returned is zero +} + diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.h b/drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.h new file mode 100644 index 000000000000..31d4face476d --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnAsfPacket.h @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $File: //depot/software/projects/feature_branches/nova_phase1/ap/apps/include/aniAsfPacket.h $ + * Contains declarations for packet manipulation routines that make it + * easy to create and parse multi-layered network frames. This module + * minimizes buffer copies while adding or removing headers, and + * adding or removing payload. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef _ANI_ASF_PACKET_H_ +#define _ANI_ASF_PACKET_H_ + +#include "vos_types.h" +#include "palTypes.h" + +#define ANI_ETH_FRAME_LEN 1516 +#define ANI_DEFAULT_PACKET_SIZE (ANI_ETH_FRAME_LEN*2) + +/** + * Opaque packet structure with internal storage for raw bytes. + * Conceptually, a tPacket is a pre-allocated buffer that contains + * data in the middle and free space on either side. The start of the + * data is called the head. Routines are provided to add data at the + * front or at the rear. The length of the packet is the total number + * of valid data bytes contained in it. The size of the packet is the + * total number of preallocated bytes. + */ +typedef struct tAniPacket tAniPacket; + +/** + * aniAsfPacketAllocate + * + * FUNCTION: + * Create a packet of size 2*ANI_DEFAULT_PACKET_SIZE and positions the + * head of the packet in the center. The allocated storage can be free + * with a call to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tPacket and its internal raw data + * buffer. Positions the head and tail pointers in the middle of the + * raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tPacket if the operation succeeds. + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocate(tAniPacket **packetPtr); + +/** + * aniAsfPacketDuplicate + * + * Duplicates a given packet exactly. That is, the contents, the size + * of the packet, and the positions of the pointers are maintained in + * the new copy. + * + * @param newPacketPtr is set to a newly allocated packet that is a + * duplicate of oldPacket + * @param oldPacket the original packet that should be duplicated + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketDuplicate(tAniPacket **newPacketPtr, tAniPacket *oldPacket); + +/** + * aniAsfPacketAllocateExplicit + * + * FUNCTION: + * Create a packet of the desired size and position the head of the + * packet at the desired offset in the internal raw data buffer. An + * application would normally set this offset to the expected length + * of the protocol header, then append the payload, and finally, + * prepend the header. The allocated storage can be free with a call + * to aniAsfPacketFree. + * + * LOGIC: + * Allocates storage for tPacket and its internal raw data + * buffer. Positions the head and tail pointers at the given offset in + * the internal raw data buffer. + * + * @param packetPtr pointer that will be set to newly allocated + * tPacket if the operation succeeds. + * @param size the size of the internal raw data buffer + * @param offset the offset in the internal raw data buffer where the + * head of the packet will be positioned initially + * + * @return ANI_OK if the operation succeeds; ANI_E_MALLOC_FAILED if + * memory could not be allocated. + * @see aniAsfPacketFree + */ +int +aniAsfPacketAllocateExplicit(tAniPacket **packetPtr, + v_U32_t size, + v_U32_t offset); + +/** + * aniAsfPacketFree + * + * FUNCTION: + * Free a previously allocated tPacket and its internal raw data + * buffer. + * + * @param packet the packet to free + * + * @return ANI_OK if the operation succeeds; ANI_E_NULL_VALUE if an + * unexpected NULL pointer is encountered + */ +int +aniAsfPacketFree(tAniPacket *packet); + +/** + * aniAsfPacket2Str + * + * FUNCTION: + * Returns a printable representation of the data contained in the + * packet. + * Note: This function returns a static buffer used by aniAsfHexStr. + * + * @param packet the packet whose contents need to be printed + */ +v_U8_t *aniAsfPacket2Str(tAniPacket *packet); + +/** + * aniAsfPacketAppendBuffer + * + * FUNCTION: + * Appends the data contained in buf to the end of the data in + * destPacket. The head of destPacket remains unchanged, while its + * length increases by len. + * + * If there isn't enough free space in destPacket for all len bytes + * then the routine fails and the length of destPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to append the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to append to + * @param buf the buffer containing data to be appended to the packet + * @param len the number of bytes to append + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketPrependBuffer + */ +int +aniAsfPacketAppendBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len); + +/** + * aniAsfPacketPrependBuffer + * + * FUNCTION: + * Prepends the data contained in buf to the start of the data in + * destPacket. The head of destPacket is repositioned and the length + * of destPacket increases by len. + * + * If there isn't enough free space in destPacket for all len bytes + * then the routine fails and the length of destPacket remains + * unchanged. + * + * LOGIC: + * Check that there is enough free space in the packet to prepend the + * buffer. If not, bail. Otherwise, copy bytes from the buffer into + * the packet's internal raw data buffer and increase the value of its + * length to reflect this. + * + * @param packet the packet to prepend to + * @param buf the buffer containing data to be prepended to the packet + * @param len the number of bytes to prepend + * + * @return ANI_OK if the operation succeeds; ANI_E_FAILED if the + * packet does not have enough free space for the complete buffer + * @see aniAsfPacketAppendBuffer + */ +int +aniAsfPacketPrependBuffer(tAniPacket *destPacket, + const v_U8_t *buf, + v_U32_t len); + +/** + * aniAsfPacketCanAppendBuffer + * + * FUNCTION: + * Determines if len bytes can be safely appended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet tail plus len of buffer should not exceed packet + * start plus packet size + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to append to + * @param len the number of bytes to append + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanAppendBuffer(tAniPacket *destPacket, + v_U32_t len); + +/** + * aniAsfPacketCanPrependBuffer + * + * FUNCTION: + * Determines if len bytes can be safely prepended to destPacket + * without overflowing. + * + * LOGIC: + * Current packet head minus len of buffer should not be less than + * start of packet. + * + * Note: This does not return a boolean value, but instead an integer + * code. + * + * @param packet the packet to prepend to + * @param len the number of bytes to prepend + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketCanPrependBuffer(tAniPacket *destPacket, + v_U32_t len); + +/** + * aniAsfPacketTruncateFromFront + * + * FUNCTION: + * Removes len bytes from the front of the packet by moving its + * head. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the front + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromFront(tAniPacket *packet, + v_U32_t len); + +/** + * aniAsfPacketTruncateFromRear + * + * FUNCTION: + * Removes len bytes from the rear of the packet by moving its + * tail. The length of the packet is decremented by len. + * + * @param packet the packet to truncate from the rear + * @param len the number of bytes to truncate + * + * @return ANI_OK if the append operation would succeed; ANI_E_FAILED + * otherwise + */ +int +aniAsfPacketTruncateFromRear(tAniPacket *packet, + v_U32_t len); + +/** + * aniAsfPacketGetLen + * + * FUNCTION: + * Returns the number of valid data bytes stored in the packet. + * + * @param packet the packet whose len we need + * + * @return the non-negative number of bytes stored in the packet + */ +int +aniAsfPacketGetLen(tAniPacket *packet); + +/** + * aniAsfPacketGetBytes + * + * FUNCTION: + * Returns a pointer to the head of the valid data stored in the + * packet. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytes(tAniPacket *packet, v_U8_t **rawBytesPtr); + +/** + * aniAsfPacketGetN + * + * Returns N bytes from the packet and moves the head of the packet + * beyond those bytes. + * + * @param packet the packet to read from + * @param n the number of bytes to read + * @param bytesPtr is set to the start of the octets + * + * @return ANI_OK if the operation succeeds; ANI_E_SHORT_PACKET if the + * packet does not have n bytes. + */ +int +aniAsfPacketGetN(tAniPacket *packet, int n, v_U8_t **bytesPtr); + +/** + * aniAsfPacketEmpty + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the middle and + * setting the length to zero. + * + * @param packet the packet to empty + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmpty(tAniPacket *packet); + +/** + * aniAsfPacketEmptyExplicit + * + * FUNCTION: + * Re-initializes the packet by positioning the head to the desired + * offset and setting the length to zero. + * + * @param packet the packet to empty + * @param offset the offset that the head of the packet should be set + * to. An application will be able to prepend and append data relative + * to this offset. + * + * @return ANI_OK if the operation succeeded + */ +int +aniAsfPacketEmptyExplicit(tAniPacket *packet, + v_U32_t offset); + + +/** + * aniAsfPacketPrependHdr + * + * FUNCTION: + * Prepends a tAniHdr at the start of the packet. All host to network + * byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param msgType the message type to write as part of the header + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrependHdr(tAniPacket *packet, v_U16_t msgType); + +/** + * aniAsfPacketGet32 + * + * FUNCTION: + * Reads a ANI_U32 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet32(tAniPacket *packet, v_U32_t *val); + +/** + * aniAsfPacketAppend32 + * + * FUNCTION: + * Appends a ANI_U32 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend32(tAniPacket *packet, v_U32_t val); + +/** + * aniAsfPacketGet16 + * + * FUNCTION: + * Reads a ANI_U16 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet16(tAniPacket *packet, v_U16_t *val); + +/** + * aniAsfPacketPrepend16 + * + * FUNCTION: + * Prepends a ANI_U16 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend16(tAniPacket *packet, v_U16_t val); + +/** + * aniAsfPacketAppend16 + * + * FUNCTION: + * Appends a ANI_U16 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend16(tAniPacket *packet, v_U16_t val); + +/** + * aniAsfPacketGet8 + * + * FUNCTION: + * Reads a ANI_U8 out of the packet and returns it. The packet's head + * is advanced and its length decremented by the appropriate length. + * All network to host byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to fill in + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketGet8(tAniPacket *packet, v_U8_t *val); + +/** + * aniAsfPacketPrepend8 + * + * FUNCTION: + * Prepends a ANI_U8 to the start of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to read from + * @param val the value to prepend + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketPrepend8(tAniPacket *packet, v_U8_t val); + +/** + * aniAsfPacketAppend8 + * + * FUNCTION: + * Appends a ANI_U8 to the end of the packet. + * All host to network byte order translation is also taken care of. + * + * @param packet the packet to write to + * @param val the value to append + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketAppend8(tAniPacket *packet, v_U8_t val); + +/** + * aniAsfPacketGetMac + * + * FUNCTION: + * Returns a tAniMacAddr from the start of the packet. + * + * @param packet the packet to read from + * @param macAddr the destination to copy the MAC address to + * + * @return ANI_OK if the operation succeeds. Also, the packet head + * pointer is advanced past the MAC address. + */ +int +aniAsfPacketGetMac(tAniPacket *packet, tAniMacAddr macAddr); + +/** + * aniAsfPacketMoveLeft + * + * FUNCTION: + * Pretends that a certain number of bytes have been prepended to the + * packet, without actually copying any bytes in. The packet head and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move head and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveLeft(tAniPacket *packet, v_U32_t count); + +/** + * aniAsfPacketMoveRight + * + * FUNCTION: + * Pretends that a certain number of bytes have been appended to the + * packet, without actually copying any bytes in. The packet tail and + * length are appropriately changed. This function is useful while + * interfacing with other libraries that only support byte array + * manipulation. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a two-step process - one: copy some bytes + * to the packet's internal buffer, two: move tail and length. This + * violates the encapsulation the packet library aims to provide. + * + * @param packet the packet whose head and length needs to be modified + * @param count the number of bytes to modify by + * + * @return ANI_OK if the operation succeeds + */ +int +aniAsfPacketMoveRight(tAniPacket *packet, v_U32_t count); + +/** + * aniAsfPacketGetBytesFromTail + * + * FUNCTION: + * Returns a pointer to the tail of the valid data stored + * in the packet. + * + * WARNING: + * Applications are discouraged from using this function + * because correct usage is a three-step process - one: call this + * routine to obtain a pointer to the current tail of the packet. + * two: treat this returned pointer like a simple array and copy + * some bytes to the packet's internal buffer, and finally + * three: move tail and length. This violates the encapsulation + * the packet library aims to provide. + * + * @param packet the packet whose bytes we need + * @param rawBytesPtr the pointer that will be set the start of the + * raw bytes. + * + * @return The non-negative number of bytes stored in the packet if + * the operation succeeded. That is the same value as what would be + * returned by aniAsfPacketGetLen. + */ +int +aniAsfPacketGetBytesFromTail(tAniPacket *packet, v_U8_t **rawBytesPtr); + + +#endif // _ANI_ASF_PACKET_H_ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnErrors.h b/drivers/staging/prima/CORE/BAP/src/bapRsnErrors.h new file mode 100644 index 000000000000..aa0cda3d181e --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnErrors.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniErrors.h $ + * + * Contains definitions of error codes that are globally visible + * across WNI applications. There are two kinds of error codes: + * generic error codes and module specific error codes. Module specific + * error codes can further be of two kinds: those that are used + * internally within sub-modules, and those that are made visible + * to other modules. Each module will be pre-allocated a range of + * negative integers from which to choose both internal and external + * error codes uniquely. Note that internally used error codes need + * not be defined in this file so long as they adhere to the allocated + * range. + * + * Author: Mayank D. Upadhyay + * Date: 17-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#ifndef _ANI_ERRORS_H_ +#define _ANI_ERRORS_H_ + +/** + * Indicates that the function returned successfully and no error was + * reported. + */ +#define ANI_OK 0 +#define ANI_ERROR ANI_E_FAILED + +/** + * The range -1 to -1024 is reserved for generic error codes that are + * applicable to all modules. + */ + +#define ANI_E_FAILED -1 /// Generic error code for failure +#define ANI_E_MALLOC_FAILED -2 /// Mem allocation failed +#define ANI_E_ILLEGAL_ARG -3 /// Function argument is illegal +#define ANI_E_NULL_VALUE -4 /// Encountered unexpected NULL value +#define ANI_E_RAND_FAILED -5 /// RNG failed +#define ANI_E_SHORT_PACKET -6 /// Packet is too small to contain data +#define ANI_E_ELEM_NOT_FND -7 /// Element not found +#define ANI_E_INVALID_LEN -8 /// Element has invalid Length +#define ANI_E_INVALID_DT -9 /// Invalid Data Type +#define ANI_E_TIMEOUT -10 /// Timeout occurred +#define ANI_E_DBM_INVALID_ID -11 /// Invalid DB id sent to server +#define ANI_E_DBM_KEY_NOT_FOUND -12 /// Key's mapping was not found +#define ANI_E_FILE_EMPTY -13 /// file empty +#define ANI_E_INVALID_MT -14 /// Invalid ANI message type +#define ANI_E_NOT_IMPLEMENTED -15 /// Feature not implemented +#define ANI_E_INVALID_PT -16 /// Invalid Parameter Type +#define ANI_E_INVALID_PV -17 /// Invalid Paramter Value +#define ANI_E_IPCOPEN -18 /// IPC open failed +#define ANI_E_IPCCONNECT -19 /// IPC connect failed +#define ANI_E_IPCSEND -20 /// IPC send failed +#define ANI_E_FILE_NOT_FOUND -21 /// file not found +#define ANI_E_FILE_INVALID_CONTENT -22 /// invalid file content +#define ANI_E_FILE_READ_FAILED -23 /// file read failed + +// ***** SSM libraries and applications use the range -1025 to -2999 ***** + +/* + * The range -1025 to -2048 is reserved for use by the + * authentication agent and its sub-modules. The sub-range -1029 to + * -1150 is reserved for CLI usage. + */ +#define ANI_E_RANGE_START_AAG -1025 + +// CLI Range starts here... +#define ANI_E_RANGE_START_AAG_CLI -1029 +#define ANI_E_CLI_ARG_MISSING -1029 // CLI command param missing +#define ANI_E_CLI_ARG_INVALID -1030 // CLI command param invalid +#define ANI_E_CLI_PAM_RADIUS_DB_UPDATE_FAILURE -1031 // Failure to update PAM RADIUS DB +#define ANI_E_CLI_AUTH_SERVER_NOT_FOUND -1032 // Auth server not found +#define ANI_E_CLI_SYS_INTERNAL_ERROR_PACKET_NULL -1033 // Internal error +#define ANI_E_CLI_INVALID_DEVICE -1034 // Invalid device +#define ANI_E_CLI_AUTH_SERVER_INVALID_IPADDR -1035 // Invalid IP addr +#define ANI_E_CLI_AUTH_ZONE_NOT_EMPTY -1036 // zone not empty +#define ANI_E_CLI_AUTH_ZONE_AUTH_SERVERS_NOT_COPIED -1037 // zone not copied +#define ANI_E_CLI_AUTH_ZONE_NAME_MISSING -1038 // zone name missing +#define ANI_E_CLI_AUTH_ZONE_EMPTY -1039 // zone empty +#define ANI_E_CLI_AUTH_ZONE_NOT_FOUND -1040 // zone not found +#define ANI_E_CLI_AUTH_SERVER_ARG_NOT_FOUND -1041 // Cli Auth server arg missing +#define ANI_E_CLI_IFNAME_ARG_NOT_FOUND -1042 // Ifname arg missing +#define ANI_E_CLI_KEYINDEX_ARG_NOT_FOUND -1043 // Keyindex arg missing +#define ANI_E_CLI_KEYLENGTH_ARG_NOT_FOUND -1044 // KeyLength arg missing +#define ANI_E_CLI_KEYLENGTH_ARG_INVALID -1045 // KeyLength arg invalid +#define ANI_E_CLI_SET_WEP_KEY_FAILED -1046 // Set Wep key failed +#define ANI_E_CLI_SYS_INTERNAL_ERROR -1047 // Internal error +#define ANI_E_CLI_OLD_PASSWORD_MISSING -1048 // Old password missing +#define ANI_E_CLI_NEW_PASSWORD_MISSING -1049 // New password + // missing +#define ANI_E_CLI_WEP_KEY_LEN_ERROR -1051 // key length error +#define ANI_E_CLI_WEP_KEY_HEX_ERROR -1052 // no hex character +#define ANI_E_CLI_WPA_MODES_CFG_ERROR -1053 // WPA config error +#define ANI_E_CLI_WEP_AND_OPEN_CFG_ERROR -1054 // WEP and open error +#define ANI_E_CLI_OPEN_AND_WEP_CFG_ERROR -1055 // open and WEP error +#define ANI_E_CLI_LEGACY_WEP_AND_OPEN_CFG_ERROR -1056 // WEP and open error +#define ANI_E_CLI_OPEN_AND_LEGACY_WEP_CFG_ERROR -1057 // open and WEP error +#define ANI_E_CLI_WPA_MODES_NOT_AVAILABLE -1058 // WPA modes not active +#define ANI_E_CLI_INVALID_LISENCE_KEY -1059 // invalid license +#define ANI_E_CLI_EXISTING_LISENCE_KEY -1060 // duplicated license +#define ANI_E_CLI_WEP_INVALID_LENGTH_CHANGE -1061 // invalid length change +#define ANI_E_CLI_CNF_PASSWORD_MISMATCH -1062 // confirm password mismatch +#define ANI_E_CLI_INVALID_DISABLE -1063 // cannot disable all sec modes +#define ANI_E_CLI_PACKNUM_RANGE_ERROR -1064 // cannot disable all sec modes +#define ANI_E_CLI_IP_ADDR_INVALID -1065 // IP address invalid +#define ANI_E_CLI_AUTH_ZONE_NAME_INVALID -1066 // zone name invalid +#define ANI_E_CLI_OLD_PASSWORD_INVALID -1067 // Old password invalid +#define ANI_E_CLI_NO_EXT_RAD_ON_NONSECP -1068 // Cannot add ext auth-server on + // non-SEC/P with RAD proxying on +#define ANI_E_CLI_NO_EXT_AUTH_ZONE_ALLOWED -1069 // Cannot add ext auth-zone on + // with RAD proxying on +#define ANI_E_CLI_PORTAL_ZONE_AUTO_CONFIGURED -1070 // Cannot manage portal auth-zone +#define ANI_E_CLI_DEL_REQ_ON_REF_AUTH_SERVER -1071 // Cannot delete auth-server + // that is in a zone +#define ANI_E_CLI_DEL_REQ_ON_REF_AUTH_ZONE -1072 // Cannot delete auth-zone + // that is used by SSID +#define ANI_E_CLI_INVALID_INTERIM_UPDT_VALUE -1073 // Invalid Accounting interim update interval +#define ANI_E_RANGE_END_AAG_CLI -1199 +// ...CLI Range ends here + +// Non-CLI related error codes.. +#define ANI_E_MIC_FAILED -1200 // A MIC check failed +#define ANI_E_REPLAY_CHECK_FAILED -1201 // Replay Ctr mismatch +#define ANI_E_RADIUS_PROFILE_MISSING -1202 // User profile + // not found +#define ANI_E_AUTH_FAILED -1203 // Authentication failed +#define ANI_E_RADIUS_PRIV_LEVEL_MISSING -1204 // ANI_ADMIN_LEVEL is missing +#define ANI_E_RADIUS_PRIV_LEVEL_INCORRECT -1205 // ANI_ADMIN_LEVEL is incorrect + +// For some reason this is not contiguous with the other error codes(???) +#define ANI_E_INVALID_COOKIE -1300 // Invalid cookie + +#define ANI_E_RANGE_END_AAG -2048 + +/* + * The range -2049 to -2148 is reserved for use by the + * RADIUS client side library. + */ +#define ANI_E_RANGE_START_RAD -2049 +#define ANI_E_RAD_FAILED -2049 /// RADIUS operation failed +#define ANI_E_RAD_ATTR_TOO_LONG -2050 /// Attribute too long +#define ANI_E_RAD_UNSOLICITED_RESP -2051 /// Unsolicited response +#define ANI_E_RAD_BAD_RESP_AUTH -2052 /// Response auth check failed +#define ANI_E_RAD_BAD_MESSG_AUTH -2053 /// Response signature invalid +#define ANI_E_RAD_ATTR_NOT_FOUND -2054 /// Requested attr not found +#define ANI_E_RAD_TIMEOUT -2055 /// Request timed out waiting for server +#define ANI_E_RAD_REJECT -2056 /// Radius server did not accept user +#define ANI_E_RANGE_END_RAD -2148 + +/* + * The range -2149 to -2999 is reserved for use by the SSM library. + */ +#define ANI_E_RANGE_START_SSM -2149 +#define ANI_E_SSM_CERT_UNPARSEABLE (ANI_E_RANGE_START_SSM - 1) +#define ANI_E_SSM_CERT_EXPIRED (ANI_E_RANGE_START_SSM - 2) +#define ANI_E_SSM_CERT_THUMBPRINT_MISMATCH (ANI_E_RANGE_START_SSM - 3) +#define ANI_E_SSM_CERT_NEW_ID (ANI_E_RANGE_START_SSM - 4) +#define ANI_E_RANGE_END_SSM -2999 + +/* + * The range -3000 to -3500 is reserved for use by the + * NetSim Server, Client, Client Modules and Pseudo driver + */ +#define ANI_E_RANGE_START_NETSIM -3000 +#define ANI_E_RANGE_END_NETSIM -3500 + +/* + * The range -3501 to -4000 is reserved for use by the + * Discovery Server and its libraries. + */ +#define ANI_E_RANGE_START_DISC -3501 +#define ANI_E_RANGE_END_DISC -4000 + +/* + * The range -4001 to -4500 is reserved for use by the + * Ezcfg Server + */ +#define ANI_E_RANGE_START_EZC -4001 + +// See file aniNmpEzcSvcMsgs.h for EZC specific error codes and messages +#define ANI_E_RANGE_END_EZC -4500 + +/* + * The range -4501 to -4600 is reserved for use by the + * Software Download (SWD) Server + */ +#define ANI_E_RANGE_START_SWD -4501 + +// See file aniSwdSvcMsgs.h for SWD specific error codes and messages +#define ANI_E_RANGE_END_SWD -4600 + +/* + * The range -4601 to -4700 is reserved for use by the + * Data Distribution Service (DDS) Server + */ +#define ANI_E_RANGE_START_DDS -4601 + +// See file aniDdsSvcMsgs.h for DDS specific error codes and messages +#define ANI_E_RANGE_END_DDS -4700 + +/* + * The range -4701 to -4800 is reserved for use by + * HTTPS components. + */ +#define ANI_E_RANGE_START_HTTPS -4701 +#define ANI_E_HTTPS_UNREACHABLE (ANI_E_RANGE_START_HTTPS - 0) +#define ANI_E_HTTPS_UNTRUSTED_CERT (ANI_E_RANGE_START_HTTPS - 1) +#define ANI_E_HTTPS_RECVD_ALERT (ANI_E_RANGE_START_HTTPS - 2) +#define ANI_E_HTTPS_FAILED (ANI_E_RANGE_START_HTTPS - 3) +#define ANI_E_RANGE_END_HTTPS -4800 + +/* + * The range -4801 to -4900 is reserved for use by + * enrollment components. + */ +#define ANI_E_RANGE_START_ENROLLMENT -4801 +#define ANI_E_ENROLL_TP_AVAILABLE (ANI_E_RANGE_START_ENROLLMENT - 0) +#define ANI_E_ENROLL_ALREADY_TRUSTED (ANI_E_RANGE_START_ENROLLMENT - 1) +#define ANI_E_ENROLL_NOT_FOUND (ANI_E_RANGE_START_ENROLLMENT - 2) +#define ANI_E_ENROLL_PWD_FAILED (ANI_E_RANGE_START_ENROLLMENT - 3) +#define ANI_E_ENROLL_FAILED (ANI_E_RANGE_START_ENROLLMENT - 4) +#define ANI_E_ENROLL_NOT_PRISTINE (ANI_E_RANGE_START_ENROLLMENT - 5) +#define ANI_E_RANGE_END_ENROLLMENT -4900 + + +/* + * The range -4901 to -5000 is reserved for use by NSM. + */ +#define ANI_E_RANGE_START_NSM -4901 +#define ANI_E_NSM_IPADDR_ASSIGNED (ANI_E_RANGE_START_NSM - 0) +#define ANI_E_RANGE_END_NSM -5000 + +/* + * The range -5001 to -5100 is reserved for use by the image + * validation library. + */ +#define ANI_E_RANGE_START_IMAGE -5001 +#define ANI_E_IMAGE_INVALID (ANI_E_RANGE_START_IMAGE - 0) +#define ANI_E_IMAGE_UNSUPPORTED (ANI_E_RANGE_START_IMAGE - 1) +#define ANI_E_RANGE_END_IMAGE -5100 + +/* + * The range -5101 to -5200 is reserved for use by CM + */ +#define ANI_E_RANGE_START_CM -5101 +#define ANI_E_MESG_UNAVAILABLE (ANI_E_RANGE_START_IMAGE - 0) +#define ANI_E_RANGE_END_CM -5200 + + +#define ANI_IS_STATUS_SUCCESS( retVal ) ( ( retVal >= 0 ) ) + +#endif //_ANI_ERRORS_H_ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.c b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.c new file mode 100644 index 000000000000..407310bd99ad --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.c @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmAesKeyWrap.c $ + * + * Contains definitions for the AES Key Wrap algorithm from RFC 3394. + * + * Author: Mayank D. Upadhyay + * Date: 31-March-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#include "vos_types.h" +#include "bapRsnSsmServices.h" +#include "bapRsnSsmEapol.h" +#include "bapRsnErrors.h" +#include "bapInternal.h" +#include "bapRsn8021xFsm.h" +#include "bapRsn8021xAuthFsm.h" +#include "vos_utils.h" +#include "vos_memory.h" +#include "vos_timer.h" +#include "bapRsnTxRx.h" +#include "bapRsnSsmAesKeyWrap.h" + +#if 0 + +#include +#include +#include + +#include +#include +#include +#include + +#include "aniSsmAesKeyWrap.h" +#include "aniSsmUtils.h" +#endif + +#define ANI_SSM_AES_KEY_WRAP_IC_SIZE ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE + +typedef struct tag_aes_key { + tANI_U32 eK[64], dK[64]; + int Nr; +} AES_KEY; + +static tANI_U8 gAniSsmAesKeyWrapIv[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 +}; + +static int +aes(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]); + +static int +aes_1(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 at[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]); + +static int +xor(tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], tANI_U32 t); + +/** + * Implements the AES Key Wrap algorithm described in RFC 3394. + * If n is the number of blocks in plainText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The first block is the IV from section 2.2.3 o the + * RFC. Note: It is the caller's responsibility to free the returned + * value. + * + * @param plainText the plaintext data to wrap + * @param len the length of the plaintext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param cipherTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyWrap(v_U32_t cryptHandle, tANI_U8 *plainText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **cipherTextPtr) +{ + int i, j, n; + int retVal; + + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE]; + tANI_U8 *r = NULL; + tANI_U32 t; + + tANI_U8 b[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2]; + + n = len / ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE; + if ((len % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Illegal number of input bytes to AES Key Wrap!"); + return ANI_E_ILLEGAL_ARG; + } + + // Allocate enough storage for 'A' as well as 'R' + r = vos_mem_malloc((n + 1) * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + if (r == NULL) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Could not allocate space for R"); + return ANI_E_MALLOC_FAILED; + } + + vos_mem_copy(a, gAniSsmAesKeyWrapIv, sizeof(a)); + vos_mem_copy(r + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, plainText, len); + + for (j = 0; j <= 5; j++) { + for (i = 1; i <= n; i++) { + + retVal = aes(cryptHandle, keyEncKey, keyEncKeyLen, + a, + r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b); + + if( !ANI_IS_STATUS_SUCCESS( retVal) ) goto error; + + vos_mem_copy(a, b, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + t = n*j + i; + xor(a, t); + vos_mem_copy(r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b + sizeof(b) - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + } + } + + vos_mem_copy(r, a, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + *cipherTextPtr = r; + + return ANI_OK; + + error: + if (r != NULL) + vos_mem_free(r); + + return retVal; + +} + +/** + * Implements the AES Key Unwrap algorithm described in RFC 3394. + * If (n+1) is the number of blocks in cipherText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The actual plaintext consists of n blocks that start at the + * second block. Note: It is the caller's responsibility to free the + * returned value. + * + * @param cipherText the cipertext data to unwrap + * @param len the length of the ciphertext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param plainTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyUnwrap(v_U32_t cryptHandle, tANI_U8 *cipherText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **plainTextPtr) +{ + int i, j; + int retVal; + + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE]; + tANI_U8 *r = NULL; + tANI_U32 n; + tANI_U32 t; + + tANI_U8 b[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2]; + + n = len / ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE - 1; + if ((len % ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Illegal number of input bytes to AES Key Unwrap!"); + return ANI_E_ILLEGAL_ARG; + } + + // Allocate enough storage for 'A' as well as 'R' + r = vos_mem_malloc((n + 1) * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + if (r == NULL) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Could not allocate space for R"); + return ANI_E_MALLOC_FAILED; + } + + vos_mem_copy(a, cipherText, sizeof(a)); + vos_mem_copy(r + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + cipherText + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + len - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + + for (j = 5; j >= 0; j--) { + for (i = n; i >= 1; i--) { + + t = n*j + i; + xor(a, t); + retVal = aes_1(cryptHandle, keyEncKey, keyEncKeyLen, + a, + r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b); + if( !ANI_IS_STATUS_SUCCESS( retVal) ) goto error; + + vos_mem_copy(a, b, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + vos_mem_copy(r + i*ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + b + sizeof(b) - ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + } + } + + if (vos_mem_compare2(a, gAniSsmAesKeyWrapIv, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE) != 0) { + retVal = ANI_E_MIC_FAILED; + goto error; + } + + *plainTextPtr = r; + + return ANI_OK; + + error: + if (r != NULL) + vos_mem_free(r); + + return retVal; +} + +static int +aes(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]) { + + int retVal = 0; + +// AES_KEY aesKey; + + tANI_U8 in[AES_BLOCK_SIZE]; + tANI_U8 *out; + + VOS_ASSERT (AES_BLOCK_SIZE == ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2); + + // Concatenate A and R[i] + vos_mem_copy(in, a, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + vos_mem_copy(in + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ri, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + out = b; + +#if 0 + retVal = AES_set_encrypt_key(keyBytes, keyLen*8, &aesKey); + if (retVal != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "AES_set_encrypt_key returned %d", retVal); + return ANI_E_FAILED; + } + + AES_encrypt(in, out, &aesKey); +#else // Enable to use VOS function + retVal = vos_encrypt_AES(cryptHandle, /* Handle */ + in, /* input */ + out, /* output */ + keyBytes); /* key */ + if (retVal != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "vos_encrypt_AES returned %d", retVal); + return ANI_E_FAILED; + } +#endif + return ANI_OK; +} + +static int +aes_1(v_U32_t cryptHandle, tANI_U8 *keyBytes, tANI_U32 keyLen, + tANI_U8 at[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 ri[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], + tANI_U8 b[AES_BLOCK_SIZE]) { + + int retVal; + +// AES_KEY aesKey; + + tANI_U8 in[AES_BLOCK_SIZE]; + tANI_U8 *out; + + VOS_ASSERT (AES_BLOCK_SIZE == ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE*2); + + // Concatenate A and R[i] + vos_mem_copy(in, at, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + vos_mem_copy(in + ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, + ri, ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE); + out = b; + +#if 0 + retVal = AES_set_decrypt_key(keyBytes, keyLen*8, &aesKey); + if (retVal != 0) { + ANI_SSM_LOG_E("AES_set_encrypt_key returned %d", retVal); + assert(0 && "AES_set_encrypt_key failed!"); + return ANI_E_FAILED; + } + + AES_decrypt(in, out, &aesKey); +#else + retVal = vos_decrypt_AES(cryptHandle, /* Handle */ + in, /* input */ + out, /* output */ + keyBytes); /* key */ + if (retVal != 0) { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "vos_decrypt_AES returned %d", retVal); + } +#endif + return ANI_OK; +} + +// From File : aniAsfHdr.h + + + +/* + * Put a long in host order into a char array in network order. + * + */ +static inline char *aniAsfWr32(char *cp, tANI_U32 x) +{ + tAniU32ValAry r; + int i; + + r.val = vos_cpu_to_be32(x); + i = sizeof(tANI_U32) - 1; + cp[3] = r.ary[i--]; + cp[2] = r.ary[i--]; + cp[1] = r.ary[i--]; + cp[0] = r.ary[i]; + + return (cp + sizeof(tANI_U32)); +} + +// From file : aniAsfMisc.c + +/* + * Put a long in host order into a char array in network order. + * + */ +char *aniAsfPut32(char *cp, tANI_U32 x) +{ + return(aniAsfWr32(cp, x)); +} + + +static int +xor(tANI_U8 a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE], tANI_U32 t) +{ + tANI_U8 tmp[4]; + aniAsfPut32((char *)tmp, t); + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-1] ^= tmp[3]; + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-2] ^= tmp[2]; + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-3] ^= tmp[1]; + a[ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE-4] ^= tmp[0]; + return ANI_OK; +} + diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.h b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.h new file mode 100644 index 000000000000..d7ebbd4e118e --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmAesKeyWrap.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Qualcomm Inc, proprietary. All rights reserved. + * Ref File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/include/aniSsmAesKeyWrap.h $ + * + * Contains SSM-private declarations related to the AES key WRAP + * algorithm described in RFC 3394. + * + * Author: Arul V Raj + * Date: 27-February-2009 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#ifndef _ANI_SSM_AES_KEY_WRAP_H_ +#define _ANI_SSM_AES_KEY_WRAP_H_ + +#define ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE 8 // Bytes +#define AES_BLOCK_SIZE 16 // Bytes + +typedef union uAniU32ValAry{ + tANI_U32 val; + char ary[sizeof(tANI_U32)]; +} tAniU32ValAry; + +/** + * Implements the AES Key Wrap algorithm described in RFC 3394. + * If n is the number of blocks in plainText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The first block is the IV from section 2.2.3 o the + * RFC. Note: It is the caller's responsibility to free the returned + * value. + * + * @param plainText the plaintext data to wrap + * @param len the length of the plaintext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param cipherTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyWrap(v_U32_t cryptHandle, tANI_U8 *plainText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **cipherTextPtr); + +/** + * Implements the AES Key Unwrap algorithm described in RFC 3394. + * If (n+1) is the number of blocks in cipherText, of size + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE, then the output value is (n+1) + * blocks. The actual plaintext consists of n blocks that start at the + * second block. Note: It is the caller's responsibility to free the + * returned value. + * + * @param cipherText the cipertext data to unwrap + * @param len the length of the ciphertext, which must be a multiple of + * ANI_SSM_AES_KEY_WRAP_BLOCK_SIZE. + * @param keyEncKey the encryption key + * @param keyEncKeyLen the length of keyEncKey + * @param plainTextPtr is set to a newly allocated array containing + * the result if the operation succeeds. It is the caller's + * responsibility to free this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmAesKeyUnwrap(v_U32_t cryptHandle, tANI_U8 *cipherText, tANI_U32 len, + tANI_U8 *keyEncKey, tANI_U32 keyEncKeyLen, + tANI_U8 **plainTextPtr); + + +#endif //_ANI_SSM_AES_KEY_WRAP_H_ + diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.c b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.c new file mode 100644 index 000000000000..304ed6b557b4 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.c @@ -0,0 +1,1129 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmEapol.c#2 $ + * + * Contains definitions of various utilities for EAPoL frame + * parsing and creation. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_utils.h" +#include +#include +#include +#include "bapRsn8021xFsm.h" +#include "vos_memory.h" + +//#include "aniSsmUtils.h" + + +//TODO: Put these in an array after EAPOL_TYPE is made an enum +#define ANI_EAPOL_TYPE_PACKET_STR "EAP" +#define ANI_EAPOL_TYPE_START_STR "START" +#define ANI_EAPOL_TYPE_LOGOFF_STR "LOGOFF" +#define ANI_EAPOL_TYPE_KEY_STR "KEY" +#define ANI_EAPOL_TYPE_ASF_ALERT_STR "ALERT" +#define ANI_EAPOL_TYPE_UNKNOWN_STR "UNKNOWN" + +/** + * The EAPOL packet is structured as follows: + */ +#define DST_MAC_POS 0 +#define SRC_MAC_POS 6 +#define ETHER_PROTO_POS 12 +#define EAPOL_VERSION_POS 14 +#define ANI_EAPOL_TYPE_POS 15 +#define EAPOL_BODY_LEN_POS 16 +#define EAPOL_BODY_POS EAPOL_RX_HEADER_SIZE + +#define EAPOL_BODY_LEN_SIZE 2 + +#define ANI_SSM_LEGACY_RC4_KEY_SIGN_OFFSET (EAPOL_BODY_POS + 28) + +/** + * Bitmasks for the RSN Key Information field + */ +#define ANI_SSM_RSN_KEY_DESC_VERS_MASK 0x0007 +#define ANI_SSM_RSN_UNICAST_MASK 0x0008 +#define ANI_SSM_RSN_KEY_INDEX_MASK 0x0030 +#define ANI_SSM_RSN_INSTALL_MASK 0x0040 +#define ANI_SSM_RSN_ACK_MASK 0x0080 +#define ANI_SSM_RSN_MIC_MASK 0x0100 +#define ANI_SSM_RSN_SECURE_MASK 0x0200 +#define ANI_SSM_RSN_ERROR_MASK 0x0400 +#define ANI_SSM_RSN_REQUEST_MASK 0x0800 +#define ANI_SSM_RSN_ENC_KEY_DATA_MASK 0x1000 + +#define ANI_SSM_RSN_KEY_DESC_VERS_OFFSET 0 +#define ANI_SSM_RSN_KEY_INDEX_OFFSET 4 + +#define ANI_SSM_RSN_KEY_MIC_OFFSET (EAPOL_BODY_POS + 77) + +/** + * Other hard coded values for convenience: + */ +static const v_U8_t +ANI_ETH_P_EAPOL_BYTES[2] = {0x00, 0x03};//BT-AMP security type{0x88, 0x8e}; +static const v_U8_t +EAPOL_VERSION_BYTES[1] = {EAPOL_VERSION_1}; +static const v_U8_t +ANI_EAPOL_TYPE_PACKET_BYTES[1] = {ANI_EAPOL_TYPE_PACKET}; +static const v_U8_t +ANI_EAPOL_TYPE_START_BYTES[1] = {ANI_EAPOL_TYPE_START}; +static const v_U8_t +ANI_EAPOL_TYPE_LOGOFF_BYTES[1] = {ANI_EAPOL_TYPE_LOGOFF}; +static const v_U8_t +ANI_EAPOL_TYPE_KEY_BYTES[1] = {ANI_EAPOL_TYPE_KEY}; +static const v_U8_t +ANI_EAPOL_TYPE_ASF_ALERT_BYTES[1] = {ANI_EAPOL_TYPE_ASF_ALERT}; +static const v_U8_t +ZERO_BYTES[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static v_U8_t BAP_RSN_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x19, 0x58 }; + + + +static int +parseRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc **rsnDescPtr); + +static int +parseRsnKeyInfo(tAniPacket *packet, + tAniRsnKeyInfo *info); + +static int +writeRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t keyDescType); + +static int +writeRsnKeyInfo(tAniPacket *packet, tAniRsnKeyInfo *info); + +static int +writeRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen); + +static int +checkRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen); + +extern void authEapolHandler( tAuthRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type); +extern void suppEapolHandler( tSuppRsnFsm *fsm, tAniPacket *eapolFrame, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t *type); + +/** + * addEapolHeaders + * + * FUNCTION: + * Prepends the EAPOL header to a packet. + * + * ASSUMPTIONS: + * The packet has enough space available for prepending the EAPOL + * header. + * + * @param packet the packet to prepend to + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * @param eapolType the EAPOL-Type field + * + * @return ANI_OK if the operation succeeds + */ +static int +addEapolHeaders(tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + v_U8_t eapolType) +{ + int retVal; + v_U16_t len; + + do + { + retVal = aniAsfPacketGetLen(packet); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + len = retVal; + retVal = aniAsfPacketPrepend16(packet, len); + + retVal = aniAsfPacketPrepend8(packet, eapolType); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, EAPOL_VERSION_BYTES, 1); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, ANI_ETH_P_EAPOL_BYTES, 2); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + //Since TL expects SNAP header in all packets we send, put it in + retVal = aniAsfPacketPrependBuffer(packet, BAP_RSN_LLC_HEADER, sizeof(BAP_RSN_LLC_HEADER)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + //packet length + len += 6/*length + eapolType+version + eth_type*/ + sizeof(BAP_RSN_LLC_HEADER); + retVal = aniAsfPacketPrepend16(packet, len); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, srcMac, sizeof(tAniMacAddr)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketPrependBuffer(packet, dstMac, sizeof(tAniMacAddr)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + }while( 0 ); + + return retVal; +} + +/** + * aniEapolWriteStart + * + * FUNCTION: + * Writes an EAPOL-Start frame to the packet. It is only used by the + * supplicant. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. There is no + * EAPOL payload for this kind of frame. + * + * ASSUMPTIONS: + * The packet has enough space available for prepending the header. + * + * @param packet the packet to which the frame should be written + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteStart(tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac) +{ + return ( addEapolHeaders(packet, dstMac, srcMac, ANI_EAPOL_TYPE_START) ); +} + +/** + * aniEapolWriteEapPacket + * + * FUNCTION: + * Writes the EAPOL/EAP-Packet frame headers. It is used + * by both the authenticator and the supplicant. This creates an EAPOL + * frame that is carrying an EAP message as its payload. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. + * + * ASSUMPTIONS: + * The EAP message (ie., the payload) is already available in the + * packet and that the packet has enough space available for + * prepending the EAPOL header. + * + * @param packet the packet containing the EAP message + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteEapPacket(tAniPacket *eapPacket, + tAniMacAddr dstMac, + tAniMacAddr srcMac) +{ + return( addEapolHeaders(eapPacket, dstMac, srcMac, ANI_EAPOL_TYPE_PACKET) ); +} + +/** + * aniEapolParse + * + * FUNCTION: + * Parses an EAPoL frame to the first level of headers (no EAP + * headers are parsed). + * + * NOTE: This is a non-destructive read, that is the + * headers are not stripped off the packet. However, any additional + * data at the end of the packet, beyond what the EAPoL headers encode + * will be stripped off. + * + * @param packet the packet containing the EAPoL frame to parse + * @param dstMac a pointer to set to the location of the destination + * MAC address + * @param srcMac a pointer to set to the location of the source + * MAC address + * @param type a pointer to set to the location of the EAPOL type + * field. + * + * @return the non-negative length of the EAPOL payload if the operation + * succeeds + */ +int +aniEapolParse(tAniPacket *packet, + v_U8_t **dstMac, + v_U8_t **srcMac, + v_U8_t **type) +{ + v_U16_t frameType; + v_U8_t *ptr; + int retVal; + int tmp; + + if (aniAsfPacketGetLen(packet) < EAPOL_BODY_POS) + return ANI_E_ILLEGAL_ARG; + + retVal = aniAsfPacketGetBytes(packet, &ptr); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Supp parsing EAPOL packet of len %d: \n", + retVal); + + frameType = (ptr[ETHER_PROTO_POS] << 8) + ptr[ETHER_PROTO_POS+1]; + + /* + * Validate the EAPOL-FRAME + */ + + if (frameType != ANI_ETH_P_EAPOL) + return ANI_E_ILLEGAL_ARG; + + *dstMac = ptr + DST_MAC_POS; + *srcMac = ptr + SRC_MAC_POS; + + // if (ptr[EAPOL_VERSION_POS] != EAPOL_VERSION_1) + // return ANI_E_ILLEGAL_ARG; + + *type = ptr + ANI_EAPOL_TYPE_POS; + retVal = (ptr[EAPOL_BODY_LEN_POS] << 8) + ptr[EAPOL_BODY_LEN_POS + 1]; + + /* + * Validate the length of the body. Allow for longer + * packets than encoded, but encoding should not be larger than + * packet. + * Note: EAPOL body len does not include headers + */ + tmp = aniAsfPacketGetLen(packet) - EAPOL_RX_HEADER_SIZE; + if (retVal > tmp) + { + retVal = ANI_E_ILLEGAL_ARG; + } + else { + if (retVal < tmp) + { + retVal = aniAsfPacketTruncateFromRear(packet, tmp - retVal); + } + } + + return retVal; +} + +/** + * aniEapolWriteKey + * + * Writes out a complete EAPOL-Key frame. The key descriptor is + * appended to the packet and the EAPOL header is prepended to it. If + * a micKey is passed in, then a MIC is calculated and inserted into + * the frame. + * + * @param packet the packet to write to + * @param dstMac the destination MAC address + * @param srcMac the source MAC address + * @param descType the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData the key descriptor data corresponding to the + * above descType. The signature field is ignored and will be + * generated in the packet. The key bytes are expected to be encrypted + * if they need to be encrypted. + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds + * + */ +int +aniEapolWriteKey(v_U32_t cryptHandle, + tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + int retVal; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + do + { + if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) + { + + retVal = writeRsnKeyDesc(packet, + (tAniEapolRsnKeyDesc *) keyDescData, + // Indicate + // ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW + // or ANI_EAPOL_KEY_DESC_TYPE_RSN + descType); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + break; + } + + retVal = addEapolHeaders(packet, dstMac, srcMac, ANI_EAPOL_TYPE_KEY); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + retVal = writeRsnKeyMic(cryptHandle, + packet, + (tAniEapolRsnKeyDesc *) keyDescData, + micKey, micKeyLen); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + } + else { + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + }while( 0 ); + + return retVal; +} + + +/** + * aniEapolParseKey + * + * Parses and verifies a complete EAPOL-Key frame. The key descriptor + * type is returned and so is a newly allocated key descriptor structure + * that is appropriate for the type. + * + * NOTE: This is a non-destructive read. That is, the packet headers + * will be unchanged at the end of this read operation. This is so + * that a followup MIC check may be done on the complete packet. If + * the packet parsing fails, the packet headers are not guaranteed to + * be unchanged. + * + * @param packet the packet to read from. Note that the frame is not + * expected to contain any additional padding at the end other than + * the exact number of key bytes. (The aniEapolParse function will + * ensure this.) + * @param descType is set to the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData is set to a newly allocated key descriptor + * corresponding to the above descType. The signature field is + * verified. The key bytes will be returned encrypted. It is the + * responsibility of the caller to free this structure and the data + * contained therein. + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolParseKey(tAniPacket *packet, + int *descType, + void **keyDescData) +{ + int retVal; + v_U8_t *bytes; + v_U32_t eapolFrameLen; + + if (packet == NULL) + return ANI_E_NULL_VALUE; + + do + { + eapolFrameLen = aniAsfPacketGetLen(packet); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Supp parsing EAPOL-Key frame of len %d\n", + eapolFrameLen); + + retVal = aniAsfPacketTruncateFromFront(packet, EAPOL_RX_HEADER_SIZE); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + retVal = aniAsfPacketGetBytes(packet, &bytes); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + + if (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN || + *bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + { + tAniEapolRsnKeyDesc *rsnDesc = NULL; + + //*descType = ANI_EAPOL_KEY_DESC_TYPE_RSN; + *descType = (*bytes == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW ? + ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW : ANI_EAPOL_KEY_DESC_TYPE_RSN) ; + retVal = parseRsnKeyDesc(packet, &rsnDesc); + if( !ANI_IS_STATUS_SUCCESS(retVal) ) break; + *keyDescData = rsnDesc; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp received unknown EAPOL-Key descriptor: %d\n", + *bytes); + retVal = ANI_E_ILLEGAL_ARG; + break; + } + + aniAsfPacketMoveLeft(packet, eapolFrameLen); + }while( 0 ); + + return retVal; +} + + + +static int +parseRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc **rsnDescPtr) +{ + int retVal = ANI_OK; + int len; + v_U8_t *bytes; + tAniEapolRsnKeyDesc *rsnDesc = NULL; + + do + { + aniAsfPacketTruncateFromFront(packet, 1); // Desc-Type + + rsnDesc = (tAniEapolRsnKeyDesc *) + vos_mem_malloc( sizeof(tAniEapolRsnKeyDesc) ); + + if (rsnDesc == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp could not malloc EAPOL-Key Descriptor for RSN\n"); + retVal = ANI_E_MALLOC_FAILED; + break; + } + + retVal = parseRsnKeyInfo(packet, &rsnDesc->info); + if (retVal != ANI_OK) break; + + retVal = aniAsfPacketGet16(packet, &rsnDesc->keyLen); + if (retVal != ANI_OK) + { + break; + } + + len = sizeof(rsnDesc->replayCounter); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->replayCounter, bytes, len); + + len = sizeof(rsnDesc->keyNonce); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyNonce, bytes, len); + + len = sizeof(rsnDesc->keyIv); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyIv, bytes, len); + + len = sizeof(rsnDesc->keyRecvSeqCounter); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyRecvSeqCounter, bytes, len); + + len = sizeof(rsnDesc->keyId); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyId, bytes, len); + + len = sizeof(rsnDesc->keyMic); + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + vos_mem_copy(rsnDesc->keyMic, bytes, len); + + retVal = aniAsfPacketGet16(packet, &rsnDesc->keyDataLen); + if (retVal != ANI_OK) + { + break; + } + + len = rsnDesc->keyDataLen; + if (len > 0) { + // We have a key + retVal = aniAsfPacketGetN(packet, len, &bytes); + if (retVal != ANI_OK) + { + break; + } + rsnDesc->keyData = (v_U8_t*)vos_mem_malloc(len); + if (rsnDesc->keyData == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Could not allocate RSN key bytes!\n"); + VOS_ASSERT( 0 ); + retVal = ANI_E_MALLOC_FAILED; + break; + } + vos_mem_copy(rsnDesc->keyData, bytes, len); + } + else { + rsnDesc->keyData = NULL; + } + + *rsnDescPtr = rsnDesc; + + }while( 0 ); + + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + vos_mem_free(rsnDesc); + } + + return retVal; +} + +static int +parseRsnKeyInfo(tAniPacket *packet, + tAniRsnKeyInfo *info) +{ + v_U16_t tmp; + int retVal; + + retVal = aniAsfPacketGet16(packet, &tmp); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + return retVal; + } + + info->keyDescVers = (tmp & ANI_SSM_RSN_KEY_DESC_VERS_MASK) + >> ANI_SSM_RSN_KEY_DESC_VERS_OFFSET; + if (info->keyDescVers != ANI_EAPOL_KEY_DESC_VERS_RC4 && + info->keyDescVers != ANI_EAPOL_KEY_DESC_VERS_AES) + return ANI_E_ILLEGAL_ARG; + + info->unicastFlag = (tmp & ANI_SSM_RSN_UNICAST_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->keyId = (tmp & ANI_SSM_RSN_KEY_INDEX_MASK) + >> ANI_SSM_RSN_KEY_INDEX_OFFSET; + info->installFlag = (tmp & ANI_SSM_RSN_INSTALL_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->ackFlag = (tmp & ANI_SSM_RSN_ACK_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->micFlag = (tmp & ANI_SSM_RSN_MIC_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->secureFlag = (tmp & ANI_SSM_RSN_SECURE_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->errorFlag = (tmp & ANI_SSM_RSN_ERROR_MASK) ? + eANI_BOOLEAN_TRUE: eANI_BOOLEAN_FALSE; + info->requestFlag = (tmp & ANI_SSM_RSN_REQUEST_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + info->encKeyDataFlag = (tmp & ANI_SSM_RSN_ENC_KEY_DATA_MASK) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE; + + return ANI_OK; +} + + +static int +writeRsnKeyDesc(tAniPacket *packet, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t keyDescType) +{ + int retVal; + + do + { + // This can be either ANI_EAPOL_KEY_DESC_TYPE_RSN + // or ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW + retVal = aniAsfPacketAppend8(packet, keyDescType); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = writeRsnKeyInfo(packet, &rsnDesc->info); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppend16(packet, rsnDesc->keyLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->replayCounter, + sizeof(rsnDesc->replayCounter)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyNonce, + sizeof(rsnDesc->keyNonce)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyIv, + sizeof(rsnDesc->keyIv)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyRecvSeqCounter, + sizeof(rsnDesc->keyRecvSeqCounter)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyId, + sizeof(rsnDesc->keyId)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + // Zero out the key MIC + retVal = aniAsfPacketAppendBuffer(packet, + ZERO_BYTES, + sizeof(rsnDesc->keyMic)); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + retVal = aniAsfPacketAppend16(packet, rsnDesc->keyDataLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + + if (rsnDesc->keyDataLen != 0) + { + retVal = aniAsfPacketAppendBuffer(packet, + rsnDesc->keyData, + rsnDesc->keyDataLen); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + } + }while( 0 ); + + return retVal; +} + +static int +writeRsnKeyInfo(tAniPacket *packet, tAniRsnKeyInfo *info) +{ + int retVal; + v_U16_t tmp; + v_U16_t infoValue; + + infoValue = 0; + + tmp = (v_U16_t)info->keyDescVers; + tmp = tmp << ANI_SSM_RSN_KEY_DESC_VERS_OFFSET; + infoValue |= (tmp & ANI_SSM_RSN_KEY_DESC_VERS_MASK); + + if (info->unicastFlag) + infoValue |= ANI_SSM_RSN_UNICAST_MASK; + + tmp = info->keyId; + tmp = tmp << ANI_SSM_RSN_KEY_INDEX_OFFSET; + infoValue |= (tmp & ANI_SSM_RSN_KEY_INDEX_MASK); + + if (info->installFlag) + infoValue |= ANI_SSM_RSN_INSTALL_MASK; + + if (info->ackFlag) + infoValue |= ANI_SSM_RSN_ACK_MASK; + + if (info->micFlag) + infoValue |= ANI_SSM_RSN_MIC_MASK; + + if (info->secureFlag) + infoValue |= ANI_SSM_RSN_SECURE_MASK; + + if (info->errorFlag) + infoValue |= ANI_SSM_RSN_ERROR_MASK; + + if (info->requestFlag) + infoValue |= ANI_SSM_RSN_REQUEST_MASK; + + if (info->encKeyDataFlag) + infoValue |= ANI_SSM_RSN_ENC_KEY_DATA_MASK; + + retVal = aniAsfPacketAppend16(packet, infoValue); + + return retVal; +} + + +static int +writeRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + int retVal = ANI_OK; + int len; + + v_U8_t *ptr = NULL; + v_U8_t *micPos = NULL; + v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two + + // Sanity check the arguments and return if no MIC generation is + // needed + if (micKey != NULL) + { + if (micKeyLen == 0 || !rsnDesc->info.micFlag) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp MIC key provided but micKeyLen or micFlag is not set!\n"); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + } + else { + if (rsnDesc->info.micFlag) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp micFlag is set but MIC key not provided!\n"); + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + // Normal condition where MIC is not desired by the caller + return ANI_OK; + } + + len = aniAsfPacketGetBytes(eapolFrame, &ptr); + if( !ANI_IS_STATUS_SUCCESS( len ) ) + { + return len; + } + + micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET + SNAP_HEADER_SIZE; + + // Clear the MIC field in the packet before the MIC computation + vos_mem_zero( micPos, VOS_DIGEST_MD5_SIZE); + + // Skip to the EAPOL version field for MIC computation + ptr += EAPOL_VERSION_POS + SNAP_HEADER_SIZE; + len -= (EAPOL_VERSION_POS + SNAP_HEADER_SIZE); + + if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) + { + if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) + { + retVal = ANI_OK; + } + else + { + retVal = ANI_ERROR; + } + } + else { + VOS_ASSERT( 0 ); + retVal = ANI_E_ILLEGAL_ARG; + } + + if (retVal == ANI_OK) + { + // Copy only 16B which is the smaller of the two and the same as + // ANI_EAPOL_KEY_RSN_MIC_SIZE + vos_mem_copy(micPos, result, VOS_DIGEST_MD5_SIZE); + } + + return retVal; +} + +/** + * aniEapolKeyCheckMic + * + * @param eapolFrame the complete EAPOL-Key packet + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds; ANI_E_MIC_FAILED if the + * MIC check fails. + */ +int +aniEapolKeyCheckMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + if (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + { + return checkRsnKeyMic(cryptHandle, eapolFrame, keyDescData, micKey, micKeyLen); + } + else { + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } +} + + +static int +checkRsnKeyMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + tAniEapolRsnKeyDesc *rsnDesc, + v_U8_t *micKey, + v_U32_t micKeyLen) +{ + int retVal = ANI_ERROR; + int len; + + v_U8_t *ptr = NULL; + v_U8_t *micPos = NULL; + + v_U8_t result[VOS_DIGEST_SHA1_SIZE]; // Larger of the two + v_U8_t incomingMic[ANI_EAPOL_KEY_RSN_MIC_SIZE]; + + if (!rsnDesc->info.micFlag) + { + VOS_ASSERT( 0 ); + return ANI_E_ILLEGAL_ARG; + } + + len = aniAsfPacketGetBytes(eapolFrame, &ptr); + if( ANI_IS_STATUS_SUCCESS( len ) ) + { + micPos = ptr + ANI_SSM_RSN_KEY_MIC_OFFSET; + + // Skip to the EAPOL version field for MIC computation + ptr += EAPOL_VERSION_POS; + len -= EAPOL_VERSION_POS; + + // Copy existing MIC to temporary location and zero it out + vos_mem_copy( incomingMic, micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE ); + vos_mem_zero( micPos, ANI_EAPOL_KEY_RSN_MIC_SIZE ); + + if (rsnDesc->info.keyDescVers == ANI_EAPOL_KEY_DESC_VERS_AES) + { + if( VOS_IS_STATUS_SUCCESS( vos_sha1_hmac_str(cryptHandle, ptr, len, micKey, micKeyLen, result) ) ) + { + retVal = ANI_OK; + } + } + else { + VOS_ASSERT( 0 ); + retVal = ANI_E_ILLEGAL_ARG; + } + + if (retVal == ANI_OK) + { + if ( !vos_mem_compare(incomingMic, result, ANI_EAPOL_KEY_RSN_MIC_SIZE)) + { + retVal = ANI_E_MIC_FAILED; + } + } + } + + return retVal; +} + +/** + * aniEapolKeyFreeDesc + * + * Frees the EAPOL key descriptor and the key bytes contained within it. + * + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolKeyFreeDesc(int descType, void *keyDescData) +{ + tAniEapolRsnKeyDesc *rsnDesc; + + if( keyDescData ) + { + if ((descType == ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW) + || (descType == ANI_EAPOL_KEY_DESC_TYPE_RSN)) + { + + rsnDesc = (tAniEapolRsnKeyDesc *) keyDescData; + if (rsnDesc->keyData != NULL) + vos_mem_free(rsnDesc->keyData); + + } + else { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Supp asked to free illegal type: %d\n", descType); + + } + + vos_mem_free(keyDescData); + } + + return ANI_OK; +} + +v_U8_t * +aniEapolType2Str(v_U8_t type) +{ + switch (type) + { + case ANI_EAPOL_TYPE_PACKET: + return (v_U8_t *)ANI_EAPOL_TYPE_PACKET_STR; + break; + case ANI_EAPOL_TYPE_START: + return (v_U8_t *)ANI_EAPOL_TYPE_START_STR; + break; + case ANI_EAPOL_TYPE_LOGOFF: + return (v_U8_t *)ANI_EAPOL_TYPE_LOGOFF_STR; + break; + case ANI_EAPOL_TYPE_KEY: + return (v_U8_t *)ANI_EAPOL_TYPE_KEY_STR; + break; + case ANI_EAPOL_TYPE_ASF_ALERT: + return (v_U8_t *)ANI_EAPOL_TYPE_ASF_ALERT_STR; + break; + default: + return (v_U8_t *)ANI_EAPOL_TYPE_UNKNOWN_STR; + break; + } +} + + +void bapRsnEapolHandler( v_PVOID_t pvFsm, tAniPacket *packet, v_BOOL_t fIsAuth ) +{ + int retVal; + v_U8_t *dstMac = NULL; + v_U8_t *srcMac = NULL; + v_U8_t *type = NULL; + + retVal = aniEapolParse(packet, &dstMac, &srcMac, &type); + if ( retVal >= 0 ) + { + retVal = ANI_OK; + + // Sanity check that a PAE role has been assigned to it, + // and then dispatch to the appropriate handler + + if( fIsAuth ) + { + tAuthRsnFsm *fsm = (tAuthRsnFsm *)pvFsm; + authEapolHandler( fsm, packet, dstMac, srcMac, type ); + } + else + { + tSuppRsnFsm *fsm = (tSuppRsnFsm *)pvFsm; + suppEapolHandler(fsm, packet, dstMac, srcMac, type); + } // switch statement + } // Successfully parsed EAPOL + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "eapolHandler Received bad EAPOL message of len %d (status=%d)\n", + aniAsfPacketGetLen(packet), retVal ); + } + aniAsfPacketFree( packet ); +} + + +int bapRsnFormPktFromVosPkt( tAniPacket **ppPacket, vos_pkt_t *pVosPacket ) +{ + int retVal = ANI_ERROR; + VOS_STATUS status; + v_U16_t uPktLen; +#define BAP_RSN_SNAP_TYPE_OFFSET 20 +#define BAP_RSN_ETHERNET_3_HEADER_LEN 22 + v_U8_t *pFrame; + tAniPacket *pAniPacket = NULL; + + do + { + status = vos_pkt_get_packet_length( pVosPacket, &uPktLen ); + if( !VOS_IS_STATUS_SUCCESS(status) ) break; + if( (uPktLen < BAP_RSN_ETHERNET_3_HEADER_LEN) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " authRsnRxFrameHandler receive eapol packet size (%d) too small (%d)\n", + uPktLen, BAP_RSN_ETHERNET_3_HEADER_LEN ); + break; + } + status = vos_pkt_peek_data( pVosPacket, 0, (v_VOID_t *)&pFrame, uPktLen ); + if( !VOS_IS_STATUS_SUCCESS(status) ) break; + retVal = aniAsfPacketAllocateExplicit(&pAniPacket, uPktLen, 0 ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " authRsnRxFrameHandler failed to get buffer size (%d) \n", + uPktLen ); + break; + } + aniAsfPacketEmptyExplicit( pAniPacket, 0 ); + pFrame[ETHER_PROTO_POS] = pFrame[BAP_RSN_SNAP_TYPE_OFFSET]; + pFrame[ETHER_PROTO_POS + 1] = pFrame[BAP_RSN_SNAP_TYPE_OFFSET + 1]; + //push ethernet II header in + retVal = aniAsfPacketAppendBuffer( pAniPacket, pFrame, ETHER_PROTO_POS + 2 ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) break; + //Get the rest of the data in + uPktLen -= BAP_RSN_ETHERNET_3_HEADER_LEN; + VOS_ASSERT( uPktLen > 0 ); + retVal = aniAsfPacketAppendBuffer( pAniPacket, pFrame + BAP_RSN_ETHERNET_3_HEADER_LEN, + uPktLen ); + if( !ANI_IS_STATUS_SUCCESS( retVal ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + " authRsnRxFrameHandler cannot retrieve eapol payload size (%d)\n", + uPktLen ); + break; + } + }while( 0 ); + + if( ANI_IS_STATUS_SUCCESS( retVal ) ) + { + *ppPacket = pAniPacket; + } + else if( pAniPacket ) + { + aniAsfPacketFree( pAniPacket ); + } + + return retVal; +} + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.h b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.h new file mode 100644 index 000000000000..f90bab8c7247 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmEapol.h @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniSsmEapol.h#1 $ + * Contains declarations of various utilities for EAPoL frame + * parsing and creation. + * range. + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef _ANI_SSM_EAPOL_H_ +#define _ANI_SSM_EAPOL_H_ + +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_packet.h" +#include + +#define ANI_ETH_P_EAPOL 0x0003 +#define ANI_ETH_P_IP 0x0800 + +/** + * The EAPOL type field is one of the following: + */ +#define ANI_EAPOL_TYPE_PACKET 0 +#define ANI_EAPOL_TYPE_START 1 +#define ANI_EAPOL_TYPE_LOGOFF 2 +#define ANI_EAPOL_TYPE_KEY 3 +#define ANI_EAPOL_TYPE_ASF_ALERT 4 + +#define EAPOL_VERSION_1 0x01 + +#define EAPOL_RX_HEADER_SIZE 18 +#define EAPOL_TX_HEADER_SIZE 26 //include LLC_SNAP +#define SNAP_HEADER_SIZE 8 + +#define ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 1 +// JEZ20041012 This needs to be fixed. This needs to support BOTH +// the older WPA Key Descriptor type of 254 AS WELL AS the newer +// Key Descriptor type of 2 +#define ANI_EAPOL_KEY_DESC_TYPE_RSN 254 +//#define ANI_EAPOL_KEY_DESC_TYPE_RSN 2 +#define ANI_EAPOL_KEY_DESC_TYPE_RSN_NEW 2 + +#define ANI_EAPOL_KEY_RSN_REPLAY_CTR_SIZE 8 +#define ANI_EAPOL_KEY_RSN_NONCE_SIZE 32 +#define ANI_EAPOL_KEY_RSN_IV_SIZE 16 +#define ANI_EAPOL_KEY_RSN_RSC_SIZE 8 +#define ANI_EAPOL_KEY_RSN_ID_SIZE 8 +#define ANI_EAPOL_KEY_RSN_MIC_SIZE 16 +#define ANI_EAPOL_KEY_RSN_ENC_KEY_SIZE 16 + +#define ANI_EAPOL_KEY_DESC_VERS_RC4 1 +#define ANI_EAPOL_KEY_DESC_VERS_AES 2 + +#define ANI_EAPOL_KEY_RC4_REPLAY_CTR_SIZE 8 +#define ANI_EAPOL_KEY_RC4_IV_SIZE 16 +#define ANI_EAPOL_KET_RC4_SIGN_SIZE 16 + +#define ANI_SSM_IE_RSN_KEY_DATA_ENCAPS_ID 0xDD +#define ANI_SSM_IE_RSN_GROUP_KEY_DATA_ENCAPS_ID 1 +#define ANI_SSM_GROUP_KEY_KDE_TX_BIT 0x04 + +typedef struct sAniEapolLegacyRc4KeyDesc { + v_U16_t keyLen; + v_U8_t replayCounter[ANI_EAPOL_KEY_RC4_REPLAY_CTR_SIZE]; + v_U8_t keyIv[ANI_EAPOL_KEY_RC4_IV_SIZE]; + tANI_BOOLEAN unicastFlag; // The high order 1 bit of key-index + v_U8_t keyId; // The lower order 7 bits of key-index (but 0..3 based) + v_U8_t signature[ANI_EAPOL_KET_RC4_SIGN_SIZE]; + v_U8_t *key; +} tAniEapolLegacyRc4KeyDesc; + +typedef struct sAniRsnKeyInfo { + v_U32_t keyDescVers; + tANI_BOOLEAN unicastFlag; // Pair-wise key + v_U16_t keyId; + tANI_BOOLEAN installFlag; + tANI_BOOLEAN ackFlag; + tANI_BOOLEAN micFlag; + tANI_BOOLEAN secureFlag; + tANI_BOOLEAN errorFlag; + tANI_BOOLEAN requestFlag; + tANI_BOOLEAN encKeyDataFlag; // RSN only (Is 0 in WPA) +} tAniRsnKeyInfo; + +typedef struct sAniEapolRsnKeyDesc { + tAniRsnKeyInfo info; + v_U16_t keyLen; + v_U8_t replayCounter[ANI_EAPOL_KEY_RSN_REPLAY_CTR_SIZE]; + v_U8_t keyNonce[ANI_EAPOL_KEY_RSN_NONCE_SIZE]; + v_U8_t keyIv[ANI_EAPOL_KEY_RSN_IV_SIZE]; + v_U8_t keyRecvSeqCounter[ANI_EAPOL_KEY_RSN_RSC_SIZE]; + v_U8_t keyId[ANI_EAPOL_KEY_RSN_ID_SIZE]; + v_U8_t keyMic[ANI_EAPOL_KEY_RSN_MIC_SIZE]; + v_U16_t keyDataLen; + v_U8_t *keyData; +} tAniEapolRsnKeyDesc; + +/** + * aniEapolWriteStart + * + * FUNCTION: + * Writes an EAPOL-Start frame to the packet. It is only used by the + * supplicant. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. There is no + * EAPOL payload for this kind of frame. + * + * ASSUMPTIONS: + * The packet has enough space available for prepending the header. + * + * @param packet the packet to which the frame should be written + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteStart(tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac); + +/** + * aniEapolWriteEapPacket + * + * FUNCTION: + * Writes the EAPOL/EAP-Packet frame headers. It is used + * by both the authenticator and the supplicant. This creates an EAPOL + * frame that is carrying an EAP message as its payload. + * + * LOGIC: + * Prepend the appropriate EAPOL header to the packet. + * + * ASSUMPTIONS: + * The EAP message (ie., the payload) is already available in the + * packet and that the packet has enough space available for + * prepending the EAPOL header. + * + * @param packet the packet containing the EAP message + * @param dstMac the MAC address of the destination (authenticator) + * @param srcMac the MAC address of the source (supplicant) + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolWriteEapPacket(tAniPacket *eapPacket, + tAniMacAddr dstMac, + tAniMacAddr srcMac); + +/** + * aniEapolParse + * + * FUNCTION: + * Parses an EAPoL frame to the first level of headers (no EAP + * headers are parsed). + * + * NOTE: This is a non-destructive read, that is the + * headers are not stripped off the packet. However, any additional + * data at the end of the packet, beyond what the EAPoL headers encode + * will be stripped off. + * + * @param packet the packet containing the EAPoL frame to parse + * @param dstMac a pointer to set to the location of the destination + * MAC address + * @param srcMac a pointer to set to the location of the source + * MAC address + * @param type a pointer to set to the location of the EAPOL type + * field. + * + * @return the non-negative length of the EAPOL payload if the operation + * succeeds + */ +int +aniEapolParse(tAniPacket *packet, + v_U8_t **dstMac, + v_U8_t **srcMac, + v_U8_t **type); + +/** + * aniEapolWriteKey + * + * Writes out a complete EAPOL-Key frame. The key descriptor is + * appended to the packet and the EAPOL header is prepended to it. If + * a micKey is passed in, then a MIC is calculated and inserted into + * the frame. + * + * @param packet the packet to write to + * @param dstMac the destination MAC address + * @param srcMac the source MAC address + * @param descType the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData the key descriptor data corresponding to the + * above descType. The signature field is ignored and will be + * generated in the packet. The key bytes are expected to be enctypted + * is they need to be encrypted. + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds + * + */ +int +aniEapolWriteKey(v_U32_t cryptHandle, + tAniPacket *packet, + tAniMacAddr dstMac, + tAniMacAddr srcMac, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen); + +/** + * aniEapolParseKey + * + * Parses and verifies a complete EAPOL-Key frame. The key descriptor + * type is returned and so is a newly allocated key descriptor structure + * that is appropriate for the type. + * + * NOTE: This is a non-destructive read. That is, the packet headers + * will be unchanged at the end of this read operation. This is so + * that a followup MIC check may be done on the complete packet. If + * the packet parsing fails, the packet headers are not guaranteed to + * be unchanged. + * + * @param packet the packet to read from. Note that the frame is not + * expected to contain any additional padding at the end other than + * the exact number of key bytes. (The aniEapolParse function will + * ensure this.) + * @param descType is set to the key descriptor type + * (ANI_EAPOL_KEY_DESC_TYPE_LEGACY_RC4 or + * ANI_EAPOL_KEY_DESC_TYPE_RSN). + * @param keyDescData is set to a newly allocated key descriptor + * corresponding to the above descType. The signature field is + * verified. The key bytes will be returned encrypted. It is the + * responsibility of the caller to free this structure and the data + * contained therein. + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolParseKey(tAniPacket *packet, + int *descType, + void **keyDescData); + +/** + * aniEapolKeyCheckMic + * + * @param eapolFrame the complete EAPOL-Key packet + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * @param micKey the MIC key + * @param micKeyLen the number of bytes in the MIC key + * + * @return ANI_OK if the operation succeeds; ANI_E_MIC_FAILED if the + * MIC check fails. + */ +int +aniEapolKeyCheckMic(v_U32_t cryptHandle, + tAniPacket *eapolFrame, + int descType, + void *keyDescData, + v_U8_t *micKey, + v_U32_t micKeyLen); + +/** + * aniEapolKeyFreeDesc + * + * Frees the EAPOL key descriptor and the key bytes contained within it. + * + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolKeyFreeDesc(int descType, void *keyDescData); + +v_U8_t * +aniEapolType2Str(v_U8_t type); + +v_U8_t * +aniEapolHdr2Str(v_U8_t *hdr); + +/** + * aniEapolKeyLogDesc + * + * Logs information about the given EAPOL key desctiptor. + * + * @param descType the key descriptor type + * @param keyDescData the key descriptor + * + * @return ANI_OK if the operation succeeds + */ +int +aniEapolKeyLogDesc(int descType, void *keyDescData); + +void bapRsnEapolHandler( v_PVOID_t pvFsm, tAniPacket *packet, v_BOOL_t fIsAuth ); +//Transfer from pVosPacket to tAniPacket. +int bapRsnFormPktFromVosPkt( tAniPacket **ppPacket, vos_pkt_t *pVosPacket ); + +#endif //_ANI_SSM_EAPOL_H_ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.c b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.c new file mode 100644 index 000000000000..f3be4866b030 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * File: $Header: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/ssm/lib/aniSsmReplayCtr.c#2 $ + * + * Contains definitions of various utilities for EAPoL frame + * parsing and creation. + * + * Author: Mayank D. Upadhyay + * Date: 19-June-2002 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#include "vos_types.h" +#include "vos_trace.h" +#include + +#include +#include "vos_status.h" +#include "vos_memory.h" +#include "vos_utils.h" +#include "vos_packet.h" + +//#include "aniSsmUtils.h" + +/* + * Opaque replay counter type. Does TX and RX side replay counter + * tracking. On the TX side, it returns monotonically increasing values + * of the counter and checks that the peer returned a value matching + * the one we sent. On the RX side, it makes sure that the peer sent a + * replay counter greater than the last one seen (excepting for the + * first time a check is made which the application has to special case.) + */ +struct sAniSsmReplayCtr { + v_U8_t size; + v_U8_t *buf; + v_U32_t currentValue; + v_U8_t init; +}; + +static int +updateCtrBuf(tAniSsmReplayCtr *ctr); + +/** + * aniSsmReplayCtrCreate + * + * Creates a replay counter and initializes it for first time + * use. The initialization can be done randomly or with a passed in + * value like 0. In case this is going to be used on the RX side, it + * doesn't matter what the initialization is and can be optimized to + * a fixed value so as to avoid the overhead of obtaining a random + * value. + * + * @param ctrPtr a pointer that will be set to the newly allocated + * counter if the operation succeeds + * @param size the number of bytes that are desired in the counter + * @param initValue if this is negative and size is greater than 4, + * the initialization is done randomly. Otherwise, these bytes are + * copied into the least significant four or less octets of the + * counter, depending on the size of the counter. i.e., if the counter + * is only 2B, then the least significant 2B of initValue will be + * copied over. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrCreate(v_U32_t cryptHandle, tAniSsmReplayCtr **ctrPtr, + v_U8_t size, + int initValue) +{ + tAniSsmReplayCtr *ctr; + + ctr = vos_mem_malloc( sizeof(tAniSsmReplayCtr) ); + if( NULL == ctr ) + { + return ANI_E_MALLOC_FAILED; + } + + ctr->buf = vos_mem_malloc( size ); + if (ctr->buf == NULL) + { + VOS_ASSERT( 0 ); + vos_mem_free(ctr); + return ANI_E_MALLOC_FAILED; + } + + ctr->size = size; + + // We cannot randomly generate the most significant bytes if the + // total number of bytes is not greater than 4 (sizeof ANI_U32). + if (initValue < 0 && ctr->size <= 4) + initValue = 0; + + // If initValue is negative, initialize the ctr randomly, else + // initialize it to what the user specified. + if (initValue < 0) + { + if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes(cryptHandle, ctr->buf, ctr->size) ) ) + { + return ANI_ERROR; + } + } + else { + ctr->currentValue = initValue - 1; + } + + *ctrPtr = ctr; + + return ANI_OK; +} + +static int +updateCtrBuf(tAniSsmReplayCtr *ctr) +{ + + v_U32_t numBytes; + v_U32_t offset; + v_U32_t tmp; + + tmp = vos_cpu_to_be32( ctr->currentValue ); + + numBytes = (4 <= ctr->size) ? 4 : ctr->size; + offset = 4 - numBytes; + vos_mem_copy(ctr->buf + ctr->size - numBytes, + ((v_U8_t *) &tmp) + offset, numBytes); + + return ANI_OK; +} + +/** + * aniSsmReplayCtrCmp + * + * Used to check if the passed in value is greater + * than, less than, or the same as the previous value. + * + * Can be used on the TX side to determine if the response to a + * request contains the same counter as the one in the request. + * + * Can be used on the RX side to determine if the request has a + * counter greater than the previous request, or if this is a + * retransmission of the previous request. The application should + * special-case the first time this is called on the RX side. + * + * @param ctr the current replay counter + * @param value the value to check against + * + * @return a negative value if current ctr is less than the + * given value, zero if they are the same, and a positive value if the + * current counter is greater than that of the given value. + */ +int +aniSsmReplayCtrCmp(tAniSsmReplayCtr *ctr, v_U8_t *value) +{ + return vos_mem_compare2(ctr->buf, value, ctr->size); +} + +/** + * aniSsmReplayCtrUpdate + * + * Used on the RX side to update the value of the current replay + * counter to that received in the next request. Typically this is + * called after it is determined that this is not a retransmission, + * and some sort of integrity checking is done on it. + * + * @param ctr the current replay counter + * @param value the value that it should be set to + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrUpdate(tAniSsmReplayCtr *ctr, + v_U8_t *value) +{ + vos_mem_copy(ctr->buf, value, ctr->size); + + return ANI_OK; +} + +/** + * aniSsmReplayCtrNext + * + * Used on the RX side to obtain the next value that should be sent + * with a request. After this call, the current value is incremented + * by one. + * + * @param ctr the current replay counter + * @param value where the next counter value should be copied + * into. The caller must allocated enough storage for this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrNext(tAniSsmReplayCtr *ctr, + v_U8_t *value) +{ + ctr->currentValue++; + updateCtrBuf(ctr); + vos_mem_copy(value, ctr->buf, ctr->size); + + return ANI_OK; +} + +/** + * aniSsmReplayCtrFree + * + * Frees the replay counter context. + * + * @param ctr the replay counter to free. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrFree(tAniSsmReplayCtr *ctr) +{ + + if (ctr->buf != NULL) + vos_mem_free(ctr->buf); + + vos_mem_free(ctr); + + return ANI_OK; +} diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.h b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.h new file mode 100644 index 000000000000..98bf31a0bc01 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmReplayCtr.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniSsmReplayCtr.h $ + * + * Contains declarations of various utilities for SSM replay counter + * module. + * + * Author: Mayank D. Upadhyay + * Date: 15-June-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ +#ifndef _ANI_SSM_REPLAY_CTR_H_ +#define _ANI_SSM_REPLAY_CTR_H_ + +#include "vos_types.h" +#include + +/* + * Opaque replay counter type. Does TX and RX side replay counter + * tracking. On the TX side, it returns monotonicall increasing values + * of the counter and checks that the peer returned a value matching + * the one we sent. On the RX side, it makes sure that the peer sent a + * replay counter greater than the last one seen (excepting for the + * first time a check is made which the application has to special case.) + */ +typedef struct sAniSsmReplayCtr tAniSsmReplayCtr; + +/** + * aniSsmReplayCtrCreate + * + * Creates a replay counter and initializes it for first time + * use. The initialization can be done randomly or with a passed in + * value like 0. In case this is going to be used on the RX side, it + * doesn't matter what the initiaalization is and can be optimized to + * a fixed value so as to avoid the overhead of obtaining a random + * value. + * + * @param ctrPtr a pointer that will be set to the newly allocated + * counter if the operation succeeds + * @param size the number of bytes that are desired in the counter + * @param initValue if this is negative and size is greater than 4, + * the initialization is done randomly. Otherwise, these bytes are + * copied into the least significant four or less octets of the + * counter, depending on the size of the counter. i.e., if the counter + * is only 2B, then the least significant 2B of initValue will be + * copied over. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrCreate(v_U32_t cryptHandle, tAniSsmReplayCtr **ctrPtr, + v_U8_t size, + int initValue); + +/** + * aniSsmReplayCtrCmp + * + * Used to check if the passed in value is greater + * than, less than, or the same as the previous value. + * + * Can be used on the TX side to determine if the response to a + * request contains the same counter as the one in the request. + * + * Can be used on the RX side to determine if the request has a + * counter greater than the previous request, or if this is a + * retransmission of the previous request. The application should + * special-case the first time this is called on the RX side. + * + * @param ctr the current replay counter + * @param value the value to check against + * + * @return A negative error code if value is less than the + * current value of the counter, zero if they are the same, and a + * positive value if the current value is greater than that of the + * counter. + */ +int +aniSsmReplayCtrCmp(tAniSsmReplayCtr *ctr, + v_U8_t *value); + +/** + * aniSsmReplayCtrUpdate + * + * Used on the RX side to update the value of the current replay + * counter to that received in the next request. Typically this is + * called after it is determined that this is not a retransmission, + * and some sort of integrity checking is done on it. + * + * @param ctr the current replay counter + * @param value the value that it should be set to + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrUpdate(tAniSsmReplayCtr *ctr, + v_U8_t *value); + +/** + * aniSsmReplayCtrNext + * + * Used on the RX side to obtain the next value that should be sent + * with a request. After this call, the current value is incremented + * by one. + * + * @param ctr the current replay counter + * @param value where the next counter value should be copied + * into. The caller must allocated enough storage for this. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrNext(tAniSsmReplayCtr *ctr, + v_U8_t *value); + +/** + * aniSsmReplayCtrFree + * + * Frees the replay counter context. + * + * @param ctr the replay counter to free. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmReplayCtrFree(tAniSsmReplayCtr *ctr); + +#endif //_ANI_SSM_REPLAY_CTR_H_ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnSsmServices.h b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmServices.h new file mode 100644 index 000000000000..5dcce1f9fff2 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnSsmServices.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * $File: //depot/software/projects/feature_branches/gen5_phase1/os/linux/classic/ap/apps/include/aniSsmServices.h $ + * + * Contains definitions of common types that the SSM exports to other + * modules. + * + * Author: Mayank D. Upadhyay + * Date: 23-January-2003 + * History:- + * Date Modified by Modification Information + * ------------------------------------------------------ + * + */ + +#ifndef _ANI_SSM_SERVICES_H_ +#define _ANI_SSM_SERVICES_H_ + +#include "vos_types.h" +#include "sirApi.h" + +#define ANI_SSM_MAX_KEYS_INFO_SIZE 512 +#define ANI_SSM_MAX_GROUP_SIZE 32 +#define ANI_SSM_MAX_USERID_SIZE 64 + +#define ANI_SSM_RSN_PMK_LEN 32 +#define ANI_SSM_RSN_PSK_LEN ANI_SSM_RSN_PMK_LEN +#define ANI_SSM_RSN_PSK_LEN_HEX (ANI_SSM_RSN_PSK_LEN + ANI_SSM_RSN_PSK_LEN) +#define ANI_SSM_MAX_PASSPHRASE_LEN 128 +#define ANI_SSM_MAX_AUTHZONE_LEN 32 +#define ANI_SSM_MAX_LANDPG_URL_LEN 128 +#define ANI_SSM_MAX_GUEST_PORTAL_PWD_LEN 32 + +#define ANI_SSM_IE_RSN_OUI {0x00, 0x0F, 0xAC} +#define ANI_SSM_IE_WPA_OUI {0x00, 0x50, 0xF2} + +#define ANI_SSM_IE_RSN_ELEM_ID 48 +#define ANI_SSM_IE_WPA_ELEM_ID 221 + +/* + * The total length of an RSN IE may be no longer than these many + * octets, including the two bytes for type and len. + */ +#define ANI_RSN_IE_MAX_LEN 257 + +/* + * PMKSA ID data type + * (PMKID is an HMAC-SHA1-128 value) + */ +#define ANI_AAG_PMKID_SIZE 16 + +#define ANI_SSM_AUTH_BITMASK 0x00010000 +#define ANI_SSM_IEMODE_BITMASK 0xC0000000 +#define ANI_SSM_ENCR_BITMASK 0x00000001 +#define ANI_SSM_IEMODE_SHIFT (30) + + +// Upper level authentication types used by AA +typedef enum eAniSsmAuthType { + eANI_SSM_AT_UNDERFLOW = -1, + + // The numbers are fixed so that they can be re-used in the XCLI + // config file and 1x.conf. + eANI_SSM_AT_NONE = 0, + eANI_SSM_AT_SHARED_KEY = 1, + eANI_SSM_AT_LEGACY_EAP = 2, + eANI_SSM_AT_RSN_PSK = 3, + eANI_SSM_AT_RSN_EAP = 4, + + eANI_SSM_AT_OVERFLOW +} tAniSsmAuthType; + +// Upper level encryption types used by AA +typedef enum eAniSsmCipherType { + eANI_SSM_CT_UNDERFLOW = -1, + + // The numbers are fixed so that they can be re-used in the XCLI + // config file and 1x.conf. + eANI_SSM_CT_NONE = 0, + eANI_SSM_CT_WEP40 = 1, + eANI_SSM_CT_WEP104 = 2, + eANI_SSM_CT_WPA_WEP40 = 3, + eANI_SSM_CT_WPA_WEP104 = 4, + eANI_SSM_CT_TKIP = 5, + eANI_SSM_CT_CCMP = 6, + + eANI_SSM_CT_OVERFLOW +} tAniSsmCipherType; + + +// WPA modes +typedef enum eAniSsmWpaModes { + eANI_SSM_WPA_UNDERFLOW = -1, + + eANI_SSM_WPA_DISABLE = 0, + eANI_SSM_WPA_1 = 1, + eANI_SSM_WPA_2 = 2, + + eANI_SSM_WPA_OVERFLOW = ((eANI_SSM_WPA_2 | eANI_SSM_WPA_1) + 1) +} tAniSsmWpaModes; + +typedef struct sAniSsmGroup { + v_U16_t len; // Valid range: 0..ANI_SSM_MAX_GROUP_SIZE + v_U8_t group[1]; +} tAniSsmGroup; + +typedef struct sAniSsmUserId { + v_U16_t len; // Valid range: 0..ANI_SSM_MAX_USERID_SIZE + v_U8_t userId[1]; +} tAniSsmUserId; + +/* + * PMKSA ID data type + * (PMKID is an HMAC-SHA1-128 value) + */ +typedef v_U8_t tAniSsmPmkId[ANI_AAG_PMKID_SIZE]; + +/** + * aniSsmInitStaticConf + * + * (Re-)Initializes the SSM internal static configuration. This may be + * from a static configuration file and will include items such as + * local MAC-ACL lists. + * + * @param configFileName - an optional filename to read from. If this is + * NULL, the default AAG static conf file is read. + * + * @return ANI_OK if the operation succeeds + */ +int +aniSsmInitStaticConf(char *configFileName); + +/** + * aniSsmIsStaMacAllowed + * + * Determines if a given STA passes the local MAC-ACL check. If + * MAC-ACL lookup is enabled, it may be either positive (whitelist) or + * negative (blacklist). If positive MAC-ACLs are on, then only those + * STAs that are in the whitelist are allowed in. If negative MAC-ACLs + * are on, then those STAs that are in the blacklist are not allowed in. + * + * Note that local MAC-ACLs may be maintained per SSID. + * + * @param staMac - the MAC address of the STA + * @param ssid - the SSID that the STA is associating on + * + * @return ANI_OK if the operation succeeds + */ +v_BOOL_t +aniSsmIsStaMacAllowed(const tAniMacAddr staMac, const tAniSSID *ssid); + +/** + * aniSsmIsSecModeAllowed + * + * Determines if the security suites requested by an RSN station or + * non-RSN station are allowed under the security mode in force at the + * moment. + * + * An RSN IE needs to be passed in if RSN is being used. Otherwise the + * ieLen field should be set to 0 or ieData set to NULL to indicate + * that no IE is present. If the RSN IE is present it is used to check + * both the authentication type and the cipher type for the group and + * pairwise keys. Special rules might apply in the case of a + * BP. Therefore, a separate flag indicates if the STA is a BP. + * + * If the station is not using RSN, the authentication type is + * tightly bound to the cipher type. For instance, when using + * shared-key MAC authentication, the cipher type will be assumed to + * be WEP. (Both WEP-40 and WEP-104 fall under the same security + * level.) When using open-system MAC authentication, the cipher type + * will be assumed to be WEP if the security level requires WEP, + * otherwise the cipher will be determined later. (When performing + * open-auth in the lowest security level, the STA is required to + * initiate EAPOL in order to establish WEP keys, or WEP cannot be not + * used.) + * + * @param secMode the security mode that is in force + * @param macAuthType the MAC-level authentication type to check + * @param ieLen is set 0 if no RSN IE is present, or to the number of + * octets in the RSN IE. + * @param ieData the optional IE data bytes, or NULL if no IE is + * present. + * @param bpIndicator eANI_BOOLEAN_TRUE if the STA is a BP, + * eANI_BOOLEAN_FALSE otherwise. + * + * @return eANI_BOOLEAN_TRUE if the authentication type is allowed, + * eANI_BOOLEAN_FALSE if not. + * + * @see aniSsmIsRsnSuiteAllowed + */ +v_BOOL_t +aniSsmIsSecModeAllowed(v_U32_t secMode, + tAniAuthType macAuthType, + v_U8_t ieLen, + v_U8_t *ieData, + v_BOOL_t bpIndicator, + v_BOOL_t wpsEnabled); + +/** + * aniSsmGenRsnSuiteList + * + * Generates a RSN information element containing a list of RSN suites + * that conform to the specified security level. This is generally + * used on the AP to generate the RSN information element it + * advertizes. + * + * @param secMode the security mode in force + * @param ieData the buffer in which to store the generated IE + * + * @return the non-negative number of bytes written into the buffer if + * the operation succeeds, or a negative error code. + */ +int +aniSsmGenRsnSuiteList(v_U32_t secMode, + v_U8_t ieData[ANI_RSN_IE_MAX_LEN]); + +/** + * aniSsmGenRsnSuiteForBp + * + * Generates a RSN information element containing exactly one RSN + * suite selector for authentication and exactly one for the + * cipher. This is generally used on the BP side while associating + * with an upstream AP. + * + * If RSN is turned off on the BP, then the IE is of length 0. + * + * NOTE: As per 802.11/D3.0, the BP has to send back the exact group + * key cipher that the AP indicated in its IE. + * + * @param apIeData contains the IE sent by the AP and is used to read + * the group key cipher that the AP wants us to use. + * @param apIeLen the length of the AP's IE + * @param bpRsnFlag should be 0 for no RSN, 1 for AES, 2 for TKIP + * @param bpPskFlag should be eANI_BOOLEAN_TRUE if RSN with PSK is + * desired. This is only relevant if bpRsnFlag is not zero. + * @param ieData the buffer in which to store the generated IE + * + * @return the non-negative number of bytes written into the buffer if + * the operation succeeds, or a negative error code. + */ +int +aniSsmGenRsnSuiteForBp(const v_U8_t *apIeData, + v_U8_t apIeLen, + v_U32_t bpRsnFlag, + v_BOOL_t bpPskFlag, + v_U8_t ieData[ANI_RSN_IE_MAX_LEN]); + +/** + * aniSsmSecMode2Str + * + * Returns a descriptive string that can be used for logging the + * security mode. + * + * @param secMode the secMode to be printed + * + * @return a printable ASCII string representing the secMode + */ +v_U8_t * +aniSsmSecMode2Str(v_U32_t secMode); + +/** + * aniSsmIe2Str + * + * Parses and returns a printable form of the IE (WPA/RSN). + * + * @param ieData the IE bytes + * @param ieLen the length of the IE + * + * @return ANI_OK if the operation succeeds + */ +v_U8_t * +aniSsmIe2Str(const v_U8_t *ieData, v_U8_t ieLen); + +#endif /* _ANI_SSM_SERVICES_H_ */ diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.c b/drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.c new file mode 100644 index 000000000000..0aa72d7a95c7 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + + vos_list.c + + \brief + + Description... + + + + ============================================================================== */ +/* $HEADER$ */ +#include "bapRsnTxRx.h" +#include "bapRsn8021xFsm.h" +#include "bapInternal.h" +#include "vos_trace.h" +#include "wlan_qct_tl.h" +#include "vos_memory.h" + + +static pnfTxCompleteHandler bapRsnFsmTxCmpHandler; +static pnfRxFrameHandler bapRsnFsmRxFrameHandler; + +extern int gReadToSetKey; + + +VOS_STATUS bapRsnRegisterTxRxCallbacks( pnfTxCompleteHandler pfnTxCom, pnfRxFrameHandler pnfRxFrame ) +{ + if( bapRsnFsmTxCmpHandler || bapRsnFsmRxFrameHandler ) + { + return VOS_STATUS_E_ALREADY; + } + + bapRsnFsmTxCmpHandler = pfnTxCom; + bapRsnFsmRxFrameHandler = pnfRxFrame; + + return ( VOS_STATUS_SUCCESS ); +} + +void bapRsnClearTxRxCallbacks(void) +{ + bapRsnFsmTxCmpHandler = NULL; + bapRsnFsmRxFrameHandler = NULL; +} + + +//To reserve a vos_packet for Tx eapol frame +//If success, pPacket is the packet and pData points to the head. +static VOS_STATUS bapRsnAcquirePacket( vos_pkt_t **ppPacket, v_U8_t **ppData, v_U16_t size ) +{ + VOS_STATUS status; + vos_pkt_t *pPacket; + + status = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT, size, 1, + VOS_TRUE, NULL, NULL ); + if( VOS_IS_STATUS_SUCCESS( status ) ) + { + status = vos_pkt_reserve_head( pPacket, (v_VOID_t **)ppData, size ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnAcquirePacket failed to reserve size = %d\n", size ); + vos_pkt_return_packet( pPacket ); + } + else + { + *ppPacket = pPacket; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnAcquirePacket failed to get vos_pkt\n" ); + } + + return ( status ); +} + + +static VOS_STATUS bapRsnTxCompleteCallback( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ) +{ + int retVal; + ptBtampContext btampContext; // use btampContext value + tCsrRoamSetKey setKeyInfo; + tSuppRsnFsm *fsm; + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pvosGCtx is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + btampContext = VOS_GET_BAP_CB(pvosGCtx); + if (NULL == btampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampContext is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + fsm = &btampContext->uFsm.suppFsm; + if (NULL == fsm) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "fsm is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //If we get a disconect from upper layer before getting the pkt from TL the + //bapRsnFsmTxCmpHandler could be NULL + //VOS_ASSERT( bapRsnFsmTxCmpHandler ); + + if( bapRsnFsmTxCmpHandler ) + { + //Change the state + //Call auth or supp FSM's handler + bapRsnFsmTxCmpHandler( pvosGCtx, pPacket, retStatus ); + } + else + { + vos_pkt_return_packet( pPacket ); + return (VOS_STATUS_SUCCESS ); + } + + //fsm->suppCtx->ptk contains the 3 16-bytes keys. We need the last one. + /* + We will move the Set key to EAPOL Completion handler. We found a race condition betweem + sending EAPOL frame and setting Key */ + if (BAP_SET_RSN_KEY == gReadToSetKey) { + vos_mem_zero( &setKeyInfo, sizeof( tCsrRoamSetKey ) ); + setKeyInfo.encType = eCSR_ENCRYPT_TYPE_AES; + setKeyInfo.keyDirection = eSIR_TX_RX; + vos_mem_copy( setKeyInfo.peerMac, fsm->suppCtx->authMac, sizeof( tAniMacAddr ) ); + setKeyInfo.paeRole = 0; //this is a supplicant + setKeyInfo.keyId = 0; //always + setKeyInfo.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy( setKeyInfo.Key, (v_U8_t *)fsm->suppCtx->ptk + (2 * CSR_AES_KEY_LEN ), CSR_AES_KEY_LEN ); + + if( !VOS_IS_STATUS_SUCCESS( bapSetKey( fsm->ctx->pvosGCtx, &setKeyInfo ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, " Supp: gotoStateStaKeySet fail to set key\n" ); + retVal = ANI_ERROR; + } + gReadToSetKey = BAP_RESET_RSN_KEY; + } + + return (VOS_STATUS_SUCCESS ); +} + + +static VOS_STATUS bapRsnTxFrame( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ) +{ + VOS_STATUS status; + WLANTL_MetaInfoType metaInfo; + + vos_mem_zero( &metaInfo, sizeof( WLANTL_MetaInfoType ) ); + metaInfo.ucIsEapol = 1; //only send eapol frame + status = WLANTL_TxBAPFrm( pvosGCtx, pPacket, &metaInfo, bapRsnTxCompleteCallback ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnTxFrame failed to send vos_pkt status = %d\n", status ); + } + + return ( status ); +} + + +/* + \brief bapRsnSendEapolFrame + To push an eapol frame to TL. + + \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format +*/ +VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt ) +{ + VOS_STATUS status; + vos_pkt_t *pPacket = NULL; + v_U8_t *pData, *pSrc; + int pktLen = aniAsfPacketGetBytes( pAniPkt, &pSrc ); + + if( pktLen <= 0 ) + { + return VOS_STATUS_E_EMPTY; + } + status = bapRsnAcquirePacket( &pPacket, &pData, pktLen ); + if( VOS_IS_STATUS_SUCCESS( status ) && ( NULL != pPacket )) + { + vos_mem_copy( pData, pSrc, pktLen ); + //Send the packet, need to check whether we have an outstanding packet first. + status = bapRsnTxFrame( pvosGCtx, pPacket ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + vos_pkt_return_packet( pPacket ); + } + } + + return ( status ); +} + + +//TL call this function on Rx frames, should only be EAPOL frames +VOS_STATUS bapRsnRxCallback( v_PVOID_t pv, vos_pkt_t *pPacket ) +{ + //Callback to auth or supp FSM's handler + VOS_ASSERT( bapRsnFsmRxFrameHandler ); + if( bapRsnFsmRxFrameHandler ) + { + bapRsnFsmRxFrameHandler( pv, pPacket ); + } + else + { + //done + vos_pkt_return_packet( pPacket ); + } + + return ( VOS_STATUS_SUCCESS ); +} + + + +VOS_STATUS bapRsnRegisterRxCallback( v_PVOID_t pvosGCtx ) +{ + VOS_STATUS status; + + status = WLANTL_RegisterBAPClient( pvosGCtx, WLANBAP_RxCallback, WLANBAP_TLFlushCompCallback ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + if( VOS_STATUS_E_EXISTS != status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "bapRsnRegisterRxCallback failed with status = %d\n", status ); + } + else + { + //We consider it ok to register it multiple times because only BAP's RSN should call this + status = VOS_STATUS_SUCCESS; + } + } + + return ( status ); +} + + diff --git a/drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.h b/drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.h new file mode 100644 index 000000000000..650dbcebde5f --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/bapRsnTxRx.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __BAPRSN_TXRX_H ) +#define __BAPRSN_TXRX_H + +/**============================================================================= + + bapRsnTxRx.h + + \brief + + Description... + + + + ==============================================================================*/ + +#include "vos_types.h" +#include "vos_status.h" +#include "vos_packet.h" +#include "bapRsnAsfPacket.h" + + +typedef int (*pnfTxCompleteHandler)( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket, VOS_STATUS retStatus ); +typedef int (*pnfRxFrameHandler)( v_PVOID_t pvosGCtx, vos_pkt_t *pPacket ); + +/* + \brief bapRsnSendEapolFrame + To push an eapol frame to TL. + + \param pAniPkt - a ready eapol frame that is prepared in tAniPacket format +*/ +VOS_STATUS bapRsnSendEapolFrame( v_PVOID_t pvosGCtx, tAniPacket *pAniPkt ); + + +/* + \brief bapRsnRegisterTxRxCallbacks + To register two callbacks for txcomplete and rxFrames . + + \param pfnTxCom - pointer to a function to handle the tx completion. + \param pnfRxFrame - point to a function to handle rx frames +*/ +VOS_STATUS bapRsnRegisterTxRxCallbacks( pnfTxCompleteHandler pfnTxCom, pnfRxFrameHandler pnfRxFrame ); + +//To set the callbaks to NULL so it can be change later +void bapRsnClearTxRxCallbacks(void); + +/* + \brief bapRsnRegisterRxCallback + To register the RX frame callbacks to TL to receive EAPOL frames . + + \param pvosGCtx - pointer to global VOSS context. +*/ +VOS_STATUS bapRsnRegisterRxCallback( v_PVOID_t pvosGCtx ); + +VOS_STATUS bapRsnRxCallback(v_PVOID_t pv, vos_pkt_t *pPacket); + +#endif //__BAPRSN_TXRX_H + + + + diff --git a/drivers/staging/prima/CORE/BAP/src/btampFsm.c b/drivers/staging/prima/CORE/BAP/src/btampFsm.c new file mode 100644 index 000000000000..183a7a255200 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/btampFsm.c @@ -0,0 +1,2697 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + b t a m p F s m . C + + OVERVIEW: + + This software unit holds the implementation of the Finite State Machine that + controls the operation of each individual AMP Physical link. + (Currently, this is limited to ONE link.) + + The btampFsm() routine provided by this module is called by the rest of + the BT-AMP PAL module whenever a control plane operation occurs that requires a + major state transition. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /prj/qct/asw/engbuilds/scl/users02/jzmuda/gb-bluez/vendor/qcom/proprietary/wlan/libra/CORE/BAP/src/btampFsm.c,v 1.11 2011/03/30 21:52:10 jzmuda Exp jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2008-10-16 jez Created module + +===========================================================================*/ + +/* This file is generated from btampFsm.cdd - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 / version 1.2 Beta 1 */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + + +#include "fsmDefs.h" +//#include "btampFsm.h" +#include "bapInternal.h" +#include "btampFsm_ext.h" + +// Pick up the BTAMP Timer API definitions +#include "bapApiTimer.h" + +// Pick up the BTAMP RSN definitions +#include "bapRsn8021xFsm.h" + +#include "bapRsn8021xAuthFsm.h" +// Pick up the SME API definitions +#include "sme_Api.h" + +// Pick up the PMC API definitions +#include "pmcApi.h" + +// Pick up the BTAMP API defintions for interfacing to External subsystems +#include "bapApiExt.h" + +#include "wlan_nlink_common.h" +#include "wlan_btc_svc.h" + +// Pick up the DOT11 Frames compiler +// I just need these one "opaque" type definition in order to use the "frames" code +typedef struct sAniSirGlobal *tpAniSirGlobal; +#include "dot11f.h" + +#if 0 +/* + * Event-related Defines. + * - Ultimately, these events will be values + * - from an enumeration. That are set by some + * - of the following events. + */ +#define eWLAN_BAP_MAC_START_BSS_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STARTED */ +#define eWLAN_BAP_MAC_START_FAILS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ +#define eWLAN_BAP_MAC_SCAN_COMPLETE /* bapScanCompleteCallback */ +#define eWLAN_BAP_CHANNEL_NOT_SELECTED /* No existing Infra assoc - e.g., use HAL to access the STA LIST and find nothing */ +#define eWLAN_BAP_MAC_CONNECT_COMPLETED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATED */ +#define eWLAN_BAP_MAC_CONNECT_FAILED /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_FAILURE or eCSR_ROAM_RESULT_NOT_ASSOCIATED */ +#define eWLAN_BAP_MAC_CONNECT_INDICATION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND */ +#define eWLAN_BAP_RSN_SUCCESS /* setKey IOCTL from the Auth/Supp App */ +#define eWLAN_BAP_RSN_FAILURE /* deAuth IOCTL from the Auth/Supp App */ +#define eWLAN_BAP_MAC_KEY_SET_SUCCESS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_KEY_SET */ +#define eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_DISASSOC_IND */ +#define eWLAN_BAP_MAC_READY_FOR_CONNECTIONS /* bapRoamCompleteCallback with eCSR_ROAM_RESULT_WDS_STOPPED */ +#define eWLAN_BAP_CHANNEL_SELECTION_FAILED /* ??? */ + +#endif /* 0 */ + +/*Min and max channel values in 2.4GHz band for operational channel validation + on connect*/ +#define WLAN_BAP_MIN_24G_CH 1 +#define WLAN_BAP_MAX_24G_CH 14 + + +/* The HCI Disconnect Logical Link Complete Event signalling routine*/ +VOS_STATUS +signalHCIDiscLogLinkCompEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status, /* the BT-AMP status */ + v_U16_t log_link_handle, /* The Logical Link that disconnected*/ + v_U8_t reason /* the BT-AMP reason code */ +); + + +/* Stubs - TODO : Remove once the functions are available */ +int +bapSuppDisconnect(tBtampContext *ctx) +{ + // Disconnect function is called internally + // TODO : Need to find, if it disconnect will be issued from bap for supplicant + return ANI_OK; +} + +int +bapAuthDisconnect(tBtampContext *ctx) +{ + // Disconnect function is called internally + // TODO : Need to find, if it disconnect will be issued from bap for supplicant + return ANI_OK; +} + +VOS_STATUS +bapSetKey( v_PVOID_t pvosGCtx, tCsrRoamSetKey *pSetKeyInfo ) +{ + tWLAN_BAPEvent bapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampContext btampContext; /* use btampContext value */ + v_U8_t status; /* return the BT-AMP status here */ + eHalStatus halStatus; + v_U32_t roamId = 0xFF; + tHalHandle hHal = NULL; + v_U8_t groupMac[ANI_MAC_ADDR_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + /* Validate params */ + if ((pvosGCtx == NULL) || (pSetKeyInfo == NULL)) + { + return VOS_STATUS_E_FAULT; + } + + btampContext = VOS_GET_BAP_CB(pvosGCtx); + /* Validate params */ + if ( btampContext == NULL) + { + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: btampContext value: %p", __func__, btampContext); + + /* Fill in the event structure */ + bapEvent.event = eWLAN_BAP_RSN_SUCCESS; + bapEvent.params = NULL; + + /* Signal the successful RSN auth and key exchange event */ + /* (You have to signal BEFORE calling sme_RoamSetKey) */ + vosStatus = btampFsm(btampContext, &bapEvent, &status); + + /* Set the Pairwise Key */ + halStatus = sme_RoamSetKey( + hHal, + btampContext->sessionId, + pSetKeyInfo, + &roamId ); + if ( halStatus != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", __LINE__, halStatus ); + return VOS_STATUS_E_FAULT; + } + + /* Set the Group Key */ + vos_mem_copy( pSetKeyInfo->peerMac, groupMac, sizeof( tAniMacAddr ) ); + halStatus = sme_RoamSetKey( + hHal, + btampContext->sessionId, + pSetKeyInfo, + &roamId ); + if ( halStatus != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", __LINE__, halStatus ); + return VOS_STATUS_E_FAULT; + } + + return vosStatus; +} + +/* + * Debug-related Defines. + * - Ultimately, these events will be values + * - from an enumeration. That are set by some + * - of the following events. + */ +#define DUMPLOG_ON +#if defined DUMPLOG_ON +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif + +/* + * State transition procedures + */ + +VOS_STATUS +gotoS1 +( + ptBtampContext btampContext, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + tWLAN_BAPRole BAPDeviceRole, + v_U8_t *status /* return the BT-AMP status here */ +) +{ + tBtampTLVHCI_Create_Physical_Link_Cmd *pBapHCIPhysLinkCreate + = (tBtampTLVHCI_Create_Physical_Link_Cmd *) bapEvent->params; + tBtampTLVHCI_Accept_Physical_Link_Cmd *pBapHCIPhysLinkAccept + = (tBtampTLVHCI_Accept_Physical_Link_Cmd *) bapEvent->params; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t conAcceptTOInterval; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Remember role */ + btampContext->BAPDeviceRole = BAPDeviceRole; + + switch(BAPDeviceRole) + { + case BT_INITIATOR: + /* Copy down the phy_link_handle value */ + btampContext->phy_link_handle = pBapHCIPhysLinkCreate->phy_link_handle; + /* Copy out the key material from the HCI command */ + btampContext->key_type = pBapHCIPhysLinkCreate->key_type; + btampContext->key_length = pBapHCIPhysLinkCreate->key_length; + vos_mem_copy( + btampContext->key_material, + pBapHCIPhysLinkCreate->key_material, + 32); /* Need a key size define */ + break; + case BT_RESPONDER: + /* Copy down the phy_link_handle value */ + btampContext->phy_link_handle = pBapHCIPhysLinkAccept->phy_link_handle; + /* Copy out the key material from the HCI command */ + btampContext->key_type = pBapHCIPhysLinkAccept->key_type; + btampContext->key_length = pBapHCIPhysLinkAccept->key_length; + vos_mem_copy( + btampContext->key_material, + pBapHCIPhysLinkAccept->key_material, + 32); /* Need a key size define */ + break; + default: + *status = WLANBAP_ERROR_HOST_REJ_RESOURCES; /* return the BT-AMP status here */ + return VOS_STATUS_E_RESOURCES; + } + + conAcceptTOInterval = (btampContext->bapConnectionAcceptTimerInterval * 5)/ 8; + /* Start the Connection Accept Timer */ + vosStatus = WLANBAP_StartConnectionAcceptTimer ( + btampContext, + conAcceptTOInterval); + + *status = WLANBAP_STATUS_SUCCESS; /* return the BT-AMP status here */ + + return VOS_STATUS_SUCCESS; +} //gotoS1 + +VOS_STATUS +gotoScanning +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole, + v_U8_t *status /* return the BT-AMP status here */ +) +{ + /* Initiate a SCAN request */ + //csrScanRequest(); + *status = WLANBAP_STATUS_SUCCESS; /* return the BT-AMP status here */ + + return VOS_STATUS_SUCCESS; +} + + +#if 0 +/*========================================================================== + + FUNCTION: convertRoleToBssType + + DESCRIPTION: Return one of the following values: + + eCSR_BSS_TYPE_INFRASTRUCTURE, + eCSR_BSS_TYPE_IBSS, // an IBSS network we will NOT start + eCSR_BSS_TYPE_START_IBSS, // an IBSS network we will start if no partners detected. + eCSR_BSS_TYPE_WDS_AP, // BT-AMP AP + eCSR_BSS_TYPE_WDS_STA, // BT-AMP station + eCSR_BSS_TYPE_ANY, +============================================================================*/ +#endif +eCsrRoamBssType +convertRoleToBssType +( + tWLAN_BAPRole bapRole /* BT-AMP role */ +) +{ + switch (bapRole) + { + case BT_RESPONDER: + // an WDS network we will join + return eCSR_BSS_TYPE_WDS_STA; + //return eCSR_BSS_TYPE_INFRASTRUCTURE; + //return eCSR_BSS_TYPE_IBSS; // Initial testing with IBSS on both ends makes more sense + case BT_INITIATOR: + // an WDS network we will start if no partners detected. + return eCSR_BSS_TYPE_WDS_AP; + //return eCSR_BSS_TYPE_START_IBSS; // I really should try IBSS on both ends + default: + return eCSR_BSS_TYPE_INFRASTRUCTURE; + } +} // convertRoleToBssType + + +char hexValue[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + +#define BAP_MIN(x, y) ((x) < (y) ? (x) : (y)) +#define MAX_BYTES 8 +// Each byte will be converted to hex digits followed by a +// punctuation (which is specified in the "delimiter" param.) Thus +// allocate three times the storage. +v_U8_t * +bapBin2Hex(const v_U8_t *bytes, v_U32_t len, char delimiter) +{ + static v_U8_t buf[MAX_BYTES*(2+1)]; + v_U32_t i; + v_U8_t *ptr; + + len = BAP_MIN(len, MAX_BYTES); + for (i = 0, ptr = buf; i < len; i++) + { + *ptr++ = hexValue[ (bytes[i] >> 4) & 0x0f]; + *ptr++ = hexValue[ bytes[i] & 0x0f]; + *ptr++ = delimiter; + //sprintf(ptr, "%.2x%c", bytes[i], delimiter); + //ptr += 3; + } + + // Delete the extra punctuation and null terminate the string + if (len > 0) + ptr--; + *ptr = '\0'; + + return buf; +}// bapBin2Hex + +char bapSsidPrefixValue[] = {'A', 'M', 'P', '-'}; + +v_U8_t * +convertBSSIDToSSID +( + v_U8_t *bssid /* BSSID value */ +) +{ + static v_U8_t ssId[32]; + + vos_mem_copy( + ssId, + bapSsidPrefixValue, + 4); + + vos_mem_copy( + &ssId[4], + bapBin2Hex(bssid, 6, '-'), + 17); + + return ssId; +} // convertBSSIDToSSID + +VOS_STATUS +convertToCsrProfile +( + ptBtampContext btampContext, /* btampContext value */ + eCsrRoamBssType bssType, + tCsrRoamProfile *pProfile /* return the profile info here */ +) +{ + static v_U8_t btampRSNIE[] = {0x30, 0x14, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, + 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x02, 0x00, 0x00 + }; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_S7_t sessionid = -1; + tHalHandle hHal = NULL; + v_U32_t triplet; + v_U8_t regulatoryClass; + v_U8_t firstChannel; + v_U8_t numChannels; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + if (NULL == btampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampContext is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //Zero out entire roamProfile structure to avoid problems in uninitialized pointers as the structure expands */ + //vos_mem_zero(pProfile,sizeof(tCsrRoamProfile)); + + //Set the BSS Type + //pProfile->BSSType = convertRoleToBssType(btampContext->BAPDeviceRole ); + pProfile->BSSType = bssType; + //pProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + + //Set the SSID + + if ( bssType == eCSR_BSS_TYPE_WDS_STA) + { + pProfile->SSIDs.numOfSSIDs = 2; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: bssType = %s, SSID specified = %s\n", __func__, "eCSR_BSS_TYPE_WDS_STA", convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr)); + + vos_mem_zero(pProfile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[0].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[0].SSID.ssId, + convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[0].SSID.length = 21; + + vos_mem_zero(pProfile->SSIDs.SSIDList[1].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[1].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[1].SSID.ssId, + convertBSSIDToSSID(btampContext->self_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[1].SSID.length = 21; + + //Set the BSSID to the Remote AP + pProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pProfile->BSSIDs.bssid, + btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr, + sizeof( tCsrBssid ) ); + + } + else if ( bssType == eCSR_BSS_TYPE_WDS_AP) + { + pProfile->SSIDs.numOfSSIDs = 1; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: bssType = %s, SSID specified = %s\n", __func__, "eCSR_BSS_TYPE_WDS_AP", convertBSSIDToSSID(btampContext->self_mac_addr)); + + vos_mem_zero(pProfile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[0].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[0].SSID.ssId, + convertBSSIDToSSID(btampContext->self_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[0].SSID.length = 21; + +#if 0 + //In case you are an AP, don't set the BSSID + pProfile->BSSIDs.numOfBSSIDs = 0; +#endif //0 + + //Set the BSSID to your "self MAC Addr" + pProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pProfile->BSSIDs.bssid, + btampContext->self_mac_addr, + sizeof( tCsrBssid ) ); + + } + else + // Handle everything else as bssType eCSR_BSS_TYPE_INFRASTRUCTURE + { + pProfile->SSIDs.numOfSSIDs = 1; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: bssType = %s, SSID specified = %s\n", __func__, "eCSR_BSS_TYPE_WDS_STA", convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr)); + + vos_mem_zero(pProfile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(pProfile->SSIDs.SSIDList[0].SSID.ssId)); + vos_mem_copy(pProfile->SSIDs.SSIDList[0].SSID.ssId, + convertBSSIDToSSID(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr), + 21); // Length of BTAMP SSID is 21 bytes + pProfile->SSIDs.SSIDList[0].SSID.length = 21; + + //Set the BSSID to the Remote AP + pProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pProfile->BSSIDs.bssid, + btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr, + sizeof( tCsrBssid ) ); + + } + + //Always set the Auth Type + //pProfile->negotiatedAuthType = eCSR_AUTH_TYPE_RSN_PSK; + //pProfile->negotiatedAuthType = eCSR_AUTH_TYPE_NONE; + //pProfile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pProfile->AuthType.numEntries = 1; + //pProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK; + + //Always set the Encryption Type + //pProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_AES; + //pProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + pProfile->EncryptionType.numEntries = 1; + //pProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES; + + pProfile->mcEncryptionType.numEntries = 1; + //pProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_AES; + + //set the RSN IE + //This is weird, but it works + pProfile->pRSNReqIE = &btampRSNIE[0]; + pProfile->nRSNReqIELength = 0x16; //TODO + //pProfile->pRSNReqIE = NULL; + + /** We don't use the WPAIE.But NULL it to avoid being used **/ + pProfile->pWPAReqIE = NULL; + pProfile->nWPAReqIELength = 0; + + // Identify the operation channel + + /* Choose the operation channel from the preferred channel list */ + pProfile->operationChannel = 0; + regulatoryClass = 0; + for (triplet = 0; triplet < btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets; triplet++) + { + firstChannel = 0; + numChannels = 0; + + /* is this a regulatory class triplet? */ + if (btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][0] == 201) + { + /* identify supported 2.4GHz regulatory classes */ + switch (btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][1]) + { + case 254: + { + /* class 254 is special regulatory class defined by BT HS+3.0 spec that + is valid only for unknown/'mobile' country */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'X') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'X')) + { + regulatoryClass = 254; + firstChannel = 1; + numChannels = 11; + } + break; + } + case 12: + { + /* class 12 in the US regulatory domain is 2.4GHz channels 1-11 */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'U') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'S')) + { + regulatoryClass = 12; + firstChannel = 1; + numChannels = 11; + } + break; + } + case 4: + { + /* class 4 in the Europe regulatory domain is 2.4GHz channels 1-13 */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'G') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'B')) + { + regulatoryClass = 4; + firstChannel = 1; + numChannels = 13; + } + break; + } + case 30: + { + /* class 30 in the Japan regulatory domain is 2.4GHz channels 1-13 */ + if ((btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[0] == 'J') && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_country[1] == 'P')) + { + regulatoryClass = 30; + firstChannel = 1; + numChannels = 13; + } + break; + } + default: + { + break; + } + } + /* if the next triplet is not another regulatory class triplet then it must be a sub-band + triplet. Skip processing the default channels for this regulatory class triplet and let + the sub-band triplet restrict the available channels */ + if (((triplet+1) < btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets) && + (btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet+1][0] != 201)) + { + continue; + } + } + else + { + /* if the regulatory class is valid then this is a sub-band triplet */ + if (regulatoryClass) + { + firstChannel = btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][0]; + numChannels = btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[triplet][1]; + } + } + + if (firstChannel && numChannels) + { + if (!btampContext->btamp_AMP_Assoc.HC_pref_num_triplets) + { + pProfile->operationChannel = firstChannel; + break; + } + else if (((btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0] + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][1]) <= firstChannel) || + ((firstChannel + numChannels ) <= btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0])) + { + continue; + } + else if ((btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0] + btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][1]) > firstChannel) + { + pProfile->operationChannel = firstChannel; + break; + } + else if ((firstChannel + numChannels) > btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0]) + { + pProfile->operationChannel = btampContext->btamp_AMP_Assoc.HC_pref_triplets[1][0]; + break; + } + } + } + + if (!pProfile->operationChannel) + { + return VOS_STATUS_E_INVAL; + } + + /*Set the selected channel */ + sessionid = sme_GetInfraSessionId(hHal); + /*if there is infra session up already, use that channel only for BT AMP + connection, else we can use the user preferred one*/ + if(-1 != sessionid) + { + pProfile->operationChannel = + sme_GetInfraOperationChannel(hHal, + sessionid); + } + + if(sme_IsChannelValid(hHal, pProfile->operationChannel)) + { + btampContext->channel = pProfile->operationChannel; + } + else + { + //no valid channel, not proceeding with connection + return VOS_STATUS_E_INVAL; + } + + if ( BT_INITIATOR == btampContext->BAPDeviceRole ) + { + pProfile->ChannelInfo.numOfChannels = 1; + pProfile->ChannelInfo.ChannelList = &pProfile->operationChannel; + } + else + { + pProfile->ChannelInfo.numOfChannels = 1; + pProfile->ChannelInfo.ChannelList = &pProfile->operationChannel; + } + + + // Turn off CB mode + pProfile->CBMode = eCSR_CB_OFF; + + //set the phyMode to accept anything + //Taurus means everything because it covers all the things we support + pProfile->phyMode = eCSR_DOT11_MODE_11n; //eCSR_DOT11_MODE_TAURUS; //eCSR_DOT11_MODE_AUTO; /*eCSR_DOT11_MODE_BEST;*/ + + //set the mode in CFG as well + sme_CfgSetInt(hHal, WNI_CFG_DOT11_MODE, WNI_CFG_DOT11_MODE_11N, NULL, eANI_BOOLEAN_FALSE); + + pProfile->bWPSAssociation = eANI_BOOLEAN_FALSE; + + //Make sure we DON'T request UAPSD + pProfile->uapsd_mask = 0; + + //return the vosStatus + return vosStatus; +} //convertToCsrProfile + +VOS_STATUS +gotoStarting +( + ptBtampContext btampContext, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + eCsrRoamBssType bssType, + v_U8_t *status /* return the BT-AMP status here */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus halStatus; + v_U32_t parseStatus; + /* tHalHandle */ + tHalHandle hHal; + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pBapHCIWriteRemoteAMPAssoc + = (tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *) bapEvent->params; + tBtampAMP_ASSOC btamp_ASSOC; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + if (NULL == btampContext) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "btampContext is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + //If we are a BT-Responder, we are assuming we are a BT "slave" and we HAVE + //to "squelch" the slaves frequent (every 1.25ms) polls. + + if (eCSR_BSS_TYPE_WDS_STA == bssType) + { + /* Sleep for 300(200) milliseconds - to allow BT through */ + vos_sleep( 200 ); + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 1); + } + + + //Tell PMC to exit BMPS; + halStatus = pmcRequestFullPower( + hHal, + WLANBAP_pmcFullPwrReqCB, + btampContext, + eSME_REASON_OTHER); + // JEZ081210: This has to wait until we sync down from + // /main/latest as of 12/4. We are currently at 12/3. + //eSME_FULL_PWR_NEEDED_BY_BAP); + //Need to check the result...because Host may have been told by + //OS to go to standby (D2) device state. In that case, I have to + //fail the HCI Create Physical Link + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, amp_assoc_remaining_length = %d", __func__, + pBapHCIWriteRemoteAMPAssoc->amp_assoc_remaining_length); +#if 0 + DUMPLOG(1, __func__, "amp_assoc_fragment", + pBapHCIWriteRemoteAMPAssoc->amp_assoc_fragment, + 64); +#endif //0 + + //What about parsing the AMP Assoc structure? + parseStatus = btampUnpackAMP_ASSOC( + hHal, + pBapHCIWriteRemoteAMPAssoc->amp_assoc_fragment, + pBapHCIWriteRemoteAMPAssoc->amp_assoc_remaining_length, + &btamp_ASSOC); + + /* Unknown or Reserved TLVs are allowed in the write AMP assoc fragment */ + if ((BTAMP_PARSE_SUCCESS != parseStatus ) && (BTAMP_UNKNOWN_TLVS != parseStatus)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, parseStatus = %d", __func__, parseStatus); + *status = WLANBAP_ERROR_INVALID_HCI_CMND_PARAM; + return VOS_STATUS_E_BADMSG; + } + + //What about writing the peer MAC address, and other info to the BTAMP + //context for this physical link? + if (btamp_ASSOC.AMP_Assoc_MAC_Addr.present == 1) + { + /* Save the peer MAC address */ + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr, + btamp_ASSOC.AMP_Assoc_MAC_Addr.mac_addr, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_mac_addr)); + /* Save it in the peer MAC address field */ + vos_mem_copy( + btampContext->peer_mac_addr, + btamp_ASSOC.AMP_Assoc_MAC_Addr.mac_addr, + sizeof(btampContext->peer_mac_addr)); + } + + if (btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.present == 1) + { + /* Save the peer Preferred Channel List */ + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_pref_country, + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.country, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_pref_country)); + /* Save the peer Preferred Channel List */ + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets = + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.num_triplets; + if(WLANBAP_MAX_NUM_TRIPLETS < + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets) + { + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets = + WLANBAP_MAX_NUM_TRIPLETS; + } + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets, + btamp_ASSOC.AMP_Assoc_Preferred_Channel_List.triplets, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_pref_triplets[0]) * + btampContext->btamp_Remote_AMP_Assoc.HC_pref_num_triplets + ); + } + + if (btamp_ASSOC.AMP_Assoc_Connected_Channel.present == 1) + { + /* Save the peer Connected Channel */ + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_country, + btamp_ASSOC.AMP_Assoc_Connected_Channel.country, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_cnct_country)); + /* Save the peer Connected Channel */ + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets = + btamp_ASSOC.AMP_Assoc_Connected_Channel.num_triplets; + if(WLANBAP_MAX_NUM_TRIPLETS < + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets) + { + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets = + WLANBAP_MAX_NUM_TRIPLETS; + } + vos_mem_copy( + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_triplets, + btamp_ASSOC.AMP_Assoc_Connected_Channel.triplets, + sizeof(btampContext->btamp_Remote_AMP_Assoc.HC_cnct_triplets[0]) * + btampContext->btamp_Remote_AMP_Assoc.HC_cnct_num_triplets + ); + } + + if (btamp_ASSOC.AMP_Assoc_PAL_Capabilities.present == 1) + { + /* Save the peer PAL Capabilities */ + btampContext->btamp_Remote_AMP_Assoc.HC_pal_capabilities + = btamp_ASSOC.AMP_Assoc_PAL_Capabilities.pal_capabilities; + } + + if (btamp_ASSOC.AMP_Assoc_PAL_Version.present == 1) + { + /* Save the peer PAL Version */ + btampContext->btamp_Remote_AMP_Assoc.HC_pal_version + = btamp_ASSOC.AMP_Assoc_PAL_Version.pal_version; + + btampContext->btamp_Remote_AMP_Assoc.HC_pal_CompanyID + = btamp_ASSOC.AMP_Assoc_PAL_Version.pal_CompanyID; + + btampContext->btamp_Remote_AMP_Assoc.HC_pal_subversion + = btamp_ASSOC.AMP_Assoc_PAL_Version.pal_subversion; + } + + //Set Connection Accept Timeout; + /* Already done in gotoS1() */ + //Set gNeedPhysLinkCompEvent; + //JEZ081114: This needs to happen earlier. In gotoS1. Right at HCI Create Physical Link + btampContext->gNeedPhysLinkCompEvent = VOS_TRUE; + //Clear gDiscRequested; + btampContext->gDiscRequested = VOS_FALSE; + //Set gPhysLinkStatus to 0 (no error); + btampContext->gPhysLinkStatus = WLANBAP_STATUS_SUCCESS; + //Set gDiscReason to 0 (no reason); + btampContext->gDiscReason = WLANBAP_STATUS_SUCCESS; + /* Initiate the link as either START or JOIN */ + //halStatus = csrRoamOpenSession(&newSession); + /*Added by Luiza:*/ + + if (btampContext->isBapSessionOpen == FALSE) + { + + halStatus = sme_OpenSession(hHal, + WLANBAP_RoamCallback, + btampContext, + // <=== JEZ081210: FIXME + //(tANI_U8 *) btampContext->self_mac_addr, + btampContext->self_mac_addr, + &btampContext->sessionId); + if(eHAL_STATUS_SUCCESS == halStatus) + { + btampContext->isBapSessionOpen = TRUE; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "sme_OpenSession failed in %s", __func__); + *status = WLANBAP_ERROR_NO_CNCT; + return VOS_STATUS_E_FAILURE; + } + } + /* Update the SME Session info for this Phys Link (i.e., for this Phys State Machine instance) */ + //bapUpdateSMESessionForThisPhysLink(newSession, PhysLinkHandle); + // Taken care of, above + //halStatus = csrRoamConnect(newSession, bssType); + // Final + vosStatus = convertToCsrProfile ( + btampContext, /* btampContext value */ + bssType, + &btampContext->csrRoamProfile); /* return the profile info here */ + if(VOS_STATUS_E_INVAL == vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Incorrect channel to create AMP link %s", __func__); + *status = WLANBAP_ERROR_NO_SUITABLE_CHANNEL; + return VOS_STATUS_E_INVAL; + } +#if 0 + halStatus = sme_RoamConnect(VOS_GET_HAL_CB(btampContext->pvosGCtx), + &btampContext->csrRoamProfile, + NULL, /* tScanResultHandle hBssListIn, */ + &btampContext->csrRoamId); +#endif //0 +//#if 0 + halStatus = sme_RoamConnect(hHal, + btampContext->sessionId, + &btampContext->csrRoamProfile, + &btampContext->csrRoamId); +//#endif //0 + + //Map the halStatus into a vosStatus + return vosStatus; +} //gotoStarting + +VOS_STATUS +gotoConnecting( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* No longer needed. This call has been made in gotoStarting(). */ + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 1); + + return vosStatus; +} //gotoConnecting + +VOS_STATUS +gotoAuthenticating( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* Signal BT Coexistence code in firmware to prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 1); + + return vosStatus; +} //gotoAuthenticating + +#if 0 +VOID initRsnSupplicant() +{ +/* This is a NO-OP. The Supplicant waits for MSG 1 */ +} +#endif /* 0 */ +VOS_STATUS +initRsnSupplicant +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* This is a NO-OP. The Supplicant waits for MSG 1 */ + /* Init RSN FSM */ + if (!(suppRsnFsmCreate(btampContext))) + { + /* Send Start Event */ + /* RSN_FSM_AUTH_START */ + } + else + { + /* RSN Init Failed */ + vosStatus = VOS_STATUS_E_FAILURE; + } + /* This is a NO-OP. The Supplicant waits for MSG 1 */ + return vosStatus; +} + +#if 0 +VOID initRsnAuthenticator() +{ +/* Signal the Authenticator/Supplicant App that we are associated. */ +/* Use an IOCTL? That the app is hanging a read on? Or use a "special" data packet. Again, that the app is waiting on a receive for. */ +} +#endif /* 0 */ +VOS_STATUS +initRsnAuthenticator +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /* Init RSN FSM */ + if (!(authRsnFsmCreate(btampContext))) + { + /* Send Start Event */ + } + else + { + /* RSN Init Failed */ + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +/* Signal the Authenticator/Supplicant App that we are associated. */ +/* Use an IOCTL? That the app is hanging a read on? Or use a "special" data packet. Again, that the app is waiting on a receive for. */ +} + +/* We have to register our STA with TL */ +VOS_STATUS +regStaWithTl +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole, + tCsrRoamInfo *pCsrRoamInfo +) +{ + VOS_STATUS vosStatus; + WLAN_STADescType staDesc; + tANI_S8 rssi = 0; + + vos_mem_zero(&staDesc, sizeof(WLAN_STADescType)); + /* Fill in everything I know about the STA */ + btampContext->ucSTAId = staDesc.ucSTAId = pCsrRoamInfo->staId; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BAP register TL ucSTAId=%d\n", + staDesc.ucSTAId ); + + /* Fill in the peer MAC address */ + vos_mem_copy( + staDesc.vSTAMACAddress.bytes, + btampContext->peer_mac_addr, + sizeof(btampContext->peer_mac_addr)); + + /* Fill in the self MAC address */ + vos_mem_copy( + staDesc.vSelfMACAddress.bytes, + btampContext->self_mac_addr, + sizeof(btampContext->peer_mac_addr)); + + /* Set the STA Type */ + staDesc.wSTAType = WLAN_STA_BT_AMP; + + // Set the QoS field appropriately, if the info available + if( pCsrRoamInfo->u.pConnectedProfile) + { + btampContext->bapQosCfg.bWmmIsEnabled = //1; + pCsrRoamInfo->u.pConnectedProfile->qosConnection; + } + else + { + btampContext->bapQosCfg.bWmmIsEnabled = 0; + } + + // set the QoS field appropriately + if( btampContext->bapQosCfg.bWmmIsEnabled ) + { + staDesc.ucQosEnabled = 1; + } + else + { + staDesc.ucQosEnabled = 0; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BAP register TL QoS_enabled=%d\n", + staDesc.ucQosEnabled ); + + // UMA is ready we inform TL not to do frame + // translation for WinMob 6.1 + //*** Not to enabled UMA. + /* Enable UMA for TX translation only when there is no concurrent session active */ + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 0; + + if ( btampContext->ucSecEnabled ) + { + staDesc.ucProtectedFrame = 1; + } + else + { + staDesc.ucProtectedFrame = 0; + } + + staDesc.ucUcastSig = pCsrRoamInfo->ucastSig; + staDesc.ucBcastSig = pCsrRoamInfo->bcastSig; + staDesc.ucInitState = ( btampContext->ucSecEnabled)? + WLANTL_STA_CONNECTED:WLANTL_STA_AUTHENTICATED; + staDesc.ucIsReplayCheckValid = VOS_FALSE; + if(NULL != pCsrRoamInfo->pBssDesc) + { + rssi = pCsrRoamInfo->pBssDesc->rssi; + } + /* register our STA with TL */ + vosStatus = WLANTL_RegisterSTAClient + ( + btampContext->pvosGCtx, + WLANBAP_STARxCB, + WLANBAP_TxCompCB, + (WLANTL_STAFetchPktCBType)WLANBAP_STAFetchPktCB, + &staDesc , + rssi); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + __func__, vosStatus, vosStatus ); + } + + if ( ! btampContext->ucSecEnabled ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_MED, + "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", btampContext->ucSTAId); + + // Connections that do not need Upper layer auth, transition TL directly + // to 'Authenticated' state. + vosStatus = WLANTL_ChangeSTAState( btampContext->pvosGCtx, staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED ); + } + else + { + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_MED, + "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", btampContext->ucSTAId ); + + vosStatus = WLANTL_ChangeSTAState( btampContext->pvosGCtx, staDesc.ucSTAId, + WLANTL_STA_CONNECTED ); + } + + return VOS_STATUS_SUCCESS; +} /* regStaWithTl */ + +#if 0 +/*========================================================================== + + FUNCTION: determineChan + + DESCRIPTION: Return the current channel we are to operate on + +============================================================================*/ +#endif + +VOS_STATUS +determineChan +( + ptBtampContext btampContext, /* btampContext value */ + tWLAN_BAPRole BAPDeviceRole, + v_U32_t *channel, /* Current channel */ + v_U8_t *status /* return the BT-AMP status here */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t activeFlag; /* Channel active flag */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + switch(BAPDeviceRole) + { + case BT_INITIATOR: + /* if an Infra assoc already exists, return that channel. */ + /* or use the results from the Scan to determine the least busy channel. How? */ + /* For now, just do this. */ + vosStatus = WLANBAP_GetCurrentChannel (btampContext, channel, &activeFlag); + break; + case BT_RESPONDER: + /* return the value obtained from the Preferred Channels field of the AMP Assoc structure from the BT-AMP peer (device A) */ + /* No! I don't have that yet. */ + /* For now, just do this. */ + vosStatus = WLANBAP_GetCurrentChannel (btampContext, channel, &activeFlag); + break; + default: + *status = WLANBAP_ERROR_HOST_REJ_RESOURCES; /* return the BT-AMP status here */ + return VOS_STATUS_E_RESOURCES; + } + *status = WLANBAP_STATUS_SUCCESS; /* return the BT-AMP status here */ + + return vosStatus; +} // determineChan + +VOS_STATUS +gotoDisconnected +( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + //Is it legitimate to always make this call? + //What if pmcRequestFullPower wasn't called? + //Tell PMC to resume BMPS; /* Whatever the previous BMPS "state" was */ + //Comment this out until such time as we have PMC support + //halStatus = pmcResumePower ( hHal); + + /* Signal BT Coexistence code in firmware to no longer prefer WLAN */ + WLANBAP_NeedBTCoexPriority ( btampContext, 0); + + //Map the halStatus into a vosStatus + return vosStatus; +} // gotoDisconnected + +VOS_STATUS +gotoDisconnecting +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t needPhysLinkCompEvent, + v_U8_t physLinkStatus, /* BT-AMP disconnecting status */ +// v_U8_t statusPresent, /* BT-AMP disconnecting status present */ + v_U8_t discRequested, + v_U8_t discReason /* BT-AMP disconnecting reason */ +) +{ + + // gNeedPhysLinkCompEvent + btampContext->gNeedPhysLinkCompEvent = needPhysLinkCompEvent; + // gPhysLinkStatus + btampContext->gPhysLinkStatus = physLinkStatus; /* BT-AMP disconnecting status */ + // gDiscRequested + btampContext->gDiscRequested = discRequested; + // gDiscReason + btampContext->gDiscReason = discReason; /* BT-AMP disconnecting reason */ + + //WLANBAP_DeInitLinkSupervision( btampHandle); + //WLANBAP_StopLinkSupervisionTimer(btampContext); + + /* Inform user space that no AMP channel is in use, for AFH purposes */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, + "Calling send_btc_nlink_msg() with AMP channel = 0"); + send_btc_nlink_msg(WLAN_AMP_ASSOC_DONE_IND, 0); + + return VOS_STATUS_SUCCESS; +} //gotoDisconnecting + +VOS_STATUS +gotoConnected +( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampHandle btampHandle = ( ptBtampHandle)btampContext; +//#if 0 + /* Stop the Connection Accept Timer */ + vosStatus = WLANBAP_StopConnectionAcceptTimer (btampContext); +//#endif + ///*De-initialize the timer */ + //vosStatus = WLANBAP_DeinitConnectionAcceptTimer(btampContext); + + /* Signal BT Coex in firmware to now honor only priority BT requests */ + WLANBAP_NeedBTCoexPriority ( btampContext, 2); + + // If required after successful Upper layer auth, transition TL + // to 'Authenticated' state. + if ( btampContext->ucSecEnabled ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_MED, + "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", btampContext->ucSTAId); + + vosStatus = WLANTL_ChangeSTAState( + btampContext->pvosGCtx, + btampContext->ucSTAId, + WLANTL_STA_AUTHENTICATED ); + } + + btampContext->dataPktPending = VOS_FALSE; + vosStatus = WLANBAP_InitLinkSupervision( btampHandle); + + /* Inform user space of the AMP channel selected, for AFH purposes */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, + "Calling send_btc_nlink_msg() with AMP channel %d", btampContext->channel); + send_btc_nlink_msg(WLAN_AMP_ASSOC_DONE_IND, btampContext->channel); + + return vosStatus; +} //gotoConnected + + +/* the HCI Event signalling routine*/ +VOS_STATUS +signalHCIPhysLinkCompEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status /* the BT-AMP status */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Physical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.phy_link_handle + = btampContext->phy_link_handle; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.ch_number + = btampContext->channel; + + if(WLANBAP_STATUS_SUCCESS == status) + { + /* Start the Tx packet monitoring timer */ + WLANBAP_StartTxPacketMonitorTimer(btampContext); + } + else + { //reset the PL handle + btampContext->phy_link_handle = 0; + } + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIPhysLinkCompEvent */ + +/* the HCI Disconnect Complete Event signalling routine*/ +VOS_STATUS +signalHCIPhysLinkDiscEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status, /* the BT-AMP status */ + v_U8_t reason /* the BT-AMP reason code */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + v_U8_t i; + tpBtampLogLinkCtx pLogLinkContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + +#ifdef BAP_DEBUG + /* Trace the tBtampCtx being passed in. */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN BAP Context Monitor: btampContext value = %p in %s:%d", btampContext, __func__, __LINE__ ); +#endif //BAP_DEBUG + + /* Loop disconnecting all Logical Links on this Physical Link */ + for (i = 0 ; i < WLANBAP_MAX_LOG_LINKS; i++) + { + pLogLinkContext = &(btampContext->btampLogLinkCtx[i]); + + if (pLogLinkContext->present == VOS_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "WLAN BAP: Deleting logical link entry %d in %s", i, + __func__); + + /* Mark this Logical Link index value as free */ + pLogLinkContext->present = VOS_FALSE; + + // signalHCIDiscLogLink(status = SUCCESS, reason = CONNECTION_TERM_BY_REMOTE_HOST); + signalHCIDiscLogLinkCompEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + i, // logical link + // I don't know how to signal CONNECTION_TERM_BY_REMOTE_HOST + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + } + + /*Reset current_log_link_index and total_log_link_index values*/ + btampContext->current_log_link_index = 0; + btampContext->total_log_link_index = 0; + + /* Format the Physical Link Disconnect Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.reason = reason;//uncommented to debug + bapHCIEvent.u.btampDisconnectPhysicalLinkCompleteEvent.phy_link_handle + = btampContext->phy_link_handle; + + /* Stop the Tx packet monitoring timer */ + WLANBAP_StopTxPacketMonitorTimer(btampContext); + + /*Need to clean up the phy link handle as we are disconnected at this + point + ?? - do we need to do any more cleanup on this*/ + btampContext->phy_link_handle = 0; + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIPhysLinkDiscEvent */ + +/* the HCI Channel Select Event signalling routine*/ +VOS_STATUS +signalHCIChanSelEvent +( + ptBtampContext btampContext /* btampContext value */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Physical Link Disconnect Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT; + bapHCIEvent.u.btampChannelSelectedEvent.present = 1; + bapHCIEvent.u.btampChannelSelectedEvent.phy_link_handle + = btampContext->phy_link_handle; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIChanSelEvent */ + + +/* the HCI Disconnect Logical Link Complete Event signalling routine*/ +VOS_STATUS +signalHCIDiscLogLinkCompEvent +( + ptBtampContext btampContext, /* btampContext value */ + v_U8_t status, /* the BT-AMP status */ + v_U16_t log_link_handle, /* The Logical Link that disconnected*/ + v_U8_t reason /* the BT-AMP reason code */ +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tBtampHCI_Event bapHCIEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Logical Link Disconnect Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.status = status; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.reason = reason; + bapHCIEvent.u.btampDisconnectLogicalLinkCompleteEvent.log_link_handle + = (log_link_handle << 8) + btampContext->phy_link_handle; + + vosStatus = (*btampContext->pBapHCIEventCB) + ( + btampContext->pHddHdl, /* this refers the BSL per application context */ + &bapHCIEvent, /* This now encodes ALL event types */ + VOS_TRUE /* Flag to indicate assoc-specific event */ + ); + + return vosStatus; +} /* signalHCIDiscLogLinkCompEvent */ + + +// These are needed to recognize RSN suite types +#define WLANBAP_RSN_OUI_SIZE 4 +tANI_U8 pRSNOui00[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x00 }; // group cipher +tANI_U8 pRSNOui01[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x01 }; // WEP-40 or RSN +tANI_U8 pRSNOui02[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x02 }; // TKIP or RSN-PSK +tANI_U8 pRSNOui03[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x03 }; // Reserved +tANI_U8 pRSNOui04[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x04 }; // AES-CCMP +tANI_U8 pRSNOui05[ WLANBAP_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; // WEP-104 + +/* Incoming Association indication validation predicate */ +v_U32_t +validAssocInd +( + ptBtampContext btampContext, /* btampContext value */ + tCsrRoamInfo *pRoamInfo +) +{ + /* tHalHandle */ + tHalHandle hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + v_U32_t ieLen; + + /* For now, always return true */ + return VOS_TRUE; + + /* Check for a valid peer MAC address */ + /* For an incoming Assoc Indication, the peer MAC address + * should match the value that the BlueTooth AMP + * configured us with. + */ + if ( !vos_mem_compare( btampContext->peer_mac_addr, + pRoamInfo->peerMac, + sizeof(btampContext->peer_mac_addr) )) + { + /* Return not valid */ + return VOS_FALSE; + } + + /* JEZ081115: For now, ignore the RSN IE */ + /* Otherwise, it is valid */ + return VOS_TRUE; + + /* Check for a trivial case: IEs missing */ + if( pRoamInfo->prsnIE == NULL ) + { + //btampContext->ieFields = NULL; + //btampContext->ieLen = 0; + /* Return not valid */ + return VOS_FALSE; + } + + //btampContext->ieLen = GET_IE_LEN_IN_BSS( pBssDesc->length ); + //ieLen = GET_IE_LEN_IN_BSS( pBssDesc->length ); + ieLen = pRoamInfo->rsnIELen; + + /* Check for a trivial case: IEs zero length */ + //if( btampContext->ieLen == 0 ) + if( ieLen == 0 ) + { + //btampContext->ieFields = NULL; + //btampContext->ieLen = 0; + /* Return not valid */ + return VOS_FALSE; + } + + { + // --- Start of block --- + tDot11fBeaconIEs dot11BeaconIEs; + tDot11fIESSID *pDot11SSID; + tDot11fIERSN *pDot11RSN; + + // JEZ081215: This really needs to be updated to just validate the RSN IE. + // Validating the SSID can be done directly from... + + // "Unpack" really wants tpAniSirGlobal (pMac) as its first param. + // But since it isn't used, I just pass in some arbitrary "context" pointer. + // So hHalHandle will make it happy. + dot11fUnpackBeaconIEs((tpAniSirGlobal) hHal, + (tANI_U8 *) pRoamInfo->prsnIE, + ieLen, + &dot11BeaconIEs); + + //DUMPLOG(9, __func__, "dot11BeaconIEs", &dot11BeaconIEs, 64); + + pDot11SSID = &dot11BeaconIEs.SSID; + + // Assume there wasn't an SSID in the Assoc Request + btampContext->assocSsidLen = 0; + + if (pDot11SSID->present ) + { + + //DUMPLOG(10, __func__, "pDot11SSID present", pDot11SSID, 64); + + btampContext->assocSsidLen = pDot11SSID->num_ssid; + vos_mem_copy(btampContext->assocSsid, + pDot11SSID->ssid, + btampContext->assocSsidLen ); + } + else + return VOS_FALSE; + + // Check the validity of the SSID against our SSID value + if ( !vos_mem_compare( btampContext->ownSsid, + pDot11SSID->ssid, + btampContext->ownSsidLen )) + { + /* Return not valid */ + return VOS_FALSE; + } + + pDot11RSN = &dot11BeaconIEs.RSN; + + // Assume there wasn't an RSN IE in the Assoc Request + //btampContext->assocRsnIeLen = 0; + + if (pDot11RSN->present ) + { + + //DUMPLOG(10, __func__, "pDot11RSN present", pDot11RSN, 64); + + //The 802.11 BT-AMP PAL only supports WPA2-PSK + if (!vos_mem_compare(pRSNOui02, // RSN-PSK + pDot11RSN->akm_suites[0], + WLANBAP_RSN_OUI_SIZE)) + return VOS_FALSE; + + //The 802.11 BT-AMP PAL only supports AES-CCMP Unicast + if (!vos_mem_compare(pRSNOui04, // AES-CCMP + pDot11RSN->pwise_cipher_suites[0], + WLANBAP_RSN_OUI_SIZE)) + return VOS_FALSE; + } + else + return VOS_FALSE; + + + } // --- End of block --- + + /* Otherwise, it is valid */ + return VOS_TRUE; +} /* validAssocInd */ + +/* the change state function*/ +void +btampfsmChangeToState +( + BTAMPFSM_INSTANCEDATA_T *instance, + BTAMPFSM_STATES_T state +) +{ + instance->stateVar = state; + //BTAMPFSM_ENTRY_FLAG_T disconnectedEntry; + +} + +/* Physical Link state machine function */ +//int +VOS_STATUS +btampFsm +( + //BTAMPFSM_INSTANCEDATA_T *instanceVar + ptBtampContext btampContext, /* btampContext value */ +// tBtampSessCtx *tpBtampSessCtx, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + v_U8_t *status /* return the BT-AMP status here */ +) +{ + /* Retrieve the phy link state machine structure + * from the btampContext value + */ + BTAMPFSM_INSTANCEDATA_T *instanceVar; + v_U32_t msg = bapEvent->event; /* State machine input event message */ + v_U32_t channel; /* Current channel */ + v_U32_t activeFlag; /* Channel active flag */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptBtampHandle btampHandle = ( ptBtampHandle)btampContext; + v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ + v_PVOID_t pHddHdl; /* Handle to return BSL context in */ + tHalHandle hHal = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* Validate params */ + if (btampHandle == NULL) + { + return VOS_STATUS_E_FAULT; + } + instanceVar = &(btampContext->bapPhysLinkMachine); + + hHal = VOS_GET_HAL_CB(btampContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + } + + + +#define CHANNEL_NOT_SELECTED (WLANBAP_GetCurrentChannel (btampContext, &channel, &activeFlag) != VOS_STATUS_SUCCESS) + + /*Initialize BTAMP PAL status code being returned to the btampFsm caller */ + *status = WLANBAP_STATUS_SUCCESS; + + switch(instanceVar->stateVar) + { + + case DISCONNECTED: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_CREATE)) + { + /*Transition from DISCONNECTED to S1 (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "DISCONNECTED", "S1"); + +#if 0 + /* This will have issues in multisession. Need not close the session */ + /* TODO : Need to have better handling */ + if(btampContext->isBapSessionOpen == TRUE)//We want to close only BT-AMP Session + { + sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId); + /*Added by Luiza:*/ + btampContext->isBapSessionOpen = FALSE; + } +#endif + + /* Set BAP device role */ + vosStatus = gotoS1( btampContext, bapEvent, BT_INITIATOR, status); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, cmd status is %d", __func__, *status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,S1); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_ACCEPT)) + { + /*Transition from DISCONNECTED to S1 (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "DISCONNECTED", "S1"); + +#if 0 + if(btampContext->isBapSessionOpen == TRUE) + { + sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId); + /*Added by Luiza:*/ + btampContext->isBapSessionOpen = FALSE; + } + /*Action code for transition */ +#endif + + /* Set BAP device role */ + vosStatus = gotoS1(btampContext, bapEvent, BT_RESPONDER, status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,S1); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "DISCONNECTED", msg); + /* Intentionally left blank */ + } + break; + + case S1: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC + ) && (btampContext->BAPDeviceRole == BT_INITIATOR && !(CHANNEL_NOT_SELECTED))) + { + /*Transition from S1 to STARTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "STARTING"); + + /*Action code for transition */ + vosStatus = determineChan(btampContext, BT_INITIATOR, &channel, status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,STARTING); + // This has to be commented out until I get the BT-AMP SME/CSR changes + vosStatus = gotoStarting( btampContext, bapEvent, eCSR_BSS_TYPE_WDS_AP, status); + if (VOS_STATUS_SUCCESS != vosStatus) + { + btampfsmChangeToState(instanceVar, S1); + } + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from S1 to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "DISCONNECTED"); + + /*Action code for transition */ + /* Set everything back as dis-connected */ + gotoDisconnected( btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + /*Signal the disconnect */ + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_HOST_TIMEOUT); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from S1 to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + /*Signal the successful physical link disconnect */ + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Signal the unsuccessful physical link creation */ + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_NO_CNCT ); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from S1 to STARTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "STARTING"); + + /*Action code for transition */ + //determineChan(BT_RESPONDER); + vosStatus = determineChan(btampContext, BT_RESPONDER, &channel, status); + btampfsmChangeToState(instanceVar,STARTING);//Moved to here to debug + // This has to be commented out until I get the BT-AMP SME/CSR changes + /*Advance outer statevar */ + // btampfsmChangeToState(instanceVar,STARTING); + vosStatus = gotoStarting( btampContext, bapEvent, eCSR_BSS_TYPE_WDS_STA, status); + if (VOS_STATUS_SUCCESS != vosStatus) + { + btampfsmChangeToState(instanceVar, S1); + } + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC + ) && (btampContext->BAPDeviceRole == BT_INITIATOR && CHANNEL_NOT_SELECTED)) + { + /*Transition from S1 to SCANNING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "S1", "SCANNING"); + + /*Action code for transition */ + gotoScanning(btampContext, BT_RESPONDER, status); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,SCANNING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "S1", msg); + /* Intentionally left blank */ + } + break; + + case STARTING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_START_BSS_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_INITIATOR)) + { + /*Transition from STARTING to CONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "CONNECTING"); + + btampfsmChangeToState(instanceVar,CONNECTING);//Moved to debug + + /*Set the selected channel */ + /*should have been already set */ + btampContext->channel = ( 0 == btampContext->channel )?1:btampContext->channel; + + /*Action code for transition */ + signalHCIChanSelEvent(btampContext); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from STARTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + // Danlin, where are the richer reason codes? + // I want to be able to convey everything 802.11 supports... + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_CHANNEL_SELECTION_FAILED)) + { + /*Transition from STARTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTED"); + + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + /*Action code for transition */ + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_HOST_REJ_RESOURCES ); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_START_BSS_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from STARTING to CONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "CONNECTING"); + + /* Set the selected channel */ + /*should have been already set */ + btampContext->channel = ( 0 == btampContext->channel )?1:btampContext->channel; + + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTING); + /*Action code for transition */ + gotoConnecting(btampContext); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from STARTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_START_FAILS)) + { + /*Transition from STARTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "STARTING", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_MAX_NUM_CNCTS ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "STARTING", msg); + /* Intentionally left blank */ + } + break; + + case CONNECTING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_COMPLETED + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from CONNECTING to AUTHENTICATING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "AUTHENTICATING"); + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "CONNECTED"); + + gotoAuthenticating(btampContext); + /*Action code for transition */ + initRsnSupplicant(btampContext, BT_RESPONDER); +#if 1 + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,AUTHENTICATING); +#else + /*Action code for transition */ + signalHCIPhysLinkCompEvent(btampContext, WLANBAP_STATUS_SUCCESS); + gotoConnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTED); +#endif + /* register our STA with TL */ + regStaWithTl ( + btampContext, /* btampContext value */ + BT_RESPONDER, + (tCsrRoamInfo *)bapEvent->params); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_INDICATION + //) && (bssDesc indicates an invalid peer MAC Addr or SecParam)){ + ) && !validAssocInd(btampContext, (tCsrRoamInfo *)bapEvent->params)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + /*Action code for transition */ + //csrRoamDisconnect(DEAUTH); + //JEZ081120: Danlin points out that I could just ignore this + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_DEAUTH); + //eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_AUTHENT_FAILURE, + VOS_FALSE, + 0); + + /*Set the status code being returned to the btampFsm caller */ + *status = WLANBAP_ERROR_AUTHENT_FAILURE; + + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_INDICATION + //) && (bssDesc indicates a valid MAC Addr and SecParam)){ + ) && validAssocInd(btampContext, (tCsrRoamInfo *)bapEvent->params)) + { + /*Transition from CONNECTING to VALIDATED (both without substates)*/ + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "VALIDATED"); + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "AUTHENTICATING"); + //VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "CONNECTED"); + + /*Action code for transition */ + // JEZ081027: This one is a pain. Since we are responding in the + // callback itself. This messes up my state machine. + //csrRoamAccept(); + + // No! This is fine. + /*Set the status code being returned to the btampFsm caller */ + *status = WLANBAP_STATUS_SUCCESS; + + /* JEZ081215: N.B.: Currently, I don't get the + * eCSR_ROAM_RESULT_WDS_ASSOCIATED as an AP. + * So, I have to register with TL, here. This + * seems weird. + */ + + /* register our STA with TL */ + regStaWithTl ( + btampContext, /* btampContext value */ + BT_INITIATOR, + (tCsrRoamInfo *)bapEvent->params ); + + gotoAuthenticating(btampContext); + /*Action code for transition */ + initRsnAuthenticator(btampContext, BT_INITIATOR); + +#if 1 + /*Advance outer statevar */ + //btampfsmChangeToState(instanceVar,VALIDATED); + btampfsmChangeToState(instanceVar,AUTHENTICATING); +#else + /*Action code for transition */ + signalHCIPhysLinkCompEvent(btampContext, WLANBAP_STATUS_SUCCESS); + gotoConnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTED); +#endif + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_FAILED)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + + /*Action code for transition */ + sme_RoamDisconnect(hHal, + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + /* Section 3.1.8 and section 3.1.9 have contradictory semantics for 0x16. + * 3.1.8 is "connection terminated by local host". 3.1.9 is "failed connection". + */ + //gotoDisconnecting(FAILED_CONNECTION); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST, //FAILED_CONNECTION + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from CONNECTING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "CONNECTING", msg); + /* Intentionally left blank */ + } + break; + + case AUTHENTICATING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_RSN_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_RESPONDER)) + { + /*Transition from AUTHENTICATING to KEYING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "AUTHENTICATING", "KEYING"); + + /*Action code for transition */ + //sme_RoamSetContext(); +#if 0 + sme_RoamSetKey( + VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId, + tSirMacAddr peerBssId, + eCsrEncryptionType encryptType, + tANI_U16 keyLength, + tANI_U8 *pKey, + VOS_TRUE, // TRUE + tANI_U8 paeRole); +#endif //0 + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,KEYING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_RSN_SUCCESS + ) && (btampContext->BAPDeviceRole == BT_INITIATOR)) + { + /*Transition from AUTHENTICATING to KEYING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "AUTHENTICATING", "KEYING"); + + /*Action code for transition */ + //sme_RoamSetContext(); +#if 0 + sme_RoamSetKey( + VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId, + tSirMacAddr peerBssId, + eCsrEncryptionType encryptType, + tANI_U16 keyLength, + tANI_U8 *pKey, + VOS_TRUE, // TRUE + tANI_U8 paeRole); +#endif //0 + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,KEYING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from AUTHENTICATING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s ConnectAcceptTimeout", __func__, "AUTHENTICATING", "DISCONNECTING"); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + /*Action code for transition */ + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from AUTHENTICATING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s Physicallink Disconnect", __func__, "AUTHENTICATING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_RSN_FAILURE)) + { + /*Transition from AUTHENTICATING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s RSN Failure", __func__, "AUTHENTICATING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(DEAUTH); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_DEAUTH); + //eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_AUTHENT_FAILURE, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "AUTHENTICATING", msg); + /* Intentionally left blank */ + } + break; + + case CONNECTED: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from CONNECTED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTED", "DISCONNECTING"); + + gotoDisconnecting( + btampContext, + VOS_FALSE, + 0, + VOS_TRUE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + + WLANBAP_DeInitLinkSupervision(( ptBtampHandle)btampContext); + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION)) + { + + /*Transition from CONNECTED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "CONNECTED", "DISCONNECTING"); + WLANBAP_DeInitLinkSupervision(( ptBtampHandle)btampContext); + + gotoDisconnecting( + btampContext, + VOS_FALSE, + 0, + VOS_TRUE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Action code for transition */ + sme_RoamDisconnect(hHal, + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "CONNECTED", msg); + /* Intentionally left blank */ + } + break; + +/* JEZ081107: This will only work if I have already signalled the disconnect complete + * event in every case where a physical link complete event is required. And a + * disconnect was requested. + * - - - + * And only if I check for gNeedPhysLinkCompEvent BEFORE I check gDiscRequested. + * Naw! Not necessary. + */ + case DISCONNECTING: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Entered DISCONNECTING:", __func__);//Debug statement + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_READY_FOR_CONNECTIONS + ) && (btampContext->gDiscRequested == VOS_TRUE)) + { + /*Transition from DISCONNECTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "DISCONNECTING", "DISCONNECTED"); + + //Clear gDiscRequested; + btampContext->gDiscRequested = VOS_FALSE; + + if(btampContext->BAPDeviceRole == BT_INITIATOR) + { + if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Get LOCK Fail"); + } + authRsnFsmFree(btampContext); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Release LOCK Fail"); + } + } + else if(btampContext->BAPDeviceRole == BT_RESPONDER) + { + suppRsnFsmFree(btampContext); + } + + /* Lookup the StaId using the phy_link_handle and the BAP context */ + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + btampContext->phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __func__); + return VOS_STATUS_E_FAULT; + } + WLANTL_ClearSTAClient(btampContext->pvosGCtx, ucSTAId); + + // gotoDisconnected(btampContext); + + // VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:In DISCONNECTING-changing outer state var to DISCONNECTED", __func__); + /*Advance outer statevar */ + // btampfsmChangeToState(instanceVar,DISCONNECTED); + + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + btampContext->gDiscReason); + /*sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId);*/ + /*Action code for transition */ + gotoDisconnected(btampContext); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:In DISCONNECTING-changing outer state var to DISCONNECTED", __func__); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_READY_FOR_CONNECTIONS + ) && (btampContext->gNeedPhysLinkCompEvent == VOS_TRUE)) + { + /*Transition from DISCONNECTING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s gNeedPhysLinkComp TRUE", __func__, "DISCONNECTING", "DISCONNECTED"); + if(btampContext->BAPDeviceRole == BT_INITIATOR) + { + if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Get LOCK Fail"); + } + authRsnFsmFree(btampContext); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&btampContext->bapLock))) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"btampFsm, Release LOCK Fail"); + } + + } + else if(btampContext->BAPDeviceRole == BT_RESPONDER) + { + suppRsnFsmFree(btampContext); + } + /* Lookup the StaId using the phy_link_handle and the BAP context */ + vosStatus = WLANBAP_GetStaIdFromLinkCtx ( + btampHandle, /* btampHandle value in */ + btampContext->phy_link_handle, /* phy_link_handle value in */ + &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ + &pHddHdl); /* Handle to return BSL context */ + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __func__); + return VOS_STATUS_E_FAULT; + } + WLANTL_ClearSTAClient(btampContext->pvosGCtx, ucSTAId); + + + /*Action code for transition */ + // signalHCIPhysLinkCompEvent(btampContext, WLANBAP_ERROR_NO_CNCT/*btampContext->gPhysLinkStatus*/); + signalHCIPhysLinkCompEvent(btampContext, btampContext->gPhysLinkStatus); + gotoDisconnected(btampContext); + /*sme_CloseSession(VOS_GET_HAL_CB(btampContext->pvosGCtx), + btampContext->sessionId);*/ + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + // signalHCIPhysLinkCompEvent(btampContext, btampContext->gPhysLinkStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "DISCONNECTING", msg); + /* Intentionally left blank */ + } + break; + + case KEYING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from KEYING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "KEYING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from KEYING to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "KEYING", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_KEY_SET_SUCCESS)) + { + /*Transition from KEYING to CONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "KEYING", "CONNECTED"); + + /*Action code for transition */ + gotoConnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,CONNECTED); + signalHCIPhysLinkCompEvent(btampContext, WLANBAP_STATUS_SUCCESS); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "KEYING", msg); + /* Intentionally left blank */ + } + break; + + case SCANNING: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_SCAN_COMPLETE)) + { + /*Transition from SCANNING to STARTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "SCANNING", "STARTING"); + + /*Action code for transition */ + vosStatus = determineChan(btampContext, BT_INITIATOR, &channel, status); + // This has to be commented out until I get the BT-AMP SME/CSR changes + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,STARTING); + vosStatus = gotoStarting( btampContext, bapEvent, eCSR_BSS_TYPE_WDS_AP, status); + if (VOS_STATUS_SUCCESS != vosStatus) + { + btampfsmChangeToState(instanceVar, SCANNING); + } + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from SCANNING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "SCANNING", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_HOST_TIMEOUT); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from SCANNING to DISCONNECTED (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "SCANNING", "DISCONNECTED"); + + /*Action code for transition */ + gotoDisconnected(btampContext); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTED); + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + signalHCIPhysLinkCompEvent( btampContext, WLANBAP_ERROR_NO_CNCT); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "SCANNING", msg); + /* Intentionally left blank */ + } + break; + + case VALIDATED: + if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_MAC_CONNECT_COMPLETED + ) && (btampContext->BAPDeviceRole == BT_INITIATOR)) + { + /*Transition from VALIDATED to AUTHENTICATING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "VALIDATED", "AUTHENTICATING"); + + gotoAuthenticating(btampContext); + /*Action code for transition */ + initRsnAuthenticator(btampContext, BT_INITIATOR); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,AUTHENTICATING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT)) + { + /*Transition from VALIDATED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "VALIDATED", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_HOST_TIMEOUT, + VOS_FALSE, + 0); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + } + else if((msg==(BTAMPFSM_EVENT_T)eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT)) + { + /*Transition from VALIDATED to DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", __func__, "VALIDATED", "DISCONNECTING"); + + /*Action code for transition */ + //csrRoamDisconnect(); + sme_RoamDisconnect(hHal, + //JEZ081115: Fixme + btampContext->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + gotoDisconnecting( + btampContext, + VOS_TRUE, + WLANBAP_ERROR_NO_CNCT, + //VOS_TRUE, // Should be VOS_FALSE !!! + VOS_FALSE, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + /*Advance outer statevar */ + btampfsmChangeToState(instanceVar,DISCONNECTING); + + // It is NOT clear that we need to send the Phy Link Disconnect + // Complete Event here. + signalHCIPhysLinkDiscEvent + ( btampContext, + WLANBAP_STATUS_SUCCESS, + WLANBAP_ERROR_TERM_BY_LOCAL_HOST); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, in state %s, invalid event msg %d", __func__, "VALIDATED", msg); + /* Intentionally left blank */ + } + break; + + default: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, invalid state %d", __func__, instanceVar->stateVar); + /*Intentionally left blank*/ + break; + } + + return vosStatus; +} + +VOS_STATUS btampEstablishLogLink(ptBtampContext btampContext) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t msg; + + tAniBtAmpLogLinkReq *pMsg; + + pMsg = vos_mem_malloc(sizeof(tAniBtAmpLogLinkReq)); + if ( NULL == pMsg ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, failed to allocate mem for req", __func__); + return VOS_STATUS_E_NOMEM; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_BTAMP_LOG_LINK_IND); + pMsg->msgLen = (tANI_U16)sizeof(tAniBtAmpLogLinkReq); + pMsg->sessionId = btampContext->sessionId; + pMsg->btampHandle = btampContext; + + msg.type = eWNI_SME_BTAMP_LOG_LINK_IND; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, failed to post msg to self", __func__); + vos_mem_free(pMsg); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +void btampEstablishLogLinkHdlr(void* pMsg) +{ + tAniBtAmpLogLinkReq *pBtAmpLogLinkReq = (tAniBtAmpLogLinkReq*)pMsg; + ptBtampContext btampContext; + + if(pBtAmpLogLinkReq) + { + btampContext = (ptBtampContext)pBtAmpLogLinkReq->btampHandle; + if(NULL != btampContext) + { + vos_sleep( 200 ); + WLAN_BAPEstablishLogicalLink(btampContext); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, btampContext is NULL", __func__); + return; + } + + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "In %s, pBtAmpLogLinkReq is NULL", __func__); + } + return; +} + diff --git a/drivers/staging/prima/CORE/BAP/src/btampFsm.h b/drivers/staging/prima/CORE/BAP/src/btampFsm.h new file mode 100644 index 000000000000..660f07e6f793 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/btampFsm.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* This file is generated from btampFsm - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 / version 1.2 Beta 1 */ + + +#ifndef __BTAMPFSM_H__ +#define __BTAMPFSM_H__ + +#include "bapRsn8021xFsm.h" + +/* State definitions */ +typedef enum +{ + AUTHENTICATING, + DISCONNECTED, + CONNECTING, + DISCONNECTING, + SCANNING, + CONNECTED, + S1, + KEYING, + VALIDATED, + STARTING, +} BTAMPFSM_STATES_T; + + +#if 0 +/* Instance data definition of state machine */ +typedef struct +{ + BTAMPFSM_ENTRY_FLAG_T disconnectedEntry; + BTAMPFSM_STATEVAR_T stateVar; + BTAMPFSM_INST_ID_T inst_id; +} BTAMPFSM_INSTANCEDATA_T; +#endif //0 + +/* Helper to initialize the machine's instance data */ +#define BTAMPFSM_INSTANCEDATA_INIT { 1, DISCONNECTED/* set init state */, 0 /* instance id */}; + +/*Prototype for the change state function*/ +void btampfsmChangeToState(BTAMPFSM_INSTANCEDATA_T *instance, BTAMPFSM_STATES_T state); + + + +/*Prototype of the state machine function */ +//int +VOS_STATUS +btampFsm +( + //BTAMPFSM_INSTANCEDATA_T *instanceVar + ptBtampContext btampContext, /* btampContext value */ +// tBtampSessCtx *tpBtampSessCtx, /* btampContext value */ + ptWLAN_BAPEvent bapEvent, /* State machine event */ + v_U8_t *status /* return the BT-AMP status here */ +); + +VOS_STATUS +bapSetKey( v_PVOID_t pvosGCtx, tCsrRoamSetKey *pSetKeyInfo ); + +int bapSuppDisconnect(tBtampContext *ctx); +int bapAuthDisconnect(tBtampContext *ctx); +VOS_STATUS btampEstablishLogLink(ptBtampContext btampContext); +#endif diff --git a/drivers/staging/prima/CORE/BAP/src/btampFsm_ext.h b/drivers/staging/prima/CORE/BAP/src/btampFsm_ext.h new file mode 100644 index 000000000000..cb089a3a508a --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/btampFsm_ext.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* This file is generated from btampFsm.cdd - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 */ + + +#ifndef __BTAMPFSM_EXT_H__ +#define __BTAMPFSM_EXT_H__ + +/* Events that can be sent to the state-machine */ +typedef enum +{ + eWLAN_BAP_TIMER_CONNECT_ACCEPT_TIMEOUT=0U, + eWLAN_BAP_MAC_CONNECT_COMPLETED +, + eWLAN_BAP_CHANNEL_SELECTION_FAILED, + eWLAN_BAP_MAC_CONNECT_FAILED, + eWLAN_BAP_MAC_CONNECT_INDICATION +, + eWLAN_BAP_MAC_KEY_SET_SUCCESS, + eWLAN_BAP_HCI_PHYSICAL_LINK_ACCEPT, + eWLAN_BAP_RSN_FAILURE, + eWLAN_BAP_MAC_SCAN_COMPLETE, + eWLAN_BAP_HCI_PHYSICAL_LINK_CREATE, + eWLAN_BAP_MAC_READY_FOR_CONNECTIONS +, + eWLAN_BAP_MAC_START_BSS_SUCCESS +, + eWLAN_BAP_RSN_SUCCESS, + eWLAN_BAP_MAC_START_FAILS, + eWLAN_BAP_HCI_PHYSICAL_LINK_DISCONNECT, + eWLAN_BAP_MAC_INDICATES_MEDIA_DISCONNECTION, + eWLAN_BAP_HCI_WRITE_REMOTE_AMP_ASSOC +, + NO_MSG +}MESSAGE_T; + + +#endif diff --git a/drivers/staging/prima/CORE/BAP/src/btampHCI.c b/drivers/staging/prima/CORE/BAP/src/btampHCI.c new file mode 100644 index 000000000000..157b8d49d8f6 --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/btampHCI.c @@ -0,0 +1,9312 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * \file btampHCI.c + * + * \brief Structures, functions & definitions for + * working with 802.11 Frames + * + * + + * + * + * This file was automatically generated by 'framesc' + * Fri Feb 27 17:29:19 2009 from the following file(s): + * + * btampHCI.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * + */ + +#include /* For memcpy */ +#include /* For offsetof */ + +#define _vsnprintf vsnprintf + +#include "vos_api.h" +#include "btampHCI.h" + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4244) +# pragma warning (disable: 4505) +# pragma warning (disable: 4702) +# pragma warning (disable: 4996) /* ... was declared deprecated */ +#endif /* Microsoft C/C++ */ + +/*Length of the value field expected in a TLV of type Connected Channel in an + AMP Assoc*/ +#define WLAN_BAP_PAL_AMP_ASSOC_CONN_CH_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type Preferred Channel in an + AMP Assoc*/ +#define WLAN_BAP_PAL_AMP_ASSOC_PREF_CH_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type MAC Address*/ +#define WLAN_BAP_PAL_MAC_ADDR_TLV_LEN 6 + +/*Length of the value field expected in a TLV of type Capabilities*/ +#define WLAN_BAP_PAL_CAPABILITIES_TLV_LEN 4 + +/*Length of the value field expected in a TLV of type Version*/ +#define WLAN_BAP_PAL_VERSION_TLV_LEN 5 + +/*Length of the value field expected in a TLV of type Accept Phy Link*/ +#define WLAN_BAP_PAL_ACC_PHY_LINK_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type Accept Log Link*/ +#define WLAN_BAP_PAL_ACC_LOG_LINK_TLV_LEN 37 + +/*Length of the value field expected in a TLV of type Create Log Link*/ +#define WLAN_BAP_PAL_CREATE_LOG_LINK_TLV_LEN 37 + +/*Length of the value field expected in a TLV of type Create Phy Link*/ +#define WLAN_BAP_PAL_CREATE_PHY_LINK_TLV_MIN_LEN 3 + +/*Length of the value field expected in a TLV of type Disconnect Log Link*/ +#define WLAN_BAP_PAL_DISC_LOG_LINK_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Disconnect Phy Link*/ +#define WLAN_BAP_PAL_DISC_PHY_LINK_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Flow Spec Modify*/ +#define WLAN_BAP_PAL_FLOW_SPEC_MOD_TLV_LEN 34 + +/*Length of the value field expected in a TLV of type Flush*/ +#define WLAN_BAP_PAL_FLUSH_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type enhanced Flush*/ +#define WLAN_BAP_PAL_ENHANCED_FLUSH_TLV_LEN 3 + +/*Length of the value field expected in a TLV of type Cancel Log Link*/ +#define WLAN_BAP_PAL_CANCEL_LOG_LINK_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Best Effort Flush + Timeout*/ +#define WLAN_BAP_PAL_READ_BE_FLUSH_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Failed Contact + Counter*/ +#define WLAN_BAP_PAL_READ_FAILED_CONTACT_CNT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Link Quality*/ +#define WLAN_BAP_PAL_READ_LINK_QUALITY_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Link Supervision + Timeout*/ +#define WLAN_BAP_PAL_READ_LINK_SVISISON_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Read Local AMP Assoc*/ +#define WLAN_BAP_PAL_READ_LOCAL_AMP_ASSOC_TLV_LEN 5 + +/*Length of the value field expected in a TLV of type Read RSSI*/ +#define WLAN_BAP_PAL_READ_RSSI_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Reset Failed Contact + Counter*/ +#define WLAN_BAP_PAL_RESET_FAILED_CONTACT_CNT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Set Event Mask*/ +#define WLAN_BAP_PAL_SET_EVENT_MASK_TLV_LEN 8 + +/*Length of the value field expected in a TLV of type Set Event Mask2*/ +#define WLAN_BAP_PAL_SET_EVENT_MASK2_TLV_LEN 8 + +/*Length of the value field expected in a TLV of type Set SHort Range Mode*/ +#define WLAN_BAP_PAL_SET_SHORT_RANGE_MODE_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Write Best Effort Flush + Timeout*/ +#define WLAN_BAP_PAL_WRITE_BE_FLUSH_TIMEOUT_TLV_LEN 6 + +/*Length of the value field expected in a TLV of type Write Connection Accept + Timeout*/ +#define WLAN_BAP_PAL_WRITE_CON_ACC_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Write Flow Control Mode*/ +#define WLAN_BAP_PAL_WRITE_FLOW_CTRL_MODE_TLV_LEN 1 + +/*Length of the value field expected in a TLV of type Write Link Supervision + Timeout*/ +#define WLAN_BAP_PAL_WRITE_LINK_SVISION_TIMEOUT_TLV_LEN 4 + +/*Length of the value field expected in a TLV of type Write Location Data*/ +#define WLAN_BAP_PAL_WRITE_LOCATION_DATA_CMD_TLV_LEN 5 + +/*Length of the value field expected in a TLV of type Write LL Acc Timeout*/ +#define WLAN_BAP_PAL_WRITE_LOG_LINK_ACC_TIMEOUT_TLV_LEN 2 + +/*Length of the value field expected in a TLV of type Write Loopback Mode*/ +#define WLAN_BAP_PAL_WRITE_LOOOPBACK_MODE_TLV_LEN 1 + +/*Length of the value field expected in a TLV of type Write Remote AMP Assoc*/ +#define WLAN_BAP_PAL_WRITE_REMOTE_AMP_ASSOC_MIN_TLV_LEN 5 + +/* As per AMP specification */ +/* Regulatory Extension Identifier for channel list */ +#define WLAN_BAP_PAL_REG_EXTN_ID_VAL 201 + +/* Regulatory Class for channel list */ +#define WLAN_BAP_PAL_REG_CLASS_VAL 254 + +/* Coverage ClASS for channel list */ +#define WLAN_BAP_PAL_COVERAGE_CLASS_VAL 0 + + +/* LOGGING and VALIDITY_CHECKING control */ +//#define WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING +//#define WLAN_BAPHCI_ENABLE_LOGGING + +typedef unsigned char tFRAMES_BOOL; +typedef void (*pfnGeneric_t)(void); + + +typedef struct sFFDefn { + v_U8_t size; + size_t offset; + v_U16_t sig; + pfnGeneric_t pfn; + const char *name; +} tFFDefn; + +typedef struct sIEDefn { + v_U8_t eid; + v_U16_t minSize; + v_U16_t maxSize; + size_t offset; + size_t presenceOffset; + size_t countOffset; + v_U16_t arraybound; + unsigned char oui[5]; + unsigned char noui; + v_U16_t sig; + pfnGeneric_t pfn; + const char *name; + tFRAMES_BOOL fMandatory; +} tIEDefn; + +#if !defined(countof) +#define countof(x) ( sizeof( (x) ) / sizeof( (x)[0] ) ) +#endif + +#if ! defined(BTAMP_MEMCPY) +# define BTAMP_MEMCPY(ctx, dst, src, len) \ + vos_mem_copy( (dst), (src), (len) ) \ + +#endif + +#if ! defined(BTAMP_MEMCMP) +# define BTAMP_MEMCMP(ctx, lhs, rhs, len) \ + memcmp( (lhs), (rhs), (len) ) \ + +#endif + +#ifndef BTAMP_HAVE_LOG_SEVERITIES +# define FRLOG_OFF ( 0 ) +# define FRLOGP ( 1 ) +# define FRLOGE ( 2 ) +# define FRLOGW ( 3 ) +# define FRLOG1 ( 4 ) +# define FRLOG2 ( 5 ) +# define FRLOG3 ( 6 ) +# define FRLOG4 ( 7 ) +#endif + +#define FRFL(x) x + +#ifdef BTAMP_ENABLE_LOGGING + +#ifndef BTAMP_HAVE_LOG_MACROS + +#include +#include + +#ifndef BTAMP_LOG_GATE +# define BTAMP_LOG_GATE FRLOGW +#endif // BTAMP_LOG_GATE + +#ifdef WIN32 + +#if defined ( _CONSOLE ) || defined ( _WINDOWS ) || defined ( _DLL ) || defined ( _LIB ) +#include +#define DBGPRINT OutputDebugStringA +#else /* Not User mode */ +#define DBGPRINT DbgPrint +#endif /* User mode */ + + + +static void framesLog(void * pCtx, int nSev, + const char *lpszFormat, ...) +{ + va_list val; + char buffer[1024]; + (void)pCtx; + if ( nSev <= BTAMP_LOG_GATE ) + { + va_start(val, lpszFormat); + _vsnprintf(buffer, 1024, lpszFormat, val); + va_end(val); + DBGPRINT(buffer); + } +} +static void framesDump(void * pCtx, int nSev, v_U8_t *pBuf, int nBuf) +{ + char buffer[35]; + int i, offset; + pCtx; + offset = 0; + if ( nSev > BTAMP_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + _snprintf(buffer, 35, "%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + DBGPRINT(buffer); + } + _snprintf(buffer, 35, "%08x: ", offset); + DBGPRINT(buffer); + for (i = 0; i < nBuf % 8; ++i) + { + _snprintf(buffer, 35, "%02x ", *pBuf); + ++pBuf; + DBGPRINT(buffer); + } + DBGPRINT("\n"); +} + +#elif defined OS_X /* Not WIN32 */ +static void framesLog(void * pCtx, int nSev, + const char *lpszFormat, ...) +{// To fill in when needed using IOLog + +} + +static void framesDump(void * pCtx, int nSev, v_U8_t *pBuf, int nBuf) +{ +} + +#elif defined LINUX + +static void framesLog(void * pCtx, int nSev, + const char *lpszFormat, ...) +{ + va_list marker; + (void)pCtx; + if ( nSev <= BTAMP_LOG_GATE ) + { + va_start( marker, lpszFormat ); + vprintf(lpszFormat, marker); + va_end( marker ); + } +} + +static void framesDump(void * pCtx, int nSev, v_U8_t *pBuf, int nBuf) +{ + char buffer[35]; + int i, offset; + (void)pCtx; + offset = 0; + if ( nSev > BTAMP_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + printf("%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + } + printf("%08x: ", offset); + for (i = 0; i < nBuf % 8; ++i) + { + printf("%02x ", *pBuf); + ++pBuf; + } + printf("\n"); +} + +#endif /* WIN32 */ + +#define FRAMES_LOG0(ctx, sev, fmt) \ + framesLog((ctx), (sev), (fmt)); +#define FRAMES_LOG1(ctx, sev, fmt, p1) \ + framesLog((ctx), (sev), (fmt), (p1)); +#define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \ + framesLog((ctx), (sev), (fmt), (p1), (p2)); +#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \ + framesLog((ctx), (sev), (fmt), (p1), (p2), (p3)); +#define FRAMES_DUMP(ctx, sev, p, n) \ + framesDump((ctx), (sev), (p), (n)); +#ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +#endif + +#endif /* End BTAMP_HAVE_LOG_MACROS */ + +#else // ! BTAMP_ENABLE_LOGGING +# define FRAMES_LOG0(ctx, sev, fmt) +# define FRAMES_LOG1(ctx, sev, fmt, p1) +# define FRAMES_LOG2(ctx, sev, fmt, p1, p2) +# define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) +# define FRAMES_DUMP(ctx, sev, p, n) +# ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +# endif +#endif // BTAMP_ENABLE_LOGGING + +#if defined( BTAMP_ENABLE_DBG_BREAK ) && defined ( WIN32 ) +# define FRAMES_DBG_BREAK() { _asm int 3 } +#else +# define FRAMES_DBG_BREAK() +#endif + +#if ! defined(BTAMP_PARAMETER_CHECK2) +# if defined (BTAMP_HAVE_WIN32_API) + +# define BTAMP_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) do { \ + if (!pSrc || IsBadReadPtr(pSrc, 4)) return BTAMP_BAD_INPUT_BUFFER; \ + if (!pBuf || IsBadWritePtr(pBuf, nBuf)) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (IsBadWritePtr(pnConsumed, 4)) return BTAMP_BAD_OUTPUT_BUFFER; \ + } while (0) + +# else + +# define BTAMP_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) do { \ + if (!pSrc) return BTAMP_BAD_INPUT_BUFFER; \ + if (!pBuf) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return BTAMP_BAD_OUTPUT_BUFFER; \ + if (!pnConsumed) return BTAMP_BAD_OUTPUT_BUFFER; \ + } while (0) +# endif +#endif + +static void framesntohs(void * pCtx, + v_U16_t *pOut, + v_U8_t *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + BTAMP_MEMCPY(pCtx, ( v_U16_t* )pOut, pIn, 2); + } + else + { + *pOut = ( v_U16_t )( *pIn << 8 ) | *( pIn + 1 ); + } +# else + if ( !fMsb ) + { + *pOut = ( v_U16_t )( *pIn | ( *( pIn + 1 ) << 8 ) ); + } + else + { + BTAMP_MEMCPY(pCtx, ( v_U16_t* )pOut, pIn, 2); + } +# endif +} + +static void framesntohl(void * pCtx, + v_U32_t *pOut, + v_U8_t *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + *pOut = * ( v_U32_t* )pIn; + } + else + { + *pOut = ( v_U32_t )( *pIn << 24 ) | + ( *( pIn + 1 ) << 16 ) | + ( *( pIn + 2 ) << 8 ) | + ( *( pIn + 3 ) ); + } +# else + if ( !fMsb ) + { + *pOut = ( v_U32_t )( *( pIn + 3 ) << 24 ) | + ( *( pIn + 2 ) << 16 ) | + ( *( pIn + 1 ) << 8 ) | + ( *( pIn ) ); + } + else + { + *pOut = * ( v_U32_t* )pIn; + } +# endif +} + +static void frameshtons(void * pCtx +, v_U8_t *pOut, + v_U16_t pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 2); + } + else + { + *pOut = ( pIn & 0xff00 ) >> 8; + *( pOut + 1 ) = pIn & 0xff; + } +# else + if ( !fMsb ) + { + *pOut = pIn & 0xff; + *( pOut + 1 ) = ( pIn & 0xff00 ) >> 8; + } + else + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 2); + } +# endif +} + +static void frameshtonl(void * pCtx, + v_U8_t *pOut, + v_U32_t pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( BTAMP_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 4); + } + else + { + *pOut = ( pIn & 0xff000000 ) >> 24; + *( pOut + 1 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 2 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 3 ) = ( pIn & 0x000000ff ); + } +# else + if ( !fMsb ) + { + *( pOut ) = ( pIn & 0x000000ff ); + *( pOut + 1 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 2 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 3 ) = ( pIn & 0xff000000 ) >> 24; + } + else + { + BTAMP_MEMCPY(pCtx, pOut, &pIn, 4); + } +# endif +} + +typedef struct sTLVDefn { + v_U32_t id; + v_U32_t pec; + v_U32_t minSize; + v_U32_t maxSize; + size_t offset; + size_t presenceOffset; + v_U16_t sig; + pfnGeneric_t pfn; + const char * name; + v_U8_t fMandatory; +} tTLVDefn; + +static tTLVDefn* FindTLVDefn( void * pCtx, + v_U8_t *pBuf, + v_U32_t nBuf, + tTLVDefn TLVs[ ] ) +{ + tTLVDefn *pTlv; + v_U32_t sType, sLen; + v_U32_t pec; + v_U16_t id; + + sType = 1; + sLen = 2; + + (void)pCtx; + + if (sType == 2) + framesntohs( pCtx, &id, pBuf, 2 ); + else { + id = *pBuf; + } + + pTlv = &( TLVs[ 0 ] ); + while ( 0xffff != pTlv->id ) + { + if ( id == pTlv->id ) + { + if ( 0 == pTlv->pec ) return pTlv; + + if( nBuf > 5 ) + { + pec = ( ( * ( pBuf + 4 ) ) << 16 ) | + ( ( * ( pBuf + 5 ) ) << 8 ) | + * ( pBuf + 6 ); + if ( pec == pTlv->pec ) + { + return pTlv; + } + } + } + + ++pTlv; + } + + return NULL; +} + +static v_U32_t UnpackTlvCore( void * pCtx, + v_U8_t *pBuf, + v_U32_t nBuf, + tTLVDefn TLVs[ ], + v_U8_t *pFrm, + size_t nFrm ); +static v_U32_t PackTlvCore(void * pCtx, + v_U8_t *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed, + tTLVDefn TLVs[], + v_U32_t *pidx); +static v_U32_t GetPackedSizeTlvCore(void * pCtx, + v_U8_t *pFrm, + v_U32_t *pnNeeded, + tTLVDefn TLVs[]); + +v_U32_t btampUnpackTlvAMP_Assoc_Connected_Channel(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_Connected_Channel *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_AMP_ASSOC_CONN_CH_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + + + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->country, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + if ( ! tlvlen ) + { + pDst->num_triplets = 0U; + return 0U; + } + else + { + /* Maximum of 5 triplets allowed, based on size of triplets definition */ + if (tlvlen / 3 > 5) + { + tlvlen = 15; + } + pDst->num_triplets = (v_U8_t)( tlvlen / 3 ); + + BTAMP_MEMCPY(pCtx, pDst->triplets, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + } + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_Connected_Channel. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_Connected_Channel_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_Connected_Channel*); + +#define SigUnpackTlvAMP_Assoc_Connected_Channel ( 0x0001 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_MAC_Addr(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_MAC_Addr *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_MAC_ADDR_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->mac_addr, pBuf, 6); + pBuf += 6; + tlvlen -= (v_U8_t)6; + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_MAC_Addr. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_MAC_Addr_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_MAC_Addr*); + +#define SigUnpackTlvAMP_Assoc_MAC_Addr ( 0x0002 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Capabilities(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_PAL_Capabilities *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_CAPABILITIES_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohl(pCtx, &pDst->pal_capabilities, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_PAL_Capabilities. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_PAL_Capabilities_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_PAL_Capabilities*); + +#define SigUnpackTlvAMP_Assoc_PAL_Capabilities ( 0x0003 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_PAL_Version(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_PAL_Version *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_VERSION_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->pal_version = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->pal_CompanyID, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->pal_subversion, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvAMP_Assoc_PAL_Version. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_PAL_Version_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_PAL_Version*); + +#define SigUnpackTlvAMP_Assoc_PAL_Version ( 0x0004 ) + + +v_U32_t btampUnpackTlvAMP_Assoc_Preferred_Channel_List(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVAMP_Assoc_Preferred_Channel_List *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_AMP_ASSOC_PREF_CH_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR,"Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + /* Contry String - 3 bytes */ + BTAMP_MEMCPY(pCtx, pDst->country, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + + if ( ! tlvlen ) + { + pDst->num_triplets = 0U; + return status; + } + else + { + /* Maximum of 5 triplets allowed, based on size of triplets definition */ + if (tlvlen > 15) + { + tlvlen = 15; + } + pDst->num_triplets = (v_U8_t)( tlvlen / 3 ); + + BTAMP_MEMCPY(pCtx, pDst->triplets, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + } + return status; +} /* End btampUnpackTlvAMP_Assoc_Preferred_Channel_List. */ + +typedef v_U32_t (*pfnUnpackTlvAMP_Assoc_Preferred_Channel_List_t)(void *, v_U8_t*, v_U16_t, tBtampTLVAMP_Assoc_Preferred_Channel_List*); + +#define SigUnpackTlvAMP_Assoc_Preferred_Channel_List ( 0x0005 ) + + +v_U32_t btampUnpackTlvFlow_Spec(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVFlow_Spec *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_FLOW_SPEC_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->flow_spec_id = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->service_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->max_sdu, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohl(pCtx, &pDst->sdu_inter_arrival, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->access_latency, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->flush_timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + (void)pCtx; + return status; +} /* End btampUnpackTlvFlow_Spec. */ + +typedef v_U32_t (*pfnUnpackTlvFlow_Spec_t)(void *, v_U8_t*, v_U16_t, tBtampTLVFlow_Spec*); + +#define SigUnpackTlvFlow_Spec ( 0x0006 ) + + +v_U32_t btampUnpackTlvHCI_Accept_Logical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Accept_Logical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_ACC_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->tx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + BTAMP_MEMCPY(pCtx, pDst->rx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Accept_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Accept_Logical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Accept_Logical_Link_Cmd*); + +#define SigUnpackTlvHCI_Accept_Logical_Link_Cmd ( 0x0007 ) + + +v_U32_t btampUnpackTlvHCI_Accept_Physical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Accept_Physical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_ACC_PHY_LINK_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_length = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + if (pDst->key_length > 32){ + pDst->present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->key_material, pBuf, ( pDst->key_length ) ); + pBuf += ( pDst->key_length ); + tlvlen -= ( pDst->key_length ); + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Accept_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Accept_Physical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Accept_Physical_Link_Cmd*); + +#define SigUnpackTlvHCI_Accept_Physical_Link_Cmd ( 0x0008 ) + + +v_U32_t btampUnpackTlvHCI_Channel_Selected_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Channel_Selected_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Channel_Selected_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Channel_Selected_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Channel_Selected_Event*); + +#define SigUnpackTlvHCI_Channel_Selected_Event ( 0x0009 ) + + +v_U32_t btampUnpackTlvHCI_Command_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Command_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + pDst->present = 1; + pDst->num_hci_command_packets = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->command_opcode, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + switch (pDst->command_opcode) + { + case 0x0c03: + pDst->cc_event.Reset.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c08: + pDst->cc_event.Flush.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Flush.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x043b: + pDst->cc_event.Logical_Link_Cancel.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Logical_Link_Cancel.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Logical_Link_Cancel.tx_flow_spec_id = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c05: + pDst->cc_event.Set_Event_Mask.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c15: + pDst->cc_event.Read_Connection_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Connection_Accept_TO.connection_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c16: + pDst->cc_event.Write_Connection_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c36: + pDst->cc_event.Read_Link_Supervision_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Link_Supervision_TO.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Link_Supervision_TO.link_supervision_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c37: + pDst->cc_event.Write_Link_Supervision_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Write_Link_Supervision_TO.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c61: + pDst->cc_event.Read_Logical_Link_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Logical_Link_Accept_TO.logical_link_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 0x0c62: + pDst->cc_event.Write_Logical_Link_Accept_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c63: + pDst->cc_event.Set_Event_Mask_Page_2.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 0x0c64: + pDst->cc_event.Read_Location_Data.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Location_Data.loc_domain_aware = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->cc_event.Read_Location_Data.loc_domain, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + pDst->cc_event.Read_Location_Data.loc_options = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3173: + pDst->cc_event.Write_Location_Data.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3174: + pDst->cc_event.Read_Flow_Control_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Flow_Control_Mode.flow_control_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3175: + pDst->cc_event.Write_Flow_Control_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3177: + pDst->cc_event.Read_BE_Flush_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohl(pCtx, &pDst->cc_event.Read_BE_Flush_TO.best_effort_flush_timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + break; + case 3178: + pDst->cc_event.Write_BE_Flush_TO.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 3179: + pDst->cc_event.Set_Short_Range_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 4097: + pDst->cc_event.Read_Local_Version_Info.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Local_Version_Info.HC_HCI_Version = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Local_Version_Info.HC_HCI_Revision, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->cc_event.Read_Local_Version_Info.HC_PAL_Version = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Local_Version_Info.HC_Manufac_Name, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Local_Version_Info.HC_PAL_Sub_Version, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 4098: + pDst->cc_event.Read_Local_Supported_Cmds.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->cc_event.Read_Local_Supported_Cmds.HC_Support_Cmds, pBuf, 64); + pBuf += 64; + tlvlen -= (v_U8_t)64; + break; + case 4101: + pDst->cc_event.Read_Buffer_Size.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Buffer_Size.HC_ACL_Data_Packet_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->cc_event.Read_Buffer_Size.HC_SCO_Packet_Length = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Buffer_Size.HC_Total_Num_ACL_Packets, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Buffer_Size.HC_Total_Num_SCO_Packets, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 4106: + pDst->cc_event.Read_Data_Block_Size.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Data_Block_Size.HC_Max_ACL_Data_Packet_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Data_Block_Size.HC_Data_Block_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Data_Block_Size.HC_Total_Num_Data_Blocks, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 5121: + pDst->cc_event.Read_Failed_Contact_Counter.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Failed_Contact_Counter.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Failed_Contact_Counter.failed_contact_counter, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 5122: + pDst->cc_event.Reset_Failed_Contact_Counter.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Reset_Failed_Contact_Counter.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + break; + case 5123: + pDst->cc_event.Read_Link_Quality.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Link_Quality.log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->cc_event.Read_Link_Quality.link_quality = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 5125: + pDst->cc_event.Read_RSSI.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_RSSI.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_RSSI.rssi = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 5129: + pDst->cc_event.Read_Local_AMP_Info.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Local_AMP_Info.HC_AMP_Status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Total_BW, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Max_Guaranteed_BW, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Min_Latency, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Max_PDU_Size, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + pDst->cc_event.Read_Local_AMP_Info.HC_Controller_Type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_PAL_Capabilities, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_AMP_Assoc_Length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_Max_Flush_Timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + framesntohl(pCtx, &pDst->cc_event.Read_Local_AMP_Info.HC_BE_Flush_Timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + break; + case 5130: + pDst->cc_event.Read_Read_Local_AMP_Assoc.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Read_Local_AMP_Assoc.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + if (pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length > 248){ + // pDst->cc_event.Read_Read_Local_AMP_Assoc.present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->cc_event.Read_Read_Local_AMP_Assoc.AMP_assoc_fragment, pBuf, ( pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ) ); + pBuf += ( pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + tlvlen -= ( pDst->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + break; + case 5131: + pDst->cc_event.Write_Remote_AMP_Assoc.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Write_Remote_AMP_Assoc.phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 6145: + pDst->cc_event.Read_Loopback_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->cc_event.Read_Loopback_Mode.loopback_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + case 6146: + pDst->cc_event.Write_Loopback_Mode.status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + break; + } + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Command_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Command_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Command_Complete_Event*); + +#define SigUnpackTlvHCI_Command_Complete_Event ( 0x000a ) + + +v_U32_t btampUnpackTlvHCI_Command_Status_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Command_Status_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->num_hci_command_packets = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->command_opcode, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Command_Status_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Command_Status_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Command_Status_Event*); + +#define SigUnpackTlvHCI_Command_Status_Event ( 0x000b ) + + +v_U32_t btampUnpackTlvHCI_Create_Logical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Create_Logical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_CREATE_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->tx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + BTAMP_MEMCPY(pCtx, pDst->rx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Create_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Create_Logical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Create_Logical_Link_Cmd*); + +#define SigUnpackTlvHCI_Create_Logical_Link_Cmd ( 0x000c ) + + +v_U32_t btampUnpackTlvHCI_Create_Physical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Create_Physical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_CREATE_PHY_LINK_TLV_MIN_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_length = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->key_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + if (pDst->key_length > 32){ + pDst->present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->key_material, pBuf, ( pDst->key_length ) ); + pBuf += ( pDst->key_length ); + tlvlen -= ( pDst->key_length ); + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Create_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Create_Physical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Create_Physical_Link_Cmd*); + +#define SigUnpackTlvHCI_Create_Physical_Link_Cmd ( 0x000d ) + + +v_U32_t btampUnpackTlvHCI_Data_Buffer_Overflow_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Data_Buffer_Overflow_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->link_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Data_Buffer_Overflow_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Data_Buffer_Overflow_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Data_Buffer_Overflow_Event*); + +#define SigUnpackTlvHCI_Data_Buffer_Overflow_Event ( 0x000e ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_DISC_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Logical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*); + +#define SigUnpackTlvHCI_Disconnect_Logical_Link_Cmd ( 0x000f ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event ( 0x0010 ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_DISC_PHY_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Physical_Link_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*); + +#define SigUnpackTlvHCI_Disconnect_Physical_Link_Cmd ( 0x0011 ) + + +v_U32_t btampUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event ( 0x0012 ) + + +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flow_Spec_Modify_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_FLOW_SPEC_MOD_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->be_aggr_counter = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->tx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + BTAMP_MEMCPY(pCtx, pDst->rx_flow_spec, pBuf, 18); + pBuf += 18; + tlvlen -= (v_U8_t)18; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flow_Spec_Modify_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flow_Spec_Modify_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Cmd*); + +#define SigUnpackTlvHCI_Flow_Spec_Modify_Cmd ( 0x0013 ) + + +v_U32_t btampUnpackTlvHCI_Flow_Spec_Modify_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flow_Spec_Modify_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*); + +#define SigUnpackTlvHCI_Flow_Spec_Modify_Complete_Event ( 0x0014 ) + + +v_U32_t btampUnpackTlvHCI_Flush_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flush_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_FLUSH_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flush_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flush_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flush_Cmd*); + +#define SigUnpackTlvHCI_Flush_Cmd ( 0x0015 ) + + +v_U32_t btampUnpackTlvHCI_Flush_Occurred_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Flush_Occurred_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Flush_Occurred_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Flush_Occurred_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Flush_Occurred_Event*); + +#define SigUnpackTlvHCI_Flush_Occurred_Event ( 0x0016 ) + + +v_U32_t btampUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->bd_addr, pBuf, 6); + pBuf += 6; + tlvlen -= (v_U8_t)6; + BTAMP_MEMCPY(pCtx, pDst->generic_amp_link_key, pBuf, 32); + pBuf += 32; + tlvlen -= (v_U8_t)32; + pDst->key_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*); + +#define SigUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event ( 0x0017 ) + + +v_U32_t btampUnpackTlvHCI_Hardware_Error_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Hardware_Error_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->hardware_code = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Hardware_Error_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Hardware_Error_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Hardware_Error_Event*); + +#define SigUnpackTlvHCI_Hardware_Error_Event ( 0x0018 ) + + +v_U32_t btampUnpackTlvHCI_Logical_Link_Cancel_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Logical_Link_Cancel_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_CANCEL_LOG_LINK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->tx_flow_spec_id = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Logical_Link_Cancel_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Logical_Link_Cancel_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Logical_Link_Cancel_Cmd*); + +#define SigUnpackTlvHCI_Logical_Link_Cancel_Cmd ( 0x0019 ) + + +v_U32_t btampUnpackTlvHCI_Logical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Logical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Logical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Logical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Logical_Link_Complete_Event ( 0x001a ) + + +v_U32_t btampUnpackTlvHCI_Loopback_Command_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Loopback_Command_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->hci_command_packet, pBuf, 64); + pBuf += 64; + tlvlen -= (v_U8_t)64; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Loopback_Command_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Loopback_Command_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Loopback_Command_Event*); + +#define SigUnpackTlvHCI_Loopback_Command_Event ( 0x001b ) + + +v_U32_t btampUnpackTlvHCI_Physical_Link_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Physical_Link_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Physical_Link_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Physical_Link_Complete_Event*); + +#define SigUnpackTlvHCI_Physical_Link_Complete_Event ( 0x001c ) + + +v_U32_t btampUnpackTlvHCI_Physical_Link_Loss_Warning_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Physical_Link_Loss_Warning_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->reason = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Physical_Link_Loss_Warning_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Physical_Link_Loss_Warning_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*); + +#define SigUnpackTlvHCI_Physical_Link_Loss_Warning_Event ( 0x001d ) + + +v_U32_t btampUnpackTlvHCI_Physical_Link_Recovery_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Physical_Link_Recovery_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Physical_Link_Recovery_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Physical_Link_Recovery_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Physical_Link_Recovery_Event*); + +#define SigUnpackTlvHCI_Physical_Link_Recovery_Event ( 0x001e ) + + +v_U32_t btampUnpackTlvHCI_Qos_Violation_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Qos_Violation_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Qos_Violation_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Qos_Violation_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Qos_Violation_Event*); + +#define SigUnpackTlvHCI_Qos_Violation_Event ( 0x001f ) + + +v_U32_t btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_BE_FLUSH_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd ( 0x0020 ) + + +v_U32_t btampUnpackTlvHCI_Read_Buffer_Size_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Buffer_Size_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Buffer_Size_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Buffer_Size_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Buffer_Size_Cmd*); + +#define SigUnpackTlvHCI_Read_Buffer_Size_Cmd ( 0x0021 ) + + +v_U32_t btampUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd ( 0x0022 ) + + +v_U32_t btampUnpackTlvHCI_Read_Data_Block_Size_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Data_Block_Size_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Data_Block_Size_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Data_Block_Size_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Data_Block_Size_Cmd*); + +#define SigUnpackTlvHCI_Read_Data_Block_Size_Cmd ( 0x0023 ) + + +v_U32_t btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_FAILED_CONTACT_CNT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*); + +#define SigUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd ( 0x0024 ) + + +v_U32_t btampUnpackTlvHCI_Read_Flow_Control_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*); + +#define SigUnpackTlvHCI_Read_Flow_Control_Mode_Cmd ( 0x0025 ) + + +v_U32_t btampUnpackTlvHCI_Read_Link_Quality_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Link_Quality_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_LINK_QUALITY_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Link_Quality_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Link_Quality_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Link_Quality_Cmd*); + +#define SigUnpackTlvHCI_Read_Link_Quality_Cmd ( 0x0026 ) + + +v_U32_t btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_LINK_SVISISON_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd ( 0x0027 ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s. tlvlen=%d.", __func__, tlvlen); + +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_READ_LOCAL_AMP_ASSOC_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->length_so_far, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->max_remote_amp_assoc_length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd ( 0x0028 ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_AMP_Information_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_AMP_Information_Cmd ( 0x0029 ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd ( 0x002a ) + + +v_U32_t btampUnpackTlvHCI_Read_Local_Version_Info_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Local_Version_Info_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Local_Version_Info_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Local_Version_Info_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Local_Version_Info_Cmd*); + +#define SigUnpackTlvHCI_Read_Local_Version_Info_Cmd ( 0x002b ) + + +v_U32_t btampUnpackTlvHCI_Read_Location_Data_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Location_Data_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Location_Data_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Location_Data_Cmd*); + +#define SigUnpackTlvHCI_Read_Location_Data_Cmd ( 0x002c ) + + +v_U32_t btampUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd ( 0x002d ) + + +v_U32_t btampUnpackTlvHCI_Read_Loopback_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_Loopback_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_Loopback_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_Loopback_Mode_Cmd*); + +#define SigUnpackTlvHCI_Read_Loopback_Mode_Cmd ( 0x002e ) + + +v_U32_t btampUnpackTlvHCI_Read_RSSI_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Read_RSSI_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_READ_RSSI_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Read_RSSI_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Read_RSSI_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Read_RSSI_Cmd*); + +#define SigUnpackTlvHCI_Read_RSSI_Cmd ( 0x002f ) + + +v_U32_t btampUnpackTlvHCI_Reset_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Reset_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Reset_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Reset_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Reset_Cmd*); + +#define SigUnpackTlvHCI_Reset_Cmd ( 0x0030 ) + + +v_U32_t btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_RESET_FAILED_CONTACT_CNT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*); + +#define SigUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd ( 0x0031 ) + + +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Set_Event_Mask_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_SET_EVENT_MASK_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->event_mask, pBuf, 8); + pBuf += 8; + tlvlen -= (v_U8_t)8; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Set_Event_Mask_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Set_Event_Mask_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Set_Event_Mask_Cmd*); + +#define SigUnpackTlvHCI_Set_Event_Mask_Cmd ( 0x0032 ) + + +v_U32_t btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s. tlvlen=%d.", __func__, tlvlen); +#ifdef WLAN_BAPHCI_ENABLE_VALIDITY_CHECKING + if ( WLAN_BAP_PAL_SET_EVENT_MASK2_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif +// return BTAMP_INVALID_TLV_LENGTH; + } +#endif + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + BTAMP_MEMCPY(pCtx, pDst->event_mask_page_2, pBuf, 8); + pBuf += 8; + tlvlen -= (v_U8_t)8; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*); + +#define SigUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd ( 0x0033 ) + + +v_U32_t btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_SET_SHORT_RANGE_MODE_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->short_range_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Set_Short_Range_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*); + +#define SigUnpackTlvHCI_Set_Short_Range_Mode_Cmd ( 0x0034 ) + + +v_U32_t btampUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + pDst->status = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + pDst->short_range_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*); + +#define SigUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event ( 0x0035 ) + + +v_U32_t btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_BE_FLUSH_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohl(pCtx, &pDst->best_effort_flush_timeout, pBuf, 0); + pBuf += 4; + tlvlen -= (v_U8_t)4; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd ( 0x0036 ) + + +v_U32_t btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_CON_ACC_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->connection_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd ( 0x0037 ) + + +v_U32_t btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_FLOW_CTRL_MODE_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->flow_control_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*); + +#define SigUnpackTlvHCI_Write_Flow_Control_Mode_Cmd ( 0x0038 ) + + +v_U32_t btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LINK_SVISION_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->link_supervision_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd ( 0x0039 ) + + +v_U32_t btampUnpackTlvHCI_Write_Location_Data_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Location_Data_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LOCATION_DATA_CMD_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->loc_domain_aware = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + BTAMP_MEMCPY(pCtx, pDst->loc_domain, pBuf, 3); + pBuf += 3; + tlvlen -= (v_U8_t)3; + pDst->loc_options = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Location_Data_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Location_Data_Cmd*); + +#define SigUnpackTlvHCI_Write_Location_Data_Cmd ( 0x003a ) + + +v_U32_t btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LOG_LINK_ACC_TIMEOUT_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->logical_link_accept_timeout, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*); + +#define SigUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd ( 0x003b ) + + +v_U32_t btampUnpackTlvHCI_Write_Loopback_Mode_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Loopback_Mode_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_LOOOPBACK_MODE_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->loopback_mode = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Loopback_Mode_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Loopback_Mode_Cmd*); + +#define SigUnpackTlvHCI_Write_Loopback_Mode_Cmd ( 0x003c ) + + +v_U32_t btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_WRITE_REMOTE_AMP_ASSOC_MIN_TLV_LEN > tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + pDst->phy_link_handle = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + framesntohs(pCtx, &pDst->length_so_far, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + framesntohs(pCtx, &pDst->amp_assoc_remaining_length, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + if (pDst->amp_assoc_remaining_length > 248){ + pDst->present = 0; + return BTAMP_SKIPPED_BAD_IE; + } + + BTAMP_MEMCPY(pCtx, pDst->amp_assoc_fragment, pBuf, ( pDst->amp_assoc_remaining_length ) ); + pBuf += ( pDst->amp_assoc_remaining_length ); + tlvlen -= ( pDst->amp_assoc_remaining_length ); + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*); + +#define SigUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd ( 0x003d ) + +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Cmd(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Enhanced_Flush_Cmd *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + + /*----------------------------------------------------------------------- + TLV Sanity check + -------------------------------------------------------------------------*/ + if ( WLAN_BAP_PAL_ENHANCED_FLUSH_TLV_LEN != tlvlen ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + /*Log invalid len*/ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid TLV len on %s", __func__); +#endif + return BTAMP_INVALID_TLV_LENGTH; + } + + /*----------------------------------------------------------------------- + Parse TLV + -----------------------------------------------------------------------*/ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + pDst->packet_type = *pBuf; + pBuf += 1; + tlvlen -= (v_U8_t)1; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Enhanced_Flush_Cmd. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Enhanced_Flush_Cmd_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Enhanced_Flush_Cmd*); + +#define SigUnpackTlvHCI_Enhanced_Flush_Cmd ( 0x003e ) + + +v_U32_t btampUnpackTlvHCI_Enhanced_Flush_Complete_Event(void * pCtx, v_U8_t *pBuf, v_U16_t tlvlen, tBtampTLVHCI_Enhanced_Flush_Complete_Event *pDst) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->log_link_handle, pBuf, 0); + pBuf += 2; + tlvlen -= (v_U8_t)2; + (void)pCtx; + return status; +} /* End btampUnpackTlvHCI_Enhanced_Flush_Completed_Event. */ + +typedef v_U32_t (*pfnUnpackTlvHCI_Enhanced_Flush_Complete_Event_t)(void *, v_U8_t*, v_U16_t, tBtampTLVHCI_Enhanced_Flush_Complete_Event*); + +#define SigUnpackTlvHCI_Enhanced_Flush_Complete_Event ( 0x003f ) + + +v_U32_t btampUnpackAMP_ASSOC(void * pCtx, v_U8_t *pBuf, v_U32_t nBuf, tBtampAMP_ASSOC *pFrm) +{ + v_U32_t i; + static tTLVDefn TLVS[ ] = { + {BTAMP_TLV_AMP_ASSOC_MAC_ADDR, 0, 9, 9, offsetof(tBtampAMP_ASSOC, AMP_Assoc_MAC_Addr), offsetof(tBtampTLVAMP_Assoc_MAC_Addr, present), SigUnpackTlvAMP_Assoc_MAC_Addr, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_MAC_Addr, "AMP_Assoc_MAC_Addr", 1, }, + {BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST, 0, 9, 0xFF/*12*/, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Preferred_Channel_List), offsetof(tBtampTLVAMP_Assoc_Preferred_Channel_List, present), SigUnpackTlvAMP_Assoc_Preferred_Channel_List, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_Preferred_Channel_List, "AMP_Assoc_Preferred_Channel_List", 1, }, + {BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL, 0, 9, 0xFF/*12*/, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Connected_Channel), offsetof(tBtampTLVAMP_Assoc_Connected_Channel, present), SigUnpackTlvAMP_Assoc_Connected_Channel, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_Connected_Channel, "AMP_Assoc_Connected_Channel", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES, 0, 7, 7, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Capabilities), offsetof(tBtampTLVAMP_Assoc_PAL_Capabilities, present), SigUnpackTlvAMP_Assoc_PAL_Capabilities, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_PAL_Capabilities, "AMP_Assoc_PAL_Capabilities", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_VERSION, 0, 8, 8, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Version), offsetof(tBtampTLVAMP_Assoc_PAL_Version, present), SigUnpackTlvAMP_Assoc_PAL_Version, (pfnGeneric_t)btampUnpackTlvAMP_Assoc_PAL_Version, "AMP_Assoc_PAL_Version", 1, }, + { 0xffff, 0 }, + }; + + v_U32_t status = 0; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampUnpackAMP_ASSOC. nBuf - %d\n", nBuf); +#endif + + status |= UnpackTlvCore(pCtx,pBuf,nBuf,TLVS,(v_U8_t*)pFrm,sizeof(*pFrm)); + + (void)i; +# ifdef BTAMP_DUMP_FRAMES + if (!BTAMP_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Unpacked the AMP_ASSOC:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_MAC_Addr:\n")); + if (!pFrm->AMP_Assoc_MAC_Addr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_MAC_Addr.mac_addr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Preferred_Channel_List:\n")); + if (!pFrm->AMP_Assoc_Preferred_Channel_List.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Preferred_Channel_List.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Preferred_Channel_List.triplets, 3 * pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Connected_Channel:\n")); + if (!pFrm->AMP_Assoc_Connected_Channel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Connected_Channel.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Connected_Channel.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Connected_Channel.triplets, 3 * pFrm->AMP_Assoc_Connected_Channel.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Capabilities:\n")); + if (!pFrm->AMP_Assoc_PAL_Capabilities.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Capabilities.pal_capabilities, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Version:\n")); + if (!pFrm->AMP_Assoc_PAL_Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_CompanyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_subversion, 2); + } + } +# endif // BTAMP_DUMP_FRAMES + return status; + +} /* End btampUnpackAMP_ASSOC. */ + +static v_U32_t UnpackTlvCore( void * pCtx, + v_U8_t *pBuf, + v_U32_t nBuf, + tTLVDefn TLVs[ ], + v_U8_t *pFrm, + size_t nFrm ) +{ + tTLVDefn *pTlv; + v_U32_t nBufRemaining, status, status2, npec; + v_U32_t sType, sLen; + v_U16_t id, len; + v_U8_t *pBufRemaining, *pfFound; + + (void)pCtx; // Shutup the compiler + (void)nFrm; + status = BTAMP_PARSE_SUCCESS; + status2 = BTAMP_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In UnpackTlvCore, nBufRemaining - %d\n", nBufRemaining); +#endif + + // While we have data... + while ( nBufRemaining ) + { + if ( 3 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL( "This frame reports " + "fewer three byte(s) remaining.\n" ) ); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + npec = 0U; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "Calling FindTLVDefn...\n", nBufRemaining); +#endif + + // Look for a matching TLV definition, + pTlv = FindTLVDefn( pCtx, pBufRemaining, nBufRemaining, TLVs ); + sType = 1; + sLen = 2; + // consume the type, + if (sType == 2) + framesntohs(pCtx, &id, pBufRemaining, 1); + else { + id = *pBufRemaining; + } + pBufRemaining += sType; + nBufRemaining -= sType; + // & length, + framesntohs(pCtx, &len, pBufRemaining, 1); + pBufRemaining += sLen; + nBufRemaining -= sLen; + + if ( pTlv && pTlv->pec ) + { + npec = 3U; + if ( 3 > nBufRemaining ) + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "3 > nBufRemaining\n"); +#endif + + FRAMES_LOG2(pCtx, FRLOGW, FRFL("TLV %d reports length" + "%d, but it has a Private Enterprise Code (3 byte" + "s.\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes" + "of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 3; + nBufRemaining -= 3; + len -= 3; + } +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "Len - %d nBufRemaining - %d\n", len, nBufRemaining); +#endif + + // Whether we found a hit or not, we can validate the reported + // length of this TLV: + if ( len > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("TLV %d reports length %" + "d, but there are only %d bytes remaining in this f" + "rame.\n"), id, len, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL( "We've parsed %d bytes" + " of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + // Now, *if* we found a hit... + if ( pTlv ) + { + if ( nBufRemaining < pTlv->minSize - npec - (sType + sLen)) + { + FRAMES_LOG3( pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but there are only " + "%d bytes remaining in this frame.\n"), + pTlv->name, pTlv->minSize, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + status |= BTAMP_INCOMPLETE_TLV; + FRAMES_DBG_BREAK( ); + goto MandatoryCheck; + } + else if ( len > pTlv->maxSize - npec - (sType + sLen)) + { + FRAMES_LOG1( pCtx, FRLOGW, FRFL("The TLV %s reports " + "an illegally large size; this TLV is presumably" + "corrupt or otherwise invalid & will be skipped " + "ipped.\n"), pTlv->name ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + FRAMES_DBG_BREAK(); + status |= BTAMP_SKIPPED_BAD_TLV; + } + else + { +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "pTlv->sig - %d\n", pTlv->sig); +#endif + + switch (pTlv->sig) + { + case SigUnpackTlvAMP_Assoc_Connected_Channel: + status2 = ( (pfnUnpackTlvAMP_Assoc_Connected_Channel_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_Connected_Channel* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_MAC_Addr: + status2 = ( (pfnUnpackTlvAMP_Assoc_MAC_Addr_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_MAC_Addr* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_PAL_Capabilities: + status2 = ( (pfnUnpackTlvAMP_Assoc_PAL_Capabilities_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_PAL_Capabilities* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_PAL_Version: + status2 = ( (pfnUnpackTlvAMP_Assoc_PAL_Version_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_PAL_Version* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvAMP_Assoc_Preferred_Channel_List: + status2 = ( (pfnUnpackTlvAMP_Assoc_Preferred_Channel_List_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVAMP_Assoc_Preferred_Channel_List* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvFlow_Spec: + status2 = ( (pfnUnpackTlvFlow_Spec_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVFlow_Spec* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Accept_Logical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Accept_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Accept_Logical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Accept_Physical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Accept_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Accept_Physical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Channel_Selected_Event: + status2 = ( (pfnUnpackTlvHCI_Channel_Selected_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Channel_Selected_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Command_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Command_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Command_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Command_Status_Event: + status2 = ( (pfnUnpackTlvHCI_Command_Status_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Command_Status_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Create_Logical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Create_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Create_Logical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Create_Physical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Create_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Create_Physical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Data_Buffer_Overflow_Event: + status2 = ( (pfnUnpackTlvHCI_Data_Buffer_Overflow_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Data_Buffer_Overflow_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Logical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Logical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Physical_Link_Cmd: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Physical_Link_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flow_Spec_Modify_Cmd: + status2 = ( (pfnUnpackTlvHCI_Flow_Spec_Modify_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flow_Spec_Modify_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flow_Spec_Modify_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flow_Spec_Modify_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flush_Cmd: + status2 = ( (pfnUnpackTlvHCI_Flush_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flush_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Flush_Occurred_Event: + status2 = ( (pfnUnpackTlvHCI_Flush_Occurred_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Flush_Occurred_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event: + status2 = ( (pfnUnpackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Hardware_Error_Event: + status2 = ( (pfnUnpackTlvHCI_Hardware_Error_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Hardware_Error_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Logical_Link_Cancel_Cmd: + status2 = ( (pfnUnpackTlvHCI_Logical_Link_Cancel_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Logical_Link_Cancel_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Logical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Logical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Loopback_Command_Event: + status2 = ( (pfnUnpackTlvHCI_Loopback_Command_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Loopback_Command_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Physical_Link_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Physical_Link_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Physical_Link_Loss_Warning_Event: + status2 = ( (pfnUnpackTlvHCI_Physical_Link_Loss_Warning_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Physical_Link_Loss_Warning_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Physical_Link_Recovery_Event: + status2 = ( (pfnUnpackTlvHCI_Physical_Link_Recovery_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Physical_Link_Recovery_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Qos_Violation_Event: + status2 = ( (pfnUnpackTlvHCI_Qos_Violation_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Qos_Violation_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Buffer_Size_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Buffer_Size_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Buffer_Size_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Data_Block_Size_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Data_Block_Size_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Data_Block_Size_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Flow_Control_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Link_Quality_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Link_Quality_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Link_Quality_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_AMP_Information_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_AMP_Information_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_AMP_Information_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Local_Version_Info_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Local_Version_Info_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Local_Version_Info_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Location_Data_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Location_Data_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_Loopback_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_Loopback_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Read_RSSI_Cmd: + status2 = ( (pfnUnpackTlvHCI_Read_RSSI_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Read_RSSI_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Reset_Cmd: + status2 = ( (pfnUnpackTlvHCI_Reset_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Reset_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd: + status2 = ( (pfnUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Set_Event_Mask_Cmd: + status2 = ( (pfnUnpackTlvHCI_Set_Event_Mask_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Set_Event_Mask_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd: + status2 = ( (pfnUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Set_Short_Range_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Set_Short_Range_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Set_Short_Range_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event: + status2 = ( (pfnUnpackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Flow_Control_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Location_Data_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Location_Data_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Loopback_Mode_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Loopback_Mode_Cmd* )(pFrm + pTlv->offset )); + break; + case SigUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd: + status2 = ( (pfnUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(pTlv->pfn) )(pCtx, pBufRemaining, len, ( tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd* )(pFrm + pTlv->offset )); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I" + " don't know about the TLV signature %d-- thi" + "s is most likely a 'framesc' bug.\n"), + pTlv->sig); + FRAMES_DBG_BREAK(); + return BTAMP_INTERNAL_ERROR; + } // End switch on sig. + } // End if on length check. + + status |= status2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "status - %x\n", status); +#endif + } + else + { + FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown TLV %d (" + "length %d)\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - (sType + sLen), len); + status |= BTAMP_UNKNOWN_TLVS; + } + + // Advance to the next TLV + pBufRemaining += len; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "len - %d nBufRemaining - %d\n", len, nBufRemaining); +#endif + + if (len > nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGW, FRFL("This TLV extends past th" + "e buffer as it was defined to us. This could mean " + "a corrupt frame, or just an incorrect length parame" + "ter.\n")); + FRAMES_DBG_BREAK(); + status |= BTAMP_LAST_TLV_TOO_LONG; + goto MandatoryCheck; + } + + nBufRemaining -= len; + + } // End iteration over TLVs. + +MandatoryCheck: + pTlv = &TLVs[0]; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "pTlv->id - %x\n", pTlv->id); +#endif + + while (0xffff != pTlv->id) + { + if (pTlv->fMandatory) + { + pfFound = (v_U8_t*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if (!*pfFound) + { + FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandatory " + "TLV %s wasn't seen.\n"), + pTlv->name); + FRAMES_DBG_BREAK(); + status |= BTAMP_MANDATORY_TLV_MISSING; + } + + } + ++pTlv; + } + + return status; +} /* End UnpacTlvkCore. */ +v_U32_t btampGetPackedTlvAMP_Assoc_Connected_Channel(void * pCtx, tBtampTLVAMP_Assoc_Connected_Channel *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_Connected_Channel\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 3; + if ( pTlv->num_triplets ) + { + *pnNeeded += ( pTlv->num_triplets * 3 ); + } + else break; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_Connected_Channel. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_Connected_Channel_t)(void *, tBtampTLVAMP_Assoc_Connected_Channel*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_Connected_Channel ( 0x003e ) + +v_U32_t btampGetPackedTlvAMP_Assoc_MAC_Addr(void * pCtx, tBtampTLVAMP_Assoc_MAC_Addr *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_MAC_Addr\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 6; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_MAC_Addr. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_MAC_Addr_t)(void *, tBtampTLVAMP_Assoc_MAC_Addr*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_MAC_Addr ( 0x003f ) + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Capabilities(void * pCtx, tBtampTLVAMP_Assoc_PAL_Capabilities *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_PAL_Capabilities\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 4; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_PAL_Capabilities. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_PAL_Capabilities_t)(void *, tBtampTLVAMP_Assoc_PAL_Capabilities*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_PAL_Capabilities ( 0x0040 ) + +v_U32_t btampGetPackedTlvAMP_Assoc_PAL_Version(void * pCtx, tBtampTLVAMP_Assoc_PAL_Version *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_PAL_Version. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_PAL_Version_t)(void *, tBtampTLVAMP_Assoc_PAL_Version*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_PAL_Version ( 0x0041 ) + +v_U32_t btampGetPackedTlvAMP_Assoc_Preferred_Channel_List(void * pCtx, tBtampTLVAMP_Assoc_Preferred_Channel_List *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvAMP_Assoc_Preferred_Channel_List\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 3; + if ( pTlv->num_triplets ) + { + *pnNeeded += ( pTlv->num_triplets * 3 ); + } + else break; + break; + } + return status; +} /* End btampGetPackedTLVAMP_Assoc_Preferred_Channel_List. */ + +typedef v_U32_t (*pfnPackSizeTlvAMP_Assoc_Preferred_Channel_List_t)(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List*, v_U32_t*); +#define SigPackSizeTlvAMP_Assoc_Preferred_Channel_List ( 0x0042 ) + +v_U32_t btampGetPackedTlvFlow_Spec(void * pCtx, tBtampTLVFlow_Spec *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 4; + break; + } + return status; +} /* End btampGetPackedTLVFlow_Spec. */ + +typedef v_U32_t (*pfnPackSizeTlvFlow_Spec_t)(void *, tBtampTLVFlow_Spec*, v_U32_t*); +#define SigPackSizeTlvFlow_Spec ( 0x0043 ) + +v_U32_t btampGetPackedTlvHCI_Accept_Logical_Link_Cmd(void * pCtx, tBtampTLVHCI_Accept_Logical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 18; + *pnNeeded += 18; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Accept_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Accept_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Accept_Logical_Link_Cmd ( 0x0044 ) + +v_U32_t btampGetPackedTlvHCI_Accept_Physical_Link_Cmd(void * pCtx, tBtampTLVHCI_Accept_Physical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += pTlv->key_length; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Accept_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Accept_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Accept_Physical_Link_Cmd ( 0x0045 ) + +v_U32_t btampGetPackedTlvHCI_Channel_Selected_Event(void * pCtx, tBtampTLVHCI_Channel_Selected_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Channel_Selected_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Channel_Selected_Event_t)(void *, tBtampTLVHCI_Channel_Selected_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Channel_Selected_Event ( 0x0046 ) + +v_U32_t btampGetPackedTlvHCI_Command_Complete_Event(void * pCtx, tBtampTLVHCI_Command_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + switch (pTlv->command_opcode) + { + case 3075: + *pnNeeded += 1; + break; + case 3080: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 1083: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 3077: + *pnNeeded += 1; + break; + case 3093: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 3094: + *pnNeeded += 1; + break; + case 3126: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 3127: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 3169: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 3170: + *pnNeeded += 1; + break; + case 3171: + *pnNeeded += 1; + break; + case 3172: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 3; + *pnNeeded += 1; + break; + case 3173: + *pnNeeded += 1; + break; + case 3174: + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 3175: + *pnNeeded += 1; + break; + case 3177: + *pnNeeded += 1; + *pnNeeded += 4; + break; + case 3178: + *pnNeeded += 1; + break; + case 3179: + *pnNeeded += 1; + break; + case 4097: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 4098: + *pnNeeded += 1; + *pnNeeded += 64; + break; + case 4101: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 4106: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 5121: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + case 5122: + *pnNeeded += 1; + *pnNeeded += 2; + break; + case 5123: + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + break; + case 5125: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 5129: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 4; + *pnNeeded += 4; + break; + case 5130: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += pTlv->cc_event.Read_Read_Local_AMP_Assoc.remaining_length; + break; + case 5131: + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6145: + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6146: + *pnNeeded += 1; + break; + } + break; + } + return status; +} /* End btampGetPackedTLVHCI_Command_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Command_Complete_Event_t)(void *, tBtampTLVHCI_Command_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Command_Complete_Event ( 0x0047 ) + +v_U32_t btampGetPackedTlvHCI_Command_Status_Event(void * pCtx, tBtampTLVHCI_Command_Status_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Command_Status_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Command_Status_Event_t)(void *, tBtampTLVHCI_Command_Status_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Command_Status_Event ( 0x0048 ) + +v_U32_t btampGetPackedTlvHCI_Create_Logical_Link_Cmd(void * pCtx, tBtampTLVHCI_Create_Logical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 18; + *pnNeeded += 18; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Create_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Create_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Logical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Create_Logical_Link_Cmd ( 0x0049 ) + +v_U32_t btampGetPackedTlvHCI_Create_Physical_Link_Cmd(void * pCtx, tBtampTLVHCI_Create_Physical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += pTlv->key_length; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Create_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Create_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Physical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Create_Physical_Link_Cmd ( 0x004a ) + +v_U32_t btampGetPackedTlvHCI_Data_Buffer_Overflow_Event(void * pCtx, tBtampTLVHCI_Data_Buffer_Overflow_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Data_Buffer_Overflow_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Data_Buffer_Overflow_Event_t)(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Data_Buffer_Overflow_Event ( 0x004b ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Cmd(void * pCtx, tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Logical_Link_Cmd ( 0x004c ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Logical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event ( 0x004d ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Cmd(void * pCtx, tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Physical_Link_Cmd ( 0x004e ) + +v_U32_t btampGetPackedTlvHCI_Disconnect_Physical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Disconnect_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event ( 0x004f ) + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Cmd(void * pCtx, tBtampTLVHCI_Flow_Spec_Modify_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 18; + *pnNeeded += 18; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flow_Spec_Modify_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flow_Spec_Modify_Cmd_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Flow_Spec_Modify_Cmd ( 0x0050 ) + +v_U32_t btampGetPackedTlvHCI_Flow_Spec_Modify_Complete_Event(void * pCtx, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flow_Spec_Modify_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event ( 0x0051 ) + +v_U32_t btampGetPackedTlvHCI_Flush_Cmd(void * pCtx, tBtampTLVHCI_Flush_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flush_Cmd_t)(void *, tBtampTLVHCI_Flush_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Flush_Cmd ( 0x0052 ) + +v_U32_t btampGetPackedTlvHCI_Flush_Occurred_Event(void * pCtx, tBtampTLVHCI_Flush_Occurred_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Flush_Occurred_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Flush_Occurred_Event_t)(void *, tBtampTLVHCI_Flush_Occurred_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Flush_Occurred_Event ( 0x0053 ) + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Pkts_Event(void * pCtx, tBtampTLVHCI_Num_Completed_Pkts_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +// while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; +#if 0 +// New + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; +// End of New +#endif +// break; + } + return status; +} /* End btampGetPackedTLVHCI_Num_Completed_Pkts_Event. */ + +v_U32_t btampGetPackedTlvHCI_Num_Completed_Data_Blocks_Event(void * pCtx, tBtampTLVHCI_Num_Completed_Data_Blocks_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +// while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 2; +// break; + } + return status; +} /* End btampGetPackedTLVHCI_Num_Completed_Data_Blocks_Event. */ + +//typedef v_U32_t (*pfnPackSizeTlvHCI_Num_Completed_Pkts_Event_t)(void *, tBtampTLVHCI_Command_Status_Event*, v_U32_t*); +//#define SigPackSizeTlvHCI_Num_Completed_Pkts_Event ( 0x0048 ) + +v_U32_t btampGetPackedTlvHCI_Generic_AMP_Link_Key_Notification_Event(void * pCtx, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 6; + *pnNeeded += 32; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Generic_AMP_Link_Key_Notification_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event ( 0x0054 ) + +v_U32_t btampGetPackedTlvHCI_Hardware_Error_Event(void * pCtx, tBtampTLVHCI_Hardware_Error_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Hardware_Error_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Hardware_Error_Event_t)(void *, tBtampTLVHCI_Hardware_Error_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Hardware_Error_Event ( 0x0055 ) + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Cancel_Cmd(void * pCtx, tBtampTLVHCI_Logical_Link_Cancel_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Logical_Link_Cancel_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Logical_Link_Cancel_Cmd_t)(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Logical_Link_Cancel_Cmd ( 0x0056 ) + +v_U32_t btampGetPackedTlvHCI_Logical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Logical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Logical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Logical_Link_Complete_Event ( 0x0057 ) + +v_U32_t btampGetPackedTlvHCI_Loopback_Command_Event(void * pCtx, tBtampTLVHCI_Loopback_Command_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 64; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Loopback_Command_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Loopback_Command_Event_t)(void *, tBtampTLVHCI_Loopback_Command_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Loopback_Command_Event ( 0x0058 ) + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Complete_Event(void * pCtx, tBtampTLVHCI_Physical_Link_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Physical_Link_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Physical_Link_Complete_Event ( 0x0059 ) + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Loss_Warning_Event(void * pCtx, tBtampTLVHCI_Physical_Link_Loss_Warning_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Physical_Link_Loss_Warning_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Physical_Link_Loss_Warning_Event_t)(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Physical_Link_Loss_Warning_Event ( 0x005a ) + +v_U32_t btampGetPackedTlvHCI_Physical_Link_Recovery_Event(void * pCtx, tBtampTLVHCI_Physical_Link_Recovery_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Physical_Link_Recovery_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Physical_Link_Recovery_Event_t)(void *, tBtampTLVHCI_Physical_Link_Recovery_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Physical_Link_Recovery_Event ( 0x005b ) + +v_U32_t btampGetPackedTlvHCI_Qos_Violation_Event(void * pCtx, tBtampTLVHCI_Qos_Violation_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Qos_Violation_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Qos_Violation_Event_t)(void *, tBtampTLVHCI_Qos_Violation_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Qos_Violation_Event ( 0x005c ) + +v_U32_t btampGetPackedTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd ( 0x005d ) + +v_U32_t btampGetPackedTlvHCI_Read_Buffer_Size_Cmd(void * pCtx, tBtampTLVHCI_Read_Buffer_Size_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Buffer_Size_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Buffer_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Buffer_Size_Cmd ( 0x005e ) + +v_U32_t btampGetPackedTlvHCI_Read_Connection_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd ( 0x005f ) + +v_U32_t btampGetPackedTlvHCI_Read_Data_Block_Size_Cmd(void * pCtx, tBtampTLVHCI_Read_Data_Block_Size_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Data_Block_Size_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Data_Block_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Data_Block_Size_Cmd ( 0x0060 ) + +v_U32_t btampGetPackedTlvHCI_Read_Failed_Contact_Counter_Cmd(void * pCtx, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd ( 0x0061 ) + +v_U32_t btampGetPackedTlvHCI_Read_Flow_Control_Mode_Cmd(void * pCtx, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd ( 0x0062 ) + +v_U32_t btampGetPackedTlvHCI_Read_Link_Quality_Cmd(void * pCtx, tBtampTLVHCI_Read_Link_Quality_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Link_Quality_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Link_Quality_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Quality_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Link_Quality_Cmd ( 0x0063 ) + +v_U32_t btampGetPackedTlvHCI_Read_Link_Supervision_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd ( 0x0064 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Assoc_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_AMP_Assoc_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd ( 0x0065 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_AMP_Information_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_AMP_Information_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_AMP_Information_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_AMP_Information_Cmd ( 0x0066 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_Supported_Cmds_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_Supported_Cmds_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd ( 0x0067 ) + +v_U32_t btampGetPackedTlvHCI_Read_Local_Version_Info_Cmd(void * pCtx, tBtampTLVHCI_Read_Local_Version_Info_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Local_Version_Info_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Local_Version_Info_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Local_Version_Info_Cmd ( 0x0068 ) + +v_U32_t btampGetPackedTlvHCI_Read_Location_Data_Cmd(void * pCtx, tBtampTLVHCI_Read_Location_Data_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Read_Location_Data_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Location_Data_Cmd ( 0x0069 ) + +v_U32_t btampGetPackedTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd ( 0x006a ) + +v_U32_t btampGetPackedTlvHCI_Read_Loopback_Mode_Cmd(void * pCtx, tBtampTLVHCI_Read_Loopback_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_Loopback_Mode_Cmd ( 0x006b ) + +v_U32_t btampGetPackedTlvHCI_Read_RSSI_Cmd(void * pCtx, tBtampTLVHCI_Read_RSSI_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Read_RSSI_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Read_RSSI_Cmd_t)(void *, tBtampTLVHCI_Read_RSSI_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Read_RSSI_Cmd ( 0x006c ) + +v_U32_t btampGetPackedTlvHCI_Reset_Cmd(void * pCtx, tBtampTLVHCI_Reset_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + break; + } + return status; +} /* End btampGetPackedTLVHCI_Reset_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Reset_Cmd_t)(void *, tBtampTLVHCI_Reset_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Reset_Cmd ( 0x006d ) + +v_U32_t btampGetPackedTlvHCI_Reset_Failed_Contact_Counter_Cmd(void * pCtx, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Reset_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd ( 0x006e ) + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Cmd(void * pCtx, tBtampTLVHCI_Set_Event_Mask_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 8; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Set_Event_Mask_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Set_Event_Mask_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Set_Event_Mask_Cmd ( 0x006f ) + +v_U32_t btampGetPackedTlvHCI_Set_Event_Mask_Page_2_Cmd(void * pCtx, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 8; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Set_Event_Mask_Page_2_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd ( 0x0070 ) + +v_U32_t btampGetPackedTlvHCI_Set_Short_Range_Mode_Cmd(void * pCtx, tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Set_Short_Range_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Set_Short_Range_Mode_Cmd_t)(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Set_Short_Range_Mode_Cmd ( 0x0071 ) + +v_U32_t btampGetPackedTlvHCI_Short_Range_Mode_Change_Complete_Event(void * pCtx, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Short_Range_Mode_Change_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event ( 0x0072 ) + +v_U32_t btampGetPackedTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 4; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd ( 0x0073 ) + +v_U32_t btampGetPackedTlvHCI_Write_Connection_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd ( 0x0074 ) + +v_U32_t btampGetPackedTlvHCI_Write_Flow_Control_Mode_Cmd(void * pCtx, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd ( 0x0075 ) + +v_U32_t btampGetPackedTlvHCI_Write_Link_Supervision_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd ( 0x0076 ) + +v_U32_t btampGetPackedTlvHCI_Write_Location_Data_Cmd(void * pCtx, tBtampTLVHCI_Write_Location_Data_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 3; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Write_Location_Data_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Location_Data_Cmd ( 0x0077 ) + +v_U32_t btampGetPackedTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void * pCtx, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd ( 0x0078 ) + +v_U32_t btampGetPackedTlvHCI_Write_Loopback_Mode_Cmd(void * pCtx, tBtampTLVHCI_Write_Loopback_Mode_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Loopback_Mode_Cmd ( 0x0079 ) + +v_U32_t btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void * pCtx, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd\n"); +#endif + + while ( pTlv->present ) + { + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += pTlv->amp_assoc_remaining_length; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Write_Remote_AMP_ASSOC_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd ( 0x007a ) + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Cmd(void * pCtx, tBtampTLVHCI_Enhanced_Flush_Cmd *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + *pnNeeded += 1; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Enhanced_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Enhanced_Flush_Cmd_t)(void *, tBtampTLVHCI_Enhanced_Flush_Cmd*, v_U32_t*); +#define SigPackSizeTlvHCI_Enhanced_Flush_Cmd ( 0x007b ) + +v_U32_t btampGetPackedTlvHCI_Enhanced_Flush_Complete_Event(void * pCtx, tBtampTLVHCI_Enhanced_Flush_Complete_Event *pTlv, v_U32_t *pnNeeded) +{ + v_U32_t status = BTAMP_PARSE_SUCCESS; + (void)pCtx; (void)pTlv; (void)pnNeeded; + while ( pTlv->present ) + { + *pnNeeded += 2; + break; + } + return status; +} /* End btampGetPackedTLVHCI_Enhanced_Flush_Complete_Event. */ + +typedef v_U32_t (*pfnPackSizeTlvHCI_Enhanced_Flush_Complete_Event_t)(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event*, v_U32_t*); +#define SigPackSizeTlvHCI_Enhanced_Flush_Complete_Event ( 0x007c ) + +v_U32_t btampGetPackedAMP_ASSOCSize(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U32_t *pnNeeded) +{ + static tTLVDefn TLVS[ ] = { + {BTAMP_TLV_AMP_ASSOC_MAC_ADDR, 0, 9, 9, offsetof(tBtampAMP_ASSOC, AMP_Assoc_MAC_Addr), offsetof(tBtampTLVAMP_Assoc_MAC_Addr, present), SigPackSizeTlvAMP_Assoc_MAC_Addr, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_MAC_Addr, "AMP_Assoc_MAC_Addr", 1, }, + {BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Preferred_Channel_List), offsetof(tBtampTLVAMP_Assoc_Preferred_Channel_List, present), SigPackSizeTlvAMP_Assoc_Preferred_Channel_List, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_Preferred_Channel_List, "AMP_Assoc_Preferred_Channel_List", 1, }, + {BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Connected_Channel), offsetof(tBtampTLVAMP_Assoc_Connected_Channel, present), SigPackSizeTlvAMP_Assoc_Connected_Channel, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_Connected_Channel, "AMP_Assoc_Connected_Channel", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES, 0, 7, 7, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Capabilities), offsetof(tBtampTLVAMP_Assoc_PAL_Capabilities, present), SigPackSizeTlvAMP_Assoc_PAL_Capabilities, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_PAL_Capabilities, "AMP_Assoc_PAL_Capabilities", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_VERSION, 0, 8, 8, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Version), offsetof(tBtampTLVAMP_Assoc_PAL_Version, present), SigPackSizeTlvAMP_Assoc_PAL_Version, (pfnGeneric_t)btampGetPackedTlvAMP_Assoc_PAL_Version, "AMP_Assoc_PAL_Version", 1, }, + { 0xffff, 0 }, + }; + + v_U32_t status = 0; + *pnNeeded = 0; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampGetPackedAMP_ASSOCSize\n"); +#endif + + status |= GetPackedSizeTlvCore(pCtx,(v_U8_t*)pFrm,pnNeeded,TLVS); + return status; +} /* End btampGetPackedAMP_ASSOCSize. */ + +static v_U32_t GetPackedSizeTlvCore(void * pCtx, + v_U8_t *pFrm, + v_U32_t *pnNeeded, + tTLVDefn TLVs[]) +{ + tTLVDefn *pTlv; + v_U32_t status, status2; + tFRAMES_BOOL *pfFound; + + status = BTAMP_PARSE_SUCCESS; + status2 = BTAMP_PARSE_SUCCESS; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In GetPackedSizeTlvCore\n"); +#endif + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound ) + { + *pnNeeded += 4U; + if ( pTlv->pec ) *pnNeeded += 3U; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In GetPackedSizeTlvCore, pTlv->sig - %d\n", pTlv->sig); +#endif + + switch (pTlv->sig) + { + case SigPackSizeTlvAMP_Assoc_Connected_Channel: + status2 = ( (pfnPackSizeTlvAMP_Assoc_Connected_Channel_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Connected_Channel* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_MAC_Addr: + status2 = ( (pfnPackSizeTlvAMP_Assoc_MAC_Addr_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_MAC_Addr* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_PAL_Capabilities: + status2 = ( (pfnPackSizeTlvAMP_Assoc_PAL_Capabilities_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Capabilities* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_PAL_Version: + status2 = ( (pfnPackSizeTlvAMP_Assoc_PAL_Version_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Version* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvAMP_Assoc_Preferred_Channel_List: + status2 = ( (pfnPackSizeTlvAMP_Assoc_Preferred_Channel_List_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Preferred_Channel_List* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvFlow_Spec: + status2 = ( (pfnPackSizeTlvFlow_Spec_t)(pTlv->pfn) )(pCtx, ( tBtampTLVFlow_Spec* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Accept_Logical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Accept_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Logical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Accept_Physical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Accept_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Physical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Channel_Selected_Event: + status2 = ( (pfnPackSizeTlvHCI_Channel_Selected_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Channel_Selected_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Command_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Command_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Command_Status_Event: + status2 = ( (pfnPackSizeTlvHCI_Command_Status_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Status_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Create_Logical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Create_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Logical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Create_Physical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Create_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Physical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Data_Buffer_Overflow_Event: + status2 = ( (pfnPackSizeTlvHCI_Data_Buffer_Overflow_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Data_Buffer_Overflow_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Logical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Physical_Link_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flow_Spec_Modify_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Flow_Spec_Modify_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Flow_Spec_Modify_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flush_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Flush_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Flush_Occurred_Event: + status2 = ( (pfnPackSizeTlvHCI_Flush_Occurred_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Occurred_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event: + status2 = ( (pfnPackSizeTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Hardware_Error_Event: + status2 = ( (pfnPackSizeTlvHCI_Hardware_Error_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Hardware_Error_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Logical_Link_Cancel_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Logical_Link_Cancel_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Cancel_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Logical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Loopback_Command_Event: + status2 = ( (pfnPackSizeTlvHCI_Loopback_Command_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Loopback_Command_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Physical_Link_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Physical_Link_Loss_Warning_Event: + status2 = ( (pfnPackSizeTlvHCI_Physical_Link_Loss_Warning_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Loss_Warning_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Physical_Link_Recovery_Event: + status2 = ( (pfnPackSizeTlvHCI_Physical_Link_Recovery_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Recovery_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Qos_Violation_Event: + status2 = ( (pfnPackSizeTlvHCI_Qos_Violation_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Qos_Violation_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Buffer_Size_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Buffer_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Buffer_Size_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Data_Block_Size_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Data_Block_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Data_Block_Size_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Link_Quality_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Link_Quality_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Quality_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_AMP_Information_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_AMP_Information_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Information_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Local_Version_Info_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Local_Version_Info_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Version_Info_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Location_Data_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Location_Data_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_Loopback_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Loopback_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Read_RSSI_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Read_RSSI_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_RSSI_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Reset_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Reset_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Set_Event_Mask_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Set_Event_Mask_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Set_Short_Range_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Set_Short_Range_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Short_Range_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event: + status2 = ( (pfnPackSizeTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Flow_Control_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Location_Data_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Location_Data_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Loopback_Mode_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Loopback_Mode_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + case SigPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd: + status2 = ( (pfnPackSizeTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd* )(pFrm + pTlv->offset), pnNeeded); + if (status2) status |= status2; + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the TLV signature %d; this is most l" + "ikely a bug in 'framesc'.\n"), pTlv->sig); + return BTAMP_INTERNAL_ERROR; + } + } + ++pTlv; + } + return status; +} +v_U32_t btampPackTlvAMP_Assoc_Connected_Channel(void * pCtx, + tBtampTLVAMP_Assoc_Connected_Channel *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_Connected_Channel\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_Connected_Channel(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3, 0); + else *pBuf = 3; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->country, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + if ( pSrc->num_triplets ) { + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->triplets ), ( pSrc->num_triplets * 3 )); + *pnConsumed += ( pSrc->num_triplets * 3 ); + pBuf += ( ( pSrc->num_triplets * 3 ) ); + nBuf -= ( ( pSrc->num_triplets * 3 ) ); + } + else break; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } + else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_Connected_Channel. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_Connected_Channel_t)(void *, tBtampTLVAMP_Assoc_Connected_Channel *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_Connected_Channel ( 0x007b ) + +v_U32_t btampPackTlvAMP_Assoc_MAC_Addr(void * pCtx, + tBtampTLVAMP_Assoc_MAC_Addr *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_MAC_Addr\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_MAC_Addr(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1, 0); + else *pBuf = 1; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->mac_addr, 6); + *pnConsumed += 6; + pBuf += 6; + nBuf -= 6; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_MAC_Addr. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_MAC_Addr_t)(void *, tBtampTLVAMP_Assoc_MAC_Addr *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_MAC_Addr ( 0x007c ) + +v_U32_t btampPackTlvAMP_Assoc_PAL_Capabilities(void * pCtx, + tBtampTLVAMP_Assoc_PAL_Capabilities *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_PAL_Capabilities\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_PAL_Capabilities(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4, 0); + else *pBuf = 4; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtonl(pCtx, pBuf, pSrc->pal_capabilities, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_PAL_Capabilities. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_PAL_Capabilities_t)(void *, tBtampTLVAMP_Assoc_PAL_Capabilities *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_PAL_Capabilities ( 0x007d ) + +v_U32_t btampPackTlvAMP_Assoc_PAL_Version(void * pCtx, + tBtampTLVAMP_Assoc_PAL_Version *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_PAL_Version\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_PAL_Version(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5, 0); + else *pBuf = 5; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->pal_version; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->pal_CompanyID, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->pal_subversion, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_PAL_Version. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_PAL_Version_t)(void *, tBtampTLVAMP_Assoc_PAL_Version *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_PAL_Version ( 0x007e ) + +v_U32_t btampPackTlvAMP_Assoc_Preferred_Channel_List(void * pCtx, + tBtampTLVAMP_Assoc_Preferred_Channel_List *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 2; +#ifdef WLAN_BAPHCI_ENABLE_LOGGING + VOS_TRACE(VOS_MODULE_ID_BAP,VOS_TRACE_LEVEL_ERROR, + "In btampPackTlvAMP_Assoc_Preferred_Channel_List\n"); +#endif + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvAMP_Assoc_Preferred_Channel_List(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 2, 0); + else *pBuf = 2; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->country, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + if ( pSrc->num_triplets ) { + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->triplets ), ( pSrc->num_triplets * 3 )); + *pnConsumed += ( pSrc->num_triplets * 3 ); + pBuf += ( ( pSrc->num_triplets * 3 ) ); + nBuf -= ( ( pSrc->num_triplets * 3 ) ); + } + else break; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvAMP_Assoc_Preferred_Channel_List. */ + +typedef v_U32_t (*pfnPackTlvAMP_Assoc_Preferred_Channel_List_t)(void *, tBtampTLVAMP_Assoc_Preferred_Channel_List *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvAMP_Assoc_Preferred_Channel_List ( 0x007f ) + +v_U32_t btampPackTlvFlow_Spec(void * pCtx, + tBtampTLVFlow_Spec *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvFlow_Spec(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 6, 0); + else *pBuf = 6; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->service_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->max_sdu, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtonl(pCtx, pBuf, pSrc->sdu_inter_arrival, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->access_latency, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->flush_timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvFlow_Spec. */ + +typedef v_U32_t (*pfnPackTlvFlow_Spec_t)(void *, tBtampTLVFlow_Spec *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvFlow_Spec ( 0x0080 ) + +v_U32_t btampPackTlvHCI_Accept_Logical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Accept_Logical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Accept_Logical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1081, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->tx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->rx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Accept_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Accept_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Logical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Accept_Logical_Link_Cmd ( 0x0081 ) + +v_U32_t btampPackTlvHCI_Accept_Physical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Accept_Physical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Accept_Physical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1078, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_length; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->key_material ), pSrc->key_length); + *pnConsumed += pSrc->key_length; + pBuf += ( pSrc->key_length ); + nBuf -= ( pSrc->key_length ); + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Accept_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Accept_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Accept_Physical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Accept_Physical_Link_Cmd ( 0x0082 ) + +v_U32_t btampPackTlvHCI_Channel_Selected_Event(void * pCtx, + tBtampTLVHCI_Channel_Selected_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Channel_Selected_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 65, 0); + else *pBuf = 65; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Channel_Selected_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Channel_Selected_Event_t)(void *, tBtampTLVHCI_Channel_Selected_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Channel_Selected_Event ( 0x0083 ) + +v_U32_t btampPackTlvHCI_Command_Complete_Event(void * pCtx, + tBtampTLVHCI_Command_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Command_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 14, 0); + else *pBuf = 14; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->num_hci_command_packets; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->command_opcode, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + switch (pSrc->command_opcode) + { + case 3075: + *pBuf = pSrc->cc_event.Reset.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3080: + *pBuf = pSrc->cc_event.Flush.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Flush.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 1083: + *pBuf = pSrc->cc_event.Logical_Link_Cancel.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Logical_Link_Cancel.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Logical_Link_Cancel.tx_flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3077: + *pBuf = pSrc->cc_event.Set_Event_Mask.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3093: + *pBuf = pSrc->cc_event.Read_Connection_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Connection_Accept_TO.connection_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3094: + *pBuf = pSrc->cc_event.Write_Connection_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3126: + *pBuf = pSrc->cc_event.Read_Link_Supervision_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Link_Supervision_TO.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Link_Supervision_TO.link_supervision_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3127: + *pBuf = pSrc->cc_event.Write_Link_Supervision_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Write_Link_Supervision_TO.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3169: + *pBuf = pSrc->cc_event.Read_Logical_Link_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Logical_Link_Accept_TO.logical_link_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 3170: + *pBuf = pSrc->cc_event.Write_Logical_Link_Accept_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3171: + *pBuf = pSrc->cc_event.Set_Event_Mask_Page_2.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3172: + *pBuf = pSrc->cc_event.Read_Location_Data.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Location_Data.loc_domain_aware; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->cc_event.Read_Location_Data.loc_domain, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + *pBuf = pSrc->cc_event.Read_Location_Data.loc_options; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3173: + *pBuf = pSrc->cc_event.Write_Location_Data.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3174: + *pBuf = pSrc->cc_event.Read_Flow_Control_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Flow_Control_Mode.flow_control_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3175: + *pBuf = pSrc->cc_event.Write_Flow_Control_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3177: + *pBuf = pSrc->cc_event.Read_BE_Flush_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_BE_Flush_TO.best_effort_flush_timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + case 3178: + *pBuf = pSrc->cc_event.Write_BE_Flush_TO.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 3179: + *pBuf = pSrc->cc_event.Set_Short_Range_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 4097: + *pBuf = pSrc->cc_event.Read_Local_Version_Info.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Local_Version_Info.HC_HCI_Version; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_Version_Info.HC_HCI_Revision, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->cc_event.Read_Local_Version_Info.HC_PAL_Version; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_Version_Info.HC_Manufac_Name, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_Version_Info.HC_PAL_Sub_Version, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 4098: + *pBuf = pSrc->cc_event.Read_Local_Supported_Cmds.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->cc_event.Read_Local_Supported_Cmds.HC_Support_Cmds, 64); + *pnConsumed += 64; + pBuf += 64; + nBuf -= 64; + break; + case 4101: + *pBuf = pSrc->cc_event.Read_Buffer_Size.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Buffer_Size.HC_ACL_Data_Packet_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->cc_event.Read_Buffer_Size.HC_SCO_Packet_Length; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Buffer_Size.HC_Total_Num_ACL_Packets, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Buffer_Size.HC_Total_Num_SCO_Packets, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 4106: + *pBuf = pSrc->cc_event.Read_Data_Block_Size.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Data_Block_Size.HC_Max_ACL_Data_Packet_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Data_Block_Size.HC_Data_Block_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Data_Block_Size.HC_Total_Num_Data_Blocks, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 5121: + *pBuf = pSrc->cc_event.Read_Failed_Contact_Counter.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Failed_Contact_Counter.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Failed_Contact_Counter.failed_contact_counter, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 5122: + *pBuf = pSrc->cc_event.Reset_Failed_Contact_Counter.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Reset_Failed_Contact_Counter.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + case 5123: + *pBuf = pSrc->cc_event.Read_Link_Quality.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Link_Quality.log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->cc_event.Read_Link_Quality.link_quality; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 5125: + *pBuf = pSrc->cc_event.Read_RSSI.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_RSSI.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_RSSI.rssi; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 5129: + *pBuf = pSrc->cc_event.Read_Local_AMP_Info.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Local_AMP_Info.HC_AMP_Status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Total_BW, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Max_Guaranteed_BW, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Min_Latency, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Max_PDU_Size, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + *pBuf = pSrc->cc_event.Read_Local_AMP_Info.HC_Controller_Type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_PAL_Capabilities, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_AMP_Assoc_Length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_Max_Flush_Timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + frameshtonl(pCtx, pBuf, pSrc->cc_event.Read_Local_AMP_Info.HC_BE_Flush_Timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + case 5130: + *pBuf = pSrc->cc_event.Read_Read_Local_AMP_Assoc.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Read_Local_AMP_Assoc.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->cc_event.Read_Read_Local_AMP_Assoc.AMP_assoc_fragment ), pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length); + *pnConsumed += pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length; + pBuf += ( pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + nBuf -= ( pSrc->cc_event.Read_Read_Local_AMP_Assoc.remaining_length ); + break; + case 5131: + *pBuf = pSrc->cc_event.Write_Remote_AMP_Assoc.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Write_Remote_AMP_Assoc.phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 6145: + *pBuf = pSrc->cc_event.Read_Loopback_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->cc_event.Read_Loopback_Mode.loopback_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + case 6146: + *pBuf = pSrc->cc_event.Write_Loopback_Mode.status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Command_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Command_Complete_Event_t)(void *, tBtampTLVHCI_Command_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Command_Complete_Event ( 0x0084 ) + +v_U32_t btampPackTlvHCI_Command_Status_Event(void * pCtx, + tBtampTLVHCI_Command_Status_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Command_Status_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 15, 0); + else *pBuf = 15; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->num_hci_command_packets; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->command_opcode, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Command_Status_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Command_Status_Event_t)(void *, tBtampTLVHCI_Command_Status_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Command_Status_Event ( 0x0085 ) + +v_U32_t btampPackTlvHCI_Create_Logical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Create_Logical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + + nConsumedOnEntry = *pnConsumed; + status = btampGetPackedTlvHCI_Create_Logical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1080, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->tx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->rx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Create_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Create_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Logical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Create_Logical_Link_Cmd ( 0x0086 ) + +v_U32_t btampPackTlvHCI_Create_Physical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Create_Physical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Create_Physical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1077, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_length; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->key_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->key_material ), pSrc->key_length); + *pnConsumed += pSrc->key_length; + pBuf += ( pSrc->key_length ); + nBuf -= ( pSrc->key_length ); + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Create_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Create_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Create_Physical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Create_Physical_Link_Cmd ( 0x0087 ) + +v_U32_t btampPackTlvHCI_Data_Buffer_Overflow_Event(void * pCtx, + tBtampTLVHCI_Data_Buffer_Overflow_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Data_Buffer_Overflow_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 26, 0); + else *pBuf = 26; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->link_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Data_Buffer_Overflow_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Data_Buffer_Overflow_Event_t)(void *, tBtampTLVHCI_Data_Buffer_Overflow_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Data_Buffer_Overflow_Event ( 0x0088 ) + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Disconnect_Logical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Logical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1082, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Logical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Logical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Logical_Link_Cmd ( 0x0089 ) + +v_U32_t btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Logical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 70, 0); + else *pBuf = 70; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Logical_Link_Complete_Event ( 0x008a ) + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Cmd(void * pCtx, + tBtampTLVHCI_Disconnect_Physical_Link_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Physical_Link_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1079, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Physical_Link_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Physical_Link_Cmd_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Physical_Link_Cmd ( 0x008b ) + +v_U32_t btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Disconnect_Physical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 66, 0); + else *pBuf = 66; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Disconnect_Physical_Link_Complete_Event ( 0x008c ) + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Cmd(void * pCtx, + tBtampTLVHCI_Flow_Spec_Modify_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flow_Spec_Modify_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1084, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->be_aggr_counter; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->tx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->rx_flow_spec, 18); + *pnConsumed += 18; + pBuf += 18; + nBuf -= 18; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flow_Spec_Modify_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flow_Spec_Modify_Cmd_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flow_Spec_Modify_Cmd ( 0x008d ) + +v_U32_t btampPackTlvHCI_Flow_Spec_Modify_Complete_Event(void * pCtx, + tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flow_Spec_Modify_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 71, 0); + else *pBuf = 71; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flow_Spec_Modify_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(void *, tBtampTLVHCI_Flow_Spec_Modify_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flow_Spec_Modify_Complete_Event ( 0x008e ) + +v_U32_t btampPackTlvHCI_Flush_Cmd(void * pCtx, + tBtampTLVHCI_Flush_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flush_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3080, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flush_Cmd_t)(void *, tBtampTLVHCI_Flush_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flush_Cmd ( 0x008f ) + +v_U32_t btampPackTlvHCI_Flush_Occurred_Event(void * pCtx, + tBtampTLVHCI_Flush_Occurred_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Flush_Occurred_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 17, 0); + else *pBuf = 17; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Flush_Occurred_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Flush_Occurred_Event_t)(void *, tBtampTLVHCI_Flush_Occurred_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Flush_Occurred_Event ( 0x0090 ) + +v_U32_t btampPackTlvHCI_Num_Completed_Pkts_Event(void * pCtx, + tBtampTLVHCI_Num_Completed_Pkts_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Num_Completed_Pkts_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; +// while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 19, 0); + else *pBuf = 19; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->num_handles; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->conn_handles[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->num_completed_pkts[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +#if 0 + // New + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +// End of new +#endif +// break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Num_Completed_Pkts_Event. */ + +v_U32_t btampPackTlvHCI_Num_Completed_Data_Blocks_Event(void * pCtx, + tBtampTLVHCI_Num_Completed_Data_Blocks_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Num_Completed_Data_Blocks_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; +// while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 72, 0); + else *pBuf = 72; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->total_num_data_blocks, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->num_handles; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->conn_handles[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->num_completed_pkts[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->num_completed_blocks[0], 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +#if 0 + // New + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, 0, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; +// End of new +#endif +// break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Num_Completed_Data_Blocks_Event. */ + +//typedef v_U32_t (*pfnPackTlvHCI_Num_Completed_Pkts_Event_t)(void *, tBtampTLVHCI_Num_Completed_Pkts_Event *, v_U8_t*, v_U32_t, v_U32_t*); +//#define SigPackTlvHCI_Num_Completed_Pkts_Event ( 0x0085 ) + +v_U32_t btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event(void * pCtx, + tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Generic_AMP_Link_Key_Notification_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 62, 0); + else *pBuf = 62; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->bd_addr, 6); + *pnConsumed += 6; + pBuf += 6; + nBuf -= 6; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->generic_amp_link_key, 32); + *pnConsumed += 32; + pBuf += 32; + nBuf -= 32; + *pBuf = pSrc->key_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(void *, tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Generic_AMP_Link_Key_Notification_Event ( 0x0091 ) + +v_U32_t btampPackTlvHCI_Hardware_Error_Event(void * pCtx, + tBtampTLVHCI_Hardware_Error_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Hardware_Error_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 16, 0); + else *pBuf = 16; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->hardware_code; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Hardware_Error_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Hardware_Error_Event_t)(void *, tBtampTLVHCI_Hardware_Error_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Hardware_Error_Event ( 0x0092 ) + +v_U32_t btampPackTlvHCI_Logical_Link_Cancel_Cmd(void * pCtx, + tBtampTLVHCI_Logical_Link_Cancel_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Logical_Link_Cancel_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 1083, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->tx_flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Logical_Link_Cancel_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Logical_Link_Cancel_Cmd_t)(void *, tBtampTLVHCI_Logical_Link_Cancel_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Logical_Link_Cancel_Cmd ( 0x0093 ) + +v_U32_t btampPackTlvHCI_Logical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Logical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Logical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 69, 0); + else *pBuf = 69; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->flow_spec_id; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Logical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Logical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Logical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Logical_Link_Complete_Event ( 0x0094 ) + +v_U32_t btampPackTlvHCI_Loopback_Command_Event(void * pCtx, + tBtampTLVHCI_Loopback_Command_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Loopback_Command_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 25, 0); + else *pBuf = 25; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->hci_command_packet, 64); + *pnConsumed += 64; + pBuf += 64; + nBuf -= 64; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Loopback_Command_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Loopback_Command_Event_t)(void *, tBtampTLVHCI_Loopback_Command_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Loopback_Command_Event ( 0x0095 ) + +v_U32_t btampPackTlvHCI_Physical_Link_Complete_Event(void * pCtx, + tBtampTLVHCI_Physical_Link_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Physical_Link_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 64, 0); + else *pBuf = 64; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Physical_Link_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Physical_Link_Complete_Event_t)(void *, tBtampTLVHCI_Physical_Link_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Physical_Link_Complete_Event ( 0x0096 ) + +v_U32_t btampPackTlvHCI_Physical_Link_Loss_Warning_Event(void * pCtx, + tBtampTLVHCI_Physical_Link_Loss_Warning_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Physical_Link_Loss_Warning_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 67, 0); + else *pBuf = 67; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->reason; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Physical_Link_Loss_Warning_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Physical_Link_Loss_Warning_Event_t)(void *, tBtampTLVHCI_Physical_Link_Loss_Warning_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Physical_Link_Loss_Warning_Event ( 0x0097 ) + +v_U32_t btampPackTlvHCI_Physical_Link_Recovery_Event(void * pCtx, + tBtampTLVHCI_Physical_Link_Recovery_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Physical_Link_Recovery_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 68, 0); + else *pBuf = 68; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Physical_Link_Recovery_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Physical_Link_Recovery_Event_t)(void *, tBtampTLVHCI_Physical_Link_Recovery_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Physical_Link_Recovery_Event ( 0x0098 ) + +v_U32_t btampPackTlvHCI_Qos_Violation_Event(void * pCtx, + tBtampTLVHCI_Qos_Violation_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Qos_Violation_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 30, 0); + else *pBuf = 30; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Qos_Violation_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Qos_Violation_Event_t)(void *, tBtampTLVHCI_Qos_Violation_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Qos_Violation_Event ( 0x0099 ) + +v_U32_t btampPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3177, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd ( 0x009a ) + +v_U32_t btampPackTlvHCI_Read_Buffer_Size_Cmd(void * pCtx, + tBtampTLVHCI_Read_Buffer_Size_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Buffer_Size_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4101, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Buffer_Size_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Buffer_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Buffer_Size_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Buffer_Size_Cmd ( 0x009b ) + +v_U32_t btampPackTlvHCI_Read_Connection_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Connection_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3093, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Connection_Accept_Timeout_Cmd ( 0x009c ) + +v_U32_t btampPackTlvHCI_Read_Data_Block_Size_Cmd(void * pCtx, + tBtampTLVHCI_Read_Data_Block_Size_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Data_Block_Size_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4106, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Data_Block_Size_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Data_Block_Size_Cmd_t)(void *, tBtampTLVHCI_Read_Data_Block_Size_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Data_Block_Size_Cmd ( 0x009d ) + +v_U32_t btampPackTlvHCI_Read_Failed_Contact_Counter_Cmd(void * pCtx, + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Failed_Contact_Counter_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5121, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Failed_Contact_Counter_Cmd ( 0x009e ) + +v_U32_t btampPackTlvHCI_Read_Flow_Control_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Flow_Control_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3174, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Flow_Control_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Flow_Control_Mode_Cmd ( 0x009f ) + +v_U32_t btampPackTlvHCI_Read_Link_Quality_Cmd(void * pCtx, + tBtampTLVHCI_Read_Link_Quality_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Link_Quality_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5123, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Link_Quality_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Link_Quality_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Quality_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Link_Quality_Cmd ( 0x00a0 ) + +v_U32_t btampPackTlvHCI_Read_Link_Supervision_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Link_Supervision_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3126, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Link_Supervision_Timeout_Cmd ( 0x00a1 ) + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Assoc_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_AMP_Assoc_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5130, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->length_so_far, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->max_remote_amp_assoc_length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_AMP_Assoc_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_AMP_Assoc_Cmd ( 0x00a2 ) + +v_U32_t btampPackTlvHCI_Read_Local_AMP_Information_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_AMP_Information_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_AMP_Information_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5129, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_AMP_Information_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_AMP_Information_Cmd_t)(void *, tBtampTLVHCI_Read_Local_AMP_Information_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_AMP_Information_Cmd ( 0x00a3 ) + +v_U32_t btampPackTlvHCI_Read_Local_Supported_Cmds_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_Supported_Cmds_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4098, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_Supported_Cmds_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_Supported_Cmds_Cmd ( 0x00a4 ) + +v_U32_t btampPackTlvHCI_Read_Local_Version_Info_Cmd(void * pCtx, + tBtampTLVHCI_Read_Local_Version_Info_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Local_Version_Info_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 4097, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Local_Version_Info_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Local_Version_Info_Cmd_t)(void *, tBtampTLVHCI_Read_Local_Version_Info_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Local_Version_Info_Cmd ( 0x00a5 ) + +v_U32_t btampPackTlvHCI_Read_Location_Data_Cmd(void * pCtx, + tBtampTLVHCI_Read_Location_Data_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Location_Data_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3172, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Read_Location_Data_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Location_Data_Cmd ( 0x00a6 ) + +v_U32_t btampPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3169, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd ( 0x00a7 ) + +v_U32_t btampPackTlvHCI_Read_Loopback_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Read_Loopback_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_Loopback_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 6145, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Read_Loopback_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_Loopback_Mode_Cmd ( 0x00a8 ) + +v_U32_t btampPackTlvHCI_Read_RSSI_Cmd(void * pCtx, + tBtampTLVHCI_Read_RSSI_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Read_RSSI_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5125, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Read_RSSI_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Read_RSSI_Cmd_t)(void *, tBtampTLVHCI_Read_RSSI_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Read_RSSI_Cmd ( 0x00a9 ) + +v_U32_t btampPackTlvHCI_Reset_Cmd(void * pCtx, + tBtampTLVHCI_Reset_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Reset_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3075, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Reset_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Reset_Cmd_t)(void *, tBtampTLVHCI_Reset_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Reset_Cmd ( 0x00aa ) + +v_U32_t btampPackTlvHCI_Reset_Failed_Contact_Counter_Cmd(void * pCtx, + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Reset_Failed_Contact_Counter_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5122, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Reset_Failed_Contact_Counter_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(void *, tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Reset_Failed_Contact_Counter_Cmd ( 0x00ab ) + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Cmd(void * pCtx, + tBtampTLVHCI_Set_Event_Mask_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Set_Event_Mask_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3077, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->event_mask, 8); + *pnConsumed += 8; + pBuf += 8; + nBuf -= 8; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Set_Event_Mask_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Set_Event_Mask_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Set_Event_Mask_Cmd ( 0x00ac ) + +v_U32_t btampPackTlvHCI_Set_Event_Mask_Page_2_Cmd(void * pCtx, + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Set_Event_Mask_Page_2_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3171, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->event_mask_page_2, 8); + *pnConsumed += 8; + pBuf += 8; + nBuf -= 8; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Set_Event_Mask_Page_2_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(void *, tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Set_Event_Mask_Page_2_Cmd ( 0x00ad ) + +v_U32_t btampPackTlvHCI_Set_Short_Range_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Set_Short_Range_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Set_Short_Range_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3179, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->short_range_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Set_Short_Range_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Set_Short_Range_Mode_Cmd_t)(void *, tBtampTLVHCI_Set_Short_Range_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Set_Short_Range_Mode_Cmd ( 0x00ae ) + +v_U32_t btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event(void * pCtx, + tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Short_Range_Mode_Change_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 76, 0); + else *pBuf = 76; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + *pBuf = pSrc->short_range_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(void *, tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Short_Range_Mode_Change_Complete_Event ( 0x00af ) + +v_U32_t btampPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3178, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtonl(pCtx, pBuf, pSrc->best_effort_flush_timeout, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd ( 0x00b0 ) + +v_U32_t btampPackTlvHCI_Write_Connection_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Connection_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3094, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->connection_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Connection_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Connection_Accept_Timeout_Cmd ( 0x00b1 ) + +v_U32_t btampPackTlvHCI_Write_Flow_Control_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Flow_Control_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3175, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->flow_control_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Flow_Control_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Flow_Control_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Flow_Control_Mode_Cmd ( 0x00b2 ) + +v_U32_t btampPackTlvHCI_Write_Link_Supervision_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Link_Supervision_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3127, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->link_supervision_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Link_Supervision_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Link_Supervision_Timeout_Cmd ( 0x00b3 ) + +v_U32_t btampPackTlvHCI_Write_Location_Data_Cmd(void * pCtx, + tBtampTLVHCI_Write_Location_Data_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Location_Data_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3173, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->loc_domain_aware; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + BTAMP_MEMCPY(pCtx, pBuf, pSrc->loc_domain, 3); + *pnConsumed += 3; + pBuf += 3; + nBuf -= 3; + *pBuf = pSrc->loc_options; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Location_Data_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Location_Data_Cmd_t)(void *, tBtampTLVHCI_Write_Location_Data_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Location_Data_Cmd ( 0x00b4 ) + +v_U32_t btampPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(void * pCtx, + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3170, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->logical_link_accept_timeout, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(void *, tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd ( 0x00b5 ) + +v_U32_t btampPackTlvHCI_Write_Loopback_Mode_Cmd(void * pCtx, + tBtampTLVHCI_Write_Loopback_Mode_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Loopback_Mode_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 6146, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->loopback_mode; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Loopback_Mode_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Loopback_Mode_Cmd_t)(void *, tBtampTLVHCI_Write_Loopback_Mode_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Loopback_Mode_Cmd ( 0x00b6 ) + +v_U32_t btampPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd(void * pCtx, + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Write_Remote_AMP_ASSOC_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 5131, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + *pBuf = pSrc->phy_link_handle; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + frameshtons(pCtx, pBuf, pSrc->length_so_far, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + frameshtons(pCtx, pBuf, pSrc->amp_assoc_remaining_length, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + BTAMP_MEMCPY(pCtx, pBuf, &( pSrc->amp_assoc_fragment ), pSrc->amp_assoc_remaining_length); + *pnConsumed += pSrc->amp_assoc_remaining_length; + pBuf += ( pSrc->amp_assoc_remaining_length ); + nBuf -= ( pSrc->amp_assoc_remaining_length ); + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(void *, tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd ( 0x00b7 ) + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Cmd(void * pCtx, + tBtampTLVHCI_Enhanced_Flush_Cmd *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 2; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Enhanced_Flush_Cmd(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 3167, 0); + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + *pBuf = pSrc->packet_type; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Enhanced_Flush_Cmd. */ + +typedef v_U32_t (*pfnPackTlvHCI_Enhanced_Flush_Cmd_t)(void *, tBtampTLVHCI_Enhanced_Flush_Cmd *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Enhanced_Flush_Cmd ( 0x00b8 ) + +v_U32_t btampPackTlvHCI_Enhanced_Flush_Complete_Event(void * pCtx, + tBtampTLVHCI_Enhanced_Flush_Complete_Event *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed) +{ + v_U8_t* pTlvLen = 0; + v_U32_t nConsumedOnEntry; + v_U32_t status = BTAMP_PARSE_SUCCESS; + v_U32_t nNeeded = 0U; + v_U32_t sType = 0U; + v_U32_t sLen = 0U; + sType = 1; + sLen = 1; + // sanity checking + if( pCtx == NULL || pSrc == NULL || + pBuf == NULL || pnConsumed == NULL) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "bad input" ); + return BTAMP_BAD_INPUT_BUFFER; + } + nConsumedOnEntry = *pnConsumed; + + status = btampGetPackedTlvHCI_Enhanced_Flush_Complete_Event(pCtx, pSrc, &nNeeded); + if ( ! BTAMP_SUCCEEDED( status ) ) return status; + nNeeded += sType + sLen; + if ( nNeeded > nBuf ) return BTAMP_BUFFER_OVERFLOW; + pTlvLen = pBuf; + while ( pSrc->present ) + { + if( sType == 2) frameshtons( pCtx, pBuf, 57, 0); + else *pBuf = 57; + pBuf += sType; nBuf -= sType; *pnConsumed += sType; + pTlvLen = pBuf; + pBuf += sLen; nBuf -= sLen; *pnConsumed += sLen; + frameshtons(pCtx, pBuf, pSrc->log_link_handle, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2; + break; + } + + if (pTlvLen && sLen == 2) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - sType - sLen, 0); + } else if(NULL != pTlvLen) + { + *pTlvLen = (v_U8_t)(*pnConsumed - nConsumedOnEntry - sType - sLen); + } + return status; +} /* End btampPackTlvHCI_Enhanced_Flush_Complete_Event. */ + +typedef v_U32_t (*pfnPackTlvHCI_Enhanced_Flush_Complete_Event_t)(void *, tBtampTLVHCI_Enhanced_Flush_Complete_Event *, v_U8_t*, v_U32_t, v_U32_t*); +#define SigPackTlvHCI_Enhanced_Flush_Complete_Event ( 0x00b9 ) + +v_U32_t btampPackAMP_ASSOC(void * pCtx, tBtampAMP_ASSOC *pFrm, v_U8_t *pBuf, v_U32_t nBuf, v_U32_t *pnConsumed) +{ + v_U32_t i; + static tTLVDefn TLVS[ ] = { + {BTAMP_TLV_AMP_ASSOC_MAC_ADDR, 0, 9, 9, offsetof(tBtampAMP_ASSOC, AMP_Assoc_MAC_Addr), offsetof(tBtampTLVAMP_Assoc_MAC_Addr, present), SigPackTlvAMP_Assoc_MAC_Addr, (pfnGeneric_t)btampPackTlvAMP_Assoc_MAC_Addr, "AMP_Assoc_MAC_Addr", 1, }, + {BTAMP_TLV_AMP_ASSOC_PREFERRED_CHANNEL_LIST, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Preferred_Channel_List), offsetof(tBtampTLVAMP_Assoc_Preferred_Channel_List, present), SigPackTlvAMP_Assoc_Preferred_Channel_List, (pfnGeneric_t)btampPackTlvAMP_Assoc_Preferred_Channel_List, "AMP_Assoc_Preferred_Channel_List", 1, }, + {BTAMP_TLV_AMP_ASSOC_CONNECTED_CHANNEL, 0, 9, 12, offsetof(tBtampAMP_ASSOC, AMP_Assoc_Connected_Channel), offsetof(tBtampTLVAMP_Assoc_Connected_Channel, present), SigPackTlvAMP_Assoc_Connected_Channel, (pfnGeneric_t)btampPackTlvAMP_Assoc_Connected_Channel, "AMP_Assoc_Connected_Channel", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_CAPABILITIES, 0, 7, 7, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Capabilities), offsetof(tBtampTLVAMP_Assoc_PAL_Capabilities, present), SigPackTlvAMP_Assoc_PAL_Capabilities, (pfnGeneric_t)btampPackTlvAMP_Assoc_PAL_Capabilities, "AMP_Assoc_PAL_Capabilities", 0, }, + {BTAMP_TLV_AMP_ASSOC_PAL_VERSION, 0, 8, 8, offsetof(tBtampAMP_ASSOC, AMP_Assoc_PAL_Version), offsetof(tBtampTLVAMP_Assoc_PAL_Version, present), SigPackTlvAMP_Assoc_PAL_Version, (pfnGeneric_t)btampPackTlvAMP_Assoc_PAL_Version, "AMP_Assoc_PAL_Version", 1, }, + { 0xffff, 0 }, + }; + + v_U32_t idx = 0; + v_U32_t status = 0; + (void)i; + *pnConsumed = 0U; + status |= PackTlvCore(pCtx,(v_U8_t*)pFrm,pBuf,nBuf,pnConsumed,TLVS,&idx); + +# ifdef BTAMP_DUMP_FRAMES + if (!BTAMP_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Packed the AMP_ASSOC:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_MAC_Addr:\n")); + if (!pFrm->AMP_Assoc_MAC_Addr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_MAC_Addr.mac_addr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Preferred_Channel_List:\n")); + if (!pFrm->AMP_Assoc_Preferred_Channel_List.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Preferred_Channel_List.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Preferred_Channel_List.triplets, 3 * pFrm->AMP_Assoc_Preferred_Channel_List.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_Connected_Channel:\n")); + if (!pFrm->AMP_Assoc_Connected_Channel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_Connected_Channel.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("num_triplets: %d.\n"), pFrm->AMP_Assoc_Connected_Channel.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* ) pFrm->AMP_Assoc_Connected_Channel.triplets, 3 * pFrm->AMP_Assoc_Connected_Channel.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Capabilities:\n")); + if (!pFrm->AMP_Assoc_PAL_Capabilities.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Capabilities.pal_capabilities, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("AMP_Assoc_PAL_Version:\n")); + if (!pFrm->AMP_Assoc_PAL_Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_CompanyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), ( v_U8_t* )&pFrm->AMP_Assoc_PAL_Version.pal_subversion, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, BTAMP_AMP_ASSOC), pBuf, nBuf); + } +# endif // BTAMP_DUMP_FRAMES + return status; + +} /* End btampUnpackAMP_ASSOC. */ + + +static v_U32_t PackTlvCore(void * pCtx, + v_U8_t *pSrc, + v_U8_t *pBuf, + v_U32_t nBuf, + v_U32_t *pnConsumed, + tTLVDefn TLVs[], + v_U32_t *pidx) +{ + tTLVDefn *pTlv; + tFRAMES_BOOL *pfFound; + v_U8_t *pBufRemaining; + v_U32_t nBufRemaining, status, status2, len; + + BTAMP_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed); + + (void)pCtx; + status = BTAMP_PARSE_SUCCESS; + status2 = BTAMP_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pSrc + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound && pTlv->minSize > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The TLV %s takes at least" + " %d bytes, but there are only %d left in the buffer." + "\n"), pTlv->name, pTlv->minSize, nBufRemaining); + return BTAMP_BUFFER_OVERFLOW; + } + + len = 0U; + + if ( *pfFound ) { + switch ( pTlv->sig ) + { + case SigPackTlvAMP_Assoc_Connected_Channel: + status2 = ( (pfnPackTlvAMP_Assoc_Connected_Channel_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Connected_Channel* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_MAC_Addr: + status2 = ( (pfnPackTlvAMP_Assoc_MAC_Addr_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_MAC_Addr* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_PAL_Capabilities: + status2 = ( (pfnPackTlvAMP_Assoc_PAL_Capabilities_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Capabilities* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_PAL_Version: + status2 = ( (pfnPackTlvAMP_Assoc_PAL_Version_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_PAL_Version* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvAMP_Assoc_Preferred_Channel_List: + status2 = ( (pfnPackTlvAMP_Assoc_Preferred_Channel_List_t)(pTlv->pfn) )(pCtx, ( tBtampTLVAMP_Assoc_Preferred_Channel_List* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvFlow_Spec: + status2 = ( (pfnPackTlvFlow_Spec_t)(pTlv->pfn) )(pCtx, ( tBtampTLVFlow_Spec* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Accept_Logical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Accept_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Logical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Accept_Physical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Accept_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Accept_Physical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Channel_Selected_Event: + status2 = ( (pfnPackTlvHCI_Channel_Selected_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Channel_Selected_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Command_Complete_Event: + status2 = ( (pfnPackTlvHCI_Command_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Command_Status_Event: + status2 = ( (pfnPackTlvHCI_Command_Status_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Command_Status_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Create_Logical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Create_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Logical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Create_Physical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Create_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Create_Physical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Data_Buffer_Overflow_Event: + status2 = ( (pfnPackTlvHCI_Data_Buffer_Overflow_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Data_Buffer_Overflow_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Logical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Disconnect_Logical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Logical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Disconnect_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Logical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Physical_Link_Cmd: + status2 = ( (pfnPackTlvHCI_Disconnect_Physical_Link_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Disconnect_Physical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Disconnect_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Disconnect_Physical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flow_Spec_Modify_Cmd: + status2 = ( (pfnPackTlvHCI_Flow_Spec_Modify_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flow_Spec_Modify_Complete_Event: + status2 = ( (pfnPackTlvHCI_Flow_Spec_Modify_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flow_Spec_Modify_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flush_Cmd: + status2 = ( (pfnPackTlvHCI_Flush_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Flush_Occurred_Event: + status2 = ( (pfnPackTlvHCI_Flush_Occurred_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Flush_Occurred_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Generic_AMP_Link_Key_Notification_Event: + status2 = ( (pfnPackTlvHCI_Generic_AMP_Link_Key_Notification_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Generic_AMP_Link_Key_Notification_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Hardware_Error_Event: + status2 = ( (pfnPackTlvHCI_Hardware_Error_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Hardware_Error_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Logical_Link_Cancel_Cmd: + status2 = ( (pfnPackTlvHCI_Logical_Link_Cancel_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Cancel_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Logical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Logical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Logical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Loopback_Command_Event: + status2 = ( (pfnPackTlvHCI_Loopback_Command_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Loopback_Command_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Physical_Link_Complete_Event: + status2 = ( (pfnPackTlvHCI_Physical_Link_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Physical_Link_Loss_Warning_Event: + status2 = ( (pfnPackTlvHCI_Physical_Link_Loss_Warning_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Loss_Warning_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Physical_Link_Recovery_Event: + status2 = ( (pfnPackTlvHCI_Physical_Link_Recovery_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Physical_Link_Recovery_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Qos_Violation_Event: + status2 = ( (pfnPackTlvHCI_Qos_Violation_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Qos_Violation_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Buffer_Size_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Buffer_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Buffer_Size_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Connection_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Data_Block_Size_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Data_Block_Size_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Data_Block_Size_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Flow_Control_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Link_Quality_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Link_Quality_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Quality_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_AMP_Assoc_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_AMP_Assoc_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_AMP_Information_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_AMP_Information_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_AMP_Information_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_Supported_Cmds_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_Supported_Cmds_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Supported_Cmds_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Local_Version_Info_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Local_Version_Info_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Local_Version_Info_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Location_Data_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Location_Data_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Logical_Link_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_Loopback_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Read_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_Loopback_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Read_RSSI_Cmd: + status2 = ( (pfnPackTlvHCI_Read_RSSI_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Read_RSSI_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Reset_Cmd: + status2 = ( (pfnPackTlvHCI_Reset_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Reset_Failed_Contact_Counter_Cmd: + status2 = ( (pfnPackTlvHCI_Reset_Failed_Contact_Counter_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Set_Event_Mask_Cmd: + status2 = ( (pfnPackTlvHCI_Set_Event_Mask_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Set_Event_Mask_Page_2_Cmd: + status2 = ( (pfnPackTlvHCI_Set_Event_Mask_Page_2_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Set_Short_Range_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Set_Short_Range_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Set_Short_Range_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Short_Range_Mode_Change_Complete_Event: + status2 = ( (pfnPackTlvHCI_Short_Range_Mode_Change_Complete_Event_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Short_Range_Mode_Change_Complete_Event* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Connection_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Connection_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Flow_Control_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Flow_Control_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Flow_Control_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Link_Supervision_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Link_Supervision_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Location_Data_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Location_Data_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Location_Data_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Loopback_Mode_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Loopback_Mode_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Loopback_Mode_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + case SigPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd: + status2 = ( (pfnPackTlvHCI_Write_Remote_AMP_ASSOC_Cmd_t)(pTlv->pfn) )(pCtx, ( tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + if (status2) status |= status2; + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don't " + "know about the TLV %d; this is most likely a bug in " + "'framesc'.\n"), pTlv->sig); + return BTAMP_INTERNAL_ERROR; + } + + } /* End if on *pfFound */ + pBufRemaining += len; + nBufRemaining -= len; + *pnConsumed += len; + ++pTlv; + if(len) ++*pidx; + } + + return status; + +} + diff --git a/drivers/staging/prima/CORE/BAP/src/fsmDefs.h b/drivers/staging/prima/CORE/BAP/src/fsmDefs.h new file mode 100644 index 000000000000..a83c056a2bbc --- /dev/null +++ b/drivers/staging/prima/CORE/BAP/src/fsmDefs.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +// Project/System dependant defines and typedefs + +#ifndef __FSMDEFS_H__ +#define __FSMDEFS_H__ + +/* Temporary fix until I clean up all the type names */ +#define BTAMPFSM_INSTANCEDATA_T tWLAN_BAPbapPhysLinkMachine + +typedef unsigned char BTAMPFSM_ENTRY_FLAG_T; +typedef unsigned char BTAMPFSM_STATEVAR_T; +typedef unsigned char BTAMPFSM_INST_ID_T; +typedef unsigned char BTAMPFSM_EVENT_T; +#endif diff --git a/drivers/staging/prima/CORE/DXE/inc/wlan_qct_dxe.h b/drivers/staging/prima/CORE/DXE/inc/wlan_qct_dxe.h new file mode 100644 index 000000000000..70c2eb650efb --- /dev/null +++ b/drivers/staging/prima/CORE/DXE/inc/wlan_qct_dxe.h @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_DXE_H +#define WLAN_QCT_DXE_H + +/**========================================================================= + + @file wlan_qct_dxe.h + + @brief + + This file contains the external API exposed by the wlan data transfer abstraction layer module. +========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/03/10 schang Created module. + +===========================================================================*/ + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_msg.h" +#include "wlan_qct_pal_sync.h" +#include "wlan_qct_wdi_dts.h" + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/* DXE Descriptor contents SWAP option flag */ + +//#define WLANDXE_ENDIAN_SWAP_ENABLE + +/* Default RX OS frame buffer size + * Size must be same with Vos Packet Size */ +#define WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE (VPKT_SIZE_BUFFER) + +/*reserve 30B of skb buff, to add NL header*/ +#define WLANDXE_NL_HEADER_SZ (30) + +/*MAX data transferred in one skb*/ +#define WLANDXE_FW_LOGGING_XFSIZE (WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE - \ + WLANDXE_NL_HEADER_SZ) + +/*The maximum number of packets that can be chained in dxe for the Low + priority channel + Note: Increased it to 240 from 128 for Windows(EA) becase Windows is + able to push 2~6 packet chain in one NET_BUFFER. It causes TX low + resource condition more easily than LA. It ends up to cause low + throughut number and spend more CPU time*/ +#ifdef WINDOWS_DT +#define WLANDXE_LO_PRI_RES_NUM 240 +#else +#define WLANDXE_LO_PRI_RES_NUM 128 +#endif + + +/*The maximum number of packets that can be chained in dxe for the HI + priority channel */ +#define WLANDXE_HI_PRI_RES_NUM 10 + +typedef enum +{ + WLANDXE_POWER_STATE_FULL, + WLANDXE_POWER_STATE_IMPS, + WLANDXE_POWER_STATE_BMPS, + WLANDXE_POWER_STATE_BMPS_PENDING, + WLANDXE_POWER_STATE_DOWN, + WLANDXE_POWER_STATE_MAX +} WLANDXE_PowerStateType; + +typedef enum +{ + WLANDXE_RIVA_POWER_STATE_ACTIVE, + WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN, + WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN, + WLANDXE_RIVA_POWER_STATE_DOWN_UNKNOWN, + WLANDXE_RIVA_POWER_STATE_MAX +} WLANDXE_RivaPowerStateType; + +/*========================================================================== + @ Type Name + WLANDXE_RxFrameReadyCbType + + @ Description + RX Frame Ready indication CB + + @ Parameters + pVoid pAdapter : Driver global control block pointer + palPacket pRXFramePtr : Received Frame Pointer + pVoid userCtxt : DTS user contect pointer + + @ Return + wpt_status +===========================================================================*/ +typedef WDTS_RxFrameReadyCbType WLANDXE_RxFrameReadyCbType; + +/*========================================================================== + @ Type Name + WLANDXE_TxCompleteCbType + + @ Description + TX complete indication CB + + @ Parameters + pVoid pAdapter : Driver global control block pointer + void pTXFramePtr : Completed TX Frame Pointer + pVoid userCtxt : DTS user contect pointer + + @ Return + wpt_status +===========================================================================*/ +typedef WDTS_TxCompleteCbType WLANDXE_TxCompleteCbType; + +/*========================================================================== + @ Type Name + WLANDXE_LowResourceCbType + + @ Description + DXE Low resource indication CB + + @ Parameters + pVoid pAdapter : Driver global control block pointer + BOOL lowResourceCondition : DXE low resource or not + pVoid userCtxt : DTS user contect pointer + + @ Return + wpt_status +===========================================================================*/ +typedef WDTS_LowResourceCbType WLANDXE_LowResourceCbType; + +/*========================================================================== + @ Type Name + WLANDXE_MbReceiveMsgCbType + + @ Description + DXE Mailbox mes receive indiacation + + @ Parameters + void + + @ Return + void +===========================================================================*/ +typedef WDTS_MbReceiveMsgType WLANDXE_MbReceiveMsgCbType; + +typedef WDTS_RxLogDoneType WLANDXE_RxLogDoneType; + +/*========================================================================== + @ Type Name + WLANDXE_SetPowerStateCbType + + @ Description + DXE Set power state ACK callback. This callback function should be + invoked by the DXE to notify WDI that set power state request is complete + + @ Parameters + status status of the set operation + pUserData Cookie that should be passed back to the caller along with the + callback. + + @ Return + None +===========================================================================*/ +typedef WDTS_SetPSCbType WLANDXE_SetPowerStateCbType; + +/*------------------------------------------------------------------------- + *Function declarations and documenation + *-------------------------------------------------------------------------*/ +/*========================================================================== + @ Function Name + WLANDXE_Open + + @ Description + Open host DXE driver, allocate DXE resources + Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool + + @ Parameters + pVoid pAdapter : Driver global control block pointer + + @ Return + pVoid DXE local module control block pointer +===========================================================================*/ +void *WLANDXE_Open +( + void +); + +/*========================================================================== + @ Function Name + WLANDXE_ClientRegistration + + @ Description + Make callback functions registration into DXE driver from DXE driver client + + @ Parameters + pVoid pDXEContext : DXE module control block + WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events + void *userContext : DXE Cliennt control block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_ClientRegistration +( + void *pDXEContext, + WDTS_ClientCallbacks WDTSCb, + void *userContext +); + +/*========================================================================== + @ Function Name + WLANDXE_Start + + @ Description + Start Host DXE driver + Initialize DXE channels and start channel + + @ Parameters + pVoid pDXEContext : DXE module control block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_Start +( + void *pDXEContext +); + +/*========================================================================== + @ Function Name + WLANDXE_TXFrame + + @ Description + Trigger frame transmit from host to RIVA + + @ Parameters + pVoid pDXEContext : DXE Control Block + wpt_packet pPacket : transmit packet structure + WDTS_ChannelType channel : TX channel + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_TxFrame +( + void *pDXEContext, + wpt_packet *pPacket, + WDTS_ChannelType channel +); + + +/*========================================================================== + @ Function Name + WLANDXE_CompleteTX + + @ Description + Informs DXE that the current series of Tx packets is complete + + @ Parameters + pDXEContext : DXE Control Block + ucTxResReq TX resource number required by TL/WDI + + @ Return + wpt_status +===========================================================================*/ +wpt_status +WLANDXE_CompleteTX +( + void* pDXEContext, + wpt_uint32 ucTxResReq +); + +/*========================================================================== + @ Function Name + WLANDXE_Stop + + @ Description + Stop DXE channels and DXE engine operations + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_Stop +( + void *pDXEContext +); + +/*========================================================================== + @ Function Name + WLANDXE_Close + + @ Description + Close DXE channels + Free DXE related resources + DXE descriptor free + Descriptor control block free + Pre allocated RX buffer free + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_Close +( + void *pDXEContext +); + +/*========================================================================== + @ Function Name + WLANDXE_TriggerTX + + @ Description + TBD + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_TriggerTX +( + void *pDXEContext +); + +/*========================================================================== + @ Function Name + WLANDXE_SetPowerState + + @ Description + From Client let DXE knows what is the WLAN HW(RIVA) power state + + @ Parameters + pVoid pDXEContext : DXE Control Block + WLANDXE_PowerStateType powerState + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_SetPowerState +( + void *pDXEContext, + WDTS_PowerStateType powerState, + WDTS_SetPSCbType cBack +); + +/*========================================================================== + @ Function Name + WLANDXE_GetFreeTxDataResNumber + + @ Description + Returns free descriptor numbers for TX data channel (TX high priority) + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_uint32 Free descriptor number of TX high pri ch +===========================================================================*/ +wpt_uint32 WLANDXE_GetFreeTxDataResNumber +( + void *pDXEContext +); + +/*========================================================================== + @ Function Name + WLANDXE_ChannelDebug + + @ Description + Display DXE Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + @ Parameters + displaySnapshot : Display DXE snapshot option + debugFlags : Enable stall detect features + defined by WPAL_DeviceDebugFlags + These features may effect + data performance. + + @ Return + NONE + +===========================================================================*/ +void WLANDXE_ChannelDebug +( + wpt_boolean displaySnapshot, + wpt_uint8 debugFlags +); + +/*========================================================================== + @ Function Name + WLANDXE_KickDxe + + @ Description + Kick Dxe when HDD TX timeout happen + + @ Parameters + NONE + + @ Return + NONE + +===========================================================================*/ +void WLANDXE_KickDxe +( + void +); + +wpt_uint32 WLANDXE_SetupLogTransfer +( + wpt_uint64 bufferAddr, + wpt_uint32 bufferLen +); + +wpt_status WLANDXE_StartLogTransfer +( +void +); +#endif /* WLAN_QCT_DXE_H */ diff --git a/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe.c b/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe.c new file mode 100644 index 000000000000..de64b93c89e3 --- /dev/null +++ b/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe.c @@ -0,0 +1,5980 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + @file wlan_qct_dxe.c + + @brief + + This file contains the external API exposed by the wlan data transfer abstraction layer module. +========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/03/10 schang Created module. + +===========================================================================*/ + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_dxe.h" +#include "wlan_qct_dxe_i.h" +#include "wlan_qct_pal_device.h" + +/*---------------------------------------------------------------------------- + * Local Definitions + * -------------------------------------------------------------------------*/ +//#define WLANDXE_DEBUG_CH_INFO_DUMP + +/* Temporary configuration defines + * Have to find out permanent solution */ +#define T_WLANDXE_MAX_DESCRIPTOR_COUNT 40 +#define T_WLANDXE_MAX_FRAME_SIZE 2000 +#define T_WLANDXE_TX_INT_ENABLE_FCOUNT 1 +#define T_WLANDXE_MEMDUMP_BYTE_PER_LINE 16 +#define T_WLANDXE_MAX_RX_PACKET_WAIT 6000 +#define T_WLANDXE_SSR_TIMEOUT 5000 +#define T_WLANDXE_PERIODIC_HEALTH_M_TIME 2500 +#define T_WLANDXE_MAX_HW_ACCESS_WAIT 2000 +#define WLANDXE_MAX_REAPED_RX_FRAMES 512 + +#define WLANPAL_RX_INTERRUPT_PRO_MASK 0x20 +#define WLANDXE_RX_INTERRUPT_PRO_UNMASK 0x5F + +/* 1msec busy wait in case CSR is not valid */ +#define WLANDXE_CSR_NEXT_READ_WAIT 1000 +/* CSR max retry count */ +#define WLANDXE_CSR_MAX_READ_COUNT 30 + +/* DXETRACE max records count */ +#define MAX_DXE_TRACE_RECORDS 512 +#define INVALID_TRACE_ADDR 0xffffffff + +/* This is temporary fot the compile + * WDI will release official version + * This must be removed */ +#define WDI_GET_PAL_CTX() NULL + +#define TRACE_WLANDXE_VAR_ENABLE 1 +#define TRACE_WLANDXE_VAR_DISABLE 0 +/*------------------------------------------------------------------------- + * Local Varables + *-------------------------------------------------------------------------*/ +/* This is temp, someone have to allocate for me, and must be part of global context */ +static WLANDXE_CtrlBlkType *tempDxeCtrlBlk; +static char *channelType[WDTS_CHANNEL_MAX] = + { + "TX_LOW_PRI", + "TX_HIGH_PRI", + "RX_LOW_PRI", + "RX_HIGH_PRI", + "RX_LOGS", + "RX_FW_LOGS", + }; +static wpt_packet *rx_reaped_buf[WLANDXE_MAX_REAPED_RX_FRAMES]; +static WLANDXE_EnvInformation dxeEnvBlk; +static dxeTraceData gdxeTraceData; +static dxeTraceRecord gdxeTraceTbl[MAX_DXE_TRACE_RECORDS]; +static spinlock_t dtraceLock; + +/*------------------------------------------------------------------------- + * External Function Proto Type + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Local Function Proto Type + *-------------------------------------------------------------------------*/ +static wpt_status dxeRXFrameSingleBufferAlloc +( + WLANDXE_CtrlBlkType *dxeCtxt, + WLANDXE_ChannelCBType *channelEntry, + WLANDXE_DescCtrlBlkType *currentCtrlBlock +); + +static wpt_status dxeNotifySmsm +( + wpt_boolean kickDxe, + wpt_boolean ringEmpty +); + +static void dxeStartSSRTimer +( + WLANDXE_CtrlBlkType *dxeCtxt +); + +static wpt_status dxeTXCleanup +( + WLANDXE_CtrlBlkType *hostCtxt +); + +static void dxeTrace +( + v_U8_t chan, v_U8_t code, v_U32_t data +); + +/*------------------------------------------------------------------------- + * Local Function + *-------------------------------------------------------------------------*/ +/*========================================================================== + @ Function Name + dxeChannelMonitor + + @ Description + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeChannelMonitor +( + char *monitorDescription, + WLANDXE_ChannelCBType *channelEntry, + wpt_log_data_stall_channel_type *channelLog +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + if((NULL == monitorDescription) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "INVALID Input ARG"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(channelEntry->channelType >= WDTS_CHANNEL_MAX) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "INVALID Channel type"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : HCBO %d, HCBDP 0x%x, HCBDC 0x%x,", + channelType[channelEntry->channelType], + channelEntry->headCtrlBlk->ctrlBlkOrder, + channelEntry->headCtrlBlk->linkedDescPhyAddr, + channelEntry->headCtrlBlk->linkedDesc->descCtrl.ctrl); + wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : TCBO %d, TCBDP 0x%x, TCBDC 0x%x", + channelType[channelEntry->channelType], + channelEntry->tailCtrlBlk->ctrlBlkOrder, + channelEntry->tailCtrlBlk->linkedDescPhyAddr, + channelEntry->tailCtrlBlk->linkedDesc->descCtrl.ctrl); + wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : FDC %d, RDC %d, TFC %d", + channelType[channelEntry->channelType], + channelEntry->numFreeDesc, + channelEntry->numRsvdDesc, + channelEntry->numTotalFrame); + + if(channelLog) + { + channelLog->numDesc = channelEntry->numDesc; + channelLog->numFreeDesc = channelEntry->numFreeDesc; + channelLog->numRsvdDesc = channelEntry->numRsvdDesc; + channelLog->headDescOrder = channelEntry->headCtrlBlk->ctrlBlkOrder; + channelLog->tailDescOrder = channelEntry->tailCtrlBlk->ctrlBlkOrder; + } + + return status; +} + +#ifdef WLANDXE_DEBUG_MEMORY_DUMP +/*========================================================================== + @ Function Name + dxeMemoryDump + + @ Description + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeMemoryDump +( + wpt_uint8 *dumpPointer, + wpt_uint32 dumpSize, + char *dumpTarget +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 numBytes = 0; + wpt_uint32 idx; + + if((NULL == dumpPointer) || + (NULL == dumpTarget)) + { + return status; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Location 0x%x, Size %d", dumpTarget, dumpPointer, dumpSize); + + numBytes = dumpSize % T_WLANDXE_MEMDUMP_BYTE_PER_LINE; + for(idx = 0; idx < dumpSize; idx++) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "0x%2x ", dumpPointer[idx]); + if(0 == ((idx + 1) % T_WLANDXE_MEMDUMP_BYTE_PER_LINE)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n"); + } + } + if(0 != numBytes) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, "\n"); + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + return status; +} +#endif /* WLANDXE_DEBUG_MEMORY_DUMP */ + +/*========================================================================== + @ Function Name + dxeDescriptorDump + + @ Description + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +wpt_status dxeDescriptorDump +( + WLANDXE_ChannelCBType *channelEntry, + WLANDXE_DescType *targetDesc, + wpt_uint32 fragmentOrder +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Descriptor Dump for channel %s, %d / %d fragment", + channelType[channelEntry->channelType], + fragmentOrder + 1, + channelEntry->numFragmentCurrentChain); + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "CTRL WORD 0x%x, TransferSize %d", + WLANDXE_U32_SWAP_ENDIAN(targetDesc->descCtrl.ctrl), + WLANDXE_U32_SWAP_ENDIAN(targetDesc->xfrSize)); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "SRC ADD 0x%x, DST ADD 0x%x, NEXT DESC 0x%x", + WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.srcMemAddrL), + WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.dstMemAddrL), + WLANDXE_U32_SWAP_ENDIAN(targetDesc->dxedesc.dxe_short_desc.phyNextL)); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + return status; +} + +/*========================================================================== + @ Function Name + dxeChannelRegisterDump + + @ Description + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +wpt_status dxeChannelRegisterDump +( + WLANDXE_ChannelCBType *channelEntry, + char *dumpTarget, + wpt_log_data_stall_channel_type *channelLog +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 chStatusReg, chControlReg, chDescReg, chLDescReg; + + /* Whatever RIVA power condition try to wakeup RIVA through SMSM + * This will not simply wakeup RIVA + * Just incase TX not wanted stuck, Trigger TX again */ + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + wpalSleep(10); + + if(channelEntry->channelType >= WDTS_CHANNEL_MAX) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "INVALID Channel type"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, &chDescReg); + wpalReadRegister(channelEntry->channelRegister.chDXELstDesclRegAddr, &chLDescReg); + wpalReadRegister(channelEntry->channelRegister.chDXECtrlRegAddr, &chControlReg); + wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, &chStatusReg); + + wpalTrace(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : CCR 0x%x, CSR 0x%x, CDR 0x%x, CLDR 0x%x", + channelType[channelEntry->channelType], + chControlReg, chStatusReg, chDescReg, chLDescReg); + + if(channelLog) + { + channelLog->ctrlRegVal = chControlReg; + channelLog->statRegVal = chStatusReg; + } + + return status; +} + +/*========================================================================== + @ Function Name + dxeChannelAllDescDump + + @ Description + Dump all DXE descriptors within assigned channe; + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + + @ Return + NONE + +===========================================================================*/ +void dxeChannelAllDescDump +( + WLANDXE_ChannelCBType *channelEntry, + WDTS_ChannelType channel, + wpt_log_data_stall_channel_type *channelLog +) +{ + wpt_uint32 channelLoop; + WLANDXE_DescCtrlBlkType *targetCtrlBlk; + wpt_uint32 previousCtrlValue = 0; + wpt_uint32 previousCtrlValid = 0; + wpt_uint32 currentCtrlValid = 0; + wpt_uint32 valDescCount = 0; + wpt_uint32 invalDescCount = 0; + + targetCtrlBlk = channelEntry->headCtrlBlk; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : %d descriptor chains, head desc ctrl 0x%x", + channelType[channelEntry->channelType], + channelEntry->numDesc, + targetCtrlBlk->linkedDesc->descCtrl.ctrl); + previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl; + + if((WDTS_CHANNEL_RX_LOW_PRI == channel) || + (WDTS_CHANNEL_RX_HIGH_PRI == channel)|| + (WDTS_CHANNEL_RX_LOG == channel)) + { + for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++) + { + if(previousCtrlValue != targetCtrlBlk->linkedDesc->descCtrl.ctrl) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder, + targetCtrlBlk->linkedDesc->descCtrl.ctrl); + } + if(targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID) + { + valDescCount++; + } + else + { + invalDescCount++; + } + previousCtrlValue = targetCtrlBlk->linkedDesc->descCtrl.ctrl; + targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk; + } + } + else + { + /* Head Descriptor is valid or not */ + previousCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID; + targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk; + for(channelLoop = 0; channelLoop < channelEntry->numDesc; channelLoop++) + { + currentCtrlValid = targetCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID; + if(currentCtrlValid) + { + valDescCount++; + } + else + { + invalDescCount++; + } + if(currentCtrlValid != previousCtrlValid) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%5d : 0x%x", targetCtrlBlk->ctrlBlkOrder, + targetCtrlBlk->linkedDesc->descCtrl.ctrl); + } + previousCtrlValid = currentCtrlValid; + targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk; + } + } + + if(channelLog) + { + channelLog->numValDesc = valDescCount; + channelLog->numInvalDesc = invalDescCount; + } + + return; +} + +/*========================================================================== + @ Function Name + dxeErrHandler + + @ Description + Dump channel information for which Error interrupt has occured and + try to recover from the Error + + @ Parameters + WLANDXE_ChannelCBType *channelCb + + @ Return + wpt_status: eWLAN_PAL_STATUS_SUCCESS if recovery is possible and + successful + eWLAN_PAL_STATUS_E_FAILURE if recovery is not possible + or recovery fails +===========================================================================*/ +wpt_status dxeErrHandler +( + WLANDXE_ChannelCBType *channelCb, + wpt_uint32 chStatusReg +) +{ + wpt_uint32 chLDescReg, channelLoop; + WLANDXE_DescCtrlBlkType *targetCtrlBlk; + + switch ((chStatusReg & WLANDXE_CH_STAT_ERR_CODE_MASK) >> + WLANDXE_CH_STAT_ERR_CODE_OFFSET) + { + + case WLANDXE_ERROR_PRG_INV_B2H_SRC_QID: + case WLANDXE_ERROR_PRG_INV_B2H_DST_QID: + case WLANDXE_ERROR_PRG_INV_B2H_SRC_IDX: + case WLANDXE_ERROR_PRG_INV_H2B_SRC_QID: + case WLANDXE_ERROR_PRG_INV_H2B_DST_QID: + case WLANDXE_ERROR_PRG_INV_H2B_DST_IDX: + { + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + wpalSleep(10); + + if(channelCb->channelType > WDTS_CHANNEL_RX_HIGH_PRI) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid Channel", __func__); + break; + } + + wpalReadRegister(channelCb->channelRegister.chDXELstDesclRegAddr, &chLDescReg); + + targetCtrlBlk = channelCb->headCtrlBlk; + + for(channelLoop = 0; channelLoop < channelCb->numDesc; channelLoop++) + { + if (targetCtrlBlk->linkedDescPhyAddr == chLDescReg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s :CHx_DESCL: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x", + channelType[channelCb->channelType], + targetCtrlBlk->linkedDesc->descCtrl.ctrl, + targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL, + targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL, + targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL); + + targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s :Next Desc: desc ctrl 0x%x, src 0x%x, dst 0x%x, next 0x%x", + channelType[channelCb->channelType], + targetCtrlBlk->linkedDesc->descCtrl.ctrl, + targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.srcMemAddrL, + targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.dstMemAddrL, + targetCtrlBlk->linkedDesc->dxedesc.dxe_short_desc.phyNextL); + break; + } + targetCtrlBlk = (WLANDXE_DescCtrlBlkType *)targetCtrlBlk->nextCtrlBlk; + } + wpalFwDumpReq(17, 0, 0, 0, 0, 1); + break; + } + case WLANDXE_ERROR_ABORT: + { + wpt_uint32 regValue, regValueLocal; + wpt_uint32 count = 0; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: DXE Abort Error from S/W", __func__); + + wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, ®Value); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: DXE CSR Value: %08x", __func__,regValue); + + //Execute the BMU recovery only if firmware triggered the ABORT + if (regValue & WLANDXE_DMA_CSR_FW_BMU_RECOVERY) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Firmware BMU recovery On %08x", __func__,regValue); + + // Clean up the descriptors + if (eWLAN_PAL_STATUS_SUCCESS != + dxeTXCleanup(tempDxeCtrlBlk)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Host DXE Cleanup Failed!!!!", __func__); + } + + // Unblock the firmware + regValue |= WLANDXE_DMA_CSR_HOST_RECOVERY_DONE; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Host DXE Cleanup done %08x", __func__,regValue); + wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS, regValue); + + // Wait for firmware to complete the cleanup + do + { + wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, ®Value); + wpalBusyWait(5000); + count++; + //count is 60 because wait is for 5 ms and 60*5=300ms + //which is the time WD bark happens in firmware + } while(count < 60 && !(regValue & WLANDXE_DMA_CSR_RECOVERY_DONE)); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: FW Cleanup done %08x", __func__,regValue); + + //clear all spare bits in CSR + wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS,regValue & + ~(WLANDXE_DMA_CSR_RECOVERY_DONE | + WLANDXE_DMA_CSR_FW_BMU_RECOVERY | + WLANDXE_DMA_CSR_HOST_RECOVERY_DONE)); + + //check if the h/w resources have recovered + wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, ®Value); + wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, ®ValueLocal); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "===== count %d ABD %d, ABD LOCAL %d =====", count, + regValue, regValueLocal); + if(regValue == 0 || regValueLocal == 0) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: HW resources have not recovered", __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; + } + break; + } + default: + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: No Debug Inormation", __func__); + break; + } + + } + return eWLAN_PAL_STATUS_E_FAILURE; +} +/*========================================================================== + @ Function Name + dxeTxThreadChannelDebugHandler + + @ Description + Dump TX channel information + + @ Parameters + Wwpt_msg *msgPtr + + @ Return + NONE + +===========================================================================*/ +void dxeTxThreadChannelDebugHandler +( + wpt_msg *msgPtr +) +{ + wpt_uint8 channelLoop; + wpt_log_data_stall_channel_type channelLog; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Whatever RIVA power condition try to wakeup RIVA through SMSM + * This will not simply wakeup RIVA + * Just incase TX not wanted stuck, Trigger TX again */ + for(channelLoop = 0; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++) + { + dxeChannelMonitor("******** Get Descriptor Snapshot ", + &tempDxeCtrlBlk->dxeChannel[channelLoop], + &channelLog); + dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], + "Abnormal successive empty interrupt", + &channelLog); + dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], + channelLoop, + &channelLog); + + wpalMemoryCopy(channelLog.channelName, + channelType[channelLoop], + WPT_TRPT_CHANNEL_NAME); + wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "================== DXE Dump End ======================"); + wpalMemoryFree(msgPtr); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + wpalPacketStallDumpLog(); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + +/*========================================================================== + @ Function Name + dxeRxThreadChannelDebugHandler + + @ Description + Dump RX channel information + + @ Parameters + Wwpt_msg *msgPtr + + @ Return + NONE + +===========================================================================*/ +void dxeRxThreadChannelDebugHandler +( + wpt_msg *msgPtr +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint8 channelLoop; + wpt_log_data_stall_channel_type channelLog; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Whatever RIVA power condition try to wakeup RIVA through SMSM + * This will not simply wakeup RIVA + * Just incase TX not wanted stuck, Trigger TX again */ + for(channelLoop = WDTS_CHANNEL_RX_LOW_PRI; channelLoop < WDTS_CHANNEL_MAX; channelLoop++) + { + if (!WLANDXE_IS_VALID_CHANNEL(channelLoop)) + continue; + + dxeChannelMonitor("******** Get Descriptor Snapshot ", + &tempDxeCtrlBlk->dxeChannel[channelLoop], + &channelLog); + dxeChannelRegisterDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], + "Abnormal successive empty interrupt", + &channelLog); + dxeChannelAllDescDump(&tempDxeCtrlBlk->dxeChannel[channelLoop], + channelLoop, &channelLog); + + wpalMemoryCopy(channelLog.channelName, + channelType[channelLoop], + WPT_TRPT_CHANNEL_NAME); + wpalPacketStallUpdateInfo(NULL, NULL, &channelLog, channelLoop); + + } + + /* Now serialise the message through Tx thread also to make sure + * no register access when RIVA is in powersave */ + /*Use the same message pointer just change the call back function */ + msgPtr->callback = dxeTxThreadChannelDebugHandler; + status = wpalPostTxMsg(WDI_GET_PAL_CTX(), + msgPtr); + if ( eWLAN_PAL_STATUS_SUCCESS != status ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Tx thread state dump req serialize fail status=%d", + status); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + +/*========================================================================== + @ Function Name + dxeCtrlBlkAlloc + + @ Description + Allocate DXE Control block + DXE control block will used by Host DXE driver only, internal structure + Will make ring linked list + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeCtrlBlkAlloc +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + unsigned int idx, fIdx; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescCtrlBlkType *freeCtrlBlk = NULL; + WLANDXE_DescCtrlBlkType *prevCtrlBlk = NULL; + WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity check */ + if((NULL == dxeCtrlBlk) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeCtrlBlkAlloc Channel Entry is not valid"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + /* Allocate pre asigned number of control blocks */ + for(idx = 0; idx < channelEntry->numDesc; idx++) + { + currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_DescCtrlBlkType)); + if(NULL == currentCtrlBlk) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeCtrlBlkOpen MemAlloc Fail for channel %d", + channelEntry->channelType); + freeCtrlBlk = channelEntry->headCtrlBlk; + for(fIdx = 0; fIdx < idx; fIdx++) + { + if(NULL == freeCtrlBlk) + { + break; + } + + nextCtrlBlk = freeCtrlBlk->nextCtrlBlk; + wpalMemoryFree((void *)freeCtrlBlk); + freeCtrlBlk = nextCtrlBlk; + } + return eWLAN_PAL_STATUS_E_FAULT; + } + + memset((wpt_uint8 *)currentCtrlBlk, 0, sizeof(WLANDXE_DescCtrlBlkType)); + /* Initialize common elements first */ + currentCtrlBlk->xfrFrame = NULL; + currentCtrlBlk->linkedDesc = NULL; + currentCtrlBlk->linkedDescPhyAddr = 0; + currentCtrlBlk->ctrlBlkOrder = idx; + + /* This is the first control block allocated + * Next Control block is not allocated yet + * head and tail must be first control block */ + if(0 == idx) + { + currentCtrlBlk->nextCtrlBlk = NULL; + channelEntry->headCtrlBlk = currentCtrlBlk; + channelEntry->tailCtrlBlk = currentCtrlBlk; + } + /* This is not first, not last control block + * previous control block may has next linked block */ + else if((0 < idx) && (idx < (channelEntry->numDesc - 1))) + { + prevCtrlBlk->nextCtrlBlk = currentCtrlBlk; + } + /* This is last control blocl + * next control block for the last control block is head, first control block + * then whole linked list made RING */ + else if((channelEntry->numDesc - 1) == idx) + { + prevCtrlBlk->nextCtrlBlk = currentCtrlBlk; + currentCtrlBlk->nextCtrlBlk = channelEntry->headCtrlBlk; + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeCtrlBlkOpen Invalid Ctrl Blk location %d", + channelEntry->channelType); + wpalMemoryFree(currentCtrlBlk); + return eWLAN_PAL_STATUS_E_FAULT; + } + + prevCtrlBlk = currentCtrlBlk; + channelEntry->numFreeDesc++; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW,"%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeDescLinkAlloc + + @ Description + Allocate DXE descriptor + DXE descriptor will be shared by DXE host driver and RIVA DXE engine + Will make RING linked list + Will be linked with Descriptor control block one by one + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeDescAllocAndLink +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescType *currentDesc = NULL; + WLANDXE_DescType *prevDesc = NULL; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + unsigned int idx; + void *physAddressAlloc = NULL; + wpt_uint32 physAddress; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity Check */ + if((NULL == dxeCtrlBlk) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeDescLinkAlloc Channel Entry is not valid"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + currentCtrlBlk = channelEntry->headCtrlBlk; + + /* allocate all DXE descriptors for this channel in one chunk */ + channelEntry->descriptorAllocation = (WLANDXE_DescType *) + wpalDmaMemoryAllocate(sizeof(WLANDXE_DescType)*channelEntry->numDesc, + &physAddressAlloc); + physAddress = (wpt_uint32) (uintptr_t)(physAddressAlloc); + if(NULL == channelEntry->descriptorAllocation) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeDescLinkAlloc Descriptor Alloc Fail"); + return eWLAN_PAL_STATUS_E_RESOURCES; + } + currentDesc = channelEntry->descriptorAllocation; + + /* Allocate pre asigned number of descriptor */ + for(idx = 0; idx < channelEntry->numDesc; idx++) + { + // descriptors were allocated in a chunk -- use the current one + if(NULL == currentDesc) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeDescLinkAlloc MemAlloc Fail for channel %d", + channelEntry->channelType); + return eWLAN_PAL_STATUS_E_FAULT; + } + memset((wpt_uint8 *)currentDesc, 0, sizeof(WLANDXE_DescType)); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "Allocated Descriptor VA %p, PA %p", currentDesc, physAddressAlloc); + + currentCtrlBlk->linkedDesc = currentDesc; + currentCtrlBlk->linkedDescPhyAddr = physAddress; + /* First descriptor, next none + * descriptor bottom location is first descriptor address */ + if(0 == idx) + { + currentDesc->dxedesc.dxe_short_desc.phyNextL = 0; + channelEntry->DescBottomLoc = currentDesc; + channelEntry->descBottomLocPhyAddr = physAddress; + } + /* Not first, not last descriptor + * may make link for previous descriptor with current descriptor + * ENDIAN SWAP needed ????? */ + else if((0 < idx) && (idx < (channelEntry->numDesc - 1))) + { + prevDesc->dxedesc.dxe_short_desc.phyNextL = + WLANDXE_U32_SWAP_ENDIAN(physAddress); + } + /* Last descriptor + * make a ring by asign next pointer as first descriptor + * ENDIAN SWAP NEEDED ??? */ + else if((channelEntry->numDesc - 1) == idx) + { + prevDesc->dxedesc.dxe_short_desc.phyNextL = + WLANDXE_U32_SWAP_ENDIAN(physAddress); + currentDesc->dxedesc.dxe_short_desc.phyNextL = + WLANDXE_U32_SWAP_ENDIAN(channelEntry->headCtrlBlk->linkedDescPhyAddr); + } + + /* If Current Channel is RX channel PAL Packet and OS packet buffer should be + * Pre allocated and physical address must be assigned into + * Corresponding DXE Descriptor */ + if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_LOG == channelEntry->channelType)) + { + status = dxeRXFrameSingleBufferAlloc(dxeCtrlBlk, + channelEntry, + currentCtrlBlk); + if( !WLAN_PAL_IS_STATUS_SUCCESS(status) ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeDescLinkAlloc RX Buffer Alloc Fail for channel %d", + channelEntry->channelType); + return status; + } + --channelEntry->numFreeDesc; + } + + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write; + currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = channelEntry->extraConfig.refWQ_swapped; + } + else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)|| + (WDTS_CHANNEL_RX_LOG == channelEntry->channelType)) + { + currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read; + currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = channelEntry->extraConfig.refWQ_swapped; + } + else + { + /* Just in case. H2H RX channel, do nothing + * By Definition this must not happen */ + } + + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + prevDesc = currentDesc; + + // advance to the next pre-allocated descriptor in the chunk + currentDesc++; + physAddress = (physAddress + sizeof(WLANDXE_DescType)); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + + @ Description + + @ Parameters + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeSetInterruptPath +( + WLANDXE_CtrlBlkType *dxeCtrlBlk +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 interruptPath = 0; + wpt_uint32 idx; + WLANDXE_ChannelCBType *channelEntry = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + foreach_valid_channel(idx) + { + channelEntry = &dxeCtrlBlk->dxeChannel[idx]; + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + interruptPath |= (1 << channelEntry->assignedDMAChannel); + } + else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType)|| + (WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType) || + (WDTS_CHANNEL_RX_LOG == channelEntry->channelType)) + { + interruptPath |= (1 << (channelEntry->assignedDMAChannel + 16)); + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "H2H TEST RX???? %d", channelEntry->channelType); + } + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "Interrupt Path Must be 0x%x", interruptPath); + dxeCtrlBlk->interruptPath = interruptPath; + wpalWriteRegister(WLANDXE_CCU_DXE_INT_SELECT, interruptPath); + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeEngineCoreStart + + @ Description + Trigger to start RIVA DXE Hardware + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + + @ Return + void + +===========================================================================*/ +static void dxeEngineCoreStart +( + WLANDXE_CtrlBlkType *dxeCtrlBlk +) +{ + wpt_uint32 registerData = 0; + wpt_uint8 readRetry; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + +#ifdef WCN_PRONTO + /* Read default */ + wpalReadRegister(WLANDXE_CCU_SOFT_RESET, ®isterData); + registerData |= WLANDXE_DMA_CCU_DXE_RESET_MASK; + + /* Make reset */ + wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData); + + /* Clear reset */ + registerData &= ~WLANDXE_DMA_CCU_DXE_RESET_MASK; + wpalWriteRegister(WLANDXE_CCU_SOFT_RESET, registerData); +#else + /* START This core init is not needed for the integrated system */ + /* Reset First */ + registerData = WLANDXE_DMA_CSR_RESET_MASK; + wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS, + registerData); +#endif /* WCN_PRONTO */ + + for(readRetry = 0; readRetry < WLANDXE_CSR_MAX_READ_COUNT; readRetry++) + { + wpalWriteRegister(WALNDEX_DMA_CSR_ADDRESS, + WLANDXE_CSR_DEFAULT_ENABLE); + wpalReadRegister(WALNDEX_DMA_CSR_ADDRESS, ®isterData); + if(!(registerData & WLANDXE_DMA_CSR_EN_MASK)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s CSR 0x%x, count %d", + __func__, registerData, readRetry); + /* CSR is not valid value, re-try to write */ + wpalBusyWait(WLANDXE_CSR_NEXT_READ_WAIT); + } + else + { + break; + } + } + if(WLANDXE_CSR_MAX_READ_COUNT == readRetry) + { + /* MAX wait, still cannot write correct value + * Panic device */ + wpalDevicePanic(); + } + + /* Is This needed? + * Not sure, revisit with integrated system */ + /* END This core init is not needed for the integrated system */ + + dxeSetInterruptPath(dxeCtrlBlk); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); +} + +/*========================================================================== + @ Function Name + dxeChannelInitProgram + + @ Description + Program RIVA DXE engine register with initial value + What must be programmed + - Source Address (SADRL, chDXESadrlRegAddr) + - Destination address (DADRL, chDXEDadrlRegAddr) + - Next Descriptor address (DESCL, chDXEDesclRegAddr) + - current descriptor address (LST_DESCL, chDXELstDesclRegAddr) + + Not need to program now + - Channel Control register (CH_CTRL, chDXECtrlRegAddr) + TX : Have to program to trigger send out frame + RX : programmed by DXE engine + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeChannelInitProgram +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 idx; + WLANDXE_DescType *currentDesc = NULL; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity Check */ + if((NULL == dxeCtrlBlk) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Channel Entry is not valid"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + /* Program Source address and destination adderss */ + if(!channelEntry->channelConfig.useShortDescFmt) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Long Descriptor not support yet"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + /* Common register area */ + /* Next linked list Descriptor pointer */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + channelEntry->headCtrlBlk->linkedDescPhyAddr); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write DESC Address register fail"); + return status; + } + + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + /* Program default registers */ + /* TX DMA channel, DMA destination address is work Q */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, + channelEntry->channelConfig.refWQ); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write TX DAddress register fail"); + return status; + } + } + else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_LOG == channelEntry->channelType)) + { + /* Initialize Descriptor control Word First */ + currentCtrlBlk = channelEntry->headCtrlBlk; + for(idx = 0; idx < channelEntry->channelConfig.nDescs; idx++) + { + currentDesc = currentCtrlBlk->linkedDesc; + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + } + + /* RX DMA channel, DMA source address is work Q */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr, + channelEntry->channelConfig.refWQ); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write RX SAddress WQ register fail"); + return status; + } + + /* RX DMA channel, Program pre allocated destination Address */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, + WLANDXE_U32_SWAP_ENDIAN(channelEntry->DescBottomLoc->dxedesc.dxe_short_desc.phyNextL)); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write RX DAddress register fail"); + return status; + } + + /* RX Channels, default Control registers MUST BE ENABLED */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr, + channelEntry->extraConfig.chan_mask); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write RX Control register fail"); + return status; + } + } + else + { + /* H2H test channel, not use work Q */ + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + + +/*========================================================================== + @ Function Name + dxeChannelStart + + @ Description + Start Specific Channel + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeChannelStart +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 regValue = 0; + wpt_uint32 intMaskVal = 0; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + channelEntry->extraConfig.chEnabled = eWLAN_PAL_TRUE; + channelEntry->extraConfig.chConfigured = eWLAN_PAL_TRUE; + + /* Enable individual channel + * not to break current channel setup, first read register */ + status = wpalReadRegister(WALNDEX_DMA_CH_EN_ADDRESS, + ®Value); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStart Read Channel Enable register fail"); + return status; + } + + /* Enable Channel specific Interrupt */ + status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, + &intMaskVal); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStart Read INT_MASK register fail"); + return status; + } + intMaskVal |= channelEntry->extraConfig.intMask; + status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, + intMaskVal); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStart Write INT_MASK register fail"); + return status; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeChannelStop + + @ Description + Stop Specific Channel + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeChannelStop +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 intMaskVal = 0; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if((NULL == dxeCtrlBlk) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStop Invalid arg input"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if ( (channelEntry->extraConfig.chEnabled != eWLAN_PAL_TRUE) || + (channelEntry->extraConfig.chConfigured != eWLAN_PAL_TRUE)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStop channels are not enabled "); + return status; + } + /* Maskout interrupt */ + status = wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, + &intMaskVal); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStop Read INT_MASK register fail"); + return status; + } + intMaskVal ^= channelEntry->extraConfig.intMask; + status = wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, + intMaskVal); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStop Write INT_MASK register fail"); + return status; + } + + channelEntry->extraConfig.chEnabled = eWLAN_PAL_FALSE; + + /* Stop Channel ??? */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeChannelClose + + @ Description + Close Specific Channel + Free pre allocated RX frame buffer if RX channel + Free DXE descriptor for each channel + Free Descriptor control block for each channel + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeChannelClose +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 idx; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescCtrlBlkType *nextCtrlBlk = NULL; + WLANDXE_DescType *currentDescriptor = NULL; + WLANDXE_DescType *nextDescriptor = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if((NULL == dxeCtrlBlk) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelStop Invalid arg input"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + currentCtrlBlk = channelEntry->headCtrlBlk; + if(NULL != currentCtrlBlk) + { + currentDescriptor = currentCtrlBlk->linkedDesc; + for(idx = 0; idx < channelEntry->numDesc; idx++) + { + if (idx + 1 != channelEntry->numDesc) + { + nextCtrlBlk = currentCtrlBlk->nextCtrlBlk; + nextDescriptor = nextCtrlBlk->linkedDesc; + } + else + { + nextCtrlBlk = NULL; + nextDescriptor = NULL; + } + if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_LOG == channelEntry->channelType)) + { + if (NULL != currentCtrlBlk->xfrFrame) + { + wpalUnlockPacket(currentCtrlBlk->xfrFrame); + wpalPacketFree(currentCtrlBlk->xfrFrame); + } + } + /* + * It is the responsibility of DXE to walk through the + * descriptor chain and unlock any pending packets (if + * locked). + */ + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + if((NULL != currentCtrlBlk->xfrFrame) && + (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame))) + { + wpalUnlockPacket(currentCtrlBlk->xfrFrame); + wpalPacketFree(currentCtrlBlk->xfrFrame); + } + } + wpalMemoryFree(currentCtrlBlk); + + currentCtrlBlk = nextCtrlBlk; + currentDescriptor = nextDescriptor; + if(NULL == currentCtrlBlk) + { + /* Already reach last of the control block + * Not need to process anymore, break */ + break; + } + } + } + + // descriptors were allocated as a single chunk so free the chunk + if(NULL != channelEntry->descriptorAllocation) + { + wpalDmaMemoryFree(channelEntry->descriptorAllocation); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeChannelCleanInt + + @ Description + Clean up interrupt from RIVA HW + After Host finish to handle interrupt, interrupt signal must be cleaned up + Otherwise next interrupt will not be generated + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + wpt_uint32 *chStat + Channel Status register value + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeChannelCleanInt +( + WLANDXE_ChannelCBType *channelEntry, + wpt_uint32 *chStat +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Read Channel Status Register to know why INT Happen */ + status = wpalReadRegister(channelEntry->channelRegister.chDXEStatusRegAddr, + chStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelCleanInt Read CH STAT register fail"); + return eWLAN_PAL_STATUS_E_FAULT; + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Channel INT Clean, Status 0x%x", + channelType[channelEntry->channelType], *chStat); + + /* Clean up all the INT within this channel */ + status = wpalWriteRegister(WLANDXE_INT_CLR_ADDRESS, + (1 << channelEntry->assignedDMAChannel)); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelCleanInt Write CH Clean register fail"); + return eWLAN_PAL_STATUS_E_FAULT; + } + + /* Clean up Error INT Bit */ + if(WLANDXE_CH_STAT_INT_ERR_MASK & *chStat) + { + status = wpalWriteRegister(WLANDXE_INT_ERR_CLR_ADDRESS, + (1 << channelEntry->assignedDMAChannel)); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelCleanInt Read CH STAT register fail"); + return eWLAN_PAL_STATUS_E_FAULT; + } + } + + /* Clean up DONE INT Bit */ + if(WLANDXE_CH_STAT_INT_DONE_MASK & *chStat) + { + status = wpalWriteRegister(WLANDXE_INT_DONE_CLR_ADDRESS, + (1 << channelEntry->assignedDMAChannel)); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelCleanInt Read CH STAT register fail"); + return eWLAN_PAL_STATUS_E_FAULT; + } + } + + /* Clean up ED INT Bit */ + if(WLANDXE_CH_STAT_INT_ED_MASK & *chStat) + { + status = wpalWriteRegister(WLANDXE_INT_ED_CLR_ADDRESS, + (1 << channelEntry->assignedDMAChannel)); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelCleanInt Read CH STAT register fail"); + return eWLAN_PAL_STATUS_E_FAULT; + } + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER +/*========================================================================== + @ Function Name + dxeRXResourceAvailableTimerExpHandler + + @ Description + During pre-set timeperiod, if free available RX buffer is not allocated + Trigger Driver re-loading to recover RX dead end + + @ Parameters + v_VOID_t *usrData + DXE context + + @ Return + NONE + +===========================================================================*/ +void dxeRXResourceAvailableTimerExpHandler +( + void *usrData +) +{ + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + wpt_uint32 numRxFreePackets; + wpt_uint32 numAllocFailures; + + dxeCtxt = (WLANDXE_CtrlBlkType *)usrData; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "RX Low resource, Durign wait time period %d, RX resource not allocated", + wpalGetDxeReplenishRXTimerVal()); + + //This API wil also try to replenish packets + wpalGetNumRxFreePacket(&numRxFreePackets); + wpalGetNumRxPacketAllocFailures(&numAllocFailures); + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Free Packets: %u, Alloc Failures: %u", + numRxFreePackets, numAllocFailures); + if (numRxFreePackets > 0) + { + /* If no. of free packets is greater than 0, it means + * that some packets were replenished and can be used + * by DXE to receive frames. So try to restart the + * resourceAvailable timer here, it will be stopped + * by the DXE's low resource callback if atleast one + * free packet reaches DXE. + */ + if (NULL != dxeCtxt) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Replenish successful. Restart the Rx Low resource timer", + __func__); + wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer, + wpalGetDxeReplenishRXTimerVal()); + return; + } + } + if(wpalIsDxeSSREnable()) + { + if (NULL != dxeCtxt) + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + + wpalWlanReload(); + + if (NULL != usrData) + dxeStartSSRTimer((WLANDXE_CtrlBlkType *)usrData); + } + else + { + wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer, + wpalGetDxeReplenishRXTimerVal()); + } + return; +} +#endif + +/*========================================================================== + @ Function Name + dxeStartSSRTimer + + @ Description + Start the dxeSSRTimer after issuing the FIQ to restart the WCN chip, + this makes sure that if the chip does not respond to the FIQ within + the timeout period the dxeSSRTimer expiration handler will take the + appropriate action. + + @ Parameters + NONE + + @ Return + NONE + +===========================================================================*/ +static void dxeStartSSRTimer +( + WLANDXE_CtrlBlkType *dxeCtxt +) +{ + if(VOS_TIMER_STATE_RUNNING != + wpalTimerGetCurStatus(&dxeCtxt->dxeSSRTimer)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Starting SSR Timer",__func__); + wpalTimerStart(&dxeCtxt->dxeSSRTimer, + T_WLANDXE_SSR_TIMEOUT); + } +} + +/*========================================================================== + @ Function Name + dxeSSRTimerExpHandler + + @ Description + Issue an explicit subsystem restart of the wcnss subsystem if the + WCN chip does not respond to the FIQ within the timeout period + + @ Parameters + v_VOID_t *usrData + + @ Return + NONE + +===========================================================================*/ +void dxeSSRTimerExpHandler +( + void *usrData +) +{ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "DXE not shutdown %d ms after FIQ!! Issue SSR", + T_WLANDXE_SSR_TIMEOUT); + wpalRivaSubystemRestart(); + + return; +} + +/*========================================================================== + @ Function Name + dxeRXPacketAvailableCB + + @ Description + If RX frame handler encounts RX buffer pool empty condition, + DXE RX handle loop will be blocked till get available RX buffer pool. + When new RX buffer pool available, Packet available CB function will + be called. + + @ Parameters + wpt_packet *freePacket + Newly allocated RX buffer + v_VOID_t *usrData + DXE context + + @ Return + NONE + +===========================================================================*/ +void dxeRXPacketAvailableCB +( + wpt_packet *freePacket, + v_VOID_t *usrData +) +{ + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + wpt_status status; + + /* Simple Sanity */ + if((NULL == freePacket) || (NULL == usrData)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Get Free RX Buffer fail, Critical Error"); + HDXE_ASSERT(0); + return; + } + + dxeCtxt = (WLANDXE_CtrlBlkType *)usrData; + + if(WLANDXE_CTXT_COOKIE != dxeCtxt->dxeCookie) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "DXE Context data corrupted, Critical Error"); + HDXE_ASSERT(0); + return; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "DXE RX packet available, post MSG to RX Thread"); + + dxeCtxt->freeRXPacket = freePacket; + + /* Serialize RX Packet Available message upon RX thread */ + if (NULL == dxeCtxt->rxPktAvailMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "DXE NULL pkt"); + HDXE_ASSERT(0); + return; + } + + status = wpalPostRxMsg(WDI_GET_PAL_CTX(), + dxeCtxt->rxPktAvailMsg); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "dxeRXPacketAvailableCB serialize fail"); + } + + return; +} + +/*========================================================================== + @ Function Name + dxeRXFrameSingleBufferAlloc + + @ Description + Allocate Platform packet buffer to prepare RX frame + RX frame memory space must be pre allocted and must be asigned to + descriptor + then whenever DMA engine want to tranfer frame from BMU, + buffer must be ready + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + WLANDXE_DescCtrlBlkType currentCtrlBlock + current control block which have to be asigned + frame buffer + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeRXFrameSingleBufferAlloc +( + WLANDXE_CtrlBlkType *dxeCtxt, + WLANDXE_ChannelCBType *channelEntry, + WLANDXE_DescCtrlBlkType *currentCtrlBlock +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_packet *currentPalPacketBuffer = NULL; + WLANDXE_DescType *currentDesc = NULL; + wpt_iterator iterator; + wpt_uint32 allocatedSize = 0; + void *physAddress = NULL; + + currentDesc = currentCtrlBlock->linkedDesc; + + if(currentDesc->descCtrl.valid) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "This Descriptor is valid, Do not refill"); + return eWLAN_PAL_STATUS_E_EXISTS; + } + + /* First check if a packet pointer has already been provided by a previously + invoked Rx packet available callback. If so use that packet. */ + if (dxeCtxt->rxPalPacketUnavailable) + { + if (NULL != dxeCtxt->freeRXPacket) + { + currentPalPacketBuffer = dxeCtxt->freeRXPacket; + dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_FALSE; + dxeCtxt->freeRXPacket = NULL; + + if (channelEntry->doneIntDisabled) + { + wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr, + channelEntry->extraConfig.chan_mask); + channelEntry->doneIntDisabled = 0; + } + } + else if (VOS_TIMER_STATE_RUNNING != + wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer)) + { + if (eWLAN_PAL_STATUS_SUCCESS != + wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer, + wpalGetDxeReplenishRXTimerVal())) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "RX resource available timer not started"); + } + else + dxeEnvBlk.rx_low_resource_timer = 1; + } + } + else if(!dxeCtxt->rxPalPacketUnavailable) + { + /* Allocate platform Packet buffer and OS Frame Buffer at here */ + currentPalPacketBuffer = wpalPacketAlloc(eWLAN_PAL_PKT_TYPE_RX_RAW, + WLANDXE_DEFAULT_RX_OS_BUFFER_SIZE, + dxeRXPacketAvailableCB, + (void *)dxeCtxt); + + if(NULL == currentPalPacketBuffer) + { + dxeCtxt->rxPalPacketUnavailable = eWLAN_PAL_TRUE; +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER + /* Out of RX free buffer, + * Start timer to recover from RX dead end */ + if(VOS_TIMER_STATE_RUNNING != + wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "RX Low resource, wait available resource"); + if (eWLAN_PAL_STATUS_SUCCESS != + wpalTimerStart(&dxeCtxt->rxResourceAvailableTimer, + wpalGetDxeReplenishRXTimerVal())) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "RX resource available timer not started"); + } + else + dxeEnvBlk.rx_low_resource_timer = 1; + } +#endif + } + } + + if(NULL == currentPalPacketBuffer) + { + return eWLAN_PAL_STATUS_E_RESOURCES; + } + + currentCtrlBlock->xfrFrame = currentPalPacketBuffer; + currentPalPacketBuffer->pktType = eWLAN_PAL_PKT_TYPE_RX_RAW; + currentPalPacketBuffer->pBD = NULL; + currentPalPacketBuffer->pBDPhys = NULL; + currentPalPacketBuffer->BDLength = 0; + + if (channelEntry->channelType == WDTS_CHANNEL_RX_FW_LOG) + wpalPacketRawTrimHead(currentCtrlBlock->xfrFrame, WLANDXE_NL_HEADER_SZ); + + status = wpalLockPacketForTransfer(currentPalPacketBuffer); + + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameBufferAlloc unable to lock packet"); + return status; + } + + /* Init iterator to get physical os buffer address */ + status = wpalIteratorInit(&iterator, currentPalPacketBuffer); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameBufferAlloc iterator init fail"); + return status; + } + status = wpalIteratorNext(&iterator, + currentPalPacketBuffer, + &physAddress, + &allocatedSize); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameBufferAlloc iterator Get Next pointer fail"); + return status; + } + currentPalPacketBuffer->pBDPhys = physAddress; + + /* DXE descriptor must have SWAPPED addres in it's structure + * !!! SWAPPED !!! */ + currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = + WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)currentPalPacketBuffer->pBDPhys); + + return status; +} + +/*========================================================================== + @ Function Name + dxeRXFrameRefillRing + + @ Description + Allocate Platform packet buffers to try to fill up the DXE Rx ring + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeRXFrameRefillRing +( + WLANDXE_CtrlBlkType *dxeCtxt, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk; + WLANDXE_DescType *currentDesc = NULL; + + while(channelEntry->numFreeDesc > 0) + { + /* Current Control block is free + * and associated frame buffer is not linked with control block anymore + * allocate new frame buffer for current control block */ + status = dxeRXFrameSingleBufferAlloc(dxeCtxt, + channelEntry, + currentCtrlBlk); + + if((eWLAN_PAL_STATUS_SUCCESS != status) && + (eWLAN_PAL_STATUS_E_EXISTS != status)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "dxeRXFrameRefillRing, out of RX buffer pool, break here"); + break; + } + + if(eWLAN_PAL_STATUS_E_EXISTS == status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameRefillRing, Descriptor Non-Empry"); + } + + currentDesc = currentCtrlBlk->linkedDesc; + currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read; + + /* Issue a dummy read from the DXE descriptor DDR location to ensure + that any posted writes are reflected in memory before DXE looks at + the descriptor. */ + if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameRefillRing, Descriptor write failed"); + ++channelEntry->desc_write_fail_count; + //HDXE_ASSERT(0); + } + + /* Kick off the DXE ring, if not in any power save mode */ + if(WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState) + { + wpalWriteRegister(WALNDEX_DMA_ENCH_ADDRESS, + 1 << channelEntry->assignedDMAChannel); + } + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + if(eWLAN_PAL_STATUS_E_EXISTS != status) + { + --channelEntry->numFreeDesc; + } + } + + channelEntry->tailCtrlBlk = currentCtrlBlk; + + return status; +} + +static wpt_uint32 dxeRXLogRefillRing +( + WLANDXE_CtrlBlkType *dxeCtxt, + WLANDXE_ChannelCBType *channelEntry, + wpt_uint64 bufferAddr, + wpt_uint32 bufferLen +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = channelEntry->tailCtrlBlk; + WLANDXE_DescType *currentDesc = NULL; + wpt_uint32 xfrSize, allocatedLen = 0; + + while(bufferLen > 0 && channelEntry->numFreeDesc > 0) + { + /* Current Control block is free + * and associated frame buffer is not linked with control block anymore + * allocate new frame buffer for current control block */ + status = dxeRXFrameSingleBufferAlloc(dxeCtxt, + channelEntry, + currentCtrlBlk); + + if((eWLAN_PAL_STATUS_SUCCESS != status) && + (eWLAN_PAL_STATUS_E_EXISTS != status)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "dxeRXFrameRefillRing, out of RX buffer pool, break here"); + break; + } + + if(eWLAN_PAL_STATUS_E_EXISTS == status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s, Descriptor Non-Empty",__func__); + } + + currentDesc = currentCtrlBlk->linkedDesc; + currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_read; + xfrSize = WLANDXE_FW_LOGGING_XFSIZE > bufferLen ? + bufferLen : WLANDXE_FW_LOGGING_XFSIZE; + currentDesc->xfrSize = xfrSize; + allocatedLen += xfrSize; + bufferLen -= xfrSize; + wpalPacketSetRxLength(currentCtrlBlk->xfrFrame, + xfrSize); + + currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = + WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)bufferAddr); + + /* Issue a dummy read from the DXE descriptor DDR location to ensure + that any posted writes are reflected in memory before DXE looks at + the descriptor. */ + if(channelEntry->extraConfig.cw_ctrl_read != currentDesc->descCtrl.ctrl) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s, Descriptor write failed",__func__); + ++channelEntry->desc_write_fail_count; + } + + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + --channelEntry->numFreeDesc; + bufferAddr += xfrSize; + } + + channelEntry->tailCtrlBlk = currentCtrlBlk; + + return allocatedLen; +} +/*========================================================================== + @ Function Name + dxeRXFrameRouteUpperLayer + + @ Description + Test DXE descriptors and if any RX frame pending within RING, + Route to upper layer + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + @ Return + < 0 Any error happen + 0 No frame pulled from RX RING + int number of RX frames pulled from RX ring + +===========================================================================*/ +static wpt_int32 dxeRXFrameRouteUpperLayer +( + WLANDXE_CtrlBlkType *dxeCtxt, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescType *currentDesc = NULL; + wpt_uint32 descCtrl, frameCount = 0, i; + wpt_int32 ret_val = -1; + + currentCtrlBlk = channelEntry->headCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + + /* Descriptoe should be SWAPPED ???? */ + descCtrl = currentDesc->descCtrl.ctrl; + + /* Get frames while VALID bit is not set (DMA complete) and a data + * associated with it */ + while(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID) && + (eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) && + (currentCtrlBlk->xfrFrame->pInternalData != NULL) && + (frameCount < WLANDXE_MAX_REAPED_RX_FRAMES) ) + { + channelEntry->numTotalFrame++; + channelEntry->numFreeDesc++; + status = wpalUnlockPacket(currentCtrlBlk->xfrFrame); + + if (eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReady unable to unlock packet"); + return ret_val; + } + + /* This Descriptor is valid, so linked Control block is also valid + * Linked Control block has pre allocated packet buffer + * So, just let upper layer knows preallocated frame pointer will be OK */ + /* Reap Rx frames */ + rx_reaped_buf[frameCount] = currentCtrlBlk->xfrFrame; + frameCount++; + currentCtrlBlk->xfrFrame = NULL; + + /* Now try to refill the ring with empty Rx buffers to keep DXE busy */ + if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType) + dxeRXFrameRefillRing(dxeCtxt, channelEntry); + + /* Test next contorl block + * if valid, this control block also has new RX frame must be handled */ + currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + descCtrl = currentDesc->descCtrl.ctrl; + } + + /* Update head control block + * current control block's valid bit was 0 + * next trial first control block must be current control block */ + channelEntry->headCtrlBlk = currentCtrlBlk; + + /* Deliver all the reaped RX frames to upper layers */ + i = 0; + while(i < frameCount) + { + dxeCtxt->rxReadyCB(dxeCtxt->clientCtxt, rx_reaped_buf[i], channelEntry->channelType); + i++; + } + + return frameCount; +} + +/*========================================================================== + @ Function Name + dxeRXFrameReady + + @ Description + Pop frame from descriptor and route frame to upper transport layer + Assign new platform packet buffer into used descriptor + Actual frame pop and resource realloc + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeRXFrameReady +( + WLANDXE_CtrlBlkType *dxeCtxt, + WLANDXE_ChannelCBType *channelEntry, + wpt_uint32 chStat +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescType *currentDesc = NULL; + wpt_uint32 descCtrl; + wpt_int32 frameCount = 0; + + wpt_uint32 descLoop; + wpt_uint32 invalidatedFound = 0; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity Check */ + if((NULL == dxeCtxt) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReady Channel Entry is not valid"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry); + + if(0 > frameCount) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReady RX frame route fail"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if((0 == frameCount) && + ((WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) || + (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState))) + { + /* None of the frame handled and CH is not enabled + * RX CH wrap around happen and No RX free frame + * RX side should wait till new free frame available in the pool + * Do not try reload driver at here*/ + if(!(chStat & WLANDXE_CH_CTRL_EN_MASK)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReady %s RING Wrapped, RX Free Low 0x%x", + channelType[channelEntry->channelType], chStat); + /* This is not empty interrupt case + * If handle this as empty interrupt, false SSR might be issued + * Frame count '1' is dummy frame count to avoid SSR */ + channelEntry->numFragmentCurrentChain = 1; + return eWLAN_PAL_STATUS_SUCCESS; + } + + currentCtrlBlk = channelEntry->headCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + descCtrl = currentDesc->descCtrl.ctrl; + + if(WLANDXE_POWER_STATE_BMPS != dxeCtxt->hostPowerState) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "RX ISR called but no frame handled PWS %d, channel %s", + (int)dxeCtxt->hostPowerState, + channelType[channelEntry->channelType]); + } + + /* Current interupt empty and previous interrupt also empty + * detected successive empty interrupt + * or first interrupt empty, this should not happen */ + if(0 == channelEntry->numFragmentCurrentChain) + { + dxeChannelMonitor("RX Ready", channelEntry, NULL); + dxeDescriptorDump(channelEntry, channelEntry->headCtrlBlk->linkedDesc, 0); + dxeChannelRegisterDump(channelEntry, "RX successive empty interrupt", NULL); + dxeChannelAllDescDump(channelEntry, channelEntry->channelType, NULL); + /* Abnormal interrupt detected, try to find not validated descriptor */ + for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++) + { + if(!(WLANDXE_U32_SWAP_ENDIAN(descCtrl) & WLANDXE_DESC_CTRL_VALID)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "Found Invalidated Descriptor %d", (int)descLoop); + if(eWLAN_PAL_STATUS_SUCCESS == wpalIsPacketLocked(currentCtrlBlk->xfrFrame)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "Packet locked, Resync Host and HW"); + channelEntry->headCtrlBlk = currentCtrlBlk; + invalidatedFound = 1; + break; + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "Packet Not Locked, cannot transfer frame"); + } + } + currentCtrlBlk = (WLANDXE_DescCtrlBlkType *)currentCtrlBlk->nextCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + descCtrl = currentDesc->descCtrl.ctrl; + } + + /* Invalidated descriptor found, and that is not head descriptor + * This means HW/SW descriptor miss match happen, and we may recover with just resync + * Try re-sync here */ + if((invalidatedFound) && (0 != descLoop)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Found New Sync location with HW, handle frames from there"); + frameCount = dxeRXFrameRouteUpperLayer(dxeCtxt, channelEntry); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "re-sync routed %d frames to upper layer", (int)frameCount); + channelEntry->numFragmentCurrentChain = frameCount; + } + /* Successive Empty interrupt + * But this case, first descriptor also invalidated, then it means head descriptor + * is linked with already handled RX frame, then could not unlock RX frame + * This is just Out of RX buffer pool, not need to anything here */ + else if((invalidatedFound) && (0 == descLoop)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Out of RX Low resource, and INT came in, do nothing till get RX resource"); + } + /* Critical error, reload driver */ + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Could not found invalidated descriptor"); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "RX successive empty interrupt, Could not find invalidated DESC reload driver"); + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + } + } + channelEntry->numFragmentCurrentChain = frameCount; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeNotifySmsm + + @ Description: Notify SMSM to start DXE engine and/or condition of Tx ring + buffer + + @ Parameters + + @ Return + wpt_status + +===========================================================================*/ +static wpt_status dxeNotifySmsm +( + wpt_boolean kickDxe, + wpt_boolean ringEmpty +) +{ + wpt_uint32 clrSt = 0; + wpt_uint32 setSt = 0; + + if(kickDxe) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "Kick off DXE"); + + if(tempDxeCtrlBlk->lastKickOffDxe == 0) + { + setSt |= WPAL_SMSM_WLAN_TX_ENABLE; + tempDxeCtrlBlk->lastKickOffDxe = 1; + } + else if(tempDxeCtrlBlk->lastKickOffDxe == 1) + { + clrSt |= WPAL_SMSM_WLAN_TX_ENABLE; + tempDxeCtrlBlk->lastKickOffDxe = 0; + } + else + { + HDXE_ASSERT(0); + } + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "no need to kick off DXE"); + } + + tempDxeCtrlBlk->txRingsEmpty = ringEmpty; + if(ringEmpty) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Empty"); + clrSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY; + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, "SMSM Tx Ring Not Empty"); + setSt |= WPAL_SMSM_WLAN_TX_RINGS_EMPTY; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, "C%x S%x", clrSt, setSt); + + /* Store the smsm notification sent to firmware */ + tempDxeCtrlBlk->smsmDxeHistogram = (tempDxeCtrlBlk->smsmDxeHistogram << 1); + if(setSt & WPAL_SMSM_WLAN_TX_ENABLE) + { + tempDxeCtrlBlk->smsmDxeHistogram |= 1; + } + else + { + tempDxeCtrlBlk->smsmDxeHistogram &= ~((wpt_uint32)1); + } + tempDxeCtrlBlk->smsmRingsEmptyHistogram = (tempDxeCtrlBlk->smsmRingsEmptyHistogram << 1); + if(setSt & WPAL_SMSM_WLAN_TX_RINGS_EMPTY) + { + tempDxeCtrlBlk->smsmRingsEmptyHistogram |= 1; + } + else + { + tempDxeCtrlBlk->smsmRingsEmptyHistogram &= ~((wpt_uint32)1); + } + wpalNotifySmsm(clrSt, setSt); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*========================================================================== + @ Function Name + dxePsComplete + + @ Description: Utility function to check the resv desc to deside if we can + get into Power Save mode now + + @ Parameters + + @ Return + None + +===========================================================================*/ +static void dxePsComplete(WLANDXE_CtrlBlkType *dxeCtxt, wpt_boolean intr_based) +{ + if( dxeCtxt->hostPowerState == WLANDXE_POWER_STATE_FULL ) + { + return; + } + + //if both HIGH & LOW Tx channels don't have anything on resv desc,all Tx pkts + //must have been consumed by RIVA, OK to get into BMPS + if((0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) && + (0 == dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc)) + { + tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_FALSE; + //if host is in BMPS & no pkt to Tx, RIVA can go to power save + if(WLANDXE_POWER_STATE_BMPS == dxeCtxt->hostPowerState) + { + dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN; + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + } + } + else //still more pkts to be served by RIVA + { + tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE; + + switch(dxeCtxt->rivaPowerState) + { + case WLANDXE_RIVA_POWER_STATE_ACTIVE: + //NOP + break; + case WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN: + if(intr_based) + { + dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE; + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + } + break; + default: + //assert + break; + } + } +} + +/*========================================================================== + @ Function Name + dxeRXEventHandler + + @ Description + Handle serailized RX frame ready event + First disable interrupt then pick up frame from pre allocated buffer + Since frame handle is doen, clear interrupt bit to ready next interrupt + Finally re enable interrupt + + @ Parameters + wpt_msg *rxReadyMsg + RX frame ready MSG pointer + include DXE control context + + @ Return + NONE + +===========================================================================*/ +void dxeRXEventHandler +( + wpt_msg *rxReadyMsg +) +{ + wpt_msg *msgContent = (wpt_msg *)rxReadyMsg; + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 intSrc = 0; + WLANDXE_ChannelCBType *channelCb = NULL; + wpt_uint32 chHighStat = 0; + wpt_uint32 chLowStat = 0; + wpt_uint32 chLogRxStat = 0; + wpt_uint32 chLogRxFwStat = 0; + wpt_uint32 regValue, chanMask; + + dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext); + + if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "RX Ready WLAN Driver re-loading in progress"); + return; + } + + /* Now try to refill the ring with empty Rx buffers to keep DXE busy */ + dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]); + dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]); + if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG)) + dxeRXFrameRefillRing(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]); + + if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chEnabled) || + (!dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chEnabled) || + (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) && + !dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chEnabled)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "DXE already stopped in RX event handler. Just return"); + return; + } + + /* Disable device interrupt */ + /* Read whole interrupt mask register and exclusive only this channel int */ + status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS, + &intSrc); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler Read INT_SRC register fail"); + return; + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, + "RX Event Handler INT Source 0x%x", intSrc); + + dxeEnvBlk.rxIntChanlSrc = intSrc&0xFF; + + if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) || + (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)) + { + if (WLANDXE_POWER_STATE_DOWN != dxeCtxt->hostPowerState) + { + if(0 == intSrc) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Read status: %d, regVal: %d", + __func__, status, intSrc); + } + else + { + /* Register Read was succesful and we have a valid interrupt + * source, so WCN is not power collapsed yet and it should + * not power collapse till we set the synchronization bit + * at the end of this function, safe to pull frames... + */ + goto pull_frames; + } + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Riva is in %d, Just Pull frames without any register touch", + __func__, dxeCtxt->hostPowerState); + + /* Not to touch any register, just pull frame directly from chain ring + * First high priority */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]; + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chHighStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler Pull from RX high channel fail"); + } + /* In case FW could not power collapse in IMPS mode + * Next power restore might have empty interrupt + * If IMPS mode has empty interrupt since RX thread race, + * Invalid re-load driver might happen + * To prevent invalid re-load driver, + * IMPS event handler set dummpy frame count */ + channelCb->numFragmentCurrentChain = 1; + + /* Second low priority */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]; + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chLowStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler Pull from RX low channel fail"); + } + /* LOW Priority CH same above */ + channelCb->numFragmentCurrentChain = 1; + + if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG)) + { + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]; + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chLogRxStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler Pull from RX log channel fail"); + } + channelCb->numFragmentCurrentChain = 1; + } + /* Interrupt will not enabled at here, it will be enabled at PS mode change */ + tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE; + dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS; + dxeEnvBlk.rxIntDisableFrame = __builtin_frame_address(0); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Host is in %d RX Int Disabled", + __func__, dxeCtxt->hostPowerState); + return; + } + +pull_frames: + /* Test High Priority Channel interrupt is enabled or not */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]; + if(intSrc & (1 << channelCb->assignedDMAChannel)) + { + status = dxeChannelCleanInt(channelCb, &chHighStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler INT Clean up fail"); + return; + } + if(WLANDXE_CH_STAT_INT_ERR_MASK & chHighStat) + { + /* Error Happen during transaction, Handle it */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : 0x%x Error Reported, Reload Driver", + channelType[channelCb->channelType], chHighStat); + + if (eWLAN_PAL_STATUS_SUCCESS != dxeErrHandler(channelCb, chHighStat)) + { + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + } + else if((WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) || + (WLANDXE_CH_STAT_INT_ED_MASK & chHighStat)) + { + /* Handle RX Ready for high priority channel */ + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chHighStat); + } + else if(WLANDXE_CH_STAT_MASKED_MASK & chHighStat) + { + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chHighStat); + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "RX HIGH CH EVNT STAT 0x%x, %d frames handled", chHighStat, channelCb->numFragmentCurrentChain); + /* Update the Rx DONE histogram */ + channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1); + if(WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat) + { + channelCb->rxDoneHistogram |= 1; + } + else + { + channelCb->rxDoneHistogram &= ~((wpt_uint64)1); + } + } + + /* Test Low Priority Channel interrupt is enabled or not */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]; + if(intSrc & (1 << channelCb->assignedDMAChannel)) + { + status = dxeChannelCleanInt(channelCb, &chLowStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler INT Clean up fail"); + return; + } + + if(WLANDXE_CH_STAT_INT_ERR_MASK & chLowStat) + { + /* Error Happen during transaction, Handle it */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : 0x%x Error Reported, Reload Driver", + channelType[channelCb->channelType], chLowStat); + + if (eWLAN_PAL_STATUS_SUCCESS != + dxeErrHandler(channelCb, chLowStat)) + { + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + } + else if((WLANDXE_CH_STAT_INT_ED_MASK & chLowStat) || + (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)) + { + /* Handle RX Ready for low priority channel */ + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chLowStat); + } + + /* Update the Rx DONE histogram */ + channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1); + if(WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat) + { + channelCb->rxDoneHistogram |= 1; + } + else + { + channelCb->rxDoneHistogram &= ~((wpt_uint64)1); + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "RX LOW CH EVNT STAT 0x%x, %d frames handled", chLowStat, channelCb->numFragmentCurrentChain); + } + + if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG)) + { + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]; + + if(intSrc & (1 << channelCb->assignedDMAChannel)) + { + status = dxeChannelCleanInt(channelCb,&chLogRxStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler INT Clean up fail"); + return; + } + + if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxStat) + { + /* Error Happen during transaction, Handle it */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : 0x%x Error Reported, Reload Driver", + channelType[channelCb->channelType], chLogRxStat); + + if (eWLAN_PAL_STATUS_SUCCESS != + dxeErrHandler(channelCb, chLogRxStat)) + { + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + + } + else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxStat) || + (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)) + { + /* Handle RX Ready for low priority channel */ + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chLogRxStat); + } + + /* Update the Rx DONE histogram */ + channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1); + if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat) + { + channelCb->rxDoneHistogram |= 1; + } + else + { + channelCb->rxDoneHistogram &= ~1; + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxStat, channelCb->numFragmentCurrentChain); + } + } + + if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_FW_LOG)) + { + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_FW_LOG]; + + if(intSrc & (1 << channelCb->assignedDMAChannel)) + { + status = dxeChannelCleanInt(channelCb,&chLogRxFwStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler INT Clean up fail"); + return; + } + + if(WLANDXE_CH_STAT_INT_ERR_MASK & chLogRxFwStat) + { + /* Error Happen during transaction, Handle it */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : 0x%x Error Reported, Reload Driver", + channelType[channelCb->channelType], chLogRxFwStat); + + if (eWLAN_PAL_STATUS_SUCCESS != + dxeErrHandler(channelCb, chLogRxFwStat)) + { + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + + } + else if((WLANDXE_CH_STAT_INT_ED_MASK & chLogRxFwStat) || + (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat)) + { + if (!dxeCtxt->hostInitiatedH2H) + { + dxeCtxt->receiveMbMsgCB(dxeCtxt->clientCtxt); + } + else + { + status = dxeRXFrameReady(dxeCtxt, + channelCb, + chLogRxFwStat); + if (channelCb->numFreeDesc == channelCb->numDesc) + { + /* + * We have already cleared the interrupts before coming here, + * but it can happen that DXE will copy some new packets after + * that and raise interrupts for those. The packets will be + * processed above but the interrupts will still be pending. + * Its safe to clear those interrupts here because we have + * pulled data from all the allocated descriptors. + */ + dxeChannelCleanInt(channelCb,&chLogRxFwStat); + dxeCtxt->hostInitiatedH2H = 0; + dxeCtxt->receiveLogCompleteCB(dxeCtxt->clientCtxt); + } + } + } + + /* Update the Rx DONE histogram */ + channelCb->rxDoneHistogram = (channelCb->rxDoneHistogram << 1); + if(WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxFwStat) + { + channelCb->rxDoneHistogram |= 1; + } + else + { + channelCb->rxDoneHistogram &= ~1; + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "RX LOG CH EVNT STAT 0x%x, %d frames handled", chLogRxFwStat, channelCb->numFragmentCurrentChain); + } + } + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler Handle Frame Ready Fail"); + return; + } + + /* Prepare Control Register EN Channel */ + if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK)) + { + HDXE_ASSERT(0); + } + + if (dxeCtxt->rxPalPacketUnavailable && + (WLANDXE_CH_STAT_INT_DONE_MASK & chHighStat)) + { + chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask & + (~WLANDXE_CH_CTRL_INE_DONE_MASK); + dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 1; + } + else + { + chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].extraConfig.chan_mask; + dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].doneIntDisabled = 0; + } + wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI].channelRegister.chDXECtrlRegAddr, + chanMask); + + /* Prepare Control Register EN Channel */ + if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK)) + { + HDXE_ASSERT(0); + } + + if (dxeCtxt->rxPalPacketUnavailable && + (WLANDXE_CH_STAT_INT_DONE_MASK & chLowStat)) + { + chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask & + (~WLANDXE_CH_CTRL_INE_DONE_MASK); + dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 1; + } + else + { + chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].extraConfig.chan_mask; + dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].doneIntDisabled = 0; + } + wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI].channelRegister.chDXECtrlRegAddr, + chanMask); + + /* We do not have knowledge of firmare capabilities when the + * RX_LOG channel is enabled. But when we get the first interrupt + * we have all the required information. So if MGMT Logging is not + * supported by the firmware, do not re-enable RX_LOG channel + */ + if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG) && wpalIsFwLoggingSupported()) + { + if(!(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & WLANDXE_CH_CTRL_EN_MASK)) + { + HDXE_ASSERT(0); + } + + if (dxeCtxt->rxPalPacketUnavailable && + (WLANDXE_CH_STAT_INT_DONE_MASK & chLogRxStat)) + { + chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask & + (~WLANDXE_CH_CTRL_INE_DONE_MASK); + dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 1; + } + else + { + chanMask = dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].extraConfig.chan_mask; + dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].doneIntDisabled = 0; + } + wpalWriteRegister(dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG].channelRegister.chDXECtrlRegAddr, + chanMask); + } + + /* Clear Interrupt handle processing bit + * RIVA may power down */ + if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled())) + { + wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, ®Value); + regValue &= WLANDXE_RX_INTERRUPT_PRO_UNMASK; + wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue); + } + else + { + wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, ®Value); + regValue &= (~WLAN_PMU_POWER_DOWN_MASK); + wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue); + } + + dxeEnvBlk.rxIntChanlSrc = 0; + + /* Enable system level ISR */ + /* Enable RX ready Interrupt at here */ + status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXEventHandler Enable RX Ready interrupt fail"); + return; + } + DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_RXINT_STATE, + TRACE_WLANDXE_VAR_ENABLE)); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + +/*========================================================================== + @ Function Name + dxeRXPacketAvailableEventHandler + + @ Description + Handle serialized RX Packet Available event when the corresponding callback + is invoked by WPAL. + Try to fill up any completed DXE descriptors with available Rx packet buffer + pointers. + + @ Parameters + wpt_msg *rxPktAvailMsg + RX frame ready MSG pointer + include DXE control context + + @ Return + NONE + +===========================================================================*/ +void dxeRXPacketAvailableEventHandler +( + wpt_msg *rxPktAvailMsg +) +{ + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_ChannelCBType *channelCb = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity Check */ + if(NULL == rxPktAvailMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXPacketAvailableEventHandler Context is not valid"); + return; + } + + dxeCtxt = (WLANDXE_CtrlBlkType *)(rxPktAvailMsg->pContext); + +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER + /* Available resource allocated + * Stop timer not needed */ + if(VOS_TIMER_STATE_RUNNING == + wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer)) + { + wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer); + dxeEnvBlk.rx_low_resource_timer = 0; + } +#endif + + do + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "dxeRXPacketAvailableEventHandler, start refilling ring"); + + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_HIGH_PRI]; + status = dxeRXFrameRefillRing(dxeCtxt,channelCb); + + // Wait for another callback to indicate when Rx resources are available + // again. + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + break; + } + + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOW_PRI]; + status = dxeRXFrameRefillRing(dxeCtxt,channelCb); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + break; + } + + if (WLANDXE_IS_VALID_CHANNEL(WDTS_CHANNEL_RX_LOG)) + { + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_RX_LOG]; + status = dxeRXFrameRefillRing(dxeCtxt,channelCb); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + break; + } + } + } while(0); + + if((WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) || + (WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState)) + { + /* Interrupt will not enabled at here, it will be enabled at PS mode change */ + tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_TRUE; + dxeEnvBlk.rxIntDisableReturn = VOS_RETURN_ADDRESS; + dxeEnvBlk.rxIntDisableFrame = __builtin_frame_address(0); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXPacketAvailableEventHandler Int Disabled by IMPS"); + } +} + +/*========================================================================== + @ Function Name + dxeRXISR + + @ Description + RX frame ready interrupt service routine + interrupt entry function, this function called based on ISR context + Must be serialized + + @ Parameters + void *hostCtxt + DXE host driver control context, + pre registerd during interrupt registration + + @ Return + NONE + +===========================================================================*/ +static void dxeRXISR +( + void *hostCtxt +) +{ + WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 regValue; + wpt_uint32 intSrc = 0; + + /* Set Interrupt processing bit + * During this bit set, WLAN HW may not power collapse */ + if (!(wpalIsFwLoggingSupported() && wpalIsFwLoggingEnabled())) + { + wpalReadRegister(WLANDXE_INT_MASK_REG_ADDRESS, ®Value); + regValue |= WLANPAL_RX_INTERRUPT_PRO_MASK; + wpalWriteRegister(WLANDXE_INT_MASK_REG_ADDRESS, regValue); + } + else + { + wpalReadRegister(WLAN_PMU_SPARE_OUT_ADDRESS, ®Value); + regValue |= WLAN_PMU_POWER_DOWN_MASK; + wpalWriteRegister(WLAN_PMU_SPARE_OUT_ADDRESS, regValue); + } + + /* Disable interrupt at here + * Disable RX Ready system level Interrupt at here + * Otherwise infinite loop might happen */ + status = wpalDisableInterrupt(DXE_INTERRUPT_RX_READY); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReadyISR Disable RX ready interrupt fail"); + return; + } + + wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS, + &intSrc); + /* Note: intSrc which holds the INT_SRC_RAW_ADDRESS reg value + While debugging crash dump convert to power of 2 for channel type */ + DXTRACE(dxeTrace(intSrc, TRACE_RXINT_STATE, TRACE_WLANDXE_VAR_DISABLE)); + + /* Serialize RX Ready interrupt upon RX thread */ + if(NULL == dxeCtxt->rxIsrMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReadyISR NULL message"); + HDXE_ASSERT(0); + return; + } + + status = wpalPostRxMsg(WDI_GET_PAL_CTX(), + dxeCtxt->rxIsrMsg); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "dxeRXFrameReadyISR interrupt serialize fail"); + } + + return; +} + +/*========================================================================== + @ Function Name + dxeTXPushFrame + + @ Description + Push TX frame into DXE descriptor and DXE register + Send notification to DXE register that TX frame is ready to transfer + + @ Parameters + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + wpt_packet *palPacket + Packet pointer ready to transfer + + @ Return + PAL_STATUS_T +===========================================================================*/ +static wpt_status dxeTXPushFrame +( + WLANDXE_ChannelCBType *channelEntry, + wpt_packet *palPacket +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescCtrlBlkType *tailCtrlBlk = NULL; + WLANDXE_DescType *currentDesc = NULL; + WLANDXE_DescType *firstDesc = NULL; + WLANDXE_DescType *LastDesc = NULL; + WLANDXE_DescType *tailDesc = NULL; + void *sourcePhysicalAddress = NULL; + wpt_uint32 xferSize = 0; + wpt_iterator iterator; + wpt_uint8 KickDxe = 0; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE; + if((0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc) && + (0 == tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc)) + { + KickDxe = 1; + } + + /* Kick DXE when the ring is about to fill */ + if (WLANDXE_TX_LOW_RES_THRESHOLD >= channelEntry->numFreeDesc) + { + KickDxe = 1; + tailCtrlBlk = channelEntry->tailCtrlBlk; + tailDesc = tailCtrlBlk->linkedDesc; + + if(tailDesc->descCtrl.ctrl& WLANDXE_DESC_CTRL_VALID) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "dxeTXPushFrame Descs threshold reached No DMA"); + } + } + + channelEntry->numFragmentCurrentChain = 0; + currentCtrlBlk = channelEntry->headCtrlBlk; + + /* Initialize interator, TX is fragmented */ + status = wpalLockPacketForTransfer(palPacket); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame unable to lock packet"); + return status; + } + + status = wpalIteratorInit(&iterator, palPacket); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame iterator init fail"); + return status; + } + + /* !!!! Revisit break condition !!!!!!! */ + while(1) + { + /* Get current descriptor pointer from current control block */ + currentDesc = currentCtrlBlk->linkedDesc; + if(NULL == firstDesc) + { + firstDesc = currentCtrlBlk->linkedDesc; + } + /* All control block will have same palPacket Pointer + * to make logic simpler */ + currentCtrlBlk->xfrFrame = palPacket; + + /* Get next fragment physical address and fragment size + * if this is the first trial, will get first physical address + * if no more fragment, Descriptor src address will be set as NULL, OK??? */ + status = wpalIteratorNext(&iterator, + palPacket, + &sourcePhysicalAddress, + &xferSize); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Get next frame fail"); + return status; + } + if((NULL == sourcePhysicalAddress) || + (0 == xferSize)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "dxeTXPushFrame end of current frame"); + break; + } + + /* This is the LAST descriptor valid for this transaction */ + LastDesc = currentCtrlBlk->linkedDesc; + + /* Program DXE descriptor */ + currentDesc->dxedesc.dxe_short_desc.srcMemAddrL = + WLANDXE_U32_SWAP_ENDIAN((wpt_uint32)(uintptr_t)sourcePhysicalAddress); + + /* Just normal data transfer from aCPU Flat Memory to BMU Q */ + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + currentDesc->dxedesc.dxe_short_desc.dstMemAddrL = + WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ); + } + else + { + /* Test specific H2H transfer, destination address already set + * Do Nothing */ + } + currentDesc->xfrSize = WLANDXE_U32_SWAP_ENDIAN(xferSize); + + /* Program channel control register */ + /* First frame not set VAL bit, why ??? */ + if(0 == channelEntry->numFragmentCurrentChain) + { + currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write; + } + else + { + currentDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid; + } + + /* Update statistics */ + channelEntry->numFragmentCurrentChain++; + channelEntry->numFreeDesc--; + channelEntry->numRsvdDesc++; + + /* Get next control block */ + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + } + channelEntry->numTotalFrame++; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "NUM TX FRAG %d, Total Frame %d", + channelEntry->numFragmentCurrentChain, channelEntry->numTotalFrame); + + /* Program Channel control register + * Set as end of packet + * Enable interrupt also for first code lock down + * performace optimization, this will be revisited */ + if(NULL == LastDesc) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame NULL Last Descriptor, broken chain"); + return eWLAN_PAL_STATUS_E_FAULT; + } + LastDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_eop_int; + /* Now First one also Valid ???? + * this procedure will prevent over handle descriptor from previous + * TX trigger */ + firstDesc->descCtrl.ctrl = channelEntry->extraConfig.cw_ctrl_write_valid; + + /* If in BMPS mode no need to notify the DXE Engine, notify SMSM instead */ + if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == tempDxeCtrlBlk->rivaPowerState) + { + /* Update channel head as next avaliable linked slot */ + channelEntry->headCtrlBlk = currentCtrlBlk; + if(KickDxe) + { + tempDxeCtrlBlk->ringNotEmpty = eWLAN_PAL_TRUE; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "SMSM_ret LO=%d HI=%d", + tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc, + tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc ); + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_TRUE; + DXTRACE(dxeTrace(channelEntry->channelType, TRACE_SMSM_NOTIFY, TRACE_WLANDXE_VAR_ENABLE)); + } + return status; + } + + /* If DXE use external descriptor, registers are not needed to be programmed + * Just after finish to program descriptor, tirigger to send */ + if(channelEntry->extraConfig.chan_mask & WLANDXE_CH_CTRL_EDEN_MASK) + { + /* Issue a dummy read from the DXE descriptor DDR location to + ensure that any previously posted write to the descriptor + completes. */ + if(channelEntry->extraConfig.cw_ctrl_write_valid != firstDesc->descCtrl.ctrl) + { + //HDXE_ASSERT(0); + } + + if(wpalIsArpPkt(palPacket)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s :ARP packet", __func__); + } + + /* Everything is ready + * Trigger to start DMA */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr, + channelEntry->extraConfig.chan_mask); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Write Channel Ctrl Register fail"); + return status; + } + DXTRACE(dxeTrace(channelEntry->channelType, TRACE_CH_ENABLE, TRACE_WLANDXE_VAR_ENABLE)); + + /* Update channel head as next avaliable linked slot */ + channelEntry->headCtrlBlk = currentCtrlBlk; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; + } + + /* If DXE not use external descriptor, program each registers */ + /* Circular buffer handle not need to program DESC register??? + * GEN5 code not programed RING buffer case + * REVISIT THIS !!!!!! */ + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + /* Destination address, assigned Work Q */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrlRegAddr, + channelEntry->channelConfig.refWQ); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Program dest address register fail"); + return status; + } + /* If descriptor format is SHORT */ + if(channelEntry->channelConfig.useShortDescFmt) + { + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDadrhRegAddr, + 0); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Program dest address register fail"); + return status; + } + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame LONG Descriptor Format!!!"); + } + } + + /* Program Source address register + * This address is already programmed into DXE Descriptor + * But register also upadte */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrlRegAddr, + WLANDXE_U32_SWAP_ENDIAN(firstDesc->dxedesc.dxe_short_desc.srcMemAddrL)); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Program src address register fail"); + return status; + } + /* If descriptor format is SHORT */ + if(channelEntry->channelConfig.useShortDescFmt) + { + status = wpalWriteRegister(channelEntry->channelRegister.chDXESadrhRegAddr, + 0); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Program dest address register fail"); + return status; + } + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame LONG Descriptor Format!!!"); + } + + /* Linked list Descriptor pointer */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + channelEntry->headCtrlBlk->linkedDescPhyAddr); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Write DESC Address register fail"); + return status; + } + /* If descriptor format is SHORT */ + if(channelEntry->channelConfig.useShortDescFmt) + { + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDeschRegAddr, + 0); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Program dest address register fail"); + return status; + } + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame LONG Descriptor Format!!!"); + } + + /* Transfer Size */ + xferSize = WLANDXE_U32_SWAP_ENDIAN(firstDesc->xfrSize); + status = wpalWriteRegister(channelEntry->channelRegister.chDXESzRegAddr, + xferSize); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Write DESC Address register fail"); + return status; + } + + /* Everything is ready + * Trigger to start DMA */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr, + channelEntry->extraConfig.chan_mask); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXPushFrame Write Channel Ctrl Register fail"); + return status; + } + + /* Update channel head as next avaliable linked slot */ + channelEntry->headCtrlBlk = currentCtrlBlk; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeTXCompFrame + + @ Description + TX Frame transfer complete event handler + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + PAL_STATUS_T +===========================================================================*/ +static wpt_status dxeTXCompFrame +( + WLANDXE_CtrlBlkType *hostCtxt, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescType *currentDesc = NULL; + wpt_uint32 descCtrlValue = 0; + unsigned int *lowThreshold = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if((NULL == hostCtxt) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompFrame Invalid ARG"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(NULL == hostCtxt->txCompCB) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompFrame TXCompCB is not registered"); + return eWLAN_PAL_STATUS_SUCCESS; + } + + status = wpalMutexAcquire(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompFrame Mutex Acquire fail"); + return status; + } + + currentCtrlBlk = channelEntry->tailCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + + if( currentCtrlBlk == channelEntry->headCtrlBlk ) + { + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompFrame Mutex Release fail"); + return status; + } + return eWLAN_PAL_STATUS_SUCCESS; + } + + + while(1) + { +// HDXE_ASSERT(WLAN_PAL_IS_STATUS_SUCCESS(WLAN_RivaValidateDesc(currentDesc))); + descCtrlValue = currentDesc->descCtrl.ctrl; + if((descCtrlValue & WLANDXE_DESC_CTRL_VALID)) + { + /* caught up with head, bail out */ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, + "dxeTXCompFrame caught up with head - next DESC has VALID set"); + break; + } + + if(currentCtrlBlk->xfrFrame == NULL) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid transfer frame"); + HDXE_ASSERT(0); + break; + } + channelEntry->numFreeDesc++; + channelEntry->numRsvdDesc--; + + /* Send Frame TX Complete notification with frame start fragment location */ + if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP) + { + hostCtxt->txCompletedFrames--; + status = wpalUnlockPacket(currentCtrlBlk->xfrFrame); + if (eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReady unable to unlock packet"); + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompFrame Mutex Release fail"); + } + return status; + } + + if(wpalIsArpPkt(currentCtrlBlk->xfrFrame)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s :ARP packet DMA-ed ", __func__); + wpalUpdateTXArpFWdeliveredStats(); + } + + hostCtxt->txCompCB(hostCtxt->clientCtxt, + currentCtrlBlk->xfrFrame, + eWLAN_PAL_STATUS_SUCCESS); + channelEntry->numFragmentCurrentChain = 0; + } + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + + /* Break condition + * Head control block is the control block must be programed for the next TX + * so, head control block is not programmed control block yet + * if loop encounte head control block, stop to complete + * in theory, COMP CB must be called already ??? */ + if(currentCtrlBlk == channelEntry->headCtrlBlk) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, + "dxeTXCompFrame caught up with head ptr"); + break; + } + /* VALID Bit check ???? */ + } + + /* Tail and Head Control block must be same */ + channelEntry->tailCtrlBlk = currentCtrlBlk; + + lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI? + &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh): + &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh); + + /* If specific channel hit low resource condition send notification to upper layer */ + if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) && + (channelEntry->numFreeDesc > *lowThreshold)) + { + /* Change it back if we raised it for fetching a remaining packet from TL */ + if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold) + { + *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "DXE TX %d channel recovered from low resource", channelEntry->channelType); + hostCtxt->lowResourceCB(hostCtxt->clientCtxt, + channelEntry->channelType, + eWLAN_PAL_TRUE); + channelEntry->hitLowResource = eWLAN_PAL_FALSE; + } + + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompFrame Mutex Release fail"); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeTXCleanup + + @ Description + Cleanup the TX channels after DXE Error + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + + @ Return + PAL_STATUS_T +===========================================================================*/ +static wpt_status dxeTXCleanup +( + WLANDXE_CtrlBlkType *hostCtxt +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_DescCtrlBlkType *currentCtrlBlk = NULL; + WLANDXE_DescType *currentDesc = NULL; + wpt_uint32 descCtrlValue = 0; + unsigned int *lowThreshold = NULL; + unsigned int idx; + WLANDXE_ChannelCBType *channelEntry; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if((NULL == hostCtxt)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid ARG", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(NULL == hostCtxt->txCompCB) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: TXCompCB is not registered",__func__); + return eWLAN_PAL_STATUS_SUCCESS; + } + + for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++) + { + channelEntry = &tempDxeCtrlBlk->dxeChannel[idx]; + if(idx != WDTS_CHANNEL_TX_LOW_PRI && idx != WDTS_CHANNEL_TX_HIGH_PRI) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: %11s continue",__func__, + channelType[channelEntry->channelType]); + continue; + } + + status = wpalMutexAcquire(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: %11s Mutex Acquire fail",__func__, + channelType[channelEntry->channelType]); + return status; + } + + currentCtrlBlk = channelEntry->tailCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + + if( currentCtrlBlk == channelEntry->headCtrlBlk ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: %11s Head and Tail are Same",__func__, + channelType[channelEntry->channelType]); + + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: %11s Mutex Release fail",__func__, + channelType[channelEntry->channelType]); + return status; + } + continue; + } + + while(1) + { + descCtrlValue = currentDesc->descCtrl.ctrl; + if((descCtrlValue & WLANDXE_DESC_CTRL_VALID)) + { + /* invalidate... */ + currentDesc->descCtrl.ctrl &= ~WLANDXE_DESC_CTRL_VALID; + } + + if(currentCtrlBlk->xfrFrame == NULL) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: %11s Invalid transfer frame",__func__, + channelType[channelEntry->channelType]); + HDXE_ASSERT(0); + break; + } + channelEntry->numFreeDesc++; + channelEntry->numRsvdDesc--; + + /* Send Frame TX Complete notification with frame start fragment location */ + if(WLANDXE_U32_SWAP_ENDIAN(descCtrlValue) & WLANDXE_DESC_CTRL_EOP) + { + hostCtxt->txCompletedFrames--; + status = wpalUnlockPacket(currentCtrlBlk->xfrFrame); + if (eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: unable to unlock packet",__func__); + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Mutex Release fail",__func__); + } + return status; + } + hostCtxt->txCompCB(hostCtxt->clientCtxt, + currentCtrlBlk->xfrFrame, + eWLAN_PAL_STATUS_SUCCESS); //mir: SUCCESS or FAILURE? + channelEntry->numFragmentCurrentChain = 0; + } + currentCtrlBlk = currentCtrlBlk->nextCtrlBlk; + currentDesc = currentCtrlBlk->linkedDesc; + + /* Break condition + * Head control block is the control block must be programed for the next TX + * so, head control block is not programmed control block yet + * if loop encounte head control block, stop to complete + * in theory, COMP CB must be called already ??? */ + if(currentCtrlBlk == channelEntry->headCtrlBlk) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: %11s caught up with head ptr",__func__, + channelType[channelEntry->channelType]); + break; + } + /* VALID Bit check ???? */ + } + + /* Tail and Head Control block must be same */ + channelEntry->tailCtrlBlk = currentCtrlBlk; + /* Re-Sync Head and CDR */ + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + channelEntry->headCtrlBlk->linkedDescPhyAddr); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write DESC Address register fail"); + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: %11s Mutex Release fail", __func__, + channelType[channelEntry->channelType]); + } + return status; + } + + lowThreshold = channelEntry->channelType == WDTS_CHANNEL_TX_LOW_PRI? + &(hostCtxt->txCompInt.txLowResourceThreshold_LoPriCh): + &(hostCtxt->txCompInt.txLowResourceThreshold_HiPriCh); + + /* If specific channel hit low resource condition send notification to upper layer */ + if((eWLAN_PAL_TRUE == channelEntry->hitLowResource) && + (channelEntry->numFreeDesc > *lowThreshold)) + { + /* Change it back if we raised it for fetching a remaining packet from TL */ + if(WLANDXE_TX_LOW_RES_THRESHOLD > *lowThreshold) + { + *lowThreshold = WLANDXE_TX_LOW_RES_THRESHOLD; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "DXE TX %d channel recovered from low resource", channelEntry->channelType); + hostCtxt->lowResourceCB(hostCtxt->clientCtxt, + channelEntry->channelType, + eWLAN_PAL_TRUE); + channelEntry->hitLowResource = eWLAN_PAL_FALSE; + } + status = wpalMutexRelease(&channelEntry->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: %11s Mutex Release fail", __func__, + channelType[channelEntry->channelType]); + } + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} +/*========================================================================== + @ Function Name + dxeTXEventHandler + + @ Description + If DXE HW sends TX related interrupt, this event handler will be called + Handle higher priority channel first + Figureout why interrupt happen and call appropriate final even handler + TX complete or error happen + + @ Parameters + void *msgPtr + Even MSG + + @ Return + PAL_STATUS_T +===========================================================================*/ +void dxeTXEventHandler +( + wpt_msg *msgPtr +) +{ + wpt_msg *msgContent = (wpt_msg *)msgPtr; + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 intSrc = 0; + wpt_uint32 chStat = 0; + WLANDXE_ChannelCBType *channelCb = NULL; + + wpt_uint8 bEnableISR = 0; + static wpt_uint8 successiveIntWithIMPS; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext); + dxeCtxt->ucTxMsgCnt = 0; + + if(eWLAN_PAL_TRUE == dxeCtxt->driverReloadInProcessing) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "wlan: TX COMP WLAN Driver re-loading in progress"); + return; + } + + /* Read whole interrupt mask register and exclusive only this channel int */ + status = wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS, + &intSrc); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompleteEventHandler Read INT_DONE_SRC register fail"); + return; + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_MED, + "TX Event Handler INT Source 0x%x", intSrc); + + dxeEnvBlk.txCmpIntChanlSrc = intSrc&0xFF; + + /* Return from here if the RIVA is in IMPS, to avoid register access */ + if(WLANDXE_POWER_STATE_IMPS == dxeCtxt->hostPowerState) + { + successiveIntWithIMPS++; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler IMPS TX COMP INT successiveIntWithIMPS %d", successiveIntWithIMPS); + status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler IMPS HC COMP interrupt fail"); + } + + status = dxeTXCompFrame(dxeCtxt, &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler IMPS LC COMP interrupt fail"); + } + + if(((dxeCtxt->txCompletedFrames) && + (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) && + (successiveIntWithIMPS == 1)) + { + dxeCtxt->txIntEnable = eWLAN_PAL_TRUE; + wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "TX COMP INT Enabled, remain TX frame count on ring %d", + dxeCtxt->txCompletedFrames); + + dxeEnvBlk.txCmpIntChanlSrc = 0; + + /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid + the posibility of a race*/ + dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE); + } + else + { + dxeCtxt->txIntEnable = eWLAN_PAL_FALSE; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "TX COMP INT NOT Enabled, RIVA still wake up? remain TX frame count on ring %d, successiveIntWithIMPS %d", + dxeCtxt->txCompletedFrames, successiveIntWithIMPS); + } + return; + } + + successiveIntWithIMPS = 0; + if((!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].extraConfig.chEnabled) || + (!dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].extraConfig.chEnabled)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "DXE already stopped in TX event handler. Just return"); + return; + } + + /* Test High Priority Channel is the INT source or not */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]; + if(intSrc & (1 << channelCb->assignedDMAChannel)) + { + status = dxeChannelCleanInt(channelCb, &chStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler INT Clean up fail"); + return; + } + + if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : 0x%x Error Reported, Reload Driver", + channelType[channelCb->channelType], chStat); + + if (eWLAN_PAL_STATUS_SUCCESS != + dxeErrHandler(channelCb, chStat)) + { + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + bEnableISR = 1; + } + else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat) + { + /* Handle TX complete for high priority channel */ + status = dxeTXCompFrame(dxeCtxt, + channelCb); + bEnableISR = 1; + } + else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat) + { + /* Handle TX complete for high priority channel */ + status = dxeTXCompFrame(dxeCtxt, + channelCb); + bEnableISR = 1; + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler TX HI status=%x", chStat); + } + + if(WLANDXE_CH_STAT_MASKED_MASK & chStat) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, + "dxeTXEventHandler TX HIGH Channel Masked Unmask it!!!!"); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, + "TX HIGH STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc); + } + + /* Test Low Priority Channel interrupt is enabled or not */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]; + if(intSrc & (1 << channelCb->assignedDMAChannel)) + { + status = dxeChannelCleanInt(channelCb, &chStat); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler INT Clean up fail"); + return; + } + + if(WLANDXE_CH_STAT_INT_ERR_MASK & chStat) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : 0x%x Error Reported, Reload Driver", + channelType[channelCb->channelType], chStat); + + if (eWLAN_PAL_STATUS_SUCCESS != + dxeErrHandler(channelCb, chStat)) + { + dxeCtxt->driverReloadInProcessing = eWLAN_PAL_TRUE; + wpalWlanReload(); + dxeStartSSRTimer(dxeCtxt); + } + bEnableISR = 1; + } + else if(WLANDXE_CH_STAT_INT_DONE_MASK & chStat) + { + /* Handle TX complete for low priority channel */ + status = dxeTXCompFrame(dxeCtxt, + channelCb); + bEnableISR = 1; + } + else if(WLANDXE_CH_STAT_INT_ED_MASK & chStat) + { + /* Handle TX complete for low priority channel */ + status = dxeTXCompFrame(dxeCtxt, + channelCb); + bEnableISR = 1; + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXEventHandler TX LO status=%x", chStat); + } + + if(WLANDXE_CH_STAT_MASKED_MASK & chStat) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, + "dxeTXEventHandler TX Low Channel Masked Unmask it!!!!"); + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "TX LOW STAT 0x%x RESRVD %d", chStat, channelCb->numRsvdDesc); + } + + if((bEnableISR || (dxeCtxt->txCompletedFrames)) && + (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) + { + dxeCtxt->txIntEnable = eWLAN_PAL_TRUE; + wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE); + if(0 != dxeCtxt->txCompletedFrames) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "TX COMP INT Enabled, remain TX frame count on ring %d", + dxeCtxt->txCompletedFrames); + } + } + + if(eWLAN_PAL_TRUE == dxeCtxt->txIntEnable) + DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_TXINT_STATE, + TRACE_WLANDXE_VAR_ENABLE)); + + dxeEnvBlk.txCmpIntChanlSrc = 0; + + /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid + the posibility of a race*/ + dxePsComplete(dxeCtxt, eWLAN_PAL_TRUE); + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + + +/*========================================================================== + @ Function Name + dxeTXCompleteProcessing + + @ Description + If DXE HW sends TX related interrupt, this event handler will be called + Handle higher priority channel first + Figureout why interrupt happen and call appropriate final even handler + TX complete or error happen + + @ Parameters + dxeCtxt DXE context + + @ Return + PAL_STATUS_T +===========================================================================*/ +void dxeTXCompleteProcessing +( + WLANDXE_CtrlBlkType *dxeCtxt +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_ChannelCBType *channelCb = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Test High Priority Channel is the INT source or not */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI]; + + /* Handle TX complete for high priority channel */ + status = dxeTXCompFrame(dxeCtxt, channelCb); + + /* Test Low Priority Channel interrupt is enabled or not */ + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]; + + /* Handle TX complete for low priority channel */ + status = dxeTXCompFrame(dxeCtxt, channelCb); + + if((eWLAN_PAL_FALSE == dxeCtxt->txIntEnable) && + ((dxeCtxt->txCompletedFrames > 0) || + (WLANDXE_POWER_STATE_FULL == dxeCtxt->hostPowerState))) + { + dxeCtxt->txIntEnable = eWLAN_PAL_TRUE; + wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s %s : %d, %s : %d", __func__, + channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].channelType], + dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_HIGH_PRI].numRsvdDesc, + channelType[dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].channelType], + dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numRsvdDesc); + + if((WLANDXE_POWER_STATE_FULL != dxeCtxt->hostPowerState) && + (eWLAN_PAL_FALSE == tempDxeCtrlBlk->smsmToggled)) + { + /* After TX Comp processing, still remaining frame on the DXE TX ring + * And when push frame, RING was not empty marked + * Then when push frame, no SMSM toggle happen + * To avoid permanent TX stall, SMSM toggle is needed at here + * With this toggle, host should gaurantee SMSM state should be changed */ + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + } + } + + /*Kicking the DXE after the TX Complete interrupt was enabled - to avoid + the posibility of a race*/ + dxePsComplete(dxeCtxt, eWLAN_PAL_FALSE); + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + +/*========================================================================== + @ Function Name + dxeTXReSyncDesc + + @ Description + When STA comeout from IMPS, check DXE TX next transfer candidate descriptor + And HW programmed descriptor. + If any async happen between HW/SW TX stall will happen + + @ Parameters + void *msgPtr + Message pointer to sync with TX thread + + @ Return + NONE +===========================================================================*/ +void dxeTXReSyncDesc +( + wpt_msg *msgPtr +) +{ + wpt_msg *msgContent = (wpt_msg *)msgPtr; + WLANDXE_CtrlBlkType *pDxeCtrlBlk; + wpt_uint32 nextDescReg; + WLANDXE_ChannelCBType *channelEntry; + WLANDXE_DescCtrlBlkType *validCtrlBlk; + wpt_uint32 descLoop; + wpt_uint32 channelLoop; + + if(NULL == msgContent) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXReSyncDesc Invalid Control Block"); + return; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "dxeTXReSyncDesc Try to re-sync TX channel if any problem"); + pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)(msgContent->pContext); + + for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++) + { + channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop]; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%11s : Try to detect TX descriptor async", channelType[channelEntry->channelType]); + wpalReadRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + &nextDescReg); + /* Async detect without TX pending frame */ + if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk) + { + if(nextDescReg != channelEntry->tailCtrlBlk->linkedDescPhyAddr) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "TX Async no Pending frame"); + + dxeChannelMonitor("!!! TX Async no Pending frame !!!", channelEntry, NULL); + dxeChannelRegisterDump(channelEntry, "!!! TX Async no Pending frame !!!", NULL); + + wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + channelEntry->tailCtrlBlk->linkedDescPhyAddr); + } + } + /* Async detect with some TX pending frames + * next descriptor register should sync with first valid descriptor */ + else + { + validCtrlBlk = channelEntry->tailCtrlBlk; + for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++) + { + if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID) + { + if(nextDescReg != validCtrlBlk->linkedDescPhyAddr) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "TX Async"); + + dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL); + dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL); + + wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + validCtrlBlk->linkedDescPhyAddr); + } + break; + } + validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk; + if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk) + { + /* Finished to test till head control blcok, but could not find valid descriptor + * from head to tail all descriptors are invalidated + * host point of view head descriptor is next TX candidate + * So, next descriptor control have to be programmed with head descriptor + * check */ + if(nextDescReg != channelEntry->headCtrlBlk->linkedDescPhyAddr) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "TX Async with not completed transferred frames, next descriptor must be head"); + + dxeChannelMonitor("!!! TX Async !!!", channelEntry, NULL); + dxeChannelRegisterDump(channelEntry, "!!! TX Async !!!", NULL); + + wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + validCtrlBlk->linkedDescPhyAddr); + } + break; + } + } + } + } + + /* HW/SW descriptor resync is done. + * Next if there are any valid descriptor in chain, Push to HW again */ + for(channelLoop = WDTS_CHANNEL_TX_LOW_PRI; channelLoop < WDTS_CHANNEL_RX_LOW_PRI; channelLoop++) + { + channelEntry = &pDxeCtrlBlk->dxeChannel[channelLoop]; + if(channelEntry->tailCtrlBlk == channelEntry->headCtrlBlk) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%11s : No TX Pending frame", + channelType[channelEntry->channelType]); + /* No Pending frame, Do nothing */ + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : TX Pending frame, process it", + channelType[channelEntry->channelType]); + validCtrlBlk = channelEntry->tailCtrlBlk; + for(descLoop = 0; descLoop < channelEntry->numDesc; descLoop++) + { + if(validCtrlBlk->linkedDesc->descCtrl.ctrl & WLANDXE_DESC_CTRL_VALID) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%11s : when exit IMPS found valid descriptor", + channelType[channelEntry->channelType]); + + /* Found valid descriptor, kick DXE */ + wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr, + channelEntry->extraConfig.chan_mask); + break; + } + validCtrlBlk = (WLANDXE_DescCtrlBlkType *)validCtrlBlk->nextCtrlBlk; + if(validCtrlBlk == channelEntry->headCtrlBlk->nextCtrlBlk) + { + /* Finished to test till head control blcok, but could not find valid descriptor + * from head to tail all descriptors are invalidated */ + break; + } + } + } + } + + wpalMemoryFree(msgPtr); + return; +} + +/*========================================================================== + @ Function Name + dxeDebugTxDescReSync + + @ Description + Check DXE Tx channel state and correct it in + case Tx Data stall is detected by calling + %dxeTXReSyncDesc. Also ensure that WCN SS + is not power collapsed before calling + %dxeTXReSyncDesc + + @ Parameters + void *msgPtr + Message pointer to sync with TX thread + + @ Return + NONE +===========================================================================*/ +void dxeDebugTxDescReSync +( + wpt_msg *msgPtr +) +{ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Check for DXE TX Async",__func__); + /* Make wake up HW */ + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + + wpalSleep(10); + + dxeTXReSyncDesc(msgPtr); +} +/*========================================================================== + @ Function Name + dxeTXISR + + @ Description + TX interrupt ISR + Platform will call this function if INT is happen + This function must be registered into platform interrupt module + + @ Parameters + void *hostCtxt + DXE host driver control context, + pre registerd during interrupt registration + + @ Return + PAL_STATUS_T +===========================================================================*/ +static void dxeTXISR +( + void *hostCtxt +) +{ + WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)hostCtxt; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 intSrc = 0; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Return from here if the RIVA is in IMPS, to avoid register access */ + if(WLANDXE_POWER_STATE_DOWN == dxeCtxt->hostPowerState) + { + dxeCtxt->txIntEnable = eWLAN_PAL_FALSE; + /* Disable interrupt at here, + IMPS or IMPS Pending state should not access RIVA register */ + status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeRXFrameReadyISR Disable RX ready interrupt fail"); + return; + } + dxeCtxt->txIntDisabledByIMPS = eWLAN_PAL_TRUE; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s Riva is in %d, return from here ", __func__, dxeCtxt->hostPowerState); + return; + } + + /* Disable TX Complete Interrupt at here */ + status = wpalDisableInterrupt(DXE_INTERRUPT_TX_COMPLE); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompISR Disable TX complete interrupt fail"); + return; + } + dxeCtxt->txIntEnable = eWLAN_PAL_FALSE; + + wpalReadRegister(WLANDXE_INT_SRC_RAW_ADDRESS, + &intSrc); + /* intSrc which holds the INT_SRC_RAW_ADDRESS reg value + While debugging crash dump convert to power of 2 for channel type */ + DXTRACE(dxeTrace(intSrc, TRACE_TXINT_STATE, TRACE_WLANDXE_VAR_DISABLE)); + + if( dxeCtxt->ucTxMsgCnt ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "Avoiding serializing TX Complete event"); + return; + } + + dxeCtxt->ucTxMsgCnt = 1; + + /* Serialize TX complete interrupt upon TX thread */ + if(NULL == dxeCtxt->txIsrMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Invalid message"); + HDXE_ASSERT(0); + return; + } + + status = wpalPostTxMsg(WDI_GET_PAL_CTX(), + dxeCtxt->txIsrMsg); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "dxeTXCompISR interrupt serialize fail status=%d", status); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + +/*========================================================================== + @ Function Name + dxeTraceInit + + @ Description + Initialize the DXTRACE when enabled + + @ Parameters + NONE + + @ Return + NONE +===========================================================================*/ +void dxeTraceInit(void) +{ + gdxeTraceData.head = INVALID_VOS_TRACE_ADDR; + gdxeTraceData.tail = INVALID_VOS_TRACE_ADDR; + gdxeTraceData.num = 0; + gdxeTraceData.enable = eWLAN_PAL_TRUE; +} + +/*========================================================================== + @ Function Name + dxeTrace + + @ Description + puts the messages in to ring-buffer + + @ Parameters + v_U8_t chan + Rx/Tx path record + v_U8_t code + Rx/Tx Event + v_U32_t data + Actual message contents + @ Return + NONE +===========================================================================*/ +void dxeTrace(v_U8_t chan, v_U8_t code, v_U32_t data) +{ + pdxeTraceRecord rec = NULL; + unsigned long flags; + + if (!gdxeTraceData.enable) + { + return; + } + + /* Aquire the lock and only one thread can access the buffer at a time */ + spin_lock_irqsave(&dtraceLock, flags); + + gdxeTraceData.num++; + + if (gdxeTraceData.num > MAX_DXE_TRACE_RECORDS) + { + gdxeTraceData.num = MAX_DXE_TRACE_RECORDS; + } + if (INVALID_VOS_TRACE_ADDR == gdxeTraceData.head) + { + /* first record */ + gdxeTraceData.head = 0; + gdxeTraceData.tail = 0; + } + else + { + /* queue is not empty */ + v_U32_t tail = gdxeTraceData.tail + 1; + if (MAX_DXE_TRACE_RECORDS == tail) + { + tail = 0; + } + if (gdxeTraceData.head == tail) + { + /* full */ + if (MAX_DXE_TRACE_RECORDS == ++gdxeTraceData.head) + { + gdxeTraceData.head = 0; + } + } + gdxeTraceData.tail = tail; + } + + rec = &gdxeTraceTbl[gdxeTraceData.tail]; + rec->code = code; + rec->data = data; + rec->time = vos_timer_get_system_time(); + rec->chan = chan; + + spin_unlock_irqrestore(&dtraceLock, flags); +} + +/*------------------------------------------------------------------------- + * Global Function + *-------------------------------------------------------------------------*/ +/*========================================================================== + @ Function Name + WLANDXE_Open + + @ Description + Open host DXE driver, allocate DXE resources + Allocate, DXE local control block, DXE descriptor pool, DXE descriptor control block pool + + @ Parameters + pVoid pAdapter : Driver global control block pointer + + @ Return + pVoid DXE local module control block pointer +===========================================================================*/ +void *WLANDXE_Open +( + void +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + unsigned int idx; + WLANDXE_ChannelCBType *currentChannel = NULL; + int smsmInitState; + wpt_uint8 chanMask = WDTS_TRANSPORT_CHANNELS_MASK; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + if (wpalIsFwLoggingEnabled()) + { + chanMask |= WDTS_RX_LOG_CHANNEL_MASK; + } + + if (wpalIsFwEvLoggingEnabled()) + { + chanMask |= WDTS_RX_FW_LOG_CHANNEL_MASK; + } + dxeSetEnabledChannels(chanMask); + + /* This is temporary allocation */ + tempDxeCtrlBlk = (WLANDXE_CtrlBlkType *)wpalMemoryAllocate(sizeof(WLANDXE_CtrlBlkType)); + if(NULL == tempDxeCtrlBlk) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Open Control Block Alloc Fail"); + return NULL; + } + wpalMemoryZero(tempDxeCtrlBlk, sizeof(WLANDXE_CtrlBlkType)); + + dxeCommonDefaultConfig(tempDxeCtrlBlk); + + foreach_valid_channel(idx) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "WLANDXE_Open Channel %s Open Start", channelType[idx]); + currentChannel = &tempDxeCtrlBlk->dxeChannel[idx]; + currentChannel->channelType = idx; + + /* Config individual channels from channel default setup table */ + status = dxeChannelDefaultConfig(tempDxeCtrlBlk, + currentChannel); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Open Channel Basic Configuration Fail for channel %d", idx); + WLANDXE_Close(tempDxeCtrlBlk); + return NULL; + } + + /* Allocate DXE Control Block will be used by host DXE driver */ + status = dxeCtrlBlkAlloc(tempDxeCtrlBlk, currentChannel); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Open Alloc DXE Control Block Fail for channel %d", idx); + + WLANDXE_Close(tempDxeCtrlBlk); + return NULL; + } + status = wpalMutexInit(¤tChannel->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "WLANDXE_Open Lock Init Fail for channel %d", idx); + WLANDXE_Close(tempDxeCtrlBlk); + return NULL; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "WLANDXE_Open Channel %s Open Success", channelType[idx]); + } + + /* Allocate and Init RX READY ISR Serialize Buffer */ + tempDxeCtrlBlk->rxIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == tempDxeCtrlBlk->rxIsrMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Open Alloc RX ISR Fail"); + WLANDXE_Close(tempDxeCtrlBlk); + return NULL; + } + wpalMemoryZero(tempDxeCtrlBlk->rxIsrMsg, sizeof(wpt_msg)); + tempDxeCtrlBlk->rxIsrMsg->callback = dxeRXEventHandler; + tempDxeCtrlBlk->rxIsrMsg->pContext = (void *)tempDxeCtrlBlk; + + /* Allocate and Init TX COMP ISR Serialize Buffer */ + tempDxeCtrlBlk->txIsrMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == tempDxeCtrlBlk->txIsrMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Open Alloc TX ISR Fail"); + WLANDXE_Close(tempDxeCtrlBlk); + return NULL; + } + wpalMemoryZero(tempDxeCtrlBlk->txIsrMsg, sizeof(wpt_msg)); + tempDxeCtrlBlk->txIsrMsg->callback = dxeTXEventHandler; + tempDxeCtrlBlk->txIsrMsg->pContext = (void *)tempDxeCtrlBlk; + + /* Allocate and Init RX Packet Available Serialize Message Buffer */ + tempDxeCtrlBlk->rxPktAvailMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == tempDxeCtrlBlk->rxPktAvailMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Open Alloc RX Packet Available Message Fail"); + WLANDXE_Close(tempDxeCtrlBlk); + return NULL; + } + wpalMemoryZero(tempDxeCtrlBlk->rxPktAvailMsg, sizeof(wpt_msg)); + tempDxeCtrlBlk->rxPktAvailMsg->callback = dxeRXPacketAvailableEventHandler; + tempDxeCtrlBlk->rxPktAvailMsg->pContext = (void *)tempDxeCtrlBlk; + + tempDxeCtrlBlk->freeRXPacket = NULL; + tempDxeCtrlBlk->dxeCookie = WLANDXE_CTXT_COOKIE; + tempDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE; + tempDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE; + tempDxeCtrlBlk->driverReloadInProcessing = eWLAN_PAL_FALSE; + tempDxeCtrlBlk->smsmToggled = eWLAN_PAL_FALSE; + tempDxeCtrlBlk->smsmRingsEmptyHistogram = 0; + tempDxeCtrlBlk->smsmDxeHistogram = 0; + + /* Initialize SMSM state + * Init State is + * Clear TX Enable + * RING EMPTY STATE */ + smsmInitState = wpalNotifySmsm(WPAL_SMSM_WLAN_TX_ENABLE, + WPAL_SMSM_WLAN_TX_RINGS_EMPTY); + if(0 != smsmInitState) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "SMSM Channel init fail %d", smsmInitState); + foreach_valid_channel(idx) + { + dxeChannelClose(tempDxeCtrlBlk, &tempDxeCtrlBlk->dxeChannel[idx]); + } + wpalMemoryFree(tempDxeCtrlBlk->rxIsrMsg); + wpalMemoryFree(tempDxeCtrlBlk->txIsrMsg); + wpalMemoryFree(tempDxeCtrlBlk); + return NULL; + } + +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER + wpalTimerInit(&tempDxeCtrlBlk->rxResourceAvailableTimer, + dxeRXResourceAvailableTimerExpHandler, + tempDxeCtrlBlk); +#endif + + wpalTimerInit(&tempDxeCtrlBlk->dxeSSRTimer, + dxeSSRTimerExpHandler, tempDxeCtrlBlk); + + spin_lock_init(&dtraceLock); + +#ifdef DXE_TRACE + DXTRACE(dxeTraceInit()); +#endif + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "WLANDXE_Open Success"); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return (void *)tempDxeCtrlBlk; +} + +/*========================================================================== + @ Function Name + WLANDXE_ClientRegistration + + @ Description + Make callback functions registration into DXE driver from DXE driver client + + @ Parameters + pVoid pDXEContext : DXE module control block + WDTS_ClientCallbacks WDTSCb : Callbacks to WDTS to indicate various events + void *userContext : DXE Cliennt control block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_ClientRegistration +( + void *pDXEContext, + WDTS_ClientCallbacks WDTSCb, + void *userContext +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_CtrlBlkType *dxeCtxt; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_ClientRegistration Invalid DXE CB"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(NULL == userContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_ClientRegistration Invalid userContext"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext; + + /* Assign */ + dxeCtxt->rxReadyCB = WDTSCb.rxFrameReadyCB; + dxeCtxt->txCompCB = WDTSCb.txCompleteCB; + dxeCtxt->lowResourceCB = WDTSCb.lowResourceCB; + dxeCtxt->receiveMbMsgCB = WDTSCb.receiveMbMsgCB; + dxeCtxt->receiveLogCompleteCB = WDTSCb.receiveLogCompleteCB; + dxeCtxt->clientCtxt = userContext; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_Start + + @ Description + Start Host DXE driver + Initialize DXE channels and start channel + + @ Parameters + pVoid pDXEContext : DXE module control block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_Start +( + void *pDXEContext +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 idx; + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start Invalid DXE CB"); + return eWLAN_PAL_STATUS_E_INVAL; + } + dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext; + + /* WLANDXE_Start called means DXE engine already initiates + * And DXE HW is reset and init finished + * But here to make sure HW is initialized, reset again */ + dxeEngineCoreStart(dxeCtxt); + + /* Individual Channel Start */ + foreach_valid_channel(idx) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "WLANDXE_Start Channel %s Start", channelType[idx]); + + /* Allocate DXE descriptor will be shared by Host driver and DXE engine */ + /* Make connection between DXE descriptor and DXE control block */ + status = dxeDescAllocAndLink(tempDxeCtrlBlk, &dxeCtxt->dxeChannel[idx]); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start Alloc DXE Descriptor Fail for channel %d", idx); + return status; + } + + /* Program each channel register with configuration arguments */ + status = dxeChannelInitProgram(dxeCtxt, + &dxeCtxt->dxeChannel[idx]); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start %d Program DMA channel Fail", idx); + return status; + } + + /* ??? Trigger to start DMA channel + * This must be seperated from ??? */ + status = dxeChannelStart(dxeCtxt, + &dxeCtxt->dxeChannel[idx]); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start %d Channel Start Fail", idx); + return status; + } + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "WLANDXE_Start Channel %s Start Success", channelType[idx]); + } + + /* Register ISR to OS */ + /* Register TX complete interrupt into platform */ + status = wpalRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE, + dxeTXISR, + dxeCtxt); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start TX comp interrupt registration Fail"); + return status; + } + + /* Register RX ready interrupt into platform */ + status = wpalRegisterInterrupt(DXE_INTERRUPT_RX_READY, + dxeRXISR, + dxeCtxt); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start RX Ready interrupt registration Fail"); + return status; + } + + /* Enable system level ISR */ + /* Enable RX ready Interrupt at here */ + status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeTXCompleteEventHandler Enable TX complete interrupt fail"); + return status; + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_TXFrame + + @ Description + Trigger frame transmit from host to RIVA + + @ Parameters + pVoid pDXEContext : DXE Control Block + wpt_packet pPacket : transmit packet structure + WDTS_ChannelType channel : TX channel + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_TxFrame +( + void *pDXEContext, + wpt_packet *pPacket, + WDTS_ChannelType channel +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_ChannelCBType *currentChannel = NULL; + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + unsigned int *lowThreshold = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start Invalid DXE CB"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(NULL == pPacket) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start Invalid pPacket"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(WDTS_CHANNEL_MAX <= channel) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Start Invalid channel"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext; + + currentChannel = &dxeCtxt->dxeChannel[channel]; + + + status = wpalMutexAcquire(¤tChannel->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_TxFrame Mutex Acquire fail"); + return status; + } + + lowThreshold = currentChannel->channelType == WDTS_CHANNEL_TX_LOW_PRI? + &(dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh): + &(dxeCtxt->txCompInt.txLowResourceThreshold_HiPriCh); + + /* Decide have to activate TX complete event or not */ + switch(dxeCtxt->txCompInt.txIntEnable) + { + /* TX complete interrupt will be activated when low DXE resource */ + case WLANDXE_TX_COMP_INT_LR_THRESHOLD: + if((currentChannel->numFreeDesc <= *lowThreshold) && + (eWLAN_PAL_FALSE == dxeCtxt->txIntEnable)) + { + dxeCtxt->txIntEnable = eWLAN_PAL_TRUE; + dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt, + channel, + eWLAN_PAL_FALSE); + } + break; + + /* TX complete interrupt will be activated n number of frames transferred */ + case WLANDXE_TX_COMP_INT_PER_K_FRAMES: + if(channel == WDTS_CHANNEL_TX_LOW_PRI) + { + currentChannel->numFrameBeforeInt++; + } + break; + + /* TX complete interrupt will be activated periodically */ + case WLANDXE_TX_COMP_INT_TIMER: + break; + } + + dxeCtxt->txCompletedFrames++; + + /* Update DXE descriptor, this is frame based + * if a frame consist of N fragments, N Descriptor will be programed */ + status = dxeTXPushFrame(currentChannel, pPacket); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_TxFrame TX Push Frame fail"); + status = wpalMutexRelease(¤tChannel->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_TxFrame Mutex Release fail"); + } + return status; + } + + /* If specific channel hit low resource condition, send notification to upper layer */ + if(currentChannel->numFreeDesc <= *lowThreshold) + { + dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt, + channel, + eWLAN_PAL_FALSE); + currentChannel->hitLowResource = eWLAN_PAL_TRUE; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "%11s : Low Resource currentChannel->numRsvdDesc %d", + channelType[currentChannel->channelType], + currentChannel->numRsvdDesc); + if (WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState) + { + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + } + } + status = wpalMutexRelease(¤tChannel->dxeChannelLock); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_TxFrame Mutex Release fail"); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_CompleteTX + + @ Description + Informs DXE that the current series of Tx packets is complete + + @ Parameters + pContext pDXEContext : DXE Control Block + ucTxResReq TX resource number required by TL/WDI + + @ Return + wpt_status +===========================================================================*/ +wpt_status +WLANDXE_CompleteTX +( + void* pContext, + wpt_uint32 ucTxResReq +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_CtrlBlkType *dxeCtxt = (WLANDXE_CtrlBlkType *)(pContext); + WLANDXE_ChannelCBType *channelCb = NULL; + wpt_boolean inLowRes; + + /* Sanity Check */ + if( NULL == pContext ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_CompleteTX invalid param"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + channelCb = &dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI]; + inLowRes = channelCb->hitLowResource; + + if(WLANDXE_TX_LOW_RES_THRESHOLD < ucTxResReq) + { + /* Raise threshold temporarily if necessary */ + dxeCtxt->txCompInt.txLowResourceThreshold_LoPriCh = ucTxResReq; + + if(eWLAN_PAL_FALSE == inLowRes) + { + /* Put the channel to low resource condition */ + dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt, + WDTS_CHANNEL_TX_LOW_PRI, + eWLAN_PAL_FALSE); + inLowRes = channelCb->hitLowResource = eWLAN_PAL_TRUE; + } + } + + /*Try to reclaim resources*/ + dxeTXCompleteProcessing(dxeCtxt); + + /* In previous WLANTL_GetFrames call, TL didn't fetch a packet + because its fragment size is larger than DXE free resource. */ + if(0 < ucTxResReq) + { + /* DXE successfully claimed enough free DXE resouces for next fetch. */ + if(WLANDXE_GetFreeTxDataResNumber(dxeCtxt) >= ucTxResReq) + { + /* DXE has not been in low resource condition. DXE forces to kick off + TX tranmit */ + if((eWLAN_PAL_FALSE == inLowRes) && + (eWLAN_PAL_FALSE == channelCb->hitLowResource)) + { + dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt, + WDTS_CHANNEL_TX_LOW_PRI, + eWLAN_PAL_FALSE); + dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt, + WDTS_CHANNEL_TX_LOW_PRI, + eWLAN_PAL_TRUE); + channelCb->hitLowResource = eWLAN_PAL_FALSE; + } + } + else + { + /* DXE doesn't have enough free DXE resources. Put the channel + to low resource condition. */ + if(eWLAN_PAL_FALSE == channelCb->hitLowResource) + { + /* Put the channel to low resource condition */ + dxeCtxt->lowResourceCB(dxeCtxt->clientCtxt, + WDTS_CHANNEL_TX_LOW_PRI, + eWLAN_PAL_FALSE); + channelCb->hitLowResource = eWLAN_PAL_TRUE; + } + } + } + + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_Stop + + @ Description + Stop DXE channels and DXE engine operations + Disable all channel interrupt + Stop all channel operation + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_Stop +( + void *pDXEContext +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 idx; + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Stop Invalid DXE CB"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext; + foreach_valid_channel(idx) + { + status = dxeChannelStop(dxeCtxt, &dxeCtxt->dxeChannel[idx]); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Stop Channel %d Stop Fail", idx); + } + } + + /* During Stop unregister interrupt */ + wpalUnRegisterInterrupt(DXE_INTERRUPT_TX_COMPLE); + wpalUnRegisterInterrupt(DXE_INTERRUPT_RX_READY); + +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER + if(VOS_TIMER_STATE_STOPPED != + wpalTimerGetCurStatus(&dxeCtxt->rxResourceAvailableTimer)) + { + wpalTimerStop(&dxeCtxt->rxResourceAvailableTimer); + } +#endif + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_Close + + @ Description + Close DXE channels + Free DXE related resources + DXE descriptor free + Descriptor control block free + Pre allocated RX buffer free + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_Close +( + void *pDXEContext +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 idx; + WLANDXE_CtrlBlkType *dxeCtxt = NULL; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Sanity */ + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_Stop Invalid DXE CB"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + dxeCtxt = (WLANDXE_CtrlBlkType *)pDXEContext; +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER + wpalTimerDelete(&dxeCtxt->rxResourceAvailableTimer); +#endif + wpalTimerDelete(&dxeCtxt->dxeSSRTimer); + foreach_valid_channel(idx) + { + wpalMutexDelete(&dxeCtxt->dxeChannel[idx].dxeChannelLock); + dxeChannelClose(dxeCtxt, &dxeCtxt->dxeChannel[idx]); + } + + if(NULL != dxeCtxt->rxIsrMsg) + { + wpalMemoryFree(dxeCtxt->rxIsrMsg); + } + if(NULL != dxeCtxt->txIsrMsg) + { + wpalMemoryFree(dxeCtxt->txIsrMsg); + } + if(NULL != dxeCtxt->rxPktAvailMsg) + { + wpalMemoryFree(dxeCtxt->rxPktAvailMsg); + } + + wpalMemoryFree(pDXEContext); + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_TriggerTX + + @ Description + TBD + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_TriggerTX +( + void *pDXEContext +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* TBD */ + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return status; +} + +/*========================================================================== + @ Function Name + dxeTxThreadSetPowerStateEventHandler + + @ Description + If WDI sends set power state req, this event handler will be called in Tx + thread context + + @ Parameters + void *msgPtr + Event MSG + + @ Return + None +===========================================================================*/ +void dxeTxThreadSetPowerStateEventHandler +( + wpt_msg *msgPtr +) +{ + wpt_msg *msgContent = (wpt_msg *)msgPtr; + WLANDXE_CtrlBlkType *dxeCtxt; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_PowerStateType reqPowerState; + wpt_int8 i; + WLANDXE_ChannelCBType *channelEntry; + wpt_log_data_stall_channel_type channelLog; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + dxeCtxt = (WLANDXE_CtrlBlkType *)(msgContent->pContext); + reqPowerState = (WLANDXE_PowerStateType)msgContent->val; + dxeCtxt->setPowerStateCb = (WLANDXE_SetPowerStateCbType)msgContent->ptr; + + switch(reqPowerState) + { + case WLANDXE_POWER_STATE_BMPS: + if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState) + { + //don't block MC waiting for num_rsvd to become 0 since it may take a while + //based on amount of TX and RX activity - during this time any received + // management frames will remain un-processed consuming RX buffers + dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN; + dxeCtxt->hostPowerState = reqPowerState; + } + else + { + status = eWLAN_PAL_STATUS_E_INVAL; + } + break; + case WLANDXE_POWER_STATE_IMPS: + if(WLANDXE_RIVA_POWER_STATE_ACTIVE == dxeCtxt->rivaPowerState) + { + + for(i = WDTS_CHANNEL_TX_LOW_PRI; i < WDTS_CHANNEL_RX_LOW_PRI; i++) + { + channelEntry = &dxeCtxt->dxeChannel[i]; + if(channelEntry->tailCtrlBlk != channelEntry->headCtrlBlk) + { + status = eWLAN_PAL_STATUS_E_FAILURE; + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%11s : %s :TX Pending frame", + channelType[channelEntry->channelType], __func__); + + dxeChannelMonitor("DXE_IMP_ERR", channelEntry, &channelLog); + dxeDescriptorDump(channelEntry, + channelEntry->headCtrlBlk->linkedDesc, 0); + dxeChannelRegisterDump(channelEntry, "DXE_IMPS_ERR", + &channelLog); + dxeChannelAllDescDump(channelEntry, + channelEntry->channelType, + &channelLog); + } + } + + if (eWLAN_PAL_STATUS_SUCCESS == status) + { + dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_IMPS_UNKNOWN; + dxeCtxt->hostPowerState = WLANDXE_POWER_STATE_IMPS; + } + } + else + { + status = eWLAN_PAL_STATUS_E_INVAL; + } + break; + case WLANDXE_POWER_STATE_FULL: + if(WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN == dxeCtxt->rivaPowerState) + { + dxeCtxt->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE; + } + dxeCtxt->hostPowerState = reqPowerState; + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + break; + case WLANDXE_POWER_STATE_DOWN: + WLANDXE_Stop((void *)dxeCtxt); + break; + default: + //assert + break; + } + + DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_POWER_STATE, dxeCtxt->hostPowerState)); + + if(WLANDXE_POWER_STATE_BMPS_PENDING != dxeCtxt->hostPowerState) + { + dxeCtxt->setPowerStateCb(status, + dxeCtxt->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].descBottomLocPhyAddr); + } + else + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s State of DXE is WLANDXE_POWER_STATE_BMPS_PENDING, so cannot proceed", __func__); + } + /* Free MSG buffer */ + wpalMemoryFree(msgPtr); + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + return; +} + + +/*========================================================================== + @ Function Name + dxeRxThreadSetPowerStateEventHandler + + @ Description + If WDI sends set power state req, this event handler will be called in Rx + thread context + + @ Parameters + void *msgPtr + Event MSG + + @ Return + None +===========================================================================*/ +void dxeRxThreadSetPowerStateEventHandler +( + wpt_msg *msgPtr +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + /* Now serialise the message through Tx thread also to make sure + * no register access when RIVA is in powersave */ + /*Use the same message pointer just change the call back function */ + msgPtr->callback = dxeTxThreadSetPowerStateEventHandler; + status = wpalPostTxMsg(WDI_GET_PAL_CTX(), + msgPtr); + if ( eWLAN_PAL_STATUS_SUCCESS != status ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Tx thread Set power state req serialize fail status=%d", + status); + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); +} + +/*========================================================================== + @ Function Name + WLANDXE_SetPowerState + + @ Description + From Client let DXE knows what is the WLAN HW(RIVA) power state + + @ Parameters + pVoid pDXEContext : DXE Control Block + WLANDXE_PowerStateType powerState + + @ Return + wpt_status +===========================================================================*/ +wpt_status WLANDXE_SetPowerState +( + void *pDXEContext, + WDTS_PowerStateType powerState, + WDTS_SetPSCbType cBack +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + WLANDXE_CtrlBlkType *pDxeCtrlBlk; + WLANDXE_PowerStateType hostPowerState; + wpt_msg *rxCompMsg; + wpt_msg *txDescReSyncMsg; + int state; + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "NULL pDXEContext passed by caller"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + pDxeCtrlBlk = (WLANDXE_CtrlBlkType *)pDXEContext; + + switch(powerState) + { + case WDTS_POWER_STATE_FULL: + dxeEnvBlk.dxe_prev_ps = pDxeCtrlBlk->hostPowerState; + if(WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState) + { + txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == txDescReSyncMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_SetPowerState, TX Resync MSG MEM alloc Fail"); + } + else + { + txDescReSyncMsg->callback = dxeTXReSyncDesc; + txDescReSyncMsg->pContext = pDxeCtrlBlk; + status = wpalPostTxMsg(WDI_GET_PAL_CTX(), + txDescReSyncMsg); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_SetPowerState, Post TX re-sync MSG fail"); + } + } + } + hostPowerState = WLANDXE_POWER_STATE_FULL; + break; + case WDTS_POWER_STATE_BMPS: + pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_BMPS; + hostPowerState = WLANDXE_POWER_STATE_BMPS; + break; + case WDTS_POWER_STATE_IMPS: + hostPowerState = WLANDXE_POWER_STATE_IMPS; + break; + case WDTS_POWER_STATE_DOWN: + pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_DOWN; + hostPowerState = WLANDXE_POWER_STATE_DOWN; + break; + default: + hostPowerState = WLANDXE_POWER_STATE_MAX; + } + + // A callback i.e. ACK back is needed only when we want to enable BMPS + // and the data/management path is active because we want to ensure + // DXE registers are not accessed when RIVA may be power-collapsed. So + // we need a callback in enter_bmps_req (the request to RIVA is sent + // only after ACK back from TX thread). A callback is not needed in + // finish_scan_req during BMPS since data-path is resumed only in + // finish_scan_rsp and no management frames are sent in between. No + // callback is needed when going from BMPS enabled to BMPS suspended/ + // disabled when it is known that RIVA is awake and cannot enter power + // collapse autonomously so no callback is needed in exit_bmps_rsp or + // init_scan_rsp + if ( cBack ) + { + //serialize through Rx thread + rxCompMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == rxCompMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_SetPowerState, MSG MEM alloc Fail"); + return eWLAN_PAL_STATUS_E_RESOURCES; + } + + /* Event type, where it must be defined???? */ + /* THIS MUST BE CLEARED ASAP + txCompMsg->type = TX_COMPLETE; */ + rxCompMsg->callback = dxeRxThreadSetPowerStateEventHandler; + rxCompMsg->pContext = pDxeCtrlBlk; + rxCompMsg->val = hostPowerState; + rxCompMsg->ptr = cBack; + status = wpalPostRxMsg(WDI_GET_PAL_CTX(), + rxCompMsg); + if ( eWLAN_PAL_STATUS_SUCCESS != status ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Rx thread Set power state req serialize fail status=%d", + status); + } + } + else + { + if ( WLANDXE_POWER_STATE_FULL == hostPowerState ) + { + if( WLANDXE_POWER_STATE_BMPS == pDxeCtrlBlk->hostPowerState ) + { + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + } + else if( WLANDXE_POWER_STATE_IMPS == pDxeCtrlBlk->hostPowerState ) + { + /* Requested Full power from exit IMPS, reenable the interrupts*/ + if(eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS) + { + pDxeCtrlBlk->rxIntDisabledByIMPS = eWLAN_PAL_FALSE; + /* Enable RX interrupt at here, if new PS is not IMPS */ + status = wpalEnableInterrupt(DXE_INTERRUPT_RX_READY); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Enable RX ready interrupt fail", __func__); + return status; + } + } + if(eWLAN_PAL_TRUE == pDxeCtrlBlk->txIntDisabledByIMPS) + { + pDxeCtrlBlk->txIntDisabledByIMPS = eWLAN_PAL_FALSE; + pDxeCtrlBlk->txIntEnable = eWLAN_PAL_TRUE; + /* Enable RX interrupt at here, if new PS is not IMPS */ + status = wpalEnableInterrupt(DXE_INTERRUPT_TX_COMPLE); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Enable TX comp interrupt fail", __func__); + return status; + } + } + } + pDxeCtrlBlk->hostPowerState = hostPowerState; + pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_ACTIVE; + } + else if ( hostPowerState == WLANDXE_POWER_STATE_BMPS ) + { + pDxeCtrlBlk->hostPowerState = hostPowerState; + pDxeCtrlBlk->rivaPowerState = WLANDXE_RIVA_POWER_STATE_BMPS_UNKNOWN; + } + else if ( hostPowerState == WLANDXE_POWER_STATE_IMPS ) + { + pDxeCtrlBlk->hostPowerState = WLANDXE_POWER_STATE_IMPS; + } + else + { + HDXE_ASSERT(0); + } + DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_POWER_STATE, + pDxeCtrlBlk->hostPowerState)); + } + + if (WDTS_POWER_STATE_FULL == powerState && + WLANDXE_POWER_STATE_FULL == pDxeCtrlBlk->hostPowerState) { + state = wpal_get_int_state(DXE_INTERRUPT_RX_READY); + if (0 == state && eWLAN_PAL_TRUE == pDxeCtrlBlk->rxIntDisabledByIMPS) { + dxeEnvBlk.rx_imps_set_fp = 1; + WARN_ON(1); + } + } + + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Exit", __func__); + + return status; +} + +/*========================================================================== + @ Function Name + WLANDXE_GetFreeTxDataResNumber + + @ Description + Returns free descriptor numbers for TX data channel (TX high priority) + + @ Parameters + pVoid pDXEContext : DXE Control Block + + @ Return + wpt_uint32 Free descriptor number of TX high pri ch +===========================================================================*/ +wpt_uint32 WLANDXE_GetFreeTxDataResNumber +( + void *pDXEContext +) +{ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "%s Enter", __func__); + + if(NULL == pDXEContext) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "NULL parameter passed by caller"); + return (0); + } + + return ((WLANDXE_CtrlBlkType *)pDXEContext)->dxeChannel[WDTS_CHANNEL_TX_LOW_PRI].numFreeDesc; +} + +/*========================================================================== + @ Function Name + WLANDXE_ChannelDebug + + @ Description + Display DXE Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + @ Parameters + displaySnapshot : Display DXE snapshot option + debugFlags : Enable stall detect features + defined by WPAL_DeviceDebugFlags + These features may effect + data performance. + + @ Return + NONE + +===========================================================================*/ +void WLANDXE_ChannelDebug +( + wpt_boolean displaySnapshot, + wpt_uint8 debugFlags +) +{ + wpt_msg *channelDebugMsg; + wpt_msg *txDescReSyncMsg ; + wpt_uint32 regValue, regValueLocal = 0; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + /* Debug Type 1, Display current snapshot */ + if(displaySnapshot) + { + /* Whatever RIVA power condition try to wakeup RIVA through SMSM + * This will not simply wakeup RIVA + * Just incase TX not wanted stuck, Trigger TX again */ + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + /* Get free BD count */ + wpalSleep(10); + wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU, ®Value); +#ifdef WCN_PRONTO + wpalReadRegister(WLANDXE_BMU_AVAILABLE_BD_PDU_LOCAL, ®ValueLocal); +#endif + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "===== DXE Dump Start HPS %d, FWS %d, TX PFC %d, ABD %d, ABD LOCAL %d =====", + tempDxeCtrlBlk->hostPowerState, tempDxeCtrlBlk->rivaPowerState, + tempDxeCtrlBlk->txCompletedFrames, regValue, regValueLocal); + + wpalPacketStallUpdateInfo((wpt_uint32 *)&tempDxeCtrlBlk->rivaPowerState, + ®Value, + NULL, + 0); + + channelDebugMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == channelDebugMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WLANDXE_ChannelDebug, MSG MEM alloc Fail"); + return ; + } + + channelDebugMsg->callback = dxeRxThreadChannelDebugHandler; + status = wpalPostRxMsg(WDI_GET_PAL_CTX(), channelDebugMsg); + if ( eWLAN_PAL_STATUS_SUCCESS != status ) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Tx thread Set power state req serialize fail status=%d", + status); + } + } + + if(debugFlags & WPAL_DEBUG_TX_DESC_RESYNC) + { + txDescReSyncMsg = (wpt_msg *)wpalMemoryAllocate(sizeof(wpt_msg)); + if(NULL == txDescReSyncMsg) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Resync MSG MEM alloc Fail",__func__); + } + else + { + txDescReSyncMsg->callback = dxeDebugTxDescReSync; + txDescReSyncMsg->pContext = tempDxeCtrlBlk; + status = wpalPostTxMsg(WDI_GET_PAL_CTX(), + txDescReSyncMsg); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Post TX re-sync MSG fail",__func__); + } + } + } + + return; +} + +/*========================================================================== + @ Function Name + WLANDXE_KickDxe + + @ Description + Kick DXE when HDD TX time out happen + + @ Parameters + NONE + + @ Return + NONE + +===========================================================================*/ +void WLANDXE_KickDxe(void) +{ + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Kick Dxe for HDD TX timeout",__func__); + /* Make wake up HW */ + dxeNotifySmsm(eWLAN_PAL_FALSE, eWLAN_PAL_TRUE); + dxeNotifySmsm(eWLAN_PAL_TRUE, eWLAN_PAL_FALSE); + DXTRACE(dxeTrace(WLANDXE_DMA_CHANNEL_MAX, TRACE_SMSM_NOTIFY, + TRACE_WLANDXE_VAR_ENABLE)); +} + +wpt_uint32 WLANDXE_SetupLogTransfer(wpt_uint64 bufferAddr, wpt_uint32 bufferLen) +{ + WLANDXE_ChannelCBType *channelEntry; + + channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG]; + + + return dxeRXLogRefillRing(tempDxeCtrlBlk, channelEntry, bufferAddr, + bufferLen); +} + +wpt_status WLANDXE_StartLogTransfer(void) +{ + WLANDXE_ChannelCBType *channelEntry; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + channelEntry = &tempDxeCtrlBlk->dxeChannel[WDTS_CHANNEL_RX_FW_LOG]; + + tempDxeCtrlBlk->hostInitiatedH2H = 1; + status = wpalWriteRegister(channelEntry->channelRegister.chDXEDesclRegAddr, + channelEntry->headCtrlBlk->linkedDescPhyAddr); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Write DESC Address register fail", __func__); + return status; + } + + status = wpalWriteRegister(channelEntry->channelRegister.chDXECtrlRegAddr, + channelEntry->extraConfig.chan_mask); + if(eWLAN_PAL_STATUS_SUCCESS != status) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeChannelInitProgram Write RX Control register fail"); + return status; + } + return status; +} diff --git a/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_cfg_i.c b/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_cfg_i.c new file mode 100644 index 000000000000..4d6b57bd0b7d --- /dev/null +++ b/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_cfg_i.c @@ -0,0 +1,729 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + @file wlan_qct_dxe_cfg_i.c + + @brief + + This file contains the external API exposed by the wlan data transfer abstraction layer module. +========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/03/10 schang Created module. + +===========================================================================*/ + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_dxe_i.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +typedef struct +{ + WDTS_ChannelType wlanChannel; + WLANDXE_DMAChannelType DMAChannel; + WLANDXE_ChannelConfigType *channelConfig; +} WLANDXE_ChannelMappingType; + +wpt_uint32 channelBaseAddressList[WLANDXE_DMA_CHANNEL_MAX] = +{ + WLANDXE_DMA_CHAN0_BASE_ADDRESS, + WLANDXE_DMA_CHAN1_BASE_ADDRESS, + WLANDXE_DMA_CHAN2_BASE_ADDRESS, + WLANDXE_DMA_CHAN3_BASE_ADDRESS, + WLANDXE_DMA_CHAN4_BASE_ADDRESS, + WLANDXE_DMA_CHAN5_BASE_ADDRESS, + WLANDXE_DMA_CHAN6_BASE_ADDRESS, + WLANDXE_DMA_CHAN7_BASE_ADDRESS +}; + +wpt_uint32 channelInterruptMask[WLANDXE_DMA_CHANNEL_MAX] = +{ + WLANDXE_INT_MASK_CHAN_0, + WLANDXE_INT_MASK_CHAN_1, + WLANDXE_INT_MASK_CHAN_2, + WLANDXE_INT_MASK_CHAN_3, + WLANDXE_INT_MASK_CHAN_4, + WLANDXE_INT_MASK_CHAN_5, + WLANDXE_INT_MASK_CHAN_6, + WLANDXE_INT_MASK_CHAN_7 +}; + +WLANDXE_ChannelConfigType chanTXLowPriConfig = +{ + /* Q handle type, Circular */ + WLANDXE_CHANNEL_HANDLE_CIRCULA, + + /* Number of Descriptor, NOT CLEAR YET !!! */ + WLANDXE_LO_PRI_RES_NUM , + + /* MAX num RX Buffer */ + 0, + + /* Reference WQ, TX23 */ + 23, + + /* USB Only, End point info */ + 0, + + /* Transfer Type */ + WLANDXE_DESC_CTRL_XTYPE_H2B, + + /* Channel Priority 7(Highest) - 0(Lowest) NOT CLEAR YET !!! */ + 4, + + /* BD attached to frames for this pipe */ + eWLAN_PAL_TRUE, + + /* chk_size, NOT CLEAR YET !!!*/ + 0, + + /* bmuThdSel, NOT CLEAR YET !!! */ + 5, + + /* Added in Gen5 for Prefetch, NOT CLEAR YET !!! */ + eWLAN_PAL_TRUE, + + /* Use short Descriptor */ + eWLAN_PAL_TRUE +}; + +WLANDXE_ChannelConfigType chanTXHighPriConfig = +{ + /* Q handle type, Circular */ + WLANDXE_CHANNEL_HANDLE_CIRCULA, + + /* Number of Descriptor, NOT CLEAR YET !!! */ + WLANDXE_HI_PRI_RES_NUM , + + /* MAX num RX Buffer */ + 0, + + /* Reference WQ, TX23 */ + 23, + + /* USB Only, End point info */ + 0, + + /* Transfer Type */ + WLANDXE_DESC_CTRL_XTYPE_H2B, + + /* Channel Priority 7(Highest) - 0(Lowest), NOT CLEAR YET !!! */ + 6, + + /* BD attached to frames for this pipe */ + eWLAN_PAL_TRUE, + + /* chk_size, NOT CLEAR YET !!!*/ + 0, + + /* bmuThdSel, NOT CLEAR YET !!! */ + 7, + + /* Added in Gen5 for Prefetch, NOT CLEAR YET !!!*/ + eWLAN_PAL_TRUE, + + /* Use short Descriptor */ + eWLAN_PAL_TRUE +}; + +WLANDXE_ChannelConfigType chanRXLowPriConfig = +{ + /* Q handle type, Circular */ + WLANDXE_CHANNEL_HANDLE_CIRCULA, + + /* Number of Descriptor, NOT CLEAR YET !!! */ + 256, + + /* MAX num RX Buffer, NOT CLEAR YET !!! */ + 1, + + /* Reference WQ, NOT CLEAR YET !!! */ + /* Temporary BMU Work Q 4 */ + 11, + + /* USB Only, End point info */ + 0, + + /* Transfer Type */ + WLANDXE_DESC_CTRL_XTYPE_B2H, + + /* Channel Priority 7(Highest) - 0(Lowest), NOT CLEAR YET !!! */ + 5, + + /* BD attached to frames for this pipe */ + eWLAN_PAL_TRUE, + + /* chk_size, NOT CLEAR YET !!!*/ + 0, + + /* bmuThdSel, NOT CLEAR YET !!! */ + 6, + + /* Added in Gen5 for Prefetch, NOT CLEAR YET !!!*/ + eWLAN_PAL_TRUE, + + /* Use short Descriptor */ + eWLAN_PAL_TRUE +}; + +WLANDXE_ChannelConfigType chanRXHighPriConfig = +{ + /* Q handle type, Circular */ + WLANDXE_CHANNEL_HANDLE_CIRCULA, + + /* Number of Descriptor, NOT CLEAR YET !!! */ + 256, + + /* MAX num RX Buffer, NOT CLEAR YET !!! */ + 1, + + /* Reference WQ, RX11 */ + 4, + + /* USB Only, End point info */ + 0, + + /* Transfer Type */ + WLANDXE_DESC_CTRL_XTYPE_B2H, + + /* Channel Priority 7(Highest) - 0(Lowest), NOT CLEAR YET !!! */ + 6, + + /* BD attached to frames for this pipe */ + eWLAN_PAL_TRUE, + + /* chk_size, NOT CLEAR YET !!!*/ + 0, + + /* bmuThdSel, NOT CLEAR YET !!! */ + 8, + + /* Added in Gen5 for Prefetch, NOT CLEAR YET !!!*/ + eWLAN_PAL_TRUE, + + /* Use short Descriptor */ + eWLAN_PAL_TRUE +}; + +WLANDXE_ChannelConfigType chanRXLogConfig = +{ + /* Q handle type, Circular */ + WLANDXE_CHANNEL_HANDLE_CIRCULA, + + /* Number of Descriptors*/ + 8, + + /* MAX num RX Buffer*/ + 1, + + /* Reference WQ, RX23 */ + 23, + + /* USB Only, End point info */ + 0, + + /* Transfer Type */ + WLANDXE_DESC_CTRL_XTYPE_B2H, + + /* Channel Priority 7(Highest) - 0(Lowest)*/ + 1, + + /* BD attached to frames for this pipe */ + eWLAN_PAL_TRUE, + + /* chk_size*/ + 0, + + /* bmuThdSel*/ + 8, + + /* Added in Gen5 for Prefetch*/ + eWLAN_PAL_TRUE, + + /* Use short Descriptor */ + eWLAN_PAL_TRUE +}; + +WLANDXE_ChannelConfigType chanRXFWLogConfig = +{ + /* Q handle type, Circular */ + WLANDXE_CHANNEL_HANDLE_CIRCULA, + + /* Number of Descriptors*/ + 32, + + /* MAX num RX Buffer*/ + 1, + + /* Reference WQ - NA as channel used for H2H */ + 0, + + /* USB Only, End point info */ + 0, + + /* Transfer Type */ + WLANDXE_DESC_CTRL_XTYPE_H2H, + + /* Channel Priority 7(Highest) - 0(Lowest)*/ + 0, + + /* BD attached to frames for this pipe */ + eWLAN_PAL_TRUE, + + /* chk_size*/ + 0, + + /* bmuThdSel*/ + 8, + + /* Added in Gen5 for Prefetch*/ + eWLAN_PAL_TRUE, + + /* Use short Descriptor */ + eWLAN_PAL_TRUE +}; + +WLANDXE_ChannelMappingType channelList[WDTS_CHANNEL_MAX] = +{ + {WDTS_CHANNEL_TX_LOW_PRI, WLANDXE_DMA_CHANNEL_0, &chanTXLowPriConfig}, + {WDTS_CHANNEL_TX_HIGH_PRI, WLANDXE_DMA_CHANNEL_4, &chanTXHighPriConfig}, + {WDTS_CHANNEL_RX_LOW_PRI, WLANDXE_DMA_CHANNEL_1, &chanRXLowPriConfig}, + {WDTS_CHANNEL_RX_HIGH_PRI, WLANDXE_DMA_CHANNEL_3, &chanRXHighPriConfig}, + {WDTS_CHANNEL_RX_LOG, WLANDXE_DMA_CHANNEL_5, &chanRXLogConfig}, + {WDTS_CHANNEL_RX_FW_LOG, WLANDXE_DMA_CHANNEL_7, &chanRXFWLogConfig}, +}; + +WLANDXE_TxCompIntConfigType txCompInt = +{ + /* TX Complete Interrupt enable method */ + WLANDXE_TX_COMP_INT_PER_K_FRAMES, + + /* TX Low Resource remaining resource threshold for Low Pri Ch */ + WLANDXE_TX_LOW_RES_THRESHOLD, + + /* TX Low Resource remaining resource threshold for High Pri Ch */ + WLANDXE_TX_LOW_RES_THRESHOLD, + + /* RX Low Resource remaining resource threshold */ + 5, + + /* Per K frame enable Interrupt */ + /*WLANDXE_HI_PRI_RES_NUM*/ 5, + + /* Periodic timer msec */ + 10 +}; + +// Indicates the DXE channels being used in the current run. +static wpt_uint8 dxeEnabledChannels; + +/*========================================================================== + @ Function Name + dxeSetEnabledChannels + + @ Description + + @ Parameters + + @ Return + void + +===========================================================================*/ +void dxeSetEnabledChannels +( + wpt_uint8 enabledChannels +) +{ + dxeEnabledChannels = enabledChannels; +} + +/*========================================================================== + @ Function Name + dxeGetEnabledChannels + + @ Description + + @ Parameters + + @ Return + wpt_uint8 + +===========================================================================*/ +wpt_uint8 dxeGetEnabledChannels +( + void +) +{ + return dxeEnabledChannels; +} + +/*========================================================================== + @ Function Name + dxeCommonDefaultConfig + + @ Description + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + + @ Return + void + +===========================================================================*/ +void dxeCommonDefaultConfig +( + WLANDXE_CtrlBlkType *dxeCtrlBlk +) +{ + dxeCtrlBlk->rxReadyCB = NULL; + dxeCtrlBlk->txCompCB = NULL; + dxeCtrlBlk->lowResourceCB = NULL; + + wpalMemoryCopy(&dxeCtrlBlk->txCompInt, + &txCompInt, + sizeof(WLANDXE_TxCompIntConfigType)); +} + +/*========================================================================== + @ Function Name + dxeChannelDefaultConfig + + @ Description + Get defualt configuration values from pre defined structure + All the channels must have it's own configurations + + @ Parameters + WLANDXE_CtrlBlkType: *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +wpt_status dxeChannelDefaultConfig +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_uint32 baseAddress; + wpt_uint32 dxeControlRead = 0; + wpt_uint32 dxeControlWrite = 0; + wpt_uint32 dxeControlWriteValid = 0; + wpt_uint32 dxeControlWriteEop = 0; + wpt_uint32 dxeControlWriteEopInt = 0; + wpt_uint32 idx; + wpt_uint32 rxResourceCount = 0; + WLANDXE_ChannelMappingType *mappedChannel = NULL; + + /* Sanity Check */ + if((NULL == dxeCtrlBlk) || (NULL == channelEntry)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "dxeLinkDescAndCtrlBlk Channel Entry is not valid"); + return eWLAN_PAL_STATUS_E_INVAL; + } + + for(idx = 0; idx < WDTS_CHANNEL_MAX; idx++) + { + if(channelEntry->channelType == channelList[idx].wlanChannel) + { + mappedChannel = &channelList[idx]; + break; + } + } + + if((NULL == mappedChannel) || (WDTS_CHANNEL_MAX == idx)) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Failed to map channel", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + wpalMemoryCopy(&channelEntry->channelConfig, + mappedChannel->channelConfig, + sizeof(WLANDXE_ChannelConfigType)); + + baseAddress = channelBaseAddressList[mappedChannel->DMAChannel]; + channelEntry->channelRegister.chDXEBaseAddr = baseAddress; + channelEntry->channelRegister.chDXEStatusRegAddr = baseAddress + WLANDXE_DMA_CH_STATUS_REG; + channelEntry->channelRegister.chDXEDesclRegAddr = baseAddress + WLANDXE_DMA_CH_DESCL_REG; + channelEntry->channelRegister.chDXEDeschRegAddr = baseAddress + WLANDXE_DMA_CH_DESCH_REG; + channelEntry->channelRegister.chDXELstDesclRegAddr = baseAddress + WLANDXE_DMA_CH_LST_DESCL_REG; + channelEntry->channelRegister.chDXECtrlRegAddr = baseAddress + WLANDXE_DMA_CH_CTRL_REG; + channelEntry->channelRegister.chDXESzRegAddr = baseAddress + WLANDXE_DMA_CH_SZ_REG; + channelEntry->channelRegister.chDXEDadrlRegAddr = baseAddress + WLANDXE_DMA_CH_DADRL_REG; + channelEntry->channelRegister.chDXEDadrhRegAddr = baseAddress + WLANDXE_DMA_CH_DADRH_REG; + channelEntry->channelRegister.chDXESadrlRegAddr = baseAddress + WLANDXE_DMA_CH_SADRL_REG; + channelEntry->channelRegister.chDXESadrhRegAddr = baseAddress + WLANDXE_DMA_CH_SADRH_REG; + + /* Channel Mask? + * This value will control channel control register. + * This register will be set to trigger actual DMA transfer activate + * CH_N_CTRL */ + channelEntry->extraConfig.chan_mask = 0; + /* Check VAL bit before processing descriptor */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_EDVEN_MASK; + /* Use External Descriptor Linked List */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_EDEN_MASK; + /* Enable Channel Interrupt on error */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_INE_ERR_MASK; + /* Enable INT after XFER done */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_INE_DONE_MASK; + /* Enable INT External Descriptor */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_INE_ED_MASK; + /* Set Channel This is not channel, event counter, somthing wrong */ + channelEntry->extraConfig.chan_mask |= + mappedChannel->DMAChannel << WLANDXE_CH_CTRL_CTR_SEL_OFFSET; + /* Transfer Type */ + channelEntry->extraConfig.chan_mask |= mappedChannel->channelConfig->xfrType; + /* Use Short Descriptor, THIS LOOKS SOME WIERD, REVISIT */ + if(!channelEntry->channelConfig.useShortDescFmt) + { + channelEntry->extraConfig.chan_mask |= WLANDXE_DESC_CTRL_DFMT; + } + /* TX Channel, Set DIQ bit, Clear SIQ bit since source is not WQ */ + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType)) + { + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_DIQ_MASK; + if (wpalWcnssIsProntoHwVer3()) + { + HDXE_MSG(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "Using WQ 6 for TX Low/High PRI Channel"); + channelEntry->channelConfig.refWQ = WLANDXE_PRONTO_TX_WQ; + } + } + /* RX Channel, Set SIQ bit, Clear DIQ bit since source is not WQ */ + else if((WDTS_CHANNEL_RX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_HIGH_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_LOG == channelEntry->channelType)) + { + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_SIQ_MASK; + } + else + { + /* This is H2H channel, TX, RX not use work Q + * Do Nothing */ + } + + if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType) + { + /* Frame Contents Swap */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_SWAP_MASK; + } + /* Host System Using Little Endian */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_ENDIAN_MASK; + /* BMU Threshold select */ + channelEntry->extraConfig.chan_mask |= + channelEntry->channelConfig.bmuThdSel << WLANDXE_CH_CTRL_BTHLD_SEL_OFFSET; + /* EOP for control register ??? */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_EOP_MASK; + /* Channel Priority */ + channelEntry->extraConfig.chan_mask |= channelEntry->channelConfig.chPriority << WLANDXE_CH_CTRL_PRIO_OFFSET; + /* PDU REL */ + channelEntry->extraConfig.chan_mask |= WLANDXE_DESC_CTRL_PDU_REL; + /* Disable DMA transfer on this channel */ + channelEntry->extraConfig.chan_mask_read_disable = channelEntry->extraConfig.chan_mask; + /* Enable DMA transfer on this channel */ + channelEntry->extraConfig.chan_mask |= WLANDXE_CH_CTRL_EN_MASK; + /* Channel Mask done */ + + /* Control Read + * Default Descriptor control Word value for RX ready DXE descriptor + * DXE engine will reference this value before DMA transfer */ + dxeControlRead = 0; + /* Source is a Queue ID, not flat memory address */ + if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType) + dxeControlRead |= WLANDXE_DESC_CTRL_SIQ; + /* Transfer direction is BMU 2 Host */ + if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType) + dxeControlRead |= WLANDXE_DESC_CTRL_XTYPE_B2H; + else + dxeControlRead |= WLANDXE_DESC_CTRL_XTYPE_H2H; + + /* End of Packet, RX is single fragment */ + dxeControlRead |= WLANDXE_DESC_CTRL_EOP; + /* BD Present, default YES, B2H case it must be 0 to insert BD */ + if(!channelEntry->channelConfig.bdPresent) + { + dxeControlRead |= WLANDXE_DESC_CTRL_BDH; + } + /* Channel Priority */ + dxeControlRead |= channelEntry->channelConfig.chPriority << WLANDXE_CH_CTRL_PRIO_OFFSET; + /* BMU Threshold select, only used H2B, not this case??? */ + dxeControlRead |= channelEntry->channelConfig.bmuThdSel << WLANDXE_CH_CTRL_BTHLD_SEL_OFFSET; + /* PDU Release, Release BD/PDU when DMA done */ + dxeControlRead |= WLANDXE_DESC_CTRL_PDU_REL; + /* Use Short Descriptor, THIS LOOKS SOME WIERD, REVISIT */ + if(!channelEntry->channelConfig.useShortDescFmt) + { + dxeControlRead |= WLANDXE_DESC_CTRL_DFMT; + } + /* Interrupt on Descriptor done */ + dxeControlRead |= WLANDXE_DESC_CTRL_INT; + /* For ready status, this Control WORD must be VALID */ + dxeControlRead |= WLANDXE_DESC_CTRL_VALID; + + /* Frame Contents Swap */ + if (WDTS_CHANNEL_RX_FW_LOG != channelEntry->channelType) + dxeControlRead |= WLANDXE_DESC_CTRL_BDT_SWAP; + + /* Host Little Endian */ + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_TX_HIGH_PRI == channelEntry->channelType) || + (WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType)) + { + dxeControlRead |= WLANDXE_DESC_CTRL_ENDIANNESS; + } + + /* SWAP if needed */ + channelEntry->extraConfig.cw_ctrl_read = WLANDXE_U32_SWAP_ENDIAN(dxeControlRead); + /* Control Read Done */ + + /* Control Write + * Write into DXE descriptor control word to TX frame + * DXE engine will reference this word to contorl TX DMA channel */ + channelEntry->extraConfig.cw_ctrl_write = 0; + /* Transfer type, from Host 2 BMU */ + dxeControlWrite |= mappedChannel->channelConfig->xfrType; + /* BD Present, this looks some weird ??? */ + if(!channelEntry->channelConfig.bdPresent) + { + dxeControlWrite |= WLANDXE_DESC_CTRL_BDH; + } + /* Channel Priority */ + dxeControlWrite |= channelEntry->channelConfig.chPriority << WLANDXE_CH_CTRL_PRIO_OFFSET; + /* Use Short Descriptor, THIS LOOKS SOME WIERD, REVISIT */ + if(!channelEntry->channelConfig.useShortDescFmt) + { + dxeControlWrite |= WLANDXE_DESC_CTRL_DFMT; + } + /* BMU Threshold select, only used H2B, not this case??? */ + dxeControlWrite |= channelEntry->channelConfig.bmuThdSel << WLANDXE_CH_CTRL_BTHLD_SEL_OFFSET; + /* Destination is WQ */ + dxeControlWrite |= WLANDXE_DESC_CTRL_DIQ; + /* Frame Contents Swap */ + dxeControlWrite |= WLANDXE_DESC_CTRL_BDT_SWAP; + /* Host Little Endian */ + dxeControlWrite |= WLANDXE_DESC_CTRL_ENDIANNESS; + /* Interrupt Enable */ + dxeControlWrite |= WLANDXE_DESC_CTRL_INT; + + dxeControlWriteValid = dxeControlWrite | WLANDXE_DESC_CTRL_VALID; + dxeControlWriteEop = dxeControlWriteValid | WLANDXE_DESC_CTRL_EOP; + dxeControlWriteEopInt = dxeControlWriteEop | WLANDXE_DESC_CTRL_INT; + + /* DXE Descriptor must has Endian swapped value */ + channelEntry->extraConfig.cw_ctrl_write = WLANDXE_U32_SWAP_ENDIAN(dxeControlWrite); + /* Control Write DONE */ + + /* Control Write include VAL bit + * This Control word used to set valid bit and + * trigger DMA transfer for specific descriptor */ + channelEntry->extraConfig.cw_ctrl_write_valid = + WLANDXE_U32_SWAP_ENDIAN(dxeControlWriteValid); + + /* Control Write include EOP + * End of Packet */ + channelEntry->extraConfig.cw_ctrl_write_eop = + WLANDXE_U32_SWAP_ENDIAN(dxeControlWriteEop); + + /* Control Write include EOP and INT + * indicate End Of Packet and generate interrupt on descriptor Done */ + channelEntry->extraConfig.cw_ctrl_write_eop_int = + WLANDXE_U32_SWAP_ENDIAN(dxeControlWriteEopInt); + + + /* size mask???? */ + channelEntry->extraConfig.chk_size_mask = + mappedChannel->channelConfig->chk_size << 10; + + channelEntry->extraConfig.refWQ_swapped = + WLANDXE_U32_SWAP_ENDIAN(channelEntry->channelConfig.refWQ); + + /* Set Channel specific Interrupt mask */ + channelEntry->extraConfig.intMask = channelInterruptMask[mappedChannel->DMAChannel]; + + + wpalGetNumRxRawPacket(&rxResourceCount); + if((WDTS_CHANNEL_TX_LOW_PRI == channelEntry->channelType) || + (0 == rxResourceCount)) + { + channelEntry->numDesc = mappedChannel->channelConfig->nDescs; + } + else if(WDTS_CHANNEL_RX_LOG == channelEntry->channelType) + { + channelEntry->numDesc = mappedChannel->channelConfig->nDescs; + } + else if(WDTS_CHANNEL_RX_FW_LOG == channelEntry->channelType) + { + channelEntry->numDesc = mappedChannel->channelConfig->nDescs; + } + else + { + channelEntry->numDesc = rxResourceCount / 4; + } + channelEntry->assignedDMAChannel = mappedChannel->DMAChannel; + channelEntry->numFreeDesc = 0; + channelEntry->numRsvdDesc = 0; + channelEntry->desc_write_fail_count = 0; + channelEntry->numFragmentCurrentChain = 0; + channelEntry->numTotalFrame = 0; + channelEntry->hitLowResource = eWLAN_PAL_FALSE; + + return status; +} diff --git a/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_i.h b/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_i.h new file mode 100644 index 000000000000..9c2eb8f337de --- /dev/null +++ b/drivers/staging/prima/CORE/DXE/src/wlan_qct_dxe_i.h @@ -0,0 +1,814 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_DXE_I_H +#define WLAN_QCT_DXE_I_H + +/**========================================================================= + + @file wlan_qct_dxe_i.h + + @brief + + This file contains the external API exposed by the wlan data transfer abstraction layer module. +========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/03/10 schang Created module. + +===========================================================================*/ + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_dxe.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_pal_timer.h" +#include "vos_trace.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WLANDXE_CTXT_COOKIE 0xC00CC111 + +#ifdef DXE_TRACE +#define DXTRACE(p) p +#else +#define DXTRACE(p) { } +#endif + +#define foreach_valid_channel(idx) \ + for (idx = 0; idx < WDTS_CHANNEL_MAX; idx++) \ + if (!(dxeGetEnabledChannels() & 1<> 8) | \ + ((a & 0xFF000000) >> 24)) +#else +/* If DXE HW does not need endian swap, DO NOTHING */ +#define WLANDXE_U32_SWAP_ENDIAN(a) (a) +#endif /* WLANDXE_ENDIAN_SWAP_ENABLE */ + +/* Log Definition will be mappped with PAL MSG */ +#define HDXE_MSG WPAL_TRACE +#define HDXE_ASSERT(a) VOS_ASSERT(a) + +#define WLANDXE_PRONTO_TX_WQ 0x6 +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/* DMA Channel Q handle Method type + * Linear handle or circular */ +typedef enum +{ + WLANDXE_CHANNEL_HANDLE_LINEAR, + WLANDXE_CHANNEL_HANDLE_CIRCULA +}WLANDXE_ChannelHandleType; + +typedef enum +{ + WLANDXE_TX_COMP_INT_LR_THRESHOLD, + WLANDXE_TX_COMP_INT_PER_K_FRAMES, + WLANDXE_TX_COMP_INT_TIMER +} WLANDXE_TXCompIntEnableType; + +typedef enum +{ + WLANDXE_SHORT_DESCRIPTOR, + WLANDXE_LONG_DESCRIPTOR +} WLANDXE_DescriptorType; + +typedef enum +{ + WLANDXE_DMA_CHANNEL_0, + WLANDXE_DMA_CHANNEL_1, + WLANDXE_DMA_CHANNEL_2, + WLANDXE_DMA_CHANNEL_3, + WLANDXE_DMA_CHANNEL_4, + WLANDXE_DMA_CHANNEL_5, + WLANDXE_DMA_CHANNEL_6, + WLANDXE_DMA_CHANNEL_7, + WLANDXE_DMA_CHANNEL_MAX +} WLANDXE_DMAChannelType; + +enum +{ + TRACE_CH_ENABLE, + TRACE_POWER_STATE, + TRACE_RXINT_STATE, + TRACE_TXINT_STATE, + TRACE_SMSM_NOTIFY +}; + +/** DXE HW Long Descriptor format */ +typedef struct +{ + wpt_uint32 srcMemAddrL; + wpt_uint32 srcMemAddrH; + wpt_uint32 dstMemAddrL; + wpt_uint32 dstMemAddrH; + wpt_uint32 phyNextL; + wpt_uint32 phyNextH; +} WLANDXE_LongDesc; + + +/** DXE HW Short Descriptor format */ +typedef struct tDXEShortDesc +{ + wpt_uint32 srcMemAddrL; + wpt_uint32 dstMemAddrL; + wpt_uint32 phyNextL; +} WLANDXE_ShortDesc; + + +/* DXE Descriptor Data Type + * Pick up from GEN5 */ +typedef struct +{ + union + { + wpt_uint32 ctrl; + wpt_uint32 valid :1; //0 = DMA stop, 1 = DMA continue with this descriptor + wpt_uint32 transferType :2; //0 = Host to Host space + wpt_uint32 eop :1; //End of Packet + wpt_uint32 bdHandling :1; //if transferType = Host to BMU, then 0 means first 128 bytes contain BD, and 1 means create new empty BD + wpt_uint32 siq :1; // SIQ + wpt_uint32 diq :1; // DIQ + wpt_uint32 pduRel :1; //0 = don't release BD and PDUs when done, 1 = release them + wpt_uint32 bthldSel :4; //BMU Threshold Select + wpt_uint32 prio :3; //Specifies the priority level to use for the transfer + wpt_uint32 stopChannel :1; //1 = DMA stops processing further, channel requires re-enabling after this + wpt_uint32 intr :1; //Interrupt on Descriptor Done + wpt_uint32 rsvd :1; //reserved + wpt_uint32 transferSize :14; //14 bits used - ignored for BMU transfers, only used for host to host transfers? + } descCtrl; + wpt_uint32 xfrSize; + union + { + WLANDXE_LongDesc dxe_long_desc; + WLANDXE_ShortDesc dxe_short_desc; + }dxedesc; +} WLANDXE_DescType; + +typedef struct +{ + void *nextCtrlBlk; + wpt_packet *xfrFrame; + WLANDXE_DescType *linkedDesc; + wpt_uint32 linkedDescPhyAddr; + wpt_uint32 ctrlBlkOrder; +} WLANDXE_DescCtrlBlkType; + +typedef struct +{ + /* Q handle method, linear or ring */ + WLANDXE_ChannelHandleType queueMethod; + + /* Number of descriptors for DXE that can be queued for transfer at one time */ + wpt_uint32 nDescs; + + /* Maximum number of receive buffers of shared memory to use for this pipe */ + wpt_uint32 nRxBuffers; + + /* Reference WQ - for H2B and B2H only */ + wpt_uint32 refWQ; + + /* for usb only, endpoint info for CH_SADR or CH_DADR */ + wpt_uint32 refEP; + + /* H2B(Tx), B2H(Rx), H2H(SRAM<->HostMem R/W) */ + wpt_uint32 xfrType; + + /* Channel Priority 7(Highest) - 0(Lowest) */ + wpt_uint32 chPriority; + + /* 1 = BD attached to frames for this pipe */ + wpt_boolean bdPresent; + + wpt_uint32 chk_size; + + wpt_uint32 bmuThdSel; + + /* Added in Gen5 for Prefetch */ + wpt_boolean useLower4G; + + wpt_boolean useShortDescFmt; + /* Till here inharited from GEN5 code */ + /* From now on, added for PRIMA */ +} WLANDXE_ChannelConfigType; + +typedef struct +{ + wpt_uint32 chDXEBaseAddr; + wpt_uint32 chDXEStatusRegAddr; + wpt_uint32 chDXEDesclRegAddr; + wpt_uint32 chDXEDeschRegAddr; + wpt_uint32 chDXELstDesclRegAddr; + wpt_uint32 chDXECtrlRegAddr; + wpt_uint32 chDXESzRegAddr; + wpt_uint32 chDXEDadrlRegAddr; + wpt_uint32 chDXEDadrhRegAddr; + wpt_uint32 chDXESadrlRegAddr; + wpt_uint32 chDXESadrhRegAddr; +} WLANDXE_ChannelRegisterType; + +typedef struct +{ + wpt_uint32 refWQ_swapped; + wpt_boolean chEnabled; + wpt_boolean chConfigured; + wpt_uint32 channel; + wpt_uint32 chk_size_mask; + wpt_uint32 bmuThdSel_mask; + wpt_uint32 cw_ctrl_read; + wpt_uint32 cw_ctrl_write; + wpt_uint32 cw_ctrl_write_valid; + wpt_uint32 cw_ctrl_write_eop; + wpt_uint32 cw_ctrl_write_eop_int; + wpt_uint32 chan_mask; + wpt_uint32 chan_mask_read_disable; + wpt_uint32 intMask; +} WLANDXE_ChannelExConfigType; + +typedef struct +{ + WDTS_ChannelType channelType; + WLANDXE_DescCtrlBlkType *headCtrlBlk; + WLANDXE_DescCtrlBlkType *tailCtrlBlk; + WLANDXE_DescType *descriptorAllocation; + WLANDXE_DescType *DescBottomLoc; + wpt_uint32 descBottomLocPhyAddr; + wpt_uint32 numDesc; + wpt_uint32 numFreeDesc; + wpt_uint32 numRsvdDesc; + wpt_uint32 desc_write_fail_count; + wpt_uint32 maxFrameSize; + wpt_uint32 numFragmentCurrentChain; + wpt_uint32 numFrameBeforeInt; + wpt_uint32 numTotalFrame; + wpt_uint32 doneIntDisabled; + wpt_mutex dxeChannelLock; + wpt_boolean hitLowResource; + WLANDXE_ChannelConfigType channelConfig; + WLANDXE_ChannelRegisterType channelRegister; + WLANDXE_ChannelExConfigType extraConfig; + WLANDXE_DMAChannelType assignedDMAChannel; + wpt_uint64 rxDoneHistogram; +} WLANDXE_ChannelCBType; + +typedef struct +{ + WLANDXE_TXCompIntEnableType txIntEnable; + unsigned int txLowResourceThreshold_LoPriCh; + unsigned int txLowResourceThreshold_HiPriCh; + unsigned int rxLowResourceThreshold; + unsigned int txInterruptEnableFrameCount; + unsigned int txInterruptEnablePeriod; +} WLANDXE_TxCompIntConfigType; + +typedef struct +{ + WLANDXE_ChannelCBType dxeChannel[WDTS_CHANNEL_MAX]; + WLANDXE_RxFrameReadyCbType rxReadyCB; + WLANDXE_TxCompleteCbType txCompCB; + WLANDXE_LowResourceCbType lowResourceCB; + WLANDXE_MbReceiveMsgCbType receiveMbMsgCB; + WLANDXE_RxLogDoneType receiveLogCompleteCB; + WLANDXE_TxCompIntConfigType txCompInt; + void *clientCtxt; + wpt_uint32 interruptPath; + wpt_msg *rxIsrMsg; + wpt_msg *txIsrMsg; + wpt_msg *rxPktAvailMsg; + volatile WLANDXE_PowerStateType hostPowerState; + wpt_boolean rxIntDisabledByIMPS; + wpt_boolean txIntDisabledByIMPS; + WLANDXE_SetPowerStateCbType setPowerStateCb; + volatile WLANDXE_RivaPowerStateType rivaPowerState; + wpt_boolean ringNotEmpty; + wpt_boolean txIntEnable; + wpt_uint32 txCompletedFrames; + wpt_uint8 ucTxMsgCnt; + wpt_uint16 lastKickOffDxe; + wpt_uint32 smsmRingsEmptyHistogram; + wpt_uint32 smsmDxeHistogram; + wpt_uint32 dxeCookie; + wpt_packet *freeRXPacket; + wpt_boolean rxPalPacketUnavailable; + wpt_boolean driverReloadInProcessing; + wpt_boolean smsmToggled; + wpt_boolean txRingsEmpty; + wpt_boolean hostInitiatedH2H; +#ifdef WLAN_DXE_LOW_RESOURCE_TIMER + wpt_timer rxResourceAvailableTimer; +#endif + wpt_timer dxeSSRTimer; +} WLANDXE_CtrlBlkType; + +typedef struct +{ + u64 *rxIntDisableReturn; + u64 *rxIntDisableFrame; + wpt_uint8 rxIntChanlSrc; + wpt_uint8 txCmpIntChanlSrc; + wpt_uint8 rx_low_resource_timer; + wpt_uint8 dxe_prev_ps; + wpt_uint8 rx_imps_set_fp; +} WLANDXE_EnvInformation; + +typedef struct +{ + /* Records are stored in ring buffer */ + v_U32_t head; + v_U32_t tail; + v_U32_t num; + + /* Config for controlling the trace */ + v_U8_t enable; +}dxeTraceData; + +typedef struct +{ + v_U32_t time; + v_U8_t chan; + v_U8_t code; + v_U32_t data; +}dxeTraceRecord, *pdxeTraceRecord; + +/*========================================================================== + @ Function Name + dxeCommonDefaultConfig + + @ Description + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + + @ Return + void + +===========================================================================*/ +extern void dxeCommonDefaultConfig +( + WLANDXE_CtrlBlkType *dxeCtrlBlk +); + +/*========================================================================== + @ Function Name + dxeChannelDefaultConfig + + @ Description + Get defualt configuration values from pre defined structure + All the channels must have it's own configurations + + @ Parameters + WLANDXE_CtrlBlkType *dxeCtrlBlk, + DXE host driver main control block + WLANDXE_ChannelCBType *channelEntry + Channel specific control block + + @ Return + wpt_status + +===========================================================================*/ +extern wpt_status dxeChannelDefaultConfig +( + WLANDXE_CtrlBlkType *dxeCtrlBlk, + WLANDXE_ChannelCBType *channelEntry +); + +void dxeSetEnabledChannels +( + wpt_uint8 enabledChannels +); + +wpt_uint8 dxeGetEnabledChannels +( + void +); +#endif /* WLAN_QCT_DXE_I_H */ diff --git a/drivers/staging/prima/CORE/HDD/inc/bap_hdd_main.h b/drivers/staging/prima/CORE/HDD/inc/bap_hdd_main.h new file mode 100644 index 000000000000..6bfab6d45762 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/bap_hdd_main.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( BAP_HDD_MAIN_H ) +#define BAP_HDD_MAIN_H + +/**=========================================================================== + + \file BAP_HDD_MAIN_H.h + + \brief Linux HDD Adapter Type + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define BSL_MAX_CLIENTS 1 +#define BSL_MAX_PHY_LINK_PER_CLIENT 1 + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief BSL_Init() - Initialize the BSL Misc char driver + + This is called in by WLANBAP_Open() as part of bringing up the BT-AMP PAL (BAP) + WLANBAP_Open() will pass in the device context created. + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int BSL_Init (void *pCtx); + +/**--------------------------------------------------------------------------- + + \brief BSL_Deinit() - De-initialize the BSL Misc char driver + + This is called in by WLANBAP_Close() as part of bringing down the BT-AMP PAL (BAP) + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ + +int BSL_Deinit(void *pCtx); + + + +#endif // end #if !defined( BAP_HDD_MAIN_H ) diff --git a/drivers/staging/prima/CORE/HDD/inc/bap_hdd_misc.h b/drivers/staging/prima/CORE/HDD/inc/bap_hdd_misc.h new file mode 100644 index 000000000000..b373760f0b46 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/bap_hdd_misc.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( BAP_HDD_MISC_H ) +#define BAP_HDD_MISC_H + +/**=========================================================================== + + \file BAP_HDD_MISC.h + + \brief Linux HDD Adapter Type + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_SetConfig() - To updates some configuration for BAP module in + SME + + This should be called after WLANBAP_Start(). + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to set the config in SME BAP + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_SetConfig +( + WLANBAP_ConfigType *pConfig +); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_RegisterWithHCI() - To register WLAN PAL with HCI + + + \param + pAdapter : HDD adapter + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to register with HCI + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_RegisterWithHCI(hdd_adapter_t *pAdapter); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_DeregisterFromHCI() - To deregister WLAN PAL with HCI + + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to deregister with HCI + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_DeregisterFromHCI(void); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_StopAmp() - To stop the current AMP traffic/connection + + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_STATUS_E_FAILURE: failed to stop AMP connection + VOS_STATUS_SUCCESS: Success + + + --------------------------------------------------------------------------*/ +VOS_STATUS WLANBAP_StopAmp(void); + +/**--------------------------------------------------------------------------- + + \brief WLANBAP_AmpSessionOn() - To check if AMP connection is on currently + + + \param - NA + + \return - + The result code associated with performing the operation + + VOS_TRUE: AMP connection is on + VOS_FALSE: AMP connection is not on + + + --------------------------------------------------------------------------*/ +v_BOOL_t WLANBAP_AmpSessionOn(void); +#endif // end #if !defined( BAP_HDD_MISC_H ) diff --git a/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h b/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h new file mode 100644 index 000000000000..764384e14f80 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/qc_sap_ioctl.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _QC_SAP_IOCTL_H_ +#define _QC_SAP_IOCTL_H_ + +/* + * QCSAP ioctls. + */ + +/* + * Max size of optional information elements. We artificially + * constrain this; it's limited only by the max frame size (and + * the max parameter size of the wireless extensions). + */ +#define QCSAP_MAX_OPT_IE 256 +#define QCSAP_MAX_WSC_IE 256 +#define QCSAP_MAX_GET_STA_INFO 512 +#define QCSAP_MAX_STR_LEN 1024 + +typedef struct sSSID +{ + u_int8_t length; + u_int8_t ssId[32]; +} tSSID; + +typedef struct sSSIDInfo +{ + tSSID ssid; + u_int8_t ssidHidden; +}tSSIDInfo; + +typedef enum { + eQC_DOT11_MODE_ALL = 0, + eQC_DOT11_MODE_ABG = 0x0001, //11a/b/g only, no HT, no proprietary + eQC_DOT11_MODE_11A = 0x0002, + eQC_DOT11_MODE_11B = 0x0004, + eQC_DOT11_MODE_11G = 0x0008, + eQC_DOT11_MODE_11N = 0x0010, + eQC_DOT11_MODE_11G_ONLY = 0x0020, + eQC_DOT11_MODE_11N_ONLY = 0x0040, + eQC_DOT11_MODE_11B_ONLY = 0x0080, + eQC_DOT11_MODE_11A_ONLY = 0x0100, + //This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL except when it starts IBSS in 11B of 2.4GHz + //It is for CSR internal use + eQC_DOT11_MODE_AUTO = 0x0200, + +} tQcPhyMode; + +#define QCSAP_ADDR_LEN 6 + +typedef u_int8_t qcmacaddr[QCSAP_ADDR_LEN]; + +struct qc_mac_acl_entry { + qcmacaddr addr; + int vlan_id; +}; + +typedef enum { + eQC_AUTH_TYPE_OPEN_SYSTEM, + eQC_AUTH_TYPE_SHARED_KEY, + eQC_AUTH_TYPE_AUTO_SWITCH +} eQcAuthType; + +typedef enum { + eQC_WPS_BEACON_IE, + eQC_WPS_PROBE_RSP_IE, + eQC_WPS_ASSOC_RSP_IE +} eQCWPSType; + + +/* + * Retrieve the WPA/RSN information element for an associated station. + */ +struct sQcSapreq_wpaie { + u_int8_t wpa_ie[QCSAP_MAX_OPT_IE]; + u_int8_t wpa_macaddr[QCSAP_ADDR_LEN]; +}; + +/* + * Retrieve the WSC information element for an associated station. + */ +struct sQcSapreq_wscie { + u_int8_t wsc_macaddr[QCSAP_ADDR_LEN]; + u_int8_t wsc_ie[QCSAP_MAX_WSC_IE]; +}; + + +/* + * Retrieve the WPS PBC Probe Request IEs. + */ +typedef struct sQcSapreq_WPSPBCProbeReqIES { + u_int8_t macaddr[QCSAP_ADDR_LEN]; + u_int16_t probeReqIELen; + u_int8_t probeReqIE[512]; +} sQcSapreq_WPSPBCProbeReqIES_t ; + +/* + * Channel List Info + */ + +typedef struct +{ + v_U8_t num_channels; + v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tChannelListInfo, *tpChannelListInfo; + + +#ifdef __linux__ +/* + * Wireless Extensions API, private ioctl interfaces. + * + * NB: Even-numbered ioctl numbers have set semantics and are privileged! + * (regardless of the incorrect comment in wireless.h!) + */ + +#define QCSAP_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) +#define QCSAP_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+1) +#define QCSAP_IOCTL_COMMIT (SIOCIWFIRSTPRIV+2) + +#define QCSAP_IOCTL_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3) +#define WE_WOWL_ADD_PTRN 1 +#define WE_WOWL_DEL_PTRN 2 + +#define QCSAP_IOCTL_GET_STAWPAIE (SIOCIWFIRSTPRIV+4) + +#define QCSAP_IOCTL_STOPBSS (SIOCIWFIRSTPRIV+6) +#define QCSAP_IOCTL_VERSION (SIOCIWFIRSTPRIV+7) +#define QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES (SIOCIWFIRSTPRIV+8) +#define QCSAP_IOCTL_GET_CHANNEL (SIOCIWFIRSTPRIV+9) +#define QCSAP_IOCTL_ASSOC_STA_MACADDR (SIOCIWFIRSTPRIV+10) +#define QCSAP_IOCTL_DISASSOC_STA (SIOCIWFIRSTPRIV+11) +#define QCSAP_IOCTL_GET_STATS (SIOCIWFIRSTPRIV+13) +#define QCSAP_IOCTL_CLR_STATS (SIOCIWFIRSTPRIV+14) + +#define QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV+15) +#define WE_SET_WLAN_DBG 1 +#define QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV+16) +#define WE_LOG_DUMP_CMD 1 +#define QCSAP_IOCTL_SET_CHANNEL_RANGE (SIOCIWFIRSTPRIV+17) + +#define WE_P2P_NOA_CMD 2 +//IOCTL to configure MCC params +#define WE_MCC_CONFIG_CREDENTIAL 3 +#define WE_MCC_CONFIG_PARAMS 4 + +#define QCSAP_IOCTL_MODIFY_ACL (SIOCIWFIRSTPRIV+18) +#define QCSAP_IOCTL_GET_CHANNEL_LIST (SIOCIWFIRSTPRIV+19) +#define QCSAP_IOCTL_SET_TX_POWER (SIOCIWFIRSTPRIV+20) +#define QCSAP_IOCTL_GET_STA_INFO (SIOCIWFIRSTPRIV+21) +#define QCSAP_IOCTL_SET_MAX_TX_POWER (SIOCIWFIRSTPRIV+22) +#define QCSAP_IOCTL_DATAPATH_SNAP_SHOT (SIOCIWFIRSTPRIV+23) +#define QCSAP_IOCTL_SET_TRAFFIC_MONITOR (SIOCIWFIRSTPRIV+24) +#define QCSAP_IOCTL_AP_STATS (SIOCIWFIRSTPRIV+25) // get routines should be odd numbered + +#define QCSAP_IOCTL_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV+27) +#define QCSAP_IOCTL_GET_TSF 1 + +#define MAX_VAR_ARGS 7 +#define QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED (SIOCIWFIRSTPRIV + 31) + +enum { + QCSAP_PARAM_MAX_ASSOC = 1, + QCSAP_PARAM_GET_WLAN_DBG = 4, + QCSAP_PARAM_CLR_ACL = 6, + QCSAP_PARAM_ACL_MODE = 7, + QCSAP_PARAM_HIDE_SSID = 8, + QCSAP_PARAM_AUTO_CHANNEL = 9, + QCSAP_PARAM_SET_MC_RATE = 10, + QCSAP_PARAM_SET_AUTO_CHANNEL = 11, + QCSAP_PARAM_GET_FRAME_LOGS = 12, + QCSAP_PARAM_SET_PROXIMITY = 13, + QCSAP_PARAM_SET_WOWL = 14, + QCSAP_PARAM_CAP_TSF = 15 +}; + +int iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +#endif /* __linux__ */ + +#endif /*_QC_SAP_IOCTL_H_*/ diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h new file mode 100644 index 000000000000..01620346d239 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_assoc.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#if !defined( HDD_CONNECTION_H__ ) +#define HDD_CONNECTION_H__ +#include +#include +#include +#define HDD_MAX_NUM_IBSS_STA ( 32 ) +#ifdef FEATURE_WLAN_TDLS +#define HDD_MAX_NUM_TDLS_STA ( 8 ) +#define TDLS_STA_INDEX_VALID(staId) \ + (((staId) >= 3) && ((staId) < 0xFF)) +#endif +#define TKIP_COUNTER_MEASURE_STARTED 1 +#define TKIP_COUNTER_MEASURE_STOPED 0 +/* Timeout (in ms) for Link to Up before Registering Station */ +#define ASSOC_LINKUP_TIMEOUT 60 +#define IBSS_BROADCAST_STAID 0 + +#ifdef WLAN_FEATURE_RMC +/* Timeout in ms for peer info request commpletion */ +#define IBSS_PEER_INFO_REQ_TIMOEUT 1000 +#endif + +/** + * struct hdd_conn_flag - connection flags + * @ht_present: ht element present or not + * @vht_present: vht element present or not + * @hs20_present: hs20 element present or not + */ +struct hdd_conn_flag { + uint8_t ht_present:1; + uint8_t vht_present:1; + uint8_t hs20_present:1; + uint8_t ht_op_present:1; + uint8_t vht_op_present:1; + uint8_t reserved:3; +}; + +/*defines for tx_BF_cap_info */ +#define TX_BF_CAP_INFO_TX_BF 0x00000001 +#define TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING 0x00000002 +#define TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING 0x00000004 +#define TX_BF_CAP_INFO_RX_ZFL 0x00000008 +#define TX_BF_CAP_INFO_TX_ZFL 0x00000010 +#define TX_BF_CAP_INFO_IMP_TX_BF 0x00000020 +#define TX_BF_CAP_INFO_CALIBRATION 0x000000c0 +#define TX_BF_CAP_INFO_CALIBRATION_SHIFT 6 +#define TX_BF_CAP_INFO_EXP_CSIT_BF 0x00000100 +#define TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT 0x00000200 +#define TX_BF_CAP_INFO_EXP_BF_CSI_FB 0x00001c00 +#define TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT 10 +#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT 0x0000e000 +#define TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT 13 +#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB 0x00070000 +#define TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT 16 +#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT 0x00180000 +#define TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT 18 +#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT 0x00600000 +#define TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT 20 +#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT 0x01800000 +#define TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT 22 +#define TX_BF_CAP_INFO_RSVD 0xfe000000 + +/* defines for antenna selection info */ +#define ANTENNA_SEL_INFO 0x01 +#define ANTENNA_SEL_INFO_EXP_CSI_FB_TX 0x02 +#define ANTENNA_SEL_INFO_ANT_ID_FB_TX 0x04 +#define ANTENNA_SEL_INFO_EXP_CSI_FB 0x08 +#define ANTENNA_SEL_INFO_ANT_ID_FB 0x10 +#define ANTENNA_SEL_INFO_RX_AS 0x20 +#define ANTENNA_SEL_INFO_TX_SOUNDING_PPDU 0x40 +#define ANTENNA_SEL_INFO_RSVD 0x80 + +typedef enum +{ + /** Not associated in Infra or participating in an IBSS / Ad-hoc network.*/ + eConnectionState_NotConnected, + + /** While connection in progress */ + eConnectionState_Connecting, + + /** Associated in an Infrastructure network.*/ + eConnectionState_Associated, + + /** Participating in an IBSS network though disconnected (no partner stations + in the IBSS).*/ + eConnectionState_IbssDisconnected, + + /** Participating in an IBSS network with partner stations also present*/ + eConnectionState_IbssConnected, + + /** Disconnecting in an Infrastructure network.*/ + eConnectionState_Disconnecting + +}eConnectionState; +/**This structure stores the connection information */ +typedef struct connection_info_s +{ + /** connection state of the NIC.*/ + eConnectionState connState; + + /** BSS type of the current connection. Comes from the MIB at the + time the connect request is issued in combination with the BssDescription + from the associated entity.*/ + + eMib_dot11DesiredBssType connDot11DesiredBssType; + /** BSSID */ + tCsrBssid bssId; + + /** SSID Info*/ + tCsrSSIDInfo SSID; + + /** Station ID */ + v_U8_t staId[ HDD_MAX_NUM_IBSS_STA ]; + /** Peer Mac Address of the IBSS Stations */ + v_MACADDR_t peerMacAddress[ HDD_MAX_NUM_IBSS_STA ]; + /** Auth Type */ + eCsrAuthType authType; + + /** Unicast Encryption Type */ + eCsrEncryptionType ucEncryptionType; + + /** Multicast Encryption Type */ + eCsrEncryptionType mcEncryptionType; + + /** Keys */ + tCsrKeys Keys; + + /** Operation Channel */ + v_U8_t operationChannel; + + /** Remembers authenticated state */ + v_U8_t uIsAuthenticated; + + /** Dot11Mode */ + tANI_U32 dot11Mode; + + uint32_t rate_flags; + + /** channel frequency */ + uint32_t freq; + + /** txrate structure holds nss & datarate info */ + struct rate_info txrate; + + /** noise information */ + int8_t noise; + + /** ht capabilities info */ + struct ieee80211_ht_cap ht_caps; + + /** vht capabilities info */ + struct ieee80211_vht_cap vht_caps; + + /** passpoint/hs20 info */ + tDot11fIEhs20vendor_ie hs20vendor_ie; + + /** conn info params is present or not */ + struct hdd_conn_flag conn_flag; + + /** ht operation info */ + struct ieee80211_ht_operation ht_operation; + + /** ht operation info */ + struct ieee80211_vht_operation vht_operation; + + /** roaming counter */ + uint32_t roam_count; + + /** rssi info */ + int8_t signal; + + /** assoc fail reason */ + int32_t assoc_status_code; +}connection_info_t; +/*Forward declaration of Adapter*/ +typedef struct hdd_adapter_s hdd_adapter_t; +typedef struct hdd_context_s hdd_context_t; +typedef struct hdd_station_ctx hdd_station_ctx_t; +typedef struct hdd_ap_ctx_s hdd_ap_ctx_t; +typedef struct hdd_mon_ctx_s hdd_mon_ctx_t; + + +extern v_BOOL_t hdd_connIsConnected( hdd_station_ctx_t *pHddStaCtx ); +eCsrBand hdd_connGetConnectedBand( hdd_station_ctx_t *pHddStaCtx ); +extern eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, v_U32_t roamId, + eRoamCmdStatus roamStatus, eCsrRoamResult roamResult ); + +extern v_VOID_t hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType ); + +v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddCtx, + eMib_dot11DesiredBssType *pConnectedBssType ); + +int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType ); + +int hdd_set_csr_auth_type( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType ); + +void hdd_assoc_registerFwdEapolCB(void *pContext); + +VOS_STATUS hdd_roamRegisterTDLSSTA( hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *peerMac, +#else + tANI_U8 *peerMac, +#endif + tANI_U16 staId, tANI_U8 ucastSig); +void hdd_PerformRoamSetKeyComplete(hdd_adapter_t *pAdapter); +VOS_STATUS hdd_roamDeregisterTDLSSTA(hdd_adapter_t *pAdapter, tANI_U8 staId); + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter, + const tANI_U16 measurementToken, + const tANI_BOOLEAN flag, + const tANI_U8 numBss); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +void iw_full_power_cbfn (void *pContext, eHalStatus status); + +#endif diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h new file mode 100644 index 000000000000..d08c9fcc97bf --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg.h @@ -0,0 +1,3817 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( HDD_CONFIG_H__ ) +#define HDD_CONFIG_H__ + +/**=========================================================================== + + \file hdd_Config.h + + \brief Android WLAN Adapter Configuration functions + + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include + +#ifdef DHCP_SERVER_OFFLOAD +#define IPADDR_NUM_ENTRIES (4) +#define IPADDR_STRING_LENGTH (16) +#define DHCP_START_POOL_ADDRESS 100 +#endif /* DHCP_SERVER_OFFLOAD */ + +//Number of items that can be configured +#define MAX_CFG_INI_ITEMS 512 + +#ifdef SAP_AUTH_OFFLOAD +/* 802.11 pre-share key length */ +#define WLAN_PSK_STRING_LENGTH (64) +#endif /* SAP_AUTH_OFFLOAD */ + +// Defines for all of the things we read from the configuration (registry). + +#define CFG_RTS_THRESHOLD_NAME "RTSThreshold" +#define CFG_RTS_THRESHOLD_MIN WNI_CFG_RTS_THRESHOLD_STAMIN // min is 0, meaning always use RTS. +#define CFG_RTS_THRESHOLD_MAX WNI_CFG_RTS_THRESHOLD_STAMAX // max is the max frame size +#define CFG_RTS_THRESHOLD_DEFAULT WNI_CFG_RTS_THRESHOLD_STADEF + +#define CFG_FRAG_THRESHOLD_NAME "gFragmentationThreshold" +#define CFG_FRAG_THRESHOLD_MIN WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN +#define CFG_FRAG_THRESHOLD_MAX WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX +#define CFG_FRAG_THRESHOLD_DEFAULT WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF + +#define CFG_CALIBRATION_NAME "gCalibration" +#define CFG_CALIBRATION_MIN ( 0 ) +#define CFG_CALIBRATION_MAX ( 1 ) +#define CFG_CALIBRATION_MAC_DEFAULT ( 1 ) +#define CFG_CALIBRATION_DEFAULT CFG_CALIBRATION_MAC_DEFAULT + +#define CFG_CALIBRATION_PERIOD_NAME "gCalibrationPeriod" +#define CFG_CALIBRATION_PERIOD_MIN ( 2 ) +#define CFG_CALIBRATION_PERIOD_MAX ( 10 ) +#define CFG_CALIBRATION_PERIOD_MAC_DEFAULT ( 5 ) +#define CFG_CALIBRATION_PERIOD_DEFAULT CFG_CALIBRATION_PERIOD_MAC_DEFAULT + +#define CFG_OPERATING_CHANNEL_NAME "gOperatingChannel" +#define CFG_OPERATING_CHANNEL_MIN ( 0 ) +#define CFG_OPERATING_CHANNEL_MAX ( 14 ) +#define CFG_OPERATING_CHANNEL_DEFAULT ( 1 ) + +#define CFG_SHORT_SLOT_TIME_ENABLED_NAME "gShortSlotTimeEnabled" +#define CFG_SHORT_SLOT_TIME_ENABLED_MIN WNI_CFG_SHORT_SLOT_TIME_STAMIN +#define CFG_SHORT_SLOT_TIME_ENABLED_MAX WNI_CFG_SHORT_SLOT_TIME_STAMAX +#define CFG_SHORT_SLOT_TIME_ENABLED_DEFAULT WNI_CFG_SHORT_SLOT_TIME_STADEF + +#define CFG_11D_SUPPORT_ENABLED_NAME "g11dSupportEnabled" +#define CFG_11D_SUPPORT_ENABLED_MIN WNI_CFG_11D_ENABLED_STAMIN +#define CFG_11D_SUPPORT_ENABLED_MAX WNI_CFG_11D_ENABLED_STAMAX +#define CFG_11D_SUPPORT_ENABLED_DEFAULT WNI_CFG_11D_ENABLED_STADEF // Default is ON + +#define CFG_11H_SUPPORT_ENABLED_NAME "g11hSupportEnabled" +#define CFG_11H_SUPPORT_ENABLED_MIN ( 0 ) +#define CFG_11H_SUPPORT_ENABLED_MAX ( 1 ) +#define CFG_11H_SUPPORT_ENABLED_DEFAULT ( 1 ) // Default is ON + +#define CFG_ENFORCE_11D_CHANNELS_NAME "gEnforce11dChannel" +#define CFG_ENFORCE_11D_CHANNELS_MIN ( 0 ) +#define CFG_ENFORCE_11D_CHANNELS_MAX ( 1 ) +#define CFG_ENFORCE_11D_CHANNELS_DEFAULT ( 0 ) + +//COUNTRY Code Priority +#define CFG_COUNTRY_CODE_PRIORITY_NAME "gCountryCodePriority" +#define CFG_COUNTRY_CODE_PRIORITY_MIN ( 0 ) +#define CFG_COUNTRY_CODE_PRIORITY_MAX ( 1 ) +#define CFG_COUNTRY_CODE_PRIORITY_DEFAULT ( 1 ) + +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_NAME "gEnforceCountryCodeMatch" +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_MIN ( 0 ) +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_MAX ( 1 ) +#define CFG_ENFORCE_COUNTRY_CODE_MATCH_DEFAULT ( 0 ) + +#define CFG_ENFORCE_DEFAULT_DOMAIN_NAME "gEnforceDefaultDomain" +#define CFG_ENFORCE_DEFAULT_DOMAIN_MIN ( 0 ) +#define CFG_ENFORCE_DEFAULT_DOMAIN_MAX ( 1 ) +#define CFG_ENFORCE_DEFAULT_DOMAIN_DEFAULT ( 0 ) + +#define CFG_GENERIC_ID1_NAME "gCfg1Id" +#define CFG_GENERIC_ID1_MIN ( 0 ) +#define CFG_GENERIC_ID1_MAX ( 0xffffffff ) +#define CFG_GENERIC_ID1_DEFAULT ( 0 ) + +#define CFG_GENERIC_ID2_NAME "gCfg2Id" +#define CFG_GENERIC_ID2_MIN ( 0 ) +#define CFG_GENERIC_ID2_MAX ( 0xffffffff ) +#define CFG_GENERIC_ID2_DEFAULT ( 0 ) + +#define CFG_GENERIC_ID3_NAME "gCfg3Id" +#define CFG_GENERIC_ID3_MIN ( 0 ) +#define CFG_GENERIC_ID3_MAX ( 0xffffffff ) +#define CFG_GENERIC_ID3_DEFAULT ( 0 ) + +#define CFG_GENERIC_ID4_NAME "gCfg4Id" +#define CFG_GENERIC_ID4_MIN ( 0 ) +#define CFG_GENERIC_ID4_MAX ( 0xffffffff ) +#define CFG_GENERIC_ID4_DEFAULT ( 0 ) + +#define CFG_GENERIC_ID5_NAME "gCfg5Id" +#define CFG_GENERIC_ID5_MIN ( 0 ) +#define CFG_GENERIC_ID5_MAX ( 0xffffffff ) +#define CFG_GENERIC_ID5_DEFAULT ( 0 ) + +#define CFG_GENERIC_VALUE1_NAME "gCfg1Value" +#define CFG_GENERIC_VALUE1_MIN ( 0 ) +#define CFG_GENERIC_VALUE1_MAX ( 0xffffffff ) +#define CFG_GENERIC_VALUE1_DEFAULT ( 0 ) + +#define CFG_GENERIC_VALUE2_NAME "gCfg2Value" +#define CFG_GENERIC_VALUE2_MIN ( 0 ) +#define CFG_GENERIC_VALUE2_MAX ( 0xffffffff ) +#define CFG_GENERIC_VALUE2_DEFAULT ( 0 ) + +#define CFG_GENERIC_VALUE3_NAME "gCfg3Value" +#define CFG_GENERIC_VALUE3_MIN ( 0 ) +#define CFG_GENERIC_VALUE3_MAX ( 0xffffffff ) +#define CFG_GENERIC_VALUE3_DEFAULT ( 0 ) + +#define CFG_GENERIC_VALUE4_NAME "gCfg4Value" +#define CFG_GENERIC_VALUE4_MIN ( 0 ) +#define CFG_GENERIC_VALUE4_MAX ( 0xffffffff ) +#define CFG_GENERIC_VALUE4_DEFAULT ( 0 ) + +#define CFG_GENERIC_VALUE5_NAME "gCfg5Value" +#define CFG_GENERIC_VALUE5_MIN ( 0 ) +#define CFG_GENERIC_VALUE5_MAX ( 0xffffffff ) +#define CFG_GENERIC_VALUE5_DEFAULT ( 0 ) + +#define CFG_HEARTBEAT_THRESH_24_NAME "gHeartbeat24" +#define CFG_HEARTBEAT_THRESH_24_MIN WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN +#define CFG_HEARTBEAT_THRESH_24_MAX WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX +#define CFG_HEARTBEAT_THRESH_24_DEFAULT WNI_CFG_HEART_BEAT_THRESHOLD_STADEF + +#define CFG_POWER_USAGE_NAME "gPowerUsage" +#define CFG_POWER_USAGE_MIN "Min" //Minimum Power Save +#define CFG_POWER_USAGE_MAX "Max" //Maximum Power Save +#define CFG_POWER_USAGE_DEFAULT "Mod" //Moderate Power Save + +//Enable suspend on Android +#define CFG_ENABLE_SUSPEND_NAME "gEnableSuspend" +#define CFG_ENABLE_SUSPEND_MIN ( 0 ) //No support for suspend +#define CFG_ENABLE_SUSPEND_MAX ( 3 ) //Map to Deep Sleep +#define CFG_ENABLE_SUSPEND_DEFAULT ( 1 ) //Map to Standby + +//Driver start/stop command mappings +#define CFG_ENABLE_ENABLE_DRIVER_STOP_NAME "gEnableDriverStop" +#define CFG_ENABLE_ENABLE_DRIVER_STOP_MIN ( 0 ) //No support for stop +#define CFG_ENABLE_ENABLE_DRIVER_STOP_MAX ( 2 ) //Map to Deep Sleep +#define CFG_ENABLE_ENABLE_DRIVER_STOP_DEFAULT ( 0 ) + +#define CFG_WOWL_PATTERN_NAME "gWowlPattern" +#define CFG_WOWL_PATTERN_DEFAULT "" + +//IMPS = IdleModePowerSave +#define CFG_ENABLE_IMPS_NAME "gEnableImps" +#define CFG_ENABLE_IMPS_MIN ( 0 ) +#define CFG_ENABLE_IMPS_MAX ( 1 ) +#define CFG_ENABLE_IMPS_DEFAULT ( 1 ) + +//SSR = SubSytemRestart +#define CFG_SSR_PANIC_ON_FAILURE_NAME "gSsrPanicOnFailure" +#define CFG_SSR_PANIC_ON_FAILURE_MIN ( 0 ) +#define CFG_SSR_PANIC_ON_FAILURE_MAX ( 1 ) +#define CFG_SSR_PANIC_ON_FAILURE_DEFAULT ( 0 ) + +#define CFG_IMPS_MINIMUM_SLEEP_TIME_NAME "gImpsMinSleepTime" +#define CFG_IMPS_MINIMUM_SLEEP_TIME_MIN ( 0 ) +#define CFG_IMPS_MINIMUM_SLEEP_TIME_MAX ( 65535 ) +#define CFG_IMPS_MINIMUM_SLEEP_TIME_DEFAULT ( 5 ) + +#define CFG_IMPS_MODERATE_SLEEP_TIME_NAME "gImpsModSleepTime" +#define CFG_IMPS_MODERATE_SLEEP_TIME_MIN ( 0 ) +#define CFG_IMPS_MODERATE_SLEEP_TIME_MAX ( 65535 ) +#define CFG_IMPS_MODERATE_SLEEP_TIME_DEFAULT ( 10) + +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_NAME "gImpsMaxSleepTime" +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_MIN ( 0 ) +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_MAX ( 65535 ) +#define CFG_IMPS_MAXIMUM_SLEEP_TIME_DEFAULT ( 15 ) + +/*If there is scan on STA interface back to back with + *time diff nDeferScanTimeInterval, driver will not + *issue a new scan. Driver will return cached result to kernel. + *the interval is in msec + */ +#define CFG_DEFER_SCAN_TIME_INTERVAL "gDeferScanTimeInterval" +#define CFG_DEFER_SCAN_TIME_INTERVAL_MIN ( 0 ) +#define CFG_DEFER_SCAN_TIME_INTERVAL_MAX ( 65535 ) +#define CFG_DEFER_SCAN_TIME_INTERVAL_DEFAULT ( 2000 ) + +//BMPS = BeaconModePowerSave +#define CFG_ENABLE_BMPS_NAME "gEnableBmps" +#define CFG_ENABLE_BMPS_MIN ( 0 ) +#define CFG_ENABLE_BMPS_MAX ( 1 ) +#define CFG_ENABLE_BMPS_DEFAULT ( 1 ) + +#define CFG_BMPS_MINIMUM_LI_NAME "gBmpsMinListenInterval" +#define CFG_BMPS_MINIMUM_LI_MIN ( 1 ) +#define CFG_BMPS_MINIMUM_LI_MAX ( 65535 ) +#define CFG_BMPS_MINIMUM_LI_DEFAULT ( 1 ) + +#define CFG_BMPS_MODERATE_LI_NAME "gBmpsModListenInterval" +#define CFG_BMPS_MODERATE_LI_MIN ( 1 ) +#define CFG_BMPS_MODERATE_LI_MAX ( 65535 ) +#define CFG_BMPS_MODERATE_LI_DEFAULT ( 1 ) + +#define CFG_BMPS_MAXIMUM_LI_NAME "gBmpsMaxListenInterval" +#define CFG_BMPS_MAXIMUM_LI_MIN ( 1 ) +#define CFG_BMPS_MAXIMUM_LI_MAX ( 65535 ) +#define CFG_BMPS_MAXIMUM_LI_DEFAULT ( 1 ) + +// gEnableAutoBmpsTimer has been previously published as an externally +// configurable parameter. See analysis of CR 178211 for detailed info +// on why we want to *always* set this to 1 i.e. we no longer want +// this parameter to be configurable. the clean solution would be for +// users to not define this item in winreg so that the default value +// (which needs to be changed to 1) gets picked up but we cannot rely on that +// since this item has been published already hence the proposed +// solution to change the name of the item along with the change in the +// default value. also we could decide to not read this item from registry +// but leaving open the option of being able to configure this item for +// ASW's internal use +#define CFG_ENABLE_AUTO_BMPS_TIMER_NAME "gEnableAutoBmpsTimer_INTERNAL" +#define CFG_ENABLE_AUTO_BMPS_TIMER_MIN ( 0 ) +#define CFG_ENABLE_AUTO_BMPS_TIMER_MAX ( 1 ) +#define CFG_ENABLE_AUTO_BMPS_TIMER_DEFAULT ( 1 ) +/* + * gEnableDynamicRAstartRate usage: + * + * 11B and 11A/G rates can be specified in multiples of 0.5 + * So for 5.5 mbps, gEnableDynamicRAstartRate=11 + * and for 12 mbps, gEnableDynamicRAstartRate=24 etc. + * + * for MCS 0 - 7 rates, Bit 7 should set to 1 and Bit 0-6 + * represent the MCS index. + * So for MCS0, gEnableDynamicRAstartRate=128 + * and for MCS2, gEnableDynamicRAstartRate=130 etc. + * + * Any invalid non-zero value will set the start rate + * to 6 mbps (value 1 will also set it to 6 mbps) + * + * Bit 8 is used to enable PER discount logic in RA + * Ex: if PER discount logic needs to be enabled along with + * RA start rate as 6mbps: + * (Bit 8 for PER discount logic and Bit 0 for 6 mbps) + * gEnableDynamicRAstartRate=257 + */ + +#define CFG_ENABLE_DYNAMIC_RA_START_RATE_NAME "gEnableDynamicRAstartRate" +#define CFG_ENABLE_DYNAMIC_RA_START_RATE_MIN (0) +#define CFG_ENABLE_DYNAMIC_RA_START_RATE_MAX (65535) +#define CFG_ENABLE_DYNAMIC_RA_START_RATE_DEFAULT (0) + +/* Bit mask value to enable RTS/CTS for different modes + * for 2.4 GHz, HT20 - 0x0001, for 2.4 GHz, HT40 - 0x0002 + * for 2.4 GHz, VHT20 - 0x0004, for 2.4 GHz, VHT40 - 0x0008 + * for 5 GHz, HT20 - 0x0100, for 5 GHz, HT40 - 0x0200 + * for 5 GHz, VHT20 - 0x0400, for 5 GHz, VHT40 - 0x0800 + * for 5 GHz, VHT80 - 0x1000 + */ +#define CFG_ENABLE_RTSCTS_HTVHT_NAME "gEnableRtsCtsHtVht" +#define CFG_ENABLE_RTSCTS_HTVHT_MIN ( 0x0000 ) +#define CFG_ENABLE_RTSCTS_HTVHT_MAX ( 0x1f0f ) +#define CFG_ENABLE_RTSCTS_HTVHT_DEFAULT ( 0x0000 ) + +#define CFG_AUTO_BMPS_TIMER_VALUE_NAME "gAutoBmpsTimerValue" +#define CFG_AUTO_BMPS_TIMER_VALUE_MIN ( 1000 ) +#define CFG_AUTO_BMPS_TIMER_VALUE_MAX ( 4294967295UL ) +#define CFG_AUTO_BMPS_TIMER_VALUE_DEFAULT ( 1000 ) + +#define CFG_MAX_RX_AMPDU_FACTOR_NAME "gMaxRxAmpduFactor" +#define CFG_MAX_RX_AMPDU_FACTOR_MIN WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN +#define CFG_MAX_RX_AMPDU_FACTOR_MAX WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX +#define CFG_MAX_RX_AMPDU_FACTOR_DEFAULT WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF + +//Configuration added to enable/disable CTS2SELF in +//Adaptive RX drain feature +#define CFG_ENABLE_ADAPT_RX_DRAIN_NAME "gEnableAdaptRxDrain" +#define CFG_ENABLE_ADAPT_RX_DRAIN_MIN WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN +#define CFG_ENABLE_ADAPT_RX_DRAIN_MAX WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX +#define CFG_ENABLE_ADAPT_RX_DRAIN_DEFAULT WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF + +typedef enum +{ + eHDD_DOT11_MODE_AUTO = 0, //covers all things we support + eHDD_DOT11_MODE_abg, //11a/b/g only, no HT, no proprietary + eHDD_DOT11_MODE_11b, + eHDD_DOT11_MODE_11g, + eHDD_DOT11_MODE_11n, + eHDD_DOT11_MODE_11g_ONLY, + eHDD_DOT11_MODE_11n_ONLY, + eHDD_DOT11_MODE_11b_ONLY, +#ifdef WLAN_FEATURE_11AC + eHDD_DOT11_MODE_11ac_ONLY, + eHDD_DOT11_MODE_11ac, +#endif +}eHddDot11Mode; + +#define CFG_DOT11_MODE_NAME "gDot11Mode" +#define CFG_DOT11_MODE_MIN eHDD_DOT11_MODE_AUTO +#ifdef WLAN_FEATURE_11AC +#define CFG_DOT11_MODE_MAX eHDD_DOT11_MODE_11ac +#define CFG_DOT11_MODE_DEFAULT eHDD_DOT11_MODE_11ac +#else +#define CFG_DOT11_MODE_MAX eHDD_DOT11_MODE_11b_ONLY +#define CFG_DOT11_MODE_DEFAULT eHDD_DOT11_MODE_11n +#endif + +#define CFG_SAP_ENABLE_11AC_NAME "gSapEnable11AC" +#define CFG_SAP_ENABLE_11AC_MIN ( 0 ) +#define CFG_SAP_ENABLE_11AC_MAX ( 1 ) +#define CFG_SAP_ENABLE_11AC_DEFAULT ( 1 ) + +#define CFG_CHANNEL_BONDING_MODE_24GHZ_NAME "gChannelBondingMode24GHz" +#define CFG_CHANNEL_BONDING_MODE_MIN WNI_CFG_CHANNEL_BONDING_MODE_STAMIN +#define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX +#define CFG_CHANNEL_BONDING_MODE_DEFAULT WNI_CFG_CHANNEL_BONDING_MODE_STADEF + +#define CFG_OVERRIDE_HT40_20_24GHZ_NAME "override_ht20_40_24g" +#define CFG_OVERRIDE_HT40_20_24GHZ_MIN 0 +#define CFG_OVERRIDE_HT40_20_24GHZ_MAX 1 +#define CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT 0 + +#define CFG_CHANNEL_BONDING_MODE_5GHZ_NAME "gChannelBondingMode5GHz" +#define CFG_CHANNEL_BONDING_MODE_MIN WNI_CFG_CHANNEL_BONDING_MODE_STAMIN +#define CFG_CHANNEL_BONDING_MODE_MAX WNI_CFG_CHANNEL_BONDING_MODE_STAMAX +#define CFG_CHANNEL_BONDING_MODE_DEFAULT WNI_CFG_CHANNEL_BONDING_MODE_STADEF + +#define CFG_FIXED_RATE_NAME "gFixedRate" +#define CFG_FIXED_RATE_MIN WNI_CFG_FIXED_RATE_STAMIN +#define CFG_FIXED_RATE_MAX WNI_CFG_FIXED_RATE_STAMAX +#define CFG_FIXED_RATE_DEFAULT WNI_CFG_FIXED_RATE_STADEF + +#define CFG_SHORT_GI_20MHZ_NAME "gShortGI20Mhz" +#define CFG_SHORT_GI_20MHZ_MIN WNI_CFG_SHORT_GI_20MHZ_STAMIN +#define CFG_SHORT_GI_20MHZ_MAX WNI_CFG_SHORT_GI_20MHZ_STAMAX +#define CFG_SHORT_GI_20MHZ_DEFAULT WNI_CFG_SHORT_GI_20MHZ_STADEF + +#define CFG_BLOCK_ACK_AUTO_SETUP_NAME "gBlockAckAutoSetup" +#define CFG_BLOCK_ACK_AUTO_SETUP_MIN ( 0 ) +#define CFG_BLOCK_ACK_AUTO_SETUP_MAX ( 1 ) +#define CFG_BLOCK_ACK_AUTO_SETUP_DEFAULT ( 1 ) + +#define CFG_SCAN_RESULT_AGE_COUNT_NAME "gScanResultAgeCount" +#define CFG_SCAN_RESULT_AGE_COUNT_MIN ( 1 ) +#define CFG_SCAN_RESULT_AGE_COUNT_MAX ( 100 ) +#define CFG_SCAN_RESULT_AGE_COUNT_DEFAULT ( 3 ) + +//All in seconds +//Not Connect, No Power Save +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_NAME "gScanResultAgeNCNPS" +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCNPS_DEFAULT ( 50 ) +//Not Connect, Power Save +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_NAME "gScanResultAgeNCPS" +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_NCPS_DEFAULT ( 300 ) +//Connect, No Power Save +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_NAME "gScanResultAgeCNPS" +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_CNPS_DEFAULT ( 150 ) +//Connect, Power Save +#define CFG_SCAN_RESULT_AGE_TIME_CPS_NAME "gScanResultAgeCPS" +#define CFG_SCAN_RESULT_AGE_TIME_CPS_MIN ( 10 ) +#define CFG_SCAN_RESULT_AGE_TIME_CPS_MAX ( 10000 ) +#define CFG_SCAN_RESULT_AGE_TIME_CPS_DEFAULT ( 600 ) + +#define CFG_RSSI_CATEGORY_GAP_NAME "gRssiCatGap" +#define CFG_RSSI_CATEGORY_GAP_MIN ( 5 ) +#define CFG_RSSI_CATEGORY_GAP_MAX ( 100 ) +#define CFG_RSSI_CATEGORY_GAP_DEFAULT ( 5 ) + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define CFG_ROAM_PREFER_5GHZ "gRoamPrefer5GHz" +#define CFG_ROAM_PREFER_5GHZ_MIN ( 0 ) +#define CFG_ROAM_PREFER_5GHZ_MAX ( 1 ) +#define CFG_ROAM_PREFER_5GHZ_DEFAULT ( 1 ) + +/* + To enable, set gRoamIntraBand=1 (Roaming within band) + To disable, set gRoamIntraBand=0 (Roaming across band) +*/ +#define CFG_ROAM_INTRA_BAND "gRoamIntraBand" +#define CFG_ROAM_INTRA_BAND_MIN ( 0 ) +#define CFG_ROAM_INTRA_BAND_MAX ( 1 ) +#define CFG_ROAM_INTRA_BAND_DEFAULT ( 0 ) +#endif + +#define CFG_SHORT_PREAMBLE_NAME "gShortPreamble" +#define CFG_SHORT_PREAMBLE_MIN WNI_CFG_SHORT_PREAMBLE_STAMIN +#define CFG_SHORT_PREAMBLE_MAX WNI_CFG_SHORT_PREAMBLE_STAMAX +#define CFG_SHORT_PREAMBLE_DEFAULT WNI_CFG_SHORT_PREAMBLE_STADEF + +#define CFG_IBSS_AUTO_BSSID_NAME "gAutoIbssBssid" +#define CFG_IBSS_AUTO_BSSID_MIN WNI_CFG_IBSS_AUTO_BSSID_STAMIN +#define CFG_IBSS_AUTO_BSSID_MAX WNI_CFG_IBSS_AUTO_BSSID_STAMAX +#define CFG_IBSS_AUTO_BSSID_DEFAULT WNI_CFG_IBSS_AUTO_BSSID_STADEF + +#define CFG_IBSS_BSSID_NAME "gIbssBssid" +#define CFG_IBSS_BSSID_MIN "000000000000" +#define CFG_IBSS_BSSID_MAX "ffffffffffff" +#define CFG_IBSS_BSSID_DEFAULT "000AF5040506" + +#define CFG_INTF0_MAC_ADDR_NAME "Intf0MacAddress" +#define CFG_INTF0_MAC_ADDR_MIN "000000000000" +#define CFG_INTF0_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF0_MAC_ADDR_DEFAULT "000AF5898980" + +#define CFG_INTF1_MAC_ADDR_NAME "Intf1MacAddress" +#define CFG_INTF1_MAC_ADDR_MIN "000000000000" +#define CFG_INTF1_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF1_MAC_ADDR_DEFAULT "000AF5898981" + +#define CFG_INTF2_MAC_ADDR_NAME "Intf2MacAddress" +#define CFG_INTF2_MAC_ADDR_MIN "000000000000" +#define CFG_INTF2_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF2_MAC_ADDR_DEFAULT "000AF5898982" + +#define CFG_INTF3_MAC_ADDR_NAME "Intf3MacAddress" +#define CFG_INTF3_MAC_ADDR_MIN "000000000000" +#define CFG_INTF3_MAC_ADDR_MAX "ffffffffffff" +#define CFG_INTF3_MAC_ADDR_DEFAULT "000AF5898983" + +#define CFG_AP_QOS_UAPSD_MODE_NAME "gEnableApUapsd" // ACs to setup U-APSD for at assoc +#define CFG_AP_QOS_UAPSD_MODE_MIN ( 0 ) +#define CFG_AP_QOS_UAPSD_MODE_MAX ( 1 ) +#define CFG_AP_QOS_UAPSD_MODE_DEFAULT ( 1 ) + +#define CFG_AP_COUNTRY_CODE "gAPCntryCode" +#define CFG_AP_COUNTRY_CODE_MIN "USI" +#define CFG_AP_COUNTRY_CODE_MAX "USI" +#define CFG_AP_COUNTRY_CODE_DEFAULT "FFF" + +#define CFG_AP_ENABLE_RANDOM_BSSID_NAME "gEnableApRandomBssid" +#define CFG_AP_ENABLE_RANDOM_BSSID_MIN ( 0 ) +#define CFG_AP_ENABLE_RANDOM_BSSID_MAX ( 1 ) +#define CFG_AP_ENABLE_RANDOM_BSSID_DEFAULT ( 0 ) + +#define CFG_AP_ENABLE_PROTECTION_MODE_NAME "gEnableApProt" +#define CFG_AP_ENABLE_PROTECTION_MODE_MIN ( 0 ) +#define CFG_AP_ENABLE_PROTECTION_MODE_MAX ( 1 ) +#define CFG_AP_ENABLE_PROTECTION_MODE_DEFAULT ( 1 ) + +// Bit map for CFG_AP_PROTECTION_MODE_DEFAULT +// LOWER byte for associated stations +// UPPER byte for overlapping stations +// each byte will have the following info +// bit15 bit14 bit13 bit12 bit11 bit10 bit9 bit8 +// OBSS RIFS LSIG_TXOP NON_GF HT20 FROM_11G FROM_11B FROM_11A +// bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 +// OBSS RIFS LSIG_TXOP NON_GF HT_20 FROM_11G FROM_11B FROM_11A +#define CFG_AP_PROTECTION_MODE_NAME "gApProtection" +#define CFG_AP_PROTECTION_MODE_MIN ( 0x0 ) +#define CFG_AP_PROTECTION_MODE_MAX ( 0xFFFF ) +#define CFG_AP_PROTECTION_MODE_DEFAULT ( 0xBFFF ) + +#define CFG_AP_OBSS_PROTECTION_MODE_NAME "gEnableApOBSSProt" +#define CFG_AP_OBSS_PROTECTION_MODE_MIN ( 0 ) +#define CFG_AP_OBSS_PROTECTION_MODE_MAX ( 1 ) +#define CFG_AP_OBSS_PROTECTION_MODE_DEFAULT ( 0 ) + +#define CFG_AP_STA_SECURITY_SEPERATION_NAME "gDisableIntraBssFwd" +#define CFG_AP_STA_SECURITY_SEPERATION_MIN ( 0 ) +#define CFG_AP_STA_SECURITY_SEPERATION_MAX ( 1 ) +#define CFG_AP_STA_SECURITY_SEPERATION_DEFAULT ( 0 ) + +#define CFG_AP_LISTEN_MODE_NAME "gEnablePhyAgcListenMode" +#define CFG_AP_LISTEN_MODE_MIN (0) +#define CFG_AP_LISTEN_MODE_MAX (128) +#define CFG_AP_LISTEN_MODE_DEFAULT (128) + +#define CFG_AP_AUTO_SHUT_OFF "gAPAutoShutOff" +#define CFG_AP_AUTO_SHUT_OFF_MIN ( 0 ) +#define CFG_AP_AUTO_SHUT_OFF_MAX ( 4294967295UL ) +#define CFG_AP_AUTO_SHUT_OFF_DEFAULT ( 0 ) + +#define CFG_FRAMES_PROCESSING_TH_MODE_NAME "gMinFramesProcThres" +#define CFG_FRAMES_PROCESSING_TH_MIN ( 0 ) +#define CFG_FRAMES_PROCESSING_TH_MAX ( 39 ) +#define CFG_FRAMES_PROCESSING_TH_DEFAULT ( 0 ) + +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL "gAPChannelSelectStartChannel" +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MIN (0) +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MAX (0xFF) +#define CFG_SAP_CHANNEL_SELECT_START_CHANNEL_DEFAULT (0) + +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL "gAPChannelSelectEndChannel" +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MIN (0) +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MAX (0xFF) +#define CFG_SAP_CHANNEL_SELECT_END_CHANNEL_DEFAULT (11) + +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND "gAPChannelSelectOperatingBand" +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MIN (0) +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MAX (0x5) +#define CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_DEFAULT (0) + +#define CFG_DISABLE_PACKET_FILTER "gDisablePacketFilter" +#define CFG_DISABLE_PACKET_FILTER_MIN (0) +#define CFG_DISABLE_PACKET_FILTER_MAX (0x1) +#define CFG_DISABLE_PACKET_FILTER_DEFAULT (0) + +#define CFG_ENABLE_LTE_COEX "gEnableLTECoex" +#define CFG_ENABLE_LTE_COEX_MIN ( 0 ) +#define CFG_ENABLE_LTE_COEX_MAX ( 1 ) +#define CFG_ENABLE_LTE_COEX_DEFAULT ( 0 ) + +#define CFG_AP_KEEP_ALIVE_PERIOD_NAME "gApKeepAlivePeriod" +#define CFG_AP_KEEP_ALIVE_PERIOD_MIN ( 3 ) +#define CFG_AP_KEEP_ALIVE_PERIOD_MAX ( 255 ) +#define CFG_AP_KEEP_ALIVE_PERIOD_DEFAULT ( 5 ) + +#define CFG_GO_KEEP_ALIVE_PERIOD_NAME "gGoKeepAlivePeriod" +#define CFG_GO_KEEP_ALIVE_PERIOD_MIN ( 3 ) +#define CFG_GO_KEEP_ALIVE_PERIOD_MAX ( 255 ) +#define CFG_GO_KEEP_ALIVE_PERIOD_DEFAULT ( 5 ) + +#define CFG_AP_LINK_MONITOR_PERIOD_NAME "gApLinkMonitorPeriod" +#define CFG_AP_LINK_MONITOR_PERIOD_MIN ( 3 ) +#define CFG_AP_LINK_MONITOR_PERIOD_MAX ( 50 ) +#define CFG_AP_LINK_MONITOR_PERIOD_DEFAULT ( 10 ) + +/* gGoLinkMonitorPeriod is period where link is idle and where + * we send NULL frame + */ +#define CFG_GO_LINK_MONITOR_PERIOD_NAME "gGoLinkMonitorPeriod" +#define CFG_GO_LINK_MONITOR_PERIOD_MIN ( 3 ) +#define CFG_GO_LINK_MONITOR_PERIOD_MAX ( 50 ) +#define CFG_GO_LINK_MONITOR_PERIOD_DEFAULT ( 10 ) + + +#define CFG_BEACON_INTERVAL_NAME "gBeaconInterval" +#define CFG_BEACON_INTERVAL_MIN WNI_CFG_BEACON_INTERVAL_STAMIN +#define CFG_BEACON_INTERVAL_MAX WNI_CFG_BEACON_INTERVAL_STAMAX +#define CFG_BEACON_INTERVAL_DEFAULT WNI_CFG_BEACON_INTERVAL_STADEF + +//Additional Handoff related Parameters +#define CFG_ENABLE_IDLE_SCAN_NAME "gEnableIdleScan" +#define CFG_ENABLE_IDLE_SCAN_MIN ( 0 ) +#define CFG_ENABLE_IDLE_SCAN_MAX ( 1 ) +#define CFG_ENABLE_IDLE_SCAN_DEFAULT ( 1 ) + +#define CFG_ROAMING_TIME_NAME "gRoamingTime" +#define CFG_ROAMING_TIME_MIN ( 0 ) +#define CFG_ROAMING_TIME_MAX ( 4294967UL ) +#define CFG_ROAMING_TIME_DEFAULT ( 10 ) + +#define CFG_VCC_RSSI_TRIGGER_NAME "gVccRssiTrigger" +#define CFG_VCC_RSSI_TRIGGER_MIN ( 0 ) +#define CFG_VCC_RSSI_TRIGGER_MAX ( 80 ) +#define CFG_VCC_RSSI_TRIGGER_DEFAULT ( 80 ) + +#define CFG_VCC_UL_MAC_LOSS_THRESH_NAME "gVccUlMacLossThresh" +#define CFG_VCC_UL_MAC_LOSS_THRESH_MIN ( 0 ) +#define CFG_VCC_UL_MAC_LOSS_THRESH_MAX ( 9 ) +#define CFG_VCC_UL_MAC_LOSS_THRESH_DEFAULT ( 9 ) + +#define CFG_PASSIVE_MAX_CHANNEL_TIME_NAME "gPassiveMaxChannelTime" +#define CFG_PASSIVE_MAX_CHANNEL_TIME_MIN ( 0 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT ( 110 ) + +#define CFG_PASSIVE_MIN_CHANNEL_TIME_NAME "gPassiveMinChannelTime" +#define CFG_PASSIVE_MIN_CHANNEL_TIME_MIN ( 0 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_DEFAULT ( 60 ) + +#define CFG_ACTIVE_MAX_CHANNEL_TIME_NAME "gActiveMaxChannelTime" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_MIN ( 0 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT ( 50 ) + +#define CFG_ACTIVE_MIN_CHANNEL_TIME_NAME "gActiveMinChannelTime" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_MIN ( 0 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_MAX ( 10000 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_DEFAULT ( 30 ) + +/* Max Dwell time during BTC eSCO call in msec*/ +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_NAME "gActiveMaxChannelTimeBtc" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN ( 0 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX ( 10000 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_DEFAULT ( 120 ) + +/* Min Dwell time during BTC eSCO call in msec*/ +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_NAME "gActiveMinChannelTimeBtc" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN ( 0 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX ( 10000 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_DEFAULT ( 60 ) + +/* Min Dwell time during BTC SCO call in msec*/ +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_NAME "gActiveMinChannelTimeBtcSCO" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN (0) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX (10000) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_DEFAULT (20) + +/* Max Dwell time during BTC SCO call in msec*/ +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_NAME "gActiveMaxChannelTimeBtcSCO" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN (0) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX (10000) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_DEFAULT (40) + +#define CFG_RETRY_LIMIT_ZERO_NAME "gRetryLimitZero" +#define CFG_RETRY_LIMIT_ZERO_MIN ( 0 ) +#define CFG_RETRY_LIMIT_ZERO_MAX ( 15 ) +#define CFG_RETRY_LIMIT_ZERO_DEFAULT ( 5 ) + +#define CFG_RETRY_LIMIT_ONE_NAME "gRetryLimitOne" +#define CFG_RETRY_LIMIT_ONE_MIN ( 0 ) +#define CFG_RETRY_LIMIT_ONE_MAX ( 15 ) +#define CFG_RETRY_LIMIT_ONE_DEFAULT ( 10 ) + +#define CFG_RETRY_LIMIT_TWO_NAME "gRetryLimitTwo" +#define CFG_RETRY_LIMIT_TWO_MIN ( 0 ) +#define CFG_RETRY_LIMIT_TWO_MAX ( 15 ) +#define CFG_RETRY_LIMIT_TWO_DEFAULT ( 15 ) + +#define CFG_DISABLE_AGG_WITH_BTC_NAME "gDisableAggWithBTC" +#define CFG_DISABLE_AGG_WITH_BTC_MIN ( 0 ) +#define CFG_DISABLE_AGG_WITH_BTC_MAX ( 1 ) +#define CFG_DISABLE_AGG_WITH_BTC_DEFAULT ( 1 ) + +#ifdef WLAN_AP_STA_CONCURRENCY + +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_NAME "gPassiveMaxChannelTimeConc" +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_DEFAULT ( 110 ) + +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_NAME "gPassiveMinChannelTimeConc" +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_DEFAULT ( 60 ) + +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_NAME "gActiveMaxChannelTimeConc" +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_DEFAULT ( 40 ) + +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_NAME "gActiveMinChannelTimeConc" +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN ( 0 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX ( 10000 ) +#define CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_DEFAULT ( 20 ) + +#define CFG_REST_TIME_CONC_NAME "gRestTimeConc" +#define CFG_REST_TIME_CONC_MIN ( 0 ) +#define CFG_REST_TIME_CONC_MAX ( 10000 ) +#define CFG_REST_TIME_CONC_DEFAULT ( 100 ) + +#define CFG_NUM_STA_CHAN_COMBINED_CONC_NAME "gNumStaChanCombinedConc" +#define CFG_NUM_STA_CHAN_COMBINED_CONC_MIN ( 1 ) +#define CFG_NUM_STA_CHAN_COMBINED_CONC_MAX ( 255 ) +#define CFG_NUM_STA_CHAN_COMBINED_CONC_DEFAULT ( 3 ) + +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_NAME "gNumP2PChanCombinedConc" +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_MIN ( 1 ) +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_MAX ( 255 ) +#define CFG_NUM_P2P_CHAN_COMBINED_CONC_DEFAULT ( 1 ) + +#endif + +#define CFG_MAX_PS_POLL_NAME "gMaxPsPoll" +#define CFG_MAX_PS_POLL_MIN WNI_CFG_MAX_PS_POLL_STAMIN +#define CFG_MAX_PS_POLL_MAX WNI_CFG_MAX_PS_POLL_STAMAX +#define CFG_MAX_PS_POLL_DEFAULT WNI_CFG_MAX_PS_POLL_STADEF + +#define CFG_MAX_TX_POWER_NAME "gTxPowerCap" +#define CFG_MAX_TX_POWER_MIN WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN +#define CFG_MAX_TX_POWER_MAX WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX +//Not to use CFG default because if no registry setting, this is ignored by SME. +#define CFG_MAX_TX_POWER_DEFAULT WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX + + +#define CFG_LOW_GAIN_OVERRIDE_NAME "gLowGainOverride" +#define CFG_LOW_GAIN_OVERRIDE_MIN WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN +#define CFG_LOW_GAIN_OVERRIDE_MAX WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX +#define CFG_LOW_GAIN_OVERRIDE_DEFAULT WNI_CFG_LOW_GAIN_OVERRIDE_STADEF + +#define CFG_RSSI_FILTER_PERIOD_NAME "gRssiFilterPeriod" +#define CFG_RSSI_FILTER_PERIOD_MIN WNI_CFG_RSSI_FILTER_PERIOD_STAMIN +#define CFG_RSSI_FILTER_PERIOD_MAX WNI_CFG_RSSI_FILTER_PERIOD_STAMAX +// Increased this value for Non-ESE AP. This is cause FW RSSI Monitoring +// the consumer of this value is ON by default. So to impact power numbers +// we are setting this to a high value. +#define CFG_RSSI_FILTER_PERIOD_DEFAULT WNI_CFG_RSSI_FILTER_PERIOD_STADEF + +#define CFG_IGNORE_DTIM_NAME "gIgnoreDtim" +#define CFG_IGNORE_DTIM_MIN WNI_CFG_IGNORE_DTIM_STAMIN +#define CFG_IGNORE_DTIM_MAX WNI_CFG_IGNORE_DTIM_STAMAX +#define CFG_IGNORE_DTIM_DEFAULT WNI_CFG_IGNORE_DTIM_STADEF + +#define CFG_MAX_LI_MODULATED_DTIM_NAME "gMaxLIModulatedDTIM" +#define CFG_MAX_LI_MODULATED_DTIM_MIN ( 1 ) +#define CFG_MAX_LI_MODULATED_DTIM_MAX ( 10 ) +#define CFG_MAX_LI_MODULATED_DTIM_DEFAULT ( 10 ) + +#define CFG_RX_ANT_CONFIGURATION_NAME "gNumRxAnt" +#define CFG_RX_ANT_CONFIGURATION_NAME_MIN ( 1 ) +#define CFG_RX_ANT_CONFIGURATION_NAME_MAX ( 2 ) +#define CFG_RX_ANT_CONFIGURATION_NAME_DEFAULT ( 2 ) + +#define CFG_FW_HEART_BEAT_MONITORING_NAME "gEnableFWHeartBeatMonitoring" +#define CFG_FW_HEART_BEAT_MONITORING_MIN ( 0 ) +#define CFG_FW_HEART_BEAT_MONITORING_MAX ( 1 ) +#define CFG_FW_HEART_BEAT_MONITORING_DEFAULT ( 1 ) + +#define CFG_FW_BEACON_FILTERING_NAME "gEnableFWBeaconFiltering" +#define CFG_FW_BEACON_FILTERING_MIN ( 0 ) +#define CFG_FW_BEACON_FILTERING_MAX ( 1 ) +#define CFG_FW_BEACON_FILTERING_DEFAULT ( 1 ) + +#define CFG_FW_RSSI_MONITORING_NAME "gEnableFWRssiMonitoring" +#define CFG_FW_RSSI_MONITORING_MIN ( 0 ) +#define CFG_FW_RSSI_MONITORING_MAX ( 1 ) +#define CFG_FW_RSSI_MONITORING_DEFAULT ( 1 ) + +#define CFG_DATA_INACTIVITY_TIMEOUT_NAME "gDataInactivityTimeout" +#define CFG_DATA_INACTIVITY_TIMEOUT_MIN ( 1 ) +#define CFG_DATA_INACTIVITY_TIMEOUT_MAX ( 255 ) +#define CFG_DATA_INACTIVITY_TIMEOUT_DEFAULT ( 20 ) + +#define CFG_NTH_BEACON_FILTER_NAME "gNthBeaconFilter" +#define CFG_NTH_BEACON_FILTER_MIN ( WNI_CFG_NTH_BEACON_FILTER_STAMIN ) +#define CFG_NTH_BEACON_FILTER_MAX ( WNI_CFG_NTH_BEACON_FILTER_STAMAX ) +#define CFG_NTH_BEACON_FILTER_DEFAULT ( WNI_CFG_NTH_BEACON_FILTER_STADEF ) + +#define CFG_RF_SETTLING_TIME_CLK_NAME "rfSettlingTimeUs" +#define CFG_RF_SETTLING_TIME_CLK_MIN ( 0 ) +#define CFG_RF_SETTLING_TIME_CLK_MAX ( 60000 ) +#define CFG_RF_SETTLING_TIME_CLK_DEFAULT ( 1500 ) + +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_NAME "gStaKeepAlivePeriod" +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MIN ( 0 ) +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX ( 65535) +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT ( 30 ) + +//WMM configuration +#define CFG_QOS_WMM_MODE_NAME "WmmIsEnabled" +#define CFG_QOS_WMM_MODE_MIN (0) +#define CFG_QOS_WMM_MODE_MAX (2) //HDD_WMM_NO_QOS +#define CFG_QOS_WMM_MODE_DEFAULT (0) //HDD_WMM_AUTO + +#define CFG_QOS_WMM_80211E_ENABLED_NAME "80211eIsEnabled" +#define CFG_QOS_WMM_80211E_ENABLED_MIN (0) +#define CFG_QOS_WMM_80211E_ENABLED_MAX (1) +#define CFG_QOS_WMM_80211E_ENABLED_DEFAULT (0) + +#define CFG_QOS_WMM_UAPSD_MASK_NAME "UapsdMask" // ACs to setup U-APSD for at assoc +#define CFG_QOS_WMM_UAPSD_MASK_MIN (0x00) +#define CFG_QOS_WMM_UAPSD_MASK_MAX (0xFF) +#define CFG_QOS_WMM_UAPSD_MASK_DEFAULT (0xaa) +#define CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT (0x0) +#define CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT (0x0) + +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_NAME "InfraUapsdVoSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MAX (4294967295UL ) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_DEFAULT (20) + +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_NAME "InfraUapsdVoSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MAX (4294967295UL ) +#define CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_DEFAULT (2000) + +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_NAME "InfraUapsdViSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_DEFAULT (300) + +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_NAME "InfraUapsdViSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_DEFAULT (2000) + +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_NAME "InfraUapsdBeSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_DEFAULT (300) + +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_NAME "InfraUapsdBeSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_DEFAULT (2000) + +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_NAME "InfraUapsdBkSrvIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_DEFAULT (300) + +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_NAME "InfraUapsdBkSuspIntv" +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MIN (0) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_DEFAULT (2000) + +#ifdef FEATURE_WLAN_ESE +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_NAME "InfraInactivityInterval" +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MIN (0) +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MAX (4294967295UL) +#define CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_DEFAULT (0) //disabled + +#define CFG_ESE_FEATURE_ENABLED_NAME "EseEnabled" +#define CFG_ESE_FEATURE_ENABLED_MIN (0) +#define CFG_ESE_FEATURE_ENABLED_MAX (1) +#define CFG_ESE_FEATURE_ENABLED_DEFAULT (0) //disabled +#endif // FEATURE_WLAN_ESE + +#ifdef FEATURE_WLAN_LFR +#define CFG_LFR_FEATURE_ENABLED_NAME "FastRoamEnabled" +#define CFG_LFR_FEATURE_ENABLED_MIN (0) +#define CFG_LFR_FEATURE_ENABLED_MAX (1) +#define CFG_LFR_FEATURE_ENABLED_DEFAULT (0) //disabled + +#define CFG_LFR_MAWC_FEATURE_ENABLED_NAME "MAWCEnabled" +#define CFG_LFR_MAWC_FEATURE_ENABLED_MIN (0) +#define CFG_LFR_MAWC_FEATURE_ENABLED_MAX (1) +#define CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT (0) /* disabled */ +#endif // FEATURE_WLAN_LFR + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +// This flag will control fasttransition in case of 11r and ESE. +// Basically with this the whole neighbor roam, pre-auth, reassoc +// can be turned ON/OFF. +// With this turned OFF 11r will completely not work. +// For 11r this flag has to be ON. +// For ESE fastroam will not work. +#define CFG_FAST_TRANSITION_ENABLED_NAME "FastTransitionEnabled" +#define CFG_FAST_TRANSITION_ENABLED_NAME_MIN (0) +#define CFG_FAST_TRANSITION_ENABLED_NAME_MAX (1) +#define CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT (1) //Enabled + +/* This parameter is used to decide whether to Roam or not. + * AP1 is the currently associated AP and AP2 is chosen for roaming. + * The Roaming will happen only if AP2 has better Signal Quality and it has a RSSI better than AP1 + * in terms of RoamRssiDiff,and RoamRssiDiff is the number of units (typically measured in dB) AP2 + * is better than AP1. + * This check is not done if the value is Zero */ +#define CFG_ROAM_RSSI_DIFF_NAME "RoamRssiDiff" +#define CFG_ROAM_RSSI_DIFF_MIN (0) +#define CFG_ROAM_RSSI_DIFF_MAX (30) +#define CFG_ROAM_RSSI_DIFF_DEFAULT (5) + +/* + * Following a scan and if potential roam candidate(s) are found, + * then determine whether to register for reassoc threshold or roam + * immediately based on this configuration parameter. If the RSSI + * of any available candidate is better than the currently associated + * AP by at least gImmediateRoamRssiDiff, then being to roam + * immediately. + * NOTE: Value of 0 means that immediate roaming is enabled by default + */ +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_NAME "gImmediateRoamRssiDiff" +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_MIN (0) +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_MAX (125) +#define CFG_IMMEDIATE_ROAM_RSSI_DIFF_DEFAULT (0) + +/*This parameter is used to set Wireless Extended Security Mode.*/ +#define CFG_ENABLE_WES_MODE_NAME "gWESModeEnabled" +#define CFG_ENABLE_WES_MODE_NAME_MIN (0) +#define CFG_ENABLE_WES_MODE_NAME_MAX (1) +#define CFG_ENABLE_WES_MODE_NAME_DEFAULT (0) + +#define CFG_ROAM_SCAN_N_PROBES "gRoamScanNProbes" +#define CFG_ROAM_SCAN_N_PROBES_MIN (1) +#define CFG_ROAM_SCAN_N_PROBES_MAX (10) +#define CFG_ROAM_SCAN_N_PROBES_DEFAULT (2) + +#define CFG_ROAM_SCAN_HOME_AWAY_TIME "gRoamScanHomeAwayTime" +#define CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN (3) +#define CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX (300) +#define CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT (CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) +#endif /* (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) */ + +#ifdef FEATURE_WLAN_OKC +#define CFG_OKC_FEATURE_ENABLED_NAME "OkcEnabled" +#define CFG_OKC_FEATURE_ENABLED_MIN (0) +#define CFG_OKC_FEATURE_ENABLED_MAX (1) +#define CFG_OKC_FEATURE_ENABLED_DEFAULT (1) +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED "gRoamScanOffloadEnabled" +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN (0) +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX (1) +#define CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT (1) + +/* Enable/disable PER based roaming */ +#define CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED "gPERRoamEnable" +#define CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED_MIN (0) +#define CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED_MAX (1) +#define CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT (0) + +/* + * Rate at which to stop monitoring data rates for PER based Roam + * Value: MBPS * 10 + * Min: Minimum rate of data transfer + * Max: Max rate for 1x1 transmission + */ +#define CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD "gPERRoamUpThresholdRate" +#define CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD_MIN (20) +#define CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD_MAX (3330) +#define CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD_DEFAULT (400) + +/* + * rate at which to start monitoring data rates for PER based roam + * Value: MBPS * 10 + */ +#define CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD "gPERRoamDownThresholdRate" +#define CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD_MIN (10) +#define CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD_MAX (3330) +#define CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD_DEFAULT (200) + +/* + * time to wait before start monitoring again once a roam scan has been + * triggered. (Minimum time difference between two scans) + * Value : seconds + */ +#define CFG_PER_ROAM_SCAN_WAIT_TIME "gPERRoamScanInterval" +#define CFG_PER_ROAM_SCAN_WAIT_TIME_MIN (10) +#define CFG_PER_ROAM_SCAN_WAIT_TIME_MAX (3600) +#define CFG_PER_ROAM_SCAN_WAIT_TIME_DEFAULT (300) + +/* Time to collect stats to trigger roam scan for Tx path */ +#define CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD "gPERRoamStatsTime" +#define CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD_MIN (5) +#define CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD_MAX (25) +#define CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD_DEFAULT (10) + +/* Rx monitoring is enabled to trigger a PER based roam scan */ +#define CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED "gPERRoamRxMonitorEnable" +#define CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED_MIN (0) +#define CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED_MAX (1) +#define CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED_DEFAULT (1) + +/* + * Minimum number of packets required to consider if PER based roam scan + * needs to be triggered in Rx + */ +#define CFG_PER_ROAM_SCAN_RX_MIN_PACKETS "gPERRoamRxPktThreshold" +#define CFG_PER_ROAM_SCAN_RX_MIN_PACKETS_MIN (10) +#define CFG_PER_ROAM_SCAN_RX_MIN_PACKETS_MAX (10000) +#define CFG_PER_ROAM_SCAN_RX_MIN_PACKETS_DEFAULT (50) + +/* + * Minimum percentage of packets needs to be below gPERRoamScanRateDownThreshold + * to trigger a roam scan + */ +#define CFG_PER_ROAM_SCAN_MIN_PERCENTAGE "gPERRoamTriggerPercent" +#define CFG_PER_ROAM_SCAN_MIN_PERCENTAGE_MIN (20) +#define CFG_PER_ROAM_SCAN_MIN_PERCENTAGE_MAX (100) +#define CFG_PER_ROAM_SCAN_MIN_PERCENTAGE_DEFAULT (60) + +/* Channel sensing is enabled/disabled for PER based roam scan */ +#define CFG_PER_ROAM_SCAN_CCA_ENABLED "gPERRoamCCAEnabled" +#define CFG_PER_ROAM_SCAN_CCA_ENABLED_MIN (0) +#define CFG_PER_ROAM_SCAN_CCA_ENABLED_MAX (1) +#define CFG_PER_ROAM_SCAN_CCA_ENABLED_DEFAULT (0) + +#define CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD "gPERRoamFullScanRssiDiffThreshold" +#define CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD_MIN (5) +#define CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD_MAX (50) +#define CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD_DEFAULT (10) + +/* + * Minimum RSSI value below which candidate will not be eligible for roam + */ +#define CFG_PER_ROAM_BAD_RSSI "gPERMinRssiThresholdForRoam" +#define CFG_PER_ROAM_BAD_RSSI_MIN (-100) +#define CFG_PER_ROAM_BAD_RSSI_MAX (-40) +#define CFG_PER_ROAM_BAD_RSSI_DEFAULT (-80) +#endif + +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME "PktClassificationBasis" // DSCP or 802.1Q +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MIN (0) +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MAX (1) +#define CFG_QOS_WMM_PKT_CLASSIFY_BASIS_DEFAULT (0) //DSCP + +/* default TSPEC parameters for AC_VO */ +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_NAME "InfraDirAcVo" +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_VO_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_NAME "InfraNomMsduSizeAcVo" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_DEFAULT (0x80D0) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_NAME "InfraMeanDataRateAcVo" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_DEFAULT (0x14500) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_NAME "InfraMinPhyRateAcVo" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_NAME "InfraSbaAcVo" +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_VO_DEFAULT (0x2001) + +/* default TSPEC parameters for AC_VI */ +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_NAME "InfraDirAcVi" +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_VI_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_NAME "InfraNomMsduSizeAcVi" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_DEFAULT (0x85DC) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_NAME "InfraMeanDataRateAcVi" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_DEFAULT (0x57E40) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_NAME "InfraMinPhyRateAcVi" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_NAME "InfraSbaAcVi" +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_VI_DEFAULT (0x2001) + +/* default TSPEC parameters for AC_BE*/ +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_NAME "InfraDirAcBe" +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_BE_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_NAME "InfraNomMsduSizeAcBe" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_DEFAULT (0x85DC) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_NAME "InfraMeanDataRateAcBe" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_DEFAULT (0x493E0) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_NAME "InfraMinPhyRateAcBe" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_NAME "InfraSbaAcBe" +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_BE_DEFAULT (0x2001) + +/* default TSPEC parameters for AC_Bk*/ +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_NAME "InfraDirAcBk" +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_MIN (0) +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_MAX (3) +#define CFG_QOS_WMM_INFRA_DIR_AC_BK_DEFAULT (3) //WLAN_QCT_CUST_WMM_TSDIR_BOTH + +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_NAME "InfraNomMsduSizeAcBk" +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MIN (0x0) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_DEFAULT (0x85DC) + +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_NAME "InfraMeanDataRateAcBk" +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_DEFAULT (0x493E0) + +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_NAME "InfraMinPhyRateAcBk" +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MIN (0x0) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MAX (0xFFFFFFFF) +#define CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_DEFAULT (0x5B8D80) + +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_NAME "InfraSbaAcBk" +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_MIN (0x2001) +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_MAX (0xFFFF) +#define CFG_QOS_WMM_INFRA_SBA_AC_BK_DEFAULT (0x2001) + +// TL configuration +#define CFG_TL_WFQ_BK_WEIGHT_NAME "WfqBkWeight" +#define CFG_TL_WFQ_BK_WEIGHT_MIN 1 +#define CFG_TL_WFQ_BK_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_BK_WEIGHT_DEFAULT 1 + +#define CFG_TL_WFQ_BE_WEIGHT_NAME "WfqBeWeight" +#define CFG_TL_WFQ_BE_WEIGHT_MIN 1 +#define CFG_TL_WFQ_BE_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_BE_WEIGHT_DEFAULT 3 + +#define CFG_TL_WFQ_VI_WEIGHT_NAME "WfqViWeight" +#define CFG_TL_WFQ_VI_WEIGHT_MIN 1 +#define CFG_TL_WFQ_VI_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_VI_WEIGHT_DEFAULT 7 + +#define CFG_TL_WFQ_VO_WEIGHT_NAME "WfqVoWeight" +#define CFG_TL_WFQ_VO_WEIGHT_MIN 1 +#define CFG_TL_WFQ_VO_WEIGHT_MAX 0xFF +#define CFG_TL_WFQ_VO_WEIGHT_DEFAULT 7 + +#define CFG_TL_DELAYED_TRGR_FRM_INT_NAME "DelayedTriggerFrmInt" +#define CFG_TL_DELAYED_TRGR_FRM_INT_MIN 1 +#define CFG_TL_DELAYED_TRGR_FRM_INT_MAX (4294967295UL) +#define CFG_TL_DELAYED_TRGR_FRM_INT_DEFAULT 3000 + +#define CFG_REORDER_TIME_BK_NAME "BkReorderTime" +#define CFG_REORDER_TIME_BK_MIN 30 +#define CFG_REORDER_TIME_BK_MAX 1000 +#define CFG_REORDER_TIME_BK_DEFAULT 100 + +#define CFG_REORDER_TIME_BE_NAME "BeReorderTime" +#define CFG_REORDER_TIME_BE_MIN 30 +#define CFG_REORDER_TIME_BE_MAX 1000 +#define CFG_REORDER_TIME_BE_DEFAULT 100 + +#define CFG_REORDER_TIME_VI_NAME "ViReorderTime" +#define CFG_REORDER_TIME_VI_MIN 30 +#define CFG_REORDER_TIME_VI_MAX 1000 +#define CFG_REORDER_TIME_VI_DEFAULT 100 + +#define CFG_REORDER_TIME_VO_NAME "VoReorderTime" +#define CFG_REORDER_TIME_VO_MIN 30 +#define CFG_REORDER_TIME_VO_MAX 1000 +#define CFG_REORDER_TIME_VO_DEFAULT 40 + +#if defined WLAN_FEATURE_VOWIFI +#define CFG_RRM_ENABLE_NAME "gRrmEnable" +#define CFG_RRM_ENABLE_MIN (0) +#define CFG_RRM_ENABLE_MAX (1) +#define CFG_RRM_ENABLE_DEFAULT (0) + +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_NAME "gRrmOperChanMax" //section 11.10.3 IEEE std. 802.11k-2008 +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_MIN (0) //Maxduration = 2^(maxDuration - 4) * bcnIntvl. +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_MAX (8) +#define CFG_RRM_OPERATING_CHAN_MAX_DURATION_DEFAULT (3) //max duration = 2^-1 * bcnIntvl (50% of bcn intvl) + +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_NAME "gRrmNonOperChanMax" //Same as above. +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MIN (0) +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MAX (8) +#define CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_DEFAULT (3) + +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_NAME "gRrmRandnIntvl" +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_MIN (10) +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_MAX (100) +#define CFG_RRM_MEAS_RANDOMIZATION_INTVL_DEFAULT (100) +#endif + +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_NAME "ImplicitQosIsEnabled" +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_MIN (0) +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_MAX (1) +#define CFG_QOS_IMPLICIT_SETUP_ENABLED_DEFAULT (1) + +#define CFG_ENABLE_LOGP_NAME "gEnableLogp" +#define CFG_ENABLE_LOGP_MIN ( 0 ) +#define CFG_ENABLE_LOGP_MAX ( 1 ) +#define CFG_ENABLE_LOGP_DEFAULT ( 1 ) + +#define CFG_BTC_EXECUTION_MODE_NAME "BtcExecutionMode" +#define CFG_BTC_EXECUTION_MODE_MIN ( 0 ) +#define CFG_BTC_EXECUTION_MODE_MAX ( 5 ) +#define CFG_BTC_EXECUTION_MODE_DEFAULT ( 0 ) + +#define CFG_BTC_DHCP_PROTECTION_NAME "BtcConsBtSlotToBlockDuringDhcp" +#define CFG_BTC_DHCP_PROTECTION_MIN ( 0 ) +#define CFG_BTC_DHCP_PROTECTION_MAX ( 0xFF ) +#define CFG_BTC_DHCP_PROTECTION_DEFAULT ( 0 ) + +#define CFG_BTC_A2DP_DHCP_PROTECTION_NAME "BtcA2DPDhcpProtectLevel" +#define CFG_BTC_A2DP_DHCP_PROTECTION_MIN ( 0 ) +#define CFG_BTC_A2DP_DHCP_PROTECTION_MAX ( 0xFF ) +#define CFG_BTC_A2DP_DHCP_PROTECTION_DEFAULT ( 7 ) + +#define CFG_BTC_STATIC_LEN_INQ_BT_NAME "btcStaticLenInqBt" +#define CFG_BTC_STATIC_LEN_INQ_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_INQ_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_INQ_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_PAGE_BT_NAME "btcStaticLenPageBt" +#define CFG_BTC_STATIC_LEN_PAGE_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_PAGE_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_PAGE_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_CONN_BT_NAME "btcStaticLenConnBt" +#define CFG_BTC_STATIC_LEN_CONN_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_CONN_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_CONN_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_LE_BT_NAME "btcStaticLenLeBt" +#define CFG_BTC_STATIC_LEN_LE_BT_MIN ( 5000 ) +#define CFG_BTC_STATIC_LEN_LE_BT_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_LE_BT_DEFAULT ( 120000 ) + +#define CFG_BTC_STATIC_LEN_INQ_WLAN_NAME "btcStaticLenInqWlan" +#define CFG_BTC_STATIC_LEN_INQ_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_INQ_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_INQ_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_NAME "btcStaticLenPageWlan" +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_PAGE_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_STATIC_LEN_CONN_WLAN_NAME "btcStaticLenConnWlan" +#define CFG_BTC_STATIC_LEN_CONN_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_CONN_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_CONN_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_STATIC_LEN_LE_WLAN_NAME "btcStaticLenLeWlan" +#define CFG_BTC_STATIC_LEN_LE_WLAN_MIN ( 0 ) +#define CFG_BTC_STATIC_LEN_LE_WLAN_MAX ( 500000 ) +#define CFG_BTC_STATIC_LEN_LE_WLAN_DEFAULT ( 30000 ) + +#define CFG_BTC_DYN_MAX_LEN_BT_NAME "btcDynMaxLenBt" +#define CFG_BTC_DYN_MAX_LEN_BT_MIN ( 25000 ) +#define CFG_BTC_DYN_MAX_LEN_BT_MAX ( 500000 ) +#define CFG_BTC_DYN_MAX_LEN_BT_DEFAULT ( 250000 ) + +#define CFG_BTC_DYN_MAX_LEN_WLAN_NAME "btcDynMaxLenWlan" +#define CFG_BTC_DYN_MAX_LEN_WLAN_MIN ( 15000 ) +#define CFG_BTC_DYN_MAX_LEN_WLAN_MAX ( 500000 ) +#define CFG_BTC_DYN_MAX_LEN_WLAN_DEFAULT ( 45000 ) + +#define CFG_BTC_MAX_SCO_BLOCK_PERC_NAME "btcMaxScoBlockPerc" +#define CFG_BTC_MAX_SCO_BLOCK_PERC_MIN ( 0 ) +#define CFG_BTC_MAX_SCO_BLOCK_PERC_MAX ( 100 ) +#define CFG_BTC_MAX_SCO_BLOCK_PERC_DEFAULT ( 1 ) + +#define CFG_BTC_DHCP_PROT_ON_A2DP_NAME "btcDhcpProtOnA2dp" +#define CFG_BTC_DHCP_PROT_ON_A2DP_MIN ( 0 ) +#define CFG_BTC_DHCP_PROT_ON_A2DP_MAX ( 1 ) +#define CFG_BTC_DHCP_PROT_ON_A2DP_DEFAULT ( 1 ) + +#define CFG_BTC_DHCP_PROT_ON_SCO_NAME "btcDhcpProtOnSco" +#define CFG_BTC_DHCP_PROT_ON_SCO_MIN ( 0 ) +#define CFG_BTC_DHCP_PROT_ON_SCO_MAX ( 1 ) +#define CFG_BTC_DHCP_PROT_ON_SCO_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V1_WAN_FREQ_NAME "mwsCoexVictim1WANFreq" +#define CFG_MWS_COEX_VX_WAN_FREQ_MIN ( 0 ) +#define CFG_MWS_COEX_VX_WAN_FREQ_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V1_WLAN_FREQ_NAME "mwsCoexVictim1WLANFreq" +#define CFG_MWS_COEX_VX_WLAN_FREQ_MIN ( 0 ) +#define CFG_MWS_COEX_VX_WLAN_FREQ_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V1_CONFIG_NAME "mwsCoexVictim1Config" +#define CFG_MWS_COEX_V1_CONFIG2_NAME "mwsCoexVictim1Config2" +#define CFG_MWS_COEX_VX_CONFIG_MIN ( 0 ) +#define CFG_MWS_COEX_VX_CONFIG_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_VX_CONFIG_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_V2_WAN_FREQ_NAME "mwsCoexVictim2WANFreq" +#define CFG_MWS_COEX_V2_WLAN_FREQ_NAME "mwsCoexVictim2WLANFreq" +#define CFG_MWS_COEX_V2_CONFIG_NAME "mwsCoexVictim2Config" +#define CFG_MWS_COEX_V2_CONFIG2_NAME "mwsCoexVictim2Config2" +#define CFG_MWS_COEX_V3_WAN_FREQ_NAME "mwsCoexVictim3WANFreq" +#define CFG_MWS_COEX_V3_WLAN_FREQ_NAME "mwsCoexVictim3WLANFreq" +#define CFG_MWS_COEX_V3_CONFIG_NAME "mwsCoexVictim3Config" +#define CFG_MWS_COEX_V3_CONFIG2_NAME "mwsCoexVictim3Config2" +#define CFG_MWS_COEX_V4_WAN_FREQ_NAME "mwsCoexVictim4WANFreq" +#define CFG_MWS_COEX_V4_WLAN_FREQ_NAME "mwsCoexVictim4WLANFreq" +#define CFG_MWS_COEX_V4_CONFIG_NAME "mwsCoexVictim4Config" +#define CFG_MWS_COEX_V4_CONFIG2_NAME "mwsCoexVictim4Config2" +#define CFG_MWS_COEX_V5_WAN_FREQ_NAME "mwsCoexVictim5WANFreq" +#define CFG_MWS_COEX_V5_WLAN_FREQ_NAME "mwsCoexVictim5WLANFreq" +#define CFG_MWS_COEX_V5_CONFIG_NAME "mwsCoexVictim5Config" +#define CFG_MWS_COEX_V5_CONFIG2_NAME "mwsCoexVictim5Config2" +#define CFG_MWS_COEX_V6_WAN_FREQ_NAME "mwsCoexVictim6WANFreq" +#define CFG_MWS_COEX_V6_WLAN_FREQ_NAME "mwsCoexVictim6WLANFreq" +#define CFG_MWS_COEX_V6_CONFIG_NAME "mwsCoexVictim6Config" +#define CFG_MWS_COEX_V6_CONFIG2_NAME "mwsCoexVictim6Config2" +#define CFG_MWS_COEX_V7_WAN_FREQ_NAME "mwsCoexVictim7WANFreq" +#define CFG_MWS_COEX_V7_WLAN_FREQ_NAME "mwsCoexVictim7WLANFreq" +#define CFG_MWS_COEX_V7_CONFIG_NAME "mwsCoexVictim7Config" +#define CFG_MWS_COEX_V7_CONFIG2_NAME "mwsCoexVictim7Config2" +#define CFG_MWS_COEX_V8_WAN_FREQ_NAME "mwsCoexVictim8WANFreq" +#define CFG_MWS_COEX_V8_WLAN_FREQ_NAME "mwsCoexVictim8WLANFreq" +#define CFG_MWS_COEX_V8_CONFIG_NAME "mwsCoexVictim8Config" +#define CFG_MWS_COEX_V8_CONFIG2_NAME "mwsCoexVictim8Config2" +#define CFG_MWS_COEX_V9_WAN_FREQ_NAME "mwsCoexVictim9WANFreq" +#define CFG_MWS_COEX_V9_WLAN_FREQ_NAME "mwsCoexVictim9WLANFreq" +#define CFG_MWS_COEX_V9_CONFIG_NAME "mwsCoexVictim9Config" +#define CFG_MWS_COEX_V9_CONFIG2_NAME "mwsCoexVictim9Config2" +#define CFG_MWS_COEX_V10_WAN_FREQ_NAME "mwsCoexVictim10WANFreq" +#define CFG_MWS_COEX_V10_WLAN_FREQ_NAME "mwsCoexVictim10WLANFreq" +#define CFG_MWS_COEX_V10_CONFIG_NAME "mwsCoexVictim10Config" +#define CFG_MWS_COEX_V10_CONFIG2_NAME "mwsCoexVictim10Config2" + +#define CFG_MWS_COEX_MODEM_BACKOFF_NAME "mwsCoexModemBackoff" +#define CFG_MWS_COEX_MODEM_BACKOFF_MIN ( 0 ) +#define CFG_MWS_COEX_MODEM_BACKOFF_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_MODEM_BACKOFF_DEFAULT ( 0 ) + +#define CFG_MWS_COEX_CONFIG1_NAME "mwsCoexConfig1" +#define CFG_MWS_COEX_CONFIGX_MIN ( 0 ) +#define CFG_MWS_COEX_CONFIGX_MAX ( 0xFFFFFFFF ) +#define CFG_MWS_COEX_CONFIGX_DEFAULT ( 0 ) +#define CFG_MWS_COEX_CONFIG2_NAME "mwsCoexConfig2" +#define CFG_MWS_COEX_CONFIG3_NAME "mwsCoexConfig3" +#define CFG_MWS_COEX_CONFIG4_NAME "mwsCoexConfig4" +#define CFG_MWS_COEX_CONFIG5_NAME "mwsCoexConfig5" +#define CFG_MWS_COEX_CONFIG6_NAME "mwsCoexConfig6" + +#define CFG_SAR_POWER_BACKOFF_NAME "SARPowerBackoff" +#define CFG_SAR_POWER_BACKOFF_MIN ( 0 ) +#define CFG_SAR_POWER_BACKOFF_MAX ( 0xFFFFFFFF ) +#define CFG_SAR_POWER_BACKOFF_DEFAULT ( 13 ) + +#if defined WLAN_FEATURE_VOWIFI_11R +#define CFG_FT_RESOURCE_REQ_NAME "gFTResourceReqSupported" +#define CFG_FT_RESOURCE_REQ_MIN (0) +#define CFG_FT_RESOURCE_REQ_MAX (1) +#define CFG_FT_RESOURCE_REQ_DEFAULT (0) +#endif + +#define CFG_TELE_BCN_TRANS_LI_NAME "telescopicBeaconTransListenInterval" +#define CFG_TELE_BCN_TRANS_LI_MIN ( 0 ) +#define CFG_TELE_BCN_TRANS_LI_MAX ( 7 ) +#define CFG_TELE_BCN_TRANS_LI_DEFAULT ( 3 ) + +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_NAME "telescopicBeaconTransListenIntervalNumIdleBcns" +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MIN ( 5 ) +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MAX ( 255 ) +#define CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_DEFAULT ( 10 ) + +#define CFG_TELE_BCN_MAX_LI_NAME "telescopicBeaconMaxListenInterval" +#define CFG_TELE_BCN_MAX_LI_MIN ( 0 ) +#define CFG_TELE_BCN_MAX_LI_MAX ( 7 ) +#define CFG_TELE_BCN_MAX_LI_DEFAULT ( 5 ) + +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_NAME "telescopicBeaconMaxListenIntervalNumIdleBcns" +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MIN ( 5 ) +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MAX ( 255 ) +#define CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_DEFAULT ( 15 ) + +#define CFG_BCN_EARLY_TERM_WAKE_NAME "beaconEarlyTerminationWakeInterval" +#define CFG_BCN_EARLY_TERM_WAKE_MIN ( 2 ) +#define CFG_BCN_EARLY_TERM_WAKE_MAX ( 255 ) +#define CFG_BCN_EARLY_TERM_WAKE_DEFAULT ( 3 ) + +#define CFG_ENABLE_ROAM_DELAY_STATS "gEnableRoamDelayStats" +#define CFG_ENABLE_ROAM_DELAY_STATS_MIN ( 0 ) +#define CFG_ENABLE_ROAM_DELAY_STATS_MAX ( 1 ) +#define CFG_ENABLE_ROAM_DELAY_STATS_DEFAULT ( 0 ) + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME "gNeighborScanTimerPeriod" +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN (3) +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX (300) +#define CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT (200) + +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_NAME "gNeighborReassocThreshold" +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MIN (10) +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MAX (125) +#define CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_DEFAULT (83) + +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_NAME "gNeighborLookupThreshold" +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN (0) +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX (120) +#define CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT (0) /*A Zero value indicates the host to calculate + Adaptive thresold based on the minimum + supported data rate.*/ + +#define CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME "gNeighborScanChannelList" +#define CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT "" + +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME "gNeighborScanChannelMinTime" +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN (10) +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX (40) +#define CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT (20) + +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_NAME "gNeighborScanChannelMaxTime" +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN (3) +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX (300) +#define CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT (30) + +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_NAME "gMaxNeighborReqTries" +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MIN (1) +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MAX (4) +#define CFG_11R_NEIGHBOR_REQ_MAX_TRIES_DEFAULT (3) + + +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_NAME "gNeighborScanRefreshPeriod" +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN (1000) +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX (60000) +#define CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT (20000) + +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_NAME "gEmptyScanRefreshPeriod" +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN (0) +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX (60000) +#define CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT (0) + +#define CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_NAME "gNeighborInitialForcedRoamTo5GhEnable" +#define CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MIN (0) +#define CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MAX (1) +#define CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_DEFAULT (0) + +/* + * gWeakZoneRssiThresholdForRoam is the minimum threshold value to get + * candidate list from firmware, firmware filters the received candidate with + * this param before sending candidate list to host. + */ +#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_NAME "gWeakZoneRssiThresholdForRoam" +#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MIN (40) +#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MAX (100) +#define CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_DEFAULT (80) + +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + +#define CFG_QOS_WMM_BURST_SIZE_DEFN_NAME "burstSizeDefinition" +#define CFG_QOS_WMM_BURST_SIZE_DEFN_MIN (0) +#define CFG_QOS_WMM_BURST_SIZE_DEFN_MAX (1) +#define CFG_QOS_WMM_BURST_SIZE_DEFN_DEFAULT (0) + +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_NAME "tsInfoAckPolicy" +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_MIN (0x00) +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_MAX (0x01) +#define CFG_QOS_WMM_TS_INFO_ACK_POLICY_DEFAULT (0x00) + +#define CFG_SINGLE_TID_RC_NAME "SingleTIDRC" +#define CFG_SINGLE_TID_RC_MIN (0) // Seperate replay counter for all TID +#define CFG_SINGLE_TID_RC_MAX (1) // Single replay counter for all TID +#define CFG_SINGLE_TID_RC_DEFAULT (1) +#define CFG_MCAST_BCAST_FILTER_SETTING_NAME "McastBcastFilter" +#define CFG_MCAST_BCAST_FILTER_SETTING_MIN (0) +#define CFG_MCAST_BCAST_FILTER_SETTING_MAX (3) +#define CFG_MCAST_BCAST_FILTER_SETTING_DEFAULT (0) + +#define CFG_DYNAMIC_PSPOLL_VALUE_NAME "gDynamicPSPollvalue" +#define CFG_DYNAMIC_PSPOLL_VALUE_MIN (0) +#define CFG_DYNAMIC_PSPOLL_VALUE_MAX (255) +#define CFG_DYNAMIC_PSPOLL_VALUE_DEFAULT (0) + +#define CFG_TELE_BCN_WAKEUP_EN_NAME "gTelescopicBeaconWakeupEn" +#define CFG_TELE_BCN_WAKEUP_EN_MIN (0) +#define CFG_TELE_BCN_WAKEUP_EN_MAX (1) +#define CFG_TELE_BCN_WAKEUP_EN_DEFAULT (0) + +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME "gAddTSWhenACMIsOff" +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MIN (0) +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MAX (1) //Send AddTs even when ACM is not set for the AC +#define CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_DEFAULT (0) + + +#define CFG_VALIDATE_SCAN_LIST_NAME "gValidateScanList" +#define CFG_VALIDATE_SCAN_LIST_MIN (0) +#define CFG_VALIDATE_SCAN_LIST_MAX (1) +#define CFG_VALIDATE_SCAN_LIST_DEFAULT (0) + +#define CFG_NULLDATA_AP_RESP_TIMEOUT_NAME "gNullDataApRespTimeout" +#define CFG_NULLDATA_AP_RESP_TIMEOUT_MIN ( WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN ) +#define CFG_NULLDATA_AP_RESP_TIMEOUT_MAX ( WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX ) +#define CFG_NULLDATA_AP_RESP_TIMEOUT_DEFAULT ( WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF ) + +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME "gApDataAvailPollInterval" +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN ( WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN ) +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX ( WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX ) +#define CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT ( WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF ) + +#define CFG_ENABLE_HOST_ARPOFFLOAD_NAME "hostArpOffload" +#define CFG_ENABLE_HOST_ARPOFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_HOST_ARPOFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_HOST_ARPOFFLOAD_DEFAULT ( 1 ) + +#define CFG_ENABLE_HOST_NSOFFLOAD_NAME "hostNSOffload" +#define CFG_ENABLE_HOST_NSOFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_HOST_NSOFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_HOST_NSOFFLOAD_DEFAULT ( 1 ) + + +#define CFG_ENABLE_BTAMP_NAME "gEnableBtAmp" +#define CFG_ENABLE_BTAMP_MIN ( 0 ) +#define CFG_ENABLE_BTAMP_MAX ( 1 ) +#define CFG_ENABLE_BTAMP_DEFAULT ( 0 ) + +#ifdef WLAN_BTAMP_FEATURE +#define CFG_BT_AMP_PREFERRED_CHANNEL_NAME "BtAmpPreferredChannel" +#define CFG_BT_AMP_PREFERRED_CHANNEL_MIN (1) +#define CFG_BT_AMP_PREFERRED_CHANNEL_MAX (11) +#define CFG_BT_AMP_PREFERRED_CHANNEL_DEFAULT (1) +#endif //WLAN_BTAMP_FEATURE + +#define CFG_BAND_CAPABILITY_NAME "BandCapability" +#define CFG_BAND_CAPABILITY_MIN (0) +#define CFG_BAND_CAPABILITY_MAX (2) +#define CFG_BAND_CAPABILITY_DEFAULT (1) + +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_NAME "enableBeaconEarlyTermination" +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_MIN ( 0 ) +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_MAX ( 1 ) +#define CFG_ENABLE_BEACON_EARLY_TERMINATION_DEFAULT ( 0 ) + +#define CFG_ENABLE_CLOSE_LOOP_NAME "gEnableCloseLoop" +#define CFG_ENABLE_CLOSE_LOOP_MIN WNI_CFG_FIXED_RATE_STAMIN +#define CFG_ENABLE_CLOSE_LOOP_MAX WNI_CFG_FIXED_RATE_STAMAX +#define CFG_ENABLE_CLOSE_LOOP_DEFAULT WNI_CFG_FIXED_RATE_STADEF + +#define CFG_ENABLE_BYPASS_11D_NAME "gEnableBypass11d" +#define CFG_ENABLE_BYPASS_11D_MIN ( 0 ) +#define CFG_ENABLE_BYPASS_11D_MAX ( 1 ) +#define CFG_ENABLE_BYPASS_11D_DEFAULT ( 1 ) + +/* + * gEnableDFSChnlScan + * 0: disable scan on DFS channels + * 1: enables passive scan on DFS channels + * 2: enables active scan on DFS channels for static list. + * Static or cfg list is the channel list set by ioctl SETROAMSCANCHANNELS. +*/ +#define CFG_ENABLE_DFS_CHNL_SCAN_NAME "gEnableDFSChnlScan" +#define CFG_ENABLE_DFS_CHNL_SCAN_MIN ( 0 ) +#define CFG_ENABLE_DFS_CHNL_SCAN_MAX ( 2 ) +#define CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT ( 1 ) + +#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_NAME "gEnableDFSPnoChnlScan" +#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_MIN ( 0 ) +#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_MAX ( 1 ) +#define CFG_ENABLE_DFS_PNO_CHNL_SCAN_DEFAULT ( 1 ) + +/* + * gStaAuthRetriesForCode17 + * It is for an IOT issue. + * When DUT receives MAX_ASSOC_STA_REACHED_STATUS as + * response for Auth frame this ini decides how many + * times DUT has to retry. + * + * This is mainly for an AP where it wants to force + * the Station to connect to its 5G profile session + * (Dual band AP) by rejecting the Auth on 2.4G band. + * But if a station is only 2.4G capable it can try + * 3 times where third time AP will allow the + * station to connect to this AP. + */ +#define CFG_STA_AUTH_RETRIES_FOR_CODE17_NAME "gStaAuthRetriesForCode17" +#define CFG_STA_AUTH_RETRIES_FOR_CODE17_MIN ( 0 ) +#define CFG_STA_AUTH_RETRIES_FOR_CODE17_MAX ( 5 ) +#define CFG_STA_AUTH_RETRIES_FOR_CODE17_DEFAULT ( 0 ) + +typedef enum +{ + eHDD_LINK_SPEED_REPORT_ACTUAL = 0, + eHDD_LINK_SPEED_REPORT_MAX = 1, + eHDD_LINK_SPEED_REPORT_MAX_SCALED = 2, +}eHddLinkSpeedReportType; +#ifdef WLAN_FEATURE_11AC +#define CFG_VHT_CHANNEL_WIDTH "gVhtChannelWidth" +#define CFG_VHT_CHANNEL_WIDTH_MIN ( 0 ) +#define CFG_VHT_CHANNEL_WIDTH_MAX ( 2 ) +#define CFG_VHT_CHANNEL_WIDTH_DEFAULT ( 2 ) + +#define CFG_VHT_ENABLE_RX_MCS_8_9 "gVhtRxMCS" +#define CFG_VHT_ENABLE_RX_MCS_8_9_MIN ( 0 ) +#define CFG_VHT_ENABLE_RX_MCS_8_9_MAX ( 2 ) +#define CFG_VHT_ENABLE_RX_MCS_8_9_DEFAULT ( 0 ) + +#define CFG_VHT_ENABLE_TX_MCS_8_9 "gVhtTxMCS" +#define CFG_VHT_ENABLE_TX_MCS_8_9_MIN ( 0 ) +#define CFG_VHT_ENABLE_TX_MCS_8_9_MAX ( 2 ) +#define CFG_VHT_ENABLE_TX_MCS_8_9_DEFAULT ( 0 ) + +#endif + +#define CFG_REPORT_MAX_LINK_SPEED "gReportMaxLinkSpeed" +#define CFG_REPORT_MAX_LINK_SPEED_MIN ( eHDD_LINK_SPEED_REPORT_ACTUAL ) +#define CFG_REPORT_MAX_LINK_SPEED_MAX ( eHDD_LINK_SPEED_REPORT_MAX_SCALED ) +#define CFG_REPORT_MAX_LINK_SPEED_DEFAULT ( eHDD_LINK_SPEED_REPORT_MAX_SCALED ) + +/* + * RSSI Thresholds + * Used when eHDD_LINK_SPEED_REPORT_SCALED is selected + */ +#define CFG_LINK_SPEED_RSSI_HIGH "gLinkSpeedRssiHigh" +#define CFG_LINK_SPEED_RSSI_HIGH_MIN ( -127 ) +#define CFG_LINK_SPEED_RSSI_HIGH_MAX ( 0 ) +#define CFG_LINK_SPEED_RSSI_HIGH_DEFAULT ( -55 ) + +#define CFG_LINK_SPEED_RSSI_MID "gLinkSpeedRssiMed" +#define CFG_LINK_SPEED_RSSI_MID_MIN ( -127 ) +#define CFG_LINK_SPEED_RSSI_MID_MAX ( 0 ) +#define CFG_LINK_SPEED_RSSI_MID_DEFAULT ( -65 ) + +#define CFG_LINK_SPEED_RSSI_LOW "gLinkSpeedRssiLow" +#define CFG_LINK_SPEED_RSSI_LOW_MIN ( -127 ) +#define CFG_LINK_SPEED_RSSI_LOW_MAX ( 0 ) +#define CFG_LINK_SPEED_RSSI_LOW_DEFAULT ( -80 ) + +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_NAME "isP2pDeviceAddrAdministrated" +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MIN ( 0 ) +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MAX ( 1 ) +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_DEFAULT ( 1 ) + + +#define CFG_ENABLE_SSR "gEnableSSR" +#define CFG_ENABLE_SSR_MIN ( 0 ) +#define CFG_ENABLE_SSR_MAX ( 1 ) +#define CFG_ENABLE_SSR_DEFAULT ( 1 ) + +#define CFG_BTC_ACTIVE_WLAN_LEN_NAME "btcActiveWlanLen" +#define CFG_BTC_ACTIVE_WLAN_LEN_MIN ( 0 ) +#define CFG_BTC_ACTIVE_WLAN_LEN_MAX ( 250000 ) +#define CFG_BTC_ACTIVE_WLAN_LEN_DEFAULT ( 60000 ) + +#define CFG_BTC_ACTIVE_BT_LEN_NAME "btcActiveBtLen" +#define CFG_BTC_ACTIVE_BT_LEN_MIN ( 0 ) +#define CFG_BTC_ACTIVE_BT_LEN_MAX ( 250000 ) +#define CFG_BTC_ACTIVE_BT_LEN_DEFAULT ( 90000 ) + +#define CFG_BTC_SAP_ACTIVE_WLAN_LEN_NAME "btcSapActiveWlanLen" +#define CFG_BTC_SAP_ACTIVE_WLAN_LEN_MIN ( 0 ) +#define CFG_BTC_SAP_ACTIVE_WLAN_LEN_MAX ( 250000 ) +#define CFG_BTC_SAP_ACTIVE_WLAN_LEN_DEFAULT ( 30000 ) + +#define CFG_BTC_SAP_ACTIVE_BT_LEN_NAME "btcSapActiveBtLen" +#define CFG_BTC_SAP_ACTIVE_BT_LEN_MIN ( 0 ) +#define CFG_BTC_SAP_ACTIVE_BT_LEN_MAX ( 250000 ) +#define CFG_BTC_SAP_ACTIVE_BT_LEN_DEFAULT ( 30000 ) + +#define CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_NAME "gObssScanActiveDwellTime" +#define CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_MIN ( 5 ) +#define CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_MAX ( 1000 ) +#define CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_DEFAULT ( 10 ) + +#define CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_NAME "gObssScanPassiveDwellTime" +#define CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_MIN ( 10 ) +#define CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_MAX ( 1000 ) +#define CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_DEFAULT ( 20 ) + +#define CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_NAME "gObssScanWidthTriggerInterval" +#define CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_MIN ( 10 ) +#define CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_MAX ( 900 ) +#define CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_DEFAULT ( 200 ) + +/* RPS configurations */ +#define CFG_RPS_CPU_MAP_MIN (0) +#define CFG_RPS_CPU_MAP_MAX (0xff) + +#define CFG_RPS_CPU_MAP_NAME "rps_mask" +#define CFG_RPS_CPU_MAP_DEFAULT (0x00) + +#define CFG_MULTICAST_HOST_FW_MSGS "gMulticastHostMsgs" +#define CFG_MULTICAST_HOST_FW_MSGS_MIN (0) +#define CFG_MULTICAST_HOST_FW_MSGS_MAX (1) +#define CFG_MULTICAST_HOST_FW_MSGS_DEFAULT (1) + +#define CFG_ENABLE_TCP_DELACK_NAME "gEnableDelAck" +#define CFG_ENABLE_TCP_DELACK_MIN (0) +#define CFG_ENABLE_TCP_DELACK_MAX (1) +#define CFG_ENABLE_TCP_DELACK_DEFAULT (1) + +#ifdef SAP_AUTH_OFFLOAD +/* Enable/Disable SAP Authentication offload + * Default: enable + */ +#define CFG_ENABLE_SAP_AUTH_OFL_NAME "gEnableSAPAuthOffload" +#define CFG_ENABLE_SAP_AUTH_OFL_MIN ( 0 ) +#define CFG_ENABLE_SAP_AUTH_OFL_MAX ( 1 ) +#define CFG_ENABLE_SAP_AUTH_OFL_DEFAULT ( 1 ) + +/* SAP Authentication offload Security Type + * 0: None Security + * 1: WPA2-PSK CCMP + */ +#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_NAME "gSAPAuthOffloadSec" +#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_MIN ( 0 ) +#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_MAX ( 1 ) +#define CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT ( 0 ) + +/* SAP Authentication offload Security Key */ +#define CFG_SAP_AUTH_OFL_KEY_NAME "gSAPAuthOffloadKey" +#define CFG_SAP_AUTH_OFL_KEY_DEFAULT "" +#endif /* SAP_AUTH_OFFLOAD */ + +/* In cfg.dat 1=1MBPS, 2=2MBPS, 3=5_5MBPS, 4=11MBPS, 5=6MBPS, 6=9MBPS, + * 7=12MBPS, 8=18MBPS, 9=24MBPS. But 6=9MBPS and 8=18MBPS are not basic + * 11g rates and should not be set by gDefaultRateIndex24Ghz. So instead + * of using index 1-9 we will use 1-7 and if user set gDefaultRateIndex24Ghz=6 + * set 7=12MBPS in CFG and if user set gDefaultRateIndex24Ghz=7 set + * 9=24MBPS in CFG. +*/ + +#define HDD_DEFAULT_RATE_12MBPS 6 +#define HDD_DEFAULT_RATE_24MBPS 7 +#define CFG_DEFAULT_RATE_12MBPS 7 +#define CFG_DEFAULT_RATE_24MBPS 9 +#define CFG_DEFAULT_RATE_INDEX_24GH "gDefaultRateIndex24Ghz" +#define CFG_DEFAULT_RATE_INDEX_24GH_MIN ( 1 ) +#define CFG_DEFAULT_RATE_INDEX_24GH_MAX ( 7 ) +#define CFG_DEFAULT_RATE_INDEX_24GH_DEFAULT ( 1 ) + +/* + * This INI item is used to control subsystem restart(SSR) test framework + * Set its value to 1 to enable APPS trigerred SSR testing + */ + +#define CFG_ENABLE_CRASH_INJECT "gEnableForceTargetAssert" +#define CFG_ENABLE_CRASH_INJECT_MIN (0) +#define CFG_ENABLE_CRASH_INJECT_MAX (1) +#define CFG_ENABLE_CRASH_INJECT_DEFAULT (0) + +static __inline tANI_U32 defHddRateToDefCfgRate( tANI_U32 defRateIndex ) +{ + switch(defRateIndex){ + case HDD_DEFAULT_RATE_12MBPS: + return CFG_DEFAULT_RATE_12MBPS; + break; + case HDD_DEFAULT_RATE_24MBPS: + return CFG_DEFAULT_RATE_24MBPS; + break; + default: + return defRateIndex; + } +} +/* + * VOS Trace Enable Control + * Notes: + * the MIN/MAX/DEFAULT values apply for all modules + * the DEFAULT value is outside the valid range. if the DEFAULT + * value is not overridden, then no change will be made to the + * "built in" default values compiled into the code + * values are a bitmap indicating which log levels are to enabled + * (must match order of vos_trace_level enumerations) + * 00000001 FATAL + * 00000010 ERROR + * 00000100 WARN + * 00001000 INFO + * 00010000 INFO HIGH + * 00100000 INFO MED + * 01000000 INFO LOW + * 10000000 DEBUG + * + * hence a value of 0xFF would set all bits (enable all logs) + */ + +#define CFG_VOS_TRACE_ENABLE_BAP_NAME "vosTraceEnableBAP" +#define CFG_VOS_TRACE_ENABLE_TL_NAME "vosTraceEnableTL" +#define CFG_VOS_TRACE_ENABLE_WDI_NAME "vosTraceEnableWDI" +#define CFG_VOS_TRACE_ENABLE_HDD_NAME "vosTraceEnableHDD" +#define CFG_VOS_TRACE_ENABLE_SME_NAME "vosTraceEnableSME" +#define CFG_VOS_TRACE_ENABLE_PE_NAME "vosTraceEnablePE" +#define CFG_VOS_TRACE_ENABLE_PMC_NAME "vosTraceEnablePMC" +#define CFG_VOS_TRACE_ENABLE_WDA_NAME "vosTraceEnableWDA" +#define CFG_VOS_TRACE_ENABLE_SYS_NAME "vosTraceEnableSYS" +#define CFG_VOS_TRACE_ENABLE_VOSS_NAME "vosTraceEnableVOSS" +#define CFG_VOS_TRACE_ENABLE_SAP_NAME "vosTraceEnableSAP" +#define CFG_VOS_TRACE_ENABLE_HDD_SAP_NAME "vosTraceEnableHDDSAP" + +#define CFG_VOS_TRACE_ENABLE_MIN (0) +#define CFG_VOS_TRACE_ENABLE_MAX (0xff) +#define CFG_VOS_TRACE_ENABLE_DEFAULT (0xffff) + +/* + * WDI Trace Enable Control + * Notes: + * the MIN/MAX/DEFAULT values apply for all modules + * the DEFAULT value is outside the valid range. if the DEFAULT + * value is not overridden, then no change will be made to the + * "built in" default values compiled into the code + * values are a bitmap indicating which log levels are to enabled + * (must match order of wpt_tracelevel enumerations) + * 00000001 FATAL + * 00000010 ERROR + * 00000100 WARN + * 00001000 INFO + * 00010000 INFO HIGH + * 00100000 INFO MED + * 01000000 INFO LOW + * + * hence a value of 0x7F would set all bits (enable all logs) + */ +#define CFG_WDI_TRACE_ENABLE_DAL_NAME "wdiTraceEnableDAL" +#define CFG_WDI_TRACE_ENABLE_CTL_NAME "wdiTraceEnableCTL" +#define CFG_WDI_TRACE_ENABLE_DAT_NAME "wdiTraceEnableDAT" +#define CFG_WDI_TRACE_ENABLE_PAL_NAME "wdiTraceEnablePAL" +#define CFG_WDI_TRACE_ENABLE_MIN (0) +#define CFG_WDI_TRACE_ENABLE_MAX (0x7f) +#define CFG_WDI_TRACE_ENABLE_DEFAULT (0xffffffff) + +#define HDD_MCASTBCASTFILTER_FILTER_NONE 0x00 +#define HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST 0x01 +#define HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST 0x02 +#define HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST 0x03 +#define HDD_MULTICAST_FILTER_LIST 0x04 + +/* + * + * SAP Auto Channel Enable + * Notes: + * Auto Channel selection for SAP configuration + * 0 - Disable Auto Channel + * 1 - Enable auto channel selection in auto mode. + * When enable auto channel, channel provided by Supplicant will be ignored. + * + * Default configuration: Auto channel is disabled. + */ + +#define CFG_SAP_AUTO_CHANNEL_SELECTION_NAME "gApAutoChannelSelection" + +#define CFG_SAP_AUTO_CHANNEL_SELECTION_MIN ( 0 ) +#define CFG_SAP_AUTO_CHANNEL_SELECTION_MAX ( 1 ) +#define CFG_SAP_AUTO_CHANNEL_SELECTION_DEFAULT ( 0 ) + +/* ACS Scan band preference + * 0 -- No preference + * 1 -- Scan 2.4G first + * 2 -- Scan 5G first +*/ +#define CFG_SAP_SCAN_BAND_PREFERENCE "gAcsScanBandPreference" +#define CFG_SAP_SCAN_BAND_PREFERENCE_MIN (0) +#define CFG_SAP_SCAN_BAND_PREFERENCE_MAX (2) +#define CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT (0) +#define CFG_ACS_BAND_SWITCH_THRESHOLD "gACSBandSwitchThreshold" +#define CFG_ACS_BAND_SWITCH_THRESHOLD_MIN (0) +#define CFG_ACS_BAND_SWITCH_THRESHOLD_MAX (4444) +/* 2 BSS, maximus RSSI -90 */ +#define CFG_ACS_BAND_SWITCH_THRESHOLD_DEFAULT (296) + +/*BMPS Logic + * Notes: + * 1 - Then Host driver and above layers control the PS mechanism + * 0 - Diver/Core Stack internally control the Power saving mechanism + */ +#define CFG_ANDRIOD_POWER_SAVE_NAME "isAndroidPsEn" +#define CFG_ANDRIOD_POWER_SAVE_MIN ( 0 ) +#define CFG_ANDRIOD_POWER_SAVE_MAX ( 1 ) +#define CFG_ANDRIOD_POWER_SAVE_DEFAULT ( 0 ) + + +/* + * Enable Dynamic DTIM + * Options + * 0 -Disable DynamicDTIM + * 1 to 5 - SLM will switch to DTIM specified here when host suspends and + * switch DTIM1 when host resumes */ +#define CFG_ENABLE_DYNAMIC_DTIM_NAME "gEnableDynamicDTIM" +#define CFG_ENABLE_DYNAMIC_DTIM_MIN ( 0 ) +#define CFG_ENABLE_DYNAMIC_DTIM_MAX ( 5 ) +#define CFG_ENABLE_DYNAMIC_DTIM_DEFAULT ( 0 ) + +/* + * Enable First Scan 2G Only + * Options + * 0 - Disable First Scan 2G Option + * 1 - Enable First Scan 2G Option + */ +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME "gEnableFirstScan2GOnly" +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_MIN ( 0 ) +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_MAX ( 1 ) +#define CFG_ENABLE_FIRST_SCAN_2G_ONLY_DEFAULT ( 0 ) + +/* + * Skip DFS Channel in case of P2P Search + * Options + * 0 - Don't Skip DFS Channel in case of P2P Search + * 1 - Skip DFS Channel in case of P2P Search + */ +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_NAME "gSkipDfsChannelInP2pSearch" +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MIN ( 0 ) +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MAX ( 1 ) +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_DEFAULT ( 1 ) + +/* + * Ignore Dynamic Dtim in case of P2P + * Options + * 0 - Consider Dynamic Dtim incase of P2P + * 1 - Ignore Dynamic Dtim incase of P2P + */ +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_NAME "gIgnoreDynamicDtimInP2pMode" +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MIN ( 0 ) +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MAX ( 1 ) +#define CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_DEFAULT ( 0 ) + + +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_NAME "gEnableAutomaticTxPowerControl" +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MIN ( 0 ) +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MAX ( 1 ) +#define CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_DEFAULT ( 1 ) + +#define CFG_SHORT_GI_40MHZ_NAME "gShortGI40Mhz" +#define CFG_SHORT_GI_40MHZ_MIN 0 +#define CFG_SHORT_GI_40MHZ_MAX 1 +#define CFG_SHORT_GI_40MHZ_DEFAULT 1 + +/* + * Enable / Disable MCC feature + * Default: Enable + */ +#define CFG_ENABLE_MCC_ENABLED_NAME "gEnableMCCMode" +#define CFG_ENABLE_MCC_ENABLED_MIN ( 0 ) +#define CFG_ENABLE_MCC_ENABLED_MAX ( 1 ) +#define CFG_ENABLE_MCC_ENABLED_DEFAULT ( 1 ) + +/* + * Allow GO in MCC mode to accept different beacon interval than STA's. + * Added for Wi-Fi Cert. 5.1.12 + * Default: gAllowMCCGODiffBI = 2 + * If gAllowMCCGODiffBI = 1 // Set to 1 for WFA certification. GO Beacon + * interval is not changed. MCC GO + * doesn't work well in optimized way. + * In worst scenario, it may invite STA + * disconnection. + * gAllowMCCGODiffBI = 2 //If set to 2 workaround 1 disassoc all the clients + * and update beacon Interval + * gAllowMCCGODiffBI = 3 //If set to 3 tear down the P2P link in auto/ + * Non-autonomous -GO case + * gAllowMCCGODiffBI = 4 //If set to 4 don't disconnect the P2P client + * in autonomous/Non-autonomous -GO case update + * the BI dynamically + */ +#define CFG_ALLOW_MCC_GO_DIFF_BI_NAME "gAllowMCCGODiffBI" +#define CFG_ALLOW_MCC_GO_DIFF_BI_MIN ( 0 ) +#define CFG_ALLOW_MCC_GO_DIFF_BI_MAX ( 4 ) +#define CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT ( 4 ) + +/* + * Enable/Disable Thermal Mitigation feature + * Default: Disable + */ +#define CFG_THERMAL_MIGRATION_ENABLE_NAME "gThermalMitigationEnable" +#define CFG_THERMAL_MIGRATION_ENABLE_MIN ( 0 ) +#define CFG_THERMAL_MIGRATION_ENABLE_MAX ( 1 ) +#define CFG_THERMAL_MIGRATION_ENABLE_DEFAULT ( 1 ) + +/* + * Enable/Disable Modulated DTIM feature + * Default: Disable + */ +#define CFG_ENABLE_MODULATED_DTIM_NAME "gEnableModulatedDTIM" +#define CFG_ENABLE_MODULATED_DTIM_MIN ( 0 ) +#define CFG_ENABLE_MODULATED_DTIM_MAX ( 5 ) +#define CFG_ENABLE_MODULATED_DTIM_DEFAULT ( 0 ) + +/* + * Enable/Disable Multicast MAC Address List feature + * Default: Disable + */ +#define CFG_MC_ADDR_LIST_ENABLE_NAME "gMCAddrListEnable" +#define CFG_MC_ADDR_LIST_ENABLE_MIN ( 0 ) +#define CFG_MC_ADDR_LIST_ENABLE_MAX ( 1 ) +#define CFG_MC_ADDR_LIST_ENABLE_DEFAULT ( 0 ) + +/* Set number of buffers to be advertised during ADDBA negotiation*/ +#define CFG_NUM_BUFF_ADVERT_NAME "gNumBuffAdvert" +#define CFG_NUM_BUFF_ADVERT_MIN ( 0 ) +#define CFG_NUM_BUFF_ADVERT_MAX ( 128 ) +#define CFG_NUM_BUFF_ADVERT_DEFAULT ( 64 ) + +/* + * Allow MCC to modify config + */ +#define CFG_MCC_CONFIG_PARAM_NAME "gMccAllowCfgModify" +#define CFG_MCC_CONFIG_PARAM_MIN ( 0x0000 ) +#define CFG_MCC_CONFIG_PARAM_MAX ( 0x01ff ) +#define CFG_MCC_CONFIG_PARAM_DEFAULT ( 0x000C ) + +#define CFG_ENABLE_RX_STBC "gEnableRXSTBC" +#define CFG_ENABLE_RX_STBC_MIN ( 0 ) +#define CFG_ENABLE_RX_STBC_MAX ( 1 ) +#define CFG_ENABLE_RX_STBC_DEFAULT ( 1 ) + +/* + * Enable/Disable vsta based on MAX Assoc limit + * defined in WCNSS_qcom_cfg.ini. + */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define CFG_VSTA_SUPPORT_ENABLE "gEnableVSTASupport" +#define CFG_VSTA_SUPPORT_ENABLE_MIN ( 0 ) +#define CFG_VSTA_SUPPORT_ENABLE_MAX ( 1 ) +#define CFG_VSTA_SUPPORT_ENABLE_DEFAULT ( 0 ) +#endif + +#ifdef FEATURE_WLAN_TDLS +#define CFG_TDLS_SUPPORT_ENABLE "gEnableTDLSSupport" +#define CFG_TDLS_SUPPORT_ENABLE_MIN ( 0 ) +#define CFG_TDLS_SUPPORT_ENABLE_MAX ( 1 ) +#define CFG_TDLS_SUPPORT_ENABLE_DEFAULT ( 0 ) + +#define CFG_TDLS_IMPLICIT_TRIGGER "gEnableTDLSImplicitTrigger" +#define CFG_TDLS_IMPLICIT_TRIGGER_MIN ( 0 ) +#define CFG_TDLS_IMPLICIT_TRIGGER_MAX ( 1 ) +#define CFG_TDLS_IMPLICIT_TRIGGER_DEFAULT ( 0 ) + +#define CFG_TDLS_TX_STATS_PERIOD "gTDLSTxStatsPeriod" +#define CFG_TDLS_TX_STATS_PERIOD_MIN (1000) +#define CFG_TDLS_TX_STATS_PERIOD_MAX ( 4294967295UL ) +#define CFG_TDLS_TX_STATS_PERIOD_DEFAULT (2000) + +#define CFG_TDLS_TX_PACKET_THRESHOLD "gTDLSTxPacketThreshold" +#define CFG_TDLS_TX_PACKET_THRESHOLD_MIN ( 0 ) +#define CFG_TDLS_TX_PACKET_THRESHOLD_MAX ( 4294967295UL ) +#define CFG_TDLS_TX_PACKET_THRESHOLD_DEFAULT (40) + +#define CFG_TDLS_DISCOVERY_PERIOD "gTDLSDiscoveryPeriod" +#define CFG_TDLS_DISCOVERY_PERIOD_MIN ( 5000 ) +#define CFG_TDLS_DISCOVERY_PERIOD_MAX ( 4294967295UL ) +#define CFG_TDLS_DISCOVERY_PERIOD_DEFAULT ( 20000 ) + +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT "gTDLSMaxDiscoveryAttempt" +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ( 1 ) +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX ( 100 ) +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT_DEFAULT (5) + +#define CFG_TDLS_IDLE_TIMEOUT "gTDLSIdleTimeout" +#define CFG_TDLS_IDLE_TIMEOUT_MIN ( 2000 ) +#define CFG_TDLS_IDLE_TIMEOUT_MAX ( 40000 ) +#define CFG_TDLS_IDLE_TIMEOUT_DEFAULT ( 5000 ) + +#define CFG_TDLS_IDLE_PACKET_THRESHOLD "gTDLSIdlePacketThreshold" +#define CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ( 0 ) +#define CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX ( 40000 ) +#define CFG_TDLS_IDLE_PACKET_THRESHOLD_DEFAULT ( 5 ) + +#define CFG_TDLS_RSSI_HYSTERESIS "gTDLSRssiHysteresis" +#define CFG_TDLS_RSSI_HYSTERESIS_MIN ( 0 ) +#define CFG_TDLS_RSSI_HYSTERESIS_MAX ( 100 ) +#define CFG_TDLS_RSSI_HYSTERESIS_DEFAULT ( 100 ) + +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD "gTDLSRSSITriggerThreshold" +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ( -120 ) +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX ( 0 ) +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD_DEFAULT ( -75 ) + +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD "gTDLSRSSITeardownThreshold" +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ( -120 ) +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX ( 0 ) +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_DEFAULT ( -75 ) + +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_NAME "gTDLSUapsdMask" // ACs to setup U-APSD for TDLS Sta +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_MIN (0) +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_MAX (15) +#define CFG_TDLS_QOS_WMM_UAPSD_MASK_DEFAULT (0) + +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE "gEnableTDLSBufferSta" +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MIN (0) +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MAX (1) +#define CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_DEFAULT (1) + +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME "gTDLSPuapsdInactivityTime" +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN (0) +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX (10) +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEFAULT (0) + +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD "gTDLSPuapsdRxFrameThreshold" +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MIN (10) +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX (20) +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_DEFAULT (10) + +#define CFG_TDLS_EXTERNAL_CONTROL "gTDLSExternalControl" +#define CFG_TDLS_EXTERNAL_CONTROL_MIN (0) +#define CFG_TDLS_EXTERNAL_CONTROL_MAX (1) +#define CFG_TDLS_EXTERNAL_CONTROL_DEFAULT (1) + +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE "gEnableTDLSOffChannel" +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MIN (0) +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MAX (1) +#define CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_DEFAULT (1) + +#define CFG_TDLS_WMM_MODE_ENABLE "gEnableTDLSWmmMode" +#define CFG_TDLS_WMM_MODE_ENABLE_MIN (0) +#define CFG_TDLS_WMM_MODE_ENABLE_MAX (1) +#define CFG_TDLS_WMM_MODE_ENABLE_DEFAULT (1) + +#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE "gEnableTDLSScanCoexistence" +#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MIN (0) +#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MAX (1) +#define CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_DEFAULT (0) + +/* Enable/Disable Consecutive Beacon miss */ +#define CFG_ENABLE_CONSECUTIVE_BMISS_NAME "gEnableConcBmiss" +#define CFG_ENABLE_CONSECUTIVE_BMISS_MIN ( 2 ) +#define CFG_ENABLE_CONSECUTIVE_BMISS_MAX ( 10 ) +#define CFG_ENABLE_CONSECUTIVE_BMISS_DEFAULT ( 5 ) + +/* Enable/Disable units of beacon wait time */ +#define CFG_ENABLE_UNITS_BEACON_WAIT_NAME "gEnableUnitBwait" +#define CFG_ENABLE_UNITS_BEACON_WAIT_MIN ( 2 ) +#define CFG_ENABLE_UNITS_BEACON_WAIT_MAX ( 10 ) +#define CFG_ENABLE_UNITS_BEACON_WAIT_DEFAULT ( 2 ) + +/* if gEnableTDLSScan + * 0: Same as gEnableTDLSScanCoexistence ; driver will do disconnect if + * Peer is not buffer STA capable. + * 1: Dut will scan in all cases. + * 2: If peer is not buffer STA capable, use CTS2self to do scan. +*/ +#define CFG_TDLS_SCAN_ENABLE "gEnableTDLSScan" +#define CFG_TDLS_SCAN_ENABLE_MIN (0) +#define CFG_TDLS_SCAN_ENABLE_MAX (2) +#define CFG_TDLS_SCAN_ENABLE_DEFAULT (0) + +#define CFG_TDLS_ENABLE_DEFER_TIMER "gTDLSEnableDeferTime" +#define CFG_TDLS_ENABLE_DEFER_TIMER_MIN (2000) +#define CFG_TDLS_ENABLE_DEFER_TIMER_MAX (6000) +#define CFG_TDLS_ENABLE_DEFER_TIMER_DEFAULT (5000) + +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define CFG_LINK_LAYER_STATS_ENABLE "gEnableLLStats" +#define CFG_LINK_LAYER_STATS_ENABLE_MIN (0) +#define CFG_LINK_LAYER_STATS_ENABLE_MAX (1) +#define CFG_LINK_LAYER_STATS_ENABLE_DEFAULT (0) +#endif + +#ifdef WLAN_FEATURE_EXTSCAN +#define CFG_EXTSCAN_ENABLE "gEnableEXTScan" +#define CFG_EXTSCAN_ENABLE_MIN (0) +#define CFG_EXTSCAN_ENABLE_MAX (1) +#define CFG_EXTSCAN_ENABLE_DEFAULT (1) +#endif + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE "gEnableActiveModeOffload" +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE_MIN ( 0 ) +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE_MAX ( 1 ) +#define CFG_ACTIVEMODE_OFFLOAD_ENABLE_DEFAULT ( 1 ) +#endif + +/* Enable/Disable LPWR Image(cMEM uBSP) Transition */ +#define CFG_ENABLE_LPWR_IMG_TRANSITION_NAME "gEnableLpwrImgTransition" +#define CFG_ENABLE_LPWR_IMG_TRANSITION_MIN ( 0 ) +#define CFG_ENABLE_LPWR_IMG_TRANSITION_MAX ( 1 ) +#define CFG_ENABLE_LPWR_IMG_TRANSITION_DEFAULT ( 1 ) + + +/* + * Scan Aging timeout value in seconds + */ +#define CFG_SCAN_AGING_PARAM_NAME "gScanAgingTime" +#define CFG_SCAN_AGING_PARAM_MIN ( 0 ) +#define CFG_SCAN_AGING_PARAM_MAX ( 200 ) +#define CFG_SCAN_AGING_PARAM_DEFAULT ( 60 ) + +/* Config Param to enable the txLdpc capability + * 0 - disable + * 1 - HT LDPC enable + * 2 - VHT LDPC enable + * 3 - HT & VHT LDPC enable */ +#define CFG_TX_LDPC_ENABLE_FEATURE "gTxLdpcEnable" +#define CFG_TX_LDPC_ENABLE_FEATURE_MIN ( 0 ) +#define CFG_TX_LDPC_ENABLE_FEATURE_MAX ( 3 ) +#define CFG_TX_LDPC_ENABLE_FEATURE_DEFAULT ( 0 ) + +/* + * Enable / Disable MCC Adaptive Scheduler feature + * Default: Enable + */ +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_NAME "gEnableMCCAdaptiveScheduler" +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MIN ( 0 ) +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MAX ( 1 ) +#define CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_DEFAULT ( 1 ) + +#ifdef WLAN_FEATURE_11AC +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE "gTxBFEnable" +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MIN ( WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN ) +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX ( WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX ) +#define CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_DEFAULT ( WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF ) + +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED "gTxBFCsnValue" +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MIN ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN ) +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MAX ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX - 1 ) +#define CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_DEFAULT ( WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX - 1 ) + +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE "gEnableMuBformee" +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MIN ( 0 ) +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MAX ( 1 ) +#define CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_DEFAULT ( 1 ) + +#define CFG_VHT_AMPDU_LEN_EXP_NAME "gVhtMaxAmpduLenExp" +#define CFG_VHT_AMPDU_LEN_EXP_MIN ( 0 ) +#define CFG_VHT_AMPDU_LEN_EXP_MAX ( 7 ) +#define CFG_VHT_AMPDU_LEN_EXP_DEFAULT ( 7 ) + +#endif + + +/* + * SAP ALLOW All Channels + */ +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_NAME "gSapAllowAllChannel" +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MIN ( 0 ) +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MAX ( 1 ) +#define CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_DEFAULT ( 0 ) + + +#ifdef WLAN_FEATURE_11AC +#define CFG_DISABLE_LDPC_WITH_TXBF_AP "gDisableLDPCWithTxbfAP" +#define CFG_DISABLE_LDPC_WITH_TXBF_AP_MIN ( 0 ) +#define CFG_DISABLE_LDPC_WITH_TXBF_AP_MAX ( 1 ) +#define CFG_DISABLE_LDPC_WITH_TXBF_AP_DEFAULT ( 0 ) +#endif + +#define CFG_LIST_OF_NON_DFS_COUNTRY_CODE "gListOfNonDfsCountryCode" +#define CFG_LIST_OF_NON_DFS_COUNTRY_CODE_DEFAULT "JO,MA" + +/* + * IBSS Operating Channels for 2.4G and 5GHz channels + */ +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_NAME "gAdHocChannel5G" +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_MIN ( 36 ) +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_MAX ( 165 ) +#define CFG_IBSS_ADHOC_CHANNEL_5GHZ_DEFAULT ( 44 ) + +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_NAME "gAdHocChannel24G" +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_MIN ( 1 ) +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_MAX ( 14 ) +#define CFG_IBSS_ADHOC_CHANNEL_24GHZ_DEFAULT ( 6 ) + +#define CFG_LIST_OF_NON_11AC_COUNTRY_CODE "gListOfNon11acCountryCode" +#define CFG_LIST_OF_NON_11AC_COUNTRY_CODE_DEFAULT "RU,UA,ZA" + +/* Parameter to control VHT support in 2.4 GHz band */ +#define CFG_ENABLE_VHT_FOR_24GHZ_NAME "gEnableVhtFor24GHzBand" +#define CFG_ENABLE_VHT_FOR_24GHZ_MIN (0) +#define CFG_ENABLE_VHT_FOR_24GHZ_MAX (1) +#define CFG_ENABLE_VHT_FOR_24GHZ_DEFAULT (0) + + +#define CFG_MAX_MEDIUM_TIME "gMaxMediumTime" +#define CFG_MAX_MEDIUM_TIME_STAMIN WNI_CFG_MAX_MEDIUM_TIME_STAMIN +#define CFG_MAX_MEDIUM_TIME_STAMAX WNI_CFG_MAX_MEDIUM_TIME_STAMAX +#define CFG_MAX_MEDIUM_TIME_STADEFAULT WNI_CFG_MAX_MEDIUM_TIME_STADEF + +/* + * SAP/P2P-GO mode traffic monitor + */ +#define CFG_ENABLE_TRAFFIC_MONITOR "gEnableTrafficMonitor" +#define CFG_ENABLE_TRAFFIC_MONITOR_MIN ( 0 ) +#define CFG_ENABLE_TRAFFIC_MONITOR_MAX ( 1 ) +#define CFG_ENABLE_TRAFFIC_MONITOR_DEFAULT ( 0 ) + +#define CFG_TRAFFIC_IDLE_TIMEOUT "gTrafficIdleTimeout" +#define CFG_TRAFFIC_IDLE_TIMEOUT_MIN ( 3000 ) +#define CFG_TRAFFIC_IDLE_TIMEOUT_MAX ( 10000 ) +#define CFG_TRAFFIC_IDLE_TIMEOUT_DEFAULT ( 5000 ) + +/* + * SCAN Offload + */ +#define CFG_SCAN_OFFLOAD_NAME "gEnableDirectedScanOffload" +#define CFG_SCAN_OFFLOAD_DISABLE ( 0 ) +#define CFG_SCAN_OFFLOAD_ENABLE ( 1 ) +#define CFG_SCAN_OFFLOAD_DEFAULT ( CFG_SCAN_OFFLOAD_DISABLE ) + +/* + * Enable legacy fast roaming (LFR) on STA link during concurrent sessions + */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY "gEnableFastRoamInConcurrency" +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MIN ( 0 ) +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MAX ( 1 ) +#define CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_DEFAULT ( 1 ) +#endif + +/* + * FlexConnectPowerFactor parameter + * Default: Disable (0) + */ +#define CFG_FLEX_CONNECT_POWER_FACTOR_NAME "gFlexConnectPowerFactor" +#define CFG_FLEX_CONNECT_POWER_FACTOR_MIN ( 0 ) +#define CFG_FLEX_CONNECT_POWER_FACTOR_MAX ( 9 ) +#define CFG_FLEX_CONNECT_POWER_FACTOR_DEFAULT ( 0 ) + +/* + * Enable heart beat monitoring offload to FW + */ +#define CFG_ENABLE_HEART_BEAT_OFFLOAD "gEnableIbssHeartBeatOffload" +#define CFG_ENABLE_HEART_BEAT_OFFLOAD_MIN ( 0 ) +#define CFG_ENABLE_HEART_BEAT_OFFLOAD_MAX ( 1 ) +#define CFG_ENABLE_HEART_BEAT_OFFLOAD_DEFAULT ( 1 ) + +#define CFG_ANTENNA_DIVERSITY_PARAM_NAME "gAntennaDiversity" +#define CFG_ANTENNA_DIVERSITY_PARAM_MIN ( 0 ) +#define CFG_ANTENNA_DIVERSITY_PARAM_MAX ( 3 ) +#define CFG_ANTENNA_DIVERSITY_PARAM_DEFAULT ( 0 ) + +#define CFG_ENABLE_SNR_MONITORING_NAME "gEnableSNRMonitoring" +#define CFG_ENABLE_SNR_MONITORING_MIN ( 0 ) +#define CFG_ENABLE_SNR_MONITORING_MAX ( 1 ) +#define CFG_ENABLE_SNR_MONITORING_DEFAULT ( 0 ) +//Macro to enable/disable dynamic timer +#define CFG_DYNAMIC_SPLIT_SCAN_NAME "gEnableDynSplitScan" +#define CFG_DYNAMIC_SPLIT_SCAN_MIN ( 0 ) +#define CFG_DYNAMIC_SPLIT_SCAN_MAX ( 1 ) +#define CFG_DYNAMIC_SPLIT_SCAN_DEFAULT ( 1 ) + +//Macro to monitor the packet count +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_NAME "gSplitScanTxRxThreshold" +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MIN ( 10 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MAX ( 100 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_DEFAULT ( 50 ) + +//Macro to handle the monitor timer value in milliseconds +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_NAME "gSplitScanTxRxTimer" +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MIN ( 1000 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MAX ( 10000 ) +#define CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_DEFAULT ( 5000 ) + +#ifdef FEATURE_WLAN_SCAN_PNO +#define CFG_PNO_SCAN_SUPPORT "gPNOScanSupport" +#define CFG_PNO_SCAN_SUPPORT_ENABLE ( 1 ) +#define CFG_PNO_SCAN_SUPPORT_DISABLE ( 0 ) +#define CFG_PNO_SCAN_SUPPORT_DEFAULT ( 1 ) + +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE "gPNOScanTimerRepeatValue" +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_DEFAULT ( 6 ) +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN ( 0 ) +#define CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX ( 0xffffffff ) +#endif + +/* Not supporting this feature in pronto */ +#define CFG_AMSDU_SUPPORT_IN_AMPDU_NAME "gAmsduSupportInAMPDU" +#define CFG_AMSDU_SUPPORT_IN_AMPDU_MIN (0) +#define CFG_AMSDU_SUPPORT_IN_AMPDU_MAX (0) +#define CFG_AMSDU_SUPPORT_IN_AMPDU_DEFAULT (0) //disabled + +/* Prefer connecting to 5G AP even if its RSSI is lower by + gSelect5GHzMargin dBm than 2.4G AP. +This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN "gSelect5GHzMargin" +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN_MIN (0) +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN_MAX (60) +#define CFG_STRICT_5GHZ_PREF_BY_MARGIN_DEFAULT (0) //set 0 to disable + +#define CFG_COALESING_IN_IBSS_NAME "gCoalesingInIBSS" +#define CFG_COALESING_IN_IBSS_MIN (0) +#define CFG_COALESING_IN_IBSS_MAX (1) +#define CFG_COALESING_IN_IBSS_DEFAULT (0) //disabled + +#define CFG_DISABLE_ATH_NAME "gAthDisable" +#define CFG_DISABLE_ATH_MIN (0) +#define CFG_DISABLE_ATH_MAX (1) +#define CFG_DISABLE_ATH_DEFAULT (0) + +//Enable Memory Debug +#ifdef MEMORY_DEBUG +#define CFG_ENABLE_MEMORY_DEBUG_NAME "gEnableMemoryDebug" +#define CFG_ENABLE_MEMORY_DEBUG_MIN (0) +#define CFG_ENABLE_MEMORY_DEBUG_MAX (1) +#define CFG_ENABLE_MEMORY_DEBUG_DEFAULT (0) +#endif + +#define CFG_OVERRIDE_COUNTRY_CODE "gStaCountryCode" +#define CFG_OVERRIDE_COUNTRY_CODE_DEFAULT "000" + +/*Once the period expires the RSSI will be compared with Threshold + * and if needed trigger events will be raised + */ +#define CFG_ASD_PROBE_INTERVAL_NAME "gAsdProbeInterval" +#define CFG_ASD_PROBE_INTERVAL_DEFAULT (50) +#define CFG_ASD_PROBE_INTERVAL_MIN (1) +#define CFG_ASD_PROBE_INTERVAL_MAX (500) + +/* RSSI Threshold used to trigger probing activity/selection process*/ +#define CFG_ASD_TRIGGER_THRESHOLD_NAME "gAsdTriggerThreshold" +#define CFG_ASD_TRIGGER_THRESHOLD_DEFAULT (-60) +#define CFG_ASD_TRIGGER_THRESHOLD_MIN (-100) +#define CFG_ASD_TRIGGER_THRESHOLD_MAX (-10) + +/*RSSI Hysteresis Threshold for RSSI-RTT*/ +#define CFG_ASD_RTT_RSSI_HYST_THRESHOLD_NAME "gAsdRTTRssiHystThreshold" +#define CFG_ASD_RTT_RSSI_HYST_THRESHOLD_DEFAULT (3) +#define CFG_ASD_RTT_RSSI_HYST_THRESHOLD_MIN (0) +#define CFG_ASD_RTT_RSSI_HYST_THRESHOLD_MAX (5) + +//Enable debug for remain on channel issues +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_NAME "gDebugP2pRemainOnChannel" +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_DEFAULT ( 0 ) +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MIN ( 0 ) +#define CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MAX ( 1 ) + +#define CFG_CTS2S_DURING_BTC_SCO_NAME "btcCTS2SduringSCO" +#define CFG_CTS2S_DURING_BTC_SCO_DEFAULT WNI_CFG_BTC_CTS2S_DURING_SCO_STADEF +#define CFG_CTS2S_DURING_BTC_SCO_MIN WNI_CFG_BTC_CTS2S_DURING_SCO_STAMIN +#define CFG_CTS2S_DURING_BTC_SCO_MAX WNI_CFG_BTC_CTS2S_DURING_SCO_STAMAX + +#define CFG_BTC_FAST_WLAN_CONN_PREF "gBtcFastWlanConnPref" +#define CFG_BTC_FAST_WLAN_CONN_PREF_DEFAULT ( 1 ) +#define CFG_BTC_FAST_WLAN_CONN_PREF_MIN ( 0 ) +#define CFG_BTC_FAST_WLAN_CONN_PREF_MAX ( 5 ) + +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN "gBtcStaticOppWlanIdleWlanLen" +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_DEFAULT ( 30000 ) +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MIN ( 0 ) +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MAX ( 250000 ) + + +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN "gBtcStaticOppWlanIdleBtLen" +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEFAULT ( 120000 ) +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MIN ( 0 ) +#define CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX ( 250000 ) + + +#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL "gBtcDisableWlanLinkCritical" +#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEFAULT ( 0 ) +#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN ( 0 ) +#define CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX ( 1 ) + +/* + * Connection related log Enable/Disable. + * 0x1 - Enable mgmt pkt logs (no probe req/rsp). + * 0x2 - Enable EAPOL pkt logs. + * 0x4 - Enable DHCP pkt logs. + * 0x0 - Disable all the above connection related logs. + */ +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE "gEnableDebugLog" +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN (0) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0) + +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_NAME "gEnableStrictRegulatoryForFCC" +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MIN ( 0 ) +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MAX ( 1 ) +#define CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_DEFAULT ( 0 ) + +#define CFG_ADVERTISE_CONCURRENT_OPERATION_NAME "gAdvertiseConcurrentOperation" +#define CFG_ADVERTISE_CONCURRENT_OPERATION_DEFAULT ( 1 ) +#define CFG_ADVERTISE_CONCURRENT_OPERATION_MIN ( 0 ) +#define CFG_ADVERTISE_CONCURRENT_OPERATION_MAX ( 1 ) + +#define CFG_RA_FILTER_ENABLE_NAME "gRAFilterEnable" +#define CFG_RA_FILTER_ENABLE_DEFAULT (0) +#define CFG_RA_FILTER_ENABLE_MIN (0) +#define CFG_RA_FILTER_ENABLE_MAX (1) + +#define CFG_RA_RATE_LIMIT_INTERVAL_NAME "gRARateLimitInterval" +#define CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT (60) +#define CFG_RA_RATE_LIMIT_INTERVAL_MIN (0) +#define CFG_RA_RATE_LIMIT_INTERVAL_MAX (3600) + +#define CFG_ROAMING_DFS_CHANNEL_NAME "gAllowDFSChannelRoam" +#define CFG_ROAMING_DFS_CHANNEL_MIN (0) +#define CFG_ROAMING_DFS_CHANNEL_MAX (1) +#define CFG_ROAMING_DFS_CHANNEL_DEFAULT (1) + +#define CFG_TCP_DELACK_COMPUTE_INTERVAL "gTcpDelAckComputeInterval" +#define CFG_TCP_DELACK_COMPUTE_INTERVAL_DEFAULT ( 2000 ) +#define CFG_TCP_DELACK_COMPUTE_INTERVAL_MIN ( 1000 ) +#define CFG_TCP_DELACK_COMPUTE_INTERVAL_MAX ( 10000 ) + +#define CFG_TCP_DELACK_THRESHOLD_HIGH "gTcpDelAckThresholdHigh" +#define CFG_TCP_DELACK_THRESHOLD_HIGH_DEFAULT ( 17000 ) +#define CFG_TCP_DELACK_THRESHOLD_HIGH_MIN ( 1000 ) +#define CFG_TCP_DELACK_THRESHOLD_HIGH_MAX ( 25000 ) + +#define CFG_TCP_DELACK_THRESHOLD_LOW "gTcpDelAckThresholdLow" +#define CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT ( 12000 ) +#define CFG_TCP_DELACK_THRESHOLD_LOW_MIN ( 0 ) +#define CFG_TCP_DELACK_THRESHOLD_LOW_MAX ( 25000 ) + + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +//Enable WLAN Logging to app space +#define CFG_WLAN_LOGGING_SUPPORT_NAME "wlanLoggingEnable" +#define CFG_WLAN_LOGGING_SUPPORT_ENABLE ( 1 ) +#define CFG_WLAN_LOGGING_SUPPORT_DISABLE ( 0 ) +#define CFG_WLAN_LOGGING_SUPPORT_DEFAULT ( 1 ) + +//Enable FATAL and ERROR logs for kmsg console +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_NAME "wlanLoggingFEToConsole" +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_ENABLE ( 1 ) +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DISABLE ( 0 ) +#define CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DEFAULT ( 1 ) + +//Number of buffers to be used for WLAN logging +#define CFG_WLAN_LOGGING_NUM_BUF_NAME "wlanLoggingNumBuf" +#define CFG_WLAN_LOGGING_NUM_BUF_MIN ( 4 ) +#define CFG_WLAN_LOGGING_NUM_BUF_MAX ( 64 ) +#define CFG_WLAN_LOGGING_NUM_BUF_DEFAULT ( 32 ) + +//Number of buffers to be used for WLAN logging +#define CFG_WLAN_PKT_STATS_NUM_BUF_NAME "wlanPerPktStatsNumBuf" +#define CFG_WLAN_PKT_STATS_NUM_BUF_MIN ( 4 ) +#define CFG_WLAN_PKT_STATS_NUM_BUF_MAX ( 64 ) +#define CFG_WLAN_PKT_STATS_NUM_BUF_DEFAULT ( 16 ) + +#endif //WLAN_LOGGING_SOCK_SVC_ENABLE + +//Enable PerPKT stats Logging +#define CFG_WLAN_PKT_STATS_LOGGING_NAME "wlanPerPktStatsLogEnable" +#define CFG_WLAN_PKT_STATS_LOGGING_ENABLE ( 1 ) +#define CFG_WLAN_PKT_STATS_LOGGING_DISABLE ( 0 ) +#define CFG_WLAN_PKT_STATS_LOGGING_DEFAULT ( 1 ) + +#define CFG_IGNORE_PEER_ERP_INFO_NAME "gIgnorePeerErpInfo" +#define CFG_IGNORE_PEER_ERP_INFO_MIN ( 0 ) +#define CFG_IGNORE_PEER_ERP_INFO_MAX ( 1 ) +#define CFG_IGNORE_PEER_ERP_INFO_DEFAULT ( 0 ) + +#define CFG_IGNORE_PEER_HT_MODE_NAME "gIgnorePeerHTopMode" +#define CFG_IGNORE_PEER_HT_MODE_MIN ( 0 ) +#define CFG_IGNORE_PEER_HT_MODE_MAX ( 1 ) +#define CFG_IGNORE_PEER_HT_MODE_DEFAULT ( 0 ) + +#define CFG_INITIAL_DWELL_TIME_NAME "gInitialDwellTime" +#define CFG_INITIAL_DWELL_TIME_DEFAULT (0) +#define CFG_INITIAL_DWELL_TIME_MIN (0) +#define CFG_INITIAL_DWELL_TIME_MAX (100) + +#define CFG_INITIAL_SCAN_SKIP_DFS_CH_NAME "gInitialScanSkipDFSCh" +#define CFG_INITIAL_SCAN_SKIP_DFS_CH_DEFAULT (1) +#define CFG_INITIAL_SCAN_SKIP_DFS_CH_MIN (0) +#define CFG_INITIAL_SCAN_SKIP_DFS_CH_MAX (1) + +#define CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_NAME "btcFatalHidnSniffBlkGuidance" +#define CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_MIN ( 0 ) +#define CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_MAX ( 2 ) +#define CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_DEFAULT ( 2 ) + +#define CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_NAME "btcCriticalHidnSniffBlkGuidance" +#define CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_MIN ( 0 ) +#define CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_MAX ( 1 ) +#define CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_DEFAULT ( 1 ) + +#define CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_NAME "btcA2dpTxQueueThold" +#define CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_MIN ( 0 ) +#define CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_MAX ( 1 ) +#define CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_DEFAULT ( 0 ) + +#define CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_NAME "btcOppTxQueueThold" +#define CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_MIN ( 0 ) +#define CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_MAX ( 3 ) +#define CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_DEFAULT ( 1 ) + +#ifdef WLAN_FEATURE_11W +#define CFG_PMF_SA_QUERY_MAX_RETRIES_NAME "pmfSaQueryMaxRetries" +#define CFG_PMF_SA_QUERY_MAX_RETRIES_DEFAULT ( 5 ) +#define CFG_PMF_SA_QUERY_MAX_RETRIES_MIN ( 0 ) +#define CFG_PMF_SA_QUERY_MAX_RETRIES_MAX ( 20 ) + +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_NAME "pmfSaQueryRetryInterval" +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_DEFAULT ( 200 ) +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_MIN ( 0 ) +#define CFG_PMF_SA_QUERY_RETRY_INTERVAL_MAX ( 2000 ) +#endif + +#define CFG_DEFER_IMPS_FOR_TIME_NAME "gDeferIMPStime" +#define CFG_DEFER_IMPS_FOR_TIME_MIN (0) +#define CFG_DEFER_IMPS_FOR_TIME_MAX (500) +#define CFG_DEFER_IMPS_FOR_TIME_DEFAULT (200) + +/* If last disconnection was due to HB failure and we reconnect + * to same AP next time, send Deauth before starting connection + */ +#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION "gSendDeauthBeforeCon" +#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MIN (0) +#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MAX (1) +#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_DEFAULT (0) + +/* gEnableMacAddrSpoof = 0 => disable mac spoofing + = 1 => enable mac spoofing in both HOST and FW + = 2 => enable mac spoofing in FW and + disable mac spoofing in HOST + */ +#define CFG_ENABLE_MAC_ADDR_SPOOFING "gEnableMacAddrSpoof" +#define CFG_ENABLE_MAC_ADDR_SPOOFING_MIN (0) +#define CFG_ENABLE_MAC_ADDR_SPOOFING_MAX (2) +#define CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT (0) + +/* Disable Mac Spoof for p2p Scan */ +#define CFG_DISABLE_P2P_MAC_ADDR_SPOOFING "gDisableP2PMacAddrSpoof" +#define CFG_DISABLE_P2P_MAC_ADDR_SPOOFING_MIN (0) +#define CFG_DISABLE_P2P_MAC_ADDR_SPOOFING_MAX (1) +#define CFG_DISABLE_P2P_MAC_ADDR_SPOOFING_DEFAULT (1) + +#define CFG_ENABLE_FATAL_EVENT_TRIGGER "gEnableFatalEvent" +#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN (0) +#define CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX (1) +#define CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT (1) + + +#define CFG_ENABLE_MGMT_LOGGING "gEnableMgmtLogging" +#define CFG_ENABLE_MGMT_LOGGING_MIN (0) +#define CFG_ENABLE_MGMT_LOGGING_MAX (1) +#define CFG_ENABLE_MGMT_LOGGING_DEFAULT (0) + +#define CFG_ENABLE_BMUHW_TRACING "gEnableBMUHWtracing" +#define CFG_ENABLE_BMUHW_TRACING_MIN (0) +#define CFG_ENABLE_BMUHW_TRACING_MAX (1) +#define CFG_ENABLE_BMUHW_TRACING_DEFAULT (1) + +#define CFG_ENABLE_FW_LOGGING "gEnableFWLogging" +#define CFG_ENABLE_FW_LOGGING_MIN (0) +#define CFG_ENABLE_FW_LOGGING_MAX (1) +#define CFG_ENABLE_FW_LOGGING_DEFAULT (1) + +// firmware will wakeup the host to send logs always +#define CFG_ENABLE_FW_CONTINIOUS_LOGGING "gEnableContFWLogging" +#define CFG_ENABLE_FW_CONTINIOUS_LOGGING_MIN (0) +#define CFG_ENABLE_FW_CONTINIOUS_LOGGING_MAX (1) +#define CFG_ENABLE_FW_CONTINIOUS_LOGGING_DEFAULT (0) + +/* when firmware log reaches this threshold and + * if host is awake it will push the logs. + */ +#define CFG_MIN_LOGGING_BUFFER_SIZE "gMinLoggingBufferSize" +#define CFG_MIN_LOGGING_BUFFER_SIZE_MIN (0) +#define CFG_MIN_LOGGING_BUFFER_SIZE_MAX (6) +#define CFG_MIN_LOGGING_BUFFER_SIZE_DEFAULT (1) + +// Max ring size in firmware to log msgs when host is suspended state +#define CFG_MAX_LOGGING_BUFFER_SIZE "gMaxLoggingBufferSize" +#define CFG_MAX_LOGGING_BUFFER_SIZE_MIN (0) +#define CFG_MAX_LOGGING_BUFFER_SIZE_MAX (6) +#define CFG_MAX_LOGGING_BUFFER_SIZE_DEFAULT (6) + +#define CFG_ENABLE_CH_AVOID "gEnableChannelAvoidance" +#define CFG_ENABLE_CH_AVOID_MIN ( 0 ) +#define CFG_ENABLE_CH_AVOID_MAX ( 1 ) +#define CFG_ENABLE_CH_AVOID_DEFAULT ( 1 ) + +#define CFG_MAX_CONCURRENT_CONNECTIONS_NAME "gMaxConcurrentActiveSessions" +#define CFG_MAX_CONCURRENT_CONNECTIONS_DEFAULT ( 2 ) +#define CFG_MAX_CONCURRENT_CONNECTIONS_MIN ( 1 ) +#define CFG_MAX_CONCURRENT_CONNECTIONS_MAX ( 4 ) + +#ifdef WLAN_FEATURE_AP_HT40_24G +#define CFG_ENABLE_HT_2040_COEX "gApHT4024G" +#define CFG_ENABLE_HT_2040_COEX_MIN ( 0 ) +#define CFG_ENABLE_HT_2040_COEX_MAX ( 1 ) +#define CFG_ENABLE_HT_2040_COEX_DEFAULT ( 0 ) +#endif + +//Enable Dynamic WMM PS support +#define CFG_ENABLE_DYNAMIC_WMMPS_NAME "gEnableDynamicWMMPS" +#define CFG_ENABLE_DYNAMIC_WMM_PS_MIN (0) +#define CFG_ENABLE_DYNAMIC_WMM_PS_MAX (1) +#define CFG_ENABLE_DYNAMIC_WMM_PS_DEFAULT (1) + +/* + * If the number of consecutive SPs for which the firmware has sent + * trigger frame (because more data bit was set to 1 at end of SP) + * when dynamic WMM PS support is enabled exceeds this value then + * firmware will come out of power save mode + */ +#define CFG_MAX_UAPSD_CONSEC_SP_NAME "gMaxUapsdConsecSP" +#define CFG_MAX_UAPSD_CONSEC_SP_DEFAULT ( 10 ) +#define CFG_MAX_UAPSD_CONSEC_SP_MIN ( 0 ) +#define CFG_MAX_UAPSD_CONSEC_SP_MAX ( 500 ) + +/* + * If the number of frames received in the "gUapsdConsecRxCntMeasWindow" + * exceeds this value then firmware will come out of power save mode. + * Comes into effect only when dynamic WMM PS is enabled. + */ +#define CFG_MAX_UAPSD_CONSEC_RX_CNT_NAME "gMaxUapsdConsecRxCnt" +#define CFG_MAX_UAPSD_CONSEC_RX_CNT_DEFAULT ( 50 ) +#define CFG_MAX_UAPSD_CONSEC_RX_CNT_MIN ( 0 ) +#define CFG_MAX_UAPSD_CONSEC_RX_CNT_MAX ( 5000 ) + +/* + * If the number of frames transmitted in the "gUapsdConsecTxCntMeasWindow" + * exceeds this value then firmware will come out of power save mode. + * Comes into effect only when dynamic WMM PS is enabled. + */ +#define CFG_MAX_UAPSD_CONSEC_TX_CNT_NAME "gMaxUapsdConsecTxCnt" +#define CFG_MAX_UAPSD_CONSEC_TX_CNT_DEFAULT ( 50 ) +#define CFG_MAX_UAPSD_CONSEC_TX_CNT_MIN ( 0 ) +#define CFG_MAX_UAPSD_CONSEC_TX_CNT_MAX ( 5000 ) + +// Read the description in "gMaxUapsdConsecRxCnt", the interval is in msec +#define CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_NAME "gUapsdConsecRxCntMeasWindow" +#define CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_DEFAULT ( 500 ) +#define CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_MIN ( 50 ) +#define CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_MAX ( 50000 ) + +// Read the description in "gMaxUapsdConsecTxCnt", the interval is in msec +#define CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_NAME "gUapsdConsecTxCntMeasWindow" +#define CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_DEFAULT ( 500 ) +#define CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_MIN ( 50 ) +#define CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_MAX ( 50000 ) + +/* + * number of PS poll frames that can be sent by the firmware to retrieve + * Data before the firmware comes out of power save mode for an AC + * which is neither Delivery or Trigger enabled when dynamic WMM PS + * is configured. + * Comes into effect only when dynamic WMM PS is enabled. +*/ +#define CFG_UAPSD_PSPOLL_NAME "gMaxPsPollInWmmUapsdMode" +#define CFG_UAPSD_PSPOLL_MIN (0) +#define CFG_UAPSD_PSPOLL_MAX (255) +#define CFG_UAPSD_PSPOLL_DEFAULT (0) + +/* + * If the number of itervals for which the firmware detects no activity + * on the WMM PS enabled ACs exceeds this value then the firmware will + * go to power save mode. The length of the interval is dynamically + * calculated by the firmware depending on the configured service + * intervals. + * Comes into effect only when dynamic WMM PS is enabled. + */ +#define CFG_MAX_UAPSD_INACT_INTVL_NAME "gMaxUapsdInactivityIntervals" +#define CFG_MAX_UAPSD_INACT_INTVL_MIN (1) +#define CFG_MAX_UAPSD_INACT_INTVL_MAX (255) +#define CFG_MAX_UAPSD_INACT_INTVL_DEFAULT (10) + +#define CFG_BURST_MODE_BE_TXOP_VALUE "gBurstModeTXOPValue" +#define CFG_BURST_MODE_BE_TXOP_VALUE_MIN ( 0 ) +#define CFG_BURST_MODE_BE_TXOP_VALUE_MAX ( 12288 ) +#define CFG_BURST_MODE_BE_TXOP_VALUE_DEFAULT ( 0 ) + +#define CFG_P2P_LISTEN_DEFER_INTERVAL_NAME "gP2PListenDeferInterval" +#define CFG_P2P_LISTEN_DEFER_INTERVAL_MIN ( 100 ) +#define CFG_P2P_LISTEN_DEFER_INTERVAL_MAX ( 200 ) +#define CFG_P2P_LISTEN_DEFER_INTERVAL_DEFAULT ( 100 ) + +#define CFG_BTC_ENABLE_IND_TIMER_VALUE "gBtcEnableIndTimerVal" +#define CFG_BTC_ENABLE_IND_TIMER_VALUE_MIN ( 5 ) +#define CFG_BTC_ENABLE_IND_TIMER_VALUE_MAX ( 60 ) +#define CFG_BTC_ENABLE_IND_TIMER_VALUE_DEFAULT ( 60 ) + +#define CFG_DXE_REPLENISH_RX_TIMER_VALUE "gDXEReplenishRXTimerVal" +#define CFG_DXE_REPLENISH_RX_TIMER_VALUE_MIN ( 0 ) +#define CFG_DXE_REPLENISH_RX_TIMER_VALUE_MAX ( 20000 ) +#define CFG_DXE_REPLENISH_RX_TIMER_VALUE_DEFAULT ( 6000 ) + +#define CFG_DXE_SSR_ENABLE "gDxeSSREnable" +#define CFG_DXE_SSR_ENABLE_DEFAULT ( 1 ) +#define CFG_DXE_SSR_ENABLE_MIN ( 0 ) +#define CFG_DXE_SSR_ENABLE_MAX ( 1 ) + +#define CFG_TOGGLE_ARP_BDRATES_NAME "gToggleArpBDRates" +#define CFG_TOGGLE_ARP_BDRATES_MIN 0 +#define CFG_TOGGLE_ARP_BDRATES_MAX 2 +#define CFG_TOGGLE_ARP_BDRATES_DEFAULT 0 + +#define CFG_DISABLE_BAR_WAKEUP_HOST_NAME "gDisableBarWakeUp" +#define CFG_DISABLE_BAR_WAKEUP_HOST_MIN 0 +#define CFG_DISABLE_BAR_WAKEUP_HOST_MAX 1 +#define CFG_DISABLE_BAR_WAKEUP_HOST_DEFAULT 0 + +#ifdef DHCP_SERVER_OFFLOAD +/* + * Enable/Disable DHCP Server Offload + * Default: Disable + */ +#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_NAME "gDHCPServerOffloadEnable" +#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MIN ( 0 ) +#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MAX ( 1 ) +#define CFG_DHCP_SERVER_OFFLOAD_SUPPORT_DEFAULT ( 1 ) + +/* Max number of DHCP clients to be supported */ +#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_NAME "gDHCPMaxNumClients" +#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MIN ( 1 ) +#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MAX ( 4 ) +#define CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_DEFAULT ( 4 ) + +/* Start address of the pool */ +#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_NAME "gDHCPStartLsb" +#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_MIN ( 100 ) +#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_MAX ( 255 ) +#define CFG_DHCP_SERVER_OFFLOAD_START_LSB_DEFAULT ( 100 ) + +/* DHCP Server IP*/ +#define CFG_DHCP_SERVER_IP_NAME "gDHCPServerIP" +#define CFG_DHCP_SERVER_IP_DEFAULT "192.168.43.1" +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/* + * Enable/Disable multicast DNS Offload + * 0x0 - Disable mDNS (Default) + * 0x1 - Enable mDNS + */ +#define CFG_MDNS_OFFLOAD_SUPPORT_NAME "gMDNSOffloadEnable" +#define CFG_MDNS_OFFLOAD_SUPPORT_MIN ( 0 ) +#define CFG_MDNS_OFFLOAD_SUPPORT_MAX ( 1 ) +#define CFG_MDNS_OFFLOAD_SUPPORT_ENABLE ( 1 ) +#define CFG_MDNS_OFFLOAD_SUPPORT_DEFAULT ( 1 ) + +/* Set FQDN string for mDNS */ +#define CFG_MDNS_FQDN_NAME "gMDNSFqdn" +#define CFG_MDNS_FQDN_DEFAULT "_GoProRemote._tcp.local" + +/* Set UFQDN string for mDNS */ +#define CFG_MDNS_UNIQUE_FQDN_NAME "gMDNSUniqueFqdn" +#define CFG_MDNS_UNIQUE_FQDN_DEFAULT "service._GoProRemote._tcp.local" + +/* Set the response Type A to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_A_NAME "gMDNSResponseTypeA" +#define CFG_MDNS_RESPONSE_TYPE_A_DEFAULT "goprobp-D89685121212.local" + +#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_NAME "gMDNSResponseTypeAIpv4Addr" +#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_MIN ( 1 ) +#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_MAX ( 0xffffffff ) +#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_DEFAULT ( 0xc0a80102 ) + +/* Set the response Type TXT to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_TXT_NAME "gMDNSResponseTypeTXT" +#define CFG_MDNS_RESPONSE_TYPE_TXT_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local" + +#define CFG_MDNS_RESPONSE_TYPE_TXT_CNT_NAME "gMDNSResponseTypeTXTContent" +#define CFG_MDNS_RESPONSE_TYPE_TXT_CNT_DEFAULT "Device=HERO 3+-BAWA Model=BAWA Version=HD3.11.02.00 Wifi Version=4.0.36.0 Protocol Version=2" + +/* Set the response Type PTR to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_PTR_NAME "gMDNSResponseTypePTR" +#define CFG_MDNS_RESPONSE_TYPE_PTR_DEFAULT "_GoProRemote._tcp.local" + +#define CFG_MDNS_RESPONSE_TYPE_PTR_DN_NAME "gMDNSResponseTypePTRDomainName" +#define CFG_MDNS_RESPONSE_TYPE_PTR_DN_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local" + +/* Set the response Type SRV to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_SRV_NAME "gMDNSResponseTypeSRV" +#define CFG_MDNS_RESPONSE_TYPE_SRV_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local" + +/* Set the response Type SRV Priority to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_NAME "gMDNSResponseTypeSRVPriority" +#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MIN ( 0 ) +#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MAX ( 65535 ) +#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_DEFAULT ( 0 ) + +/* Set the response Type SRV Weight to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_NAME "gMDNSResponseTypeSRVWeight" +#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MIN ( 0 ) +#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MAX ( 65525 ) +#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_DEFAULT ( 0 ) + +/* Set the response Type SRV Port to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_NAME "gMDNSResponseTypeSRVPort" +#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MIN ( 0 ) +#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MAX ( 65525 ) +#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_DEFAULT ( 80 ) + +/* Set the response Type SRV Target to mDNS queries */ +#define CFG_MDNS_RESPONSE_TYPE_SRV_TGT_NAME "gMDNSResponseTypeSRVTarget" +#define CFG_MDNS_RESPONSE_TYPE_SRV_TGT_DEFAULT "goprobp-D89685121212.local" +#endif /* MDNS_OFFLOAD */ + +/* + * gExtScanConcMode is used to manage EXT Scan during concurrency + * This can be useful during WFD session. To avoid glitches during WFD + * either ext scan has to be disabled or use split scan + * 0: Disable EXT Scan + * 1: Use Split scan + * 2: Enable EXT Scan + */ +#define CFG_EXT_SCAN_CONC_MODE "gExtScanConcMode" +#define CFG_EXT_SCAN_CONC_MODE_MIN (0) +#define CFG_EXT_SCAN_CONC_MODE_MAX (2) +#define CFG_EXT_SCAN_CONC_MODE_DEFAULT (0) + +/* + * If within gLinkFailTimeout period(values is mentioned in msec) if FW + * doesn't receive acks for gLinkFailTxCnt number of packets, then link will + * be disconnected. + */ + +#define CFG_LINK_FAIL_TIMEOUT_NAME "gLinkFailTimeout" +#define CFG_LINK_FAIL_TIMEOUT_MIN ( 1000 ) +#define CFG_LINK_FAIL_TIMEOUT_MAX ( 60000 ) +#define CFG_LINK_FAIL_TIMEOUT_DEF ( 6000 ) + +#define CFG_LINK_FAIL_TX_CNT_NAME "gLinkFailTxCnt" +#define CFG_LINK_FAIL_TX_CNT_MIN ( 50 ) +#define CFG_LINK_FAIL_TX_CNT_MAX ( 1000 ) +#define CFG_LINK_FAIL_TX_CNT_DEF ( 200 ) + +#define CFG_OPTIMIZE_CA_EVENT_NAME "gOptimizeCAevent" +#define CFG_OPTIMIZE_CA_EVENT_DISABLE ( 0 ) +#define CFG_OPTIMIZE_CA_EVENT_ENABLE ( 1 ) +#define CFG_OPTIMIZE_CA_EVENT_DEFAULT ( 0 ) + +#define CFG_FWR_MEM_DUMP_NAME "gEnableFwrMemDump" +#define CFG_FWR_MEM_DUMP_MAX ( 1 ) +#define CFG_FWR_MEM_DUMP_MIN ( 0 ) +#define CFG_FWR_MEM_DUMP_DEF ( 1 ) + +#define CFG_ACTIVE_PASSIVE_CHAN_CONV_NAME "gActivePassiveChCon" +#define CFG_ACTIVE_PASSIVE_CHAN_CONV_MIN (0) +#define CFG_ACTIVE_PASSIVE_CHAN_CONV_MAX (1) +#define CFG_ACTIVE_PASSIVE_CHAN_CONV_DEF (1) + +#define CFG_WIFI_CONFIG_ENABLE "gEnableWifiConfig" +#define CFG_WIFI_CONFIG_MIN (0) +#define CFG_WIFI_CONFIG_MAX (1) +#define CFG_WIFI_CONFIG_DEFAULT (1) + +#define CFG_MAXCHAN_FOR_CHANTIME_CORR_NAME "gMaxChannelForMoreDwellTime" +#define CFG_MAXCHAN_FOR_CHANTIME_CORR_MIN (0) +#define CFG_MAXCHAN_FOR_CHANTIME_CORR_MAX (35) +#define CFG_MAXCHAN_FOR_CHANTIME_CORR_DEFAULT (10) + +/* + * BOffsetCorrectionEnable : This ini will control enabling/disabling + * of rate dependent power offsets in firmware + */ +#define CFG_SAR_BOFFSET_SET_CORRECTION_NAME "gBOffsetCorrectionEnable" +#define CFG_SAR_BOFFSET_SET_CORRECTION_MIN (0) +#define CFG_SAR_BOFFSET_SET_CORRECTION_MAX (1) +#define CFG_SAR_BOFFSET_SET_CORRECTION_DEFAULT (0) + +/* + * If gEnableEdcaParams is set to 1, params gEdcaVoCwmin, + * gEdcaViCwmin, gEdcaBkCwmin, gEdcaBeCwmin, gEdcaVoCwmax, + * gEdcaViCwmax, gEdcaBkCwmax, gEdcaBeCwmax, gEdcaVoAifs, + * gEdcaViAifs, gEdcaBkAifs and gEdcaBeAifs values are used + * to overwrite the values received from AP + */ +#define CFG_ENABLE_EDCA_INI_NAME "gEnableEdcaParams" +#define CFG_ENABLE_EDCA_INI_MIN (0) +#define CFG_ENABLE_EDCA_INI_MAX (1) +#define CFG_ENABLE_EDCA_INI_DEFAULT (0) + +/* Cwmin value for EDCA_AC_VO. CWVomin = 2^gEdcaVoCwmin -1 */ +#define CFG_EDCA_VO_CWMIN_VALUE_NAME "gEdcaVoCwmin" +#define CFG_EDCA_VO_CWMIN_VALUE_MIN (0x0) +#define CFG_EDCA_VO_CWMIN_VALUE_MAX (15) +#define CFG_EDCA_VO_CWMIN_VALUE_DEFAULT (2) + +/* Cwmin value for EDCA_AC_VI. CWVimin = 2^gEdcaViCwmin -1 */ +#define CFG_EDCA_VI_CWMIN_VALUE_NAME "gEdcaViCwmin" +#define CFG_EDCA_VI_CWMIN_VALUE_MIN (0x0) +#define CFG_EDCA_VI_CWMIN_VALUE_MAX (15) +#define CFG_EDCA_VI_CWMIN_VALUE_DEFAULT (3) + +/* Cwmin value for EDCA_AC_BK. CWBkmin = 2^gEdcaBkCwmin -1 */ +#define CFG_EDCA_BK_CWMIN_VALUE_NAME "gEdcaBkCwmin" +#define CFG_EDCA_BK_CWMIN_VALUE_MIN (0x0) +#define CFG_EDCA_BK_CWMIN_VALUE_MAX (15) +#define CFG_EDCA_BK_CWMIN_VALUE_DEFAULT (4) + +/* Cwmin value for EDCA_AC_BE. CWBemin = 2^gEdcaBeCwmin -1 */ +#define CFG_EDCA_BE_CWMIN_VALUE_NAME "gEdcaBeCwmin" +#define CFG_EDCA_BE_CWMIN_VALUE_MIN (0x0) +#define CFG_EDCA_BE_CWMIN_VALUE_MAX (15) +#define CFG_EDCA_BE_CWMIN_VALUE_DEFAULT (4) + +/* Cwmax value for EDCA_AC_VO. CWVomax = 2^gEdcaVoCwmax -1 */ +#define CFG_EDCA_VO_CWMAX_VALUE_NAME "gEdcaVoCwmax" +#define CFG_EDCA_VO_CWMAX_VALUE_MIN (0) +#define CFG_EDCA_VO_CWMAX_VALUE_MAX (15) +#define CFG_EDCA_VO_CWMAX_VALUE_DEFAULT (3) + +/* Cwmax value for EDCA_AC_VI. CWVimax = 2^gEdcaViCwmax -1 */ +#define CFG_EDCA_VI_CWMAX_VALUE_NAME "gEdcaViCwmax" +#define CFG_EDCA_VI_CWMAX_VALUE_MIN (0) +#define CFG_EDCA_VI_CWMAX_VALUE_MAX (15) +#define CFG_EDCA_VI_CWMAX_VALUE_DEFAULT (4) + +/* Cwmax value for EDCA_AC_BK. CWBkmax = 2^gEdcaBkCwmax -1 */ +#define CFG_EDCA_BK_CWMAX_VALUE_NAME "gEdcaBkCwmax" +#define CFG_EDCA_BK_CWMAX_VALUE_MIN (0) +#define CFG_EDCA_BK_CWMAX_VALUE_MAX (15) +#define CFG_EDCA_BK_CWMAX_VALUE_DEFAULT (10) + +/* Cwmax value for EDCA_AC_BE. CWBemax = 2^gEdcaBeCwmax -1 */ +#define CFG_EDCA_BE_CWMAX_VALUE_NAME "gEdcaBeCwmax" +#define CFG_EDCA_BE_CWMAX_VALUE_MIN (0) +#define CFG_EDCA_BE_CWMAX_VALUE_MAX (15) +#define CFG_EDCA_BE_CWMAX_VALUE_DEFAULT (10) + +/* Aifs value for EDCA_AC_VO.*/ +#define CFG_EDCA_VO_AIFS_VALUE_NAME "gEdcaVoAifs" +#define CFG_EDCA_VO_AIFS_VALUE_MIN (0) +#define CFG_EDCA_VO_AIFS_VALUE_MAX (15) +#define CFG_EDCA_VO_AIFS_VALUE_DEFAULT (2) + +/* Aifs value for EDCA_AC_VI.*/ +#define CFG_EDCA_VI_AIFS_VALUE_NAME "gEdcaViAifs" +#define CFG_EDCA_VI_AIFS_VALUE_MIN (0) +#define CFG_EDCA_VI_AIFS_VALUE_MAX (15) +#define CFG_EDCA_VI_AIFS_VALUE_DEFAULT (2) + +/* Aifs value for EDCA_AC_BK.*/ +#define CFG_EDCA_BK_AIFS_VALUE_NAME "gEdcaBkAifs" +#define CFG_EDCA_BK_AIFS_VALUE_MIN (0) +#define CFG_EDCA_BK_AIFS_VALUE_MAX (15) +#define CFG_EDCA_BK_AIFS_VALUE_DEFAULT (7) + +/* Aifs value for EDCA_AC_BE.*/ +#define CFG_EDCA_BE_AIFS_VALUE_NAME "gEdcaBeAifs" +#define CFG_EDCA_BE_AIFS_VALUE_MIN (0) +#define CFG_EDCA_BE_AIFS_VALUE_MAX (15) +#define CFG_EDCA_BE_AIFS_VALUE_DEFAULT (3) + +/* If gSendMgmtPktViaWQ5 is enabled, mgmt packet will go via WQ5 */ +#define CFG_SEND_MGMT_PKT_VIA_WQ5_NAME "gSendMgmtPktViaWQ5" +#define CFG_SEND_MGMT_PKT_VIA_WQ5_MIN ( 0 ) +#define CFG_SEND_MGMT_PKT_VIA_WQ5_MAX ( 1) +#define CFG_SEND_MGMT_PKT_VIA_WQ5_DEF ( 0 ) + +/* + * gSapProbeRespOffload: when set in sap, offloads the + * probe response transmission to firmware + */ +#define CFG_SAP_PROBE_RESP_OFFLOAD_NAME "gSapProbeRespOffload" +#define CFG_SAP_PROBE_RESP_OFFLOAD_MIN (0) +#define CFG_SAP_PROBE_RESP_OFFLOAD_MAX (1) +#define CFG_SAP_PROBE_RESP_OFFLOAD_DEFAULT (1) + +/* + * gDisableScanDuringSco is used to disable/enable scan during SCO call + * This can be useful to avoid glitches because of EXIT_IMPS invoked by scan + * when SCO call in progress + * 0: Enable scan + * 1: Disable scan + */ +#define CFG_DISABLE_SCAN_DURING_SCO "gDisableScanDuringSco" +#define CFG_DISABLE_SCAN_DURING_SCO_MIN (0) +#define CFG_DISABLE_SCAN_DURING_SCO_MAX (1) +#define CFG_DISABLE_SCAN_DURING_SCO_DEFAULT (0) + +#define CFG_SAP_INTERNAL_RESTART_NAME "gEnableSapInternalRestart" +#define CFG_SAP_INTERNAL_RESTART_MIN (0) +#define CFG_SAP_INTERNAL_RESTART_MAX (1) +#define CFG_SAP_INTERNAL_RESTART_DEFAULT (1) + +/* + * maximum interval (in seconds) for a + * single scan plan supported by the device. + */ +#define CFG_MAX_SCHED_SCAN_PLAN_INT_NAME "g_max_sched_scan_plan_int" +#define CFG_MAX_SCHED_SCAN_PLAN_INT_MIN (1) +#define CFG_MAX_SCHED_SCAN_PLAN_INT_MAX (7200) +#define CFG_MAX_SCHED_SCAN_PLAN_INT_DEFAULT (3600) + +/* + * maximum number of iterations for a single + * scan plan supported by the device. + */ +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_NAME "g_max_sched_scan_plan_itrns" +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN (1) +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX (100) +#define CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT (10) + +/* + * gEnableLFRMBB is used to disable/enable LFR Make before Break + * 1: Enable LFR Make before Break + * 0: Disable LFR Make before Break + */ +#define CFG_ENABLE_LFR_MBB "gEnableLFRMBB" +#define CFG_ENABLE_LFR_MBB_MIN (0) +#define CFG_ENABLE_LFR_MBB_MAX (1) +#define CFG_ENABLE_LFR_MBB_DEFAULT (0) + +/* Value for TRIGGER_NULLFRAME_BEFORE_HB.*/ +#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_NAME "gTriggerNullframeBeforeHb" +#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN (0) +#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX (1) +#define CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEFAULT (0) + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +typedef struct +{ + //Bitmap to track what is explicitly configured + DECLARE_BITMAP(bExplicitCfg, MAX_CFG_INI_ITEMS); + + //Config parameters + v_U32_t RTSThreshold; + v_U32_t FragmentationThreshold; + v_U32_t nCheckForHangTime; + v_U32_t Calibration; + v_U32_t CalibrationPeriod; + v_U8_t OperatingChannel; + v_BOOL_t ShortSlotTimeEnabled; + v_BOOL_t Is11dSupportEnabled; + v_BOOL_t Is11hSupportEnabled; + v_U32_t nDeferScanTimeInterval; + v_BOOL_t fEnforce11dChannels; + v_BOOL_t fSupplicantCountryCodeHasPriority; + v_BOOL_t fEnforceCountryCodeMatch; + v_BOOL_t fEnforceDefaultDomain; + v_U32_t Cfg1Id; + v_U32_t Cfg2Id; + v_U32_t Cfg3Id; + v_U32_t Cfg4Id; + v_U32_t Cfg5Id; + v_U32_t Cfg1Value; + v_U32_t Cfg2Value; + v_U32_t Cfg3Value; + v_U32_t Cfg4Value; + v_U32_t Cfg5Value; + v_U32_t HeartbeatThresh24; + char PowerUsageControl[4]; + v_U8_t nEnableSuspend; + v_U8_t nEnableDriverStop; + v_BOOL_t fIsImpsEnabled; + v_BOOL_t fIsSsrPanicOnFailure; + v_BOOL_t fIsLogpEnabled; + v_U8_t btcExecutionMode; + v_U8_t btcConsBtSlotsToBlockDuringDhcp; + v_U8_t btcA2DPBtSubIntervalsDuringDhcp; + v_U32_t btcStaticLenInqBt; + v_U32_t btcStaticLenPageBt; + v_U32_t btcStaticLenConnBt; + v_U32_t btcStaticLenLeBt; + v_U32_t btcStaticLenInqWlan; + v_U32_t btcStaticLenPageWlan; + v_U32_t btcStaticLenConnWlan; + v_U32_t btcStaticLenLeWlan; + v_U32_t btcDynMaxLenBt; + v_U32_t btcDynMaxLenWlan; + v_U32_t btcMaxScoBlockPerc; + v_U32_t btcDhcpProtOnA2dp; + v_U32_t btcDhcpProtOnSco; + v_U32_t mwsCoexVictimWANFreq[10]; + v_U32_t mwsCoexVictimWLANFreq[10]; + v_U32_t mwsCoexVictimConfig[10]; + v_U32_t mwsCoexVictimConfig2[10]; + v_U32_t mwsCoexModemBackoff; + v_U32_t mwsCoexConfig[6]; + v_U32_t SARPowerBackoff; + v_U32_t nImpsModSleepTime; + v_U32_t nImpsMaxSleepTime; + v_U32_t nImpsMinSleepTime; + v_BOOL_t fIsBmpsEnabled; + v_U32_t nBmpsModListenInterval; + v_U32_t nBmpsMaxListenInterval; + v_U32_t nBmpsMinListenInterval; + v_BOOL_t fIsAutoBmpsTimerEnabled; + v_U32_t nAutoBmpsTimerValue; + eHddDot11Mode dot11Mode; + v_U32_t nChannelBondingMode24GHz; + bool override_ht20_40_24g; + v_U32_t nChannelBondingMode5GHz; + v_U32_t MaxRxAmpduFactor; + v_U32_t nBAAgingTimerInterval; + v_U16_t TxRate; + v_U32_t AdaptiveThresholdAlgo; + v_U32_t ShortGI20MhzEnable; + v_U32_t BlockAckAutoSetup; + v_U32_t ScanResultAgeCount; + v_U32_t nScanAgeTimeNCNPS; + v_U32_t nScanAgeTimeNCPS; + v_U32_t nScanAgeTimeCNPS; + v_U32_t nScanAgeTimeCPS; + v_U8_t nRssiCatGap; + v_BOOL_t fIsShortPreamble; + v_BOOL_t fIsAutoIbssBssid; + v_MACADDR_t IbssBssid; + v_U32_t AdHocChannel5G; + v_U32_t AdHocChannel24G; + v_U8_t intfAddrMask; + v_MACADDR_t intfMacAddr[VOS_MAX_CONCURRENCY_PERSONA]; + + v_BOOL_t apUapsdEnabled; + v_BOOL_t apRandomBssidEnabled; + v_BOOL_t apProtEnabled; + v_U16_t apProtection; + v_BOOL_t apOBSSProtEnabled; + v_U8_t MinFramesProcThres; + v_U8_t apCntryCode[4]; + v_BOOL_t apDisableIntraBssFwd; + v_U8_t nEnableListenMode; + v_U32_t nAPAutoShutOff; + v_U8_t apStartChannelNum; + v_U8_t apEndChannelNum; + v_U8_t apOperatingBand; + v_BOOL_t apAutoChannelSelection; + v_U8_t enableLTECoex; + v_U32_t apKeepAlivePeriod; + v_U32_t goKeepAlivePeriod; + v_U32_t apLinkMonitorPeriod; + v_U32_t goLinkMonitorPeriod; + v_U32_t nBeaconInterval; + v_U8_t nTxPowerCap; //In dBm + v_BOOL_t fIsLowGainOverride; + v_U8_t disablePacketFilter; +#if defined WLAN_FEATURE_VOWIFI + v_BOOL_t fRrmEnable; + v_U8_t nInChanMeasMaxDuration; + v_U8_t nOutChanMeasMaxDuration; + v_U16_t nRrmRandnIntvl; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + //Vowifi 11r params + v_BOOL_t fFTResourceReqSupported; +#endif + + v_BOOL_t gEnableRoamDelayStats; +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + v_U16_t nNeighborScanPeriod; + v_U8_t nNeighborReassocRssiThreshold; + v_U8_t nNeighborLookupRssiThreshold; + v_U8_t neighborScanChanList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + v_U16_t nNeighborScanMinChanTime; + v_U16_t nNeighborScanMaxChanTime; + v_U16_t nMaxNeighborReqTries; + v_U16_t nNeighborResultsRefreshPeriod; + v_U16_t nEmptyScanRefreshPeriod; + v_U8_t nNeighborInitialForcedRoamTo5GhEnable; + v_U8_t nWeakZoneRssiThresholdForRoam; +#endif + + //Additional Handoff params + v_BOOL_t nEnableIdleScan; + v_U32_t nRoamingTime; + v_U16_t nVccRssiTrigger; + v_U32_t nVccUlMacLossThreshold; + + v_U32_t nPassiveMinChnTime; //in units of milliseconds + v_U32_t nPassiveMaxChnTime; //in units of milliseconds + v_U32_t nActiveMinChnTime; //in units of milliseconds + v_U32_t nActiveMaxChnTime; //in units of milliseconds + + v_U32_t nInitialDwellTime; //in units of milliseconds + + uint32_t min_chntime_btc_esco; //in units of milliseconds + uint32_t max_chntime_btc_esco; //in units of milliseconds + uint32_t min_chntime_btc_sco; + uint32_t max_chntime_btc_sco; +#ifdef WLAN_AP_STA_CONCURRENCY + v_U32_t nPassiveMinChnTimeConc; //in units of milliseconds + v_U32_t nPassiveMaxChnTimeConc; //in units of milliseconds + v_U32_t nActiveMinChnTimeConc; //in units of milliseconds + v_U32_t nActiveMaxChnTimeConc; //in units of milliseconds + v_U32_t nRestTimeConc; //in units of milliseconds + v_U8_t nNumStaChanCombinedConc; //number of channels combined for + //STA in each split scan operation + v_U8_t nNumP2PChanCombinedConc; //number of channels combined for + //P2P in each split scan operation +#endif + + v_U8_t nMaxPsPoll; + + v_U8_t nRssiFilterPeriod; + v_BOOL_t fIgnoreDtim; + v_U8_t fMaxLIModulatedDTIM; + + v_U8_t nRxAnt; + v_U8_t fEnableFwHeartBeatMonitoring; + v_U8_t fEnableFwBeaconFiltering; + v_BOOL_t fEnableFwRssiMonitoring; + v_U8_t nDataInactivityTimeout; + v_U8_t nthBeaconFilter; + + //WMM QoS Configuration + hdd_wmm_user_mode_t WmmMode; + v_BOOL_t b80211eIsEnabled; + v_U8_t UapsdMask; // what ACs to setup U-APSD for at assoc + v_U32_t InfraUapsdVoSrvIntv; + v_U32_t InfraUapsdVoSuspIntv; + v_U32_t InfraUapsdViSrvIntv; + v_U32_t InfraUapsdViSuspIntv; + v_U32_t InfraUapsdBeSrvIntv; + v_U32_t InfraUapsdBeSuspIntv; + v_U32_t InfraUapsdBkSrvIntv; + v_U32_t InfraUapsdBkSuspIntv; +#ifdef FEATURE_WLAN_LFR + v_BOOL_t isFastRoamIniFeatureEnabled; + v_BOOL_t MAWCEnabled; +#endif +#ifdef FEATURE_WLAN_ESE + v_U32_t InfraInactivityInterval; + v_BOOL_t isEseIniFeatureEnabled; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + v_BOOL_t isFastTransitionEnabled; + v_U8_t RoamRssiDiff; + v_U8_t nImmediateRoamRssiDiff; + v_BOOL_t isWESModeEnabled; +#endif +#ifdef FEATURE_WLAN_OKC + v_BOOL_t isOkcIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + v_BOOL_t isRoamOffloadScanEnabled; + v_BOOL_t isPERRoamEnabled; + v_BOOL_t isPERRoamRxPathEnabled; + v_BOOL_t isPERRoamCCAEnabled; + v_S15_t PERRoamFullScanThreshold; + v_S15_t PERMinRssiThresholdForRoam; + v_U16_t rateUpThreshold; + v_U16_t rateDownThreshold; + v_U16_t PERroamTriggerPercent; + v_U32_t waitPeriodForNextPERScan; + v_U32_t PERtimerThreshold; + v_U32_t PERroamRxPktsThreshold; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + tANI_BOOLEAN enable_lfr_mbb; +#endif + + hdd_wmm_classification_t PktClassificationBasis; // DSCP or 802.1Q + v_BOOL_t bImplicitQosEnabled; + + /* default TSPEC parameters for AC_VO */ + sme_QosWmmDirType InfraDirAcVo; + v_U16_t InfraNomMsduSizeAcVo; + v_U32_t InfraMeanDataRateAcVo; + v_U32_t InfraMinPhyRateAcVo; + v_U16_t InfraSbaAcVo; + + /* default TSPEC parameters for AC_VI */ + sme_QosWmmDirType InfraDirAcVi; + v_U16_t InfraNomMsduSizeAcVi; + v_U32_t InfraMeanDataRateAcVi; + v_U32_t InfraMinPhyRateAcVi; + v_U16_t InfraSbaAcVi; + + /* default TSPEC parameters for AC_BE */ + sme_QosWmmDirType InfraDirAcBe; + v_U16_t InfraNomMsduSizeAcBe; + v_U32_t InfraMeanDataRateAcBe; + v_U32_t InfraMinPhyRateAcBe; + v_U16_t InfraSbaAcBe; + + /* default TSPEC parameters for AC_BK */ + sme_QosWmmDirType InfraDirAcBk; + v_U16_t InfraNomMsduSizeAcBk; + v_U32_t InfraMeanDataRateAcBk; + v_U32_t InfraMinPhyRateAcBk; + v_U16_t InfraSbaAcBk; + + /* TL related configuration */ + v_U8_t WfqBkWeight; + v_U8_t WfqBeWeight; + v_U8_t WfqViWeight; + v_U8_t WfqVoWeight; + v_U32_t DelayedTriggerFrmInt; + v_U16_t BkReorderAgingTime; + v_U16_t BeReorderAgingTime; + v_U16_t ViReorderAgingTime; + v_U16_t VoReorderAgingTime; + + /* Wowl pattern */ + char wowlPattern[1024]; + + /* Control for Replay counetr. value 1 means + single replay counter for all TID*/ + v_BOOL_t bSingleTidRc; + v_U8_t mcastBcastFilterSetting; + v_BOOL_t fhostArpOffload; + v_BOOL_t fhostNSOffload; + v_BOOL_t burstSizeDefinition; + v_U8_t tsInfoAckPolicy; + + /* RF Settling Time Clock */ + v_U32_t rfSettlingTimeUs; + v_U8_t enableBtAmp; +#ifdef WLAN_BTAMP_FEATURE + v_U8_t preferredChannel; +#endif //WLAN_BTAMP_FEATURE + + v_U8_t dynamicPsPollValue; + v_BOOL_t AddTSWhenACMIsOff; + v_BOOL_t fValidateScanList; + + v_U32_t infraStaKeepAlivePeriod; + v_U8_t nNullDataApRespTimeout; + v_U8_t nBandCapability; + + v_U32_t apDataAvailPollPeriodInMs; + v_BOOL_t fEnableBeaconEarlyTermination; + v_BOOL_t teleBcnWakeupEn; + +/* VOS Trace Control*/ + v_U16_t vosTraceEnableBAP; + v_U16_t vosTraceEnableTL; + v_U16_t vosTraceEnableWDI; + v_U16_t vosTraceEnableHDD; + v_U16_t vosTraceEnableSME; + v_U16_t vosTraceEnablePE; + v_U16_t vosTraceEnablePMC; + v_U16_t vosTraceEnableWDA; + v_U16_t vosTraceEnableSYS; + v_U16_t vosTraceEnableVOSS; + v_U16_t vosTraceEnableSAP; + v_U16_t vosTraceEnableHDDSAP; + + /* WDI Trace Control */ + v_U32_t wdiTraceEnableDAL; + v_U32_t wdiTraceEnableCTL; + v_U32_t wdiTraceEnableDAT; + v_U32_t wdiTraceEnablePAL; + v_U16_t nTeleBcnTransListenInterval; + v_U16_t nTeleBcnMaxListenInterval; + v_U16_t nTeleBcnTransLiNumIdleBeacons; + v_U16_t nTeleBcnMaxLiNumIdleBeacons; + v_U8_t bcnEarlyTermWakeInterval; + v_U32_t enableCloseLoop; + v_U8_t enableBypass11d; + v_U8_t enableDFSChnlScan; + v_U8_t enableDFSPnoChnlScan; + v_U8_t enableDynamicDTIM; + v_U8_t enableAutomaticTxPowerControl; + v_U8_t ShortGI40MhzEnable; + eHddLinkSpeedReportType reportMaxLinkSpeed; + v_S31_t linkSpeedRssiHigh; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + v_BOOL_t nRoamPrefer5GHz; + v_BOOL_t nRoamIntraBand; + v_U8_t nProbes; + v_U16_t nRoamScanHomeAwayTime; +#endif + v_S31_t linkSpeedRssiMid; + v_S31_t linkSpeedRssiLow; + v_U8_t enableMCC; + v_U8_t allowMCCGODiffBI; + v_BOOL_t isP2pDeviceAddrAdministrated; + v_U8_t thermalMitigationEnable; +#ifdef WLAN_FEATURE_11AC + v_U8_t vhtChannelWidth; + v_U8_t vhtRxMCS; + v_U8_t vhtTxMCS; + v_BOOL_t enableTxBF; + v_U8_t txBFCsnValue; + v_BOOL_t enableMuBformee; + v_U8_t gVhtMaxAmpduLenExp; +#endif + v_U8_t enableModulatedDTIM; + v_U32_t fEnableMCAddrList; + v_BOOL_t enableFirstScan2GOnly; + v_BOOL_t skipDfsChnlInP2pSearch; + v_BOOL_t ignoreDynamicDtimInP2pMode; + v_U16_t configMccParam; + v_U32_t numBuffAdvert; + v_BOOL_t enableRxSTBC; +#ifdef FEATURE_WLAN_TDLS + v_BOOL_t fEnableTDLSSupport; + v_BOOL_t fEnableTDLSImplicitTrigger; + v_U32_t fTDLSTxStatsPeriod; + v_U32_t fTDLSTxPacketThreshold; + v_U32_t fTDLSDiscoveryPeriod; + v_U32_t fTDLSMaxDiscoveryAttempt; + v_U32_t fTDLSIdleTimeout; + v_U32_t fTDLSIdlePacketThreshold; + v_U32_t fTDLSRSSIHysteresis; + v_S31_t fTDLSRSSITriggerThreshold; + v_S31_t fTDLSRSSITeardownThreshold; + v_U32_t fTDLSUapsdMask; // what ACs to setup U-APSD for TDLS + v_U32_t fEnableTDLSBufferSta; + v_U32_t fTDLSPuapsdInactivityTimer; + v_U32_t fTDLSRxFrameThreshold; + v_BOOL_t fTDLSExternalControl; + v_U32_t fEnableTDLSOffChannel; + v_U32_t fEnableTDLSWmmMode; + v_BOOL_t fEnableTDLSScanCoexSupport; + v_BOOL_t fEnableTDLSScan; +#endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + v_BOOL_t fEnableLLStats; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + v_BOOL_t fEnableEXTScan; +#endif +#ifdef WLAN_SOFTAP_VSTA_FEATURE + v_BOOL_t fEnableVSTASupport; +#endif +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + v_BOOL_t fEnableActiveModeOffload; +#endif + v_U32_t enableLpwrImgTransition; + v_U32_t enable_conc_bmiss; + v_U32_t enable_units_bwait; + v_U8_t scanAgingTimeout; + v_BOOL_t enableTxLdpc; + v_U8_t disableLDPCWithTxbfAP; + v_U8_t enableMCCAdaptiveScheduler; + v_BOOL_t isAndroidPsEn; + v_BOOL_t sapAllowAllChannel; + v_U8_t retryLimitZero; + v_U8_t retryLimitOne; + v_U8_t retryLimitTwo; + v_U8_t disableAggWithBtc; + char listOfNonDfsCountryCode[128]; + v_BOOL_t enableSSR; + char listOfNon11acCountryCode[128]; + v_U32_t cfgMaxMediumTime; + v_U8_t enableTrafficMonitor; + v_U32_t trafficIdleTimeout; + v_BOOL_t enableVhtFor24GHzBand; + v_U8_t fScanOffload; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* Flag indicating whether legacy fast roam during concurrency is enabled in cfg.ini or not */ + v_BOOL_t bFastRoamInConIniFeatureEnabled; +#endif + v_BOOL_t fEnableAdaptRxDrain; + //TX and RX traffic threshold for split scan + v_U8_t txRxThresholdForSplitScan; + v_U8_t dynSplitscan; //Enable/Disable dynamic + //splitscan + //Traffic monitor timer for split scan + v_U32_t trafficMntrTmrForSplitScan; + v_U8_t flexConnectPowerFactor; + v_BOOL_t enableIbssHeartBeatOffload; + v_U32_t antennaDiversity; + v_BOOL_t fEnableSNRMonitoring; + /*PNO related parameters */ +#ifdef FEATURE_WLAN_SCAN_PNO + v_BOOL_t configPNOScanSupport; + v_U32_t configPNOScanTimerRepeatValue; +#endif + v_U8_t isAmsduSupportInAMPDU; + v_U8_t nSelect5GHzMargin; + v_U8_t isCoalesingInIBSSAllowed; + v_BOOL_t cfgAthDisable; + v_U32_t cfgBtcActiveWlanLen; + v_U32_t cfgBtcActiveBtLen; + v_U32_t cfgBtcSapActiveWlanLen; + v_U32_t cfgBtcSapActiveBtLen; +#ifdef MEMORY_DEBUG + v_BOOL_t IsMemoryDebugSupportEnabled; +#endif + char overrideCountryCode[4]; + v_U32_t gAsdProbeInterval; + v_S7_t gAsdTriggerThreshold; + v_U32_t gAsdRTTRssiHystThreshold; + v_BOOL_t debugP2pRemainOnChannel; + v_U32_t cfgBtcCTS2SduringSCO; + v_U32_t gEnableDebugLog; + v_U16_t nOBSSScanActiveDwellTime; + v_U16_t nOBSSScanPassiveDwellTime; + v_U16_t nOBSSScanWidthTriggerInterval; + v_BOOL_t gEnableStrictRegulatoryForFCC; + v_BOOL_t advertiseConcurrentOperation; + v_U32_t defaultRateIndex24Ghz; + v_BOOL_t sapEnable11AC; + v_BOOL_t cfgRAFilterEnable; + v_U16_t cfgRARateLimitInterval; + v_U8_t allowDFSChannelRoam; + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + //WLAN Logging + v_U32_t wlanLoggingEnable; + v_U32_t wlanLoggingFEToConsole; + v_U32_t wlanLoggingNumBuf; + v_U32_t wlanPerPktStatsLogEnable; + v_U32_t wlanPerPktStatsNumBuf; +#endif + v_BOOL_t ignorePeerErpInfo; + v_BOOL_t initialScanSkipDFSCh; + v_U32_t cfgBtcFatalHidnSniffBlkGuidance; + v_U32_t cfgBtcCriticalHidnSniffBlkGuidance; + v_U32_t cfgBtcA2dpTxQueueThold; + v_U32_t cfgBtcOppTxQueueThold; + v_U32_t tcpDelAckComputeInterval; + v_U32_t tcpDelAckThresholdHigh; + v_U32_t tcpDelAckThresholdLow; + +#ifdef WLAN_FEATURE_11W + v_U32_t pmfSaQueryMaxRetries; + v_U32_t pmfSaQueryRetryInterval; +#endif + v_U32_t deferImpsTime; + v_BOOL_t sendDeauthBeforeCon; + v_U8_t enableMacSpoofing; + v_BOOL_t disableP2PMacSpoofing; + v_BOOL_t enableFatalEvent; + v_BOOL_t enableMgmtLogging; + v_BOOL_t enableBMUHWtracing; + v_BOOL_t enableFWLogging; + v_BOOL_t enableContFWLogging; + v_U8_t minLoggingBufferSize; + v_U8_t maxLoggingBufferSize; + v_BOOL_t fenableCHAvoidance; + v_U8_t gMaxConcurrentActiveSessions; + + v_U32_t enableDynamicWMMPS; + v_U32_t maxUapsdConsecSP; + v_U32_t maxUapsdConsecRxCnt; + v_U32_t maxUapsdConsecTxCnt; + v_U32_t uapsdConsecRxCntMeasWindow; + v_U32_t uapsdConsecTxCntMeasWindow; + v_U32_t maxPsPollInWmmUapsdMode; + v_U32_t maxUapsdInactivityIntervals; + v_U32_t burstModeTXOPValue; + v_U8_t acsScanBandPreference; + v_U16_t acsBandSwitchThreshold; + v_U32_t enableDynamicRAStartRate; + v_U32_t enableRtsCtsHtVht; +#ifdef WLAN_FEATURE_AP_HT40_24G + v_BOOL_t apHT40_24GEnabled; +#endif + v_U16_t gP2PListenDeferInterval; + v_U8_t btcEnableIndTimerVal; + v_U8_t btcFastWlanConnPref; + v_U32_t dxeReplenishRXTimerVal; + v_U32_t dxeSSREnable; + v_U8_t multicast_host_msgs; + v_BOOL_t toggleArpBDRates; + v_U32_t btcStaticOppWlanIdleWlanLen; + v_U32_t btcStaticOppWlanIdleBtLen; + v_U32_t btc_disable_wlan_link_critical; + v_U32_t linkFailTimeout; + v_U32_t linkFailTxCnt; + v_BOOL_t ignorePeerHTopMode; + v_U8_t gOptimizeCAevent; + v_BOOL_t enableFwrMemDump; + v_U8_t gActivePassiveChCon; + v_U32_t cfgExtScanConcMode; + v_U16_t rps_mask; + v_BOOL_t fEnableWifiConfig; + v_BOOL_t crash_inject_enabled; + v_U32_t enable_delack; + v_BOOL_t disableBarWakeUp; + v_U8_t max_chan_for_dwell_time_cfg; + v_U16_t tdls_enable_defer_time; + v_U8_t boffset_correction_enable; +#ifdef DHCP_SERVER_OFFLOAD + v_BOOL_t enable_dhcp_srv_offload; + v_U32_t dhcp_max_num_clients; + v_U8_t dhcp_srv_ip[IPADDR_STRING_LENGTH]; + v_U8_t dhcp_start_lsb; +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + uint32_t enable_mdns_offload; + uint8_t mdns_fqdn[MAX_MDNS_FQDN_LEN]; + uint8_t mdns_uniquefqdn[MAX_MDNS_FQDN_LEN]; + uint8_t mdns_resp_type_a[MAX_MDNS_RESP_LEN]; + uint32_t mdns_resp_type_a_ipv4; + uint8_t mdns_resp_type_txt[MAX_MDNS_RESP_LEN]; + uint8_t mdns_resp_type_txt_content[MAX_MDNS_RESP_LEN]; + uint8_t mdns_resp_type_ptr[MAX_MDNS_RESP_LEN]; + uint8_t mdns_resp_type_ptr_dname[MAX_MDNS_RESP_LEN]; + uint8_t mdns_resp_type_srv[MAX_MDNS_RESP_LEN]; + uint16_t mdns_resp_type_srv_priority; + uint16_t mdns_resp_type_srv_weight; + uint16_t mdns_resp_type_srv_port; + uint8_t mdns_resp_type_srv_target[MAX_MDNS_RESP_LEN]; +#endif /* MDNS_OFFLOAD */ + uint32_t enable_edca_params; + uint32_t edca_vo_cwmin; + uint32_t edca_vi_cwmin; + uint32_t edca_bk_cwmin; + uint32_t edca_be_cwmin; + uint32_t edca_vo_cwmax; + uint32_t edca_vi_cwmax; + uint32_t edca_bk_cwmax; + uint32_t edca_be_cwmax; + uint32_t edca_vo_aifs; + uint32_t edca_vi_aifs; + uint32_t edca_bk_aifs; + uint32_t edca_be_aifs; + v_BOOL_t sendMgmtPktViaWQ5; + v_BOOL_t sap_probe_resp_offload; + v_BOOL_t disable_scan_during_sco; + v_BOOL_t sap_internal_restart; +#ifdef SAP_AUTH_OFFLOAD + bool enable_sap_auth_offload; + uint32_t sap_auth_offload_sec_type; + uint8_t sap_auth_offload_key[WLAN_PSK_STRING_LENGTH]; +#endif /* SAP_AUTH_OFFLOAD */ + uint32_t max_sched_scan_plan_interval; + uint32_t max_sched_scan_plan_iterations; + uint32_t sta_auth_retries_for_code17; + uint32_t trigger_nullframe_before_hb; +} hdd_config_t; + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ +VOS_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx); +VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ); +v_BOOL_t hdd_update_config_dat ( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_cfg_get_config(hdd_context_t *pHddCtx, char *pBuf, int buflen); +eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode( eHddDot11Mode dot11Mode ); +VOS_STATUS hdd_execute_config_command(hdd_context_t *pHddCtx, char *command); +tANI_BOOLEAN hdd_is_okc_mode_enabled(hdd_context_t *pHddCtx); + +VOS_STATUS hdd_string_to_u8_array(char *str, tANI_U8 *intArray, tANI_U8 *len, + tANI_U8 intArrayMaxLen, char *seperator); + +#ifdef MDNS_OFFLOAD +int hdd_string_to_string_array(char *data, uint8_t *datalist, + char separator, uint8_t *num_entries, + uint8_t max_entries, + uint8_t max_len_entry); +#endif /* MDNS_OFFLOAD */ + +#define VAR_OFFSET( _Struct, _Var ) (offsetof(_Struct, _Var)) +#define VAR_SIZE( _Struct, _Var ) (sizeof(((_Struct *)0)->_Var)) + +#define VAR_FLAGS_NONE ( 0 ) +#define VAR_FLAGS_REQUIRED ( 1 << 0 ) // bit 0 is Required or Optional +#define VAR_FLAGS_OPTIONAL ( 0 << 0 ) + +#define VAR_FLAGS_RANGE_CHECK ( 1 << 1 ) // bit 1 tells if range checking is required. + // If less than MIN, assume MIN. + // If greater than MAX, assume MAX. + +#define VAR_FLAGS_RANGE_CHECK_ASSUME_MINMAX ( VAR_FLAGS_RANGE_CHECK ) + +#define VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT ( 1 << 2 ) // bit 2 is range checking that assumes the DEFAULT value + // If less than MIN, assume DEFAULT, + // If grateer than MAX, assume DEFAULT. + +#define VAR_FLAGS_DYNAMIC_CFG ( 1 << 3 ) // Bit 3 indicates that + // the config item can be + // modified dynamicially + // on a running system + +typedef enum +{ + WLAN_PARAM_Integer, + WLAN_PARAM_SignedInteger, + WLAN_PARAM_HexInteger, + WLAN_PARAM_String, + WLAN_PARAM_MacAddr, +}WLAN_PARAMETER_TYPE; + +#define REG_VARIABLE( _Name, _Type, _Struct, _VarName, \ + _Flags, _Default, _Min, _Max ) \ +{ \ + ( _Name ), \ + ( _Type ), \ + ( _Flags ), \ + VAR_OFFSET( _Struct, _VarName ), \ + VAR_SIZE( _Struct, _VarName ), \ + ( _Default ), \ + ( _Min ), \ + ( _Max ), \ + NULL, \ + 0 \ +} + +#define REG_DYNAMIC_VARIABLE( _Name, _Type, _Struct, _VarName, \ + _Flags, _Default, _Min, _Max, \ + _CBFunc, _CBParam ) \ +{ \ + ( _Name ), \ + ( _Type ), \ + ( VAR_FLAGS_DYNAMIC_CFG | ( _Flags ) ), \ + VAR_OFFSET( _Struct, _VarName ), \ + VAR_SIZE( _Struct, _VarName ), \ + ( _Default ), \ + ( _Min ), \ + ( _Max ), \ + ( _CBFunc ), \ + ( _CBParam ) \ +} + +#define REG_VARIABLE_STRING( _Name, _Type, _Struct, _VarName, \ + _Flags, _Default ) \ +{ \ + ( _Name ), \ + ( _Type ), \ + ( _Flags ), \ + VAR_OFFSET( _Struct, _VarName ), \ + VAR_SIZE( _Struct, _VarName ), \ + (unsigned long)( _Default ), \ + 0, \ + 0, \ + NULL, \ + 0 \ +} + +typedef struct tREG_TABLE_ENTRY { + + char* RegName; // variable name in the qcom_cfg.ini file + WLAN_PARAMETER_TYPE RegType; // variable type in the hdd_config_t structure + unsigned long Flags; // Specify optional parms and if RangeCheck is performed + unsigned short VarOffset; // offset to field from the base address of the structure + unsigned short VarSize; // size (in bytes) of the field + unsigned long VarDefault; // default value to use + unsigned long VarMin; // minimum value, for range checking + unsigned long VarMax; // maximum value, for range checking + // Dynamic modification notifier + void (*pfnDynamicNotify)(hdd_context_t *pHddCtx, unsigned long NotifyId); + unsigned long NotifyId; // Dynamic modification identifier +} REG_TABLE_ENTRY; + +static __inline unsigned long utilMin( unsigned long a, unsigned long b ) +{ + return( ( a < b ) ? a : b ); +} + +#endif diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h new file mode 100644 index 000000000000..ef99dd041de6 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_cfg80211.h @@ -0,0 +1,1665 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( HDD_CFG80211_H__ ) +#define HDD_CFG80211_H__ + + +/**=========================================================================== + + \file wlan_hdd_cfg80211.h + + \brief cfg80211 functions declarations + + ==========================================================================*/ + +/* $HEADER$ */ + + +//value for initial part of frames and number of bytes to be compared +#define GAS_INITIAL_REQ "\x04\x0a" +#define GAS_INITIAL_REQ_SIZE 2 + +#define GAS_INITIAL_RSP "\x04\x0b" +#define GAS_INITIAL_RSP_SIZE 2 + +#define GAS_COMEBACK_REQ "\x04\x0c" +#define GAS_COMEBACK_REQ_SIZE 2 + +#define GAS_COMEBACK_RSP "\x04\x0d" +#define GAS_COMEBACK_RSP_SIZE 2 + +#define P2P_PUBLIC_ACTION_FRAME "\x04\x09\x50\x6f\x9a\x09" +#define P2P_PUBLIC_ACTION_FRAME_SIZE 6 + +#define P2P_ACTION_FRAME "\x7f\x50\x6f\x9a\x09" +#define P2P_ACTION_FRAME_SIZE 5 + +#define SA_QUERY_FRAME_REQ "\x08\x00" +#define SA_QUERY_FRAME_REQ_SIZE 2 + +#define SA_QUERY_FRAME_RSP "\x08\x01" +#define SA_QUERY_FRAME_RSP_SIZE 2 + +#define HDD_P2P_WILDCARD_SSID "DIRECT-" //TODO Put it in proper place; +#define HDD_P2P_WILDCARD_SSID_LEN 7 + +#define WNM_BSS_ACTION_FRAME "\x0a\x07" +#define WNM_BSS_ACTION_FRAME_SIZE 2 + +#define WNM_NOTIFICATION_FRAME "\x0a\x1a" +#define WNM_NOTIFICATION_FRAME_SIZE 2 + +#define WPA_OUI_TYPE "\x00\x50\xf2\x01" +#define BLACKLIST_OUI_TYPE "\x00\x50\x00\x00" +#define WHITELIST_OUI_TYPE "\x00\x50\x00\x01" +#define WPA_OUI_TYPE_SIZE 4 + +#define WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 +#define BASIC_RATE_MASK 0x80 +#define RATE_MASK 0x7f + +#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS +/* GPS application requirement */ +#define QCOM_VENDOR_IE_ID 221 +#define QCOM_OUI1 0x00 +#define QCOM_OUI2 0xA0 +#define QCOM_OUI3 0xC6 +#define QCOM_VENDOR_IE_AGE_TYPE 0x100 +#define QCOM_VENDOR_IE_AGE_LEN 11 + +#ifdef FEATURE_WLAN_TDLS +#define WLAN_IS_TDLS_SETUP_ACTION(action) \ + ((SIR_MAC_TDLS_SETUP_REQ <= action) && (SIR_MAC_TDLS_SETUP_CNF >= action)) +#if !defined (TDLS_MGMT_VERSION2) +#define TDLS_MGMT_VERSION2 0 +#endif +#endif + +#define MAX_CHANNEL NUM_2_4GHZ_CHANNELS + NUM_5GHZ_CHANNELS + +#define IS_CHANNEL_VALID(channel) ((channel >= 0 && channel < 15) \ + || (channel >= 36 && channel <= 184)) + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* Number of Radios */ +#define NUM_RADIOS 0x1 +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + + +typedef struct { + u8 element_id; + u8 len; + u8 oui_1; + u8 oui_2; + u8 oui_3; + u32 type; + u32 age; +}__attribute__((packed)) qcom_ie_age ; +#endif + +enum qca_nl80211_vendor_subcmds { + QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0, + QCA_NL80211_VENDOR_SUBCMD_TEST = 1, + + /* subcmds 2..8 not yet allocated */ + QCA_NL80211_VENDOR_SUBCMD_ROAMING = 9, + + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY = 10, + QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY = 11, + QCA_NL80211_VENDOR_SUBCMD_NAN = 12, + QCA_NL80211_VENDOR_SUBCMD_STATS_EXT = 13, + + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET = 14, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET = 15, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR = 16, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS = 17, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS = 18, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS = 19, + /* subcommands for extscan start here */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START = 20, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP = 21, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS = 22, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES = 23, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS = 24, + /* Used when report_threshold is reached in scan cache. */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE = 25, + /* Used to report scan results when each probe rsp. is received, + * if report_events enabled in wifi_scan_cmd_params. + */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT = 26, + /* Indicates progress of scanning state-machine. */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT = 27, + /* Indicates BSSID Hotlist. */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND = 28, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST = 29, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST = 30, + /* EXT TDLS */ + QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE = 34, + QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE = 35, + QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS = 36, + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE = 37, + /* Get supported features */ + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES = 38, + QCA_NL80211_VENDOR_SUBCMD_MAC_OUI = 39, + /* Set nodfs_flag */ + QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG = 40, + + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST = 41, + + /* Get Concurrency Matrix */ + QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42, + QCA_NL80211_VENDOR_SUBCMD_APFIND = 52, + /* Start Wifi Logger */ + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START = 62, + + /* Get Wifi Specific Info */ + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO = 61, + /* Start Wifi Memory Dump */ + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP = 63, + + /* + * APIs corresponding to the sub commands 65-68 are deprecated. + * These sub commands are reserved and not supposed to be used + * for any other purpose + */ + + /* Wi-Fi Configuration subcommands */ + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION = 74, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION = 75, + QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA = 77, + + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI = 80, + + QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS = 79, + + /* subcommand to get link properties */ + QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101, + + QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105, + + /* send BSS Information */ + QCA_NL80211_VENDOR_SUBCMD_GET_STATION = 121, + + /* Start / Stop the NUD stats collections */ + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET = 149, + /* Get the NUD stats, represented by the enum qca_attr_nud_stats_get */ + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET = 150, +}; + +/** + * enum qca_wlan_vendor_attr_get_station - Sub commands used by + * QCA_NL80211_VENDOR_SUBCMD_GET_STATION to get the corresponding + * station information. The information obtained through these + * commands signify the current info in connected state and + * latest cached information during the connected state , if queried + * when in disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO: bss info + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON: assoc fail reason + */ +enum qca_wlan_vendor_attr_get_station { + QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO, + QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_802_11_mode - dot11 mode + * @QCA_WLAN_802_11_MODE_INVALID: Invalid dot11 mode + * @QCA_WLAN_802_11_MODE_11A: mode A + * @QCA_WLAN_802_11_MODE_11B: mode B + * @QCA_WLAN_802_11_MODE_11G: mode G + * @QCA_WLAN_802_11_MODE_11N: mode N + * @QCA_WLAN_802_11_MODE_11AC: mode AC + */ +enum qca_wlan_802_11_mode { + QCA_WLAN_802_11_MODE_INVALID, + QCA_WLAN_802_11_MODE_11A, + QCA_WLAN_802_11_MODE_11B, + QCA_WLAN_802_11_MODE_11G, + QCA_WLAN_802_11_MODE_11N, + QCA_WLAN_802_11_MODE_11AC, +}; + +/** + * enum qca_wlan_auth_type - Authentication key management type + * @QCA_WLAN_AUTH_TYPE_INVALID: Invalid key management type + * @QCA_WLAN_AUTH_TYPE_OPEN: Open key + * @QCA_WLAN_AUTH_TYPE_SHARED: shared key + * @QCA_WLAN_AUTH_TYPE_WPA: wpa key + * @QCA_WLAN_AUTH_TYPE_WPA_PSK: wpa psk key + * @QCA_WLAN_AUTH_TYPE_WPA_NONE: wpa none key + * @QCA_WLAN_AUTH_TYPE_RSN: rsn key + * @QCA_WLAN_AUTH_TYPE_RSN_PSK: rsn psk key + * @QCA_WLAN_AUTH_TYPE_FT: ft key + * @QCA_WLAN_AUTH_TYPE_FT_PSK: ft psk key + * @QCA_WLAN_AUTH_TYPE_SHA256: shared 256 key + * @QCA_WLAN_AUTH_TYPE_SHA256_PSK: shared 256 psk + * @QCA_WLAN_AUTH_TYPE_WAI: wai key + * @QCA_WLAN_AUTH_TYPE_WAI_PSK wai psk key + * @QCA_WLAN_AUTH_TYPE_CCKM_WPA: cckm wpa key + * @QCA_WLAN_AUTH_TYPE_CCKM_RSN: cckm rsn key + */ +enum qca_wlan_auth_type { + QCA_WLAN_AUTH_TYPE_INVALID, + QCA_WLAN_AUTH_TYPE_OPEN, + QCA_WLAN_AUTH_TYPE_SHARED, + QCA_WLAN_AUTH_TYPE_WPA, + QCA_WLAN_AUTH_TYPE_WPA_PSK, + QCA_WLAN_AUTH_TYPE_WPA_NONE, + QCA_WLAN_AUTH_TYPE_RSN, + QCA_WLAN_AUTH_TYPE_RSN_PSK, + QCA_WLAN_AUTH_TYPE_FT, + QCA_WLAN_AUTH_TYPE_FT_PSK, + QCA_WLAN_AUTH_TYPE_SHA256, + QCA_WLAN_AUTH_TYPE_SHA256_PSK, + QCA_WLAN_AUTH_TYPE_WAI, + QCA_WLAN_AUTH_TYPE_WAI_PSK, + QCA_WLAN_AUTH_TYPE_CCKM_WPA, + QCA_WLAN_AUTH_TYPE_CCKM_RSN, + QCA_WLAN_AUTH_TYPE_AUTOSWITCH, +}; + +/** + * enum qca_wlan_vendor_attr_get_station_info - Station Info queried + * through QCA_NL80211_VENDOR_SUBCMD_GET_STATION. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_INVALID: Invalid Attribute + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR: + * Get the standard NL attributes Nested with this attribute. + * Ex : Query BW , BITRATE32 , NSS , Signal , Noise of the Link - + * NL80211_ATTR_SSID / NL80211_ATTR_SURVEY_INFO (Connected Channel) / + * NL80211_ATTR_STA_INFO + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR: + * Get the standard NL attributes Nested with this attribute. + * Ex : Query HT/VHT Capability advertized by the AP. + * NL80211_ATTR_VHT_CAPABILITY / NL80211_ATTR_HT_CAPABILITY + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT: + * Number of successful Roam attempts before a + * disconnect, Unsigned 32 bit value + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM: + * Authentication Key Management Type used for the connected session. + * Signified by enum qca_wlan_auth_type + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE: 802.11 Mode of the + * connected Session, signified by enum qca_wlan_802_11_mode + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION: + * HS20 Indication Element + * @QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON: + * Status Code Corresponding to the Association Failure. + * Unsigned 32 bit value. + */ +enum qca_wlan_vendor_attr_get_station_info { + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST - 1, +}; + +/* define short names for get station info attributes */ +#define LINK_INFO_STANDARD_NL80211_ATTR \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR +#define AP_INFO_STANDARD_NL80211_ATTR \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR +#define INFO_ROAM_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT +#define INFO_AKM \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM +#define WLAN802_11_MODE \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE +#define AP_INFO_HS20_INDICATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION +#define HT_OPERATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION +#define VHT_OPERATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION +#define INFO_ASSOC_FAIL_REASON \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON + +enum qca_nl80211_vendor_subcmds_index { +#ifdef FEATURE_WLAN_CH_AVOID + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX, +#endif /* FEATURE_WLAN_CH_AVOID */ + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX, + /* EXTSCAN Events */ + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX, + /*EXT TDLS*/ + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX, + + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX, + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX, +}; + +/** + * qca_wlan_vendor_attr_nud_stats_set: attribute to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET. This carry the requisite + * information to start / stop the NUD stats collection. + */ +enum qca_attr_nud_stats_set { + QCA_ATTR_NUD_STATS_SET_INVALID = 0, + + /* Flag to Start / Stop the NUD stats collection + * Start - If included , Stop - If not included + */ + QCA_ATTR_NUD_STATS_SET_START = 1, + /* IPv4 address of Default Gateway (in network byte order) */ + QCA_ATTR_NUD_STATS_GW_IPV4 = 2, + + /* keep last */ + QCA_ATTR_NUD_STATS_SET_LAST, + QCA_ATTR_NUD_STATS_SET_MAX = + QCA_ATTR_NUD_STATS_SET_LAST - 1, +}; + +/** + * qca_attr_nud_stats_get: attribute to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET. This carry the requisite + * NUD stats collected when queried. + */ +enum qca_attr_nud_stats_get { + QCA_ATTR_NUD_STATS_GET_INVALID = 0, + /* ARP Request Count from net dev */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV = 1, + /* ARP Request Count sent to lower MAC from upper MAC */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC = 2, + /* ARP Request Count received by lower MAC from upper MAC */ + QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC = 3, + /* ARP Request Count successfully transmitted by the device */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS = 4, + /* ARP Response Count received by lower MAC */ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC = 5, + /* ARP Response Count received by upper MAC */ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC = 6, + /* ARP Response Count delivered to netdev */ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV = 7, + /* ARP Response Count delivered to netdev */ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP = 8, + /* + * Flag indicating if the Stations Link to AP is active. + * Active Link - If exists, Inactive link - If not included + */ + QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE= 9, + QCA_ATTR_NUD_STATS_AP_LINK_DAD= 10, + /* keep last */ + QCA_ATTR_NUD_STATS_GET_LAST, + QCA_ATTR_NUD_STATS_GET_MAX = + QCA_ATTR_NUD_STATS_GET_LAST - 1, + }; + +enum qca_wlan_vendor_attr +{ + QCA_WLAN_VENDOR_ATTR_INVALID = 0, + /* used by QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY */ + QCA_WLAN_VENDOR_ATTR_DFS = 1, + /* used by QCA_NL80211_VENDOR_SUBCMD_NAN */ + QCA_WLAN_VENDOR_ATTR_NAN = 2, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, + /* used by QCA_NL80211_VENDOR_SUBCMD_ROAMING, u32 with values defined + * by enum qca_roaming_policy. */ + QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY = 5, + QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6, + /* Unsigned 32-bit value from enum qca_set_band. */ + QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1, +}; + +/*EXT TDLS*/ +enum qca_wlan_vendor_attr_tdls_enable +{ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR, + /* signed 32-bit value, but lets keep as unsigned for now */ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_tdls_disable +{ + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_tdls_get_status +{ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR, + /* signed 32-bit value, but lets keep as unsigned for now */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_tdls_state +{ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_INVALID = 0, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR, + /* signed 32-bit value, but lets keep as unsigned for now */ + QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_AFTER_LAST - 1, +}; + + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +enum qca_wlan_vendor_attr_ll_stats_set +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD = 1, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_ll_stats_get +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_INVALID = 0, + /* Unsigned 32bit value provided by the caller issuing the GET stats + * command. When reporting the stats results, the driver uses the same + * value to indicate which GET request the results correspond to. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID, + /* Unsigned 34bit value - bit mask to identify what + * statistics are requested for retrieval. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_ll_stats_clr +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ll_stats_results_type - ll stats result type + * + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_INVALID: Initial invalid value + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO: Link layer stats type radio + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE: Link layer stats type interface + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER: Link layer stats type peer + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_AFTER_LAST: Last value + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_MAX: Max value + */ +enum qca_wlan_vendor_attr_ll_stats_results_type { + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO = 1, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_results +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_INVALID = 0, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_REQ_ID = 1, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK, + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_* are + * nested within the interface stats. + */ + + /* Interface mode, e.g., STA, SOFTAP, IBSS, etc. + * Type = enum wifi_interface_mode */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, + /* Interface MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR, + /* Type = enum wifi_connection_state, + * e.g., DISCONNECTED, AUTHENTICATING, etc. + * valid for STA, CLI only. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE, + /* Type = enum wifi_roam_state. Roaming state, + * e.g., IDLE or ACTIVE (is that valid for STA only?) + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING, + /* Unsigned 32bit value. WIFI_CAPABILITY_XXX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES, + /* NULL terminated SSID. An array of 33 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID, + /* BSSID. An array of 6 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID, + /* Country string advertised by AP. An array of 3 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR, + /* Country string for this association. An array of 3 Unsigned 8bit values*/ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_* could + * be nested within the interface stats. + */ + + /* Type = enum wifi_traffic_ac, e.g., V0, VI, BE and BK */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES, + /* Unsigned 32bit value. Number of peers */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_* are + * nested within the interface stats. + */ + + /* Type = enum wifi_peer_type. Peer type, e.g., STA, AP, P2P GO etc. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE, + /* MAC addr corresponding to respective peer. + * An array of 6 Unsigned 8bit values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS, + /* Unsigned int 32bit value representing capabilities + * corresponding to respective peer. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES, + /* Unsigned 32bit value. Number of rates */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES, + + /* Attributes nested within the rate stats.*/ + /* Unsigned 8bit value */ + /* Unsigned int 8bit value; 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE, + /* Unsigned int 8bit value; 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS, + /* Unsigned int 8bit value; 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW, + /* Unsigned int 8bit value; OFDM/CCK rate code would be as per IEEE Std + * in the units of 0.5mbps HT/VHT it would be mcs index */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX, + + /* Unsigned 32bit value. Bit rate in units of 100Kbps */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* could be + * nested within the peer info stats. + */ + + /* Unsigned int 32bit value. Number of successfully transmitted data pkts, + * i.e., with ACK received *corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU, + /* Unsigned int 32bit value. Number of received data pkts + * corresponding to the respective rate. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU, + /* Unsigned int 32bit value. Number of data pkts losses, i.e., + * no ACK received corresponding to *the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST, + /* Unsigned int 32bit value. Total number of data pkt retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES, + /* Unsigned int 32bit value. Total number of short data pkt retries for + the respective rate. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT, + /* Unsigned int 32bit value. Total number of long data pkt retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID, + /* Unsigned 32bit value. Total number of msecs the radio is awake + * accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * transmitting accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * in active receive accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to all scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to NAN accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to EXTSCAN accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to roam scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to PNO scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to HS2.0 scans and GAS exchange accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20, + /* Unsigned 32bit value. Number of channels. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_ + * could be nested within the channel stats. + */ + + /* Type = enum wifi_channel_width. Channel width, e.g., 20, 40, 80, etc.*/ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH, + /* Unsigned 32bit value. Primary 20MHz channel. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ, + /* Unsigned 32bit value. Center frequency (MHz) first segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0, + /* Unsigned 32bit value. Center frequency (MHz) second segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ could be + * nested within the radio stats. + */ + + /* Unsigned int 32bit value representing total number of msecs the radio + * s awake on that *channel accruing over time, corresponding to + * the respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME, + /* Unsigned int 32bit value representing total number of msecs the + * CCA register is busy accruing *over time corresponding to the + * respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME, + + + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO, + + /* Unsigned 8bit value. Used by the driver; if set to 1, it indicates that + * more stats, e.g., peers or radio, are to follow in the next + * QCA_NL80211_VENDOR_SUBCMD_LL_STATS_*_RESULTS event. + * Otherwise, it is set to 0. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA, + + /* Unsigned 64bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET, + + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED, + + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED, + + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME, + + /* Unsigned 32bit value to indicate ll stats result type */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST -1, +}; + + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_EXTSCAN + +enum qca_wlan_vendor_attr_extscan_config_params +{ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0, + + /* Unsigned 32-bit value; Middleware provides it to the driver. Middle ware + * either gets it from caller, e.g., framework, or generates one if + * framework doesn't provide it. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + + /* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS, + + /* NL attributes for input params used by + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START sub command. + */ + + /* Unsigned 32-bit value; channel frequency */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL, + /* Unsigned 32-bit value; dwell time in ms. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME, + /* Unsigned 8-bit value; 0: active; 1: passive; N/A for DFS */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE, + /* Unsigned 8-bit value; channel class */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS, + + /* Unsigned 8-bit value; bucket index, 0 based */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX, + /* Unsigned 8-bit value; band. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND, + /* Unsigned 32-bit value; desired period, in ms. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD, + /* Unsigned 8-bit value; report events semantics. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS, + /* Unsigned 32-bit value. + * Followed by a nested array of EXTSCAN_CHANNEL_SPEC_* attributes. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS, + + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC, + + /* Unsigned 32-bit value; base timer period in ms. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD, + /* Unsigned 32-bit value; number of APs to store in each scan in the + * BSSID/RSSI history buffer (keep the highest RSSI APs). + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN, + /* Unsigned 8-bit value; in %, when scan buffer is this much full, wake up + * APPS. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT, + /* Unsigned 8-bit value; number of scan bucket specs; followed by a nested + * array of_EXTSCAN_BUCKET_SPEC_* attributes and values. The size of the + * array is determined by NUM_BUCKETS. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS, + + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC, + + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH, + /* Unsigned 32-bit value; maximum number of results to be returned. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX, + + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL, + + /* Number of hotlist APs as unsigned 32-bit value, followed by a nested + * array of AP_THRESHOLD_PARAM attributes and values. The size of the + * array is determined by NUM_AP. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP, + + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM, + + /* Unsigned 32bit value; number of samples for averaging RSSI. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE, + /* Unsigned 32bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE, + /* Unsigned 32bit value; number of APs breaching threshold. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING, + /* Unsigned 32bit value; number of APs. Followed by an array of + * AP_THRESHOLD_PARAM attributes. Size of the array is NUM_AP. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP, + /* Unsigned 32bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE, + + /* Unsigned 32-bit value. If max_period is non zero or different than + * period, then this bucket is an exponential backoff bucket. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD, + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT, + /* Unsigned 32-bit value. For exponential back off bucket, number of scans + * performed at a given period and until the exponent is applied. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT, + /* Unsigned 8-bit value; in number of scans, wake up AP after these + * many scans. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS, + + /* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST sub command. + */ + /* Unsigned 32bit value; number of samples to confirm SSID loss. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE, + /* Number of hotlist SSIDs as unsigned 32-bit value, followed by a nested + * array of SSID_THRESHOLD_PARAM_* attributes and values. The size of the + * array is determined by NUM_SSID. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID, + /* Array of QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM, + + /* An array of 33 x Unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID, + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH, + + /* Unsigned 32-bit value; a bitmask w/additional extscan config flag. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_extscan_results +{ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_INVALID = 0, + + /* Unsigned 32-bit value; must match the request Id supplied by Wi-Fi HAL + * in the corresponding subcmd NL msg + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + + /* Unsigned 32-bit value; used to indicate the status response from + * firmware/driver for the vendor sub-command. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, + + /* EXTSCAN Valid Channels attributes */ + /* Unsigned 32bit value; followed by a nested array of CHANNELS. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS, + /* An array of NUM_CHANNELS x Unsigned 32bit value integers representing + * channel numbers + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS, + + /* EXTSCAN Capabilities attributes */ + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE, + /* Signed 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES, + + /* EXTSCAN Attributes used with + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE sub-command. + */ + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + + + /* EXTSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT sub-command. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_* + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST, + + /* Unsigned 32-bit value; age of sample at the time of retrieval */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + /* 33 x unsiged 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + /* Unsigned 32-bit value; channel frequency in MHz */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY, + /* Unsigned 32-bit value; size of the IE DATA blob */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH, + /* An array of IE_LENGTH x Unsigned 8-bit value; blob of all the + * information elements found in the beacon; this data should be a + * packed list of wifi_information_element objects, one after the other. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA, + /* Unsigned 8-bit value; set by driver to indicate more scan results are + * available. + */ + /* Unsigned 8-bit value; set by driver to indicate more scan results are + * available. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + + /* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE + * to indicate number of wifi scan results/bssids retrieved by the scan. + * Also, use QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST to indicate the list + * of wifi scan results returned for each cached result block. + */ + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT sub-command. + */ + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS, + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE + * to indicate number of results. + */ + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE sub-command. + */ + /* An array of 6 x Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL, + /* Unsigned 32-bit value. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI, + /* A nested array of signed 32-bit RSSI values. Size of the array is + * determined by (NUM_RSSI of SIGNIFICANT_CHANGE_RESULT_NUM_RSSI. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST, + + /* EXTSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of gscan cached results returned. + * Also, use QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST to indicate + * the list of gscan cached results. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_NL80211_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_* + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST, + /* Unsigned 32-bit value; a unique identifier for the scan unit. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID, + /* Unsigned 32-bit value; a bitmask w/additional information about scan. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS, + /* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of wifi scan results/bssids retrieved by the scan. + * Also, use QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST to indicate the list + * of wifi scan results returned for each cached result block. + */ + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND sub-command. + */ + /* Use QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE for number + * of results. + * Use QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST to indicate the nested + * list of wifi scan results returned for each wifi_passpoint_match_result block. + * Array size: QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE. + */ + + /* EXTSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND sub-command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES, + /* A nested array of + * QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_* + * attributes. Array size = + * *_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST, + + /* Unsigned 32-bit value; network block id for the matched network */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID, + /* Use QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST to indicate the nested + * list of wifi scan results returned for each wifi_passpoint_match_result block. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN, + /* An array size of PASSPOINT_MATCH_ANQP_LEN of unsigned 8-bit values; + * ANQP data in the information_element format. + */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP, + + /* Unsigned 32bit value; a EXTSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS, + /* Unsigned 32bit value; a EXTSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS, + /* Unsigned 32bit value; a EXTSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID, + /* Unsigned 32bit value; a EXTSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID, + + /* Use attr QCA_WLAN_VENDOR_ATTR_EXTSCAN_NUM_RESULTS_AVAILABLE + * to indicate number of results. + */ + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX = + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST - 1, +}; + +#endif /* WLAN_FEATURE_EXTSCAN */ +enum qca_wlan_vendor_attr_set_scanning_mac_oui{ + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX = + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST - 1, +}; + +/* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO sub command. + */ +enum qca_wlan_vendor_attr_get_wifi_info { + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION = 1, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_get_supported_features { + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_FEATURE_SET = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX = + QCA_WLAN_VENDOR_ATTR_FEATURE_SET_AFTER_LAST - 1, +}; + +/* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX sub command. + */ +enum qca_wlan_vendor_attr_get_concurrency_matrix { + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX = 1, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE = 2, + /* An array of SET_SIZE x Unsigned 32bit values representing + * concurrency combinations. + */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET = 3, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX = + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_wifi_logger_start - Enum for wifi logger starting + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_INVALID: Invalid attribute + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID: Ring ID + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL: Verbose level + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS: Flag + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST: Last value + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX: Max value + */ +enum qca_wlan_vendor_attr_wifi_logger_start { + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID = 1, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL = 2, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS = 3, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST - 1, +}; + +/* NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES. + */ +enum qca_wlan_vendor_attr_link_properties { + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID = 0, + /* Unsigned 8bit value for specifying nof spatial streams */ + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS = 1, + /* Unsigned 8bit value for the rate flags */ + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS = 2, + /* Unsigned 32bit value for operating frequency */ + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ = 3, + + /* KEEP LAST */ + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAX = + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_config: wifi config attr + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_INVALID: invalid config + * @QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM: dynamic dtim + * @QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR: stats avg. factor + * @QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME: guard time + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LAST: last config + * @QCA_WLAN_VENDOR_ATTR_CONFIG_MAX: max config + */ +enum qca_wlan_vendor_config { + QCA_WLAN_VENDOR_ATTR_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM, + QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, + QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, + QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT, + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_RATE, + QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS, + /* 8-bit unsigned value to set the beacon miss threshold in 2.4 GHz */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24 = 37, + /* 8-bit unsigned value to set the beacon miss threshold in 5 GHz */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5 = 38, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_LAST - 1 +}; + +/* Feature defines */ +#define WIFI_FEATURE_INFRA 0x0001 /* Basic infrastructure mode */ +#define WIFI_FEATURE_INFRA_5G 0x0002 /* Support for 5 GHz Band */ +#define WIFI_FEATURE_HOTSPOT 0x0004 /* Support for GAS/ANQP */ +#define WIFI_FEATURE_P2P 0x0008 /* Wifi-Direct */ +#define WIFI_FEATURE_SOFT_AP 0x0010 /* Soft AP */ +#define WIFI_FEATURE_EXTSCAN 0x0020 /* Extended Scan APIs */ +#define WIFI_FEATURE_NAN 0x0040 /* Neighbor Awareness + Networking */ +#define WIFI_FEATURE_D2D_RTT 0x0080 /* Device-to-device RTT */ +#define WIFI_FEATURE_D2AP_RTT 0x0100 /* Device-to-AP RTT */ +#define WIFI_FEATURE_BATCH_SCAN 0x0200 /* Batched Scan (legacy) */ +#define WIFI_FEATURE_PNO 0x0400 /* Preferred network offload */ +#define WIFI_FEATURE_ADDITIONAL_STA 0x0800 /* Support for two STAs */ +#define WIFI_FEATURE_TDLS 0x1000 /* Tunnel directed link + setup */ +#define WIFI_FEATURE_TDLS_OFFCHANNEL 0x2000 /* Support for TDLS off + channel */ +#define WIFI_FEATURE_EPR 0x4000 /* Enhanced power reporting */ +#define WIFI_FEATURE_AP_STA 0x8000 /* Support for AP STA + Concurrency */ +#define WIFI_FEATURE_LINK_LAYER_STATS 0x10000 /* Link layer stats */ + +#define WIFI_FEATURE_RTT3 0x20000 /* RTT3 */ + +/* WIFI CONFIG Parameter defines */ +#define WIFI_CONFIG_SET_AVG_STATS_FACTOR 0x0001 /* Average stats factor */ +#define WIFI_CONFIG_SET_GUARD_TIME 0x0002 /* Guard Time */ +#define WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT 0x0001 /* BCNMISS_PENALTY_COUNT */ + +/* Add more features here */ +enum qca_wlan_vendor_attr_set_no_dfs_flag +{ + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX = + QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_AFTER_LAST - 1, +}; +/* + * enum qca_wlan_vendor_attr_wifi_logger_get_ring_data - Get ring data + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_INVALID: Invalid attribute + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID: Ring ID + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_AFTER_LAST: Last value + * @QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX: Max value + */ +enum qca_wlan_vendor_attr_wifi_logger_get_ring_data { + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_AFTER_LAST - 1, +}; + + +/* Vendor id to be used in vendor specific command and events + * to user space. Use QCA OUI 00:13:74 to match with define in + * supplicant code. + */ +#define QCA_NL80211_VENDOR_ID 0x001374 + +#ifdef FEATURE_WLAN_CH_AVOID +#define HDD_MAX_AVOID_FREQ_RANGES 15 +typedef struct sHddAvoidFreqRange +{ + u32 startFreq; + u32 endFreq; +} tHddAvoidFreqRange; + +typedef struct sHddAvoidFreqList +{ + u32 avoidFreqRangeCount; + tHddAvoidFreqRange avoidFreqRange[HDD_MAX_AVOID_FREQ_RANGES]; +} tHddAvoidFreqList; +#endif /* FEATURE_WLAN_CH_AVOID */ + + +/** + * enum qca_wlan_rssi_monitoring_control - rssi control commands + * @QCA_WLAN_RSSI_MONITORING_CONTROL_INVALID: invalid + * @QCA_WLAN_RSSI_MONITORING_START: rssi monitoring start + * @QCA_WLAN_RSSI_MONITORING_STOP: rssi monitoring stop + */ +enum qca_wlan_rssi_monitoring_control { + QCA_WLAN_RSSI_MONITORING_CONTROL_INVALID = 0, + QCA_WLAN_RSSI_MONITORING_START, + QCA_WLAN_RSSI_MONITORING_STOP, +}; + +/** + * enum qca_wlan_vendor_attr_rssi_monitoring - rssi monitoring + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_INVALID: Invalid + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL: control + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI: max rssi + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI: min rssi + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID: current bssid + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI: current rssi + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST: after last + * @QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX: max + */ +enum qca_wlan_vendor_attr_rssi_monitoring { + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, + + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI, + + /* attributes to be used/received in callback */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX = + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST - 1, +}; + +#ifdef WLAN_FEATURE_OFFLOAD_PACKETS +/** + * enum wlan_offloaded_packets_control - control commands + * @WLAN_START_OFFLOADED_PACKETS: start offloaded packets + * @WLAN_STOP_OFFLOADED_PACKETS: stop offloaded packets + * + */ +enum wlan_offloaded_packets_control +{ + WLAN_START_OFFLOADED_PACKETS = 1, + WLAN_STOP_OFFLOADED_PACKETS = 2 +}; + +/** + * enum qca_wlan_vendor_attr_offloaded_packets - offloaded packets + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_INVALID: invalid + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL: control + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID: request id + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA: ip packet data + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR: src mac address + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR: destination mac address + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD: period in milli seconds + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST: after last + * @QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX: max + */ +enum qca_wlan_vendor_attr_offloaded_packets +{ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID, + + /* Packet in hex format */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX = + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST - 1, +}; +#endif + +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo + ); + +#ifdef FEATURE_WLAN_LFR +int wlan_hdd_cfg80211_pmksa_candidate_notify( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + int index, bool preauth ); +#endif + +#ifdef FEATURE_WLAN_LFR_METRICS +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo); + +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status); + +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo); +#endif + +#ifdef FEATURE_WLAN_WAPI +void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, + u8 key_index, const u8 *mac_addr, const u8 *key , int key_Len); +#endif +struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size); + +int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request); + +int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand); + +int wlan_hdd_cfg80211_init(struct device *dev, + struct wiphy *wiphy, + hdd_config_t *pCfg + ); + +int wlan_hdd_cfg80211_register( struct wiphy *wiphy); +void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter); + +void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter); +#ifdef CONFIG_ENABLE_LINUX_REG +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#else +int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#endif +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#else +int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +#endif +#endif + +extern v_VOID_t hdd_connSetConnectionState( hdd_station_ctx_t *pHddStaCtx, + eConnectionState connState ); +VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel); +#ifdef FEATURE_WLAN_TDLS +int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy, + struct net_device *dev, u8 *peer); +#endif +#ifdef WLAN_FEATURE_GTK_OFFLOAD +extern void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp); +#endif +void* wlan_hdd_change_country_code_cb(void *pAdapter); +void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel); + +v_U8_t* wlan_hdd_cfg80211_get_ie_ptr( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_U8_t *pIes, +#else + v_U8_t *pIes, +#endif + int length, v_U8_t eid); + +#ifdef FEATURE_WLAN_CH_AVOID +int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx, + tHddAvoidFreqList *pAvoidFreqList); +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_EXTSCAN +void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType, + void *pMsg); +#endif /* WLAN_FEATURE_EXTSCAN */ + +void hdd_rssi_threshold_breached_cb(void *hddctx, + struct rssi_breach_event *data); + +void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx); + +#ifdef FEATURE_OEM_DATA_SUPPORT +void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType, + void *pMsg, tANI_U32 evLen); +#endif /* FEATURE_OEM_DATA_SUPPORT */ + +#if !(defined (SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC)) +static inline struct sk_buff * +backported_cfg80211_vendor_event_alloc(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + struct wireless_dev *wdev, +#endif + int approxlen, + int event_idx, gfp_t gfp) +{ + return cfg80211_vendor_event_alloc(wiphy, approxlen, event_idx, gfp); +} +#define cfg80211_vendor_event_alloc backported_cfg80211_vendor_event_alloc +#endif + +/** + * enum qca_wlan_vendor_attr_memory_dump - values for memory dump attributes + * @QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_INVALID - Invalid + * @QCA_WLAN_VENDOR_ATTR_REQUEST_ID - Indicate request ID + * @QCA_WLAN_VENDOR_ATTR_MEMDUMP_SIZE - Indicate size of the memory dump + * @QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_AFTER_LAST - To keep track of the last enum + * @QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_MAX - max value possible for this type + * + * enum values are used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP sub command. + */ +enum qca_wlan_vendor_attr_memory_dump { + QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_REQUEST_ID = 1, + QCA_WLAN_VENDOR_ATTR_MEMDUMP_SIZE = 2, + + QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_MAX = + QCA_WLAN_VENDOR_ATTR_MEMORY_DUMP_AFTER_LAST - 1, +}; + +#if defined(CFG80211_DISCONNECTED_V2) || \ +(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) +static inline void wlan_hdd_cfg80211_indicate_disconnect(struct net_device *dev, + bool locally_generated, + int reason) +{ + cfg80211_disconnected(dev, reason, NULL, 0, + locally_generated, GFP_KERNEL); +} +#else +static inline void wlan_hdd_cfg80211_indicate_disconnect(struct net_device *dev, + bool locally_generated, + int reason) +{ + cfg80211_disconnected(dev, reason, NULL, 0, + GFP_KERNEL); +} +#endif + +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list( + hdd_adapter_t *pAdapter, tSirMacAddr bssid); + +struct cfg80211_bss *wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter, + tSirBssDescription *bss_desc); +#ifdef CFG80211_DEL_STA_V2 +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + struct station_del_parameters *param); +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) || defined(WITH_BACKPORTS) +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, const u8 *mac); +#else +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac); +#endif +#endif + +int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter); +int wlan_hdd_try_disconnect(hdd_adapter_t *pAdapter); +#endif diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_debugfs.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_debugfs.h new file mode 100644 index 000000000000..57cb046f3c79 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_debugfs.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_DEBUGFS_H +#define _WLAN_HDD_DEBUGFS_H + +#ifdef WLAN_OPEN_SOURCE +VOS_STATUS hdd_debugfs_init(hdd_adapter_t *pAdapter); +void hdd_debugfs_exit(hdd_context_t *pHddCtx); +#else +inline VOS_STATUS hdd_debugfs_init(hdd_adapter_t *pAdapter) +{ + return VOS_STATUS_SUCCESS; +} +inline void hdd_debugfs_exit(hdd_context_t *pHddCtx) +{ +} +#endif /* #ifdef WLAN_OPEN_SOURCE */ +#endif /* #ifndef _WLAN_HDD_DEBUGFS_H */ + diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dev_pwr.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dev_pwr.h new file mode 100644 index 000000000000..57bbc5957ff4 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dev_pwr.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_DEV_PWR_H +#define __WLAN_HDD_DEV_PWR_H + +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + + @brief Registration function. + Register suspend, resume callback functions with platform driver. + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddRegisterPmOps(hdd_context_t *pHddCtx); + +/*---------------------------------------------------------------------------- + + @brief De-registration function. + Deregister the suspend, resume callback functions with platform driver + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS De-Registration Success + VOS_STATUS_E_FAILURE De-Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDeregisterPmOps(hdd_context_t *pHddCtx); + +/*---------------------------------------------------------------------------- + + @brief TM Level Change handler + Received Tm Level changed notification + + @param dev : Device context + changedTmLevel : Changed new TM level + + @return + +----------------------------------------------------------------------------*/ +void hddDevTmLevelChangedHandler(struct device *dev, int changedTmLevel); + +/*---------------------------------------------------------------------------- + + @brief Register function + Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmRegisterNotifyCallback(hdd_context_t *pHddCtx); + +/*---------------------------------------------------------------------------- + + @brief Un-Register function + Un-Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Un-Registration Success + VOS_STATUS_E_FAILURE Un-Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmUnregisterNotifyCallback(hdd_context_t *pHddCtx); + +#endif diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dp_utils.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dp_utils.h new file mode 100644 index 000000000000..fb1ce32dbcc9 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_dp_utils.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_HDD_DP_UTILS_H ) +#define __WLAN_HDD_DP_UTILS_H + +/**============================================================================= + wlan_hdd_dp_utils.h + + \brief Utility functions for data path module + + ==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include + +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ + +typedef struct list_head hdd_list_node_t; + +typedef struct hdd_list_s +{ + hdd_list_node_t anchor; + v_SIZE_t count; + v_SIZE_t max_size; + int ratelimit_count; + spinlock_t lock; +} hdd_list_t; + +typedef struct +{ + hdd_list_node_t anchor; + struct sk_buff *skb; + int userPriority; +} skb_list_node_t; + +//FIXME Need a helper function to cleanup skbs in a queue. Required for cleanup/shutdown + +/**----------------------------------------------------------------------------- + Function declarations and documenation + ----------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t hdd_list_init( hdd_list_t *pList, v_SIZE_t max_size) +{ + INIT_LIST_HEAD( &pList->anchor ); + pList->count = 0; + pList->max_size = max_size; + spin_lock_init(&pList->lock); +} + +VOS_INLINE_FN v_VOID_t hdd_list_destroy( hdd_list_t *pList ) +{ + if ( pList->count !=0 ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: list length not equal to zero",__func__); + } +} + +VOS_INLINE_FN v_VOID_t hdd_list_size( hdd_list_t *pList, v_SIZE_t *pSize ) +{ + *pSize = pList->count; +} + +VOS_STATUS hdd_list_insert_front( hdd_list_t *pList, hdd_list_node_t *pNode ); + +VOS_STATUS hdd_list_insert_back( hdd_list_t *pList, hdd_list_node_t *pNode ); + +VOS_STATUS hdd_list_insert_back_size( hdd_list_t *pList, hdd_list_node_t *pNode, v_SIZE_t *pSize ); + +VOS_STATUS hdd_list_remove_front( hdd_list_t *pList, hdd_list_node_t **ppNode ); + +VOS_STATUS hdd_list_remove_back( hdd_list_t *pList, hdd_list_node_t **ppNode ); + +VOS_STATUS hdd_list_remove_node( hdd_list_t *pList, hdd_list_node_t *pNodeToRemove ); +VOS_STATUS hdd_list_peek_front( hdd_list_t *pList, hdd_list_node_t **ppNode ); +VOS_STATUS hdd_list_peek_next( hdd_list_t *pList, hdd_list_node_t *pNode, + hdd_list_node_t **ppNode ); +VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ); +#endif //__WLAN_HDD_DP_UTILS_H diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ether.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ether.h new file mode 100644 index 000000000000..1ea13c75fcf8 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ether.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_ETHER_H +#define _WLAN_HDD_ETHER_H +/*============================================================================ + @file wlan_hdd_ether.h + + This module describes Ethernet packet formats for processing by HDD. + +============================================================================*/ +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define WLAN_SNAP_OUI_LEN 3 +#define WLAN_SNAP_DSAP 0xAAU +#define WLAN_SNAP_SSAP 0xAAU +#define WLAN_SNAP_CTRL 0x03 +#define WLAN_MIN_PROTO 0x0600 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +struct wlan_snap_hdr { + unsigned char dsap; + unsigned char ssap; + unsigned char ctrl; + unsigned char oui[WLAN_SNAP_OUI_LEN]; +} __packed; + +struct wlan_8023 { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + __be16 h_len; + struct wlan_snap_hdr h_snap; + __be16 h_proto; +} __packed; + +struct wlan_8023_vlan { + unsigned char h_dest[ETH_ALEN]; + unsigned char h_source[ETH_ALEN]; + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + __be16 h_len; + struct wlan_snap_hdr h_snap; + __be16 h_proto; +} __packed; + +union generic_ethhdr { + struct ethhdr eth_II; + struct vlan_ethhdr eth_IIv; + struct wlan_8023 eth_8023; + struct wlan_8023_vlan eth_8023v; +}; + +#endif /* #ifndef _WLAN_HDD_ETHER_H */ diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ftm.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ftm.h new file mode 100644 index 000000000000..7c7fa9c05337 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_ftm.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_HDD_FTM_H +#define WLAN_HDD_FTM_H +#include "vos_status.h" +#include "vos_mq.h" +#include "vos_api.h" +#include "msg.h" +#include "halTypes.h" +#include "vos_types.h" +#include + +#define WLAN_FTM_SUCCESS 0 +#define WLAN_FTM_FAILURE 1 + +#define WLAN_FTM_START 1 +#define WLAN_FTM_STOP 2 +#define WLAN_FTM_CMD 3 + + +#define WLAN_FTM_PHY_CMD 100 +#define SIR_HAL_FTM_CMD 10 +#define QUALCOMM_MODULE_TYPE 2 +#define WLAN_FTM_COMMAND_TIME_OUT 10000 +#define PHYDBG_PREAMBLE_NOT_SUPPORTED 0xFF +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0) +#define WE_FTM_ON_OFF 1 +#define WE_TX_PKT_GEN 2 +#define WE_SET_TX_IFS 3 +#define WE_SET_TX_PKT_CNT 4 +#define WE_SET_TX_PKT_LEN 5 +#define WE_SET_CHANNEL 6 +#define WE_SET_TX_POWER 7 +#define WE_CLEAR_RX_PKT_CNT 8 +#define WE_RX 9 +#define WE_ENABLE_CHAIN 10 +#define WE_SET_PWR_CNTL_MODE 11 +#define WE_ENABLE_DPD 12 +#define WE_SET_CB 13 +#define WE_TX_CW_RF_GEN 14 +#define WE_SET_POWER_INDEX 15 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) +#define WE_GET_CHANNEL 1 +#define WE_GET_TX_POWER 2 +#define WE_GET_RX_PKT_CNT 3 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2) + +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3) +#define WE_SET_MAC_ADDRESS 1 +#define WE_SET_TX_RATE 2 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4) +#define WE_SET_WLAN_DBG 1 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5) +#define WE_GET_MAC_ADDRESS 1 +#define WE_GET_TX_RATE 2 +#define WE_GET_FTM_VERSION 3 +#define WE_GET_FTM_STATUS 4 +#define WE_GET_RX_RSSI 5 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_FTM_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6) +#define WE_SET_NV_DEFAULTS 1 + +#define WLAN_FTM_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7) +#define WE_SET_TX_WF_GAIN 1 +#define WE_SET_DUMP 2 + +#define WE_FTM_MAX_STR_LEN 1024 +#define MAX_FTM_VAR_ARGS 7 + +#define MAX_NV_TABLE_SIZE 40000 + +typedef enum { + WLAN_FTM_CMD_START = 1, + WLAN_FTM_CMD_STOP, + WLAN_FTM_CMD_CMD +} wlan_hdd_ftm_cmds; +typedef struct ftm_hdr_s { + v_U16_t cmd_id; + v_U16_t data_len; + v_U16_t respPktSize; +} ftm_hdr_t; + +/* The request buffer of FTM which contains a byte of command and the request */ +typedef struct wlan_hdd_ftm_payload_s { + v_U16_t ftm_cmd_type; + v_U8_t pFtmCmd[1]; +}wlan_hdd_ftm_payload; +#define SIZE_OF_FTM_DIAG_HEADER_LEN 12 +/* the FTM command/response structure */ +typedef struct wlan_hdd_ftm_request_s +{ + v_U8_t cmd_code; + v_U8_t sub_sys_id; + v_U16_t mode_id; + ftm_hdr_t ftm_hdr; + v_U16_t module_type; + wlan_hdd_ftm_payload ftmpkt; +}wlan_hdd_ftm_request_t; + +typedef struct wlan_hdd_ftm_response_s +{ + v_U8_t cmd_code; + v_U8_t sub_sys_id; + v_U16_t mode_id; + ftm_hdr_t ftm_hdr; + v_U16_t ftm_err_code; + wlan_hdd_ftm_payload ftmpkt; +}wlan_hdd_ftm_response_t; + +typedef enum { + WLAN_FTM_INITIALIZED, + WLAN_FTM_STOPPED, + WLAN_FTM_STARTED, + WLAN_FTM_STARTING, +} wlan_hdd_ftm_state; +typedef struct wlan_hdd_ftm_status_s +{ + v_U8_t ftm_state; + wlan_hdd_ftm_request_t *pRequestBuf; + wlan_hdd_ftm_response_t *pResponseBuf; + tAniNlHdr *wnl; + /**vos event */ + vos_event_t ftm_vos_event; + + /** completion variable for ftm command to complete*/ + struct completion ftm_comp_var; + v_BOOL_t IsCmdPending; + v_BOOL_t cmd_iwpriv; + + /** Large size of NV Table Handle **/ + eNvTable processingNVTable; + v_U32_t targetNVTableSize; + v_U8_t *targetNVTablePointer; + v_U32_t processedNVTableSize; + v_U8_t *tempNVTableBuffer; + struct completion startCmpVar; + +} wlan_hdd_ftm_status_t; +typedef struct ftm_msg_s +{ + /* This field can be used as sequence + number/dialogue token for matching request/response */ + v_U16_t type; + + /* This guy carries the command buffer along with command id */ + void *cmd_ptr; + v_U32_t bodyval; +} ftm_msg_t; +typedef struct ftm_rsp_msg_s +{ + v_U16_t msgId; + v_U16_t msgBodyLength; + v_U32_t respStatus; + v_U8_t *msgResponse; +} ftm_rsp_msg_t; + +typedef struct rateIndex2Preamble +{ + v_U16_t rate_index; + v_U16_t Preamble; +} rateIndex2Preamble_t; +typedef struct freq_chan_s +{ + v_U16_t freq; + v_U16_t chan; +} freq_chan_t; + +typedef struct rateStr2rateIndex_s +{ + v_U16_t rate_index; + char rate_str[30]; +} rateStr2rateIndex_t; + + +#define FTM_SWAP16(A) ((((tANI_U16)(A) & 0xff00) >> 8) | \ + (((tANI_U16)(A) & 0x00ff) << 8) \ + ) +#define PTT_HEADER_LENGTH 8 + +#define FTM_VOS_EVENT_WAIT_TIME 10000 + +#define SIZE_OF_TABLE(a) (sizeof(a) / sizeof(a[0])) + +int wlan_hdd_ftm_open(hdd_context_t *pHddCtx); +void wlan_hdd_process_ftm_cmd (hdd_context_t *pHddCtx,tAniNlHdr *wnl); +int wlan_hdd_ftm_close(hdd_context_t *pHddCtx); + +#endif diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_host_offload.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_host_offload.h new file mode 100644 index 000000000000..07d609b63dcb --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_host_offload.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_HOST_OFFLOAD_H__ +#define __WLAN_HDD_HOST_OFFLOAD_H__ + +/**=========================================================================== + + \file wlan_hdd_host_offload.h + + \brief Android WLAN HDD Host Offload API + + + ==========================================================================*/ + +/* Offload types. */ +#define WLAN_IPV4_ARP_REPLY_OFFLOAD 0 +#define WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 + +/* Enable or disable offload. */ +#define WLAN_OFFLOAD_DISABLE 0 +#define WLAN_OFFLOAD_ENABLE 0x1 +#define WLAN_OFFLOAD_BC_FILTER_ENABLE 0x2 +#define WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE (WLAN_OFFLOAD_ENABLE | WLAN_OFFLOAD_BC_FILTER_ENABLE) + +/* Offload request. */ +typedef struct +{ + v_U8_t offloadType; + v_U8_t enableOrDisable; + union + { + v_U8_t hostIpv4Addr [4]; + v_U8_t hostIpv6Addr [16]; + } params; + v_MACADDR_t bssId; +} tHostOffloadRequest, *tpHostOffloadRequest; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void hdd_wlan_offload_event(uint8_t type, uint8_t state); +#else +static inline +void hdd_wlan_offload_event(uint8_t type, uint8_t state) +{ + return; +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#endif // __WLAN_HDD_HOST_OFFLOAD_H__ + diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h new file mode 100644 index 000000000000..1c9aec962119 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_hostapd.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_HOSTAPD_H ) +#define WLAN_HDD_HOSTAPD_H + +/**=========================================================================== + + \file WLAN_HDD_HOSTAPD_H.h + + \brief Linux HDD HOSTAPD include file + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +#include +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +/* max length of command string in hostapd ioctl */ +#define HOSTAPD_IOCTL_COMMAND_STRLEN_MAX 8192 + +hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *name); + +VOS_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter, tANI_U8 rtnl_held); + +VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, tANI_U8 rtnl_held); + +eCsrAuthType +hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4]); + +eCsrEncryptionType +hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4]); + +eCsrEncryptionType +hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4]); + +eCsrAuthType +hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4]); + +eCsrEncryptionType +hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4]); + +VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t*, struct tagCsrDelStaParams*); +void hdd_softap_sta_disassoc(hdd_adapter_t*,v_U8_t*); +void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t*,v_BOOL_t); +int hdd_softap_unpackIE( tHalHandle halHandle, + eCsrEncryptionType *pEncryptType, + eCsrEncryptionType *mcEncryptType, + eCsrAuthType *pAuthType, + v_BOOL_t *pMFPCapable, + v_BOOL_t *pMFPRequired, + u_int16_t gen_ie_len, + u_int8_t *gen_ie ); + +/** + * hdd_change_ch_avoidance_status() - update is_ch_avoid_in_progress flag + * + * @hdd_ctx: pointer to hdd context + * @value: value to set + * + * This function will change the value of is_ch_avoid_in_progress + * + * Return: none + */ +static inline void +hdd_change_ch_avoidance_status(hdd_context_t *hdd_ctx, + bool value) +{ + vos_spin_lock_acquire(&hdd_ctx->sap_update_info_lock); + hdd_ctx->is_ch_avoid_in_progress = value; + vos_spin_lock_release(&hdd_ctx->sap_update_info_lock); +} + + +VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback); +VOS_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter, bool re_init); +void hdd_set_ap_ops( struct net_device *pWlanHostapdDev ); +int hdd_hostapd_stop (struct net_device *dev); +void hdd_restart_softap (hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter); +#ifdef FEATURE_WLAN_CH_AVOID +void hdd_hostapd_ch_avoid_cb(void *pAdapter, void *indParam); +#endif /* FEATURE_WLAN_CH_AVOID */ +int hdd_del_all_sta(hdd_adapter_t *pAdapter); +void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter); +void hdd_sap_destroy_timers(hdd_adapter_t *adapter); + +#ifdef SAP_AUTH_OFFLOAD +bool hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, + bool enabled); +#else +static inline bool +hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, bool enabled) +{ +} +#endif + +/** + * hdd_check_for_unsafe_ch() - Check the current operating channel with + * unsafe channel list. + * @phostapd_adapter : Pointer to HDD adapter. + * @hdd_ctx: pointer to hdd context. + * + * Check the current operating chennel of SAP with unsafe channel list + * and Restart the SAP on safe channel if currently SAP is + * on unsafe channel. + * + * Return : None + */ +void hdd_check_for_unsafe_ch(hdd_adapter_t *phostapd_adapter, + hdd_context_t *hdd_ctx); +void hdd_force_scc_restart_sap(hdd_adapter_t *adapter, + hdd_context_t *hdd_ctx, tANI_U8 channelId); + +#endif // end #if !defined( WLAN_HDD_HOSTAPD_H ) diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_includes.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_includes.h new file mode 100644 index 000000000000..e8d38031eb4c --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_includes.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( HDD_INCLUDES_H__ ) +#define HDD_INCLUDES_H__ + +/**=========================================================================== + + \file wlan_hdd_includes.h + + \brief Internal includes for the Linux HDD + + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +// throw all the includes in here f to get the .c files in the HDD to compile. + +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_dp_utils.h" +#include "wlan_hdd_mib.h" +#include "wlan_hdd_wext.h" +#include "wlan_hdd_main.h" +#include "wlan_hdd_tx_rx.h" + +#ifdef FEATURE_OEM_DATA_SUPPORT +/*include for oem data req specific structures*/ +/*and function declarations*/ +#include "wlan_hdd_oemdata.h" +#endif + +#endif // end #if !defined( HDD_INCLUDES_H__ ) diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_keep_alive.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_keep_alive.h new file mode 100644 index 000000000000..a3aff13c9558 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_keep_alive.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_KEEP_ALIVE_H__ +#define __WLAN_HDD_KEEP_ALIVE_H__ + +/**=========================================================================== + + \file wlan_hdd_keep_alive.h + + \brief Android WLAN HDD Keep-Alive API + + + ==========================================================================*/ + +/* Packet Types. */ +#define WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 +#define WLAN_KEEP_ALIVE_NULL_PKT 1 + +/* Enable or disable offload. */ +#define WLAN_KEEP_ALIVE_DISABLE 0 +#define WLAN_KEEP_ALIVE_ENABLE 0x1 + +/* Offload request. */ +typedef struct +{ + v_U8_t packetType; + v_U32_t timePeriod; + v_U8_t hostIpv4Addr[4]; + v_U8_t destIpv4Addr[4]; + v_U8_t destMacAddr [6]; + v_U8_t bssIdx; +} tKeepAliveRequest, *tpKeepAliveRequest; + +#endif // __WLAN_HDD_KEEP_ALIVE_H__ + diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h new file mode 100644 index 000000000000..4b9c5a7b9746 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_main.h @@ -0,0 +1,2229 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#if !defined( WLAN_HDD_MAIN_H ) +#define WLAN_HDD_MAIN_H +/**=========================================================================== + + \file WLAN_HDD_MAIN_H.h + + \brief Linux HDD Adapter Type + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include "sirMacProtDef.h" +#include "csrApi.h" +#include +#include +#include +#include +#include +#ifdef WLAN_OPEN_SOURCE +#include +#endif +#include +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif +#include "wlan_hdd_cfg80211.h" + +#include /* Necessary because we use the proc fs */ +#include +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +/** Number of attempts to detect/remove card */ +#define LIBRA_CARD_INSERT_DETECT_MAX_COUNT 5 +#define LIBRA_CARD_REMOVE_DETECT_MAX_COUNT 5 + +/** Number of Tx Queues. This should be same as the one + * used in TL WLANTL_NUM_TX_QUEUES */ +#define NUM_TX_QUEUES 5 + +/** HDD's internal Tx Queue Length. Needs to be a power of 2 */ +#define HDD_TX_QUEUE_MAX_LEN 128 +/** HDD internal Tx Queue Low Watermark. Net Device TX queue is disabled + * when HDD queue becomes full. This Low watermark is used to enable + * the Net Device queue again */ +#define HDD_TX_QUEUE_LOW_WATER_MARK (HDD_TX_QUEUE_MAX_LEN*3/4) +/** Bytes to reserve in the headroom */ +#define LIBRA_HW_NEEDED_HEADROOM 128 +/** Hdd Tx Time out value */ +#ifdef LIBRA_LINUX_PC +#define HDD_TX_TIMEOUT (8000) +#else +#define HDD_TX_TIMEOUT msecs_to_jiffies(5000) +#endif +/** Hdd Default MTU */ +#define HDD_DEFAULT_MTU (1500) + +/**event flags registered net device*/ +#define NET_DEVICE_REGISTERED (0) +#define SME_SESSION_OPENED (1) +#define INIT_TX_RX_SUCCESS (2) +#define WMM_INIT_DONE (3) +#define SOFTAP_BSS_STARTED (4) +#define DEVICE_IFACE_OPENED (5) +#define TDLS_INIT_DONE (6) +#define SOFTAP_INIT_DONE (7) + +/** Maximum time(ms)to wait for disconnect to complete **/ +#define WLAN_WAIT_TIME_DISCONNECT 5000 +#define WLAN_WAIT_TIME_STATS 800 +#define WLAN_WAIT_TIME_POWER 5000 +#define WLAN_WAIT_TIME_COUNTRY 1000 +#define WLAN_WAIT_TIME_CHANNEL_UPDATE 600 +#define FW_STATE_WAIT_TIME 500 +#define FW_STATE_RSP_LEN 100 + +/* Amount of time to wait for sme close session callback. + This value should be larger than the timeout used by WDI to wait for + a response from WCNSS */ +#define WLAN_WAIT_TIME_SESSIONOPENCLOSE 15000 +#define WLAN_WAIT_TIME_ABORTSCAN 2000 + +/** Maximum time(ms) to wait for tdls add sta to complete **/ +#define WAIT_TIME_TDLS_ADD_STA 1500 + +/** Maximum time(ms) to wait for tdls del sta to complete **/ +#define WAIT_TIME_TDLS_DEL_STA 1500 + +/** Maximum time(ms) to wait for Link Establish Req to complete **/ +#define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 + +/** Maximum time(ms) to wait for tdls mgmt to complete **/ +#define WAIT_TIME_TDLS_MGMT 11000 + +/** Maximum time(ms) to wait for tdls initiator to start direct communication **/ +#define WAIT_TIME_TDLS_INITIATOR 600 + +/**Maximum time(ms) to wait for clear packet req to complete **/ +#define PKT_FILTER_TIMEOUT 300 + +/* Maximum time to get linux regulatory entry settings */ +#ifdef CONFIG_ENABLE_LINUX_REG +#define LINUX_REG_WAIT_TIME 300 +#else +#define CRDA_WAIT_TIME 300 +#endif + +#define WAIT_TIME_FW_LOGS 2000 +/* Scan Req Timeout */ +#define WLAN_WAIT_TIME_SCAN_REQ 100 + +#define MAX_NUMBER_OF_ADAPTERS 4 + +#define MAX_CFG_STRING_LEN 255 + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +/** Mac Address string **/ +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ADDRESS_STR_LEN 18 /* Including null terminator */ +#define MAX_GENIE_LEN 255 + +#define WLAN_CHIP_VERSION "WCNSS" + +#define hddLog(level, args...) VOS_TRACE( VOS_MODULE_ID_HDD, level, ## args) +#define ENTER() VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__) +#define EXIT() VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Exit:%s", __func__) +#define ENTER_DEV(dev) VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Enter:%s dev_name: %s", __func__, (dev)->name) + +#define WLAN_HDD_GET_PRIV_PTR(__dev__) (hdd_adapter_t*)(netdev_priv((__dev__))) + +#define MAX_EXIT_ATTEMPTS_DURING_LOGP 20 + +#define MAX_NO_OF_2_4_CHANNELS 14 + +#define WLAN_HDD_PUBLIC_ACTION_FRAME 4 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET 24 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET 24 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET 30 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET 0 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET 1 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET 2 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET 5 +#define WLAN_HDD_VENDOR_SPECIFIC_ACTION 0x09 +#define WLAN_HDD_WFA_OUI 0x506F9A +#define WLAN_HDD_WFA_P2P_OUI_TYPE 0x09 +#define WLAN_HDD_P2P_SOCIAL_CHANNELS 3 +#define WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN 1 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET 6 + +#define WLAN_HDD_IS_SOCIAL_CHANNEL(center_freq) \ +(((center_freq) == 2412) || ((center_freq) == 2437) || ((center_freq) == 2462)) + +#define WLAN_HDD_CHANNEL_IN_UNII_1_BAND(center_freq) \ +(((center_freq) == 5180 ) || ((center_freq) == 5200) \ +|| ((center_freq) == 5220) || ((center_freq) == 5240)) + +#ifdef WLAN_FEATURE_11W +#define WLAN_HDD_SA_QUERY_ACTION_FRAME 8 +#endif + +#define WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP 14 +#define WLAN_HDD_TDLS_ACTION_FRAME 12 +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK +#define HDD_WAKE_LOCK_DURATION 50 //in msecs +#endif + +#define WLAN_HDD_QOS_ACTION_FRAME 1 +#define WLAN_HDD_QOS_MAP_CONFIGURE 4 +#define HDD_SAP_WAKE_LOCK_DURATION 10000 //in msecs + +#define HDD_MOD_EXIT_SSR_MAX_RETRIES 30 + +/* Maximum number of interfaces allowed(STA, P2P Device, P2P Interface) */ +#define WLAN_MAX_INTERFACES 3 + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define GTK_OFFLOAD_ENABLE 0 +#define GTK_OFFLOAD_DISABLE 1 +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +#define HDD_PNO_SCAN_TIMERS_SET_ONE 1 +/* value should not be greater than PNO_MAX_SCAN_TIMERS */ +#define HDD_PNO_SCAN_TIMERS_SET_MULTIPLE 6 +#define WLAN_WAIT_TIME_PNO 2000 +#endif + +#define MAX_USER_COMMAND_SIZE 4096 + +#define HDD_MAC_ADDR_LEN 6 +typedef v_U8_t tWlanHddMacAddr[HDD_MAC_ADDR_LEN]; + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define HDD_BATCH_SCAN_VERSION (17) +#define HDD_SET_BATCH_SCAN_DEFAULT_FREQ (30)/*batch scan frequency default 30s*/ +#define HDD_SET_BATCH_SCAN_BEST_NETWORK (16)/*best network default value*/ +#define HDD_SET_BATCH_SCAN_DEFAULT_BAND (0)/*auto means both 2.4GHz and 5GHz*/ +#define HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY (1)/*only 2.4GHz band*/ +#define HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY (2)/*only 5GHz band*/ +#define HDD_SET_BATCH_SCAN_REQ_TIME_OUT (15000) /*Batch scan req timeout in ms*/ +#define HDD_GET_BATCH_SCAN_RSP_TIME_OUT (15000) /*Batch scan req timeout in ms*/ +#define HDD_BATCH_SCAN_AP_META_INFO_SIZE (150) /*AP meta info size in string*/ + +#define MIN(a, b) (a > b ? b : a) + +#endif +#define SCAN_REJECT_THRESHOLD_TIME 300000 /* Time is in msec, equal to 5 mins */ +#define SCAN_REJECT_THRESHOLD 15 + + +#define WLAN_WAIT_TIME_EXTSCAN 1000 + +#define HDD_MAX_STA_COUNT (HAL_NUM_STA) + +#ifdef MDNS_OFFLOAD +#define MDNS_HEADER_LEN 12 +#define MDNS_FQDN_TYPE_GENERAL 0 +#define MDNS_FQDN_TYPE_UNIQUE 1 +#define MAX_NUM_FIELD_DOMAINNAME 6 +#define MAX_LEN_DOMAINNAME_FIELD 64 +#define MAX_MDNS_RESP_TYPE 6 +#define MDNS_TYPE_A 1 +#define MDNS_TYPE_TXT 16 +#define MDNS_TYPE_PTR 12 +#define MDNS_TYPE_PTR_DNAME 13 +#define MDNS_TYPE_SRV 33 +#define MDNS_TYPE_SRV_TARGET 34 +#define MDNS_CLASS 1 +#define MDNS_TTL 5 +#endif /* MDNS_OFFLOAD */ + +#define HDD_MIN_TX_POWER (-100) /* minimum tx power */ +#define HDD_MAX_TX_POWER (+100) /* maximum tx power */ +/* + * Generic asynchronous request/response support + * + * Many of the APIs supported by HDD require a call to SME to + * perform an action or to retrieve some data. In most cases SME + * performs the operation asynchronously, and will execute a provided + * callback function when the request has completed. In order to + * synchronize this the HDD API allocates a context which is then + * passed to SME, and which is then, in turn, passed back to the + * callback function when the operation completes. The callback + * function then sets a completion variable inside the context which + * the HDD API is waiting on. In an ideal world the HDD API would + * wait forever (or at least for a long time) for the response to be + * received and for the completion variable to be set. However in + * most cases these HDD APIs are being invoked in the context of a + * userspace thread which has invoked either a cfg80211 API or a + * wireless extensions ioctl and which has taken the kernel rtnl_lock. + * Since this lock is used to synchronize many of the kernel tasks, we + * do not want to hold it for a long time. In addition we do not want + * to block userspace threads (such as the wpa supplicant's main + * thread) for an extended time. Therefore we only block for a short + * time waiting for the response before we timeout. This means that + * it is possible for the HDD API to timeout, and for the callback to + * be invoked afterwards. In order for the callback function to + * determine if the HDD API is still waiting, a magic value is also + * stored in the shared context. Only if the context has a valid + * magic will the callback routine do any work. In order to further + * synchronize these activities a spinlock is used so that if any HDD + * API timeout coincides with its callback, the operations of the two + * threads will be serialized. + */ + +struct statsContext +{ + struct completion completion; + hdd_adapter_t *pAdapter; + unsigned int magic; +}; + +struct getFrameLogCtx +{ + struct completion completion; + hdd_adapter_t *pAdapter; + unsigned int magic; +}; + +extern spinlock_t hdd_context_lock; + +#define STATS_CONTEXT_MAGIC 0x53544154 //STAT +#define RSSI_CONTEXT_MAGIC 0x52535349 //RSSI +#define POWER_CONTEXT_MAGIC 0x504F5752 //POWR +#define SNR_CONTEXT_MAGIC 0x534E5200 //SNR +#define BCN_MISS_RATE_CONTEXT_MAGIC 0x513F5753 +#define FW_STATS_CONTEXT_MAGIC 0x5022474E //FW STATS +#define GET_FRAME_LOG_MAGIC 0x464c4f47 //FLOG +#define MON_MODE_MSG_MAGIC 0x51436B3A //MON_MODE +#define ANTENNA_CONTEXT_MAGIC 0x414E544E //ANTN +#define CLEAR_FILTER_MAGIC 0x52349732 //CLEAR FILTER +#define MON_MODE_MSG_TIMEOUT 5000 +#define MON_MODE_START 1 +#define MON_MODE_STOP 0 + +/* + * Driver miracast parameters 0-Disabled + * 1-Source, 2-Sink + */ +#define WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL 0 +#define WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL 2 + +typedef struct hdd_tx_rx_stats_s +{ + // start_xmit stats + __u32 txXmitCalled; + __u32 txXmitDropped; + __u32 txXmitBackPressured; + __u32 txXmitQueued; + __u32 txXmitClassifiedAC[NUM_TX_QUEUES]; + __u32 txXmitDroppedAC[NUM_TX_QUEUES]; + __u32 txXmitBackPressuredAC[NUM_TX_QUEUES]; + __u32 txXmitQueuedAC[NUM_TX_QUEUES]; + // fetch_cbk stats + __u32 txFetched; + __u32 txFetchedAC[NUM_TX_QUEUES]; + __u32 txFetchEmpty; + __u32 txFetchLowResources; + __u32 txFetchDequeueError; + __u32 txFetchDequeued; + __u32 txFetchDequeuedAC[NUM_TX_QUEUES]; + __u32 txFetchDePressured; + __u32 txFetchDePressuredAC[NUM_TX_QUEUES]; + // complete_cbk_stats + __u32 txCompleted; + // flush stats + __u32 txFlushed; + __u32 txFlushedAC[NUM_TX_QUEUES]; + // Deque depressure stats + __u32 txDequeDePressured; + __u32 txDequeDePressuredAC[NUM_TX_QUEUES]; + // rx stats + __u32 rxChains; + __u32 rxPackets; + __u32 rxDropped; + __u32 rxDelivered; + __u32 rxRefused; + __u32 pkt_tx_count; //TX pkt Counter used for dynamic splitscan + __u32 pkt_rx_count; //RX pkt Counter used for dynamic splitscan +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + __u32 txMcast[WIFI_AC_MAX]; +#endif + // tx timeout stats + __u32 txTimeoutCount; + __u32 continuousTxTimeoutCount; + v_ULONG_t jiffiesLastTxTimeOut;//Store time when last txtime out occur +} hdd_tx_rx_stats_t; + +typedef struct hdd_chip_reset_stats_s +{ + __u32 totalLogpResets; + __u32 totalCMD53Failures; + __u32 totalMutexReadFailures; + __u32 totalMIFErrorFailures; + __u32 totalFWHearbeatFailures; + __u32 totalUnknownExceptions; +} hdd_chip_reset_stats_t; + +#ifdef WLAN_FEATURE_11W +typedef struct hdd_pmf_stats_s +{ + uint8 numUnprotDeauthRx; + uint8 numUnprotDisassocRx; +} hdd_pmf_stats_t; +#endif + +typedef enum +{ + HDD_TX_FRAME_IN_NOT_ASSOCIATED_STATE = 0, + HDD_VOS_PACKET_RETURNED_BY_VOSS_IS_NULL, + HDD_WLANTL_STAPKTPENDING_RETURNED_ERROR_CODE, + HDD_INSERT_TX_QUEUE_FAILED, + HDD_FAILED_TO_SIGNAL_TL, + HDD_ERROR_ATTACHING_SKB, + HDD_FAILURE_EXTRACTING_SKB_FROM_VOS_PKT, + HDD_FAILURE_WALKING_PACKET_CHAIN, + HDD_STA_RX_ARP_PACKET_REFUSED_IN_NET_STACK +} HDD_PACKET_DROP_CAUSE; + +typedef struct hdd_arp_stats_s +{ + uint16 txCount; + uint16 rxCount; + uint16 txDropped; + uint16 rxDropped; + uint16 rxDelivered; + uint16 rxRefused; + uint16 tx_host_fw_sent; + uint16 rx_host_drop_reorder; + uint16_t tx_fw_cnt; + uint16_t rx_fw_cnt; + uint16_t tx_ack_cnt; + HDD_PACKET_DROP_CAUSE reason; +} hdd_arp_stats_t; + +typedef struct hdd_stats_s +{ + tCsrSummaryStatsInfo summary_stat; + tCsrGlobalClassAStatsInfo ClassA_stat; + tCsrGlobalClassBStatsInfo ClassB_stat; + tCsrGlobalClassCStatsInfo ClassC_stat; + tCsrGlobalClassDStatsInfo ClassD_stat; + tCsrPerStaStatsInfo perStaStats; + hdd_tx_rx_stats_t hddTxRxStats; + hdd_chip_reset_stats_t hddChipResetStats; + hdd_arp_stats_t hddArpStats; +#ifdef WLAN_FEATURE_11W + hdd_pmf_stats_t hddPmfStats; +#endif +} hdd_stats_t; + +typedef enum +{ + HDD_ROAM_STATE_NONE, + + // Issuing a disconnect due to transition into low power states. + HDD_ROAM_STATE_DISCONNECTING_POWER, + + // move to this state when HDD sets a key with SME/CSR. Note this is + // an important state to get right because we will get calls into our SME + // callback routine for SetKey activity that we did not initiate! + HDD_ROAM_STATE_SETTING_KEY, +} HDD_ROAM_STATE; + +typedef enum +{ + eHDD_SUSPEND_NONE = 0, + eHDD_SUSPEND_DEEP_SLEEP, + eHDD_SUSPEND_STANDBY, +} hdd_ps_state_t; + +typedef struct roaming_info_s +{ + HDD_ROAM_STATE roamingState; + vos_event_t roamingEvent; + + tWlanHddMacAddr bssid; + tWlanHddMacAddr peerMac; + tANI_U32 roamId; + eRoamCmdStatus roamStatus; + v_BOOL_t deferKeyComplete; + +} roaming_info_t; + +#ifdef FEATURE_WLAN_WAPI +/* Define WAPI macros for Length, BKID count etc*/ +#define MAX_WPI_KEY_LENGTH 16 +#define MAX_NUM_PN 16 +#define MAC_ADDR_LEN 6 +#define MAX_ADDR_INDEX 12 +#define MAX_NUM_AKM_SUITES 16 +#define MAX_NUM_UNI_SUITES 16 +#define MAX_NUM_BKIDS 16 + +/** WAPI AUTH mode definition */ +enum _WAPIAuthMode +{ + WAPI_AUTH_MODE_OPEN = 0, + WAPI_AUTH_MODE_PSK = 1, + WAPI_AUTH_MODE_CERT +} __packed; +typedef enum _WAPIAuthMode WAPIAuthMode; + +/** WAPI Work mode structure definition */ +#define WZC_ORIGINAL 0 +#define WAPI_EXTENTION 1 + +struct _WAPI_FUNCTION_MODE +{ + unsigned char wapiMode; +}__packed; + +typedef struct _WAPI_FUNCTION_MODE WAPI_FUNCTION_MODE; + +typedef struct _WAPI_BKID +{ + v_U8_t bkid[16]; +}WAPI_BKID, *pWAPI_BKID; + +/** WAPI Association information structure definition */ +struct _WAPI_AssocInfo +{ + v_U8_t elementID; + v_U8_t length; + v_U16_t version; + v_U16_t akmSuiteCount; + v_U32_t akmSuite[MAX_NUM_AKM_SUITES]; + v_U16_t unicastSuiteCount; + v_U32_t unicastSuite[MAX_NUM_UNI_SUITES]; + v_U32_t multicastSuite; + v_U16_t wapiCability; + v_U16_t bkidCount; + WAPI_BKID bkidList[MAX_NUM_BKIDS]; +} __packed; + +typedef struct _WAPI_AssocInfo WAPI_AssocInfo; +typedef struct _WAPI_AssocInfo *pWAPI_IEAssocInfo; + +/** WAPI KEY Type definition */ +enum _WAPIKeyType +{ + PAIRWISE_KEY, //0 + GROUP_KEY //1 +}__packed; +typedef enum _WAPIKeyType WAPIKeyType; + +/** WAPI KEY Direction definition */ +enum _KEY_DIRECTION +{ + None, + Rx, + Tx, + Rx_Tx +}__packed; + +typedef enum _KEY_DIRECTION WAPI_KEY_DIRECTION; + +/** WAPI KEY stucture definition */ +struct WLAN_WAPI_KEY +{ + WAPIKeyType keyType; + WAPI_KEY_DIRECTION keyDirection; /*reserved for future use*/ + v_U8_t keyId; + v_U8_t addrIndex[MAX_ADDR_INDEX]; /*reserved for future use*/ + int wpiekLen; + v_U8_t wpiek[MAX_WPI_KEY_LENGTH]; + int wpickLen; + v_U8_t wpick[MAX_WPI_KEY_LENGTH]; + v_U8_t pn[MAX_NUM_PN]; /*reserved for future use*/ +}__packed; + +typedef struct WLAN_WAPI_KEY WLAN_WAPI_KEY; +typedef struct WLAN_WAPI_KEY *pWLAN_WAPI_KEY; + +#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define WPA_GET_BE24(a) ((u32) ( (a[0] << 16) | (a[1] << 8) | a[2])) +#define WLAN_EID_WAPI 68 +#define WAPI_PSK_AKM_SUITE 0x02721400 +#define WAPI_CERT_AKM_SUITE 0x01721400 + +/** WAPI BKID List stucture definition */ +struct _WLAN_BKID_LIST +{ + v_U32_t length; + v_U32_t BKIDCount; + WAPI_BKID BKID[1]; +}__packed; + +typedef struct _WLAN_BKID_LIST WLAN_BKID_LIST; +typedef struct _WLAN_BKID_LIST *pWLAN_BKID_LIST; + + +/** WAPI Information stucture definition */ +struct hdd_wapi_info_s +{ + v_U32_t nWapiMode; + v_BOOL_t fIsWapiSta; + v_MACADDR_t cachedMacAddr; + v_UCHAR_t wapiAuthMode; +}__packed; +typedef struct hdd_wapi_info_s hdd_wapi_info_t; +#endif /* FEATURE_WLAN_WAPI */ + +typedef struct beacon_data_s { + u8 *head; + u8 *tail; + u8 *proberesp_ies; + u8 *assocresp_ies; + int head_len; + int tail_len; + int proberesp_ies_len; + int assocresp_ies_len; + int dtim_period; +} beacon_data_t; + +typedef enum device_mode +{ /* MAINTAIN 1 - 1 CORRESPONDENCE WITH tVOS_CON_MODE*/ + WLAN_HDD_INFRA_STATION, + WLAN_HDD_SOFTAP, + WLAN_HDD_P2P_CLIENT, + WLAN_HDD_P2P_GO, + WLAN_HDD_MONITOR, + WLAN_HDD_FTM, + WLAN_HDD_IBSS, + WLAN_HDD_P2P_DEVICE +}device_mode_t; + +typedef enum rem_on_channel_request_type +{ + REMAIN_ON_CHANNEL_REQUEST, + OFF_CHANNEL_ACTION_TX, +}rem_on_channel_request_type_t; + +/* Thermal mitigation Level Enum Type */ +typedef enum +{ + WLAN_HDD_TM_LEVEL_0, + WLAN_HDD_TM_LEVEL_1, + WLAN_HDD_TM_LEVEL_2, + WLAN_HDD_TM_LEVEL_3, + WLAN_HDD_TM_LEVEL_4, + WLAN_HDD_TM_LEVEL_MAX +} WLAN_TmLevelEnumType; + +typedef enum +{ + WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS = 0 , + WLAN_HDD_LOAD_IN_PROGRESS = 1<<0, + WLAN_HDD_UNLOAD_IN_PROGRESS = 1<<1, +}load_unload_sequence; + +/* Driver Action based on thermal mitigation level structure */ +typedef struct +{ + v_BOOL_t ampduEnable; + v_BOOL_t enterImps; + v_U32_t txSleepDuration; + v_U32_t txOperationDuration; + v_U32_t txBlockFrameCountThreshold; +} hdd_tmLevelAction_t; + +/* Thermal Mitigation control context structure */ +typedef struct +{ + WLAN_TmLevelEnumType currentTmLevel; + hdd_tmLevelAction_t tmAction; + vos_timer_t txSleepTimer; + struct mutex tmOperationLock; + vos_event_t setTmDoneEvent; + v_U32_t txFrameCount; + v_TIME_t lastblockTs; + v_TIME_t lastOpenTs; + struct netdev_queue *blockedQueue; + v_BOOL_t qBlocked; +} hdd_thermal_mitigation_info_t; +typedef struct action_pkt_buffer +{ + tANI_U8* frame_ptr; + tANI_U32 frame_length; + tANI_U16 freq; +}action_pkt_buffer_t; + +typedef struct hdd_remain_on_chan_ctx +{ + struct net_device *dev; + struct ieee80211_channel chan; + enum nl80211_channel_type chan_type; + unsigned int duration; + u64 cookie; + rem_on_channel_request_type_t rem_on_chan_request; + vos_timer_t hdd_remain_on_chan_timer; + action_pkt_buffer_t action_pkt_buff; + v_U32_t hdd_remain_on_chan_cancel_in_progress; + tANI_BOOLEAN is_pending_roc_cancelled; +}hdd_remain_on_chan_ctx_t; + +typedef enum{ + HDD_IDLE, + HDD_PD_REQ_ACK_PENDING, + HDD_GO_NEG_REQ_ACK_PENDING, + HDD_INVALID_STATE, +}eP2PActionFrameState; + +typedef enum { + WLAN_HDD_GO_NEG_REQ, + WLAN_HDD_GO_NEG_RESP, + WLAN_HDD_GO_NEG_CNF, + WLAN_HDD_INVITATION_REQ, + WLAN_HDD_INVITATION_RESP, + WLAN_HDD_DEV_DIS_REQ, + WLAN_HDD_DEV_DIS_RESP, + WLAN_HDD_PROV_DIS_REQ, + WLAN_HDD_PROV_DIS_RESP, + WLAN_HDD_ACTION_FRM_TYPE_MAX = 255, +}tActionFrmType; + +typedef struct hdd_cfg80211_state_s +{ + tANI_U16 current_freq; + u64 action_cookie; + tANI_U8 *buf; + size_t len; + struct sk_buff *skb; + hdd_remain_on_chan_ctx_t* remain_on_chan_ctx; + eP2PActionFrameState actionFrmState; + /*is_go_neg_ack_received flag is set to 1 when the + pending ack for GO negotiation req is received*/ + v_BOOL_t is_go_neg_ack_received; +}hdd_cfg80211_state_t; + + +typedef enum{ + HDD_SSR_NOT_REQUIRED, + HDD_SSR_REQUIRED, + HDD_SSR_DISABLED, +}e_hdd_ssr_required; + +/*--------------------------------------------------------------------------- + hdd_ibss_peer_info_params_t +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t staIdx; //StaIdx + v_U32_t txRate; //Current Tx Rate + v_U32_t mcsIndex; //MCS Index + v_U32_t txRateFlags; //TxRate Flags + v_S7_t rssi; //RSSI +}hdd_ibss_peer_info_params_t; + +typedef struct { + /** The station entry is used or not */ + v_BOOL_t isUsed; + + /** Station ID reported back from HAL. Broadcast + * uses station ID zero by default. */ + v_U8_t ucSTAId; + + /** MAC address of the station */ + v_MACADDR_t macAddrSTA; + + /** Current Station state so HDD knows how to deal with packet + * queue. Most recent states used to change TL STA state. */ + WLANTL_STAStateType tlSTAState; + + /** Transmit queues for each AC (VO,VI,BE etc). */ + hdd_list_t wmm_tx_queue[NUM_TX_QUEUES]; + + /** Might need to differentiate queue depth in contention case */ + v_U16_t aTxQueueDepth[NUM_TX_QUEUES]; + + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t txSuspended[NUM_TX_QUEUES]; + + /** Track QoS status of station */ + v_BOOL_t isQosEnabled; + + /** The station entry for which Deauth is in progress */ + v_BOOL_t isDeauthInProgress; + +} hdd_ibss_station_info_t; + +typedef struct +{ + /** Request status */ + v_U32_t status; + + /** Number of peers */ + v_U8_t numIBSSPeers; + + /* IBSS Station table */ + hdd_ibss_station_info_t ibssStaInfo[HDD_MAX_NUM_IBSS_STA]; + + /** Peer Info parameters */ + hdd_ibss_peer_info_params_t ibssPeerList[HDD_MAX_NUM_IBSS_STA]; +}hdd_ibss_peer_info_t; + +struct hdd_station_ctx +{ + /** Handle to the Wireless Extension State */ + hdd_wext_state_t WextState; + +#ifdef FEATURE_WLAN_TDLS + tdlsCtx_t *pHddTdlsCtx; +#endif + + + /**Connection information*/ + connection_info_t conn_info; + + roaming_info_t roam_info; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + int ft_carrier_on; +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + tSirGtkOffloadParams gtkOffloadReqParams; +#endif + /*Increment whenever ibss New peer joins and departs the network */ + int ibss_sta_generation; + + /*Save the wep/wpa-none keys*/ + tCsrRoamSetKey ibss_enc_key; + hdd_ibss_peer_info_t ibss_peer_info; + + v_BOOL_t hdd_ReassocScenario; + v_BOOL_t get_mgmt_log_sent; + +}; + +#define BSS_STOP 0 +#define BSS_START 1 +typedef struct hdd_hostapd_state_s +{ + int bssState; + vos_event_t vosEvent; + VOS_STATUS vosStatus; + v_BOOL_t bCommit; + +} hdd_hostapd_state_t; + +#ifdef DHCP_SERVER_OFFLOAD +typedef struct hdd_dhcp_state_s +{ + VOS_STATUS dhcp_offload_status; + vos_event_t vos_event; +} hdd_dhcp_state_t; +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +typedef struct hdd_mdns_state_s +{ + VOS_STATUS mdns_enable_status; + VOS_STATUS mdns_fqdn_status; + VOS_STATUS mdns_resp_status; + vos_event_t vos_event; +} hdd_mdns_state_t; +#endif /* MDNS_OFFLOAD */ + +#ifdef WLAN_FEATURE_TSF + +#define HDD_TSF_CAP_REQ_TIMEOUT 2000 +#define HDD_TSF_GET_REQ_TIMEOUT 2000 + +/** + * enum hdd_tsf_get_state - status of get tsf action + * + * TSF_RETURN: get tsf + * TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap + * TSF_NOT_RETURNED_BY_FW: fw not returned tsf + * TSF_CURRENT_IN_CAP_STATE: driver in capture state + * TSF_CAPTURE_FAIL: capture fail + * TSF_GET_FAIL: get fail + * TSF_RESET_GPIO_FAIL: GPIO reset fail + * TSF_SAP_NOT_STARTED_NO_TSF SAP not started + */ +enum hdd_tsf_get_state { + TSF_RETURN = 0, + TSF_STA_NOT_CONNECTED_NO_TSF, + TSF_NOT_RETURNED_BY_FW, + TSF_CURRENT_IN_CAP_STATE, + TSF_CAPTURE_FAIL, + TSF_GET_FAIL, + TSF_RESET_GPIO_FAIL, + TSF_SAP_NOT_STARTED_NO_TSF +}; + +/** + * enum hdd_tsf_capture_state - status of capture + * + * TSF_IDLE: idle + * TSF__CAP_STATE: current is in capture state + */ +enum hdd_tsf_capture_state { + TSF_IDLE = 0, + TSF_CAP_STATE +}; + +/** + * struct hdd_tsf_ctx_s - TSF capture ctx + * @tsf_get_state : tsf action enum + * @tsf_capture_state: tsf capture state enum + * @tsf_capture_done_event : Indicate tsf completion + * @tsf_high : Higher 32-bit for 64-bit tsf + * @tsf_lo : Lower 32-bit for 64-bit tsf + * + */ +struct hdd_tsf_ctx_s { + enum hdd_tsf_get_state tsf_get_state; + enum hdd_tsf_capture_state tsf_capture_state; + vos_event_t tsf_capture_done_event; + vos_spin_lock_t tsf_lock; + uint32_t tsf_high; + uint32_t tsf_low; +}; + +#endif /* WLAN_FEATURE_TSF */ +/* + * Per station structure kept in HDD for multiple station support for SoftAP +*/ + +struct hdd_ap_ctx_s +{ + hdd_hostapd_state_t HostapdState; + + // Memory differentiation mode is enabled + //v_U16_t uMemoryDiffThreshold; + //v_U8_t uNumActiveAC; + //v_U8_t uActiveACMask; + //v_U8_t aTxQueueLimit[NUM_TX_QUEUES]; + + /** Packet Count to update uNumActiveAC and uActiveACMask */ + //v_U16_t uUpdatePktCount; + + /** Station ID assigned after BSS starts */ + v_U8_t uBCStaId; + + v_U8_t uPrivacy; // The privacy bits of configuration + + tSirWPSPBCProbeReq WPSPBCProbeReq; + + tsap_Config_t sapConfig; + + struct semaphore semWpsPBCOverlapInd; + + v_BOOL_t apDisableIntraBssFwd; + + vos_timer_t hdd_ap_inactivity_timer; + + v_U8_t operatingChannel; + + v_BOOL_t uIsAuthenticated; + + eCsrEncryptionType ucEncryptType; + + //This will point to group key data, if it is received before start bss. + tCsrRoamSetKey groupKey; + // This will have WEP key data, if it is received before start bss + tCsrRoamSetKey wepKey[CSR_MAX_NUM_KEY]; + + beacon_data_t *beacon; +}; + +#define NUM_FILTERS_SUPPORTED 1 +struct filter +{ + v_MACADDR_t macAddr; + v_BOOL_t isA1filter; + v_BOOL_t isA2filter; + v_BOOL_t isA3filter; +}; + +struct hdd_mon_ctx_s +{ + /* start or stop */ + v_BOOL_t state; + /*Conversion of packet required or not*/ + v_BOOL_t is80211to803ConReq; + v_U32_t ChannelNo; + v_U32_t ChannelBW; + v_BOOL_t crcCheckEnabled; + v_U8_t numOfMacFilters; + struct filter mmFilters[NUM_FILTERS_SUPPORTED]; + v_U64_t typeSubtypeBitmap; + v_U64_t rsvd; +}; + +typedef struct hdd_scaninfo_s +{ + /* The scan id */ + v_U32_t scanId; + + /* The scan pending */ + v_U32_t mScanPending; + + /* Counter for mScanPending so that the scan pending + error log is not printed for more than 5 times */ + v_U32_t mScanPendingCounter; + + /* Client Wait Scan Result */ + v_U32_t waitScanResult; + + /* Additional IE for scan */ + tSirAddie scanAddIE; + + /* Scan mode*/ + tSirScanType scan_mode; + + /* Scan Completion Event */ + struct completion scan_req_completion_event; + + /* completion variable for abortscan */ + struct completion abortscan_event_var; + + vos_event_t scan_finished_event; + + hdd_scan_pending_option_e scan_pending_option; + tANI_U8 sessionId; + /* time to store last station scan done. */ + v_TIME_t last_scan_timestamp; + tANI_U8 last_scan_channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 last_scan_numChannels; + +}hdd_scaninfo_t; + +typedef struct +{ + struct wiphy *wiphy; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev; +#endif + struct cfg80211_scan_request *scan_request; + int magic; + int attempt; + int reject; + struct delayed_work scan_work; +}scan_context_t; + +/* Changing value from 10 to 240, as later is + supported by wcnss */ +#define WLAN_HDD_MAX_MC_ADDR_LIST 240 + +#ifdef WLAN_FEATURE_PACKET_FILTERING +typedef struct multicast_addr_list +{ + v_U8_t isFilterApplied; + v_U8_t mc_cnt; + v_U8_t addr[WLAN_HDD_MAX_MC_ADDR_LIST][ETH_ALEN]; +} t_multicast_add_list; +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/*Batch scan repsonse AP info*/ +typedef struct +{ + /*Batch ID*/ + tANI_U32 batchId; + /*is it last AP in GET BATCH SCAN RSP*/ + v_BOOL_t isLastAp; + /*BSSID*/ + tANI_U8 bssid[SIR_MAC_ADDR_LEN]; + /*SSID*/ + tANI_U8 ssid[SIR_MAX_SSID_SIZE + 1]; + /*Channel*/ + tANI_U8 ch; + /*RSSI or Level*/ + tANI_S8 rssi; + /*Age*/ + tANI_U32 age; +}tHDDbatchScanRspApInfo; + +/*Batch scan response list*/ +struct tHDDBatchScanRspList +{ + tHDDbatchScanRspApInfo ApInfo; + struct tHDDBatchScanRspList *pNext; +}; + +typedef struct tHDDBatchScanRspList tHddBatchScanRsp; + +/*Batch Scan state*/ +typedef enum +{ + /*Batch scan is started this means WLS_BATCHING SET command is issued + from framework*/ + eHDD_BATCH_SCAN_STATE_STARTED, + + /*Batch scan is stopped this means WLS_BATCHING STOP command is issued + from framework*/ + eHDD_BATCH_SCAN_STATE_STOPPED, + + eHDD_BATCH_SCAN_STATE_MAX, +} eHDD_BATCH_SCAN_STATE; + +#endif + +#define HDD_SCAN_REJECT_RATE_LIMIT 5 + +/* + * @eHDD_SCAN_REJECT_DEFAULT: default value + * @eHDD_CONNECTION_IN_PROGRESS: connection is in progress + * @eHDD_REASSOC_IN_PROGRESS: reassociation is in progress + * @eHDD_EAPOL_IN_PROGRESS: STA/P2P-CLI is in middle of EAPOL/WPS exchange + * @eHDD_SAP_EAPOL_IN_PROGRESS: SAP/P2P-GO is in middle of EAPOL/WPS exchange + */ +typedef enum +{ + eHDD_SCAN_REJECT_DEFAULT = 0, + eHDD_CONNECTION_IN_PROGRESS, + eHDD_REASSOC_IN_PROGRESS, + eHDD_EAPOL_IN_PROGRESS, + eHDD_SAP_EAPOL_IN_PROGRESS, +} scan_reject_states; + +typedef struct +{ + struct completion completion; + tANI_U32 magic; + hdd_adapter_t *pAdapter; +}fwStatsContext_t; + +#define WLAN_HDD_ADAPTER_MAGIC 0x574c414e //ASCII "WLAN" + +struct hdd_adapter_s +{ + void *pHddCtx; + + device_mode_t device_mode; + + /** Handle to the network device */ + struct net_device *dev; + +#ifdef WLAN_NS_OFFLOAD + /** IPv6 notifier callback for handling NS offload on change in IP */ + struct work_struct ipv6NotifierWorkQueue; +#endif + + /** IPv4 notifier callback for handling ARP offload on change in IP */ + struct work_struct ipv4NotifierWorkQueue; + + //TODO Move this to sta Ctx + struct wireless_dev wdev ; + struct cfg80211_scan_request *request ; + + /** ops checks if Opportunistic Power Save is Enable or Not + * ctw stores ctWindow value once we receive Opps command from + * wpa_supplicant then using ctWindow value we need to Enable + * Opportunistic Power Save + */ + tANI_U8 ops; + tANI_U32 ctw; + + /** Current MAC Address for the adapter */ + v_MACADDR_t macAddressCurrent; + + /**Event Flags*/ + unsigned long event_flags; + + /**Device TX/RX statistics*/ + struct net_device_stats stats; + /** HDD statistics*/ + hdd_stats_t hdd_stats; + /**Mib information*/ + sHddMib_t hdd_mib; + + tANI_U8 sessionId; + + /* Completion variable for session close */ + struct completion session_close_comp_var; + + /* Completion variable for session open */ + struct completion session_open_comp_var; + + //TODO: move these to sta ctx. These may not be used in AP + /** completion variable for disconnect callback */ + struct completion disconnect_comp_var; + + /** Completion of change country code */ + struct completion change_country_code; + + /* completion variable for Linkup Event */ + struct completion linkup_event_var; + + /* completion variable for cancel remain on channel Event */ + struct completion cancel_rem_on_chan_var; + + /** completion variable for PNO req callback */ + struct completion pno_comp_var; + int pno_req_status; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + /* completion variable for off channel remain on channel Event */ + struct completion offchannel_tx_event; +#endif + /* Completion variable for action frame */ + struct completion tx_action_cnf_event; + /* Completion variable for remain on channel ready */ + struct completion rem_on_chan_ready_event; + + /* Completion variable for Upper Layer Authentication */ + struct completion ula_complete; + +#ifdef FEATURE_WLAN_TDLS + struct completion tdls_add_station_comp; + struct completion tdls_del_station_comp; + struct completion tdls_mgmt_comp; + struct completion tdls_link_establish_req_comp; + eHalStatus tdlsAddStaStatus; +#endif + +#ifdef WLAN_FEATURE_RMC + struct completion ibss_peer_info_comp; +#endif /* WLAN_FEATURE_RMC */ + + /* completion variable for wlan suspend */ + struct completion wlan_suspend_comp_var; + + /* Track whether the linkup handling is needed */ + v_BOOL_t isLinkUpSvcNeeded; + + /* Mgmt Frames TX completion status code */ + tANI_U32 mgmtTxCompletionStatus; + +/************************************************************* + * Tx Queues + */ + /** Transmit queues for each AC (VO,VI,BE etc) */ + hdd_list_t wmm_tx_queue[NUM_TX_QUEUES]; + /**Track whether VOS is in a low resource state*/ + v_BOOL_t isVosOutOfResource; + + /**Track whether 3/4th of resources are used */ + v_BOOL_t isVosLowResource; + + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t isTxSuspended[NUM_TX_QUEUES]; + + /** WMM Status */ + hdd_wmm_status_t hddWmmStatus; +/************************************************************* + */ +/************************************************************* + * TODO - Remove it later + */ + /** Multiple station supports */ + /** Per-station structure */ + //v_U8_t uNumActiveStation; + + v_U16_t aTxQueueLimit[NUM_TX_QUEUES]; +/************************************************************* + */ + +#ifdef FEATURE_WLAN_WAPI + hdd_wapi_info_t wapi_info; +#endif + + /* Keep track ns offload count */ + v_U8_t ns_slots; + + v_S7_t rssi; + v_S7_t rssi_on_disconnect; + + tANI_U8 snr; + + struct work_struct monTxWorkQueue; + struct sk_buff *skb_to_tx; + + /* sta_id to mac addr hash*/ + spinlock_t sta_hash_lock; + tANI_U8 is_sta_id_hash_initialized; + struct sta_hash{ + tANI_U16 mask; + tANI_U16 idx_bits; + hdd_list_t *bins; + } sta_id_hash; + + union { + hdd_station_ctx_t station; + hdd_ap_ctx_t ap; + hdd_mon_ctx_t monitor; + }sessionCtx; + + hdd_cfg80211_state_t cfg80211State; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + t_multicast_add_list mc_addr_list; +#endif + + //Magic cookie for adapter sanity verification + v_U32_t magic; + v_BOOL_t higherDtimTransition; + v_BOOL_t survey_idx; + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*Completion variable for set batch scan request*/ + struct completion hdd_set_batch_scan_req_var; + /*Completion variable for get batch scan request*/ + struct completion hdd_get_batch_scan_req_var; + /*HDD batch scan lock*/ + struct mutex hdd_batch_scan_lock; + /*HDD set batch scan request*/ + tSirSetBatchScanReq hddSetBatchScanReq; + /*HDD set batch scan response*/ + tSirSetBatchScanRsp hddSetBatchScanRsp; + /*HDD stop batch scan indication*/ + tSirStopBatchScanInd hddStopBatchScanInd; + /*HDD get batch scan request*/ + tSirTriggerBatchScanResultInd hddTriggerBatchScanResultInd; + /*Batched scan reponse queue: new batch scan results added at the tail + and old batch scan results are deleted from head*/ + tHddBatchScanRsp *pBatchScanRsp; + /*No of scans in batch scan rsp(MSCAN)*/ + v_U32_t numScanList; + /*isTruncated = 1 batch scan rsp is truncated + isTruncated = 0 batch scan rsp is complete*/ + v_BOOL_t isTruncated; + /*Wait for get batch scan response from FW or not*/ + volatile v_BOOL_t hdd_wait_for_get_batch_scan_rsp; + /*Wait for set batch scan response from FW or not*/ + volatile v_BOOL_t hdd_wait_for_set_batch_scan_rsp; + /*Previous batch scan ID*/ + v_U32_t prev_batch_id; + /*Batch scan state*/ + eHDD_BATCH_SCAN_STATE batchScanState; +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + tAniTrafStrmMetrics tsmStats; +#endif + /* Flag to ensure PSB is configured through framework */ + v_U8_t psbChanged; + v_ULONG_t prev_rx_packets; + /* UAPSD psb value configured through framework */ + v_U8_t configuredPsb; + v_BOOL_t is_roc_inprogress; + v_U32_t maxRateFlags; +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + v_BOOL_t isLinkLayerStatsSet; +#endif + /* DSCP to UP QoS Mapping */ + sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1]; + /* Lock for active sessions while processing deauth/Disassoc */ + spinlock_t lock_for_active_session; + tSirFwStatsResult fwStatsRsp; + + /* Time stamp for last completed RoC request */ + v_TIME_t lastRocTs; + + /* work queue to defer the back to back p2p_listen */ + struct delayed_work roc_work; + + /* Time stamp for start RoC request */ + v_TIME_t startRocTs; + + /* Wireless statistics */ + struct iw_statistics iwStats; + + /* Currently used antenna Index*/ + int antennaIndex; +#ifdef DHCP_SERVER_OFFLOAD + hdd_dhcp_state_t dhcp_status; +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + hdd_mdns_state_t mdns_status; +#endif /* MDNS_OFFLOAD */ + +#ifdef WLAN_FEATURE_TSF + struct hdd_tsf_ctx_s tsf_cap_ctx; +#endif + bool con_status; + bool dad; +}; + +#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) +#define WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.monitor) +#define WLAN_HDD_GET_AP_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.ap) +#define WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter) (&(pAdapter)->sessionCtx.station.WextState) +#define WLAN_HDD_GET_CTX(pAdapter) ((hdd_context_t*)pAdapter->pHddCtx) +#define WLAN_HDD_GET_HAL_CTX(pAdapter) (((hdd_context_t*)(pAdapter->pHddCtx))->hHal) +#define WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter) (&(pAdapter)->sessionCtx.ap.HostapdState) +#define WLAN_HDD_GET_CFG_STATE_PTR(pAdapter) (&(pAdapter)->cfg80211State) +#ifdef FEATURE_WLAN_TDLS +#define WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter) \ + (((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && \ + (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode)) ? 0 : 1) +#define WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter) \ + ((WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter)) ? \ + (tdlsCtx_t*)(pAdapter)->sessionCtx.station.pHddTdlsCtx : NULL) +#endif + +typedef struct hdd_adapter_list_node +{ + hdd_list_node_t node; // MUST be first element + hdd_adapter_t *pAdapter; +}hdd_adapter_list_node_t; + +typedef struct hdd_priv_data_s +{ + tANI_U8 *buf; + int used_len; + int total_len; +}hdd_priv_data_t; + +typedef struct +{ + vos_timer_t trafficTimer; + atomic_t isActiveMode; + v_U8_t isInitialized; + vos_lock_t trafficLock; + v_TIME_t lastFrameTs; +}hdd_traffic_monitor_t; + +typedef struct +{ + struct completion completion; + tANI_U32 magic; +}bcnMissRateContext_t; + +typedef struct +{ + v_MACADDR_t randomMacAddr; + v_U8_t isReqDeferred; + v_U8_t isEnabled; + struct mutex macSpoofingLock; +}macAddrSpoof_t; + +#define WLAN_WAIT_TIME_LL_STATS 800 + +#define WLAN_WAIT_TIME_NUD_STATS 800 +#define WLAN_NUD_STATS_LEN 800 +#define WLAN_NUD_STATS_ARP_PKT_TYPE 1 + +/* FW memory dump feature +@TODO : Move this code to a separate file later */ +#define PROCFS_MEMDUMP_DIR "debug" +#define PROCFS_MEMDUMP_NAME "fwdump" +#define FW_MEM_DUMP_REQ_ID 1 +#define FW_MEM_DUMP_TIMEOUT_MS 800 +#define FW_MEM_DUMP_MAGIC 0x3C3A2D44 + +/** + * struct hdd_fw_mem_dump_req_ctx - hdd fw mem dump req context + * + * @magic : magic for validating cfg80211 requests + * @status: status for cfg80211 requests + * @pHDDCtx: ptr to HDD context + * @req_completion: completion variable for fw mem dump + */ +struct hdd_fw_mem_dump_req_ctx { + uint32_t magic; + bool status; + struct completion req_completion; +}; + +/** + * callback type to check fw mem dump request.Called from SVC + * context and update status in HDD. + */ +typedef void (*hdd_fw_mem_dump_req_cb)(struct hdd_fw_mem_dump_req_ctx *); + +int memdump_init(void); +int memdump_deinit(void); +void wlan_hdd_fw_mem_dump_cb(void *,tAniFwrDumpRsp *); +int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx); +void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx*); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/** + * struct hdd_ll_stats_context - hdd link layer stats context + * + * @request_id: userspace-assigned link layer stats request id + * @request_bitmap: userspace-assigned link layer stats request bitmap + * @response_event: LL stats request wait event + */ +struct hdd_ll_stats_context { + uint32_t request_id; + uint32_t request_bitmap; + struct completion response_event; +}; +#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */ + +/** + * struct hdd_nud_stats_context - hdd NUD stats context + * + * @response_event: NUD stats request wait event + */ +struct hdd_nud_stats_context { + struct completion response_event; +}; + +#ifdef WLAN_FEATURE_EXTSCAN +/** + * struct hdd_ext_scan_context - hdd ext scan context + * + * @request_id: userspace-assigned ID associated with the request + * @response_status: Status returned by FW in response to a request + * @ignore_cached_results: Flag to ignore cached results or not + * @capability_response: Ext scan capability response data from target + */ + +struct hdd_ext_scan_context { + v_U32_t request_id; + int response_status; + bool ignore_cached_results; + struct completion response_event; + tSirEXTScanCapabilitiesEvent capability_response; +}; +#endif /* End of WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_OFFLOAD_PACKETS +/** + * struct hdd_offloaded_packets - request id to pattern id mapping + * @request_id: request id + * @pattern_id: pattern id + * + */ +struct hdd_offloaded_packets +{ + uint32_t request_id; + uint8_t pattern_id; +}; + +/** + * struct hdd_offloaded_packets_ctx - offloaded packets context + * @op_table: request id to pattern id table + * @op_lock: mutex lock + */ +struct hdd_offloaded_packets_ctx +{ + struct hdd_offloaded_packets op_table[MAXNUM_PERIODIC_TX_PTRNS]; + struct mutex op_lock; +}; +#endif + +/** Adapter stucture definition */ + +struct hdd_context_s +{ + /** Global VOS context */ + v_CONTEXT_t pvosContext; + + /** HAL handle...*/ + tHalHandle hHal; + + struct wiphy *wiphy ; + //TODO Remove this from here. + + hdd_list_t hddAdapters; //List of adapters + /* One per STA: 1 for RX_BCMC_STA_ID and 1 for SAP_SELF_STA_ID*/ + hdd_adapter_t *sta_to_adapter[WLAN_MAX_STA_COUNT + 3]; //One per sta. For quick reference. + + /** Pointer for firmware image data */ + const struct firmware *fw; + + /** Pointer for configuration data */ + const struct firmware *cfg; + + /** Pointer for nv data */ + const struct firmware *nv; + + /** Pointer to the parent device */ + struct device *parent_dev; + + pid_t pid_sdio_claimed; + atomic_t sdio_claim_count; + + /** Config values read from qcom_cfg.ini file */ + hdd_config_t *cfg_ini; + wlan_hdd_ftm_status_t ftm; + /** completion variable for full power callback */ + struct completion full_pwr_comp_var; + /** completion variable for Request BMPS callback */ + struct completion req_bmps_comp_var; + + /** completion variable for standby callback */ + struct completion standby_comp_var; + + /* Completion variable to indicate Rx Thread Suspended */ + struct completion rx_sus_event_var; + + /* Completion variable to indicate Tx Thread Suspended */ + struct completion tx_sus_event_var; + + /* Completion variable to indicate Mc Thread Suspended */ + struct completion mc_sus_event_var; + + /* Completion variable for regulatory hint */ +#ifdef CONFIG_ENABLE_LINUX_REG + struct completion linux_reg_req; +#else + struct completion driver_crda_req; +#endif + /* Completion variable to indicate updation of channel */ + struct completion wiphy_channel_update_event; + + v_BOOL_t nEnableStrictRegulatoryForFCC; + + v_BOOL_t isWlanSuspended; + + v_BOOL_t isTxThreadSuspended; + + v_BOOL_t isMcThreadSuspended; + + v_BOOL_t isRxThreadSuspended; + + volatile v_BOOL_t isLogpInProgress; + + struct completion ssr_comp_var; + + v_U8_t isLoadUnloadInProgress; + + /**Track whether driver has been suspended.*/ + hdd_ps_state_t hdd_ps_state; + + /* Track whether Mcast/Bcast Filter is enabled.*/ + v_BOOL_t hdd_mcastbcast_filter_set; + + /* Track whether ignore DTIM is enabled*/ + v_BOOL_t hdd_ignore_dtim_enabled; + v_U32_t hdd_actual_ignore_DTIM_value; + v_U32_t hdd_actual_LI_value; + + + v_BOOL_t hdd_wlan_suspended; + bool rx_wow_dump; + + uint8_t bad_sta[HDD_MAX_STA_COUNT]; + + spinlock_t filter_lock; + + /* Lock to avoid race condtion during start/stop bss*/ + struct mutex sap_lock; + + struct work_struct sap_start_work; + bool is_sap_restart_required; + bool is_ch_avoid_in_progress; + vos_spin_lock_t sap_update_info_lock; + + /* Lock to avoid race condtion between ROC timeout and + cancel callbacks*/ + struct mutex roc_lock; + /** ptt Process ID*/ + v_SINT_t ptt_pid; +#ifdef WLAN_KD_READY_NOTIFIER + v_BOOL_t kd_nl_init; +#endif /* WLAN_KD_READY_NOTIFIER */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + /* OEM App registered or not */ + v_BOOL_t oem_app_registered; + + /* OEM App Process ID */ + v_SINT_t oem_pid; +#endif + + v_U8_t change_iface; + + /** Concurrency Parameters*/ + tVOS_CONCURRENCY_MODE concurrency_mode; + + v_U8_t no_of_open_sessions[VOS_MAX_NO_OF_MODE]; + v_U8_t no_of_active_sessions[VOS_MAX_NO_OF_MODE]; + + hdd_chip_reset_stats_t hddChipResetStats; + /* Number of times riva restarted */ + v_U32_t hddRivaResetStats; + + /* Can we allow AMP connection right now*/ + v_BOOL_t isAmpAllowed; + + /** P2P Device MAC Address for the adapter */ + v_MACADDR_t p2pDeviceAddress; + + /* Thermal mitigation information */ + hdd_thermal_mitigation_info_t tmInfo; + +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_t rx_wake_lock; +#endif + + /* + * Framework initiated driver restarting + * hdd_reload_timer : Restart retry timer + * isRestartInProgress: Restart in progress + * hdd_restart_retries: Restart retries + * + */ + vos_timer_t hdd_restart_timer; + atomic_t isRestartInProgress; + u_int8_t hdd_restart_retries; + + hdd_scaninfo_t scan_info; + + /*is_dyanmic_channel_range_set is set to 1 when Softap_set_channel_range + is invoked*/ + v_BOOL_t is_dynamic_channel_range_set; + vos_wake_lock_t sap_wake_lock; +#ifdef FEATURE_WLAN_TDLS + eTDLSSupportMode tdls_mode; + eTDLSSupportMode tdls_mode_last; + tdlsConnInfo_t tdlsConnInfo[HDD_MAX_NUM_TDLS_STA]; + /* TDLS peer connected count */ + tANI_U16 connected_peer_count; + scan_context_t scan_ctxt; + /* Lock to avoid race condition during TDLS operations*/ + struct mutex tdls_lock; +#endif + + hdd_traffic_monitor_t traffic_monitor; + + /* MC/BC Filter state variable + * This always contains the value that is currently + * configured + * */ + v_U8_t configuredMcastBcastFilter; + + v_U8_t sus_res_mcastbcast_filter; + + v_BOOL_t sus_res_mcastbcast_filter_valid; + + v_BOOL_t mc_list_cfg_in_fwr; + + /* debugfs entry */ + struct dentry *debugfs_phy; + + /* Use below lock to protect access to isSchedScanUpdatePending + * since it will be accessed in two different contexts. + */ + spinlock_t schedScan_lock; + + // Flag keeps track of wiphy suspend/resume + v_BOOL_t isWiphySuspended; + + // Indicates about pending sched_scan results + v_BOOL_t isSchedScanUpdatePending; + /* + * TX_rx_pkt_count_timer + */ + vos_timer_t tx_rx_trafficTmr; + v_U8_t drvr_miracast; + v_U8_t issplitscan_enabled; + v_U8_t isTdlsScanCoexistence; + + /* VHT80 allowed*/ + v_BOOL_t isVHT80Allowed; + +#ifdef FEATURE_WLAN_CH_AVOID + v_U16_t unsafeChannelCount; + v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS]; + v_U16_t safeChannelList[NUM_20MHZ_RF_CHANNELS]; +#endif /* FEATURE_WLAN_CH_AVOID */ + + v_BOOL_t btCoexModeSet; + v_BOOL_t isPnoEnable; + macAddrSpoof_t spoofMacAddr; + /* flag to decide if driver need to scan DFS channels or not */ + v_BOOL_t disable_dfs_flag; + +#ifdef WLAN_NS_OFFLOAD + /* + * IPv6 notifier callback for handling NS offload on change in IP + */ + struct notifier_block ipv6_notifier; +#endif + + /* IPv4 notifier callback for handling ARP offload on change in + * IP + */ + struct notifier_block ipv4_notifier; + //Lock to avoid race condition during wmm operations + struct mutex wmmLock; + v_BOOL_t mgmt_frame_logging; + v_BOOL_t isSetBandByNL; + v_U8_t fw_Version[SIR_VERSION_STRING_LEN]; +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + struct hdd_ll_stats_context ll_stats_context; +#endif /* End of WLAN_FEATURE_LINK_LAYER_STATS */ + struct hdd_nud_stats_context nud_stats_context; + +#ifdef WLAN_FEATURE_EXTSCAN + struct hdd_ext_scan_context ext_scan_context; +#endif /* WLAN_FEATURE_EXTSCAN */ + + /* Time since boot up to WiFi turn ON (in micro seconds) */ + v_U64_t wifi_turn_on_time_since_boot; + unsigned long last_suspend_success; + v_U32_t continuous_suspend_fail_cnt; + +#ifdef WLAN_FEATURE_OFFLOAD_PACKETS + struct hdd_offloaded_packets_ctx op_ctx; +#endif + + /* work queue to defer mac spoofing */ + struct delayed_work spoof_mac_addr_work; + + vos_timer_t delack_timer; + struct mutex cur_rx_level_lock; + v_U32_t cur_rx_level; + v_U64_t prev_rx; + v_ULONG_t mode; + + /* bit map to set/reset TDLS by different sources */ + unsigned long tdls_source_bitmap; + + /* tdls source timer to enable/disable TDLS on p2p listen */ + vos_timer_t tdls_source_timer; + + v_U64_t extscan_start_time_since_boot; + v_U8_t last_scan_reject_session_id; + scan_reject_states last_scan_reject_reason; + v_TIME_t last_scan_reject_timestamp; + v_U8_t scan_reject_cnt; + bool is_ap_mode_wow_supported; + bool is_fatal_event_log_sup; + + uint32_t track_arp_ip; +}; + +typedef enum { + TP_IND_LOW = 1, + TP_IND_MEDIUM, + TP_IND_HIGH, +}TP_IND_TYPE; + +/* Use to notify the TDLS or BTCOEX is mode enable */ +typedef enum +{ + WLAN_TDLS_MODE, + WLAN_BTCOEX_MODE, +} WLAN_MODE_TYPE; + +#define WLAN_HDD_IS_LOAD_IN_PROGRESS(pHddCtx) \ + (pHddCtx->isLoadUnloadInProgress & WLAN_HDD_LOAD_IN_PROGRESS) + +#define WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx) \ + (pHddCtx->isLoadUnloadInProgress & WLAN_HDD_UNLOAD_IN_PROGRESS) + +#define WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx) \ + (pHddCtx->isLoadUnloadInProgress & \ + (WLAN_HDD_LOAD_IN_PROGRESS | WLAN_HDD_UNLOAD_IN_PROGRESS)) + +/* Logging of both Mgmt and Data pkts are supported by HW in both TX & RX. + * But only support for logging of Mgmt pkts is supported from host driver. + */ +typedef enum +{ + WLAN_FRAME_LOGGING_FRAMETYPE_DATA, + WLAN_FRAME_LOGGING_FRAMETYPE_MGMT, +} WLAN_FRAME_LOGGING_FRAMETYPE; + +// Only first 64/128 bytes of Mgmt/Data pkts can be logged. +typedef enum +{ + WLAN_MGMT_LOGGING_FRAMESIZE_64BYTES = 64, + WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES = 128, +} WLAN_MGMT_LOGGING_FRAMESIZE; + +/* In Circular Mode HW buffer will be filled in circular fashion with buffer + * overwritten when buffer memory is full and new pkt is to be logged. + * Freeze mode will stop filling the buffer memory when buffer is full and thus + * no more pkts will logged unless buffer memory is freed. + */ +typedef enum +{ + WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR, + WLAN_FRAME_LOGGING_BUFFERMODE_FREEZE, +} WLAN_FRAME_LOGGING_BUFFERMODE; + +/* WLAN_FRAME_LOG_EN - Enables frame logging in HW + * WLAN_BMUHW_TRACE_LOG_EN - 8K/16K memory buffer will be used for logging + * WLAN_QXDM_LOG_EN - FW QXDM logs will be routed through host driver + * WLAN_DPU_TXP_LOG_EN - pkts will be logged at both DPU and TXP HW block. + */ +typedef enum +{ + WLAN_FRAME_LOG_EN = 1<<0, + WLAN_BMUHW_TRACE_LOG_EN = 1<<1, + WLAN_QXDM_LOG_EN = 1<<2, + WLAN_DPU_TXP_LOG_EN = 1<<3, + WLAN_FW_MEM_DUMP_EN = 1<<6, +} WLAN_ENABLE_HW_FW_LOG_TYPE; + +#ifdef MDNS_OFFLOAD +/* Offload struct */ +struct hdd_mdns_resp_info { + uint8_t num_entries; + uint8_t *data; + uint16_t *offset; +}; + +struct hdd_mdns_resp_matched { + uint8_t num_matched; + uint8_t type; +}; +#endif /* MDNS_OFFLOAD */ + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ +const char * hdd_device_modetoString(v_U8_t device_mode); +VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode); + +VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode, + hdd_adapter_list_node_t** pNextAdapterNode); + +VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode); + +VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode); + +VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode); + +VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode); + +hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, + const char* name, tSirMacAddr macAddr, + tANI_U8 rtnl_held ); +VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held ); +VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx ); +struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy, + struct ieee80211_channel *channel, + const u8 *bssid, + const u8 *ssid, size_t ssid_len); +void hdd_connect_result(struct net_device *dev, const u8 *bssid, + tCsrRoamInfo *roam_info, const u8 *req_ie, + size_t req_ie_len, const u8 * resp_ie, + size_t resp_ie_len, u16 status, gfp_t gfp); +void hdd_dump_concurrency_info(hdd_context_t *pHddCtx); +hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name ); +hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, tSirMacAddr macAddr ); +hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx, + tANI_U32 sme_session_id ); +hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx ); +VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter ); +hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode ); +void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held ); +VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + const v_BOOL_t bCloseSession ); +void hdd_set_station_ops( struct net_device *pWlanDev ); +tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx); +void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr); +v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode ); +void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type); +void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar); +VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar, + hdd_mon_ctx_t *pMonCtx , void* callback); +void hdd_set_conparam ( v_UINT_t newParam ); +tVOS_CON_MODE hdd_get_conparam( void ); + +void wlan_hdd_enable_deepsleep(v_VOID_t * pVosContext); +v_BOOL_t wlan_hdd_is_GO_power_collapse_allowed(hdd_context_t* pHddCtx); +v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx); +v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx); +tSirAbortScanStatus hdd_abort_mac_scan(hdd_context_t* pHddCtx, + tANI_U8 sessionId, + eCsrAbortReason reason); +void hdd_processSpoofMacAddrRequest(struct work_struct *work); +void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ); + +void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id); +void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, + tVOS_CON_MODE mode); +void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter); +void hdd_prevent_suspend(uint32_t reason); +void hdd_allow_suspend(uint32_t reason); +void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason); +bool hdd_is_ssr_required(void); +void hdd_set_ssr_required(e_hdd_ssr_required value); +void hdd_set_pre_close(hdd_context_t *pHddCtx); + +VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx); +VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type); + +void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy); +VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx); +void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx); +void hdd_set_pwrparams(hdd_context_t *pHddCtx); +void hdd_reset_pwrparams(hdd_context_t *pHddCtx); +int wlan_hdd_validate_context(hdd_context_t *pHddCtx); +v_BOOL_t hdd_is_valid_mac_address(const tANI_U8* pMacAddr); +VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx); +VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx); +void hdd_ipv4_notifier_work_queue(struct work_struct *work); +v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id, + scan_reject_states *reason); +void hdd_set_ibss_ops(hdd_adapter_t *pAdapter); +#ifdef WLAN_FEATURE_PACKET_FILTERING +int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType, tANI_U8 sessionId); +#endif + +#ifdef WLAN_NS_OFFLOAD +void hdd_ipv6_notifier_work_queue(struct work_struct *work); +#endif + +#ifdef WLAN_FEATURE_RMC +v_MACADDR_t* hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter, v_U8_t staIdx); +#endif /* WLAN_FEATURE_RMC */ + +#ifdef CONFIG_ENABLE_LINUX_REG +void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx); +#endif +int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr); + +/* + * start/stop bandwidth compute timer, Based on which tcp delack + * value will be configured + */ +void hdd_manage_delack_timer(hdd_context_t *pHddCtx); + +void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx); +void hdd_start_delack_timer(hdd_context_t *pHddCtx); +void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx); +v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx); +void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level); + +/* + * Calculate the packet channel bandwidth and send notification to cnss demon + */ +void hdd_request_tcp_delack(hdd_context_t *pHddCtx, + uint64_t rx_packets); +void hdd_tcp_delack_compute_function(void *priv); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/**--------------------------------------------------------------------------- + + \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING + IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled: + WLS_BATCHING VERSION + WLS_BATCHING SET + WLS_BATCHING GET + WLS_BATCHING STOP + + \param - pAdapter Pointer to HDD adapter + \param - pPrivdata Pointer to priv_data + \param - command Pointer to command + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_handle_batch_scan_ioctl +( + hdd_adapter_t *pAdapter, + hdd_priv_data_t *pPrivdata, + tANI_U8 *command +); + +/**--------------------------------------------------------------------------- + + \brief hdd_deinit_batch_scan () - This function cleans up batch scan data + structures + + \param - pAdapter Pointer to HDD adapter + + \return - None + + --------------------------------------------------------------------------*/ + +void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter); + +#endif /*End of FEATURE_WLAN_BATCH_SCAN*/ +void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len); + +boolean hdd_is_5g_supported(hdd_context_t * pHddCtx); + +int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter); + +#ifdef CONFIG_ENABLE_LINUX_REG +VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init ); +#endif + +VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx); +hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx); + +VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx, + tANI_U8 dfsScanMode); + +v_U8_t hdd_is_fw_logging_enabled(void); +v_U8_t hdd_is_fw_ev_logging_enabled(void); + +#define HDD_STA_ID_HASH_MULTIPLIER 2 + +struct hdd_align_mac_addr_t { + uint16 bytes_ab; + uint16 bytes_cd; + uint16 bytes_ef; +}; + +typedef struct hdd_staid_hash_node +{ + hdd_list_node_t node; + v_U8_t sta_id; + v_MACADDR_t mac_addr; +}hdd_staid_hash_node_t; + +/* sta_id hash related APIs */ +VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter); +VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter); +int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter, + v_MACADDR_t *mac_addr_in); +VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter, + v_U8_t sta_id, v_MACADDR_t *mac_addr); +VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter, + v_U8_t sta_id, v_MACADDR_t *mac_addr); +int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter, + v_MACADDR_t *mac_addr_in); +void hdd_init_frame_logging(hdd_context_t *pHddCtx); + +int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, + tANI_U8* command, tANI_U8 cmd_len); +void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind); + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/** + * hdd_init_ll_stats_ctx() - initialize link layer stats context + * @hdd_ctx: Pointer to hdd context + * + * Return: none + */ +static inline void hdd_init_ll_stats_ctx(hdd_context_t *hdd_ctx) +{ + init_completion(&hdd_ctx->ll_stats_context.response_event); + hdd_ctx->ll_stats_context.request_bitmap = 0; + + return; +} +#else +static inline void hdd_init_ll_stat_ctx(void) +{ + return; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/** + * hdd_init_nud_stats_ctx() - initialize NUD stats context + * @hdd_ctx: Pointer to hdd context + * + * Return: none + */ +static inline void hdd_init_nud_stats_ctx(hdd_context_t *hdd_ctx) +{ + init_completion(&hdd_ctx->nud_stats_context.response_event); + return; +} + +void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter); +void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy); +void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx); +int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request); +void wlan_hdd_schedule_defer_scan(struct work_struct *work); +void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request, + unsigned long delay); +int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, + const tANI_U8 channel, const handoff_src src); +#ifdef DHCP_SERVER_OFFLOAD +VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter, + bool re_init); +#endif +#ifdef MDNS_OFFLOAD +bool wlan_hdd_set_mdns_offload(hdd_adapter_t *adapter); +#else +static inline bool wlan_hdd_set_mdns_offload(hdd_adapter_t *adapter) +{ + return FALSE; +} +#endif /* MDNS_OFFLOAD */ + +void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter); + +/** + * hdd_drv_cmd_validate() - Validates for space in hdd driver command + * @command: pointer to input data (its a NULL terminated string) + * @len: length of command name + * + * This function checks for space after command name and if no space + * is found returns error. + * + * Return: 0 for success non-zero for failure + */ +int hdd_drv_cmd_validate(tANI_U8 *command, int len); + +#ifdef WLAN_FEATURE_TSF +void wlan_hdd_tsf_init(hdd_adapter_t *adapter); +int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len); +int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len); +#else +static inline void +wlan_hdd_tsf_init(hdd_adapter_t *adapter) +{ + return; +} + +static inline int +hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +{ + return -ENOTSUPP; +} + +static inline int +hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +{ + return -ENOTSUPP; +} +#endif +int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter); +#endif // end #if !defined( WLAN_HDD_MAIN_H ) diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_mib.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_mib.h new file mode 100644 index 000000000000..a4502775985d --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_mib.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_MIB_h__ ) +#define WLAN_HDD_MIB_h__ + + +#include + +typedef enum +{ + eMib_dot11DesiredBssType_infrastructure = 1, + eMib_dot11DesiredBssType_independent = 2, + eMib_dot11DesiredBssType_infra_ap =3, + eMib_dot11DesiredBssType_any = 4 + +} eMib_dot11DesiredBssType; + + +/** This is the maximum number of BSSIDs supported in the + dot11DesiredBssidList. All the code operates off of + this maximum BSSID list count. */ +#define MIB_DOT11_DESIRED_BSSID_LIST_MAX_COUNT ( 1 ) + +typedef struct +{ + v_U32_t cEntries; + + v_MACADDR_t BSSIDs[ MIB_DOT11_DESIRED_BSSID_LIST_MAX_COUNT ]; + +} sMib_dot11DesiredBssidList; + + + +/** This is the maximum number of SSIDs supported in the + dot11DesiredSsidList. All the code operates off of + this maximum SSID list count. */ + +#define MIB_DOT11_DESIRED_SSID_LIST_MAX_COUNT ( 1 ) + +#define MIB_DOT11_SSID_MAX_LENGTH ( 32 ) + +typedef struct +{ + v_U32_t ssidLength; + v_U8_t ssid[ MIB_DOT11_SSID_MAX_LENGTH ]; + +} sDot11Ssid; + +typedef struct +{ + v_U32_t cEntries; + + sDot11Ssid SSIDs[ MIB_DOT11_DESIRED_SSID_LIST_MAX_COUNT ]; + +} sMib_dot11DesiredSsidList; + + + +typedef enum +{ + // these are bitmasks.... + eMib_dot11AutoConfigEnabled_None = 0U, + eMib_dot11AutoConfigEnabled_Phy = 0x00000001U, + eMib_dot11AutoConfigEnabled_Mac = 0x00000002U + +} eMib_dot11AutoConfigEnabled; + + + +#define MIB_DOT11_SUPPORTED_PHY_TYPES_MAX_COUNT ( 3 ) + +typedef enum tagMib_dot11PhyType +{ + eMib_dot11PhyType_11b, + eMib_dot11PhyType_11a, + eMib_dot11PhyType_11g, + eMib_dot11PhyType_all +} eMib_dot11PhyType; + +typedef struct tagMib_dot11SupportedPhyTypes +{ + v_U32_t cEntries; + eMib_dot11PhyType phyTypes[ MIB_DOT11_SUPPORTED_PHY_TYPES_MAX_COUNT ]; +} sMib_dot11SupportedPhyTypes; + + +typedef enum +{ + eMib_DevicePowerState_D0, + eMib_DevicePowerState_D1, + eMib_DevicePowerState_D2, + eMib_DevicePowerState_D3 + +} eMib_DevicePowerState; + + +typedef enum +{ + eMib_dot11NICPowerState_OFF = VOS_FALSE, + eMib_dot11NICPowerState_ON = VOS_TRUE + +} eMib_dot11NICPowerState; + + +typedef enum +{ + eMib_dot11HardwarePHYState_OFF = VOS_FALSE, + eMib_dot11HardwarePHYState_ON = VOS_TRUE + +} eMib_dot11HardwarePHYState; + + +typedef enum +{ + eMib_dot11PowerSavingLevel_None, + eMib_dot11PowerSavingLevel_MaxPS, + eMib_dot11PowerSavingLevel_FastPS, + eMib_dot11PowerSavingLevel_MaximumLevel + +} eMib_dot11PowerSavingLevel; + + +#define MIB_DOT11_MAC_EXCLUSION_LIST_MAX_COUNT 4 +typedef struct +{ + v_U32_t cEntries; + + v_MACADDR_t macAddrs[ MIB_DOT11_MAC_EXCLUSION_LIST_MAX_COUNT ]; + +} sMib_dot11MacExcludeList; + +#define MIB_DOT11_PRIVACY_EXEMPT_LIST_MAX_COUNT 32 + +typedef enum +{ + eMib_dot11ExemptionAction_Always, + eMib_dot11ExemptionAction_OnKeyMapUnavailable + +}eMib_dot11ExemptAction; + +typedef enum +{ + eMib_dot11ExemptPacket_Unicast, + eMib_dot11ExemptPacket_Multicast, + eMib_dot11ExemptPacket_Both + +}eMib_dot11ExemptPacket; + +typedef struct +{ + v_U16_t uEtherType; + eMib_dot11ExemptAction exemptAction; + eMib_dot11ExemptPacket exemptPacket; + +}sMib_dot11PrivacyExemption; + +typedef struct +{ + v_U32_t cEntries; + + sMib_dot11PrivacyExemption privacyExemptList[ MIB_DOT11_PRIVACY_EXEMPT_LIST_MAX_COUNT ]; + +} sMib_dot11PrivacyExemptionList; + +typedef struct sHddMib_s +{ + eMib_dot11DesiredBssType mibDot11DesiredBssType; + + sMib_dot11DesiredBssidList mibDot11DesiredBssidList; + + sMib_dot11DesiredSsidList mibDot11DesiredSsidList; + + eMib_dot11AutoConfigEnabled mibDot11AutoConfigEnabled; + + // the device power state for the device (the D-state... you know D0, D1, D2, etc. + eMib_DevicePowerState mibDevicePowerState; + + // dot11NICPowerState is really the on/off state of the PHY. This can be + // mamipulated through OIDs like a software control for radio on/off. + eMib_dot11NICPowerState mibDot11NICPowerState; + + // Hardware PHY state is the on/off state of the hardware PHY. + eMib_dot11HardwarePHYState mibDot11HardwarePHYState; + + // dot11 Power Saving level is the 802.11 power saving level/state for the 802.11 + // NIC. Typically this is mapped to 802.11 BMPS in some fashion. We are not going + // to disappoint; the Libra NIC maps these to different BMPS settings. + eMib_dot11PowerSavingLevel mibDot11PowerSavingLevel; + + sMib_dot11MacExcludeList mibDot11MacExcludeList; + + sMib_dot11PrivacyExemptionList mibDot11PrivacyExemptionList; + + sMib_dot11SupportedPhyTypes mibDot11SupportedPhyTypes; + eMib_dot11PhyType mibDot11CurrentPhyType; + + v_BOOL_t dot11IbssJoinOnly; + v_BOOL_t HiddenNetworkEnabled; + + +}sHddMib_t; + +#endif diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h new file mode 100644 index 000000000000..47522e172ee6 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_oemdata.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/**=========================================================================== + + \file wlan_hdd_oemdata.h + + \brief Internal includes for the oem data + + + ==========================================================================*/ + + +#ifndef __WLAN_HDD_OEM_DATA_H__ +#define __WLAN_HDD_OEM_DATA_H__ + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif + +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +struct iw_oem_data_req +{ + v_U8_t oemDataReq[OEM_DATA_REQ_SIZE]; +}; + +int iw_set_oem_data_req( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); + +int iw_get_oem_data_rsp( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra); + +struct iw_oem_data_rsp +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +}; + +int oem_activate_service(void *pAdapter); +void oem_deactivate_service(void); + +int iw_get_oem_data_cap(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +#define OEM_APP_SIGNATURE_LEN 16 +#define OEM_APP_SIGNATURE_STR "QUALCOMM-OEM-APP" + +#define OEM_TARGET_SIGNATURE_LEN 8 +#define OEM_TARGET_SIGNATURE "QUALCOMM" + +#define OEM_CAP_MAX_NUM_CHANNELS 128 + +#define TARGET_TYPE_PRONTO 0xa0 + +#define WLAN_HAL_CHAN_FLAG_DFS 10 + +typedef enum +{ + /* Error null context */ + OEM_ERR_NULL_CONTEXT = 1, + + /* OEM App is not registered */ + OEM_ERR_APP_NOT_REGISTERED, + + /* Invalid signature */ + OEM_ERR_INVALID_SIGNATURE, + + /* Invalid message type */ + OEM_ERR_NULL_MESSAGE_HEADER, + + /* Invalid message type */ + OEM_ERR_INVALID_MESSAGE_TYPE, + + /* Invalid length in message body */ + OEM_ERR_INVALID_MESSAGE_LENGTH +} eOemErrorCode; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 major; + tANI_U8 minor; + tANI_U8 patch; + tANI_U8 build; +} tDriverVersion; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Signature of chip set vendor, e.g. QUALCOMM */ + tANI_U8 oem_target_signature[OEM_TARGET_SIGNATURE_LEN]; + tANI_U32 oem_target_type; /* Chip type */ + tANI_U32 oem_fw_version; /* FW version */ + tDriverVersion driver_version; /* CLD version */ + tANI_U16 allowed_dwell_time_min; /* Channel dwell time - allowed min */ + tANI_U16 allowed_dwell_time_max; /* Channel dwell time - allowed max */ + tANI_U16 curr_dwell_time_min; /* Channel dwell time - current min */ + tANI_U16 curr_dwell_time_max; /* Channel dwell time - current max */ + tANI_U16 supported_bands; /* 2.4G or 5G Hz */ + tANI_U16 num_channels; /* Num of channels IDs to follow */ + tANI_U8 channel_list[OEM_CAP_MAX_NUM_CHANNELS]; /* List of channel IDs */ +} t_iw_oem_data_cap; + +typedef PACKED_PRE struct PACKED_POST +{ + /* channel id */ + tANI_U32 chan_id; + + /* reserved0 */ + tANI_U32 reserved0; + + /* Primary 20 MHz channel frequency in MHz */ + tANI_U32 mhz; + + /* Center frequency 1 in MHz */ + tANI_U32 band_center_freq1; + + /* Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode */ + tANI_U32 band_center_freq2; + + /* channel info described below */ + tANI_U32 info; + + /* contains min power, max power, reg power and reg class id */ + tANI_U32 reg_info_1; + + /* contains antennamax */ + tANI_U32 reg_info_2; +} tHddChannelInfo; + +#endif //__WLAN_HDD_OEM_DATA_H__ + +#endif //FEATURE_OEM_DATA_SUPPORT diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_p2p.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_p2p.h new file mode 100644 index 000000000000..4e733f039fc1 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_p2p.h @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __P2P_H +#define __P2P_H +/**=========================================================================== + +\file wlan_hdd_p2p.h + +\brief Linux HDD P2P include file + +==========================================================================*/ +#include +#include +#define ACTION_FRAME_TX_TIMEOUT 2000 +#define WAIT_CANCEL_REM_CHAN 1000 +#define WAIT_REM_CHAN_READY 1000 +#define WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX 3000 +#define READY_EVENT_PROPOGATE_TIME 2 + +#define ACTION_FRAME_DEFAULT_WAIT 200 + +#define ESTIMATED_ROC_DUR_REQD_FOR_ACTION_TX 20 + +#define WLAN_HDD_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2) +#define WLAN_HDD_GET_SUBTYPE_FRM_FC(__fc__) (((__fc__) & 0xF0) >> 4) +#define WLAN_HDD_80211_FRM_DA_OFFSET 4 +#define P2P_WILDCARD_SSID_LEN 7 +#define P2P_WILDCARD_SSID "DIRECT-" +#define ACTION_FRAME_RSP_WAIT 500 +#define ACTION_FRAME_ACK_WAIT 300 +#ifdef WLAN_FEATURE_11W +#define WLAN_HDD_SET_WEP_FRM_FC(__fc__) ( (__fc__) = ((__fc__) | 0x40)) +#endif //WLAN_FEATURE_11W + +#define HDD_P2P_MAX_ROC_DURATION 1000 + +enum hdd_rx_flags { + HDD_RX_FLAG_DECRYPTED = 1 << 0, + HDD_RX_FLAG_MMIC_STRIPPED = 1 << 1, + HDD_RX_FLAG_IV_STRIPPED = 1 << 2, +}; + + +#define P2P_POWER_SAVE_TYPE_OPPORTUNISTIC (1 << 0) +#define P2P_POWER_SAVE_TYPE_PERIODIC_NOA (1 << 1) +#define P2P_POWER_SAVE_TYPE_SINGLE_NOA (1 << 2) + +#ifdef WLAN_FEATURE_P2P_DEBUG +typedef enum { P2P_NOT_ACTIVE, + P2P_GO_NEG_PROCESS, + P2P_GO_NEG_COMPLETED, + P2P_CLIENT_CONNECTING_STATE_1, + P2P_GO_COMPLETED_STATE, + P2P_CLIENT_CONNECTED_STATE_1, + P2P_CLIENT_DISCONNECTED_STATE, + P2P_CLIENT_CONNECTING_STATE_2, + P2P_CLIENT_COMPLETED_STATE + }tP2PConnectionStatus; + +extern tP2PConnectionStatus globalP2PConnectionStatus; +#endif + +typedef struct p2p_app_setP2pPs{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; +}p2p_app_setP2pPs_t; + +int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie ); + +int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie ); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie); +#endif + +int hdd_setP2pPs( struct net_device *dev, void *msgData ); +int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command ); +int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command ); + +void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, tANI_U8* pbFrames, + tANI_U8 frameType, + tANI_U32 rxChan, tANI_S8 rxRssi); +void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter ); +void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess ); +int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter); +VOS_STATUS wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, u64 *cookie); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, + bool channel_type_valid, +#endif + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +int wlan_hdd_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, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +int wlan_hdd_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 ); +#else +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie ); +#endif + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, const char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +struct net_device* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#else +int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev ); +#else +int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ); +#endif +void hdd_p2p_roc_work_queue(struct work_struct *work); +#endif // __P2P_H diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_packet_filtering.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_packet_filtering.h new file mode 100644 index 000000000000..73229f2bc016 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_packet_filtering.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: wlan_hdd_packet_filtering.h +* +* Description: Packet Filter Definitions. +* +* +******************************************************************************/ + +#ifndef __WLAN_HDD_PACKET_FILTERING_H__ +#define __WLAN_HDD_PACKET_FILTERING_H__ + + + +#ifdef WLAN_FEATURE_PACKET_FILTERING + +#define HDD_MAX_CMP_PER_PACKET_FILTER 5 +#define HDD_FILTER_IPV6_MC_UC 1 +#define HDD_FILTER_IPV6_MC 0 +#define HDD_FILTER_ID_IPV6_MC 10 +#define HDD_FILTER_ID_IPV6_UC 11 + +#define HDD_IPV6_MC_CMP_DATA 0x33 +#define HDD_IPV6_UC_CMP_DATA 0x01 +#define HDD_IPV6_CMP_DATA_0 0x86 +#define HDD_IPV6_CMP_DATA_1 0xDD + +#define HDD_WLAN_MAC_ADDR_LEN 6 +#define HDD_MAX_NUM_MULTICAST_ADDRESS 10 + +typedef enum +{ + HDD_FILTER_PROTO_TYPE_INVALID = 0, + HDD_FILTER_PROTO_TYPE_MAC = 1, + HDD_FILTER_PROTO_TYPE_ARP = 2, + HDD_FILTER_PROTO_TYPE_IPV4 =3 , + HDD_FILTER_PROTO_TYPE_IPV6 = 4, + HDD_FILTER_PROTO_TYPE_UDP = 5, + HDD_FILTER_PROTO_TYPE_MAX +} eProtoLayer; + +typedef enum +{ + HDD_RCV_FILTER_INVALID = 0, + HDD_RCV_FILTER_SET = 1, + HDD_RCV_FILTER_CLEAR = 2, + HDD_RCV_FILTER_MAX +}eFilterAction; + +typedef enum +{ + HDD_FILTER_CMP_TYPE_INVALID = 0, + HDD_FILTER_CMP_TYPE_EQUAL = 1, + HDD_FILTER_CMP_TYPE_MASK_EQUAL = 2, + HDD_FILTER_CMP_TYPE_NOT_EQUAL = 3, + HDD_FILTER_CMP_TYPE_MASK_NOT_EQUAL = 4, + HDD_FILTER_CMP_TYPE_MAX +}eCompareFlag; + +struct PacketFilterParamsCfg +{ + v_U8_t protocolLayer; + v_U8_t cmpFlag; + v_U8_t dataOffset; + v_U8_t dataLength; + v_U8_t compareData[8]; + v_U8_t dataMask[8]; +}; + +typedef struct +{ + v_U8_t filterAction; + v_U8_t filterId; + v_U8_t numParams; + struct PacketFilterParamsCfg paramsData [HDD_MAX_CMP_PER_PACKET_FILTER]; +}tPacketFilterCfg, *tpPacketFilterCfg; + +typedef v_U8_t tHddMacAddr[HDD_WLAN_MAC_ADDR_LEN]; + +typedef struct +{ + v_U8_t mcastBcastFilterSetting; + v_U8_t mcast_addr_cnt; + tHddMacAddr multicastAddr[HDD_MAX_NUM_MULTICAST_ADDRESS]; +} tRcvFltMcAddrList, *tpRcvFltMcAddrList; + +#endif +#endif // __WLAN_HDD_PACKET_FILTERING_H__ diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_power.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_power.h new file mode 100644 index 000000000000..70c700ab4261 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_power.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_POWER_H +#define __WLAN_HDD_POWER_H + +/**=========================================================================== + + \file wlan_hdd_power.h + + \brief Linux HDD Power + + ==========================================================================*/ + + +/*-------------------------------------------------------------------------- + * Include Files + *------------------------------------------------------------------------*/ +#include "wlan_hdd_main.h" + +/*--------------------------------------------------------------------------- + * Preprocessor definitions and constants + *-------------------------------------------------------------------------*/ + //gEnableSuspend = 1 in INI file implies suspend to standby + #define WLAN_MAP_SUSPEND_TO_STANDBY 1 + + //gEnableSuspend = 2 in INI file implies suspend to deep sleep + #define WLAN_MAP_SUSPEND_TO_DEEP_SLEEP 2 + + //gEnableSuspend = 3 in INI file implies suspend to set MCAST/BCAST filter + #define WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER 3 + + //gEnableDriverStop = 1 implies map driver stop to standby + #define WLAN_MAP_DRIVER_STOP_TO_STANDBY 1 + + //gEnableDriverStop = 2 implies map sriver stop to deep sleep + #define WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP 2 + + //Maximum time (ms) to wait for standby to complete + #define WLAN_WAIT_TIME_STANDBY 3000 + + //Maximum time (ms) to wait for full pwr to complete + #define WLAN_WAIT_TIME_FULL_PWR 3000 + + +/*--------------------------------------------------------------------------- + * Type declarations + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function declarations and documentation + * ------------------------------------------------------------------------*/ + eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx); + VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, + hdd_adapter_t* pAdapter); + VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx); + VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, + hdd_adapter_t* pAdapter); +#ifdef CONFIG_HAS_EARLYSUSPEND + VOS_STATUS hdd_wlan_reset(void); + VOS_STATUS hdd_wlan_reset_initialization(void) ; +#endif + /* SSR shutdown & re-init functions */ + VOS_STATUS hdd_wlan_shutdown(void); + VOS_STATUS hdd_wlan_re_init(void); + +void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter); +VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t* pAdapter, int fenable); +/* + * Function: hdd_conf_hostoffload + * Central function to configure the supported offloads, + * either enable or disable them. + */ +void hdd_conf_hostoffload(hdd_adapter_t * pAdapter, v_BOOL_t fenable); +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable); +#endif +#ifdef WLAN_NS_OFFLOAD +void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable); +#endif + +int wlan_hdd_ipv4_changed(struct notifier_block *nb, + unsigned long data, void *arg); +int wlan_hdd_ipv6_changed(struct notifier_block *nb, + unsigned long data, void *arg); + +eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx, + bool value); +bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx); +void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action); + +/** + * enum suspend_resume_state - Suspend resume state + * @HDD_WLAN_EARLY_SUSPEND: Early suspend state. + * @HDD_WLAN_SUSPEND: Suspend state. + * @HDD_WLAN_EARLY_RESUME: Early resume state. + * @HDD_WLAN_RESUME: Resume state. + * + * Suspend state to indicate in diag event of suspend resume. + */ + +enum suspend_resume_state { + HDD_WLAN_EARLY_SUSPEND, + HDD_WLAN_SUSPEND, + HDD_WLAN_EARLY_RESUME, + HDD_WLAN_RESUME +}; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void hdd_wlan_suspend_resume_event(uint8_t state); +#else +static inline +void hdd_wlan_suspend_resume_event(uint8_t state) +{ + return; +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t* pHddCtx); + +#endif // if !defined __WLAN_QCT_DRIVER_H diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h new file mode 100644 index 000000000000..a41cc1cfdeda --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_softap_tx_rx.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_SOFTAP_TX_RX_H ) +#define WLAN_HDD_SOFTAP_TX_RX_H + +/**=========================================================================== + + \file wlan_hdd_softap_tx_rx.h + + \brief Linux HDD SOFTAP Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +#define HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN (82*2) +#define HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN (78*2) +#define HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN (74*2) +#define HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN (70*2) + +/* SoftAP specific AC Weights */ +#define HDD_SOFTAP_BK_WEIGHT_DEFAULT 1 +#define HDD_SOFTAP_BE_WEIGHT_DEFAULT 3 +#define HDD_SOFTAP_VI_WEIGHT_DEFAULT 8 +#define HDD_SOFTAP_VO_WEIGHT_DEFAULT 18 + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/**============================================================================ + @brief hdd_softap_get_connected_sta() - Function to get numbeer of connected + stations with softap + + @param pHostapdAdapter : [in] pointer to saftap adapter + + @return : Number of connected peer with softap + ===========================================================================*/ + +v_U8_t hdd_softap_get_connected_sta(hdd_adapter_t *pHostapdAdapter); + +/**============================================================================ + @brief hdd_softap_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra softap network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +extern int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); + +/**============================================================================ + @brief hdd_softap_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to Libra network device + @return : None + ===========================================================================*/ +extern void hdd_softap_tx_timeout(struct net_device *dev); + +/**============================================================================ + @brief hdd_softap_stats() - Function registered with the Linux OS for + device TX/RX statistics + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +extern struct net_device_stats* hdd_softap_stats(struct net_device *dev); + +/**============================================================================ + @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter, bool re_init); + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_deinit_tx_rx(hdd_adapter_t *pAdapter, + bool re_init); + +/**============================================================================ + @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @param pmacAddrSTA : [in] pointer to the MAC address of the station + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA); + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId ); + +/**============================================================================ + @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the SDIO bus + succesfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ); + +/**============================================================================ + @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ucAC : [in] pointer to access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ucAC, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ); + +/**============================================================================ + @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +extern VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ); + +/**============================================================================ + @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when a packet was received + for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (conatining sk_buff) + @param staId : [in] Station Id + @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s) + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + v_U8_t staId, + WLANTL_RxMetaInfoType* pRxMetaInfo ); + +/**============================================================================ + @brief hdd_softap_DeregisterSTA - Deregister a station from TL block + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deregister + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ); + +/**============================================================================ + @brief hdd_softap_RegisterSTA - Register a station into TL block + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deregister + @param fAuthRequired: [in] Station requires further security negotiation or not + @param fPrivacyBit : [in] privacy bit needs to be set or not + @param ucastSig : [in] Unicast Signature send to TL + @param bcastSig : [in] Broadcast Signature send to TL + @param pPeerMacAddress : [in] station MAC address + @param fWmmEnabled : [in] Wmm enabled sta or not + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter, + v_BOOL_t fAuthRequired, + v_BOOL_t fPrivacyBit, + v_U8_t staId, + v_U8_t ucastSig, + v_U8_t bcastSig, + v_MACADDR_t *pPeerMacAddress, + v_BOOL_t fWmmEnabled); + +/**============================================================================ + @brief hdd_softap_Register_BC_STA - Register a default broadcast station into TL block + + @param pAdapter : [in] pointer to adapter context + @param fPrivacyBit : [in] privacy bit needs to be set or not + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit); + +/**============================================================================ + @brief hdd_softap_DeregisterSTA - DeRegister the default broadcast station into TL block + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter); + +/**============================================================================ + @brief hdd_softap_stop_bss - Helper function to stop bss and do cleanup in HDD and TL + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pHostapdAdapter); + + +/**============================================================================ + @brief hdd_softap_change_STA_state - Helper function to change station state by MAC address + + @param pAdapter : [in] pointer to adapter context + @param pDestMacAddress : [in] pointer to station MAC address + @param state : [in] new station state + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state); + +/**============================================================================ + @brief hdd_softap_GetStaId - Helper function to get station Id from MAC address + + @param pAdapter : [in] pointer to adapter context + @param pDestMacAddress : [in] pointer to station MAC address + @param staId : [out] station id + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_GetStaId( hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId); + +/**============================================================================ + @brief hdd_softap_GetConnectedStaId - Helper function to get station Id of the connected device + + @param pAdapter : [in] pointer to adapter context + @param staId : [out] station id + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + =========================================================================== */ +extern VOS_STATUS hdd_softap_GetConnectedStaId( hdd_adapter_t *pAdapter, v_U8_t *staId); + +/**========================================================================== + + \brief hdd_start_trafficMonitor() - + This function dynamically enable traffic monitor functonality + the command iwpriv wlanX setTrafficMon . + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + + ========================================================================== */ +VOS_STATUS hdd_start_trafficMonitor(hdd_adapter_t *pAdapter, bool re_init); + +/**========================================================================== + + \brief hdd_stop_trafficMonitor() - + This function dynamically disable traffic monitor functonality + the command iwpriv wlanX setTrafficMon . + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + + ========================================================================== */ +VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter, bool re_init); + +#endif // end #if !defined( WLAN_HDD_SOFTAP_TX_RX_H ) diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h new file mode 100644 index 000000000000..c9731f1d9dc0 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tdls.h @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __HDD_TDSL_H +#define __HDD_TDSL_H +/**=========================================================================== + +\file wlan_hdd_tdls.h + +\brief Linux HDD TDLS include file +==========================================================================*/ + +#ifdef FEATURE_WLAN_TDLS + +#define MAX_NUM_TDLS_PEER 3 + +#define TDLS_SUB_DISCOVERY_PERIOD 100 + +#define TDLS_MAX_DISCOVER_REQS_PER_TIMER 1 + +#define TDLS_DISCOVERY_PERIOD 3600000 + +#define TDLS_TX_STATS_PERIOD 3600000 + +#define TDLS_IMPLICIT_TRIGGER_PKT_THRESHOLD 100 + +#define TDLS_RX_IDLE_TIMEOUT 5000 + +#define TDLS_RSSI_TRIGGER_HYSTERESIS 50 + +/* before UpdateTimer expires, we want to timeout discovery response. +should not be more than 2000 */ +#define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 + +#define TDLS_CTX_MAGIC 0x54444c53 // "TDLS" + +#define TDLS_MAX_SCAN_SCHEDULE 10 +#define TDLS_MAX_SCAN_REJECT 5 +#define TDLS_DELAY_SCAN_PER_CONNECTION 100 + +#define TDLS_IS_CONNECTED(peer) \ + ((eTDLS_LINK_CONNECTED == (peer)->link_status) || \ + (eTDLS_LINK_TEARING == (peer)->link_status)) + +/* TDLS Off Channel Bandwidth Offset */ +#define TDLS_OFF_CHANNEL_BW_OFFSET 0 + +/* TDLS Channel Switch Request */ +#define TDLS_CHANNEL_SWITCH_ENABLE 1 +#define TDLS_CHANNEL_SWITCH_DISABLE 2 + +enum tdls_disable_source { + HDD_SET_TDLS_MODE_SOURCE_USER = 1, + HDD_SET_TDLS_MODE_SOURCE_SCAN = 2, + HDD_SET_TDLS_MODE_SOURCE_OFFCHANNEL = 4, + HDD_SET_TDLS_MODE_SOURCE_BTC = 8, + HDD_SET_TDLS_MODE_SOURCE_P2P = 16 +}; + +typedef struct +{ + tANI_U32 tdls; + tANI_U32 tx_period_t; + tANI_U32 tx_packet_n; + tANI_U32 discovery_period_t; + tANI_U32 discovery_tries_n; + tANI_U32 idle_timeout_t; + tANI_U32 idle_packet_n; + tANI_U32 rssi_hysteresis; + tANI_S32 rssi_trigger_threshold; + tANI_S32 rssi_teardown_threshold; +} tdls_config_params_t; + +typedef enum { + eTDLS_SUPPORT_NOT_ENABLED = 0, + eTDLS_SUPPORT_DISABLED, /* suppress implicit trigger and not respond to the peer */ + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY, /* suppress implicit trigger, but respond to the peer */ + eTDLS_SUPPORT_ENABLED, /* implicit trigger */ +} eTDLSSupportMode; + +typedef enum eTDLSCapType{ + eTDLS_CAP_NOT_SUPPORTED = -1, + eTDLS_CAP_UNKNOWN = 0, + eTDLS_CAP_SUPPORTED = 1, +} tTDLSCapType; + +typedef enum eTDLSLinkStatus { + eTDLS_LINK_IDLE = 0, + eTDLS_LINK_DISCOVERING, + eTDLS_LINK_DISCOVERED, + eTDLS_LINK_CONNECTING, + eTDLS_LINK_CONNECTED, + eTDLS_LINK_TEARING, +} tTDLSLinkStatus; + +/** + * enum tdls_teardown_reason - Reason for TDLS teardown + * @eTDLS_TEARDOWN_EXT_CTRL: Reason ext ctrl. + * @eTDLS_TEARDOWN_CONCURRENCY: Reason concurrency. + * @eTDLS_TEARDOWN_RSSI_THRESHOLD: Reason rssi threashold. + * @eTDLS_TEARDOWN_TXRX_THRESHOLD: Reason txrx threashold. + * @eTDLS_TEARDOWN_BTCOEX: Reason BTCOEX. + * @eTDLS_TEARDOWN_SCAN: Reason scan. + * @eTDLS_TEARDOWN_BSS_DISCONNECT: Reason bss disconnected. + * + * Reason to indicate in diag event of tdls teardown. + */ + +enum tdls_teardown_reason { + eTDLS_TEARDOWN_EXT_CTRL, + eTDLS_TEARDOWN_CONCURRENCY, + eTDLS_TEARDOWN_RSSI_THRESHOLD, + eTDLS_TEARDOWN_TXRX_THRESHOLD, + eTDLS_TEARDOWN_BTCOEX, + eTDLS_TEARDOWN_SCAN, + eTDLS_TEARDOWN_BSS_DISCONNECT, +}; + +typedef enum { + eTDLS_LINK_SUCCESS, /* Success */ + eTDLS_LINK_UNSPECIFIED = -1, /* Unspecified reason */ + eTDLS_LINK_NOT_SUPPORTED = -2, /* Remote side doesn't support TDLS */ + eTDLS_LINK_UNSUPPORTED_BAND = -3, /* Remote side doesn't support this band */ + eTDLS_LINK_NOT_BENEFICIAL = -4, /* Going to AP is better than going direct */ + eTDLS_LINK_DROPPED_BY_REMOTE = -5 /* Remote side doesn't want it anymore */ +} tTDLSLinkReason; + +typedef struct { + int channel; /* channel hint, in channel number (NOT frequency ) */ + int global_operating_class; /* operating class to use */ + int max_latency_ms; /* max latency that can be tolerated by apps */ + int min_bandwidth_kbps; /* bandwidth required by apps, in kilo bits per second */ +} tdls_req_params_t; + +typedef enum { + WIFI_TDLS_DISABLED, /* TDLS is not enabled, or is disabled now */ + WIFI_TDLS_ENABLED, /* TDLS is enabled, but not yet tried */ + WIFI_TDLS_TRYING, /* Direct link is being attempted (optional) */ + WIFI_TDLS_ESTABLISHED, /* Direct link is established */ + WIFI_TDLS_ESTABLISHED_OFF_CHANNEL, /* Direct link is established using MCC */ + WIFI_TDLS_DROPPED, /* Direct link was established, but is now dropped */ + WIFI_TDLS_FAILED /* Direct link failed */ +} tdls_state_t; + +typedef int (*cfg80211_exttdls_callback)( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8* mac, +#else + tANI_U8* mac, +#endif + tANI_S32 state, + tANI_S32 reason, + void *ctx); +typedef struct { + tANI_U16 period; + tANI_U16 bytes; +} tdls_tx_tput_config_t; + +typedef struct { + tANI_U16 period; + tANI_U16 tries; +} tdls_discovery_config_t; + +typedef struct { + tANI_U16 timeout; +} tdls_rx_idle_config_t; + +typedef struct { + tANI_U16 rssi_thres; +} tdls_rssi_config_t; + +struct _hddTdlsPeer_t; + +typedef struct { + struct list_head peer_list[256]; + hdd_adapter_t *pAdapter; +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_t peerDiscoverTimer; +#endif + vos_timer_t peerUpdateTimer; + vos_timer_t peerDiscoveryTimeoutTimer; + tdls_config_params_t threshold_config; + tANI_S32 discovery_peer_cnt; + tANI_U32 discovery_sent_cnt; + tANI_S8 ap_rssi; + struct _hddTdlsPeer_t *curr_candidate; + struct work_struct implicit_setup; + bool is_tdls_disabled_bmps; + v_U32_t magic; +} tdlsCtx_t; + +typedef struct _hddTdlsPeer_t { + struct list_head node; + tdlsCtx_t *pHddTdlsCtx; + tSirMacAddr peerMac; + tANI_U16 staId ; + tANI_S8 rssi; + tTDLSCapType tdls_support; + tTDLSLinkStatus link_status; + tANI_U8 signature; + tANI_U8 is_responder; + tANI_U8 discovery_processed; + tANI_U16 discovery_attempt; + tANI_U16 tx_pkt; + tANI_U16 rx_pkt; + tANI_U8 uapsdQueues; + tANI_U8 qos; + tANI_U8 maxSp; + tANI_U8 isBufSta; + tANI_U8 isOffChannelSupported; + tANI_U8 supported_channels_len; + tANI_U8 supported_channels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supported_oper_classes_len; + tANI_U8 supported_oper_classes[SIR_MAC_MAX_SUPP_OPER_CLASSES]; + vos_timer_t peerIdleTimer; + vos_timer_t initiatorWaitTimeoutTimer; + tANI_BOOLEAN isForcedPeer; + /*EXT TDLS*/ + tTDLSLinkReason reason; + cfg80211_exttdls_callback state_change_notification; + tANI_BOOLEAN isOffChannelConfigured; + tANI_BOOLEAN isOffChannelEstablished; + tdls_req_params_t peerParams; +} hddTdlsPeer_t; + +typedef struct { + /* Session ID */ + tANI_U8 sessionId; + /*TDLS peer station id */ + v_U8_t staId; + /* TDLS peer mac Address */ + v_MACADDR_t peerMac; +} tdlsConnInfo_t; + +int wlan_hdd_sta_tdls_init(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_init(hdd_context_t * pHddCtx); + +void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter, tANI_BOOLEAN mutexLock); + +void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac); + +void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac); + +int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + u8 staId); + +hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, + const u8 *mac, + tANI_BOOLEAN mutexLock); + +hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac +#else + u8 *mac +#endif +); + +int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams); +hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac +#else + u8 *mac +#endif + ); + +int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8* mac, +#else + u8* mac, +#endif + tTDLSCapType cap); + +void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, + tTDLSLinkStatus status, + tTDLSLinkReason reason); +void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tTDLSLinkStatus linkStatus, + tTDLSLinkReason reason); + +int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac); + +int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tCsrStaParams *StaParams, + tANI_BOOLEAN isBufSta, + tANI_BOOLEAN isOffChannelSupported, + tANI_BOOLEAN isQosWmmSta); + +int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_S8 rxRssi); + +int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_U8 responder); + +int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_U8 uSignature); + +int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config); + +int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac +#else + u8 *mac +#endif + ); + +tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter); + +int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen); + +void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode); + +void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter); + +hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + u8 skip_self, tANI_BOOLEAN mutexLock); + +void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode, + v_BOOL_t bUpdateLast, + enum tdls_disable_source source); + +tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx); + +void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter); + +int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request); + +void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter); + +void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter, + vos_timer_t *timer, + v_U32_t expirationTime); +void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter, + hddTdlsPeer_t *curr_peer, + tANI_U16 reason); +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void hdd_send_wlan_tdls_teardown_event(uint32_t reason, + uint8_t *peer_mac); +void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, + uint8_t is_off_chan_supported, + uint8_t is_off_chan_configured, + uint8_t is_off_chan_established); +void hdd_wlan_block_scan_by_tdls(void); + +#else +static inline +void hdd_send_wlan_tdls_teardown_event(uint32_t reason, + uint8_t *peer_mac) +{ + return; +} +static inline +void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, + uint8_t is_off_chan_supported, + uint8_t is_off_chan_configured, + uint8_t is_off_chan_established) +{ + return; +} +static inline +void hdd_wlan_block_scan_by_tdls(void) +{ + return; +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_BOOLEAN forcePeer); +int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *peer +#else + u8 *peer +#endif +); +int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *peer, +#else + u8 *peer, +#endif + tdls_req_params_t *tdls_peer_params, + cfg80211_exttdls_callback callback); +void hdd_tdls_notify_mode_change(hdd_adapter_t *pAdapter, + hdd_context_t *pHddCtx); +void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *pHddCtx); +/*EXT TDLS*/ +int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8* mac, +#else + tANI_U8* mac, +#endif + tANI_S32 *state, + tANI_S32 *reason); +void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, + tANI_S32 *state, + tANI_S32 *reason); +int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, + cfg80211_exttdls_callback callback); +int hdd_set_tdls_scan_type(hdd_adapter_t *pAdapter, + tANI_U8 *ptr); + +// tdlsoffchan +hddTdlsPeer_t *wlan_hdd_tdls_get_connected_peer(hdd_adapter_t *pAdapter); + +int wlan_hdd_validate_tdls_context(hdd_context_t *pHddCtx, tdlsCtx_t *pTdlsCtx); + +void wlan_hdd_tdls_reenable(hdd_context_t *pHddCtx); + +void wlan_hdd_tdls_notify_packet(hdd_adapter_t *adapter, struct sk_buff *skb); + +void wlan_hdd_change_tdls_mode(void *hdd_ctx); + +void wlan_hdd_start_stop_tdls_source_timer(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode); +#else +static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *pAdapter, + hdd_context_t *pHddCtx) +{ +} +static inline void +wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *pHddCtx) +{ +} +static inline void +wlan_hdd_tdls_reenable(hdd_context_t *pHddCtx) +{ +} +static inline void +wlan_hdd_tdls_notify_packet(hdd_adapter_t *adapter, struct sk_buff *skb) +{ +} +static inline void +wlan_hdd_change_tdls_mode(void *hdd_ctx) +{ +} + +static inline void +wlan_hdd_start_stop_tdls_source_timer(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode) +{ +} +#endif +void wlan_hdd_tdls_update_rx_pkt_cnt_n_rssi(hdd_adapter_t *pAdapter, + u8 *mac, v_S7_t rssiAvg); + + +tdlsConnInfo_t *wlan_hdd_get_conn_info(hdd_context_t *pHddCtx, + tANI_U8 idx); + +v_VOID_t wlan_hdd_tdls_initiator_wait_cb(v_PVOID_t userData); + +void wlan_hdd_get_tdls_stats(hdd_adapter_t *pAdapter); + +#endif // __HDD_TDSL_H diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_trace.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_trace.h new file mode 100644 index 000000000000..b12c6a37ef98 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_trace.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_HDD_TRACE_H__ +#define __WLAN_HDD_TRACE_H__ + +#include "macTrace.h" + +#define NO_SESSION 0xFF +#define TRACE_CODE_HDD_RX_SME_MSG 0xFF + +enum +{ + TRACE_CODE_HDD_OPEN_REQUEST, + TRACE_CODE_HDD_STOP_REQUEST, + TRACE_CODE_HDD_TX_TIMEOUT, + TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL, + TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL, + TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL, + TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL, + TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL, + TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL, + TRACE_CODE_HDD_SETROAMDELTA_IOCTL, + TRACE_CODE_HDD_GETROAMDELTA_IOCTL, + TRACE_CODE_HDD_GETBAND_IOCTL, + TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL, + TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL, + TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL, + TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, + TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST, + TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST, + TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT, + TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR, + TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL, + TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL, + TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL, + TRACE_CODE_HDD_ADD_VIRTUAL_INTF, + TRACE_CODE_HDD_DEL_VIRTUAL_INTF, + TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF, + TRACE_CODE_HDD_CFG80211_START_AP, + TRACE_CODE_HDD_CFG80211_CHANGE_BEACON, + TRACE_CODE_HDD_CFG80211_STOP_AP, + TRACE_CODE_HDD_CFG80211_CHANGE_BSS, + TRACE_CODE_HDD_CFG80211_ADD_KEY, + TRACE_CODE_HDD_CFG80211_GET_KEY, + TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, + TRACE_CODE_HDD_CFG80211_CONNECT, + TRACE_CODE_HDD_CFG80211_DISCONNECT, + TRACE_CODE_HDD_CFG80211_JOIN_IBSS, + TRACE_CODE_HDD_CFG80211_LEAVE_IBSS, + TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS, + TRACE_CODE_HDD_CFG80211_SET_TXPOWER, + TRACE_CODE_HDD_CFG80211_GET_TXPOWER, + TRACE_CODE_HDD_CFG80211_SET_CHANNEL, + TRACE_CODE_HDD_CFG80211_ADD_BEACON, + TRACE_CODE_HDD_CFG80211_SET_BEACON, + TRACE_CODE_HDD_CFG80211_CHANGE_IFACE, + TRACE_CODE_HDD_CHANGE_STATION, + TRACE_CODE_HDD_CFG80211_UPDATE_BSS, + TRACE_CODE_HDD_CFG80211_SCAN, + TRACE_CODE_HDD_REMAIN_ON_CHANNEL, + TRACE_CODE_HDD_REMAINCHANREADYHANDLER, + TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL, + TRACE_CODE_HDD_ACTION, + TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, + TRACE_CODE_HDD_CFG80211_GET_STA, + TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT, + TRACE_CODE_HDD_CFG80211_DEL_STA, + TRACE_CODE_HDD_CFG80211_ADD_STA, + TRACE_CODE_HDD_CFG80211_SET_PMKSA, + TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES, + TRACE_CODE_HDD_CFG80211_TDLS_MGMT, + TRACE_CODE_HDD_CFG80211_TDLS_OPER, + TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA, + TRACE_CODE_HDD_UNSUPPORTED_IOCTL, + TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL, + TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL, + TRACE_CODE_HDD_STOP_NETDEV, + TRACE_CODE_HDD_WAKE_NETDEV, + TRACE_CODE_HDD_FLUSH_TX_QUEUES, + TRACE_CODE_HDD_CFG80211_RESUME_WLAN, + TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN, + TRACE_CODE_HDD_CFG80211_SET_MAC_ACL, + TRACE_CODE_HDD_CFG80211_TESTMODE, + TRACE_CODE_HDD_CFG80211_DUMP_SURVEY, + TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START, + TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP, + TRACE_CODE_HDD_CFG80211_DEL_PMKSA, +}; + +extern void hddTraceDump(void *pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex); +extern void hddTraceInit(void); +void hdd_register_debug_callback(void); + +#endif + + diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h new file mode 100644 index 000000000000..06c5accb2ff8 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_HDD_TX_RX_H ) +#define WLAN_HDD_TX_RX_H + +/**=========================================================================== + + \file wlan_hdd_tx_rx.h + + \brief Linux HDD Tx/RX APIs + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ +#define HDD_ETHERTYPE_802_1_X ( 0x888E ) +#define HDD_ETHERTYPE_802_1_X_FRAME_OFFSET ( 12 ) +#define HDD_ETHERTYPE_802_1_X_SIZE ( 2 ) +#ifdef FEATURE_WLAN_WAPI +#define HDD_ETHERTYPE_WAI ( 0x88b4 ) +#endif +#define HDD_ETHERTYPE_ARP ( 0x0806 ) +#define HDD_ETHERTYPE_ARP_SIZE 42 + +#define HDD_80211_HEADER_LEN 24 +#define HDD_80211_HEADER_QOS_CTL 2 +#define HDD_LLC_HDR_LEN 6 +#define HDD_FRAME_TYPE_MASK 0x0c +#define HDD_FRAME_SUBTYPE_MASK 0xf0 +#define HDD_FRAME_TYPE_DATA 0x08 +#define HDD_FRAME_TYPE_MGMT 0x00 +#define HDD_FRAME_SUBTYPE_QOSDATA 0x80 +#define HDD_FRAME_SUBTYPE_DEAUTH 0xC0 +#define HDD_FRAME_SUBTYPE_DISASSOC 0xA0 +#define HDD_DEST_ADDR_OFFSET 6 + +#define HDD_MAC_HDR_SIZE 6 + +#define HDD_PSB_CFG_INVALID 0xFF +#define HDD_PSB_CHANGED 0xFF +#define SME_QOS_UAPSD_CFG_BK_CHANGED_MASK 0xF1 +#define SME_QOS_UAPSD_CFG_BE_CHANGED_MASK 0xF2 +#define SME_QOS_UAPSD_CFG_VI_CHANGED_MASK 0xF4 +#define SME_QOS_UAPSD_CFG_VO_CHANGED_MASK 0xF8 + +#define HDD_ETH_HEADER_LEN 14 + +/* WLAN_DHCP_DEBUG */ +#define RX_PATH ( 0 ) +#define TX_PATH ( 1 ) + +#define BOOTP_SERVER_PORT ( 67 ) +#define BOOTP_CLIENT_PORT ( 68 ) + +#define ETH_TYPE_OFFSET ( 12 ) +#define ETH_TYPE_IP_PKT ( 0x0800 ) +#define BOOTP_MSG_OFFSET ( 42 ) +#define BOOTP_REQUEST_MSG ( 1 ) +#define BOOTP_RESPONSE_MSG ( 2 ) + +#define DHCPDISCOVER ( 1 ) +#define DHCPOFFER ( 2 ) +#define DHCPREQUEST ( 3 ) +#define DHCPACK ( 5 ) +#define DHCPNAK ( 6 ) +#define DHCPRELEASE ( 7 ) +#define DHCPINFORM ( 8 ) + +#define SKB_MIN_LENGTH ( 35 ) +#define PROTOCOL_OFFSET ( 9 ) +#define UDP_PROTOCOL ( 17 ) + +#define UDP_SRC_PORT_OFFSET ( 34 ) +#define UDP_DEST_PORT_OFFSET ( 36 ) + +#define DHCP_OPTION53 ( 0x35 ) +#define DHCP_OPTION53_LENGTH ( 1 ) +#define DHCP_OPTION53_OFFSET ( 0x11A ) +#define DHCP_OPTION53_LENGTH_OFFSET ( 0x11B ) +#define DHCP_OPTION53_STATUS_OFFSET ( 0x11C ) +/* WLAN_DHCP_DEBUG */ + +#define TID3 0x60 + + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ +/**============================================================================ + @brief hdd_ibss_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets in IBSS mode. + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +extern int hdd_ibss_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); + +/**============================================================================ + @brief hdd_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +extern int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); + +extern int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); +/**============================================================================ + @brief hdd_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to Libra network device + @return : None + ===========================================================================*/ +extern void hdd_tx_timeout(struct net_device *dev); + +/**============================================================================ + @brief hdd_stats() - Function registered with the Linux OS for + device TX/RX statistics + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +extern struct net_device_stats* hdd_stats(struct net_device *dev); + +/**============================================================================ + @brief hdd_ibss_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern void hdd_ibss_init_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_ibss_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context.. + @return : VOS_STATUS_E_FAILURE if any errors encountered. + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_ibss_deinit_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the SDIO bus + succesfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ); + +/**============================================================================ + @brief hdd_ibss_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ucAC : [in] pointer to access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_ibss_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ucAC, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ); + +/**============================================================================ + @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ucAC : [in] pointer to access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ucAC, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ); + +/**============================================================================ + @brief hdd_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +extern VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ); + +extern VOS_STATUS hdd_rx_packet_monitor_cbk(v_VOID_t *vosContext,vos_pkt_t *pVosPacket, int conversion); + +/**============================================================================ + @brief hdd_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when a packet was received + for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (conatining sk_buff) + @param staId : [in] Station Id + @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s) + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +extern VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + v_U8_t staId, + WLANTL_RxMetaInfoType* pRxMetaInfo ); + + +/**============================================================================ + @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is EAPOL + : VOS_FALSE otherwise + ===========================================================================*/ +extern v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ); + +/**============================================================================ + @brief hdd_mon_tx_mgmt_pkt() - Transmit MGMT packet received on monitor + interface. + + @param pAdapter: [in] SAP/P2P GO adapter. + ===========================================================================*/ +void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter); + +/**============================================================================ + @brief hdd_mon_tx_work_queue() - workqueue handler for transmitting mgmt packets.. + + @param work: [in] workqueue structure. + ===========================================================================*/ +void hdd_mon_tx_work_queue(struct work_struct *work); + +/**============================================================================ + @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address + @param pHddStaCtx : [in] pointer to HDD Station Context + pMacAddress [in] pointer to Peer Mac address + staID [out] pointer to Station Index + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ +VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, + v_MACADDR_t *pMacAddress, v_U8_t *staId); + +/**============================================================================ + @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() - + Timer handler to check enable/disable split scan + @param pHddStaCtx : Hdd adapter + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ +void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *pAdapter); + +/**============================================================================ + @brief hdd_flush_ibss_tx_queues() - + Flush tx queues in IBSS mode + @param pAdapter: Hdd adapter + @param STAId: Sta index + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ +void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId); + +/**========================================================================= + @brief hdd_wmm_acquire_access_required()- + Determine whether wmm ac acquire access is required + @param pAdapter : pointer to Adapter context + @param acType : AC + @return : void + ========================================================================*/ +void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter, + WLANTL_ACEnumType acType); + +/**========================================================================= + @brief hdd_dump_dhcp_pkt()- For printing DHCP logs + @param skb : pointer to skb + @param path : path direction + @return : void + ========================================================================*/ +void hdd_dump_dhcp_pkt(struct sk_buff *skb, int path); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * wlan_hdd_log_eapol() - Function to check and extract EAPOL params + * @skb: skb data + * @event_type: One of enum wifi_connectivity_events to indicate Tx/Rx + * + * This function parses the input skb data to get the EAPOL params,if the + * packet is EAPOL and store it in the pointer passed as input + * + * Return: None + * + */ +void wlan_hdd_log_eapol(struct sk_buff *skb, + uint8_t event_type); +#else +static inline void wlan_hdd_log_eapol(struct sk_buff *skb, + uint8_t event_type) +{ +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +/** + * hdd_rx_fwd_eapol() - forward cached eapol frames + * @vosContext : pointer to vos global context + * @pVosPacket: pointer to vos packet + * + * Return: None + * + */ +void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket); + +#endif // end #if !defined( WLAN_HDD_TX_RX_H ) diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_version.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_version.h new file mode 100644 index 000000000000..f81514dfbe09 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_version.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//================================================================== +// +// File: hdd_Version.h +// +// Description: Miniport driver version information +// +// Author: Larry Cawley +// +// Copyright 2007, QUALCOMM, Inc. All rights reserved. +// +//=================================================================== +#if !defined( __hddVersion_h__ ) +#define __hddVersion_h__ + +// force string expansion from chars +#define strEXPAND(x) #x +#define strSTRING(x) strEXPAND(x) +#define strVERSION( _mj, _mn, _sfx, _build ) strSTRING(_mj) "." strSTRING(_mn) "." strSTRING(_sfx) "." strSTRING(_build) + + +#if defined( BLD_REL ) +#define HDD_DRIVER_MAJOR_VERSION BLD_REL +#else +#define HDD_DRIVER_MAJOR_VERSION 0 +#endif + +#if defined( BLD_VER ) +#define HDD_DRIVER_MINOR_VERSION BLD_VER +#else +#define HDD_DRIVER_MINOR_VERSION 0 +#endif + +#if defined( BLD_SFX ) +#define HDD_DRIVER_SUFFIX BLD_SFX +#else +#define HDD_DRIVER_SUFFIX 0 +#endif + +#if defined( BLD_NUM ) +#define HDD_DRIVER_BUILD BLD_NUM +#else +#define HDD_DRIVER_BUILD 0000 +#endif +#define HDD_BUILD_DATETIME __DATE__ " " __TIME__ + +#define HDD_DRIVER_VERSION WNI_DRIVER_MAJOR_VERSION,WNI_DRIVER_MINOR_VERSION + +#define HDD_DRIVER_VERSION_STR strVERSION( WNI_DRIVER_MAJOR_VERSION, WNI_DRIVER_MINOR_VERSION, WNI_DRIVER_SUFFIX, WNI_DRIVER_BUILD ) + +#define HDD_COMPANYNAME_FULL "QUALCOMM, Inc." +#define HDD_DRIVER_DESCRIPTION "QUALCOMM Gen6 802.11n Wireless Adapter" +#define OEM_FILEDESCRIPTION_STR ANI_DRIVER_DESCRIPTION + +#define OEM_COMPANYNAME_STR ANI_COMPANYNAME_FULL + +#define OEM_INTERNALNAME_STR "WLAN_QCT_DRV.dll" +#define OEM_INTERNALNAME_STR2 "WLAN_QCT_DRV.dll" +#define OEM_ORIGINALFILENAME_STR "WLAN_QCT_DRV.dll" + +#define OEM_LEGALCOPYRIGHT_YEARS "2008" +#define OEM_LEGALCOPYRIGHT_STR "Copyright \251 " OEM_COMPANYNAME_STR "," OEM_LEGALCOPYRIGHT_YEARS +#define OEM_PRODUCTNAME_STR HDD_DRIVER_DESCRIPTION + +#define OEM_PRODUCTVERSION HDD_DRIVER_VERSION +#define OEM_FILEVERSION_STR HDD_DRIVER_VERSION_STR +#define OEM_FILEVERSION HDD_DRIVER_MAJOR_VERSION,HDD_DRIVER_MINOR_VERSION,HDD_DRIVER_SUFFIX,HDD_DRIVER_BUILD +#define OEM_PRODUCTVERSION_STR HDD_DRIVER_VERSION_STR + + +#endif // __hddVersion_h__ diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h new file mode 100644 index 000000000000..1a58dc027fdb --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wext.h @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WEXT_IW_H__ +#define __WEXT_IW_H__ + +#include +#include +#include +#include +#include +#include +#include "vos_event.h" + +/* + * order of parameters in addTs private ioctl + */ +#define HDD_WLAN_WMM_PARAM_HANDLE 0 +#define HDD_WLAN_WMM_PARAM_TID 1 +#define HDD_WLAN_WMM_PARAM_DIRECTION 2 +#define HDD_WLAN_WMM_PARAM_APSD 3 +#define HDD_WLAN_WMM_PARAM_USER_PRIORITY 4 +#define HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE 5 +#define HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE 6 +#define HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE 7 +#define HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE 8 +#define HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE 9 +#define HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE 10 +#define HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE 11 +#define HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE 12 +#define HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL 13 +#define HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL 14 +#define HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN 15 +#define HDD_WLAN_WMM_PARAM_ACK_POLICY 16 +#define HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL 17 +#define HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL 18 +#define HDD_WLAN_WMM_PARAM_COUNT 19 + +#define MHZ 6 + +#define WE_MAX_STR_LEN 1024 +#define WLAN_HDD_UI_BAND_AUTO 0 +#define WLAN_HDD_UI_BAND_5_GHZ 1 +#define WLAN_HDD_UI_BAND_2_4_GHZ 2 +/* SETBAND x */ +/* 012345678 */ +#define WLAN_HDD_UI_SET_BAND_VALUE_OFFSET 8 + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +/* 41 - STA support with Virtual STA feature + * 1 - Broadcast STA + * 4 - reserved Self STA: ap_self_sta, wlan_self_sta, + * wlan_peer_sta, p2p_self_sta + * 4 - General Purpose Stations to support Virtual STAs + */ +#define VSTA_NUM_STA 41 +#define VSTA_NUM_RESV_SELFSTA 4 +#define VSTA_NUM_BC_STA 1 +#define VSTA_NUM_GPSTA 4 +#define VSTA_NUM_ASSOC_STA (VSTA_NUM_STA - VSTA_NUM_RESV_SELFSTA -\ + VSTA_NUM_BC_STA - VSTA_NUM_GPSTA ) +#endif + +/* 12 - STA support without Virtual STA feature + * 1 - Broadcast STA + * 1 - reserved Self STA: ap_self_sta or wlan_self_sta, + */ +#define NUM_STA 12 +#define NUM_RESV_SELFSTA 1 +#define NUM_BC_STA 1 +#define NUM_ASSOC_STA (NUM_STA - NUM_RESV_SELFSTA - NUM_BC_STA) + +typedef enum +{ + HDD_WLAN_WMM_DIRECTION_UPSTREAM = 0, + HDD_WLAN_WMM_DIRECTION_DOWNSTREAM = 1, + HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL = 2, +} hdd_wlan_wmm_direction_e; + +typedef enum +{ + HDD_WLAN_WMM_POWER_SAVE_LEGACY = 0, + HDD_WLAN_WMM_POWER_SAVE_UAPSD = 1, +} hdd_wlan_wmm_power_save_e; + +typedef enum +{ + // TSPEC/re-assoc done, async + HDD_WLAN_WMM_STATUS_SETUP_SUCCESS = 0, + // no need to setup TSPEC since ACM=0 and no UAPSD desired, sync + async + HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD = 1, + // no need to setup TSPEC since ACM=0 and UAPSD already exists, sync + async + HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING = 2, + // TSPEC result pending, sync + HDD_WLAN_WMM_STATUS_SETUP_PENDING = 3, + // TSPEC/re-assoc failed, sync + async + HDD_WLAN_WMM_STATUS_SETUP_FAILED = 4, + // Request rejected due to invalid params, sync + async + HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM = 5, + // TSPEC request rejected since AP!=QAP, sync + HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM = 6, + + // TSPEC modification/re-assoc successful, async + HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS = 7, + // TSPEC modification a no-op since ACM=0 and no change in UAPSD, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD = 8, + // TSPEC modification a no-op since ACM=0 and requested U-APSD already exists, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING = 9, + // TSPEC result pending, sync + HDD_WLAN_WMM_STATUS_MODIFY_PENDING = 10, + // TSPEC modification failed, prev TSPEC in effect, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_FAILED = 11, + // TSPEC modification request rejected due to invalid params, sync + async + HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM = 12, + + // TSPEC release successful, sync and also async + HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS = 13, + // TSPEC release pending, sync + HDD_WLAN_WMM_STATUS_RELEASE_PENDING = 14, + // TSPEC release failed, sync + async + HDD_WLAN_WMM_STATUS_RELEASE_FAILED = 15, + // TSPEC release rejected due to invalid params, sync + HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM = 16, + // TSPEC modified due to the mux'ing of requests on ACs, async + + HDD_WLAN_WMM_STATUS_MODIFIED = 17, + // TSPEC revoked by AP, async + HDD_WLAN_WMM_STATUS_LOST = 18, + // some internal failure like memory allocation failure, etc, sync + HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE = 19, + + // U-APSD failed during setup but OTA setup (whether TSPEC exchnage or + // re-assoc) was done so app should release this QoS, async + HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED = 20, + // U-APSD failed during modify, but OTA setup (whether TSPEC exchnage or + // re-assoc) was done so app should release this QoS, async + HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED = 21 + +} hdd_wlan_wmm_status_e; + +/** TS Info Ack Policy */ +typedef enum +{ + HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK = 0, + HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 1, +} hdd_wlan_wmm_ts_info_ack_policy_e; + +/** vendor element ID */ +#define IE_EID_VENDOR ( 221 ) /* 0xDD */ +#define IE_LEN_SIZE 1 +#define IE_EID_SIZE 1 +#define IE_VENDOR_OUI_SIZE 4 + +/** Maximum Length of WPA/RSN IE */ +#define MAX_WPA_RSN_IE_LEN 40 + +/** Maximum Number of WEP KEYS */ +#define MAX_WEP_KEYS 4 + +/** Ether Address Length */ +#define ETHER_ADDR_LEN 6 + +/** Enable 11d */ +#define ENABLE_11D 1 + +/** Disable 11d */ +#define DISABLE_11D 0 + +/* + refer wpa.h in wpa supplicant code for REASON_MICHAEL_MIC_FAILURE + + supplicant sets REASON_MICHAEL_MIC_FAILURE as the reason code when it sends the MLME deauth IOCTL + for TKIP counter measures +*/ +#define HDD_REASON_MICHAEL_MIC_FAILURE 14 + +/* + * These are for TLV fields in WPS IE + */ +#define HDD_WPS_UUID_LEN 16 +#define HDD_WPS_ELEM_VERSION 0x104a +#define HDD_WPS_ELEM_REQUEST_TYPE 0x103a +#define HDD_WPS_ELEM_CONFIG_METHODS 0x1008 +#define HDD_WPS_ELEM_UUID_E 0x1047 +#define HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE 0x1054 +#define HDD_WPS_ELEM_RF_BANDS 0x103c +#define HDD_WPS_ELEM_ASSOCIATION_STATE 0x1002 +#define HDD_WPS_ELEM_CONFIGURATION_ERROR 0x1009 +#define HDD_WPS_ELEM_DEVICE_PASSWORD_ID 0x1012 + +#define HDD_WPA_ELEM_VENDOR_EXTENSION 0x1049 + +#define HDD_WPS_MANUFACTURER_LEN 64 +#define HDD_WPS_MODEL_NAME_LEN 32 +#define HDD_WPS_MODEL_NUM_LEN 32 +#define HDD_WPS_SERIAL_NUM_LEN 32 +#define HDD_WPS_DEVICE_OUI_LEN 4 +#define HDD_WPS_DEVICE_NAME_LEN 32 + +#define HDD_WPS_ELEM_WPS_STATE 0x1044 +#define HDD_WPS_ELEM_APSETUPLOCK 0x1057 +#define HDD_WPS_ELEM_SELECTEDREGISTRA 0x1041 +#define HDD_WPS_ELEM_RSP_TYPE 0x103B +#define HDD_WPS_ELEM_MANUFACTURER 0x1021 +#define HDD_WPS_ELEM_MODEL_NAME 0x1023 +#define HDD_WPS_ELEM_MODEL_NUM 0x1024 +#define HDD_WPS_ELEM_SERIAL_NUM 0x1042 +#define HDD_WPS_ELEM_DEVICE_NAME 0x1011 +#define HDD_WPS_ELEM_REGISTRA_CONF_METHODS 0x1053 + + + +#define WPS_OUI_TYPE "\x00\x50\xf2\x04" +#define WPS_OUI_TYPE_SIZE 4 + +#define SS_OUI_TYPE "\x00\x16\x32" +#define SS_OUI_TYPE_SIZE 3 + +#define P2P_OUI_TYPE "\x50\x6f\x9a\x09" +#define P2P_OUI_TYPE_SIZE 4 + +#define HS20_OUI_TYPE "\x50\x6f\x9a\x10" +#define HS20_OUI_TYPE_SIZE 4 + +#define OSEN_OUI_TYPE "\x50\x6f\x9a\x12" +#define OSEN_OUI_TYPE_SIZE 4 + +#ifdef WLAN_FEATURE_WFD +#define WFD_OUI_TYPE "\x50\x6f\x9a\x0a" +#define WFD_OUI_TYPE_SIZE 4 +#endif + +typedef enum +{ + eWEXT_WPS_OFF = 0, + eWEXT_WPS_ON = 1, +}hdd_wps_mode_e; + +typedef enum +{ + DRIVER_POWER_MODE_AUTO = 0, + DRIVER_POWER_MODE_ACTIVE = 1, +} hdd_power_mode_e; + +typedef enum +{ + WEXT_SCAN_PENDING_GIVEUP = 0, + WEXT_SCAN_PENDING_PIGGYBACK = 1, + WEXT_SCAN_PENDING_DELAY = 2, + WEXT_SCAN_PENDING_MAX +} hdd_scan_pending_option_e; + +enum +{ + WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR = 1<<0, + WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR = 1<<1, + WLAN_HDD_GET_FRAME_LOG_CMD_BMU_TRACING = 1<<2, +}; + +/* + * This structure contains the interface level (granularity) + * configuration information in support of wireless extensions. + */ +typedef struct hdd_wext_state_s +{ + /** The CSR "desired" Profile */ + tCsrRoamProfile roamProfile; + + /** BSSID to which connect request is received */ + tCsrBssid req_bssId; + + /** The association status code */ + v_U32_t statusCode; + + /** wpa version WPA/WPA2/None*/ + v_S31_t wpaVersion; + + /**WPA or RSN IE*/ + u_int8_t WPARSNIE[MAX_WPA_RSN_IE_LEN]; + + /**gen IE */ + tSirAddie genIE; + + /**Additional IE for assoc */ + tSirAddie assocAddIE; + + /**auth key mgmt */ + v_S31_t authKeyMgmt; + + /**vos event */ + vos_event_t vosevent; + + vos_event_t scanevent; + + /**Counter measure state, Started/Stopped*/ + v_BOOL_t mTKIPCounterMeasures; + + /**Completion Variable*/ + struct completion completion_var; + +#ifdef FEATURE_OEM_DATA_SUPPORT + /* oem data req in Progress */ + v_BOOL_t oemDataReqInProgress; + + /* oem data req ID */ + v_U32_t oemDataReqID; +#endif + +#ifdef FEATURE_WLAN_ESE + /* ESE state variables */ + v_BOOL_t isESEConnection; + eCsrAuthType collectedAuthType; /* Collected from ALL SIOCSIWAUTH Ioctls. Will be negotiatedAuthType - in tCsrProfile */ +#endif +}hdd_wext_state_t; + +typedef struct ccp_freq_chan_map_s{ + // List of frequencies + v_U32_t freq; + v_U32_t chan; +}hdd_freq_chan_map_t; + +#define wlan_hdd_get_wps_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE, ie, ie_len) + +#define wlan_hdd_get_p2p_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE, ie, ie_len) + +#ifdef WLAN_FEATURE_WFD +#define wlan_hdd_get_wfd_ie_ptr(ie, ie_len) \ + wlan_hdd_get_vendor_oui_ie_ptr(WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE, ie, ie_len) +#endif + +extern int hdd_UnregisterWext(struct net_device *dev); +extern int hdd_register_wext(struct net_device *dev); +extern int hdd_wlan_get_freq(v_U32_t chan,v_U32_t *freq); +extern int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, + union iwreq_data *wrqu); +extern int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, + union iwreq_data *wrqu); +extern void hdd_wlan_get_version(hdd_adapter_t *pAdapter, + union iwreq_data *wrqu, char *extra); + +extern int iw_get_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_cscan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_essid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra); + + +extern int iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra); + +extern int iw_get_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra); + +VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset); + + +VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset); + +VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset); + +void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result); + +extern int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int iw_set_three_ints_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int hdd_priv_get_data(struct iw_point *p_priv_data, + union iwreq_data *wrqu); + +extern void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len); + +void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter); +void hdd_GetClassA_statisticsCB(void *pStats, void *pContext); + +VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter); + +v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, + v_U8_t *ie, int ie_len); + +VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode); + +VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx, + hdd_adapter_t *pAdapter); + +VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx); + +VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter); + +VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter); + +VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value); + +VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr); + +void hdd_wmm_tx_snapshot(hdd_adapter_t *pAdapter); + +#ifdef FEATURE_WLAN_TDLS +VOS_STATUS iw_set_tdls_params(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra, int nOffset); +int iw_set_tdlsoffchannelmode(hdd_adapter_t *pAdapter, int offchanmode); +int iw_set_tdlssecoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset); +int iw_set_tdlsoffchannel(hdd_context_t *pHddCtx, int offchannel); +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +VOS_STATUS wlan_hdd_get_roam_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value); +#endif + +#ifdef WLAN_FEATURE_PACKET_FILTERING +void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set); +#endif +void* wlan_hdd_change_country_code_callback(void *pAdapter); + +int hdd_setBand(struct net_device *dev, u8 ui_band); +int hdd_setBand_helper(struct net_device *dev, const char *command); +VOS_STATUS wlan_hdd_get_frame_logs(hdd_adapter_t *pAdapter, v_U8_t flag); +int wlan_hdd_set_proximity(int set_value, tHalHandle hal); +#endif // __WEXT_IW_H__ + diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wmm.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wmm.h new file mode 100644 index 000000000000..4e1eb237b831 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wmm.h @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_WMM_H +#define _WLAN_HDD_WMM_H +/*============================================================================ + @file wlan_hdd_wmm.h + + This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation) + houses all the logic for WMM in HDD. + + On the control path, it has the logic to setup QoS, modify QoS and delete + QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an + explicit application invoked and an internal HDD invoked. The implicit QoS + is for applications that do NOT call the custom QCT WLAN OIDs for QoS but + which DO mark their traffic for priortization. It also has logic to start, + update and stop the U-APSD trigger frame generation. It also has logic to + read WMM related config parameters from the registry. + + On the data path, it has the logic to figure out the WMM AC of an egress + packet and when to signal TL to serve a particular AC queue. It also has the + logic to retrieve a packet based on WMM priority in response to a fetch from + TL. + + The remaining functions are utility functions for information hiding. +============================================================================*/ +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +// #define HDD_WMM_DEBUG 1 + +#define HDD_WMM_CTX_MAGIC 0x574d4d58 // "WMMX" + +#define HDD_WMM_HANDLE_IMPLICIT 0xFFFFFFFF + +#define HDD_WLAN_INVALID_STA_ID 0xFF + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*! @brief AC/Queue Index values for Linux Qdisc to operate on different traffic. +*/ +typedef enum +{ + HDD_LINUX_AC_VO = 0, + HDD_LINUX_AC_VI = 1, + HDD_LINUX_AC_BE = 2, + HDD_LINUX_AC_BK = 3 + +} hdd_wmm_linuxac_t; + +/*! @brief types of classification supported +*/ +typedef enum +{ + HDD_WMM_CLASSIFICATION_DSCP = 0, + HDD_WMM_CLASSIFICATION_802_1Q = 1 + +} hdd_wmm_classification_t; + +/*! @brief UAPSD state +*/ +typedef enum +{ + HDD_WMM_NON_UAPSD = 0, + HDD_WMM_UAPSD = 1 + +} hdd_wmm_uapsd_state_t; + + +typedef enum +{ + //STA can associate with any AP, & HDD looks at the SME notification after + // association to find out if associated with QAP and acts accordingly + HDD_WMM_USER_MODE_AUTO = 0, + //SME will add the extra logic to make sure STA associates with a QAP only + HDD_WMM_USER_MODE_QBSS_ONLY = 1, + //SME will not join a QoS AP, unless the phy mode setting says "Auto". In + // that case, STA is free to join 11n AP. Although from HDD point of view, + // it will not be doing any packet classifications + HDD_WMM_USER_MODE_NO_QOS = 2, + +} hdd_wmm_user_mode_t; + +// UAPSD Mask bits +// (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) +#define HDD_AC_VO 0x1 +#define HDD_AC_VI 0x2 +#define HDD_AC_BK 0x4 +#define HDD_AC_BE 0x8 + +/*! @brief WMM Qos instance control block +*/ +typedef struct +{ + struct list_head node; + v_U32_t handle; + v_U32_t qosFlowId; + hdd_adapter_t* pAdapter; + WLANTL_ACEnumType acType; + hdd_wlan_wmm_status_e lastStatus; + struct work_struct wmmAcSetupImplicitQos; + v_U32_t magic; +} hdd_wmm_qos_context_t; + +/*! @brief WMM related per-AC state & status info +*/ +typedef struct +{ + // does the AP require access to this AC? + v_BOOL_t wmmAcAccessRequired; + + // does the worker thread need to acquire access to this AC? + v_BOOL_t wmmAcAccessNeeded; + + // is implicit QoS negotiation currently taking place? + v_BOOL_t wmmAcAccessPending; + + // has implicit QoS negotiation already failed? + v_BOOL_t wmmAcAccessFailed; + + // has implicit QoS negotiation already succeeded? + v_BOOL_t wmmAcAccessGranted; + + // is access to this AC allowed, either because we are not doing + // WMM, we are not doing implicit QoS, implict QoS has completed, + // or explicit QoS has completed? + v_BOOL_t wmmAcAccessAllowed; + + // is the wmmAcTspecInfo valid? + v_BOOL_t wmmAcTspecValid; + + // are the wmmAcUapsd* fields valid? + v_BOOL_t wmmAcUapsdInfoValid; + + // current (possibly aggregate) Tspec for this AC + sme_QosWmmTspecInfo wmmAcTspecInfo; + + // current U-APSD parameters + v_BOOL_t wmmAcIsUapsdEnabled; + v_U32_t wmmAcUapsdServiceInterval; + v_U32_t wmmAcUapsdSuspensionInterval; + sme_QosWmmDirType wmmAcUapsdDirection; + +#ifdef FEATURE_WLAN_ESE + // Inactivity time parameters for TSPEC + v_U32_t wmmInactivityTime; + v_U32_t wmmPrevTrafficCnt; + vos_timer_t wmmInactivityTimer; +#endif + +} hdd_wmm_ac_status_t; + +/*! @brief WMM state & status info +*/ +typedef struct +{ + struct list_head wmmContextList; + hdd_wmm_ac_status_t wmmAcStatus[WLANTL_MAX_AC]; + v_BOOL_t wmmQap; + v_BOOL_t wmmQosConnection; +} hdd_wmm_status_t; + +extern const v_U8_t hdd_QdiscAcToTlAC[]; +extern const v_U8_t hddWmmUpToAcMap[]; +extern const v_U8_t hddLinuxUpToAcMap[]; + +#define WLAN_HDD_MAX_DSCP 0x3f + +/**============================================================================ + @brief hdd_wmm_init() - Function which will initialize the WMM configuation + and status to an initial state. The configuration can later be overwritten + via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation + and status to an initial state. The configuration can later be overwritten + via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_wmm_adapter_close() - Function which will perform any necessary work to + to clean up the WMM functionality prior to the kernel module unload + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter ); + +/**============================================================================ + @brief hdd_wmm_select_queue() - Function which will classify an OS packet + into linux Qdisc expectation + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to OS packet (sk_buff) + + @return : queue_index/linux AC value. + ===========================================================================*/ +v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb); + +/**============================================================================ + @brief hdd_hostapd_select_queue() - Function which will classify the packet + according to linux qdisc expectation. + + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to os packet + + @return : Qdisc queue index + ===========================================================================*/ + +v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)) + , void *accel_priv +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + , select_queue_fallback_t fallbac +#endif +); + + +/**============================================================================ + @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet + into a WMM AC based on either 802.1Q or DSCP + + @param pAdapter : [in] pointer to adapter context + @param skb : [in] pointer to OS packet (sk_buff) + @param pAcType : [out] pointer to WMM AC type of OS packet + + @return : None + ===========================================================================*/ +v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter, + struct sk_buff *skb, + WLANTL_ACEnumType* pAcType, + sme_QosWmmUpType* pUserPri); + + +/**============================================================================ + @brief hdd_wmm_acquire_access() - Function which will attempt to acquire + admittance for a WMM AC + + @param pAdapter : [in] pointer to adapter context + @param acType : [in] WMM AC type of OS packet + @param pGranted : [out] pointer to boolean flag when indicates if access + has been granted or not + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter, + WLANTL_ACEnumType acType, + v_BOOL_t * pGranted ); + +/**============================================================================ + @brief hdd_wmm_assoc() - Function which will handle the housekeeping + required by WMM when association takes place + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ); + +/**============================================================================ + @brief hdd_wmm_connect() - Function which will handle the housekeeping + required by WMM when a connection is established + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ); + +/**============================================================================ + @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the + initial value of the UAPSD mask based upon the device configuration + + @param pAdapter : [in] pointer to adapter context + @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter, + tANI_U8 *pUapsdMask ); + +/**============================================================================ + @brief hdd_wmm_is_active() - Function which will determine if WMM is + active on the current connection + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_TRUE if WMM is enabled + : VOS_FALSE if WMM is not enabled + ===========================================================================*/ +v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter ); + +/**============================================================================ + @brief hdd_wmm_addts() - Function which will add a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + @param pTspec : [in] pointer to the traffic spec + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter, + v_U32_t handle, + sme_QosWmmTspecInfo* pTspec ); + +/**============================================================================ + @brief hdd_wmm_delts() - Function which will delete a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter, + v_U32_t handle ); + +/**============================================================================ + @brief hdd_wmm_checkts() - Function which will return the status of a traffic + spec at the request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter, + v_U32_t handle ); +/**============================================================================ + @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status + of all ACs + @param pAdapter : [in] pointer to adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter ); + +/**============================================================================ + @brief hdd_log_ip_addr() - Function to log IP header src and dst address + @param pAdapter : [in] pointer to os packet + + @return : None + ===========================================================================*/ +void hdd_log_ip_addr(struct sk_buff *skb); + +/**============================================================================ + @brief hdd_get_arp_src_ip() - Function to get ARP src IP addr + @param pAdapter : [in] pointer to os packet + + @return : IP address + ===========================================================================*/ +uint32_t hdd_get_arp_src_ip(struct sk_buff *skb); + +#endif /* #ifndef _WLAN_HDD_WMM_H */ diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wowl.h b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wowl.h new file mode 100644 index 000000000000..93ae7f97de09 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_hdd_wowl.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_HDD_WOWL_H +#define _WLAN_HDD_WOWL_H + +/*============================================================================ + @file wlan_hdd_wowl.h + + This module houses all the logic for WOWL in HDD. + + It provides the following APIs + + - Ability to enable/disable following WoWL modes + 1) Magic packet (MP) mode + 2) Pattern Byte Matching (PBM) mode + - Ability to add/remove patterns for PBM + + A Magic Packet is a packet that contains 6 0xFFs followed by 16 contiguous + copies of the receiving NIC's Ethernet address. There is no API to configure + Magic Packet Pattern. + + Wakeup pattern (used for PBM) is defined as following: + typedef struct + { + U8 PatternSize; // Non-Zero pattern size + U8 PatternMaskSize; // Non-zero pattern mask size + U8 PatternMask[PatternMaskSize]; // Pattern mask + U8 Pattern[PatternSize]; // Pattern + } hdd_wowl_ptrn_t; + + PatternSize and PatternMaskSize indicate size of the variable length Pattern + and PatternMask. PatternMask indicates which bytes of an incoming packet + should be compared with corresponding bytes in the pattern. + + Maximum allowed pattern size is 128 bytes. Maximum allowed PatternMaskSize + is 16 bytes. + + Maximum number of patterns that can be configured is 8 + + HDD will add following 2 commonly used patterns for PBM by default: + 1) ARP Broadcast Pattern + 2) Unicast Pattern + + However note that WoWL will not be enabled by default by HDD. WoWL needs to + enabled explcitly by exercising the iwpriv command. + + HDD will expose an API that accepts patterns as Hex string in the following + format: "PatternSize:PatternMaskSize:PatternMask:Pattern". Mutliple patterns + can be specified by deleimiting each pattern with the ';' token. + "PatternSize1:PatternMaskSize1:PatternMask1:Pattern1;PatternSize2:...." + + Patterns can be configured dynamically via iwpriv cmd or statically via + qcom_cfg.ini file + + PBM (when enabled) can perform filtering on unicast data or broadcast data or + both. These configurations are part of factory defaults (cfg.dat) and + the deafult behavior is to perform filtering on both unicast and data frames. + + MP filtering (when enabled) is performed ALWAYS on both unicast and broadcast + data frames. + + Mangement frames are not subjected to WoWL filtering and are discarded when + WoWL is enabled. + + Whenever a patern match succeeds, RX path is restored and packets (both + management and data) will be pushed to the host from that point onwards. + Therefore, exit from WoWL is implicit and happens automatically when the + first packet match succeeds. + + WoWL works on top of BMPS. So when WoWL is requested, SME will attempt to put + the device in BMPS mode (if not already in BMPS). If attempt to BMPS fails, + request for WoWL will be rejected. + + +============================================================================*/ +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/**============================================================================ + @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be + used when PBM filtering is enabled + + @param ptrn : [in] pointer to the pattern string to be added + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn); + +/**============================================================================ + @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern + + @param ptrn : [in] pointer to the pattern string to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn); + +/**============================================================================ + @brief hdd_add_wowl_ptrn_debugfs() - Function which will add a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be added + pattern_offset : [in] offset of the pattern in the frame payload + pattern_buf : [in] pointer to the pattern hex string to be added + pattern_mask : [in] pointer to the pattern mask hex string + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx, + v_U8_t pattern_offset, char *pattern_buf, + char *pattern_mask); + +/**============================================================================ + @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx); + +/**============================================================================ + @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one + of MP and PBM must be enabled + + @param enable_mp : [in] Whether to enable magic packet WoWL mode + @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_enter_wowl (hdd_adapter_t *pAdapter, v_BOOL_t enable_mp, v_BOOL_t enable_pbm); + +/**============================================================================ + @brief hdd_exit_wowl() - Function which will disable WoWL + + @param wowlExitSrc: is wowl exiting because of wakeup pkt or user explicitly + disabling WoWL + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter, tWowlExitSource wowlExitSrc); + +/**============================================================================ + @brief hdd_init_wowl() - Init function which will initialize the WoWL module + and perform any required intial configuration + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_init_wowl (hdd_adapter_t* pAdapter); + +/**============================================================================ + @brief hdd_parse_hex() - function returns integer equivalent of hexa decimal + + @return : integer equivalent of hexa decimal + ===========================================================================*/ +int hdd_parse_hex(unsigned char c); + +#endif /* #ifndef _WLAN_HDD_WOWL_H */ diff --git a/drivers/staging/prima/CORE/HDD/inc/wlan_qct_driver.h b/drivers/staging/prima/CORE/HDD/inc/wlan_qct_driver.h new file mode 100644 index 000000000000..f231690439b3 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/inc/wlan_qct_driver.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_DRIVER_H ) +#define __WLAN_QCT_DRIVER_H + +/**======================================================================== + + \file wlan_qct_driver.h + + \brief Header file for Wireless LAN Host Device Driver Kernel Module + + + ========================================================================*/ + +/**======================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/05/09 kanand Created module. + + ===========================================================================*/ + +/*-------------------------------------------------------------------------- + * Include Files + *------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Preprocessor definitions and constants + *-------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Type declarations + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function declarations and documentation + * ------------------------------------------------------------------------*/ + +#endif // if !defined __WLAN_QCT_DRIVER_H diff --git a/drivers/staging/prima/CORE/HDD/src/bap_hdd_main.c b/drivers/staging/prima/CORE/HDD/src/bap_hdd_main.c new file mode 100644 index 000000000000..af48daba32e0 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/bap_hdd_main.c @@ -0,0 +1,4542 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file bap_hdd_main.c + + \brief 802.11 BT-AMP PAL Host Device Driver implementation + + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /prj/qct/asw/engbuilds/scl/users02/jzmuda/gb-bluez/vendor/qcom/proprietary/wlan/libra/CORE/HDD/src/bap_hdd_main.c,v 1.63 2011/04/01 15:24:20 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 12/1/09 JZmuda Created module. + + ==========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#ifdef WLAN_BTAMP_FEATURE +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +//#include +#include +#include +/* -------------------------------------------------------------------------*/ +#include +#include +#include +#include +/* -------------------------------------------------------------------------*/ +#include +#include + +#include +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +// the difference between the next two is that the first is the max +// number we support in our current implementation while the second is +// the max allowed by the spec +#define BSL_MAX_PHY_LINKS ( BSL_MAX_CLIENTS * BSL_MAX_PHY_LINK_PER_CLIENT ) +#define BSL_MAX_ALLOWED_PHY_LINKS 255 + +// these likely will need tuning based on experiments +#define BSL_MAX_RX_PKT_DESCRIPTOR 100 +#define BSL_MAX_TX_PKT_DESCRIPTOR 100 + +// these caps are in place to not have run-away queues, again needs empirical tuning +#define BSL_MAX_SIZE_TX_ACL_QUEUE 50 +#define BSL_MAX_SIZE_RX_ACL_QUEUE 50 +#define BSL_MAX_SIZE_RX_EVT_QUEUE 50 + +#if 0 +What are the maximum sizes of a command packet, an event packet and an ACL +data packet? + +[JimZ]: Sizes: +1. Cmd Maximum size is slightly greater than 672 btyes. But I am pretty sure +right now that I will never have more than 240 bytes to send down at a time. And +that is good. Because some rather unpleasant things happen at the HCI interface +if I exceed that. ( Think 8-bit CPUs. And the limitations of an 8-bit length + field. ) + +2. Event - Ditto. + +3. Data 1492 bytes +#endif + +// jimz +// TLV related defines + +#define USE_FINAL_FRAMESC +//#undef USE_FINAL_FRAMESC +// jimz +// TLV related defines + +#ifndef USE_FINAL_FRAMESC //USE_FINAL_FRAMESC +// AMP ASSOC TLV related defines +#define AMP_ASSOC_TLV_TYPE_SIZE 2 +#define AMP_ASSOC_TLV_LEN_SIZE 2 +#define AMP_ASSOC_TLV_TYPE_AND_LEN_SIZE (AMP_ASSOC_TLV_TYPE_SIZE + AMP_ASSOC_TLV_LEN_SIZE) + +// FLOW SPEC TLV related defines +#define FLOWSPEC_TYPE_SIZE 2 +#define FLOWSPEC_LEN_SIZE 2 +#define FLOWSPEC_TYPE_AND_LEN_SIZE (FLOWSPEC_TYPE_SIZE + FLOWSPEC_LEN_SIZE) + +// CMD TLV related defines +#define CMD_TLV_TYPE_SIZE 2 +#define CMD_TLV_LEN_SIZE 2 +#define CMD_TLV_TYPE_AND_LEN_SIZE (CMD_TLV_TYPE_SIZE + CMD_TLV_LEN_SIZE) + +// Event TLV related defines +#define EVENT_TLV_TYPE_SIZE 2 +#define EVENT_TLV_LEN_SIZE 2 +#define EVENT_TLV_TYPE_AND_LEN_SIZE (EVENT_TLV_TYPE_SIZE + EVENT_TLV_LEN_SIZE) + +// Data header size related defines +#define DATA_HEADER_SIZE 4 + +#else //USE_FINAL_FRAMESC + +// AMP ASSOC TLV related defines +#define AMP_ASSOC_TLV_TYPE_SIZE 1 +#define AMP_ASSOC_TLV_LEN_SIZE 2 +#define AMP_ASSOC_TLV_TYPE_AND_LEN_SIZE (AMP_ASSOC_TLV_TYPE_SIZE + AMP_ASSOC_TLV_LEN_SIZE) + +// FLOW SPEC TLV related defines +#define FLOWSPEC_TYPE_SIZE 1 +#define FLOWSPEC_LEN_SIZE 1 +#define FLOWSPEC_TYPE_AND_LEN_SIZE (FLOWSPEC_TYPE_SIZE + FLOWSPEC_LEN_SIZE) + +// CMD TLV related defines +#define CMD_TLV_TYPE_SIZE 2 +#define CMD_TLV_LEN_SIZE 1 +#define CMD_TLV_TYPE_AND_LEN_SIZE (CMD_TLV_TYPE_SIZE + CMD_TLV_LEN_SIZE) + +// Event TLV related defines +#define EVENT_TLV_TYPE_SIZE 1 +#define EVENT_TLV_LEN_SIZE 1 +#define EVENT_TLV_TYPE_AND_LEN_SIZE (EVENT_TLV_TYPE_SIZE + EVENT_TLV_LEN_SIZE) + +// Data header size related defines +#define DATA_HEADER_SIZE 4 + +#endif // USE_FINAL_FRAMESC +// jimz + +#define BSL_MAX_EVENT_SIZE 700 + +#define BSL_DEV_HANDLE 0x1234 + +// Debug related defines +#define DBGLOG printf +//#define DUMPLOG +#if defined DUMPLOG +#define DUMPLOG(n, name1, name2, aStr, size) do { \ + int i; \ + DBGLOG("%d. %s: %s = \n", n, name1, name2); \ + for (i = 0; i < size; i++) \ + DBGLOG("%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \ + DBGLOG("\n"); \ + } while (0) +#else +#define DUMPLOG(n, name1, name2, aStr, size) +#endif + +// These are required to replace some Microsoft specific specifiers +//#define UNALIGNED __align +#define UNALIGNED +#define INFINITE 0 + +#define BT_AMP_HCI_CTX_MAGIC 0x48434949 // "HCII" + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +// Temporary Windows types +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef void * HANDLE; +typedef char TCHAR; +typedef void *LPVOID; +typedef const void *LPCVOID; + +typedef struct +{ + BOOL used; // is this a valid context? + vos_event_t ReadableEvt; // the event a ReadFile can block on + ptBtampHandle bapHdl; // our handle in BAP + vos_list_t PhyLinks; // a list of all associations setup by this client +// Newly added for BlueZ + struct hci_dev *hdev; // the BlueZ HCI device structure + + /* I don't know how many of these Tx fields we need */ + spinlock_t lock; /* For serializing operations */ + + struct sk_buff_head txq; /* We need the ACL Data Tx queue */ + + /* We definitely need some of these rx_skb fields */ + unsigned long rx_state; + unsigned long rx_count; + struct sk_buff *rx_skb; + + struct net_device *p_dev; // Our parent wlan network device + +} BslClientCtxType; + +typedef struct +{ + BslClientCtxType* pctx; + /* Tx skb queue and the workstructure for handling Tx as deferred work. */ + struct sk_buff *tx_skb; + + struct work_struct hciInterfaceProcessing; + v_U32_t magic; + +} BslHciWorkStructure; + +typedef struct +{ + TCHAR* ValueName; // name of the value + DWORD Type; // type of value + DWORD DwordValue; // DWORD value + TCHAR* StringValue; // string value + +} BslRegEntry; + +typedef struct +{ + BOOL used; // is this a valid context? + hdd_list_t ACLTxQueue[WLANTL_MAX_AC]; // the TX ACL queues + BslClientCtxType* pClientCtx; // ptr to application context that spawned + // this association + v_U8_t PhyLinkHdl; // BAP handle for this association + void* pPhyLinkDescNode; // ptr to node in list of assoc in client ctx + // real type BslPhyLinksNodeType* + +} BslPhyLinkCtxType; + +typedef struct +{ + vos_list_node_t node; // MUST be first element + BslPhyLinkCtxType* pPhy; // ptr to an association context + +} BslPhyLinksNodeType; + +typedef struct +{ + vos_list_node_t node; // MUST be first element + vos_pkt_t* pVosPkt; // ptr to a RX VoS pkt which can hold an HCI event or ACL data + +} BslRxListNodeType; + +// Borrowed from wlan_hdd_dp_utils.h +typedef struct +{ + hdd_list_node_t node; // MUST be first element + struct sk_buff * skb; // ptr to the ACL data + +} BslTxListNodeType; + +typedef struct +{ + BslPhyLinkCtxType* ptr; // ptr to the association context for this phy_link_handle + +} BslPhyLinkMapEntryType; + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +BslClientCtxType* gpBslctx; + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ +// Temporary (until multi-phy link) pointer to BT-AMP context +static void *gpCtx; + +// an efficient lookup from phy_link_handle to phy link context +static BslPhyLinkMapEntryType BslPhyLinkMap[BSL_MAX_ALLOWED_PHY_LINKS]; + +//static HANDLE hBsl = NULL; //INVALID_HANDLE_VALUE; +static BOOL bBslInited = FALSE; + +static BslClientCtxType BslClientCtx[BSL_MAX_CLIENTS]; +//static vos_lock_t BslClientLock; + +static BslPhyLinkCtxType BslPhyLinkCtx[BSL_MAX_PHY_LINKS]; +//static vos_lock_t BslPhyLock; + +// the pool for association contexts +static vos_list_t BslPhyLinksDescPool; +static BslPhyLinksNodeType BslPhyLinksDesc[BSL_MAX_PHY_LINKS]; + +//static v_U32_t Eventlen = 0; + +/*--------------------------------------------------------------------------- + * Forward declarations + *-------------------------------------------------------------------------*/ +static void bslWriteFinish(struct work_struct *work); + +/*--------------------------------------------------------------------------- + * Driver Entry points and Structure definitions + *-------------------------------------------------------------------------*/ +static int BSL_Open (struct hci_dev *hdev); +static int BSL_Close (struct hci_dev *hdev); +static int BSL_Flush(struct hci_dev *hdev); +static int BSL_IOControl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); +static int BSL_Write(struct sk_buff *skb); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static void BSL_Destruct(struct hci_dev *hdev); +#endif + + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ +static v_BOOL_t WLANBAP_AmpConnectionAllowed(void) +{ + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + v_BOOL_t retVal = VOS_FALSE; + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + return pHddCtx->isAmpAllowed; + } + else + { + return retVal; + } + } + return retVal; +} + +/** + @brief WLANBAP_STAFetchPktCB() - The fetch packet callback registered + with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STAFetchPktCBType routine being called. Which is called by + TL when the scheduling algorithms allows for transmission of another + packet to the module. + + This function is here to "wrap" or abstract WLANTL_STAFetchPktCBType. + Because the BAP-specific HDD "shim" layer (BSL) doesn't know anything + about STAIds, or other parameters required by TL. + + @param pHddHdl: [in] The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STAFetchCBType to retreive + this value. + @param pucAC: [inout] access category requested by TL, if HDD does not + have packets on this AC it can choose to service another AC queue in + the order of priority + @param vosDataBuff: [out] pointer to the VOSS data buffer that was + transmitted + @param tlMetaInfo: [out] meta info related to the data frame + + @return + The result code associated with performing the operation +*/ +static VOS_STATUS WLANBAP_STAFetchPktCB +( + v_PVOID_t pHddHdl, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +) +{ + BslPhyLinkCtxType* pPhyCtx; + VOS_STATUS VosStatus; + v_U8_t AcIdxStart; + v_U8_t AcIdx; + hdd_list_node_t *pLink; + BslTxListNodeType *pNode; + struct sk_buff * skb; + BslClientCtxType* pctx; + WLANTL_ACEnumType Ac; + vos_pkt_t* pVosPkt; + WLANTL_MetaInfoType TlMetaInfo; + pctx = &BslClientCtx[0]; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "WLANBAP_STAFetchPktCB" ); + + // sanity checking + if( pHddHdl == NULL || vosDataBuff == NULL || + tlMetaInfo == NULL || ucAC >= WLANTL_MAX_AC || ucAC < 0 ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STAFetchPktCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + + // Initialize the VOSS packet returned to NULL - in case of error + *vosDataBuff = NULL; + + pPhyCtx = (BslPhyLinkCtxType *)pHddHdl; + AcIdx = AcIdxStart = ucAC; + + spin_lock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + VosStatus = hdd_list_remove_front( &pPhyCtx->ACLTxQueue[AcIdx], &pLink ); + spin_unlock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + + if ( VOS_STATUS_E_EMPTY == VosStatus ) + { + do + { + AcIdx = (AcIdx + 1) % WLANTL_MAX_AC; + + spin_lock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + VosStatus = hdd_list_remove_front( &pPhyCtx->ACLTxQueue[AcIdx], &pLink ); + spin_unlock_bh(&pPhyCtx->ACLTxQueue[AcIdx].lock); + + } + while ( VosStatus == VOS_STATUS_E_EMPTY && AcIdx != AcIdxStart ); + + if ( VosStatus == VOS_STATUS_E_EMPTY ) + { + // Queue is empty. This can happen. Just return NULL back to TL... + return(VOS_STATUS_E_EMPTY); + } + else if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT( 0 ); + } + } + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT( 0 ); + } + + pNode = (BslTxListNodeType *)pLink; + skb = pNode->skb; + + // I will access the skb in a VOSS packet + // Wrap the OS provided skb in a VOSS packet + // Attach skb to VOS packet. + VosStatus = vos_pkt_wrap_data_packet( &pVosPkt, + VOS_PKT_TYPE_TX_802_3_DATA, + skb, + NULL, + NULL); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STAFetchPktCB vos_pkt_wrap_data_packet " + "failed status =%d", VosStatus ); + kfree_skb(skb); + return VosStatus; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s: pVosPkt(vos_pkt_t *)=%p", __func__, + pVosPkt ); + + VosStatus = WLANBAP_XlateTxDataPkt( pctx->bapHdl, pPhyCtx->PhyLinkHdl, + &Ac, &TlMetaInfo, pVosPkt); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STAFetchPktCB WLANBAP_XlateTxDataPkt " + "failed status =%d", VosStatus ); + + // return the packet + VosStatus = vos_pkt_return_packet( pVosPkt ); + kfree_skb(skb); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return VosStatus; + } + // give TL the VoS pkt + *vosDataBuff = pVosPkt; + + // provide the meta-info BAP provided previously + *tlMetaInfo = TlMetaInfo; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: *vosDataBuff(vos_pkt_t *)=%p", __func__, *vosDataBuff ); + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_STAFetchPktCB() + +/** + @brief WLANBAP_STARxCB() - The receive callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_STARxCBType routine being called. Which is called by + TL to notify when a packet was received for a registered STA. + + @param pHddHdl: [in] The HDD(BSL) specific context for this association. + Use the STAId passed to me by TL in WLANTL_STARxCBType to retrieve this value. + @param vosDataBuff: [in] pointer to the VOSS data buffer that was received + (it may be a linked list) + @param pRxMetaInfo: [in] Rx meta info related to the data frame + + @return + The result code associated with performing the operation +*/ +static VOS_STATUS WLANBAP_STARxCB +( + v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + WLANTL_RxMetaInfoType* pRxMetaInfo +) +{ + BslPhyLinkCtxType* pctx; + BslClientCtxType* ppctx; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + WLANTL_ACEnumType Ac; // this is not needed really + struct sk_buff *skb = NULL; + vos_pkt_t* pVosPacket; + vos_pkt_t* pNextVosPacket; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "WLANBAP_STARxCB" ); + + // sanity checking + if ( pHddHdl == NULL || vosDataBuff == NULL || pRxMetaInfo == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STARxCB bad input" ); + if(NULL != vosDataBuff) + { + VosStatus = vos_pkt_return_packet( vosDataBuff ); + } + return VOS_STATUS_E_FAILURE; + } + + pctx = (BslPhyLinkCtxType *)pHddHdl; + ppctx = pctx->pClientCtx; + + if( NULL == ppctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STARxCB ClientCtx is NULL" ); + VosStatus = vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAILURE; + } + + // walk the chain until all are processed + pVosPacket = vosDataBuff; + do + { + // get the pointer to the next packet in the chain + // (but don't unlink the packet since we free the entire chain later) + VosStatus = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE); + + // both "success" and "empty" are acceptable results + if (!((VosStatus == VOS_STATUS_SUCCESS) || (VosStatus == VOS_STATUS_E_EMPTY))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,"%s: Failure walking packet chain", __func__); + return VOS_STATUS_E_FAILURE; + } + + // process the packet + VosStatus = WLANBAP_XlateRxDataPkt( ppctx->bapHdl, pctx->PhyLinkHdl, + &Ac, pVosPacket ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, "WLANBAP_STARxCB WLANBAP_XlateRxDataPkt " + "failed status = %d", VosStatus ); + + VosStatus = VOS_STATUS_E_FAILURE; + + break; + } + + // Extract the OS packet (skb). + // Tell VOS to detach the OS packet from the VOS packet + VosStatus = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( VosStatus )) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: Failure extracting skb from vos pkt. " + "VosStatus = %d", __func__, VosStatus ); + + VosStatus = VOS_STATUS_E_FAILURE; + + break; + } + + //JEZ100809: While an skb is being handled by the kernel, is "skb->dev" de-ref'd? + skb->dev = (struct net_device *) gpBslctx->hdev; + bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; + //skb->protocol = eth_type_trans(skb, skb->dev); + //skb->ip_summed = CHECKSUM_UNNECESSARY; + + // This is my receive skb pointer + gpBslctx->rx_skb = skb; + + // This is how data and events are passed up to BlueZ + hci_recv_frame(gpBslctx->rx_skb); + + // now process the next packet in the chain + pVosPacket = pNextVosPacket; + + } while (pVosPacket); + + + //JEZ100922: We are free to return the enclosing VOSS packet. + VosStatus = vos_pkt_return_packet( vosDataBuff ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_STARxCB() + +/** + @brief WLANBAP_TxCompCB() - The Tx complete callback registered with BAP by HDD. + + It is called by the BAP immediately upon the underlying + WLANTL_TxCompCBType routine being called. Which is called by + TL to notify when a transmission for a packet has ended. + + @param pHddHdl: [in] The HDD(BSL) specific context for this association + @param vosDataBuff: [in] pointer to the VOSS data buffer that was transmitted + @param wTxSTAtus: [in] status of the transmission + + @return + The result code associated with performing the operation +*/ +extern v_VOID_t WLANBAP_TxPacketMonitorHandler ( v_PVOID_t ); // our handle in BAP + +static VOS_STATUS WLANBAP_TxCompCB +( + v_PVOID_t pHddHdl, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + //BslTxListNodeType* pTxNode; + void* pOsPkt = NULL; + BslPhyLinkCtxType* pctx; + BslClientCtxType* ppctx; + static int num_packets; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "WLANBAP_TxCompCB. vosDataBuff(vos_pkt_t *)=%p", vosDataBuff ); + + // be aware that pHddHdl can be NULL or can point to the per association + // BSL context from the register data plane. In either case it does not + // matter since we will simply free the VoS pkt and reclaim the TX + // descriptor + + // sanity checking + if ( vosDataBuff == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_TxCompCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + + //Return the skb to the OS + VosStatus = vos_pkt_get_os_packet( vosDataBuff, &pOsPkt, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( VosStatus )) + { + //This is bad but still try to free the VOSS resources if we can + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( vosDataBuff ); + return VOS_STATUS_E_FAILURE; + } + + kfree_skb((struct sk_buff *)pOsPkt); + + //Return the VOS packet resources. + VosStatus = vos_pkt_return_packet( vosDataBuff ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + // JEZ110330: Now signal the layer above me...that I have released some packets. + pctx = (BslPhyLinkCtxType *)pHddHdl; + ppctx = pctx->pClientCtx; + num_packets = (num_packets + 1) % 4; + if (num_packets == 0 ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "%s: Sending up number of completed packets. num_packets = %d.", __func__, num_packets ); + WLANBAP_TxPacketMonitorHandler ( (v_PVOID_t) ppctx->bapHdl ); // our handle in BAP + } + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_TxCompCB() + +/** + @brief BslFlushTxQueues() - flush the Tx queues + + @param pPhyCtx : [in] ptr to the phy context whose queues need to be flushed + + @return + VOS_STATUS + +*/ +static VOS_STATUS BslFlushTxQueues +( + BslPhyLinkCtxType* pPhyCtx +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + hdd_list_node_t* pLink; + BslTxListNodeType *pNode; + + + if(TRUE == pPhyCtx->used) + { + while (++i != WLANTL_MAX_AC) + { + //Free up any packets in the Tx queue + spin_lock_bh(&pPhyCtx->ACLTxQueue[i].lock); + while (true) + { + VosStatus = hdd_list_remove_front(&pPhyCtx->ACLTxQueue[i], &pLink ); + if(VOS_STATUS_E_EMPTY != VosStatus) + { + pNode = (BslTxListNodeType *)pLink; + kfree_skb(pNode->skb); + continue; + } + break; + } + spin_unlock_bh(&pPhyCtx->ACLTxQueue[i].lock); + } + } + return(VOS_STATUS_SUCCESS); +} // BslFlushTxQueues + + +/** + @brief BslReleasePhyCtx() - this function will free up an association context + + @param pPhyCtx : [in] ptr to the phy context to release + + @return + None + +*/ +static void BslReleasePhyCtx +( + BslPhyLinkCtxType* pPhyCtx +) +{ + uintptr_t OldMapVal; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslReleasePhyCtx" ); + + pPhyCtx->used = FALSE; + + + if (BslPhyLinkMap[pPhyCtx->PhyLinkHdl].ptr == NULL) return; + + + // update the phy link handle based map so TX data is stopped from flowing through + OldMapVal = vos_atomic_set( (uintptr_t *) (BslPhyLinkMap[pPhyCtx->PhyLinkHdl].ptr), + (uintptr_t) 0 ); + + // clear out the Tx Queues + VosStatus = BslFlushTxQueues(pPhyCtx); + + // clear out the parent ptr + // pPhyCtx->pClientCtx = NULL;//commented to debug exception + + // we also need to remove this assocation from the list of active + // associations maintained in the application context + if( pPhyCtx->pPhyLinkDescNode ) + { + VosStatus = vos_list_remove_node( &pPhyCtx->pClientCtx->PhyLinks, + &((BslPhyLinksNodeType*)pPhyCtx->pPhyLinkDescNode)->node); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus ) ); + //Return the PhyLink handle to the free pool + VosStatus = vos_list_insert_front(&BslPhyLinksDescPool,&((BslPhyLinksNodeType*)pPhyCtx->pPhyLinkDescNode)->node); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus ) ); + + pPhyCtx->pPhyLinkDescNode = NULL; + } + pPhyCtx->pClientCtx = NULL;//Moved here to bebug the exception + + pPhyCtx->used = FALSE; + +} // BslReleasePhyCtx() + +/** + @brief WLAN_BAPEventCB() - Implements the callback for ALL asynchronous events. + + Including Events resulting from: + * HCI Create Physical Link, + * Disconnect Physical Link, + * Create Logical Link, + * Flow Spec Modify, + * HCI Reset, + * HCI Flush,... + + Also used to return sync events locally by BSL + + @param pHddHdl: [in] The HDD(BSL) specific context for this association. + BSL gets this from the downgoing packets Physical handle value. + @param pBapHCIEvent: [in] pointer to the union of "HCI Event" structures. + Contains all info needed for HCI event. + @param AssocSpecificEvent: [in] flag indicates assoc-specific (1) or + global (0) event + + @return + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pBapHCIEvent is NULL + VOS_STATUS_SUCCESS: Success +*/ +static VOS_STATUS WLANBAP_EventCB +( + v_PVOID_t pHddHdl, /* this could refer to either the BSL per + association context which got passed in during + register data plane OR the BSL per application + context passed in during register BAP callbacks + based on setting of the Boolean flag below */ + tpBtampHCI_Event pBapHCIEvent, /* This now encodes ALL event types including + Command Complete and Command Status*/ + v_BOOL_t AssocSpecificEvent /* Flag to indicate global or assoc-specific event */ +) +{ + BslClientCtxType* pctx; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + vos_pkt_t* pVosPkt; + v_U32_t PackStatus; + static v_U8_t Buff[BSL_MAX_EVENT_SIZE]; // stack overflow? + v_U32_t Written = 0; // FramesC REQUIRES this + v_U32_t OldMapVal; + struct sk_buff *skb = NULL; + + // sanity checking + if ( pBapHCIEvent == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB event=%d " + "assoc_specific=%d", pBapHCIEvent->bapHCIEventCode, AssocSpecificEvent ); + + if ( pHddHdl == NULL ) + { + /* Consider the following error scenarios to bypass the NULL check: + - create LL without a call for create PL before + - delete LL or PL when no AMP connection has been established yet + Client context is unimportant from HCI point of view, only needed by the TLV API in BAP + TODO: Change the TLV APIs to not to carry the client context; it doesn't use it anyway + */ + if (( AssocSpecificEvent ) && + (BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT != pBapHCIEvent->bapHCIEventCode) && + (BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT != pBapHCIEvent->bapHCIEventCode)) + { + pctx = gpBslctx; + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_FATAL, "WLANBAP_EventCB bad input" ); + return VOS_STATUS_E_FAILURE; + } + } + + + if(NULL != pHddHdl) + { + if ( AssocSpecificEvent ) + { + // get the app context from the assoc context + pctx = ((BslPhyLinkCtxType *)pHddHdl)->pClientCtx; + } + else + { + pctx = (BslClientCtxType *)pHddHdl; + } + } + + if(NULL == pctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "pctx is NULL in %s", __func__); + + return VOS_STATUS_E_FAULT; + + } + + VosStatus = vos_pkt_get_packet( &pVosPkt, VOS_PKT_TYPE_RX_RAW, + BSL_MAX_EVENT_SIZE, 1, 0, NULL, NULL); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB vos_pkt_get_packet " + "failed status=%d", VosStatus ); + return(VosStatus); + } + + switch ( pBapHCIEvent->bapHCIEventCode ) + { + /** BT events */ + case BTAMP_TLV_HCI_COMMAND_COMPLETE_EVENT: + { + /* + BTAMP_TLV_HCI_RESET_CMD: + BTAMP_TLV_HCI_FLUSH_CMD: + BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD: + BTAMP_TLV_HCI_SET_EVENT_MASK_CMD: + BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD: + BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD: + BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD: + BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD: + BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD: + BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD: + BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD: + BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TO_CMD: + BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TO_CMD: + BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD: + BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFORMATION_CMD: + BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_COMMANDS_CMD: + BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD: + BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD: + BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD: + BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD: + BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD: + BTAMP_TLV_HCI_READ_RSSI_CMD: + BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD: + BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD: + BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD: + BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD: + BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD: + BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0: + + */ + + // pack + PackStatus = btampPackTlvHCI_Command_Complete_Event( pctx, + &pBapHCIEvent->u.btampCommandCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Command_Complete_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_COMMAND_STATUS_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Command_Status_Event( pctx, + &pBapHCIEvent->u.btampCommandStatusEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Command_Status_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_NUM_OF_COMPLETED_PKTS_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Num_Completed_Pkts_Event( pctx, + &pBapHCIEvent->u.btampNumOfCompletedPktsEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Num_Completed_Pkts_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_NUM_OF_COMPLETED_DATA_BLOCKS_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Num_Completed_Data_Blocks_Event( pctx, + &pBapHCIEvent->u.btampNumOfCompletedDataBlocksEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Num_Completed_Data_Blocks_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_HARDWARE_ERROR_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Hardware_Error_Event( pctx, + &pBapHCIEvent->u.btampHardwareErrorEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_FLUSH_OCCURRED_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Flush_Occurred_Event( pctx, + &pBapHCIEvent->u.btampFlushOccurredEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Flush_Occurred_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_ENHANCED_FLUSH_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Enhanced_Flush_Complete_Event( pctx, + &pBapHCIEvent->u.btampEnhancedFlushCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampPackTlvHCI_Enhanced_Flush_Complete_Event failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_LOOPBACK_COMMAND_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Loopback_Command_Event( pctx, + &pBapHCIEvent->u.btampLoopbackCommandEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_DATA_BUFFER_OVERFLOW_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Data_Buffer_Overflow_Event( pctx, + &pBapHCIEvent->u.btampDataBufferOverflowEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_QOS_VIOLATION_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Qos_Violation_Event( pctx, + &pBapHCIEvent->u.btampQosViolationEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + /** BT v3.0 events */ + case BTAMP_TLV_HCI_GENERIC_AMP_LINK_KEY_NOTIFICATION_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Generic_AMP_Link_Key_Notification_Event( pctx, + &pBapHCIEvent->u.btampGenericAMPLinkKeyNotificationEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Physical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampPhysicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + // look at this event to determine whether to cleanup the PHY context + if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_STATUS_SUCCESS ) + { + // register the data plane now + VosStatus = WLANBAP_RegisterDataPlane( pctx->bapHdl, + WLANBAP_STAFetchPktCB, + WLANBAP_STARxCB, + WLANBAP_TxCompCB, + (BslPhyLinkCtxType *)pHddHdl ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB WLANBAP_RegisterDataPlane " + "failed status = %d", VosStatus ); + // we still want to send the event upto app so do not bail + } + else + { + // update the phy link handle based map so TX data can start flowing through + OldMapVal = vos_atomic_set( (uintptr_t*)BslPhyLinkMap+pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.phy_link_handle, + (uintptr_t) pHddHdl ); + +// VOS_ASSERT( OldMapVal == 0 );//Commented to test reconnect + } + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_HOST_REJ_RESOURCES ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_HOST_TIMEOUT ) + { + //We need to update the phy link handle here to be able to reissue physical link accept + // update the phy link handle based map so TX data can start flowing through + OldMapVal = vos_atomic_set( (uintptr_t*)BslPhyLinkMap+pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.phy_link_handle, + (uintptr_t) pHddHdl ); + +// VOS_ASSERT( OldMapVal == 0 );//Commented to test reconnect + + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_MAX_NUM_CNCTS ) + { + //We need to update the phy link handle here to be able to reissue physical link /create/accept + // update the phy link handle based map so TX data can start flowing through + OldMapVal = vos_atomic_set( (uintptr_t*)BslPhyLinkMap+pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.phy_link_handle, + (uintptr_t) pHddHdl ); +// VOS_ASSERT( OldMapVal == 0 );//Commented to test reconnect + + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_HOST_TIMEOUT ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + 0x16 /* WLANBAP_ERROR_FAILED_CONNECTION? */ ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + 0x8 /* WLANBAP_ERROR_AUTH_FAILED? */ ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else if ( pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status == + WLANBAP_ERROR_NO_CNCT ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB unexpected HCI Phy Link Comp Evt " + "status =%d", pBapHCIEvent->u.btampPhysicalLinkCompleteEvent.status ); + } + + break; + } + case BTAMP_TLV_HCI_CHANNEL_SELECTED_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Channel_Selected_Event( pctx, + &pBapHCIEvent->u.btampChannelSelectedEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Disconnect_Physical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + // we need to cleanup the PHY context always but have these checks to make + // sure we catch unexpected behavior, strangely enough even when peer triggers + // the disconnect the reason code is still 0x16, weird + if ( pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.status == WLANBAP_STATUS_SUCCESS && + pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.reason == WLANBAP_ERROR_TERM_BY_LOCAL_HOST ) + { + BslReleasePhyCtx( (BslPhyLinkCtxType *)pHddHdl ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB unexpected HCI Dis Phy Link Comp Evt " + "status =%d reason =%d", pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.status, + pBapHCIEvent->u.btampDisconnectPhysicalLinkCompleteEvent.reason ); + } + + break; + } + case BTAMP_TLV_HCI_PHYSICAL_LINK_LOSS_WARNING_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Physical_Link_Loss_Warning_Event( pctx, + &pBapHCIEvent->u.btampPhysicalLinkLossWarningEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_PHYSICAL_LINK_RECOVERY_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Physical_Link_Recovery_Event( pctx, + &pBapHCIEvent->u.btampPhysicalLinkRecoveryEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_LOGICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Logical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampLogicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Disconnect_Logical_Link_Complete_Event( pctx, + &pBapHCIEvent->u.btampDisconnectLogicalLinkCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Flow_Spec_Modify_Complete_Event( pctx, + &pBapHCIEvent->u.btampFlowSpecModifyCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + case BTAMP_TLV_HCI_SHORT_RANGE_MODE_CHANGE_COMPLETE_EVENT: + { + // pack + PackStatus = btampPackTlvHCI_Short_Range_Mode_Change_Complete_Event( pctx, + &pBapHCIEvent->u.btampShortRangeModeChangeCompleteEvent, Buff, BSL_MAX_EVENT_SIZE, &Written ); + + if ( !BTAMP_SUCCEEDED( PackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANBAP_EventCB: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", PackStatus); + // handle the error + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + break; + } + default: + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB unexpected event" ); + + VosStatus = vos_pkt_return_packet( pVosPkt ); + + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + break; + } + } + + VOS_ASSERT(Written <= BSL_MAX_EVENT_SIZE); + + // stick the event into a VoS pkt + VosStatus = vos_pkt_push_head( pVosPkt, Buff, Written ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_EventCB vos_pkt_push_head " + "status =%d", VosStatus ); + + // return the packet + VosStatus = vos_pkt_return_packet( pVosPkt ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + // Extract the OS packet (skb). + // Tell VOS to detach the OS packet from the VOS packet + VosStatus = vos_pkt_get_os_packet( pVosPkt, (v_VOID_t **)&skb, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( VosStatus )) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: Failure extracting skb from vos pkt. " + "VosStatus = %d", __func__, VosStatus ); + + // return the packet + VosStatus = vos_pkt_return_packet( pVosPkt ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + return(VOS_STATUS_E_FAILURE); + } + + //JEZ100922: We are free to return the enclosing VOSS packet. + VosStatus = vos_pkt_return_packet( pVosPkt ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus )); + + //JEZ100809: While an skb is being handled by the kernel, is "skb->dev" de-ref'd? + skb->dev = (struct net_device *) gpBslctx->hdev; + bt_cb(skb)->pkt_type = HCI_EVENT_PKT; + //skb->protocol = eth_type_trans(skb, skb->dev); + //skb->ip_summed = CHECKSUM_UNNECESSARY; + + // This is my receive skb pointer + gpBslctx->rx_skb = skb; + + // This is how data and events are passed up to BlueZ + hci_recv_frame(gpBslctx->rx_skb); + + return(VOS_STATUS_SUCCESS); +} // WLANBAP_EventCB() + +static VOS_STATUS +WLANBAP_PhyLinkFailure +( + BslClientCtxType* pctx, + v_U8_t phy_link_handle +) +{ + VOS_STATUS vosStatus; + tBtampHCI_Event bapHCIEvent; + + /* Format the Physical Link Complete event to return... */ + bapHCIEvent.bapHCIEventCode = BTAMP_TLV_HCI_PHYSICAL_LINK_COMPLETE_EVENT; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.present = 1; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.status = WLANBAP_ERROR_UNSPECIFIED_ERROR; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.phy_link_handle + = phy_link_handle; + bapHCIEvent.u.btampPhysicalLinkCompleteEvent.ch_number + = 0; + //TBD: Could be a cleaner way to get the PhyLinkCtx handle; For now works + BslPhyLinkCtx[0].pClientCtx = pctx; + vosStatus = WLANBAP_EventCB( &BslPhyLinkCtx[0], &bapHCIEvent, TRUE ); + + return vosStatus; +} + +/** + @brief BslFindAndInitClientCtx() - This function will find and initialize a client + a.k.a app context + + @param pctx : [inout] ptr to the client context + + @return + TRUE if all OK, FALSE otherwise + +*/ +static BOOL BslFindAndInitClientCtx +( + BslClientCtxType** pctx_ +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BslClientCtxType* pctx; + v_U8_t i; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslFindAndInitClientCtx" ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH,"%s:BslClientLock already inited",__func__); + // return(0); + } + + for ( i=0; i < BSL_MAX_CLIENTS; i++ ) + { + if ( !BslClientCtx[i].used ) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH,"%s:BslClientCtx[%d] selected",__func__, i); + BslClientCtx[i].used = TRUE; + break; + } + } + + if ( i == BSL_MAX_CLIENTS ) + { + // no more clients can be supported + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslFindAndInitClientCtx no more " + "clients can be supported MAX=%d", BSL_MAX_CLIENTS ); + return FALSE; + } + + //pctx = BslClientCtx + i; + pctx = gpBslctx; + + // get a handle from BAP + VosStatus = WLANBAP_GetNewHndl(&pctx->bapHdl); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + pctx->used = FALSE; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:WLAN_GetNewHndl Failed",__func__); + + return(FALSE); + } + + // register the event cb with BAP, this cb is used for BOTH association + // specific and non-association specific event notifications by BAP. + // However association specific events will be called with a different + // cookie that is passed in during the physical link create/accept + VosStatus = WLAN_BAPRegisterBAPCallbacks( pctx->bapHdl, WLANBAP_EventCB, pctx ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + pctx->used = FALSE; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:WLAN_BAPRegsiterBAPCallaback Failed",__func__); + + return(FALSE); + } + + // init the PhyLinks queue to keep track of the assoc's of this client + VosStatus = vos_list_init( &pctx->PhyLinks ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus ) ); + + *pctx_ = pctx; + + return(TRUE); +} //BslFindAndInitClientCtx() + +/** + @brief BslReleaseClientCtx() - This function will release a client a.k.a. app + context + + @param pctx : [in] ptr to the client context + + @return + None + +*/ +//#if 0 +static void BslReleaseClientCtx +( + BslClientCtxType* pctx +) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + vos_list_node_t* pLink; + BslPhyLinksNodeType *pPhyNode; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslReleaseClientCtx" ); + + // an app can do this without cleaning up after itself i.e. it can have active associations and + // data pending, we need to cleanup its mess + + // first tell BAP we dont want the handle anymore, BAP will cleanup all the associations and + // consume resulting HCI events, so after this we will not get any HCI events. we will also + // not see any FetchPktCB and RxPktCB. We can still expect TxCompletePktCB + VosStatus = WLANBAP_ReleaseHndl( pctx->bapHdl ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus ) ); + + + // find and free all of the association contexts belonging to this app + while ( VOS_IS_STATUS_SUCCESS( VosStatus = vos_list_remove_front( &pctx->PhyLinks, &pLink ) ) ) + { + pPhyNode = (BslPhyLinksNodeType *)pLink; + + // since the phy link has already been removed from the list of active + // associations, make sure we dont attempt to do this again + pPhyNode->pPhy->pPhyLinkDescNode = NULL; + + BslReleasePhyCtx( pPhyNode->pPhy ); + } + + VOS_ASSERT( VosStatus == VOS_STATUS_E_EMPTY ); + + // destroy the PhyLinks queue + VosStatus = vos_list_destroy( &pctx->PhyLinks ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus ) ); + + pctx->used = FALSE; + +} // BslReleaseClientCtx() +//#endif + +/** + @brief BslInitPhyCtx() - Initialize the Phy Context array. + + + @return + TRUE if all OK, FALSE otherwise + +*/ +static BOOL BslInitPhyCtx (void) +{ + v_U16_t i; + // free PHY context + + for ( i=0; iused = TRUE; + + // store the PHY link handle + BslPhyLinkCtx[i].PhyLinkHdl = PhyLinkHdl; + + // init the TX queues + for ( j=0; jACLTxQueue ); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS( VosStatus ) ); + } + + // need to add this Phy context to the client list of associations, + // useful during Close operation + + // get a pkt desc + VosStatus = vos_list_remove_front( &BslPhyLinksDescPool, &pLink ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + // this could happen due to pool not being big enough, etc + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslFindAndInitPhyCtx failed to " + "get node from BslPhyLinksDescPool vstatus=%d", VosStatus ); + BslReleasePhyCtx( *ppPhyCtx ); + return FALSE; + } + + // stick the VOS pkt into the node + pNode = (BslPhyLinksNodeType *) pLink; + pNode->node = *pLink; + pNode->pPhy = *ppPhyCtx; + + + // now queue the pkt into the correct queue + VosStatus = vos_list_insert_back( &pctx->PhyLinks, pLink ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + // need to record the desc for this assocation in the list of + // active assocations in client context to allow cleanup later + (*ppPhyCtx)->pPhyLinkDescNode = pNode; + + return(TRUE); + } +} // BslFindAndInitPhyCtx() + +/** + @brief BslProcessHCICommand() - This function will process an HCI command i.e + take an HCI command buffer, unpack it and then call the appropriate BAP API + + @param pctx : [in] ptr to the client context + @param pBuffer_ : [in] the input buffer containing the HCI command + @param Count_ : [in] size of the HCI command buffer + + @return + TRUE if all OK, FALSE otherwise + +*/ +static BOOL BslProcessHCICommand +( + BslClientCtxType* pctx, + LPCVOID pBuffer_, + DWORD Count_ +) +{ + LPVOID pBuffer = (LPVOID) pBuffer_; // castaway the const-ness of the ptr + v_U16_t Count = (v_U16_t) Count_; // this should be OK max size < 1500 + v_U32_t UnpackStatus; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BOOL Status; + BslPhyLinkCtxType* pPhyCtx; + tBtampHCI_Event HCIEvt; + v_U16_t x = 1; + int i = 0; + + // the opcode is in LE, if we are LE too then this is fine else we need some + // byte swapping + v_U16_t cmdOpcode = *(UNALIGNED v_U16_t *)pBuffer; + v_U8_t *pBuf = (v_U8_t *)pBuffer; + v_U8_t *pTmp = (v_U8_t *)pBuf; + + // TODO: do we really need to do this per call even though the op is quite cheap + if(*(v_U8_t *)&x == 0) + { + // BE + cmdOpcode = ( cmdOpcode & 0xFF ) << 8 | ( cmdOpcode & 0xFF00 ) >> 8; + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslProcessHCICommand: cmdOpcode = %hx", cmdOpcode ); + + for(i=0; i<4; i++) + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: *pBuf before advancepTmp[%x] = %x", i,pTmp[i] ); + + pBuf+=CMD_TLV_TYPE_AND_LEN_SIZE; + + + switch ( cmdOpcode ) + { + /** BT v3.0 Link Control commands */ + case BTAMP_TLV_HCI_CREATE_PHYSICAL_LINK_CMD: + { + tBtampTLVHCI_Create_Physical_Link_Cmd CreatePhysicalLinkCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Create_Physical_Link_Cmd( NULL, + pBuf, Count, &CreatePhysicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Create_Physical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + if(VOS_FALSE == WLANBAP_AmpConnectionAllowed()) + { + VosStatus = WLANBAP_PhyLinkFailure(pctx, CreatePhysicalLinkCmd.phy_link_handle); + if ( VOS_STATUS_SUCCESS != VosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLANBAP_PhyLinkFailure failed"); + // handle the error + return(FALSE); + } + break; + } + + // setup the per PHY link BAP context + Status = BslFindAndInitPhyCtx( pctx, CreatePhysicalLinkCmd.phy_link_handle, + &pPhyCtx ); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "CreatePhysicalLinkCmd.phy_link_handle=%d",CreatePhysicalLinkCmd.phy_link_handle); + + if ( !Status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: BslFindAndInitPhyCtx failed"); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPPhysicalLinkCreate( pctx->bapHdl, + &CreatePhysicalLinkCmd, pPhyCtx, &HCIEvt ); + + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPPhysicalLinkCreate failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pPhyCtx, &HCIEvt, TRUE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_ACCEPT_PHYSICAL_LINK_CMD: + { + tBtampTLVHCI_Accept_Physical_Link_Cmd AcceptPhysicalLinkCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Accept_Physical_Link_Cmd( NULL, + pBuf, Count, &AcceptPhysicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Accept_Physical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + if(VOS_FALSE == WLANBAP_AmpConnectionAllowed()) + { + VosStatus = WLANBAP_PhyLinkFailure(pctx, AcceptPhysicalLinkCmd.phy_link_handle); + if ( VOS_STATUS_SUCCESS != VosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLANBAP_PhyLinkFailure failed"); + // handle the error + return(FALSE); + } + break; + } + + // setup the per PHY link BAP context + Status = BslFindAndInitPhyCtx( pctx, AcceptPhysicalLinkCmd.phy_link_handle, + &pPhyCtx ); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "AcceptPhysicalLinkCmd.phy_link_handle=%d",AcceptPhysicalLinkCmd.phy_link_handle); + + if ( !Status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: BslFindAndInitPhyCtx failed"); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPPhysicalLinkAccept( pctx->bapHdl, + &AcceptPhysicalLinkCmd, pPhyCtx, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPPhysicalLinkAccept failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pPhyCtx, &HCIEvt, TRUE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + BslReleasePhyCtx( pPhyCtx ); + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_PHYSICAL_LINK_CMD: + { + tBtampTLVHCI_Disconnect_Physical_Link_Cmd DisconnectPhysicalLinkCmd; + Count = Count - 3;//Type and length field lengths are not needed + pTmp = pBuf; + for(i=0; i<4; i++) + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: *pBuf in Disconnect phy link pTmp[%x] = %x", i,pTmp[i] ); + // unpack + UnpackStatus = btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd( NULL, + pBuf, Count, &DisconnectPhysicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Disconnect_Physical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPPhysicalLinkDisconnect( pctx->bapHdl, + &DisconnectPhysicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPPhysicalLinkDisconnect failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_CREATE_LOGICAL_LINK_CMD: + { + tBtampTLVHCI_Create_Logical_Link_Cmd CreateLogicalLinkCmd; + Count -= 3; //To send the correct length to unpack event + // unpack + UnpackStatus = btampUnpackTlvHCI_Create_Logical_Link_Cmd( NULL, + pBuf, Count, &CreateLogicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Create_Logical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkCreate( pctx->bapHdl, + &CreateLogicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkCreate failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_ACCEPT_LOGICAL_LINK_CMD: + { + tBtampTLVHCI_Accept_Logical_Link_Cmd AcceptLogicalLinkCmd; + Count = Count - 3;//Subtract Type and Length fields + // unpack + UnpackStatus = btampUnpackTlvHCI_Accept_Logical_Link_Cmd( NULL, + pBuf, Count, &AcceptLogicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Accept_Logical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkAccept( pctx->bapHdl, + &AcceptLogicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkAccept failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_DISCONNECT_LOGICAL_LINK_CMD: + { + tBtampTLVHCI_Disconnect_Logical_Link_Cmd DisconnectLogicalLinkCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd( NULL, + pBuf, Count, &DisconnectLogicalLinkCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Disconnect_Logical_Link_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkDisconnect( pctx->bapHdl, + &DisconnectLogicalLinkCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkDisconnect failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_LOGICAL_LINK_CANCEL_CMD: + { + tBtampTLVHCI_Logical_Link_Cancel_Cmd LogicalLinkCancelCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Logical_Link_Cancel_Cmd( NULL, + pBuf, Count, &LogicalLinkCancelCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Logical_Link_Cancel_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPLogicalLinkCancel( pctx->bapHdl, + &LogicalLinkCancelCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPLogicalLinkCancel failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_FLOW_SPEC_MODIFY_CMD: + { + tBtampTLVHCI_Flow_Spec_Modify_Cmd FlowSpecModifyCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Flow_Spec_Modify_Cmd( NULL, + pBuf, Count, &FlowSpecModifyCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Flow_Spec_Modify_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPFlowSpecModify( pctx->bapHdl, + &FlowSpecModifyCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPFlowSpecModify failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* + Host Controller and Baseband Commands + */ + case BTAMP_TLV_HCI_RESET_CMD: + { + VosStatus = WLAN_BAPReset( pctx->bapHdl ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReset failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_SET_EVENT_MASK_CMD: + { + tBtampTLVHCI_Set_Event_Mask_Cmd SetEventMaskCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Set_Event_Mask_Cmd( NULL, + pBuf, Count, &SetEventMaskCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Set_Event_Mask_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPSetEventMask( pctx->bapHdl, + &SetEventMaskCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPSetEventMask failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_FLUSH_CMD: + { + tBtampTLVHCI_Flush_Cmd FlushCmd; + + // unpack + UnpackStatus = btampUnpackTlvHCI_Flush_Cmd( NULL, + pBuf, Count, &FlushCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Flush_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + /* Flush the TX queue */ +//#ifdef BAP_DEBUG + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s:HCI Flush command - will flush Tx Queue", __func__); +//#endif //BAP_DEBUG + // JEZ100604: Temporary short cut + pPhyCtx = &BslPhyLinkCtx[0]; + VosStatus = BslFlushTxQueues ( pPhyCtx); + + /* Acknowledge the command */ + VosStatus = WLAN_BAPFlush( pctx->bapHdl, &FlushCmd ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLAN_BAPFlush failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_ENHANCED_FLUSH_CMD: + { + tBtampTLVHCI_Enhanced_Flush_Cmd FlushCmd; + + // unpack + UnpackStatus = btampUnpackTlvHCI_Enhanced_Flush_Cmd( NULL, + pBuf, Count, &FlushCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: btampUnpackTlvHCI_Enhanced_Flush_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + /* Flush the TX queue */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s:HCI Flush command - will flush Tx Queue for pkt type %d", __func__, FlushCmd.packet_type); + // We support BE traffic only + if(WLANTL_AC_BE == FlushCmd.packet_type) + { + pPhyCtx = &BslPhyLinkCtx[0]; + VosStatus = BslFlushTxQueues ( pPhyCtx); + } + + /* Acknowledge the command */ + VosStatus = WLAN_EnhancedBAPFlush( pctx->bapHdl, &FlushCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLAN_EnahncedBAPFlush failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_CONNECTION_ACCEPT_TIMEOUT_CMD: + { + VosStatus = WLAN_BAPReadConnectionAcceptTimeout( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadConnectionAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Connection_Accept_Timeout_Cmd WriteConnectionAcceptTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd( NULL, + pBuf, Count, &WriteConnectionAcceptTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Connection_Accept_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteConnectionAcceptTimeout( pctx->bapHdl, + &WriteConnectionAcceptTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteConnectionAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LINK_SUPERVISION_TIMEOUT_CMD: + { + tBtampTLVHCI_Read_Link_Supervision_Timeout_Cmd ReadLinkSupervisionTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd( NULL, + pBuf, Count, &ReadLinkSupervisionTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Link_Supervision_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLinkSupervisionTimeout( pctx->bapHdl, + &ReadLinkSupervisionTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLinkSupervisionTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LINK_SUPERVISION_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Link_Supervision_Timeout_Cmd WriteLinkSupervisionTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd( NULL, + pBuf, Count, &WriteLinkSupervisionTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Link_Supervision_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLinkSupervisionTimeout( pctx->bapHdl, + &WriteLinkSupervisionTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLinkSupervisionTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* v3.0 Host Controller and Baseband Commands */ + case BTAMP_TLV_HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + { + VosStatus = WLAN_BAPReadLogicalLinkAcceptTimeout( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLogicalLinkAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Logical_Link_Accept_Timeout_Cmd WriteLogicalLinkAcceptTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd( NULL, + pBuf, Count, &WriteLogicalLinkAcceptTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Logical_Link_Accept_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLogicalLinkAcceptTimeout( pctx->bapHdl, + &WriteLogicalLinkAcceptTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLogicalLinkAcceptTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_SET_EVENT_MASK_PAGE_2_CMD: + { + tBtampTLVHCI_Set_Event_Mask_Page_2_Cmd SetEventMaskPage2Cmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd( NULL, + pBuf, Count, &SetEventMaskPage2Cmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Set_Event_Mask_Page_2_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPSetEventMaskPage2( pctx->bapHdl, + &SetEventMaskPage2Cmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPSetEventMaskPage2 failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCATION_DATA_CMD: + { + VosStatus = WLAN_BAPReadLocationData( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocationData failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LOCATION_DATA_CMD: + { + tBtampTLVHCI_Write_Location_Data_Cmd WriteLocationDataCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Location_Data_Cmd( NULL, + pBuf, Count, &WriteLocationDataCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Location_Data_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLocationData( pctx->bapHdl, + &WriteLocationDataCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLocationData failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_FLOW_CONTROL_MODE_CMD: + { + VosStatus = WLAN_BAPReadFlowControlMode( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadFlowControlMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_FLOW_CONTROL_MODE_CMD: + { + tBtampTLVHCI_Write_Flow_Control_Mode_Cmd WriteFlowControlModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd( NULL, + pBuf, Count, &WriteFlowControlModeCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Flow_Control_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteFlowControlMode( pctx->bapHdl, + &WriteFlowControlModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteFlowControlMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT_CMD: + { + tBtampTLVHCI_Read_Best_Effort_Flush_Timeout_Cmd ReadBestEffortFlushTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd( NULL, + pBuf, Count, &ReadBestEffortFlushTimeoutCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Best_Effort_Flush_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadBestEffortFlushTimeout( pctx->bapHdl, + &ReadBestEffortFlushTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadBestEffortFlushTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CMD: + { + tBtampTLVHCI_Write_Best_Effort_Flush_Timeout_Cmd WriteBestEffortFlushTimeoutCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd( NULL, + pBuf, Count, &WriteBestEffortFlushTimeoutCmd); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Best_Effort_Flush_Timeout_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteBestEffortFlushTimeout( pctx->bapHdl, + &WriteBestEffortFlushTimeoutCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteBestEffortFlushTimeout failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /** opcode definition for this command from AMP HCI CR D9r4 markup */ + case BTAMP_TLV_HCI_SET_SHORT_RANGE_MODE_CMD: + { + tBtampTLVHCI_Set_Short_Range_Mode_Cmd SetShortRangeModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd( NULL, + pBuf, Count, &SetShortRangeModeCmd); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Set_Short_Range_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPSetShortRangeMode( pctx->bapHdl, + &SetShortRangeModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPSetShortRangeMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* End of v3.0 Host Controller and Baseband Commands */ + /* + Informational Parameters + */ + case BTAMP_TLV_HCI_READ_LOCAL_VERSION_INFO_CMD: + { + VosStatus = WLAN_BAPReadLocalVersionInfo( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalVersionInfo failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCAL_SUPPORTED_CMDS_CMD: + { + VosStatus = WLAN_BAPReadLocalSupportedCmds( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalSupportedCmds failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_BUFFER_SIZE_CMD: + { + VosStatus = WLAN_BAPReadBufferSize( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadBufferSize failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* v3.0 Informational commands */ + case BTAMP_TLV_HCI_READ_DATA_BLOCK_SIZE_CMD: + { + VosStatus = WLAN_BAPReadDataBlockSize( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadDataBlockSize failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* + Status Parameters + */ + case BTAMP_TLV_HCI_READ_FAILED_CONTACT_COUNTER_CMD: + { + tBtampTLVHCI_Read_Failed_Contact_Counter_Cmd ReadFailedContactCounterCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd( NULL, + pBuf, Count, &ReadFailedContactCounterCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Failed_Contact_Counter_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadFailedContactCounter( pctx->bapHdl, + &ReadFailedContactCounterCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadFailedContactCounter failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_RESET_FAILED_CONTACT_COUNTER_CMD: + { + tBtampTLVHCI_Reset_Failed_Contact_Counter_Cmd ResetFailedContactCounterCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd( NULL, + pBuf, Count, &ResetFailedContactCounterCmd); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Reset_Failed_Contact_Counter_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPResetFailedContactCounter( pctx->bapHdl, + &ResetFailedContactCounterCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPResetFailedContactCounter failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LINK_QUALITY_CMD: + { + tBtampTLVHCI_Read_Link_Quality_Cmd ReadLinkQualityCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Link_Quality_Cmd( NULL, + pBuf, Count, &ReadLinkQualityCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Link_Quality_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLinkQuality( pctx->bapHdl, + &ReadLinkQualityCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLinkQuality failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_RSSI_CMD: + { + tBtampTLVHCI_Read_RSSI_Cmd ReadRssiCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_RSSI_Cmd( NULL, + pBuf, Count, &ReadRssiCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_RSSI_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadRSSI( pctx->bapHdl, + &ReadRssiCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadRSSI failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCAL_AMP_INFORMATION_CMD: + { + tBtampTLVHCI_Read_Local_AMP_Information_Cmd ReadLocalAmpInformationCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd( NULL, + pBuf, Count, &ReadLocalAmpInformationCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Local_AMP_Information_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLocalAMPInfo( pctx->bapHdl, + &ReadLocalAmpInformationCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalAMPInfo failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_READ_LOCAL_AMP_ASSOC_CMD: + { + tBtampTLVHCI_Read_Local_AMP_Assoc_Cmd ReadLocalAmpAssocCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd( NULL, + pBuf, Count, &ReadLocalAmpAssocCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Local_AMP_Assoc_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLocalAMPAssoc( pctx->bapHdl, + &ReadLocalAmpAssocCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLocalAMPAssoc failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_REMOTE_AMP_ASSOC_CMD: + { + tBtampTLVHCI_Write_Remote_AMP_ASSOC_Cmd WriteRemoteAmpAssocCmd; + // unpack + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: HCI_Write_Remote_AMP_ASSOC_Cmd Count = %d", Count); + DUMPLOG(1, __func__, "HCI_Write_Remote_AMP_ASSOC cmd", + pBuf, + Count); + + UnpackStatus = btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd( NULL, + pBuf, Count, &WriteRemoteAmpAssocCmd ); + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WriteRemoteAmpAssocCmd.amp_assoc_remaining_length = %d", + WriteRemoteAmpAssocCmd.amp_assoc_remaining_length + ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Remote_AMP_ASSOC_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + +//#define BAP_UNIT_TEST +#ifdef BAP_UNIT_TEST + { + unsigned char test_amp_assoc_fragment[] = + { + 0x01, 0x00, 0x06, 0x00, 0x00, 0xde, 0xad, 0xbe, + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x0c, 0x00, 0x55, 0x53, 0x20, 0xc9, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x06, 0x00, 0x55, 0x53, + 0x20, 0xc9, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }; + WriteRemoteAmpAssocCmd.present = 1; + WriteRemoteAmpAssocCmd.phy_link_handle = 1; + WriteRemoteAmpAssocCmd.length_so_far = 0; + WriteRemoteAmpAssocCmd.amp_assoc_remaining_length = 74; + /* Set the amp_assoc_fragment to the right values of MAC addr and + * channels + */ + vos_mem_copy( + WriteRemoteAmpAssocCmd.amp_assoc_fragment, + test_amp_assoc_fragment, + sizeof( test_amp_assoc_fragment)); + + } +#endif + + VosStatus = WLAN_BAPWriteRemoteAMPAssoc( pctx->bapHdl, + &WriteRemoteAmpAssocCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteRemoteAMPAssoc failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + /* + Debug Commands + */ + case BTAMP_TLV_HCI_READ_LOOPBACK_MODE_CMD: + { + tBtampTLVHCI_Read_Loopback_Mode_Cmd ReadLoopbackModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Read_Loopback_Mode_Cmd( NULL, + pBuf, Count, &ReadLoopbackModeCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Read_Loopback_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPReadLoopbackMode( pctx->bapHdl, + &ReadLoopbackModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPReadLoopbackMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_WRITE_LOOPBACK_MODE_CMD: + { + tBtampTLVHCI_Write_Loopback_Mode_Cmd WriteLoopbackModeCmd; + // unpack + UnpackStatus = btampUnpackTlvHCI_Write_Loopback_Mode_Cmd( NULL, + pBuf, Count, &WriteLoopbackModeCmd ); + + if ( !BTAMP_SUCCEEDED( UnpackStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: btampUnpackTlvHCI_Write_Loopback_Mode_Cmd failed status %d", UnpackStatus); + // handle the error + return(FALSE); + } + + VosStatus = WLAN_BAPWriteLoopbackMode( pctx->bapHdl, + &WriteLoopbackModeCmd, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPWriteLoopbackMode failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_0: + { + VosStatus = WLAN_BAPVendorSpecificCmd0( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPVendorSpecificCmd0 failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + case BTAMP_TLV_HCI_VENDOR_SPECIFIC_CMD_1: + { + VosStatus = WLAN_BAPVendorSpecificCmd1( pctx->bapHdl, &HCIEvt ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLAN_BAPVendorSpecificCmd1 failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + break; + } + default: + { + /* Unknow opcode. Return a command status event...with "Unknown Opcode" status */ + + /* Format the command status event to return... */ + HCIEvt.bapHCIEventCode = BTAMP_TLV_HCI_COMMAND_STATUS_EVENT; + HCIEvt.u.btampCommandStatusEvent.present = 1; + HCIEvt.u.btampCommandStatusEvent.status = WLANBAP_ERROR_UNKNOWN_HCI_CMND; + HCIEvt.u.btampCommandStatusEvent.num_hci_command_packets = 1; + HCIEvt.u.btampCommandStatusEvent.command_opcode + = cmdOpcode; + + // this may look strange as this is the function registered + // with BAP for the EventCB but we are also going to use it + // as a helper function. The difference is that this invocation + // runs in HCI command sending caller context while the callback + // will happen in BAP's context whatever that may be + VosStatus = WLANBAP_EventCB( pctx, &HCIEvt, FALSE ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BslProcessHCICommand: WLANBAP_EventCB failed status %d", VosStatus); + // handle the error + return(FALSE); + } + + + break; + } + } + + return(TRUE); +} // BslProcessHCICommand() + + +/** + @brief BslProcessACLDataTx() - This function will process an egress ACL data packet + + @param pctx : [in] ptr to the client context + @param pBuffer_ : [in] ptr to the buffer containing the ACL data packet + @param pCount : [in] size of the ACL data packet buffer + + @return + TRUE if all OK, FALSE otherwise + +*/ +#define BTAMP_USE_VOS_WRAPPER +//#undef BTAMP_USE_VOS_WRAPPER +#ifdef BTAMP_USE_VOS_WRAPPER +static BOOL BslProcessACLDataTx +( + BslClientCtxType* pctx, + struct sk_buff *skb, + v_SIZE_t* pCount +) +#else +static BOOL BslProcessACLDataTx +( + BslClientCtxType* pctx, + LPCVOID pBuffer_, + v_SIZE_t* pCount +) +#endif +{ +#ifndef BTAMP_USE_VOS_WRAPPER + LPVOID pBuffer = (LPVOID) pBuffer_; // castaway const-ness of ptr +#endif + BOOL findPhyStatus; + BslPhyLinkCtxType* pPhyCtx; + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + WLANTL_ACEnumType Ac; + hdd_list_node_t* pLink; + BslTxListNodeType *pNode; + v_SIZE_t ListSize; + // I will access the skb in a VOSS packet +#ifndef BTAMP_USE_VOS_WRAPPER + struct sk_buff *skb; +#endif +#if 0 + static int num_packets; +#endif + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BslProcessACLDataTx" ); + + // need to find the PHY link for this ACL data pkt based on phy_link_handle + // TODO need some endian-ness check? + ////findPhyStatus = BslFindPhyCtx( pctx, *(v_U8_t *)skb->data, &pPhyCtx ); + //findPhyStatus = BslFindPhyCtx( pctx, *(v_U8_t *)pBuffer, &pPhyCtx ); + // JEZ100604: Temporary short cut + pPhyCtx = &BslPhyLinkCtx[0]; + findPhyStatus = VOS_TRUE; + + if ( findPhyStatus ) + { + //Use the skb->cb field to hold the list node information + pNode = (BslTxListNodeType *) &skb->cb; + + // This list node info includes the VOS pkt + pNode->skb = skb; + + // stick the SKB into the node + pLink = (hdd_list_node_t *) pNode; + VosStatus = WLANBAP_GetAcFromTxDataPkt(pctx->bapHdl, skb->data, &Ac); + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessACLDataTx WLANBAP_GetAcFromTxDataPkt " + "failed status =%d", VosStatus ); + + Ac = WLANTL_AC_BE; + } + + // now queue the pkt into the correct queue + // We will want to insert a node of type BslTxListNodeType (was going to be vos_pkt_list_node_t) + spin_lock_bh(&pPhyCtx->ACLTxQueue[Ac].lock); + VosStatus = hdd_list_insert_back( &pPhyCtx->ACLTxQueue[Ac], pLink ); + spin_unlock_bh(&pPhyCtx->ACLTxQueue[Ac].lock); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + // determine if there is a need to signal TL through BAP + hdd_list_size( &pPhyCtx->ACLTxQueue[Ac], &ListSize ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_ASSERT(0); + } + + if ( ListSize == 1 ) + { + // Let TL know we have a packet to send for this AC + VosStatus = WLANBAP_STAPktPending( pctx->bapHdl, pPhyCtx->PhyLinkHdl, Ac ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessACLDataTx WLANBAP_STAPktPending " + "failed status =%d", VosStatus ); + VOS_ASSERT(0); + } + } + + return(TRUE); + } + else + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BslProcessACLDataTx attempting to send " + "data for a non-existant assocation" ); + + return(FALSE); + } + + +} // BslProcessACLDataTx() + + +static inline void *hci_get_drvdata(struct hci_dev *hdev) +{ + return hdev->driver_data; +} + +static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) +{ + hdev->driver_data = data; +} + +/*--------------------------------------------------------------------------- + * Function definitions + *-------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief BSL_Init() - Initialize the BSL Misc char driver + + This is called in vos_open(), right after WLANBAP_Open(), as part of + bringing up the BT-AMP PAL (BAP) + vos_open() will pass in the VOS context. In which a BSL context can be created. + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +//int BSL_Init (void *pCtx) +int BSL_Init ( v_PVOID_t pvosGCtx ) +{ + BslClientCtxType* pctx = NULL; + ptBtampHandle bapHdl = NULL; // our handle in BAP + //ptBtampContext pBtampCtx = NULL; + int err = 0; + struct hci_dev *hdev = NULL; + //struct net_device *dev = NULL; // Our parent wlan network device + hdd_adapter_t *pAdapter = NULL; // Used to retrieve the parent WLAN device + hdd_context_t *pHddCtx = NULL; + hdd_config_t *pConfig = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL; + VOS_STATUS status; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Init"); + + /*------------------------------------------------------------------------ + Allocate (and sanity check?!) BSL control block + ------------------------------------------------------------------------*/ + //vos_alloc_context(pvosGCtx, VOS_MODULE_ID_BSL, (v_VOID_t**)&pctx, sizeof(BslClientCtxType)); + pctx = &BslClientCtx[0]; + + bapHdl = vos_get_context( VOS_MODULE_ID_BAP, pvosGCtx); + if ( NULL == bapHdl ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BAP pointer from pvosGCtx on BSL_Init"); + return VOS_STATUS_E_FAULT; + } + // Save away the btamp (actually the vos) context + gpCtx = pvosGCtx; + + /* Save away the pointer to the BT-AMP PAL context in the BSL driver context */ + pctx->bapHdl = bapHdl; + + /* Save away the pointer to the BSL driver context in a global (fix this) */ + gpBslctx = pctx; + + /* Initialize all the Phy Contexts to un-used */ + BslInitPhyCtx(); + + /* Initialize the Rx fields in the HCI driver context */ + //pctx->rx_state = RECV_WAIT_PACKET_TYPE; + pctx->rx_count = 0; + pctx->rx_skb = NULL; + + /* JEZ100713: Temporarily the Tx skb queue will have depth one.*/ + // Don't disturb tx_skb + //pctx->tx_skb = NULL; + //pctx->tx_skb = alloc_skb(WLANBAP_MAX_80211_PAL_PDU_SIZE+12, GFP_ATOMIC); + + pctx->hdev = NULL; + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, pvosGCtx ); + if(NULL != pHddCtx) + { + pConfig = pHddCtx->cfg_ini; + } + if(NULL == pConfig) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Didn't register as HCI device"); + return 0; + } + else if(0 == pConfig->enableBtAmp) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, + "Didn't register as HCI device, user option(gEnableBtAmp) is set to 0"); + return 0; + } + + if (VOS_STA_SAP_MODE == hdd_get_conparam()) + { + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + if ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + if ( WLAN_HDD_SOFTAP == pAdapterNode->pAdapter->device_mode) + { + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + } + else if (WLAN_HDD_P2P_GO == pAdapterNode->pAdapter->device_mode) + { + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO); + } + } + } + else + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid HDD Adapter pointer from pvosGCtx on BSL_Init"); + return VOS_STATUS_E_FAULT; + } + + /* Save away the pointer to the parent WLAN device in BSL driver context */ + pctx->p_dev = pAdapter->dev; + + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Can't allocate HCI device in BSL_Init"); + return VOS_STATUS_E_FAULT; + } + + /* Save away the HCI device pointer in the BSL driver context */ + pctx->hdev = hdev; + +#if defined HCI_80211 || defined HCI_AMP +#define BUILD_FOR_BLUETOOTH_NEXT_2_6 +#else +#undef BUILD_FOR_BLUETOOTH_NEXT_2_6 +#endif + +#ifdef BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->bus = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ +#ifdef HCI_80211 + hdev->dev_type = HCI_80211; +#else + hdev->dev_type = HCI_AMP; +#endif +#ifdef FEATURE_WLAN_BTAMP_UT + /* For the "real" BlueZ build, DON'T Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif +#else //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->type = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ + //hdev->dev_type = HCI_80211; + ////hdev->dev_type = HCI_AMP; + /* For the "temporary" BlueZ build, Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* Save away the BSL driver pointer in the HCI device context */ + + hci_set_drvdata(hdev, pctx); + /* Set the parent device for this HCI device. This is our WLAN net_device */ + SET_HCIDEV_DEV(hdev, &pctx->p_dev->dev); + + hdev->open = BSL_Open; + hdev->close = BSL_Close; + hdev->flush = BSL_Flush; + hdev->send = BSL_Write; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + hdev->destruct = BSL_Destruct; + hdev->owner = THIS_MODULE; +#endif + hdev->ioctl = BSL_IOControl; + + + /* Timeout before it is safe to send the first HCI packet */ + msleep(1000); + + /* Register HCI device */ + err = hci_register_dev(hdev); + if (err < 0) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unable to register HCI device, err=%d", err); + pctx->hdev = NULL; + hci_free_dev(hdev); + return -ENODEV; + } + + pHddCtx->isAmpAllowed = VOS_TRUE; + return 0; +} // BSL_Init() + +/**--------------------------------------------------------------------------- + + \brief BSL_Deinit() - De-initialize the BSL Misc char driver + + This is called in by WLANBAP_Close() as part of bringing down the BT-AMP PAL (BAP) + + \param - NA + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ + +int BSL_Deinit( v_PVOID_t pvosGCtx ) +{ + //int err = 0; + struct hci_dev *hdev; + BslClientCtxType* pctx = NULL; + + //pctx = vos_get_context( VOS_MODULE_ID_BSL, pvosGCtx); + pctx = gpBslctx; + + if ( NULL == pctx ) + { + //VOS_TRACE( VOS_MODULE_ID_BSL, VOS_TRACE_LEVEL_ERROR, + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on BSL_Init"); + return VOS_STATUS_E_FAULT; + } + + /* Retrieve the HCI device pointer from the BSL driver context */ + hdev = pctx->hdev; + + if (!hdev) + return 0; + + /* hci_unregister_dev is called again here, in case user didn't call it */ + /* Unregister device from BlueZ; fcn sends us HCI commands before it returns */ + /* And then the registered hdev->close fcn should be called by BlueZ (BSL_Close) */ + hci_unregister_dev(hdev); + /* BSL_Close is called again here, in case BlueZ didn't call it */ + BSL_Close(hdev); + hci_free_dev(hdev); + pctx->hdev = NULL; + + return 0; +} // BSL_Deinit() + + +/** + @brief BSL_Open() - This function opens a device for reading, and writing. + An application indirectly invokes this function when it calls the fopen() + system call to open a special device file names. + + @param *hdev : [in] pointer to the open HCI device structure. + BSL_Init (Device Manager) function creates and stores this HCI + device context in the BSL context. + + @return + This function returns a status code. Negative codes are failures. + + NB: I don't seem to be following this convention. +*/ +//static int BSL_Open(struct inode *pInode, struct file *pFile) +static int BSL_Open( struct hci_dev *hdev ) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BslClientCtxType* pctx = (BslClientCtxType *)(hci_get_drvdata(hdev)); + v_U16_t i; + BOOL rval; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Open"); + + /* you can only open a btamp device one time */ + if (bBslInited) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "BSL_Open: Already Opened."); + return -EPERM; /* Operation not permitted */ + } + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSLClientLock already inited"); + // return -EIO; /* I/O error */ + return 0; + } + + VosStatus = vos_list_init( &BslPhyLinksDescPool ); + + if ( !VOS_IS_STATUS_SUCCESS( VosStatus ) ) + { + //return -EIO; /* I/O error */ + return 0; + } + + // now we need to populate this pool with the free pkt desc from the array + for ( i=0; iprivate_data != NULL) + bBslInited = TRUE; + + rval = BslFindAndInitClientCtx( &pctx ); + + if(rval != TRUE) + { + // Where is the clean-up in case the above BslFindAndInitClientCtx() call + // fails? + //return -EIO; /* I/O error */ + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSLFindAndInitClientContext failed"); + return 0; + } + + + /* Let Linux fopen() know everything is all right */ + return 0; +} // BSL_Open() + +/** + @brief BSL_Close() - This function closes a device context created by + BSL_Open(). May be called more than once during AMP PAL shut down. + + @param *hdev : [in] pointer to the open HCI device structure. + BSL_Init (Device Manager) function creates and stores this HCI + device context in the BSL context. + + @return + TRUE indicates success. FALSE indicates failure. +*/ +//static int BSL_Close (struct inode *pInode, struct file *pFile) +static int BSL_Close ( struct hci_dev *hdev ) +{ + VOS_STATUS VosStatus = VOS_STATUS_SUCCESS; + BslClientCtxType* pctx; + vos_list_node_t* pLink; + v_U16_t i; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Close"); + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + pHddCtx->isAmpAllowed = VOS_FALSE; + } + } + + // it may seem there is some risk here because we are using a value + // passed into us as a pointer. what if this pointer is 0 or points to + // someplace bad? as it turns out the caller is device manager and not + // the application. kernel should trap such invalid access but we will check + // for NULL pointer + if ( hdev == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "BSL_Close: NULL hdev specified"); + return FALSE; + } + + pctx = (BslClientCtxType *)(hci_get_drvdata(hdev)); + + if ( pctx == NULL || !bBslInited) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_LOW, "BSL_Close: %s is not open", hdev->name); + return TRUE; + } + + // need to cleanup any per PHY state and the common RX state + BslReleaseClientCtx( pctx ); + for ( i=0; ilen)=%d", __func__, skb->len); + + // Sanity check inputs + if ( 0 == skb->len ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: skb is empty", __func__); + //return -EFAULT; /* Bad address */ + return 0; + } + + hdev = (struct hci_dev *)(skb->dev); + + // Sanity check the HCI device in the skb + if ( hdev == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Frame for Unknown HCI device (hdev=NULL)", __func__); + //return -ENODEV; /* no device */ + return 0; + } + + pctx = (BslClientCtxType *)hci_get_drvdata(hdev); + + // Sanity check inputs + if ( pctx == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: pctx is bad i/p", __func__); + //return -EFAULT; /* Bad address */ + return 0; + /* Maybe I should return "no device" */ + //return -ENODEV; /* no device */ + } + + // Switch for each case of packet type + switch (bt_cb(skb)->pkt_type) + { + case HCI_ACLDATA_PKT: + // Directly execute the data write + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: HCI ACL data tx, skb=%p", + __func__, skb); + // ACL data + hdev->stat.acl_tx++; + // Correct way of doing this... + written = skb->len; +#ifdef BTAMP_USE_VOS_WRAPPER + status = BslProcessACLDataTx( pctx, skb, &written ); +#else + status = BslProcessACLDataTx( pctx, skb->data, &written ); + // Free up the skb + kfree_skb(skb); +#endif //BTAMP_USE_VOS_WRAPPER + break; + case HCI_COMMAND_PKT: + // Defer the HCI command writes + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HCI command", __func__); + hdev->stat.cmd_tx++; + + // Allocate an HCI context. To use as a "container" for the "work" to be deferred. + pHciContext = kmalloc(sizeof(*pHciContext), GFP_ATOMIC); + if (NULL == pHciContext) + { + // no memory for HCI context. Nothing we can do but drop + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate context", __func__); + kfree_skb(skb); + return 0; + } + + // save away the tx skb in the HCI context...so it can be + // retrieved by the work procedure. + pHciContext->tx_skb = skb; + // save away the pctx context...so it can be retrieved by the work procedure. + pHciContext->pctx = pctx; + pHciContext->magic = BT_AMP_HCI_CTX_MAGIC; + vos_init_work(&pHciContext->hciInterfaceProcessing, + bslWriteFinish); + + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Scheduling work for skb %p, BT-AMP Client context %p, work %p", + __func__, skb, pctx, pHciContext); + + status = schedule_work(&pHciContext->hciInterfaceProcessing); + + // Check result + if ( 0 == status ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: hciInterfaceProcessing work already queued. This should never happen.", __func__); + } + + + // Temporary way of doing this + //written = skb->len-CMD_TLV_TYPE_AND_LEN_SIZE; + written = skb->len; + break; + case HCI_SCODATA_PKT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: unknown type", __func__); + hdev->stat.sco_tx++; + // anything else including HCI events and SCO data + status = FALSE; + // Free up the skb + kfree_skb(skb); + break; + default: + // anything else including HCI events and SCO data + status = FALSE; + // Free up the skb + kfree_skb(skb); + break; + }; + + + // JEZ100809: For the HCI command, will the caller need to wait until the work takes place and + // return the ACTUAL amount of data written. + +// The next line is temporary + //written = skb->len; + return(written); +} // BSL_Write() + +/** + @brief bslWriteFinish() - This function finished the writes operation + started by BSL_Write(). + + @param work : [in] pointer to work structure + + @return : void + +*/ +static void bslWriteFinish(struct work_struct *work) +{ + //BslClientCtxType* pctx = + // container_of(work, BslClientCtxType, hciInterfaceProcessing); + BslHciWorkStructure *pHciContext = + container_of(work, BslHciWorkStructure, hciInterfaceProcessing); + BslClientCtxType* pctx = pHciContext->pctx; + VOS_STATUS status; + struct sk_buff *skb; + struct hci_dev *hdev; + //char *bslBuff = NULL; + v_SIZE_t written = 0; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pctx); + + // Sanity check inputs + if ( pctx == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: pctx is bad i/p", __func__); + return; // -EFAULT; /* Bad address */ + } + + //skb = pctx->tx_skb; + skb = pHciContext->tx_skb; + kfree( pHciContext); + + // Sanity check inputs + if ( skb == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: skb is bad i/p", __func__); + return; // -EFAULT; /* Bad address */ + } + + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Count (skb->len)=%d", __func__, skb->len); + + hdev = (struct hci_dev *)(skb->dev); + + // Sanity check the HCI device in the skb + if ( hdev == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Frame for Unknown HCI device (hdev=NULL)", __func__); + return; // -ENODEV; /* no device */ + } + + + // Sanity check inputs + if ( pctx != (BslClientCtxType *)hci_get_drvdata(hdev)); + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: pctx and hdev not consistent - bad i/p", __func__); + return; // -EFAULT; /* Bad address */ + /* Maybe I should return "no device" */ + //return -ENODEV; /* no device */ + } + + // Switch for each case of packet type + switch (bt_cb(skb)->pkt_type) + { + case HCI_COMMAND_PKT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HCI command", __func__); + hdev->stat.cmd_tx++; + // HCI command + status = BslProcessHCICommand( pctx, skb->data, skb->len-CMD_TLV_TYPE_AND_LEN_SIZE); + // Temporary way of doing this + //written = skb->len-CMD_TLV_TYPE_AND_LEN_SIZE; + written = skb->len; + break; + case HCI_SCODATA_PKT: + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: unknown type", __func__); + hdev->stat.sco_tx++; + // anything else including HCI events and SCO data + status = FALSE; + break; + default: + // anything else including HCI events and SCO data + status = FALSE; + break; + }; + + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Freeing skb %p", + __func__, skb); + + consume_skb(skb); + +// How do I return the actual number of bytes written to the caller? +// return(written); + return; +} //bslWriteFinish() + +VOS_STATUS WLANBAP_SetConfig +( + WLANBAP_ConfigType *pConfig +) +{ + BslClientCtxType* pctx; + VOS_STATUS status; + // sanity checking + if ( pConfig == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_SetConfig bad input" ); + return VOS_STATUS_E_FAILURE; + } + pctx = gpBslctx; + if ( NULL == pctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pctx on WLANBAP_SetConfig"); + return VOS_STATUS_E_FAULT; + } + + // get a handle from BAP + status = WLANBAP_GetNewHndl(&pctx->bapHdl); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_SetConfig can't get BAP handle" ); + return VOS_STATUS_E_FAILURE; + } + + + status = WLAN_BAPSetConfig(pctx->bapHdl, pConfig); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_SetConfig can't set BAP config" ); + return VOS_STATUS_E_FAILURE; + } + + return(VOS_STATUS_SUCCESS); +} + +VOS_STATUS WLANBAP_RegisterWithHCI(hdd_adapter_t *pAdapter) +{ + struct hci_dev *hdev = NULL; + BslClientCtxType* pctx = NULL; + int err = 0; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + + pctx = gpBslctx; + + if ( NULL == pctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pctx on WLANBAP_RegisterWithHCI"); + return VOS_STATUS_E_FAULT; + } + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid HDD Adapter pointer from pvosGCtx on WLANBAP_RegisterWithHCI"); + return VOS_STATUS_E_FAULT; + } + + if(NULL != pctx->hdev) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_WARN, + "Already registered as HCI device"); + return VOS_STATUS_SUCCESS; + } + + + + /* Save away the pointer to the parent WLAN device in BSL driver context */ + pctx->p_dev = pAdapter->dev; + + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Can't allocate HCI device in WLANBAP_RegisterWithHCI"); + return VOS_STATUS_E_FAULT; + } + + /* Save away the HCI device pointer in the BSL driver context */ + pctx->hdev = hdev; + +#if defined HCI_80211 || defined HCI_AMP +#define BUILD_FOR_BLUETOOTH_NEXT_2_6 +#else +#undef BUILD_FOR_BLUETOOTH_NEXT_2_6 +#endif + +#ifdef BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->bus = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ +#ifdef HCI_80211 + hdev->dev_type = HCI_80211; +#else + hdev->dev_type = HCI_AMP; +#endif +#ifdef FEATURE_WLAN_BTAMP_UT + /* For the "real" BlueZ build, DON'T Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif +#else //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* HCI "bus type" of HCI_VIRTUAL should apply */ + hdev->type = HCI_VIRTUAL; + /* Set the dev_type to BT-AMP 802.11 */ + //hdev->dev_type = HCI_80211; + ////hdev->dev_type = HCI_AMP; + /* For the "temporary" BlueZ build, Set the device "quirks" to indicate RAW */ + set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); +#endif //BUILD_FOR_BLUETOOTH_NEXT_2_6 + /* Save away the BSL driver pointer in the HCI device context */ + hci_set_drvdata(hdev, pctx); + /* Set the parent device for this HCI device. This is our WLAN net_device */ + SET_HCIDEV_DEV(hdev, &pctx->p_dev->dev); + + hdev->open = BSL_Open; + hdev->close = BSL_Close; + hdev->flush = BSL_Flush; + hdev->send = BSL_Write; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + hdev->owner = THIS_MODULE; + hdev->destruct = BSL_Destruct; +#endif + hdev->ioctl = BSL_IOControl; + + + /* Timeout before it is safe to send the first HCI packet */ + msleep(1000); + + /* Register HCI device */ + err = hci_register_dev(hdev); + if (err < 0) + { + VOS_TRACE(VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Unable to register HCI device, err=%d", err); + pctx->hdev = NULL; + hci_free_dev(hdev); + return VOS_STATUS_E_FAULT; + } + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + } + } + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANBAP_DeregisterFromHCI(void) +{ + struct hci_dev *hdev; + BslClientCtxType* pctx = NULL; + + pctx = gpBslctx; + + if ( NULL == pctx ) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on WLANBAP_DeregisterFromHCI"); + return VOS_STATUS_E_FAULT; + } + + /* Retrieve the HCI device pointer from the BSL driver context */ + hdev = pctx->hdev; + + if (!hdev) + return VOS_STATUS_E_FAULT; + + /* Unregister device from BlueZ; fcn sends us HCI commands before it returns */ + /* And then the registered hdev->close fcn should be called by BlueZ (BSL_Close) */ + hci_unregister_dev(hdev); + + /* BSL_Close is called again here, in case BlueZ didn't call it */ + BSL_Close(hdev); + hci_free_dev(hdev); + pctx->hdev = NULL; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS WLANBAP_StopAmp(void) +{ + BslClientCtxType* pctx; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pctx = gpBslctx; + + if(NULL == pctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on WLANBAP_StopAmp"); + status = VOS_STATUS_E_FAULT; + } + else + { + //is AMP session on, if so disconnect + if(VOS_TRUE == WLAN_BAPSessionOn(pctx->bapHdl)) + { + status = WLAN_BAPDisconnect(pctx->bapHdl); + } + } + return status; +} + +v_BOOL_t WLANBAP_AmpSessionOn(void) +{ + BslClientCtxType* pctx; + + pctx = gpBslctx; + if(NULL == pctx) + { + VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, + "Invalid BSL pointer from pvosGCtx on WLANBAP_AmpSessionOn"); + return VOS_FALSE; + } + else + { + return( WLAN_BAPSessionOn(pctx->bapHdl)); + } +} + + +#endif // WLAN_BTAMP_FEATURE diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c new file mode 100644 index 000000000000..6a962d4f373a --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c @@ -0,0 +1,5876 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_assoc.c + \brief WLAN Host Device Driver implementation + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 05/06/09 Shailender Created module. + ==========================================================================*/ + +#include "wlan_hdd_includes.h" +#include +#include "dot11f.h" +#include "wlan_nlink_common.h" +#include "wlan_btc_svc.h" +#include "wlan_hdd_power.h" +#include "wlan_hdd_trace.h" +#include +#include +#include +#include "wlan_hdd_cfg80211.h" +#include "csrInsideApi.h" +#include "wlan_hdd_p2p.h" +#include +#include "wlan_hdd_tdls.h" +#include "sme_Api.h" +#include "wlan_hdd_hostapd.h" +#include "vos_utils.h" +#include + +v_BOOL_t mibIsDot11DesiredBssTypeInfrastructure( hdd_adapter_t *pAdapter ); + +struct ether_addr +{ + u_char ether_addr_octet[6]; +}; +// These are needed to recognize WPA and RSN suite types +#define HDD_WPA_OUI_SIZE 4 +v_U8_t ccpWpaOui00[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x00 }; +v_U8_t ccpWpaOui01[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x01 }; +v_U8_t ccpWpaOui02[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 }; +v_U8_t ccpWpaOui03[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x03 }; +v_U8_t ccpWpaOui04[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x04 }; +v_U8_t ccpWpaOui05[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x05 }; +#ifdef FEATURE_WLAN_ESE +v_U8_t ccpWpaOui06[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM +#endif /* FEATURE_WLAN_ESE */ +#define HDD_RSN_OUI_SIZE 4 +v_U8_t ccpRSNOui00[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x00 }; // group cipher +v_U8_t ccpRSNOui01[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x01 }; // WEP-40 or RSN +v_U8_t ccpRSNOui02[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x02 }; // TKIP or RSN-PSK +v_U8_t ccpRSNOui03[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x03 }; // Reserved +v_U8_t ccpRSNOui04[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x04 }; // AES-CCMP +v_U8_t ccpRSNOui05[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; // WEP-104 +#ifdef FEATURE_WLAN_ESE +v_U8_t ccpRSNOui06[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W +v_U8_t ccpRSNOui07[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x06 }; // RSN-PSK-SHA256 +/* RSN-8021X-SHA256 */ +v_U8_t ccpRSNOui08[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; +#endif + +#if defined(WLAN_FEATURE_VOWIFI_11R) +// Offset where the EID-Len-IE, start. +#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2)*/ +#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */ +#endif + +#define BEACON_FRAME_IES_OFFSET 12 + +#ifdef WLAN_FEATURE_11W +void hdd_indicateUnprotMgmtFrame(hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +static void hdd_indicateTsmIe(hdd_adapter_t *pAdapter, tANI_U8 tid, + tANI_U8 state, + tANI_U16 measInterval ); +static void hdd_indicateCckmPreAuth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo); +static void hdd_indicateEseAdjApRepInd(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo); +static void hdd_indicateEseBcnReportInd(const hdd_adapter_t *pAdapter, const tCsrRoamInfo *pRoamInfo); + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ); + +v_VOID_t hdd_connSetConnectionState( hdd_station_ctx_t *pHddStaCtx, + eConnectionState connState ) +{ + // save the new connection state + hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"), + pHddStaCtx->conn_info.connState,connState); + pHddStaCtx->conn_info.connState = connState; +} + +// returns FALSE if not connected. +// returns TRUE for the two 'connected' states (Infra Associated or IBSS Connected ). +// returns the connection state. Can specify NULL if you dont' want to get the actual state. + +static inline v_BOOL_t hdd_connGetConnectionState( hdd_station_ctx_t *pHddStaCtx, + eConnectionState *pConnState ) +{ + v_BOOL_t fConnected; + eConnectionState connState; + + // get the connection state. + connState = pHddStaCtx->conn_info.connState; + // Set the fConnected return variable based on the Connected State. + if ( eConnectionState_Associated == connState || + eConnectionState_IbssConnected == connState || + eConnectionState_IbssDisconnected == connState) + { + fConnected = VOS_TRUE; + } + else + { + fConnected = VOS_FALSE; + } + + if ( pConnState ) + { + *pConnState = connState; + } + + return( fConnected ); +} + +v_BOOL_t hdd_connIsConnected( hdd_station_ctx_t *pHddStaCtx ) +{ + return( hdd_connGetConnectionState( pHddStaCtx, NULL ) ); +} + +eCsrBand hdd_connGetConnectedBand( hdd_station_ctx_t *pHddStaCtx ) +{ + v_U8_t staChannel = 0; + + if ( eConnectionState_Associated == pHddStaCtx->conn_info.connState ) + { + staChannel = pHddStaCtx->conn_info.operationChannel; + } + + if ( staChannel > 0 && staChannel < 14 ) + return eCSR_BAND_24; + else if (staChannel >= 36 && staChannel <= 165 ) + return eCSR_BAND_5G; + else /* If station is not connected return as eCSR_BAND_ALL */ + return eCSR_BAND_ALL; +} + + +//TODO - Not used anyhwere. Can be removed. +#if 0 +// +v_BOOL_t hdd_connIsConnectedInfra( hdd_adapter_t *pAdapter ) +{ + v_BOOL_t fConnectedInfra = FALSE; + eConnectionState connState; + + if ( hdd_connGetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connState ) ) + { + if ( eConnectionState_Associated == connState ) + { + fConnectedInfra = TRUE; + } + } + + return( fConnectedInfra ); +} +#endif + +static inline v_BOOL_t hdd_connGetConnectedCipherAlgo( hdd_station_ctx_t *pHddStaCtx, eCsrEncryptionType *pConnectedCipherAlgo ) +{ + v_BOOL_t fConnected = VOS_FALSE; + + fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL ); + + if ( pConnectedCipherAlgo ) + { + *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType; + } + + return( fConnected ); +} + +inline v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eMib_dot11DesiredBssType *pConnectedBssType ) +{ + v_BOOL_t fConnected = VOS_FALSE; + + fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL ); + + if ( pConnectedBssType ) + { + *pConnectedBssType = pHddStaCtx->conn_info.connDot11DesiredBssType; + } + + return( fConnected ); +} + +static inline void hdd_connSaveConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eCsrRoamBssType csrRoamBssType ) +{ + switch( csrRoamBssType ) + { + case eCSR_BSS_TYPE_INFRASTRUCTURE: + pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_infrastructure; + break; + + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_independent; + break; + + /** We will never set the BssType to 'any' when attempting a connection + so CSR should never send this back to us.*/ + case eCSR_BSS_TYPE_ANY: + default: + VOS_ASSERT( 0 ); + break; + } + +} + +/** + * hdd_copy_vht_caps()- copy vht caps info from roam info to + * hdd station context. + * @hdd_sta_ctx: pointer to hdd station context + * @roam_info: pointer to roam info + * + * Return: None + */ +static void hdd_copy_ht_caps(hdd_station_ctx_t *hdd_sta_ctx, + tCsrRoamInfo *roam_info) +{ + tDot11fIEHTCaps *roam_ht_cap = &roam_info->ht_caps; + struct ieee80211_ht_cap *hdd_ht_cap = &hdd_sta_ctx->conn_info.ht_caps; + uint32_t i, temp_ht_cap; + + vos_mem_zero(hdd_ht_cap, sizeof(struct ieee80211_ht_cap)); + + if (roam_ht_cap->advCodingCap) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LDPC_CODING; + if (roam_ht_cap->supportedChannelWidthSet) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + temp_ht_cap = roam_ht_cap->mimoPowerSave & + (IEEE80211_HT_CAP_SM_PS >> IEEE80211_HT_CAP_SM_PS_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->cap_info |= + temp_ht_cap << IEEE80211_HT_CAP_SM_PS_SHIFT; + if (roam_ht_cap->greenField) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_GRN_FLD; + if (roam_ht_cap->shortGI20MHz) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_20; + if (roam_ht_cap->shortGI40MHz) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_SGI_40; + if (roam_ht_cap->txSTBC) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_TX_STBC; + temp_ht_cap = roam_ht_cap->rxSTBC & (IEEE80211_HT_CAP_RX_STBC >> + IEEE80211_HT_CAP_RX_STBC_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->cap_info |= + temp_ht_cap << IEEE80211_HT_CAP_RX_STBC_SHIFT; + if (roam_ht_cap->delayedBA) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DELAY_BA; + if (roam_ht_cap->maximalAMSDUsize) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_MAX_AMSDU; + if (roam_ht_cap->dsssCckMode40MHz) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_DSSSCCK40; + if (roam_ht_cap->psmp) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_RESERVED; + if (roam_ht_cap->stbcControlFrame) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_40MHZ_INTOLERANT; + if (roam_ht_cap->lsigTXOPProtection) + hdd_ht_cap->cap_info |= IEEE80211_HT_CAP_LSIG_TXOP_PROT; + + + /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ + if (roam_ht_cap->maxRxAMPDUFactor) + hdd_ht_cap->ampdu_params_info |= + IEEE80211_HT_AMPDU_PARM_FACTOR; + temp_ht_cap = roam_ht_cap->mpduDensity & + (IEEE80211_HT_AMPDU_PARM_DENSITY >> + IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->ampdu_params_info |= + temp_ht_cap << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT; + + /* 802.11n HT extended capabilities masks */ + if (roam_ht_cap->pco) + hdd_ht_cap->extended_ht_cap_info |= + IEEE80211_HT_EXT_CAP_PCO; + temp_ht_cap = roam_ht_cap->transitionTime & + (IEEE80211_HT_EXT_CAP_PCO_TIME >> + IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->extended_ht_cap_info |= + temp_ht_cap << IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT; + temp_ht_cap = roam_ht_cap->mcsFeedback & + (IEEE80211_HT_EXT_CAP_MCS_FB >> IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->extended_ht_cap_info |= + temp_ht_cap << IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT; + + /* tx_bf_cap_info capabilities */ + if (roam_ht_cap->txBF) + hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_BF; + if (roam_ht_cap->rxStaggeredSounding) + hdd_ht_cap->tx_BF_cap_info |= + TX_BF_CAP_INFO_RX_STAG_RED_SOUNDING; + if (roam_ht_cap->txStaggeredSounding) + hdd_ht_cap->tx_BF_cap_info |= + TX_BF_CAP_INFO_TX_STAG_RED_SOUNDING; + if (roam_ht_cap->rxZLF) + hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_RX_ZFL; + if (roam_ht_cap->txZLF) + hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_TX_ZFL; + if (roam_ht_cap->implicitTxBF) + hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_IMP_TX_BF; + temp_ht_cap = roam_ht_cap->calibration & + (TX_BF_CAP_INFO_CALIBRATION >> TX_BF_CAP_INFO_CALIBRATION_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << TX_BF_CAP_INFO_CALIBRATION_SHIFT; + if (roam_ht_cap->explicitCSITxBF) + hdd_ht_cap->tx_BF_cap_info |= TX_BF_CAP_INFO_EXP_CSIT_BF; + if (roam_ht_cap->explicitUncompressedSteeringMatrix) + hdd_ht_cap->tx_BF_cap_info |= + TX_BF_CAP_INFO_EXP_UNCOMP_STEER_MAT; + temp_ht_cap = roam_ht_cap->explicitBFCSIFeedback & + (TX_BF_CAP_INFO_EXP_BF_CSI_FB >> + TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << TX_BF_CAP_INFO_EXP_BF_CSI_FB_SHIFT; + temp_ht_cap = + roam_ht_cap->explicitUncompressedSteeringMatrixFeedback & + (TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT >> + TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << + TX_BF_CAP_INFO_EXP_UNCMP_STEER_MAT_SHIFT; + temp_ht_cap = + roam_ht_cap->explicitCompressedSteeringMatrixFeedback & + (TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB >> + TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << + TX_BF_CAP_INFO_EXP_CMP_STEER_MAT_FB_SHIFT; + temp_ht_cap = roam_ht_cap->csiNumBFAntennae & + (TX_BF_CAP_INFO_CSI_NUM_BF_ANT >> + TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << TX_BF_CAP_INFO_CSI_NUM_BF_ANT_SHIFT; + temp_ht_cap = roam_ht_cap->uncompressedSteeringMatrixBFAntennae & + (TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT >> + TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << + TX_BF_CAP_INFO_UNCOMP_STEER_MAT_BF_ANT_SHIFT; + temp_ht_cap = roam_ht_cap->compressedSteeringMatrixBFAntennae & + (TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT >> + TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT); + if (temp_ht_cap) + hdd_ht_cap->tx_BF_cap_info |= + temp_ht_cap << + TX_BF_CAP_INFO_COMP_STEER_MAT_BF_ANT_SHIFT; + + /* antenna selection */ + if (roam_ht_cap->antennaSelection) + hdd_ht_cap->antenna_selection_info |= ANTENNA_SEL_INFO; + if (roam_ht_cap->explicitCSIFeedbackTx) + hdd_ht_cap->antenna_selection_info |= + ANTENNA_SEL_INFO_EXP_CSI_FB_TX; + if (roam_ht_cap->antennaIndicesFeedbackTx) + hdd_ht_cap->antenna_selection_info |= + ANTENNA_SEL_INFO_ANT_ID_FB_TX; + if (roam_ht_cap->explicitCSIFeedback) + hdd_ht_cap->antenna_selection_info |= + ANTENNA_SEL_INFO_EXP_CSI_FB; + if (roam_ht_cap->antennaIndicesFeedback) + hdd_ht_cap->antenna_selection_info |= + ANTENNA_SEL_INFO_ANT_ID_FB; + if (roam_ht_cap->rxAS) + hdd_ht_cap->antenna_selection_info |= + ANTENNA_SEL_INFO_RX_AS; + if (roam_ht_cap->txSoundingPPDUs) + hdd_ht_cap->antenna_selection_info |= + ANTENNA_SEL_INFO_TX_SOUNDING_PPDU; + + /* mcs data rate */ + for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; ++i) + hdd_ht_cap->mcs.rx_mask[i] = + roam_ht_cap->supportedMCSSet[i]; + hdd_ht_cap->mcs.rx_highest = + ((short) (roam_ht_cap->supportedMCSSet[11]) << 8) | + ((short) (roam_ht_cap->supportedMCSSet[10])); + hdd_ht_cap->mcs.tx_params = + roam_ht_cap->supportedMCSSet[12]; +} + + +#define VHT_CAP_MAX_MPDU_LENGTH_MASK 0x00000003 +#define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2 +#define VHT_CAP_RXSTBC_MASK_SHIFT 8 +#define VHT_CAP_BEAMFORMEE_STS_SHIFT 13 +#define VHT_CAP_BEAMFORMEE_STS_MASK \ + (0x0000e000 >> VHT_CAP_BEAMFORMEE_STS_SHIFT) +#define VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16 +#define VHT_CAP_SOUNDING_DIMENSIONS_MASK \ + (0x00070000 >> VHT_CAP_SOUNDING_DIMENSIONS_SHIFT) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT 23 +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \ + (0x03800000 >> VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT) +#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT 26 + +/** + * hdd_copy_ht_caps()- copy ht caps info from roam info to + * hdd station context. + * @hdd_sta_ctx: pointer to hdd station context + * @roam_info: pointer to roam info + * + * Return: None + */ +static void hdd_copy_vht_caps(hdd_station_ctx_t *hdd_sta_ctx, + tCsrRoamInfo *roam_info) +{ + tDot11fIEVHTCaps *roam_vht_cap = &roam_info->vht_caps; + struct ieee80211_vht_cap *hdd_vht_cap = + &hdd_sta_ctx->conn_info.vht_caps; + uint32_t temp_vht_cap; + + vos_mem_zero(hdd_vht_cap, sizeof(struct ieee80211_vht_cap)); + + temp_vht_cap = roam_vht_cap->maxMPDULen & VHT_CAP_MAX_MPDU_LENGTH_MASK; + hdd_vht_cap->vht_cap_info |= temp_vht_cap; + temp_vht_cap = roam_vht_cap->supportedChannelWidthSet & + (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK >> + VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT); + if (temp_vht_cap) + if (roam_vht_cap->supportedChannelWidthSet & + (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ >> + VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT)) + hdd_vht_cap->vht_cap_info |= + temp_vht_cap << + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + if (roam_vht_cap->supportedChannelWidthSet & + (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ >> + VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT)) + hdd_vht_cap->vht_cap_info |= + temp_vht_cap << + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; + if (roam_vht_cap->ldpcCodingCap) + hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_RXLDPC; + if (roam_vht_cap->shortGI80MHz) + hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_80; + if (roam_vht_cap->shortGI160and80plus80MHz) + hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_SHORT_GI_160; + if (roam_vht_cap->txSTBC) + hdd_vht_cap->vht_cap_info |= IEEE80211_VHT_CAP_TXSTBC; + temp_vht_cap = roam_vht_cap->rxSTBC & (IEEE80211_VHT_CAP_RXSTBC_MASK >> + VHT_CAP_RXSTBC_MASK_SHIFT); + if (temp_vht_cap) + hdd_vht_cap->vht_cap_info |= + temp_vht_cap << VHT_CAP_RXSTBC_MASK_SHIFT; + if (roam_vht_cap->suBeamFormerCap) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; + if (roam_vht_cap->suBeamformeeCap) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; + temp_vht_cap = roam_vht_cap->csnofBeamformerAntSup & + (VHT_CAP_BEAMFORMEE_STS_MASK); + if (temp_vht_cap) + hdd_vht_cap->vht_cap_info |= + temp_vht_cap << VHT_CAP_BEAMFORMEE_STS_SHIFT; + temp_vht_cap = roam_vht_cap->numSoundingDim & + (VHT_CAP_SOUNDING_DIMENSIONS_MASK); + if (temp_vht_cap) + hdd_vht_cap->vht_cap_info |= + temp_vht_cap << VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + if (roam_vht_cap->muBeamformerCap) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; + if (roam_vht_cap->muBeamformeeCap) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; + if (roam_vht_cap->vhtTXOPPS) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_VHT_TXOP_PS; + if (roam_vht_cap->htcVHTCap) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_HTC_VHT; + temp_vht_cap = roam_vht_cap->maxAMPDULenExp & + (VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); + if (temp_vht_cap) + hdd_vht_cap->vht_cap_info |= + temp_vht_cap << + VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK_SHIFT; + temp_vht_cap = roam_vht_cap->vhtLinkAdaptCap & + (IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB >> + VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT); + if (temp_vht_cap) + hdd_vht_cap->vht_cap_info |= temp_vht_cap << + VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB_SHIFT; + if (roam_vht_cap->rxAntPattern) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN; + if (roam_vht_cap->txAntPattern) + hdd_vht_cap->vht_cap_info |= + IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; + hdd_vht_cap->supp_mcs.rx_mcs_map = roam_vht_cap->rxMCSMap; + hdd_vht_cap->supp_mcs.rx_highest = + ((uint16_t)roam_vht_cap->rxHighSupDataRate); + hdd_vht_cap->supp_mcs.tx_mcs_map = roam_vht_cap->txMCSMap; + hdd_vht_cap->supp_mcs.tx_highest = + ((uint16_t)roam_vht_cap->txSupDataRate); +} + +/* ht param */ +#define HT_PARAM_CONTROLLED_ACCESS_ONLY 0x10 +#define HT_PARAM_SERVICE_INT_GRAN 0xe0 +#define HT_PARAM_SERVICE_INT_GRAN_SHIFT 5 + +/* operatinon mode */ +#define HT_OP_MODE_TX_BURST_LIMIT 0x0008 + +/* stbc_param */ +#define HT_STBC_PARAM_MCS 0x007f + +/** + * hdd_copy_ht_operation()- copy HT operation element from roam info to + * hdd station context. + * @hdd_sta_ctx: pointer to hdd station context + * @roam_info: pointer to roam info + * + * Return: None + */ +static void hdd_copy_ht_operation(hdd_station_ctx_t *hdd_sta_ctx, + tCsrRoamInfo *roam_info) +{ + tDot11fIEHTInfo *roam_ht_ops = &roam_info->ht_operation; + struct ieee80211_ht_operation *hdd_ht_ops = + &hdd_sta_ctx->conn_info.ht_operation; + uint32_t i, temp_ht_ops; + + vos_mem_zero(hdd_ht_ops, sizeof(struct ieee80211_ht_operation)); + + hdd_ht_ops->primary_chan = roam_ht_ops->primaryChannel; + + /* HT_PARAMS */ + temp_ht_ops = roam_ht_ops->secondaryChannelOffset & + IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + if (temp_ht_ops) + hdd_ht_ops->ht_param |= temp_ht_ops; + else + hdd_ht_ops->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; + if (roam_ht_ops->recommendedTxWidthSet) + hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; + if (roam_ht_ops->rifsMode) + hdd_ht_ops->ht_param |= IEEE80211_HT_PARAM_RIFS_MODE; + if (roam_ht_ops->controlledAccessOnly) + hdd_ht_ops->ht_param |= HT_PARAM_CONTROLLED_ACCESS_ONLY; + temp_ht_ops = roam_ht_ops->serviceIntervalGranularity & + (HT_PARAM_SERVICE_INT_GRAN >> HT_PARAM_SERVICE_INT_GRAN_SHIFT); + if (temp_ht_ops) + hdd_ht_ops->ht_param |= temp_ht_ops << + HT_PARAM_SERVICE_INT_GRAN_SHIFT; + + /* operation mode */ + temp_ht_ops = roam_ht_ops->opMode & + IEEE80211_HT_OP_MODE_PROTECTION; + switch (temp_ht_ops) { + case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: + hdd_ht_ops->operation_mode |= + IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER; + break; + case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: + hdd_ht_ops->operation_mode |= + IEEE80211_HT_OP_MODE_PROTECTION_20MHZ; + break; + case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: + hdd_ht_ops->operation_mode |= + IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED; + break; + case IEEE80211_HT_OP_MODE_PROTECTION_NONE: + default: + hdd_ht_ops->operation_mode |= + IEEE80211_HT_OP_MODE_PROTECTION_NONE; + } + if (roam_ht_ops->nonGFDevicesPresent) + hdd_ht_ops->operation_mode |= + IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT; + if (roam_ht_ops->transmitBurstLimit) + hdd_ht_ops->operation_mode |= + HT_OP_MODE_TX_BURST_LIMIT; + if (roam_ht_ops->obssNonHTStaPresent) + hdd_ht_ops->operation_mode |= + IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT; + + /* stbc_param */ + temp_ht_ops = roam_ht_ops->basicSTBCMCS & + HT_STBC_PARAM_MCS; + if (temp_ht_ops) + hdd_ht_ops->stbc_param |= temp_ht_ops; + if (roam_ht_ops->dualCTSProtection) + hdd_ht_ops->stbc_param |= + IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT; + if (roam_ht_ops->secondaryBeacon) + hdd_ht_ops->stbc_param |= + IEEE80211_HT_STBC_PARAM_STBC_BEACON; + if (roam_ht_ops->lsigTXOPProtectionFullSupport) + hdd_ht_ops->stbc_param |= + IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT; + if (roam_ht_ops->pcoActive) + hdd_ht_ops->stbc_param |= + IEEE80211_HT_STBC_PARAM_PCO_ACTIVE; + if (roam_ht_ops->pcoPhase) + hdd_ht_ops->stbc_param |= + IEEE80211_HT_STBC_PARAM_PCO_PHASE; + + /* basic MCs set */ + for (i = 0; i < 16; ++i) + hdd_ht_ops->basic_set[i] = + roam_ht_ops->basicMCSSet[i]; +} + +/** + * hdd_copy_vht_operation()- copy VHT operations element from roam info to + * hdd station context. + * @hdd_sta_ctx: pointer to hdd station context + * @roam_info: pointer to roam info + * + * Return: None + */ +static void hdd_copy_vht_operation(hdd_station_ctx_t *hdd_sta_ctx, + tCsrRoamInfo *roam_info) +{ + tDot11fIEVHTOperation *roam_vht_ops = &roam_info->vht_operation; + struct ieee80211_vht_operation *hdd_vht_ops = + &hdd_sta_ctx->conn_info.vht_operation; + + vos_mem_zero(hdd_vht_ops, sizeof(struct ieee80211_vht_operation)); + + hdd_vht_ops->chan_width = roam_vht_ops->chanWidth; + hdd_vht_ops->center_freq_seg1_idx = roam_vht_ops->chanCenterFreqSeg1; + hdd_vht_ops->center_freq_seg2_idx = roam_vht_ops->chanCenterFreqSeg2; + hdd_vht_ops->basic_mcs_set = roam_vht_ops->basicMCSSet; +} + + +/** + * hdd_save_bss_info() - save connection info in hdd sta ctx + * @adapter: Pointer to adapter + * @roam_info: pointer to roam info + * + * Return: None + */ +static void hdd_save_bss_info(hdd_adapter_t *adapter, + tCsrRoamInfo *roam_info) +{ + hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + hdd_sta_ctx->conn_info.freq = vos_chan_to_freq( + hdd_sta_ctx->conn_info.operationChannel); + if (roam_info->vht_caps.present) { + hdd_sta_ctx->conn_info.conn_flag.vht_present = true; + hdd_copy_vht_caps(hdd_sta_ctx, roam_info); + } else { + hdd_sta_ctx->conn_info.conn_flag.vht_present = false; + } + if (roam_info->ht_caps.present) { + hdd_sta_ctx->conn_info.conn_flag.ht_present = true; + hdd_copy_ht_caps(hdd_sta_ctx, roam_info); + } else { + hdd_sta_ctx->conn_info.conn_flag.ht_present = false; + } + if (roam_info->reassoc) + hdd_sta_ctx->conn_info.roam_count++; + if (roam_info->hs20vendor_ie.present) { + hdd_sta_ctx->conn_info.conn_flag.hs20_present = true; + vos_mem_copy(&hdd_sta_ctx->conn_info.hs20vendor_ie, + &roam_info->hs20vendor_ie, + sizeof(roam_info->hs20vendor_ie)); + } else { + hdd_sta_ctx->conn_info.conn_flag.hs20_present = false; + } + if (roam_info->ht_operation.present) { + hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true; + hdd_copy_ht_operation(hdd_sta_ctx, roam_info); + } else { + hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false; + } + if (roam_info->vht_operation.present) { + hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true; + hdd_copy_vht_operation(hdd_sta_ctx, roam_info); + } else { + hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false; + } +} + +void hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType ) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE; + + VOS_ASSERT( pRoamInfo ); + + if ( pRoamInfo ) + { + // Save the BSSID for the connection... + if ( eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType ) + { + VOS_ASSERT( pRoamInfo->pBssDesc ); + vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,6 ); + + // Save the Station ID for this station from the 'Roam Info'. + //For IBSS mode, staId is assigned in NEW_PEER_IND + //For reassoc, the staID doesn't change and it may be invalid in this structure + //so no change here. + if( !pRoamInfo->fReassocReq ) + { + pHddStaCtx->conn_info.staId [0]= pRoamInfo->staId; + } + } + else if ( eCSR_BSS_TYPE_IBSS == eBssType ) + { + vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,sizeof(pRoamInfo->bssid) ); + } + else + { + // can't happen. We need a valid IBSS or Infra setting in the BSSDescription + // or we can't function. + VOS_ASSERT( 0 ); + } + + // notify WMM + hdd_wmm_connect(pAdapter, pRoamInfo, eBssType); + + if( !pRoamInfo->u.pConnectedProfile ) + { + VOS_ASSERT( pRoamInfo->u.pConnectedProfile ); + } + else + { + // Get Multicast Encryption Type + encryptType = pRoamInfo->u.pConnectedProfile->mcEncryptionType; + pHddStaCtx->conn_info.mcEncryptionType = encryptType; + // Get Unicast Encrytion Type + encryptType = pRoamInfo->u.pConnectedProfile->EncryptionType; + pHddStaCtx->conn_info.ucEncryptionType = encryptType; + + pHddStaCtx->conn_info.authType = pRoamInfo->u.pConnectedProfile->AuthType; + + pHddStaCtx->conn_info.operationChannel = pRoamInfo->u.pConnectedProfile->operationChannel; + + // Save the ssid for the connection + vos_mem_copy( &pHddStaCtx->conn_info.SSID.SSID, &pRoamInfo->u.pConnectedProfile->SSID, sizeof( tSirMacSSid ) ); + + // Save dot11mode in which STA associated to AP + pHddStaCtx->conn_info.dot11Mode = pRoamInfo->u.pConnectedProfile->dot11Mode; + + pHddStaCtx->conn_info.rate_flags = pRoamInfo->maxRateFlags; + } + hdd_save_bss_info(pAdapter, pRoamInfo); + } + + // save the connected BssType + hdd_connSaveConnectedBssType( pHddStaCtx, eBssType ); + +} + +#if defined(WLAN_FEATURE_VOWIFI_11R) +/* + * Send the 11R key information to the supplicant. + * Only then can the supplicant generate the PMK-R1. + * (BTW, the ESE supplicant also needs the Assoc Resp IEs + * for the same purpose.) + * + * Mainly the Assoc Rsp IEs are passed here. For the IMDA + * this contains the R1KHID, R0KHID and the MDID. + * For FT, this consists of the Reassoc Rsp FTIEs. + * This is the Assoc Response. + */ +static void hdd_SendFTAssocResponse(struct net_device *dev, hdd_adapter_t *pAdapter, + tCsrRoamInfo *pCsrRoamInfo) +{ + union iwreq_data wrqu; + char *buff; + unsigned int len = 0; + u8 *pFTAssocRsp = NULL; + + if (pCsrRoamInfo->nAssocRspLength == 0) + { + hddLog(LOGE, + "%s: pCsrRoamInfo->nAssocRspLength=%d", + __func__, (int)pCsrRoamInfo->nAssocRspLength); + return; + } + + pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength + + pCsrRoamInfo->nAssocReqLength); + if (pFTAssocRsp == NULL) + { + hddLog(LOGE, "%s: AssocReq or AssocRsp is NULL", __func__); + return; + } + + // pFTAssocRsp needs to point to the IEs + pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET; + hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__, + (unsigned int)pFTAssocRsp[0], + (unsigned int)pFTAssocRsp[1]); + + // We need to send the IEs to the supplicant. + buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC); + if (buff == NULL) + { + hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__); + return; + } + + // Send the Assoc Resp, the supplicant needs this for initial Auth. + len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET; + wrqu.data.length = len; + memset(buff, 0, IW_GENERIC_IE_MAX); + memcpy(buff, pFTAssocRsp, len); + wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff); + + kfree(buff); +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/*--------------------------------------------------- + * + * Send the FTIEs, RIC IEs during FT. This is eventually + * used to send the FT events to the supplicant + * + * At the reception of Auth2 we send the RIC followed + * by the auth response IEs to the supplicant. + * Once both are received in the supplicant, an FT + * event is generated to the supplicant. + * + *--------------------------------------------------- + */ +void hdd_SendFTEvent(hdd_adapter_t *pAdapter) +{ + tANI_U16 auth_resp_len = 0; + tANI_U32 ric_ies_length = 0; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + +#if defined(KERNEL_SUPPORT_11R_CFG80211) + struct cfg80211_ft_event_params ftEvent; + v_U8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN]; + v_U8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN]; + struct net_device *dev = pAdapter->dev; +#else + char *buff; + union iwreq_data wrqu; + tANI_U16 str_len; +#endif + +#if defined(KERNEL_SUPPORT_11R_CFG80211) + vos_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN); + vos_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN); + + sme_GetRICIEs(pHddCtx->hHal, (u8 *)ricIe, + DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length ); + if (ric_ies_length == 0) + { + hddLog(LOGW, + "%s: RIC IEs is of length 0 not sending RIC Information for now", + __func__); + } + + ftEvent.ric_ies = ricIe; + ftEvent.ric_ies_len = ric_ies_length; + hddLog(LOG1, "%s: RIC IEs is of length %d", __func__, (int)ric_ies_length); + + sme_GetFTPreAuthResponse(pHddCtx->hHal, (u8 *)ftIe, + DOT11F_IE_FTINFO_MAX_LEN, &auth_resp_len); + + if (auth_resp_len == 0) + { + hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__); + return; + } + + sme_SetFTPreAuthState(pHddCtx->hHal, TRUE); + + ftEvent.target_ap = ftIe; + + ftEvent.ies = (u8 *)(ftIe + SIR_MAC_ADDR_LENGTH); + ftEvent.ies_len = auth_resp_len - SIR_MAC_ADDR_LENGTH; + + hddLog(LOG1, "%s ftEvent.ies_len %zu", __FUNCTION__, ftEvent.ies_len); + hddLog(LOG1, "%s ftEvent.ric_ies_len %zu", + __FUNCTION__, ftEvent.ric_ies_len ); + hddLog(LOG1, "%s ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x ", + __FUNCTION__, ftEvent.target_ap[0], ftEvent.target_ap[1], + ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4], + ftEvent.target_ap[5]); + + (void)cfg80211_ft_event(dev, &ftEvent); + +#else + // We need to send the IEs to the supplicant + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC); + if (buff == NULL) + { + hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__); + return; + } + vos_mem_zero(buff, IW_CUSTOM_MAX); + + // Sme needs to send the RIC IEs first + str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX); + sme_GetRICIEs( pHddCtx->hHal, (u8 *)&(buff[str_len]), + (IW_CUSTOM_MAX - str_len), &ric_ies_length ); + if (ric_ies_length == 0) + { + hddLog(LOGW, + "%s: RIC IEs is of length 0 not sending RIC Information for now", + __func__); + } + else + { + wrqu.data.length = str_len + ric_ies_length; + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff); + } + + // Sme needs to provide the Auth Resp + vos_mem_zero(buff, IW_CUSTOM_MAX); + str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX); + sme_GetFTPreAuthResponse(pHddCtx->hHal, (u8 *)&buff[str_len], + (IW_CUSTOM_MAX - str_len), &auth_resp_len); + + if (auth_resp_len == 0) + { + hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__); + kfree(buff); + return; + } + + wrqu.data.length = str_len + auth_resp_len; + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff); + + kfree(buff); +#endif +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +#ifdef FEATURE_WLAN_ESE + +/* + * Send the ESE required "new AP Channel info" to the supplicant. + * (This keeps the supplicant "up to date" on the current channel.) + * + * The current (new AP) channel information is passed in. + */ +static void hdd_SendNewAPChannelInfo(struct net_device *dev, hdd_adapter_t *pAdapter, + tCsrRoamInfo *pCsrRoamInfo) +{ + union iwreq_data wrqu; + tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc; + + + if (descriptor == NULL) + { + hddLog(LOGE, + "%s: pCsrRoamInfo->pBssDesc=%p", + __func__, descriptor); + return; + } + + // Send the Channel event, the supplicant needs this to generate the Adjacent AP report. + hddLog(LOGW, "%s: Sending up an SIOCGIWFREQ, channelId=%d", __func__, descriptor->channelId); + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.freq.m = descriptor->channelId; + wrqu.freq.e = 0; + wrqu.freq.i = 0; + wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL); +} + +#endif /* FEATURE_WLAN_ESE */ + +void hdd_SendUpdateBeaconIEsEvent(hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo) +{ + union iwreq_data wrqu; + u8 *pBeaconIes; + u8 currentLen = 0; + char *buff; + int totalIeLen = 0, currentOffset = 0, strLen; + + memset(&wrqu, '\0', sizeof(wrqu)); + + if (0 == pCsrRoamInfo->nBeaconLength) + { + hddLog(LOGE, "%s: pCsrRoamInfo->nBeaconFrameLength = 0", __func__); + return; + } + pBeaconIes = (u8 *)(pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET); + if (pBeaconIes == NULL) + { + hddLog(LOGE, "%s: Beacon IEs is NULL", __func__); + return; + } + + // pBeaconIes needs to point to the IEs + hddLog(LOG1, "%s: Beacon IEs is now at %02x%02x", __func__, + (unsigned int)pBeaconIes[0], + (unsigned int)pBeaconIes[1]); + hddLog(LOG1, "%s: Beacon IEs length = %d", __func__, pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET); + + // We need to send the IEs to the supplicant. + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC); + if (buff == NULL) + { + hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__); + return; + } + vos_mem_zero(buff, IW_CUSTOM_MAX); + + strLen = strlcpy(buff,"BEACONIEs=", IW_CUSTOM_MAX); + currentLen = strLen + 1; + + totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET; + do + { + /* If the beacon size exceeds max CUSTOM event size, break it into chunks of CUSTOM event + * max size and send it to supplicant. Changes are done in supplicant to handle this */ + vos_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1)); + currentLen = VOS_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1); + vos_mem_copy(&buff[strLen + 1], pBeaconIes+currentOffset, currentLen); + currentOffset += currentLen; + totalIeLen -= currentLen; + wrqu.data.length = strLen + 1 + currentLen; + if (totalIeLen) + buff[strLen] = 1; // This tells supplicant more chunks are pending + else + buff[strLen] = 0; // For last chunk of beacon IE to supplicant + + hddLog(LOG1, "%s: Beacon IEs length to supplicant = %d", __func__, currentLen); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff); + } while (totalIeLen > 0); + + kfree(buff); +} + +static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRoamInfo) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + union iwreq_data wrqu; + int we_event; + char *msg; + int type = -1; + +#if defined (WLAN_FEATURE_VOWIFI_11R) + // Added to find the auth type on the fly at run time + // rather than with cfg to see if FT is enabled + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile); +#endif + + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + we_event = SIOCGIWAP; + + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */ + { + /* In case of roaming ; We are not doing disconnect. + * If disconnect is not being done for roam; We will not + * decrease count for Active sessions. We should not increase active + * active session in case of roaming. + */ + if((pHddStaCtx->ft_carrier_on == FALSE) && !pCsrRoamInfo->fReassocReq) + { + wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode); + } + memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId, sizeof(pCsrRoamInfo->pBssDesc->bssId)); + type = WLAN_STA_ASSOC_DONE_IND; + +#ifdef WLAN_FEATURE_P2P_DEBUG + if(pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTING_STATE_1) + { + globalP2PConnectionStatus = P2P_CLIENT_CONNECTED_STATE_1; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from " + "Connecting state to Connected State for 8-way " + "Handshake"); + } + else if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTING_STATE_2) + { + globalP2PConnectionStatus = P2P_CLIENT_COMPLETED_STATE; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from " + "Connecting state to P2P Client Connection Completed"); + } + } +#endif + hddLog(VOS_TRACE_LEVEL_INFO, MAC_ADDRESS_STR " connected to " + MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes), + MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data)); + hdd_SendUpdateBeaconIEsEvent(pAdapter, pCsrRoamInfo); + + hdd_manage_delack_timer(pHddCtx); + + /* Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS is Enabled Or + * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_VOWIFI_11R is Enabled + * and fFTEnable is TRUE */ +#ifdef WLAN_FEATURE_VOWIFI_11R + // Send FT Keys to the supplicant when FT is enabled + if ((pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN_PSK) || + (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN) +#ifdef FEATURE_WLAN_ESE + || (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) || + (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA) +#endif + ) + { + hdd_SendFTAssocResponse(dev, pAdapter, pCsrRoamInfo); + } +#endif + } + else if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) // IBss Associated + { + wlan_hdd_incr_active_session(pHddCtx, pAdapter->device_mode); + memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId, ETH_ALEN); + type = WLAN_STA_ASSOC_DONE_IND; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wlan: new IBSS connection to " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId)); + } + else /* Not Associated */ + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wlan: disconnected"); + type = WLAN_STA_DISASSOC_DONE_IND; + memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + + hdd_manage_delack_timer(pHddCtx); + } + hdd_dump_concurrency_info(pHddCtx); + + msg = NULL; + /*During the WLAN uninitialization,supplicant is stopped before the + driver so not sending the status of the connection to supplicant*/ + if(pHddCtx->isLoadUnloadInProgress == WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS) + { + wireless_send_event(dev, we_event, &wrqu, msg); +#ifdef FEATURE_WLAN_ESE + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */ + { + if ( (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) || + (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA) ) + hdd_SendNewAPChannelInfo(dev, pAdapter, pCsrRoamInfo); + } +#endif + } + send_btc_nlink_msg(type, 0); +} + +void hdd_connRemoveConnectInfo( hdd_station_ctx_t *pHddStaCtx ) +{ + // Remove staId, bssId and peerMacAddress + pHddStaCtx->conn_info.staId [ 0 ] = 0; + vos_mem_zero( &pHddStaCtx->conn_info.bssId, sizeof( v_MACADDR_t ) ); + vos_mem_zero( &pHddStaCtx->conn_info.peerMacAddress[ 0 ], sizeof( v_MACADDR_t ) ); + + // Clear all security settings + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + + vos_mem_zero( &pHddStaCtx->conn_info.Keys, sizeof( tCsrKeys ) ); + vos_mem_zero( &pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey) ); + + // Set not-connected state + pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY; + + vos_mem_zero( &pHddStaCtx->conn_info.SSID, sizeof( tCsrSSIDInfo ) ); +} + +VOS_STATUS hdd_ibss_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId ) +{ + v_U8_t ac; + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t txSuspended[NUM_TX_QUEUES]; + v_U8_t tlAC; + v_U8_t i; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ibss_peer_info_t *pPeerInfo; + + if( NULL == pHddStaCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD station context NULL ",__func__); + return VOS_STATUS_E_FAILURE; + } + + pPeerInfo = &pHddStaCtx->ibss_peer_info; + if (FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Deinit station not inited %d", __func__, STAId ); + return VOS_STATUS_E_FAILURE; + } + + hdd_flush_ibss_tx_queues(pAdapter, STAId); + + for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++) + { + tlAC = hdd_QdiscAcToTlAC[ac]; + txSuspended[ac] = pPeerInfo->ibssStaInfo[STAId].txSuspended[tlAC]; + } + + vos_mem_zero(&pPeerInfo->ibssStaInfo[STAId], sizeof(hdd_ibss_station_info_t)); + + /* re-init hdd list, since netdev can still open adapter until + * driver gets unloaded + */ + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], + HDD_TX_QUEUE_MAX_LEN); + } + + for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++) + { + if (txSuspended[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue re-enabled", __func__); + netif_wake_subqueue(pAdapter->dev, ac); + } + } + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS hdd_ibss_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus; + + vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + __func__, staId, vosStatus, vosStatus ); + } + + vosStatus = hdd_ibss_deinit_tx_rx_sta ( pAdapter, staId ); + if( VOS_STATUS_E_FAILURE == vosStatus ) + { + VOS_TRACE ( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "hdd_ibss_deinit_tx_rx_sta() failed for staID %d. " + "Status = %d [0x%08X]", + staId, vosStatus, vosStatus ); + } + + return( vosStatus ); +} + +VOS_STATUS hdd_ibss_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA) +{ + v_U8_t i = 0; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ibss_peer_info_t * pPeerInfo = &pHddStaCtx->ibss_peer_info; + + if (pPeerInfo->ibssStaInfo[STAId].isUsed) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Reinit station %d", __func__, STAId ); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_zero(&pPeerInfo->ibssStaInfo[STAId], sizeof(hdd_ibss_station_info_t)); + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + + pPeerInfo->ibssStaInfo[STAId].isUsed = VOS_TRUE; + pPeerInfo->ibssStaInfo[STAId].isDeauthInProgress = VOS_FALSE; + vos_copy_macaddr( &pPeerInfo->ibssStaInfo[STAId].macAddrSTA, pmacAddrSTA); + + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS hdd_ibss_RegisterSTA( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + v_U8_t staId, + v_MACADDR_t *pPeerMacAddress, + tSirBssDescription *pBssDesc ) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + eCsrEncryptionType connectedCipherAlgo; + v_BOOL_t fConnected; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ibss_peer_info_t * pPeerInfo = &pHddStaCtx->ibss_peer_info; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ( pPeerInfo->ibssStaInfo[staId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "clean up old entry for STA %d", staId); + hdd_ibss_DeregisterSTA( pAdapter, staId ); + } + + staDesc.ucSTAId = staId; + staDesc.wSTAType = WLAN_STA_IBSS; + + // Note that for IBSS, the STA MAC address and BSSID are goign to be different where + // in infrastructure, they are the same (BSSID is the MAC address of the AP). So, + // for IBSS we have a second field to pass to TL in the STA descriptor that we don't + // pass when making an Infrastructure connection. + vos_mem_copy(staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes)); + vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId, 6 ); + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + if (hdd_wmm_is_active(pAdapter)) + { + staDesc.ucQosEnabled = 1; + } + else + { + staDesc.ucQosEnabled = 0; + } + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "HDD SOFTAP register TL QoS_enabled=%d", + staDesc.ucQosEnabled ); + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if ( connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE ) + { + staDesc.ucProtectedFrame = 1; + } + else + { + staDesc.ucProtectedFrame = 0; + + } + + hdd_ibss_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress); + + // UMA is Not ready yet, Xlation will be done by TL + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + // Initialize signatures and state + staDesc.ucUcastSig = pRoamInfo->ucastSig; + staDesc.ucBcastSig = pRoamInfo->bcastSig; + staDesc.ucInitState = WLANTL_STA_AUTHENTICATED; + + staDesc.ucIsReplayCheckValid = VOS_FALSE; + + // Register the Station with TL. + vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext, + hdd_rx_packet_cbk, + hdd_tx_complete_cbk, + hdd_ibss_tx_fetch_packet_cbk, &staDesc, + pBssDesc->rssi ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + vosStatus, vosStatus ); + return vosStatus; + } + + //Timer value should be in milliseconds + if ( pHddCtx->cfg_ini->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + pHddCtx->cfg_ini->trafficMntrTmrForSplitScan); + } + + pPeerInfo->ibssStaInfo[staId].ucSTAId = staId; + pPeerInfo->ibssStaInfo[staId].isQosEnabled = staDesc.ucQosEnabled; + + vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED ); + + pPeerInfo->ibssStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED; + pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE; + + return( vosStatus ); +} + +/* TODO Revist this function. and data path */ +static VOS_STATUS hdd_roamDeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus; + + hdd_disconnect_tx_rx(pAdapter); + + vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + __func__, staId, vosStatus, vosStatus ); + } + return( vosStatus ); +} + +/** + * hdd_print_bss_info() - print bss info + * @hdd_sta_ctx: pointer to hdd station context + * + * Return: None + */ +void hdd_print_bss_info(hdd_station_ctx_t *hdd_sta_ctx) +{ + uint32_t *cap_info; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"WIFI DATA LOGGER"); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"channel: %d", + hdd_sta_ctx->conn_info.freq); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"dot11mode: %d", + hdd_sta_ctx->conn_info.dot11Mode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"AKM: %d", + hdd_sta_ctx->conn_info.authType); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ssid: %.*s", + hdd_sta_ctx->conn_info.SSID.SSID.length, + hdd_sta_ctx->conn_info.SSID.SSID.ssId); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"roam count: %d", + hdd_sta_ctx->conn_info.roam_count); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ant_info: %d", + hdd_sta_ctx->conn_info.txrate.nss); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"datarate legacy %d", + hdd_sta_ctx->conn_info.txrate.legacy); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"datarate mcs: %d", + hdd_sta_ctx->conn_info.txrate.mcs); + if (hdd_sta_ctx->conn_info.conn_flag.ht_present) { + cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.ht_caps; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"ht caps: %x", + *cap_info); + } + if (hdd_sta_ctx->conn_info.conn_flag.vht_present) { + cap_info = (uint32_t *)&hdd_sta_ctx->conn_info.vht_caps; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"vht caps: %x", + *cap_info); + } + if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"hs20 info: %x", + hdd_sta_ctx->conn_info.hs20vendor_ie.release_num); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"signal: %d", + hdd_sta_ctx->conn_info.signal); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"noise: %d", + hdd_sta_ctx->conn_info.noise); +} + + +static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vstatus; + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + v_U8_t sta_id; + v_BOOL_t sendDisconInd = TRUE; + + // Sanity check + if(dev == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: net_dev is released return", __func__); + return eHAL_STATUS_FAILURE; + } + + // notify apps that we can't pass traffic anymore + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(dev); + netif_carrier_off(dev); + //TxTimeoutCount need to reset in case of disconnect handler + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + + INIT_COMPLETION(pAdapter->disconnect_comp_var); + /* If only STA mode is on */ + if((pHddCtx->concurrency_mode <= 1) && + (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <= 1)) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + } + + /* Need to apply spin lock before decreasing active sessions + * as there can be chance for double decrement if context switch + * Calls wlan_hdd_disconnect. + */ + + spin_lock_bh(&pAdapter->lock_for_active_session); + + /* HDD has initiated disconnect, do not send disconnect indication + * to kernel. Sending disconnected event to kernel for userspace + * initiated disconnect will be handled by diconnect handler call + * to cfg80211_disconnected + */ + if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) || + (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL(" HDD has initiated a disconnect, no need to send" + " disconnect indication to kernel")); + sendDisconInd = FALSE; + } + else if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Set HDD connState to eConnectionState_Disconnecting from %d "), + pHddStaCtx->conn_info.connState); + hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting ); + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + } + spin_unlock_bh(&pAdapter->lock_for_active_session); + + hdd_clearRoamProfileIe( pAdapter ); + + hdd_wmm_init( pAdapter ); + + // indicate 'disconnect' status to wpa_supplicant... + hdd_SendAssociationEvent(dev,pRoamInfo); + /* indicate disconnected event to nl80211 */ + if(roamStatus != eCSR_ROAM_IBSS_LEAVE) + { + /*During the WLAN uninitialization,supplicant is stopped before the + driver so not sending the status of the connection to supplicant*/ + if(pHddCtx->isLoadUnloadInProgress == WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS) + { + if (sendDisconInd) + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: sent disconnected event to nl80211", + __func__); +#ifdef WLAN_FEATURE_P2P_DEBUG + if(pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + if(globalP2PConnectionStatus == P2P_CLIENT_CONNECTED_STATE_1) + { + globalP2PConnectionStatus = P2P_CLIENT_DISCONNECTED_STATE; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] 8 way Handshake completed " + "and moved to disconnected state"); + } + else if(globalP2PConnectionStatus == P2P_CLIENT_COMPLETED_STATE) + { + globalP2PConnectionStatus = P2P_NOT_ACTIVE; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] P2P Client is removed " + "and moved to inactive state"); + } + } +#endif + if ((roamStatus == eCSR_ROAM_LOSTLINK) && + !pRoamInfo->reasonCode) + wlan_hdd_get_frame_logs(pAdapter, + WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR); + /*Only send indication to kernel if not initiated by kernel*/ + if ( sendDisconInd ) + { + /* To avoid wpa_supplicant sending "HANGED" CMD to ICS UI */ + if ( eCSR_ROAM_LOSTLINK == roamStatus ) + { + wlan_hdd_cfg80211_indicate_disconnect(dev, false, + pRoamInfo->reasonCode); + } + else + { + wlan_hdd_cfg80211_indicate_disconnect(dev, false, + WLAN_REASON_UNSPECIFIED); + } + } + + if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + hddLog(LOG1, + FL("P2P client is getting removed and we are tryig to re-enable TDLS")); + wlan_hdd_tdls_reenable(pHddCtx); + } + + //If the Device Mode is Station + // and the P2P Client is Connected + //Enable BMPS + + // In case of JB, as Change-Iface may or maynot be called for p2p0 + // Enable BMPS/IMPS in case P2P_CLIENT disconnected + if(VOS_STATUS_SUCCESS == hdd_issta_p2p_clientconnected(pHddCtx)) + { + //Enable BMPS only of other Session is P2P Client + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + + if(NULL != pHddCtx) + { + //Only P2P Client is there Enable Bmps back + if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) && + (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE])) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + } + } + } + } + } + + hdd_wmm_adapter_clear(pAdapter); + /* Clear PER based roam stats */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (sme_IsFeatureSupportedByFW(PER_BASED_ROAMING) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + pHddCtx->cfg_ini && pHddCtx->cfg_ini->isPERRoamEnabled && + pHddCtx->cfg_ini->isPERRoamRxPathEnabled) + sme_unset_per_roam_rxconfig(pHddCtx->hHal); +#endif +#if defined(WLAN_FEATURE_VOWIFI_11R) + sme_FTReset(WLAN_HDD_GET_HAL_CTX(pAdapter)); +#endif + + if (eCSR_ROAM_IBSS_LEAVE == roamStatus) + { + v_U8_t i; + + sta_id = IBSS_BROADCAST_STAID; + vstatus = hdd_ibss_DeregisterSTA( pAdapter, sta_id ); + if ( !VOS_IS_STATUS_SUCCESS(vstatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("hdd_roamDeregisterSTA() failed to for staID %d. " + "Status= %d [0x%x]"), + sta_id, status, status ); + + status = eHAL_STATUS_FAILURE; + } + pHddCtx->sta_to_adapter[sta_id] = NULL; + + /*Clear all the peer sta register with TL.*/ + for (i =0; i < HDD_MAX_NUM_IBSS_STA; i++ ) + { + if (0 != pHddStaCtx->conn_info.staId[i]) + { + sta_id = pHddStaCtx->conn_info.staId[i]; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Deregister StaID %d"),sta_id); + vstatus = hdd_ibss_DeregisterSTA( pAdapter, sta_id ); + if ( !VOS_IS_STATUS_SUCCESS(vstatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("hdd_roamDeregisterSTA() failed to for staID %d. " + "Status= %d [0x%x]"), + sta_id, status, status ); + status = eHAL_STATUS_FAILURE; + } + + vstatus = hdd_sta_id_hash_remove_entry(pAdapter, + sta_id, &pHddStaCtx->conn_info.peerMacAddress[i]); + if (vstatus != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not able to remove staid hash %d"), + sta_id); + status = eHAL_STATUS_FAILURE; + } else { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("ibss station removed sta_id %d mac:" + MAC_ADDRESS_STR), sta_id, + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.peerMacAddress[i].bytes)); + } + + /*set the staid and peer mac as 0, all other reset are + * done in hdd_connRemoveConnectInfo. + */ + pHddStaCtx->conn_info.staId[i]= 0; + vos_mem_zero( &pHddStaCtx->conn_info.peerMacAddress[i], sizeof( v_MACADDR_t ) ); + + if (sta_id < (WLAN_MAX_STA_COUNT + 3)) + pHddCtx->sta_to_adapter[sta_id] = NULL; + } + } + + } + else + { + sta_id = pHddStaCtx->conn_info.staId[0]; + /* clear scan cache for Link Lost */ + if (pRoamInfo && !pRoamInfo->reasonCode && + (eCSR_ROAM_LOSTLINK == roamStatus)) { + wlan_hdd_cfg80211_update_bss_list(pAdapter, + pHddStaCtx->conn_info.bssId); + sme_remove_bssid_from_scan_list(pHddCtx->hHal, + pHddStaCtx->conn_info.bssId); + } + + //We should clear all sta register with TL, for now, only one. + vstatus = hdd_roamDeregisterSTA( pAdapter, sta_id ); + if ( !VOS_IS_STATUS_SUCCESS(vstatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("hdd_roamDeregisterSTA() failed to for staID %d. " + "Status= %d [0x%x]"), + sta_id, status, status ); + + status = eHAL_STATUS_FAILURE; + } + + pHddCtx->sta_to_adapter[sta_id] = NULL; + } + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + if (VOS_STATUS_SUCCESS != + WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE_AC)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "WLANTL_ClearInterfaceStats Failed", __func__); + } + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0; + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0; + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0; + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0; +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + pAdapter->dad = false; + + // Clear saved connection information in HDD + hdd_connRemoveConnectInfo( pHddStaCtx ); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + hdd_connSetConnectionState( pHddStaCtx, eConnectionState_NotConnected ); +#ifdef WLAN_FEATURE_GTK_OFFLOAD + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + memset(&pHddStaCtx->gtkOffloadReqParams, 0, + sizeof (tSirGtkOffloadParams)); + pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE; + } +#endif + +#ifdef FEATURE_WLAN_TDLS + if (eCSR_ROAM_IBSS_LEAVE != roamStatus) + { + wlan_hdd_tdls_disconnection_callback(pAdapter); + } +#endif + + //Unblock anyone waiting for disconnect to complete + complete(&pAdapter->disconnect_comp_var); + hdd_print_bss_info(pHddStaCtx); + return( status ); +} + +static void hdd_postTLPacketPendingInd(hdd_adapter_t *pAdapter, + v_U8_t staId) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_SINT_t i; + v_SIZE_t size; + VOS_STATUS status; + v_BOOL_t granted = VOS_FALSE; + + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) || + (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)) + { + //Indicate to TL that there is pending data if a queue is non empty + for (i = WLANTL_AC_HIGH_PRIO; i>=0; --i) + { + size = 0; + hdd_list_size(&pAdapter->wmm_tx_queue[i], &size); + if (size > 0) + { + if (i != WLANTL_AC_HIGH_PRIO) + { + if (VOS_FALSE == + pAdapter->hddWmmStatus.wmmAcStatus[i].wmmAcAccessAllowed) + { + hdd_wmm_acquire_access(pAdapter, + (WLANTL_ACEnumType)i, &granted); + pAdapter->psbChanged |= (1 << i); + } + else + granted = VOS_TRUE; + } + + if (granted || (i == WLANTL_AC_HIGH_PRIO)) + { + status = WLANTL_STAPktPending(pHddCtx->pvosContext, + staId, (WLANTL_ACEnumType)i); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Failure in indicating pkt to TL for QID=%d", + __func__, i); + } + } + } + } + } +} + +static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + v_U8_t staId, + v_MACADDR_t *pPeerMacAddress, + tSirBssDescription *pBssDesc ) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + eCsrEncryptionType connectedCipherAlgo; + v_BOOL_t fConnected; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param = pHddCtx->cfg_ini; + + if ( NULL == pBssDesc) + { + return VOS_STATUS_E_FAILURE; + } + // Get the Station ID from the one saved during the assocation. + staDesc.ucSTAId = staId; + + staDesc.wSTAType = WLAN_STA_INFRA; + + // grab the bssid from the connection info in the adapter structure and hand that + // over to TL when registering. + vos_mem_copy( staDesc.vSTAMACAddress.bytes, pHddStaCtx->conn_info.bssId, + sizeof(pHddStaCtx->conn_info.bssId) ); + + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + // set the QoS field appropriately + if (hdd_wmm_is_active(pAdapter)) + { + staDesc.ucQosEnabled = 1; + } + else + { + staDesc.ucQosEnabled = 0; + } + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if ( connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE ) + { + staDesc.ucProtectedFrame = 1; + } + else + { + staDesc.ucProtectedFrame = 0; + + } + +#ifdef FEATURE_WLAN_ESE + staDesc.ucIsEseSta = pRoamInfo->isESEAssoc; +#endif //FEATURE_WLAN_ESE + +#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK + /* check whether replay check is valid for the station or not */ + if( (eCSR_ENCRYPT_TYPE_TKIP == connectedCipherAlgo) || (eCSR_ENCRYPT_TYPE_AES == connectedCipherAlgo)) + { + /* Encryption mode is either TKIP or AES + and replay check is valid for only these + two encryption modes */ + staDesc.ucIsReplayCheckValid = VOS_TRUE; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "HDD register TL ucIsReplayCheckValid %d: Replay check is needed for station", staDesc.ucIsReplayCheckValid); + } + + else + { + /* For other encryption modes replay check is + not needed */ + staDesc.ucIsReplayCheckValid = VOS_FALSE; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "HDD register TL ucIsReplayCheckValid %d", staDesc.ucIsReplayCheckValid); + } +#endif + +#ifdef FEATURE_WLAN_WAPI + hddLog(LOG1, "%s: WAPI STA Registered: %d", __func__, pAdapter->wapi_info.fIsWapiSta); + if (pAdapter->wapi_info.fIsWapiSta) + { + staDesc.ucIsWapiSta = 1; + } + else + { + staDesc.ucIsWapiSta = 0; + } +#endif /* FEATURE_WLAN_WAPI */ + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame ); + + // UMA is Not ready yet, Xlation will be done by TL + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "HDD register TL QoS_enabled=%d", + staDesc.ucQosEnabled ); + // Initialize signatures and state + staDesc.ucUcastSig = pRoamInfo->ucastSig; + staDesc.ucBcastSig = pRoamInfo->bcastSig; + staDesc.ucInitState = pRoamInfo->fAuthRequired ? + WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED; + // Register the Station with TL... + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HDD register TL ucInitState=%d", __func__, staDesc.ucInitState ); + vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext, + hdd_rx_packet_cbk, + hdd_tx_complete_cbk, + hdd_tx_fetch_packet_cbk, &staDesc, + pBssDesc->rssi ); + + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + vosStatus, vosStatus ); + return vosStatus; + } + + if ( cfg_param->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + cfg_param->trafficMntrTmrForSplitScan); + } + + // if (WPA), tell TL to go to 'connected' and after keys come to the driver, + // then go to 'authenticated'. For all other authentication types + // (those that donot require upper layer authentication) we can put + // TL directly into 'authenticated' state. + if (staDesc.wSTAType != WLAN_STA_IBSS) + VOS_ASSERT( fConnected ); + + if ( !pRoamInfo->fAuthRequired ) + { + // Connections that do not need Upper layer auth, transition TL directly + // to 'Authenticated' state. + vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED ); + + pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE; + + hdd_postTLPacketPendingInd(pAdapter, staDesc.ucSTAId); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "ULA auth StaId= %d. Changing TL state to CONNECTED" + "at Join time", pHddStaCtx->conn_info.staId[0] ); + vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, staDesc.ucSTAId, + WLANTL_STA_CONNECTED ); + pHddStaCtx->conn_info.uIsAuthenticated = VOS_FALSE; + } + return( vosStatus ); +} + +static void hdd_SendReAssocEvent(struct net_device *dev, hdd_adapter_t *pAdapter, + tCsrRoamInfo *pCsrRoamInfo, v_U8_t *reqRsnIe, tANI_U32 reqRsnLength) +{ + unsigned int len = 0; + u8 *pFTAssocRsp = NULL; + v_U8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL); + tANI_U32 rspRsnLength = 0; + struct cfg80211_bss* bss; + tCsrRoamConnectedProfile roam_profile; + struct ieee80211_channel *chan; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + if (!rspRsnIe) { + hddLog(LOGE, "%s: Unable to allocate RSN IE", __func__); + return; + } + + if (pCsrRoamInfo == NULL) { + hddLog(LOGE, "%s: Invalid CSR roam info", __func__); + goto done; + } + + if (pCsrRoamInfo->nAssocRspLength == 0) { + hddLog(LOGE, "%s: Invalid assoc response length", __func__); + goto done; + } + + pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength + + pCsrRoamInfo->nAssocReqLength); + if (pFTAssocRsp == NULL) + goto done; + + //pFTAssocRsp needs to point to the IEs + pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET; + hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__, + (unsigned int)pFTAssocRsp[0], + (unsigned int)pFTAssocRsp[1]); + + // Send the Assoc Resp, the supplicant needs this for initial Auth. + len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET; + rspRsnLength = len; + memcpy(rspRsnIe, pFTAssocRsp, len); + memset(rspRsnIe + len, 0, IW_GENERIC_IE_MAX - len); + + chan = ieee80211_get_channel(pAdapter->wdev.wiphy, + (int) pCsrRoamInfo->pBssDesc->channelId); + vos_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile)); + sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roam_profile); + bss = hdd_get_bss_entry(pAdapter->wdev.wiphy, + chan, pCsrRoamInfo->bssid, + &roam_profile.SSID.ssId[0], + roam_profile.SSID.length); + cfg80211_roamed_bss(dev, bss, + reqRsnIe, reqRsnLength, + rspRsnIe, rspRsnLength,GFP_KERNEL); + +done: + kfree(rspRsnIe); +} + +void hdd_PerformRoamSetKeyComplete(hdd_adapter_t *pAdapter) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + tCsrRoamInfo roamInfo; + roamInfo.fAuthRequired = FALSE; + vos_mem_copy(roamInfo.bssid, + pHddStaCtx->roam_info.bssid, + WNI_CFG_BSSID_LEN); + vos_mem_copy(roamInfo.peerMac, + pHddStaCtx->roam_info.peerMac, + WNI_CFG_BSSID_LEN); + + halStatus = hdd_RoamSetKeyCompleteHandler(pAdapter, + &roamInfo, + pHddStaCtx->roam_info.roamId, + pHddStaCtx->roam_info.roamStatus, + eCSR_ROAM_RESULT_AUTHENTICATED); + if (halStatus != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, "%s: Set Key complete failure", __func__); + } + pHddStaCtx->roam_info.deferKeyComplete = FALSE; +} + +static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_adapter_t *pHostapdAdapter = NULL; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN]; + tANI_U32 reqRsnLength = DOT11F_IE_RSN_MAX_LEN; +#if defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) || defined (WLAN_FEATURE_VOWIFI_11R) + int ft_carrier_on = FALSE; +#endif + int status; + v_BOOL_t hddDisconInProgress = FALSE; + + /* HDD has initiated disconnect, do not send connect result indication + * to kernel as it will be handled by __cfg80211_disconnect. + */ + if (((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) || + (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)) && + ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) || + (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL(" Disconnect from HDD in progress ")); + hddDisconInProgress = TRUE; + } + + if ( eCSR_ROAM_RESULT_ASSOCIATED == roamResult ) + { + if ( !hddDisconInProgress ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_Associated", + __func__); + hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Associated ); + } + + pAdapter->maxRateFlags = pRoamInfo->maxRateFlags; + // Save the connection info from CSR... + hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE ); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (sme_IsFeatureSupportedByFW(PER_BASED_ROAMING) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + !hddDisconInProgress && + pHddCtx->cfg_ini && pHddCtx->cfg_ini->isPERRoamEnabled && + pHddCtx->cfg_ini->isPERRoamRxPathEnabled) + sme_set_per_roam_rxconfig(pHddCtx->hHal, + pHddStaCtx->conn_info.staId[0], + pHddCtx->cfg_ini->rateDownThreshold, + pHddCtx->cfg_ini->rateUpThreshold, + pHddCtx->cfg_ini->PERroamTriggerPercent, + pHddCtx->cfg_ini->PERroamRxPktsThreshold, + pHddCtx->cfg_ini->waitPeriodForNextPERScan); +#endif + +#ifdef FEATURE_WLAN_WAPI + if ( pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE || + pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_PSK ) + { + pAdapter->wapi_info.fIsWapiSta = 1; + } + else + { + pAdapter->wapi_info.fIsWapiSta = 0; + } +#endif /* FEATURE_WLAN_WAPI */ + + // indicate 'connect' status to userspace + hdd_SendAssociationEvent(dev,pRoamInfo); + + + // Initialize the Linkup event completion variable + INIT_COMPLETION(pAdapter->linkup_event_var); + + /* + Sometimes Switching ON the Carrier is taking time to activate the device properly. Before allowing any + packet to go up to the application, device activation has to be ensured for proper queue mapping by the + kernel. we have registered net device notifier for device change notification. With this we will come to + know that the device is getting activated properly. + */ +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (pHddStaCtx->ft_carrier_on == FALSE && !hddDisconInProgress ) + { +#endif + // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable + pAdapter->isLinkUpSvcNeeded = TRUE; + + // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable + pAdapter->isLinkUpSvcNeeded = TRUE; + + // Switch on the Carrier to activate the device + netif_carrier_on(dev); + + // Wait for the Link to up to ensure all the queues are set properly by the kernel + status = wait_for_completion_interruptible_timeout(&pAdapter->linkup_event_var, + msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)); + if(!status) + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning:ASSOC_LINKUP_TIMEOUT", __func__); + } + + // Disable Linkup Event Servicing - no more service required from the net device notifier call + pAdapter->isLinkUpSvcNeeded = FALSE; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + } + else { + pHddStaCtx->ft_carrier_on = FALSE; + ft_carrier_on = TRUE; + } +#endif + /* Check for STAID */ + if( (WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId ) + pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter; + else + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Wrong Staid: %d", __func__, pRoamInfo->staId); + + //For reassoc, the station is already registered, all we need is to change the state + //of the STA in TL. + //If authentication is required (WPA/WPA2/DWEP), change TL to CONNECTED instead of AUTHENTICATED + //pRoamInfo->fReassocReq will be set only for the reassoc to same ap + if( !pRoamInfo->fReassocReq ) + { + struct cfg80211_bss *bss; +#ifdef WLAN_FEATURE_VOWIFI_11R + u8 *pFTAssocRsp = NULL; + unsigned int assocRsplen = 0; + u8 *pFTAssocReq = NULL; + unsigned int assocReqlen = 0; + struct ieee80211_channel *chan; +#endif + v_U8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN]; + tANI_U32 rspRsnLength = DOT11F_IE_RSN_MAX_LEN; + + /* add bss_id to cfg80211 data base */ + bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo); + if (NULL == bss) + { + hddLog(LOGE, + FL("Not able to create BSS entry")); + netif_carrier_off(dev); + if (!hddDisconInProgress) { + /* + * Here driver was not able to update cfg80211 database + * this can happen if connected channel is not valid, + * i.e reg domain was changed during connection. + * Queue disconnect for the session if disconnect is + * not in progress. + */ + hddLog(LOGE, FL("Disconnecting...")); + sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + return eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN || + pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_FT_RSN_PSK ) + { + + //Association Response + pFTAssocRsp = (u8 *)(pRoamInfo->pbFrames + pRoamInfo->nBeaconLength + + pRoamInfo->nAssocReqLength); + if (pFTAssocRsp != NULL) + { + // pFTAssocRsp needs to point to the IEs + pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET; + hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__, + (unsigned int)pFTAssocRsp[0], + (unsigned int)pFTAssocRsp[1]); + assocRsplen = pRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET; + } + else + { + hddLog(LOGE, "%s:AssocRsp is NULL", __func__); + assocRsplen = 0; + } + + //Association Request + pFTAssocReq = (u8 *)(pRoamInfo->pbFrames + + pRoamInfo->nBeaconLength); + if (pFTAssocReq != NULL) + { + if(!ft_carrier_on) + { + // pFTAssocReq needs to point to the IEs + pFTAssocReq += FT_ASSOC_REQ_IES_OFFSET; + hddLog(LOG1, "%s: pFTAssocReq is now at %02x%02x", __func__, + (unsigned int)pFTAssocReq[0], + (unsigned int)pFTAssocReq[1]); + assocReqlen = pRoamInfo->nAssocReqLength - FT_ASSOC_REQ_IES_OFFSET; + } + else + { + /* This should contain only the FTIEs */ + assocReqlen = pRoamInfo->nAssocReqLength; + } + } + else + { + hddLog(LOGE, "%s:AssocReq is NULL", __func__); + assocReqlen = 0; + } + + if(ft_carrier_on) + { + if ( !hddDisconInProgress ) + { + struct cfg80211_bss *roam_bss; + + hddLog(LOG1, "%s ft_carrier_on is %d, sending roamed " + "indication", __FUNCTION__, ft_carrier_on); + chan = ieee80211_get_channel(pAdapter->wdev.wiphy, + (int)pRoamInfo->pBssDesc->channelId); + hddLog(LOG1, "assocReqlen %d assocRsplen %d", assocReqlen, + assocRsplen); + if (pHddCtx->cfg_ini && + pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_SEND_REASSOC_RSP, NULL, 0); + } + roam_bss = hdd_get_bss_entry(pAdapter->wdev.wiphy, + chan, pRoamInfo->bssid, + pRoamInfo->u.pConnectedProfile->SSID.ssId, + pRoamInfo->u.pConnectedProfile->SSID.length); + cfg80211_roamed_bss(dev, roam_bss, + pFTAssocReq, assocReqlen, + pFTAssocRsp, assocRsplen, + GFP_KERNEL); + } + if (sme_GetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + sme_SetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter), FALSE); + pRoamInfo->fAuthRequired = FALSE; + + vos_mem_copy(pHddStaCtx->roam_info.bssid, + pRoamInfo->bssid, + HDD_MAC_ADDR_LEN); + vos_mem_copy(pHddStaCtx->roam_info.peerMac, + pRoamInfo->peerMac, + HDD_MAC_ADDR_LEN); + pHddStaCtx->roam_info.roamId = roamId; + pHddStaCtx->roam_info.roamStatus = roamStatus; + pHddStaCtx->roam_info.deferKeyComplete = TRUE; + } + } + else if ( !hddDisconInProgress ) + { + hddLog(LOG1, "%s ft_carrier_on is %d, sending connect " + "indication", __FUNCTION__, ft_carrier_on); + hdd_connect_result(dev, pRoamInfo->bssid, pRoamInfo, + pFTAssocReq, assocReqlen, + pFTAssocRsp, assocRsplen, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + } + } + else +#endif + { + /* wpa supplicant expecting WPA/RSN IE in connect result */ + csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &reqRsnLength, + reqRsnIe); + + csrRoamGetWpaRsnRspIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &rspRsnLength, + rspRsnIe); + if ( !hddDisconInProgress ) + { +#if defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if(ft_carrier_on) + { + hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength); + if (pHddCtx->cfg_ini && + pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_SEND_REASSOC_RSP, NULL, 0); + } + } + else +#endif /* FEATURE_WLAN_ESE */ + + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: sending connect indication to nl80211:" + " for bssid " MAC_ADDRESS_STR + " result:%d and Status:%d", + __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid), + roamResult, roamStatus); + /* inform connect result to nl80211 */ + hdd_connect_result(dev, pRoamInfo->bssid, + pRoamInfo, + reqRsnIe, reqRsnLength, + rspRsnIe, rspRsnLength, + WLAN_STATUS_SUCCESS, + GFP_KERNEL); + } + } + } + if ( !hddDisconInProgress ) + { + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + pHddCtx->wiphy, +#endif + bss); + // Register the Station with TL after associated... + vosStatus = hdd_roamRegisterSTA( pAdapter, + pRoamInfo, + pHddStaCtx->conn_info.staId[ 0 ], + NULL, + pRoamInfo->pBssDesc ); + } + } + else + { + /* wpa supplicant expecting WPA/RSN IE in connect result */ + /* in case of reassociation also need to indicate it to supplicant */ + csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &reqRsnLength, + reqRsnIe); + + hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength); + //Reassoc successfully + if( pRoamInfo->fAuthRequired ) + { + vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[ 0 ], + WLANTL_STA_CONNECTED ); + pHddStaCtx->conn_info.uIsAuthenticated = VOS_FALSE; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: staId: %d Changing TL state to AUTHENTICATED", + __func__, pHddStaCtx->conn_info.staId[ 0 ] ); + vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[ 0 ], + WLANTL_STA_AUTHENTICATED ); + pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE; + hdd_postTLPacketPendingInd(pAdapter, + pHddStaCtx->conn_info.staId[0]); + } + } + + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // perform any WMM-related association processing + hdd_wmm_assoc(pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Cannot register STA with TL. Failed with vosStatus = %d [%08X]", + vosStatus, vosStatus ); + } +#ifdef WLAN_FEATURE_11W + vos_mem_zero( &pAdapter->hdd_stats.hddPmfStats, + sizeof(pAdapter->hdd_stats.hddPmfStats) ); +#endif + + // Start the Queue + if ( !hddDisconInProgress ) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_wake_all_queues(dev); + } + if (pHddCtx->cfg_ini && pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_ENABLE_TX_QUEUE, NULL, 0); + } +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_tdls_connection_callback(pAdapter); +#endif + } + else + { + hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (pRoamInfo) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wlan: connection failed with " MAC_ADDRESS_STR " result:%d and Status:%d", + MAC_ADDR_ARRAY(pRoamInfo->bssid), roamResult, roamStatus); + else + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wlan: connection failed with " MAC_ADDRESS_STR " result:%d and Status:%d", + MAC_ADDR_ARRAY(pWextState->req_bssId), + roamResult, roamStatus); + if (!pHddStaCtx->get_mgmt_log_sent) { + pHddStaCtx->get_mgmt_log_sent = TRUE; + wlan_hdd_get_frame_logs(pAdapter, + WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR); + } + + if ((eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE == roamResult) || + (pRoamInfo && + ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode) || + (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode) || + (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE == pRoamInfo->statusCode)))) { + wlan_hdd_cfg80211_update_bss_list(pAdapter, + pRoamInfo ? pRoamInfo->bssid : pWextState->req_bssId); + sme_remove_bssid_from_scan_list(pHddCtx->hHal, + pRoamInfo ? pRoamInfo->bssid : pWextState->req_bssId); + } + /* Set connection state to eConnectionState_NotConnected only when CSR + * has completed operation - with a ASSOCIATION_FAILURE status + */ + if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus && !hddDisconInProgress ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + hdd_connSetConnectionState( pHddStaCtx, eConnectionState_NotConnected); + } + if((pHddCtx->concurrency_mode <= 1) && + (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1)) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + } + + //If the Device Mode is Station + // and the P2P Client is Connected + //Enable BMPS + + // In case of JB, as Change-Iface may or maynot be called for p2p0 + // Enable BMPS/IMPS in case P2P_CLIENT disconnected + if(((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) && + (vos_concurrent_open_sessions_running())) + { + //Enable BMPS only of other Session is P2P Client + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + + if(NULL != pHddCtx) + { + //Only P2P Client is there Enable Bmps back + if((0 == pHddCtx->no_of_open_sessions[VOS_STA_SAP_MODE]) && + (0 == pHddCtx->no_of_open_sessions[VOS_P2P_GO_MODE])) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + } + } + } + + /* CR465478: Only send up a connection failure result when CSR has + * completed operation - with a ASSOCIATION_FAILURE status.*/ + if ( eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus && !hddDisconInProgress ) + { + + if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + { + hddLog(LOG1, + FL("Assoication Failure for P2P client and we are trying to re-enable TDLS")); + wlan_hdd_tdls_reenable(pHddCtx); + } + + if (pRoamInfo) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: send connect failure to nl80211:" + " for bssid " MAC_ADDRESS_STR + " result:%d and Status:%d reasonCode %d" , + __func__, MAC_ADDR_ARRAY(pRoamInfo->bssid), + roamResult, roamStatus, pRoamInfo->reasonCode); + pHddStaCtx->conn_info.assoc_status_code = + pRoamInfo->statusCode; + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: connect failed:" + " for bssid " MAC_ADDRESS_STR + " result:%d and Status:%d" , + __func__, MAC_ADDR_ARRAY(pWextState->req_bssId), + roamResult, roamStatus); + } + + /* inform association failure event to nl80211 */ + if ( eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult ) + { + if (pRoamInfo) + hdd_connect_result(dev, pRoamInfo->bssid, NULL, + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL); + else + hdd_connect_result(dev, pWextState->req_bssId, NULL, + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL); + } + else + { + if (pRoamInfo) + hdd_connect_result(dev, pRoamInfo->bssid, NULL, + NULL, 0, NULL, 0, + pRoamInfo->reasonCode ? + pRoamInfo->reasonCode : + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); + else + hdd_connect_result(dev, pWextState->req_bssId, NULL, + NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); + } + /*Clear the roam profile*/ + hdd_clearRoamProfileIe( pAdapter ); + } + + hdd_wmm_init( pAdapter ); + + if (pRoamInfo) + { + WLANTL_AssocFailed(pRoamInfo->staId); + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(dev); + netif_carrier_off(dev); + + } + + if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) + { + pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP); + if (pHostapdAdapter != NULL) + { + /* Restart SAP if its operating channel is different + * from AP channel. + */ + if (pHostapdAdapter->sessionCtx.ap.operatingChannel != + (int)pRoamInfo->pBssDesc->channelId) + { + hddLog(VOS_TRACE_LEVEL_INFO,"Restart Sap as SAP channel is %d " + "and STA channel is %d", pHostapdAdapter->sessionCtx.ap.operatingChannel, + (int)pRoamInfo->pBssDesc->channelId); + hdd_hostapd_stop(pHostapdAdapter->dev); + if (pHddCtx->cfg_ini->enable_sap_auth_offload) + hdd_force_scc_restart_sap(pHostapdAdapter, + pHddCtx, (int)pRoamInfo->pBssDesc->channelId); + + } + } + } + return eHAL_STATUS_SUCCESS; +} + +/**============================================================================ + * + @brief hdd_RoamIbssIndicationHandler() - Here we update the status of the + Ibss when we receive information that we have started/joined an ibss session + + ===========================================================================*/ +static void hdd_RoamIbssIndicationHandler( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + struct cfg80211_bss *bss; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s: id %d, status %d, result %d", + __func__, pAdapter->dev->name, roamId, roamStatus, roamResult); + + switch( roamResult ) + { + // both IBSS Started and IBSS Join should come in here. + case eCSR_ROAM_RESULT_IBSS_STARTED: + case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS: + case eCSR_ROAM_RESULT_IBSS_COALESCED: + { + if (NULL == pRoamInfo) + { + VOS_ASSERT(0); + return; + } + + /* When IBSS Started comes from CSR, we need to move + * connection state to IBSS Disconnected (meaning no peers + * are in the IBSS). + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_IbssDisconnected", + __func__); + hdd_connSetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + eConnectionState_IbssDisconnected ); + /*notify wmm */ + hdd_wmm_connect(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS); + pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] = pAdapter; + + if (pRoamInfo->pBssDesc) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) + struct ieee80211_channel *chan; + int chan_no; + unsigned int freq; +#endif + hdd_ibss_RegisterSTA (pAdapter, pRoamInfo, + IBSS_BROADCAST_STAID, + &broadcastMacAddr, pRoamInfo->pBssDesc); + + /* we created the IBSS, notify supplicant */ + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s: created ibss " + MAC_ADDRESS_STR, + __func__, pAdapter->dev->name, + MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId)); + + /* we must first give cfg80211 the BSS information */ + bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo); + if (NULL == bss) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: %s: unable to create IBSS entry", + __func__, pAdapter->dev->name); + return; + } +#ifdef WLAN_FEATURE_RMC + netif_carrier_on(pAdapter->dev); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues(pAdapter->dev); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) + chan_no = pRoamInfo->pBssDesc->channelId; + + if (chan_no <= 14) + freq = ieee80211_channel_to_frequency(chan_no, + IEEE80211_BAND_2GHZ); + else + freq = ieee80211_channel_to_frequency(chan_no, + IEEE80211_BAND_5GHZ); + + chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq); + + if (chan) + cfg80211_ibss_joined(pAdapter->dev, bss->bssid, + chan, GFP_KERNEL); + else + hddLog(LOGE, FL("%s: chanId: %d, can't find channel"), + pAdapter->dev->name, + (int)pRoamInfo->pBssDesc->channelId); +#else + cfg80211_ibss_joined(pAdapter->dev, bss->bssid, GFP_KERNEL); +#endif + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + pHddCtx->wiphy, +#endif + bss); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NULL Bss Desc",__func__); + } + + /* Set Broadcast key again in case IBSS_COALESCED as DEL BSS, + * in IBSS_COALESCED will remove the BC key. + */ + if ((eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) && + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY + == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY + == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_TKIP == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_AES == pHddStaCtx->ibss_enc_key.encType )) + { + u8 grpmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + VOS_STATUS vosStatus; + + pHddStaCtx->ibss_enc_key.keyDirection = eSIR_TX_RX; + + memcpy(&pHddStaCtx->ibss_enc_key.peerMac, + grpmacaddr, WNI_CFG_BSSID_LEN); + hddLog(VOS_TRACE_LEVEL_INFO, + FL(" SET GTK in case of COALESCED")); + vosStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &pHddStaCtx->ibss_enc_key, &roamId ); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_RoamSetKey failed, returned %d"),vosStatus); + } + } + break; + } + + case eCSR_ROAM_RESULT_IBSS_START_FAILED: + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s: unable to create IBSS", + __func__, pAdapter->dev->name); + break; + } + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s: unexpected result %d", + __func__, pAdapter->dev->name, (int)roamResult); + break; + } + + return; +} + +/**============================================================================ + * + @brief roamSaveIbssStation() - Save the IBSS peer MAC address in the adapter. + This information is passed to iwconfig later. The peer that joined + last is passed as information to iwconfig. + If we add HDD_MAX_NUM_IBSS_STA or less STA we return success else we + return FALSE. + + ===========================================================================*/ +static int roamSaveIbssStation(hdd_adapter_t *pAdapter, v_U8_t staId, v_MACADDR_t *peerMacAddress) +{ + int fSuccess = FALSE; + int idx = 0; + VOS_STATUS status; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ ) + { + if ( 0 == pHddStaCtx->conn_info.staId[ idx ] ) + { + pHddStaCtx->conn_info.staId[ idx ] = staId; + + vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ], peerMacAddress ); + + fSuccess = TRUE; + break; + } + } + + status = hdd_sta_id_hash_add_entry(pAdapter, staId, peerMacAddress); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not able to add staid hash %d"), staId); + return FALSE; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("New station added sta_id %d mac:" + MAC_ADDRESS_STR), staId, + MAC_ADDR_ARRAY(peerMacAddress->bytes)); + + return( fSuccess ); +} +/**============================================================================ + * + @brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter. + If we remove HDD_MAX_NUM_IBSS_STA or less STA we return success else we + return FALSE. + + ===========================================================================*/ +static int roamRemoveIbssStation( hdd_adapter_t *pAdapter, v_U8_t staId ) +{ + int fSuccess = FALSE; + int idx = 0; + v_U8_t valid_idx = 0; + v_U8_t del_idx = 0; + v_U8_t empty_slots = 0; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + VOS_STATUS status; + + for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ ) + { + if ( staId == pHddStaCtx->conn_info.staId[ idx ] ) + { + pHddStaCtx->conn_info.staId[ idx ] = 0; + status = hdd_sta_id_hash_remove_entry(pAdapter, + staId, &pHddStaCtx->conn_info.peerMacAddress[idx]); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not able to remove staid hash %d"), staId ); + fSuccess = FALSE; + } else { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("station removed sta_id %d mac:" + MAC_ADDRESS_STR), staId, + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.peerMacAddress[idx].bytes)); + + vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ] ); + + fSuccess = TRUE; + // Note the deleted Index, if its 0 we need special handling + del_idx = idx; + empty_slots++; + } + } + else + { + if (pHddStaCtx->conn_info.staId[idx] != 0) + { + valid_idx = idx; + } + else + { + // Found an empty slot + empty_slots++; + } + } + } + + if (HDD_MAX_NUM_IBSS_STA == empty_slots) + { + // Last peer departed, set the IBSS state appropriately + pHddStaCtx->conn_info.connState = eConnectionState_IbssDisconnected; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Last IBSS Peer Departed!!!" ); + } + + // Find next active staId, to have a valid sta trigger for TL. + if (fSuccess == TRUE) + { + if (del_idx == 0) + { + if (pHddStaCtx->conn_info.staId[valid_idx] != 0) + { + pHddStaCtx->conn_info.staId[0] = pHddStaCtx->conn_info.staId[valid_idx]; + vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ 0 ], + &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ]); + + pHddStaCtx->conn_info.staId[valid_idx] = 0; + vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ] ); + } + } + } + return( fSuccess ); +} + +/**============================================================================ + * + @brief roamIbssConnectHandler() : We update the status of the IBSS to + connected in this function. + + ===========================================================================*/ +static eHalStatus roamIbssConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo ) +{ + struct cfg80211_bss *bss; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: IBSS Connect Indication from SME!!! " + "Set HDD connState to eConnectionState_IbssConnected", + __func__); + // Set the internal connection state to show 'IBSS Connected' (IBSS with a partner stations)... + hdd_connSetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), eConnectionState_IbssConnected ); + + // Save the connection info from CSR... + hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS ); + + // Send the bssid address to the wext. + hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo); + /* add bss_id to cfg80211 data base */ + bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo); + if (NULL == bss) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: %s: unable to create IBSS entry", + __func__, pAdapter->dev->name); + return eHAL_STATUS_FAILURE; + } + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + WLAN_HDD_GET_CTX(pAdapter)->wiphy, +#endif + bss); + + return( eHAL_STATUS_SUCCESS ); +} + +/**============================================================================ + * + @brief hdd_RoamSetKeyCompleteHandler() - Update the security parameters. + + ===========================================================================*/ +static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + eCsrEncryptionType connectedCipherAlgo; + v_BOOL_t fConnected = FALSE; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + WLANTL_STAStateType prevTLState = WLANTL_STA_INIT; + ENTER(); + + if (NULL == pRoamInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "pRoamInfo is NULL"); + return eHAL_STATUS_FAILURE; + } + // if ( WPA ), tell TL to go to 'authenticated' after the keys are set. + // then go to 'authenticated'. For all other authentication types (those that do + // not require upper layer authentication) we can put TL directly into 'authenticated' + // state. + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Set Key completion roamStatus =%d roamResult=%d " MAC_ADDRESS_STR, + roamStatus, roamResult, MAC_ADDR_ARRAY(pRoamInfo->peerMac)); + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if( fConnected ) + { + if ( WLAN_HDD_IBSS == pAdapter->device_mode ) + { + v_U8_t staId; + + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + if ( 0 == memcmp( pRoamInfo->peerMac, + &broadcastMacAddr, VOS_MAC_ADDR_SIZE ) ) + { + vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext, + IBSS_BROADCAST_STAID); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL STA GTK Installed for STAID=%d", IBSS_BROADCAST_STAID); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + else + { + vosStatus = hdd_Ibss_GetStaId(pHddStaCtx, + (v_MACADDR_t*)pRoamInfo->peerMac, + &staId); + if ( VOS_STATUS_SUCCESS == vosStatus ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL STA Ptk Installed for STAID=%d", staId); + vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext, + staId); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + } + } + else + { + WLANTL_GetSTAState(pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[0], + &prevTLState); + // TODO: Considering getting a state machine in HDD later. + // This routine is invoked twice. 1)set PTK 2)set GTK. + // The folloing if statement will be TRUE when setting GTK. + // At this time we don't handle the state in detail. + // Related CR: 174048 - TL not in authenticated state + if ( ( eCSR_ROAM_RESULT_AUTHENTICATED == roamResult ) && + (pRoamInfo != NULL) && !pRoamInfo->fAuthRequired ) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, "Key set " + "for StaId=%d. Changing TL state to AUTHENTICATED from" + " state:%d", pHddStaCtx->conn_info.staId[0], prevTLState); + + // Connections that do not need Upper layer authentication, + // transition TL to 'Authenticated' state after the keys are set. + vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[ 0 ], + WLANTL_STA_AUTHENTICATED ); + + pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE; + + if (WLANTL_STA_AUTHENTICATED != prevTLState) + hdd_postTLPacketPendingInd(pAdapter, + pHddStaCtx->conn_info.staId[0]); + //Need to call offload because when roaming happen at that time fwr + //clean offload info as part of the DelBss + // No need to configure offload if host was not suspended + spin_lock(&pHddCtx->filter_lock); + if(pHddCtx->hdd_wlan_suspended) + { + spin_unlock(&pHddCtx->filter_lock); + hdd_ReConfigSuspendDataClearedDuringRoaming(pHddCtx); + } + else + { + spin_unlock(&pHddCtx->filter_lock); + } + if (pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_SET_GTK_RSP, NULL, 0); + } + } + else + { + vosStatus = WLANTL_STAPtkInstalled( pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[ 0 ]); + + /* In case of OSEN move TL to 'Authenticated' after PTK is set */ + if (pWextState->roamProfile.bOSENAssociation == VOS_TRUE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, "PTK set" + " for StaId=%d. Due to OSEN, Changing TL state to" + "AUTHENTICATED from state:%d", + pHddStaCtx->conn_info.staId[0], prevTLState); + + vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[ 0 ], + WLANTL_STA_AUTHENTICATED ); + + pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE; + + if (WLANTL_STA_AUTHENTICATED != prevTLState) + hdd_postTLPacketPendingInd(pAdapter, + pHddStaCtx->conn_info.staId[0]); + } + + + + if (pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_SET_PTK_RSP, (void *)pRoamInfo->peerMac, 6); + } + } + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + } + else + { + // possible disassoc after issuing set key and waiting set key complete + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + + EXIT(); + return( eHAL_STATUS_SUCCESS ); +} +/**============================================================================ + * + @brief hdd_RoamMicErrorIndicationHandler() - This function indicates the Mic failure to the supplicant. + ===========================================================================*/ +static eHalStatus hdd_RoamMicErrorIndicationHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, eCsrRoamResult roamResult ) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if( eConnectionState_Associated == pHddStaCtx->conn_info.connState && + TKIP_COUNTER_MEASURE_STOPED == pHddStaCtx->WextState.mTKIPCounterMeasures ) + { + struct iw_michaelmicfailure msg; + union iwreq_data wreq; + memset(&msg, '\0', sizeof(msg)); + msg.src_addr.sa_family = ARPHRD_ETHER; + memcpy(msg.src_addr.sa_data, pRoamInfo->u.pMICFailureInfo->taMacAddr, sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr)); + hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(msg.src_addr.sa_data)); + + if(pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE) + msg.flags = IW_MICFAILURE_GROUP; + else + msg.flags = IW_MICFAILURE_PAIRWISE; + memset(&wreq, 0, sizeof(wreq)); + wreq.data.length = sizeof(msg); + wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq, (char *)&msg); + /* inform mic failure to nl80211 */ + cfg80211_michael_mic_failure(pAdapter->dev, + pRoamInfo->u.pMICFailureInfo->taMacAddr, + ((pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE) ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE), + pRoamInfo->u.pMICFailureInfo->keyId, + pRoamInfo->u.pMICFailureInfo->TSC, + GFP_KERNEL); + + } + + return( eHAL_STATUS_SUCCESS ); +} + +/**============================================================================ + * + @brief roamRoamConnectStatusUpdateHandler() - The Ibss connection status is + updated regularly here in this function. + + ===========================================================================*/ +static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult ) +{ + VOS_STATUS vosStatus; + + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + switch( roamResult ) + { + case eCSR_ROAM_RESULT_IBSS_NEW_PEER: + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + struct station_info *staInfo; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "IBSS New Peer indication from SME with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d", + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId), + pRoamInfo->staId ); + + pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter; + + pHddCtx->sta_to_adapter[IBSS_BROADCAST_STAID] = pAdapter; + WLANTL_UpdateSTABssIdforIBSS(pHddCtx->pvosContext, + IBSS_BROADCAST_STAID,pHddStaCtx->conn_info.bssId); + + // Register the Station with TL for the new peer. + vosStatus = hdd_ibss_RegisterSTA( pAdapter, + pRoamInfo, + pRoamInfo->staId, + (v_MACADDR_t *)pRoamInfo->peerMac, + pRoamInfo->pBssDesc ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Cannot register STA with TL for IBSS. Failed with vosStatus = %d [%08X]", + vosStatus, vosStatus ); + } + if (!roamSaveIbssStation(pAdapter, + pRoamInfo->staId, + (v_MACADDR_t *)pRoamInfo->peerMac)) + { + hddLog(LOGW, FL("Not Able to add sta in sta hash")); + break; + } + pHddStaCtx->ibss_sta_generation++; + + staInfo = vos_mem_malloc(sizeof(*staInfo)); + if (staInfo == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "memory allocation for station_info failed"); + return eHAL_STATUS_FAILED_ALLOC; + } + + memset(staInfo, 0, sizeof(*staInfo)); + staInfo->filled = 0; + staInfo->generation = pHddStaCtx->ibss_sta_generation; + + cfg80211_new_sta(pAdapter->dev, + (const u8 *)pRoamInfo->peerMac, + staInfo, GFP_KERNEL); + vos_mem_free(staInfo); + + if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_TKIP == pHddStaCtx->ibss_enc_key.encType + ||eCSR_ENCRYPT_TYPE_AES == pHddStaCtx->ibss_enc_key.encType ) + { + pHddStaCtx->ibss_enc_key.keyDirection = eSIR_TX_RX; + + memcpy(&pHddStaCtx->ibss_enc_key.peerMac, + pRoamInfo->peerMac, WNI_CFG_BSSID_LEN); + + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_INFO_HIGH, "New peer joined set PTK encType=%d", + pHddStaCtx->ibss_enc_key.encType); + + vosStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &pHddStaCtx->ibss_enc_key, &roamId ); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", + __func__, vosStatus); + return VOS_STATUS_E_FAILURE; + } + } + netif_carrier_on(pAdapter->dev); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues(pAdapter->dev); + break; + } + + case eCSR_ROAM_RESULT_IBSS_CONNECT: + { + + roamIbssConnectHandler( pAdapter, pRoamInfo ); + + break; + } + case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED: + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if ( !roamRemoveIbssStation(pAdapter, pRoamInfo->staId ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "IBSS peer departed by cannot find peer in our registration table with TL" ); + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "IBSS Peer Departed from SME with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d", + MAC_ADDR_ARRAY(pRoamInfo->peerMac), + MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId), + pRoamInfo->staId ); + + hdd_ibss_DeregisterSTA( pAdapter, pRoamInfo->staId ); + + pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL; + pHddStaCtx->ibss_sta_generation++; + + cfg80211_del_sta(pAdapter->dev, + (const u8 *)&pRoamInfo->peerMac, + GFP_KERNEL); + break; + } + case eCSR_ROAM_RESULT_IBSS_INACTIVE: + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME"); + // Stop only when we are inactive + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + hdd_connSetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), eConnectionState_NotConnected ); + + // Send the bssid address to the wext. + hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo); + // clean up data path + hdd_disconnect_tx_rx(pAdapter); + break; + } + default: + break; + + } + + return( eHAL_STATUS_SUCCESS ); +} + +#ifdef FEATURE_WLAN_TDLS +/**============================================================================ + * + @brief hdd_roamRegisterTDLSSTA() - Construct the staDesc and register with + TL the new STA. This is called as part of ADD_STA in the TDLS setup + Return: VOS_STATUS + + ===========================================================================*/ +VOS_STATUS hdd_roamRegisterTDLSSTA(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *peerMac, +#else + tANI_U8 *peerMac, +#endif + tANI_U16 staId, tANI_U8 ucastSig) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + eCsrEncryptionType connectedCipherAlgo = eCSR_ENCRYPT_TYPE_UNKNOWN; + v_BOOL_t fConnected = FALSE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param = pHddCtx->cfg_ini; + + fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo ); + if (!fConnected) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s not connected. ignored", __func__); + return VOS_FALSE; + } + + /* + * TDLS sta in BSS should be set as STA type TDLS and STA MAC should + * be peer MAC, here we are wokrking on direct Link + */ + staDesc.ucSTAId = staId ; + + staDesc.wSTAType = WLAN_STA_TDLS ; + + vos_mem_copy( staDesc.vSTAMACAddress.bytes, peerMac, + sizeof(tSirMacAddr) ); + + vos_mem_copy(staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId,6 ); + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + /* set the QoS field appropriately ..*/ + (hdd_wmm_is_active(pAdapter)) ? (staDesc.ucQosEnabled = 1) + : (staDesc.ucQosEnabled = 0) ; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "HDD register \ + TL QoS_enabled=%d", staDesc.ucQosEnabled ); + + staDesc.ucProtectedFrame = (connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE) ; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame ); + + /* + * UMA is ready we inform TL to do frame translation. + */ + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + + /* Initialize signatures and state */ + staDesc.ucUcastSig = ucastSig ; + + /* tdls Direct Link do not need bcastSig */ + staDesc.ucBcastSig = 0 ; + +#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK + if(staDesc.ucProtectedFrame) + staDesc.ucIsReplayCheckValid = VOS_TRUE; + else + staDesc.ucIsReplayCheckValid = VOS_FALSE; +#endif + + staDesc.ucInitState = WLANTL_STA_CONNECTED ; + + /* Register the Station with TL... */ + vosStatus = WLANTL_RegisterSTAClient( pVosContext, + hdd_rx_packet_cbk, + hdd_tx_complete_cbk, + hdd_tx_fetch_packet_cbk, &staDesc, 0 ); + + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_RegisterSTAClient() failed to register. " + "Status= %d [0x%08X]", __func__, vosStatus, vosStatus ); + return vosStatus; + } + + if ( cfg_param->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)) ) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + cfg_param->trafficMntrTmrForSplitScan); + } + return( vosStatus ); +} + +VOS_STATUS hdd_roamDeregisterTDLSSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus; + vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + __func__, staId, vosStatus, vosStatus ); + } + return( vosStatus ); +} + + +/* + * HDD interface between SME and TL to ensure TDLS client registration with + * TL in case of new TDLS client is added and deregistration at the time + * TDLS client is deleted. + */ + +eHalStatus hdd_RoamTdlsStatusUpdateHandler(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + eHalStatus status = eHAL_STATUS_FAILURE ; + tANI_U8 staIdx; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR), + roamResult == eCSR_ROAM_RESULT_ADD_TDLS_PEER ? + "ADD_TDLS_PEER" : + roamResult == eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? + "DEL_TDLS_PEER" : + roamResult == eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? + "DEL_TDLS_PEER_IND" : + roamResult == eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ? + "DEL_ALL_TDLS_PEER_IND" : + roamResult == eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? + "UPDATE_TDLS_PEER" : + roamResult == eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ? + "LINK_ESTABLISH_REQ_RSP" : + roamResult == eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP ? + "CHANNEL_SWITCH_REQ_RSP" : "UNKNOWN", + pRoamInfo->staId, MAC_ADDR_ARRAY(pRoamInfo->peerMac)); + switch( roamResult ) + { + case eCSR_ROAM_RESULT_ADD_TDLS_PEER: + { + if(eSIR_SME_SUCCESS != pRoamInfo->statusCode) + { + hddTdlsPeer_t *curr_peer; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("%s: Add Sta is failed. %d"),__func__, pRoamInfo->statusCode); + wlan_hdd_tdls_check_bmps(pAdapter); + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, + pRoamInfo->peerMac, FALSE); + if (NULL != curr_peer) + curr_peer->link_status = eTDLS_LINK_TEARING; + else + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s %d curr_peer is Null", __func__,__LINE__); + mutex_unlock(&pHddCtx->tdls_lock); + } + else + { + + /* check if there is available index for this new TDLS STA */ + for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ ) + { + if (0 == pHddCtx->tdlsConnInfo[staIdx].staId ) + { + pHddCtx->tdlsConnInfo[staIdx].sessionId = pRoamInfo->sessionId; + pHddCtx->tdlsConnInfo[staIdx].staId = pRoamInfo->staId; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("TDLS: STA IDX at %d is %d " + "of mac " MAC_ADDRESS_STR), + staIdx, pHddCtx->tdlsConnInfo[staIdx].staId, + MAC_ADDR_ARRAY(pRoamInfo->peerMac)); + + vos_copy_macaddr(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + (v_MACADDR_t *)pRoamInfo->peerMac) ; + status = eHAL_STATUS_SUCCESS ; + break ; + } + } + if (staIdx < HDD_MAX_NUM_TDLS_STA) + { + if (-1 == wlan_hdd_tdls_set_sta_id(pAdapter, pRoamInfo->peerMac, pRoamInfo->staId)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wlan_hdd_tdls_set_sta_id() failed"); + return VOS_FALSE; + } + + (WLAN_HDD_GET_CTX(pAdapter))->sta_to_adapter[pRoamInfo->staId] = pAdapter; + /* store the ucast signature , if required for further reference. */ + + wlan_hdd_tdls_set_signature( pAdapter, pRoamInfo->peerMac, pRoamInfo->ucastSig ); + /* start TDLS client registration with TL */ + status = hdd_roamRegisterTDLSSTA( pAdapter, + pRoamInfo->peerMac, + pRoamInfo->staId, + pRoamInfo->ucastSig); + wlan_hdd_tdls_increment_peer_count(pAdapter); + } + else + { + status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: no available slot in conn_info. staId %d cannot be stored", __func__, pRoamInfo->staId); + } + pAdapter->tdlsAddStaStatus = status; + } + complete(&pAdapter->tdls_add_station_comp); + break ; + } + case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER: + { + if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Add Sta is failed. %d", __func__, pRoamInfo->statusCode); + } + /* store the ucast signature which will be used later when + * registering to TL + */ + pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode; + complete(&pAdapter->tdls_add_station_comp); + break; + } + case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP: + { + if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) + { + hddTdlsPeer_t *curr_peer; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Link Establish Request failed. %d", __func__, pRoamInfo->statusCode); + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, + pRoamInfo->peerMac, FALSE); + if (curr_peer) + curr_peer->link_status = eTDLS_LINK_TEARING; + else + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s %d curr_peer is Null",__func__,__LINE__); + mutex_unlock(&pHddCtx->tdls_lock); + } + complete(&pAdapter->tdls_link_establish_req_comp); + break; + } + case eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP: + { + if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Channel switch request failed. %d", __func__, + pRoamInfo->statusCode); + else + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Channel switch request Success", __func__); + break; + } + case eCSR_ROAM_RESULT_DELETE_TDLS_PEER: + { + hddTdlsPeer_t *curr_peer; + for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ ) + { + if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) && + pRoamInfo->staId == pHddCtx->tdlsConnInfo[staIdx].staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("HDD: del STA IDX = %x"), pRoamInfo->staId) ; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, + pRoamInfo->peerMac, FALSE); + if (NULL != curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " Current status for peer" MAC_ADDRESS_STR "is %d", + MAC_ADDR_ARRAY(pRoamInfo->peerMac), curr_peer->link_status); + if (TDLS_IS_CONNECTED(curr_peer) || + (eTDLS_LINK_CONNECTING == curr_peer->link_status)) + { + mutex_unlock(&pHddCtx->tdls_lock); + hdd_roamDeregisterTDLSSTA ( pAdapter, pRoamInfo->staId ); + } + else + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_decrement_peer_count(pAdapter); + } + else + mutex_unlock(&pHddCtx->tdls_lock); + + mutex_lock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_reset_peer(pAdapter, pRoamInfo->peerMac); + mutex_unlock(&pHddCtx->tdls_lock); + + pHddCtx->tdlsConnInfo[staIdx].staId = 0 ; + pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + wlan_hdd_tdls_check_bmps(pAdapter); + status = eHAL_STATUS_SUCCESS ; + break ; + } + } + complete(&pAdapter->tdls_del_station_comp); + } + break ; + case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND: + { + hddTdlsPeer_t *curr_peer; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Sending teardown to supplicant with reason code %u", + __func__, pRoamInfo->reasonCode); + +#ifdef CONFIG_TDLS_IMPLICIT + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, pRoamInfo->peerMac, + FALSE); + wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer, pRoamInfo->reasonCode); + hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT, + curr_peer->peerMac); + mutex_unlock(&pHddCtx->tdls_lock); +#endif + status = eHAL_STATUS_SUCCESS ; + break ; + } + case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND: + { + /* 0 staIdx is assigned to AP we dont want to touch that */ + for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ ) + { + if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pRoamInfo->sessionId) && + pHddCtx->tdlsConnInfo[staIdx].staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("hdd_tdlsStatusUpdate: staIdx %d " MAC_ADDRESS_STR), + pHddCtx->tdlsConnInfo[staIdx].staId, + MAC_ADDR_ARRAY(pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes)); + + mutex_lock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_reset_peer(pAdapter, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); + mutex_unlock(&pHddCtx->tdls_lock); + + hdd_roamDeregisterTDLSSTA ( pAdapter, pHddCtx->tdlsConnInfo[staIdx].staId ); + wlan_hdd_tdls_decrement_peer_count(pAdapter); + + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + pHddCtx->tdlsConnInfo[staIdx].staId = 0 ; + pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; + + status = eHAL_STATUS_SUCCESS ; + } + } + wlan_hdd_tdls_check_bmps(pAdapter); + break ; + } + default: + { + break ; + } + } + + return status ; +} +#endif + +void iw_full_power_cbfn (void *pContext, eHalStatus status) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext; + hdd_context_t *pHddCtx = NULL; + int ret; + + ENTER(); + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pAdapter [%p]", + __func__, pAdapter); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return; + } + + if (pHddCtx->cfg_ini->fIsBmpsEnabled) + { + sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), NULL, NULL); + } + + EXIT(); +} + +eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, + eRoamCmdStatus roamStatus, eCsrRoamResult roamResult ) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext; + hdd_wext_state_t *pWextState = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + struct cfg80211_bss *bss_status; + hdd_context_t *pHddCtx = NULL; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "CSR Callback: status= %d result= %d roamID=%d", + roamStatus, roamResult, roamId ); + + /*Sanity check*/ + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter or adapter has invalid magic"); + return eHAL_STATUS_FAILURE; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if ((NULL == pWextState) || (NULL == pHddStaCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid WEXT state or HDD station context"); + return eHAL_STATUS_FAILURE; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG, + pAdapter->sessionId, roamStatus)); + switch( roamStatus ) + { + case eCSR_ROAM_SESSION_OPENED: + set_bit(SME_SESSION_OPENED, &pAdapter->event_flags); + complete(&pAdapter->session_open_comp_var); + break; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + /* We did pre-auth,then we attempted a 11r or ese reassoc. + * reassoc failed due to failure, timeout, reject from ap + * in any case tell the OS, our carrier is off and mark + * interface down */ + case eCSR_ROAM_FT_REASSOC_FAILED: + hddLog(LOGE, FL("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"), + roamStatus, roamResult, pAdapter->sessionId); + sme_resetCoexEevent(WLAN_HDD_GET_HAL_CTX(pAdapter)); + halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */ + if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set == TRUE) { + (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE; + } + pHddStaCtx->ft_carrier_on = FALSE; + pHddStaCtx->hdd_ReassocScenario = FALSE; + break; + + case eCSR_ROAM_FT_START: + // When we roam for EsE and 11r, we dont want the + // OS to be informed that the link is down. So mark + // the link ready for ft_start. After this the + // eCSR_ROAM_SHOULD_ROAM will be received. + // Where in we will not mark the link down + // Also we want to stop tx at this point when we will be + // doing disassoc at this time. This saves 30-60 msec + // after reassoc. + { + struct net_device *dev = pAdapter->dev; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(dev); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_DISABLE_TX_QUEUE, NULL, 0); + } + /* + * Deregister this STA with TL, but do not flush the packets + * for this STA from wmm_tx_queue. Since there is no valid STA + * for these packets they will not be transmitted. Eventually + * after the reassociation is successful, these packets will be + * transmitted after registering STA with TL again. This ensures + * that driver does not drop packets during roaming. + */ + status = WLANTL_ClearSTAClient(pHddCtx->pvosContext, + pHddStaCtx->conn_info.staId[0]); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("WLANTL_ClearSTAClient failed for staID %d." + "Status= %d [0x%x]"), pHddStaCtx->conn_info.staId[0], + status, status); + halStatus = eHAL_STATUS_FAILURE; + } + } + pHddStaCtx->ft_carrier_on = TRUE; + pHddStaCtx->hdd_ReassocScenario = VOS_TRUE; + break; +#endif + + case eCSR_ROAM_SHOULD_ROAM: + // Dont need to do anything + { + struct net_device *dev = pAdapter->dev; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + // notify apps that we can't pass traffic anymore + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(dev); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (pHddStaCtx->ft_carrier_on == FALSE) + { +#endif + netif_carrier_off(dev); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + } +#endif + +#if !(defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)) + //We should clear all sta register with TL, for now, only one. + status = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] ); + if ( !VOS_IS_STATUS_SUCCESS(status ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"), + pHddStaCtx->conn_info.staId[0], status, status ); + halStatus = eHAL_STATUS_FAILURE; + } +#endif + } + break; + case eCSR_ROAM_LOSTLINK: + case eCSR_ROAM_DISASSOCIATED: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "****eCSR_ROAM_DISASSOCIATED****"); + sme_resetCoexEevent(WLAN_HDD_GET_HAL_CTX(pAdapter)); + halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */ + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->hdd_mcastbcast_filter_set == TRUE) + { + hdd_conf_mcastbcast_filter(pHddCtx, FALSE); + + if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) { + pHddCtx->configuredMcastBcastFilter = + pHddCtx->sus_res_mcastbcast_filter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: disassociation happening, restoring configuredMcastBcastFilter"); + hddLog(VOS_TRACE_LEVEL_INFO,"McastBcastFilter = %d", + pHddCtx->configuredMcastBcastFilter); + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: already called mcastbcast filter"); + (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE; + } +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* Call to clear any MC Addr List filter applied after + * successful connection. + */ + wlan_hdd_set_mc_addr_list(pAdapter, FALSE); +#endif + } + break; + case eCSR_ROAM_IBSS_LEAVE: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "****eCSR_ROAM_IBSS_LEAVE****"); + halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + break; + case eCSR_ROAM_ASSOCIATION_COMPLETION: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "****eCSR_ROAM_ASSOCIATION_COMPLETION****"); + // To Do - address probable memory leak with WEP encryption upon successful association + if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) + { + //Clear saved connection information in HDD + hdd_connRemoveConnectInfo( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) ); + } + halStatus = hdd_AssociationCompletionHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + + break; + case eCSR_ROAM_ASSOCIATION_FAILURE: + halStatus = hdd_AssociationCompletionHandler( pAdapter, + pRoamInfo, roamId, roamStatus, roamResult ); + break; + case eCSR_ROAM_IBSS_IND: + hdd_RoamIbssIndicationHandler( pAdapter, pRoamInfo, roamId, + roamStatus, roamResult ); + break; + + case eCSR_ROAM_CONNECT_STATUS_UPDATE: + halStatus = roamRoamConnectStatusUpdateHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + break; + + case eCSR_ROAM_MIC_ERROR_IND: + halStatus = hdd_RoamMicErrorIndicationHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + break; + case eCSR_ROAM_LOST_LINK_PARAMS_IND: + { + /* + * The RSSI will be subtracted from 100 as FW is sending the RSSI by + * adding the 100 value. + */ + pAdapter->rssi_on_disconnect = pRoamInfo->u.pLostLinkParams->rssi - 100; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : Rssi on Disconnect : %d", + __func__, pAdapter->rssi_on_disconnect); + break; + } + case eCSR_ROAM_SET_KEY_COMPLETE: + { + hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + if((pHddCtx) && + (TRUE == pHddCtx->hdd_wlan_suspended) && + ((eCSR_ROAM_RESULT_NONE == roamResult)|| + (pRoamInfo && pRoamInfo->is11rAssoc))) + { + /* Send DTIM period to the FW; only if the wlan is already + in suspend. This is the case with roaming (reassoc), + DELETE_BSS_REQ zeroes out Modulated/Dynamic DTIM sent in + previous suspend_wlan. Sending SET_POWER_PARAMS_REQ + before the ENTER_BMPS_REQ ensures Listen Interval is + regained back to LI * Modulated DTIM */ + hdd_set_pwrparams(pHddCtx); + + /* At this point, device should not be in BMPS; + if due to unexpected scenario, if we are in BMPS, + then trigger Exit and Enter BMPS to take DTIM period + effective */ + if (BMPS == pmcGetPmcState(pHddCtx->hHal)) + { + hddLog( LOGE, FL("Not expected: device is already in BMPS mode, Exit & Enter BMPS again!")); + + sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_full_power_cbfn, pAdapter, + eSME_FULL_PWR_NEEDED_BY_HDD); + } + } + + if ((pHddCtx) && + (FULL_POWER == pmcGetPmcState(pHddCtx->hHal)) && + (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) && + ((eCSR_ROAM_RESULT_NONE == roamResult) || + (pRoamInfo && pRoamInfo->is11rAssoc))) + { + hddLog( LOG1, FL("Device in full power." + "Stop and start traffic timer for roaming")); + pmcStopTrafficTimer(pHddCtx->hHal); + if (pmcStartTrafficTimer(pHddCtx->hHal, + TRAFFIC_TIMER_ROAMING) != eHAL_STATUS_SUCCESS) + { + hddLog(LOGP, FL("Cannot start traffic timer")); + } + } + + halStatus = hdd_RoamSetKeyCompleteHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult ); + if ((eCSR_ROAM_RESULT_NONE == roamResult) || + (pRoamInfo && pRoamInfo->is11rAssoc)) + pHddStaCtx->hdd_ReassocScenario = FALSE; + } + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_ROAM_FT_RESPONSE: + hdd_SendFTEvent(pAdapter); + break; +#endif +#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + case eCSR_ROAM_PMK_NOTIFY: + if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType) + { + /* Notify the supplicant of a new candidate */ + halStatus = wlan_hdd_cfg80211_pmksa_candidate_notify(pAdapter, pRoamInfo, 1, false); + } + break; +#endif + +#ifdef FEATURE_WLAN_LFR_METRICS + case eCSR_ROAM_PREAUTH_INIT_NOTIFY: + /* This event is to notify pre-auth initiation */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter, pRoamInfo)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + case eCSR_ROAM_PREAUTH_STATUS_SUCCESS: + /* This event will notify pre-auth completion in case of success */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter, + pRoamInfo, 1)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + case eCSR_ROAM_PREAUTH_STATUS_FAILURE: + /* This event will notify pre-auth completion in case of failure. */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter, + pRoamInfo, 0)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + case eCSR_ROAM_HANDOVER_SUCCESS: + /* This event is to notify handover success. + It will be only invoked on success */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_cfg80211_roam_metrics_handover(pAdapter, pRoamInfo)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; +#endif + case eCSR_ROAM_REMAIN_CHAN_READY: + hdd_remainChanReadyHandler( pAdapter ); + break; + case eCSR_ROAM_SEND_ACTION_CNF: + hdd_sendActionCnf( pAdapter, + (roamResult == eCSR_ROAM_RESULT_NONE) ? TRUE : FALSE ); + break; +#ifdef FEATURE_WLAN_TDLS + case eCSR_ROAM_TDLS_STATUS_UPDATE: + halStatus = hdd_RoamTdlsStatusUpdateHandler( pAdapter, pRoamInfo, + roamId, roamStatus, roamResult ); + break ; + case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND: + wlan_hdd_tdls_mgmt_completion_callback(pAdapter, pRoamInfo->reasonCode); + break; +#endif +#ifdef WLAN_FEATURE_11W + case eCSR_ROAM_UNPROT_MGMT_FRAME_IND: + hdd_indicateUnprotMgmtFrame(pAdapter, pRoamInfo->nFrameLength, + pRoamInfo->pbFrames, + pRoamInfo->frameType); + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eCSR_ROAM_TSM_IE_IND: + hdd_indicateTsmIe(pAdapter, pRoamInfo->tsmIe.tsid, + pRoamInfo->tsmIe.state, pRoamInfo->tsmIe.msmt_interval); + break; + + case eCSR_ROAM_CCKM_PREAUTH_NOTIFY: + { + if (eCSR_AUTH_TYPE_CCKM_WPA == pHddStaCtx->conn_info.authType || + eCSR_AUTH_TYPE_CCKM_RSN == pHddStaCtx->conn_info.authType) + { + hdd_indicateCckmPreAuth(pAdapter, pRoamInfo); + } + break; + } + + case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND: + { + hdd_indicateEseAdjApRepInd(pAdapter, pRoamInfo); + break; + } + + case eCSR_ROAM_ESE_BCN_REPORT_IND: + { + hdd_indicateEseBcnReportInd(pAdapter, pRoamInfo); + break; + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eCSR_ROAM_UPDATE_MAX_RATE_IND: + { + pAdapter->maxRateFlags = roamResult; + break; + } + case eCSR_ROAM_UPDATE_SCAN_RESULT: + if (pRoamInfo && pRoamInfo->pBssDesc) { + bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter, + pRoamInfo->pBssDesc); + if (bss_status) + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) || defined(WITH_BACKPORTS) + (WLAN_HDD_GET_CTX(pAdapter))->wiphy, +#endif + bss_status); + else + hddLog(LOG1, FL("UPDATE_SCAN_RESULT returned NULL")); + } + break; + default: + break; + } + return( halStatus ); +} +eCsrAuthType hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4]) +{ + eCsrAuthType auth_type; + // is the auth type supported? + if ( memcmp(auth_suite , ccpRSNOui01, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN; + } else + if (memcmp(auth_suite , ccpRSNOui02, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN_PSK; + } else +#ifdef WLAN_FEATURE_VOWIFI_11R + if (memcmp(auth_suite , ccpRSNOui04, 4) == 0) + { + // Check for 11r FT Authentication with PSK + auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK; + } else + if (memcmp(auth_suite , ccpRSNOui03, 4) == 0) + { + // Check for 11R FT Authentication with 802.1X + auth_type = eCSR_AUTH_TYPE_FT_RSN; + } else +#endif +#ifdef FEATURE_WLAN_ESE + if (memcmp(auth_suite , ccpRSNOui06, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_CCKM_RSN; + } else +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + if (memcmp(auth_suite , ccpRSNOui07, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256; + } else + if (memcmp(auth_suite , ccpRSNOui08, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256; + } else +#endif + { + auth_type = eCSR_AUTH_TYPE_UNKNOWN; + } + return auth_type; +} + +eCsrAuthType +hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4]) +{ + eCsrAuthType auth_type; + // is the auth type supported? + if ( memcmp(auth_suite , ccpWpaOui01, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_WPA; + } else + if (memcmp(auth_suite , ccpWpaOui02, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_WPA_PSK; + } else +#ifdef FEATURE_WLAN_ESE + if (memcmp(auth_suite , ccpWpaOui06, 4) == 0) + { + auth_type = eCSR_AUTH_TYPE_CCKM_WPA; + } else +#endif /* FEATURE_WLAN_ESE */ + { + auth_type = eCSR_AUTH_TYPE_UNKNOWN; + } + hddLog(LOG1, FL("auth_type: %d"), auth_type); + return auth_type; +} + +eCsrEncryptionType +hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4]) +{ + eCsrEncryptionType cipher_type; + // is the cipher type supported? + if ( memcmp(cipher_suite , ccpRSNOui04, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_AES; + } + else if (memcmp(cipher_suite , ccpRSNOui02, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_TKIP; + } + else if (memcmp(cipher_suite , ccpRSNOui00, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_NONE; + } + else if (memcmp(cipher_suite , ccpRSNOui01, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + else if (memcmp(cipher_suite , ccpRSNOui05, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + else + { + cipher_type = eCSR_ENCRYPT_TYPE_FAILED; + } + hddLog(LOG1, FL("cipher_type: %d"), cipher_type); + return cipher_type; +} +/* To find if the MAC address is NULL */ +static tANI_U8 hdd_IsMACAddrNULL (tANI_U8 *macAddr, tANI_U8 length) +{ + int i; + for (i = 0; i < length; i++) + { + if (0x00 != (macAddr[i])) + { + return FALSE; + } + } + return TRUE; +} /****** end hdd_IsMACAddrNULL() ******/ + +eCsrEncryptionType +hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4]) +{ + eCsrEncryptionType cipher_type; + // is the cipher type supported? + if ( memcmp(cipher_suite , ccpWpaOui04, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_AES; + } else + if (memcmp(cipher_suite , ccpWpaOui02, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_TKIP; + } else + if (memcmp(cipher_suite , ccpWpaOui00, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_NONE; + } else + if (memcmp(cipher_suite , ccpWpaOui01, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } else + if (memcmp(cipher_suite , ccpWpaOui05, 4) == 0) + { + cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } else + { + cipher_type = eCSR_ENCRYPT_TYPE_FAILED; + } + hddLog(LOG1, FL("cipher_type: %d"), cipher_type); + return cipher_type; +} + +static tANI_S32 hdd_ProcessGENIE(hdd_adapter_t *pAdapter, + struct ether_addr *pBssid, + eCsrEncryptionType *pEncryptType, + eCsrEncryptionType *mcEncryptType, + eCsrAuthType *pAuthType, +#ifdef WLAN_FEATURE_11W + u_int8_t *pMfpRequired, + u_int8_t *pMfpCapable, +#endif + u_int16_t gen_ie_len, + u_int8_t *gen_ie) +{ + tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + eHalStatus result; + tDot11fIERSN dot11RSNIE; + tDot11fIEWPA dot11WPAIE; + tANI_U32 i; + tANI_U8 *pRsnIe; + tANI_U16 RSNIeLen; + tPmkidCacheInfo PMKIDCache[4]; // Local transfer memory + v_BOOL_t updatePMKCache = FALSE; + + /* Clear struct of tDot11fIERSN and tDot11fIEWPA specifically setting present + flag to 0 */ + memset( &dot11WPAIE, 0 , sizeof(tDot11fIEWPA) ); + memset( &dot11RSNIE, 0 , sizeof(tDot11fIERSN) ); + + // Type check + if ( gen_ie[0] == DOT11F_EID_RSN) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) ) + { + hddLog(LOGE, "%s: Invalid DOT11F RSN IE length :%d\n", + __func__, gen_ie_len); + return -EINVAL; + } + // Skip past the EID byte and length byte + pRsnIe = gen_ie + 2; + RSNIeLen = gen_ie_len - 2; + // Unpack the RSN IE + dot11fUnpackIeRSN((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11RSNIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"), + __func__, dot11RSNIE.pwise_cipher_suite_count ); + hddLog(LOG1, FL("%s: authentication suite count: %d"), + __func__, dot11RSNIE.akm_suite_count); + /*Here we have followed the apple base code, + but probably I suspect we can do something different*/ + //dot11RSNIE.akm_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]); + //dot11RSNIE.pwise_cipher_suite_count + *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]); + //dot11RSNIE.gp_cipher_suite_count + *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite); +#ifdef WLAN_FEATURE_11W + *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1 ; + *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1 ; +#endif + // Set the PMKSA ID Cache for this interface + for (i=0; iether_addr_octet , 6)) + { + hddLog(LOGE, "%s: Invalid MAC adrr", __func__); + break; + } + updatePMKCache = TRUE; + // For right now, I assume setASSOCIATE() has passed in the bssid. + vos_mem_copy(PMKIDCache[i].BSSID, + pBssid, ETHER_ADDR_LEN); + vos_mem_copy(PMKIDCache[i].PMKID, + dot11RSNIE.pmkid[i], + CSR_RSN_PMKID_SIZE); + } + + if (updatePMKCache) + { + // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache + hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with cache entry %d."), + __func__, i ); + // Finally set the PMKSA ID Cache in CSR + result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId, + PMKIDCache, + dot11RSNIE.pmkid_count, + FALSE); + } + } + else if (gen_ie[0] == DOT11F_EID_WPA) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) + { + hddLog(LOGE, "%s: Invalid DOT11F WPA IE length :%d\n", + __func__, gen_ie_len); + return -EINVAL; + } + // Skip past the EID byte and length byte - and four byte WiFi OUI + pRsnIe = gen_ie + 2 + 4; + RSNIeLen = gen_ie_len - (2 + 4); + // Unpack the WPA IE + dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11WPAIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"), + __func__, dot11WPAIE.unicast_cipher_count ); + hddLog(LOG1, FL("%s: WPA authentication suite count: %d"), + __func__, dot11WPAIE.auth_suite_count); + //dot11WPAIE.auth_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]); + //dot11WPAIE.unicast_cipher_count + *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]); + //dot11WPAIE.unicast_cipher_count + *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher); + } + else + { + hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]); + return -EINVAL; + } + return 0; +} +int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + v_U32_t status = 0; + eCsrEncryptionType RSNEncryptType; + eCsrEncryptionType mcRSNEncryptType; +#ifdef WLAN_FEATURE_11W + u_int8_t RSNMfpRequired = 0; + u_int8_t RSNMfpCapable = 0; +#endif + struct ether_addr bSsid; // MAC address of assoc peer + // MAC address of assoc peer + // But, this routine is only called when we are NOT associated. + vos_mem_copy(bSsid.ether_addr_octet, + pWextState->roamProfile.BSSIDs.bssid, + sizeof(bSsid.ether_addr_octet)); + if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) + { + //continue + } + else + { + return 0; + } + // The actual processing may eventually be more extensive than this. + // Right now, just consume any PMKIDs that are sent in by the app. + status = hdd_ProcessGENIE(pAdapter, + &bSsid, // MAC address of assoc peer + &RSNEncryptType, + &mcRSNEncryptType, + RSNAuthType, +#ifdef WLAN_FEATURE_11W + &RSNMfpRequired, + &RSNMfpCapable, +#endif + pWextState->WPARSNIE[1]+2, + pWextState->WPARSNIE); + if (status == 0) + { + // Now copy over all the security attributes you have parsed out + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + + pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; // Use the cipher type in the RSN IE + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = mcRSNEncryptType; + + if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && + ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) || + (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) + { + /*For wpa none supplicant sends the WPA IE with unicast cipher as + eCSR_ENCRYPT_TYPE_NONE ,where as the multicast cipher as + either AES/TKIP based on group cipher configuration + mentioned in the wpa_supplicant.conf.*/ + + /*Set the unicast cipher same as multicast cipher*/ + pWextState->roamProfile.EncryptionType.encryptionType[0] + = mcRSNEncryptType; + } + +#ifdef WLAN_FEATURE_11W + hddLog( LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"), + RSNMfpRequired, RSNMfpCapable); + pWextState->roamProfile.MFPRequired = RSNMfpRequired; + pWextState->roamProfile.MFPCapable = RSNMfpCapable; +#endif + hddLog( LOG1, + FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"), + *RSNAuthType, RSNEncryptType, mcRSNEncryptType); + } + return 0; +} +int hdd_set_csr_auth_type ( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + ENTER(); + + pRoamProfile->AuthType.numEntries = 1; + hddLog( LOG1, "%s: pHddStaCtx->conn_info.authType = %d", __func__, pHddStaCtx->conn_info.authType); + + switch( pHddStaCtx->conn_info.authType) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: + case eCSR_AUTH_TYPE_CCKM_RSN: +#endif + if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) { + + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM ; + } else + if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) { + +#ifdef FEATURE_WLAN_ESE + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X)) { + hddLog( LOG1, "%s: set authType to CCKM WPA. AKM also 802.1X.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA; + } else + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA)) { + hddLog( LOG1, "%s: Last chance to set authType to CCKM WPA.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA; + } else +#endif + if((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA; + } else + if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) + == IW_AUTH_KEY_MGMT_PSK) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_PSK; + } else { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_NONE; + } + } + if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) { +#ifdef FEATURE_WLAN_ESE + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X)) { + hddLog( LOG1, "%s: set authType to CCKM RSN. AKM also 802.1X.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN; + } else + if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN)) { + hddLog( LOG1, "%s: Last chance to set authType to CCKM RSN.", __func__); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN; + } else +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X)) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN; + }else + if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK) && + ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) + == IW_AUTH_KEY_MGMT_PSK)) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN_PSK; + } else +#endif + +#ifdef WLAN_FEATURE_11W + if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK_SHA256; + } else + if (RSNAuthType == eCSR_AUTH_TYPE_RSN_8021X_SHA256) { + pRoamProfile->AuthType.authType[0] = + eCSR_AUTH_TYPE_RSN_8021X_SHA256; + } else +#endif + + if( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) + == IW_AUTH_KEY_MGMT_802_1X) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN; + } else + if ( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK) + == IW_AUTH_KEY_MGMT_PSK) { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK; + } else { + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN; + } + } + break; + + case eCSR_AUTH_TYPE_SHARED_KEY: + + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; + break; + default: + +#ifdef FEATURE_WLAN_ESE + hddLog( LOG1, "%s: In default, unknown auth type.", __func__); +#endif /* FEATURE_WLAN_ESE */ + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN; + break; + } + + hddLog( LOG1, "%s Set roam Authtype to %d", + __func__, pWextState->roamProfile.AuthType.authType[0]); + + EXIT(); + return 0; +} + +/** + * hdd_rx_fwd_eapol() - forward cached eapol frames + * @vosContext : pointer to vos global context + * @pVosPacket: pointer to vos packet + * + * Return: None + * + */ +void hdd_assoc_registerFwdEapolCB(void *pContext) +{ + WLANTL_RegisterFwdEapol(pContext, hdd_rx_fwd_eapol); +} + +/**--------------------------------------------------------------------------- + + \brief __iw_set_essid() - + This function sets the ssid received from wpa_supplicant + to the CSR roam profile. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +int __iw_set_essid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + v_U32_t status = 0; + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + v_U32_t roamId; + tCsrRoamProfile *pRoamProfile; + eCsrAuthType RSNAuthType; + tHalHandle hHal; + hdd_station_ctx_t *pHddStaCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + if(pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s :Counter measure is in progress", __func__); + return -EBUSY; + } + if( SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length ) + return -EINVAL; + pRoamProfile = &pWextState->roamProfile; + + /*Try disconnecting if already in connected state*/ + status = wlan_hdd_try_disconnect(pAdapter); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing" + " connection")); + return -EALREADY; + } + /** wpa_supplicant 0.8.x, wext driver uses */ + /** when cfg80211 defined, wpa_supplicant wext driver uses + zero-length, null-string ssid for force disconnection. + after disconnection (if previously connected) and cleaning ssid, + driver MUST return success */ + if ( 0 == wrqu->essid.length ) { + return 0; + } + + status = hdd_wmm_get_uapsd_mask(pAdapter, + &pWextState->roamProfile.uapsd_mask); + if (VOS_STATUS_SUCCESS != status) + { + pWextState->roamProfile.uapsd_mask = 0; + } + pWextState->roamProfile.SSIDs.numOfSSIDs = 1; + + pWextState->roamProfile.SSIDs.SSIDList->SSID.length = wrqu->essid.length; + + vos_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId, sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId)); + vos_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId), extra, wrqu->essid.length); + if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion || + IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion ) { + + //set gen ie + hdd_SetGENIEToCsr(pAdapter, &RSNAuthType); + + //set auth + hdd_set_csr_auth_type(pAdapter, RSNAuthType); + } +#ifdef FEATURE_WLAN_WAPI + hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__); + if (pAdapter->wapi_info.nWapiMode) + { + switch (pAdapter->wapi_info.wapiAuthMode) + { + case WAPI_AUTH_MODE_PSK: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__, pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.numEntries = 1; + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK; + break; + } + case WAPI_AUTH_MODE_CERT: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__, pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.numEntries = 1; + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + break; + } + } // End of switch + if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK || + pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) + { + hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__); + pRoamProfile->EncryptionType.numEntries = 1; + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + pRoamProfile->mcEncryptionType.numEntries = 1; + pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + } + } +#endif /* FEATURE_WLAN_WAPI */ + /* if previous genIE is not NULL, update AssocIE */ + if (0 != pWextState->genIE.length) + { + memset( &pWextState->assocAddIE, 0, sizeof(pWextState->assocAddIE) ); + memcpy( pWextState->assocAddIE.addIEdata, pWextState->genIE.addIEdata, + pWextState->genIE.length); + pWextState->assocAddIE.length = pWextState->genIE.length; + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + + /* clear previous genIE after use it */ + memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) ); + } + + /* assumes it is not WPS Association by default, except when pAddIEAssoc has WPS IE */ + pWextState->roamProfile.bWPSAssociation = FALSE; + + if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc, + pWextState->roamProfile.nAddIEAssocLength)) + pWextState->roamProfile.bWPSAssociation = TRUE; + + + // Disable auto BMPS entry by PMC until DHCP is done + sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), TRUE); + + pWextState->roamProfile.csrPersona = pAdapter->device_mode; + (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE; + + if ( eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType ) + { + hdd_select_cbmode(pAdapter, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->AdHocChannel5G); + } + /* + * Change conn_state to connecting before sme_RoamConnect(), + * because sme_RoamConnect() has a direct path to call + * hdd_smeRoamCallback(), which will change the conn_state + * If direct path, conn_state will be accordingly changed + * to NotConnected or Associated by either + * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() + * in sme_RoamCallback() + * if sme_RomConnect is to be queued, + * Connecting state will remain until it is completed. + * + * If connection state is not changed, + * connection state will remain in eConnectionState_NotConnected state. + * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true + * if conn state is eConnectionState_NotConnected. + * If "hddDisconInProgress" is set to true then cfg80211 layer is not + * informed of connect result indication which is an issue. + */ + if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Set HDD connState to eConnectionState_Connecting")); + hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + eConnectionState_Connecting); + } + status = sme_RoamConnect( hHal,pAdapter->sessionId, + &(pWextState->roamProfile), &roamId); + + if ((eHAL_STATUS_SUCCESS != status) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"), + pAdapter->sessionId, status); + /* change back to NotAssociated */ + hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + eConnectionState_NotConnected); + } + pRoamProfile->ChannelInfo.ChannelList = NULL; + pRoamProfile->ChannelInfo.numOfChannels = 0; + + EXIT(); + return status; +} + +int iw_set_essid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_essid(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_get_essid() - + This function returns the essid to the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int __iw_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *wextBuf; + hdd_station_ctx_t *pHddStaCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == wextBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: wextBuf is NULL",__func__); + return -EINVAL; + } + + if((pHddStaCtx->conn_info.connState == eConnectionState_Associated && + wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) || + ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected || + pHddStaCtx->conn_info.connState == eConnectionState_IbssDisconnected) && + wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) + { + dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length; + memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId, dwrq->length); + dwrq->flags = 1; + } else { + memset(extra, 0, dwrq->length); + dwrq->length = 0; + dwrq->flags = 0; + } + EXIT(); + return 0; +} + +int iw_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_essid(dev, info, dwrq, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +/**--------------------------------------------------------------------------- + + \brief __iw_set_auth() - + This function sets the auth type received from the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int __iw_set_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *pWextState; + hdd_station_ctx_t *pHddStaCtx; + tCsrRoamProfile *pRoamProfile; + eCsrEncryptionType mcEncryptionType; + eCsrEncryptionType ucEncryptionType; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + pRoamProfile = &pWextState->roamProfile; + + switch(wrqu->param.flags & IW_AUTH_INDEX) + { + case IW_AUTH_WPA_VERSION: + + pWextState->wpaVersion = wrqu->param.value; + + break; + + case IW_AUTH_CIPHER_PAIRWISE: + { + if(wrqu->param.value & IW_AUTH_CIPHER_NONE) { + ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + } + else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) { + ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP; + } + else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) { + ucEncryptionType = eCSR_ENCRYPT_TYPE_AES; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) { + + if( (IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) ) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) ) + /*Dynamic WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40; + else + /*Static WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104) { + + if( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) ) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + /*Dynamic WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104; + else + /*Static WEP key*/ + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + + } + else { + + hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER", + __func__, wrqu->param.value); + return -EINVAL; + } + + pRoamProfile->EncryptionType.numEntries = 1; + pRoamProfile->EncryptionType.encryptionType[0] = ucEncryptionType; + } + break; + case IW_AUTH_CIPHER_GROUP: + { + if(wrqu->param.value & IW_AUTH_CIPHER_NONE) { + mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) { + mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) { + mcEncryptionType = eCSR_ENCRYPT_TYPE_AES; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) { + + if( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X )) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40; + + else + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + + else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104) + { + /*Dynamic WEP keys won't work with shared keys*/ + if( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + { + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104; + } + else + { + mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + } + else { + + hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER", + __func__, wrqu->param.value); + return -EINVAL; + } + + pRoamProfile->mcEncryptionType.numEntries = 1; + pRoamProfile->mcEncryptionType.encryptionType[0] = mcEncryptionType; + } + break; + + case IW_AUTH_80211_AUTH_ALG: + { + /*Save the auth algo here and set auth type to SME Roam profile + in the iw_set_ap_address*/ + if( wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM) + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + else if(wrqu->param.value & IW_AUTH_ALG_SHARED_KEY) + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY; + + else if(wrqu->param.value & IW_AUTH_ALG_LEAP) + /*Not supported*/ + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pWextState->roamProfile.AuthType.authType[0] = pHddStaCtx->conn_info.authType; + } + break; + + case IW_AUTH_KEY_MGMT: + { +#ifdef FEATURE_WLAN_ESE +#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */ + /*Check for CCKM AKM type */ + if ( wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: CCKM AKM Set %d", + __func__, wrqu->param.value); + /* Set the CCKM bit in authKeyMgmt */ + /* Right now, this breaks all ref to authKeyMgmt because our + * code doesn't realize it is a "bitfield" + */ + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM; + /*Set the key management to 802.1X*/ + //pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; + pWextState->isESEConnection = eANI_BOOLEAN_TRUE; + //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA. + pWextState->collectedAuthType = eCSR_AUTH_TYPE_CCKM_RSN; + } else if ( wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) { + /*Save the key management*/ + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK; + //pWextState->authKeyMgmt = wrqu->param.value; + //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA. + pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN; + } else if (!( wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) { + pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE; //eCSR_AUTH_TYPE_WPA_NONE + /*Save the key management anyway*/ + pWextState->authKeyMgmt = wrqu->param.value; + } else { // It must be IW_AUTH_KEY_MGMT_802_1X + /*Save the key management*/ + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X; + //pWextState->authKeyMgmt = wrqu->param.value; + //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA. + pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN; + } +#else + /*Save the key management*/ + pWextState->authKeyMgmt = wrqu->param.value; +#endif /* FEATURE_WLAN_ESE */ + } + break; + + case IW_AUTH_TKIP_COUNTERMEASURES: + { + if(wrqu->param.value) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure started %d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED; + } + else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure stopped=%d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED; + } + } + break; + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_WPA_ENABLED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_ROAMING_CONTROL: + case IW_AUTH_PRIVACY_INVOKED: + + default: + + hddLog(LOGW, "%s called with unsupported auth type %d", __func__, + wrqu->param.flags & IW_AUTH_INDEX); + break; + } + + EXIT(); + return 0; +} + +int iw_set_auth(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_auth(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_get_auth() - + This function returns the auth type to the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int __iw_get_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + hdd_adapter_t* pAdapter; + hdd_wext_state_t *pWextState; + tCsrRoamProfile *pRoamProfile; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + pRoamProfile = &pWextState->roamProfile; + + switch(pRoamProfile->negotiatedAuthType) + { + case eCSR_AUTH_TYPE_WPA_NONE: + wrqu->param.flags = IW_AUTH_WPA_VERSION; + wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED; + break; + case eCSR_AUTH_TYPE_WPA: + wrqu->param.flags = IW_AUTH_WPA_VERSION; + wrqu->param.value = IW_AUTH_WPA_VERSION_WPA; + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: +#endif + case eCSR_AUTH_TYPE_RSN: + wrqu->param.flags = IW_AUTH_WPA_VERSION; + wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2; + break; + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + wrqu->param.value = IW_AUTH_ALG_SHARED_KEY; + break; + case eCSR_AUTH_TYPE_UNKNOWN: + hddLog(LOG1,"%s called with unknown auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + hddLog(LOG1,"%s called with WPA PSK auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + return -EIO; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN_PSK: +#endif + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + hddLog(LOG1,"%s called with RSN PSK auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + return -EIO; + default: + hddLog(LOGE,"%s called with unknown auth type", __func__); + wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM; + return -EIO; + } + if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) + { + switch(pRoamProfile->negotiatedUCEncryptionType) + { + case eCSR_ENCRYPT_TYPE_NONE: + wrqu->param.value = IW_AUTH_CIPHER_NONE; + break; + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP40; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + wrqu->param.value = IW_AUTH_CIPHER_TKIP; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP104; + break; + case eCSR_ENCRYPT_TYPE_AES: + wrqu->param.value = IW_AUTH_CIPHER_CCMP; + break; + default: + hddLog(LOG1, "%s called with unknown auth type %d ", + __func__, pRoamProfile->negotiatedUCEncryptionType); + return -EIO; + } + } + + if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) + { + switch(pRoamProfile->negotiatedMCEncryptionType) + { + case eCSR_ENCRYPT_TYPE_NONE: + wrqu->param.value = IW_AUTH_CIPHER_NONE; + break; + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP40; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + wrqu->param.value = IW_AUTH_CIPHER_TKIP; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + wrqu->param.value = IW_AUTH_CIPHER_WEP104; + break; + case eCSR_ENCRYPT_TYPE_AES: + wrqu->param.value = IW_AUTH_CIPHER_CCMP; + break; + default: + hddLog(LOG1, "%s called with unknown auth type %d ", + __func__, pRoamProfile->negotiatedMCEncryptionType); + return -EIO; + } + } + + hddLog(LOG1, "%s called with auth type %d", + __func__, pRoamProfile->AuthType.authType[0]); + EXIT(); + return 0; +} + +int iw_get_auth(struct net_device *dev,struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_auth(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_set_ap_address() - + This function calls the sme_RoamConnect function to associate + to the AP with the specified BSSID received from the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int __iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_station_ctx_t *pHddStaCtx; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + v_U8_t *pMacAddress = NULL; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pHddStaCtx is NULL", __func__); + return -EINVAL; + } + + pMacAddress = (v_U8_t*) wrqu->ap_addr.sa_data; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s "MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pMacAddress)); + vos_mem_copy( pHddStaCtx->conn_info.bssId, pMacAddress, sizeof( tCsrBssid )); + + EXIT(); + return 0; +} + +int iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_ap_address(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_get_ap_address() - + This function returns the BSSID to the wpa_supplicant + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int __iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_station_ctx_t *pHddStaCtx; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: pHddStaCtx is NULL", __func__); + return -EINVAL; + } + + if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) || + (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)) + { + memcpy(wrqu->ap_addr.sa_data,pHddStaCtx->conn_info.bssId,ETH_ALEN); + } + else + { + memset(wrqu->ap_addr.sa_data,0,sizeof(wrqu->ap_addr.sa_data)); + } + EXIT(); + return 0; +} + +int iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_ap_address(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef WLAN_FEATURE_11W +/**--------------------------------------------------------------------------- + + \brief hdd_indicateUnprotMgmtFrame - + This function forwards the unprotected management frame to the supplicant + \param - pAdapter - Pointer to HDD adapter + - nFrameLength - Length of the unprotected frame being passed + - pbFrames - Pointer to the frame buffer + - frameType - 802.11 frame type + \return - nothing + + --------------------------------------------------------------------------*/ +void hdd_indicateUnprotMgmtFrame( hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ) +{ + tANI_U8 type = 0; + tANI_U8 subType = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Frame Type = %d Frame Length = %d", + __func__, frameType, nFrameLength); + + /* Sanity Checks */ + if (NULL == pAdapter) + { + hddLog( LOGE, FL("pAdapter is NULL")); + return; + } + + if (NULL == pAdapter->dev) + { + hddLog( LOGE, FL("pAdapter->dev is NULL")); + return; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog( LOGE, FL("pAdapter has invalid magic")); + return; + } + + if( !nFrameLength ) + { + hddLog( LOGE, FL("Frame Length is Invalid ZERO")); + return; + } + + if (NULL == pbFrames) { + hddLog( LOGE, FL("pbFrames is NULL")); + return; + } + + type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]); + subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]); + + /* Get pAdapter from Destination mac address of the frame */ + if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames, nFrameLength); +#else + cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames, nFrameLength); +#endif + pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++; + } + else if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DEAUTH) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames, nFrameLength); +#else + cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames, nFrameLength); +#endif + pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++; + } + else + { + hddLog( LOGE, FL("Frame type %d and subtype %d are not valid"), type, subType); + return; + } +} +#endif + +#if defined (FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void hdd_indicateTsmIe(hdd_adapter_t *pAdapter, tANI_U8 tid, + tANI_U8 state, + tANI_U16 measInterval ) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + int nBytes = 0; + + if (NULL == pAdapter) + return; + + // create the event + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + hddLog(VOS_TRACE_LEVEL_INFO, "TSM Ind tid(%d) state(%d) MeasInt(%d)", + tid, state, measInterval); + + nBytes = snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d",tid,state,measInterval); + + wrqu.data.pointer = buf; + wrqu.data.length = nBytes; + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + +void hdd_indicateCckmPreAuth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + char *pos = buf; + int nBytes = 0, freeBytes = IW_CUSTOM_MAX; + + if ((NULL == pAdapter) || (NULL == pRoamInfo)) + return; + + // create the event + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */ + hddLog(VOS_TRACE_LEVEL_INFO, "CCXPREAUTHNOTIFY=%02x:%02x:%02x:%02x:%02x:%02x %u:%u", + pRoamInfo->bssid[0], pRoamInfo->bssid[1], pRoamInfo->bssid[2], + pRoamInfo->bssid[3], pRoamInfo->bssid[4], pRoamInfo->bssid[5], + pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]); + + nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY="); + pos += nBytes; + freeBytes -= nBytes; + + vos_mem_copy(pos, pRoamInfo->bssid, WNI_CFG_BSSID_LEN); + pos += WNI_CFG_BSSID_LEN; + freeBytes -= WNI_CFG_BSSID_LEN; + + nBytes = snprintf(pos, freeBytes, " %u:%u", pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]); + freeBytes -= nBytes; + + wrqu.data.pointer = buf; + wrqu.data.length = (IW_CUSTOM_MAX - freeBytes); + + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + +void hdd_indicateEseAdjApRepInd(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + int nBytes = 0; + + if ((NULL == pAdapter) || (NULL == pRoamInfo)) + return; + + // create the event + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + hddLog(VOS_TRACE_LEVEL_INFO, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay); + + nBytes = snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay); + + wrqu.data.pointer = buf; + wrqu.data.length = nBytes; + + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + +void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter, + const tANI_U16 measurementToken, + const tANI_BOOLEAN flag, + const tANI_U8 numBss) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX]; + char *pos = buf; + int nBytes = 0, freeBytes = IW_CUSTOM_MAX; + + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("CCXBCNREP=%d %d %d"), measurementToken, flag, + numBss); + + nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken, + flag, numBss); + + wrqu.data.pointer = buf; + wrqu.data.length = nBytes; + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + + +static void hdd_indicateEseBcnReportInd(const hdd_adapter_t *pAdapter, + const tCsrRoamInfo *pRoamInfo) +{ + union iwreq_data wrqu; + char buf[IW_CUSTOM_MAX + 1]; + char *pos = buf; + int nBytes = 0, freeBytes = IW_CUSTOM_MAX; + tANI_U8 i = 0, len = 0; + tANI_U8 tot_bcn_ieLen = 0; /* total size of the beacon report data */ + tANI_U8 lastSent = 0, sendBss = 0; + int bcnRepFieldSize = sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].bcnReportFields); + tANI_U8 ieLenByte = 1; + /* CCXBCNREP=meas_tokflagno_of_bsstot_bcn_ie_len = 18 bytes */ +#define ESEBCNREPHEADER_LEN (18) + + if ((NULL == pAdapter) || (NULL == pRoamInfo)) + return; + + /* Custom event can pass maximum of 256 bytes of data, + based on the IE len we need to identify how many BSS info can + be filled in to custom event data */ + /* + meas_tokflagno_of_bsstot_bcn_ie_len bcn_rep_data + bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces + CCXBCNREP=meas_tokflagno_of_bsstot_bcn_ie_len = 18 bytes + */ + + if ((pRoamInfo->pEseBcnReportRsp->flag >> 1) && (!pRoamInfo->pEseBcnReportRsp->numBss)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "Measurement Done but no scan results"); + /* If the measurement is none and no scan results found, + indicate the supplicant about measurement done */ + hdd_indicateEseBcnReportNoResults(pAdapter, + pRoamInfo->pEseBcnReportRsp->measurementToken, + pRoamInfo->pEseBcnReportRsp->flag, + pRoamInfo->pEseBcnReportRsp->numBss); + } + else + { + while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) + { + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buf, '\0', sizeof(buf)); + tot_bcn_ieLen = 0; + sendBss = 0; + pos = buf; + freeBytes = IW_CUSTOM_MAX; + + for (i = lastSent; i < pRoamInfo->pEseBcnReportRsp->numBss; i++) + { + len = bcnRepFieldSize + ieLenByte + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i].ieLen; + if ((len + tot_bcn_ieLen) > (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) + { + break; + } + tot_bcn_ieLen += len; + sendBss++; + hddLog(VOS_TRACE_LEVEL_INFO, "i(%d) sizeof bcnReportFields(%d)" + "IeLength(%d) Length of Ie(%d) totLen(%d)", + i, bcnRepFieldSize, 1, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i].ieLen, + tot_bcn_ieLen); + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Sending %d BSS Info", sendBss); + hddLog(VOS_TRACE_LEVEL_INFO, "CCXBCNREP=%d %d %d %d", + pRoamInfo->pEseBcnReportRsp->measurementToken, pRoamInfo->pEseBcnReportRsp->flag, + sendBss, tot_bcn_ieLen); + + nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ", + pRoamInfo->pEseBcnReportRsp->measurementToken, pRoamInfo->pEseBcnReportRsp->flag, + sendBss); + pos += nBytes; + freeBytes -= nBytes; + + /* Copy total Beacon report data length */ + vos_mem_copy(pos, (char*)&tot_bcn_ieLen, sizeof(tot_bcn_ieLen)); + pos += sizeof(tot_bcn_ieLen); + freeBytes -= sizeof(tot_bcn_ieLen); + + for (i = 0; i < sendBss; i++) + { + hddLog(VOS_TRACE_LEVEL_INFO, "ChanNum(%d) Spare(%d) MeasDuration(%d)" + " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)" + " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)" + " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)", + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.ChanNum, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Spare, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.MeasDuration, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.PhyType, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.RecvSigPower, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.ParentTsf, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.TargetTsf[0], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.TargetTsf[1], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.BcnInterval, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.CapabilityInfo, + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[0], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[1], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[2], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[3], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[4], + pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields.Bssid[5]); + + /* bcn report fields are copied */ + len = sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields); + vos_mem_copy(pos, (char*)&pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].bcnReportFields, len); + pos += len; + freeBytes -= len; + + /* Add 1 byte of ie len */ + len = pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].ieLen; + vos_mem_copy(pos, (char*)&len, sizeof(len)); + pos += sizeof(len); + freeBytes -= sizeof(len); + + /* copy IE from scan results */ + vos_mem_copy(pos, (char*)pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[i+lastSent].pBuf, len); + pos += len; + freeBytes -= len; + } + + wrqu.data.pointer = buf; + wrqu.data.length = strlen(buf); + + // send the event + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + lastSent += sendBss; + } + } +} + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c new file mode 100644 index 000000000000..7272ed0d9125 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg.c @@ -0,0 +1,6882 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 07/27/09 kanand Created module. + + ==========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +static void cbNotifySetRoamPrefer5GHz(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamPrefer5GHz((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nRoamPrefer5GHz); +} + +static void cbNotifySetImmediateRoamRssiDiff(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateImmediateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->nImmediateRoamRssiDiff); +} + +static void cbNotifySetRoamRssiDiff(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->RoamRssiDiff); +} + +static void cbNotifySetFastTransitionEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->isFastTransitionEnabled); +} + +static void cbNotifySetRoamIntraBand(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nRoamIntraBand); +} + +static void cbNotifySetWESMode(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->isWESModeEnabled); +} + +static void cbNotifySetRoamScanNProbes(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nProbes); +} + +static void cbNotifySetRoamScanHomeAwayTime(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nRoamScanHomeAwayTime, eANI_BOOLEAN_TRUE); +} +#endif + +#ifdef FEATURE_WLAN_OKC +static void cbNotifySetOkcFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated +} +#endif + +#ifdef FEATURE_WLAN_LFR +static void NotifyIsFastRoamIniFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled ); +} + +static void NotifyIsMAWCIniFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + /* at the point this routine is called, the value in the cfg_ini table has already been updated */ + sme_UpdateIsMAWCIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->MAWCEnabled ); +} +#endif + +#ifdef FEATURE_WLAN_ESE +static void cbNotifySetEseFeatureEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->isEseIniFeatureEnabled ); +} +#endif + +static void cbNotifySetFwRssiMonitoring(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_UpdateConfigFwRssiMonitoring((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->fEnableFwRssiMonitoring ); +} + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +static void cbNotifySetNeighborLookupRssiThreshold(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nNeighborLookupRssiThreshold ); +} + +static void cbNotifySetNeighborScanPeriod(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nNeighborScanPeriod ); +} + +static void cbNotifySetNeighborResultsRefreshPeriod(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod ); +} + +static void cbNotifySetEmptyScanRefreshPeriod(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nEmptyScanRefreshPeriod); +} + +static void cbNotifySetNeighborScanMinChanTime(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + // at the point this routine is called, the value in the cfg_ini table has already been updated + sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nNeighborScanMinChanTime); +} + +static void cbNotifySetNeighborScanMaxChanTime(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->nNeighborScanMaxChanTime); +} +#endif + +static void cbNotifySetEnableSSR(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateEnableSSR((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->enableSSR); +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +static void cbNotifyUpdateRoamScanOffloadEnabled(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->isRoamOffloadScanEnabled); + if (0 == pHddCtx->cfg_ini->isRoamOffloadScanEnabled) + { + pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled = 0; + sme_UpdateEnableFastRoamInConcurrency((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled ); + } +} + +static void cbNotifySetEnableFastRoamInConcurrency(hdd_context_t *pHddCtx, unsigned long NotifyId) +{ + sme_UpdateEnableFastRoamInConcurrency((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->bFastRoamInConIniFeatureEnabled ); +} + +#endif + +REG_TABLE_ENTRY g_registry_table[] = +{ + REG_VARIABLE( CFG_RTS_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, RTSThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RTS_THRESHOLD_DEFAULT, + CFG_RTS_THRESHOLD_MIN, + CFG_RTS_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_FRAG_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, FragmentationThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FRAG_THRESHOLD_DEFAULT, + CFG_FRAG_THRESHOLD_MIN, + CFG_FRAG_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_CALIBRATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, Calibration, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_CALIBRATION_DEFAULT, + CFG_CALIBRATION_MIN, + CFG_CALIBRATION_MAX ), + + REG_VARIABLE( CFG_CALIBRATION_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, CalibrationPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_CALIBRATION_PERIOD_DEFAULT, + CFG_CALIBRATION_PERIOD_MIN, + CFG_CALIBRATION_PERIOD_MAX ), + + REG_VARIABLE( CFG_OPERATING_CHANNEL_NAME, WLAN_PARAM_Integer, + hdd_config_t, OperatingChannel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OPERATING_CHANNEL_DEFAULT, + CFG_OPERATING_CHANNEL_MIN, + CFG_OPERATING_CHANNEL_MAX ), + + REG_VARIABLE( CFG_SHORT_SLOT_TIME_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, ShortSlotTimeEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SHORT_SLOT_TIME_ENABLED_DEFAULT, + CFG_SHORT_SLOT_TIME_ENABLED_MIN, + CFG_SHORT_SLOT_TIME_ENABLED_MAX ), + + REG_VARIABLE( CFG_11D_SUPPORT_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, Is11dSupportEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_11D_SUPPORT_ENABLED_DEFAULT, + CFG_11D_SUPPORT_ENABLED_MIN, + CFG_11D_SUPPORT_ENABLED_MAX ), + + REG_VARIABLE( CFG_11H_SUPPORT_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, Is11hSupportEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_11H_SUPPORT_ENABLED_DEFAULT, + CFG_11H_SUPPORT_ENABLED_MIN, + CFG_11H_SUPPORT_ENABLED_MAX ), + + REG_VARIABLE( CFG_ENFORCE_11D_CHANNELS_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnforce11dChannels, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENFORCE_11D_CHANNELS_DEFAULT, + CFG_ENFORCE_11D_CHANNELS_MIN, + CFG_ENFORCE_11D_CHANNELS_MAX ), + + REG_VARIABLE( CFG_COUNTRY_CODE_PRIORITY_NAME, WLAN_PARAM_Integer, + hdd_config_t, fSupplicantCountryCodeHasPriority, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_COUNTRY_CODE_PRIORITY_DEFAULT, + CFG_COUNTRY_CODE_PRIORITY_MIN, + CFG_COUNTRY_CODE_PRIORITY_MAX), + + REG_VARIABLE( CFG_ENFORCE_COUNTRY_CODE_MATCH_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnforceCountryCodeMatch, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENFORCE_COUNTRY_CODE_MATCH_DEFAULT, + CFG_ENFORCE_COUNTRY_CODE_MATCH_MIN, + CFG_ENFORCE_COUNTRY_CODE_MATCH_MAX ), + + REG_VARIABLE( CFG_ENFORCE_DEFAULT_DOMAIN_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnforceDefaultDomain, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENFORCE_DEFAULT_DOMAIN_DEFAULT, + CFG_ENFORCE_DEFAULT_DOMAIN_MIN, + CFG_ENFORCE_DEFAULT_DOMAIN_MAX ), + + REG_VARIABLE( CFG_GENERIC_ID1_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg1Id, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_ID1_DEFAULT, + CFG_GENERIC_ID1_MIN, + CFG_GENERIC_ID1_MAX ), + + REG_VARIABLE( CFG_GENERIC_ID2_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg2Id, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_ID2_DEFAULT, + CFG_GENERIC_ID2_MIN, + CFG_GENERIC_ID2_MAX ), + + REG_VARIABLE( CFG_GENERIC_ID3_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg3Id, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_ID3_DEFAULT, + CFG_GENERIC_ID3_MIN, + CFG_GENERIC_ID3_MAX ), + + REG_VARIABLE( CFG_GENERIC_ID4_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg4Id, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_ID4_DEFAULT, + CFG_GENERIC_ID4_MIN, + CFG_GENERIC_ID4_MAX ), + + REG_VARIABLE( CFG_GENERIC_ID5_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg5Id, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_ID5_DEFAULT, + CFG_GENERIC_ID5_MIN, + CFG_GENERIC_ID5_MAX ), + + REG_VARIABLE( CFG_GENERIC_VALUE1_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg1Value, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_VALUE1_DEFAULT, + CFG_GENERIC_VALUE1_MIN, + CFG_GENERIC_VALUE1_MAX ), + + REG_VARIABLE( CFG_GENERIC_VALUE2_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg2Value, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_VALUE2_DEFAULT, + CFG_GENERIC_VALUE2_MIN, + CFG_GENERIC_VALUE2_MAX ), + + REG_VARIABLE( CFG_GENERIC_VALUE3_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg3Value, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_VALUE3_DEFAULT, + CFG_GENERIC_VALUE3_MIN, + CFG_GENERIC_VALUE3_MAX ), + + REG_VARIABLE( CFG_GENERIC_VALUE4_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg4Value, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_VALUE4_DEFAULT, + CFG_GENERIC_VALUE4_MIN, + CFG_GENERIC_VALUE4_MAX ), + + REG_VARIABLE( CFG_GENERIC_VALUE5_NAME, WLAN_PARAM_Integer, + hdd_config_t, Cfg5Value, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GENERIC_VALUE5_DEFAULT, + CFG_GENERIC_VALUE5_MIN, + CFG_GENERIC_VALUE5_MAX ), + + REG_VARIABLE( CFG_HEARTBEAT_THRESH_24_NAME, WLAN_PARAM_Integer, + hdd_config_t, HeartbeatThresh24, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_HEARTBEAT_THRESH_24_DEFAULT, + CFG_HEARTBEAT_THRESH_24_MIN, + CFG_HEARTBEAT_THRESH_24_MAX ), + + REG_VARIABLE_STRING( CFG_POWER_USAGE_NAME, WLAN_PARAM_String, + hdd_config_t, PowerUsageControl, + VAR_FLAGS_OPTIONAL, + (void *)CFG_POWER_USAGE_DEFAULT ), + + REG_VARIABLE( CFG_ENABLE_SUSPEND_NAME, WLAN_PARAM_Integer, + hdd_config_t, nEnableSuspend, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SUSPEND_DEFAULT, + CFG_ENABLE_SUSPEND_MIN, + CFG_ENABLE_SUSPEND_MAX ), + + REG_VARIABLE( CFG_ENABLE_ENABLE_DRIVER_STOP_NAME, WLAN_PARAM_Integer, + hdd_config_t, nEnableDriverStop, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_ENABLE_DRIVER_STOP_DEFAULT, + CFG_ENABLE_ENABLE_DRIVER_STOP_MIN, + CFG_ENABLE_ENABLE_DRIVER_STOP_MAX ), + + REG_VARIABLE( CFG_ENABLE_IMPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsImpsEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_IMPS_DEFAULT, + CFG_ENABLE_IMPS_MIN, + CFG_ENABLE_IMPS_MAX ), + + REG_VARIABLE( CFG_SSR_PANIC_ON_FAILURE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsSsrPanicOnFailure, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SSR_PANIC_ON_FAILURE_DEFAULT, + CFG_SSR_PANIC_ON_FAILURE_MIN, + CFG_SSR_PANIC_ON_FAILURE_MAX), + + REG_VARIABLE( CFG_ENABLE_LOGP_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsLogpEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LOGP_DEFAULT, + CFG_ENABLE_LOGP_MIN, + CFG_ENABLE_LOGP_MAX ), + + REG_VARIABLE( CFG_IMPS_MINIMUM_SLEEP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImpsMinSleepTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMPS_MINIMUM_SLEEP_TIME_DEFAULT, + CFG_IMPS_MINIMUM_SLEEP_TIME_MIN, + CFG_IMPS_MINIMUM_SLEEP_TIME_MAX ), + + REG_VARIABLE( CFG_IMPS_MAXIMUM_SLEEP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImpsMaxSleepTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMPS_MAXIMUM_SLEEP_TIME_DEFAULT, + CFG_IMPS_MAXIMUM_SLEEP_TIME_MIN, + CFG_IMPS_MAXIMUM_SLEEP_TIME_MAX ), + + REG_VARIABLE( CFG_DEFER_SCAN_TIME_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, nDeferScanTimeInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DEFER_SCAN_TIME_INTERVAL_DEFAULT, + CFG_DEFER_SCAN_TIME_INTERVAL_MIN, + CFG_DEFER_SCAN_TIME_INTERVAL_MAX ), + + REG_VARIABLE( CFG_IMPS_MODERATE_SLEEP_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImpsModSleepTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMPS_MODERATE_SLEEP_TIME_DEFAULT, + CFG_IMPS_MODERATE_SLEEP_TIME_MIN, + CFG_IMPS_MODERATE_SLEEP_TIME_MAX ), + + REG_VARIABLE( CFG_ENABLE_BMPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsBmpsEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BMPS_DEFAULT, + CFG_ENABLE_BMPS_MIN, + CFG_ENABLE_BMPS_MAX ), + + REG_VARIABLE( CFG_BMPS_MINIMUM_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBmpsMinListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BMPS_MINIMUM_LI_DEFAULT, + CFG_BMPS_MINIMUM_LI_MIN, + CFG_BMPS_MINIMUM_LI_MAX ), + + REG_VARIABLE( CFG_BMPS_MAXIMUM_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBmpsMaxListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BMPS_MAXIMUM_LI_DEFAULT, + CFG_BMPS_MAXIMUM_LI_MIN, + CFG_BMPS_MAXIMUM_LI_MAX ), + + REG_VARIABLE( CFG_BMPS_MODERATE_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBmpsModListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BMPS_MODERATE_LI_DEFAULT, + CFG_BMPS_MODERATE_LI_MIN, + CFG_BMPS_MODERATE_LI_MAX ), + + REG_VARIABLE( CFG_ENABLE_AUTO_BMPS_TIMER_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsAutoBmpsTimerEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_AUTO_BMPS_TIMER_DEFAULT, + CFG_ENABLE_AUTO_BMPS_TIMER_MIN, + CFG_ENABLE_AUTO_BMPS_TIMER_MAX ), + + REG_VARIABLE( CFG_AUTO_BMPS_TIMER_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, nAutoBmpsTimerValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AUTO_BMPS_TIMER_VALUE_DEFAULT, + CFG_AUTO_BMPS_TIMER_VALUE_MIN, + CFG_AUTO_BMPS_TIMER_VALUE_MAX ), + + REG_VARIABLE( CFG_DOT11_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, dot11Mode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_DOT11_MODE_DEFAULT, + CFG_DOT11_MODE_MIN, + CFG_DOT11_MODE_MAX ), + + REG_VARIABLE( CFG_CHANNEL_BONDING_MODE_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, nChannelBondingMode24GHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_CHANNEL_BONDING_MODE_DEFAULT, + CFG_CHANNEL_BONDING_MODE_MIN, + CFG_CHANNEL_BONDING_MODE_MAX), + + REG_VARIABLE(CFG_OVERRIDE_HT40_20_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, override_ht20_40_24g, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OVERRIDE_HT40_20_24GHZ_DEFAULT, + CFG_OVERRIDE_HT40_20_24GHZ_MIN, + CFG_OVERRIDE_HT40_20_24GHZ_MAX), + + REG_VARIABLE( CFG_CHANNEL_BONDING_MODE_5GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, nChannelBondingMode5GHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_CHANNEL_BONDING_MODE_DEFAULT, + CFG_CHANNEL_BONDING_MODE_MIN, + CFG_CHANNEL_BONDING_MODE_MAX), + + REG_VARIABLE( CFG_MAX_RX_AMPDU_FACTOR_NAME, WLAN_PARAM_Integer, + hdd_config_t, MaxRxAmpduFactor, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_MAX_RX_AMPDU_FACTOR_DEFAULT, + CFG_MAX_RX_AMPDU_FACTOR_MIN, + CFG_MAX_RX_AMPDU_FACTOR_MAX), + + REG_VARIABLE( CFG_FIXED_RATE_NAME, WLAN_PARAM_Integer, + hdd_config_t, TxRate, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_FIXED_RATE_DEFAULT, + CFG_FIXED_RATE_MIN, + CFG_FIXED_RATE_MAX ), + + REG_VARIABLE( CFG_SHORT_GI_20MHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, ShortGI20MhzEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SHORT_GI_20MHZ_DEFAULT, + CFG_SHORT_GI_20MHZ_MIN, + CFG_SHORT_GI_20MHZ_MAX ), + + REG_VARIABLE( CFG_BLOCK_ACK_AUTO_SETUP_NAME, WLAN_PARAM_Integer, + hdd_config_t, BlockAckAutoSetup, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_BLOCK_ACK_AUTO_SETUP_DEFAULT, + CFG_BLOCK_ACK_AUTO_SETUP_MIN, + CFG_BLOCK_ACK_AUTO_SETUP_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_COUNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, ScanResultAgeCount, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_COUNT_DEFAULT, + CFG_SCAN_RESULT_AGE_COUNT_MIN, + CFG_SCAN_RESULT_AGE_COUNT_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_NCNPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeNCNPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_NCNPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_NCNPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_NCNPS_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_NCPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeNCPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_NCPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_NCPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_NCPS_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_CNPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeCNPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_CNPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_CNPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_CNPS_MAX ), + + REG_VARIABLE( CFG_SCAN_RESULT_AGE_TIME_CPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nScanAgeTimeCPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SCAN_RESULT_AGE_TIME_CPS_DEFAULT, + CFG_SCAN_RESULT_AGE_TIME_CPS_MIN, + CFG_SCAN_RESULT_AGE_TIME_CPS_MAX ), + + REG_VARIABLE( CFG_RSSI_CATEGORY_GAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRssiCatGap, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RSSI_CATEGORY_GAP_DEFAULT, + CFG_RSSI_CATEGORY_GAP_MIN, + CFG_RSSI_CATEGORY_GAP_MAX ), + + REG_VARIABLE( CFG_SHORT_PREAMBLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsShortPreamble, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SHORT_PREAMBLE_DEFAULT, + CFG_SHORT_PREAMBLE_MIN, + CFG_SHORT_PREAMBLE_MAX ), + + REG_VARIABLE( CFG_IBSS_AUTO_BSSID_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsAutoIbssBssid, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_AUTO_BSSID_DEFAULT, + CFG_IBSS_AUTO_BSSID_MIN, + CFG_IBSS_AUTO_BSSID_MAX ), + + REG_VARIABLE_STRING( CFG_IBSS_BSSID_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, IbssBssid, + VAR_FLAGS_OPTIONAL, + (void *)CFG_IBSS_BSSID_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF0_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[0], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF0_MAC_ADDR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF1_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[1], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF1_MAC_ADDR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF2_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[2], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF2_MAC_ADDR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_INTF3_MAC_ADDR_NAME, WLAN_PARAM_MacAddr, + hdd_config_t, intfMacAddr[3], + VAR_FLAGS_OPTIONAL, + (void *)CFG_INTF3_MAC_ADDR_DEFAULT ), + + REG_VARIABLE( CFG_AP_QOS_UAPSD_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, apUapsdEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_QOS_UAPSD_MODE_DEFAULT, + CFG_AP_QOS_UAPSD_MODE_MIN, + CFG_AP_QOS_UAPSD_MODE_MAX ), + + REG_VARIABLE_STRING( CFG_AP_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, apCntryCode, + VAR_FLAGS_OPTIONAL, + (void *)CFG_AP_COUNTRY_CODE_DEFAULT ), + + REG_VARIABLE( CFG_AP_ENABLE_RANDOM_BSSID_NAME, WLAN_PARAM_Integer, + hdd_config_t, apRandomBssidEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_ENABLE_RANDOM_BSSID_DEFAULT, + CFG_AP_ENABLE_RANDOM_BSSID_MIN, + CFG_AP_ENABLE_RANDOM_BSSID_MAX ), + + REG_VARIABLE( CFG_AP_ENABLE_PROTECTION_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, apProtEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_ENABLE_PROTECTION_MODE_DEFAULT, + CFG_AP_ENABLE_PROTECTION_MODE_MIN, + CFG_AP_ENABLE_PROTECTION_MODE_MAX ), + + REG_VARIABLE( CFG_AP_PROTECTION_MODE_NAME, WLAN_PARAM_HexInteger, + hdd_config_t, apProtection, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_PROTECTION_MODE_DEFAULT, + CFG_AP_PROTECTION_MODE_MIN, + CFG_AP_PROTECTION_MODE_MAX ), + + REG_VARIABLE( CFG_AP_OBSS_PROTECTION_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, apOBSSProtEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_OBSS_PROTECTION_MODE_DEFAULT, + CFG_AP_OBSS_PROTECTION_MODE_MIN, + CFG_AP_OBSS_PROTECTION_MODE_MAX ), + + REG_VARIABLE( CFG_AP_STA_SECURITY_SEPERATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, apDisableIntraBssFwd, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_STA_SECURITY_SEPERATION_DEFAULT, + CFG_AP_STA_SECURITY_SEPERATION_MIN, + CFG_AP_STA_SECURITY_SEPERATION_MAX ), + + REG_VARIABLE( CFG_FRAMES_PROCESSING_TH_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, MinFramesProcThres, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FRAMES_PROCESSING_TH_DEFAULT, + CFG_FRAMES_PROCESSING_TH_MIN, + CFG_FRAMES_PROCESSING_TH_MAX ), + + REG_VARIABLE(CFG_SAP_CHANNEL_SELECT_START_CHANNEL , WLAN_PARAM_Integer, + hdd_config_t, apStartChannelNum, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_DEFAULT, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MIN, + CFG_SAP_CHANNEL_SELECT_START_CHANNEL_MAX ), + + REG_VARIABLE(CFG_SAP_CHANNEL_SELECT_END_CHANNEL , WLAN_PARAM_Integer, + hdd_config_t, apEndChannelNum, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_DEFAULT, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MIN, + CFG_SAP_CHANNEL_SELECT_END_CHANNEL_MAX ), + + REG_VARIABLE(CFG_SAP_CHANNEL_SELECT_OPERATING_BAND , WLAN_PARAM_Integer, + hdd_config_t, apOperatingBand, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_DEFAULT, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MIN, + CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_MAX ), + + REG_VARIABLE(CFG_SAP_AUTO_CHANNEL_SELECTION_NAME , WLAN_PARAM_Integer, + hdd_config_t, apAutoChannelSelection, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_AUTO_CHANNEL_SELECTION_DEFAULT, + CFG_SAP_AUTO_CHANNEL_SELECTION_MIN, + CFG_SAP_AUTO_CHANNEL_SELECTION_MAX ), + + REG_VARIABLE(CFG_ENABLE_LTE_COEX , WLAN_PARAM_Integer, + hdd_config_t, enableLTECoex, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LTE_COEX_DEFAULT, + CFG_ENABLE_LTE_COEX_MIN, + CFG_ENABLE_LTE_COEX_MAX ), + + REG_VARIABLE( CFG_AP_KEEP_ALIVE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apKeepAlivePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_KEEP_ALIVE_PERIOD_DEFAULT, + CFG_AP_KEEP_ALIVE_PERIOD_MIN, + CFG_AP_KEEP_ALIVE_PERIOD_MAX), + + REG_VARIABLE( CFG_GO_KEEP_ALIVE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, goKeepAlivePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GO_KEEP_ALIVE_PERIOD_DEFAULT, + CFG_GO_KEEP_ALIVE_PERIOD_MIN, + CFG_GO_KEEP_ALIVE_PERIOD_MAX), + + REG_VARIABLE( CFG_AP_LINK_MONITOR_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apLinkMonitorPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_LINK_MONITOR_PERIOD_DEFAULT, + CFG_AP_LINK_MONITOR_PERIOD_MIN, + CFG_AP_LINK_MONITOR_PERIOD_MAX), + + REG_VARIABLE( CFG_GO_LINK_MONITOR_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, goLinkMonitorPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_GO_LINK_MONITOR_PERIOD_DEFAULT, + CFG_GO_LINK_MONITOR_PERIOD_MIN, + CFG_GO_LINK_MONITOR_PERIOD_MAX), + + REG_VARIABLE(CFG_DISABLE_PACKET_FILTER , WLAN_PARAM_Integer, + hdd_config_t, disablePacketFilter, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_PACKET_FILTER_DEFAULT, + CFG_DISABLE_PACKET_FILTER_MIN, + CFG_DISABLE_PACKET_FILTER_MAX ), + + REG_VARIABLE( CFG_BEACON_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBeaconInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_BEACON_INTERVAL_DEFAULT, + CFG_BEACON_INTERVAL_MIN, + CFG_BEACON_INTERVAL_MAX ), + + REG_VARIABLE( CFG_ENABLE_IDLE_SCAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, nEnableIdleScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_IDLE_SCAN_DEFAULT, + CFG_ENABLE_IDLE_SCAN_MIN, + CFG_ENABLE_IDLE_SCAN_MAX ), + + REG_VARIABLE( CFG_ROAMING_TIME_NAME , WLAN_PARAM_Integer, + hdd_config_t, nRoamingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAMING_TIME_DEFAULT, + CFG_ROAMING_TIME_MIN, + CFG_ROAMING_TIME_MAX ), + + REG_VARIABLE( CFG_VCC_RSSI_TRIGGER_NAME , WLAN_PARAM_Integer, + hdd_config_t, nVccRssiTrigger, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VCC_RSSI_TRIGGER_DEFAULT, + CFG_VCC_RSSI_TRIGGER_MIN, + CFG_VCC_RSSI_TRIGGER_MAX ), + + REG_VARIABLE( CFG_VCC_UL_MAC_LOSS_THRESH_NAME , WLAN_PARAM_Integer, + hdd_config_t, nVccUlMacLossThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VCC_UL_MAC_LOSS_THRESH_DEFAULT, + CFG_VCC_UL_MAC_LOSS_THRESH_MIN, + CFG_VCC_UL_MAC_LOSS_THRESH_MAX ), + + REG_VARIABLE( CFG_PASSIVE_MAX_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMaxChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_MIN, + CFG_PASSIVE_MAX_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_PASSIVE_MIN_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMinChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_MIN, + CFG_PASSIVE_MIN_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MAX_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMaxChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MIN_CHANNEL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMinChnTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_NAME, WLAN_PARAM_Integer, + hdd_config_t, max_chntime_btc_esco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_NAME, WLAN_PARAM_Integer, + hdd_config_t, min_chntime_btc_esco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_MAX ), + + REG_VARIABLE(CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_NAME, WLAN_PARAM_Integer, + hdd_config_t, min_chntime_btc_sco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_BTC_SCO_MAX ), + + REG_VARIABLE(CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_NAME, WLAN_PARAM_Integer, + hdd_config_t, max_chntime_btc_sco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_BTC_SCO_MAX ), + + REG_VARIABLE( CFG_RETRY_LIMIT_ZERO_NAME, WLAN_PARAM_Integer, + hdd_config_t, retryLimitZero, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RETRY_LIMIT_ZERO_DEFAULT, + CFG_RETRY_LIMIT_ZERO_MIN, + CFG_RETRY_LIMIT_ZERO_MAX ), + + REG_VARIABLE( CFG_RETRY_LIMIT_ONE_NAME, WLAN_PARAM_Integer, + hdd_config_t, retryLimitOne, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RETRY_LIMIT_ONE_DEFAULT, + CFG_RETRY_LIMIT_ONE_MIN, + CFG_RETRY_LIMIT_ONE_MAX ), + + REG_VARIABLE( CFG_RETRY_LIMIT_TWO_NAME, WLAN_PARAM_Integer, + hdd_config_t, retryLimitTwo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RETRY_LIMIT_TWO_DEFAULT, + CFG_RETRY_LIMIT_TWO_MIN, + CFG_RETRY_LIMIT_TWO_MAX ), + + REG_VARIABLE( CFG_DISABLE_AGG_WITH_BTC_NAME, WLAN_PARAM_Integer, + hdd_config_t, disableAggWithBtc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_AGG_WITH_BTC_DEFAULT, + CFG_DISABLE_AGG_WITH_BTC_MIN, + CFG_DISABLE_AGG_WITH_BTC_MAX ), + +#ifdef WLAN_AP_STA_CONCURRENCY + REG_VARIABLE( CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMaxChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_DEFAULT, + CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MIN, + CFG_PASSIVE_MAX_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nPassiveMinChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_DEFAULT, + CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MIN, + CFG_PASSIVE_MIN_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMaxChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_DEFAULT, + CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MIN, + CFG_ACTIVE_MAX_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nActiveMinChnTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_DEFAULT, + CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MIN, + CFG_ACTIVE_MIN_CHANNEL_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_REST_TIME_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRestTimeConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REST_TIME_CONC_DEFAULT, + CFG_REST_TIME_CONC_MIN, + CFG_REST_TIME_CONC_MAX ), + + REG_VARIABLE( CFG_NUM_STA_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNumStaChanCombinedConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NUM_STA_CHAN_COMBINED_CONC_DEFAULT, + CFG_NUM_STA_CHAN_COMBINED_CONC_MIN, + CFG_NUM_STA_CHAN_COMBINED_CONC_MAX ), + + REG_VARIABLE( CFG_NUM_P2P_CHAN_COMBINED_CONC_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNumP2PChanCombinedConc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NUM_P2P_CHAN_COMBINED_CONC_DEFAULT, + CFG_NUM_P2P_CHAN_COMBINED_CONC_MIN, + CFG_NUM_P2P_CHAN_COMBINED_CONC_MAX ), +#endif + + REG_VARIABLE( CFG_MAX_PS_POLL_NAME, WLAN_PARAM_Integer, + hdd_config_t, nMaxPsPoll, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_PS_POLL_DEFAULT, + CFG_MAX_PS_POLL_MIN, + CFG_MAX_PS_POLL_MAX ), + + REG_VARIABLE( CFG_MAX_TX_POWER_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTxPowerCap, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_TX_POWER_DEFAULT, + CFG_MAX_TX_POWER_MIN, + CFG_MAX_TX_POWER_MAX ), + + REG_VARIABLE( CFG_LOW_GAIN_OVERRIDE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIsLowGainOverride, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LOW_GAIN_OVERRIDE_DEFAULT, + CFG_LOW_GAIN_OVERRIDE_MIN, + CFG_LOW_GAIN_OVERRIDE_MAX ), + + REG_VARIABLE( CFG_RSSI_FILTER_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRssiFilterPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RSSI_FILTER_PERIOD_DEFAULT, + CFG_RSSI_FILTER_PERIOD_MIN, + CFG_RSSI_FILTER_PERIOD_MAX ), + + REG_VARIABLE( CFG_IGNORE_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, fIgnoreDtim, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_DTIM_DEFAULT, + CFG_IGNORE_DTIM_MIN, + CFG_IGNORE_DTIM_MAX ), + + REG_VARIABLE( CFG_MAX_LI_MODULATED_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, fMaxLIModulatedDTIM, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_LI_MODULATED_DTIM_DEFAULT, + CFG_MAX_LI_MODULATED_DTIM_MIN, + CFG_MAX_LI_MODULATED_DTIM_MAX ), + + REG_VARIABLE( CFG_RX_ANT_CONFIGURATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRxAnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RX_ANT_CONFIGURATION_NAME_DEFAULT, + CFG_RX_ANT_CONFIGURATION_NAME_MIN, + CFG_RX_ANT_CONFIGURATION_NAME_MAX ), + + REG_VARIABLE( CFG_FW_HEART_BEAT_MONITORING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableFwHeartBeatMonitoring, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FW_HEART_BEAT_MONITORING_DEFAULT, + CFG_FW_HEART_BEAT_MONITORING_MIN, + CFG_FW_HEART_BEAT_MONITORING_MAX ), + + REG_VARIABLE( CFG_FW_BEACON_FILTERING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableFwBeaconFiltering, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FW_BEACON_FILTERING_DEFAULT, + CFG_FW_BEACON_FILTERING_MIN, + CFG_FW_BEACON_FILTERING_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_FW_RSSI_MONITORING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableFwRssiMonitoring, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FW_RSSI_MONITORING_DEFAULT, + CFG_FW_RSSI_MONITORING_MIN, + CFG_FW_RSSI_MONITORING_MAX, + cbNotifySetFwRssiMonitoring, 0 ), + + REG_VARIABLE( CFG_DATA_INACTIVITY_TIMEOUT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nDataInactivityTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DATA_INACTIVITY_TIMEOUT_DEFAULT, + CFG_DATA_INACTIVITY_TIMEOUT_MIN, + CFG_DATA_INACTIVITY_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_NTH_BEACON_FILTER_NAME, WLAN_PARAM_Integer, + hdd_config_t, nthBeaconFilter, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NTH_BEACON_FILTER_DEFAULT, + CFG_NTH_BEACON_FILTER_MIN, + CFG_NTH_BEACON_FILTER_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, WmmMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_MODE_DEFAULT, + CFG_QOS_WMM_MODE_MIN, + CFG_QOS_WMM_MODE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_80211E_ENABLED_NAME , WLAN_PARAM_Integer, + hdd_config_t, b80211eIsEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_80211E_ENABLED_DEFAULT, + CFG_QOS_WMM_80211E_ENABLED_MIN, + CFG_QOS_WMM_80211E_ENABLED_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_UAPSD_MASK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, UapsdMask, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_UAPSD_MASK_DEFAULT, + CFG_QOS_WMM_UAPSD_MASK_MIN, + CFG_QOS_WMM_UAPSD_MASK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdVoSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VO_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdVoSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VO_SUS_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdViSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VI_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdViSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_VI_SUS_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBeSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BE_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBeSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BE_SUS_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBkSrvIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BK_SRV_INTV_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraUapsdBkSuspIntv, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_DEFAULT, + CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MIN, + CFG_QOS_WMM_INFRA_UAPSD_BK_SUS_INTV_MAX ), + +#ifdef FEATURE_WLAN_ESE + REG_VARIABLE( CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, InfraInactivityInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_DEFAULT, + CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MIN, + CFG_QOS_WMM_INFRA_INACTIVITY_INTERVAL_MAX), + REG_DYNAMIC_VARIABLE( CFG_ESE_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isEseIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ESE_FEATURE_ENABLED_DEFAULT, + CFG_ESE_FEATURE_ENABLED_MIN, + CFG_ESE_FEATURE_ENABLED_MAX, + cbNotifySetEseFeatureEnabled, 0 ), +#endif // FEATURE_WLAN_ESE + +#ifdef FEATURE_WLAN_LFR + // flag to turn ON/OFF Legacy Fast Roaming + REG_DYNAMIC_VARIABLE( CFG_LFR_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isFastRoamIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LFR_FEATURE_ENABLED_DEFAULT, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX, + NotifyIsFastRoamIniFeatureEnabled, 0 ), + + /* flag to turn ON/OFF Motion assistance for Legacy Fast Roaming */ + REG_DYNAMIC_VARIABLE( CFG_LFR_MAWC_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, MAWCEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LFR_MAWC_FEATURE_ENABLED_DEFAULT, + CFG_LFR_MAWC_FEATURE_ENABLED_MIN, + CFG_LFR_MAWC_FEATURE_ENABLED_MAX, + NotifyIsMAWCIniFeatureEnabled, 0 ), + +#endif // FEATURE_WLAN_LFR + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + // flag to turn ON/OFF 11r and ESE FastTransition + REG_DYNAMIC_VARIABLE( CFG_FAST_TRANSITION_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isFastTransitionEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT, + CFG_FAST_TRANSITION_ENABLED_NAME_MIN, + CFG_FAST_TRANSITION_ENABLED_NAME_MAX, + cbNotifySetFastTransitionEnabled, 0 ), + + /* Variable to specify the delta/difference between the RSSI of current AP + * and roamable AP while roaming */ + REG_DYNAMIC_VARIABLE( CFG_ROAM_RSSI_DIFF_NAME, WLAN_PARAM_Integer, + hdd_config_t, RoamRssiDiff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_RSSI_DIFF_DEFAULT, + CFG_ROAM_RSSI_DIFF_MIN, + CFG_ROAM_RSSI_DIFF_MAX, + cbNotifySetRoamRssiDiff, 0), + + REG_DYNAMIC_VARIABLE( CFG_IMMEDIATE_ROAM_RSSI_DIFF_NAME, WLAN_PARAM_Integer, + hdd_config_t, nImmediateRoamRssiDiff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IMMEDIATE_ROAM_RSSI_DIFF_DEFAULT, + CFG_IMMEDIATE_ROAM_RSSI_DIFF_MIN, + CFG_IMMEDIATE_ROAM_RSSI_DIFF_MAX, + cbNotifySetImmediateRoamRssiDiff, 0), + + REG_DYNAMIC_VARIABLE( CFG_ENABLE_WES_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, isWESModeEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_WES_MODE_NAME_DEFAULT, + CFG_ENABLE_WES_MODE_NAME_MIN, + CFG_ENABLE_WES_MODE_NAME_MAX, + cbNotifySetWESMode, 0), +#endif +#ifdef FEATURE_WLAN_OKC + REG_DYNAMIC_VARIABLE( CFG_OKC_FEATURE_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isOkcIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OKC_FEATURE_ENABLED_DEFAULT, + CFG_OKC_FEATURE_ENABLED_MIN, + CFG_OKC_FEATURE_ENABLED_MAX, + cbNotifySetOkcFeatureEnabled, 0 ), +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + REG_DYNAMIC_VARIABLE( CFG_ROAM_SCAN_OFFLOAD_ENABLED, WLAN_PARAM_Integer, + hdd_config_t, isRoamOffloadScanEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT, + CFG_ROAM_SCAN_OFFLOAD_ENABLED_MIN, + CFG_ROAM_SCAN_OFFLOAD_ENABLED_MAX, + cbNotifyUpdateRoamScanOffloadEnabled, 0), +#endif + REG_VARIABLE( CFG_QOS_WMM_PKT_CLASSIFY_BASIS_NAME , WLAN_PARAM_Integer, + hdd_config_t, PktClassificationBasis, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_PKT_CLASSIFY_BASIS_DEFAULT, + CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MIN, + CFG_QOS_WMM_PKT_CLASSIFY_BASIS_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_VO_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VO_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_VO_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcVo, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VO_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VO_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_VO_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_VI_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_VI_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_VI_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcVi, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VI_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_VI_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_VI_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_BE_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BE_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_BE_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcBe, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BE_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BE_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_BE_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_DIR_AC_BK_NAME , WLAN_PARAM_Integer, + hdd_config_t, InfraDirAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_DIR_AC_BK_MIN, + CFG_QOS_WMM_INFRA_DIR_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraNomMsduSizeAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MIN, + CFG_QOS_WMM_INFRA_NOM_MSDU_SIZE_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMeanDataRateAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MIN, + CFG_QOS_WMM_INFRA_MEAN_DATA_RATE_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraMinPhyRateAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MIN, + CFG_QOS_WMM_INFRA_MIN_PHY_RATE_AC_BK_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_INFRA_SBA_AC_BK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, InfraSbaAcBk, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BK_DEFAULT, + CFG_QOS_WMM_INFRA_SBA_AC_BK_MIN, + CFG_QOS_WMM_INFRA_SBA_AC_BK_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_BK_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqBkWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_BK_WEIGHT_DEFAULT, + CFG_TL_WFQ_BK_WEIGHT_MIN, + CFG_TL_WFQ_BK_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_BE_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqBeWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_BE_WEIGHT_DEFAULT, + CFG_TL_WFQ_BE_WEIGHT_MIN, + CFG_TL_WFQ_BE_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_VI_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqViWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_VI_WEIGHT_DEFAULT, + CFG_TL_WFQ_VI_WEIGHT_MIN, + CFG_TL_WFQ_VI_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_WFQ_VO_WEIGHT_NAME , WLAN_PARAM_Integer, + hdd_config_t, WfqVoWeight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_WFQ_VO_WEIGHT_DEFAULT, + CFG_TL_WFQ_VO_WEIGHT_MIN, + CFG_TL_WFQ_VO_WEIGHT_MAX ), + + REG_VARIABLE( CFG_TL_DELAYED_TRGR_FRM_INT_NAME , WLAN_PARAM_Integer, + hdd_config_t, DelayedTriggerFrmInt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TL_DELAYED_TRGR_FRM_INT_DEFAULT, + CFG_TL_DELAYED_TRGR_FRM_INT_MIN, + CFG_TL_DELAYED_TRGR_FRM_INT_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_BK_NAME , WLAN_PARAM_Integer, + hdd_config_t, BkReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_BK_DEFAULT, + CFG_REORDER_TIME_BK_MIN, + CFG_REORDER_TIME_BK_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_BE_NAME , WLAN_PARAM_Integer, + hdd_config_t, BeReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_BE_DEFAULT, + CFG_REORDER_TIME_BE_MIN, + CFG_REORDER_TIME_BE_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_VI_NAME , WLAN_PARAM_Integer, + hdd_config_t, ViReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_VI_DEFAULT, + CFG_REORDER_TIME_VI_MIN, + CFG_REORDER_TIME_VI_MAX ), + + REG_VARIABLE( CFG_REORDER_TIME_VO_NAME , WLAN_PARAM_Integer, + hdd_config_t, VoReorderAgingTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REORDER_TIME_VO_DEFAULT, + CFG_REORDER_TIME_VO_MIN, + CFG_REORDER_TIME_VO_MAX ), + + REG_VARIABLE_STRING( CFG_WOWL_PATTERN_NAME, WLAN_PARAM_String, + hdd_config_t, wowlPattern, + VAR_FLAGS_OPTIONAL, + (void *)CFG_WOWL_PATTERN_DEFAULT ), + + REG_VARIABLE( CFG_QOS_IMPLICIT_SETUP_ENABLED_NAME , WLAN_PARAM_Integer, + hdd_config_t, bImplicitQosEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_IMPLICIT_SETUP_ENABLED_DEFAULT, + CFG_QOS_IMPLICIT_SETUP_ENABLED_MIN, + CFG_QOS_IMPLICIT_SETUP_ENABLED_MAX ), + + REG_VARIABLE( CFG_BTC_EXECUTION_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcExecutionMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_EXECUTION_MODE_DEFAULT, + CFG_BTC_EXECUTION_MODE_MIN, + CFG_BTC_EXECUTION_MODE_MAX ), + + REG_VARIABLE( CFG_BTC_DHCP_PROTECTION_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcConsBtSlotsToBlockDuringDhcp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DHCP_PROTECTION_DEFAULT, + CFG_BTC_DHCP_PROTECTION_MIN, + CFG_BTC_DHCP_PROTECTION_MAX ), + + REG_VARIABLE( CFG_BTC_A2DP_DHCP_PROTECTION_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcA2DPBtSubIntervalsDuringDhcp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_A2DP_DHCP_PROTECTION_DEFAULT, + CFG_BTC_A2DP_DHCP_PROTECTION_MIN, + CFG_BTC_A2DP_DHCP_PROTECTION_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_INQ_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenInqBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_BT_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_BT_MIN, + CFG_BTC_STATIC_LEN_INQ_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_PAGE_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenPageBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_BT_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_BT_MIN, + CFG_BTC_STATIC_LEN_PAGE_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_CONN_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenConnBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_BT_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_BT_MIN, + CFG_BTC_STATIC_LEN_CONN_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_LE_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenLeBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_LE_BT_DEFAULT, + CFG_BTC_STATIC_LEN_LE_BT_MIN, + CFG_BTC_STATIC_LEN_LE_BT_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_INQ_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenInqWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_INQ_WLAN_MIN, + CFG_BTC_STATIC_LEN_INQ_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_PAGE_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenPageWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_PAGE_WLAN_MIN, + CFG_BTC_STATIC_LEN_PAGE_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_CONN_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenConnWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_CONN_WLAN_MIN, + CFG_BTC_STATIC_LEN_CONN_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_LEN_LE_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcStaticLenLeWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_LEN_LE_WLAN_DEFAULT, + CFG_BTC_STATIC_LEN_LE_WLAN_MIN, + CFG_BTC_STATIC_LEN_LE_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_DYN_MAX_LEN_BT_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDynMaxLenBt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DYN_MAX_LEN_BT_DEFAULT, + CFG_BTC_DYN_MAX_LEN_BT_MIN, + CFG_BTC_DYN_MAX_LEN_BT_MAX ), + + REG_VARIABLE( CFG_BTC_DYN_MAX_LEN_WLAN_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDynMaxLenWlan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DYN_MAX_LEN_WLAN_DEFAULT, + CFG_BTC_DYN_MAX_LEN_WLAN_MIN, + CFG_BTC_DYN_MAX_LEN_WLAN_MAX ), + + REG_VARIABLE( CFG_BTC_MAX_SCO_BLOCK_PERC_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcMaxScoBlockPerc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_MAX_SCO_BLOCK_PERC_DEFAULT, + CFG_BTC_MAX_SCO_BLOCK_PERC_MIN, + CFG_BTC_MAX_SCO_BLOCK_PERC_MAX ), + + REG_VARIABLE( CFG_BTC_DHCP_PROT_ON_A2DP_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDhcpProtOnA2dp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DHCP_PROT_ON_A2DP_DEFAULT, + CFG_BTC_DHCP_PROT_ON_A2DP_MIN, + CFG_BTC_DHCP_PROT_ON_A2DP_MAX ), + + REG_VARIABLE( CFG_BTC_DHCP_PROT_ON_SCO_NAME , WLAN_PARAM_Integer, + hdd_config_t, btcDhcpProtOnSco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DHCP_PROT_ON_SCO_DEFAULT, + CFG_BTC_DHCP_PROT_ON_SCO_MIN, + CFG_BTC_DHCP_PROT_ON_SCO_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V1_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V2_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V3_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V4_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V5_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V6_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V7_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[6], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V8_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[7], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V9_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[8], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_WAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWANFreq[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WAN_FREQ_MIN, + CFG_MWS_COEX_VX_WAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_WLAN_FREQ_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimWLANFreq[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_DEFAULT, + CFG_MWS_COEX_VX_WLAN_FREQ_MIN, + CFG_MWS_COEX_VX_WLAN_FREQ_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_CONFIG_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_V10_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexVictimConfig2[9], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_DEFAULT, + CFG_MWS_COEX_VX_CONFIG_MIN, + CFG_MWS_COEX_VX_CONFIG_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_MODEM_BACKOFF_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexModemBackoff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_MODEM_BACKOFF_DEFAULT, + CFG_MWS_COEX_MODEM_BACKOFF_MIN, + CFG_MWS_COEX_MODEM_BACKOFF_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG1_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[0], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG2_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[1], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG3_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[2], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG4_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[3], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG5_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[4], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_MWS_COEX_CONFIG6_NAME , WLAN_PARAM_Integer, + hdd_config_t, mwsCoexConfig[5], + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_CONFIGX_DEFAULT, + CFG_MWS_COEX_CONFIGX_MIN, + CFG_MWS_COEX_CONFIGX_MAX ), + + REG_VARIABLE( CFG_SAR_POWER_BACKOFF_NAME , WLAN_PARAM_Integer, + hdd_config_t, SARPowerBackoff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAR_POWER_BACKOFF_DEFAULT, + CFG_SAR_POWER_BACKOFF_MIN, + CFG_SAR_POWER_BACKOFF_MAX ), + + REG_VARIABLE( CFG_AP_LISTEN_MODE_NAME , WLAN_PARAM_Integer, + hdd_config_t, nEnableListenMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_LISTEN_MODE_DEFAULT, + CFG_AP_LISTEN_MODE_MIN, + CFG_AP_LISTEN_MODE_MAX ), + + REG_VARIABLE( CFG_AP_AUTO_SHUT_OFF , WLAN_PARAM_Integer, + hdd_config_t, nAPAutoShutOff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_AUTO_SHUT_OFF_DEFAULT, + CFG_AP_AUTO_SHUT_OFF_MIN, + CFG_AP_AUTO_SHUT_OFF_MAX ), + +#if defined WLAN_FEATURE_VOWIFI + REG_VARIABLE( CFG_RRM_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fRrmEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_ENABLE_DEFAULT, + CFG_RRM_ENABLE_MIN, + CFG_RRM_ENABLE_MAX ), + + REG_VARIABLE( CFG_RRM_OPERATING_CHAN_MAX_DURATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, nInChanMeasMaxDuration, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_OPERATING_CHAN_MAX_DURATION_DEFAULT, + CFG_RRM_OPERATING_CHAN_MAX_DURATION_MIN, + CFG_RRM_OPERATING_CHAN_MAX_DURATION_MAX ), + + REG_VARIABLE( CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, nOutChanMeasMaxDuration, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_DEFAULT, + CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MIN, + CFG_RRM_NON_OPERATING_CHAN_MAX_DURATION_MAX ), + + REG_VARIABLE( CFG_RRM_MEAS_RANDOMIZATION_INTVL_NAME, WLAN_PARAM_Integer, + hdd_config_t, nRrmRandnIntvl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RRM_MEAS_RANDOMIZATION_INTVL_DEFAULT, + CFG_RRM_MEAS_RANDOMIZATION_INTVL_MIN, + CFG_RRM_MEAS_RANDOMIZATION_INTVL_MAX ), +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + REG_VARIABLE( CFG_FT_RESOURCE_REQ_NAME, WLAN_PARAM_Integer, + hdd_config_t, fFTResourceReqSupported, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FT_RESOURCE_REQ_DEFAULT, + CFG_FT_RESOURCE_REQ_MIN, + CFG_FT_RESOURCE_REQ_MAX ), +#endif + + REG_VARIABLE( CFG_ENABLE_ROAM_DELAY_STATS, WLAN_PARAM_Integer, + hdd_config_t, gEnableRoamDelayStats, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_ROAM_DELAY_STATS_DEFAULT, + CFG_ENABLE_ROAM_DELAY_STATS_MIN, + CFG_ENABLE_ROAM_DELAY_STATS_MAX ), + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_TIMER_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborScanPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX, + cbNotifySetNeighborScanPeriod, 0 ), + + REG_VARIABLE( CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborReassocRssiThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_DEFAULT, + CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_REASSOC_RSSI_THRESHOLD_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborLookupRssiThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX, + cbNotifySetNeighborLookupRssiThreshold, 0 ), + + REG_VARIABLE_STRING( CFG_NEIGHBOR_SCAN_CHAN_LIST_NAME, WLAN_PARAM_String, + hdd_config_t, neighborScanChanList, + VAR_FLAGS_OPTIONAL, + (void *)CFG_NEIGHBOR_SCAN_CHAN_LIST_DEFAULT ), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborScanMinChanTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX, + cbNotifySetNeighborScanMinChanTime, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborScanMaxChanTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX, + cbNotifySetNeighborScanMaxChanTime, 0 ), + + REG_VARIABLE( CFG_11R_NEIGHBOR_REQ_MAX_TRIES_NAME, WLAN_PARAM_Integer, + hdd_config_t, nMaxNeighborReqTries, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_11R_NEIGHBOR_REQ_MAX_TRIES_DEFAULT, + CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MIN, + CFG_11R_NEIGHBOR_REQ_MAX_TRIES_MAX), + + REG_DYNAMIC_VARIABLE( CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborResultsRefreshPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT, + CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX, + cbNotifySetNeighborResultsRefreshPeriod, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_EMPTY_SCAN_REFRESH_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, nEmptyScanRefreshPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT, + CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN, + CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX, + cbNotifySetEmptyScanRefreshPeriod, 0 ), + + REG_VARIABLE( CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNeighborInitialForcedRoamTo5GhEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_DEFAULT, + CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MIN, + CFG_NEIGHBOR_INITIAL_FORCED_ROAM_TO_5GH_ENABLE_MAX), + + REG_VARIABLE(CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_NAME, + WLAN_PARAM_Integer, + hdd_config_t, nWeakZoneRssiThresholdForRoam, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_DEFAULT, + CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MIN, + CFG_NEIGHBOR_WEAK_ZONE_RSSI_THRESHOLD_FOR_ROAM_MAX), + +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + + REG_VARIABLE( CFG_QOS_WMM_BURST_SIZE_DEFN_NAME , WLAN_PARAM_Integer, + hdd_config_t, burstSizeDefinition, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_BURST_SIZE_DEFN_DEFAULT, + CFG_QOS_WMM_BURST_SIZE_DEFN_MIN, + CFG_QOS_WMM_BURST_SIZE_DEFN_MAX ), + + REG_VARIABLE( CFG_MCAST_BCAST_FILTER_SETTING_NAME, WLAN_PARAM_Integer, + hdd_config_t, mcastBcastFilterSetting, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MCAST_BCAST_FILTER_SETTING_DEFAULT, + CFG_MCAST_BCAST_FILTER_SETTING_MIN, + CFG_MCAST_BCAST_FILTER_SETTING_MAX ), + + REG_VARIABLE( CFG_ENABLE_HOST_ARPOFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fhostArpOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HOST_ARPOFFLOAD_DEFAULT, + CFG_ENABLE_HOST_ARPOFFLOAD_MIN, + CFG_ENABLE_HOST_ARPOFFLOAD_MAX ), + + REG_VARIABLE( CFG_ENABLE_HOST_NSOFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fhostNSOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HOST_NSOFFLOAD_DEFAULT, + CFG_ENABLE_HOST_NSOFFLOAD_MIN, + CFG_ENABLE_HOST_NSOFFLOAD_MAX ), + + REG_VARIABLE( CFG_QOS_WMM_TS_INFO_ACK_POLICY_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, tsInfoAckPolicy, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_WMM_TS_INFO_ACK_POLICY_DEFAULT, + CFG_QOS_WMM_TS_INFO_ACK_POLICY_MIN, + CFG_QOS_WMM_TS_INFO_ACK_POLICY_MAX ), + + REG_VARIABLE( CFG_SINGLE_TID_RC_NAME, WLAN_PARAM_Integer, + hdd_config_t, bSingleTidRc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SINGLE_TID_RC_DEFAULT, + CFG_SINGLE_TID_RC_MIN, + CFG_SINGLE_TID_RC_MAX), + + REG_VARIABLE( CFG_DYNAMIC_PSPOLL_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, dynamicPsPollValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DYNAMIC_PSPOLL_VALUE_DEFAULT, + CFG_DYNAMIC_PSPOLL_VALUE_MIN, + CFG_DYNAMIC_PSPOLL_VALUE_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_WAKEUP_EN_NAME, WLAN_PARAM_Integer, + hdd_config_t, teleBcnWakeupEn, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_WAKEUP_EN_DEFAULT, + CFG_TELE_BCN_WAKEUP_EN_MIN, + CFG_TELE_BCN_WAKEUP_EN_MAX ), + + REG_VARIABLE( CFG_INFRA_STA_KEEP_ALIVE_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, infraStaKeepAlivePeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT, + CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MIN, + CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX), + + REG_VARIABLE( CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_NAME , WLAN_PARAM_Integer, + hdd_config_t, AddTSWhenACMIsOff, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_DEFAULT, + CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MIN, + CFG_QOS_ADDTS_WHEN_ACM_IS_OFF_MAX ), + + + REG_VARIABLE( CFG_VALIDATE_SCAN_LIST_NAME , WLAN_PARAM_Integer, + hdd_config_t, fValidateScanList, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VALIDATE_SCAN_LIST_DEFAULT, + CFG_VALIDATE_SCAN_LIST_MIN, + CFG_VALIDATE_SCAN_LIST_MAX ), + + REG_VARIABLE( CFG_NULLDATA_AP_RESP_TIMEOUT_NAME, WLAN_PARAM_Integer, + hdd_config_t, nNullDataApRespTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_NULLDATA_AP_RESP_TIMEOUT_DEFAULT, + CFG_NULLDATA_AP_RESP_TIMEOUT_MIN, + CFG_NULLDATA_AP_RESP_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_AP_DATA_AVAIL_POLL_PERIOD_NAME, WLAN_PARAM_Integer, + hdd_config_t, apDataAvailPollPeriodInMs, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AP_DATA_AVAIL_POLL_PERIOD_DEFAULT, + CFG_AP_DATA_AVAIL_POLL_PERIOD_MIN, + CFG_AP_DATA_AVAIL_POLL_PERIOD_MAX ), + + REG_VARIABLE( CFG_ENABLE_BTAMP_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableBtAmp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BTAMP_DEFAULT, + CFG_ENABLE_BTAMP_MIN, + CFG_ENABLE_BTAMP_MAX ), + +#ifdef WLAN_BTAMP_FEATURE + REG_VARIABLE( CFG_BT_AMP_PREFERRED_CHANNEL_NAME, WLAN_PARAM_Integer, + hdd_config_t, preferredChannel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BT_AMP_PREFERRED_CHANNEL_DEFAULT, + CFG_BT_AMP_PREFERRED_CHANNEL_MIN, + CFG_BT_AMP_PREFERRED_CHANNEL_MAX ), +#endif //WLAN_BTAMP_FEATURE + REG_VARIABLE( CFG_BAND_CAPABILITY_NAME, WLAN_PARAM_Integer, + hdd_config_t, nBandCapability, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BAND_CAPABILITY_DEFAULT, + CFG_BAND_CAPABILITY_MIN, + CFG_BAND_CAPABILITY_MAX ), + + REG_VARIABLE( CFG_ENABLE_BEACON_EARLY_TERMINATION_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableBeaconEarlyTermination, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BEACON_EARLY_TERMINATION_DEFAULT, + CFG_ENABLE_BEACON_EARLY_TERMINATION_MIN, + CFG_ENABLE_BEACON_EARLY_TERMINATION_MAX ), +/* CFG_VOS_TRACE_ENABLE Parameters */ + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_BAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableBAP, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_TL_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableTL, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_WDI_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableWDI, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_HDD_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableHDD, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_SME_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableSME, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_PE_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnablePE, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_PMC_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnablePMC, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_WDA_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableWDA, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_SYS_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableSYS, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_VOSS_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableVOSS, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_SAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableSAP, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_VOS_TRACE_ENABLE_HDD_SAP_NAME, WLAN_PARAM_Integer, + hdd_config_t, vosTraceEnableHDDSAP, + VAR_FLAGS_OPTIONAL, + CFG_VOS_TRACE_ENABLE_DEFAULT, + CFG_VOS_TRACE_ENABLE_MIN, + CFG_VOS_TRACE_ENABLE_MAX ), + + /* note that since the default value is out of range we cannot + enable range check, otherwise we get a system log message */ + REG_VARIABLE( CFG_WDI_TRACE_ENABLE_DAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, wdiTraceEnableDAL, + VAR_FLAGS_OPTIONAL, + CFG_WDI_TRACE_ENABLE_DEFAULT, + CFG_WDI_TRACE_ENABLE_MIN, + CFG_WDI_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_WDI_TRACE_ENABLE_CTL_NAME, WLAN_PARAM_Integer, + hdd_config_t, wdiTraceEnableCTL, + VAR_FLAGS_OPTIONAL, + CFG_WDI_TRACE_ENABLE_DEFAULT, + CFG_WDI_TRACE_ENABLE_MIN, + CFG_WDI_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_WDI_TRACE_ENABLE_DAT_NAME, WLAN_PARAM_Integer, + hdd_config_t, wdiTraceEnableDAT, + VAR_FLAGS_OPTIONAL, + CFG_WDI_TRACE_ENABLE_DEFAULT, + CFG_WDI_TRACE_ENABLE_MIN, + CFG_WDI_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_WDI_TRACE_ENABLE_PAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, wdiTraceEnablePAL, + VAR_FLAGS_OPTIONAL, + CFG_WDI_TRACE_ENABLE_DEFAULT, + CFG_WDI_TRACE_ENABLE_MIN, + CFG_WDI_TRACE_ENABLE_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_TRANS_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnTransListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_TRANS_LI_DEFAULT, + CFG_TELE_BCN_TRANS_LI_MIN, + CFG_TELE_BCN_TRANS_LI_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnTransLiNumIdleBeacons, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_DEFAULT, + CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MIN, + CFG_TELE_BCN_TRANS_LI_NUM_IDLE_BCNS_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_MAX_LI_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnMaxListenInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_MAX_LI_DEFAULT, + CFG_TELE_BCN_MAX_LI_MIN, + CFG_TELE_BCN_MAX_LI_MAX ), + + REG_VARIABLE( CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_NAME, WLAN_PARAM_Integer, + hdd_config_t, nTeleBcnMaxLiNumIdleBeacons, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_DEFAULT, + CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MIN, + CFG_TELE_BCN_MAX_LI_NUM_IDLE_BCNS_MAX ), + + REG_VARIABLE( CFG_BCN_EARLY_TERM_WAKE_NAME, WLAN_PARAM_Integer, + hdd_config_t, bcnEarlyTermWakeInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BCN_EARLY_TERM_WAKE_DEFAULT, + CFG_BCN_EARLY_TERM_WAKE_MIN, + CFG_BCN_EARLY_TERM_WAKE_MAX ), + + REG_VARIABLE( CFG_ENABLE_CLOSE_LOOP_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableCloseLoop, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_CLOSE_LOOP_DEFAULT, + CFG_ENABLE_CLOSE_LOOP_MIN, + CFG_ENABLE_CLOSE_LOOP_MAX ), + + REG_VARIABLE( CFG_ENABLE_BYPASS_11D_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableBypass11d, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BYPASS_11D_DEFAULT, + CFG_ENABLE_BYPASS_11D_MIN, + CFG_ENABLE_BYPASS_11D_MAX ), + + REG_VARIABLE( CFG_ENABLE_DFS_CHNL_SCAN_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDFSChnlScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DFS_CHNL_SCAN_DEFAULT, + CFG_ENABLE_DFS_CHNL_SCAN_MIN, + CFG_ENABLE_DFS_CHNL_SCAN_MAX ), + + REG_VARIABLE( CFG_ENABLE_DFS_PNO_CHNL_SCAN_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDFSPnoChnlScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DFS_PNO_CHNL_SCAN_DEFAULT, + CFG_ENABLE_DFS_PNO_CHNL_SCAN_MIN, + CFG_ENABLE_DFS_PNO_CHNL_SCAN_MAX ), + + REG_VARIABLE( CFG_ENABLE_DYNAMIC_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDynamicDTIM, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DYNAMIC_DTIM_DEFAULT, + CFG_ENABLE_DYNAMIC_DTIM_MIN, + CFG_ENABLE_DYNAMIC_DTIM_MAX ), + + REG_VARIABLE( CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableAutomaticTxPowerControl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_DEFAULT, + CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MIN, + CFG_ENABLE_AUTOMATIC_TX_POWER_CONTROL_MAX ), + + REG_VARIABLE( CFG_SHORT_GI_40MHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, ShortGI40MhzEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SHORT_GI_40MHZ_DEFAULT, + CFG_SHORT_GI_40MHZ_MIN, + CFG_SHORT_GI_40MHZ_MAX ), + + REG_DYNAMIC_VARIABLE( CFG_REPORT_MAX_LINK_SPEED, WLAN_PARAM_Integer, + hdd_config_t, reportMaxLinkSpeed, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_REPORT_MAX_LINK_SPEED_DEFAULT, + CFG_REPORT_MAX_LINK_SPEED_MIN, + CFG_REPORT_MAX_LINK_SPEED_MAX, + NULL, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_LINK_SPEED_RSSI_HIGH, WLAN_PARAM_SignedInteger, + hdd_config_t, linkSpeedRssiHigh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_SPEED_RSSI_HIGH_DEFAULT, + CFG_LINK_SPEED_RSSI_HIGH_MIN, + CFG_LINK_SPEED_RSSI_HIGH_MAX, + NULL, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_LINK_SPEED_RSSI_MID, WLAN_PARAM_SignedInteger, + hdd_config_t, linkSpeedRssiMid, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_SPEED_RSSI_MID_DEFAULT, + CFG_LINK_SPEED_RSSI_MID_MIN, + CFG_LINK_SPEED_RSSI_MID_MAX, + NULL, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_LINK_SPEED_RSSI_LOW, WLAN_PARAM_SignedInteger, + hdd_config_t, linkSpeedRssiLow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_SPEED_RSSI_LOW_DEFAULT, + CFG_LINK_SPEED_RSSI_LOW_MIN, + CFG_LINK_SPEED_RSSI_LOW_MAX, + NULL, 0 ), + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + REG_DYNAMIC_VARIABLE( CFG_ROAM_PREFER_5GHZ, WLAN_PARAM_Integer, + hdd_config_t, nRoamPrefer5GHz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_PREFER_5GHZ_DEFAULT, + CFG_ROAM_PREFER_5GHZ_MIN, + CFG_ROAM_PREFER_5GHZ_MAX, + cbNotifySetRoamPrefer5GHz, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_INTRA_BAND, WLAN_PARAM_Integer, + hdd_config_t, nRoamIntraBand, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_INTRA_BAND_DEFAULT, + CFG_ROAM_INTRA_BAND_MIN, + CFG_ROAM_INTRA_BAND_MAX, + cbNotifySetRoamIntraBand, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_SCAN_N_PROBES, WLAN_PARAM_Integer, + hdd_config_t, nProbes, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_N_PROBES_DEFAULT, + CFG_ROAM_SCAN_N_PROBES_MIN, + CFG_ROAM_SCAN_N_PROBES_MAX, + cbNotifySetRoamScanNProbes, 0 ), + + REG_DYNAMIC_VARIABLE( CFG_ROAM_SCAN_HOME_AWAY_TIME, WLAN_PARAM_Integer, + hdd_config_t, nRoamScanHomeAwayTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX, + cbNotifySetRoamScanHomeAwayTime, 0 ), + +#endif + + REG_VARIABLE( CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_NAME, WLAN_PARAM_Integer, + hdd_config_t, isP2pDeviceAddrAdministrated, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_DEFAULT, + CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MIN, + CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED_MAX ), + + REG_VARIABLE( CFG_ENABLE_MCC_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableMCC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MCC_ENABLED_DEFAULT, + CFG_ENABLE_MCC_ENABLED_MIN, + CFG_ENABLE_MCC_ENABLED_MAX ), + + REG_VARIABLE( CFG_ALLOW_MCC_GO_DIFF_BI_NAME, WLAN_PARAM_Integer, + hdd_config_t, allowMCCGODiffBI, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ALLOW_MCC_GO_DIFF_BI_DEFAULT, + CFG_ALLOW_MCC_GO_DIFF_BI_MIN, + CFG_ALLOW_MCC_GO_DIFF_BI_MAX ), + + REG_VARIABLE( CFG_THERMAL_MIGRATION_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, thermalMitigationEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_THERMAL_MIGRATION_ENABLE_DEFAULT, + CFG_THERMAL_MIGRATION_ENABLE_MIN, + CFG_THERMAL_MIGRATION_ENABLE_MAX ), + + REG_VARIABLE( CFG_ENABLE_MODULATED_DTIM_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableModulatedDTIM, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MODULATED_DTIM_DEFAULT, + CFG_ENABLE_MODULATED_DTIM_MIN, + CFG_ENABLE_MODULATED_DTIM_MAX ), + + REG_VARIABLE( CFG_MC_ADDR_LIST_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableMCAddrList, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MC_ADDR_LIST_ENABLE_DEFAULT, + CFG_MC_ADDR_LIST_ENABLE_MIN, + CFG_MC_ADDR_LIST_ENABLE_MAX ), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_VHT_CHANNEL_WIDTH, WLAN_PARAM_Integer, + hdd_config_t, vhtChannelWidth, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_CHANNEL_WIDTH_DEFAULT, + CFG_VHT_CHANNEL_WIDTH_MIN, + CFG_VHT_CHANNEL_WIDTH_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_RX_MCS_8_9, WLAN_PARAM_Integer, + hdd_config_t, vhtRxMCS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_ENABLE_RX_MCS_8_9_DEFAULT, + CFG_VHT_ENABLE_RX_MCS_8_9_MIN, + CFG_VHT_ENABLE_RX_MCS_8_9_MAX), + + REG_VARIABLE( CFG_VHT_ENABLE_TX_MCS_8_9, WLAN_PARAM_Integer, + hdd_config_t, vhtTxMCS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_VHT_ENABLE_TX_MCS_8_9_DEFAULT, + CFG_VHT_ENABLE_TX_MCS_8_9_MIN, + CFG_VHT_ENABLE_TX_MCS_8_9_MAX), + + REG_VARIABLE( CFG_VHT_AMPDU_LEN_EXP_NAME, WLAN_PARAM_Integer, + hdd_config_t, gVhtMaxAmpduLenExp, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_AMPDU_LEN_EXP_DEFAULT, + CFG_VHT_AMPDU_LEN_EXP_MIN, + CFG_VHT_AMPDU_LEN_EXP_MAX ), +#endif + + REG_VARIABLE( CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableFirstScan2GOnly, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FIRST_SCAN_2G_ONLY_DEFAULT, + CFG_ENABLE_FIRST_SCAN_2G_ONLY_MIN, + CFG_ENABLE_FIRST_SCAN_2G_ONLY_MAX ), + + REG_VARIABLE( CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_NAME, WLAN_PARAM_Integer, + hdd_config_t, skipDfsChnlInP2pSearch, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_DEFAULT, + CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MIN, + CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH_MAX ), + + REG_VARIABLE( CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, ignoreDynamicDtimInP2pMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_DEFAULT, + CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MIN, + CFG_IGNORE_DYNAMIC_DTIM_IN_P2P_MODE_MAX ), + + REG_VARIABLE( CFG_NUM_BUFF_ADVERT_NAME, WLAN_PARAM_Integer, + hdd_config_t,numBuffAdvert , + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_NUM_BUFF_ADVERT_DEFAULT, + CFG_NUM_BUFF_ADVERT_MIN, + CFG_NUM_BUFF_ADVERT_MAX ), + + REG_VARIABLE( CFG_MCC_CONFIG_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, configMccParam, + VAR_FLAGS_OPTIONAL, + CFG_MCC_CONFIG_PARAM_DEFAULT, + CFG_MCC_CONFIG_PARAM_MIN, + CFG_MCC_CONFIG_PARAM_MAX ), + REG_VARIABLE( CFG_ENABLE_RX_STBC, WLAN_PARAM_Integer, + hdd_config_t, enableRxSTBC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_RX_STBC_DEFAULT, + CFG_ENABLE_RX_STBC_MIN, + CFG_ENABLE_RX_STBC_MAX ), +#ifdef FEATURE_WLAN_TDLS + REG_VARIABLE( CFG_TDLS_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSSupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_SUPPORT_ENABLE_MIN, + CFG_TDLS_SUPPORT_ENABLE_MAX ), + + REG_VARIABLE( CFG_TDLS_IMPLICIT_TRIGGER, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSImplicitTrigger, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_IMPLICIT_TRIGGER_DEFAULT, + CFG_TDLS_IMPLICIT_TRIGGER_MIN, + CFG_TDLS_IMPLICIT_TRIGGER_MAX ), + + REG_VARIABLE( CFG_TDLS_TX_STATS_PERIOD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSTxStatsPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_TX_STATS_PERIOD_DEFAULT, + CFG_TDLS_TX_STATS_PERIOD_MIN, + CFG_TDLS_TX_STATS_PERIOD_MAX ), + + REG_VARIABLE( CFG_TDLS_TX_PACKET_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSTxPacketThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_TX_PACKET_THRESHOLD_DEFAULT, + CFG_TDLS_TX_PACKET_THRESHOLD_MIN, + CFG_TDLS_TX_PACKET_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_DISCOVERY_PERIOD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSDiscoveryPeriod, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_DISCOVERY_PERIOD_DEFAULT, + CFG_TDLS_DISCOVERY_PERIOD_MIN, + CFG_TDLS_DISCOVERY_PERIOD_MAX ), + + REG_VARIABLE( CFG_TDLS_MAX_DISCOVERY_ATTEMPT, WLAN_PARAM_Integer, + hdd_config_t, fTDLSMaxDiscoveryAttempt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_DEFAULT, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX ), + + REG_VARIABLE( CFG_TDLS_IDLE_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, fTDLSIdleTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_IDLE_TIMEOUT_DEFAULT, + CFG_TDLS_IDLE_TIMEOUT_MIN, + CFG_TDLS_IDLE_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_TDLS_IDLE_PACKET_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSIdlePacketThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_IDLE_PACKET_THRESHOLD_DEFAULT, + CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, + CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_HYSTERESIS, WLAN_PARAM_Integer, + hdd_config_t, fTDLSRSSIHysteresis, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_HYSTERESIS_DEFAULT, + CFG_TDLS_RSSI_HYSTERESIS_MIN, + CFG_TDLS_RSSI_HYSTERESIS_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_TRIGGER_THRESHOLD, WLAN_PARAM_SignedInteger, + hdd_config_t, fTDLSRSSITriggerThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_DEFAULT, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX ), + + REG_VARIABLE( CFG_TDLS_RSSI_TEARDOWN_THRESHOLD, WLAN_PARAM_SignedInteger, + hdd_config_t, fTDLSRSSITeardownThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_DEFAULT, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX ), + +REG_VARIABLE( CFG_TDLS_QOS_WMM_UAPSD_MASK_NAME , WLAN_PARAM_HexInteger, + hdd_config_t, fTDLSUapsdMask, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_QOS_WMM_UAPSD_MASK_DEFAULT, + CFG_TDLS_QOS_WMM_UAPSD_MASK_MIN, + CFG_TDLS_QOS_WMM_UAPSD_MASK_MAX ), + +REG_VARIABLE( CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSBufferSta, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MIN, + CFG_TDLS_BUFFER_STA_SUPPORT_ENABLE_MAX ), + +REG_VARIABLE( CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSOffChannel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MIN, + CFG_TDLS_OFF_CHANNEL_SUPPORT_ENABLE_MAX ), + +REG_VARIABLE( CFG_TDLS_PUAPSD_INACTIVITY_TIME, WLAN_PARAM_Integer, + hdd_config_t, fTDLSPuapsdInactivityTimer, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEFAULT, + CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN, + CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX ), + +REG_VARIABLE( CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, fTDLSRxFrameThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_DEFAULT, + CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MIN, + CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_MAX ), + +REG_VARIABLE( CFG_TDLS_EXTERNAL_CONTROL, WLAN_PARAM_Integer, + hdd_config_t, fTDLSExternalControl, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_EXTERNAL_CONTROL_DEFAULT, + CFG_TDLS_EXTERNAL_CONTROL_MIN, + CFG_TDLS_EXTERNAL_CONTROL_MAX ), + +REG_VARIABLE( CFG_TDLS_WMM_MODE_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSWmmMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_WMM_MODE_ENABLE_DEFAULT, + CFG_TDLS_WMM_MODE_ENABLE_MIN, + CFG_TDLS_WMM_MODE_ENABLE_MAX ), + +REG_VARIABLE( CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSScanCoexSupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_DEFAULT, + CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MIN, + CFG_TDLS_SCAN_COEX_SUPPORT_ENABLE_MAX ), + +REG_VARIABLE( CFG_TDLS_SCAN_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableTDLSScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_SCAN_ENABLE_DEFAULT, + CFG_TDLS_SCAN_ENABLE_MIN, + CFG_TDLS_SCAN_ENABLE_MAX ), +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +REG_VARIABLE( CFG_LINK_LAYER_STATS_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableLLStats, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_LAYER_STATS_ENABLE_DEFAULT, + CFG_LINK_LAYER_STATS_ENABLE_MIN, + CFG_LINK_LAYER_STATS_ENABLE_MAX ), +#endif +#ifdef WLAN_FEATURE_EXTSCAN +REG_VARIABLE( CFG_EXTSCAN_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableEXTScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXTSCAN_ENABLE_DEFAULT, + CFG_EXTSCAN_ENABLE_MIN, + CFG_EXTSCAN_ENABLE_MAX ), +#endif + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + REG_VARIABLE( CFG_VSTA_SUPPORT_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableVSTASupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VSTA_SUPPORT_ENABLE_DEFAULT, + CFG_VSTA_SUPPORT_ENABLE_MIN, + CFG_VSTA_SUPPORT_ENABLE_MAX ), +#endif + REG_VARIABLE( CFG_ENABLE_LPWR_IMG_TRANSITION_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableLpwrImgTransition, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LPWR_IMG_TRANSITION_DEFAULT, + CFG_ENABLE_LPWR_IMG_TRANSITION_MIN, + CFG_ENABLE_LPWR_IMG_TRANSITION_MAX ), + + REG_VARIABLE( CFG_ENABLE_CONSECUTIVE_BMISS_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_conc_bmiss, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_CONSECUTIVE_BMISS_DEFAULT, + CFG_ENABLE_CONSECUTIVE_BMISS_MIN, + CFG_ENABLE_CONSECUTIVE_BMISS_MAX ), + + REG_VARIABLE( CFG_ENABLE_UNITS_BEACON_WAIT_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_units_bwait, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_UNITS_BEACON_WAIT_DEFAULT, + CFG_ENABLE_UNITS_BEACON_WAIT_MIN, + CFG_ENABLE_UNITS_BEACON_WAIT_MAX ), + + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + REG_VARIABLE( CFG_ACTIVEMODE_OFFLOAD_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableActiveModeOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVEMODE_OFFLOAD_ENABLE_DEFAULT, + CFG_ACTIVEMODE_OFFLOAD_ENABLE_MIN, + CFG_ACTIVEMODE_OFFLOAD_ENABLE_MAX ), +#endif + + REG_VARIABLE( CFG_SCAN_AGING_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, scanAgingTimeout, + VAR_FLAGS_OPTIONAL, + CFG_SCAN_AGING_PARAM_DEFAULT, + CFG_SCAN_AGING_PARAM_MIN, + CFG_SCAN_AGING_PARAM_MAX ), + + REG_VARIABLE( CFG_TX_LDPC_ENABLE_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableTxLdpc, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TX_LDPC_ENABLE_FEATURE_DEFAULT, + CFG_TX_LDPC_ENABLE_FEATURE_MIN, + CFG_TX_LDPC_ENABLE_FEATURE_MAX ), + + REG_VARIABLE( CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableMCCAdaptiveScheduler, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_DEFAULT, + CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MIN, + CFG_ENABLE_MCC_ADATIVE_SCHEDULER_ENABLED_MAX ), + + REG_VARIABLE( CFG_ANDRIOD_POWER_SAVE_NAME, WLAN_PARAM_Integer, + hdd_config_t, isAndroidPsEn, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ANDRIOD_POWER_SAVE_DEFAULT, + CFG_ANDRIOD_POWER_SAVE_MIN, + CFG_ANDRIOD_POWER_SAVE_MAX), + + REG_VARIABLE( CFG_IBSS_ADHOC_CHANNEL_5GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, AdHocChannel5G, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_5GHZ_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_5GHZ_MIN, + CFG_IBSS_ADHOC_CHANNEL_5GHZ_MAX), + + REG_VARIABLE( CFG_IBSS_ADHOC_CHANNEL_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, AdHocChannel24G, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_24GHZ_DEFAULT, + CFG_IBSS_ADHOC_CHANNEL_24GHZ_MIN, + CFG_IBSS_ADHOC_CHANNEL_24GHZ_MAX), + + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableTxBF, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_DEFAULT, + CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MIN, + CFG_VHT_SU_BEAMFORMEE_CAP_FEATURE_MAX ), + + REG_VARIABLE( CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, WLAN_PARAM_Integer, + hdd_config_t, txBFCsnValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_DEFAULT, + CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MIN, + CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_MAX ), + REG_VARIABLE( CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE, WLAN_PARAM_Integer, + hdd_config_t, enableMuBformee, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_DEFAULT, + CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MIN, + CFG_VHT_ENABLE_MU_BFORMEE_CAP_FEATURE_MAX ), + +#endif + + REG_VARIABLE( CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, sapAllowAllChannel, + VAR_FLAGS_OPTIONAL, + CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_DEFAULT, + CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MIN, + CFG_SAP_ALLOW_ALL_CHANNEL_PARAM_MAX ), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_DISABLE_LDPC_WITH_TXBF_AP, WLAN_PARAM_Integer, + hdd_config_t, disableLDPCWithTxbfAP, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_LDPC_WITH_TXBF_AP_DEFAULT, + CFG_DISABLE_LDPC_WITH_TXBF_AP_MIN, + CFG_DISABLE_LDPC_WITH_TXBF_AP_MAX ), +#endif + + REG_VARIABLE_STRING( CFG_LIST_OF_NON_DFS_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, listOfNonDfsCountryCode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + (void *)CFG_LIST_OF_NON_DFS_COUNTRY_CODE_DEFAULT), + + REG_DYNAMIC_VARIABLE( CFG_ENABLE_SSR, WLAN_PARAM_Integer, + hdd_config_t, enableSSR, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SSR_DEFAULT, + CFG_ENABLE_SSR_MIN, + CFG_ENABLE_SSR_MAX, + cbNotifySetEnableSSR, 0 ), + + REG_VARIABLE_STRING( CFG_LIST_OF_NON_11AC_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, listOfNon11acCountryCode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + (void *)CFG_LIST_OF_NON_11AC_COUNTRY_CODE_DEFAULT), + + REG_VARIABLE(CFG_MAX_MEDIUM_TIME, WLAN_PARAM_Integer, + hdd_config_t, cfgMaxMediumTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_MEDIUM_TIME_STADEFAULT, + CFG_MAX_MEDIUM_TIME_STAMIN, + CFG_MAX_MEDIUM_TIME_STAMAX ), + + REG_VARIABLE( CFG_ENABLE_TRAFFIC_MONITOR, WLAN_PARAM_Integer, + hdd_config_t, enableTrafficMonitor, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_TRAFFIC_MONITOR_DEFAULT, + CFG_ENABLE_TRAFFIC_MONITOR_MIN, + CFG_ENABLE_TRAFFIC_MONITOR_MAX), + + REG_VARIABLE( CFG_TRAFFIC_IDLE_TIMEOUT, WLAN_PARAM_Integer, + hdd_config_t, trafficIdleTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TRAFFIC_IDLE_TIMEOUT_DEFAULT, + CFG_TRAFFIC_IDLE_TIMEOUT_MIN, + CFG_TRAFFIC_IDLE_TIMEOUT_MAX), + +#ifdef WLAN_FEATURE_11AC + REG_VARIABLE( CFG_ENABLE_VHT_FOR_24GHZ_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableVhtFor24GHzBand, + VAR_FLAGS_OPTIONAL, + CFG_ENABLE_VHT_FOR_24GHZ_DEFAULT, + CFG_ENABLE_VHT_FOR_24GHZ_MIN, + CFG_ENABLE_VHT_FOR_24GHZ_MAX), +#endif + + REG_VARIABLE( CFG_SCAN_OFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, fScanOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SCAN_OFFLOAD_DEFAULT, + CFG_SCAN_OFFLOAD_DISABLE, + CFG_SCAN_OFFLOAD_ENABLE ), + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + REG_DYNAMIC_VARIABLE( CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY, WLAN_PARAM_Integer, + hdd_config_t, bFastRoamInConIniFeatureEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_DEFAULT, + CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MIN, + CFG_ENABLE_FAST_ROAM_IN_CONCURRENCY_MAX, + cbNotifySetEnableFastRoamInConcurrency, 0 ), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED, WLAN_PARAM_Integer, + hdd_config_t, isPERRoamEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED_DEFAULT, + CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED_MIN, + CFG_PER_ROAM_SCAN_OFFLOAD_ENABLED_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, rateUpThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD_DEFAULT, + CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD_MIN, + CFG_PER_ROAM_SCAN_RATE_UP_THRESHOLD_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, rateDownThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD_DEFAULT, + CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD_MIN, + CFG_PER_ROAM_SCAN_RATE_DOWN_THRESHOLD_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_WAIT_TIME, WLAN_PARAM_Integer, + hdd_config_t, waitPeriodForNextPERScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_WAIT_TIME_DEFAULT, + CFG_PER_ROAM_SCAN_WAIT_TIME_MIN, + CFG_PER_ROAM_SCAN_WAIT_TIME_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD, WLAN_PARAM_Integer, + hdd_config_t, PERtimerThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD_DEFAULT, + CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD_MIN, + CFG_PER_ROAM_SCAN_PER_TIME_THRESHOLD_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED, WLAN_PARAM_Integer, + hdd_config_t, isPERRoamRxPathEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED_DEFAULT, + CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED_MIN, + CFG_PER_ROAM_SCAN_RX_MONITOR_ENABLED_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_MIN_PERCENTAGE, WLAN_PARAM_Integer, + hdd_config_t, PERroamTriggerPercent, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_MIN_PERCENTAGE_DEFAULT, + CFG_PER_ROAM_SCAN_MIN_PERCENTAGE_MIN, + CFG_PER_ROAM_SCAN_MIN_PERCENTAGE_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_RX_MIN_PACKETS, WLAN_PARAM_Integer, + hdd_config_t, PERroamRxPktsThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_RX_MIN_PACKETS_DEFAULT, + CFG_PER_ROAM_SCAN_RX_MIN_PACKETS_MIN, + CFG_PER_ROAM_SCAN_RX_MIN_PACKETS_MAX), + + REG_VARIABLE(CFG_PER_ROAM_SCAN_CCA_ENABLED, WLAN_PARAM_Integer, + hdd_config_t, isPERRoamCCAEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_SCAN_CCA_ENABLED_DEFAULT, + CFG_PER_ROAM_SCAN_CCA_ENABLED_MIN, + CFG_PER_ROAM_SCAN_CCA_ENABLED_MAX), + + REG_VARIABLE(CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD, WLAN_PARAM_SignedInteger, + hdd_config_t, PERRoamFullScanThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD_DEFAULT, + CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD_MIN, + CFG_PER_ROAM_FULL_SCAN_RSSI_THRESHOLD_MAX), + + REG_VARIABLE(CFG_PER_ROAM_BAD_RSSI, WLAN_PARAM_SignedInteger, + hdd_config_t, PERMinRssiThresholdForRoam, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PER_ROAM_BAD_RSSI_DEFAULT, + CFG_PER_ROAM_BAD_RSSI_MIN, + CFG_PER_ROAM_BAD_RSSI_MAX), +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + REG_VARIABLE(CFG_ENABLE_LFR_MBB, WLAN_PARAM_Integer, + hdd_config_t, enable_lfr_mbb, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_LFR_MBB_DEFAULT, + CFG_ENABLE_LFR_MBB_MIN, + CFG_ENABLE_LFR_MBB_MAX ), +#endif + + REG_VARIABLE( CFG_ENABLE_ADAPT_RX_DRAIN_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableAdaptRxDrain, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_ENABLE_ADAPT_RX_DRAIN_DEFAULT, + CFG_ENABLE_ADAPT_RX_DRAIN_MIN, + CFG_ENABLE_ADAPT_RX_DRAIN_MAX), + + REG_VARIABLE( CFG_DYNAMIC_SPLIT_SCAN_NAME, WLAN_PARAM_Integer, + hdd_config_t, dynSplitscan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DYNAMIC_SPLIT_SCAN_DEFAULT, + CFG_DYNAMIC_SPLIT_SCAN_MIN, + CFG_DYNAMIC_SPLIT_SCAN_MAX ), + + REG_VARIABLE( CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, txRxThresholdForSplitScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MIN, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_THRSHLD_MAX ), + + REG_VARIABLE( CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_NAME, WLAN_PARAM_Integer, + hdd_config_t, trafficMntrTmrForSplitScan, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_DEFAULT, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MIN, + CFG_SPLIT_SCAN_TRAFFIC_MONITOR_TIMER_MAX ), + + REG_VARIABLE( CFG_FLEX_CONNECT_POWER_FACTOR_NAME, WLAN_PARAM_Integer, + hdd_config_t, flexConnectPowerFactor, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_MINMAX, + CFG_FLEX_CONNECT_POWER_FACTOR_DEFAULT, + CFG_FLEX_CONNECT_POWER_FACTOR_MIN, + CFG_FLEX_CONNECT_POWER_FACTOR_MAX ), + + REG_VARIABLE( CFG_ENABLE_HEART_BEAT_OFFLOAD, WLAN_PARAM_Integer, + hdd_config_t, enableIbssHeartBeatOffload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HEART_BEAT_OFFLOAD_DEFAULT, + CFG_ENABLE_HEART_BEAT_OFFLOAD_MIN, + CFG_ENABLE_HEART_BEAT_OFFLOAD_MAX), + + REG_VARIABLE( CFG_ANTENNA_DIVERSITY_PARAM_NAME, WLAN_PARAM_Integer, + hdd_config_t, antennaDiversity, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ANTENNA_DIVERSITY_PARAM_DEFAULT, + CFG_ANTENNA_DIVERSITY_PARAM_MIN, + CFG_ANTENNA_DIVERSITY_PARAM_MAX), + + REG_VARIABLE( CFG_ENABLE_SNR_MONITORING_NAME, WLAN_PARAM_Integer, + hdd_config_t, fEnableSNRMonitoring, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK , + CFG_ENABLE_SNR_MONITORING_DEFAULT, + CFG_ENABLE_SNR_MONITORING_MIN, + CFG_ENABLE_SNR_MONITORING_MAX), + +#ifdef FEATURE_WLAN_SCAN_PNO + REG_VARIABLE( CFG_PNO_SCAN_SUPPORT, WLAN_PARAM_Integer, + hdd_config_t, configPNOScanSupport, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PNO_SCAN_SUPPORT_DEFAULT, + CFG_PNO_SCAN_SUPPORT_DISABLE, + CFG_PNO_SCAN_SUPPORT_ENABLE), + + REG_VARIABLE( CFG_PNO_SCAN_TIMER_REPEAT_VALUE, WLAN_PARAM_Integer, + hdd_config_t, configPNOScanTimerRepeatValue, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PNO_SCAN_TIMER_REPEAT_VALUE_DEFAULT, + CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MIN, + CFG_PNO_SCAN_TIMER_REPEAT_VALUE_MAX), +#endif + REG_VARIABLE( CFG_AMSDU_SUPPORT_IN_AMPDU_NAME , WLAN_PARAM_Integer, + hdd_config_t, isAmsduSupportInAMPDU, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_AMSDU_SUPPORT_IN_AMPDU_DEFAULT, + CFG_AMSDU_SUPPORT_IN_AMPDU_MIN, + CFG_AMSDU_SUPPORT_IN_AMPDU_MAX ), + + REG_VARIABLE( CFG_STRICT_5GHZ_PREF_BY_MARGIN , WLAN_PARAM_Integer, + hdd_config_t, nSelect5GHzMargin, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_STRICT_5GHZ_PREF_BY_MARGIN_DEFAULT, + CFG_STRICT_5GHZ_PREF_BY_MARGIN_MIN, + CFG_STRICT_5GHZ_PREF_BY_MARGIN_MAX ), + + REG_VARIABLE( CFG_COALESING_IN_IBSS_NAME , WLAN_PARAM_Integer, + hdd_config_t, isCoalesingInIBSSAllowed, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_COALESING_IN_IBSS_DEFAULT, + CFG_COALESING_IN_IBSS_MIN, + CFG_COALESING_IN_IBSS_MAX ), + + REG_VARIABLE( CFG_DISABLE_ATH_NAME , WLAN_PARAM_Integer, + hdd_config_t, cfgAthDisable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_ATH_DEFAULT, + CFG_DISABLE_ATH_MIN, + CFG_DISABLE_ATH_MAX ), + REG_VARIABLE(CFG_BTC_ACTIVE_WLAN_LEN_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcActiveWlanLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_ACTIVE_WLAN_LEN_DEFAULT, + CFG_BTC_ACTIVE_WLAN_LEN_MIN, + CFG_BTC_ACTIVE_WLAN_LEN_MAX ), + + REG_VARIABLE(CFG_BTC_ACTIVE_BT_LEN_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcActiveBtLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_ACTIVE_BT_LEN_DEFAULT, + CFG_BTC_ACTIVE_BT_LEN_MIN, + CFG_BTC_ACTIVE_BT_LEN_MAX ), + + REG_VARIABLE(CFG_BTC_SAP_ACTIVE_WLAN_LEN_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcSapActiveWlanLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_SAP_ACTIVE_WLAN_LEN_DEFAULT, + CFG_BTC_SAP_ACTIVE_WLAN_LEN_MIN, + CFG_BTC_SAP_ACTIVE_WLAN_LEN_MAX ), + + REG_VARIABLE(CFG_BTC_SAP_ACTIVE_BT_LEN_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcSapActiveBtLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_SAP_ACTIVE_BT_LEN_DEFAULT, + CFG_BTC_SAP_ACTIVE_BT_LEN_MIN, + CFG_BTC_SAP_ACTIVE_BT_LEN_MAX ), + +#ifdef MEMORY_DEBUG + REG_VARIABLE(CFG_ENABLE_MEMORY_DEBUG_NAME, WLAN_PARAM_Integer, + hdd_config_t, IsMemoryDebugSupportEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MEMORY_DEBUG_DEFAULT, + CFG_ENABLE_MEMORY_DEBUG_MIN, + CFG_ENABLE_MEMORY_DEBUG_MAX ), +#endif + + REG_VARIABLE_STRING( CFG_OVERRIDE_COUNTRY_CODE, WLAN_PARAM_String, + hdd_config_t, overrideCountryCode, + VAR_FLAGS_OPTIONAL, + (void *)CFG_OVERRIDE_COUNTRY_CODE_DEFAULT), + + REG_VARIABLE( CFG_ASD_PROBE_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, gAsdProbeInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ASD_PROBE_INTERVAL_DEFAULT, + CFG_ASD_PROBE_INTERVAL_MIN, + CFG_ASD_PROBE_INTERVAL_MAX), + + REG_VARIABLE( CFG_ASD_TRIGGER_THRESHOLD_NAME, WLAN_PARAM_SignedInteger, + hdd_config_t, gAsdTriggerThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ASD_TRIGGER_THRESHOLD_DEFAULT, + CFG_ASD_TRIGGER_THRESHOLD_MIN, + CFG_ASD_TRIGGER_THRESHOLD_MAX), + + REG_VARIABLE( CFG_ASD_RTT_RSSI_HYST_THRESHOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, gAsdRTTRssiHystThreshold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ASD_RTT_RSSI_HYST_THRESHOLD_DEFAULT, + CFG_ASD_RTT_RSSI_HYST_THRESHOLD_MIN, + CFG_ASD_RTT_RSSI_HYST_THRESHOLD_MAX), + + REG_VARIABLE( CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_NAME, WLAN_PARAM_Integer, + hdd_config_t, debugP2pRemainOnChannel, + VAR_FLAGS_OPTIONAL, + CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_DEFAULT, + CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MIN, + CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_MAX ), + + REG_VARIABLE(CFG_CTS2S_DURING_BTC_SCO_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcCTS2SduringSCO, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_CTS2S_DURING_BTC_SCO_DEFAULT, + CFG_CTS2S_DURING_BTC_SCO_MIN, + CFG_CTS2S_DURING_BTC_SCO_MAX ), + + REG_VARIABLE( CFG_ENABLE_DEBUG_CONNECT_ISSUE, WLAN_PARAM_Integer, + hdd_config_t, gEnableDebugLog, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT, + CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN , + CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX), + + REG_VARIABLE(CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nOBSSScanActiveDwellTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_DEFAULT, + CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_MIN, + CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_MAX ), + + REG_VARIABLE(CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nOBSSScanPassiveDwellTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_DEFAULT, + CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_MIN, + CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_MAX ), + + REG_VARIABLE(CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_NAME, + WLAN_PARAM_Integer, + hdd_config_t, nOBSSScanWidthTriggerInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_DEFAULT, + CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_MIN, + CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_MAX ), + + REG_VARIABLE( CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_NAME, WLAN_PARAM_Integer, + hdd_config_t, gEnableStrictRegulatoryForFCC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_DEFAULT, + CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MIN, + CFG_ENABLE_STRICT_REGULATORY_FOR_FCC_MAX ), + + REG_VARIABLE( CFG_ADVERTISE_CONCURRENT_OPERATION_NAME , WLAN_PARAM_Integer, + hdd_config_t, advertiseConcurrentOperation, + VAR_FLAGS_OPTIONAL, + CFG_ADVERTISE_CONCURRENT_OPERATION_DEFAULT, + CFG_ADVERTISE_CONCURRENT_OPERATION_MIN, + CFG_ADVERTISE_CONCURRENT_OPERATION_MAX ), + + REG_VARIABLE( CFG_DEFAULT_RATE_INDEX_24GH, WLAN_PARAM_Integer, + hdd_config_t, defaultRateIndex24Ghz, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DEFAULT_RATE_INDEX_24GH_DEFAULT, + CFG_DEFAULT_RATE_INDEX_24GH_MIN, + CFG_DEFAULT_RATE_INDEX_24GH_MAX ), + + REG_VARIABLE( CFG_SAP_ENABLE_11AC_NAME, WLAN_PARAM_Integer, + hdd_config_t, sapEnable11AC, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_ENABLE_11AC_DEFAULT, + CFG_SAP_ENABLE_11AC_MIN, + CFG_SAP_ENABLE_11AC_MAX ), + + REG_VARIABLE(CFG_RA_FILTER_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgRAFilterEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RA_FILTER_ENABLE_DEFAULT, + CFG_RA_FILTER_ENABLE_MIN, + CFG_RA_FILTER_ENABLE_MAX ), + + REG_VARIABLE(CFG_RA_RATE_LIMIT_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgRARateLimitInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RA_RATE_LIMIT_INTERVAL_DEFAULT, + CFG_RA_RATE_LIMIT_INTERVAL_MIN, + CFG_RA_RATE_LIMIT_INTERVAL_MAX ), + + REG_VARIABLE( CFG_ROAMING_DFS_CHANNEL_NAME , WLAN_PARAM_Integer, + hdd_config_t, allowDFSChannelRoam, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAMING_DFS_CHANNEL_DEFAULT, + CFG_ROAMING_DFS_CHANNEL_MIN, + CFG_ROAMING_DFS_CHANNEL_MAX ), + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + REG_VARIABLE( CFG_WLAN_LOGGING_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanLoggingEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_LOGGING_SUPPORT_DEFAULT, + CFG_WLAN_LOGGING_SUPPORT_DISABLE, + CFG_WLAN_LOGGING_SUPPORT_ENABLE ), + + REG_VARIABLE( CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanLoggingFEToConsole, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DEFAULT, + CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_DISABLE, + CFG_WLAN_LOGGING_FE_CONSOLE_SUPPORT_ENABLE ), + + REG_VARIABLE( CFG_WLAN_LOGGING_NUM_BUF_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanLoggingNumBuf, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_LOGGING_NUM_BUF_DEFAULT, + CFG_WLAN_LOGGING_NUM_BUF_MIN, + CFG_WLAN_LOGGING_NUM_BUF_MAX ), + + REG_VARIABLE( CFG_WLAN_PKT_STATS_LOGGING_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanPerPktStatsLogEnable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_PKT_STATS_LOGGING_DEFAULT, + CFG_WLAN_PKT_STATS_LOGGING_DISABLE, + CFG_WLAN_PKT_STATS_LOGGING_ENABLE ), + + REG_VARIABLE( CFG_WLAN_PKT_STATS_NUM_BUF_NAME, WLAN_PARAM_Integer, + hdd_config_t, wlanPerPktStatsNumBuf, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WLAN_PKT_STATS_NUM_BUF_DEFAULT, + CFG_WLAN_PKT_STATS_NUM_BUF_MIN, + CFG_WLAN_PKT_STATS_NUM_BUF_MAX ), + +#endif //WLAN_LOGGING_SOCK_SVC_ENABLE + + REG_VARIABLE( CFG_IGNORE_PEER_ERP_INFO_NAME, WLAN_PARAM_Integer, + hdd_config_t, ignorePeerErpInfo, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_PEER_ERP_INFO_DEFAULT, + CFG_IGNORE_PEER_ERP_INFO_MIN, + CFG_IGNORE_PEER_ERP_INFO_MAX ), + + REG_VARIABLE( CFG_IGNORE_PEER_HT_MODE_NAME, WLAN_PARAM_Integer, + hdd_config_t, ignorePeerHTopMode, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_IGNORE_PEER_HT_MODE_DEFAULT, + CFG_IGNORE_PEER_HT_MODE_MIN, + CFG_IGNORE_PEER_HT_MODE_MAX ), + + REG_VARIABLE(CFG_INITIAL_DWELL_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, nInitialDwellTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INITIAL_DWELL_TIME_DEFAULT, + CFG_INITIAL_DWELL_TIME_MIN, + CFG_INITIAL_DWELL_TIME_MAX ), + + REG_VARIABLE(CFG_INITIAL_SCAN_SKIP_DFS_CH_NAME, WLAN_PARAM_Integer, + hdd_config_t, initialScanSkipDFSCh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_INITIAL_SCAN_SKIP_DFS_CH_DEFAULT, + CFG_INITIAL_SCAN_SKIP_DFS_CH_MIN, + CFG_INITIAL_SCAN_SKIP_DFS_CH_MAX), + + REG_VARIABLE(CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcFatalHidnSniffBlkGuidance, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_DEFAULT, + CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_MIN, + CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_MAX ), + + REG_VARIABLE(CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcCriticalHidnSniffBlkGuidance, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_DEFAULT, + CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_MIN, + CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_MAX ), + + REG_VARIABLE(CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcA2dpTxQueueThold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_DEFAULT, + CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_MIN, + CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_MAX ), + + REG_VARIABLE(CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_NAME, WLAN_PARAM_Integer, + hdd_config_t, cfgBtcOppTxQueueThold, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_DEFAULT, + CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_MIN, + CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_MAX ), + +#ifdef WLAN_FEATURE_11W + REG_VARIABLE(CFG_PMF_SA_QUERY_MAX_RETRIES_NAME, WLAN_PARAM_Integer, + hdd_config_t, pmfSaQueryMaxRetries, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PMF_SA_QUERY_MAX_RETRIES_DEFAULT, + CFG_PMF_SA_QUERY_MAX_RETRIES_MIN, + CFG_PMF_SA_QUERY_MAX_RETRIES_MAX ), + + REG_VARIABLE(CFG_PMF_SA_QUERY_RETRY_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, pmfSaQueryRetryInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_PMF_SA_QUERY_RETRY_INTERVAL_DEFAULT, + CFG_PMF_SA_QUERY_RETRY_INTERVAL_MIN, + CFG_PMF_SA_QUERY_RETRY_INTERVAL_MAX ), +#endif + + REG_VARIABLE(CFG_DEFER_IMPS_FOR_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, deferImpsTime, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DEFER_IMPS_FOR_TIME_DEFAULT, + CFG_DEFER_IMPS_FOR_TIME_MIN, + CFG_DEFER_IMPS_FOR_TIME_MAX), + + REG_VARIABLE(CFG_ENABLE_DEAUTH_BEFORE_CONNECTION, WLAN_PARAM_Integer, + hdd_config_t, sendDeauthBeforeCon, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_DEFAULT, + CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MIN, + CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MAX), + + REG_VARIABLE(CFG_ENABLE_MAC_ADDR_SPOOFING, WLAN_PARAM_Integer, + hdd_config_t, enableMacSpoofing, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT, + CFG_ENABLE_MAC_ADDR_SPOOFING_MIN, + CFG_ENABLE_MAC_ADDR_SPOOFING_MAX), + + REG_VARIABLE(CFG_DISABLE_P2P_MAC_ADDR_SPOOFING, WLAN_PARAM_Integer, + hdd_config_t, disableP2PMacSpoofing, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_P2P_MAC_ADDR_SPOOFING_DEFAULT, + CFG_DISABLE_P2P_MAC_ADDR_SPOOFING_MIN, + CFG_DISABLE_P2P_MAC_ADDR_SPOOFING_MAX), + + REG_VARIABLE(CFG_ENABLE_FATAL_EVENT_TRIGGER, WLAN_PARAM_Integer, + hdd_config_t, enableFatalEvent, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FATAL_EVENT_TRIGGER_DEFAULT, + CFG_ENABLE_FATAL_EVENT_TRIGGER_MIN, + CFG_ENABLE_FATAL_EVENT_TRIGGER_MAX), + + REG_VARIABLE(CFG_ENABLE_MGMT_LOGGING, WLAN_PARAM_Integer, + hdd_config_t, enableMgmtLogging, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_MGMT_LOGGING_DEFAULT, + CFG_ENABLE_MGMT_LOGGING_MIN, + CFG_ENABLE_MGMT_LOGGING_MAX), + + REG_VARIABLE(CFG_ENABLE_BMUHW_TRACING, WLAN_PARAM_Integer, + hdd_config_t, enableBMUHWtracing, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_BMUHW_TRACING_DEFAULT, + CFG_ENABLE_BMUHW_TRACING_MIN, + CFG_ENABLE_BMUHW_TRACING_MAX), + + REG_VARIABLE(CFG_ENABLE_FW_LOGGING, WLAN_PARAM_Integer, + hdd_config_t, enableFWLogging, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_LOGGING_DEFAULT, + CFG_ENABLE_FW_LOGGING_MIN, + CFG_ENABLE_FW_LOGGING_MAX), + + REG_VARIABLE(CFG_ENABLE_FW_CONTINIOUS_LOGGING, WLAN_PARAM_Integer, + hdd_config_t, enableContFWLogging, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_FW_CONTINIOUS_LOGGING_DEFAULT, + CFG_ENABLE_FW_CONTINIOUS_LOGGING_MIN, + CFG_ENABLE_FW_CONTINIOUS_LOGGING_MAX), + + REG_VARIABLE(CFG_MIN_LOGGING_BUFFER_SIZE, WLAN_PARAM_Integer, + hdd_config_t, minLoggingBufferSize, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MIN_LOGGING_BUFFER_SIZE_DEFAULT, + CFG_MIN_LOGGING_BUFFER_SIZE_MIN, + CFG_MIN_LOGGING_BUFFER_SIZE_MAX), + + REG_VARIABLE(CFG_MAX_LOGGING_BUFFER_SIZE, WLAN_PARAM_Integer, + hdd_config_t, maxLoggingBufferSize, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_LOGGING_BUFFER_SIZE_DEFAULT, + CFG_MAX_LOGGING_BUFFER_SIZE_MIN, + CFG_MAX_LOGGING_BUFFER_SIZE_MAX), + + REG_VARIABLE(CFG_ENABLE_CH_AVOID, WLAN_PARAM_Integer, + hdd_config_t, fenableCHAvoidance, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_CH_AVOID_DEFAULT, + CFG_ENABLE_CH_AVOID_MIN, + CFG_ENABLE_CH_AVOID_MAX ), + + REG_VARIABLE(CFG_MAX_CONCURRENT_CONNECTIONS_NAME, WLAN_PARAM_Integer, + hdd_config_t, gMaxConcurrentActiveSessions, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_CONCURRENT_CONNECTIONS_DEFAULT, + CFG_MAX_CONCURRENT_CONNECTIONS_MIN, + CFG_MAX_CONCURRENT_CONNECTIONS_MAX ), + +#ifdef WLAN_FEATURE_AP_HT40_24G + REG_VARIABLE(CFG_ENABLE_HT_2040_COEX, WLAN_PARAM_Integer, + hdd_config_t, apHT40_24GEnabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_HT_2040_COEX_DEFAULT, + CFG_ENABLE_HT_2040_COEX_MIN, + CFG_ENABLE_HT_2040_COEX_MAX ), +#endif + + REG_VARIABLE( CFG_ENABLE_DYNAMIC_WMMPS_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDynamicWMMPS, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DYNAMIC_WMM_PS_DEFAULT, + CFG_ENABLE_DYNAMIC_WMM_PS_MIN, + CFG_ENABLE_DYNAMIC_WMM_PS_MAX ), + + REG_VARIABLE( CFG_MAX_UAPSD_CONSEC_SP_NAME, WLAN_PARAM_Integer, + hdd_config_t, maxUapsdConsecSP, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_UAPSD_CONSEC_SP_DEFAULT, + CFG_MAX_UAPSD_CONSEC_SP_MIN, + CFG_MAX_UAPSD_CONSEC_SP_MAX ), + + REG_VARIABLE( CFG_MAX_UAPSD_CONSEC_RX_CNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, maxUapsdConsecRxCnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_UAPSD_CONSEC_RX_CNT_DEFAULT, + CFG_MAX_UAPSD_CONSEC_RX_CNT_MIN, + CFG_MAX_UAPSD_CONSEC_RX_CNT_MAX ), + + REG_VARIABLE( CFG_MAX_UAPSD_CONSEC_TX_CNT_NAME, WLAN_PARAM_Integer, + hdd_config_t, maxUapsdConsecTxCnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_UAPSD_CONSEC_TX_CNT_DEFAULT, + CFG_MAX_UAPSD_CONSEC_TX_CNT_MIN, + CFG_MAX_UAPSD_CONSEC_TX_CNT_MAX ), + + REG_VARIABLE( CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_NAME, WLAN_PARAM_Integer, + hdd_config_t, uapsdConsecRxCntMeasWindow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_DEFAULT, + CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_MIN, + CFG_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_MAX ), + + REG_VARIABLE( CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_NAME, WLAN_PARAM_Integer, + hdd_config_t, uapsdConsecTxCntMeasWindow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_DEFAULT, + CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_MIN, + CFG_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_MAX ), + + REG_VARIABLE( CFG_UAPSD_PSPOLL_NAME, WLAN_PARAM_Integer, + hdd_config_t, maxPsPollInWmmUapsdMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_UAPSD_PSPOLL_DEFAULT, + CFG_UAPSD_PSPOLL_MIN, + CFG_UAPSD_PSPOLL_MAX ), + + REG_VARIABLE( CFG_MAX_UAPSD_INACT_INTVL_NAME, WLAN_PARAM_Integer, + hdd_config_t, maxUapsdInactivityIntervals, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_UAPSD_INACT_INTVL_DEFAULT, + CFG_MAX_UAPSD_INACT_INTVL_MIN, + CFG_MAX_UAPSD_INACT_INTVL_MAX ), + + REG_VARIABLE( CFG_BURST_MODE_BE_TXOP_VALUE, WLAN_PARAM_Integer, + hdd_config_t, burstModeTXOPValue, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BURST_MODE_BE_TXOP_VALUE_DEFAULT, + CFG_BURST_MODE_BE_TXOP_VALUE_MIN, + CFG_BURST_MODE_BE_TXOP_VALUE_MAX ), + REG_VARIABLE( CFG_SAP_SCAN_BAND_PREFERENCE, WLAN_PARAM_Integer, + hdd_config_t, acsScanBandPreference, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT, + CFG_SAP_SCAN_BAND_PREFERENCE_MIN, + CFG_SAP_SCAN_BAND_PREFERENCE_MAX ), + + REG_VARIABLE( CFG_ENABLE_DYNAMIC_RA_START_RATE_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableDynamicRAStartRate, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DYNAMIC_RA_START_RATE_DEFAULT, + CFG_ENABLE_DYNAMIC_RA_START_RATE_MIN, + CFG_ENABLE_DYNAMIC_RA_START_RATE_MAX), + + REG_VARIABLE( CFG_P2P_LISTEN_DEFER_INTERVAL_NAME, WLAN_PARAM_Integer, + hdd_config_t, gP2PListenDeferInterval, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_P2P_LISTEN_DEFER_INTERVAL_DEFAULT, + CFG_P2P_LISTEN_DEFER_INTERVAL_MIN, + CFG_P2P_LISTEN_DEFER_INTERVAL_MAX), + + REG_VARIABLE( CFG_BTC_ENABLE_IND_TIMER_VALUE, WLAN_PARAM_Integer, + hdd_config_t, btcEnableIndTimerVal, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_ENABLE_IND_TIMER_VALUE_DEFAULT, + CFG_BTC_ENABLE_IND_TIMER_VALUE_MIN, + CFG_BTC_ENABLE_IND_TIMER_VALUE_MAX), + + REG_VARIABLE( CFG_BTC_FAST_WLAN_CONN_PREF , WLAN_PARAM_Integer, + hdd_config_t, btcFastWlanConnPref, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_FAST_WLAN_CONN_PREF_DEFAULT, + CFG_BTC_FAST_WLAN_CONN_PREF_MIN, + CFG_BTC_FAST_WLAN_CONN_PREF_MAX ), + + REG_VARIABLE( CFG_ENABLE_RTSCTS_HTVHT_NAME, WLAN_PARAM_Integer, + hdd_config_t, enableRtsCtsHtVht, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_RTSCTS_HTVHT_DEFAULT, + CFG_ENABLE_RTSCTS_HTVHT_MIN, + CFG_ENABLE_RTSCTS_HTVHT_MAX), + + REG_VARIABLE( CFG_DXE_REPLENISH_RX_TIMER_VALUE, WLAN_PARAM_Integer, + hdd_config_t, dxeReplenishRXTimerVal, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DXE_REPLENISH_RX_TIMER_VALUE_DEFAULT, + CFG_DXE_REPLENISH_RX_TIMER_VALUE_MIN, + CFG_DXE_REPLENISH_RX_TIMER_VALUE_MAX ), + + REG_VARIABLE( CFG_DXE_SSR_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, dxeSSREnable, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DXE_SSR_ENABLE_DEFAULT, + CFG_DXE_SSR_ENABLE_MIN, + CFG_DXE_SSR_ENABLE_MAX ), + + REG_VARIABLE( CFG_MULTICAST_HOST_FW_MSGS, WLAN_PARAM_Integer, + hdd_config_t, multicast_host_msgs, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MULTICAST_HOST_FW_MSGS_DEFAULT, + CFG_MULTICAST_HOST_FW_MSGS_MIN, + CFG_MULTICAST_HOST_FW_MSGS_MAX), + + REG_VARIABLE( CFG_TOGGLE_ARP_BDRATES_NAME, WLAN_PARAM_Integer, + hdd_config_t, toggleArpBDRates, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TOGGLE_ARP_BDRATES_DEFAULT, + CFG_TOGGLE_ARP_BDRATES_MIN, + CFG_TOGGLE_ARP_BDRATES_MAX), + + REG_VARIABLE( CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN , WLAN_PARAM_Integer, + hdd_config_t, btcStaticOppWlanIdleWlanLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_DEFAULT, + CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MIN, + CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MAX ), + + REG_VARIABLE( CFG_BTC_DISABLE_WLAN_LINK_CRITICAL , WLAN_PARAM_Integer, + hdd_config_t, btc_disable_wlan_link_critical, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEFAULT, + CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN, + CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX ), + + REG_VARIABLE( CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN , WLAN_PARAM_Integer, + hdd_config_t, btcStaticOppWlanIdleBtLen, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEFAULT, + CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MIN, + CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX ), + + REG_VARIABLE( CFG_TCP_DELACK_COMPUTE_INTERVAL, WLAN_PARAM_Integer, + hdd_config_t, tcpDelAckComputeInterval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TCP_DELACK_COMPUTE_INTERVAL_DEFAULT, + CFG_TCP_DELACK_COMPUTE_INTERVAL_MIN, + CFG_TCP_DELACK_COMPUTE_INTERVAL_MAX), + + REG_VARIABLE( CFG_TCP_DELACK_THRESHOLD_HIGH, WLAN_PARAM_Integer, + hdd_config_t, tcpDelAckThresholdHigh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_HIGH_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_HIGH_MIN, + CFG_TCP_DELACK_THRESHOLD_HIGH_MAX ), + + REG_VARIABLE( CFG_TCP_DELACK_THRESHOLD_LOW, WLAN_PARAM_Integer, + hdd_config_t, tcpDelAckThresholdLow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_LOW_DEFAULT, + CFG_TCP_DELACK_THRESHOLD_LOW_MIN, + CFG_TCP_DELACK_THRESHOLD_LOW_MAX ), + + REG_VARIABLE( CFG_LINK_FAIL_TIMEOUT_NAME , WLAN_PARAM_Integer, + hdd_config_t, linkFailTimeout, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_FAIL_TIMEOUT_DEF, + CFG_LINK_FAIL_TIMEOUT_MIN, + CFG_LINK_FAIL_TIMEOUT_MAX ), + + REG_VARIABLE( CFG_LINK_FAIL_TX_CNT_NAME , WLAN_PARAM_Integer, + hdd_config_t, linkFailTxCnt, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_LINK_FAIL_TX_CNT_DEF, + CFG_LINK_FAIL_TX_CNT_MIN, + CFG_LINK_FAIL_TX_CNT_MAX ), + + REG_VARIABLE( CFG_OPTIMIZE_CA_EVENT_NAME, WLAN_PARAM_Integer, + hdd_config_t, gOptimizeCAevent, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_OPTIMIZE_CA_EVENT_DEFAULT, + CFG_OPTIMIZE_CA_EVENT_DISABLE, + CFG_OPTIMIZE_CA_EVENT_ENABLE ), + + REG_VARIABLE(CFG_FWR_MEM_DUMP_NAME, WLAN_PARAM_Integer, + hdd_config_t,enableFwrMemDump, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_FWR_MEM_DUMP_DEF, + CFG_FWR_MEM_DUMP_MIN, + CFG_FWR_MEM_DUMP_MAX), + + REG_VARIABLE( CFG_ACTIVE_PASSIVE_CHAN_CONV_NAME, WLAN_PARAM_Integer, + hdd_config_t, gActivePassiveChCon, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ACTIVE_PASSIVE_CHAN_CONV_DEF, + CFG_ACTIVE_PASSIVE_CHAN_CONV_MIN, + CFG_ACTIVE_PASSIVE_CHAN_CONV_MAX ), + + REG_VARIABLE( CFG_EXT_SCAN_CONC_MODE , WLAN_PARAM_Integer, + hdd_config_t, cfgExtScanConcMode, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EXT_SCAN_CONC_MODE_DEFAULT, + CFG_EXT_SCAN_CONC_MODE_MIN, + CFG_EXT_SCAN_CONC_MODE_MAX ), + + REG_VARIABLE( CFG_RPS_CPU_MAP_NAME, WLAN_PARAM_HexInteger, + hdd_config_t, rps_mask, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_RPS_CPU_MAP_DEFAULT, + CFG_RPS_CPU_MAP_MIN, + CFG_RPS_CPU_MAP_MAX), + + REG_VARIABLE( CFG_WIFI_CONFIG_ENABLE, WLAN_PARAM_Integer, + hdd_config_t, fEnableWifiConfig, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_WIFI_CONFIG_DEFAULT, + CFG_WIFI_CONFIG_MIN, + CFG_WIFI_CONFIG_MAX ), + + REG_VARIABLE( CFG_ENABLE_CRASH_INJECT, WLAN_PARAM_Integer, + hdd_config_t, crash_inject_enabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_CRASH_INJECT_DEFAULT, + CFG_ENABLE_CRASH_INJECT_MIN, + CFG_ENABLE_CRASH_INJECT_MAX), + + REG_VARIABLE( CFG_ENABLE_TCP_DELACK_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_delack, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_TCP_DELACK_DEFAULT, + CFG_ENABLE_TCP_DELACK_MIN, + CFG_ENABLE_TCP_DELACK_MAX ), + + REG_VARIABLE( CFG_DISABLE_BAR_WAKEUP_HOST_NAME, WLAN_PARAM_Integer, + hdd_config_t, disableBarWakeUp, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_BAR_WAKEUP_HOST_DEFAULT, + CFG_DISABLE_BAR_WAKEUP_HOST_MIN, + CFG_DISABLE_BAR_WAKEUP_HOST_MAX), + + REG_VARIABLE( CFG_MAXCHAN_FOR_CHANTIME_CORR_NAME, WLAN_PARAM_Integer, + hdd_config_t, max_chan_for_dwell_time_cfg, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAXCHAN_FOR_CHANTIME_CORR_DEFAULT, + CFG_MAXCHAN_FOR_CHANTIME_CORR_MIN, + CFG_MAXCHAN_FOR_CHANTIME_CORR_MAX ), + + REG_VARIABLE(CFG_TDLS_ENABLE_DEFER_TIMER, WLAN_PARAM_Integer, + hdd_config_t, tdls_enable_defer_time, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TDLS_ENABLE_DEFER_TIMER_DEFAULT, + CFG_TDLS_ENABLE_DEFER_TIMER_MIN, + CFG_TDLS_ENABLE_DEFER_TIMER_MAX), + + REG_VARIABLE(CFG_SAR_BOFFSET_SET_CORRECTION_NAME, WLAN_PARAM_Integer, + hdd_config_t, boffset_correction_enable, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAR_BOFFSET_SET_CORRECTION_DEFAULT, + CFG_SAR_BOFFSET_SET_CORRECTION_MIN, + CFG_SAR_BOFFSET_SET_CORRECTION_MAX), + + + REG_VARIABLE(CFG_ENABLE_EDCA_INI_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_edca_params, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_EDCA_INI_DEFAULT, + CFG_ENABLE_EDCA_INI_MIN, + CFG_ENABLE_EDCA_INI_MAX), + + REG_VARIABLE(CFG_EDCA_VO_CWMIN_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_vo_cwmin, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_VO_CWMIN_VALUE_DEFAULT, + CFG_EDCA_VO_CWMIN_VALUE_MIN, + CFG_EDCA_VO_CWMIN_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_VI_CWMIN_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_vi_cwmin, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_VI_CWMIN_VALUE_DEFAULT, + CFG_EDCA_VI_CWMIN_VALUE_MIN, + CFG_EDCA_VI_CWMIN_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_BK_CWMIN_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_bk_cwmin, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_BK_CWMIN_VALUE_DEFAULT, + CFG_EDCA_BK_CWMIN_VALUE_MIN, + CFG_EDCA_BK_CWMIN_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_BE_CWMIN_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_be_cwmin, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_BE_CWMIN_VALUE_DEFAULT, + CFG_EDCA_BE_CWMIN_VALUE_MIN, + CFG_EDCA_BE_CWMIN_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_VO_CWMAX_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_vo_cwmax, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_VO_CWMAX_VALUE_DEFAULT, + CFG_EDCA_VO_CWMAX_VALUE_MIN, + CFG_EDCA_VO_CWMAX_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_VI_CWMAX_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_vi_cwmax, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_VI_CWMAX_VALUE_DEFAULT, + CFG_EDCA_VI_CWMAX_VALUE_MIN, + CFG_EDCA_VI_CWMAX_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_BK_CWMAX_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_bk_cwmax, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_BK_CWMAX_VALUE_DEFAULT, + CFG_EDCA_BK_CWMAX_VALUE_MIN, + CFG_EDCA_BK_CWMAX_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_BE_CWMAX_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_be_cwmax, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_BE_CWMAX_VALUE_DEFAULT, + CFG_EDCA_BE_CWMAX_VALUE_MIN, + CFG_EDCA_BE_CWMAX_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_VO_AIFS_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_vo_aifs, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_VO_AIFS_VALUE_DEFAULT, + CFG_EDCA_VO_AIFS_VALUE_MIN, + CFG_EDCA_VO_AIFS_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_VI_AIFS_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_vi_aifs, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_VI_AIFS_VALUE_DEFAULT, + CFG_EDCA_VI_AIFS_VALUE_MIN, + CFG_EDCA_VI_AIFS_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_BK_AIFS_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_bk_aifs, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_BK_AIFS_VALUE_DEFAULT, + CFG_EDCA_BK_AIFS_VALUE_MIN, + CFG_EDCA_BK_AIFS_VALUE_MAX), + + REG_VARIABLE(CFG_EDCA_BE_AIFS_VALUE_NAME, WLAN_PARAM_Integer, + hdd_config_t, edca_be_aifs, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_EDCA_BE_AIFS_VALUE_DEFAULT, + CFG_EDCA_BE_AIFS_VALUE_MIN, + CFG_EDCA_BE_AIFS_VALUE_MAX), + + REG_VARIABLE( CFG_SEND_MGMT_PKT_VIA_WQ5_NAME , WLAN_PARAM_Integer, + hdd_config_t, sendMgmtPktViaWQ5, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SEND_MGMT_PKT_VIA_WQ5_DEF, + CFG_SEND_MGMT_PKT_VIA_WQ5_MIN, + CFG_SEND_MGMT_PKT_VIA_WQ5_MAX ), + + REG_VARIABLE(CFG_SAP_PROBE_RESP_OFFLOAD_NAME, WLAN_PARAM_Integer, + hdd_config_t, sap_probe_resp_offload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_PROBE_RESP_OFFLOAD_DEFAULT, + CFG_SAP_PROBE_RESP_OFFLOAD_MIN, + CFG_SAP_PROBE_RESP_OFFLOAD_MAX), + + REG_VARIABLE(CFG_SAP_INTERNAL_RESTART_NAME, WLAN_PARAM_Integer, + hdd_config_t, sap_internal_restart, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_INTERNAL_RESTART_DEFAULT, + CFG_SAP_INTERNAL_RESTART_MIN, + CFG_SAP_INTERNAL_RESTART_MAX), + + REG_VARIABLE(CFG_DISABLE_SCAN_DURING_SCO, WLAN_PARAM_Integer, + hdd_config_t, disable_scan_during_sco, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DISABLE_SCAN_DURING_SCO_DEFAULT, + CFG_DISABLE_SCAN_DURING_SCO_MIN, + CFG_DISABLE_SCAN_DURING_SCO_MAX ), +#ifdef SAP_AUTH_OFFLOAD + REG_VARIABLE(CFG_ENABLE_SAP_AUTH_OFL_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_sap_auth_offload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_SAP_AUTH_OFL_DEFAULT, + CFG_ENABLE_SAP_AUTH_OFL_MIN, + CFG_ENABLE_SAP_AUTH_OFL_MAX ), + + REG_VARIABLE(CFG_SAP_AUTH_OFL_SECURITY_TYPE_NAME, WLAN_PARAM_Integer, + hdd_config_t, sap_auth_offload_sec_type, + VAR_FLAGS_OPTIONAL | CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT, + CFG_SAP_AUTH_OFL_SECURITY_TYPE_DEFAULT, + CFG_SAP_AUTH_OFL_SECURITY_TYPE_MIN, + CFG_SAP_AUTH_OFL_SECURITY_TYPE_MAX ), + + REG_VARIABLE_STRING(CFG_SAP_AUTH_OFL_KEY_NAME, WLAN_PARAM_String, + hdd_config_t, sap_auth_offload_key, + VAR_FLAGS_OPTIONAL, + (void *) CFG_SAP_AUTH_OFL_KEY_DEFAULT ), +#endif +#ifdef DHCP_SERVER_OFFLOAD + REG_VARIABLE(CFG_DHCP_SERVER_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_dhcp_srv_offload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DHCP_SERVER_OFFLOAD_SUPPORT_DEFAULT, + CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MIN, + CFG_DHCP_SERVER_OFFLOAD_SUPPORT_MAX), + + REG_VARIABLE(CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_NAME, WLAN_PARAM_Integer, + hdd_config_t, dhcp_max_num_clients, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_DEFAULT, + CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MIN, + CFG_DHCP_SERVER_OFFLOAD_NUM_CLIENT_MAX), + + REG_VARIABLE_STRING(CFG_DHCP_SERVER_IP_NAME, WLAN_PARAM_String, + hdd_config_t, dhcp_srv_ip, + VAR_FLAGS_OPTIONAL, + (void *) CFG_DHCP_SERVER_IP_DEFAULT), + + REG_VARIABLE(CFG_DHCP_SERVER_OFFLOAD_START_LSB_NAME, WLAN_PARAM_Integer, + hdd_config_t, dhcp_start_lsb, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DHCP_SERVER_OFFLOAD_START_LSB_DEFAULT, + CFG_DHCP_SERVER_OFFLOAD_START_LSB_MIN, + CFG_DHCP_SERVER_OFFLOAD_START_LSB_MAX), +#endif /* DHCP_SERVER_OFFLOAD */ + REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_INT_NAME, WLAN_PARAM_Integer, + hdd_config_t, max_sched_scan_plan_interval, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_INT_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_INT_MIN, + CFG_MAX_SCHED_SCAN_PLAN_INT_MAX), + + REG_VARIABLE(CFG_MAX_SCHED_SCAN_PLAN_ITRNS_NAME, WLAN_PARAM_Integer, + hdd_config_t, max_sched_scan_plan_iterations, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT, + CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN, + CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX), + +#ifdef MDNS_OFFLOAD + REG_VARIABLE( CFG_MDNS_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, enable_mdns_offload, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MDNS_OFFLOAD_SUPPORT_DEFAULT, + CFG_MDNS_OFFLOAD_SUPPORT_MIN, + CFG_MDNS_OFFLOAD_SUPPORT_MAX ), + + REG_VARIABLE_STRING( CFG_MDNS_FQDN_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_fqdn, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_FQDN_DEFAULT ), + + REG_VARIABLE_STRING( CFG_MDNS_UNIQUE_FQDN_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_uniquefqdn, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_UNIQUE_FQDN_DEFAULT ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_A_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_a, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_A_DEFAULT ), + + REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_A_IPV4_NAME, WLAN_PARAM_HexInteger, + hdd_config_t, mdns_resp_type_a_ipv4, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_A_IPV4_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_A_IPV4_MIN, + CFG_MDNS_RESPONSE_TYPE_A_IPV4_MAX ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_TXT_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_txt, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_TXT_DEFAULT ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_TXT_CNT_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_txt_content, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_TXT_CNT_DEFAULT ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_PTR_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_ptr, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_PTR_DEFAULT ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_PTR_DN_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_ptr_dname, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_PTR_DN_DEFAULT ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_SRV_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_srv, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_SRV_DEFAULT ), + + REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_NAME, WLAN_PARAM_Integer, + hdd_config_t, mdns_resp_type_srv_priority, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MIN, + CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MAX ), + + REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_NAME, WLAN_PARAM_Integer, + hdd_config_t, mdns_resp_type_srv_weight, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MIN, + CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MAX ), + + REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_PORT_NAME, WLAN_PARAM_Integer, + hdd_config_t, mdns_resp_type_srv_port, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_SRV_PORT_DEFAULT, + CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MIN, + CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MAX ), + + REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_SRV_TGT_NAME, WLAN_PARAM_String, + hdd_config_t, mdns_resp_type_srv_target, + VAR_FLAGS_OPTIONAL, + (void *) CFG_MDNS_RESPONSE_TYPE_SRV_TGT_DEFAULT ), +#endif /* MDNS_OFFLOAD */ + + REG_VARIABLE( CFG_STA_AUTH_RETRIES_FOR_CODE17_NAME, WLAN_PARAM_Integer, + hdd_config_t, sta_auth_retries_for_code17, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_STA_AUTH_RETRIES_FOR_CODE17_DEFAULT, + CFG_STA_AUTH_RETRIES_FOR_CODE17_MIN, + CFG_STA_AUTH_RETRIES_FOR_CODE17_MAX ), + + REG_VARIABLE( CFG_TRIGGER_NULLFRAME_BEFORE_HB_NAME, WLAN_PARAM_Integer, + hdd_config_t, trigger_nullframe_before_hb, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEFAULT, + CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN, + CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX ), +}; + +/* + * This function returns a pointer to the character after the occurence + * of a new line character. It also modifies the original string by replacing + * the '\n' character with the null character. + * Function returns NULL if no new line character was found before end of + * string was reached + */ +static char* get_next_line(char* str, char *str_end) +{ + char c; + + if( str == NULL || *str == '\0') { + return NULL; + } + + c = *str; + while(c != '\n' && c != '\0' && c != 0xd) { + str = str + 1; + if (str > str_end) + { + return str; + } + c = *str; + } + + if (c == '\0' ) { + return NULL; + } + else + { + return (str+1); + } + + return NULL; +} + +// look for space. Ascii values to look are - +// 0x09 == horizontal tab +// 0x0a == Newline ("\n") +// 0x0b == vertical tab +// 0x0c == Newpage or feed form. +// 0x0d == carriage return (CR or "\r") +// Null ('\0') should not considered as space. +#define i_isspace(ch) (((ch) >= 0x09 && (ch) <= 0x0d) || (ch) == ' ') + +/* + * This function trims any leading and trailing white spaces + */ +static char *i_trim(char *str) + +{ + char *ptr; + + if(*str == '\0') return str; + + /* Find the first non white-space*/ + for (ptr = str; i_isspace(*ptr); ptr++); + if (*ptr == '\0') + return str; + + /* This is the new start of the string*/ + str = ptr; + + /* Find the last non white-space */ + ptr += strlen(ptr) - 1; + for (; ptr != str && i_isspace(*ptr); ptr--); + /* Null terminate the following character */ + ptr[1] = '\0'; + + return str; +} + + +//Structure to store each entry in qcom_cfg.ini file +typedef struct +{ + char *name; + char *value; +}tCfgIniEntry; + +static VOS_STATUS hdd_apply_cfg_ini( hdd_context_t * pHddCtx, + tCfgIniEntry* iniTable, unsigned long entries); + +#ifdef WLAN_CFG_DEBUG +void dump_cfg_ini (tCfgIniEntry* iniTable, unsigned long entries) +{ + unsigned long i; + + for (i = 0; i < entries; i++) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s entry Name=[%s] value=[%s]", + WLAN_INI_FILE, iniTable[i].name, iniTable[i].value); + } +} +#endif + +/* + * This function reads the qcom_cfg.ini file and + * parses each 'Name=Value' pair in the ini file + */ +VOS_STATUS hdd_parse_config_ini(hdd_context_t* pHddCtx) +{ + int status, i=0; + /** Pointer for firmware image data */ + const struct firmware *fw = NULL; + char *buffer, *line, *pTemp = NULL; + size_t size; + char *name, *value; + /* cfgIniTable is static to avoid excess stack usage */ + static tCfgIniEntry cfgIniTable[MAX_CFG_INI_ITEMS]; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + memset(cfgIniTable, 0, sizeof(cfgIniTable)); + + status = request_firmware(&fw, WLAN_INI_FILE, pHddCtx->parent_dev); + + if(status) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: request_firmware failed %d",__func__, status); + vos_status = VOS_STATUS_E_FAILURE; + goto config_exit; + } + if(!fw || !fw->data || !fw->size) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: %s download failed", + __func__, WLAN_INI_FILE); + vos_status = VOS_STATUS_E_FAILURE; + goto config_exit; + } + + hddLog(VOS_TRACE_LEVEL_INFO , "%s: qcom_cfg.ini Size %zu", __func__, fw->size); + + buffer = (char*)vos_mem_vmalloc(fw->size); + + if(NULL == buffer) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: kmalloc failure",__func__); + release_firmware(fw); + return VOS_STATUS_E_FAILURE; + } + pTemp = buffer; + + vos_mem_copy((void*)buffer,(void *)fw->data, fw->size); + size = fw->size; + + while (buffer != NULL) + { + /* + * get_next_line function used to modify the \n and \r delimiter + * to \0 before returning, without checking if it is over parsing the + * source buffer. So changed the function not to modify the buffer + * passed to it and letting the calling/caller function to take + * care of the return pointer validation and modification of the buffer. + * So validating if the return pointer is not greater than the end + * buffer address and modifying the buffer value. + */ + line = get_next_line(buffer, (pTemp + (fw->size-1))); + if(line >= (pTemp + fw->size)) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: INI file seems to be corrupted", + __func__); + vos_status = VOS_STATUS_E_FAILURE; + goto config_exit; + } + else if(line) { + *(line - 1) = '\0'; + } + + buffer = i_trim(buffer); + + hddLog(LOG1, "%s: item", buffer); + + if(strlen((char*)buffer) == 0 || *buffer == '#') { + buffer = line; + continue; + } + else if(strncmp(buffer, "END", 3) == 0 ) { + break; + } + else + { + name = buffer; + while(*buffer != '=' && *buffer != '\0') + buffer++; + if(*buffer != '\0') { + *buffer++ = '\0'; + i_trim(name); + if(strlen (name) != 0) { + buffer = i_trim(buffer); + if(strlen(buffer)>0) { + value = buffer; + while(!i_isspace(*buffer) && *buffer != '\0') + buffer++; + *buffer = '\0'; + cfgIniTable[i].name= name; + cfgIniTable[i++].value= value; + if(i >= MAX_CFG_INI_ITEMS) { + hddLog(LOGE,"%s: Number of items in %s > %d", + __func__, WLAN_INI_FILE, MAX_CFG_INI_ITEMS); + break; + } + } + } + } + } + buffer = line; + } + + //Loop through the registry table and apply all these configs + vos_status = hdd_apply_cfg_ini(pHddCtx, cfgIniTable, i); + +config_exit: + release_firmware(fw); + vos_mem_vfree(pTemp); + return vos_status; +} + + +static void print_hdd_cfg(hdd_context_t *pHddCtx) +{ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "*********Config values in HDD Adapter*******"); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [RTSThreshold] Value = %u",pHddCtx->cfg_ini->RTSThreshold) ; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [OperatingChannel] Value = [%u]",pHddCtx->cfg_ini->OperatingChannel); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [PowerUsageControl] Value = [%s]",pHddCtx->cfg_ini->PowerUsageControl); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fIsImpsEnabled] Value = [%u]",pHddCtx->cfg_ini->fIsImpsEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [AutoBmpsTimerEnabled] Value = [%u]",pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nAutoBmpsTimerValue] Value = [%u]",pHddCtx->cfg_ini->nAutoBmpsTimerValue); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nVccRssiTrigger] Value = [%u]",pHddCtx->cfg_ini->nVccRssiTrigger); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gIbssBssid] Value =["MAC_ADDRESS_STR"]", + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->IbssBssid.bytes)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [Intf0MacAddress] Value =["MAC_ADDRESS_STR"]", + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [Intf1MacAddress] Value =["MAC_ADDRESS_STR"]", + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[1].bytes)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [Intf2MacAddress] Value =["MAC_ADDRESS_STR"]", + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[2].bytes)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [Intf3MacAddress] Value =["MAC_ADDRESS_STR"]", + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[3].bytes)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApEnableUapsd] value = [%u]",pHddCtx->cfg_ini->apUapsdEnabled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAPCntryCode] Value =[%c%c%c]", + pHddCtx->cfg_ini->apCntryCode[0],pHddCtx->cfg_ini->apCntryCode[1], + pHddCtx->cfg_ini->apCntryCode[2]); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableApProt] value = [%u]", pHddCtx->cfg_ini->apProtEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAPAutoShutOff] Value = [%u]", pHddCtx->cfg_ini->nAPAutoShutOff); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableListenMode] Value = [%u]", pHddCtx->cfg_ini->nEnableListenMode); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApProtection] value = [%u]",pHddCtx->cfg_ini->apProtection); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableApOBSSProt] value = [%u]",pHddCtx->cfg_ini->apOBSSProtEnabled); + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApAutoChannelSelection] value = [%u]",pHddCtx->cfg_ini->apAutoChannelSelection); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ChannelBondingMode] Value = [%u]",pHddCtx->cfg_ini->nChannelBondingMode24GHz); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [%s] Value = [%u] ", + CFG_OVERRIDE_HT40_20_24GHZ_NAME, pHddCtx->cfg_ini->override_ht20_40_24g); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ChannelBondingMode] Value = [%u]",pHddCtx->cfg_ini->nChannelBondingMode5GHz); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [dot11Mode] Value = [%u]",pHddCtx->cfg_ini->dot11Mode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WmmMode] Value = [%u] ",pHddCtx->cfg_ini->WmmMode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [UapsdMask] Value = [0x%x] ",pHddCtx->cfg_ini->UapsdMask); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [PktClassificationBasis] Value = [%u] ",pHddCtx->cfg_ini->PktClassificationBasis); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ImplicitQosIsEnabled] Value = [%u]",(int)pHddCtx->cfg_ini->bImplicitQosEnabled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdVoSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdVoSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdVoSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdVoSuspIntv); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdViSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdViSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdViSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdViSuspIntv); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBeSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBeSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBeSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBeSuspIntv); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBkSrvIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBkSrvIntv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraUapsdBkSuspIntv] Value = [%u] ",pHddCtx->cfg_ini->InfraUapsdBkSuspIntv); +#ifdef FEATURE_WLAN_ESE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraInactivityInterval] Value = [%u] ",pHddCtx->cfg_ini->InfraInactivityInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [EseEnabled] Value = [%u] ",pHddCtx->cfg_ini->isEseIniFeatureEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [FastTransitionEnabled] Value = [%u] ",pHddCtx->cfg_ini->isFastTransitionEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gTxPowerCap] Value = [%u] dBm ",pHddCtx->cfg_ini->nTxPowerCap); +#endif +#ifdef FEATURE_WLAN_LFR + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [FastRoamEnabled] Value = [%u] ",pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [MAWCEnabled] Value = [%u] ",pHddCtx->cfg_ini->MAWCEnabled); +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [RoamRssiDiff] Value = [%u] ",pHddCtx->cfg_ini->RoamRssiDiff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ImmediateRoamRssiDiff] Value = [%u] ",pHddCtx->cfg_ini->nImmediateRoamRssiDiff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [isWESModeEnabled] Value = [%u] ",pHddCtx->cfg_ini->isWESModeEnabled); +#endif +#ifdef FEATURE_WLAN_OKC + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [OkcEnabled] Value = [%u] ",pHddCtx->cfg_ini->isOkcIniFeatureEnabled); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcVo] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcVo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcVo] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcVo); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcVi] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcVi); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcVi] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcVi); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcBe] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcBe); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcBe] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcBe); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraDirAcBk] Value = [%u] ",pHddCtx->cfg_ini->InfraDirAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraNomMsduSizeAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraNomMsduSizeAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMeanDataRateAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMeanDataRateAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraMinPhyRateAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraMinPhyRateAcBk); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [InfraSbaAcBk] Value = [0x%x] ",pHddCtx->cfg_ini->InfraSbaAcBk); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqBkWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqBkWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqBeWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqBeWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqViWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqViWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [WfqVoWeight] Value = [%u] ",pHddCtx->cfg_ini->WfqVoWeight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [DelayedTriggerFrmInt] Value = [%u] ",pHddCtx->cfg_ini->DelayedTriggerFrmInt); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BkReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->BkReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BeReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->BeReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ViReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->ViReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [VoReorderAgingTime] Value = [%u] ",pHddCtx->cfg_ini->VoReorderAgingTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [mcastBcastFilterSetting] Value = [%u] ",pHddCtx->cfg_ini->mcastBcastFilterSetting); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fhostArpOffload] Value = [%u] ",pHddCtx->cfg_ini->fhostArpOffload); +#ifdef WLAN_FEATURE_VOWIFI_11R + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fFTResourceReqSupported] Value = [%u] ",pHddCtx->cfg_ini->fFTResourceReqSupported); +#endif + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableRoamDelayStats] Value = [%u] ",pHddCtx->cfg_ini->gEnableRoamDelayStats); +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborReassocRssiThreshold] Value = [%u] ",pHddCtx->cfg_ini->nNeighborReassocRssiThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborLookupRssiThreshold] Value = [%u] ",pHddCtx->cfg_ini->nNeighborLookupRssiThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanMinChanTime] Value = [%u] ",pHddCtx->cfg_ini->nNeighborScanMinChanTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanMaxChanTime] Value = [%u] ",pHddCtx->cfg_ini->nNeighborScanMaxChanTime); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nMaxNeighborRetries] Value = [%u] ",pHddCtx->cfg_ini->nMaxNeighborReqTries); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanPeriod] Value = [%u] ",pHddCtx->cfg_ini->nNeighborScanPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborScanResultsRefreshPeriod] Value = [%u] ",pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nEmptyScanRefreshPeriod] Value = [%u] ",pHddCtx->cfg_ini->nEmptyScanRefreshPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nNeighborInitialForcedRoamTo5GhEnable] Value = [%u] ",pHddCtx->cfg_ini->nNeighborInitialForcedRoamTo5GhEnable); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nWeakZoneRssiThresholdForRoam] Value = [%u] ",pHddCtx->cfg_ini->nWeakZoneRssiThresholdForRoam); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [burstSizeDefinition] Value = [0x%x] ",pHddCtx->cfg_ini->burstSizeDefinition); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [tsInfoAckPolicy] Value = [0x%x] ",pHddCtx->cfg_ini->tsInfoAckPolicy); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [rfSettlingTimeUs] Value = [%u] ",pHddCtx->cfg_ini->rfSettlingTimeUs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [bSingleTidRc] Value = [%u] ",pHddCtx->cfg_ini->bSingleTidRc); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gDynamicPSPollvalue] Value = [%u] ",pHddCtx->cfg_ini->dynamicPsPollValue); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAddTSWhenACMIsOff] Value = [%u] ",pHddCtx->cfg_ini->AddTSWhenACMIsOff); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gValidateScanList] Value = [%u] ",pHddCtx->cfg_ini->fValidateScanList); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gStaKeepAlivePeriod] Value = [%u] ",pHddCtx->cfg_ini->infraStaKeepAlivePeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApDataAvailPollInterVal] Value = [%u] ",pHddCtx->cfg_ini->apDataAvailPollPeriodInMs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableBtAmp] Value = [%u] ",pHddCtx->cfg_ini->enableBtAmp); +#ifdef WLAN_BTAMP_FEATURE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BtAmpPreferredChannel] Value = [%u] ",pHddCtx->cfg_ini->preferredChannel); +#endif //WLAN_BTAMP_FEATURE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [BandCapability] Value = [%u] ",pHddCtx->cfg_ini->nBandCapability); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [fEnableBeaconEarlyTermination] Value = [%u] ",pHddCtx->cfg_ini->fEnableBeaconEarlyTermination); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [teleBcnWakeupEnable] Value = [%u] ",pHddCtx->cfg_ini->teleBcnWakeupEn); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [transListenInterval] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnTransListenInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [transLiNumIdleBeacons] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnTransLiNumIdleBeacons); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [maxListenInterval] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnMaxListenInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [maxLiNumIdleBeacons] Value = [%u] ",pHddCtx->cfg_ini->nTeleBcnMaxLiNumIdleBeacons); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [bcnEarlyTermWakeInterval] Value = [%u] ",pHddCtx->cfg_ini->bcnEarlyTermWakeInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableBypass11d] Value = [%u] ",pHddCtx->cfg_ini->enableBypass11d); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableDFSChnlScan] Value = [%u] ",pHddCtx->cfg_ini->enableDFSChnlScan); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableDFSPnoChnlScan] Value = [%u] ",pHddCtx->cfg_ini->enableDFSPnoChnlScan); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gReportMaxLinkSpeed] Value = [%u] ",pHddCtx->cfg_ini->reportMaxLinkSpeed); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [thermalMitigationEnable] Value = [%u] ",pHddCtx->cfg_ini->thermalMitigationEnable); +#ifdef WLAN_FEATURE_11AC + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gVhtChannelWidth] value = [%u]",pHddCtx->cfg_ini->vhtChannelWidth); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [enableFirstScan2GOnly] Value = [%u] ",pHddCtx->cfg_ini->enableFirstScan2GOnly); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [skipDfsChnlInP2pSearch] Value = [%u] ",pHddCtx->cfg_ini->skipDfsChnlInP2pSearch); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ignoreDynamicDtimInP2pMode] Value = [%u] ",pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [enableRxSTBC] Value = [%u] ",pHddCtx->cfg_ini->enableRxSTBC); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableLpwrImgTransition] Value = [%u] ",pHddCtx->cfg_ini->enableLpwrImgTransition); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [enable_conc_bmiss] Value = [%u] ",pHddCtx->cfg_ini->enable_conc_bmiss); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [enable_units_bwait] Value = [%u] ",pHddCtx->cfg_ini->enable_units_bwait); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableSSR] Value = [%u] ",pHddCtx->cfg_ini->enableSSR); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableVhtFor24GHzBand] Value = [%u] ",pHddCtx->cfg_ini->enableVhtFor24GHzBand); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableTrafficMonitor] Value = [%u] ", pHddCtx->cfg_ini->enableTrafficMonitor); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gTrafficIdleTimeout] Value = [%u] ", pHddCtx->cfg_ini->trafficIdleTimeout); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gFlexConnectPowerFactor] Value = [%u] ", pHddCtx->cfg_ini->flexConnectPowerFactor); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableIbssHeartBeatOffload] Value = [%u] ", pHddCtx->cfg_ini->enableIbssHeartBeatOffload); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAntennaDiversity] Value = [%u] ", pHddCtx->cfg_ini->antennaDiversity); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gGoLinkMonitorPeriod] Value = [%u]",pHddCtx->cfg_ini->goLinkMonitorPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApLinkMonitorPeriod] Value = [%u]",pHddCtx->cfg_ini->apLinkMonitorPeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gGoKeepAlivePeriod] Value = [%u]",pHddCtx->cfg_ini->goKeepAlivePeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApKeepAlivePeriod]Value = [%u]",pHddCtx->cfg_ini->apKeepAlivePeriod); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAmsduSupportInAMPDU] Value = [%u] ",pHddCtx->cfg_ini->isAmsduSupportInAMPDU); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [nSelect5GHzMargin] Value = [%u] ",pHddCtx->cfg_ini->nSelect5GHzMargin); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gCoalesingInIBSS] Value = [%u] ",pHddCtx->cfg_ini->isCoalesingInIBSSAllowed); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [overrideCountryCode] Value = [%s] ",pHddCtx->cfg_ini->overrideCountryCode); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdProbeInterval] Value = [%u]",pHddCtx->cfg_ini->gAsdProbeInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdTriggerThreshold] Value = [%hhd]",pHddCtx->cfg_ini->gAsdTriggerThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAsdRTTRssiHystThreshold]Value = [%u]",pHddCtx->cfg_ini->gAsdRTTRssiHystThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gIgnorePeerErpInfo] Value = [%u] ", + pHddCtx->cfg_ini->ignorePeerErpInfo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [disableP2PMacSpoofing] Value = [%u] ", + pHddCtx->cfg_ini->disableP2PMacSpoofing); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [enableFatalEvent] Value = [%u] ", + pHddCtx->cfg_ini->enableFatalEvent); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gRoamtoDFSChannel] Value = [%u] ",pHddCtx->cfg_ini->allowDFSChannelRoam); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gMaxConcurrentActiveSessions] Value = [%u] ", pHddCtx->cfg_ini->gMaxConcurrentActiveSessions); +#ifdef WLAN_FEATURE_AP_HT40_24G + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gApHT4024G] Value = [%u]", pHddCtx->cfg_ini->apHT40_24GEnabled); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAcsScanBandPreference] Value = [%u] ",pHddCtx->cfg_ini->acsScanBandPreference); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gACSBandSwitchThreshold] value = [%u]",pHddCtx->cfg_ini->acsBandSwitchThreshold); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gDeferScanTimeInterval] value = [%u]",pHddCtx->cfg_ini->nDeferScanTimeInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableTDLSScan] value = [%u]\n",pHddCtx->cfg_ini->fEnableTDLSScan); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gDxeReplenishRXTimerVal] Value = [%u] ", pHddCtx->cfg_ini->dxeReplenishRXTimerVal); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gDxeSSREnable] Value = [%u] ", pHddCtx->cfg_ini->dxeSSREnable); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [toggleArpBDRates] Value = [%u] ", pHddCtx->cfg_ini->toggleArpBDRates); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [ExtScanConcMode] Value = [%u] ", pHddCtx->cfg_ini->cfgExtScanConcMode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableForceTargetAssert] Value = [%u] ", pHddCtx->cfg_ini->crash_inject_enabled); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gTcpDelAckComputeInterval] Value = [%u] ", + pHddCtx->cfg_ini->tcpDelAckComputeInterval); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gTcpDelAckThresholdHigh] Value = [%u] ", + pHddCtx->cfg_ini->tcpDelAckThresholdHigh); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gTcpDelAckThresholdLow] Value = [%u] ", + pHddCtx->cfg_ini->tcpDelAckThresholdLow); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableDelAck] Value = [%u] ", + pHddCtx->cfg_ini->enable_delack); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [disableBarWakeUp] Value = [%u] ", + pHddCtx->cfg_ini->disableBarWakeUp); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMaxChannelForMoreDwellTime] Value = [%u] ", + pHddCtx->cfg_ini->max_chan_for_dwell_time_cfg); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gTDLSEnableDeferTime] Value = [%u] ", + pHddCtx->cfg_ini->tdls_enable_defer_time); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_ENABLE_EDCA_INI_NAME, + pHddCtx->cfg_ini->enable_edca_params); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_VO_CWMIN_VALUE_NAME, + pHddCtx->cfg_ini->edca_vo_cwmin); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_VI_CWMIN_VALUE_NAME, + pHddCtx->cfg_ini->edca_vi_cwmin); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_BK_CWMIN_VALUE_NAME, + pHddCtx->cfg_ini->edca_bk_cwmin); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_BE_CWMIN_VALUE_NAME, + pHddCtx->cfg_ini->edca_be_cwmin); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_VO_CWMAX_VALUE_NAME, + pHddCtx->cfg_ini->edca_vo_cwmax); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_VI_CWMAX_VALUE_NAME, + pHddCtx->cfg_ini->edca_vi_cwmax); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_BK_CWMAX_VALUE_NAME, + pHddCtx->cfg_ini->edca_bk_cwmax); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_BE_CWMAX_VALUE_NAME, + pHddCtx->cfg_ini->edca_be_cwmax); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_VO_AIFS_VALUE_NAME, + pHddCtx->cfg_ini->edca_vo_aifs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_VI_AIFS_VALUE_NAME, + pHddCtx->cfg_ini->edca_vi_aifs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_BK_AIFS_VALUE_NAME, + pHddCtx->cfg_ini->edca_bk_aifs); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_EDCA_BE_AIFS_VALUE_NAME, + pHddCtx->cfg_ini->edca_be_aifs); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gSendMgmtPktViaWQ5] Value = [%u] ", + pHddCtx->cfg_ini->sendMgmtPktViaWQ5); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", CFG_SAP_PROBE_RESP_OFFLOAD_NAME, + pHddCtx->cfg_ini->sap_probe_resp_offload); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamStatsTime] Value = [%lu] ", + (long unsigned int)pHddCtx->cfg_ini->PERtimerThreshold); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamRxMonitorEnabled] Value = [%u] ", + pHddCtx->cfg_ini->isPERRoamRxPathEnabled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamTriggerPercent] Value = [%u] ", + pHddCtx->cfg_ini->PERroamTriggerPercent); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamRxPktThreshold] Value = [%u] ", + pHddCtx->cfg_ini->PERroamRxPktsThreshold); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamCCAEnabled] Value = [%u] ", + pHddCtx->cfg_ini->isPERRoamCCAEnabled); + +#ifdef DHCP_SERVER_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gDHCPServerOffloadEnable] Value = [%u]", + pHddCtx->cfg_ini->enable_dhcp_srv_offload); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gDHCPMaxNumClients] Value = [%u]", + pHddCtx->cfg_ini->dhcp_max_num_clients); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gDHCPServerIP] Value = [%s]", + pHddCtx->cfg_ini->dhcp_srv_ip); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gDHCPStartLsb] Value = [%u]", + pHddCtx->cfg_ini->dhcp_start_lsb); +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSOffloadEnable] Value = [%u]", + pHddCtx->cfg_ini->enable_mdns_offload); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSFqdn] Value = [%s]", + pHddCtx->cfg_ini->mdns_fqdn); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSUniqueFqdn] Value = [%s]", + pHddCtx->cfg_ini->mdns_uniquefqdn); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeA] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_a); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeAIpv4Addr] Value = [%u]", + pHddCtx->cfg_ini->mdns_resp_type_a_ipv4); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeTXT] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_txt); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeTXTContent] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_txt_content); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypePTR] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_ptr); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypePTRDomainName] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_ptr_dname); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeSRV] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_srv); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeSRVPriority] Value = [%u]", + pHddCtx->cfg_ini->mdns_resp_type_srv_priority); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeSRVWeight] Value = [%u]", + pHddCtx->cfg_ini->mdns_resp_type_srv_weight); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeSRVPort] Value = [%u]", + pHddCtx->cfg_ini->mdns_resp_type_srv_port); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gMDNSResponseTypeSRVTarget] Value = [%s]", + pHddCtx->cfg_ini->mdns_resp_type_srv_target); +#endif /* MDNS_OFFLOAD */ + + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamFullScanThreshold] Value = [%u] ", + pHddCtx->cfg_ini->PERRoamFullScanThreshold); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERMinRssiThresholdForRoam] Value = [%d] ", + pHddCtx->cfg_ini->PERMinRssiThresholdForRoam); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamScanInterval] Value = [%lu] ", + (long unsigned int)pHddCtx->cfg_ini->waitPeriodForNextPERScan); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamDownThresholdRate] Value = [%u] ", + pHddCtx->cfg_ini->rateDownThreshold); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamEnable] Value = [%u] ", + pHddCtx->cfg_ini->isPERRoamEnabled); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gPERRoamUpThresholdRate] Value = [%u] ", + pHddCtx->cfg_ini->rateUpThreshold); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gDisableScanDuringSco] Value = [%u] ", + pHddCtx->cfg_ini->disable_scan_during_sco); +#endif +#ifdef SAP_AUTH_OFFLOAD + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableSAPAuthOffload] Value = [%u] ", + pHddCtx->cfg_ini->enable_sap_auth_offload); +#endif + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableSapInternalRestart] Value = [%u] ", + pHddCtx->cfg_ini->sap_internal_restart); + +#ifdef WLAN_FEATURE_LFR_MBB + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [gEnableLFRMBB] Value = [%u] ", + pHddCtx->cfg_ini->enable_lfr_mbb); +#endif + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [sta_auth_retries_for_code17] Value = [%u] ", + pHddCtx->cfg_ini->sta_auth_retries_for_code17); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Name = [%s] Value = [%u] ", + CFG_TRIGGER_NULLFRAME_BEFORE_HB_NAME, + pHddCtx->cfg_ini->trigger_nullframe_before_hb); +} + + + +#define CFG_VALUE_MAX_LEN 256 +#define CFG_ENTRY_MAX_LEN (32+CFG_VALUE_MAX_LEN) +VOS_STATUS hdd_cfg_get_config(hdd_context_t *pHddCtx, char *pBuf, int buflen) +{ + unsigned int idx; + REG_TABLE_ENTRY *pRegEntry = g_registry_table; + unsigned long cRegTableEntries = sizeof(g_registry_table) / sizeof( g_registry_table[ 0 ]); + v_U32_t value; + char valueStr[CFG_VALUE_MAX_LEN]; + char configStr[CFG_ENTRY_MAX_LEN]; + char *fmt; + void *pField; + v_MACADDR_t *pMacAddr; + char *pCur = pBuf; + int curlen; + + // start with an empty string + *pCur = '\0'; + + for ( idx = 0; idx < cRegTableEntries; idx++, pRegEntry++ ) + { + pField = ( (v_U8_t *)pHddCtx->cfg_ini) + pRegEntry->VarOffset; + + if ( ( WLAN_PARAM_Integer == pRegEntry->RegType ) || + ( WLAN_PARAM_SignedInteger == pRegEntry->RegType ) || + ( WLAN_PARAM_HexInteger == pRegEntry->RegType ) ) + { + value = 0; + memcpy( &value, pField, pRegEntry->VarSize ); + if ( WLAN_PARAM_HexInteger == pRegEntry->RegType ) + { + fmt = "%x"; + } + else if ( WLAN_PARAM_SignedInteger == pRegEntry->RegType ) + { + fmt = "%d"; + } + else + { + fmt = "%u"; + } + snprintf(valueStr, CFG_VALUE_MAX_LEN, fmt, value); + } + else if ( WLAN_PARAM_String == pRegEntry->RegType ) + { + snprintf(valueStr, CFG_VALUE_MAX_LEN, "%s", (char *)pField); + } + else if ( WLAN_PARAM_MacAddr == pRegEntry->RegType ) + { + pMacAddr = (v_MACADDR_t *) pField; + snprintf(valueStr, CFG_VALUE_MAX_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x", + pMacAddr->bytes[0], + pMacAddr->bytes[1], + pMacAddr->bytes[2], + pMacAddr->bytes[3], + pMacAddr->bytes[4], + pMacAddr->bytes[5]); + } + else + { + snprintf(valueStr, CFG_VALUE_MAX_LEN, "(unhandled)"); + } + curlen = scnprintf(configStr, CFG_ENTRY_MAX_LEN, + "%s=[%s]%s\n", + pRegEntry->RegName, + valueStr, + test_bit(idx, (void *)&pHddCtx->cfg_ini->bExplicitCfg) ? + "*" : ""); + + // ideally we want to return the config to the application + // however the config is too big so we just printk() for now +#ifdef RETURN_IN_BUFFER + if (curlen < buflen) + { + // copy string + '\0' + memcpy(pCur, configStr, curlen+1); + + // account for addition; + pCur += curlen; + buflen -= curlen; + } + else + { + // buffer space exhausted, return what we have + return VOS_STATUS_E_RESOURCES; + } +#else + printk(KERN_CRIT "%s", configStr); +#endif // RETURN_IN_BUFFER + +} + +#ifndef RETURN_IN_BUFFER + // notify application that output is in system log + snprintf(pCur, buflen, "WLAN configuration written to system log"); +#endif // RETURN_IN_BUFFER + + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS find_cfg_item (tCfgIniEntry* iniTable, unsigned long entries, + char *name, char** value) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + unsigned long i; + + for (i = 0; i < entries; i++) { + if (strcmp(iniTable[i].name, name) == 0) { + *value = iniTable[i].value; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Found %s entry for Name=[%s] Value=[%s] ", + WLAN_INI_FILE, name, *value); + return VOS_STATUS_SUCCESS; + } + } + + return status; +} + +static int parseHexDigit(char c) +{ + if (c >= '0' && c <= '9') + return c-'0'; + if (c >= 'a' && c <= 'f') + return c-'a'+10; + if (c >= 'A' && c <= 'F') + return c-'A'+10; + + return 0; +} + + +static VOS_STATUS hdd_apply_cfg_ini( hdd_context_t *pHddCtx, tCfgIniEntry* iniTable, unsigned long entries) +{ + VOS_STATUS match_status = VOS_STATUS_E_FAILURE; + VOS_STATUS ret_status = VOS_STATUS_SUCCESS; + unsigned int idx; + void *pField; + char *value_str = NULL; + unsigned long len_value_str; + char *candidate; + v_U32_t value; + v_S31_t svalue; + void *pStructBase = pHddCtx->cfg_ini; + REG_TABLE_ENTRY *pRegEntry = g_registry_table; + unsigned long cRegTableEntries = sizeof(g_registry_table) / sizeof( g_registry_table[ 0 ]); + v_U32_t cbOutString; + int i; + int rv; + + // sanity test + if (MAX_CFG_INI_ITEMS < cRegTableEntries) + { + hddLog(LOGE, "%s: MAX_CFG_INI_ITEMS too small, must be at least %ld", + __func__, cRegTableEntries); + } + + for ( idx = 0; idx < cRegTableEntries; idx++, pRegEntry++ ) + { + //Calculate the address of the destination field in the structure. + pField = ( (v_U8_t *)pStructBase )+ pRegEntry->VarOffset; + + match_status = find_cfg_item(iniTable, entries, pRegEntry->RegName, &value_str); + + if( (match_status != VOS_STATUS_SUCCESS) && ( pRegEntry->Flags & VAR_FLAGS_REQUIRED ) ) + { + // If we could not read the cfg item and it is required, this is an error. + hddLog(LOGE, "%s: Failed to read required config parameter %s", + __func__, pRegEntry->RegName); + ret_status = VOS_STATUS_E_FAILURE; + break; + } + + if ( ( WLAN_PARAM_Integer == pRegEntry->RegType ) || + ( WLAN_PARAM_HexInteger == pRegEntry->RegType ) ) + { + // If successfully read from the registry, use the value read. + // If not, use the default value. + if ( match_status == VOS_STATUS_SUCCESS && (WLAN_PARAM_Integer == pRegEntry->RegType)) { + rv = kstrtou32(value_str, 10, &value); + if (rv < 0) { + hddLog(LOGE, "%s: Reg Parameter %s invalid. Enforcing default", + __func__, pRegEntry->RegName); + value = pRegEntry->VarDefault; + } + } + else if ( match_status == VOS_STATUS_SUCCESS && (WLAN_PARAM_HexInteger == pRegEntry->RegType)) { + rv = kstrtou32(value_str, 16, &value); + if (rv < 0) { + hddLog(LOGE, "%s: Reg paramter %s invalid. Enforcing default", + __func__, pRegEntry->RegName); + value = pRegEntry->VarDefault; + } + } + else { + value = pRegEntry->VarDefault; + } + + // If this parameter needs range checking, do it here. + if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK ) + { + if ( value > pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum [%u > %lu]. Enforcing Maximum", + __func__, pRegEntry->RegName, value, pRegEntry->VarMax ); + value = pRegEntry->VarMax; + } + + if ( value < pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum [%u < %lu]. Enforcing Minimum", + __func__, pRegEntry->RegName, value, pRegEntry->VarMin); + value = pRegEntry->VarMin; + } + } + // If this parameter needs range checking, do it here. + else if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT ) + { + if ( value > pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum [%u > %lu]. Enforcing Default= %lu", + __func__, pRegEntry->RegName, value, pRegEntry->VarMax, pRegEntry->VarDefault ); + value = pRegEntry->VarDefault; + } + + if ( value < pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum [%u < %lu]. Enforcing Default= %lu", + __func__, pRegEntry->RegName, value, pRegEntry->VarMin, pRegEntry->VarDefault ); + value = pRegEntry->VarDefault; + } + } + + // Move the variable into the output field. + memcpy( pField, &value, pRegEntry->VarSize ); + } + else if ( WLAN_PARAM_SignedInteger == pRegEntry->RegType ) + { + // If successfully read from the registry, use the value read. + // If not, use the default value. + if (VOS_STATUS_SUCCESS == match_status) + { + rv = kstrtos32(value_str, 10, &svalue); + if (rv < 0) { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Reg Parameter %s invalid. Enforcing Default", + __func__, pRegEntry->RegName); + svalue = (v_S31_t)pRegEntry->VarDefault; + } + } + else + { + svalue = (v_S31_t)pRegEntry->VarDefault; + } + + // If this parameter needs range checking, do it here. + if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK ) + { + if ( svalue > (v_S31_t)pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum " + "[%d > %d]. Enforcing Maximum", __func__, + pRegEntry->RegName, svalue, (int)pRegEntry->VarMax ); + svalue = (v_S31_t)pRegEntry->VarMax; + } + + if ( svalue < (v_S31_t)pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum " + "[%d < %d]. Enforcing Minimum", __func__, + pRegEntry->RegName, svalue, (int)pRegEntry->VarMin); + svalue = (v_S31_t)pRegEntry->VarMin; + } + } + // If this parameter needs range checking, do it here. + else if ( pRegEntry->Flags & VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT ) + { + if ( svalue > (v_S31_t)pRegEntry->VarMax ) + { + hddLog(LOGE, "%s: Reg Parameter %s > allowed Maximum " + "[%d > %d]. Enforcing Default= %d", + __func__, pRegEntry->RegName, svalue, + (int)pRegEntry->VarMax, + (int)pRegEntry->VarDefault ); + svalue = (v_S31_t)pRegEntry->VarDefault; + } + + if ( svalue < (v_S31_t)pRegEntry->VarMin ) + { + hddLog(LOGE, "%s: Reg Parameter %s < allowed Minimum " + "[%d < %d]. Enforcing Default= %d", + __func__, pRegEntry->RegName, svalue, + (int)pRegEntry->VarMin, + (int)pRegEntry->VarDefault); + svalue = pRegEntry->VarDefault; + } + } + + // Move the variable into the output field. + memcpy( pField, &svalue, pRegEntry->VarSize ); + } + // Handle string parameters + else if ( WLAN_PARAM_String == pRegEntry->RegType ) + { +#ifdef WLAN_CFG_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "RegName = %s, VarOffset %u VarSize %u VarDefault %s", + pRegEntry->RegName, pRegEntry->VarOffset, pRegEntry->VarSize, (char*)pRegEntry->VarDefault); +#endif + + if ( match_status == VOS_STATUS_SUCCESS) + { + len_value_str = strlen(value_str); + + if(len_value_str > (pRegEntry->VarSize - 1)) { + hddLog(LOGE, "%s: Invalid Value=[%s] specified for Name=[%s] in %s", + __func__, value_str, pRegEntry->RegName, WLAN_INI_FILE); + cbOutString = utilMin( strlen( (char *)pRegEntry->VarDefault ), pRegEntry->VarSize - 1 ); + memcpy( pField, (void *)(pRegEntry->VarDefault), cbOutString ); + ( (v_U8_t *)pField )[ cbOutString ] = '\0'; + } + else + { + memcpy( pField, (void *)(value_str), len_value_str); + ( (v_U8_t *)pField )[ len_value_str ] = '\0'; + } + } + else + { + // Failed to read the string parameter from the registry. Use the default. + cbOutString = utilMin( strlen( (char *)pRegEntry->VarDefault ), pRegEntry->VarSize - 1 ); + memcpy( pField, (void *)(pRegEntry->VarDefault), cbOutString ); + ( (v_U8_t *)pField )[ cbOutString ] = '\0'; + } + } + else if ( WLAN_PARAM_MacAddr == pRegEntry->RegType ) + { + if(pRegEntry->VarSize != VOS_MAC_ADDR_SIZE) { + hddLog(LOGE, "%s: Invalid VarSize %u for Name=[%s]", + __func__, pRegEntry->VarSize, pRegEntry->RegName); + continue; + } + candidate = (char*)pRegEntry->VarDefault; + if ( match_status == VOS_STATUS_SUCCESS) { + len_value_str = strlen(value_str); + if(len_value_str != (VOS_MAC_ADDR_SIZE*2)) { + hddLog(LOGE, "%s: Invalid MAC addr [%s] specified for Name=[%s] in %s", + __func__, value_str, pRegEntry->RegName, WLAN_INI_FILE); + } + else + candidate = value_str; + } + //parse the string and store it in the byte array + for(i=0; iRegName); + } + + // did we successfully parse a cfg item for this parameter? + if( (match_status == VOS_STATUS_SUCCESS) && + (idx < MAX_CFG_INI_ITEMS) ) + { + set_bit(idx, (void *)&pHddCtx->cfg_ini->bExplicitCfg); + } + } + + print_hdd_cfg(pHddCtx); + + return( ret_status ); +} + +eCsrPhyMode hdd_cfg_xlate_to_csr_phy_mode( eHddDot11Mode dot11Mode ) +{ + switch (dot11Mode) + { + case (eHDD_DOT11_MODE_abg): + return eCSR_DOT11_MODE_abg; + case (eHDD_DOT11_MODE_11b): + return eCSR_DOT11_MODE_11b; + case (eHDD_DOT11_MODE_11g): + return eCSR_DOT11_MODE_11g; + default: + case (eHDD_DOT11_MODE_11n): + return eCSR_DOT11_MODE_11n; + case (eHDD_DOT11_MODE_11g_ONLY): + return eCSR_DOT11_MODE_11g_ONLY; + case (eHDD_DOT11_MODE_11n_ONLY): + return eCSR_DOT11_MODE_11n_ONLY; + case (eHDD_DOT11_MODE_11b_ONLY): + return eCSR_DOT11_MODE_11b_ONLY; +#ifdef WLAN_FEATURE_11AC + case (eHDD_DOT11_MODE_11ac_ONLY): + return eCSR_DOT11_MODE_11ac_ONLY; + case (eHDD_DOT11_MODE_11ac): + return eCSR_DOT11_MODE_11ac; +#endif + case (eHDD_DOT11_MODE_AUTO): + return eCSR_DOT11_MODE_AUTO; + } + +} + +static void hdd_set_btc_config(hdd_context_t *pHddCtx) +{ + hdd_config_t *pConfig = pHddCtx->cfg_ini; + tSmeBtcConfig btcParams; + int i; + + sme_BtcGetConfig(pHddCtx->hHal, &btcParams); + + btcParams.btcExecutionMode = pConfig->btcExecutionMode; + btcParams.btcConsBtSlotsToBlockDuringDhcp = pConfig->btcConsBtSlotsToBlockDuringDhcp; + btcParams.btcA2DPBtSubIntervalsDuringDhcp = pConfig->btcA2DPBtSubIntervalsDuringDhcp; + + btcParams.btcStaticLenInqBt = pConfig->btcStaticLenInqBt; + btcParams.btcStaticLenPageBt = pConfig->btcStaticLenPageBt; + btcParams.btcStaticLenConnBt = pConfig->btcStaticLenConnBt; + btcParams.btcStaticLenLeBt = pConfig->btcStaticLenLeBt; + btcParams.btcStaticLenInqWlan = pConfig->btcStaticLenInqWlan; + btcParams.btcStaticLenPageWlan = pConfig->btcStaticLenPageWlan; + btcParams.btcStaticLenConnWlan = pConfig->btcStaticLenConnWlan; + btcParams.btcStaticLenLeWlan = pConfig->btcStaticLenLeWlan; + btcParams.btcDynMaxLenBt = pConfig->btcDynMaxLenBt; + btcParams.btcDynMaxLenWlan = pConfig->btcDynMaxLenWlan; + btcParams.btcMaxScoBlockPerc = pConfig->btcMaxScoBlockPerc; + btcParams.btcDhcpProtOnA2dp = pConfig->btcDhcpProtOnA2dp; + btcParams.btcDhcpProtOnSco = pConfig->btcDhcpProtOnSco; + + for (i = 0; i < 10; i++) + { + btcParams.mwsCoexVictimWANFreq[i] = pConfig->mwsCoexVictimWANFreq[i]; + btcParams.mwsCoexVictimWLANFreq[i] = pConfig->mwsCoexVictimWLANFreq[i]; + btcParams.mwsCoexVictimConfig[i] = pConfig->mwsCoexVictimConfig[i]; + btcParams.mwsCoexVictimConfig2[i] = pConfig->mwsCoexVictimConfig2[i]; + } + for (i = 0; i < 6; i++) + { + btcParams.mwsCoexConfig[i] = pConfig->mwsCoexConfig[i]; + } + btcParams.mwsCoexModemBackoff = pConfig->mwsCoexModemBackoff; + btcParams.SARPowerBackoff = pConfig->SARPowerBackoff; + + sme_BtcSetConfig(pHddCtx->hHal, &btcParams); +} + +static void hdd_set_power_save_config(hdd_context_t *pHddCtx, tSmeConfigParams *smeConfig) +{ + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + tPmcBmpsConfigParams bmpsParams; + + sme_GetConfigPowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE, &bmpsParams); + + if (strcmp(pConfig->PowerUsageControl, "Min") == 0) + { + smeConfig->csrConfig.impsSleepTime = pConfig->nImpsMinSleepTime; + bmpsParams.bmpsPeriod = pConfig->nBmpsMinListenInterval; + bmpsParams.enableBeaconEarlyTermination = pConfig->fEnableBeaconEarlyTermination; + bmpsParams.bcnEarlyTermWakeInterval = pConfig->bcnEarlyTermWakeInterval; + } + if (strcmp(pConfig->PowerUsageControl, "Max") == 0) + { + smeConfig->csrConfig.impsSleepTime = pConfig->nImpsMaxSleepTime; + bmpsParams.bmpsPeriod = pConfig->nBmpsMaxListenInterval; + bmpsParams.enableBeaconEarlyTermination = pConfig->fEnableBeaconEarlyTermination; + bmpsParams.bcnEarlyTermWakeInterval = pConfig->bcnEarlyTermWakeInterval; + } + if (strcmp(pConfig->PowerUsageControl, "Mod") == 0) + { + smeConfig->csrConfig.impsSleepTime = pConfig->nImpsModSleepTime; + bmpsParams.bmpsPeriod = pConfig->nBmpsModListenInterval; + bmpsParams.enableBeaconEarlyTermination = pConfig->fEnableBeaconEarlyTermination; + bmpsParams.bcnEarlyTermWakeInterval = pConfig->bcnEarlyTermWakeInterval; + } + + if (pConfig->fIsImpsEnabled) + { + sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + else + { + sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + + /*If isAndroidPsEn is 1 then Host driver and above layers control the PS mechanism + If Value set to 0 Driver/Core Stack internally control the Power saving mechanism */ + sme_SetHostPowerSave (pHddCtx->hHal, pConfig->isAndroidPsEn); + + if (pConfig->fIsBmpsEnabled) + { + sme_EnablePowerSave (pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + else + { + sme_DisablePowerSave (pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + + bmpsParams.trafficMeasurePeriod = pConfig->nAutoBmpsTimerValue; + + if (sme_SetConfigPowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE, &bmpsParams)== eHAL_STATUS_FAILURE) + { + hddLog(LOGE, "SetConfigPowerSave failed to set BMPS params"); + } + + if(pConfig->fIsAutoBmpsTimerEnabled) + { + sme_StartAutoBmpsTimer(pHddCtx->hHal); + } + +} + +VOS_STATUS hdd_string_to_u8_array(char *str, tANI_U8 *intArray, + tANI_U8 *len, tANI_U8 intArrayMaxLen, + char *seperator) +{ + char *s = str; + + if( str == NULL || intArray == NULL || len == NULL ) + { + return VOS_STATUS_E_INVAL; + } + *len = 0; + + while ( (s != NULL) && (*len < intArrayMaxLen) ) + { + int val; + //Increment length only if sscanf succesfully extracted one element. + //Any other return value means error. Ignore it. + if( sscanf(s, "%d", &val ) == 1 ) + { + if (val > 255 || val < 0) + return VOS_STATUS_E_FAILURE; + intArray[*len] = (tANI_U8) val; + *len += 1; + } + s = strpbrk( s, seperator); + if( s ) + s++; + } + + return VOS_STATUS_SUCCESS; + +} + +#ifdef MDNS_OFFLOAD +int hdd_string_to_string_array(char *data, uint8_t *datalist, + char separator, uint8_t *num_entries, + uint8_t max_entries, + uint8_t max_len_entry) +{ + uint8_t num = 0; + char *str = NULL; + char *temp_str = NULL; + char *field; + uint16_t len = 0; + + if ((data == NULL) || ( datalist == NULL) || (num_entries == NULL)) + return VOS_STATUS_E_INVAL; + + str = vos_mem_malloc(strlen((char *)data)); + if (!str) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s str allocation failed",__func__); + return -ENOMEM; + } + vos_mem_copy(str, data, strlen((char *)data)); + temp_str = str; + /* parse the string */ + while (str && ('\0' != *str) && (num < max_entries)) { + field = str; + while (str && ('\0' != *str) && (separator != *str)) + str++; + if ('\0' == *str) { + /* reach the end of string */ + if ('\0' != *field) { + strlcpy((char *)(datalist + + (num * max_len_entry)), + field, max_len_entry); + num++; + } + break; + } + /* replace separator with NULL to terminate the data */ + *str++ = '\0'; + len = (char *)str - (char *)field; + strlcpy((char *)(datalist + (num * max_len_entry)), + field, len); + num++; + } + *num_entries = num; + vos_mem_free(temp_str); + + return 0; +} +#endif /* MDNS_OFFLOAD */ + +v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx ) +{ + v_BOOL_t fStatus = TRUE; +#ifdef WLAN_SOFTAP_VSTA_FEATURE + tANI_U32 val; +#endif + + hdd_config_t *pConfig = pHddCtx->cfg_ini; + tSirMacHTCapabilityInfo *htCapInfo; + tANI_U32 temp32; + tANI_U16 temp16; + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SHORT_GI_20MHZ, + pConfig->ShortGI20MhzEnable, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SHORT_GI_20MHZ to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_CAL_CONTROL, pConfig->Calibration, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_CAL_CONTROL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_CAL_PERIOD, pConfig->CalibrationPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_CAL_PERIOD to CCM"); + } + + if ( 0 != pConfig->Cfg1Id ) + { + if (ccmCfgSetInt(pHddCtx->hHal, pConfig->Cfg1Id, pConfig->Cfg1Value, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on Cfg1Id to CCM"); + } + + } + + if ( 0 != pConfig->Cfg2Id ) + { + if (ccmCfgSetInt(pHddCtx->hHal, pConfig->Cfg2Id, pConfig->Cfg2Value, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on Cfg2Id to CCM"); + } + } + + if ( 0 != pConfig->Cfg3Id ) + { + if (ccmCfgSetInt(pHddCtx->hHal, pConfig->Cfg3Id, pConfig->Cfg3Value, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on Cfg3Id to CCM"); + } + } + + if ( 0 != pConfig->Cfg4Id ) + { + if (ccmCfgSetInt(pHddCtx->hHal, pConfig->Cfg4Id, pConfig->Cfg4Value, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on Cfg4Id to CCM"); + } + } + + if ( 0 != pConfig->Cfg5Id ) + { + if (ccmCfgSetInt(pHddCtx->hHal, pConfig->Cfg5Id, pConfig->Cfg5Value, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on Cfg5Id to CCM"); + } + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BA_AUTO_SETUP, pConfig->BlockAckAutoSetup, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BA_AUTO_SETUP to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_FIXED_RATE, pConfig->TxRate, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_FIXED_RATE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_RX_AMPDU_FACTOR, + pConfig->MaxRxAmpduFactor, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_HT_AMPDU_PARAMS_MAX_RX_AMPDU_FACTOR to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SHORT_PREAMBLE, pConfig->fIsShortPreamble, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_SHORT_PREAMBLE to CCM"); + } + + if (pConfig->fIsAutoIbssBssid) + { + if (ccmCfgSetStr(pHddCtx->hHal, WNI_CFG_BSSID, (v_U8_t *)"000000000000", + sizeof(v_BYTE_t) * VOS_MAC_ADDR_SIZE, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_BSSID to CCM"); + } + } + else + { + if ( VOS_FALSE == vos_is_macaddr_group( &pConfig->IbssBssid )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "MAC Addr (IBSS BSSID) read from Registry is: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pConfig->IbssBssid.bytes)); + if (ccmCfgSetStr(pHddCtx->hHal, WNI_CFG_BSSID, pConfig->IbssBssid.bytes, + sizeof(v_BYTE_t) * VOS_MAC_ADDR_SIZE, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_BSSID to CCM"); + } + } + else + { + fStatus = FALSE; + hddLog(LOGE,"Could not pass on WNI_CFG_BSSID to CCM"); + } + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME, + pConfig->nPassiveMinChnTime, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME" + " to CCM\n"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + pConfig->nPassiveMaxChnTime, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME" + " to CCM\n"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BEACON_INTERVAL, pConfig->nBeaconInterval, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BEACON_INTERVAL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_PS_POLL, pConfig->nMaxPsPoll, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_PS_POLL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_CURRENT_RX_ANTENNA, pConfig-> nRxAnt, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_CURRENT_RX_ANTENNA configuration info to HAL" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LOW_GAIN_OVERRIDE, pConfig->fIsLowGainOverride, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_LOW_GAIN_OVERRIDE to HAL"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RSSI_FILTER_PERIOD, pConfig->nRssiFilterPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_RSSI_FILTER_PERIOD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, pConfig->fIgnoreDtim, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_IGNORE_DTIM configuration to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_ENABLE_HEART_BEAT, pConfig->fEnableFwHeartBeatMonitoring, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_PS_HEART_BEAT configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_ENABLE_BCN_FILTER, pConfig->fEnableFwBeaconFiltering, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_PS_BCN_FILTER configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR, pConfig->fEnableFwRssiMonitoring, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on WNI_CFG_PS_RSSI_MONITOR configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, pConfig->nDataInactivityTimeout, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_NTH_BEACON_FILTER, pConfig->nthBeaconFilter, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_NTH_BEACON_FILTER configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_LTE_COEX, pConfig->enableLTECoex, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_LTE_COEX to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE, pConfig->nEnableListenMode, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_KEEP_ALIVE_TIMEOUT, pConfig->apKeepAlivePeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_AP_KEEP_ALIVE_TIMEOUT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_GO_KEEP_ALIVE_TIMEOUT, pConfig->goKeepAlivePeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_GO_KEEP_ALIVE_TIMEOUT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_LINK_MONITOR_TIMEOUT, pConfig->apLinkMonitorPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_AP_LINK_MONITOR_TIMEOUT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_GO_LINK_MONITOR_TIMEOUT, pConfig->goLinkMonitorPeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_GO_LINK_MONITOR_TIMEOUT to CCM"); + } + + +#if defined WLAN_FEATURE_VOWIFI + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RRM_ENABLED, pConfig->fRrmEnable, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RRM_ENABLE configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RRM_OPERATING_CHAN_MAX, pConfig->nInChanMeasMaxDuration, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RRM_OPERATING_CHAN_MAX configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, pConfig->nOutChanMeasMaxDuration, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RRM_OUT_CHAN_MAX configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MCAST_BCAST_FILTER_SETTING, pConfig->mcastBcastFilterSetting, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SINGLE_TID_RC, pConfig->bSingleTidRc, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_SINGLE_TID_RC configuration info to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_WAKEUP_EN, pConfig->teleBcnWakeupEn, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_WAKEUP_EN configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_TRANS_LI, pConfig->nTeleBcnTransListenInterval, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_TRANS_LI configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_MAX_LI, pConfig->nTeleBcnMaxListenInterval, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_MAX_LI configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS, pConfig->nTeleBcnTransLiNumIdleBeacons, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS, pConfig->nTeleBcnMaxLiNumIdleBeacons, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RF_SETTLING_TIME_CLK, pConfig->rfSettlingTimeUs, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RF_SETTLING_TIME_CLK configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD, pConfig->infraStaKeepAlivePeriod, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD configuration info to CCM" ); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_PS_POLL_VALUE, pConfig->dynamicPsPollValue, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_DYNAMIC_PS_POLL_VALUE configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT, pConfig->nNullDataApRespTimeout, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_PS_NULLDATA_DELAY_TIMEOUT configuration info to CCM" ); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD, pConfig->apDataAvailPollPeriodInMs, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD configuration info to CCM" ); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, pConfig->FragmentationThreshold, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_FRAGMENTATION_THRESHOLD configuration info to CCM" ); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RTS_THRESHOLD, pConfig->RTSThreshold, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_RTS_THRESHOLD configuration info to CCM" ); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_11D_ENABLED, pConfig->Is11dSupportEnabled, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_11D_ENABLED configuration info to CCM" ); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HEART_BEAT_THRESHOLD, pConfig->HeartbeatThresh24, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_HEART_BEAT_THRESHOLD configuration info to CCM" ); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_CLOSE_LOOP, + pConfig->enableCloseLoop, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_CLOSE_LOOP to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TX_PWR_CTRL_ENABLE, + pConfig->enableAutomaticTxPowerControl, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TX_PWR_CTRL_ENABLE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SHORT_GI_40MHZ, + pConfig->ShortGI40MhzEnable, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SHORT_GI_40MHZ to CCM"); + } + + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST, pConfig->fEnableMCAddrList, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_MC_ADDR_LIST to CCM"); + } + + /* cache the value configured in fwr */ + pHddCtx->mc_list_cfg_in_fwr = pConfig->fEnableMCAddrList; + +#ifdef WLAN_FEATURE_11AC + /* Based on cfg.ini, update the Basic MCS set, RX/TX MCS map in the cfg.dat */ + /* valid values are 0(MCS0-7), 1(MCS0-8), 2(MCS0-9) */ + /* we update only the least significant 2 bits in the corresponding fields */ + if( (pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11ac) ) + { + { + tANI_U32 temp = 0; + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, &temp); + temp = (temp & 0xFFFC) | pConfig->vhtRxMCS; + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_BASIC_MCS_SET, + temp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_BASIC_MCS_SET to CCM"); + } + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP, &temp); + temp = (temp & 0xFFFC) | pConfig->vhtRxMCS; + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_RX_MCS_MAP, + temp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RX_MCS_MAP to CCM"); + } + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, &temp); + temp = (temp & 0xFFFC) | pConfig->vhtTxMCS; + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_TX_MCS_MAP, + temp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_TX_MCS_MAP to CCM"); + } + /* Currently shortGI40Mhz is used for shortGI80Mhz */ + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_SHORT_GI_80MHZ, + pConfig->ShortGI40MhzEnable, NULL, eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass WNI_VHT_SHORT_GI_80MHZ to CCM\n"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, + pConfig->gVhtMaxAmpduLenExp, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_AMPDU_LEN_EXPONENT to CCM"); + } + + } + } +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_NUM_BUFF_ADVERT,pConfig->numBuffAdvert, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_NUM_BUFF_ADVERT to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HT_RX_STBC, + pConfig->enableRxSTBC, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_HT_RX_STBC to CCM"); + } + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_HT_CAP_INFO, &temp32); + temp16 = temp32 & 0xffff; + htCapInfo = (tSirMacHTCapabilityInfo *)&temp16; + htCapInfo->rxSTBC = pConfig->enableRxSTBC; + temp32 = temp16; + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HT_CAP_INFO, + temp32, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_HT_CAP_INFO to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_VHT_RXSTBC, + pConfig->enableRxSTBC, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_VHT_RXSTBC to CCM"); + } + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + if(pConfig->fEnableVSTASupport) + { + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_ASSOC_STA_LIMIT, &val); + if( val <= WNI_CFG_ASSOC_STA_LIMIT_STADEF) + val = WNI_CFG_ASSOC_STA_LIMIT_STAMAX; + } + else + { + val = WNI_CFG_ASSOC_STA_LIMIT_STADEF; + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ASSOC_STA_LIMIT, val, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE,"Failure: Could not pass on WNI_CFG_ASSOC_STA_LIMIT configuration info to CCM" ); + } +#endif + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_LPWR_IMG_TRANSITION, + pConfig->enableLpwrImgTransition, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_LPWR_IMG_TRANSITION to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, pConfig->enableMCCAdaptiveScheduler, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP, pConfig->disableLDPCWithTxbfAP, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_THRESHOLD_ZERO, pConfig->retryLimitZero, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DYNAMIC_THRESHOLD_ZERO to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_THRESHOLD_ONE, pConfig->retryLimitOne, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DYNAMIC_THRESHOLD_ONE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DYNAMIC_THRESHOLD_TWO, pConfig->retryLimitTwo, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DYNAMIC_THRESHOLD_TWO to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_MEDIUM_TIME, pConfig->cfgMaxMediumTime, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_MEDIUM_TIME to CCM"); + } + +#ifdef FEATURE_WLAN_TDLS + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, + pConfig->fTDLSUapsdMask, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK to CCM"); + } + + if (TRUE == pConfig->fEnableTDLSScanCoexSupport) + { + /* TDLSScanCoexistance feature is supported when the DUT acts as only + * the Sleep STA and hence explicitly disable the BufferSta capability + * on the DUT. DUT's Buffer STA capability is explicitly disabled to + * ensure that the TDLS peer shall not go to TDLS power save mode. + */ + pConfig->fEnableTDLSBufferSta = FALSE; + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_BUF_STA_ENABLED, + pConfig->fEnableTDLSBufferSta, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_BUF_STA_ENABLED to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_PUAPSD_INACT_TIME, + pConfig->fTDLSPuapsdInactivityTimer, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_PUAPSD_INACT_TIME to CCM"); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_RX_FRAME_THRESHOLD, + pConfig->fTDLSRxFrameThreshold, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_RX_FRAME_THRESHOLD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED, + pConfig->fEnableTDLSOffChannel, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_BUF_STA_ENABLED to CCM\n"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TDLS_WMM_MODE_ENABLED, + pConfig->fEnableTDLSWmmMode, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_TDLS_WMM_MODE_ENABLED to CCM\n"); + } + +#endif + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_ADAPT_RX_DRAIN, + pConfig->fEnableAdaptRxDrain, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_ADAPT_RX_DRAIN to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_FLEX_CONNECT_POWER_FACTOR, + pConfig->flexConnectPowerFactor, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Failure: Could not pass on " + "WNI_CFG_FLEX_CONNECT_POWER_FACTOR to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ANTENNA_DIVESITY, + pConfig->antennaDiversity, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ANTENNA_DIVESITY to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ATH_DISABLE, + pConfig->cfgAthDisable, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ATH_DISABLE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_ACTIVE_WLAN_LEN, + pConfig->cfgBtcActiveWlanLen, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_BTC_ACTIVE_WLAN_LEN to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_ACTIVE_BT_LEN, + pConfig->cfgBtcActiveBtLen, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_BTC_ACTIVE_BT_LEN to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN, + pConfig->cfgBtcSapActiveWlanLen, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_BTC_ACTIVE_WLAN_LEN to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_SAP_ACTIVE_BT_LEN, + pConfig->cfgBtcSapActiveBtLen, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_BTC_ACTIVE_BT_LEN to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ASD_PROBE_INTERVAL, + pConfig->gAsdProbeInterval, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ASD_PROBE_INTERVAL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ASD_TRIGGER_THRESHOLD, + pConfig->gAsdTriggerThreshold, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ASD_TRIGGER_THRESHOLD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD, + pConfig->gAsdRTTRssiHystThreshold, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ASD_RSSI_HYST_THRESHOLD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL, + pConfig->debugP2pRemainOnChannel, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, + "Could not pass on WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_CTS2S_DURING_SCO, + pConfig->cfgBtcCTS2SduringSCO, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BTC_CTS2S_DURING_SCO to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_DEFAULT_RATE_INDEX_24GHZ, + defHddRateToDefCfgRate(pConfig->defaultRateIndex24Ghz), + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DEFAULT_RATE_INDEX_24GHZ to" + " CCM\n"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RA_FILTER_ENABLE, pConfig->cfgRAFilterEnable, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_RA_FILTER_ENABLE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RA_RATE_LIMIT_INTERVAL, pConfig->cfgRARateLimitInterval, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_RA_FILTER_ENABLE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE, + pConfig->cfgBtcFatalHidnSniffBlkGuidance, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE, + pConfig->cfgBtcCriticalHidnSniffBlkGuidance, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD, + pConfig->cfgBtcA2dpTxQueueThold, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD, + pConfig->cfgBtcOppTxQueueThold, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD to CCM"); + } + +#ifdef WLAN_FEATURE_11W + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + pConfig->pmfSaQueryMaxRetries, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SA_QUERY_MAX_RETRIES to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + pConfig->pmfSaQueryRetryInterval, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SA_QUERY_RETRY_INTERVAL to CCM"); + } +#endif + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_UAPSD_CONSEC_SP, + pConfig->maxUapsdConsecSP, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_UAPSD_CONSEC_SP"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT, + pConfig->maxUapsdConsecRxCnt, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT, + pConfig->maxUapsdConsecTxCnt, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW, + pConfig->uapsdConsecTxCntMeasWindow, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW, + pConfig->uapsdConsecRxCntMeasWindow, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE, + pConfig->maxPsPollInWmmUapsdMode, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS, + pConfig->maxUapsdInactivityIntervals, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_DYNAMIC_WMMPS, + pConfig->enableDynamicWMMPS, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_DYNAMIC_WMMPS"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BURST_MODE_BE_TXOP_VALUE, + pConfig->burstModeTXOPValue, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BURST_MODE_BE_TXOP_VALUE "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE, + pConfig->enableDynamicRAStartRate, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BTC_FAST_WLAN_CONN_PREF, + pConfig->btcFastWlanConnPref, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BTC_FAST_WLAN_CONN_PREF "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_RTSCTS_HTVHT, + pConfig->enableRtsCtsHtVht, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_ENABLE_RTSCTS_HTVHT to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TOGGLE_ARP_BDRATES, + pConfig->toggleArpBDRates, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on" + "WNI_CFG_TOGGLE_ARP_BDRATES to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN, + pConfig->btcStaticOppWlanIdleWlanLen, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN, + pConfig->btcStaticOppWlanIdleBtLen, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL, + pConfig->btc_disable_wlan_link_critical, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LINK_FAIL_TIMEOUT, + pConfig->linkFailTimeout, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_LINK_FAIL_TIMEOUT "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LINK_FAIL_TX_CNT, + pConfig->linkFailTxCnt, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_LINK_FAIL_TX_CNT "); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_OPTIMIZE_CA_EVENT, + pConfig->gOptimizeCAevent, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_OPTIMIZE_CA_EVENT "); + } + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_EXT_SCAN_CONC_MODE, pConfig->cfgExtScanConcMode, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_EXT_SCAN_CONC_MODE to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ACTIVE_PASSIVE_CON, + pConfig->gActivePassiveChCon, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ACTIVE_PASSIVE_CON "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MAC_ADDR_SPOOFING, + pConfig->enableMacSpoofing, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_MAC_ADDR_SPOOFING "); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DISABLE_BAR_WAKE_UP_HOST, + pConfig->disableBarWakeUp, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_BAR_WAKE_UP_HOST to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_SAR_BOFFSET_SET_CORRECTION, + pConfig->boffset_correction_enable, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_SAR_BOFFSET_SET_CORRECTION to CCM"); + } + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DISABLE_SCAN_DURING_SCO, + pConfig->disable_scan_during_sco, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_DISABLE_SCAN_DURING_SCO to CCM"); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_CONC_BMISS, + pConfig->enable_conc_bmiss, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_CONC_BMISS to CCM"); + } + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_UNITS_BWAIT, + pConfig->enable_units_bwait, NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Could not pass on WNI_CFG_ENABLE_UNITS_BWAIT to CCM"); + } + + if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB, + pConfig->trigger_nullframe_before_hb, NULL, + eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + fStatus = FALSE; + hddLog(LOGE, "Couldn't pass WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB to CCM"); + } + return fStatus; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_init_set_sme_config() - + + This function initializes the sme configuration parameters + + \param - pHddCtx - Pointer to the HDD Adapter. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + eHalStatus halStatus; + tpSmeConfigParams smeConfig; + + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + smeConfig = vos_mem_malloc(sizeof(tSmeConfigParams)); + if (NULL == smeConfig) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s smeConfig allocation failed",__func__); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_zero( smeConfig, sizeof( tSmeConfigParams ) ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s bWmmIsEnabled=%d 802_11e_enabled=%d dot11Mode=%d", __func__, + pConfig->WmmMode, pConfig->b80211eIsEnabled, pConfig->dot11Mode); + + // Config params obtained from the registry + + smeConfig->csrConfig.RTSThreshold = pConfig->RTSThreshold; + smeConfig->csrConfig.FragmentationThreshold = pConfig->FragmentationThreshold; + smeConfig->csrConfig.shortSlotTime = pConfig->ShortSlotTimeEnabled; + smeConfig->csrConfig.Is11dSupportEnabled = pConfig->Is11dSupportEnabled; + smeConfig->csrConfig.HeartbeatThresh24 = pConfig->HeartbeatThresh24; + + smeConfig->csrConfig.phyMode = hdd_cfg_xlate_to_csr_phy_mode ( pConfig->dot11Mode ); + + if( (pConfig->dot11Mode == eHDD_DOT11_MODE_abg) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11b) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11g) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11b_ONLY) || + (pConfig->dot11Mode == eHDD_DOT11_MODE_11g_ONLY)) + { + smeConfig->csrConfig.channelBondingMode24GHz = 0; + smeConfig->csrConfig.channelBondingMode5GHz = 0; + } + else + { + smeConfig->csrConfig.channelBondingMode24GHz = pConfig->nChannelBondingMode24GHz; + smeConfig->csrConfig.channelBondingMode5GHz = pConfig->nChannelBondingMode5GHz; + } + smeConfig->csrConfig.TxRate = pConfig->TxRate; + smeConfig->csrConfig.nScanResultAgeCount = pConfig->ScanResultAgeCount; + smeConfig->csrConfig.scanAgeTimeNCNPS = pConfig->nScanAgeTimeNCNPS; + smeConfig->csrConfig.scanAgeTimeNCPS = pConfig->nScanAgeTimeNCPS; + smeConfig->csrConfig.scanAgeTimeCNPS = pConfig->nScanAgeTimeCNPS; + smeConfig->csrConfig.scanAgeTimeCPS = pConfig->nScanAgeTimeCPS; + smeConfig->csrConfig.AdHocChannel24 = pConfig->OperatingChannel; + smeConfig->csrConfig.fEnforce11dChannels = pConfig->fEnforce11dChannels; + smeConfig->csrConfig.fSupplicantCountryCodeHasPriority = pConfig->fSupplicantCountryCodeHasPriority; + smeConfig->csrConfig.fEnforceCountryCodeMatch = pConfig->fEnforceCountryCodeMatch; + smeConfig->csrConfig.fEnforceDefaultDomain = pConfig->fEnforceDefaultDomain; + smeConfig->csrConfig.bCatRssiOffset = pConfig->nRssiCatGap; + smeConfig->csrConfig.vccRssiThreshold = pConfig->nVccRssiTrigger; + smeConfig->csrConfig.vccUlMacLossThreshold = pConfig->nVccUlMacLossThreshold; + smeConfig->csrConfig.nRoamingTime = pConfig->nRoamingTime; + smeConfig->csrConfig.IsIdleScanEnabled = pConfig->nEnableIdleScan; + smeConfig->csrConfig.nInitialDwellTime = pConfig->nInitialDwellTime; + smeConfig->csrConfig.nActiveMaxChnTime = pConfig->nActiveMaxChnTime; + smeConfig->csrConfig.nActiveMinChnTime = pConfig->nActiveMinChnTime; + smeConfig->csrConfig.nPassiveMaxChnTime = pConfig->nPassiveMaxChnTime; + smeConfig->csrConfig.nPassiveMinChnTime = pConfig->nPassiveMinChnTime; + smeConfig->csrConfig.max_chntime_btc_esco = + pConfig->max_chntime_btc_esco; + smeConfig->csrConfig.min_chntime_btc_esco = + pConfig->min_chntime_btc_esco; + smeConfig->csrConfig.min_chntime_btc_sco = + pConfig->min_chntime_btc_sco; + smeConfig->csrConfig.max_chntime_btc_sco = + pConfig->max_chntime_btc_sco; + smeConfig->csrConfig.disableAggWithBtc = pConfig->disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + smeConfig->csrConfig.nActiveMaxChnTimeConc = pConfig->nActiveMaxChnTimeConc; + smeConfig->csrConfig.nActiveMinChnTimeConc = pConfig->nActiveMinChnTimeConc; + smeConfig->csrConfig.nPassiveMaxChnTimeConc = pConfig->nPassiveMaxChnTimeConc; + smeConfig->csrConfig.nPassiveMinChnTimeConc = pConfig->nPassiveMinChnTimeConc; + smeConfig->csrConfig.nRestTimeConc = pConfig->nRestTimeConc; + smeConfig->csrConfig.nNumStaChanCombinedConc = pConfig->nNumStaChanCombinedConc; + smeConfig->csrConfig.nNumP2PChanCombinedConc = pConfig->nNumP2PChanCombinedConc; + +#endif + smeConfig->csrConfig.Is11eSupportEnabled = pConfig->b80211eIsEnabled; + smeConfig->csrConfig.WMMSupportMode = pConfig->WmmMode; + +#if defined WLAN_FEATURE_VOWIFI + smeConfig->rrmConfig.rrmEnabled = pConfig->fRrmEnable; + smeConfig->rrmConfig.maxRandnInterval = pConfig->nRrmRandnIntvl; +#endif + //Remaining config params not obtained from registry + // On RF EVB beacon using channel 1. +#ifdef WLAN_FEATURE_11AC + smeConfig->csrConfig.nVhtChannelWidth = pConfig->vhtChannelWidth; + smeConfig->csrConfig.enableTxBF = pConfig->enableTxBF; + smeConfig->csrConfig.txBFCsnValue = pConfig->txBFCsnValue; + smeConfig->csrConfig.enableVhtFor24GHz = pConfig->enableVhtFor24GHzBand; + /* Consider Mu-beamformee only if SU-beamformee is enabled */ + if ( pConfig->enableTxBF ) + smeConfig->csrConfig.enableMuBformee = pConfig->enableMuBformee; + else + smeConfig->csrConfig.enableMuBformee = 0; +#endif + smeConfig->csrConfig.AdHocChannel5G = pConfig->AdHocChannel5G; + smeConfig->csrConfig.AdHocChannel24 = pConfig->AdHocChannel24G; + smeConfig->csrConfig.ProprietaryRatesEnabled = 0; + smeConfig->csrConfig.HeartbeatThresh50 = 40; + smeConfig->csrConfig.bandCapability = pConfig->nBandCapability; + if (pConfig->nBandCapability == eCSR_BAND_24) + { + smeConfig->csrConfig.Is11hSupportEnabled = 0; + } else { + smeConfig->csrConfig.Is11hSupportEnabled = pConfig->Is11hSupportEnabled; + } + smeConfig->csrConfig.cbChoice = 0; + smeConfig->csrConfig.bgScanInterval = 0; + smeConfig->csrConfig.eBand = pConfig->nBandCapability; + smeConfig->csrConfig.nTxPowerCap = pConfig->nTxPowerCap; + smeConfig->csrConfig.fEnableBypass11d = pConfig->enableBypass11d; + smeConfig->csrConfig.fEnableDFSChnlScan = pConfig->enableDFSChnlScan; + smeConfig->csrConfig.disable_scan_during_sco = + pConfig->disable_scan_during_sco; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + smeConfig->csrConfig.nRoamPrefer5GHz = pConfig->nRoamPrefer5GHz; + smeConfig->csrConfig.nRoamIntraBand = pConfig->nRoamIntraBand; + smeConfig->csrConfig.nProbes = pConfig->nProbes; + smeConfig->csrConfig.nRoamScanHomeAwayTime = pConfig->nRoamScanHomeAwayTime; +#endif + smeConfig->csrConfig.fFirstScanOnly2GChnl = pConfig->enableFirstScan2GOnly; + + //FIXME 11d config is hardcoded + if ( VOS_STA_SAP_MODE != hdd_get_conparam()) + { + smeConfig->csrConfig.Csr11dinfo.Channels.numChannels = 0; + + /* if there is a requirement that HDD will control the default + * channel list & country code (say from .ini file) we need to + * add some logic here. Otherwise the default 11d info should + * come from NV as per our current implementation */ + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "AP country Code %s", pConfig->apCntryCode); + + if (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0) + sme_setRegInfo(pHddCtx->hHal, pConfig->apCntryCode); + sme_set11dinfo(pHddCtx->hHal, smeConfig); + } + hdd_set_power_save_config(pHddCtx, smeConfig); + hdd_set_btc_config(pHddCtx); + +#ifdef WLAN_FEATURE_VOWIFI_11R + smeConfig->csrConfig.csr11rConfig.IsFTResourceReqSupported = pConfig->fFTResourceReqSupported; +#endif +#ifdef FEATURE_WLAN_LFR + smeConfig->csrConfig.isFastRoamIniFeatureEnabled = pConfig->isFastRoamIniFeatureEnabled; + smeConfig->csrConfig.MAWCEnabled = pConfig->MAWCEnabled; +#endif +#ifdef FEATURE_WLAN_ESE + smeConfig->csrConfig.isEseIniFeatureEnabled = pConfig->isEseIniFeatureEnabled; + if( pConfig->isEseIniFeatureEnabled ) + { + pConfig->isFastTransitionEnabled = TRUE; + } +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + smeConfig->csrConfig.isFastTransitionEnabled = pConfig->isFastTransitionEnabled; + smeConfig->csrConfig.RoamRssiDiff = pConfig->RoamRssiDiff; + smeConfig->csrConfig.nImmediateRoamRssiDiff = pConfig->nImmediateRoamRssiDiff; + smeConfig->csrConfig.isWESModeEnabled = pConfig->isWESModeEnabled; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + smeConfig->csrConfig.isRoamOffloadScanEnabled = + pConfig->isRoamOffloadScanEnabled; + smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = + pConfig->bFastRoamInConIniFeatureEnabled; + smeConfig->csrConfig.isPERRoamEnabled = + pConfig->isPERRoamEnabled; + smeConfig->csrConfig.rateUpThreshold = pConfig->rateUpThreshold; + smeConfig->csrConfig.rateDownThreshold = pConfig->rateDownThreshold; + smeConfig->csrConfig.waitPeriodForNextPERScan = + pConfig->waitPeriodForNextPERScan; + smeConfig->csrConfig.PERtimerThreshold = pConfig->PERtimerThreshold; + smeConfig->csrConfig.isPERRoamCCAEnabled = pConfig->isPERRoamCCAEnabled; + smeConfig->csrConfig.PERRoamFullScanThreshold = + pConfig->PERRoamFullScanThreshold * -1; + smeConfig->csrConfig.PERroamTriggerPercent = pConfig->PERroamTriggerPercent; + smeConfig->csrConfig.PERMinRssiThresholdForRoam = + pConfig->PERMinRssiThresholdForRoam; + + if (0 == smeConfig->csrConfig.isRoamOffloadScanEnabled) + { + /* Disable roaming in concurrency if roam scan offload is disabled */ + smeConfig->csrConfig.bFastRoamInConIniFeatureEnabled = 0; + } +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + smeConfig->csrConfig.enable_lfr_mbb = pConfig->enable_lfr_mbb; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + smeConfig->csrConfig.neighborRoamConfig.nNeighborReassocRssiThreshold = pConfig->nNeighborReassocRssiThreshold; + smeConfig->csrConfig.neighborRoamConfig.nNeighborLookupRssiThreshold = pConfig->nNeighborLookupRssiThreshold; + smeConfig->csrConfig.neighborRoamConfig.nNeighborScanMaxChanTime = pConfig->nNeighborScanMaxChanTime; + smeConfig->csrConfig.neighborRoamConfig.nNeighborScanMinChanTime = pConfig->nNeighborScanMinChanTime; + smeConfig->csrConfig.neighborRoamConfig.nNeighborScanTimerPeriod = pConfig->nNeighborScanPeriod; + smeConfig->csrConfig.neighborRoamConfig.nMaxNeighborRetries = pConfig->nMaxNeighborReqTries; + smeConfig->csrConfig.neighborRoamConfig.nNeighborResultsRefreshPeriod = pConfig->nNeighborResultsRefreshPeriod; + smeConfig->csrConfig.neighborRoamConfig.nEmptyScanRefreshPeriod = pConfig->nEmptyScanRefreshPeriod; + //Making Forced 5G roaming to tightly coupled with the gEnableFirstScan2GOnly + //=1 only, Also making sure if HW does not support 5G RF band then no need to + //enable this feature even though it is enabled in .ini. + if((pConfig->enableFirstScan2GOnly) && (pConfig->nBandCapability != eCSR_BAND_24)) + { + smeConfig->csrConfig.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable + = pConfig->nNeighborInitialForcedRoamTo5GhEnable; + } + smeConfig->csrConfig.neighborRoamConfig.nWeakZoneRssiThresholdForRoam = + pConfig->nWeakZoneRssiThresholdForRoam; + hdd_string_to_u8_array( pConfig->neighborScanChanList, + smeConfig->csrConfig.neighborRoamConfig.neighborScanChanList.channelList, + &smeConfig->csrConfig.neighborRoamConfig.neighborScanChanList.numChannels, + WNI_CFG_VALID_CHANNEL_LIST_LEN, "," ); +#endif + + smeConfig->csrConfig.addTSWhenACMIsOff = pConfig->AddTSWhenACMIsOff; + smeConfig->csrConfig.fValidateList = pConfig->fValidateScanList; + smeConfig->csrConfig.allowDFSChannelRoam = pConfig->allowDFSChannelRoam; + //Enable/Disable MCC + smeConfig->csrConfig.fEnableMCCMode = pConfig->enableMCC; + smeConfig->csrConfig.fAllowMCCGODiffBI = pConfig->allowMCCGODiffBI; + + //Scan Results Aging Time out value + smeConfig->csrConfig.scanCfgAgingTime = pConfig->scanAgingTimeout; + + smeConfig->csrConfig.enableTxLdpc = pConfig->enableTxLdpc; + + smeConfig->csrConfig.isAmsduSupportInAMPDU = pConfig->isAmsduSupportInAMPDU; + if(pConfig->nBandCapability != eCSR_BAND_24) + { + smeConfig->csrConfig.nSelect5GHzMargin = pConfig->nSelect5GHzMargin; + } + smeConfig->csrConfig.ignorePeerErpInfo = pConfig->ignorePeerErpInfo; + smeConfig->csrConfig.ignorePeerHTopMode = pConfig->ignorePeerHTopMode; + smeConfig->csrConfig.disableP2PMacSpoofing = pConfig->disableP2PMacSpoofing; + smeConfig->csrConfig.enableFatalEvent= pConfig->enableFatalEvent; + smeConfig->csrConfig.initialScanSkipDFSCh = pConfig->initialScanSkipDFSCh; + + smeConfig->csrConfig.isCoalesingInIBSSAllowed = + pHddCtx->cfg_ini->isCoalesingInIBSSAllowed; + + + /* update SSR config */ + sme_UpdateEnableSSR((tHalHandle)(pHddCtx->hHal), pHddCtx->cfg_ini->enableSSR); + /* Update the Directed scan offload setting */ + smeConfig->fScanOffload = pHddCtx->cfg_ini->fScanOffload; + + smeConfig->csrConfig.scanBandPreference = + pHddCtx->cfg_ini->acsScanBandPreference; + + smeConfig->fEnableDebugLog = pHddCtx->cfg_ini->gEnableDebugLog; + smeConfig->csrConfig.sendDeauthBeforeCon = pConfig->sendDeauthBeforeCon; + smeConfig->csrConfig.nOBSSScanWidthTriggerInterval = + pConfig->nOBSSScanWidthTriggerInterval; + smeConfig->fDeferIMPSTime = pHddCtx->cfg_ini->deferImpsTime; + smeConfig->fBtcEnableIndTimerVal = pHddCtx->cfg_ini->btcEnableIndTimerVal; + smeConfig->csrConfig.roamDelayStatsEnabled = pHddCtx->cfg_ini->gEnableRoamDelayStats; + smeConfig->csrConfig.max_chan_for_dwell_time_cfg = + pHddCtx->cfg_ini->max_chan_for_dwell_time_cfg; + + smeConfig->csrConfig.enable_edca_params = + pHddCtx->cfg_ini->enable_edca_params; + + smeConfig->csrConfig.edca_vo_cwmin = + pHddCtx->cfg_ini->edca_vo_cwmin; + smeConfig->csrConfig.edca_vi_cwmin = + pHddCtx->cfg_ini->edca_vi_cwmin; + smeConfig->csrConfig.edca_bk_cwmin = + pHddCtx->cfg_ini->edca_bk_cwmin; + smeConfig->csrConfig.edca_be_cwmin = + pHddCtx->cfg_ini->edca_be_cwmin; + + smeConfig->csrConfig.edca_vo_cwmax = + pHddCtx->cfg_ini->edca_vo_cwmax; + smeConfig->csrConfig.edca_vi_cwmax = + pHddCtx->cfg_ini->edca_vi_cwmax; + smeConfig->csrConfig.edca_bk_cwmax = + pHddCtx->cfg_ini->edca_bk_cwmax; + smeConfig->csrConfig.edca_be_cwmax = + pHddCtx->cfg_ini->edca_be_cwmax; + + smeConfig->csrConfig.edca_vo_aifs = + pHddCtx->cfg_ini->edca_vo_aifs; + smeConfig->csrConfig.edca_vi_aifs = + pHddCtx->cfg_ini->edca_vi_aifs; + smeConfig->csrConfig.edca_bk_aifs = + pHddCtx->cfg_ini->edca_bk_aifs; + smeConfig->csrConfig.edca_be_aifs = + pHddCtx->cfg_ini->edca_be_aifs; + + smeConfig->csrConfig.sta_auth_retries_for_code17 = + pHddCtx->cfg_ini->sta_auth_retries_for_code17; + + sme_set_mgmt_frm_via_wq5((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->sendMgmtPktViaWQ5); + + vos_set_multicast_logging(pHddCtx->cfg_ini->multicast_host_msgs); + halStatus = sme_UpdateConfig( pHddCtx->hHal, smeConfig); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + status = VOS_STATUS_E_FAILURE; + hddLog(LOGE, "sme_UpdateConfig() return failure %d", halStatus); + } + + vos_mem_free(smeConfig); + return status; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_execute_config_command() - + + This function executes an arbitrary configuration set command + + \param - pHddCtx - Pointer to the HDD Adapter. + \parmm - command - a configuration command of the form: + = + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_execute_config_command(hdd_context_t *pHddCtx, char *command) +{ + size_t tableSize = sizeof(g_registry_table)/sizeof(g_registry_table[0]); + REG_TABLE_ENTRY *pRegEntry; + char *clone; + char *pCmd; + void *pField; + char *name; + char *value_str; + v_U32_t value; + v_S31_t svalue; + size_t len_value_str; + unsigned int idx; + unsigned int i; + VOS_STATUS vstatus; + int rv; + + // assume failure until proven otherwise + vstatus = VOS_STATUS_E_FAILURE; + + // clone the command so that we can manipulate it + clone = kstrdup(command, GFP_ATOMIC); + if (NULL == clone) + { + hddLog(LOGE, "%s: memory allocation failure, unable to process [%s]", + __func__, command); + return vstatus; + } + + // 'clone' will point to the beginning of the string so it can be freed + // 'pCmd' will be used to walk/parse the command + pCmd = clone; + + // get rid of leading/trailing whitespace + pCmd = i_trim(pCmd); + if ('\0' == *pCmd) + { + // only whitespace + hddLog(LOGE, "%s: invalid command, only whitespace:[%s]", + __func__, command); + goto done; + } + + // parse the = + name = pCmd; + while (('=' != *pCmd) && ('\0' != *pCmd)) + { + pCmd++; + } + if ('\0' == *pCmd) + { + // did not find '=' + hddLog(LOGE, "%s: invalid command, no '=':[%s]", + __func__, command); + goto done; + } + + // replace '=' with NUL to terminate the + *pCmd++ = '\0'; + name = i_trim(name); + if ('\0' == *name) + { + // did not find a name + hddLog(LOGE, "%s: invalid command, no :[%s]", + __func__, command); + goto done; + } + + value_str = i_trim(pCmd); + if ('\0' == *value_str) + { + // did not find a value + hddLog(LOGE, "%s: invalid command, no :[%s]", + __func__, command); + goto done; + } + + // lookup the configuration item + for (idx = 0; idx < tableSize; idx++) + { + if (0 == strcmp(name, g_registry_table[idx].RegName)) + { + // found a match + break; + } + } + if (tableSize == idx) + { + // did not match the name + hddLog(LOGE, "%s: invalid command, unknown configuration item:[%s]", + __func__, command); + goto done; + } + + pRegEntry = &g_registry_table[idx]; + if (!(pRegEntry->Flags & VAR_FLAGS_DYNAMIC_CFG)) + { + // does not support dynamic configuration + hddLog(LOGE, "%s: invalid command, %s does not support " + "dynamic configuration", __func__, name); + goto done; + } + + pField = ((v_U8_t *)pHddCtx->cfg_ini) + pRegEntry->VarOffset; + + switch (pRegEntry->RegType) + { + case WLAN_PARAM_Integer: + rv = kstrtou32(value_str, 10, &value); + if (rv < 0) + goto done; + if (value < pRegEntry->VarMin) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %u < min value %lu", + __func__, value, pRegEntry->VarMin); + goto done; + } + if (value > pRegEntry->VarMax) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %u > max value %lu", + __func__, value, pRegEntry->VarMax); + goto done; + } + memcpy(pField, &value, pRegEntry->VarSize); + break; + + case WLAN_PARAM_HexInteger: + rv = kstrtou32(value_str, 16, &value); + if (rv < 0) + goto done; + if (value < pRegEntry->VarMin) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %x < min value %lx", + __func__, value, pRegEntry->VarMin); + goto done; + } + if (value > pRegEntry->VarMax) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %x > max value %lx", + __func__, value, pRegEntry->VarMax); + goto done; + } + memcpy(pField, &value, pRegEntry->VarSize); + break; + + case WLAN_PARAM_SignedInteger: + rv = kstrtos32(value_str, 10, &svalue); + if (rv < 0) + goto done; + if (svalue < (v_S31_t)pRegEntry->VarMin) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %d < min value %d", + __func__, svalue, (int)pRegEntry->VarMin); + goto done; + } + if (svalue > (v_S31_t)pRegEntry->VarMax) + { + // out of range + hddLog(LOGE, "%s: invalid command, value %d > max value %d", + __func__, svalue, (int)pRegEntry->VarMax); + goto done; + } + memcpy(pField, &svalue, pRegEntry->VarSize); + break; + + case WLAN_PARAM_String: + len_value_str = strlen(value_str); + if (len_value_str > (pRegEntry->VarSize - 1)) + { + // too big + hddLog(LOGE, + "%s: invalid command, string [%s] length " + "%zu exceeds maximum length %u", + __func__, value_str, + len_value_str, (pRegEntry->VarSize - 1)); + goto done; + } + // copy string plus NUL + memcpy(pField, value_str, (len_value_str + 1)); + break; + + case WLAN_PARAM_MacAddr: + len_value_str = strlen(value_str); + if (len_value_str != (VOS_MAC_ADDR_SIZE * 2)) + { + // out of range + hddLog(LOGE, + "%s: invalid command, MAC address [%s] length " + "%zu is not expected length %u", + __func__, value_str, + len_value_str, (VOS_MAC_ADDR_SIZE * 2)); + goto done; + } + //parse the string and store it in the byte array + for (i = 0; i < VOS_MAC_ADDR_SIZE; i++) + { + ((char*)pField)[i] = (char) + ((parseHexDigit(value_str[(i * 2)]) * 16) + + parseHexDigit(value_str[(i * 2) + 1])); + } + break; + + default: + goto done; + } + + // if we get here, we had a successful modification + vstatus = VOS_STATUS_SUCCESS; + + // config table has been modified, is there a notifier? + if (NULL != pRegEntry->pfnDynamicNotify) + { + (pRegEntry->pfnDynamicNotify)(pHddCtx, pRegEntry->NotifyId); + } + + // note that this item was explicitly configured + if (idx < MAX_CFG_INI_ITEMS) + { + set_bit(idx, (void *)&pHddCtx->cfg_ini->bExplicitCfg); + } + done: + kfree(clone); + return vstatus; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_is_okc_mode_enabled() - + + This function returns whether OKC mode is enabled or not + + \param - pHddCtx - Pointer to the HDD Adapter. + + \return - 1 for enabled, zero for disabled + + --------------------------------------------------------------------------*/ + +tANI_BOOLEAN hdd_is_okc_mode_enabled(hdd_context_t *pHddCtx) +{ + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pHddCtx is NULL", __func__); + return -EINVAL; + } + +#ifdef FEATURE_WLAN_OKC + return pHddCtx->cfg_ini->isOkcIniFeatureEnabled; +#else + return eANI_BOOLEAN_FALSE; +#endif +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c new file mode 100644 index 000000000000..c9c56e849a39 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -0,0 +1,20804 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + * + */ + + + + +/**======================================================================== + + \file wlan_hdd_cfg80211.c + + \brief WLAN Host Device Driver implementation + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 21/12/09 Ashwani Created module. + + 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID + Ganesh K + ==========================================================================*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ccmApi.h" +#include "sirParams.h" +#include "dot11f.h" +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_wext.h" +#include "sme_Api.h" +#include "wlan_hdd_p2p.h" +#include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_hostapd.h" +#include "sapInternal.h" +#include "wlan_hdd_softap_tx_rx.h" +#include "wlan_hdd_main.h" +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_power.h" +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#ifdef WLAN_BTAMP_FEATURE +#include "bap_hdd_misc.h" +#endif +#include +#include "wlan_hdd_tdls.h" +#include "wlan_hdd_wmm.h" +#include "wlan_qct_wda.h" +#include "wlan_nv.h" +#include "wlan_hdd_dev_pwr.h" +#include "qwlan_version.h" +#include "wlan_logging_sock_svc.h" +#include "wlan_hdd_misc.h" + + +#define g_mode_rates_size (12) +#define a_mode_rates_size (8) +#define FREQ_BASE_80211G (2407) +#define FREQ_BAND_DIFF_80211G (5) +#define MAX_SCAN_SSID 9 +#define MAX_PENDING_LOG 5 +#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \ + ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields))) + +#define HDD2GHZCHAN(freq, chan, flag) { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (freq), \ + .hw_value = (chan),\ + .flags = (flag), \ + .max_antenna_gain = 0 ,\ + .max_power = 30, \ +} + +#define HDD5GHZCHAN(freq, chan, flag) { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = (freq), \ + .hw_value = (chan),\ + .flags = (flag), \ + .max_antenna_gain = 0 ,\ + .max_power = 30, \ +} + +#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\ +{\ + .bitrate = rate, \ + .hw_value = rate_id, \ + .flags = flag, \ +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03 +#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04 +#endif + +#define HDD_CHANNEL_14 14 +#define WLAN_HDD_MAX_FEATURE_SET 8 + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* + * Used to allocate the size of 4096 for the link layer stats. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements on link layer + * statistics. + */ +#define LL_STATS_EVENT_BUF_SIZE 4096 +#endif +#ifdef WLAN_FEATURE_EXTSCAN +/* + * Used to allocate the size of 4096 for the EXTScan NL data. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements. + */ + +#define EXTSCAN_EVENT_BUF_SIZE 4096 +#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32 +#endif + +/*EXT TDLS*/ +/* + * Used to allocate the size of 4096 for the TDLS. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements on link layer + * statistics. + */ +#define EXTTDLS_EVENT_BUF_SIZE 4096 + +/* + * Values for Mac spoofing feature + * + */ +#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0 +#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1 +#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2 +#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms + +/* + * max_sched_scan_plans defined to 10 + */ +#define MAX_SCHED_SCAN_PLANS 10 + +static const u32 hdd_cipher_suites[] = +{ + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, +#ifdef FEATURE_WLAN_ESE +#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */ + WLAN_CIPHER_SUITE_KRK, + WLAN_CIPHER_SUITE_CCMP, +#else + WLAN_CIPHER_SUITE_CCMP, +#endif +#ifdef FEATURE_WLAN_WAPI + WLAN_CIPHER_SUITE_SMS4, +#endif +#ifdef WLAN_FEATURE_11W + WLAN_CIPHER_SUITE_AES_CMAC, +#endif +}; + +static inline int is_broadcast_ether_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} + +const static struct ieee80211_channel hdd_channels_2_4_GHZ[] = +{ + HDD2GHZCHAN(2412, 1, 0) , + HDD2GHZCHAN(2417, 2, 0) , + HDD2GHZCHAN(2422, 3, 0) , + HDD2GHZCHAN(2427, 4, 0) , + HDD2GHZCHAN(2432, 5, 0) , + HDD2GHZCHAN(2437, 6, 0) , + HDD2GHZCHAN(2442, 7, 0) , + HDD2GHZCHAN(2447, 8, 0) , + HDD2GHZCHAN(2452, 9, 0) , + HDD2GHZCHAN(2457, 10, 0) , + HDD2GHZCHAN(2462, 11, 0) , + HDD2GHZCHAN(2467, 12, 0) , + HDD2GHZCHAN(2472, 13, 0) , + HDD2GHZCHAN(2484, 14, 0) , +}; + +const static struct ieee80211_channel hdd_channels_5_GHZ[] = +{ + HDD5GHZCHAN(4920, 240, 0) , + HDD5GHZCHAN(4940, 244, 0) , + HDD5GHZCHAN(4960, 248, 0) , + HDD5GHZCHAN(4980, 252, 0) , + HDD5GHZCHAN(5040, 208, 0) , + HDD5GHZCHAN(5060, 212, 0) , + HDD5GHZCHAN(5080, 216, 0) , + HDD5GHZCHAN(5180, 36, 0) , + HDD5GHZCHAN(5200, 40, 0) , + HDD5GHZCHAN(5220, 44, 0) , + HDD5GHZCHAN(5240, 48, 0) , + HDD5GHZCHAN(5260, 52, 0) , + HDD5GHZCHAN(5280, 56, 0) , + HDD5GHZCHAN(5300, 60, 0) , + HDD5GHZCHAN(5320, 64, 0) , + HDD5GHZCHAN(5500,100, 0) , + HDD5GHZCHAN(5520,104, 0) , + HDD5GHZCHAN(5540,108, 0) , + HDD5GHZCHAN(5560,112, 0) , + HDD5GHZCHAN(5580,116, 0) , + HDD5GHZCHAN(5600,120, 0) , + HDD5GHZCHAN(5620,124, 0) , + HDD5GHZCHAN(5640,128, 0) , + HDD5GHZCHAN(5660,132, 0) , + HDD5GHZCHAN(5680,136, 0) , + HDD5GHZCHAN(5700,140, 0) , +#ifdef FEATURE_WLAN_CH144 + HDD5GHZCHAN(5720,144, 0) , +#endif /* FEATURE_WLAN_CH144 */ + HDD5GHZCHAN(5745,149, 0) , + HDD5GHZCHAN(5765,153, 0) , + HDD5GHZCHAN(5785,157, 0) , + HDD5GHZCHAN(5805,161, 0) , + HDD5GHZCHAN(5825,165, 0) , +}; + +static struct ieee80211_rate g_mode_rates[] = +{ + HDD_G_MODE_RATETAB(10, 0x1, 0), + HDD_G_MODE_RATETAB(20, 0x2, 0), + HDD_G_MODE_RATETAB(55, 0x4, 0), + HDD_G_MODE_RATETAB(110, 0x8, 0), + HDD_G_MODE_RATETAB(60, 0x10, 0), + HDD_G_MODE_RATETAB(90, 0x20, 0), + HDD_G_MODE_RATETAB(120, 0x40, 0), + HDD_G_MODE_RATETAB(180, 0x80, 0), + HDD_G_MODE_RATETAB(240, 0x100, 0), + HDD_G_MODE_RATETAB(360, 0x200, 0), + HDD_G_MODE_RATETAB(480, 0x400, 0), + HDD_G_MODE_RATETAB(540, 0x800, 0), +}; + +static struct ieee80211_rate a_mode_rates[] = +{ + HDD_G_MODE_RATETAB(60, 0x10, 0), + HDD_G_MODE_RATETAB(90, 0x20, 0), + HDD_G_MODE_RATETAB(120, 0x40, 0), + HDD_G_MODE_RATETAB(180, 0x80, 0), + HDD_G_MODE_RATETAB(240, 0x100, 0), + HDD_G_MODE_RATETAB(360, 0x200, 0), + HDD_G_MODE_RATETAB(480, 0x400, 0), + HDD_G_MODE_RATETAB(540, 0x800, 0), +}; + +static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ = +{ + .channels = NULL, + .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ), + .band = IEEE80211_BAND_2GHZ, + .bitrates = g_mode_rates, + .n_bitrates = g_mode_rates_size, + .ht_cap.ht_supported = 1, + .ht_cap.cap = IEEE80211_HT_CAP_SGI_20 + | IEEE80211_HT_CAP_GRN_FLD + | IEEE80211_HT_CAP_DSSSCCK40 + | IEEE80211_HT_CAP_LSIG_TXOP_PROT, + .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, + .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ), + .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, +}; + +static struct ieee80211_supported_band wlan_hdd_band_5_GHZ = +{ + .channels = NULL, + .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ), + .band = IEEE80211_BAND_5GHZ, + .bitrates = a_mode_rates, + .n_bitrates = a_mode_rates_size, + .ht_cap.ht_supported = 1, + .ht_cap.cap = IEEE80211_HT_CAP_SGI_20 + | IEEE80211_HT_CAP_GRN_FLD + | IEEE80211_HT_CAP_DSSSCCK40 + | IEEE80211_HT_CAP_LSIG_TXOP_PROT + | IEEE80211_HT_CAP_SGI_40 + | IEEE80211_HT_CAP_SUP_WIDTH_20_40, + .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, + .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ), + .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED, +}; + +/* This structure contain information what kind of frame are expected in + TX/RX direction for each kind of interface */ +static const struct ieee80211_txrx_stypes +wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ACTION) | + BIT(SIR_MAC_MGMT_PROBE_REQ), + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) | + BIT(SIR_MAC_MGMT_REASSOC_REQ) | + BIT(SIR_MAC_MGMT_PROBE_REQ) | + BIT(SIR_MAC_MGMT_DISASSOC) | + BIT(SIR_MAC_MGMT_AUTH) | + BIT(SIR_MAC_MGMT_DEAUTH) | + BIT(SIR_MAC_MGMT_ACTION), + }, + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) | + BIT(SIR_MAC_MGMT_REASSOC_REQ) | + BIT(SIR_MAC_MGMT_PROBE_REQ) | + BIT(SIR_MAC_MGMT_DISASSOC) | + BIT(SIR_MAC_MGMT_AUTH) | + BIT(SIR_MAC_MGMT_DEAUTH) | + BIT(SIR_MAC_MGMT_ACTION), + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ACTION) | + BIT(SIR_MAC_MGMT_PROBE_REQ), + }, + [NL80211_IFTYPE_P2P_GO] = { + /* This is also same as for SoftAP */ + .tx = 0xffff, + .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) | + BIT(SIR_MAC_MGMT_REASSOC_REQ) | + BIT(SIR_MAC_MGMT_PROBE_REQ) | + BIT(SIR_MAC_MGMT_DISASSOC) | + BIT(SIR_MAC_MGMT_AUTH) | + BIT(SIR_MAC_MGMT_DEAUTH) | + BIT(SIR_MAC_MGMT_ACTION), + }, +}; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +static const struct ieee80211_iface_limit +wlan_hdd_iface_limit[] = { + { + /* max = 3 ; Our driver create two interfaces during driver init + * wlan0 and p2p0 interfaces. p2p0 is considered as station + * interface until a group is formed. In JB architecture, once the + * group is formed, interface type of p2p0 is changed to P2P GO or + * Client. + * When supplicant remove the group, it first issue a set interface + * cmd to change the mode back to Station. In JB this works fine as + * we advertize two station type interface during driver init. + * Some vendors create separate interface for P2P GO/Client, + * after group formation(Third one). But while group remove + * supplicant first tries to change the mode(3rd interface) to STATION + * But as we advertized only two sta type interfaces nl80211 was + * returning error for the third one which was leading to failure in + * delete interface. Ideally while removing the group, supplicant + * should not try to change the 3rd interface mode to Station type. + * Till we get a fix in wpa_supplicant, we advertize max STA + * interface type to 3 + */ + .max = 3, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT), + }, +}; + +/* By default, only single channel concurrency is allowed */ +static struct ieee80211_iface_combination +wlan_hdd_iface_combination = { + .limits = wlan_hdd_iface_limit, + .num_different_channels = 1, + /* + * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0 + * and p2p0 interfaces during driver init + * Some vendors create separate interface for P2P operations. + * wlan0: STA interface + * p2p0: P2P Device interface, action frames goes + * through this interface. + * p2p-xx: P2P interface, After GO negotiation this interface is + * created for p2p operations(GO/CLIENT interface). + */ + .max_interfaces = WLAN_MAX_INTERFACES, + .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit), + .beacon_int_infra_match = false, +}; +#endif + +static struct cfg80211_ops wlan_hdd_cfg80211_ops; + +/* Data rate 100KBPS based on IE Index */ +struct index_data_rate_type +{ + v_U8_t beacon_rate_index; + v_U16_t supported_rate[4]; +}; + +/* 11B, 11G Rate table include Basic rate and Extended rate + The IDX field is the rate index + The HI field is the rate when RSSI is strong or being ignored + (in this case we report actual rate) + The MID field is the rate when RSSI is moderate + (in this case we cap 11b rates at 5.5 and 11g rates at 24) + The LO field is the rate when RSSI is low + (in this case we don't report rates, actual current rate used) + */ +static const struct +{ + v_U8_t beacon_rate_index; + v_U16_t supported_rate[4]; +} supported_data_rate[] = +{ +/* IDX HI HM LM LO (RSSI-based index */ + {2, { 10, 10, 10, 0}}, + {4, { 20, 20, 10, 0}}, + {11, { 55, 20, 10, 0}}, + {12, { 60, 55, 20, 0}}, + {18, { 90, 55, 20, 0}}, + {22, {110, 55, 20, 0}}, + {24, {120, 90, 60, 0}}, + {36, {180, 120, 60, 0}}, + {44, {220, 180, 60, 0}}, + {48, {240, 180, 90, 0}}, + {66, {330, 180, 90, 0}}, + {72, {360, 240, 90, 0}}, + {96, {480, 240, 120, 0}}, + {108, {540, 240, 120, 0}} +}; + +/* MCS Based rate table */ +static struct index_data_rate_type supported_mcs_rate[] = +{ +/* MCS L20 L40 S20 S40 */ + {0, {65, 135, 72, 150}}, + {1, {130, 270, 144, 300}}, + {2, {195, 405, 217, 450}}, + {3, {260, 540, 289, 600}}, + {4, {390, 810, 433, 900}}, + {5, {520, 1080, 578, 1200}}, + {6, {585, 1215, 650, 1350}}, + {7, {650, 1350, 722, 1500}} +}; + +#ifdef WLAN_FEATURE_11AC + +#define DATA_RATE_11AC_MCS_MASK 0x03 + +struct index_vht_data_rate_type +{ + v_U8_t beacon_rate_index; + v_U16_t supported_VHT80_rate[2]; + v_U16_t supported_VHT40_rate[2]; + v_U16_t supported_VHT20_rate[2]; +}; + +typedef enum +{ + DATA_RATE_11AC_MAX_MCS_7, + DATA_RATE_11AC_MAX_MCS_8, + DATA_RATE_11AC_MAX_MCS_9, + DATA_RATE_11AC_MAX_MCS_NA +} eDataRate11ACMaxMcs; + +/* SSID broadcast type */ +typedef enum eSSIDBcastType +{ + eBCAST_UNKNOWN = 0, + eBCAST_NORMAL = 1, + eBCAST_HIDDEN = 2, +} tSSIDBcastType; + +/* MCS Based VHT rate table */ +static struct index_vht_data_rate_type supported_vht_mcs_rate[] = +{ +/* MCS L80 S80 L40 S40 L20 S40*/ + {0, {293, 325}, {135, 150}, {65, 72}}, + {1, {585, 650}, {270, 300}, {130, 144}}, + {2, {878, 975}, {405, 450}, {195, 217}}, + {3, {1170, 1300}, {540, 600}, {260, 289}}, + {4, {1755, 1950}, {810, 900}, {390, 433}}, + {5, {2340, 2600}, {1080, 1200}, {520, 578}}, + {6, {2633, 2925}, {1215, 1350}, {585, 650}}, + {7, {2925, 3250}, {1350, 1500}, {650, 722}}, + {8, {3510, 3900}, {1620, 1800}, {780, 867}}, + {9, {3900, 4333}, {1800, 2000}, {780, 867}} +}; +#endif /* WLAN_FEATURE_11AC */ + +/*array index points to MCS and array value points respective rssi*/ +static int rssiMcsTbl[][10] = +{ +/*MCS 0 1 2 3 4 5 6 7 8 9*/ + {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20 + {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40 + {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80 +}; + +extern struct net_device_ops net_ops_struct; +#ifdef FEATURE_WLAN_SCAN_PNO +static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter); +#endif + +#ifdef WLAN_NL80211_TESTMODE +enum wlan_hdd_tm_attr +{ + WLAN_HDD_TM_ATTR_INVALID = 0, + WLAN_HDD_TM_ATTR_CMD = 1, + WLAN_HDD_TM_ATTR_DATA = 2, + WLAN_HDD_TM_ATTR_TYPE = 3, + /* keep last */ + WLAN_HDD_TM_ATTR_AFTER_LAST, + WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1, +}; + +enum wlan_hdd_tm_cmd +{ + WLAN_HDD_TM_CMD_WLAN_HB = 1, +}; + +#define WLAN_HDD_TM_DATA_MAX_LEN 5000 + +static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] = +{ + [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 }, + [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY, + .len = WLAN_HDD_TM_DATA_MAX_LEN }, +}; +#endif /* WLAN_NL80211_TESTMODE */ + +#ifdef FEATURE_WLAN_CH_AVOID +/* + * FUNCTION: wlan_hdd_send_avoid_freq_event + * This is called when wlan driver needs to send vendor specific + * avoid frequency range event to userspace + */ +int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx, + tHddAvoidFreqList *pAvoidFreqList) +{ + struct sk_buff *vendor_event; + + ENTER(); + + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return -1; + } + + if (!pAvoidFreqList) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAvoidFreqList is null", __func__); + return -1; + } + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + sizeof(tHddAvoidFreqList), + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX, + GFP_KERNEL); + if (!vendor_event) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_event_alloc failed", __func__); + return -1; + } + + memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)), + (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList)); + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + + EXIT(); + return 0; +} +#endif /* FEATURE_WLAN_CH_AVOID */ + +/* + * FUNCTION: __wlan_hdd_cfg80211_nan_request + * This is called when wlan driver needs to send vendor specific + * nan request event. + */ +static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + tNanRequestReq nan_req; + VOS_STATUS status; + int ret_val = -1; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + + if (0 == data_len) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("NAN - Invalid Request, length = 0")); + return ret_val; + } + + if (NULL == data) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("NAN - Invalid Request, data is NULL")); + return ret_val; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + hddLog(LOG1, FL("Received NAN command")); + vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + (tANI_U8 *)data, data_len); + + /* check the NAN Capability */ + if (TRUE != sme_IsFeatureSupportedByFW(NAN)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("NAN is not supported by Firmware")); + return -EINVAL; + } + + nan_req.request_data_len = data_len; + nan_req.request_data = data; + + status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId); + if (VOS_STATUS_SUCCESS == status) + { + ret_val = 0; + } + return ret_val; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_nan_request + * Wrapper to protect the nan vendor command from ssr + */ +static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_nan_callback + * This is a callback function and it gets called + * when we need to report nan response event to + * upper layers. + */ +static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *vendor_event; + int status; + tSirNanEvent *data; + + ENTER(); + if (NULL == msg) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL(" msg received here is null")); + return; + } + data = msg; + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + data->event_data_len + + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN, + data->event_data_len, data->event_data)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR_NAN put fail")); + kfree_skb(vendor_event); + return; + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + EXIT(); +} + +/* + * FUNCTION: wlan_hdd_cfg80211_nan_init + * This function is called to register the callback to sme layer + */ +inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx) +{ + sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback); +} + +/* + * define short names for the global vendor params + * used by __wlan_hdd_cfg80211_get_station_cmd() + */ +#define STATION_INVALID \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID +#define STATION_INFO \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO +#define STATION_ASSOC_FAIL_REASON \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON +#define STATION_MAX \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + +static const struct nla_policy +hdd_get_station_policy[STATION_MAX + 1] = { + [STATION_INFO] = {.type = NLA_FLAG}, + [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG}, +}; + +/** + * hdd_get_station_assoc_fail() - Handle get station assoc fail + * @hdd_ctx: HDD context within host driver + * @wdev: wireless device + * + * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL. + * Validate cmd attributes and send the station info to upper layers. + * + * Return: Success(0) or reason code for failure + */ +static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter) +{ + struct sk_buff *skb = NULL; + uint32_t nl_buf_len; + hdd_station_ctx_t *hdd_sta_ctx; + + nl_buf_len = NLMSG_HDRLEN; + nl_buf_len += sizeof(uint32_t); + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); + + if (!skb) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed"); + return -ENOMEM; + } + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON, + hdd_sta_ctx->conn_info.assoc_status_code)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + return cfg80211_vendor_cmd_reply(skb); +fail: + if (skb) + kfree_skb(skb); + return -EINVAL; +} + +/** + * hdd_map_auth_type() - transform auth type specific to + * vendor command + * @auth_type: csr auth type + * + * Return: Success(0) or reason code for failure + */ +static int hdd_convert_auth_type(uint32_t auth_type) +{ + uint32_t ret_val; + + switch (auth_type) { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + ret_val = QCA_WLAN_AUTH_TYPE_OPEN; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + ret_val = QCA_WLAN_AUTH_TYPE_SHARED; + break; + case eCSR_AUTH_TYPE_WPA: + ret_val = QCA_WLAN_AUTH_TYPE_WPA; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH; + break; + case eCSR_AUTH_TYPE_WPA_NONE: + ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE; + break; + case eCSR_AUTH_TYPE_RSN: + ret_val = QCA_WLAN_AUTH_TYPE_RSN; + break; + case eCSR_AUTH_TYPE_RSN_PSK: + ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK; + break; + case eCSR_AUTH_TYPE_FT_RSN: + ret_val = QCA_WLAN_AUTH_TYPE_FT; + break; + case eCSR_AUTH_TYPE_FT_RSN_PSK: + ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK; + break; + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + ret_val = QCA_WLAN_AUTH_TYPE_WAI; + break; + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK; + break; +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: + ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA; + break; + case eCSR_AUTH_TYPE_CCKM_RSN: + ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN; + break; +#endif + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK; + break; + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: + ret_val = QCA_WLAN_AUTH_TYPE_SHA256; + break; + case eCSR_NUM_OF_SUPPORT_AUTH_TYPE: + case eCSR_AUTH_TYPE_FAILED: + case eCSR_AUTH_TYPE_NONE: + default: + ret_val = QCA_WLAN_AUTH_TYPE_INVALID; + break; + } + return ret_val; +} + +/** + * hdd_map_dot_11_mode() - transform dot11mode type specific to + * vendor command + * @dot11mode: dot11mode + * + * Return: Success(0) or reason code for failure + */ +static int hdd_convert_dot11mode(uint32_t dot11mode) +{ + uint32_t ret_val; + + switch (dot11mode) { + case eCSR_CFG_DOT11_MODE_11A: + ret_val = QCA_WLAN_802_11_MODE_11A; + break; + case eCSR_CFG_DOT11_MODE_11B: + ret_val = QCA_WLAN_802_11_MODE_11B; + break; + case eCSR_CFG_DOT11_MODE_11G: + ret_val = QCA_WLAN_802_11_MODE_11G; + break; + case eCSR_CFG_DOT11_MODE_11N: + ret_val = QCA_WLAN_802_11_MODE_11N; + break; + case eCSR_CFG_DOT11_MODE_11AC: + ret_val = QCA_WLAN_802_11_MODE_11AC; + break; + case eCSR_CFG_DOT11_MODE_AUTO: + case eCSR_CFG_DOT11_MODE_ABG: + default: + ret_val = QCA_WLAN_802_11_MODE_INVALID; + } + return ret_val; +} + +/** + * hdd_add_tx_bitrate() - add tx bitrate attribute + * @skb: pointer to sk buff + * @hdd_sta_ctx: pointer to hdd station context + * @idx: attribute index + * + * Return: Success(0) or reason code for failure + */ +static int32_t hdd_add_tx_bitrate(struct sk_buff *skb, + hdd_station_ctx_t *hdd_sta_ctx, + int idx) +{ + struct nlattr *nla_attr; + uint32_t bitrate, bitrate_compat; + + nla_attr = nla_nest_start(skb, idx); + if (!nla_attr) + goto fail; + /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ + bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate); + + /* report 16-bit bitrate only if we can */ + bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; + if (bitrate > 0 && + nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (bitrate_compat > 0 && + nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS, + hdd_sta_ctx->conn_info.txrate.nss)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + nla_nest_end(skb, nla_attr); + return 0; +fail: + return -EINVAL; +} + +/** + * hdd_add_sta_info() - add station info attribute + * @skb: pointer to sk buff + * @hdd_sta_ctx: pointer to hdd station context + * @idx: attribute index + * + * Return: Success(0) or reason code for failure + */ +static int32_t hdd_add_sta_info(struct sk_buff *skb, + hdd_station_ctx_t *hdd_sta_ctx, int idx) +{ + struct nlattr *nla_attr; + + nla_attr = nla_nest_start(skb, idx); + if (!nla_attr) + goto fail; + if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, + (hdd_sta_ctx->conn_info.signal + 100))) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE)) + goto fail; + nla_nest_end(skb, nla_attr); + return 0; +fail: + return -EINVAL; +} + +/** + * hdd_add_survey_info() - add survey info attribute + * @skb: pointer to sk buff + * @hdd_sta_ctx: pointer to hdd station context + * @idx: attribute index + * + * Return: Success(0) or reason code for failure + */ +static int32_t hdd_add_survey_info(struct sk_buff *skb, + hdd_station_ctx_t *hdd_sta_ctx, + int idx) +{ + struct nlattr *nla_attr; + + nla_attr = nla_nest_start(skb, idx); + if (!nla_attr) + goto fail; + if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY, + hdd_sta_ctx->conn_info.freq) || + nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE, + (hdd_sta_ctx->conn_info.noise + 100))) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + nla_nest_end(skb, nla_attr); + return 0; +fail: + return -EINVAL; +} + +/** + * hdd_add_link_standard_info() - add link info attribute + * @skb: pointer to sk buff + * @hdd_sta_ctx: pointer to hdd station context + * @idx: attribute index + * + * Return: Success(0) or reason code for failure + */ +static int32_t +hdd_add_link_standard_info(struct sk_buff *skb, + hdd_station_ctx_t *hdd_sta_ctx, int idx) +{ + struct nlattr *nla_attr; + + nla_attr = nla_nest_start(skb, idx); + if (!nla_attr) + goto fail; + if (nla_put(skb, + NL80211_ATTR_SSID, + hdd_sta_ctx->conn_info.SSID.SSID.length, + hdd_sta_ctx->conn_info.SSID.SSID.ssId)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO)) + goto fail; + if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO)) + goto fail; + nla_nest_end(skb, nla_attr); + return 0; +fail: + return -EINVAL; +} + +/** + * hdd_add_ap_standard_info() - add ap info attribute + * @skb: pointer to sk buff + * @hdd_sta_ctx: pointer to hdd station context + * @idx: attribute index + * + * Return: Success(0) or reason code for failure + */ +static int32_t +hdd_add_ap_standard_info(struct sk_buff *skb, + hdd_station_ctx_t *hdd_sta_ctx, int idx) +{ + struct nlattr *nla_attr; + + nla_attr = nla_nest_start(skb, idx); + if (!nla_attr) + goto fail; + if (hdd_sta_ctx->conn_info.conn_flag.vht_present) + if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY, + sizeof(hdd_sta_ctx->conn_info.vht_caps), + &hdd_sta_ctx->conn_info.vht_caps)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_sta_ctx->conn_info.conn_flag.ht_present) + if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY, + sizeof(hdd_sta_ctx->conn_info.ht_caps), + &hdd_sta_ctx->conn_info.ht_caps)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + nla_nest_end(skb, nla_attr); + return 0; +fail: + return -EINVAL; +} + +/** + * hdd_get_station_info() - send BSS information to supplicant + * @hdd_ctx: pointer to hdd context + * @adapter: pointer to adapter + * + * Return: 0 if success else error status + */ +static int hdd_get_station_info(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter) +{ + struct sk_buff *skb = NULL; + uint8_t *tmp_hs20 = NULL; + uint32_t nl_buf_len; + hdd_station_ctx_t *hdd_sta_ctx; + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + nl_buf_len = NLMSG_HDRLEN; + nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) + + sizeof(hdd_sta_ctx->conn_info.freq) + + sizeof(hdd_sta_ctx->conn_info.noise) + + sizeof(hdd_sta_ctx->conn_info.signal) + + (sizeof(uint32_t) * 2) + + sizeof(hdd_sta_ctx->conn_info.txrate.nss) + + sizeof(hdd_sta_ctx->conn_info.roam_count) + + sizeof(hdd_sta_ctx->conn_info.authType) + + sizeof(hdd_sta_ctx->conn_info.dot11Mode); + if (hdd_sta_ctx->conn_info.conn_flag.vht_present) + nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps); + if (hdd_sta_ctx->conn_info.conn_flag.ht_present) + nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps); + if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) { + tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie); + nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - + 1); + } + if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present) + nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation); + if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present) + nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation); + + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); + if (!skb) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed", + __func__, __LINE__); + return -ENOMEM; + } + + if (hdd_add_link_standard_info(skb, hdd_sta_ctx, + LINK_INFO_STANDARD_NL80211_ATTR)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_add_ap_standard_info(skb, hdd_sta_ctx, + AP_INFO_STANDARD_NL80211_ATTR)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (nla_put_u32(skb, INFO_ROAM_COUNT, + hdd_sta_ctx->conn_info.roam_count) || + nla_put_u32(skb, INFO_AKM, + hdd_convert_auth_type( + hdd_sta_ctx->conn_info.authType)) || + nla_put_u32(skb, WLAN802_11_MODE, + hdd_convert_dot11mode( + hdd_sta_ctx->conn_info.dot11Mode))) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present) + if (nla_put(skb, HT_OPERATION, + (sizeof(hdd_sta_ctx->conn_info.ht_operation)), + &hdd_sta_ctx->conn_info.ht_operation)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present) + if (nla_put(skb, VHT_OPERATION, + (sizeof(hdd_sta_ctx->conn_info.vht_operation)), + &hdd_sta_ctx->conn_info.vht_operation)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) + if (nla_put(skb, AP_INFO_HS20_INDICATION, + (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1), + tmp_hs20 + 1)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail"); + goto fail; + } + + return cfg80211_vendor_cmd_reply(skb); +fail: + if (skb) + kfree_skb(skb); + return -EINVAL; +} + +/** + * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd + * @wiphy: corestack handler + * @wdev: wireless device + * @data: data + * @data_len: data length + * + * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION. + * Validate cmd attributes and send the station info to upper layers. + * + * Return: Success(0) or reason code for failure + */ +static int32_t +__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1]; + int32_t status; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter"); + if (VOS_FTM_MODE == hdd_get_conparam()) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode"); + status = -EPERM; + goto out; + } + + status = wlan_hdd_validate_context(hdd_ctx); + if (0 != status) + goto out; + + + status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX, + data, data_len, NULL); + if (status) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR"); + goto out; + } + + /* Parse and fetch Command Type*/ + if (tb[STATION_INFO]) { + status = hdd_get_station_info(hdd_ctx, adapter); + } else if (tb[STATION_ASSOC_FAIL_REASON]) { + status = hdd_get_station_assoc_fail(hdd_ctx, adapter); + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed"); + status = -EINVAL; + goto out; + } + EXIT(); +out: + return status; +} + +/** + * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd + * @wiphy: corestack handler + * @wdev: wireless device + * @data: data + * @data_len: data length + * + * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION. + * Validate cmd attributes and send the station info to upper layers. + * + * Return: Success(0) or reason code for failure + */ +static int32_t +hdd_cfg80211_get_station_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * undef short names defined for get station command + * used by __wlan_hdd_cfg80211_get_station_cmd() + */ +#undef STATION_INVALID +#undef STATION_INFO +#undef STATION_ASSOC_FAIL_REASON +#undef STATION_MAX + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE, + stats->rate.preamble) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS, + stats->rate.nss) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW, + stats->rate.bw) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX, + stats->rate.rateMcsIdx) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE, + stats->rate.bitrate ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU, + stats->txMpdu ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU, + stats->rxMpdu ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST, + stats->mpduLost ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES, + stats->retries) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT, + stats->retriesShort ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG, + stats->retriesLong)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + return TRUE; +} + +static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats, + struct sk_buff *vendor_event) +{ + u32 i = 0; + struct nlattr *rateInfo; + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE, + stats->type) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS, + VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES, + stats->capabilities) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES, + stats->numRate)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + goto error; + } + + rateInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO); + if(!rateInfo) + return FALSE; + for (i = 0; i < stats->numRate; i++) + { + struct nlattr *rates; + tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *) + stats->rateStats + + (i * sizeof(tSirWifiRateStat))); + rates = nla_nest_start(vendor_event, i); + if(!rates) + return FALSE; + + if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + nla_nest_end(vendor_event, rates); + } + nla_nest_end(vendor_event, rateInfo); + + return TRUE; +error: + return FALSE; +} + +static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC, + stats->ac ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU, + stats->txMpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU, + stats->rxMpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST, + stats->txMcast ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST, + stats->rxMcast ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU, + stats->rxAmpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU, + stats->txAmpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST, + stats->mpduLost )|| + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES, + stats->retries ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT, + stats->retriesShort ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG, + stats->retriesLong ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN, + stats->contentionTimeMin ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX, + stats->contentionTimeMax ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG, + stats->contentionTimeAvg ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES, + stats->contentionNumSamples )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + } + return TRUE; +} + +static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats, + struct sk_buff *vendor_event) +{ + if (nla_put_s32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR, + VOS_MAC_ADDR_SIZE, stats->macAddr) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE, + stats->state ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING, + stats->roaming ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES, + stats->capabilities ) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID, + strlen(stats->ssid), stats->ssid) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID, + WNI_CFG_BSSID_LEN, stats->bssid) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR, + WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, + WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr) + ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + } + return TRUE; +} + +static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter, + tpSirWifiIfaceStat pWifiIfaceStat, + struct sk_buff *vendor_event) +{ + int i = 0; + struct nlattr *wmmInfo; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL; + tSirWifiWmmAcStat accessclassStats; + + if (FALSE == put_wifi_interface_info( + &pWifiIfaceStat->info, + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + + } + pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *) + vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType)); + if (NULL == pWifiIfaceStatTL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return FALSE; + } + + accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK]; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] = + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE]; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats; + + accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac = + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac; + + if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED) + { + if (VOS_STATUS_SUCCESS == + WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL)) + { + /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are + * obtained from TL structure + */ + + pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx + + pWifiIfaceStatTL->mgmtRx; + pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData; + + pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast; + pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast; + + pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu; + pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu; + + pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu; + pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu + = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu; + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL")); + } + + pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast = + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO]; + pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast = + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI]; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast = + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE]; + pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast = + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK]; + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated")); + } + + + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX, + pWifiIfaceStat->beaconRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX, + pWifiIfaceStat->mgmtRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX, + pWifiIfaceStat->mgmtActionRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX, + pWifiIfaceStat->mgmtActionTx) || + nla_put_s32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT, + pWifiIfaceStat->rssiMgmt) || + nla_put_s32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA, + pWifiIfaceStat->rssiData) || + nla_put_s32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK, + pWifiIfaceStat->rssiAck)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + vos_mem_free(pWifiIfaceStatTL); + return FALSE; + } + +#ifdef FEATURE_EXT_LL_STAT + /* + * Ensure when EXT_LL_STAT is supported by both host and fwr, + * then host should send Leaky AP stats to upper layer, + * otherwise no need to send these stats. + */ + if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) && + sme_IsFeatureSupportedByDriver(EXT_LL_STAT) + ) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"), + pWifiIfaceStat->leakyApStat.is_leaky_ap, + pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked, + pWifiIfaceStat->leakyApStat.rx_leak_window, + pWifiIfaceStat->leakyApStat.avg_bcn_spread); + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED, + pWifiIfaceStat->leakyApStat.is_leaky_ap) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED, + pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME, + pWifiIfaceStat->leakyApStat.rx_leak_window) || + nla_put_u64(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET, + pWifiIfaceStat->leakyApStat.avg_bcn_spread)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXT_LL_STAT put fail")); + vos_mem_free(pWifiIfaceStatTL); + return FALSE; + } + } +#endif + wmmInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO); + if(!wmmInfo) + { + vos_mem_free(pWifiIfaceStatTL); + return FALSE; + } + for (i = 0; i < WIFI_AC_MAX; i++) + { + struct nlattr *wmmStats; + wmmStats = nla_nest_start(vendor_event, i); + if(!wmmStats) + { + vos_mem_free(pWifiIfaceStatTL); + return FALSE; + } + if (FALSE == put_wifi_wmm_ac_stat( + &pWifiIfaceStat->AccessclassStats[i], + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put Fail")); + vos_mem_free(pWifiIfaceStatTL); + return FALSE; + } + + nla_nest_end(vendor_event, wmmStats); + } + nla_nest_end(vendor_event, wmmInfo); + vos_mem_free(pWifiIfaceStatTL); + return TRUE; +} + +static tSirWifiInterfaceMode + hdd_map_device_to_ll_iface_mode ( int deviceMode ) +{ + switch (deviceMode) + { + case WLAN_HDD_INFRA_STATION: + return WIFI_INTERFACE_STA; + case WLAN_HDD_SOFTAP: + return WIFI_INTERFACE_SOFTAP; + case WLAN_HDD_P2P_CLIENT: + return WIFI_INTERFACE_P2P_CLIENT; + case WLAN_HDD_P2P_GO: + return WIFI_INTERFACE_P2P_GO; + case WLAN_HDD_IBSS: + return WIFI_INTERFACE_IBSS; + default: + return WIFI_INTERFACE_UNKNOWN; + } +} + +static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter, + tpSirWifiInterfaceInfo pInfo) +{ + v_U8_t *staMac = NULL; + hdd_station_ctx_t *pHddStaCtx; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode); + + vos_mem_copy(pInfo->macAddr, + pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) + { + pInfo->state = WIFI_DISCONNECTED; + } + if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Session ID %d, Connection is in progress", __func__, + pAdapter->sessionId); + pInfo->state = WIFI_ASSOCIATING; + } + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]); + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: client " MAC_ADDRESS_STR + " is in the middle of WPS/EAPOL exchange.", __func__, + MAC_ADDR_ARRAY(staMac)); + pInfo->state = WIFI_AUTHENTICATING; + } + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + pInfo->state = WIFI_ASSOCIATED; + vos_mem_copy(pInfo->bssid, + &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN); + vos_mem_copy(pInfo->ssid, + pHddStaCtx->conn_info.SSID.SSID.ssId, + pHddStaCtx->conn_info.SSID.SSID.length); + //NULL Terminate the string. + pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0; + } + } + vos_mem_copy(pInfo->countryStr, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + + vos_mem_copy(pInfo->apCountryStr, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + + return TRUE; +} + +/* + * hdd_link_layer_process_peer_stats () - This function is called after + * receiving Link Layer Peer statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter, + v_VOID_t *pData) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tpSirWifiPeerStat pWifiPeerStat; + tpSirWifiPeerInfo pWifiPeerInfo; + struct nlattr *peerInfo; + struct sk_buff *vendor_event; + int status, i; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return; + } + + pWifiPeerStat = (tpSirWifiPeerStat) pData; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_PEER_ALL : numPeers %u", + pWifiPeerStat->numPeers); + /* + * Allocate a size of 4096 for the peer stats comprising + * each of size = sizeof (tSirWifiPeerInfo) + numRate * + * sizeof (tSirWifiRateStat).Each field is put with an + * NL attribute.The size of 4096 is considered assuming + * that number of rates shall not exceed beyond 50 with + * the sizeof (tSirWifiRateStat) being 32. + */ + vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE); + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_cmd_alloc_reply_skb failed", + __func__); + return; + } + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + pWifiPeerStat->numPeers)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__); + kfree_skb(vendor_event); + return; + } + + peerInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO); + if(!peerInfo) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail", + __func__); + kfree_skb(vendor_event); + return; + } + + pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *) + pWifiPeerStat->peerInfo); + + for (i = 1; i <= pWifiPeerStat->numPeers; i++) + { + int numRate = pWifiPeerInfo->numRate; + struct nlattr *peers = nla_nest_start(vendor_event, i); + + if(!peers) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: peer stats put fail", + __func__); + kfree_skb(vendor_event); + return; + } + if (FALSE == put_wifi_peer_info( + pWifiPeerInfo, vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: put_wifi_peer_info put fail", __func__); + kfree_skb(vendor_event); + return; + } + + pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *) + pWifiPeerStat->peerInfo + + (i * sizeof(tSirWifiPeerInfo)) + + (numRate * sizeof (tSirWifiRateStat))); + nla_nest_end(vendor_event, peers); + } + nla_nest_end(vendor_event, peerInfo); + cfg80211_vendor_cmd_reply(vendor_event); + EXIT(); +} + +/* + * hdd_link_layer_process_iface_stats () - This function is called after + * receiving Link Layer Interface statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter, + v_VOID_t *pData) +{ + tpSirWifiIfaceStat pWifiIfaceStat; + struct sk_buff *vendor_event; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return; + } + /* + * Allocate a size of 4096 for the interface stats comprising + * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered + * assuming that all these fit with in the limit.Please take + * a call on the limit based on the data requirements on + * interface statistics. + */ + vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE); + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_cmd_alloc_reply_skb failed") ); + return; + } + + pWifiIfaceStat = (tpSirWifiIfaceStat) pData; + + + if (FALSE == hdd_get_interface_info( pAdapter, + &pWifiIfaceStat->info)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("hdd_get_interface_info get fail") ); + kfree_skb(vendor_event); + return; + } + + if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat, + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("put_wifi_iface_stats fail") ); + kfree_skb(vendor_event); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "WMI_LINK_STATS_IFACE Data"); + + cfg80211_vendor_cmd_reply(vendor_event); + + EXIT(); +} + +/* + * hdd_link_layer_process_radio_stats () - This function is called after + * receiving Link Layer Radio statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter, + v_VOID_t *pData) +{ + int status, i; + tpSirWifiRadioStat pWifiRadioStat; + tpSirWifiChannelStats pWifiChannelStats; + struct sk_buff *vendor_event; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + struct nlattr *chList; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return; + } + pWifiRadioStat = (tpSirWifiRadioStat) pData; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_RADIO" + " number of radios = %u" + " radio is %d onTime is %u " + " txTime is %u rxTime is %u " + " onTimeScan is %u onTimeNbd is %u " + " onTimeEXTScan is %u onTimeRoamScan is %u " + " onTimePnoScan is %u onTimeHs20 is %u " + " numChannels is %u", + NUM_RADIOS, + pWifiRadioStat->radio, pWifiRadioStat->onTime, + pWifiRadioStat->txTime, pWifiRadioStat->rxTime, + pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd, + pWifiRadioStat->onTimeEXTScan, + pWifiRadioStat->onTimeRoamScan, + pWifiRadioStat->onTimePnoScan, + pWifiRadioStat->onTimeHs20, + pWifiRadioStat->numChannels); + /* + * Allocate a size of 4096 for the Radio stats comprising + * sizeof (tSirWifiRadioStat) + numChannels * sizeof + * (tSirWifiChannelStats).Each channel data is put with an + * NL attribute.The size of 4096 is considered assuming that + * number of channels shall not exceed beyond 60 with the + * sizeof (tSirWifiChannelStats) being 24 bytes. + */ + + vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE); + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_cmd_alloc_reply_skb failed") ); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID, + pWifiRadioStat->radio) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS, + NUM_RADIOS) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME, + pWifiRadioStat->onTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME, + pWifiRadioStat->txTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME, + pWifiRadioStat->rxTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN, + pWifiRadioStat->onTimeScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD, + pWifiRadioStat->onTimeNbd) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN, + pWifiRadioStat->onTimeEXTScan)|| + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN, + pWifiRadioStat->onTimeRoamScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN, + pWifiRadioStat->onTimePnoScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20, + pWifiRadioStat->onTimeHs20) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS, + pWifiRadioStat->numChannels)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + kfree_skb(vendor_event); + return ; + } + + chList = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO); + if(!chList) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail", + __func__); + kfree_skb(vendor_event); + return; + } + for (i = 0; i < pWifiRadioStat->numChannels; i++) + { + struct nlattr *chInfo; + + pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*) + pWifiRadioStat->channels + + (i * sizeof(tSirWifiChannelStats))); + + chInfo = nla_nest_start(vendor_event, i); + if(!chInfo) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to put chInfo", + __func__); + kfree_skb(vendor_event); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH, + pWifiChannelStats->channel.width) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ, + pWifiChannelStats->channel.centerFreq) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0, + pWifiChannelStats->channel.centerFreq0) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1, + pWifiChannelStats->channel.centerFreq1) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME, + pWifiChannelStats->onTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME, + pWifiChannelStats->ccaBusyTime)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed") ); + kfree_skb(vendor_event); + return ; + } + nla_nest_end(vendor_event, chInfo); + } + nla_nest_end(vendor_event, chList); + + cfg80211_vendor_cmd_reply(vendor_event); + + EXIT(); + return; +} + +/* + * hdd_link_layer_stats_ind_callback () - This function is called after + * receiving Link Layer indications from FW.This callback converts the firmware + * data to the NL data and send the same to the kernel/upper layers. + */ +static void hdd_link_layer_stats_ind_callback ( void *pCtx, + int indType, + void *pRsp, u8 *macAddr) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)pCtx; + hdd_adapter_t *pAdapter = NULL; + struct hdd_ll_stats_context *context; + tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp; + int status; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return; + } + + pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL(" MAC address %pM does not exist with host"), + macAddr); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Interface: %s LLStats indType: %d", __func__, + pAdapter->dev->name, indType); + + switch (indType) + { + case SIR_HAL_LL_STATS_RESULTS_RSP: + { + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM " + "respId = %u, moreResultToFollow = %u", + linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId, + macAddr, linkLayerStatsResults->respId, + linkLayerStatsResults->moreResultToFollow); + + spin_lock(&hdd_context_lock); + context = &pHddCtx->ll_stats_context; + /* validate response received from target */ + if ((context->request_id != linkLayerStatsResults->respId) || + !(context->request_bitmap & linkLayerStatsResults->paramId)) + { + spin_unlock(&hdd_context_lock); + hddLog(LOGE, + FL("Error : Request id %d response id %d request bitmap 0x%x" + "response bitmap 0x%x"), + context->request_id, linkLayerStatsResults->respId, + context->request_bitmap, linkLayerStatsResults->paramId); + return; + } + spin_unlock(&hdd_context_lock); + + if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO ) + { + hdd_link_layer_process_radio_stats(pAdapter, + (v_VOID_t *)linkLayerStatsResults->result); + spin_lock(&hdd_context_lock); + context->request_bitmap &= ~(WMI_LINK_STATS_RADIO); + spin_unlock(&hdd_context_lock); + } + else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE ) + { + hdd_link_layer_process_iface_stats(pAdapter, + (v_VOID_t *)linkLayerStatsResults->result); + spin_lock(&hdd_context_lock); + context->request_bitmap &= ~(WMI_LINK_STATS_IFACE); + spin_unlock(&hdd_context_lock); + } + else if ( linkLayerStatsResults->paramId & + WMI_LINK_STATS_ALL_PEER ) + { + hdd_link_layer_process_peer_stats(pAdapter, + (v_VOID_t *)linkLayerStatsResults->result); + spin_lock(&hdd_context_lock); + context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER); + spin_unlock(&hdd_context_lock); + } /* WMI_LINK_STATS_ALL_PEER */ + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("INVALID LL_STATS_NOTIFY RESPONSE ***********")); + } + + spin_lock(&hdd_context_lock); + /* complete response event if all requests are completed */ + if (0 == context->request_bitmap) + complete(&context->response_event); + spin_unlock(&hdd_context_lock); + + break; + } + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType); + break; + } + + EXIT(); + return; +} + +const struct +nla_policy +qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] = + { .type = NLA_U32 }, +}; + +static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int status; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1]; + tSirLLStatsSetReq linkLayerStatsSetReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD adapter is Null")); + return -ENODEV; + } + /* check the LLStats Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) || + (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) + { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("Link Layer Statistics not supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_set_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL() ); + return -EINVAL; + } + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present")); + return -EINVAL; + } + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present")); + return -EINVAL; + } + // Shall take the request Id if the Upper layers pass. 1 For now. + linkLayerStatsSetReq.reqId = 1; + + linkLayerStatsSetReq.mpduSizeThreshold = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]); + + linkLayerStatsSetReq.aggressiveStatisticsGathering = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]); + + vos_mem_copy(linkLayerStatsSetReq.macAddr, + pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d " + "Statistics Gathering = %d ", + linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr, + linkLayerStatsSetReq.mpduSizeThreshold, + linkLayerStatsSetReq.aggressiveStatisticsGathering); + + if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB( + pHddCtx->hHal, + hdd_link_layer_stats_ind_callback)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_SetLinkLayerStatsIndCB Failed", __func__); + return -EINVAL; + + } + + if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal, + &linkLayerStatsSetReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_LLStatsSetReq Failed", __func__); + return -EINVAL; + } + + pAdapter->isLinkLayerStatsSet = 1; + + EXIT(); + return 0; +} +static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +const struct +nla_policy +qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] = +{ + /* Unsigned 32bit value provided by the caller issuing the GET stats + * command. When reporting + * the stats results, the driver uses the same value to indicate + * which GET request the results + * correspond to. + */ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 }, + + /* Unsigned 32bit value . bit mask to identify what statistics are + requested for retrieval */ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 }, +}; + +static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + unsigned long rc; + struct hdd_ll_stats_context *context; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1]; + tSirLLStatsGetReq linkLayerStatsGetReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + int status; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL ; + } + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + if (pHddStaCtx == NULL) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: HddStaCtx is Null", __func__); + return -ENODEV; + } + + /* check the LLStats Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) || + (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Link Layer Statistics not supported by Firmware")); + return -EINVAL; + } + + + if (!pAdapter->isLinkLayerStatsSet) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: isLinkLayerStatsSet : %d", + __func__, pAdapter->isLinkLayerStatsSet); + return -EINVAL; + } + + if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Roaming in progress, so unable to proceed this request", __func__); + return -EBUSY; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_get_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL() ); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present")); + return -EINVAL; + } + + + linkLayerStatsGetReq.reqId = + nla_get_u32( tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]); + linkLayerStatsGetReq.paramIdMask = + nla_get_u32( tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]); + + vos_mem_copy(linkLayerStatsGetReq.macAddr, + pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d", + linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr, + linkLayerStatsGetReq.paramIdMask); + + spin_lock(&hdd_context_lock); + context = &pHddCtx->ll_stats_context; + context->request_id = linkLayerStatsGetReq.reqId; + context->request_bitmap = linkLayerStatsGetReq.paramIdMask; + INIT_COMPLETION(context->response_event); + spin_unlock(&hdd_context_lock); + + if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal, + &linkLayerStatsGetReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_LLStatsGetReq Failed", __func__); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS)); + if (!rc) + { + hddLog(LOGE, + FL("Target response timed out request id %d request bitmap 0x%x"), + context->request_id, context->request_bitmap); + return -ETIMEDOUT; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +const struct +nla_policy +qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 }, +}; + +static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1]; + tSirLLStatsClearReq linkLayerStatsClearReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + u32 statsClearReqMask; + u8 stopReq; + int status; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + /* check the LLStats Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) || + (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Enable LLStats Capability")); + return -EINVAL; + } + + if (!pAdapter->isLinkLayerStatsSet) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: isLinkLayerStatsSet : %d", + __func__, pAdapter->isLinkLayerStatsSet); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_clr_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL() ); + return -EINVAL; + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] || + + !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") ); + return -EINVAL; + + } + + + statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]); + + stopReq = linkLayerStatsClearReq.stopReq = + nla_get_u8( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]); + + // Shall take the request Id if the Upper layers pass. 1 For now. + linkLayerStatsClearReq.reqId = 1; + + vos_mem_copy(linkLayerStatsClearReq.macAddr, + pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR reqId = %d, MAC = %pM," + "statsClearReqMask = 0x%X, stopReq = %d", + linkLayerStatsClearReq.reqId, + linkLayerStatsClearReq.macAddr, + linkLayerStatsClearReq.statsClearReqMask, + linkLayerStatsClearReq.stopReq); + + if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal, + &linkLayerStatsClearReq)) + { + struct sk_buff *temp_skbuff; + hdd_station_ctx_t *pHddStaCtx; + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (VOS_STATUS_SUCCESS != + WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pHddStaCtx->conn_info.staId[0], statsClearReqMask)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "WLANTL_ClearInterfaceStats Failed", __func__); + return -EINVAL; + } + if ((statsClearReqMask & WIFI_STATS_IFACE_AC) || + (statsClearReqMask & WIFI_STATS_IFACE)) { + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0; + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0; + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0; + pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0; + } + + temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + 2 * sizeof(u32) + + NLMSG_HDRLEN); + + if (temp_skbuff != NULL) + { + + if (nla_put_u32(temp_skbuff, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK, + statsClearReqMask) || + nla_put_u32(temp_skbuff, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP, + stopReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail")); + kfree_skb(temp_skbuff); + return -EINVAL; + } + /* If the ask is to stop the stats collection as part of clear + * (stopReq = 1) , ensure that no further requests of get + * go to the firmware by having isLinkLayerStatsSet set to 0. + * However it the stopReq as part of the clear request is 0 , + * the request to get the statistics are honoured as in this + * case the firmware is just asked to clear the statistics. + */ + if (linkLayerStatsClearReq.stopReq == 1) + pAdapter->isLinkLayerStatsSet = 0; + return cfg80211_vendor_cmd_reply(temp_skbuff); + } + return -ENOMEM; + } + + EXIT(); + return -EINVAL; +} +static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; + + +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_EXTSCAN +static const struct nla_policy +wlan_hdd_extscan_config_policy + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] = +{ + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 }, + + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] = + { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] = + { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] = + { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] = + { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] = + { .type = NLA_U8 }, + + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = { + .type = NLA_UNSPEC, + .len = HDD_MAC_ADDR_LEN}, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] = + { .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] = + { .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] = + { .type = NLA_BINARY, + .len = IEEE80211_MAX_SSID_LEN + 1 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] = + { .type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] = + { .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] = + { .type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] = + { .type = NLA_U32 }, +}; + +/** + * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target + * @ctx: hdd global context + * @data: capabilities data + * + * Return: none + */ +static void +wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg) +{ + struct hdd_ext_scan_context *context; + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + tSirEXTScanCapabilitiesEvent *data = + (tSirEXTScanCapabilitiesEvent *) pMsg; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) + { + return; + } + + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + vos_spin_lock_acquire(&hdd_context_lock); + + context = &pHddCtx->ext_scan_context; + /* validate response received from target*/ + if (context->request_id != data->requestId) + { + vos_spin_lock_release(&hdd_context_lock); + hddLog(LOGE, + FL("Target response id did not match: request_id %d resposne_id %d"), + context->request_id, data->requestId); + return; + } + else + { + context->capability_response = *data; + complete(&context->response_event); + } + + vos_spin_lock_release(&hdd_context_lock); + + return; +} + +/* + * define short names for the global vendor params + * used by wlan_hdd_send_ext_scan_capability() + */ +#define PARAM_REQUEST_ID \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID +#define PARAM_STATUS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS +#define MAX_SCAN_CACHE_SIZE \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE +#define MAX_SCAN_BUCKETS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS +#define MAX_AP_CACHE_PER_SCAN \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN +#define MAX_RSSI_SAMPLE_SIZE \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE +#define MAX_SCAN_RPT_THRHOLD \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD +#define MAX_HOTLIST_BSSIDS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS +#define MAX_BSSID_HISTORY_ENTRIES \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES +#define MAX_HOTLIST_SSIDS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS +#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS + +static int wlan_hdd_send_ext_scan_capability(void *ctx) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + int ret; + tSirEXTScanCapabilitiesEvent *data; + tANI_U32 nl_buf_len; + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + data = &(pHddCtx->ext_scan_context.capability_response); + + nl_buf_len = NLMSG_HDRLEN; + nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) + + (sizeof(data->status) + NLA_HDRLEN) + + (sizeof(data->scanCacheSize) + NLA_HDRLEN) + + (sizeof(data->scanBuckets) + NLA_HDRLEN) + + (sizeof(data->maxApPerScan) + NLA_HDRLEN) + + (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) + + (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) + + (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) + + (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) + + (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len); + + if (!skb) + { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -ENOMEM; + } + + hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status); + hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)", + data->scanCacheSize, data->scanBuckets, data->maxApPerScan); + hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)", + data->maxRssiSampleSize, data->maxScanReportingThreshold); + hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)" + "max_hotlist_ssids (%u)", data->maxHotlistAPs, + data->maxBsidHistoryEntries, data->maxHotlistSSIDs); + + if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) || + nla_put_u32(skb, PARAM_STATUS, data->status) || + nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) || + nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) || + nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN, + data->maxApPerScan) || + nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE, + data->maxRssiSampleSize) || + nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD, + data->maxScanReportingThreshold) || + nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) || + nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES, + data->maxBsidHistoryEntries) || + nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) || + nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0)) + { + hddLog(LOGE, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_cmd_reply(skb); + return 0; + +nla_put_failure: + kfree_skb(skb); + return -EINVAL;; +} + +/* + * done with short names for the global vendor params + * used by wlan_hdd_send_ext_scan_capability() + */ +#undef PARAM_REQUEST_ID +#undef PARAM_STATUS +#undef MAX_SCAN_CACHE_SIZE +#undef MAX_SCAN_BUCKETS +#undef MAX_AP_CACHE_PER_SCAN +#undef MAX_RSSI_SAMPLE_SIZE +#undef MAX_SCAN_RPT_THRHOLD +#undef MAX_HOTLIST_BSSIDS +#undef MAX_BSSID_HISTORY_ENTRIES +#undef MAX_HOTLIST_SSIDS + +static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg) +{ + tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg; + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal ); + struct hdd_ext_scan_context *context; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) + return; + + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status); + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + if (context->request_id == pData->requestId) { + context->response_status = pData->status ? -EINVAL : 0; + complete(&context->response_event); + } + spin_unlock(&hdd_context_lock); + + /* + * Store the Request ID for comparing with the requestID obtained + * in other requests.HDD shall return a failure is the extscan_stop + * request is issued with a different requestId as that of the + * extscan_start request. Also, This requestId shall be used while + * indicating the full scan results to the upper layers. + * The requestId is stored with the assumption that the firmware + * shall return the ext scan start request's requestId in ext scan + * start response. + */ + if (pData->status == 0) + pMac->sme.extScanStartReqId = pData->requestId; + + EXIT(); + return; +} + + +static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg) +{ + tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg; + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct hdd_ext_scan_context *context; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)){ + return; + } + + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId, + pData->status); + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + if (context->request_id == pData->requestId) { + context->response_status = pData->status ? -EINVAL : 0; + complete(&context->response_event); + } + spin_unlock(&hdd_context_lock); + + EXIT(); + return; +} + +static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx, + void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + tpSirEXTScanSetBssidHotListRspParams pData = + (tpSirEXTScanSetBssidHotListRspParams) pMsg; + struct hdd_ext_scan_context *context; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)){ + return; + } + + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId, + pData->status); + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + if (context->request_id == pData->requestId) { + context->response_status = pData->status ? -EINVAL : 0; + complete(&context->response_event); + } + spin_unlock(&hdd_context_lock); + + EXIT(); + return; +} + +static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx, + void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + tpSirEXTScanResetBssidHotlistRspParams pData = + (tpSirEXTScanResetBssidHotlistRspParams) pMsg; + struct hdd_ext_scan_context *context; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) { + return; + } + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId, + pData->status); + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + if (context->request_id == pData->requestId) { + context->response_status = pData->status ? -EINVAL : 0; + complete(&context->response_event); + } + spin_unlock(&hdd_context_lock); + + EXIT(); + return; +} + +static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx, + void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tANI_U32 i = 0, j, resultsPerEvent, scan_id_index; + tANI_S32 totalResults; + tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg; + tpSirWifiScanResult pSirWifiScanResult, head_ptr; + struct hdd_ext_scan_context *context; + bool ignore_cached_results = false; + tExtscanCachedScanResult *result; + struct nlattr *nla_results; + tANI_U16 ieLength= 0; + tANI_U8 *ie = NULL; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) + return; + + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + spin_lock(&hdd_context_lock); + context = &pHddCtx->ext_scan_context; + ignore_cached_results = context->ignore_cached_results; + spin_unlock(&hdd_context_lock); + + if (ignore_cached_results) { + hddLog(LOGE, + FL("Ignore the cached results received after timeout")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u", + pData->requestId, pData->moreData, pData->scanResultSize); + + result = (tExtscanCachedScanResult *)&(pData->result); + + for (scan_id_index = 0; scan_id_index < pData->scanResultSize; + scan_id_index++) { + result+= scan_id_index; + + totalResults = result->num_results; + hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u", + result->scan_id, result->flags, totalResults); + i = 0; + + do{ + resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ? + EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults); + totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND; + + skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + resultsPerEvent)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 ))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID, + result->scan_id)) { + hddLog(LOGE, FL("put fail")); + goto fail; + } + + nla_results = nla_nest_start(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST); + if (!nla_results) + goto fail; + + if (resultsPerEvent) { + struct nlattr *aps; + struct nlattr *nla_result; + + nla_result = nla_nest_start(skb, scan_id_index); + if(!nla_result) + goto fail; + + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID, + result->scan_id) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS, + result->flags) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + totalResults)) { + hddLog(LOGE, FL("put fail")); + goto fail; + } + + aps = nla_nest_start(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST); + if (!aps) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + head_ptr = (tpSirWifiScanResult) &(result->ap); + + for (j = 0; j < resultsPerEvent; j++, i++) { + struct nlattr *ap; + pSirWifiScanResult = head_ptr + i; + + /* + * Firmware returns timestamp from extscan_start till + * BSSID was cached (in micro seconds). Add this with + * time gap between system boot up to extscan_start + * to derive the time since boot when the + * BSSID was cached. + */ + pSirWifiScanResult->ts += + pHddCtx->extscan_start_time_since_boot; + hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) " + "Ssid (%s)" + "Bssid: %pM " + "Channel (%u)" + "Rssi (%d)" + "RTT (%u)" + "RTT_SD (%u)" + "Beacon Period %u" + "Capability 0x%x " + "Ie length %d", + i, + pSirWifiScanResult->ts, + pSirWifiScanResult->ssid, + pSirWifiScanResult->bssid, + pSirWifiScanResult->channel, + pSirWifiScanResult->rssi, + pSirWifiScanResult->rtt, + pSirWifiScanResult->rtt_sd, + pSirWifiScanResult->beaconPeriod, + pSirWifiScanResult->capability, + ieLength); + + ap = nla_nest_start(skb, j + 1); + if (!ap) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + if (nla_put_u64(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + pSirWifiScanResult->ts) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + sizeof(pSirWifiScanResult->ssid), + pSirWifiScanResult->ssid) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + sizeof(pSirWifiScanResult->bssid), + pSirWifiScanResult->bssid) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + pSirWifiScanResult->channel) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + pSirWifiScanResult->rssi) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + pSirWifiScanResult->rtt) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + pSirWifiScanResult->rtt_sd)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD, + pSirWifiScanResult->beaconPeriod)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY, + pSirWifiScanResult->capability)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH, + ieLength)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + if (ieLength) + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA, + ieLength, ie)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + + nla_nest_end(skb, ap); + } + nla_nest_end(skb, aps); + nla_nest_end(skb, nla_result); + } + + nla_nest_end(skb, nla_results); + + cfg80211_vendor_cmd_reply(skb); + + } while (totalResults > 0); + } + + if (!pData->moreData) { + spin_lock(&hdd_context_lock); + context->response_status = 0; + complete(&context->response_event); + spin_unlock(&hdd_context_lock); + } + + EXIT(); + return; +fail: + kfree_skb(skb); + return; +} + +static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx, + void *pMsg) +{ + tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg; + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tANI_U32 i, index; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) { + hddLog(LOGE, + FL("HDD context is not valid or response")); + return; + } + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + if (pData->bss_found) + index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX; + else + index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX; + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + index, GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss); + hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData); + hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found); + + for (i = 0; i < pData->numHotlistBss; i++) { + hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) " + "Ssid (%s) " + "Bssid (" MAC_ADDRESS_STR ") " + "Channel (%u) " + "Rssi (%d) " + "RTT (%u) " + "RTT_SD (%u) ", + i, + pData->bssHotlist[i].ts, + pData->bssHotlist[i].ssid, + MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid), + pData->bssHotlist[i].channel, + pData->bssHotlist[i].rssi, + pData->bssHotlist[i].rtt, + pData->bssHotlist[i].rtt_sd); + } + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + pData->numHotlistBss)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail")); + goto fail; + } + if (pData->numHotlistBss) { + struct nlattr *aps; + + aps = nla_nest_start(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST); + if (!aps) + goto fail; + + for (i = 0; i < pData->numHotlistBss; i++) { + struct nlattr *ap; + + ap = nla_nest_start(skb, i + 1); + if (!ap) + goto fail; + + if (nla_put_u64(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + pData->bssHotlist[i].ts) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + sizeof(pData->bssHotlist[i].ssid), + pData->bssHotlist[i].ssid) || + nla_put(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + sizeof(pData->bssHotlist[i].bssid), + pData->bssHotlist[i].bssid) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + pData->bssHotlist[i].channel) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + pData->bssHotlist[i].rssi) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + pData->bssHotlist[i].rtt) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + pData->bssHotlist[i].rtt_sd)) + goto fail; + + nla_nest_end(skb, ap); + } + nla_nest_end(skb, aps); + + if (nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData)) + goto fail; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + EXIT(); + return; + +fail: + kfree_skb(skb); + return; + +} + +static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx, + void *pMsg) +{ + struct sk_buff *skb; + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + tpSirWifiFullScanResultEvent pData = + (tpSirWifiFullScanResultEvent) (pMsg); + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) { + hddLog(LOGE, + FL("HDD context is not valid or response")); + return; + } + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + /* + * If the full scan result including IE data exceeds NL 4K size + * limitation, drop that beacon/probe rsp frame. + */ + if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) { + hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!")); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData); + hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) " + "Ssid (%s)" + "Bssid (" MAC_ADDRESS_STR ")" + "Channel (%u)" + "Rssi (%d)" + "RTT (%u)" + "RTT_SD (%u)" + "Bcn Period %d" + "Capability 0x%X "), + pData->ap.ts, + pData->ap.ssid, + MAC_ADDR_ARRAY(pData->ap.bssid), + pData->ap.channel, + pData->ap.rssi, + pData->ap.rtt, + pData->ap.rtt_sd, + pData->ap.beaconPeriod, + pData->ap.capability); + + hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength); + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u64(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP, + pData->ap.ts) || + nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID, + sizeof(pData->ap.ssid), + pData->ap.ssid) || + nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID, + WNI_CFG_BSSID_LEN, + pData->ap.bssid) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL, + pData->ap.channel) || + nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI, + pData->ap.rssi) || + nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT, + pData->ap.rtt) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD, + pData->ap.rtt_sd) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD, + pData->ap.beaconPeriod) || + nla_put_u16(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY, + pData->ap.capability) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH, + pData->ieLength) || + nla_put_u8(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA, + pData->moreData)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + if (pData->ieLength) { + if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA, + pData->ieLength, + pData->ie)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + EXIT(); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx, + void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tpSirEXTScanResultsAvailableIndParams pData = + (tpSirEXTScanResultsAvailableIndParams) pMsg; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)){ + hddLog(LOGE, + FL("HDD context is not valid or response")); + return; + } + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", + pData->numResultsAvailable); + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE, + pData->numResultsAvailable)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + EXIT(); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + struct sk_buff *skb = NULL; + tpSirEXTScanProgressIndParams pData = + (tpSirEXTScanProgressIndParams) pMsg; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)){ + hddLog(LOGE, + FL("HDD context is not valid or response")); + return; + } + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId); + hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)", + pData->extScanEventType); + hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)", + pData->status); + + if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE, + pData->extScanEventType) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID, + pData->requestId) || + nla_put_u32(skb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS, + pData->status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + EXIT(); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} + +void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType, + void *pMsg) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) { + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType); + + + switch(evType) { + case SIR_HAL_EXTSCAN_START_RSP: + wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg); + break; + + case SIR_HAL_EXTSCAN_STOP_RSP: + wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg); + break; + case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP: + /* There is no need to send this response to upper layer + Just log the message */ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP")); + break; + case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP: + wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg); + break; + + case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP: + wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg); + break; + + case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP: + wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg); + break; + case SIR_HAL_EXTSCAN_PROGRESS_IND: + wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg); + break; + case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND: + wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg); + break; + case SIR_HAL_EXTSCAN_SCAN_RESULT_IND: + wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg); + break; + case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND: + wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg); + break; + case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND: + wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType); + break; + } + EXIT(); +} + +static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + tSirGetEXTScanCapabilitiesReqParams reqMsg; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr + *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + struct hdd_ext_scan_context *context; + unsigned long rc; + int ret; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + /* check the EXTScan Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) || + (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) || + (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXTScan not enabled/supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + + reqMsg.requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId); + + reqMsg.sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId); + + vos_spin_lock_acquire(&hdd_context_lock); + context = &pHddCtx->ext_scan_context; + context->request_id = reqMsg.requestId; + INIT_COMPLETION(context->response_event); + vos_spin_lock_release(&hdd_context_lock); + + status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_EXTScanGetCapabilities failed(err=%d)"), status); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN)); + if (!rc) { + hddLog(LOGE, FL("Target response timed out")); + return -ETIMEDOUT; + } + + ret = wlan_hdd_send_ext_scan_capability(pHddCtx); + if (ret) + hddLog(LOGE, FL("Failed to send ext scan capability to user space")); + + return ret; + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + tSirEXTScanGetCachedResultsReqParams reqMsg; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr + *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + struct hdd_ext_scan_context *context; + unsigned long rc; + int retval; + + ENTER(); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + /* check the EXTScan Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) || + (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) || + (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXTScan not enabled/supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + + reqMsg.requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId); + + reqMsg.sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId); + + /* Parse and fetch flush parameter */ + if (!tb + [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed")); + goto failed; + } + reqMsg.flush = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush); + + spin_lock(&hdd_context_lock); + context = &pHddCtx->ext_scan_context; + context->request_id = reqMsg.requestId; + context->ignore_cached_results = false; + INIT_COMPLETION(context->response_event); + spin_unlock(&hdd_context_lock); + + status = sme_getCachedResults(pHddCtx->hHal, &reqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_getCachedResults failed(err=%d)"), status); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN)); + if (!rc) { + hddLog(LOGE, FL("Target response timed out")); + retval = -ETIMEDOUT; + spin_lock(&hdd_context_lock); + context->ignore_cached_results = true; + spin_unlock(&hdd_context_lock); + } else { + spin_lock(&hdd_context_lock); + retval = context->response_status; + spin_unlock(&hdd_context_lock); + } + + EXIT(); + return retval; + +failed: + return -EINVAL; +} +static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr + *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr + *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *apTh; + eHalStatus status; + tANI_U8 i = 0; + int rem; + struct hdd_ext_scan_context *context; + tANI_U32 request_id; + unsigned long rc; + int retval; + + ENTER(); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + /* check the EXTScan Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) || + (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) || + (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXTScan not enabled/supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + pReqMsg = (tpSirEXTScanSetBssidHotListReqParams) + vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + + pReqMsg->requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + /* Parse and fetch number of APs */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed")); + goto fail; + } + + /* Parse and fetch lost ap sample size */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) { + hddLog(LOGE, FL("attr lost ap sample size failed")); + goto fail; + } + + pReqMsg->lostBssidSampleSize = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]); + hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + pReqMsg->numBssid = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]); + if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) { + hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"), + pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS); + goto fail; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid); + + nla_for_each_nested(apTh, + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) { + if (i == pReqMsg->numBssid) { + hddLog(LOGW, FL("Ignoring excess AP")); + break; + } + + if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(apTh), nla_len(apTh), + NULL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed")); + goto fail; + } + + /* Parse and fetch MAC address */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed")); + goto fail; + } + memcpy(pReqMsg->ap[i].bssid, nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]), + sizeof(tSirMacAddr)); + hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid); + + /* Parse and fetch low RSSI */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed")); + goto fail; + } + pReqMsg->ap[i].low = nla_get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low); + + /* Parse and fetch high RSSI */ + if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed")); + goto fail; + } + pReqMsg->ap[i].high = nla_get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"), + pReqMsg->ap[i].high); + i++; + } + + if (i < pReqMsg->numBssid) { + hddLog(LOGW, FL("Number of AP %u less than expected %u"), + i, pReqMsg->numBssid); + pReqMsg->numBssid = i; + } + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + INIT_COMPLETION(context->response_event); + context->request_id = request_id = pReqMsg->requestId; + spin_unlock(&hdd_context_lock); + + status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_SetBssHotlist failed(err=%d)"), status); + vos_mem_free(pReqMsg); + return -EINVAL; + } + + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN)); + + if (!rc) { + hddLog(LOGE, FL("sme_SetBssHotlist timed out")); + retval = -ETIMEDOUT; + } else { + spin_lock(&hdd_context_lock); + if (context->request_id == request_id) + retval = context->response_status; + else + retval = -EINVAL; + spin_unlock(&hdd_context_lock); + } + + vos_mem_free(pReqMsg); + EXIT(); + return retval; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data, + dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + uint8_t num_channels = 0; + uint8_t num_chan_new = 0; + uint8_t buf[256] = {0}; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + tANI_U32 requestId, maxChannels; + tWifiBand wifiBand; + eHalStatus status; + struct sk_buff *replySkb; + tANI_U8 i,j,k; + int ret,len = 0;; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId); + + /* Parse and fetch wifi band */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed")); + return -EINVAL; + } + wifiBand = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand); + + /* Parse and fetch max channels */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]) + { + hddLog(LOGE, FL("attr max channels failed")); + return -EINVAL; + } + maxChannels = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels); + + status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal), + wifiBand, chan_list, + &num_channels); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_GetValidChannelsByBand failed (err=%d)"), status); + return -EINVAL; + } + + num_channels = VOS_MIN(num_channels, maxChannels); + num_chan_new = num_channels; + /* remove the indoor only channels if iface is SAP */ + if (WLAN_HDD_SOFTAP == pAdapter->device_mode) + { + num_chan_new = 0; + for (i = 0; i < num_channels; i++) + for (j = 0; j < IEEE80211_NUM_BANDS; j++) { + if (wiphy->bands[j] == NULL) + continue; + for (k = 0; k < wiphy->bands[j]->n_channels; k++) { + if ((chan_list[i] == + wiphy->bands[j]->channels[k].center_freq) && + (!(wiphy->bands[j]->channels[k].flags & + IEEE80211_CHAN_INDOOR_ONLY))) { + chan_list[num_chan_new] = chan_list[i]; + num_chan_new++; + } + } + } + } + + hddLog(LOG1, FL("Number of channels: %d"), num_chan_new); + for (i = 0; i < num_chan_new; i++) + len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]); + hddLog(LOG1, "Channels: %s", buf); + + replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + sizeof(u32) * num_chan_new + + NLMSG_HDRLEN); + + if (!replySkb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("valid channels: buffer alloc fail")); + return -EINVAL; + } + if (nla_put_u32(replySkb, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS, + num_chan_new) || + nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS, + sizeof(u32) * num_chan_new, chan_list)) { + + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + kfree_skb(replySkb); + return -EINVAL; + } + + ret = cfg80211_vendor_cmd_reply(replySkb); + + EXIT(); + return ret; +} + +static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data, + dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int hdd_extscan_start_fill_bucket_channel_spec( + hdd_context_t *pHddCtx, + tpSirEXTScanStartReqParams pReqMsg, + struct nlattr **tb) +{ + struct nlattr *bucket[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + struct nlattr *buckets; + struct nlattr *channels; + int rem1, rem2; + eHalStatus status; + tANI_U8 bktIndex, j, numChannels; + uint32_t expected_buckets; + tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U32 passive_max_chn_time, active_max_chn_time; + + expected_buckets = pReqMsg->numBuckets; + bktIndex = 0; + + nla_for_each_nested(buckets, + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) { + if (bktIndex >= expected_buckets) { + hddLog(LOGW, FL("ignoring excess buckets")); + break; + } + + if (nla_parse(bucket, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(buckets), nla_len(buckets), + wlan_hdd_extscan_config_policy)) { + hddLog(LOGE, FL("nla_parse failed")); + return -EINVAL; + } + + /* Parse and fetch bucket spec */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) { + hddLog(LOGE, FL("attr bucket index failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].bucket = nla_get_u8( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]); + hddLog(LOG1, FL("Bucket spec Index %d"), + pReqMsg->buckets[bktIndex].bucket); + + /* Parse and fetch wifi band */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) { + hddLog(LOGE, FL("attr wifi band failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].band = nla_get_u8( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]); + hddLog(LOG1, FL("Wifi band %d"), + pReqMsg->buckets[bktIndex].band); + + /* Parse and fetch period */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) { + hddLog(LOGE, FL("attr period failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].period = nla_get_u32( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]); + hddLog(LOG1, FL("period %d"), + pReqMsg->buckets[bktIndex].period); + + /* Parse and fetch report events */ + if (!bucket[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) { + hddLog(LOGE, FL("attr report events failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8( + bucket[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]); + hddLog(LOG1, FL("report events %d"), + pReqMsg->buckets[bktIndex].reportEvents); + + /* Parse and fetch max period */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) { + hddLog(LOGE, FL("attr max period failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].max_period = nla_get_u32( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]); + hddLog(LOG1, FL("max period %u"), + pReqMsg->buckets[bktIndex].max_period); + + /* Parse and fetch exponent */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) { + hddLog(LOGE, FL("attr exponent failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].exponent = nla_get_u32( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]); + hddLog(LOG1, FL("exponent %u"), + pReqMsg->buckets[bktIndex].exponent); + + /* Parse and fetch step count */ + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) { + hddLog(LOGE, FL("attr step count failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].step_count = nla_get_u32( + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]); + hddLog(LOG1, FL("Step count %u"), + pReqMsg->buckets[bktIndex].step_count); + + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time); + ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time); + + /* Framework shall pass the channel list if the input WiFi band is + * WIFI_BAND_UNSPECIFIED. + * If the input WiFi band is specified (any value other than + * WIFI_BAND_UNSPECIFIED) then driver populates the channel list + */ + if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) { + numChannels = 0; + hddLog(LOG1, "WiFi band is specified, driver to fill channel list"); + status = sme_GetValidChannelsByBand(pHddCtx->hHal, + pReqMsg->buckets[bktIndex].band, + chanList, &numChannels); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(LOGE, + FL("sme_GetValidChannelsByBand failed (err=%d)"), + status); + return -EINVAL; + } + + pReqMsg->buckets[bktIndex].numChannels = + VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS); + hddLog(LOG1, FL("Num channels %d"), + pReqMsg->buckets[bktIndex].numChannels); + + for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels; + j++) { + pReqMsg->buckets[bktIndex].channels[j].channel = + chanList[j]; + pReqMsg->buckets[bktIndex].channels[j]. + chnlClass = 0; + if (CSR_IS_CHANNEL_DFS( + vos_freq_to_chan(chanList[j]))) { + pReqMsg->buckets[bktIndex].channels[j]. + passive = 1; + pReqMsg->buckets[bktIndex].channels[j]. + dwellTimeMs = passive_max_chn_time; + } else { + pReqMsg->buckets[bktIndex].channels[j]. + passive = 0; + pReqMsg->buckets[bktIndex].channels[j]. + dwellTimeMs = active_max_chn_time; + } + + hddLog(LOG1, + "Channel %u Passive %u Dwell time %u ms", + pReqMsg->buckets[bktIndex].channels[j].channel, + pReqMsg->buckets[bktIndex].channels[j].passive, + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs); + } + + bktIndex++; + continue; + } + + /* Parse and fetch number of channels */ + if (!bucket[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) { + hddLog(LOGE, FL("attr num channels failed")); + return -EINVAL; + } + + pReqMsg->buckets[bktIndex].numChannels = + nla_get_u32(bucket[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]); + hddLog(LOG1, FL("num channels %d"), + pReqMsg->buckets[bktIndex].numChannels); + + if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) { + hddLog(LOGE, FL("attr channel spec failed")); + return -EINVAL; + } + + j = 0; + nla_for_each_nested(channels, + bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) { + if (nla_parse(channel, + QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + nla_data(channels), nla_len(channels), + wlan_hdd_extscan_config_policy)) { + hddLog(LOGE, FL("nla_parse failed")); + return -EINVAL; + } + + /* Parse and fetch channel */ + if (!channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) { + hddLog(LOGE, FL("attr channel failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].channels[j].channel = + nla_get_u32(channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]); + hddLog(LOG1, FL("channel %u"), + pReqMsg->buckets[bktIndex].channels[j].channel); + + /* Parse and fetch dwell time */ + if (!channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) { + hddLog(LOGE, FL("attr dwelltime failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = + nla_get_u32(channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]); + + hddLog(LOG1, FL("Dwell time (%u ms)"), + pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs); + + + /* Parse and fetch channel spec passive */ + if (!channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) { + hddLog(LOGE, + FL("attr channel spec passive failed")); + return -EINVAL; + } + pReqMsg->buckets[bktIndex].channels[j].passive = + nla_get_u8(channel[ + QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]); + hddLog(LOG1, FL("Chnl spec passive %u"), + pReqMsg->buckets[bktIndex].channels[j].passive); + + j++; + } + + bktIndex++; + } + + return 0; +} + + +/* + * define short names for the global vendor params + * used by wlan_hdd_cfg80211_extscan_start() + */ +#define PARAM_MAX \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +#define PARAM_REQUEST_ID \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID +#define PARAM_BASE_PERIOD \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD +#define PARAM_MAX_AP_PER_SCAN \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN +#define PARAM_RPT_THRHLD_PERCENT \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT +#define PARAM_RPT_THRHLD_NUM_SCANS \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS +#define PARAM_NUM_BUCKETS \ +QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS + +static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + tpSirEXTScanStartReqParams pReqMsg = NULL; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[PARAM_MAX + 1]; + int retval; + eHalStatus status; + tANI_U32 request_id; + struct hdd_ext_scan_context *context; + unsigned long rc; + + ENTER(); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + /* check the EXTScan Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) || + (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) || + (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXTScan not enabled/supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb, PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + + pReqMsg = (tpSirEXTScanStartReqParams) + vos_mem_malloc(sizeof(*pReqMsg)); + if (!pReqMsg) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed")); + return -ENOMEM; + } + + pReqMsg->requestId = nla_get_u32( + tb[PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId); + + pReqMsg->sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId); + + /* Parse and fetch base period */ + if (!tb[PARAM_BASE_PERIOD]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed")); + goto fail; + } + pReqMsg->basePeriod = nla_get_u32( + tb[PARAM_BASE_PERIOD]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"), + pReqMsg->basePeriod); + + /* Parse and fetch max AP per scan */ + if (!tb[PARAM_MAX_AP_PER_SCAN]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed")); + goto fail; + } + pReqMsg->maxAPperScan = nla_get_u32( + tb[PARAM_MAX_AP_PER_SCAN]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"), + pReqMsg->maxAPperScan); + + /* Parse and fetch report threshold */ + if (!tb[PARAM_RPT_THRHLD_PERCENT]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed")); + goto fail; + } + pReqMsg->reportThresholdPercent = nla_get_u8( + tb[PARAM_RPT_THRHLD_PERCENT]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"), + pReqMsg->reportThresholdPercent); + + /* Parse and fetch report threshold num scans */ + if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) { + hddLog(LOGE, FL("attr report_threshold num scans failed")); + goto fail; + } + pReqMsg->reportThresholdNumScans = nla_get_u8( + tb[PARAM_RPT_THRHLD_NUM_SCANS]); + hddLog(LOG1, FL("Report Threshold num scans %d"), + pReqMsg->reportThresholdNumScans); + + /* Parse and fetch number of buckets */ + if (!tb[PARAM_NUM_BUCKETS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed")); + goto fail; + } + pReqMsg->numBuckets = nla_get_u8( + tb[PARAM_NUM_BUCKETS]); + if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) { + hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets " + "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS); + pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"), + pReqMsg->numBuckets); + + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed")); + goto fail; + } + + pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc; + + if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb)) + goto fail; + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + INIT_COMPLETION(context->response_event); + context->request_id = request_id = pReqMsg->requestId; + spin_unlock(&hdd_context_lock); + + status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_EXTScanStart failed(err=%d)"), status); + goto fail; + } + + pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime(); + + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN)); + + if (!rc) { + hddLog(LOGE, FL("sme_ExtScanStart timed out")); + retval = -ETIMEDOUT; + } else { + spin_lock(&hdd_context_lock); + if (context->request_id == request_id) + retval = context->response_status; + else + retval = -EINVAL; + spin_unlock(&hdd_context_lock); + } + + vos_mem_free(pReqMsg); + EXIT(); + return retval; + +fail: + vos_mem_free(pReqMsg); + return -EINVAL; +} + +/* + * done with short names for the global vendor params + * used by wlan_hdd_cfg80211_extscan_start() + */ +#undef PARAM_MAX +#undef PARAM_REQUEST_ID +#undef PARAM_BASE_PERIOD +#undef PARAMS_MAX_AP_PER_SCAN +#undef PARAMS_RPT_THRHLD_PERCENT +#undef PARAMS_RPT_THRHLD_NUM_SCANS +#undef PARAMS_NUM_BUCKETS + +static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + tSirEXTScanStopReqParams reqMsg; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + int retval; + unsigned long rc; + struct hdd_ext_scan_context *context; + tANI_U32 request_id; + + ENTER(); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return -EINVAL; + } + /* check the EXTScan Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) || + (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) || + (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXTScan not enabled/supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + + reqMsg.requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId); + + reqMsg.sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId); + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + INIT_COMPLETION(context->response_event); + context->request_id = request_id = reqMsg.requestId; + spin_unlock(&hdd_context_lock); + + status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_EXTScanStop failed(err=%d)"), status); + return -EINVAL; + } + + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN)); + + if (!rc) { + hddLog(LOGE, FL("sme_ExtScanStop timed out")); + retval = -ETIMEDOUT; + } else { + spin_lock(&hdd_context_lock); + if (context->request_id == request_id) + retval = context->response_status; + else + retval = -EINVAL; + spin_unlock(&hdd_context_lock); + } + + return retval; + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + tSirEXTScanResetBssidHotlistReqParams reqMsg; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1]; + eHalStatus status; + struct hdd_ext_scan_context *context; + tANI_U32 request_id; + unsigned long rc; + int retval; + + ENTER(); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(LOGE, FL("HDD context is not valid")); + return -EINVAL; + } + /* check the EXTScan Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) || + (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) || + (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("EXTScan not enabled/supported by Firmware")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX, + data, dataLen, + wlan_hdd_extscan_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch request Id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed")); + return -EINVAL; + } + + reqMsg.requestId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId); + + reqMsg.sessionId = pAdapter->sessionId; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId); + + context = &pHddCtx->ext_scan_context; + spin_lock(&hdd_context_lock); + INIT_COMPLETION(context->response_event); + context->request_id = request_id = reqMsg.requestId; + spin_unlock(&hdd_context_lock); + + status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ResetBssHotlist failed(err=%d)"), status); + return -EINVAL; + } + + /* request was sent -- wait for the response */ + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN)); + if (!rc) { + hddLog(LOGE, FL("sme_ResetBssHotlist timed out")); + retval = -ETIMEDOUT; + } else { + spin_lock(&hdd_context_lock); + if (context->request_id == request_id) + retval = context->response_status; + else + retval = -EINVAL; + spin_unlock(&hdd_context_lock); + } + + EXIT(); + return retval; +} + +static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int dataLen) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /* WLAN_FEATURE_EXTSCAN */ + +/*EXT TDLS*/ +static const struct nla_policy +wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = { + .type = NLA_UNSPEC, + .len = HDD_MAC_ADDR_LEN}, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] = + {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 }, + +}; + +static const struct nla_policy +wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = { + .type = NLA_UNSPEC, + .len = HDD_MAC_ADDR_LEN}, + +}; + +static const struct nla_policy +wlan_hdd_tdls_config_state_change_policy[ + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = { + .type = NLA_UNSPEC, + .len = HDD_MAC_ADDR_LEN}, + [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] = + {.type = NLA_S32 }, + +}; + +static const struct nla_policy +wlan_hdd_tdls_config_get_status_policy[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = { + .type = NLA_UNSPEC, + .len = HDD_MAC_ADDR_LEN}, + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 }, + [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS] + = {.type = NLA_S32 }, + +}; + +static const struct nla_policy +wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] = +{ + [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = { + .type = NLA_UNSPEC, + .len = VOS_MAC_ADDR_FIRST_3_BYTES}, +}; + +static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1]; + + ENTER(); + + if (0 != wlan_hdd_validate_context(pHddCtx)){ + return -EINVAL; + } + if (0 == pHddCtx->cfg_ini->enableMacSpoofing) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini")); + return -ENOTSUPP; + } + if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){ + hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW")); + return -ENOTSUPP; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX, + data, data_len, wlan_hdd_mac_config)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]), + VOS_MAC_ADDR_LAST_3_BYTES); + + pHddCtx->spoofMacAddr.isEnabled = TRUE; + + vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]), + VOS_MAC_ADDR_FIRST_3_BYTES); + if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) && + (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) && + (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0)) + { + hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing")); + vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes, + VOS_MAC_ADDRESS_LEN); + pHddCtx->spoofMacAddr.isEnabled = FALSE; + } + + schedule_delayed_work(&pHddCtx->spoof_mac_addr_work, + msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL)); + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + u8 peer[6] = {0}; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1]; + eHalStatus ret; + tANI_S32 state; + tANI_S32 reason; + tANI_S32 global_operating_class = 0; + tANI_S32 channel = 0; + struct sk_buff *skb = NULL; + int retVal; + + ENTER(); + + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return -EINVAL; + } + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context")); + return -EINVAL; + } + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled")); + return -ENOTSUPP; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX, + data, data_len, + wlan_hdd_tdls_config_get_status_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(peer, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]), + sizeof(peer)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer)); + + wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason); + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + 4 * sizeof(s32) + + NLMSG_HDRLEN); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR), + reason, + state, + global_operating_class, + channel, + MAC_ADDR_ARRAY(peer)); + if (nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, + state) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, + reason) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS, + global_operating_class) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL, + channel)) { + + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + retVal = cfg80211_vendor_cmd_reply(skb); + EXIT(); + return retVal; + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int wlan_hdd_cfg80211_exttdls_callback( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8* mac, +#else + tANI_U8* mac, +#endif + tANI_S32 state, + tANI_S32 reason, + void *ctx) +{ + hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx; + struct sk_buff *skb = NULL; + tANI_S32 global_operating_class = 0; + tANI_S32 channel = 0; + hdd_context_t *pHddCtx; + + ENTER(); + + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (wlan_hdd_validate_context(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context")); + return -EINVAL; + } + + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled")); + return -ENOTSUPP; + } + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering ")); + hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)", + reason, + state, + global_operating_class, + channel); + hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(mac)); + + if (nla_put(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR, + VOS_MAC_ADDR_SIZE, mac) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE, + state) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON, + reason) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL, + channel) || + nla_put_s32(skb, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS, + global_operating_class) + ) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail")); + goto nla_put_failure; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + EXIT(); + return (0); + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + u8 peer[6] = {0}; + struct net_device *dev = wdev->netdev; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1]; + eHalStatus status; + tdls_req_params_t pReqMsg = {0}; + int ret; + hdd_adapter_t *pAdapter; + + ENTER(); + + if (!dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL")); + return -EINVAL; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context")); + return -EINVAL; + } + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled")); + return -ENOTSUPP; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX, + data, data_len, + wlan_hdd_tdls_config_enable_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(peer, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]), + sizeof(peer)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer)); + + /* Parse and fetch channel */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed")); + return -EINVAL; + } + pReqMsg.channel = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel); + + /* Parse and fetch global operating class */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed")); + return -EINVAL; + } + pReqMsg.global_operating_class = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"), + pReqMsg.global_operating_class); + + /* Parse and fetch latency ms */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed")); + return -EINVAL; + } + pReqMsg.max_latency_ms = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"), + pReqMsg.max_latency_ms); + + /* Parse and fetch required bandwidth kbps */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed")); + return -EINVAL; + } + + pReqMsg.min_bandwidth_kbps = nla_get_s32( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"), + pReqMsg.min_bandwidth_kbps); + + ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter, + peer, + &pReqMsg, + wlan_hdd_cfg80211_exttdls_callback); + + EXIT(); + return ret; +} + +static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + u8 peer[6] = {0}; + struct net_device *dev = wdev->netdev; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1]; + eHalStatus status; + int ret; + hdd_adapter_t *pAdapter; + + ENTER(); + + if (!dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL")); + return -EINVAL; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context")); + return -EINVAL; + } + if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled")); + return -ENOTSUPP; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX, + data, data_len, + wlan_hdd_tdls_config_disable_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + /* Parse and fetch mac address */ + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed")); + return -EINVAL; + } + + memcpy(peer, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]), + sizeof(peer)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer)); + + ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer); + + EXIT(); + return ret; +} + +static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int +__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct sk_buff *skb = NULL; + tANI_U32 fset = 0; + int ret = 0; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { + hddLog(LOG1, FL("Infra Station mode is supported by driver")); + fset |= WIFI_FEATURE_INFRA; + } + + if (TRUE == hdd_is_5g_supported(pHddCtx)) { + hddLog(LOG1, FL("INFRA_5G is supported by firmware")); + fset |= WIFI_FEATURE_INFRA_5G; + } + +#ifdef WLAN_FEATURE_P2P + if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) && + (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) { + hddLog(LOG1, FL("WiFi-Direct is supported by driver")); + fset |= WIFI_FEATURE_P2P; + } +#endif + + /* Soft-AP is supported currently by default */ + fset |= WIFI_FEATURE_SOFT_AP; + + /* HOTSPOT is a supplicant feature, enable it by default */ + fset |= WIFI_FEATURE_HOTSPOT; + +#ifdef WLAN_FEATURE_EXTSCAN + if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) && + sme_IsFeatureSupportedByFW(EXTENDED_SCAN) && + sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) { + hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware")); + fset |= WIFI_FEATURE_EXTSCAN; + } +#endif + + if (sme_IsFeatureSupportedByFW(NAN)) { + hddLog(LOG1, FL("NAN is supported by firmware")); + fset |= WIFI_FEATURE_NAN; + } + + /* D2D RTT is not supported currently by default */ + if (sme_IsFeatureSupportedByFW(RTT)) { + hddLog(LOG1, FL("RTT is supported by firmware")); + fset |= WIFI_FEATURE_D2AP_RTT; + } + + if (sme_IsFeatureSupportedByFW(RTT3)) { + hddLog(LOG1, FL("RTT3 is supported by firmware")); + fset |= WIFI_FEATURE_RTT3; + } + +#ifdef FEATURE_WLAN_BATCH_SCAN + if (fset & WIFI_FEATURE_EXTSCAN) { + hddLog(LOG1, FL("Batch scan is supported as extscan is supported")); + fset &= ~WIFI_FEATURE_BATCH_SCAN; + } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) { + hddLog(LOG1, FL("Batch scan is supported by firmware")); + fset |= WIFI_FEATURE_BATCH_SCAN; + } +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO + if (pHddCtx->cfg_ini->configPNOScanSupport && + (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) { + hddLog(LOG1, FL("PNO is supported by firmware")); + fset |= WIFI_FEATURE_PNO; + } +#endif + + /* STA+STA is supported currently by default */ + fset |= WIFI_FEATURE_ADDITIONAL_STA; + +#ifdef FEATURE_WLAN_TDLS + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) && + sme_IsFeatureSupportedByFW(TDLS)) { + hddLog(LOG1, FL("TDLS is supported by firmware")); + fset |= WIFI_FEATURE_TDLS; + } + + /* TDLS_OFFCHANNEL is not supported currently by default */ +#endif + +#ifdef WLAN_AP_STA_CONCURRENCY + /* AP+STA concurrency is supported currently by default */ + fset |= WIFI_FEATURE_AP_STA; +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + fset |= WIFI_FEATURE_LINK_LAYER_STATS; + hddLog(LOG1, FL("Link layer stats is supported by driver")); +#endif + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) + + NLMSG_HDRLEN); + + if (!skb) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -EINVAL; + } + hddLog(LOG1, FL("Supported Features : 0x%x"), fset); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) { + hddLog(LOGE, FL("nla put fail")); + goto nla_put_failure; + } + + ret = cfg80211_vendor_cmd_reply(skb); + EXIT(); + return ret; + +nla_put_failure: + kfree_skb(skb); + return -EINVAL; +} + +static int +wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static const struct +nla_policy +qca_wlan_vendor_wifi_logger_get_ring_data_policy +[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID] + = {.type = NLA_U32 }, +}; + +static int + __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + VOS_STATUS status; + uint32_t ring_id; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb + [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1]; + + ENTER(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) { + return ret; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX, + data, data_len, + qca_wlan_vendor_wifi_logger_get_ring_data_policy)) { + hddLog(LOGE, FL("Invalid attribute")); + return -EINVAL; + } + + /* Parse and fetch ring id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) { + hddLog(LOGE, FL("attr ATTR failed")); + return -EINVAL; + } + + ring_id = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]); + + hddLog(LOG1, FL("Bug report triggered by framework")); + + status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL, + WLAN_LOG_INDICATOR_FRAMEWORK, + WLAN_LOG_REASON_CODE_FRAMEWORK, + TRUE, TRUE + ); + if (VOS_STATUS_SUCCESS != status) { + hddLog(LOGE, FL("Failed to trigger bug report")); + + return -EINVAL; + } + + return 0; + + +} + + +static int + wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy, + wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; + +} + +#define MAX_CONCURRENT_MATRIX \ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX +#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX +static const struct nla_policy +wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = { + [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32}, +}; + +static int +__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0}; + uint8_t i, feature_sets, max_feature_sets; + struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1]; + struct sk_buff *reply_skb; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + int ret; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len, + wlan_hdd_get_concurrency_matrix_policy)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch max feature set */ + if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) { + hddLog(LOGE, FL("Attr max feature set size failed")); + return -EINVAL; + } + max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]); + hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets); + + /* Fill feature combination matrix */ + feature_sets = 0; + feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA | + WIFI_FEATURE_P2P; + + feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA | + WIFI_FEATURE_SOFT_AP; + + feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P | + WIFI_FEATURE_SOFT_AP; + + feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA | + WIFI_FEATURE_SOFT_AP | + WIFI_FEATURE_P2P; + + /* Add more feature combinations here */ + + feature_sets = VOS_MIN(feature_sets, max_feature_sets); + hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets); + hddLog(LOG1, "Feature set matrix"); + for (i = 0; i < feature_sets; i++) + hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]); + + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) + + sizeof(u32) * feature_sets + + NLMSG_HDRLEN); + + if (reply_skb) { + if (nla_put_u32(reply_skb, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE, + feature_sets) || + nla_put(reply_skb, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET, + sizeof(u32) * feature_sets, feature_set_matrix)) { + hddLog(LOGE, FL("nla put fail")); + kfree_skb(reply_skb); + return -EINVAL; + } + + ret = cfg80211_vendor_cmd_reply(reply_skb); + EXIT(); + return ret; + } + hddLog(LOGE, FL("Feature set matrix: buffer alloc fail")); + return -ENOMEM; + +} + +#undef MAX_CONCURRENT_MATRIX +#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX + +static int +wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data, + data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int +__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + int ret; + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + if( !pHddCtx->cfg_ini->enableFwrMemDump || + (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported")); + return -EINVAL; + } + /*call common API for FW mem dump req*/ + ret = wlan_hdd_fw_mem_dump_req(pHddCtx); + + if (!ret) + { + /*indicate to userspace the status of fw mem dump */ + wlan_indicate_mem_dump_complete(true); + } + else + { + /*else send failure to userspace */ + wlan_indicate_mem_dump_complete(false); + } + EXIT(); + return ret; +} + +/** + * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the NL data. + * @data_len:Length of @data + * + * This is called when wlan driver needs to get the firmware memory dump + * via vendor specific command. + * + * Return: 0 on success, error number otherwise. + */ + +static int +wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret = 0; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data, + data_len); + vos_ssr_unprotect(__func__); + return ret; +} + +static const struct +nla_policy +qca_wlan_vendor_wifi_logger_start_policy +[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID] + = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL] + = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS] + = {.type = NLA_U32 }, +}; + +/** + * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable + * or disable the collection of packet statistics from the firmware + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * This function is used to enable or disable the collection of packet + * statistics from the firmware + * + * Return: 0 on success and errno on failure + */ +static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + eHalStatus status; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1]; + tAniWifiStartLog start_log; + + status = wlan_hdd_validate_context(hdd_ctx); + if (0 != status) { + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX, + data, data_len, + qca_wlan_vendor_wifi_logger_start_policy)) { + hddLog(LOGE, FL("Invalid attribute")); + return -EINVAL; + } + + /* Parse and fetch ring id */ + if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) { + hddLog(LOGE, FL("attr ATTR failed")); + return -EINVAL; + } + start_log.ringId = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]); + hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId); + + /* Parse and fetch verbose level */ + if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) { + hddLog(LOGE, FL("attr verbose_level failed")); + return -EINVAL; + } + start_log.verboseLevel = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]); + hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel); + + /* Parse and fetch flag */ + if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) { + hddLog(LOGE, FL("attr flag failed")); + return -EINVAL; + } + start_log.flag = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]); + hddLog(LOG1, FL("flag=%d"), start_log.flag); + + if ((RING_ID_PER_PACKET_STATS == start_log.ringId) && + (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable || + !vos_isPktStatsEnabled())) + + { + hddLog(LOGE, FL("per pkt stats not enabled")); + return -EINVAL; + } + + vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel); + return 0; +} + +/** + * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable + * or disable the collection of packet statistics from the firmware + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * This function is used to enable or disable the collection of packet + * statistics from the firmware + * + * Return: 0 on success and errno on failure + */ +static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + + ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy, + wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static const struct nla_policy +wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + +1] = +{ + [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 }, +}; + +static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1]; + eHalStatus status; + u32 dfsFlag = 0; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + return -EINVAL; + } + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX, + data, data_len, + wlan_hdd_set_no_dfs_flag_config_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch required bandwidth kbps */ + if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed")); + return -EINVAL; + } + + dfsFlag = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]); + hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"), + dfsFlag); + + pHddCtx->disable_dfs_flag = dfsFlag; + + sme_disable_dfs_channel(hHal, dfsFlag); + sme_FilterScanResults(hHal, pAdapter->sessionId); + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; + +} + +const struct +nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = +{ + [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { + .type = NLA_UNSPEC, + .len = HDD_MAC_ADDR_LEN}, +}; + +static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + + u8 bssid[6] = {0}; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + eHalStatus status = eHAL_STATUS_SUCCESS; + v_U32_t isFwrRoamEnabled = FALSE; + int ret; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + return ret; + } + + ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, + data, data_len, + qca_wlan_vendor_attr); + if (ret){ + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR")); + return -EINVAL; + } + + /* Parse and fetch Enable flag */ + if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed")); + return -EINVAL; + } + + isFwrRoamEnabled = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled); + + /* Parse and fetch bssid */ + if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed")); + return -EINVAL; + } + + memcpy(bssid, nla_data( + tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), + sizeof(bssid)); + hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid)); + + //Update roaming + status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled); + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(LOGE, + FL("sme_ConfigFwrRoaming failed (err=%d)"), status); + return -EINVAL; + } + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy, + struct wireless_dev *wdev, const void *data, int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +static const struct +nla_policy +qca_wlan_vendor_get_wifi_info_policy[ + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = { + [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 }, +}; + + +/** + * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * This is called when wlan driver needs to send wifi driver related info + * (driver/fw version) to the user space application upon request. + * + * Return: Return the Success or Failure code. + */ +static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1]; + tSirVersionString version; + uint32 version_len; + uint8 attr; + int status; + struct sk_buff *reply_skb = NULL; + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + status = wlan_hdd_validate_context(hdd_ctx); + if (0 != status) { + hddLog(LOGE, FL("HDD context is not valid")); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data, + data_len, qca_wlan_vendor_get_wifi_info_policy)) { + hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed")); + return -EINVAL; + } + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) { + hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"), + QWLAN_VERSIONSTR); + strlcpy(version, QWLAN_VERSIONSTR, sizeof(version)); + attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION; + } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) { + hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"), + hdd_ctx->fw_Version); + strlcpy(version, hdd_ctx->fw_Version, sizeof(version)); + attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION; + } else { + hddLog(LOGE, FL("Invalid attribute in get wifi info request")); + return -EINVAL; + } + + version_len = strlen(version); + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + version_len + NLA_HDRLEN + NLMSG_HDRLEN); + if (!reply_skb) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + return -ENOMEM; + } + + if (nla_put(reply_skb, attr, version_len, version)) { + hddLog(LOGE, FL("nla put fail")); + kfree_skb(reply_skb); + return -EINVAL; + } + + return cfg80211_vendor_cmd_reply(reply_skb); +} + +/** + * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * @data_len: Length of the data received + * + * This function is used to enable or disable the collection of packet + * statistics from the firmware + * + * Return: 0 on success and errno on failure + */ + +static int +wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) + + +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy, + wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + + +/* + * define short names for the global vendor params + * used by __wlan_hdd_cfg80211_monitor_rssi() + */ +#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX +#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID +#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL +#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI +#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI + +/**--------------------------------------------------------------------------- + + \brief hdd_rssi_monitor_start_done - callback to be executed when rssi + monitor start is completed successfully. + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status) +{ + hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is NULL",__func__); + return; + } + + if (VOS_STATUS_SUCCESS == status) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful")); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful")); + } + + return; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor + stop is completed successfully. + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status) +{ + hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is NULL",__func__); + return; + } + + if (VOS_STATUS_SUCCESS == status) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful")); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful")); + } + + return; +} + +/** + * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Data length + * + * Return: 0 on success, negative errno on failure + */ + +static int +__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + hdd_station_ctx_t *pHddStaCtx; + struct nlattr *tb[PARAM_MAX + 1]; + tpSirRssiMonitorReq pReq; + eHalStatus status; + int ret; + uint32_t control; + static const struct nla_policy policy[PARAM_MAX + 1] = { + [PARAM_REQUEST_ID] = { .type = NLA_U32 }, + [PARAM_CONTROL] = { .type = NLA_U32 }, + [PARAM_MIN_RSSI] = { .type = NLA_S8 }, + [PARAM_MAX_RSSI] = { .type = NLA_S8 }, + }; + + ENTER(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) { + return -EINVAL; + } + + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + hddLog(LOGE, FL("Not in Connected state!")); + return -ENOTSUPP; + } + + if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + if (!tb[PARAM_REQUEST_ID]) { + hddLog(LOGE, FL("attr request id failed")); + return -EINVAL; + } + + if (!tb[PARAM_CONTROL]) { + hddLog(LOGE, FL("attr control failed")); + return -EINVAL; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq)); + if(NULL == pReq) + { + hddLog(LOGE, + FL("vos_mem_alloc failed ")); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0); + + pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]); + pReq->sessionId = pAdapter->sessionId; + pReq->rssiMonitorCbContext = hdd_ctx; + control = nla_get_u32(tb[PARAM_CONTROL]); + vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN); + + hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"), + pReq->requestId, pReq->sessionId, control); + + if (control == QCA_WLAN_RSSI_MONITORING_START) { + if (!tb[PARAM_MIN_RSSI]) { + hddLog(LOGE, FL("attr min rssi failed")); + goto fail; + } + + if (!tb[PARAM_MAX_RSSI]) { + hddLog(LOGE, FL("attr max rssi failed")); + goto fail; + } + + pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]); + pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]); + pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done; + + if (!(pReq->minRssi < pReq->maxRssi)) { + hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"), + pReq->minRssi, pReq->maxRssi); + goto fail; + } + hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"), + pReq->minRssi, pReq->maxRssi); + status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq); + + } + else if (control == QCA_WLAN_RSSI_MONITORING_STOP) { + pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done; + status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq); + } + else { + hddLog(LOGE, FL("Invalid control cmd: %d"), control); + goto fail; + } + + if (!HAL_STATUS_SUCCESS(status)) { + hddLog(LOGE, + FL("sme_set_rssi_monitoring failed(err=%d)"), status); + goto fail; + } + + return 0; +fail: + vos_mem_free(pReq); + return -EINVAL; +} + +/* + * done with short names for the global vendor params + * used by __wlan_hdd_cfg80211_monitor_rssi() + */ +#undef PARAM_MAX +#undef PARAM_CONTROL +#undef PARAM_REQUEST_ID +#undef PARAM_MAX_RSSI +#undef PARAM_MIN_RSSI + +/** + * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of @data + * + * Return: 0 on success; errno on failure + */ +static int +wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +/** + * hdd_rssi_threshold_breached_cb() - rssi breached NL event + * @hddctx: HDD context + * @data: rssi breached event data + * + * This function reads the rssi breached event %data and fill in the skb with + * NL attributes and send up the NL event. + * This callback execute in atomic context and must not invoke any + * blocking calls. + * + * Return: none + */ +void hdd_rssi_threshold_breached_cb(void *hddctx, + struct rssi_breach_event *data) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)hddctx; + int status; + struct sk_buff *skb; + + ENTER(); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + return; + } + + if (!data) { + hddLog(LOGE, FL("data is null")); + return; + } + + skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + NULL, +#endif + EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX, + GFP_KERNEL); + + if (!skb) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + hddLog(LOG1, "Req Id: %u Current rssi: %d", + data->request_id, data->curr_rssi); + hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(data->curr_bssid.bytes)); + + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, + data->request_id) || + nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID, + sizeof(data->curr_bssid), data->curr_bssid.bytes) || + nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI, + data->curr_rssi)) { + hddLog(LOGE, FL("nla put fail")); + goto fail; + } + + cfg80211_vendor_event(skb, GFP_KERNEL); + return; + +fail: + kfree_skb(skb); + return; +} + + + +/** + * __wlan_hdd_cfg80211_setband() - set band + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Data length + * + * Return: 0 on success, negative errno on failure + */ +static int +__wlan_hdd_cfg80211_setband(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + int ret; + static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1] + = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }}; + + ENTER(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len, + policy)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) { + hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed")); + return -EINVAL; + } + + hdd_ctx->isSetBandByNL = TRUE; + ret = hdd_setBand(dev, + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE])); + hdd_ctx->isSetBandByNL = FALSE; + + EXIT(); + return ret; +} + +/** + * wlan_hdd_cfg80211_setband() - Wrapper to offload packets + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of @data + * + * Return: 0 on success; errno on failure + */ +static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_setband(wiphy, + wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef WLAN_FEATURE_OFFLOAD_PACKETS +/** + * hdd_map_req_id_to_pattern_id() - map request id to pattern id + * @hdd_ctx: HDD context + * @request_id: [input] request id + * @pattern_id: [output] pattern id + * + * This function loops through request id to pattern id array + * if the slot is available, store the request id and return pattern id + * if entry exists, return the pattern id + * + * Return: 0 on success and errno on failure + */ +static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx, + uint32_t request_id, + uint8_t *pattern_id) +{ + uint32_t i; + + mutex_lock(&hdd_ctx->op_ctx.op_lock); + for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) + { + if (hdd_ctx->op_ctx.op_table[i].request_id == 0) + { + hdd_ctx->op_ctx.op_table[i].request_id = request_id; + *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id; + mutex_unlock(&hdd_ctx->op_ctx.op_lock); + return 0; + } else if (hdd_ctx->op_ctx.op_table[i].request_id == + request_id) { + *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id; + mutex_unlock(&hdd_ctx->op_ctx.op_lock); + return 0; + } + } + mutex_unlock(&hdd_ctx->op_ctx.op_lock); + return -EINVAL; +} + +/** + * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id + * @hdd_ctx: HDD context + * @request_id: [input] request id + * @pattern_id: [output] pattern id + * + * This function loops through request id to pattern id array + * reset request id to 0 (slot available again) and + * return pattern id + * + * Return: 0 on success and errno on failure + */ +static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx, + uint32_t request_id, + uint8_t *pattern_id) +{ + uint32_t i; + + mutex_lock(&hdd_ctx->op_ctx.op_lock); + for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) + { + if (hdd_ctx->op_ctx.op_table[i].request_id == request_id) + { + hdd_ctx->op_ctx.op_table[i].request_id = 0; + *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id; + mutex_unlock(&hdd_ctx->op_ctx.op_lock); + return 0; + } + } + mutex_unlock(&hdd_ctx->op_ctx.op_lock); + return -EINVAL; +} + + +/* + * define short names for the global vendor params + * used by __wlan_hdd_cfg80211_offloaded_packets() + */ +#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX +#define PARAM_REQUEST_ID \ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID +#define PARAM_CONTROL \ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL +#define PARAM_IP_PACKET \ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA +#define PARAM_SRC_MAC_ADDR \ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR +#define PARAM_DST_MAC_ADDR \ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR +#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD + +/** + * wlan_hdd_add_tx_ptrn() - add tx pattern + * @adapter: adapter pointer + * @hdd_ctx: hdd context + * @tb: nl attributes + * + * This function reads the NL attributes and forms a AddTxPtrn message + * posts it to SME. + * + */ +static int +wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx, + struct nlattr **tb) +{ + struct sSirAddPeriodicTxPtrn *add_req; + eHalStatus status; + uint32_t request_id, ret, len; + uint8_t pattern_id = 0; + v_MACADDR_t dst_addr; + uint16_t eth_type = htons(ETH_P_IP); + + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) + { + hddLog(LOGE, FL("Not in Connected state!")); + return -ENOTSUPP; + } + + add_req = vos_mem_malloc(sizeof(*add_req)); + if (!add_req) + { + hddLog(LOGE, FL("memory allocation failed")); + return -ENOMEM; + } + + /* Parse and fetch request Id */ + if (!tb[PARAM_REQUEST_ID]) + { + hddLog(LOGE, FL("attr request id failed")); + goto fail; + } + + request_id = nla_get_u32(tb[PARAM_REQUEST_ID]); + hddLog(LOG1, FL("Request Id: %u"), request_id); + if (request_id == 0) + { + hddLog(LOGE, FL("request_id cannot be zero")); + goto fail; + } + + if (!tb[PARAM_PERIOD]) + { + hddLog(LOGE, FL("attr period failed")); + goto fail; + } + add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]); + hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs); + if (add_req->usPtrnIntervalMs == 0) + { + hddLog(LOGE, FL("Invalid interval zero, return failure")); + goto fail; + } + + if (!tb[PARAM_SRC_MAC_ADDR]) + { + hddLog(LOGE, FL("attr source mac address failed")); + goto fail; + } + nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR], + VOS_MAC_ADDR_SIZE); + hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(add_req->macAddress)); + + if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE)) + { + hddLog(LOGE, + FL("input src mac address and connected ap bssid are different")); + goto fail; + } + + if (!tb[PARAM_DST_MAC_ADDR]) + { + hddLog(LOGE, FL("attr dst mac address failed")); + goto fail; + } + nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE); + hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(dst_addr.bytes)); + + if (!tb[PARAM_IP_PACKET]) + { + hddLog(LOGE, FL("attr ip packet failed")); + goto fail; + } + add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]); + hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize); + + if (add_req->ucPtrnSize < 0 || + add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE - + HDD_ETH_HEADER_LEN)) + { + hddLog(LOGE, FL("Invalid IP packet len: %d"), + add_req->ucPtrnSize); + goto fail; + } + + len = 0; + vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE); + len += VOS_MAC_ADDR_SIZE; + vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress, + VOS_MAC_ADDR_SIZE); + len += VOS_MAC_ADDR_SIZE; + vos_mem_copy(&add_req->ucPattern[len], ð_type, 2); + len += 2; + + /* + * This is the IP packet, add 14 bytes Ethernet (802.3) header + * ------------------------------------------------------------ + * | 14 bytes Ethernet (802.3) header | IP header and payload | + * ------------------------------------------------------------ + */ + vos_mem_copy(&add_req->ucPattern[len], + nla_data(tb[PARAM_IP_PACKET]), + add_req->ucPtrnSize); + add_req->ucPtrnSize += len; + + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + add_req->ucPattern, add_req->ucPtrnSize); + + ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id); + if (ret) + { + hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret); + goto fail; + } + add_req->ucPtrnId = pattern_id; + hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId); + + status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req); + if (!HAL_STATUS_SUCCESS(status)) + { + hddLog(LOGE, + FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status); + goto fail; + } + + EXIT(); + vos_mem_free(add_req); + return 0; + +fail: + vos_mem_free(add_req); + return -EINVAL; +} + +/** + * wlan_hdd_del_tx_ptrn() - delete tx pattern + * @adapter: adapter pointer + * @hdd_ctx: hdd context + * @tb: nl attributes + * + * This function reads the NL attributes and forms a DelTxPtrn message + * posts it to SME. + * + */ +static int +wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx, + struct nlattr **tb) +{ + struct sSirDelPeriodicTxPtrn *del_req; + eHalStatus status; + uint32_t request_id, ret; + uint8_t pattern_id = 0; + + /* Parse and fetch request Id */ + if (!tb[PARAM_REQUEST_ID]) + { + hddLog(LOGE, FL("attr request id failed")); + return -EINVAL; + } + request_id = nla_get_u32(tb[PARAM_REQUEST_ID]); + if (request_id == 0) + { + hddLog(LOGE, FL("request_id cannot be zero")); + return -EINVAL; + } + + ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id); + if (ret) + { + hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret); + return -EINVAL; + } + + del_req = vos_mem_malloc(sizeof(*del_req)); + if (!del_req) + { + hddLog(LOGE, FL("memory allocation failed")); + return -ENOMEM; + } + + vos_mem_set(del_req, sizeof(*del_req), 0); + vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress)); + del_req->ucPatternIdBitmap |= (0x1 << pattern_id); + hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"), + request_id, pattern_id, del_req->ucPatternIdBitmap); + + status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req); + if (!HAL_STATUS_SUCCESS(status)) + { + hddLog(LOGE, + FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status); + goto fail; + } + + EXIT(); + vos_mem_free(del_req); + return 0; + +fail: + vos_mem_free(del_req); + return -EINVAL; +} + + +/** + * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Data length + * + * Return: 0 on success, negative errno on failure + */ +static int +__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[PARAM_MAX + 1]; + uint8_t control; + int ret; + static const struct nla_policy policy[PARAM_MAX + 1] = + { + [PARAM_REQUEST_ID] = { .type = NLA_U32 }, + [PARAM_CONTROL] = { .type = NLA_U32 }, + [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY, + .len = VOS_MAC_ADDR_SIZE }, + [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY, + .len = VOS_MAC_ADDR_SIZE }, + [PARAM_PERIOD] = { .type = NLA_U32 }, + }; + + ENTER(); + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN)) + { + hddLog(LOGE, + FL("Periodic Tx Pattern Offload feature is not supported in FW!")); + return -ENOTSUPP; + } + + if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) + { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + if (!tb[PARAM_CONTROL]) + { + hddLog(LOGE, FL("attr control failed")); + return -EINVAL; + } + control = nla_get_u32(tb[PARAM_CONTROL]); + hddLog(LOG1, FL("Control: %d"), control); + + if (control == WLAN_START_OFFLOADED_PACKETS) + return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb); + else if (control == WLAN_STOP_OFFLOADED_PACKETS) + return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb); + else + { + hddLog(LOGE, FL("Invalid control: %d"), control); + return -EINVAL; + } +} + +/* + * done with short names for the global vendor params + * used by __wlan_hdd_cfg80211_offloaded_packets() + */ +#undef PARAM_MAX +#undef PARAM_REQUEST_ID +#undef PARAM_CONTROL +#undef PARAM_IP_PACKET +#undef PARAM_SRC_MAC_ADDR +#undef PARAM_DST_MAC_ADDR +#undef PARAM_PERIOD + +/** + * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of @data + * + * Return: 0 on success; errno on failure + */ +static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy, + wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +static const struct +nla_policy +qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = { + [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { + .type = NLA_BINARY, + .len = HDD_MAC_ADDR_LEN}, +}; + +/** + * wlan_hdd_cfg80211_get_link_properties() - This function is used to + * get link properties like nss, rate flags and operating frequency for + * the connection with the given peer. + * @wiphy: WIPHY structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of the data received + * + * This function return the above link properties on success. + * + * Return: 0 on success and errno on failure + */ +static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *hdd_sta_ctx; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1]; + uint8_t peer_mac[VOS_MAC_ADDR_SIZE]; + uint32_t sta_id; + struct sk_buff *reply_skb; + uint32_t rate_flags = 0; + uint8_t nss; + uint8_t final_rate_flags = 0; + uint32_t freq; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + + if (0 != wlan_hdd_validate_context(hdd_ctx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid")); + return -EINVAL; + } + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len, + qca_wlan_vendor_attr_policy)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Attribute peerMac not provided for mode=%d"), + adapter->device_mode); + return -EINVAL; + } + + if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Attribute peerMac is invalid=%d"), + adapter->device_mode); + return -EINVAL; + } + + memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), + sizeof(peer_mac)); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"), + MAC_ADDR_ARRAY(peer_mac), adapter->device_mode); + + if (adapter->device_mode == WLAN_HDD_INFRA_STATION || + adapter->device_mode == WLAN_HDD_P2P_CLIENT) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if ((hdd_sta_ctx->conn_info.connState != + eConnectionState_Associated) || + !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac, + VOS_MAC_ADDRESS_LEN)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not Associated to mac "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(peer_mac)); + return -EINVAL; + } + + nss = 1; //pronto supports only one spatial stream + freq = vos_chan_to_freq( + hdd_sta_ctx->conn_info.operationChannel); + rate_flags = hdd_sta_ctx->conn_info.rate_flags; + + } else if (adapter->device_mode == WLAN_HDD_P2P_GO || + adapter->device_mode == WLAN_HDD_SOFTAP) { + + pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return -ENOENT; + } + + + for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) { + if (pSapCtx->aStaInfo[sta_id].isUsed && + !vos_is_macaddr_broadcast( + &pSapCtx->aStaInfo[sta_id].macAddrSTA) && + vos_mem_compare( + &pSapCtx->aStaInfo[sta_id].macAddrSTA, + peer_mac, VOS_MAC_ADDRESS_LEN)) + break; + } + + if (WLAN_MAX_STA_COUNT == sta_id) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("No active peer with mac="MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(peer_mac)); + return -EINVAL; + } + + nss = 1; //pronto supports only one spatial stream + freq = vos_chan_to_freq( + (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel); + rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags; + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not Associated! with mac"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(peer_mac)); + return -EINVAL; + } + + if (!(rate_flags & eHAL_TX_RATE_LEGACY)) { + if (rate_flags & eHAL_TX_RATE_VHT80) { + final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS; + final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; + } else if (rate_flags & eHAL_TX_RATE_VHT40) { + final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS; + final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } else if (rate_flags & eHAL_TX_RATE_VHT20) { + final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS; + } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) { + final_rate_flags |= RATE_INFO_FLAGS_MCS; + if (rate_flags & eHAL_TX_RATE_HT40) + final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } + + if (rate_flags & eHAL_TX_RATE_SGI) { + if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS)) + final_rate_flags |= RATE_INFO_FLAGS_MCS; + final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI; + } + } + + reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN); + + if (NULL == reply_skb) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("getLinkProperties: skb alloc failed")); + return -EINVAL; + } + + if (nla_put_u8(reply_skb, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS, + nss) || + nla_put_u8(reply_skb, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS, + final_rate_flags) || + nla_put_u32(reply_skb, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ, + freq)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed")); + kfree_skb(reply_skb); + return -EINVAL; + } + + return cfg80211_vendor_cmd_reply(reply_skb); +} + +#define BEACON_MISS_THRESH_2_4 \ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24 +#define BEACON_MISS_THRESH_5_0 \ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5 +#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX +#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM +#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR +#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME +#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \ + QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS + +/** + * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration + * vendor command + * + * @wiphy: wiphy device pointer + * @wdev: wireless device pointer + * @data: Vendor command data buffer + * @data_len: Buffer length + * + * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX. + * + * Return: EOK or other error codes. + */ + +static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hdd_station_ctx_t *pHddStaCtx; + struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1]; + tpSetWifiConfigParams pReq; + tModifyRoamParamsReqParams modifyRoamParamsReq; + eHalStatus status; + int ret_val; + uint8_t hb_thresh_val; + + static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = { + [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 }, + [PARAM_MODULATED_DTIM] = { .type = NLA_U32 }, + [PARAM_GUARD_TIME] = { .type = NLA_U32}, + [PARAM_BCNMISS_PENALTY_PARAM_COUNT] = + { .type = NLA_U32}, + [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 }, + [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 }, + }; + + ENTER(); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + ret_val = wlan_hdd_validate_context(pHddCtx); + if (ret_val) { + return ret_val; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + /* check the Wifi Capability */ + if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) && + (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("WIFICONFIG not supported by Firmware")); + return -EINVAL; + } + + if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) { + modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT; + modifyRoamParamsReq.value = + nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]); + + if (eHAL_STATUS_SUCCESS != + sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__); + ret_val = -EINVAL; + } + return ret_val; + } + + /* Moved this down in order to provide provision to set beacon + * miss penalty count irrespective of connection state. + */ + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + hddLog(LOGE, FL("Not in Connected state!")); + return -ENOTSUPP; + } + + pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams)); + + if (!pReq) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for tSetWifiConfigParams", + __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0); + + pReq->sessionId = pAdapter->sessionId; + vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN); + + if (tb[PARAM_MODULATED_DTIM]) { + pReq->paramValue = nla_get_u32( + tb[PARAM_MODULATED_DTIM]); + hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "), + pReq->paramValue); + pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue; + hdd_set_pwrparams(pHddCtx); + if (BMPS == pmcGetPmcState(pHddCtx->hHal)) { + hddLog( LOG1, FL("WifiConfig: Requesting FullPower!")); + + sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_full_power_cbfn, pAdapter, + eSME_FULL_PWR_NEEDED_BY_HDD); + } + else + { + hddLog( LOG1, FL("WifiConfig Not in BMPS state")); + } + } + + if (tb[PARAM_STATS_AVG_FACTOR]) { + pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR; + pReq->paramValue = nla_get_u16( + tb[PARAM_STATS_AVG_FACTOR]); + hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "), + pReq->paramType, pReq->paramValue); + status = sme_set_wificonfig_params(pHddCtx->hHal, pReq); + + if (eHAL_STATUS_SUCCESS != status) + { + vos_mem_free(pReq); + pReq = NULL; + ret_val = -EPERM; + return ret_val; + } + } + + + if (tb[PARAM_GUARD_TIME]) { + pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME; + pReq->paramValue = nla_get_u32( + tb[PARAM_GUARD_TIME]); + hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "), + pReq->paramType, pReq->paramValue); + status = sme_set_wificonfig_params(pHddCtx->hHal, pReq); + + if (eHAL_STATUS_SUCCESS != status) + { + vos_mem_free(pReq); + pReq = NULL; + ret_val = -EPERM; + return ret_val; + } + + } + + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) { + hb_thresh_val = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]); + + hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d", + hb_thresh_val); + ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val, + NULL, eANI_BOOLEAN_FALSE); + + status = sme_update_hb_threshold( + (WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_HEART_BEAT_THRESHOLD, + hb_thresh_val, eCSR_BAND_24); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status); + vos_mem_free(pReq); + pReq = NULL; + return -EPERM; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) { + hb_thresh_val = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]); + + hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d", + hb_thresh_val); + ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val, + NULL, eANI_BOOLEAN_FALSE); + + status = sme_update_hb_threshold( + (WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_HEART_BEAT_THRESHOLD, + hb_thresh_val, eCSR_BAND_5G); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status); + vos_mem_free(pReq); + pReq = NULL; + return -EPERM; + } + } + + EXIT(); + return ret_val; +} + +/** + * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration + * vendor command + * + * @wiphy: wiphy device pointer + * @wdev: wireless device pointer + * @data: Vendor command data buffer + * @data_len: Buffer length + * + * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX. + * + * Return: EOK or other error codes. + */ +static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev, + data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * define short names for the global vendor params + * used by wlan_hdd_cfg80211_setarp_stats_cmd() + */ +#define STATS_SET_INVALID \ + QCA_ATTR_NUD_STATS_SET_INVALID +#define STATS_SET_START \ + QCA_ATTR_NUD_STATS_SET_START +#define STATS_GW_IPV4 \ + QCA_ATTR_NUD_STATS_GW_IPV4 +#define STATS_SET_MAX \ + QCA_ATTR_NUD_STATS_SET_MAX + +const struct nla_policy +qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] = +{ + [STATS_SET_START] = {.type = NLA_FLAG }, + [STATS_GW_IPV4] = {.type = NLA_U32 }, +}; + +/** + * hdd_set_nud_stats_cb() - hdd callback api to get status + * @data: pointer to adapter + * @rsp: status + * + * Return: None + */ +static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp) +{ + + hdd_adapter_t *adapter = (hdd_adapter_t *)data; + + if (NULL == adapter) + return; + + if (VOS_STATUS_SUCCESS == rsp) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s success received STATS_SET_START", __func__); + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s STATS_SET_START Failed!!", __func__); + } + return; +} + +/** + * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to apfind configuration data. + * @data_len: the length in byte of apfind data. + * + * This is called when wlan driver needs to send arp stats to + * firmware. + * + * Return: An error code or 0 on success. + */ +static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct nlattr *tb[STATS_SET_MAX + 1]; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext; + setArpStatsParams arp_stats_params; + int err = 0; + + ENTER(); + + err = wlan_hdd_validate_context(hdd_ctx); + if (0 != err) + return err; + + if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s NUD_DEBUG feature not supported by firmware!!", __func__); + return -EINVAL; + } + + err = nla_parse(tb, STATS_SET_MAX, data, data_len, + qca_wlan_vendor_set_nud_stats); + if (err) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s STATS_SET_START ATTR", __func__); + return err; + } + + if (tb[STATS_SET_START]) + { + if (!tb[STATS_GW_IPV4]) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s STATS_SET_START CMD", __func__); + return -EINVAL; + } + arp_stats_params.flag = true; + arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]); + } else { + arp_stats_params.flag = false; + } + if (arp_stats_params.flag) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s STATS_SET_START Cleared!!", __func__); + vos_mem_zero(&adapter->hdd_stats.hddArpStats, + sizeof(adapter->hdd_stats.hddArpStats)); + + arp_stats_params.pkt_type = 1; // ARP packet type + + if (arp_stats_params.flag) { + hdd_ctx->track_arp_ip = arp_stats_params.ip_addr; + WLANTL_SetARPFWDatapath(pVosContext, true); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s Set FW in data path for ARP with tgt IP :%d", + __func__, hdd_ctx->track_arp_ip); + } + else { + WLANTL_SetARPFWDatapath(pVosContext, false); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s Remove FW from data path", __func__); + } + + arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb; + arp_stats_params.data_ctx = adapter; + + if (eHAL_STATUS_SUCCESS != + sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s STATS_SET_START CMD Failed!!", __func__); + return -EINVAL; + } + + EXIT(); + + return err; +} + +/** + * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to apfind configuration data. + * @data_len: the length in byte of apfind data. + * + * This is called when wlan driver needs to send arp stats to + * firmware. + * + * Return: An error code or 0 on success. + */ +static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} +#undef STATS_SET_INVALID +#undef STATS_SET_START +#undef STATS_GW_IPV4 +#undef STATS_SET_MAX + +/* + * define short names for the global vendor params + * used by wlan_hdd_cfg80211_setarp_stats_cmd() + */ +#define STATS_GET_INVALID \ + QCA_ATTR_NUD_STATS_SET_INVALID +#define COUNT_FROM_NETDEV \ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV +#define COUNT_TO_LOWER_MAC \ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC +#define RX_COUNT_BY_LOWER_MAC \ + QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC +#define COUNT_TX_SUCCESS \ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS +#define RSP_RX_COUNT_BY_LOWER_MAC \ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC +#define RSP_RX_COUNT_BY_UPPER_MAC \ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC +#define RSP_COUNT_TO_NETDEV \ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV +#define RSP_COUNT_OUT_OF_ORDER_DROP \ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP +#define AP_LINK_ACTIVE \ + QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE +#define AP_LINK_DAD \ + QCA_ATTR_NUD_STATS_AP_LINK_DAD +#define STATS_GET_MAX \ + QCA_ATTR_NUD_STATS_GET_MAX + +const struct nla_policy +qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] = +{ + [COUNT_FROM_NETDEV] = {.type = NLA_U16 }, + [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 }, + [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 }, + [COUNT_TX_SUCCESS] = {.type = NLA_U16 }, + [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 }, + [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 }, + [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 }, + [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 }, + [AP_LINK_ACTIVE] = {.type = NLA_FLAG }, + [AP_LINK_DAD] = {.type = NLA_FLAG }, +}; + +static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp) +{ + + hdd_adapter_t *adapter = (hdd_adapter_t *)data; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct hdd_nud_stats_context *context; + int status; + + ENTER(); + + if (NULL == adapter) + return; + + status = wlan_hdd_validate_context(hdd_ctx); + if (0 != status) { + return; + } + + if (!rsp) { + hddLog(LOGE, FL("data is null")); + return; + } + + adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt; + adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt; + adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt; + adapter->dad |= rsp->dad; + + spin_lock(&hdd_context_lock); + context = &hdd_ctx->nud_stats_context; + complete(&context->response_event); + spin_unlock(&hdd_context_lock); + + return; +} +static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int err = 0; + unsigned long rc; + struct hdd_nud_stats_context *context; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + getArpStatsParams arp_stats_params; + struct sk_buff *skb; + + ENTER(); + + err = wlan_hdd_validate_context(hdd_ctx); + if (0 != err) + return err; + + arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE; + arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb; + arp_stats_params.data_ctx = adapter; + + spin_lock(&hdd_context_lock); + context = &hdd_ctx->nud_stats_context; + INIT_COMPLETION(context->response_event); + spin_unlock(&hdd_context_lock); + + if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s NUD_DEBUG feature not supported by firmware!!", __func__); + return -EINVAL; + } + + if (eHAL_STATUS_SUCCESS != + sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s STATS_SET_START CMD Failed!!", __func__); + return -EINVAL; + } + + rc = wait_for_completion_timeout(&context->response_event, + msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS)); + if (!rc) + { + hddLog(LOGE, + FL("Target response timed out request ")); + return -ETIMEDOUT; + } + + skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + WLAN_NUD_STATS_LEN); + if (!skb) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_cmd_alloc_reply_skb failed", + __func__); + return -ENOMEM; + } + + if (nla_put_u16(skb, COUNT_FROM_NETDEV, + adapter->hdd_stats.hddArpStats.txCount) || + nla_put_u16(skb, COUNT_TO_LOWER_MAC, + adapter->hdd_stats.hddArpStats.tx_host_fw_sent) || + nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC, + adapter->hdd_stats.hddArpStats.tx_fw_cnt) || + nla_put_u16(skb, COUNT_TX_SUCCESS, + adapter->hdd_stats.hddArpStats.tx_ack_cnt) || + nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC, + adapter->hdd_stats.hddArpStats.rx_fw_cnt) || + nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC, + adapter->hdd_stats.hddArpStats.rxCount) || + nla_put_u16(skb, RSP_COUNT_TO_NETDEV, + adapter->hdd_stats.hddArpStats.rxDelivered) || + nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP, + adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) { + hddLog(LOGE, FL("nla put fail")); + kfree_skb(skb); + return -EINVAL; + } + if (adapter->con_status) + nla_put_flag(skb, AP_LINK_ACTIVE); + if (adapter->dad) + nla_put_flag(skb, AP_LINK_DAD); + + cfg80211_vendor_cmd_reply(skb); + return err; +} + +static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +#undef QCA_ATTR_NUD_STATS_SET_INVALID +#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV +#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC +#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC +#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS +#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC +#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC +#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV +#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP +#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE +#undef QCA_ATTR_NUD_STATS_GET_MAX + + + +#ifdef WLAN_FEATURE_APFIND +/** + * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to apfind configuration data. + * @data_len: the length in byte of apfind data. + * + * This is called when wlan driver needs to send APFIND configurations to + * firmware. + * + * Return: An error code or 0 on success. + */ +static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + struct sme_ap_find_request_req apfind_req; + VOS_STATUS status; + int ret_val; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + + ENTER(); + + ret_val = wlan_hdd_validate_context(hdd_ctx); + if (ret_val) + return ret_val; + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EPERM; + } + + apfind_req.request_data_len = data_len; + apfind_req.request_data = data; + + status = sme_apfind_set_cmd(&apfind_req); + if (VOS_STATUS_SUCCESS != status) { + ret_val = -EIO; + } + return ret_val; +} + +/** + * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: pointer to apfind configuration data. + * @data_len: the length in byte of apfind data. + * + * This is called when wlan driver needs to send APFIND configurations to + * firmware. + * + * Return: An error code or 0 on success. + */ +static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /* WLAN_FEATURE_APFIND */ +const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = +{ + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_firmware_roaming + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_nan_request + }, + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_ll_stats_clear + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_ll_stats_set + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_ll_stats_get + }, +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef WLAN_FEATURE_EXTSCAN + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_start + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_stop + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_extscan_get_valid_channels + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_get_capabilities + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_get_cached_results + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist + }, +#endif /* WLAN_FEATURE_EXTSCAN */ +/*EXT TDLS*/ + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_exttdls_enable + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_exttdls_disable + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_exttdls_get_status + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_get_supported_features + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_disable_dfs_channels + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_get_concurrency_matrix + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_get_fw_mem_dump + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_setband + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_wifi_logger_start + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV| + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_get_wifi_info + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_monitor_rssi + }, +#ifdef WLAN_FEATURE_OFFLOAD_PACKETS + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_offloaded_packets + }, +#endif + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_get_link_properties + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_wifi_configuration_set + }, +#ifdef WLAN_FEATURE_APFIND + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_apfind_cmd + }, +#endif /* WLAN_FEATURE_APFIND */ + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_set_nud_stats + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_get_nud_stats + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = hdd_cfg80211_get_station_cmd + }, +}; + +/* vendor specific events */ +static const +struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = +{ +#ifdef FEATURE_WLAN_CH_AVOID + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY + }, +#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + { + /* Index = 1*/ + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET + }, + { + /* Index = 2*/ + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET + }, + { + /* Index = 3*/ + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR + }, + { + /* Index = 4*/ + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS + }, + { + /* Index = 5*/ + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS + }, + { + /* Index = 6*/ + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS + }, +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef WLAN_FEATURE_EXTSCAN + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST + }, + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST + }, +#endif /* WLAN_FEATURE_EXTSCAN */ +/*EXT TDLS*/ + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE + }, + [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP + }, + + + [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN + }, + + { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO, + }, + [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI + }, + [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST + }, + [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET, + }, +}; + +/* + * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc + * This function is called by hdd_wlan_startup() + * during initialization. + * This function is used to allocate wiphy structure. + */ +struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size) +{ + struct wiphy *wiphy; + ENTER(); + /* + * Create wiphy device + */ + wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size); + + if (!wiphy) + { + /* Print error and jump into err label and free the memory */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__); + return NULL; + } + + + return wiphy; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \ + defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT) +/** + * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy + * @wiphy: pointer to wiphy + * @config: pointer to config + * + * Return: None + */ +static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy, + hdd_config_t *config) +{ + wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS; + if (config->max_sched_scan_plan_interval) + wiphy->max_sched_scan_plan_interval = + config->max_sched_scan_plan_interval; + if (config->max_sched_scan_plan_iterations) + wiphy->max_sched_scan_plan_iterations = + config->max_sched_scan_plan_iterations; +} +#else +static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy, + hdd_config_t *config) +{ +} +#endif + +/* + * FUNCTION: wlan_hdd_cfg80211_update_band + * This function is called from the supplicant through a + * private ioctl to change the band value + */ +int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand) +{ + int i, j; + eNVChannelEnabledType channelEnabledState; + + ENTER(); + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + + if (NULL == wiphy->bands[i]) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d", + __func__, i); + continue; + } + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + channelEnabledState = vos_nv_getChannelEnabledState( + band->channels[j].hw_value); + + if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + + if (NV_CHANNEL_DISABLE == channelEnabledState || + NV_CHANNEL_INVALID == channelEnabledState) + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + } + else if (NV_CHANNEL_DFS == channelEnabledState) + { + band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; + band->channels[j].flags |= IEEE80211_CHAN_RADAR; + } + else + { + band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED + |IEEE80211_CHAN_RADAR); + } + } + } + return 0; +} +/* + * FUNCTION: wlan_hdd_cfg80211_init + * This function is called by hdd_wlan_startup() + * during initialization. + * This function is used to initialize and register wiphy structure. + */ +int wlan_hdd_cfg80211_init(struct device *dev, + struct wiphy *wiphy, + hdd_config_t *pCfg + ) +{ + int i, j; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + + ENTER(); + + /* Now bind the underlying wlan device with wiphy */ + set_wiphy_dev(wiphy, dev); + + wiphy->mgmt_stypes = wlan_hdd_txrx_stypes; + +#ifndef CONFIG_ENABLE_LINUX_REG + /* the flag for the other case would be initialzed in + vos_init_wiphy_from_nv_bin */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + wiphy->regulatory_flags |= REGULATORY_STRICT_REG; +#else + wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; +#endif +#endif + + /* This will disable updating of NL channels from passive to + * active if a beacon is received on passive channel. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS; +#else + wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS; +#endif + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME + | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD + | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL + | WIPHY_FLAG_OFFCHAN_TX; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; +#else + wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE; +#endif +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (pCfg->isFastTransitionEnabled +#ifdef FEATURE_WLAN_LFR + || pCfg->isFastRoamIniFeatureEnabled +#endif +#ifdef FEATURE_WLAN_ESE + || pCfg->isEseIniFeatureEnabled +#endif + ) + { + wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; + } +#endif +#ifdef FEATURE_WLAN_TDLS + wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS + | WIPHY_FLAG_TDLS_EXTERNAL_SETUP; +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + if (pCfg->configPNOScanSupport) + { + wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS; + wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS; + wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH; + } +#endif/*FEATURE_WLAN_SCAN_PNO*/ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + wiphy->features |= NL80211_FEATURE_HT_IBSS; +#endif + +#ifdef CONFIG_ENABLE_LINUX_REG + /* even with WIPHY_FLAG_CUSTOM_REGULATORY, + driver can still register regulatory callback and + it will get regulatory settings in wiphy->band[], but + driver need to determine what to do with both + regulatory settings */ + + wiphy->reg_notifier = wlan_hdd_linux_reg_notifier; +#else + wiphy->reg_notifier = wlan_hdd_crda_reg_notifier; +#endif + + wiphy->max_scan_ssids = MAX_SCAN_SSID; + + wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH; + + wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS; + + /* Supports STATION & AD-HOC modes right now */ + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) + | BIT(NL80211_IFTYPE_AP); + + if (VOS_MONITOR_MODE == hdd_get_conparam()) + { + wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); + } + + if( pCfg->advertiseConcurrentOperation ) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + if( pCfg->enableMCC ) + { + /* Currently, supports up to two channels */ + wlan_hdd_iface_combination.num_different_channels = 2; + + if( !pCfg->allowMCCGODiffBI ) + wlan_hdd_iface_combination.beacon_int_infra_match = true; + + } + wiphy->iface_combinations = &wlan_hdd_iface_combination; + wiphy->n_iface_combinations = 1; +#endif + } + + /* Before registering we need to update the ht capabilitied based + * on ini values*/ + if( !pCfg->ShortGI20MhzEnable ) + { + wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; + wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20; + } + + if( !pCfg->ShortGI40MhzEnable ) + { + wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; + } + + if( !pCfg->nChannelBondingMode5GHz ) + { + wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } + /* + * In case of static linked driver at the time of driver unload, + * module exit doesn't happens. Module cleanup helps in cleaning + * of static memory. + * If driver load happens statically, at the time of driver unload, + * wiphy flags don't get reset because of static memory. + * It's better not to store channel in static memory. + */ + wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ; + wiphy->bands[IEEE80211_BAND_2GHZ]->channels = + (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ)); + if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not enough memory to allocate channels")); + return -ENOMEM; + } + vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels, + &hdd_channels_2_4_GHZ[0], + sizeof(hdd_channels_2_4_GHZ)); + + if (true == hdd_is_5g_supported(pHddCtx)) + { + wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ; + wiphy->bands[IEEE80211_BAND_5GHZ]->channels = + (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ)); + if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not enough memory to allocate channels")); + vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); + wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL; + return -ENOMEM; + } + vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels, + &hdd_channels_5_GHZ[0], + sizeof(hdd_channels_5_GHZ)); + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + + if (NULL == wiphy->bands[i]) + { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d", + __func__, i); + continue; + } + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only + { + // Enable social channels for P2P + if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq)) + band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; + else + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only + { + band->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + } + } + /*Initialise the supported cipher suite details*/ + wiphy->cipher_suites = hdd_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites); + + /*signal strength in mBm (100*dBm) */ + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + wiphy->max_remain_on_channel_duration = 5000; +#endif + + wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands); + wiphy->vendor_commands = hdd_wiphy_vendor_commands; + wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events; + wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events); + + hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg); + + EXIT(); + return 0; +} + +/* In this function we are registering wiphy. */ +int wlan_hdd_cfg80211_register(struct wiphy *wiphy) +{ + ENTER(); + /* Register our wiphy dev with cfg80211 */ + if (0 > wiphy_register(wiphy)) + { + /* print error */ + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__); + return -EIO; + } + + EXIT(); + return 0; +} + +/* In this function we are updating channel list when, + regulatory domain is FCC and country code is US. + Here In FCC standard 5GHz UNII-1 Bands are indoor only. + As per FCC smart phone is not a indoor device. + GO should not opeate on indoor channels */ +void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy) +{ + int j; + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE; + //Default counrtycode from NV at the time of wiphy initialization. + if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal, + &defaultCountryCode[0])) + { + hddLog(LOGE, FL("Failed to get default country code from NV")); + } + if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S')) + { + if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ]) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ ); + return; + } + for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ]; + // Mark UNII -1 band channel as passive + if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq)) + band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + } + } +} +/* This function registers for all frame which supplicant is interested in */ +void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + /* Register for all P2P action, public action etc frames */ + v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4); + ENTER(); + /* Register frame indication call back */ + sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame); + /* Right now we are registering these frame when driver is getting + initialized. Once we will move to 2.6.37 kernel, in which we have + frame register ops, we will move this code as a part of that */ + /* GAS Initial Request */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE ); + + /* GAS Initial Response */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE ); + + /* GAS Comeback Request */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE ); + + /* GAS Comeback Response */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE ); + + /* P2P Public Action */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)P2P_PUBLIC_ACTION_FRAME, + P2P_PUBLIC_ACTION_FRAME_SIZE ); + + /* P2P Action */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)P2P_ACTION_FRAME, + P2P_ACTION_FRAME_SIZE ); + + /* WNM BSS Transition Request frame */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)WNM_BSS_ACTION_FRAME, + WNM_BSS_ACTION_FRAME_SIZE ); + + /* WNM-Notification */ + sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)WNM_NOTIFICATION_FRAME, + WNM_NOTIFICATION_FRAME_SIZE ); +} + +void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + /* Register for all P2P action, public action etc frames */ + v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4); + + ENTER(); + + /* Right now we are registering these frame when driver is getting + initialized. Once we will move to 2.6.37 kernel, in which we have + frame register ops, we will move this code as a part of that */ + /* GAS Initial Request */ + + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE ); + + /* GAS Initial Response */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE ); + + /* GAS Comeback Request */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE ); + + /* GAS Comeback Response */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE ); + + /* P2P Public Action */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)P2P_PUBLIC_ACTION_FRAME, + P2P_PUBLIC_ACTION_FRAME_SIZE ); + + /* P2P Action */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)P2P_ACTION_FRAME, + P2P_ACTION_FRAME_SIZE ); + /* WNM-Notification */ + sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type, + (v_U8_t*)WNM_NOTIFICATION_FRAME, + WNM_NOTIFICATION_FRAME_SIZE ); +} + +#ifdef FEATURE_WLAN_WAPI +void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index, + const u8 *mac_addr, const u8 *key , int key_Len) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + tCsrRoamSetKey setKey; + v_BOOL_t isConnected = TRUE; + int status = 0; + v_U32_t roamId= 0xFF; + tANI_U8 *pKeyPtr = NULL; + int n = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; // Store Key ID + setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption + setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX + setKey.paeRole = 0 ; // the PAE role + if (!mac_addr || is_broadcast_ether_addr(mac_addr)) + { + vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac ); + } + else + { + isConnected = hdd_connIsConnected(pHddStaCtx); + vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN); + } + setKey.keyLength = key_Len; + pKeyPtr = setKey.Key; + memcpy( pKeyPtr, key, key_Len); + + hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x", + __func__, key_Len); + for (n = 0 ; n < key_Len; n++) + hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ", + __func__,n,setKey.Key[n]); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + if ( isConnected ) + { + status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + } + if ( status != 0 ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", + __LINE__, status ); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + /* Need to clear any trace of key value in the memory. + * Thus zero out the memory even though it is local + * variable. + */ + vos_mem_zero(&setKey, sizeof(setKey)); +} +#endif /* FEATURE_WLAN_WAPI*/ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter, + beacon_data_t **ppBeacon, + struct beacon_parameters *params) +#else +int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter, + beacon_data_t **ppBeacon, + struct cfg80211_beacon_data *params, + int dtim_period) +#endif +{ + int size; + beacon_data_t *beacon = NULL; + beacon_data_t *old = NULL; + int head_len, tail_len, proberesp_ies_len, assocresp_ies_len; + const u8 *head, *tail, *proberesp_ies, *assocresp_ies; + + ENTER(); + if (params->head && !params->head_len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("head_len is NULL")); + return -EINVAL; + } + + old = pAdapter->sessionCtx.ap.beacon; + + if (!params->head && !old) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("session(%d) old and new heads points to NULL"), + pAdapter->sessionId); + return -EINVAL; + } + + if (params->tail && !params->tail_len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("tail_len is zero but tail is not NULL")); + return -EINVAL; + } + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38)) + /* Kernel 3.0 is not updating dtim_period for set beacon */ + if (!params->dtim_period) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("dtim period is 0")); + return -EINVAL; + } +#endif + + if (params->head) + { + head_len = params->head_len; + head = params->head; + } else + { + head_len = old->head_len; + head = old->head; + } + + if (params->tail || !old) + { + tail_len = params->tail_len; + tail = params->tail; + } else + { + tail_len = old->tail_len; + tail = old->tail; + } + + if (params->proberesp_ies || !old) + { + proberesp_ies_len = params->proberesp_ies_len; + proberesp_ies = params->proberesp_ies; + } else + { + proberesp_ies_len = old->proberesp_ies_len; + proberesp_ies = old->proberesp_ies; + } + + if (params->assocresp_ies || !old) + { + assocresp_ies_len = params->assocresp_ies_len; + assocresp_ies = params->assocresp_ies; + } else + { + assocresp_ies_len = old->assocresp_ies_len; + assocresp_ies = old->assocresp_ies; + } + + size = sizeof(beacon_data_t) + head_len + tail_len + + proberesp_ies_len + assocresp_ies_len; + + beacon = kzalloc(size, GFP_KERNEL); + if( beacon == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Mem allocation for beacon failed")); + return -ENOMEM; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + if (params->dtim_period) + beacon->dtim_period = params->dtim_period; + else + beacon->dtim_period = old->dtim_period; +#else + if (dtim_period) + beacon->dtim_period = dtim_period; + else + beacon->dtim_period = old->dtim_period; +#endif + + beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t); + beacon->tail = beacon->head + head_len; + beacon->proberesp_ies = beacon->tail + tail_len; + beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len; + + beacon->head_len = head_len; + beacon->tail_len = tail_len; + beacon->proberesp_ies_len = proberesp_ies_len; + beacon->assocresp_ies_len= assocresp_ies_len; + + if (head && head_len) + memcpy(beacon->head, head, head_len); + if (tail && tail_len) + memcpy(beacon->tail, tail, tail_len); + if (proberesp_ies && proberesp_ies_len) + memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len); + if (assocresp_ies && assocresp_ies_len) + memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len); + + *ppBeacon = beacon; + + kfree(old); + + return 0; +} + +v_U8_t* wlan_hdd_cfg80211_get_ie_ptr( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + const v_U8_t *pIes, +#else + v_U8_t *pIes, +#endif + int length, v_U8_t eid) +{ + int left = length; + v_U8_t *ptr = (v_U8_t *)pIes; + v_U8_t elem_id,elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len,left); + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +/* Check if rate is 11g rate or not */ +static int wlan_hdd_rate_is_11g(u8 rate) +{ + static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */ + u8 i; + for (i = 0; i < 8; i++) + { + if(rate == gRateArray[i]) + return TRUE; + } + return FALSE; +} + +/* Check for 11g rate and set proper 11g only mode */ +static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht, + u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode) +{ + u8 i, num_rates = pIe[0]; + + pIe += 1; + for ( i = 0; i < num_rates; i++) + { + if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) + { + /* If rate set have 11g rate than change the mode to 11G */ + *pSapHw_mode = eSAP_DOT11_MODE_11g; + if (pIe[i] & BASIC_RATE_MASK) + { + /* If we have 11g rate as basic rate, it means mode + is 11g only mode. + */ + *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY; + *pCheckRatesfor11g = FALSE; + } + } + else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i]) + { + *require_ht = TRUE; + } + } + return; +} + +static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter) +{ + tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig; + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head; + u8 checkRatesfor11g = TRUE; + u8 require_ht = FALSE; + u8 *pIe=NULL; + + pConfig->SapHw_mode= eSAP_DOT11_MODE_11b; + + pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0], + pBeacon->head_len, WLAN_EID_SUPP_RATES); + if (pIe != NULL) + { + pIe += 1; + wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g, + &pConfig->SapHw_mode); + } + + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_EXT_SUPP_RATES); + if (pIe != NULL) + { + + pIe += 1; + wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g, + &pConfig->SapHw_mode); + } + + if( pConfig->channel > 14 ) + { + pConfig->SapHw_mode= eSAP_DOT11_MODE_11a; + } + + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_HT_CAPABILITY); + + if(pIe) + { + pConfig->SapHw_mode= eSAP_DOT11_MODE_11n; + if(require_ht) + pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY; + } +} + +static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie, + v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size) +{ + v_U16_t ielen = 0; + v_U8_t *pIe = NULL; + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + + pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size, + pBeacon->tail, pBeacon->tail_len); + + if (pIe) + { + ielen = pIe[1] + 2; + if ((*total_ielen + ielen) <= MAX_GENIE_LEN) + { + vos_mem_copy(&genie[*total_ielen], pIe, ielen); + } + else + { + hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***"); + return -EINVAL; + } + *total_ielen += ielen; + } + return 0; +} + +static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter, + v_U8_t *genie, v_U8_t *total_ielen) +{ + beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + int left = pBeacon->tail_len; + v_U8_t *ptr = pBeacon->tail; + v_U8_t elem_id, elem_len; + v_U16_t ielen = 0; + + if ( NULL == ptr || 0 == left ) + return; + + while (left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if (elem_len > left) + { + hddLog( VOS_TRACE_LEVEL_ERROR, + "****Invalid IEs eid = %d elem_len=%d left=%d*****", + elem_id, elem_len, left); + return; + } + if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE)) + { + /* skipping the VSIE's which we don't want to include or + * it will be included by existing code + */ + if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) && +#ifdef WLAN_FEATURE_WFD + (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) && +#endif + (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) && + (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0)) + { + ielen = ptr[1] + 2; + if ((*total_ielen + ielen) <= MAX_GENIE_LEN) + { + vos_mem_copy(&genie[*total_ielen], ptr, ielen); + *total_ielen += ielen; + } + else + { + hddLog( VOS_TRACE_LEVEL_ERROR, + "IE Length is too big " + "IEs eid=%d elem_len=%d total_ie_lent=%d", + elem_id, elem_len, *total_ielen); + } + } + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return; +} + +int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter) +{ + v_U8_t *genie; + v_U8_t total_ielen = 0; + v_U8_t addIE[1] = {0}; + int ret = 0; + beacon_data_t *pBeacon = NULL; + + genie = vos_mem_malloc(MAX_GENIE_LEN); + + if(genie == NULL) { + + return -ENOMEM; + } + + pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) + { + hddLog(LOGE, + FL("Adding WPS IE failed")); + ret = -EINVAL; + goto done; + } + +#ifdef WLAN_FEATURE_WFD + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) + { + hddLog(LOGE, + FL("Adding WFD IE failed")); + ret = -EINVAL; + goto done; + } +#endif + + if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie, + &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)) + { + hddLog(LOGE, + FL("Adding P2P IE failed")); + ret = -EINVAL; + goto done; + } + + if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) + { + wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen); + } + + if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL, + eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM"); + ret = -EINVAL; + goto done; + } + + if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL, + test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM"); + ret = -EINVAL; + goto done; + } + + // Added for ProResp IE + if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0)) + { + u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len; + u8 probe_rsp_ie_len[3] = {0}; + u8 counter = 0; + /* Check Probe Resp Length if it is greater then 255 then Store + Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 & + WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able + Store More then 255 bytes into One Variable. + */ + while ((rem_probe_resp_ie_len > 0) && (counter < 3)) + { + if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN) + { + probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN; + rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN; + } + else + { + probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len; + rem_probe_resp_ie_len = 0; + } + } + + rem_probe_resp_ie_len = 0; + + if (probe_rsp_ie_len[0] > 0) + { + if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + (tANI_U8*)&pBeacon-> + proberesp_ies[rem_probe_resp_ie_len], + probe_rsp_ie_len[0], NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM"); + ret = -EINVAL; + goto done; + } + rem_probe_resp_ie_len += probe_rsp_ie_len[0]; + } + + if (probe_rsp_ie_len[1] > 0) + { + if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + (tANI_U8*)&pBeacon-> + proberesp_ies[rem_probe_resp_ie_len], + probe_rsp_ie_len[1], NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM"); + ret = -EINVAL; + goto done; + } + rem_probe_resp_ie_len += probe_rsp_ie_len[1]; + } + + if (probe_rsp_ie_len[2] > 0) + { + if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + (tANI_U8*)&pBeacon-> + proberesp_ies[rem_probe_resp_ie_len], + probe_rsp_ie_len[2], NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM"); + ret = -EINVAL; + goto done; + } + rem_probe_resp_ie_len += probe_rsp_ie_len[2]; + } + + if (probe_rsp_ie_len[1] == 0 ) + { + if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM"); + } + } + + if (probe_rsp_ie_len[2] == 0 ) + { + if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM"); + } + } + + if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL, + test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM"); + ret = -EINVAL; + goto done; + } + } + else + { + // Reset WNI_CFG_PROBE_RSP Flags + wlan_hdd_reset_prob_rspies(pHostapdAdapter); + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: No Probe Response IE received in set beacon", + __func__); + } + + // Added for AssocResp IE + if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0)) + { + if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies, + pBeacon->assocresp_ies_len, NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM"); + ret = -EINVAL; + goto done; + } + + if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL, + test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ? + eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + ret = -EINVAL; + goto done; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: No Assoc Response IE received in set beacon", + __func__); + + if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + } + } + +done: + vos_mem_free(genie); + return ret; +} + +/* + * FUNCTION: wlan_hdd_validate_operation_channel + * called by wlan_hdd_cfg80211_start_bss() and + * wlan_hdd_cfg80211_set_channel() + * This function validates whether given channel is part of valid + * channel list. + */ +VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel) +{ + + v_U32_t num_ch = 0; + u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + u32 indx = 0; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U8_t fValidChannel = FALSE, count = 0; + hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + + num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if ( hdd_pConfig_ini->sapAllowAllChannel) + { + /* Validate the channel */ + for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++) + { + if ( channel == rfChannels[count].channelNum ) + { + fValidChannel = TRUE; + break; + } + } + if (fValidChannel != TRUE) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return VOS_STATUS_E_FAILURE; + } + } + else + { + if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + valid_ch, &num_ch)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to get valid channel list", __func__); + return VOS_STATUS_E_FAILURE; + } + for (indx = 0; indx < num_ch; indx++) + { + if (channel == valid_ch[indx]) + { + break; + } + } + + if (indx >= num_ch) + { + if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + eCsrBand band; + unsigned int freq; + + sme_GetFreqBand(hHal, &band); + + if (eCSR_BAND_5G == band) + { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)) + if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ)) + { + freq = ieee80211_channel_to_frequency(channel, + IEEE80211_BAND_2GHZ); + } + else + { + freq = ieee80211_channel_to_frequency(channel, + IEEE80211_BAND_5GHZ); + } +#else + freq = ieee80211_channel_to_frequency(channel); +#endif + if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq)) + return VOS_STATUS_SUCCESS; + } + } + + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return VOS_STATUS_E_FAILURE; + } + } + + return VOS_STATUS_SUCCESS; + +} + +/** + * FUNCTION: __wlan_hdd_cfg80211_set_channel + * This function is used to set the channel number + */ +static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type + ) +{ + hdd_adapter_t *pAdapter = NULL; + v_U32_t num_ch = 0; + int channel = 0; + int freq = chan->center_freq; /* freq is in MHZ */ + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + if( NULL == dev ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Called with dev = NULL.", __func__); + return -ENODEV; + } + pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId, + channel_type )); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: device_mode = %s (%d) freq = %d", __func__, + hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode, chan->center_freq); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + /* + * Do freq to chan conversion + * TODO: for 11a + */ + + channel = ieee80211_frequency_to_channel(freq); + + /* Check freq range */ + if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) || + (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Channel [%d] is outside valid range from %d to %d", + __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN, + WNI_CFG_CURRENT_CHANNEL_STAMAX); + return -EINVAL; + } + + num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) && + (WLAN_HDD_P2P_GO != pAdapter->device_mode)) + { + if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return -EINVAL; + } + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: set channel to [%d] for device mode =%d", + __func__, channel,pAdapter->device_mode); + } + if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + ) + { + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) + { + /* Link is up then return cant set channel*/ + hddLog( VOS_TRACE_LEVEL_ERROR, + "%s: IBSS Associated, can't set the channel", __func__); + return -EINVAL; + } + + num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1; + pHddStaCtx->conn_info.operationChannel = channel; + pRoamProfile->ChannelInfo.ChannelList = + &pHddStaCtx->conn_info.operationChannel; + } + else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + if(VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter,channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return -EINVAL; + } + (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel; + } + else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) + { + hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + + /* If auto channel selection is configured as enable/ 1 then ignore + channel set by supplicant + */ + if ( cfg_param->apAutoChannelSelection ) + { + (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = + AUTO_CHANNEL_SELECT; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: set channel to auto channel (0) for device mode =%s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + } + else + { + if(VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter,channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, channel); + return -EINVAL; + } + (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel; + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Invalid device mode failed to set valid channel", __func__); + return -EINVAL; + } + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type + ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef DHCP_SERVER_OFFLOAD +void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context, + VOS_STATUS status) +{ + hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context; + + ENTER(); + + if (NULL == adapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: adapter is NULL",__func__); + return; + } + + adapter->dhcp_status.dhcp_offload_status = status; + vos_event_set(&adapter->dhcp_status.vos_event); + return; +} + +/** + * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload + * @hostapd_adapter: pointer to hostapd adapter. + * @re_init: flag set if api called post ssr + * + * Return: None + */ +VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter, + bool re_init) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter); + sir_dhcp_srv_offload_info dhcp_srv_info; + tANI_U8 num_entries = 0; + tANI_U8 srv_ip[IPADDR_NUM_ENTRIES]; + tANI_U8 num; + tANI_U32 temp; + VOS_STATUS ret; + + ENTER(); + + if (!re_init) { + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return VOS_STATUS_E_INVAL; + } + + /* Prepare the request to send to SME */ + dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info)); + if (NULL == dhcp_srv_info) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: could not allocate tDhcpSrvOffloadInfo!", __func__); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info)); + + dhcp_srv_info->bssidx = hostapd_adapter->sessionId; + dhcp_srv_info->dhcp_srv_offload_enabled = TRUE; + dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients; + dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb; + dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done; + dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter; + + hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip, + srv_ip, + &num_entries, + IPADDR_NUM_ENTRIES, "."); + if (num_entries != IPADDR_NUM_ENTRIES) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: incorrect IP address (%s) assigned for DHCP server!", + __func__, hdd_ctx->cfg_ini->dhcp_srv_ip); + vos_mem_free(dhcp_srv_info); + return VOS_STATUS_E_FAILURE; + } + + if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: invalid IP address (%s)! It could NOT be multicast IP address!", + __func__, hdd_ctx->cfg_ini->dhcp_srv_ip); + vos_mem_free(dhcp_srv_info); + return VOS_STATUS_E_FAILURE; + } + + if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: invalid IP address (%s)! The last field must be less than 100!", + __func__, hdd_ctx->cfg_ini->dhcp_srv_ip); + vos_mem_free(dhcp_srv_info); + return VOS_STATUS_E_FAILURE; + } + + for (num = 0; num < num_entries; num++) { + temp = srv_ip[num]; + dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num)); + } + + if (eHAL_STATUS_SUCCESS != + sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_set_dhcp_srv_offload fail!", __func__); + vos_mem_free(dhcp_srv_info); + return VOS_STATUS_E_FAILURE; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: enable DHCP Server offload successfully!", __func__); + + vos_mem_free(dhcp_srv_info); + return 0; +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, + struct beacon_parameters *params) +#else +static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, + struct cfg80211_beacon_data *params, + const u8 *ssid, size_t ssid_len, + enum nl80211_hidden_ssid hidden_ssid, + v_U8_t auth_type) +#endif +{ + tsap_Config_t *pConfig; + beacon_data_t *pBeacon = NULL; + struct ieee80211_mgmt *pMgmt_frame; + v_U8_t *pIe=NULL; + v_U16_t capab_info; + eCsrAuthType RSNAuthType; + eCsrEncryptionType RSNEncryptType; + eCsrEncryptionType mcRSNEncryptType; + int status = VOS_STATUS_SUCCESS, ret = 0; + tpWLAN_SAPEventCB pSapEventCallback; + hdd_hostapd_state_t *pHostapdState; + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + struct qc_mac_acl_entry *acl_entry = NULL; + hdd_config_t *iniConfig; + v_SINT_t i; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + tSmeConfigParams *psmeConfig; + v_BOOL_t MFPCapable = VOS_FALSE; + v_BOOL_t MFPRequired = VOS_FALSE; + v_BOOL_t sapEnable11AC = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC; + u_int16_t prev_rsn_length = 0; + + ENTER(); + + wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx); + iniConfig = pHddCtx->cfg_ini; + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + + pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig; + + pBeacon = pHostapdAdapter->sessionCtx.ap.beacon; + + pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head; + + pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int; + + //channel is already set in the set_channel Call back + //pConfig->channel = pCommitConfig->channel; + + /*Protection parameter to enable or disable*/ + pConfig->protEnabled = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled; + + pConfig->dtim_period = pBeacon->dtim_period; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***", + pConfig->dtim_period); + + if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) + { + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_COUNTRY); + if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0) + { + tANI_BOOLEAN restartNeeded; + pConfig->ieee80211d = 1; + vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3); + sme_setRegInfo(hHal, pConfig->countryCode); + sme_ResetCountryCodeInformation(hHal, &restartNeeded); + } + else if(pIe) + { + tANI_BOOLEAN restartNeeded; + pConfig->ieee80211d = 1; + vos_mem_copy(pConfig->countryCode, &pIe[2], 3); + sme_setRegInfo(hHal, pConfig->countryCode); + sme_ResetCountryCodeInformation(hHal, &restartNeeded); + } + else + { + pConfig->ieee80211d = 0; + } + /* + * If auto channel is configured i.e. channel is 0, + * so skip channel validation. + */ + if( AUTO_CHANNEL_SELECT != pConfig->channel ) + { + if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Channel [%d]", __func__, pConfig->channel); + return -EINVAL; + } + } + else + { + if(1 != pHddCtx->is_dynamic_channel_range_set) + { + hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini; + WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum, + hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand); + } + pHddCtx->is_dynamic_channel_range_set = 0; + } + } + else + { + pConfig->ieee80211d = 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) + pConfig->authType = eSAP_OPEN_SYSTEM; + else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY) + pConfig->authType = eSAP_SHARED_KEY; + else + pConfig->authType = eSAP_AUTO_SWITCH; +#else + if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) + pConfig->authType = eSAP_OPEN_SYSTEM; + else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY) + pConfig->authType = eSAP_SHARED_KEY; + else + pConfig->authType = eSAP_AUTO_SWITCH; +#endif + + capab_info = pMgmt_frame->u.beacon.capab_info; + + pConfig->privacy = (pMgmt_frame->u.beacon.capab_info & + WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE; +#ifdef SAP_AUTH_OFFLOAD + /* In case of sap offload, hostapd.conf is configuted with open mode and + * security is configured from ini file. Due to open mode in hostapd.conf + * privacy bit is set to false which will result in not sending, + * data packets as encrypted. + * If enable_sap_auth_offload is enabled in ini and + * sap_auth_offload_sec_type is type of WPA2-PSK, + * driver will set privacy bit to 1. + */ + if (pHddCtx->cfg_ini->enable_sap_auth_offload && + pHddCtx->cfg_ini->sap_auth_offload_sec_type) + pConfig->privacy = VOS_TRUE; +#endif + + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy; + + /*Set wps station to configured*/ + pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len); + + if(pIe) + { + if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) + { + hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***"); + return -EINVAL; + } + else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0) + { + hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2)); + /* Check 15 bit of WPS IE as it contain information for wps state + * WPS state + */ + if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) + { + pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED; + } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15]) + { + pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED; + } + } + } + else + { + pConfig->wps_state = SAP_WPS_DISABLED; + } + pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up + + pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE; + pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE; + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType = + eCSR_ENCRYPT_TYPE_NONE; + + pConfig->RSNWPAReqIELength = 0; + memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE)); + pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len, + WLAN_EID_RSN); + if(pIe && pIe[1]) + { + pConfig->RSNWPAReqIELength = pIe[1] + 2; + if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE)) + memcpy(&pConfig->RSNWPAReqIE[0], pIe, + pConfig->RSNWPAReqIELength); + else + hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d", + pConfig->RSNWPAReqIELength); + /* The actual processing may eventually be more extensive than + * this. Right now, just consume any PMKIDs that are sent in + * by the app. + * */ + status = hdd_softap_unpackIE( + vos_get_context( VOS_MODULE_ID_SME, pVosContext), + &RSNEncryptType, + &mcRSNEncryptType, + &RSNAuthType, + &MFPCapable, + &MFPRequired, + pConfig->RSNWPAReqIE[1]+2, + pConfig->RSNWPAReqIE); + + if( VOS_STATUS_SUCCESS == status ) + { + /* Now copy over all the security attributes you have + * parsed out + * */ + pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE + pConfig->mcRSNEncryptType = mcRSNEncryptType; + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType + = RSNEncryptType; + hddLog( LOG1, FL("CSR AuthType = %d, " + "EncryptionType = %d mcEncryptionType = %d"), + RSNAuthType, RSNEncryptType, mcRSNEncryptType); + } + } + + pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE, + pBeacon->tail, pBeacon->tail_len); + + if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) + { + if (pConfig->RSNWPAReqIE[0]) + { + /*Mixed mode WPA/WPA2*/ + prev_rsn_length = pConfig->RSNWPAReqIELength; + pConfig->RSNWPAReqIELength += pIe[1] + 2; + if (pConfig->RSNWPAReqIELength <= + (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length)) + memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe, + pIe[1] + 2); + else + hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d", + pConfig->RSNWPAReqIELength); + + } + else + { + pConfig->RSNWPAReqIELength = pIe[1] + 2; + if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE)) + memcpy(&pConfig->RSNWPAReqIE[0], pIe, + pConfig->RSNWPAReqIELength); + else + hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d", + pConfig->RSNWPAReqIELength); + status = hdd_softap_unpackIE( + vos_get_context( VOS_MODULE_ID_SME, pVosContext), + &RSNEncryptType, + &mcRSNEncryptType, + &RSNAuthType, + &MFPCapable, + &MFPRequired, + pConfig->RSNWPAReqIE[1]+2, + pConfig->RSNWPAReqIE); + + if( VOS_STATUS_SUCCESS == status ) + { + /* Now copy over all the security attributes you have + * parsed out + * */ + pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE + pConfig->mcRSNEncryptType = mcRSNEncryptType; + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType + = RSNEncryptType; + hddLog( LOG1, FL("CSR AuthType = %d, " + "EncryptionType = %d mcEncryptionType = %d"), + RSNAuthType, RSNEncryptType, mcRSNEncryptType); + } + } + } + + if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) { + hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***"); + return -EINVAL; + } + + pConfig->SSIDinfo.ssidHidden = VOS_FALSE; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + if (params->ssid != NULL) + { + memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len); + pConfig->SSIDinfo.ssid.length = params->ssid_len; + if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) + pConfig->SSIDinfo.ssidHidden = VOS_TRUE; + } +#else + if (ssid != NULL) + { + memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len); + pConfig->SSIDinfo.ssid.length = ssid_len; + if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) + pConfig->SSIDinfo.ssidHidden = VOS_TRUE; + } +#endif + + vos_mem_copy(pConfig->self_macaddr.bytes, + pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + /* default value */ + pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED; + pConfig->num_accept_mac = 0; + pConfig->num_deny_mac = 0; + + pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE, + pBeacon->tail, pBeacon->tail_len); + + /* pIe for black list is following form: + type : 1 byte + length : 1 byte + OUI : 4 bytes + acl type : 1 byte + no of mac addr in black list: 1 byte + list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id + */ + if ((pIe != NULL) && (pIe[1] != 0)) + { + pConfig->SapMacaddr_acl = pIe[6]; + pConfig->num_deny_mac = pIe[7]; + hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d", + pIe[6], pIe[7]); + if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS) + pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS; + acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); + for (i = 0; i < pConfig->num_deny_mac; i++) + { + vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr)); + acl_entry++; + } + } + pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE, + pBeacon->tail, pBeacon->tail_len); + + /* pIe for white list is following form: + type : 1 byte + length : 1 byte + OUI : 4 bytes + acl type : 1 byte + no of mac addr in white list: 1 byte + list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id + */ + if ((pIe != NULL) && (pIe[1] != 0)) + { + pConfig->SapMacaddr_acl = pIe[6]; + pConfig->num_accept_mac = pIe[7]; + hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d", + pIe[6], pIe[7]); + if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS) + pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS; + acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); + for (i = 0; i < pConfig->num_accept_mac; i++) + { + vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr)); + acl_entry++; + } + } + + wlan_hdd_set_sapHwmode(pHostapdAdapter); + +#ifdef WLAN_FEATURE_11AC + /* Overwrite the hostapd setting for HW mode only for 11ac. + * This is valid only if mode is set to 11n in hostapd, sapEnable11AC + * is set in .ini and 11ac is supported by both host and firmware. + * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) + */ + if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) || + (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) && + (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) && + (sme_IsFeatureSupportedByFW(DOT11AC)) ) + { + v_U32_t operatingBand = 0; + pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac; + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + + /* If ACS disable and selected channel <= 14 + * OR + * ACS enabled and ACS operating band is choosen as 2.4 + * AND + * VHT in 2.4G Disabled + * THEN + * Fallback to 11N mode + */ + if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END) + || (AUTO_CHANNEL_SELECT == pConfig->channel && + operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) && + iniConfig->enableVhtFor24GHzBand == FALSE) + { + hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"), + operatingBand, pConfig->channel); + pConfig->SapHw_mode = eSAP_DOT11_MODE_11n; + } + } +#endif + + // ht_capab is not what the name conveys,this is used for protection bitmap + pConfig->ht_capab = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection; + + if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter)) + { + hddLog(LOGE, FL("SAP Not able to set AP IEs")); + return -EINVAL; + } + + //Uapsd Enabled Bit + pConfig->UapsdEnable = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled; + //Enable OBSS protection + pConfig->obssProtEnabled = + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled; + +#ifdef WLAN_FEATURE_11W + pConfig->mfpCapable = MFPCapable; + pConfig->mfpRequired = MFPRequired; + hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"), + pConfig->mfpCapable, pConfig->mfpRequired); +#endif + + hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes)); + hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"), + pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int, + (int)pConfig->channel); + hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"), + pConfig->SapHw_mode, pConfig->privacy, + pConfig->authType); + hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"), + (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable); + hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"), + pConfig->protEnabled, pConfig->obssProtEnabled); + + if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) + { + //Bss already started. just return. + //TODO Probably it should update some beacon params. + hddLog( LOGE, "Bss Already started...Ignore the request"); + EXIT(); + return 0; + } + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections")); + return -EINVAL; + } + + pConfig->persona = pHostapdAdapter->device_mode; + + psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams)); + if ( NULL != psmeConfig) + { + vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams)); + sme_GetConfigParam(hHal, psmeConfig); + pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference; +#ifdef WLAN_FEATURE_AP_HT40_24G + if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)) + && pHddCtx->cfg_ini->apHT40_24GEnabled) + { + psmeConfig->csrConfig.apHT40_24GEnabled = 1; + sme_UpdateConfig (hHal, psmeConfig); + } +#endif + vos_mem_free(psmeConfig); + } + pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold; + + set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags); + + pSapEventCallback = hdd_hostapd_SAPEventCB; + if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig, + (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS) + { + hddLog(LOGE,FL("SAP Start Bss fail")); + ret = -EINVAL; + goto error; + } + + hddLog(LOG1, + FL("Waiting for Scan to complete(auto mode) and BSS to start")); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: HDD vos wait for single_event failed!!")); + smeGetCommandQStatus(hHal); + VOS_ASSERT(0); + } + + set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags); + if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) != + VOS_STATUS_SUCCESS) + { + hddLog(LOGE,FL("Fail to get Softap sessionID")); + VOS_ASSERT(0); + } + /* Initialize WMM configuation */ + hdd_wmm_init(pHostapdAdapter); + wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode); + +#ifdef DHCP_SERVER_OFFLOAD + /* set dhcp server offload */ + if (iniConfig->enable_dhcp_srv_offload && + sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) { + vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event); + status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("HDD DHCP Server Offload Failed!!")); + vos_event_reset(&pHostapdState->vosEvent); + if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) { + status = vos_wait_single_event(&pHostapdState->vosEvent, + 10000); + if (!VOS_IS_STATUS_SUCCESS(status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + ret = -EINVAL; + goto error; + } + } + } + status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000); + if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: DHCP HDD vos wait for single_event failed!! %d"), + pHostapdAdapter->dhcp_status.dhcp_offload_status); + vos_event_reset(&pHostapdState->vosEvent); + if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) { + status = vos_wait_single_event(&pHostapdState->vosEvent, + 10000); + if (!VOS_IS_STATUS_SUCCESS(status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + ret = -EINVAL; + goto error; + } + } + } +#ifdef MDNS_OFFLOAD + if (iniConfig->enable_mdns_offload) { + vos_event_reset(&pHostapdAdapter->mdns_status.vos_event); + status = wlan_hdd_set_mdns_offload(pHostapdAdapter); + if (VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("HDD MDNS Server Offload Failed!!")); + vos_event_reset(&pHostapdState->vosEvent); + if (VOS_STATUS_SUCCESS == + WLANSAP_StopBss(pHddCtx->pvosContext)) { + status = vos_wait_single_event(&pHostapdState->vosEvent, + 10000); + if (!VOS_IS_STATUS_SUCCESS(status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + ret = -EINVAL; + goto error; + } + } + } + status = vos_wait_single_event(&pHostapdAdapter-> + mdns_status.vos_event, 2000); + if (!VOS_IS_STATUS_SUCCESS(status) || + pHostapdAdapter->mdns_status.mdns_enable_status || + pHostapdAdapter->mdns_status.mdns_fqdn_status || + pHostapdAdapter->mdns_status.mdns_resp_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"), + pHostapdAdapter->mdns_status.mdns_enable_status, + pHostapdAdapter->mdns_status.mdns_fqdn_status, + pHostapdAdapter->mdns_status.mdns_resp_status); + vos_event_reset(&pHostapdState->vosEvent); + if (VOS_STATUS_SUCCESS == + WLANSAP_StopBss(pHddCtx->pvosContext)) { + status = vos_wait_single_event(&pHostapdState->vosEvent, + 10000); + if (!VOS_IS_STATUS_SUCCESS(status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + ret = -EINVAL; + goto error; + } + } + } + } +#endif /* MDNS_OFFLOAD */ + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("DHCP Disabled ini %d, FW %d"), + iniConfig->enable_dhcp_srv_offload, + sme_IsFeatureSupportedByFW(SAP_OFFLOADS)); + } +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef WLAN_FEATURE_P2P_DEBUG + if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) + { + if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) + { + globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE; + hddLog(LOGE,"[P2P State] From Go nego completed to " + "Non-autonomous Group started"); + } + else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE) + { + globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE; + hddLog(LOGE,"[P2P State] From Inactive to " + "Autonomous Group started"); + } + } +#endif + /* Check and restart SAP if it is on Unsafe channel */ + hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx); + + pHostapdState->bCommit = TRUE; + EXIT(); + + return 0; +error: + clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags); + return ret; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_ADD_BEACON, + pAdapter->sessionId, params->interval)); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)", + hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections")); + return -EINVAL; + } + + if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + beacon_data_t *old,*new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (old) + { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("already beacon info added to session(%d)"), + pAdapter->sessionId); + return -EALREADY; + } + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s:Error!!! Allocating the new beacon",__func__); + return -EINVAL; + } + + pAdapter->sessionCtx.ap.beacon = new; + + status = wlan_hdd_cfg80211_start_bss(pAdapter, params); + } + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_BEACON, + pAdapter->sessionId, pHddStaCtx->conn_info.authType)); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + beacon_data_t *old,*new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (!old) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("session(%d) old and new heads points to NULL"), + pAdapter->sessionId); + return -ENOENT; + } + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params); + + if(status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Error!!! Allocating the new beacon",__func__); + return -EINVAL; + } + + pAdapter->sessionCtx.ap.beacon = new; + + status = wlan_hdd_cfg80211_start_bss(pAdapter, params); + } + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy, + struct net_device *dev) +#else +static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy, + struct net_device *dev) +#endif +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = NULL; + hdd_scaninfo_t *pScanInfo = NULL; + VOS_STATUS status; + long ret; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter context is Null", __func__); + return -ENODEV; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_STOP_AP, + pAdapter->sessionId, pAdapter->device_mode)); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pScanInfo = &pHddCtx->scan_info; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + ret = wlan_hdd_scan_abort(pAdapter); + + if (ret < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Timeout occurred while waiting for abortscan %ld"), ret); + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + + VOS_ASSERT(pScanInfo->mScanPending); + return -EAGAIN; + } + VOS_ASSERT(pScanInfo->mScanPending); + } + + /* Delete all associated STAs before stopping AP/P2P GO */ + hdd_del_all_sta(pAdapter); + hdd_hostapd_stop(dev); + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + beacon_data_t *old; + + old = pAdapter->sessionCtx.ap.beacon; + + if (!old) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("session(%d) beacon data points to NULL"), + pAdapter->sessionId); + return -ENOENT; + } + + hdd_cleanup_actionframe(pHddCtx, pAdapter); + + mutex_lock(&pHddCtx->sap_lock); + if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + { + if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) ) + { + hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: HDD vos wait for single_event failed!!")); + VOS_ASSERT(0); + } + } + clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags); + /* BSS stopped, clear the active sessions for this device mode */ + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + } + mutex_unlock(&pHddCtx->sap_lock); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s:Error!!! Stopping the BSS",__func__); + return -EINVAL; + } + + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE) + ==eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM"); + } + + if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + } + + // Reset WNI_CFG_PROBE_RSP Flags + wlan_hdd_reset_prob_rspies(pAdapter); + + clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags); + + pAdapter->sessionCtx.ap.beacon = NULL; + kfree(old); +#ifdef WLAN_FEATURE_P2P_DEBUG + if((pAdapter->device_mode == WLAN_HDD_P2P_GO) && + (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE)) + { + hddLog(LOGE,"[P2P State] From GO completed to Inactive state " + "GO got removed"); + globalP2PConnectionStatus = P2P_NOT_ACTIVE; + } +#endif + } + EXIT(); + return status; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) +static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#else +static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0)) + +static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *params) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + if (NULL == dev || NULL == params) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Device or params is Null", __func__); + return -ENODEV; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId, + params-> beacon_interval)); + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter magic is invalid", __func__); + return -ENODEV; + } + + clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + beacon_data_t *old, *new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (old) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("already beacon info added to session(%d)"), + pAdapter->sessionId); + return -EALREADY; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, + &new, + ¶ms->beacon); +#else + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, + &new, + ¶ms->beacon, + params->dtim_period); +#endif + + if (status != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s:Error!!! Allocating the new beacon", __func__); + return -EINVAL; + } + pAdapter->sessionCtx.ap.beacon = new; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wlan_hdd_cfg80211_set_channel(wiphy, dev, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + params->channel, params->channel_type); +#else + params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef))); +#endif +#endif + status = wlan_hdd_cfg80211_start_bss(pAdapter, ¶ms->beacon, params->ssid, + params->ssid_len, params->hidden_ssid, + params->auth_type); + } + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ap_settings *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CHANGE_BEACON, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__, pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + beacon_data_t *old,*new; + + old = pAdapter->sessionCtx.ap.beacon; + + if (!old) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("session(%d) beacon data points to NULL"), + pAdapter->sessionId); + return -ENOENT; + } + + status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0); + + if(status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Error!!! Allocating the new beacon",__func__); + return -EINVAL; + } + + pAdapter->sessionCtx.ap.beacon = new; + + status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0, + pAdapter->sessionCtx.ap.sapConfig.authType); + } + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_beacon_data *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0)) + +static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CHANGE_BSS, + pAdapter->sessionId, params->ap_isolate)); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + if((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + /* ap_isolate == -1 means that in change bss, upper layer doesn't + * want to update this parameter */ + if (-1 != params->ap_isolate) + { + pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate; + } + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy, + struct net_device *dev, + struct bss_parameters *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} +/* FUNCTION: wlan_hdd_change_country_code_cd +* to wait for contry code completion +*/ +void* wlan_hdd_change_country_code_cb(void *pAdapter) +{ + hdd_adapter_t *call_back_pAdapter = pAdapter; + complete(&call_back_pAdapter->change_country_code); + return NULL; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_change_iface + * This function is used to set the interface type (INFRASTRUCTURE/ADHOC) + */ +int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params + ) +{ + struct wireless_dev *wdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + hdd_context_t *pHddCtx; + hdd_adapter_t *pP2pAdapter = NULL; + tCsrRoamProfile *pRoamProfile = NULL; + eCsrRoamBssType LastBSSType; + hdd_config_t *pConfig = NULL; + eMib_dot11DesiredBssType connectedBssType; + VOS_STATUS status; + long ret; + + ENTER(); + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter context is null", __func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return VOS_STATUS_E_FAILURE; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CHANGE_IFACE, + pAdapter->sessionId, type)); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections")); + return -EINVAL; + } + pConfig = pHddCtx->cfg_ini; + wdev = ndev->ieee80211_ptr; + +#ifdef WLAN_BTAMP_FEATURE + if((NL80211_IFTYPE_P2P_CLIENT == type)|| + (NL80211_IFTYPE_ADHOC == type)|| + (NL80211_IFTYPE_AP == type)|| + (NL80211_IFTYPE_P2P_GO == type)) + { + pHddCtx->isAmpAllowed = VOS_FALSE; + // stop AMP traffic + status = WLANBAP_StopAmp(); + if(VOS_STATUS_SUCCESS != status ) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop AMP", __func__); + return -EINVAL; + } + } +#endif //WLAN_BTAMP_FEATURE + /* Reset the current device mode bit mask*/ + wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode); + + if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) && + ((type == NL80211_IFTYPE_P2P_CLIENT) || + (type == NL80211_IFTYPE_P2P_GO))) + { + /* Notify Mode change in case of concurrency. + * Below function invokes TDLS teardown Functionality Since TDLS is + * not Supported in case of concurrency i.e Once P2P session + * is detected disable offchannel and teardown TDLS links + */ + hddLog(LOG1, + FL("Device mode = %d Interface type = %d"), + pAdapter->device_mode, type); + hdd_tdls_notify_mode_change(pAdapter, pHddCtx); + } + + if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) + ) + { + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (!pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is null", __func__); + return VOS_STATUS_E_FAILURE; + } + pRoamProfile = &pWextState->roamProfile; + LastBSSType = pRoamProfile->BSSType; + + switch (type) + { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: setting interface Type to INFRASTRUCTURE", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; +#ifdef WLAN_FEATURE_11AC + if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO) + { + pConfig->dot11Mode = eHDD_DOT11_MODE_11ac; + } +#endif + pRoamProfile->phyMode = + hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode); + wdev->iftype = type; + //Check for sub-string p2p to confirm its a p2p interface + if (NULL != strstr(ndev->name,"p2p")) + { +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_exit(pAdapter, TRUE); + mutex_unlock(&pHddCtx->tdls_lock); +#endif + pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ? + WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT; + } + else + { + pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ? + WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT; + } + break; + + case NL80211_IFTYPE_ADHOC: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: setting interface Type to ADHOC", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS; + pRoamProfile->phyMode = + hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode); + pAdapter->device_mode = WLAN_HDD_IBSS; + wdev->iftype = type; + hdd_set_ibss_ops( pAdapter ); + hdd_ibss_init_tx_rx( pAdapter ); + + status = hdd_sta_id_hash_attach(pAdapter); + if (VOS_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to initialize hash for IBSS")); + } + break; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: setting interface Type to %s", __func__, + (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo"); + + //Cancel any remain on channel for GO mode + if (NL80211_IFTYPE_P2P_GO == type) + { + wlan_hdd_cancel_existing_remain_on_channel(pAdapter); + } + if (NL80211_IFTYPE_AP == type) + { + /* As Loading WLAN Driver one interface being created for p2p device + * address. This will take one HW STA and the max number of clients + * that can connect to softAP will be reduced by one. so while changing + * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 + * interface as it is not required in SoftAP mode. + */ + + // Get P2P Adapter + pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE); + + if (pP2pAdapter) + { + hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE); + hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE); + hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE); + } + } + //Disable IMPS & BMPS for SAP/GO + if(VOS_STATUS_E_FAILURE == + hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO)) + { + //Fail to Exit BMPS + VOS_ASSERT(0); + } + + hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE ); + +#ifdef FEATURE_WLAN_TDLS + + /* A Mutex Lock is introduced while changing the mode to + * protect the concurrent access for the Adapters by TDLS + * module. + */ + mutex_lock(&pHddCtx->tdls_lock); +#endif + //De-init the adapter. + hdd_deinit_adapter( pHddCtx, pAdapter, TRUE); + memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx)); + pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ? + WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO; +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) && + (pConfig->apRandomBssidEnabled)) + { + /* To meet Android requirements create a randomized + MAC address of the form 02:1A:11:Fx:xx:xx */ + get_random_bytes(&ndev->dev_addr[3], 3); + ndev->dev_addr[0] = 0x02; + ndev->dev_addr[1] = 0x1A; + ndev->dev_addr[2] = 0x11; + ndev->dev_addr[3] |= 0xF0; + memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr, + VOS_MAC_ADDR_SIZE); + pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n", + MAC_ADDR_ARRAY(ndev->dev_addr)); + } + + hdd_set_ap_ops( pAdapter->dev ); + + /* This is for only SAP mode where users can + * control country through ini. + * P2P GO follows station country code + * acquired during the STA scanning. */ + if((NL80211_IFTYPE_AP == type) && + (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)) + { + int status = 0; + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO, + "%s: setting country code from INI ", __func__); + init_completion(&pAdapter->change_country_code); + status = (int)sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + wlan_hdd_change_country_code_cb, + pConfig->apCntryCode, pAdapter, + pHddCtx->pvosContext, + eSIR_FALSE, + eSIR_TRUE); + if (eHAL_STATUS_SUCCESS == status) + { + /* Wait for completion */ + ret = wait_for_completion_interruptible_timeout( + &pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + if (ret <= 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("SME Timed out while setting country code %ld"), + ret); + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SME Change Country code failed",__func__); + return -EINVAL; + } + } + status = hdd_init_ap_mode(pAdapter, false); + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Error initializing the ap mode", __func__); + return -EINVAL; + } + hdd_set_conparam(1); + + status = hdd_sta_id_hash_attach(pAdapter); + if (VOS_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to initialize hash for AP")); + return -EINVAL; + } + + /*interface type changed update in wiphy structure*/ + if(wdev) + { + wdev->iftype = type; + pHddCtx->change_iface = type; + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ERROR !!!! Wireless dev is NULL", __func__); + return -EINVAL; + } + goto done; + } + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type", + __func__); + return -EOPNOTSUPP; + } + } + else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + switch(type) + { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_ADHOC: + + hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE ); +#ifdef FEATURE_WLAN_TDLS + + /* A Mutex Lock is introduced while changing the mode to + * protect the concurrent access for the Adapters by TDLS + * module. + */ + mutex_lock(&pHddCtx->tdls_lock); +#endif + hdd_deinit_adapter( pHddCtx, pAdapter, TRUE); + wdev->iftype = type; + //Check for sub-string p2p to confirm its a p2p interface + if (NULL != strstr(ndev->name,"p2p")) + { + pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ? + WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT; + } + else + { + pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ? + WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT; + } + + /* set con_mode to STA only when no SAP concurrency mode */ + if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO))) + hdd_set_conparam(0); + pHddCtx->change_iface = type; + memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx)); + hdd_set_station_ops( pAdapter->dev ); +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + status = hdd_init_station_mode( pAdapter ); + if( VOS_STATUS_SUCCESS != status ) + return -EOPNOTSUPP; + /* In case of JB, for P2P-GO, only change interface will be called, + * This is the right place to enable back bmps_imps() + */ + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + goto done; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + wdev->iftype = type; + pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ? + WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO; + goto done; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type", + __func__); + return -EOPNOTSUPP; + + } + + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + return -EOPNOTSUPP; + } + + + if(pRoamProfile) + { + if ( LastBSSType != pRoamProfile->BSSType ) + { + /*interface type changed update in wiphy structure*/ + wdev->iftype = type; + + /*the BSS mode changed, We need to issue disconnect + if connected or in IBSS disconnect state*/ + if ( hdd_connGetConnectedBssType( + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) || + ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) ) + { + /*need to issue a disconnect to CSR.*/ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + if( eHAL_STATUS_SUCCESS == + sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED ) ) + { + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on disconnect_comp_var failed %ld"), ret); + } + } + } + } + } + +done: + /*set bitmask based on updated value*/ + wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode); + + /* Only STA mode support TM now + * all other mode, TM feature should be disabled */ + if ( (pHddCtx->cfg_ini->thermalMitigationEnable) && + (~VOS_STA & pHddCtx->concurrency_mode) ) + { + hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0); + } + +#ifdef WLAN_BTAMP_FEATURE + if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) && + (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1)) + { + //we are ok to do AMP + pHddCtx->isAmpAllowed = VOS_TRUE; + } +#endif //WLAN_BTAMP_FEATURE + EXIT(); + return 0; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_change_iface + * wrapper function to protect the actual implementation from SSR. + */ +int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params + ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef FEATURE_WLAN_TDLS +static int wlan_hdd_tdls_add_station(struct wiphy *wiphy, + struct net_device *dev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + bool update, tCsrStaParams *StaParams) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hddTdlsPeer_t *pTdlsPeer; + long ret; + tANI_U16 numCurrTdlsPeers; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + ENTER(); + + if (!dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL")); + return -EINVAL; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL")); + return -EINVAL; + } + + if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid arguments"); + return -EINVAL; + } + + if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) || + (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS mode is disabled OR not enabled in FW." + MAC_ADDRESS_STR " Request declined.", + __func__, MAC_ADDR_ARRAY(mac)); + return -ENOTSUPP; + } + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + wlan_hdd_tdls_set_link_status(pAdapter, + mac, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + return -EBUSY; + } + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac); + + if ( NULL == pTdlsPeer ) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid", + __func__, MAC_ADDR_ARRAY(mac), update); + mutex_unlock(&pHddCtx->tdls_lock); + return -EINVAL; + } + + /* in add station, we accept existing valid staId if there is */ + if ((0 == update) && + ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) || + (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR + " link_status %d. staId %d. add station ignored.", + __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId); + mutex_unlock(&pHddCtx->tdls_lock); + return 0; + } + /* in change station, we accept only when staId is valid */ + if ((1 == update) && + ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) || + (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId)))) + { + tANI_U16 staId = pTdlsPeer->staId; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " link status %d. staId %d. change station %s.", + __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId, + (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined"); + mutex_unlock(&pHddCtx->tdls_lock); + return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM; + } + mutex_unlock(&pHddCtx->tdls_lock); + + /* when others are on-going, we want to change link_status to idle */ + if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS setup is ongoing. Request declined.", + __func__, MAC_ADDR_ARRAY(mac)); + goto error; + } + + /* first to check if we reached to maximum supported TDLS peer. + TODO: for now, return -EPERM looks working fine, + but need to check if any other errno fit into this category.*/ + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS Max peer already connected. Request declined." + " Num of peers (%d), Max allowed (%d).", + __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers, + HDD_MAX_NUM_TDLS_STA); + goto error; + } + else + { + hddTdlsPeer_t *pTdlsPeer; + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer)) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " already connected. Request declined.", + __func__, MAC_ADDR_ARRAY(mac)); + return -EPERM; + } + mutex_unlock(&pHddCtx->tdls_lock); + } + if (0 == update) + wlan_hdd_tdls_set_link_status(pAdapter, + mac, + eTDLS_LINK_CONNECTING, + eTDLS_LINK_SUCCESS); + + /* debug code */ + if (NULL != StaParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS Peer Parameters.", __func__); + if(StaParams->htcap_present) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "ht_capa->extended_capabilities: %0x", + StaParams->HTCap.extendedHtCapInfo); + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "params->capability: %0x",StaParams->capability); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "params->ext_capab_len: %0x",StaParams->extn_capability[0]); + if(StaParams->vhtcap_present) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x", + StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest, + StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest); + } + { + int i = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:"); + for (i = 0; i < sizeof(StaParams->supported_rates); i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "[%d]: %x ", i, StaParams->supported_rates[i]); + } + } /* end debug code */ + else if ((1 == update) && (NULL == StaParams)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : update is true, but staParams is NULL. Error!", __func__); + return -EPERM; + } + + INIT_COMPLETION(pAdapter->tdls_add_station_comp); + + if (!update) + { + /*Before adding sta make sure that device exited from BMPS*/ + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Adding tdls peer sta. Disable BMPS", __func__); + status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS")); + } + } + + ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, mac); + if (ret != eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to add TDLS peer STA. Enable Bmps")); + wlan_hdd_tdls_check_bmps(pAdapter); + return -EPERM; + } + } + else + { + ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, mac, StaParams); + if (ret != eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params")); + return -EPERM; + } + } + + ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA)); + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + + if ((pTdlsPeer != NULL) && + (pTdlsPeer->link_status == eTDLS_LINK_TEARING)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("peer link status %u"), pTdlsPeer->link_status); + mutex_unlock(&pHddCtx->tdls_lock); + goto error; + } + mutex_unlock(&pHddCtx->tdls_lock); + + if (ret <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: timeout waiting for tdls add station indication %ld", + __func__, ret); + goto error; + } + + if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Add Station is unsucessful", __func__); + return -EPERM; + } + + return 0; + +error: + wlan_hdd_tdls_set_link_status(pAdapter, + mac, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + return -EPERM; + +} +#endif + +static int __wlan_hdd_change_station(struct wiphy *wiphy, + struct net_device *dev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + struct station_parameters *params) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + v_MACADDR_t STAMacAddress; + int ret = 0; +#ifdef FEATURE_WLAN_TDLS + tCsrStaParams StaParams = {0}; + tANI_U8 isBufSta = 0; + tANI_U8 isOffChannelSupported = 0; + tANI_U8 isQosWmmSta = FALSE; +#endif + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if ((NULL == pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter "); + return -EINVAL; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CHANGE_STATION, + pAdapter->sessionId, params->listen_interval)); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid HDD station context"); + return -EINVAL; + } + vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t)); + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO)) + { + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) + { + status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress, + WLANTL_STA_AUTHENTICATED); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Not able to change TL state to AUTHENTICATED", __func__); + return -EINVAL; + } + } + } + else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) { +#ifdef FEATURE_WLAN_TDLS + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + StaParams.capability = params->capability; + StaParams.uapsd_queues = params->uapsd_queues; + StaParams.max_sp = params->max_sp; + + /* Convert (first channel , number of channels) tuple to + * the total list of channels. This goes with the assumption + * that if the first channel is < 14, then the next channels + * are an incremental of 1 else an incremental of 4 till the number + * of channels. + */ + if (0 != params->supported_channels_len) { + int i = 0,j = 0,k = 0, no_of_channels = 0 ; + for ( i = 0 ; i < params->supported_channels_len ; i+=2) + { + int wifi_chan_index; + StaParams.supported_channels[j] = params->supported_channels[i]; + wifi_chan_index = + ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 ); + no_of_channels = params->supported_channels[i+1]; + for(k=1; k <= no_of_channels; k++) + { + StaParams.supported_channels[j+1] = + StaParams.supported_channels[j] + wifi_chan_index; + j+=1; + } + } + StaParams.supported_channels_len = j; + } + if (params->supported_oper_classes_len > + SIR_MAC_MAX_SUPP_OPER_CLASSES) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "received oper classes:%d, resetting it to max supported %d", + params->supported_oper_classes_len, + SIR_MAC_MAX_SUPP_OPER_CLASSES); + params->supported_oper_classes_len = + SIR_MAC_MAX_SUPP_OPER_CLASSES; + } + vos_mem_copy(StaParams.supported_oper_classes, + params->supported_oper_classes, + params->supported_oper_classes_len); + StaParams.supported_oper_classes_len = + params->supported_oper_classes_len; + + if (params->ext_capab_len > sizeof(StaParams.extn_capability)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "received extn capabilities:%d, resetting it to max supported", + params->ext_capab_len); + params->ext_capab_len = sizeof(StaParams.extn_capability); + } + if (0 != params->ext_capab_len) + vos_mem_copy(StaParams.extn_capability, params->ext_capab, + params->ext_capab_len); + + if (NULL != params->ht_capa) + { + StaParams.htcap_present = 1; + vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap)); + } + + StaParams.supported_rates_len = params->supported_rates_len; + + /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32. + * The supported_rates array , for all the structures propogating till Add Sta + * to the firmware has to be modified , if the supplicant (ieee80211) is + * modified to send more rates. + */ + + /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES + */ + if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES) + StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES; + + if (0 != StaParams.supported_rates_len) { + int i = 0; + vos_mem_copy(StaParams.supported_rates, params->supported_rates, + StaParams.supported_rates_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Supported Rates with Length %d", StaParams.supported_rates_len); + for (i=0; i < StaParams.supported_rates_len; i++) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "[%d]: %0x", i, StaParams.supported_rates[i]); + } + + if (NULL != params->vht_capa) + { + StaParams.vhtcap_present = 1; + vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap)); + } + + if (0 != params->ext_capab_len ) { + /*Define A Macro : TODO Sunil*/ + if ((1<<4) & StaParams.extn_capability[3]) { + isBufSta = 1; + } + /* TDLS Channel Switching Support */ + if ((1<<6) & StaParams.extn_capability[3]) { + isOffChannelSupported = 1; + } + } + + if (pHddCtx->cfg_ini->fEnableTDLSWmmMode && + (params->ht_capa || params->vht_capa || + (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)))) + /* TDLS Peer is WME/QoS capable */ + isQosWmmSta = TRUE; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d", + __func__, isQosWmmSta, StaParams.htcap_present); + + status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, + &StaParams, isBufSta, + isOffChannelSupported, + isQosWmmSta); + + if (VOS_STATUS_SUCCESS != status) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__); + return -EINVAL; + } + status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams); + + if (VOS_STATUS_SUCCESS != status) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_ChangeTdlsPeerSta failed!", __func__); + return -EINVAL; + } + } +#endif + } + EXIT(); + return status; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) +static int wlan_hdd_change_station(struct wiphy *wiphy, + struct net_device *dev, + const u8 *mac, + struct station_parameters *params) +#else +static int wlan_hdd_change_station(struct wiphy *wiphy, + struct net_device *dev, + u8 *mac, + struct station_parameters *params) +#endif +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_change_station(wiphy, dev, mac, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_add_key + * This function is used to initialize the key information + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, + struct key_params *params + ) +#else +static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, const u8 *mac_addr, + struct key_params *params + ) +#endif +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + tCsrRoamSetKey setKey; + u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + int status; + v_U32_t roamId= 0xFF; + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + hdd_hostapd_state_t *pHostapdState; + VOS_STATUS vos_status; + eHalStatus halStatus; + hdd_context_t *pHddCtx; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_ADD_KEY, + pAdapter->sessionId, params->key_len)); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + if (CSR_MAX_NUM_KEY <= key_index) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__, + key_index); + + return -EINVAL; + } + + if (CSR_MAX_KEY_LEN < params->key_len) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__, + params->key_len); + + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: called with key index = %d & key length %d", + __func__, key_index, params->key_len); + + /*extract key idx, key len and key*/ + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; + setKey.keyLength = params->key_len; + vos_mem_copy(&setKey.Key[0],params->key, params->key_len); + + switch (params->cipher) + { + case WLAN_CIPHER_SUITE_WEP40: + setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + break; + + case WLAN_CIPHER_SUITE_WEP104: + setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + break; + + case WLAN_CIPHER_SUITE_TKIP: + { + u8 *pKey = &setKey.Key[0]; + setKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + + vos_mem_zero(pKey, CSR_MAX_KEY_LEN); + + /*Supplicant sends the 32bytes key in this order + + |--------------|----------|----------| + | Tk1 |TX-MIC | RX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + + */ + /*Sme expects the 32 bytes key to be in the below order + + |--------------|----------|----------| + | Tk1 |RX-MIC | TX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + */ + /* Copy the Temporal Key 1 (TK1) */ + vos_mem_copy(pKey, params->key, 16); + + /*Copy the rx mic first*/ + vos_mem_copy(&pKey[16], ¶ms->key[24], 8); + + /*Copy the tx mic */ + vos_mem_copy(&pKey[24], ¶ms->key[16], 8); + + + break; + } + + case WLAN_CIPHER_SUITE_CCMP: + setKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + +#ifdef FEATURE_WLAN_WAPI + case WLAN_CIPHER_SUITE_SMS4: + { + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr, + params->key, params->key_len); + return 0; + } +#endif + +#ifdef FEATURE_WLAN_ESE + case WLAN_CIPHER_SUITE_KRK: + setKey.encType = eCSR_ENCRYPT_TYPE_KRK; + break; +#endif + +#ifdef WLAN_FEATURE_11W + case WLAN_CIPHER_SUITE_AES_CMAC: + setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC; + break; +#endif + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u", + __func__, params->cipher); + status = -EOPNOTSUPP; + goto end; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d", + __func__, setKey.encType); + + if ( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + (!pairwise) +#else + (!mac_addr || is_broadcast_ether_addr(mac_addr)) +#endif + ) + { + /* set group key*/ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s- %d: setting Broadcast key", + __func__, __LINE__); + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN); + } + else + { + /* set pairwise key*/ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s- %d: setting pairwise key", + __func__, __LINE__); + setKey.keyDirection = eSIR_TX_RX; + vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN); + } + if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise) + { + setKey.keyDirection = eSIR_TX_RX; + /*Set the group key*/ + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", __func__, status); + status = -EINVAL; + goto end; + } + /*Save the keys here and call sme_RoamSetKey for setting + the PTK after peer joins the IBSS network*/ + vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key, + &setKey, sizeof(tCsrRoamSetKey)); + goto end; + } + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) || + (pAdapter->device_mode == WLAN_HDD_P2P_GO)) + { + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if( pHostapdState->bssState == BSS_START ) + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + vos_status = wlan_hdd_check_ula_done(pAdapter); + + if ( vos_status != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d", + __LINE__, vos_status ); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + + status = -EINVAL; + goto end; + } + + status = WLANSAP_SetKeySta( pVosContext, &setKey); + + if ( status != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", + __LINE__, status ); + status = -EINVAL; + goto end; + } + } + + /* Saving WEP keys */ + else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType || + eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType ) + { + //Save the wep key in ap context. Issue setkey after the BSS is started. + hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey)); + } + else + { + //Save the key in ap context. Issue setkey after the BSS is started. + hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey)); + } + } + else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) ) + { + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + if (!pairwise) +#else + if (!mac_addr || is_broadcast_ether_addr(mac_addr)) +#endif + { + /* set group key*/ + if (pHddStaCtx->roam_info.deferKeyComplete) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s- %d: Perform Set key Complete", + __func__, __LINE__); + hdd_PerformRoamSetKeyComplete(pAdapter); + } + } + + pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len; + + pWextState->roamProfile.Keys.defaultIndex = key_index; + + + vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0], + params->key, params->key_len); + + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d", + __func__, setKey.peerMac[0], setKey.peerMac[1], + setKey.peerMac[2], setKey.peerMac[3], + setKey.peerMac[4], setKey.peerMac[5], + setKey.keyDirection); + + vos_status = wlan_hdd_check_ula_done(pAdapter); + + if ( vos_status != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d", + __LINE__, vos_status ); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + + status = -EINVAL; + goto end; + + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* The supplicant may attempt to set the PTK once pre-authentication + is done. Save the key in the UMAC and include it in the ADD BSS + request */ + halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey); + if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: Update PreAuth Key success", __func__); + status = 0; + goto end; + } + else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Update PreAuth Key failed", __func__); + status = -EINVAL; + goto end; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + /* issue set key request to SME*/ + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", __func__, status); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + status = -EINVAL; + goto end; + } + + + /* in case of IBSS as there was no information available about WEP keys during + * IBSS join, group key intialized with NULL key, so re-initialize group key + * with correct value*/ + if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) && + !( ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)) + && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) + ) + && + ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher) + || (WLAN_CIPHER_SUITE_WEP104 == params->cipher) + ) + ) + { + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN); + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d", + __func__, setKey.peerMac[0], setKey.peerMac[1], + setKey.peerMac[2], setKey.peerMac[3], + setKey.peerMac[4], setKey.peerMac[5], + setKey.keyDirection); + + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed for group key (IBSS), returned %d", + __func__, status); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + status = -EINVAL; + goto end; + } + } + } + +end: + /* Need to clear any trace of key value in the memory. + * Thus zero out the memory even though it is local + * variable. + */ + vos_mem_zero(&setKey, sizeof(setKey)); + EXIT(); + return status; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, bool pairwise, + const u8 *mac_addr, + struct key_params *params + ) +#else +static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, const u8 *mac_addr, + struct key_params *params + ) +#endif +{ + int ret; + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise, + mac_addr, params); +#else + ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr, + params); +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_get_key + * This function is used to get the key information + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int __wlan_hdd_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*) + ) +#else +static int __wlan_hdd_cfg80211_get_key( + struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params*) + ) +#endif +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + hdd_wext_state_t *pWextState = NULL; + tCsrRoamProfile *pRoamProfile = NULL; + struct key_params params; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pRoamProfile = &(pWextState->roamProfile); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + memset(¶ms, 0, sizeof(params)); + + if (CSR_MAX_NUM_KEY <= key_index) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index); + return -EINVAL; + } + + switch(pRoamProfile->EncryptionType.encryptionType[0]) + { + case eCSR_ENCRYPT_TYPE_NONE: + params.cipher = IW_AUTH_CIPHER_NONE; + break; + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + params.cipher = WLAN_CIPHER_SUITE_WEP40; + break; + + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + params.cipher = WLAN_CIPHER_SUITE_WEP104; + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + params.cipher = WLAN_CIPHER_SUITE_TKIP; + break; + + case eCSR_ENCRYPT_TYPE_AES: + params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; + break; + + default: + params.cipher = IW_AUTH_CIPHER_NONE; + break; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_GET_KEY, + pAdapter->sessionId, params.cipher)); + + params.key_len = pRoamProfile->Keys.KeyLength[key_index]; + params.seq_len = 0; + params.seq = NULL; + params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0]; + callback(cookie, ¶ms); + EXIT(); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int wlan_hdd_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*) + ) +#else +static int wlan_hdd_cfg80211_get_key( + struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, struct key_params*) + ) +#endif +{ + int ret; + + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise, + mac_addr, cookie, callback); +#else + ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr, + callback); +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_del_key + * This function is used to delete the key information + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr + ) +#else +static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + const u8 *mac_addr + ) +#endif +{ + int status = 0; + + //This code needs to be revisited. There is sme_removeKey API, we should + //plan to use that. After the change to use correct index in setkey, + //it is observed that this is invalidating peer + //key index whenever re-key is done. This is affecting data link. + //It should be ok to ignore del_key. +#if 0 + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tCsrRoamSetKey setKey; + v_U32_t roamId= 0xFF; + + ENTER(); + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n", + __func__,pAdapter->device_mode); + + if (CSR_MAX_NUM_KEY <= key_index) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__, + key_index); + + return -EINVAL; + } + + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; + + if (mac_addr) + vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN); + else + vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN); + + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if( pHostapdState->bssState == BSS_START) + { + status = WLANSAP_SetKeySta( pVosContext, &setKey); + + if ( status != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", + __LINE__, status ); + } + } + } + else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + ) + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x", + __func__, setKey.peerMac[0], setKey.peerMac[1], + setKey.peerMac[2], setKey.peerMac[3], + setKey.peerMac[4], setKey.peerMac[5]); + if(pAdapter->sessionCtx.station.conn_info.connState == + eConnectionState_Associated) + { + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failure, returned %d", + __func__, status); + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + return -EINVAL; + } + } + } +#endif + EXIT(); + return status; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool pairwise, + const u8 *mac_addr + ) +#else +static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + const u8 *mac_addr + ) +#endif +{ + int ret; + + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise, + mac_addr); +#else + ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr); +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_default_key + * This function is used to set the default tx key index + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool unicast, bool multicast) +#else +static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index) +#endif +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + int status; + hdd_wext_state_t *pWextState; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + + ENTER(); + + if ((NULL == pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter"); + return -EINVAL; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY, + pAdapter->sessionId, key_index)); + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if ((NULL == pWextState) || (NULL == pHddStaCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid Wext state or HDD context"); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d", + __func__,pAdapter->device_mode, key_index); + + if (CSR_MAX_NUM_KEY <= key_index) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__, + key_index); + + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + ) + { + if ( (eCSR_ENCRYPT_TYPE_TKIP != + pHddStaCtx->conn_info.ucEncryptionType) && +#ifdef FEATURE_WLAN_WAPI + (eCSR_ENCRYPT_TYPE_WPI != + pHddStaCtx->conn_info.ucEncryptionType) && +#endif + (eCSR_ENCRYPT_TYPE_AES != + pHddStaCtx->conn_info.ucEncryptionType) + ) + { + /* if default key index is not same as previous one, + * then update the default key index */ + + tCsrRoamSetKey setKey; + v_U32_t roamId= 0xFF; + tCsrKeys *Keys = &pWextState->roamProfile.Keys; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d", + __func__, key_index); + + Keys->defaultIndex = (u8)key_index; + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + setKey.keyId = key_index; + setKey.keyLength = Keys->KeyLength[key_index]; + + vos_mem_copy(&setKey.Key[0], + &Keys->KeyMaterial[key_index][0], + Keys->KeyLength[key_index]); + + setKey.keyDirection = eSIR_TX_RX; + + vos_mem_copy(setKey.peerMac, + &pHddStaCtx->conn_info.bssId[0], + WNI_CFG_BSSID_LEN); + + if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN && + pWextState->roamProfile.EncryptionType.encryptionType[0] == + eCSR_ENCRYPT_TYPE_WEP104) + { + /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104 + even though ap is configured for WEP-40 encryption. In this canse the key length + is 5 but the encryption type is 104 hence checking the key langht(5) and encryption + type(104) and switching encryption type to 40*/ + pWextState->roamProfile.EncryptionType.encryptionType[0] = + eCSR_ENCRYPT_TYPE_WEP40; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = + eCSR_ENCRYPT_TYPE_WEP40; + } + + setKey.encType = + pWextState->roamProfile.EncryptionType.encryptionType[0]; + + /* issue set key request */ + status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &setKey, &roamId ); + + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_RoamSetKey failed, returned %d", __func__, + status); + return -EINVAL; + } + } + } + + /* In SoftAp mode setting key direction for default mode */ + else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) + { + if ( (eCSR_ENCRYPT_TYPE_TKIP != + pWextState->roamProfile.EncryptionType.encryptionType[0]) && + (eCSR_ENCRYPT_TYPE_AES != + pWextState->roamProfile.EncryptionType.encryptionType[0]) + ) + { + /* Saving key direction for default key index to TX default */ + hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT; + } + } + EXIT(); + return status; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index, + bool unicast, bool multicast) +#else +static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index) +#endif +{ + int ret; + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast, + multicast); +#else + ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index); +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_inform_bss + * This function is used to inform the BSS details to nl80211 interface. + */ +static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss( + hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile) +{ + struct net_device *dev = pAdapter->dev; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + tSirBssDescription *pBssDesc = roamProfile->pBssDesc; + int chan_no; + int ie_length; + const char *ie; + unsigned int freq; + struct ieee80211_channel *chan; + int rssi = 0; + struct cfg80211_bss *bss = NULL; + + if( NULL == pBssDesc ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__); + return bss; + } + + chan_no = pBssDesc->channelId; + ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length ); + ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL); + + if( NULL == ie ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__); + return bss; + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)) + if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ)) + { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ); + } + else + { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ); + } +#else + freq = ieee80211_channel_to_frequency(chan_no); +#endif + + chan = __ieee80211_get_channel(wiphy, freq); + + if (!chan) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__); + return NULL; + } + + rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100; + + return cfg80211_inform_bss(wiphy, chan, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + CFG80211_BSS_FTYPE_UNKNOWN, +#endif + pBssDesc->bssId, + le64_to_cpu(*(__le64 *)pBssDesc->timeStamp), + pBssDesc->capabilityInfo, + pBssDesc->beaconInterval, ie, ie_length, + rssi, GFP_KERNEL ); +} + +/* + * wlan_hdd_cfg80211_update_bss_list :to inform nl80211 + * interface that BSS might have been lost. + * @pAdapter: adaptor + * @bssid: bssid which might have been lost + * + * Return: bss which is unlinked from kernel cache + */ +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list( + hdd_adapter_t *pAdapter, tSirMacAddr bssid) +{ + struct net_device *dev = pAdapter->dev; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_bss *bss = NULL; + + bss = hdd_get_bss_entry(wiphy, + NULL, bssid, + NULL, 0); + if (bss == NULL) { + hddLog(LOGE, FL("BSS not present")); + } else { + hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid)); + cfg80211_unlink_bss(wiphy, bss); + } + return bss; +} + + +/* + * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame + * This function is used to inform the BSS details to nl80211 interface. + */ +struct cfg80211_bss* +wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter, + tSirBssDescription *bss_desc + ) +{ + /* + cfg80211_inform_bss() is not updating ie field of bss entry, if entry + already exists in bss data base of cfg80211 for that particular BSS ID. + Using cfg80211_inform_bss_frame to update the bss entry instead of + cfg80211_inform_bss, But this call expects mgmt packet as input. As of + now there is no possibility to get the mgmt(probe response) frame from PE, + converting bss_desc to ieee80211_mgmt(probe response) and passing to + cfg80211_inform_bss_frame. + */ + struct net_device *dev = pAdapter->dev; + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + int chan_no = bss_desc->channelId; +#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS + qcom_ie_age *qie_age = NULL; + int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age); +#else + int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ); +#endif + const char *ie = + ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL); + unsigned int freq; + struct ieee80211_channel *chan; + struct ieee80211_mgmt *mgmt = NULL; + struct cfg80211_bss *bss_status = NULL; + size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length; + int rssi = 0; + hdd_context_t *pHddCtx; + int status; +#ifdef WLAN_OPEN_SOURCE + struct timespec ts; +#endif + + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return NULL; + } + + mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL); + if (!mgmt) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: memory allocation failed ", __func__); + return NULL; + } + + memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN); + +#ifdef WLAN_OPEN_SOURCE + /* Android does not want the timestamp from the frame. + Instead it wants a monotonic increasing value */ + get_monotonic_boottime(&ts); + mgmt->u.probe_resp.timestamp = + ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); +#else + /* keep old behavior for non-open source (for now) */ + memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp, + sizeof (bss_desc->timeStamp)); + +#endif + + mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval; + mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo; + +#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS + /* GPS Requirement: need age ie per entry. Using vendor specific. */ + /* Assuming this is the last IE, copy at the end */ + ie_length -=sizeof(qcom_ie_age); + qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length); + qie_age->element_id = QCOM_VENDOR_IE_ID; + qie_age->len = QCOM_VENDOR_IE_AGE_LEN; + qie_age->oui_1 = QCOM_OUI1; + qie_age->oui_2 = QCOM_OUI2; + qie_age->oui_3 = QCOM_OUI3; + qie_age->type = QCOM_VENDOR_IE_AGE_TYPE; + /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all + * bss related timestamp is in units of ms. Due to this when scan results + * are sent to lowi the scan age is high.To address this, send age in units + * of 1/10 ms. + */ + qie_age->age = (vos_timer_get_system_time() - + bss_desc->nReceivedTime)/10; +#endif + + memcpy(mgmt->u.probe_resp.variable, ie, ie_length); + if (bss_desc->fProbeRsp) + { + mgmt->frame_control |= + (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); + } + else + { + mgmt->frame_control |= + (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); + } + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)) + if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) && + (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL)) + { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ); + } + else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) && + (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL)) + + { + freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d", + __func__, chan_no); + kfree(mgmt); + return NULL; + } +#else + freq = ieee80211_channel_to_frequency(chan_no); +#endif + chan = __ieee80211_get_channel(wiphy, freq); + /*when the band is changed on the fly using the GUI, three things are done + * 1. scan abort 2.flush scan results from cache 3.update the band with the new band user specified(refer to the hdd_setBand_helper function) + * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band. + * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function. + * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels + * and discards the channels correponding to previous band and calls back with zero bss results. + * but if the time between band update and scan done callback is very small then band change will not reflect in SME and SME reports to HDD + * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so + * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed. + * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark. + * So drop the bss and continue to next bss. + */ + if(chan == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("chan pointer is NULL, chan_no: %d freq: %d"), + chan_no, freq); + kfree(mgmt); + return NULL; + } + /*To keep the rssi icon of the connected AP in the scan window + *and the rssi icon of the wireless networks in sync + * */ + if (( eConnectionState_Associated == + pAdapter->sessionCtx.station.conn_info.connState ) && + ( VOS_TRUE == vos_mem_compare(bss_desc->bssId, + pAdapter->sessionCtx.station.conn_info.bssId, + WNI_CFG_BSSID_LEN)) && + (pHddCtx->hdd_wlan_suspended == FALSE)) + { + /* supplicant takes the signal strength in terms of mBm(100*dBm) */ + rssi = (pAdapter->rssi * 100); + } + else + { + rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d" + " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid), + vos_freq_to_chan(chan->center_freq), (int)(rssi/100)); + + bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt, + frame_len, rssi, GFP_KERNEL); + kfree(mgmt); + return bss_status; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_update_bss_db + * This function is used to update the BSS data base of CFG8011 + */ +struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo + ) +{ + tCsrRoamConnectedProfile roamProfile; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + struct cfg80211_bss *bss = NULL; + + ENTER(); + + memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile)); + sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile); + + if (NULL != roamProfile.pBssDesc) + { + bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter, + roamProfile.pBssDesc); + + if (NULL == bss) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL", + __func__); + } + + sme_RoamFreeConnectProfile(hHal, &roamProfile); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL", + __func__); + } + return bss; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_update_bss + */ +static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy, + hdd_adapter_t *pAdapter + ) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tCsrScanResultInfo *pScanResult; + eHalStatus status = 0; + int ret; + tScanResultHandle pResult; + struct cfg80211_bss *bss_status = NULL; + hdd_context_t *pHddCtx; + bool is_p2p_scan = false; + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_UPDATE_BSS, + NO_SESSION, pAdapter->sessionId)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + if (pAdapter->request != NULL) + { + if ((pAdapter->request->n_ssids == 1) + && (pAdapter->request->ssids != NULL) + && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7)) + is_p2p_scan = true; + } + /* + * start getting scan results and populate cgf80211 BSS database + */ + status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult); + + /* no scan results */ + if (NULL == pResult) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d", + __func__, status); + wlan_hdd_get_frame_logs(pAdapter, + WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR); + return status; + } + + pScanResult = sme_ScanResultGetFirst(hHal, pResult); + + while (pScanResult) + { + /* + * cfg80211_inform_bss() is not updating ie field of bss entry, if + * entry already exists in bss data base of cfg80211 for that + * particular BSS ID. Using cfg80211_inform_bss_frame to update the + * bss entry instead of cfg80211_inform_bss, But this call expects + * mgmt packet as input. As of now there is no possibility to get + * the mgmt(probe response) frame from PE, converting bss_desc to + * ieee80211_mgmt(probe response) and passing to c + * fg80211_inform_bss_frame. + * */ + if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) && + !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) ) + { + pScanResult = sme_ScanResultGetNext(hHal, pResult); + continue; //Skip the non p2p bss entries + } + bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter, + &pScanResult->BssDescriptor); + + + if (NULL == bss_status) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: NULL returned by cfg80211_inform_bss", __func__); + } + else + { + cfg80211_put_bss( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + wiphy, +#endif + bss_status); + } + + pScanResult = sme_ScanResultGetNext(hHal, pResult); + } + + sme_ScanResultPurge(hHal, pResult); + is_p2p_scan = false; + return 0; +} + +void +hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel) +{ + VOS_TRACE(VOS_MODULE_ID_HDD, logLevel, + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr)); +} /****** end hddPrintMacAddr() ******/ + +void +hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel) +{ + VOS_TRACE(VOS_MODULE_ID_HDD, logLevel, + "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4], + pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10], + pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]); +} /****** end hddPrintPmkId() ******/ + +//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel); +//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL); + +//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size); +//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16); + +#define dump_bssid(bssid) \ + { \ + hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \ + hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\ + } + +#define dump_pmkid(pMac, pmkid) \ + { \ + hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \ + hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\ + } + +#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +/* + * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify + * This function is used to notify the supplicant of a new PMKSA candidate. + */ +int wlan_hdd_cfg80211_pmksa_candidate_notify( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + int index, bool preauth ) +{ +#ifdef FEATURE_WLAN_OKC + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + ENTER(); + hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__); + + if( NULL == pRoamInfo ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__); + return -EINVAL; + } + + if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx)) + { + dump_bssid(pRoamInfo->bssid); + cfg80211_pmksa_candidate_notify(dev, index, + pRoamInfo->bssid, preauth, GFP_KERNEL); + } +#endif /* FEATURE_WLAN_OKC */ + return 0; +} +#endif //FEATURE_WLAN_LFR + +#ifdef FEATURE_WLAN_LFR_METRICS +/* + * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth + * 802.11r/LFR metrics reporting function to report preauth initiation + * + */ +#define MAX_LFR_METRICS_EVENT_LENGTH 100 +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter, + tCsrRoamInfo *pRoamInfo) +{ + unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1]; + union iwreq_data wrqu; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(LOGE, "%s: pAdapter is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* create the event */ + memset(&wrqu, 0, sizeof(wrqu)); + memset(metrics_notification, 0, sizeof(metrics_notification)); + + wrqu.data.pointer = metrics_notification; + wrqu.data.length = scnprintf(metrics_notification, + sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid)); + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status + * 802.11r/LFR metrics reporting function to report preauth completion + * or failure + */ +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status( + hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status) +{ + unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1]; + union iwreq_data wrqu; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(LOGE, "%s: pAdapter is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* create the event */ + memset(&wrqu, 0, sizeof(wrqu)); + memset(metrics_notification, 0, sizeof(metrics_notification)); + + scnprintf(metrics_notification, sizeof(metrics_notification), + "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pRoamInfo->bssid)); + + if (1 == preauth_status) + strncat(metrics_notification, " TRUE", 5); + else + strncat(metrics_notification, " FALSE", 6); + + wrqu.data.pointer = metrics_notification; + wrqu.data.length = strlen(metrics_notification); + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover + * 802.11r/LFR metrics reporting function to report handover initiation + * + */ +VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter, + tCsrRoamInfo *pRoamInfo) +{ + unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1]; + union iwreq_data wrqu; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(LOGE, "%s: pAdapter is NULL!", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* create the event */ + memset(&wrqu, 0, sizeof(wrqu)); + memset(metrics_notification, 0, sizeof(metrics_notification)); + + wrqu.data.pointer = metrics_notification; + wrqu.data.length = scnprintf(metrics_notification, + sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid)); + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} +#endif + + +/** + * wlan_hdd_cfg80211_validate_scan_req - validate scan request + * @scan_req: scan request to be checked + * + * Return: true or false + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) +static inline bool wlan_hdd_cfg80211_validate_scan_req(struct + cfg80211_scan_request + *scan_req, hdd_context_t + *hdd_ctx) +{ + if (!scan_req || !scan_req->wiphy || + scan_req->wiphy != hdd_ctx->wiphy) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request"); + return false; + } + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress"); + return false; + } + return true; +} +#else +static inline bool wlan_hdd_cfg80211_validate_scan_req(struct + cfg80211_scan_request + *scan_req, hdd_context_t + *hdd_ctx) +{ + if (!scan_req || !scan_req->wiphy || + scan_req->wiphy != hdd_ctx->wiphy) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request"); + return false; + } + return true; +} +#endif + +#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP) +/* + * FUNCTION: hdd_cfg80211_scan_done_callback + * scanning callback function, called after finishing scan + * + */ +static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle, + void *pContext, tANI_U32 scanId, eCsrScanStatus status) +{ + struct net_device *dev = (struct net_device *) pContext; + //struct wireless_dev *wdev = dev->ieee80211_ptr; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_scaninfo_t *pScanInfo; + struct cfg80211_scan_request *req = NULL; + int ret = 0; + bool aborted = false; + long waitRet = 0; + tANI_U8 i; + hdd_context_t *pHddCtx; + + ENTER(); + + if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC || + !pAdapter->dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid")); + return 0; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null")); + return 0; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (!NET_DEV_IS_IFF_UP(pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down")); + } +#endif + pScanInfo = &pHddCtx->scan_info; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s called with halHandle = %p, pContext = %p," + "scanID = %d, returned status = %d", + __func__, halHandle, pContext, (int) scanId, (int) status); + + pScanInfo->mScanPendingCounter = 0; + + //Block on scan req completion variable. Can't wait forever though. + waitRet = wait_for_completion_interruptible_timeout( + &pScanInfo->scan_req_completion_event, + msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ)); + if (waitRet <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s wait on scan_req_completion_event failed %ld",__func__, waitRet); + VOS_ASSERT(pScanInfo->mScanPending); + goto allow_suspend; + } + + if (pScanInfo->mScanPending != VOS_TRUE) + { + VOS_ASSERT(pScanInfo->mScanPending); + goto allow_suspend; + } + + /* Check the scanId */ + if (pScanInfo->scanId != scanId) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s called with mismatched scanId pScanInfo->scanId = %d " + "scanId = %d", __func__, (int) pScanInfo->scanId, + (int) scanId); + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (NET_DEV_IS_IFF_UP(pAdapter)) +#endif + { + ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy, + pAdapter); + if (0 > ret) + hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__); + } + + /* If any client wait scan result through WEXT + * send scan done event to client */ + if (pHddCtx->scan_info.waitScanResult) + { + /* The other scan request waiting for current scan finish + * Send event to notify current scan finished */ + if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option) + { + vos_event_set(&pHddCtx->scan_info.scan_finished_event); + } + /* Send notify to WEXT client */ + else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option) + { + struct net_device *dev = pAdapter->dev; + union iwreq_data wrqu; + int we_event; + char *msg; + + memset(&wrqu, '\0', sizeof(wrqu)); + we_event = SIOCGIWSCAN; + msg = NULL; + wireless_send_event(dev, we_event, &wrqu, msg); + } + } + pHddCtx->scan_info.waitScanResult = FALSE; + + /* Get the Scan Req */ + req = pAdapter->request; + pAdapter->request = NULL; + + /* Scan is no longer pending */ + pScanInfo->mScanPending = VOS_FALSE; + + if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx)) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"), + NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down"); +#endif + + if (pAdapter->dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"), + pAdapter->dev->name); + } + complete(&pScanInfo->abortscan_event_var); + goto allow_suspend; + } + + /* last_scan_timestamp is used to decide if new scan + * is needed or not on station interface. If last station + * scan time and new station scan time is less then + * last_scan_timestamp ; driver will return cached scan. + */ + if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find + { + pScanInfo->last_scan_timestamp = vos_timer_get_system_time(); + + if ( req->n_channels ) + { + for (i = 0; i < req->n_channels ; i++ ) + { + pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value; + } + /* store no of channel scanned */ + pHddCtx->scan_info.last_scan_numChannels= req->n_channels; + } + + } + + /* + * cfg80211_scan_done informing NL80211 about completion + * of scanning + */ + if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE) + { + aborted = true; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (NET_DEV_IS_IFF_UP(pAdapter) && + wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx)) +#endif + cfg80211_scan_done(req, aborted); + + complete(&pScanInfo->abortscan_event_var); + +allow_suspend: + if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE + ) && (pHddCtx->spoofMacAddr.isEnabled + || pHddCtx->spoofMacAddr.isReqDeferred)) { + /* Generate new random mac addr for next scan */ + hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr"); + + schedule_delayed_work(&pHddCtx->spoof_mac_addr_work, + msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL)); + } + + /* release the wake lock at the end of the scan*/ + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN); + + /* Acquire wakelock to handle the case where APP's tries to suspend + * immediatly after the driver gets connect request(i.e after scan) + * from supplicant, this result in app's is suspending and not able + * to process the connect request to AP */ + hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (NET_DEV_IS_IFF_UP(pAdapter)) +#endif +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_tdls_scan_done_callback(pAdapter); +#endif + + EXIT(); + return 0; +} + +/* + * FUNCTION: hdd_isConnectionInProgress + * Go through each adapter and check if Connection is in progress + * + */ +v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id, + scan_reject_states *reason) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status = 0; + v_U8_t staId = 0; + v_U8_t *staMac = NULL; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Adapter with device mode %s (%d) exists", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) && + (eConnectionState_Connecting == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + { + hddLog(LOG1, + "%s: %p(%d) Connection is in progress", __func__, + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId); + if (session_id && reason) + { + *session_id = pAdapter->sessionId; + *reason = eHDD_CONNECTION_IN_PROGRESS; + } + return VOS_TRUE; + } + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + hddLog(LOG1, + "%s: %p(%d) Reassociation is in progress", __func__, + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId); + if (session_id && reason) + { + *session_id = pAdapter->sessionId; + *reason = eHDD_REASSOC_IN_PROGRESS; + } + return VOS_TRUE; + } + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]); + hddLog(LOG1, + "%s: client " MAC_ADDRESS_STR + " is in the middle of WPS/EAPOL exchange.", __func__, + MAC_ADDR_ARRAY(staMac)); + if (session_id && reason) + { + *session_id = pAdapter->sessionId; + *reason = eHDD_EAPOL_IN_PROGRESS; + } + return VOS_TRUE; + } + } + else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode)) + { + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_FALSE; + } + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) + { + if ((pSapCtx->aStaInfo[staId].isUsed) && + (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState)) + { + staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]); + + hddLog(LOG1, + "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the " + "middle of WPS/EAPOL exchange.", __func__, + MAC_ADDR_ARRAY(staMac)); + if (session_id && reason) + { + *session_id = pAdapter->sessionId; + *reason = eHDD_SAP_EAPOL_IN_PROGRESS; + } + return VOS_TRUE; + } + } + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return VOS_FALSE; +} + +/** + * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant + * to the Scan request + * @scanRequest: Pointer to the csr scan request + * @request: Pointer to the scan request from supplicant + * + * Return: None + */ +#ifdef CFG80211_SCAN_BSSID +static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest, + struct cfg80211_scan_request *request) +{ + vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE); +} +#else +static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest, + struct cfg80211_scan_request *request) +{ +} +#endif + +/* + * FUNCTION: __wlan_hdd_cfg80211_scan + * this scan respond to scan trigger and update cfg80211 scan database + * later, scan dump command can be used to recieve scan results + */ +int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_wext_state_t *pwextBuf = NULL; + hdd_config_t *cfg_param = NULL; + tCsrScanRequest scanRequest; + tANI_U8 *channelList = NULL, i; + v_U32_t scanId = 0; + int status; + hdd_scaninfo_t *pScanInfo = NULL; + v_U8_t* pP2pIe = NULL; + int ret = 0; + v_U8_t *pWpsIe=NULL; + bool is_p2p_scan = false; + v_U8_t curr_session_id; + scan_reject_states curr_reason; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = NULL; + if (NULL == request) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: scan req param null", __func__); + return -EINVAL; + } + dev = request->wdev->netdev; +#endif + + pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + ENTER(); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if (NULL == pwextBuf) + { + hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n", + __func__); + return -EIO; + } + cfg_param = pHddCtx->cfg_ini; + pScanInfo = &pHddCtx->scan_info; + +#ifdef WLAN_BTAMP_FEATURE + //Scan not supported when AMP traffic is on. + if (VOS_TRUE == WLANBAP_AmpSessionOn()) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: No scanning when AMP is on", __func__); + return -EOPNOTSUPP; + } +#endif + //Scan on any other interface is not supported. + if (pAdapter->device_mode == WLAN_HDD_SOFTAP) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Not scanning on device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + return -EOPNOTSUPP; + } + + if (TRUE == pScanInfo->mScanPending) + { + if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__); + } + return -EBUSY; + } + + // Don't allow scan if PNO scan is going on. + if (pHddCtx->isPnoEnable) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pno scan in progress")); + return -EBUSY; + } + + //Don't Allow Scan and return busy if Remain On + //Channel and action frame is pending + //Otherwise Cancel Remain On Channel and allow Scan + //If no action frame pending + if (0 != wlan_hdd_check_remain_on_channel(pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__); + return -EBUSY; + } + + if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Acquire lock fail", __func__); + return -EAGAIN; + } + if (TRUE == pHddCtx->tmInfo.tmAction.enterImps) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: MAX TM Level Scan not allowed", __func__); + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + return -EBUSY; + } + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + + /* Check if scan is allowed at this point of time. + */ + if (TRUE == pHddCtx->btCoexModeSet) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("BTCoex Mode operation in progress")); + return -EBUSY; + } + if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason)) + { + + if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT)) + hddLog(LOGE, FL("Scan not allowed Session %d reason %d"), + curr_session_id, curr_reason); + if (pHddCtx->last_scan_reject_session_id != curr_session_id || + pHddCtx->last_scan_reject_reason != curr_reason || + !pHddCtx->last_scan_reject_timestamp) + { + pHddCtx->last_scan_reject_session_id = curr_session_id; + pHddCtx->last_scan_reject_reason = curr_reason; + pHddCtx->last_scan_reject_timestamp = + jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME; + pHddCtx->scan_reject_cnt = 0; + } + else + { + pHddCtx->scan_reject_cnt++; + + if ((pHddCtx->scan_reject_cnt >= + SCAN_REJECT_THRESHOLD) && + vos_system_time_after(jiffies_to_msecs(jiffies), + pHddCtx->last_scan_reject_timestamp)) + { + hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"), + curr_session_id, curr_reason, pHddCtx->scan_reject_cnt, + vos_system_time_after(jiffies_to_msecs(jiffies), + pHddCtx->last_scan_reject_timestamp)); + pHddCtx->last_scan_reject_timestamp = 0; + pHddCtx->scan_reject_cnt = 0; + if (pHddCtx->cfg_ini->enableFatalEvent) + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_SCAN_NOT_ALLOWED, + FALSE, FALSE); + else + { + hddLog(LOGE, FL("Triggering SSR")); + vos_wlanRestart(); + } + } + } + return -EBUSY; + } + pHddCtx->last_scan_reject_timestamp = 0; + pHddCtx->last_scan_reject_session_id = 0xFF; + pHddCtx->last_scan_reject_reason = 0; + pHddCtx->scan_reject_cnt = 0; + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1. + * Becasue of this, driver is assuming that this is not wildcard scan and so + * is not aging out the scan results. + */ + if (request->ssids && '\0' == request->ssids->ssid[0]) + { + request->n_ssids = 0; + } + + if ((request->ssids) && (0 < request->n_ssids)) + { + tCsrSSIDInfo *SsidInfo; + int j; + scanRequest.SSIDs.numOfSSIDs = request->n_ssids; + /* Allocate num_ssid tCsrSSIDInfo structure */ + SsidInfo = scanRequest.SSIDs.SSIDList = + ( tCsrSSIDInfo *)vos_mem_malloc( + request->n_ssids*sizeof(tCsrSSIDInfo)); + + if(NULL == scanRequest.SSIDs.SSIDList) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: memory alloc failed SSIDInfo buffer", __func__); + return -ENOMEM; + } + + /* copy all the ssid's and their length */ + for(j = 0; j < request->n_ssids; j++, SsidInfo++) + { + /* get the ssid length */ + SsidInfo->SSID.length = request->ssids[j].ssid_len; + vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0], + SsidInfo->SSID.length); + SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0'; + hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s", + j, SsidInfo->SSID.ssId); + } + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } + else if(WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SCAN, + pAdapter->sessionId, 0)); + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } + else + { + /*Set the scan type to default type, in this case it is ACTIVE*/ + scanRequest.scanType = pScanInfo->scan_mode; + } + scanRequest.minChnTime = cfg_param->nActiveMinChnTime; + scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime; + + csr_scan_request_assign_bssid(&scanRequest, request); + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + /*TODO: scan the requested channels only*/ + + /*Right now scanning all the channels */ + if (MAX_CHANNEL < request->n_channels) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "No of Scan Channels exceeded limit: %d", request->n_channels); + request->n_channels = MAX_CHANNEL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "No of Scan Channels: %d", request->n_channels); + + + if( request->n_channels ) + { + char chList [(request->n_channels*5)+1]; + int len; + channelList = vos_mem_malloc( request->n_channels ); + if( NULL == channelList ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: memory alloc failed channelList", __func__); + status = -ENOMEM; + goto free_mem; + } + + for( i = 0, len = 0; i < request->n_channels ; i++ ) + { + channelList[i] = request->channels[i]->hw_value; + len += snprintf(chList+len, 5, "%d ", channelList[i]); + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "Channel-List: %s ", chList); + } + + scanRequest.ChannelInfo.numOfChannels = request->n_channels; + scanRequest.ChannelInfo.ChannelList = channelList; + + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + + /* if there is back to back scan happening in driver with in + * nDeferScanTimeInterval interval driver should defer new scan request + * and should provide last cached scan results instead of new channel list. + * This rule is not applicable if scan is p2p scan. + * This condition will work only in case when last request no of channels + * and channels are exactly same as new request. + * This should be done only in connected state + * Scan shouldn't be defered for WPS scan case. + */ + + pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len); + /* if wps ie is NULL , then only defer scan */ + if ( pWpsIe == NULL && + (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx))) + { + if ( pScanInfo->last_scan_timestamp !=0 && + ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval)) + { + if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 && + (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) && + vos_mem_compare(pScanInfo->last_scan_channelList, + channelList, pScanInfo->last_scan_numChannels)) + { + hddLog(VOS_TRACE_LEVEL_WARN, + " New and old station scan time differ is less then %u", + pHddCtx->cfg_ini->nDeferScanTimeInterval); + + ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy, + pAdapter); + + hddLog(VOS_TRACE_LEVEL_WARN, + "Return old cached scan as all channels and no of channels are same"); + + if (0 > ret) + hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__); + + cfg80211_scan_done(request, eCSR_SCAN_SUCCESS); + + status = eHAL_STATUS_SUCCESS; + goto free_mem; + } + } + } + + /* Flush the scan results(only p2p beacons) for STA scan and P2P + * search (Flush on both full scan and social scan but not on single + * channel scan).P2P search happens on 3 social channels (1, 6, 11) + */ + + /* Supplicant does single channel scan after 8-way handshake + * and in that case driver shoudnt flush scan results. If + * driver flushes the scan results here and unfortunately if + * the AP doesnt respond to our probe req then association + * fails which is not desired + */ + if ((request->n_ssids == 1) + && (request->ssids != NULL) + && vos_mem_compare(&request->ssids[0], "DIRECT-", 7)) + is_p2p_scan = true; + + if( is_p2p_scan || + (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) ) + { + hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results"); + sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId ); + } + + if( request->ie_len ) + { + /* save this for future association (join requires this) */ + /*TODO: Array needs to be converted to dynamic allocation, + * as multiple ie.s can be sent in cfg80211_scan_request structure + * CR 597966 + */ + memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) ); + memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len); + pScanInfo->scanAddIE.length = request->ie_len; + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) + { + if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH) + { + pwextBuf->roamProfile.nAddIEScanLength = request->ie_len; + memcpy( pwextBuf->roamProfile.addIEScan, + request->ie, request->ie_len); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:" + "%zu", request->ie_len); + } + + } + scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length; + scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata; + + pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie, + request->ie_len); + if (pP2pIe != NULL) + { +#ifdef WLAN_FEATURE_P2P_DEBUG + if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) || + (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) && + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from " + "Go nego completed to Connection is started"); + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started " + "for 8way Handshake"); + } + else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) && + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2; + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from " + "Disconnected state to Connection is started"); + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started " + "for 4way Handshake"); + } +#endif + + /* no_cck will be set during p2p find to disable 11b rates */ + if(TRUE == request->no_cck) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: This is a P2P Search", __func__); + scanRequest.p2pSearch = 1; + + if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS ) + { + /* set requestType to P2P Discovery */ + scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY; + } + + /* + Skip Dfs Channel in case of P2P Search + if it is set in ini file + */ + if(cfg_param->skipDfsChnlInP2pSearch) + { + scanRequest.skipDfsChnlInP2pSearch = 1; + } + else + { + scanRequest.skipDfsChnlInP2pSearch = 0; + } + + } + } + } + + INIT_COMPLETION(pScanInfo->scan_req_completion_event); + +#ifdef FEATURE_WLAN_TDLS + /* if tdls disagree scan right now, return immediately. + tdls will schedule the scan when scan is allowed. (return SUCCESS) + or will reject the scan if any TDLS is in progress. (return -EBUSY) + */ + status = wlan_hdd_tdls_scan_callback (pAdapter, + wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request); + if (status <= 0) + { + if (!status) + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress." + "scan rejected %d", __func__, status); + else + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d", + __func__, status); + hdd_wlan_block_scan_by_tdls(); + goto free_mem; + } +#endif + + /* acquire the wakelock to avoid the apps suspend during the scan. To + * address the following issues. + * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in + * BMPS/IMPS this result in android trying to suspend aggressively and backing off + * for long time, this result in apps running at full power for long time. + * 2) Connected scenario: If we allow the suspend during the scan, RIVA will + * be stuck in full power because of resume BMPS + */ + hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN); + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "requestType %d, scanType %d, minChnTime %d, maxChnTime %d," + "p2pSearch %d, skipDfsChnlInP2pSearch %d", + scanRequest.requestType, scanRequest.scanType, + scanRequest.minChnTime, scanRequest.maxChnTime, + scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch); + + if (pHddCtx->spoofMacAddr.isEnabled && + pHddCtx->cfg_ini->enableMacSpoofing == 1) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: MAC Spoofing enabled for current scan", __func__); + /* Updating SelfSta Mac Addr in TL which will be used to get staidx + * to fill TxBds for probe request during current scan + */ + status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext, + &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent); + + if(status != VOS_STATUS_SUCCESS) + { + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN); + status = -EFAULT; +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_tdls_scan_done_callback(pAdapter); +#endif + goto free_mem; + } + } + wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR); + status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &scanRequest, &scanId, + &hdd_cfg80211_scan_done_callback, dev ); + + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_ScanRequest returned error %d", __func__, status); + complete(&pScanInfo->scan_req_completion_event); + if(eHAL_STATUS_RESOURCES == status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress." + "So defer the scan by informing busy",__func__); + status = -EBUSY; + } else { + status = -EIO; + } + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN); + +#ifdef FEATURE_WLAN_TDLS + wlan_hdd_tdls_scan_done_callback(pAdapter); +#endif + goto free_mem; + } + + pScanInfo->mScanPending = TRUE; + pScanInfo->sessionId = pAdapter->sessionId; + pAdapter->request = request; + pScanInfo->scanId = scanId; + + complete(&pScanInfo->scan_req_completion_event); + +free_mem: + if( scanRequest.SSIDs.SSIDList ) + { + vos_mem_free(scanRequest.SSIDs.SSIDList); + } + + if( channelList ) + vos_mem_free( channelList ); + + EXIT(); + return status; +} + +int wlan_hdd_cfg80211_scan( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_scan(wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request); + vos_ssr_unprotect(__func__); + + return ret; +} + +void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel) +{ + v_U8_t iniDot11Mode = + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode; + eHddDot11Mode hddDot11Mode = iniDot11Mode; + + hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"), + iniDot11Mode); + switch ( iniDot11Mode ) + { + case eHDD_DOT11_MODE_AUTO: + case eHDD_DOT11_MODE_11ac: + case eHDD_DOT11_MODE_11ac_ONLY: +#ifdef WLAN_FEATURE_11AC + if ( sme_IsFeatureSupportedByDriver(DOT11AC) && + sme_IsFeatureSupportedByFW(DOT11AC) ) + hddDot11Mode = eHDD_DOT11_MODE_11ac; + else + hddDot11Mode = eHDD_DOT11_MODE_11n; +#else + hddDot11Mode = eHDD_DOT11_MODE_11n; +#endif + break; + case eHDD_DOT11_MODE_11n: + case eHDD_DOT11_MODE_11n_ONLY: + hddDot11Mode = eHDD_DOT11_MODE_11n; + break; + default: + hddDot11Mode = iniDot11Mode; + break; + } +#ifdef WLAN_FEATURE_AP_HT40_24G + if (operationChannel > SIR_11B_CHANNEL_END) +#endif + { + /* This call decides required channel bonding mode */ + sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal), + hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode), + operationChannel); + } +} + +/* + * FUNCTION: wlan_hdd_cfg80211_connect_start + * This function is used to start the association process + */ +int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter, + const u8 *ssid, size_t ssid_len, const u8 *bssid, + const u8 *bssid_hint, u8 operatingChannel) +{ + int status = 0; + hdd_wext_state_t *pWextState; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *hdd_sta_ctx; + v_U32_t roamId; + tCsrRoamProfile *pRoamProfile; + eCsrAuthType RSNAuthType; + + ENTER(); + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + status = wlan_hdd_validate_context(pHddCtx); + if (status) + { + return status; + } + + if (SIR_MAC_MAX_SSID_LENGTH < ssid_len) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__); + return -EINVAL; + } + + wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx); + + pRoamProfile = &pWextState->roamProfile; + + if (pRoamProfile) + { + hdd_station_ctx_t *pHddStaCtx; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + pHddStaCtx->get_mgmt_log_sent = FALSE; + + wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR); + + if (HDD_WMM_USER_MODE_NO_QOS == + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode) + { + /*QoS not enabled in cfg file*/ + pRoamProfile->uapsd_mask = 0; + } + else + { + /*QoS enabled, update uapsd mask from cfg file*/ + pRoamProfile->uapsd_mask = + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask; + } + + pRoamProfile->SSIDs.numOfSSIDs = 1; + pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len; + vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId, + sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId)); + vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId), + ssid, ssid_len); + + vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN); + vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN); + + if (bssid) + { + pRoamProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid, + WNI_CFG_BSSID_LEN); + /* Save BSSID in seperate variable as well, as RoamProfile + BSSID is getting zeroed out in the association process. And in + case of join failure we should send valid BSSID to supplicant + */ + vos_mem_copy(pWextState->req_bssId, bssid, + WNI_CFG_BSSID_LEN); + + } + else if (bssid_hint) + { + /* Store bssid_hint to use in the scan filter. */ + vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint, + WNI_CFG_BSSID_LEN); + /* + * Save BSSID in seperate variable as well, as RoamProfile + * BSSID is getting zeroed out in the association process. And in + * case of join failure we should send valid BSSID to supplicant + */ + vos_mem_copy(pWextState->req_bssId, bssid_hint, + WNI_CFG_BSSID_LEN); + hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pRoamProfile->bssid_hint)); + } + + + hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"), + pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel); + if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) || + (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion)) + { + /*set gen ie*/ + hdd_SetGENIEToCsr(pAdapter, &RSNAuthType); + /*set auth*/ + hdd_set_csr_auth_type(pAdapter, RSNAuthType); + } +#ifdef FEATURE_WLAN_WAPI + if (pAdapter->wapi_info.nWapiMode) + { + hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__); + switch (pAdapter->wapi_info.wapiAuthMode) + { + case WAPI_AUTH_MODE_PSK: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__, + pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK; + break; + } + case WAPI_AUTH_MODE_CERT: + { + hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__, + pAdapter->wapi_info.wapiAuthMode); + pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + break; + } + } // End of switch + if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK || + pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) + { + hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__); + pRoamProfile->AuthType.numEntries = 1; + pRoamProfile->EncryptionType.numEntries = 1; + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + pRoamProfile->mcEncryptionType.numEntries = 1; + pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; + } + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef WLAN_FEATURE_GTK_OFFLOAD + /* Initializing gtkOffloadReqParams */ + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + memset(&pHddStaCtx->gtkOffloadReqParams, 0, + sizeof (tSirGtkOffloadParams)); + pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE; + } +#endif + pRoamProfile->csrPersona = pAdapter->device_mode; + + if( operatingChannel ) + { + pRoamProfile->ChannelInfo.ChannelList = &operatingChannel; + pRoamProfile->ChannelInfo.numOfChannels = 1; + } + else + { + pRoamProfile->ChannelInfo.ChannelList = NULL; + pRoamProfile->ChannelInfo.numOfChannels = 0; + } + if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel) + { + hdd_select_cbmode(pAdapter,operatingChannel); + } + + /* + * Change conn_state to connecting before sme_RoamConnect(), + * because sme_RoamConnect() has a direct path to call + * hdd_smeRoamCallback(), which will change the conn_state + * If direct path, conn_state will be accordingly changed + * to NotConnected or Associated by either + * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() + * in sme_RoamCallback() + * if sme_RomConnect is to be queued, + * Connecting state will remain until it is completed. + * If connection state is not changed, + * connection state will remain in eConnectionState_NotConnected state. + * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true + * if conn state is eConnectionState_NotConnected. + * If "hddDisconInProgress" is set to true then cfg80211 layer is not + * informed of connect result indication which is an issue. + */ + + if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Set HDD connState to eConnectionState_Connecting")); + hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + eConnectionState_Connecting); + } + status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, pRoamProfile, &roamId); + + if ((eHAL_STATUS_SUCCESS != status) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"), + pAdapter->sessionId, status); + /* change back to NotAssociated */ + hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + eConnectionState_NotConnected); + } + + pRoamProfile->ChannelInfo.ChannelList = NULL; + pRoamProfile->ChannelInfo.numOfChannels = 0; + + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__); + return -EINVAL; + } + EXIT(); + return status; +} + +/* + * FUNCTION: wlan_hdd_set_cfg80211_auth_type + * This function is used to set the authentication type (OPEN/SHARED). + * + */ +static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter, + enum nl80211_auth_type auth_type) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + /*set authentication type*/ + switch (auth_type) + { + case NL80211_AUTHTYPE_AUTOMATIC: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to AUTOSWITCH", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH; + break; + + case NL80211_AUTHTYPE_OPEN_SYSTEM: +#ifdef WLAN_FEATURE_VOWIFI_11R + case NL80211_AUTHTYPE_FT: +#endif /* WLAN_FEATURE_VOWIFI_11R */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to OPEN", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + break; + + case NL80211_AUTHTYPE_SHARED_KEY: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to SHARED", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY; + break; +#ifdef FEATURE_WLAN_ESE + case NL80211_AUTHTYPE_NETWORK_EAP: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: set authentication type to CCKM WPA", __func__); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required. + break; +#endif + + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unsupported authentication type %d", __func__, + auth_type); + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN; + return -EINVAL; + } + + pWextState->roamProfile.AuthType.authType[0] = + pHddStaCtx->conn_info.authType; + return 0; +} + +/* + * FUNCTION: wlan_hdd_set_akm_suite + * This function is used to set the key mgmt type(PSK/8021x). + * + */ +static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter, + u32 key_mgmt + ) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + ENTER(); + /* Should be in ieee802_11_defs.h */ +#ifndef WLAN_AKM_SUITE_8021X_SHA256 +#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05 +#endif +#ifndef WLAN_AKM_SUITE_PSK_SHA256 +#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06 +#endif + /*set key mgmt type*/ + switch(key_mgmt) + { + case WLAN_AKM_SUITE_PSK: + case WLAN_AKM_SUITE_PSK_SHA256: +#ifdef WLAN_FEATURE_VOWIFI_11R + case WLAN_AKM_SUITE_FT_PSK: +#endif + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK; + break; + + case WLAN_AKM_SUITE_8021X: + case WLAN_AKM_SUITE_8021X_SHA256: +#ifdef WLAN_FEATURE_VOWIFI_11R + case WLAN_AKM_SUITE_FT_8021X: +#endif + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X; + break; +#ifdef FEATURE_WLAN_ESE +#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */ +#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */ + case WLAN_AKM_SUITE_CCKM: + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM; + break; +#endif +#ifndef WLAN_AKM_SUITE_OSEN +#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */ + case WLAN_AKM_SUITE_OSEN: + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN", + __func__); + pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X; + break; +#endif + + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d", + __func__, key_mgmt); + return -EINVAL; + + } + return 0; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_set_cipher + * This function is used to set the encryption type + * (NONE/WEP40/WEP104/TKIP/CCMP). + */ +static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter, + u32 cipher, + bool ucast + ) +{ + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + if (!cipher) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none", + __func__, cipher); + encryptionType = eCSR_ENCRYPT_TYPE_NONE; + } + else + { + + /*set encryption method*/ + switch (cipher) + { + case IW_AUTH_CIPHER_NONE: + encryptionType = eCSR_ENCRYPT_TYPE_NONE; + break; + + case WLAN_CIPHER_SUITE_WEP40: + encryptionType = eCSR_ENCRYPT_TYPE_WEP40; + break; + + case WLAN_CIPHER_SUITE_WEP104: + encryptionType = eCSR_ENCRYPT_TYPE_WEP104; + break; + + case WLAN_CIPHER_SUITE_TKIP: + encryptionType = eCSR_ENCRYPT_TYPE_TKIP; + break; + + case WLAN_CIPHER_SUITE_CCMP: + encryptionType = eCSR_ENCRYPT_TYPE_AES; + break; +#ifdef FEATURE_WLAN_WAPI + case WLAN_CIPHER_SUITE_SMS4: + encryptionType = eCSR_ENCRYPT_TYPE_WPI; + break; +#endif + +#ifdef FEATURE_WLAN_ESE + case WLAN_CIPHER_SUITE_KRK: + encryptionType = eCSR_ENCRYPT_TYPE_KRK; + break; +#endif + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d", + __func__, cipher); + return -EOPNOTSUPP; + } + } + + if (ucast) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d", + __func__, encryptionType); + pHddStaCtx->conn_info.ucEncryptionType = encryptionType; + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] = + encryptionType; + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d", + __func__, encryptionType); + pHddStaCtx->conn_info.mcEncryptionType = encryptionType; + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType; + } + + return 0; +} + + +/* + * FUNCTION: wlan_hdd_cfg80211_set_ie + * This function is used to parse WPA/RSN IE's. + */ +int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *ie, +#else + u8 *ie, +#endif + size_t ie_len + ) +{ + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *genie = ie; +#else + u8 *genie = ie; +#endif + v_U16_t remLen = ie_len; +#ifdef FEATURE_WLAN_WAPI + v_U32_t akmsuite[MAX_NUM_AKM_SUITES]; + u16 *tmp; + v_U16_t akmsuiteCount; + int *akmlist; +#endif + ENTER(); + + /* clear previous assocAddIE */ + pWextState->assocAddIE.length = 0; + pWextState->roamProfile.bWPSAssociation = VOS_FALSE; + pWextState->roamProfile.bOSENAssociation = VOS_FALSE; + + while (remLen >= 2) + { + v_U16_t eLen = 0; + v_U8_t elementId; + elementId = *genie++; + eLen = *genie++; + remLen -= 2; + + /* Sanity check on eLen */ + if (eLen > remLen) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]", + __func__, eLen, elementId); + VOS_ASSERT(0); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]", + __func__, elementId, eLen); + + switch ( elementId ) + { + case DOT11F_EID_WPA: + if (4 > eLen) /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */ + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WPA IE", __func__); + return -EINVAL; + } + else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)", + __func__, eLen + 2); + + if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.bWPSAssociation = VOS_TRUE; + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } + else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) + { + if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]", + __func__, eLen); + VOS_ASSERT(0); + return -EINVAL; + } + + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2); + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/); + pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len; + } + else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE, + P2P_OUI_TYPE_SIZE))) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)", + __func__, eLen + 2); + + if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } +#ifdef WLAN_FEATURE_WFD + else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE, + WFD_OUI_TYPE_SIZE)) + /*Consider WFD IE, only for P2P Client */ + && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)", + __func__, eLen + 2); + + if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + // WFD IE is saved to Additional IE ; it should be accumulated to handle + // WPS IE + P2P IE + WFD IE + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } +#endif + /* Appending HS 2.0 Indication Element in Assiciation Request */ + else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE, + HS20_OUI_TYPE_SIZE)) ) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)", + __func__, eLen + 2); + + if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } + /* Appending OSEN Information Element in Assiciation Request */ + else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE, + OSEN_OUI_TYPE_SIZE)) ) + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)", + __func__, eLen + 2); + + if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.bOSENAssociation = VOS_TRUE; + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + } + + /* Update only for WPA IE */ + if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) && + (WLAN_HDD_IBSS == pAdapter->device_mode)) { + + /* populating as ADDIE in beacon frames */ + if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2, + NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS) + { + if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Coldn't pass " + "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM"); + } + }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/ + else + hddLog(LOGE, + "Could not pass on " + "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM"); + + /* IBSS mode doesn't contain params->proberesp_ies still + beaconIE's need to be populated in probe response frames */ + if ( (NULL != (genie - 2)) && (0 != eLen + 2) ) + { + u16 rem_probe_resp_ie_len = eLen + 2; + u8 probe_rsp_ie_len[3] = {0}; + u8 counter = 0; + + /* Check Probe Resp Length if it is greater then 255 then + Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 + & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are + not able Store More then 255 bytes into One Variable */ + + while ((rem_probe_resp_ie_len > 0) && (counter < 3)) + { + if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN) + { + probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN; + rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN; + } + else + { + probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len; + rem_probe_resp_ie_len = 0; + } + } + + rem_probe_resp_ie_len = 0; + + if (probe_rsp_ie_len[0] > 0) + { + if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + (tANI_U8*)(genie - 2), + probe_rsp_ie_len[0], NULL, + eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass" + "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM"); + } + rem_probe_resp_ie_len += probe_rsp_ie_len[0]; + } + + if (probe_rsp_ie_len[1] > 0) + { + if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)), + probe_rsp_ie_len[1], NULL, + eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass" + "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM"); + } + rem_probe_resp_ie_len += probe_rsp_ie_len[1]; + } + + if (probe_rsp_ie_len[2] > 0) + { + if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)), + probe_rsp_ie_len[2], NULL, + eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass" + "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM"); + } + rem_probe_resp_ie_len += probe_rsp_ie_len[2]; + } + + if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + "Could not pass" + "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM"); + } + } + } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */ + break; + case DOT11F_EID_RSN: + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2); + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/); + pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len; + break; + + /* Appending extended capabilities with Interworking or + * bsstransition bit set in Assoc Req. + * + * In assoc req this EXT Cap will only be taken into account if + * interworkingService or bsstransition bit is set to 1. + * Driver is only interested in interworkingService and + * bsstransition capability from supplicant. + * If in future any other EXT Cap info is + * required from supplicat, it needs to be handled while + * sending Assoc Req in LIM. + */ + case DOT11F_EID_EXTCAP: + { + v_U16_t curAddIELen = pWextState->assocAddIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)", + __func__, eLen + 2); + + if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE " + "Need bigger buffer space"); + VOS_ASSERT(0); + return -ENOMEM; + } + memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2); + pWextState->assocAddIE.length += eLen + 2; + + pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; + pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; + break; + } +#ifdef FEATURE_WLAN_WAPI + case WLAN_EID_WAPI: + pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1 + hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u", + pAdapter->wapi_info.nWapiMode); + tmp = (u16 *)ie; + tmp = tmp + 2; // Skip element Id and Len, Version + akmsuiteCount = WPA_GET_LE16(tmp); + tmp = tmp + 1; + akmlist = (int *)(tmp); + if(akmsuiteCount <= MAX_NUM_AKM_SUITES) + { + memcpy(akmsuite, akmlist, (4*akmsuiteCount)); + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count"); + VOS_ASSERT(0); + return -EINVAL; + } + + if (WAPI_PSK_AKM_SUITE == akmsuite[0]) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK", + __func__); + pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK; + } + if (WAPI_CERT_AKM_SUITE == akmsuite[0]) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE", + __func__); + pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT; + } + break; +#endif + default: + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s Set UNKNOWN IE %X", __func__, elementId); + /* when Unknown IE is received we should break and continue + * to the next IE in the buffer instead we were returning + * so changing this to break */ + break; + } + genie += eLen; + remLen -= eLen; + } + EXIT(); + return 0; +} + +/* + * FUNCTION: hdd_isWPAIEPresent + * Parse the received IE to find the WPA IE + * + */ +static bool hdd_isWPAIEPresent( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + const u8 *ie, +#else + u8 *ie, +#endif + u8 ie_len) +{ + v_U8_t eLen = 0; + v_U16_t remLen = ie_len; + v_U8_t elementId = 0; + + while (remLen >= 2) + { + elementId = *ie++; + eLen = *ie++; + remLen -= 2; + if (eLen > remLen) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: IE length is wrong %d", __func__, eLen); + return FALSE; + } + if ((elementId == DOT11F_EID_WPA) && (remLen > 5)) + { + /* OUI - 0x00 0X50 0XF2 + WPA Information Element - 0x01 + WPA version - 0x01*/ + if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5)) + return TRUE; + } + ie += eLen; + remLen -= eLen; + } + return FALSE; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_set_privacy + * This function is used to initialize the security + * parameters during connect operation. + */ +int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter, + struct cfg80211_connect_params *req + ) +{ + int status = 0; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + ENTER(); + + /*set wpa version*/ + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + + if (req->crypto.wpa_versions) + { + if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA; + } + else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2; + } + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__, + pWextState->wpaVersion); + + /*set authentication type*/ + status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to set authentication type ", __func__); + return status; + } + + /*set key mgmt type*/ + if (req->crypto.n_akm_suites) + { + status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite", + __func__); + return status; + } + } + + /*set pairwise cipher type*/ + if (req->crypto.n_ciphers_pairwise) + { + status = wlan_hdd_cfg80211_set_cipher(pAdapter, + req->crypto.ciphers_pairwise[0], true); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to set unicast cipher type", __func__); + return status; + } + } + else + { + /*Reset previous cipher suite to none*/ + status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true); + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to set unicast cipher type", __func__); + return status; + } + } + + /*set group cipher type*/ + status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group, + false); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type", + __func__); + return status; + } + +#ifdef WLAN_FEATURE_11W + pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED); +#endif + + /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/ + if (req->ie_len) + { + status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len); + if ( 0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE", + __func__); + return status; + } + } + + /*incase of WEP set default key information*/ + if (req->key && req->key_len) + { + if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0]) + || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0]) + ) + { + if ( IW_AUTH_KEY_MGMT_802_1X + == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported", + __func__); + return -EOPNOTSUPP; + } + else + { + u8 key_len = req->key_len; + u8 key_idx = req->key_idx; + + if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len) + && (CSR_MAX_NUM_KEY > key_idx) + ) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: setting default wep key, key_idx = %hu key_len %hu", + __func__, key_idx, key_len); + vos_mem_copy( + &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0], + req->key, key_len); + pWextState->roamProfile.Keys.KeyLength[key_idx] = + (u8)key_len; + pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx; + } + } + } + } + + return status; +} + +/* + * FUNCTION: wlan_hdd_try_disconnect + * This function is used to disconnect from previous + * connection + */ +int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter ) +{ + long ret = 0; + int status, result = 0; + hdd_station_ctx_t *pHddStaCtx; + eMib_dot11DesiredBssType connectedBssType; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType ); + + if((eMib_dot11DesiredBssType_independent == connectedBssType) || + (eConnectionState_Associated == pHddStaCtx->conn_info.connState) || + (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) || + (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)) + { + /* Indicate disconnect to SME so that in-progress connection or preauth + * can be aborted + */ + sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + spin_lock_bh(&pAdapter->lock_for_active_session); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + } + spin_unlock_bh(&pAdapter->lock_for_active_session); + hdd_connSetConnectionState(pHddStaCtx, + eConnectionState_Disconnecting); + /* Issue disconnect to CSR */ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + if(eHAL_STATUS_CMD_NOT_QUEUED == status) { + hddLog(LOG1, + FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect")); + } else if ( 0 != status ) { + hddLog(LOGE, + FL("csrRoamDisconnect failure, returned %d"), + (int)status ); + result = -EINVAL; + goto disconnected; + } + ret = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) { + hddLog(LOGE, + "%s: Failed to disconnect, timed out", __func__); + result = -ETIMEDOUT; + } + } + else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState) + { + ret = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!ret) + { + hddLog(LOGE, FL("Failed to receive disconnect event")); + result = -ETIMEDOUT; + } + } +disconnected: + hddLog(LOG1, + FL("Set HDD connState to eConnectionState_NotConnected")); + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + return result; +} + +/** + * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present + * @adapter: Pointer to the HDD adapter + * @req: Pointer to the structure cfg_connect_params receieved from user space + * + * This function will start reassociation if bssid hint, channel hint and + * previous bssid parameters are present in the connect request + * + * Return: success if reassociation is happening + * Error code if reassociation is not permitted or not happening + */ +#ifdef CFG80211_CONNECT_PREV_BSSID +static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter, + struct cfg80211_connect_params *req) +{ + int status = -EPERM; + if (req->bssid_hint && req->channel_hint && req->prev_bssid) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR), + req->channel_hint->hw_value, + MAC_ADDR_ARRAY(req->bssid_hint)); + status = hdd_reassoc(adapter, req->bssid_hint, + req->channel_hint->hw_value, + CONNECT_CMD_USERSPACE); + } + return status; +} +#else +static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter, + struct cfg80211_connect_params *req) +{ + return -EPERM; +} +#endif + +/** + * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to + * connect in HT20 mode + * @hdd_ctx: hdd context + * @adapter: Pointer to the HDD adapter + * @req: Pointer to the structure cfg_connect_params receieved from user space + * + * This function will check if supplicant has indicated to to connect in HT20 + * mode. this is currently applicable only for 2.4Ghz mode only. + * if feature is enabled and supplicant indicate HT20 set + * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false. + * + * Return: void + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) +static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter, + struct cfg80211_connect_params *req) +{ + hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); + tCsrRoamProfile *roam_profile; + + roam_profile = &wext_state->roamProfile; + roam_profile->force_24ghz_in_ht20 = false; + if (hdd_ctx->cfg_ini->override_ht20_40_24g && + !(req->ht_capa.cap_info & + IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + roam_profile->force_24ghz_in_ht20 = true; + + hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"), + req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g); +} +#else +static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter, + struct cfg80211_connect_params *req) +{ + hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); + tCsrRoamProfile *roam_profile; + + roam_profile = &wext_state->roamProfile; + roam_profile->force_24ghz_in_ht20 = false; +} +#endif + +/* + * FUNCTION: __wlan_hdd_cfg80211_connect + * This function is used to start the association process + */ +static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *req + ) +{ + int status; + u16 channel; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \ + defined(CFG80211_BSSID_HINT_BACKPORT) + const u8 *bssid_hint = req->bssid_hint; +#else + const u8 *bssid_hint = NULL; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev ); + VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL; + hdd_context_t *pHddCtx = NULL; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CONNECT, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: device_mode = %s (%d)", __func__, + hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + status = wlan_hdd_reassoc_bssid_hint(pAdapter, req); + if (0 == status) + return status; + + +#ifdef WLAN_BTAMP_FEATURE + //Infra connect not supported when AMP traffic is on. + if( VOS_TRUE == WLANBAP_AmpSessionOn() ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: No connection when AMP is on", __func__); + return -ECONNREFUSED; + } +#endif + + //If Device Mode is Station Concurrent Sessions Exit BMps + //P2P Mode will be taken care in Open/close adapter + if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + (vos_concurrent_open_sessions_running())) { + exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, + WLAN_HDD_INFRA_STATION); + } + + /*Try disconnecting if already in connected state*/ + status = wlan_hdd_try_disconnect(pAdapter); + if ( 0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing" + " connection")); + return -EALREADY; + } + /* Check for max concurrent connections after doing disconnect if any*/ + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections")); + return -ECONNREFUSED; + } + + /*initialise security parameters*/ + status = wlan_hdd_cfg80211_set_privacy(pAdapter, req); + + if ( 0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params", + __func__); + return status; + } + + if (pHddCtx->spoofMacAddr.isEnabled) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: MAC Spoofing enabled ", __func__); + /* Updating SelfSta Mac Addr in TL which will be used to get staidx + * to fill TxBds for probe request during SSID scan which may happen + * as part of connect command + */ + status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext, + &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent); + if (status != VOS_STATUS_SUCCESS) + return -ECONNREFUSED; + } + + if (req->channel) + channel = req->channel->hw_value; + else + channel = 0; + + /* Abort if any scan is going on */ + status = wlan_hdd_scan_abort(pAdapter); + if (0 != status) + hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed")); + + wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req); + + status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid, + req->ssid_len, req->bssid, + bssid_hint, channel); + + if (0 != status) + { + //ReEnable BMPS if disabled + if((VOS_STATUS_SUCCESS == exitbmpsStatus) && + (NULL != pHddCtx)) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + //ReEnable Bmps and Imps back + hdd_enable_bmps_imps(pHddCtx); + } + hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed")); + return status; + } + pHddCtx->isAmpAllowed = VOS_FALSE; + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *req) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_disconnect + * This function is used to issue a disconnect request to SME + */ +int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason ) +{ + int status, result = 0; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + long ret; + eConnectionState prev_conn_state; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + /* Indicate sme of disconnect so that in progress connection or preauth + * can be aborted + */ + sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + pHddCtx->isAmpAllowed = VOS_TRUE; + + /* Need to apply spin lock before decreasing active sessions + * as there can be chance for double decrement if context switch + * Calls hdd_DisConnectHandler. + */ + + prev_conn_state = pHddStaCtx->conn_info.connState; + + spin_lock_bh(&pAdapter->lock_for_active_session); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + } + hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting ); + spin_unlock_bh(&pAdapter->lock_for_active_session); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL( "Set HDD connState to eConnectionState_Disconnecting" )); + + INIT_COMPLETION(pAdapter->disconnect_comp_var); + + /* + * stop tx queues before deleting STA/BSS context from the firmware. + * tx has to be disabled because the firmware can get busy dropping + * the tx frames after BSS/STA has been deleted and will not send + * back a response resulting in WDI timeout + */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + + /*issue disconnect*/ + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, reason); + if((eHAL_STATUS_CMD_NOT_QUEUED == status) && + prev_conn_state != eConnectionState_Connecting) + { + hddLog(LOG1, + FL("status = %d, already disconnected"), status); + result = 0; + goto disconnected; + } + /* + * Wait here instead of returning directly, this will block the next + * connect command and allow processing of the scan for ssid and + * the previous connect command in CSR. Else we might hit some + * race conditions leading to SME and HDD out of sync. + */ + else if(eHAL_STATUS_CMD_NOT_QUEUED == status) + { + hddLog(LOG1, + FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect")); + } + else if ( 0 != status ) + { + hddLog(LOGE, + FL("csrRoamDisconnect failure, returned %d"), + (int)status); + result = -EINVAL; + goto disconnected; + } + ret = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status)) + { + hddLog(LOGE, + "%s: Failed to disconnect, timed out", __func__); + result = -ETIMEDOUT; + } +disconnected: + hddLog(LOG1, + FL("Set HDD connState to eConnectionState_NotConnected")); + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) + /* Sending disconnect event to userspace for kernel version < 3.11 + * is handled by __cfg80211_disconnect call to __cfg80211_disconnected + */ + hddLog(LOG1, FL("Send disconnected event to userspace")); + + wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true, + WLAN_REASON_UNSPECIFIED); +#endif + + EXIT(); + return result; +} + + +/* + * FUNCTION: __wlan_hdd_cfg80211_disconnect + * This function is used to issue a disconnect request to SME + */ +static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy, + struct net_device *dev, + u16 reason + ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + int status; + tCsrRoamProfile *pRoamProfile; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; +#ifdef FEATURE_WLAN_TDLS + tANI_U8 staIdx; +#endif + + ENTER(); + + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return -EINVAL; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (!pHddStaCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL")); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DISCONNECT, + pAdapter->sessionId, reason)); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d", + __func__, reason); + + if (NULL != pRoamProfile) + { + /*issue disconnect request to SME, if station is in connected state*/ + if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) || + (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)) + { + eCsrRoamDisconnectReason reasonCode = + eCSR_DISCONNECT_REASON_UNSPECIFIED; + hdd_scaninfo_t *pScanInfo; + switch(reason) + { + case WLAN_REASON_MIC_FAILURE: + reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR; + break; + + case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY: + case WLAN_REASON_DISASSOC_AP_BUSY: + case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: + reasonCode = eCSR_DISCONNECT_REASON_DISASSOC; + break; + + case WLAN_REASON_PREV_AUTH_NOT_VALID: + case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: + case WLAN_REASON_DEAUTH_LEAVING: + reasonCode = eCSR_DISCONNECT_REASON_DEAUTH; + break; + + default: + reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED; + break; + } + pScanInfo = &pHddCtx->scan_info; + if (pScanInfo->mScanPending) + { + hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, " + "Aborting Scan"); + hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + wlan_hdd_cancel_existing_remain_on_channel(pAdapter); +#ifdef FEATURE_WLAN_TDLS + /* First clean up the tdls peers if any */ + for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) + { + if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) && + (pHddCtx->tdlsConnInfo[staIdx].staId)) + { + uint8 *mac; + mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR, + __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId, + MAC_ADDR_ARRAY(mac)); + status = sme_DeleteTdlsPeerSta( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + mac); + if (status != eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA")); + return -EPERM; + } + } + } +#endif + + hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"), + reasonCode, + pHddStaCtx->conn_info.connState); + status = wlan_hdd_disconnect(pAdapter, reasonCode); + if ( 0 != status ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s wlan_hdd_disconnect failure, returned %d", + __func__, (int)status ); + return -EINVAL; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API" + "called while in %d state", __func__, + pHddStaCtx->conn_info.connState); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__); + } + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy, + struct net_device *dev, + u16 reason + ) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss + * This function is used to initialize the security + * settings in IBSS mode. + */ +static int wlan_hdd_cfg80211_set_privacy_ibss( + hdd_adapter_t *pAdapter, + struct cfg80211_ibss_params *params + ) +{ + int status = 0; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ENTER(); + + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey)); + + if (params->ie_len && ( NULL != params->ie) ) + { + if (wlan_hdd_cfg80211_get_ie_ptr (params->ie, + params->ie_len, WLAN_EID_RSN )) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2; + encryptionType = eCSR_ENCRYPT_TYPE_AES; + } + else if ( hdd_isWPAIEPresent (params->ie, params->ie_len )) + { + tDot11fIEWPA dot11WPAIE; + tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + u8 *ie; + + memset(&dot11WPAIE, 0, sizeof(dot11WPAIE)); + ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie, + params->ie_len, DOT11F_EID_WPA); + if ( NULL != ie ) + { + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA; + // Unpack the WPA IE + //Skip past the EID byte and length byte - and four byte WiFi OUI + dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, + &ie[2+4], + ie[1] - 4, + &dot11WPAIE); + /*Extract the multicast cipher, the encType for unicast + cipher for wpa-none is none*/ + encryptionType = + hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher); + } + } + + status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len); + + if (0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE", + __func__); + return status; + } + } + + pWextState->roamProfile.AuthType.authType[0] = + pHddStaCtx->conn_info.authType = + eCSR_AUTH_TYPE_OPEN_SYSTEM; + + if (params->privacy) + { + /* Security enabled IBSS, At this time there is no information available + * about the security paramters, so initialise the encryption type to + * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY. + * The correct security parameters will be updated later in + * wlan_hdd_cfg80211_add_key */ + /* Hal expects encryption type to be set inorder + *enable privacy bit in beacons */ + + encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "encryptionType=%d", encryptionType); + pHddStaCtx->conn_info.ucEncryptionType = encryptionType; + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType; + return status; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_join_ibss + * This function is used to create/join an IBSS + */ +static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params + ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile; + int status; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tSirMacAddr bssid; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_JOIN_IBSS, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: device_mode = %s (%d)", __func__, + hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if (NULL == pWextState) + { + hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption", + __func__); + return -EIO; + } + + if (vos_max_concurrent_connections_reached()) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections")); + return -ECONNREFUSED; + } + + /*Try disconnecting if already in connected state*/ + status = wlan_hdd_try_disconnect(pAdapter); + if ( 0 > status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing" + " IBSS connection")); + return -EALREADY; + } + + pRoamProfile = &pWextState->roamProfile; + + if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType ) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s Interface type is not set to IBSS", __func__); + return -EINVAL; + } + + /* BSSID is provided by upper layers hence no need to AUTO generate */ + if (NULL != params->bssid) { + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__); + return -EIO; + } + vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid)); + } + else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0) + { + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__); + return -EIO; + } + + vos_mem_copy((v_U8_t *)bssid, + (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0], + sizeof(bssid)); + } + + /* Set Channel */ + if (NULL != +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + params->chandef.chan) +#else + params->channel) +#endif + { + u8 channelNum; + v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + int indx; + + /* Get channel number */ + channelNum = + ieee80211_frequency_to_channel( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) + params->chandef.chan->center_freq); +#else + params->channel->center_freq); +#endif + + if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + validChan, &numChans)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list", + __func__); + return -EOPNOTSUPP; + } + + for (indx = 0; indx < numChans; indx++) + { + if (channelNum == validChan[indx]) + { + break; + } + } + if (indx >= numChans) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d", + __func__, channelNum); + return -EINVAL; + } + /* Set the Operational Channel */ + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__, + channelNum); + pRoamProfile->ChannelInfo.numOfChannels = 1; + pHddStaCtx->conn_info.operationChannel = channelNum; + pRoamProfile->ChannelInfo.ChannelList = + &pHddStaCtx->conn_info.operationChannel; + } + + /* Initialize security parameters */ + status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params); + if (status < 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters", + __func__); + return status; + } + + /* Issue connect start */ + status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid, + params->ssid_len, (const u8 *)&bssid, NULL, + pHddStaCtx->conn_info.operationChannel); + + if (0 > status) + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__); + + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_ibss_params *params + ) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_leave_ibss + * This function is used to leave an IBSS + */ +static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy, + struct net_device *dev + ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrRoamProfile *pRoamProfile; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status; + eHalStatus hal_status; +#ifdef WLAN_FEATURE_RMC + tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0}; +#endif + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_LEAVE_IBSS, + pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE)); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__, + hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + if (NULL == pWextState) + { + hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption", + __func__); + return -EIO; + } + + pRoamProfile = &pWextState->roamProfile; + + /* Issue disconnect only if interface type is set to IBSS */ + if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType) + { + hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS", + __func__); + return -EINVAL; + } + +#ifdef WLAN_FEATURE_RMC + /* Clearing add IE of beacon */ + if (ccmCfgSetStr(pHddCtx->hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN, + NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__); + return -EINVAL; + } + if (ccmCfgSetInt(pHddCtx->hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL, + eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG", + __func__); + return -EINVAL; + } + + // Reset WNI_CFG_PROBE_RSP Flags + wlan_hdd_reset_prob_rspies(pAdapter); + + if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG", + __func__); + return -EINVAL; + } +#endif + + /* Issue Disconnect request */ + INIT_COMPLETION(pAdapter->disconnect_comp_var); + hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_IBSS_LEAVE); + if (!HAL_STATUS_SUCCESS(hal_status)) { + hddLog(LOGE, + FL("sme_RoamDisconnect failed hal_status(%d)"), + hal_status); + return -EAGAIN; + } + status = wait_for_completion_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (!status) { + hddLog(LOGE, + FL("wait on disconnect_comp_var failed")); + return -ETIMEDOUT; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy, + struct net_device *dev + ) +{ + int ret = 0; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params + * This function is used to set the phy parameters + * (RTS Threshold/FRAG Threshold/Retry Count etc ...) + */ +static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy, + u32 changed) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + tHalHandle hHal = pHddCtx->hHal; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS, + NO_SESSION, wiphy->rts_threshold)); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) + { + u16 rts_threshold = (wiphy->rts_threshold == -1) ? + WNI_CFG_RTS_THRESHOLD_STAMAX : + wiphy->rts_threshold; + + if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) || + (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid RTS Threshold value %hu", + __func__, rts_threshold); + return -EINVAL; + } + + if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, + rts_threshold, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for rts_threshold value %hu", + __func__, rts_threshold); + return -EIO; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__, + rts_threshold); + } + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) + { + u16 frag_threshold = (wiphy->frag_threshold == -1) ? + WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX : + wiphy->frag_threshold; + + if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)|| + (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid frag_threshold value %hu", __func__, + frag_threshold); + return -EINVAL; + } + + if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, + frag_threshold, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for frag_threshold value %hu", + __func__, frag_threshold); + return -EIO; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__, + frag_threshold); + } + + if ((changed & WIPHY_PARAM_RETRY_SHORT) + || (changed & WIPHY_PARAM_RETRY_LONG)) + { + u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ? + wiphy->retry_short : + wiphy->retry_long; + + if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) || + (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu", + __func__, retry_value); + return -EINVAL; + } + + if (changed & WIPHY_PARAM_RETRY_SHORT) + { + if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, + retry_value, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for long retry count %hu", + __func__, retry_value); + return -EIO; + } + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu", + __func__, retry_value); + } + else if (changed & WIPHY_PARAM_RETRY_SHORT) + { + if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, + retry_value, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for short retry count %hu", + __func__, retry_value); + return -EIO; + } + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu", + __func__, retry_value); + } + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy, + u32 changed) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_txpower + * This function is used to set the txpower + */ +static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) + enum tx_power_setting type, +#else + enum nl80211_tx_power_setting type, +#endif + int dbm) +{ + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + tHalHandle hHal = NULL; + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_TXPOWER, + NO_SESSION, type )); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hHal = pHddCtx->hHal; + + if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, + dbm, ccmCfgSetCallback, + eANI_BOOLEAN_TRUE)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm); + return -EIO; + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__, + dbm); + + switch(type) + { + case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/ + /* Fall through */ + case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/ + if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed", + __func__); + return -EIO; + } + break; + case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported", + __func__); + return -EOPNOTSUPP; + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d", + __func__, type); + return -EIO; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) + enum tx_power_setting type, +#else + enum nl80211_tx_power_setting type, +#endif + int dbm) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_txpower(wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + wdev, +#endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35) + type, +#else + type, +#endif + dbm); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_get_txpower + * This function is used to read the txpower + */ +static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif + int *dbm) +{ + + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + int status; + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + *dbm = 0; + return status; + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__); + return -ENOENT; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_GET_TXPOWER, + pAdapter->sessionId, pAdapter->device_mode)); + wlan_hdd_get_classAstats(pAdapter); + *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr; + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + struct wireless_dev *wdev, +#endif + int *dbm) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_txpower(wiphy, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) + wdev, +#endif + dbm); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * wlan_hdd_fill_summary_stats() - populate station_info summary stats + * @stats: summary stats to use as a source + * @info: kernel station_info struct to use as a destination + * + * Return: None + */ +static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats, + struct station_info *info) +{ + int i; + + info->rx_packets = stats->rx_frm_cnt; + info->tx_packets = 0; + info->tx_retries = 0; + info->tx_failed = 0; + + for (i = 0; i < 4; ++i) { + info->tx_packets += stats->tx_frm_cnt[i]; + info->tx_retries += stats->multiple_retry_cnt[i]; + info->tx_failed += stats->fail_cnt[i]; + } + + info->filled |= STATION_INFO_TX_PACKETS | + STATION_INFO_TX_RETRIES | + STATION_INFO_TX_FAILED | + STATION_INFO_RX_PACKETS; +} + +/** + * wlan_hdd_get_sap_stats() - get aggregate SAP stats + * @adapter: sap adapter to get stats for + * @info: kernel station_info struct to populate + * + * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to + * support "station dump" and "station get" for SAP vdevs, even though they + * aren't technically stations. + * + * Return: errno + */ +static int +wlan_hdd_get_sap_stats(hdd_adapter_t *adapter, struct station_info *info) +{ + VOS_STATUS status; + + status = wlan_hdd_get_station_stats(adapter); + if (!VOS_IS_STATUS_SUCCESS(status)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Failed to get SAP stats; status:%d", status); + return 0; + } + + wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info); + + return 0; +} + +static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8* mac, +#else + u8* mac, +#endif + struct station_info *sinfo) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length; + tANI_U32 rate_flags; + + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + hdd_config_t *pCfg = pHddCtx->cfg_ini; + + tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX]; + tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX; + tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; + tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX; + tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET]; + tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET; + tANI_U16 maxRate = 0; + int8_t snr = 0; + tANI_U16 myRate; + tANI_U16 currentRate = 0; + tANI_U8 maxSpeedMCS = 0; + tANI_U8 maxMCSIdx = 0; + tANI_U8 rateFlag = 1; + tANI_U8 i, j, rssidx, mode=0; + tANI_U16 temp; + int status; + +#ifdef WLAN_FEATURE_11AC + tANI_U32 vht_mcs_map; + eDataRate11ACMaxMcs vhtMaxMcs; +#endif /* WLAN_FEATURE_11AC */ + + ENTER(); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if (pAdapter->device_mode == WLAN_HDD_SOFTAP) + return wlan_hdd_get_sap_stats(pAdapter, sinfo); + + if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) || + (0 == ssidlen)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or" + " Invalid ssidlen, %d", __func__, ssidlen); + /*To keep GUI happy*/ + return 0; + } + + if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Roaming in progress, so unable to proceed this request", __func__); + /* return a cached value */ + sinfo->signal = pAdapter->rssi; + return 0; + } + + wlan_hdd_get_station_stats(pAdapter); + rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags; + + wlan_hdd_get_rssi(pAdapter, &sinfo->signal); + wlan_hdd_get_snr(pAdapter, &snr); + pHddStaCtx->conn_info.signal = sinfo->signal; + pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr; + sinfo->filled |= STATION_INFO_SIGNAL; + + /*overwrite rate_flags if MAX link-speed need to be reported*/ + if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) || + (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed && + sinfo->signal >= pCfg->linkSpeedRssiLow)) + { + rate_flags = pAdapter->maxRateFlags; + } + + //convert to the UI units of 100kbps + myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5; + +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("RSSI %d, RLMS %u, rate %d, rssi high %d, rssi mid %d, rssi low %d, rate_flags 0x%x, MCS %d\n", + sinfo->signal, + pCfg->reportMaxLinkSpeed, + myRate, + (int) pCfg->linkSpeedRssiHigh, + (int) pCfg->linkSpeedRssiMid, + (int) pCfg->linkSpeedRssiLow, + (int) rate_flags, + (int) pAdapter->hdd_stats.ClassA_stat.mcs_index); +#endif //LINKSPEED_DEBUG_ENABLED + + if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed) + { + // we do not want to necessarily report the current speed + if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) + { + // report the max possible speed + rssidx = 0; + } + else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed) + { + // report the max possible speed with RSSI scaling + if (sinfo->signal >= pCfg->linkSpeedRssiHigh) + { + // report the max possible speed + rssidx = 0; + } + else if (sinfo->signal >= pCfg->linkSpeedRssiMid) + { + // report middle speed + rssidx = 1; + } + else if (sinfo->signal >= pCfg->linkSpeedRssiLow) + { + // report middle speed + rssidx = 2; + } + else + { + // report actual speed + rssidx = 3; + } + } + else + { + // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid value for reportMaxLinkSpeed: %u", + __func__, pCfg->reportMaxLinkSpeed); + rssidx = 0; + } + + maxRate = 0; + + /* Get Basic Rate Set */ + if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET, + OperationalRates, &ORLeng)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__); + /*To keep GUI happy*/ + return 0; + } + + for (i = 0; i < ORLeng; i++) + { + for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++) + { + /* Validate Rate Set */ + if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F)) + { + currentRate = supported_data_rate[j].supported_rate[rssidx]; + break; + } + } + /* Update MAX rate */ + maxRate = (currentRate > maxRate)?currentRate:maxRate; + } + + /* Get Extended Rate Set */ + if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + ExtendedRates, &ERLeng)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__); + /*To keep GUI happy*/ + return 0; + } + + for (i = 0; i < ERLeng; i++) + { + for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++) + { + if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F)) + { + currentRate = supported_data_rate[j].supported_rate[rssidx]; + break; + } + } + /* Update MAX rate */ + maxRate = (currentRate > maxRate)?currentRate:maxRate; + } + + /* Get MCS Rate Set -- + Only if we are always reporting max speed (or) + if we have good rssi */ + if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY)) + { + if (rate_flags & eHAL_TX_RATE_VHT80) + mode = 2; + else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40)) + mode = 1; + else + mode = 0; + + if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET, + MCSRates, &MCSLeng)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__); + /*To keep GUI happy*/ + return 0; + } + rateFlag = 0; +#ifdef WLAN_FEATURE_11AC + /* VHT80 rate has seperate rate table */ + if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80)) + { + ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map); + vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK ); + if (rate_flags & eHAL_TX_RATE_SGI) + { + rateFlag |= 1; + } + if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs) + { + maxMCSIdx = 7; + } + else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs) + { + maxMCSIdx = 8; + } + else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs) + { + //VHT20 is supporting 0~8 + if (rate_flags & eHAL_TX_RATE_VHT20) + maxMCSIdx = 8; + else + maxMCSIdx = 9; + } + + if (0 != rssidx)/*check for scaled */ + { + //get middle rate MCS index if rssi=1/2 + for (i=0; i <= maxMCSIdx; i++) + { + if (sinfo->signal <= rssiMcsTbl[mode][i]) + { + maxMCSIdx = i; + break; + } + } + } + + if (rate_flags & eHAL_TX_RATE_VHT80) + { + currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag]; + maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag]; + } + else if (rate_flags & eHAL_TX_RATE_VHT40) + { + currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag]; + maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag]; + } + else if (rate_flags & eHAL_TX_RATE_VHT20) + { + currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag]; + maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag]; + } + + maxSpeedMCS = 1; + if (currentRate > maxRate) + { + maxRate = currentRate; + } + + } + else +#endif /* WLAN_FEATURE_11AC */ + { + if (rate_flags & eHAL_TX_RATE_HT40) + { + rateFlag |= 1; + } + if (rate_flags & eHAL_TX_RATE_SGI) + { + rateFlag |= 2; + } + + temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]); + if (rssidx == 1 || rssidx == 2) + { + //get middle rate MCS index if rssi=1/2 + for (i=0; i <= 7; i++) + { + if (sinfo->signal <= rssiMcsTbl[mode][i]) + { + temp = i+1; + break; + } + } + } + + for (i = 0; i < MCSLeng; i++) + { + for (j = 0; j < temp; j++) + { + if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i]) + { + currentRate = supported_mcs_rate[j].supported_rate[rateFlag]; + maxMCSIdx = supported_mcs_rate[j].beacon_rate_index; + break; + } + } + if ((j < temp) && (currentRate > maxRate)) + { + maxRate = currentRate; + } + } + maxSpeedMCS = 1; + } + } + + else if (!(rate_flags & eHAL_TX_RATE_LEGACY)) + { + maxRate = myRate; + maxSpeedMCS = 1; + maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index; + } + // make sure we report a value at least as big as our current rate + if ((maxRate < myRate) || (0 == maxRate)) + { + maxRate = myRate; + if (rate_flags & eHAL_TX_RATE_LEGACY) + { + maxSpeedMCS = 0; + } + else + { + maxSpeedMCS = 1; + maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index; + } + } + + if (rate_flags & eHAL_TX_RATE_LEGACY) + { + sinfo->txrate.legacy = maxRate; +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy); +#endif //LINKSPEED_DEBUG_ENABLED + } + else + { + sinfo->txrate.mcs = maxMCSIdx; +#ifdef WLAN_FEATURE_11AC + sinfo->txrate.nss = 1; + if (rate_flags & eHAL_TX_RATE_VHT80) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; + } + else if (rate_flags & eHAL_TX_RATE_VHT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } + else if (rate_flags & eHAL_TX_RATE_VHT20) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + } +#endif /* WLAN_FEATURE_11AC */ + if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + if (rate_flags & eHAL_TX_RATE_HT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } + } + if (rate_flags & eHAL_TX_RATE_SGI) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + } + +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting MCS rate %d flags %x\n", + sinfo->txrate.mcs, + sinfo->txrate.flags ); +#endif //LINKSPEED_DEBUG_ENABLED + } + } + else + { + // report current rate instead of max rate + + if (rate_flags & eHAL_TX_RATE_LEGACY) + { + //provide to the UI in units of 100kbps + sinfo->txrate.legacy = myRate; +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy); +#endif //LINKSPEED_DEBUG_ENABLED + } + else + { + //must be MCS + sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index; +#ifdef WLAN_FEATURE_11AC + sinfo->txrate.nss = 1; + if (rate_flags & eHAL_TX_RATE_VHT80) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + } + else +#endif /* WLAN_FEATURE_11AC */ + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; + } + if (rate_flags & eHAL_TX_RATE_SGI) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + } + if (rate_flags & eHAL_TX_RATE_HT40) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; + } +#ifdef WLAN_FEATURE_11AC + else if (rate_flags & eHAL_TX_RATE_VHT80) + { + sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; + } +#endif /* WLAN_FEATURE_11AC */ +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("Reporting actual MCS rate %d flags %x\n", + sinfo->txrate.mcs, + sinfo->txrate.flags ); +#endif //LINKSPEED_DEBUG_ENABLED + } + } + sinfo->filled |= STATION_INFO_TX_BITRATE; + + sinfo->tx_packets = + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] + + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] + + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] + + pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3]; + + sinfo->tx_retries = + pAdapter->hdd_stats.summary_stat.retry_cnt[0] + + pAdapter->hdd_stats.summary_stat.retry_cnt[1] + + pAdapter->hdd_stats.summary_stat.retry_cnt[2] + + pAdapter->hdd_stats.summary_stat.retry_cnt[3]; + + sinfo->tx_failed = + pAdapter->hdd_stats.summary_stat.fail_cnt[0] + + pAdapter->hdd_stats.summary_stat.fail_cnt[1] + + pAdapter->hdd_stats.summary_stat.fail_cnt[2] + + pAdapter->hdd_stats.summary_stat.fail_cnt[3]; + + sinfo->filled |= + STATION_INFO_TX_PACKETS | + STATION_INFO_TX_RETRIES | + STATION_INFO_TX_FAILED; + + sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt; + sinfo->filled |= STATION_INFO_RX_PACKETS; + + vos_mem_copy(&pHddStaCtx->conn_info.txrate, + &sinfo->txrate, sizeof(sinfo->txrate)); + if (rate_flags & eHAL_TX_RATE_LEGACY) + hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"), + sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets, + sinfo->rx_packets); + else + hddLog(LOG1, + FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"), + sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags, + sinfo->tx_packets, sinfo->rx_packets); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_GET_STA, + pAdapter->sessionId, maxRate)); + EXIT(); + return 0; +} +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) +static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, + const u8* mac, struct station_info *sinfo) +#else +static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, + u8* mac, struct station_info *sinfo) +#endif +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, bool mode, int timeout) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + VOS_STATUS vos_status; + int status; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__); + return -ENODEV; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT, + pAdapter->sessionId, timeout)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if ((DRIVER_POWER_MODE_AUTO == !mode) && + (TRUE == pHddCtx->hdd_wlan_suspended) && + (pHddCtx->cfg_ini->fhostArpOffload) && + (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + { + + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: in cfg80211_set_power_mgmt, calling arp offload"); + vos_status = hdd_conf_arp_offload(pAdapter, TRUE); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s:Failed to enable ARPOFFLOAD Feature %d", + __func__, vos_status); + } + } + + /**The get power cmd from the supplicant gets updated by the nl only + *on successful execution of the function call + *we are oppositely mapped w.r.t mode in the driver + **/ + vos_status = wlan_hdd_enter_bmps(pAdapter, !mode); + + if (VOS_STATUS_E_FAILURE == vos_status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to enter bmps mode", __func__); + return -EINVAL; + } + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, bool mode, int timeout) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout); + vos_ssr_unprotect(__func__); + + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index) +{ + ENTER(); + return 0; +} + +static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy, + struct net_device *netdev, + u8 key_index) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index); + vos_ssr_unprotect(__func__); + return ret; +} +#endif //LINUX_VERSION_CODE + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +static int __wlan_hdd_set_txq_params(struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_txq_params *params) +{ + ENTER(); + return 0; +} +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int __wlan_hdd_set_txq_params(struct wiphy *wiphy, + struct ieee80211_txq_params *params) +{ + ENTER(); + return 0; +} +#endif //LINUX_VERSION_CODE + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +static int wlan_hdd_set_txq_params(struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_txq_params *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_set_txq_params(wiphy, dev, params); + vos_ssr_unprotect(__func__); + return ret; +} +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +static int wlan_hdd_set_txq_params(struct wiphy *wiphy, + struct ieee80211_txq_params *params) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_set_txq_params(wiphy, params); + vos_ssr_unprotect(__func__); + return ret; +} +#endif + +static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + struct tagCsrDelStaParams *pDelStaParams) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + VOS_STATUS vos_status; + int status; + v_U8_t staId; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + + ENTER(); + + if ( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__); + return -EINVAL; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DEL_STA, + pAdapter->sessionId, pAdapter->device_mode)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode) + || (WLAN_HDD_P2P_GO == pAdapter->device_mode) + ) + { + pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return -ENOENT; + } + if (pHddCtx->cfg_ini->enable_sap_auth_offload) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload"); + pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON; + } + if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr)) + { + v_U16_t i; + for(i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if ((pSapCtx->aStaInfo[i].isUsed) && + (!pSapCtx->aStaInfo[i].isDeauthInProgress)) + { + vos_mem_copy(pDelStaParams->peerMacAddr, + pSapCtx->aStaInfo[i].macAddrSTA.bytes, + ETHER_ADDR_LEN); + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Delete STA with MAC::" + MAC_ADDRESS_STR, + __func__, + MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr)); + vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams); + if (VOS_IS_STATUS_SUCCESS(vos_status)) + pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE; + } + } + } + else + { + + vos_status = hdd_softap_GetStaId(pAdapter, + (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Skip this DEL STA as this is not used::" + MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr)); + return -ENOENT; + } + + if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Skip this DEL STA as deauth is in progress::" + MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr)); + return -ENOENT; + } + + pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Delete STA with MAC::" + MAC_ADDRESS_STR, + __func__, + MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr)); + + vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE; + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: STA removal failed for ::" + MAC_ADDRESS_STR, + __func__, + MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr)); + return -ENOENT; + } + + } + } + + EXIT(); + + return 0; +} + +#ifdef CFG80211_DEL_STA_V2 +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, + struct station_del_parameters *param) +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, const u8 *mac) +#else +int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac) +#endif +#endif +{ + int ret; + struct tagCsrDelStaParams delStaParams; + + vos_ssr_protect(__func__); + +#ifdef CFG80211_DEL_STA_V2 + if (NULL == param) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__); + vos_ssr_unprotect(__func__); + return -EINVAL; + } + + WLANSAP_PopulateDelStaParams(param->mac, param->reason_code, + param->subtype, &delStaParams); + +#else + WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams); +#endif + ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams); + + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *dev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + struct station_parameters *params) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int status = -EPERM; +#ifdef FEATURE_WLAN_TDLS + u32 mask, set; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_ADD_STA, + pAdapter->sessionId, params->listen_interval)); + mask = params->sta_flags_mask; + + set = params->sta_flags_set; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR, + __func__, mask, set, MAC_ADDR_ARRAY(mac)); + + if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL); + } + } +#endif + EXIT(); + return status; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) +static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *dev, const u8 *mac, + struct station_parameters *params) +#else +static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac, struct station_parameters *params) +#endif +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params); + vos_ssr_unprotect(__func__); + + return ret; +} +#ifdef FEATURE_WLAN_LFR + +static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle halHandle; + eHalStatus result; + int status; + hdd_context_t *pHddCtx; + tPmkidCacheInfo pmk_id; + + ENTER(); + + // Validate pAdapter + if ( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__); + return -EINVAL; + } + + if (!pmksa) { + hddLog(LOGE, FL("pmksa is NULL")); + return -EINVAL; + } + + if (!pmksa->bssid || !pmksa->pmkid) { + hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"), + pmksa->bssid, pmksa->pmkid); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pmksa->bssid)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + // Retrieve halHandle + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN); + vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE); + + /* Add to the PMKSA ID Cache in CSR */ + result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId, + &pmk_id, 1, FALSE); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_PMKSA, + pAdapter->sessionId, result)); + + EXIT(); + return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL; +} + +static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle halHandle; + hdd_context_t *pHddCtx; + int status = 0; + + ENTER(); + + /* Validate pAdapter */ + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__); + return -EINVAL; + } + + if (!pmksa) { + hddLog(LOGE, FL("pmksa is NULL")); + return -EINVAL; + } + + if (!pmksa->bssid) { + hddLog(LOGE, FL("pmksa->bssid is NULL")); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pmksa->bssid)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + /*Retrieve halHandle*/ + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DEL_PMKSA, + pAdapter->sessionId, 0)); + /* Delete the PMKID CSR cache */ + if (eHAL_STATUS_SUCCESS != + sme_RoamDelPMKIDfromCache(halHandle, + pAdapter->sessionId, pmksa->bssid, FALSE)) { + hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pmksa->bssid)); + status = -EINVAL; + } + + EXIT(); + return status; +} + + +static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa); + vos_ssr_unprotect(__func__); + + return ret; + +} + +static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle halHandle; + hdd_context_t *pHddCtx; + int status = 0; + + ENTER(); + + /* Validate pAdapter */ + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Adapter" ,__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + /*Retrieve halHandle*/ + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + /* Flush the PMKID cache in CSR */ + if (eHAL_STATUS_SUCCESS != + sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache")); + status = -EINVAL; + } + EXIT(); + return status; +} + +static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211) +static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__); + return -ENODEV; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__); + return -EINVAL; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES, + pAdapter->sessionId, pHddStaCtx->conn_info.connState)); + // Added for debug on reception of Re-assoc Req. + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"), + ftie->ie_len); + hddLog(LOGE, FL("Should be Re-assoc Req IEs")); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__, + ftie->ie_len); +#endif + + // Pass the received FT IEs to SME + sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, + (const u8 *)ftie->ie, + ftie->ie_len); + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_update_ft_ies_params *ftie) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO + +void hdd_cfg80211_sched_scan_done_callback(void *callbackContext, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd) +{ + int ret; + hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext; + hdd_context_t *pHddCtx; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return ; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is Null!!!", __func__); + return ; + } + + spin_lock(&pHddCtx->schedScan_lock); + if (TRUE == pHddCtx->isWiphySuspended) + { + pHddCtx->isSchedScanUpdatePending = TRUE; + spin_unlock(&pHddCtx->schedScan_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Update cfg80211 scan database after it resume", __func__); + return ; + } + spin_unlock(&pHddCtx->schedScan_lock); + + ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter); + + if (0 > ret) + hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__); + else + { + /* Acquire wakelock to handle the case where APP's tries to suspend + * immediatly after the driver gets connect request(i.e after pno) + * from supplicant, this result in app's is suspending and not able + * to process the connect request to AP */ + hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN); + } + cfg80211_sched_scan_results(pHddCtx->wiphy); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: cfg80211 scan result database updated", __func__); +} + +/* + * FUNCTION: wlan_hdd_is_pno_allowed + * Disallow pno if any session is active + */ +static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pTempAdapter = NULL; + hdd_station_ctx_t *pStaCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status = 0; + + if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: PNO is allowed only in STA interface", __func__); + return eHAL_STATUS_FAILURE; + } + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + /* The current firmware design does not allow PNO during any + * active sessions. PNO is allowed only in case when sap session + * is present and sapo auth offload feature enabled in firmare. + */ + while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status)) + { + pTempAdapter = pAdapterNode->pAdapter; + pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter); + + if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode) + && (eConnectionState_NotConnected != pStaCtx->conn_info.connState)) + || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode) + || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode) + || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode && + !pHddCtx->cfg_ini->enable_sap_auth_offload) + || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel) + ) + { + return eHAL_STATUS_FAILURE; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return eHAL_STATUS_SUCCESS; +} + +void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status) +{ + hdd_adapter_t *pAdapter = callbackContext; + hdd_context_t *pHddCtx; + + ENTER(); + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid adapter or adapter has invalid magic")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return; + } + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("PNO enable response status = %d"), status); + pHddCtx->isPnoEnable = FALSE; + } + + pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY; + complete(&pAdapter->pno_comp_var); + EXIT(); +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \ + defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT) +/** + * hdd_config_sched_scan_plan() - configures the sched scan plans + * from the framework. + * @pno_req: pointer to PNO scan request + * @request: pointer to scan request from framework + * + * Return: None + */ +static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req, + struct cfg80211_sched_scan_request *request, + hdd_context_t *hdd_ctx) +{ + v_U32_t i = 0; + + pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans; + for (i = 0; i < request->n_scan_plans; i++) + { + pno_req->scanTimers.aTimerValues[i].uTimerRepeat = + request->scan_plans[i].iterations; + pno_req->scanTimers.aTimerValues[i].uTimerValue = + request->scan_plans[i].interval; + } +} +#else +static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req, + struct cfg80211_sched_scan_request *request, + hdd_context_t *hdd_ctx) +{ + v_U32_t i, temp_int; + /* Driver gets only one time interval which is hardcoded in + * supplicant for 10000ms. Taking power consumption into account 6 + * timers will be used, Timervalue is increased exponentially + * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each + * timer is configurable through INI param gPNOScanTimerRepeatValue. + * If it is set to 0 only one timer will be used and PNO scan cycle + * will be repeated after each interval specified by supplicant + * till PNO is disabled. + */ + if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue) + pno_req->scanTimers.ucScanTimersCount = + HDD_PNO_SCAN_TIMERS_SET_ONE; + else + pno_req->scanTimers.ucScanTimersCount = + HDD_PNO_SCAN_TIMERS_SET_MULTIPLE; + + temp_int = (request->interval)/1000; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Base scan interval = %d PNOScanTimerRepeatValue = %d", + temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue); + for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++) + { + pno_req->scanTimers.aTimerValues[i].uTimerRepeat = + hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue; + pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int; + temp_int *= 2; + } + //Repeat last timer until pno disabled. + pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0; +} +#endif + +/* + * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start + * Function to enable PNO + */ +static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_sched_scan_request *request) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tSirPNOScanReq pnoRequest = {0}; + hdd_context_t *pHddCtx; + tHalHandle hHal; + v_U32_t i, indx, num_ch, j; + u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN; + eHalStatus status = eHAL_STATUS_FAILURE; + int ret = 0; + hdd_config_t *pConfig = NULL; + v_U32_t num_ignore_dfs_ch = 0; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + + if (0 != ret) + { + return -EINVAL; + } + + pConfig = pHddCtx->cfg_ini; + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HAL context is Null!!!", __func__); + return -EINVAL; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START, + pAdapter->sessionId, pAdapter->device_mode)); + ret = wlan_hdd_scan_abort(pAdapter); + if (ret < 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: aborting the existing scan is unsuccessfull", __func__); + return -EBUSY; + } + + if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("Cannot handle sched_scan")); + return -EBUSY; + } + + if (TRUE == pHddCtx->isPnoEnable) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("already PNO is enabled")); + return -EBUSY; + } + + if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: abort ROC failed ", __func__); + return -EBUSY; + } + + pHddCtx->isPnoEnable = TRUE; + + pnoRequest.enable = 1; /*Enable PNO */ + pnoRequest.ucNetworksCount = request->n_match_sets; + + if (( !pnoRequest.ucNetworksCount ) || + ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS )) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Network input is not correct %d Max Network supported is %d", + __func__, pnoRequest.ucNetworksCount, + SIR_PNO_MAX_SUPP_NETWORKS); + ret = -EINVAL; + goto error; + } + + if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Incorrect number of channels %d", + __func__, request->n_channels); + ret = -EINVAL; + goto error; + } + + /* Framework provides one set of channels(all) + * common for all saved profile */ + if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + channels_allowed, &num_channels_allowed)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to get valid channel list", __func__); + ret = -EINVAL; + goto error; + } + /* Checking each channel against allowed channel list */ + num_ch = 0; + if (request->n_channels) + { + char chList [(request->n_channels*5)+1]; + int len; + for (i = 0, len = 0; i < request->n_channels; i++) + { + for (indx = 0; indx < num_channels_allowed; indx++) + { + if (request->channels[i]->hw_value == channels_allowed[indx]) + { + if ((!pConfig->enableDFSPnoChnlScan) && + (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx]))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : Dropping DFS channel : %d", + __func__,channels_allowed[indx]); + num_ignore_dfs_ch++; + break; + } + + valid_ch[num_ch++] = request->channels[i]->hw_value; + len += snprintf(chList+len, 5, "%d ", + request->channels[i]->hw_value); + break ; + } + } + } + hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList); + + /*If all channels are DFS and dropped, then ignore the PNO request*/ + if (num_ignore_dfs_ch == request->n_channels) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : All requested channels are DFS channels", __func__); + ret = -EINVAL; + goto error; + } + } + + pnoRequest.aNetworks = + vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount); + if (pnoRequest.aNetworks == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory aNetworks %u"), + (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount); + goto error; + } + vos_mem_zero(pnoRequest.aNetworks, + sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount); + + /* Filling per profile params */ + for (i = 0; i < pnoRequest.ucNetworksCount; i++) + { + pnoRequest.aNetworks[i].ssId.length = + request->match_sets[i].ssid.ssid_len; + + if (( 0 == pnoRequest.aNetworks[i].ssId.length ) || + ( pnoRequest.aNetworks[i].ssId.length > 32 ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SSID Len %d is not correct for network %d", + __func__, pnoRequest.aNetworks[i].ssId.length, i); + ret = -EINVAL; + goto error; + } + + memcpy(pnoRequest.aNetworks[i].ssId.ssId, + request->match_sets[i].ssid.ssid, + request->match_sets[i].ssid.ssid_len); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: SSID of network %d is %s ", __func__, + i, pnoRequest.aNetworks[i].ssId.ssId); + pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/ + pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/ + pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/ + + /*Copying list of valid channel into request */ + memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch); + pnoRequest.aNetworks[i].ucChannelCount = num_ch; + + pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value + } + + for (i = 0; i < request->n_ssids; i++) + { + j = 0; + while (j < pnoRequest.ucNetworksCount) + { + if ((pnoRequest.aNetworks[j].ssId.length == + request->ssids[i].ssid_len) && + (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId, + request->ssids[i].ssid, + pnoRequest.aNetworks[j].ssId.length))) + { + pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN; + break; + } + j++; + } + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Number of hidden networks being Configured = %d", + request->n_ssids); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "request->ie_len = %zu", request->ie_len); + + pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE); + if (pnoRequest.p24GProbeTemplate == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory p24GProbeTemplate %u"), + SIR_PNO_MAX_PB_REQ_SIZE); + goto error; + } + + pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE); + if (pnoRequest.p5GProbeTemplate == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory p5GProbeTemplate %u"), + SIR_PNO_MAX_PB_REQ_SIZE); + goto error; + } + + vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE); + vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE); + + if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) && + (NULL != request->ie)) + { + pnoRequest.us24GProbeTemplateLen = request->ie_len; + memcpy(pnoRequest.p24GProbeTemplate, request->ie, + pnoRequest.us24GProbeTemplateLen); + + pnoRequest.us5GProbeTemplateLen = request->ie_len; + memcpy(pnoRequest.p5GProbeTemplate, request->ie, + pnoRequest.us5GProbeTemplateLen); + } + + hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx); + + pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE; + + INIT_COMPLETION(pAdapter->pno_comp_var); + pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb; + pnoRequest.callbackContext = pAdapter; + pAdapter->pno_req_status = 0; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d", + pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO, + pnoRequest.scanTimers.ucScanTimersCount); + + status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), + &pnoRequest, pAdapter->sessionId, + hdd_cfg80211_sched_scan_done_callback, pAdapter); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to enable PNO", __func__); + ret = -EINVAL; + goto error; + } + + ret = wait_for_completion_timeout( + &pAdapter->pno_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_PNO)); + if (0 >= ret) + { + // Did not receive the response for PNO enable in time. + // Assuming the PNO enable was success. + // Returning error from here, because we timeout, results + // in side effect of Wifi (Wifi Setting) not to work. + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Timed out waiting for PNO to be Enabled")); + ret = 0; + } + + ret = pAdapter->pno_req_status; + return ret; + +error: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("PNO scanRequest offloaded ret = %d"), ret); + pHddCtx->isPnoEnable = FALSE; + if (pnoRequest.aNetworks) + vos_mem_free(pnoRequest.aNetworks); + if (pnoRequest.p24GProbeTemplate) + vos_mem_free(pnoRequest.p24GProbeTemplate); + if (pnoRequest.p5GProbeTemplate) + vos_mem_free(pnoRequest.p5GProbeTemplate); + + EXIT(); + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_sched_scan_start + * NL interface to enable PNO + */ +static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy, + struct net_device *dev, struct cfg80211_sched_scan_request *request) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop + * Function to disable PNO + */ +static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, + struct net_device *dev) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + tHalHandle hHal; + tSirPNOScanReq pnoRequest = {0}; + int ret = 0; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is Null", __func__); + return -ENODEV; + } + + /* The return 0 is intentional when isLogpInProgress and + * isLoadUnloadInProgress. We did observe a crash due to a return of + * failure in sched_scan_stop , especially for a case where the unload + * of the happens at the same time. The function __cfg80211_stop_sched_scan + * was clearing rdev->sched_scan_req only when the sched_scan_stop returns + * success. If it returns a failure , then its next invocation due to the + * clean up of the second interface will have the dev pointer corresponding + * to the first one leading to a crash. + */ + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + pHddCtx->isPnoEnable = FALSE; + return ret; + } + + if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HAL context is Null!!!", __func__); + return -EINVAL; + } + + pnoRequest.enable = 0; /* Disable PNO */ + pnoRequest.ucNetworksCount = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP, + pAdapter->sessionId, pAdapter->device_mode)); + + INIT_COMPLETION(pAdapter->pno_comp_var); + pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb; + pnoRequest.callbackContext = pAdapter; + pAdapter->pno_req_status = 0; + status = sme_SetPreferredNetworkList(hHal, &pnoRequest, + pAdapter->sessionId, + NULL, pAdapter); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to disabled PNO"); + ret = -EINVAL; + goto error; + } + ret = wait_for_completion_timeout( + &pAdapter->pno_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_PNO)); + if (0 >= ret) + { + // Did not receive the response for PNO disable in time. + // Assuming the PNO disable was success. + // Returning error from here, because we timeout, results + // in side effect of Wifi (Wifi Setting) not to work. + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Timed out waiting for PNO to be disabled")); + ret = 0; + } + + ret = pAdapter->pno_req_status; + pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE; + +error: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("PNO scan disabled ret = %d"), ret); + + EXIT(); + return ret; +} + +/* + * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop + * NL interface to disable PNO + */ +static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy, + struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /*FEATURE_WLAN_SCAN_PNO*/ + + +#ifdef FEATURE_WLAN_TDLS +#if TDLS_MGMT_VERSION2 +static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, + u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) +#else /* TDLS_MGMT_VERSION2 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) +static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + u32 peer_capability, bool initiator, + const u8 *buf, size_t len) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) +static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + u32 peer_capability, const u8 *buf, + size_t len) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) +static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, + u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) +#else +static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, + u8 dialog_token, + u16 status_code, const u8 *buf, + size_t len) +#endif +#endif +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + VOS_STATUS status; + int max_sta_failed = 0; + int responder; + long rc; + int ret; + hddTdlsPeer_t *pTdlsPeer; +#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)) + u32 peer_capability = 0; +#endif + tANI_U16 numCurrTdlsPeers; + hdd_station_ctx_t *pHddStaCtx = NULL; + tdlsCtx_t *pHddTdlsCtx; + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_TDLS_MGMT, + pAdapter->sessionId, action_code)); + + pHddCtx = wiphy_priv(wiphy); + if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid arguments"); + return -EINVAL; + } + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + wlan_hdd_tdls_set_link_status(pAdapter, + peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + return -EBUSY; + } + + if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (!pHddTdlsCtx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pHddTdlsCtx not valid.", __func__); + } + + if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS mode is disabled OR not enabled in FW." + MAC_ADDRESS_STR " action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -ENOTSUPP; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if( NULL == pHddStaCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD station context NULL ",__func__); + return -EINVAL; + } + + /* STA should be connected and authenticated + * before sending any TDLS frames + */ + if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) || + (FALSE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "STA is not connected or unauthenticated. " + "connState %u, uIsAuthenticated %u", + pHddStaCtx->conn_info.connState, + pHddStaCtx->conn_info.uIsAuthenticated); + return -EAGAIN; + } + + /* other than teardown frame, other mgmt frames are not sent if disabled */ + if (SIR_MAC_TDLS_TEARDOWN != action_code) + { + /* if tdls_mode is disabled to respond to peer's request */ + if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR + " TDLS mode is disabled. action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + + return -ENOTSUPP; + } + + if (vos_max_concurrent_connections_reached()) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections")); + return -EINVAL; + } + } + + if (WLAN_IS_TDLS_SETUP_ACTION(action_code)) + { + if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS setup is ongoing. action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -EPERM; + } + } + + if (SIR_MAC_TDLS_SETUP_REQ == action_code || + SIR_MAC_TDLS_SETUP_RSP == action_code ) + { + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers) + { + /* supplicant still sends tdls_mgmt(SETUP_REQ) even after + we return error code at 'add_station()'. Hence we have this + check again in addtion to add_station(). + Anyway, there is no hard to double-check. */ + if (SIR_MAC_TDLS_SETUP_REQ == action_code) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + __func__, MAC_ADDR_ARRAY(peer), action_code, + numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA); + return -EINVAL; + } + else + { + /* maximum reached. tweak to send error code to peer and return + error code to supplicant */ + status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + __func__, MAC_ADDR_ARRAY(peer), status_code, + numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA); + max_sta_failed = -EPERM; + /* fall through to send setup resp with failure status + code */ + } + } + else + { + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer)) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:" MAC_ADDRESS_STR " already connected. action %d declined.", + __func__, MAC_ADDR_ARRAY(peer), action_code); + return -EPERM; + } + mutex_unlock(&pHddCtx->tdls_lock); + } + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu", + "tdls_mgmt", MAC_ADDR_ARRAY(peer), + action_code, dialog_token, status_code, len); + + /*Except teardown responder will not be used so just make 0*/ + responder = 0; + if (SIR_MAC_TDLS_TEARDOWN == action_code) + { + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + + if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer)) + responder = pTdlsPeer->is_responder; + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu", + __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status, + dialog_token, status_code, len); + mutex_unlock(&pHddCtx->tdls_lock); + return -EPERM; + } + mutex_unlock(&pHddCtx->tdls_lock); + } + + /* Discard TDLS setup if peer is removed by user app */ + if ((pHddCtx->cfg_ini->fTDLSExternalControl) && + ((SIR_MAC_TDLS_SETUP_REQ == action_code) || + (SIR_MAC_TDLS_SETUP_CNF == action_code) || + (SIR_MAC_TDLS_DIS_REQ == action_code))) { + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(LOGE, FL("TDLS External Control enabled, but peer " + MAC_ADDRESS_STR " is not forced, so reject the action code %d"), + MAC_ADDR_ARRAY(peer), action_code); + return -EINVAL; + } + mutex_unlock(&pHddCtx->tdls_lock); + } + + /* For explicit trigger of DIS_REQ come out of BMPS for + successfully receiving DIS_RSP from peer. */ + if ((SIR_MAC_TDLS_SETUP_RSP == action_code) || + (SIR_MAC_TDLS_SETUP_CNF== action_code) || + (SIR_MAC_TDLS_DIS_RSP == action_code) || + (SIR_MAC_TDLS_DIS_REQ == action_code)) + { + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Sending frame action_code %u.Disable BMPS", __func__, + action_code); + status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS")); + } else { + pHddTdlsCtx->is_tdls_disabled_bmps = true; + } + } + if (SIR_MAC_TDLS_DIS_REQ != action_code) { + if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities")); + } + } + } + + /* make sure doesn't call send_mgmt() while it is pending */ + if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY", + __func__, MAC_ADDR_ARRAY(peer), action_code); + ret = -EBUSY; + goto tx_failed; + } + + pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC; + INIT_COMPLETION(pAdapter->tdls_mgmt_comp); + + status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peer, action_code, dialog_token, + status_code, peer_capability, (tANI_U8 *)buf, len, + responder); + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_SendTdlsMgmtFrame failed!", __func__); + pAdapter->mgmtTxCompletionStatus = FALSE; + ret = -EINVAL; + goto tx_failed; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__, + WAIT_TIME_TDLS_MGMT); + + rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_MGMT)); + + if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Mgmt Tx Completion failed status %ld TxCompletion %u", + __func__, rc, pAdapter->mgmtTxCompletionStatus); + pAdapter->mgmtTxCompletionStatus = FALSE; + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: LOGP in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + if (rc <= 0) + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + TRUE, TRUE); + + ret = -EINVAL; + goto tx_failed; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Mgmt Tx Completion status %ld TxCompletion %u", + __func__, rc, pAdapter->mgmtTxCompletionStatus); + } + + if (max_sta_failed) + { + ret = max_sta_failed; + goto tx_failed; + } + + if (SIR_MAC_TDLS_SETUP_RSP == action_code) + { + if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response")); + } + } + else if (SIR_MAC_TDLS_SETUP_CNF == action_code) + { + if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response")); + } + } + + return 0; + +tx_failed: + /* add_station will be called before sending TDLS_SETUP_REQ and + * TDLS_SETUP_RSP and as part of add_station driver will enable + * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of + * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled + * as part of processing NL80211_TDLS_DISABLE_LINK. So need to + * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails. + */ + + if ((SIR_MAC_TDLS_SETUP_REQ == action_code) || + (SIR_MAC_TDLS_SETUP_RSP == action_code)) + wlan_hdd_tdls_check_bmps(pAdapter); + return ret; +} + +#if TDLS_MGMT_VERSION2 +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, + u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) +#else /* TDLS_MGMT_VERSION2 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + u32 peer_capability, bool initiator, + const u8 *buf, size_t len) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + const u8 *peer, u8 action_code, + u8 dialog_token, u16 status_code, + u32 peer_capability, const u8 *buf, + size_t len) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, + struct net_device *dev, + u8 *peer, u8 action_code, + u8 dialog_token, + u16 status_code, u32 peer_capability, + const u8 *buf, size_t len) +#else +static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, + u8 *peer, u8 action_code, u8 dialog_token, + u16 status_code, const u8 *buf, size_t len) +#endif +#endif +{ + int ret; + + vos_ssr_protect(__func__); +#if TDLS_MGMT_VERSION2 + ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, + peer_capability, buf, len); +#else /* TDLS_MGMT_VERSION2 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS) + ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, + peer_capability, initiator, + buf, len); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) + ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, + peer_capability, buf, len); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, + peer_capability, buf, len); +#else + ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code, + dialog_token, status_code, buf, len); +#endif +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *peer, +#else + u8 *peer, +#endif + tdls_req_params_t *tdls_peer_params, + cfg80211_exttdls_callback callback) +{ + + hddTdlsPeer_t *pTdlsPeer = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + + if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) || + (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ", + __func__, pHddCtx->cfg_ini->fTDLSExternalControl, + pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger); + return -ENOTSUPP; + } + + /* To cater the requirement of establishing the TDLS link + * irrespective of the data traffic , get an entry of TDLS peer. + */ + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer); + if (pTdlsPeer == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: peer " MAC_ADDRESS_STR " not existing", + __func__, MAC_ADDR_ARRAY(peer)); + mutex_unlock(&pHddCtx->tdls_lock); + return -EINVAL; + } + + /* check FW TDLS Off Channel capability */ + if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) && + (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) && + (NULL != tdls_peer_params)) + { + pTdlsPeer->peerParams.channel = tdls_peer_params->channel; + pTdlsPeer->peerParams.global_operating_class = + tdls_peer_params->global_operating_class; + pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms; + pTdlsPeer->peerParams.min_bandwidth_kbps = + tdls_peer_params->min_bandwidth_kbps; + /* check configured channel is valid, non dfs and + * not current operating channel */ + if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter), + tdls_peer_params->channel)) && + (pHddStaCtx) && + (tdls_peer_params->channel != + pHddStaCtx->conn_info.operationChannel)) + { + pTdlsPeer->isOffChannelConfigured = TRUE; + } + else + { + pTdlsPeer->isOffChannelConfigured = FALSE; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Configured Tdls Off Channel is not valid", __func__); + + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls_off_channel %d isOffChannelConfigured %d " + "current operating channel %d", + __func__, pTdlsPeer->peerParams.channel, + pTdlsPeer->isOffChannelConfigured, + (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0)); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS off channel FW capability %d, " + "host capab %d or Invalid TDLS Peer Params", __func__, + sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL), + pHddCtx->cfg_ini->fEnableTDLSOffChannel); + } + + if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) { + + mutex_unlock(&pHddCtx->tdls_lock); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " %s TDLS Add Force Peer Failed", + __func__); + return -EINVAL; + } + /*EXT TDLS*/ + + if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " %s TDLS set callback Failed", + __func__); + return -EINVAL; + } + + mutex_unlock(&pHddCtx->tdls_lock); + + return(0); + +} + +int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *peer +#else + u8 *peer +#endif +) +{ + + hddTdlsPeer_t *pTdlsPeer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + + if (0 != wlan_hdd_validate_context(pHddCtx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL")); + return -EINVAL; + } + + if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) || + (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ", + __func__, pHddCtx->cfg_ini->fTDLSExternalControl, + pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger); + return -ENOTSUPP; + } + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR + " peer not existing", + __func__, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + else { + wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL, + pTdlsPeer->peerMac); + /* if channel switch is configured, reset + the channel for this peer */ + if (TRUE == pTdlsPeer->isOffChannelConfigured) + { + pTdlsPeer->peerParams.channel = 0; + pTdlsPeer->isOffChannelConfigured = FALSE; + } + } + + if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer")); + return -EINVAL; + } + + /*EXT TDLS*/ + + if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " %s TDLS set callback Failed", + __func__); + return -EINVAL; + } + + mutex_unlock(&pHddCtx->tdls_lock); + + return(0); +} +static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *peer, +#else + u8 *peer, +#endif + enum nl80211_tdls_operation oper) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + int status; + hddTdlsPeer_t *pTdlsPeer; + + ENTER(); + + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return -EINVAL; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_TDLS_OPER, + pAdapter->sessionId, oper)); + if ( NULL == peer ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid arguments", __func__); + return -EINVAL; + } + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + + if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport || + FALSE == sme_IsFeatureSupportedByFW(TDLS)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "TDLS Disabled in INI (%d) OR not enabled in FW (%d) " + "Cannot process TDLS commands", + pHddCtx->cfg_ini->fEnableTDLSSupport, + sme_IsFeatureSupportedByFW(TDLS)); + return -ENOTSUPP; + } + + switch (oper) { + case NL80211_TDLS_ENABLE_LINK: + { + VOS_STATUS status; + long ret; + tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0, + 0, 0, 0, 0, 0, 0, {0}, 0, {0} }; + WLAN_STADescType staDesc; + tANI_U16 numCurrTdlsPeers = 0; + hddTdlsPeer_t *connPeer = NULL; + tANI_U8 suppChannelLen = 0; + tSirMacAddr peerMac; + int channel; + tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + memset(&staDesc, 0, sizeof(staDesc)); + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR + " (oper %d) not exsting. ignored", + __func__, MAC_ADDR_ARRAY(peer), (int)oper); + return -EINVAL; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper", + MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status, + "NL80211_TDLS_ENABLE_LINK"); + + if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u " + MAC_ADDRESS_STR " failed", + __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer)); + mutex_unlock(&pHddCtx->tdls_lock); + return -EINVAL; + } + + /* before starting tdls connection, set tdls + * off channel established status to default value */ + pTdlsPeer->isOffChannelEstablished = FALSE; + + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED); + /* TDLS Off Channel, Disable tdls channel switch, + when there are more than one tdls link */ + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (numCurrTdlsPeers == 2) + { + mutex_lock(&pHddCtx->tdls_lock); + /* get connected peer and send disable tdls off chan */ + connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter); + if ((connPeer) && + (connPeer->isOffChannelSupported == TRUE) && + (connPeer->isOffChannelConfigured == TRUE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: More then one peer connected, Disable " + "TDLS channel switch", __func__); + + connPeer->isOffChannelEstablished = FALSE; + vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr)); + channel = connPeer->peerParams.channel; + + mutex_unlock(&pHddCtx->tdls_lock); + + ret = sme_SendTdlsChanSwitchReq( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + peerMac, + channel, + TDLS_OFF_CHANNEL_BW_OFFSET, + TDLS_CHANNEL_SWITCH_DISABLE); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to send TDLS switch channel request")); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: No TDLS Connected Peer or " + "isOffChannelSupported %d " + "isOffChannelConfigured %d", + __func__, + (connPeer ? (connPeer->isOffChannelSupported) + : -1), + (connPeer ? (connPeer->isOffChannelConfigured) + : -1)); + mutex_unlock(&pHddCtx->tdls_lock); + } + } + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " (oper %d) peer got freed in other context. ignored", + __func__, MAC_ADDR_ARRAY(peer), (int)oper); + return -EINVAL; + } + peer_status = pTdlsPeer->link_status; + mutex_unlock(&pHddCtx->tdls_lock); + + if (eTDLS_LINK_CONNECTED != peer_status) + { + if (IS_ADVANCE_TDLS_ENABLE) { + + if (0 != wlan_hdd_tdls_get_link_establish_params( + pAdapter, peer,&tdlsLinkEstablishParams)) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params")); + return -EINVAL; + } + INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp); + + ret = sme_SendTdlsLinkEstablishParams( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peer, + &tdlsLinkEstablishParams); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params")); + } + /* Send TDLS peer UAPSD capabilities to the firmware and + * register with the TL on after the response for this operation + * is received . + */ + ret = wait_for_completion_interruptible_timeout( + &pAdapter->tdls_link_establish_req_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ)); + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s %d: " MAC_ADDRESS_STR + " (oper %d) peer got freed in other context. ignored", + __func__, __LINE__, MAC_ADDR_ARRAY(peer), + (int)oper); + return -EINVAL; + } + peer_status = pTdlsPeer->link_status; + mutex_unlock(&pHddCtx->tdls_lock); + + if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Link Establish Request Failed Status %ld"), + ret); + return -EINVAL; + } + } + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR + " (oper %d) peer got freed in other context. ignored", + __func__, MAC_ADDR_ARRAY(peer), (int)oper); + return -EINVAL; + } + + wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, + eTDLS_LINK_CONNECTED, + eTDLS_LINK_SUCCESS); + staDesc.ucSTAId = pTdlsPeer->staId; + staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdlsLinkEstablishParams of peer " + MAC_ADDRESS_STR "uapsdQueues: %d" + "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d" + "isResponder: %d peerstaId: %d", + __func__, + MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac), + tdlsLinkEstablishParams.uapsdQueues, + tdlsLinkEstablishParams.qos, + tdlsLinkEstablishParams.maxSp, + tdlsLinkEstablishParams.isBufSta, + tdlsLinkEstablishParams.isOffChannelSupported, + tdlsLinkEstablishParams.isResponder, + pTdlsPeer->staId); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: StaDesc ucSTAId: %d ucQosEnabled: %d", + __func__, + staDesc.ucSTAId, + staDesc.ucQosEnabled); + + ret = WLANTL_UpdateTdlsSTAClient( + pHddCtx->pvosContext, + &staDesc); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params")); + } + + /* Mark TDLS client Authenticated .*/ + status = WLANTL_ChangeSTAState( pHddCtx->pvosContext, + pTdlsPeer->staId, + WLANTL_STA_AUTHENTICATED); + if (VOS_STATUS_SUCCESS == status) + { + if (pTdlsPeer->is_responder == 0) + { + v_U8_t staId = (v_U8_t)pTdlsPeer->staId; + tdlsConnInfo_t *tdlsInfo; + + tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId); + + if (!vos_timer_is_initialized( + &pTdlsPeer->initiatorWaitTimeoutTimer)) + { + /* Initialize initiator wait callback */ + vos_timer_init( + &pTdlsPeer->initiatorWaitTimeoutTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_initiator_wait_cb, + tdlsInfo); + } + wlan_hdd_tdls_timer_restart(pAdapter, + &pTdlsPeer->initiatorWaitTimeoutTimer, + WAIT_TIME_TDLS_INITIATOR); + /* suspend initiator TX until it receives direct packet from the + reponder or WAIT_TIME_TDLS_INITIATOR timer expires */ + ret = WLANTL_SuspendDataTx( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + &staId, NULL); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx")); + } + } + + if ((TRUE == pTdlsPeer->isOffChannelSupported) && + (TRUE == pTdlsPeer->isOffChannelConfigured)) + { + suppChannelLen = + tdlsLinkEstablishParams.supportedChannelsLen; + + if ((suppChannelLen > 0) && + (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS)) + { + tANI_U8 suppPeerChannel = 0; + int i = 0; + for (i = 0U; i < suppChannelLen; i++) + { + suppPeerChannel = + tdlsLinkEstablishParams.supportedChannels[i]; + + pTdlsPeer->isOffChannelSupported = FALSE; + if (suppPeerChannel == + pTdlsPeer->peerParams.channel) + { + pTdlsPeer->isOffChannelSupported = TRUE; + break; + } + } + } + else + { + pTdlsPeer->isOffChannelSupported = FALSE; + } + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS channel switch request for channel " + "%d isOffChannelConfigured %d suppChannelLen " + "%d isOffChannelSupported %d", __func__, + pTdlsPeer->peerParams.channel, + pTdlsPeer->isOffChannelConfigured, + suppChannelLen, + pTdlsPeer->isOffChannelSupported); + + /* TDLS Off Channel, Enable tdls channel switch, + when their is only one tdls link and it supports */ + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if ((numCurrTdlsPeers == 1) && + (TRUE == pTdlsPeer->isOffChannelSupported) && + (TRUE == pTdlsPeer->isOffChannelConfigured)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Send TDLS channel switch request for channel %d", + __func__, pTdlsPeer->peerParams.channel); + + pTdlsPeer->isOffChannelEstablished = TRUE; + vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr)); + channel = pTdlsPeer->peerParams.channel; + + mutex_unlock(&pHddCtx->tdls_lock); + + ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + peerMac, + channel, + TDLS_OFF_CHANNEL_BW_OFFSET, + TDLS_CHANNEL_SWITCH_ENABLE); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req")); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS channel switch request not sent" + " numCurrTdlsPeers %d " + "isOffChannelSupported %d " + "isOffChannelConfigured %d", + __func__, numCurrTdlsPeers, + pTdlsPeer->isOffChannelSupported, + pTdlsPeer->isOffChannelConfigured); + mutex_unlock(&pHddCtx->tdls_lock); + } + + } + else + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_check_bmps(pAdapter); + + /* Update TL about the UAPSD masks , to route the packets to firmware */ + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta) + || pHddCtx->cfg_ini->fTDLSUapsdMask ) + { + int ac; + uint8 ucAc[4] = { WLANTL_AC_VO, + WLANTL_AC_VI, + WLANTL_AC_BK, + WLANTL_AC_BE }; + uint8 tlTid[4] = { 7, 5, 2, 3 } ; + for(ac=0; ac < 4; ac++) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pTdlsPeer->staId, ucAc[ac], + tlTid[ac], tlTid[ac], 0, 0, + WLANTL_BI_DIR ); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC")); + } + } + } + } + + /* stop TCP delack timer if TDLS is enable */ + set_bit(WLAN_TDLS_MODE, &pHddCtx->mode); + hdd_manage_delack_timer(pHddCtx); + hdd_wlan_tdls_enable_link_event(peer, + pTdlsPeer->isOffChannelSupported, + pTdlsPeer->isOffChannelConfigured, + pTdlsPeer->isOffChannelEstablished); + } + break; + case NL80211_TDLS_DISABLE_LINK: + { + tANI_U16 numCurrTdlsPeers = 0; + hddTdlsPeer_t *connPeer = NULL; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peer)); + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + + + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR + " (oper %d) not exsting. ignored", + __func__, MAC_ADDR_ARRAY(peer), (int)oper); + return -EINVAL; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper", + MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status, + "NL80211_TDLS_DISABLE_LINK"); + + if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) + { + long status; + + /* set tdls off channel status to false for this peer */ + pTdlsPeer->isOffChannelEstablished = FALSE; + wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, + eTDLS_LINK_TEARING, + (pTdlsPeer->link_status == eTDLS_LINK_TEARING)? + eTDLS_LINK_UNSPECIFIED: + eTDLS_LINK_DROPPED_BY_REMOTE); + mutex_unlock(&pHddCtx->tdls_lock); + + INIT_COMPLETION(pAdapter->tdls_del_station_comp); + + status = sme_DeleteTdlsPeerSta( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peer ); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA")); + } + + status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA)); + + mutex_lock(&pHddCtx->tdls_lock); + pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE); + if ( NULL == pTdlsPeer ) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR + " peer was freed in other context", + __func__, MAC_ADDR_ARRAY(peer)); + return -EINVAL; + } + + wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + mutex_unlock(&pHddCtx->tdls_lock); + + if (status <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Del station failed status %ld", + __func__, status); + return -EPERM; + } + + /* TDLS Off Channel, Enable tdls channel switch, + when their is only one tdls link and it supports */ + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (numCurrTdlsPeers == 1) + { + tSirMacAddr peerMac; + int channel; + + mutex_lock(&pHddCtx->tdls_lock); + connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter); + + if (connPeer == NULL) { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s connPeer is NULL", __func__); + return -EINVAL; + } + + vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr)); + channel = connPeer->peerParams.channel; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS channel switch " + "isOffChannelSupported %d " + "isOffChannelConfigured %d " + "isOffChannelEstablished %d", + __func__, + (connPeer ? connPeer->isOffChannelSupported : -1), + (connPeer ? connPeer->isOffChannelConfigured : -1), + (connPeer ? connPeer->isOffChannelEstablished : -1)); + + if ((connPeer) && + (connPeer->isOffChannelSupported == TRUE) && + (connPeer->isOffChannelConfigured == TRUE)) + { + connPeer->isOffChannelEstablished = TRUE; + mutex_unlock(&pHddCtx->tdls_lock); + status = sme_SendTdlsChanSwitchReq( + WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + peerMac, + channel, + TDLS_OFF_CHANNEL_BW_OFFSET, + TDLS_CHANNEL_SWITCH_ENABLE); + if (status != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req")); + } + } + else + mutex_unlock(&pHddCtx->tdls_lock); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS channel switch request not sent " + "numCurrTdlsPeers %d ", + __func__, numCurrTdlsPeers); + } + } + else + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS Peer Station doesn't exist.", __func__); + } + if (numCurrTdlsPeers == 0) { + /* start TCP delack timer if TDLS is disable */ + clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode); + hdd_manage_delack_timer(pHddCtx); + } + } + break; + case NL80211_TDLS_TEARDOWN: + { + status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Error in TDLS Teardown")); + return status; + } + break; + } + case NL80211_TDLS_SETUP: + { + status = wlan_hdd_tdls_extctrl_config_peer(pAdapter, + peer, + NULL, + NULL); + + if (0 != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Error in TDLS Setup")); + return status; + } + break; + } + case NL80211_TDLS_DISCOVERY_REQ: + /* We don't support in-driver setup/teardown/discovery */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: Driver doesn't support in-driver setup/teardown/discovery " + ,__func__); + return -ENOTSUPP; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: unsupported event",__func__); + return -ENOTSUPP; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *peer, +#else + u8 *peer, +#endif + enum nl80211_tdls_operation oper) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper); + vos_ssr_unprotect(__func__); + + return ret; +} + +int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy, + struct net_device *dev, u8 *peer) +{ + hddLog(VOS_TRACE_LEVEL_INFO, + "tdls send discover req: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(peer)); +#if TDLS_MGMT_VERSION2 + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0); +#else +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0); +#else + return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, + WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0); +#endif +#endif /* KERNEL_VERSION */ +} +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* + * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback + * Callback rountine called upon receiving response for + * get offload info + */ +void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) +{ + + hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext; + tANI_U8 tempReplayCounter[8]; + hdd_station_ctx_t *pHddStaCtx; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return ; + } + + if (NULL == pGtkOffloadGetInfoRsp) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pGtkOffloadGetInfoRsp is Null", __func__); + return ; + } + + if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: wlan Failed to get replay counter value", + __func__); + return ; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + /* Update replay counter */ + pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter = + pGtkOffloadGetInfoRsp->ullKeyReplayCounter; + + { + /* changing from little to big endian since supplicant + * works on big endian format + */ + int i; + tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter; + + for (i = 0; i < 8; i++) + { + tempReplayCounter[7-i] = (tANI_U8)p[i]; + } + } + + /* Update replay counter to NL */ + cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId, + tempReplayCounter, GFP_KERNEL); +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data + * This function is used to offload GTK rekeying job to the firmware. + */ +int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_gtk_rekey_data *data) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hdd_station_ctx_t *pHddStaCtx; + tHalHandle hHal; + int result; + tSirGtkOffloadParams hddGtkOffloadReqParams; + eHalStatus status = eHAL_STATUS_FAILURE; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA, + pAdapter->sessionId, pAdapter->device_mode)); + + result = wlan_hdd_validate_context(pHddCtx); + if (0 != result) + { + return result; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HAL context is Null!!!", __func__); + return -EAGAIN; + } + + pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE; + memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN); + memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN); + memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId, + WNI_CFG_BSSID_LEN); + { + /* changing from big to little endian since driver + * works on little endian format + */ + tANI_U8 *p = + (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter; + int i; + + for (i = 0; i < 8; i++) + { + p[7-i] = data->replay_ctr[i]; + } + } + + if (TRUE == pHddCtx->hdd_wlan_suspended) + { + /* if wlan is suspended, enable GTK offload directly from here */ + memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams, + sizeof (tSirGtkOffloadParams)); + status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams, + pAdapter->sessionId); + + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_SetGTKOffload failed, returned %d", + __func__, status); + + /* Need to clear any trace of key value in the memory. + * Thus zero out the memory even though it is local + * variable. + */ + vos_mem_zero(&hddGtkOffloadReqParams, + sizeof(hddGtkOffloadReqParams)); + return status; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_SetGTKOffload successfull", __func__); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: wlan not suspended GTKOffload request is stored", + __func__); + } + + /* Need to clear any trace of key value in the memory. + * Thus zero out the memory even though it is local + * variable. + */ + vos_mem_zero(&hddGtkOffloadReqParams, + sizeof(hddGtkOffloadReqParams)); + + EXIT(); + return eHAL_STATUS_SUCCESS; +} + +int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_gtk_rekey_data *data) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /*WLAN_FEATURE_GTK_OFFLOAD*/ +/* + * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl + * This function is used to set access control policy + */ +static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy, + struct net_device *dev, + const struct cfg80211_acl_data *params) +{ + int i; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_hostapd_state_t *pHostapdState; + tsap_Config_t *pConfig; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + if (NULL == params) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: params is Null", __func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pVosContext = pHddCtx->pvosContext; + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + if (NULL == pHostapdState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: pHostapdState is Null", __func__); + return -EINVAL; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d" + "no acl entries = %d", params->acl_policy, params->n_acl_entries); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SET_MAC_ACL, + pAdapter->sessionId, pAdapter->device_mode)); + + if (WLAN_HDD_SOFTAP == pAdapter->device_mode) + { + pConfig = &pAdapter->sessionCtx.ap.sapConfig; + + /* default value */ + pConfig->num_accept_mac = 0; + pConfig->num_deny_mac = 0; + + /** + * access control policy + * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are + * listed in hostapd.deny file. + * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are + * listed in hostapd.accept file. + */ + if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy) + { + pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED; + } + else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy) + { + pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Acl Policy : %d is not supported", + __func__, params->acl_policy); + return -ENOTSUPP; + } + + if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl) + { + pConfig->num_accept_mac = params->n_acl_entries; + for (i = 0; i < params->n_acl_entries; i++) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "** Add ACL MAC entry %i in WhiletList :" + MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(params->mac_addrs[i].addr)); + + vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr, + sizeof(qcmacaddr)); + } + } + else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl) + { + pConfig->num_deny_mac = params->n_acl_entries; + for (i = 0; i < params->n_acl_entries; i++) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "** Add ACL MAC entry %i in BlackList :" + MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(params->mac_addrs[i].addr)); + + vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr, + sizeof(qcmacaddr)); + } + } + + if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SAP Set Mac Acl fail", __func__); + return -EINVAL; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid device_mode = %s (%d)", + __func__, hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + return -EINVAL; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy, + struct net_device *dev, + const struct cfg80211_acl_data *params) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef WLAN_NL80211_TESTMODE +#ifdef FEATURE_WLAN_LPHB +void wlan_hdd_cfg80211_lphb_ind_handler +( + void *pAdapter, + void *indCont +) +{ + tSirLPHBInd *lphbInd; + struct sk_buff *skb; + hdd_context_t *pHddCtxt; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LPHB indication arrived"); + + if (pAdapter == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL\n",__func__); + return; + } + + if (NULL == indCont) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LPHB IND, invalid argument"); + return; + } + + pHddCtxt = (hdd_context_t *)pAdapter; + lphbInd = (tSirLPHBInd *)indCont; + skb = cfg80211_testmode_alloc_event_skb( + pHddCtxt->wiphy, + sizeof(tSirLPHBInd), + GFP_ATOMIC); + if (!skb) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LPHB timeout, NL buffer alloc fail"); + return; + } + + if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN_HDD_TM_ATTR_CMD put fail"); + goto nla_put_failure; + } + if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN_HDD_TM_ATTR_TYPE put fail"); + goto nla_put_failure; + } + if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA, + sizeof(tSirLPHBInd), lphbInd)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WLAN_HDD_TM_ATTR_DATA put fail"); + goto nla_put_failure; + } + cfg80211_testmode_event(skb, GFP_ATOMIC); + return; + +nla_put_failure: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLA Put fail"); + kfree_skb(skb); + + return; +} +#endif /* FEATURE_WLAN_LPHB */ + +static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) +{ + struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1]; + int err = 0; +#ifdef FEATURE_WLAN_LPHB + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + eHalStatus smeStatus; + + ENTER(); + + err = wlan_hdd_validate_context(pHddCtx); + if (0 != err) + { + return err; + } +#endif /* FEATURE_WLAN_LPHB */ + + err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy); + if (err) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Testmode INV ATTR", __func__); + return err; + } + + if (!tb[WLAN_HDD_TM_ATTR_CMD]) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Testmode INV CMD", __func__); + return -EINVAL; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_TESTMODE, + NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))); + switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])) + { +#ifdef FEATURE_WLAN_LPHB + /* Low Power Heartbeat configuration request */ + case WLAN_HDD_TM_CMD_WLAN_HB: + { + int buf_len; + void *buf; + tSirLPHBReq *hb_params = NULL; + tSirLPHBReq *hb_params_temp = NULL; + + if (!tb[WLAN_HDD_TM_ATTR_DATA]) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Testmode INV DATA", __func__); + return -EINVAL; + } + + buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]); + buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]); + + if (buf_len > sizeof(*hb_params)) { + hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"), + buf_len); + return -ERANGE; + } + + hb_params_temp =(tSirLPHBReq *)buf; + if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) && + (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0)) + return -EINVAL; + + hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq)); + if (NULL == hb_params) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s Request Buffer Alloc Fail", __func__); + return -EINVAL; + } + + vos_mem_zero(hb_params, sizeof(tSirLPHBReq)); + vos_mem_copy(hb_params, buf, buf_len); + smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal), + hb_params, + wlan_hdd_cfg80211_lphb_ind_handler); + if (eHAL_STATUS_SUCCESS != smeStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "LPHB Config Fail, disable"); + vos_mem_free(hb_params); + } + return 0; + } +#endif /* FEATURE_WLAN_LPHB */ + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: unsupported event",__func__); + return -EOPNOTSUPP; + } + + EXIT(); + return err; +} + +static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) + struct wireless_dev *wdev, +#endif + void *data, int len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /* CONFIG_NL80211_TESTMODE */ + +extern void hdd_set_wlan_suspend_mode(bool suspend); +static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, + struct net_device *dev, + int idx, struct survey_info *survey) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + tHalHandle halHandle; + v_U32_t channel = 0, freq = 0; /* Initialization Required */ + v_S7_t snr,rssi; + int status, i, j, filled = 0; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + if (NULL == wiphy) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: wiphy is Null", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring || + 0 != pAdapter->survey_idx || + eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + /* The survey dump ops when implemented completely is expected to + * return a survey of all channels and the ops is called by the + * kernel with incremental values of the argument 'idx' till it + * returns -ENONET. But we can only support the survey for the + * operating channel for now. survey_idx is used to track + * that the ops is called only once and then return -ENONET for + * the next iteration + */ + pAdapter->survey_idx = 0; + return -ENONET; + } + + if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Roaming in progress, hence return ", __func__); + return -ENONET; + } + + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + + wlan_hdd_get_snr(pAdapter, &snr); + wlan_hdd_get_rssi(pAdapter, &rssi); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_DUMP_SURVEY, + pAdapter->sessionId, pAdapter->device_mode)); + sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId); + hdd_wlan_get_freq(channel, &freq); + + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + if (NULL == wiphy->bands[i]) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: wiphy->bands[i] is NULL, i = %d", __func__, i); + continue; + } + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + struct ieee80211_supported_band *band = wiphy->bands[i]; + + if (band->channels[j].center_freq == (v_U16_t)freq) + { + survey->channel = &band->channels[j]; + /* The Rx BDs contain SNR values in dB for the received frames + * while the supplicant expects noise. So we calculate and + * return the value of noise (dBm) + * SNR (dB) = RSSI (dBm) - NOISE (dBm) + */ + survey->noise = rssi - snr; + survey->filled = SURVEY_INFO_NOISE_DBM; + filled = 1; + } + } + } + + if (filled) + pAdapter->survey_idx = 1; + else + { + pAdapter->survey_idx = 0; + return -ENONET; + } + + EXIT(); + return 0; +} + +static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, + struct net_device *dev, + int idx, struct survey_info *survey) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_resume_wlan + * this is called when cfg80211 driver resume + * driver updates latest sched_scan scan result(if any) to cfg80211 database + */ +int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + hdd_adapter_t *pAdapter; + hdd_adapter_list_node_t *pAdapterNode, *pNext; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return 0; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN, + NO_SESSION, pHddCtx->isWiphySuspended)); + + if (pHddCtx->is_ap_mode_wow_supported) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Resume SoftAP", __func__); + hdd_set_wlan_suspend_mode(false); + } + + spin_lock(&pHddCtx->schedScan_lock); + pHddCtx->isWiphySuspended = FALSE; + if (TRUE != pHddCtx->isSchedScanUpdatePending) + { + spin_unlock(&pHddCtx->schedScan_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Return resume is not due to PNO indication", __func__); + return 0; + } + // Reset flag to avoid updatating cfg80211 data old results again + pHddCtx->isSchedScanUpdatePending = FALSE; + spin_unlock(&pHddCtx->schedScan_lock); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (NULL != pAdapter) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ) + { + if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: NO SCAN result", __func__); + } + else + { + /* Acquire wakelock to handle the case where APP's tries to + * suspend immediately after updating the scan results. Whis + * results in app's is in suspended state and not able to + * process the connect request to AP + */ + hdd_prevent_suspend_timeout(2000, + WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN); + cfg80211_sched_scan_results(pHddCtx->wiphy); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : cfg80211 scan result database updated", __func__); + + EXIT(); + return 0; + + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Failed to find Adapter", __func__); + EXIT(); + return 0; +} + +int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_resume_wlan(wiphy); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan + * this is called when cfg80211 driver suspends + */ +int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + int ret = 0; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + if (pHddCtx->is_ap_mode_wow_supported) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Suspend SoftAP", __func__); + hdd_set_wlan_suspend_mode(true); + } + + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN, + NO_SESSION, pHddCtx->isWiphySuspended)); + pHddCtx->isWiphySuspended = TRUE; + + EXIT(); + + return 0; +} + +int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef FEATURE_OEM_DATA_SUPPORT +static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx, + void *pMsg, tANI_U32 evLen) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) { + return; + } + if (!pMsg) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null")); + return; + } + + send_oem_data_rsp_msg(evLen, pMsg); + + EXIT(); + return; + +} + +void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType, + void *pMsg, tANI_U32 evLen) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) { + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen); + + switch(evType) { + case SIR_HAL_START_OEM_DATA_RSP_IND_NEW: + wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType); + break; + } + EXIT(); +} +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \ + defined(CFG80211_ABORT_SCAN) +/** + * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api + * @wiphy: Pointer to wiphy + * @wdev: Pointer to wireless device structure + * + * This function is used to abort an ongoing scan + * + * Return: None + */ +static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + int ret; + + ENTER(); + + if (NULL == adapter) { + hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL")); + return; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return; + + wlan_hdd_scan_abort(adapter); + + return; +} + +/** + * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api + * @wiphy: Pointer to wiphy + * @wdev: Pointer to wireless device structure + * + * Return: None + */ +void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + vos_ssr_protect(__func__); + __wlan_hdd_cfg80211_abort_scan(wiphy, wdev); + vos_ssr_unprotect(__func__); + + return; +} +#endif + +/* cfg80211_ops */ +static struct cfg80211_ops wlan_hdd_cfg80211_ops = +{ + .add_virtual_intf = wlan_hdd_add_virtual_intf, + .del_virtual_intf = wlan_hdd_del_virtual_intf, + .change_virtual_intf = wlan_hdd_cfg80211_change_iface, + .change_station = wlan_hdd_change_station, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) + .add_beacon = wlan_hdd_cfg80211_add_beacon, + .del_beacon = wlan_hdd_cfg80211_del_beacon, + .set_beacon = wlan_hdd_cfg80211_set_beacon, +#else + .start_ap = wlan_hdd_cfg80211_start_ap, + .change_beacon = wlan_hdd_cfg80211_change_beacon, + .stop_ap = wlan_hdd_cfg80211_stop_ap, +#endif + .change_bss = wlan_hdd_cfg80211_change_bss, + .add_key = wlan_hdd_cfg80211_add_key, + .get_key = wlan_hdd_cfg80211_get_key, + .del_key = wlan_hdd_cfg80211_del_key, + .set_default_key = wlan_hdd_cfg80211_set_default_key, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + .set_channel = wlan_hdd_cfg80211_set_channel, +#endif + .scan = wlan_hdd_cfg80211_scan, + .connect = wlan_hdd_cfg80211_connect, + .disconnect = wlan_hdd_cfg80211_disconnect, + .join_ibss = wlan_hdd_cfg80211_join_ibss, + .leave_ibss = wlan_hdd_cfg80211_leave_ibss, + .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params, + .set_tx_power = wlan_hdd_cfg80211_set_txpower, + .get_tx_power = wlan_hdd_cfg80211_get_txpower, + .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel, + .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel, + .mgmt_tx = wlan_hdd_mgmt_tx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait, + .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key, + .set_txq_params = wlan_hdd_set_txq_params, +#endif + .get_station = wlan_hdd_cfg80211_get_station, + .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt, + .del_station = wlan_hdd_cfg80211_del_station, + .add_station = wlan_hdd_cfg80211_add_station, +#ifdef FEATURE_WLAN_LFR + .set_pmksa = wlan_hdd_cfg80211_set_pmksa, + .del_pmksa = wlan_hdd_cfg80211_del_pmksa, + .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa, +#endif +#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211) + .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies, +#endif +#ifdef FEATURE_WLAN_TDLS + .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt, + .tdls_oper = wlan_hdd_cfg80211_tdls_oper, +#endif +#ifdef WLAN_FEATURE_GTK_OFFLOAD + .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data, +#endif /* WLAN_FEATURE_GTK_OFFLOAD */ +#ifdef FEATURE_WLAN_SCAN_PNO + .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start, + .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop, +#endif /*FEATURE_WLAN_SCAN_PNO */ + .resume = wlan_hdd_cfg80211_resume_wlan, + .suspend = wlan_hdd_cfg80211_suspend_wlan, + .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl, +#ifdef WLAN_NL80211_TESTMODE + .testmode_cmd = wlan_hdd_cfg80211_testmode, +#endif + .dump_survey = wlan_hdd_cfg80211_dump_survey, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \ + defined(CFG80211_ABORT_SCAN) + .abort_scan = wlan_hdd_cfg80211_abort_scan, +#endif +}; + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_debugfs.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_debugfs.c new file mode 100644 index 000000000000..b53edcc3be58 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_debugfs.c @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WLAN_OPEN_SOURCE +#include +#include +#include + +#define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8 +#define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512 +#define MAX_USER_COMMAND_SIZE_FRAME 4096 + +static ssize_t __wcnss_wowenable_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + char cmd[MAX_USER_COMMAND_SIZE_WOWL_ENABLE + 1]; + char *sptr, *token; + v_U8_t wow_enable = 0; + v_U8_t wow_mp = 0; + v_U8_t wow_pbm = 0; + + ENTER(); + + pAdapter = (hdd_adapter_t *)file->private_data; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return -EINVAL; + } + + if (!sme_IsFeatureSupportedByFW(WOW)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Wake-on-Wireless feature is not supported " + "in firmware!", __func__); + + return -EINVAL; + } + + if (count > MAX_USER_COMMAND_SIZE_WOWL_ENABLE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Command length is larger than %d bytes.", + __func__, MAX_USER_COMMAND_SIZE_WOWL_ENABLE); + + return -EINVAL; + } + + /* Get command from user */ + if (copy_from_user(cmd, buf, count)) + return -EFAULT; + cmd[count] = '\0'; + sptr = cmd; + + /* Get enable or disable wow */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &wow_enable)) + return -EINVAL; + + /* Disable wow */ + if (!wow_enable) { + if (!hdd_exit_wowl(pAdapter, eWOWL_EXIT_USER)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hdd_exit_wowl failed!", __func__); + + return -EFAULT; + } + + return count; + } + + /* Get enable or disable magic packet mode */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &wow_mp)) + return -EINVAL; + if (wow_mp > 1) + wow_mp = 1; + + /* Get enable or disable pattern byte matching mode */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + if (kstrtou8(token, 0, &wow_pbm)) + return -EINVAL; + if (wow_pbm > 1) + wow_pbm = 1; + + if (!hdd_enter_wowl(pAdapter, wow_mp, wow_pbm)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hdd_enter_wowl failed!", __func__); + + return -EFAULT; + } + EXIT(); + return count; +} + +static ssize_t wcnss_wowenable_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + ssize_t ret; + + vos_ssr_protect(__func__); + ret = __wcnss_wowenable_write(file, buf, count, ppos); + vos_ssr_unprotect(__func__); + + return ret; +} + +static ssize_t __wcnss_wowpattern_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + char cmd[MAX_USER_COMMAND_SIZE_WOWL_PATTERN + 1]; + char *sptr, *token; + v_U8_t pattern_idx = 0; + v_U8_t pattern_offset = 0; + char *pattern_buf; + char *pattern_mask; + + ENTER(); + + pAdapter = (hdd_adapter_t *)file->private_data; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return -EINVAL; + } + if (!sme_IsFeatureSupportedByFW(WOW)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Wake-on-Wireless feature is not supported " + "in firmware!", __func__); + + return -EINVAL; + } + + if (count > MAX_USER_COMMAND_SIZE_WOWL_PATTERN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Command length is larger than %d bytes.", + __func__, MAX_USER_COMMAND_SIZE_WOWL_PATTERN); + + return -EINVAL; + } + + /* Get command from user */ + if (copy_from_user(cmd, buf, count)) + return -EFAULT; + cmd[count] = '\0'; + sptr = cmd; + + /* Get pattern idx */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + + if (kstrtou8(token, 0, &pattern_idx)) + return -EINVAL; + + /* Get pattern offset */ + token = strsep(&sptr, " "); + + /* Delete pattern if no further argument */ + if (!token) { + hdd_del_wowl_ptrn_debugfs(pAdapter, pattern_idx); + + return count; + } + + if (kstrtou8(token, 0, &pattern_offset)) + return -EINVAL; + + /* Get pattern */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + + pattern_buf = token; + + /* Get pattern mask */ + token = strsep(&sptr, " "); + if (!token) + return -EINVAL; + + pattern_mask = token; + pattern_mask[strlen(pattern_mask) - 1] = '\0'; + + hdd_add_wowl_ptrn_debugfs(pAdapter, pattern_idx, pattern_offset, + pattern_buf, pattern_mask); + EXIT(); + return count; +} + +static ssize_t wcnss_wowpattern_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + ssize_t ret; + + vos_ssr_protect(__func__); + ret = __wcnss_wowpattern_write(file, buf, count, ppos); + vos_ssr_unprotect(__func__); + + return ret; +} + +static ssize_t __wcnss_patterngen_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams; + tSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams; + char *cmd, *sptr, *token; + v_U8_t pattern_idx = 0; + v_U8_t pattern_duration = 0; + char *pattern_buf; + v_U16_t pattern_len = 0; + v_U16_t i = 0; + + ENTER(); + + pAdapter = (hdd_adapter_t *)file->private_data; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return -EINVAL; + } + + if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Periodic Tx Pattern Offload feature is not supported " + "in firmware!", __func__); + + return -EINVAL; + } + + /* Get command from user */ + if (count <= MAX_USER_COMMAND_SIZE_FRAME) + cmd = vos_mem_malloc(count + 1); + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Command length is larger than %d bytes.", + __func__, MAX_USER_COMMAND_SIZE_FRAME); + + return -EINVAL; + } + + if (!cmd) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for cmd failed!", __func__); + + return -EFAULT; + } + + if (copy_from_user(cmd, buf, count)) + { + vos_mem_free(cmd); + return -EFAULT; + } + cmd[count] = '\0'; + sptr = cmd; + + /* Get pattern idx */ + token = strsep(&sptr, " "); + if (!token) + goto failure; + if (kstrtou8(token, 0, &pattern_idx)) + goto failure; + + if (pattern_idx > (MAXNUM_PERIODIC_TX_PTRNS - 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Pattern index %d is not in the range (0 ~ %d).", + __func__, pattern_idx, MAXNUM_PERIODIC_TX_PTRNS - 1); + + goto failure; + } + + /* Get pattern duration */ + token = strsep(&sptr, " "); + if (!token) + goto failure; + if (kstrtou8(token, 0, &pattern_duration)) + goto failure; + + /* Delete pattern using index if duration is 0 */ + if (!pattern_duration) + { + delPeriodicTxPtrnParams = + vos_mem_malloc(sizeof(tSirDelPeriodicTxPtrn)); + if (!delPeriodicTxPtrnParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for delPeriodicTxPtrnParams " + "failed!", __func__); + + vos_mem_free(cmd); + return -EFAULT; + } + + delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx; + vos_mem_copy(delPeriodicTxPtrnParams->macAddress, + pAdapter->macAddressCurrent.bytes, 6); + + /* Delete pattern */ + if (eHAL_STATUS_SUCCESS != sme_DelPeriodicTxPtrn(pHddCtx->hHal, + delPeriodicTxPtrnParams)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_DelPeriodicTxPtrn() failed!", __func__); + + vos_mem_free(delPeriodicTxPtrnParams); + goto failure; + } + + vos_mem_free(delPeriodicTxPtrnParams); + vos_mem_free(cmd); + return count; + } + + /* Check if it's in connected state only when adding patterns */ + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Not in Connected state!", __func__); + + goto failure; + } + + /* Get pattern */ + token = strsep(&sptr, " "); + if (!token) + goto failure; + + pattern_buf = token; + pattern_buf[strlen(pattern_buf) - 1] = '\0'; + pattern_len = strlen(pattern_buf); + + /* Since the pattern is a hex string, 2 characters represent 1 byte. */ + if (pattern_len % 2) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern!", __func__); + + goto failure; + } + else + pattern_len >>= 1; + + if (pattern_len < 14 || pattern_len > PERIODIC_TX_PTRN_MAX_SIZE) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Not an 802.3 frame!", __func__); + + goto failure; + } + + addPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirAddPeriodicTxPtrn)); + if (!addPeriodicTxPtrnParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation for addPeriodicTxPtrnParams " + "failed!", __func__); + + vos_mem_free(cmd); + return -EFAULT; + } + + addPeriodicTxPtrnParams->ucPtrnId = pattern_idx; + addPeriodicTxPtrnParams->usPtrnIntervalMs = pattern_duration * 500; + addPeriodicTxPtrnParams->ucPtrnSize = pattern_len; + vos_mem_copy(addPeriodicTxPtrnParams->macAddress, + pAdapter->macAddressCurrent.bytes, 6); + + /* Extract the pattern */ + for(i = 0; i < addPeriodicTxPtrnParams->ucPtrnSize; i++) + { + addPeriodicTxPtrnParams->ucPattern[i] = + (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]); + + /* Skip to next byte */ + pattern_buf += 2; + } + + /* Add pattern */ + if (eHAL_STATUS_SUCCESS != sme_AddPeriodicTxPtrn(pHddCtx->hHal, + addPeriodicTxPtrnParams)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AddPeriodicTxPtrn() failed!", __func__); + + vos_mem_free(addPeriodicTxPtrnParams); + goto failure; + } + + vos_mem_free(addPeriodicTxPtrnParams); + vos_mem_free(cmd); + EXIT(); + return count; + +failure: + vos_mem_free(cmd); + return -EINVAL; +} + +static ssize_t wcnss_patterngen_write(struct file *file, + const char __user *buf, size_t count, loff_t *ppos) +{ + ssize_t ret; + + vos_ssr_protect(__func__); + ret = __wcnss_patterngen_write(file, buf, count, ppos); + vos_ssr_unprotect(__func__); + + return ret; + +} + +static int __wcnss_debugfs_open(struct inode *inode, struct file *file) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + + ENTER(); + + pAdapter = (hdd_adapter_t *)file->private_data; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid adapter or adapter has invalid magic.", + __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return -EINVAL; + } + + if (inode->i_private) + { + file->private_data = inode->i_private; + } + EXIT(); + return 0; +} + +static int wcnss_debugfs_open(struct inode *inode, struct file *file) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wcnss_debugfs_open(inode, file); + vos_ssr_unprotect(__func__); + + return ret; +} + +static const struct file_operations fops_wowenable = { + .write = wcnss_wowenable_write, + .open = wcnss_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static const struct file_operations fops_wowpattern = { + .write = wcnss_wowpattern_write, + .open = wcnss_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static const struct file_operations fops_patterngen = { + .write = wcnss_patterngen_write, + .open = wcnss_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +VOS_STATUS hdd_debugfs_init(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->debugfs_phy = debugfs_create_dir("wlan_wcnss", 0); + + if (NULL == pHddCtx->debugfs_phy) + return VOS_STATUS_E_FAILURE; + + if (NULL == debugfs_create_file("wow_enable", S_IRUSR | S_IWUSR, + pHddCtx->debugfs_phy, pAdapter, &fops_wowenable)) + return VOS_STATUS_E_FAILURE; + + if (NULL == debugfs_create_file("wow_pattern", S_IRUSR | S_IWUSR, + pHddCtx->debugfs_phy, pAdapter, &fops_wowpattern)) + return VOS_STATUS_E_FAILURE; + + if (NULL == debugfs_create_file("pattern_gen", S_IRUSR | S_IWUSR, + pHddCtx->debugfs_phy, pAdapter, &fops_patterngen)) + return VOS_STATUS_E_FAILURE; + + return VOS_STATUS_SUCCESS; +} + +void hdd_debugfs_exit(hdd_context_t *pHddCtx) +{ + debugfs_remove_recursive(pHddCtx->debugfs_phy); +} +#endif /* #ifdef WLAN_OPEN_SOURCE */ + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c new file mode 100644 index 000000000000..d715393414b3 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dev_pwr.c @@ -0,0 +1,774 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 03/29/11 tbh Created module. + + ==========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include +#ifdef ANI_BUS_TYPE_PLATFORM +#include +#else +#include +#endif // ANI_BUS_TYP_PLATFORM + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + * Global variables. + *-------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Local variables. + *-------------------------------------------------------------------------*/ +/* Reference VoIP, 100msec delay make disconnect. + * So TX sleep must be less than 100msec + * Every 20msec TX frame will goes out. + * 10 frame means 2seconds TX operation */ +static const hdd_tmLevelAction_t thermalMigrationAction[WLAN_HDD_TM_LEVEL_MAX] = +{ + /* TM Level 0, Do nothing, just normal operaton */ + {1, 0, 0, 0, 0xFFFFF}, + /* Tm Level 1, disable TX AMPDU */ + {0, 0, 0, 0, 0xFFFFF}, + /* TM Level 2, disable AMDPU, + * TX sleep 100msec if TX frame count is larger than 16 during 300msec */ + {0, 0, 100, 300, 16}, + /* TM Level 3, disable AMDPU, + * TX sleep 500msec if TX frame count is larger than 11 during 500msec */ + {0, 0, 500, 500, 11}, + /* TM Level 4, MAX TM level, enter IMPS */ + {0, 1, 1000, 500, 10} +}; + +#ifdef HAVE_WCNSS_SUSPEND_RESUME_NOTIFY +static bool suspend_notify_sent; +#endif + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * hdd_wlan_suspend_resume_event()- send suspend/resume state + * + * @state: suspend/resume state + * + * This Function send send suspend resume state diag event + * + * Return: void. + */ +void hdd_wlan_suspend_resume_event(uint8_t state) +{ + WLAN_VOS_DIAG_EVENT_DEF(suspend_state, + struct vos_event_suspend); + vos_mem_zero( &suspend_state, + sizeof(suspend_state)); + + suspend_state.state= state; + WLAN_VOS_DIAG_EVENT_REPORT(&suspend_state, + EVENT_WLAN_SUSPEND_RESUME); + +} +#endif + + +/*---------------------------------------------------------------------------- + + @brief Function to suspend the wlan driver. + + @param hdd_context_t pHddCtx + Global hdd context + + + @return None + +----------------------------------------------------------------------------*/ +static int wlan_suspend(hdd_context_t* pHddCtx) +{ + long rc = 0; + + pVosSchedContext vosSchedContext = NULL; + + /* Get the global VOSS context */ + vosSchedContext = get_vos_sched_ctxt(); + + if(!vosSchedContext) { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_FATAL,"%s: Global VOS_SCHED context is Null",__func__); + return 0; + } + + if (!pHddCtx->last_suspend_success) + pHddCtx->last_suspend_success = vos_timer_get_system_time(); + + if (!vos_is_apps_power_collapse_allowed(pHddCtx)) + { + /* Fail this suspend */ + pHddCtx->continuous_suspend_fail_cnt++; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("Fail wlan suspend: not in IMPS/BMPS, continuous Failcnt %d"), + pHddCtx->continuous_suspend_fail_cnt); + + /* call fatal event if power collapse fails for + * WLAN_POWER_COLLAPSE_FAIL_THRESHOLD time. + */ + if ((vos_timer_get_system_time() - pHddCtx->last_suspend_success) >= + WLAN_POWER_COLLAPSE_FAIL_THRESHOLD) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Current time: %lu Last suspend fail time: %lu continuous fail count: %d"), + vos_timer_get_system_time(), pHddCtx->last_suspend_success, + pHddCtx->continuous_suspend_fail_cnt); + pHddCtx->last_suspend_success = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, + FALSE, TRUE); + } + return -EPERM; + } + pHddCtx->continuous_suspend_fail_cnt = 0; + /* + Suspending MC Thread, Rx Thread and Tx Thread as the platform driver is going to Suspend. + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Suspending Mc, Rx and Tx Threads",__func__); + + INIT_COMPLETION(pHddCtx->tx_sus_event_var); + + /* Indicate Tx Thread to Suspend */ + set_bit(TX_SUSPEND_EVENT, &vosSchedContext->txEventFlag); + + wake_up_interruptible(&vosSchedContext->txWaitQueue); + + /* Wait for Suspend Confirmation from Tx Thread */ + rc = wait_for_completion_interruptible_timeout(&pHddCtx->tx_sus_event_var, msecs_to_jiffies(200)); + + if (rc <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: TX Thread: timeout while suspending %ld" + , __func__, rc); + /* There is a race condition here, where the TX Thread can process the + * SUSPEND_EVENT even after the wait_for_completion has timed out. + * Check the SUSPEND_EVENT_MASK, if it is already cleared by the TX + * Thread then it means it is going to suspend, so do not return failure + * from here. + */ + if (!test_and_clear_bit(TX_SUSPEND_EVENT, + &vosSchedContext->txEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TX Thread: will still suspend", __func__); + goto tx_suspend; + } + /* call fatal event if suspend for + * WLAN_POWER_COLLAPSE_FAIL_THRESHOLD time. + */ + if ((vos_timer_get_system_time() - pHddCtx->last_suspend_success) >= + WLAN_POWER_COLLAPSE_FAIL_THRESHOLD) + { + pHddCtx->last_suspend_success = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, + FALSE, TRUE); + } + return -ETIME; + } + +tx_suspend: + /* Set the Tx Thread as Suspended */ + pHddCtx->isTxThreadSuspended = TRUE; + + INIT_COMPLETION(pHddCtx->rx_sus_event_var); + + /* Indicate Rx Thread to Suspend */ + set_bit(RX_SUSPEND_EVENT, &vosSchedContext->rxEventFlag); + + wake_up_interruptible(&vosSchedContext->rxWaitQueue); + + /* Wait for Suspend Confirmation from Rx Thread */ + rc = wait_for_completion_interruptible_timeout(&pHddCtx->rx_sus_event_var, msecs_to_jiffies(200)); + + if (rc <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: RX Thread: timeout while suspending %ld", __func__, rc); + /* There is a race condition here, where the RX Thread can process the + * SUSPEND_EVENT even after the wait_for_completion has timed out. + * Check the SUSPEND_EVENT_MASK, if it is already cleared by the RX + * Thread then it means it is going to suspend, so do not return failure + * from here. + */ + if (!test_and_clear_bit(RX_SUSPEND_EVENT, + &vosSchedContext->rxEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: RX Thread: will still suspend", __func__); + goto rx_suspend; + } + + /* Indicate Tx Thread to Resume */ + complete(&vosSchedContext->ResumeTxEvent); + + /* Set the Tx Thread as Resumed */ + pHddCtx->isTxThreadSuspended = FALSE; + /* call fatal event if suspend for + * WLAN_POWER_COLLAPSE_FAIL_THRESHOLD time. + */ + if ((vos_timer_get_system_time() - pHddCtx->last_suspend_success) >= + WLAN_POWER_COLLAPSE_FAIL_THRESHOLD) + { + pHddCtx->last_suspend_success = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, + FALSE, TRUE); + } + + return -ETIME; + } + +rx_suspend: + /* Set the Rx Thread as Suspended */ + pHddCtx->isRxThreadSuspended = TRUE; + + INIT_COMPLETION(pHddCtx->mc_sus_event_var); + + /* Indicate MC Thread to Suspend */ + set_bit(MC_SUSPEND_EVENT, &vosSchedContext->mcEventFlag); + + wake_up_interruptible(&vosSchedContext->mcWaitQueue); + + /* Wait for Suspend Confirmation from MC Thread */ + rc = wait_for_completion_interruptible_timeout(&pHddCtx->mc_sus_event_var, + msecs_to_jiffies(200)); + + if (rc <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: MC Thread: timeout while suspending %ld", + __func__, rc); + /* There is a race condition here, where the MC Thread can process the + * SUSPEND_EVENT even after the wait_for_completion has timed out. + * Check the SUSPEND_EVENT_MASK, if it is already cleared by the MC + * Thread then it means it is going to suspend, so do not return failure + * from here. + */ + if (!test_and_clear_bit(MC_SUSPEND_EVENT, + &vosSchedContext->mcEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: MC Thread: will still suspend", __func__); + goto mc_suspend; + } + + /* Indicate Rx Thread to Resume */ + complete(&vosSchedContext->ResumeRxEvent); + + /* Set the Rx Thread as Resumed */ + pHddCtx->isRxThreadSuspended = FALSE; + + /* Indicate Tx Thread to Resume */ + complete(&vosSchedContext->ResumeTxEvent); + + /* Set the Tx Thread as Resumed */ + pHddCtx->isTxThreadSuspended = FALSE; + + /* call fatal event if suspend for + * WLAN_POWER_COLLAPSE_FAIL_THRESHOLD time. + */ + if ((vos_timer_get_system_time() - pHddCtx->last_suspend_success) >= + WLAN_POWER_COLLAPSE_FAIL_THRESHOLD) + { + pHddCtx->last_suspend_success = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, + FALSE, TRUE); + } + + return -ETIME; + } + +mc_suspend: + /* Set the Mc Thread as Suspended */ + pHddCtx->isMcThreadSuspended = TRUE; + + /* Set the Station state as Suspended */ + pHddCtx->isWlanSuspended = TRUE; + pHddCtx->last_suspend_success = 0; + pHddCtx->rx_wow_dump = true; + hdd_wlan_suspend_resume_event(HDD_WLAN_SUSPEND); + return 0; +} + +/*---------------------------------------------------------------------------- + + @brief Function to resume the wlan driver. + + @param hdd_context_t pHddCtx + Global hdd context + + + @return None + +----------------------------------------------------------------------------*/ +static void wlan_resume(hdd_context_t* pHddCtx) +{ + pVosSchedContext vosSchedContext = NULL; + + //Get the global VOSS context. + vosSchedContext = get_vos_sched_ctxt(); + + if(!vosSchedContext) { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_FATAL,"%s: Global VOS_SCHED context is Null",__func__); + return; + } + + /* + Resuming Mc, Rx and Tx Thread as platform Driver is resuming. + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Resuming Mc, Rx and Tx Thread",__func__); + + /* Indicate MC Thread to Resume */ + complete(&vosSchedContext->ResumeMcEvent); + + /* Set the Mc Thread as Resumed */ + pHddCtx->isMcThreadSuspended = FALSE; + + /* Indicate Rx Thread to Resume */ + complete(&vosSchedContext->ResumeRxEvent); + + /* Set the Rx Thread as Resumed */ + pHddCtx->isRxThreadSuspended = FALSE; + + /* Indicate Tx Thread to Resume */ + complete(&vosSchedContext->ResumeTxEvent); + + /* Set the Tx Thread as Resumed */ + pHddCtx->isTxThreadSuspended = FALSE; + + /* Set the Station state as Suspended */ + pHddCtx->isWlanSuspended = FALSE; + hdd_wlan_suspend_resume_event(HDD_WLAN_RESUME); +} + +/*---------------------------------------------------------------------------- + + @brief Function to suspend the wlan driver. + This function will get called by platform driver Suspend on System Suspend + + @param dev platform_func_device + + + @return None + +----------------------------------------------------------------------------*/ +int __hddDevSuspendHdlr(struct device *dev) +{ + int ret = 0; + hdd_context_t* pHddCtx = NULL; + + ENTER(); + + pHddCtx = (hdd_context_t*)wcnss_wlan_get_drvdata(dev); + + /* Get the HDD context */ + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + if(pHddCtx->isWlanSuspended == TRUE) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_FATAL,"%s: WLAN is already in suspended state",__func__); + return 0; + } + + /* Suspend the wlan driver */ + ret = wlan_suspend(pHddCtx); + if(ret != 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_FATAL,"%s: Not able to suspend wlan",__func__); + return ret; + } + +#ifdef HAVE_WCNSS_SUSPEND_RESUME_NOTIFY + if(hdd_is_suspend_notify_allowed(pHddCtx)) + { + wcnss_suspend_notify(); + suspend_notify_sent = true; + } +#endif + + EXIT(); + return 0; +} + +int hddDevSuspendHdlr(struct device *dev) +{ + int ret; + vos_ssr_protect(__func__); + ret = __hddDevSuspendHdlr(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +/*---------------------------------------------------------------------------- + + @brief Function to resume the wlan driver. + This function will get called by platform driver Resume on System Resume + + @param dev platform_func_device + + + @return None + +----------------------------------------------------------------------------*/ +int __hddDevResumeHdlr(struct device *dev) +{ + hdd_context_t* pHddCtx = NULL; + int ret = 0; + + ENTER(); + + pHddCtx = (hdd_context_t*)wcnss_wlan_get_drvdata(dev); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + if(pHddCtx->isWlanSuspended != TRUE) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_FATAL,"%s: WLAN is already in resumed state",__func__); + return 0; + } + + /* Resume the wlan driver */ + wlan_resume(pHddCtx); +#ifdef HAVE_WCNSS_SUSPEND_RESUME_NOTIFY + if(suspend_notify_sent == true) + { + wcnss_resume_notify(); + suspend_notify_sent = false; + } +#endif + EXIT(); + return 0; +} + +int hddDevResumeHdlr(struct device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hddDevResumeHdlr(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +static const struct dev_pm_ops pm_ops = { + .suspend = hddDevSuspendHdlr, + .resume = hddDevResumeHdlr, +}; + +/*---------------------------------------------------------------------------- + * + + @brief Registration function. + Register suspend, resume callback functions with platform driver. + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddRegisterPmOps(hdd_context_t *pHddCtx) +{ + wcnss_wlan_register_pm_ops(pHddCtx->parent_dev, &pm_ops); + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + @brief De-registration function. + Deregister the suspend, resume callback functions with platform driver + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS De-Registration Success + VOS_STATUS_E_FAILURE De-Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDeregisterPmOps(hdd_context_t *pHddCtx) +{ + wcnss_wlan_unregister_pm_ops(pHddCtx->parent_dev, &pm_ops); + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + @brief TX frame block timeout handler + Resume TX, and reset TX frame count + + @param hdd_context_t pHddCtx + Global hdd context + + @return NONE + +----------------------------------------------------------------------------*/ +void hddDevTmTxBlockTimeoutHandler(void *usrData) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)usrData; + hdd_adapter_t *staAdapater; + + ENTER(); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + staAdapater = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + + if ((NULL == staAdapater) || (WLAN_HDD_ADAPTER_MAGIC != staAdapater->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + FL("invalid Adapter %p"), staAdapater); + VOS_ASSERT(0); + return; + } + + if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Acquire lock fail", __func__); + return; + } + pHddCtx->tmInfo.txFrameCount = 0; + + /* Resume TX flow */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_wake_all_queues(staAdapater->dev); + pHddCtx->tmInfo.qBlocked = VOS_FALSE; + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + + EXIT(); + return; +} + +/*---------------------------------------------------------------------------- + + @brief TM Level Change handler + Received Tm Level changed notification + + @param dev : Device context + changedTmLevel : Changed new TM level + + @return + +----------------------------------------------------------------------------*/ +void hddDevTmLevelChangedHandler(struct device *dev, int changedTmLevel) +{ + hdd_context_t *pHddCtx = NULL; + WLAN_TmLevelEnumType newTmLevel = changedTmLevel; + hdd_adapter_t *staAdapater; + + pHddCtx = (hdd_context_t*)wcnss_wlan_get_drvdata(dev); + + if ((pHddCtx->tmInfo.currentTmLevel == newTmLevel) || + (!pHddCtx->cfg_ini->thermalMitigationEnable)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_WARN, + "%s: TM Not enabled %d or Level does not changed %d", + __func__, pHddCtx->cfg_ini->thermalMitigationEnable, newTmLevel); + /* TM Level does not changed, + * Or feature does not enabled + * do nothing */ + return; + } + + /* Only STA mode support TM now + * all other mode, TM feature should be disabled */ + if (~VOS_STA & pHddCtx->concurrency_mode) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: CMODE 0x%x, TM disable", + __func__, pHddCtx->concurrency_mode); + newTmLevel = WLAN_HDD_TM_LEVEL_0; + } + + if ((newTmLevel < WLAN_HDD_TM_LEVEL_0) || + (newTmLevel >= WLAN_HDD_TM_LEVEL_MAX)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: TM level %d out of range", + __func__, newTmLevel); + return; + } + + if (newTmLevel != WLAN_HDD_TM_LEVEL_4) + sme_SetTmLevel(pHddCtx->hHal, newTmLevel, 0); + + if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Acquire lock fail", __func__); + return; + } + + pHddCtx->tmInfo.currentTmLevel = newTmLevel; + pHddCtx->tmInfo.txFrameCount = 0; + vos_mem_copy(&pHddCtx->tmInfo.tmAction, + &thermalMigrationAction[newTmLevel], + sizeof(hdd_tmLevelAction_t)); + + + if (pHddCtx->tmInfo.tmAction.enterImps) + { + staAdapater = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (staAdapater) + { + if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(staAdapater))) + { + sme_RoamDisconnect(pHddCtx->hHal, + staAdapater->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } + } + + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + + return; +} + +/*---------------------------------------------------------------------------- + + @brief Register function + Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Registration Success + VOS_STATUS_E_FAILURE Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmRegisterNotifyCallback(hdd_context_t *pHddCtx) +{ + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO, + "%s: Register TM Handler", __func__); + + wcnss_register_thermal_mitigation(pHddCtx->parent_dev ,hddDevTmLevelChangedHandler); + + /* Set Default TM Level as Lowest, do nothing */ + pHddCtx->tmInfo.currentTmLevel = WLAN_HDD_TM_LEVEL_0; + vos_mem_zero(&pHddCtx->tmInfo.tmAction, sizeof(hdd_tmLevelAction_t)); + vos_timer_init(&pHddCtx->tmInfo.txSleepTimer, + VOS_TIMER_TYPE_SW, + hddDevTmTxBlockTimeoutHandler, + (void *)pHddCtx); + mutex_init(&pHddCtx->tmInfo.tmOperationLock); + pHddCtx->tmInfo.txFrameCount = 0; + pHddCtx->tmInfo.blockedQueue = NULL; + pHddCtx->tmInfo.qBlocked = VOS_FALSE; + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + @brief Un-Register function + Un-Register Thermal Mitigation Level Changed handle callback function + + @param hdd_context_t pHddCtx + Global hdd context + + @return General status code + VOS_STATUS_SUCCESS Un-Registration Success + VOS_STATUS_E_FAILURE Un-Registration Fail + +----------------------------------------------------------------------------*/ +VOS_STATUS hddDevTmUnregisterNotifyCallback(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + wcnss_unregister_thermal_mitigation(hddDevTmLevelChangedHandler); + + if(VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer)) + { + vosStatus = vos_timer_stop(&pHddCtx->tmInfo.txSleepTimer); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timer stop fail", __func__); + } + } + + // Destroy the vos timer... + vosStatus = vos_timer_destroy(&pHddCtx->tmInfo.txSleepTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "%s: Fail to destroy timer", __func__); + } + + return VOS_STATUS_SUCCESS; +} + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dp_utils.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dp_utils.c new file mode 100644 index 000000000000..7a18c4e773d8 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_dp_utils.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + wlan_hdd_dp_utils.c + + \brief Utility functions for data path module + + Description... + + ==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include + +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Function declarations and documenation + ----------------------------------------------------------------------------*/ + + +VOS_STATUS hdd_list_insert_front( hdd_list_t *pList, hdd_list_node_t *pNode ) +{ + list_add( pNode, &pList->anchor ); + pList->count++; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_insert_back( hdd_list_t *pList, hdd_list_node_t *pNode ) +{ + list_add_tail( pNode, &pList->anchor ); + pList->count++; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_insert_back_size( hdd_list_t *pList, hdd_list_node_t *pNode, v_SIZE_t *pSize ) +{ + list_add_tail( pNode, &pList->anchor ); + pList->count++; + *pSize = pList->count; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_remove_front( hdd_list_t *pList, hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.next; + *ppNode = listptr; + list_del(pList->anchor.next); + pList->count--; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_remove_back( hdd_list_t *pList, hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.prev; + *ppNode = listptr; + list_del(pList->anchor.prev); + pList->count--; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_remove_node( hdd_list_t *pList, + hdd_list_node_t *pNodeToRemove ) +{ + hdd_list_node_t *tmp; + int found = 0; + + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + // verify that pNodeToRemove is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNodeToRemove) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_del(pNodeToRemove); + pList->count--; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_peek_front( hdd_list_t *pList, + hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + if ( list_empty( &pList->anchor ) ) + { + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.next; + *ppNode = listptr; + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_list_peek_next( hdd_list_t *pList, hdd_list_node_t *pNode, + hdd_list_node_t **ppNode ) +{ + struct list_head * listptr; + int found = 0; + hdd_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL)) + { + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + + if (found == 0) + { + return VOS_STATUS_E_INVAL; + } + + listptr = pNode->next; + if (listptr == &pList->anchor) + { + return VOS_STATUS_E_EMPTY; + } + + *ppNode = listptr; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ) +{ + int i; + int k; + char temp[3] = {0}; + int rv; + + //18 is MAC Address length plus the colons + if ( !pSrcMac && (length > 18 || length < 18) ) + { + return VOS_STATUS_E_FAILURE; + } + i = k = 0; + while ( i < length ) + { + memcpy(temp, pSrcMac+i, 2); + rv = kstrtou8(temp, 16, &pDescMac[k++]); + if (rv < 0) + return VOS_STATUS_E_FAILURE; + i += 3; + } + + return VOS_STATUS_SUCCESS; +} + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c new file mode 100644 index 000000000000..c14890ccb2e2 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -0,0 +1,2857 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= +* wlan_hdd_early_suspend.c +* +* \brief power management functions +* +* Description +* +==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- +* Include files +* ----------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include + +#include "halTypes.h" +#include "sme_Api.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_qct_wda.h" + +#include +#include +#include "cfgApi.h" +#include + +#ifdef WLAN_BTAMP_FEATURE +#include "bapApi.h" +#include "bap_hdd_main.h" +#include "bap_hdd_misc.h" +#endif + +#include +#include +#include +#include +#include +/**----------------------------------------------------------------------------- +* Preprocessor definitions and constants +* ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- +* Type declarations +* ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- +* Function and variables declarations +* ----------------------------------------------------------------------------*/ +#include "wlan_hdd_power.h" +#include "wlan_hdd_packet_filtering.h" + +#define HDD_SSR_BRING_UP_TIME 180000 +#define NS_DEFAULT_SLOT_INDEX 4 +#define NS_EXTENDED_SLOT_INDEX 18 + +static eHalStatus g_full_pwr_status; +static eHalStatus g_standby_status; + +extern VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx); +extern void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter); + +extern struct notifier_block hdd_netdev_notifier; +extern tVOS_CON_MODE hdd_get_conparam ( void ); + +static struct timer_list ssr_timer; +static bool ssr_timer_started; + +void inline check_and_set_suspend_resume_mcbc_filter(hdd_context_t *pHddCtx) +{ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: sus_res_mcbc_filter_valid: %d sus_res_mcbc_filter: %d configuredMcBcFilter: %d"), + pHddCtx->sus_res_mcastbcast_filter_valid, + pHddCtx->sus_res_mcastbcast_filter, + pHddCtx->configuredMcastBcastFilter); + if ( VOS_FALSE == pHddCtx->sus_res_mcastbcast_filter_valid) + { + pHddCtx->sus_res_mcastbcast_filter = + pHddCtx->configuredMcastBcastFilter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: saving sus_res_mcastbcast_filter = %d"), + pHddCtx->sus_res_mcastbcast_filter); + } +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * hdd_wlan_offload_event()- send offloads event + * + * @type: offload type + * @state: enabled or disabled + * + * This Function send offloads enable/disable diag event + * + * Return: void. + */ + +void hdd_wlan_offload_event(uint8_t type, uint8_t state) +{ + WLAN_VOS_DIAG_EVENT_DEF(host_offload, + struct vos_event_offload_req); + vos_mem_zero(&host_offload, sizeof(host_offload)); + + host_offload.offload_type = type; + host_offload.state = state; + + WLAN_VOS_DIAG_EVENT_REPORT(&host_offload, EVENT_OFFLOAD_REQ); +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +//Callback invoked by PMC to report status of standby request +void hdd_suspend_standby_cbk (void *callbackContext, eHalStatus status) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Standby status = %d", __func__, status); + g_standby_status = status; + + if(eHAL_STATUS_SUCCESS == status) + { + pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY; + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__); + } + + complete(&pHddCtx->standby_comp_var); +} + +//Callback invoked by PMC to report status of full power request +void hdd_suspend_full_pwr_callback(void *callbackContext, eHalStatus status) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Full Power status = %d", __func__, status); + g_full_pwr_status = status; + + if(eHAL_STATUS_SUCCESS == status) + { + pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE; + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__); + } + + complete(&pHddCtx->full_pwr_comp_var); +} + +eHalStatus hdd_exit_standby(hdd_context_t *pHddCtx) +{ + eHalStatus status = VOS_STATUS_SUCCESS; + long ret; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from standby",__func__); + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + + g_full_pwr_status = eHAL_STATUS_FAILURE; + status = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, pHddCtx, + eSME_FULL_PWR_NEEDED_BY_HDD); + + if(status == eHAL_STATUS_PMC_PENDING) + { + //Block on a completion variable. Can't wait forever though + ret = wait_for_completion_interruptible_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld", + __func__, ret); + } + status = g_full_pwr_status; + if(g_full_pwr_status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__); + VOS_ASSERT(0); + goto failure; + } + } + else if(status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d", + __func__, status); + VOS_ASSERT(0); + goto failure; + } + else + pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE; + +failure: + //No blocking to reduce latency. No other device should be depending on WLAN + //to finish resume and WLAN won't be instantly on after resume + return status; +} + + +//Helper routine to put the chip into standby +VOS_STATUS hdd_enter_standby(hdd_context_t *pHddCtx) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + long ret; + + //Disable IMPS/BMPS as we do not want the device to enter any power + //save mode on its own during suspend sequence + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + //Note we do not disable queues unnecessarily. Queues should already be disabled + //if STA is disconnected or the queue will be disabled as and when disconnect + //happens because of standby procedure. + + //Ensure that device is in full power first. There is scope for optimization + //here especially in scenarios where PMC is already in IMPS or REQUEST_IMPS. + //Core s/w needs to be optimized to handle this. Until then we request full + //power before issuing request for standby. + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + g_full_pwr_status = eHAL_STATUS_FAILURE; + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, + pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD); + + if(halStatus == eHAL_STATUS_PMC_PENDING) + { + //Block on a completion variable. Can't wait forever though + ret = wait_for_completion_interruptible_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on full_pwr_comp_var failed %ld", + __func__, ret); + } + + if(g_full_pwr_status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower Failed",__func__); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + } + else if(halStatus != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed - status %d", + __func__, halStatus); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + + if(pHddCtx->hdd_mcastbcast_filter_set == TRUE) { + hdd_conf_mcastbcast_filter(pHddCtx, FALSE); + pHddCtx->hdd_mcastbcast_filter_set = FALSE; + } + + //Request standby. Standby will cause the STA to disassociate first. TX queues + //will be disabled (by HDD) when STA disconnects. You do not want to disable TX + //queues here. Also do not assert if the failure code is eHAL_STATUS_PMC_NOT_NOW as PMC + //will send this failure code in case of concurrent sessions. Power Save cannot be supported + //when there are concurrent sessions. + INIT_COMPLETION(pHddCtx->standby_comp_var); + g_standby_status = eHAL_STATUS_FAILURE; + halStatus = sme_RequestStandby(pHddCtx->hHal, hdd_suspend_standby_cbk, pHddCtx); + + if (halStatus == eHAL_STATUS_PMC_PENDING) + { + //Wait till WLAN device enters standby mode + ret = wait_for_completion_timeout(&pHddCtx->standby_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_STANDBY)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on standby_comp_var failed %ld"), ret); + } + if (g_standby_status != eHAL_STATUS_SUCCESS && g_standby_status != eHAL_STATUS_PMC_NOT_NOW) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed",__func__); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + } + else if (halStatus != eHAL_STATUS_SUCCESS && halStatus != eHAL_STATUS_PMC_NOT_NOW) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestStandby failed - status %d", + __func__, halStatus); + VOS_ASSERT(0); + vosStatus = VOS_STATUS_E_FAILURE; + goto failure; + } + else + pHddCtx->hdd_ps_state = eHDD_SUSPEND_STANDBY; + +failure: + //Restore IMPS config + if(pHddCtx->cfg_ini->fIsImpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + + //Restore BMPS config + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + return vosStatus; +} + + +//Helper routine for Deep sleep entry +VOS_STATUS hdd_enter_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter) +{ + eHalStatus halStatus; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + long ret; + + //Stop the Interface TX queue. + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + + //Disable IMPS,BMPS as we do not want the device to enter any power + //save mode on it own during suspend sequence + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + //Ensure that device is in full power as we will touch H/W during vos_Stop + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + g_full_pwr_status = eHAL_STATUS_FAILURE; + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_suspend_full_pwr_callback, + pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD); + + if(halStatus == eHAL_STATUS_PMC_PENDING) + { + //Block on a completion variable. Can't wait forever though + ret = wait_for_completion_interruptible_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on full_pwr_comp_var failed %ld"), ret); + } + if(g_full_pwr_status != eHAL_STATUS_SUCCESS){ + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: sme_RequestFullPower failed",__func__); + VOS_ASSERT(0); + } + } + else if(halStatus != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Request for Full Power failed",__func__); + VOS_ASSERT(0); + } + + //Issue a disconnect. This is required to inform the supplicant that + //STA is getting disassociated and for GUI to be updated properly + INIT_COMPLETION(pAdapter->disconnect_comp_var); + halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + + //Success implies disconnect command got queued up successfully + if(halStatus == eHAL_STATUS_SUCCESS) + { + //Block on a completion variable. Can't wait forever though. + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on disconnect_comp_var failed %ld"), ret); + } + } + + + //None of the steps should fail after this. Continue even in case of failure + vosStatus = vos_stop( pHddCtx->pvosContext ); + if( !VOS_IS_STATUS_SUCCESS( vosStatus )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: vos_stop return failed %d", + __func__, vosStatus); + VOS_ASSERT(0); + if (isSsrPanicOnFailure()) + VOS_BUG(0); + } + + pHddCtx->hdd_ps_state = eHDD_SUSPEND_DEEP_SLEEP; + + //Restore IMPS config + if(pHddCtx->cfg_ini->fIsImpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + + //Restore BMPS config + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + return vosStatus; +} + +VOS_STATUS hdd_exit_deep_sleep(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter) +{ + VOS_STATUS vosStatus; + eHalStatus halStatus; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling hdd_set_sme_config",__func__); + vosStatus = hdd_set_sme_config( pHddCtx ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed in hdd_set_sme_config",__func__); + goto err_deep_sleep; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling vos_start",__func__); + vosStatus = vos_start( pHddCtx->pvosContext ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed in vos_start",__func__); + if (isSsrPanicOnFailure()) + VOS_BUG(0); + goto err_deep_sleep; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: calling hdd_post_voss_start_config",__func__); + vosStatus = hdd_post_voss_start_config( pHddCtx ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed in hdd_post_voss_start_config",__func__); + goto err_voss_stop; + } + + + //Open a SME session for future operation + halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pHddCtx, + (tANI_U8 *)&pAdapter->macAddressCurrent, + &pAdapter->sessionId); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"sme_OpenSession() failed with status code %08d [x%08x]", + halStatus, halStatus ); + goto err_voss_stop; + + } + + pHddCtx->hdd_ps_state = eHDD_SUSPEND_NONE; + + //Trigger the initial scan + hdd_wlan_initial_scan(pAdapter); + + return VOS_STATUS_SUCCESS; + +err_voss_stop: + vos_stop(pHddCtx->pvosContext); +err_deep_sleep: + return VOS_STATUS_E_FAILURE; + +} + +void __hdd_ipv6_notifier_work_queue(struct work_struct *work) +{ + hdd_adapter_t* pAdapter = + container_of(work, hdd_adapter_t, ipv6NotifierWorkQueue); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + if (NULL == pAdapter) + { + hddLog(LOGE, FL("Adapter is invalid")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return; + } + + if ((eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) + && (pHddCtx->hdd_wlan_suspended)) + { + check_and_set_suspend_resume_mcbc_filter(pHddCtx); + // This invocation being part of the IPv6 registration callback, + // set the newly generated ip address to f/w in suspend mode. +#ifdef WLAN_NS_OFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + hdd_conf_ns_offload(pAdapter, 1); + } +#endif + } +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* wlan_hdd_set_mc_addr_list() is called from the early suspend + * only so when new ipv6 address is generated the screen may not + * on so we need to call it here to update the list in f/w. + */ + wlan_hdd_set_mc_addr_list(pAdapter, TRUE); +#endif + EXIT(); +} + +void hdd_ipv6_notifier_work_queue(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_ipv6_notifier_work_queue(work); + vos_ssr_unprotect(__func__); +} +int __wlan_hdd_ipv6_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)arg; + struct net_device *ndev = ifa->idev->dev; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_context_t *pHddCtx; + VOS_STATUS vos_status; + int status; + + ENTER(); + pHddCtx = container_of(nb, hdd_context_t, ipv6_notifier); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return NOTIFY_DONE; + } + + vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status) + { + if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev && + (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION || + pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) + { + + if (eConnectionState_Associated == + WLAN_HDD_GET_STATION_CTX_PTR + (pAdapterNode->pAdapter)->conn_info.connState) + sme_dhcp_done_ind(pHddCtx->hHal, + pAdapterNode->pAdapter->sessionId); + if (pHddCtx->cfg_ini->nEnableSuspend == + WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER) + { + schedule_work(&pAdapterNode->pAdapter->ipv6NotifierWorkQueue); + } + else + { + hddLog(LOG1, FL("Not scheduling ipv6 wq nEnableSuspend = %d"), + pHddCtx->cfg_ini->nEnableSuspend); + } + break; + } + vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + EXIT(); + return NOTIFY_DONE; +} + +int wlan_hdd_ipv6_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_ipv6_changed( nb, data, arg); + vos_ssr_unprotect(__func__); + return ret; +} + +/* + * Function: hdd_conf_hostoffload + * Central function to configure the supported offloads, + * either enable or disable them. + */ +void hdd_conf_hostoffload(hdd_adapter_t *pAdapter, v_BOOL_t fenable) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t *pVosContext = NULL; + VOS_STATUS vstatus = VOS_STATUS_E_FAILURE; + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Configuring offloads with flag: %d"), + fenable); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL == pVosContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Global VOS context is Null")); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HDD context is Null", __func__); + return; + } + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + ((WLAN_HDD_SOFTAP == pAdapter->device_mode) && + (pHddCtx->is_ap_mode_wow_supported))) + { + if (fenable) + { + if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) && + (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + || (WLAN_HDD_SOFTAP == pAdapter->device_mode)) + { + if ((pHddCtx->cfg_ini->fhostArpOffload)) + { + /* + * Configure the ARP Offload. + * Even if it fails we have to reconfigure the MC/BC + * filter flag as we want RIVA not to drop BroadCast + * Packets + */ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Calling ARP Offload with flag: %d"), fenable); + vstatus = hdd_conf_arp_offload(pAdapter, fenable); + pHddCtx->configuredMcastBcastFilter &= + ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST); + + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "Failed to enable ARPOFfloadFeature %d", + vstatus); + } + } + //Configure GTK_OFFLOAD +#ifdef WLAN_FEATURE_GTK_OFFLOAD + hdd_conf_gtk_offload(pAdapter, fenable); +#endif + +#ifdef WLAN_NS_OFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + /* + * Configure the NS Offload. + * Even if it fails we have to reconfigure the MC/BC filter flag + * as we want RIVA not to drop Multicast Packets + */ + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Calling NS Offload with flag: %d"), fenable); + hdd_conf_ns_offload(pAdapter, fenable); + pHddCtx->configuredMcastBcastFilter &= + ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); + } +#endif + + } + } + else + { + //Disable ARPOFFLOAD + if (pHddCtx->cfg_ini->fhostArpOffload) + { + vstatus = hdd_conf_arp_offload(pAdapter, fenable); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "Failed to disable ARPOffload Feature %d", vstatus); + } + } + //Disable GTK_OFFLOAD +#ifdef WLAN_FEATURE_GTK_OFFLOAD + hdd_conf_gtk_offload(pAdapter, fenable); +#endif + +#ifdef WLAN_NS_OFFLOAD + //Disable NSOFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + hdd_conf_ns_offload(pAdapter, fenable); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("ns offload ini is disabled")); + } +#endif + } + } + return; +} + + +#ifdef WLAN_NS_OFFLOAD +/**---------------------------------------------------------------------------- + + \brief hdd_conf_ns_offload() - Configure NS offload + + Called during SUSPEND to configure the NS offload (MC BC filter) which + reduces power consumption. + + \param - pAdapter - Adapter context for which NS offload is to be configured + \param - fenable - 0 - disable. + 1 - enable. (with IPv6 notifier registration) + 2 - enable. (without IPv6 notifier registration) + + \return - void + + ---------------------------------------------------------------------------*/ +void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable) +{ + struct inet6_dev *in6_dev; + struct inet6_ifaddr *ifp; + struct list_head *p; + int slot_index = NS_DEFAULT_SLOT_INDEX; + tANI_U8 **selfIPv6Addr = NULL; + tANI_U8 *selfIPv6AddrValid = NULL; + tSirHostOffloadReq offLoadRequest; + hdd_context_t *pHddCtx; + tHalHandle halHandle; + + int i = 0, slot = 0; + int ret = 0; + eHalStatus returnStatus; + + ENTER(); + hddLog(LOG1, FL(" fenable = %d"), fenable); + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is Null")); + return; + } + + halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return; + } + + if (sme_IsFeatureSupportedByFW(EXTENDED_NSOFFLOAD_SLOT)) + { + slot_index = NS_EXTENDED_SLOT_INDEX; + } + + hddLog(VOS_TRACE_LEVEL_INFO, FL("slot_idex = %d"), slot_index); + + selfIPv6AddrValid = + (tANI_U8 *)vos_mem_malloc(sizeof(tANI_U8) * slot_index); + + if (NULL == selfIPv6AddrValid) + { + hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for" + " selfIPv6AddrValid")); + goto end; + } + + vos_mem_zero(selfIPv6AddrValid, slot_index * sizeof(tANI_U8)); + + selfIPv6Addr = (tANI_U8 **)vos_mem_malloc(sizeof(tANI_U8 *) * slot_index); + + if (NULL == selfIPv6Addr) + { + hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory for" + " selfIPv6Addr")); + goto end; + } + + vos_mem_zero(selfIPv6Addr, slot_index * sizeof(tANI_U8 *)); + + for (slot = 0; slot < slot_index; slot++) + { + selfIPv6Addr[slot] = + (tANI_U8 *)vos_mem_malloc(SIR_MAC_IPV6_ADDR_LEN); + if (NULL == selfIPv6Addr[slot]) + { + hddLog (VOS_TRACE_LEVEL_ERROR, FL("Failed to allocate memory" + "for selfIPv6Addr")); + goto end; + } + vos_mem_zero(selfIPv6Addr[slot], SIR_MAC_IPV6_ADDR_LEN); + } + + i = 0; + + if (fenable) + { + in6_dev = __in6_dev_get(pAdapter->dev); + if (NULL != in6_dev) + { + read_lock_bh(&in6_dev->lock); + list_for_each(p, &in6_dev->addr_list) + { + if (i >= slot_index) + { + hddLog (VOS_TRACE_LEVEL_ERROR, + FL("IPv6 address list is greater than IPv6" + "address supported by firmware")); + hddLog (VOS_TRACE_LEVEL_ERROR, + FL("FW supported IPv6 address = %d"), slot_index); + break; + } + ifp = list_entry(p, struct inet6_ifaddr, if_list); + switch(ipv6_addr_src_scope(&ifp->addr)) + { + case IPV6_ADDR_SCOPE_LINKLOCAL: + vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr, + sizeof(ifp->addr.s6_addr)); + selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID; + hddLog (VOS_TRACE_LEVEL_INFO, + FL("Found IPV6_ADDR_SCOPE_LINKLOCAL Address : %pI6"), + selfIPv6Addr[i]); + break; + case IPV6_ADDR_SCOPE_GLOBAL: + vos_mem_copy(selfIPv6Addr[i], &ifp->addr.s6_addr, + sizeof(ifp->addr.s6_addr)); + selfIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID; + hddLog (VOS_TRACE_LEVEL_INFO, + FL("Found IPV6_ADDR_SCOPE_GLOBAL Address : %pI6"), + selfIPv6Addr[i]); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("The Scope %d is not supported"), + ipv6_addr_src_scope(&ifp->addr)); + } + if (selfIPv6AddrValid[i] == SIR_IPV6_ADDR_VALID) + { + i++; + } + } + /* store actual slots being used */ + pAdapter->ns_slots = i; + read_unlock_bh(&in6_dev->lock); + + vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest)); + for (i =0; i < slot_index; i++) + { + if (selfIPv6AddrValid[i]) + { + //Filling up the request structure + /* Filling the selfIPv6Addr with solicited address + * A Solicited-Node multicast address is created by + * taking the last 24 bits of a unicast or anycast + * address and appending them to the prefix + * + * FF02:0000:0000:0000:0000:0001:FFXX:XX + * + * here XX is the unicast/anycast bits + */ + offLoadRequest.nsOffloadInfo.selfIPv6Addr[0] = 0xFF; + offLoadRequest.nsOffloadInfo.selfIPv6Addr[1] = 0x02; + offLoadRequest.nsOffloadInfo.selfIPv6Addr[11] = 0x01; + offLoadRequest.nsOffloadInfo.selfIPv6Addr[12] = 0xFF; + offLoadRequest.nsOffloadInfo.selfIPv6Addr[13] = + selfIPv6Addr[i][13]; + offLoadRequest.nsOffloadInfo.selfIPv6Addr[14] = + selfIPv6Addr[i][14]; + offLoadRequest.nsOffloadInfo.selfIPv6Addr[15] = + selfIPv6Addr[i][15]; + offLoadRequest.nsOffloadInfo.slotIdx = i; + + vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[0], + selfIPv6Addr[i], sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN); + vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr, + &pAdapter->macAddressCurrent.bytes, + sizeof(tANI_U8)*SIR_MAC_ADDR_LEN); + + offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[0] = + SIR_IPV6_ADDR_VALID; + offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD; + offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; + hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, + SIR_OFFLOAD_ENABLE); + + hddLog (VOS_TRACE_LEVEL_INFO, + FL("configuredMcastBcastFilter: %d" + "NSOffload Slot = %d"), + pHddCtx->configuredMcastBcastFilter, i); + + if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) + && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST == + pHddCtx->sus_res_mcastbcast_filter) || + (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter)) && + (!WDA_IS_MCAST_FLT_ENABLE_IN_FW || + (WDA_IS_MCAST_FLT_ENABLE_IN_FW && + !(pHddCtx->cfg_ini->fEnableMCAddrList)))) + { + offLoadRequest.enableOrDisable = + SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE; + } + hdd_wlan_offload_event( + SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE, + SIR_OFFLOAD_ENABLE); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: NS filter programmed %d"), + offLoadRequest.enableOrDisable); + vos_mem_copy(&offLoadRequest.params.hostIpv6Addr, + &offLoadRequest.nsOffloadInfo.targetIPv6Addr[0], + sizeof(tANI_U8)*SIR_MAC_IPV6_ADDR_LEN); + + hddLog (VOS_TRACE_LEVEL_INFO, + FL("Setting NSOffload with solicitedIp: %pI6," + "targetIp: %pI6"), + offLoadRequest.nsOffloadInfo.selfIPv6Addr, + offLoadRequest.nsOffloadInfo.targetIPv6Addr[0]); + + //Configure the Firmware with this + returnStatus = sme_SetHostOffload(halHandle, + pAdapter->sessionId, &offLoadRequest); + if(eHAL_STATUS_SUCCESS != returnStatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to enable HostOffload feature with" + " status: %d"), returnStatus); + } + vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest)); + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("IPv6 dev does not exist. Failed to request NSOffload")); + goto end; + } + } + else + { + //Disable NSOffload + vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq)); + offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE; + offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD; + hdd_wlan_offload_event(SIR_IPV6_NS_OFFLOAD, + SIR_OFFLOAD_DISABLE); + + for (i = 0; i < pAdapter->ns_slots; i++) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disable Slot= %d"), i); + offLoadRequest.nsOffloadInfo.slotIdx = i; + if (eHAL_STATUS_SUCCESS != + sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failure to disable" + " %d Slot"), i); + } + } + pAdapter->ns_slots = 0; + } +end: + while (slot > 0 && selfIPv6Addr[--slot]) + { + vos_mem_free(selfIPv6Addr[slot]); + } + if (selfIPv6Addr) + { + vos_mem_free(selfIPv6Addr); + } + if (selfIPv6AddrValid) + { + vos_mem_free(selfIPv6AddrValid); + } + EXIT(); + return; +} +#endif + +void __hdd_ipv4_notifier_work_queue(struct work_struct *work) +{ + hdd_adapter_t* pAdapter = + container_of(work, hdd_adapter_t, ipv4NotifierWorkQueue); + hdd_context_t *pHddCtx; + int status; + + ENTER(); + if (NULL == pAdapter) + { + hddLog(LOGE, FL("Adapter is invalid")); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return; + } + + if ((eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) + && (pHddCtx->hdd_wlan_suspended)) + { + // This invocation being part of the IPv4 registration callback, + // we are passing second parameter as 2 to avoid registration + // of IPv4 notifier again. + check_and_set_suspend_resume_mcbc_filter(pHddCtx); + if (pHddCtx->cfg_ini->fhostArpOffload) + { + hdd_conf_arp_offload(pAdapter, 2); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: arp offload ini is disabled in host")); + } + } + EXIT(); +} + +void hdd_ipv4_notifier_work_queue(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_ipv4_notifier_work_queue(work); + vos_ssr_unprotect(__func__); +} + +int __wlan_hdd_ipv4_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)arg; + struct in_ifaddr **ifap = NULL; + struct in_device *in_dev; + + struct net_device *ndev = ifa->ifa_dev->dev; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_context_t *pHddCtx; + VOS_STATUS vos_status; + int status; + + ENTER(); + pHddCtx = container_of(nb, hdd_context_t, ipv4_notifier); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return NOTIFY_DONE; + } + + vos_status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == vos_status) + { + if (pAdapterNode->pAdapter && pAdapterNode->pAdapter->dev == ndev && + (pAdapterNode->pAdapter->device_mode == WLAN_HDD_INFRA_STATION || + pAdapterNode->pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) + { + + if (eConnectionState_Associated == + WLAN_HDD_GET_STATION_CTX_PTR + (pAdapterNode->pAdapter)->conn_info.connState) + sme_dhcp_done_ind(pHddCtx->hHal, + pAdapterNode->pAdapter->sessionId); + if ((pHddCtx->cfg_ini->nEnableSuspend != + WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER) + || (!pHddCtx->cfg_ini->fhostArpOffload)) + { + hddLog(LOG1, FL("Offload not enabled MCBC=%d, ARPOffload=%d"), + pHddCtx->cfg_ini->nEnableSuspend, + pHddCtx->cfg_ini->fhostArpOffload); + return NOTIFY_DONE; + } + + if ((in_dev = + __in_dev_get_rtnl(pAdapterNode->pAdapter->dev)) != NULL) + { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) + { + if (!strcmp(pAdapterNode->pAdapter->dev->name, + ifa->ifa_label)) + { + break; /* found */ + } + } + } + if(ifa && ifa->ifa_local) + { + schedule_work(&pAdapterNode->pAdapter->ipv4NotifierWorkQueue); + } + break; + } + vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + EXIT(); + return NOTIFY_DONE; +} + +int wlan_hdd_ipv4_changed(struct notifier_block *nb, + unsigned long data, void *arg) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_ipv4_changed( nb, data, arg); + vos_ssr_unprotect(__func__); + return ret; +} + +/**---------------------------------------------------------------------------- + + \brief hdd_conf_arp_offload() - Configure ARP offload + + Called during SUSPEND to configure the ARP offload (MC BC filter) which + reduces power consumption. + + \param - pAdapter -Adapter context for which ARP offload is to be configured + \param - fenable - 0 - disable. + 1 - enable. (with IPv4 notifier registration) + 2 - enable. (without IPv4 notifier registration) + + \return - + VOS_STATUS_SUCCESS - on successful operation + VOS_STATUS_E_FAILURE - on failure of operation +-----------------------------------------------------------------------------*/ +VOS_STATUS hdd_conf_arp_offload(hdd_adapter_t *pAdapter, int fenable) +{ + struct in_ifaddr **ifap = NULL; + struct in_ifaddr *ifa = NULL; + struct in_device *in_dev; + int i = 0; + tSirHostOffloadReq offLoadRequest; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + hddLog(VOS_TRACE_LEVEL_INFO, FL(" fenable = %d "), fenable); + + if(fenable) + { + if ((in_dev = __in_dev_get_rtnl(pAdapter->dev)) != NULL) + { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) + { + if (!strcmp(pAdapter->dev->name, ifa->ifa_label)) + { + break; /* found */ + } + } + } + if(ifa && ifa->ifa_local) + { + offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD; + offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; + hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD, + SIR_OFFLOAD_ENABLE); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Enabled", __func__); + + if (((HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter) || + (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter)) && + (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)) + { + offLoadRequest.enableOrDisable = + SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE; + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: inside arp offload conditional check"); + } + hdd_wlan_offload_event(SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE, + SIR_OFFLOAD_ENABLE); + + hddLog(VOS_TRACE_LEVEL_INFO, "offload: arp filter programmed = %d", + offLoadRequest.enableOrDisable); + + //converting u32 to IPV4 address + for(i = 0 ; i < 4; i++) + { + offLoadRequest.params.hostIpv4Addr[i] = + (ifa->ifa_local >> (i*8) ) & 0xFF ; + } + hddLog(VOS_TRACE_LEVEL_INFO, " Enable SME HostOffload: %d.%d.%d.%d", + offLoadRequest.params.hostIpv4Addr[0], + offLoadRequest.params.hostIpv4Addr[1], + offLoadRequest.params.hostIpv4Addr[2], + offLoadRequest.params.hostIpv4Addr[3]); + + if (eHAL_STATUS_SUCCESS != + sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to enable HostOffload " + "feature", __func__); + return VOS_STATUS_E_FAILURE; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, FL("IP Address is not assigned")); + return VOS_STATUS_E_AGAIN; + } + + return VOS_STATUS_SUCCESS; + } + else + { + vos_mem_zero((void *)&offLoadRequest, sizeof(tSirHostOffloadReq)); + offLoadRequest.enableOrDisable = SIR_OFFLOAD_DISABLE; + offLoadRequest.offloadType = SIR_IPV4_ARP_REPLY_OFFLOAD; + hdd_wlan_offload_event(SIR_IPV4_ARP_REPLY_OFFLOAD, + SIR_OFFLOAD_DISABLE); + if (eHAL_STATUS_SUCCESS != + sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offLoadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to disable host " + "offload feature", __func__); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; + } +} + +/* + * This function is called before setting mcbc filters + * to modify filter value considering Different Offloads +*/ +void hdd_mcbc_filter_modification(hdd_context_t* pHddCtx, + tANI_U8 *pMcBcFilter) +{ + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("NULL HDD context passed")); + return; + } + + *pMcBcFilter = pHddCtx->configuredMcastBcastFilter; + if (pHddCtx->cfg_ini->fhostArpOffload) + { + /* ARP offload is enabled, do not block bcast packets at RXP + * Will be using Bitmasking to reset the filter. As we have + * disable Broadcast filtering, Anding with the negation + * of Broadcast BIT + */ + hddLog(VOS_TRACE_LEVEL_INFO, FL(" ARP offload is enabled")); + *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST); + } + +#ifdef WLAN_NS_OFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + /* NS offload is enabled, do not block mcast packets at RXP + * Will be using Bitmasking to reset the filter. As we have + * disable Multicast filtering, Anding with the negation + * of Multicast BIT + */ + hddLog(VOS_TRACE_LEVEL_INFO, FL(" NS offload is enabled")); + *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); + } +#endif + + if ((pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW) + { + *pMcBcFilter &= ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); + } + + pHddCtx->configuredMcastBcastFilter = *pMcBcFilter; +} + +void hdd_conf_mcastbcast_filter(hdd_context_t* pHddCtx, v_BOOL_t setfilter) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tpSirWlanSetRxpFilters wlanRxpFilterParam = + vos_mem_malloc(sizeof(tSirWlanSetRxpFilters)); + if (NULL == wlanRxpFilterParam) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Configuring Mcast/Bcast Filter Setting. setfilter %d", __func__, setfilter); + if (TRUE == setfilter) + { + hdd_mcbc_filter_modification(pHddCtx, + &wlanRxpFilterParam->configuredMcstBcstFilterSetting); + } + else + { + /*Use the current configured value to clear*/ + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + } + + wlanRxpFilterParam->setMcstBcstFilter = setfilter; + halStatus = sme_ConfigureRxpFilter(pHddCtx->hHal, wlanRxpFilterParam); + + if (setfilter && (eHAL_STATUS_SUCCESS == halStatus)) + { + pHddCtx->hdd_mcastbcast_filter_set = TRUE; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s to post set/reset filter to" + "lower mac with status %d" + "configuredMcstBcstFilterSetting = %d" + "setMcstBcstFilter = %d",(eHAL_STATUS_SUCCESS != halStatus) ? + "Failed" : "Success", halStatus, + wlanRxpFilterParam->configuredMcstBcstFilterSetting, + wlanRxpFilterParam->setMcstBcstFilter); + + if (eHAL_STATUS_SUCCESS != halStatus) + vos_mem_free(wlanRxpFilterParam); +} + +/* + * Enable/Disable McAddrList cfg item in fwr. + */ +eHalStatus hdd_set_mc_list_cfg_item(hdd_context_t* pHddCtx, + bool value) +{ + eHalStatus ret_val; + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_ENABLE_MC_ADDR_LIST, + value, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + ret_val = eHAL_STATUS_FAILURE; + hddLog(LOGE, + FL("offload: can't pass WNI_CFG_ENABLE_MC_ADDR_LIST to CCM")); + return ret_val; + } + + ret_val = sme_update_cfg_int_param(pHddCtx->hHal, + WNI_CFG_ENABLE_MC_ADDR_LIST); + if (!HAL_STATUS_SUCCESS(ret_val)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Failed to toggle MC_ADDR_LIST_INI %d "), + ret_val); + return ret_val; + } + /* cache the value configured in fwr */ + pHddCtx->mc_list_cfg_in_fwr = value; + return eHAL_STATUS_SUCCESS; +} + +bool is_mc_list_cfg_disable_required(hdd_context_t* pHddCtx) +{ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: fEnableMCList %d sus_res_mcbc_filter %d mc_list_in_fwr %d"), + pHddCtx->cfg_ini->fEnableMCAddrList, + pHddCtx->sus_res_mcastbcast_filter, + pHddCtx->mc_list_cfg_in_fwr); + + /* + * If MCAddrList is enabled in ini and MCBC filter is set to + * Either Filter None or Filter all BC then, Fwr need to push + * all MC to host. This can be achieved by disabling cfg MCAddrList + * in fwr. As in driver load, firmware have this value to 1 we + * need to set it to 0. Same needs to be reverted on resume. + */ + if (pHddCtx->cfg_ini->fEnableMCAddrList && + WDA_IS_MCAST_FLT_ENABLE_IN_FW && + ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid)&& + ((HDD_MCASTBCASTFILTER_FILTER_NONE == + pHddCtx->sus_res_mcastbcast_filter) || + (HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST == + pHddCtx->sus_res_mcastbcast_filter))) + ) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: cfg ini need to disable in fwr")); + return true; + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: cfg ini disable not needed ")); + return false; + } +} + +/** + * hdd_mc_addr_list_cfg_config() - To set mc list cfg configuration in fwr + * @pHddCtx: hdd context handle + * @action: true to disable MCAddrList in fwr to get all MC pkt to host + * false to set ini value of MCAddrList in fwr if it was toggled + * Return: none + * + * Ensure Below API is invoked always post modification + * of sus_res_mcastbcast_filter. + */ +void hdd_mc_addr_list_cfg_config(hdd_context_t* pHddCtx, bool action) +{ + if (action) + { + /* check host need to disable mc list ini in fwr */ + if (is_mc_list_cfg_disable_required(pHddCtx)) + { + /* + * Yes Host should disable the mc list in fwr + * But Ensure host might already disable it + * This can happen when user issue set/clear MCBC + * ioctl with 2 to 0 or vice versa. + */ + if (pHddCtx->cfg_ini->fEnableMCAddrList == + pHddCtx->mc_list_cfg_in_fwr) + { + hdd_set_mc_list_cfg_item(pHddCtx, + !pHddCtx->cfg_ini->fEnableMCAddrList); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: setting mc_list_cfg_in_fwr: %d"), + !pHddCtx->cfg_ini->fEnableMCAddrList); + } + } + else + { + /* Host toggled mc list ini in fwr previosuly, set to ini value */ + if (pHddCtx->cfg_ini->fEnableMCAddrList != + pHddCtx->mc_list_cfg_in_fwr) + { + hdd_set_mc_list_cfg_item(pHddCtx, + pHddCtx->cfg_ini->fEnableMCAddrList); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: setting mc_list_cfg_in_fwr: %d"), + pHddCtx->cfg_ini->fEnableMCAddrList); + } + } + } + else + { + /* Host toggled mc list ini in fwr previosuly, set to ini value */ + if (pHddCtx->cfg_ini->fEnableMCAddrList != + pHddCtx->mc_list_cfg_in_fwr) + { + hdd_set_mc_list_cfg_item(pHddCtx, + pHddCtx->cfg_ini->fEnableMCAddrList); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("offload: setting mc_list_cfg_in_fwr: %d"), + pHddCtx->cfg_ini->fEnableMCAddrList); + } + } +} + +/** + * hdd_suspend_ind_callback: This API will set completion event for suspend + * @pAdapter: hdd_adapter_t + * @status: suspend status + * + * Return: none + */ +static void hdd_suspend_ind_callback(void *context, VOS_STATUS status) +{ + hdd_adapter_t *adapter = (hdd_adapter_t *)context; + if (NULL == adapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is NULL",__func__); + return; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("suspend status %d"), status); + complete(&adapter->wlan_suspend_comp_var); +} + +static void hdd_conf_suspend_ind(hdd_context_t* pHddCtx, + hdd_adapter_t *pAdapter) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tpSirWlanSuspendParam wlanSuspendParam = + vos_mem_malloc(sizeof(tSirWlanSuspendParam)); + + check_and_set_suspend_resume_mcbc_filter(pHddCtx); + if(NULL == wlanSuspendParam) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: send wlan suspend indication", __func__); + + if((pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER)) + { + //Configure supported OffLoads + hdd_conf_hostoffload(pAdapter, TRUE); + wlanSuspendParam->configuredMcstBcstFilterSetting = pHddCtx->configuredMcastBcastFilter; + hddLog(VOS_TRACE_LEVEL_INFO, + FL("saving configuredMcastBcastFilterSetting = %d"), + wlanSuspendParam->configuredMcstBcstFilterSetting); +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* During suspend, configure MC Addr list filter to the firmware + * function takes care of checking necessary conditions before + * configuring. + */ + wlan_hdd_set_mc_addr_list(pAdapter, TRUE); +#endif + + if( (pHddCtx->cfg_ini->fEnableMCAddrList) && WDA_IS_MCAST_FLT_ENABLE_IN_FW) + { + + hddLog(VOS_TRACE_LEVEL_INFO, "offload: MCaddrlist: FW capability set "); + pHddCtx->configuredMcastBcastFilter &= + ~(HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST); + } + + wlanSuspendParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + + wlanSuspendParam->wlan_sus_callback = hdd_suspend_ind_callback; + wlanSuspendParam->context = pAdapter; + /* mc add list cfg item configuration in fwr */ + hdd_mc_addr_list_cfg_config(pHddCtx, true); + + } + + halStatus = sme_ConfigureSuspendInd(pHddCtx->hHal, wlanSuspendParam); + if(eHAL_STATUS_SUCCESS == halStatus) + { + pHddCtx->hdd_mcastbcast_filter_set = TRUE; + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sme_ConfigureSuspendInd returned failure %d"), halStatus); + vos_mem_free(wlanSuspendParam); + } +} + +static void hdd_conf_resume_ind(hdd_adapter_t *pAdapter) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + hdd_context_t* pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tpSirWlanResumeParam wlanResumeParam; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: send wlan resume indication", __func__); + + wlanResumeParam = vos_mem_malloc(sizeof(tSirWlanResumeParam)); + + if (NULL == wlanResumeParam) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: memory allocation failed for wlanResumeParam ", __func__); + return; + } + + //Disable supported OffLoads + hdd_conf_hostoffload(pAdapter, FALSE); + + wlanResumeParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + halStatus = sme_ConfigureResumeReq(pHddCtx->hHal, wlanResumeParam); + if (eHAL_STATUS_SUCCESS != halStatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_ConfigureResumeReq return failure %d", __func__, halStatus); + vos_mem_free(wlanResumeParam); + } + + pHddCtx->hdd_mcastbcast_filter_set = FALSE; + /* mc add list cfg item configuration in fwr */ + hdd_mc_addr_list_cfg_config(pHddCtx, false); + + if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) { + pHddCtx->configuredMcastBcastFilter = + pHddCtx->sus_res_mcastbcast_filter; + pHddCtx->sus_res_mcastbcast_filter_valid = VOS_FALSE; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "offload: in hdd_conf_resume_ind, restoring configuredMcastBcastFilter"); + hddLog(VOS_TRACE_LEVEL_INFO, "configuredMcastBcastFilter = %d", + pHddCtx->configuredMcastBcastFilter); + + +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* Filer was applied during suspend inditication + * clear it when we resume. + */ + wlan_hdd_set_mc_addr_list(pAdapter, FALSE); +#endif +} + +//Suspend routine registered with Android OS +void hdd_suspend_wlan(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + long ret; + VOS_STATUS status; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + bool hdd_enter_bmps = FALSE; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being suspended by Android OS",__func__); + + //Get the global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return; + } + + if (pHddCtx->isLogpInProgress) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Ignore suspend wlan, LOGP in progress!", __func__); + return; + } + + if (pHddCtx->hdd_wlan_suspended) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Ignore suspend wlan, Already suspended!", __func__); + return; + } + + pHddCtx->hdd_wlan_suspended = TRUE; + hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_SUSPEND); + hdd_set_pwrparams(pHddCtx); + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + && (WLAN_HDD_SOFTAP != pAdapter->device_mode) + && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) ) + + { // we skip this registration for modes other than STA, SAP and P2P client modes. + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + continue; + } + /* Avoid multiple enter/exit BMPS in this while loop using + * hdd_enter_bmps flag + */ + if (FALSE == hdd_enter_bmps && (BMPS == pmcGetPmcState(pHddCtx->hHal))) + { + hdd_enter_bmps = TRUE; + + /* If device was already in BMPS, and dynamic DTIM is set, + * exit(set the device to full power) and enter BMPS again + * to reflect new DTIM value */ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE); + + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO); + + pHddCtx->hdd_ignore_dtim_enabled = TRUE; + } +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if (pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY) + { + //stop the interface before putting the chip to standby + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + } + else if (pHddCtx->cfg_ini->nEnableSuspend == + WLAN_MAP_SUSPEND_TO_DEEP_SLEEP) + { + //Execute deep sleep procedure + hdd_enter_deep_sleep(pHddCtx, pAdapter); + } +#endif + + INIT_COMPLETION(pAdapter->wlan_suspend_comp_var); + /*Suspend notification sent down to driver*/ + hdd_conf_suspend_ind(pHddCtx, pAdapter); + ret = wait_for_completion_interruptible_timeout( + &pAdapter->wlan_suspend_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_FULL_PWR)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:wait on suspend failed %ld", + __func__, ret); + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if(pHddCtx->cfg_ini->nEnableSuspend == WLAN_MAP_SUSPEND_TO_STANDBY) + { + hdd_enter_standby(pHddCtx); + } +#endif + + return; +} + +/** + * @brief hdd_ReConfigSuspendDataClearedDuringRoaming() - Reconfigure the + * suspend related data which was cleared during roaming in FWR. + */ +void hdd_ReConfigSuspendDataClearedDuringRoaming(hdd_context_t *pHddCtx) + +{ + VOS_STATUS vstatus = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + + ENTER(); + + spin_lock(&pHddCtx->filter_lock); + check_and_set_suspend_resume_mcbc_filter(pHddCtx); + spin_unlock(&pHddCtx->filter_lock); + + hdd_conf_mcastbcast_filter(pHddCtx, TRUE); + if(pHddCtx->hdd_mcastbcast_filter_set != TRUE) + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Not able to set mcast/bcast filter ")); + + vstatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + //No need to configure GTK Offload from here because it might possible + //cfg80211_set_rekey_data might not yet came, anyway GTK offload will + //be handled as part of cfg80211_set_rekey_data processing. + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == vstatus ) + { + pAdapter = pAdapterNode->pAdapter; + if( pAdapter && + (( pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))) + { + if (pHddCtx->cfg_ini->fhostArpOffload) + { + //Configure ARPOFFLOAD + vstatus = hdd_conf_arp_offload(pAdapter, TRUE); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Failed to disable ARPOffload Feature %d"), vstatus); + } + } +#ifdef WLAN_NS_OFFLOAD + //Configure NSOFFLOAD + if (pHddCtx->cfg_ini->fhostNSOffload) + { + hdd_conf_ns_offload(pAdapter, TRUE); + } +#endif +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* During suspend, configure MC Addr list filter to the firmware + * function takes care of checking necessary conditions before + * configuring. + */ + wlan_hdd_set_mc_addr_list(pAdapter, TRUE); +#endif + } + vstatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + EXIT(); +} + +static void hdd_PowerStateChangedCB +( + v_PVOID_t callbackContext, + tPmcState newState +) +{ + hdd_context_t *pHddCtx = callbackContext; + + /* if the driver was not in BMPS during early suspend, + * the dynamic DTIM is now updated at Riva */ + if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended + && (pHddCtx->cfg_ini->enableDynamicDTIM || + pHddCtx->cfg_ini->enableModulatedDTIM) + && (pHddCtx->hdd_ignore_dtim_enabled == FALSE)) + { + pHddCtx->hdd_ignore_dtim_enabled = TRUE; + } + spin_lock(&pHddCtx->filter_lock); + if ((newState == BMPS) && pHddCtx->hdd_wlan_suspended) + { + check_and_set_suspend_resume_mcbc_filter(pHddCtx); + spin_unlock(&pHddCtx->filter_lock); + hdd_conf_mcastbcast_filter(pHddCtx, TRUE); + if(pHddCtx->hdd_mcastbcast_filter_set != TRUE) + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not able to set mcast/bcast filter ", __func__); + } + else + { + /* Android framework can send resume request when the WCN chip is + * in IMPS mode. When the chip exits IMPS mode the firmware will + * restore all the registers to the state they were before the chip + * entered IMPS and so our hardware filter settings confgured by the + * resume request will be lost. So reconfigure the filters on detecting + * a change in the power state of the WCN chip. + */ + spin_unlock(&pHddCtx->filter_lock); + if (IMPS != newState) + { + spin_lock(&pHddCtx->filter_lock); + if (FALSE == pHddCtx->hdd_wlan_suspended) + { + spin_unlock(&pHddCtx->filter_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + "Not in IMPS/BMPS and suspended state"); + hdd_conf_mcastbcast_filter(pHddCtx, FALSE); + } + else + { + spin_unlock(&pHddCtx->filter_lock); + } + } + } +} + +void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx) +{ + v_CONTEXT_t pVosContext; + tHalHandle smeContext; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (NULL == pVosContext) + { + hddLog(LOGE, "%s: Invalid pContext", __func__); + return; + } + smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext); + if (NULL == smeContext) + { + hddLog(LOGE, "%s: Invalid smeContext", __func__); + return; + } + + spin_lock_init(&pHddCtx->filter_lock); + if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER == + pHddCtx->cfg_ini->nEnableSuspend) + { + pmcRegisterDeviceStateUpdateInd(smeContext, + hdd_PowerStateChangedCB, pHddCtx); + } +} + +void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx) +{ + v_CONTEXT_t pVosContext; + tHalHandle smeContext; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (NULL == pVosContext) + { + hddLog(LOGE, "%s: Invalid pContext", __func__); + return; + } + smeContext = vos_get_context(VOS_MODULE_ID_SME, pVosContext); + if (NULL == smeContext) + { + hddLog(LOGE, "%s: Invalid smeContext", __func__); + return; + } + + if (WLAN_MAP_SUSPEND_TO_MCAST_BCAST_FILTER == + pHddCtx->cfg_ini->nEnableSuspend) + { + pmcDeregisterDeviceStateUpdateInd(smeContext, hdd_PowerStateChangedCB); + } +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void hdd_conf_gtk_offload(hdd_adapter_t *pAdapter, v_BOOL_t fenable) +{ + eHalStatus ret; + tSirGtkOffloadParams hddGtkOffloadReqParams; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if(fenable) + { + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags )) + { + vos_mem_copy(&hddGtkOffloadReqParams, + &pHddStaCtx->gtkOffloadReqParams, + sizeof (tSirGtkOffloadParams)); + + ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + &hddGtkOffloadReqParams, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != ret) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_SetGTKOffload failed, returned %d", + __func__, ret); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_SetGTKOffload successfull", __func__); + } + + } + else + { + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (0 == memcmp(&pHddStaCtx->gtkOffloadReqParams.bssId, + &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN)) && + (GTK_OFFLOAD_ENABLE == pHddStaCtx->gtkOffloadReqParams.ulFlags)) + { + + /* Host driver has previously offloaded GTK rekey */ + ret = sme_GetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + wlan_hdd_cfg80211_update_replayCounterCallback, + pAdapter, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != ret) + + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_GetGTKOffload failed, returned %d", + __func__, ret); + return; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_GetGTKOffload successful", + __func__); + + /* Sending GTK offload dissable */ + memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams, + sizeof (tSirGtkOffloadParams)); + hddGtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE; + ret = sme_SetGTKOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + &hddGtkOffloadReqParams, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != ret) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to dissable GTK offload, returned %d", + __func__, ret); + return; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: successfully dissabled GTK offload request to HAL", + __func__); + } + } + } + return; +} +#endif /*WLAN_FEATURE_GTK_OFFLOAD*/ + +void hdd_resume_wlan(void) +{ + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + v_CONTEXT_t pVosContext = NULL; + tPmcState pmc_state; + hdd_adapter_t *first_adapter = NULL; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed by Android OS",__func__); + + //Get the global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return; + } + + if (pHddCtx->isLogpInProgress) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Ignore resume wlan, LOGP in progress!", __func__); + return; + } + + if (!pHddCtx->hdd_wlan_suspended) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Ignore resume wlan, Already resumed!", __func__); + return; + } + + pHddCtx->hdd_wlan_suspended = FALSE; + hdd_wlan_suspend_resume_event(HDD_WLAN_EARLY_RESUME); + + /* Get first valid adapter for disable/enable bmps purpose */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + first_adapter = pAdapterNode->pAdapter; + if (first_adapter != NULL) + break; + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + pmc_state = pmcGetPmcState(pHddCtx->hHal); + if (BMPS == pmc_state && first_adapter) + { + /* put the device into full power */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Disaling bmps during resume", __func__); + wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_ACTIVE); + } + + /*loop through all adapters. Concurrency */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + && (WLAN_HDD_SOFTAP != pAdapter->device_mode) + && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) ) + { // we skip this registration for modes other than STA, SAP and P2P client modes. + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + continue; + } + + +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_DEEP_SLEEP) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: WLAN being resumed from deep sleep",__func__); + hdd_exit_deep_sleep(pAdapter); + } +#endif + + if(pHddCtx->hdd_ignore_dtim_enabled == TRUE) + { + /*Switch back to DTIM 1*/ + tSirSetPowerParamsReq powerRequest = { 0 }; + + powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value; + powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value; + powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + + /*Disabled ModulatedDTIM if enabled on suspend*/ + if(pHddCtx->cfg_ini->enableModulatedDTIM) + powerRequest.uDTIMPeriod = 0; + + /* Update ignoreDTIM and ListedInterval in CFG with default values */ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM, + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval, + NULL, eANI_BOOLEAN_FALSE); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Switch to DTIM%d",powerRequest.uListenInterval); + sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE); + + if (BMPS == pmc_state) + { + pHddCtx->hdd_ignore_dtim_enabled = FALSE; + } + } + + hdd_conf_resume_ind(pAdapter); + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + if (BMPS == pmc_state && first_adapter) + { + /* put the device into full power */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Enable bmps during resume", __func__); + /* put the device back into BMPS */ + wlan_hdd_enter_bmps(first_adapter, DRIVER_POWER_MODE_AUTO); + } + +#ifdef SUPPORT_EARLY_SUSPEND_STANDBY_DEEPSLEEP + if(pHddCtx->hdd_ps_state == eHDD_SUSPEND_STANDBY) + { + hdd_exit_standby(pHddCtx); + } +#endif + + return; +} + +VOS_STATUS hdd_wlan_reset_initialization(void) +{ + v_CONTEXT_t pVosContext = NULL; + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN being reset",__func__); + + //Get the global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Preventing the phone from going to suspend",__func__); + + // Prevent the phone from going to sleep + hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT); + + return VOS_STATUS_SUCCESS; +} + + +/* + * Based on the ioctl command recieved by HDD, put WLAN driver + * into the quiet mode. This is the same as the early suspend + * notification that driver used to listen + */ +void hdd_set_wlan_suspend_mode(bool suspend) +{ + vos_ssr_protect(__func__); + if (suspend) + hdd_suspend_wlan(); + else + hdd_resume_wlan(); + vos_ssr_unprotect(__func__); +} + +static void hdd_ssr_timer_init(void) +{ + init_timer(&ssr_timer); +} + +static void hdd_ssr_timer_del(void) +{ + del_timer(&ssr_timer); + ssr_timer_started = false; +} + +static void hdd_ssr_timer_cb(unsigned long data) +{ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD SSR timer expired", __func__); + +#ifdef WCN_PRONTO + if (wcnss_hardware_type() == WCNSS_PRONTO_HW) + wcnss_pronto_log_debug_regs(); +#endif + + VOS_BUG(0); +} + +static void hdd_ssr_timer_start(int msec) +{ + if(ssr_timer_started) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: trying to start SSR timer when it's running" + ,__func__); + } + ssr_timer.expires = jiffies + msecs_to_jiffies(msec); + ssr_timer.function = hdd_ssr_timer_cb; + add_timer(&ssr_timer); + ssr_timer_started = true; +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * hdd_wlan_ssr_shutdown_event()- send ssr shutdown state + * + * This Function send send ssr shutdown state diag event + * + * Return: void. + */ +static void hdd_wlan_ssr_shutdown_event(void) +{ + WLAN_VOS_DIAG_EVENT_DEF(ssr_shutdown, + struct host_event_wlan_ssr_shutdown); + vos_mem_zero(&ssr_shutdown, sizeof(ssr_shutdown)); + ssr_shutdown.status = SSR_SUB_SYSTEM_SHUTDOWN; + WLAN_VOS_DIAG_EVENT_REPORT(&ssr_shutdown, + EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM); +} +#else +static inline void hdd_wlan_ssr_shutdown_event(void) +{ + +}; +#endif + +/* the HDD interface to WLAN driver shutdown, + * the primary shutdown function in SSR + */ +VOS_STATUS hdd_wlan_shutdown(void) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + pVosSchedContext vosSchedContext = NULL; + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutting down! ",__func__); + + /* if re-init never happens, then do SSR1 */ + hdd_ssr_timer_init(); + hdd_ssr_timer_start(HDD_SSR_BRING_UP_TIME); + + /* Get the global VOSS context. */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + /* Get the HDD context. */ + pHddCtx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return VOS_STATUS_E_FAILURE; + } + + vos_set_snoc_high_freq_voting(false); + //Stop the traffic monitor timer + if ((pHddCtx->cfg_ini->dynSplitscan)&& (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_stop(&pHddCtx->tx_rx_trafficTmr); + } + vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work); + vos_flush_work(&pHddCtx->sap_start_work); + hdd_reset_all_adapters(pHddCtx); + + /* set default value of Tcp delack and stop timer */ + hdd_set_default_stop_delack_timer(pHddCtx); + + /* DeRegister with platform driver as client for Suspend/Resume */ + vosStatus = hddDeregisterPmOps(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__); + } + + vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__); + } + + /* Disable IMPS/BMPS as we do not want the device to enter any power + * save mode on its own during reset sequence + */ + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE); + + vosSchedContext = get_vos_sched_ctxt(); + + /* Wakeup all driver threads */ + if(TRUE == pHddCtx->isMcThreadSuspended){ + complete(&vosSchedContext->ResumeMcEvent); + pHddCtx->isMcThreadSuspended= FALSE; + } + if(TRUE == pHddCtx->isTxThreadSuspended){ + complete(&vosSchedContext->ResumeTxEvent); + pHddCtx->isTxThreadSuspended= FALSE; + } + if(TRUE == pHddCtx->isRxThreadSuspended){ + complete(&vosSchedContext->ResumeRxEvent); + pHddCtx->isRxThreadSuspended= FALSE; + } + /* Reset the Suspend Variable */ + pHddCtx->isWlanSuspended = FALSE; + + /* Stop all the threads; we do not want any messages to be a processed, + * any more and the best way to ensure that is to terminate the threads + * gracefully. + */ + /* Wait for MC to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down MC thread",__func__); + set_bit(MC_SHUTDOWN_EVENT, &vosSchedContext->mcEventFlag); + set_bit(MC_POST_EVENT, &vosSchedContext->mcEventFlag); + wake_up_interruptible(&vosSchedContext->mcWaitQueue); + wait_for_completion(&vosSchedContext->McShutdown); + + /* Wait for TX to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down TX thread",__func__); + set_bit(TX_SHUTDOWN_EVENT, &vosSchedContext->txEventFlag); + set_bit(TX_POST_EVENT, &vosSchedContext->txEventFlag); + wake_up_interruptible(&vosSchedContext->txWaitQueue); + wait_for_completion(&vosSchedContext->TxShutdown); + + /* Wait for RX to exit */ + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Shutting down RX thread",__func__); + set_bit(RX_SHUTDOWN_EVENT, &vosSchedContext->rxEventFlag); + set_bit(RX_POST_EVENT, &vosSchedContext->rxEventFlag); + wake_up_interruptible(&vosSchedContext->rxWaitQueue); + + wait_for_completion(&vosSchedContext->RxShutdown); + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Stop(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop BAP",__func__); + } +#endif //WLAN_BTAMP_FEATURE + vosStatus = vos_wda_shutdown(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop wda %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing SME STOP",__func__); + /* Stop SME - Cannot invoke vos_stop as vos_stop relies + * on threads being running to process the SYS Stop + */ + vosStatus = sme_Stop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop sme %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing MAC STOP",__func__); + /* Stop MAC (PE and HAL) */ + vosStatus = macStop(pHddCtx->hHal, HAL_STOP_TYPE_SYS_RESET); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop mac %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Doing TL STOP",__func__); + /* Stop TL */ + vosStatus = WLANTL_Stop(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop TL %d", __func__, vosStatus); + VOS_ASSERT(0); + } + + hdd_unregister_mcast_bcast_filter(pHddCtx); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Flush Queues",__func__); + /* Clean up message queues of TX and MC thread */ + vos_sched_flush_mc_mqs(vosSchedContext); + vos_sched_flush_tx_mqs(vosSchedContext); + vos_sched_flush_rx_mqs(vosSchedContext); +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_flush_pkt_queue(); + /*Free fw dump mem in case of SSR/Shutdown */ + wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE); + wlan_free_fwr_mem_dump_buffer(); +#endif + + /* Deinit all the TX and MC queues */ + vos_sched_deinit_mqs(vosSchedContext); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Doing VOS Shutdown",__func__); + + /* shutdown VOSS */ + vos_shutdown(pVosContext); + + /*mac context has already been released in mac_close call + so setting it to NULL in hdd context*/ + pHddCtx->hHal = (tHalHandle)NULL; + + if (free_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock", + __func__); + } + hdd_wlan_ssr_shutdown_event(); + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN driver shutdown complete" + ,__func__); + return VOS_STATUS_SUCCESS; +} + +int hdd_dhcp_mdns_offload(hdd_adapter_t *adapter) +{ + hdd_config_t *config; + int status = VOS_STATUS_SUCCESS; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + config = hdd_ctx->cfg_ini; + if (NULL == config) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("cfg_ini is NULL!!")); + return -EINVAL; + } +#ifdef DHCP_SERVER_OFFLOAD + /* set dhcp server offload */ + if (config->enable_dhcp_srv_offload && + sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) { + vos_event_reset(&adapter->dhcp_status.vos_event); + status = wlan_hdd_set_dhcp_server_offload(adapter, true); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("HDD DHCP Server Offload Failed!!")); + return -EINVAL; + } + status = vos_wait_single_event(&adapter->dhcp_status.vos_event, 2000); + if (!VOS_IS_STATUS_SUCCESS(status) || + adapter->dhcp_status.dhcp_offload_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: DHCP HDD vos wait for single_event failed!! %d"), + adapter->dhcp_status.dhcp_offload_status); + return -EINVAL; + } +#ifdef MDNS_OFFLOAD + if (config->enable_mdns_offload) { + vos_event_reset(&adapter->mdns_status.vos_event); + status = wlan_hdd_set_mdns_offload(adapter); + if (VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("HDD MDNS Server Offload Failed!!")); + return -EINVAL; + } + status = vos_wait_single_event(&adapter-> + mdns_status.vos_event, 2000); + if (!VOS_IS_STATUS_SUCCESS(status) || + adapter->mdns_status.mdns_enable_status || + adapter->mdns_status.mdns_fqdn_status || + adapter->mdns_status.mdns_resp_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"), + adapter->mdns_status.mdns_enable_status, + adapter->mdns_status.mdns_fqdn_status, + adapter->mdns_status.mdns_resp_status); + return -EINVAL; + } + } +#endif /* MDNS_OFFLOAD */ + } else { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("DHCP Disabled ini %d, FW %d"), + config->enable_dhcp_srv_offload, + sme_IsFeatureSupportedByFW(SAP_OFFLOADS)); + } +#endif /* DHCP_SERVER_OFFLOAD */ + return status; +} + +/** + * hdd_ssr_restart_sap() - restart sap on SSR + * @hdd_ctx: hdd context + * + * Return: nothing + */ +static void hdd_ssr_restart_sap(hdd_context_t *hdd_ctx) +{ + VOS_STATUS status; + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + hdd_adapter_t *adapter; + hdd_hostapd_state_t *hostapd_state; + + ENTER(); + + status = hdd_get_front_adapter (hdd_ctx, &adapter_node); + while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (adapter && adapter->device_mode == WLAN_HDD_SOFTAP) { + if (test_bit(SOFTAP_INIT_DONE, &adapter->event_flags)) { + hostapd_state = + WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + hddLog(VOS_TRACE_LEVEL_INFO, FL("Restart prev SAP session")); + wlan_hdd_start_sap(adapter); + if (!VOS_IS_STATUS_SUCCESS( + hdd_dhcp_mdns_offload(adapter))) { + vos_event_reset( + &hostapd_state->vosEvent); + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("DHCP/MDNS offload Failed!!")); + if (VOS_STATUS_SUCCESS == + WLANSAP_StopBss( + hdd_ctx->pvosContext)) { + status = vos_wait_single_event( + &hostapd_state->vosEvent + , 10000); + if (!VOS_IS_STATUS_SUCCESS( + status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + return; + } + } + } + } + } + status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next); + adapter_node = next; + } + + EXIT(); +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** +* hdd_wlan_ssr_reinit_event()- send ssr reinit state +* +* This Function send send ssr reinit state diag event +* +* Return: void. +*/ +static void hdd_wlan_ssr_reinit_event(void) +{ + WLAN_VOS_DIAG_EVENT_DEF(ssr_reinit, struct host_event_wlan_ssr_reinit); + vos_mem_zero(&ssr_reinit, sizeof(ssr_reinit)); + ssr_reinit.status = SSR_SUB_SYSTEM_REINIT; + WLAN_VOS_DIAG_EVENT_REPORT(&ssr_reinit, + EVENT_WLAN_SSR_REINIT_SUBSYSTEM); +} +#else +static inline void hdd_wlan_ssr_reinit_event(void) +{ + +} +#endif + +/* the HDD interface to WLAN driver re-init. + * This is called to initialize/start WLAN driver after a shutdown. + */ +VOS_STATUS hdd_wlan_re_init(void) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + eHalStatus halStatus; +#ifdef HAVE_WCNSS_CAL_DOWNLOAD + int max_retries = 0; +#endif +#ifdef HAVE_CBC_DONE + int max_cbc_retries = 0; +#endif +#ifdef WLAN_BTAMP_FEATURE + hdd_config_t *pConfig = NULL; + WLANBAP_ConfigType btAmpConfig; +#endif + + struct device *dev = NULL; + hdd_ssr_timer_del(); + hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT); + +#ifdef HAVE_WCNSS_CAL_DOWNLOAD + /* wait until WCNSS driver downloads NV */ + while (!wcnss_device_ready() && 10 >= ++max_retries) { + msleep(1000); + } + if (max_retries >= 10) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__); + goto err_re_init; + } +#endif + +#ifdef HAVE_CBC_DONE + while (!wcnss_cbc_complete() && 20 >= ++max_cbc_retries) { + msleep(1000); + } + if (max_cbc_retries >= 20) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__); + } +#endif + + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, TRUE); + + /* The driver should always be initialized in STA mode after SSR */ + if (VOS_STA_SAP_MODE != hdd_get_conparam()) + hdd_set_conparam(0); + + dev = wcnss_wlan_get_device(); + if (NULL == dev) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wcnss dev is NULL",__func__); + goto err_re_init; + } + + /* Re-open VOSS, it is a re-open b'se control transport was never closed. */ + vosStatus = vos_open(&pVosContext, dev); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed",__func__); + goto err_re_init; + } + + /* Get the HDD context. */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if(!pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + goto err_vosclose; + } + + /* Save the hal context in Adapter */ + pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext ); + if ( NULL == pHddCtx->hHal ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HAL context is null",__func__); + goto err_vosclose; + } + + /* Set the SME configuration parameters. */ + vosStatus = hdd_set_sme_config(pHddCtx); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed hdd_set_sme_config",__func__); + goto err_vosclose; + } + + vosStatus = vos_preStart( pHddCtx->pvosContext ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__); + goto err_vosclose; + } + + /* In the integrated architecture we update the configuration from + the INI file and from NV before vOSS has been started so that + the final contents are available to send down to the cCPU */ + /* Apply the cfg.ini to cfg.dat */ + if (FALSE == hdd_update_config_dat(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ ); + goto err_vosclose; + } + + /* Set the MAC Address, currently this is used by HAL to add self sta. + * Remove this once self sta is added as part of session open. */ + halStatus = cfgSetStr(pHddCtx->hHal, WNI_CFG_STA_ID, + (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0], + sizeof(pHddCtx->cfg_ini->intfMacAddr[0])); + if (!HAL_STATUS_SUCCESS(halStatus)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. " + "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus); + goto err_vosclose; + } + + /* Start VOSS which starts up the SME/MAC/HAL modules and everything else + Note: Firmware image will be read and downloaded inside vos_start API */ + vosStatus = vos_start( pVosContext ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__); + if (isSsrPanicOnFailure()) + VOS_BUG(0); + goto err_vosclose; + } + + /* Exchange capability info between Host and FW and also get versioning info from FW */ + hdd_exchange_version_and_caps(pHddCtx); + + vosStatus = hdd_post_voss_start_config( pHddCtx ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed", + __func__); + goto err_vosstop; + } + +#ifdef CONFIG_ENABLE_LINUX_REG + vosStatus = wlan_hdd_init_channels_for_cc(pHddCtx, REINIT); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed", + __func__); + goto err_vosstop; + } +#endif + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Open(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open BAP",__func__); + goto err_vosstop; + } + vosStatus = BSL_Init(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Init BSL",__func__); + goto err_bap_close; + } + vosStatus = WLANBAP_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start TL",__func__); + goto err_bap_close; + } + pConfig = pHddCtx->cfg_ini; + btAmpConfig.ucPreferredChannel = pConfig->preferredChannel; + vosStatus = WLANBAP_SetConfig(&btAmpConfig); +#endif //WLAN_BTAMP_FEATURE + + /* Restart all adapters */ + hdd_start_all_adapters(pHddCtx); + pHddCtx->last_scan_reject_session_id = 0xFF; + pHddCtx->last_scan_reject_reason = 0; + pHddCtx->last_scan_reject_timestamp = 0; + pHddCtx->scan_reject_cnt = 0; + pHddCtx->hdd_mcastbcast_filter_set = FALSE; + pHddCtx->btCoexModeSet = FALSE; + hdd_register_mcast_bcast_filter(pHddCtx); + wlan_hdd_tdls_init(pHddCtx); + /* Register with platform driver as client for Suspend/Resume */ + vosStatus = hddRegisterPmOps(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__); + goto err_bap_stop; + } + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if (pHddCtx->cfg_ini->wlanLoggingEnable && + (pHddCtx->cfg_ini->enableFWLogging || + pHddCtx->cfg_ini->enableMgmtLogging || + pHddCtx->cfg_ini->enableContFWLogging)) + { + hdd_init_frame_logging(pHddCtx); + } +#endif + + /* Allow the phone to go to sleep */ + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT); + /* register for riva power on lock */ + if (req_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed", + __func__); + goto err_unregister_pmops; + } + sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb); + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + + sme_register_mgmt_frame_ind_callback(pHddCtx->hHal,hdd_indicate_mgmt_frame); + +#ifdef WLAN_FEATURE_EXTSCAN + sme_EXTScanRegisterCallback(pHddCtx->hHal, + wlan_hdd_cfg80211_extscan_callback, + pHddCtx); +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + sme_OemDataRegisterCallback(pHddCtx->hHal, + wlan_hdd_cfg80211_oemdata_callback, + pHddCtx); +#endif /* FEATURE_OEM_DATA_SUPPORT */ + + goto success; + +err_unregister_pmops: + hddDeregisterPmOps(pHddCtx); + +err_bap_stop: +#ifdef CONFIG_HAS_EARLYSUSPEND + hdd_unregister_mcast_bcast_filter(pHddCtx); +#endif + hdd_close_all_adapters(pHddCtx); +#ifdef WLAN_BTAMP_FEATURE + WLANBAP_Stop(pVosContext); +#endif + +#ifdef WLAN_BTAMP_FEATURE +err_bap_close: + WLANBAP_Close(pVosContext); +#endif + +err_vosstop: + vos_stop(pVosContext); + +err_vosclose: + if(!isSsrPanicOnFailure()) + { + /* If we hit this, it means wlan driver is in bad state and needs + * driver unload and load. + */ + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + return VOS_STATUS_E_FAILURE; + } + + vos_close(pVosContext); + vos_sched_close(pVosContext); + if (pHddCtx) + { + /* Unregister the Net Device Notifier */ + unregister_netdevice_notifier(&hdd_netdev_notifier); + /* Clean up HDD Nlink Service */ + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); +#ifdef WLAN_KD_READY_NOTIFIER + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ + /* Free up dynamically allocated members inside HDD Adapter */ + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + + wiphy_unregister(pHddCtx->wiphy); + hdd_wlan_free_wiphy_channels(pHddCtx->wiphy); + wiphy_free(pHddCtx->wiphy); + } + vos_preClose(&pVosContext); + +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif + +err_re_init: + /* Allow the phone to go to sleep */ + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT); + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + VOS_BUG(0); + return -EPERM; + +success: + hdd_wlan_ssr_reinit_event(); + /* Trigger replay of BTC events */ + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); + + if (pHddCtx->cfg_ini->sap_internal_restart) + hdd_ssr_restart_sap(pHddCtx); + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_ftm.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_ftm.c new file mode 100644 index 000000000000..7bf993d8c5f5 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_ftm.c @@ -0,0 +1,5967 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_ftm.c + + \brief This file contains the WLAN factory test mode implementation + + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/20/11 Leo/Henri Convergence for Prima and Volans. Single image + for FTM and mission mode + 04/5/09 Shailender Created module. + + ==========================================================================*/ +#include +#include "vos_sched.h" +#include +#include "sirTypes.h" +#include "halTypes.h" +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "sme_Api.h" +#include "macInitApi.h" +#include "wlan_qct_sys.h" +#include "wlan_qct_tl.h" +#include "wlan_hdd_misc.h" +#include "i_vos_packet.h" +#include "vos_nvitem.h" +#include "wlan_hdd_main.h" +#include "qwlan_version.h" + +#include "wlan_nv.h" +#include "wlan_qct_wda.h" +#include "cfgApi.h" +#include "pttMsgApi.h" +#include "wlan_qct_pal_device.h" +#include "linux/wcnss_wlan.h" +#include "qc_sap_ioctl.h" + +#define RXMODE_DISABLE_ALL 0 +#define RXMODE_ENABLE_ALL 1 +#define RXMODE_ENABLE_11GN 2 +#define RXMODE_ENABLE_11B 3 + +#define FTM_CHAIN_SEL_NO_RX_TX 0 +#define FTM_CHAIN_SEL_R0_ON 1 +#define FTM_CHAIN_SEL_T0_ON 2 +#define FTM_CHAIN_SEL_R0_T0_ON 3 +#define FTM_CHAIN_SEL_ANTENNA_0 7 +#define FTM_CHAIN_SEL_ANTENNA_1 8 +#define FTM_CHAIN_SEL_MAX 8 + +#define WCNSS_TXFIR_OFFSET 0x00018000 + +#define QWLAN_PHYDBG_TXPKT_CNT_CNT_MASK 0xFFFF + +#ifndef QWLAN_AGC_CHANNEL_FREQ_REG_OFFSET +#define QWLAN_AGC_CHANNEL_FREQ_REG_OFFSET 0x00013c34 +#define QWLAN_AGC_CHANNEL_FREQ_FREQ_MASK 0x1FFF +#endif /* QWLAN_AGC_CHANNEL_FREQ_REG_OFFSET */ + + +/* To set 4MAC addresses from given first MAC address, + * Last byte value within given MAC address must less than 0xFF - 3 */ +#define QWLAN_MAX_MAC_LAST_BYTE_VALUE 0xFC +#define NV_EMBEDDED_VERSION 0x80 + +#define QWLAN_TXFIR_CFG_DPD_BYPASS_MASK 0x8 + +typedef struct { + tANI_U32 tableSize; /* Whole NV Table Size */ + tANI_U32 chunkSize; /* Current Chunk Size < 2K */ + eNvTable nvTable; + tANI_U8 tableData; /* Filled by host driver */ +} pttGetNvTable; + +typedef struct { + tANI_U32 tableSize; /* Whole NV Table Size */ + tANI_U32 chunkSize; /* Current Chunk Size < 2K */ + eNvTable nvTable; + tANI_U8 tableData; +} pttSetNvTable; + + +extern const sHalNv nvDefaults; +static int wlan_ftm_register_wext(hdd_adapter_t *pAdapter); +static int wlan_ftm_stop(hdd_context_t *pHddCtx); +VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len); + +static rateStr2rateIndex_t rateName_rateIndex_tbl[] = +{ + { HAL_PHY_RATE_11B_LONG_1_MBPS, "11B_LONG_1_MBPS"}, + { HAL_PHY_RATE_11B_LONG_2_MBPS, "11B_LONG_2_MBPS"}, + { HAL_PHY_RATE_11B_LONG_5_5_MBPS, "11B_LONG_5_5_MBPS"}, + { HAL_PHY_RATE_11B_LONG_11_MBPS, "11B_LONG_11_MBPS"}, + { HAL_PHY_RATE_11B_SHORT_2_MBPS, "11B_SHORT_2_MBPS"}, + { HAL_PHY_RATE_11B_SHORT_5_5_MBPS, "11B_SHORT_5_5_MBPS"}, + { HAL_PHY_RATE_11B_SHORT_11_MBPS, "11B_SHORT_11_MBPS"}, + //Spica_Virgo 11A 20MHz Rates + { HAL_PHY_RATE_11A_6_MBPS, "11A_6_MBPS"}, + { HAL_PHY_RATE_11A_9_MBPS, "11A_9_MBPS"}, + { HAL_PHY_RATE_11A_12_MBPS, "11A_12_MBPS"}, + { HAL_PHY_RATE_11A_18_MBPS, "11A_18_MBPS"}, + { HAL_PHY_RATE_11A_24_MBPS, "11A_24_MBPS"}, + { HAL_PHY_RATE_11A_36_MBPS, "11A_36_MBPS"}, + { HAL_PHY_RATE_11A_48_MBPS, "11A_48_MBPS"}, + { HAL_PHY_RATE_11A_54_MBPS, "11A_54_MBPS"}, + +//MCS Index #0-15 (20MHz) + { HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, "MCS_6_5_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_13_MBPS, "MCS_13_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, "MCS_19_5_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_26_MBPS, "MCS_26_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_39_MBPS, "MCS_39_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_52_MBPS, "MCS_52_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, "MCS_58_5_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_65_MBPS, "MCS_65_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, "MCS_SG_7_2_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, "MCS_SG_14_4_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, "MCS_SG_21_7_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, "MCS_SG_28_9_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, "MCS_SG_43_3_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, "MCS_SG_57_8_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, "MCS_SG_65_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, "MCS_SG_72_2_MBPS"}, + +//MCS Index #8-15 (40MHz) + + { HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, "MCS_CB_13_5_MBPS" }, + { HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, "MCS_CB_27_MBPS" }, + { HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, "MCS_CB_40_5_MBPS" }, + { HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, "MCS_CB_54_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, "MCS_CB_81_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, "MCS_CB_108_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, "MCS_CB_121_5_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, "MCS_CB_135_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, "MCS_CB_15_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, "MCS_CB_30_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, "MCS_CB_45_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, "MCS_CB_60_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, "MCS_CB_90_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, "MCS_CB_120_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, "MCS_CB_135_MBPS"}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, "MCS_CB_150_MBPS"}, + +#ifdef WLAN_FEATURE_11AC + /*11AC rate 20MHZ Normal GI*/ + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_6_5_MBPS, "MCS_VHT20_NGI_6_5_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_13_MBPS, "MCS_VHT20_NGI_13_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_19_5_MBPS,"MCS_VHT20_NGI_19_5_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_26_MBPS, "MCS_VHT20_NGI_26_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_39_MBPS, "MCS_VHT20_NGI_39_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_52_MBPS, "MCS_VHT20_NGI_52_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_58_5_MBPS,"MCS_VHT20_NGI_58_5_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_65_MBPS, "MCS_VHT20_NGI_65_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_78_MBPS, "MCS_VHT20_NGI_78_MBPS"}, +#ifdef WCN_PRONTO + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS,"MCS_VHT20_NGI_86_5_MBPS"}, +#endif + + /*11AC rate 20MHZ Short GI*/ + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_7_2_MBPS, "MCS_VHT20_SGI_7_2_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_14_4_MBPS,"MCS_VHT20_SGI_14_4_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_21_6_MBPS,"MCS_VHT20_SGI_21_6_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_28_8_MBPS,"MCS_VHT20_SGI_28_8_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_43_3_MBPS,"MCS_VHT20_SGI_43_3_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_57_7_MBPS,"MCS_VHT20_SGI_57_7_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_65_MBPS, "MCS_VHT20_SGI_65_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_72_2_MBPS,"MCS_VHT20_SGI_72_2_MBPS"}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_86_6_MBPS,"MCS_VHT20_SGI_86_6_MBPS"}, +#ifdef WCN_PRONTO + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS,"MCS_VHT20_SGI_96_1_MBPS"}, +#endif + + /*11AC rates 40MHZ normal GI*/ + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + "MCS_VHT40_NGI_CB_13_5_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + "MCS_VHT40_NGI_CB_27_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + "MCS_VHT40_NGI_CB_40_5_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + "MCS_VHT40_NGI_CB_54_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + "MCS_VHT40_NGI_CB_81_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + "MCS_VHT40_NGI_CB_108_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + "MCS_VHT40_NGI_CB_121_5_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + "MCS_VHT40_NGI_CB_135_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + "MCS_VHT40_NGI_CB_162_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + "MCS_VHT40_NGI_CB_180_MBPS"}, + + /*11AC rates 40MHZ short GI*/ + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + "MCS_VHT40_SGI_CB_15_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + "MCS_VHT40_SGI_CB_30_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + "MCS_VHT40_SGI_CB_45_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + "MCS_VHT40_SGI_CB_60_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + "MCS_VHT40_SGI_CB_90_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + "MCS_VHT40_SGI_CB_120_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + "MCS_VHT40_SGI_CB_135_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + "MCS_VHT40_SGI_CB_150_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + "MCS_VHT40_SGI_CB_180_MBPS"}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + "MCS_VHT40_SGI_CB_200_MBPS"}, + + /*11AC rates 80 MHZ normal GI*/ + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + "MCS_VHT80_NGI_CB_29_3_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + "MCS_VHT80_NGI_CB_58_5_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + "MCS_VHT80_NGI_CB_87_8_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + "MCS_VHT80_NGI_CB_117_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + "MCS_VHT80_NGI_CB_175_5_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + "MCS_VHT80_NGI_CB_234_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + "MCS_VHT80_NGI_CB_263_3_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + "MCS_VHT80_NGI_CB_292_5_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + "MCS_VHT80_NGI_CB_351_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + "MCS_VHT80_NGI_CB_390_MBPS"}, + + /*11AC rates 80 MHZ short GI*/ + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + "MCS_VHT80_SGI_CB_32_5_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + "MCS_VHT80_SGI_CB_65_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + "MCS_VHT80_SGI_CB_97_5_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + "MCS_VHT80_SGI_CB_130_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + "MCS_VHT80_SGI_CB_195_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + "MCS_VHT80_SGI_CB_260_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + "MCS_VHT80_SGI_CB_292_5_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + "MCS_VHT80_SGI_CB_325_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + "MCS_VHT80_SGI_CB_390_MBPS"}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, + "MCS_VHT80_SGI_CB_433_3_MBPS"}, +#endif +}; + +static rateIndex2Preamble_t rate_index_2_preamble_table[] = +{ + + { HAL_PHY_RATE_11B_LONG_1_MBPS, PHYDBG_PREAMBLE_LONGB}, + { HAL_PHY_RATE_11B_LONG_2_MBPS, PHYDBG_PREAMBLE_LONGB}, + { HAL_PHY_RATE_11B_LONG_5_5_MBPS, PHYDBG_PREAMBLE_LONGB}, + { HAL_PHY_RATE_11B_LONG_11_MBPS, PHYDBG_PREAMBLE_LONGB}, + { HAL_PHY_RATE_11B_SHORT_2_MBPS, PHYDBG_PREAMBLE_SHORTB}, + { HAL_PHY_RATE_11B_SHORT_5_5_MBPS, PHYDBG_PREAMBLE_SHORTB}, + { HAL_PHY_RATE_11B_SHORT_11_MBPS, PHYDBG_PREAMBLE_SHORTB}, + + + //Spica_Virgo 11A 20MHz Rates + { HAL_PHY_RATE_11A_6_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_9_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_12_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_18_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_24_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_36_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_48_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_54_MBPS, PHYDBG_PREAMBLE_OFDM}, + + // 11A 20MHz Rates + { HAL_PHY_RATE_11A_DUP_6_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_9_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_12_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_18_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_24_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_36_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_48_MBPS, PHYDBG_PREAMBLE_OFDM}, + { HAL_PHY_RATE_11A_DUP_54_MBPS, PHYDBG_PREAMBLE_OFDM}, + + //MCS Index #0-15 (20MHz) + { HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_13_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_26_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_39_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_52_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_65_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS,PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS,PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS,PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS,PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS,PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, PHYDBG_PREAMBLE_NOT_SUPPORTED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, PHYDBG_PREAMBLE_MIXED}, + + //MCS index (40MHz) + { HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, PHYDBG_PREAMBLE_MIXED}, + +#ifdef WLAN_FEATURE_11AC + /*11AC rate 20MHZ Normal GI*/ + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_6_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_13_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_19_5_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_26_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_39_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_52_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_58_5_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_65_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_78_MBPS, PHYDBG_PREAMBLE_MIXED}, +#ifdef WCN_PRONTO + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS,PHYDBG_PREAMBLE_MIXED}, +#endif + /*11AC rate 20MHZ Short GI*/ + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_7_2_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_14_4_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_21_6_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_28_8_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_43_3_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_57_7_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_65_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_72_2_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_86_6_MBPS,PHYDBG_PREAMBLE_MIXED}, +#ifdef WCN_PRONTO + { HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS,PHYDBG_PREAMBLE_MIXED}, +#endif + + /*11AC rates 40MHZ normal GI*/ + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, PHYDBG_PREAMBLE_MIXED}, + + /*11AC rates 40MHZ short GI*/ + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS,PHYDBG_PREAMBLE_MIXED}, + + /*11AC rates 80 MHZ normal GI*/ + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, PHYDBG_PREAMBLE_MIXED}, + + /*11AC rates 80 MHZ short GI*/ + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS,PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, PHYDBG_PREAMBLE_MIXED}, + { HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS,PHYDBG_PREAMBLE_MIXED}, +#endif +}; + +static unsigned int valid_channel[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 36, 40, 44, 48, + 52, 56, 60, 64, 100, 104, 108, + 112, 116, 120, 124, 128, 132, + 136, 140, 149, 153, 157, 161, + 165, 208, 212, 216, 240, 244, + 248, 252, 0 }; +static unsigned int valid_channel_cb40[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 38, + 42, 46, 50, 54, 58, 62, 102, 106, + 110, 114, 118, 122, 126, 130, 134, + 138, 151, 155, 159, 163, 210, 214, + 242, 246, 250, 0 }; +static unsigned int valid_channel_cb80[] = { 7, 42, 46, 50, 54, 58, 106, 110, + 114, 118, 122, 126, 130, 134, 155, + 159, 246, 0 }; + +typedef struct +{ + tANI_BOOLEAN frameGenEnabled; + tANI_BOOLEAN wfRfGenEnabled; + tANI_BOOLEAN wfmEnabled; + sPttFrameGenParams frameParams; + v_U16_t powerCtlMode; + v_U16_t rxmode; + v_U16_t chainSelect; + ePhyChanBondState cbmode; + ePowerTempIndexSource powerIndex; + +} FTM_STATUS ; +static FTM_STATUS ftm_status; + +//tpAniSirGlobal pMac; +static tPttMsgbuffer *pMsgBuf; + +static void _ftm_status_init(void) +{ + tANI_U8 addr1[ANI_MAC_ADDR_SIZE] = { 0x00, 0x11, 0x11, 0x11, 0x11, 0x11 }; //dest + tANI_U8 addr2[ANI_MAC_ADDR_SIZE] = { 0x00, 0x22, 0x22, 0x22, 0x22, 0x22 }; //sour + tANI_U8 addr3[ANI_MAC_ADDR_SIZE] = { 0x00, 0x33, 0x33, 0x33, 0x33, 0x33 }; //bssId + + ftm_status.wfmEnabled = eANI_BOOLEAN_FALSE; + ftm_status.frameGenEnabled = eANI_BOOLEAN_FALSE; + ftm_status.wfRfGenEnabled = eANI_BOOLEAN_FALSE; + ftm_status.frameParams.numTestPackets = 0; //Continuous + ftm_status.frameParams.interFrameSpace = 200; + ftm_status.frameParams.rate = HAL_PHY_RATE_11A_6_MBPS; + ftm_status.frameParams.payloadContents = TEST_PAYLOAD_RANDOM; + ftm_status.frameParams.payloadLength = 1000; + ftm_status.frameParams.payloadFillByte = 0xA5; + ftm_status.frameParams.pktAutoSeqNum = eANI_BOOLEAN_FALSE; + ftm_status.frameParams.tx_mode = 0; + ftm_status.frameParams.crc = 0; + ftm_status.frameParams.preamble = PHYDBG_PREAMBLE_OFDM; + memcpy(&ftm_status.frameParams.addr1[0], addr1, ANI_MAC_ADDR_SIZE); + memcpy(&ftm_status.frameParams.addr2[0], addr2, ANI_MAC_ADDR_SIZE); + memcpy(&ftm_status.frameParams.addr3[0], addr3, ANI_MAC_ADDR_SIZE); + ftm_status.powerCtlMode= 2 ; //CLPC mode + ftm_status.rxmode = RXMODE_ENABLE_ALL; /* macStart() enables all receive pkt types */ + ftm_status.chainSelect = FTM_CHAIN_SEL_R0_T0_ON; + ftm_status.cbmode = 0 ; //none channel bonding + ftm_status.powerIndex = FIXED_POWER_DBM; + + return; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_postmsg() - + + The function used for sending the command to the halphy. + + \param - cmd_ptr - Pointer command buffer. + + \param - cmd_len - Command length. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static v_U32_t wlan_ftm_postmsg(v_U8_t *cmd_ptr, v_U16_t cmd_len) +{ + vos_msg_t *ftmReqMsg; + vos_msg_t ftmMsg; + ENTER(); + + ftmReqMsg = (vos_msg_t *) cmd_ptr; + + ftmMsg.type = WDA_FTM_CMD_REQ; + ftmMsg.reserved = 0; + ftmMsg.bodyptr = (v_U8_t*)cmd_ptr; + ftmMsg.bodyval = 0; + + /* Use Vos messaging mechanism to send the command to halPhy */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message( + VOS_MODULE_ID_WDA, + (vos_msg_t *)&ftmMsg)) { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__); + + return VOS_STATUS_E_FAILURE; + } + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + + \brief wlan_ftm_vos_open() - Open the vOSS Module + + The \a wlan_ftm_vos_open() function opens the vOSS Scheduler + Upon successful initialization: + + - All VOS submodules should have been initialized + + - The VOS scheduler should have opened + + - All the WLAN SW components should have been opened. This include + MAC. + + + \param devHandle: pointer to the OS specific device handle. + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa wlan_ftm_vos_open() + +---------------------------------------------------------------------------*/ +static VOS_STATUS wlan_ftm_vos_open( v_CONTEXT_t pVosContext, v_PVOID_t devHandle ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int iter = 0; + tSirRetStatus sirStatus = eSIR_SUCCESS; + tMacOpenParameters macOpenParms; + pVosContextType gpVosContext = (pVosContextType)pVosContext; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening VOSS", __func__); + + if (NULL == gpVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to open VOSS without a PreOpen",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Initialize the probe event */ + if (vos_event_init(&gpVosContext->ProbeEvent) != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init probeEvent",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + if(vos_event_init(&(gpVosContext->wdaCompleteEvent)) != VOS_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init wdaCompleteEvent",__func__); + VOS_ASSERT(0); + + goto err_probe_event; + } + + if(vos_event_init(&(gpVosContext->fwLogsComplete)) != VOS_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init fwLogsComplete",__func__); + VOS_ASSERT(0); + + goto err_wda_complete_event; + } + + /* Initialize the free message queue */ + vStatus = vos_mq_init(&gpVosContext->freeVosMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to initialize VOS free message queue %d", + __func__, vStatus); + VOS_ASSERT(0); + goto err_fw_logs_complete_event; + } + + for (iter = 0; iter < VOS_CORE_MAX_MESSAGES; iter++) + { + (gpVosContext->aMsgWrappers[iter]).pVosMsg = + &(gpVosContext->aMsgBuffers[iter]); + INIT_LIST_HEAD(&gpVosContext->aMsgWrappers[iter].msgNode); + vos_mq_put(&gpVosContext->freeVosMq, &(gpVosContext->aMsgWrappers[iter])); + } + + /* Now Open the VOS Scheduler */ + vStatus= vos_sched_open(gpVosContext, &gpVosContext->vosSched, + sizeof(VosSchedContext)); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open VOS Scheduler %d", __func__, vStatus); + VOS_ASSERT(0); + goto err_msg_queue; + } + + /* Open the SYS module */ + vStatus = sysOpen(gpVosContext); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open SYS module %d", __func__, vStatus); + VOS_ASSERT(0); + goto err_sched_close; + } + + /*Open the WDA module */ + vos_mem_set(&macOpenParms, sizeof(macOpenParms), 0); + macOpenParms.driverType = eDRIVER_TYPE_MFG; + vStatus = WDA_open(gpVosContext, devHandle, &macOpenParms); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open WDA module %d", __func__, vStatus); + VOS_ASSERT(0); + goto err_sys_close; + } + + /* initialize the NV module */ + vStatus = vos_nv_open(); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + // NV module cannot be initialized, however the driver is allowed + // to proceed + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to initialize the NV module %d", __func__, vStatus); + goto err_wda_close; + } + + vStatus = vos_nv_get_dictionary_data(); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to get dictionary data for NV %d", + __func__, vStatus); + goto err_wda_close; + } + + /* If we arrive here, both threads dispacthing messages correctly */ + + /* Now proceed to open the MAC */ + + /* UMA is supported in hardware for performing the + frame translation 802.11 <-> 802.3 */ + macOpenParms.frameTransRequired = 1; + sirStatus = macOpen(&(gpVosContext->pMACContext), gpVosContext->pHDDContext, + &macOpenParms); + + if (eSIR_SUCCESS != sirStatus) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open MAC %d", __func__, sirStatus); + VOS_ASSERT(0); + goto err_nv_close; + } + + /* Now proceed to open the SME */ + vStatus = sme_Open(gpVosContext->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open SME %d", __func__, vStatus); + goto err_mac_close; + } + return VOS_STATUS_SUCCESS; + + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS successfully Opened",__func__); + + return VOS_STATUS_SUCCESS; +err_mac_close: + macClose(gpVosContext->pMACContext); + +err_nv_close: + vos_nv_close(); + +err_wda_close: + WDA_close(gpVosContext); + +err_sys_close: + sysClose(gpVosContext); + +err_sched_close: + vos_sched_close(gpVosContext); +err_msg_queue: + vos_mq_deinit(&gpVosContext->freeVosMq); + +err_fw_logs_complete_event: + vos_event_destroy(&gpVosContext->fwLogsComplete); + +err_wda_complete_event: + vos_event_destroy(&gpVosContext->wdaCompleteEvent); + +err_probe_event: + vos_event_destroy(&gpVosContext->ProbeEvent); + + return VOS_STATUS_E_FAILURE; + +} /* wlan_ftm_vos_open() */ + +/*--------------------------------------------------------------------------- + + \brief wlan_ftm_vos_close() - Close the vOSS Module + + The \a wlan_ftm_vos_close() function closes the vOSS Module + + \param vosContext context of vos + + \return VOS_STATUS_SUCCESS - successfully closed + + \sa wlan_ftm_vos_close() + +---------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_vos_close( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + pVosContextType gpVosContext = (pVosContextType)vosContext; + + vosStatus = sme_Close(((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SME %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close MAC %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + ((pVosContextType)vosContext)->pMACContext = NULL; + + vosStatus = vos_nv_close(); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close NV %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + vosStatus = sysClose( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SYS %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + if ( TRUE == WDA_needShutdown(vosContext)) + { + vosStatus = WDA_shutdown(vosContext, VOS_TRUE); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to shutdown WDA %d", __func__, vosStatus); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + } + + } + else + { + vosStatus = WDA_close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close WDA %d", __func__, vosStatus); + VOS_ASSERT(VOS_IS_STATUS_SUCCESS(vosStatus)); + } + } + + vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq); + + vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy ProbeEvent %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy wdaCompleteEvent %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->fwLogsComplete); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy fwLogsComplete %d", __func__, vosStatus); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_txifs() - + + This function is used for + + \param - pAdapter - Pointer HDD Context. + - ifs + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + + +static VOS_STATUS wlan_ftm_priv_set_txifs(hdd_adapter_t *pAdapter,v_U32_t ifs) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + /* do not allow to change setting when tx pktgen is enabled */ + if (ftm_status.frameGenEnabled) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:cannot set txifs when pktgen is enabled.",__func__); + return VOS_STATUS_E_FAILURE; + } + + if (ifs > 100000) //max = (MSK_24 / ONE_MICROSECOND) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:ifs value is invalid %x", __func__, ifs); + return VOS_STATUS_E_FAILURE; + } + + ftm_status.frameParams.interFrameSpace = ifs; + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_txpktcnt() - + + This function is used for + + \param - pAdapter - Pointer HDD Context. + - ifs + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_set_txpktcnt(hdd_adapter_t *pAdapter,v_U32_t cnt) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + /* do not allow to change setting when tx pktgen is enabled */ + if (ftm_status.frameGenEnabled) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:cannot set txpktcnt when pktgen is enabled.",__func__); + return VOS_STATUS_E_FAILURE; + } + + if (cnt > QWLAN_PHYDBG_TXPKT_CNT_CNT_MASK) //0xFFFF + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pktcnt value is invalid %08x", __func__, cnt); + return VOS_STATUS_E_FAILURE; + } + + ftm_status.frameParams.numTestPackets = cnt; + + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wlan_ftm_priv_set_txpktlen(hdd_adapter_t *pAdapter,v_U32_t len) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + /* do not allow to change setting when tx pktgen is enabled */ + if (ftm_status.frameGenEnabled) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:cannot set txpktcnt when pktgen is enabled.",__func__); + return VOS_STATUS_E_FAILURE; + } + + if (len > 4095) //4096 + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:payload len is invalid %08x", __func__, len); + return VOS_STATUS_E_FAILURE; + } + + ftm_status.frameParams.payloadLength = (tANI_U16)len; + + return VOS_STATUS_SUCCESS; +} + + +static VOS_STATUS wlan_ftm_priv_start_stop_tx_pktgen(hdd_adapter_t *pAdapter,v_U16_t startStop); +/**--------------------------------------------------------------------------- +set_tx_wf_gain + is +Designates the number of amplitude gain (31 to 255). +Description +This command can be set only when Tx CW generation is stopped. +--------------------------------------------------------------------------*/ +static VOS_STATUS wlan_ftm_priv_set_wfgain(hdd_adapter_t *pAdapter,v_S15_t dGain,v_U16_t rfGain) +{ + uPttMsgs *pMsgBody; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + printk(KERN_EMERG "dGain: %02x rfGain: %02x", dGain,rfGain); + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm.", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (ftm_status.wfRfGenEnabled) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:cannot set gain when cwgen is enabled.", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (dGain > 24 || dGain <-39) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:digital gain value is invalid", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (rfGain > 31) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:rf gain value is invalid", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (pMsgBuf == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + wlan_ftm_priv_start_stop_tx_pktgen(pAdapter,0); + wlan_ftm_priv_start_stop_tx_pktgen(pAdapter,0); + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_SET_TX_WAVEFORM_GAIN_PRIMA_V1; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetTxWaveformGain_PRIMA_V1) + PTT_HEADER_LENGTH; + pMsgBody = &pMsgBuf->msgBody; + pMsgBody->SetTxWaveformGain_PRIMA_V1.txChain = PHY_TX_CHAIN_0; + pMsgBody->SetTxWaveformGain_PRIMA_V1.gain = (rfGain << 16 | (dGain & 0xffff)); + if (wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength) != + VOS_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed",__func__); + return VOS_STATUS_E_FAILURE; + } + + wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed",__func__); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + + +/**--------------------------------------------------------------------------- + wlan_ftm_priv_cw_rf_gen + is < 1 | 0 > + 1 : Start Tx CW rf generation + 0 : Stop Tx CW rf generation + Description + This command starts/stops Tx CW rf generation. +--------------------------------------------------------------------------*/ +static VOS_STATUS wlan_ftm_priv_cw_rf_gen(hdd_adapter_t *pAdapter,v_U16_t startStop) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + printk(KERN_EMERG "startStop: %02x ", startStop); + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (startStop != 1 && startStop != 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Tx value is invalid ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if ((ftm_status.wfRfGenEnabled && startStop == 1) || + (!ftm_status.wfRfGenEnabled && startStop == 0)) + { + return VOS_STATUS_SUCCESS; + } + + if (pMsgBuf == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + if (startStop == 1) { + tANI_U16 numSamples = 1; + tANI_BOOLEAN clk80 = TRUE; + v_BYTE_t msgT[4] = {0xff,0x00,0x00,0x00}; + + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_SET_WAVEFORM; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetWaveformRF) + PTT_HEADER_LENGTH; + pMsgBody = &pMsgBuf->msgBody; + + memcpy((v_BYTE_t*)pMsgBody->SetWaveformRF.waveform,msgT,4); + pMsgBody->SetWaveformRF.numSamples = numSamples; + pMsgBody->SetWaveformRF.clk80 = clk80; + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + if (status != VOS_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:posting PTT_MSG_CONFIG_TX_PACKET_GEN failed", + __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: PTT_MSG_CONFIG_TX_PACKET_GEN failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + } else { + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_STOP_WAVEFORM; + pMsgBuf->msgBodyLength = PTT_HEADER_LENGTH; + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + if(status != VOS_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if(pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + } + } +done: + if (status == VOS_STATUS_SUCCESS) { + if (startStop == 1) + ftm_status.wfRfGenEnabled = eANI_BOOLEAN_TRUE; + else + ftm_status.wfRfGenEnabled = eANI_BOOLEAN_FALSE; + } + return status; +} + + +static VOS_STATUS wlan_ftm_priv_enable_chain(hdd_adapter_t *pAdapter,v_U16_t chainSelect) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + v_U16_t chainSelect_save = chainSelect; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + long ret; + + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + if (chainSelect > FTM_CHAIN_SEL_MAX) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Invalid chain %08x", __func__, chainSelect); + return VOS_STATUS_E_FAILURE; + } + + /* do not allow to change setting when tx pktgen is enabled */ + if (ftm_status.frameGenEnabled) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:cannot select chain when pktgen is enabled.",__func__); + return VOS_STATUS_E_FAILURE; + } + + switch (chainSelect) + { + case FTM_CHAIN_SEL_NO_RX_TX: + chainSelect = PHY_CHAIN_SEL_NO_RX_TX; + break; + + case FTM_CHAIN_SEL_R0_ON: + chainSelect = PHY_CHAIN_SEL_R0_ON; + break; + + case FTM_CHAIN_SEL_T0_ON: + chainSelect = PHY_CHAIN_SEL_T0_ON; + break; + + case FTM_CHAIN_SEL_ANTENNA_0: + chainSelect = PHY_CHAIN_SEL_ANT_0; + break; + + case FTM_CHAIN_SEL_ANTENNA_1: + chainSelect = PHY_CHAIN_SEL_ANT_1; + break; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_ENABLE_CHAINS; + pMsgBuf->msgBodyLength = sizeof(tMsgPttEnableChains) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + pMsgBody->EnableChains.chainSelect = chainSelect; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ftm_status.chainSelect = chainSelect_save; +done: + + return status; +} + +/**--------------------------------------------------------------------------- + --------------------------------------------------------------------------*/ +static VOS_STATUS wlan_ftm_priv_get_status(hdd_adapter_t *pAdapter,char *buf) +{ + int ii; + int lenBuf = WE_FTM_MAX_STR_LEN; + int lenRes = 0; + char *chain[] = { + "None", + "R0,R1", + "R0", + "R1", + "T0", + "R0,R1,T0" + }; + char *rx[] = { + "disable", + "11b/g/n", + "11g/n", + "11b" + }; + char *tx[] = { + "stopped", + "started", + }; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + lenRes = snprintf(buf, lenBuf, "\n chainSelect: %s\n rxmode: %s\n " + "txpktgen: %s\n txifs: %d\n txrate: ", + chain[ftm_status.chainSelect], rx[ftm_status.rxmode], + tx[ftm_status.frameGenEnabled], + ftm_status.frameParams.interFrameSpace); + if ((lenRes < 0) || (lenRes >= lenBuf)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to copy data into buf %d"), lenRes); + return VOS_STATUS_E_FAILURE; + } + + buf += lenRes; + lenBuf -= lenRes; + + for (ii = 0; ii < SIZE_OF_TABLE(rateName_rateIndex_tbl); ii++) + { + if (rateName_rateIndex_tbl[ii].rate_index == ftm_status.frameParams.rate) + break; + } + + if (ii < SIZE_OF_TABLE(rateName_rateIndex_tbl)) + { + lenRes = strlcpy(buf, rateName_rateIndex_tbl[ii].rate_str, lenBuf); + } + else + { + lenRes = strlcpy(buf, "invalid", lenBuf); + } + if ((lenRes < 0) || (lenRes >= lenBuf)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to copy data into buf %d"), lenRes); + return VOS_STATUS_E_FAILURE; + } + + buf += lenRes; + lenBuf -= lenRes; + + lenRes = snprintf(buf, lenBuf, "\n power ctl mode: %d\n txpktcnt: %d\n " + "txpktlen: %d\n", ftm_status.powerCtlMode, + ftm_status.frameParams.numTestPackets, + ftm_status.frameParams.payloadLength); + + if ((lenRes < 0) || (lenRes >= lenBuf)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to copy data into buf %d"), lenRes); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + + +void HEXDUMP(char *s0, char *s1, int len) +{ + int i = 0, j = 0; + printk(KERN_EMERG "%s\n :", s0); + + if (len > 8) + { + for (j = 0; j < len/8; j++) + { + printk(KERN_EMERG "%02x %02x %02x %02x %02x %02x %02x %02x", + s1[j*8], s1[j*8+1], s1[j*8+2], s1[j*8+3], s1[j*8+4], + s1[j*8+5],s1[j*8+6],s1[j*8+7] ); + } + len = len - j*8; + } + for (i = 0; i< len; i++) { + printk(KERN_EMERG "%02x ", s1[j*8+i]); + } + printk("\n"); +} + +/*--------------------------------------------------------------------------- + + \brief vos_ftm_preStart() - + + The \a vos_ftm_preStart() function to download CFG. + including: + - ccmStart + + - WDA: triggers the CFG download + + + \param pVosContext: The VOS context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_start + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_ftm_preStart( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "vos prestart"); + + if (NULL == pVosContext->pWDAContext) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* call macPreStart */ + vStatus = macPreStart(pVosContext->pMACContext); + if ( !VOS_IS_STATUS_SUCCESS(vStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed at macPreStart "); + return VOS_STATUS_E_FAILURE; + } + + /* call ccmStart */ + ccmStart(pVosContext->pMACContext); + + /* Reset wda wait event */ + vos_event_reset(&pVosContext->wdaCompleteEvent); + + + /*call WDA pre start*/ + vStatus = WDA_preStart(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to WDA prestart "); + macStop(pVosContext->pMACContext, HAL_STOP_TYPE_SYS_DEEP_SLEEP); + ccmStop(pVosContext->pMACContext); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Need to update time out of complete */ + vStatus = vos_wait_single_event( &pVosContext->wdaCompleteEvent, 1000); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete",__func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_preStart reporting other error",__func__); + } + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_open() - + + The function hdd_wlan_startup calls this function to initialize the FTM specific modules. + + \param - pAdapter - Pointer HDD Context. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +int wlan_hdd_ftm_open(hdd_context_t *pHddCtx) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext= NULL; + hdd_adapter_t *pAdapter; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening VOSS", __func__); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL == pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to open VOSS without a PreOpen", __func__); + VOS_ASSERT(0); + goto err_vos_status_failure; + } + + // Open VOSS + vStatus = wlan_ftm_vos_open( pVosContext, pHddCtx->parent_dev); + + if ( !VOS_IS_STATUS_SUCCESS( vStatus )) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_open failed", __func__); + goto err_vos_status_failure; + } + + /* + For Integrated SOC, only needed to start WDA, whihc happens in wlan_hdd_ftm_start() + */ + /* Save the hal context in Adapter */ + pHddCtx->hHal = (tHalHandle)vos_get_context(VOS_MODULE_ID_SME, pVosContext ); + + if ( NULL == pHddCtx->hHal ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: HAL context is null", __func__); + goto err_ftm_vos_close; + } + + pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_FTM, "wlan%d", + wlan_hdd_get_intf_addr(pHddCtx), FALSE); + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed", __func__); + goto err_adapter_open_failure; + } + + if( wlan_ftm_register_wext(pAdapter)!= 0 ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_register_wext failed", __func__); + goto err_adapter_close; + } + + //Initialize the nlink service + if(nl_srv_init() != 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: nl_srv_init failed", __func__); + goto err_ftm_register_wext_close; + } + +#ifdef WLAN_KD_READY_NOTIFIER + pHddCtx->kd_nl_init = 1; +#endif /* WLAN_KD_READY_NOTIFIER */ + +#ifdef PTT_SOCK_SVC_ENABLE + //Initialize the PTT service + if(ptt_sock_activate_svc(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: ptt_sock_activate_svc failed", __func__); + goto err_nl_srv_init; + } +#endif + + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.targetNVTablePointer = NULL; + pHddCtx->ftm.processedNVTableSize = 0; + pHddCtx->ftm.tempNVTableBuffer = (v_U8_t *)vos_mem_malloc(MAX_NV_TABLE_SIZE); + if(NULL == pHddCtx->ftm.tempNVTableBuffer) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NV Table Buffer Alloc Fail", __func__); + VOS_ASSERT(0); + goto err_nl_srv_init; + } + vos_mem_zero((v_VOID_t *)pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + + _ftm_status_init(); + /* Initialize the ftm vos event */ + if (vos_event_init(&pHddCtx->ftm.ftm_vos_event) != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to init probeEvent", __func__); + VOS_ASSERT(0); + vos_mem_free(pHddCtx->ftm.tempNVTableBuffer); + goto err_nl_srv_init; + } + + pHddCtx->ftm.ftm_state = WLAN_FTM_INITIALIZED; + init_completion(&pHddCtx->ftm.startCmpVar); + + return VOS_STATUS_SUCCESS; + +err_nl_srv_init: +#ifdef WLAN_KD_READY_NOTIFIER +nl_srv_exit(pHddCtx->ptt_pid); +#else +nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ +ptt_sock_deactivate_svc(pHddCtx); +err_ftm_register_wext_close: +hdd_UnregisterWext(pAdapter->dev); + +err_adapter_close: +err_adapter_open_failure: +hdd_close_all_adapters( pHddCtx ); + +err_ftm_vos_close: + wlan_ftm_vos_close(pVosContext); +err_vos_status_failure: + + return VOS_STATUS_E_FAILURE; +} + + + +int wlan_hdd_ftm_close(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t vosContext = pHddCtx->pvosContext; + + hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_FTM); + ENTER(); + if(pAdapter == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__); + return VOS_STATUS_E_NOMEM; + } + + /*release the wlan_hdd_process_ftm_cmd(), if waiting for any response.*/ + if (pHddCtx->ftm.IsCmdPending == TRUE) + { + if (vos_event_set(&pHddCtx->ftm.ftm_vos_event)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + } + } + if(WLAN_FTM_STARTED == pHddCtx->ftm.ftm_state) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Ftm has been started. stopping ftm", __func__); + wlan_ftm_stop(pHddCtx); + } +#ifdef WLAN_KD_READY_NOTIFIER + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ + ptt_sock_deactivate_svc(pHddCtx); + + //TODO---------- + //Deregister the device with the kernel + hdd_UnregisterWext(pAdapter->dev); + +#if 0 + if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) + { + unregister_netdev(pAdapter->dev); + clear_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags); + } +#endif + //----------------- + + vosStatus = vos_sched_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close VOSS Scheduler",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + //Close VOSS + wlan_ftm_vos_close(vosContext); + hdd_close_all_adapters( pHddCtx ); + vosStatus = vos_event_destroy(&pHddCtx->ftm.ftm_vos_event); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to destroy ftm_vos Event",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + vos_mem_free(pHddCtx->ftm.tempNVTableBuffer); + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_send_response() - + + The function sends the response to the ptt socket application running in user space. + + \param - pAdapter - Pointer HDD Context. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_send_response(hdd_context_t *pHddCtx){ + + if( ptt_sock_send_msg_to_app(&pHddCtx->ftm.wnl->wmsg, 0, + ANI_NL_MSG_PUMAC, pHddCtx->ftm.wnl->nlh.nlmsg_pid, 0) < 0) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Ptt Socket error sending message to the app!!")); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_start() - + + This function gets called when the FTM start commands received from the ptt socket application and + it starts the following modules. + 1) SAL Start. + 2) BAL Start. + 3) MAC Start to download the firmware. + + + \param - pAdapter - Pointer HDD Context. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int wlan_hdd_ftm_start(hdd_context_t *pHddCtx) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + tSirRetStatus sirStatus = eSIR_SUCCESS; + pVosContextType pVosContext = (pVosContextType)(pHddCtx->pvosContext); + tHalMacStartParameters halStartParams; + + if (WLAN_FTM_STARTED == pHddCtx->ftm.ftm_state) + { + return VOS_STATUS_SUCCESS; + } + + pHddCtx->ftm.ftm_state = WLAN_FTM_STARTING; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Starting Libra SW", __func__); + + /* We support only one instance for now ...*/ + if (pVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: mismatch in context",__func__); + goto err_status_failure; + } + + + if (pVosContext->pMACContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: MAC NULL context",__func__); + goto err_status_failure; + } + + /* + Prima needs to start the WDA correctly instead of BAL and SAL + */ + + /* Vos preStart is calling */ + if ( !VOS_IS_STATUS_SUCCESS(vos_ftm_preStart(pHddCtx->pvosContext) ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_preStart failed",__func__); + goto err_status_failure; + } + + + vStatus = WDA_NVDownload_Start(pVosContext); + + if ( vStatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start NV Download",__func__); + return VOS_STATUS_E_FAILURE; + } + + vStatus = vos_wait_single_event(&(pVosContext->wdaCompleteEvent), 1000 * 30); + + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA_NVDownload_Start complete",__func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_NVDownload_Start reporting other error",__func__); + } + VOS_ASSERT(0); + WDA_setNeedShutdown(pHddCtx->pvosContext); + goto err_status_failure; + } + + vStatus = WDA_start(pVosContext); + if (vStatus != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start WDA",__func__); + goto err_status_failure; + } + + + /* Start the MAC */ + vos_mem_zero((v_PVOID_t)&halStartParams, sizeof(tHalMacStartParameters)); + + + halStartParams.driverType = eDRIVER_TYPE_MFG; + + /* Start the MAC */ + sirStatus = macStart(pVosContext->pMACContext,(v_PVOID_t)&halStartParams); + + + if (eSIR_SUCCESS != sirStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start MAC", __func__); + + goto err_wda_stop; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: MAC correctly started",__func__); + + + pHddCtx->ftm.ftm_state = WLAN_FTM_STARTED; + + return VOS_STATUS_SUCCESS; + +err_wda_stop: + vos_event_reset(&(pVosContext->wdaCompleteEvent)); + WDA_stop(pVosContext, HAL_STOP_TYPE_RF_KILL); + vStatus = vos_wait_single_event(&(pVosContext->wdaCompleteEvent), 1000); + if(vStatus != VOS_STATUS_SUCCESS) + { + if(vStatus == VOS_STATUS_E_TIMEOUT) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA_stop complete",__func__); + + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_stop reporting other error",__func__); + } + VOS_ASSERT(0); + } + +err_status_failure: + + pHddCtx->ftm.ftm_state = WLAN_FTM_INITIALIZED; + return VOS_STATUS_E_FAILURE; + +} + + +static int wlan_ftm_stop(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus; + + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + + //if(pHddCtx->ftm.cmd_iwpriv == TRUE) + { + /* STOP MAC only */ + v_VOID_t *hHal; + hHal = vos_get_context( VOS_MODULE_ID_SME, pHddCtx->pvosContext ); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL hHal", __func__); + } + else + { + vosStatus = macStop(hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + } + + + WDA_stop(pHddCtx->pvosContext, HAL_STOP_TYPE_RF_KILL); + + } + return WLAN_FTM_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_get_nv_table() - + Get Specific NV table + NV V2 dedicated API + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 1, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_get_nv_table +( + hdd_context_t *pHddCtx, + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + pttGetNvTable *nvTable = (pttGetNvTable *)&ftmCmd->msgBody.GetNvTable; + v_SIZE_t nvSize; + sHalNvV2 *nvContents = NULL; + eNvVersionType nvVersion; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Not valid driver context"); + return -EINVAL; + } + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V2 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + /* Test first chunk of NV table */ + if ((NV_MAX_TABLE == pHddCtx->ftm.processingNVTable) || + (0 == pHddCtx->ftm.processedNVTableSize)) + { + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if ((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + + switch (nvTable->nvTable) + { + case NV_TABLE_RATE_POWER_SETTINGS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.pwrOptimum); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.pwrOptimum; + break; + + case NV_TABLE_REGULATORY_DOMAINS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.regDomains); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.regDomains; + break; + + case NV_TABLE_DEFAULT_COUNTRY: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.defaultCountryTable); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.defaultCountryTable; + break; + + case NV_TABLE_TPC_POWER_TABLE: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.plutCharacterized); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.plutCharacterized[0]; + break; + + case NV_TABLE_TPC_PDADC_OFFSETS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.plutPdadcOffset); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.plutPdadcOffset[0]; + break; + + case NV_TABLE_VIRTUAL_RATE: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.pwrOptimum_virtualRate); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.pwrOptimum_virtualRate[0]; + break; + + case NV_TABLE_RSSI_CHANNEL_OFFSETS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.rssiChanOffsets); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.rssiChanOffsets[0]; + break; + + case NV_TABLE_HW_CAL_VALUES: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.hwCalValues); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.hwCalValues; + break; + + case NV_TABLE_FW_CONFIG: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.fwConfig); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.fwConfig; + break; + + case NV_TABLE_ANTENNA_PATH_LOSS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.antennaPathLoss); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.antennaPathLoss[0]; + break; + + case NV_TABLE_PACKET_TYPE_POWER_LIMITS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.pktTypePwrLimits); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.pktTypePwrLimits[0][0]; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV Table %d", nvTable->nvTable); + return -EIO; + break; + } + + if (pHddCtx->ftm.targetNVTableSize != nvTable->tableSize) + { + /* Invalid table size, discard and initialize data */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Invalid Table Size %d for Table %d" + " expected size %d", nvTable->tableSize, nvTable->nvTable, + pHddCtx->ftm.targetNVTableSize); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + return -EINVAL; + } + + /* Set Current Processing NV table type */ + pHddCtx->ftm.processingNVTable = nvTable->nvTable; + /* Copy target NV table value into temp context buffer */ + vos_mem_copy(pHddCtx->ftm.tempNVTableBuffer, + pHddCtx->ftm.targetNVTablePointer, + pHddCtx->ftm.targetNVTableSize); + + } + + if (pHddCtx->ftm.processingNVTable != nvTable->nvTable) + { + /* Invalid table type */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Invalid NV Table, now Processing %d, not %d", + pHddCtx->ftm.processingNVTable, nvTable->nvTable); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + + return -EINVAL; + } + + /* Copy next chunk of NV table value into response buffer */ + vos_mem_copy(&nvTable->tableData, + pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize, + nvTable->chunkSize); + /* Update processed pointer to prepare next chunk copy */ + pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize; + + if (pHddCtx->ftm.targetNVTableSize == pHddCtx->ftm.processedNVTableSize) + { + /* Finished to process last chunk of data, initialize buffer */ + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_set_nv_table() - + Set Specific NV table as given + NV V2 dedicated API + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 1, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_set_nv_table +( + hdd_context_t *pHddCtx, + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + pttSetNvTable *nvTable = (pttSetNvTable *)&ftmCmd->msgBody.SetNvTable; + v_SIZE_t nvSize; + sHalNvV2 *nvContents = NULL; + eNvVersionType nvVersion; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Not valid driver context"); + return -EINVAL; + } + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V2 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + /* Test first chunk of NV table */ + if ((NV_MAX_TABLE == pHddCtx->ftm.processingNVTable) || + (0 == pHddCtx->ftm.processedNVTableSize)) + { + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if ((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EINVAL; + } + + switch (nvTable->nvTable) + { + case NV_TABLE_RATE_POWER_SETTINGS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.pwrOptimum); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.pwrOptimum; + break; + + case NV_TABLE_REGULATORY_DOMAINS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.regDomains); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.regDomains; + break; + + case NV_TABLE_DEFAULT_COUNTRY: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.defaultCountryTable); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.defaultCountryTable; + break; + + case NV_TABLE_TPC_POWER_TABLE: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.plutCharacterized); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.plutCharacterized[0]; + break; + + case NV_TABLE_TPC_PDADC_OFFSETS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.plutPdadcOffset); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.plutPdadcOffset[0]; + break; + + case NV_TABLE_VIRTUAL_RATE: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.pwrOptimum_virtualRate); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.pwrOptimum_virtualRate[0]; + break; + + case NV_TABLE_RSSI_CHANNEL_OFFSETS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.rssiChanOffsets); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.rssiChanOffsets[0]; + break; + + case NV_TABLE_HW_CAL_VALUES: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.hwCalValues); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.hwCalValues; + break; + + case NV_TABLE_FW_CONFIG: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.fwConfig); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.fwConfig; + break; + + case NV_TABLE_ANTENNA_PATH_LOSS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.antennaPathLoss); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.antennaPathLoss[0]; + break; + + case NV_TABLE_PACKET_TYPE_POWER_LIMITS: + pHddCtx->ftm.targetNVTableSize = sizeof(nvContents->tables.pktTypePwrLimits); + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)&nvContents->tables.pktTypePwrLimits[0][0]; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV Table %d", nvTable->nvTable); + return -EIO; + break; + } + + /* Set Current Processing NV table type */ + pHddCtx->ftm.processingNVTable = nvTable->nvTable; + if (pHddCtx->ftm.targetNVTableSize != nvTable->tableSize) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Invalid Table Size %d", nvTable->tableSize); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + return -EINVAL; + } + } + + if (pHddCtx->ftm.processingNVTable != nvTable->nvTable) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Invalid NV Table, now Processing %d, not %d", + pHddCtx->ftm.processingNVTable, nvTable->nvTable); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + return -EINVAL; + } + vos_mem_copy(pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize, + &nvTable->tableData, + nvTable->chunkSize); + + pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize; + if (pHddCtx->ftm.targetNVTableSize == pHddCtx->ftm.processedNVTableSize) + { + vos_mem_copy(pHddCtx->ftm.targetNVTablePointer, + pHddCtx->ftm.tempNVTableBuffer, + pHddCtx->ftm.targetNVTableSize); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_blank_nv() - + Set all NV table value as default + NV V2 dedicated API + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 0, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_blank_nv_table +( + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + v_SIZE_t nvSize; + v_SIZE_t itemSize; + sHalNvV2 *nvContents = NULL; + eNvVersionType nvVersion; + + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V2 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + itemSize = sizeof(nvContents->tables.pwrOptimum); + memcpy(&nvContents->tables.pwrOptimum, + &nvDefaultsV2.tables.pwrOptimum, + itemSize); + + itemSize = sizeof(nvContents->tables.regDomains); + memcpy(&nvContents->tables.regDomains, + &nvDefaultsV2.tables.regDomains, + itemSize); + + itemSize = sizeof(nvContents->tables.defaultCountryTable); + memcpy(&nvContents->tables.defaultCountryTable, + &nvDefaultsV2.tables.defaultCountryTable, + itemSize); + + itemSize = sizeof(nvContents->tables.plutCharacterized); + memcpy(&nvContents->tables.plutCharacterized[0], + &nvDefaultsV2.tables.plutCharacterized[0], + itemSize); + + itemSize = sizeof(nvContents->tables.plutPdadcOffset); + memcpy(&nvContents->tables.plutPdadcOffset[0], + &nvDefaultsV2.tables.plutPdadcOffset[0], + itemSize); + + itemSize = sizeof(nvContents->tables.pwrOptimum_virtualRate); + memcpy(&nvContents->tables.pwrOptimum_virtualRate[0], + &nvDefaultsV2.tables.pwrOptimum_virtualRate[0], + itemSize); + + itemSize = sizeof(nvContents->tables.rssiChanOffsets); + memcpy(&nvContents->tables.rssiChanOffsets[0], + &nvDefaultsV2.tables.rssiChanOffsets[0], + itemSize); + + itemSize = sizeof(nvContents->tables.hwCalValues); + memcpy(&nvContents->tables.hwCalValues, + &nvDefaultsV2.tables.hwCalValues, + itemSize); + + itemSize = sizeof(nvContents->tables.antennaPathLoss); + memcpy(&nvContents->tables.antennaPathLoss[0], + &nvDefaultsV2.tables.antennaPathLoss[0], + itemSize); + + itemSize = sizeof(nvContents->tables.pktTypePwrLimits); + memcpy(&nvContents->tables.pktTypePwrLimits[0][0], + &nvDefaultsV2.tables.pktTypePwrLimits[0][0], + itemSize); + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_delete_nv_table() - + Delete Specific NV table + NV V2 dedicated API + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 1, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_delete_nv_table +( + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + tMsgPttDelNvTable *nvTable = (tMsgPttDelNvTable *)&ftmCmd->msgBody.DelNvTable; + v_SIZE_t nvSize; + v_SIZE_t itemSize; + sHalNvV2 *nvContents = NULL; + eNvVersionType nvVersion; + + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if ((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V2 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + switch (nvTable->nvTable) + { + case NV_TABLE_RATE_POWER_SETTINGS: + itemSize = sizeof(nvContents->tables.pwrOptimum); + memcpy(&nvContents->tables.pwrOptimum, + &nvDefaultsV2.tables.pwrOptimum, + itemSize); + break; + + case NV_TABLE_REGULATORY_DOMAINS: + itemSize = sizeof(nvContents->tables.regDomains); + memcpy(&nvContents->tables.regDomains, + &nvDefaultsV2.tables.regDomains, + itemSize); + break; + + case NV_TABLE_DEFAULT_COUNTRY: + itemSize = sizeof(nvContents->tables.defaultCountryTable); + memcpy(&nvContents->tables.defaultCountryTable, + &nvDefaultsV2.tables.defaultCountryTable, + itemSize); + break; + + case NV_TABLE_TPC_POWER_TABLE: + itemSize = sizeof(nvContents->tables.plutCharacterized); + memcpy(&nvContents->tables.plutCharacterized[0], + &nvDefaultsV2.tables.plutCharacterized[0], + itemSize); + break; + + case NV_TABLE_TPC_PDADC_OFFSETS: + itemSize = sizeof(nvContents->tables.plutPdadcOffset); + memcpy(&nvContents->tables.plutPdadcOffset[0], + &nvDefaultsV2.tables.plutPdadcOffset[0], + itemSize); + break; + + case NV_TABLE_VIRTUAL_RATE: + itemSize = sizeof(nvContents->tables.pwrOptimum_virtualRate); + memcpy(&nvContents->tables.pwrOptimum_virtualRate[0], + &nvDefaultsV2.tables.pwrOptimum_virtualRate[0], + itemSize); + break; + + case NV_TABLE_RSSI_CHANNEL_OFFSETS: + itemSize = sizeof(nvContents->tables.rssiChanOffsets); + memcpy(&nvContents->tables.rssiChanOffsets[0], + &nvDefaultsV2.tables.rssiChanOffsets[0], + itemSize); + break; + + case NV_TABLE_HW_CAL_VALUES: + itemSize = sizeof(nvContents->tables.hwCalValues); + memcpy(&nvContents->tables.hwCalValues, + &nvDefaultsV2.tables.hwCalValues, + itemSize); + break; + + case NV_TABLE_FW_CONFIG: + itemSize = sizeof(nvContents->tables.fwConfig); + memcpy(&nvContents->tables.fwConfig, + &nvDefaultsV2.tables.fwConfig, + itemSize); + break; + + case NV_TABLE_ANTENNA_PATH_LOSS: + itemSize = sizeof(nvContents->tables.antennaPathLoss); + memcpy(&nvContents->tables.antennaPathLoss[0], + &nvDefaultsV2.tables.antennaPathLoss[0], + itemSize); + break; + + case NV_TABLE_PACKET_TYPE_POWER_LIMITS: + itemSize = sizeof(nvContents->tables.pktTypePwrLimits); + memcpy(&nvContents->tables.pktTypePwrLimits[0][0], + &nvDefaultsV2.tables.pktTypePwrLimits[0][0], + itemSize); + break; + + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV Table %d", nvTable->nvTable); + return -EIO; + break; + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_get_nv_field() - + Get Specific NV field + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 1, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_get_nv_field +( + tPttMsgbuffer *ftmCmd +) +{ + sNvFields nvFieldDataBuffer; + tMsgPttGetNvField *nvField = (tMsgPttGetNvField *)&ftmCmd->msgBody.GetNvField; + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + sHalNv *nvContents = NULL; + v_SIZE_t nvSize; + + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if ((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + memcpy(&nvFieldDataBuffer, &nvContents->fields, sizeof(sNvFields)); + + switch (nvField->nvField) + { + case NV_COMMON_PRODUCT_ID: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.productId, + sizeof(nvFieldDataBuffer.productId)); + break; + + case NV_COMMON_PRODUCT_BANDS: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.productBands, + sizeof(nvFieldDataBuffer.productBands)); + break; + + case NV_COMMON_NUM_OF_TX_CHAINS: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.numOfTxChains, + sizeof(nvFieldDataBuffer.numOfTxChains)); + break; + + case NV_COMMON_NUM_OF_RX_CHAINS: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.numOfRxChains, + sizeof(nvFieldDataBuffer.numOfRxChains)); + break; + + case NV_COMMON_MAC_ADDR: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.macAddr[0], + NV_FIELD_MAC_ADDR_SIZE); + break; + + case NV_COMMON_MFG_SERIAL_NUMBER: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.mfgSN[0], + NV_FIELD_MFG_SN_SIZE); + break; + + case NV_COMMON_WLAN_NV_REV_ID: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.wlanNvRevId, + sizeof(nvFieldDataBuffer.wlanNvRevId)); + break; + + case NV_COMMON_COUPLER_TYPE: + memcpy((void *)&nvField->fieldData, + &nvFieldDataBuffer.couplerType, + sizeof(nvFieldDataBuffer.couplerType)); + break; + + case NV_COMMON_NV_VERSION: + { + VOS_STATUS nvEmbededStatus = VOS_STATUS_SUCCESS; + v_U8_t nvVersion = nvFieldDataBuffer.nvVersion; + + nvEmbededStatus = vos_nv_isEmbeddedNV(); + + if ( nvEmbededStatus == VOS_STATUS_SUCCESS ) + { + // High bit is set to indicate embedded NV.. + nvVersion = nvVersion | NV_EMBEDDED_VERSION; + } + + memcpy((void *)&nvField->fieldData, + &nvVersion, + sizeof(nvFieldDataBuffer.nvVersion)); + } + break; + + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV field %d", nvField->nvField); + return -EIO; + break; + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_set_nv_field() - + Set Specific NV field + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 1, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_set_nv_field +( + tPttMsgbuffer *ftmCmd +) +{ + tMsgPttSetNvField *nvField = (tMsgPttSetNvField *)&ftmCmd->msgBody.SetNvField; + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + v_SIZE_t nvSize; + sHalNv *nvContents = NULL; + v_U8_t macLoop; + v_U8_t *pNVMac; + v_U8_t lastByteMAC; + + + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + + switch (nvField->nvField) + { + case NV_COMMON_PRODUCT_ID: + memcpy(&nvContents->fields.productId, + &nvField->fieldData, + sizeof(nvContents->fields.productId)); + break; + + case NV_COMMON_PRODUCT_BANDS: + memcpy(&nvContents->fields.productBands, + &nvField->fieldData, + sizeof(nvContents->fields.productBands)); + break; + + case NV_COMMON_NUM_OF_TX_CHAINS: + memcpy(&nvContents->fields.numOfTxChains, + &nvField->fieldData, + sizeof(nvContents->fields.numOfTxChains)); + break; + + case NV_COMMON_NUM_OF_RX_CHAINS: + memcpy(&nvContents->fields.numOfRxChains, + &nvField->fieldData, + sizeof(nvContents->fields.numOfRxChains)); + break; + + case NV_COMMON_MAC_ADDR: + /* If Last byte is larger than 252 (0xFC), return Error, + * Since 3MACs should be derived from first MAC */ + if(QWLAN_MAX_MAC_LAST_BYTE_VALUE < + nvField->fieldData.macAddr.macAddr1[VOS_MAC_ADDRESS_LEN - 1]) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Last Byte of the seed MAC is too large 0x%x", + nvField->fieldData.macAddr.macAddr1[VOS_MAC_ADDRESS_LEN - 1]); + return -EILSEQ; + } + + pNVMac = (v_U8_t *)nvContents->fields.macAddr; + lastByteMAC = nvField->fieldData.macAddr.macAddr1[VOS_MAC_ADDRESS_LEN - 1]; + for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++) + { + nvField->fieldData.macAddr.macAddr1[VOS_MAC_ADDRESS_LEN - 1] = + lastByteMAC + macLoop; + vos_mem_copy(pNVMac + (macLoop * NV_FIELD_MAC_ADDR_SIZE), + &nvField->fieldData.macAddr.macAddr1[0], + NV_FIELD_MAC_ADDR_SIZE); + } + break; + + case NV_COMMON_MFG_SERIAL_NUMBER: + memcpy(&nvContents->fields.mfgSN[0], + &nvField->fieldData, + NV_FIELD_MFG_SN_SIZE); + break; + + case NV_COMMON_WLAN_NV_REV_ID: + memcpy(&nvContents->fields.wlanNvRevId, + &nvField->fieldData, + sizeof(nvContents->fields.wlanNvRevId)); + break; + + case NV_COMMON_COUPLER_TYPE: + memcpy(&nvContents->fields.couplerType, + &nvField->fieldData, + sizeof(nvContents->fields.couplerType)); + break; + + case NV_COMMON_NV_VERSION: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Cannot modify NV version field %d", nvField->nvField); + return -EIO; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV field %d", nvField->nvField); + return -EIO; + break; + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_store_nv_table() - + Store Cached NV information into Flash Memory, file + NV V2 dedicated API + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 0, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_store_nv_table +( + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + v_SIZE_t nvSize; + tMsgPttStoreNvTable *nvTable = (tMsgPttStoreNvTable *)&ftmCmd->msgBody.StoreNvTable; + void *tablePtr = NULL; + unsigned int tableSize = 0; + VNV_TYPE tableVNVType = VNV_FIELD_IMAGE; + sHalNvV2 *nvContents = NULL; + eNvVersionType nvVersion; + + nvStatus = vos_nv_getNVBuffer((void **)&nvContents, &nvSize); + if((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V2 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + /* Set Platform type as PRIMA */ + nvContents->fields.wlanNvRevId = 2; + + switch(nvTable->nvTable) + { + case NV_FIELDS_IMAGE: + tablePtr = (void *)&nvContents->fields; + tableSize = sizeof(nvContents->fields); + tableVNVType = VNV_FIELD_IMAGE; + break; + + case NV_TABLE_RATE_POWER_SETTINGS: + tablePtr = (void *)&nvContents->tables.pwrOptimum[0]; + tableSize = sizeof(nvContents->tables.pwrOptimum); + tableVNVType = VNV_RATE_TO_POWER_TABLE; + break; + + case NV_TABLE_REGULATORY_DOMAINS: + tablePtr = (void *)&nvContents->tables.regDomains[0]; + tableSize = sizeof(nvContents->tables.regDomains); + tableVNVType = VNV_REGULARTORY_DOMAIN_TABLE; + break; + + case NV_TABLE_DEFAULT_COUNTRY: + tablePtr = (void *)&nvContents->tables.defaultCountryTable; + tableSize = sizeof(nvContents->tables.defaultCountryTable); + tableVNVType = VNV_DEFAULT_LOCATION; + break; + + case NV_TABLE_TPC_POWER_TABLE: + tablePtr = (void *)&nvContents->tables.plutCharacterized[0]; + tableSize = sizeof(nvContents->tables.plutCharacterized); + tableVNVType = VNV_TPC_POWER_TABLE; + break; + + case NV_TABLE_TPC_PDADC_OFFSETS: + tablePtr = (void *)&nvContents->tables.plutPdadcOffset[0]; + tableSize = sizeof(nvContents->tables.plutPdadcOffset); + tableVNVType = VNV_TPC_PDADC_OFFSETS; + break; + + case NV_TABLE_VIRTUAL_RATE: + tablePtr = (void *)&nvContents->tables.pwrOptimum_virtualRate[0]; + tableSize = sizeof(nvContents->tables.pwrOptimum_virtualRate); + tableVNVType = VNV_TABLE_VIRTUAL_RATE; + break; + + case NV_TABLE_RSSI_CHANNEL_OFFSETS: + tablePtr = (void *)&nvContents->tables.rssiChanOffsets[0]; + tableSize = sizeof(nvContents->tables.rssiChanOffsets); + tableVNVType = VNV_RSSI_CHANNEL_OFFSETS; + break; + + case NV_TABLE_HW_CAL_VALUES: + tablePtr = (void *)&nvContents->tables.hwCalValues; + tableSize = sizeof(nvContents->tables.hwCalValues); + tableVNVType = VNV_HW_CAL_VALUES; + break; + + case NV_TABLE_FW_CONFIG: + tablePtr = (void *)&nvContents->tables.fwConfig; + tableSize = sizeof(nvContents->tables.fwConfig); + tableVNVType = VNV_FW_CONFIG; + break; + + case NV_TABLE_ANTENNA_PATH_LOSS: + tablePtr = (void *)&nvContents->tables.antennaPathLoss[0]; + tableSize = sizeof(nvContents->tables.antennaPathLoss); + tableVNVType = VNV_ANTENNA_PATH_LOSS; + break; + + case NV_TABLE_PACKET_TYPE_POWER_LIMITS: + tablePtr = (void *)&nvContents->tables.pktTypePwrLimits[0][0]; + tableSize = sizeof(nvContents->tables.pktTypePwrLimits); + tableVNVType = VNV_PACKET_TYPE_POWER_LIMITS; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Supported Table Type %d", nvTable->nvTable); + return -EIO; + break; + + } + + nvStatus = vos_nv_write(tableVNVType, + tablePtr, + tableSize); + if(VOS_STATUS_SUCCESS != nvStatus) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Failed update nv item %d", nvStatus); + return -EIO; + } + + return 1; +} + +/* -------------------------------------------------------------------------- + \brief wlan_hdd_ftm_get_nv_bin() - + Get NV bin read from Flash Memory, file + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 0, Process Host command success +--------------------------------------------------------------------------*/ + +static int wlan_hdd_ftm_get_nv_bin +( + v_U16_t msgId, + hdd_context_t *pHddCtx, + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + pttGetNvTable *nvTable = (pttGetNvTable *)&ftmCmd->msgBody.GetNvBin; + v_SIZE_t nvSize; + v_U8_t *nvContents; + v_U16_t offset = 0; + eNvVersionType nvVersion; + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V3 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + if ((NV_MAX_TABLE == pHddCtx->ftm.processingNVTable) || + (0 == pHddCtx->ftm.processedNVTableSize)) + { + if ( msgId == PTT_MSG_GET_NV_BIN ) + { + nvStatus = vos_nv_getNVEncodedBuffer((void **)&nvContents, &nvSize); + } + else + { + nvStatus = vos_nv_getNVDictionary((void **)&nvContents, &nvSize); + } + + if ((VOS_STATUS_SUCCESS != nvStatus) || (NULL == nvContents)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Fail to get cached NV value Status %d"), nvStatus); + return -EIO; + } + + switch (nvTable->nvTable) + { + case NV_BINARY_IMAGE: + pHddCtx->ftm.targetNVTablePointer = (v_U8_t *)nvContents; + break; + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV Table %d", nvTable->nvTable); + return -EIO; + break; + } + + /* Set Current Processing NV table type */ + pHddCtx->ftm.processingNVTable = nvTable->nvTable; + if ( msgId == PTT_MSG_GET_NV_BIN ) + { + pHddCtx->ftm.targetNVTableSize = nvSize + sizeof(v_U32_t); + /* Validity Period */ + pHddCtx->ftm.tempNVTableBuffer[0] = 0xFF; + pHddCtx->ftm.tempNVTableBuffer[1] = 0xFF; + pHddCtx->ftm.tempNVTableBuffer[2] = 0xFF; + pHddCtx->ftm.tempNVTableBuffer[3] = 0xFF; + offset = sizeof(v_U32_t); + } + else + { + pHddCtx->ftm.targetNVTableSize = nvSize; + offset = 0; + } + + /* Copy target NV table value into temp context buffer */ + vos_mem_copy(&pHddCtx->ftm.tempNVTableBuffer[offset], + pHddCtx->ftm.targetNVTablePointer, + pHddCtx->ftm.targetNVTableSize); + } + + + if (pHddCtx->ftm.processingNVTable != nvTable->nvTable) + { + /* Invalid table type */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Invalid NV Table, now Processing %d, not %d", + pHddCtx->ftm.processingNVTable, nvTable->nvTable); + + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + + return -EINVAL; + } + + nvTable->tableSize = pHddCtx->ftm.targetNVTableSize; + + /* Update processed pointer to prepare next chunk copy */ + if ( (nvTable->chunkSize + pHddCtx->ftm.processedNVTableSize) > + pHddCtx->ftm.targetNVTableSize ) + { + nvTable->chunkSize = + (pHddCtx->ftm.targetNVTableSize - pHddCtx->ftm.processedNVTableSize); + } + + /* Copy next chunk of NV table value into response buffer */ + vos_mem_copy( + &nvTable->tableData, + pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize, + nvTable->chunkSize); + + pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize; + + if (pHddCtx->ftm.targetNVTableSize == pHddCtx->ftm.processedNVTableSize) + { + /* Finished to process last chunk of data, initialize buffer */ + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_set_nv_bin() - + Set NV bin to Flash Memory, file + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 0, Process Host command success + ++----------------------------------------------------------------------------*/ + +static int wlan_hdd_ftm_set_nv_bin +( + hdd_context_t *pHddCtx, + tPttMsgbuffer *ftmCmd +) +{ + VOS_STATUS nvStatus = VOS_STATUS_SUCCESS; + pttSetNvTable *nvTable = (pttSetNvTable *)&ftmCmd->msgBody.SetNvBin; + eNvVersionType nvVersion; + + nvVersion = vos_nv_getNvVersion(); + if (E_NV_V3 != nvVersion) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s : Not valid NV Version %d", __func__, nvVersion); + return -EINVAL; + } + + + /* Test first chunk of NV table */ + if ((NV_MAX_TABLE == pHddCtx->ftm.processingNVTable) || + (0 == pHddCtx->ftm.processedNVTableSize)) + { + switch (nvTable->nvTable) + { + case NV_BINARY_IMAGE: + pHddCtx->ftm.targetNVTableSize = nvTable->tableSize; + break; + default: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Not Valid NV Table %d", nvTable->nvTable); + return -EIO; + break; + } + + /* Set Current Processing NV table type */ + pHddCtx->ftm.processingNVTable = nvTable->nvTable; + pHddCtx->ftm.processedNVTableSize = 0; + + if (pHddCtx->ftm.targetNVTableSize != nvTable->tableSize) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Invalid Table Size %d", nvTable->tableSize); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + return -EINVAL; + } + } + + if (pHddCtx->ftm.processingNVTable != nvTable->nvTable) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Invalid NV Table, now Processing %d, not %d", + pHddCtx->ftm.processingNVTable, nvTable->nvTable); + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + return -EINVAL; + } + + vos_mem_copy( + pHddCtx->ftm.tempNVTableBuffer + pHddCtx->ftm.processedNVTableSize, + &nvTable->tableData, + nvTable->chunkSize); + + pHddCtx->ftm.processedNVTableSize += nvTable->chunkSize; + + if (pHddCtx->ftm.targetNVTableSize == pHddCtx->ftm.processedNVTableSize) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Processing Done!! write encoded Buffer %d", + pHddCtx->ftm.targetNVTableSize); + + nvStatus = wlan_write_to_efs ((v_U8_t*)pHddCtx->ftm.tempNVTableBuffer, + (v_U16_t)pHddCtx->ftm.targetNVTableSize); + + if ((VOS_STATUS_SUCCESS != nvStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Fail to set NV Binary %d", nvStatus); + return -EIO; + } + + nvStatus = vos_nv_setNVEncodedBuffer( + (v_U8_t*)pHddCtx->ftm.tempNVTableBuffer, + (v_SIZE_t)pHddCtx->ftm.targetNVTableSize); + + if ((VOS_STATUS_SUCCESS != nvStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Fail to set NV Binary %d", nvStatus); + return -EIO; + } + + pHddCtx->ftm.processingNVTable = NV_MAX_TABLE; + pHddCtx->ftm.targetNVTableSize = 0; + pHddCtx->ftm.processedNVTableSize = 0; + vos_mem_zero(pHddCtx->ftm.tempNVTableBuffer, MAX_NV_TABLE_SIZE); + } + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_ftm_temp_get_rel_num() - + Get internal release number + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + -1, Process Host command fail, vail out + 0, Process Host command success + + --------------------------------------------------------------------------*/ +int wlan_hdd_ftm_temp_get_rel_num +( + tPttMsgbuffer *ftmCmd +) +{ + tMsgPttGetBuildReleaseNumber *relNum = (tMsgPttGetBuildReleaseNumber *)&ftmCmd->msgBody.GetBuildReleaseNumber; + + relNum->relParams.drvMjr = QWLAN_VERSION_MAJOR; + relNum->relParams.drvMnr = QWLAN_VERSION_MINOR; + relNum->relParams.drvPtch = QWLAN_VERSION_PATCH; + relNum->relParams.drvBld = QWLAN_VERSION_BUILD; + relNum->relParams.pttMax = 10; + relNum->relParams.pttMin = 1; + + return 1; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_process_ftm_host_cmd() - + process any command should be handled within host. + decide any command should be send to HAL or not + + \param - ftmCmd - Pointer FTM Commad Buffer + + \return - int + < 0, Process Host command fail, bail out + 0, Process Host command success, not need to send CMD to HAL + 1, Process Host command success, need to send CMD to HAL + + --------------------------------------------------------------------------*/ +int wlan_hdd_process_ftm_host_cmd +( + hdd_context_t *pHddCtx, + void *ftmCmd +) +{ + tPttMsgbuffer *pFTMCmd = (tPttMsgbuffer *)ftmCmd; + int needToRouteHal = 1; + int hostState = 1; + + switch(pFTMCmd->msgId) + { + case PTT_MSG_GET_NV_TABLE: + hostState = wlan_hdd_ftm_get_nv_table(pHddCtx, pFTMCmd); + needToRouteHal = 0; + break; + + case PTT_MSG_SET_NV_TABLE: + hostState = wlan_hdd_ftm_set_nv_table(pHddCtx, pFTMCmd); + /* Temp NV Operation will be isolated to host + needToRouteHal = 1; */ + needToRouteHal = 0; + break; + + case PTT_MSG_BLANK_NV: + hostState = wlan_hdd_ftm_blank_nv_table(pFTMCmd); + needToRouteHal = 1; + break; + + case PTT_MSG_DEL_NV_TABLE: + hostState = wlan_hdd_ftm_delete_nv_table(pFTMCmd); + needToRouteHal = 1; + break; + + case PTT_MSG_GET_NV_FIELD: + hostState = wlan_hdd_ftm_get_nv_field(pFTMCmd); + needToRouteHal = 0; + break; + + case PTT_MSG_SET_NV_FIELD: + hostState = wlan_hdd_ftm_set_nv_field(pFTMCmd); + needToRouteHal = 0; + break; + + case PTT_MSG_STORE_NV_TABLE: + hostState = wlan_hdd_ftm_store_nv_table(pFTMCmd); + needToRouteHal = 0; + break; + + case PTT_MSG_GET_NV_BIN: + case PTT_MSG_GET_DICTIONARY: + hostState = wlan_hdd_ftm_get_nv_bin(pFTMCmd->msgId, pHddCtx, pFTMCmd); + needToRouteHal = 0; + break; + + case PTT_MSG_SET_NV_BIN: + hostState = wlan_hdd_ftm_set_nv_bin(pHddCtx, pFTMCmd); + needToRouteHal = 0; + break; + + case PTT_MSG_DBG_READ_REGISTER: + wpalReadRegister(pFTMCmd->msgBody.DbgReadRegister.regAddr, + &pFTMCmd->msgBody.DbgReadRegister.regValue); + needToRouteHal = 0; + break; + + case PTT_MSG_DBG_WRITE_REGISTER: + wpalWriteRegister(pFTMCmd->msgBody.DbgWriteRegister.regAddr, + pFTMCmd->msgBody.DbgWriteRegister.regValue); + needToRouteHal = 0; + break; + + case PTT_MSG_DBG_READ_MEMORY: + wpalReadDeviceMemory(pFTMCmd->msgBody.DbgReadMemory.memAddr, + (unsigned char *)pFTMCmd->msgBody.DbgReadMemory.pMemBuf, + pFTMCmd->msgBody.DbgReadMemory.nBytes); + needToRouteHal = 0; + break; + + case PTT_MSG_DBG_WRITE_MEMORY: + wpalWriteDeviceMemory(pFTMCmd->msgBody.DbgWriteMemory.memAddr, + (unsigned char *)pFTMCmd->msgBody.DbgWriteMemory.pMemBuf, + pFTMCmd->msgBody.DbgWriteMemory.nBytes); + needToRouteHal = 0; + break; + + case PTT_MSG_GET_BUILD_RELEASE_NUMBER: + wlan_hdd_ftm_temp_get_rel_num(pFTMCmd); + needToRouteHal = 0; + break; + + default: + needToRouteHal = 1; + break; + } + + if( 0 > hostState) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Host Command Handle Fail, Bailout"); + return hostState; + } + + return needToRouteHal; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_process_ftm_cmd() - + + This function process the commands received from the ptt socket application. + + \param - pAdapter - Pointer HDD Context. + + \param - wnl - Pointer to the ANI netlink header. + + \return - none + + --------------------------------------------------------------------------*/ + +void wlan_hdd_process_ftm_cmd +( + hdd_context_t *pHddCtx, + tAniNlHdr *wnl +) +{ + wlan_hdd_ftm_request_t *pRequestBuf = (wlan_hdd_ftm_request_t*)(((v_U8_t*)(&wnl->wmsg))+sizeof(tAniHdr)) ; + v_U16_t cmd_len; + v_U8_t *pftm_data; + pVosContextType pVosContext = (pVosContextType)(pHddCtx->pvosContext); + int hostState; + tPttMsgbuffer *tempRspBuffer = NULL; + static int count; + + ENTER(); + + //Delay to fix NV write failure on JB + vos_busy_wait(10000); //10ms + + if (!pRequestBuf) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: request buffer is null",__func__); + return ; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: Load/Unload in Progress. Ignoring FTM Command %d" + , __func__, pRequestBuf->ftmpkt.ftm_cmd_type); + return ; + } + + /*Save the received request*/ + pHddCtx->ftm.pRequestBuf = pRequestBuf; + + pHddCtx->ftm.pResponseBuf = (wlan_hdd_ftm_response_t*)pRequestBuf; + /*Save the received request netlink header used for sending the response*/ + pHddCtx->ftm.wnl = wnl; + if (pRequestBuf->module_type != QUALCOMM_MODULE_TYPE) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid Module Type =%d",__func__,pRequestBuf->module_type); + + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + return ; + } + + if (VOS_FTM_MODE != hdd_get_conparam()) + { + count++; + if (count == 1 || !(count % 10)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Driver not loaded in FTM" + " mode, current mode: %d ",__func__, hdd_get_conparam()); + } + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + return ; + } + + switch (pRequestBuf->ftmpkt.ftm_cmd_type) + { + case WLAN_FTM_START: + if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTED) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: FTM has already started =%d",__func__,pRequestBuf->ftmpkt.ftm_cmd_type); + pHddCtx->ftm.pResponseBuf->ftm_hdr.data_len -= 1; + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_SUCCESS; + wlan_ftm_send_response(pHddCtx); + return; + } + + if (wlan_hdd_ftm_start(pVosContext->pHDDContext) != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: : Failed to start WLAN FTM" + ,__func__); + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + complete(&pHddCtx->ftm.startCmpVar); + return; + } + /* Ptt application running on the host PC expects the length to be one byte less that what we have received*/ + pHddCtx->ftm.pResponseBuf->ftm_hdr.data_len -= 1; + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_SUCCESS; + pHddCtx->ftm.pResponseBuf->ftmpkt.ftm_cmd_type = 0; + + wlan_ftm_send_response(pHddCtx); + complete(&pHddCtx->ftm.startCmpVar); + break; + + case WLAN_FTM_STOP: + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:: FTM has not started",__func__); + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_SUCCESS; + wlan_ftm_send_response(pHddCtx); + return; + } + + if (VOS_STATUS_SUCCESS != wlan_ftm_stop(pHddCtx)) { + + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + return; + } + + pHddCtx->ftm.ftm_state = WLAN_FTM_STOPPED; + /* This would send back the Command Success Status */ + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_SUCCESS; + + wlan_ftm_send_response(pHddCtx); + + break; + + case WLAN_FTM_CMD: + /* if it is regular FTM command, pass it to HAL PHY */ + if(pHddCtx->ftm.IsCmdPending == TRUE) { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:: FTM command pending for process",__func__); + return; + } + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:: FTM has not started",__func__); + + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + return; + + } + vos_event_reset(&pHddCtx->ftm.ftm_vos_event); + cmd_len = pRequestBuf->ftm_hdr.data_len; + cmd_len -= (sizeof(wlan_hdd_ftm_request_t)- sizeof(pRequestBuf->ftmpkt.ftm_cmd_type)); + pftm_data = pRequestBuf->ftmpkt.pFtmCmd; + + hostState = wlan_hdd_process_ftm_host_cmd(pHddCtx, pftm_data); + if (0 == hostState) + { + tempRspBuffer = (tPttMsgbuffer *)vos_mem_malloc(((tPttMsgbuffer *)pftm_data)->msgBodyLength); + if (NULL == tempRspBuffer) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s:: temp Mem Alloc Fail",__func__); + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + return; + } + memcpy(tempRspBuffer, pftm_data, ((tPttMsgbuffer *)pftm_data)->msgBodyLength); + tempRspBuffer->msgResponse = PTT_STATUS_SUCCESS; + memcpy((unsigned char *)&pHddCtx->ftm.pResponseBuf->ftmpkt, + (unsigned char *) tempRspBuffer, + tempRspBuffer->msgBodyLength); + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_SUCCESS; + wlan_ftm_send_response(pHddCtx); + vos_mem_free(tempRspBuffer); + return; + } + else if (0 > hostState) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "*** Host Command Handle Fail ***"); + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + return; + } + + //HEXDUMP("Request:",(char*)pftm_data,cmd_len); + + + /*Post the command to the HAL*/ + if (wlan_ftm_postmsg(pftm_data, cmd_len) != VOS_STATUS_SUCCESS) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:: FTM command failed",__func__); + return; + + } + /*After successful posting of message the command should be pending*/ + pHddCtx->ftm.IsCmdPending = TRUE; + + /*Wait here until you get the response from HAL*/ + if (vos_wait_single_event(&pHddCtx->ftm.ftm_vos_event, FTM_VOS_EVENT_WAIT_TIME)!= VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: vos_wait_single_event failed",__func__); + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + pHddCtx->ftm.IsCmdPending = FALSE; + return; + } + /*This check will handle the case where the completion is sent by + wlan_hdd_process_ftm_cmd() and not by the HAL*/ + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: Load/Unload in Progress. Ignoring FTM Command %d" + , __func__, pRequestBuf->ftmpkt.ftm_cmd_type); + + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_FAILURE; + wlan_ftm_send_response(pHddCtx); + pHddCtx->ftm.IsCmdPending = FALSE; + return ; + } + + cmd_len = be16_to_cpu(pHddCtx->ftm.wnl->wmsg.length); + + //HEXDUMP("Response to QXDM:", (char *)&pAdapter->ftm.wnl->wmsg, cmd_len); + + wlan_ftm_send_response(pHddCtx); + pHddCtx->ftm.IsCmdPending = FALSE; + break; + + default: + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:: Command not supported",__func__); + return; + } + + EXIT(); + return; +} /* wlan_adp_ftm_cmd() */ + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_start_stop_ftm() - + + This function is used for start/stop the ftm driver. + + \param - pAdapter - Pointer HDD Context. + - start - 1/0 to start/stop ftm driver. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_start_stop_ftm(hdd_adapter_t *pAdapter, + v_U16_t start) +{ + VOS_STATUS status; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (start) + { + pHddCtx->ftm.cmd_iwpriv = TRUE; + status = wlan_hdd_ftm_start(pHddCtx); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "FTM Start Failed"); + return VOS_STATUS_E_FAILURE; + } + if (NULL == pMsgBuf) + { + pMsgBuf = (tPttMsgbuffer *)vos_mem_malloc(sizeof(tPttMsgbuffer)); + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + } + } + else + { + status = wlan_ftm_stop(pHddCtx); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "FTM Stop Failed"); + return VOS_STATUS_E_FAILURE; + } + pHddCtx->ftm.ftm_state = WLAN_FTM_STOPPED; + if (pMsgBuf) + { + vos_mem_free((v_VOID_t * )pMsgBuf); + pMsgBuf = NULL; + } + } + return VOS_STATUS_SUCCESS; +} + + +static VOS_STATUS validate_channel(unsigned int channel,unsigned int cb) +{ + unsigned int *table = NULL; + int index = 0; + + if (PHY_SINGLE_CHANNEL_CENTERED == cb) + table = valid_channel; + else if (cb >= PHY_DOUBLE_CHANNEL_LOW_PRIMARY && + cb <= PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + table = valid_channel_cb40; + else if (cb >= PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED && + cb <= PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH) + table = valid_channel_cb80; + + if (NULL == table) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s failed to find channel table %d", + __func__, cb); + return VOS_STATUS_E_FAILURE; + } + + while (table[index] != 0) + { + if (table[index] == channel) + return VOS_STATUS_SUCCESS; + + index++; + } + + return VOS_STATUS_E_FAILURE; +} + + +static unsigned int get_primary_channel(unsigned int center_channel,unsigned int cb) +{ + unsigned int primary_channel = center_channel; + + switch (cb) + { + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + primary_channel -= 2; + break; + + + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + primary_channel += 2; + break; + + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + primary_channel -= 6; + break; + + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + primary_channel += 6; + break; + } + + return primary_channel; + +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_channel() - + + This function is used for setting the channel to the halphy ptt module. + + \param - pAdapter - Pointer HDD Context. + - channel - Channel Number 1-14. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_set_channel(hdd_adapter_t *pAdapter,v_U16_t channel) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + if (VOS_STATUS_SUCCESS != validate_channel(channel, ftm_status.cbmode)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Invalid Channel Number. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_set(pMsgBuf, sizeof(*pMsgBuf), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_SET_CHANNEL; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetChannel) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + pMsgBody->SetChannel.chId = get_primary_channel(channel, ftm_status.cbmode); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Channel =%d",pMsgBody->SetChannel.chId); + pMsgBody->SetChannel.cbState = ftm_status.cbmode ; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + + } +done: + + return status; +} + +static VOS_STATUS wlan_ftm_priv_set_dump(hdd_adapter_t *pAdapter, int *value) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_set(pMsgBuf, sizeof(*pMsgBuf), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_PRIMA_GENERIC_CMD; + pMsgBuf->msgBodyLength = sizeof(tMsgPttPrimaGenericCmd) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + pMsgBody->PrimaGenericCmd.cmdIdx = value[0]; + pMsgBody->PrimaGenericCmd.param1 = value[1]; + pMsgBody->PrimaGenericCmd.param2 = value[2]; + pMsgBody->PrimaGenericCmd.param3 = value[3]; + pMsgBody->PrimaGenericCmd.param4 = value[4]; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + +done: + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_pwr_cntl_mode() - + + This function is used for setting the power control mode for tx. + + \param - pAdapter - Pointer HDD Context. + - pwr_mode - power control mode 0-2. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_set_pwr_cntl_mode(hdd_adapter_t *pAdapter, + v_U16_t pwr_mode) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + if (pwr_mode > 2) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:invalid control mode.valid mode is 0 , 1, 2.", __func__); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBody = &pMsgBuf->msgBody; + pMsgBuf->msgId = PTT_MSG_CLOSE_TPC_LOOP_PRIMA_V1; + pMsgBuf->msgBodyLength = sizeof(tMsgPttCloseTpcLoop) + PTT_HEADER_LENGTH; + + pMsgBody->CloseTpcLoop.tpcClose = pwr_mode; + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf, pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ftm_status.powerCtlMode= pwr_mode; + + done: + return status; + +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_txpower() - + + This function is used for setting the txpower to the halphy ptt module. + + \param - pAdapter - Pointer HDD Context. + - txpower - txpower Number 1-18. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_set_txpower(hdd_adapter_t *pAdapter, + v_U16_t txpower) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + /* do not allow to change setting when tx pktgen is enabled, although halphy does allow changing tx power + * when tx pktgen is enabled + */ + if (ftm_status.frameGenEnabled) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:cannot set txpower when pktgen is enabled.", __func__); + return VOS_STATUS_E_FAILURE; + } + + if(!(txpower >= 9 && txpower <= 24)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Invalid tx power. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBody = &pMsgBuf->msgBody; + pMsgBuf->msgId = PTT_MSG_SET_TX_POWER; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetTxPower) + PTT_HEADER_LENGTH; + + pMsgBody->SetTxPower.dbmPwr = txpower*100; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + done: + + return status; + +} + + +static VOS_STATUS wlan_ftm_priv_enable_dpd(hdd_adapter_t *pAdapter, + v_U16_t enable) +{ + tANI_U32 value = 0; + tANI_U32 reg_addr; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + reg_addr = WCNSS_TXFIR_OFFSET; + + wpalReadRegister(reg_addr, &value); + if (enable) + { + value &= (~QWLAN_TXFIR_CFG_DPD_BYPASS_MASK); + } + else + { + value |= QWLAN_TXFIR_CFG_DPD_BYPASS_MASK; + } + + wpalWriteRegister(reg_addr, value); + + return VOS_STATUS_SUCCESS; +} + + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_txrate() - + + This function is used for setting the txrate to the halphy ptt module. + It converts the user input string for txrate to the tx rate index. + + \param - pAdapter - Pointer HDD Context. + - txrate - Pointer to the tx rate string. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_set_txrate(hdd_adapter_t *pAdapter,char *txrate) +{ + int ii; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm.",__func__); + return VOS_STATUS_E_FAILURE; + } + + /* do not allow to change setting when tx pktgen is enabled */ + if (ftm_status.frameGenEnabled) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:cannot set txrate when pktgen is enabled.",__func__); + return VOS_STATUS_E_FAILURE; + } + + for(ii = 0; ii < SIZE_OF_TABLE(rateName_rateIndex_tbl); ii++) + { + if(!strcmp(rateName_rateIndex_tbl[ii].rate_str,txrate)) + break; + } + if(ii >= SIZE_OF_TABLE(rateName_rateIndex_tbl)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Invalid Rate String",__func__); + return VOS_STATUS_E_FAILURE; + } + + ftm_status.frameParams.rate = rateName_rateIndex_tbl[ii].rate_index; + ftm_status.frameParams.preamble = rate_index_2_preamble_table[rateName_rateIndex_tbl[ii].rate_index].Preamble; + + return VOS_STATUS_SUCCESS; +} + + + +static VOS_STATUS wlan_ftm_priv_set_power_index(hdd_adapter_t *pAdapter, + ePowerTempIndexSource pwr_source) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (pwr_source > 3) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:invalid power index source. valid mode is 0, 1, 2, 3. ", + __func__); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBody = &pMsgBuf->msgBody; + pMsgBuf->msgId = PTT_MSG_SET_PWR_INDEX_SOURCE; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetPwrIndexSource) + PTT_HEADER_LENGTH; + + pMsgBody->SetPwrIndexSource.indexSource = pwr_source; + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ftm_status.powerIndex = pwr_source; +done: + + return status; +} + + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_start_stop_tx_pktgen() - + + This function is used for start/stop the tx packet generation. + + \param - pAdapter - Pointer HDD Context. + - startStop - Value( 1/0) start/stop the tx packet generation. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_start_stop_tx_pktgen(hdd_adapter_t *pAdapter,v_U16_t startStop) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + if (startStop != 1 && startStop != 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Tx value is invalid ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if ((ftm_status.frameGenEnabled && startStop == 1) || + (!ftm_status.frameGenEnabled && startStop == 0)) + { + return VOS_STATUS_SUCCESS ; + } + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + + if (startStop == 1) + { + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_CONFIG_TX_PACKET_GEN; + pMsgBuf->msgBodyLength = sizeof(tMsgPttConfigTxPacketGen) + PTT_HEADER_LENGTH; + pMsgBody = &pMsgBuf->msgBody; + pMsgBody->ConfigTxPacketGen.frameParams = ftm_status.frameParams ; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:posting PTT_MSG_CONFIG_TX_PACKET_GEN failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: PTT_MSG_CONFIG_TX_PACKET_GEN failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + if (ftm_status.powerCtlMode == 2) //only for CLPC mode + { + status = wlan_ftm_priv_set_power_index(pAdapter, + ftm_status.powerIndex); + if(status != VOS_STATUS_SUCCESS) + { + goto done; + } + } + } + + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_START_STOP_TX_PACKET_GEN; + pMsgBuf->msgBodyLength = sizeof(tMsgPttStartStopTxPacketGen) + PTT_HEADER_LENGTH; + pMsgBody = &pMsgBuf->msgBody; + pMsgBody->StartStopTxPacketGen.startStop = startStop; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + if(status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:wlan_ftm_postmsg failed",__func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ret = wait_for_completion_interruptible_timeout( + &pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + if(pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ptt response status failed",__func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + +done: + + if (status == VOS_STATUS_SUCCESS) + { + if (startStop == 1) + { + ftm_status.frameGenEnabled = eANI_BOOLEAN_TRUE; + } + else + { + ftm_status.frameGenEnabled = eANI_BOOLEAN_FALSE; + } + } + + return status; +} + + + +static VOS_STATUS wlan_ftm_priv_set_cb(hdd_adapter_t *pAdapter, v_U16_t cbmode) +{ + + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (cbmode > PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:cb mode value is invalid ", __func__); + return VOS_STATUS_E_FAILURE; + } + + ftm_status.cbmode = cbmode; + + return VOS_STATUS_SUCCESS; + +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_rx_mode() - + + This function is used for start/stop the rx packet generation. + + \param - pAdapter - Pointer HDD Context. + - rxmode - 0-disable RX. + - 1-rx ALL frames + - 2-rx 11 g/n frames + - 3-rx 11b frames + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_rx_mode(hdd_adapter_t *pAdapter,v_U16_t rxmode) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + if (rxmode > 3) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Rx mode value is invalid ", __func__); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + + pMsgBuf->msgId = PTT_MSG_SET_RX_DISABLE_MODE; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetRxDisableMode) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + switch(rxmode) + { + case RXMODE_DISABLE_ALL: + pMsgBody->SetRxDisableMode.disabled.agPktsDisabled = VOS_TRUE; + pMsgBody->SetRxDisableMode.disabled.bPktsDisabled = VOS_TRUE; + pMsgBody->SetRxDisableMode.disabled.slrPktsDisabled= VOS_TRUE; + break; + + case RXMODE_ENABLE_ALL: + pMsgBody->SetRxDisableMode.disabled.agPktsDisabled = VOS_FALSE; + pMsgBody->SetRxDisableMode.disabled.bPktsDisabled = VOS_FALSE; + pMsgBody->SetRxDisableMode.disabled.slrPktsDisabled= VOS_FALSE; + break; + + case RXMODE_ENABLE_11GN: + pMsgBody->SetRxDisableMode.disabled.agPktsDisabled = VOS_FALSE; + pMsgBody->SetRxDisableMode.disabled.bPktsDisabled = VOS_TRUE; + pMsgBody->SetRxDisableMode.disabled.slrPktsDisabled= VOS_TRUE; + break; + + case RXMODE_ENABLE_11B: + pMsgBody->SetRxDisableMode.disabled.agPktsDisabled = VOS_TRUE; + pMsgBody->SetRxDisableMode.disabled.bPktsDisabled = VOS_FALSE; + pMsgBody->SetRxDisableMode.disabled.slrPktsDisabled= VOS_TRUE; + break; + + } + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL(" wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ftm_status.rxmode = rxmode ; +done: + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_rx_pkt_clear() - + + This function sets the rx pkt count to zero. + + \param - pAdapter - Pointer HDD Context. + - rx_pkt_clear - rx_pkt_clear value. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_rx_pkt_clear(hdd_adapter_t *pAdapter,v_U16_t rx_pkt_clear) +{ + VOS_STATUS status; + long ret; + + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + if (rx_pkt_clear != 1) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Invalid rx_pkt_clear value ", __func__); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_RESET_RX_PACKET_STATISTICS; + pMsgBuf->msgBodyLength = /*sizeof(tMsgPttResetRxPacketStatistics) + */PTT_HEADER_LENGTH; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } +done: + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_get_channel() - + + This function gets the channel number from the halphy ptt module and + returns the channel number to the application. + + \param - pAdapter - Pointer HDD Context. + - pChannel - Poniter to get the Channel number. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_get_channel(hdd_adapter_t *pAdapter,v_U16_t *pChannel) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + v_U16_t freq; + long ret; + + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + v_PVOID_t devHandle = pHddCtx->parent_dev; + struct device *wcnss_device = (struct device *)devHandle; + struct resource *wcnss_memory; + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_DBG_READ_REGISTER; + pMsgBuf->msgBodyLength = sizeof(tMsgPttDbgReadRegister) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + wcnss_memory = wcnss_wlan_get_memory_map(wcnss_device); + if (NULL == wcnss_memory) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: wcnss_memory is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + else + { + pMsgBody->DbgReadRegister.regAddr = wcnss_memory->start + + QWLAN_AGC_CHANNEL_FREQ_REG_OFFSET; + } + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + freq = ((v_U16_t)pMsgBody->DbgReadRegister.regValue & QWLAN_AGC_CHANNEL_FREQ_FREQ_MASK); + + *pChannel = vos_freq_to_chan(freq); + (*pChannel) ? (status = VOS_STATUS_SUCCESS) : (status = VOS_STATUS_E_FAILURE); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Channel = %d freq = %d",*pChannel, freq); + done: + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_get_txpower() - + + This function gets the TX power from the halphy ptt module and + returns the TX power to the application. + + \param - pAdapter - Pointer HDD Context. + - pTxPwr - Poniter to get the Tx power. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_get_txpower(hdd_adapter_t *pAdapter,v_U16_t *pTxPwr) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_GET_TX_POWER_REPORT; + pMsgBuf->msgBodyLength = sizeof(tMsgPttGetTxPowerReport) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: PTT_MSG_GET_TX_POWER_REPORT failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + *pTxPwr = pMsgBody->GetTxPowerReport.pwrTemplateIndex; + + done: + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_get_txrate() - + + This function gets the TX rate from the halphy ptt module and + returns the TX rate to the application. + + \param - pAdapter - Pointer HDD Context. + - pTxRate - Poniter to get the Tx rate. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_get_txrate(hdd_adapter_t *pAdapter,char *pTxRate) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U16_t ii; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + for(ii = 0; ii < SIZE_OF_TABLE(rateName_rateIndex_tbl); ii++) { + if(rateName_rateIndex_tbl[ii].rate_index == ftm_status.frameParams.rate) + break; + } + if(ii >= SIZE_OF_TABLE(rateName_rateIndex_tbl)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Invalid Rate Index",__func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + strlcpy(pTxRate,rateName_rateIndex_tbl[ii].rate_str, WE_FTM_MAX_STR_LEN); + +done: + return status; + +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_get_rx_pkt_count() - + + This function gets the rx pkt count from the halphy ptt module and + returns the rx pkt count to the application. + + \param - pAdapter - Pointer HDD Context. + - pRxPktCnt - Poniter to get the rx pkt count. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_get_rx_pkt_count(hdd_adapter_t *pAdapter,v_U16_t *pRxPktCnt) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + long ret; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_GET_RX_PKT_COUNTS; + pMsgBuf->msgBodyLength = sizeof(tMsgPttGetRxPktCounts) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + *pRxPktCnt = pMsgBody->GetRxPktCounts.counters.totalRxPackets; +done: + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_get_rx_rssi() - + + This function gets the rx rssi from the halphy ptt module and + returns the rx rssi to the application. + + \param - pAdapter - Pointer HDD Context. + - buf - Poniter to get rssi of Rx chains + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_get_rx_rssi(hdd_adapter_t *pAdapter,char *buf) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + long ret; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (NULL == pMsgBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:pMsgBuf is NULL", __func__); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_GET_RX_RSSI; + pMsgBuf->msgBodyLength = sizeof(tMsgPttGetRxRssi) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ret = snprintf(buf, WE_FTM_MAX_STR_LEN, " R0:%d, R1:%d", + pMsgBody->GetRxRssi.rssi.rx[0], + pMsgBody->GetRxRssi.rssi.rx[1]); + + if( ret < 0 || ret >= WE_FTM_MAX_STR_LEN ) + { + status = VOS_STATUS_E_FAILURE; + } + +done: + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_get_mac_address() - + + This function gets the mac address from the halphy ptt module and + returns the mac address to the application. + + \param - pAdapter - Pointer HDD Context. + - buf - Poniter to get the mac address. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_get_mac_address(hdd_adapter_t *pAdapter,char *buf) +{ + v_BOOL_t itemIsValid = VOS_FALSE; + v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = {0, 0x0a, 0xf5, 4,5, 6}; + int ret; + + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + + if(pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:Ftm has not started. Please start the ftm. ",__func__); + return VOS_STATUS_E_FAILURE; + } + /*Check the NV FIELD is valid or not*/ + if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) == VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + vos_nv_readMacAddress(macAddr); + + ret = snprintf(buf, WE_FTM_MAX_STR_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x", + MAC_ADDR_ARRAY(macAddr)); + if( ret < 0 || ret >= WE_FTM_MAX_STR_LEN ) + { + return VOS_STATUS_E_FAILURE; + } + } + } + else + { + /*Return Hard coded mac address*/ + ret = snprintf(buf, WE_FTM_MAX_STR_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x", + MAC_ADDR_ARRAY(macAddr)); + + if( ret < 0 || ret >= WE_FTM_MAX_STR_LEN ) + { + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief wlan_ftm_priv_set_mac_address() - + + This function sets the mac address to the halphy ptt module and + sends the netlink message to the ptt socket application which writes + the macaddress to the qcom_wlan_nv.bin file + + \param - pAdapter - Pointer HDD Context. + - buf - Poniter to the macaddress. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_ftm_priv_set_mac_address(hdd_adapter_t *pAdapter,char *buf) +{ + uPttMsgs *pMsgBody; + VOS_STATUS status; + int macAddr[VOS_MAC_ADDRESS_LEN]; + v_U8_t *pMacAddress; + v_U8_t ii; + hdd_context_t *pHddCtx = (hdd_context_t *)pAdapter->pHddCtx; + long ret; + + if (pHddCtx->ftm.ftm_state != WLAN_FTM_STARTED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ftm has not started. Please start the ftm. ", __func__); + return VOS_STATUS_E_FAILURE; + } + vos_mem_set(pMsgBuf, sizeof(tPttMsgbuffer), 0); + init_completion(&pHddCtx->ftm.ftm_comp_var); + pMsgBuf->msgId = PTT_MSG_SET_NV_FIELD; + pMsgBuf->msgBodyLength = sizeof(tMsgPttSetNvField) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + pMsgBody->SetNvField.nvField = NV_COMMON_MAC_ADDR; + + /*We get the mac address in string format "XX:XX:XX:XX:XX:XX" convert to hex*/ + if (6 != sscanf(buf,"%02x:%02x:%02x:%02x:%02x:%02x",&macAddr[0],(int*)&macAddr[1],(int*)&macAddr[2],(int*)&macAddr[3],(int*)&macAddr[4],(int*)&macAddr[5])) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MacAddress Input %s", buf); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "MacAddress = " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr)); + + + pMacAddress = &pMsgBody->SetNvField.fieldData.macAddr.macAddr1[0]; + + for(ii = 0; ii < VOS_MAC_ADDRESS_LEN; ii++) + pMacAddress[ii] = (v_U8_t)macAddr[ii]; + + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "pMacAddress = " MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pMacAddress)); + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed!!", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } + + if (pMsgBuf->msgResponse != PTT_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:Ptt response status failed", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "NV_COMMON_MAC_ADDR Success!!!"); + + init_completion(&pHddCtx->ftm.ftm_comp_var); + memset( pMsgBuf,0,sizeof(tPttMsgbuffer)); + + pMsgBuf->msgId = PTT_MSG_STORE_NV_TABLE; + pMsgBuf->msgBodyLength = sizeof(tMsgPttStoreNvTable) + PTT_HEADER_LENGTH; + + pMsgBody = &pMsgBuf->msgBody; + + pMsgBody->StoreNvTable.nvTable = NV_FIELDS_IMAGE; + + status = wlan_ftm_postmsg((v_U8_t*)pMsgBuf,pMsgBuf->msgBodyLength); + + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:wlan_ftm_postmsg failed!!!!", __func__); + status = VOS_STATUS_E_FAILURE; + goto done; + } + + ret = wait_for_completion_interruptible_timeout(&pHddCtx->ftm.ftm_comp_var, + msecs_to_jiffies(WLAN_FTM_COMMAND_TIME_OUT)); + if (0 >= ret ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("wait on ftm_comp_var failed %ld"), ret); + } +done: + + return VOS_STATUS_SUCCESS; +} + +/* set param sub-ioctls */ +static int __iw_ftm_setchar_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret,sub_cmd; + unsigned int length; + char *param; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + struct iw_point s_priv_data; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + ret =0; + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) + { + return -EINVAL; + } + + /* make sure all params are correctly passed to function */ + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) + { + return -EINVAL; + } + + pAdapter = (hdd_adapter_t *)netdev_priv(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + sub_cmd = s_priv_data.flags; + length = s_priv_data.length; + + /* we cannot use iotctl_private_iw_point in kernel to allocate memory + * to store data from userspace as IW_SETCHAR_GETNONE is defined as + * odd number which assigns set_args to zero.we assisgn memory using + * kzalloc here to hold userspace data + */ + param = kzalloc(length + 1, GFP_KERNEL); + if (!param) + return -EINVAL; + + if (copy_from_user(param, s_priv_data.pointer, length)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:Failed to get user data %s", __func__, param); + + ret = -EINVAL; + goto OUT; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received length %d, parameters: %s", __func__, length, param); + + switch(sub_cmd) + { + case WE_SET_MAC_ADDRESS: + { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SET MAC ADDRESS"); + + status = wlan_ftm_priv_set_mac_address(pAdapter,param); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "wlan_ftm_priv_set_mac_address Failed =%d",status); + + ret = -EINVAL; + } + + break; + } + case WE_SET_TX_RATE: + { + status = wlan_ftm_priv_set_txrate(pAdapter,param); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "wlan_ftm_priv_set_txrate Failed =%d",status); + + ret = -EINVAL; + } + + break; + } + default: + { + hddLog(LOGE, "%s: Invalid sub command %d",__func__, sub_cmd); + ret = -EINVAL; + break; + } + } + +OUT: + kfree(param); + EXIT(); + return ret; +} + +static int iw_ftm_setchar_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_ftm_setchar_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_ftm_setint_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int sub_cmd = value[0]; + int set_value = value[1]; + int ret = 0; /* success */ + VOS_STATUS status; + + ENTER(); + + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + switch(sub_cmd) + { + case WE_FTM_ON_OFF: + { + status = wlan_ftm_priv_start_stop_ftm(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s Failed =%d",__func__, status); + ret = -EINVAL; + } + + break; + } + + case WE_TX_PKT_GEN: + status = wlan_ftm_priv_start_stop_tx_pktgen(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_start_stop_tx_pktgen Failed =%d",status); + ret = -EINVAL; + } + break; + + case WE_SET_TX_IFS: + status = wlan_ftm_priv_set_txifs(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_txifs Failed =%d",status); + ret = -EINVAL; + } + break; + + case WE_SET_TX_PKT_CNT: + status = wlan_ftm_priv_set_txpktcnt(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_txpktcnt Failed =%d",status); + ret = -EINVAL; + } + break; + + case WE_SET_TX_PKT_LEN: + status = wlan_ftm_priv_set_txpktlen(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_txpktlen Failed =%d",status); + ret = -EINVAL; + } + break; + + case WE_TX_CW_RF_GEN: + status = wlan_ftm_priv_cw_rf_gen(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_cw_gen Failed =%d\n",status); + ret = -EINVAL; + } + break; + + case WE_SET_CHANNEL: + { + status = wlan_ftm_priv_set_channel(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_channel Failed =%d",status); + ret = -EINVAL; + } + break; + } + case WE_SET_TX_POWER: + { + status = wlan_ftm_priv_set_txpower(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_set_txpower Failed =%d",status); + ret = -EINVAL; + } + break; + } + case WE_CLEAR_RX_PKT_CNT: + { + status = wlan_ftm_priv_rx_pkt_clear(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_rx_pkt_clear Failed =%d",status); + ret = -EINVAL; + } + break; + } + case WE_RX: + { + status = wlan_ftm_priv_rx_mode(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_rx_mode Failed =%d",status); + ret = -EINVAL; + } + break; + } + case WE_ENABLE_CHAIN: + { + status = wlan_ftm_priv_enable_chain(pAdapter,set_value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_enable_chain Failed =%d",status); + ret = -EINVAL; + } + break; + } + + case WE_SET_PWR_CNTL_MODE: + { + status = wlan_ftm_priv_set_pwr_cntl_mode(pAdapter, set_value); + if (status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "set_pwr_cntl_mode failed = %d", + status); + ret = -EINVAL; + } + break; + } + + case WE_ENABLE_DPD: + { + status = wlan_ftm_priv_enable_dpd(pAdapter, set_value); + if (status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "enable_dpd failed = %d", status); + ret = -EINVAL; + } + break; + } + + case WE_SET_CB: + { + status = wlan_ftm_priv_set_cb(pAdapter, set_value); + if (status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "set_cb failed = %d", status); + ret = -EINVAL; + } + break; + } + + case WE_SET_POWER_INDEX: + { + status = wlan_ftm_priv_set_power_index(pAdapter, set_value); + if (status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "set power index failed = %d", + status); + ret = -EINVAL; + } + break; + } + + default: + { + hddLog(LOGE, "Invalid IOCTL setvalue command %d value %d", + sub_cmd, set_value); + break; + } + } + + EXIT(); + return ret; +} + +static int iw_ftm_setint_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_ftm_setint_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +/* get param sub-ioctls */ +static int __iw_ftm_setnone_getint(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int ret = 0; /* success */ + VOS_STATUS status; + + ENTER(); + + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + switch (value[0]) + { + case WE_GET_CHANNEL: + { + status = wlan_ftm_priv_get_channel(pAdapter,(v_U16_t*)value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_get_channel Failed =%d",status); + ret = -EINVAL; + } + break; + } + case WE_GET_TX_POWER: + { + status = wlan_ftm_priv_get_txpower(pAdapter,(v_U16_t*)value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_get_txpower Failed =%d",status); + ret = -EINVAL; + } + break; + } + case WE_GET_RX_PKT_CNT: + { + status = wlan_ftm_priv_get_rx_pkt_count(pAdapter,(v_U16_t*)value); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"wlan_ftm_priv_get_rx_pkt_count Failed =%d",status); + ret = -EINVAL; + } + break; + } + default: + { + hddLog(LOGE, "Invalid IOCTL get_value command %d ",value[0]); + break; + } + } + + EXIT(); + return ret; +} + +static int iw_ftm_setnone_getint(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_ftm_setnone_getint(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_ftm_get_char_setnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int sub_cmd = wrqu->data.flags; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + switch(sub_cmd) + { + case WE_GET_MAC_ADDRESS: + { + status = wlan_ftm_priv_get_mac_address(pAdapter, extra); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "wlan_ftm_priv_get_mac_address failed =%d",status); + return -EINVAL; + } + wrqu->data.length = strlen(extra)+1; + break; + } + case WE_GET_TX_RATE: + { + status = wlan_ftm_priv_get_txrate(pAdapter, extra); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "wlan_ftm_priv_get_txrate failed =%d",status); + return -EINVAL; + } + + wrqu->data.length = strlen(extra)+1; + break; + } + case WE_GET_FTM_STATUS: + { + status = wlan_ftm_priv_get_status(pAdapter, extra); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "wlan_ftm_priv_get_status failed =%d",status); + return -EINVAL; + } + + wrqu->data.length = strlen(extra)+1; + break; + } + case WE_GET_RX_RSSI: + { + status = wlan_ftm_priv_get_rx_rssi(pAdapter, extra); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "wlan_ftm_priv_get_rx_rssi failed =%d",status); + return -EINVAL; + } + + wrqu->data.length = strlen(extra)+1; + break; + } + default: + { + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd ); + break; + } + } + + EXIT(); + return 0; +} + +static int iw_ftm_get_char_setnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_ftm_get_char_setnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + + return ret; +} + +VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len) +{ +#if defined(MSM_PLATFORM) + tAniHdr *wmsg = NULL; + v_U8_t *pBuf; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext= NULL; + + pBuf = (v_U8_t*)vos_mem_malloc(sizeof(tAniHdr) + sizeof(v_U32_t)+ data_len); + if(pBuf == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pBuf is NULL",__func__); + return VOS_STATUS_E_NOMEM; + } + wmsg = (tAniHdr*)pBuf; + wmsg->type = PTT_MSG_FTM_CMDS_TYPE; + wmsg->length = data_len + sizeof(tAniHdr)+ sizeof(v_U32_t); + wmsg->length = FTM_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + /*Get the Hdd Context */ + //pAdapter = ((VosContextType*)(pVosContext))->pHDDContext; + pHddCtx = (hdd_context_t *)(((VosContextType*)(pVosContext))->pHDDContext); + + /* EfS command Code */ + *(v_U32_t*)pBuf = 0x000000EF; + + pBuf += sizeof(v_U32_t); + + memcpy(pBuf, pData,data_len); + + if(pHddCtx->ftm.cmd_iwpriv == TRUE) { + if( ptt_sock_send_msg_to_app(wmsg, 0, + ANI_NL_MSG_PUMAC, pHddCtx->ptt_pid, 0) < 0) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Ptt Socket error sending message to the app!!")); + vos_mem_free((v_VOID_t*)wmsg); + return VOS_STATUS_E_FAILURE; + } + } + else { + if( ptt_sock_send_msg_to_app(wmsg, 0, + ANI_NL_MSG_PUMAC, pHddCtx->ftm.wnl->nlh.nlmsg_pid, 0) < 0) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Ptt Socket error sending message to the app!!")); + vos_mem_free((v_VOID_t*)wmsg); + return VOS_STATUS_E_FAILURE; + } + } + + vos_mem_free((v_VOID_t*)wmsg); +#endif //FTM and ANDROID + + return VOS_STATUS_SUCCESS; +} + +/* action sub-ioctls */ +static int __iw_ftm_setnone_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int sub_cmd = wrqu->data.flags; + int ret = 0; /* success */ + + switch (sub_cmd) + { + case WE_SET_NV_DEFAULTS: + { + v_U8_t *pu8buf,*pTempBuf; + v_U16_t size; + size = sizeof(v_U32_t) + sizeof(sHalNv); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HAL NV Size =%d",size); + pu8buf = vos_mem_malloc(size); + if(pu8buf == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pu8buf is NULL",__func__); + return VOS_STATUS_E_NOMEM; + } + memset(pu8buf,0,size); + pTempBuf = pu8buf; + pTempBuf += sizeof(v_U32_t); + memcpy(pTempBuf,&nvDefaults,sizeof(sHalNv)); + + wlan_write_to_efs(pu8buf,size); + vos_mem_free(pu8buf); + } + + default: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: unknown ioctl %d", __func__, sub_cmd); + hddLog(LOGE, "Invalid IOCTL action command %d ", sub_cmd); + break; + } + } + + return ret; +} + +static int iw_ftm_setnone_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_ftm_setnone_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_ftm_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int sub_cmd = wrqu->data.flags; + int *value = (int*)wrqu->data.pointer; + int ret = 0; + VOS_STATUS status; + + ENTER(); + + if(wrqu->data.length < 2) + { + hddLog(LOGE, "Invalid number of Arguments %d ", wrqu->data.length); + return -EINVAL; + } + + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + switch (sub_cmd) + { + case WE_SET_TX_WF_GAIN: + { + v_S15_t dGain = 0; + v_U16_t rfGain = 0; + + dGain = *(v_S15_t*) value++; + rfGain = *(v_U16_t*) value; + status = wlan_ftm_priv_set_wfgain(pAdapter,dGain,rfGain); + + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "wlan_ftm_priv_set_wfgain Failed =%d\n", status); + return -EINVAL; + } + } + break; + + case WE_SET_DUMP: + if (*value == 1) + { + status = wlan_ftm_priv_set_dump(pAdapter, value); + if(status != VOS_STATUS_SUCCESS) + { + hddLog(LOGE, "wlan_ftm_priv_set_dump Failed =%d\n", + status); + ret = -EINVAL; + } + }else + { + hddLog(LOGE, "%s arg[0]: %d expecting arg[0]: 1\n", + __func__, *value); + } + break; + + default: + { + hddLog(LOGE, "Invalid IOCTL command %d ", sub_cmd ); + break; + } + } + + EXIT(); + return 0; +} + + +static int iw_ftm_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + union iwreq_data u_priv_wrqu; + int apps_args[MAX_VAR_ARGS] = {0}; + int num_args; + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu)) + { + return -EINVAL; + } + + if (NULL == u_priv_wrqu.data.pointer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NULL data pointer", __func__); + return -EINVAL; + } + + num_args = u_priv_wrqu.data.length; + if (num_args > MAX_VAR_ARGS) + { + num_args = MAX_VAR_ARGS; + } + + if (copy_from_user(apps_args, u_priv_wrqu.data.pointer, + (sizeof(int)) * num_args)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data from user buffer", __func__); + return -EFAULT; + } + + vos_ssr_protect(__func__); + ret = __iw_ftm_set_var_ints_getnone(dev, info, &u_priv_wrqu, + (char *)&apps_args); + vos_ssr_unprotect(__func__); + + return ret; +} + +static const iw_handler we_ftm_private[] = { + + [WLAN_FTM_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_ftm_setint_getnone, //set priv ioctl + [WLAN_FTM_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_ftm_setnone_getint, //get priv ioctl + [WLAN_FTM_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_ftm_setchar_getnone, //get priv ioctl + [WLAN_FTM_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_ftm_get_char_setnone, + [WLAN_FTM_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_ftm_setnone_getnone, //action priv ioctl + [WLAN_FTM_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_ftm_set_var_ints_getnone, +}; + +/*Maximum command length can be only 15 */ +static const struct iw_priv_args we_ftm_private_args[] = { + + /* handlers for main ioctl */ + { WLAN_FTM_PRIV_SET_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "" }, + + { WE_FTM_ON_OFF, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ftm" }, + + { WE_TX_PKT_GEN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tx" }, + + { WE_SET_TX_IFS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txifs" }, + + { WE_SET_TX_PKT_CNT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txpktcnt" }, + + { WE_SET_TX_PKT_LEN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txpktlen" }, + + { WE_SET_TX_WF_GAIN, + IW_PRIV_TYPE_INT | MAX_FTM_VAR_ARGS, + 0, + "set_tx_wf_gain" }, + + { WE_TX_CW_RF_GEN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tx_cw_rf_gen" }, + { WE_SET_CHANNEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_channel" }, + + { WE_SET_TX_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_txpower" }, + + { WE_CLEAR_RX_PKT_CNT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "clr_rxpktcnt" }, + + { WE_RX, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "rx" }, + + { WE_ENABLE_CHAIN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ena_chain" }, + + { WE_SET_PWR_CNTL_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "pwr_cntl_mode" }, + + { WE_ENABLE_DPD, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "ena_dpd" }, + + { WE_SET_CB, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_cb" }, + + { WE_SET_POWER_INDEX, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set_power_index" }, + + /* handlers for main ioctl */ + { WLAN_FTM_PRIV_SET_NONE_GET_INT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "" }, + + { WE_GET_CHANNEL, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_channel" }, + + { WE_GET_TX_POWER, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_txpower" }, + + { WE_GET_RX_PKT_CNT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_rxpktcnt" }, + + /* handlers for main ioctl */ + { WLAN_FTM_PRIV_SET_CHAR_GET_NONE, + IW_PRIV_TYPE_CHAR| 512, + 0, + "" }, + + { WE_SET_MAC_ADDRESS, + IW_PRIV_TYPE_CHAR| 512, + 0, + "set_mac_address" }, + + { WE_SET_TX_RATE, + IW_PRIV_TYPE_CHAR | 512, + 0, + "set_txrate" }, + + /* handlers for main ioctl */ + { WLAN_FTM_PRIV_GET_CHAR_SET_NONE, + 0, + IW_PRIV_TYPE_CHAR| WE_FTM_MAX_STR_LEN, + "" }, + + { WE_GET_MAC_ADDRESS, + 0, + IW_PRIV_TYPE_CHAR| WE_FTM_MAX_STR_LEN, + "get_mac_address" }, + + { WE_GET_TX_RATE, + 0, + IW_PRIV_TYPE_CHAR| WE_FTM_MAX_STR_LEN, + "get_txrate" }, + + { WE_GET_FTM_STATUS, + 0, + IW_PRIV_TYPE_CHAR| WE_FTM_MAX_STR_LEN, + "get_status" }, + + { WE_GET_RX_RSSI, + 0, + IW_PRIV_TYPE_CHAR| WE_FTM_MAX_STR_LEN, + "get_rx_rssi" }, + + { WLAN_FTM_PRIV_SET_VAR_INT_GET_NONE, + IW_PRIV_TYPE_INT | MAX_FTM_VAR_ARGS, + 0, + "" }, + /* handlers for main ioctl */ + { WLAN_FTM_PRIV_SET_NONE_GET_NONE, + 0, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_SET_NV_DEFAULTS, + 0, + 0, + "set_nv_defaults" }, + + { WE_SET_DUMP, + IW_PRIV_TYPE_INT | MAX_FTM_VAR_ARGS, + 0, + "dump" }, + +}; + +const struct iw_handler_def we_ftm_handler_def = { + .num_standard = 0, + .num_private = sizeof(we_ftm_private) / sizeof(we_ftm_private[0]), + .num_private_args = sizeof(we_ftm_private_args) / sizeof(we_ftm_private_args[0]), + + .standard = (iw_handler *)NULL, + .private = (iw_handler *)we_ftm_private, + .private_args = we_ftm_private_args, + .get_wireless_stats = NULL, +}; + +static int wlan_ftm_register_wext(hdd_adapter_t *pAdapter) +{ + + //hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + // Zero the memory. This zeros the profile structure. + //memset(pwextBuf, 0,sizeof(hdd_wext_state_t)); + + pAdapter->dev->wireless_handlers = (struct iw_handler_def *)&we_ftm_handler_def; + + return 0; +} + + +VOS_STATUS WLANFTM_McProcessMsg (v_VOID_t *message) +{ + ftm_rsp_msg_t *pFtmMsgRsp; + + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext= NULL; + + ENTER(); + + pFtmMsgRsp = (ftm_rsp_msg_t *)message; + + if (!message ) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "WLAN FTM:Invalid parameter sent on WLANFTM_ProcessMainMessage"); + return VOS_STATUS_E_INVAL; + } + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + /*Get the Hdd Context */ + pHddCtx = ((VosContextType*)(pVosContext))->pHDDContext; + + if (pHddCtx->ftm.cmd_iwpriv == TRUE) { + + memcpy((char*)pMsgBuf, (char*)message, pFtmMsgRsp->msgBodyLength); + complete(&pHddCtx->ftm.ftm_comp_var); + } + else { + /*Response length to Ptt App*/ + pHddCtx->ftm.wnl->wmsg.length = sizeof(tAniHdr)+ SIZE_OF_FTM_DIAG_HEADER_LEN + pFtmMsgRsp->msgBodyLength; + + /*Ptt App expects the response length in LE */ + pHddCtx->ftm.wnl->wmsg.length = FTM_SWAP16(pHddCtx->ftm.wnl->wmsg.length); + + /*Response expects the length to be in */ + pHddCtx->ftm.pResponseBuf->ftm_hdr.data_len = pHddCtx->ftm.pRequestBuf->ftm_hdr.data_len - + sizeof(pHddCtx->ftm.pRequestBuf->ftm_hdr.data_len); + + /*Copy the message*/ + memcpy((char*)&pHddCtx->ftm.pResponseBuf->ftmpkt,(char*)message,pFtmMsgRsp->msgBodyLength); + + /*Update the error code*/ + pHddCtx->ftm.pResponseBuf->ftm_err_code = WLAN_FTM_SUCCESS; + + vos_status = vos_event_set(&pHddCtx->ftm.ftm_vos_event); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!")); + return VOS_STATUS_E_FAILURE; + } + } + EXIT(); + return VOS_STATUS_SUCCESS; + +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c new file mode 100644 index 000000000000..f318f1fadd9d --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c @@ -0,0 +1,5404 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_hostapd.c + \brief WLAN Host Device Driver implementation + + + ========================================================================*/ +/**========================================================================= + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/5/09 Shailender Created module. + 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure + ==========================================================================*/ +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_nlink_common.h" +#include "wlan_btc_svc.h" +#include +#include "wlan_hdd_tdls.h" +#include "wlan_hdd_p2p.h" +#include "cfgApi.h" +#include "wniCfg.h" +#include +#include "wlan_hdd_hostapd.h" + +#ifdef FEATURE_WLAN_CH_AVOID +#include "wcnss_wlan.h" +#endif /* FEATURE_WLAN_CH_AVOID */ +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" + +#define IS_UP(_dev) \ + (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) +#define IS_UP_AUTO(_ic) \ + (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO) +#define WE_WLAN_VERSION 1 +#define WE_GET_STA_INFO_SIZE 30 +/* WEXT limition: MAX allowed buf len for any * + * IW_PRIV_TYPE_CHAR is 2Kbytes * + */ +#define WE_SAP_MAX_STA_INFO 0x7FF + +#define SAP_24GHZ_CH_COUNT (14) + +#ifdef FEATURE_WLAN_CH_AVOID +/* Channle/Freqency table */ +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; +safeChannelType safeChannels[NUM_20MHZ_RF_CHANNELS] = +{ + /*CH , SAFE, default safe */ + {1 , VOS_TRUE}, //RF_CHAN_1, + {2 , VOS_TRUE}, //RF_CHAN_2, + {3 , VOS_TRUE}, //RF_CHAN_3, + {4 , VOS_TRUE}, //RF_CHAN_4, + {5 , VOS_TRUE}, //RF_CHAN_5, + {6 , VOS_TRUE}, //RF_CHAN_6, + {7 , VOS_TRUE}, //RF_CHAN_7, + {8 , VOS_TRUE}, //RF_CHAN_8, + {9 , VOS_TRUE}, //RF_CHAN_9, + {10 , VOS_TRUE}, //RF_CHAN_10, + {11 , VOS_TRUE}, //RF_CHAN_11, + {12 , VOS_TRUE}, //RF_CHAN_12, + {13 , VOS_TRUE}, //RF_CHAN_13, + {14 , VOS_TRUE}, //RF_CHAN_14, + {240, VOS_TRUE}, //RF_CHAN_240, + {244, VOS_TRUE}, //RF_CHAN_244, + {248, VOS_TRUE}, //RF_CHAN_248, + {252, VOS_TRUE}, //RF_CHAN_252, + {208, VOS_TRUE}, //RF_CHAN_208, + {212, VOS_TRUE}, //RF_CHAN_212, + {216, VOS_TRUE}, //RF_CHAN_216, + {36 , VOS_TRUE}, //RF_CHAN_36, + {40 , VOS_TRUE}, //RF_CHAN_40, + {44 , VOS_TRUE}, //RF_CHAN_44, + {48 , VOS_TRUE}, //RF_CHAN_48, + {52 , VOS_TRUE}, //RF_CHAN_52, + {56 , VOS_TRUE}, //RF_CHAN_56, + {60 , VOS_TRUE}, //RF_CHAN_60, + {64 , VOS_TRUE}, //RF_CHAN_64, + {100, VOS_TRUE}, //RF_CHAN_100, + {104, VOS_TRUE}, //RF_CHAN_104, + {108, VOS_TRUE}, //RF_CHAN_108, + {112, VOS_TRUE}, //RF_CHAN_112, + {116, VOS_TRUE}, //RF_CHAN_116, + {120, VOS_TRUE}, //RF_CHAN_120, + {124, VOS_TRUE}, //RF_CHAN_124, + {128, VOS_TRUE}, //RF_CHAN_128, + {132, VOS_TRUE}, //RF_CHAN_132, + {136, VOS_TRUE}, //RF_CHAN_136, + {140, VOS_TRUE}, //RF_CHAN_140, + {149, VOS_TRUE}, //RF_CHAN_149, + {153, VOS_TRUE}, //RF_CHAN_153, + {157, VOS_TRUE}, //RF_CHAN_157, + {161, VOS_TRUE}, //RF_CHAN_161, + {165, VOS_TRUE}, //RF_CHAN_165, +}; +#endif /* FEATURE_WLAN_CH_AVOID */ + +/*--------------------------------------------------------------------------- + * Function definitions + *-------------------------------------------------------------------------*/ +/**--------------------------------------------------------------------------- + + \brief __hdd_hostapd_open() - HDD Open function for hostapd interface + + This is called in response to ifconfig up + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int __hdd_hostapd_open (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + ENTER(); + + if(!test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + { + //WMM_INIT OR BSS_START not completed + hddLog( LOGW, "Ignore hostadp open request"); + EXIT(); + return 0; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0)); + //Turn ON carrier state + netif_carrier_on(dev); + //Enable all Tx queues + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues(dev); + + EXIT(); + return 0; +} + +int hdd_hostapd_open (struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_hostapd_open(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_hostapd_stop() - HDD stop function for hostapd interface + + This is called in response to ifconfig down + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int __hdd_hostapd_stop (struct net_device *dev) +{ + ENTER(); + + if(NULL != dev) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + //Stop all tx queues + netif_tx_disable(dev); + + //Turn OFF carrier state + netif_carrier_off(dev); + } + + EXIT(); + return 0; +} + +int hdd_hostapd_stop (struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_hostapd_stop(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_hostapd_uninit() - HDD uninit function + + This is called during the netdev unregister to uninitialize all data +associated with the device + + \param - dev Pointer to net_device structure + + \return - void + + --------------------------------------------------------------------------*/ +static void __hdd_hostapd_uninit (struct net_device *dev) +{ + hdd_adapter_t *pHostapdAdapter = netdev_priv(dev); + hdd_context_t *pHddCtx; + + ENTER(); + + if (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Invalid magic")); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("NULL pHddCtx")); + return; + } + + hdd_deinit_adapter(pHostapdAdapter->pHddCtx, pHostapdAdapter, TRUE); + + /* after uninit our adapter structure will no longer be valid */ + pHostapdAdapter->dev = NULL; + pHostapdAdapter->magic = 0; + + EXIT(); +} + +static void hdd_hostapd_uninit (struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_hostapd_uninit(dev); + vos_ssr_unprotect(__func__); + + return; +} +/**============================================================================ + @brief hdd_hostapd_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets. There are 2 versions of this function. One that uses + locked queue and other that uses lockless queues. Both have been retained to + do some performance testing + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +int hdd_hostapd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + return 0; +} + +int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu) +{ + return 0; +} + +int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu) +{ + int ret; + vos_ssr_protect(__func__); + ret = __hdd_hostapd_change_mtu(dev, new_mtu); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int hdd_hostapd_driver_command(hdd_adapter_t *pAdapter, + hdd_priv_data_t *priv_data) +{ + tANI_U8 *command = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_scaninfo_t *pScanInfo = NULL; + int ret = 0; + int status; + /* + * Note that valid pointers are provided by caller + */ + + ENTER(); + + if (priv_data->total_len <= 0 || + priv_data->total_len > HOSTAPD_IOCTL_COMMAND_STRLEN_MAX) + { + /* below we allocate one more byte for command buffer. + * To avoid addition overflow total_len should be + * smaller than INT_MAX. */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: integer out of range len %d", + __func__, priv_data->total_len); + ret = -EFAULT; + goto exit; + } + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + /* Allocate +1 for '\0' */ + command = kmalloc((priv_data->total_len + 1), GFP_KERNEL); + if (!command) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to allocate memory", __func__); + ret = -ENOMEM; + goto exit; + } + + if (copy_from_user(command, priv_data->buf, priv_data->total_len)) + { + ret = -EFAULT; + goto exit; + } + + /* Make sure the command is NUL-terminated */ + command[priv_data->total_len] = '\0'; + + hddLog(VOS_TRACE_LEVEL_INFO, + "***HOSTAPD*** : Received %s cmd from Wi-Fi GUI***", command); + + if (strncmp(command, "P2P_SET_NOA", 11) == 0) + { + hdd_setP2pNoa(pAdapter->dev, command); + } + else if (strncmp(command, "P2P_SET_PS", 10) == 0) + { + hdd_setP2pOpps(pAdapter->dev, command); + } +#ifdef FEATURE_WLAN_BATCH_SCAN + else if (strncmp(command, "WLS_BATCHING", 12) == 0) + { + ret = hdd_handle_batch_scan_ioctl(pAdapter, priv_data, command); + } +#endif + else if (strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0) + { + /* + * command should be a string having format + * SET_SAP_CHANNEL_LIST + */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Preferred Channels for SAP", + __func__); + + ret = sapSetPreferredChannel(command); + } + else if ( strncasecmp(command, "MIRACAST", 8) == 0 ) + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tANI_U8 filterType = 0; + tANI_U8 *value; + + ret = hdd_drv_cmd_validate(command, 8); + if (ret) + goto exit; + + value = command + 9; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &filterType); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, + * then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range ", __func__); + ret = -EINVAL; + goto exit; + } + if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) || + (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source," + " 2-Sink ", __func__); + ret = -EINVAL; + goto exit; + } + //Filtertype value should be either 0-Disabled, 1-Source, 2-sink + pHddCtx->drvr_miracast = filterType; + pScanInfo = &pHddCtx->scan_info; + if (filterType && pScanInfo != NULL && + pHddCtx->scan_info.mScanPending) + { + /*Miracast Session started. Abort Scan */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s, Aborting Scan For Miracast",__func__); + hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx); + sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast); + } + else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0) + { + ret = hdd_drv_cmd_validate(command, 16); + if (ret) + goto exit; + + ret = hdd_enable_disable_ca_event(pHddCtx, command, 16); + } + +exit: + if (command) + { + kfree(command); + } + EXIT(); + return ret; +} + +#ifdef CONFIG_COMPAT +static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter, + struct ifreq *ifr) +{ + struct { + compat_uptr_t buf; + int used_len; + int total_len; + } compat_priv_data; + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&compat_priv_data, ifr->ifr_data, + sizeof(compat_priv_data))) { + ret = -EFAULT; + goto exit; + } + priv_data.buf = compat_ptr(compat_priv_data.buf); + priv_data.used_len = compat_priv_data.used_len; + priv_data.total_len = compat_priv_data.total_len; + ret = hdd_hostapd_driver_command(pAdapter, &priv_data); + exit: + return ret; +} +#else /* CONFIG_COMPAT */ +static int hdd_hostapd_driver_compat_ioctl(hdd_adapter_t *pAdapter, + struct ifreq *ifr) +{ + /* will never be invoked */ + return 0; +} +#endif /* CONFIG_COMPAT */ + +static int hdd_hostapd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) { + ret = -EFAULT; + } else { + ret = hdd_hostapd_driver_command(pAdapter, &priv_data); + } + return ret; +} + +static int __hdd_hostapd_ioctl(struct net_device *dev, + struct ifreq *ifr, int cmd) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + ret = -ENODEV; + goto exit; + } + if (dev != pAdapter->dev) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter/dev inconsistency", __func__); + ret = -ENODEV; + goto exit; + } + + if ((!ifr) || (!ifr->ifr_data)) { + ret = -EINVAL; + goto exit; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) { + ret = -EBUSY; + goto exit; + } + + switch (cmd) { + case (SIOCDEVPRIVATE + 1): + if (is_compat_task()) + ret = hdd_hostapd_driver_compat_ioctl(pAdapter, ifr); + else + ret = hdd_hostapd_driver_ioctl(pAdapter, ifr); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d", + __func__, cmd); + ret = -EINVAL; + break; + } + exit: + EXIT(); + return ret; +} + +static int hdd_hostapd_ioctl(struct net_device *dev, + struct ifreq *ifr, int cmd) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_hostapd_ioctl(dev, ifr, cmd); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_hostapd_set_mac_address() - + This function sets the user specified mac address using + the command ifconfig wlanX hw ether . + + \param - dev - Pointer to the net device. + - addr - Pointer to the sockaddr. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *psta_mac_addr = addr; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); + EXIT(); + return 0; +} + +static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_hostapd_set_mac_address(dev, addr); + vos_ssr_unprotect(__func__); + + return ret; +} + +void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback) +{ + struct net_device *dev = (struct net_device *)usrDataForCallback; + v_BYTE_t we_custom_event[64]; + union iwreq_data wrqu; + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; +#ifdef DISABLE_CONCURRENCY_AUTOSAVE + VOS_STATUS vos_status; + hdd_ap_ctx_t *pHddApCtx; +#endif /*DISABLE_CONCURRENCY_AUTOSAVE */ + + /* event_name space-delimiter driver_module_name */ + /* Format of the event is "AUTO-SHUT.indication" " " "module_name" */ + char * autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME; + int event_len = strlen(autoShutEvent) + 1; /* For the NULL at the end */ + + ENTER(); + + pHostapdAdapter = netdev_priv(dev); + if ((NULL == pHostapdAdapter) || + (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) + { + hddLog(LOGE, FL("invalid adapter: %p"), pHostapdAdapter); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } +#ifdef DISABLE_CONCURRENCY_AUTOSAVE + if (vos_concurrent_open_sessions_running()) + { + /* + This timer routine is going to be called only when AP + persona is up. + If there are concurrent sessions running we do not want + to shut down the Bss.Instead we run the timer again so + that if Autosave is enabled next time and other session + was down only then we bring down AP + */ + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + vos_status = vos_timer_start( + &pHddApCtx->hdd_ap_inactivity_timer, + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff + * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + } + EXIT(); + return; + } +#endif /*DISABLE_CONCURRENCY_AUTOSAVE */ + memset(&we_custom_event, '\0', sizeof(we_custom_event)); + memcpy(&we_custom_event, autoShutEvent, event_len); + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = event_len; + + hddLog(LOG1, FL("Shutting down AP interface due to inactivity")); + wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event); + + EXIT(); +} + +VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter) +{ + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: UPDATE Beacon Params", __func__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + halStatus = sme_ChangeMCCBeaconInterval(hHal, pSapCtx->sessionId); + if(halStatus == eHAL_STATUS_FAILURE ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update Beacon Params", __func__); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} + +void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter, v_PVOID_t usrDataForCallback) +{ + v_U8_t staId = 0; + struct net_device *dev; + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + + dev = (struct net_device *)usrDataForCallback; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return; + } + hddLog(LOGE, FL("Clearing all the STA entry....")); + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) + { + if ( pSapCtx->aStaInfo[staId].isUsed && + ( staId != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)) + { + //Disconnect all the stations + hdd_softap_sta_disassoc(pHostapdAdapter, &pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]); + } + } +} + +static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,v_PVOID_t usrDataForCallback) +{ + struct net_device *dev; + hdd_context_t *pHddCtx = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + dev = (struct net_device *)usrDataForCallback; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) { + return status; + } + + if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) + { + if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("Deleting SAP/P2P link!!!!!!")); + } + clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode); + } + EXIT(); + return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY; +} + +#ifdef SAP_AUTH_OFFLOAD +bool hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, + bool enabled) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + struct tSirSapOffloadInfo sap_offload_info; + + vos_mem_copy( &sap_offload_info.macAddr, + pHostapdAdapter->macAddressCurrent.bytes, VOS_MAC_ADDR_SIZE); + + sap_offload_info.sap_auth_offload_enable = enabled; + sap_offload_info.sap_auth_offload_sec_type = + pHddCtx->cfg_ini->sap_auth_offload_sec_type; + sap_offload_info.key_len = + strlen(pHddCtx->cfg_ini->sap_auth_offload_key); + + if (sap_offload_info.sap_auth_offload_enable && + sap_offload_info.sap_auth_offload_sec_type) + { + if (sap_offload_info.key_len < 8 || + sap_offload_info.key_len > WLAN_PSK_STRING_LENGTH) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: invalid key length(%d) of WPA security!", __func__, + sap_offload_info.key_len); + return false; + } + } + if (sap_offload_info.key_len) + { + vos_mem_copy(sap_offload_info.key, + pHddCtx->cfg_ini->sap_auth_offload_key, + sap_offload_info.key_len); + } + if (eHAL_STATUS_SUCCESS != + sme_set_sap_auth_offload(pHddCtx->hHal, &sap_offload_info)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: sme_set_sap_auth_offload fail!", __func__); + return false; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: sme_set_sap_auth_offload successfully!", __func__); + return true; +} +#endif + +VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCallback) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_ap_ctx_t *pHddApCtx; + hdd_hostapd_state_t *pHostapdState; + struct net_device *dev; + eSapHddEvent sapEvent; + union iwreq_data wrqu; + v_BYTE_t *we_custom_event_generic = NULL; + int we_event = 0; + int i = 0; + v_U8_t staId; + VOS_STATUS vos_status; + v_BOOL_t bWPSState; + v_BOOL_t bApActive = FALSE; + v_BOOL_t bAuthRequired = TRUE; + tpSap_AssocMacAddr pAssocStasArray = NULL; + char unknownSTAEvent[IW_CUSTOM_MAX+1]; + char maxAssocExceededEvent[IW_CUSTOM_MAX+1]; + v_BYTE_t we_custom_start_event[64]; + char *startBssEvent; + hdd_context_t *pHddCtx; + hdd_scaninfo_t *pScanInfo = NULL; + struct iw_michaelmicfailure msg; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + hdd_config_t *cfg_param; + + dev = (struct net_device *)usrDataForCallback; + pHostapdAdapter = netdev_priv(dev); + + if ((NULL == pHostapdAdapter) || + (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "invalid adapter or adapter has invalid magic"); + return eHAL_STATUS_FAILURE; + } + pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return eHAL_STATUS_FAILURE; + } + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + sapEvent = pSapEvent->sapHddEventCode; + memset(&wrqu, '\0', sizeof(wrqu)); + pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx); + cfg_param = pHddCtx->cfg_ini; + + + switch(sapEvent) + { + case eSAP_START_BSS_EVENT : + hddLog(LOG1, FL("BSS configured status = %s, channel = %u, bc sta Id = %d"), + pSapEvent->sapevt.sapStartBssCompleteEvent.status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS", + pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel, + pSapEvent->sapevt.sapStartBssCompleteEvent.staId); + + pHostapdState->vosStatus = pSapEvent->sapevt.sapStartBssCompleteEvent.status; + vos_status = vos_event_set(&pHostapdState->vosEvent); + + if (!VOS_IS_STATUS_SUCCESS(vos_status) || pHostapdState->vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: startbss event failed!!")); + goto stopbss; + } + else + { + if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) + { + if ((cfg_param->dynSplitscan) && + (!pHddCtx->issplitscan_enabled)) + { + pHddCtx->issplitscan_enabled = TRUE; + sme_enable_disable_split_scan( + WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + cfg_param->nNumStaChanCombinedConc, + cfg_param->nNumP2PChanCombinedConc); + } + } + + pHddApCtx->uBCStaId = pSapEvent->sapevt.sapStartBssCompleteEvent.staId; + //@@@ need wep logic here to set privacy bit + vos_status = hdd_softap_Register_BC_STA(pHostapdAdapter, pHddApCtx->uPrivacy); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(LOGW, FL("Failed to register BC STA %d"), vos_status); + hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback); + } + } + + if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) + { + // AP Inactivity timer init and start + vos_status = vos_timer_init( &pHddApCtx->hdd_ap_inactivity_timer, VOS_TIMER_TYPE_SW, + hdd_hostapd_inactivity_timer_cb, (v_PVOID_t)dev ); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + + vos_status = vos_timer_start( &pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + + } + pHddApCtx->operatingChannel = pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel; + pHostapdState->bssState = BSS_START; + + // Send current operating channel of SoftAP to BTC-ES + send_btc_nlink_msg(WLAN_BTC_SOFTAP_BSS_START, 0); + + //Check if there is any group key pending to set. + if( pHddApCtx->groupKey.keyLength ) + { + if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta( + (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, + &pHddApCtx->groupKey ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SetKeySta failed", __func__); + } + pHddApCtx->groupKey.keyLength = 0; + } + else if ( pHddApCtx->wepKey[0].keyLength ) + { + int i=0; + for ( i = 0; i < CSR_MAX_NUM_KEY; i++ ) + { + if( VOS_STATUS_SUCCESS != WLANSAP_SetKeySta( + (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, + &pHddApCtx->wepKey[i] ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SetKeySta failed idx %d", __func__, i); + } + } + } + //Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled + startBssEvent = "SOFTAP.enabled"; + memset(&we_custom_start_event, '\0', sizeof(we_custom_start_event)); + memcpy(&we_custom_start_event, startBssEvent, strlen(startBssEvent)); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlen(startBssEvent); + we_event = IWEVCUSTOM; + we_custom_event_generic = we_custom_start_event; + hdd_dump_concurrency_info(pHddCtx); + break; //Event will be sent after Switch-Case stmt + + case eSAP_STOP_BSS_EVENT: + hddLog(LOG1, FL("BSS stop status = %s"),pSapEvent->sapevt.sapStopBssCompleteEvent.status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + + //Free up Channel List incase if it is set + sapCleanupChannelList(); + + pHddApCtx->operatingChannel = 0; //Invalidate the channel info. + + if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) + { + hddLog(LOG1, + FL("P2P Go is getting removed and we are trying to re-enable TDLS")); + wlan_hdd_tdls_reenable(pHddCtx); + } + + goto stopbss; + case eSAP_STA_SET_KEY_EVENT: + //TODO: forward the message to hostapd once implementtation is done for now just print + hddLog(LOG1, FL("SET Key: configured status = %s"),pSapEvent->sapevt.sapStationSetKeyCompleteEvent.status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + return VOS_STATUS_SUCCESS; + case eSAP_STA_DEL_KEY_EVENT: + //TODO: forward the message to hostapd once implementtation is done for now just print + hddLog(LOG1, FL("Event received %s"),"eSAP_STA_DEL_KEY_EVENT"); + return VOS_STATUS_SUCCESS; + case eSAP_STA_MIC_FAILURE_EVENT: + { + memset(&msg, '\0', sizeof(msg)); + msg.src_addr.sa_family = ARPHRD_ETHER; + memcpy(msg.src_addr.sa_data, &pSapEvent->sapevt.sapStationMICFailureEvent.staMac, sizeof(v_MACADDR_t)); + hddLog(LOG1, "MIC MAC "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(msg.src_addr.sa_data)); + if(pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) + msg.flags = IW_MICFAILURE_GROUP; + else + msg.flags = IW_MICFAILURE_PAIRWISE; + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(msg); + we_event = IWEVMICHAELMICFAILURE; + we_custom_event_generic = (v_BYTE_t *)&msg; + } + /* inform mic failure to nl80211 */ + cfg80211_michael_mic_failure(dev, + pSapEvent->sapevt. + sapStationMICFailureEvent.staMac.bytes, + ((pSapEvent->sapevt.sapStationMICFailureEvent.multicast == eSAP_TRUE) ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE), + pSapEvent->sapevt.sapStationMICFailureEvent.keyId, + pSapEvent->sapevt.sapStationMICFailureEvent.TSC, + GFP_KERNEL); + break; + + case eSAP_STA_ASSOC_EVENT: + case eSAP_STA_REASSOC_EVENT: + wrqu.addr.sa_family = ARPHRD_ETHER; + memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac, + sizeof(v_MACADDR_t)); + hddLog(LOG1, " associated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + we_event = IWEVREGISTERED; + + WLANSAP_Get_WPS_State((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, &bWPSState); + + if ( (eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) || + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddApCtx->ucEncryptType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddApCtx->ucEncryptType ) ) + { + bAuthRequired = FALSE; + } + /* fAuthRequiredshould should be false for sap offload */ + if ((bAuthRequired || bWPSState) +#ifdef SAP_AUTH_OFFLOAD + && !cfg_param->enable_sap_auth_offload +#endif + ) + { + vos_status = hdd_softap_RegisterSTA( pHostapdAdapter, + TRUE, + pHddApCtx->uPrivacy, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId, + 0, + 0, + (v_MACADDR_t *)wrqu.addr.sa_data, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""), + vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + } + else + { + vos_status = hdd_softap_RegisterSTA( pHostapdAdapter, + FALSE, + pHddApCtx->uPrivacy, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId, + 0, + 0, + (v_MACADDR_t *)wrqu.addr.sa_data, + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("Failed to register STA %d "MAC_ADDRESS_STR""), + vos_status, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + } + + staId = + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId; + if (VOS_IS_STATUS_SUCCESS(vos_status)) + { + + pSapCtx->aStaInfo[staId].rate_flags = + pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.rate_flags; + } + + // Stop AP inactivity timer + if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_RUNNING) + { + vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to start AP inactivity timer")); + } +#ifdef WLAN_OPEN_SOURCE + if (wake_lock_active(&pHddCtx->sap_wake_lock)) + { + vos_wake_lock_release(&pHddCtx->sap_wake_lock, + WIFI_POWER_EVENT_WAKELOCK_SAP); + } + vos_wake_lock_timeout_release(&pHddCtx->sap_wake_lock, + HDD_SAP_WAKE_LOCK_DURATION, + WIFI_POWER_EVENT_WAKELOCK_SAP); + +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + { + struct station_info *staInfo; + v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen; + + staInfo = vos_mem_malloc(sizeof(*staInfo)); + if (staInfo == NULL) { + hddLog(LOGE, FL("alloc station_info failed")); + return VOS_STATUS_E_NOMEM; + } + + memset(staInfo, 0, sizeof(*staInfo)); + if (iesLen <= MAX_ASSOC_IND_IE_LEN ) + { + staInfo->assoc_req_ies = + (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0]; + staInfo->assoc_req_ies_len = iesLen; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31)) + staInfo->filled |= STATION_INFO_ASSOC_REQ_IES; +#endif + cfg80211_new_sta(dev, + (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0], + staInfo, GFP_KERNEL); + vos_mem_free(staInfo); + } + else + { + hddLog(LOGE, FL(" Assoc Ie length is too long")); + } + } +#endif + hdd_manage_delack_timer(pHddCtx); + + pScanInfo = &pHddCtx->scan_info; + // Lets do abort scan to ensure smooth authentication for client + if ((pScanInfo != NULL) && pScanInfo->mScanPending) + { + hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + + break; + case eSAP_STA_DISASSOC_EVENT: + memcpy(wrqu.addr.sa_data, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, + sizeof(v_MACADDR_t)); + hddLog(LOG1, " disassociated "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(wrqu.addr.sa_data)); + if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason == eSAP_USR_INITATED_DISASSOC) + hddLog(LOG1," User initiated disassociation"); + else + hddLog(LOG1," MAC initiated disassociation"); + we_event = IWEVEXPIRED; + vos_status = hdd_softap_GetStaId(pHostapdAdapter, &pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac, &staId); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!")); + return VOS_STATUS_E_FAILURE; + } + hdd_softap_DeregisterSTA(pHostapdAdapter, staId); + + if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) + { + spin_lock_bh( &pSapCtx->staInfo_lock ); + // Start AP inactivity timer if no stations associated with it + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (pSapCtx->aStaInfo[i].isUsed && i != (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId) + { + bApActive = TRUE; + break; + } + } + spin_unlock_bh( &pSapCtx->staInfo_lock ); + + if (bApActive == FALSE) + { + if (pHddApCtx->hdd_ap_inactivity_timer.state == VOS_TIMER_STATE_STOPPED) + { + vos_status = vos_timer_start(&pHddApCtx->hdd_ap_inactivity_timer, (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff * 1000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to init AP inactivity timer")); + } + else + VOS_ASSERT(vos_timer_getCurrentState(&pHddApCtx->hdd_ap_inactivity_timer) == VOS_TIMER_STATE_STOPPED); + } + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + cfg80211_del_sta(dev, + (const u8 *)&pSapEvent->sapevt.sapStationDisassocCompleteEvent.staMac.bytes[0], + GFP_KERNEL); +#endif + //Update the beacon Interval if it is P2P GO + vos_status = hdd_change_mcc_go_beacon_interval(pHostapdAdapter); + if (VOS_STATUS_SUCCESS != vos_status) + { + hddLog(LOGE, "%s: failed to update Beacon interval %d", + __func__, vos_status); + } + hdd_manage_delack_timer(pHddCtx); + break; + case eSAP_WPS_PBC_PROBE_REQ_EVENT: + { + static const char * message ="MLMEWPSPBCPROBEREQ.indication"; + union iwreq_data wreq; + + down(&pHddApCtx->semWpsPBCOverlapInd); + pHddApCtx->WPSPBCProbeReq.probeReqIELen = pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIELen; + + vos_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.probeReqIE, + pHddApCtx->WPSPBCProbeReq.probeReqIELen); + + vos_mem_copy(pHddApCtx->WPSPBCProbeReq.peerMacAddr, pSapEvent->sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq.peerMacAddr, sizeof(v_MACADDR_t)); + hddLog(LOG1, "WPS PBC probe req "MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.peerMacAddr)); + memset(&wreq, 0, sizeof(wreq)); + wreq.data.length = strlen(message); // This is length of message + wireless_send_event(dev, IWEVCUSTOM, &wreq, (char *)message); + + return VOS_STATUS_SUCCESS; + } + case eSAP_ASSOC_STA_CALLBACK_EVENT: + pAssocStasArray = pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas; + if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) + { // List of associated stations + for (i = 0; i < pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta; i++) + { + hddLog(LOG1,"Associated Sta Num %d:assocId=%d, staId=%d, staMac="MAC_ADDRESS_STR, + i+1, + pAssocStasArray->assocId, + pAssocStasArray->staId, + MAC_ADDR_ARRAY(pAssocStasArray->staMac.bytes)); + pAssocStasArray++; + } + } + vos_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas);// Release caller allocated memory here + pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL; + return VOS_STATUS_SUCCESS; + case eSAP_REMAIN_CHAN_READY: + hdd_remainChanReadyHandler( pHostapdAdapter ); + return VOS_STATUS_SUCCESS; + case eSAP_SEND_ACTION_CNF: + hdd_sendActionCnf( pHostapdAdapter, + ( eSAP_STATUS_SUCCESS == + pSapEvent->sapevt.sapActionCnf.actionSendSuccess ) ? + TRUE : FALSE ); + return VOS_STATUS_SUCCESS; + case eSAP_UNKNOWN_STA_JOIN: + snprintf(unknownSTAEvent, IW_CUSTOM_MAX, "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x", + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4], + pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]); + we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ + wrqu.data.pointer = unknownSTAEvent; + wrqu.data.length = strlen(unknownSTAEvent); + we_custom_event_generic = (v_BYTE_t *)unknownSTAEvent; + hddLog(LOGE,"%s", unknownSTAEvent); + break; + + case eSAP_MAX_ASSOC_EXCEEDED: + snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX, "Peer %02x:%02x:%02x:%02x:%02x:%02x denied" + " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect" + " one or more devices to enable the new device connection", + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4], + pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[5]); + we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */ + wrqu.data.pointer = maxAssocExceededEvent; + wrqu.data.length = strlen(maxAssocExceededEvent); + we_custom_event_generic = (v_BYTE_t *)maxAssocExceededEvent; + hddLog(LOG1,"%s", maxAssocExceededEvent); + break; + case eSAP_STA_ASSOC_IND: + return VOS_STATUS_SUCCESS; + + case eSAP_DISCONNECT_ALL_P2P_CLIENT: + hddLog(LOG1, FL(" Disconnecting all the P2P Clients....")); + hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback); + return VOS_STATUS_SUCCESS; + + case eSAP_MAC_TRIG_STOP_BSS_EVENT : + vos_status = hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(LOGW, FL("hdd_stop_bss_link failed %d"), vos_status); + } + return VOS_STATUS_SUCCESS; + + default: + hddLog(LOG1,"SAP message is not handled"); + goto stopbss; + return VOS_STATUS_SUCCESS; + } + wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic); + return VOS_STATUS_SUCCESS; + +stopbss : + { + v_BYTE_t we_custom_event[64]; + char *stopBssEvent = "STOP-BSS.response";//17 + int event_len = strlen(stopBssEvent); + + hddLog(LOG1, FL("BSS stop status = %s"), + pSapEvent->sapevt.sapStopBssCompleteEvent.status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + + /* Change the BSS state now since, as we are shutting things down, + * we don't want interfaces to become re-enabled */ + pHostapdState->bssState = BSS_STOP; + + if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff) + { + if (VOS_TIMER_STATE_RUNNING == pHddApCtx->hdd_ap_inactivity_timer.state) + { + vos_status = vos_timer_stop(&pHddApCtx->hdd_ap_inactivity_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to stop AP inactivity timer")); + } + + vos_status = vos_timer_destroy(&pHddApCtx->hdd_ap_inactivity_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to Destroy AP inactivity timer")); + } + + /* Stop the pkts from n/w stack as we are going to free all of + * the TX WMM queues for all STAID's */ + + /* + * If channel avoidance is in progress means driver is performing SAP + * restart. So don't do carrier off, which may lead framework to do + * driver reload. + */ + hddLog(LOG1, FL("ch avoid in progress: %d"), + pHddCtx->is_ch_avoid_in_progress); + if (pHddCtx->is_ch_avoid_in_progress && + pHddCtx->cfg_ini->sap_internal_restart) + netif_tx_disable(dev); + else + hdd_hostapd_stop(dev); + + /* reclaim all resources allocated to the BSS */ + vos_status = hdd_softap_stop_bss(pHostapdAdapter); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGW, FL("hdd_softap_stop_bss failed %d"), vos_status); + + /* once the event is set, structure dev/pHostapdAdapter should + * not be touched since they are now subject to being deleted + * by another thread */ + if (eSAP_STOP_BSS_EVENT == sapEvent) + vos_event_set(&pHostapdState->vosEvent); + + /* notify userspace that the BSS has stopped */ + memset(&we_custom_event, '\0', sizeof(we_custom_event)); + memcpy(&we_custom_event, stopBssEvent, event_len); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = event_len; + we_event = IWEVCUSTOM; + we_custom_event_generic = we_custom_event; + wireless_send_event(dev, we_event, &wrqu, (char *)we_custom_event_generic); + hdd_dump_concurrency_info(pHddCtx); + } + return VOS_STATUS_SUCCESS; +} + +int hdd_softap_unpackIE( + tHalHandle halHandle, + eCsrEncryptionType *pEncryptType, + eCsrEncryptionType *mcEncryptType, + eCsrAuthType *pAuthType, + v_BOOL_t *pMFPCapable, + v_BOOL_t *pMFPRequired, + u_int16_t gen_ie_len, + u_int8_t *gen_ie ) +{ + tDot11fIERSN dot11RSNIE; + tDot11fIEWPA dot11WPAIE; + + tANI_U8 *pRsnIe; + tANI_U16 RSNIeLen; + + if (NULL == halHandle) + { + hddLog(LOGE, FL("Error haHandle returned NULL")); + return -EINVAL; + } + + // Validity checks + if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) || + (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) ) + return -EINVAL; + // Type check + if ( gen_ie[0] == DOT11F_EID_RSN) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) ) + { + return VOS_STATUS_E_FAILURE; + } + // Skip past the EID byte and length byte + pRsnIe = gen_ie + 2; + RSNIeLen = gen_ie_len - 2; + // Unpack the RSN IE + memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN)); + dot11fUnpackIeRSN((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11RSNIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"), + __func__, dot11RSNIE.pwise_cipher_suite_count ); + hddLog(LOG1, FL("%s: authentication suite count: %d"), + __func__, dot11RSNIE.akm_suite_count); + /*Here we have followed the apple base code, + but probably I suspect we can do something different*/ + //dot11RSNIE.akm_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]); + //dot11RSNIE.pwise_cipher_suite_count + *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]); + //dot11RSNIE.gp_cipher_suite_count + *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite); + // Set the PMKSA ID Cache for this interface + *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80); + *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40); + + // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache + } else + if (gen_ie[0] == DOT11F_EID_WPA) + { + // Validity checks + if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) || + (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) + { + return VOS_STATUS_E_FAILURE; + } + // Skip past the EID byte and length byte - and four byte WiFi OUI + pRsnIe = gen_ie + 2 + 4; + RSNIeLen = gen_ie_len - (2 + 4); + // Unpack the WPA IE + memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA)); + dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, + pRsnIe, + RSNIeLen, + &dot11WPAIE); + // Copy out the encryption and authentication types + hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"), + __func__, dot11WPAIE.unicast_cipher_count ); + hddLog(LOG1, FL("%s: WPA authentication suite count: %d"), + __func__, dot11WPAIE.auth_suite_count); + //dot11WPAIE.auth_suite_count + // Just translate the FIRST one + *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]); + //dot11WPAIE.unicast_cipher_count + *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]); + //dot11WPAIE.unicast_cipher_count + *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher); + *pMFPCapable = VOS_FALSE; + *pMFPRequired = VOS_FALSE; + } + else + { + hddLog(LOGW, FL("%s: gen_ie[0]: %d"), __func__, gen_ie[0]); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_CH_AVOID + +/*========================================================================== + FUNCTION sapUpdateUnsafeChannelList + + DESCRIPTION + Function Undate unsafe channel list table + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSapCtx : SAP context pointer, include unsafe channel list + + RETURN VALUE + NONE +============================================================================*/ +void hdd_hostapd_update_unsafe_channel_list(hdd_context_t *pHddCtx, + v_U16_t *unsafeChannelList, v_U16_t unsafeChannelCount) +{ + v_U16_t i, j; + + vos_mem_zero((void *)pHddCtx->unsafeChannelList, + sizeof(pHddCtx->unsafeChannelList)); + if (0 == unsafeChannelCount) + { + pHddCtx->unsafeChannelCount = 0; + } + else + { + if (unsafeChannelCount > NUM_20MHZ_RF_CHANNELS) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("unsafeChannelCount%hd greater than %d"), + unsafeChannelCount, NUM_20MHZ_RF_CHANNELS); + unsafeChannelCount = NUM_20MHZ_RF_CHANNELS; + } + vos_mem_copy((void *)pHddCtx->unsafeChannelList, + unsafeChannelList, + unsafeChannelCount * sizeof(tANI_U16)); + pHddCtx->unsafeChannelCount = unsafeChannelCount; + } + + /* Flush, default set all channel safe */ + for (i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) + { + safeChannels[i].isSafe = VOS_TRUE; + } + + /* Try to find unsafe channel */ + for (i = 0; i < pHddCtx->unsafeChannelCount; i++) + { + for (j = 0; j < NUM_20MHZ_RF_CHANNELS; j++) + { + if(safeChannels[j].channelNumber == pHddCtx->unsafeChannelList[i]) + { + /* Found unsafe channel, update it */ + safeChannels[j].isSafe = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s : CH %d is not safe", + __func__, pHddCtx->unsafeChannelList[i]); + break; + } + } + } + + return; +} + +/** + * hdd_unsafe_channel_restart_sap - restart sap if sap is on unsafe channel + * @adapter: hdd ap adapter + * + * hdd_unsafe_channel_restart_sap check all unsafe channel list + * and if ACS is enabled, driver will ask userspace to restart the + * sap. User space on LTE coex indication restart driver. + * + * Return - none + */ +static void hdd_unsafe_channel_restart_sap(hdd_adapter_t *adapter, + hdd_context_t *hdd_ctx) +{ + + if (!(adapter && (WLAN_HDD_SOFTAP == adapter->device_mode))) { + return; + } + + hddLog(LOG1, FL("Current operation channel %d"), + adapter->sessionCtx.ap.operatingChannel); + if (false == hdd_ctx->is_ch_avoid_in_progress) { + hdd_change_ch_avoidance_status(hdd_ctx, true); + + vos_flush_work( + &hdd_ctx->sap_start_work); + + /* + * current operating channel + * is un-safe channel, restart SAP + */ + hddLog(LOG1, + FL("Restarting SAP due to unsafe channel")); + + adapter->sessionCtx.ap.sapConfig.channel = + AUTO_CHANNEL_SELECT; + + + if (hdd_ctx->cfg_ini->sap_internal_restart) { + netif_tx_disable(adapter->dev); + schedule_work(&hdd_ctx->sap_start_work); + } else { + hdd_hostapd_stop(adapter->dev); + } + + return; + } + return; +} + +void hdd_check_for_unsafe_ch(hdd_adapter_t *phostapd_adapter, + hdd_context_t *hdd_ctxt) +{ + v_U16_t channelLoop; + v_U16_t unsafeChannelCount = 0; + v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS]; + + /* Get unsafe channel list */ + vos_get_wlan_unsafe_channel(unsafeChannelList, sizeof(unsafeChannelList), + &unsafeChannelCount); + for (channelLoop = 0; channelLoop < unsafeChannelCount; channelLoop++) + { + if ((unsafeChannelList[channelLoop] == + phostapd_adapter->sessionCtx.ap.operatingChannel)) { + if ((AUTO_CHANNEL_SELECT == + phostapd_adapter->sessionCtx.ap.sapConfig.channel) + && (WLAN_HDD_SOFTAP == phostapd_adapter->device_mode)) { + /* + * current operating channel is un-safe channel + * restart driver + */ + hdd_unsafe_channel_restart_sap(phostapd_adapter, hdd_ctxt); + /* + * On LE, this event is handled by wlan-services to + * restart SAP. On android, this event would be + * ignored. + */ + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_SAP_RESTART_IND, + NULL, 0); + } + break; + } + } + return; +} + + + +/**--------------------------------------------------------------------------- + + \brief hdd_hostapd_ch_avoid_cb() - + + Avoid channel notification from FW handler. + FW will send un-safe channle list to avoid overwrapping. + hostapd should not use notified channel + + \param - pAdapter HDD adapter pointer + indParam channel avoid notification parameter + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_hostapd_ch_avoid_cb +( + void *context, + void *indParam +) +{ + hdd_adapter_t *pHostapdAdapter = NULL; + hdd_context_t *hddCtxt; + tSirChAvoidIndType *chAvoidInd; + v_U8_t rangeLoop; + v_U16_t channelLoop; + v_U16_t dupCheck; + v_U16_t startChannel; + v_U16_t endChannel; + v_U16_t unsafeChannelCount = 0; + v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS]; + v_CONTEXT_t pVosContext; + tHddAvoidFreqList hddAvoidFreqList; + tANI_U32 i; +#ifdef WLAN_FEATURE_AP_HT40_24G + ptSapContext pSapCtx = NULL; + tHalHandle hHal; + v_U8_t cbMode; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t delay; +#endif + + /* Basic sanity */ + if ((NULL == context) || (NULL == indParam)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : Invalid arguments", __func__); + return; + } + + hddCtxt = (hdd_context_t *)context; + chAvoidInd = (tSirChAvoidIndType *)indParam; + pVosContext = hddCtxt->pvosContext; + + /* Make unsafe channel list */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : band count %d", + __func__, chAvoidInd->avoidRangeCount); + vos_mem_zero((void *)unsafeChannelList, + NUM_20MHZ_RF_CHANNELS * sizeof(v_U16_t)); + for (rangeLoop = 0; rangeLoop < chAvoidInd->avoidRangeCount; rangeLoop++) + { + if (unsafeChannelCount >= NUM_20MHZ_RF_CHANNELS) { + hddLog(LOGW, FL("LTE Coex unsafe channel list full")); + break; + } + startChannel = ieee80211_frequency_to_channel( + chAvoidInd->avoidFreqRange[rangeLoop].startFreq); + endChannel = ieee80211_frequency_to_channel( + chAvoidInd->avoidFreqRange[rangeLoop].endFreq); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : start %d : %d, end %d : %d", + __func__, + chAvoidInd->avoidFreqRange[rangeLoop].startFreq, + startChannel, + chAvoidInd->avoidFreqRange[rangeLoop].endFreq, + endChannel); + for (channelLoop = startChannel; + channelLoop < (endChannel + 1); + channelLoop++) + { + /* Channel duplicate check routine */ + for (dupCheck = 0; dupCheck < unsafeChannelCount; dupCheck++) + { + if (unsafeChannelList[dupCheck] == channelLoop) + { + /* This channel is duplicated */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : found duplicated channel %d", + __func__, channelLoop); + break; + } + } + if (dupCheck == unsafeChannelCount) + { + int ii; + for(ii=0; ii= NUM_20MHZ_RF_CHANNELS) { + hddLog(LOGW, FL("LTE Coex unsafe channel list full")); + break; + } + } + } + } + else + { + /* DUP, do nothing */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : duplicated channel %d", + __func__, channelLoop); + } + } + } + /* Update unsafe channel cache + * WCN Platform Driver cache */ + wcnss_set_wlan_unsafe_channel(unsafeChannelList, + unsafeChannelCount); + + /* Store into local cache + * Start with STA and later start SAP + * in this scenario, local cache will be used */ + hdd_hostapd_update_unsafe_channel_list(hddCtxt, + unsafeChannelList, + unsafeChannelCount); + + /* generate vendor specific event */ + vos_mem_zero((void *)&hddAvoidFreqList, sizeof(tHddAvoidFreqList)); + for (i = 0; i < chAvoidInd->avoidRangeCount; i++) + { + hddAvoidFreqList.avoidFreqRange[i].startFreq = + chAvoidInd->avoidFreqRange[i].startFreq; + hddAvoidFreqList.avoidFreqRange[i].endFreq = + chAvoidInd->avoidFreqRange[i].endFreq; + } + hddAvoidFreqList.avoidFreqRangeCount = chAvoidInd->avoidRangeCount; + + wlan_hdd_send_avoid_freq_event(hddCtxt, &hddAvoidFreqList); + + /* Get SAP context first + * SAP and P2PGO would not concurrent */ + pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_SOFTAP); +#ifdef WLAN_FEATURE_AP_HT40_24G + if (NULL == pHostapdAdapter) + { + pHostapdAdapter = hdd_get_adapter(hddCtxt, WLAN_HDD_P2P_GO); + } +#endif + if ((pHostapdAdapter) && + (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) && + (unsafeChannelCount)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : Current operation channel %d", + __func__, + pHostapdAdapter->sessionCtx.ap.operatingChannel); + /* Check and Restart the SAP if it is on unsafe channel */ + hdd_check_for_unsafe_ch(pHostapdAdapter, hddCtxt); + + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (hddCtxt->cfg_ini->apHT40_24GEnabled) + { + pSapCtx = VOS_GET_SAP_CB(pVosContext); + + if(pSapCtx == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("SAP Secondary channel: %d "), + pSapCtx->sap_sec_chan); + + /* tHalHandle */ + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("In invalid hHal")); + return; + } + + cbMode = sme_GetChannelBondingMode24G(hHal); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Selected Channel bonding : %d"), cbMode); + + if (cbMode && (pSapCtx->sap_sec_chan > 0)) + { + int i; + eHalStatus halStatus; + + for (i = 0; i < unsafeChannelCount; i++) + { + if ((pSapCtx->sap_sec_chan == unsafeChannelList[i])) + { + /* Current SAP Secondary channel is un-safe channel */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Move SAP from HT40 to HT20")); + + halStatus = sme_SetHT2040Mode(hHal, pSapCtx->sessionId, + PHY_SINGLE_CHANNEL_CENTERED); + + if (halStatus == eHAL_STATUS_FAILURE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to change HT20/40 mode")); + return; + } + + /* Disable Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(hHal, + PHY_SINGLE_CHANNEL_CENTERED); + return; + } + } + } + + if ((!pSapCtx->numHT40IntoSta) + && (pHostapdAdapter) + && (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))) + { + /* if Unsafe channel is Zero or SAP Primary/Secondary channel + * are Safe then start HT20/40 timer to Move SAP from HT20 + * to HT40. + */ + if (((!unsafeChannelCount) + || (!sapCheckHT40SecondaryIsNotAllowed(pSapCtx))) && (!cbMode)) + { + /* Stop Previous Running HT20/40 Timer & Start timer + with (OBSS TransitionDelayFactor * obss interval) + delay after time out move AP from HT20 -> HT40 + mode + */ + if (VOS_TIMER_STATE_RUNNING == pSapCtx->sap_HT2040_timer.state) + { + vosStatus = vos_timer_stop(&pSapCtx->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + + delay = + (pSapCtx->ObssScanInterval * pSapCtx->ObssTransitionDelayFactor); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Start HT20/40 transition timer (%d sec)"), delay); + + vosStatus = vos_timer_start( &pSapCtx->sap_HT2040_timer, + (delay * 1000)); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Start HT20/40 timer")); + } + else + { + /* Stop HT20/40 Timer */ + if (VOS_TIMER_STATE_RUNNING == pSapCtx->sap_HT2040_timer.state) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Stop HT20/40 transition timer")); + vosStatus = vos_timer_stop(&pSapCtx->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + } + } + } +#endif + return; +} +#endif /* FEATURE_WLAN_CH_AVOID */ + +int +static __iw_softap_setparam(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal; + hdd_context_t *pHddCtx = NULL; + int *value = (int *)extra; + int sub_cmd = value[0]; + int set_value = value[1]; + eHalStatus status; + int ret = 0; /* success */ + int enable_pattrn_byte_match, enable_magic_pkt; + v_CONTEXT_t pVosContext; + + ENTER(); + + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hostapd Adapter is null", + __func__); + return -1; + } + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return -1; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (!hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal ctx is null", __func__); + return -1; + } + + pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + if (!pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Vos ctx is null", __func__); + return -1; + } + + switch(sub_cmd) + { + + case QCSAP_PARAM_CLR_ACL: + if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext )) + { + ret = -EIO; + } + break; + + case QCSAP_PARAM_ACL_MODE: + if ((eSAP_ALLOW_ALL < (eSapMacAddrACL)set_value) || + (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL)set_value)) + { + hddLog(LOGE, FL("Invalid ACL Mode value %d"), set_value); + ret = -EINVAL; + } + else + { + WLANSAP_SetMode(pVosContext, set_value); + } + break; + + case QCSAP_PARAM_SET_AUTO_CHANNEL: + if ((0 != set_value) && (1 != set_value)) + { + hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value); + ret = -EINVAL; + } + else + { + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value; + } + break; + + case QCSAP_PARAM_MAX_ASSOC: + if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) + { + hddLog(LOGE, FL("Invalid setMaxAssoc value %d"), set_value); + ret = -EINVAL; + } + else + { + if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) + { + hddLog(LOGW, FL("setMaxAssoc value %d higher than max allowed %d." + "Setting it to max allowed and continuing"), + set_value, WNI_CFG_ASSOC_STA_LIMIT_STAMAX); + set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX; + } + status = ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, + set_value, NULL, eANI_BOOLEAN_FALSE); + if ( status != eHAL_STATUS_SUCCESS ) + { + hddLog(LOGE, FL("setMaxAssoc failure, status %d"), + status); + ret = -EIO; + } + } + break; + + case QCSAP_PARAM_HIDE_SSID: + { + eHalStatus status = eHAL_STATUS_SUCCESS; + status = sme_HideSSID(hHal, pHostapdAdapter->sessionId, set_value); + if(eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCSAP_PARAM_HIDE_SSID failed", + __func__); + return status; + } + break; + } + + case QCSAP_PARAM_SET_MC_RATE: + { + tSirRateUpdateInd *rateUpdate; + + rateUpdate = (tSirRateUpdateInd *) + vos_mem_malloc(sizeof(tSirRateUpdateInd)); + if (NULL == rateUpdate) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SET_MC_RATE indication alloc fail", __func__); + ret = -1; + break; + } + vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd )); + + hddLog(VOS_TRACE_LEVEL_INFO, "MC Target rate %d", set_value); + /* Ignore unicast */ + rateUpdate->ucastDataRate = -1; + rateUpdate->mcastDataRate24GHz = set_value; + rateUpdate->mcastDataRate5GHz = set_value; + rateUpdate->mcastDataRate24GHzTxFlag = 0; + rateUpdate->mcastDataRate5GHzTxFlag = 0; + status = sme_SendRateUpdateInd(hHal, rateUpdate); + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SET_MC_RATE failed", __func__); + vos_mem_free(rateUpdate); + ret = -1; + } + break; + } + case QCSAP_PARAM_GET_FRAME_LOGS: + { + if (wlan_hdd_get_frame_logs(pHostapdAdapter, set_value) + != VOS_STATUS_SUCCESS) + { + ret = -EINVAL; + } + break; + } + case QCSAP_PARAM_SET_PROXIMITY: + { + ret = wlan_hdd_set_proximity(set_value, hHal); + break; + } + case QCSAP_PARAM_SET_WOWL: + { + if (!pHddCtx->is_ap_mode_wow_supported) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Not supported",__func__); + return -ENOTSUPP; + } + switch (set_value) + { + case 0x00: + hdd_exit_wowl(pHostapdAdapter, eWOWL_EXIT_USER); + break; + case 0x01: + case 0x02: + case 0x03: + enable_magic_pkt = (set_value & 0x01) ? 1 : 0; + enable_pattrn_byte_match = (set_value & 0x02) ? 1 : 0; + hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s", + (enable_magic_pkt ? "YES":"NO"), + (enable_pattrn_byte_match ? "YES":"NO")); + hdd_enter_wowl(pHostapdAdapter, enable_magic_pkt, + enable_pattrn_byte_match); + break; + default: + hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL", set_value); + ret = -EINVAL; + break; + } + break; + } + case QCSAP_PARAM_CAP_TSF: + { + ret = hdd_capture_tsf(pHostapdAdapter, + (uint32_t *)&set_value, 1); + break; + } + default: + hddLog(LOGE, FL("Invalid setparam command %d value %d"), + sub_cmd, set_value); + ret = -EINVAL; + break; + } + + EXIT(); + return ret; +} + +int +static iw_softap_setparam(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_setparam(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int +static __iw_softap_getparam(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int sub_cmd = value[0]; + eHalStatus status; + int ret = 0; /* success */ + v_CONTEXT_t pVosContext; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pVosContext Context is NULL",__func__); + return -EINVAL; + } + switch (sub_cmd) + { + case QCSAP_PARAM_MAX_ASSOC: + status = ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),status); + ret = -EIO; + } + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + if (pHddCtx->cfg_ini->fEnableVSTASupport) + { + if (*value > VSTA_NUM_ASSOC_STA) + { + *value = VSTA_NUM_ASSOC_STA; + } + if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) && + (*value > (VSTA_NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA)))) + { + *value = (VSTA_NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA)); + } + } + else +#endif + { + if (*value > NUM_ASSOC_STA) + { + *value = NUM_ASSOC_STA; + } + if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) && + (*value > (NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA)))) + { + *value = (NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA)); + } + } + break; + + case QCSAP_PARAM_CLR_ACL: + if ( VOS_STATUS_SUCCESS != WLANSAP_ClearACL( pVosContext )) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("WLANSAP_ClearACL failed")); + ret = -EIO; + } + *value = 0; + break; + + case QCSAP_PARAM_GET_WLAN_DBG: + { + vos_trace_display(); + *value = 0; + break; + } + + case QCSAP_PARAM_AUTO_CHANNEL: + { + *value = (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection; + break; + } + + default: + hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd); + ret = -EINVAL; + break; + + } + + EXIT(); + return ret; +} + +int +static iw_softap_getparam(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_getparam(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int +static __iw_softap_setchar_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int sub_cmd; + int ret = 0; /* success */ + char *pBuffer = NULL; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + struct iw_point s_priv_data; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pAdapter = (netdev_priv(dev)); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + if (!pHddCtx->is_ap_mode_wow_supported) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Not supported",__func__); + return -ENOTSUPP; + } + + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) + { + return -EINVAL; + } + + /* make sure all params are correctly passed to function */ + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) + { + return -EINVAL; + } + + sub_cmd = s_priv_data.flags; + + /* ODD number is used for set, copy data using copy_from_user */ + pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); + if (NULL == pBuffer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received length %d", __func__, s_priv_data.length); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received data %s", __func__, pBuffer); + + switch(sub_cmd) + { + case WE_WOWL_ADD_PTRN: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN"); + ret = hdd_add_wowl_ptrn(pAdapter, pBuffer); + if (!ret) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to add pattern :%d", ret); + break; + case WE_WOWL_DEL_PTRN: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN"); + ret = hdd_del_wowl_ptrn(pAdapter, pBuffer); + if (!ret) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Failed to del pattern :%d", ret); + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ioctl not supported in SOFTAP"); + ret = -EINVAL; + break; + } + + kfree(pBuffer); + return ret; +} + +int +static iw_softap_setchar_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_setchar_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* Usage: + BLACK_LIST = 0 + WHITE_LIST = 1 + ADD MAC = 0 + REMOVE MAC = 1 + + mac addr will be accepted as a 6 octet mac address with each octet inputted in hex + for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33 + while using this ioctl + + Syntax: + iwpriv softap.0 modify_acl + <6 octet mac addr> + + Examples: + eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list + iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0 + eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list + iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1 +*/ +int __iw_softap_modify_acl(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + v_CONTEXT_t pVosContext; + hdd_context_t *pHddCtx; + v_BYTE_t *value = (v_BYTE_t*)extra; + v_U8_t pPeerStaMac[VOS_MAC_ADDR_SIZE]; + int listType, cmd, i; + int ret = 0; /* success */ + + ENTER(); + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Vos Context is NULL",__func__); + return -EINVAL; + } + for (i=0; ioperatingChannel; + + EXIT(); + return 0; +} + + +int +static iw_softap_getchannel(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_getchannel(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int +static __iw_softap_set_max_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int set_value, ret = 0; + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + if (NULL == value) + return -ENOMEM; + + /* Assign correct slef MAC address */ + vos_mem_copy(bssid, pHostapdAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + vos_mem_copy(selfMac, pHostapdAdapter->macAddressCurrent.bytes, + VOS_MAC_ADDR_SIZE); + + set_value = value[0]; + if (eHAL_STATUS_SUCCESS != sme_SetMaxTxPower(hHal, bssid, selfMac, set_value)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed", + __func__); + return -EIO; + } + + EXIT(); + return 0; +} + +int +static iw_softap_set_max_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +int +static __iw_display_data_path_snapshot(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + /* Function intitiating dumping states of + * HDD(WMM Tx Queues) + * TL State (with Per Client infor) + * DXE Snapshot (Called at the end of TL Snapshot) + */ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hdd_wmm_tx_snapshot(pHostapdAdapter); + WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT); + + EXIT(); + return 0; +} + +int +static iw_display_data_path_snapshot(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_display_data_path_snapshot(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int +static __iw_softap_set_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext; + tHalHandle hHal; + int *value = (int *)extra; + int set_value, ret = 0; + ptSapContext pSapCtx = NULL; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Vos Context is NULL",__func__); + return -EINVAL; + } + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + if (NULL == value) + return -ENOMEM; + + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if (NULL == pSapCtx) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + set_value = value[0]; + if (eHAL_STATUS_SUCCESS != sme_SetTxPower(hHal, pSapCtx->sessionId, set_value)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting tx power failed", + __func__); + return -EIO; + } + + EXIT(); + return 0; +} + +int +static iw_softap_set_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_set_tx_power(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief iw_softap_set_trafficmonitor() - + This function dynamically enable/disable traffic monitor functonality + the command iwpriv wlanX setTrafficMon . + + \param - dev - Pointer to the net device. + - addr - Pointer to the sockaddr. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int __iw_softap_set_trafficmonitor(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + int *isSetTrafficMon = (int *)extra; + hdd_context_t *pHddCtx; + int status; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s : ", __func__); + + if (NULL == isSetTrafficMon) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from extra", __func__); + return -ENOMEM; + } + + if (TRUE == *isSetTrafficMon) + { + pHddCtx->cfg_ini->enableTrafficMonitor= TRUE; + if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter, false)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR, + "%s: failed to Start Traffic Monitor timer ", __func__ ); + return -EIO; + } + } + else if (FALSE == *isSetTrafficMon) + { + pHddCtx->cfg_ini->enableTrafficMonitor= FALSE; + if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter, false)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR, + "%s: failed to Stop Traffic Monitor timer ", __func__ ); + return -EIO; + } + + } + + EXIT(); + return 0; +} + +static int iw_softap_set_trafficmonitor(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_set_trafficmonitor(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0) + +int +static __iw_softap_getassoc_stamacaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + hdd_station_info_t *pStaInfo = NULL; + char *buf; + int cnt = 0; + int left; + int ret = 0; + /* maclist_index must be u32 to match userspace */ + u32 maclist_index; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + /* + * NOTE WELL: this is a "get" ioctl but it uses an even ioctl + * number, and even numbered iocts are supposed to have "set" + * semantics. Hence the wireless extensions support in the kernel + * won't correctly copy the result to userspace, so the ioctl + * handler itself must copy the data. Output format is 32-bit + * record length, followed by 0 or more 6-byte STA MAC addresses. + * + * Further note that due to the incorrect semantics, the "iwpriv" + * userspace application is unable to correctly invoke this API, + * hence it is not registered in the hostapd_private_args. This + * API can only be invoked by directly invoking the ioctl() system + * call. + */ + + /* make sure userspace allocated a reasonable buffer size */ + if (wrqu->data.length < sizeof(maclist_index)) { + hddLog(LOG1, "%s: invalid userspace buffer", __func__); + return -EINVAL; + } + + pVosContext = ( WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return -EFAULT; + } + + /* allocate local buffer to build the response */ + buf = kmalloc(wrqu->data.length, GFP_KERNEL); + if (!buf) { + hddLog(LOG1, "%s: failed to allocate response buffer", __func__); + return -ENOMEM; + } + + pStaInfo = pSapCtx->aStaInfo; + /* start indexing beyond where the record count will be written */ + maclist_index = sizeof(maclist_index); + left = wrqu->data.length - maclist_index; + + spin_lock_bh(&pSapCtx->staInfo_lock); + while ((cnt < WLAN_MAX_STA_COUNT) && (left >= VOS_MAC_ADDR_SIZE)) { + if ((pStaInfo[cnt].isUsed) && + (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) { + memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA), + VOS_MAC_ADDR_SIZE); + maclist_index += VOS_MAC_ADDR_SIZE; + left -= VOS_MAC_ADDR_SIZE; + } + cnt++; + } + spin_unlock_bh(&pSapCtx->staInfo_lock); + + *((u32 *)buf) = maclist_index; + wrqu->data.length = maclist_index; + if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) { + hddLog(LOG1, "%s: failed to copy response to user buffer", __func__); + ret = -EFAULT; + } + kfree(buf); + + EXIT(); + return ret; +} + +int +static iw_softap_getassoc_stamacaddr(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* Usage: + mac addr will be accepted as a 6 octet mac address with each octet inputted in hex + for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33 + while using this ioctl + + Syntax: + iwpriv softap.0 disassoc_sta <6 octet mac address> + + e.g. + disassociate sta with mac addr 00:0a:f5:11:22:33 from softap + iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33 +*/ + +int +static __iw_softap_disassoc_sta(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + v_U8_t *peerMacAddr; + int ret = 0; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + /* iwpriv tool or framework calls this ioctl with + * data passed in extra (less than 16 octets); + */ + peerMacAddr = (v_U8_t *)(extra); + + hddLog(LOG1, "%s data " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(peerMacAddr)); + hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr); + EXIT(); + return 0; +} + +int +static iw_softap_disassoc_sta(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int +static __iw_softap_ap_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + WLANTL_TRANSFER_STA_TYPE statBuffer; + char *pstatbuf; + int len, ret = 0; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + memset(&statBuffer, 0, sizeof(statBuffer)); + WLANSAP_GetStatistics((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext, + &statBuffer, (v_BOOL_t)wrqu->data.flags); + + pstatbuf = kzalloc(QCSAP_MAX_WSC_IE, GFP_KERNEL); + if(NULL == pstatbuf) { + hddLog(LOG1, "unable to allocate memory"); + return -ENOMEM; + } + + len = scnprintf(pstatbuf, QCSAP_MAX_WSC_IE, + "RUF=%d RMF=%d RBF=%d " + "RUB=%d RMB=%d RBB=%d " + "TUF=%d TMF=%d TBF=%d " + "TUB=%d TMB=%d TBB=%d ", + (int)statBuffer.rxUCFcnt, (int)statBuffer.rxMCFcnt, + (int)statBuffer.rxBCFcnt, (int)statBuffer.rxUCBcnt, + (int)statBuffer.rxMCBcnt, (int)statBuffer.rxBCBcnt, + (int)statBuffer.txUCFcnt, (int)statBuffer.txMCFcnt, + (int)statBuffer.txBCFcnt, (int)statBuffer.txUCBcnt, + (int)statBuffer.txMCBcnt, (int)statBuffer.txBCBcnt); + + if (len >= QCSAP_MAX_WSC_IE) { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + kfree(pstatbuf); + return -EFAULT; + } + + strlcpy(extra, pstatbuf, len); + wrqu->data.length = len; + kfree(pstatbuf); + + EXIT(); + return 0; +} +int +static __iw_softap_ap_get_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_tx_rx_stats_t *pStats; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pStats = &pAdapter->hdd_stats.hddTxRxStats; + snprintf(extra, QCSAP_MAX_STR_LEN, + "\nTransmit" + "\ncalled %u, dropped %u, backpressured %u, queued %u" + "\n dropped BK %u, BE %u, VI %u, VO %u" + "\n classified BK %u, BE %u, VI %u, VO %u" + "\nbackpressured BK %u, BE %u, VI %u, VO %u" + "\n queued BK %u, BE %u, VI %u, VO %u" + "\nfetched %u, empty %u, lowres %u, deqerr %u" + "\ndequeued %u, depressured %u, deque-depressured %u,\ + completed %u, flushed %u" + "\n fetched BK %u, BE %u, VI %u, VO %u" + "\n dequeued BK %u, BE %u, VI %u, VO %u" + "\n depressured BK %u, BE %u, VI %u, VO %u" + "\nDeque depressured BK %u, BE %u, VI %u, VO %u" + "\n flushed BK %u, BE %u, VI %u, VO %u" + "\n\nReceive" + "\nchains %u, packets %u, dropped %u, delivered %u, refused %u" + "\n\nResetsStats" + "\n", + pStats->txXmitCalled, + pStats->txXmitDropped, + pStats->txXmitBackPressured, + pStats->txXmitQueued, + + pStats->txXmitDroppedAC[WLANTL_AC_BK], + pStats->txXmitDroppedAC[WLANTL_AC_BE], + pStats->txXmitDroppedAC[WLANTL_AC_VI], + pStats->txXmitDroppedAC[WLANTL_AC_VO], + + pStats->txXmitClassifiedAC[WLANTL_AC_BK], + pStats->txXmitClassifiedAC[WLANTL_AC_BE], + pStats->txXmitClassifiedAC[WLANTL_AC_VI], + pStats->txXmitClassifiedAC[WLANTL_AC_VO], + + pStats->txXmitBackPressuredAC[WLANTL_AC_BK], + pStats->txXmitBackPressuredAC[WLANTL_AC_BE], + pStats->txXmitBackPressuredAC[WLANTL_AC_VI], + pStats->txXmitBackPressuredAC[WLANTL_AC_VO], + + pStats->txXmitQueuedAC[WLANTL_AC_BK], + pStats->txXmitQueuedAC[WLANTL_AC_BE], + pStats->txXmitQueuedAC[WLANTL_AC_VI], + pStats->txXmitQueuedAC[WLANTL_AC_VO], + + pStats->txFetched, + pStats->txFetchEmpty, + pStats->txFetchLowResources, + pStats->txFetchDequeueError, + + pStats->txFetchDequeued, + pStats->txFetchDePressured, + pStats->txDequeDePressured, + pStats->txCompleted, + pStats->txFlushed, + + pStats->txFetchedAC[WLANTL_AC_BK], + pStats->txFetchedAC[WLANTL_AC_BE], + pStats->txFetchedAC[WLANTL_AC_VI], + pStats->txFetchedAC[WLANTL_AC_VO], + + pStats->txFetchDequeuedAC[WLANTL_AC_BK], + pStats->txFetchDequeuedAC[WLANTL_AC_BE], + pStats->txFetchDequeuedAC[WLANTL_AC_VI], + pStats->txFetchDequeuedAC[WLANTL_AC_VO], + + pStats->txFetchDePressuredAC[WLANTL_AC_BK], + pStats->txFetchDePressuredAC[WLANTL_AC_BE], + pStats->txFetchDePressuredAC[WLANTL_AC_VI], + pStats->txFetchDePressuredAC[WLANTL_AC_VO], + + pStats->txDequeDePressuredAC[WLANTL_AC_BK], + pStats->txDequeDePressuredAC[WLANTL_AC_BE], + pStats->txDequeDePressuredAC[WLANTL_AC_VI], + pStats->txDequeDePressuredAC[WLANTL_AC_VO], + + pStats->txFlushedAC[WLANTL_AC_BK], + pStats->txFlushedAC[WLANTL_AC_BE], + pStats->txFlushedAC[WLANTL_AC_VI], + pStats->txFlushedAC[WLANTL_AC_VO], + + pStats->rxChains, + pStats->rxPackets, + pStats->rxDropped, + pStats->rxDelivered, + pStats->rxRefused + ); + + wrqu->data.length = strlen(extra) + 1; + + return 0; +} + +int +static __iw_softap_ap_clear_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: clearing", __func__); + memset(&pAdapter->stats, 0, sizeof(pAdapter->stats)); + memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats)); + return 0; +} + + +int +static iw_softap_get_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + vos_ssr_protect(__func__); + ret = __iw_softap_ap_get_stats(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + return ret; +} + +int +static iw_softap_clear_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + vos_ssr_protect(__func__); + ret = __iw_softap_ap_clear_stats(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + return ret; +} + +int +static iw_softap_ap_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_ap_stats(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/** + * __iw_softap_get_three() - return three value to upper layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/out + * + * Return: execute result + */ +static int __iw_softap_get_three(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + uint32_t *value = (uint32_t *)extra; + uint32_t sub_cmd = value[0]; + int ret = 0; /* success */ + + hdd_adapter_t *padapter = WLAN_HDD_GET_PRIV_PTR(dev); + + switch (sub_cmd) { + case QCSAP_IOCTL_GET_TSF: + ret = hdd_indicate_tsf(padapter, value, 3); + break; + default: + hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd); + break; + } + return ret; +} + + +/** + * iw_softap_get_three() - return three value to upper layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/Output + * + * Return: execute result + */ +static int iw_softap_get_three(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_get_three(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +static int __iw_softap_set_channel_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int startChannel = value[0]; + int endChannel = value[1]; + int band = value[2]; + VOS_STATUS status; + int ret = 0; /* success */ + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + status = WLANSAP_SetChannelRange(hHal,startChannel,endChannel,band); + if(status != VOS_STATUS_SUCCESS) + { + hddLog( LOGE, FL("iw_softap_set_channel_range: startChannel = %d, endChannel = %d band = %d"), + startChannel,endChannel, band); + ret = -EINVAL; + } + + pHddCtx->is_dynamic_channel_range_set = 1; + + EXIT(); + return ret; +} + +static int iw_softap_set_channel_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_set_channel_range(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +int __iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + v_U32_t num_channels = 0; + v_U8_t i = 0; + v_U8_t bandStartChannel = RF_CHAN_1; + v_U8_t bandEndChannel = RF_CHAN_165; + v_U32_t temp_num_channels = 0; + hdd_adapter_t *pHostapdAdapter; + tHalHandle hHal; + v_REGDOMAIN_t domainIdCurrentSoftap; + tpChannelListInfo channel_list = (tpChannelListInfo) extra; + eCsrBand curBand = eCSR_BAND_ALL; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pHostapdAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &curBand)) + { + hddLog(LOGE,FL("not able get the current frequency band")); + return -EIO; + } + wrqu->data.length = sizeof(tChannelListInfo); + ENTER(); + + if (eCSR_BAND_24 == curBand) + { + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + } + else if (eCSR_BAND_5G == curBand) + { + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + } + + hddLog(LOG1, FL("curBand = %d, bandStartChannel = %hu, " + "bandEndChannel = %hu "), curBand, + bandStartChannel, bandEndChannel ); + + for( i = bandStartChannel; i <= bandEndChannel; i++ ) + { + if( NV_CHANNEL_ENABLE == regChannels[i].enabled ) + { + channel_list->channels[num_channels] = rfChannels[i].channelNum; + num_channels++; + } + } + + /* remove indoor channels if the domain is FCC, channels 36 - 48 */ + + temp_num_channels = num_channels; + + if(eHAL_STATUS_SUCCESS != sme_getSoftApDomain(hHal,(v_REGDOMAIN_t *) &domainIdCurrentSoftap)) + { + hddLog(LOGE,FL("Failed to get Domain ID, %d"),domainIdCurrentSoftap); + return -EIO; + } + + if(REGDOMAIN_FCC == domainIdCurrentSoftap && + pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC ) + { + for(i = 0; i < temp_num_channels; i++) + { + + if((channel_list->channels[i] > 35) && + (channel_list->channels[i] < 49)) + { + vos_mem_move(&channel_list->channels[i], + &channel_list->channels[i+1], + temp_num_channels - (i-1)); + num_channels--; + temp_num_channels--; + i--; + } + } + } + + hddLog(LOG1,FL(" number of channels %d"), num_channels); + + channel_list->num_channels = num_channels; + EXIT(); + + return 0; +} + +int iw_softap_get_channel_list(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_get_channel_list(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static +int __iw_get_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext; + VOS_STATUS status; + v_U32_t length = DOT11F_IE_RSN_MAX_LEN; + v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN]; + int ret = 0; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is not valid ",__func__); + return -EINVAL; + } + hddLog(LOG1,FL("getGEN_IE ioctl")); + // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.) + status = WLANSap_getstationIE_information(pVosContext, + &length, + genIeBytes); + + if (VOS_STATUS_SUCCESS != status) { + hddLog(LOGE, FL("failed to get sta ies")); + return -EFAULT; + } + + wrqu->data.length = length; + if (length > DOT11F_IE_RSN_MAX_LEN) { + hddLog(LOGE, + FL("invalid buffer length length:%d"), length); + return -E2BIG; + } + + vos_mem_copy(extra, genIeBytes, length); + + hddLog(LOG1, FL("RSN IE of %d bytes returned"), wrqu->data.length); + + EXIT(); + return 0; +} + +static +int iw_get_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_genie(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static +int __iw_get_WPSPBCProbeReqIEs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs; + hdd_ap_ctx_t *pHddApCtx; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + if (NULL == pHddApCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: AP context is NULL",__func__); + return -EINVAL; + } + + hddLog(LOG1,FL("get_WPSPBCProbeReqIEs ioctl")); + memset((void*)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs)); + + WPSPBCProbeReqIEs.probeReqIELen = pHddApCtx->WPSPBCProbeReq.probeReqIELen; + vos_mem_copy(&WPSPBCProbeReqIEs.probeReqIE, + pHddApCtx->WPSPBCProbeReq.probeReqIE, + WPSPBCProbeReqIEs.probeReqIELen); + vos_mem_copy(&WPSPBCProbeReqIEs.macaddr, + pHddApCtx->WPSPBCProbeReq.peerMacAddr, + sizeof(v_MACADDR_t)); + if (copy_to_user(wrqu->data.pointer, + (void *)&WPSPBCProbeReqIEs, + sizeof(WPSPBCProbeReqIEs))) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen; + hddLog(LOG1, FL("Macaddress : "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr)); + up(&pHddApCtx->semWpsPBCOverlapInd); + EXIT(); + return 0; +} + +static +int iw_get_WPSPBCProbeReqIEs(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_WPSPBCProbeReqIEs(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_set_auth_hostap() - + This function sets the auth type received from the wpa_supplicant. + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int __iw_set_auth_hostap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *pWextState; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + switch(wrqu->param.flags & IW_AUTH_INDEX) + { + case IW_AUTH_TKIP_COUNTERMEASURES: + { + if(wrqu->param.value) { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure started %d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED; + } + else { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "Counter Measure stopped=%d", wrqu->param.value); + pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED; + } + + hdd_softap_tkip_mic_fail_counter_measure(pAdapter, + wrqu->param.value); + } + break; + + default: + + hddLog(LOGW, "%s called with unsupported auth type %d", __func__, + wrqu->param.flags & IW_AUTH_INDEX); + break; + } + + EXIT(); + return 0; +} + +int iw_set_auth_hostap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_auth_hostap(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_ap_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + v_CONTEXT_t pVosContext; + hdd_context_t *pHddCtx; + hdd_ap_ctx_t *pHddApCtx; + int retval = 0; + VOS_STATUS vstatus; + struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; + v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + int key_index; + struct iw_point *encoding = &wrqu->encoding; + tCsrRoamSetKey setKey; +// tCsrRoamRemoveKey RemoveKey; + int i; + + ENTER(); + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + retval = wlan_hdd_validate_context(pHddCtx); + if (0 != retval) + { + return retval; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pVosContext is NULL",__func__); + return -EINVAL; + } + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + if (NULL == pHddApCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: AP Context is NULL",__func__); + return -EINVAL; + } + + key_index = encoding->flags & IW_ENCODE_INDEX; + + if(key_index > 0) { + + /*Convert from 1-based to 0-based keying*/ + key_index--; + } + if(!ext->key_len) { +#if 0 + /*Set the encrytion type to NONE*/ +#if 0 + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; +#endif + + RemoveKey.keyId = key_index; + if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /*Key direction for group is RX only*/ + vos_mem_copy(RemoveKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN); + } + else { + vos_mem_copy(RemoveKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN); + } + switch(ext->alg) + { + case IW_ENCODE_ALG_NONE: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + case IW_ENCODE_ALG_WEP: + RemoveKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104; + break; + case IW_ENCODE_ALG_TKIP: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + break; + case IW_ENCODE_ALG_CCMP: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + default: + RemoveKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Remove key cipher_alg:%d key_len%d *pEncryptionType :%d", + __func__,(int)ext->alg,(int)ext->key_len,RemoveKey.encType); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Peer Mac = "MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(RemoveKey.peerMac)); + ); + vstatus = WLANSAP_DelKeySta( pVosContext, &RemoveKey); + if ( vstatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "[%4d] WLANSAP_DeleteKeysSta returned ERROR status= %d", + __LINE__, vstatus ); + retval = -EINVAL; + } +#endif + return retval; + + } + + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + + setKey.keyId = key_index; + setKey.keyLength = ext->key_len; + + if(ext->key_len <= CSR_MAX_KEY_LEN) { + vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len); + } + + if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /*Key direction for group is RX only*/ + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN); + } + else { + + setKey.keyDirection = eSIR_TX_RX; + vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN); + } + if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + { + setKey.keyDirection = eSIR_TX_DEFAULT; + vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN); + } + + /*For supplicant pae role is zero*/ + setKey.paeRole = 0; + + switch(ext->alg) + { + case IW_ENCODE_ALG_NONE: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + + case IW_ENCODE_ALG_WEP: + setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104; + pHddApCtx->uPrivacy = 1; + hddLog(LOG1, "(%s) uPrivacy=%d", __func__, pHddApCtx->uPrivacy); + break; + + case IW_ENCODE_ALG_TKIP: + { + v_U8_t *pKey = &setKey.Key[0]; + + setKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + + vos_mem_zero(pKey, CSR_MAX_KEY_LEN); + + /*Supplicant sends the 32bytes key in this order + + |--------------|----------|----------| + | Tk1 |TX-MIC | RX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + + */ + /*Sme expects the 32 bytes key to be in the below order + + |--------------|----------|----------| + | Tk1 |RX-MIC | TX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + */ + /* Copy the Temporal Key 1 (TK1) */ + vos_mem_copy(pKey,ext->key,16); + + /*Copy the rx mic first*/ + vos_mem_copy(&pKey[16],&ext->key[24],8); + + /*Copy the tx mic */ + vos_mem_copy(&pKey[24],&ext->key[16],8); + + } + break; + + case IW_ENCODE_ALG_CCMP: + setKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + + default: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s:EncryptionType:%d key_len:%d, KeyId:%d"), __func__, setKey.encType, setKey.keyLength, + setKey.keyId); + for(i=0; i< ext->key_len; i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%02x"), setKey.Key[i]); + + vstatus = WLANSAP_SetKeySta( pVosContext, &setKey); + if ( vstatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANSAP_SetKeySta returned ERROR status= %d", __LINE__, vstatus ); + retval = -EINVAL; + } + + EXIT(); + return retval; +} + +static int iw_set_ap_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_ap_encodeext(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_ap_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ +#if 0 + hdd_adapter_t *pAdapter = (netdev_priv(dev)); + struct iw_mlme *mlme = (struct iw_mlme *)extra; + + ENTER(); + + //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED + switch (mlme->cmd) { + case IW_MLME_DISASSOC: + case IW_MLME_DEAUTH: + hddLog(LOG1, "Station disassociate"); + if( pAdapter->conn_info.connState == eConnectionState_Associated ) + { + eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED; + + if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE ) + reason = eCSR_DISCONNECT_REASON_MIC_ERROR; + + status = sme_RoamDisconnect( pAdapter->hHal,pAdapter->sessionId, reason); + + //clear all the reason codes + if (status != 0) + { + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", __func__, (int)mlme->cmd, (int)status); + } + + netif_stop_queue(dev); + netif_carrier_off(dev); + } + else + { + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd); + } + default: + hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd); + return -EINVAL; + }//end of switch + EXIT(); +#endif + return 0; +// return status; +} + +static int iw_set_ap_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_ap_mlme(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_ap_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + v_U32_t status = 0; + + status = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu); + + return status; +} + +static int iw_get_ap_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_ap_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + v_U32_t status = 0; + + status = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu); + + return status; +} + +static int iw_get_ap_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_ap_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + v_U32_t status = FALSE, channel = 0, freq = 0; + hdd_adapter_t *pHostapdAdapter; + tHalHandle hHal; + hdd_hostapd_state_t *pHostapdState; + hdd_ap_ctx_t *pHddApCtx; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + if (NULL == pHostapdState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pHostapdState is NULL",__func__); + return -EINVAL; + } + hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + if (NULL == pHddApCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: AP context is NULL",__func__); + return -EINVAL; + } + if(pHostapdState->bssState == BSS_STOP ) + { + if (ccmCfgGetInt(hHal, WNI_CFG_CURRENT_CHANNEL, &channel) + != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to get WNI_CFG_CURRENT_CHANNEL from cfg")); + return -EIO; + } + else + { + status = hdd_wlan_get_freq(channel, &freq); + if( TRUE == status) + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = freq; + fwrq->e = MHZ; + } + } + } + else + { + channel = pHddApCtx->operatingChannel; + status = hdd_wlan_get_freq(channel, &freq); + if( TRUE == status) + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = freq; + fwrq->e = MHZ; + } + } + + EXIT(); + return 0; +} + +static int iw_get_ap_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_ap_freq(dev, info, fwrq, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int status = 0; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + wrqu->mode = IW_MODE_MASTER; + + EXIT(); + return status; +} + +static int iw_get_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_mode(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int __iw_softap_stopbss(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter; + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx = NULL; + + ENTER(); + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) { + return status; + } + + if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) + { + if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext) ) ) + { + hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("ERROR: HDD vos wait for single_event failed!!")); + VOS_ASSERT(0); + } + } + clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, pHostapdAdapter->device_mode); + } + EXIT(); + return (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY; +} + +static int iw_softap_stopbss(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_stopbss(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_softap_version(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hdd_wlan_get_version(pHostapdAdapter, wrqu, extra); + EXIT(); + return 0; +} + +static int iw_softap_version(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_version(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, v_U8_t *pBuf, int buf_len) +{ + v_U8_t i; + int len = 0; + const char sta_info_header[] = "staId staAddress\n"; + v_CONTEXT_t pVosContext; + hdd_context_t *pHddCtx; + ptSapContext pSapCtx = NULL; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + { + return VOS_STATUS_E_FAULT; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: VOS context is not valid",__func__); + return VOS_STATUS_E_FAULT; + } + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + + len = snprintf(pBuf, buf_len, sta_info_header); + if (len >= buf_len) { + hddLog(LOGE, FL("Insufficient buffer:%d, %d"), buf_len, len); + return -E2BIG; + } + pBuf += len; + buf_len -= len; + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if(pSapCtx->aStaInfo[i].isUsed) + { + len = scnprintf(pBuf, buf_len, "%5d .%02x:%02x:%02x:%02x:%02x:%02x\n", + pSapCtx->aStaInfo[i].ucSTAId, + pSapCtx->aStaInfo[i].macAddrSTA.bytes[0], + pSapCtx->aStaInfo[i].macAddrSTA.bytes[1], + pSapCtx->aStaInfo[i].macAddrSTA.bytes[2], + pSapCtx->aStaInfo[i].macAddrSTA.bytes[3], + pSapCtx->aStaInfo[i].macAddrSTA.bytes[4], + pSapCtx->aStaInfo[i].macAddrSTA.bytes[5]); + if (len >= buf_len) { + hddLog(LOGE, FL("Insufficient buffer:%d, %d"), buf_len, len); + return -E2BIG; + } + pBuf += len; + buf_len -= len; + } + if(WE_GET_STA_INFO_SIZE > buf_len) + { + break; + } + } + EXIT(); + return 0; +} + +static int __iw_softap_get_sta_info(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + int ret; + ENTER(); + ret = hdd_softap_get_sta_info(pHostapdAdapter, extra, WE_SAP_MAX_STA_INFO); + if (ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!",__func__); + return ret; + } + wrqu->data.length = strlen(extra); + EXIT(); + return 0; +} + +static int iw_softap_get_sta_info(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_softap_get_sta_info(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_ap_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext; + eHalStatus halStatus= eHAL_STATUS_SUCCESS; + u_int8_t *genie = (u_int8_t *)extra; + int ret = 0; + + ENTER(); + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pVosContext = pHddCtx->pvosContext; + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Context is NULL",__func__); + return -EINVAL; + } + if(!wrqu->data.length) + { + EXIT(); + return 0; + } + + if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WPARSN Ie input length is more than max[%d]", __func__, + wrqu->data.length); + return -EINVAL; + } + + switch (genie[0]) + { + case DOT11F_EID_WPA: + case DOT11F_EID_RSN: + if((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) + { + hdd_softap_Deregister_BC_STA(pHostapdAdapter); + hdd_softap_Register_BC_STA(pHostapdAdapter, 1); + } + (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1; + halStatus = WLANSAP_Set_WPARSNIes(pVosContext, genie, wrqu->data.length); + break; + + default: + hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, genie[0]); + halStatus = 0; + } + + EXIT(); + return halStatus; +} + +static int iw_set_ap_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_ap_genie(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static VOS_STATUS wlan_hdd_get_classAstats_for_station(hdd_adapter_t *pAdapter, u8 staid) +{ + eHalStatus hstatus; + long lrc; + struct statsContext context; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), + eCSR_HDD, + SME_GLOBAL_CLASSA_STATS, + hdd_GetClassA_statisticsCB, + 0, // not periodic + FALSE, //non-cached results + staid, + &context); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics for link speed", + __func__); + } + else + { + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while retrieving link speed", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + return VOS_STATUS_SUCCESS; +} + +int __iw_get_softap_linkspeed(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) + +{ + hdd_adapter_t *pHostapdAdapter; + hdd_context_t *pHddCtx; + char *pLinkSpeed = (char*)extra; + char *pmacAddress; + v_U32_t link_speed; + unsigned short staId; + int len = sizeof(v_U32_t)+1; + v_BYTE_t macAddress[VOS_MAC_ADDR_SIZE]; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + int rc, valid; + + ENTER(); + + pHostapdAdapter = (netdev_priv(dev)); + if (NULL == pHostapdAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + valid = wlan_hdd_validate_context(pHddCtx); + if (0 != valid) + { + return valid; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s wrqu->data.length= %d", __func__, wrqu->data.length); + + if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) + { + pmacAddress = kmalloc(MAC_ADDRESS_STR_LEN, GFP_KERNEL); + if (NULL == pmacAddress) { + hddLog(LOG1, "unable to allocate memory"); + return -ENOMEM; + } + if (copy_from_user((void *)pmacAddress, + wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) + { + hddLog(LOG1, "%s: failed to copy data to user buffer", __func__); + kfree(pmacAddress); + return -EFAULT; + } + pmacAddress[MAC_ADDRESS_STR_LEN-1] = '\0'; + + status = hdd_string_to_hex (pmacAddress, MAC_ADDRESS_STR_LEN, macAddress ); + kfree(pmacAddress); + + if (!VOS_IS_STATUS_SUCCESS(status )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("String to Hex conversion Failed")); + } + } + /* If no mac address is passed and/or its length is less than 17, + * link speed for first connected client will be returned. + */ + if (wrqu->data.length < 17 || !VOS_IS_STATUS_SUCCESS(status )) + { + status = hdd_softap_GetConnectedStaId(pHostapdAdapter, (void *)(&staId)); + } + else + { + status = hdd_softap_GetStaId(pHostapdAdapter, + (v_MACADDR_t *)macAddress, (void *)(&staId)); + } + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("ERROR: HDD Failed to find sta id!!")); + link_speed = 0; + } + else + { + status = wlan_hdd_get_classAstats_for_station(pHostapdAdapter , staId); + + if (!VOS_IS_STATUS_SUCCESS(status )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics")); + return -EINVAL; + } + + WLANTL_GetSTALinkCapacity(pHddCtx->pvosContext, + staId, &link_speed); + + link_speed = link_speed / 10; + + if (0 == link_speed) + { + /* The linkspeed returned by HAL is in units of 500kbps. + * converting it to mbps. + * This is required to support legacy firmware which does + * not return link capacity. + */ + link_speed =(int)pHostapdAdapter->hdd_stats.ClassA_stat.tx_rate/2; + } + } + + wrqu->data.length = len; + rc = snprintf(pLinkSpeed, len, "%u", link_speed); + + if ((rc < 0) || (rc >= len)) + { + // encoding or length error? + hddLog(VOS_TRACE_LEVEL_ERROR,FL( "Unable to encode link speed")); + return -EIO; + } + + EXIT(); + return 0; +} + +int iw_get_softap_linkspeed(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static const iw_handler hostapd_handler[] = +{ + (iw_handler) NULL, /* SIOCSIWCOMMIT */ + (iw_handler) NULL, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) NULL, /* SIOCSIWFREQ */ + (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */ + (iw_handler) NULL, /* SIOCSIWMODE */ + (iw_handler) iw_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) NULL, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + (iw_handler) NULL, /* SIOCSIWSPY */ + (iw_handler) NULL, /* SIOCGIWSPY */ + (iw_handler) NULL, /* SIOCSIWTHRSPY */ + (iw_handler) NULL, /* SIOCGIWTHRSPY */ + (iw_handler) NULL, /* SIOCSIWAP */ + (iw_handler) NULL, /* SIOCGIWAP */ + (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ + (iw_handler) NULL, /* SIOCSIWSCAN */ + (iw_handler) NULL, /* SIOCGIWSCAN */ + (iw_handler) NULL, /* SIOCSIWESSID */ + (iw_handler) NULL, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) NULL, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWRATE */ + (iw_handler) NULL, /* SIOCGIWRATE */ + (iw_handler) NULL, /* SIOCSIWRTS */ + (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */ + (iw_handler) NULL, /* SIOCSIWFRAG */ + (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */ + (iw_handler) NULL, /* SIOCSIWTXPOW */ + (iw_handler) NULL, /* SIOCGIWTXPOW */ + (iw_handler) NULL, /* SIOCSIWRETRY */ + (iw_handler) NULL, /* SIOCGIWRETRY */ + (iw_handler) NULL, /* SIOCSIWENCODE */ + (iw_handler) NULL, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */ + (iw_handler) NULL, /* SIOCGIWGENIE */ + (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */ + (iw_handler) NULL, /* SIOCGIWAUTH */ + (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */ + (iw_handler) NULL, /* SIOCGIWENCODEEXT */ + (iw_handler) NULL, /* SIOCSIWPMKSA */ +}; + +/* + * Note that the following ioctls were defined with semantics which + * cannot be handled by the "iwpriv" userspace application and hence + * they are not included in the hostapd_private_args array + * QCSAP_IOCTL_ASSOC_STA_MACADDR + */ + +static const struct iw_priv_args hostapd_private_args[] = { + { QCSAP_IOCTL_SETPARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam" }, + { QCSAP_IOCTL_SETPARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" }, + { QCSAP_PARAM_GET_FRAME_LOGS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "getFrameLogs" }, + { QCSAP_PARAM_MAX_ASSOC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMaxAssoc" }, + { QCSAP_PARAM_HIDE_SSID, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID" }, + { QCSAP_PARAM_SET_MC_RATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate" }, + { QCSAP_PARAM_SET_PROXIMITY, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setProximity" }, + { QCSAP_PARAM_CAP_TSF, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "cap_tsf" }, + { QCSAP_PARAM_SET_WOWL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wowl" }, + { QCSAP_IOCTL_GETPARAM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam" }, + { QCSAP_IOCTL_GETPARAM, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" }, + { QCSAP_PARAM_MAX_ASSOC, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc" }, + { QCSAP_PARAM_GET_WLAN_DBG, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" }, + { QCSAP_PARAM_AUTO_CHANNEL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" }, + { QCSAP_PARAM_SET_AUTO_CHANNEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" }, + { QCSAP_PARAM_CLR_ACL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "setClearAcl" }, + { QCSAP_PARAM_ACL_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode" }, + { QCSAP_IOCTL_GET_STAWPAIE, + 0, IW_PRIV_TYPE_BYTE | DOT11F_IE_RSN_MAX_LEN, "get_staWPAIE" }, + { QCSAP_IOCTL_STOPBSS, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0, "stopbss" }, + { QCSAP_IOCTL_VERSION, 0, + IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "version" }, + { QCSAP_IOCTL_GET_STA_INFO, 0, + IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info" }, + { QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES, + IW_PRIV_TYPE_BYTE | sizeof(sQcSapreq_WPSPBCProbeReqIES_t) | IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs" }, + { QCSAP_IOCTL_GET_CHANNEL, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" }, + { QCSAP_IOCTL_DISASSOC_STA, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6 , 0, "disassoc_sta" }, + { QCSAP_IOCTL_AP_STATS, 0, + IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE, "ap_stats" }, + /* handlers for main ioctl */ + { QCSAP_IOCTL_PRIV_SET_NONE_GET_THREE_INT, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, "" }, +#ifdef WLAN_FEATURE_TSF + { QCSAP_IOCTL_GET_TSF, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + "get_tsf" }, +#endif + { QCSAP_IOCTL_GET_STATS, 0, + IW_PRIV_TYPE_CHAR | QCSAP_MAX_STR_LEN, "getStats"}, + { QCSAP_IOCTL_CLR_STATS, 0, 0, "clearStats" }, + { QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED, + IW_PRIV_TYPE_CHAR | 18, + IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" }, + + { QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "" }, + /* handlers for sub-ioctl */ + { WE_SET_WLAN_DBG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setwlandbg" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_LOG_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dump" }, + { WE_P2P_NOA_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "SetP2pPs" }, + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_CREDENTIAL, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccCrdnl" }, + + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_PARAMS, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccConfig" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_MODIFY_ACL, + IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, + 0, + "modify_acl" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_GET_CHANNEL_LIST, + 0, + IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo), + "getChannelList" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_TX_POWER, + IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxPower" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_MAX_TX_POWER, + IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower" }, + + { QCSAP_IOCTL_DATAPATH_SNAP_SHOT, + IW_PRIV_TYPE_NONE | IW_PRIV_TYPE_NONE, + 0, + "dataSnapshot" }, + + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_TRAFFIC_MONITOR, + IW_PRIV_TYPE_INT| IW_PRIV_SIZE_FIXED | 1, + 0, + "setTrafficMon" }, + /* handlers for main ioctl */ + { QCSAP_IOCTL_SET_CHAR_GET_NONE, + IW_PRIV_TYPE_CHAR| 512, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_WOWL_ADD_PTRN, + IW_PRIV_TYPE_CHAR| 512, + 0, + "wowlAddPtrn" }, + + { WE_WOWL_DEL_PTRN, + IW_PRIV_TYPE_CHAR| 512, + 0, + "wowlDelPtrn" }, +}; + +static const iw_handler hostapd_private[] = { + [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam, //set priv ioctl + [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam, //get priv ioctl + [QCSAP_IOCTL_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = + iw_softap_setchar_getnone, + [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie, //get station genIE + [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss, // stop bss + [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version, // get driver version + [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] = iw_get_WPSPBCProbeReqIEs, + [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] = iw_softap_getchannel, + [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] = iw_softap_getassoc_stamacaddr, + [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] = iw_softap_disassoc_sta, + [QCSAP_IOCTL_AP_STATS - SIOCIWFIRSTPRIV] = iw_softap_ap_stats, + [QCSAP_IOCTL_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] = iw_softap_get_three, + [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone, + [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone, + [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] = iw_softap_set_channel_range, + [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] = iw_softap_modify_acl, + [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] = iw_softap_get_channel_list, + [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] = iw_softap_get_sta_info, + [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_softap_linkspeed, + [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_tx_power, + [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] = iw_softap_set_max_tx_power, + [QCSAP_IOCTL_DATAPATH_SNAP_SHOT - SIOCIWFIRSTPRIV] = iw_display_data_path_snapshot, + [QCSAP_IOCTL_SET_TRAFFIC_MONITOR - SIOCIWFIRSTPRIV] = iw_softap_set_trafficmonitor, + [QCSAP_IOCTL_GET_STATS - SIOCIWFIRSTPRIV] = iw_softap_get_stats, + [QCSAP_IOCTL_CLR_STATS - SIOCIWFIRSTPRIV] = iw_softap_clear_stats, +}; +const struct iw_handler_def hostapd_handler_def = { + .num_standard = sizeof(hostapd_handler) / sizeof(hostapd_handler[0]), + .num_private = sizeof(hostapd_private) / sizeof(hostapd_private[0]), + .num_private_args = sizeof(hostapd_private_args) / sizeof(hostapd_private_args[0]), + .standard = (iw_handler *)hostapd_handler, + .private = (iw_handler *)hostapd_private, + .private_args = hostapd_private_args, + .get_wireless_stats = NULL, +}; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) +struct net_device_ops net_ops_struct = { + .ndo_open = hdd_hostapd_open, + .ndo_stop = hdd_hostapd_stop, + .ndo_uninit = hdd_hostapd_uninit, + .ndo_start_xmit = hdd_softap_hard_start_xmit, + .ndo_tx_timeout = hdd_softap_tx_timeout, + .ndo_get_stats = hdd_softap_stats, + .ndo_set_mac_address = hdd_hostapd_set_mac_address, + .ndo_do_ioctl = hdd_hostapd_ioctl, + .ndo_change_mtu = hdd_hostapd_change_mtu, + .ndo_select_queue = hdd_hostapd_select_queue, + }; +#endif + +int hdd_set_hostapd(hdd_adapter_t *pAdapter) +{ + return VOS_STATUS_SUCCESS; +} + +void hdd_set_ap_ops( struct net_device *pWlanHostapdDev ) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) + pWlanHostapdDev->netdev_ops = &net_ops_struct; +#else + pWlanHostapdDev->open = hdd_hostapd_open; + pWlanHostapdDev->stop = hdd_hostapd_stop; + pWlanHostapdDev->uninit = hdd_hostapd_uninit; + pWlanHostapdDev->hard_start_xmit = hdd_softap_hard_start_xmit; + pWlanHostapdDev->tx_timeout = hdd_softap_tx_timeout; + pWlanHostapdDev->get_stats = hdd_softap_stats; + pWlanHostapdDev->set_mac_address = hdd_hostapd_set_mac_address; + pWlanHostapdDev->do_ioctl = hdd_hostapd_ioctl; +#endif +} + +VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter, bool re_init) +{ + hdd_hostapd_state_t * phostapdBuf; +#ifdef DHCP_SERVER_OFFLOAD + hdd_dhcp_state_t *dhcp_status; +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + hdd_mdns_state_t *mdns_status; +#endif /* MDNS_OFFLOAD */ + struct net_device *dev = pAdapter->dev; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_STATUS status; + hdd_config_t *ini_cfg; +#ifdef FEATURE_WLAN_CH_AVOID + v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS]; + v_U16_t unsafeChannelCount; +#endif /* FEATURE_WLAN_CH_AVOID */ + + if (pHddCtx->isLogpInProgress && !re_init) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:LOGP in Progress. Ignore!!!",__func__); + status = VOS_STATUS_E_FAILURE; + } + + ENTER(); + +#ifdef SAP_AUTH_OFFLOAD + if (pHddCtx->cfg_ini->enable_sap_auth_offload) + { + if (!hdd_set_sap_auth_offload(pAdapter, TRUE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("SAP AUTH OFFLOAD is not enabled successfully, Don't start SAP")); + return VOS_STATUS_E_FAILURE; + } + } +#endif + + // Allocate the Wireless Extensions state structure + phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR( pAdapter ); +#ifdef DHCP_SERVER_OFFLOAD + dhcp_status = &pAdapter->dhcp_status; +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + mdns_status = &pAdapter->mdns_status; +#endif /* MDNS_OFFLOAD */ + + spin_lock_init(&pAdapter->sta_hash_lock); + pAdapter->is_sta_id_hash_initialized = VOS_FALSE; + + sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode); + +#ifdef FEATURE_WLAN_CH_AVOID + /* Get unsafe cahnnel list from cached location */ + wcnss_get_wlan_unsafe_channel(unsafeChannelList, + sizeof(unsafeChannelList), + &unsafeChannelCount); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : Unsafe Channel count %d", + __func__, unsafeChannelCount); + hdd_hostapd_update_unsafe_channel_list(pHddCtx, + unsafeChannelList, + unsafeChannelCount); +#endif /* FEATURE_WLAN_CH_AVOID */ + + // Zero the memory. This zeros the profile structure. + memset(phostapdBuf, 0,sizeof(hdd_hostapd_state_t)); +#ifdef DHCP_SERVER_OFFLOAD + memset(dhcp_status, 0,sizeof(*dhcp_status)); +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + memset(mdns_status, 0,sizeof(*mdns_status)); +#endif /* MDNS_OFFLOAD */ + + // Set up the pointer to the Wireless Extensions state structure + // NOP + status = hdd_set_hostapd(pAdapter); + if(!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_hostapd failed!!")); + return status; + } + + status = vos_event_init(&phostapdBuf->vosEvent); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!")); + return status; + } +#ifdef DHCP_SERVER_OFFLOAD + status = vos_event_init(&dhcp_status->vos_event); + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: Hostapd HDD vos event init failed!!")); + return status; + } +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + status = vos_event_init(&mdns_status->vos_event); + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Hostapd HDD vos event init failed!!")); + return status; + } +#endif /* MDNS_OFFLOAD */ + + sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1); + + // Register as a wireless device + dev->wireless_handlers = (struct iw_handler_def *)& hostapd_handler_def; + + //Initialize the data path module + status = hdd_softap_init_tx_rx(pAdapter, re_init); + if ( !VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_softap_init_tx_rx failed", __func__); + } + + status = hdd_wmm_adapter_init( pAdapter ); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "hdd_wmm_adapter_init() failed with status code %08d [x%08x]", + status, status ); + goto error_wmm_init; + } + + set_bit(WMM_INIT_DONE, &pAdapter->event_flags); + + ini_cfg = pHddCtx->cfg_ini; + if (re_init && ini_cfg) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("start_ch: %d end_ch:%d op_band:%d"), + ini_cfg->apStartChannelNum, ini_cfg->apEndChannelNum, + ini_cfg->apOperatingBand); + WLANSAP_SetChannelRange(WLAN_HDD_GET_HAL_CTX(pAdapter), + ini_cfg->apStartChannelNum, + ini_cfg->apEndChannelNum, + ini_cfg->apOperatingBand); + } + + return status; + +error_wmm_init: + hdd_softap_deinit_tx_rx(pAdapter, re_init); + EXIT(); + return status; +} + +hdd_adapter_t* hdd_wlan_create_ap_dev( hdd_context_t *pHddCtx, tSirMacAddr macAddr, tANI_U8 *iface_name ) +{ + struct net_device *pWlanHostapdDev = NULL; + hdd_adapter_t *pHostapdAdapter = NULL; + v_CONTEXT_t pVosContext= NULL; + + pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) + NET_NAME_UNKNOWN, +#endif + ether_setup, NUM_TX_QUEUES); + if (pWlanHostapdDev != NULL) + { + pHostapdAdapter = netdev_priv(pWlanHostapdDev); + + //Init the net_device structure + ether_setup(pWlanHostapdDev); + + //Initialize the adapter context to zeros. + vos_mem_zero(pHostapdAdapter, sizeof( hdd_adapter_t )); + pHostapdAdapter->dev = pWlanHostapdDev; + pHostapdAdapter->pHddCtx = pHddCtx; + pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC; + + //Get the Global VOSS context. + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + //Save the adapter context in global context for future. + ((VosContextType*)(pVosContext))->pHDDSoftAPContext = (v_VOID_t*)pHostapdAdapter; + + //Init the net_device structure + strlcpy(pWlanHostapdDev->name, (const char *)iface_name, IFNAMSIZ); + + hdd_set_ap_ops( pHostapdAdapter->dev ); + + pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT; + pWlanHostapdDev->mtu = HDD_DEFAULT_MTU; + + vos_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,sizeof(tSirMacAddr)); + vos_mem_copy(pHostapdAdapter->macAddressCurrent.bytes, (void *)macAddr, sizeof(tSirMacAddr)); + + pWlanHostapdDev->destructor = free_netdev; + pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev ; + pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy; + pHostapdAdapter->wdev.netdev = pWlanHostapdDev; + + SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev); + } + return pHostapdAdapter; +} + +VOS_STATUS hdd_register_hostapd( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held ) +{ + struct net_device *dev = pAdapter->dev; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + if( rtnl_lock_held ) + { + if (strnchr(dev->name, strlen(dev->name), '%')) { + if( dev_alloc_name(dev, dev->name) < 0 ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s:Failed:dev_alloc_name", __func__); + return VOS_STATUS_E_FAILURE; + } + } + if (register_netdevice(dev)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s:Failed:register_netdevice", __func__); + return VOS_STATUS_E_FAILURE; + } + } + else + { + if (register_netdev(dev)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed:register_netdev", __func__); + return VOS_STATUS_E_FAILURE; + } + } + set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags); + + EXIT(); + return status; +} + +VOS_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, tANI_U8 rtnl_held) +{ + ENTER(); + + hdd_softap_deinit_tx_rx(pAdapter, false); + + /* if we are being called during driver unload, then the dev has already + been invalidated. if we are being called at other times, then we can + detatch the wireless device handlers */ + if (pAdapter->dev) + { + if (TRUE == rtnl_held) + { + pAdapter->dev->wireless_handlers = NULL; + } + else + { + rtnl_lock(); + pAdapter->dev->wireless_handlers = NULL; + rtnl_unlock(); + } + } + EXIT(); + return 0; +} + +/** + * hdd_sap_indicate_disconnect_for_sta() - Indicate disconnect indication + * to supplicant, if there any clients connected to SAP interface. + * @adapter: sap adapter context + * + * Return: nothing + */ +void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter) +{ + tSap_Event sap_event; + int staId; + hdd_context_t *hdd_ctx; + v_CONTEXT_t vos_ctx; + ptSapContext sap_ctx; + + ENTER(); + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (NULL == hdd_ctx || NULL == hdd_ctx->cfg_ini) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: HDD context is Null", __func__); + return; + } + + vos_ctx = hdd_ctx->pvosContext; + if (NULL == vos_ctx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: VOS context is not valid",__func__); + return; + } + + sap_ctx = VOS_GET_SAP_CB(vos_ctx); + if (!sap_ctx) { + hddLog(LOGE, FL("invalid sap context")); + return; + } + + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) { + if (sap_ctx->aStaInfo[staId].isUsed) { + hddLog(LOG1, FL("staId: %d isUsed: %d %p"), + staId, sap_ctx->aStaInfo[staId].isUsed, + sap_ctx); + + if (vos_is_macaddr_broadcast( + &sap_ctx->aStaInfo[staId].macAddrSTA)) + continue; + + sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; + vos_mem_copy( + &sap_event.sapevt. + sapStationDisassocCompleteEvent.staMac, + &sap_ctx->aStaInfo[staId].macAddrSTA, + sizeof(v_MACADDR_t)); + sap_event.sapevt.sapStationDisassocCompleteEvent. + reason = + eSAP_MAC_INITATED_DISASSOC; + sap_event.sapevt.sapStationDisassocCompleteEvent. + statusCode = + eSIR_SME_RESOURCES_UNAVAILABLE; + hdd_hostapd_SAPEventCB(&sap_event, + sap_ctx->pUsrContext); + } + } + + clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags); + + EXIT(); +} + +/** + * hdd_sap_destroy_timers() - Destroy sap timers + * @adapter: sap adapter context + * + * Return: nothing + */ +void hdd_sap_destroy_timers(hdd_adapter_t *adapter) +{ + hdd_context_t *hdd_ctx; + v_CONTEXT_t vos_ctx; + ptSapContext sap_ctx; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + + ENTER(); + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + if (NULL == hdd_ctx || NULL == hdd_ctx->cfg_ini) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: HDD context is Null", __func__); + return; + } + + vos_ctx = hdd_ctx->pvosContext; + if (NULL == vos_ctx) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: VOS context is not valid",__func__); + return; + } + + sap_ctx = VOS_GET_SAP_CB(vos_ctx); + if (!sap_ctx) { + hddLog(LOGE, FL("invalid sap context")); + return; + } + + if (VOS_TIMER_STATE_RUNNING == sap_ctx->sap_HT2040_timer.state) { + status = vos_timer_stop(&sap_ctx->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(status)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + + status = vos_timer_destroy(&sap_ctx->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(status)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Destroy HT20/40 timer")); + +} + +/** + * hdd_force_scc_restart_sap - restart sap to forcer SCC + * @adapter: hdd ap adapter + * + * hdd_force_scc_restart_sap will choose station channel and will + * schedule work to restart the sap. + * + * Return - none + */ +void hdd_force_scc_restart_sap(hdd_adapter_t *adapter, + hdd_context_t *hdd_ctx, tANI_U8 channelId) +{ + if (!(adapter && (WLAN_HDD_SOFTAP == adapter->device_mode))) { + return; + } + + hddLog(LOG1, FL("Current operation channel %d"), + adapter->sessionCtx.ap.operatingChannel); + hddLog(LOG1, FL("STA channel is %d"), + channelId); + + vos_flush_work( + &hdd_ctx->sap_start_work); + + hddLog(LOGE, + FL("Restarting SAP for force SCC ")); + + adapter->sessionCtx.ap.sapConfig.channel = channelId; + + if (hdd_ctx->cfg_ini->sap_internal_restart) { + netif_tx_disable(adapter->dev); + schedule_work(&hdd_ctx->sap_start_work); + } else { + hdd_hostapd_stop(adapter->dev); + } + return; +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c new file mode 100644 index 000000000000..6dc22da0ec2a --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_main.c @@ -0,0 +1,17039 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*======================================================================== + + \file wlan_hdd_main.c + + \brief WLAN Host Device Driver implementation + + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/5/09 Shailender Created module. + 02/24/10 Sudhir.S.Kohalli Added to support param for SoftAP module + 06/03/10 js - Added support to hostapd driven deauth/disassoc/mic failure + ==========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +//#include +#include +#include +#include +#include +#include +#ifdef ANI_BUS_TYPE_PLATFORM +#include +#endif //ANI_BUS_TYPE_PLATFORM +#ifdef ANI_BUS_TYPE_PCI +#include "wcnss_wlan.h" +#endif /* ANI_BUS_TYPE_PCI */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WLAN_BTAMP_FEATURE +#include +#include +#endif // WLAN_BTAMP_FEATURE +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include +#include +#include +#include +#include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_p2p.h" +#include +int wlan_hdd_ftm_start(hdd_context_t *pAdapter); +#include "sapApi.h" +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#include +#else +#include +#endif +#include +#include +#include "cfgApi.h" +#include "wlan_hdd_dev_pwr.h" +#ifdef WLAN_BTAMP_FEATURE +#include "bap_hdd_misc.h" +#endif +#include "wlan_qct_pal_trace.h" +#include "qwlan_version.h" +#include "wlan_qct_wda.h" +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif +#include "wlan_hdd_debugfs.h" +#include "sapInternal.h" + +#ifdef MODULE +#define WLAN_MODULE_NAME module_name(THIS_MODULE) +#else +#define WLAN_MODULE_NAME "wlan" +#endif + +#ifdef TIMER_MANAGER +#define TIMER_MANAGER_STR " +TIMER_MANAGER" +#else +#define TIMER_MANAGER_STR "" +#endif + +#ifdef MEMORY_DEBUG +#define MEMORY_DEBUG_STR " +MEMORY_DEBUG" +#else +#define MEMORY_DEBUG_STR "" +#endif +#define MAX_WAIT_FOR_ROC_COMPLETION 3 +/* the Android framework expects this param even though we don't use it */ +#define BUF_LEN 20 +static char fwpath_buffer[BUF_LEN]; +static struct kparam_string fwpath = { + .string = fwpath_buffer, + .maxlen = BUF_LEN, +}; + +static char *country_code; +static int enable_11d = -1; +static int enable_dfs_chan_scan = -1; +static int gbcnMissRate = -1; + +#ifndef MODULE +static int wlan_hdd_inited; +#endif + +/* + * spinlock for synchronizing asynchronous request/response + * (full description of use in wlan_hdd_main.h) + */ +DEFINE_SPINLOCK(hdd_context_lock); + +/* + * The rate at which the driver sends RESTART event to supplicant + * once the function 'vos_wlanRestart()' is called + * + */ +#define WLAN_HDD_RESTART_RETRY_DELAY_MS 5000 /* 5 second */ +#define WLAN_HDD_RESTART_RETRY_MAX_CNT 5 /* 5 retries */ + +/* + * Size of Driver command strings from upper layer + */ +#define SIZE_OF_SETROAMMODE 11 /* size of SETROAMMODE */ +#define SIZE_OF_GETROAMMODE 11 /* size of GETROAMMODE */ + +#ifdef WLAN_FEATURE_RMC +/* + * Ibss prop IE from command will be of size: + * size = sizeof(oui) + sizeof(oui_data) + 1(Element ID) + 1(EID Length) + * OUI_DATA should be at least 3 bytes long + */ +#define WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH (3) +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +#define TID_MIN_VALUE 0 +#define TID_MAX_VALUE 15 +static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid, + tAniTrafStrmMetrics* pTsmMetrics); +static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue, + tCsrEseBeaconReq *pEseBcnReq); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/* + * Maximum buffer size used for returning the data back to user space + */ +#define WLAN_MAX_BUF_SIZE 1024 +#define WLAN_PRIV_DATA_MAX_LEN 8192 + +/* + * When ever we need to print IBSSPEERINFOALL for morethan 16 STA + * we will split the printing. + */ +#define NUM_OF_STA_DATA_TO_PRINT 16 + +#ifdef WLAN_FEATURE_RMC +#define WLAN_NLINK_CESIUM 30 +#endif + +//wait time for beacon miss rate. +#define BCN_MISS_RATE_TIME 500 + +/* + * Android DRIVER command structures + */ +struct android_wifi_reassoc_params { + unsigned char bssid[18]; + int channel; +}; + +static vos_wake_lock_t wlan_wake_lock; + +/* set when SSR is needed after unload */ +static e_hdd_ssr_required isSsrRequired = HDD_SSR_NOT_REQUIRED; + +//internal function declaration +static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx); +static void wlan_hdd_restart_init(hdd_context_t *pHddCtx); +static void wlan_hdd_restart_deinit(hdd_context_t *pHddCtx); + +#ifdef WLAN_FEATURE_RMC +static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo); + +static int hdd_open_cesium_nl_sock(void); +static void hdd_close_cesium_nl_sock(void); +static struct sock *cesium_nl_srv_sock; +static v_U16_t cesium_pid; + +static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue, + tANI_U8 *tx_fail_count, + tANI_U16 *pid); + +static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg); + +#endif /* WLAN_FEATURE_RMC */ +void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback); +void hdd_set_wlan_suspend_mode(bool suspend); + +v_U16_t hdd_select_queue(struct net_device *dev, + struct sk_buff *skb +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)) + , void *accel_priv +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + , select_queue_fallback_t fallback +#endif +); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +static void hdd_set_multicast_list(struct net_device *dev); +#endif + +void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand); +static VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels); +static VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, + tANI_U8 *pChannel, tANI_U8 *pDwellTime, + tANI_U8 **pBuf, tANI_U8 *pBufLen); +static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue, + tANI_U8 *pTargetApBssid, tANI_U8 *pChannel); +#endif + +/* Store WLAN driver info in a global variable such that crash debugger + can extract it from driver debug symbol and crashdump for post processing */ +tANI_U8 g_wlan_driver[ ] = "pronto_driver"; + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, tANI_U8 *pCckmIeLen); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx); +const char * hdd_device_modetoString(v_U8_t device_mode) +{ + switch(device_mode) + { + CASE_RETURN_STRING( WLAN_HDD_INFRA_STATION ); + CASE_RETURN_STRING( WLAN_HDD_SOFTAP ); + CASE_RETURN_STRING( WLAN_HDD_P2P_CLIENT ); + CASE_RETURN_STRING( WLAN_HDD_P2P_GO ); + CASE_RETURN_STRING( WLAN_HDD_MONITOR); + CASE_RETURN_STRING( WLAN_HDD_FTM ); + CASE_RETURN_STRING( WLAN_HDD_IBSS ); + CASE_RETURN_STRING( WLAN_HDD_P2P_DEVICE ); + default: + return "device_mode Unknown"; + } +} + +static int __hdd_netdev_notifier_call(struct notifier_block * nb, + unsigned long state, + void *ndev) +{ + struct net_device *dev = ndev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; +#ifdef WLAN_BTAMP_FEATURE + VOS_STATUS status; +#endif + long result; + + //Make sure that this callback corresponds to our device. + if ((strncmp(dev->name, "wlan", 4)) && + (strncmp(dev->name, "p2p", 3))) + return NOTIFY_DONE; + + if (!dev->ieee80211_ptr) + return NOTIFY_DONE; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Adapter Null Pointer", __func__); + VOS_ASSERT(0); + return NOTIFY_DONE; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__); + VOS_ASSERT(0); + return NOTIFY_DONE; + } + if (pHddCtx->isLogpInProgress) + return NOTIFY_DONE; + + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: %s New Net Device State = %lu", + __func__, dev->name, state); + + switch (state) { + case NETDEV_REGISTER: + break; + + case NETDEV_UNREGISTER: + break; + + case NETDEV_UP: + break; + + case NETDEV_DOWN: + break; + + case NETDEV_CHANGE: + if(TRUE == pAdapter->isLinkUpSvcNeeded) + complete(&pAdapter->linkup_event_var); + break; + + case NETDEV_GOING_DOWN: + result = wlan_hdd_scan_abort(pAdapter); + if (result < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred while waiting for abortscan %ld", + __func__, result); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Scan Abort Successful" , __func__); + } +#ifdef WLAN_BTAMP_FEATURE + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__); + status = WLANBAP_StopAmp(); + if(VOS_STATUS_SUCCESS != status ) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop AMP", __func__); + } + else + { + //a state m/c implementation in PAL is TBD to avoid this delay + msleep(500); + if ( pHddCtx->isAmpAllowed ) + { + WLANBAP_DeregisterFromHCI(); + pHddCtx->isAmpAllowed = VOS_FALSE; + } + } +#endif //WLAN_BTAMP_FEATURE + break; + + default: + break; + } + + return NOTIFY_DONE; +} + +static int hdd_netdev_notifier_call(struct notifier_block * nb, + unsigned long state, + void *ndev) +{ + int ret; + vos_ssr_protect(__func__); + ret = __hdd_netdev_notifier_call( nb, state, ndev); + vos_ssr_unprotect(__func__); + return ret; +} + +struct notifier_block hdd_netdev_notifier = { + .notifier_call = hdd_netdev_notifier_call, +}; + +/*--------------------------------------------------------------------------- + * Function definitions + *-------------------------------------------------------------------------*/ +void hdd_unregister_mcast_bcast_filter(hdd_context_t *pHddCtx); +void hdd_register_mcast_bcast_filter(hdd_context_t *pHddCtx); +//variable to hold the insmod parameters +static int con_mode; +#ifndef MODULE +/* current con_mode - used only for statically linked driver + * con_mode is changed by userspace to indicate a mode change which will + * result in calling the module exit and init functions. The module + * exit function will clean up based on the value of con_mode prior to it + * being changed by userspace. So curr_con_mode records the current con_mode + * for exit when con_mode becomes the next mode for init + */ +static int curr_con_mode; +#endif + +#ifdef WLAN_FEATURE_OFFLOAD_PACKETS +/** + * hdd_init_offloaded_packets_ctx() - Initialize offload packets context + * @hdd_ctx: hdd global context + * + * Return: none + */ +static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx) +{ + uint8_t i; + + mutex_init(&hdd_ctx->op_ctx.op_lock); + for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) + { + hdd_ctx->op_ctx.op_table[i].request_id = 0; + hdd_ctx->op_ctx.op_table[i].pattern_id = i; + } +} +#else +static void hdd_init_offloaded_packets_ctx(hdd_context_t *hdd_ctx) +{ +} +#endif + +/**--------------------------------------------------------------------------- + + \brief hdd_vos_trace_enable() - Configure initial VOS Trace enable + + Called immediately after the cfg.ini is read in order to configure + the desired trace levels. + + \param - moduleId - module whose trace level is being configured + \param - bitmask - bitmask of log levels to be enabled + + \return - void + + --------------------------------------------------------------------------*/ +static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask) +{ + wpt_tracelevel level; + + /* if the bitmask is the default value, then a bitmask was not + specified in cfg.ini, so leave the logging level alone (it + will remain at the "compiled in" default value) */ + if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask) + { + return; + } + + /* a mask was specified. start by disabling all logging */ + vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0); + + /* now cycle through the bitmask until all "set" bits are serviced */ + level = VOS_TRACE_LEVEL_FATAL; + while (0 != bitmask) + { + if (bitmask & 1) + { + vos_trace_setValue(moduleId, level, 1); + } + level++; + bitmask >>= 1; + } +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_wdi_trace_enable() - Configure initial WDI Trace enable + + Called immediately after the cfg.ini is read in order to configure + the desired trace levels in the WDI. + + \param - moduleId - module whose trace level is being configured + \param - bitmask - bitmask of log levels to be enabled + + \return - void + + --------------------------------------------------------------------------*/ +static void hdd_wdi_trace_enable(wpt_moduleid moduleId, v_U32_t bitmask) +{ + wpt_tracelevel level; + + /* if the bitmask is the default value, then a bitmask was not + specified in cfg.ini, so leave the logging level alone (it + will remain at the "compiled in" default value) */ + if (CFG_WDI_TRACE_ENABLE_DEFAULT == bitmask) + { + return; + } + + /* a mask was specified. start by disabling all logging */ + wpalTraceSetLevel(moduleId, eWLAN_PAL_TRACE_LEVEL_NONE, 0); + + /* now cycle through the bitmask until all "set" bits are serviced */ + level = eWLAN_PAL_TRACE_LEVEL_FATAL; + while (0 != bitmask) + { + if (bitmask & 1) + { + wpalTraceSetLevel(moduleId, level, 1); + } + level++; + bitmask >>= 1; + } +} + +/* + * FUNCTION: wlan_hdd_validate_context + * This function is used to check the HDD context + */ +int wlan_hdd_validate_context(hdd_context_t *pHddCtx) +{ + + if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: HDD context is Null", __func__); + return -ENODEV; + } + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: LOGP %s. Ignore!!", __func__, + vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL) + ?"failed":"in Progress"); + return -EAGAIN; + } + + if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return -EAGAIN; + } + return 0; +} +#ifdef CONFIG_ENABLE_LINUX_REG +void hdd_checkandupdate_phymode( hdd_context_t *pHddCtx) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + eCsrPhyMode phyMode; + hdd_config_t *cfg_param = NULL; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD Context is null !!"); + return ; + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "pAdapter is null !!"); + return ; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "pHddStaCtx is null !!"); + return ; + } + + cfg_param = pHddCtx->cfg_ini; + if (NULL == cfg_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "cfg_params not available !!"); + return ; + } + + phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter)); + + if (!pHddCtx->isVHT80Allowed) + { + if ((eCSR_DOT11_MODE_AUTO == phyMode) || + (eCSR_DOT11_MODE_11ac == phyMode) || + (eCSR_DOT11_MODE_11ac_ONLY == phyMode)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Setting phymode to 11n!!"); + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n); + } + } + else + { + /*New country Supports 11ac as well resetting value back from .ini*/ + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), + hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode)); + return ; + } + + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) || + (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode))) + { + VOS_STATUS vosStatus; + + // need to issue a disconnect to CSR. + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED ); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + long ret; + + ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (0 >= ret) + hddLog(LOGE, FL("failure waiting for disconnect_comp_var %ld"), + ret); + } + + } +} +#else +void hdd_checkandupdate_phymode( hdd_adapter_t *pAdapter, char *country_code) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param; + eCsrPhyMode phyMode; + long ret; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD Context is null !!"); + return ; + } + + cfg_param = pHddCtx->cfg_ini; + + if (NULL == cfg_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "cfg_params not available !!"); + return ; + } + + phyMode = sme_GetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter)); + + if (NULL != strstr(cfg_param->listOfNon11acCountryCode, country_code)) + { + if ((eCSR_DOT11_MODE_AUTO == phyMode) || + (eCSR_DOT11_MODE_11ac == phyMode) || + (eCSR_DOT11_MODE_11ac_ONLY == phyMode)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Setting phymode to 11n!!"); + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_DOT11_MODE_11n); + } + } + else + { + /*New country Supports 11ac as well resetting value back from .ini*/ + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), + hdd_cfg_xlate_to_csr_phy_mode(cfg_param->dot11Mode)); + return ; + } + + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + ((eCSR_CFG_DOT11_MODE_11AC_ONLY == pHddStaCtx->conn_info.dot11Mode) || + (eCSR_CFG_DOT11_MODE_11AC == pHddStaCtx->conn_info.dot11Mode))) + { + VOS_STATUS vosStatus; + + // need to issue a disconnect to CSR. + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED ); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + ret = wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "wait on disconnect_comp_var is failed %ld", ret); + } + } + + } +} +#endif //CONFIG_ENABLE_LINUX_REG + +void hdd_checkandupdate_dfssetting( hdd_adapter_t *pAdapter, char *country_code) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_config_t *cfg_param; + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD Context is null !!"); + return ; + } + + cfg_param = pHddCtx->cfg_ini; + + if (NULL == cfg_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "cfg_params not available !!"); + return ; + } + + if (NULL != strstr(cfg_param->listOfNonDfsCountryCode, country_code) || + pHddCtx->disable_dfs_flag == TRUE) + { + /*New country doesn't support DFS */ + sme_UpdateDfsSetting(WLAN_HDD_GET_HAL_CTX(pAdapter), 0); + } + +} + +#ifdef WLAN_FEATURE_RMC +static int hdd_parse_setrmcenable_command(tANI_U8 *pValue, tANI_U8 *pRmcEnable) +{ + tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + char buf[32]; + *pRmcEnable = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return 0; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return 0; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return 0; + } + + /* getting the first argument which enables or disables RMC + * for input IP v4 address*/ + sscanf(inPtr, "%31s ", buf); + v = kstrtos32(buf, 10, &tempInt); + if ( v < 0) + { + return -EINVAL; + } + + *pRmcEnable = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "ucRmcEnable: %d", *pRmcEnable); + + return 0; +} + +/* Function header left blank Intentionally */ +static int hdd_parse_setrmcactionperiod_command(tANI_U8 *pValue, + tANI_U32 *pActionPeriod) +{ + tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + char buf[32]; + *pActionPeriod = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return 0; + } + + /* getting the first argument which enables or disables RMC + * for input IP v4 address*/ + sscanf(inPtr, "%31s ", buf); + v = kstrtos32(buf, 10, &tempInt); + if ( v < 0) + { + return -EINVAL; + } + + /* Range checking for passed paramter */ + if (tempInt < WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN || + tempInt > WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX) + { + return -EINVAL; + } + + *pActionPeriod = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "uActionPeriod: %d", *pActionPeriod); + + return 0; +} + +/* Function header left blank Intentionally */ +static int hdd_parse_setrmcrate_command(tANI_U8 *pValue, + tANI_U32 *pRate, tTxrateinfoflags *pTxFlags) +{ + tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + char buf[32]; + *pRate = 0; + *pTxFlags = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return 0; + } + + /* + * getting the first argument which sets multicast rate. + */ + sscanf(inPtr, "%31s ", buf); + v = kstrtos32(buf, 10, &tempInt); + if ( v < 0) + { + return -EINVAL; + } + + /* + * Validate the multicast rate. + */ + switch (tempInt) + { + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Unsupported rate: %d", tempInt); + return -EINVAL; + case 0: + case 6: + case 9: + case 12: + case 18: + case 24: + case 36: + case 48: + case 54: + *pTxFlags = eHAL_TX_RATE_LEGACY; + *pRate = tempInt * 10; + break; + case 65: + *pTxFlags = eHAL_TX_RATE_HT20; + *pRate = tempInt * 10; + break; + case 72: + *pTxFlags = eHAL_TX_RATE_HT20 | eHAL_TX_RATE_SGI; + *pRate = 722; /* fractional rate 72.2 Mbps */ + break; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Rate: %d", *pRate); + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_cfg80211_get_ibss_peer_info_cb() - Callback function for IBSS + Peer Info request + + This is an asynchronous callback function from SME when the peer info + is received + + \pUserData -> Adapter private data + \pPeerInfoRsp -> Peer info response + + \return - 0 for success non-zero for failure + --------------------------------------------------------------------------*/ +static void +hdd_cfg80211_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData; + tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp; + hdd_station_ctx_t *pStaCtx; + v_U8_t i; + + /*Sanity check*/ + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog(LOGE, + FL("invalid adapter or adapter has invalid magic")); + return; + } + + pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL != pStaCtx && NULL != pPeerInfo && + eHAL_STATUS_SUCCESS == pPeerInfo->status) + { + pStaCtx->ibss_peer_info.status = pPeerInfo->status; + pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers; + + /* Paranoia check */ + if (pPeerInfo->numPeers < HDD_MAX_NUM_IBSS_STA) + { + for (i = 0; i < pPeerInfo->numPeers; i++) + { + memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i], + &pPeerInfo->peerInfoParams[i], + sizeof(hdd_ibss_peer_info_params_t)); + } + hddLog(LOG1, + FL("Peer Info copied in HDD")); + } + else + { + hddLog(LOGE, + FL(" Number of peers %d returned is more than limit %d"), + pPeerInfo->numPeers, HDD_MAX_NUM_IBSS_STA); + } + } + else + { + hddLog(LOG1, + FL("peerInfo returned is NULL")); + } + + complete(&pAdapter->ibss_peer_info_comp); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_cfg80211_get_ibss_peer_info_all() - + + Request function to get IBSS peer info from lower layers + + \pAdapter -> Adapter context + + \return - 0 for success non-zero for failure + --------------------------------------------------------------------------*/ +static +VOS_STATUS hdd_cfg80211_get_ibss_peer_info_all(hdd_adapter_t *pAdapter) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + long status; + VOS_STATUS retStatus = VOS_STATUS_E_FAILURE; + + INIT_COMPLETION(pAdapter->ibss_peer_info_comp); + + retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter, + hdd_cfg80211_get_ibss_peer_info_cb, + VOS_TRUE, 0xFF); + + if (VOS_STATUS_SUCCESS == retStatus) + { + status = wait_for_completion_interruptible_timeout + (&pAdapter->ibss_peer_info_comp, + msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT)); + + /* status will be 0 if timed out */ + if (status <= 0) + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld", + __func__, status); + retStatus = VOS_STATUS_E_FAILURE; + return retStatus; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__); + } + + return retStatus; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_cfg80211_get_ibss_peer_info() - + + Request function to get IBSS peer info from lower layers + + \pAdapter -> Adapter context + \staIdx -> Sta index for which the peer info is requested + + \return - 0 for success non-zero for failure + --------------------------------------------------------------------------*/ +static VOS_STATUS +hdd_cfg80211_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx) +{ + long status; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS retStatus = VOS_STATUS_E_FAILURE; + + INIT_COMPLETION(pAdapter->ibss_peer_info_comp); + + retStatus = sme_RequestIBSSPeerInfo(hHal, pAdapter, + hdd_cfg80211_get_ibss_peer_info_cb, + VOS_FALSE, staIdx); + + if (VOS_STATUS_SUCCESS == retStatus) + { + status = wait_for_completion_interruptible_timeout + (&pAdapter->ibss_peer_info_comp, + msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT)); + + /* status = 0 on timeout */ + if (status <= 0) + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning: IBSS_PEER_INFO_TIMEOUT %ld", + __func__, status); + retStatus = VOS_STATUS_E_FAILURE; + return retStatus; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__); + } + + return retStatus; +} + +/* Function header left blank Intentionally */ +VOS_STATUS +hdd_parse_get_ibss_peer_info(tANI_U8 *pValue, v_MACADDR_t *pPeerMacAddr) +{ + tANI_U8 *inPtr = pValue; + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + + /*no argument after the command*/ + if (NULL == inPtr) + { + return VOS_STATUS_E_FAILURE;; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return VOS_STATUS_E_FAILURE;; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return VOS_STATUS_E_FAILURE;; + } + + /*getting the first argument ie the peer mac address */ + if (inPtr[2] != ':' || inPtr[5] != ':' || inPtr[8] != ':' || + inPtr[11] != ':' || inPtr[14] != ':') + { + return VOS_STATUS_E_FAILURE;; + } + sscanf(inPtr, "%2x:%2x:%2x:%2x:%2x:%2x", + (unsigned int *)&pPeerMacAddr->bytes[0], + (unsigned int *)&pPeerMacAddr->bytes[1], + (unsigned int *)&pPeerMacAddr->bytes[2], + (unsigned int *)&pPeerMacAddr->bytes[3], + (unsigned int *)&pPeerMacAddr->bytes[4], + (unsigned int *)&pPeerMacAddr->bytes[5]); + + /* The command buffer seems to be fine */ + return VOS_STATUS_SUCCESS; +} + +/* Function header left blank Intentionally */ +static int hdd_parse_set_ibss_oui_data_command(tANI_U8 *command, tANI_U8 *ie, + tANI_U32 limit) +{ + tANI_U8 len; + tANI_U8 data; + + /* skip white space */ + while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) + { + command++; + limit--; + } + + /* skip element id and element length */ + len = 2; + + /* extract oui */ + while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) && + (limit > 1)) + { + /* Convert ASCII to decimal */ + data = ((*command -'0') << 4) | (*(command + 1) - '0'); + ie[len++] = data; + command += 2; + limit -= 2; + } + + /* skip white space */ + while ((SPACE_ASCII_VALUE == *command) && ('\0' != *command)) + { + command++; + limit--; + } + + /* extract data */ + while ((SPACE_ASCII_VALUE != *command) && ('\0' != *command) && + (limit > 1)) + { + /* Convert ASCII to decimal */ + data = ((*command -'0') << 4) | (*(command + 1) - '0'); + ie[len++] = data; + command += 2; + limit -= 2; + } + + /* fill element id and element length */ + ie[0] = IE_EID_VENDOR; + ie[1] = len - 2; + + return len; +} + +static tANI_U32 hdd_find_ibss_wpa_ie_pos(tANI_U8 *addIePtr, tANI_U32 addIeLen) +{ + tANI_U32 ieLenPresent = 0; + int left = addIeLen; + v_U8_t *ptr = addIePtr; + v_U8_t elem_id,elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + hddLog(LOGE, + FL("****Invalid elem_len=%d left=%d*****"), + elem_len,left); + return 0; + } + if ((elem_id == IE_EID_VENDOR) && + (left >= WPA_OUI_TYPE_SIZE)) + { + if (!memcmp(&ptr[2], WPA_OUI_TYPE, + WPA_OUI_TYPE_SIZE)) + { + ieLenPresent += elem_len + 2; + return ieLenPresent; + } + } + ieLenPresent += (elem_len + 2); + left -= elem_len; + ptr += (elem_len + 2); + } + return 0; +} + +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/**--------------------------------------------------------------------------- + + \brief hdd_extract_assigned_int_from_str() - Extracts assigned integer from + input string + + This function extracts assigned integer from string in below format: + "STRING=10" : extracts integer 10 from this string + + \param - pInPtr Pointer to input string + \param - base Base for string to int conversion(10 for decimal 16 for hex) + \param - pOutPtr Pointer to variable in which extracted integer needs to be + assigned + \param - pLastArg to tell whether it is last arguement in input string or + not + + \return - NULL for failure cases + pointer to next arguement in input string for success cases + --------------------------------------------------------------------------*/ +static tANI_U8 * +hdd_extract_assigned_int_from_str +( + tANI_U8 *pInPtr, + tANI_U8 base, + tANI_U32 *pOutPtr, + tANI_U8 *pLastArg +) +{ + int tempInt; + int v = 0; + char buf[32]; + int val = 0; + *pLastArg = FALSE; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE); + if (NULL == pInPtr) + { + return NULL; + } + + pInPtr++; + + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + val = sscanf(pInPtr, "%32s ", buf); + if (val < 0 && val > strlen(pInPtr)) + { + return NULL; + } + pInPtr += val; + v = kstrtos32(buf, base, &tempInt); + if (v < 0) + { + return NULL; + } + if (tempInt < 0) + { + tempInt = 0; + } + *pOutPtr = tempInt; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE); + if (NULL == pInPtr) + { + *pLastArg = TRUE; + return NULL; + } + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + return pInPtr; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_extract_assigned_char_from_str() - Extracts assigned char from + input string + + This function extracts assigned character from string in below format: + "STRING=A" : extracts char 'A' from this string + + \param - pInPtr Pointer to input string + \param - pOutPtr Pointer to variable in which extracted char needs to be + assigned + \param - pLastArg to tell whether it is last arguement in input string or + not + + \return - NULL for failure cases + pointer to next arguement in input string for success cases + --------------------------------------------------------------------------*/ +static tANI_U8 * +hdd_extract_assigned_char_from_str +( + tANI_U8 *pInPtr, + tANI_U8 *pOutPtr, + tANI_U8 *pLastArg +) +{ + *pLastArg = FALSE; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), EQUALS_TO_ASCII_VALUE); + if (NULL == pInPtr) + { + return NULL; + } + + pInPtr++; + + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + *pOutPtr = *pInPtr; + + pInPtr = strnchr(pInPtr, strlen(pInPtr), SPACE_ASCII_VALUE); + if (NULL == pInPtr) + { + *pLastArg = TRUE; + return NULL; + } + while ((SPACE_ASCII_VALUE == *pInPtr) && ('\0' != *pInPtr)) pInPtr++; + + return pInPtr; +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_set_batchscan_command () - HDD parse set batch scan command + + This function parses set batch scan command in below format: + WLS_BATCHING_SET followed by below arguements + "SCANFREQ=XX" : Optional defaults to 30 sec + "MSCAN=XX" : Required number of scans to attempt to batch + "BESTN=XX" : Best Network (RSSI) defaults to 16 + "CHANNEL=" : optional defaults to all channels, can list 'A'or` B. + A. implies only 5 GHz , B. implies only 2.4GHz + "RTT=X" : optional defaults to 0 + returns the MIN of MSCAN or the max # of scans firmware can cache or -1 on + error + + For example input commands: + 1) WLS_BATCHING_SET SCANFREQ=60 MSCAN=10 BESTN=20 CHANNEL=A RTT=0 -> This is + translated into set batch scan with following parameters: + a) Frequence 60 seconds + b) Batch 10 scans together + c) Best RSSI to be 20 + d) 5GHz band only + e) RTT is equal to 0 + + \param - pValue Pointer to input channel list + \param - pHddSetBatchScanReq Pointer to HDD batch scan request structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static int +hdd_parse_set_batchscan_command +( + tANI_U8 *pValue, + tSirSetBatchScanReq *pHddSetBatchScanReq +) +{ + tANI_U8 *inPtr = pValue; + tANI_U8 val = 0; + tANI_U8 lastArg = 0; + tANI_U32 nScanFreq = HDD_SET_BATCH_SCAN_DEFAULT_FREQ; + tANI_U32 nMscan; + tANI_U32 nBestN = HDD_SET_BATCH_SCAN_BEST_NETWORK; + tANI_U8 ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND; + tANI_U32 nRtt = 0; + tANI_U32 temp; + + /*go to space after WLS_BATCHING_SET command*/ + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*check and parse SCANFREQ*/ + if ((strncmp(inPtr, "SCANFREQ", 8) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &temp, &lastArg); + + if (0 != temp) + { + nScanFreq = temp; + } + + if ( (NULL == inPtr) || (TRUE == lastArg)) + { + return -EINVAL; + } + } + + /*check and parse MSCAN*/ + if ((strncmp(inPtr, "MSCAN", 5) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &nMscan, &lastArg); + + if (0 == nMscan) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "invalid MSCAN=%d", nMscan); + return -EINVAL; + } + + if (TRUE == lastArg) + { + goto done; + } + else if (NULL == inPtr) + { + return -EINVAL; + } + } + else + { + return -EINVAL; + } + + /*check and parse BESTN*/ + if ((strncmp(inPtr, "BESTN", 5) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &temp, &lastArg); + + if (0 != temp) + { + nBestN = temp; + } + + if (TRUE == lastArg) + { + goto done; + } + else if (NULL == inPtr) + { + return -EINVAL; + } + } + + /*check and parse CHANNEL*/ + if ((strncmp(inPtr, "CHANNEL", 7) == 0)) + { + inPtr = hdd_extract_assigned_char_from_str(inPtr, &val, &lastArg); + + if (('A' == val) || ('a' == val)) + { + ucRfBand = HDD_SET_BATCH_SCAN_5GHz_BAND_ONLY; + } + else if (('B' == val) || ('b' == val)) + { + ucRfBand = HDD_SET_BATCH_SCAN_24GHz_BAND_ONLY; + } + else + { + ucRfBand = HDD_SET_BATCH_SCAN_DEFAULT_BAND; + } + + if (TRUE == lastArg) + { + goto done; + } + else if (NULL == inPtr) + { + return -EINVAL; + } + } + + /*check and parse RTT*/ + if ((strncmp(inPtr, "RTT", 3) == 0)) + { + inPtr = hdd_extract_assigned_int_from_str(inPtr, 10, + &nRtt, &lastArg); + if (TRUE == lastArg) + { + goto done; + } + if (NULL == inPtr) + { + return -EINVAL; + } + } + + +done: + + pHddSetBatchScanReq->scanFrequency = nScanFreq; + pHddSetBatchScanReq->numberOfScansToBatch = nMscan; + pHddSetBatchScanReq->bestNetwork = nBestN; + pHddSetBatchScanReq->rfBand = ucRfBand; + pHddSetBatchScanReq->rtt = nRtt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received WLS_BATCHING_SET with SCANFREQ=%d " + "MSCAN=%d BESTN=%d CHANNEL=%d RTT=%d", + pHddSetBatchScanReq->scanFrequency, + pHddSetBatchScanReq->numberOfScansToBatch, + pHddSetBatchScanReq->bestNetwork, + pHddSetBatchScanReq->rfBand, + pHddSetBatchScanReq->rtt); + + return 0; +}/*End of hdd_parse_set_batchscan_command*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_set_batch_scan_req_callback () - This function is called after + receiving set batch scan response from FW and it saves set batch scan + response data FW to HDD context and sets the completion event on + which hdd_ioctl is waiting + + \param - callbackContext Pointer to HDD adapter + \param - pRsp Pointer to set batch scan response data received from FW + + \return - nothing + + --------------------------------------------------------------------------*/ +static void hdd_set_batch_scan_req_callback +( + void *callbackContext, + tSirSetBatchScanRsp *pRsp +) +{ + hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext; + tSirSetBatchScanRsp *pHddSetBatchScanRsp; + + /*sanity check*/ + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + VOS_ASSERT(0); + return; + } + pHddSetBatchScanRsp = &pAdapter->hddSetBatchScanRsp; + + /*save set batch scan response*/ + pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Received set batch scan rsp from FW with nScansToBatch=%d", + pHddSetBatchScanRsp->nScansToBatch); + + pAdapter->hdd_wait_for_set_batch_scan_rsp = FALSE; + complete(&pAdapter->hdd_set_batch_scan_req_var); + + return; +}/*End of hdd_set_batch_scan_req_callback*/ + + +/**--------------------------------------------------------------------------- + + \brief hdd_populate_batch_scan_rsp_queue () - This function stores AP meta + info in hdd batch scan response queue + + \param - pAdapter Pointer to hdd adapter + \param - pAPMetaInfo Pointer to access point meta info + \param - scanId scan ID of batch scan response + \param - isLastAp tells whether AP is last AP in batch scan response or not + + \return - nothing + + --------------------------------------------------------------------------*/ +static void hdd_populate_batch_scan_rsp_queue( hdd_adapter_t* pAdapter, + tpSirBatchScanNetworkInfo pApMetaInfo, tANI_U32 scanId, v_BOOL_t isLastAp) +{ + tHddBatchScanRsp *pHead; + tHddBatchScanRsp *pNode; + tHddBatchScanRsp *pPrev; + tHddBatchScanRsp *pTemp; + tANI_U8 ssidLen; + + /*head of hdd batch scan response queue*/ + pHead = pAdapter->pBatchScanRsp; + + pNode = (tHddBatchScanRsp *)vos_mem_malloc(sizeof(tHddBatchScanRsp)); + if (NULL == pNode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Could not allocate memory", __func__); + VOS_ASSERT(0); + return; + } + + vos_mem_copy(pNode->ApInfo.bssid, pApMetaInfo->bssid, + sizeof(pNode->ApInfo.bssid)); + ssidLen = strlen(pApMetaInfo->ssid); + if (SIR_MAX_SSID_SIZE < ssidLen) + { + /*invalid scan result*/ + vos_mem_free(pNode); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid AP meta info ssidlen %d", __func__, ssidLen); + return; + } + vos_mem_copy(pNode->ApInfo.ssid, pApMetaInfo->ssid, ssidLen); + /*null terminate ssid*/ + pNode->ApInfo.ssid[ssidLen] = '\0'; + pNode->ApInfo.ch = pApMetaInfo->ch; + pNode->ApInfo.rssi = pApMetaInfo->rssi; + pNode->ApInfo.age = pApMetaInfo->timestamp; + pNode->ApInfo.batchId = scanId; + pNode->ApInfo.isLastAp = isLastAp; + + pNode->pNext = NULL; + if (NULL == pHead) + { + pAdapter->pBatchScanRsp = pNode; + } + else + { + pTemp = pHead; + while (NULL != pTemp) + { + pPrev = pTemp; + pTemp = pTemp->pNext; + } + pPrev->pNext = pNode; + } + + return; +}/*End of hdd_populate_batch_scan_rsp_queue*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_batch_scan_result_ind_callback () - This function is called after + receiving batch scan response indication from FW. It saves get batch scan + response data in HDD batch scan response queue. This callback sets the + completion event on which hdd_ioctl is waiting only after getting complete + batch scan response data from FW + + \param - callbackContext Pointer to HDD adapter + \param - pRsp Pointer to get batch scan response data received from FW + + \return - nothing + + --------------------------------------------------------------------------*/ +static void hdd_batch_scan_result_ind_callback +( + void *callbackContext, + void *pRsp +) +{ + v_BOOL_t isLastAp; + tANI_U32 numApMetaInfo; + tANI_U32 numNetworkInScanList; + tANI_U32 numberScanList; + tANI_U32 nextScanListOffset; + tANI_U32 nextApMetaInfoOffset; + hdd_adapter_t* pAdapter; + tpSirBatchScanList pScanList; + tpSirBatchScanNetworkInfo pApMetaInfo; + tpSirBatchScanResultIndParam pBatchScanRsp;/*batch scan rsp data from FW*/ + tSirSetBatchScanReq *pReq; + + pAdapter = (hdd_adapter_t *)callbackContext; + /*sanity check*/ + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + VOS_ASSERT(0); + return; + } + + /*initialize locals*/ + pReq = &pAdapter->hddSetBatchScanReq; + pBatchScanRsp = (tpSirBatchScanResultIndParam)pRsp; + isLastAp = FALSE; + numApMetaInfo = 0; + numNetworkInScanList = 0; + numberScanList = 0; + nextScanListOffset = 0; + nextApMetaInfoOffset = 0; + pScanList = NULL; + pApMetaInfo = NULL; + + if ((NULL == pBatchScanRsp) || (NULL == pReq)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pBatchScanRsp is %p pReq %p", __func__, pBatchScanRsp, pReq); + isLastAp = TRUE; + goto done; + } + + pAdapter->numScanList = numberScanList = pBatchScanRsp->numScanLists; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Batch scan rsp: numberScalList %d", numberScanList); + + if ((!numberScanList) || (numberScanList > pReq->numberOfScansToBatch)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: numberScanList %d", __func__, numberScanList); + isLastAp = TRUE; + goto done; + } + + while (numberScanList) + { + pScanList = (tpSirBatchScanList)((tANI_U8 *)pBatchScanRsp->scanResults + + nextScanListOffset); + if (NULL == pScanList) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pScanList is %p", __func__, pScanList); + isLastAp = TRUE; + goto done; + } + numNetworkInScanList = numApMetaInfo = pScanList->numNetworksInScanList; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Batch scan rsp: numApMetaInfo %d scanId %d", + numApMetaInfo, pScanList->scanId); + + if ((!numApMetaInfo) || (numApMetaInfo > pReq->bestNetwork)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: numApMetaInfo %d", __func__, numApMetaInfo); + isLastAp = TRUE; + goto done; + } + + /*Initialize next AP meta info offset for next scan list*/ + nextApMetaInfoOffset = 0; + + while (numApMetaInfo) + { + pApMetaInfo = (tpSirBatchScanNetworkInfo)(pScanList->scanList + + nextApMetaInfoOffset); + if (NULL == pApMetaInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pApMetaInfo is %p", __func__, pApMetaInfo); + isLastAp = TRUE; + goto done; + } + /*calculate AP age*/ + pApMetaInfo->timestamp = + pBatchScanRsp->timestamp - pApMetaInfo->timestamp; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: bssId "MAC_ADDRESS_STR + " ch %d rssi %d timestamp %d", __func__, + MAC_ADDR_ARRAY(pApMetaInfo->bssid), + pApMetaInfo->ch, pApMetaInfo->rssi, + pApMetaInfo->timestamp); + + /*mark last AP in batch scan response*/ + if ((TRUE == pBatchScanRsp->isLastResult) && + (1 == numberScanList) && (1 == numApMetaInfo)) + { + isLastAp = TRUE; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + /*store batch scan repsonse in hdd queue*/ + hdd_populate_batch_scan_rsp_queue(pAdapter, pApMetaInfo, + pScanList->scanId, isLastAp); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + nextApMetaInfoOffset += sizeof(tSirBatchScanNetworkInfo); + numApMetaInfo--; + } + + nextScanListOffset += ((sizeof(tSirBatchScanList) - sizeof(tANI_U8)) + + (sizeof(tSirBatchScanNetworkInfo) + * numNetworkInScanList)); + numberScanList--; + } + +done: + + /*notify hdd_ioctl only if complete batch scan rsp is received and it was + requested from hdd_ioctl*/ + if ((TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) && + (TRUE == isLastAp)) + { + pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE; + complete(&pAdapter->hdd_get_batch_scan_req_var); + } + + return; +}/*End of hdd_batch_scan_result_ind_callback*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_format_batch_scan_rsp () - This function formats batch scan + response as per batch scan FR request format by putting proper markers + + \param - pDest pointer to destination buffer + \param - cur_len current length + \param - tot_len total remaining size which can be written to user space + \param - pApMetaInfo Pointer to get batch scan response AP meta info + \param - pAdapter Pointer to HDD adapter + + \return - ret no of characters written + + --------------------------------------------------------------------------*/ +static tANI_U32 +hdd_format_batch_scan_rsp +( + tANI_U8 *pDest, + tANI_U32 cur_len, + tANI_U32 tot_len, + tHddBatchScanRsp *pApMetaInfo, + hdd_adapter_t* pAdapter +) +{ + tANI_U32 ret = 0; + tANI_U32 rem_len = 0; + tANI_U8 temp_len = 0; + tANI_U8 temp_total_len = 0; + tANI_U8 temp[HDD_BATCH_SCAN_AP_META_INFO_SIZE]; + tANI_U8 *pTemp = temp; + + /*Batch scan reponse needs to be returned to user space in + following format: + "scancount=X\n" where X is the number of scans in current batch + batch + "trunc\n" optional present if current scan truncated + "bssid=XX:XX:XX:XX:XX:XX\n" + "ssid=XXXX\n" + "freq=X\n" frequency in Mhz + "level=XX\n" + "age=X\n" ms + "dist=X\n" cm (-1 if not available) + "errror=X\n" (-1if not available) + "====\n" (end of ap marker) + "####\n" (end of scan marker) + "----\n" (end of results)*/ + /*send scan result in above format to user space based on + available length*/ + /*The GET response may have more data than the driver can return in its + buffer. In that case the buffer should be filled to the nearest complete + scan, ending with "%%%%".Subsequent callsshould return the remaining data + starting with the next scan (optional .trunc\n., .apcount=X\n., etc). + The final buffer should end with "----\n"*/ + + /*sanity*/ + if (cur_len > tot_len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invaid cur_len %d tot_len %d", __func__, cur_len, tot_len); + return 0; + } + else + { + rem_len = (tot_len - cur_len); + } + + /*end scan marker*/ + if (pApMetaInfo->ApInfo.batchId != pAdapter->prev_batch_id) + { + temp_len = snprintf(pTemp, sizeof(temp), "####\n"); + pTemp += temp_len; + temp_total_len += temp_len; + } + + /*bssid*/ + temp_len = snprintf(pTemp, sizeof(temp), + "bssid=0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", + pApMetaInfo->ApInfo.bssid[0], pApMetaInfo->ApInfo.bssid[1], + pApMetaInfo->ApInfo.bssid[2], pApMetaInfo->ApInfo.bssid[3], + pApMetaInfo->ApInfo.bssid[4], pApMetaInfo->ApInfo.bssid[5]); + pTemp += temp_len; + temp_total_len += temp_len; + + /*ssid*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "ssid=%s\n", + pApMetaInfo->ApInfo.ssid); + pTemp += temp_len; + temp_total_len += temp_len; + + /*freq*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "freq=%d\n", + sme_ChnToFreq(pApMetaInfo->ApInfo.ch)); + pTemp += temp_len; + temp_total_len += temp_len; + + /*level*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "level=%d\n", + pApMetaInfo->ApInfo.rssi); + pTemp += temp_len; + temp_total_len += temp_len; + + /*age*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "age=%d\n", + pApMetaInfo->ApInfo.age); + pTemp += temp_len; + temp_total_len += temp_len; + + /*dist*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "dist=-1\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*error*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "error=-1\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*end AP marker*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "====\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*last AP in batch scan response*/ + if(TRUE == pApMetaInfo->ApInfo.isLastAp) + { + /*end scan marker*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "####\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + /*end batch scan result marker*/ + temp_len = snprintf(pTemp, (sizeof(temp) - temp_total_len), "----\n"); + pTemp += temp_len; + temp_total_len += temp_len; + + } + + if (temp_total_len < rem_len) + { + ret = temp_total_len + 1; + strlcpy(pDest, temp, ret); + pAdapter->isTruncated = FALSE; + } + else + { + pAdapter->isTruncated = TRUE; + if (rem_len >= strlen("%%%%")) + { + ret = snprintf(pDest, sizeof(temp), "%%%%"); + } + else + { + ret = 0; + } + } + + return ret; + +}/*End of hdd_format_batch_scan_rsp*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_populate_user_batch_scan_rsp() - This function populates user data + buffer starting with head of hdd batch scan response queue + + \param - pAdapter Pointer to HDD adapter + \param - pDest Pointer to user data buffer + \param - cur_len current offset in user buffer + \param - rem_len remaining no of bytes in user buffer + + \return - number of bytes written in user buffer + + --------------------------------------------------------------------------*/ + +tANI_U32 hdd_populate_user_batch_scan_rsp +( + hdd_adapter_t* pAdapter, + tANI_U8 *pDest, + tANI_U32 cur_len, + tANI_U32 rem_len +) +{ + tHddBatchScanRsp *pHead; + tHddBatchScanRsp *pPrev; + tANI_U32 len; + + pAdapter->isTruncated = FALSE; + + /*head of hdd batch scan response queue*/ + pHead = pAdapter->pBatchScanRsp; + while (pHead) + { + len = hdd_format_batch_scan_rsp(pDest, cur_len, rem_len, pHead, + pAdapter); + pDest += len; + pDest--; + cur_len += len; + if(TRUE == pAdapter->isTruncated) + { + /*result is truncated return rest of scan rsp in next req*/ + cur_len = rem_len; + break; + } + pPrev = pHead; + pHead = pHead->pNext; + pAdapter->pBatchScanRsp = pHead; + if (TRUE == pPrev->ApInfo.isLastAp) + { + pAdapter->prev_batch_id = 0; + } + else + { + pAdapter->prev_batch_id = pPrev->ApInfo.batchId; + } + vos_mem_free(pPrev); + pPrev = NULL; + } + + return cur_len; +}/*End of hdd_populate_user_batch_scan_rsp*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_return_batch_scan_rsp_to_user () - This function returns batch + scan response data from HDD queue to user space + It does following in detail: + a) if HDD has enough data in its queue then it 1st copies data to user + space and then send get batch scan indication message to FW. In this + case it does not wait on any event and batch scan response data will + be populated in HDD response queue in MC thread context after receiving + indication from FW + b) else send get batch scan indication message to FW and wait on an event + which will be set once HDD receives complete batch scan response from + FW and then this function returns batch scan response to user space + + \param - pAdapter Pointer to HDD adapter + \param - pPrivData Pointer to priv_data + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_return_batch_scan_rsp_to_user +( + hdd_adapter_t* pAdapter, + hdd_priv_data_t *pPrivData, + tANI_U8 *command +) +{ + tANI_U8 *pDest; + tANI_U32 count = 0; + tANI_U32 len = 0; + tANI_U32 cur_len = 0; + tANI_U32 rem_len = 0; + eHalStatus halStatus; + unsigned long rc; + tSirTriggerBatchScanResultInd *pReq; + + pReq = &pAdapter->hddTriggerBatchScanResultInd; + pReq->param = 0;/*batch scan client*/ + pDest = (tANI_U8 *)(command + pPrivData->used_len); + pAdapter->hdd_wait_for_get_batch_scan_rsp = FALSE; + + cur_len = pPrivData->used_len; + if (pPrivData->total_len > pPrivData->used_len) + { + rem_len = pPrivData->total_len - pPrivData->used_len; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid user data buffer total_len %d used_len %d", + __func__, pPrivData->total_len, pPrivData->used_len); + return -EFAULT; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest, + cur_len, rem_len); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + /*enough scan result available in cache to return to user space or + scan result needs to be fetched 1st from fw and then return*/ + if (len == cur_len) + { + pAdapter->hdd_wait_for_get_batch_scan_rsp = TRUE; + halStatus = sme_TriggerBatchScanResultInd( + WLAN_HDD_GET_HAL_CTX(pAdapter), pReq, + pAdapter->sessionId, hdd_batch_scan_result_ind_callback, + pAdapter); + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + if (TRUE == pAdapter->hdd_wait_for_get_batch_scan_rsp) + { + INIT_COMPLETION(pAdapter->hdd_get_batch_scan_req_var); + rc = wait_for_completion_timeout( + &pAdapter->hdd_get_batch_scan_req_var, + msecs_to_jiffies(HDD_GET_BATCH_SCAN_RSP_TIME_OUT)); + if (0 >= rc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: wait on hdd_get_batch_scan_req_var failed %ld", + __func__, rc); + return -EFAULT; + } + } + + len = snprintf(pDest, HDD_BATCH_SCAN_AP_META_INFO_SIZE, + "scancount=%u\n", pAdapter->numScanList); + pDest += len; + cur_len += len; + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + len = hdd_populate_user_batch_scan_rsp(pAdapter, pDest, + cur_len, rem_len); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + count = 0; + len = (len - pPrivData->used_len); + pDest = (command + pPrivData->used_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NEW BATCH SCAN RESULT:"); + while(count < len) + { + printk("%c", *(pDest + count)); + count++; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: copy %d data to user buffer", __func__, len); + if (copy_to_user(pPrivData->buf, pDest, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_GetBatchScanScan returned failure halStatus %d", + halStatus); + return -EINVAL; + } + } + else + { + count = 0; + len = (len - pPrivData->used_len); + pDest = (command + pPrivData->used_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "REMAINING TRUNCATED BATCH SCAN RESULT:"); + while(count < len) + { + printk("%c", *(pDest + count)); + count++; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: copy %d data to user buffer", __func__, len); + if (copy_to_user(pPrivData->buf, pDest, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + return -EFAULT; + } + } + + return 0; +} /*End of hdd_return_batch_scan_rsp_to_user*/ + +/**--------------------------------------------------------------------------- + + \brief hdd_handle_batch_scan_ioctl () - This function handles WLS_BATCHING + IOCTLs from user space. Following BATCH SCAN DEV IOCTs are handled: + WLS_BATCHING VERSION + WLS_BATCHING SET + WLS_BATCHING GET + WLS_BATCHING STOP + + \param - pAdapter Pointer to HDD adapter + \param - pPrivdata Pointer to priv_data + \param - command Pointer to command + + \return - 0 for success -EFAULT for failure + + --------------------------------------------------------------------------*/ + +int hdd_handle_batch_scan_ioctl +( + hdd_adapter_t *pAdapter, + hdd_priv_data_t *pPrivdata, + tANI_U8 *command +) +{ + int ret = 0; + hdd_context_t *pHddCtx; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) + { + goto exit; + } + + if (strncmp(command, "WLS_BATCHING VERSION", 20) == 0) + { + char extra[32]; + tANI_U8 len = 0; + tANI_U8 version = HDD_BATCH_SCAN_VERSION; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "WLS_BATCHING_VERSION %d", + version); + if (copy_to_user(pPrivdata->buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + ret = HDD_BATCH_SCAN_VERSION; + } + else if (strncmp(command, "WLS_BATCHING SET", 16) == 0) + { + int status; + tANI_U8 *value = (command + 16); + eHalStatus halStatus; + unsigned long rc; + tSirSetBatchScanReq *pReq = &pAdapter->hddSetBatchScanReq; + tSirSetBatchScanRsp *pRsp = &pAdapter->hddSetBatchScanRsp; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if ((WLAN_HDD_INFRA_STATION != pAdapter->device_mode) && + (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) && + (WLAN_HDD_P2P_GO != pAdapter->device_mode) && + (WLAN_HDD_P2P_DEVICE != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received WLS_BATCHING SET command in invalid mode %s (%d) " + "WLS_BATCHING_SET is only allowed in infra STA/P2P client mode", + hdd_device_modetoString(pAdapter->device_mode), + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_set_batchscan_command(value, pReq); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid WLS_BATCHING SET command"); + ret = -EINVAL; + goto exit; + } + + + pAdapter->hdd_wait_for_set_batch_scan_rsp = TRUE; + halStatus = sme_SetBatchScanReq(WLAN_HDD_GET_HAL_CTX(pAdapter), pReq, + pAdapter->sessionId, hdd_set_batch_scan_req_callback, + pAdapter); + + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + char extra[32]; + tANI_U8 len = 0; + tANI_U8 mScan = 0; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "sme_SetBatchScanReq returned success halStatus %d", + halStatus); + if (TRUE == pAdapter->hdd_wait_for_set_batch_scan_rsp) + { + INIT_COMPLETION(pAdapter->hdd_set_batch_scan_req_var); + rc = wait_for_completion_timeout( + &pAdapter->hdd_set_batch_scan_req_var, + msecs_to_jiffies(HDD_SET_BATCH_SCAN_REQ_TIME_OUT)); + if (0 == rc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout waiting for set batch scan to complete", + __func__); + ret = -EINVAL; + goto exit; + } + } + if ( !pRsp->nScansToBatch ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Received set batch scan failure response from FW", + __func__); + ret = -EINVAL; + goto exit; + } + /*As per the Batch Scan Framework API we should return the MIN of + either MSCAN or the max # of scans firmware can cache*/ + mScan = MIN(pReq->numberOfScansToBatch , pRsp->nScansToBatch); + + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STARTED; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: request MSCAN %d response MSCAN %d ret %d", + __func__, pReq->numberOfScansToBatch, pRsp->nScansToBatch, mScan); + len = scnprintf(extra, sizeof(extra), "%d", mScan); + if (copy_to_user(pPrivdata->buf, &extra, len + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy MSCAN value to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_SetBatchScanReq returned failure halStatus %d", + halStatus); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "WLS_BATCHING STOP", 17) == 0) + { + eHalStatus halStatus; + tSirStopBatchScanInd *pInd = &pAdapter->hddStopBatchScanInd; + pInd->param = 0; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Batch scan is not yet enabled batch scan state %d", + pAdapter->batchScanState); + ret = -EINVAL; + goto exit; + } + + mutex_lock(&pAdapter->hdd_batch_scan_lock); + hdd_deinit_batch_scan(pAdapter); + mutex_unlock(&pAdapter->hdd_batch_scan_lock); + + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + + halStatus = sme_StopBatchScanInd(WLAN_HDD_GET_HAL_CTX(pAdapter), pInd, + pAdapter->sessionId); + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + ret = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "sme_StopBatchScanInd returned success halStatus %d", + halStatus); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_StopBatchScanInd returned failure halStatus %d", + halStatus); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "WLS_BATCHING GET", 16) == 0) + { + tANI_U32 remain_len; + + if (FALSE == sme_IsFeatureSupportedByFW(BATCH_SCAN)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Batch scan feature is not supported by FW", __func__); + ret = -EINVAL; + goto exit; + } + + if (eHDD_BATCH_SCAN_STATE_STARTED != pAdapter->batchScanState) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Batch scan is not yet enabled could not return results" + "Batch Scan state %d", + pAdapter->batchScanState); + ret = -EINVAL; + goto exit; + } + + pPrivdata->used_len = 16; + remain_len = pPrivdata->total_len - pPrivdata->used_len; + if (remain_len < pPrivdata->total_len) + { + /*Clear previous batch scan response data if any*/ + vos_mem_zero((tANI_U8 *)(command + pPrivdata->used_len), remain_len); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid total length from user space can't fetch batch" + " scan response total_len %d used_len %d remain len %d", + pPrivdata->total_len, pPrivdata->used_len, remain_len); + ret = -EINVAL; + goto exit; + } + ret = hdd_return_batch_scan_rsp_to_user(pAdapter, pPrivdata, command); + } + +exit: + EXIT(); + return ret; +} + + +#endif/*End of FEATURE_WLAN_BATCH_SCAN*/ + +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/** + * hdd_assign_handoff_src_reassoc - Set handoff source as REASSOC + * to Handoff request + * @handoffInfo: Pointer to Handoff request + * @src: enum of handoff_src + * Return: None + */ +#ifndef QCA_WIFI_ISOC +static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest + *handoffInfo, handoff_src src) +{ + handoffInfo->src = src; +} +#else +static inline void hdd_assign_handoff_src_reassoc(tCsrHandoffRequest + *handoffInfo, handoff_src src) +{ +} +#endif + +/** + * hdd_reassoc() - perform a user space-directed reassoc + * + * @pAdapter: Adapter upon which the command was received + * @bssid: BSSID with which to reassociate + * @channel: channel upon which to reassociate + * @src: The source for the trigger of this action + * + * Return: 0 for success non-zero for failure + */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, + const tANI_U8 channel, const handoff_src src) +{ + hdd_station_ctx_t *pHddStaCtx; + tCsrHandoffRequest handoffInfo; + hdd_context_t *pHddCtx = NULL; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* if not associated, no need to proceed with reassoc */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + hddLog(LOG1, FL("Not associated")); + return -EINVAL; + } + + /* if the target bssid is same as currently associated AP, + then no need to proceed with reassoc */ + if (!memcmp(bssid, pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) { + hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid")); + return -EINVAL; + } + + /* Check channel number is a valid channel number */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter, channel)) { + hddLog(LOGE, FL("Invalid Channel %d"), channel); + return -EINVAL; + } + + /* Proceed with reassoc */ + handoffInfo.channel = channel; + hdd_assign_handoff_src_reassoc(&handoffInfo, src); + memcpy(handoffInfo.bssid, bssid, sizeof(tSirMacAddr)); + sme_HandoffRequest(pHddCtx->hHal, &handoffInfo); + return 0; +} +#else +int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, + const tANI_U8 channel, const handoff_src src) +{ + return -EPERM; +} +#endif + +/** + * hdd_parse_reassoc_v1() - parse version 1 of the REASSOC command + * This function parses the v1 REASSOC command with the format + * REASSOC xx:xx:xx:xx:xx:xx CH where "xx:xx:xx:xx:xx:xx" is the + * Hex-ASCII representation of the BSSID and CH is the ASCII + * representation of the channel. For example + * REASSOC 00:0a:0b:11:22:33 48 + * + * @pAdapter: Adapter upon which the command was received + * @command: ASCII text command that was received + * + * Return: 0 for success non-zero for failure + */ +static int +hdd_parse_reassoc_v1(hdd_adapter_t *pAdapter, const char *command) +{ + tANI_U8 channel = 0; + tSirMacAddr bssid; + int ret; + + ret = hdd_parse_reassoc_command_v1_data(command, bssid, &channel); + if (ret) + hddLog(LOGE, FL("Failed to parse reassoc command data")); + else + ret = hdd_reassoc(pAdapter, bssid, channel, REASSOC); + + return ret; +} + +/** + * hdd_parse_reassoc_v2() - parse version 2 of the REASSOC command + * This function parses the v2 REASSOC command with the format + * REASSOC + * + * @pAdapter: Adapter upon which the command was received + * @command: command that was received, ASCII command followed + * by binary data + * @total_len: Total length of the command received + * + * Return: 0 for success non-zero for failure + */ +static int +hdd_parse_reassoc_v2(hdd_adapter_t *pAdapter, const char *command, + int total_len) +{ + struct android_wifi_reassoc_params params; + tSirMacAddr bssid; + int ret; + + if (total_len < sizeof(params) + 8) { + hddLog(LOGE, FL("Invalid command length")); + return -EINVAL; + } + + /* The params are located after "REASSOC " */ + memcpy(¶ms, command + 8, sizeof(params)); + + if (!mac_pton(params.bssid, (u8 *)&bssid)) { + hddLog(LOGE, FL("MAC address parsing failed")); + ret = -EINVAL; + } else { + ret = hdd_reassoc(pAdapter, bssid, params.channel, REASSOC); + } + return ret; +} + +/** + * hdd_parse_reassoc() - parse the REASSOC command + * There are two different versions of the REASSOC command.Version 1 + * of the command contains a parameter list that is ASCII characters + * whereas version 2 contains a combination of ASCII and binary + * payload. Determine if a version 1 or a version 2 command is being + * parsed by examining the parameters, and then dispatch the parser + * that is appropriate for the command. + * + * @pAdapter: Adapter upon which the command was received + * @command: command that was received + * @total_len: Total length of the command received + * + * Return: 0 for success non-zero for failure + */ +static int +hdd_parse_reassoc(hdd_adapter_t *pAdapter, const char *command, int total_len) +{ + int ret; + + /* + * both versions start with "REASSOC" + * v1 has a bssid and channel # as an ASCII string + * REASSOC xx:xx:xx:xx:xx:xx CH + * v2 has a C struct + * REASSOC + * + * The first field in the v2 struct is also the bssid in ASCII. + * But in the case of a v2 message the BSSID is NUL-terminated. + * Hence we can peek at that offset to see if this is V1 or V2 + * REASSOC xx:xx:xx:xx:xx:xx* + * 1111111111222222 + * 01234567890123456789012345 + */ + + if (total_len < 26) { + hddLog(LOGE, FL("Invalid command (total_len=%d)"), total_len); + return -EINVAL; + } + + if (command[25]) + ret = hdd_parse_reassoc_v1(pAdapter, command); + else + ret = hdd_parse_reassoc_v2(pAdapter, command, total_len); + + return ret; +} +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE FEATURE_WLAN_LFR */ + +static void getBcnMissRateCB(VOS_STATUS status, int bcnMissRate, void *data) +{ + bcnMissRateContext_t *pCBCtx; + + if (NULL == data) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL")); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + pCBCtx = (bcnMissRateContext_t *)data; + gbcnMissRate = -1; + + if (pCBCtx->magic != BCN_MISS_RATE_CONTEXT_MAGIC) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid context magic: %08x"), pCBCtx->magic); + spin_unlock(&hdd_context_lock); + return ; + } + + if (VOS_STATUS_SUCCESS == status) + { + gbcnMissRate = bcnMissRate; + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("failed to get bcnMissRate")); + } + + complete(&(pCBCtx->completion)); + spin_unlock(&hdd_context_lock); + + return; +} + +void hdd_FWStatisCB( VOS_STATUS status, + tSirFwStatsResult *fwStatsResult, void *pContext ) +{ + fwStatsContext_t *fwStatsCtx; + hdd_adapter_t *pAdapter; + + hddLog(VOS_TRACE_LEVEL_INFO, FL(" with status = %d"),status); + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("argument data is NULL")); + return; + } + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + fwStatsCtx = (fwStatsContext_t *) pContext; + if (fwStatsCtx->magic != FW_STATS_CONTEXT_MAGIC) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid context magic: %08x"), fwStatsCtx->magic); + spin_unlock(&hdd_context_lock); + return; + } + pAdapter = fwStatsCtx->pAdapter; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("pAdapter returned is NULL or invalid")); + spin_unlock(&hdd_context_lock); + return; + } + pAdapter->fwStatsRsp.type = 0; + if ((VOS_STATUS_SUCCESS == status) && (NULL != fwStatsResult)) + { + switch( fwStatsResult->type ) + { + case FW_UBSP_STATS: + { + memcpy(&pAdapter->fwStatsRsp,fwStatsResult,sizeof(tSirFwStatsResult)); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("ubsp_enter_cnt = %d ubsp_jump_ddr_cnt = %d"), + pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_enter_cnt, + pAdapter->fwStatsRsp.fwStatsData.ubspStats.ubsp_jump_ddr_cnt); + } + break; + default: + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL(" No handling for stats type %d"),fwStatsResult->type); + } + } + } + complete(&(fwStatsCtx->completion)); + spin_unlock(&hdd_context_lock); + return; +} + +/* + *hdd_parse_setmaxtxpower_command() - HDD Parse MAXTXPOWER command + *@pValue Pointer to MAXTXPOWER command + *@pTxPower Pointer to tx power + * + *This function parses the MAXTXPOWER command passed in the format + * MAXTXPOWERX(Tx power in dbm) + * For example input commands: + * 1) MAXTXPOWER -8 -> This is translated into set max TX power to -8 dbm + * 2) MAXTXPOWER -23 -> This is translated into set max TX power to -23 dbm + * + *return - 0 for success non-zero for failure + */ +static int hdd_parse_setmaxtxpower_command(unsigned char *pValue, int *pTxPower) +{ + unsigned char *inPtr = pValue; + int tempInt; + int v = 0; + *pTxPower = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /* no argument after the command */ + if (NULL == inPtr) + return -EINVAL; + /* no space after the command */ + else if (SPACE_ASCII_VALUE != *inPtr) + return -EINVAL; + + /* removing empty spaces */ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /* no argument followed by spaces */ + if ('\0' == *inPtr) + return 0; + + v = kstrtos32(inPtr, 10, &tempInt); + + /* Range checking for passed parameter */ + if ((tempInt < HDD_MIN_TX_POWER) || (tempInt > HDD_MAX_TX_POWER)) + return -EINVAL; + + *pTxPower = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SETMAXTXPOWER: %d", *pTxPower); + + return 0; +} + +static int hdd_get_dwell_time(hdd_config_t *pCfg, tANI_U8 *command, char *extra, tANI_U8 n, tANI_U8 *len) +{ + int ret = 0; + + if (!pCfg || !command || !extra || !len) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passsed for GETDWELLTIME is incorrect", __func__); + ret = -EINVAL; + return ret; + } + + if (strncmp(command, "GETDWELLTIME ACTIVE MAX", 23) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MAX %u\n", + (int)pCfg->nActiveMaxChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME ACTIVE MIN", 23) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME ACTIVE MIN %u\n", + (int)pCfg->nActiveMinChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME PASSIVE MAX", 24) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MAX %u\n", + (int)pCfg->nPassiveMaxChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME PASSIVE MIN", 24) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME PASSIVE MIN %u\n", + (int)pCfg->nPassiveMinChnTime); + return ret; + } + else if (strncmp(command, "GETDWELLTIME", 12) == 0) + { + *len = scnprintf(extra, n, "GETDWELLTIME %u \n", + (int)pCfg->nActiveMaxChnTime); + return ret; + } + else + { + ret = -EINVAL; + } + + return ret; +} + +int hdd_drv_cmd_validate(tANI_U8 *command, int len) +{ + if (command[len] != ' ') + return -EINVAL; + + return 0; +} + +static int hdd_set_dwell_time(hdd_adapter_t *pAdapter, tANI_U8 *command) +{ + tHalHandle hHal; + hdd_config_t *pCfg; + tANI_U8 *value = command; + int val = 0, ret = 0, temp = 0; + tSmeConfigParams smeConfig; + + if (!pAdapter || !command || !(pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini) + || !(hHal = (WLAN_HDD_GET_HAL_CTX(pAdapter)))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME is incorrect", __func__); + ret = -EINVAL; + return ret; + } + + vos_mem_zero(&smeConfig, sizeof(smeConfig)); + sme_GetConfigParam(hHal, &smeConfig); + + if (strncmp(command, "SETDWELLTIME ACTIVE MAX", 23) == 0 ) + { + if (hdd_drv_cmd_validate(command, 23)) + return -EINVAL; + + value = value + 24; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN || + val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME ACTIVE MAX is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nActiveMaxChnTime = val; + smeConfig.csrConfig.nActiveMaxChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME ACTIVE MIN", 23) == 0) + { + if (hdd_drv_cmd_validate(command, 23)) + return -EINVAL; + + value = value + 24; + temp = kstrtou32(value, 10, &val); + if (temp !=0 || val < CFG_ACTIVE_MIN_CHANNEL_TIME_MIN || + val > CFG_ACTIVE_MIN_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passsed for SETDWELLTIME ACTIVE MIN is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nActiveMinChnTime = val; + smeConfig.csrConfig.nActiveMinChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME PASSIVE MAX", 24) == 0) + { + if (hdd_drv_cmd_validate(command, 24)) + return -EINVAL; + + value = value + 25; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_PASSIVE_MAX_CHANNEL_TIME_MIN || + val > CFG_PASSIVE_MAX_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME PASSIVE MAX is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nPassiveMaxChnTime = val; + smeConfig.csrConfig.nPassiveMaxChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME PASSIVE MIN", 24) == 0) + { + if (hdd_drv_cmd_validate(command, 24)) + return -EINVAL; + + value = value + 25; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_PASSIVE_MIN_CHANNEL_TIME_MIN || + val > CFG_PASSIVE_MIN_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME PASSIVE MIN is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nPassiveMinChnTime = val; + smeConfig.csrConfig.nPassiveMinChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else if (strncmp(command, "SETDWELLTIME", 12) == 0) + { + if (hdd_drv_cmd_validate(command, 12)) + return -EINVAL; + + value = value + 13; + temp = kstrtou32(value, 10, &val); + if (temp != 0 || val < CFG_ACTIVE_MAX_CHANNEL_TIME_MIN || + val > CFG_ACTIVE_MAX_CHANNEL_TIME_MAX ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: argument passed for SETDWELLTIME is incorrect", __func__); + ret = -EFAULT; + return ret; + } + pCfg->nActiveMaxChnTime = val; + smeConfig.csrConfig.nActiveMaxChnTime = val; + sme_UpdateConfig(hHal, &smeConfig); + } + else + { + ret = -EINVAL; + } + + return ret; +} +static int hdd_cmd_setFccChannel(hdd_context_t *pHddCtx, tANI_U8 *cmd, + tANI_U8 cmd_len) +{ + tANI_U8 *value; + tANI_U8 fcc_constraint; + + eHalStatus status; + int ret = 0; + value = cmd + cmd_len + 1; + + ret = kstrtou8(value, 10, &fcc_constraint); + if ((ret < 0) || (fcc_constraint > 1)) { + /* + * If the input value is greater than max value of datatype, + * then also it is a failure + */ + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: value out of range", __func__); + return -EINVAL; + } + + status = sme_handleSetFccChannel(pHddCtx->hHal, fcc_constraint, + pHddCtx->scan_info.mScanPending); + if (status != eHAL_STATUS_SUCCESS) + ret = -EPERM; + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_enable_disable_ca_event() - When Host sends IOCTL (enabled), + FW will send *ONE* CA ind to Host(even though it is duplicate). + When Host send IOCTL (disable), FW doesn't perform any action. + Whenever any change in CA *and* WLAN is in SAP/P2P-GO mode, FW + sends CA ind to host. (regard less of IOCTL status) + \param - pHddCtx - HDD context + \param - command - command received from framework + \param - cmd_len - len of the command + + \return - 0 on success, appropriate error values on failure. + + --------------------------------------------------------------------------*/ +int hdd_enable_disable_ca_event(hdd_context_t *pHddCtx, tANI_U8* command, tANI_U8 cmd_len) +{ + tANI_U8 set_value; + int ret = 0; + eHalStatus status; + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + ret = -EINVAL; + goto exit; + } + + if (pHddCtx->cfg_ini->gOptimizeCAevent == 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "Enable gOptimizeCAevent" + " ini param to control channel avooidance indication"); + ret = 0; + goto exit; + } + + set_value = command[cmd_len + 1] - '0'; + status = sme_enableDisableChanAvoidIndEvent(pHddCtx->hHal, set_value); + if (status != eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to send" + " enableDisableChanAoidance command to SME\n", __func__); + ret = -EINVAL; + } + +exit: + return ret; +} + +/** + * wlan_hdd_fastreassoc_handoff_request() - Post Handoff request to SME + * @pHddCtx: Pointer to the HDD context + * @channel: channel to reassociate + * @targetApBssid: Target AP/BSSID to reassociate + * + * Return: None + */ +#if defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) && !defined(QCA_WIFI_ISOC) +static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx, + uint8_t channel, tSirMacAddr targetApBssid) +{ + tCsrHandoffRequest handoffInfo; + handoffInfo.channel = channel; + handoffInfo.src = FASTREASSOC; + vos_mem_copy(handoffInfo.bssid, targetApBssid, sizeof(tSirMacAddr)); + sme_HandoffRequest(pHddCtx->hHal, &handoffInfo); +} +#else +static void wlan_hdd_fastreassoc_handoff_request(hdd_context_t *pHddCtx, + uint8_t channel, tSirMacAddr targetApBssid) +{ +} +#endif + +/** + * csr_fastroam_neighbor_ap_event() - Function to trigger scan/roam + * @pAdapter: Pointer to HDD adapter + * @channel: Channel to scan/roam + * @targetApBssid: BSSID to roam + * + * Return: None + */ +#ifdef QCA_WIFI_ISOC +static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter, + uint8_t channel, tSirMacAddr targetApBssid) +{ + smeIssueFastRoamNeighborAPEvent(WLAN_HDD_GET_HAL_CTX(pAdapter), + &targetApBssid[0], eSME_ROAM_TRIGGER_SCAN, channel); +} +#else +static void csr_fastroam_neighbor_ap_event(hdd_adapter_t *pAdapter, + uint8_t channel, tSirMacAddr targetApBssid) +{ +} +#endif + +/** + * wlan_hdd_handle_fastreassoc() - Handle fastreassoc command + * @pAdapter: pointer to hdd adapter + * @command: pointer to the command received + * + * Return: VOS_STATUS enum + */ +static VOS_STATUS wlan_hdd_handle_fastreassoc(hdd_adapter_t *pAdapter, + uint8_t *command) +{ + tANI_U8 *value = command; + tANI_U8 channel = 0; + tSirMacAddr targetApBssid; + hdd_station_ctx_t *pHddStaCtx = NULL; + hdd_context_t *pHddCtx = NULL; + int ret; + tCsrRoamModifyProfileFields mod_profile_fields; + uint32_t roam_id = 0; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + /* if not associated, no need to proceed with reassoc */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + hddLog(LOG1, FL("Not associated!")); + return eHAL_STATUS_FAILURE; + } + + ret = hdd_parse_reassoc_command_v1_data(value, targetApBssid, &channel); + if (ret) { + hddLog(LOGE, FL("Failed to parse reassoc command data")); + return eHAL_STATUS_FAILURE; + } + + /* if the target bssid is same as currently associated AP, + then no need to proceed with reassoc */ + if (vos_mem_compare(targetApBssid, + pHddStaCtx->conn_info.bssId, + sizeof(tSirMacAddr))) { + sme_GetModifyProfileFields(pHddCtx->hHal, pAdapter->sessionId, + &mod_profile_fields); + sme_RoamReassoc(pHddCtx->hHal, pAdapter->sessionId, NULL, + mod_profile_fields, &roam_id, 1); + hddLog(LOG1, FL("Reassoc BSSID is same as currently associated AP bssid")); + return eHAL_STATUS_SUCCESS; + } + + /* Check channel number is a valid channel number */ + if (VOS_STATUS_SUCCESS != + wlan_hdd_validate_operation_channel(pAdapter, channel)) { + hddLog(LOGE, FL("Invalid Channel [%d]"), channel); + return eHAL_STATUS_FAILURE; + } + + /* Proceed with reassoc */ + wlan_hdd_fastreassoc_handoff_request(pHddCtx, channel, targetApBssid); + + /* Proceed with scan/roam */ + csr_fastroam_neighbor_ap_event(pAdapter, channel, targetApBssid); + + return eHAL_STATUS_SUCCESS; +} + +/** + * hdd_assign_reassoc_handoff - Set handoff source as REASSOC + * @handoffInfo: Pointer to the csr Handoff Request. + * + * Return: None + */ +#ifndef QCA_WIFI_ISOC +static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo) +{ + handoffInfo->src = REASSOC; +} +#else +static inline void hdd_assign_reassoc_handoff(tCsrHandoffRequest *handoffInfo) +{ +} +#endif + +static int hdd_driver_command(hdd_adapter_t *pAdapter, + hdd_priv_data_t *ppriv_data) +{ + hdd_priv_data_t priv_data; + tANI_U8 *command = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_scaninfo_t *pScanInfo = NULL; + int ret = 0; + int status; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + struct cfg80211_mgmt_tx_params params; +#endif + + ENTER(); + /* + * Note that valid pointers are provided by caller + */ + + /* copy to local struct to avoid numerous changes to legacy code */ + priv_data = *ppriv_data; + + if (priv_data.total_len <= 0 || + priv_data.total_len > WLAN_PRIV_DATA_MAX_LEN) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s:invalid priv_data.total_len(%d)!!!", __func__, + priv_data.total_len); + ret = -EINVAL; + goto exit; + } + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + ret = -EINVAL; + goto exit; + } + /* Allocate +1 for '\0' */ + command = kmalloc(priv_data.total_len + 1, GFP_KERNEL); + if (!command) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to allocate memory", __func__); + ret = -ENOMEM; + goto exit; + } + + if (copy_from_user(command, priv_data.buf, priv_data.total_len)) + { + ret = -EFAULT; + goto exit; + } + + /* Make sure the command is NUL-terminated */ + command[priv_data.total_len] = '\0'; + + /* at one time the following block of code was conditional. braces + * have been retained to avoid re-indenting the legacy code + */ + { + hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received %s cmd from Wi-Fi GUI***", __func__, command); + + if (strncmp(command, "P2P_DEV_ADDR", 12) == 0 ) + { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL, + pAdapter->sessionId, (unsigned) + (*(pHddCtx->p2pDeviceAddress.bytes+2)<<24 | + *(pHddCtx->p2pDeviceAddress.bytes+3)<<16 | + *(pHddCtx->p2pDeviceAddress.bytes+4)<<8 | + *(pHddCtx->p2pDeviceAddress.bytes+5)))); + if (copy_to_user(priv_data.buf, pHddCtx->p2pDeviceAddress.bytes, + sizeof(tSirMacAddr))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + } + } + else if(strncmp(command, "SETBAND", 7) == 0) + { + tANI_U8 *ptr = command ; + + ret = hdd_drv_cmd_validate(command, 7); + if (ret) + goto exit; + + /* Change band request received */ + + /* First 8 bytes will have "SETBAND " and + * 9 byte will have band setting value */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: SetBandCommand Info comm %s UL %d, TL %d", __func__, command, priv_data.used_len, priv_data.total_len); + if(VOS_FTM_MODE != hdd_get_conparam()) + { + /* Change band request received */ + ret = hdd_setBand_helper(pAdapter->dev, ptr); + if(ret < 0) + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to set band ret=%d", __func__, ret); + } + } + else if(strncmp(command, "SETWMMPS", 8) == 0) + { + tANI_U8 *ptr = command; + + ret = hdd_drv_cmd_validate(command, 8); + if (ret) + goto exit; + + ret = hdd_wmmps_helper(pAdapter, ptr); + } + + else if(strncmp(command, "TDLSSCAN", 8) == 0) + { + tANI_U8 *ptr = command; + + ret = hdd_drv_cmd_validate(command, 8); + if (ret) + goto exit; + + ret = hdd_set_tdls_scan_type(pAdapter, ptr); + } + + else if ( strncasecmp(command, "COUNTRY", 7) == 0 ) + { + char *country_code; + + ret = hdd_drv_cmd_validate(command, 7); + if (ret) + goto exit; + + country_code = command + 8; + + INIT_COMPLETION(pAdapter->change_country_code); + hdd_checkandupdate_dfssetting(pAdapter, country_code); +#ifndef CONFIG_ENABLE_LINUX_REG + hdd_checkandupdate_phymode(pAdapter, country_code); +#endif + ret = (int)sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + wlan_hdd_change_country_code_callback, + country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE); + if (eHAL_STATUS_SUCCESS == ret) + { + ret = wait_for_completion_interruptible_timeout( + &pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + if (0 >= ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME while setting country code timed out %d", + __func__, ret); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: SME Change Country code fail ret=%d", __func__, ret); + ret = -EINVAL; + } + + } + /* + command should be a string having format + SET_SAP_CHANNEL_LIST + */ + else if(strncmp(command, "SET_SAP_CHANNEL_LIST", 20) == 0) + { + tANI_U8 *ptr = command; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + " Received Command to Set Preferred Channels for SAP in %s", __func__); + + ret = sapSetPreferredChannel(ptr); + } + else if(strncmp(command, "SETSUSPENDMODE", 14) == 0) + { + int suspend = 0; + tANI_U8 *ptr; + + ret = hdd_drv_cmd_validate(command, 14); + if (ret) + goto exit; + + ptr = (tANI_U8*)command + 15; + + suspend = *ptr - '0'; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL, + pAdapter->sessionId, suspend)); + hdd_set_wlan_suspend_mode(suspend); + } +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + else if (strncmp(command, "SETROAMTRIGGER", 14) == 0) + { + tANI_U8 *value = command; + tANI_S8 rssi = 0; + tANI_U8 lookUpThreshold = CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_DEFAULT; + eHalStatus status = eHAL_STATUS_SUCCESS; + + ret = hdd_drv_cmd_validate(command, 14); + if (ret) + goto exit; + + /* Move pointer to ahead of SETROAMTRIGGER */ + value = value + 15; + + /* Convert the value from ascii to integer */ + ret = kstrtos8(value, 10, &rssi); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed Input value may be out of range[%d - %d]", + __func__, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX); + ret = -EINVAL; + goto exit; + } + + lookUpThreshold = abs(rssi); + + if ((lookUpThreshold < CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN) || + (lookUpThreshold > CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Neighbor lookup threshold value %d is out of range" + " (Min: %d Max: %d)", lookUpThreshold, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MIN, + CFG_NEIGHBOR_LOOKUP_RSSI_THRESHOLD_MAX); + ret = -EINVAL; + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL, + pAdapter->sessionId, lookUpThreshold)); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Roam trigger" + " (Neighbor lookup threshold) = %d", __func__, lookUpThreshold); + + pHddCtx->cfg_ini->nNeighborLookupRssiThreshold = lookUpThreshold; + status = sme_setNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to set roam trigger, try again", __func__); + ret = -EPERM; + goto exit; + } + + /* Set Reassoc threshold to (lookup rssi threshold + 5 dBm) */ + pHddCtx->cfg_ini->nNeighborReassocRssiThreshold = lookUpThreshold + 5; + sme_setNeighborReassocRssiThreshold((tHalHandle)(pHddCtx->hHal), lookUpThreshold + 5); + } + else if (strncmp(command, "GETROAMTRIGGER", 14) == 0) + { + tANI_U8 lookUpThreshold = sme_getNeighborLookupRssiThreshold((tHalHandle)(pHddCtx->hHal)); + int rssi = (-1) * lookUpThreshold; + char extra[32]; + tANI_U8 len = 0; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL, + pAdapter->sessionId, lookUpThreshold)); + len = scnprintf(extra, sizeof(extra), "%s %d", command, rssi); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANPERIOD", 17) == 0) + { + tANI_U8 *value = command; + tANI_U8 roamScanPeriod = 0; + tANI_U16 neighborEmptyScanRefreshPeriod = CFG_EMPTY_SCAN_REFRESH_PERIOD_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 17); + if (ret) + goto exit; + + /* input refresh period is in terms of seconds */ + /* Move pointer to ahead of SETROAMSCANPERIOD */ + value = value + 18; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamScanPeriod); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed Input value may be out of range[%d - %d]", + __func__, + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000), + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + + if ((roamScanPeriod < (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000)) || + (roamScanPeriod > (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam scan period value %d is out of range" + " (Min: %d Max: %d)", roamScanPeriod, + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MIN/1000), + (CFG_EMPTY_SCAN_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL, + pAdapter->sessionId, roamScanPeriod)); + neighborEmptyScanRefreshPeriod = roamScanPeriod * 1000; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam scan period" + " (Empty Scan refresh period) = %d", __func__, roamScanPeriod); + + pHddCtx->cfg_ini->nEmptyScanRefreshPeriod = neighborEmptyScanRefreshPeriod; + sme_UpdateEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborEmptyScanRefreshPeriod); + } + else if (strncmp(command, "GETROAMSCANPERIOD", 17) == 0) + { + tANI_U16 nEmptyScanRefreshPeriod = sme_getEmptyScanRefreshPeriod((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL, + pAdapter->sessionId, nEmptyScanRefreshPeriod)); + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMSCANPERIOD", (nEmptyScanRefreshPeriod/1000)); + /* Returned value is in units of seconds */ + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANREFRESHPERIOD", 24) == 0) + { + tANI_U8 *value = command; + tANI_U8 roamScanRefreshPeriod = 0; + tANI_U16 neighborScanRefreshPeriod = CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 24); + if (ret) + goto exit; + + /* input refresh period is in terms of seconds */ + /* Move pointer to ahead of SETROAMSCANREFRESHPERIOD */ + value = value + 25; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamScanRefreshPeriod); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed Input value may be out of range[%d - %d]", + __func__, + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000), + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + + if ((roamScanRefreshPeriod < (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000)) || + (roamScanRefreshPeriod > (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Neighbor scan results refresh period value %d is out of range" + " (Min: %d Max: %d)", roamScanRefreshPeriod, + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MIN/1000), + (CFG_NEIGHBOR_SCAN_RESULTS_REFRESH_PERIOD_MAX/1000)); + ret = -EINVAL; + goto exit; + } + neighborScanRefreshPeriod = roamScanRefreshPeriod * 1000; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam scan refresh period" + " (Scan refresh period) = %d", __func__, roamScanRefreshPeriod); + + pHddCtx->cfg_ini->nNeighborResultsRefreshPeriod = neighborScanRefreshPeriod; + sme_setNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal), neighborScanRefreshPeriod); + } + else if (strncmp(command, "GETROAMSCANREFRESHPERIOD", 24) == 0) + { + tANI_U16 value = sme_getNeighborScanRefreshPeriod((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMSCANREFRESHPERIOD", (value/1000)); + /* Returned value is in units of seconds */ + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#ifdef FEATURE_WLAN_LFR + /* SETROAMMODE */ + else if (strncmp(command, "SETROAMMODE", SIZE_OF_SETROAMMODE) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN roamMode = CFG_LFR_FEATURE_ENABLED_DEFAULT; + + ret = hdd_drv_cmd_validate(command, SIZE_OF_SETROAMMODE); + if (ret) + goto exit; + + /* Move pointer to ahead of SETROAMMODE */ + value = value + SIZE_OF_SETROAMMODE + 1; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, SIZE_OF_SETROAMMODE, &roamMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + if ((roamMode < CFG_LFR_FEATURE_ENABLED_MIN) || + (roamMode > CFG_LFR_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam Mode value %d is out of range" + " (Min: %d Max: %d)", roamMode, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set Roam Mode = %d", __func__, roamMode); + /* + * Note that + * SETROAMMODE 0 is to enable LFR while + * SETROAMMODE 1 is to disable LFR, but + * NotifyIsFastRoamIniFeatureEnabled 0/1 is to enable/disable. + * So, we have to invert the value to call sme_UpdateIsFastRoamIniFeatureEnabled. + */ + if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode) + roamMode = CFG_LFR_FEATURE_ENABLED_MAX; /* Roam enable */ + else + roamMode = CFG_LFR_FEATURE_ENABLED_MIN; /* Roam disable */ + + pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = roamMode; + sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), roamMode); + } + /* GETROAMMODE */ + else if (strncmp(command, "GETROAMMODE", SIZE_OF_GETROAMMODE) == 0) + { + tANI_BOOLEAN roamMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + /* + * roamMode value shall be inverted because the sementics is different. + */ + if (CFG_LFR_FEATURE_ENABLED_MIN == roamMode) + roamMode = CFG_LFR_FEATURE_ENABLED_MAX; + else + roamMode = CFG_LFR_FEATURE_ENABLED_MIN; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, roamMode); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#endif +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + else if (strncmp(command, "SETROAMDELTA", 12) == 0) + { + tANI_U8 *value = command; + tANI_U8 roamRssiDiff = CFG_ROAM_RSSI_DIFF_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 12); + if (ret) + goto exit; + + /* Move pointer to ahead of SETROAMDELTA */ + value = value + 13; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamRssiDiff); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_RSSI_DIFF_MIN, + CFG_ROAM_RSSI_DIFF_MAX); + ret = -EINVAL; + goto exit; + } + + if ((roamRssiDiff < CFG_ROAM_RSSI_DIFF_MIN) || + (roamRssiDiff > CFG_ROAM_RSSI_DIFF_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam rssi diff value %d is out of range" + " (Min: %d Max: %d)", roamRssiDiff, + CFG_ROAM_RSSI_DIFF_MIN, + CFG_ROAM_RSSI_DIFF_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam rssi diff = %d", __func__, roamRssiDiff); + + pHddCtx->cfg_ini->RoamRssiDiff = roamRssiDiff; + sme_UpdateRoamRssiDiff((tHalHandle)(pHddCtx->hHal), roamRssiDiff); + } + else if (strncmp(command, "GETROAMDELTA", 12) == 0) + { + tANI_U8 roamRssiDiff = sme_getRoamRssiDiff((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMDELTA_IOCTL, + pAdapter->sessionId, roamRssiDiff)); + len = scnprintf(extra, sizeof(extra), "%s %d", + command, roamRssiDiff); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + else if (strncmp(command, "GETBAND", 7) == 0) + { + int band = -1; + char extra[32]; + tANI_U8 len = 0; + hdd_getBand_helper(pHddCtx, &band); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETBAND_IOCTL, + pAdapter->sessionId, band)); + len = scnprintf(extra, sizeof(extra), "%s %d", command, band); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANCHANNELS", 19) == 0) + { + tANI_U8 *value = command; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 numChannels = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = hdd_parse_channellist(value, ChannelList, &numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse channel list information", __func__); + ret = -EINVAL; + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL, + pAdapter->sessionId, numChannels)); + if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: number of channels (%d) supported exceeded max (%d)", __func__, + numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN); + ret = -EINVAL; + goto exit; + } + status = sme_ChangeRoamScanChannelList((tHalHandle)(pHddCtx->hHal), ChannelList, + numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update channel list information", __func__); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "GETROAMSCANCHANNELS", 19) == 0) + { + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 numChannels = 0; + tANI_U8 j = 0; + char extra[128] = {0}; + int len; + + if (eHAL_STATUS_SUCCESS != sme_getRoamScanChannelList( (tHalHandle)(pHddCtx->hHal), + ChannelList, &numChannels )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: failed to get roam scan channel list", __func__); + ret = -EFAULT; + goto exit; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL, + pAdapter->sessionId, numChannels)); + /* output channel list is of the format + [Number of roam scan channels][Channel1][Channel2]... */ + /* copy the number of channels in the 0th index */ + len = scnprintf(extra, sizeof(extra), "%s %d", command, numChannels); + for (j = 0; (j < numChannels) && len <= sizeof(extra); j++) + { + len += scnprintf(extra + len, sizeof(extra) - len, " %d", + ChannelList[j]); + } + + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETCCXMODE", 10) == 0) + { + tANI_BOOLEAN eseMode = sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (eseMode && + hdd_is_okc_mode_enabled(pHddCtx) && + sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETCCXMODE", eseMode); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETOKCMODE", 10) == 0) + { + tANI_BOOLEAN okcMode = hdd_is_okc_mode_enabled(pHddCtx); + char extra[32]; + tANI_U8 len = 0; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (okcMode && + sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) && + sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETOKCMODE", okcMode); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETFASTROAM", 11) == 0) + { + tANI_BOOLEAN lfrMode = sme_getIsLfrFeatureEnabled((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETFASTROAM", lfrMode); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "GETFASTTRANSITION", 17) == 0) + { + tANI_BOOLEAN ft = sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETFASTTRANSITION", ft); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMSCANCHANNELMINTIME", 25) == 0) + { + tANI_U8 *value = command; + tANI_U8 minTime = CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 25); + if (ret) + goto exit; + + /* Move pointer to ahead of SETROAMSCANCHANNELMINTIME */ + value = value + 26; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &minTime); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + if ((minTime < CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN) || + (minTime > CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "scan min channel time value %d is out of range" + " (Min: %d Max: %d)", minTime, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MIN_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL, + pAdapter->sessionId, minTime)); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change channel min time = %d", __func__, minTime); + + pHddCtx->cfg_ini->nNeighborScanMinChanTime = minTime; + sme_setNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal), minTime); + } + else if (strncmp(command, "SENDACTIONFRAME", 15) == 0) + { + tANI_U8 *value = command; + tANI_U8 channel = 0; + tANI_U8 dwellTime = 0; + tANI_U8 bufLen = 0; + tANI_U8 *buf = NULL; + tSirMacAddr targetApBssid; + eHalStatus status = eHAL_STATUS_SUCCESS; + struct ieee80211_channel chan; + tANI_U8 finalLen = 0; + tANI_U8 *finalBuf = NULL; + tANI_U8 temp = 0; + u64 cookie; + hdd_station_ctx_t *pHddStaCtx = NULL; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* if not associated, no need to send action frame */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_send_action_frame_data(value, targetApBssid, &channel, + &dwellTime, &buf, &bufLen); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse send action frame data", __func__); + ret = -EINVAL; + goto exit; + } + + /* if the target bssid is different from currently associated AP, + then no need to send action frame */ + if (VOS_TRUE != vos_mem_compare(targetApBssid, + pHddStaCtx->conn_info.bssId, sizeof(tSirMacAddr))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:STA is not associated to this AP!",__func__); + ret = -EINVAL; + vos_mem_free(buf); + buf = NULL; + goto exit; + } + + /* if the channel number is different from operating channel then + no need to send action frame */ + if (channel != pHddStaCtx->conn_info.operationChannel) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: channel(%d) is different from operating channel(%d)", + __func__, channel, pHddStaCtx->conn_info.operationChannel); + ret = -EINVAL; + vos_mem_free(buf); + buf = NULL; + goto exit; + } + chan.center_freq = sme_ChnToFreq(channel); + + finalLen = bufLen + 24; + finalBuf = vos_mem_malloc(finalLen); + if (NULL == finalBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:memory allocation failed",__func__); + ret = -ENOMEM; + vos_mem_free(buf); + buf = NULL; + goto exit; + } + vos_mem_zero(finalBuf, finalLen); + + /* Fill subtype */ + temp = SIR_MAC_MGMT_ACTION << 4; + vos_mem_copy(finalBuf + 0, &temp, sizeof(temp)); + + /* Fill type */ + temp = SIR_MAC_MGMT_FRAME; + vos_mem_copy(finalBuf + 2, &temp, sizeof(temp)); + + /* Fill destination address (bssid of the AP) */ + vos_mem_copy(finalBuf + 4, targetApBssid, sizeof(targetApBssid)); + + /* Fill source address (STA mac address) */ + vos_mem_copy(finalBuf + 10, pAdapter->macAddressCurrent.bytes, sizeof(pAdapter->macAddressCurrent.bytes)); + + /* Fill BSSID (AP mac address) */ + vos_mem_copy(finalBuf + 16, targetApBssid, sizeof(targetApBssid)); + + /* Fill received buffer from 24th address */ + vos_mem_copy(finalBuf + 24, buf, bufLen); + + /* done with the parsed buffer */ + vos_mem_free(buf); + buf = NULL; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + params.chan = &chan; + params.offchan = 0; + params.wait = dwellTime; + params.buf = finalBuf; + params.len = finalLen; + params.no_cck = 1; + params.dont_wait_for_ack = 1; + ret = wlan_hdd_mgmt_tx(NULL, &pAdapter->wdev, ¶ms, &cookie); +#else + wlan_hdd_mgmt_tx( NULL, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + &(pAdapter->wdev), +#else + pAdapter->dev, +#endif + &chan, 0, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + NL80211_CHAN_HT20, 1, +#endif + dwellTime, finalBuf, finalLen, 1, + 1, &cookie ); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)*/ + vos_mem_free(finalBuf); + } + else if (strncmp(command, "GETROAMSCANCHANNELMINTIME", 25) == 0) + { + tANI_U16 val = sme_getNeighborScanMinChanTime((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMSCANCHANNELMINTIME", val); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL, + pAdapter->sessionId, val)); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANCHANNELTIME", 18) == 0) + { + tANI_U8 *value = command; + tANI_U16 maxTime = CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 18); + if (ret) + goto exit; + + /* Move pointer to ahead of SETSCANCHANNELTIME */ + value = value + 19; + /* Convert the value from ascii to integer */ + ret = kstrtou16(value, 10, &maxTime); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou16 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou16 failed range [%d - %d]", __func__, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((maxTime < CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN) || + (maxTime > CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "lfr mode value %d is out of range" + " (Min: %d Max: %d)", maxTime, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MIN, + CFG_NEIGHBOR_SCAN_MAX_CHAN_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change channel max time = %d", __func__, maxTime); + + pHddCtx->cfg_ini->nNeighborScanMaxChanTime = maxTime; + sme_setNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal), maxTime); + } + else if (strncmp(command, "GETSCANCHANNELTIME", 18) == 0) + { + tANI_U16 val = sme_getNeighborScanMaxChanTime((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETSCANCHANNELTIME", val); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANHOMETIME", 15) == 0) + { + tANI_U8 *value = command; + tANI_U16 val = CFG_NEIGHBOR_SCAN_TIMER_PERIOD_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 15); + if (ret) + goto exit; + + /* Move pointer to ahead of SETSCANHOMETIME */ + value = value + 16; + /* Convert the value from ascii to integer */ + ret = kstrtou16(value, 10, &val); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou16 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou16 failed range [%d - %d]", __func__, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX); + ret = -EINVAL; + goto exit; + } + + if ((val < CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN) || + (val > CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "scan home time value %d is out of range" + " (Min: %d Max: %d)", val, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MIN, + CFG_NEIGHBOR_SCAN_TIMER_PERIOD_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change scan home time = %d", __func__, val); + + pHddCtx->cfg_ini->nNeighborScanPeriod = val; + sme_setNeighborScanPeriod((tHalHandle)(pHddCtx->hHal), val); + } + else if (strncmp(command, "GETSCANHOMETIME", 15) == 0) + { + tANI_U16 val = sme_getNeighborScanPeriod((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETSCANHOMETIME", val); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETROAMINTRABAND", 16) == 0) + { + tANI_U8 *value = command; + tANI_U8 val = CFG_ROAM_INTRA_BAND_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 16); + if (ret) + goto exit; + + /* Move pointer to ahead of SETROAMINTRABAND */ + value = value + 17; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &val); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_INTRA_BAND_MIN, + CFG_ROAM_INTRA_BAND_MAX); + ret = -EINVAL; + goto exit; + } + + if ((val < CFG_ROAM_INTRA_BAND_MIN) || + (val > CFG_ROAM_INTRA_BAND_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "intra band mode value %d is out of range" + " (Min: %d Max: %d)", val, + CFG_ROAM_INTRA_BAND_MIN, + CFG_ROAM_INTRA_BAND_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change intra band = %d", __func__, val); + + pHddCtx->cfg_ini->nRoamIntraBand = val; + sme_setRoamIntraBand((tHalHandle)(pHddCtx->hHal), val); + } + else if (strncmp(command, "GETROAMINTRABAND", 16) == 0) + { + tANI_U16 val = sme_getRoamIntraBand((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + /* value is interms of msec */ + len = scnprintf(extra, sizeof(extra), "%s %d", + "GETROAMINTRABAND", val); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANNPROBES", 14) == 0) + { + tANI_U8 *value = command; + tANI_U8 nProbes = CFG_ROAM_SCAN_N_PROBES_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 14); + if (ret) + goto exit; + + /* Move pointer to ahead of SETSCANNPROBES */ + value = value + 15; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &nProbes); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_SCAN_N_PROBES_MIN, + CFG_ROAM_SCAN_N_PROBES_MAX); + ret = -EINVAL; + goto exit; + } + + if ((nProbes < CFG_ROAM_SCAN_N_PROBES_MIN) || + (nProbes > CFG_ROAM_SCAN_N_PROBES_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NProbes value %d is out of range" + " (Min: %d Max: %d)", nProbes, + CFG_ROAM_SCAN_N_PROBES_MIN, + CFG_ROAM_SCAN_N_PROBES_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set nProbes = %d", __func__, nProbes); + + pHddCtx->cfg_ini->nProbes = nProbes; + sme_UpdateRoamScanNProbes((tHalHandle)(pHddCtx->hHal), nProbes); + } + else if (strncmp(command, "GETSCANNPROBES", 14) == 0) + { + tANI_U8 val = sme_getRoamScanNProbes((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, val); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETSCANHOMEAWAYTIME", 19) == 0) + { + tANI_U8 *value = command; + tANI_U16 homeAwayTime = CFG_ROAM_SCAN_HOME_AWAY_TIME_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 19); + if (ret) + goto exit; + + /* Move pointer to ahead of SETSCANHOMEAWAYTIME */ + /* input value is in units of msec */ + value = value + 20; + /* Convert the value from ascii to integer */ + ret = kstrtou16(value, 10, &homeAwayTime); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((homeAwayTime < CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN) || + (homeAwayTime > CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "homeAwayTime value %d is out of range" + " (Min: %d Max: %d)", homeAwayTime, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MIN, + CFG_ROAM_SCAN_HOME_AWAY_TIME_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set scan away time = %d", __func__, homeAwayTime); + if (pHddCtx->cfg_ini->nRoamScanHomeAwayTime != homeAwayTime) + { + pHddCtx->cfg_ini->nRoamScanHomeAwayTime = homeAwayTime; + sme_UpdateRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal), homeAwayTime, eANI_BOOLEAN_TRUE); + } + } + else if (strncmp(command, "GETSCANHOMEAWAYTIME", 19) == 0) + { + tANI_U16 val = sme_getRoamScanHomeAwayTime((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, val); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "REASSOC", 7) == 0) + { + ret = hdd_drv_cmd_validate(command, 7); + if (ret) + goto exit; + + ret = hdd_parse_reassoc(pAdapter, command, priv_data.total_len); + if (!ret) + goto exit; + } + else if (strncmp(command, "SETWESMODE", 10) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN wesMode = CFG_ENABLE_WES_MODE_NAME_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 10); + if (ret) + goto exit; + + /* Move pointer to ahead of SETWESMODE */ + value = value + 11; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &wesMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ENABLE_WES_MODE_NAME_MIN, + CFG_ENABLE_WES_MODE_NAME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((wesMode < CFG_ENABLE_WES_MODE_NAME_MIN) || + (wesMode > CFG_ENABLE_WES_MODE_NAME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "WES Mode value %d is out of range" + " (Min: %d Max: %d)", wesMode, + CFG_ENABLE_WES_MODE_NAME_MIN, + CFG_ENABLE_WES_MODE_NAME_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set WES Mode rssi diff = %d", __func__, wesMode); + + pHddCtx->cfg_ini->isWESModeEnabled = wesMode; + sme_UpdateWESMode((tHalHandle)(pHddCtx->hHal), wesMode); + } + else if (strncmp(command, "GETWESMODE", 10) == 0) + { + tANI_BOOLEAN wesMode = sme_GetWESMode((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, wesMode); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || FEATURE_WLAN_LFR */ +#ifdef FEATURE_WLAN_LFR + else if (strncmp(command, "SETFASTROAM", 11) == 0) + { + tANI_U8 *value = command; + tANI_U8 lfrMode = CFG_LFR_FEATURE_ENABLED_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 11); + if (ret) + goto exit; + + /* Move pointer to ahead of SETFASTROAM */ + value = value + 12; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &lfrMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + if ((lfrMode < CFG_LFR_FEATURE_ENABLED_MIN) || + (lfrMode > CFG_LFR_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "lfr mode value %d is out of range" + " (Min: %d Max: %d)", lfrMode, + CFG_LFR_FEATURE_ENABLED_MIN, + CFG_LFR_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change lfr mode = %d", __func__, lfrMode); + + pHddCtx->cfg_ini->isFastRoamIniFeatureEnabled = lfrMode; + sme_UpdateIsFastRoamIniFeatureEnabled((tHalHandle)(pHddCtx->hHal), lfrMode); + } +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + else if (strncmp(command, "SETFASTTRANSITION", 17) == 0) + { + tANI_U8 *value = command; + tANI_U8 ft = CFG_FAST_TRANSITION_ENABLED_NAME_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 17); + if (ret) + goto exit; + + /* Move pointer to ahead of SETFASTROAM */ + value = value + 18; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &ft); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_FAST_TRANSITION_ENABLED_NAME_MIN, + CFG_FAST_TRANSITION_ENABLED_NAME_MAX); + ret = -EINVAL; + goto exit; + } + + if ((ft < CFG_FAST_TRANSITION_ENABLED_NAME_MIN) || + (ft > CFG_FAST_TRANSITION_ENABLED_NAME_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "ft mode value %d is out of range" + " (Min: %d Max: %d)", ft, + CFG_FAST_TRANSITION_ENABLED_NAME_MIN, + CFG_FAST_TRANSITION_ENABLED_NAME_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change ft mode = %d", __func__, ft); + + pHddCtx->cfg_ini->isFastTransitionEnabled = ft; + sme_UpdateFastTransitionEnabled((tHalHandle)(pHddCtx->hHal), ft); + } + else if (strncmp(command, "SETDFSSCANMODE", 14) == 0) + { + tANI_U8 *value = command; + tANI_U8 dfsScanMode = DFS_CHNL_SCAN_ENABLED_NORMAL; + + ret = hdd_drv_cmd_validate(command, 14); + if (ret) + goto exit; + + /* Move pointer to ahead of SETDFSSCANMODE */ + value = value + 15; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &dfsScanMode); + if (ret < 0) + { + /* If the input value is greater than max value of + datatype, then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ENABLE_DFS_CHNL_SCAN_MIN, + CFG_ENABLE_DFS_CHNL_SCAN_MAX); + ret = -EINVAL; + goto exit; + } + + if ((dfsScanMode < CFG_ENABLE_DFS_CHNL_SCAN_MIN) || + (dfsScanMode > CFG_ENABLE_DFS_CHNL_SCAN_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "dfsScanMode value %d is out of range" + " (Min: %d Max: %d)", dfsScanMode, + CFG_ENABLE_DFS_CHNL_SCAN_MIN, + CFG_ENABLE_DFS_CHNL_SCAN_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set DFS Scan Mode = %d", + __func__, dfsScanMode); + + ret = wlan_hdd_handle_dfs_chan_scan(pHddCtx, dfsScanMode); + } + else if (strncmp(command, "GETDFSSCANMODE", 14) == 0) + { + tANI_U8 dfsScanMode = sme_GetDFSScanMode(pHddCtx->hHal); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", command, dfsScanMode); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "FASTREASSOC", 11) == 0) + { + ret = wlan_hdd_handle_fastreassoc(pAdapter, command); + if (!ret) + goto exit; + } +#endif +#ifdef FEATURE_WLAN_ESE + else if (strncmp(command, "SETCCXMODE", 10) == 0) + { + tANI_U8 *value = command; + tANI_U8 eseMode = CFG_ESE_FEATURE_ENABLED_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 10); + if (ret) + goto exit; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) && + hdd_is_okc_mode_enabled(pHddCtx) && + sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + /* Move pointer to ahead of SETCCXMODE */ + value = value + 11; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &eseMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_ESE_FEATURE_ENABLED_MIN, + CFG_ESE_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + if ((eseMode < CFG_ESE_FEATURE_ENABLED_MIN) || + (eseMode > CFG_ESE_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Ese mode value %d is out of range" + " (Min: %d Max: %d)", eseMode, + CFG_ESE_FEATURE_ENABLED_MIN, + CFG_ESE_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change ese mode = %d", __func__, eseMode); + + pHddCtx->cfg_ini->isEseIniFeatureEnabled = eseMode; + sme_UpdateIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal), eseMode); + } +#endif + else if (strncmp(command, "SETROAMSCANCONTROL", 18) == 0) + { + tANI_U8 *value = command; + tANI_BOOLEAN roamScanControl = 0; + + ret = hdd_drv_cmd_validate(command, 18); + if (ret) + goto exit; + + /* Move pointer to ahead of SETROAMSCANCONTROL */ + value = value + 19; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &roamScanControl); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed ", __func__); + ret = -EINVAL; + goto exit; + } + + if (0 != roamScanControl) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "roam scan control invalid value = %d", + roamScanControl); + ret = -EINVAL; + goto exit; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to Set roam scan control = %d", __func__, roamScanControl); + + sme_SetRoamScanControl((tHalHandle)(pHddCtx->hHal), roamScanControl); + } +#ifdef FEATURE_WLAN_OKC + else if (strncmp(command, "SETOKCMODE", 10) == 0) + { + tANI_U8 *value = command; + tANI_U8 okcMode = CFG_OKC_FEATURE_ENABLED_DEFAULT; + + ret = hdd_drv_cmd_validate(command, 10); + if (ret) + goto exit; + + /* Check if the features OKC/ESE/11R are supported simultaneously, + then this operation is not permitted (return FAILURE) */ + if (sme_getIsEseFeatureEnabled((tHalHandle)(pHddCtx->hHal)) && + hdd_is_okc_mode_enabled(pHddCtx) && + sme_getIsFtFeatureEnabled((tHalHandle)(pHddCtx->hHal))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: OKC/ESE/11R are supported simultaneously" + " hence this operation is not permitted!", __func__); + ret = -EPERM; + goto exit; + } + + /* Move pointer to ahead of SETOKCMODE */ + value = value + 11; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &okcMode); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + CFG_OKC_FEATURE_ENABLED_MIN, + CFG_OKC_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + if ((okcMode < CFG_OKC_FEATURE_ENABLED_MIN) || + (okcMode > CFG_OKC_FEATURE_ENABLED_MAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Okc mode value %d is out of range" + " (Min: %d Max: %d)", okcMode, + CFG_OKC_FEATURE_ENABLED_MIN, + CFG_OKC_FEATURE_ENABLED_MAX); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to change okc mode = %d", __func__, okcMode); + + pHddCtx->cfg_ini->isOkcIniFeatureEnabled = okcMode; + } +#endif /* FEATURE_WLAN_OKC */ + else if (strncmp(command, "GETROAMSCANCONTROL", 18) == 0) + { + tANI_BOOLEAN roamScanControl = sme_GetRoamScanControl((tHalHandle)(pHddCtx->hHal)); + char extra[32]; + tANI_U8 len = 0; + + len = scnprintf(extra, sizeof(extra), "%s %d", + command, roamScanControl); + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } +#ifdef WLAN_FEATURE_PACKET_FILTERING + else if (strncmp(command, "ENABLE_PKTFILTER_IPV6", 21) == 0) + { + tANI_U8 filterType = 0; + tANI_U8 *value = command; + + ret = hdd_drv_cmd_validate(command, 21); + if (ret) + goto exit; + + /* Move pointer to ahead of ENABLE_PKTFILTER_IPV6 */ + value = value + 22; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &filterType); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, + * then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range ", __func__); + ret = -EINVAL; + goto exit; + } + + if (filterType != 0 && filterType != 1) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Accepted Values are 0 and 1 ", __func__); + ret = -EINVAL; + goto exit; + } + wlan_hdd_setIPv6Filter(WLAN_HDD_GET_CTX(pAdapter), filterType, + pAdapter->sessionId); + } +#endif + else if (strncmp(command, "BTCOEXMODE", 10) == 0 ) + { + char *dhcpPhase; + int ret; + + ret = hdd_drv_cmd_validate(command, 10); + if (ret) + goto exit; + + dhcpPhase = command + 11; + if ('1' == *dhcpPhase) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("send DHCP START indication")); + + pHddCtx->btCoexModeSet = TRUE; + + ret = wlan_hdd_scan_abort(pAdapter); + if (ret < 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to abort existing scan %d"), ret); + } + + sme_DHCPStartInd(pHddCtx->hHal, pAdapter->device_mode, + pAdapter->sessionId); + } + else if ('2' == *dhcpPhase) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("send DHCP STOP indication")); + + pHddCtx->btCoexModeSet = FALSE; + + sme_DHCPStopInd(pHddCtx->hHal, pAdapter->device_mode, + pAdapter->sessionId); + } + } + else if (strncmp(command, "SCAN-ACTIVE", 11) == 0) + { + hddLog(LOG1, + FL("making default scan to ACTIVE")); + pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN; + } + else if (strncmp(command, "SCAN-PASSIVE", 12) == 0) + { + hddLog(LOG1, + FL("making default scan to PASSIVE")); + pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN; + } + else if (strncmp(command, "GETDWELLTIME", 12) == 0) + { + hdd_config_t *pCfg = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + char extra[32]; + tANI_U8 len = 0; + + memset(extra, 0, sizeof(extra)); + ret = hdd_get_dwell_time(pCfg, command, extra, sizeof(extra), &len); + len = VOS_MIN(priv_data.total_len, len + 1); + if (ret != 0 || copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + ret = len; + } + else if (strncmp(command, "SETDWELLTIME", 12) == 0) + { + ret = hdd_set_dwell_time(pAdapter, command); + } + else if ( strncasecmp(command, "MIRACAST", 8) == 0 ) + { + tANI_U8 filterType = 0; + tANI_U8 *value; + + ret = hdd_drv_cmd_validate(command, 8); + if (ret) + goto exit; + + value = command + 9; + + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &filterType); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, + * then also kstrtou8 fails + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range ", __func__); + ret = -EINVAL; + goto exit; + } + if ((filterType < WLAN_HDD_DRIVER_MIRACAST_CFG_MIN_VAL ) || + (filterType > WLAN_HDD_DRIVER_MIRACAST_CFG_MAX_VAL)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Accepted Values are 0 to 2. 0-Disabled, 1-Source," + " 2-Sink ", __func__); + ret = -EINVAL; + goto exit; + } + //Filtertype value should be either 0-Disabled, 1-Source, 2-sink + pHddCtx->drvr_miracast = filterType; + pScanInfo = &pHddCtx->scan_info; + if (filterType && pScanInfo != NULL && + pHddCtx->scan_info.mScanPending) + { + /*Miracast Session started. Abort Scan */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s, Aborting Scan For Miracast",__func__); + hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + hdd_tx_rx_pkt_cnt_stat_timer_handler(pHddCtx); + sme_SetMiracastMode(pHddCtx->hHal, pHddCtx->drvr_miracast); + } + else if (strncmp(command, "SETMCRATE", 9) == 0) + { + tANI_U8 *value = command; + int targetRate; + tSirRateUpdateInd *rateUpdate; + eHalStatus status; + + ret = hdd_drv_cmd_validate(command, 9); + if (ret) + goto exit; + + /* Only valid for SAP mode */ + if (WLAN_HDD_SOFTAP != pAdapter->device_mode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SAP mode is not running", __func__); + ret = -EFAULT; + goto exit; + } + + /* Move pointer to ahead of SETMCRATE */ + /* input value is in units of hundred kbps */ + value = value + 10; + /* Convert the value from ascii to integer, decimal base */ + ret = kstrtouint(value, 10, &targetRate); + + rateUpdate = (tSirRateUpdateInd *)vos_mem_malloc(sizeof(tSirRateUpdateInd)); + if (NULL == rateUpdate) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SETMCRATE indication alloc fail", __func__); + ret = -EFAULT; + goto exit; + } + vos_mem_zero(rateUpdate, sizeof(tSirRateUpdateInd )); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "MC Target rate %d", targetRate); + /* Ignore unicast */ + rateUpdate->ucastDataRate = -1; + rateUpdate->mcastDataRate24GHz = targetRate; + rateUpdate->mcastDataRate5GHz = targetRate; + rateUpdate->mcastDataRate24GHzTxFlag = 0; + rateUpdate->mcastDataRate5GHzTxFlag = 0; + status = sme_SendRateUpdateInd(pHddCtx->hHal, rateUpdate); + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SET_MC_RATE failed", __func__); + vos_mem_free(rateUpdate); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "MAXTXPOWER", 10) == 0) + { + int status; + int txPower; + eHalStatus smeStatus; + tANI_U8 *value = command; + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + status = hdd_parse_setmaxtxpower_command(value, &txPower); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MAXTXPOWER command "); + ret = -EINVAL; + goto exit; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "max tx power %d selfMac: " + MAC_ADDRESS_STR " bssId: " MAC_ADDRESS_STR " ", + txPower, MAC_ADDR_ARRAY(selfMac), + MAC_ADDR_ARRAY(bssid)); + smeStatus = sme_SetMaxTxPower((tHalHandle)(pHddCtx->hHal), + bssid, selfMac, txPower) ; + if( smeStatus != eHAL_STATUS_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:Set max tx power failed", + __func__); + ret = -EINVAL; + goto exit; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set max tx power success", + __func__); + } +#ifdef FEATURE_WLAN_BATCH_SCAN + else if (strncmp(command, "WLS_BATCHING", 12) == 0) + { + ret = hdd_handle_batch_scan_ioctl(pAdapter, &priv_data, command); + } +#endif +#ifdef WLAN_FEATURE_RMC + else if ((strncasecmp(command, "SETIBSSBEACONOUIDATA", 20) == 0) && + (WLAN_HDD_IBSS == pAdapter->device_mode)) + { + int i = 0; + tANI_U8 *ibss_ie; + tANI_U32 command_len; + tANI_U8 *value = command; + tHalHandle hHal = pHddCtx->hHal; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U32 ibss_ie_length; + tANI_U32 len, present; + tANI_U8 *addIE; + tANI_U8 *addIEData; + + hddLog(LOG1, + FL(" received command %s"),((char *) value)); + /* validate argument of command */ + if (strlen(value) <= 21) + { + hddLog(LOGE, + FL("No arguements in command length %zu"), strlen(value)); + ret = -EFAULT; + goto exit; + } + + /* moving to arguments of commands */ + value = value + 21; + command_len = strlen(value); + + /* oui_data can't be less than 3 bytes */ + if (command_len <= (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) + { + hddLog(LOGE, + FL("Invalid SETIBSSBEACONOUIDATA command length %d"), + command_len); + ret = -EFAULT; + goto exit; + } + ibss_ie = vos_mem_malloc(command_len); + if (!ibss_ie) { + hddLog(LOGE, + FL("Could not allocate memory for command length %d"), + command_len); + ret = -ENOMEM; + goto exit; + } + vos_mem_zero(ibss_ie, command_len); + + ibss_ie_length = hdd_parse_set_ibss_oui_data_command(value, ibss_ie, + command_len); + if (ibss_ie_length < (2 * WLAN_HDD_IBSS_MIN_OUI_DATA_LENGTH)) { + hddLog(LOGE, FL("Could not parse command %s return length %d"), + value, ibss_ie_length); + ret = -EFAULT; + vos_mem_free(ibss_ie); + goto exit; + } + + hddLog(LOG1, FL("ibss_ie length %d ibss_ie:"), ibss_ie_length); + while (i < ibss_ie_length) + hddLog(LOG1, FL("0x%x"), ibss_ie[i++]); + + /* Populate Vendor IE in Beacon */ + if ((ccmCfgGetInt(hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, + &present)) != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, + FL("unable to ftch WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + goto exit; + } + + addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN); + if (!addIE) { + hddLog(LOGE, + FL("Could not allocate memory for command length %d"), + command_len); + vos_mem_free(ibss_ie); + ret = -ENOMEM; + goto exit; + } + vos_mem_zero(addIE, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN); + + if (present) + { + if ((wlan_cfgGetStrLen(pMac, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &len)) != eSIR_SUCCESS) + { + hddLog(LOGE, + FL("unable to fetch WNI_CFG_PROBE_RSP_BCN_ADDNIE_LEN")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + vos_mem_free(addIE); + goto exit; + } + + if (len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && + ((len + ibss_ie_length) <= + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN)) + { + if ((ccmCfgGetStr(hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, &len)) + != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, + FL("unable to fetch WNI_PROBE_RSP_BCN_ADDNIE_DATA")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + vos_mem_free(addIE); + goto exit; + } + else + { + /* Curruntly only WPA IE is added before Vendor IE + * so we can blindly place the Vendor IE after WPA + * IE. If no WPA IE found replace all with Vendor IE. + */ + len = hdd_find_ibss_wpa_ie_pos(addIE, len); + } + } + else + { + hddLog(LOGE, + FL("IE len exceed limit len %d,ibss_ie_length %d "), + len, ibss_ie_length); + ret = -EFAULT; + vos_mem_free(addIE); + vos_mem_free(ibss_ie); + goto exit; + } + } + else { + len = 0; + } + + vos_mem_copy (addIE + len , ibss_ie, ibss_ie_length); + len += ibss_ie_length; + + if (ccmCfgSetStr(hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, addIE, len, NULL, + eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, + FL("unable to set WNI_CFG_PRBE_RSP_BCN_ADDNIE_DATA")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + vos_mem_free(addIE); + goto exit; + } + vos_mem_free(addIE); + if (ccmCfgSetInt(hHal, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL, + eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, + FL("unble to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + goto exit; + } + + /* Populate Vendor IE in probe resp */ + if ((ccmCfgGetInt(hHal, + WNI_CFG_PROBE_RSP_ADDNIE_FLAG, + &present)) != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, + FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_FLAG")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + goto exit; + } + + addIEData = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN); + if (!addIEData) { + hddLog(LOGE, + FL("Could not allocate memory for command length %d"), + command_len); + vos_mem_free(ibss_ie); + ret = -ENOMEM; + goto exit; + } + vos_mem_zero(addIEData, WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN); + + if (present) { + if (eSIR_SUCCESS != wlan_cfgGetStrLen(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &len)) { + hddLog(LOGE, + FL("unable to fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + vos_mem_free(addIEData); + goto exit; + } + if (len < WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && len && + (ibss_ie_length + len) <= + WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) { + + if ((ccmCfgGetStr(hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, addIEData, &len)) + != eHAL_STATUS_SUCCESS) { + hddLog(LOGE, + FL("unable fetch WNI_CFG_PROBE_RSP_ADDNIE_DATA1")); + ret = -EFAULT; + vos_mem_free(ibss_ie); + vos_mem_free(addIEData); + goto exit; + } + else { + /* Curruntly only WPA IE is added before Vendor IE + * so we can blindly place the Vendor IE after WPA + * IE. If no WPA IE found replace all with Vendor IE. + */ + len = hdd_find_ibss_wpa_ie_pos(addIEData, len); + } + } + else + { + hddLog(LOGE, + FL("IE len exceed limit len %d,ibss_ie_length %d "), + len, ibss_ie_length); + ret = -EFAULT; + vos_mem_free(addIEData); + vos_mem_free(ibss_ie); + goto exit; + } + } /* probe rsp ADD IE present */ + else { + /* probe rsp add IE is not present */ + len = 0; + } + + vos_mem_copy(addIEData +len , ibss_ie, ibss_ie_length); + len += ibss_ie_length; + + vos_mem_free(ibss_ie); + + if (ccmCfgSetStr(hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + (tANI_U8*)(addIEData), + len, NULL, + eANI_BOOLEAN_FALSE) + == eHAL_STATUS_FAILURE) { + hddLog(LOGE, + FL("unable to copy to WNI_CFG_PROBE_RSP_ADDNIE_DATA1")); + ret = -EFAULT; + vos_mem_free(addIEData); + goto exit; + } + vos_mem_free(addIEData); + if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL, + eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + hddLog(LOGE, + FL("unable to copy WNI_CFG_PROBE_RSP_ADDNIE_FLAG")); + ret = -EFAULT; + goto exit; + } + } + else if (strncasecmp(command, "SETRMCENABLE", 12) == 0) + { + tANI_U8 *value = command; + tANI_U8 ucRmcEnable = 0; + int status; + + if ((WLAN_HDD_IBSS != pAdapter->device_mode) && + (WLAN_HDD_SOFTAP != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received SETRMCENABLE command in invalid mode %d " + "SETRMCENABLE command is only allowed in IBSS or SOFTAP mode", + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_setrmcenable_command(value, &ucRmcEnable); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid SETRMCENABLE command "); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: ucRmcEnable %d ", __func__, ucRmcEnable); + + if (TRUE == ucRmcEnable) + { + status = sme_EnableRMC( (tHalHandle)(pHddCtx->hHal), + pAdapter->sessionId ); + } + else if(FALSE == ucRmcEnable) + { + status = sme_DisableRMC( (tHalHandle)(pHddCtx->hHal), + pAdapter->sessionId ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid SETRMCENABLE command %d", ucRmcEnable); + ret = -EINVAL; + goto exit; + } + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: SETRMC %d failed status %d", __func__, ucRmcEnable, + status); + ret = -EINVAL; + goto exit; + } + } + else if (strncasecmp(command, "SETRMCACTIONPERIOD", 18) == 0) + { + tANI_U8 *value = command; + tANI_U32 uActionPeriod = 0; + int status; + + if ((WLAN_HDD_IBSS != pAdapter->device_mode) && + (WLAN_HDD_SOFTAP != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received SETRMC command in invalid mode %d " + "SETRMC command is only allowed in IBSS or SOFTAP mode", + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_setrmcactionperiod_command(value, &uActionPeriod); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid SETRMCACTIONPERIOD command "); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: uActionPeriod %d ", __func__, uActionPeriod); + + if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY, + uActionPeriod, NULL, eANI_BOOLEAN_FALSE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Could not set SETRMCACTIONPERIOD %d", __func__, uActionPeriod); + ret = -EINVAL; + goto exit; + } + + } + else if (strncasecmp(command, "GETIBSSPEERINFOALL", 18) == 0) + { + /* Peer Info All Command */ + int status = eHAL_STATUS_SUCCESS; + hdd_station_ctx_t *pHddStaCtx = NULL; + char *extra = NULL; + int idx = 0, length = 0; + v_MACADDR_t *macAddr; + v_U32_t txRateMbps = 0, numOfBytestoPrint = 0; + + if (WLAN_HDD_IBSS == pAdapter->device_mode) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: pAdapter is not valid for this device mode", + __func__); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received GETIBSSPEERINFOALL Command", __func__); + + + /* Handle the command */ + status = hdd_cfg80211_get_ibss_peer_info_all(pAdapter); + if (VOS_STATUS_SUCCESS == status) + { + /* The variable extra needed to be allocated on the heap since + * amount of memory required to copy the data for 32 devices + * exceeds the size of 1024 bytes of default stack size. On + * 64 bit devices, the default max stack size of 2048 bytes + */ + extra = kmalloc(WLAN_MAX_BUF_SIZE, GFP_KERNEL); + + if (NULL == extra) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:kmalloc failed", __func__); + ret = -EINVAL; + goto exit; + } + + /* Copy number of stations */ + length = scnprintf( extra, WLAN_MAX_BUF_SIZE, "%d ", + pHddStaCtx->ibss_peer_info.numIBSSPeers); + numOfBytestoPrint = length; + for (idx = 0; idx < pHddStaCtx->ibss_peer_info.numIBSSPeers; idx++) + { + macAddr = + hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter, + pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx); + if (NULL != macAddr) + { + txRateMbps = + ((pHddStaCtx->ibss_peer_info.ibssPeerList[idx].txRate)*500*1000)/1000000; + + length += scnprintf( (extra + length), WLAN_MAX_BUF_SIZE - length, + "%02x:%02x:%02x:%02x:%02x:%02x %d %d ", + macAddr->bytes[0], macAddr->bytes[1], macAddr->bytes[2], + macAddr->bytes[3], macAddr->bytes[4], macAddr->bytes[5], + (int)txRateMbps, + (int)pHddStaCtx->ibss_peer_info.ibssPeerList[idx].rssi); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: MAC ADDR is NULL for staIdx: %d", __func__, + pHddStaCtx->ibss_peer_info.ibssPeerList[idx].staIdx); + } + + /* + * VOS_TRACE() macro has limitation of 512 bytes for the print + * buffer. Hence printing the data in two chunks. The first chunk + * will have the data for 16 devices and the second chunk will + * have the rest. + */ + if (idx < NUM_OF_STA_DATA_TO_PRINT) + { + numOfBytestoPrint = length; + } + } + + /* + * Copy the data back into buffer, if the data to copy is + * morethan 512 bytes than we will split the data and do + * it in two shots + */ + if (copy_to_user(priv_data.buf, extra, numOfBytestoPrint)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Copy into user data buffer failed ", __func__); + ret = -EFAULT; + kfree(extra); + goto exit; + } + priv_data.buf[numOfBytestoPrint] = '\0'; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "%s", priv_data.buf); + + if (length > numOfBytestoPrint) + { + if (copy_to_user(priv_data.buf + numOfBytestoPrint, + extra + numOfBytestoPrint, + length - numOfBytestoPrint + 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Copy into user data buffer failed ", __func__); + ret = -EFAULT; + kfree(extra); + goto exit; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "%s", &priv_data.buf[numOfBytestoPrint]); + } + + /* Free temporary buffer */ + kfree(extra); + } + + else + { + /* Command failed, log error */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: GETIBSSPEERINFOALL command failed with status code %d", + __func__, status); + ret = -EINVAL; + goto exit; + } + ret = 0; + } + else if(strncasecmp(command, "GETIBSSPEERINFO", 15) == 0) + { + /* Peer Info command */ + tANI_U8 *value = command; + VOS_STATUS status; + hdd_station_ctx_t *pHddStaCtx = NULL; + char extra[128] = { 0 }; + v_U32_t length = 0; + v_U8_t staIdx = 0; + v_U32_t txRateMbps = 0; + v_MACADDR_t peerMacAddr; + + if (WLAN_HDD_IBSS == pAdapter->device_mode) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: pAdapter is not valid for this device mode", + __func__); + ret = -EINVAL; + goto exit; + } + + /* if there are no peers, no need to continue with the command */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received GETIBSSPEERINFO Command", __func__); + + if (eConnectionState_IbssConnected != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:No IBSS Peers coalesced", __func__); + ret = -EINVAL; + goto exit; + } + + /* Parse the incoming command buffer */ + status = hdd_parse_get_ibss_peer_info(value, &peerMacAddr); + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid GETIBSSPEERINFO command", __func__); + ret = -EINVAL; + goto exit; + } + + /* Get station index for the peer mac address */ + hdd_Ibss_GetStaId(pHddStaCtx, &peerMacAddr, &staIdx); + + if (staIdx > HDD_MAX_NUM_IBSS_STA) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid StaIdx %d returned", __func__, staIdx); + ret = -EINVAL; + goto exit; + } + + /* Handle the command */ + status = hdd_cfg80211_get_ibss_peer_info(pAdapter, staIdx); + if (VOS_STATUS_SUCCESS == status) + { + v_U32_t txRate = pHddStaCtx->ibss_peer_info.ibssPeerList[0].txRate; + txRateMbps = (txRate * 500 * 1000)/1000000; + + length = scnprintf( extra, sizeof(extra), "%d %d", (int)txRateMbps, + (int)pHddStaCtx->ibss_peer_info.ibssPeerList[0].rssi); + + /* Copy the data back into buffer */ + if (copy_to_user(priv_data.buf, &extra, length+ 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: copy data to user buffer failed GETIBSSPEERINFO command", + __func__); + ret = -EFAULT; + goto exit; + } + } + else + { + /* Command failed, log error */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: GETIBSSPEERINFO command failed with status code %d", + __func__, status); + ret = -EINVAL; + goto exit; + } + + /* Success ! */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "%s", priv_data.buf); + ret = 0; + } + else if (strncasecmp(command, "SETRMCTXRATE", 12) == 0) + { + tANI_U8 *value = command; + tANI_U32 uRate = 0; + tTxrateinfoflags txFlags = 0; + tSirRateUpdateInd *rateUpdateParams; + int status; + + if ((WLAN_HDD_IBSS != pAdapter->device_mode) && + (WLAN_HDD_SOFTAP != pAdapter->device_mode)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Received SETRMCTXRATE command in invalid mode %d " + "SETRMC command is only allowed in IBSS or SOFTAP mode", + pAdapter->device_mode); + ret = -EINVAL; + goto exit; + } + + status = hdd_parse_setrmcrate_command(value, &uRate, &txFlags); + if (status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid SETRMCTXRATE command "); + ret = -EINVAL; + goto exit; + } + + rateUpdateParams = vos_mem_malloc(sizeof(tSirRateUpdateInd)); + if (NULL == rateUpdateParams) + { + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: uRate %d ", __func__, uRate); + + vos_mem_zero(rateUpdateParams, sizeof(tSirRateUpdateInd )); + + /* -1 implies ignore this param */ + rateUpdateParams->ucastDataRate = -1; + + /* + * Fill the user specifieed RMC rate param + * and the derived tx flags. + */ + rateUpdateParams->rmcDataRate = uRate; + rateUpdateParams->rmcDataRateTxFlag = txFlags; + + status = sme_SendRateUpdateInd((tHalHandle)(pHddCtx->hHal), rateUpdateParams); + } + else if (strncasecmp(command, "SETIBSSTXFAILEVENT", 18) == 0 ) + { + char *value; + tANI_U8 tx_fail_count = 0; + tANI_U16 pid = 0; + + value = command; + + ret = hdd_ParseIBSSTXFailEventParams(value, &tx_fail_count, &pid); + + if (0 != ret) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Failed to parse SETIBSSTXFAILEVENT arguments", + __func__); + goto exit; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: tx_fail_cnt=%hhu, pid=%hu", + __func__, tx_fail_count, pid); + + if (0 == tx_fail_count) + { + // Disable TX Fail Indication + if (eHAL_STATUS_SUCCESS == + sme_TXFailMonitorStartStopInd(pHddCtx->hHal, + tx_fail_count, + NULL)) + { + cesium_pid = 0; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to disable TX Fail Event ", __func__); + ret = -EINVAL; + } + } + else + { + if (eHAL_STATUS_SUCCESS == + sme_TXFailMonitorStartStopInd(pHddCtx->hHal, + tx_fail_count, + (void*)hdd_tx_fail_ind_callback)) + { + cesium_pid = pid; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Registered Cesium pid %u", __func__, + cesium_pid); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to enable TX Fail Monitoring", __func__); + ret = -EINVAL; + } + } + } + +#endif /* WLAN_FEATURE_RMC */ +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + else if (strncmp(command, "SETCCXROAMSCANCHANNELS", 22) == 0) + { + tANI_U8 *value = command; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 numChannels = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = hdd_parse_channellist(value, ChannelList, &numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse channel list information", __func__); + ret = -EINVAL; + goto exit; + } + + if (numChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: number of channels (%d) supported exceeded max (%d)", __func__, + numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN); + ret = -EINVAL; + goto exit; + } + status = sme_SetEseRoamScanChannelList((tHalHandle)(pHddCtx->hHal), + ChannelList, + numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to update channel list information", __func__); + ret = -EINVAL; + goto exit; + } + } + else if (strncmp(command, "GETTSMSTATS", 11) == 0) + { + tANI_U8 *value = command; + char extra[128] = {0}; + int len = 0; + tANI_U8 tid = 0; + hdd_station_ctx_t *pHddStaCtx = NULL; + tAniTrafStrmMetrics tsmMetrics; + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + ret = hdd_drv_cmd_validate(command, 11); + if (ret) + goto exit; + + /* if not associated, return error */ + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Not associated!",__func__); + ret = -EINVAL; + goto exit; + } + + /* Move pointer to ahead of GETTSMSTATS */ + value = value + 12; + /* Convert the value from ascii to integer */ + ret = kstrtou8(value, 10, &tid); + if (ret < 0) + { + /* If the input value is greater than max value of datatype, then also + kstrtou8 fails */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kstrtou8 failed range [%d - %d]", __func__, + TID_MIN_VALUE, + TID_MAX_VALUE); + ret = -EINVAL; + goto exit; + } + + if ((tid < TID_MIN_VALUE) || (tid > TID_MAX_VALUE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "tid value %d is out of range" + " (Min: %d Max: %d)", tid, + TID_MIN_VALUE, + TID_MAX_VALUE); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received Command to get tsm stats tid = %d", __func__, tid); + + if (VOS_STATUS_SUCCESS != hdd_get_tsm_stats(pAdapter, tid, &tsmMetrics)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to get tsm stats", __func__); + ret = -EFAULT; + goto exit; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "UplinkPktQueueDly(%d)\n" + "UplinkPktQueueDlyHist[0](%d)\n" + "UplinkPktQueueDlyHist[1](%d)\n" + "UplinkPktQueueDlyHist[2](%d)\n" + "UplinkPktQueueDlyHist[3](%d)\n" + "UplinkPktTxDly(%u)\n" + "UplinkPktLoss(%d)\n" + "UplinkPktCount(%d)\n" + "RoamingCount(%d)\n" + "RoamingDly(%d)", tsmMetrics.UplinkPktQueueDly, + tsmMetrics.UplinkPktQueueDlyHist[0], + tsmMetrics.UplinkPktQueueDlyHist[1], + tsmMetrics.UplinkPktQueueDlyHist[2], + tsmMetrics.UplinkPktQueueDlyHist[3], + tsmMetrics.UplinkPktTxDly, tsmMetrics.UplinkPktLoss, + tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, tsmMetrics.RoamingDly); + + /* Output TSM stats is of the format + GETTSMSTATS [PktQueueDly] [PktQueueDlyHist[0]]:[PktQueueDlyHist[1]] ...[RoamingDly] + eg., GETTSMSTATS 10 1:0:0:161 20 1 17 8 39800 */ + len = scnprintf(extra, sizeof(extra), "%s %d %d:%d:%d:%d %u %d %d %d %d", command, + tsmMetrics.UplinkPktQueueDly, tsmMetrics.UplinkPktQueueDlyHist[0], + tsmMetrics.UplinkPktQueueDlyHist[1], tsmMetrics.UplinkPktQueueDlyHist[2], + tsmMetrics.UplinkPktQueueDlyHist[3], tsmMetrics.UplinkPktTxDly, + tsmMetrics.UplinkPktLoss, tsmMetrics.UplinkPktCount, tsmMetrics.RoamingCount, + tsmMetrics.RoamingDly); + + len = VOS_MIN(priv_data.total_len, len + 1); + if (copy_to_user(priv_data.buf, &extra, len)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + } + else if (strncmp(command, "SETCCKMIE", 9) == 0) + { + tANI_U8 *value = command; + tANI_U8 *cckmIe = NULL; + tANI_U8 cckmIeLen = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = hdd_parse_get_cckm_ie(value, &cckmIe, &cckmIeLen); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse cckm ie data", __func__); + ret = -EINVAL; + goto exit; + } + + if (cckmIeLen > DOT11F_IE_RSN_MAX_LEN) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: CCKM Ie input length is more than max[%d]", __func__, + DOT11F_IE_RSN_MAX_LEN); + vos_mem_free(cckmIe); + cckmIe = NULL; + ret = -EINVAL; + goto exit; + } + sme_SetCCKMIe((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, cckmIe, cckmIeLen); + vos_mem_free(cckmIe); + cckmIe = NULL; + } + else if (strncmp(command, "CCXBEACONREQ", 12) == 0) + { + tANI_U8 *value = command; + tCsrEseBeaconReq eseBcnReq; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = hdd_parse_ese_beacon_req(value, &eseBcnReq); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to parse ese beacon req", __func__); + ret = -EINVAL; + goto exit; + } + if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Not associated")); + hdd_indicateEseBcnReportNoResults (pAdapter, + eseBcnReq.bcnReq[0].measurementToken, + 0x02, //BIT(1) set for measurement done + 0); // no BSS + goto exit; + } + + status = sme_SetEseBeaconRequest((tHalHandle)(pHddCtx->hHal), pAdapter->sessionId, &eseBcnReq); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_SetEseBeaconRequest failed (%d)", __func__, status); + ret = -EINVAL; + goto exit; + } + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + else if (strncmp(command, "GETBCNMISSRATE", 14) == 0) + { + eHalStatus status; + char buf[32], len; + long waitRet; + bcnMissRateContext_t getBcnMissRateCtx; + + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + hddLog(VOS_TRACE_LEVEL_WARN, + FL("GETBCNMISSRATE: STA is not in connected state")); + ret = -1; + goto exit; + } + + init_completion(&(getBcnMissRateCtx.completion)); + getBcnMissRateCtx.magic = BCN_MISS_RATE_CONTEXT_MAGIC; + + status = sme_getBcnMissRate((tHalHandle)(pHddCtx->hHal), + pAdapter->sessionId, + (void *)getBcnMissRateCB, + (void *)(&getBcnMissRateCtx)); + if( eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("GETBCNMISSRATE: fail to post WDA cmd")); + ret = -EINVAL; + goto exit; + } + + waitRet = wait_for_completion_interruptible_timeout + (&getBcnMissRateCtx.completion, BCN_MISS_RATE_TIME); + if(waitRet <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed to wait on bcnMissRateComp %d"), ret); + + //Make magic number to zero so that callback is not called. + spin_lock(&hdd_context_lock); + getBcnMissRateCtx.magic = 0x0; + spin_unlock(&hdd_context_lock); + ret = -EINVAL; + goto exit; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("GETBCNMISSRATE: bcnMissRate: %d"), gbcnMissRate); + + len = snprintf(buf, sizeof(buf), "GETBCNMISSRATE %d", gbcnMissRate); + if (copy_to_user(priv_data.buf, &buf, len + 1)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + ret = -EFAULT; + goto exit; + } + ret = len; + } +#ifdef FEATURE_WLAN_TDLS + else if (strncmp(command, "TDLSSECONDARYCHANNELOFFSET", 26) == 0) { + tANI_U8 *value = command; + int set_value; + + ret = hdd_drv_cmd_validate(command, 26); + if (ret) + goto exit; + + /* Move pointer to ahead of TDLSOFFCH*/ + value += 26; + if (!(sscanf(value, "%d", &set_value))) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("No input identified")); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Tdls offchannel offset:%d", + __func__, set_value); + ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value); + if (ret < 0) + { + ret = -EINVAL; + goto exit; + } + + } else if (strncmp(command, "TDLSOFFCHANNELMODE", 18) == 0) { + tANI_U8 *value = command; + int set_value; + + ret = hdd_drv_cmd_validate(command, 18); + if (ret) + goto exit; + + /* Move pointer to ahead of tdlsoffchnmode*/ + value += 18; + ret = sscanf(value, "%d", &set_value); + if (ret != 1) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("No input identified")); + ret = -EINVAL; + goto exit; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Tdls offchannel mode:%d", + __func__, set_value); + ret = iw_set_tdlsoffchannelmode(pAdapter, set_value); + if (ret < 0) + { + ret = -EINVAL; + goto exit; + } + } else if (strncmp(command, "TDLSOFFCHANNEL", 14) == 0) { + tANI_U8 *value = command; + int set_value; + + ret = hdd_drv_cmd_validate(command, 14); + if (ret) + goto exit; + + /* Move pointer to ahead of TDLSOFFCH*/ + value += 14; + ret = sscanf(value, "%d", &set_value); + if (ret != 1) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Wrong value is given for hdd_set_tdls_offchannel"); + ret = -EINVAL; + goto exit; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Tdls offchannel num: %d", + __func__, set_value); + ret = iw_set_tdlsoffchannel(pHddCtx, set_value); + if (ret < 0) + { + ret = -EINVAL; + goto exit; + } + } +#endif + else if (strncmp(command, "GETFWSTATS", 10) == 0) + { + eHalStatus status; + char *buf = NULL; + char len; + long waitRet; + fwStatsContext_t fwStatsCtx; + tSirFwStatsResult *fwStatsRsp = &(pAdapter->fwStatsRsp); + tANI_U8 *ptr = command; + int stats; + + ret = hdd_drv_cmd_validate(command, 10); + if (ret) + goto exit; + + stats = *(ptr + 11) - '0'; + hddLog(VOS_TRACE_LEVEL_INFO, FL("stats = %d "),stats); + if (!IS_FEATURE_FW_STATS_ENABLE) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Get Firmware stats feature not supported")); + ret = -EINVAL; + goto exit; + } + + if (FW_STATS_MAX <= stats || 0 >= stats) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL(" stats %d not supported"),stats); + ret = -EINVAL; + goto exit; + } + + init_completion(&(fwStatsCtx.completion)); + fwStatsCtx.magic = FW_STATS_CONTEXT_MAGIC; + fwStatsCtx.pAdapter = pAdapter; + fwStatsRsp->type = 0; + status = sme_GetFwStats( (tHalHandle)pHddCtx->hHal, stats, + &fwStatsCtx, hdd_FWStatisCB); + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL(" fail to post WDA cmd status = %d"), status); + ret = -EINVAL; + goto exit; + } + waitRet = wait_for_completion_timeout + (&(fwStatsCtx.completion), FW_STATE_WAIT_TIME); + if (waitRet <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed to wait on GwtFwstats")); + //Make magic number to zero so that callback is not executed. + spin_lock(&hdd_context_lock); + fwStatsCtx.magic = 0x0; + spin_unlock(&hdd_context_lock); + ret = -EINVAL; + goto exit; + } + if (fwStatsRsp->type) + { + buf = kmalloc(FW_STATE_RSP_LEN, GFP_KERNEL); + if (!buf) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL(" failed to allocate memory")); + ret = -ENOMEM; + goto exit; + } + switch( fwStatsRsp->type ) + { + case FW_UBSP_STATS: + { + len = snprintf(buf, FW_STATE_RSP_LEN, + "GETFWSTATS: ubsp_enter_cnt %d ubsp_jump_ddr_cnt %d", + fwStatsRsp->fwStatsData.ubspStats.ubsp_enter_cnt, + fwStatsRsp->fwStatsData.ubspStats.ubsp_jump_ddr_cnt); + } + break; + default: + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL( "No handling for stats type %d"),fwStatsRsp->type); + ret = -EFAULT; + kfree(buf); + goto exit; + } + } + if (copy_to_user(priv_data.buf, buf, len + 1)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL(" failed to copy data to user buffer")); + ret = -EFAULT; + kfree(buf); + goto exit; + } + ret = len; + kfree(buf); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed to fetch the stats")); + ret = -EFAULT; + goto exit; + } + + } + else if (strncasecmp(command, "SET_FCC_CHANNEL", 15) == 0) + { + ret = hdd_drv_cmd_validate(command, 15); + if (ret) + goto exit; + + /* + * this command wld be called by user-space when it detects WLAN + * ON after airplane mode is set. When APM is set, WLAN turns off. + * But it can be turned back on. Otherwise; when APM is turned back + * off, WLAN wld turn back on. So at that point the command is + * expected to come down. 0 means disable, 1 means enable. The + * constraint is removed when parameter 1 is set or different + * country code is set + */ + ret = hdd_cmd_setFccChannel(pHddCtx, command, 15); + } + else if (strncasecmp(command, "DISABLE_CA_EVENT", 16) == 0) + { + ret = hdd_drv_cmd_validate(command, 16); + if (ret) + goto exit; + + ret = hdd_enable_disable_ca_event(pHddCtx, command, 16); + } + else { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_UNSUPPORTED_IOCTL, + pAdapter->sessionId, 0)); + hddLog( VOS_TRACE_LEVEL_WARN, FL("Unsupported GUI command %s"), + command); + } + } +exit: + EXIT(); + if (command) + { + kfree(command); + } + return ret; +} + +#ifdef CONFIG_COMPAT +static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + struct { + compat_uptr_t buf; + int used_len; + int total_len; + } compat_priv_data; + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&compat_priv_data, ifr->ifr_data, + sizeof(compat_priv_data))) { + ret = -EFAULT; + goto exit; + } + priv_data.buf = compat_ptr(compat_priv_data.buf); + priv_data.used_len = compat_priv_data.used_len; + priv_data.total_len = compat_priv_data.total_len; + ret = hdd_driver_command(pAdapter, &priv_data); + exit: + return ret; +} +#else /* CONFIG_COMPAT */ +static int hdd_driver_compat_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + /* will never be invoked */ + return 0; +} +#endif /* CONFIG_COMPAT */ + +static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) +{ + hdd_priv_data_t priv_data; + int ret = 0; + + /* + * Note that pAdapter and ifr have already been verified by caller, + * and HDD context has also been validated + */ + if (copy_from_user(&priv_data, ifr->ifr_data, sizeof(priv_data))) { + ret = -EFAULT; + } else { + ret = hdd_driver_command(pAdapter, &priv_data); + } + return ret; +} + +int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter context is Null", __func__); + ret = -ENODEV; + goto exit; + } + if (dev != pAdapter->dev) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter/dev inconsistency", __func__); + ret = -ENODEV; + goto exit; + } + + if ((!ifr) || (!ifr->ifr_data)) { + ret = -EINVAL; + goto exit; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) { + ret = -EBUSY; + goto exit; + } + + switch (cmd) { + case (SIOCDEVPRIVATE + 1): + if (is_compat_task()) + ret = hdd_driver_compat_ioctl(pAdapter, ifr); + else + ret = hdd_driver_ioctl(pAdapter, ifr); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d", + __func__, cmd); + ret = -EINVAL; + break; + } + exit: + EXIT(); + return ret; +} + +int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_ioctl(dev, ifr, cmd); + vos_ssr_unprotect(__func__); + + return ret; +} + +int hdd_mon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + return 0; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + + \brief hdd_parse_ese_beacon_req() - Parse ese beacon request + + This function parses the ese beacon request passed in the format + CCXBEACONREQ + Channel 1Scan Mode Meas DurationChannel N + Scan Mode NMeas Duration N + if the Number of bcn req fields (N) does not match with the actual number of fields passed + then take N. + and are treated as one pair + For example, CCXBEACONREQ 2 1 1 1 30 2 44 0 40. + This function does not take care of removing duplicate channels from the list + + \param - pValue Pointer to data + \param - pEseBcnReq output pointer to store parsed ie information + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue, + tCsrEseBeaconReq *pEseBcnReq) +{ + tANI_U8 *inPtr = pValue; + uint8_t input = 0; + uint32_t tempInt = 0; + int j = 0, i = 0, v = 0; + char buf[32]; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) return -EINVAL; + + /*getting the first argument ie measurement token*/ + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos8(buf, 10, &input); + if ( v < 0) return -EINVAL; + + input = VOS_MIN(input, SIR_ESE_MAX_MEAS_IE_REQS); + pEseBcnReq->numBcnReqIe = input; + + hddLog(LOG1, "Number of Bcn Req Ie fields: %d", pEseBcnReq->numBcnReqIe); + + + for (j = 0; j < (pEseBcnReq->numBcnReqIe); j++) + { + for (i = 0; i < 4; i++) + { + /*inPtr pointing to the beginning of first space after number of ie fields*/ + inPtr = strpbrk( inPtr, " " ); + /*no ie data after the number of ie fields argument*/ + if (NULL == inPtr) return -EINVAL; + + /*removing empty space*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no ie data after the number of ie fields argument and spaces*/ + if ( '\0' == *inPtr ) return -EINVAL; + + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtou32(buf, 10, &tempInt); + if (v < 0) return -EINVAL; + + switch (i) + { + case 0: /* Measurement token */ + if (!tempInt) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Measurement Token: %u", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].measurementToken = tempInt; + break; + + case 1: /* Channel number */ + if ((!tempInt) || + (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Channel Number: %u", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].channel = tempInt; + break; + + case 2: /* Scan mode */ + if ((tempInt < eSIR_PASSIVE_SCAN) || (tempInt > eSIR_BEACON_TABLE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Scan Mode(%u) Expected{0|1|2}", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].scanMode= tempInt; + break; + + case 3: /* Measurement duration */ + if (((!tempInt) && (pEseBcnReq->bcnReq[j].scanMode != eSIR_BEACON_TABLE)) || + ((pEseBcnReq->bcnReq[j].scanMode == eSIR_BEACON_TABLE))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid Measurement Duration: %u", tempInt); + return -EINVAL; + } + pEseBcnReq->bcnReq[j].measurementDuration = tempInt; + break; + } + } + } + + for (j = 0; j < pEseBcnReq->numBcnReqIe; j++) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Index(%d) Measurement Token(%u)Channel(%u) Scan Mode(%u) Measurement Duration(%u)\n", + j, + pEseBcnReq->bcnReq[j].measurementToken, + pEseBcnReq->bcnReq[j].channel, + pEseBcnReq->bcnReq[j].scanMode, + pEseBcnReq->bcnReq[j].measurementDuration); + } + + return VOS_STATUS_SUCCESS; +} + +static void hdd_GetTsmStatsCB( tAniTrafStrmMetrics tsmMetrics, const tANI_U32 staId, void *pContext ) +{ + struct statsContext *pStatsContext = NULL; + hdd_adapter_t *pAdapter = NULL; + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the tsm stats */ + pAdapter->tsmStats.UplinkPktQueueDly = tsmMetrics.UplinkPktQueueDly; + vos_mem_copy(pAdapter->tsmStats.UplinkPktQueueDlyHist, + tsmMetrics.UplinkPktQueueDlyHist, + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/ + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0])); + pAdapter->tsmStats.UplinkPktTxDly = tsmMetrics.UplinkPktTxDly; + pAdapter->tsmStats.UplinkPktLoss = tsmMetrics.UplinkPktLoss; + pAdapter->tsmStats.UplinkPktCount = tsmMetrics.UplinkPktCount; + pAdapter->tsmStats.RoamingCount = tsmMetrics.RoamingCount; + pAdapter->tsmStats.RoamingDly = tsmMetrics.RoamingDly; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + + + +static VOS_STATUS hdd_get_tsm_stats(hdd_adapter_t *pAdapter, const tANI_U8 tid, + tAniTrafStrmMetrics* pTsmMetrics) +{ + hdd_station_ctx_t *pHddStaCtx = NULL; + eHalStatus hstatus; + VOS_STATUS vstatus = VOS_STATUS_SUCCESS; + long lrc; + struct statsContext context; + hdd_context_t *pHddCtx = NULL; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* we are connected prepare our callback context */ + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + + /* query tsm stats */ + hstatus = sme_GetTsmStats(pHddCtx->hHal, hdd_GetTsmStatsCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context, pHddCtx->pvosContext, tid); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unable to retrieve statistics", + __func__); + vstatus = VOS_STATUS_E_FAULT; + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while retrieving statistics", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + vstatus = VOS_STATUS_E_TIMEOUT; + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + if (VOS_STATUS_SUCCESS == vstatus) + { + pTsmMetrics->UplinkPktQueueDly = pAdapter->tsmStats.UplinkPktQueueDly; + vos_mem_copy(pTsmMetrics->UplinkPktQueueDlyHist, + pAdapter->tsmStats.UplinkPktQueueDlyHist, + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist)/ + sizeof(pAdapter->tsmStats.UplinkPktQueueDlyHist[0])); + pTsmMetrics->UplinkPktTxDly = pAdapter->tsmStats.UplinkPktTxDly; + pTsmMetrics->UplinkPktLoss = pAdapter->tsmStats.UplinkPktLoss; + pTsmMetrics->UplinkPktCount = pAdapter->tsmStats.UplinkPktCount; + pTsmMetrics->RoamingCount = pAdapter->tsmStats.RoamingCount; + pTsmMetrics->RoamingDly = pAdapter->tsmStats.RoamingDly; + } + return vstatus; +} +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +void hdd_getBand_helper(hdd_context_t *pHddCtx, int *pBand) +{ + eCsrBand band = -1; + sme_GetFreqBand((tHalHandle)(pHddCtx->hHal), &band); + switch (band) + { + case eCSR_BAND_ALL: + *pBand = WLAN_HDD_UI_BAND_AUTO; + break; + + case eCSR_BAND_24: + *pBand = WLAN_HDD_UI_BAND_2_4_GHZ; + break; + + case eCSR_BAND_5G: + *pBand = WLAN_HDD_UI_BAND_5_GHZ; + break; + + default: + hddLog( VOS_TRACE_LEVEL_WARN, "%s: Invalid Band %d", __func__, band); + *pBand = -1; + break; + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_send_action_frame_data() - HDD Parse send action frame data + + This function parses the send action frame data passed in the format + SENDACTIONFRAME + + \param - pValue Pointer to input data + \param - pTargetApBssid Pointer to target Ap bssid + \param - pChannel Pointer to the Target AP channel + \param - pDwellTime Pointer to the time to stay off-channel after transmitting action frame + \param - pBuf Pointer to data + \param - pBufLen Pointer to data length + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_parse_send_action_frame_data(tANI_U8 *pValue, tANI_U8 *pTargetApBssid, tANI_U8 *pChannel, + tANI_U8 *pDwellTime, tANI_U8 **pBuf, tANI_U8 *pBufLen) +{ + tANI_U8 *inPtr = pValue; + tANI_U8 *dataEnd; + int tempInt; + int j = 0; + int i = 0; + int v = 0; + tANI_U8 tempBuf[32]; + tANI_U8 tempByte = 0; + /* 12 hexa decimal digits, 5 ':' and '\0' */ + tANI_U8 macAddress[18]; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + v = sscanf(inPtr, "%17s", macAddress); + if (!((1 == v) && hdd_is_valid_mac_address(macAddress))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MAC address or All hex inputs are not read (%d)", v); + return -EINVAL; + } + + pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]); + pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]); + pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]); + pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]); + pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]); + pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]); + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the next argument ie the channel number */ + v = sscanf(inPtr, "%31s ", tempBuf); + if (1 != v) return -EINVAL; + + v = kstrtos32(tempBuf, 10, &tempInt); + if ( v < 0 || tempInt <= 0 || tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX ) + return -EINVAL; + + *pChannel = tempInt; + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the next argument ie the dwell time */ + v = sscanf(inPtr, "%31s ", tempBuf); + if (1 != v) return -EINVAL; + + v = kstrtos32(tempBuf, 10, &tempInt); + if ( v < 0 || tempInt < 0) return -EINVAL; + + *pDwellTime = tempInt; + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /* find the length of data */ + dataEnd = inPtr; + while(('\0' != *dataEnd) ) + { + dataEnd++; + } + *pBufLen = dataEnd - inPtr ; + if ( *pBufLen <= 0) return -EINVAL; + + /* Allocate the number of bytes based on the number of input characters + whether it is even or odd. + if the number of input characters are even, then we need N/2 byte. + if the number of input characters are odd, then we need do (N+1)/2 to + compensate rounding off. + For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough. + If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */ + *pBuf = vos_mem_malloc((*pBufLen + 1)/2); + if (NULL == *pBuf) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return -EINVAL; + } + + /* the buffer received from the upper layer is character buffer, + we need to prepare the buffer taking 2 characters in to a U8 hex decimal number + for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st + and f0 in 3rd location */ + for (i = 0, j = 0; j < *pBufLen; j += 2) + { + if( j+1 == *pBufLen) + { + tempByte = hdd_parse_hex(inPtr[j]); + } + else + { + tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1])); + } + (*pBuf)[i++] = tempByte; + } + *pBufLen = i; + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_parse_channellist() - HDD Parse channel list + + This function parses the channel list passed in the format + SETROAMSCANCHANNELSChannel 1Channel 2Channel N + if the Number of channels (N) does not match with the actual number of channels passed + then take the minimum of N and count of (Ch1, Ch2, ...Ch M) + For example, if SETROAMSCANCHANNELS 3 36 40 44 48, only 36, 40 and 44 shall be taken. + If SETROAMSCANCHANNELS 5 36 40 44 48, ignore 5 and take 36, 40, 44 and 48. + This function does not take care of removing duplicate channels from the list + + \param - pValue Pointer to input channel list + \param - ChannelList Pointer to local output array to record channel list + \param - pNumChannels Pointer to number of roam scan channels + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_parse_channellist(tANI_U8 *pValue, tANI_U8 *pChannelList, tANI_U8 *pNumChannels) +{ + tANI_U8 *inPtr = pValue; + int tempInt; + int j = 0; + int v = 0; + char buf[32]; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the first argument ie the number of channels*/ + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos32(buf, 10, &tempInt); + if ((v < 0) || + (tempInt <= 0) || + (tempInt > WNI_CFG_VALID_CHANNEL_LIST_LEN)) + { + return -EINVAL; + } + + *pNumChannels = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Number of channels are: %d", *pNumChannels); + + for (j = 0; j < (*pNumChannels); j++) + { + /*inPtr pointing to the beginning of first space after number of channels*/ + inPtr = strpbrk( inPtr, " " ); + /*no channel list after the number of channels argument*/ + if (NULL == inPtr) + { + if (0 != j) + { + *pNumChannels = j; + return VOS_STATUS_SUCCESS; + } + else + { + return -EINVAL; + } + } + + /*removing empty space*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr)) inPtr++; + + /*no channel list after the number of channels argument and spaces*/ + if ( '\0' == *inPtr ) + { + if (0 != j) + { + *pNumChannels = j; + return VOS_STATUS_SUCCESS; + } + else + { + return -EINVAL; + } + } + + v = sscanf(inPtr, "%31s ", buf); + if (1 != v) return -EINVAL; + + v = kstrtos32(buf, 10, &tempInt); + if ((v < 0) || + (tempInt <= 0) || + (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + return -EINVAL; + } + pChannelList[j] = tempInt; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "Channel %d added to preferred channel list", + pChannelList[j] ); + } + + return VOS_STATUS_SUCCESS; +} + + +/** + * hdd_parse_reassoc_command_v1_data() - HDD Parse reassoc command data + * This function parses the reasoc command data passed in the format + * REASSOC + * + * @pValue: Pointer to input data (its a NUL terminated string) + * @pTargetApBssid: Pointer to target Ap bssid + * @pChannel: Pointer to the Target AP channel + * + * Return: 0 for success non-zero for failure + */ +static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue, + tANI_U8 *pTargetApBssid, tANI_U8 *pChannel) +{ + const tANI_U8 *inPtr = pValue; + int tempInt; + int v = 0; + tANI_U8 tempBuf[32]; + /* 12 hexa decimal digits, 5 ':' and '\0' */ + tANI_U8 macAddress[18]; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + v = sscanf(inPtr, "%17s", macAddress); + if (!((1 == v) && hdd_is_valid_mac_address(macAddress))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid MAC address or All hex inputs are not read (%d)", v); + return -EINVAL; + } + + pTargetApBssid[0] = hdd_parse_hex(macAddress[0]) << 4 | hdd_parse_hex(macAddress[1]); + pTargetApBssid[1] = hdd_parse_hex(macAddress[3]) << 4 | hdd_parse_hex(macAddress[4]); + pTargetApBssid[2] = hdd_parse_hex(macAddress[6]) << 4 | hdd_parse_hex(macAddress[7]); + pTargetApBssid[3] = hdd_parse_hex(macAddress[9]) << 4 | hdd_parse_hex(macAddress[10]); + pTargetApBssid[4] = hdd_parse_hex(macAddress[12]) << 4 | hdd_parse_hex(macAddress[13]); + pTargetApBssid[5] = hdd_parse_hex(macAddress[15]) << 4 | hdd_parse_hex(macAddress[16]); + + /* point to the next argument */ + inPtr = strnchr(inPtr, strlen(inPtr), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) return -EINVAL; + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /*getting the next argument ie the channel number */ + v = sscanf(inPtr, "%31s ", tempBuf); + if (1 != v) return -EINVAL; + + v = kstrtos32(tempBuf, 10, &tempInt); + if ((v < 0) || + (tempInt < 0) || + (tempInt > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + return -EINVAL; + } + + *pChannel = tempInt; + return VOS_STATUS_SUCCESS; +} + +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + + \brief hdd_parse_get_cckm_ie() - HDD Parse and fetch the CCKM IE + + This function parses the SETCCKM IE command + SETCCKMIE + + \param - pValue Pointer to input data + \param - pCckmIe Pointer to output cckm Ie + \param - pCckmIeLen Pointer to output cckm ie length + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_parse_get_cckm_ie(tANI_U8 *pValue, tANI_U8 **pCckmIe, + tANI_U8 *pCckmIeLen) +{ + tANI_U8 *inPtr = pValue; + tANI_U8 *dataEnd; + int j = 0; + int i = 0; + tANI_U8 tempByte = 0; + + inPtr = strnchr(pValue, strlen(pValue), SPACE_ASCII_VALUE); + /*no argument after the command*/ + if (NULL == inPtr) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *inPtr) + { + return -EINVAL; + } + + /*removing empty spaces*/ + while ((SPACE_ASCII_VALUE == *inPtr) && ('\0' != *inPtr) ) inPtr++; + + /*no argument followed by spaces*/ + if ('\0' == *inPtr) + { + return -EINVAL; + } + + /* find the length of data */ + dataEnd = inPtr; + while(('\0' != *dataEnd) ) + { + dataEnd++; + ++(*pCckmIeLen); + } + if ( *pCckmIeLen <= 0) return -EINVAL; + + /* Allocate the number of bytes based on the number of input characters + whether it is even or odd. + if the number of input characters are even, then we need N/2 byte. + if the number of input characters are odd, then we need do (N+1)/2 to + compensate rounding off. + For example, if N = 18, then (18 + 1)/2 = 9 bytes are enough. + If N = 19, then we need 10 bytes, hence (19 + 1)/2 = 10 bytes */ + *pCckmIe = vos_mem_malloc((*pCckmIeLen + 1)/2); + if (NULL == *pCckmIe) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: vos_mem_alloc failed ", __func__); + return -EINVAL; + } + vos_mem_zero(*pCckmIe, (*pCckmIeLen + 1)/2); + /* the buffer received from the upper layer is character buffer, + we need to prepare the buffer taking 2 characters in to a U8 hex decimal number + for example 7f0000f0...form a buffer to contain 7f in 0th location, 00 in 1st + and f0 in 3rd location */ + for (i = 0, j = 0; j < *pCckmIeLen; j += 2) + { + tempByte = (hdd_parse_hex(inPtr[j]) << 4) | (hdd_parse_hex(inPtr[j + 1])); + (*pCckmIe)[i++] = tempByte; + } + *pCckmIeLen = i; + + return VOS_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/**--------------------------------------------------------------------------- + + \brief hdd_is_valid_mac_address() - Validate MAC address + + This function validates whether the given MAC address is valid or not + Expected MAC address is of the format XX:XX:XX:XX:XX:XX + where X is the hexa decimal digit character and separated by ':' + This algorithm works even if MAC address is not separated by ':' + + This code checks given input string mac contains exactly 12 hexadecimal digits. + and a separator colon : appears in the input string only after + an even number of hex digits. + + \param - pMacAddr pointer to the input MAC address + \return - 1 for valid and 0 for invalid + + --------------------------------------------------------------------------*/ + +v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr) +{ + int xdigit = 0; + int separator = 0; + while (*pMacAddr) + { + if (isxdigit(*pMacAddr)) + { + xdigit++; + } + else if (':' == *pMacAddr) + { + if (0 == xdigit || ((xdigit / 2) - 1) != separator) + break; + + ++separator; + } + else + { + separator = -1; + /* Invalid MAC found */ + return 0; + } + ++pMacAddr; + } + return (xdigit == 12 && (separator == 5 || separator == 0)); +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_open() - HDD Open function + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int __hdd_open(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + v_BOOL_t in_standby = TRUE; + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: pAdapter is Null", __func__); + return -ENODEV; + } + + pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST, + pAdapter->sessionId, pAdapter->device_mode)); + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return -ENODEV; + } + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) ) + { + if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: chip already out of standby", + __func__); + in_standby = FALSE; + break; + } + else + { + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + + if (TRUE == in_standby) + { + if (VOS_STATUS_SUCCESS != wlan_hdd_exit_lowpower(pHddCtx, pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to bring " + "wlan out of power save", __func__); + return -EINVAL; + } + } + + set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags); + if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Enabling Tx Queues", __func__); + /* Enable TX queues only when we are connected */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues(dev); + } + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_open() - Wrapper function for __hdd_open to protect it from SSR + + This is called in response to ifconfig up + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ +int hdd_open(struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_open(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +int __hdd_mon_open (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + if(pAdapter == NULL) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter context is Null", __func__); + return -EINVAL; + } + + return 0; +} + +int hdd_mon_open (struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_mon_open(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +int hdd_mon_stop(struct net_device *dev) +{ + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_stop() - HDD stop function + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure + + --------------------------------------------------------------------------*/ + +int __hdd_stop (struct net_device *dev) +{ + int ret = 0; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + v_BOOL_t enter_standby = TRUE; + + ENTER(); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: pAdapter is Null", __func__); + return -ENODEV; + } + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST, + pAdapter->sessionId, pAdapter->device_mode)); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (ret) + { + return ret; + } + + /* Nothing to be done if the interface is not opened */ + if (VOS_FALSE == test_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NETDEV Interface is not OPENED", __func__); + return -ENODEV; + } + + /* Make sure the interface is marked as closed */ + clear_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__); + + /* Disable TX on the interface, after this hard_start_xmit() will not + * be called on that interface + */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + + /* Mark the interface status as "down" for outside world */ + netif_carrier_off(pAdapter->dev); + + /* The interface is marked as down for outside world (aka kernel) + * But the driver is pretty much alive inside. The driver needs to + * tear down the existing connection on the netdev (session) + * cleanup the data pipes and wait until the control plane is stabilized + * for this interface. The call also needs to wait until the above + * mentioned actions are completed before returning to the caller. + * Notice that the hdd_stop_adapter is requested not to close the session + * That is intentional to be able to scan if it is a STA/P2P interface + */ + hdd_stop_adapter(pHddCtx, pAdapter, VOS_FALSE); +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); +#endif + /* DeInit the adapter. This ensures datapath cleanup as well */ + hdd_deinit_adapter(pHddCtx, pAdapter, TRUE); +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + /* SoftAP ifaces should never go in power save mode + making sure same here. */ + if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode ) + || (WLAN_HDD_MONITOR == pAdapter->device_mode ) + || (WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + /* SoftAP mode, so return from here */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: In SAP MODE", __func__); + EXIT(); + return 0; + } + /* Find if any iface is up. If any iface is up then can't put device to + * sleep/power save mode + */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( (NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status) ) + { + if (test_bit(DEVICE_IFACE_OPENED, &pAdapterNode->pAdapter->event_flags)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Still other ifaces are up cannot " + "put device to sleep", __func__); + enter_standby = FALSE; + break; + } + else + { + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + } + + if (TRUE == enter_standby) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: All Interfaces are Down " + "entering standby", __func__); + if (VOS_STATUS_SUCCESS != wlan_hdd_enter_lowpower(pHddCtx)) + { + /*log and return success*/ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed to put " + "wlan in power save", __func__); + } + } + + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_stop() - wrapper_function for __hdd_stop to protect it from SSR + + This is called in response to ifconfig down + + \param - dev Pointer to net_device structure + + \return - 0 for success non-zero for failure +-----------------------------------------------------------------------------*/ +int hdd_stop (struct net_device *dev) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_stop(dev); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_uninit() - HDD uninit function + + \param - dev Pointer to net_device structure + + \return - void + + --------------------------------------------------------------------------*/ +static void __hdd_uninit (struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + ENTER(); + + do + { + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: NULL pAdapter", __func__); + break; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Invalid magic", __func__); + break; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: NULL pHddCtx", __func__); + break; + } + + if (dev != pAdapter->dev) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Invalid device reference", __func__); + /* we haven't validated all cases so let this go for now */ + } +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); +#endif + hdd_deinit_adapter(pHddCtx, pAdapter, TRUE); +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + + /* after uninit our adapter structure will no longer be valid */ + pAdapter->dev = NULL; + pAdapter->magic = 0; + pAdapter->pHddCtx = NULL; + } while (0); + + EXIT(); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR + + This is called during the netdev unregister to uninitialize all data +associated with the device + + \param - dev Pointer to net_device structure + + \return - void + + --------------------------------------------------------------------------*/ +static void hdd_uninit (struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_uninit(dev); + vos_ssr_unprotect(__func__); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_release_firmware() - + + This function calls the release firmware API to free the firmware buffer. + + \param - pFileName Pointer to the File Name. + pCtx - Pointer to the adapter . + + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx = (hdd_context_t*)pCtx; + ENTER(); + + + if (!strcmp(WLAN_FW_FILE, pFileName)) { + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: Loaded firmware file is %s",__func__,pFileName); + + if(pHddCtx->fw) { + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + } + else + status = VOS_STATUS_E_FAILURE; + } + else if (!strcmp(WLAN_NV_FILE,pFileName)) { + if(pHddCtx->nv) { + release_firmware(pHddCtx->nv); + pHddCtx->nv = NULL; + } + else + status = VOS_STATUS_E_FAILURE; + + } + + EXIT(); + return status; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_request_firmware() - + + This function reads the firmware file using the request firmware + API and returns the the firmware data and the firmware file size. + + \param - pfileName - Pointer to the file name. + - pCtx - Pointer to the adapter . + - ppfw_data - Pointer to the pointer of the firmware data. + - pSize - Pointer to the file size. + + \return - VOS_STATUS_SUCCESS for success, VOS_STATUS_E_FAILURE for failure + + --------------------------------------------------------------------------*/ + + +VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize) +{ + int status; + VOS_STATUS retval = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx = (hdd_context_t*)pCtx; + ENTER(); + + if( (!strcmp(WLAN_FW_FILE, pfileName)) ) { + + status = request_firmware(&pHddCtx->fw, pfileName, pHddCtx->parent_dev); + + if(status || !pHddCtx->fw || !pHddCtx->fw->data) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Firmware %s download failed", + __func__, pfileName); + retval = VOS_STATUS_E_FAILURE; + } + + else { + *ppfw_data = (v_VOID_t *)pHddCtx->fw->data; + *pSize = pHddCtx->fw->size; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Firmware size = %d", + __func__, *pSize); + } + } + else if(!strcmp(WLAN_NV_FILE, pfileName)) { + + status = request_firmware(&pHddCtx->nv, pfileName, pHddCtx->parent_dev); + + if(status || !pHddCtx->nv || !pHddCtx->nv->data) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: nv %s download failed", + __func__, pfileName); + retval = VOS_STATUS_E_FAILURE; + } + + else { + *ppfw_data = (v_VOID_t *)pHddCtx->nv->data; + *pSize = pHddCtx->nv->size; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: nv file size = %d", + __func__, *pSize); + } + } + + EXIT(); + return retval; +} +/**--------------------------------------------------------------------------- + \brief hdd_full_pwr_cbk() - HDD full power callbackfunction + + This is the function invoked by SME to inform the result of a full power + request issued by HDD + + \param - callbackcontext - Pointer to cookie + status - result of request + + \return - None + +--------------------------------------------------------------------------*/ +void hdd_full_pwr_cbk(void *callbackContext, eHalStatus status) +{ + hdd_context_t *pHddCtx = (hdd_context_t*)callbackContext; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"HDD full Power callback status = %d", status); + if(&pHddCtx->full_pwr_comp_var) + { + complete(&pHddCtx->full_pwr_comp_var); + } +} + +#ifdef WLAN_FEATURE_RMC +static void hdd_tx_fail_ind_callback(v_U8_t *MacAddr, v_U8_t seqNo) +{ + int payload_len; + struct sk_buff *skb; + struct nlmsghdr *nlh; + v_U8_t *data; + + payload_len = ETH_ALEN; + + if (0 == cesium_pid) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: cesium process not registered", + __func__); + return; + } + + if ((skb = nlmsg_new(payload_len,GFP_ATOMIC)) == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: nlmsg_new() failed for msg size[%d]", + __func__, NLMSG_SPACE(payload_len)); + return; + } + + nlh = nlmsg_put(skb, cesium_pid, seqNo, 0, payload_len, NLM_F_REQUEST); + + if (NULL == nlh) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: nlmsg_put() failed for msg size[%d]", + __func__, NLMSG_SPACE(payload_len)); + + kfree_skb(skb); + return; + } + + data = nlmsg_data(nlh); + memcpy(data, MacAddr, ETH_ALEN); + + if (nlmsg_unicast(cesium_nl_srv_sock, skb, cesium_pid) < 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_unicast() failed for msg size[%d]", + __func__, NLMSG_SPACE(payload_len)); + } + + return; +} + +/**--------------------------------------------------------------------------- + \brief hdd_ParseuserParams - return a pointer to the next argument + + \return - status + +--------------------------------------------------------------------------*/ +static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg) +{ + tANI_U8 *pVal; + + pVal = strchr(pValue, ' '); + + if (NULL == pVal) + { + /* no argument remains */ + return -EINVAL; + } + else if (SPACE_ASCII_VALUE != *pVal) + { + /* no space after the current argument */ + return -EINVAL; + } + + pVal++; + + /* remove empty spaces */ + while ((SPACE_ASCII_VALUE == *pVal) && ('\0' != *pVal)) + { + pVal++; + } + + /* no argument followed by spaces */ + if ('\0' == *pVal) + { + return -EINVAL; + } + + *ppArg = pVal; + + return 0; +} + +/**---------------------------------------------------------------------------- + \brief hdd_ParseIBSSTXFailEventParams - Parse params for SETIBSSTXFAILEVENT + + \return - status + +------------------------------------------------------------------------------*/ +static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue, + tANI_U8 *tx_fail_count, + tANI_U16 *pid) +{ + tANI_U8 *param = NULL; + int ret; + + ret = hdd_ParseUserParams(pValue, ¶m); + + if (0 == ret && NULL != param) + { + if (1 != sscanf(param, "%hhu", tx_fail_count)) + { + ret = -EINVAL; + goto done; + } + } + else + { + goto done; + } + + if (0 == *tx_fail_count) + { + *pid = 0; + goto done; + } + + pValue = param; + pValue++; + + ret = hdd_ParseUserParams(pValue, ¶m); + + if (0 == ret) + { + if (1 != sscanf(param, "%hu", pid)) + { + ret = -EINVAL; + goto done; + } + } + else + { + goto done; + } + +done: + return ret; +} + +static int hdd_open_cesium_nl_sock() +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct netlink_kernel_cfg cfg = { + .groups = WLAN_NLINK_MCAST_GRP_ID, + .input = NULL + }; +#endif + int ret = 0; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + THIS_MODULE, +#endif + &cfg); +#else + cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM, + WLAN_NLINK_MCAST_GRP_ID, NULL, NULL, THIS_MODULE); +#endif + + if (cesium_nl_srv_sock == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLINK: cesium netlink_kernel_create failed"); + ret = -ECONNREFUSED; + } + + return ret; +} + +static void hdd_close_cesium_nl_sock() +{ + if (NULL != cesium_nl_srv_sock) + { + netlink_kernel_release(cesium_nl_srv_sock); + cesium_nl_srv_sock = NULL; + } +} +#endif /* WLAN_FEATURE_RMC */ +/**--------------------------------------------------------------------------- + + \brief hdd_req_bmps_cbk() - HDD Request BMPS callback function + + This is the function invoked by SME to inform the result of BMPS + request issued by HDD + + \param - callbackcontext - Pointer to cookie + status - result of request + + \return - None + +--------------------------------------------------------------------------*/ +void hdd_req_bmps_cbk(void *callbackContext, eHalStatus status) +{ + + struct completion *completion_var = (struct completion*) callbackContext; + + hddLog(VOS_TRACE_LEVEL_ERROR, "HDD BMPS request Callback, status = %d", status); + if(completion_var != NULL) + { + complete(completion_var); + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_get_cfg_file_size() - + + This function reads the configuration file using the request firmware + API and returns the configuration file size. + + \param - pCtx - Pointer to the adapter . + - pFileName - Pointer to the file name. + - pBufSize - Pointer to the buffer size. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize) +{ + int status; + hdd_context_t *pHddCtx = (hdd_context_t*)pCtx; + + ENTER(); + + status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev); + + if(status || !pHddCtx->fw || !pHddCtx->fw->data) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__); + status = VOS_STATUS_E_FAILURE; + } + else { + *pBufSize = pHddCtx->fw->size; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: CFG size = %d", __func__, *pBufSize); + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + } + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_read_cfg_file() - + + This function reads the configuration file using the request firmware + API and returns the cfg data and the buffer size of the configuration file. + + \param - pCtx - Pointer to the adapter . + - pFileName - Pointer to the file name. + - pBuffer - Pointer to the data buffer. + - pBufSize - Pointer to the buffer size. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName, + v_VOID_t *pBuffer, v_SIZE_t *pBufSize) +{ + int status; + hdd_context_t *pHddCtx = (hdd_context_t*)pCtx; + + ENTER(); + + status = request_firmware(&pHddCtx->fw, pFileName, pHddCtx->parent_dev); + + if(status || !pHddCtx->fw || !pHddCtx->fw->data) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: CFG download failed",__func__); + return VOS_STATUS_E_FAILURE; + } + else { + if(*pBufSize != pHddCtx->fw->size) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Caller sets invalid CFG " + "file size", __func__); + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + return VOS_STATUS_E_FAILURE; + } + else { + if(pBuffer) { + vos_mem_copy(pBuffer,pHddCtx->fw->data,*pBufSize); + } + release_firmware(pHddCtx->fw); + pHddCtx->fw = NULL; + } + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief __hdd_set_mac_address() - + + This function sets the user specified mac address using + the command ifconfig wlanX hw ether . + + \param - dev - Pointer to the net device. + - addr - Pointer to the sockaddr. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static int __hdd_set_mac_address(struct net_device *dev, void *addr) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + struct sockaddr *psta_mac_addr = addr; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN); + memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); + + EXIT(); + return halStatus; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_set_mac_address() - + + Wrapper function to protect __hdd_set_mac_address() function from ssr + + \param - dev - Pointer to the net device. + - addr - Pointer to the sockaddr. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int hdd_set_mac_address(struct net_device *dev, void *addr) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_set_mac_address(dev, addr); + vos_ssr_unprotect(__func__); + + return ret; +} + +tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx) +{ + int i; + for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) + { + if( 0 == ((pHddCtx->cfg_ini->intfAddrMask) & (1 << i)) ) + break; + } + + if( VOS_MAX_CONCURRENCY_PERSONA == i) + return NULL; + + pHddCtx->cfg_ini->intfAddrMask |= (1 << i); + return &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0]; +} + +void wlan_hdd_release_intf_addr(hdd_context_t* pHddCtx, tANI_U8* releaseAddr) +{ + int i; + for ( i = 0; i < VOS_MAX_CONCURRENCY_PERSONA; i++) + { + if ( !memcmp(releaseAddr, &pHddCtx->cfg_ini->intfMacAddr[i].bytes[0], 6) ) + { + pHddCtx->cfg_ini->intfAddrMask &= ~(1 << i); + break; + } + } + return; +} + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) + static struct net_device_ops wlan_drv_ops = { + .ndo_open = hdd_open, + .ndo_stop = hdd_stop, + .ndo_uninit = hdd_uninit, + .ndo_start_xmit = hdd_hard_start_xmit, + .ndo_tx_timeout = hdd_tx_timeout, + .ndo_get_stats = hdd_stats, + .ndo_do_ioctl = hdd_ioctl, + .ndo_set_mac_address = hdd_set_mac_address, + .ndo_select_queue = hdd_select_queue, +#ifdef WLAN_FEATURE_PACKET_FILTERING +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0)) + .ndo_set_rx_mode = hdd_set_multicast_list, +#else + .ndo_set_multicast_list = hdd_set_multicast_list, +#endif //LINUX_VERSION_CODE +#endif + }; + static struct net_device_ops wlan_mon_drv_ops = { + .ndo_open = hdd_mon_open, + .ndo_stop = hdd_mon_stop, + .ndo_uninit = hdd_uninit, + .ndo_start_xmit = hdd_mon_hard_start_xmit, + .ndo_tx_timeout = hdd_tx_timeout, + .ndo_get_stats = hdd_stats, + .ndo_do_ioctl = hdd_mon_ioctl, + .ndo_set_mac_address = hdd_set_mac_address, + }; + +#endif + +void hdd_set_station_ops( struct net_device *pWlanDev ) +{ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) + pWlanDev->netdev_ops = &wlan_drv_ops; +#else + pWlanDev->open = hdd_open; + pWlanDev->stop = hdd_stop; + pWlanDev->uninit = hdd_uninit; + pWlanDev->hard_start_xmit = NULL; + pWlanDev->tx_timeout = hdd_tx_timeout; + pWlanDev->get_stats = hdd_stats; + pWlanDev->do_ioctl = hdd_ioctl; + pWlanDev->set_mac_address = hdd_set_mac_address; +#endif +} + +void hdd_set_ibss_ops( hdd_adapter_t *pAdapter ) +{ + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) + wlan_drv_ops.ndo_start_xmit = hdd_ibss_hard_start_xmit; + #else + pAdapter->dev->hard_start_xmit = hdd_ibss_hard_start_xmit; + #endif +} + +static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMacAddr macAddr, const char* name ) +{ + struct net_device *pWlanDev = NULL; + hdd_adapter_t *pAdapter = NULL; + /* + * cfg80211 initialization and registration.... + */ + pWlanDev = alloc_netdev_mq(sizeof( hdd_adapter_t ), name, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) + NET_NAME_UNKNOWN, +#endif + ether_setup, NUM_TX_QUEUES); + if(pWlanDev != NULL) + { + + //Save the pointer to the net_device in the HDD adapter + pAdapter = (hdd_adapter_t*) netdev_priv( pWlanDev ); + + vos_mem_zero( pAdapter, sizeof( hdd_adapter_t ) ); + + pAdapter->dev = pWlanDev; + pAdapter->pHddCtx = pHddCtx; + pAdapter->magic = WLAN_HDD_ADAPTER_MAGIC; + spin_lock_init(&pAdapter->lock_for_active_session); + +#ifdef FEATURE_WLAN_BATCH_SCAN + pAdapter->pBatchScanRsp = NULL; + pAdapter->numScanList = 0; + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + pAdapter->prev_batch_id = 0; + mutex_init(&pAdapter->hdd_batch_scan_lock); +#endif + + pAdapter->isLinkUpSvcNeeded = FALSE; + pAdapter->higherDtimTransition = eANI_BOOLEAN_TRUE; + //Init the net_device structure + strlcpy(pWlanDev->name, name, IFNAMSIZ); + + vos_mem_copy(pWlanDev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr)); + vos_mem_copy( pAdapter->macAddressCurrent.bytes, macAddr, sizeof(tSirMacAddr)); + pWlanDev->watchdog_timeo = HDD_TX_TIMEOUT; + pWlanDev->hard_header_len += LIBRA_HW_NEEDED_HEADROOM; + + hdd_set_station_ops( pAdapter->dev ); + + pWlanDev->destructor = free_netdev; + pWlanDev->ieee80211_ptr = &pAdapter->wdev ; + pAdapter->wdev.wiphy = pHddCtx->wiphy; + pAdapter->wdev.netdev = pWlanDev; + /* set pWlanDev's parent to underlying device */ + SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev); + + hdd_wmm_init( pAdapter ); + } + + return pAdapter; +} + +VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held ) +{ + struct net_device *pWlanDev = pAdapter->dev; + //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + //eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + if( rtnl_lock_held ) + { + if (strnchr(pWlanDev->name, strlen(pWlanDev->name), '%')) { + if( dev_alloc_name(pWlanDev, pWlanDev->name) < 0 ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:dev_alloc_name",__func__); + return VOS_STATUS_E_FAILURE; + } + } + if (register_netdevice(pWlanDev)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s:Failed:register_netdev",__func__); + return VOS_STATUS_E_FAILURE; + } + } + else + { + if(register_netdev(pWlanDev)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed:register_netdev",__func__); + return VOS_STATUS_E_FAILURE; + } + } + set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags); + + return VOS_STATUS_SUCCESS; +} + +static eHalStatus hdd_smeCloseSessionCallback(void *pContext) +{ + hdd_adapter_t *pAdapter = pContext; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: NULL pAdapter", __func__); + return eHAL_STATUS_INVALID_PARAMETER; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid magic", __func__); + return eHAL_STATUS_NOT_INITIALIZED; + } + + clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags); + +#ifndef WLAN_OPEN_SOURCE + /* need to make sure all of our scheduled work has completed. + * This callback is called from MC thread context, so it is safe to + * to call below flush workqueue API from here. + * + * Even though this is called from MC thread context, if there is a faulty + * work item in the system, that can hang this call forever. So flushing + * this global work queue is not safe; and now we make sure that + * individual work queues are stopped correctly. But the cancel work queue + * is a GPL only API, so the proprietary version of the driver would still + * rely on the global work queue flush. + */ + flush_scheduled_work(); +#endif + + /* We can be blocked while waiting for scheduled work to be + * flushed, and the adapter structure can potentially be freed, in + * which case the magic will have been reset. So make sure the + * magic is still good, and hence the adapter structure is still + * valid, before signaling completion */ + if (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic) + { + complete(&pAdapter->session_close_comp_var); + } + + return eHAL_STATUS_SUCCESS; +} +/** + * hdd_close_tx_queues() - close tx queues + * @hdd_ctx: hdd global context + * + * Return: None + */ +static void hdd_close_tx_queues(hdd_context_t *hdd_ctx) +{ + VOS_STATUS status; + hdd_adapter_t *adapter; + hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL; + /* Not validating hdd_ctx as it's already done by the caller */ + ENTER(); + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (adapter && adapter->dev) { + netif_tx_disable (adapter->dev); + netif_carrier_off(adapter->dev); + } + status = hdd_get_next_adapter(hdd_ctx, adapter_node, + &next_adapter); + adapter_node = next_adapter; + } + EXIT(); +} + +VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter ) +{ + struct net_device *pWlanDev = pAdapter->dev; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + long rc = 0; + + spin_lock_init( &pAdapter->sta_hash_lock); + pAdapter->is_sta_id_hash_initialized = VOS_FALSE; + + INIT_COMPLETION(pAdapter->session_open_comp_var); + sme_SetCurrDeviceMode(pHddCtx->hHal, pAdapter->device_mode); + //Open a SME session for future operation + halStatus = sme_OpenSession( pHddCtx->hHal, hdd_smeRoamCallback, pAdapter, + (tANI_U8 *)&pAdapter->macAddressCurrent, &pAdapter->sessionId); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "sme_OpenSession() failed with status code %08d [x%08x]", + halStatus, halStatus ); + status = VOS_STATUS_E_FAILURE; + goto error_sme_open; + } + + //Block on a completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pAdapter->session_open_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + if (rc <= 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "Session is not opened within timeout period code %ld", rc ); + status = VOS_STATUS_E_FAILURE; + goto error_sme_open; + } + + // Register wireless extensions + if( eHAL_STATUS_SUCCESS != (halStatus = hdd_register_wext(pWlanDev))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_register_wext() failed with status code %08d [x%08x]", + halStatus, halStatus ); + status = VOS_STATUS_E_FAILURE; + goto error_register_wext; + } + + //Safe to register the hard_start_xmit function again + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) + wlan_drv_ops.ndo_start_xmit = hdd_hard_start_xmit; + #else + pWlanDev->hard_start_xmit = hdd_hard_start_xmit; + #endif + + //Set the Connection State to Not Connected + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + + //Set the default operation channel + pHddStaCtx->conn_info.operationChannel = pHddCtx->cfg_ini->OperatingChannel; + + /* Make the default Auth Type as OPEN*/ + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + if( VOS_STATUS_SUCCESS != ( status = hdd_init_tx_rx( pAdapter ) ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_init_tx_rx() failed with status code %08d [x%08x]", + status, status ); + goto error_init_txrx; + } + + set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + + if( VOS_STATUS_SUCCESS != ( status = hdd_wmm_adapter_init( pAdapter ) ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_wmm_adapter_init() failed with status code %08d [x%08x]", + status, status ); + goto error_wmm_init; + } + + set_bit(WMM_INIT_DONE, &pAdapter->event_flags); + + return VOS_STATUS_SUCCESS; + +error_wmm_init: + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + hdd_deinit_tx_rx(pAdapter); +error_init_txrx: + hdd_UnregisterWext(pWlanDev); +error_register_wext: + if (test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) + { + INIT_COMPLETION(pAdapter->session_close_comp_var); + if (eHAL_STATUS_SUCCESS == sme_CloseSession(pHddCtx->hHal, + pAdapter->sessionId, FALSE, VOS_TRUE, + hdd_smeCloseSessionCallback, pAdapter)) + { + unsigned long rc; + + //Block on a completion variable. Can't wait forever though. + rc = wait_for_completion_timeout( + &pAdapter->session_close_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + if (rc <= 0) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Session is not opened within timeout period code %ld"), rc); + } +} +error_sme_open: + return status; +} + +void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter ) +{ + hdd_cfg80211_state_t *cfgState; + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if( NULL != cfgState->buf ) + { + long rc; + INIT_COMPLETION(pAdapter->tx_action_cnf_event); + rc = wait_for_completion_interruptible_timeout( + &pAdapter->tx_action_cnf_event, + msecs_to_jiffies(ACTION_FRAME_TX_TIMEOUT)); + if (rc <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s ERROR: HDD Wait for Action Confirmation Failed!! %ld" + , __func__, rc); + + // Inform tx status as FAILURE to upper layer and free cfgState->buf + hdd_sendActionCnf( pAdapter, FALSE ); + } + } + return; +} + +void hdd_deinit_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held ) +{ + ENTER(); + switch ( pAdapter->device_mode ) + { + case WLAN_HDD_IBSS: + { + if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags)) + { + hdd_ibss_deinit_tx_rx( pAdapter ); + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + } + } + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + { + if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags)) + { + hdd_deinit_tx_rx( pAdapter ); + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + } + + if(test_bit(WMM_INIT_DONE, &pAdapter->event_flags)) + { + hdd_wmm_adapter_close( pAdapter ); + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + } + + hdd_cleanup_actionframe(pHddCtx, pAdapter); + break; + } + + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + { + + if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags)) + { + hdd_wmm_adapter_close( pAdapter ); + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + } + + hdd_cleanup_actionframe(pHddCtx, pAdapter); + + hdd_unregister_hostapd(pAdapter, rtnl_held); + /* set con_mode to STA only when no SAP concurrency mode */ + if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO))) + hdd_set_conparam(0); + break; + } + + case WLAN_HDD_MONITOR: + { + if(test_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags)) + { + hdd_deinit_tx_rx( pAdapter ); + clear_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + } + break; + } + + + default: + break; + } + + EXIT(); +} + +void hdd_cleanup_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, tANI_U8 rtnl_held ) +{ + struct net_device *pWlanDev = NULL; + + ENTER(); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return; + } + + pWlanDev = pAdapter->dev; + +#ifdef FEATURE_WLAN_BATCH_SCAN + if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) + ) + { + if (pAdapter) + { + if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState) + { + hdd_deinit_batch_scan(pAdapter); + } + } + } +#endif + + if(test_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags)) { + if( rtnl_held ) + { + unregister_netdevice(pWlanDev); + } + else + { + unregister_netdev(pWlanDev); + } + // note that the pAdapter is no longer valid at this point + // since the memory has been reclaimed + } + + EXIT(); +} + +void hdd_set_pwrparams(hdd_context_t *pHddCtx) +{ + VOS_STATUS status; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + /*loop through all adapters.*/ + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION != pAdapter->device_mode) + && (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode) ) + + { // we skip this registration for modes other than STA and P2P client modes. + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + continue; + } + + //Apply Dynamic DTIM For P2P + //Only if ignoreDynamicDtimInP2pMode is not set in ini + if ((pHddCtx->cfg_ini->enableDynamicDTIM || + pHddCtx->cfg_ini->enableModulatedDTIM) && + ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + ((WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) && + !(pHddCtx->cfg_ini->ignoreDynamicDtimInP2pMode))) && + (eANI_BOOLEAN_TRUE == pAdapter->higherDtimTransition) && + (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) && + (pHddCtx->cfg_ini->fIsBmpsEnabled)) + { + tSirSetPowerParamsReq powerRequest = { 0 }; + + powerRequest.uIgnoreDTIM = 1; + powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + + if (pHddCtx->cfg_ini->enableModulatedDTIM) + { + powerRequest.uDTIMPeriod = pHddCtx->cfg_ini->enableModulatedDTIM; + powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value; + } + else + { + powerRequest.uListenInterval = pHddCtx->cfg_ini->enableDynamicDTIM; + } + + /* Update ignoreDTIM and ListedInterval in CFG to remain at the DTIM + * specified during Enter/Exit BMPS when LCD off*/ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM, + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval, + NULL, eANI_BOOLEAN_FALSE); + + /* switch to the DTIM specified in cfg.ini */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Switch to DTIM %d Listen interval %d", + powerRequest.uDTIMPeriod, + powerRequest.uListenInterval); + sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE); + break; + + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } +} + +void hdd_reset_pwrparams(hdd_context_t *pHddCtx) +{ + /*Switch back to DTIM 1*/ + tSirSetPowerParamsReq powerRequest = { 0 }; + + powerRequest.uIgnoreDTIM = pHddCtx->hdd_actual_ignore_DTIM_value; + powerRequest.uListenInterval = pHddCtx->hdd_actual_LI_value; + powerRequest.uMaxLIModulatedDTIM = pHddCtx->cfg_ini->fMaxLIModulatedDTIM; + + /* Update ignoreDTIM and ListedInterval in CFG with default values */ + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, powerRequest.uIgnoreDTIM, + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, powerRequest.uListenInterval, + NULL, eANI_BOOLEAN_FALSE); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Switch to DTIM%d",powerRequest.uListenInterval); + sme_SetPowerParams( pHddCtx->hHal, &powerRequest, TRUE); + +} + +VOS_STATUS hdd_enable_bmps_imps(hdd_context_t *pHddCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx)) + { + hddLog( LOGE, FL("Wlan Unload in progress")); + return VOS_STATUS_E_PERM; + } + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + { + sme_EnablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + } + + if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled) + { + sme_StartAutoBmpsTimer(pHddCtx->hHal); + } + + if (pHddCtx->cfg_ini->fIsImpsEnabled) + { + sme_EnablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + + return status; +} + +VOS_STATUS hdd_disable_bmps_imps(hdd_context_t *pHddCtx, tANI_U8 session_type) +{ + hdd_adapter_t *pAdapter = NULL; + eHalStatus halStatus; + VOS_STATUS status = VOS_STATUS_E_INVAL; + v_BOOL_t disableBmps = FALSE; + v_BOOL_t disableImps = FALSE; + + switch(session_type) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_GO: + //Exit BMPS -> Is Sta/P2P Client is already connected + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if((NULL != pAdapter)&& + hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + disableBmps = TRUE; + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT); + if((NULL != pAdapter)&& + hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) + { + disableBmps = TRUE; + } + + //Exit both Bmps and Imps incase of Go/SAP Mode + if((WLAN_HDD_SOFTAP == session_type) || + (WLAN_HDD_P2P_GO == session_type)) + { + disableBmps = TRUE; + disableImps = TRUE; + } + + if(TRUE == disableImps) + { + if (pHddCtx->cfg_ini->fIsImpsEnabled) + { + sme_DisablePowerSave (pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + } + } + + if(TRUE == disableBmps) + { + if(pHddCtx->cfg_ini->fIsBmpsEnabled) + { + halStatus = sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + + if(eHAL_STATUS_SUCCESS != halStatus) + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Disable Power Save", __func__); + VOS_ASSERT(0); + return status; + } + } + + if(pHddCtx->cfg_ini->fIsAutoBmpsTimerEnabled) + { + halStatus = sme_StopAutoBmpsTimer(pHddCtx->hHal); + + if(eHAL_STATUS_SUCCESS != halStatus) + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Stop Auto Bmps Timer", __func__); + VOS_ASSERT(0); + return status; + } + } + } + + if((TRUE == disableBmps) || + (TRUE == disableImps)) + { + /* Now, get the chip into Full Power now */ + INIT_COMPLETION(pHddCtx->full_pwr_comp_var); + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_pwr_cbk, + pHddCtx, eSME_FULL_PWR_NEEDED_BY_HDD); + + if(halStatus != eHAL_STATUS_SUCCESS) + { + if(halStatus == eHAL_STATUS_PMC_PENDING) + { + long ret; + //Block on a completion variable. Can't wait forever though + ret = wait_for_completion_interruptible_timeout( + &pHddCtx->full_pwr_comp_var, + msecs_to_jiffies(1000)); + if (ret <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: wait on full_pwr_comp_var failed %ld", + __func__, ret); + } + } + else + { + status = VOS_STATUS_E_FAILURE; + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Request for Full Power failed", __func__); + VOS_ASSERT(0); + return status; + } + } + + status = VOS_STATUS_SUCCESS; + } + + break; + } + return status; +} + +void hdd_monPostMsgCb(tANI_U32 *magic, struct completion *cmpVar) +{ + if (magic == NULL || cmpVar == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid arguments %p %p"), magic, cmpVar); + return; + } + if (*magic != MON_MODE_MSG_MAGIC) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("maic: %x"), *magic); + return; + } + + complete(cmpVar); + return; +} + +void hdd_init_mon_mode (hdd_adapter_t *pAdapter) + { + hdd_mon_ctx_t *pMonCtx = NULL; + pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter); + + pMonCtx->state = 0; + pMonCtx->ChannelNo = 1; + pMonCtx->ChannelBW = 20; + pMonCtx->crcCheckEnabled = 1; + pMonCtx->typeSubtypeBitmap = 0xFFFF00000000; + pMonCtx->is80211to803ConReq = 1; + pMonCtx->numOfMacFilters = 0; + } + + +hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, + const char *iface_name, tSirMacAddr macAddr, + tANI_U8 rtnl_held ) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_list_node_t *pHddAdapterNode = NULL; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + VOS_STATUS exitbmpsStatus; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d",__func__,iface_name,session_type); + + if(macAddr == NULL) + { + /* Not received valid macAddr */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Unable to add virtual intf: Not able to get" + "valid mac address",__func__); + return NULL; + } + + //Disable BMPS incase of Concurrency + exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, session_type); + + if(VOS_STATUS_E_FAILURE == exitbmpsStatus) + { + //Fail to Exit BMPS + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Fail to Exit BMPS", __func__); + VOS_ASSERT(0); + return NULL; + } + + switch(session_type) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + { + pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name ); + + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + +#ifdef FEATURE_WLAN_TDLS + /* A Mutex Lock is introduced while changing/initializing the mode to + * protect the concurrent access for the Adapters by TDLS module. + */ + mutex_lock(&pHddCtx->tdls_lock); +#endif + + pAdapter->wdev.iftype = (session_type == WLAN_HDD_P2P_CLIENT) ? + NL80211_IFTYPE_P2P_CLIENT: + NL80211_IFTYPE_STATION; + + pAdapter->device_mode = session_type; +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + + hdd_initialize_adapter_common(pAdapter); + status = hdd_init_station_mode( pAdapter ); + if( VOS_STATUS_SUCCESS != status ) + goto err_free_netdev; + + status = hdd_register_interface( pAdapter, rtnl_held ); + if( VOS_STATUS_SUCCESS != status ) + { +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); +#endif + hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held); +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + goto err_free_netdev; + } + + // Workqueue which gets scheduled in IPv4 notification callback. + vos_init_work(&pAdapter->ipv4NotifierWorkQueue, hdd_ipv4_notifier_work_queue); + +#ifdef WLAN_NS_OFFLOAD + // Workqueue which gets scheduled in IPv6 notification callback. + vos_init_work(&pAdapter->ipv6NotifierWorkQueue, hdd_ipv6_notifier_work_queue); +#endif + //Stop the Interface TX queue. + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + //netif_tx_disable(pWlanDev); + netif_carrier_off(pAdapter->dev); + + if (WLAN_HDD_P2P_CLIENT == session_type || + WLAN_HDD_P2P_DEVICE == session_type) + { + /* Initialize the work queue to defer the + * back to back RoC request */ + vos_init_delayed_work(&pAdapter->roc_work, + hdd_p2p_roc_work_queue); + } + + break; + } + + case WLAN_HDD_P2P_GO: + case WLAN_HDD_SOFTAP: + { + pAdapter = hdd_wlan_create_ap_dev( pHddCtx, macAddr, (tANI_U8 *)iface_name ); + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + pAdapter->wdev.iftype = (session_type == WLAN_HDD_SOFTAP) ? + NL80211_IFTYPE_AP: + NL80211_IFTYPE_P2P_GO; + pAdapter->device_mode = session_type; + + hdd_initialize_adapter_common(pAdapter); + status = hdd_init_ap_mode(pAdapter, false); + if( VOS_STATUS_SUCCESS != status ) + goto err_free_netdev; + + status = hdd_sta_id_hash_attach(pAdapter); + if (VOS_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to attach hash for session %d"), session_type); + hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held); + goto err_free_netdev; + } + + status = hdd_register_hostapd( pAdapter, rtnl_held ); + if( VOS_STATUS_SUCCESS != status ) + { + hdd_deinit_adapter(pHddCtx, pAdapter, rtnl_held); + goto err_free_netdev; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + + hdd_set_conparam( 1 ); + + if (WLAN_HDD_P2P_GO == session_type) + { + /* Initialize the work queue to + * defer the back to back RoC request */ + INIT_DELAYED_WORK(&pAdapter->roc_work, + hdd_p2p_roc_work_queue); + } + + break; + } + case WLAN_HDD_MONITOR: + { + pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name ); + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + // Register wireless extensions + if( VOS_STATUS_SUCCESS != (status = hdd_register_wext(pAdapter->dev))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "hdd_register_wext() failed with status code %08d [x%08x]", + status, status ); + status = VOS_STATUS_E_FAILURE; + } + + pAdapter->wdev.iftype = NL80211_IFTYPE_MONITOR; + pAdapter->device_mode = session_type; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) + pAdapter->dev->netdev_ops = &wlan_mon_drv_ops; +#else + pAdapter->dev->open = hdd_mon_open; + pAdapter->dev->hard_start_xmit = hdd_mon_hard_start_xmit; + pAdapter->dev->stop = hdd_mon_stop; + pAdapter->dev->do_ioctl = hdd_mon_ioctl; +#endif + status = hdd_register_interface( pAdapter, rtnl_held ); + hdd_init_mon_mode( pAdapter ); + hdd_initialize_adapter_common(pAdapter); + hdd_init_tx_rx( pAdapter ); + set_bit(INIT_TX_RX_SUCCESS, &pAdapter->event_flags); + //Stop the Interface TX queue. + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + } + break; + case WLAN_HDD_FTM: + { + pAdapter = hdd_alloc_station_adapter( pHddCtx, macAddr, iface_name ); + + if( NULL == pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to allocate adapter for session %d"), session_type); + return NULL; + } + + /* Assign NL80211_IFTYPE_STATION as interface type to resolve Kernel Warning + * message while loading driver in FTM mode. */ + pAdapter->wdev.iftype = NL80211_IFTYPE_STATION; + pAdapter->device_mode = session_type; + status = hdd_register_interface( pAdapter, rtnl_held ); + + hdd_initialize_adapter_common(pAdapter); + hdd_init_tx_rx( pAdapter ); + + //Stop the Interface TX queue. + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + netif_carrier_off(pAdapter->dev); + } + break; + default: + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s Invalid session type %d", + __func__, session_type); + VOS_ASSERT(0); + return NULL; + } + } + + if( VOS_STATUS_SUCCESS == status ) + { + //Add it to the hdd's session list. + pHddAdapterNode = vos_mem_malloc( sizeof( hdd_adapter_list_node_t ) ); + if( NULL == pHddAdapterNode ) + { + status = VOS_STATUS_E_NOMEM; + } + else + { + pHddAdapterNode->pAdapter = pAdapter; + status = hdd_add_adapter_back ( pHddCtx, + pHddAdapterNode ); + } + } + + if( VOS_STATUS_SUCCESS != status ) + { + if( NULL != pAdapter ) + { + hdd_cleanup_adapter( pHddCtx, pAdapter, rtnl_held ); + pAdapter = NULL; + } + if( NULL != pHddAdapterNode ) + { + vos_mem_free( pHddAdapterNode ); + } + + goto resume_bmps; + } + + if(VOS_STATUS_SUCCESS == status) + { + wlan_hdd_set_concurrency_mode(pHddCtx, session_type); + //Initialize the WoWL service + if(!hdd_init_wowl(pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_init_wowl failed",__func__); + goto err_free_netdev; + } + //Initialize the TSF capture data + wlan_hdd_tsf_init(pAdapter); + } + return pAdapter; + +err_free_netdev: + free_netdev(pAdapter->dev); + wlan_hdd_release_intf_addr( pHddCtx, + pAdapter->macAddressCurrent.bytes ); + +resume_bmps: + //If bmps disabled enable it + if(VOS_STATUS_SUCCESS == exitbmpsStatus) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + return NULL; +} + +VOS_STATUS hdd_close_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + tANI_U8 rtnl_held ) +{ + hdd_adapter_list_node_t *pAdapterNode, *pCurrent, *pNext; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pCurrent ); + if( VOS_STATUS_SUCCESS != status ) + { + hddLog(VOS_TRACE_LEVEL_WARN,"%s: adapter list empty %d", + __func__, status); + return status; + } + + while ( pCurrent->pAdapter != pAdapter ) + { + status = hdd_get_next_adapter ( pHddCtx, pCurrent, &pNext ); + if( VOS_STATUS_SUCCESS != status ) + break; + + pCurrent = pNext; + } + pAdapterNode = pCurrent; + if( VOS_STATUS_SUCCESS == status ) + { + wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode); + hdd_cleanup_adapter( pHddCtx, pAdapterNode->pAdapter, rtnl_held ); + +#ifdef FEATURE_WLAN_TDLS + + /* A Mutex Lock is introduced while changing/initializing the mode to + * protect the concurrent access for the Adapters by TDLS module. + */ + mutex_lock(&pHddCtx->tdls_lock); +#endif + + hdd_remove_adapter( pHddCtx, pAdapterNode ); + vos_mem_free( pAdapterNode ); + pAdapterNode = NULL; + +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + + + /* If there is a single session of STA/P2P client, re-enable BMPS */ + if ((!vos_concurrent_open_sessions_running()) && + ((pHddCtx->no_of_open_sessions[VOS_STA_MODE] >= 1) || + (pHddCtx->no_of_open_sessions[VOS_P2P_CLIENT_MODE] >= 1))) + { + if (pHddCtx->hdd_wlan_suspended) + { + hdd_set_pwrparams(pHddCtx); + } + hdd_enable_bmps_imps(pHddCtx); + } + + return VOS_STATUS_SUCCESS; + } + + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pHddAdapterNode; + VOS_STATUS status; + + ENTER(); + + do + { + status = hdd_remove_front_adapter( pHddCtx, &pHddAdapterNode ); + if( pHddAdapterNode && VOS_STATUS_SUCCESS == status ) + { + hdd_cleanup_adapter( pHddCtx, pHddAdapterNode->pAdapter, FALSE ); + vos_mem_free( pHddAdapterNode ); + } + }while( NULL != pHddAdapterNode && VOS_STATUS_E_EMPTY != status ); + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter) +{ + v_U8_t addIE[1] = {0}; + + if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1,(tANI_U8*)addIE, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM"); + } + + if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM"); + } + + if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM"); + } +} + +VOS_STATUS hdd_cleanup_ap_events(hdd_adapter_t *adapter) +{ +#ifdef DHCP_SERVER_OFFLOAD + vos_event_destroy(&adapter->dhcp_status.vos_event); +#endif +#ifdef MDNS_OFFLOAD + vos_event_destroy(&adapter->mdns_status.vos_event); +#endif + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, + const v_BOOL_t bCloseSession ) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + hdd_scaninfo_t *pScanInfo = NULL; + union iwreq_data wrqu; + v_U8_t retry = 0; + long ret; + VOS_STATUS status; + + if (pHddCtx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:LOGP in Progress. Ignore!!!",__func__); + return VOS_STATUS_E_FAILURE; + } + + ENTER(); + + pScanInfo = &pHddCtx->scan_info; + switch(pAdapter->device_mode) + { + case WLAN_HDD_IBSS: + if ( VOS_TRUE == bCloseSession ) + { + status = hdd_sta_id_hash_detach(pAdapter); + if (status != VOS_STATUS_SUCCESS) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sta id hash detach failed")); + } + + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + { + hdd_station_ctx_t *pstation = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_exit(pAdapter, TRUE); + mutex_unlock(&pHddCtx->tdls_lock); +#endif + if( hdd_connIsConnected(pstation) || + (pstation->conn_info.connState == eConnectionState_Connecting) ) + { + /* + * Indicate sme of disconnect so that in progress connection + * or preauth can be aborted. + */ + sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId); + INIT_COMPLETION(pAdapter->disconnect_comp_var); + if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS) + halStatus = sme_RoamDisconnect(pHddCtx->hHal, + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_IBSS_LEAVE); + else + halStatus = sme_RoamDisconnect(pHddCtx->hHal, + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + /* Success implies disconnect command got queued up successfully + * Or cmd not queued as scan for SSID is in progress + */ + if((eHAL_STATUS_SUCCESS == halStatus) || + (eHAL_STATUS_CMD_NOT_QUEUED == halStatus)) + { + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0 && + (eHAL_STATUS_CMD_NOT_QUEUED != halStatus)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: wait on disconnect_comp_var failed %ld", + __func__, ret); + } + } + else + { + hddLog(LOGE, "%s: failed to post disconnect event to SME", + __func__); + } + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL); + } + else if(pstation->conn_info.connState == + eConnectionState_Disconnecting) + { + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("wait on disconnect_comp_var failed %ld"), ret); + } + } + if(pScanInfo != NULL && pHddCtx->scan_info.mScanPending) + { + wlan_hdd_scan_abort(pAdapter); + } + if ((pAdapter->device_mode != WLAN_HDD_INFRA_STATION) && + (pAdapter->device_mode != WLAN_HDD_IBSS)) + { + while (pAdapter->is_roc_inprogress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ROC in progress for session %d!!!", + __func__, pAdapter->sessionId); + // waiting for ROC to expire + msleep(500); + /* In GO present case , if retry exceeds 3, + it means something went wrong. */ + if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ROC completion is not received.!!!", __func__); + if (eHAL_STATUS_SUCCESS != + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter), + pAdapter->sessionId )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Cancel Remain on Channel")); + } + wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + break; + } + } + vos_flush_delayed_work(&pAdapter->roc_work); + } +#ifdef WLAN_NS_OFFLOAD + vos_flush_work(&pAdapter->ipv6NotifierWorkQueue); +#endif + + vos_flush_work(&pAdapter->ipv4NotifierWorkQueue); + + /* It is possible that the caller of this function does not + * wish to close the session + */ + if (VOS_TRUE == bCloseSession && + test_bit(SME_SESSION_OPENED, &pAdapter->event_flags)) + { + INIT_COMPLETION(pAdapter->session_close_comp_var); + if (eHAL_STATUS_SUCCESS == + sme_CloseSession(pHddCtx->hHal, pAdapter->sessionId, FALSE, + VOS_FALSE, hdd_smeCloseSessionCallback, pAdapter)) + { + unsigned long ret; + + //Block on a completion variable. Can't wait forever though. + ret = wait_for_completion_timeout( + &pAdapter->session_close_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_SESSIONOPENCLOSE)); + if ( 0 >= ret) + { + hddLog(LOGE, "%s: failure waiting for session_close_comp_var %ld", + __func__, ret); + } + } + } + } + break; + + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + if ( VOS_TRUE == bCloseSession ) + { + status = hdd_sta_id_hash_detach(pAdapter); + if (status != VOS_STATUS_SUCCESS) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sta id hash detach failed")); + } + + //Any softap specific cleanup here... + hdd_cleanup_ap_events(pAdapter); + if (pAdapter->device_mode == WLAN_HDD_P2P_GO) { + while (pAdapter->is_roc_inprogress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ROC in progress for session %d!!!", + __func__, pAdapter->sessionId); + msleep(500); + if ( retry++ > MAX_WAIT_FOR_ROC_COMPLETION ) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ROC completion is not received.!!!", __func__); + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + break; + } + } + + vos_flush_delayed_work(&pAdapter->roc_work); + } +#ifdef SAP_AUTH_OFFLOAD + if (pHddCtx->cfg_ini->enable_sap_auth_offload) + hdd_set_sap_auth_offload(pAdapter, FALSE); +#endif + mutex_lock(&pHddCtx->sap_lock); + if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + { + VOS_STATUS status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + //Stop Bss. + status = WLANSAP_StopBss(pHddCtx->pvosContext); + if (VOS_IS_STATUS_SUCCESS(status)) + { + hdd_hostapd_state_t *pHostapdState = + WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(LOGE, "%s: failure waiting for WLANSAP_StopBss %d", + __func__, status); + } + } + else + { + hddLog(LOGE, "%s: failure in WLANSAP_StopBss", __func__); + } + clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + + if (eHAL_STATUS_FAILURE == + ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, + 0, NULL, eANI_BOOLEAN_FALSE)) + { + hddLog(LOGE, + "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG", + __func__); + } + + if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL, + eANI_BOOLEAN_FALSE) ) + { + hddLog(LOGE, + "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + } + + // Reset WNI_CFG_PROBE_RSP Flags + wlan_hdd_reset_prob_rspies(pAdapter); + kfree(pAdapter->sessionCtx.ap.beacon); + pAdapter->sessionCtx.ap.beacon = NULL; + } + mutex_unlock(&pHddCtx->sap_lock); + break; + + case WLAN_HDD_MONITOR: + break; + + default: + break; + } + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +/** + * wlan_hdd_restart_sap() - to restart SAP in driver internally + * @ap_adapter: - Pointer to SAP hdd_adapter_t structure + * + * wlan_hdd_restart_sap first delete SAP and do cleanup. + * After that WLANSAP_StartBss start re-start process of SAP. + * + * Return: None + */ +static void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter) +{ + hdd_ap_ctx_t *pHddApCtx; + hdd_hostapd_state_t *pHostapdState; + VOS_STATUS vos_status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(ap_adapter); +#ifdef CFG80211_DEL_STA_V2 + struct station_del_parameters delStaParams; +#endif + tsap_Config_t *pConfig; + + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); + pConfig = &pHddApCtx->sapConfig; + + mutex_lock(&pHddCtx->sap_lock); + if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) { +#ifdef CFG80211_DEL_STA_V2 + delStaParams.mac = NULL; + delStaParams.subtype = SIR_MAC_MGMT_DEAUTH >> 4; + delStaParams.reason_code = eCsrForcedDeauthSta; + wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev, + &delStaParams); +#else + wlan_hdd_cfg80211_del_station(ap_adapter->wdev.wiphy, ap_adapter->dev, + NULL); +#endif + hdd_cleanup_actionframe(pHddCtx, ap_adapter); + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); + vos_event_reset(&pHostapdState->vosEvent); + + if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) { + vos_status = vos_wait_single_event(&pHostapdState->vosEvent, + 10000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + goto end; + } + } + clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags); + wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode); + hddLog(LOG1, FL("SAP Stop Success")); + + if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) { + hddLog(LOGE, FL("SAP Not able to set AP IEs")); + goto end; + } + + if (WLANSAP_StartBss(pHddCtx->pvosContext, hdd_hostapd_SAPEventCB, + pConfig, (v_PVOID_t)ap_adapter->dev) != VOS_STATUS_SUCCESS) { + hddLog(LOGE, FL("SAP Start Bss fail")); + goto end; + } + + hddLog(LOG1, FL("Waiting for SAP to start")); + vos_status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(LOGE, FL("SAP Start failed")); + goto end; + } + hddLog(LOG1, FL("SAP Start Success")); + set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags); + wlan_hdd_incr_active_session(pHddCtx, ap_adapter->device_mode); + pHostapdState->bCommit = TRUE; + if (!VOS_IS_STATUS_SUCCESS(hdd_dhcp_mdns_offload(ap_adapter))) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("DHCP/MDNS offload Failed!!")); + vos_event_reset(&pHostapdState->vosEvent); + if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) { + vos_status = vos_wait_single_event(&pHostapdState->vosEvent, + 10000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + hddLog(LOGE, FL("SAP Stop Failed")); + goto end; + } + } + } + } +end: + mutex_unlock(&pHddCtx->sap_lock); + return; +} + +/** + * __hdd_sap_restart_handle() - to handle restarting of SAP + * @work: name of the work + * + * Purpose of this function is to trigger sap start. this function + * will be called from workqueue. + * + * Return: void. + */ +static void __hdd_sap_restart_handle(struct work_struct *work) +{ + hdd_adapter_t *sap_adapter; + hdd_context_t *hdd_ctx = container_of(work, + hdd_context_t, + sap_start_work); + if (0 != wlan_hdd_validate_context(hdd_ctx)) { + vos_ssr_unprotect(__func__); + return; + } + sap_adapter = hdd_get_adapter(hdd_ctx, + WLAN_HDD_SOFTAP); + if (sap_adapter == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("sap_adapter is NULL")); + vos_ssr_unprotect(__func__); + return; + } + + if (hdd_ctx->is_ch_avoid_in_progress) { + sap_adapter->sessionCtx.ap.sapConfig.channel = AUTO_CHANNEL_SELECT; + wlan_hdd_restart_sap(sap_adapter); + hdd_change_ch_avoidance_status(hdd_ctx, false); + } + if (hdd_ctx->cfg_ini->enable_sap_auth_offload) + wlan_hdd_restart_sap(sap_adapter); +} + +/** + * hdd_sap_restart_handle() - to handle restarting of SAP + * @work: name of the work + * + * Purpose of this function is to trigger sap start. this function + * will be called from workqueue. + * + * Return: void. + */ +static void hdd_sap_restart_handle(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_sap_restart_handle(work); + vos_ssr_unprotect(__func__); +} + + +VOS_STATUS hdd_stop_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE ); + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + + +#ifdef FEATURE_WLAN_BATCH_SCAN +/**--------------------------------------------------------------------------- + + \brief hdd_deinit_batch_scan () - This function cleans up batch scan data + structures + + \param - pAdapter Pointer to HDD adapter + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_deinit_batch_scan(hdd_adapter_t *pAdapter) +{ + tHddBatchScanRsp *pNode; + tHddBatchScanRsp *pPrev; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Adapter context is Null", __func__); + return; + } + + pNode = pAdapter->pBatchScanRsp; + while (pNode) + { + pPrev = pNode; + pNode = pNode->pNext; + vos_mem_free((v_VOID_t * )pPrev); + } + + pAdapter->pBatchScanRsp = NULL; + pAdapter->numScanList = 0; + pAdapter->batchScanState = eHDD_BATCH_SCAN_STATE_STOPPED; + pAdapter->prev_batch_id = 0; + + return; +} +#endif + + +VOS_STATUS hdd_reset_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + + if (pHddCtx->cfg_ini->sap_internal_restart && + pAdapter->device_mode == WLAN_HDD_SOFTAP) { + hddLog(LOG1, FL("driver supports sap restart")); + vos_flush_work(&pHddCtx->sap_start_work); + hdd_sap_indicate_disconnect_for_sta(pAdapter); + hdd_cleanup_actionframe(pHddCtx, pAdapter); + hdd_softap_deinit_tx_rx(pAdapter, true); + hdd_sap_destroy_timers(pAdapter); + } else { + netif_carrier_off(pAdapter->dev); + } + + pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE; + + hdd_deinit_tx_rx(pAdapter); + + if(pAdapter->device_mode == WLAN_HDD_IBSS ) + hdd_ibss_deinit_tx_rx(pAdapter); + + status = hdd_sta_id_hash_detach(pAdapter); + if (status != VOS_STATUS_SUCCESS) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("sta id hash detach failed for session id %d"), + pAdapter->sessionId); + + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + + if (test_bit(WMM_INIT_DONE, &pAdapter->event_flags)) + { + hdd_wmm_adapter_close( pAdapter ); + clear_bit(WMM_INIT_DONE, &pAdapter->event_flags); + } + + if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + { + clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags); + } + +#ifdef FEATURE_WLAN_BATCH_SCAN + if (eHDD_BATCH_SCAN_STATE_STARTED == pAdapter->batchScanState) + { + hdd_deinit_batch_scan(pAdapter); + } +#endif + +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_exit(pAdapter, TRUE); + mutex_unlock(&pHddCtx->tdls_lock); +#endif + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +/** + * hdd_get_bss_entry() - Get the bss entry matching the chan, bssid and ssid + * @wiphy: wiphy + * @channel: channel of the BSS to find + * @bssid: bssid of the BSS to find + * @ssid: ssid of the BSS to find + * @ssid_len: ssid len of of the BSS to find + * + * The API is a wrapper to get bss from kernel matching the chan, + * bssid and ssid + * + * Return: Void + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \ + && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY) + +struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy, + struct ieee80211_channel *channel, + const u8 *bssid, + const u8 *ssid, size_t ssid_len) +{ + return cfg80211_get_bss(wiphy, channel, bssid, + ssid, ssid_len, + WLAN_CAPABILITY_ESS, + WLAN_CAPABILITY_ESS); +} +#else +struct cfg80211_bss* hdd_get_bss_entry(struct wiphy *wiphy, + struct ieee80211_channel *channel, + const u8 *bssid, + const u8 *ssid, size_t ssid_len) +{ + return cfg80211_get_bss(wiphy, channel, bssid, + ssid, ssid_len, + IEEE80211_BSS_TYPE_ESS, + IEEE80211_PRIVACY_ANY); +} +#endif + +/** + * hdd_connect_result() - API to send connection status to supplicant + * @dev: network device + * @bssid: bssid to which we want to associate + * @roam_info: information about connected bss + * @req_ie: Request Information Element + * @req_ie_len: len of the req IE + * @resp_ie: Response IE + * @resp_ie_len: len of ht response IE + * @status: status + * @gfp: Kernel Flag + * + * The API is a wrapper to send connection status to supplicant + * + * Return: Void + */ +#if defined CFG80211_CONNECT_BSS +void hdd_connect_result(struct net_device *dev, + const u8 *bssid, + tCsrRoamInfo *roam_info, + const u8 *req_ie, + size_t req_ie_len, + const u8 *resp_ie, + size_t resp_ie_len, + u16 status, + gfp_t gfp) +{ + hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev); + struct cfg80211_bss *bss = NULL; + + if (WLAN_STATUS_SUCCESS == status) { + struct ieee80211_channel *chan; + int freq; + int chan_no = roam_info->pBssDesc->channelId;; + + if (chan_no <= 14) + freq = ieee80211_channel_to_frequency(chan_no, + IEEE80211_BAND_2GHZ); + else + freq = ieee80211_channel_to_frequency(chan_no, + IEEE80211_BAND_5GHZ); + + chan = ieee80211_get_channel(padapter->wdev.wiphy, freq); + bss = hdd_get_bss_entry(padapter->wdev.wiphy, + chan, bssid, + roam_info->u.pConnectedProfile->SSID.ssId, + roam_info->u.pConnectedProfile->SSID.length); + } + + cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len, + resp_ie, resp_ie_len, status, gfp); +} +#else +void hdd_connect_result(struct net_device *dev, + const u8 *bssid, + tCsrRoamInfo *roam_info, + const u8 *req_ie, + size_t req_ie_len, + const u8 * resp_ie, + size_t resp_ie_len, + u16 status, + gfp_t gfp) +{ + cfg80211_connect_result(dev, bssid, req_ie, req_ie_len, + resp_ie, resp_ie_len, status, gfp); +} +#endif + +VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + eConnectionState connState; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + hdd_wmm_init( pAdapter ); + + switch(pAdapter->device_mode) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_P2P_DEVICE: + + connState = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState; + + hdd_init_station_mode(pAdapter); + /* Open the gates for HDD to receive Wext commands */ + pAdapter->isLinkUpSvcNeeded = FALSE; + pHddCtx->scan_info.mScanPending = FALSE; + pHddCtx->scan_info.waitScanResult = FALSE; + + //Trigger the initial scan + if (!pHddCtx->isLogpInProgress) + hdd_wlan_initial_scan(pAdapter); + + //Indicate disconnect event to supplicant if associated previously + if (eConnectionState_Associated == connState || + eConnectionState_IbssConnected == connState ) + { + union iwreq_data wrqu; + memset(&wrqu, '\0', sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN); + wireless_send_event(pAdapter->dev, SIOCGIWAP, &wrqu, NULL); + pAdapter->sessionCtx.station.hdd_ReassocScenario = VOS_FALSE; + + /* indicate disconnected event to nl80211 */ + wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, false, + WLAN_REASON_UNSPECIFIED); + } + else if (eConnectionState_Connecting == connState) + { + /* + * Indicate connect failure to supplicant if we were in the + * process of connecting + */ + hdd_connect_result(pAdapter->dev, NULL, NULL, + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL); + } + break; + + case WLAN_HDD_SOFTAP: + if (pHddCtx->cfg_ini->sap_internal_restart) { + hdd_init_ap_mode(pAdapter, true); + status = hdd_sta_id_hash_attach(pAdapter); + if (VOS_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("failed to attach hash for")); + } + } + break; + + case WLAN_HDD_P2P_GO: + hddLog(VOS_TRACE_LEVEL_ERROR, "%s [SSR] send stop ap to supplicant", + __func__); + cfg80211_ap_stopped(pAdapter->dev, GFP_KERNEL); + break; + + case WLAN_HDD_MONITOR: + /* monitor interface start */ + break; + default: + break; + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + v_U32_t roamId; + long ret; + + ENTER(); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ) + { + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Set HDD connState to eConnectionState_NotConnected", + __func__); + spin_lock_bh(&pAdapter->lock_for_active_session); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); + } + pHddStaCtx->conn_info.connState = eConnectionState_NotConnected; + spin_unlock_bh(&pAdapter->lock_for_active_session); + init_completion(&pAdapter->disconnect_comp_var); + sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (0 >= ret) + hddLog(LOGE, "%s: failure waiting for disconnect_comp_var %ld", + __func__, ret); + + pWextState->roamProfile.csrPersona = pAdapter->device_mode; + pHddCtx->isAmpAllowed = VOS_FALSE; + sme_RoamConnect(pHddCtx->hHal, + pAdapter->sessionId, &(pWextState->roamProfile), + &roamId); + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + EXIT(); + + return VOS_STATUS_SUCCESS; +} + +void hdd_dump_concurrency_info(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + hdd_ap_ctx_t *pHddApCtx; + hdd_hostapd_state_t * pHostapdState; + tCsrBssid staBssid = { 0 }, p2pBssid = { 0 }, apBssid = { 0 }; + v_U8_t staChannel = 0, p2pChannel = 0, apChannel = 0; + const char *p2pMode = "DEV"; + const char *ccMode = "Standalone"; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + switch (pAdapter->device_mode) { + case WLAN_HDD_INFRA_STATION: + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) { + staChannel = pHddStaCtx->conn_info.operationChannel; + memcpy(staBssid, pHddStaCtx->conn_info.bssId, sizeof(staBssid)); + } + break; + case WLAN_HDD_P2P_CLIENT: + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) { + p2pChannel = pHddStaCtx->conn_info.operationChannel; + memcpy(p2pBssid, pHddStaCtx->conn_info.bssId, sizeof(p2pBssid)); + p2pMode = "CLI"; + } + break; + case WLAN_HDD_P2P_GO: + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) { + p2pChannel = pHddApCtx->operatingChannel; + memcpy(p2pBssid, pAdapter->macAddressCurrent.bytes, sizeof(p2pBssid)); + } + p2pMode = "GO"; + break; + case WLAN_HDD_SOFTAP: + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + if (pHostapdState->bssState == BSS_START && pHostapdState->vosStatus==VOS_STATUS_SUCCESS) { + apChannel = pHddApCtx->operatingChannel; + memcpy(apBssid, pAdapter->macAddressCurrent.bytes, sizeof(apBssid)); + } + break; + default: + break; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + if (staChannel > 0 && (apChannel > 0 || p2pChannel > 0)) { + ccMode = (p2pChannel==staChannel||apChannel==staChannel) ? "SCC" : "MCC"; + } + hddLog(VOS_TRACE_LEVEL_INFO, "wlan(%d) " MAC_ADDRESS_STR " %s", + staChannel, MAC_ADDR_ARRAY(staBssid), ccMode); + if (p2pChannel > 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, "p2p-%s(%d) " MAC_ADDRESS_STR, + p2pMode, p2pChannel, MAC_ADDR_ARRAY(p2pBssid)); + } + if (apChannel > 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, "AP(%d) " MAC_ADDRESS_STR, + apChannel, MAC_ADDR_ARRAY(apBssid)); + } + + if (p2pChannel > 0 && apChannel > 0) { + hddLog(VOS_TRACE_LEVEL_ERROR, "Error concurrent SAP %d and P2P %d which is not support", apChannel, p2pChannel); + } +} + +bool hdd_is_ssr_required( void) +{ + return (isSsrRequired == HDD_SSR_REQUIRED); +} + +/* Once SSR is disabled then it cannot be set. */ +void hdd_set_ssr_required( e_hdd_ssr_required value) +{ + if (HDD_SSR_DISABLED == isSsrRequired) + return; + + isSsrRequired = value; +} + +void hdd_set_pre_close( hdd_context_t *pHddCtx) +{ + sme_PreClose(pHddCtx->hHal); +} + +VOS_STATUS hdd_get_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode) +{ + VOS_STATUS status; + spin_lock_bh(&pHddCtx->hddAdapters.lock); + status = hdd_list_peek_front ( &pHddCtx->hddAdapters, + (hdd_list_node_t**) ppAdapterNode ); + spin_unlock_bh(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_get_next_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode, + hdd_adapter_list_node_t** pNextAdapterNode) +{ + VOS_STATUS status; + spin_lock_bh(&pHddCtx->hddAdapters.lock); + status = hdd_list_peek_next ( &pHddCtx->hddAdapters, + (hdd_list_node_t*) pAdapterNode, + (hdd_list_node_t**)pNextAdapterNode ); + + spin_unlock_bh(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_remove_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode) +{ + VOS_STATUS status; + spin_lock_bh(&pHddCtx->hddAdapters.lock); + status = hdd_list_remove_node ( &pHddCtx->hddAdapters, + &pAdapterNode->node ); + spin_unlock_bh(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_remove_front_adapter( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t** ppAdapterNode) +{ + VOS_STATUS status; + spin_lock_bh(&pHddCtx->hddAdapters.lock); + status = hdd_list_remove_front( &pHddCtx->hddAdapters, + (hdd_list_node_t**) ppAdapterNode ); + spin_unlock_bh(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_add_adapter_back( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode) +{ + VOS_STATUS status; + spin_lock_bh(&pHddCtx->hddAdapters.lock); + status = hdd_list_insert_back ( &pHddCtx->hddAdapters, + (hdd_list_node_t*) pAdapterNode ); + spin_unlock_bh(&pHddCtx->hddAdapters.lock); + return status; +} + +VOS_STATUS hdd_add_adapter_front( hdd_context_t *pHddCtx, + hdd_adapter_list_node_t* pAdapterNode) +{ + VOS_STATUS status; + spin_lock_bh(&pHddCtx->hddAdapters.lock); + status = hdd_list_insert_front ( &pHddCtx->hddAdapters, + (hdd_list_node_t*) pAdapterNode ); + spin_unlock_bh(&pHddCtx->hddAdapters.lock); + return status; +} + +hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, + tSirMacAddr macAddr ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && vos_mem_compare( pAdapter->macAddressCurrent.bytes, + macAddr, sizeof(tSirMacAddr) ) ) + { + return pAdapter; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && !strncmp( pAdapter->dev->name, (const char *)name, + IFNAMSIZ ) ) + { + return pAdapter; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx, + tANI_U32 sme_session_id ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS vos_status; + + + vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode); + + while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status)) + { + pAdapter = pAdapterNode->pAdapter; + + if (pAdapter->sessionId == sme_session_id) + return pAdapter; + + vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_session_id %d does not exist with host", + __func__, sme_session_id); + + return NULL; +} + +hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && (mode == pAdapter->device_mode) ) + { + return pAdapter; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +//Remove this function later +hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( pAdapter && WLAN_HDD_MONITOR == pAdapter->device_mode ) + { + return pAdapter; + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + return NULL; + +} + +/**--------------------------------------------------------------------------- + + \brief hdd_get_operating_channel() - + + This API returns the operating channel of the requested device mode + + \param - pHddCtx - Pointer to the HDD context. + - mode - Device mode for which operating channel is required + suported modes - WLAN_HDD_INFRA_STATION, WLAN_HDD_P2P_CLIENT + WLAN_HDD_SOFTAP, WLAN_HDD_P2P_GO. + \return - channel number. "0" id the requested device is not found OR it is not connected. + --------------------------------------------------------------------------*/ +v_U8_t hdd_get_operating_channel( hdd_context_t *pHddCtx, device_mode_t mode ) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + v_U8_t operatingChannel = 0; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if( mode == pAdapter->device_mode ) + { + switch(pAdapter->device_mode) + { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + if( hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR( pAdapter )) ) + operatingChannel = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.operationChannel; + break; + case WLAN_HDD_SOFTAP: + case WLAN_HDD_P2P_GO: + /*softap connection info */ + if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + operatingChannel = (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->operatingChannel; + break; + default: + break; + } + + break; //Found the device of interest. break the loop + } + + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return operatingChannel; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/**--------------------------------------------------------------------------- + + \brief __hdd_set_multicast_list() - + + This used to set the multicast address list. + + \param - dev - Pointer to the WLAN device. + - skb - Pointer to OS packet (sk_buff). + \return - success/fail + + --------------------------------------------------------------------------*/ +static void __hdd_set_multicast_list(struct net_device *dev) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int mc_count; + int i = 0, ret = 0; + struct netdev_hw_addr *ha; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Adapter context is Null", __func__); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return; + } + if (dev->flags & IFF_ALLMULTI) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: allow all multicast frames", __func__); + pAdapter->mc_addr_list.mc_cnt = 0; + } + else + { + mc_count = netdev_mc_count(dev); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: mc_count = %u", __func__, mc_count); + if (mc_count > WLAN_HDD_MAX_MC_ADDR_LIST) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: No free filter available; allow all multicast frames", __func__); + pAdapter->mc_addr_list.mc_cnt = 0; + return; + } + + pAdapter->mc_addr_list.mc_cnt = mc_count; + + netdev_for_each_mc_addr(ha, dev) { + if (i == mc_count) + break; + memset(&(pAdapter->mc_addr_list.addr[i][0]), 0, ETH_ALEN); + memcpy(&(pAdapter->mc_addr_list.addr[i][0]), ha->addr, ETH_ALEN); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: mlist[%d] = "MAC_ADDRESS_STR, + __func__, i, + MAC_ADDR_ARRAY(pAdapter->mc_addr_list.addr[i])); + i++; + } + } + + if (pHddCtx->hdd_wlan_suspended) + { + /* + * Configure the Mcast address list to FW + * If wlan is already in suspend mode + */ + wlan_hdd_set_mc_addr_list(pAdapter, TRUE); + } + EXIT(); + return; +} + +static void hdd_set_multicast_list(struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_set_multicast_list(dev); + vos_ssr_unprotect(__func__); +} +#endif + +/**--------------------------------------------------------------------------- + + \brief hdd_select_queue() - + + This function is registered with the Linux OS for network + core to decide which queue to use first. + + \param - dev - Pointer to the WLAN device. + - skb - Pointer to OS packet (sk_buff). + \return - ac, Queue Index/access category corresponding to UP in IP header + + --------------------------------------------------------------------------*/ +v_U16_t hdd_select_queue(struct net_device *dev, + struct sk_buff *skb +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)) + , void *accel_priv +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + , select_queue_fallback_t fallback +#endif +) +{ + return hdd_wmm_select_queue(dev, skb); +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_initial_scan() - + + This function triggers the initial scan + + \param - pAdapter - Pointer to the HDD adapter. + + --------------------------------------------------------------------------*/ +void hdd_wlan_initial_scan(hdd_adapter_t *pAdapter) +{ + tCsrScanRequest scanReq; + tCsrChannelInfo channelInfo; + eHalStatus halStatus; + tANI_U32 scanId; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + vos_mem_zero(&scanReq, sizeof(tCsrScanRequest)); + vos_mem_set(&scanReq.bssid, sizeof(tCsrBssid), 0xff); + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + + if(sme_Is11dSupported(pHddCtx->hHal)) + { + halStatus = sme_ScanGetBaseChannels( pHddCtx->hHal, &channelInfo ); + if ( HAL_STATUS_SUCCESS( halStatus ) ) + { + scanReq.ChannelInfo.ChannelList = vos_mem_malloc(channelInfo.numOfChannels); + if( !scanReq.ChannelInfo.ChannelList ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s kmalloc failed", __func__); + vos_mem_free(channelInfo.ChannelList); + channelInfo.ChannelList = NULL; + return; + } + vos_mem_copy(scanReq.ChannelInfo.ChannelList, channelInfo.ChannelList, + channelInfo.numOfChannels); + scanReq.ChannelInfo.numOfChannels = channelInfo.numOfChannels; + vos_mem_free(channelInfo.ChannelList); + channelInfo.ChannelList = NULL; + } + + scanReq.scanType = eSIR_PASSIVE_SCAN; + scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN; + scanReq.maxChnTime = pHddCtx->cfg_ini->nPassiveMaxChnTime; + scanReq.minChnTime = pHddCtx->cfg_ini->nPassiveMinChnTime; + } + else + { + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + scanReq.maxChnTime = pHddCtx->cfg_ini->nActiveMaxChnTime; + scanReq.minChnTime = pHddCtx->cfg_ini->nActiveMinChnTime; + } + + halStatus = sme_ScanRequest(pHddCtx->hHal, pAdapter->sessionId, &scanReq, &scanId, NULL, NULL); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_ScanRequest failed status code %d", + __func__, halStatus ); + } + + if(sme_Is11dSupported(pHddCtx->hHal)) + vos_mem_free(scanReq.ChannelInfo.ChannelList); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_full_power_callback() - HDD full power callback function + + This is the function invoked by SME to inform the result of a full power + request issued by HDD + + \param - callbackcontext - Pointer to cookie + \param - status - result of request + + \return - None + + --------------------------------------------------------------------------*/ +static void hdd_full_power_callback(void *callbackContext, eHalStatus status) +{ + struct statsContext *pContext = callbackContext; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: context = %p, status = %d", __func__, pContext, status); + + if (NULL == callbackContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, context [%p]", + __func__, callbackContext); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if (POWER_CONTEXT_MAGIC != pContext->magic) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, magic [%08x]", + __func__, pContext->magic); + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pContext->magic = 0; + + /* notify the caller */ + complete(&pContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +void wlan_hdd_mon_set_typesubtype( hdd_mon_ctx_t *pMonCtx,int type) +{ + pMonCtx->typeSubtypeBitmap = 0; + if( type%10 ) /* Management Packets */ + pMonCtx->typeSubtypeBitmap |= 0xFFFF; + type/=10; + if( type%10 ) /* Control Packets */ + pMonCtx->typeSubtypeBitmap |= 0xFFFF0000; + type/=10; + if( type%10 ) /* Data Packets */ + pMonCtx->typeSubtypeBitmap |= 0xFFFF00000000; +} + +VOS_STATUS wlan_hdd_mon_postMsg(tANI_U32 *magic, struct completion *cmpVar, + hdd_mon_ctx_t *pMonCtx , void* callback) +{ + vos_msg_t monMsg; + tSirMonModeReq *pMonModeReq; + + if (MON_MODE_START == pMonCtx->state) + monMsg.type = WDA_MON_START_REQ; + else if (MON_MODE_STOP == pMonCtx->state) + monMsg.type = WDA_MON_STOP_REQ; + else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid monitor state %d"), pMonCtx->state); + return VOS_STATUS_E_FAILURE; + } + + pMonModeReq = vos_mem_malloc(sizeof(tSirMonModeReq)); + if (pMonModeReq == NULL) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("fail to allocate memory for monitor mode req")); + return VOS_STATUS_E_FAILURE; + } + + pMonModeReq->magic = magic; + pMonModeReq->cmpVar = cmpVar; + pMonModeReq->data = pMonCtx; + pMonModeReq->callback = callback; + + monMsg.reserved = 0; + monMsg.bodyptr = pMonModeReq; + monMsg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message( + VOS_MODULE_ID_WDA,(vos_msg_t *)&monMsg)) { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: : Failed to post Msg to HAL",__func__); + vos_mem_free(pMonModeReq); + } + return VOS_STATUS_SUCCESS; +} + +void wlan_hdd_mon_close(hdd_context_t *pHddCtx) +{ + VOS_STATUS vosStatus; + v_CONTEXT_t pVosContext = pHddCtx->pvosContext; + long ret; + hdd_mon_ctx_t *pMonCtx = NULL; + v_U32_t magic; + struct completion cmpVar; + + hdd_adapter_t *pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR); + if(pAdapter == NULL || pVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:pAdapter is NULL",__func__); + return ; + } + + pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter); + if (pMonCtx!= NULL && pMonCtx->state == MON_MODE_START) { + pMonCtx->state = MON_MODE_STOP; + magic = MON_MODE_MSG_MAGIC; + init_completion(&cmpVar); + if (VOS_STATUS_SUCCESS != + wlan_hdd_mon_postMsg(&magic, &cmpVar, + pMonCtx, hdd_monPostMsgCb)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to post MON MODE REQ")); + pMonCtx->state = MON_MODE_START; + magic = 0; + return; + } + ret = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT); + magic = 0; + if (ret <= 0 ) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("timeout on monitor mode completion %ld"), ret); + } + } + + hdd_UnregisterWext(pAdapter->dev); + + vos_mon_stop( pVosContext ); + + vosStatus = vos_sched_close( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to close VOSS Scheduler",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_nv_close(); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close NV", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vos_close(pVosContext); + + #ifdef WLAN_KD_READY_NOTIFIER + nl_srv_exit(pHddCtx->ptt_pid); + #else + nl_srv_exit(); + #endif + + hdd_close_all_adapters( pHddCtx ); +} +/** + * hdd_wlan_free_wiphy_channels - free Channel pointer for wiphy + * @ wiphy: the wiphy to validate against + * + * Return: void + */ +void hdd_wlan_free_wiphy_channels(struct wiphy *wiphy) +{ + int i =0; + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + if (NULL != wiphy->bands[i] && + (NULL != wiphy->bands[i]->channels)) + { + vos_mem_free(wiphy->bands[i]->channels); + wiphy->bands[i]->channels = NULL; + } + } +} +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_exit() - HDD WLAN exit function + + This is the driver exit point (invoked during rmmod) + + \param - pHddCtx - Pointer to the HDD Context + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_wlan_exit(hdd_context_t *pHddCtx) +{ + eHalStatus halStatus; + v_CONTEXT_t pVosContext = pHddCtx->pvosContext; + VOS_STATUS vosStatus; + struct wiphy *wiphy = pHddCtx->wiphy; + hdd_adapter_t* pAdapter = NULL; + struct statsContext powerContext; + long lrc; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + + ENTER(); + + + if (VOS_MONITOR_MODE == hdd_get_conparam()) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: MONITOR MODE",__func__); + wlan_hdd_mon_close(pHddCtx); + goto free_hdd_ctx; + } + else if (VOS_FTM_MODE != hdd_get_conparam()) + { + // Unloading, restart logic is no more required. + wlan_hdd_restart_deinit(pHddCtx); + +#ifdef FEATURE_WLAN_TDLS + /* At the time of driver unloading; if tdls connection is present; + * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer. + * wlan_hdd_tdls_find_peer always checks for valid context; + * as load/unload in progress there can be a race condition. + * hdd_rx_packet_cbk calls wlan_hdd_tdls_find_peer only + * when tdls state is enabled. + * As soon as driver set load/unload flag; tdls flag also needs + * to be disabled so that hdd_rx_packet_cbk won't call + * wlan_hdd_tdls_find_peer. + */ + wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE, + HDD_SET_TDLS_MODE_SOURCE_USER); +#endif + + vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus) + { + pAdapter = pAdapterNode->pAdapter; + if (NULL != pAdapter) + { + /* Disable TX on the interface, after this hard_start_xmit() will + * not be called on that interface + */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(pAdapter->dev); + + /* Mark the interface status as "down" for outside world */ + netif_carrier_off(pAdapter->dev); + + /* DeInit the adapter. This ensures that all data packets + * are freed. + */ +#ifdef FEATURE_WLAN_TDLS + mutex_lock(&pHddCtx->tdls_lock); +#endif + hdd_deinit_adapter(pHddCtx, pAdapter, FALSE); +#ifdef FEATURE_WLAN_TDLS + mutex_unlock(&pHddCtx->tdls_lock); +#endif + vos_flush_delayed_work(&pHddCtx->scan_ctxt.scan_work); + + wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt); + + if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) + { + wlan_hdd_cfg80211_deregister_frames(pAdapter); + hdd_UnregisterWext(pAdapter->dev); + } + + } + vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + + // Cancel any outstanding scan requests. We are about to close all + // of our adapters, but an adapter structure is what SME passes back + // to our callback function. Hence if there are any outstanding scan + // requests then there is a race condition between when the adapter + // is closed and when the callback is invoked.We try to resolve that + // race condition here by canceling any outstanding scans before we + // close the adapters. + // Note that the scans may be cancelled in an asynchronous manner, + // so ideally there needs to be some kind of synchronization. Rather + // than introduce a new synchronization here, we will utilize the + // fact that we are about to Request Full Power, and since that is + // synchronized, the expectation is that by the time Request Full + // Power has completed all scans will be cancelled. + if (pHddCtx->scan_info.mScanPending) + { + if(NULL != pAdapter) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("abort scan mode: %d sessionId: %d"), + pAdapter->device_mode, + pAdapter->sessionId); + } + hdd_abort_mac_scan(pHddCtx, + pHddCtx->scan_info.sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: FTM MODE",__func__); + if (pHddCtx->ftm.ftm_state == WLAN_FTM_STARTING) + { + INIT_COMPLETION(pHddCtx->ftm.startCmpVar); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: in middle of FTM START", __func__); + lrc = wait_for_completion_timeout(&pHddCtx->ftm.startCmpVar, + msecs_to_jiffies(20000)); + if(!lrc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: timedout on ftmStartCmpVar fatal error", __func__); + } + } + wlan_hdd_ftm_close(pHddCtx); + goto free_hdd_ctx; + } + + /* DeRegister with platform driver as client for Suspend/Resume */ + vosStatus = hddDeregisterPmOps(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDeregisterPmOps failed",__func__); + VOS_ASSERT(0); + } + + vosStatus = hddDevTmUnregisterNotifyCallback(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmUnregisterNotifyCallback failed",__func__); + } + + //Stop the traffic monitor timer + if ((pHddCtx->cfg_ini->dynSplitscan) && (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_stop(&pHddCtx->tx_rx_trafficTmr); + } + + // Destroy the traffic monitor timer + if ((pHddCtx->cfg_ini->dynSplitscan) && + (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->tx_rx_trafficTmr)))) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Cannot deallocate Traffic monitor timer", __func__); + } + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->delack_timer)) { + vos_timer_stop(&pHddCtx->delack_timer); + } + + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->delack_timer))) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Cannot deallocate Bus bandwidth timer", __func__); + } + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) { + vos_timer_stop(&pHddCtx->tdls_source_timer); + } + + vos_set_snoc_high_freq_voting(false); + + vos_timer_destroy(&pHddCtx->tdls_source_timer); + + //Disable IMPS/BMPS as we do not want the device to enter any power + //save mode during shutdown + sme_DisablePowerSave(pHddCtx->hHal, ePMC_IDLE_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_BEACON_MODE_POWER_SAVE); + sme_DisablePowerSave(pHddCtx->hHal, ePMC_UAPSD_MODE_POWER_SAVE); + + //Ensure that device is in full power as we will touch H/W during vos_Stop + init_completion(&powerContext.completion); + powerContext.magic = POWER_CONTEXT_MAGIC; + + halStatus = sme_RequestFullPower(pHddCtx->hHal, hdd_full_power_callback, + &powerContext, eSME_FULL_PWR_NEEDED_BY_HDD); + + if (eHAL_STATUS_SUCCESS != halStatus) + { + if (eHAL_STATUS_PMC_PENDING == halStatus) + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout( + &powerContext.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: %s while requesting full power", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Request for Full Power failed, status %d", + __func__, halStatus); + /* continue -- need to clean up as much as possible */ + } + } + if ((eHAL_STATUS_SUCCESS == halStatus) || + (eHAL_STATUS_PMC_PENDING == halStatus && lrc > 0)) + { + /* This will issue a dump command which will clean up + BTQM queues and unblock MC thread */ + vos_fwDumpReq(274, 0, 0, 0, 0, 1); + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + powerContext.magic = 0; + spin_unlock(&hdd_context_lock); + + /* If Device is shutdown, no point for SME to wait for responses + from device. Pre Close SME */ + if(wcnss_device_is_shutdown()) + { + sme_PreClose(pHddCtx->hHal); + } + hdd_debugfs_exit(pHddCtx); + +#ifdef WLAN_NS_OFFLOAD + hddLog(LOG1, FL("Unregister IPv6 notifier")); + unregister_inet6addr_notifier(&pHddCtx->ipv6_notifier); +#endif + hddLog(LOG1, FL("Unregister IPv4 notifier")); + unregister_inetaddr_notifier(&pHddCtx->ipv4_notifier); + + // Unregister the Net Device Notifier + unregister_netdevice_notifier(&hdd_netdev_notifier); + + hdd_stop_all_adapters( pHddCtx ); + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Stop(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop BAP",__func__); + } +#endif //WLAN_BTAMP_FEATURE + + //Stop all the modules + vosStatus = vos_stop( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop VOSS",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + if (isSsrPanicOnFailure()) + VOS_BUG(0); + } + + //This requires pMac access, Call this before vos_close(). + hdd_unregister_mcast_bcast_filter(pHddCtx); + + //Close the scheduler before calling vos_close to make sure no thread is + // scheduled after the each module close is called i.e after all the data + // structures are freed. + vosStatus = vos_sched_close( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to close VOSS Scheduler",__func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + /* Destroy the wake lock */ + vos_wake_lock_destroy(&pHddCtx->rx_wake_lock); +#endif + /* Destroy the wake lock */ + vos_wake_lock_destroy(&pHddCtx->sap_wake_lock); + +#ifdef CONFIG_ENABLE_LINUX_REG + vosStatus = vos_nv_close(); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close NV", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif + + //Close VOSS + //This frees pMac(HAL) context. There should not be any call that requires pMac access after this. + vos_close(pVosContext); + + //Close Watchdog + if(pHddCtx->cfg_ini->fIsLogpEnabled) + vos_watchdog_close(pVosContext); + + //Clean up HDD Nlink Service + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); + + hdd_close_tx_queues(pHddCtx); + wlan_free_fwr_mem_dump_buffer(); + memdump_deinit(); + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if (pHddCtx->cfg_ini->wlanLoggingEnable) + { + wlan_logging_sock_deactivate_svc(); + } +#endif + +#ifdef WLAN_KD_READY_NOTIFIER + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ + +#ifdef WLAN_FEATURE_RMC + hdd_close_cesium_nl_sock(); +#endif /* WLAN_FEATURE_RMC */ + + hdd_close_all_adapters( pHddCtx ); + + vos_flush_delayed_work(&pHddCtx->spoof_mac_addr_work); + vos_flush_work(&pHddCtx->sap_start_work); + +free_hdd_ctx: + /* free the power on lock from platform driver */ + if (free_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to free power on lock", + __func__); + } + + //Free up dynamically allocated members inside HDD Adapter + if (pHddCtx->cfg_ini) + { + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + } + + /* FTM/MONITOR mode, WIPHY did not registered + If un-register here, system crash will happen */ + if (!(VOS_FTM_MODE == hdd_get_conparam() || + VOS_MONITOR_MODE == hdd_get_conparam())) + { + wiphy_unregister(wiphy) ; + hdd_wlan_free_wiphy_channels(wiphy); + } + wiphy_free(wiphy) ; + if (hdd_is_ssr_required()) + { + /* WDI timeout had happened during unload, so SSR is needed here */ + subsystem_restart("wcnss"); + msleep(5000); + } + hdd_set_ssr_required (VOS_FALSE); +} + + +/**--------------------------------------------------------------------------- + + \brief hdd_update_config_from_nv() - Function to update the contents of + the running configuration with parameters taken from NV storage + + \param - pHddCtx - Pointer to the HDD global context + + \return - VOS_STATUS_SUCCESS if successful + + --------------------------------------------------------------------------*/ +static VOS_STATUS hdd_update_config_from_nv(hdd_context_t* pHddCtx) +{ + v_BOOL_t itemIsValid = VOS_FALSE; + VOS_STATUS status; + v_MACADDR_t macFromNV[VOS_MAX_CONCURRENCY_PERSONA]; + v_U8_t macLoop; + + /*If the NV is valid then get the macaddress from nv else get it from qcom_cfg.ini*/ + status = vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid); + if(status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_getValidity() failed"); + return VOS_STATUS_E_FAILURE; + } + + if (itemIsValid == VOS_TRUE) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH," Reading the Macaddress from NV"); + status = vos_nv_readMultiMacAddress((v_U8_t *)&macFromNV[0].bytes[0], + VOS_MAX_CONCURRENCY_PERSONA); + if(status != VOS_STATUS_SUCCESS) + { + /* Get MAC from NV fail, not update CFG info + * INI MAC value will be used for MAC setting */ + hddLog(VOS_TRACE_LEVEL_ERROR," vos_nv_readMacAddress() failed"); + return VOS_STATUS_E_FAILURE; + } + + /* If first MAC is not valid, treat all others are not valid + * Then all MACs will be got from ini file */ + if(vos_is_macaddr_zero(&macFromNV[0])) + { + /* MAC address in NV file is not configured yet */ + hddLog(VOS_TRACE_LEVEL_WARN, "Invalid MAC in NV file"); + return VOS_STATUS_E_INVAL; + } + + /* Get MAC address from NV, update CFG info */ + for(macLoop = 0; macLoop < VOS_MAX_CONCURRENCY_PERSONA; macLoop++) + { + if(vos_is_macaddr_zero(&macFromNV[macLoop])) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"not valid MAC from NV for %d", macLoop); + /* This MAC is not valid, skip it + * This MAC will be got from ini file */ + } + else + { + vos_mem_copy((v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[macLoop].bytes[0], + (v_U8_t *)&macFromNV[macLoop].bytes[0], + VOS_MAC_ADDR_SIZE); + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "NV ITEM, MAC Not valid"); + return VOS_STATUS_E_FAILURE; + } + + + return VOS_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_post_voss_start_config() - HDD post voss start config helper + + \param - pAdapter - Pointer to the HDD + + \return - None + + --------------------------------------------------------------------------*/ +VOS_STATUS hdd_post_voss_start_config(hdd_context_t* pHddCtx) +{ + eHalStatus halStatus; + v_U32_t listenInterval; + tANI_U32 ignoreDtim; + + + // Send ready indication to the HDD. This will kick off the MAC + // into a 'running' state and should kick off an initial scan. + halStatus = sme_HDDReadyInd( pHddCtx->hHal ); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: sme_HDDReadyInd() failed with status " + "code %08d [x%08x]",__func__, halStatus, halStatus ); + return VOS_STATUS_E_FAILURE; + } + + // Set default LI and ignoreDtim into HDD context, + // otherwise under some race condition, HDD will set 0 LI value into RIVA, + // And RIVA will crash + wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_LISTEN_INTERVAL, &listenInterval); + pHddCtx->hdd_actual_LI_value = listenInterval; + wlan_cfgGetInt(pHddCtx->hHal, WNI_CFG_IGNORE_DTIM, &ignoreDtim); + pHddCtx->hdd_actual_ignore_DTIM_value = ignoreDtim; + + + return VOS_STATUS_SUCCESS; +} + +/* wake lock APIs for HDD */ +void hdd_prevent_suspend(uint32_t reason) +{ + + vos_wake_lock_acquire(&wlan_wake_lock, reason); + +} + +void hdd_allow_suspend(uint32_t reason) +{ + + vos_wake_lock_release(&wlan_wake_lock, reason); + +} + +void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason) +{ + + vos_wake_lock_timeout_release(&wlan_wake_lock, timeout, + reason); + +} + +/**--------------------------------------------------------------------------- + + \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability + information between Host and Riva + + This function gets reported version of FW + It also finds the version of Riva headers used to compile the host + It compares the above two and prints a warning if they are different + It gets the SW and HW version string + Finally, it exchanges capabilities between host and Riva i.e. host and riva exchange a msg + indicating the features they support through a bitmap + + \param - pHddCtx - Pointer to HDD context + + \return - void + + --------------------------------------------------------------------------*/ + +void hdd_exchange_version_and_caps(hdd_context_t *pHddCtx) +{ + + tSirVersionType versionCompiled; + tSirVersionType versionReported; + tSirVersionString versionString; + tANI_U8 fwFeatCapsMsgSupported = 0; + VOS_STATUS vstatus; + + memset(&versionCompiled, 0, sizeof(versionCompiled)); + memset(&versionReported, 0, sizeof(versionReported)); + + /* retrieve and display WCNSS version information */ + do { + + vstatus = sme_GetWcnssWlanCompiledVersion(pHddCtx->hHal, + &versionCompiled); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS WLAN compiled version", + __func__); + break; + } + + vstatus = sme_GetWcnssWlanReportedVersion(pHddCtx->hHal, + &versionReported); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS WLAN reported version", + __func__); + break; + } + + if ((versionCompiled.major != versionReported.major) || + (versionCompiled.minor != versionReported.minor) || + (versionCompiled.version != versionReported.version) || + (versionCompiled.revision != versionReported.revision)) + { + pr_err("%s: WCNSS WLAN Version %u.%u.%u.%u, " + "Host expected %u.%u.%u.%u\n", + WLAN_MODULE_NAME, + (int)versionReported.major, + (int)versionReported.minor, + (int)versionReported.version, + (int)versionReported.revision, + (int)versionCompiled.major, + (int)versionCompiled.minor, + (int)versionCompiled.version, + (int)versionCompiled.revision); + } + else + { + pr_info("%s: WCNSS WLAN version %u.%u.%u.%u\n", + WLAN_MODULE_NAME, + (int)versionReported.major, + (int)versionReported.minor, + (int)versionReported.version, + (int)versionReported.revision); + } + + vstatus = sme_GetWcnssSoftwareVersion(pHddCtx->hHal, + versionString, + sizeof(versionString)); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS software version string", + __func__); + break; + } + + pr_info("%s: WCNSS software version %s\n", + WLAN_MODULE_NAME, versionString); + vos_mem_copy(pHddCtx->fw_Version, versionString, sizeof(versionString)); + + vstatus = sme_GetWcnssHardwareVersion(pHddCtx->hHal, + versionString, + sizeof(versionString)); + if (!VOS_IS_STATUS_SUCCESS(vstatus)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: unable to retrieve WCNSS hardware version string", + __func__); + break; + } + + pr_info("%s: WCNSS hardware version %s\n", + WLAN_MODULE_NAME, versionString); + + /* 1.Check if FW version is greater than 0.1.1.0. Only then send host-FW capability exchange message + 2.Host-FW capability exchange message is only present on riva 1.1 so + send the message only if it the riva is 1.1 + minor numbers for different riva branches: + 0 -> (1.0)Mainline Build + 1 -> (1.1)Mainline Build + 2->(1.04) Stability Build + */ + if (((versionReported.major>0) || (versionReported.minor>1) || + ((versionReported.minor>=1) && (versionReported.version>=1))) + && ((versionReported.major == 1) && (versionReported.minor >= 1))) + fwFeatCapsMsgSupported = 1; + + if (fwFeatCapsMsgSupported) + { +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(!pHddCtx->cfg_ini->fEnableActiveModeOffload) + sme_disableFeatureCapablity(WLANACTIVE_OFFLOAD); +#endif + /* Indicate if IBSS heartbeat monitoring needs to be offloaded */ + if (!pHddCtx->cfg_ini->enableIbssHeartBeatOffload) + { + sme_disableFeatureCapablity(IBSS_HEARTBEAT_OFFLOAD); + } + + sme_featureCapsExchange(pHddCtx->hHal); + } + + } while (0); + +} +void wlan_hdd_send_svc_nlink_msg(int type, void *data, int len) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *ani_hdr; + int flags = GFP_KERNEL; + void *nl_data = NULL; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + flags = GFP_ATOMIC; + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags); + + if(skb == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_SVC; + + ani_hdr = NLMSG_DATA(nlh); + ani_hdr->type = type; + + switch(type) { + case WLAN_SVC_SAP_RESTART_IND: + ani_hdr->length = 0; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + break; + case WLAN_SVC_WLAN_TP_IND: + ani_hdr->length = len; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + + len)); + nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); + memcpy(nl_data, data, len); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len)); + break; + case WLAN_MSG_RPS_ENABLE_IND: + ani_hdr->length = len; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len)); + nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr); + memcpy(nl_data, data, len); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len)); + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Attempt to send unknown nlink message %d", type); + kfree_skb(skb); + return; + } + + nl_srv_bcast(skb); + + return; +} + +/** + * hdd_request_tcp_delack() - Find the Delack value based on RX packet + * @pHddCtx: Valid Global HDD context pointer + * @rx_packets: Number of RX packet in perticular time + * + * Based on the RX packet this function calculate next value of tcp delack. + * This function compare rx packet value to high and low threshold limit. + * + * Return: void + */ +void hdd_request_tcp_delack(hdd_context_t *pHddCtx, uint64_t rx_packets) +{ + /* average of rx_packets and prev_rx is taken so that + bus width doesnot fluctuate much */ + uint64_t temp_rx = (rx_packets + pHddCtx->prev_rx)/2; + TP_IND_TYPE next_rx_level = pHddCtx->cur_rx_level; + + pHddCtx->prev_rx = rx_packets; + if (temp_rx > pHddCtx->cfg_ini->tcpDelAckThresholdHigh) + next_rx_level = TP_IND_HIGH; + else if (temp_rx <= pHddCtx->cfg_ini->tcpDelAckThresholdLow) + next_rx_level = TP_IND_LOW; + + hdd_set_delack_value(pHddCtx, next_rx_level); +} + +#define HDD_BW_GET_DIFF(x, y) ((x) >= (y) ? (x) - (y) : (ULONG_MAX - (y) + (x))) + +/** + * hdd_tcp_delack_compute_function() - get link status + * @priv: Valid Global HDD context pointer + * + * This function find number of RX packet during timer life span. + * It request tcp delack with number of RX packet and re-configure delack timer + * for tcpDelAckComputeInterval timer interval. + * + * Return: void + */ +void hdd_tcp_delack_compute_function(void *priv) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)priv; + hdd_adapter_t *pAdapter = NULL; + v_U32_t rx_packets = 0; + hdd_adapter_list_node_t *pAdapterNode = NULL; + VOS_STATUS status = 0; + + for (status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + NULL != pAdapterNode && VOS_STATUS_SUCCESS == status; + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pAdapterNode)) { + if ((pAdapter = pAdapterNode->pAdapter) == NULL) + continue; + + rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets, + pAdapter->prev_rx_packets); + pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + } + + hdd_request_tcp_delack(pHddCtx, rx_packets); + + vos_timer_start(&pHddCtx->delack_timer, + pHddCtx->cfg_ini->tcpDelAckComputeInterval); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_is_5g_supported() - HDD function to know if hardware supports 5GHz + + \param - pHddCtx - Pointer to the hdd context + + \return - true if hardware supports 5GHz + + --------------------------------------------------------------------------*/ +boolean hdd_is_5g_supported(hdd_context_t * pHddCtx) +{ + /* If wcnss_wlan_iris_xo_mode() returns WCNSS_XO_48MHZ(1); + * then hardware support 5Ghz. + */ + if (WCNSS_XO_48MHZ == wcnss_wlan_iris_xo_mode()) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware supports 5Ghz", __func__); + return true; + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Hardware doesn't supports 5Ghz", + __func__); + return false; + } +} + +/**--------------------------------------------------------------------------- + + \brief hdd_generate_iface_mac_addr_auto() - HDD Mac Interface Auto + generate function + + This is generate the random mac address for WLAN interface + + \param - pHddCtx - Pointer to HDD context + idx - Start interface index to get auto + generated mac addr. + mac_addr - Mac address + + \return - 0 for success, < 0 for failure + + --------------------------------------------------------------------------*/ + +static int hdd_generate_iface_mac_addr_auto(hdd_context_t *pHddCtx, + int idx, v_MACADDR_t mac_addr) +{ + int i; + unsigned int serialno; + serialno = wcnss_get_serial_number(); + + if (0 != serialno) + { + /* MAC address has 3 bytes of OUI so we have a maximum of 3 + bytes of the serial number that can be used to generate + the other 3 bytes of the MAC address. Mask off all but + the lower 3 bytes (this will also make sure we don't + overflow in the next step) */ + serialno &= 0x00FFFFFF; + + /* we need a unique address for each session */ + serialno *= VOS_MAX_CONCURRENCY_PERSONA; + + /* autogen other Mac addresses */ + for (i = idx; i < VOS_MAX_CONCURRENCY_PERSONA; i++) + { + /* start with the entire default address */ + pHddCtx->cfg_ini->intfMacAddr[i] = mac_addr; + /* then replace the lower 3 bytes */ + pHddCtx->cfg_ini->intfMacAddr[i].bytes[3] = (serialno >> 16) & 0xFF; + pHddCtx->cfg_ini->intfMacAddr[i].bytes[4] = (serialno >> 8) & 0xFF; + pHddCtx->cfg_ini->intfMacAddr[i].bytes[5] = serialno & 0xFF; + + serialno++; + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Derived Mac Addr: " + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[i].bytes)); + } + + } + else + { + hddLog(LOGE, FL("Failed to Get Serial NO")); + return -1; + } + return 0; +} + +int wlan_hdd_mon_open(hdd_context_t *pHddCtx) +{ + VOS_STATUS status; + v_CONTEXT_t pVosContext= NULL; + hdd_adapter_t *pAdapter= NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL == pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to open VOSS without a PreOpen", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + status = vos_nv_open(); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + /* NV module cannot be initialized */ + hddLog( VOS_TRACE_LEVEL_FATAL, + "%s: vos_nv_open failed", __func__); + return VOS_STATUS_E_FAILURE; + } + + status = vos_init_wiphy_from_nv_bin(); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + /* NV module cannot be initialized */ + hddLog( VOS_TRACE_LEVEL_FATAL, + "%s: vos_init_wiphy failed", __func__); + goto err_vos_nv_close; + } + + status = vos_open( &pVosContext, pHddCtx->parent_dev); + if ( !VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__); + goto err_vos_nv_close; + } + + status = vos_mon_start( pVosContext ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__); + goto err_vosclose; + } + + WLANTL_SetMonRxCbk( pVosContext, hdd_rx_packet_monitor_cbk ); + WDA_featureCapsExchange(pVosContext); + wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx); + + pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_MONITOR, "wlan%d", + wlan_hdd_get_intf_addr(pHddCtx), FALSE ); + if( pAdapter == NULL ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__); + goto err_close_adapter; + } + + //Initialize the nlink service + if(nl_srv_init() != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__); + goto err_close_adapter; + } + return VOS_STATUS_SUCCESS; + +err_close_adapter: + hdd_close_all_adapters( pHddCtx ); + vos_mon_stop( pVosContext ); +err_vosclose: + status = vos_sched_close( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to close VOSS Scheduler", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) ); + } + vos_close(pVosContext ); + +err_vos_nv_close: + vos_nv_close(); + +return status; +} +/**--------------------------------------------------------------------------- + + \brief hdd_11d_scan_done - callback to be executed when 11d scan is + completed to flush out the scan results + + 11d scan is done during driver load and is a passive scan on all + channels supported by the device, 11d scans may find some APs on + frequencies which are forbidden to be used in the regulatory domain + the device is operating in. If these APs are notified to the supplicant + it may try to connect to these APs, thus flush out all the scan results + which are present in SME after 11d scan is done. + + \return - eHalStatus + + --------------------------------------------------------------------------*/ +static eHalStatus hdd_11d_scan_done(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + ENTER(); + + sme_ScanFlushResult(halHandle, 0); + + EXIT(); + + return eHAL_STATUS_SUCCESS; +} +/**--------------------------------------------------------------------------- + + \brief hdd_init_frame_logging_done - callback to be executed when mgmt frame + logging is completed successfully. + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_init_frame_logging_done(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp) +{ + hdd_context_t* pHddCtx = (hdd_context_t*)fwlogInitCbContext; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is NULL",__func__); + return; + } + + if ((pRsp->status == VOS_STATUS_SUCCESS) && + (TRUE == pHddCtx->cfg_ini->enableMgmtLogging)) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init successful")); + pHddCtx->mgmt_frame_logging = TRUE; + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Mgmt Frame Logging init not success")); + pHddCtx->mgmt_frame_logging = FALSE; + return; + } + + /*Check feature supported by FW*/ + if(TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)) + { + //Store fwr mem dump size given by firmware. + wlan_store_fwr_mem_dump_size(pRsp->fw_mem_dump_max_size); + } + else + { + wlan_store_fwr_mem_dump_size(0); + } + + +} +/**--------------------------------------------------------------------------- + + \brief hdd_init_frame_logging - function to initialize frame logging. + Currently only Mgmt Frames are logged in both TX + and Rx direction and are sent to userspace + application using logger thread when queried. + + \return - None + + --------------------------------------------------------------------------*/ +void hdd_init_frame_logging(hdd_context_t* pHddCtx) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tSirFWLoggingInitParam wlanFWLoggingInitParam = {0}; + + if (TRUE != sme_IsFeatureSupportedByFW(MGMT_FRAME_LOGGING) && + TRUE != sme_IsFeatureSupportedByFW(LOGGING_ENHANCEMENT)) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("MGMT_FRAME_LOGGING not supp by FW")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Configuring %s %s %s %s Logging",__func__, + pHddCtx->cfg_ini->enableFWLogging?"FW Log,":"", + pHddCtx->cfg_ini->enableContFWLogging ? "Cont FW log,":"", + pHddCtx->cfg_ini->enableMgmtLogging ? "Mgmt Pkt Log":"", + pHddCtx->cfg_ini->enableFwrMemDump ? "Fw Mem dump":""); + + if (pHddCtx->cfg_ini->enableFWLogging || + pHddCtx->cfg_ini->enableContFWLogging) + { + wlanFWLoggingInitParam.enableFlag |= WLAN_QXDM_LOG_EN; + } + + if (pHddCtx->cfg_ini->enableMgmtLogging) + { + wlanFWLoggingInitParam.enableFlag |= WLAN_FRAME_LOG_EN; + } + if (pHddCtx->cfg_ini->enableBMUHWtracing) + { + wlanFWLoggingInitParam.enableFlag |= WLAN_BMUHW_TRACE_LOG_EN; + } + if(pHddCtx->cfg_ini->enableFwrMemDump && + (TRUE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))) + { + wlanFWLoggingInitParam.enableFlag |= WLAN_FW_MEM_DUMP_EN; + } + if( wlanFWLoggingInitParam.enableFlag == 0 ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Logging not enabled", __func__); + return; + } + wlanFWLoggingInitParam.frameType = WLAN_FRAME_LOGGING_FRAMETYPE_MGMT; + wlanFWLoggingInitParam.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES; + wlanFWLoggingInitParam.bufferMode = WLAN_FRAME_LOGGING_BUFFERMODE_CIRCULAR; + wlanFWLoggingInitParam.continuousFrameLogging = + pHddCtx->cfg_ini->enableContFWLogging; + + wlanFWLoggingInitParam.enableFlag &= ~WLAN_DPU_TXP_LOG_EN; + + wlanFWLoggingInitParam.minLogBufferSize = + pHddCtx->cfg_ini->minLoggingBufferSize; + wlanFWLoggingInitParam.maxLogBufferSize = + pHddCtx->cfg_ini->maxLoggingBufferSize; + wlanFWLoggingInitParam.fwlogInitCallback = hdd_init_frame_logging_done; + wlanFWLoggingInitParam.fwlogInitCbContext= pHddCtx; + + halStatus = sme_InitMgmtFrameLogging(pHddCtx->hHal, &wlanFWLoggingInitParam); + + if (eHAL_STATUS_SUCCESS != halStatus) + { + hddLog(LOGE, FL("sme_InitMgmtFrameLogging failed, returned %d"), + halStatus); + } + + return; +} + +static void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt) +{ + hdd_adapter_t *adapter; + hdd_adapter_list_node_t *adapter_node, *next; + VOS_STATUS status = VOS_STATUS_SUCCESS; + struct wlan_rps_data rps_data; + int count; + + if(!hdd_ctxt->cfg_ini->rps_mask) + { + return; + } + + for (count=0; count < WLAN_SVC_IFACE_NUM_QUEUES; count++) + { + rps_data.cpu_map[count] = hdd_ctxt->cfg_ini->rps_mask; + } + + rps_data.num_queues = WLAN_SVC_IFACE_NUM_QUEUES; + + hddLog(LOG1, FL("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x"), + rps_data.cpu_map[0], rps_data.cpu_map[1],rps_data.cpu_map[2], + rps_data.cpu_map[3], rps_data.cpu_map[4], rps_data.cpu_map[5]); + + status = hdd_get_front_adapter (hdd_ctxt, &adapter_node); + + while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) + { + adapter = adapter_node->pAdapter; + if (NULL != adapter) { + strlcpy(rps_data.ifname, adapter->dev->name, + sizeof(rps_data.ifname)); + wlan_hdd_send_svc_nlink_msg(WLAN_MSG_RPS_ENABLE_IND, + (void *)&rps_data,sizeof(rps_data)); + } + status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next); + adapter_node = next; + } +} + +void wlan_hdd_schedule_defer_scan(struct work_struct *work) +{ + scan_context_t *scan_ctx = + container_of(work, scan_context_t, scan_work.work); + + if (NULL == scan_ctx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("scan_ctx is NULL")); + return; + } + + if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic)) + return; + + scan_ctx->attempt++; + + wlan_hdd_cfg80211_scan(scan_ctx->wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + scan_ctx->dev, +#endif + scan_ctx->scan_request); +} + +int wlan_hdd_copy_defer_scan_context(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + scan_context_t *scan_ctx; + + ENTER(); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return -1; + } + + scan_ctx = &pHddCtx->scan_ctxt; + + scan_ctx->wiphy = wiphy; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + scan_ctx->dev = dev; +#endif + + scan_ctx->scan_request = request; + + EXIT(); + return 0; +} + +void wlan_hdd_defer_scan_init_work(hdd_context_t *pHddCtx, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request, + unsigned long delay) +{ + if (TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic) + { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, dev, request); +#else + wlan_hdd_copy_defer_scan_context(pHddCtx, wiphy, request); +#endif + pHddCtx->scan_ctxt.attempt = 0; + pHddCtx->scan_ctxt.magic = TDLS_CTX_MAGIC; + } + schedule_delayed_work(&pHddCtx->scan_ctxt.scan_work, delay); +} + +void wlan_hdd_init_deinit_defer_scan_context(scan_context_t *scan_ctx) +{ + scan_ctx->magic = 0; + scan_ctx->attempt = 0; + scan_ctx->reject = 0; + scan_ctx->scan_request = NULL; + + return; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_startup() - HDD init function + + This is the driver startup code executed once a WLAN device has been detected + + \param - dev - Pointer to the underlying device + + \return - 0 for success, < 0 for failure + + --------------------------------------------------------------------------*/ + +int hdd_wlan_startup(struct device *dev ) +{ + VOS_STATUS status; + hdd_adapter_t *pAdapter = NULL; + hdd_adapter_t *pP2pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext= NULL; +#ifdef WLAN_BTAMP_FEATURE + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + WLANBAP_ConfigType btAmpConfig; + hdd_config_t *pConfig; +#endif + int ret; + struct wiphy *wiphy; + v_MACADDR_t mac_addr; + + ENTER(); + /* + * cfg80211: wiphy allocation + */ + wiphy = wlan_hdd_cfg80211_wiphy_alloc(sizeof(hdd_context_t)) ; + + if(wiphy == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cfg80211 init failed", __func__); + return -EIO; + } + pHddCtx = wiphy_priv(wiphy); + + //Initialize the adapter context to zeros. + vos_mem_zero(pHddCtx, sizeof( hdd_context_t )); + + pHddCtx->wiphy = wiphy; + hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); + pHddCtx->isLoadUnloadInProgress = WLAN_HDD_LOAD_IN_PROGRESS; + + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + + /* register for riva power on lock to platform driver + * Locking power early to ensure FW doesn't reset by kernel while + * host driver is busy initializing itself */ + if (req_riva_power_on_lock("wlan")) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: req riva power on lock failed", + __func__); + goto err_free_hdd_context; + } + + /*Get vos context here bcoz vos_open requires it*/ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(pVosContext == NULL) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed vos_get_global_context",__func__); + goto err_free_hdd_context; + } + + //Save the Global VOSS context in adapter context for future. + pHddCtx->pvosContext = pVosContext; + + //Save the adapter context in global context for future. + ((VosContextType*)(pVosContext))->pHDDContext = (v_VOID_t*)pHddCtx; + + pHddCtx->parent_dev = dev; + pHddCtx->last_scan_reject_session_id = 0xFF; + pHddCtx->last_scan_reject_reason = 0; + pHddCtx->last_scan_reject_timestamp = 0; + pHddCtx->scan_reject_cnt = 0; + + init_completion(&pHddCtx->full_pwr_comp_var); + init_completion(&pHddCtx->standby_comp_var); + init_completion(&pHddCtx->req_bmps_comp_var); + init_completion(&pHddCtx->scan_info.scan_req_completion_event); + init_completion(&pHddCtx->scan_info.abortscan_event_var); + init_completion(&pHddCtx->wiphy_channel_update_event); + init_completion(&pHddCtx->ssr_comp_var); + init_completion(&pHddCtx->mc_sus_event_var); + init_completion(&pHddCtx->tx_sus_event_var); + init_completion(&pHddCtx->rx_sus_event_var); + + + hdd_init_ll_stats_ctx(pHddCtx); + hdd_init_nud_stats_ctx(pHddCtx); + +#ifdef CONFIG_ENABLE_LINUX_REG + init_completion(&pHddCtx->linux_reg_req); +#else + init_completion(&pHddCtx->driver_crda_req); +#endif + +#ifdef WLAN_FEATURE_EXTSCAN + init_completion(&pHddCtx->ext_scan_context.response_event); +#endif /* WLAN_FEATURE_EXTSCAN */ + + spin_lock_init(&pHddCtx->schedScan_lock); + vos_spin_lock_init(&pHddCtx->sap_update_info_lock); + + hdd_list_init( &pHddCtx->hddAdapters, MAX_NUMBER_OF_ADAPTERS ); + + vos_init_delayed_work(&pHddCtx->spoof_mac_addr_work, + hdd_processSpoofMacAddrRequest); + vos_init_work(&pHddCtx->sap_start_work, hdd_sap_restart_handle); + +#ifdef FEATURE_WLAN_TDLS + /* tdls_lock is initialized before an hdd_open_adapter ( which is + * invoked by other instances also) to protect the concurrent + * access for the Adapters by TDLS module. + */ + mutex_init(&pHddCtx->tdls_lock); +#endif + mutex_init(&pHddCtx->spoofMacAddr.macSpoofingLock); + mutex_init(&pHddCtx->wmmLock); + + hdd_init_offloaded_packets_ctx(pHddCtx); + /* By default Strict Regulatory For FCC should be false */ + + pHddCtx->nEnableStrictRegulatoryForFCC = FALSE; + // Load all config first as TL config is needed during vos_open + pHddCtx->cfg_ini = (hdd_config_t*) kmalloc(sizeof(hdd_config_t), GFP_KERNEL); + if(pHddCtx->cfg_ini == NULL) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed kmalloc hdd_config_t",__func__); + goto err_free_hdd_context; + } + + vos_mem_zero(pHddCtx->cfg_ini, sizeof( hdd_config_t )); + + // Read and parse the qcom_cfg.ini file + status = hdd_parse_config_ini( pHddCtx ); + if ( VOS_STATUS_SUCCESS != status ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s", + __func__, WLAN_INI_FILE); + goto err_config; + } +#ifdef MEMORY_DEBUG + if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled) + vos_mem_init(); + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d", + __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled); +#endif + + /* INI has been read, initialise the configuredMcastBcastFilter with + * INI value as this will serve as the default value + */ + pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting; + hddLog(VOS_TRACE_LEVEL_INFO, "Setting configuredMcastBcastFilter: %d", + pHddCtx->cfg_ini->mcastBcastFilterSetting); + + if (false == hdd_is_5g_supported(pHddCtx)) + { + //5Ghz is not supported. + if (1 != pHddCtx->cfg_ini->nBandCapability) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Setting pHddCtx->cfg_ini->nBandCapability = 1", __func__); + pHddCtx->cfg_ini->nBandCapability = 1; + } + } + + /* If SNR Monitoring is enabled, FW has to parse all beacons + * for calcaluting and storing the average SNR, so set Nth beacon + * filter to 1 to enable FW to parse all the beaocons + */ + if (1 == pHddCtx->cfg_ini->fEnableSNRMonitoring) + { + /* The log level is deliberately set to WARN as overriding + * nthBeaconFilter to 1 will increase power cosumption and this + * might just prove helpful to detect the power issue. + */ + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Setting pHddCtx->cfg_ini->nthBeaconFilter = 1", __func__); + pHddCtx->cfg_ini->nthBeaconFilter = 1; + } + /* + * cfg80211: Initialization ... + */ + if (0 < wlan_hdd_cfg80211_init(dev, wiphy, pHddCtx->cfg_ini)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: wlan_hdd_cfg80211_init return failure", __func__); + goto err_config; + } + + // Update VOS trace levels based upon the cfg.ini + hdd_vos_trace_enable(VOS_MODULE_ID_BAP, + pHddCtx->cfg_ini->vosTraceEnableBAP); + hdd_vos_trace_enable(VOS_MODULE_ID_TL, + pHddCtx->cfg_ini->vosTraceEnableTL); + hdd_vos_trace_enable(VOS_MODULE_ID_WDI, + pHddCtx->cfg_ini->vosTraceEnableWDI); + hdd_vos_trace_enable(VOS_MODULE_ID_HDD, + pHddCtx->cfg_ini->vosTraceEnableHDD); + hdd_vos_trace_enable(VOS_MODULE_ID_SME, + pHddCtx->cfg_ini->vosTraceEnableSME); + hdd_vos_trace_enable(VOS_MODULE_ID_PE, + pHddCtx->cfg_ini->vosTraceEnablePE); + hdd_vos_trace_enable(VOS_MODULE_ID_PMC, + pHddCtx->cfg_ini->vosTraceEnablePMC); + hdd_vos_trace_enable(VOS_MODULE_ID_WDA, + pHddCtx->cfg_ini->vosTraceEnableWDA); + hdd_vos_trace_enable(VOS_MODULE_ID_SYS, + pHddCtx->cfg_ini->vosTraceEnableSYS); + hdd_vos_trace_enable(VOS_MODULE_ID_VOSS, + pHddCtx->cfg_ini->vosTraceEnableVOSS); + hdd_vos_trace_enable(VOS_MODULE_ID_SAP, + pHddCtx->cfg_ini->vosTraceEnableSAP); + hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP, + pHddCtx->cfg_ini->vosTraceEnableHDDSAP); + + // Update WDI trace levels based upon the cfg.ini + hdd_wdi_trace_enable(eWLAN_MODULE_DAL, + pHddCtx->cfg_ini->wdiTraceEnableDAL); + hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL, + pHddCtx->cfg_ini->wdiTraceEnableCTL); + hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA, + pHddCtx->cfg_ini->wdiTraceEnableDAT); + hdd_wdi_trace_enable(eWLAN_MODULE_PAL, + pHddCtx->cfg_ini->wdiTraceEnablePAL); + + if (VOS_FTM_MODE == hdd_get_conparam()) + { + if ( VOS_STATUS_SUCCESS != wlan_hdd_ftm_open(pHddCtx) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_ftm_open Failed",__func__); + goto err_free_hdd_context; + } + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: FTM driver loaded success fully",__func__); + pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE); + return VOS_STATUS_SUCCESS; + } + + if( VOS_MONITOR_MODE == hdd_get_conparam()) + { + if ( VOS_STATUS_SUCCESS != wlan_hdd_mon_open(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: wlan_hdd_mon_open Failed",__func__); + goto err_free_hdd_context; + } + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Driver loaded in Monitor Mode",__func__); + pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE); + return VOS_STATUS_SUCCESS; + } + + //Open watchdog module + if(pHddCtx->cfg_ini->fIsLogpEnabled) + { + status = vos_watchdog_open(pVosContext, + &((VosContextType*)pVosContext)->vosWatchdog, sizeof(VosWatchdogContext)); + + if(!VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_watchdog_open failed",__func__); + goto err_config; + } + } + + pHddCtx->isLogpInProgress = FALSE; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); + +#ifdef CONFIG_ENABLE_LINUX_REG + /* initialize the NV module. This is required so that + we can initialize the channel information in wiphy + from the NV.bin data. The channel information in + wiphy needs to be initialized before wiphy registration */ + + status = vos_nv_open(); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + /* NV module cannot be initialized */ + hddLog( VOS_TRACE_LEVEL_FATAL, + "%s: vos_nv_open failed", __func__); + goto err_wdclose; + } + + status = vos_init_wiphy_from_nv_bin(); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + /* NV module cannot be initialized */ + hddLog( VOS_TRACE_LEVEL_FATAL, + "%s: vos_init_wiphy failed", __func__); + goto err_vos_nv_close; + } + +#endif + //Initialize the nlink service + if(nl_srv_init() != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: nl_srv_init failed", __func__); + goto err_vos_nv_close; + } + +#ifdef WLAN_KD_READY_NOTIFIER + pHddCtx->kd_nl_init = 1; +#endif /* WLAN_KD_READY_NOTIFIER */ + + vos_set_roam_delay_stats_enabled(pHddCtx->cfg_ini->gEnableRoamDelayStats); + status = vos_open( &pVosContext, pHddCtx->parent_dev); + if ( !VOS_IS_STATUS_SUCCESS( status )) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_open failed", __func__); + goto err_nl_srv; + } + + pHddCtx->hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, pVosContext ); + + if ( NULL == pHddCtx->hHal ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HAL context is null", __func__); + goto err_vosclose; + } + + status = vos_preStart( pHddCtx->pvosContext ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: vos_preStart failed", __func__); + goto err_vosclose; + } + + if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) + { + pHddCtx->cfg_ini->enableDFSChnlScan = enable_dfs_chan_scan; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_dfs_chan_scan set to %d", + __func__, enable_dfs_chan_scan); + } + if (0 == enable_11d || 1 == enable_11d) + { + pHddCtx->cfg_ini->Is11dSupportEnabled = enable_11d; + hddLog(VOS_TRACE_LEVEL_INFO, "%s: module enable_11d set to %d", + __func__, enable_11d); + } + + /* Note that the vos_preStart() sequence triggers the cfg download. + The cfg download must occur before we update the SME config + since the SME config operation must access the cfg database */ + status = hdd_set_sme_config( pHddCtx ); + + if ( VOS_STATUS_SUCCESS != status ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Failed hdd_set_sme_config", __func__); + goto err_vosclose; + } + + /* In the integrated architecture we update the configuration from + the INI file and from NV before vOSS has been started so that + the final contents are available to send down to the cCPU */ + + // Apply the cfg.ini to cfg.dat + if (FALSE == hdd_update_config_dat(pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: config update failed",__func__ ); + goto err_vosclose; + } + + // Get mac addr from platform driver + ret = wcnss_get_wlan_mac_address((char*)&mac_addr.bytes); + + if ((0 == ret) && (!vos_is_macaddr_zero(&mac_addr))) + { + /* Store the mac addr for first interface */ + pHddCtx->cfg_ini->intfMacAddr[0] = mac_addr; + + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: WLAN Mac Addr: " + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes)); + + /* Here, passing Arg2 as 1 because we do not want to change the + last 3 bytes (means non OUI bytes) of first interface mac + addr. + */ + if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 1, mac_addr)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failed to generate wlan interface mac addr " + "using MAC from ini file ", __func__); + } + } + else if (VOS_STATUS_SUCCESS != hdd_update_config_from_nv(pHddCtx)) + { + // Apply the NV to cfg.dat + /* Prima Update MAC address only at here */ +#ifdef WLAN_AUTOGEN_MACADDR_FEATURE + /* There was not a valid set of MAC Addresses in NV. See if the + default addresses were modified by the cfg.ini settings. If so, + we'll use them, but if not, we'll autogenerate a set of MAC + addresses based upon the device serial number */ + + static const v_MACADDR_t default_address = + {{0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}}; + + if (0 == memcmp(&default_address, &pHddCtx->cfg_ini->intfMacAddr[0], + sizeof(default_address))) + { + /* cfg.ini has the default address, invoke autogen logic */ + + /* Here, passing Arg2 as 0 because we want to change the + last 3 bytes (means non OUI bytes) of all the interfaces + mac addr. + */ + if (0 != hdd_generate_iface_mac_addr_auto(pHddCtx, 0, + default_address)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failed to generate wlan interface mac addr " + "using MAC from ini file " MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes)); + } + } + else +#endif //WLAN_AUTOGEN_MACADDR_FEATURE + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid MAC address in NV, using MAC from ini file " + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY(pHddCtx->cfg_ini->intfMacAddr[0].bytes)); + } + } + { + eHalStatus halStatus; + + /* Set the MAC Address Currently this is used by HAL to + * add self sta. Remove this once self sta is added as + * part of session open. + */ + halStatus = cfgSetStr( pHddCtx->hHal, WNI_CFG_STA_ID, + (v_U8_t *)&pHddCtx->cfg_ini->intfMacAddr[0], + sizeof( pHddCtx->cfg_ini->intfMacAddr[0]) ); + + if (!HAL_STATUS_SUCCESS( halStatus )) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failed to set MAC Address. " + "HALStatus is %08d [x%08x]",__func__, halStatus, halStatus ); + goto err_vosclose; + } + } + + /*Start VOSS which starts up the SME/MAC/HAL modules and everything else + Note: Firmware image will be read and downloaded inside vos_start API */ + status = vos_start( pHddCtx->pvosContext ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: vos_start failed",__func__); + if (isSsrPanicOnFailure()) + VOS_BUG(0); + goto err_vosclose; + } + +#ifdef FEATURE_WLAN_CH_AVOID + /* Plug in avoid channel notification callback + * This should happen before ADD_SELF_STA + * FW will send first IND with ADD_SELF_STA REQ from host */ + + /* check the Channel Avoidance is enabled */ + if (TRUE == pHddCtx->cfg_ini->fenableCHAvoidance) + { + sme_AddChAvoidCallback(pHddCtx->hHal, + hdd_hostapd_ch_avoid_cb); + } +#endif /* FEATURE_WLAN_CH_AVOID */ + + /* Exchange capability info between Host and FW and also get versioning info from FW */ + hdd_exchange_version_and_caps(pHddCtx); + +#ifdef CONFIG_ENABLE_LINUX_REG + status = wlan_hdd_init_channels(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels failed", + __func__); + goto err_vosstop; + } +#endif + + status = hdd_post_voss_start_config( pHddCtx ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_post_voss_start_config failed", + __func__); + goto err_vosstop; + } + +#ifndef CONFIG_ENABLE_LINUX_REG + wlan_hdd_cfg80211_update_reg_info( wiphy ); + + /* registration of wiphy dev with cfg80211 */ + if (0 > wlan_hdd_cfg80211_register(wiphy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__); + goto err_vosstop; + } +#endif + +#ifdef CONFIG_ENABLE_LINUX_REG + /* registration of wiphy dev with cfg80211 */ + if (0 > wlan_hdd_cfg80211_register(wiphy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__); + goto err_vosstop; + } + + status = wlan_hdd_init_channels_for_cc(pHddCtx, INIT); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: wlan_hdd_init_channels_for_cc failed", + __func__); + goto err_unregister_wiphy; + } +#endif + + wcnss_wlan_set_drvdata(pHddCtx->parent_dev, pHddCtx); + + if (VOS_STA_SAP_MODE == hdd_get_conparam()) + { + pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_SOFTAP, "softap.%d", + wlan_hdd_get_intf_addr(pHddCtx), FALSE ); + } + else + { + pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_INFRA_STATION, "wlan%d", + wlan_hdd_get_intf_addr(pHddCtx), FALSE ); + if (pAdapter != NULL) + { + if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && !(pHddCtx->cfg_ini->intfMacAddr[0].bytes[0] & 0x02)) + { + vos_mem_copy( pHddCtx->p2pDeviceAddress.bytes, + pHddCtx->cfg_ini->intfMacAddr[0].bytes, + sizeof(tSirMacAddr)); + + /* Generate the P2P Device Address. This consists of the device's + * primary MAC address with the locally administered bit set. + */ + pHddCtx->p2pDeviceAddress.bytes[0] |= 0x02; + } + else + { + tANI_U8* p2p_dev_addr = wlan_hdd_get_intf_addr(pHddCtx); + if (p2p_dev_addr != NULL) + { + vos_mem_copy(&pHddCtx->p2pDeviceAddress.bytes[0], + p2p_dev_addr, VOS_MAC_ADDR_SIZE); + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to allocate mac_address for p2p_device", + __func__); + goto err_close_adapter; + } + } + + pP2pAdapter = hdd_open_adapter( pHddCtx, WLAN_HDD_P2P_DEVICE, "p2p%d", + &pHddCtx->p2pDeviceAddress.bytes[0], FALSE ); + if ( NULL == pP2pAdapter ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to do hdd_open_adapter for P2P Device Interface", + __func__); + goto err_close_adapter; + } + } + } + + if( pAdapter == NULL ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: hdd_open_adapter failed", __func__); + goto err_close_adapter; + } + + if (country_code) + { + eHalStatus ret; + INIT_COMPLETION(pAdapter->change_country_code); + hdd_checkandupdate_dfssetting(pAdapter, country_code); +#ifndef CONFIG_ENABLE_LINUX_REG + hdd_checkandupdate_phymode(pAdapter, country_code); +#endif + ret = sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + wlan_hdd_change_country_code_callback, + country_code, + pAdapter, pHddCtx->pvosContext, + eSIR_TRUE, eSIR_TRUE); + if (eHAL_STATUS_SUCCESS == ret) + { + ret = wait_for_completion_interruptible_timeout( + &pAdapter->change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + + if (0 >= ret) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: SME while setting country code timed out", __func__); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: SME Change Country code from module param fail ret=%d", + __func__, ret); + } + } + +#ifdef WLAN_BTAMP_FEATURE + vStatus = WLANBAP_Open(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to open BAP",__func__); + goto err_close_adapter; + } + + vStatus = BSL_Init(pVosContext); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Init BSL",__func__); + goto err_bap_close; + } + vStatus = WLANBAP_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start TL",__func__); + goto err_bap_close; + } + + pConfig = pHddCtx->cfg_ini; + btAmpConfig.ucPreferredChannel = pConfig->preferredChannel; + status = WLANBAP_SetConfig(&btAmpConfig); + +#endif //WLAN_BTAMP_FEATURE + + /* + * UapsdMask is 0xf if U-APSD is enbaled for all AC's... + * The value of CFG_QOS_WMM_UAPSD_MASK_DEFAULT is 0xaa(Magic Value) + * which is greater than 0xf. So the below check is safe to make + * sure that there is no entry for UapsdMask in the ini + */ + if (CFG_QOS_WMM_UAPSD_MASK_DEFAULT == pHddCtx->cfg_ini->UapsdMask) + { + if(IS_DYNAMIC_WMM_PS_ENABLED) + { + hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Enable UAPSD for VI & VO", + __func__); + pHddCtx->cfg_ini->UapsdMask = + CFG_QOS_WMM_UAPSD_MASK_DYMANIC_WMM_PS_DEFAULT; + } + else + { + hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: Do not enable UAPSD", + __func__); + pHddCtx->cfg_ini->UapsdMask = + CFG_QOS_WMM_UAPSD_MASK_LEGACY_WMM_PS_DEFAULT; + } + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!(IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE)) + { + hddLog(VOS_TRACE_LEVEL_DEBUG,"%s: ROAM_SCAN_OFFLOAD Feature not supported",__func__); + pHddCtx->cfg_ini->isRoamOffloadScanEnabled = 0; + sme_UpdateRoamScanOffloadEnabled((tHalHandle)(pHddCtx->hHal), + pHddCtx->cfg_ini->isRoamOffloadScanEnabled); + } +#endif + + wlan_hdd_tdls_init(pHddCtx); + + wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt); + + vos_init_delayed_work(&pHddCtx->scan_ctxt.scan_work, + wlan_hdd_schedule_defer_scan); + + sme_Register11dScanDoneCallback(pHddCtx->hHal, hdd_11d_scan_done); + + /* Register with platform driver as client for Suspend/Resume */ + status = hddRegisterPmOps(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddRegisterPmOps failed",__func__); +#ifdef WLAN_BTAMP_FEATURE + goto err_bap_stop; +#else + goto err_close_adapter; +#endif //WLAN_BTAMP_FEATURE + } + + /* Open debugfs interface */ + if (VOS_STATUS_SUCCESS != hdd_debugfs_init(pAdapter)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: hdd_debugfs_init failed!", __func__); + } + + /* Register TM level change handler function to the platform */ + status = hddDevTmRegisterNotifyCallback(pHddCtx); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hddDevTmRegisterNotifyCallback failed",__func__); + goto err_unregister_pmops; + } + + // register net device notifier for device change notification + ret = register_netdevice_notifier(&hdd_netdev_notifier); + + if(ret < 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: register_netdevice_notifier failed",__func__); + goto err_unregister_pmops; + } + + //Initialize the BTC service + if(btc_activate_service(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: btc_activate_service failed",__func__); + goto err_reg_netdev; + } + +#ifdef FEATURE_OEM_DATA_SUPPORT + //Initialize the OEM service + if (oem_activate_service(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: oem_activate_service failed", __func__); + goto err_btc_activate_service; + } +#endif + +#ifdef PTT_SOCK_SVC_ENABLE + //Initialize the PTT service + if(ptt_sock_activate_svc(pHddCtx) != 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: ptt_sock_activate_svc failed",__func__); + goto err_oem_activate_service; + } +#endif + +#ifdef WLAN_FEATURE_RMC + if (hdd_open_cesium_nl_sock() < 0) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: hdd_open_cesium_nl_sock failed", __func__); + goto err_ptt_sock_activate_svc; + } +#endif + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if(pHddCtx->cfg_ini && pHddCtx->cfg_ini->wlanLoggingEnable) + { + if(wlan_logging_sock_activate_svc( + pHddCtx->cfg_ini->wlanLoggingFEToConsole, + pHddCtx->cfg_ini->wlanLoggingNumBuf, + pHddCtx->cfg_ini->wlanPerPktStatsLogEnable, + pHddCtx->cfg_ini->wlanPerPktStatsNumBuf)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_logging_sock_activate_svc" + " failed", __func__); + goto err_open_cesium_nl_sock; + } + //TODO: To Remove enableDhcpDebug and use gEnableDebugLog for + //EAPOL and DHCP + if (!pHddCtx->cfg_ini->gEnableDebugLog) + pHddCtx->cfg_ini->gEnableDebugLog = + VOS_PKT_PROTO_TYPE_EAPOL | VOS_PKT_PROTO_TYPE_DHCP | + VOS_PKT_PROTO_TYPE_ARP; + } + + if (pHddCtx->cfg_ini->wlanLoggingEnable && + (pHddCtx->cfg_ini->enableFWLogging || + pHddCtx->cfg_ini->enableMgmtLogging || + pHddCtx->cfg_ini->enableContFWLogging || + pHddCtx->cfg_ini->enableFwrMemDump ) + ) + { + hdd_init_frame_logging(pHddCtx); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Logging disabled in ini")); + } + +#endif + +#ifdef SAP_AUTH_OFFLOAD + if (!sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL(" SAP AUTH OFFLOAD not supp by FW")); + pHddCtx->cfg_ini->enable_sap_auth_offload = 0; + } +#endif + + if (vos_is_multicast_logging()) + wlan_logging_set_log_level(); + + hdd_register_mcast_bcast_filter(pHddCtx); + if (VOS_STA_SAP_MODE != hdd_get_conparam()) + { + /* Action frame registered in one adapter which will + * applicable to all interfaces + */ + wlan_hdd_cfg80211_register_frames(pAdapter); + } + + mutex_init(&pHddCtx->sap_lock); + mutex_init(&pHddCtx->roc_lock); + +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + /* Initialize the wake lcok */ + vos_wake_lock_init(&pHddCtx->rx_wake_lock, + "qcom_rx_wakelock"); + +#endif + /* Initialize the wake lcok */ + vos_wake_lock_init(&pHddCtx->sap_wake_lock, + "qcom_sap_wakelock"); + + + vos_event_init(&pHddCtx->scan_info.scan_finished_event); + pHddCtx->scan_info.scan_pending_option = WEXT_SCAN_PENDING_GIVEUP; + + pHddCtx->isLoadUnloadInProgress = WLAN_HDD_NO_LOAD_UNLOAD_IN_PROGRESS; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, FALSE); + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); + +#ifdef FEATURE_WLAN_SCAN_PNO + /*SME must send channel update configuration to RIVA*/ + sme_UpdateChannelConfig(pHddCtx->hHal); +#endif + /* Send the update default channel list to the FW*/ + sme_UpdateChannelList(pHddCtx->hHal); + + /* Fwr capabilities received, Set the Dot11 mode */ + sme_SetPhyMode(WLAN_HDD_GET_HAL_CTX(pAdapter), + hdd_cfg_xlate_to_csr_phy_mode(pHddCtx->cfg_ini->dot11Mode)); + sme_SetDefDot11Mode(pHddCtx->hHal); + +#ifndef CONFIG_ENABLE_LINUX_REG + /*updating wiphy so that regulatory user hints can be processed*/ + if (wiphy) + { + regulatory_hint(wiphy, "00"); + } +#endif + // Initialize the restart logic + wlan_hdd_restart_init(pHddCtx); + + if (pHddCtx->cfg_ini->fIsLogpEnabled) { + vos_wdthread_init_timer_work(vos_process_wd_timer); + /* Initialize the timer to detect thread stuck issues */ + vos_thread_stuck_timer_init( + &((VosContextType*)pVosContext)->vosWatchdog); + } + + //Register the traffic monitor timer now + if ( pHddCtx->cfg_ini->dynSplitscan) + { + vos_timer_init(&pHddCtx->tx_rx_trafficTmr, + VOS_TIMER_TYPE_SW, + hdd_tx_rx_pkt_cnt_stat_timer_handler, + (void *)pHddCtx); + } + wlan_hdd_cfg80211_nan_init(pHddCtx); + + mutex_init(&pHddCtx->cur_rx_level_lock); + vos_timer_init(&pHddCtx->delack_timer, VOS_TIMER_TYPE_SW, + hdd_tcp_delack_compute_function,(void *)pHddCtx); + vos_timer_init(&pHddCtx->tdls_source_timer, VOS_TIMER_TYPE_SW, + wlan_hdd_change_tdls_mode, (void *)pHddCtx); + +#ifdef WLAN_FEATURE_EXTSCAN + sme_EXTScanRegisterCallback(pHddCtx->hHal, + wlan_hdd_cfg80211_extscan_callback, + pHddCtx); +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + sme_OemDataRegisterCallback(pHddCtx->hHal, + wlan_hdd_cfg80211_oemdata_callback, + pHddCtx); +#endif /* FEATURE_OEM_DATA_SUPPORT */ + + sme_set_rssi_threshold_breached_cb(pHddCtx->hHal, hdd_rssi_threshold_breached_cb); +#ifdef WLAN_NS_OFFLOAD + // Register IPv6 notifier to notify if any change in IP + // So that we can reconfigure the offload parameters + pHddCtx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed; + ret = register_inet6addr_notifier(&pHddCtx->ipv6_notifier); + if (ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv6 notifier")); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv6 notifier")); + } +#endif + + vos_mem_set((uint8_t *)&pHddCtx->bad_sta, HDD_MAX_STA_COUNT, 0); + + // Register IPv4 notifier to notify if any change in IP + // So that we can reconfigure the offload parameters + pHddCtx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed; + ret = register_inetaddr_notifier(&pHddCtx->ipv4_notifier); + if (ret) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register IPv4 notifier")); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Registered IPv4 notifier")); + } + /*Fw mem dump procfs initialization*/ + memdump_init(); + hdd_dp_util_send_rps_ind(pHddCtx); + + pHddCtx->is_ap_mode_wow_supported = + sme_IsFeatureSupportedByFW(SAP_MODE_WOW); + + pHddCtx->is_fatal_event_log_sup = + sme_IsFeatureSupportedByFW(FATAL_EVENT_LOGGING); + hddLog(VOS_TRACE_LEVEL_INFO, FL("FATAL_EVENT_LOGGING: %d"), + pHddCtx->is_fatal_event_log_sup); + + hdd_assoc_registerFwdEapolCB(pVosContext); + + goto success; + +err_open_cesium_nl_sock: +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + hdd_close_cesium_nl_sock(); +#endif + +err_ptt_sock_activate_svc: +#ifdef PTT_SOCK_SVC_ENABLE + ptt_sock_deactivate_svc(pHddCtx); +#endif + +err_oem_activate_service: +#ifdef FEATURE_OEM_DATA_SUPPORT + oem_deactivate_service(); +#endif + +err_btc_activate_service: + btc_deactivate_service(); + +err_reg_netdev: + unregister_netdevice_notifier(&hdd_netdev_notifier); + +err_unregister_pmops: + hddDevTmUnregisterNotifyCallback(pHddCtx); + hddDeregisterPmOps(pHddCtx); + + hdd_debugfs_exit(pHddCtx); + +#ifdef WLAN_BTAMP_FEATURE +err_bap_stop: + WLANBAP_Stop(pVosContext); +#endif + +#ifdef WLAN_BTAMP_FEATURE +err_bap_close: + WLANBAP_Close(pVosContext); +#endif + +err_close_adapter: + hdd_close_all_adapters( pHddCtx ); +#ifdef CONFIG_ENABLE_LINUX_REG +err_unregister_wiphy: +#endif + wiphy_unregister(wiphy) ; + hdd_wlan_free_wiphy_channels(wiphy); + +err_vosstop: + vos_stop(pVosContext); + +err_vosclose: + status = vos_sched_close( pVosContext ); + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to close VOSS Scheduler", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status ) ); + } + vos_close(pVosContext ); + +err_nl_srv: +#ifdef WLAN_KD_READY_NOTIFIER + nl_srv_exit(pHddCtx->ptt_pid); +#else + nl_srv_exit(); +#endif /* WLAN_KD_READY_NOTIFIER */ +err_vos_nv_close: + +#ifdef CONFIG_ENABLE_LINUX_REG + vos_nv_close(); + +#endif + +err_wdclose: + if(pHddCtx->cfg_ini->fIsLogpEnabled) + vos_watchdog_close(pVosContext); + +err_config: + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + +err_free_hdd_context: + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); + free_riva_power_on_lock("wlan"); + wiphy_free(wiphy) ; + //kfree(wdev) ; + VOS_BUG(1); + + if (hdd_is_ssr_required()) + { + /* WDI timeout had happened during load, so SSR is needed here */ + subsystem_restart("wcnss"); + msleep(5000); + } + hdd_set_ssr_required (VOS_FALSE); + + return -EIO; + +success: + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_driver_init() - Core Driver Init Function + + This is the driver entry point - called in different timeline depending + on whether the driver is statically or dynamically linked + + \param - None + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int hdd_driver_init( void) +{ + VOS_STATUS status; + v_CONTEXT_t pVosContext = NULL; + struct device *dev = NULL; + int ret_status = 0; +#ifdef HAVE_WCNSS_CAL_DOWNLOAD + int max_retries = 0; +#endif +#ifdef HAVE_CBC_DONE + int max_cbc_retries = 0; +#endif + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_init_svc(); +#endif + + ENTER(); + + vos_wake_lock_init(&wlan_wake_lock, "wlan"); + + pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME, + QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR); + +#ifdef ANI_BUS_TYPE_PCI + + dev = wcnss_wlan_get_device(); + +#endif // ANI_BUS_TYPE_PCI + +#ifdef ANI_BUS_TYPE_PLATFORM + +#ifdef HAVE_WCNSS_CAL_DOWNLOAD + /* wait until WCNSS driver downloads NV */ + while (!wcnss_device_ready() && 10 >= ++max_retries) { + msleep(1000); + } + + if (max_retries >= 10) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__); + vos_wake_lock_destroy(&wlan_wake_lock); +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_deinit_svc(); +#endif + + return -ENODEV; + } +#endif + +#ifdef HAVE_CBC_DONE + while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) { + msleep(1000); + } + if (max_cbc_retries >= 10) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__); + } +#endif + + dev = wcnss_wlan_get_device(); +#endif // ANI_BUS_TYPE_PLATFORM + + + do { + if (NULL == dev) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__); + ret_status = -1; + break; + } + +#ifdef TIMER_MANAGER + vos_timer_manager_init(); +#endif + + /* Preopen VOSS so that it is ready to start at least SAL */ + status = vos_preOpen(&pVosContext); + + if (!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__); + ret_status = -1; + break; + } + + hddTraceInit(); + hdd_register_debug_callback(); + +#ifndef MODULE + /* For statically linked driver, call hdd_set_conparam to update curr_con_mode + */ + hdd_set_conparam((v_UINT_t)con_mode); +#endif + + // Call our main init function + if (hdd_wlan_startup(dev)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed", + __func__); + vos_preClose( &pVosContext ); + ret_status = -1; + break; + } + + } while (0); + + if (0 != ret_status) + { +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif + vos_wake_lock_destroy(&wlan_wake_lock); +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_deinit_svc(); +#endif + + pr_err("%s: driver load failure\n", WLAN_MODULE_NAME); + } + else + { + //Send WLAN UP indication to Nlink Service + send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0); + + pr_info("%s: driver loaded\n", WLAN_MODULE_NAME); + } + + EXIT(); + + return ret_status; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_module_init() - Init Function + + This is the driver entry point (invoked when module is loaded using insmod) + + \param - None + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +#ifdef MODULE +static int __init hdd_module_init ( void) +{ + return hdd_driver_init(); +} +#else /* #ifdef MODULE */ +static int __init hdd_module_init ( void) +{ + /* Driver initialization is delayed to fwpath_changed_handler */ + return 0; +} +#endif /* #ifdef MODULE */ + + +/**--------------------------------------------------------------------------- + + \brief hdd_driver_exit() - Exit function + + This is the driver exit point (invoked when module is unloaded using rmmod + or con_mode was changed by userspace) + + \param - None + + \return - None + + --------------------------------------------------------------------------*/ +static void hdd_driver_exit(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + v_REGDOMAIN_t regId; + unsigned long rc = 0; + + pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME, QWLAN_VERSIONSTR); + + //Get the global vos context + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + goto done; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: module exit called before probe",__func__); + } + else if (VOS_MONITOR_MODE == hdd_get_conparam()) + { + hddLog(VOS_TRACE_LEVEL_INFO,"%s: MONITOR MODE",__func__); + pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + hdd_wlan_exit(pHddCtx); + vos_preClose( &pVosContext ); + goto done; + } + else + { + /* We wait for active entry threads to exit from driver + * by waiting until rtnl_lock is available. + */ + rtnl_lock(); + rtnl_unlock(); + + INIT_COMPLETION(pHddCtx->ssr_comp_var); + if ((pHddCtx->isLogpInProgress) && (FALSE == + vos_is_wlan_in_badState(VOS_MODULE_ID_HDD, NULL))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:SSR in Progress; block rmmod !!!", __func__); + rc = wait_for_completion_timeout(&pHddCtx->ssr_comp_var, + msecs_to_jiffies(30000)); + if(!rc) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:SSR timedout, fatal error", __func__); + VOS_BUG(0); + } + } + + pHddCtx->isLoadUnloadInProgress = WLAN_HDD_UNLOAD_IN_PROGRESS; + vos_set_load_unload_in_progress(VOS_MODULE_ID_VOSS, TRUE); + + /* Driver Need to send country code 00 in below condition + * 1) If gCountryCodePriority is set to 1; and last country + * code set is through 11d. This needs to be done in case + * when NV country code is 00. + * This Needs to be done as when kernel store last country + * code and if stored country code is not through 11d, + * in sme_HandleChangeCountryCodeByUser we will disable 11d + * in next load/unload as soon as we get any country through + * 11d. In sme_HandleChangeCountryCodeByUser + * pMsg->countryCode will be last countryCode and + * pMac->scan.countryCode11d will be country through 11d so + * due to mismatch driver will disable 11d. + * + */ + + if ((eANI_BOOLEAN_TRUE == sme_Is11dCountrycode(pHddCtx->hHal) && + pHddCtx->cfg_ini->fSupplicantCountryCodeHasPriority && + sme_Is11dSupported(pHddCtx->hHal))) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("CountryCode 00 is being set while unloading driver")); + vos_nv_getRegDomainFromCountryCode(®Id , "00", COUNTRY_USER); + } + + //Do all the cleanup before deregistering the driver + hdd_wlan_exit(pHddCtx); + } + + vos_preClose( &pVosContext ); + +#ifdef TIMER_MANAGER + vos_timer_exit(); +#endif +#ifdef MEMORY_DEBUG + vos_mem_exit(); +#endif + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_logging_sock_deinit_svc(); +#endif + +done: + vos_wake_lock_destroy(&wlan_wake_lock); + + pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_module_exit() - Exit function + + This is the driver exit point (invoked when module is unloaded using rmmod) + + \param - None + + \return - None + + --------------------------------------------------------------------------*/ +static void __exit hdd_module_exit(void) +{ + hdd_driver_exit(); +} + +#ifdef MODULE +static int fwpath_changed_handler(const char *kmessage, + struct kernel_param *kp) +{ + return param_set_copystring(kmessage, kp); +} + +static int con_mode_handler(const char *kmessage, + struct kernel_param *kp) +{ + return param_set_int(kmessage, kp); +} +#else /* #ifdef MODULE */ +/**--------------------------------------------------------------------------- + + \brief kickstart_driver + + This is the driver entry point + - delayed driver initialization when driver is statically linked + - invoked when module parameter fwpath is modified from userspace to signal + initializing the WLAN driver or when con_mode is modified from userspace + to signal a switch in operating mode + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int kickstart_driver(void) +{ + int ret_status; + + if (!wlan_hdd_inited) { + ret_status = hdd_driver_init(); + wlan_hdd_inited = ret_status ? 0 : 1; + return ret_status; + } + + hdd_driver_exit(); + + msleep(200); + + ret_status = hdd_driver_init(); + wlan_hdd_inited = ret_status ? 0 : 1; + return ret_status; +} + +/**--------------------------------------------------------------------------- + + \brief fwpath_changed_handler() - Handler Function + + Handle changes to the fwpath parameter + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int fwpath_changed_handler(const char *kmessage, + struct kernel_param *kp) +{ + int ret; + + ret = param_set_copystring(kmessage, kp); + if (0 == ret) + ret = kickstart_driver(); + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief con_mode_handler() - + + Handler function for module param con_mode when it is changed by userspace + Dynamically linked - do nothing + Statically linked - exit and init driver, as in rmmod and insmod + + \param - + + \return - + + --------------------------------------------------------------------------*/ +static int con_mode_handler(const char *kmessage, struct kernel_param *kp) +{ + int ret; + + ret = param_set_int(kmessage, kp); + if (0 == ret) + ret = kickstart_driver(); + return ret; +} +#endif /* #ifdef MODULE */ + +/**--------------------------------------------------------------------------- + + \brief hdd_get_conparam() - + + This is the driver exit point (invoked when module is unloaded using rmmod) + + \param - None + + \return - tVOS_CON_MODE + + --------------------------------------------------------------------------*/ +tVOS_CON_MODE hdd_get_conparam ( void ) +{ +#ifdef MODULE + return (tVOS_CON_MODE)con_mode; +#else + return (tVOS_CON_MODE)curr_con_mode; +#endif +} +void hdd_set_conparam ( v_UINT_t newParam ) +{ + con_mode = newParam; +#ifndef MODULE + curr_con_mode = con_mode; +#endif +} +/**--------------------------------------------------------------------------- + + \brief hdd_softap_sta_deauth() - function + + This to take counter measure to handle deauth req from HDD + + \param - pAdapter - Pointer to the HDD + + \param - enable - boolean value + + \return - None + + --------------------------------------------------------------------------*/ + +VOS_STATUS hdd_softap_sta_deauth(hdd_adapter_t *pAdapter, + struct tagCsrDelStaParams *pDelStaParams) +{ + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + + ENTER(); + + hddLog(LOG1, "hdd_softap_sta_deauth:(%p, false)", + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + + //Ignore request to deauth bcmc station + if (pDelStaParams->peerMacAddr[0] & 0x1) + return vosStatus; + + vosStatus = WLANSAP_DeauthSta(pVosContext, pDelStaParams); + + EXIT(); + return vosStatus; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_del_all_sta() - function + + This function removes all the stations associated on stopping AP/P2P GO. + + \param - pAdapter - Pointer to the HDD + + \return - None + + --------------------------------------------------------------------------*/ + +int hdd_del_all_sta(hdd_adapter_t *pAdapter) +{ + v_U16_t i; + VOS_STATUS vos_status; + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return 1; + } + ENTER(); + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Delete all STAs associated.",__func__); + if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) + || (pAdapter->device_mode == WLAN_HDD_P2P_GO) + ) + { + for(i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if ((pSapCtx->aStaInfo[i].isUsed) && + (!pSapCtx->aStaInfo[i].isDeauthInProgress)) + { + struct tagCsrDelStaParams delStaParams; + + WLANSAP_PopulateDelStaParams( + pSapCtx->aStaInfo[i].macAddrSTA.bytes, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + SIR_MAC_MGMT_DEAUTH >> 4, + &delStaParams); + vos_status = hdd_softap_sta_deauth(pAdapter, &delStaParams); + if (VOS_IS_STATUS_SUCCESS(vos_status)) + pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE; + } + } + } + + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_softap_sta_disassoc() - function + + This to take counter measure to handle deauth req from HDD + + \param - pAdapter - Pointer to the HDD + + \param - enable - boolean value + + \return - None + + --------------------------------------------------------------------------*/ + +void hdd_softap_sta_disassoc(hdd_adapter_t *pAdapter,v_U8_t *pDestMacAddress) +{ + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + + ENTER(); + + hddLog( LOGE, "hdd_softap_sta_disassoc:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + + //Ignore request to disassoc bcmc station + if( pDestMacAddress[0] & 0x1 ) + return; + + WLANSAP_DisassocSta(pVosContext,pDestMacAddress); +} + +void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *pAdapter,v_BOOL_t enable) +{ + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + + ENTER(); + + hddLog( LOGE, "hdd_softap_tkip_mic_fail_counter_measure:(%p, false)", (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + + WLANSAP_SetCounterMeasure(pVosContext, (v_BOOL_t)enable); +} + +/**--------------------------------------------------------------------------- + * + * \brief hdd_get__concurrency_mode() - + * + * + * \param - None + * + * \return - CONCURRENCY MODE + * + * --------------------------------------------------------------------------*/ +tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void ) +{ + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx; + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + return (tVOS_CONCURRENCY_MODE)pHddCtx->concurrency_mode; + } + } + + /* we are in an invalid state :( */ + hddLog(LOGE, "%s: Invalid context", __func__); + return VOS_STA; +} +v_BOOL_t +wlan_hdd_is_GO_power_collapse_allowed (hdd_context_t* pHddCtx) +{ + hdd_adapter_t *pAdapter = NULL; + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_GO); + if (pAdapter == NULL) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("GO doesn't exist")); + return TRUE; + } + if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("GO started")); + return TRUE; + } + else + /* wait till GO changes its interface to p2p device */ + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Del_bss called, avoid apps suspend")); + return FALSE; + +} +/* Decide whether to allow/not the apps power collapse. + * Allow apps power collapse if we are in connected state. + * if not, allow only if we are in IMPS */ +v_BOOL_t hdd_is_apps_power_collapse_allowed(hdd_context_t* pHddCtx) +{ + tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal); + tANI_BOOLEAN scanRspPending = csrNeighborRoamScanRspPending(pHddCtx->hHal); + tANI_BOOLEAN inMiddleOfRoaming = csrNeighborMiddleOfRoaming(pHddCtx->hHal); + hdd_config_t *pConfig = pHddCtx->cfg_ini; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status; + tVOS_CONCURRENCY_MODE concurrent_state = 0; + + if (VOS_STA_SAP_MODE == hdd_get_conparam()) + return TRUE; + + concurrent_state = hdd_get_concurrency_mode(); + + if ((concurrent_state == (VOS_STA | VOS_P2P_GO)) && + !(wlan_hdd_is_GO_power_collapse_allowed(pHddCtx))) + return FALSE; +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + + if(((concurrent_state == (VOS_STA | VOS_P2P_CLIENT)) || + (concurrent_state == (VOS_STA | VOS_P2P_GO)))&& + (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + return TRUE; +#endif + + /*loop through all adapters. TBD fix for Concurrency */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) + || (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ) + { + if (((pConfig->fIsImpsEnabled || pConfig->fIsBmpsEnabled) + && (pmcState != IMPS && pmcState != BMPS && pmcState != UAPSD + && pmcState != STOPPED && pmcState != STANDBY && + pmcState != WOWL)) || + (eANI_BOOLEAN_TRUE == scanRspPending) || + (eANI_BOOLEAN_TRUE == inMiddleOfRoaming)) + { + if(pmcState == FULL_POWER && + sme_IsCoexScoIndicationSet(pHddCtx->hHal)) + { + /* + * When SCO indication comes from Coex module , host will + * enter in to full power mode, but this should not prevent + * apps processor power collapse. + */ + hddLog(LOG1, + FL("Allow apps power collapse" + "even when sco indication is set")); + return TRUE; + } + hddLog( LOGE, "%s: do not allow APPS power collapse-" + "pmcState = %d scanRspPending = %d " + "inMiddleOfRoaming = %d connected = %d", + __func__, pmcState, scanRspPending, + inMiddleOfRoaming, hdd_connIsConnected( + WLAN_HDD_GET_STATION_CTX_PTR( pAdapter ))); + wlan_hdd_get_tdls_stats(pAdapter); + return FALSE; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return TRUE; +} + +/* Decides whether to send suspend notification to Riva + * if any adapter is in BMPS; then it is required */ +v_BOOL_t hdd_is_suspend_notify_allowed(hdd_context_t* pHddCtx) +{ + tPmcState pmcState = pmcGetPmcState(pHddCtx->hHal); + hdd_config_t *pConfig = pHddCtx->cfg_ini; + + if (pConfig->fIsBmpsEnabled && (pmcState == BMPS)) + { + return TRUE; + } + return FALSE; +} + +void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + switch(mode) + { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + pHddCtx->concurrency_mode |= (1 << mode); + pHddCtx->no_of_open_sessions[mode]++; + break; + default: + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x " + "Number of open sessions for mode %d = %d"), + pHddCtx->concurrency_mode, mode, + pHddCtx->no_of_open_sessions[mode]); +} + + +void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + switch(mode) + { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + pHddCtx->no_of_open_sessions[mode]--; + if (!(pHddCtx->no_of_open_sessions[mode])) + pHddCtx->concurrency_mode &= (~(1 << mode)); + break; + default: + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("concurrency_mode = 0x%x " + "Number of open sessions for mode %d = %d"), + pHddCtx->concurrency_mode, mode, pHddCtx->no_of_open_sessions[mode]); + +} +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_incr_active_session() + * + * This function increments the number of active sessions + * maintained per device mode + * Incase of STA/P2P CLI/IBSS upon connection indication it is incremented + * Incase of SAP/P2P GO upon bss start it is incremented + * + * \param pHddCtx - HDD Context + * \param mode - device mode + * + * \return - None + * + * --------------------------------------------------------------------------*/ +void wlan_hdd_incr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + switch (mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + pHddCtx->no_of_active_sessions[mode]++; + break; + default: + hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode); + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"), + mode, + pHddCtx->no_of_active_sessions[mode]); +} + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_decr_active_session() + * + * This function decrements the number of active sessions + * maintained per device mode + * Incase of STA/P2P CLI/IBSS upon disconnection it is decremented + * Incase of SAP/P2P GO upon bss stop it is decremented + * + * \param pHddCtx - HDD Context + * \param mode - device mode + * + * \return - None + * + * --------------------------------------------------------------------------*/ +void wlan_hdd_decr_active_session(hdd_context_t *pHddCtx, tVOS_CON_MODE mode) +{ + + switch (mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + case VOS_P2P_GO_MODE: + case VOS_STA_SAP_MODE: + if (pHddCtx->no_of_active_sessions[mode] > 0) + pHddCtx->no_of_active_sessions[mode]--; + else + hddLog(VOS_TRACE_LEVEL_INFO, FL(" No.# of Active sessions" + "is already Zero")); + break; + default: + hddLog(VOS_TRACE_LEVEL_INFO, FL("Not Expected Mode %d"), mode); + break; + } + hddLog(VOS_TRACE_LEVEL_INFO, FL("No.# of active sessions for mode %d = %d"), + mode, + pHddCtx->no_of_active_sessions[mode]); +} + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_init + * + * This function initalizes restart timer/flag. An internal function. + * + * \param - pHddCtx + * + * \return - None + * + * --------------------------------------------------------------------------*/ + +static void wlan_hdd_restart_init(hdd_context_t *pHddCtx) +{ + /* Initialize */ + pHddCtx->hdd_restart_retries = 0; + atomic_set(&pHddCtx->isRestartInProgress, 0); + vos_timer_init(&pHddCtx->hdd_restart_timer, + VOS_TIMER_TYPE_SW, + wlan_hdd_restart_timer_cb, + pHddCtx); +} +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_deinit + * + * This function cleans up the resources used. An internal function. + * + * \param - pHddCtx + * + * \return - None + * + * --------------------------------------------------------------------------*/ + +static void wlan_hdd_restart_deinit(hdd_context_t* pHddCtx) +{ + + VOS_STATUS vos_status; + /* Block any further calls */ + atomic_set(&pHddCtx->isRestartInProgress, 1); + /* Cleanup */ + vos_status = vos_timer_stop( &pHddCtx->hdd_restart_timer ); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to stop HDD restart timer")); + vos_status = vos_timer_destroy(&pHddCtx->hdd_restart_timer); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + hddLog(LOGE, FL("Failed to destroy HDD restart timer")); + +} + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_framework_restart + * + * This function uses a cfg80211 API to start a framework initiated WLAN + * driver module unload/load. + * + * Also this API keep retrying (WLAN_HDD_RESTART_RETRY_MAX_CNT). + * + * + * \param - pHddCtx + * + * \return - VOS_STATUS_SUCCESS: Success + * VOS_STATUS_E_EMPTY: Adapter is Empty + * VOS_STATUS_E_NOMEM: No memory + + * --------------------------------------------------------------------------*/ + +static VOS_STATUS wlan_hdd_framework_restart(hdd_context_t *pHddCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + int len = (sizeof (struct ieee80211_mgmt)); + struct ieee80211_mgmt *mgmt = NULL; + + /* Prepare the DEAUTH managment frame with reason code */ + mgmt = kzalloc(len, GFP_KERNEL); + if(mgmt == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: memory allocation failed (%d bytes)", __func__, len); + return VOS_STATUS_E_NOMEM; + } + mgmt->u.deauth.reason_code = WLAN_REASON_DISASSOC_LOW_ACK; + + /* Iterate over all adapters/devices */ + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + if ((NULL == pAdapterNode) || (VOS_STATUS_SUCCESS != status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("fail to get adapter: %p %d"), pAdapterNode, status); + goto end; + } + + do + { + if(pAdapterNode->pAdapter && + WLAN_HDD_ADAPTER_MAGIC == pAdapterNode->pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "restarting the driver(intf:\'%s\' mode:%d :try %d)", + pAdapterNode->pAdapter->dev->name, + pAdapterNode->pAdapter->device_mode, + pHddCtx->hdd_restart_retries + 1); + /* + * CFG80211 event to restart the driver + * + * 'cfg80211_send_unprot_deauth' sends a + * NL80211_CMD_UNPROT_DEAUTHENTICATE event to supplicant at any state + * of SME(Linux Kernel) state machine. + * + * Reason code WLAN_REASON_DISASSOC_LOW_ACK is currently used to restart + * the driver. + * + */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + cfg80211_rx_unprot_mlme_mgmt(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len); +#else + cfg80211_send_unprot_deauth(pAdapterNode->pAdapter->dev, (u_int8_t*)mgmt, len ); +#endif + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } while((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status)); + + end: + /* Free the allocated management frame */ + kfree(mgmt); + + /* Retry until we unload or reach max count */ + if(++pHddCtx->hdd_restart_retries < WLAN_HDD_RESTART_RETRY_MAX_CNT) + vos_timer_start(&pHddCtx->hdd_restart_timer, WLAN_HDD_RESTART_RETRY_DELAY_MS); + + return status; + +} +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_timer_cb + * + * Restart timer callback. An internal function. + * + * \param - User data: + * + * \return - None + * + * --------------------------------------------------------------------------*/ + +void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback) +{ + hdd_context_t *pHddCtx = usrDataForCallback; + wlan_hdd_framework_restart(pHddCtx); + return; + +} + + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_restart_driver + * + * This function sends an event to supplicant to restart the WLAN driver. + * + * This function is called from vos_wlanRestart. + * + * \param - pHddCtx + * + * \return - VOS_STATUS_SUCCESS: Success + * VOS_STATUS_E_EMPTY: Adapter is Empty + * VOS_STATUS_E_ALREADY: Request already in progress + + * --------------------------------------------------------------------------*/ +VOS_STATUS wlan_hdd_restart_driver(hdd_context_t *pHddCtx) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + /* A tight check to make sure reentrancy */ + if(atomic_xchg(&pHddCtx->isRestartInProgress, 1)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLAN restart is already in progress", __func__); + + return VOS_STATUS_E_ALREADY; + } + /* Send reset FIQ to WCNSS to invoke SSR. */ +#ifdef HAVE_WCNSS_RESET_INTR + wcnss_reset_fiq(TRUE); +#endif + + return status; +} + +/** + * hdd_get_total_sessions() - provide total number of active sessions + * @pHddCtx: Valid Global HDD context pointer + * + * This function iterates through pAdaptors and find the number of all active + * sessions. This active sessions includes connected sta, p2p client and number + * of client connected to sap/p2p go. + * + * Return: Total number of active sessions. + */ +v_U8_t hdd_get_total_sessions(hdd_context_t *pHddCtx) +{ + v_U8_t active_session = 0; + hdd_station_ctx_t *pHddStaCtx; + hdd_adapter_list_node_t *pAdapterNode, *pNext; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapter = pAdapterNode->pAdapter; + switch (pAdapter->device_mode) { + case VOS_STA_MODE: + case VOS_P2P_CLIENT_MODE: + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState) + active_session += 1; + break; + case VOS_STA_SAP_MODE: + case VOS_P2P_GO_MODE: + active_session += hdd_softap_get_connected_sta(pAdapter); + break; + default: + break; + } + + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + return active_session; +} + +/** + * hdd_set_delack_value() - Set delack value + * @pHddCtx: Valid Global HDD context pointer + * @next_rx_level: Value to set for delack + * + * This function compare present value and next value of delack. If the both + * are diffrent then it sets next value . + * + * Return: void. + */ +void hdd_set_delack_value(hdd_context_t *pHddCtx, v_U32_t next_rx_level) +{ + if (pHddCtx->cur_rx_level != next_rx_level) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: TCP DELACK trigger level %d", + __func__, next_rx_level); + mutex_lock(&pHddCtx->cur_rx_level_lock); + pHddCtx->cur_rx_level = next_rx_level; + mutex_unlock(&pHddCtx->cur_rx_level_lock); + wlan_hdd_send_svc_nlink_msg(WLAN_SVC_WLAN_TP_IND, &next_rx_level, + sizeof(next_rx_level)); + } +} + +/** + * hdd_set_default_stop_delack_timer() - Start delack timer + * @pHddCtx: Valid Global HDD context pointer + * + * This function stop delack timer and set delack value to default.. + * + * Return: void. + */ + +void hdd_set_default_stop_delack_timer(hdd_context_t *pHddCtx) +{ + if (VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->delack_timer)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: Can not stop timer", __func__); + return; + } + + vos_timer_stop(&pHddCtx->delack_timer); + hdd_set_delack_value(pHddCtx, TP_IND_LOW); +} + +/** + * hdd_start_delack_timer() - Start delack timer + * @pHddCtx: Valid Global HDD context pointer + * + * This function starts the delack timer for tcpDelAckComputeInterval time + * interval.The default timer value is 2 second. + * + * Return: void. + */ +void hdd_start_delack_timer(hdd_context_t *pHddCtx) +{ + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->delack_timer)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: Timer is already running", __func__); + return; + } + + vos_timer_start(&pHddCtx->delack_timer, + pHddCtx->cfg_ini->tcpDelAckComputeInterval); +} + +/** + * hdd_update_prev_rx_packet_count() - Update previous rx packet count + * @pHddCtx: Valid Global HDD context pointer + * + * This function updates the prev_rx_packets count from the corresponding + * pAdapter states. This prev_rx_packets will diffed with the packet count + * at the end of delack timer. That can give number of RX packet is spacific + * time. + * + * Return: void. + */ +void hdd_update_prev_rx_packet_count(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode, *pNext; + hdd_adapter_t *pAdapter; + VOS_STATUS status; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) { + pAdapter = pAdapterNode->pAdapter; + pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } +} + +/** + * hdd_manage_delack_timer() - start\stop delack timer + * @pHddCtx: Valid Global HDD context pointer + * + * This function check the number of concerent session present, it starts the + * delack timer if only one session is present. + * In the case of BT_COEX and TDLS mode it blindly stop delack functionality. + * + * Return: void. + */ +void hdd_manage_delack_timer(hdd_context_t *pHddCtx) +{ + uint8_t sessions; + + if (!pHddCtx->cfg_ini->enable_delack) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: TCP DELACK is not enabled", __func__); + return; + } + + /* Blindly stop timer of BTCOEX and TDLS Session is up */ + if (pHddCtx->mode != 0) { + hdd_set_default_stop_delack_timer(pHddCtx); + return; + } + + sessions = hdd_get_total_sessions(pHddCtx); + if (sessions == 1) { + hdd_update_prev_rx_packet_count(pHddCtx); + hdd_start_delack_timer(pHddCtx); + } else { + hdd_set_default_stop_delack_timer(pHddCtx); + } +} + +/**--------------------------------------------------------------------------- + * + * \brief wlan_hdd_init_channels + * + * This function is used to initialize the channel list in CSR + * + * This function is called from hdd_wlan_startup + * + * \param - pHddCtx: HDD context + * + * \return - VOS_STATUS_SUCCESS: Success + * VOS_STATUS_E_FAULT: Failure reported by SME + + * --------------------------------------------------------------------------*/ +static VOS_STATUS wlan_hdd_init_channels(hdd_context_t *pHddCtx) +{ + eHalStatus status; + + status = sme_InitChannels(pHddCtx->hHal); + if (HAL_STATUS_SUCCESS(status)) + { + return VOS_STATUS_SUCCESS; + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Channel initialization failed(%d)", + __func__, status); + return VOS_STATUS_E_FAULT; + } +} + +#ifdef CONFIG_ENABLE_LINUX_REG +VOS_STATUS wlan_hdd_init_channels_for_cc(hdd_context_t *pHddCtx, driver_load_type init ) +{ + eHalStatus status; + + status = sme_InitChannelsForCC(pHddCtx->hHal, init); + if (HAL_STATUS_SUCCESS(status)) + { + return VOS_STATUS_SUCCESS; + } + else + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Issue reg hint failed(%d)", + __func__, status); + return VOS_STATUS_E_FAULT; + } +} +#endif +/* + * API to find if there is any STA or P2P-Client is connected + */ +VOS_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *pHddCtx) +{ + return sme_isSta_p2p_clientConnected(pHddCtx->hHal); +} + + +/* + * API to find if the firmware will send logs using DXE channel + */ +v_U8_t hdd_is_fw_logging_enabled(void) +{ + hdd_context_t *pHddCtx; + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, + vos_get_global_context(VOS_MODULE_ID_HDD, NULL)); + + return (pHddCtx && pHddCtx->cfg_ini->enableMgmtLogging); +} + +/* + * API to find if the firmware will send trace logs using DXE channel + */ +v_U8_t hdd_is_fw_ev_logging_enabled(void) +{ + hdd_context_t *pHddCtx; + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, + vos_get_global_context(VOS_MODULE_ID_HDD, NULL)); + + return (pHddCtx && pHddCtx->cfg_ini->enableFWLogging); +} +/* + * API to find if there is any session connected + */ +VOS_STATUS hdd_is_any_session_connected(hdd_context_t *pHddCtx) +{ + return sme_is_any_session_connected(pHddCtx->hHal); +} + + +int wlan_hdd_scan_abort(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_scaninfo_t *pScanInfo = NULL; + long status = 0; + tSirAbortScanStatus abortScanStatus; + + pScanInfo = &pHddCtx->scan_info; + INIT_COMPLETION(pScanInfo->abortscan_event_var); + if (pScanInfo->mScanPending) + { + abortScanStatus = hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("abortScanStatus: %d"), abortScanStatus); + + /* If there is active scan command lets wait for the completion else + * there is no need to wait as scan command might be in the SME pending + * command list. + */ + if (abortScanStatus == eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY) + { + status = wait_for_completion_timeout( + &pScanInfo->abortscan_event_var, + msecs_to_jiffies(5000)); + if (0 >= status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout or Interrupt occurred while waiting for abort" + "scan, status- %ld", __func__, status); + return -ETIMEDOUT; + } + } + else if (abortScanStatus == eSIR_ABORT_SCAN_FAILURE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("hdd_abort_mac_scan failed")); + return -VOS_STATUS_E_FAILURE; + } + } + return 0; +} + +/** + * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to + * user space + * @frame_ind: Management frame data to be informed. + * + * This function is used to indicate management frame to + * user space + * + * Return: None + * + */ +void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) +{ + hdd_context_t *hdd_ctx = NULL; + hdd_adapter_t *adapter = NULL; + v_CONTEXT_t vos_context = NULL; + + /* Get the global VOSS context.*/ + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_context) { + hddLog(LOGE, FL("Global VOS context is Null")); + return; + } + /* Get the HDD context.*/ + hdd_ctx = + (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context ); + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + { + return; + } + adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, + frame_ind->sessionId); + + if ((NULL != adapter) && + (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) + __hdd_indicate_mgmt_frame(adapter, + frame_ind->frameLen, + frame_ind->frameBuf, + frame_ind->frameType, + frame_ind->rxChan, + frame_ind->rxRssi); + return; + +} + +VOS_STATUS wlan_hdd_cancel_remain_on_channel(hdd_context_t *pHddCtx) +{ + hdd_adapter_t *pAdapter; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS vosStatus; + + vosStatus = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus) + { + pAdapter = pAdapterNode->pAdapter; + if (NULL != pAdapter) + { + if (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode || + WLAN_HDD_P2P_CLIENT == pAdapter->device_mode || + WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + hddLog(LOG1, FL("abort ROC deviceMode: %d"), + pAdapter->device_mode); + if (VOS_STATUS_SUCCESS != + wlan_hdd_cancel_existing_remain_on_channel(pAdapter)) + { + hddLog(LOGE, FL("failed to abort ROC")); + return VOS_STATUS_E_FAILURE; + } + } + } + vosStatus = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return VOS_STATUS_SUCCESS; +} + +hdd_remain_on_chan_ctx_t *hdd_get_remain_on_channel_ctx(hdd_context_t *pHddCtx) +{ + hdd_adapter_t *pAdapter; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_cfg80211_state_t *cfgState; + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + VOS_STATUS vosStatus; + + vosStatus = hdd_get_front_adapter (pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_E_EMPTY != vosStatus) + { + pAdapter = pAdapterNode->pAdapter; + if (NULL != pAdapter) + { + cfgState = WLAN_HDD_GET_CFG_STATE_PTR(pAdapter); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx) + break; + } + vosStatus = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + return pRemainChanCtx; +} + +/** + * wlan_hdd_handle_dfs_chan_scan () - handles disable/enable DFS channels + * + * @pHddCtx: HDD context within host driver + * @dfsScanMode: dfsScanMode passed from ioctl + * + */ + +VOS_STATUS wlan_hdd_handle_dfs_chan_scan(hdd_context_t *pHddCtx, + tANI_U8 dfsScanMode) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + VOS_STATUS vosStatus; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(!pHddCtx) + { + hddLog(LOGE, FL("HDD context is Null")); + return eHAL_STATUS_FAILURE; + } + + if (pHddCtx->scan_info.mScanPending) + { + hddLog(LOG1, FL("Aborting scan for sessionId: %d"), + pHddCtx->scan_info.sessionId); + hdd_abort_mac_scan(pHddCtx, + pHddCtx->scan_info.sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + + if (!dfsScanMode) + { + vosStatus = hdd_get_front_adapter( pHddCtx, &pAdapterNode); + while ((NULL != pAdapterNode) && + (VOS_STATUS_SUCCESS == vosStatus)) + { + pAdapter = pAdapterNode->pAdapter; + + if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if(!pHddStaCtx) + { + hddLog(LOGE, FL("HDD STA context is Null")); + return eHAL_STATUS_FAILURE; + } + + /* if STA is already connected on DFS channel, + disconnect immediately*/ + if (hdd_connIsConnected(pHddStaCtx) && + (NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState( + pHddStaCtx->conn_info.operationChannel))) + { + status = sme_RoamDisconnect(pHddCtx->hHal, + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + hddLog(LOG1, FL("Client connected on DFS channel %d," + "sme_RoamDisconnect returned with status: %d" + "for sessionid: %d"), pHddStaCtx->conn_info. + operationChannel, status, pAdapter->sessionId); + } + } + + vosStatus = hdd_get_next_adapter(pHddCtx, pAdapterNode, + &pNext); + pAdapterNode = pNext; + } + } + + sme_UpdateDFSScanMode(pHddCtx->hHal, dfsScanMode); + sme_UpdateDFSRoamMode(pHddCtx->hHal, + (dfsScanMode != DFS_CHNL_SCAN_DISABLED)); + + status = sme_HandleDFSChanScan(pHddCtx->hHal); + if (!HAL_STATUS_SUCCESS(status)) + { + hddLog(LOGE, + FL("Failed in sme_HandleDFSChanScan (err=%d)"), status); + return status; + } + + return status; +} + +static int hdd_log2_ceil(unsigned value) +{ + /* need to switch to unsigned math so that negative values + * will right-shift towards 0 instead of -1 + */ + unsigned tmp = value; + int log2 = -1; + + if (value == 0) + return 0; + + while (tmp) { + log2++; + tmp >>= 1; + } + if (1U << log2 != value) + log2++; + + return log2; +} + +/** + * hdd_sta_id_hash_attach() - initialize sta id to macaddr hash + * @pAdapter: adapter handle + * + * Return: vos status + */ +VOS_STATUS hdd_sta_id_hash_attach(hdd_adapter_t *pAdapter) +{ + int hash_elem, log2, i; + + spin_lock_bh( &pAdapter->sta_hash_lock); + if (pAdapter->is_sta_id_hash_initialized == VOS_TRUE) { + spin_unlock_bh( &pAdapter->sta_hash_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hash already attached for session id %d", + __func__, pAdapter->sessionId); + return VOS_STATUS_SUCCESS; + } + spin_unlock_bh( &pAdapter->sta_hash_lock); + + hash_elem = WLAN_MAX_STA_COUNT; + hash_elem *= HDD_STA_ID_HASH_MULTIPLIER; + log2 = hdd_log2_ceil(hash_elem); + hash_elem = 1 << log2; + + pAdapter->sta_id_hash.mask = hash_elem - 1; + pAdapter->sta_id_hash.idx_bits = log2; + pAdapter->sta_id_hash.bins = + vos_mem_malloc(hash_elem *sizeof(hdd_list_t)); + if (!pAdapter->sta_id_hash.bins) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: malloc failed for session %d", + __func__, pAdapter->sessionId); + return VOS_STATUS_E_NOMEM; + } + + for (i = 0; i < hash_elem; i++) + hdd_list_init(&pAdapter->sta_id_hash.bins[i], WLAN_MAX_STA_COUNT); + + spin_lock_bh( &pAdapter->sta_hash_lock); + pAdapter->is_sta_id_hash_initialized = VOS_TRUE; + spin_unlock_bh( &pAdapter->sta_hash_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Station ID Hash attached for session id %d", + __func__, pAdapter->sessionId); + + return VOS_STATUS_SUCCESS; +} + +/** + * hdd_sta_id_hash_detach() - deinit sta_id to macaddr hash + * @pAdapter: adapter handle + * + * Return: vos status + */ +VOS_STATUS hdd_sta_id_hash_detach(hdd_adapter_t *pAdapter) +{ + int hash_elem, i; + v_SIZE_t size; + + spin_lock_bh( &pAdapter->sta_hash_lock); + if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) { + spin_unlock_bh( &pAdapter->sta_hash_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: hash not initialized for session id %d", + __func__, pAdapter->sessionId); + return VOS_STATUS_SUCCESS; + } + + pAdapter->is_sta_id_hash_initialized = VOS_FALSE; + spin_unlock_bh( &pAdapter->sta_hash_lock); + + hash_elem = 1 << pAdapter->sta_id_hash.idx_bits; + + /* free all station info*/ + for (i = 0; i < hash_elem; i++) { + hdd_list_size(&pAdapter->sta_id_hash.bins[i], &size); + if (size != 0) { + VOS_STATUS status; + hdd_staid_hash_node_t *sta_info_node = NULL; + hdd_staid_hash_node_t *next_node = NULL; + status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[i], + (hdd_list_node_t**) &sta_info_node ); + + while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status ) + { + status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[i], + &sta_info_node->node); + vos_mem_free(sta_info_node); + + status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[i], + (hdd_list_node_t*)sta_info_node, + (hdd_list_node_t**)&next_node); + sta_info_node = next_node; + } + } + } + + vos_mem_free(pAdapter->sta_id_hash.bins); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Station ID Hash detached for session id %d", + __func__, pAdapter->sessionId); + return VOS_STATUS_SUCCESS; +} + +/** + * hdd_sta_id_hash_calculate_index() - derive index from macaddr + * @pAdapter: adapter handle + * @mac_addr_in: input mac address + * + * Return: index derived from mac address + */ +int hdd_sta_id_hash_calculate_index(hdd_adapter_t *pAdapter, + v_MACADDR_t *mac_addr_in) +{ + uint16 index; + struct hdd_align_mac_addr_t * mac_addr = + (struct hdd_align_mac_addr_t *)mac_addr_in; + + index = mac_addr->bytes_ab ^ + mac_addr->bytes_cd ^ mac_addr->bytes_ef; + index ^= index >> pAdapter->sta_id_hash.idx_bits; + index &= pAdapter->sta_id_hash.mask; + return index; +} + +/** + * hdd_sta_id_hash_add_entry() - add entry in hash + * @pAdapter: adapter handle + * @sta_id: station id + * @mac_addr: mac address + * + * Return: vos status + */ +VOS_STATUS hdd_sta_id_hash_add_entry(hdd_adapter_t *pAdapter, + v_U8_t sta_id, v_MACADDR_t *mac_addr) +{ + uint16 index; + hdd_staid_hash_node_t *sta_info_node = NULL; + + index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr); + sta_info_node = vos_mem_malloc(sizeof(hdd_staid_hash_node_t)); + if (!sta_info_node) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: malloc failed", __func__); + return VOS_STATUS_E_NOMEM; + } + + sta_info_node->sta_id = sta_id; + vos_mem_copy(&sta_info_node->mac_addr, mac_addr, sizeof(v_MACADDR_t)); + + spin_lock_bh( &pAdapter->sta_hash_lock); + if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) { + spin_unlock_bh( &pAdapter->sta_hash_lock); + vos_mem_free(sta_info_node); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: hash is not initialized for session id %d", + __func__, pAdapter->sessionId); + return VOS_STATUS_E_FAILURE; + } + + hdd_list_insert_back ( &pAdapter->sta_id_hash.bins[index], + (hdd_list_node_t*) sta_info_node ); + spin_unlock_bh( &pAdapter->sta_hash_lock); + return VOS_STATUS_SUCCESS; +} + +/** + * hdd_sta_id_hash_remove_entry() - remove entry from hash + * @pAdapter: adapter handle + * @sta_id: station id + * @mac_addr: mac address + * + * Return: vos status + */ +VOS_STATUS hdd_sta_id_hash_remove_entry(hdd_adapter_t *pAdapter, + v_U8_t sta_id, v_MACADDR_t *mac_addr) +{ + uint16 index; + VOS_STATUS status; + hdd_staid_hash_node_t *sta_info_node = NULL; + hdd_staid_hash_node_t *next_node = NULL; + + spin_lock_bh( &pAdapter->sta_hash_lock); + if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) { + spin_unlock_bh( &pAdapter->sta_hash_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hash is not initialized for session id %d", + __func__, pAdapter->sessionId); + return VOS_STATUS_E_FAILURE; + } + + index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr); + status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index], + (hdd_list_node_t**) &sta_info_node ); + + while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status ) + { + if (sta_info_node->sta_id == sta_id) { + status = hdd_list_remove_node( &pAdapter->sta_id_hash.bins[index], + &sta_info_node->node); + vos_mem_free(sta_info_node); + break; + } + status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index], + (hdd_list_node_t*)sta_info_node, (hdd_list_node_t**)&next_node); + sta_info_node = next_node; + } + spin_unlock_bh( &pAdapter->sta_hash_lock); + return status; +} + +/** + * hdd_sta_id_find_from_mac_addr() - find sta id from mac address + * @pAdapter: adapter handle + * @mac_addr_in: mac address + * + * Return: station id + */ +int hdd_sta_id_find_from_mac_addr(hdd_adapter_t *pAdapter, + v_MACADDR_t *mac_addr_in) +{ + uint8 is_found = 0; + uint8 sta_id = HDD_WLAN_INVALID_STA_ID; + uint16 index; + VOS_STATUS status; + hdd_staid_hash_node_t *sta_info_node = NULL; + hdd_staid_hash_node_t *next_node = NULL; + + spin_lock_bh( &pAdapter->sta_hash_lock); + if (pAdapter->is_sta_id_hash_initialized != VOS_TRUE) { + spin_unlock_bh( &pAdapter->sta_hash_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + FL("hash is not initialized for session id %d"), + pAdapter->sessionId); + return HDD_WLAN_INVALID_STA_ID; + } + + index = hdd_sta_id_hash_calculate_index(pAdapter, mac_addr_in); + status = hdd_list_peek_front ( &pAdapter->sta_id_hash.bins[index], + (hdd_list_node_t**) &sta_info_node ); + + while ( NULL != sta_info_node && VOS_STATUS_SUCCESS == status ) + { + if (vos_mem_compare(&sta_info_node->mac_addr, + mac_addr_in, sizeof(v_MACADDR_t))) { + is_found = 1; + sta_id = sta_info_node->sta_id; + break; + } + status = hdd_list_peek_next (&pAdapter->sta_id_hash.bins[index], + (hdd_list_node_t*)sta_info_node, + (hdd_list_node_t**)&next_node); + sta_info_node = next_node; + } + spin_unlock_bh( &pAdapter->sta_hash_lock); + return sta_id; +} + +/*FW memory dump feature*/ +/** + * This structure hold information about the /proc file + * + */ +static struct proc_dir_entry *proc_file, *proc_dir; + +/** + * memdump_read() - perform read operation in memory dump proc file + * + * @file - handle for the proc file. + * @buf - pointer to user space buffer. + * @count - number of bytes to be read. + * @pos - offset in the from buffer. + * + * This function performs read operation for the memory dump proc file. + * + * Return: number of bytes read on success, error code otherwise. + */ +static ssize_t memdump_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + int status; + hdd_context_t *hdd_ctx = (hdd_context_t *)PDE_DATA(file_inode(file)); + size_t ret_count; + loff_t bytes_left; + ENTER(); + + hddLog(LOG1, FL("Read req for size:%zu pos:%llu"), count, *pos); + status = wlan_hdd_validate_context(hdd_ctx); + if (0 != status) { + return -EINVAL; + } + + if (!wlan_fwr_mem_dump_test_and_set_read_allowed_bit()) { + hddLog(LOGE, FL("Current mem dump request timed out/failed")); + return -EINVAL; + } + + /* run fs_read_handler in an atomic context*/ + vos_ssr_protect(__func__); + ret_count = wlan_fwr_mem_dump_fsread_handler( buf, count, pos, &bytes_left); + if(bytes_left == 0) + { + /*Free the fwr mem dump buffer */ + wlan_free_fwr_mem_dump_buffer(); + wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE); + ret_count=0; + } + /*if SSR/unload code is waiting for memdump_read to finish,signal it*/ + vos_ssr_unprotect(__func__); + EXIT(); + return ret_count; +} + +/** + * struct memdump_fops - file operations for memory dump feature + * @read - read function for memory dump operation. + * + * This structure initialize the file operation handle for memory + * dump feature + */ +static const struct file_operations memdump_fops = { + read: memdump_read +}; + +/* +* wlan_hdd_fw_mem_dump_cb : callback for Fw mem dump request +* To be passed by HDD to WDA and called upon receiving of response +* from firmware +* @fwMemDumpReqContext : memory dump request context +* @dump_rsp : dump response from HAL +* Returns none +*/ +void wlan_hdd_fw_mem_dump_cb(void *fwMemDumpReqContext, + tAniFwrDumpRsp *dump_rsp) +{ + struct hdd_fw_mem_dump_req_ctx *pHddFwMemDumpCtx = (struct hdd_fw_mem_dump_req_ctx *)fwMemDumpReqContext; + + ENTER(); + spin_lock(&hdd_context_lock); + if(!pHddFwMemDumpCtx || (FW_MEM_DUMP_MAGIC != pHddFwMemDumpCtx->magic)) { + spin_unlock(&hdd_context_lock); + return; + } + /* report the status to requesting function and free mem.*/ + if (dump_rsp->dump_status != eHAL_STATUS_SUCCESS) { + hddLog(LOGE, FL("fw dump request declined by fwr")); + //set the request completion variable + complete(&(pHddFwMemDumpCtx->req_completion)); + //Free the allocated fwr dump + wlan_free_fwr_mem_dump_buffer(); + wlan_set_fwr_mem_dump_state(FW_MEM_DUMP_IDLE); + } + else { + hddLog(LOG1, FL("fw dump request accepted by fwr")); + /* register the HDD callback which will be called by SVC */ + wlan_set_svc_fw_mem_dump_req_cb((void*)wlan_hdd_fw_mem_dump_req_cb,(void*)pHddFwMemDumpCtx); + } + spin_unlock(&hdd_context_lock); + EXIT(); + +} + +/** + * memdump_procfs_remove() - Remove file/dir under procfs for memory dump + * + * This function removes file/dir under proc file system that was + * processing firmware memory dump + * + * Return: None + */ +static void memdump_procfs_remove(void) +{ + remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir); + hddLog(LOG1 , FL("/proc/%s/%s removed\n"), + PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME); + remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL); + hddLog(LOG1 , FL("/proc/%s removed\n"), PROCFS_MEMDUMP_DIR); +} + +/** + * memdump_procfs_init() - Initialize procfs for memory dump + * + * @vos_ctx - Global vos context. + * + * This function create file under proc file system to be used later for + * processing firmware memory dump + * + * Return: 0 on success, error code otherwise. + */ +static int memdump_procfs_init(void *vos_ctx) +{ + hdd_context_t *hdd_ctx; + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + if (!hdd_ctx) { + hddLog(LOGE , FL("Invalid HDD context")); + return -EINVAL; + } + + proc_dir = proc_mkdir(PROCFS_MEMDUMP_DIR, NULL); + if (proc_dir == NULL) { + remove_proc_entry(PROCFS_MEMDUMP_DIR, NULL); + hddLog(LOGE , FL("Error: Could not initialize /proc/%s"), + PROCFS_MEMDUMP_DIR); + return -ENOMEM; + } + + proc_file = proc_create_data(PROCFS_MEMDUMP_NAME, + S_IRUSR | S_IWUSR, proc_dir, + &memdump_fops, hdd_ctx); + if (proc_file == NULL) { + remove_proc_entry(PROCFS_MEMDUMP_NAME, proc_dir); + hddLog(LOGE , FL("Error: Could not initialize /proc/%s"), + PROCFS_MEMDUMP_NAME); + return -ENOMEM; + } + + hddLog(LOG1 , FL("/proc/%s/%s created"), + PROCFS_MEMDUMP_DIR, PROCFS_MEMDUMP_NAME); + + return 0; +} + +/** + * memdump_init() - Initialization function for memory dump feature + * + * This function creates proc file for memdump feature and registers + * HDD callback function with SME. + * + * Return - 0 on success, error otherwise + */ +int memdump_init(void) +{ + hdd_context_t *hdd_ctx; + void *vos_ctx; + int status = 0; + + vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_ctx) { + hddLog(LOGE, FL("Invalid VOS context")); + return -EINVAL; + } + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + if (!hdd_ctx) { + hddLog(LOGE , FL("Invalid HDD context")); + return -EINVAL; + } + + status = memdump_procfs_init(vos_ctx); + if (status) { + hddLog(LOGE , FL("Failed to create proc file")); + return status; + } + + return 0; +} + +/** + * memdump_deinit() - De initialize memdump feature + * + * This function removes proc file created for memdump feature. + * + * Return: None + */ +int memdump_deinit(void) +{ + hdd_context_t *hdd_ctx; + void *vos_ctx; + + vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_ctx) { + hddLog(LOGE, FL("Invalid VOS context")); + return -EINVAL; + } + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + if(!hdd_ctx) { + hddLog(LOGE , FL("Invalid HDD context")); + return -EINVAL; + } + + memdump_procfs_remove(); + return 0; +} + +/** + * wlan_hdd_fw_mem_dump_req(pHddCtx) - common API(cfg80211/ioctl) for requesting fw mem dump to SME + * Return: HAL status + */ + +int wlan_hdd_fw_mem_dump_req(hdd_context_t * pHddCtx) +{ + tAniFwrDumpReq fw_mem_dump_req={0}; + struct hdd_fw_mem_dump_req_ctx fw_mem_dump_ctx; + eHalStatus status = eHAL_STATUS_FAILURE; + int ret=0, result; + ENTER(); + + /*Check whether a dump request is already going on + *Caution this function will free previously held memory if new dump request is allowed*/ + if (!wlan_fwr_mem_dump_test_and_set_write_allowed_bit()) { + hddLog(LOGE, FL("Fw memdump already in progress")); + return -EBUSY; + } + //Allocate memory for fw mem dump buffer + ret = wlan_fwr_mem_dump_buffer_allocation(); + if(ret == -EFAULT) + { + hddLog(LOGE, FL("Fwr mem dump not supported by FW")); + return ret; + } + if (0 != ret) { + hddLog(LOGE, FL("Fwr mem Allocation failed")); + return -ENOMEM; + } + init_completion(&fw_mem_dump_ctx.req_completion); + fw_mem_dump_ctx.magic = FW_MEM_DUMP_MAGIC; + fw_mem_dump_ctx.status = false; + + fw_mem_dump_req.fwMemDumpReqCallback = wlan_hdd_fw_mem_dump_cb; + fw_mem_dump_req.fwMemDumpReqContext = &fw_mem_dump_ctx; + status = sme_FwMemDumpReq(pHddCtx->hHal, &fw_mem_dump_req); + if(eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: fw_mem_dump_req failed ", __func__); + wlan_free_fwr_mem_dump_buffer(); + ret = -EFAULT; + goto cleanup; + } + /*wait for fw mem dump completion to send event to userspace*/ + result = + wait_for_completion_timeout(&fw_mem_dump_ctx.req_completion, + msecs_to_jiffies(FW_MEM_DUMP_TIMEOUT_MS)); + if (0 >= result ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: fw_mem_dump_req timeout %d ", __func__,result); + ret = -ETIMEDOUT; + } +cleanup: + spin_lock(&hdd_context_lock); + fw_mem_dump_ctx.magic = 0; + if(!ret && !fw_mem_dump_ctx.status) + ret = -EFAULT; + spin_unlock(&hdd_context_lock); + + EXIT(); + return ret; +} + +/** + * HDD callback which will be called by SVC to indicate mem dump completion. + */ +void wlan_hdd_fw_mem_dump_req_cb(struct hdd_fw_mem_dump_req_ctx* pHddFwMemDumpCtx) +{ + if (!pHddFwMemDumpCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: HDD context not valid ", __func__); + return; + } + spin_lock(&hdd_context_lock); + /* check the req magic and set status */ + if (pHddFwMemDumpCtx->magic == FW_MEM_DUMP_MAGIC) + { + pHddFwMemDumpCtx->status = true; + //signal the completion + complete(&(pHddFwMemDumpCtx->req_completion)); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: fw mem dump request possible timeout ", __func__); + } + spin_unlock(&hdd_context_lock); +} + +void hdd_initialize_adapter_common(hdd_adapter_t *pAdapter) +{ + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: pAdapter is NULL ", __func__); + return; + } + init_completion(&pAdapter->session_open_comp_var); + init_completion(&pAdapter->session_close_comp_var); + init_completion(&pAdapter->disconnect_comp_var); + init_completion(&pAdapter->linkup_event_var); + init_completion(&pAdapter->cancel_rem_on_chan_var); + init_completion(&pAdapter->rem_on_chan_ready_event); + init_completion(&pAdapter->pno_comp_var); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + init_completion(&pAdapter->offchannel_tx_event); +#endif + init_completion(&pAdapter->tx_action_cnf_event); +#ifdef FEATURE_WLAN_TDLS + init_completion(&pAdapter->tdls_add_station_comp); + init_completion(&pAdapter->tdls_del_station_comp); + init_completion(&pAdapter->tdls_mgmt_comp); + init_completion(&pAdapter->tdls_link_establish_req_comp); +#endif + +#ifdef WLAN_FEATURE_RMC + init_completion(&pAdapter->ibss_peer_info_comp); +#endif /* WLAN_FEATURE_RMC */ + init_completion(&pAdapter->ula_complete); + init_completion(&pAdapter->change_country_code); + +#ifdef FEATURE_WLAN_BATCH_SCAN + init_completion(&pAdapter->hdd_set_batch_scan_req_var); + init_completion(&pAdapter->hdd_get_batch_scan_req_var); +#endif + init_completion(&pAdapter->wlan_suspend_comp_var); + + return; +} + +#ifdef MDNS_OFFLOAD + +/** + * hdd_mdns_enable_offload_done() - mdns enable offload response api + * @padapter: holds adapter + * @status: response status + * + * Return - None + */ +void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status) +{ + hdd_adapter_t* adapter = (hdd_adapter_t*) padapter; + + ENTER(); + + if (NULL == adapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: adapter is NULL",__func__); + return; + } + + adapter->mdns_status.mdns_enable_status = status; + vos_event_set(&adapter->mdns_status.vos_event); + return; +} + +/** + * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api + * @padapter: holds adapter + * @status: responce status + * + * Return - None + */ +void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status) +{ + hdd_adapter_t* adapter = (hdd_adapter_t*) padapter; + + ENTER(); + + if (NULL == adapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: adapter is NULL",__func__); + return; + } + + adapter->mdns_status.mdns_fqdn_status = status; + return; +} + +/** + * hdd_mdns_resp_offload_done() - mdns resp offload response api + * @padapter: holds adapter + * @status: responce status + * + * Return - None + */ +void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status) +{ + hdd_adapter_t* adapter = (hdd_adapter_t*) padapter; + + ENTER(); + + if (NULL == adapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: adapter is NULL",__func__); + return; + } + + adapter->mdns_status.mdns_resp_status = status; + return; +} + +/** + * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name + * @response: Pointer to a struct hdd_mdns_resp_info + * @resp_info: Pointer to a struct tSirMDNSResponseInfo + * + * This function will pack the whole domain name without compression. It will + * add the leading len for each field and add zero length octet to terminate + * the domain name. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response, + sir_mdns_resp_info resp_info) +{ + uint8_t num; + uint16_t idx; + uint8_t len = 0; + + if ((response == NULL) || (response->data == NULL) || + (response->offset == NULL)) { + hddLog(LOGE, FL("Either data or offset in response is NULL!")); + return FALSE; + } + + if ((resp_info == NULL) || + (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) { + hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN); + return FALSE; + } + + for (num = 0; num < response->num_entries; num++) { + response->offset[num] = + resp_info->resp_len + MDNS_HEADER_LEN; + idx = num * MAX_LEN_DOMAINNAME_FIELD; + len = strlen((char *)&response->data[idx]); + if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), + MAX_MDNS_RESP_LEN); + return FALSE; + } + resp_info->resp_data[resp_info->resp_len] = len; + resp_info->resp_len++; + vos_mem_copy(&resp_info->resp_data[resp_info->resp_len], + &response->data[idx], len); + resp_info->resp_len += len; + } + + /* The domain name terminates with the zero length octet */ + if (num == response->num_entries) { + if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), + MAX_MDNS_RESP_LEN); + return FALSE; + } + resp_info->resp_data[resp_info->resp_len] = 0; + resp_info->resp_len++; + } + + return TRUE; +} + +/** + * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data + * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo + * @resp_info: Pointer to a struct tSirMDNSResponseInfo + * + * Return: None + */ +static void wlan_hdd_mdns_format_response_u16(uint16_t value, + sir_mdns_resp_info resp_info) +{ + uint8_t val_u8; + + if ((resp_info == NULL) || (resp_info->resp_data == NULL)) + return; + val_u8 = (value & 0xff00) >> 8; + resp_info->resp_data[resp_info->resp_len++] = val_u8; + val_u8 = value & 0xff; + resp_info->resp_data[resp_info->resp_len++] = val_u8; +} + +/** + * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data + * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo + * @resp_info: Pointer to a struct tSirMDNSResponseInfo + * + * Return: None + */ +static void wlan_hdd_mdns_format_response_u32(uint32_t value, + sir_mdns_resp_info resp_info) +{ + uint8_t val_u8; + + if ((resp_info == NULL) || (resp_info->resp_data == NULL)) + return; + val_u8 = (value & 0xff000000) >> 24; + resp_info->resp_data[resp_info->resp_len++] = val_u8; + val_u8 = (value & 0xff0000) >> 16; + resp_info->resp_data[resp_info->resp_len++] = val_u8; + val_u8 = (value & 0xff00) >> 8; + resp_info->resp_data[resp_info->resp_len++] = val_u8; + val_u8 = value & 0xff; + resp_info->resp_data[resp_info->resp_len++] = val_u8; +} + +/** + * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response + * @resp_type: Response type for mDNS + * @resp_info: Pointer to a struct tSirMDNSResponseInfo + * + * This function will pack the response type, class and TTL (Time To Live). + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type, + sir_mdns_resp_info resp_info) +{ + uint16_t len; + + if (resp_info == NULL) { + hddLog(LOGE, FL("resp_info is NULL!")); + return FALSE; + } + + len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t)); + if (len >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN); + return FALSE; + } + + /* Fill Type, Class, TTL */ + wlan_hdd_mdns_format_response_u16(resp_type, resp_info); + wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info); + wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info); + + return TRUE; +} + +/** + * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response + * @resp_info: Pointer to a struct tSirMDNSResponseInfo + * @response_dst: The response which domain name is compressed. + * @response_src: The response which domain name is matched with response_dst. + * Its offset is used for data compression. + * @num_matched: The number of matched entries between response_dst and + * response_src + * + * This function will form the different fields of domain name in response_dst + * if any. Then use the offset of the matched domain name in response_src to + * compress the matched domain name. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *response_dst, + struct hdd_mdns_resp_info *response_src, + uint8_t num_matched) +{ + uint8_t num, num_diff; + uint16_t value, idx; + uint8_t len = 0; + + if ((response_src == NULL) || (response_dst == NULL) || + (resp_info == NULL)) { + hddLog(LOGE, FL("response info is NULL!")); + return FALSE; + } + + if (response_dst->num_entries < num_matched) { + hddLog(LOGE, FL("num_entries is less than num_matched!")); + return FALSE; + } + + if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN); + return FALSE; + } + + num_diff = response_dst->num_entries - num_matched; + if ((num_diff > 0) && (response_dst->data == NULL)) { + hddLog(LOGE, FL("response_dst->data is NULL!")); + return FALSE; + } + + /* + * Handle the unmatched string at the beginning + * Store the length of octets and the octets + */ + for (num = 0; num < num_diff; num++) { + response_dst->offset[num] = + resp_info->resp_len + MDNS_HEADER_LEN; + idx = num * MAX_LEN_DOMAINNAME_FIELD; + len = strlen((char *)&response_dst->data[idx]); + if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), + MAX_MDNS_RESP_LEN); + return FALSE; + } + resp_info->resp_data[resp_info->resp_len] = len; + resp_info->resp_len++; + vos_mem_copy(&resp_info->resp_data[resp_info->resp_len], + &response_dst->data[idx], len); + resp_info->resp_len += len; + } + /* + * Handle the matched string from the end + * Just keep the offset and mask the leading two bit + */ + if (response_src->num_entries >= num_matched) { + num_diff = response_src->num_entries - num_matched; + value = response_src->offset[num_diff]; + if (value > 0) { + value |= 0xc000; + if ((resp_info->resp_len + sizeof(uint16_t)) >= + MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), + MAX_MDNS_RESP_LEN); + return FALSE; + } + wlan_hdd_mdns_format_response_u16(value, resp_info); + return TRUE; + } + } + return FALSE; +} + +/** + * wlan_hdd_mdns_reset_response() - Reset the response info + * @response: The response which info is reset. + * + * Return: None + */ +static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response) +{ + if (response == NULL) + return; + response->num_entries = 0; + response->data = NULL; + response->offset = NULL; +} + +/** + * wlan_hdd_mdns_init_response() - Initialize the response info + * @response: The response which info is initiatized. + * @resp_dname: The domain name string which might be tokenized. + * + * This function will allocate the memory for both response->data and + * response->offset. Besides, it will also tokenize the domain name to some + * entries and fill response->num_entries with the num of entries. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response, + uint8_t *resp_dname, char separator) +{ + uint16_t size; + + if ((resp_dname == NULL) || (response == NULL)) { + hddLog(LOGE, FL("resp_dname or response is NULL!")); + return FALSE; + } + + size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD; + response->data = vos_mem_malloc(size); + if (response->data) { + vos_mem_zero(response->data, size); + if (VOS_STATUS_SUCCESS != + hdd_string_to_string_array((char *)resp_dname, + response->data, + separator, + &response->num_entries, + MAX_NUM_FIELD_DOMAINNAME, + MAX_LEN_DOMAINNAME_FIELD)) { + hddLog(LOGE, FL("hdd_string_to_string_array fail!")); + goto err_init_resp; + } + + if ((response->num_entries > 0) && + (strlen((char *)&response->data[0]) > 0)) { + size = sizeof(uint16_t) * response->num_entries; + response->offset = vos_mem_malloc(size); + if (response->offset) { + vos_mem_zero(response->offset, size); + return TRUE; + } + } + } + +err_init_resp: + if (response->data) + vos_mem_free(response->data); + wlan_hdd_mdns_reset_response(response); + return FALSE; +} + +/** + * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries + * @response1: The response info is used to be compared. + * @response2: The response info is used to be compared. + * + * This function will find the matched entries from the end. + * + * Return: Return the number of the matched entries. + */ +static uint8_t +wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1, + struct hdd_mdns_resp_info *response2) +{ + uint8_t min, len1, i; + uint16_t num1, num2; + uint8_t num_matched = 0; + + min = VOS_MIN(response1->num_entries, response2->num_entries); + + for (i = 1; i <= min; i++) { + num1 = (response1->num_entries - i); + num1 *= MAX_LEN_DOMAINNAME_FIELD; + num2 = (response2->num_entries - i); + num2 *= MAX_LEN_DOMAINNAME_FIELD; + len1 = strlen((char *)&response1->data[num1]); + + if ((len1 == 0) || + (len1 != strlen((char *)&response2->data[num2]))) + break; + if (memcmp(&response1->data[num1], + &response2->data[num2], len1)) + break; + else + num_matched++; + } + + return num_matched; +} + +/** + * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries + * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched + * @numlist: The number of the elements in the array matchedlist. + * + * Find the max number of the matched entries among the array matchedlist. + * + * Return: None + */ +static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist, + uint8_t numlist) +{ + int j; + struct hdd_mdns_resp_matched tmp; + + /* At least two values are used for sorting */ + if ((numlist < 2) || (matchedlist == NULL)) { + hddLog(LOGE, FL("At least two values are used for sorting!")); + return; + } + + for (j = 0; j < numlist-1; j++) { + if (matchedlist[j].num_matched > + matchedlist[j+1].num_matched) { + vos_mem_copy(&tmp, &matchedlist[j], + sizeof(struct hdd_mdns_resp_matched)); + vos_mem_copy(&matchedlist[j], &matchedlist[j+1], + sizeof(struct hdd_mdns_resp_matched)); + vos_mem_copy(&matchedlist[j+1], &tmp, + sizeof(struct hdd_mdns_resp_matched)); + } + } +} + +/** + * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A + * + * Type A response include QName, response type, class, TTL and Ipv4. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *resptype_a) +{ + uint16_t value; + uint32_t len; + + ENTER(); + if ((ini_config == NULL) || (resp_info == NULL) || + (resptype_a == NULL)) { + hddLog(LOGE, FL("ini_config or response info is NULL!")); + return FALSE; + } + + /* No Type A response */ + if (strlen((char *)ini_config->mdns_resp_type_a) <= 0) + return TRUE; + + /* Wrong response is assigned, just ignore this response */ + if (!wlan_hdd_mdns_init_response(resptype_a, + ini_config->mdns_resp_type_a, '.')) + return TRUE; + + /* Process response domain name */ + if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_A); + return FALSE; + } + + /* Process response Type, Class, TTL */ + if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"), + MDNS_TYPE_A); + return FALSE; + } + + /* Process response RDLength, RData */ + len = sizeof(uint16_t) + sizeof(uint32_t); + len += resp_info->resp_len; + if (len >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN); + return FALSE; + } + value = sizeof(uint32_t); + wlan_hdd_mdns_format_response_u16(value, resp_info); + wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4, + resp_info); + + EXIT(); + return TRUE; +} + +/** + * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt + * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A + * + * Type Txt response include QName, response type, class, TTL and text content. + * Also, it will find the matched QName from resptype_A and compress the data. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *resptype_txt, + struct hdd_mdns_resp_info *resptype_a) +{ + uint8_t num_matched; + uint8_t num; + uint16_t idx; + uint16_t value = 0; + uint32_t len; + uint32_t total_len; + bool status; + struct hdd_mdns_resp_info resptype_content; + + ENTER(); + + if ((ini_config == NULL) || (resp_info == NULL) || + (resptype_txt == NULL)) { + hddLog(LOGE, FL("ini_config or response info is NULL!")); + return FALSE; + } + + /* No Type Txt response */ + if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0) + return TRUE; + + /* Wrong response is assigned, just ignore this response */ + if (!wlan_hdd_mdns_init_response(resptype_txt, + ini_config->mdns_resp_type_txt, '.')) + return TRUE; + + /* + * For data compression + * Check if any strings are matched with Type A response + */ + if (resptype_a && (resptype_a->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt, + resptype_a); + if (num_matched > 0) { + if (!wlan_hdd_mdns_compress_data(resp_info, + resptype_txt, resptype_a, num_matched)) { + hddLog(LOGE, FL("Fail to compress mDNS " + "response (%d)!"), MDNS_TYPE_TXT); + return FALSE; + } + } else { + /* + * num_matched is zero. Error! + * At least ".local" is needed. + */ + hddLog(LOGE, FL("No matched string! Fail to pack mDNS " + "response (%d)!"), MDNS_TYPE_TXT); + return FALSE; + } + } else { + /* no TypeA response, so show the whole data */ + if (!wlan_hdd_mdns_process_response_dname(resptype_txt, + resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_TXT); + return FALSE; + } + } + + /* Process response Type, Class, TTL */ + if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"), + MDNS_TYPE_TXT); + return FALSE; + } + + /* + * Process response RDLength, RData. + * TypeTxt RData include len. + */ + status = wlan_hdd_mdns_init_response(&resptype_content, + ini_config->mdns_resp_type_txt_content, + '/'); + if (status == FALSE) { + hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL")); + return FALSE; + } + + for (num = 0; num < resptype_content.num_entries; num++) { + idx = num * MAX_LEN_DOMAINNAME_FIELD; + value += strlen((char *)&resptype_content.data[idx]); + } + + /* content len is uint16_t */ + total_len = sizeof(uint16_t); + total_len += resp_info->resp_len + value + + resptype_content.num_entries; + + if (total_len >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN); + return FALSE; + } + wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries, + resp_info); + + for (num = 0; num < resptype_content.num_entries; num++) { + idx = num * MAX_LEN_DOMAINNAME_FIELD; + len = strlen((char *)&resptype_content.data[idx]); + resp_info->resp_data[resp_info->resp_len] = len; + resp_info->resp_len++; + + vos_mem_copy(&resp_info->resp_data[resp_info->resp_len], + &resptype_content.data[idx], len); + + resp_info->resp_len += len; + hddLog(LOG1, FL("index = %d, len = %d, str = %s"), + num, len, &resptype_content.data[idx]); + } + + EXIT(); + return TRUE; +} + +/** + * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * domain name + * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt + * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A + * + * The Type Ptr response include Type PTR domain name in its data field. + * Also, it will find the matched QName from the existing resptype_ptr, + * resptype_txt, resptype_a and then compress the data. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *resptype_ptr_dn, + struct hdd_mdns_resp_info *resptype_ptr, + struct hdd_mdns_resp_info *resptype_txt, + struct hdd_mdns_resp_info *resptype_a) +{ + uint8_t num_matched, numlist, size; + struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1]; + struct hdd_mdns_resp_info *resp; + + if ((ini_config == NULL) || (resp_info == NULL) || + (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) { + hddLog(LOGE, FL("ini_config or response info is NULL!")); + return FALSE; + } + + /* No Type Ptr domain name response */ + if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0) + return TRUE; + + /* Wrong response is assigned, just ignore this response */ + if (!wlan_hdd_mdns_init_response(resptype_ptr_dn, + ini_config->mdns_resp_type_ptr_dname, '.')) + return TRUE; + + /* + * For data compression + * Check if any strings are matched with previous + * response. + */ + numlist = 0; + size = (MAX_MDNS_RESP_TYPE-1); + size *= sizeof(struct hdd_mdns_resp_matched); + vos_mem_zero(matchedlist, size); + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn, + resptype_ptr); + if (num_matched > 0) { + matchedlist[numlist].num_matched = num_matched; + matchedlist[numlist].type = MDNS_TYPE_PTR; + numlist++; + } + if (resptype_txt && (resptype_txt->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_ptr_dn, resptype_txt); + if (num_matched > 0) { + matchedlist[numlist].num_matched = num_matched; + matchedlist[numlist].type = MDNS_TYPE_TXT; + numlist++; + } + } + if (resptype_a && (resptype_a->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_ptr_dn,resptype_a); + if (num_matched > 0) { + matchedlist[numlist].num_matched = num_matched; + matchedlist[numlist].type = MDNS_TYPE_A; + numlist++; + } + } + if (numlist > 0) { + if (numlist > 1) + wlan_hdd_mdns_find_max(matchedlist, numlist); + resp = NULL; + switch (matchedlist[numlist-1].type) { + case MDNS_TYPE_A: + resp = resptype_a; + break; + case MDNS_TYPE_TXT: + resp = resptype_txt; + break; + case MDNS_TYPE_PTR: + resp = resptype_ptr; + break; + default: + hddLog(LOGE, FL("Fail to compress mDNS response " + "(%d)!"), MDNS_TYPE_PTR_DNAME); + return FALSE; + } + num_matched = matchedlist[numlist-1].num_matched; + if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn, + resp, num_matched)) { + hddLog(LOGE, FL("Fail to compress mDNS response " + "(%d)!"), MDNS_TYPE_PTR_DNAME); + return FALSE; + } + } else { + /* num = 0 -> no matched string */ + if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn, + resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_PTR_DNAME); + return FALSE; + } + } + + return TRUE; +} + +/** + * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * domain name + * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt + * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A + * + * The Type Ptr response include QName, response type, class, TTL and + * Type PTR domain name. Also, it will find the matched QName from the + * existing resptype_txt, resptype_a and then compress the data. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *resptype_ptr, + struct hdd_mdns_resp_info *resptype_ptr_dn, + struct hdd_mdns_resp_info *resptype_txt, + struct hdd_mdns_resp_info *resptype_a) +{ + uint8_t num_matched, num_matched1; + uint16_t value; + uint8_t val_u8; + uint32_t offset_data_len, len; + + ENTER(); + if ((ini_config == NULL) || (resp_info == NULL) || + (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) { + hddLog(LOGE, FL("ini_config or response info is NULL!")); + return FALSE; + } + + /* No Type Ptr response */ + if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0) + return TRUE; + + /* Wrong response is assigned, just ignore this response */ + if (!wlan_hdd_mdns_init_response(resptype_ptr, + ini_config->mdns_resp_type_ptr, '.')) + return TRUE; + + /* + * For data compression + * Check if any strings are matched with Type A response + */ + num_matched = 0; + num_matched1 = 0; + if (resptype_a && (resptype_a->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr, + resptype_a); + } + if (resptype_txt && (resptype_txt->num_entries > 0)) { + num_matched1 = wlan_hdd_mdns_find_entries_from_end( + resptype_ptr, resptype_txt); + } + if ((num_matched != num_matched1) || + ((num_matched > 0) && (num_matched1 > 0))) { + if (num_matched >= num_matched1) { + if (!wlan_hdd_mdns_compress_data(resp_info, + resptype_ptr, resptype_a, num_matched)) { + hddLog(LOGE, FL("Fail to compress mDNS " + "response (%d)!"), MDNS_TYPE_PTR); + return FALSE; + } + } else { + /* num_matched is less than num_matched1 */ + if (!wlan_hdd_mdns_compress_data(resp_info, + resptype_ptr, resptype_txt, num_matched1)) { + hddLog(LOGE, FL("Fail to compress mDNS " + "response (%d)!"), MDNS_TYPE_PTR); + return FALSE; + } + } + } else { + /* + * Both num_matched and num_matched1 are zero. + * no TypeA & TypeTxt + */ + if (!wlan_hdd_mdns_process_response_dname(resptype_ptr, + resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_PTR); + return FALSE; + } + } + + /* Process response Type, Class, TTL */ + if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"), + MDNS_TYPE_PTR); + return FALSE; + } + + /* + * Process response RDLength, RData (Ptr domain name) + * Save the offset of RData length + */ + offset_data_len = resp_info->resp_len; + resp_info->resp_len += sizeof(uint16_t); + + if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info, + resptype_ptr_dn, resptype_ptr, + resptype_txt, resptype_a)) { + return FALSE; + } + /* Set the RData length */ + len = offset_data_len + sizeof(uint16_t); + if ((resptype_ptr_dn->num_entries > 0) && + (resp_info->resp_len > len)) { + value = resp_info->resp_len - len; + val_u8 = (value & 0xff00) >> 8; + resp_info->resp_data[offset_data_len] = val_u8; + val_u8 = value & 0xff; + resp_info->resp_data[offset_data_len+1] = val_u8; + } else { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_PTR); + return FALSE; + } + + EXIT(); + return TRUE; +} + +/** + * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv + * target + * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv + * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * domain name + * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt + * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A + * + * The Type service target is one of the data field in the Type SRV response. + * Also, it will find the matched QName from the existing resptype_srv, + * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress + * the data. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *resptype_srv_tgt, + struct hdd_mdns_resp_info *resptype_srv, + struct hdd_mdns_resp_info *resptype_ptr, + struct hdd_mdns_resp_info *resptype_ptr_dn, + struct hdd_mdns_resp_info *resptype_txt, + struct hdd_mdns_resp_info *resptype_a) +{ + uint8_t num_matched, num, size; + struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1]; + struct hdd_mdns_resp_info *resp; + + if ((ini_config == NULL) || (resp_info == NULL) || + (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) { + hddLog(LOGE, FL("ini_config or response info is NULL!")); + return FALSE; + } + + /* No Type Srv Target response */ + if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0) + return TRUE; + + /* Wrong response is assigned, just ignore this response */ + if (!wlan_hdd_mdns_init_response(resptype_srv_tgt, + ini_config->mdns_resp_type_srv_target, '.')) + return TRUE; + + /* + * For data compression + * Check if any strings are matched with previous response. + */ + num = 0; + size = (MAX_MDNS_RESP_TYPE-1); + size *= sizeof(struct hdd_mdns_resp_matched); + vos_mem_zero(matchedlist, size); + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt, + resptype_srv); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_SRV; + num++; + } + if (resptype_ptr && (resptype_ptr->num_entries > 0)) { + if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_srv_tgt, resptype_ptr_dn); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_PTR_DNAME; + num++; + } + } + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_srv_tgt, resptype_ptr); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_PTR; + num++; + } + } + if (resptype_txt && (resptype_txt->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_srv_tgt, resptype_txt); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_TXT; + num++; + } + } + if (resptype_a && (resptype_a->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_srv_tgt, resptype_a); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_A; + num++; + } + } + if (num > 0) { + if (num > 1) + wlan_hdd_mdns_find_max(matchedlist, num); + resp = NULL; + switch (matchedlist[num-1].type) { + case MDNS_TYPE_A: + resp = resptype_a; + break; + case MDNS_TYPE_TXT: + resp = resptype_txt; + break; + case MDNS_TYPE_PTR: + resp = resptype_ptr; + break; + case MDNS_TYPE_PTR_DNAME: + resp = resptype_ptr_dn; + break; + case MDNS_TYPE_SRV: + resp = resptype_srv; + break; + default: + hddLog(LOGE, FL("Fail to compress mDNS response " + "(%d)!"), MDNS_TYPE_SRV_TARGET); + return FALSE; + } + num_matched = matchedlist[num-1].num_matched; + if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt, + resp, num_matched)) { + hddLog(LOGE, FL("Fail to compress mDNS response " + "(%d)!"), MDNS_TYPE_SRV_TARGET); + return FALSE; + } + } else { + /* num = 0 -> no matched string */ + if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt, + resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_SRV_TARGET); + return FALSE; + } + } + + return TRUE; +} + +/** + * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv + * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv + * target + * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr + * domain name + * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt + * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A + * + * The Type SRV (Service) response include QName, response type, class, TTL + * and four kinds of data fields. Also, it will find the matched QName from + * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and + * then compress the data. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool +wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info, + struct hdd_mdns_resp_info *resptype_srv, + struct hdd_mdns_resp_info *resptype_srv_tgt, + struct hdd_mdns_resp_info *resptype_ptr, + struct hdd_mdns_resp_info *resptype_ptr_dn, + struct hdd_mdns_resp_info *resptype_txt, + struct hdd_mdns_resp_info *resptype_a) +{ + uint8_t num_matched, num, size; + uint16_t value; + uint8_t val_u8; + uint32_t offset_data_len, len; + struct hdd_mdns_resp_info *resp; + struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1]; + + ENTER(); + + if ((ini_config == NULL) || (resp_info == NULL) || + (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) { + hddLog(LOGE, FL("ini_config or response info is NULL!")); + return FALSE; + } + + /* No Type Srv response */ + if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0) + return TRUE; + + /* Wrong response is assigned, just ignore this response */ + if (!wlan_hdd_mdns_init_response(resptype_srv, + ini_config->mdns_resp_type_srv, '.')) + return TRUE; + + /* + * For data compression + * Check if any strings are matched with Type A response + */ + num = 0; + size = (MAX_MDNS_RESP_TYPE-1); + size *= sizeof(struct hdd_mdns_resp_matched); + vos_mem_zero(matchedlist, size); + if (resptype_ptr && (resptype_ptr->num_entries > 0)) { + if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end( + resptype_srv, + resptype_ptr_dn); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_PTR_DNAME; + num++; + } + } + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv, + resptype_ptr); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_PTR; + num++; + } + } + if (resptype_txt && (resptype_txt->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv, + resptype_txt); + if (num_matched > 0) { + matchedlist[num].num_matched =num_matched; + matchedlist[num].type = MDNS_TYPE_TXT; + num++; + } + } + if (resptype_a && (resptype_a->num_entries > 0)) { + num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv, + resptype_a); + if (num_matched > 0) { + matchedlist[num].num_matched = num_matched; + matchedlist[num].type = MDNS_TYPE_A; + num++; + } + } + if (num > 0) { + if (num > 1) + wlan_hdd_mdns_find_max(matchedlist, num); + resp = NULL; + switch (matchedlist[num-1].type) { + case MDNS_TYPE_A: + resp = resptype_a; + break; + case MDNS_TYPE_TXT: + resp = resptype_txt; + break; + case MDNS_TYPE_PTR: + resp = resptype_ptr; + break; + case MDNS_TYPE_PTR_DNAME: + resp = resptype_ptr_dn; + break; + default: + hddLog(LOGE, FL("Fail to compress mDNS response " + "(%d)!"), MDNS_TYPE_SRV); + return FALSE; + } + num_matched = matchedlist[num-1].num_matched; + if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv, + resp, num_matched)) { + hddLog(LOGE, FL("Fail to compress mDNS response " + "(%d)!"), MDNS_TYPE_SRV); + return FALSE; + } + } else { + /* num = 0 -> no matched string */ + if (!wlan_hdd_mdns_process_response_dname(resptype_srv, + resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_SRV); + return FALSE; + } + } + + /* Process response Type, Class, TTL */ + if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) { + hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"), + MDNS_TYPE_SRV); + return FALSE; + } + + /* + * Process response RDLength, RData (Srv target name) + * Save the offset of RData length + */ + offset_data_len = resp_info->resp_len; + resp_info->resp_len += sizeof(uint16_t); + + len = resp_info->resp_len + (3 * sizeof(uint16_t)); + if (len >= MAX_MDNS_RESP_LEN) { + hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN); + return FALSE; + } + + /* set Srv Priority */ + value = ini_config->mdns_resp_type_srv_priority; + wlan_hdd_mdns_format_response_u16(value, resp_info); + /* set Srv Weight */ + value = ini_config->mdns_resp_type_srv_weight; + wlan_hdd_mdns_format_response_u16(value, resp_info); + /* set Srv Port */ + value = ini_config->mdns_resp_type_srv_port; + wlan_hdd_mdns_format_response_u16(value, resp_info); + + if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info, + resptype_srv_tgt, resptype_srv, + resptype_ptr, resptype_ptr_dn, + resptype_txt, resptype_a)) { + return FALSE; + } + /* Set the RData length */ + len = offset_data_len + sizeof(uint16_t); + if ((resptype_srv_tgt->num_entries > 0) && + (resp_info->resp_len > len)) { + value = resp_info->resp_len - len; + val_u8 = (value & 0xff00) >> 8; + resp_info->resp_data[offset_data_len] = val_u8; + val_u8 = value & 0xff; + resp_info->resp_data[offset_data_len+1] = val_u8; + } else { + hddLog(LOGE, FL("Fail to process mDNS response (%d)!"), + MDNS_TYPE_SRV); + return FALSE; + } + + EXIT(); + return TRUE; +} + +/** + * wlan_hdd_mdns_free_mem() - Free the allocated memory + * @response: Pointer to the struct hdd_mdns_resp_info + * + * Return: None + */ +static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response) +{ + if (response && response->data) + vos_mem_free(response->data); + if (response && response->offset) + vos_mem_free(response->offset); +} + +/** + * wlan_hdd_mdns_pack_response() - Pack mDNS response + * @ini_config: Pointer to the struct hdd_config_t + * @resp_info: Pointer to the struct tSirMDNSResponseInfo + * + * This function will pack four types of responses (Type A, Type Txt, Type Ptr + * and Type Service). Each response contains QName, response type, class, TTL + * and data fields. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config, + sir_mdns_resp_info resp_info) +{ + struct hdd_mdns_resp_info resptype_a, resptype_txt; + struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn; + struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt; + uint32_t num_res_records = 0; + bool status = FALSE; + + ENTER(); + + wlan_hdd_mdns_reset_response(&resptype_a); + wlan_hdd_mdns_reset_response(&resptype_txt); + wlan_hdd_mdns_reset_response(&resptype_ptr); + wlan_hdd_mdns_reset_response(&resptype_ptr_dn); + wlan_hdd_mdns_reset_response(&resptype_srv); + wlan_hdd_mdns_reset_response(&resptype_srv_tgt); + + resp_info->resp_len = 0; + + /* Process Type A response */ + if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info, + &resptype_a)) + goto err_resptype_a; + + if ((resptype_a.num_entries > 0) && + (strlen((char *)&resptype_a.data[0]) > 0)) + num_res_records++; + + /* Process Type TXT response */ + if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info, + &resptype_txt, &resptype_a)) + goto err_resptype_txt; + + if ((resptype_txt.num_entries > 0) && + (strlen((char *)&resptype_txt.data[0]) > 0)) + num_res_records++; + + /* Process Type PTR response */ + if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info, + &resptype_ptr, &resptype_ptr_dn, + &resptype_txt, &resptype_a)) + goto err_resptype_ptr; + + if ((resptype_ptr.num_entries > 0) && + (strlen((char *)&resptype_ptr.data[0]) > 0)) + num_res_records++; + + /* Process Type SRV response */ + if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info, + &resptype_srv, &resptype_srv_tgt, + &resptype_ptr, &resptype_ptr_dn, + &resptype_txt, &resptype_a)) + goto err_resptype_srv; + + if ((resptype_srv.num_entries > 0) && + (strlen((char *)&resptype_srv.data[0]) > 0)) + num_res_records++; + + resp_info->resourceRecord_count = num_res_records; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Pack mDNS response data successfully!", __func__); + status = TRUE; + +err_resptype_srv: + wlan_hdd_mdns_free_mem(&resptype_srv); + wlan_hdd_mdns_free_mem(&resptype_srv_tgt); + +err_resptype_ptr: + wlan_hdd_mdns_free_mem(&resptype_ptr); + wlan_hdd_mdns_free_mem(&resptype_ptr_dn); + +err_resptype_txt: + wlan_hdd_mdns_free_mem(&resptype_txt); + +err_resptype_a: + wlan_hdd_mdns_free_mem(&resptype_a); + + EXIT(); + return status; +} + +/** + * wlan_hdd_set_mdns_offload() - Enable mDNS offload + * @hostapd_adapter: Pointer to the struct hdd_adapter_t + * + * This function will set FQDN/unique FQDN (full qualified domain name) + * and the mDNS response. Then send them to SME. + * + * Return: Return boolean. TRUE for success, FALSE for fail. + */ +bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter); + sir_mdns_offload_info mdns_offload_info; + sir_mdns_fqdn_info mdns_fqdn_info; + sir_mdns_resp_info mdns_resp_info; + uint32_t fqdn_len, ufqdn_len; + + ENTER(); + + /* 1. Prepare the MDNS fqdn request to send to SME */ + fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn); + ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn); + if ((fqdn_len == 0) && (ufqdn_len == 0)) { + hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d," + "ufqdn_len %d!"), fqdn_len, ufqdn_len); + return FALSE; + } + + mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info)); + if (NULL == mdns_fqdn_info) { + hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!")); + return FALSE; + } + /* MDNS fqdn request */ + if (fqdn_len > 0) { + vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info)); + mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId; + mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL; + mdns_fqdn_info->fqdn_len = fqdn_len; + mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done; + mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter; + vos_mem_copy(mdns_fqdn_info->fqdn_data, + hdd_ctx->cfg_ini->mdns_fqdn, + mdns_fqdn_info->fqdn_len); + + if (eHAL_STATUS_SUCCESS != + sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) { + hddLog(LOGE, FL("sme_set_mdns_fqdn fail!")); + vos_mem_free(mdns_fqdn_info); + return FALSE; + } + } + /* MDNS unique fqdn request */ + if (ufqdn_len > 0) { + vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info)); + mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId; + mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE; + mdns_fqdn_info->fqdn_len = ufqdn_len; + mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done; + mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter; + vos_mem_copy(mdns_fqdn_info->fqdn_data, + hdd_ctx->cfg_ini->mdns_uniquefqdn, + mdns_fqdn_info->fqdn_len); + if (eHAL_STATUS_SUCCESS != + sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) { + hddLog(LOGE, FL("sme_set_mdns_fqdn fail!")); + vos_mem_free(mdns_fqdn_info); + return FALSE; + } + } + vos_mem_free(mdns_fqdn_info); + + /* 2. Prepare the MDNS response request to send to SME */ + mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info)); + if (NULL == mdns_resp_info) { + hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!")); + return FALSE; + } + + vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info)); + mdns_resp_info->bss_idx = hostapd_adapter->sessionId; + mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done; + mdns_resp_info->mdns_resp_cb_context = hostapd_adapter; + if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) { + hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!")); + vos_mem_free(mdns_resp_info); + return FALSE; + } + if (eHAL_STATUS_SUCCESS != + sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) { + hddLog(LOGE, FL("sme_set_mdns_resp fail!")); + vos_mem_free(mdns_resp_info); + return FALSE; + } + vos_mem_free(mdns_resp_info); + + /* 3. Prepare the MDNS Enable request to send to SME */ + mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info)); + if (NULL == mdns_offload_info) { + hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!")); + return FALSE; + } + + vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info)); + + mdns_offload_info->bss_idx = hostapd_adapter->sessionId; + mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload; + mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done; + mdns_offload_info->mdns_enable_cb_context = hostapd_adapter; + if (eHAL_STATUS_SUCCESS != + sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) { + hddLog(LOGE, FL("sme_set_mdns_offload fail!")); + vos_mem_free(mdns_offload_info); + return FALSE; + } + + vos_mem_free(mdns_offload_info); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: enable mDNS offload successfully!", __func__); + return TRUE; +} + + +#endif /* MDNS_OFFLOAD */ + +/** + * wlan_hdd_start_sap() - This function starts bss of SAP. + * @ap_adapter: SAP adapter + * + * This function will process the starting of sap adapter. + * + * Return: void. + */ +void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter) +{ + hdd_ap_ctx_t *hdd_ap_ctx; + hdd_hostapd_state_t *hostapd_state; + VOS_STATUS vos_status; + hdd_context_t *hdd_ctx; + tsap_Config_t *pConfig; + + if (NULL == ap_adapter) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("ap_adapter is NULL here")); + return; + } + + hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter); + hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); + hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); + pConfig = &ap_adapter->sessionCtx.ap.sapConfig; + + mutex_lock(&hdd_ctx->sap_lock); + if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) + goto end; + + if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) { + hddLog(LOGE, FL("SAP Not able to set AP IEs")); + goto end; + } + + vos_event_reset(&hostapd_state->vosEvent); + if (WLANSAP_StartBss(hdd_ctx->pvosContext, hdd_hostapd_SAPEventCB, + &hdd_ap_ctx->sapConfig, (v_PVOID_t)ap_adapter->dev) + != VOS_STATUS_SUCCESS) { + goto end; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Waiting for SAP to start")); + vos_status = vos_wait_single_event(&hostapd_state->vosEvent, 10000); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("SAP Start failed")); + goto end; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP Start Success")); + set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags); + + wlan_hdd_incr_active_session(hdd_ctx, ap_adapter->device_mode); + hostapd_state->bCommit = TRUE; + +end: + mutex_unlock(&hdd_ctx->sap_lock); + return; +} + +#ifdef WLAN_FEATURE_TSF + +/** + * hdd_tsf_cb() - handle tsf request callback + * + * @pcb_cxt: pointer to the hdd_contex + * @ptsf: pointer to struct stsf + * + * Based on the request sent . + * + * Return: Describe the execute result of this routine + */ +static int hdd_tsf_cb(void *pcb_ctx, struct stsf *ptsf) +{ + hdd_context_t *hddctx; + int status; + hdd_adapter_t* adapter = (hdd_adapter_t*)pcb_ctx; + + if (pcb_ctx == NULL || ptsf == NULL) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + hddctx = (hdd_context_t *)pcb_ctx; + status = wlan_hdd_validate_context(hddctx); + if (0 != status) + return -EINVAL; + + if (NULL == adapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed to find adapter")); + return -EINVAL; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("tsf cb handle event, device_mode is %d"), + adapter->device_mode); + + /* copy the return value to hdd_tsf_ctx in adapter*/ + if (ptsf->tsf_req_status) { + + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_get_state = TSF_NOT_RETURNED_BY_FW; + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event); + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + + hddLog(VOS_TRACE_LEVEL_ERROR, FL("tsf req failure :%d"), + ptsf->tsf_req_status); + return ptsf->tsf_req_status; + } + /* If this is a get request.Store the tsf values in adapter. */ + if (!ptsf->set_tsf_req) { + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_low = ptsf->tsf_low; + adapter->tsf_cap_ctx.tsf_high = ptsf->tsf_high; + adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN; + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("hdd_get_tsf_cb sta=%u, tsf_low=%u, tsf_high=%u"), + adapter->sessionId, ptsf->tsf_low, ptsf->tsf_high); + } + else { + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE; + adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + } + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + vos_event_set (&adapter->tsf_cap_ctx.tsf_capture_done_event); + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + + /* free allocated mem */ + vos_mem_free(ptsf); + + return 0; +} + +/** + * hdd_capture_tsf() - capture tsf + * + * @adapter: pointer to adapter + * @buf: pointer to upper layer buf + * @len : the length of buf + * + * This function returns tsf value to uplayer. + * + * Return: Describe the execute result of this routine + */ +int hdd_capture_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +{ + int ret = 0; + hdd_station_ctx_t *hdd_sta_ctx; + hdd_context_t *hdd_ctx; + tSirCapTsfParams cap_tsf_params; + VOS_STATUS status; + + if (adapter == NULL || buf == NULL) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid pointer")); + return -EINVAL; + } + if (len != 1) + return -EINVAL; + + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + if (wlan_hdd_validate_context(hdd_ctx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid hdd ctx")); + return -EINVAL; + } + if (adapter->device_mode == WLAN_HDD_INFRA_STATION || + adapter->device_mode == WLAN_HDD_P2P_CLIENT) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_sta_ctx->conn_info.connState != + eConnectionState_Associated) { + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("failed to cap tsf, not connect with ap")); + buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF; + return ret; + } + } + if ((adapter->device_mode == WLAN_HDD_SOFTAP || + adapter->device_mode == WLAN_HDD_P2P_GO) && + !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Soft AP / P2p GO not beaconing")); + buf[0] = TSF_SAP_NOT_STARTED_NO_TSF; + return ret; + } + if (adapter->tsf_cap_ctx.tsf_capture_state == TSF_CAP_STATE) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("current in capture state, pls reset")); + buf[0] = TSF_CURRENT_IN_CAP_STATE; + } else { + hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd")); + buf[0] = TSF_RETURN; + cap_tsf_params.session_id = adapter->sessionId; + cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb; + cap_tsf_params.tsf_rsp_cb_ctx = adapter; + + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_capture_state = TSF_CAP_STATE; + adapter->tsf_cap_ctx.tsf_get_state = TSF_CURRENT_IN_CAP_STATE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + + ret = sme_capture_tsf_req(hdd_ctx->hHal, cap_tsf_params); + + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail")); + buf[0] = TSF_CAPTURE_FAIL; + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + return -EINVAL; + } + /* wait till we get a response from fw */ + status = vos_wait_single_event(&adapter->tsf_cap_ctx. + tsf_capture_done_event, + HDD_TSF_CAP_REQ_TIMEOUT); + + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("capture tsf vos wait for single_event failed!! %d"), + adapter->tsf_cap_ctx.tsf_get_state); + + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + + return -EINVAL; + } + } + buf[0] = TSF_RETURN; + hddLog(VOS_TRACE_LEVEL_INFO, + FL("ioctl return cap tsf cmd, ret = %d"), ret); + return ret; +} + +/** + * hdd_indicate_tsf() - return tsf to uplayer + * + * @adapter: pointer to adapter + * @buf: pointer to uplayer buf + * @len : the length of buf + * + * This function returns tsf value to uplayer. + * + * Return: Describe the execute result of this routine + */ +int hdd_indicate_tsf(hdd_adapter_t *adapter, uint32_t *buf, int len) +{ + int ret = 0; + hdd_station_ctx_t *hdd_sta_ctx; + hdd_context_t *hdd_ctx; + tSirCapTsfParams cap_tsf_params; + VOS_STATUS status; + + if (adapter == NULL || buf == NULL) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid pointer")); + return -EINVAL; + } + if (len != 3) + return -EINVAL; + + buf [1] = 0; + buf [2] = 0; + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + if (wlan_hdd_validate_context(hdd_ctx)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("invalid hdd ctx")); + return -EINVAL; + } + if (adapter->device_mode == WLAN_HDD_INFRA_STATION || + adapter->device_mode == WLAN_HDD_P2P_CLIENT) { + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_sta_ctx->conn_info.connState != + eConnectionState_Associated) { + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("failed to cap tsf, not connect with ap")); + buf[0] = TSF_STA_NOT_CONNECTED_NO_TSF; + return ret; + } + } + if ((adapter->device_mode == WLAN_HDD_SOFTAP || + adapter->device_mode == WLAN_HDD_P2P_GO) && + !(test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Soft AP / P2p GO not beaconing")); + buf[0] = TSF_SAP_NOT_STARTED_NO_TSF; + return ret; + } + + if (adapter->tsf_cap_ctx.tsf_capture_state != TSF_CAP_STATE || + adapter->tsf_cap_ctx.tsf_get_state != TSF_CURRENT_IN_CAP_STATE ) { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Not in capture state,Enter capture state first")); + buf[0] = TSF_GET_FAIL; + } else { + hddLog(VOS_TRACE_LEVEL_INFO, FL("ioctl issue cap tsf cmd")); + cap_tsf_params.session_id = adapter->sessionId; + cap_tsf_params.tsf_rsp_cb_func = hdd_tsf_cb; + cap_tsf_params.tsf_rsp_cb_ctx = adapter; + + ret = sme_get_tsf_req(hdd_ctx->hHal, cap_tsf_params); + + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("capture fail")); + buf[0] = TSF_CAPTURE_FAIL; + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + return -EINVAL; + } + /* wait till we get a response from fw */ + status = vos_wait_single_event(&adapter->tsf_cap_ctx. + tsf_capture_done_event, + HDD_TSF_GET_REQ_TIMEOUT); + + if (!VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("capture tsf vos wait for single_event failed!! %d"), + status); + + vos_spin_lock_acquire(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_spin_lock_release(&adapter->tsf_cap_ctx.tsf_lock); + return status; + } + buf[1] = adapter->tsf_cap_ctx.tsf_low; + buf[2] = adapter->tsf_cap_ctx.tsf_high; + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("get tsf cmd,status=%u, tsf_low=%u, tsf_high=%u"), + buf[0], buf[1], buf[2]); + } + hddLog(VOS_TRACE_LEVEL_INFO, + FL("ioctl return cap tsf cmd, ret = %d"), ret); + return ret; +} + +void wlan_hdd_tsf_init(hdd_adapter_t *adapter) +{ + + if (adapter == NULL) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("TSF init on a null adapter!")); + return; + } + + adapter->tsf_cap_ctx.tsf_get_state = TSF_RETURN; + adapter->tsf_cap_ctx.tsf_capture_state = TSF_IDLE; + vos_event_init(&adapter->tsf_cap_ctx.tsf_capture_done_event); + vos_spin_lock_init(&adapter->tsf_cap_ctx.tsf_lock); + adapter->tsf_cap_ctx.tsf_high = 0; + adapter->tsf_cap_ctx.tsf_low = 0; +} + +#endif + +//Register the module init/exit functions +module_init(hdd_module_init); +module_exit(hdd_module_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Qualcomm Atheros, Inc."); +MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER"); + +module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +module_param(enable_dfs_chan_scan, int, + S_IRUSR | S_IRGRP | S_IROTH); + +module_param(enable_11d, int, + S_IRUSR | S_IRGRP | S_IROTH); + +module_param(country_code, charp, + S_IRUSR | S_IRGRP | S_IROTH); diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_mib.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_mib.c new file mode 100644 index 000000000000..e1f40a888308 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_mib.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "wlan_hdd_includes.h" + + +static inline v_VOID_t mibGetDot11DesiredBssType( hdd_adapter_t *pAdapter, eMib_dot11DesiredBssType *pDot11DesiredBssType ) +{ + *pDot11DesiredBssType = pAdapter->hdd_mib.mibDot11DesiredBssType; + return; +} + +static inline VOS_STATUS mibSetDot11DesiredBssType( hdd_adapter_t *pAdapter, eMib_dot11DesiredBssType mibDot11DesiredBssType ) +{ + pAdapter->hdd_mib.mibDot11DesiredBssType = mibDot11DesiredBssType; + return( VOS_STATUS_SUCCESS ); +} + +v_BOOL_t mibIsDot11DesiredBssTypeInfrastructure( hdd_adapter_t *pAdapter ) +{ + eMib_dot11DesiredBssType mibDot11DesiredBssType; + mibGetDot11DesiredBssType( pAdapter, &mibDot11DesiredBssType ); + + return( eMib_dot11DesiredBssType_infrastructure == mibDot11DesiredBssType ); +} + + +static inline v_BOOL_t mibIsDot11DesiredBssTypeIndependent( hdd_adapter_t *pAdapter ) +{ + eMib_dot11DesiredBssType mibDot11DesiredBssType; + mibGetDot11DesiredBssType( pAdapter, &mibDot11DesiredBssType ); + + return( eMib_dot11DesiredBssType_independent == mibDot11DesiredBssType ); +} + +static inline v_VOID_t mibGetDot11IbssJoinOnly( hdd_adapter_t *pAdapter, v_BOOL_t *pdot11IbssJoinOnly ) +{ + *pdot11IbssJoinOnly = pAdapter->hdd_mib.dot11IbssJoinOnly; + return; +} + +static inline VOS_STATUS mibSetDot11IbssJoinOnly( hdd_adapter_t *pAdapter, v_BOOL_t dot11IbssJoinOnly ) +{ + pAdapter->hdd_mib.dot11IbssJoinOnly = dot11IbssJoinOnly; + return( VOS_STATUS_SUCCESS ); +} + +static inline VOS_STATUS mibSetDot11NICPowerState( hdd_adapter_t *pAdapter, eMib_dot11NICPowerState *pMibDot11NICPowerState ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pAdapter->hdd_mib.mibDot11NICPowerState = *pMibDot11NICPowerState; + + return( status ); +} + +static inline VOS_STATUS mibSetDot11NICPowerStateOff( hdd_adapter_t *pAdapter ) +{ + eMib_dot11NICPowerState dot11NICPowerState = eMib_dot11NICPowerState_OFF; + return( mibSetDot11NICPowerState( pAdapter, &dot11NICPowerState ) ); +} + +static inline void mibGetDot11NICPowerState( hdd_adapter_t *pAdapter, eMib_dot11NICPowerState *pMibDot11NICPowerState ) +{ + *pMibDot11NICPowerState = pAdapter->hdd_mib.mibDot11NICPowerState; + + return; +} + +static inline v_BOOL_t mibIsDot11NICPowerStateOn( hdd_adapter_t *pAdapter ) +{ + eMib_dot11NICPowerState dot11NICPowerState; + + mibGetDot11NICPowerState( pAdapter, &dot11NICPowerState ); + + return( eMib_dot11NICPowerState_ON == dot11NICPowerState ); +} + +static inline v_BOOL_t mibIsDot11NICPowerStateOff( hdd_adapter_t *pAdapter ) +{ + return( !mibIsDot11NICPowerStateOn( pAdapter ) ); +} + +static inline VOS_STATUS mibSetDot11DesiredSsidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredSsidList *pDot11DesiredSsidList ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if ( pDot11DesiredSsidList->cEntries > MIB_DOT11_DESIRED_SSID_LIST_MAX_COUNT ) + + pAdapter->hdd_mib.mibDot11DesiredSsidList = *pDot11DesiredSsidList ; + + return( status ); +} + +static inline VOS_STATUS mibSetDot11DesiredBssidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredBssidList *pDot11DesiredBssidList ) +{ + pAdapter->hdd_mib.mibDot11DesiredBssidList = *pDot11DesiredBssidList; + + return( VOS_STATUS_SUCCESS ); +} + + +static inline v_VOID_t mibGetDot11DesiredBssidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredBssidList *pMibDot11DesiredBssidList ) +{ + *pMibDot11DesiredBssidList = pAdapter->hdd_mib.mibDot11DesiredBssidList; + + return; +} + + +static inline v_VOID_t mibGetDot11DesiredSsidList( hdd_adapter_t *pAdapter, sMib_dot11DesiredSsidList *pMibDot11DesiredSsidList ) +{ + *pMibDot11DesiredSsidList = pAdapter->hdd_mib.mibDot11DesiredSsidList; + + return; +} + + +static inline VOS_STATUS mibSetDot11AutoConfigEnabled( hdd_adapter_t *pAdapter, eMib_dot11AutoConfigEnabled *pMibDot11AutoConfigEnabled ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pAdapter->hdd_mib.mibDot11AutoConfigEnabled = *pMibDot11AutoConfigEnabled; + + return( status ); +} + + +static inline v_VOID_t mibGetDot11AutoConfigEnabled( hdd_adapter_t *pAdapter, eMib_dot11AutoConfigEnabled *pMibDot11AutoConfigEnabled ) +{ + *pMibDot11AutoConfigEnabled = pAdapter->hdd_mib.mibDot11AutoConfigEnabled; + + return; +} + +static inline VOS_STATUS mibSetDot11MacExcludeList( hdd_adapter_t *pAdapter, sMib_dot11MacExcludeList *pDot11MacExcludeList ) +{ + pAdapter->hdd_mib.mibDot11MacExcludeList = *pDot11MacExcludeList; + + return( VOS_STATUS_SUCCESS ); +} + +static inline VOS_STATUS mibGetDot11MacExcludeList( hdd_adapter_t *pAdapter, sMib_dot11MacExcludeList *pDot11MacExcludeList ) +{ + *pDot11MacExcludeList = pAdapter->hdd_mib.mibDot11MacExcludeList; + + return( VOS_STATUS_SUCCESS ); +} + +static inline void mibSetDefaultDot11MacExcludeList( hdd_adapter_t *pAdapter ) +{ + pAdapter->hdd_mib.mibDot11MacExcludeList.cEntries = 0; +} + +static inline VOS_STATUS mibSetDot11HardwarePHYState( hdd_adapter_t *pAdapter, eMib_dot11HardwarePHYState *pMibDot11HardwarePHYState ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pAdapter->hdd_mib.mibDot11HardwarePHYState = *pMibDot11HardwarePHYState; + + return( status ); +} + + +static inline void mibGetDot11HardwarePHYState( hdd_adapter_t *pAdapter, eMib_dot11HardwarePHYState *pMibDot11HardwarePHYState ) +{ + *pMibDot11HardwarePHYState = pAdapter->hdd_mib.mibDot11HardwarePHYState; + + return; +} + +static inline void mibSetDefaultDot11PrivacyExemptionList( hdd_adapter_t *pAdapter ) +{ + pAdapter->hdd_mib.mibDot11PrivacyExemptionList.cEntries = 0; +} + + +static inline void mibGetDot11PowerSavingLevel( hdd_adapter_t *pAdapter, eMib_dot11PowerSavingLevel *pMibDot11PowerSavingLevel ) +{ + *pMibDot11PowerSavingLevel = pAdapter->hdd_mib.mibDot11PowerSavingLevel; + + return; +} + + +static inline void mibGetDevicePowerState( hdd_adapter_t *pAdapter, eMib_DevicePowerState *pMibDevicePowerState ) +{ + *pMibDevicePowerState = pAdapter->hdd_mib.mibDevicePowerState; + + return; +} + + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c new file mode 100644 index 000000000000..df015ac40a5f --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_oemdata.c @@ -0,0 +1,1011 @@ +/* + * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/*================================================================================ + \file wlan_hdd_oemdata.c + + \brief Linux Wireless Extensions for oem data req/rsp + + $Id: wlan_hdd_oemdata.c,v 1.34 2010/04/15 01:49:23 -- VINAY + + Copyright (C) Qualcomm Inc. + +================================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "qwlan_version.h" + +static struct hdd_context_s *pHddCtx; + +/*--------------------------------------------------------------------------------------------- + + \brief hdd_OemDataReqCallback() - + + This function also reports the results to the user space + + \return - eHalStatus enumeration + +-----------------------------------------------------------------------------------------------*/ +static eHalStatus hdd_OemDataReqCallback(tHalHandle hHal, + void *pContext, + tANI_U32 oemDataReqID, + eOemDataReqStatus oemDataReqStatus) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + struct net_device *dev = (struct net_device *) pContext; + union iwreq_data wrqu; + char buffer[IW_CUSTOM_MAX+1]; + + memset(&wrqu, '\0', sizeof(wrqu)); + memset(buffer, '\0', sizeof(buffer)); + + //now if the status is success, then send an event up + //so that the application can request for the data + //else no need to send the event up + if(oemDataReqStatus == eOEM_DATA_REQ_FAILURE) + { + snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-FAILED"); + hddLog(LOGW, "%s: oem data req %d failed", __func__, oemDataReqID); + } + else if(oemDataReqStatus == eOEM_DATA_REQ_INVALID_MODE) + { + snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-INVALID-MODE"); + hddLog(LOGW, "%s: oem data req %d failed because the driver is in invalid mode (IBSS|BTAMP|AP)", __func__, oemDataReqID); + } + else + { + snprintf(buffer, IW_CUSTOM_MAX, "QCOM: OEM-DATA-REQ-SUCCESS"); + //everything went alright + } + + wrqu.data.pointer = buffer; + wrqu.data.length = strlen(buffer); + + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buffer); + + return status; +} + +/**-------------------------------------------------------------------------------------------- + + \brief __iw_get_oem_data_rsp() - + + This function gets the oem data response. This invokes + the respective sme functionality. Function for handling the oem data rsp + IOCTL + + \param - dev - Pointer to the net device + - info - Pointer to the iw_oem_data_req + - wrqu - Pointer to the iwreq data + - extra - Pointer to the data + + \return - 0 for success, non zero for failure + +-----------------------------------------------------------------------------------------------*/ +int __iw_get_oem_data_rsp( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int rc = 0; + eHalStatus status; + struct iw_oem_data_rsp* pHddOemDataRsp; + tOemDataRsp* pSmeOemDataRsp; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + + ENTER(); + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) + { + return rc; + } + do + { + //get the oem data response from sme + status = sme_getOemDataRsp(WLAN_HDD_GET_HAL_CTX(pAdapter), &pSmeOemDataRsp); + if (status != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, "%s: failed in sme_getOemDataRsp", __func__); + rc = -EIO; + break; + } + else + { + if (pSmeOemDataRsp != NULL) + { + pHddOemDataRsp = (struct iw_oem_data_rsp*)(extra); + vos_mem_copy(pHddOemDataRsp->oemDataRsp, pSmeOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); + } + else + { + hddLog(LOGE, "%s: pSmeOemDataRsp = NULL", __func__); + rc = -EIO; + break; + } + } + } while(0); + + EXIT(); + return rc; +} + +int iw_get_oem_data_rsp( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_oem_data_rsp(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**-------------------------------------------------------------------------------------------- + + \brief __iw_set_oem_data_req() - + + This function sets the oem data req configuration. This invokes + the respective sme oem data req functionality. Function for + handling the set IOCTL for the oem data req configuration + + \param - dev - Pointer to the net device + - info - Pointer to the iw_oem_data_req + - wrqu - Pointer to the iwreq data + - extra - Pointer to the data + + \return - 0 for success, non zero for failure + +-----------------------------------------------------------------------------------------------*/ +int __iw_set_oem_data_req( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int rc = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + struct iw_oem_data_req *pOemDataReq = NULL; + tOemDataReqConfig oemDataReqConfig; + tANI_U32 oemDataReqID = 0; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *pwextBuf; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) + { + return rc; + } + + pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pwextBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pwextBuf is NULL",__func__); + return -EINVAL; + } + + if (pHddCtx->isPnoEnable) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pno scan in progress")); + return -EBUSY; + } + + do + { + if (NULL != wrqu->data.pointer) + { + pOemDataReq = (struct iw_oem_data_req *)wrqu->data.pointer; + } + + if (pOemDataReq == NULL) + { + hddLog(LOGE, "in %s oemDataReq == NULL", __func__); + rc = -EIO; + break; + } + + vos_mem_zero(&oemDataReqConfig, sizeof(tOemDataReqConfig)); + + if (copy_from_user((&oemDataReqConfig)->oemDataReq, + pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: copy_from_user() failed!", __func__); + rc = -EFAULT; + break; + } + + status = sme_OemDataReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &oemDataReqConfig, + &oemDataReqID, + &hdd_OemDataReqCallback, + dev); + if (status != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_OemDataReq status %d", __func__, status); + rc = -EFAULT; + break; + } + + pwextBuf->oemDataReqID = oemDataReqID; + pwextBuf->oemDataReqInProgress = TRUE; + + } while(0); + + EXIT(); + return rc; +} + +int iw_set_oem_data_req( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_oem_data_req(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief iw_get_oem_data_cap() + + This function gets the capability information for OEM Data Request + and Response. + + \param - dev - Pointer to the net device + - info - Pointer to the t_iw_oem_data_cap + - wrqu - Pointer to the iwreq data + - extra - Pointer to the data + + \return - 0 for success, non zero for failure + +----------------------------------------------------------------------------*/ +int iw_get_oem_data_cap( + struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + eHalStatus status; + t_iw_oem_data_cap oemDataCap; + t_iw_oem_data_cap *pHddOemDataCap; + hdd_adapter_t *pAdapter = netdev_priv(dev); + hdd_context_t *pHddContext; + hdd_config_t *pConfig; + tANI_U32 numChannels; + tANI_U8 chanList[OEM_CAP_MAX_NUM_CHANNELS]; + tANI_U32 i; + int ret; + + ENTER(); + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Invalid context, pAdapter is null", __func__); + return -EINVAL; + } + + pHddContext = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddContext); + if (0 != ret) + return ret; + + pConfig = pHddContext->cfg_ini; + + do + { + vos_mem_zero(&oemDataCap, sizeof(oemDataCap)); + strlcpy(oemDataCap.oem_target_signature, OEM_TARGET_SIGNATURE, + OEM_TARGET_SIGNATURE_LEN); + oemDataCap.oem_target_type = TARGET_TYPE_PRONTO; + oemDataCap.oem_fw_version = 0; + oemDataCap.driver_version.major = QWLAN_VERSION_MAJOR; + oemDataCap.driver_version.minor = QWLAN_VERSION_MINOR; + oemDataCap.driver_version.patch = QWLAN_VERSION_PATCH; + oemDataCap.driver_version.build = QWLAN_VERSION_BUILD; + oemDataCap.allowed_dwell_time_min = pConfig->nNeighborScanMinChanTime; + oemDataCap.allowed_dwell_time_max = pConfig->nNeighborScanMaxChanTime; + oemDataCap.curr_dwell_time_min = + sme_getNeighborScanMinChanTime(pHddContext->hHal); + oemDataCap.curr_dwell_time_max = + sme_getNeighborScanMaxChanTime(pHddContext->hHal); + oemDataCap.supported_bands = pConfig->nBandCapability; + + /* request for max num of channels */ + numChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + status = sme_GetCfgValidChannels(pHddContext->hHal, + &chanList[0], + &numChannels); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:failed to get valid channel list", __func__); + return -ENOENT; + } + else + { + /* make sure num channels is not more than chan list array */ + if (numChannels > OEM_CAP_MAX_NUM_CHANNELS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Num of channels(%d) more than length(%d) of chanlist", + __func__, numChannels, OEM_CAP_MAX_NUM_CHANNELS); + return -ENOMEM; + } + + oemDataCap.num_channels = numChannels; + for (i = 0; i < numChannels; i++) + { + oemDataCap.channel_list[i] = chanList[i]; + } + } + + pHddOemDataCap = (t_iw_oem_data_cap *)(extra); + vos_mem_copy(pHddOemDataCap, &oemDataCap, sizeof(*pHddOemDataCap)); + } while (0); + + EXIT(); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief send_oem_reg_rsp_nlink_msg() - send oem registration response + + This function sends oem message to registered application process + + \param - + - none + + \return - none + + --------------------------------------------------------------------------*/ +static void send_oem_reg_rsp_nlink_msg(void) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tANI_U8 *buf; + tANI_U8 *numInterfaces; + tANI_U8 *deviceMode; + tANI_U8 *vdevId; + hdd_adapter_list_node_t *pAdapterNode = NULL; + hdd_adapter_list_node_t *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status = 0; + + /* OEM message is always to a specific process and cannot be a broadcast */ + if (pHddCtx->oem_pid == 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid dest pid", __func__); + return; + } + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_APP_REG_RSP; + + /* Fill message body: + * First byte will be number of interfaces, followed by + * two bytes for each interfaces + * - one byte for device mode + * - one byte for vdev id + */ + buf = (char *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + numInterfaces = buf++; + *numInterfaces = 0; + + /* Iterate through each of the adapters and fill device mode and vdev id */ + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while ((VOS_STATUS_SUCCESS == status) && pAdapterNode) + { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter) + { + deviceMode = buf++; + vdevId = buf++; + *deviceMode = pAdapter->device_mode; + *vdevId = pAdapter->sessionId; + (*numInterfaces)++; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: numInterfaces: %d, deviceMode: %d, vdevId: %d", + __func__, *numInterfaces, *deviceMode, *vdevId); + } + status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + aniHdr->length = sizeof(tANI_U8) + (*numInterfaces) * 2 * sizeof(tANI_U8); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending App Reg Response length (%d) to process pid (%d)", + __func__, aniHdr->length, pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief send_oem_err_rsp_nlink_msg() - send oem error response + + This function sends error response to oem app + + \param - + - app_pid - PID of oem application process + + \return - none + + --------------------------------------------------------------------------*/ +static void send_oem_err_rsp_nlink_msg(v_SINT_t app_pid, tANI_U8 error_code) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tANI_U8 *buf; + + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_OEM_ERROR; + aniHdr->length = sizeof(tANI_U8); + nlh->nlmsg_len = NLMSG_LENGTH(sizeof(tAniMsgHdr) + aniHdr->length); + + /* message body will contain one byte of error code */ + buf = (char *) ((char *) aniHdr + sizeof(tAniMsgHdr)); + *buf = error_code; + + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + aniHdr->length)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending oem error response to process pid (%d)", + __func__, app_pid); + + (void)nl_srv_ucast(skb, app_pid, MSG_DONTWAIT); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief send_oem_data_rsp_msg() - send oem data response + + This function sends oem data rsp message to registered application process + over the netlink socket. + + \param - + - oemDataRsp - Pointer to OEM Data Response struct + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +void send_oem_data_rsp_msg(tANI_U32 length, tANI_U8 *oemDataRsp) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tANI_U8 *oemData; + + /* OEM message is always to a specific process and cannot be a broadcast */ + if (pHddCtx->oem_pid == 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid dest pid", __func__); + return; + } + + if (length > NEW_OEM_DATA_RSP_SIZE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid length of Oem Data response", __func__); + return; + } + + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + length), + GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_OEM_DATA_RSP; + + aniHdr->length = length; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + oemData = (tANI_U8 *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + vos_mem_copy(oemData, oemDataRsp, length); + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending Oem Data Response of len (%d) to process pid (%d)", + __func__, length, pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief oem_process_channel_info_req_msg() - process oem channel_info request + + This function responds with channel info to oem process + + \param - + - numOfChannels - number of channels + - chanList - channel list + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static int oem_process_channel_info_req_msg(int numOfChannels, char *chanList) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tHddChannelInfo *pHddChanInfo; + tHddChannelInfo hddChanInfo; + tANI_U8 chanId; + tANI_U32 reg_info_1; + tANI_U32 reg_info_2; + eHalStatus status = eHAL_STATUS_FAILURE; + int i; + tANI_U8 *buf; + + /* OEM message is always to a specific process and cannot be a broadcast */ + if (pHddCtx->oem_pid == 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: invalid dest pid", __func__); + return -1; + } + + skb = alloc_skb(NLMSG_SPACE(sizeof(tAniMsgHdr) + sizeof(tANI_U8) + + numOfChannels * sizeof(tHddChannelInfo)), GFP_KERNEL); + if (skb == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: alloc_skb failed", __func__); + return -1; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_OEM; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = ANI_MSG_CHANNEL_INFO_RSP; + + aniHdr->length = sizeof(tANI_U8) + numOfChannels * sizeof(tHddChannelInfo); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + aniHdr->length)); + + /* First byte of message body will have num of channels */ + buf = (char *) ((char *)aniHdr + sizeof(tAniMsgHdr)); + *buf++ = numOfChannels; + + /* Next follows channel info struct for each channel id. + * If chan id is wrong or SME returns failure for a channel + * then fill in 0 in channel info for that particular channel + */ + for (i = 0 ; i < numOfChannels; i++) + { + pHddChanInfo = (tHddChannelInfo *) ((char *) buf + + i * sizeof(tHddChannelInfo)); + + chanId = chanList[i]; + status = sme_getRegInfo(pHddCtx->hHal, chanId, + ®_info_1, ®_info_2); + if (eHAL_STATUS_SUCCESS == status) + { + /* band center freq1, and freq2 depends on peer's capability + * and at this time we might not be associated on the given + * channel, so fill freq1=mhz, and freq2=0 + */ + hddChanInfo.chan_id = chanId; + hddChanInfo.reserved0 = 0; + hddChanInfo.mhz = vos_chan_to_freq(chanId); + hddChanInfo.band_center_freq1 = hddChanInfo.mhz; + hddChanInfo.band_center_freq2 = 0; + + /* set only DFS flag in info, rest of the fields will be filled in + * by the OEM App + */ + hddChanInfo.info = 0; + if (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(chanId)) + hddChanInfo.info |= (1 << WLAN_HAL_CHAN_FLAG_DFS); + + hddChanInfo.reg_info_1 = reg_info_1; + hddChanInfo.reg_info_2 = reg_info_2; + } + else + { + /* chanId passed to sme_getRegInfo is not valid, fill in zeros + * in channel info struct + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sme_getRegInfo failed for chan (%d), return info 0", + __func__, chanId); + hddChanInfo.chan_id = chanId; + hddChanInfo.reserved0 = 0; + hddChanInfo.mhz = 0; + hddChanInfo.band_center_freq1 = 0; + hddChanInfo.band_center_freq2 = 0; + hddChanInfo.info = 0; + hddChanInfo.reg_info_1 = 0; + hddChanInfo.reg_info_2 = 0; + } + vos_mem_copy(pHddChanInfo, &hddChanInfo, sizeof(tHddChannelInfo)); + } + + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr) + aniHdr->length))); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: sending channel info resp for num channels (%d) to pid (%d)", + __func__, numOfChannels, pHddCtx->oem_pid); + + (void)nl_srv_ucast(skb, pHddCtx->oem_pid, MSG_DONTWAIT); + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief oem_process_data_req_msg() - process oem data request + + This function sends oem message to SME + + \param - + - oemDataLen - Length to OEM Data buffer + - oemData - Pointer to OEM Data buffer + + \return - eHalStatus enumeration + + --------------------------------------------------------------------------*/ +void oem_process_data_req_msg(int oemDataLen, char *oemData) +{ + tOemDataReqNewConfig oemDataReqNewConfig; + hdd_adapter_t *pAdapter = NULL; + + /* for now, STA interface only */ + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: No adapter for STA mode", __func__); + return; + } + + if (!oemData) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: oemData is null", __func__); + return; + } + + vos_mem_zero(&oemDataReqNewConfig, sizeof(tOemDataReqNewConfig)); + vos_mem_copy(&oemDataReqNewConfig.selfMacAddr, + pAdapter->macAddressCurrent.bytes, sizeof(tSirMacAddr)); + vos_mem_copy(&oemDataReqNewConfig.oemDataReqNew, oemData, oemDataLen); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "selfMacAddr: " MAC_ADDRESS_STR" ", + MAC_ADDR_ARRAY(oemDataReqNewConfig.selfMacAddr)); + + sme_OemDataReqNew(pHddCtx->hHal, + &oemDataReqNewConfig); +} + +/* + * Callback function invoked by Netlink service for all netlink + * messages (from user space) addressed to WLAN_NL_MSG_OEM + */ + +/** + * oem_msg_callback() - callback invoked by netlink service + * @skb: skb with netlink message + * + * This function gets invoked by netlink service when a message + * is received from user space addressed to WLAN_NL_MSG_OEM + * + * Return: zero on success + * On error, error number will be returned. + */ +static int oem_msg_callback(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + tAniMsgHdr *msg_hdr; + int ret; + char *sign_str = NULL; + char* aniMsgBody; + tANI_U32 *oemMsgSubType; + + nlh = (struct nlmsghdr *)skb->data; + + if (!nlh) { + hddLog(LOGE, FL("Netlink header null")); + return -EPERM; + } + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) { + hddLog(LOGE, FL("HDD context is not valid")); + return ret; + } + + msg_hdr = NLMSG_DATA(nlh); + + if (!msg_hdr) { + hddLog(LOGE, FL("Message header null")); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, OEM_ERR_NULL_MESSAGE_HEADER); + return -EPERM; + } + + if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr) + msg_hdr->length)) { + hddLog(LOGE, FL("Invalid nl msg len, nlh->nlmsg_len (%d), msg_hdr->len (%d)"), + nlh->nlmsg_len, msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + + hddLog(LOG1, FL("Received App msg type: %d"), msg_hdr->type); + + switch (msg_hdr->type) { + case ANI_MSG_APP_REG_REQ: + /* Registration request is only allowed for Qualcomm Application */ + hddLog(LOG1, FL("Received App Req Req from App process pid(%d), len(%d)"), + nlh->nlmsg_pid, msg_hdr->length); + + sign_str = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr)); + if ((OEM_APP_SIGNATURE_LEN == msg_hdr->length) && + (0 == strncmp(sign_str, OEM_APP_SIGNATURE_STR, + OEM_APP_SIGNATURE_LEN))) { + hddLog(LOG1, FL("Valid App Req Req from oem app process pid(%d)"), + nlh->nlmsg_pid); + + pHddCtx->oem_app_registered = TRUE; + pHddCtx->oem_pid = nlh->nlmsg_pid; + send_oem_reg_rsp_nlink_msg(); + } else { + hddLog(LOGE, FL("Invalid signature in App Reg Request from pid(%d)"), + nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_SIGNATURE); + return -EPERM; + } + break; + + case ANI_MSG_OEM_DATA_REQ: + hddLog(LOG1, FL("Received Oem Data Request length(%d) from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!pHddCtx->oem_app_registered) || + (nlh->nlmsg_pid != pHddCtx->oem_pid)) { + /* either oem app is not registered yet or pid is different */ + hddLog(LOGE, FL("OEM DataReq: app not registered(%d) or incorrect pid(%d)"), + pHddCtx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + if ((!msg_hdr->length) || (OEM_DATA_REQ_SIZE < msg_hdr->length)) { + hddLog(LOGE, FL("Invalid length (%d) in Oem Data Request"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + aniMsgBody = (char *)((char *)msg_hdr + sizeof(tAniMsgHdr)); + oemMsgSubType = (tANI_U32*) aniMsgBody; + hddLog(LOG1, FL("oemMsgSubType: 0x%x"), *oemMsgSubType); + + oem_process_data_req_msg(msg_hdr->length, + (char *) ((char *)msg_hdr + + sizeof(tAniMsgHdr))); + break; + + case ANI_MSG_CHANNEL_INFO_REQ: + hddLog(LOG1, + FL("Received channel info request, num channel(%d) from pid: %d"), + msg_hdr->length, nlh->nlmsg_pid); + + if ((!pHddCtx->oem_app_registered) || + (nlh->nlmsg_pid != pHddCtx->oem_pid)) { + /* either oem app is not registered yet or pid is different */ + hddLog(LOGE, + FL("Chan InfoReq: app not registered(%d) or incorrect pid(%d)"), + pHddCtx->oem_app_registered, nlh->nlmsg_pid); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_APP_NOT_REGISTERED); + return -EPERM; + } + + /* message length contains list of channel ids */ + if ((!msg_hdr->length) || + (WNI_CFG_VALID_CHANNEL_LIST_LEN < msg_hdr->length)) { + hddLog(LOGE, + FL("Invalid length (%d) in channel info request"), + msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_LENGTH); + return -EPERM; + } + oem_process_channel_info_req_msg(msg_hdr->length, + (char *)((char*)msg_hdr + sizeof(tAniMsgHdr))); + break; + + default: + hddLog(LOGE, + FL("Received Invalid message type (%d), length (%d)"), + msg_hdr->type, msg_hdr->length); + send_oem_err_rsp_nlink_msg(nlh->nlmsg_pid, + OEM_ERR_INVALID_MESSAGE_TYPE); + return -EPERM; + } + return 0; +} + +static int __oem_msg_callback(struct sk_buff *skb) +{ + int ret; + + vos_ssr_protect(__func__); + ret = oem_msg_callback(skb); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief oem_activate_service() - Activate oem message handler + + This function registers a handler to receive netlink message from + an OEM application process. + + \param - + - pAdapter - pointer to HDD adapter + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +int oem_activate_service(void *pAdapter) +{ + pHddCtx = (struct hdd_context_s*) pAdapter; + + /* Register the msg handler for msgs addressed to WLAN_NL_MSG_OEM */ + nl_srv_register(WLAN_NL_MSG_OEM, __oem_msg_callback); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief oem_deactivate_service() - Deactivate oem message handler + + This function unregisters a handler to receive netlink message from + an OEM application process. + + \return - none + --------------------------------------------------------------------------*/ +void oem_deactivate_service() +{ + /* unregister the msg handler for msgs addressed to WLAN_NL_MSG_OEM */ + nl_srv_unregister(WLAN_NL_MSG_OEM, __oem_msg_callback); +} + + +#endif diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c new file mode 100644 index 000000000000..feef357215bd --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_p2p.c @@ -0,0 +1,2894 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_p2p.c + + \brief WLAN Host Device Driver implementation for P2P commands interface + + + ========================================================================*/ + +#include +#include +#include +#include "sme_Api.h" +#include "sme_QosApi.h" +#include "wlan_hdd_p2p.h" +#include "sapApi.h" +#include "wlan_hdd_main.h" +#include "vos_trace.h" +#include +#include +#include +#include +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif +#include "wlan_hdd_trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_sched.h" + +//Ms to Micro Sec +#define MS_TO_MUS(x) ((x)*1000); +tANI_U8* hdd_getActionString( tANI_U16 MsgType ) +{ + switch (MsgType) + { + CASE_RETURN_STRING(SIR_MAC_ACTION_SPECTRUM_MGMT); + CASE_RETURN_STRING(SIR_MAC_ACTION_QOS_MGMT); + CASE_RETURN_STRING(SIR_MAC_ACTION_DLP); + CASE_RETURN_STRING(SIR_MAC_ACTION_BLKACK); + CASE_RETURN_STRING(SIR_MAC_ACTION_PUBLIC_USAGE); + CASE_RETURN_STRING(SIR_MAC_ACTION_RRM); + CASE_RETURN_STRING(SIR_MAC_ACTION_FAST_BSS_TRNST); + CASE_RETURN_STRING(SIR_MAC_ACTION_HT); + CASE_RETURN_STRING(SIR_MAC_ACTION_SA_QUERY); + CASE_RETURN_STRING(SIR_MAC_ACTION_PROT_DUAL_PUB); + CASE_RETURN_STRING(SIR_MAC_ACTION_WNM); + CASE_RETURN_STRING(SIR_MAC_ACTION_UNPROT_WNM); + CASE_RETURN_STRING(SIR_MAC_ACTION_TDLS); + CASE_RETURN_STRING(SIR_MAC_ACITON_MESH); + CASE_RETURN_STRING(SIR_MAC_ACTION_MHF); + CASE_RETURN_STRING(SIR_MAC_SELF_PROTECTED); + CASE_RETURN_STRING(SIR_MAC_ACTION_WME); + CASE_RETURN_STRING(SIR_MAC_ACTION_VHT); + default: + return ("UNKNOWN"); + } +} + + +#ifdef WLAN_FEATURE_P2P_DEBUG +#define MAX_P2P_ACTION_FRAME_TYPE 9 +const char *p2p_action_frame_type[]={"GO Negotiation Request", + "GO Negotiation Response", + "GO Negotiation Confirmation", + "P2P Invitation Request", + "P2P Invitation Response", + "Device Discoverability Request", + "Device Discoverability Response", + "Provision Discovery Request", + "Provision Discovery Response"}; + +/* We no need to protect this variable since + * there is no chance of race to condition + * and also not make any complicating the code + * just for debugging log + */ +tP2PConnectionStatus globalP2PConnectionStatus = P2P_NOT_ACTIVE; + +#endif +#define MAX_TDLS_ACTION_FRAME_TYPE 11 +const char *tdls_action_frame_type[] = {"TDLS Setup Request", + "TDLS Setup Response", + "TDLS Setup Confirm", + "TDLS Teardown", + "TDLS Peer Traffic Indication", + "TDLS Channel Switch Request", + "TDLS Channel Switch Response", + "TDLS Peer PSM Request", + "TDLS Peer PSM Response", + "TDLS Peer Traffic Response", + "TDLS Discovery Request" }; + +extern struct net_device_ops net_ops_struct; + +static int hdd_wlan_add_rx_radiotap_hdr( struct sk_buff *skb, + int rtap_len, int flag ); + +static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter, + hdd_cfg80211_state_t* cfgState, + tANI_BOOLEAN actionSendSuccess ); + +static void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ); + +static v_BOOL_t wlan_hdd_is_type_p2p_action( const u8 *buf, uint32_t len ) +{ + const u8 *ouiPtr; + + if (len < WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET + 1) { + return VOS_FALSE; + } + + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_CATEGORY_OFFSET] != + WLAN_HDD_PUBLIC_ACTION_FRAME ) { + return VOS_FALSE; + } + + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_ACTION_OFFSET] != + WLAN_HDD_VENDOR_SPECIFIC_ACTION ) { + return VOS_FALSE; + } + + ouiPtr = &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_OFFSET]; + + if ( WPA_GET_BE24(ouiPtr) != WLAN_HDD_WFA_OUI ) { + return VOS_FALSE; + } + + if ( buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OUI_TYPE_OFFSET] != + WLAN_HDD_WFA_P2P_OUI_TYPE ) { + return VOS_FALSE; + } + + return VOS_TRUE; +} + +static bool hdd_p2p_is_action_type_rsp( const u8 *buf, uint32_t len ) +{ + tActionFrmType actionFrmType; + + if ( wlan_hdd_is_type_p2p_action(buf, len) ) + { + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET]; + if ( actionFrmType != WLAN_HDD_INVITATION_REQ && + actionFrmType != WLAN_HDD_GO_NEG_REQ && + actionFrmType != WLAN_HDD_DEV_DIS_REQ && + actionFrmType != WLAN_HDD_PROV_DIS_REQ ) + return VOS_TRUE; + } + return VOS_FALSE; +} + +eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx, + eHalStatus status ) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t*) pCtx; + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + rem_on_channel_request_type_t req_type; + + if (pHddCtx == NULL) + { + hddLog(LOGE, "%s: Hdd Context is NULL", __func__); + return eHAL_STATUS_FAILURE; + } + + mutex_lock(&pHddCtx->roc_lock); + + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx == NULL) + { + hddLog( LOGW, + "%s: No Rem on channel pending for which Rsp is received", __func__); + mutex_unlock(&pHddCtx->roc_lock); + return eHAL_STATUS_SUCCESS; + } + + hddLog( VOS_TRACE_LEVEL_INFO, + "Received ROC rsp (request type %d, channel %d, cookie %llu", + pRemainChanCtx->rem_on_chan_request, + pRemainChanCtx->chan.center_freq, + pRemainChanCtx->cookie); + if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop( + &pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer")); + } + if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL("Failed to destroy hdd_remain_on_chan_timer")); + } + if ( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request ) + { + if( cfgState->buf ) + { + hddLog( LOG1, + "%s: We need to receive yet an ack from one of tx packet", + __func__); + } + cfg80211_remain_on_channel_expired( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pRemainChanCtx->dev->ieee80211_ptr, +#else + pRemainChanCtx->dev, +#endif + pRemainChanCtx->cookie, + &pRemainChanCtx->chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pRemainChanCtx->chan_type, +#endif + GFP_KERNEL); + pAdapter->lastRocTs = vos_timer_get_system_time(); + } + + req_type = pRemainChanCtx->rem_on_chan_request; + mutex_unlock(&pHddCtx->roc_lock); + + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + tANI_U8 sessionId = pAdapter->sessionId; + if( REMAIN_ON_CHANNEL_REQUEST == req_type ) + { + sme_DeregisterMgmtFrame( + hHal, sessionId, + (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), + NULL, 0 ); + } + } + else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + WLANSAP_DeRegisterMgmtFrame( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), + NULL, 0 ); + } + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if ( pRemainChanCtx ) + { + /* Trigger kernel panic if ROC timer state is not set to unused state + * before freeing the ROC ctx. + */ + if (VOS_TIMER_STATE_UNUSED != vos_timer_getCurrentState( + &pRemainChanCtx->hdd_remain_on_chan_timer)) + VOS_BUG(0); + + if (pRemainChanCtx->action_pkt_buff.frame_ptr != NULL + && pRemainChanCtx->action_pkt_buff.frame_length != 0) + { + vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr); + } + hddLog( LOG1, FL( + "Freeing ROC ctx cfgState->remain_on_chan_ctx=%p"), + cfgState->remain_on_chan_ctx); + vos_mem_free( pRemainChanCtx ); + pRemainChanCtx = NULL; + cfgState->remain_on_chan_ctx = NULL; + } + mutex_unlock(&pHddCtx->roc_lock); + if (eHAL_STATUS_SUCCESS != status) + complete(&pAdapter->rem_on_chan_ready_event); + complete(&pAdapter->cancel_rem_on_chan_var); + pAdapter->is_roc_inprogress = FALSE; + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + return eHAL_STATUS_SUCCESS; +} + +VOS_STATUS wlan_hdd_cancel_existing_remain_on_channel(hdd_adapter_t *pAdapter) +{ + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status = 0; + + if (NULL == pHddCtx) + { + hddLog(LOGE, "%s: HddCtx is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if(pRemainChanCtx != NULL) + { + if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( + &pRemainChanCtx->hdd_remain_on_chan_timer)) + { + hddLog(VOS_TRACE_LEVEL_INFO, + "Cancel Existing ROC (cookie=%llu)", + pRemainChanCtx->cookie); + + if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop( + &pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer")); + } + } + /* Wait till remain on channel ready indication before issuing cancel + * remain on channel request, otherwise if remain on channel not + * received and if the driver issues cancel remain on channel then lim + * will be in unknown state. + */ + if (pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress != TRUE) + { + mutex_unlock(&pHddCtx->roc_lock); + status = wait_for_completion_interruptible_timeout( + &pAdapter->rem_on_chan_ready_event, + msecs_to_jiffies(WAIT_REM_CHAN_READY)); + if (0 >= status) + { + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx) + pRemainChanCtx->is_pending_roc_cancelled = TRUE; + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOGE, + "%s: timeout waiting for remain on channel" + " ready indication %d", + __func__, status); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + FALSE, TRUE); + return VOS_STATUS_E_FAILURE; + } + + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (NULL == pRemainChanCtx) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOGE, + "%s-%d: pRemainChanCtx is NULL", + __func__, __LINE__); + return VOS_STATUS_E_FAILURE; + } + /* Check again if cancel remain on channel is started. + * If its started wait for its completiona and return. + */ + if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOG1, + "ROC timer cancellation in progress," + " wait for completion"); + status = wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (0 >= status) + { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var failed %d", + __func__, status); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; + } + else + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE; + INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); + mutex_unlock(&pHddCtx->roc_lock); + + /* Issue abort remain on chan request to sme. + * The remain on channel callback will make sure the remain_on_chan + * expired event is sent. + */ + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )) + { + if (eHAL_STATUS_SUCCESS != + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), + pAdapter->sessionId )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Cancel Remain on Channel")); + } + } + else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + } + + status = wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + if (0 >= status) + { + hddLog(LOGE, + FL("Timeout waiting for cancel remain on channel ready indication %d"), + status); + return VOS_STATUS_E_FAILURE; + } + } + else + { + hddLog( LOG1, + "ROC timer cancellation in progress," + " wait for completion"); + mutex_unlock(&pHddCtx->roc_lock); + status = wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (0 >= status) + { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var failed %d", + __func__, status); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; + } + } + else + { + hddLog(LOG1, + "%s: remain_on_chan_ctx is NULL", __func__); + mutex_unlock(&pHddCtx->roc_lock); + } + return VOS_STATUS_SUCCESS; +} + +int wlan_hdd_check_remain_on_channel(hdd_adapter_t *pAdapter) +{ + int status = 0; + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if(WLAN_HDD_P2P_GO != pAdapter->device_mode) + { + //Cancel Existing Remain On Channel + //If no action frame is pending + if( cfgState->remain_on_chan_ctx != NULL) + { + //Check whether Action Frame is pending or not + if( cfgState->buf == NULL) + { + wlan_hdd_cancel_existing_remain_on_channel(pAdapter); + } + else + { + hddLog(VOS_TRACE_LEVEL_DEBUG, + "Cannot Cancel Existing Remain on Channel"); + status = -EBUSY; + } + } + } + return status; +} +void wlan_hdd_remain_on_chan_timeout(void *data) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)data; + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + hdd_cfg80211_state_t *cfgState; + hdd_context_t *pHddCtx; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog( LOGE, FL("pAdapter is invalid %p !!!"), pAdapter); + return; + } + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + + if (NULL == pRemainChanCtx) + { + hddLog( LOGE, FL("No Remain on channel is pending")); + mutex_unlock(&pHddCtx->roc_lock); + return; + } + + if ( TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress ) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOGE, FL("Cancellation already in progress")); + return; + } + + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE; + INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOG1,"%s: Cancel Remain on Channel on timeout", __func__); + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + if (eHAL_STATUS_SUCCESS != + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter), + pAdapter->sessionId )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Cancel Remain on Channel")); + } + } + else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + } + + wlan_hdd_start_stop_tdls_source_timer(pHddCtx, eTDLS_SUPPORT_ENABLED); + + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); +} + +static int wlan_hdd_p2p_start_remain_on_channel( + hdd_adapter_t *pAdapter) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter_temp; + v_BOOL_t isGoPresent = VOS_FALSE; + hdd_context_t *pHddCtx; + hdd_cfg80211_state_t *cfgState; + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + rem_on_channel_request_type_t request_type; + unsigned int duration; + v_U16_t hw_value; + + int ret = 0; + + ENTER(); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + if (NULL == cfgState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: cfgState is not valid ",__func__); + return -EINVAL; + } + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if ( pRemainChanCtx == NULL) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOGE, + "%s-%d: pRemainChanCtx is NULL", + __func__, __LINE__); + return ret; + } + request_type = pRemainChanCtx->rem_on_chan_request; + /* Initialize Remain on chan timer */ + status = vos_timer_init(&pRemainChanCtx->hdd_remain_on_chan_timer, + VOS_TIMER_TYPE_SW, + wlan_hdd_remain_on_chan_timeout, + pAdapter); + if (status != VOS_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Not able to initalize remain_on_chan timer")); + hddLog( LOG1, FL( + "Freeing ROC ctx cfgState->remain_on_chan_ctx=%p"), + cfgState->remain_on_chan_ctx); + cfgState->remain_on_chan_ctx = NULL; + vos_mem_free(pRemainChanCtx); + mutex_unlock(&pHddCtx->roc_lock); + return -EINVAL; + } + + duration = pRemainChanCtx->duration; + hw_value = pRemainChanCtx->chan.hw_value; + mutex_unlock(&pHddCtx->roc_lock); + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter_temp = pAdapterNode->pAdapter; + if (WLAN_HDD_P2P_GO == pAdapter_temp->device_mode) + { + isGoPresent = VOS_TRUE; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + //call sme API to start remain on channel. + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + tANI_U8 sessionId = pAdapter->sessionId; + //call sme API to start remain on channel. + if (eHAL_STATUS_SUCCESS != sme_RemainOnChannel( + WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, + hw_value, duration, + wlan_hdd_remain_on_channel_callback, pAdapter, + (tANI_U8)(request_type == REMAIN_ON_CHANNEL_REQUEST)? TRUE:FALSE)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL(" RemainOnChannel returned fail")); + + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + hddLog( LOG1, FL( + "Freeing ROC ctx cfgState->remain_on_chan_ctx=%p"), + cfgState->remain_on_chan_ctx); + if (pRemainChanCtx) + { + if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy + (&pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL( + "Failed to destroy hdd_remain_on_chan_timer")); + } + vos_mem_free(pRemainChanCtx); + cfgState->remain_on_chan_ctx = NULL; + } + mutex_unlock(&pHddCtx->roc_lock); + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + return -EINVAL; + } + + if( REMAIN_ON_CHANNEL_REQUEST == request_type) + { + if( eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame( + WLAN_HDD_GET_HAL_CTX(pAdapter), + sessionId, (SIR_MAC_MGMT_FRAME << 2) | + (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0 )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "sme_RegisterMgmtFrame returned fail"); + } + } + + } + else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + //call sme API to start remain on channel. + if (VOS_STATUS_SUCCESS != WLANSAP_RemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + hw_value, duration, + wlan_hdd_remain_on_channel_callback, pAdapter )) + + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_RemainOnChannel returned fail", __func__); + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + hddLog( LOG1, FL( + "Freeing ROC ctx cfgState->remain_on_chan_ctx=%p"), + cfgState->remain_on_chan_ctx); + if (pRemainChanCtx) + { + if(!VOS_IS_STATUS_SUCCESS(vos_timer_destroy + (&pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL( + "Failed to destroy hdd_remain_on_chan_timer")); + } + vos_mem_free (pRemainChanCtx); + cfgState->remain_on_chan_ctx = NULL; + } + mutex_unlock(&pHddCtx->roc_lock); + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + return -EINVAL; + } + + + if (VOS_STATUS_SUCCESS != WLANSAP_RegisterMgmtFrame( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_PROBE_REQ << 4), + NULL, 0 )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_RegisterMgmtFrame returned fail", __func__); + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + return -EINVAL; + } + + } + + wlan_hdd_start_stop_tdls_source_timer(pHddCtx, eTDLS_SUPPORT_DISABLED); + + pAdapter->is_roc_inprogress = TRUE; + EXIT(); + return 0; +} + + +static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, + struct net_device *dev, + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie, + rem_on_channel_request_type_t request_type ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_context_t *pHddCtx = NULL; + VOS_STATUS checkReadyInd; + hdd_adapter_t *pStaAdapter; + int status = 0; + + ENTER(); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__,pAdapter->device_mode); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + hddLog(VOS_TRACE_LEVEL_INFO, + "chan(hw_val)0x%x chan(centerfreq) %d chan type 0x%x, dur %d," + " request type %d, cookie %llu", + chan->hw_value, chan->center_freq, channel_type, duration, + request_type, *cookie); +#else + hddLog(VOS_TRACE_LEVEL_INFO, + "chan(hw_val)0x%x chan(centerfreq) %d, duration %d" + " reuest type %d, cookie %llu", chan->hw_value, chan->center_freq, + duration, request_type, *cookie ); +#endif + //Cancel existing remain On Channel if any + checkReadyInd = wlan_hdd_cancel_existing_remain_on_channel(pAdapter); + if (VOS_STATUS_SUCCESS != checkReadyInd) + { + hddLog( LOGE, FL("Cancel Roc in progress")); + return -EBUSY; + } + + if (TRUE == pHddCtx->btCoexModeSet) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("BTCoex Mode operation in progress")); + return -EBUSY; + } + + if(hdd_isConnectionInProgress((hdd_context_t *)pAdapter->pHddCtx, NULL, + NULL)) + { + hddLog( LOGE, + "%s: Connection is in progress", __func__); + return -EBUSY; + } + + mutex_lock(&pHddCtx->roc_lock); + + if (cfgState->remain_on_chan_ctx) + VOS_BUG(0); + + pRemainChanCtx = vos_mem_malloc( sizeof(hdd_remain_on_chan_ctx_t) ); + if( NULL == pRemainChanCtx ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Not able to allocate memory for Channel context", + __func__); + mutex_unlock(&pHddCtx->roc_lock); + return -ENOMEM; + } + + vos_mem_zero(pRemainChanCtx, sizeof (hdd_remain_on_chan_ctx_t)); + vos_mem_copy( &pRemainChanCtx->chan, chan, + sizeof(struct ieee80211_channel) ); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pRemainChanCtx->chan_type = channel_type; +#endif + pRemainChanCtx->duration = duration; + pRemainChanCtx->dev = dev; + *cookie = (uintptr_t) pRemainChanCtx; + pRemainChanCtx->cookie = *cookie; + pRemainChanCtx->rem_on_chan_request = request_type; + cfgState->remain_on_chan_ctx = pRemainChanCtx; + cfgState->current_freq = chan->center_freq; + pRemainChanCtx->action_pkt_buff.freq = 0; + pRemainChanCtx->action_pkt_buff.frame_ptr = NULL; + pRemainChanCtx->action_pkt_buff.frame_length = 0; + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = FALSE; + pRemainChanCtx->is_pending_roc_cancelled = FALSE; + + INIT_COMPLETION(pAdapter->rem_on_chan_ready_event); + + if (REMAIN_ON_CHANNEL_REQUEST == request_type) + { + pStaAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if((NULL != pStaAdapter)&& + hdd_connIsConnected( WLAN_HDD_GET_STATION_CTX_PTR(pStaAdapter))) + { + if (pAdapter->lastRocTs !=0 && + ((vos_timer_get_system_time() - pAdapter->lastRocTs ) + < pHddCtx->cfg_ini->gP2PListenDeferInterval)) + { + if (pRemainChanCtx->duration > HDD_P2P_MAX_ROC_DURATION) + pRemainChanCtx->duration = HDD_P2P_MAX_ROC_DURATION; + + mutex_unlock(&pHddCtx->roc_lock); + + schedule_delayed_work(&pAdapter->roc_work, + msecs_to_jiffies(pHddCtx->cfg_ini->gP2PListenDeferInterval)); + hddLog(VOS_TRACE_LEVEL_INFO, "Defer interval is %hu, pAdapter %p", + pHddCtx->cfg_ini->gP2PListenDeferInterval, pAdapter); + return 0; + } + } + } + + mutex_unlock(&pHddCtx->roc_lock); + status = wlan_hdd_p2p_start_remain_on_channel(pAdapter); + + EXIT(); + return status; +} + +int __wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie ) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_REMAIN_ON_CHANNEL, + pAdapter->sessionId, REMAIN_ON_CHANNEL_REQUEST)); + ret = wlan_hdd_request_remain_on_channel(wiphy, dev, + chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, +#endif + duration, cookie, + REMAIN_ON_CHANNEL_REQUEST); + EXIT(); + return ret; +} + +int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + struct ieee80211_channel *chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, +#endif + unsigned int duration, u64 *cookie ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_remain_on_channel(wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wdev, +#else + dev, +#endif + chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, +#endif + duration, cookie); + vos_ssr_unprotect(__func__); + + return ret; +} + + +void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter ) +{ + hdd_cfg80211_state_t *cfgState = NULL; + hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL; + hdd_context_t *pHddCtx; + VOS_STATUS status; + if (NULL == pAdapter) + { + hddLog(LOGE, FL("pAdapter is NULL")); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + hddLog(LOGE, FL("pHddCtx is NULL")); + return; + } + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + pAdapter->startRocTs = vos_timer_get_system_time(); + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if( pRemainChanCtx != NULL ) + { + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_REMAINCHANREADYHANDLER, + pAdapter->sessionId, pRemainChanCtx->duration)); + //start timer for actual duration + status = vos_timer_start(&pRemainChanCtx->hdd_remain_on_chan_timer, + (pRemainChanCtx->duration)); + if (VOS_STATUS_SUCCESS!=status) + { + hddLog( LOGE, FL("Remain on Channel timer start failed")); + } + if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) + { + cfg80211_ready_on_channel( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pAdapter->dev->ieee80211_ptr, +#else + pAdapter->dev, +#endif + (uintptr_t)pRemainChanCtx, + &pRemainChanCtx->chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + pRemainChanCtx->chan_type, +#endif + pRemainChanCtx->duration, GFP_KERNEL ); + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + else if( OFF_CHANNEL_ACTION_TX == pRemainChanCtx->rem_on_chan_request) + { + complete(&pAdapter->offchannel_tx_event); + } +#endif + // Check for cached action frame + if ( pRemainChanCtx->action_pkt_buff.frame_length != 0 ) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, + pRemainChanCtx->action_pkt_buff.freq, 0, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + NL80211_RXMGMT_FLAG_ANSWERED); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) + cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, + pRemainChanCtx->action_pkt_buff.freq, 0, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, + pRemainChanCtx->action_pkt_buff.freq, 0, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + GFP_ATOMIC ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + cfg80211_rx_mgmt( pAdapter->dev, + pRemainChanCtx->action_pkt_buff.freq, 0, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + GFP_ATOMIC ); +#else + cfg80211_rx_mgmt( pAdapter->dev, + pRemainChanCtx->action_pkt_buff.freq, + pRemainChanCtx->action_pkt_buff.frame_ptr, + pRemainChanCtx->action_pkt_buff.frame_length, + GFP_ATOMIC ); +#endif //LINUX_VERSION_CODE + hddLog( LOGE, "%s: Sent cached action frame to supplicant", __func__); + vos_mem_free(pRemainChanCtx->action_pkt_buff.frame_ptr); + pRemainChanCtx->action_pkt_buff.frame_length = 0; + pRemainChanCtx->action_pkt_buff.freq = 0; + pRemainChanCtx->action_pkt_buff.frame_ptr = NULL; + } + hddLog( VOS_TRACE_LEVEL_INFO, "Ready on chan ind (cookie=%llu)", + pRemainChanCtx->cookie); + complete(&pAdapter->rem_on_chan_ready_event); + if (TRUE == pRemainChanCtx->is_pending_roc_cancelled) + { + mutex_unlock(&pHddCtx->roc_lock); + /* since pRemainChanCtx->is_pending_roc_cancelled is + * set, it means Cancel Reamain on channel command is + * pending because remain on channel event was not + * ready when cancel ROC was issued.So issue + * cancel ROC now. + */ + wlan_hdd_cancel_existing_remain_on_channel(pAdapter); + } + else + { + mutex_unlock(&pHddCtx->roc_lock); + } + } + else + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__); + } + return; +} + +int __wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie ) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + int status; + u64 cookie_dummy; + + ENTER(); + cookie_dummy = cookie << 32; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL, + pAdapter->sessionId, cookie_dummy)); + hddLog( LOG1, "Cancel remain on channel req"); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + return status; + } + hddLog( LOG1, "Cancel remain on channel req (cookie = %llu)", cookie); + + /* FIXME cancel currently running remain on chan. + * Need to check cookie and cancel accordingly + */ + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if( (cfgState->remain_on_chan_ctx == NULL) || + (cfgState->remain_on_chan_ctx->cookie != cookie) ) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOGE, + "%s: No Remain on channel pending with specified cookie value", + __func__); + return -EINVAL; + } + if (TRUE != pRemainChanCtx->is_pending_roc_cancelled) + { + mutex_unlock(&pHddCtx->roc_lock); + /* wait until remain on channel ready event received + * for already issued remain on channel request */ + status = wait_for_completion_interruptible_timeout(&pAdapter->rem_on_chan_ready_event, + msecs_to_jiffies(WAIT_REM_CHAN_READY)); + if (0 >= status) + { + hddLog( LOGE, + "%s: timeout waiting for remain on channel ready indication %d", + __func__, status); + mutex_lock(&pHddCtx->roc_lock); + if (cfgState->remain_on_chan_ctx) + cfgState->remain_on_chan_ctx->is_pending_roc_cancelled = TRUE; + mutex_unlock(&pHddCtx->roc_lock); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_HDD_TIME_OUT, + FALSE, TRUE); + return 0; + + } + mutex_lock(&pHddCtx->roc_lock); + } + else + { + hddLog( LOG1, FL("Cancel ROC event is already pending, " + "waiting for ready on channel indication.") ); + mutex_unlock(&pHddCtx->roc_lock); + return 0; + } + if (NULL != cfgState->remain_on_chan_ctx) + { + if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop( + &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer")); + } + if (TRUE == pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog( LOG1, + FL("ROC timer cancellation in progress," + " wait for completion")); + status = wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (0 >= status) + { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var failed %d", + __func__, status); + } + return 0; + } + else + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress = TRUE; + } + INIT_COMPLETION(pAdapter->cancel_rem_on_chan_var); + mutex_unlock(&pHddCtx->roc_lock); + /* Issue abort remain on chan request to sme. + * The remain on channel callback will make sure the remain_on_chan + * expired event is sent. + */ + if ( ( WLAN_HDD_INFRA_STATION == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_CLIENT == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode )) + { + tANI_U8 sessionId = pAdapter->sessionId; + if (eHAL_STATUS_SUCCESS != + sme_CancelRemainOnChannel( WLAN_HDD_GET_HAL_CTX( pAdapter ), + sessionId )) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Cancel Remain on Channel")); + } + } + else if (WLAN_HDD_P2P_GO == pAdapter->device_mode) + { + WLANSAP_CancelRemainOnChannel( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid device_mode = %d", + __func__, pAdapter->device_mode); + return -EIO; + } + status = wait_for_completion_interruptible_timeout(&pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (0 >= status) + { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var failed %d", __func__, status); + } + hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_ROC); + + EXIT(); + return 0; +} + +int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct wireless_dev *wdev, +#else + struct net_device *dev, +#endif + u64 cookie ) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_cancel_remain_on_channel(wiphy, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wdev, +#else + dev, +#endif + cookie); + vos_ssr_unprotect(__func__); + + return ret; +} + + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, + bool channel_type_valid, +#endif + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +int __wlan_hdd_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, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +int __wlan_hdd_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 ) +#else +int __wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie ) +#endif //LINUX_VERSION_CODE +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + hdd_remain_on_chan_ctx_t *pRemainChanCtx = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tANI_U8 type; + tANI_U8 subType; + tActionFrmType actionFrmType = WLAN_HDD_ACTION_FRM_TYPE_MAX; + bool noack = 0; + int status; + uint32_t mgmt_hdr_len = sizeof(struct ieee80211_hdr_3addr); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + uint8_t home_ch = 0; +#endif + + ENTER(); + + if (len < mgmt_hdr_len + 1) { + hddLog(VOS_TRACE_LEVEL_ERROR,"Invalid Length"); + return -EINVAL; + } + + type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]); + subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_ACTION, pAdapter->sessionId, + pAdapter->device_mode )); + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + return status; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d type: %d", + __func__, pAdapter->device_mode, type); + + + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION) && + wlan_hdd_is_type_p2p_action( + &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], len - mgmt_hdr_len)) + { + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; +#ifdef WLAN_FEATURE_P2P_DEBUG + if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] ---> OTA", + actionFrmType); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s ---> OTA", + p2p_action_frame_type[actionFrmType]); + if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && + (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; + hddLog(LOGE,"[P2P State]Inactive state to " + "GO negotiation progress state"); + } + else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && + (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; + hddLog(LOGE,"[P2P State]GO nego progress to GO nego" + " completed state"); + } + } +#endif + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + noack = dont_wait_for_ack; +#endif + + + //If the wait is coming as 0 with off channel set + //then set the wait to 200 ms + if (offchan && !wait) + { + wait = ACTION_FRAME_DEFAULT_WAIT; + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if (pRemainChanCtx) + { + tANI_U32 current_time = vos_timer_get_system_time(); + int remaining_roc_time = ((int) pRemainChanCtx->duration - + (current_time - pAdapter->startRocTs)); + if ( remaining_roc_time > ACTION_FRAME_DEFAULT_WAIT) + wait = remaining_roc_time; + } + mutex_unlock(&pHddCtx->roc_lock); + } + + //Call sme API to send out a action frame. + // OR can we send it directly through data path?? + // After tx completion send tx status back. + if ( ( WLAN_HDD_SOFTAP == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + if (type == SIR_MAC_MGMT_FRAME) + { + if (subType == SIR_MAC_MGMT_PROBE_RSP) + { + /* Drop Probe response recieved from supplicant, as for GO and + SAP PE itself sends probe response + */ + goto err_rem_channel; + } + else if ((subType == SIR_MAC_MGMT_DISASSOC) || + (subType == SIR_MAC_MGMT_DEAUTH)) + { + /* During EAP failure or P2P Group Remove supplicant + * is sending del_station command to driver. From + * del_station function, Driver will send deauth frame to + * p2p client. No need to send disassoc frame from here. + * so Drop the frame here and send tx indication back to + * supplicant. + */ + tANI_U8 dstMac[ETH_ALEN] = {0}; + memcpy(&dstMac, &buf[WLAN_HDD_80211_FRM_DA_OFFSET], ETH_ALEN); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Deauth/Disassoc received for STA:" + MAC_ADDRESS_STR, + __func__, + MAC_ADDR_ARRAY(dstMac)); + goto err_rem_channel; + } + } + } + + if( NULL != cfgState->buf ) + { + if ( !noack ) + { + hddLog( LOGE, "(%s):Previous P2P Action frame packet pending", + __func__); + hdd_cleanup_actionframe(pAdapter->pHddCtx, pAdapter); + } + else + { + hddLog( LOGE, "(%s):Pending Action frame packet return EBUSY", + __func__); + return -EBUSY; + } + } + + if( subType == SIR_MAC_MGMT_ACTION) + { + hddLog( LOG1, "Action frame tx request : %s", + hdd_getActionString(buf[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET])); + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + if ( (( WLAN_HDD_SOFTAP == pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode )) && + (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))) + { + home_ch = pAdapter->sessionCtx.ap.operatingChannel; + } + else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) && + (pAdapter->sessionCtx.station.conn_info.connState == + eConnectionState_Associated)) + { + home_ch = pAdapter->sessionCtx.station.conn_info.operationChannel; + } + //If GO adapter exists and operating on same frequency + //then we will not request remain on channel + if (ieee80211_frequency_to_channel(chan->center_freq) == home_ch) + { + /* if GO exist and is not off channel + * wait time should be zero. + */ + wait = 0; + goto send_frame; + } +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + if( offchan && wait) + { + int status; + rem_on_channel_request_type_t req_type = OFF_CHANNEL_ACTION_TX; + // In case of P2P Client mode if we are already + // on the same channel then send the frame directly + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if( (pRemainChanCtx != NULL) && + (cfgState->current_freq == chan->center_freq) + ) + { + if ( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( + &pRemainChanCtx->hdd_remain_on_chan_timer) ) + { + /* Some times FW is taking almost 500 msec for + * full 15 retries, which leads to ROC expiration + * by the time peer gets response from other peer. + * Therefore as part of temporary fix , in host + * ROC time is extended. For frames where we are + * expecting response from peer , its extended by + * 500 msec to make ROC wait time as 1 sec and + * in other cases its extended by 300 msec to make + * total ROC wait as 500 msec. + * TODO: FW needs to fix as why 15 retry is taking + * such long time. + */ + if ( actionFrmType == WLAN_HDD_INVITATION_REQ || + actionFrmType == WLAN_HDD_GO_NEG_REQ || + actionFrmType == WLAN_HDD_GO_NEG_RESP ) + wait = wait + ACTION_FRAME_RSP_WAIT; + else if ( actionFrmType == WLAN_HDD_GO_NEG_CNF || + actionFrmType == WLAN_HDD_INVITATION_RESP ) + wait = wait + ACTION_FRAME_ACK_WAIT; + + if (!VOS_IS_STATUS_SUCCESS(vos_timer_stop( + &pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL("Failed to stop hdd_remain_on_chan_timer")); + } + status = vos_timer_start( + &pRemainChanCtx->hdd_remain_on_chan_timer, + wait); + + mutex_unlock(&pHddCtx->roc_lock); + + hddLog(VOS_TRACE_LEVEL_INFO, + "action frame: extending the wait time %u", + wait); + + if ( status != VOS_STATUS_SUCCESS ) + { + hddLog( LOGE, "Remain on Channel timer start failed"); + } + goto send_frame; + } + else + { + if ( TRUE == + pRemainChanCtx->hdd_remain_on_chan_cancel_in_progress ) + { + mutex_unlock(&pHddCtx->roc_lock); + hddLog(VOS_TRACE_LEVEL_INFO, + "action frame tx: waiting for completion of ROC "); + + status = wait_for_completion_interruptible_timeout( + &pAdapter->cancel_rem_on_chan_var, + msecs_to_jiffies(WAIT_CANCEL_REM_CHAN)); + if (0 >= status) + { + hddLog( LOGE, + "%s:wait on cancel_rem_on_chan_var failed %d", + __func__, status); + } + goto bypass_lock; + } + } + } + mutex_unlock(&pHddCtx->roc_lock); +bypass_lock: + hddLog(VOS_TRACE_LEVEL_INFO, + "action frame: Request ROC for wait time %u", wait); + INIT_COMPLETION(pAdapter->offchannel_tx_event); + status = wlan_hdd_request_remain_on_channel(wiphy, dev, + chan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, +#endif + wait, cookie, + req_type); + + if(0 != status) + { + if( (-EBUSY == status) && + (cfgState->current_freq == chan->center_freq) ) + { + goto send_frame; + } + goto err_rem_channel; + } + /* Wait for driver to be ready on the requested channel */ + status = wait_for_completion_interruptible_timeout( + &pAdapter->offchannel_tx_event, + msecs_to_jiffies(WAIT_CHANGE_CHANNEL_FOR_OFFCHANNEL_TX)); + if(0 >= status) + { + hddLog( LOGE, "wait on offchannel_tx_event failed %d", status); + goto err_rem_channel; + } + } + else if ( offchan ) + { + /* Check before sending action frame + whether we already remain on channel */ + if(NULL == cfgState->remain_on_chan_ctx) + { + goto err_rem_channel; + } + } + send_frame: +#endif + + if(!noack) + { + cfgState->buf = vos_mem_malloc( len ); //buf; + if( cfgState->buf == NULL ) + return -ENOMEM; + + cfgState->len = len; + + vos_mem_copy( cfgState->buf, buf, len); + + mutex_lock(&pHddCtx->roc_lock); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + if( cfgState->remain_on_chan_ctx ) + { + cfgState->action_cookie = cfgState->remain_on_chan_ctx->cookie; + *cookie = cfgState->action_cookie; + } + else + { +#endif + *cookie = (uintptr_t) cfgState->buf; + cfgState->action_cookie = *cookie; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + } +#endif + mutex_unlock(&pHddCtx->roc_lock); + } + + if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + ( WLAN_HDD_P2P_DEVICE == pAdapter->device_mode ) + ) + { + tANI_U8 sessionId = pAdapter->sessionId; + + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION) && + wlan_hdd_is_type_p2p_action( + &buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET], + len - mgmt_hdr_len)) + { + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; + hddLog(LOG1, "Tx Action Frame %u.", actionFrmType); + if (actionFrmType == WLAN_HDD_PROV_DIS_REQ) + { + cfgState->actionFrmState = HDD_PD_REQ_ACK_PENDING; + hddLog(LOG1, "%s: HDD_PD_REQ_ACK_PENDING.", __func__); + } + else if (actionFrmType == WLAN_HDD_GO_NEG_REQ) + { + cfgState->actionFrmState = HDD_GO_NEG_REQ_ACK_PENDING; + hddLog(LOG1, "%s: HDD_GO_NEG_REQ_ACK_PENDING.", __func__); + } + } + + if (eHAL_STATUS_SUCCESS != + sme_sendAction( WLAN_HDD_GET_HAL_CTX(pAdapter), + sessionId, buf, len, wait, noack)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_sendAction returned fail", __func__); + goto err; + } + } + else if( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || + ( WLAN_HDD_P2P_GO == pAdapter->device_mode ) + ) + { + if( VOS_STATUS_SUCCESS != + WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + buf, len, 0 ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SendAction returned fail", __func__); + goto err; + } + } + + return 0; +err: + if(!noack) + { + hdd_sendActionCnf( pAdapter, FALSE ); + } + return 0; +err_rem_channel: + *cookie = (uintptr_t)cfgState; + cfg80211_mgmt_tx_status( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pAdapter->dev->ieee80211_ptr, +#else + pAdapter->dev, +#endif + *cookie, buf, len, FALSE, GFP_KERNEL ); + EXIT(); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +int wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, + struct cfg80211_mgmt_tx_params *params, u64 *cookie) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct wireless_dev *wdev, + struct ieee80211_channel *chan, bool offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + enum nl80211_channel_type channel_type, + bool channel_type_valid, +#endif + unsigned int wait, + const u8 *buf, size_t len, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +int wlan_hdd_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, bool no_cck, + bool dont_wait_for_ack, u64 *cookie ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +int wlan_hdd_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 ) +#else +int wlan_hdd_mgmt_tx( struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie ) +#endif //LINUX_VERSION_CODE +{ + int ret; + + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + ret = __wlan_hdd_mgmt_tx(wiphy, wdev, params->chan, params->offchan, + params->wait, params->buf, params->len, + params->no_cck, params->dont_wait_for_ack, + cookie); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + ret = __wlan_hdd_mgmt_tx(wiphy, wdev, + chan, offchan, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + channel_type, + channel_type_valid, +#endif + wait, + buf, len, no_cck, + dont_wait_for_ack, cookie); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan, + channel_type, channel_type_valid, wait, + buf, len, no_cck, + dont_wait_for_ack, cookie); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, offchan, + channel_type, channel_type_valid, wait, + buf, len, cookie); +#else + ret = __wlan_hdd_mgmt_tx(wiphy, dev, chan, channel_type, + channel_type_valid, buf, len, cookie); +#endif //LINUX_VERSION_CODE + vos_ssr_unprotect(__func__); + + return ret; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + u64 cookie_dummy; + cookie_dummy = cookie << 32; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, NO_SESSION, cookie_dummy)); + return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, wdev, cookie ); +} +#else +int __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie) +{ + u64 cookie_dummy; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + cookie_dummy = cookie << 32; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT, + pAdapter->sessionId, cookie_dummy)); + return wlan_hdd_cfg80211_cancel_remain_on_channel( wiphy, dev, cookie ); +} +#endif +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct wireless_dev *wdev, + u64 cookie) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, wdev, cookie); + vos_ssr_unprotect(__func__); + + return ret; +} +#else +int wlan_hdd_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, + struct net_device *dev, + u64 cookie) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_mgmt_tx_cancel_wait(wiphy, dev, cookie); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif +#endif + +void hdd_sendActionCnf( hdd_adapter_t *pAdapter, tANI_BOOLEAN actionSendSuccess ) +{ + hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + cfgState->actionFrmState = HDD_IDLE; + + if( NULL == cfgState->buf ) + { + return; + } + if (cfgState->is_go_neg_ack_received) + { + cfgState->is_go_neg_ack_received = 0; + /* Sometimes its possible that host may receive the ack for GO + * negotiation req after sending go negotaition confirmation, + * in such case drop the ack received for the go negotiation + * request, so that supplicant waits for the confirmation ack + * from firmware. + */ + hddLog( LOG1, FL("Drop the pending ack received in cfgState->actionFrmState %d"), + cfgState->actionFrmState); + return; + } + + hddLog( LOG1, "Send Action cnf, actionSendSuccess %d", actionSendSuccess); + + /* If skb is NULL it means this packet was received on CFG80211 interface + * else it was received on Monitor interface */ + if( cfgState->skb == NULL ) + { + /* + * buf is the same pointer it passed us to send. Since we are sending + * it through control path, we use different buffers. + * In case of mac80211, they just push it to the skb and pass the same + * data while sending tx ack status. + * */ + cfg80211_mgmt_tx_status( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + pAdapter->dev->ieee80211_ptr, +#else + pAdapter->dev, +#endif + cfgState->action_cookie, + cfgState->buf, cfgState->len, actionSendSuccess, GFP_KERNEL ); + vos_mem_free( cfgState->buf ); + cfgState->buf = NULL; + } + else + { + hdd_adapter_t* pMonAdapter = + hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR ); + if( pMonAdapter == NULL ) + { + hddLog( LOGE, "Not able to get Monitor Adapter"); + cfgState->skb = NULL; + vos_mem_free( cfgState->buf ); + cfgState->buf = NULL; + complete(&pAdapter->tx_action_cnf_event); + return; + } + /* Send TX completion feedback over monitor interface. */ + hdd_wlan_tx_complete( pMonAdapter, cfgState, actionSendSuccess ); + cfgState->skb = NULL; + vos_mem_free( cfgState->buf ); + cfgState->buf = NULL; + /* Look for the next Mgmt packet to TX */ + hdd_mon_tx_mgmt_pkt(pAdapter); + } + complete(&pAdapter->tx_action_cnf_event); +} + +/** + * hdd_setP2pNoa + * + *FUNCTION: + * This function is called from hdd_hostapd_ioctl function when Driver + * get P2P_SET_NOA comand from wpa_supplicant using private ioctl + * + *LOGIC: + * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param dev Pointer to net device structure + * @param command Pointer to command + * + * @return Status + */ + +int hdd_setP2pNoa( struct net_device *dev, tANI_U8 *command ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tP2pPsConfig NoA; + int count, duration, start_time; + char *param; + tANI_U8 ret = 0; + + param = strnchr(command, strlen(command), ' '); + if (param == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: strnchr failed to find delimeter",__func__); + return -EINVAL; + } + param++; + ret = sscanf(param, "%d %d %d", &count, &start_time, &duration); + if (ret < 3) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: P2P_SET GO NoA: fail to read param " + "count=%d duration=%d interval=%d ", + __func__, count, start_time, duration); + return -EINVAL; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_SET GO NoA: count=%d duration=%d interval=%d", + __func__, count, start_time, duration); + duration = MS_TO_MUS(duration); + /* PS Selection + * Periodic NoA (2) + * Single NOA (4) + */ + NoA.opp_ps = 0; + NoA.ctWindow = 0; + if (count == 1) + { + NoA.duration = 0; + NoA.single_noa_duration = duration; + NoA.psSelection = P2P_POWER_SAVE_TYPE_SINGLE_NOA; + } + else + { + NoA.duration = duration; + NoA.single_noa_duration = 0; + NoA.psSelection = P2P_POWER_SAVE_TYPE_PERIODIC_NOA; + } + NoA.interval = MS_TO_MUS(100); + NoA.count = count; + NoA.sessionid = pAdapter->sessionId; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d " + "PsSelection %x", __func__, NoA.opp_ps, + NoA.ctWindow, NoA.duration, NoA.interval, + NoA.count, NoA.single_noa_duration, + NoA.psSelection); + + sme_p2pSetPs(hHal, &NoA); + return status; +} + +/** + * hdd_setP2pOpps + * + *FUNCTION: + * This function is called from hdd_hostapd_ioctl function when Driver + * get P2P_SET_PS comand from wpa_supplicant using private ioctl + * + *LOGIC: + * Fill NoA Struct According to P2P Power save Option and Pass it to SME layer + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param dev Pointer to net device structure + * @param command Pointer to command + * + * @return Status + */ + +int hdd_setP2pOpps( struct net_device *dev, tANI_U8 *command ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tP2pPsConfig NoA; + char *param; + int legacy_ps, opp_ps, ctwindow; + tANI_U8 ret = 0; + + param = strnchr(command, strlen(command), ' '); + if (param == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: strnchr failed to find delimeter",__func__); + return -EINVAL; + } + param++; + ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow); + if (ret < 3) + { + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: P2P_SET GO PS: fail to read param " + " legacy_ps=%d opp_ps=%d ctwindow=%d ", + __func__, legacy_ps, opp_ps, ctwindow); + return -EINVAL; + } + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d", + __func__, legacy_ps, opp_ps, ctwindow); + + /* PS Selection + * Opportunistic Power Save (1) + */ + + /* From wpa_cli user need to use separate command to set ctWindow and Opps + * When user want to set ctWindow during that time other parameters + * values are coming from wpa_supplicant as -1. + * Example : User want to set ctWindow with 30 then wpa_cli command : + * P2P_SET ctwindow 30 + * Command Received at hdd_hostapd_ioctl is as below: + * P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30) + */ + if (ctwindow != -1) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Opportunistic Power Save is %s", + (TRUE == pAdapter->ops) ? "Enable" : "Disable" ); + + if (ctwindow != pAdapter->ctw) + { + pAdapter->ctw = ctwindow; + + if(pAdapter->ops) + { + NoA.opp_ps = pAdapter->ops; + NoA.ctWindow = pAdapter->ctw; + NoA.duration = 0; + NoA.single_noa_duration = 0; + NoA.interval = 0; + NoA.count = 0; + NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC; + NoA.sessionid = pAdapter->sessionId; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d " + "PsSelection %x", __func__, NoA.opp_ps, + NoA.ctWindow, NoA.duration, NoA.interval, + NoA.count, NoA.single_noa_duration, + NoA.psSelection); + + sme_p2pSetPs(hHal, &NoA); + } + return 0; + } + } + + if (opp_ps != -1) + { + pAdapter->ops = opp_ps; + + if ((opp_ps != -1) && (pAdapter->ctw)) + { + NoA.opp_ps = opp_ps; + NoA.ctWindow = pAdapter->ctw; + NoA.duration = 0; + NoA.single_noa_duration = 0; + NoA.interval = 0; + NoA.count = 0; + NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC; + NoA.sessionid = pAdapter->sessionId; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d " + "PsSelection %x", __func__, NoA.opp_ps, + NoA.ctWindow, NoA.duration, NoA.interval, + NoA.count, NoA.single_noa_duration, + NoA.psSelection); + + sme_p2pSetPs(hHal, &NoA); + } + } + return status; +} + +int hdd_setP2pPs( struct net_device *dev, void *msgData ) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tP2pPsConfig NoA; + p2p_app_setP2pPs_t *pappNoA = (p2p_app_setP2pPs_t *) msgData; + + NoA.opp_ps = pappNoA->opp_ps; + NoA.ctWindow = pappNoA->ctWindow; + NoA.duration = pappNoA->duration; + NoA.interval = pappNoA->interval; + NoA.count = pappNoA->count; + NoA.single_noa_duration = pappNoA->single_noa_duration; + NoA.psSelection = pappNoA->psSelection; + NoA.sessionid = pAdapter->sessionId; + + sme_p2pSetPs(hHal, &NoA); + return status; +} + +static tANI_U8 wlan_hdd_get_session_type( enum nl80211_iftype type ) +{ + tANI_U8 sessionType; + + switch( type ) + { + case NL80211_IFTYPE_AP: + sessionType = WLAN_HDD_SOFTAP; + break; + case NL80211_IFTYPE_P2P_GO: + sessionType = WLAN_HDD_P2P_GO; + break; + case NL80211_IFTYPE_P2P_CLIENT: + sessionType = WLAN_HDD_P2P_CLIENT; + break; + case NL80211_IFTYPE_STATION: + sessionType = WLAN_HDD_INFRA_STATION; + break; + case NL80211_IFTYPE_MONITOR: + sessionType = WLAN_HDD_MONITOR; + break; + default: + sessionType = WLAN_HDD_INFRA_STATION; + break; + } + + return sessionType; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) +struct wireless_dev* __wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, const char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +struct wireless_dev* __wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +struct net_device* __wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#else +int __wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#endif +{ + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + hdd_adapter_t *pAdapter = NULL; + hdd_scaninfo_t *pScanInfo = NULL; + int ret = 0; + + ENTER(); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + return ERR_PTR(-EINVAL); +#else + return -EAGAIN; +#endif + } + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_ADD_VIRTUAL_INTF, NO_SESSION, type)); + if (WLAN_HDD_P2P_CLIENT != wlan_hdd_get_session_type(type) && + WLAN_HDD_INFRA_STATION != wlan_hdd_get_session_type(type) && + hdd_get_adapter(pHddCtx, wlan_hdd_get_session_type(type)) != NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Interface type %d already exists. Two" + "interfaces of same type are not supported currently.",__func__, type); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + return ERR_PTR(-EINVAL); +#else + return -EAGAIN; +#endif + } + + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + pScanInfo = &pHddCtx->scan_info; + if ((pScanInfo != NULL) && (pAdapter != NULL) && + (pHddCtx->scan_info.mScanPending)) + { + hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Abort Scan while adding virtual interface",__func__); + } + + pAdapter = NULL; + if (pHddCtx->cfg_ini->isP2pDeviceAddrAdministrated && + ((NL80211_IFTYPE_P2P_GO == type) || + (NL80211_IFTYPE_P2P_CLIENT == type))) + { + /* Generate the P2P Interface Address. this address must be + * different from the P2P Device Address. + */ + v_MACADDR_t p2pDeviceAddress = pHddCtx->p2pDeviceAddress; + p2pDeviceAddress.bytes[4] ^= 0x80; + pAdapter = hdd_open_adapter( pHddCtx, + wlan_hdd_get_session_type(type), + name, p2pDeviceAddress.bytes, + VOS_TRUE ); + } + else + { + pAdapter = hdd_open_adapter( pHddCtx, wlan_hdd_get_session_type(type), + name, wlan_hdd_get_intf_addr(pHddCtx), VOS_TRUE ); + } + + if( NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + return ERR_PTR(-EINVAL); +#else + return -EINVAL; +#endif + } + + if ((type == NL80211_IFTYPE_P2P_CLIENT) || + (type == NL80211_IFTYPE_P2P_GO)) + { + /* Below function Notifies Mode change and + * If p2p session is detected then invokes functionality to + * Teardown TDLS links and disable offchannel if any. Since + * TDLS is not supported in case of concurrency. + */ + hddLog(LOG1, FL("Interface type = %d"), type); + hdd_tdls_notify_mode_change(pAdapter, pHddCtx); + } + + EXIT(); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + return pAdapter->dev->ieee80211_ptr; +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + return pAdapter->dev; +#else + return 0; +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, const char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +struct wireless_dev* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) +struct net_device* wlan_hdd_add_virtual_intf( + struct wiphy *wiphy, char *name, enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#else +int wlan_hdd_add_virtual_intf( struct wiphy *wiphy, char *name, + enum nl80211_iftype type, + u32 *flags, struct vif_params *params ) +#endif +{ +#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))) + struct wireless_dev* wdev; +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + struct net_device* ndev; +#else + int ret; +#endif + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + wdev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params); + vos_ssr_unprotect(__func__); + return wdev; +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) + ndev = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params); + vos_ssr_unprotect(__func__); + return ndev; +#else + ret = __wlan_hdd_add_virtual_intf(wiphy, name, type, flags, params); + vos_ssr_unprotect(__func__); + return ret; +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev ) +#else +int __wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ) +#endif +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct net_device *dev = wdev->netdev; +#endif + hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev ); + hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int status; + + ENTER(); + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, + TRACE_CODE_HDD_DEL_VIRTUAL_INTF, + pAdapter->sessionId, pAdapter->device_mode)); + hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", + __func__,pVirtAdapter->device_mode); + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + return status; + } + + wlan_hdd_release_intf_addr( pHddCtx, + pVirtAdapter->macAddressCurrent.bytes ); + + hdd_stop_adapter( pHddCtx, pVirtAdapter, VOS_TRUE); + hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE ); + EXIT(); + return 0; +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) +int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct wireless_dev *wdev ) +#else +int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ) +#endif +{ + int ret; + + vos_ssr_protect(__func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + ret = __wlan_hdd_del_virtual_intf(wiphy, wdev); +#else + ret = __wlan_hdd_del_virtual_intf(wiphy, dev); +#endif + vos_ssr_unprotect(__func__); + + return ret; +} + +void hdd_sendMgmtFrameOverMonitorIface( hdd_adapter_t *pMonAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType ) +{ + //Indicate a Frame over Monitor Intf. + int rxstat; + struct sk_buff *skb = NULL; + int needed_headroom = 0; + int flag = HDD_RX_FLAG_IV_STRIPPED | HDD_RX_FLAG_DECRYPTED | + HDD_RX_FLAG_MMIC_STRIPPED; +#ifdef WLAN_OPEN_SOURCE +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + hdd_context_t* pHddCtx = (hdd_context_t*)(pMonAdapter->pHddCtx); +#endif +#endif + hddLog( LOG1, FL("Indicate Frame over Monitor Intf")); + + if (NULL == pbFrames) + { + hddLog(LOGE, FL("NULL frame pointer")); + return; + } + + /* room for the radiotap header based on driver features + * 1 Byte for RADIO TAP Flag, 1 Byte padding and 2 Byte for + * RX flags. + * */ + needed_headroom = sizeof(struct ieee80211_radiotap_header) + 4; + + //alloc skb here + skb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC); + if (unlikely(NULL == skb)) + { + hddLog( LOGW, FL("Unable to allocate skb")); + return; + } + skb_reserve(skb, VPKT_SIZE_BUFFER); + if (unlikely(skb_headroom(skb) < nFrameLength)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "HDD [%d]: Insufficient headroom, " + "head[%p], data[%p], req[%d]", + __LINE__, skb->head, skb->data, nFrameLength); + kfree_skb(skb); + return ; + } + // actually push the data + memcpy(skb_push(skb, nFrameLength), pbFrames, nFrameLength); + /* prepend radiotap information */ + if( 0 != hdd_wlan_add_rx_radiotap_hdr( skb, needed_headroom, flag ) ) + { + hddLog( LOGE, FL("Not Able Add Radio Tap")); + //free skb + kfree_skb(skb); + return ; + } + + skb_reset_mac_header( skb ); + skb->dev = pMonAdapter->dev; + skb->protocol = eth_type_trans( skb, skb->dev ); + skb->ip_summed = CHECKSUM_NONE; +#ifdef WLAN_OPEN_SOURCE +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION, + WIFI_POWER_EVENT_WAKELOCK_HOLD_RX); +#endif +#endif + rxstat = netif_rx_ni(skb); + if( NET_RX_SUCCESS == rxstat ) + { + hddLog( LOG1, FL("Success")); + } + else + hddLog( LOGE, FL("Failed %d"), rxstat); + + return ; +} + +void __hdd_indicate_mgmt_frame(hdd_adapter_t *pAdapter, + tANI_U32 nFrameLength, + tANI_U8* pbFrames, + tANI_U8 frameType, + tANI_U32 rxChan, + tANI_S8 rxRssi) +{ + tANI_U16 freq; + tANI_U16 extend_time; + tANI_U8 type = 0; + tANI_U8 subType = 0; + tActionFrmType actionFrmType; + hdd_cfg80211_state_t *cfgState = NULL; + hdd_scaninfo_t *pScanInfo = NULL; + hdd_context_t *pHddCtx = NULL; + VOS_STATUS status; + hdd_remain_on_chan_ctx_t* pRemainChanCtx = NULL; + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Frame Type = %d Frame Length = %d"), + frameType, nFrameLength); + + if (NULL == pAdapter) + { + hddLog(LOGE, FL("pAdapter is NULL")); + return; + } + + if (0 == nFrameLength) + { + hddLog(LOGE, FL("Frame Length is Invalid ZERO")); + return; + } + + if (NULL == pbFrames) + { + hddLog(LOGE, FL("pbFrames is NULL")); + return; + } + + type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]); + subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]); + + /* Get pAdapter from Destination mac address of the frame */ + if ((type == SIR_MAC_MGMT_FRAME) && + (subType != SIR_MAC_MGMT_PROBE_REQ) && + !vos_is_macaddr_broadcast( + (v_MACADDR_t *)&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET])) + { + pAdapter = hdd_get_adapter_by_macaddr( WLAN_HDD_GET_CTX(pAdapter), + &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET]); + if (NULL == pAdapter) + { + /* Under assumtion that we don't receive any action frame + * with BCST as destination we dropping action frame + */ + hddLog(VOS_TRACE_LEVEL_FATAL,"pAdapter for action frame is NULL Macaddr = " + MAC_ADDRESS_STR , + MAC_ADDR_ARRAY(&pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET])); + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Frame Type = %d Frame Length = %d" + " subType = %d",__func__,frameType,nFrameLength,subType); + return; + } + } + + + if (NULL == pAdapter->dev) + { + hddLog( LOGE, FL("pAdapter->dev is NULL")); + return; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + hddLog( LOGE, FL("pAdapter has invalid magic")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD Context Null Pointer", __func__); + return; + } + + if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode )) + { + hdd_adapter_t *pMonAdapter = + hdd_get_mon_adapter( WLAN_HDD_GET_CTX(pAdapter) ); + + if (NULL != pMonAdapter) + { + hddLog( LOG1, FL("Indicate Frame over Monitor Interface")); + hdd_sendMgmtFrameOverMonitorIface( pMonAdapter, nFrameLength, + pbFrames, frameType); + return; + } + } + + //Channel indicated may be wrong. TODO + //Indicate an action frame. + if( rxChan <= MAX_NO_OF_2_4_CHANNELS ) + { + freq = ieee80211_channel_to_frequency( rxChan, + IEEE80211_BAND_2GHZ); + } + else + { + freq = ieee80211_channel_to_frequency( rxChan, + IEEE80211_BAND_5GHZ); + } + + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if ((type == SIR_MAC_MGMT_FRAME) && + (subType == SIR_MAC_MGMT_ACTION)) + { + if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_PUBLIC_ACTION_FRAME) + { + // public action frame + if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == SIR_MAC_ACTION_VENDOR_SPECIFIC) && + vos_mem_compare(&pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE)) + // P2P action frames + { + actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; + hddLog(LOG1, "Rx Action Frame %u", actionFrmType); +#ifdef WLAN_FEATURE_P2P_DEBUG + if(actionFrmType >= MAX_P2P_ACTION_FRAME_TYPE) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] unknown[%d] <--- OTA", + actionFrmType); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P] %s <--- OTA", + p2p_action_frame_type[actionFrmType]); + if( (actionFrmType == WLAN_HDD_PROV_DIS_REQ) && + (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_PROCESS; + hddLog(LOGE,"[P2P State]Inactive state to " + "GO negotiation progress state"); + } + else if( (actionFrmType == WLAN_HDD_GO_NEG_CNF) && + (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; + hddLog(LOGE,"[P2P State]GO negotiation progress to " + "GO negotiation completed state"); + } + else if( (actionFrmType == WLAN_HDD_INVITATION_REQ) && + (globalP2PConnectionStatus == P2P_NOT_ACTIVE) ) + { + globalP2PConnectionStatus = P2P_GO_NEG_COMPLETED; + hddLog(LOGE,"[P2P State]Inactive state to GO negotiation" + " completed state Autonomous GO formation"); + } + } +#endif + mutex_lock(&pHddCtx->roc_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + + if (pRemainChanCtx != NULL && VOS_TIMER_STATE_RUNNING + == vos_timer_getCurrentState(&pRemainChanCtx->hdd_remain_on_chan_timer)) + { + if ( actionFrmType == WLAN_HDD_GO_NEG_REQ || + actionFrmType == WLAN_HDD_GO_NEG_RESP || + actionFrmType == WLAN_HDD_INVITATION_REQ || + actionFrmType == WLAN_HDD_DEV_DIS_REQ || + actionFrmType == WLAN_HDD_PROV_DIS_REQ ) + { + hddLog( LOG1, "Extend RoC timer on reception of" + " Action Frame"); + if ((actionFrmType == WLAN_HDD_GO_NEG_REQ) + || (actionFrmType == WLAN_HDD_GO_NEG_RESP)) + extend_time = 2 * ACTION_FRAME_DEFAULT_WAIT; + else + extend_time = ACTION_FRAME_DEFAULT_WAIT; + if (completion_done(&pAdapter->rem_on_chan_ready_event)) + { + if(!VOS_IS_STATUS_SUCCESS(vos_timer_stop( + &pRemainChanCtx->hdd_remain_on_chan_timer))) + { + hddLog( LOGE, FL( + "Failed to stop hdd_remain_on_chan_timer")); + } + status = vos_timer_start( + &pRemainChanCtx->hdd_remain_on_chan_timer, + extend_time); + if (status != VOS_STATUS_SUCCESS) + { + hddLog( LOGE, "ROC timer start failed"); + } + } + else + { + // Buffer Packet + if (pRemainChanCtx->action_pkt_buff.frame_length == 0) + { + pRemainChanCtx->action_pkt_buff.frame_length = + nFrameLength; + pRemainChanCtx->action_pkt_buff.freq = freq; + pRemainChanCtx->action_pkt_buff.frame_ptr + = vos_mem_malloc(nFrameLength); + vos_mem_copy( + pRemainChanCtx->action_pkt_buff.frame_ptr, + pbFrames, nFrameLength); + hddLog( LOGE,"%s:" + "Action Pkt Cached successfully !!!", __func__); + } + else + { + hddLog( LOGE,"%s:" + "Frames are pending. dropping frame !!!", + __func__); + } + mutex_unlock(&pHddCtx->roc_lock); + return; + } + } + } + if (pRemainChanCtx != NULL && + vos_timer_is_initialized( + &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer) && + VOS_TIMER_STATE_RUNNING != vos_timer_getCurrentState( + &cfgState->remain_on_chan_ctx->hdd_remain_on_chan_timer)) + hddLog( LOG1, "%s:" + "Rcvd action frame after timer expired ", __func__); + + mutex_unlock(&pHddCtx->roc_lock); + + if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) && + (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) || + ((actionFrmType == WLAN_HDD_GO_NEG_RESP) && + (cfgState->actionFrmState == HDD_GO_NEG_REQ_ACK_PENDING))) + { + hddLog(LOG1, "%s: ACK_PENDING and But received RESP for Action frame ", + __func__); + cfgState->is_go_neg_ack_received = 1; + + hdd_sendActionCnf(pAdapter, TRUE); + } + } +#ifdef FEATURE_WLAN_TDLS + else if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_PUBLIC_ACTION_TDLS_DISC_RESP) + { + u8 *mac = &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6]; + hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] TDLS Discovery Response," MAC_ADDRESS_STR " RSSI[%d] <--- OTA", + MAC_ADDR_ARRAY(mac),rxRssi); + + wlan_hdd_tdls_set_rssi(pAdapter, mac, rxRssi); + wlan_hdd_tdls_recv_discovery_resp(pAdapter, mac); + } +#endif + } + + pScanInfo = &pHddCtx->scan_info; + if ((pScanInfo != NULL) && (pHddCtx->scan_info.mScanPending)) + { + hddLog(LOGE,"Action frame received when Scanning is in" + " progress. Abort Scan."); + hdd_abort_mac_scan(pAdapter->pHddCtx, + pScanInfo->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + + if(pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_TDLS_ACTION_FRAME) + { + actionFrmType = pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1]; + if(actionFrmType >= MAX_TDLS_ACTION_FRAME_TYPE) + { + hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] Action type[%d] <--- OTA", + actionFrmType); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO,"[TDLS] %s <--- OTA", + tdls_action_frame_type[actionFrmType]); + } + vos_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS, + SIR_MAC_ACTION_RX, SIR_MAC_MGMT_ACTION, + actionFrmType, &pbFrames[WLAN_HDD_80211_FRM_DA_OFFSET+6]); + } + + if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&& + (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) ) + { + sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, + pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId); + } + } + + //Indicate Frame Over Normal Interface + hddLog( LOG1, FL("Indicate Frame over NL80211 Interface")); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, pbFrames, + nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) + cfg80211_rx_mgmt(pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, pbFrames, + nFrameLength, NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + cfg80211_rx_mgmt( pAdapter->dev->ieee80211_ptr, freq, rxRssi * 100, + pbFrames, nFrameLength, + GFP_ATOMIC ); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) + cfg80211_rx_mgmt( pAdapter->dev, freq, rxRssi * 100, + pbFrames, nFrameLength, + GFP_ATOMIC ); +#else + cfg80211_rx_mgmt( pAdapter->dev, freq, + pbFrames, nFrameLength, + GFP_ATOMIC ); +#endif //LINUX_VERSION_CODE +} + +/* + * ieee80211_add_rx_radiotap_header - add radiotap header + */ +static int hdd_wlan_add_rx_radiotap_hdr ( + struct sk_buff *skb, int rtap_len, int flag ) +{ + u8 rtap_temp[20] = {0}; + struct ieee80211_radiotap_header *rthdr; + unsigned char *pos; + u16 rx_flags = 0; + + rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]); + + /* radiotap header, set always present flags */ + rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | + (1 << IEEE80211_RADIOTAP_RX_FLAGS)); + rthdr->it_len = cpu_to_le16(rtap_len); + + pos = (unsigned char *) (rthdr + 1); + + /* the order of the following fields is important */ + + /* IEEE80211_RADIOTAP_FLAGS */ + *pos = 0; + pos++; + + /* IEEE80211_RADIOTAP_RX_FLAGS: Length 2 Bytes */ + /* ensure 2 byte alignment for the 2 byte field as required */ + if ((pos - (u8 *)rthdr) & 1) + pos++; + put_unaligned_le16(rx_flags, pos); + pos += 2; + + // actually push the data + memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len); + + return 0; +} + +static void hdd_wlan_tx_complete( hdd_adapter_t* pAdapter, + hdd_cfg80211_state_t* cfgState, + tANI_BOOLEAN actionSendSuccess ) +{ + struct ieee80211_radiotap_header *rthdr; + unsigned char *pos; + struct sk_buff *skb = cfgState->skb; +#ifdef WLAN_OPEN_SOURCE +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + hdd_context_t *pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); +#endif +#endif + + /* 2 Byte for TX flags and 1 Byte for Retry count */ + u32 rtHdrLen = sizeof(*rthdr) + 3; + + u8 *data; + + /* We have to return skb with Data starting with MAC header. We have + * copied SKB data starting with MAC header to cfgState->buf. We will pull + * entire skb->len from skb and then we will push cfgState->buf to skb + * */ + if( NULL == skb_pull(skb, skb->len) ) + { + hddLog( LOGE, FL("Not Able to Pull %d byte from skb"), skb->len); + kfree_skb(cfgState->skb); + return; + } + + data = skb_push( skb, cfgState->len ); + + if (data == NULL) + { + hddLog( LOGE, FL("Not Able to Push %zu byte to skb"), cfgState->len); + kfree_skb( cfgState->skb ); + return; + } + + memcpy( data, cfgState->buf, cfgState->len ); + + /* send frame to monitor interfaces now */ + if( skb_headroom(skb) < rtHdrLen ) + { + hddLog( LOGE, FL("No headroom for rtap header")); + kfree_skb(cfgState->skb); + return; + } + + rthdr = (struct ieee80211_radiotap_header*) skb_push( skb, rtHdrLen ); + + memset( rthdr, 0, rtHdrLen ); + rthdr->it_len = cpu_to_le16( rtHdrLen ); + rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | + (1 << IEEE80211_RADIOTAP_DATA_RETRIES) + ); + + pos = (unsigned char *)( rthdr+1 ); + + // Fill TX flags + *pos = actionSendSuccess; + pos += 2; + + // Fill retry count + *pos = 0; + pos++; + + skb_set_mac_header( skb, 0 ); + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + memset( skb->cb, 0, sizeof( skb->cb ) ); +#ifdef WLAN_OPEN_SOURCE +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION, + WIFI_POWER_EVENT_WAKELOCK_HOLD_RX); +#endif +#endif + if (in_interrupt()) + netif_rx( skb ); + else + netif_rx_ni( skb ); + + /* Enable Queues which we have disabled earlier */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues( pAdapter->dev ); + +} + +void __hdd_p2p_roc_work_queue(struct work_struct *work) +{ + hdd_adapter_t *pAdapter = container_of(to_delayed_work(work), hdd_adapter_t, roc_work); + hddLog( VOS_TRACE_LEVEL_INFO, FL("%s: "), __func__); + wlan_hdd_p2p_start_remain_on_channel(pAdapter); + return; +} + +void hdd_p2p_roc_work_queue(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_p2p_roc_work_queue(work); + vos_ssr_unprotect(__func__); + return; +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_scan.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_scan.c new file mode 100644 index 000000000000..3cc5b1d19705 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_scan.c @@ -0,0 +1,1332 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_scan.c + + \brief WLAN Host Device Driver implementation + + + ========================================================================*/ + +/**========================================================================= + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/5/09 Shailender Created module. + + ==========================================================================*/ + /* To extract the Scan results */ + +/* Add a stream event */ + +#include +#include +#include +#include +#include +#include +#ifdef WLAN_BTAMP_FEATURE +#include "bap_hdd_misc.h" +#endif + +#include +#include +#include + +#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00" +#define WEXT_CSCAN_HEADER_SIZE 12 +#define WEXT_CSCAN_SSID_SECTION 'S' +#define WEXT_CSCAN_CHANNEL_SECTION 'C' +#define WEXT_CSCAN_NPROBE_SECTION 'N' +#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A' +#define WEXT_CSCAN_PASV_DWELL_SECTION 'P' +#define WEXT_CSCAN_HOME_DWELL_SECTION 'H' +#define WEXT_CSCAN_TYPE_SECTION 'T' +#define WEXT_CSCAN_PENDING_SECTION 'O' +#define WEXT_CSCAN_TYPE_DEFAULT 0 +#define WEXT_CSCAN_TYPE_PASSIVE 1 +#define WEXT_CSCAN_PASV_DWELL_TIME 130 +#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250 +#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000 +#define WEXT_CSCAN_HOME_DWELL_TIME 130 +#define MAX_RATES 12 + +#define WEXT_CSCAN_SCAN_DONE_WAIT_TIME 2000 + +typedef struct hdd_scan_info{ + struct net_device *dev; + struct iw_request_info *info; + char *start; + char *end; +} hdd_scan_info_t, *hdd_scan_info_tp; + +static v_S31_t hdd_TranslateABGRateToMbpsRate(v_U8_t *pFcRate) +{ + + /** Slightly more sophisticated processing has to take place here. + Basic rates are rounded DOWN. HT rates are rounded UP.*/ + return ( (( ((v_S31_t) *pFcRate) & 0x007f) * 1000000) / 2); +} + + +static eHalStatus hdd_AddIwStreamEvent(int cmd, int length, char* data, hdd_scan_info_t *pscanInfo, char **last_event, char **current_event ) +{ + struct iw_event event; + + *last_event = *current_event; + vos_mem_zero(&event, sizeof (struct iw_event)); + event.cmd = cmd; + event.u.data.flags = 1; + event.u.data.length = length; + *current_event = iwe_stream_add_point (pscanInfo->info,*current_event, pscanInfo->end, &event, data); + + if(*last_event == *current_event) + { + /* no space to add event */ + hddLog( LOGW, "%s: no space left to add event", __func__); + return -E2BIG; /* Error code, may be E2BIG */ + } + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_GetWPARSNIEs() - + + This function extract the WPA/RSN IE from the Bss descriptor IEs fields + + \param - ieFields - Pointer to the Bss Descriptor IEs. + - ie_length - IE Length. + - last_event -Points to the last event. + - current_event - Points to the + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + +/* Extract the WPA and/or RSN IEs */ +static eHalStatus hdd_GetWPARSNIEs( v_U8_t *ieFields, v_U16_t ie_length, char **last_event, char **current_event, hdd_scan_info_t *pscanInfo ) +{ + v_U8_t eid, elen, *element; + v_U16_t tie_length=0; + + ENTER(); + + element = ieFields; + tie_length = ie_length; + + while( tie_length > 2 && element != NULL ) + { + eid = element[0]; + elen = element[1]; + + /*If element length is greater than total remaining ie length, + *break the loop*/ + if ((elen+2) > tie_length) + break; + + switch(eid) + { + case DOT11F_EID_WPA: + case DOT11F_EID_RSN: +#ifdef FEATURE_WLAN_WAPI + case DOT11F_EID_WAPI: +#endif + if(hdd_AddIwStreamEvent( IWEVGENIE, elen+2, (char*)element, pscanInfo, last_event, current_event ) < 0 ) + return -E2BIG; + break; + + default: + break; + } + + /* Next element */ + tie_length -= (2 + elen); + element += 2 + elen; + } + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_IndicateScanResult() - + + This function returns the scan results to the wpa_supplicant + + \param - scanInfo - Pointer to the scan info structure. + - descriptor - Pointer to the Bss Descriptor. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +#define MAX_CUSTOM_LEN 64 +static eHalStatus hdd_IndicateScanResult(hdd_scan_info_t *scanInfo, tCsrScanResultInfo *scan_result) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(scanInfo->dev) ; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tSirBssDescription *descriptor = &scan_result->BssDescriptor; + struct iw_event event; + char *current_event = scanInfo->start; + char *end = scanInfo->end; + char *last_event; + char *current_pad; + v_U16_t ie_length = 0; + v_U16_t capabilityInfo; + char *modestr; + int error; + char custom[MAX_CUSTOM_LEN]; + char *p; + + hddLog( LOG1, "hdd_IndicateScanResult " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(descriptor->bssId)); + + error = 0; + last_event = current_event; + vos_mem_zero(&event, sizeof (event)); + + /* BSSID */ + event.cmd = SIOCGIWAP; + event.u.ap_addr.sa_family = ARPHRD_ETHER; + vos_mem_copy (event.u.ap_addr.sa_data, descriptor->bssId, + sizeof (descriptor->bssId)); + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_ADDR_LEN); + + if (last_event == current_event) + { + /* no space to add event */ + /* Error code may be E2BIG */ + hddLog(LOGE, "hdd_IndicateScanResult: no space for SIOCGIWAP "); + return -E2BIG; + } + + last_event = current_event; + vos_mem_zero(&event, sizeof (struct iw_event)); + + /* Protocol Name */ + event.cmd = SIOCGIWNAME; + + switch (descriptor->nwType) + { + case eSIR_11A_NW_TYPE: + modestr = "a"; + break; + case eSIR_11B_NW_TYPE: + modestr = "b"; + break; + case eSIR_11G_NW_TYPE: + modestr = "g"; + break; + case eSIR_11N_NW_TYPE: + modestr = "n"; + break; + default: + hddLog( LOGW, "%s: Unknown network type [%d]", + __func__, descriptor->nwType); + modestr = "?"; + break; + } + snprintf(event.u.name, IFNAMSIZ, "IEEE 802.11%s", modestr); + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_CHAR_LEN); + + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWNAME"); + /* Error code, may be E2BIG */ + return -E2BIG; + } + + last_event = current_event; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /*Freq*/ + event.cmd = SIOCGIWFREQ; + + event.u.freq.m = descriptor->channelId; + event.u.freq.e = 0; + event.u.freq.i = 0; + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_FREQ_LEN); + + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWFREQ"); + return -E2BIG; + } + + last_event = current_event; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /* BSS Mode */ + event.cmd = SIOCGIWMODE; + + capabilityInfo = descriptor->capabilityInfo; + + if (SIR_MAC_GET_ESS(capabilityInfo)) + { + event.u.mode = IW_MODE_INFRA; + } + else if (SIR_MAC_GET_IBSS(capabilityInfo)) + { + event.u.mode = IW_MODE_ADHOC; + } + else + { + /* neither ESS or IBSS */ + event.u.mode = IW_MODE_AUTO; + } + + current_event = iwe_stream_add_event(scanInfo->info,current_event, end, + &event, IW_EV_UINT_LEN); + + if (last_event == current_event) + { /* no space to add event */ + hddLog(LOGE, "hdd_IndicateScanResult: no space for SIOCGIWMODE"); + return -E2BIG; + } + /* To extract SSID */ + ie_length = GET_IE_LEN_IN_BSS( descriptor->length ); + + if (ie_length > 0) + { + /* dot11BeaconIEs is a large struct, so we make it static to + avoid stack overflow. This API is only invoked via ioctl, + so it is serialized by the kernel rtnl_lock and hence does + not need to be reentrant */ + static tDot11fBeaconIEs dot11BeaconIEs; + tDot11fIESSID *pDot11SSID; + tDot11fIESuppRates *pDot11SuppRates; + tDot11fIEExtSuppRates *pDot11ExtSuppRates; + tDot11fIEHTCaps *pDot11IEHTCaps; + int numBasicRates = 0; + int maxNumRates = 0; + + pDot11IEHTCaps = NULL; + + dot11fUnpackBeaconIEs ((tpAniSirGlobal) + hHal, (tANI_U8 *) descriptor->ieFields, ie_length, &dot11BeaconIEs); + + pDot11SSID = &dot11BeaconIEs.SSID; + + + if (pDot11SSID->present ) { + last_event = current_event; + vos_mem_zero (&event, sizeof (struct iw_event)); + + event.cmd = SIOCGIWESSID; + event.u.data.flags = 1; + event.u.data.length = scan_result->ssId.length; + current_event = iwe_stream_add_point (scanInfo->info,current_event, end, + &event, (char *)scan_result->ssId.ssId); + + if(last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); + return -E2BIG; + } + } + + if( hdd_GetWPARSNIEs( ( tANI_U8 *) descriptor->ieFields, ie_length, &last_event, ¤t_event, scanInfo ) < 0 ) + { + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWESSID"); + return -E2BIG; + } + + last_event = current_event; + current_pad = current_event + IW_EV_LCP_LEN; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /*Rates*/ + event.cmd = SIOCGIWRATE; + + + pDot11SuppRates = &dot11BeaconIEs.SuppRates; + + if (pDot11SuppRates->present ) + { + int i; + + numBasicRates = pDot11SuppRates->num_rates; + for (i=0; inum_rates; i++) + { + if (0 != (pDot11SuppRates->rates[i] & 0x7F)) + { + event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( + &pDot11SuppRates->rates[i]); + + current_pad = iwe_stream_add_value (scanInfo->info,current_event, + current_pad, end, &event, IW_EV_PARAM_LEN); + } + } + + } + + pDot11ExtSuppRates = &dot11BeaconIEs.ExtSuppRates; + + if (pDot11ExtSuppRates->present ) + { + int i,no_of_rates; + maxNumRates = numBasicRates + pDot11ExtSuppRates->num_rates; + + /* Check to make sure the total number of rates + doesn't exceed IW_MAX_BITRATES */ + + maxNumRates = VOS_MIN(maxNumRates , IW_MAX_BITRATES); + + if((maxNumRates - numBasicRates) > MAX_RATES) + { + no_of_rates = MAX_RATES; + hddLog( LOGW, "Accessing array out of bound that array is pDot11ExtSuppRates->rates "); + } + else + { + no_of_rates = maxNumRates - numBasicRates; + } + for ( i=0; i< no_of_rates ; i++ ) + { + if (0 != (pDot11ExtSuppRates->rates[i] & 0x7F)) + { + event.u.bitrate.value = hdd_TranslateABGRateToMbpsRate ( + &pDot11ExtSuppRates->rates[i]); + + current_pad = iwe_stream_add_value (scanInfo->info,current_event, + current_pad, end, &event, IW_EV_PARAM_LEN); + } + } + } + + + if ((current_pad - current_event) >= IW_EV_LCP_LEN) + { + current_event = current_pad; + } + else + { + if (last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWRATE"); + return -E2BIG; + } + } + + last_event = current_event; + vos_mem_zero (&event, sizeof (struct iw_event)); + + + event.cmd = SIOCGIWENCODE; + + if (SIR_MAC_GET_PRIVACY(capabilityInfo)) + { + event.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + } + else + { + event.u.data.flags = IW_ENCODE_DISABLED; + } + event.u.data.length = 0; + + current_event = iwe_stream_add_point(scanInfo->info,current_event, end, &event, (char *)pDot11SSID->ssid); + + + if(last_event == current_event) + { /* no space to add event + Error code, may be E2BIG */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for SIOCGIWENCODE"); + return -E2BIG; + } + } + + last_event = current_event; + vos_mem_zero( &event, sizeof (struct iw_event)); + + /*RSSI*/ + event.cmd = IWEVQUAL; + event.u.qual.qual = descriptor->rssi; + event.u.qual.noise = descriptor->sinr; + + /*To keep the rssi icon of the connected AP in the scan window + *and the rssi icon of the wireless networks in sync */ + if (( eConnectionState_Associated == + pAdapter->sessionCtx.station.conn_info.connState ) && + ( VOS_TRUE == vos_mem_compare(descriptor->bssId, + pAdapter->sessionCtx.station.conn_info.bssId, + WNI_CFG_BSSID_LEN))) + { + event.u.qual.level = pAdapter->rssi; + } + else + { + event.u.qual.level = VOS_MIN ((descriptor->rssi + descriptor->sinr), 0); + } + + event.u.qual.updated = IW_QUAL_ALL_UPDATED; + + current_event = iwe_stream_add_event(scanInfo->info,current_event, + end, &event, IW_EV_QUAL_LEN); + + if(last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVQUAL"); + return -E2BIG; + } + + + /* AGE */ + event.cmd = IWEVCUSTOM; + p = custom; + p += scnprintf(p, MAX_CUSTOM_LEN, " Age: %lu", + vos_timer_get_system_time() - descriptor->nReceivedTime); + event.u.data.length = p - custom; + current_event = iwe_stream_add_point (scanInfo->info,current_event, end, + &event, custom); + if(last_event == current_event) + { /* no space to add event */ + hddLog( LOGE, "hdd_IndicateScanResult: no space for IWEVCUSTOM (age)"); + return -E2BIG; + } + + scanInfo->start = current_event; + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_processSpoofMacAddrRequest() - + + The function is called from scan completion callback and from + cfg80211 vendor command + + \param - pHddCtx - Pointer to the HDD Context. + + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +void __hdd_processSpoofMacAddrRequest(struct work_struct *work) +{ + hdd_context_t *pHddCtx = + container_of(to_delayed_work(work), hdd_context_t, spoof_mac_addr_work); + + ENTER(); + + if (wlan_hdd_validate_context(pHddCtx)) + return; + + mutex_lock(&pHddCtx->spoofMacAddr.macSpoofingLock); + + if (pHddCtx->spoofMacAddr.isEnabled) { + if (VOS_STATUS_SUCCESS != vos_randomize_n_bytes( + (void *)(&pHddCtx->spoofMacAddr.randomMacAddr.bytes[3]), + VOS_MAC_ADDR_LAST_3_BYTES)) { + pHddCtx->spoofMacAddr.isEnabled = FALSE; + mutex_unlock(&pHddCtx->spoofMacAddr.macSpoofingLock); + hddLog(LOGE, FL("Failed to generate random Mac Addr")); + return; + } + } + + hddLog(LOG1, FL("New Mac Addr Generated "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHddCtx->spoofMacAddr.randomMacAddr.bytes)); + + if (pHddCtx->scan_info.mScanPending != TRUE) + { + pHddCtx->spoofMacAddr.isReqDeferred = FALSE; + hddLog(LOG1, FL("Processing Spoof request now")); + /* Inform SME about spoof mac addr request*/ + if ( eHAL_STATUS_SUCCESS != sme_SpoofMacAddrReq(pHddCtx->hHal, + &pHddCtx->spoofMacAddr.randomMacAddr)) + { + hddLog(LOGE, FL("Sending Spoof request failed - Disable spoofing")); + pHddCtx->spoofMacAddr.isEnabled = FALSE; + } + } else + { + hddLog(LOG1, FL("Scan in Progress. Spoofing Deferred")); + pHddCtx->spoofMacAddr.isReqDeferred = TRUE; + } + + mutex_unlock(&pHddCtx->spoofMacAddr.macSpoofingLock); + + EXIT(); + + return; +} + +void hdd_processSpoofMacAddrRequest(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_processSpoofMacAddrRequest(work); + vos_ssr_unprotect(__func__); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_ScanRequestCallback() - + + The sme module calls this callback function once it finish the scan request + and this function notifies the scan complete event to the wpa_supplicant. + + \param - halHandle - Pointer to the Hal Handle. + - pContext - Pointer to the data context. + - scanId - Scan ID. + - status - CSR Status. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static eHalStatus hdd_ScanRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + struct net_device *dev = (struct net_device *) pContext; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + union iwreq_data wrqu; + int we_event; + char *msg; + + ENTER(); + + hddLog(LOGW,"%s called with halHandle = %p, pContext = %p, scanID = %d," + " returned status = %d", __func__, halHandle, pContext, + (int) scanId, (int) status); + + /* if there is a scan request pending when the wlan driver is unloaded + we may be invoked as SME flushes its pending queue. If that is the + case, the underlying net_device may have already been destroyed, so + do some quick sanity before proceeding */ + if (pAdapter->dev != dev) + { + hddLog(LOGW, "%s: device mismatch %p vs %p", + __func__, pAdapter->dev, dev); + return eHAL_STATUS_SUCCESS; + } + + /* Check the scanId */ + if (pHddCtx->scan_info.scanId != scanId) + { + hddLog(LOGW, "%s called with mismatched scanId pHddCtx->scan_info.scanId = %d " + "scanId = %d ", __func__, (int) pHddCtx->scan_info.scanId, + (int) scanId); + } + + /* Scan is no longer pending */ + pHddCtx->scan_info.mScanPending = VOS_FALSE; + + // notify any applications that may be interested + memset(&wrqu, '\0', sizeof(wrqu)); + we_event = SIOCGIWSCAN; + msg = NULL; + wireless_send_event(dev, we_event, &wrqu, msg); + + EXIT(); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + + return eHAL_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_set_scan() - + + This function process the scan request from the wpa_supplicant + and set the scan request to the SME + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + +int __iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *pwextBuf; + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + struct iw_scan_req *scanReq = (struct iw_scan_req *)extra; + int ret = 0; + + ENTER(); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pwextBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pwextBuf is NULL",__func__); + return -EINVAL; + } +#ifdef WLAN_BTAMP_FEATURE + //Scan not supported when AMP traffic is on. + if( VOS_TRUE == WLANBAP_AmpSessionOn() ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__); + return eHAL_STATUS_SUCCESS; + } +#endif + if(pHddCtx->scan_info.mScanPending == TRUE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__); + return eHAL_STATUS_SUCCESS; + } + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + if (NULL != wrqu->data.pointer) + { + /* set scanType, active or passive */ + if ((IW_SCAN_TYPE_ACTIVE == scanReq->scan_type) || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode)) + { + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } + else + { + scanRequest.scanType = eSIR_PASSIVE_SCAN; + } + + /* set bssid using sockaddr from iw_scan_req */ + vos_mem_copy(scanRequest.bssid, + &scanReq->bssid.sa_data, sizeof(scanRequest.bssid) ); + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { + + if(scanReq->essid_len && + (scanReq->essid_len <= SIR_MAC_MAX_SSID_LENGTH)) { + scanRequest.SSIDs.numOfSSIDs = 1; + scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if(scanRequest.SSIDs.SSIDList) { + scanRequest.SSIDs.SSIDList->SSID.length = scanReq->essid_len; + vos_mem_copy(scanRequest.SSIDs.SSIDList-> SSID.ssId,scanReq->essid,scanReq->essid_len); + } + else + { + scanRequest.SSIDs.numOfSSIDs = 0; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Unable to allocate memory",__func__); + VOS_ASSERT(0); + } + } + else + { + hddLog(LOGE, FL("Invalid essid length : %d"), scanReq->essid_len); + } + } + + /* set min and max channel time */ + scanRequest.minChnTime = scanReq->min_channel_time; + scanRequest.maxChnTime = scanReq->max_channel_time; + + } + else + { + if(pHddCtx->scan_info.scan_mode == eSIR_ACTIVE_SCAN) { + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + } else { + scanRequest.scanType = eSIR_PASSIVE_SCAN; + } + + vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff ); + + /* set min and max channel time to zero */ + scanRequest.minChnTime = 0; + scanRequest.maxChnTime = 0; + } + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + /*Scan all the channels */ + scanRequest.ChannelInfo.numOfChannels = 0; + + scanRequest.ChannelInfo.ChannelList = NULL; + + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + + /* if previous genIE is not NULL, update ScanIE */ + if (0 != pwextBuf->genIE.length) + { + memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) ); + memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata, + pwextBuf->genIE.length ); + pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length; + /* Maximum length of each IE is SIR_MAC_MAX_IE_LENGTH */ + if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length) + { + memcpy( pwextBuf->roamProfile.addIEScan, + pHddCtx->scan_info.scanAddIE.addIEdata, + pHddCtx->scan_info.scanAddIE.length); + pwextBuf->roamProfile.nAddIEScanLength = + pHddCtx->scan_info.scanAddIE.length; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid ScanIE, Length is %d", pwextBuf->genIE.length); + } + /* clear previous genIE after use it */ + memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); + } + + /* push addIEScan in scanRequset if exist */ + if (pHddCtx->scan_info.scanAddIE.addIEdata && + pHddCtx->scan_info.scanAddIE.length) + { + scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length; + scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata; + } + if (pHddCtx->spoofMacAddr.isEnabled && + pHddCtx->cfg_ini->enableMacSpoofing == 1) + { + hddLog(LOG1, FL("MAC Spoofing enabled for current scan")); + /* + * Updating SelfSta Mac Addr in TL which will be used to get + * staidx to fill TxBds for probe request during current scan + */ + status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext, + &pHddCtx->spoofMacAddr.randomMacAddr, + &pAdapter->macAddressCurrent); + + if (status != eHAL_STATUS_SUCCESS) + { + hddLog(LOGE, FL("Failed to update MAC Spoof Addr in TL")); + goto error; + } + } + status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev ); + if (!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:sme_ScanRequest fail %d!!!",__func__, status); + goto error; + } + + pHddCtx->scan_info.mScanPending = TRUE; + pHddCtx->scan_info.sessionId = pAdapter->sessionId; + + pHddCtx->scan_info.scanId = scanId; + +error: + if ((wrqu->data.flags & IW_SCAN_THIS_ESSID) && (scanReq->essid_len)) + vos_mem_free(scanRequest.SSIDs.SSIDList); + + EXIT(); + return status; +} + +int iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_scan(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/**--------------------------------------------------------------------------- + + \brief __iw_get_scan() - + + This function returns the scan results to the wpa_supplicant + + \param - dev - Pointer to the net device. + - info - Pointer to the iw_request_info. + - wrqu - Pointer to the iwreq_data. + - extra - Pointer to the data. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + + +int __iw_get_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tHalHandle hHal; + tCsrScanResultInfo *pScanResult; + eHalStatus status = eHAL_STATUS_SUCCESS; + hdd_scan_info_t scanInfo; + tScanResultHandle pResult; + int i = 0, ret = 0; + + ENTER(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter buffer length %d!!!", + __func__, (wrqu->data.length)?wrqu->data.length:IW_SCAN_MAX_DATA); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if (TRUE == pHddCtx->scan_info.mScanPending) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:mScanPending is TRUE !!!",__func__); + return -EAGAIN; + } + scanInfo.dev = dev; + scanInfo.start = extra; + scanInfo.info = info; + + if (0 == wrqu->data.length) + { + scanInfo.end = extra + IW_SCAN_MAX_DATA; + } + else + { + scanInfo.end = extra + wrqu->data.length; + } + + status = sme_ScanGetResult(hHal,pAdapter->sessionId,NULL,&pResult); + + if (NULL == pResult) + { + // no scan results + hddLog(LOG1,"__iw_get_scan: NULL Scan Result "); + return 0; + } + + pScanResult = sme_ScanResultGetFirst(hHal, pResult); + + while (pScanResult) + { + status = hdd_IndicateScanResult(&scanInfo, pScanResult); + if (0 != status) + { + break; + } + i++; + pScanResult = sme_ScanResultGetNext(hHal, pResult); + } + + sme_ScanResultPurge(hHal, pResult); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit total %d BSS reported !!!",__func__, i); + EXIT(); + return status; +} + +int iw_get_scan(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_scan(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +#if 0 +static eHalStatus hdd_CscanRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + struct net_device *dev = (struct net_device *) pContext; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + union iwreq_data wrqu; + int we_event; + char *msg; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + ENTER(); + + hddLog(LOG1,"%s called with halHandle = %p, pContext = %p, scanID = %d," + " returned status = %d", __func__, halHandle, pContext, + (int) scanId, (int) status); + + /* Check the scanId */ + if (pwextBuf->scanId != scanId) + { + hddLog(LOGW, "%s called with mismatched scanId pWextState->scanId = %d " + "scanId = %d ", __func__, (int) pwextBuf->scanId, + (int) scanId); + } + + /* Scan is no longer pending */ + pwextBuf->mScanPending = VOS_FALSE; + + // notify any applications that may be interested + memset(&wrqu, '\0', sizeof(wrqu)); + we_event = SIOCGIWSCAN; + msg = NULL; + wireless_send_event(dev, we_event, &wrqu, msg); + + vos_status = vos_event_set(&pwextBuf->vosevent); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos_event_set failed!!")); + return VOS_STATUS_E_FAILURE; + } + + EXIT(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + + return eHAL_STATUS_SUCCESS; +} +#endif + +int iw_set_cscan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev) ; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + v_U8_t channelIdx; + + ENTER(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: enter !!!",__func__); + +#ifdef WLAN_BTAMP_FEATURE + //Scan not supported when AMP traffic is on. + if( VOS_TRUE == WLANBAP_AmpSessionOn() ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: No scanning when AMP is on",__func__); + return eHAL_STATUS_SUCCESS; + } +#endif + + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__); + return eHAL_STATUS_SUCCESS; + } + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + if (NULL != wrqu->data.pointer) + { + char *str_ptr = NULL; + tCsrSSIDInfo *SsidInfo = NULL; + int num_ssid = 0; + int i, j, ssid_start; + hdd_scan_pending_option_e scanPendingOption = WEXT_SCAN_PENDING_GIVEUP; + + str_ptr = extra; + + i = WEXT_CSCAN_HEADER_SIZE; + + if( WEXT_CSCAN_PENDING_SECTION == str_ptr[i] ) + { + scanPendingOption = (hdd_scan_pending_option_e)str_ptr[++i]; + ++i; + } + pHddCtx->scan_info.scan_pending_option = scanPendingOption; + + if(pHddCtx->scan_info.mScanPending == TRUE) + { + hddLog(LOG1,"%s: mScanPending is TRUE",__func__); + /* If any scan is pending, just giveup this scan request */ + if(WEXT_SCAN_PENDING_GIVEUP == scanPendingOption) + { + pHddCtx->scan_info.waitScanResult = FALSE; + return eHAL_STATUS_SUCCESS; + } + /* If any scan pending, wait till finish current scan, + and try this scan request when previous scan finish */ + else if(WEXT_SCAN_PENDING_DELAY == scanPendingOption) + { + pHddCtx->scan_info.waitScanResult = TRUE; + vos_event_reset(&pHddCtx->scan_info.scan_finished_event); + if(vos_wait_single_event(&pHddCtx->scan_info.scan_finished_event, + WEXT_CSCAN_SCAN_DONE_WAIT_TIME)) + { + hddLog(LOG1,"%s: Previous SCAN does not finished on time",__func__); + return eHAL_STATUS_SUCCESS; + } + } + /* Piggyback previous scan result */ + else if(WEXT_SCAN_PENDING_PIGGYBACK == scanPendingOption) + { + pHddCtx->scan_info.waitScanResult = TRUE; + return eHAL_STATUS_SUCCESS; + } + } + pHddCtx->scan_info.waitScanResult = FALSE; + + /* Check for scan IE */ + while( WEXT_CSCAN_SSID_SECTION == str_ptr[i] ) + { + /* ssid_len */ + if(str_ptr[++i] != WEXT_CSCAN_CHANNEL_SECTION) + { + /* total number of ssid's */ + num_ssid++; + /* increment length filed */ + i += str_ptr[i] + 1; + } + /* i should be saved and it will be pointing to 'C' */ + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: numSsid %d !!!",__func__, num_ssid); + if( num_ssid ) + { + /* To be fixed in SME and PE: override the number of ssid with 1, + * as SME and PE does not handle multiple SSID in scan request + * */ + scanRequest.SSIDs.numOfSSIDs = num_ssid; + /* Allocate num_ssid tCsrSSIDInfo structure */ + SsidInfo = scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(num_ssid*sizeof(tCsrSSIDInfo)); + if(NULL == scanRequest.SSIDs.SSIDList) { + hddLog(VOS_TRACE_LEVEL_ERROR, "memory alloc failed SSIDInfo buffer"); + return -ENOMEM; + } + + /* copy all the ssid's and their length */ + ssid_start = WEXT_CSCAN_HEADER_SIZE + 1;/* skipping 'S' */ + for(j = 0; j < num_ssid; j++) { + if( SIR_MAC_MAX_SSID_LENGTH < str_ptr[ssid_start]){ + scanRequest.SSIDs.numOfSSIDs -= 1; + } else{ + /* get the ssid length */ + SsidInfo->SSID.length = str_ptr[ssid_start++]; + vos_mem_copy(SsidInfo->SSID.ssId, &str_ptr[ssid_start], SsidInfo->SSID.length); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s", j, SsidInfo->SSID.ssId); + } + /* skipping length */ + ssid_start += str_ptr[ssid_start - 1] + 1; + /* Store next ssid info */ + SsidInfo++; + } + } + + /* Check for Channel IE */ + if ( WEXT_CSCAN_CHANNEL_SECTION == str_ptr[i]) + { + if( str_ptr[++i] == 0 ) + { + scanRequest.ChannelInfo.numOfChannels = 0; + scanRequest.ChannelInfo.ChannelList = NULL; + i++; + } + else { + + /* increment the counter */ + scanRequest.ChannelInfo.numOfChannels = str_ptr[i++]; + /* store temp channel list */ + /* SME expects 1 byte channel content */ + scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(scanRequest.ChannelInfo.numOfChannels * sizeof(v_U8_t)); + if(NULL == scanRequest.ChannelInfo.ChannelList) + { + hddLog(LOGE, "memory alloc failed for channel list creation"); + status = -ENOMEM; + goto exit_point; + } + + for(channelIdx = 0; channelIdx < scanRequest.ChannelInfo.numOfChannels; channelIdx++) + { + /* SCAN request from upper layer has 2 bytes channel */ + scanRequest.ChannelInfo.ChannelList[channelIdx] = (v_U8_t)str_ptr[i]; + i += sizeof(v_U16_t); + } + } + } + + /* Set default */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + scanRequest.minChnTime = 0; + scanRequest.maxChnTime = 0; + + /* Now i is pointing to passive dwell dwell time */ + /* 'P',min dwell time, max dwell time */ + /* next two offsets contain min and max channel time */ + if( WEXT_CSCAN_PASV_DWELL_SECTION == (str_ptr[i]) ) + { + /* No SSID specified, num_ssid == 0, then start paasive scan */ + if (!num_ssid || (eSIR_PASSIVE_SCAN == pHddCtx->scan_info.scan_mode)) + { + scanRequest.scanType = eSIR_PASSIVE_SCAN; + scanRequest.minChnTime = (v_U8_t)str_ptr[++i];//scanReq->min_channel_time; + scanRequest.maxChnTime = (v_U8_t)str_ptr[++i];//scanReq->max_channel_time; + i++; + } + else + { + i += 3; + } + } + + /* H indicates active channel time */ + if( WEXT_CSCAN_HOME_DWELL_SECTION == (str_ptr[i]) ) + { + if (num_ssid || (eSIR_ACTIVE_SCAN == pHddCtx->scan_info.scan_mode)) + { + scanRequest.scanType = eSIR_ACTIVE_SCAN; + scanRequest.minChnTime = str_ptr[++i];//scanReq->min_channel_time; + scanRequest.maxChnTime = str_ptr[++i];//scanReq->max_channel_time; + i++; + } + else + { + i +=3; + } + } + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + pHddCtx->scan_info.mScanPending = TRUE; + + /* if previous genIE is not NULL, update ScanIE */ + if(0 != pwextBuf->genIE.length) + { + memset( &pHddCtx->scan_info.scanAddIE, 0, sizeof(pHddCtx->scan_info.scanAddIE) ); + memcpy( pHddCtx->scan_info.scanAddIE.addIEdata, pwextBuf->genIE.addIEdata, + pwextBuf->genIE.length ); + pHddCtx->scan_info.scanAddIE.length = pwextBuf->genIE.length; + if (SIR_MAC_MAX_IE_LENGTH >= pwextBuf->genIE.length) + { + memcpy( pwextBuf->roamProfile.addIEScan, + pHddCtx->scan_info.scanAddIE.addIEdata, + pHddCtx->scan_info.scanAddIE.length); + pwextBuf->roamProfile.nAddIEScanLength = + pHddCtx->scan_info.scanAddIE.length; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid ScanIE, Length is %d", + pwextBuf->genIE.length); + } + + /* clear previous genIE after use it */ + memset( &pwextBuf->genIE, 0, sizeof(pwextBuf->genIE) ); + } + + /* push addIEScan in scanRequset if exist */ + if (pHddCtx->scan_info.scanAddIE.addIEdata && + pHddCtx->scan_info.scanAddIE.length) + { + scanRequest.uIEFieldLen = pHddCtx->scan_info.scanAddIE.length; + scanRequest.pIEField = pHddCtx->scan_info.scanAddIE.addIEdata; + } + + status = sme_ScanRequest( (WLAN_HDD_GET_CTX(pAdapter))->hHal, + pAdapter->sessionId,&scanRequest, &scanId, &hdd_ScanRequestCallback, dev ); + if( !HAL_STATUS_SUCCESS(status) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: SME scan fail status %d !!!",__func__, status); + pHddCtx->scan_info.mScanPending = FALSE; + status = -EINVAL; + goto exit_point; + } + + pHddCtx->scan_info.scanId = scanId; + pHddCtx->scan_info.sessionId = pAdapter->sessionId; + + } //end of data->pointer + else { + status = -1; + } + +exit_point: + + /* free ssidlist */ + if (scanRequest.SSIDs.SSIDList) + { + vos_mem_free(scanRequest.SSIDs.SSIDList); + } + /* free the channel list */ + if(scanRequest.ChannelInfo.ChannelList) + { + vos_mem_free((void*)scanRequest.ChannelInfo.ChannelList); + } + + EXIT(); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: exit !!!",__func__); + return status; +} + +/* Abort any MAC scan if in progress */ +tSirAbortScanStatus hdd_abort_mac_scan(hdd_context_t* pHddCtx, + tANI_U8 sessionId, + eCsrAbortReason reason) +{ + return sme_AbortMacScan(pHddCtx->hHal, sessionId, reason); +} + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c new file mode 100644 index 000000000000..2cb3b89887b5 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_softap_tx_rx.c @@ -0,0 +1,2229 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**=========================================================================== + + \file wlan_hdd_softap_tx_rx.c + + \brief Linux HDD Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#include +#else +#include +#endif +#include "sapInternal.h" +#include "wlan_hdd_trace.h" +#include "vos_diag_core_event.h" +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function definitions and documenation + -------------------------------------------------------------------------*/ +#if 0 +static void hdd_softap_dump_sk_buff(struct sk_buff * skb) +{ + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head); + //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len); + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], + skb->data[5], skb->data[6], skb->data[7]); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12], + skb->data[13], skb->data[14], skb->data[15]); +} +#endif + +extern void hdd_set_wlan_suspend_mode(bool suspend); + +#define HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ +#define HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST 1 +#define HDD_SAP_TX_STALL_SSR_THRESHOLD 5 +#define HDD_SAP_TX_STALL_RECOVERY_THRESHOLD HDD_SAP_TX_STALL_SSR_THRESHOLD - 2 +#define HDD_SAP_TX_STALL_FATAL_EVENT_THRESHOLD 2 + + +static DEFINE_RATELIMIT_STATE(hdd_softap_tx_timeout_rs, \ + HDD_SAP_TX_TIMEOUT_RATELIMIT_INTERVAL, \ + HDD_SAP_TX_TIMEOUT_RATELIMIT_BURST); + +/**============================================================================ + @brief hdd_softap_traffic_monitor_timeout_handler() - + SAP/P2P GO traffin monitor timeout handler function + If no traffic during programmed time, trigger suspand mode + + @param pUsrData : [in] pointer to hdd context + @return : NONE + ===========================================================================*/ +void hdd_softap_traffic_monitor_timeout_handler( void *pUsrData ) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)pUsrData; + v_TIME_t currentTS; + + ENTER(); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + currentTS = vos_timer_get_system_time(); + if (pHddCtx->cfg_ini->trafficIdleTimeout < + (currentTS - pHddCtx->traffic_monitor.lastFrameTs)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: No Data Activity calling Wlan Suspend", __func__ ); + hdd_set_wlan_suspend_mode(1); + atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 0); + } + else + { + vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer, + pHddCtx->cfg_ini->trafficIdleTimeout); + } + + EXIT(); + return; +} + +VOS_STATUS hdd_start_trafficMonitor( hdd_adapter_t *pAdapter, bool re_init) +{ + + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + if (!re_init) { + status = wlan_hdd_validate_context(pHddCtx); + if (-ENODEV == status) { + return status; + } + } + + if ((pHddCtx->cfg_ini->enableTrafficMonitor) && + (!pHddCtx->traffic_monitor.isInitialized)) + { + atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1); + vos_timer_init(&pHddCtx->traffic_monitor.trafficTimer, + VOS_TIMER_TYPE_SW, + hdd_softap_traffic_monitor_timeout_handler, + pHddCtx); + vos_lock_init(&pHddCtx->traffic_monitor.trafficLock); + pHddCtx->traffic_monitor.isInitialized = 1; + pHddCtx->traffic_monitor.lastFrameTs = 0; + /* Start traffic monitor timer here + * If no AP assoc, immediatly go into suspend */ + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s Start Traffic Monitor Timer", __func__); + vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer, + pHddCtx->cfg_ini->trafficIdleTimeout); + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s Traffic Monitor is not Enable in ini file", __func__); + } + + EXIT(); + return status; +} + +VOS_STATUS hdd_stop_trafficMonitor( hdd_adapter_t *pAdapter, bool re_init) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + ENTER(); + + if (!re_init){ + status = wlan_hdd_validate_context(pHddCtx); + if (-ENODEV == status) { + return status; + } + } + + if (pHddCtx->traffic_monitor.isInitialized) + { + if (VOS_TIMER_STATE_STOPPED != + vos_timer_getCurrentState(&pHddCtx->traffic_monitor.trafficTimer)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s Stop Traffic Monitor Timer", __func__); + vos_timer_stop(&pHddCtx->traffic_monitor.trafficTimer); + } + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s Destroy Traffic Monitor Timer", __func__); + vos_timer_destroy(&pHddCtx->traffic_monitor.trafficTimer); + vos_lock_destroy(&pHddCtx->traffic_monitor.trafficLock); + pHddCtx->traffic_monitor.isInitialized = 0; + } + EXIT(); + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_softap_flush_tx_queues() - Utility function to flush the TX queues + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + v_U8_t STAId = 0; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + spin_lock_bh( &pSapCtx->staInfo_lock ); + for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) + { + if (FALSE == pSapCtx->aStaInfo[STAId].isUsed) + { + continue; + } + + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock); + while (true) + { + status = hdd_list_remove_front ( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &anchor); + + if (VOS_STATUS_E_EMPTY != status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + + //current list is empty + break; + } + pSapCtx->aStaInfo[STAId].txSuspended[i] = VOS_FALSE; + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock); + } + pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE; + } + + spin_unlock_bh( &pSapCtx->staInfo_lock ); + + return status; +} + +/** + * hdd_softap_get_connected_sta() - provide number of connected STA + * @pHostapdAdapter: pAdapter for SAP + * + * This function is invoked for SAP mode to get connected STA. + * + * Return: Total number of connected STA to SAP. + */ +v_U8_t hdd_softap_get_connected_sta(hdd_adapter_t *pHostapdAdapter) +{ + v_U8_t i, sta_ct = 0; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + + pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if (pSapCtx == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("psapCtx is NULL")); + goto error; + } + + spin_lock_bh(&pSapCtx->staInfo_lock); + // get stations associated with SAP + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { + if (pSapCtx->aStaInfo[i].isUsed && + (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA))) + sta_ct++; + } + spin_unlock_bh( &pSapCtx->staInfo_lock ); + +error: + return sta_ct; +} + +/**============================================================================ + @brief __hdd_softap_hard_start_xmit() - Function registered with the Linux OS + for transmitting packets. There are 2 versions of this function. One that + uses locked queue and other that uses lockless queues. Both have been + retained to do some performance testing + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +int __hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + VOS_STATUS status; + WLANTL_ACEnumType ac = WLANTL_AC_BE; + sme_QosWmmUpType up = SME_QOS_WMM_UP_BE; + skb_list_node_t *pktNode = NULL; + v_SIZE_t pktListSize = 0; + v_BOOL_t txSuspended = VOS_FALSE; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + vos_list_node_t *anchor = NULL; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + //Extract the destination address from ethernet frame + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + int os_status = NETDEV_TX_OK; + struct sk_buff *skb1; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + return os_status; + } + + if (pHddCtx == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is NULL")); + goto xmit_done; + } + + pDestMacAddress = (v_MACADDR_t*)skb->data; + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: enter", __func__); + + spin_lock_bh( &pSapCtx->staInfo_lock ); + if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress)) + { + //The BC/MC station ID is assigned during BSS starting phase. SAP will return the station + //ID used for BC/MC traffic. The station id is registered to TL as well. + STAId = pHddApCtx->uBCStaId; + + /* Setting priority for broadcast packets which doesn't go to select_queue function */ + skb->priority = SME_QOS_WMM_UP_BE; + skb->queue_mapping = HDD_LINUX_AC_BE; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "%s: BC/MC packet", __func__); + } + else + { + STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress); + if (STAId == HDD_WLAN_INVALID_STA_ID || STAId >= WLAN_MAX_STA_COUNT) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to find right station", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + goto xmit_done; + } + else if (FALSE == pSapCtx->aStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: STA %d is unregistered", __func__, STAId); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + goto xmit_done; + } + + if ( (WLANTL_STA_CONNECTED != pSapCtx->aStaInfo[STAId].tlSTAState) && + (WLANTL_STA_AUTHENTICATED != pSapCtx->aStaInfo[STAId].tlSTAState) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Station not connected yet", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + goto xmit_done; + } + else if(WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[STAId].tlSTAState) + { + if(ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: NON-EAPOL packet in non-Authenticated state", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + kfree_skb(skb); + goto xmit_done; + } + } + } + + //Get TL AC corresponding to Qdisc queue index/AC. + ac = hdd_QdiscAcToTlAC[skb->queue_mapping]; + //user priority from IP header, which is already extracted and set from + //select_queue call back function + up = skb->priority; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Classified as ac %d up %d", __func__, ac, up); + + if (( NULL != pHddCtx ) && + (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP)) + { + hdd_dump_dhcp_pkt(skb, TX_PATH); + } + + // If the memory differentiation mode is enabled, the memory limit of each queue will be + // checked. Over-limit packets will be dropped. + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize); + + if (pHddCtx->bad_sta[STAId]) { + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *fskb = NULL; + if(pktListSize >= (pAdapter->aTxQueueLimit[ac])/2) { + hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], + &anchor); + pktNode = list_entry(anchor, skb_list_node_t, anchor); + fskb = pktNode->skb; + kfree_skb(fskb); + pktListSize--; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + } + } + + if(pktListSize >= pAdapter->aTxQueueLimit[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize); + ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[ac]; + pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_TRUE; + netif_stop_subqueue(dev, skb_get_queue_mapping(skb)); + txSuspended = VOS_TRUE; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV, + pAdapter->sessionId, ac)); + } + + /* If 3/4th of the max queue size is used then enable the flag. + * This flag indicates to place the DHCP packets in VOICE AC queue.*/ + if (WLANTL_AC_BE == ac) + { + if (pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK) + { + if (!(pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count % 0x40)) + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: TX queue for Best Effort AC is 3/4th full", __func__); + pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].ratelimit_count++; + pSapCtx->aStaInfo[STAId].vosLowResource = VOS_TRUE; + } + else + { + pSapCtx->aStaInfo[STAId].vosLowResource = VOS_FALSE; + } + } + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + + if (VOS_TRUE == txSuspended) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: TX queue full for AC=%d Disable OS TX queue", + __func__, ac ); + os_status = NETDEV_TX_BUSY; + goto xmit_done; + } + + //Use the skb->cb field to hold the list node information + pktNode = (skb_list_node_t *)&skb->cb; + + //Stick the OS packet inside this node. + pktNode->skb = skb; + + //Stick the User Priority inside this node + pktNode->userPriority = up; + + INIT_LIST_HEAD(&pktNode->anchor); + + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize ); + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s:Insert Tx queue failed. Pkt dropped", __func__); + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + ++pAdapter->stats.tx_dropped; + kfree_skb(skb); + goto xmit_done; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac]; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count; + + if (1 == pktListSize) + { + //Let TL know we have a packet to send for this AC + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to signal TL for AC=%d STAId =%d", + __func__, ac, STAId ); + + //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle + //as we are in a soft irq context. Also it must be the same packet that we just allocated. + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor); + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + /* Free the skb only if we are able to remove it from the list. + * If we are not able to retrieve it from the list it means that + * the skb was pulled by TX Thread and is use so we should not free + * it here + */ + if (VOS_IS_STATUS_SUCCESS(status)) + { + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb1 = pktNode->skb; + kfree_skb(skb1); + } + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + goto xmit_done; + } + } + dev->trans_start = jiffies; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "%s: exit", __func__); + +xmit_done: + spin_unlock_bh( &pSapCtx->staInfo_lock ); + return os_status; +} + +int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + int ret; + vos_ssr_protect(__func__); + ret = __hdd_softap_hard_start_xmit(skb, dev); + vos_ssr_unprotect(__func__); + return ret; +} + +/**============================================================================ + @brief hdd_softap_sta_2_sta_xmit This function for Transmitting the frames when the traffic is between two stations. + + @param skb : [in] pointer to packet (sk_buff) + @param dev : [in] pointer to Libra network device + @param STAId : [in] Station Id of Destination Station + @param up : [in] User Priority + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +VOS_STATUS hdd_softap_sta_2_sta_xmit(struct sk_buff *skb, + struct net_device *dev, + v_U8_t STAId, + v_U8_t up) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + skb_list_node_t *pktNode = NULL; + v_SIZE_t pktListSize = 0; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + v_U8_t ac; + vos_list_node_t *anchor = NULL; + struct sk_buff *skb1; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + kfree_skb(skb); + status = VOS_STATUS_E_FAILURE; + return status; + } + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: enter", __func__); + + spin_lock_bh( &pSapCtx->staInfo_lock ); + if ( FALSE == pSapCtx->aStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: STA %d is unregistered", __func__, STAId ); + kfree_skb(skb); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + + /* If the QoS is not enabled on the receiving station, then send it with BE priority */ + if ( !pSapCtx->aStaInfo[STAId].isQosEnabled ) + up = SME_QOS_WMM_UP_BE; + + ac = hddWmmUpToAcMap[up]; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Classified as ac %d up %d", __func__, ac, up); + + skb->queue_mapping = hddLinuxUpToAcMap[up]; + + //Use the skb->cb field to hold the list node information + pktNode = (skb_list_node_t *)&skb->cb; + + //Stick the OS packet inside this node. + pktNode->skb = skb; + + //Stick the User Priority inside this node + pktNode->userPriority = up; + + INIT_LIST_HEAD(&pktNode->anchor); + + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktListSize); + if(pSapCtx->aStaInfo[STAId].txSuspended[ac] || + pktListSize >= pAdapter->aTxQueueLimit[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize); + /* TODO:Rx Flowchart should be trigerred here to SUPEND SSC on RX side. + * SUSPEND should be done based on Threshold. RESUME would be + * triggered in fetch cbk after recovery. + */ + kfree_skb(skb); + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + status = hdd_list_insert_back_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &pktNode->anchor, &pktListSize ); + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s:Insert Tx queue failed. Pkt dropped", __func__); + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + ++pAdapter->stats.tx_dropped; + kfree_skb(skb); + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac]; + + if (1 == pktListSize) + { + //Let TL know we have a packet to send for this AC + //VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__); + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, STAId, ac ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to signal TL for AC=%d STAId =%d", + __func__, ac, STAId ); + + //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle + //as we are in a soft irq context. Also it must be the same packet that we just allocated. + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + status = hdd_list_remove_back( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor); + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + /* Free the skb only if we are able to remove it from the list. + * If we are not able to retrieve it from the list it means that + * the skb was pulled by TX Thread and is use so we should not free + * it here + */ + if (VOS_IS_STATUS_SUCCESS(status)) + { + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb1 = pktNode->skb; + kfree_skb(skb1); + } + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + status = VOS_STATUS_E_FAILURE; + goto xmit_end; + } + } + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, "%s: exit", __func__); + +xmit_end: + spin_unlock_bh( &pSapCtx->staInfo_lock ); + return status; +} + +/**============================================================================ + @brief __hdd_softap_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to Libra network device + @return : None + ===========================================================================*/ +void __hdd_softap_tx_timeout(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct netdev_queue *txq; + int i = 0; + int status = 0; + hdd_context_t *pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred jiffies %lu dev->trans_start %lu", + __func__, jiffies, dev->trans_start); + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (status != 0) + { + return; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount; + + for (i = 0; i < NUM_TX_QUEUES; i++) + { + txq = netdev_get_tx_queue(dev, i); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "Queue%d status: %d", i, netif_tx_queue_stopped(txq)); + } + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "carrier state: %d", netif_carrier_ok(dev)); + + ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount; + + if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount == + HDD_SAP_TX_STALL_RECOVERY_THRESHOLD) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Request firmware for recovery",__func__); + WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP); + } + if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > + HDD_SAP_TX_STALL_SSR_THRESHOLD) + { + // Driver could not recover, issue SSR + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot recover from Data stall Issue SSR", + __func__); + WLANTL_FatalError(); + // reset count after issuing the SSR + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + return; + } + + /* If Tx stalled for a long time then *hdd_tx_timeout* is called + * every 5sec. The TL debug spits out a lot of information on the + * serial console, if it is called every time *hdd_tx_timeout* is + * called then we may get a watchdog bite on the Application + * processor, so ratelimit the TL debug logs. + */ + if (__ratelimit(&hdd_softap_tx_timeout_rs)) + { + hdd_wmm_tx_snapshot(pAdapter); + WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT); + } + /* Call fatal event if data stall is for + * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times + */ + if (HDD_SAP_TX_STALL_FATAL_EVENT_THRESHOLD == + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount) + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DATA_STALL, + FALSE, TRUE); +} + +void hdd_softap_tx_timeout(struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_softap_tx_timeout(dev); + vos_ssr_unprotect(__func__); + return; +} + +/**============================================================================ + @brief __hdd_softap_stats() - Function registered with the Linux OS for + device TX/RX statistic + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +struct net_device_stats* __hdd_softap_stats(struct net_device *dev) +{ + hdd_adapter_t* priv = netdev_priv(dev); + return &priv->stats; +} + +struct net_device_stats* hdd_softap_stats(struct net_device *dev) +{ + struct net_device_stats *priv_stats; + vos_ssr_protect(__func__); + priv_stats = __hdd_softap_stats(dev); + vos_ssr_unprotect(__func__); + + return priv_stats; +} + +/**============================================================================ + @brief hdd_softap_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_init_tx_rx(hdd_adapter_t *pAdapter, bool re_init) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + v_SIZE_t size = 0; + + v_U8_t STAId = 0; + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + + v_U8_t pACWeights[] = { + HDD_SOFTAP_BK_WEIGHT_DEFAULT, + HDD_SOFTAP_BE_WEIGHT_DEFAULT, + HDD_SOFTAP_VI_WEIGHT_DEFAULT, + HDD_SOFTAP_VO_WEIGHT_DEFAULT + }; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + + + pAdapter->isVosOutOfResource = VOS_FALSE; + pAdapter->isVosLowResource = VOS_FALSE; + + vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats)); + + while (++i != NUM_TX_QUEUES) + hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + + /* Initial HDD buffer control / flow control fields*/ + vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE_TX_802_3_DATA, &size); + + pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN; + + for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) + { + vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t)); + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + } + + /* Update the AC weights suitable for SoftAP mode of operation */ + WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights); + + if (VOS_STATUS_SUCCESS != hdd_start_trafficMonitor(pAdapter, re_init)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: failed to start Traffic Monito timer ", __func__ ); + return VOS_STATUS_E_INVAL; + } + return status; +} + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_deinit_tx_rx( hdd_adapter_t *pAdapter, bool re_init) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if (VOS_STATUS_SUCCESS != hdd_stop_trafficMonitor(pAdapter, re_init)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Fail to Stop Traffic Monito timer", __func__ ); + return VOS_STATUS_E_INVAL; + } + + status = hdd_softap_flush_tx_queues(pAdapter); + + return status; +} + +/**============================================================================ + @brief hdd_softap_flush_tx_queues_sta() - Utility function to flush the TX queues of a station + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +static VOS_STATUS hdd_softap_flush_tx_queues_sta( hdd_adapter_t *pAdapter, v_U8_t STAId ) +{ + v_U8_t i = -1; + + hdd_list_node_t *anchor = NULL; + + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + if (FALSE == pSapCtx->aStaInfo[STAId].isUsed) + { + return VOS_STATUS_SUCCESS; + } + + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock); + while (true) + { + if (VOS_STATUS_E_EMPTY != + hdd_list_remove_front(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], + &anchor)) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + + //current list is empty + break; + } + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i].lock); + } + + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: flushed the TX queues of sta:%d", __func__, STAId); + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_softap_init_tx_rx_sta() - Init function to initialize a station in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @param pmacAddrSTA : [in] pointer to the MAC address of the station + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_init_tx_rx_sta( hdd_adapter_t *pAdapter, v_U8_t STAId, v_MACADDR_t *pmacAddrSTA) +{ + v_U8_t i = 0; + VOS_STATUS status; + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + + spin_lock_bh( &pSapCtx->staInfo_lock ); + if (pSapCtx->aStaInfo[STAId].isUsed) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Reinit station %d", __func__, STAId ); + spin_unlock_bh( &pSapCtx->staInfo_lock ); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t)); + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + + pSapCtx->aStaInfo[STAId].isUsed = TRUE; + pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE; + vos_copy_macaddr( &pSapCtx->aStaInfo[STAId].macAddrSTA, pmacAddrSTA); + + spin_unlock_bh( &pSapCtx->staInfo_lock ); + + status = hdd_sta_id_hash_add_entry(pAdapter, STAId, pmacAddrSTA); + if (status != VOS_STATUS_SUCCESS) { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Not able to add staid hash %d"), STAId); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + FL("New station added sta_id %d mac:" + MAC_ADDRESS_STR), STAId, + MAC_ADDR_ARRAY(pmacAddrSTA->bytes)); + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_softap_deinit_tx_rx_sta() - Deinit function to clean up a statioin in Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @param STAId : [in] Station ID to deinit + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_deinit_tx_rx_sta ( hdd_adapter_t *pAdapter, v_U8_t STAId ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t ac; + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t txSuspended[NUM_TX_QUEUES]; + v_U8_t tlAC; + hdd_hostapd_state_t *pHostapdState; + v_U8_t i; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter); + + spin_lock_bh( &pSapCtx->staInfo_lock ); + if (FALSE == pSapCtx->aStaInfo[STAId].isUsed) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Deinit station not inited %d", __func__, STAId ); + spin_unlock_bh( &pSapCtx->staInfo_lock ); + return VOS_STATUS_E_FAILURE; + } + + status = hdd_softap_flush_tx_queues_sta(pAdapter, STAId); + + pSapCtx->aStaInfo[STAId].isUsed = FALSE; + pSapCtx->aStaInfo[STAId].isDeauthInProgress = FALSE; + + status = hdd_sta_id_hash_remove_entry(pAdapter, + STAId, &pSapCtx->aStaInfo[STAId].macAddrSTA); + if (status != VOS_STATUS_SUCCESS) { + spin_unlock_bh( &pSapCtx->staInfo_lock ); + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Not able to remove staid hash %d"), STAId); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + FL("station removed sta_id %d mac:" + MAC_ADDRESS_STR), STAId, + MAC_ADDR_ARRAY(pSapCtx->aStaInfo[STAId].macAddrSTA.bytes)); + + /* if this STA had any of its WMM TX queues suspended, then the + associated queue on the network interface was disabled. check + to see if that is the case, in which case we need to re-enable + the interface queue. but we only do this if the BSS is running + since, if the BSS is stopped, all of the interfaces have been + stopped and should not be re-enabled */ + + if (BSS_START == pHostapdState->bssState) + { + for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++) + { + tlAC = hdd_QdiscAcToTlAC[ac]; + txSuspended[ac] = pSapCtx->aStaInfo[STAId].txSuspended[tlAC]; + } + } + vos_mem_zero(&pSapCtx->aStaInfo[STAId], sizeof(hdd_station_info_t)); + + /* re-init spin lock, since netdev can still open adapter until + * driver gets unloaded + */ + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], + HDD_TX_QUEUE_MAX_LEN); + } + + if (BSS_START == pHostapdState->bssState) + { + for (ac = HDD_LINUX_AC_VO; ac <= HDD_LINUX_AC_BK; ac++) + { + if (txSuspended[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue re-enabled", __func__); + netif_wake_subqueue(pAdapter->dev, ac); + } + } + } + + spin_unlock_bh( &pSapCtx->staInfo_lock ); + return status; +} + +/**============================================================================ + @brief hdd_softap_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_disconnect_tx_rx( hdd_adapter_t *pAdapter ) +{ + return hdd_softap_flush_tx_queues(pAdapter); +} + +/**============================================================================ + @brief hdd_softap_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the bus + succesfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = NULL; + void* pOsPkt = NULL; + + if( ( NULL == vosContext ) || ( NULL == pVosPacket ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Return the skb to the OS + status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE ); + if ((!VOS_IS_STATUS_SUCCESS(status)) || (!pOsPkt)) + { + //This is bad but still try to free the VOSS resources if we can + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + //Get the Adapter context. + pAdapter = (hdd_adapter_t *)netdev_priv(((struct sk_buff *)pOsPkt)->dev); + if((pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is invalid", __func__); + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txCompleted; + } + + kfree_skb((struct sk_buff *)pOsPkt); + + //Return the VOS packet resources. + status = vos_pkt_return_packet( pVosPacket ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Could not return VOS packet to the pool", __func__); + } + + return status; +} + + +/**============================================================================ + @brief hdd_softap_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ac : [in] access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ac, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter = NULL; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + vos_pkt_t *pVosPacket = NULL; + v_MACADDR_t* pDestMacAddress = NULL; + v_TIME_t timestamp; + v_SIZE_t size = 0; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + hdd_context_t *pHddCtx = NULL; + v_U8_t proto_type = 0; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pStaId ) || + ( NULL == ppVosPacket ) || + ( NULL == pPktMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null Params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + STAId = *pStaId; + if (STAId >= WLAN_MAX_STA_COUNT) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid STAId %d passed by TL", __func__, STAId); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[STAId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + + if (FALSE == pSapCtx->aStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Unregistered STAId %d passed by TL", __func__, STAId); + return VOS_STATUS_E_FAILURE; + } + + /* Monitor traffic */ + if ( pHddCtx->cfg_ini->enableTrafficMonitor ) + { + pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time(); + if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) ) + { + vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock); + /* It was IDLE mode, + * this is new state, then switch mode from suspend to resume */ + if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) ) + { + hdd_set_wlan_suspend_mode(0); + vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer, + pHddCtx->cfg_ini->trafficIdleTimeout); + atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1); + } + vos_lock_release(&pHddCtx->traffic_monitor.trafficLock); + } + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetched; + + *ppVosPacket = NULL; + + //Make sure the AC being asked for is sane + if( ac > WLANTL_MAX_AC || ac < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid AC %d passed by TL", __func__, ac); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac]; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: AC %d passed by TL", __func__, ac); + + //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources + //This simplifies the locking and unlocking of Tx queue + status = vos_pkt_wrap_data_packet( &pVosPacket, + VOS_PKT_TYPE_TX_802_3_DATA, + NULL, //OS Pkt is not being passed + hdd_softap_tx_low_resource_cbk, + pAdapter ); + + if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES) + { + //Remember VOS is in a low resource situation + pAdapter->isVosOutOfResource = VOS_TRUE; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_WARN, + "%s: VOSS in Low Resource scenario", __func__); + //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty. + return VOS_STATUS_E_FAILURE; + } + + /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. Do not get next AC + as the other branch does. + */ + spin_lock_bh( &pSapCtx->staInfo_lock ); + spin_lock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &size); + + if (0 == size) + { + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + spin_unlock_bh( &pSapCtx->staInfo_lock ); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_EMPTY; + } + + status = hdd_list_remove_front( &pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[ac].lock); + spin_unlock_bh( &pSapCtx->staInfo_lock ); + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: AC %d has packets pending", __func__, ac); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Error in de-queuing skb from Tx queue status = %d", + __func__, status ); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_FAILURE; + } + + //Attach skb to VOS packet. + status = vos_pkt_set_os_packet( pVosPacket, skb ); + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Error attaching skb", __func__); + vos_pkt_return_packet(pVosPacket); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Just being paranoid. To be removed later + if(pVosPacket == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS packet returned by VOSS is NULL", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Return VOS packet to TL; + *ppVosPacket = pVosPacket; + + //Fill out the meta information needed by TL + //FIXME This timestamp is really the time stamp of wrap_data_packet + vos_pkt_get_timestamp( pVosPacket, ×tamp ); + pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp; + if ( 1 < size ) + { + pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send + } + else + { + pPktMetaInfo->bMorePackets = 0; + } + + pPktMetaInfo->ucIsEapol = 0; + + if(pSapCtx->aStaInfo[STAId].tlSTAState != WLANTL_STA_AUTHENTICATED) + { + if (TRUE == hdd_IsEAPOLPacket( pVosPacket )) + { + pPktMetaInfo->ucIsEapol = 1; + wlan_hdd_log_eapol(skb, + WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED); + } + } + + if ((NULL != pHddCtx) && + (pHddCtx->cfg_ini->gEnableDebugLog)) + { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog); + if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SAP TX EAPOL"); + } + else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SAP TX DHCP"); + } + else if (VOS_PKT_PROTO_TYPE_ARP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SAP TX ARP"); + } + } +//xg: @@@@: temporarily disble these. will revisit later + { + pPktMetaInfo->ac = ac; + pPktMetaInfo->ucUP = pktNode->userPriority; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + } + + pPktMetaInfo->ucType = 0; //FIXME Don't know what this is + //Extract the destination address from ethernet frame + pDestMacAddress = (v_MACADDR_t*)skb->data; + + // we need 802.3 to 802.11 frame translation + // (note that Bcast/Mcast will be translated in SW, unicast in HW) + pPktMetaInfo->ucDisableFrmXtl = 0; + pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0; + pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0; + + if ( (pSapCtx->aStaInfo[STAId].txSuspended[ac]) && + (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue re-enabled", __func__); + pSapCtx->aStaInfo[STAId].txSuspended[ac] = VOS_FALSE; + netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb)); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV, + pAdapter->sessionId, ac)); + } + + // We're giving the packet to TL so consider it transmitted from + // a statistics perspective. We account for it here instead of + // when the packet is returned for two reasons. First, TL will + // manipulate the skb to the point where the len field is not + // accurate, leading to inaccurate byte counts if we account for + // it later. Second, TL does not provide any feedback as to + // whether or not the packet was successfully sent over the air, + // so the packet counts will be the same regardless of where we + // account for them + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac]; + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Valid VOS PKT returned to TL", __func__); + + return status; +} + + +/**============================================================================ + @brief hdd_softap_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +VOS_STATUS hdd_softap_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ) +{ + VOS_STATUS status; + v_SINT_t i = 0; + v_SIZE_t size = 0; + hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + v_CONTEXT_t pVosContext = NULL; + ptSapContext pSapCtx = NULL; + + if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Invalid adapter %p"), pAdapter); + return VOS_STATUS_E_FAILURE; + } + pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + //Return the packet to VOS. We just needed to know that VOS is out of low resource + //situation. Here we will only signal TL that there is a pending data for a STA. + //VOS packet will be requested (if needed) when TL comes back to fetch data. + vos_pkt_return_packet( pVosPacket ); + + pAdapter->isVosOutOfResource = VOS_FALSE; + + // Indicate to TL that there is pending data if a queue is non empty. + // This Code wasnt included in earlier version which resulted in + // Traffic stalling + for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) + { + if ((pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_AUTHENTICATED) || + (pSapCtx->aStaInfo[STAId].tlSTAState == WLANTL_STA_CONNECTED)) + { + for( i=NUM_TX_QUEUES-1; i>=0; --i ) + { + size = 0; + hdd_list_size(&pSapCtx->aStaInfo[STAId].wmm_tx_queue[i], &size); + if ( size > 0 ) + { + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId, + (WLANTL_ACEnumType)i ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure in indicating pkt to TL for ac=%d", __func__,i); + } + } + } + } + } + return VOS_STATUS_SUCCESS; +} + + +/**============================================================================ + @brief hdd_softap_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when one or more packets were + received for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param pVosPacketChain : [in] pointer to VOS packet chain + @param staId : [in] Station Id (Adress 1 Index) + @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s). + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_softap_rx_packet_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacketChain, + v_U8_t staId, + WLANTL_RxMetaInfoType* pRxMetaInfo ) +{ + hdd_adapter_t *pAdapter = NULL; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + int rxstat; + struct sk_buff *skb = NULL; + vos_pkt_t* pVosPacket; + vos_pkt_t* pNextVosPacket; + hdd_context_t *pHddCtx = NULL; + v_U8_t proto_type = 0; + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pVosPacketChain ) || + ( NULL == pRxMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[staId]; + if( (NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: invalid adapter or adapter has invalid magic",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Monitor traffic */ + if ( pHddCtx->cfg_ini->enableTrafficMonitor ) + { + pHddCtx->traffic_monitor.lastFrameTs = vos_timer_get_system_time(); + if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) ) + { + vos_lock_acquire(&pHddCtx->traffic_monitor.trafficLock); + /* It was IDLE mode, + * this is new state, then switch mode from suspend to resume */ + if ( !atomic_read(&pHddCtx->traffic_monitor.isActiveMode) ) + { + hdd_set_wlan_suspend_mode(0); + vos_timer_start(&pHddCtx->traffic_monitor.trafficTimer, + pHddCtx->cfg_ini->trafficIdleTimeout); + atomic_set(&pHddCtx->traffic_monitor.isActiveMode, 1); + } + vos_lock_release(&pHddCtx->traffic_monitor.trafficLock); + } + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxChains; + + // walk the chain until all are processed + pVosPacket = pVosPacketChain; + do + { + // get the pointer to the next packet in the chain + // (but don't unlink the packet since we free the entire chain later) + status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE); + + // both "success" and "empty" are acceptable results + if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY))) + { + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure walking packet chain", __func__); + return VOS_STATUS_E_FAILURE; + } + + // Extract the OS packet (skb). + status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (TRUE == hdd_IsEAPOLPacket(pVosPacket)) + wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); + + pVosPacket->pSkb = NULL; + //hdd_softap_dump_sk_buff(skb); + + skb->dev = pAdapter->dev; + + if(skb->dev == NULL) { + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_FATAL, + "ERROR!!Invalid netdevice"); + return VOS_STATUS_E_FAILURE; + } + ++pAdapter->hdd_stats.hddTxRxStats.rxPackets; + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += skb->len; + + if (pHddCtx->cfg_ini->gEnableDebugLog) + { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog); + if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SAP RX EAPOL"); + } + else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SAP RX DHCP"); + } + else if (VOS_PKT_PROTO_TYPE_ARP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "SAP RX ARP"); + } + } + + if (pHddCtx->rx_wow_dump) { + if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) && + !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type)) + hdd_log_ip_addr(skb); + pHddCtx->rx_wow_dump = false; + } + + if (WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) + { + //MC/BC packets. Duplicate a copy of packet + struct sk_buff *pSkbCopy; + hdd_ap_ctx_t *pHddApCtx; + + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + if (!(pHddApCtx->apDisableIntraBssFwd)) + { + pSkbCopy = skb_copy(skb, GFP_ATOMIC); + if (pSkbCopy) + { + hdd_softap_sta_2_sta_xmit(pSkbCopy, pSkbCopy->dev, + pHddApCtx->uBCStaId, (pRxMetaInfo->ucUP)); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: skb allocation fails", __func__); + } + + + } //(WLAN_RX_BCMC_STA_ID == staId) + + if ((WLAN_RX_BCMC_STA_ID == pRxMetaInfo->ucDesSTAId) || + (WLAN_RX_SAP_SELF_STA_ID == pRxMetaInfo->ucDesSTAId)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "%s: send one packet to kernel", __func__); + if ((NULL != pHddCtx) && + (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP)) + { + hdd_dump_dhcp_pkt(skb, RX_PATH); + } + + skb->protocol = eth_type_trans(skb, skb->dev); + skb->ip_summed = CHECKSUM_NONE; +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION, + WIFI_POWER_EVENT_WAKELOCK_HOLD_RX); + +#endif + rxstat = netif_rx_ni(skb); + if (NET_RX_SUCCESS == rxstat) + { + ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count; + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.rxRefused; + } + } + else if ((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->apDisableIntraBssFwd) + { + kfree_skb(skb); + } + else + { + //loopback traffic + status = hdd_softap_sta_2_sta_xmit(skb, skb->dev, + pRxMetaInfo->ucDesSTAId, (pRxMetaInfo->ucUP)); + } + + // now process the next packet in the chain + pVosPacket = pNextVosPacket; + + } while (pVosPacket); + + //Return the entire VOS packet chain to the resource pool + status = vos_pkt_return_packet( pVosPacketChain ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure returning vos pkt", __func__); + } + + pAdapter->dev->last_rx = jiffies; + + return status; +} + +VOS_STATUS hdd_softap_DeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx; + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return VOS_STATUS_E_INVAL; + } + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic", __func__); + return VOS_STATUS_E_INVAL; + } + + pHddCtx = (hdd_context_t*)(pAdapter->pHddCtx); + //Clear station in TL and then update HDD data structures. This helps + //to block RX frames from other station to this station. + vosStatus = WLANTL_ClearSTAClient( pHddCtx->pvosContext, staId ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "WLANTL_ClearSTAClient() failed to for staID %d. " + "Status= %d [0x%08X]", + staId, vosStatus, vosStatus ); + } + + vosStatus = hdd_softap_deinit_tx_rx_sta ( pAdapter, staId ); + if( VOS_STATUS_E_FAILURE == vosStatus ) + { + VOS_TRACE ( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "hdd_softap_deinit_tx_rx_sta() failed for staID %d. " + "Status = %d [0x%08X]", + staId, vosStatus, vosStatus ); + return( vosStatus ); + } + + pHddCtx->sta_to_adapter[staId] = NULL; + + return( vosStatus ); +} + +VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter, + v_BOOL_t fAuthRequired, + v_BOOL_t fPrivacyBit, + v_U8_t staId, + v_U8_t ucastSig, + v_U8_t bcastSig, + v_MACADDR_t *pPeerMacAddress, + v_BOOL_t fWmmEnabled ) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + WLAN_STADescType staDesc = {0}; + hdd_context_t *pHddCtx = pAdapter->pHddCtx; + hdd_adapter_t *pmonAdapter = NULL; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + //eCsrEncryptionType connectedCipherAlgo; + //v_BOOL_t fConnected; + + /* + * Clean up old entry if it is not cleaned up properly + */ + if ( pSapCtx->aStaInfo[staId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "clean up old entry for STA %d", staId); + hdd_softap_DeregisterSTA( pAdapter, staId ); + } + + // Get the Station ID from the one saved during the assocation. + + staDesc.ucSTAId = staId; + + + /*Save the pAdapter Pointer for this staId*/ + pHddCtx->sta_to_adapter[staId] = pAdapter; + + staDesc.wSTAType = WLAN_STA_SOFTAP; + + vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) ); + vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, &pAdapter->macAddressCurrent,6 ); + vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent ); + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "register station"); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "station mac " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(staDesc.vSTAMACAddress.bytes)); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "BSSIDforIBSS " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(staDesc.vBSSIDforIBSS.bytes)); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "SOFTAP SELFMAC " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(staDesc.vSelfMACAddress.bytes)); + + vosStatus = hdd_softap_init_tx_rx_sta(pAdapter, staId, &staDesc.vSTAMACAddress); + + staDesc.ucQosEnabled = fWmmEnabled; + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "HDD SOFTAP register TL QoS_enabled=%d", + staDesc.ucQosEnabled ); + + staDesc.ucProtectedFrame = (v_U8_t)fPrivacyBit ; + + + // For PRIMA UMA frame translation is not enable yet. + staDesc.ucSwFrameTXXlation = 1; + staDesc.ucSwFrameRXXlation = 1; + staDesc.ucAddRmvLLC = 1; + + // Initialize signatures and state + staDesc.ucUcastSig = ucastSig; + staDesc.ucBcastSig = bcastSig; + staDesc.ucInitState = fAuthRequired ? + WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED; + + staDesc.ucIsReplayCheckValid = VOS_FALSE; + + // Register the Station with TL... + vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + hdd_softap_rx_packet_cbk, + hdd_softap_tx_complete_cbk, + hdd_softap_tx_fetch_packet_cbk, &staDesc, 0 ); + + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "SOFTAP WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]", + vosStatus, vosStatus ); + return vosStatus; + } + + //Timer value should be in milliseconds + if ( pHddCtx->cfg_ini->dynSplitscan && + ( VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) + { + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + pHddCtx->cfg_ini->trafficMntrTmrForSplitScan); + } + + // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver, + // then go to 'authenticated'. For all other authentication types (those that do + // not require upper layer authentication) we can put TL directly into 'authenticated' + // state. + + //VOS_ASSERT( fConnected ); + pSapCtx->aStaInfo[staId].ucSTAId = staId; + pSapCtx->aStaInfo[staId].isQosEnabled = fWmmEnabled; + if ( !fAuthRequired ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", + pSapCtx->aStaInfo[staId].ucSTAId ); + + // Connections that do not need Upper layer auth, transition TL directly + // to 'Authenticated' state. + vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId, + WLANTL_STA_AUTHENTICATED ); + + pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_AUTHENTICATED; + pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_TRUE; + } + else + { + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pSapCtx->aStaInfo[staId].ucSTAId ); + + vosStatus = WLANTL_ChangeSTAState( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staDesc.ucSTAId, + WLANTL_STA_CONNECTED ); + pSapCtx->aStaInfo[staId].tlSTAState = WLANTL_STA_CONNECTED; + + pAdapter->sessionCtx.ap.uIsAuthenticated = VOS_FALSE; + + } + pmonAdapter= hdd_get_mon_adapter( pAdapter->pHddCtx); + if(pmonAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO_HIGH, + "Turn on Monitor the carrier"); + netif_carrier_on(pmonAdapter->dev); + //Enable Tx queue + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues(pmonAdapter->dev); + } + netif_carrier_on(pAdapter->dev); + //Enable Tx queue + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues(pAdapter->dev); + + return( vosStatus ); +} + +VOS_STATUS hdd_softap_Register_BC_STA( hdd_adapter_t *pAdapter, v_BOOL_t fPrivacyBit) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + + pHddCtx->sta_to_adapter[WLAN_RX_BCMC_STA_ID] = pAdapter; + pHddCtx->sta_to_adapter[WLAN_RX_SAP_SELF_STA_ID] = pAdapter; + vosStatus = hdd_softap_RegisterSTA( pAdapter, VOS_FALSE, fPrivacyBit, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId, 0, 1, &broadcastMacAddr,0); + + return vosStatus; +} + +VOS_STATUS hdd_softap_Deregister_BC_STA( hdd_adapter_t *pAdapter) +{ + return hdd_softap_DeregisterSTA( pAdapter, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId); +} + +VOS_STATUS hdd_softap_stop_bss( hdd_adapter_t *pAdapter) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + v_U8_t staId = 0; + hdd_context_t *pHddCtx; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + /*bss deregister is not allowed during wlan driver loading or unloading*/ + if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Loading_unloading in Progress. Ignore!!!",__func__); + return VOS_STATUS_E_PERM; + } + + vosStatus = hdd_softap_Deregister_BC_STA( pAdapter); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to deregister BC sta Id %d", __func__, (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->uBCStaId); + } + + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) + { + if (pSapCtx->aStaInfo[staId].isUsed)// This excludes BC sta as it is already deregistered + { + vosStatus = hdd_softap_DeregisterSTA( pAdapter, staId); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to deregister sta Id %d", __func__, staId); + } + } + } + + return vosStatus; +} + +VOS_STATUS hdd_softap_change_STA_state( hdd_adapter_t *pAdapter, v_MACADDR_t *pDestMacAddress, WLANTL_STAStateType state) +{ + v_U8_t ucSTAId = WLAN_MAX_STA_COUNT; + VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS; + v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: enter", __func__); + + if (VOS_STATUS_SUCCESS != hdd_softap_GetStaId(pAdapter, pDestMacAddress, &ucSTAId)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to find right station", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[ucSTAId].macAddrSTA, pDestMacAddress)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Station MAC address does not matching", __func__); + return VOS_STATUS_E_FAILURE; + } + + vosStatus = WLANTL_ChangeSTAState( pVosContext, ucSTAId, state ); + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: change station to state %d succeed", __func__, state); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + pSapCtx->aStaInfo[ucSTAId].tlSTAState = WLANTL_STA_AUTHENTICATED; + } + + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s exit",__func__); + + return vosStatus; +} + + +VOS_STATUS hdd_softap_GetStaId(hdd_adapter_t *pAdapter, v_MACADDR_t *pMacAddress, v_U8_t *staId) +{ + v_U8_t i; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (vos_mem_compare(&pSapCtx->aStaInfo[i].macAddrSTA, pMacAddress, sizeof(v_MACADDR_t)) && + pSapCtx->aStaInfo[i].isUsed) + { + *staId = i; + return VOS_STATUS_SUCCESS; + } + } + + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS hdd_softap_GetConnectedStaId(hdd_adapter_t *pAdapter, v_U8_t *staId) +{ + v_U8_t i; + + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return VOS_STATUS_E_FAULT; + } + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (pSapCtx->aStaInfo[i].isUsed && + (!vos_is_macaddr_broadcast(&pSapCtx->aStaInfo[i].macAddrSTA))) + { + *staId = i; + return VOS_STATUS_SUCCESS; + } + } + + return VOS_STATUS_E_FAILURE; +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c new file mode 100644 index 000000000000..d17995429c22 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tdls.c @@ -0,0 +1,3685 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**======================================================================== + + \file wlan_hdd_tdls.c + + \brief WLAN Host Device Driver implementation for TDLS + + ========================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_hdd_tdls.h" +#include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_assoc.h" +#include "sme_Api.h" +#include "vos_sched.h" + +static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx); +static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx); +static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx); +static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx); +int wpa_tdls_is_allowed_force_peer(tdlsCtx_t *pHddTdlsCtx, u8 *mac); +#ifdef CONFIG_TDLS_IMPLICIT +static void wlan_hdd_tdls_implicit_send_discovery_request(tdlsCtx_t *pHddTdlsCtx); +#endif + +static u8 wlan_hdd_tdls_hash_key (const u8 *mac) +{ + int i; + u8 key = 0; + + for (i = 0; i < 6; i++) + key ^= mac[i]; + + return key; +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * hdd_send_wlan_tdls_teardown_event()- send TDLS teardown event + * + * @reason: reason for tear down. + * @peer_mac: peer mac + * + * This Function send TDLS teardown diag event + * + * Return: void. + */ +void hdd_send_wlan_tdls_teardown_event(uint32_t reason, + uint8_t *peer_mac) +{ + WLAN_VOS_DIAG_EVENT_DEF(tdls_tear_down, + struct vos_event_tdls_teardown); + vos_mem_zero(&tdls_tear_down, + sizeof(tdls_tear_down)); + + tdls_tear_down.reason = reason; + vos_mem_copy(tdls_tear_down.peer_mac, + peer_mac, HDD_MAC_ADDR_LEN); + WLAN_VOS_DIAG_EVENT_REPORT(&tdls_tear_down, + EVENT_WLAN_TDLS_TEARDOWN); +} + +/** + * hdd_wlan_tdls_enable_link_event()- send TDLS enable link event + * + * @peer_mac: peer mac + * @is_off_chan_supported: Does peer supports off chan + * @is_off_chan_configured: If off channel is configured + * @is_off_chan_established: If off chan is established + * + * This Function send TDLS enable link diag event + * + * Return: void. + */ + +void hdd_wlan_tdls_enable_link_event(const uint8_t *peer_mac, + uint8_t is_off_chan_supported, + uint8_t is_off_chan_configured, + uint8_t is_off_chan_established) +{ + WLAN_VOS_DIAG_EVENT_DEF(tdls_event, + struct vos_event_tdls_enable_link); + vos_mem_zero(&tdls_event, + sizeof(tdls_event)); + + vos_mem_copy(tdls_event.peer_mac, + peer_mac, HDD_MAC_ADDR_LEN); + + tdls_event.is_off_chan_supported = + is_off_chan_supported; + tdls_event.is_off_chan_configured = + is_off_chan_configured; + tdls_event.is_off_chan_established = + is_off_chan_established; + + WLAN_VOS_DIAG_EVENT_REPORT(&tdls_event, + EVENT_WLAN_TDLS_ENABLE_LINK); +} + +/** + * hdd_wlan_block_scan_by_tdls()- send event + * if scan is blocked by tdls + * + * This Function send send diag event if scan is + * blocked by tdls + * + * Return: void. + */ + +void hdd_wlan_block_scan_by_tdls(void) +{ + WLAN_VOS_DIAG_EVENT_DEF(tdls_scan_block_status, + struct vos_event_tdls_scan_rejected); + + vos_mem_zero(&tdls_scan_block_status, + sizeof(tdls_scan_block_status)); + + tdls_scan_block_status.status = true; + WLAN_VOS_DIAG_EVENT_REPORT(&tdls_scan_block_status, + EVENT_TDLS_SCAN_BLOCK); +} + +#endif + + +/** + * wlan_hdd_tdls_disable_offchan_and_teardown_links - Disable offchannel + * and teardown TDLS links + * @hddCtx : pointer to hdd context + * + * Return: None + */ +void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx) +{ + u16 connected_tdls_peers = 0; + u8 staIdx; + hddTdlsPeer_t *curr_peer = NULL; + hdd_adapter_t *adapter = NULL; + bool tdls_unlock = FALSE; + + if (eTDLS_SUPPORT_NOT_ENABLED == hddctx->tdls_mode) { + hddLog(LOG1, FL("TDLS mode is disabled OR not enabled in FW")); + return ; + } + + adapter = hdd_get_adapter(hddctx, WLAN_HDD_INFRA_STATION); + + if (adapter == NULL) { + hddLog(LOGE, FL("Station Adapter Not Found")); + goto done; + } + + connected_tdls_peers = wlan_hdd_tdlsConnectedPeers(adapter); + if (!connected_tdls_peers) { + hddLog(LOG1, FL("No TDLS connected peers to delete TDLS peers")); + goto done; + } + + /* TDLS is not supported in case of concurrency + * Disable TDLS Offchannel to avoid more than two concurrent channels. + */ + if (connected_tdls_peers == 1) { + tSirMacAddr peer_mac; + int32_t channel; + + mutex_lock(&hddctx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_connected_peer(adapter); + if (curr_peer && (curr_peer->isOffChannelConfigured == TRUE)) { + hddLog(LOG1, FL("%s: Concurrency detected, Disable " + "TDLS channel switch"), __func__); + curr_peer->isOffChannelEstablished = FALSE; + channel = curr_peer->peerParams.channel; + vos_mem_copy(peer_mac, curr_peer->peerMac, sizeof(tSirMacAddr)); + mutex_unlock(&hddctx->tdls_lock); + + sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(adapter), + adapter->sessionId, + peer_mac, + channel, + TDLS_OFF_CHANNEL_BW_OFFSET, + TDLS_CHANNEL_SWITCH_DISABLE); + tdls_unlock = TRUE; + } + if (tdls_unlock == FALSE) + mutex_unlock(&hddctx->tdls_lock); + } + + /* Send Msg to PE for sending deauth and deleting all the TDLS peers */ + sme_DeleteAllTDLSPeers(hddctx->hHal, adapter->sessionId); + + /* As mentioned above TDLS is not supported in case of concurrency + * Find the connected peer and generate TDLS teardown indication to + * supplicant. + */ + for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) { + if (!hddctx->tdlsConnInfo[staIdx].staId) + continue; + + mutex_lock(&hddctx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_all_peer(hddctx, + hddctx->tdlsConnInfo[staIdx].peerMac.bytes); + + if (!curr_peer) + { + mutex_unlock(&hddctx->tdls_lock); + continue; + } + + wlan_hdd_tdls_reset_peer(adapter, curr_peer->peerMac); + + hddLog(LOG1, FL("indicate TDLS teardown (staId %d)"), + curr_peer->staId); + + /* Indicate teardown to supplicant */ + wlan_hdd_tdls_indicate_teardown( + curr_peer->pHddTdlsCtx->pAdapter, + curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_CONCURRENCY, + curr_peer->peerMac); + mutex_unlock(&hddctx->tdls_lock); + + /* Del Sta happened already as part of sme_DeleteAllTDLSPeers + * Hence clear hdd data structure. + */ + hdd_roamDeregisterTDLSSTA(adapter, + hddctx->tdlsConnInfo[staIdx].staId); + wlan_hdd_tdls_decrement_peer_count(adapter); + + hddctx->tdlsConnInfo[staIdx].staId = 0 ; + hddctx->tdlsConnInfo[staIdx].sessionId = 255; + vos_mem_zero(&hddctx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + wlan_hdd_tdls_check_bmps(adapter); + } + +done: + wlan_hdd_tdls_set_mode(hddctx, eTDLS_SUPPORT_DISABLED, FALSE, + HDD_SET_TDLS_MODE_SOURCE_P2P); + hddLog(LOG1, FL("TDLS Support Disabled")); +} + +/** + * hdd_tdls_notify_mode_change - Notify mode change + * @adapter: pointer to hdd adapter + * @hddCtx : pointer to hdd context + * + * Return: None + */ +void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, hdd_context_t *hddctx) +{ + wlan_hdd_tdls_disable_offchan_and_teardown_links(hddctx); +} + +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER +static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData ) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx; + tdlsCtx_t *pHddTdlsCtx; + int discover_req_sent = 0; + v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD; + v_CONTEXT_t pVosContext; + + ENTER(); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pVosContext points to NULL")); + return; + } + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + pHddTdlsCtx = (tdlsCtx_t *)userData; + if (0 != (wlan_hdd_validate_tdls_context(pHddCtx, pHddTdlsCtx))) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid pHddTdlsCtx context")); + return; + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__); + + if (0 == pHddTdlsCtx->discovery_peer_cnt) + pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx); + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each (pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i, + MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->discovery_processed, + discover_req_sent, + curr_peer->tdls_support, + curr_peer->link_status, + curr_peer->discovery_attempt, + pHddTdlsCtx->threshold_config.discovery_tries_n); + + if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) { + if (!curr_peer->discovery_processed) { + + curr_peer->discovery_processed = 1; + discover_req_sent++; + pHddTdlsCtx->discovery_peer_cnt--; + + if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) && + (eTDLS_LINK_IDLE == curr_peer->link_status) && + (curr_peer->tx_pkt >= + pHddTdlsCtx->threshold_config.tx_packet_n)) { + + if (curr_peer->discovery_attempt < + pHddTdlsCtx->threshold_config.discovery_tries_n) { + cfg80211_tdls_oper_request( + pHddTdlsCtx->pAdapter->dev, + curr_peer->peerMac, + NL80211_TDLS_DISCOVERY_REQ, + FALSE, + GFP_KERNEL); + curr_peer->discovery_attempt++; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: Maximum Discovery retries reached", __func__); + curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED; + } + + } + } + } + else + goto exit_loop; + } + } +exit_loop: + + if (0 != pHddTdlsCtx->discovery_peer_cnt) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER", + pHddTdlsCtx->discovery_peer_cnt); + discover_expiry = TDLS_SUB_DISCOVERY_PERIOD; + goto done; + } + discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t; + + wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx); + + + /* Commenting out the following function as it was introducing + * a race condition when pHddTdlsCtx is deleted. Also , this + * function is consuming more time in the timer callback. + * RSSI based trigger needs to revisit this part of the code. + */ + + /* + * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi); + */ + +done: + mutex_unlock(&pHddCtx->tdls_lock); + EXIT(); + return; +} +#endif + +static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData ) +{ +#ifdef CONFIG_TDLS_IMPLICIT + tdlsConnInfo_t *tdlsInfo = (tdlsConnInfo_t *) userData; + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext; + hdd_adapter_t *pAdapter = NULL; + + ENTER(); + + if (!tdlsInfo->staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("peer (staidx %u) doesn't exists"), tdlsInfo->staId); + return; + } + + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pVosContext points to NULL")); + return; + } + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + pAdapter = hdd_get_adapter_by_sme_session_id(pHddCtx, tdlsInfo->sessionId); + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, + (u8 *) &tdlsInfo->peerMac.bytes[0], FALSE); + + if (NULL == curr_peer) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid tdls idle timer expired")); + return; + } + + pHddTdlsCtx = curr_peer->pHddTdlsCtx; + if (0 != (wlan_hdd_validate_tdls_context(pHddCtx, pHddTdlsCtx))) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid pHddTdlsCtx context")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Tx/Rx Idle " MAC_ADDRESS_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->tx_pkt, + curr_peer->rx_pkt, + curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n); + + /* Check tx/rx statistics on this tdls link for recent activities and + * then decide whether to tear down the link or keep it. + */ + if ((curr_peer->tx_pkt >= curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n) || (curr_peer->rx_pkt >= curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n)) + { + /* this tdls link got back to normal, so keep it */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls link to " MAC_ADDRESS_STR " back to normal, will stay", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac)); + } + else + { + /* this tdls link needs to get torn down */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: trigger tdls link to " MAC_ADDRESS_STR " down", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac)); + + wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter, + curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_TXRX_THRESHOLD, + curr_peer->peerMac); + + } + mutex_unlock(&pHddCtx->tdls_lock); + EXIT(); +#endif +} + +static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData ) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext; + + ENTER(); + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pVosContext points to NULL")); + return; + } + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + mutex_lock(&pHddCtx->tdls_lock); + pHddTdlsCtx = (tdlsCtx_t *)userData; + if (0 != (wlan_hdd_validate_tdls_context(pHddCtx, pHddTdlsCtx))) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid pHddTdlsCtx context")); + return; + } + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each (pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " link_status %d" + " tdls_support %d", __func__, MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->link_status, curr_peer->tdls_support); + + if ((pHddCtx->tdls_mode == eTDLS_SUPPORT_DISABLED) && + (eTDLS_LINK_DISCOVERING == curr_peer->link_status)) { + curr_peer->tdls_support = eTDLS_CAP_UNKNOWN; + wlan_hdd_tdls_set_peer_link_status( + curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS is disabled. Resetting link_status of peer " + MAC_ADDRESS_STR " to %d, tdls_support %d", __func__, + MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->link_status, curr_peer->tdls_support); + + goto next_peer; + } + + if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "tx %d, rx %d (thr.pkt %d/idle %d), rssi %d (thr.trig %d/hys %d/tear %d)", + curr_peer->tx_pkt, curr_peer->rx_pkt, + pHddTdlsCtx->threshold_config.tx_packet_n, + pHddTdlsCtx->threshold_config.idle_packet_n, + curr_peer->rssi, + pHddTdlsCtx->threshold_config.rssi_trigger_threshold, + pHddTdlsCtx->threshold_config.rssi_hysteresis, + pHddTdlsCtx->threshold_config.rssi_teardown_threshold); + + if ((eTDLS_LINK_IDLE == curr_peer->link_status) || + (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){ + + if (pHddCtx->cfg_ini->fTDLSExternalControl && + (FALSE == curr_peer->isForcedPeer)) { + goto next_peer; + } + + if (curr_peer->tx_pkt >= + pHddTdlsCtx->threshold_config.tx_packet_n) { + + if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter)) + { + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Tput trigger TDLS pre-setup"); +#ifdef CONFIG_TDLS_IMPLICIT + pHddTdlsCtx->curr_candidate = curr_peer; + wlan_hdd_tdls_implicit_send_discovery_request(pHddTdlsCtx); +#endif + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Maximum peer connected already! %d", + __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) ); + } + goto next_peer; + } + } + else if (eTDLS_LINK_CONNECTED == curr_peer->link_status) { + if ((tANI_S32)curr_peer->rssi < + (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) { + + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_WARN, + "Tear down - low RSSI: " MAC_ADDRESS_STR "!", + MAC_ADDR_ARRAY(curr_peer->peerMac)); +#ifdef CONFIG_TDLS_IMPLICIT + wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter, + curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_RSSI_THRESHOLD, + curr_peer->peerMac); + +#endif + goto next_peer; + } + + /* Only teardown based on non zero idle packet threshold, to address a use + * case where this threshold does not get consider for TEAR DOWN. + */ + + if (( 0 != pHddTdlsCtx->threshold_config.idle_packet_n ) && + ((curr_peer->tx_pkt < + pHddTdlsCtx->threshold_config.idle_packet_n) && + (curr_peer->rx_pkt < + pHddTdlsCtx->threshold_config.idle_packet_n))) { + if (!vos_timer_is_initialized(&curr_peer->peerIdleTimer)) + { + v_U8_t staId = (v_U8_t)curr_peer->staId; + tdlsConnInfo_t *tdlsInfo; + + tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId); + vos_timer_init(&curr_peer->peerIdleTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_idle_cb, + tdlsInfo); + } + if (VOS_TIMER_STATE_RUNNING != + vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!", + MAC_ADDR_ARRAY(curr_peer->peerMac)); + wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter, + &curr_peer->peerIdleTimer, + pHddTdlsCtx->threshold_config.idle_timeout_t); + } + } else { + if (vos_timer_is_initialized( + &curr_peer->peerIdleTimer) && + VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState( + &curr_peer->peerIdleTimer)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!", + MAC_ADDR_ARRAY(curr_peer->peerMac)); + vos_timer_stop( &curr_peer->peerIdleTimer); + } + } + +// if (curr_peer->rssi < +// (pHddTdlsCtx->threshold_config.rssi_hysteresis + +// pHddTdlsCtx->ap_rssi)) { +// +//#ifdef CONFIG_TDLS_IMPLICIT +// cfg80211_tdls_oper_request(pHddTdlsCtx->dev, +// curr_peer->peerMac, +// NL80211_TDLS_TEARDOWN, FALSE, +// GFP_KERNEL); +//#endif +// } + } + } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) { + + if (pHddCtx->cfg_ini->fTDLSExternalControl && + (FALSE == curr_peer->isForcedPeer)) { + goto next_peer; + } + if (!TDLS_IS_CONNECTED(curr_peer)) { + if (curr_peer->tx_pkt >= + pHddTdlsCtx->threshold_config.tx_packet_n) { + + /* Ignore discovery attempt if External Control is enabled, that + * is, peer is forced. In that case, continue discovery attempt + * regardless attempt count + */ + if (curr_peer->isForcedPeer || curr_peer->discovery_attempt++ < + pHddTdlsCtx->threshold_config.discovery_tries_n) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "TDLS UNKNOWN discover "); +#ifdef CONFIG_TDLS_IMPLICIT + pHddTdlsCtx->curr_candidate = curr_peer; + wlan_hdd_tdls_implicit_send_discovery_request(pHddTdlsCtx); +#endif + } + else + { + curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED; + wlan_hdd_tdls_set_peer_link_status( + curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_NOT_SUPPORTED); + + } + } + } + } + +next_peer: + curr_peer->tx_pkt = 0; + curr_peer->rx_pkt = 0; + } + } + + wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter, + &pHddTdlsCtx->peerUpdateTimer, + pHddTdlsCtx->threshold_config.tx_period_t); + mutex_unlock(&pHddCtx->tdls_lock); + EXIT(); +} + +static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext; + + ENTER(); + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pVosContext points to NULL")); + return; + } + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + pHddTdlsCtx = (tdlsCtx_t *)userData; + if (0 != (wlan_hdd_validate_tdls_context(pHddCtx, pHddTdlsCtx))) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid pHddTdlsCtx context")); + return; + } + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + if (eTDLS_LINK_DISCOVERING == tmp->link_status) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " to idle state", __func__, + MAC_ADDR_ARRAY(tmp->peerMac)); + wlan_hdd_tdls_set_peer_link_status( + tmp, + eTDLS_LINK_IDLE, + eTDLS_LINK_NOT_SUPPORTED); + } + } + } + + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter); + EXIT(); + return; +} + +v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData ) +{ + tdlsConnInfo_t *tdlsInfo = (tdlsConnInfo_t *) userData; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t *pAdapter = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + hddTdlsPeer_t *curr_peer = NULL; + + ENTER(); + + if (!tdlsInfo->staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("peer (staidx %u) doesn't exists"), tdlsInfo->staId); + return; + } + if (!pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is NULL")); + return; + } + + pAdapter = hdd_get_adapter_by_sme_session_id(pHddCtx, tdlsInfo->sessionId); + + if (!pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, + (u8 *) &tdlsInfo->peerMac.bytes[0], FALSE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("peer doesn't exists")); + mutex_unlock(&pHddCtx->tdls_lock); + return; + } + pHddTdlsCtx = curr_peer->pHddTdlsCtx; + + if ( NULL == pHddTdlsCtx ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return; + } + if (0 != (wlan_hdd_validate_context( + WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter)))) + { + return; + } + WLANTL_ResumeDataTx( (WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter))->pvosContext, + (v_U8_t *)&curr_peer->staId); + mutex_unlock(&pHddCtx->tdls_lock); + EXIT(); +} + +static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return; + } + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + list_del(pos); + vos_mem_free(tmp); + tmp = NULL; + } + } +} + +void wlan_hdd_tdls_btCoex_cb(void *data, int indType) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + u16 connectedTdlsPeers; + hddTdlsPeer_t *currPeer; + tANI_U16 numCurrTdlsPeers = 0; + + ENTER(); + if ((NULL == data) || (indType < 0)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Invalid arguments")); + return; + } + + pHddCtx = (hdd_context_t *)data; + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + /* if tdls is not enabled, then continue btCoex */ + if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("tdls is not enabled")); + return; + } + + /* get pAdapter context, do we need WLAN_HDD_P2P_CLIENT */ + pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is not valid")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: BtCoex notification type %d", __func__, indType); + /* BtCoex notification type enabled, Disable TDLS */ + if (indType == SIR_COEX_IND_TYPE_TDLS_DISABLE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("BtCoex notification, Disable TDLS")); + mutex_lock(&pHddCtx->tdls_lock); + /* tdls is in progress */ + currPeer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, FALSE); + if (NULL != currPeer) + { + wlan_hdd_tdls_set_peer_link_status (currPeer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + } + mutex_unlock(&pHddCtx->tdls_lock); + + /* while tdls is up */ + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode) + { + connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + /* disable implicit trigger logic & tdls operatoin */ + wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE, + HDD_SET_TDLS_MODE_SOURCE_BTC); + + /* teardown the peers on the btcoex */ + if (connectedTdlsPeers) + { + tANI_U8 staIdx; + hddTdlsPeer_t *curr_peer; + + mutex_lock(&pHddCtx->tdls_lock); + for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) + { + if (pHddCtx->tdlsConnInfo[staIdx].staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: indicate TDLS teardown (staId %d)"), + __func__,pHddCtx->tdlsConnInfo[staIdx].staId); + +#ifdef CONFIG_TDLS_IMPLICIT + curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, + pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); + if(curr_peer) { + wlan_hdd_tdls_indicate_teardown( + curr_peer->pHddTdlsCtx->pAdapter, curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_BTCOEX, + curr_peer->peerMac); + } +#endif + } + } + mutex_unlock(&pHddCtx->tdls_lock); + } + } + /* stop TCP delack timer if BtCoex is enable */ + set_bit(WLAN_BTCOEX_MODE, &pHddCtx->mode); + hdd_manage_delack_timer(pHddCtx); + } + /* BtCoex notification type enabled, Enable TDLS */ + else if (indType == SIR_COEX_IND_TYPE_TDLS_ENABLE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("BtCoex notification, Enable TDLS")); + /* if tdls was enabled before btCoex, re-enable tdls mode */ + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: revert tdls mode %d"), __func__, + pHddCtx->tdls_mode_last); + wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE, + HDD_SET_TDLS_MODE_SOURCE_BTC); + } + + clear_bit(WLAN_BTCOEX_MODE, &pHddCtx->mode); + numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if(numCurrTdlsPeers == 0) { + /* start delack timer if BtCoex is disable and tdls is not present */ + hdd_manage_delack_timer(pHddCtx); + } + } + + EXIT(); + return; +} + +/* initialize TDLS global context */ +void wlan_hdd_tdls_init(hdd_context_t *pHddCtx ) +{ + v_U8_t staIdx; + eHalStatus status; + + pHddCtx->connected_peer_count = 0; + + wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt); + + for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) + { + pHddCtx->tdlsConnInfo[staIdx].staId = 0; + pHddCtx->tdlsConnInfo[staIdx].sessionId = 255; + vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac, + sizeof(v_MACADDR_t)) ; + } + + status = sme_RegisterBtCoexTDLSCallback(pHddCtx->hHal, + wlan_hdd_tdls_btCoex_cb); + if (status != eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to register BT Coex TDLS callback")); + } + + if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) && + (TRUE == sme_IsFeatureSupportedByFW(TDLS))) + { + if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) + { + pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY; + hddLog(LOGE, FL("TDLS Implicit trigger not enabled!")); + return; + } + pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED; + } + else + { + hddLog(LOGE, + FL("TDLS not enabled (%d) or FW doesn't support (%d)"), + pHddCtx->cfg_ini->fEnableTDLSSupport, + sme_IsFeatureSupportedByFW(TDLS)); + pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + } +} + +int wlan_hdd_sta_tdls_init(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tdlsCtx_t *pHddTdlsCtx; + int i; + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s pHddCtx is NULL", __func__); + return -EINVAL; + } + + if (test_bit(TDLS_INIT_DONE, &pAdapter->event_flags)) + { + hddLog(LOG1, + FL("TDLS INIT DONE set to 1, no point in re-init")); + /* Return success as TDLS is already initialized */ + return 0; + } + + if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) || + (FALSE == sme_IsFeatureSupportedByFW(TDLS))) + { + pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + pAdapter->sessionCtx.station.pHddTdlsCtx = NULL; + hddLog(VOS_TRACE_LEVEL_INFO, "%s TDLS not enabled (%d) or FW doesn't support (%d)!", + __func__, pHddCtx->cfg_ini->fEnableTDLSSupport, + sme_IsFeatureSupportedByFW(TDLS)); + return -EINVAL; + } + /* TDLS is supported only in STA / P2P Client modes, + * hence the check for TDLS support in a specific Device mode. + */ + if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS is not supported in mode : %d", __func__, pAdapter->device_mode); + return -EINVAL; + } + /* Check for the valid pHddTdlsCtx. If valid do not further + * allocate the memory, rather continue with the initialization. + * If tdls_initialization would get reinvoked without tdls_exit + * getting invoked (SSR) there is no point to further proceed + * with the memory allocations. + */ + if (NULL == pAdapter->sessionCtx.station.pHddTdlsCtx) + { + pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t)); + + if (NULL == pHddTdlsCtx) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__); + pAdapter->sessionCtx.station.pHddTdlsCtx = NULL; + return -ENOMEM; + } + /* initialize TDLS pAdater context */ + vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t)); +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_discover_peer_cb, + pHddTdlsCtx); +#endif + + vos_timer_init(&pHddTdlsCtx->peerUpdateTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_update_peer_cb, + pHddTdlsCtx); + vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer, + VOS_TIMER_TYPE_SW, + wlan_hdd_tdls_discovery_timeout_peer_cb, + pHddTdlsCtx); + + pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx; + } + + pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx; + + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0); + + pHddTdlsCtx->pAdapter = pAdapter; + + for (i = 0; i < 256; i++) + { + INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]); + } + + pHddTdlsCtx->curr_candidate = NULL; + pHddTdlsCtx->magic = 0; + + /* remember configuration even if it is not used right now. it could be used later */ + pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod; + pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold; + pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod; + pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt; + pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout; + pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold; + pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis; + pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold; + pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold; + + set_bit(TDLS_INIT_DONE, &pAdapter->event_flags); + + return 0; +} + +void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter, tANI_BOOLEAN mutexLock) +{ + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return; + } + + /* + * NOTE: The Callers of this function should ensure to acquire the + * tdls_lock to avoid any concurrent access to the Adapter and logp + * protection has to be ensured. + */ + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + + if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is Null", __func__); + return ; + } + if (!test_bit(TDLS_INIT_DONE, &pAdapter->event_flags)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS INIT DONE set to 0, no point in exit", __func__); + return; + } + clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags); + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return; + } + + /* must stop timer here before freeing peer list, because peerIdleTimer is + part of peer list structure. */ + wlan_hdd_tdls_timers_destroy(pHddTdlsCtx); + wlan_hdd_tdls_free_list(pHddTdlsCtx); + + wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt); + + pHddTdlsCtx->magic = 0; + pHddTdlsCtx->pAdapter = NULL; + vos_mem_free(pHddTdlsCtx); + pAdapter->sessionCtx.station.pHddTdlsCtx = NULL; + pHddTdlsCtx = NULL; +} + +/* stop all monitoring timers per Adapter */ +static void wlan_hdd_tdls_monitor_timers_stop(tdlsCtx_t *pHddTdlsCtx) +{ +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer); +#endif + vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer); + vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); +} + +/* stop all per peer timers */ +static void wlan_hdd_tdls_peer_timers_stop(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + for (i = 0; i < 256; i++) + { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each (pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " -> stop idle timer", + __func__, + MAC_ADDR_ARRAY(curr_peer->peerMac)); + if (vos_timer_is_initialized(&curr_peer->peerIdleTimer)) + vos_timer_stop ( &curr_peer->peerIdleTimer ); + if (vos_timer_is_initialized(&curr_peer->initiatorWaitTimeoutTimer)) + vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer ); + } + } +} + +/* stop all the tdls timers running */ +static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx); + wlan_hdd_tdls_peer_timers_stop(pHddTdlsCtx); +} + +static void wlan_hdd_tdls_monitor_timers_destroy(tdlsCtx_t *pHddTdlsCtx) +{ +#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER + vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer); + vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer); +#endif + vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer); + vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer); + vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); + vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); +} +/*Free all the timers related to the TDLS peer */ +static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + for (i = 0; i < 256; i++) + { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each (pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + + if (vos_timer_is_initialized(&curr_peer->peerIdleTimer)){ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " -> destroy idle timer", + __func__, + MAC_ADDR_ARRAY(curr_peer->peerMac)); + vos_timer_stop ( &curr_peer->peerIdleTimer ); + vos_timer_destroy ( &curr_peer->peerIdleTimer ); + } + if (vos_timer_is_initialized(&curr_peer->initiatorWaitTimeoutTimer)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " -> destroy initiatorWaitTimeoutTimer", + __func__, + MAC_ADDR_ARRAY(curr_peer->peerMac)); + vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer); + vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer); + } + } + } +} + +/* destroy all the tdls timers running */ +static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_monitor_timers_destroy(pHddTdlsCtx); + wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx); +} + +/* if mac address exist, return pointer + if mac address doesn't exist, create a list and add, return pointer + return NULL if fails to get new mac address +*/ +hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac +#else + u8 *mac +#endif + ) +{ + struct list_head *head; + hddTdlsPeer_t *peer; + u8 key; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + + + if (!pAdapter) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL")); + return NULL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return 0; + } + + /* if already there, just update */ + peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (peer != NULL) + { + return peer; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("peer mac address %pM"), mac); + + /* not found, allocate and add the list */ + peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); + if (NULL == peer) { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__); + return NULL; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + + if (NULL == pHddTdlsCtx) + { + vos_mem_free(peer); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return NULL; + } + + key = wlan_hdd_tdls_hash_key(mac); + head = &pHddTdlsCtx->peer_list[key]; + + vos_mem_zero(peer, sizeof(hddTdlsPeer_t)); + vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac)); + peer->pHddTdlsCtx = pHddTdlsCtx; + list_add_tail(&peer->node, head); + + return peer; +} + +/* + * NOTE: + * The Callers of this function should ensure to release the + * tdls_lock before calling this function to avoid deadlocks. + */ + +int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8* mac, +#else + u8* mac, +#endif + tTDLSCapType cap) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->tdls_support = cap; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, + tTDLSLinkStatus status, + tTDLSLinkReason reason) +{ + /*EXT TDLS*/ + tANI_S32 state = 0; + tANI_S32 res = 0; + /*EXT TDLS*/ + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + return; + } + + hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u", + MAC_ADDR_ARRAY(curr_peer->peerMac), status); + + curr_peer->link_status = status; + + /*EXT TDLS*/ + if (curr_peer->isForcedPeer && curr_peer->state_change_notification) + { + /*save the reason for any further query*/ + curr_peer->reason = reason; + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res); + + (curr_peer->state_change_notification)( + curr_peer->peerMac, + state, + res, + curr_peer->pHddTdlsCtx->pAdapter); + + } + /*EXT TDLS*/ + +} + +void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tTDLSLinkStatus linkStatus, + tTDLSLinkReason reason) +{ + + /*EXT TDLS*/ + tANI_S32 state = 0; + tANI_S32 res = 0; + /*EXT TDLS*/ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (pHddCtx == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddCtx is NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer == NULL) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "tdls set peer " MAC_ADDRESS_STR " link status to %u", + MAC_ADDR_ARRAY(curr_peer->peerMac), linkStatus); + + curr_peer->link_status= linkStatus; + + /*EXT TDLS*/ + + if (curr_peer->isForcedPeer && curr_peer->state_change_notification) + { + /*save the reason for any further query*/ + curr_peer->reason = reason; + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res); + mutex_unlock(&pHddCtx->tdls_lock); + (*curr_peer->state_change_notification)(mac, + state, + res, + pAdapter); + } + else + mutex_unlock(&pHddCtx->tdls_lock); + + /*EXT TDLS*/ + return; +} + +int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac) +{ + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx = NULL; + hdd_context_t *pHddCtx; + + ENTER(); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != wlan_hdd_validate_context(pHddCtx)) + return -1; + + mutex_lock(&pHddCtx->tdls_lock); + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if ( NULL == pHddTdlsCtx ) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddTdlsCtx is NULL device mode = %d"), + pAdapter->device_mode); + return -1; + } + + pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter); + + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + mutex_unlock(&pHddCtx->tdls_lock); + return 0; + } + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + + if (NULL == curr_peer) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + if (pHddTdlsCtx->discovery_sent_cnt) + pHddTdlsCtx->discovery_sent_cnt--; + + + wlan_hdd_tdls_check_power_save_prohibited(pAdapter); + + if (0 == pHddTdlsCtx->discovery_sent_cnt) + { + vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer); + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Discovery(%u) Response from " MAC_ADDRESS_STR " link_status %d", + pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->link_status); + + curr_peer->tdls_support = eTDLS_CAP_SUPPORTED; + + if (eTDLS_LINK_DISCOVERING == curr_peer->link_status) + { + /* Since we are here, it means Throughput threshold is alredy met. Make sure RSSI + threshold is also met before setting up TDLS link*/ + if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold) + { + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_DISCOVERED, + eTDLS_LINK_SUCCESS); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" , + MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi, + pHddTdlsCtx->threshold_config.rssi_trigger_threshold); + + if (pHddCtx->tdls_mode != eTDLS_SUPPORT_DISABLED) + { + /* TDLS can be disabled from multiple sources like + * scan, p2p-listen, p2p, btc etc ... + * Dont initiate tdls setup if tdls is disabled + */ + cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, + NL80211_TDLS_SETUP, FALSE, + GFP_KERNEL); + } + else + { + curr_peer->tdls_support = eTDLS_CAP_UNKNOWN; + wlan_hdd_tdls_set_peer_link_status( + curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS is disabled. Resetting link_status of peer " + MAC_ADDRESS_STR " to %d, tdls_support %d", __func__, + MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->link_status, curr_peer->tdls_support); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ", + MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi, + pHddTdlsCtx->threshold_config.rssi_trigger_threshold); + + /* if RSSI threshold is not met then allow further discovery + * attempts by decrementing count for the last attempt + */ + if (curr_peer->discovery_attempt) + curr_peer->discovery_attempt--; + + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + } + mutex_unlock(&pHddCtx->tdls_lock); + } + else + { + mutex_unlock(&pHddCtx->tdls_lock); + wlan_hdd_tdls_check_bmps(pAdapter); + } + + EXIT(); + return 0; +} + +int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tCsrStaParams *StaParams, + tANI_BOOLEAN isBufSta, + tANI_BOOLEAN isOffChannelSupported, + tANI_BOOLEAN isQosWmmSta) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->uapsdQueues = StaParams->uapsd_queues; + curr_peer->maxSp = StaParams->max_sp; + curr_peer->isBufSta = isBufSta; + curr_peer->isOffChannelSupported = isOffChannelSupported; + + vos_mem_copy(curr_peer->supported_channels, + StaParams->supported_channels, + StaParams->supported_channels_len); + + curr_peer->supported_channels_len = + StaParams->supported_channels_len; + + vos_mem_copy(curr_peer->supported_oper_classes, + StaParams->supported_oper_classes, + StaParams->supported_oper_classes_len); + + curr_peer->supported_oper_classes_len = + StaParams->supported_oper_classes_len; + curr_peer->qos = isQosWmmSta; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + tdlsLinkEstablishParams->isResponder = curr_peer->is_responder; + tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues; + tdlsLinkEstablishParams->maxSp = curr_peer->maxSp; + tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta; + tdlsLinkEstablishParams->isOffChannelSupported = + curr_peer->isOffChannelSupported; + + vos_mem_copy(tdlsLinkEstablishParams->supportedChannels, + curr_peer->supported_channels, + curr_peer->supported_channels_len); + + tdlsLinkEstablishParams->supportedChannelsLen = + curr_peer->supported_channels_len; + + vos_mem_copy(tdlsLinkEstablishParams->supportedOperClasses, + curr_peer->supported_oper_classes, + curr_peer->supported_oper_classes_len); + + tdlsLinkEstablishParams->supportedOperClassesLen = + curr_peer->supported_oper_classes_len; + tdlsLinkEstablishParams->qos = curr_peer->qos; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_S8 rxRssi) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(hdd_ctx))) { + return -1; + } + + mutex_lock(&hdd_ctx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer == NULL) + { + mutex_unlock(&hdd_ctx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + return -1; + } + + curr_peer->rssi = rxRssi; + mutex_unlock(&hdd_ctx->tdls_lock); + + return 0; +} + +int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_U8 responder) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->is_responder = responder; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_U8 uSignature) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->signature = uSignature; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + + +void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac) +{ + memcpy(mac, skb->data, 6); +} + +void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac) +{ + memcpy(mac, skb->data+6, 6); +} + +/** + * wlan_hdd_tdls_is_forced_peer - function to check if peer is forced peer + * @adapter: pointer to hdd apater + * @mac: peer mac address + * + * Function identified is the peer is forced for tdls connection + * + * return: true: peer is forced false: peer is not forced + */ +static bool wlan_hdd_tdls_is_forced_peer(hdd_adapter_t *adapter, + const u8 *mac) +{ + hddTdlsPeer_t *peer; + hdd_context_t *hddctx = WLAN_HDD_GET_CTX(adapter); + bool is_forced_peer; + + mutex_lock(&hddctx->tdls_lock); + peer = wlan_hdd_tdls_find_peer(adapter, mac, FALSE); + if (!peer) + { + is_forced_peer = false; + goto ret; + } + + if (!peer->isForcedPeer) + { + is_forced_peer = false; + goto ret; + } + is_forced_peer = true; + +ret: + mutex_unlock(&hddctx->tdls_lock); + return is_forced_peer; +} + +/** + * wlan_hdd_tdls_increment_pkt_count - function to increment tdls tx packet cnt + * @pAdapter: pointer to hdd adapter + * @skb: pointer to sk_buff + * + * Function to increment packet count if packet is destined to tdls peer + * + * return: None + */ +static void wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, + struct sk_buff *skb) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *hdd_sta_ctx; + u8 mac[6]; + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return; + + if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode) + goto error; + + if (!pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) + goto error; + + wlan_hdd_tdls_extract_da(skb, mac); + + if (pHddCtx->cfg_ini->fTDLSExternalControl) + { + if (!wlan_hdd_tdls_is_forced_peer(pAdapter, mac)) + goto error; + } + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (vos_is_macaddr_group((v_MACADDR_t *)mac)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "broadcast packet, not adding to peer list"); + goto error; + } + + if (memcmp(hdd_sta_ctx->conn_info.bssId, mac, 6) == 0) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED, + "packet da is bssid, not adding to peer list"); + goto error; + } + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("curr_peer is NULL")); + mutex_unlock(&pHddCtx->tdls_lock); + goto error; + } + + curr_peer->tx_pkt++; + + mutex_unlock(&pHddCtx->tdls_lock); + +error: + return; +} + +void wlan_hdd_tdls_notify_packet(hdd_adapter_t *adapter, struct sk_buff *skb) +{ + wlan_hdd_tdls_increment_pkt_count(adapter, skb); +} + +static int wlan_hdd_tdls_check_config(tdls_config_params_t *config) +{ + if (config->tdls > 2) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls); + return -1; + } + if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN || + config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%ld>", __func__, config->tx_period_t, + CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX); + return -1; + } + if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN || + config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%ld>", __func__, config->tx_packet_n, + CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX); + return -1; + } + if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN || + config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%ld>", __func__, config->discovery_period_t, + CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX); + return -1; + } + if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN || + config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n, + CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX); + return -1; + } + if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN || + config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t, + CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX); + return -1; + } + if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN || + config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n, + CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX); + return -1; + } + if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN || + config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis, + CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX); + return -1; + } + if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN || + config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold, + CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX); + return -1; + } + if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN || + config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold, + CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX); + return -1; + } + return 0; +} + +int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + eTDLSSupportMode req_tdls_mode; + + if ((TRUE != pHddCtx->cfg_ini->fEnableTDLSSupport) && + (TRUE != sme_IsFeatureSupportedByFW(TDLS))) + { + hddLog(LOGE, + FL("TDLS not enabled (%d) or FW doesn't support (%d)"), + pHddCtx->cfg_ini->fEnableTDLSSupport, + sme_IsFeatureSupportedByFW(TDLS)); + pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; + return -EINVAL; + } + + mutex_lock(&pHddCtx->tdls_lock); + if (NULL == pHddTdlsCtx) + { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS not enabled!")); + return -1; + } + + if (wlan_hdd_tdls_check_config(config) != 0) + { + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + /* config->tdls is mapped to 0->1, 1->2, 2->3 */ + req_tdls_mode = config->tdls + 1; + if (pHddCtx->tdls_mode == req_tdls_mode) + { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls); + return -1; + } + + /* copy the configuration only when given tdls mode is implicit trigger enable */ + if (eTDLS_SUPPORT_ENABLED == req_tdls_mode) + { + memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t)); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "iw set tdls params: %d %d %d %d %d %d %d %d %d %d", + config->tdls, + config->tx_period_t, + config->tx_packet_n, + config->discovery_period_t, + config->discovery_tries_n, + config->idle_timeout_t, + config->idle_packet_n, + config->rssi_hysteresis, + config->rssi_trigger_threshold, + config->rssi_teardown_threshold); + + mutex_unlock(&pHddCtx->tdls_lock); + + wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE, + HDD_SET_TDLS_MODE_SOURCE_USER); + + return 0; +} + +int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + u8 staId) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + mutex_unlock(&pHddCtx->tdls_lock); + return -1; + } + + curr_peer->staId = staId; + + mutex_unlock(&pHddCtx->tdls_lock); + return 0; +} + +int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + tANI_BOOLEAN forcePeer) +{ + /* NOTE: + * Hold mutex tdls_lock before calling this function + */ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((NULL == pHddCtx)) return -1; + + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer == NULL) + goto error; + curr_peer->isForcedPeer = forcePeer; + + return 0; +error: + return -1; +} + +/* if peerMac is found, then it returns pointer to hddTdlsPeer_t + otherwise, it returns NULL +*/ +hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, + const u8 *mac, + tANI_BOOLEAN mutexLock) +{ + u8 key; + struct list_head *pos; + struct list_head *head; + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return 0; + } + + if ( mutexLock ) + { + mutex_lock(&pHddCtx->tdls_lock); + } + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) + { + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; + } + + key = wlan_hdd_tdls_hash_key(mac); + + head = &pHddTdlsCtx->peer_list[key]; + + list_for_each(pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + if (!memcmp(mac, curr_peer->peerMac, 6)) { + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + return curr_peer; + } + } + if ( mutexLock ) + mutex_unlock(&pHddCtx->tdls_lock); + + return NULL; +} + +hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac +#else + u8 *mac +#endif +) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + hddTdlsPeer_t *curr_peer= NULL; + VOS_STATUS status = 0; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer) + { + return curr_peer; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return curr_peer; +} + + +int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac +#else + u8 *mac +#endif +) +{ + hdd_context_t *pHddCtx; + hddTdlsPeer_t *curr_peer; + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + + if (0 != (wlan_hdd_validate_context(pHddCtx))) + return -EINVAL; + + curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: curr_peer is NULL", __func__); + return -1; + } + + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + curr_peer->staId = 0; + + /* Throughput Monitor shall disable the split scan when + * TDLS scan coexistance is disabled.At this point of time + * since TDLS scan coexistance is not meeting the criteria + * to be operational, explicitly make it false to enable + * throughput monitor takes the control of split scan. + */ + if (pHddCtx->isTdlsScanCoexistence == TRUE) + { + pHddCtx->isTdlsScanCoexistence = FALSE; + } + + if((eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) && + (vos_timer_is_initialized(&curr_peer->peerIdleTimer)) && + (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&curr_peer->peerIdleTimer))) + { + vos_timer_stop( &curr_peer->peerIdleTimer ); + } + + return 0; +} + +/* Caller has to take the lock before calling this function */ +static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + tmp->tx_pkt = 0; + tmp->rx_pkt = 0; + } + } + + return ; +} + +/* Caller has to take the lock before calling this function */ +static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *tmp; + struct list_head *pos, *q; + + pHddTdlsCtx->discovery_peer_cnt = 0; + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + tmp->discovery_processed = 0; + } + } + + return 0; +} + +static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx) +{ + int i; + struct list_head *head; + struct list_head *pos, *q; + int discovery_peer_cnt=0; + hddTdlsPeer_t *tmp; + + /* + * This function expects the callers to acquire the Mutex. + */ + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each_safe (pos, q, head) { + tmp = list_entry(pos, hddTdlsPeer_t, node); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s, %d, " MAC_ADDRESS_STR, __func__, i, + MAC_ADDR_ARRAY(tmp->peerMac)); + discovery_peer_cnt++; + } + } + return discovery_peer_cnt; +} + +tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = NULL; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid pAdapter: %p"), pAdapter); + return 0; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return 0; + } + EXIT(); + return pHddCtx->connected_peer_count; +} + +hddTdlsPeer_t *wlan_hdd_tdls_get_connected_peer(hdd_adapter_t *pAdapter) +{ + /* NOTE: + * Hold mutext tdls_lock before calling this function + */ + int i; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer = NULL; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return NULL; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) { + return NULL; + } + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each(pos, head) { + curr_peer= list_entry (pos, hddTdlsPeer_t, node); + if (curr_peer && (curr_peer->link_status == eTDLS_LINK_CONNECTED)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " eTDLS_LINK_CONNECTED", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac)); + return curr_peer; + } + } + } + + EXIT(); + return NULL; +} + +int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen) +{ + int i; + int len, init_len; + struct list_head *head; + struct list_head *pos; + hddTdlsPeer_t *curr_peer; + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return 0; + } + + init_len = buflen; + len = scnprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n", + "MAC", "Id", "cap", "up", "RSSI"); + buf += len; + buflen -= len; + /* 1234567890123456789012345678901234567 */ + len = scnprintf(buf, buflen, "---------------------------------\n"); + buf += len; + buflen -= len; + + mutex_lock(&pHddCtx->tdls_lock); + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) { + mutex_unlock(&pHddCtx->tdls_lock); + len = scnprintf(buf, buflen, "TDLS not enabled\n"); + return len; + } + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + + list_for_each(pos, head) { + curr_peer= list_entry (pos, hddTdlsPeer_t, node); + + if (buflen < 32+1) + break; + len = scnprintf(buf, buflen, + MAC_ADDRESS_STR"%3d%4s%3s%5d\n", + MAC_ADDR_ARRAY(curr_peer->peerMac), + curr_peer->staId, + (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N", + TDLS_IS_CONNECTED(curr_peer) ? "Y":"N", + curr_peer->rssi); + buf += len; + buflen -= len; + } + } + mutex_unlock(&pHddCtx->tdls_lock); + + EXIT(); + return init_len-buflen; +} + +void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((NULL == pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("pHddCtx or pHddTdlsCtx points to NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + if (0 != wlan_hdd_sta_tdls_init(pAdapter)) + { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(LOGE, FL("wlan_hdd_sta_tdls_init failed")); + return; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if ((NULL == pHddTdlsCtx)) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("pHddCtx or pHddTdlsCtx points to NULL device mode = %d"), pAdapter->device_mode); + return; + } + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s, update %d discover %d", __func__, + pHddTdlsCtx->threshold_config.tx_period_t, + pHddTdlsCtx->threshold_config.discovery_period_t); + + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) + { + wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx); + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter, + &pHddTdlsCtx->peerUpdateTimer, + pHddTdlsCtx->threshold_config.tx_period_t); + } + mutex_unlock(&pHddCtx->tdls_lock); + +} + +void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx; + hdd_context_t *pHddCtx; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s", __func__); + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (0 != wlan_hdd_validate_context(pHddCtx)) + return; + + mutex_lock(&pHddCtx->tdls_lock); + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return; + } + + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + wlan_hdd_tdls_exit(pAdapter, TRUE); + + mutex_unlock(&pHddCtx->tdls_lock); +} + +void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode) +{ + pAdapter->mgmtTxCompletionStatus = statusCode; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Mgmt TX Completion %d",__func__, statusCode); + complete(&pAdapter->tdls_mgmt_comp); +} + +void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + pHddCtx->connected_peer_count++; + wlan_hdd_tdls_check_power_save_prohibited(pAdapter); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: %d", + __func__, pHddCtx->connected_peer_count); + + mutex_unlock(&pHddCtx->tdls_lock); + + EXIT(); +} + +void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + if (pHddCtx->connected_peer_count) + pHddCtx->connected_peer_count--; + wlan_hdd_tdls_check_power_save_prohibited(pAdapter); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: %d", + __func__, pHddCtx->connected_peer_count); + + mutex_unlock(&pHddCtx->tdls_lock); + + EXIT(); +} + +void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter) +{ + + tdlsCtx_t *pHddTdlsCtx = NULL; + hdd_context_t *pHddCtx = NULL; + hddTdlsPeer_t *curr_peer; + VOS_STATUS status; + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid pAdapter: %p"), pAdapter); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddCtx points to NULL")); + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, FALSE); + if (NULL != curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls in progress. Dont check for BMPS " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY (curr_peer->peerMac)); + mutex_unlock(&pHddCtx->tdls_lock); + return; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL == pHddTdlsCtx) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx points to NULL")); + return; + } + if ((TDLS_CTX_MAGIC != pHddCtx->scan_ctxt.magic) && + (0 == pHddCtx->connected_peer_count) && + (0 == pHddTdlsCtx->discovery_sent_cnt)) + { + mutex_unlock(&pHddCtx->tdls_lock); + if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: No TDLS peer connected/discovery sent. Enable BMPS", + __func__); + status = hdd_enable_bmps_imps(pHddCtx); + + if (status == VOS_STATUS_SUCCESS) + pHddTdlsCtx->is_tdls_disabled_bmps = false; + } + } + else + { + mutex_unlock(&pHddCtx->tdls_lock); + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS peer connected. Disable BMPS", __func__); + status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION); + + if (status == VOS_STATUS_SUCCESS) + pHddTdlsCtx->is_tdls_disabled_bmps = true; + } + } + return; +} + +/* return pointer to hddTdlsPeer_t if TDLS is ongoing. Otherwise return NULL. + * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE + * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if + mac is NULL, this argument is ignored, and check for all the peer list. + */ +static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + u8 skip_self) +{ + int i; + struct list_head *head; + hddTdlsPeer_t *curr_peer; + struct list_head *pos; + tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);; + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return NULL; + } + + for (i = 0; i < 256; i++) { + head = &pHddTdlsCtx->peer_list[i]; + list_for_each(pos, head) { + curr_peer = list_entry (pos, hddTdlsPeer_t, node); + if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) { + continue; + } + else + { + if (eTDLS_LINK_CONNECTING == curr_peer->link_status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING", + __func__, MAC_ADDR_ARRAY(curr_peer->peerMac)); + return curr_peer; + } + } + } + } + return NULL; +} + +hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const u8 *mac, +#else + u8 *mac, +#endif + u8 skip_self, tANI_BOOLEAN mutexLock) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + hddTdlsPeer_t *curr_peer= NULL; + VOS_STATUS status = 0; + + if (mutexLock) + { + mutex_lock(&pHddCtx->tdls_lock); + } + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + curr_peer = wlan_hdd_tdls_find_progress_peer(pAdapter, mac, skip_self); + if (curr_peer) + { + if (mutexLock) + mutex_unlock(&pHddCtx->tdls_lock); + return curr_peer; + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + if (mutexLock) + mutex_unlock(&pHddCtx->tdls_lock); + return NULL; +} + +static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_timers_stop(pHddTdlsCtx); +} + +static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx) +{ + wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx); + pHddTdlsCtx->discovery_sent_cnt = 0; + wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx); + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + + wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter, + &pHddTdlsCtx->peerUpdateTimer, + pHddTdlsCtx->threshold_config.tx_period_t); +} + +void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode, + v_BOOL_t bUpdateLast, + enum tdls_disable_source source) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + VOS_STATUS status; + hdd_adapter_t *pAdapter; + tdlsCtx_t *pHddTdlsCtx; + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s mode %d", __func__, (int)tdls_mode); + + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + mutex_lock(&pHddCtx->tdls_lock); + + if (pHddCtx->tdls_mode == tdls_mode) + { + mutex_unlock(&pHddCtx->tdls_lock); + hddLog(VOS_TRACE_LEVEL_INFO, "%s already in mode %d", __func__, + (int)tdls_mode); + + if (tdls_mode == eTDLS_SUPPORT_DISABLED) + { + /* + * TDLS is already disabled hence set source mask and return + */ + set_bit((unsigned long)source, &pHddCtx->tdls_source_bitmap); + return; + } + if (tdls_mode == eTDLS_SUPPORT_ENABLED) + { + /* + * TDLS is already disabled hence set source mask and return + */ + clear_bit((unsigned long)source, &pHddCtx->tdls_source_bitmap); + return; + } + return; + } + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + if(eTDLS_SUPPORT_ENABLED == tdls_mode) + { + clear_bit((unsigned long)source, &pHddCtx->tdls_source_bitmap); + + /* + * Check if any TDLS source bit is set and if bitmap is + * not zero then we should not enable TDLS + */ + if (pHddCtx->tdls_source_bitmap) + { + mutex_unlock(&pHddCtx->tdls_lock); + return; + } + wlan_hdd_tdls_implicit_enable(pHddTdlsCtx); + } + else if((eTDLS_SUPPORT_DISABLED == tdls_mode)) + { + set_bit((unsigned long)source, &pHddCtx->tdls_source_bitmap); + wlan_hdd_tdls_implicit_disable(pHddTdlsCtx); + if (pHddTdlsCtx->is_tdls_disabled_bmps) { + if (FALSE == sme_IsPmcBmps(pHddCtx->hHal)) { + VOS_TRACE( VOS_MODULE_ID_HDD, + VOS_TRACE_LEVEL_DEBUG, + "%s: TDLS is disabled. Enable BMPS", + __func__); + status = hdd_enable_bmps_imps(pHddCtx); + + if (status == VOS_STATUS_SUCCESS) + pHddTdlsCtx->is_tdls_disabled_bmps = false; + } + } + } + else if ((eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode)) + { + clear_bit((unsigned long)source, &pHddCtx->tdls_source_bitmap); + + /* + * Check if any TDLS source bit is set and if bitmap is + * not zero then we should not enable TDLS + */ + if (pHddCtx->tdls_source_bitmap) + { + mutex_unlock(&pHddCtx->tdls_lock); + return; + } + wlan_hdd_tdls_implicit_disable(pHddTdlsCtx); + } + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + if(bUpdateLast) + { + pHddCtx->tdls_mode_last = tdls_mode; + } + else + { + pHddCtx->tdls_mode_last = pHddCtx->tdls_mode; + } + pHddCtx->tdls_mode = tdls_mode; + + mutex_unlock(&pHddCtx->tdls_lock); + +} + +static +void wlan_hdd_tdls_implicit_send_discovery_request(tdlsCtx_t * pHddTdlsCtx) +{ + hdd_context_t *pHddCtx = NULL; + hddTdlsPeer_t *curr_peer = NULL, *temp_peer = NULL; + + ENTER(); + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx is NULL")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter); + + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + curr_peer = pHddTdlsCtx->curr_candidate; + if (NULL == curr_peer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + + return; + } + + /* This function is called in mutex_lock */ + temp_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, FALSE); + if (NULL != temp_peer) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR " ongoing. pre_setup ignored", + __func__, MAC_ADDR_ARRAY(temp_peer->peerMac)); + goto done; + } + + if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support) + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_DISCOVERING, + eTDLS_LINK_SUCCESS); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Implicit TDLS, Send Discovery request event", __func__); + + cfg80211_tdls_oper_request(pHddTdlsCtx->pAdapter->dev, + curr_peer->peerMac, + NL80211_TDLS_DISCOVERY_REQ, + FALSE, + GFP_KERNEL); + pHddTdlsCtx->discovery_sent_cnt++; + + wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter); + + wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter, + &pHddTdlsCtx->peerDiscoveryTimeoutTimer, + pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: discovery count %u timeout %u msec", + __func__, pHddTdlsCtx->discovery_sent_cnt, + pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); + +done: + pHddTdlsCtx->curr_candidate = NULL; + pHddTdlsCtx->magic = 0; + EXIT(); + return; +} + +tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + VOS_STATUS status = 0; + tANI_U32 count = 0; + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + if (NULL != pHddTdlsCtx) + { + count = count + pHddTdlsCtx->discovery_sent_cnt; + } + status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext ); + pAdapterNode = pNext; + } + return count; +} + +void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter) +{ + tdlsCtx_t *pHddTdlsCtx = NULL; + hdd_context_t *pHddCtx = NULL; + + + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid pAdapter: %p"), pAdapter); + return; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL(" pHddCtx or pHddTdlsCtx points to NULL")); + return; + } + + if ((0 == pHddCtx->connected_peer_count) && + (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx))) + { + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0); + return; + } + sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1); + return; +} + +/* return negative = caller should stop and return error code immediately + return 0 = caller should stop and return success immediately + return 1 = caller can continue to scan + */ +int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter, + struct wiphy *wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + struct net_device *dev, +#endif + struct cfg80211_scan_request *request) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + u16 connectedTdlsPeers; + hddTdlsPeer_t *curr_peer, *connected_peer; + unsigned long delay; + hdd_config_t *cfg_param = pHddCtx->cfg_ini; + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return 0; + } + + /* if tdls is not enabled, then continue scan */ + if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)) + return 1; + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, FALSE); + if (NULL != curr_peer) + { + if (pHddCtx->scan_ctxt.reject++ >= TDLS_MAX_SCAN_REJECT) + { + pHddCtx->scan_ctxt.reject = 0; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: " MAC_ADDRESS_STR ". scan rejected %d. force it to idle", + __func__, MAC_ADDR_ARRAY (curr_peer->peerMac), pHddCtx->scan_ctxt.reject); + + wlan_hdd_tdls_set_peer_link_status (curr_peer, + eTDLS_LINK_IDLE, + eTDLS_LINK_UNSPECIFIED); + mutex_unlock(&pHddCtx->tdls_lock); + return 1; + } + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls in progress. scan rejected %d", + __func__, pHddCtx->scan_ctxt.reject); + return -EBUSY; + } + else + mutex_unlock(&pHddCtx->tdls_lock); + + /* tdls teardown is ongoing */ + if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode) + { + connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + if (connectedTdlsPeers && (pHddCtx->scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE)) + { + delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec", + __func__, connectedTdlsPeers, pHddCtx->scan_ctxt.attempt, delay); + + wlan_hdd_defer_scan_init_work (pHddCtx, wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request, + msecs_to_jiffies(delay)); + /* scan should not continue */ + return 0; + } + /* no connected peer or max retry reached, scan continue */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls disabled. connected_peers %d attempt %d. scan allowed", + __func__, connectedTdlsPeers, pHddCtx->scan_ctxt.attempt); + return 1; + } + + /* if fEnableTDLSScan flag is 1 ; driverwill allow scan even if + * peer station is not buffer STA capable + * + * RX: If there is any RX activity, device will lose RX packets, + * as peer will not be aware that device is off channel. + * TX: TX is stopped whenever device initiate scan. + */ + if (pHddCtx->cfg_ini->fEnableTDLSScan == 1) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("Allow SCAN in all TDLS cases")); + return 1; + } + + /* while tdls is up, first time scan */ + else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode) + { + connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter); + + /* check the TDLS link and Scan coexistance Capability */ + if ( (TRUE == pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport) && + (TRUE == sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE)) && + (connectedTdlsPeers == 1) ) + { + mutex_lock(&pHddCtx->tdls_lock); + /* get connected peer information */ + connected_peer = wlan_hdd_tdls_get_connected_peer(pAdapter); + if (NULL == connected_peer) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid connected_peer, Continue Scanning", __func__); + /* scan should continue */ + return 1; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: TDLS Scan Co-exist supported connectedTdlsPeers =%d buffersta =%d"), + __func__,connectedTdlsPeers,connected_peer->isBufSta); + + if (connected_peer->isBufSta) + { + mutex_unlock(&pHddCtx->tdls_lock); + pHddCtx->isTdlsScanCoexistence = TRUE; + if ((cfg_param->dynSplitscan) && (!pHddCtx->issplitscan_enabled)) + { + pHddCtx->issplitscan_enabled = TRUE; + sme_enable_disable_split_scan( + WLAN_HDD_GET_HAL_CTX(pAdapter), + cfg_param->nNumStaChanCombinedConc, + cfg_param->nNumP2PChanCombinedConc); + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s:%d TDLS Scan Co-exist supported splitscan_enabled =%d "), + __func__, __LINE__, pHddCtx->issplitscan_enabled); + return 1; + } + else + mutex_unlock(&pHddCtx->tdls_lock); + + } + else + { + /* Throughput Monitor shall disable the split scan when + * TDLS scan coexistance is disabled.At this point of time + * since TDLS scan coexistance is not meeting the criteria + * to be operational, explicitly make it false to enable + * throughput monitor takes the control of split scan. + */ + pHddCtx->isTdlsScanCoexistence = FALSE; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: TDLS Scan Co-exist not supported connectedTdlsPeers =%d" + " TDLSScanCoexSupport param =%d TDLS_SCAN_COEXISTENCE =%d"), + __func__, connectedTdlsPeers, + pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport, + sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE)); + + /* disable implicit trigger logic & tdls operatoin */ + wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE, + HDD_SET_TDLS_MODE_SOURCE_SCAN); + /* fall back to the implementation of teardown the peers on the scan + * when the number of connected peers are more than one. TDLS Scan + * coexistance feature is exercised only when a single peer is + * connected and the DUT shall not advertize the Buffer Sta capability, + * so that the peer shall not go to the TDLS power save + */ + + if (connectedTdlsPeers) + { + tANI_U8 staIdx; + hddTdlsPeer_t *curr_peer; + + mutex_lock(&pHddCtx->tdls_lock); + for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++) + { + if (pHddCtx->tdlsConnInfo[staIdx].staId) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: indicate TDLS teardown (staId %d)"), + __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ; + +#ifdef CONFIG_TDLS_IMPLICIT + curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, + pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes); + if(curr_peer) { + wlan_hdd_tdls_indicate_teardown( + curr_peer->pHddTdlsCtx->pAdapter, curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + hdd_send_wlan_tdls_teardown_event( + eTDLS_TEARDOWN_SCAN, + curr_peer->peerMac); + } +#endif + } + } + mutex_unlock(&pHddCtx->tdls_lock); + /* schedule scan */ + delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec", + __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter), + delay); + + wlan_hdd_defer_scan_init_work (pHddCtx, wiphy, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + dev, +#endif + request, + msecs_to_jiffies(delay)); + /* scan should not continue */ + return 0; + } + /* no connected peer, scan continue */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: tdls_mode %d, and no tdls connection. scan allowed", + __func__, pHddCtx->tdls_mode); + } + EXIT(); + return 1; +} + +void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if(0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + /* if tdls is not enabled then don't revert tdls mode */ + if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("Failed to revert: Mode=%d"), + pHddCtx->tdls_mode); + return; + } + + /* free allocated memory at scan time */ + wlan_hdd_init_deinit_defer_scan_context(&pHddCtx->scan_ctxt); + + /* if tdls was enabled before scan, re-enable tdls mode */ + if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last); + + wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE, + HDD_SET_TDLS_MODE_SOURCE_SCAN); + } + wlan_hdd_tdls_check_bmps(pAdapter); + + EXIT(); +} + +void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter, + vos_timer_t *timer, + v_U32_t expirationTime) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddStaCtx is NULL")); + return; + } + + /* Check whether driver load unload is in progress */ + if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Driver load/unload is in progress.", __func__); + return; + } + + if (hdd_connIsConnected(pHddStaCtx)) + { + vos_timer_stop(timer); + vos_timer_start(timer, expirationTime); + } +} +void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter, + hddTdlsPeer_t *curr_peer, + tANI_U16 reason) +{ + hdd_context_t *pHddCtx; + + if ((NULL == pAdapter || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) || + (NULL == curr_peer)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("parameters passed are invalid")); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + if ((eTDLS_LINK_CONNECTED != curr_peer->link_status) && + (eTDLS_LINK_CONNECTING != curr_peer->link_status)) + return; + + /* Throughput Monitor shall disable the split scan when + * TDLS scan coexistance is disabled.At this point of time + * since TDLS scan coexistance is not meeting the criteria + * to be operational, explicitly make it false to enable + * throughput monitor takes the control of split scan. + */ + if (pHddCtx && (pHddCtx->isTdlsScanCoexistence == TRUE)) + { + pHddCtx->isTdlsScanCoexistence = FALSE; + } + + wlan_hdd_tdls_set_peer_link_status(curr_peer, + eTDLS_LINK_TEARING, + eTDLS_LINK_UNSPECIFIED); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Setting NL80211_TDLS_TEARDOWN, reason %d"), reason); + cfg80211_tdls_oper_request(pAdapter->dev, + curr_peer->peerMac, + NL80211_TDLS_TEARDOWN, + reason, + GFP_KERNEL); +} + + +/*EXT TDLS*/ +int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer, + cfg80211_exttdls_callback callback) +{ + /* NOTE: + * Hold mutex tdls_lock before calling this function + */ + + hdd_context_t *pHddCtx; + hdd_adapter_t *pAdapter; + + if (!curr_peer) return -1; + + pAdapter = curr_peer->pHddTdlsCtx->pAdapter; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if ((NULL == pHddCtx)) return -1; + + curr_peer->state_change_notification = callback; + + return 0; +} + +void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer, + tANI_S32 *state, + tANI_S32 *reason) +{ + *reason = curr_peer->reason; + + switch(curr_peer->link_status) + { + case eTDLS_LINK_IDLE: + case eTDLS_LINK_DISCOVERED: + *state = WIFI_TDLS_ENABLED; + break; + case eTDLS_LINK_DISCOVERING: + case eTDLS_LINK_CONNECTING: + *state = WIFI_TDLS_TRYING; + break; + case eTDLS_LINK_CONNECTED: + if (TRUE == curr_peer->isOffChannelEstablished) + { + *state = WIFI_TDLS_ESTABLISHED_OFF_CHANNEL; + } + else + { + *state = WIFI_TDLS_ESTABLISHED; + } + break; + case eTDLS_LINK_TEARING: + *state = WIFI_TDLS_DROPPED; + break; + } + +} + +int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8* mac, +#else + tANI_U8* mac, +#endif + tANI_S32 *state, + tANI_S32 *reason) +{ + + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if (curr_peer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is NULL")); + + *state = WIFI_TDLS_DISABLED; + *reason = eTDLS_LINK_UNSPECIFIED; + } + else + { + if (pHddCtx->cfg_ini->fTDLSExternalControl && + (FALSE == curr_peer->isForcedPeer)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("curr_peer is not Forced")); + *state = WIFI_TDLS_DISABLED; + *reason = eTDLS_LINK_UNSPECIFIED; + } + else + { + wlan_hdd_tdls_get_wifi_hal_state(curr_peer, state, reason); + } + } + mutex_unlock(&pHddCtx->tdls_lock); + return (0); +} + +int hdd_set_tdls_scan_type(hdd_adapter_t *pAdapter, + tANI_U8 *ptr) +{ + int tdls_scan_type; + hdd_context_t *pHddCtx; + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tdls_scan_type = ptr[9] - '0'; + + if (tdls_scan_type <= 2) + { + pHddCtx->cfg_ini->fEnableTDLSScan = tdls_scan_type; + return 0; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " Wrong value is given for tdls_scan_type " + " Making fEnableTDLSScan as 0 "); + pHddCtx->cfg_ini->fEnableTDLSScan = 0; + return -EINVAL; + } +} +int wlan_hdd_validate_tdls_context(hdd_context_t *pHddCtx, + tdlsCtx_t *pHddTdlsCtx) +{ + VOS_STATUS status; + int found = 0; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter; + + if (NULL == pHddTdlsCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS context is NULL")); + return -EINVAL; + } + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) + { + pAdapter = pAdapterNode->pAdapter; + if (NULL != pAdapter) + { + if (pHddTdlsCtx == pAdapter->sessionCtx.station.pHddTdlsCtx && + (NULL != pHddTdlsCtx->pAdapter) && + (WLAN_HDD_ADAPTER_MAGIC == pHddTdlsCtx->pAdapter->magic)) + { + found = 1; + break; + } + } + status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + if (found == 1) + { + return 0; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS context doesnot belongs to valid adapter")); + return -EINVAL; + } +} + + +void wlan_hdd_tdls_update_rx_pkt_cnt_n_rssi(hdd_adapter_t *pAdapter, + u8 *mac, v_S7_t rssiAvg) +{ + hddTdlsPeer_t *curr_peer; + hdd_context_t *pHddCtx = NULL; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + mutex_lock(&pHddCtx->tdls_lock); + curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE); + if ((NULL != curr_peer) && + (eTDLS_LINK_CONNECTED == curr_peer->link_status)) + { + curr_peer->rx_pkt++; + curr_peer->rssi = rssiAvg; + } + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "mac : " MAC_ADDRESS_STR "rssi is %d", + MAC_ADDR_ARRAY(mac), rssiAvg); +} + +/** + * wlan_hdd_tdls_reenable() - Re-Enable TDLS + * @hddctx: pointer to hdd context + * + * Function re-enable's TDLS which might be disabled during concurrency + * + * Return: None + */ +void wlan_hdd_tdls_reenable(hdd_context_t *pHddCtx) +{ + + if ((TRUE != pHddCtx->cfg_ini->fEnableTDLSSupport) || + (TRUE != sme_IsFeatureSupportedByFW(TDLS))) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("tdls support not enabled")); + return; + } + + /* if tdls is not enabled then don't revert tdls mode */ + if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("TDLS disabled so no need to enable: Mode=%d"), + pHddCtx->tdls_mode); + return; + } + + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == + pHddCtx->tdls_mode_last) { + /* Enable TDLS support Once P2P session ends since + * upond detection of concurrency TDLS might be disabled + */ + hddLog(LOG1, FL("TDLS mode set to %d"), pHddCtx->tdls_mode_last); + wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, + FALSE, HDD_SET_TDLS_MODE_SOURCE_P2P); + } +} + +tdlsConnInfo_t *wlan_hdd_get_conn_info(hdd_context_t *pHddCtx, + tANI_U8 idx) +{ + tANI_U8 staIdx; + + /* check if there is available index for this new TDLS STA */ + for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ ) + { + if (idx == pHddCtx->tdlsConnInfo[staIdx].staId ) + { + hddLog(LOG1, FL("tdls peer with staIdx %u exists"), idx ); + return (&pHddCtx->tdlsConnInfo[staIdx]); + } + } + hddLog(LOGE, FL("tdls peer with staIdx %u not exists"), idx ); + return NULL; +} + +void wlan_hdd_change_tdls_mode(void *data) +{ + hdd_context_t *hdd_ctx = (hdd_context_t *)data; + + wlan_hdd_tdls_set_mode(hdd_ctx, eTDLS_SUPPORT_ENABLED, FALSE, + HDD_SET_TDLS_MODE_SOURCE_OFFCHANNEL); +} + +void wlan_hdd_start_stop_tdls_source_timer(hdd_context_t *pHddCtx, + eTDLSSupportMode tdls_mode) +{ + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->tdls_source_timer)) + vos_timer_stop(&pHddCtx->tdls_source_timer); + + if (tdls_mode == eTDLS_SUPPORT_DISABLED) { + wlan_hdd_tdls_set_mode(pHddCtx, tdls_mode, FALSE, + HDD_SET_TDLS_MODE_SOURCE_OFFCHANNEL); + } + + vos_timer_start(&pHddCtx->tdls_source_timer, + pHddCtx->cfg_ini->tdls_enable_defer_time); + + return; +} + +void wlan_hdd_get_tdls_stats(hdd_adapter_t *pAdapter) +{ + hdd_context_t *pHddCtx = NULL; + tdlsCtx_t *pHddTdlsCtx = NULL; + tANI_U16 numConnectedTdlsPeers = 0; + tANI_U16 numDiscoverySentCnt = 0; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + ENTER(); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter); + + mutex_lock(&pHddCtx->tdls_lock); + if (NULL == pHddTdlsCtx) + { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("pHddTdlsCtx points to NULL")); + return; + } + numConnectedTdlsPeers = pHddCtx->connected_peer_count; + numDiscoverySentCnt = pHddTdlsCtx->discovery_sent_cnt; + mutex_unlock(&pHddCtx->tdls_lock); + + hddLog( LOGE, "%s: TDLS Mode: %d TDLS connected peer count %d" + " DiscoverySentCnt=%d", __func__, pHddCtx->tdls_mode, + numConnectedTdlsPeers, numDiscoverySentCnt); + EXIT(); + + return; +} + + +/*EXT TDLS*/ diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_trace.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_trace.c new file mode 100644 index 000000000000..6901109e46d5 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_trace.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "vos_trace.h" +#include "vos_types.h" +#include "wlan_hdd_trace.h" +#include "wlan_hdd_main.h" + +static tANI_U8* hddTraceGetEventString(tANI_U32 code) +{ + switch(code) + { + CASE_RETURN_STRING(TRACE_CODE_HDD_OPEN_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_STOP_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_TX_TIMEOUT); + CASE_RETURN_STRING(TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMDELTA_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMDELTA_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETBAND_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST); + CASE_RETURN_STRING(TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_ADD_VIRTUAL_INTF); + CASE_RETURN_STRING(TRACE_CODE_HDD_DEL_VIRTUAL_INTF); + CASE_RETURN_STRING(TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_START_AP); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CHANGE_BEACON); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_STOP_AP); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CHANGE_BSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_ADD_KEY); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_GET_KEY ); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CONNECT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_DISCONNECT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_JOIN_IBSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_LEAVE_IBSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_TXPOWER); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_GET_TXPOWER); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SCAN); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_CHANNEL); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_ADD_BEACON); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_BEACON); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CHANGE_IFACE); + CASE_RETURN_STRING(TRACE_CODE_HDD_CHANGE_STATION); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_UPDATE_BSS); + CASE_RETURN_STRING(TRACE_CODE_HDD_REMAIN_ON_CHANNEL); + CASE_RETURN_STRING(TRACE_CODE_HDD_REMAINCHANREADYHANDLER); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL); + CASE_RETURN_STRING(TRACE_CODE_HDD_ACTION); + CASE_RETURN_STRING(TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_GET_STA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_DEL_STA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_ADD_STA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_PMKSA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_DEL_PMKSA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_TDLS_MGMT); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_TDLS_OPER); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_RESUME_WLAN); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_SET_MAC_ACL); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_TESTMODE); + CASE_RETURN_STRING(TRACE_CODE_HDD_CFG80211_DUMP_SURVEY); + CASE_RETURN_STRING(TRACE_CODE_HDD_UNSUPPORTED_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL); + CASE_RETURN_STRING(TRACE_CODE_HDD_STOP_NETDEV); + CASE_RETURN_STRING(TRACE_CODE_HDD_WAKE_NETDEV); + CASE_RETURN_STRING(TRACE_CODE_HDD_FLUSH_TX_QUEUES); + default: + return ("UNKNOWN"); + break; + } +} + +void hddTraceDump(void *pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex) +{ + if (TRACE_CODE_HDD_RX_SME_MSG == pRecord->code) + { + hddLog(LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, "RX SME MSG:", + get_eRoamCmdStatus_str(pRecord->data), pRecord->data); + } + else + { + hddLog(LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, "HDD Event:", + hddTraceGetEventString(pRecord->code), pRecord->data); + } +} + +void hddTraceInit() +{ + vosTraceRegister(VOS_MODULE_ID_HDD, (tpvosTraceCb)&hddTraceDump); +} + +/** + * hdd_state_info_dump() - prints state information of hdd layer + */ +static void hdd_state_info_dump(void) +{ + v_CONTEXT_t vos_ctx_ptr; + hdd_context_t *hdd_ctx_ptr = NULL; + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + VOS_STATUS status; + hdd_station_ctx_t *hdd_sta_ctx = NULL; + hdd_adapter_t *adapter =NULL; + + /* get the global voss context */ + vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + + if (!vos_ctx_ptr) { + hddLog(LOGE, FL("Invalid Global VOSS Context")); + VOS_ASSERT(0); + return; + } + hdd_ctx_ptr = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx_ptr); + if (!hdd_ctx_ptr) { + hddLog(LOGE, FL("HDD context is Null")); + return; + } + + hddLog(LOG1, + FL("mScanPending %d isWlanSuspended %d disable_dfs_flag %d"), + hdd_ctx_ptr->scan_info.mScanPending, + hdd_ctx_ptr->isWlanSuspended, hdd_ctx_ptr->disable_dfs_flag); + + status = hdd_get_front_adapter(hdd_ctx_ptr, &adapter_node); + + while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (adapter->dev) + hddLog(LOG1, FL("device name: %s"), adapter->dev->name); + switch (adapter->device_mode) { + case WLAN_HDD_INFRA_STATION: + case WLAN_HDD_P2P_CLIENT: + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + hddLog(LOG1, FL("connState: %d device_mode: %d"), + hdd_sta_ctx->conn_info.connState, adapter->device_mode); + break; + + default: + break; + } + status = hdd_get_next_adapter(hdd_ctx_ptr, adapter_node, &next); + adapter_node = next; + } +} + +/** + * hdd_register_debug_callback() - registration function for hdd layer + * to print hdd state information + */ +void hdd_register_debug_callback() +{ + vos_register_debug_callback(VOS_MODULE_ID_HDD, &hdd_state_info_dump); +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c new file mode 100644 index 000000000000..b0a8c4201333 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -0,0 +1,3247 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**=========================================================================== + + \file wlan_hdd_tx_rx.c + + \brief Linux HDD Tx/RX APIs + + ==========================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#include +#else +#include +#endif + +#include +#include +#include +#include +#include "sapApi.h" +#include +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif + +#include "vos_diag_core_event.h" +#include "vos_utils.h" +#include "sapInternal.h" +#include "wlan_hdd_trace.h" +#include "wlan_qct_wda.h" +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +const v_U8_t hddWmmAcToHighestUp[] = { + SME_QOS_WMM_UP_RESV, + SME_QOS_WMM_UP_EE, + SME_QOS_WMM_UP_VI, + SME_QOS_WMM_UP_NC +}; + +//Mapping Linux AC interpretation to TL AC. +const v_U8_t hdd_QdiscAcToTlAC[] = { + WLANTL_AC_VO, + WLANTL_AC_VI, + WLANTL_AC_BE, + WLANTL_AC_BK, + WLANTL_AC_HIGH_PRIO, +}; + +#define HDD_TX_TIMEOUT_RATELIMIT_INTERVAL 20*HZ +#define HDD_TX_TIMEOUT_RATELIMIT_BURST 1 +#define HDD_TX_STALL_SSR_THRESHOLD 5 +#define HDD_TX_STALL_SSR_THRESHOLD_HIGH 13 +#define HDD_TX_STALL_RECOVERY_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 2 +#define HDD_TX_STALL_KICKDXE_THRESHOLD HDD_TX_STALL_SSR_THRESHOLD - 4 +#define HDD_TX_STALL_FATAL_EVENT_THRESHOLD 2 +#define EAPOL_MASK 0x8013 +#define EAPOL_M1_BIT_MASK 0x8000 +#define EAPOL_M2_BIT_MASK 0x0001 +#define EAPOL_M3_BIT_MASK 0x8013 +#define EAPOL_M4_BIT_MASK 0x0003 + + +int gRatefromIdx[] = { + 10,20,55,100, + 10,20,55,110, + 60,90,120,180,240,360,480,540, + 65,130,195,260,390,520,585,650, + 72,144,217,289,434,578,650,722, + 65,130,195,260,390,520,585,650, + 135,270,405,540,810,1080,1215,1350, + 150,300,450,600,900,1200,1350,1500, + 135,270,405,540,810,1080,1215,1350, + 1350,1350,65,130,195,260,390, 520, + 585,650,780,1350,1350,1350,1350,1350, + 1350,1350,1350,1350,655,722,866,1350, + 1350,1350,135,270,405,540,810,1080, + 1215,1350,1350,1620,1800,1350,1350,1350, + 1350,1350,1350,1200,1350,1500,1350,1800, + 2000,1350, 292,585,877,1170,1755,2340, + 2632,2925,1350,3510,3900,1350,1350,1350, + 1350,1350,1350,1350,2925,3250,1350,3900, + 4333 + }; +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#define HDD_EAPOL_PACKET_TYPE_OFFSET (15) +#define HDD_EAPOL_KEY_INFO_OFFSET (19) +#define HDD_EAPOL_DEST_MAC_OFFSET (0) +#define HDD_EAPOL_SRC_MAC_OFFSET (6) +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + + +static DEFINE_RATELIMIT_STATE(hdd_tx_timeout_rs, \ + HDD_TX_TIMEOUT_RATELIMIT_INTERVAL, \ + HDD_TX_TIMEOUT_RATELIMIT_BURST); + +static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter); + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function definitions and documenation + -------------------------------------------------------------------------*/ + +#ifdef DATA_PATH_UNIT_TEST +//Utility function to dump an sk_buff +static void dump_sk_buff(struct sk_buff * skb) +{ + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: head = %p", __func__, skb->head); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data = %p", __func__, skb->data); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: tail = %p", __func__, skb->tail); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: end = %p", __func__, skb->end); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: len = %d", __func__, skb->len); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: data_len = %d", __func__, skb->data_len); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: mac_len = %d", __func__, skb->mac_len); + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[0], skb->data[1], skb->data[2], skb->data[3], skb->data[4], + skb->data[5], skb->data[6], skb->data[7]); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", + skb->data[8], skb->data[9], skb->data[10], skb->data[11], skb->data[12], + skb->data[13], skb->data[14], skb->data[15]); +} + +//Function for Unit Test only +static void transport_thread(hdd_adapter_t *pAdapter) +{ + v_U8_t staId; + WLANTL_ACEnumType ac = WLANTL_AC_BE; + vos_pkt_t *pVosPacket = NULL ; + vos_pkt_t dummyPacket; + WLANTL_MetaInfoType pktMetaInfo; + WLANTL_RxMetaInfoType pktRxMetaInfo; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return; + } + + status = hdd_tx_fetch_packet_cbk( pAdapter->pvosContext, + &staId, + &ac, + &pVosPacket, + &pktMetaInfo ); + if (status != VOS_STATUS_SUCCESS && status != VOS_STATUS_E_EMPTY) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_tx_fetch_packet_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_tx_fetch_packet_cbk", __func__); + + status = hdd_tx_complete_cbk(pAdapter->pvosContext, &dummyPacket, VOS_STATUS_SUCCESS); + if (status != VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_tx_complete_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_tx_complete_cbk", __func__); + + status = hdd_tx_low_resource_cbk(pVosPacket, pAdapter); + if (status != VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_tx_low_resource_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_tx_low_resource_cbk", __func__); + + status = hdd_rx_packet_cbk( pAdapter->pvosContext, + &dummyPacket, + staId, + &pktRxMetaInfo); + if (status != VOS_STATUS_SUCCESS) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test FAIL hdd_rx_packet_cbk", __func__); + else + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Test PASS hdd_rx_packet_cbk", __func__); + +} +#endif + + +/**============================================================================ + @brief hdd_flush_tx_queues() - Utility function to flush the TX queues + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +static VOS_STATUS hdd_flush_tx_queues( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + + pAdapter->isVosLowResource = VOS_FALSE; + + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_FLUSH_TX_QUEUES, + pAdapter->sessionId, 0)); + + while (++i != NUM_TX_QUEUES) + { + //Free up any packets in the Tx queue + spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock); + while (true) + { + status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[i], &anchor ); + if(VOS_STATUS_E_EMPTY != status) + { + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + //TODO + //++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + break; + } + spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock); + // backpressure is no longer in effect + pAdapter->isTxSuspended[i] = VOS_FALSE; + } + + return status; +} + +/**============================================================================ + @brief hdd_flush_ibss_tx_queues() - Utility function to flush the TX queues + in IBSS mode + + @param pAdapter : [in] pointer to adapter context + : [in] Staion Id + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId) +{ + v_U8_t i; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info; + + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock); + while (true) + { + if (VOS_STATUS_E_EMPTY != + hdd_list_remove_front(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], + &anchor)) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + break; + } + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock); + } +} + +static struct sk_buff* hdd_mon_tx_fetch_pkt(hdd_adapter_t* pAdapter) +{ + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + v_SIZE_t size = 0; + WLANTL_ACEnumType ac = 0; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_list_node_t *anchor = NULL; + + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return NULL; + } + + // do we have any packets pending in this AC? + hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size ); + if( size == 0 ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: NO Packet Pending", __func__); + return NULL; + } + + //Remove the packet from the queue + spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock); + status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to remove Packet from the list", + __func__); + + return NULL; + } + + // if we are in a backpressure situation see if we can turn the hose back on + if ( (pAdapter->isTxSuspended[ac]) && + (size <= HDD_TX_QUEUE_LOW_WATER_MARK) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: TX queue[%d] re-enabled", __func__, ac); + pAdapter->isTxSuspended[ac] = VOS_FALSE; + /* Enable Queues which we have disabled earlier */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Enabling queues")); + netif_tx_start_all_queues( pAdapter->dev ); + } + + return skb; +} + +void hdd_mon_tx_mgmt_pkt(hdd_adapter_t* pAdapter) +{ + hdd_cfg80211_state_t *cfgState; + struct sk_buff* skb; + hdd_adapter_t* pMonAdapter = NULL; + struct ieee80211_hdr *hdr; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + if (pAdapter == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return; + } + pMonAdapter = hdd_get_adapter( pAdapter->pHddCtx, WLAN_HDD_MONITOR ); + if (pMonAdapter == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: pMonAdapter is NULL", __func__); + return; + } + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + + if( NULL != cfgState->buf ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Already one MGMT packet Tx going on", __func__); + return; + } + + skb = hdd_mon_tx_fetch_pkt(pMonAdapter); + + if (NULL == skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: No Packet Pending", __func__); + return; + } + + cfgState->buf = vos_mem_malloc( skb->len ); //buf; + if( cfgState->buf == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to Allocate memory", __func__); + goto fail; + } + + cfgState->len = skb->len; + + vos_mem_copy( cfgState->buf, skb->data, skb->len); + + cfgState->skb = skb; //buf; + cfgState->action_cookie = (uintptr_t)cfgState->buf; + + hdr = (struct ieee80211_hdr *)skb->data; + if( (hdr->frame_control & HDD_FRAME_TYPE_MASK) + == HDD_FRAME_TYPE_MGMT ) + { + if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK) + == HDD_FRAME_SUBTYPE_DEAUTH ) + { + struct tagCsrDelStaParams delStaParams; + + WLANSAP_PopulateDelStaParams(hdr->addr1, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams); + + hdd_softap_sta_deauth(pAdapter, &delStaParams); + goto mgmt_handled; + } + else if( (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK) + == HDD_FRAME_SUBTYPE_DISASSOC ) + { + hdd_softap_sta_disassoc( pAdapter, hdr->addr1 ); + goto mgmt_handled; + } + } + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Sending action frame to SAP to TX, Len %d", __func__, skb->len); + + if (VOS_STATUS_SUCCESS != + WLANSAP_SendAction( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + skb->data, skb->len, 0) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: WLANSAP_SendAction returned fail", __func__); + hdd_sendActionCnf( pAdapter, FALSE ); + } + EXIT(); + return; + +mgmt_handled: + EXIT(); + hdd_sendActionCnf( pAdapter, TRUE ); + return; +fail: + kfree_skb(pAdapter->skb_to_tx); + pAdapter->skb_to_tx = NULL; + return; +} + +void __hdd_mon_tx_work_queue(struct work_struct *work) +{ + hdd_adapter_t* pAdapter = container_of(work, hdd_adapter_t, monTxWorkQueue); + hdd_mon_tx_mgmt_pkt(pAdapter); +} + +void hdd_mon_tx_work_queue(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_mon_tx_work_queue(work); + vos_ssr_unprotect(__func__); +} + +int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Packet Rcvd at Monitor interface," + " Dropping the packet",__func__); + kfree_skb(skb); + return NETDEV_TX_OK; +} + +/**============================================================================ + @brief hdd_dhcp_pkt_info() - + Function to log DHCP pkt info + + @param skb : [in] pointer to OS packet (sk_buff) + @return : None + ===========================================================================*/ + +void hdd_dhcp_pkt_info(struct sk_buff *skb) +{ + /* port no 67 (0x43) or 68 (0x44) */ + + if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_REQUEST_MSG) + hddLog(VOS_TRACE_LEVEL_INFO, FL("Request")); + else if (*((u8*)skb->data + BOOTP_MSG_OFFSET) == BOOTP_RESPONSE_MSG) + hddLog(VOS_TRACE_LEVEL_INFO, FL("Response")); + else + hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP invalid")); + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("DHCP Dest Addr: %pM Src Addr %pM " + " source port : %d, dest port : %d"), + skb->data, (skb->data + 6), + ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))), + ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET)))); + + if ((skb->data[DHCP_OPTION53_OFFSET] == DHCP_OPTION53) && + (skb->data[DHCP_OPTION53_LENGTH_OFFSET] == DHCP_OPTION53_LENGTH)) { + + switch (skb->data[DHCP_OPTION53_STATUS_OFFSET]) { + case DHCPDISCOVER: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP DISCOVER")); + break; + case DHCPREQUEST: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP REQUEST")); + break; + case DHCPOFFER: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP OFFER")); + break; + case DHCPACK: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP ACK")); + break; + case DHCPNAK: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP NACK")); + break; + case DHCPRELEASE: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP RELEASE")); + break; + case DHCPINFORM: + hddLog(VOS_TRACE_LEVEL_INFO,FL("DHCP INFORM")); + break; + + default: + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: DHCP Not Defined OPTION53 : %d", __func__, + skb->data[DHCP_OPTION53_STATUS_OFFSET]); + } + } +} + +/**============================================================================ + @brief hdd_dump_dhcp_pkt() - + Function to dump DHCP packets in TX and RX path. + + @param skb : [in] pointer to OS packet (sk_buff) + @param path : [in] bool indicating TX/RX path + @return : None + ===========================================================================*/ +void hdd_dump_dhcp_pkt(struct sk_buff *skb, int path) +{ + + if ((ntohs(*((u16*)((u8*)skb->data + ETH_TYPE_OFFSET))) + == ETH_TYPE_IP_PKT) || + (ntohs(*((u8*)skb->data + PROTOCOL_OFFSET)) == UDP_PROTOCOL)) { + + /* IP protocol 12 bytes of mac addresses in 802.3 header */ + if ( ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) == + BOOTP_SERVER_PORT || + ntohs(*((u16*)((u8*)skb->data + UDP_DEST_PORT_OFFSET))) == + BOOTP_CLIENT_PORT || + ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) == + BOOTP_SERVER_PORT || + ntohs(*((u16*)((u8*)skb->data + UDP_SRC_PORT_OFFSET))) == + BOOTP_CLIENT_PORT ) { + + if (path == TX_PATH) { + hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP TX PATH")); + } else { + hddLog(VOS_TRACE_LEVEL_INFO, FL("DHCP RX PATH")); + } + + hdd_dhcp_pkt_info(skb); + } + } +} + +/**============================================================================ + @brief hdd_ibss_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets in case of IBSS. There are 2 versions of this function. + One that uses locked queue and other that uses lockless queues. Both have been + retained to do some performance testing + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ + int hdd_ibss_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) + { + VOS_STATUS status; + WLANTL_ACEnumType ac; + sme_QosWmmUpType up; + skb_list_node_t *pktNode = NULL; + hdd_list_node_t *anchor = NULL; + v_SIZE_t pktListSize = 0; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_ibss_peer_info_t * pPeerInfo; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + v_BOOL_t txSuspended = VOS_FALSE; + struct sk_buff *skb1; + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + + if (NULL == pHddCtx || NULL == pHddStaCtx) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s HDD context is NULL", __func__); + return NETDEV_TX_BUSY; + } + pPeerInfo = &pHddStaCtx->ibss_peer_info; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + + //Get TL AC corresponding to Qdisc queue index/AC. + ac = hdd_QdiscAcToTlAC[skb->queue_mapping]; + + if (eConnectionState_IbssDisconnected == pHddStaCtx->conn_info.connState) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Tx frame in disconnected state in IBSS mode", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + kfree_skb(skb); + return NETDEV_TX_OK; + } + + STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress); + if ((STAId == HDD_WLAN_INVALID_STA_ID) && + (vos_is_macaddr_broadcast( pDestMacAddress ) || + vos_is_macaddr_group(pDestMacAddress))) + { + STAId = IBSS_BROADCAST_STAID; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "%s: BC/MC packet", __func__); + } + else if (STAId >= HDD_MAX_NUM_IBSS_STA) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Received Unicast frame with invalid staID", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + kfree_skb(skb); + return NETDEV_TX_OK; + } + + //user priority from IP header, which is already extracted and set from + //select_queue call back function + up = skb->priority; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; + + VOS_TRACE( VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Classified as ac %d up %d", __func__, ac, up); + + if ( pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP ) + { + hdd_dump_dhcp_pkt(skb, TX_PATH); + } + + spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &pktListSize); + if(pktListSize >= pAdapter->aTxQueueLimit[ac]) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: station %d ac %d queue over limit %d", __func__, STAId, ac, pktListSize); + pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_TRUE; + netif_stop_subqueue(dev, skb_get_queue_mapping(skb)); + txSuspended = VOS_TRUE; + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: TX queue full for AC=%d Disable OS TX queue", + __func__, ac ); + return NETDEV_TX_BUSY; + } + + /* If 3/4th of the max queue size is used then enable the flag. + * This flag indicates to place the DHCP packets in VOICE AC queue.*/ + if (WLANTL_AC_BE == ac) + { + if (pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: TX queue for Best Effort AC is 3/4th full", __func__); + pAdapter->isVosLowResource = VOS_TRUE; + } + else + { + pAdapter->isVosLowResource = VOS_FALSE; + } + } + + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + + //Use the skb->cb field to hold the list node information + pktNode = (skb_list_node_t *)&skb->cb; + + //Stick the OS packet inside this node. + pktNode->skb = skb; + + //Stick the User Priority inside this node + pktNode->userPriority = up; + + INIT_LIST_HEAD(&pktNode->anchor); + + spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + status = hdd_list_insert_back_size( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], + &pktNode->anchor, &pktListSize ); + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s:Insert Tx queue failed. Pkt dropped", __func__); + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + ++pAdapter->stats.tx_dropped; + kfree_skb(skb); + return NETDEV_TX_OK; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[ac]; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count; + + if (1 == pktListSize) + { + //Let TL know we have a packet to send for this AC + status = WLANTL_STAPktPending( pHddCtx->pvosContext, STAId, ac ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "%s: Failed to signal TL for AC=%d STAId =%d", + __func__, ac, STAId ); + + /* Remove the packet from queue. It must be at the back of the queue, as TX thread + * cannot preempt us in the middle as we are in a soft irq context. + * Also it must be the same packet that we just allocated. + */ + spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + status = hdd_list_remove_back( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor); + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + /* Free the skb only if we are able to remove it from the list. + * If we are not able to retrieve it from the list it means that + * the skb was pulled by TX Thread and is use so we should not free + * it here + */ + if (VOS_IS_STATUS_SUCCESS(status)) + { + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb1 = pktNode->skb; + kfree_skb(skb1); + } + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[ac]; + return NETDEV_TX_OK; + } + } + + dev->trans_start = jiffies; + + return NETDEV_TX_OK; + } + +/**============================================================================ + @brief __hdd_hard_start_xmit() - Function registered with the Linux OS for + transmitting packets. There are 2 versions of this function. One that uses + locked queue and other that uses lockless queues. Both have been retained to + do some performance testing + + @param skb : [in] pointer to OS packet (sk_buff) + @param dev : [in] pointer to Libra network device + + @return : NET_XMIT_DROP if packets are dropped + : NET_XMIT_SUCCESS if packet is enqueued succesfully + ===========================================================================*/ +int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + VOS_STATUS status; + WLANTL_ACEnumType qid, ac; + sme_QosWmmUpType up; + skb_list_node_t *pktNode = NULL; + hdd_list_node_t *anchor = NULL; + v_SIZE_t pktListSize = 0; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_BOOL_t granted; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_BOOL_t txSuspended = VOS_FALSE; + struct sk_buff *skb1; + v_BOOL_t arp_pkt; + + if (NULL == pHddCtx) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s HDD context is NULL", __func__); + return NETDEV_TX_BUSY; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitCalled; + + if (unlikely(netif_subqueue_stopped(dev, skb))) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s is called when netif TX %d is disabled", + __func__, skb->queue_mapping); + return NETDEV_TX_BUSY; + } + + arp_pkt = vos_is_arp_pkt(skb, false); + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txCount; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s :ARP packet received form net_dev", __func__); + } + + //Get TL Q index corresponding to Qdisc queue index/AC. + qid = hdd_QdiscAcToTlAC[skb->queue_mapping]; + ac = qid; + + if (qid == WLANTL_AC_HIGH_PRIO) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s It must be a Eapol/Wapi/DHCP packet device_mode:%d", + __func__, pAdapter->device_mode); + ac = hddWmmUpToAcMap[skb->priority]; + } + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + FL("Tx frame in not associated state in %d context"), + pAdapter->device_mode); + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_TX_FRAME_IN_NOT_ASSOCIATED_STATE; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s :Tx frame in not associated state, ARP packet Dropped ", + __func__); + } + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid]; + kfree_skb(skb); + return NETDEV_TX_OK; + } + STAId = pHddStaCtx->conn_info.staId[0]; + + //user priority from IP header, which is already extracted and set from + //select_queue call back function + up = skb->priority; + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[qid]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: Classified as ac %d up %d", __func__, ac, up); +#endif // HDD_WMM_DEBUG + + if (pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_FIRST_XMIT_TIME, (void *)skb, 0); + } + + spin_lock(&pAdapter->wmm_tx_queue[qid].lock); + /*CR 463598,384996*/ + /*For every increment of 10 pkts in the queue, we inform TL about pending pkts. + *We check for +1 in the logic,to take care of Zero count which + *occurs very frequently in low traffic cases */ + if((pAdapter->wmm_tx_queue[qid].count + 1) % 10 == 0) + { + /* Use the following debug statement during Engineering Debugging.There are chance that this will lead to a Watchdog Bark + * if it is in the mainline code and if the log level is enabled by someone for debugging + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,"%s:Queue is Filling up.Inform TL again about pending packets", __func__);*/ + + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId, qid + ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: WLANTL_STAPktPending() returned error code %d", + __func__, status); + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_WLANTL_STAPKTPENDING_RETURNED_ERROR_CODE; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:ARP Packet Dropped WLANTL_STAPktPending returned error %d", + __func__, status); + } + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid]; + kfree_skb(skb); + spin_unlock(&pAdapter->wmm_tx_queue[qid].lock); + return NETDEV_TX_OK; + } + } + + if (pHddCtx->bad_sta[STAId]) { + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *fskb = NULL; + + if (pAdapter->wmm_tx_queue[qid].count >= + pAdapter->wmm_tx_queue[qid].max_size / 2) { + hdd_list_remove_front(&pAdapter->wmm_tx_queue[qid], + &anchor); + pktNode = list_entry(anchor, skb_list_node_t, anchor); + fskb = pktNode->skb; + kfree_skb(fskb); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + } + } + + //If we have already reached the max queue size, disable the TX queue + if ( pAdapter->wmm_tx_queue[qid].count == pAdapter->wmm_tx_queue[qid].max_size) + { + ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressured; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitBackPressuredAC[qid]; + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queue for QId %d"), qid); + netif_tx_stop_queue(netdev_get_tx_queue(dev, skb_get_queue_mapping(skb))); + pAdapter->isTxSuspended[qid] = VOS_TRUE; + txSuspended = VOS_TRUE; + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_NETDEV, + pAdapter->sessionId, qid)); + } + + /* If 3/4th of the max queue size is used then enable the flag. + * This flag indicates to place the DHCP packets in VOICE AC queue.*/ + if (WLANTL_AC_BE == qid) + { + if (pAdapter->wmm_tx_queue[qid].count >= HDD_TX_QUEUE_LOW_WATER_MARK) + { + pAdapter->isVosLowResource = VOS_TRUE; + } + else + { + pAdapter->isVosLowResource = VOS_FALSE; + } + } + + spin_unlock(&pAdapter->wmm_tx_queue[qid].lock); + + if (( NULL != pHddCtx ) && + (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP)) + { + hdd_dump_dhcp_pkt(skb, TX_PATH); + } + + if (VOS_TRUE == txSuspended) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue full for QId=%d Disable OS TX queue", + __func__, qid ); + return NETDEV_TX_BUSY; + } + + //Use the skb->cb field to hold the list node information + pktNode = (skb_list_node_t *)&skb->cb; + + //Stick the OS packet inside this node. + pktNode->skb = skb; + + //Stick the User Priority inside this node + pktNode->userPriority = up; + + + INIT_LIST_HEAD(&pktNode->anchor); + + //Insert the OS packet into the appropriate AC queue + spin_lock(&pAdapter->wmm_tx_queue[qid].lock); + status = hdd_list_insert_back_size( &pAdapter->wmm_tx_queue[qid], &pktNode->anchor, &pktListSize ); + spin_unlock(&pAdapter->wmm_tx_queue[qid].lock); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__); + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_INSERT_TX_QUEUE_FAILED; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Insert Tx queue failed. ARP packet dropped", __func__); + } + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid]; + ++pAdapter->stats.tx_dropped; + kfree_skb(skb); + return NETDEV_TX_OK; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueued; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitQueuedAC[qid]; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count; + + if (HDD_PSB_CHANGED == pAdapter->psbChanged) + { + /* Function which will determine acquire admittance for a + * WMM AC is required or not based on psb configuration done + * in the framework + */ + hdd_wmm_acquire_access_required(pAdapter, ac); + } + + //Make sure we have access to this access category + if (((pAdapter->psbChanged & (1 << ac)) && likely(pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed)) || + (pHddStaCtx->conn_info.uIsAuthenticated == VOS_FALSE)) + { + granted = VOS_TRUE; + } + else + { + status = hdd_wmm_acquire_access( pAdapter, ac, &granted ); + pAdapter->psbChanged |= (1 << ac); + } + + if ( (granted && ( pktListSize == 1 )) || + (qid == WLANTL_AC_HIGH_PRIO)) + { + //Let TL know we have a packet to send for this AC + //VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s:Indicating Packet to TL", __func__); + status = WLANTL_STAPktPending( + (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId, qid ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Failed to signal TL for QId=%d", __func__, qid ); + + //Remove the packet from queue. It must be at the back of the queue, as TX thread cannot preempt us in the middle + //as we are in a soft irq context. Also it must be the same packet that we just allocated. + spin_lock(&pAdapter->wmm_tx_queue[qid].lock); + status = hdd_list_remove_back( &pAdapter->wmm_tx_queue[qid], &anchor ); + spin_unlock(&pAdapter->wmm_tx_queue[qid].lock); + /* Free the skb only if we are able to remove it from the list. + * If we are not able to retrieve it from the list it means that + * the skb was pulled by TX Thread and is use so we should not free + * it here + */ + if (VOS_IS_STATUS_SUCCESS(status)) + { + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb1 = pktNode->skb; + kfree_skb(skb1); + } + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILED_TO_SIGNAL_TL; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ARP packet Dropped : Failed to signal TL for QId=%d", + __func__, qid ); + } + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped; + ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid]; + return NETDEV_TX_OK; + } + } + + dev->trans_start = jiffies; + + return NETDEV_TX_OK; +} + +int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + int ret; + vos_ssr_protect(__func__); + ret = __hdd_hard_start_xmit(skb, dev); + vos_ssr_unprotect(__func__); + return ret; +} + +/**============================================================================ + @brief hdd_Ibss_GetStaId() - Get the StationID using the Peer Mac address + + @param pHddStaCtx : [in] pointer to HDD Station Context + pMacAddress [in] pointer to Peer Mac address + staID [out] pointer to Station Index + @return : VOS_STATUS_SUCCESS/VOS_STATUS_E_FAILURE + ===========================================================================*/ + +VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, v_MACADDR_t *pMacAddress, v_U8_t *staId) +{ + v_U8_t idx; + + for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) + { + if (vos_mem_compare(&pHddStaCtx->conn_info.peerMacAddress[ idx ], + pMacAddress, sizeof(v_MACADDR_t))) + { + *staId = pHddStaCtx->conn_info.staId[idx]; + return VOS_STATUS_SUCCESS; + } + } + + return VOS_STATUS_E_FAILURE; +} + +/**============================================================================ + @brief __hdd_tx_timeout() - Function handles timeout during transmission. + + @param dev : [in] pointer to network device + @return : None + ===========================================================================*/ +void __hdd_tx_timeout(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + struct netdev_queue *txq; + hdd_remain_on_chan_ctx_t *pRemainChanCtx; + int i = 0; + int status = 0; + v_ULONG_t diff_in_jiffies = 0; + hdd_station_ctx_t *pHddStaCtx = NULL; + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Transmission timeout occurred jiffies %lu dev->trans_start %lu", + __func__,jiffies,dev->trans_start); + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (status !=0 ) + { + return; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if ( NULL == pHddStaCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pHddStaCtx is NULL")); + return; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txTimeoutCount; + + //Getting here implies we disabled the TX queues for too long. Queues are + //disabled either because of disassociation or low resource scenarios. In + //case of disassociation it is ok to ignore this. But if associated, we have + //do possible recovery here + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "num_bytes AC0: %d AC1: %d AC2: %d AC3: %d", + pAdapter->wmm_tx_queue[0].count, + pAdapter->wmm_tx_queue[1].count, + pAdapter->wmm_tx_queue[2].count, + pAdapter->wmm_tx_queue[3].count); + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "tx_suspend AC0: %d AC1: %d AC2: %d AC3: %d", + pAdapter->isTxSuspended[0], + pAdapter->isTxSuspended[1], + pAdapter->isTxSuspended[2], + pAdapter->isTxSuspended[3]); + + for (i = 0; i < dev->num_tx_queues; i++) + { + txq = netdev_get_tx_queue(dev, i); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "Queue%d status: %d txq->trans_start %lu", + i, netif_tx_queue_stopped(txq),txq->trans_start); + } + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "carrier state: %d", netif_carrier_ok(dev)); + + /* continuousTxTimeoutCount will be reset whenever TL fetches packet + * from HDD + */ + ++pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount; + + diff_in_jiffies = jiffies - pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut; + if((pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > 1)&& + ((diff_in_jiffies) > (HDD_TX_TIMEOUT * 2 )) + ) + { + /* + * In Open security case when there is no traffic is running, it may possible + * tx time-out may once happen and later we recovered then we need to + * reset the continuousTxTimeoutCount because it is only getting modified + * when traffic is running. So if over a period of time if this count reaches + * to HDD_TX_STALL_SSR_THRESHOLD then host is triggering false subsystem restart. + * so in genuine Tx Time out case kernel will call the tx time-out back to back at + * interval of HDD_TX_TIMEOUT.So now we are checking if previous TX TIME out was + * occurred more then twice of HDD_TX_TIMEOUT back then we may recovered here. + */ + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("This is false alarm so resetting the continuousTxTimeoutCount")); + } + + //update last jiffies after the check + pAdapter->hdd_stats.hddTxRxStats.jiffiesLastTxTimeOut = jiffies; + + if (!pHddStaCtx->conn_info.uIsAuthenticated) { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + FL("TL is not in authenticated state so skipping SSR")); + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + goto print_log; + } + if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount == + HDD_TX_STALL_KICKDXE_THRESHOLD) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Request Kick DXE for recovery",__func__); + WLANTL_TLDebugMessage(WLANTL_DEBUG_KICKDXE); + } + if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount == + HDD_TX_STALL_RECOVERY_THRESHOLD) + { + VOS_TRACE(VOS_MODULE_ID_HDD_SAP_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Request firmware for recovery",__func__); + WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP); + } + + /* + * This function is getting called in softirq context, So don't hold + * any mutex. + * There is no harm here in not holding the mutex as long as we are + * not accessing the pRemainChanCtx contents. + */ + pRemainChanCtx = hdd_get_remain_on_channel_ctx(pHddCtx); + if (!pRemainChanCtx) + { + if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > + HDD_TX_STALL_SSR_THRESHOLD) + { + // Driver could not recover, issue SSR + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot recover from Data stall Issue SSR", + __func__); + WLANTL_FatalError(); + // reset count after issuing the SSR + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + return; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "Remain on channel in progress"); + /* The supplicant can retry "P2P Invitation Request" for 120 times + * and so there is a possbility that we can remain off channel for + * the entire duration of these retries(which can be max 60sec). + * If we encounter such a case, let us not trigger SSR after 30sec + * but wait for 60sec to let the device go on home channel and start + * tx. If tx does not start within 70sec we will issue SSR. + */ + if (pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount > + HDD_TX_STALL_SSR_THRESHOLD_HIGH) + { + // Driver could not recover, issue SSR + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot recover from Data stall Issue SSR", + __func__); + WLANTL_FatalError(); + return; + } + } + +print_log: + /* If Tx stalled for a long time then *hdd_tx_timeout* is called + * every 5sec. The TL debug spits out a lot of information on the + * serial console, if it is called every time *hdd_tx_timeout* is + * called then we may get a watchdog bite on the Application + * processor, so ratelimit the TL debug logs. + */ + if (__ratelimit(&hdd_tx_timeout_rs)) + { + hdd_wmm_tx_snapshot(pAdapter); + WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT); + } + /* Call fatal event if data stall is for + * HDD_TX_STALL_FATAL_EVENT_THRESHOLD times + */ + if (HDD_TX_STALL_FATAL_EVENT_THRESHOLD == + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount) + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DATA_STALL, + FALSE, TRUE); +} + +/**============================================================================ + @brief hdd_tx_timeout() - Function called by OS if there is any + timeout during transmission. Since HDD simply enqueues packet + and returns control to OS right away, this would never be invoked + + @param dev : [in] pointer to network device + @return : None + ===========================================================================*/ +void hdd_tx_timeout(struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_tx_timeout(dev); + vos_ssr_unprotect(__func__); +} + +/**============================================================================ + @brief __hdd_stats() - Function registered with the Linux OS for + device TX/RX statistic + + @param dev : [in] pointer to Libra network device + + @return : pointer to net_device_stats structure + ===========================================================================*/ +struct net_device_stats* __hdd_stats(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return NULL; + } + + return &pAdapter->stats; +} + +struct net_device_stats* hdd_stats(struct net_device *dev) +{ + struct net_device_stats* dev_stats; + + vos_ssr_protect(__func__); + dev_stats = __hdd_stats(dev); + vos_ssr_unprotect(__func__); + + return dev_stats; +} + +/**============================================================================ + @brief hdd_ibss_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +void hdd_ibss_init_tx_rx( hdd_adapter_t *pAdapter ) +{ + v_U8_t i; + v_U8_t STAId = 0; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_ibss_peer_info_t *pPeerInfo = &pHddStaCtx->ibss_peer_info; + v_U8_t pACWeights[] = { + HDD_SOFTAP_BK_WEIGHT_DEFAULT, + HDD_SOFTAP_BE_WEIGHT_DEFAULT, + HDD_SOFTAP_VI_WEIGHT_DEFAULT, + HDD_SOFTAP_VO_WEIGHT_DEFAULT + }; + + pAdapter->isVosOutOfResource = VOS_FALSE; + pAdapter->isVosLowResource = VOS_FALSE; + + // Since SAP model is used for IBSS also. Using same queue length as in SAP. + pAdapter->aTxQueueLimit[WLANTL_AC_BK] = HDD_SOFTAP_TX_BK_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_BE] = HDD_SOFTAP_TX_BE_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_VI] = HDD_SOFTAP_TX_VI_QUEUE_MAX_LEN; + pAdapter->aTxQueueLimit[WLANTL_AC_VO] = HDD_SOFTAP_TX_VO_QUEUE_MAX_LEN; + + for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++) + { + vos_mem_zero(&pPeerInfo->ibssStaInfo[STAId], sizeof(hdd_ibss_station_info_t)); + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + hdd_list_init(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + } + + /* Update the AC weights suitable for SoftAP mode of operation */ + WLANTL_SetACWeights((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, pACWeights); +} + +/**============================================================================ + @brief hdd_ibss_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context.. + @return : VOS_STATUS_E_FAILURE if any errors encountered. + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_ibss_deinit_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t STAId = 0; + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + hdd_ibss_peer_info_t * pPeerInfo = &pHddStaCtx->ibss_peer_info; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + v_SINT_t i = -1; + + for (STAId = 0; STAId < HDD_MAX_NUM_IBSS_STA; STAId++) + { + if (VOS_FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed) + { + continue; + } + for (i = 0; i < NUM_TX_QUEUES; i ++) + { + spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock); + while (true) + { + status = hdd_list_remove_front ( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i], &anchor); + + if (VOS_STATUS_E_EMPTY != status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushed; + ++pAdapter->hdd_stats.hddTxRxStats.txFlushedAC[i]; + kfree_skb(skb); + continue; + } + + //current list is empty + break; + } + pPeerInfo->ibssStaInfo[STAId].txSuspended[i] = VOS_FALSE; + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[i].lock); + } + } + pAdapter->isVosLowResource = VOS_FALSE; + + return status; +} + +/**============================================================================ + @brief hdd_init_tx_rx() - Init function to initialize Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + pAdapter->isVosOutOfResource = VOS_FALSE; + pAdapter->isVosLowResource = VOS_FALSE; + + //vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats)); + //Will be zeroed out during alloc + + while (++i != NUM_TX_QUEUES) + { + pAdapter->isTxSuspended[i] = VOS_FALSE; + hdd_list_init( &pAdapter->wmm_tx_queue[i], HDD_TX_QUEUE_MAX_LEN); + } + + return status; +} + + +/**============================================================================ + @brief hdd_deinit_tx_rx() - Deinit function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_deinit_tx_rx( hdd_adapter_t *pAdapter ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SINT_t i = -1; + + if ( NULL == pAdapter ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("pAdapter is NULL")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + status = hdd_flush_tx_queues(pAdapter); + if (VOS_STATUS_SUCCESS != status) + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + FL("failed to flush tx queues")); + + while (++i != NUM_TX_QUEUES) + { + //Free up actual list elements in the Tx queue + hdd_list_destroy( &pAdapter->wmm_tx_queue[i] ); + } + + return status; +} + + +/**============================================================================ + @brief hdd_disconnect_tx_rx() - Disconnect function to clean up Tx/RX + modules in HDD + + @param pAdapter : [in] pointer to adapter context + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_disconnect_tx_rx( hdd_adapter_t *pAdapter ) +{ + return hdd_flush_tx_queues(pAdapter); +} + + +/**============================================================================ + @brief hdd_IsEAPOLPacket() - Checks the packet is EAPOL or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is EAPOL + : VOS_FALSE otherwise + ===========================================================================*/ + +v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_BOOL_t fEAPOL = VOS_FALSE; + void *pBuffer = NULL; + + + vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, + &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + if ( pBuffer && *(unsigned short*)pBuffer == + vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X) ) + { + fEAPOL = VOS_TRUE; + } + } + + return fEAPOL; +} + +/**============================================================================ + @brief hdd_IsARP() - Checks the packet is ARP or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is ARP + : VOS_FALSE otherwise + ===========================================================================*/ + +v_BOOL_t hdd_IsARP( vos_pkt_t *pVosPacket ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_BOOL_t fIsARP = VOS_FALSE; + void *pBuffer = NULL; + + + vosStatus = vos_pkt_peek_data( pVosPacket, + (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, + &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + if ( pBuffer && *(unsigned short*)pBuffer == + vos_cpu_to_be16(HDD_ETHERTYPE_ARP) ) + { + fIsARP = VOS_TRUE; + } + } + + return fIsARP; +} + +#ifdef FEATURE_WLAN_WAPI // Need to update this function +/**============================================================================ + @brief hdd_IsWAIPacket() - Checks the packet is WAI or not. + + @param pVosPacket : [in] pointer to vos packet + @return : VOS_TRUE if the packet is WAI + : VOS_FALSE otherwise + ===========================================================================*/ + +v_BOOL_t hdd_IsWAIPacket( vos_pkt_t *pVosPacket ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_BOOL_t fIsWAI = VOS_FALSE; + void *pBuffer = NULL; + + // Need to update this function + vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, + &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); + + if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + if ( pBuffer && *(unsigned short*)pBuffer == + vos_cpu_to_be16(HDD_ETHERTYPE_WAI) ) + { + fIsWAI = VOS_TRUE; + } + } + + return fIsWAI; +} +#endif /* FEATURE_WLAN_WAPI */ + +/**============================================================================ + @brief hdd_tx_complete_cbk() - Callback function invoked by TL + to indicate that a packet has been transmitted across the SDIO bus + succesfully. OS packet resources can be released after this cbk. + + @param vosContext : [in] pointer to VOS context + @param pVosPacket : [in] pointer to VOS packet (containing skb) + @param vosStatusIn : [in] status of the transmission + + @return : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_tx_complete_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacket, + VOS_STATUS vosStatusIn ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + void* pOsPkt = NULL; + + if( ( NULL == vosContext ) || ( NULL == pVosPacket ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Return the skb to the OS + status = vos_pkt_get_os_packet( pVosPacket, &pOsPkt, VOS_TRUE ); + if (!VOS_IS_STATUS_SUCCESS( status )) + { + //This is bad but still try to free the VOSS resources if we can + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + //Get the Adapter context. + pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_INFRA_STATION); + if (pAdapter == NULL || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Invalid adapter %p", __func__, pAdapter); + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txCompleted; + } + + kfree_skb((struct sk_buff *)pOsPkt); + + //Return the VOS packet resources. + status = vos_pkt_return_packet( pVosPacket ); + if (!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Could not return VOS packet to the pool", __func__); + } + + return status; +} + +/**============================================================================ + @brief hdd_ibss_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ac : [in] access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_ibss_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ac, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter = NULL; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + vos_pkt_t *pVosPacket = NULL; + v_MACADDR_t* pDestMacAddress = NULL; + v_TIME_t timestamp; + v_SIZE_t size = 0; + v_U8_t STAId = WLAN_MAX_STA_COUNT; + hdd_context_t *pHddCtx = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + hdd_ibss_peer_info_t *pPeerInfo = NULL; + v_U8_t proto_type = 0; + v_U16_t packet_size; + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pStaId ) || + ( NULL == ppVosPacket ) || + ( NULL == pPktMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null Params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + STAId = *pStaId; + pAdapter = pHddCtx->sta_to_adapter[STAId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + pHddStaCtx = &pAdapter->sessionCtx.station; + pPeerInfo = &pHddStaCtx->ibss_peer_info; + + if (FALSE == pPeerInfo->ibssStaInfo[STAId].isUsed ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Unregistered STAId %d passed by TL", __func__, STAId); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetched; + + *ppVosPacket = NULL; + + //Make sure the AC being asked for is sane + if( ac > WLANTL_MAX_AC || ac < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid AC %d passed by TL", __func__, ac); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac]; + + //Get the vos packet before so that we are prepare for VOS low reseurce condition + //This simplifies the locking and unlocking of Tx queue + status = vos_pkt_wrap_data_packet( &pVosPacket, + VOS_PKT_TYPE_TX_802_3_DATA, + NULL, //OS Pkt is not being passed + hdd_tx_low_resource_cbk, + pAdapter ); + + if ((status == VOS_STATUS_E_ALREADY) || (status == VOS_STATUS_E_RESOURCES)) + { + //Remember VOS is in a low resource situation + pAdapter->isVosOutOfResource = VOS_TRUE; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: VOSS in Low Resource scenario", __func__); + //TL needs to handle this case. VOS_STATUS_E_EMPTY is returned when the queue is empty. + return VOS_STATUS_E_FAILURE; + } + + /* Only fetch this station and this AC. Return VOS_STATUS_E_EMPTY if nothing there. + Do not get next AC as the other branch does. + */ + spin_lock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + hdd_list_size(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &size); + + if (0 == size) + { + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_EMPTY; + } + + status = hdd_list_remove_front( &pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pPeerInfo->ibssStaInfo[STAId].wmm_tx_queue[ac].lock); + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: AC %d has packets pending", __func__, ac); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Error in de-queuing skb from Tx queue status = %d", + __func__, status ); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_FAILURE; + } + + //Attach skb to VOS packet. + status = vos_pkt_set_os_packet( pVosPacket, skb ); + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Error attaching skb", __func__); + vos_pkt_return_packet(pVosPacket); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Return VOS packet to TL; + *ppVosPacket = pVosPacket; + + //Fill out the meta information needed by TL + vos_pkt_get_timestamp( pVosPacket, ×tamp ); + pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp; + if ( 1 < size ) + { + pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send + } + else + { + pPktMetaInfo->bMorePackets = 0; + } + + if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE) + pPktMetaInfo->ucIsEapol = 0; + else + pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0; + + if ((NULL != pHddCtx) && + (pHddCtx->cfg_ini->gEnableDebugLog)) + { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog); + if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "IBSS STA TX EAPOL"); + } + else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "IBSS STA TX DHCP"); + } + else if (VOS_PKT_PROTO_TYPE_ARP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "IBSS STA TX ARP"); + } + } + + vos_pkt_get_packet_length( pVosPacket,&packet_size ); + if ( HDD_ETHERTYPE_ARP_SIZE == packet_size ) + pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0; + + pPktMetaInfo->ucUP = pktNode->userPriority; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + pPktMetaInfo->ucType = 0; + + //Extract the destination address from ethernet frame + pDestMacAddress = (v_MACADDR_t*)skb->data; + + // we need 802.3 to 802.11 frame translation + // (note that Bcast/Mcast will be translated in SW, unicast in HW) + pPktMetaInfo->ucDisableFrmXtl = 0; + pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0; + pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0; + + if ( (pPeerInfo->ibssStaInfo[STAId].txSuspended[ac]) && + (size <= ((pAdapter->aTxQueueLimit[ac]*3)/4) )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue re-enabled", __func__); + pPeerInfo->ibssStaInfo[STAId].txSuspended[ac] = VOS_FALSE; + netif_wake_subqueue(pAdapter->dev, skb_get_queue_mapping(skb)); + } + + // We're giving the packet to TL so consider it transmitted from + // a statistics perspective. We account for it here instead of + // when the packet is returned for two reasons. First, TL will + // manipulate the skb to the point where the len field is not + // accurate, leading to inaccurate byte counts if we account for + // it later. Second, TL does not provide any feedback as to + // whether or not the packet was successfully sent over the air, + // so the packet counts will be the same regardless of where we + // account for them + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac]; + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Valid VOS PKT returned to TL", __func__); + + return status; +} + +/**============================================================================ + @brief hdd_tx_fetch_packet_cbk() - Callback function invoked by TL to + fetch a packet for transmission. + + @param vosContext : [in] pointer to VOS context + @param staId : [in] Station for which TL is requesting a pkt + @param ac : [in] access category requested by TL + @param pVosPacket : [out] pointer to VOS packet packet pointer + @param pPktMetaInfo : [out] pointer to meta info for the pkt + + @return : VOS_STATUS_E_EMPTY if no packets to transmit + : VOS_STATUS_E_FAILURE if any errors encountered + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_tx_fetch_packet_cbk( v_VOID_t *vosContext, + v_U8_t *pStaId, + WLANTL_ACEnumType ac, + vos_pkt_t **ppVosPacket, + WLANTL_MetaInfoType *pPktMetaInfo ) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_list_node_t *anchor = NULL; + skb_list_node_t *pktNode = NULL; + struct sk_buff *skb = NULL; + vos_pkt_t *pVosPacket = NULL; + v_MACADDR_t* pDestMacAddress = NULL; + v_TIME_t timestamp; + WLANTL_ACEnumType newAc; + v_SIZE_t size = 0; + v_U16_t packet_size; + tANI_U8 acAdmitted, i; + v_U8_t proto_type = 0; + WLANTL_ACEnumType actualAC; + v_BOOL_t arp_pkt; + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pStaId ) || + ( NULL == ppVosPacket ) || + ( NULL == pPktMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null Params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + //Get the HDD context. + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if(pHddCtx == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + pAdapter = pHddCtx->sta_to_adapter[*pStaId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("invalid adapter:%p for staId:%u"), pAdapter, *pStaId); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetched; + + *ppVosPacket = NULL; + + //Make sure the AC being asked for is sane + if (ac > WLANTL_AC_HIGH_PRIO || ac < 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid QId %d passed by TL", __func__, ac); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.txFetchedAC[ac]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: AC %d passed by TL", __func__, ac); +#endif // HDD_WMM_DEBUG + + // do we have any packets pending in this AC? + hdd_list_size( &pAdapter->wmm_tx_queue[ac], &size ); + if( size > 0 ) + { + // yes, so process it +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: AC %d has packets pending", __func__, ac); +#endif // HDD_WMM_DEBUG + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty; +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: no packets pending", __func__); +#endif // HDD_WMM_DEBUG + return VOS_STATUS_E_FAILURE; + } + + // Note here that we are not checking "wmmAcAccessAllowed" for packets + // in new queue since there is no one AC associated to the new queue. + // Since there will be either eapol or dhcp pkts in new queue overlooking + // this should be okay from implicit QoS perspective. + if (ac != WLANTL_AC_HIGH_PRIO) + { + // We find an AC with packets + // or we determine we have no more packets to send + // HDD is not allowed to change AC. + + // has this AC been admitted? or + // To allow EAPOL packets when not authenticated + if (unlikely((0==pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed) && + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.uIsAuthenticated)) + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchEmpty; +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "%s: no packets pending", __func__); +#endif // HDD_WMM_DEBUG + return VOS_STATUS_E_FAILURE; + } + } + + //Get the vos packet. I don't want to dequeue and enqueue again if we are out of VOS resources + //This simplifies the locking and unlocking of Tx queue + status = vos_pkt_wrap_data_packet( &pVosPacket, + VOS_PKT_TYPE_TX_802_3_DATA, + NULL, //OS Pkt is not being passed + hdd_tx_low_resource_cbk, + pAdapter ); + + if (status == VOS_STATUS_E_ALREADY || status == VOS_STATUS_E_RESOURCES) + { + //Remember VOS is in a low resource situation + pAdapter->isVosOutOfResource = VOS_TRUE; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchLowResources; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOSS in Low Resource scenario", __func__); + //TL will now think we have no more packets in this AC + return VOS_STATUS_E_FAILURE; + } + + //Remove the packet from the queue + spin_lock_bh(&pAdapter->wmm_tx_queue[ac].lock); + status = hdd_list_remove_front( &pAdapter->wmm_tx_queue[ac], &anchor ); + spin_unlock_bh(&pAdapter->wmm_tx_queue[ac].lock); + + if(VOS_STATUS_SUCCESS == status) + { + //If success then we got a valid packet from some AC + pktNode = list_entry(anchor, skb_list_node_t, anchor); + skb = pktNode->skb; + actualAC = hddWmmUpToAcMap[pktNode->userPriority]; + if (actualAC >= WLANTL_MAX_AC) + { + /* To fix klocwork */ + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, + "%s: Invalid AC for packet:%d", __func__, actualAC); + actualAC = WLANTL_AC_BE; + } + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN, "%s: Error in de-queuing " + "skb from Tx queue status = %d", __func__, status ); + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_FAILURE; + } + arp_pkt = vos_is_arp_pkt(skb, false); + //Attach skb to VOS packet. + status = vos_pkt_set_os_packet( pVosPacket, skb ); + if (status != VOS_STATUS_SUCCESS) + { + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_ERROR_ATTACHING_SKB; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s :Error attaching skb,ARP packet droped", __func__); + } + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: Error attaching skb", __func__); + vos_pkt_return_packet(pVosPacket); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + + //Just being paranoid. To be removed later + if(pVosPacket == NULL) + { + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.txDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_VOS_PACKET_RETURNED_BY_VOSS_IS_NULL; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s :VOS packet returned by VOSS is NULL,ARP packet droped", + __func__); + } + + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOS packet returned by VOSS is NULL", __func__); + ++pAdapter->stats.tx_dropped; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError; + kfree_skb(skb); + return VOS_STATUS_E_FAILURE; + } + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + if (vos_is_macaddr_multicast((v_MACADDR_t*)skb->data)) + { + pAdapter->hdd_stats.hddTxRxStats.txMcast[actualAC]++; + } + +#endif + + wlan_hdd_tdls_notify_packet(pAdapter, skb); + + //Return VOS packet to TL; + *ppVosPacket = pVosPacket; + + //Fill out the meta information needed by TL + //FIXME This timestamp is really the time stamp of wrap_data_packet + vos_pkt_get_timestamp( pVosPacket, ×tamp ); + pPktMetaInfo->usTimeStamp = (v_U16_t)timestamp; + + if(pAdapter->sessionCtx.station.conn_info.uIsAuthenticated == VOS_TRUE) + pPktMetaInfo->ucIsEapol = 0; + else + pPktMetaInfo->ucIsEapol = hdd_IsEAPOLPacket( pVosPacket ) ? 1 : 0; + + if (pPktMetaInfo->ucIsEapol) + wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED); + if ((NULL != pHddCtx) && + (pHddCtx->cfg_ini->gEnableDebugLog)) + { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog); + if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA TX EAPOL"); + } + else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA TX DHCP"); + } + else if (VOS_PKT_PROTO_TYPE_ARP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA TX ARP"); + } + } + + vos_pkt_get_packet_length( pVosPacket,&packet_size ); + if( HDD_ETHERTYPE_ARP_SIZE == packet_size ) + pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0; + + if(pPktMetaInfo->ucIsArp) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s :STA TX ARP Received in TL ",__func__); + } + +#ifdef FEATURE_WLAN_WAPI + // Override usIsEapol value when its zero for WAPI case + pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0; +#endif /* FEATURE_WLAN_WAPI */ + + /* 1. Check if ACM is set for this AC + * 2. If set, check if this AC had already admitted + * 3. If not already admitted, downgrade the UP to next best UP + * 4. Allow only when medium time is non zero when Addts accepted + * else downgrade traffic. we opted downgrading over Delts when + * medium time is zero because while doing downgradig driver is not + * clearing the wmm context so consider in subsequent roaming + * if AP (new or same AP) accept the Addts with valid medium time + * no application support is required where if we have opted + * delts Applications have to again do Addts or STA will never + * go for Addts. + */ + pPktMetaInfo->ac = actualAC; + if(!pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcAccessRequired || + (pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid && + pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecInfo.medium_time)) + { + pPktMetaInfo->ucUP = pktNode->userPriority; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + } + else + { + //Downgrade the UP + acAdmitted = pAdapter->hddWmmStatus.wmmAcStatus[actualAC].wmmAcTspecValid; + newAc = WLANTL_AC_BK; + for (i=actualAC-1; i>0; i--) + { + if (pAdapter->hddWmmStatus.wmmAcStatus[i].wmmAcAccessRequired == 0) + { + newAc = i; + break; + } + } + pPktMetaInfo->ucUP = hddWmmAcToHighestUp[newAc]; + pPktMetaInfo->ucTID = pPktMetaInfo->ucUP; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW, + "Downgrading UP %d to UP %d ", + pktNode->userPriority, pPktMetaInfo->ucUP); + } + + if (pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_TL_FIRST_XMIT_TIME, NULL, 0); + } + + pPktMetaInfo->ucType = 0; //FIXME Don't know what this is + pPktMetaInfo->ucDisableFrmXtl = 0; //802.3 frame so we need to xlate + if ( 1 < size ) + { + pPktMetaInfo->bMorePackets = 1; //HDD has more packets to send + } + else + { + pPktMetaInfo->bMorePackets = 0; + } + + //Extract the destination address from ethernet frame + pDestMacAddress = (v_MACADDR_t*)skb->data; + pPktMetaInfo->ucBcast = vos_is_macaddr_broadcast( pDestMacAddress ) ? 1 : 0; + pPktMetaInfo->ucMcast = vos_is_macaddr_group( pDestMacAddress ) ? 1 : 0; + + + + // if we are in a backpressure situation see if we can turn the hose back on + if ( (pAdapter->isTxSuspended[ac]) && + (size <= HDD_TX_QUEUE_LOW_WATER_MARK) ) + { + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressured; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDePressuredAC[ac]; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: TX queue[%d] re-enabled", __func__, ac); + pAdapter->isTxSuspended[ac] = VOS_FALSE; + netif_tx_wake_queue(netdev_get_tx_queue(pAdapter->dev, + skb_get_queue_mapping(skb) )); + MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_WAKE_NETDEV, + pAdapter->sessionId, ac)); + } + + + // We're giving the packet to TL so consider it transmitted from + // a statistics perspective. We account for it here instead of + // when the packet is returned for two reasons. First, TL will + // manipulate the skb to the point where the len field is not + // accurate, leading to inaccurate byte counts if we account for + // it later. Second, TL does not provide any feedback as to + // whether or not the packet was successfully sent over the air, + // so the packet counts will be the same regardless of where we + // account for them + pAdapter->stats.tx_bytes += skb->len; + ++pAdapter->stats.tx_packets; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeued; + ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeuedAC[ac]; + pAdapter->hdd_stats.hddTxRxStats.continuousTxTimeoutCount = 0; + + if((pHddCtx->cfg_ini->thermalMitigationEnable) && + (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)) + { + if(mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Tm Lock fail", __func__); + return VOS_STATUS_E_FAILURE; + } + if(WLAN_HDD_TM_LEVEL_1 < pHddCtx->tmInfo.currentTmLevel) + { + if(0 == pHddCtx->tmInfo.txFrameCount) + { + /* Just recovered from sleep timeout */ + pHddCtx->tmInfo.lastOpenTs = timestamp; + } + + if((VOS_FALSE == pHddCtx->tmInfo.qBlocked) && + ((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) && + (pHddCtx->tmInfo.txFrameCount >= pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold)) + { + /* During TX open duration, TX frame count is larger than threshold + * Block TX during Sleep time */ + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_stop_all_queues(pAdapter->dev); + pHddCtx->tmInfo.qBlocked = VOS_TRUE; + pHddCtx->tmInfo.lastblockTs = timestamp; + if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pHddCtx->tmInfo.txSleepTimer)) + { + vos_timer_start(&pHddCtx->tmInfo.txSleepTimer, pHddCtx->tmInfo.tmAction.txSleepDuration); + } + } + else if(((timestamp - pHddCtx->tmInfo.lastOpenTs) > (pHddCtx->tmInfo.tmAction.txOperationDuration / 10)) && + (pHddCtx->tmInfo.txFrameCount < pHddCtx->tmInfo.tmAction.txBlockFrameCountThreshold)) + { + /* During TX open duration, TX frame count is less than threshold + * Reset count and timestamp to prepare next cycle */ + pHddCtx->tmInfo.lastOpenTs = timestamp; + pHddCtx->tmInfo.txFrameCount = 0; + } + else + { + /* Do Nothing */ + } + pHddCtx->tmInfo.txFrameCount++; + } + mutex_unlock(&pHddCtx->tmInfo.tmOperationLock); + } + + +#ifdef HDD_WMM_DEBUG + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,"%s: Valid VOS PKT returned to TL", __func__); +#endif // HDD_WMM_DEBUG + + return status; +} + + +/**============================================================================ + @brief hdd_tx_low_resource_cbk() - Callback function invoked in the + case where VOS packets are not available at the time of the call to get + packets. This callback function is invoked by VOS when packets are + available. + + @param pVosPacket : [in] pointer to VOS packet + @param userData : [in] opaque user data that was passed initially + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + =============================================================================*/ +VOS_STATUS hdd_tx_low_resource_cbk( vos_pkt_t *pVosPacket, + v_VOID_t *userData ) +{ + VOS_STATUS status; + v_SINT_t i = 0; + v_SIZE_t size = 0; + hdd_adapter_t* pAdapter = (hdd_adapter_t *)userData; + + if (NULL == pAdapter || WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Invalid adapter %p"), pAdapter); + return VOS_STATUS_E_FAILURE; + } + + //Return the packet to VOS. We just needed to know that VOS is out of low resource + //situation. Here we will only signal TL that there is a pending data for a STA. + //VOS packet will be requested (if needed) when TL comes back to fetch data. + vos_pkt_return_packet( pVosPacket ); + + pAdapter->isVosOutOfResource = VOS_FALSE; + + //Indicate to TL that there is pending data if a queue is non empty + for( i=NUM_TX_QUEUES-1; i>=0; --i ) + { + size = 0; + hdd_list_size( &pAdapter->wmm_tx_queue[i], &size ); + if ( size > 0 ) + { + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId [0], + (WLANTL_ACEnumType)i ); + if( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure in indicating pkt to TL for ac=%d", __func__, i); + } + } + } + + return VOS_STATUS_SUCCESS; +} + +static void hdd_mon_add_rx_radiotap_hdr (struct sk_buff *skb, + int rtap_len, v_PVOID_t pRxPacket, hdd_mon_ctx_t *pMonCtx) +{ + u8 rtap_temp[28] = {0}; + struct ieee80211_radiotap_header *rthdr; + unsigned char *pos; + u32 mac_time; + u16 rx_flags = 0; + u16 rateIdx; + u16 channel_flags = 0; + u8 rfBand; + s8 currentRSSI, currentRSSI0, currentRSSI1; + s8 noise; + + mac_time = WDA_GET_RX_TIMESTAMP(pRxPacket); + rateIdx = WDA_GET_RX_MAC_RATE_IDX(pRxPacket); + if( rateIdx >= 210 && rateIdx <= 217) + rateIdx-=202; + if( rateIdx >= 218 && rateIdx <= 225 ) + rateIdx-=210; + + if(rateIdx >= (sizeof(gRatefromIdx)/ sizeof(int))) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: invalid rateIdx %d make it 0", __func__, rateIdx); + rateIdx = 0; + } + rfBand = WDA_GET_RX_RFBAND(pRxPacket); + if (IS_5G_BAND(rfBand)) + channel_flags |= IEEE80211_CHAN_5GHZ; + else + channel_flags |= IEEE80211_CHAN_2GHZ; + currentRSSI0 = WDA_GETRSSI0(pRxPacket) - 100; + currentRSSI1 = WDA_GETRSSI1(pRxPacket) - 100; + currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1; + noise = WDA_GET_RX_SNR(pRxPacket); + + rthdr = (struct ieee80211_radiotap_header *)(&rtap_temp[0]); + + /* radiotap header, set always present flags */ + rthdr->it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | + (1 << IEEE80211_RADIOTAP_FLAGS) | + (1 << IEEE80211_RADIOTAP_CHANNEL) | + (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | + (1 << IEEE80211_RADIOTAP_RX_FLAGS)); + rthdr->it_len = cpu_to_le16(rtap_len); + + pos = (unsigned char *) (rthdr + 1); + + /* IEEE80211_RADIOTAP_TSFT */ + put_unaligned_le64(mac_time, pos); + pos += 8; + + /* IEEE80211_RADIOTAP_FLAGS */ + *pos = 0; + pos++; + + /* IEEE80211_RADIOTAP_RATE */ + *pos = gRatefromIdx[rateIdx]/5; + pos++; + + /* IEEE80211_RADIOTAP_CHANNEL */ + put_unaligned_le16(pMonCtx->ChannelNo, pos); + pos += 2; + put_unaligned_le16(channel_flags, pos); + pos += 2; + + /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ + *pos = currentRSSI; + pos++; + + /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ + *pos = noise; + pos++; + + if ((pos - (u8 *)rthdr) & 1) + pos++; + put_unaligned_le16(rx_flags, pos); + pos += 2; + + memcpy(skb_push(skb, rtap_len), &rtap_temp[0], rtap_len); +} + + +VOS_STATUS hdd_rx_packet_monitor_cbk(v_VOID_t *vosContext,vos_pkt_t *pVosPacket, int conversion) +{ + struct sk_buff *skb = NULL; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_mon_ctx_t *pMonCtx = NULL; + v_PVOID_t pvBDHeader = NULL; + int rxstat; + int needed_headroom = 0; + + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pVosPacket ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Failed to get pHddCtx from vosContext")); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = hdd_get_adapter(pHddCtx,WLAN_HDD_MONITOR); + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Invalid adapter %p for MONITOR MODE"), pAdapter); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + status = WDA_DS_PeekRxPacketInfo( pVosPacket, (v_PVOID_t)&pvBDHeader, 1/*Swap BD*/ ); + if ( NULL == pvBDHeader ) + { + VOS_TRACE( VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR, + "Cannot extract BD header"); + /* Drop packet */ + vos_pkt_return_packet(pVosPacket); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxChains; + status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_TRUE ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + vos_pkt_return_packet( pVosPacket ); + return VOS_STATUS_E_FAILURE; + } + + if(!conversion) + { + pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter); + needed_headroom = sizeof(struct ieee80211_radiotap_header) + 18; + hdd_mon_add_rx_radiotap_hdr( skb, needed_headroom, pvBDHeader, pMonCtx ); + } + + skb_reset_mac_header( skb ); + skb->dev = pAdapter->dev; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_802_2); + skb->ip_summed = CHECKSUM_NONE; + ++pAdapter->hdd_stats.hddTxRxStats.rxPackets; + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += skb->len; + + rxstat = netif_rx_ni(skb); + if (NET_RX_SUCCESS == rxstat) + { + ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count; + } + else + { + ++pAdapter->hdd_stats.hddTxRxStats.rxRefused; + } + + status = vos_pkt_return_packet( pVosPacket ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__); + } + pAdapter->dev->last_rx = jiffies; + +return status; +} + +bool hdd_is_duplicate_ip_arp(struct sk_buff *skb) +{ + struct in_ifaddr **ifap = NULL; + struct in_ifaddr *ifa = NULL; + struct in_device *in_dev; + uint32_t arp_ip,if_ip; + + if (NULL == skb) + return false; + + arp_ip = hdd_get_arp_src_ip(skb); + + if(!skb->dev) return false; + + in_dev = __in_dev_get_rtnl(skb->dev); + + if (in_dev) { + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) { + if (!strcmp(skb->dev->name, ifa->ifa_label)) + break; + } + } + if (ifa && ifa->ifa_local) { + + if_ip = ntohl(ifa->ifa_local); + if (if_ip == arp_ip) { + return true; + } + } + + return false; +} + +/**============================================================================ + @brief hdd_rx_packet_cbk() - Receive callback registered with TL. + TL will call this to notify the HDD when one or more packets were + received for a registered STA. + + @param vosContext : [in] pointer to VOS context + @param pVosPacketChain : [in] pointer to VOS packet chain + @param staId : [in] Station Id + @param pRxMetaInfo : [in] pointer to meta info for the received pkt(s) + + @return : VOS_STATUS_E_FAILURE if any errors encountered, + : VOS_STATUS_SUCCESS otherwise + ===========================================================================*/ +VOS_STATUS hdd_rx_packet_cbk( v_VOID_t *vosContext, + vos_pkt_t *pVosPacketChain, + v_U8_t staId, + WLANTL_RxMetaInfoType* pRxMetaInfo ) +{ + hdd_adapter_t *pAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + int rxstat; + struct sk_buff *skb = NULL; + vos_pkt_t* pVosPacket; + vos_pkt_t* pNextVosPacket; + v_U8_t proto_type = 0; + v_BOOL_t arp_pkt; + + //Sanity check on inputs + if ( ( NULL == vosContext ) || + ( NULL == pVosPacketChain ) || + ( NULL == pRxMetaInfo ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = (hdd_context_t *)vos_get_context( VOS_MODULE_ID_HDD, vosContext ); + if ( NULL == pHddCtx ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + pAdapter = pHddCtx->sta_to_adapter[staId]; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("Invalid adapter %p for staId %u"), pAdapter, staId); + return VOS_STATUS_E_FAILURE; + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxChains; + + // walk the chain until all are processed + pVosPacket = pVosPacketChain; + do + { + // get the pointer to the next packet in the chain + // (but don't unlink the packet since we free the entire chain later) + status = vos_pkt_walk_packet_chain( pVosPacket, &pNextVosPacket, VOS_FALSE); + + // both "success" and "empty" are acceptable results + if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY))) + { + + if(hdd_IsARP(pVosPacket)) + { + ++pAdapter->hdd_stats.hddArpStats.rxDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_WALKING_PACKET_CHAIN; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ARP packet Drop: Failure walking packet chain", __func__); + } + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure walking packet chain", __func__); + return VOS_STATUS_E_FAILURE; + } + + // Extract the OS packet (skb). + status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + + if(hdd_IsARP(pVosPacket)) + { + ++pAdapter->hdd_stats.hddArpStats.rxDropped; + pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_EXTRACTING_SKB_FROM_VOS_PKT; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: ARP packet Dropped: Failure extracting skb from vos pkt", + __func__); + } + ++pAdapter->hdd_stats.hddTxRxStats.rxDropped; + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure extracting skb from vos pkt", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (TRUE == hdd_IsEAPOLPacket( pVosPacket )) + wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); + + pVosPacket->pSkb = NULL; + + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL, + "Magic cookie(%x) for adapter sanity verification is invalid", pAdapter->magic); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_TDLS + if ((eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) && + 0 != pHddCtx->connected_peer_count) + { + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + u8 mac[6]; + + memcpy(mac, skb->data+6, 6); + + if (vos_is_macaddr_group((v_MACADDR_t *)mac)) { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED, + "rx broadcast packet, not adding to peer list"); + } else if ((memcmp(pHddStaCtx->conn_info.bssId, + mac, 6) != 0) && (pRxMetaInfo->isStaTdls)) { + wlan_hdd_tdls_update_rx_pkt_cnt_n_rssi(pAdapter, mac, + pRxMetaInfo->rssiAvg); + } else { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_MED, + "rx packet sa is bssid, not adding to peer list"); + } + } +#endif + if (pHddCtx->cfg_ini->gEnableDebugLog) + { + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog); + if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA RX EAPOL"); + } + else if (VOS_PKT_PROTO_TYPE_DHCP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA RX DHCP"); + } + else if (VOS_PKT_PROTO_TYPE_ARP & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA RX ARP"); + } + } + + arp_pkt = vos_is_arp_pkt(skb, false); + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.rxCount; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s :STA RX ARP received",__func__); + } + + if (pHddCtx->rx_wow_dump) { + if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) && + !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type)) + hdd_log_ip_addr(skb); + pHddCtx->rx_wow_dump = false; + } + + if (pHddCtx->cfg_ini->gEnableRoamDelayStats) + { + vos_record_roam_event(e_HDD_RX_PKT_CBK_TIME, (void *)skb, 0); + } + if (( NULL != pHddCtx ) && + (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_PROTO_TYPE_DHCP)) + { + hdd_dump_dhcp_pkt(skb, RX_PATH); + } + + skb->dev = pAdapter->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + skb->ip_summed = CHECKSUM_NONE; + ++pAdapter->hdd_stats.hddTxRxStats.rxPackets; + ++pAdapter->stats.rx_packets; + pAdapter->stats.rx_bytes += skb->len; + + if (arp_pkt) + { + pAdapter->dad = hdd_is_duplicate_ip_arp(skb); + if(pAdapter->dad) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s :Duplicate IP detected",__func__); + } +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_timeout_release(&pHddCtx->rx_wake_lock, + HDD_WAKE_LOCK_DURATION, + WIFI_POWER_EVENT_WAKELOCK_HOLD_RX); +#endif + if (pNextVosPacket) + { + rxstat = netif_rx(skb); + } + else + { + rxstat = netif_rx_ni(skb); + } + + if (NET_RX_SUCCESS == rxstat) + { + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.rxDelivered; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "STA RX ARP packet Delivered to net stack"); + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered; + ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count; + } + else + { + + if (arp_pkt) + { + ++pAdapter->hdd_stats.hddArpStats.rxRefused; + pAdapter->hdd_stats.hddArpStats.reason = HDD_STA_RX_ARP_PACKET_REFUSED_IN_NET_STACK; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s :STA RX ARP packet Refused in net stack", __func__); + } + + ++pAdapter->hdd_stats.hddTxRxStats.rxRefused; + } + // now process the next packet in the chain + pVosPacket = pNextVosPacket; + + } while (pVosPacket); + + //Return the entire VOS packet chain to the resource pool + status = vos_pkt_return_packet( pVosPacketChain ); + if(!VOS_IS_STATUS_SUCCESS( status )) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,"%s: Failure returning vos pkt", __func__); + } + + pAdapter->dev->last_rx = jiffies; + + return status; +} +/**============================================================================ + @brief hdd_tx_rx_pkt_cnt_stat_timer_handler() - + Enable/Disable split scan based on TX and RX traffic. + @param HddContext : [in] pointer to Hdd context + @return : None + ===========================================================================*/ +void hdd_tx_rx_pkt_cnt_stat_timer_handler( void *phddctx) +{ + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + hdd_adapter_t *pAdapter = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + hdd_context_t *pHddCtx = (hdd_context_t *)phddctx; + hdd_config_t *cfg_param = pHddCtx->cfg_ini; + VOS_STATUS status; + v_U8_t staId = 0; + v_U8_t fconnected = 0; + + ENTER(); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + if (!cfg_param->dynSplitscan) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Error : Dynamic split scan is not Enabled : %d", + __func__, pHddCtx->cfg_ini->dynSplitscan); + return; + } + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if ((NULL != pAdapter) && (WLAN_HDD_ADAPTER_MAGIC == pAdapter->magic)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Adapter with device mode %d exists", + __func__, pAdapter->device_mode); + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if ((eConnectionState_Associated == + pHddStaCtx->conn_info.connState) && + (VOS_TRUE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + fconnected = TRUE; + } + } + else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) || + (WLAN_HDD_P2P_GO == pAdapter->device_mode)) + { + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return; + } + for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) + { + if ((pSapCtx->aStaInfo[staId].isUsed) && + (WLANTL_STA_AUTHENTICATED == + pSapCtx->aStaInfo[staId].tlSTAState)) + { + fconnected = TRUE; + } + } + } + if ( fconnected ) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: One of the interface is connected check for scan", + __func__); + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: pkt_tx_count: %d, pkt_rx_count: %d " + "miracast = %d", __func__, + pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count, + pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count, + pHddCtx->drvr_miracast); + + vos_timer_start(&pHddCtx->tx_rx_trafficTmr, + cfg_param->trafficMntrTmrForSplitScan); + //Check for the previous statistics count + if ((pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count > + cfg_param->txRxThresholdForSplitScan) || + (pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count > + cfg_param->txRxThresholdForSplitScan) || + pHddCtx->drvr_miracast || + (WLAN_HDD_P2P_GO == pAdapter->device_mode)) + { + pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0; + pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0; + + if (!pHddCtx->issplitscan_enabled) + { + pHddCtx->issplitscan_enabled = TRUE; + sme_enable_disable_split_scan( + WLAN_HDD_GET_HAL_CTX(pAdapter), + cfg_param->nNumStaChanCombinedConc, + cfg_param->nNumP2PChanCombinedConc); + } + return; + } + else + { + pAdapter->hdd_stats.hddTxRxStats.pkt_tx_count = 0; + pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count = 0; + } + fconnected = FALSE; + } + } + status = hdd_get_next_adapter( pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + /* If TDLSScanCoexistence is enabled, then the TDLS module shall take care + * of disabling the split scan and thus do not disable the same when the + * low TXRX condition is met. + */ + if ((pHddCtx->isTdlsScanCoexistence == FALSE) && (pHddCtx->issplitscan_enabled)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, + "%s: Disable split scan", __func__); + pHddCtx->issplitscan_enabled = FALSE; + sme_enable_disable_split_scan( + pHddCtx->hHal, + SME_DISABLE_SPLIT_SCAN, + SME_DISABLE_SPLIT_SCAN); + } + EXIT(); + return; +} + +/** + * hdd_rx_fwd_eapol() - forward cached eapol frames + * @vosContext : pointer to vos global context + * @pVosPacket: pointer to vos packet + * + * Return: None + * + */ +void hdd_rx_fwd_eapol(v_VOID_t *vosContext, vos_pkt_t *pVosPacket) +{ + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t * pAdapter; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + struct sk_buff *skb = NULL; + uint8_t proto_type; + uint8_t status; + + if ((NULL == vosContext) || (NULL == pVosPacket)) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: Null global context", __func__); + return; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vosContext); + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: HDD adapter context is Null", __func__); + return; + } + + status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode ); + + while ( NULL != pAdapterNode && 0 == status ) + { + pAdapter = pAdapterNode->pAdapter; + + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + break; + + status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR, + "%s: No adapter", __func__); + return; + } + + vos_pkt_get_os_packet(pVosPacket, (v_VOID_t **)&skb, VOS_FALSE); + proto_type = vos_pkt_get_proto_type(skb, + pHddCtx->cfg_ini->gEnableDebugLog); + if (VOS_PKT_PROTO_TYPE_EAPOL & proto_type) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "STA RX EAPOL"); + } + + skb->dev = pAdapter->dev; + skb->protocol = eth_type_trans(skb, skb->dev); + skb->ip_summed = CHECKSUM_NONE; + + netif_rx_ni(skb); +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/* + * wlan_hdd_get_eapol_params() - Function to extract EAPOL params + * @skb: skb data + * @eapol_params: Pointer to hold the parsed EAPOL params + * @event_type: Event type to indicate Tx/Rx + * + * This function parses the input skb data to get the EAPOL params,if the + * packet is EAPOL and store it in the pointer passed as input + * + */ +void wlan_hdd_get_eapol_params(struct sk_buff *skb, + struct vos_event_wlan_eapol *eapol_params, + uint8_t event_type) +{ + uint8_t packet_type=0; + + packet_type = (uint8_t)(*(uint8_t *) + (skb->data + HDD_EAPOL_PACKET_TYPE_OFFSET)); + + /* EAPOL msg type i.e. whether EAPOL-Start or + * EAPOL-Key etc. messages Present at 15 offset. + */ + eapol_params->eapol_packet_type = packet_type; + + /* This tells if its a M1/M2/M3/M4 packet. + * Present at 19th offset in EAPOL frame. + */ + eapol_params->eapol_key_info = (uint16_t)(*(uint16_t *) + (skb->data + HDD_EAPOL_KEY_INFO_OFFSET)); + /* This tells if EAPOL packet is in RX or TX + * direction. + */ + eapol_params->event_sub_type = event_type; + + /* This tells the rate at which EAPOL packet + * is send or received. + */ + //TODO fill data rate for rx packet. + eapol_params->eapol_rate = 0;/* As of now, zero */ + + vos_mem_copy(eapol_params->dest_addr, + (skb->data + HDD_EAPOL_DEST_MAC_OFFSET), + sizeof(eapol_params->dest_addr)); + vos_mem_copy(eapol_params->src_addr, + (skb->data + HDD_EAPOL_SRC_MAC_OFFSET), + sizeof(eapol_params->src_addr)); + return; +} +/* + * wlan_hdd_event_eapol_log() - Function to log EAPOL events + * @eapol_params: Structure containing EAPOL params + * + * This function logs the parsed EAPOL params + * + * Return: None + * + */ + +static void wlan_hdd_event_eapol_log(struct vos_event_wlan_eapol eapol_params) +{ + WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, struct vos_event_wlan_eapol); + + wlan_diag_event.event_sub_type = eapol_params.event_sub_type; + wlan_diag_event.eapol_packet_type = eapol_params.eapol_packet_type; + wlan_diag_event.eapol_key_info = eapol_params.eapol_key_info; + wlan_diag_event.eapol_rate = eapol_params.eapol_rate; + vos_mem_copy(wlan_diag_event.dest_addr, + eapol_params.dest_addr, + sizeof (wlan_diag_event.dest_addr)); + vos_mem_copy(wlan_diag_event.src_addr, + eapol_params.src_addr, + sizeof (wlan_diag_event.src_addr)); + WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL); +} + +/* + * wlan_hdd_log_eapol() - Function to check and extract EAPOL params + * @skb: skb data + * @event_type: One of enum wifi_connectivity_events to indicate Tx/Rx + * + * This function parses the input skb data to get the EAPOL params,if the + * packet is EAPOL and store it in the pointer passed as input + * + * Return: None + * + */ +void wlan_hdd_log_eapol(struct sk_buff *skb, + uint8_t event_type) +{ + struct vos_event_wlan_eapol eapol_params; + + wlan_hdd_get_eapol_params(skb, &eapol_params, event_type); + wlan_hdd_event_eapol_log(eapol_params); + + if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M1_BIT_MASK) + { + hddLog(LOG1, FL("%s: M1 packet"),eapol_params.event_sub_type == + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX"); + } + else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M2_BIT_MASK) + { + hddLog(LOG1, FL("%s: M2 packet"),eapol_params.event_sub_type == + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX"); + + } + + else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M3_BIT_MASK) + { + hddLog(LOG1, FL("%s: M3 packet"),eapol_params.event_sub_type == + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX"); + } + + else if ((eapol_params.eapol_key_info & EAPOL_MASK )== EAPOL_M4_BIT_MASK) + { + hddLog(LOG1, FL("%s: M4 packet"),eapol_params.event_sub_type == + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? "RX" : "TX"); + + } + +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c new file mode 100644 index 000000000000..fbd52e7ef7d3 --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wext.c @@ -0,0 +1,12050 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/** ------------------------------------------------------------------------ * + ------------------------------------------------------------------------ * + + + \file wlan_hdd_wext.c + + \brief Airgo Linux Wireless Extensions Common Control Plane Types and + interfaces. + + $Id: wlan_hdd_wext.c,v 1.34 2007/04/14 01:49:23 jimz Exp jimz $ + + This file defines all of the types that are utilized by the CCP module + of the "Portable" HDD. This file also includes the underlying Linux + Wireless Extensions Data types referred to by CCP. + + ======================================================================== */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WLAN_BTAMP_FEATURE +#include +#endif +#include +#include +#include "ccmApi.h" +#include "sirParams.h" +#include "csrApi.h" +#include "csrInsideApi.h" +#if defined WLAN_FEATURE_VOWIFI +#include "smeRrmInternal.h" +#endif +#include +#include "dot11f.h" +#include +#include +#include +#include "utilsApi.h" +#include "wlan_hdd_p2p.h" +#ifdef FEATURE_WLAN_TDLS +#include "wlan_hdd_tdls.h" +#endif + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include "wlan_hdd_power.h" +#include "qwlan_version.h" +#include "wlan_hdd_host_offload.h" +#include "wlan_hdd_keep_alive.h" +#ifdef WLAN_FEATURE_PACKET_FILTERING +#include "wlan_hdd_packet_filtering.h" +#endif + +#include +#include +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_tl.h" + +#include "wlan_hdd_misc.h" +#include "bap_hdd_misc.h" + +#include "wlan_hdd_dev_pwr.h" +#include "qc_sap_ioctl.h" +#include "sme_Api.h" +#include "vos_trace.h" +#include "wlan_hdd_assoc.h" + +#include "vos_utils.h" +#include "sapInternal.h" + +#ifdef CONFIG_HAS_EARLYSUSPEND +extern void hdd_suspend_wlan(struct early_suspend *wlan_suspend); +extern void hdd_resume_wlan(struct early_suspend *wlan_suspend); +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT +#define MAX_OEM_DATA_RSP_LEN 2047 +#endif + +#define HDD_FINISH_ULA_TIME_OUT 800 +#define COUNTRY_CODE_LEN 2 + + +// tdlsoffchan +#ifdef FEATURE_WLAN_TDLS +static int tdlsOffCh = 1; +static int tdlsOffChBwOffset = 0; +#endif + +static int ioctl_debug; +module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +/* To Validate Channel against the Frequency and Vice-Versa */ +static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2}, + {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6}, {2442, 7}, {2447, 8}, + {2452, 9}, {2457, 10}, {2462, 11}, {2467 ,12}, {2472, 13}, + {2484, 14}, {4920, 240}, {4940, 244}, {4960, 248}, {4980, 252}, + {5040, 208}, {5060, 212}, {5080, 216}, {5180, 36}, {5200, 40}, {5220, 44}, + {5240, 48}, {5260, 52}, {5280, 56}, {5300, 60}, {5320, 64}, {5500, 100}, + {5520, 104}, {5540, 108}, {5560, 112}, {5580, 116}, {5600, 120}, + {5620, 124}, {5640, 128}, {5660, 132}, {5680, 136}, {5700, 140}, + {5720, 144}, {5745, 149}, {5765, 153}, {5785, 157}, {5805, 161}, + {5825, 165} }; + +#define FREQ_CHAN_MAP_TABLE_SIZE (sizeof(freq_chan_map)/sizeof(freq_chan_map[0])) + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0) +#define WE_SET_11D_STATE 1 +#define WE_WOWL 2 +#define WE_SET_POWER 3 +#define WE_SET_MAX_ASSOC 4 +#define WE_SET_SAP_AUTO_CHANNEL_SELECTION 5 +#define WE_SET_DATA_INACTIVITY_TO 6 +#define WE_SET_MAX_TX_POWER 7 +#define WE_SET_HIGHER_DTIM_TRANSITION 8 +#define WE_SET_TM_LEVEL 9 +#define WE_ENABLE_STRICT_FCC_REG 10 +#define WE_SET_MAX_TX_POWER_2_4 11 +#define WE_SET_MAX_TX_POWER_5_0 12 +/* Private IOCTL for debug connection issues */ +#define WE_SET_DEBUG_LOG 13 +// tdlsoffchan +#ifdef FEATURE_WLAN_TDLS +#define WE_SET_TDLS_OFF_CHAN 14 +#define WE_SET_TDLS_SEC_OFF_CHAN_OFFSET 15 +#define WE_SET_TDLS_OFF_CHAN_MODE 16 +#endif +#define WE_SET_SCAN_BAND_PREFERENCE 17 +#define WE_SET_MIRACAST_VENDOR_CONFIG 18 +#define WE_GET_FRAME_LOG 19 +#ifdef FEATURE_WLAN_TDLS +#define WE_SET_TDLS_2040_BSS_COEXISTENCE 20 +#endif +#define WE_SET_RTS_CTS_HTVHT 21 +#define WE_SET_MONITOR_STATE 22 +#define WE_SET_PKT_STATS_ENABLE_DISABLE 23 +#define WE_SET_PROXIMITY_ENABLE 24 +#define WE_CAP_TSF 25 +#define WE_SET_MODULATED_DTIM 26 +#define WLAN_SET_DYNNAMIC_AGGREGATION 27 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) +#define WE_GET_11D_STATE 1 +#define WE_IBSS_STATUS 2 +#define WE_PMC_STATE 3 +#define WE_GET_WLAN_DBG 4 +#define WE_GET_MAX_ASSOC 6 +#define WE_GET_WDI_DBG 7 +#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8 +#define WE_GET_CONCURRENCY_MODE 9 +#define WE_GET_SCAN_BAND_PREFERENCE 10 +#define WE_GET_ANTENA_DIVERSITY_SELECTION 11 +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2) + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3) +#define WE_WOWL_ADD_PTRN 1 +#define WE_WOWL_DEL_PTRN 2 +#if defined WLAN_FEATURE_VOWIFI +#define WE_NEIGHBOR_REPORT_REQUEST 3 +#endif +#define WE_SET_AP_WPS_IE 4 //This is called in station mode to set probe rsp ie. +#define WE_SET_CONFIG 5 +#define WE_SET_ENCRYPT_MSG 6 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4) +#define WE_SET_WLAN_DBG 1 +#define WE_SET_WDI_DBG 2 +#define WE_SET_SAP_CHANNELS 3 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5) +#define WE_WLAN_VERSION 1 +#define WE_GET_STATS 2 +#define WE_GET_CFG 3 +#define WE_GET_WMM_STATUS 4 +#define WE_GET_CHANNEL_LIST 5 +#ifdef WLAN_FEATURE_11AC +#define WE_GET_RSSI 6 +#endif +#define WE_GET_ROAM_RSSI 7 +#ifdef FEATURE_WLAN_TDLS +#define WE_GET_TDLS_PEERS 8 +#endif +#ifdef WLAN_FEATURE_11W +#define WE_GET_11W_INFO 9 +#endif +#define WE_GET_STATES 10 +#ifdef WLAN_FEATURE_RMC +#define WE_GET_IBSS_STA_INFO 11 +#endif +#define WE_GET_SNR 12 + +#ifdef FEATURE_OEM_DATA_SUPPORT +#define WE_GET_OEM_DATA_CAP 13 +#endif + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6) +#define WE_CLEAR_STATS 1 +#define WE_INIT_AP 2 +#define WE_STOP_AP 3 +#ifdef WLAN_BTAMP_FEATURE +#define WE_ENABLE_AMP 4 +#define WE_DISABLE_AMP 5 +#endif /* WLAN_BTAMP_FEATURE */ +#define WE_ENABLE_DXE_STALL_DETECT 6 +#define WE_DISPLAY_DXE_SNAP_SHOT 7 +#define WE_SET_REASSOC_TRIGGER 8 +#define WE_DISPLAY_DATAPATH_SNAP_SHOT 9 +#ifdef WLAN_FEATURE_RMC +#define WE_IBSS_GET_PEER_INFO_ALL 10 +#endif +#define WE_STOP_OBSS_SCAN 11 +#define WE_DUMP_ROAM_TIMER_LOG 12 +#define WE_RESET_ROAM_TIMER_LOG 13 +#define WE_GET_FW_LOGS 14 +#define WE_GET_FW_MEMDUMP 15 + +/* Private ioctls and their sub-ioctls */ +#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7) +#define WE_LOG_DUMP_CMD 1 + +#define WE_P2P_NOA_CMD 2 +//IOCTL to configure MCC params +#define WE_MCC_CONFIG_CREDENTIAL 3 +#define WE_MCC_CONFIG_PARAMS 4 + +#ifdef FEATURE_WLAN_TDLS +#define WE_TDLS_CONFIG_PARAMS 5 +#endif +#ifdef WLAN_FEATURE_RMC +#define WE_IBSS_GET_PEER_INFO 6 +#endif + +#define WE_MTRACE_DUMP_CMD 8 +#define WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD 9 +#define WE_CONFIGURE_MONITOR_MODE 10 +#define WE_SET_MONITOR_MODE_FILTER 11 + +#ifdef FEATURE_WLAN_TDLS +#undef MAX_VAR_ARGS +#define MAX_VAR_ARGS 10 +#else +#define MAX_VAR_ARGS 7 +#endif + +/* Private ioctls (with no sub-ioctls) */ +/* note that they must be odd so that they have "get" semantics */ +#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9) +#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11) +#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13) + +/* (SIOCIWFIRSTPRIV + 8) is currently unused */ +/* (SIOCIWFIRSTPRIV + 16) is currently unused */ +/* (SIOCIWFIRSTPRIV + 10) is currently unused */ +/* (SIOCIWFIRSTPRIV + 12) is currently unused */ +/* (SIOCIWFIRSTPRIV + 14) is currently unused */ +#define WLAN_PRIV_SET_NONE_GET_THREE_INT (SIOCIWFIRSTPRIV + 15) +#define WE_GET_TSF 1 + +#ifdef FEATURE_OEM_DATA_SUPPORT +/* Private ioctls for setting the measurement configuration */ +#define WLAN_PRIV_SET_OEM_DATA_REQ (SIOCIWFIRSTPRIV + 17) +#define WLAN_PRIV_GET_OEM_DATA_RSP (SIOCIWFIRSTPRIV + 19) +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20) +#endif + +/* Private ioctl for setting the host offload feature */ +#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18) + +/* Private ioctl to get the statistics */ +#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21) + +/* Private ioctl to set the Keep Alive Params */ +#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22) +#ifdef WLAN_FEATURE_PACKET_FILTERING +/* Private ioctl to set the Packet Filtering Params */ +#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23) +#endif + +#ifdef FEATURE_WLAN_SCAN_PNO +/* Private ioctl to get the statistics */ +#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24) +#endif + +#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25) /*Don't change this number*/ + +#define WLAN_PRIV_SET_MCBC_FILTER (SIOCIWFIRSTPRIV + 26) +#define WLAN_PRIV_CLEAR_MCBC_FILTER (SIOCIWFIRSTPRIV + 27) +/* Private ioctl to trigger reassociation */ + +#define WLAN_SET_POWER_PARAMS (SIOCIWFIRSTPRIV + 29) +#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31) + +#define WLAN_STATS_INVALID 0 +#define WLAN_STATS_RETRY_CNT 1 +#define WLAN_STATS_MUL_RETRY_CNT 2 +#define WLAN_STATS_TX_FRM_CNT 3 +#define WLAN_STATS_RX_FRM_CNT 4 +#define WLAN_STATS_FRM_DUP_CNT 5 +#define WLAN_STATS_FAIL_CNT 6 +#define WLAN_STATS_RTS_FAIL_CNT 7 +#define WLAN_STATS_ACK_FAIL_CNT 8 +#define WLAN_STATS_RTS_SUC_CNT 9 +#define WLAN_STATS_RX_DISCARD_CNT 10 +#define WLAN_STATS_RX_ERROR_CNT 11 +#define WLAN_STATS_TX_BYTE_CNT 12 + +#define WLAN_STATS_RX_BYTE_CNT 13 +#define WLAN_STATS_RX_RATE 14 +#define WLAN_STATS_TX_RATE 15 + +#define WLAN_STATS_RX_UC_BYTE_CNT 16 +#define WLAN_STATS_RX_MC_BYTE_CNT 17 +#define WLAN_STATS_RX_BC_BYTE_CNT 18 +#define WLAN_STATS_TX_UC_BYTE_CNT 19 +#define WLAN_STATS_TX_MC_BYTE_CNT 20 +#define WLAN_STATS_TX_BC_BYTE_CNT 21 + +#define FILL_TLV(__p, __type, __size, __val, __tlen) do { \ + if ((__tlen + __size + 2) < WE_MAX_STR_LEN) \ + { \ + *__p++ = __type; \ + *__p++ = __size; \ + memcpy(__p, __val, __size); \ + __p += __size; \ + __tlen += __size + 2; \ + } \ + else \ + { \ + hddLog(VOS_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!"); \ + } \ + } while(0); + +#define VERSION_VALUE_MAX_LEN 32 + +#define TX_PER_TRACKING_DEFAULT_RATIO 5 +#define TX_PER_TRACKING_MAX_RATIO 10 +#define TX_PER_TRACKING_DEFAULT_WATERMARK 5 + +#define WLAN_ADAPTER 0 +#define P2P_ADAPTER 1 + +#define TX_PWR_MIN 6 +#define TX_PWR_MAX 22 +#define TX_PWR_DEF 50 + +/* Dynamic Aggregation */ +#define DISABLE_AGGREGATION 0 +#define ENABLE_AGGREGATION 1 +/* + * When supplicant sends SETBAND ioctl it queries for channels from + * cfg80211 layer by sending itself EVENT_CHANNEL_LIST_CHANGED command. + * This is not required if the return type from ioctl is + * DO_NOT_SEND_CHANNEL_CHANGE_EVENT as wiphy will send channel change + * event as part of regulatory_hint. + */ +enum { + SEND_CHANNEL_CHANGE_EVENT = 0, + DO_NOT_SEND_CHANNEL_CHANGE_EVENT, +}; + +/*MCC Configuration parameters */ +enum { + MCC_SCHEDULE_TIME_SLICE_CFG_PARAM = 1, + MCC_MAX_NULL_SEND_TIME_CFG_PARAM, + MCC_TX_EARLY_STOP_TIME_CFG_PARAM, + MCC_RX_DRAIN_TIME_CFG_PARAM, + MCC_CHANNEL_SWITCH_TIME_CFG_PARAM, + MCC_MIN_CHANNEL_TIME_CFG_PARAM, + MCC_PARK_BEFORE_TBTT_CFG_PARAM, + MCC_MIN_AFTER_DTIM_CFG_PARAM, + MCC_TOO_CLOSE_MARGIN_CFG_PARAM, +}; + +int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, + v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +int wlan_hdd_set_filter(hdd_adapter_t *pAdapter, tpPacketFilterCfg pRequest); +#endif +static int get_fwr_memdump(struct net_device *, + struct iw_request_info *, + union iwreq_data *, char *); +/**--------------------------------------------------------------------------- + + \brief mem_alloc_copy_from_user_helper - + + Helper function to allocate buffer and copy user data. + + \param - wrqu - Pointer to IOCTL Data. + len - size + + \return - On Success pointer to buffer, On failure NULL + + --------------------------------------------------------------------------*/ +void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len) +{ + u8 *ptr = NULL; + + /* in order to protect the code, an extra byte is post appended to the buffer + * and the null termination is added. However, when allocating (len+1) byte + * of memory, we need to make sure that there is no uint overflow when doing + * addition. In theory check len < UINT_MAX protects the uint overflow. For + * wlan private ioctl, the buffer size is much less than UINT_MAX, as a good + * guess, now, it is assumed that the private command buffer size is no + * greater than 4K (4096 bytes). So we use 4096 as the upper boundary for now. + */ + if (len > MAX_USER_COMMAND_SIZE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid length"); + return NULL; + } + + ptr = kmalloc(len + 1, GFP_KERNEL); + if (NULL == ptr) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "unable to allocate memory"); + return NULL; + } + + if (copy_from_user(ptr, wrqu_data, len)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + kfree(ptr); + return NULL; + } + ptr[len] = '\0'; + return ptr; +} + +// Function to handle and get compatible struct iw_point passed to ioctl. +int hdd_priv_get_data(struct iw_point *p_priv_data, + union iwreq_data *wrqu) +{ + if ((NULL == p_priv_data) || (NULL == wrqu)) + { + return -EINVAL; + } + +#ifdef CONFIG_COMPAT + if (is_compat_task()) + { + struct compat_iw_point *p_compat_priv_data; + + // Compat task: typecast to campat structure and copy the members. + p_compat_priv_data = (struct compat_iw_point *) &wrqu->data; + + p_priv_data->pointer = compat_ptr(p_compat_priv_data->pointer); + p_priv_data->length = p_compat_priv_data->length; + p_priv_data->flags = p_compat_priv_data->flags; + }//if(is_compat_task()) + else + { +#endif //#ifdef CONFIG_COMPAT + + // Non compat task: directly copy the structure. + memcpy(p_priv_data, &wrqu->data, sizeof(struct iw_point)); + +#ifdef CONFIG_COMPAT + }//else of - if(is_compat_task()) +#endif //#ifdef CONFIG_COMPAT + + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief hdd_wlan_get_version() - + + This function use to get Wlan Driver, Firmware, & Hardware Version. + + \param - pAdapter Pointer to the adapter. + wrqu - Pointer to IOCTL REQUEST Data. + extra - Pointer to char + + \return - none + + --------------------------------------------------------------------------*/ +void hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu, + char *extra) +{ + VOS_STATUS status; + tSirVersionString wcnss_SW_version; + tSirVersionString wcnss_HW_version; + tSirVersionString iris_name; + char *pIRISversion; + char *pSWversion; + char *pHWversion; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + status = sme_GetWcnssSoftwareVersion(hHal, wcnss_SW_version, + sizeof(wcnss_SW_version)); + if (VOS_IS_STATUS_SUCCESS(status)) + { + pSWversion = wcnss_SW_version; + } + else + { + pSWversion = "Unknown"; + } + + status = sme_GetWcnssHardwareVersion(hHal, wcnss_HW_version, + sizeof(wcnss_HW_version)); + if (VOS_IS_STATUS_SUCCESS(status)) + { + pHWversion = wcnss_HW_version; + } + else + { + pHWversion = "Unknown"; + } + + status = wcnss_get_iris_name(iris_name); + + if (!status) { + pIRISversion = iris_name; + } else { + pIRISversion = "Unknown"; + } + + wrqu->data.length = scnprintf(extra, WE_MAX_STR_LEN, + "Host SW:%s, FW:%s, HW:%s, IRIS_HW:%s", + QWLAN_VERSIONSTR, + pSWversion, + pHWversion, pIRISversion); + + return; +} + +#ifdef WLAN_FEATURE_RMC +void hdd_get_ibss_peer_info_cb(v_VOID_t *pUserData, v_VOID_t *pPeerInfoRsp) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pUserData; + tSirPeerInfoRspParams *pPeerInfo = (tSirPeerInfoRspParams *)pPeerInfoRsp; + hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + v_U8_t i; + + if (NULL != pPeerInfo && eHAL_STATUS_SUCCESS == pPeerInfo->status) + { + pStaCtx->ibss_peer_info.status = pPeerInfo->status; + pStaCtx->ibss_peer_info.numIBSSPeers = pPeerInfo->numPeers; + for (i = 0; i < pPeerInfo->numPeers; i++) + { + memcpy(&pStaCtx->ibss_peer_info.ibssPeerList[i], + &pPeerInfo->peerInfoParams[i], sizeof(hdd_ibss_peer_info_params_t)); + } + } + else + { + hddLog(LOGE, + FL("PEER_INFO_CMD_STATUS is not SUCCESS")); + } + + complete(&pAdapter->ibss_peer_info_comp); +} + +v_MACADDR_t* hdd_wlan_get_ibss_mac_addr_from_staid(hdd_adapter_t *pAdapter, v_U8_t staIdx) +{ + v_U8_t idx; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ ) + { + if ( 0 != pHddStaCtx->conn_info.staId[ idx ] && + staIdx == pHddStaCtx->conn_info.staId[ idx ]) + { + return (&pHddStaCtx->conn_info.peerMacAddress[ idx ]); + } + } + return NULL; +} + +eHalStatus hdd_wlan_get_ibss_peer_info(hdd_adapter_t *pAdapter, v_U8_t staIdx) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ibss_peer_info_t *pPeerInfo = &pStaCtx->ibss_peer_info; + + status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb, + VOS_FALSE, staIdx); + + INIT_COMPLETION(pAdapter->ibss_peer_info_comp); + + if (eHAL_STATUS_SUCCESS == status) + { + long ret; + ret = wait_for_completion_interruptible_timeout + (&pAdapter->ibss_peer_info_comp, + msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT)); + if (ret <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on ibss_peer_info_comp %ld"), ret); + return eHAL_STATUS_FAILURE; + } + + /** Print the peer info */ + pr_info("pPeerInfo->numIBSSPeers = %d ", pPeerInfo->numIBSSPeers); + pr_info("============================================================"); + { + v_MACADDR_t *macAddr = hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter, + staIdx); + v_U32_t txRateMbps = ((pPeerInfo->ibssPeerList[0].txRate)*500*1000)/1000000; + + if (NULL != macAddr) + { + pr_info("PEER ADDR :" MAC_ADDRESS_STR " TxRate: %d Mbps RSSI: %d", + MAC_ADDR_ARRAY(macAddr->bytes), + (int)txRateMbps, (int)pPeerInfo->ibssPeerList[0].rssi); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " ERROR: PEER MAC ADDRESS NOT FOUND "); + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__); + } + + return status; +} + +eHalStatus hdd_wlan_get_ibss_peer_info_all(hdd_adapter_t *pAdapter) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + hdd_station_ctx_t *pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ibss_peer_info_t *pPeerInfo = &pStaCtx->ibss_peer_info; + int i; + + status = sme_RequestIBSSPeerInfo(hHal, pAdapter, hdd_get_ibss_peer_info_cb, + VOS_TRUE, 0xFF); + INIT_COMPLETION(pAdapter->ibss_peer_info_comp); + + if (eHAL_STATUS_SUCCESS == status) + { + long ret; + ret = wait_for_completion_interruptible_timeout + (&pAdapter->ibss_peer_info_comp, + msecs_to_jiffies(IBSS_PEER_INFO_REQ_TIMOEUT)); + if (ret <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on ibss_peer_info_comp %ld"), ret); + return eHAL_STATUS_FAILURE; + } + + /** Print the peer info */ + pr_info("pPeerInfo->numIBSSPeers = %d ", (int)pPeerInfo->numIBSSPeers); + pr_info("============================================================"); + for (i = 0; i < pPeerInfo->numIBSSPeers; i++) + { + v_U8_t staIdx = pPeerInfo->ibssPeerList[i].staIdx; + v_MACADDR_t *macAddr = hdd_wlan_get_ibss_mac_addr_from_staid(pAdapter, + staIdx); + v_U32_t txRateMbps = ((pPeerInfo->ibssPeerList[0].txRate)*500*1000)/1000000; + + pr_info("STAIDX:%d ", (int)pPeerInfo->ibssPeerList[i].staIdx); + if (NULL != macAddr) + { + pr_info(" PEER ADDR :" MAC_ADDRESS_STR " TxRate: %d Mbps RSSI: %d", + MAC_ADDR_ARRAY(macAddr->bytes), + (int)txRateMbps, (int)pPeerInfo->ibssPeerList[i].rssi); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " ERROR: PEER MAC ADDRESS NOT FOUND "); + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Warning: sme_RequestIBSSPeerInfo Request failed", __func__); + } + + return status; +} +#endif /* WLAN_FEATURE_RMC */ + +int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu) +{ + tHalHandle hHal; + hdd_context_t *pHddCtx; + v_U32_t threshold = 0; + int ret = 0; + + ENTER(); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if ( eHAL_STATUS_SUCCESS != + ccmCfgGetInt(hHal, WNI_CFG_RTS_THRESHOLD, &threshold) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_RTS_THRESHOLD")); + return -EIO; + } + wrqu->rts.value = threshold; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("Rts-Threshold=%d!!"), wrqu->rts.value); + + EXIT(); + + return 0; +} + +int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu) +{ + tHalHandle hHal; + hdd_context_t *pHddCtx; + v_U32_t threshold = 0, status = 0; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if ( ccmCfgGetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold) + != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD")); + return -EIO; + } + wrqu->frag.value = threshold; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("Frag-Threshold=%d!!"), wrqu->frag.value); + + EXIT(); + + return 0; +} + +int hdd_wlan_get_freq(v_U32_t channel, v_U32_t *pfreq) +{ + int i; + if (channel > 0) + { + for (i=0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++) + { + if (channel == freq_chan_map[i].chan) + { + *pfreq = freq_chan_map[i].freq; + return 1; + } + } + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("Invalid channel no=%d!!"), channel); + return -EINVAL; +} + +static v_BOOL_t +hdd_IsAuthTypeRSN( tHalHandle halHandle, eCsrAuthType authType) +{ + v_BOOL_t rsnType = VOS_FALSE; + // is the authType supported? + switch (authType) + { + case eCSR_AUTH_TYPE_NONE: //never used + rsnType = eANI_BOOLEAN_FALSE; + break; + // MAC layer authentication types + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + rsnType = eANI_BOOLEAN_FALSE; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + rsnType = eANI_BOOLEAN_FALSE; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + rsnType = eANI_BOOLEAN_FALSE; + break; + + // Upper layer authentication types + case eCSR_AUTH_TYPE_WPA: + rsnType = eANI_BOOLEAN_TRUE; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + rsnType = eANI_BOOLEAN_TRUE; + break; + case eCSR_AUTH_TYPE_WPA_NONE: + rsnType = eANI_BOOLEAN_TRUE; + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: +#endif + case eCSR_AUTH_TYPE_RSN: + rsnType = eANI_BOOLEAN_TRUE; + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN_PSK: +#endif + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + rsnType = eANI_BOOLEAN_TRUE; + break; + //case eCSR_AUTH_TYPE_FAILED: + case eCSR_AUTH_TYPE_UNKNOWN: + rsnType = eANI_BOOLEAN_FALSE; + break; + default: + hddLog(LOGE, FL("%s called with unknown authType - default to Open, None"), + __func__); + rsnType = eANI_BOOLEAN_FALSE; + break; + } + hddLog(LOGE, FL("%s called with authType: %d, returned: %d"), + __func__, authType, rsnType); + return rsnType; +} + +static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) +{ + struct statsContext *pStatsContext; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n", + __func__, (int)rssi, (int)staId, pContext); + } + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the rssi.FW will return RSSI as -100 + * if there are no samples to calculate the average + * RSSI + */ + if (rssi != -100) + pAdapter->rssi = rssi; + if (pAdapter->rssi > 0) + pAdapter->rssi = 0; + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +static void hdd_GetSnrCB(tANI_S8 snr, tANI_U32 staId, void *pContext) +{ + struct statsContext *pStatsContext; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: snr [%d] STA [%d] pContext [%p]\n", + __func__, (int)snr, (int)staId, pContext); + } + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (SNR_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the snr */ + pAdapter->snr = snr; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) +{ + struct statsContext context; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus hstatus; + long lrc; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); + /* return a cached value */ + *rssi_value = pAdapter->rssi; + return VOS_STATUS_SUCCESS; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated, rssi on Disconnect : %d", + __func__, pAdapter->rssi_on_disconnect); + *rssi_value = pAdapter->rssi_on_disconnect; + return VOS_STATUS_SUCCESS; + } + + if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Roaming in progress, hence return last cached RSSI", __func__); + *rssi_value = pAdapter->rssi; + return VOS_STATUS_SUCCESS; + } + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = RSSI_CONTEXT_MAGIC; + + hstatus = sme_GetRssi(pHddCtx->hHal, hdd_GetRssiCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context, pHddCtx->pvosContext); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving RSSI", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + /* we'll now returned a cached value below */ + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *rssi_value = pAdapter->rssi; + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: RSSI = %d", __func__, *rssi_value); + + return VOS_STATUS_SUCCESS; +} +/**--------------------------------------------------------------------------- + + \brief wlan_hdd_get_frame_logs() - + + This function use to get Frames log. + + \param - pAdapter Pointer to the adapter. + flag - Specify type of request. Clear and Send request are + supported. + + \return - none + + --------------------------------------------------------------------------*/ +VOS_STATUS wlan_hdd_get_frame_logs(hdd_adapter_t *pAdapter, v_U8_t flag) +{ + hdd_context_t *pHddCtx; + eHalStatus hstatus; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (!pHddCtx->mgmt_frame_logging) + { + hddLog(LOGW, FL("Frame Logging not init!")); + return VOS_STATUS_E_AGAIN; + } + + if ((flag != WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR) && + (flag != WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR) && + (flag != WLAN_HDD_GET_FRAME_LOG_CMD_BMU_TRACING)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Incorrect getFrame params!", __func__); + return VOS_STATUS_E_INVAL; + } + + if ((flag == WLAN_HDD_GET_FRAME_LOG_CMD_BMU_TRACING) && + (!pHddCtx->cfg_ini->enableBMUHWtracing)) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: BMUHW Tracing not enabled!", __func__); + return VOS_STATUS_E_INVAL; + } + + hstatus = sme_GetFramesLog(pHddCtx->hHal, flag); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to get Frame Logs", __func__); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, v_S7_t *snr) +{ + struct statsContext context; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus hstatus; + long lrc; + int valid; + + ENTER(); + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + valid = wlan_hdd_validate_context(pHddCtx); + if (0 != valid) + { + return VOS_STATUS_E_FAULT; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is not valid")); + return VOS_STATUS_E_FAULT; + } + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = SNR_CONTEXT_MAGIC; + + hstatus = sme_GetSnr(pHddCtx->hHal, hdd_GetSnrCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: SME %s while retrieving SNR", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + /* we'll now returned a cached value below */ + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *snr = pAdapter->snr; + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + +static void hdd_GetRoamRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext ) +{ + struct statsContext *pStatsContext; + hdd_adapter_t *pAdapter; + if (ioctl_debug) + { + pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n", + __func__, (int)rssi, (int)staId, pContext); + } + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the rssi.FW will return RSSI as -100 + * if there are no samples to calculate the average + * RSSI + */ + if (rssi != -100) + pAdapter->rssi = rssi; + + if (pAdapter->rssi > 0) + pAdapter->rssi = 0; + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + + + +VOS_STATUS wlan_hdd_get_roam_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value) +{ + struct statsContext context; + hdd_context_t *pHddCtx = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + eHalStatus hstatus; + long lrc; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); + /* return a cached value */ + *rssi_value = pAdapter->rssi; + return VOS_STATUS_SUCCESS; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s:Not associated!",__func__); + /* return a cached value */ + *rssi_value = 0; + return VOS_STATUS_SUCCESS; + } + + if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Roaming in progress, hence return last cached RSSI", __func__); + *rssi_value = pAdapter->rssi; + return VOS_STATUS_SUCCESS; + } + + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = RSSI_CONTEXT_MAGIC; + + hstatus = sme_GetRoamRssi(pHddCtx->hHal, hdd_GetRoamRssiCB, + pHddStaCtx->conn_info.staId[ 0 ], + pHddStaCtx->conn_info.bssId, + &context, pHddCtx->pvosContext); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + /* we'll now returned a cached value below */ + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *rssi_value = pAdapter->rssi; + + return VOS_STATUS_SUCCESS; +} +#endif + + +void hdd_StatisticsCB( void *pStats, void *pContext ) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext; + hdd_stats_t *pStatsCache = NULL; + hdd_wext_state_t *pWextState; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + tCsrSummaryStatsInfo *pSummaryStats = NULL; + tCsrGlobalClassAStatsInfo *pClassAStats = NULL; + tCsrGlobalClassBStatsInfo *pClassBStats = NULL; + tCsrGlobalClassCStatsInfo *pClassCStats = NULL; + tCsrGlobalClassDStatsInfo *pClassDStats = NULL; + tCsrPerStaStatsInfo *pPerStaStats = NULL; + + if (pAdapter!= NULL) + pStatsCache = &pAdapter->hdd_stats; + + + pSummaryStats = (tCsrSummaryStatsInfo *)pStats; + pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 ); + pClassBStats = (tCsrGlobalClassBStatsInfo *)( pClassAStats + 1 ); + pClassCStats = (tCsrGlobalClassCStatsInfo *)( pClassBStats + 1 ); + pClassDStats = (tCsrGlobalClassDStatsInfo *)( pClassCStats + 1 ); + pPerStaStats = (tCsrPerStaStatsInfo *)( pClassDStats + 1 ); + + if (pStatsCache!=NULL) + { + // and copy the stats into the cache we keep in the adapter instance structure + vos_mem_copy( &pStatsCache->summary_stat, pSummaryStats, sizeof( pStatsCache->summary_stat ) ); + vos_mem_copy( &pStatsCache->ClassA_stat, pClassAStats, sizeof( pStatsCache->ClassA_stat ) ); + vos_mem_copy( &pStatsCache->ClassB_stat, pClassBStats, sizeof( pStatsCache->ClassB_stat ) ); + vos_mem_copy( &pStatsCache->ClassC_stat, pClassCStats, sizeof( pStatsCache->ClassC_stat ) ); + vos_mem_copy( &pStatsCache->ClassD_stat, pClassDStats, sizeof( pStatsCache->ClassD_stat ) ); + vos_mem_copy( &pStatsCache->perStaStats, pPerStaStats, sizeof( pStatsCache->perStaStats ) ); + } + + if(pAdapter) + { + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if(pWextState) + { + vos_status = vos_event_set(&pWextState->vosevent); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + return; + } + } + } +} + +void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result) +{ + v_CONTEXT_t pVosContext; + hdd_context_t *pHddCtx; + VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx ); +#if 0 + hdd_wext_state_t *pWextState; + v_U32_t roamId; +#endif + + ENTER(); + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL); + + pHddCtx = (hdd_context_t*) vos_get_context(VOS_MODULE_ID_HDD,pVosContext); + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid pHddCtx", __func__); + return; + } +#if 0 + pWextState = pAdapter->pWextState; +#endif + + if (WNI_CFG_NEED_RESTART == result || WNI_CFG_NEED_RELOAD == result) + { + //TODO Verify is this is really used. If yes need to fix it. + hdd_reconnect_all_adapters( pHddCtx ); +#if 0 + pAdapter->conn_info.connState = eConnectionState_NotConnected; + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect(halHandle, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + + if(VOS_STATUS_SUCCESS == vosStatus) + wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + + sme_RoamConnect(halHandle, + pAdapter->sessionId, &(pWextState->roamProfile), + &roamId); +#endif + } + + EXIT(); + +} + +void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter) +{ + hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + /* clear WPA/RSN/WSC IE information in the profile */ + pWextState->roamProfile.nWPAReqIELength = 0; + pWextState->roamProfile.pWPAReqIE = (tANI_U8 *)NULL; + pWextState->roamProfile.nRSNReqIELength = 0; + pWextState->roamProfile.pRSNReqIE = (tANI_U8 *)NULL; + +#ifdef FEATURE_WLAN_WAPI + pWextState->roamProfile.nWAPIReqIELength = 0; + pWextState->roamProfile.pWAPIReqIE = (tANI_U8 *)NULL; +#endif + + pWextState->roamProfile.bWPSAssociation = VOS_FALSE; + pWextState->roamProfile.bOSENAssociation = VOS_FALSE; + pWextState->roamProfile.nAddIEScanLength = 0; + memset(pWextState->roamProfile.addIEScan, 0 , SIR_MAC_MAX_ADD_IE_LENGTH+2); + pWextState->roamProfile.pAddIEAssoc = (tANI_U8 *)NULL; + pWextState->roamProfile.nAddIEAssocLength = 0; + + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] + = eCSR_ENCRYPT_TYPE_NONE; + + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] + = eCSR_ENCRYPT_TYPE_NONE; + + pWextState->roamProfile.AuthType.numEntries = 1; + pWextState->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + vos_mem_zero((pWextState->roamProfile.bssid_hint), WNI_CFG_BSSID_LEN); +#ifdef WLAN_FEATURE_11W + pWextState->roamProfile.MFPEnabled = eANI_BOOLEAN_FALSE; + pWextState->roamProfile.MFPRequired = 0; + pWextState->roamProfile.MFPCapable = 0; +#endif + + pWextState->authKeyMgmt = 0; + + vos_mem_zero(&pWextState->roamProfile.Keys, + sizeof(pWextState->roamProfile.Keys)); + +#ifdef FEATURE_WLAN_WAPI + pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN; + pAdapter->wapi_info.nWapiMode = 0; +#endif + + vos_mem_zero((void *)(pWextState->req_bssId), WNI_CFG_BSSID_LEN); + +} + +void wlan_hdd_ula_done_cb(v_VOID_t *callbackContext) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t*)callbackContext; + + if ( (pAdapter == NULL) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pAdapter magic/ pAdapter is NULL", __func__); + } + else + { + complete(&pAdapter->ula_complete); + } +} + +VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + VOS_STATUS vos_status; + unsigned long rc; + + if (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated) + { + INIT_COMPLETION(pAdapter->ula_complete); + + /*To avoid race condition between the set key and the last EAPOL + packet, notify TL to finish upper layer authentication incase if the + last EAPOL packet pending in the TL queue.*/ + vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb, pAdapter); + + if ( vos_status != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] WLANTL_Finish_ULA returned ERROR status= %d", + __LINE__, vos_status ); + return vos_status; + + } + + rc = wait_for_completion_timeout(&pAdapter->ula_complete, + msecs_to_jiffies(HDD_FINISH_ULA_TIME_OUT)); + if (rc <= 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failure wait on ULA to complete %ld"), rc); + /* we'll still fall through and return success since the + * connection may still get established but is just taking + * too long for us to wait */ + } + } + return VOS_STATUS_SUCCESS; +} + +v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, v_U8_t *ie, int ie_len) +{ + + int left = ie_len; + v_U8_t *ptr = ie; + v_U8_t elem_id,elem_len; + v_U8_t eid = 0xDD; + + if ( NULL == ie || 0 == ie_len ) + return NULL; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len,left); + return NULL; + } + if ((elem_id == eid) && (elem_len >= oui_size)) + { + if(memcmp( &ptr[2], oui, oui_size)==0) + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +static int __iw_set_commit(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL\n", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + /* Do nothing for now */ + + EXIT(); + return ret; +} + +static int iw_set_commit(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_commit(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_name(struct net_device *dev, + struct iw_request_info *info, + char *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL\n", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ); + EXIT(); + return ret; +} + +static int iw_get_name(struct net_device *dev, + struct iw_request_info *info, + char *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_name(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tCsrRoamProfile *pRoamProfile; + eCsrRoamBssType LastBSSType; + eMib_dot11DesiredBssType connectedBssType; + hdd_config_t *pConfig; + struct wireless_dev *wdev; + int status = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return 0; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (pWextState == NULL) + { + hddLog(LOGE, "%s ERROR: Data Storage Corruption", __func__); + return -EINVAL; + } + + wdev = dev->ieee80211_ptr; + pRoamProfile = &pWextState->roamProfile; + LastBSSType = pRoamProfile->BSSType; + + hddLog(LOG1, "%s Old Bss type = %d", __func__, LastBSSType); + + switch (wrqu->mode) + { + case IW_MODE_ADHOC: + hddLog(LOG1, "%s Setting AP Mode as IW_MODE_ADHOC", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS; + // Set the phymode correctly for IBSS. + pConfig = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini; + pWextState->roamProfile.phyMode = hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode); + pAdapter->device_mode = WLAN_HDD_IBSS; + wdev->iftype = NL80211_IFTYPE_ADHOC; + break; + case IW_MODE_INFRA: + hddLog(LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + wdev->iftype = NL80211_IFTYPE_STATION; + break; + case IW_MODE_AUTO: + hddLog(LOG1, "%s Setting AP Mode as IW_MODE_AUTO", __func__); + pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY; + break; + default: + hddLog(LOGE, "%s Unknown AP Mode value %d ", __func__, wrqu->mode); + return -EOPNOTSUPP; + } + + if ( LastBSSType != pRoamProfile->BSSType ) + { + //the BSS mode changed + // We need to issue disconnect if connected or in IBSS disconnect state + if ( hdd_connGetConnectedBssType( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) || + ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) ) + { + VOS_STATUS vosStatus; + // need to issue a disconnect to CSR. + INIT_COMPLETION(pAdapter->disconnect_comp_var); + vosStatus = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_IBSS_LEAVE ); + if(VOS_STATUS_SUCCESS == vosStatus) + { + long ret; + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on disconnect_comp_var %ld"), ret); + } + } + } + + EXIT(); + return 0; +} + +static int iw_set_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_mode(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return 0; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (pWextState == NULL) + { + hddLog(LOGE, "%s ERROR: Data Storage Corruption", __func__); + return -EINVAL; + } + + switch (pWextState->roamProfile.BSSType) + { + case eCSR_BSS_TYPE_INFRASTRUCTURE: + hddLog(LOG1, "%s returns IW_MODE_INFRA", __func__); + wrqu->mode = IW_MODE_INFRA; + break; + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + hddLog(LOG1, "%s returns IW_MODE_ADHOC", __func__); + wrqu->mode = IW_MODE_ADHOC; + break; + case eCSR_BSS_TYPE_ANY: + hddLog(LOG1, "%s returns IW_MODE_AUTO", __func__); + wrqu->mode = IW_MODE_AUTO; + break; + default: + hddLog(LOG1, "%s returns APMODE_UNKNOWN", __func__); + break; + } + + EXIT(); + return 0; +} + +static int iw_get_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_mode(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + v_U32_t numChans = 0; + v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + v_U32_t indx = 0; + v_U32_t status = 0; + + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tHalHandle hHal; + hdd_station_ctx_t *pHddStaCtx; + tCsrRoamProfile * pRoamProfile; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Invalid Adapter",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:STA context is NULL",__func__); + return -EINVAL; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + pRoamProfile = &pWextState->roamProfile; + + hddLog(LOG1,"setCHANNEL ioctl"); + + /* Link is up then return cant set channel*/ + if(eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState || + eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + hddLog( LOGE, "IBSS Associated"); + return -EOPNOTSUPP; + } + + /* Settings by Frequency as input */ + if((wrqu->freq.e == 1) && (wrqu->freq.m >= (tANI_U32)2.412e8) && + (wrqu->freq.m <= (tANI_U32)5.825e8)) + { + tANI_U32 freq = wrqu->freq.m / 100000; + + while ((indx < FREQ_CHAN_MAP_TABLE_SIZE) && (freq != freq_chan_map[indx].freq)) + indx++; + if (indx >= FREQ_CHAN_MAP_TABLE_SIZE) + { + return -EINVAL; + } + wrqu->freq.e = 0; + wrqu->freq.m = freq_chan_map[indx].chan; + + } + + if (wrqu->freq.e == 0) + { + if((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) || + (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX)) + { + hddLog(LOG1,"%s: Channel [%d] is outside valid range from %d to %d", + __func__, wrqu->freq.m, WNI_CFG_CURRENT_CHANNEL_STAMIN, + WNI_CFG_CURRENT_CHANNEL_STAMAX); + return -EINVAL; + } + + numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if (ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST, + validChan, &numChans) != eHAL_STATUS_SUCCESS){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST")); + return -EIO; + } + + for (indx = 0; indx < numChans; indx++) { + if (wrqu->freq.m == validChan[indx]){ + break; + } + } + } + else{ + + return -EINVAL; + } + + if(indx >= numChans) + { + return -EINVAL; + } + + /* Set the Operational Channel */ + numChans = pRoamProfile->ChannelInfo.numOfChannels = 1; + pHddStaCtx->conn_info.operationChannel = wrqu->freq.m; + pRoamProfile->ChannelInfo.ChannelList = &pHddStaCtx->conn_info.operationChannel; + + hddLog(LOG1,"pRoamProfile->operationChannel = %d", wrqu->freq.m); + + EXIT(); + + return status; +} + +static int iw_set_freq(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_freq(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + v_U32_t status = FALSE, channel = 0, freq = 0; + hdd_adapter_t *pAdapter; + tHalHandle hHal; + hdd_wext_state_t *pWextState; + tCsrRoamProfile * pRoamProfile; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: HddStaCtx is NULL", __func__); + return -EINVAL; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + pRoamProfile = &pWextState->roamProfile; + + if( pHddStaCtx->conn_info.connState== eConnectionState_Associated ) + { + if (sme_GetOperationChannel(hHal, &channel, pAdapter->sessionId) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to get operating channel %u"), pAdapter->sessionId); + return -EIO; + } + else + { + status = hdd_wlan_get_freq(channel, &freq); + if( TRUE == status ) + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = freq; + fwrq->e = MHZ; + } + } + } + else + { + /* Set Exponent parameter as 6 (MHZ) in struct iw_freq + * iwlist & iwconfig command shows frequency into proper + * format (2.412 GHz instead of 246.2 MHz)*/ + fwrq->m = 0; + fwrq->e = MHZ; + } + + EXIT(); + return ret; +} + +static int iw_get_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_freq(dev, info, fwrq, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + wrqu->txpower.value = 0; + return 0; + } + wlan_hdd_get_classAstats(pAdapter); + wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr; + + EXIT(); + return 0; +} + +static int iw_get_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_tx_power(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + if ( ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, wrqu->txpower.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_CURRENT_TX_POWER_LEVEL")); + return -EIO; + } + + EXIT(); + + return 0; +} + +static int iw_set_tx_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_tx_power(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_bitrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) { + wrqu->bitrate.value = 0; + } + else + { + status = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_GLOBAL_CLASSB_STATS | + SME_GLOBAL_CLASSC_STATS | + SME_GLOBAL_CLASSD_STATS | + SME_PER_STA_STATS, + hdd_StatisticsCB, 0, FALSE, + pHddStaCtx->conn_info.staId[0], pAdapter ); + + if(eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics", + __func__); + return status; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME timeout while retrieving statistics", + __func__); + return VOS_STATUS_E_FAILURE; + } + + wrqu->bitrate.value = pAdapter->hdd_stats.ClassA_stat.tx_rate*500*1000; + } + + EXIT(); + + return vos_status; +} + +static int iw_get_bitrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_bitrate(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +/* ccm call back function */ + +static int __iw_set_bitrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_wext_state_t *pWextState; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN]; + v_U32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN; + v_U32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN; + v_U32_t i, rate; + v_U32_t valid_rate = FALSE, active_phy_mode = 0; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + return -ENXIO ; + } + + rate = wrqu->bitrate.value; + + if (rate == -1) + { + rate = WNI_CFG_FIXED_RATE_AUTO; + valid_rate = TRUE; + } + else if (ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS) + { + if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G + || active_phy_mode == WNI_CFG_DOT11_MODE_11B) + { + if ((ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_SUPPORTED_RATES_11A, + supp_rates, &a_len) == eHAL_STATUS_SUCCESS) && + (ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_SUPPORTED_RATES_11B, + supp_rates, &b_len) == eHAL_STATUS_SUCCESS)) + { + for (i = 0; i < (b_len + a_len); ++i) + { + /* supported rates returned is double the actual rate so we divide it by 2 */ + if ((supp_rates[i]&0x7F)/2 == rate) + { + valid_rate = TRUE; + rate = i + WNI_CFG_FIXED_RATE_1MBPS; + break; + } + } + } + } + } + if (valid_rate != TRUE) + { + return -EINVAL; + } + if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), + WNI_CFG_FIXED_RATE, rate, + ccmCfgSetCallback,eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_FIXED_RATE")); + return -EIO; + } + + EXIT(); + return 0; +} + +static int iw_set_bitrate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_bitrate(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *pWextState; + u_int8_t *genie = NULL; + u_int8_t *base_genie = NULL; + v_U16_t remLen; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + if (!wrqu->data.length) { + hdd_clearRoamProfileIe(pAdapter); + EXIT(); + return 0; + } + + base_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer, + wrqu->data.length); + if (NULL == base_genie) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + genie = base_genie; + + remLen = wrqu->data.length; + + hddLog(LOG1,"iw_set_genie ioctl IE[0x%X], LEN[%d]", genie[0], genie[1]); + + /* clear any previous genIE before this call */ + memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) ); + + while (remLen >= 2) + { + v_U16_t eLen = 0; + v_U8_t elementId; + elementId = *genie++; + eLen = *genie++; + remLen -= 2; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]", + __func__, elementId, eLen); + + if (remLen < eLen) { + hddLog(LOGE, "Remaining len: %u less than ie len: %u", + remLen, eLen); + ret = -EINVAL; + goto exit; + } + + switch ( elementId ) + { + case IE_EID_VENDOR: + if ((IE_LEN_SIZE+IE_EID_SIZE+IE_VENDOR_OUI_SIZE) > eLen) /* should have at least OUI */ + { + ret = -EINVAL; + goto exit; + } + + if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) + { + v_U16_t curGenIELen = pWextState->genIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)", + __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2); + + if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + VOS_ASSERT(0); + ret = -EINVAL; + goto exit; + } + // save to Additional IE ; it should be accumulated to handle WPS IE + other IE + memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2); + pWextState->genIE.length += eLen + 2; + } + else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) + { + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2); + if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + ret = -EINVAL; + VOS_ASSERT(0); + goto exit; + } + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)); + pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nWPAReqIELength = eLen + 2; + } + else /* any vendorId except WPA IE should be accumulated to genIE */ + { + v_U16_t curGenIELen = pWextState->genIE.length; + hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OUI(%02x %02x %02x %02x) IE(len %d)", + __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2); + + if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) ) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + VOS_ASSERT(0); + ret = -ENOMEM; + goto exit; + } + // save to Additional IE ; it should be accumulated to handle WPS IE + other IE + memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2); + pWextState->genIE.length += eLen + 2; + } + break; + case DOT11F_EID_RSN: + hddLog (LOG1, "%s Set RSN IE (len %d)",__func__, eLen+2); + if ((eLen + 2) > (sizeof(pWextState->WPARSNIE))) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. " + "Need bigger buffer space"); + ret = -EINVAL; + VOS_ASSERT(0); + goto exit; + } + memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN ); + memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)); + pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE; + pWextState->roamProfile.nRSNReqIELength = eLen + 2; + break; + + default: + hddLog (LOGE, "%s Set UNKNOWN IE %X",__func__, elementId); + goto exit; + } + remLen -= eLen; + + /* Move genie only if next element is present */ + if (remLen >= 2) + genie += eLen; + } + +exit: + EXIT(); + kfree(base_genie); + return ret; +} + +static int iw_set_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_genie(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_wext_state_t *pWextState; + hdd_context_t *pHddCtx; + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + eHalStatus status; + v_U32_t length = DOT11F_IE_RSN_MAX_LEN; + v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN]; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + if( pHddStaCtx->conn_info.connState == eConnectionState_NotConnected) + { + return -ENXIO; + } + + // Return something ONLY if we are associated with an RSN or WPA network + if ( VOS_TRUE != hdd_IsAuthTypeRSN(WLAN_HDD_GET_HAL_CTX(pAdapter), + pWextState->roamProfile.negotiatedAuthType)) + { + return -ENXIO; + } + + // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.) + status = csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &length, + genIeBytes); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(LOGE, FL("failed to get WPA-RSN IE data")); + return -EFAULT; + } + + wrqu->data.length = length; + if (length > DOT11F_IE_RSN_MAX_LEN) { + hddLog(LOGE, + FL("invalid buffer length length:%d"), length); + return -E2BIG; + } + + vos_mem_copy( extra, (v_VOID_t*)genIeBytes, length); + + hddLog(LOG1, FL("RSN IE of %d bytes returned"), wrqu->data.length ); + + EXIT(); + + return 0; +} + +static int iw_get_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_genie(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int __iw_get_encode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_wext_state_t *pWextState; + tCsrRoamProfile *pRoamProfile; + int keyId, i, ret = 0; + eCsrAuthType authType = eCSR_AUTH_TYPE_NONE; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + pRoamProfile = &(pWextState->roamProfile); + keyId = pRoamProfile->Keys.defaultIndex; + + if(keyId < 0 || keyId >= MAX_WEP_KEYS) + { + hddLog(LOG1,"%s: Invalid keyId : %d",__func__,keyId); + return -EINVAL; + } + + if(pRoamProfile->Keys.KeyLength[keyId] > 0) + { + dwrq->flags |= IW_ENCODE_ENABLED; + dwrq->length = pRoamProfile->Keys.KeyLength[keyId]; + vos_mem_copy(extra,&(pRoamProfile->Keys.KeyMaterial[keyId][0]),pRoamProfile->Keys.KeyLength[keyId]); + + dwrq->flags |= (keyId + 1); + + } + else + { + dwrq->flags |= IW_ENCODE_DISABLED; + } + + for(i=0; i < MAX_WEP_KEYS; i++) + { + if(pRoamProfile->Keys.KeyMaterial[i] == NULL) + { + continue; + } + else + { + break; + } + } + + if(MAX_WEP_KEYS == i) + { + dwrq->flags |= IW_ENCODE_NOKEY; + } + + authType = ((hdd_station_ctx_t*)WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType; + + if(eCSR_AUTH_TYPE_OPEN_SYSTEM == authType) + { + dwrq->flags |= IW_ENCODE_OPEN; + } + else + { + dwrq->flags |= IW_ENCODE_RESTRICTED; + } + EXIT(); + return 0; +} + +static int iw_get_encode(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_encode(dev, info, dwrq, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +#define PAE_ROLE_AUTHENTICATOR 1 // =1 for authenticator, +#define PAE_ROLE_SUPPLICANT 0 // =0 for supplicant + + +/* + * This function sends a single 'key' to LIM at all time. + */ + +static int __iw_get_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U32_t status = 0; + + status = hdd_wlan_get_rts_threshold(pAdapter,wrqu); + + return status; +} + +static int iw_get_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_rts_threshold(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tHalHandle hHal; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if ( wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX ) + { + return -EINVAL; + } + + if ( ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_RTS_THRESHOLD")); + return -EIO; + } + + EXIT(); + + return 0; +} + +static int iw_set_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_rts_threshold(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U32_t status = 0; + + status = hdd_wlan_get_frag_threshold(pAdapter,wrqu); + + return status; +} + +static int iw_get_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_frag_threshold(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tHalHandle hHal; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if ( wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX ) + { + return -EINVAL; + } + + if ( ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_FRAGMENTATION_THRESHOLD")); + return -EIO; + } + + EXIT(); + + return 0; +} + +static int iw_set_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_frag_threshold(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + EXIT(); + return -EOPNOTSUPP; +} + +static int iw_get_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_power_mode(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +static int __iw_set_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + EXIT(); + return -EOPNOTSUPP; +} + +static int iw_set_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_power_mode(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int ret = 0; + struct iw_range *range = (struct iw_range *) extra; + + v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + + v_U32_t num_channels = sizeof(channels); + v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN]; + v_U32_t a_len; + v_U32_t b_len; + v_U32_t active_phy_mode = 0; + v_U8_t index = 0, i; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return -EINVAL; + } + wrqu->data.length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + + /*Get the phy mode*/ + if (ccmCfgGetInt(hHal, + WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "active_phy_mode = %d", active_phy_mode); + + if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G) + { + /*Get the supported rates for 11G band*/ + a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN; + if (ccmCfgGetStr(hHal, + WNI_CFG_SUPPORTED_RATES_11A, + supp_rates, &a_len) == eHAL_STATUS_SUCCESS) + { + if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN) + { + a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN; + } + for (i = 0; i < a_len; i++) + { + range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000; + } + range->num_bitrates = a_len; + } + else + { + return -EIO; + } + } + else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B) + { + /*Get the supported rates for 11B band*/ + b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN; + if (ccmCfgGetStr(hHal, + WNI_CFG_SUPPORTED_RATES_11B, + supp_rates, &b_len) == eHAL_STATUS_SUCCESS) + { + if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN) + { + b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN; + } + for (i = 0; i < b_len; i++) + { + range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000; + } + range->num_bitrates = b_len; + } + else + { + return -EIO; + } + } + } + + range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX; + range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN; + range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX; + + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + range->num_encoding_sizes = 2; + range->max_encoding_tokens = MAX_WEP_KEYS; + + // we support through Wireless Extensions 22 + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 22; + + /*Supported Channels and Frequencies*/ + if (ccmCfgGetStr((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels, &num_channels) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_VALID_CHANNEL_LIST")); + return -EIO; + } + if (num_channels > IW_MAX_FREQUENCIES) + { + num_channels = IW_MAX_FREQUENCIES; + } + + range->num_channels = num_channels; + range->num_frequency = num_channels; + + for (index=0; index < num_channels; index++) + { + v_U32_t frq_indx = 0; + + range->freq[index].i = channels[index]; + while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE) + { + if(channels[index] == freq_chan_map[frq_indx].chan) + { + range->freq[index].m = freq_chan_map[frq_indx].freq * 100000; + range->freq[index].e = 1; + break; + } + frq_indx++; + } + } + + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + + /*Encryption capability*/ + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + + /* Txpower capability */ + range->txpower_capa = IW_TXPOW_MWATT; + + /*Scanning capability*/ + #if WIRELESS_EXT >= 22 + range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL; + #endif + + EXIT(); + return 0; +} + +static int iw_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_range(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* Callback function registered with PMC to know status of PMC request */ +static void iw_power_callback_fn (void *pContext, eHalStatus status) +{ + struct statsContext *pStatsContext; + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + pStatsContext = (struct statsContext *)pContext; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if (POWER_CONTEXT_MAGIC != pStatsContext->magic) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, magic [%08x]", + __func__, pStatsContext->magic); + + if (ioctl_debug) + { + pr_info("%s: Invalid context, magic [%08x]\n", + __func__, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +/* Callback function for tx per hit */ +void hdd_tx_per_hit_cb (void *pCallbackContext) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCallbackContext; + unsigned char tx_fail[16]; + union iwreq_data wrqu; + + if (NULL == pAdapter || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + hddLog(LOGE, "hdd_tx_per_hit_cb: pAdapter is NULL"); + return; + } + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlcpy(tx_fail, "TX_FAIL", sizeof(tx_fail)); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail); +} + +void hdd_GetClassA_statisticsCB(void *pStats, void *pContext) +{ + struct statsContext *pStatsContext; + tCsrGlobalClassAStatsInfo *pClassAStats; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: pStats [%p] pContext [%p]\n", + __func__, pStats, pContext); + } + + if ((NULL == pStats) || (NULL == pContext)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pStats [%p] pContext [%p]", + __func__, pStats, pContext); + return; + } + + pClassAStats = pStats; + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ + pAdapter->hdd_stats.ClassA_stat = *pClassAStats; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + eHalStatus hstatus; + long lrc; + struct statsContext context; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Padapter is NULL", __func__); + return VOS_STATUS_E_FAULT; + } + if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__); + return VOS_STATUS_SUCCESS; + } + + /* we are connected + prepare our callback context */ + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + /* query only for Class A statistics (which include link speed) */ + hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), + eCSR_HDD, + SME_GLOBAL_CLASSA_STATS, + hdd_GetClassA_statisticsCB, + 0, // not periodic + FALSE, //non-cached results + pHddStaCtx->conn_info.staId[0], + &context); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve Class A statistics", + __func__); + /* we'll returned a cached value below */ + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while retrieving Class A statistics", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + /* either callback updated pAdapter stats or it has cached data */ + return VOS_STATUS_SUCCESS; +} + +static void hdd_get_station_statisticsCB(void *pStats, void *pContext) +{ + struct statsContext *pStatsContext; + tCsrSummaryStatsInfo *pSummaryStats; + tCsrGlobalClassAStatsInfo *pClassAStats; + hdd_adapter_t *pAdapter; + + if (ioctl_debug) + { + pr_info("%s: pStats [%p] pContext [%p]\n", + __func__, pStats, pContext); + } + + if ((NULL == pStats) || (NULL == pContext)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pStats [%p] pContext [%p]", + __func__, pStats, pContext); + return; + } + + /* there is a race condition that exists between this callback + function and the caller since the caller could time out either + before or while this code is executing. we use a spinlock to + serialize these actions */ + spin_lock(&hdd_context_lock); + + pSummaryStats = (tCsrSummaryStatsInfo *)pStats; + pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 ); + pStatsContext = pContext; + pAdapter = pStatsContext->pAdapter; + if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, pStatsContext->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n", + __func__, pAdapter, pStatsContext->magic); + } + return; + } + + /* context is valid so caller is still waiting */ + + /* paranoia: invalidate the magic */ + pStatsContext->magic = 0; + + /* copy over the stats. do so as a struct copy */ + pAdapter->hdd_stats.summary_stat = *pSummaryStats; + pAdapter->hdd_stats.ClassA_stat = *pClassAStats; + + /* notify the caller */ + complete(&pStatsContext->completion); + + /* serialization is complete */ + spin_unlock(&hdd_context_lock); +} + +VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter) +{ + hdd_station_ctx_t *pHddStaCtx; + hdd_ap_ctx_t *sap_ctx; + eHalStatus hstatus; + long lrc; + struct statsContext context; + tANI_U8 sta_id; + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Padapter is NULL", __func__); + return VOS_STATUS_SUCCESS; + } + + if (pAdapter->device_mode == WLAN_HDD_SOFTAP) { + sap_ctx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + sta_id = sap_ctx->uBCStaId; + } else { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + sta_id = pHddStaCtx->conn_info.staId[0]; + } + + /* we are connected + prepare our callback context */ + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = STATS_CONTEXT_MAGIC; + + /* query only for Summary & Class A statistics */ + hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter), + eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_PER_PKT_STATS, + hdd_get_station_statisticsCB, + 0, // not periodic + FALSE, //non-cached results + sta_id, + &context); + if (eHAL_STATUS_SUCCESS != hstatus) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve statistics", + __func__); + /* we'll return with cached values */ + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while retrieving statistics", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + /* either callback updated pAdapter stats or it has cached data */ + return VOS_STATUS_SUCCESS; +} + + +/* + * Support for the LINKSPEED private command + * Per the WiFi framework the response must be of the form + * "LinkSpeed xx" + */ +static int iw_get_linkspeed(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + char *pLinkSpeed = (char*)extra; + int len = sizeof(v_U32_t) + 1; + v_U32_t link_speed; + hdd_station_ctx_t *pHddStaCtx; + VOS_STATUS status; + int rc, valid = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + valid = wlan_hdd_validate_context(pHddCtx); + if (0 != valid) + { + return valid; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + /* we are not connected so we don't have a classAstats */ + link_speed = 0; + } + else + { + status = wlan_hdd_get_classAstats(pAdapter); + + if (!VOS_IS_STATUS_SUCCESS(status )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to retrieve SME statistics")); + return -EINVAL; + } + + /* Unit of link capacity is obtained from the TL API is MbpsX10 */ + WLANTL_GetSTALinkCapacity(WLAN_HDD_GET_CTX(pAdapter)->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + &link_speed); + + link_speed = link_speed / 10; + + if (0 == link_speed) + { + /* The linkspeed returned by HAL is in units of 500kbps. + * converting it to mbps. + * This is required to support legacy firmware which does + * not return link capacity. + */ + link_speed = pAdapter->hdd_stats.ClassA_stat.tx_rate/2; + } + + } + + wrqu->data.length = len; + // return the linkspeed in the format required by the WiFi Framework + rc = snprintf(pLinkSpeed, len, "%u", link_speed); + if ((rc < 0) || (rc >= len)) + { + // encoding or length error? + hddLog(VOS_TRACE_LEVEL_ERROR,FL("Unable to encode link speed")); + return -EIO; + } + + EXIT(); + /* a value is being successfully returned */ + return rc; +} + +/* + * Helper function to return correct value for WLAN_GET_LINK_SPEED + * + */ +static int __iw_get_linkspeed_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int rc; + + rc = iw_get_linkspeed(dev, info, wrqu, extra); + + if (rc < 0) + return rc; + + /* a value is being successfully returned */ + return 0; +} + +static int iw_get_linkspeed_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_linkspeed_priv(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* + * Support for the RSSI & RSSI-APPROX private commands + * Per the WiFi framework the response must be of the form + * " rssi " + * unless we are not associated, in which case the response is + * "OK" + */ +static int iw_get_rssi(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + char *cmd = extra; + int len = wrqu->data.length; + v_S7_t s7Rssi = 0; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length; + VOS_STATUS vosStatus; + int rc; + + if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) || + (0 == ssidlen) || (ssidlen >= len)) + { + /* we are not connected or our SSID is too long + so we cannot report an rssi */ + rc = scnprintf(cmd, len, "OK"); + } + else + { + /* we are connected with a valid SSID + so we can write the SSID into the return buffer + (note that it is not NUL-terminated) */ + memcpy(cmd, pHddStaCtx->conn_info.SSID.SSID.ssId, ssidlen ); + + wlan_hdd_get_station_stats(pAdapter); + vosStatus = wlan_hdd_get_rssi(pAdapter, &s7Rssi); + + if (VOS_STATUS_SUCCESS == vosStatus) + { + /* append the rssi to the ssid in the format required by + the WiFI Framework */ + rc = scnprintf(&cmd[ssidlen], len - ssidlen, " rssi %d", s7Rssi); + rc += ssidlen; + } + else + { + rc = -1; + } + } + + /* verify that we wrote a valid response */ + if ((rc < 0) || (rc >= len)) + { + // encoding or length error? + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to encode RSSI, got [%s]", + __func__, cmd); + return -EIO; + } + + /* a value is being successfully returned */ + return rc; +} + +/* + * Support for SoftAP channel range private command + */ +static int iw_softap_set_channel_range( struct net_device *dev, + int startChannel, + int endChannel, + int band) +{ + VOS_STATUS status; + int ret = 0; + hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + + + status = WLANSAP_SetChannelRange(hHal, startChannel, endChannel, band); + if (VOS_STATUS_SUCCESS != status) + { + ret = -EINVAL; + } + pHddCtx->is_dynamic_channel_range_set = 1; + return ret; +} + +static uint8 chartohex(char c) +{ + uint8 val = 0; + if (c >= '0' && c <= '9') + val = c - '0'; + else if (c >= 'a' && c <= 'f') + val = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = c - 'A' + 10; + else + hddLog(VOS_TRACE_LEVEL_ERROR, "Not a valid hex char"); + + return val; +} + +uint8 getByte(char **buf) +{ + uint8 byte = 0; + char *temp = *buf; + byte = chartohex(*temp) * 16; + temp++; + byte += chartohex(*temp); + temp++; + *buf = temp; + return byte; +} + +static void parse_Bufferforpkt(tSirpkt80211 *pkt, u8 *pBuffer, u16 len) +{ + tSir80211Header *macHeader; + int i = 0, j = 0, length = 0; + uint8 byte = 0; + char *temp = pBuffer; + uint16 fragNum = 0; + char *pHeader; + tSir80211Header header; + + macHeader = &pkt->macHeader; + + pkt->encParams.keyParams.key[0].keyId = *temp - '0'; + + temp++; + + hddLog(VOS_TRACE_LEVEL_ERROR, "Input Message to encrypt"); + hddLog(VOS_TRACE_LEVEL_ERROR, "Key Id : %d", + pkt->encParams.keyParams.key[0].keyId); + + for (i = 0; i< 16; i++) { + pkt->encParams.keyParams.key[0].key[i] + = getByte(&temp); + } + + print_hex_dump(KERN_INFO, "Key : ", DUMP_PREFIX_NONE, 16, 1, + &pkt->encParams.keyParams.key[0].key[0], 16, 0); + + for (i = 0; i< 6; i++) { + pkt->encParams.pn[i] + = getByte(&temp); + } + + print_hex_dump(KERN_INFO, "PN : ", DUMP_PREFIX_NONE, 16, 1, + &pkt->encParams.pn[0], 6, 0); + + for (i = 0, j= 5; i< 3; i++, j--) { + byte = pkt->encParams.pn[i]; + pkt->encParams.pn[i] = pkt->encParams.pn[j]; + pkt->encParams.pn[j] = byte; + } + + length = getByte(&temp); + if (length > sizeof(tSir80211Header)) + length = sizeof(tSir80211Header); + + pHeader = temp; + vos_mem_zero(&header, sizeof(tSir80211Header)); + for (i = 0; i < length; i++) { + *((uint8 *)&header + i) = getByte(&pHeader); + } + + print_hex_dump(KERN_INFO, "Header : ", DUMP_PREFIX_NONE, 16, 1, + (char *)&header, length, 0); + + byte = getByte(&temp); + + macHeader->frameCtrl.protVer = byte & 0x3; + macHeader->frameCtrl.type = (byte >> 2) & 0x3; + macHeader->frameCtrl.subType = (byte >> 4) & 0xF; + + byte = getByte(&temp); + macHeader->frameCtrl.toDS = (byte) & 0x1; + macHeader->frameCtrl.fromDS = (byte >> 1) & 0x1; + macHeader->frameCtrl.moreFrag = (byte >> 2) & 0x1; + macHeader->frameCtrl.retry = (byte >> 3) & 0x1; + macHeader->frameCtrl.powerMgmt = (byte >> 4) & 0x1; + macHeader->frameCtrl.moreData = (byte >> 5) & 0x1; + macHeader->frameCtrl.wep = (byte >> 6) & 0x1; + macHeader->frameCtrl.order = (byte >> 7) & 0x1; + + hddLog(VOS_TRACE_LEVEL_INFO, "macHeader->frameCtrl.protVer : %x " + "macHeader->frameCtrl.type : %x " + "macHeader->frameCtrl.subType : %x " + "macHeader->frameCtrl.toDS : %x " + "macHeader->frameCtrl.fromDS : %x " + "macHeader->frameCtrl.moreFrag : %x " + "macHeader->frameCtrl.retry : %x " + "macHeader->frameCtrl.powerMgmt : %x " + "macHeader->frameCtrl.MoreData : %x " + "macHeader->frameCtrl.wep : %x " + "macHeader->frameCtrl.order : %x " + , macHeader->frameCtrl.protVer + , macHeader->frameCtrl.type + , macHeader->frameCtrl.subType + , macHeader->frameCtrl.toDS + , macHeader->frameCtrl.fromDS + , macHeader->frameCtrl.moreFrag + , macHeader->frameCtrl.retry + , macHeader->frameCtrl.powerMgmt + , macHeader->frameCtrl.moreData + , macHeader->frameCtrl.wep + , macHeader->frameCtrl.order); + + + macHeader->usDurationId = getByte(&temp); + macHeader->usDurationId += getByte(&temp) << 8; + + macHeader->vA1[0] = getByte(&temp); + macHeader->vA1[1] = getByte(&temp); + macHeader->vA1[2] = getByte(&temp); + macHeader->vA1[3] = getByte(&temp); + macHeader->vA1[4] = getByte(&temp); + macHeader->vA1[5] = getByte(&temp); + + macHeader->vA2[0] = getByte(&temp); + macHeader->vA2[1] = getByte(&temp); + macHeader->vA2[2] = getByte(&temp); + macHeader->vA2[3] = getByte(&temp); + macHeader->vA2[4] = getByte(&temp); + macHeader->vA2[5] = getByte(&temp); + + macHeader->vA3[0] = getByte(&temp); + macHeader->vA3[1] = getByte(&temp); + macHeader->vA3[2] = getByte(&temp); + macHeader->vA3[3] = getByte(&temp); + macHeader->vA3[4] = getByte(&temp); + macHeader->vA3[5] = getByte(&temp); + + macHeader->sSeqCtrl = getByte(&temp); + fragNum = macHeader->sSeqCtrl & 0xF; + macHeader->sSeqCtrl >>= 4; + + macHeader->sSeqCtrl += getByte(&temp) << 4; + + macHeader->sSeqCtrl |= fragNum << 12; + + if (length == 30 || length == 32) { + macHeader->optvA4[0] = getByte(&temp); + macHeader->optvA4[1] = getByte(&temp); + macHeader->optvA4[2] = getByte(&temp); + macHeader->optvA4[3] = getByte(&temp); + macHeader->optvA4[4] = getByte(&temp); + macHeader->optvA4[5] = getByte(&temp); + } + + if (length == 26 || length == 32) { + macHeader->usQosCtrl = getByte(&temp); + macHeader->usQosCtrl += getByte(&temp) << 8; + } + + //parse payload + length = getByte(&temp); + length += getByte(&temp) << 8; + hddLog(VOS_TRACE_LEVEL_INFO,"Payload length : %d", length); + + if (length >= WLAN_DISA_MAX_PAYLOAD_SIZE) + length = WLAN_DISA_MAX_PAYLOAD_SIZE; + + pkt->data.length = length; + + for (i = 0; i< length; i++) { + pkt->data.data[i] = getByte(&temp); + } + + print_hex_dump(KERN_INFO, "Data : ", DUMP_PREFIX_NONE, 16, 1, + &pkt->data.data[0], pkt->data.length, 0); +} + +/**--------------------------------------------------------------------------- + + \brief hdd_encrypt_msg_cb() - Callback function for DISA + encrypt message request + This is an asynchronous callback function from SME when the encrypted data + is received + + \pEncInfoRsp -> Encrypted data info + + \return - 0 for success non-zero for failure + --------------------------------------------------------------------------*/ +static void +hdd_encrypt_msg_cb(v_VOID_t *pUserData, v_VOID_t *pEncInfoRsp) +{ + tpSetEncryptedDataRspParams pEncryptedDataRsp; + + pEncryptedDataRsp = (tpSetEncryptedDataRspParams)pEncInfoRsp; + + hddLog(VOS_TRACE_LEVEL_ERROR, "Encrypted Message"); + hddLog(VOS_TRACE_LEVEL_ERROR, "Length : %d", + pEncryptedDataRsp->encryptedPayload.length); + hddLog(VOS_TRACE_LEVEL_ERROR, " Encrypted Data: "); + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, + pEncryptedDataRsp->encryptedPayload.data, + pEncryptedDataRsp->encryptedPayload.length, 0); +} + +VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode) +{ + struct statsContext context; + eHalStatus status; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL"); + return VOS_STATUS_E_FAULT; + } + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (pHddCtx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + return VOS_STATUS_E_FAILURE; + } + + init_completion(&context.completion); + + context.pAdapter = pAdapter; + context.magic = POWER_CONTEXT_MAGIC; + + if (DRIVER_POWER_MODE_ACTIVE == mode) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering " + "Full Power", __func__); + status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context, + eSME_FULL_PWR_NEEDED_BY_HDD); + // Enter Full power command received from GUI this means we are disconnected + // Set PMC remainInPowerActiveTillDHCP flag to disable auto BMPS entry by PMC + sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE); + if (eHAL_STATUS_PMC_PENDING == status) + { + /* request was sent -- wait for the response */ + int lrc = wait_for_completion_interruptible_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting fullpower ", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + } + else if (DRIVER_POWER_MODE_AUTO == mode) + { + /* If this is called by hdd_suspend_wlan or hdd_resume_wlan, driver + * was already in BMPS state and thus either STA or P2P-CLI is in + * associated state and authenticated, so even if STA connState is + * not associated it can be assumed that P2P-CLI is associated and + * authenticated. Thus driver can enter BMPS. And even if we try to enter + * BMPS with no adaptor in associated state, pmcRequestBmps will check + * if all condition are satisfied for entering BMPS. + */ + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + hddLog(LOGE, + FL("Station is associated but, still not Authenticated ignore " + "power save mode")); + return VOS_STATUS_E_AGAIN; + } + + if (pHddCtx->cfg_ini->fIsBmpsEnabled) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ", + __func__); + // Enter BMPS command received from GUI this means DHCP is completed + // Clear PMC remainInPowerActiveTillDHCP flag to enable auto BMPS entry + sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), + FALSE); + status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context); + if (eHAL_STATUS_PMC_PENDING == status) + { + /* request was sent -- wait for the response */ + int lrc = wait_for_completion_interruptible_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while requesting BMPS", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + } + } + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not " + "enabled in the cfg"); + } + } + + /* either we never sent a request, we sent a request and received a + response or we sent a request and timed out. if we never sent a + request or if we sent a request and got a response, we want to + clear the magic out of paranoia. if we timed out there is a + race condition such that the callback function could be + executing at the same time we are. of primary concern is if the + callback function had already verified the "magic" but had not + yet set the completion variable when a timeout occurred. we + serialize these activities by invalidating the magic while + holding a shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx, + hdd_adapter_t *pAdapter) +{ + VOS_STATUS vos_Status; + + if ((NULL == pAdapter) || (NULL == pHddCtx)) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid pointer"); + return VOS_STATUS_E_FAULT; + } + + /**Exit from Deep sleep or standby if we get the driver + START cmd from android GUI + */ + if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit " + "from Stand by",__func__); + vos_Status = hdd_exit_standby(pHddCtx); + } + else if (eHDD_SUSPEND_DEEP_SLEEP == pHddCtx->hdd_ps_state) + { + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit " + "from deep sleep",__func__); + vos_Status = hdd_exit_deep_sleep(pHddCtx, pAdapter); + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Not in standby or deep sleep. " + "Ignore start cmd %d", __func__, pHddCtx->hdd_ps_state); + vos_Status = VOS_STATUS_SUCCESS; + } + + return vos_Status; +} + +VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx) +{ + VOS_STATUS vos_Status = VOS_STATUS_E_FAILURE; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "HDD context NULL"); + return VOS_STATUS_E_FAULT; + } + + if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop) + { + //Execute standby procedure. + //Executing standby procedure will cause the STA to + //disassociate first and then the chip will be put into standby. + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering Stand by mode"); + vos_Status = hdd_enter_standby(pHddCtx); + } + else if (WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP == + pHddCtx->cfg_ini->nEnableDriverStop) + { + //Execute deep sleep procedure + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering " + "deep sleep mode"); + //Deep sleep not supported + vos_Status = hdd_enter_standby(pHddCtx); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO_LOW, "%s: Driver stop is not enabled %d", + __func__, pHddCtx->cfg_ini->nEnableDriverStop); + vos_Status = VOS_STATUS_SUCCESS; + } + + return vos_Status; +} + + +void* wlan_hdd_change_country_code_callback(void *pAdapter) +{ + + hdd_adapter_t *call_back_pAdapter = pAdapter; + complete(&call_back_pAdapter->change_country_code); + + return NULL; +} + +static int __iw_set_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + char *cmd = NULL; + int cmd_len = wrqu->data.length; + int rc = 0, ret = 0; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + hdd_context_t *pHddCtx; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + rc = wlan_hdd_validate_context(pHddCtx); + if (0 != rc) + { + return rc; + } + + cmd = mem_alloc_copy_from_user_helper(wrqu->data.pointer, + wrqu->data.length); + if (NULL == cmd) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + if (ioctl_debug) + { + pr_info("%s: req [%s] len [%d]\n", __func__, cmd, cmd_len); + } + + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: ***Received %s cmd from Wi-Fi GUI***", __func__, cmd); + + if (strncmp(cmd, "CSCAN", 5) == 0 ) + { + if (eHAL_STATUS_SUCCESS != iw_set_cscan(dev, info, wrqu, cmd)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Error in iw_set_scan!", __func__); + rc = -EINVAL; + } + } + else if( strcasecmp(cmd, "start") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Start command"); + /*Exit from Deep sleep or standby if we get the driver START cmd from android GUI*/ + + vos_status = wlan_hdd_exit_lowpower(pHddCtx, pAdapter); + if (vos_status == VOS_STATUS_SUCCESS) + { + union iwreq_data wrqu; + char buf[10]; + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlcpy(buf, "START", sizeof(buf)); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: START CMD Status %d", __func__, vos_status); + rc = -EIO; + } + goto done; + } + else if( strcasecmp(cmd, "stop") == 0 ) + { + union iwreq_data wrqu; + char buf[10]; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Stop command"); + + wlan_hdd_enter_lowpower(pHddCtx); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = strlcpy(buf, "STOP", sizeof(buf)); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + goto done; + } + else if (strcasecmp(cmd, "macaddr") == 0) + { + ret = snprintf(cmd, cmd_len, "Macaddr = " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes)); + } + else if (strcasecmp(cmd, "scan-active") == 0) + { + hddLog(LOG1, + FL("making default scan to active")); + pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN; + ret = snprintf(cmd, cmd_len, "OK"); + } + else if (strcasecmp(cmd, "scan-passive") == 0) + { + hddLog(LOG1, + FL("making default scan to passive")); + pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN; + ret = snprintf(cmd, cmd_len, "OK"); + } + else if( strcasecmp(cmd, "scan-mode") == 0 ) + { + ret = snprintf(cmd, cmd_len, "ScanMode = %u", pHddCtx->scan_info.scan_mode); + } + else if( strcasecmp(cmd, "linkspeed") == 0 ) + { + ret = iw_get_linkspeed(dev, info, wrqu, cmd); + } + else if( strncasecmp(cmd, "rssi", 4) == 0 ) + { + ret = iw_get_rssi(dev, info, wrqu, cmd); + } + else if( strncasecmp(cmd, "powermode", 9) == 0 ) { + int mode; + char *ptr; + + if (9 < cmd_len) + { + ptr = (char*)(cmd + 9); + + }else{ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "CMD LENGTH %d is not correct",cmd_len); + kfree(cmd); + return -EINVAL; + } + + if (1 != sscanf(ptr,"%d",&mode)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "powermode input %s is not correct",ptr); + kfree(cmd); + return -EIO; + } + + wlan_hdd_enter_bmps(pAdapter, mode); + /*TODO:Set the power mode*/ + } + else if (strncasecmp(cmd, "getpower", 8) == 0 ) { + v_U32_t pmc_state; + v_U16_t value; + + pmc_state = pmcGetPmcState(WLAN_HDD_GET_HAL_CTX(pAdapter)); + if(pmc_state == BMPS) { + value = DRIVER_POWER_MODE_AUTO; + } + else { + value = DRIVER_POWER_MODE_ACTIVE; + } + ret = snprintf(cmd, cmd_len, "powermode = %u", value); + } + else if( strncasecmp(cmd, "btcoexmode", 10) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "btcoexmode"); + /*TODO: set the btcoexmode*/ + } + else if( strcasecmp(cmd, "btcoexstat") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO, "BtCoex Status"); + /*TODO: Return the btcoex status*/ + } + else if( strcasecmp(cmd, "rxfilter-start") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Start command"); + + /*TODO: Enable Rx data Filter*/ + } + else if( strcasecmp(cmd, "rxfilter-stop") == 0 ) { + + hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Stop command"); + + /*TODO: Disable Rx data Filter*/ + } + else if( strcasecmp(cmd, "rxfilter-statistics") == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "Rx Data Filter Statistics command"); + /*TODO: rxfilter-statistics*/ + } + else if( strncasecmp(cmd, "rxfilter-add", 12) == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-add"); + /*TODO: rxfilter-add*/ + } + else if( strncasecmp(cmd, "rxfilter-remove",15) == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-remove"); + /*TODO: rxfilter-remove*/ + } +#ifdef FEATURE_WLAN_SCAN_PNO + else if( strncasecmp(cmd, "pnosetup", 8) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "pnosetup"); + /*TODO: support pnosetup*/ + } + else if( strncasecmp(cmd, "pnoforce", 8) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "pnoforce"); + /*TODO: support pnoforce*/ + } + else if( strncasecmp(cmd, "pno",3) == 0 ) { + + hddLog( VOS_TRACE_LEVEL_INFO, "pno"); + vos_status = iw_set_pno(dev, info, wrqu, cmd, 3); + kfree(cmd); + return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL; + } + else if( strncasecmp(cmd, "rssifilter",10) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "rssifilter"); + vos_status = iw_set_rssi_filter(dev, info, wrqu, cmd, 10); + kfree(cmd); + return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL; + } +#endif /*FEATURE_WLAN_SCAN_PNO*/ + else if( strncasecmp(cmd, "powerparams",11) == 0 ) { + hddLog( VOS_TRACE_LEVEL_INFO, "powerparams"); + vos_status = iw_set_power_params(dev, info, wrqu, cmd, 11); + kfree(cmd); + return (vos_status == VOS_STATUS_SUCCESS) ? 0 : -EINVAL; + } + else if( 0 == strncasecmp(cmd, "CONFIG-TX-TRACKING", 18) ) { + tSirTxPerTrackingParam tTxPerTrackingParam; + char *ptr; + + if (18 < cmd_len) + { + ptr = (char*)(cmd + 18); + }else{ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "CMD LENGTH %d is not correct",cmd_len); + kfree(cmd); + return -EINVAL; + } + + if (4 != sscanf(ptr,"%hhu %hhu %hhu %u", + &(tTxPerTrackingParam.ucTxPerTrackingEnable), + &(tTxPerTrackingParam.ucTxPerTrackingPeriod), + &(tTxPerTrackingParam.ucTxPerTrackingRatio), + &(tTxPerTrackingParam.uTxPerTrackingWatermark))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "CONFIG-TX-TRACKING %s input is not correct",ptr); + kfree(cmd); + return -EIO; + } + + // parameters checking + // period has to be larger than 0 + if (0 == tTxPerTrackingParam.ucTxPerTrackingPeriod) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Period input is not correct"); + kfree(cmd); + return -EIO; + } + + // use default value 5 is the input is not reasonable. in unit of 10% + if ((tTxPerTrackingParam.ucTxPerTrackingRatio > TX_PER_TRACKING_MAX_RATIO) || (0 == tTxPerTrackingParam.ucTxPerTrackingRatio)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Ratio input is not good. use default 5"); + tTxPerTrackingParam.ucTxPerTrackingRatio = TX_PER_TRACKING_DEFAULT_RATIO; + } + + // default is 5 + if (0 == tTxPerTrackingParam.uTxPerTrackingWatermark) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Tx Packet number input is not good. use default 5"); + tTxPerTrackingParam.uTxPerTrackingWatermark = TX_PER_TRACKING_DEFAULT_WATERMARK; + } + + if (eHAL_STATUS_SUCCESS != + sme_SetTxPerTracking(pHddCtx->hHal, + hdd_tx_per_hit_cb, + (void*)pAdapter, &tTxPerTrackingParam)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Set Tx PER Tracking Failed!"); + rc = -EIO; + } + } + else { + hddLog( VOS_TRACE_LEVEL_WARN, "%s: Unsupported GUI command %s", + __func__, cmd); + } +done: + /* many of the commands write information back into the command + string using snprintf(). check the return value here in one + place */ + if ((ret < 0) || (ret >= cmd_len)) + { + /* there was an encoding error or overflow */ + rc = -EINVAL; + } + else if (ret > 0) + { + if (copy_to_user(wrqu->data.pointer, cmd, ret)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data to user buffer", __func__); + kfree(cmd); + return -EFAULT; + } + wrqu->data.length = ret; + } + + if (ioctl_debug) + { + pr_info("%s: rsp [%s] len [%d] status %d\n", + __func__, cmd, wrqu->data.length, rc); + } + kfree(cmd); + EXIT(); + return rc; +} + +static int iw_set_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + vos_ssr_protect(__func__); + ret = __iw_set_priv(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + EXIT(); + return 0; +} + +static int iw_set_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_nick(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + EXIT(); + return 0; +} + +static int iw_get_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_nick(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* cat /proc/net/wireless invokes this function to get wireless stats */ +static struct iw_statistics * __get_wireless_stats(struct net_device *dev) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + v_S7_t snr = 0, rssi = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + + ENTER(); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return NULL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return NULL; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return NULL; + } + + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + wlan_hdd_get_station_stats(pAdapter); + wlan_hdd_get_snr(pAdapter, &snr); + wlan_hdd_get_rssi(pAdapter, &rssi); + + vos_mem_zero(&pAdapter->iwStats, sizeof(pAdapter->iwStats)); + pAdapter->iwStats.status = 0; + pAdapter->iwStats.qual.qual = snr; + pAdapter->iwStats.qual.level = rssi; + pAdapter->iwStats.qual.noise = rssi - snr; + pAdapter->iwStats.discard.code = 0; + pAdapter->iwStats.discard.retries= 0; + pAdapter->iwStats.miss.beacon = 0; + pAdapter->iwStats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("not in associated state: %d"), pHddStaCtx->conn_info.connState); + return NULL; + } + + EXIT(); + return &(pAdapter->iwStats); +} + +static struct iw_statistics *get_wireless_stats(struct net_device *dev) +{ + + struct iw_statistics *stats; + + vos_ssr_protect(__func__); + stats = __get_wireless_stats(dev); + vos_ssr_unprotect(__func__); + + return stats; +} + +static int __iw_set_encode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) + +{ + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + hdd_wext_state_t *pWextState; + hdd_context_t *pHddCtx; + struct iw_point *encoderq = &(wrqu->encoding); + v_U32_t keyId; + v_U8_t key_length; + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + v_BOOL_t fKeyPresent = 0; + int i; + eHalStatus status = eHAL_STATUS_SUCCESS; + + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL ",__func__); + return -EINVAL; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + + keyId = encoderq->flags & IW_ENCODE_INDEX; + + if(keyId) + { + if(keyId > MAX_WEP_KEYS) + { + return -EINVAL; + } + + fKeyPresent = 1; + keyId--; + } + else + { + fKeyPresent = 0; + } + + + if(wrqu->data.flags & IW_ENCODE_DISABLED) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****iwconfig wlan0 key off*****"); + if(!fKeyPresent) { + + for(i=0;i < CSR_MAX_NUM_KEY; i++) { + + if(pWextState->roamProfile.Keys.KeyMaterial[i]) + pWextState->roamProfile.Keys.KeyLength[i] = 0; + } + } + pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + pWextState->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + + pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + + if(eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + INIT_COMPLETION(pAdapter->disconnect_comp_var); + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED ); + if(eHAL_STATUS_SUCCESS == status) + { + long ret; + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on disconnect_comp_var %ld"), ret); + } + } + + return status; + + } + + if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) + { + hddLog(VOS_TRACE_LEVEL_INFO, "iwconfig wlan0 key on"); + + pHddStaCtx->conn_info.authType = (encoderq->flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY : eCSR_AUTH_TYPE_OPEN_SYSTEM; + + } + + + if(wrqu->data.length > 0) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",__func__,wrqu->data.length); + + key_length = wrqu->data.length; + + /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued.*/ + + if(5 == key_length) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Call with WEP40,key_len=%d",__func__,key_length); + + if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP40; + } + else + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + } + else if(13 == key_length) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s:Call with WEP104,key_len:%d",__func__,key_length); + + if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)) + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP104; + } + else + { + encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + } + else + { + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Invalid WEP key length :%d", + __func__, key_length); + return -EINVAL; + } + + pHddStaCtx->conn_info.ucEncryptionType = encryptionType; + pHddStaCtx->conn_info.mcEncryptionType = encryptionType; + pWextState->roamProfile.EncryptionType.numEntries = 1; + pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType; + pWextState->roamProfile.mcEncryptionType.numEntries = 1; + pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType; + + if((eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) && + ((eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) || + (eCSR_AUTH_TYPE_SHARED_KEY == pHddStaCtx->conn_info.authType))) + { + + vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[keyId][0],extra,key_length); + + pWextState->roamProfile.Keys.KeyLength[keyId] = (v_U8_t)key_length; + pWextState->roamProfile.Keys.defaultIndex = (v_U8_t)keyId; + + return status; + } + } + EXIT(); + return 0; +} + +static int iw_set_encode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu,char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_encode(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_wext_state_t *pWextState; + tCsrRoamProfile *pRoamProfile; + int keyId; + eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE; + eCsrAuthType authType = eCSR_AUTH_TYPE_NONE; + int i, ret = 0; + hdd_context_t *pHddCtx; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + pRoamProfile = &(pWextState->roamProfile); + + keyId = pRoamProfile->Keys.defaultIndex; + + if(keyId < 0 || keyId >= MAX_WEP_KEYS) + { + hddLog(LOG1,"%s: Invalid keyId : %d",__func__,keyId); + return -EINVAL; + } + + if(pRoamProfile->Keys.KeyLength[keyId] > 0) + { + dwrq->flags |= IW_ENCODE_ENABLED; + dwrq->length = pRoamProfile->Keys.KeyLength[keyId]; + vos_mem_copy(extra, &(pRoamProfile->Keys.KeyMaterial[keyId][0]), + pRoamProfile->Keys.KeyLength[keyId]); + } + else + { + dwrq->flags |= IW_ENCODE_DISABLED; + } + + for(i=0; i < MAX_WEP_KEYS; i++) + { + if(pRoamProfile->Keys.KeyMaterial[i] == NULL) + { + continue; + } + else + { + break; + } + } + + if(MAX_WEP_KEYS == i) + { + dwrq->flags |= IW_ENCODE_NOKEY; + } + else + { + dwrq->flags |= IW_ENCODE_ENABLED; + } + + encryptionType = pRoamProfile->EncryptionType.encryptionType[0]; + + if(eCSR_ENCRYPT_TYPE_NONE == encryptionType) + { + dwrq->flags |= IW_ENCODE_DISABLED; + } + + authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType; + + if(IW_AUTH_ALG_OPEN_SYSTEM == authType) + { + dwrq->flags |= IW_ENCODE_OPEN; + } + else + { + dwrq->flags |= IW_ENCODE_RESTRICTED; + } + EXIT(); + return 0; + +} + +static int iw_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + int ret; + vos_ssr_protect(__func__); + ret = __iw_get_encodeext(dev, info, dwrq, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + hdd_wext_state_t *pWextState; + hdd_context_t *pHddCtx; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + tCsrRoamProfile *pRoamProfile; + v_U32_t status = 0; + + struct iw_encode_ext *ext = (struct iw_encode_ext*)extra; + + v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + int key_index; + struct iw_point *encoding = &wrqu->encoding; + tCsrRoamSetKey setKey; + v_U32_t roamId= 0xFF; + VOS_STATUS vos_status; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + pRoamProfile = &pWextState->roamProfile; + key_index = encoding->flags & IW_ENCODE_INDEX; + + if(key_index > 0) { + + /*Convert from 1-based to 0-based keying*/ + key_index--; + } + if(!ext->key_len) { + + /*Set the encrytion type to NONE*/ + pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + return status; + } + + if(eConnectionState_NotConnected == pHddStaCtx->conn_info.connState && + (IW_ENCODE_ALG_WEP == ext->alg)) + { + if(IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) { + + VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + ("Invalid Configuration:%s"),__func__); + return -EINVAL; + } + else { + /*Static wep, update the roam profile with the keys */ + if(ext->key && (ext->key_len <= eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES) && + key_index < CSR_MAX_NUM_KEY) { + vos_mem_copy(&pRoamProfile->Keys.KeyMaterial[key_index][0],ext->key,ext->key_len); + pRoamProfile->Keys.KeyLength[key_index] = (v_U8_t)ext->key_len; + + if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + pRoamProfile->Keys.defaultIndex = (v_U8_t)key_index; + + } + } + return status; + } + + vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey)); + + setKey.keyId = key_index; + setKey.keyLength = ext->key_len; + + if(ext->key_len <= CSR_MAX_KEY_LEN) { + vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len); + } + + if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /*Key direction for group is RX only*/ + setKey.keyDirection = eSIR_RX_ONLY; + vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN); + } + else { + + setKey.keyDirection = eSIR_TX_RX; + vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN); + } + + /*For supplicant pae role is zero*/ + setKey.paeRole = 0; + + switch(ext->alg) + { + case IW_ENCODE_ALG_NONE: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + + case IW_ENCODE_ALG_WEP: + setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104; + break; + + case IW_ENCODE_ALG_TKIP: + { + v_U8_t *pKey = &setKey.Key[0]; + + setKey.encType = eCSR_ENCRYPT_TYPE_TKIP; + + vos_mem_zero(pKey, CSR_MAX_KEY_LEN); + + /*Supplicant sends the 32bytes key in this order + + |--------------|----------|----------| + | Tk1 |TX-MIC | RX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + + */ + /*Sme expects the 32 bytes key to be in the below order + + |--------------|----------|----------| + | Tk1 |RX-MIC | TX Mic | + |--------------|----------|----------| + <---16bytes---><--8bytes--><--8bytes--> + */ + /* Copy the Temporal Key 1 (TK1) */ + vos_mem_copy(pKey,ext->key,16); + + /*Copy the rx mic first*/ + vos_mem_copy(&pKey[16],&ext->key[24],8); + + /*Copy the tx mic */ + vos_mem_copy(&pKey[24],&ext->key[16],8); + + } + break; + + case IW_ENCODE_ALG_CCMP: + setKey.encType = eCSR_ENCRYPT_TYPE_AES; + break; + +#ifdef FEATURE_WLAN_ESE +#define IW_ENCODE_ALG_KRK 6 + case IW_ENCODE_ALG_KRK: + setKey.encType = eCSR_ENCRYPT_TYPE_KRK; + break; +#endif /* FEATURE_WLAN_ESE */ + + default: + setKey.encType = eCSR_ENCRYPT_TYPE_NONE; + break; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d"),__func__,(int)ext->alg,(int)ext->key_len,setKey.encType); + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* The supplicant may attempt to set the PTK once pre-authentication + is done. Save the key in the UMAC and include it in the ADD + BSS request */ + halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey); + if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_INFO_MED, + "%s: Update PreAuth Key success", __func__); + return 0; + } + else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Update PreAuth Key failed", __func__); + return -EINVAL; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY; + + vos_status = wlan_hdd_check_ula_done(pAdapter); + if ( vos_status != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d", + __LINE__, vos_status ); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + + halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),pAdapter->sessionId, &setKey, &roamId ); + + if ( halStatus != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "[%4d] sme_RoamSetKey returned ERROR status= %d", + __LINE__, halStatus ); + + pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE; + } + EXIT(); + return halStatus; +} + +static int iw_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_encodeext(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if(wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN || + wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Invalid Retry-Limit=%d!!"),wrqu->retry.value); + + return -EINVAL; + } + + if(wrqu->retry.flags & IW_RETRY_LIMIT) { + + if((wrqu->retry.flags & IW_RETRY_LONG)) + { + if ( ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_LONG_RETRY_LIMIT")); + return -EIO; + } + } + else if((wrqu->retry.flags & IW_RETRY_SHORT)) + { + if ( ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_SHORT_RETRY_LIMIT")); + return -EIO; + } + } + } + else + { + return -EOPNOTSUPP; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Set Retry-Limit=%d!!"),wrqu->retry.value); + + EXIT(); + + return 0; + +} + +static int iw_set_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_retry(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tHalHandle hHal; + v_U32_t retry = 0; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + if((wrqu->retry.flags & IW_RETRY_LONG)) + { + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG; + + if ( ccmCfgGetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_LONG_RETRY_LIMIT")); + return -EIO; + } + + wrqu->retry.value = retry; + } + else if ((wrqu->retry.flags & IW_RETRY_SHORT)) + { + wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT; + + if ( ccmCfgGetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_SHORT_RETRY_LIMIT")); + return -EIO; + } + + wrqu->retry.value = retry; + } + else { + return -EOPNOTSUPP; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Retry-Limit=%d!!"),retry); + + EXIT(); + + return 0; +} + +static int iw_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_retry(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + struct iw_mlme *mlme = (struct iw_mlme *)extra; + eHalStatus status = eHAL_STATUS_SUCCESS; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:STA context is NULL",__func__); + return -EINVAL; + } + + //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED + switch (mlme->cmd) { + case IW_MLME_DISASSOC: + case IW_MLME_DEAUTH: + + if( pHddStaCtx->conn_info.connState == eConnectionState_Associated ) + { + eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED; + + if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE ) + reason = eCSR_DISCONNECT_REASON_MIC_ERROR; + + INIT_COMPLETION(pAdapter->disconnect_comp_var); + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,reason); + + if(eHAL_STATUS_SUCCESS == status) + { + long ret; + ret = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + if (ret <= 0) + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("failed wait on disconnect_comp_var %ld"), ret); + } + else + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d", + __func__, (int)mlme->cmd, (int)status ); + + /* Resetting authKeyMgmt */ + (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues")); + netif_tx_disable(dev); + netif_carrier_off(dev); + + } + else + { + hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state", __func__, (int)mlme->cmd ); + } + break; + default: + hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate", __func__, (int)mlme->cmd ); + return -EINVAL; + }//end of switch + + EXIT(); + + return status; + +} + +static int iw_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_mlme(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +int wlan_hdd_set_proximity(int set_value, tHalHandle hal) +{ + sHwCalValues hwCalValues; + uint16 hwCalTxPower; + uint8 txPwr = TX_PWR_DEF; + + hddLog(LOG1, FL("WE_SET_PROXIMITY_ENABLE: %d"), set_value); + + if (TRUE == set_value) { + if(vos_nv_read( VNV_HW_CAL_VALUES, &hwCalValues, + NULL, sizeof(sHwCalValues) ) + != VOS_STATUS_SUCCESS) { + return -EINVAL; + } + hwCalTxPower = (uint16)(hwCalValues.calData.hwParam7 >> 16); + + hddLog(LOG1, FL("hwCalTxPower:%x nv_data:%x"), + hwCalTxPower, hwCalValues.calData.hwParam7); + + txPwr = (int8)(hwCalTxPower & 0x00FF); + txPwr = txPwr/10; + if (txPwr == 0) + txPwr = TX_PWR_DEF; + else if (txPwr < TX_PWR_MIN) + txPwr = TX_PWR_MIN; + else if (txPwr > TX_PWR_MAX) + txPwr = TX_PWR_MAX; + + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, txPwr, hal) != + eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Setting tx power failed for 2.4GHz band %d"), txPwr); + return -EIO; + } + + txPwr = (int8)((hwCalTxPower >> 8) & 0x00FF); + txPwr /= 10; + if (txPwr == 0) + txPwr = TX_PWR_DEF; + else if (txPwr < TX_PWR_MIN) + txPwr = TX_PWR_MIN; + else if (txPwr > TX_PWR_MAX) + txPwr = TX_PWR_MAX; + + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, txPwr, hal) != + eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("setting tx power failed for 5GHz band %d"), txPwr); + return -EIO; + } + } + else if(FALSE == set_value) { + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, txPwr, hal) != + eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Setting tx power failed for 2.4GHz band %d"), txPwr); + return -EIO; + } + + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, txPwr, hal) != + eHAL_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("setting tx power failed for 5GHz band %d"), txPwr); + return -EIO; + } + } + else { + return -EINVAL; + } + + return eHAL_STATUS_SUCCESS; +} + +static int hdd_set_dynamic_aggregation(int value, hdd_adapter_t *adapter) +{ + int ret = 0; + tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter); + tDelBaParams del_session; + + del_session.session_id = adapter->sessionId; + hddLog(LOG1, FL("WLAN_SET_DYNNAMIC_AGGREGATION: %d"), value); + + if ((value == DISABLE_AGGREGATION) || (value == ENABLE_AGGREGATION)) + { + ret = ccmCfgSetInt(hal, WNI_CFG_ENABLE_TX_RX_AGGREGATION, + value,NULL, eANI_BOOLEAN_FALSE); + if (ret != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_ENABLE_TX_RX_AGGREGATION")); + return -EIO; + } + + } else { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Invalid command input")); + return -EINVAL; + } + ret = sme_del_sta_ba_session_req(hal, del_session); + if (ret != VOS_STATUS_SUCCESS) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("send ba session req fail")); + return -EINVAL; + } + + EXIT(); + return ret; +} + +/* set param sub-ioctls */ +static int __iw_setint_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal = NULL; + hdd_wext_state_t *pWextState; + hdd_context_t *pHddCtx; + hdd_mon_ctx_t *pMonCtx = NULL; + int *value = (int *)extra; + int sub_cmd = value[0]; + int set_value = value[1]; + int ret = 0; /* success */ + int enable_pbm, enable_mp; +#ifdef CONFIG_HAS_EARLYSUSPEND + v_U8_t nEnableSuspendOld; +#endif + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + if ( VOS_MONITOR_MODE != hdd_get_conparam()) + { + /* In monitor mode hHal is NULL */ + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + INIT_COMPLETION(pWextState->completion_var); + } + switch(sub_cmd) + { + case WE_SET_11D_STATE: + { + tSmeConfigParams smeConfig; + memset(&smeConfig, 0x00, sizeof(smeConfig)); + + if(((ENABLE_11D == set_value) || (DISABLE_11D == set_value)) && + (hHal)) { + sme_GetConfigParam(hHal,&smeConfig); + smeConfig.csrConfig.Is11dSupportEnabled = (v_BOOL_t)set_value; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%d!!"),smeConfig.csrConfig.Is11dSupportEnabled); + + sme_UpdateConfig(hHal,&smeConfig); + } + else { + return -EINVAL; + } + break; + } + + case WE_WOWL: + { + switch (set_value) + { + case 0x00: + hdd_exit_wowl(pAdapter, eWOWL_EXIT_USER); + break; + case 0x01: + case 0x02: + case 0x03: + enable_mp = (set_value & 0x01) ? 1 : 0; + enable_pbm = (set_value & 0x02) ? 1 : 0; + hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s", + (enable_mp ? "YES":"NO"), (enable_pbm ? "YES":"NO")); + hdd_enter_wowl(pAdapter, enable_mp, enable_pbm); + break; + default: + hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL", set_value); + ret = -EINVAL; + break; + } + + break; + } + case WE_SET_POWER: + { + switch (set_value) + { + case 0: //Full Power + { + struct statsContext context; + eHalStatus status = eHAL_STATUS_FAILURE; + + init_completion(&context.completion); + + context.pAdapter = pAdapter; + context.magic = POWER_CONTEXT_MAGIC; + + if (NULL == hHal) + return -EINVAL; + + status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context, + eSME_FULL_PWR_NEEDED_BY_HDD); + + if (eHAL_STATUS_PMC_PENDING == status) + { + int lrc = wait_for_completion_interruptible_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while requesting fullpower", + __func__, (0 == lrc) ? + "timeout" : "interrupt"); + } + } + /* either we have a response or we timed out. if we timed + out there is a race condition such that the callback + function could be executing at the same time we are. of + primary concern is if the callback function had already + verified the "magic" but had not yet set the completion + variable when a timeout occurred. we serialize these + activities by invalidating the magic while holding a + shared spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + hddLog(LOGE, "iwpriv Full Power completed"); + break; + } + case 1: //Enable BMPS + if (hHal) + sme_EnablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE); + else + ret = -EINVAL; + break; + case 2: //Disable BMPS + if (hHal) + sme_DisablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE); + else + ret = -EINVAL; + break; + case 3: //Request Bmps + { + struct statsContext context; + eHalStatus status = eHAL_STATUS_FAILURE; + + init_completion(&context.completion); + + context.pAdapter = pAdapter; + context.magic = POWER_CONTEXT_MAGIC; + + if (NULL == hHal) + return -EINVAL; + + status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter), + iw_power_callback_fn, &context); + if (eHAL_STATUS_PMC_PENDING == status) + { + int lrc = wait_for_completion_interruptible_timeout( + &context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_POWER)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME %s while requesting BMPS", + __func__, (0 == lrc) ? "timeout" : + "interrupt"); + } + } + /* either we have a response or we timed out. if we + timed out there is a race condition such that the + callback function could be executing at the same + time we are. of primary concern is if the callback + function had already verified the "magic" but had + not yet set the completion variable when a timeout + occurred. we serialize these activities by + invalidating the magic while holding a shared + spinlock which will cause us to block if the + callback is currently executing */ + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + hddLog(LOGE, "iwpriv Request BMPS completed"); + break; + } + case 4: //Enable IMPS + if (hHal) + sme_EnablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE); + else + ret = -EINVAL; + break; + case 5: //Disable IMPS + if (hHal) + sme_DisablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE); + else + ret = -EINVAL; + break; + case 6: //Enable Standby + if (hHal) + sme_EnablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE); + else + ret = -EINVAL; + break; + case 7: //Disable Standby + if (hHal) + sme_DisablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE); + else + ret = -EINVAL; + break; + case 8: //Request Standby +#ifdef CONFIG_HAS_EARLYSUSPEND +#endif + break; + case 9: //Start Auto Bmps Timer + if (hHal) + sme_StartAutoBmpsTimer(hHal); + else + ret = -EINVAL; + break; + case 10://Stop Auto BMPS Timer + if (hHal) + sme_StopAutoBmpsTimer(hHal); + else + ret = -EINVAL; + break; +#ifdef CONFIG_HAS_EARLYSUSPEND + case 11://suspend to standby +#ifdef CONFIG_HAS_EARLYSUSPEND + nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 1; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld; +#endif + break; + case 12://suspend to deep sleep +#ifdef CONFIG_HAS_EARLYSUSPEND + nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 2; + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld; +#endif + break; + case 13://resume from suspend +#ifdef CONFIG_HAS_EARLYSUSPEND +#endif + break; +#endif + default: + hddLog(LOGE, "Invalid arg %d in WE_SET_POWER IOCTL", set_value); + ret = -EINVAL; + break; + } + break; + } + + case WE_SET_MAX_ASSOC: + { + if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) || + (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) || + (NULL == hHal)) + { + ret = -EINVAL; + } + else if ( ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, + set_value, NULL, eANI_BOOLEAN_FALSE) + != eHAL_STATUS_SUCCESS ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to set ini parameter, WNI_CFG_ASSOC_STA_LIMIT")); + ret = -EIO; + } + break; + } + + case WE_SET_SAP_AUTO_CHANNEL_SELECTION: + { + if( 0 == set_value ) + { + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection = 0; + } + else if ( 1 == set_value ) + { + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection = 1; + } + else + { + hddLog(LOGE, "Invalid arg %d in WE_SET_SAP_AUTO_CHANNEL_SELECTION IOCTL", set_value); + ret = -EINVAL; + } + break; + } + + case WE_SET_DATA_INACTIVITY_TO: + { + if (NULL == hHal) + return -EINVAL; + + if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) || + (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) || + (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal, + WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, + set_value, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)) + { + hddLog(LOGE,"Failure: Could not pass on " + "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info " + "to CCM"); + ret = -EINVAL; + } + break; + } + case WE_SET_MAX_TX_POWER: + { + tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + + if (NULL == hHal) + return -EINVAL; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Setting maximum tx power %d dBm", + __func__, set_value); + if( sme_SetMaxTxPower(hHal, bssid, selfMac, set_value) != + eHAL_STATUS_SUCCESS ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed", + __func__); + return -EIO; + } + + break; + } + case WE_SET_MAX_TX_POWER_2_4: + { + if (NULL == hHal) + return -EINVAL; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Setting maximum tx power %d dBm for 2.4 GHz band", + __func__, set_value); + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_24, set_value, hHal) != + eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Setting maximum tx power failed for 2.4 GHz band", + __func__); + return -EIO; + } + + break; + } + case WE_SET_MAX_TX_POWER_5_0: + { + if (NULL == hHal) + return -EINVAL; + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Setting maximum tx power %d dBm for 5.0 GHz band", + __func__, set_value); + if (sme_SetMaxTxPowerPerBand(eCSR_BAND_5G, set_value, hHal) != + eHAL_STATUS_SUCCESS) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Setting maximum tx power failed for 5.0 GHz band", + __func__); + return -EIO; + } + + break; + } + case WE_SET_HIGHER_DTIM_TRANSITION: + { + if(!((set_value == eANI_BOOLEAN_FALSE) || + (set_value == eANI_BOOLEAN_TRUE))) + { + hddLog(LOGE, "Dynamic DTIM Incorrect data:%d", set_value); + ret = -EINVAL; + } + else + { + if(pAdapter->higherDtimTransition != set_value) + { + pAdapter->higherDtimTransition = set_value; + hddLog(LOG1, "%s: higherDtimTransition set to :%d", __func__, pAdapter->higherDtimTransition); + } + } + + break; + } + + case WE_SET_TM_LEVEL: + { + hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter); + hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d", (int)set_value); + hddDevTmLevelChangedHandler(hddCtxt->parent_dev, set_value); + + break; + } + + case WE_ENABLE_STRICT_FCC_REG: + { + hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter); + struct wiphy *wiphy = NULL; + long lrc; + int status; + + wiphy = hddCtxt->wiphy; + if(wiphy == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy is NULL ", __func__); + break; + } + init_completion(&hddCtxt->wiphy_channel_update_event); + + hddCtxt->nEnableStrictRegulatoryForFCC = set_value; + + status = regulatory_hint(wiphy, "00"); + if(status < 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Failure in setting regulatory rule ", __func__); + break; + } + + /* Wait for completion */ + lrc = wait_for_completion_interruptible_timeout(&hddCtxt->wiphy_channel_update_event, + msecs_to_jiffies(WLAN_WAIT_TIME_CHANNEL_UPDATE)); + if (lrc <= 0) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while setting strict FCC regulatory rule ", + __func__, (0 == lrc) ? "Timeout" : "Interrupt"); + return (0 == lrc) ? -ETIMEDOUT : -EINTR; + } + hddLog(VOS_TRACE_LEVEL_INFO,"%s: SUCCESS in setting strict FCC regulatory rule", __func__); + + break; + } + case WE_SET_DEBUG_LOG: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + pHddCtx->cfg_ini->gEnableDebugLog = set_value; + if (hHal) + sme_UpdateConnectDebug(pHddCtx->hHal, set_value); + else + ret = -1; + break; + } +#ifdef FEATURE_WLAN_TDLS + case WE_SET_TDLS_OFF_CHAN: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Tdls offchannel num %d", + __func__, set_value); + ret = iw_set_tdlsoffchannel(pHddCtx, set_value); + break; + } + case WE_SET_TDLS_SEC_OFF_CHAN_OFFSET: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Tdls sec offchan offset %d", + __func__, set_value); + ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value); + break; + } + case WE_SET_TDLS_OFF_CHAN_MODE: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Tdls offchannel mode %d", + __func__, set_value); + ret = iw_set_tdlsoffchannelmode(pAdapter, set_value); + break; + } +#endif + case WE_SET_SCAN_BAND_PREFERENCE: + { + tSmeConfigParams smeConfig; + memset(&smeConfig, 0x00, sizeof(smeConfig)); + if(pAdapter->device_mode != WLAN_HDD_INFRA_STATION) { + ret = -EINVAL; + break; + } + hddLog(LOG1, "WE_SET_BAND_PREFERRENCE val %d ", set_value); + + if ((eCSR_BAND_ALL == set_value || + eCSR_BAND_24 == set_value || eCSR_BAND_5G == set_value) && + (hHal)) { + sme_GetConfigParam(hHal, &smeConfig); + smeConfig.csrConfig.scanBandPreference = set_value; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "set band scan preference = %d\n", + smeConfig.csrConfig.scanBandPreference); + + sme_UpdateConfig(hHal, &smeConfig); + } + else { + ret = -EINVAL; + } + break; + } + /* The WE_SET_MIRACAST_VENDOR_CONFIG IOCTL should be set before the + * connection happens so that the params can take effect during + * association. Also this should not be used in STA+p2p concurrency + * as the param will also effect the STA mode. + */ + case WE_SET_MIRACAST_VENDOR_CONFIG: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + hddLog(LOG1, FL( + "Set Miracast vendor tuning %d"), set_value); + + if (NULL == hHal) + return -EINVAL; + + if (1 == set_value || 0 == set_value) + { + if (eHAL_STATUS_SUCCESS != sme_SetMiracastVendorConfig(pHddCtx->hHal, + pHddCtx->cfg_ini->numBuffAdvert, set_value)) + { + hddLog( LOGE, FL("set vendor miracast config failed")); + ret = -EIO; + } + } + else + { + hddLog(LOGE, + FL("Invalid value %d in WE_SET_MIRACAST_VENDOR_CONFIG IOCTL"), set_value); + ret = -EINVAL; + } + break; + } + + case WE_GET_FRAME_LOG: + { + if (wlan_hdd_get_frame_logs(pAdapter, set_value) + != VOS_STATUS_SUCCESS) + { + ret = -EINVAL; + } + break; + } + + case WE_SET_TDLS_2040_BSS_COEXISTENCE: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: TDLS_2040_BSS_COEXISTENCE %d", __func__, set_value); + if ((set_value == 0 || set_value == 1) && (hHal)) + { + sme_SetTdls2040BSSCoexistence(WLAN_HDD_GET_HAL_CTX(pAdapter), + set_value); + } + else + ret = -EINVAL; + + break; + } + /* Bit mask value to enable RTS/CTS for different modes + * for 2.4 GHz, HT20 - 0x0001, for 2.4 GHz, HT40 - 0x0002 + * for 2.4 GHz, VHT20 - 0x0004, for 2.4 GHz, VHT40 - 0x0008 + * for 5 GHz, HT20 - 0x0100, for 5 GHz, HT40 - 0x0200 + * for 5 GHz, VHT20 - 0x0400, for 5 GHz, VHT40 - 0x0800 + * for 5 GHz, VHT80 - 0x1000 + */ + case WE_SET_RTS_CTS_HTVHT: + { + + hddLog( LOG1, FL("WE_SET_RTS_CTS_HTVHT set value %d"), set_value); + + if (NULL == hHal) + return -EINVAL; + + if (eHAL_STATUS_SUCCESS != + sme_SetRtsCtsHtVht( pHddCtx->hHal, set_value)) + { + hddLog( LOGE, FL("set WE_SET_RTS_CTS_HTVHT failed")); + ret = -EINVAL; + } + break; + } + case WE_SET_MONITOR_STATE: + { + v_U32_t magic = 0; + struct completion cmpVar; + long waitRet = 0; + tVOS_CON_MODE mode = hdd_get_conparam(); + + if( VOS_MONITOR_MODE != mode) + { + hddLog(LOGE, "invalid mode %d", mode); + ret = -EIO; + break; + } + + pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter); + if( pMonCtx == NULL ) + { + hddLog(LOGE, "Monitor Context NULL"); + ret = -EIO; + break; + } + if (pMonCtx->state == set_value) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("already in same mode curr_mode:%d req_mode: %d"), + pMonCtx->state, set_value); + break; + } + pMonCtx->state = set_value; + magic = MON_MODE_MSG_MAGIC; + init_completion(&cmpVar); + if (VOS_STATUS_SUCCESS != + wlan_hdd_mon_postMsg(&magic, &cmpVar, + pMonCtx, hdd_monPostMsgCb)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to post MON MODE REQ")); + pMonCtx->state = (pMonCtx->state==MON_MODE_START)? + MON_MODE_STOP : MON_MODE_START; + magic = 0; + ret = -EIO; + break; + } + waitRet = wait_for_completion_timeout(&cmpVar, MON_MODE_MSG_TIMEOUT); + magic = 0; + if (waitRet <= 0 ){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to wait on monitor mode completion %ld"), + waitRet); + } + break; + } + case WE_SET_PKT_STATS_ENABLE_DISABLE: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tAniWifiStartLog start_log; + if (!pHddCtx->cfg_ini->wlanPerPktStatsLogEnable || + !vos_isPktStatsEnabled()) + { + hddLog(LOGE, FL("per pkt stats not enabled")); + return -EINVAL; + } + hddLog(LOG1, FL("Set Pkt Stats %d"), set_value); + + if (1 == set_value || 0 == set_value) + { + start_log.ringId = RING_ID_PER_PACKET_STATS; + start_log.flag = 0; + if (set_value) + start_log.verboseLevel = WLAN_LOG_LEVEL_ACTIVE; + else + start_log.verboseLevel = WLAN_LOG_LEVEL_OFF; + + vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel); + } + else + { + hddLog(LOGE, + FL("Invalid value %d in WE_SET_PKT_STATS_ENABLE_DISABLE IOCTL"), + set_value); + ret = -EINVAL; + } + break; + } + case WE_SET_PROXIMITY_ENABLE: + { + if (NULL == hHal) + return -EINVAL; + + ret = wlan_hdd_set_proximity(set_value, hHal); + break; + } + case WE_CAP_TSF: + { + if (NULL == hHal) + return -EINVAL; + + ret = hdd_capture_tsf(pAdapter, (uint32_t *)&set_value, 1); + break; + } + case WE_SET_MODULATED_DTIM: + { + if ((set_value < CFG_ENABLE_MODULATED_DTIM_MIN) || + (set_value > CFG_ENABLE_MODULATED_DTIM_MAX)) { + hddLog(LOGE, FL("Invalid value %d in gEnableModuleDTIM"), + set_value); + return -EINVAL; + } else { + ret = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini-> + enableModulatedDTIM = set_value; + } + } + case WLAN_SET_DYNNAMIC_AGGREGATION: + { + if (NULL == hHal) + return -EINVAL; + + ret = hdd_set_dynamic_aggregation(set_value, pAdapter); + break; + } + default: + { + hddLog(LOGE, "Invalid IOCTL setvalue command %d value %d", + sub_cmd, set_value); + break; + } + } + EXIT(); + return ret; +} + +static int iw_setint_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_setint_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return 0; +} +/* set param sub-ioctls */ +static int __iw_setchar_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + VOS_STATUS vstatus; + int sub_cmd; + int ret = 0; /* success */ + char *pBuffer = NULL; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; +#ifdef WLAN_FEATURE_VOWIFI + hdd_config_t *pConfig; +#endif /* WLAN_FEATURE_VOWIFI */ + struct iw_point s_priv_data; + tSirpkt80211 *pkt; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pAdapter = (netdev_priv(dev)); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } +#ifdef WLAN_FEATURE_VOWIFI + pConfig = pHddCtx->cfg_ini; +#endif + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) + { + return -EINVAL; + } + + /* make sure all params are correctly passed to function */ + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) + { + return -EINVAL; + } + + sub_cmd = s_priv_data.flags; + + /* ODD number is used for set, copy data using copy_from_user */ + pBuffer = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); + if (NULL == pBuffer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received length %d", __func__, s_priv_data.length); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Received data %s", __func__, pBuffer); + + switch(sub_cmd) + { + case WE_WOWL_ADD_PTRN: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN"); + hdd_add_wowl_ptrn(pAdapter, pBuffer); + break; + case WE_WOWL_DEL_PTRN: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN"); + hdd_del_wowl_ptrn(pAdapter, pBuffer); + break; +#if defined WLAN_FEATURE_VOWIFI + case WE_NEIGHBOR_REPORT_REQUEST: + { + tRrmNeighborReq neighborReq; + tRrmNeighborRspCallbackInfo callbackInfo; + + if (pConfig->fRrmEnable) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Neighbor Request"); + neighborReq.no_ssid = (s_priv_data.length - 1) ? false : true ; + if( !neighborReq.no_ssid ) + { + neighborReq.ssid.length = (s_priv_data.length - 1) > 32 ? 32 : (s_priv_data.length - 1) ; + vos_mem_copy( neighborReq.ssid.ssId, pBuffer, neighborReq.ssid.length ); + } + + callbackInfo.neighborRspCallback = NULL; + callbackInfo.neighborRspCallbackContext = NULL; + callbackInfo.timeout = 5000; //5 seconds + sme_NeighborReportRequest( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &neighborReq, &callbackInfo ); + } + else + { + hddLog(LOGE, "%s: Ignoring neighbor request as RRM is not enabled", __func__); + ret = -EINVAL; + } + } + break; +#endif + case WE_SET_AP_WPS_IE: + hddLog( LOGE, "Received WE_SET_AP_WPS_IE" ); + sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), pBuffer, s_priv_data.length ); + break; + case WE_SET_CONFIG: + vstatus = hdd_execute_config_command(pHddCtx, pBuffer); + if (VOS_STATUS_SUCCESS != vstatus) + { + ret = -EINVAL; + } + break; + case WE_SET_ENCRYPT_MSG: + pkt = vos_mem_malloc(sizeof(tSirpkt80211)); + if (NULL == pkt) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + ret = -ENOMEM; + break; + } + + memset(pkt, 0, sizeof(tSirpkt80211)); + + if (FALSE == sme_IsFeatureSupportedByFW(DISA)) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Firmware is not DISA capable")); + ret = -EINVAL; + vos_mem_free(pkt); + break; + } + + parse_Bufferforpkt(pkt, pBuffer, wrqu->data.length); + + ret = sme_Encryptmsgsend(pHddCtx->hHal, (u8 *)pkt, + sizeof(tSirpkt80211), hdd_encrypt_msg_cb); + if (eHAL_STATUS_SUCCESS != ret) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SENDEncryptMSG: fail to post WDA cmd")); + ret = -EINVAL; + } + vos_mem_free(pkt); + + break; + + default: + { + hddLog(LOGE, "%s: Invalid sub command %d",__func__, sub_cmd); + ret = -EINVAL; + break; + } + } + kfree(pBuffer); + + EXIT(); + return ret; +} + +static int iw_setchar_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_setchar_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static void hdd_GetCurrentAntennaIndex(int antennaId, void *pContext) +{ + struct statsContext *context; + hdd_adapter_t *pAdapter; + + if (NULL == pContext) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Bad param, pContext [%p]", + __func__, pContext); + return; + } + + context = pContext; + pAdapter = context->pAdapter; + + spin_lock(&hdd_context_lock); + + if ((NULL == pAdapter) || (ANTENNA_CONTEXT_MAGIC != context->magic)) + { + /* the caller presumably timed out so there is nothing we can do */ + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter [%p] magic [%08x]", + __func__, pAdapter, context->magic); + return; + } + + context->magic = 0; + pAdapter->antennaIndex = antennaId; + + complete(&context->completion); + spin_unlock(&hdd_context_lock); +} + +static VOS_STATUS wlan_hdd_get_current_antenna_index(hdd_adapter_t *pAdapter, + int *antennaIndex) +{ + hdd_context_t *pHddCtx; + eHalStatus halStatus; + struct statsContext context; + long lrc; + + ENTER(); + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_WARN, + "%s: Invalid context, pAdapter", __func__); + return VOS_STATUS_E_FAULT; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return VOS_STATUS_E_FAULT; + } + if (TRUE != sme_IsFeatureSupportedByFW(ANTENNA_DIVERSITY_SELECTION)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: ANTENNA_DIVERSITY_SELECTION is not supported by Firwmare", + __func__); + return VOS_STATUS_E_NOSUPPORT; + } + init_completion(&context.completion); + context.pAdapter = pAdapter; + context.magic = ANTENNA_CONTEXT_MAGIC; + + halStatus = sme_GetCurrentAntennaIndex(pHddCtx->hHal, + hdd_GetCurrentAntennaIndex, + &context, pAdapter->sessionId); + if (eHAL_STATUS_SUCCESS != halStatus) + { + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve Antenna Index", + __func__); + /* we'll returned a cached value below */ + *antennaIndex = -1; + return VOS_STATUS_E_FAILURE; + } + else + { + /* request was sent -- wait for the response */ + lrc = wait_for_completion_interruptible_timeout(&context.completion, + msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); + if (lrc <= 0) + { + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:SME %s while retrieving Antenna" + " Index", + __func__, (0 == lrc) ? "timeout" : "interrupt"); + *antennaIndex = -1; + return VOS_STATUS_E_FAILURE; + } + } + spin_lock(&hdd_context_lock); + context.magic = 0; + spin_unlock(&hdd_context_lock); + + *antennaIndex = pAdapter->antennaIndex; + + EXIT(); + return VOS_STATUS_SUCCESS; +} + +/* get param sub-ioctls */ +static int __iw_setnone_getint(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int ret = 0; /* success */ + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + + switch (value[0]) + { + case WE_GET_11D_STATE: + { + tSmeConfigParams smeConfig; + sme_GetConfigParam(hHal,&smeConfig); + + *value = smeConfig.csrConfig.Is11dSupportEnabled; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%d!!"),*value); + + break; + } + + case WE_IBSS_STATUS: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****Return IBSS Status*****"); + break; + + case WE_PMC_STATE: + { + *value = pmcGetPmcState(hHal); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("PMC state=%d!!"),*value); + break; + } + case WE_GET_WLAN_DBG: + { + vos_trace_display(); + *value = 0; + break; + } + case WE_GET_MAX_ASSOC: + { + if (ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value) != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("failed to get ini parameter, WNI_CFG_ASSOC_STA_LIMIT")); + ret = -EIO; + } +#ifdef WLAN_SOFTAP_VSTA_FEATURE + if (pHddCtx->cfg_ini->fEnableVSTASupport) + { + if (*value > VSTA_NUM_ASSOC_STA) + { + *value = VSTA_NUM_ASSOC_STA; + } + if ((pHddCtx->hddAdapters.count > VSTA_NUM_RESV_SELFSTA) && + (*value > (VSTA_NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA)))) + { + *value = (VSTA_NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - VSTA_NUM_RESV_SELFSTA)); + } + } + else +#endif + { + if (*value > NUM_ASSOC_STA) + { + *value = NUM_ASSOC_STA; + } + if ((pHddCtx->hddAdapters.count > NUM_RESV_SELFSTA) && + (*value > (NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA)))) + { + *value = (NUM_ASSOC_STA - + (pHddCtx->hddAdapters.count - NUM_RESV_SELFSTA)); + } + } + break; + } + + case WE_GET_WDI_DBG: + { + wpalTraceDisplay(); + *value = 0; + break; + } + + case WE_GET_SAP_AUTO_CHANNEL_SELECTION: + { + *value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection; + break; + } + case WE_GET_CONCURRENCY_MODE: + { + *value = hdd_get_concurrency_mode ( ); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("concurrency mode=%d"),*value); + break; + } + + case WE_GET_SCAN_BAND_PREFERENCE: + { + tSmeConfigParams smeConfig; + sme_GetConfigParam(hHal, &smeConfig); + *value = smeConfig.csrConfig.scanBandPreference; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "scanBandPreference = %d\n", *value); + break; + } + case WE_GET_ANTENA_DIVERSITY_SELECTION: + { + wlan_hdd_get_current_antenna_index(pAdapter, value); + break; + } + default: + { + hddLog(LOGE, "Invalid IOCTL get_value command %d ",value[0]); + break; + } + } + EXIT(); + return ret; +} + +static int iw_setnone_getint(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_setnone_getint(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; + +} +/* set param sub-ioctls */ +int __iw_set_three_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int *value = (int *)extra; + int sub_cmd = value[0]; + int ret = 0; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + switch(sub_cmd) + { + case WE_SET_WLAN_DBG: + { + vos_trace_setValue( value[1], value[2], value[3]); + break; + } + case WE_SET_WDI_DBG: + { + wpalTraceSetLevel( value[1], value[2], value[3]); + break; + } + case WE_SET_SAP_CHANNELS: + { + ret = iw_softap_set_channel_range( dev, value[1], value[2], value[3]); + break; + } + + default: + { + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd ); + break; + } + } + EXIT(); + return ret; +} + +int iw_set_three_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_three_ints_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_get_char_setnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + int sub_cmd = wrqu->data.flags; + hdd_context_t *pHddCtx; + int ret = 0; +#ifdef WLAN_FEATURE_11W + hdd_wext_state_t *pWextState; +#endif + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (pAdapter == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL!", __func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } +#ifdef WLAN_FEATURE_11W + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } +#endif + + switch(sub_cmd) + { + case WE_WLAN_VERSION: + { + hdd_wlan_get_version(pAdapter, wrqu, extra); + break; + } + + case WE_GET_STATS: + { + tHalHandle hHal = NULL; + tpAniSirGlobal pMac = NULL; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats; + hdd_chip_reset_stats_t *pResetStats = &pHddCtx->hddChipResetStats; + hdd_arp_stats_t *parpStats = &pAdapter->hdd_stats.hddArpStats; + + + snprintf(extra, WE_MAX_STR_LEN, + "\nTransmit" + "\ncalled %u, dropped %u, backpressured %u, queued %u" + "\n dropped BK %u, BE %u, VI %u, VO %u" + "\n classified BK %u, BE %u, VI %u, VO %u" + "\nbackpressured BK %u, BE %u, VI %u, VO %u" + "\n queued BK %u, BE %u, VI %u, VO %u" + "\nfetched %u, empty %u, lowres %u, deqerr %u" + "\ndequeued %u, depressured %u, deque-depressured %u, completed %u, flushed %u" + "\n fetched BK %u, BE %u, VI %u, VO %u" + "\n dequeued BK %u, BE %u, VI %u, VO %u" + "\n depressured BK %u, BE %u, VI %u, VO %u" + "\nDeque depressured BK %u, BE %u, VI %u, VO %u" + "\n flushed BK %u, BE %u, VI %u, VO %u" + "\n\nReceive" + "\nchains %u, packets %u, dropped %u, delivered %u, refused %u" + "\n\nResetsStats" + "\n TotalLogp %u Cmd53 %u MutexRead %u MIF-Error %u FW-Heartbeat %u Others %u" + "\n" + "\n\nARP Transmit" + "\nTransmit Count %u, dropped %u" + "\n\nARP Receive" + "\nReceive Count %u, dropped %u, Delivered %u, Refused %u, Drop Reason %u" + "\n", + pStats->txXmitCalled, + pStats->txXmitDropped, + pStats->txXmitBackPressured, + pStats->txXmitQueued, + + pStats->txXmitDroppedAC[WLANTL_AC_BK], + pStats->txXmitDroppedAC[WLANTL_AC_BE], + pStats->txXmitDroppedAC[WLANTL_AC_VI], + pStats->txXmitDroppedAC[WLANTL_AC_VO], + + pStats->txXmitClassifiedAC[WLANTL_AC_BK], + pStats->txXmitClassifiedAC[WLANTL_AC_BE], + pStats->txXmitClassifiedAC[WLANTL_AC_VI], + pStats->txXmitClassifiedAC[WLANTL_AC_VO], + + pStats->txXmitBackPressuredAC[WLANTL_AC_BK], + pStats->txXmitBackPressuredAC[WLANTL_AC_BE], + pStats->txXmitBackPressuredAC[WLANTL_AC_VI], + pStats->txXmitBackPressuredAC[WLANTL_AC_VO], + + pStats->txXmitQueuedAC[WLANTL_AC_BK], + pStats->txXmitQueuedAC[WLANTL_AC_BE], + pStats->txXmitQueuedAC[WLANTL_AC_VI], + pStats->txXmitQueuedAC[WLANTL_AC_VO], + + pStats->txFetched, + pStats->txFetchEmpty, + pStats->txFetchLowResources, + pStats->txFetchDequeueError, + + pStats->txFetchDequeued, + pStats->txFetchDePressured, + pStats->txDequeDePressured, + pStats->txCompleted, + pStats->txFlushed, + + pStats->txFetchedAC[WLANTL_AC_BK], + pStats->txFetchedAC[WLANTL_AC_BE], + pStats->txFetchedAC[WLANTL_AC_VI], + pStats->txFetchedAC[WLANTL_AC_VO], + + pStats->txFetchDequeuedAC[WLANTL_AC_BK], + pStats->txFetchDequeuedAC[WLANTL_AC_BE], + pStats->txFetchDequeuedAC[WLANTL_AC_VI], + pStats->txFetchDequeuedAC[WLANTL_AC_VO], + + pStats->txFetchDePressuredAC[WLANTL_AC_BK], + pStats->txFetchDePressuredAC[WLANTL_AC_BE], + pStats->txFetchDePressuredAC[WLANTL_AC_VI], + pStats->txFetchDePressuredAC[WLANTL_AC_VO], + + pStats->txDequeDePressuredAC[WLANTL_AC_BK], + pStats->txDequeDePressuredAC[WLANTL_AC_BE], + pStats->txDequeDePressuredAC[WLANTL_AC_VI], + pStats->txDequeDePressuredAC[WLANTL_AC_VO], + + pStats->txFlushedAC[WLANTL_AC_BK], + pStats->txFlushedAC[WLANTL_AC_BE], + pStats->txFlushedAC[WLANTL_AC_VI], + pStats->txFlushedAC[WLANTL_AC_VO], + + pStats->rxChains, + pStats->rxPackets, + pStats->rxDropped, + pStats->rxDelivered, + pStats->rxRefused, + + pResetStats->totalLogpResets, + pResetStats->totalCMD53Failures, + pResetStats->totalMutexReadFailures, + pResetStats->totalMIFErrorFailures, + pResetStats->totalFWHearbeatFailures, + pResetStats->totalUnknownExceptions, + + parpStats->txCount, + parpStats->txDropped, + + parpStats->rxCount, + parpStats->rxDropped, + parpStats->rxDelivered, + parpStats->rxRefused, + parpStats->reason + ); + wrqu->data.length = strlen(extra); + + hHal = WLAN_HDD_GET_HAL_CTX( pAdapter ); + + if (hHal) + pMac = PMAC_STRUCT( hHal ); + + if (pMac && (wrqu->data.length < WE_MAX_STR_LEN)) { + __u32 pmmStatsLength = WE_MAX_STR_LEN - wrqu->data.length; + snprintf(extra+wrqu->data.length, pmmStatsLength, + "\n BMPS sleepcnt %lld, BMPS awakecnt %lld" + "\n BMPS sleepreqfailcnt %lld, BMPS wakeupreqfailcnt %lld" + "\n IMPS sleepcnt %lld, IMPS awakecnt %lld" + "\n IMPS sleepreqfailcnt %lld, IMPS wakeupreqfailcnt %lld, IMPS lasterr %lld" + "\n", + pMac->pmm.BmpscntSleep, + pMac->pmm.BmpscntAwake, + pMac->pmm.BmpsSleeReqFailCnt, + pMac->pmm.BmpsWakeupReqFailCnt, + pMac->pmm.ImpsCntSleep, + pMac->pmm.ImpsCntAwake, + pMac->pmm.ImpsSleepErrCnt, + pMac->pmm.ImpsWakeupErrCnt, + pMac->pmm.ImpsLastErr + ); + } + + wrqu->data.length = strlen(extra)+1; + break; + } + +/* The case prints the current state of the HDD, SME, CSR, PE, TL + *it can be extended for WDI Global State as well. + *And currently it only checks P2P_CLIENT adapter. + *P2P_DEVICE and P2P_GO have not been added as of now. +*/ + case WE_GET_STATES: + { + int buf = 0, len = 0; + int adapter_num = 0; + int count = 0, check = 1; + + tANI_U16 tlState; + tHalHandle hHal = NULL; + tpAniSirGlobal pMac = NULL; + hdd_station_ctx_t *pHddStaCtx = NULL; + + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + hdd_adapter_t *useAdapter = NULL; + + /* Print wlan0 or p2p0 states based on the adapter_num + *by using the correct adapter + */ + while ( adapter_num < 2 ) + { + if ( WLAN_ADAPTER == adapter_num ) + { + useAdapter = pAdapter; + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n\n wlan0 States:-"); + len += buf; + } + else if ( P2P_ADAPTER == adapter_num ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n\n p2p0 States:-"); + len += buf; + + if( !pHddCtx ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pHddCtx is NULL"); + len += buf; + break; + } + + /*Printing p2p0 states only in the case when the device is + configured as a p2p_client*/ + useAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_CLIENT); + if ( !useAdapter ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n Device not configured as P2P_CLIENT."); + len += buf; + break; + } + } + + hHal = WLAN_HDD_GET_HAL_CTX( useAdapter ); + if (!hHal) { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pMac is NULL"); + len += buf; + break; + } + pMac = PMAC_STRUCT( hHal ); + if (!pMac) { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pMac is NULL"); + len += buf; + break; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR( useAdapter ); + if( !pHddStaCtx ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n pHddStaCtx is NULL"); + len += buf; + break; + } + + tlState = smeGetTLSTAState(hHal, pHddStaCtx->conn_info.staId[0]); + + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n HDD Conn State - %s " + "\n \n SME State:" + "\n Neighbour Roam State - %s" + "\n CSR State - %s" + "\n CSR Substate - %s" + "\n \n TL STA %d State: %s", + macTraceGetHDDWlanConnState( + pHddStaCtx->conn_info.connState), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState), + macTraceGetcsrRoamState( + pMac->roam.curState[useAdapter->sessionId]), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[useAdapter->sessionId]), + pHddStaCtx->conn_info.staId[0], + macTraceGetTLState(tlState) + ); + len += buf; + adapter_num++; + } + + if (pMac) { + /* Printing Lim State starting with global lim states */ + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n \n LIM STATES:-" + "\n Global Sme State - %s "\ + "\n Global mlm State - %s "\ + "\n", + macTraceGetLimSmeState(pMac->lim.gLimSmeState), + macTraceGetLimMlmState(pMac->lim.gLimMlmState) + ); + len += buf; + + /*printing the PE Sme and Mlm states for valid lim sessions*/ + while ( check < 3 && count < pMac->lim.maxBssId) + { + if ( pMac->lim.gpSession[count].valid ) + { + buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, + "\n Lim Valid Session %d:-" + "\n PE Sme State - %s " + "\n PE Mlm State - %s " + "\n", + check, + macTraceGetLimSmeState(pMac->lim.gpSession[count].limSmeState), + macTraceGetLimMlmState(pMac->lim.gpSession[count].limMlmState) + ); + + len += buf; + check++; + } + count++; + } + } + + wrqu->data.length = strlen(extra)+1; + break; + } + + case WE_GET_CFG: + { + hdd_cfg_get_config(WLAN_HDD_GET_CTX(pAdapter), extra, WE_MAX_STR_LEN); + wrqu->data.length = strlen(extra)+1; + break; + } +#ifdef WLAN_FEATURE_11AC + case WE_GET_RSSI: + { + v_S7_t s7Rssi = 0; + wlan_hdd_get_station_stats(pAdapter); + wlan_hdd_get_rssi(pAdapter, &s7Rssi); + snprintf(extra, WE_MAX_STR_LEN, "rssi=%d",s7Rssi); + wrqu->data.length = strlen(extra)+1; + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WE_GET_ROAM_RSSI: + { + v_S7_t s7Rssi = 0; + wlan_hdd_get_roam_rssi(pAdapter, &s7Rssi); + snprintf(extra, WE_MAX_STR_LEN, "rssi=%d", s7Rssi); + wrqu->data.length = strlen(extra)+1; + break; + } +#endif + case WE_GET_WMM_STATUS: + { + snprintf(extra, WE_MAX_STR_LEN, + "\nDir: 0=up, 1=down, 3=both\n" + "|------------------------|\n" + "|AC | ACM |Admitted| Dir |\n" + "|------------------------|\n" + "|VO | %d | %3s | %d |\n" + "|VI | %d | %3s | %d |\n" + "|BE | %d | %3s | %d |\n" + "|BK | %d | %3s | %d |\n" + "|------------------------|\n", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcTspecInfo.ts_info.direction, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcTspecInfo.ts_info.direction, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcTspecInfo.ts_info.direction, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessRequired, + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessAllowed?"YES":"NO", + pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcTspecInfo.ts_info.direction); + + + wrqu->data.length = strlen(extra)+1; + break; + } + case WE_GET_CHANNEL_LIST: + { + VOS_STATUS status; + v_U8_t i, len; + char* buf ; + tANI_U8 pBuf[COUNTRY_CODE_LEN]; + tANI_U8 uBufLen = COUNTRY_CODE_LEN; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + tChannelListInfo channel_list; + + memset(&channel_list, 0, sizeof(channel_list)); + status = iw_softap_get_channel_list(dev, info, wrqu, (char *)&channel_list); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s GetChannelList Failed!!!",__func__); + return -EINVAL; + } + buf = extra; + + /** + * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. Maximum buffer + * needed = 5 * number of channels. Check ifsufficient + * buffer is available and then proceed to fill the buffer. + */ + if(WE_MAX_STR_LEN < (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s Insufficient Buffer to populate channel list", + __func__); + return -EINVAL; + } + len = scnprintf(buf, WE_MAX_STR_LEN, "%u ", + channel_list.num_channels); + if( eHAL_STATUS_SUCCESS == sme_GetCountryCode(pHddCtx->hHal, pBuf, &uBufLen)) + { + //Printing Country code in getChannelList + for(i= 0; i < COUNTRY_CODE_LEN; i++) + { + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, + "%c ", pBuf[i]); + } + } + for(i = 0 ; i < channel_list.num_channels; i++) + { + len += scnprintf(buf + len, WE_MAX_STR_LEN - len, + "%u ", channel_list.channels[i]); + } + wrqu->data.length = strlen(extra)+1; + + break; + } +#ifdef FEATURE_WLAN_TDLS + case WE_GET_TDLS_PEERS: + { + wrqu->data.length = wlan_hdd_tdls_get_all_peers(pAdapter, extra, WE_MAX_STR_LEN)+1; + break; + } +#endif +#ifdef WLAN_FEATURE_11W + case WE_GET_11W_INFO: + { + hddLog(LOGE, "WE_GET_11W_ENABLED = %d", pWextState->roamProfile.MFPEnabled ); + + snprintf(extra, WE_MAX_STR_LEN, + "\n BSSID %02X:%02X:%02X:%02X:%02X:%02X, Is PMF Assoc? %d" + "\n Number of Unprotected Disassocs %d" + "\n Number of Unprotected Deauths %d", + (*pWextState->roamProfile.BSSIDs.bssid)[0], (*pWextState->roamProfile.BSSIDs.bssid)[1], + (*pWextState->roamProfile.BSSIDs.bssid)[2], (*pWextState->roamProfile.BSSIDs.bssid)[3], + (*pWextState->roamProfile.BSSIDs.bssid)[4], (*pWextState->roamProfile.BSSIDs.bssid)[5], + pWextState->roamProfile.MFPEnabled, pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx, + pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx); + + wrqu->data.length = strlen(extra)+1; + break; + } +#endif +#ifdef WLAN_FEATURE_RMC + case WE_GET_IBSS_STA_INFO: + { + hdd_station_ctx_t *pHddStaCtx = + WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + int idx = 0; + int length = 0, buf = 0; + + for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) + { + if (0 != pHddStaCtx->conn_info.staId[ idx ]) + { + buf = snprintf + ( + (extra + length), WE_MAX_STR_LEN - length, + "\n%d .%02x:%02x:%02x:%02x:%02x:%02x\n", + pHddStaCtx->conn_info.staId[ idx ], + pHddStaCtx->conn_info.peerMacAddress[idx].bytes[0], + pHddStaCtx->conn_info.peerMacAddress[idx].bytes[1], + pHddStaCtx->conn_info.peerMacAddress[idx].bytes[2], + pHddStaCtx->conn_info.peerMacAddress[idx].bytes[3], + pHddStaCtx->conn_info.peerMacAddress[idx].bytes[4], + pHddStaCtx->conn_info.peerMacAddress[idx].bytes[5] + ); + length += buf; + } + } + wrqu->data.length = strlen(extra)+1; + break; + } +#endif + case WE_GET_SNR: + { + v_S7_t s7snr = 0; + int status = 0; + hdd_context_t *pHddCtx; + hdd_station_ctx_t *pHddStaCtx; + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + return status; + } + + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring || + eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + hddLog(LOGE, "%s: getSNR failed: Enable SNR Monitoring-%d," + " ConnectionState-%d", __func__, + pHddCtx->cfg_ini->fEnableSNRMonitoring, + pHddStaCtx->conn_info.connState); + return -ENONET; + } + + /*update the stats in TL*/ + wlan_hdd_get_station_stats(pAdapter); + wlan_hdd_get_snr(pAdapter, &s7snr); + snprintf(extra, WE_MAX_STR_LEN, "snr=%d",s7snr); + wrqu->data.length = strlen(extra) + 1; + break; + } + +#ifdef FEATURE_OEM_DATA_SUPPORT + case WE_GET_OEM_DATA_CAP: + { + return iw_get_oem_data_cap(dev, info, wrqu, extra); + } +#endif /* FEATURE_OEM_DATA_SUPPORT */ + + default: + { + hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd ); + break; + } + } + EXIT(); + return 0; +} + +static int iw_get_char_setnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_char_setnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/* action sub-ioctls */ +static int __iw_setnone_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int sub_cmd; + int ret = 0; /* success */ + struct iw_point s_priv_data; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&s_priv_data, wrqu)) + { + return -EINVAL; + } + + sub_cmd = s_priv_data.flags; + + switch (sub_cmd) + { + case WE_CLEAR_STATS: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: clearing", __func__); + memset(&pAdapter->stats, 0, sizeof(pAdapter->stats)); + memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats)); + break; + } + case WE_INIT_AP: + { + /*FIX ME: Need to be revisited if multiple SAPs to be supported */ + + /* As Soft AP mode might been changed to STA already with + * killing of Hostapd, need to find the adpater by name + * rather than mode */ + hdd_adapter_t* pAdapter_to_stop = + hdd_get_adapter_by_name(WLAN_HDD_GET_CTX(pAdapter), "softap.0"); + if( pAdapter_to_stop ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Adapter with name softap.0 already " + "exist, ignoring the request.\nRemove the " + "adapter and try again\n"); + break; + } + pr_info("Init AP trigger\n"); + hdd_open_adapter( WLAN_HDD_GET_CTX(pAdapter), WLAN_HDD_SOFTAP, "softap.%d", + wlan_hdd_get_intf_addr( WLAN_HDD_GET_CTX(pAdapter) ),TRUE); + break; + } +#ifdef WLAN_FEATURE_RMC + case WE_IBSS_GET_PEER_INFO_ALL: + { + hdd_wlan_get_ibss_peer_info_all(pAdapter); + break; + } +#endif + case WE_STOP_AP: + { + /*FIX ME: Need to be revisited if multiple SAPs to be supported */ + /* As Soft AP mode has been changed to STA already with killing of Hostapd, + * this is a dead code and need to find the adpater by name rather than mode */ + hdd_adapter_t* pAdapter_to_stop = + hdd_get_adapter_by_name(WLAN_HDD_GET_CTX(pAdapter), "softap.0"); + if( pAdapter_to_stop ) + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + pr_info("Stopping AP mode\n"); + + if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + /* EXIT BMPS as fw cannot handle DEL_STA when its in BMPS */ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE); + } + + /*Make sure that pAdapter cleaned properly*/ + hdd_stop_adapter( pHddCtx, pAdapter_to_stop, VOS_TRUE ); + hdd_deinit_adapter( pHddCtx, pAdapter_to_stop, TRUE); + memset(&pAdapter_to_stop->sessionCtx, 0, sizeof(pAdapter_to_stop->sessionCtx)); + + wlan_hdd_release_intf_addr(WLAN_HDD_GET_CTX(pAdapter), + pAdapter_to_stop->macAddressCurrent.bytes); + hdd_close_adapter(WLAN_HDD_GET_CTX(pAdapter), pAdapter_to_stop, + TRUE); + + if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) + { + /* put the device back into BMPS */ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO); + } + } + else + { + printk(KERN_ERR"SAP adapter not found to stop it!\n"); + } + + break; + } +#ifdef WLAN_BTAMP_FEATURE + case WE_ENABLE_AMP: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: enabling AMP", __func__); + WLANBAP_RegisterWithHCI(pAdapter); + break; + } + case WE_DISABLE_AMP: + { + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __func__); + + pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); + status = WLANBAP_StopAmp(); + if(VOS_STATUS_SUCCESS != status ) + { + pHddCtx->isAmpAllowed = VOS_TRUE; + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Failed to stop AMP", __func__); + } + else + { + //a state m/c implementation in PAL is TBD to avoid this delay + msleep(500); + pHddCtx->isAmpAllowed = VOS_FALSE; + WLANBAP_DeregisterFromHCI(); + } + + break; + } +#endif + case WE_ENABLE_DXE_STALL_DETECT: + { + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + sme_transportDebug(hHal, VOS_FALSE, VOS_TRUE); + break; + } + case WE_DISPLAY_DXE_SNAP_SHOT: + { + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + sme_transportDebug(hHal, VOS_TRUE, VOS_FALSE); + break; + } + case WE_DISPLAY_DATAPATH_SNAP_SHOT: + { + hddLog(LOGE, "%s: called %d",__func__, sub_cmd); + hdd_wmm_tx_snapshot(pAdapter); + WLANTL_TLDebugMessage(WLANTL_DEBUG_TX_SNAPSHOT); + break; + } + + case WE_SET_REASSOC_TRIGGER: + { + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpAniSirGlobal pMac = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U32_t roamId = 0; + tCsrRoamModifyProfileFields modProfileFields; + sme_GetModifyProfileFields(pMac, pAdapter->sessionId, &modProfileFields); + sme_RoamReassoc(pMac, pAdapter->sessionId, NULL, modProfileFields, &roamId, 1); + return 0; + } + + case WE_STOP_OBSS_SCAN: + { + /* 1.OBSS Scan is mandatory while operating in 2.4GHz + 2.OBSS scan is stopped by Firmware during the disassociation + 3.OBSS stop comamnd is added for debugging purpose*/ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + tpAniSirGlobal pMac; + + if (pAdapter == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " pAdapter is NULL "); + return -EINVAL; + } + pMac = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (pMac == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " pMac is NULL "); + return -EINVAL; + } + sme_HT40StopOBSSScan(pMac, pAdapter->sessionId); + } + break; + case WE_DUMP_ROAM_TIMER_LOG: + { + vos_dump_roam_time_log_service(); + break; + } + + case WE_RESET_ROAM_TIMER_LOG: + { + vos_reset_roam_timer_log(); + break; + } + case WE_GET_FW_LOGS: + { + vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL, + WLAN_LOG_INDICATOR_IOCTL, + WLAN_LOG_REASON_IOCTL, + TRUE, TRUE); + break; + } + case WE_GET_FW_MEMDUMP: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "FW_MEM_DUMP requested "); + get_fwr_memdump(dev,info,wrqu,extra); + break; + } + default: + { + hddLog(LOGE, "%s: unknown ioctl %d", __func__, sub_cmd); + break; + } + } + EXIT(); + return ret; +} + +static int iw_setnone_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_setnone_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +void hdd_wmm_tx_snapshot(hdd_adapter_t *pAdapter) +{ + /* + * Function to display HDD WMM information + * for Tx Queues. + * Prints globala as well as per client depending + * whether the clients are registered or not. + */ + int i = 0, j = 0; + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = VOS_GET_SAP_CB(pVosContext); + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ibss_peer_info_t *pPeerInfo; + v_SIZE_t tx_queue_count[NUM_TX_QUEUES]; + + for ( i=0; i< NUM_TX_QUEUES; i++) + { + spin_lock_bh(&pAdapter->wmm_tx_queue[i].lock); + tx_queue_count[i] = pAdapter->wmm_tx_queue[i].count; + spin_unlock_bh(&pAdapter->wmm_tx_queue[i].lock); + } + + for ( i=0; i< NUM_TX_QUEUES; i++) { + if (tx_queue_count[i]) { + hddLog(LOGE, "HDD WMM TxQueue Info For AC: %d Count: %d", + i, tx_queue_count[i]); + } + } + + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("psapCtx is NULL")); + return; + } + + spin_lock_bh(&pSapCtx->staInfo_lock); + for(i =0; iaStaInfo[i].isUsed) + { + hddLog(LOGE, "******STAIndex: %d*********", i); + for ( j=0; j< NUM_TX_QUEUES; j++) + { + if( pSapCtx->aStaInfo[i].wmm_tx_queue[j].count ) + { + spin_lock_bh(&pSapCtx->aStaInfo[i].wmm_tx_queue[j].lock); + hddLog(LOGE, "HDD TxQueue Info For AC: %d Count: %d", + j, pSapCtx->aStaInfo[i].wmm_tx_queue[j].count); + spin_unlock_bh(&pSapCtx->aStaInfo[i].wmm_tx_queue[j].lock); + } + } + } + } + spin_unlock_bh(&pSapCtx->staInfo_lock); + + if(pHddStaCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("pHddStaCtx is NULL")); + return; + } + + pPeerInfo = &pHddStaCtx->ibss_peer_info; + if(pPeerInfo == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("ppeerinfo is NULL")); + return; + } + + for (i = 0; i < HDD_MAX_NUM_IBSS_STA; i++) { + if (pPeerInfo->ibssStaInfo[i].isUsed) { + hddLog(LOGE, "******IBSS STAIndex: %d*********", i); + for (j = 0; j < NUM_TX_QUEUES; j++) { + if (pPeerInfo->ibssStaInfo[i].wmm_tx_queue[j].count) { + spin_lock_bh( + &pPeerInfo->ibssStaInfo[i].wmm_tx_queue[j].lock); + hddLog(LOGE, + "HDD TxQueue Info For AC: %d Count: %d PrevAdress:%p, NextAddress:%p", + j, pPeerInfo->ibssStaInfo[i].wmm_tx_queue[j].count, + pPeerInfo->ibssStaInfo[i].wmm_tx_queue[j].anchor.prev, + pPeerInfo->ibssStaInfo[i].wmm_tx_queue[j].anchor.next); + spin_unlock_bh( + &pPeerInfo->ibssStaInfo[i].wmm_tx_queue[j].lock); + } + } + } + } + +} + +static int __iw_set_var_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal = NULL; + int sub_cmd; + int *apps_args = (int *) extra; + hdd_station_ctx_t *pStaCtx = NULL ; + hdd_mon_ctx_t *pMonCtx = NULL; + hdd_context_t *pHddCtx = NULL; + hdd_ap_ctx_t *pAPCtx = NULL; + v_CONTEXT_t pVosContext; + int cmd = 0; + int staId = 0; + int ret = 0; + + ENTER(); + if (extra == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NULL extra buffer pointer", __func__); + return -EINVAL; + } + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + if( VOS_MONITOR_MODE != hdd_get_conparam()) + { + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + } + sub_cmd = wrqu->data.flags; + + hddLog(LOG1, "%s: Received length %d", __func__, wrqu->data.length); + + + if(( sub_cmd == WE_MCC_CONFIG_CREDENTIAL ) || + (sub_cmd == WE_MCC_CONFIG_PARAMS )) + { + if(( pAdapter->device_mode == WLAN_HDD_INFRA_STATION )|| + ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT )) + { + pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + staId = pStaCtx->conn_info.staId[0]; + } + else if (( pAdapter->device_mode == WLAN_HDD_P2P_GO ) || + ( pAdapter->device_mode == WLAN_HDD_SOFTAP )) + { + pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + staId = pAPCtx->uBCStaId; + } + else + { + hddLog(LOGE, "%s: Device mode %d not recognised", __FUNCTION__, pAdapter->device_mode); + return 0; + } + } + + switch (sub_cmd) + { + case WE_LOG_DUMP_CMD: + { + if(apps_args[0] == 26) { + if (!pHddCtx->cfg_ini->crash_inject_enabled) { + hddLog(LOGE, "Crash Inject ini disabled, Ignore Crash Inject"); + return 0; + } + } + hddLog(LOG1, "%s: LOG_DUMP %d arg1 %d arg2 %d arg3 %d arg4 %d", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4]); + if (hHal) + logPrintf(hHal, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4]); + + } + break; +#ifdef WLAN_FEATURE_RMC + case WE_IBSS_GET_PEER_INFO: + { + pr_info ( "Station ID = %d\n",apps_args[0]); + hdd_wlan_get_ibss_peer_info(pAdapter, apps_args[0]); + } + break; +#endif + + case WE_P2P_NOA_CMD: + { + p2p_app_setP2pPs_t p2pNoA; + + if (pAdapter->device_mode != WLAN_HDD_P2P_GO) { + hddLog(LOGE, + FL("Setting NoA is not allowed in Device mode:%d"), + pAdapter->device_mode); + return -EINVAL; + } + + p2pNoA.opp_ps = apps_args[0]; + p2pNoA.ctWindow = apps_args[1]; + p2pNoA.duration = apps_args[2]; + p2pNoA.interval = apps_args[3]; + p2pNoA.count = apps_args[4]; + p2pNoA.single_noa_duration = apps_args[5]; + p2pNoA.psSelection = apps_args[6]; + + hddLog(LOG1, "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d " + "interval %d count %d single noa duration %d PsSelection %x", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4], apps_args[5], apps_args[6]); + + hdd_setP2pPs(dev, &p2pNoA); + + } + break; + + case WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD: + { + hddLog(LOG1, "%s: SELECTIVE_MODULE_LOG %d arg1 %d arg2", + __func__, apps_args[0], apps_args[1]); + vosTraceEnable(apps_args[0], apps_args[1]); + } + break; + + case WE_MTRACE_DUMP_CMD: + { + hddLog(LOG1, "%s: MTRACE_DUMP code %d session %d count %d " + "bitmask_of_module %d ", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3]); + if (hHal) + vosTraceDumpAll((void*)hHal , apps_args[0], apps_args[1], + apps_args[2], apps_args[3]); + + } + break; + + case WE_MCC_CONFIG_CREDENTIAL : + { + cmd = 287; //Command should be updated if there is any change + // in the Riva dump command + if((apps_args[0] >= 40 ) && (apps_args[0] <= 160 )) + { + if (hHal) + logPrintf(hHal, cmd, staId, apps_args[0], apps_args[1], + apps_args[2]); + } + else + { + hddLog(LOGE, "%s : Enter valid MccCredential value between MIN :40 and MAX:160", __func__); + return 0; + } + } + break; + + case WE_MCC_CONFIG_PARAMS : + { + cmd = 288; //command Should be updated if there is any change + // in the Riva dump command + hdd_validate_mcc_config(pAdapter, staId, apps_args[0], apps_args[1],apps_args[2]); + } + break; + +#ifdef FEATURE_WLAN_TDLS + case WE_TDLS_CONFIG_PARAMS : + { + tdls_config_params_t tdlsParams; + + tdlsParams.tdls = apps_args[0]; + tdlsParams.tx_period_t = apps_args[1]; + tdlsParams.tx_packet_n = apps_args[2]; + tdlsParams.discovery_period_t = apps_args[3]; + tdlsParams.discovery_tries_n = apps_args[4]; + tdlsParams.idle_timeout_t = apps_args[5]; + tdlsParams.idle_packet_n = apps_args[6]; + tdlsParams.rssi_hysteresis = apps_args[7]; + tdlsParams.rssi_trigger_threshold = apps_args[8]; + tdlsParams.rssi_teardown_threshold = apps_args[9]; + + wlan_hdd_tdls_set_params(dev, &tdlsParams); + } + break; +#endif + case WE_CONFIGURE_MONITOR_MODE: + { + v_U32_t magic = 0; + struct completion cmpVar; + long waitRet = 0; + tVOS_CON_MODE mode = hdd_get_conparam(); + + if (VOS_MONITOR_MODE != mode) { + hddLog(LOGE, FL("invalid mode %d"), mode); + return -EIO; + } + + pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter); + if( pMonCtx == NULL ) + { + hddLog(LOGE, "Monitor Context NULL"); + return -EIO; + } + hddLog(LOG1, "%s: Monitor MOde Configuration: ChNo=%d ChBW=%d CRCCheck=%d type=%d ConversionBit=%d", + __func__, apps_args[0], apps_args[1], apps_args[2], + apps_args[3], apps_args[4]); + /* Input Validation part of FW */ + pMonCtx->ChannelNo = apps_args[0]; + pMonCtx->ChannelBW = apps_args[1]; + pMonCtx->crcCheckEnabled = apps_args[2]; + wlan_hdd_mon_set_typesubtype( pMonCtx,apps_args[3]); + pMonCtx->is80211to803ConReq = apps_args[4]; + WLANTL_SetIsConversionReq(pVosContext,apps_args[4]); + if( pMonCtx->is80211to803ConReq ) + pAdapter->dev->type = ARPHRD_ETHER; + else + pAdapter->dev->type = ARPHRD_IEEE80211_RADIOTAP; + if( (apps_args[3]!= 100 && apps_args[3]!= 0) && apps_args[4] ) + { + hddLog(LOGE, "%s: Filtering data packets as management and control" + " cannot be converted to 802.3 ",__func__); + pMonCtx->typeSubtypeBitmap = 0xFFFF00000000; + } + if (MON_MODE_START == pMonCtx->state) { + magic = MON_MODE_MSG_MAGIC; + init_completion(&cmpVar); + if (VOS_STATUS_SUCCESS != + wlan_hdd_mon_postMsg(&magic, &cmpVar, + pMonCtx, hdd_monPostMsgCb)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to post MON MODE REQ")); + magic = 0; + return -EIO; + } + waitRet = wait_for_completion_timeout(&cmpVar, + MON_MODE_MSG_TIMEOUT); + magic = 0; + if (waitRet <= 0 ) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to wait on monitor mode completion %ld"), + waitRet); + } + } + } + break; + + case WE_SET_MONITOR_MODE_FILTER: + { + v_U32_t magic = 0; + struct completion cmpVar; + long waitRet = 0; + tVOS_CON_MODE mode = hdd_get_conparam(); + + if (VOS_MONITOR_MODE != mode) { + hddLog(LOGE, FL("invalid mode %d"), mode); + return -EIO; + } + + pMonCtx = WLAN_HDD_GET_MONITOR_CTX_PTR(pAdapter); + if( pMonCtx == NULL ) + { + hddLog(LOGE, "Monitor Context NULL"); + return -EIO; + } + /* Input Validation Part of FW */ + pMonCtx->numOfMacFilters=1; + pMonCtx->mmFilters[0].macAddr.bytes[0]=apps_args[0]; + pMonCtx->mmFilters[0].macAddr.bytes[1]=apps_args[1]; + pMonCtx->mmFilters[0].macAddr.bytes[2]=apps_args[2]; + pMonCtx->mmFilters[0].macAddr.bytes[3]=apps_args[3]; + pMonCtx->mmFilters[0].macAddr.bytes[4]=apps_args[4]; + pMonCtx->mmFilters[0].macAddr.bytes[5]=apps_args[5]; + pMonCtx->mmFilters[0].isA1filter = apps_args[6]; + pMonCtx->mmFilters[0].isA2filter = apps_args[7]; + pMonCtx->mmFilters[0].isA3filter = apps_args[8]; + hddLog(LOG1, "%s: Monitor Filter: %pM A1=%d A2=%d A3=%d ", + __func__, pMonCtx->mmFilters[0].macAddr.bytes, + apps_args[6], apps_args[7], apps_args[8]); + if (MON_MODE_START == pMonCtx->state) { + magic = MON_MODE_MSG_MAGIC; + init_completion(&cmpVar); + if (VOS_STATUS_SUCCESS != + wlan_hdd_mon_postMsg(&magic, &cmpVar, + pMonCtx, hdd_monPostMsgCb)) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to post MON MODE REQ")); + magic = 0; + return -EIO; + } + waitRet = wait_for_completion_timeout(&cmpVar, + MON_MODE_MSG_TIMEOUT); + magic = 0; + if (waitRet <= 0 ) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("failed to wait on monitor mode completion %ld"), + waitRet); + } + } + } + break; + + default: + { + hddLog(LOGE, "%s: Invalid IOCTL command %d", + __func__, sub_cmd ); + } + break; + } + EXIT(); + return 0; +} + +static int iw_hdd_set_var_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + union iwreq_data u_priv_wrqu; + int apps_args[MAX_VAR_ARGS] = {0}; + int num_args; + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + /* helper function to get iwreq_data with compat handling. */ + if (hdd_priv_get_data(&u_priv_wrqu.data, wrqu)) + { + return -EINVAL; + } + + if (NULL == u_priv_wrqu.data.pointer) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: NULL data pointer", __func__); + return -EINVAL; + } + + num_args = u_priv_wrqu.data.length; + if (num_args > MAX_VAR_ARGS) + { + num_args = MAX_VAR_ARGS; + } + + if (copy_from_user(apps_args, u_priv_wrqu.data.pointer, + (sizeof(int)) * num_args)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to copy data from user buffer", __func__); + return -EFAULT; + } + + vos_ssr_protect(__func__); + ret = __iw_set_var_ints_getnone(dev, info, &u_priv_wrqu, + (char *)&apps_args); + vos_ssr_unprotect(__func__); + + return ret; +} + +int iw_set_var_ints_getnone(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + vos_ssr_protect(__func__); + ret = __iw_set_var_ints_getnone(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_add_tspec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra; + int params[HDD_WLAN_WMM_PARAM_COUNT]; + sme_QosWmmTspecInfo tSpec; + v_U32_t handle; + struct iw_point s_priv_data; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + // make sure the application is sufficiently priviledged + // note that the kernel will do this for "set" ioctls, but since + // this ioctl wants to return status to user space it must be + // defined as a "get" ioctl + if (!capable(CAP_NET_ADMIN)) + { + return -EPERM; + } + // we must be associated in order to add a tspec + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // since we are defined to be a "get" ioctl, and since the number + // of params exceeds the number of params that wireless extensions + // will pass down in the iwreq_data, we must copy the "set" params. + // We must handle the compat for iwreq_data in 32U/64K environment. + + // helper fucntion to get iwreq_data with compat handling. + if (hdd_priv_get_data(&s_priv_data, wrqu)) + { + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // make sure all params are correctly passed to function + if ((NULL == s_priv_data.pointer) || + (HDD_WLAN_WMM_PARAM_COUNT != s_priv_data.length)) + { + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // from user space ourselves + if (copy_from_user(¶ms, s_priv_data.pointer, sizeof(params))) + { + // hmmm, can't get them + return -EIO; + } + + // clear the tspec + memset(&tSpec, 0, sizeof(tSpec)); + + // validate the handle + handle = params[HDD_WLAN_WMM_PARAM_HANDLE]; + if (HDD_WMM_HANDLE_IMPLICIT == handle) + { + // that one is reserved + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + // validate the TID + if (params[HDD_WLAN_WMM_PARAM_TID] > 7) + { + // out of range + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID]; + + // validate the direction + switch (params[HDD_WLAN_WMM_PARAM_DIRECTION]) + { + case HDD_WLAN_WMM_DIRECTION_UPSTREAM: + tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK; + break; + + case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM: + tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK; + break; + + case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL: + tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH; + break; + + default: + // unknown + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + tSpec.ts_info.psb = params[HDD_WLAN_WMM_PARAM_APSD]; + + // validate the user priority + if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX) + { + // out of range + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY]; + if(0 > tSpec.ts_info.up || SME_QOS_WMM_UP_MAX < tSpec.ts_info.up) + { + hddLog(VOS_TRACE_LEVEL_ERROR,"***ts_info.up out of bounds***"); + return 0; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, + "%s:TS_INFO PSB %d UP %d !!!", __func__, + tSpec.ts_info.psb, tSpec.ts_info.up); + + tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE]; + tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE]; + tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE]; + tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE]; + tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE]; + tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE]; + tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE]; + tSpec.surplus_bw_allowance = params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE]; + tSpec.min_service_interval = params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL]; + tSpec.max_service_interval = params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL]; + tSpec.suspension_interval = params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL]; + tSpec.inactivity_interval = params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL]; + + tSpec.ts_info.burst_size_defn = params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN]; + + // Save the expected UAPSD settings by application, this will be needed + // when re-negotiating UAPSD settings during BT Coex cases. + tSpec.expec_psb_byapp = params[HDD_WLAN_WMM_PARAM_APSD]; + + // validate the ts info ack policy + switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY]) + { + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK: + tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + break; + + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK: + tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK; + break; + + default: + // unknown + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec); + + EXIT(); + return 0; +} + + +static int iw_add_tspec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_add_tspec(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_del_tspec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int *params = (int *)extra; + hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra; + v_U32_t handle; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + // make sure the application is sufficiently priviledged + // note that the kernel will do this for "set" ioctls, but since + // this ioctl wants to return status to user space it must be + // defined as a "get" ioctl + if (!capable(CAP_NET_ADMIN)) + { + return -EPERM; + } + // although we are defined to be a "get" ioctl, the params we require + // will fit in the iwreq_data, therefore unlike iw_add_tspec() there + // is no need to copy the params from user space + + // validate the handle + handle = params[HDD_WLAN_WMM_PARAM_HANDLE]; + if (HDD_WMM_HANDLE_IMPLICIT == handle) + { + // that one is reserved + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + *pStatus = hdd_wmm_delts(pAdapter, handle); + + EXIT(); + return 0; +} + +static int iw_del_tspec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_del_tspec(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + + +static int __iw_get_tspec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int *params = (int *)extra; + hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra; + v_U32_t handle; + int ret = 0; + + ENTER(); + + // although we are defined to be a "get" ioctl, the params we require + // will fit in the iwreq_data, therefore unlike iw_add_tspec() there + // is no need to copy the params from user space + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + // validate the handle + handle = params[HDD_WLAN_WMM_PARAM_HANDLE]; + if (HDD_WMM_HANDLE_IMPLICIT == handle) + { + // that one is reserved + *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + return 0; + } + + *pStatus = hdd_wmm_checkts(pAdapter, handle); + EXIT(); + return 0; +} + +static int iw_get_tspec(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_tspec(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/** + * __iw_setnone_get_threeint() - return three value to up layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/Output + * + * Return: execute result + */ +static int __iw_setnone_get_threeint(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; /* success */ + uint32_t *value = (int *)extra; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + + hddLog(VOS_TRACE_LEVEL_INFO, FL("param = %d"), value[0]); + + switch (value[0]) { + case WE_GET_TSF: + ret = hdd_indicate_tsf(adapter, value, 3); + break; + default: + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("Invalid IOCTL get_value command %d"), + value[0]); + break; + } + return ret; +} + +/** + * iw_setnone_get_threeint() - return three value to up layer. + * + * @dev: pointer of net_device of this wireless card + * @info: meta data about Request sent + * @wrqu: include request info + * @extra: buf used for in/Output + * + * Return: execute result + */ +static int iw_setnone_get_threeint(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_setnone_get_threeint(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +// +// +// Each time the supplicant has the auth_request or reassoc request +// IEs ready. This is pushed to the driver. The driver will inturn use +// it to send out the auth req and reassoc req for 11r FT Assoc. +// +static int __iw_set_fties(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_station_ctx_t *pHddStaCtx; + hdd_context_t *pHddCtx; + int ret = 0; + //v_CONTEXT_t pVosContext; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (NULL == pHddStaCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: STA Context is NULL",__func__); + return -EINVAL; + } + if (!wrqu->data.length) + { + hddLog(LOGE, FL("called with 0 length IEs")); + return -EINVAL; + } + if (wrqu->data.pointer == NULL) + { + hddLog(LOGE, FL("called with NULL IE")); + return -EINVAL; + } + + // Added for debug on reception of Re-assoc Req. + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + hddLog(LOGE, FL("Called with Ie of length = %d when not associated"), + wrqu->data.length); + hddLog(LOGE, FL("Should be Re-assoc Req IEs")); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + hddLog(LOGE, FL("%s called with Ie of length = %d"), __func__, wrqu->data.length); +#endif + + // Pass the received FT IEs to SME + sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, extra, + wrqu->data.length); + + EXIT(); + return 0; +} + +static int iw_set_fties(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_fties(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif + +static int __iw_set_dynamic_mcbc_filter(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + tpRcvFltMcAddrList pRequest = (tpRcvFltMcAddrList)extra; + hdd_context_t *pHddCtx; + tpSirWlanSetRxpFilters wlanRxpFilterParam; + tHalHandle hHal; + tpSirRcvFltMcAddrList mc_addr_list_ptr; + int idx; + eHalStatus ret_val; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret_val = wlan_hdd_validate_context(pHddCtx); + if (0 != ret_val) + { + return ret_val; + } + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + if (HDD_MULTICAST_FILTER_LIST == pRequest->mcastBcastFilterSetting) + { +#ifdef WLAN_FEATURE_PACKET_FILTERING + + mc_addr_list_ptr = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList)); + if (NULL == mc_addr_list_ptr) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + return -ENOMEM; + } + + mc_addr_list_ptr->ulMulticastAddrCnt = pRequest->mcast_addr_cnt; + + if (mc_addr_list_ptr->ulMulticastAddrCnt > HDD_MAX_NUM_MULTICAST_ADDRESS) + mc_addr_list_ptr->ulMulticastAddrCnt = HDD_MAX_NUM_MULTICAST_ADDRESS; + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr List Cnt %d", __func__, + mc_addr_list_ptr->ulMulticastAddrCnt); + + for (idx = 0; idx < mc_addr_list_ptr->ulMulticastAddrCnt; idx++) + { + memcpy(&mc_addr_list_ptr->multicastAddr[idx], + pRequest->multicastAddr[idx], HDD_WLAN_MAC_ADDR_LEN); + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s MC Addr for Idx %d ="MAC_ADDRESS_STR, __func__, + idx, MAC_ADDR_ARRAY(mc_addr_list_ptr->multicastAddr[idx])); + } + + ret_val = sme_8023MulticastList(hHal, pAdapter->sessionId, mc_addr_list_ptr); + vos_mem_free(mc_addr_list_ptr); + if (eHAL_STATUS_SUCCESS != ret_val) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to Set MC Address List", + __func__); + return -EINVAL; + } +#endif //WLAN_FEATURE_PACKET_FILTERING + } + else + { + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Set MC BC Filter Config request: %d suspend %d", + __func__, pRequest->mcastBcastFilterSetting, + pHddCtx->hdd_wlan_suspended); + spin_lock(&pHddCtx->filter_lock); + pHddCtx->configuredMcastBcastFilter = pRequest->mcastBcastFilterSetting; + spin_unlock(&pHddCtx->filter_lock); + + if (pHddCtx->hdd_wlan_suspended) + { + wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters)); + if (NULL == wlanRxpFilterParam) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + return -EINVAL; + } + + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pRequest->mcastBcastFilterSetting; + wlanRxpFilterParam->setMcstBcstFilter = TRUE; + /* Fwr expect offload needs to clear before set */ + hdd_conf_hostoffload(pAdapter, FALSE); + spin_lock(&pHddCtx->filter_lock); + pHddCtx->configuredMcastBcastFilter = pRequest->mcastBcastFilterSetting; + spin_unlock(&pHddCtx->filter_lock); + if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) + { + hddLog(VOS_TRACE_LEVEL_INFO, "%s: pRequest->mcastBcastFilterSetting ", __func__); + pHddCtx->sus_res_mcastbcast_filter = + pRequest->mcastBcastFilterSetting; + } + + hdd_conf_hostoffload(pAdapter, TRUE); + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + + hddLog(VOS_TRACE_LEVEL_INFO, "%s:MC/BC changed Req %d Set %d En %d", + __func__, + pHddCtx->configuredMcastBcastFilter, + wlanRxpFilterParam->configuredMcstBcstFilterSetting, + wlanRxpFilterParam->setMcstBcstFilter); + + if (eHAL_STATUS_SUCCESS != + sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), + wlanRxpFilterParam)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute set HW MC/BC Filter request", + __func__); + vos_mem_free(wlanRxpFilterParam); + return -EINVAL; + } + + /* mc add list cfg item configuration in fwr */ + hdd_mc_addr_list_cfg_config(pHddCtx, true); + } + } + + EXIT(); + return 0; +} + +static int iw_set_dynamic_mcbc_filter(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_dynamic_mcbc_filter(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_clear_dynamic_mcbc_filter(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tpSirWlanSetRxpFilters wlanRxpFilterParam; + int ret = 0; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + spin_lock(&pHddCtx->filter_lock); + //Reset the filter to INI value as we have to clear the dynamic filter + pHddCtx->configuredMcastBcastFilter = pHddCtx->cfg_ini->mcastBcastFilterSetting; + spin_unlock(&pHddCtx->filter_lock); + + //Configure FW with new setting + if (pHddCtx->hdd_wlan_suspended) + { + wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters)); + if (NULL == wlanRxpFilterParam) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc failed", __func__); + return -EINVAL; + } + + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + wlanRxpFilterParam->setMcstBcstFilter = TRUE; + /* Fwr expect offload needs to clear before set */ + hdd_conf_hostoffload(pAdapter, FALSE); + spin_lock(&pHddCtx->filter_lock); + pHddCtx->configuredMcastBcastFilter = + pHddCtx->cfg_ini->mcastBcastFilterSetting; + spin_unlock(&pHddCtx->filter_lock); + + if (VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) + { + pHddCtx->sus_res_mcastbcast_filter = + pHddCtx->cfg_ini->mcastBcastFilterSetting; + } + + hdd_conf_hostoffload(pAdapter, TRUE); + wlanRxpFilterParam->configuredMcstBcstFilterSetting = + pHddCtx->configuredMcastBcastFilter; + if (eHAL_STATUS_SUCCESS != + sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), + wlanRxpFilterParam)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute set HW MC/BC Filter request", + __func__); + vos_mem_free(wlanRxpFilterParam); + return -EINVAL; + } + + /* mc add list cfg item configuration in fwr */ + hdd_mc_addr_list_cfg_config(pHddCtx, true); + } + EXIT(); + return 0; +} + + +static int iw_clear_dynamic_mcbc_filter(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_clear_dynamic_mcbc_filter(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_host_offload(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tpHostOffloadRequest pRequest = (tpHostOffloadRequest) extra; + tSirHostOffloadReq offloadRequest; + int ret = 0; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + /* Debug display of request components. */ + switch (pRequest->offloadType) + { + case WLAN_IPV4_ARP_REPLY_OFFLOAD: + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Host offload request: ARP reply", __func__); + switch (pRequest->enableOrDisable) + { + case WLAN_OFFLOAD_DISABLE: + hddLog(VOS_TRACE_LEVEL_WARN, " disable"); + break; + case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE: + hddLog(VOS_TRACE_LEVEL_WARN, " BC Filtering enable"); + case WLAN_OFFLOAD_ENABLE: + hddLog(VOS_TRACE_LEVEL_WARN, " ARP offload enable"); + hddLog(VOS_TRACE_LEVEL_WARN, " IP address: %d.%d.%d.%d", + pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1], + pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]); + } + break; + + case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Host offload request: neighbor discovery", + __func__); + switch (pRequest->enableOrDisable) + { + case WLAN_OFFLOAD_DISABLE: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " disable"); + break; + case WLAN_OFFLOAD_ENABLE: + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " enable"); + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " IP address: %x:%x:%x:%x:%x:%x:%x:%x", + *(v_U16_t *)(pRequest->params.hostIpv6Addr), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 2), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 4), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 6), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 8), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 10), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 12), + *(v_U16_t *)(pRequest->params.hostIpv6Addr + 14)); + } + } + + /* Execute offload request. The reason that we can copy the request information + from the ioctl structure to the SME structure is that they are laid out + exactly the same. Otherwise, each piece of information would have to be + copied individually. */ + memcpy(&offloadRequest, pRequest, wrqu->data.length); + if (eHAL_STATUS_SUCCESS != sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &offloadRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute host offload request", + __func__); + return -EINVAL; + } + + EXIT(); + return 0; +} + +static int iw_set_host_offload(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_host_offload(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int __iw_set_keepalive_params(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tpKeepAliveRequest pRequest = (tpKeepAliveRequest) extra; + tSirKeepAliveReq keepaliveRequest; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + /* Debug display of request components. */ + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: Set Keep Alive Request : TimePeriod %d size %zu", + __func__, pRequest->timePeriod, sizeof(tKeepAliveRequest)); + + switch (pRequest->packetType) + { + case WLAN_KEEP_ALIVE_NULL_PKT: + hddLog(VOS_TRACE_LEVEL_WARN, "%s: Keep Alive Request: Tx NULL", __func__); + break; + + case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP: + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Keep Alive Request: Tx UnSolicited ARP RSP", + __func__); + + hddLog(VOS_TRACE_LEVEL_WARN, " Host IP address: %d.%d.%d.%d", + pRequest->hostIpv4Addr[0], pRequest->hostIpv4Addr[1], + pRequest->hostIpv4Addr[2], pRequest->hostIpv4Addr[3]); + + hddLog(VOS_TRACE_LEVEL_WARN, " Dest IP address: %d.%d.%d.%d", + pRequest->destIpv4Addr[0], pRequest->destIpv4Addr[1], + pRequest->destIpv4Addr[2], pRequest->destIpv4Addr[3]); + + hddLog(VOS_TRACE_LEVEL_WARN, " Dest MAC address: %d:%d:%d:%d:%d:%d", + pRequest->destMacAddr[0], pRequest->destMacAddr[1], + pRequest->destMacAddr[2], pRequest->destMacAddr[3], + pRequest->destMacAddr[4], pRequest->destMacAddr[5]); + break; + + } + + /* Execute keep alive request. The reason that we can copy the request information + from the ioctl structure to the SME structure is that they are laid out + exactly the same. Otherwise, each piece of information would have to be + copied individually. */ + memcpy(&keepaliveRequest, pRequest, wrqu->data.length); + + hddLog(VOS_TRACE_LEVEL_INFO, "set Keep: TP before SME %d", + keepaliveRequest.timePeriod); + + if (eHAL_STATUS_SUCCESS != sme_SetKeepAlive(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, &keepaliveRequest)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Keep Alive", + __func__); + return -EINVAL; + } + EXIT(); + return 0; +} + +static int iw_set_keepalive_params(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + vos_ssr_protect(__func__); + ret = __iw_set_keepalive_params(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/**----------------------------------------------------------------- + + \brief hdd_pkt_filter_done - callback to be executed on completion + successful/failure) for clear filter request. + + \return - None + + --------------------------------------------------------------------------*/ +static void hdd_pkt_filter_done(void *data, v_U32_t status) +{ + struct statsContext *cbCtx = (struct statsContext *)data; + + hddLog(VOS_TRACE_LEVEL_INFO, + FL("Pkt Filter Clear Status : %d"), status); + + if (data == NULL) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid context")); + return; + } + + spin_lock(&hdd_context_lock); + if (cbCtx->magic != CLEAR_FILTER_MAGIC) + { + spin_unlock(&hdd_context_lock); + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid context, magic %x"), cbCtx->magic); + if (ioctl_debug) + { + pr_info("%s: Invalid context, magic [%08x]\n", + __func__, cbCtx->magic); + } + return; + } + + complete(&cbCtx->completion); + spin_unlock(&hdd_context_lock); +} + +int wlan_hdd_set_filter(hdd_adapter_t *pAdapter, tpPacketFilterCfg pRequest) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; + tSirRcvPktFilterCfgType packetFilterSetReq = {0}; + tSirRcvFltPktClearParam packetFilterClrReq = {0}; + struct statsContext cbCtx; + int i=0, status; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + return status; + + if (pHddCtx->cfg_ini->disablePacketFilter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Packet Filtering Disabled. Returning ", + __func__ ); + return 0; + } + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + /* Debug display of request components. */ + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Packet Filter Request : FA %d params %d", + __func__, pRequest->filterAction, pRequest->numParams); + + switch (pRequest->filterAction) + { + case HDD_RCV_FILTER_SET: + hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set Packet Filter Request for Id: %d", + __func__, pRequest->filterId); + + packetFilterSetReq.filterId = pRequest->filterId; + if ( pRequest->numParams >= HDD_MAX_CMP_PER_PACKET_FILTER) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Number of Params exceed Max limit %d", + __func__, pRequest->numParams); + return -EINVAL; + } + packetFilterSetReq.numFieldParams = pRequest->numParams; + packetFilterSetReq.coalesceTime = 0; + packetFilterSetReq.filterType = 1; + for (i=0; i < pRequest->numParams; i++) + { + packetFilterSetReq.paramsData[i].protocolLayer = pRequest->paramsData[i].protocolLayer; + packetFilterSetReq.paramsData[i].cmpFlag = pRequest->paramsData[i].cmpFlag; + packetFilterSetReq.paramsData[i].dataOffset = pRequest->paramsData[i].dataOffset; + packetFilterSetReq.paramsData[i].dataLength = pRequest->paramsData[i].dataLength; + packetFilterSetReq.paramsData[i].reserved = 0; + + hddLog(VOS_TRACE_LEVEL_INFO, "Proto %d Comp Flag %d Filter Type %d", + pRequest->paramsData[i].protocolLayer, pRequest->paramsData[i].cmpFlag, + packetFilterSetReq.filterType); + + hddLog(VOS_TRACE_LEVEL_INFO, "Data Offset %d Data Len %d", + pRequest->paramsData[i].dataOffset, pRequest->paramsData[i].dataLength); + if ((sizeof(packetFilterSetReq.paramsData[i].compareData)) < + (pRequest->paramsData[i].dataLength)) + return -EINVAL; + + memcpy(&packetFilterSetReq.paramsData[i].compareData, + pRequest->paramsData[i].compareData, pRequest->paramsData[i].dataLength); + memcpy(&packetFilterSetReq.paramsData[i].dataMask, + pRequest->paramsData[i].dataMask, pRequest->paramsData[i].dataLength); + + hddLog(VOS_TRACE_LEVEL_INFO, "CData %d CData %d CData %d CData %d CData %d CData %d", + pRequest->paramsData[i].compareData[0], pRequest->paramsData[i].compareData[1], + pRequest->paramsData[i].compareData[2], pRequest->paramsData[i].compareData[3], + pRequest->paramsData[i].compareData[4], pRequest->paramsData[i].compareData[5]); + + hddLog(VOS_TRACE_LEVEL_INFO, "MData %d MData %d MData %d MData %d MData %d MData %d", + pRequest->paramsData[i].dataMask[0], pRequest->paramsData[i].dataMask[1], + pRequest->paramsData[i].dataMask[2], pRequest->paramsData[i].dataMask[3], + pRequest->paramsData[i].dataMask[4], pRequest->paramsData[i].dataMask[5]); + } + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, &packetFilterSetReq, pAdapter->sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Set Filter", + __func__); + return -EINVAL; + } + + WLANTL_SetDataPktFilter((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pHddStaCtx->conn_info.staId[0], true); + break; + + case HDD_RCV_FILTER_CLEAR: + + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Clear Packet Filter Request for Id: %d", + __func__, pRequest->filterId); + + if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) { + WLANTL_ResetRxSSN((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pHddStaCtx->conn_info.staId[0]); + } + + init_completion(&cbCtx.completion); + cbCtx.magic = CLEAR_FILTER_MAGIC; + cbCtx.pAdapter = pAdapter; + packetFilterClrReq.cbCtx = &cbCtx; + packetFilterClrReq.filterId = pRequest->filterId; + packetFilterClrReq.pktFilterCallback = hdd_pkt_filter_done; + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, &packetFilterClrReq, pAdapter->sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Clear Filter", + __func__); + return -EINVAL; + } + + status = wait_for_completion_interruptible_timeout(&cbCtx.completion, + msecs_to_jiffies(PKT_FILTER_TIMEOUT)); + spin_lock(&hdd_context_lock); + cbCtx.magic = 0; + spin_unlock(&hdd_context_lock); + if (0 >= status) + { + hddLog(LOGE, FL("failure waiting for pkt_filter_comp_var %d"), + status); + return -EINVAL; + } + + WLANTL_SetDataPktFilter((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + pHddStaCtx->conn_info.staId[0], false); + break; + + default : + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Packet Filter Request: Invalid %d", + __func__, pRequest->filterAction); + return -EINVAL; + } + return 0; +} + +int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType, + tANI_U8 sessionId) +{ + tSirRcvPktFilterCfgType packetFilterSetReq = {0}; + tSirRcvFltPktClearParam packetFilterClrReq = {0}; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL(" NULL HDD Context Passed")); + return -EINVAL; + } + + if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return -EBUSY; + } + + if (pHddCtx->cfg_ini->disablePacketFilter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Packet Filtering Disabled. Returning ", + __func__ ); + return -EINVAL; + } + + switch (filterType) + { + /* For setting IPV6 MC and UC Filter we need to configure + * 2 filters, one for MC and one for UC. + * The Filter ID shouldn't be swapped, which results in making + * UC Filter ineffective. + * We have Hardcode all the values + * + * Reason for a seperate UC filter is because, driver need to + * specify the FW that the specific filter is for unicast + * otherwise FW will not pass the unicast frames by default + * through the filter. This is required to avoid any performance + * hits when no unicast filter is set and only MC/BC are set. + * The way driver informs host is by using the MAC protocol + * layer, CMP flag set to MAX, CMP Data set to 1. + */ + + case HDD_FILTER_IPV6_MC_UC: + /* Setting IPV6 MC Filter below + */ + packetFilterSetReq.filterType = HDD_RCV_FILTER_SET; + packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC; + packetFilterSetReq.numFieldParams = 2; + packetFilterSetReq.paramsData[0].protocolLayer = + HDD_FILTER_PROTO_TYPE_MAC; + packetFilterSetReq.paramsData[0].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[0].dataOffset = + WLAN_HDD_80211_FRM_DA_OFFSET; + packetFilterSetReq.paramsData[0].dataLength = 1; + packetFilterSetReq.paramsData[0].compareData[0] = + HDD_IPV6_MC_CMP_DATA; + + packetFilterSetReq.paramsData[1].protocolLayer = + HDD_FILTER_PROTO_TYPE_ARP; + packetFilterSetReq.paramsData[1].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN; + packetFilterSetReq.paramsData[1].dataLength = 2; + packetFilterSetReq.paramsData[1].compareData[0] = + HDD_IPV6_CMP_DATA_0; + packetFilterSetReq.paramsData[1].compareData[1] = + HDD_IPV6_CMP_DATA_1; + + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, + &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Set IPv6 Mulicast Filter", + __func__); + return -EINVAL; + } + + memset( &packetFilterSetReq, 0, sizeof(tSirRcvPktFilterCfgType)); + + /* + * Setting IPV6 UC Filter below + */ + packetFilterSetReq.filterType = HDD_RCV_FILTER_SET; + packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_UC; + packetFilterSetReq.numFieldParams = 2; + packetFilterSetReq.paramsData[0].protocolLayer = + HDD_FILTER_PROTO_TYPE_MAC; + packetFilterSetReq.paramsData[0].cmpFlag = + HDD_FILTER_CMP_TYPE_MAX; + packetFilterSetReq.paramsData[0].dataOffset = 0; + packetFilterSetReq.paramsData[0].dataLength = 1; + packetFilterSetReq.paramsData[0].compareData[0] = + HDD_IPV6_UC_CMP_DATA; + + packetFilterSetReq.paramsData[1].protocolLayer = + HDD_FILTER_PROTO_TYPE_ARP; + packetFilterSetReq.paramsData[1].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN; + packetFilterSetReq.paramsData[1].dataLength = 2; + packetFilterSetReq.paramsData[1].compareData[0] = + HDD_IPV6_CMP_DATA_0; + packetFilterSetReq.paramsData[1].compareData[1] = + HDD_IPV6_CMP_DATA_1; + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, + &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Set IPv6 Unicast Filter", + __func__); + return -EINVAL; + } + + break; + + case HDD_FILTER_IPV6_MC: + /* + * IPV6 UC Filter might be already set, + * clear the UC Filter. As the Filter + * IDs are static, we can directly clear it. + */ + packetFilterSetReq.filterType = HDD_RCV_FILTER_SET; + packetFilterClrReq.filterId = HDD_FILTER_ID_IPV6_UC; + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, + &packetFilterClrReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Clear IPv6 Unicast Filter", + __func__); + return -EINVAL; + } + + /* + * Setting IPV6 MC Filter below + */ + packetFilterSetReq.filterId = HDD_FILTER_ID_IPV6_MC; + packetFilterSetReq.numFieldParams = 2; + packetFilterSetReq.paramsData[0].protocolLayer = + HDD_FILTER_PROTO_TYPE_MAC; + packetFilterSetReq.paramsData[0].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[0].dataOffset = + WLAN_HDD_80211_FRM_DA_OFFSET; + packetFilterSetReq.paramsData[0].dataLength = 1; + packetFilterSetReq.paramsData[0].compareData[0] = + HDD_IPV6_MC_CMP_DATA; + + packetFilterSetReq.paramsData[1].protocolLayer = + HDD_FILTER_PROTO_TYPE_ARP; + packetFilterSetReq.paramsData[1].cmpFlag = + HDD_FILTER_CMP_TYPE_NOT_EQUAL; + packetFilterSetReq.paramsData[1].dataOffset = ETH_ALEN; + packetFilterSetReq.paramsData[1].dataLength = 2; + packetFilterSetReq.paramsData[1].compareData[0] = + HDD_IPV6_CMP_DATA_0; + packetFilterSetReq.paramsData[1].compareData[1] = + HDD_IPV6_CMP_DATA_1; + + + if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, + &packetFilterSetReq, sessionId)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Failure to execute Set IPv6 Multicast Filter", + __func__); + return -EINVAL; + } + break; + + default : + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Packet Filter Request: Invalid", + __func__); + return -EINVAL; + } + return 0; +} + +void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set) +{ + v_U8_t i; + tpSirRcvFltMcAddrList pMulticastAddrs = NULL; + tHalHandle hHal = NULL; + hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx; + + if (NULL == pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD CTX is NULL")); + return; + } + + hHal = pHddCtx->hHal; + + if (NULL == hHal) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("HAL Handle is NULL")); + return; + } + + /* Check if INI is enabled or not, other wise just return + */ + if (pHddCtx->cfg_ini->fEnableMCAddrList) + { + pMulticastAddrs = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList)); + if (NULL == pMulticastAddrs) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Could not allocate Memory")); + return; + } + + if (set) + { + /* Following pre-conditions should be satisfied before wei + * configure the MC address list. + */ + if (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) || + (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) + && pAdapter->mc_addr_list.mc_cnt + && (eConnectionState_Associated == + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState)) + { + pMulticastAddrs->ulMulticastAddrCnt = + pAdapter->mc_addr_list.mc_cnt; + for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) + { + memcpy(pMulticastAddrs->multicastAddr[i], + pAdapter->mc_addr_list.addr[i], + sizeof(pAdapter->mc_addr_list.addr[i])); + hddLog(VOS_TRACE_LEVEL_INFO, + "%s: %s multicast filter: addr =" + MAC_ADDRESS_STR, + __func__, set ? "setting" : "clearing", + MAC_ADDR_ARRAY(pMulticastAddrs->multicastAddr[i])); + } + /* Set multicast filter */ + sme_8023MulticastList(hHal, pAdapter->sessionId, + pMulticastAddrs); + } + } + else + { + /* Need to clear only if it was previously configured + */ + if (pAdapter->mc_addr_list.isFilterApplied) + { + pMulticastAddrs->ulMulticastAddrCnt = 0; + sme_8023MulticastList(hHal, pAdapter->sessionId, + pMulticastAddrs); + } + + } + pAdapter->mc_addr_list.isFilterApplied = set ? TRUE : FALSE; + vos_mem_free(pMulticastAddrs); + } + else + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("gMCAddrListEnable is not enabled in INI")); + } + return; +} + +static int __iw_set_packet_filter_params(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tpPacketFilterCfg pRequest = NULL; + int ret = 0; + struct iw_point s_priv_data; + + ENTER(); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + if (hdd_priv_get_data(&s_priv_data, wrqu)) + { + return -EINVAL; + } + + if ((NULL == s_priv_data.pointer) || (0 == s_priv_data.length)) + { + return -EINVAL; + } + + /* ODD number is used for set, copy data using copy_from_user */ + pRequest = mem_alloc_copy_from_user_helper(s_priv_data.pointer, + s_priv_data.length); + if (NULL == pRequest) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + ret = wlan_hdd_set_filter(pAdapter, pRequest); + kfree(pRequest); + + EXIT(); + return ret; +} + +static int iw_set_packet_filter_params(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_packet_filter_params(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif +static int __iw_get_statistics(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + hdd_wext_state_t *pWextState; + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + char *p = extra; + int tlen = 0, ret = 0; + tCsrSummaryStatsInfo *pStats; + + tCsrGlobalClassAStatsInfo *aStats; + tCsrGlobalClassDStatsInfo *dStats; + + ENTER(); + + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + pStats = &(pAdapter->hdd_stats.summary_stat); + aStats = &(pAdapter->hdd_stats.ClassA_stat); + dStats = &(pAdapter->hdd_stats.ClassD_stat); + if (eConnectionState_Associated != (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) { + + wrqu->txpower.value = 0; + } + else { + status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_GLOBAL_CLASSB_STATS | + SME_GLOBAL_CLASSC_STATS | + SME_GLOBAL_CLASSD_STATS | + SME_PER_STA_STATS, + hdd_StatisticsCB, 0, FALSE, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter ); + + if (eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Unable to retrieve SME statistics", + __func__); + return -EINVAL; + } + + pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + if (NULL == pWextState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: pWextState is NULL",__func__); + return -EINVAL; + } + + vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: SME timeout while retrieving statistics", + __func__); + /*Remove the SME statistics list by passing NULL in callback argument*/ + status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD, + SME_SUMMARY_STATS | + SME_GLOBAL_CLASSA_STATS | + SME_GLOBAL_CLASSB_STATS | + SME_GLOBAL_CLASSC_STATS | + SME_GLOBAL_CLASSD_STATS | + SME_PER_STA_STATS, + NULL, 0, FALSE, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter ); + + return -EINVAL; + } + FILL_TLV(p, (tANI_U8)WLAN_STATS_RETRY_CNT, + (tANI_U8) sizeof (pStats->retry_cnt), + (char*) &(pStats->retry_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_MUL_RETRY_CNT, + (tANI_U8) sizeof (pStats->multiple_retry_cnt), + (char*) &(pStats->multiple_retry_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_FRM_CNT, + (tANI_U8) sizeof (pStats->tx_frm_cnt), + (char*) &(pStats->tx_frm_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_FRM_CNT, + (tANI_U8) sizeof (pStats->rx_frm_cnt), + (char*) &(pStats->rx_frm_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_FRM_DUP_CNT, + (tANI_U8) sizeof (pStats->frm_dup_cnt), + (char*) &(pStats->frm_dup_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_FAIL_CNT, + (tANI_U8) sizeof (pStats->fail_cnt), + (char*) &(pStats->fail_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_FAIL_CNT, + (tANI_U8) sizeof (pStats->rts_fail_cnt), + (char*) &(pStats->rts_fail_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_ACK_FAIL_CNT, + (tANI_U8) sizeof (pStats->ack_fail_cnt), + (char*) &(pStats->ack_fail_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_SUC_CNT, + (tANI_U8) sizeof (pStats->rts_succ_cnt), + (char*) &(pStats->rts_succ_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_DISCARD_CNT, + (tANI_U8) sizeof (pStats->rx_discard_cnt), + (char*) &(pStats->rx_discard_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_ERROR_CNT, + (tANI_U8) sizeof (pStats->rx_error_cnt), + (char*) &(pStats->rx_error_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]), + (char*) &(dStats->tx_uc_byte_cnt[0]), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_byte_cnt), + (char*) &(dStats->rx_byte_cnt), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_RATE, + (tANI_U8) sizeof (dStats->rx_rate), + (char*) &(dStats->rx_rate), + tlen); + + /* Transmit rate, in units of 500 kbit/sec */ + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_RATE, + (tANI_U8) sizeof (aStats->tx_rate), + (char*) &(aStats->tx_rate), + tlen); + + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_UC_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_uc_byte_cnt[0]), + (char*) &(dStats->rx_uc_byte_cnt[0]), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_MC_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_mc_byte_cnt), + (char*) &(dStats->rx_mc_byte_cnt), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BC_BYTE_CNT, + (tANI_U8) sizeof (dStats->rx_bc_byte_cnt), + (char*) &(dStats->rx_bc_byte_cnt), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_UC_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]), + (char*) &(dStats->tx_uc_byte_cnt[0]), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_MC_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_mc_byte_cnt), + (char*) &(dStats->tx_mc_byte_cnt), + tlen); + FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BC_BYTE_CNT, + (tANI_U8) sizeof (dStats->tx_bc_byte_cnt), + (char*) &(dStats->tx_bc_byte_cnt), + tlen); + + wrqu->data.length = tlen; + + } + + EXIT(); + + return 0; +} + +static int iw_get_statistics(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_get_statistics(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +#ifdef FEATURE_WLAN_SCAN_PNO + +/*Max Len for PNO notification*/ +#define MAX_PNO_NOTIFY_LEN 100 +void found_pref_network_cb (void *callbackContext, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd) +{ + hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext; + union iwreq_data wrqu; + char buf[MAX_PNO_NOTIFY_LEN+1]; + + hddLog(VOS_TRACE_LEVEL_WARN, "A preferred network was found: %s with rssi: -%d", + pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi); + + // create the event + memset(&wrqu, 0, sizeof(wrqu)); + memset(buf, 0, sizeof(buf)); + + snprintf(buf, MAX_PNO_NOTIFY_LEN, "QCOM: Found preferred network: %s with RSSI of -%u", + pPrefNetworkFoundInd->ssId.ssId, + (unsigned int)pPrefNetworkFoundInd->rssi); + + wrqu.data.pointer = buf; + wrqu.data.length = strlen(buf); + + // send the event + + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); + +} + + +/*string based input*/ +VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + /* pnoRequest is a large struct, so we make it static to avoid stack + overflow. This API is only invoked via ioctl, so it is + serialized by the kernel rtnl_lock and hence does not need to be + reentrant */ + tSirPNOScanReq pnoRequest = {0}; + char *ptr, *data; + v_U8_t i,j, ucParams, ucMode; + size_t len; + eHalStatus status = eHAL_STATUS_FAILURE; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO data len %d data %s", + wrqu->data.length, + extra); + + if (wrqu->data.length <= nOffset ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "PNO input is not correct"); + return VOS_STATUS_E_FAILURE; + } + + pnoRequest.enable = 0; + pnoRequest.ucNetworksCount = 0; + /*----------------------------------------------------------------------- + Input is string based and expected to be like this: + + + for each network: + + + + + e.g: + 1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 2 300 0 + + this translates into: + ----------------------------- + enable PNO + look for 2 networks: + test - with authentication type 0 and encryption type 0, + that can be found on 3 channels: 1 6 and 11 , + SSID bcast type is unknown (directed probe will be sent if AP not found) + and must meet -40dBm RSSI + + test2 - with auth and enrytption type 4/4 + that can be found on 6 channels 1, 2, 3, 4, 5 and 6 + bcast type is non-bcast (directed probe will be sent) + and must not meet any RSSI threshold + + scan every 5 seconds 2 times, scan every 300 seconds until stopped + -----------------------------------------------------------------------*/ + + /* making sure argument string ends with '\0' */ + len = (wrqu->data.length-nOffset) + 1; + data = vos_mem_malloc(len); + if (NULL == data) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("fail to allocate memory %zu"), len); + return -EINVAL; + } + vos_mem_zero(data, len); + vos_mem_copy(data, &extra[nOffset], (len-1)); + ptr = data; + + if (1 != sscanf(ptr," %hhu%n", &(pnoRequest.enable), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO enable input is not valid %s",ptr); + vos_mem_free(data); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pnoRequest.enable ) + { + /*Disable PNO*/ + memset(&pnoRequest, 0, sizeof(pnoRequest)); + status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), + &pnoRequest, + pAdapter->sessionId, + found_pref_network_cb, pAdapter); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: failed to disable PNO", __func__); + vos_mem_free(data); + return VOS_STATUS_E_FAILURE; + } + pHddCtx->isPnoEnable = FALSE; + vos_mem_free(data); + return VOS_STATUS_SUCCESS; + } + + if (TRUE == pHddCtx->isPnoEnable) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("already PNO is enabled")); + vos_mem_free(data); + return -EBUSY; + } + pHddCtx->isPnoEnable = TRUE; + + ptr += nOffset; + + if (1 != sscanf(ptr," %hhu %n", &(pnoRequest.ucNetworksCount), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO count input not valid %s",ptr); + goto error; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO enable %d networks count %d offset %d", + pnoRequest.enable, + pnoRequest.ucNetworksCount, + nOffset); + + /* Parameters checking: + ucNetworksCount has to be larger than 0*/ + if (( 0 == pnoRequest.ucNetworksCount ) || + ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS )) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Network input is not correct"); + goto error; + } + + ptr += nOffset; + + pnoRequest.aNetworks = + vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount); + if (pnoRequest.aNetworks == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory aNetworks %u"), + (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount); + goto error; + } + vos_mem_zero(pnoRequest.aNetworks, + sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount); + + for ( i = 0; i < pnoRequest.ucNetworksCount; i++ ) + { + + pnoRequest.aNetworks[i].ssId.length = 0; + + ucParams = sscanf(ptr," %hhu %n", + &(pnoRequest.aNetworks[i].ssId.length),&nOffset); + + if (1 != ucParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO ssid length input is not valid %s",ptr); + goto error; + } + + if (( 0 == pnoRequest.aNetworks[i].ssId.length ) || + ( pnoRequest.aNetworks[i].ssId.length > 32 ) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "SSID Len %d is not correct for network %d", + pnoRequest.aNetworks[i].ssId.length, i); + goto error; + } + + /*Advance to SSID*/ + ptr += nOffset; + + memcpy(pnoRequest.aNetworks[i].ssId.ssId, ptr, + pnoRequest.aNetworks[i].ssId.length); + ptr += pnoRequest.aNetworks[i].ssId.length; + + ucParams = sscanf(ptr," %u %u %hhu %n", + &(pnoRequest.aNetworks[i].authentication), + &(pnoRequest.aNetworks[i].encryption), + &(pnoRequest.aNetworks[i].ucChannelCount), + &nOffset); + + if ( 3 != ucParams ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Incorrect cmd %s",ptr); + goto error; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO len %d ssid 0x%08x%08x%08x%08x%08x%08x%08x%08x" + "auth %d encry %d channel count %d offset %d", + pnoRequest.aNetworks[i].ssId.length, + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[0]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[4]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[8]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[12]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[16]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[20]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[24]), + *((v_U32_t *) &pnoRequest.aNetworks[i].ssId.ssId[28]), + pnoRequest.aNetworks[i].authentication, + pnoRequest.aNetworks[i].encryption, + pnoRequest.aNetworks[i].ucChannelCount, + nOffset ); + + /*Advance to channel list*/ + ptr += nOffset; + + if (SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Incorrect number of channels"); + goto error; + } + + if ( 0 != pnoRequest.aNetworks[i].ucChannelCount) + { + for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++) + { + if (1 != sscanf(ptr," %hhu %n", + &(pnoRequest.aNetworks[i].aChannels[j]), + &nOffset)) + { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO network channel input is not valid %s",ptr); + goto error; + } + if (!IS_CHANNEL_VALID(pnoRequest.aNetworks[i].aChannels[j])) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid channel: %hhu"), + pnoRequest.aNetworks[i].aChannels[j]); + goto error; + } + + /*Advance to next channel number*/ + ptr += nOffset; + } + } + + if (1 != sscanf(ptr," %u %n", + &(pnoRequest.aNetworks[i].bcastNetwType), + &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO broadcast network type input is not valid %s",ptr); + goto error; + } + if (pnoRequest.aNetworks[i].bcastNetwType > 2) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid bcast nw type: %u"), + pnoRequest.aNetworks[i].bcastNetwType); + goto error; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO bcastNetwType %d offset %d", + pnoRequest.aNetworks[i].bcastNetwType, + nOffset ); + + /*Advance to rssi Threshold*/ + ptr += nOffset; + + if (1 != sscanf(ptr," %hhu %n", + &(pnoRequest.aNetworks[i].rssiThreshold), + &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "PNO rssi threshold input is not valid %s",ptr); + goto error; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO rssi %d offset %d", + pnoRequest.aNetworks[i].rssiThreshold, + nOffset ); + /*Advance to next network*/ + ptr += nOffset; + }/*For ucNetworkCount*/ + + ucParams = sscanf(ptr," %hhu %n", + &(pnoRequest.scanTimers.ucScanTimersCount), + &nOffset); + + /*Read the scan timers*/ + if (( 1 == ucParams ) && ( pnoRequest.scanTimers.ucScanTimersCount > 0 )) + { + ptr += nOffset; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Scan timer count %d offset %d", + pnoRequest.scanTimers.ucScanTimersCount, + nOffset ); + + if ( SIR_PNO_MAX_SCAN_TIMERS < pnoRequest.scanTimers.ucScanTimersCount ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Incorrect cmd - too many scan timers"); + goto error; + } + + for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++ ) + { + ucParams = sscanf(ptr," %u %u %n", + &(pnoRequest.scanTimers.aTimerValues[i].uTimerValue), + &( pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat), + &nOffset); + + if (2 != ucParams) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Incorrect cmd - diff params then expected %d", ucParams); + goto error; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "PNO Timer value %d Timer repeat %d offset %d", + pnoRequest.scanTimers.aTimerValues[i].uTimerValue, + pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat, + nOffset ); + + ptr += nOffset; + } + + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "No scan timers provided param count %d scan timers %d", + ucParams, pnoRequest.scanTimers.ucScanTimersCount ); + + /*Scan timers defaults to 5 minutes*/ + pnoRequest.scanTimers.ucScanTimersCount = 1; + pnoRequest.scanTimers.aTimerValues[0].uTimerValue = 60; + pnoRequest.scanTimers.aTimerValues[0].uTimerRepeat = 0; + } + + ucParams = sscanf(ptr," %hhu %n",&(ucMode), &nOffset); + + pnoRequest.modePNO = ucMode; + /*for LA we just expose suspend option*/ + if (( 1 != ucParams )||( ucMode >= SIR_PNO_MODE_MAX )) + { + pnoRequest.modePNO = SIR_PNO_MODE_ON_SUSPEND; + } + pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE); + if (pnoRequest.p24GProbeTemplate == NULL){ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory p24GProbeTemplate %u"), + SIR_PNO_MAX_PB_REQ_SIZE); + goto error; + } + + pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE); + if (pnoRequest.p5GProbeTemplate == NULL){ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory p5GProbeTemplate %u"), + SIR_PNO_MAX_PB_REQ_SIZE); + goto error; + } + + vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE); + vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE); + + status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest, + pAdapter->sessionId, + found_pref_network_cb, pAdapter); + if (eHAL_STATUS_SUCCESS == status) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: PNO enabled", __func__); + vos_mem_free(data); + return VOS_STATUS_SUCCESS; + } +error: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to enable PNO", __func__); + pHddCtx->isPnoEnable = FALSE; + if (pnoRequest.aNetworks) + vos_mem_free(pnoRequest.aNetworks); + if (pnoRequest.p24GProbeTemplate) + vos_mem_free(pnoRequest.p24GProbeTemplate); + if (pnoRequest.p5GProbeTemplate) + vos_mem_free(pnoRequest.p5GProbeTemplate); + + vos_mem_free(data); + return VOS_STATUS_E_FAILURE; +}/*iw_set_pno*/ + +VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + v_U8_t rssiThreshold = 0; + v_U8_t nRead; + + nRead = sscanf(extra + nOffset,"%hhu", + &rssiThreshold); + + if ( 1 != nRead ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "Incorrect format"); + return VOS_STATUS_E_FAILURE; + } + + sme_SetRSSIFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), rssiThreshold); + return VOS_STATUS_SUCCESS; +} + + +static int __iw_set_pno_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + int ret = 0; + VOS_STATUS status; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Set PNO Private"); + + status = iw_set_pno(dev,info,wrqu,extra,0); + + EXIT(); + return status; +} + +static int iw_set_pno_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_pno_priv(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} +#endif /*FEATURE_WLAN_SCAN_PNO*/ + +//Common function to SetBand +int hdd_setBand(struct net_device *dev, u8 ui_band) +{ + hdd_adapter_t *pAdapter; + tHalHandle hHal; + hdd_context_t *pHddCtx; + hdd_scaninfo_t *pScanInfo = NULL; + eCsrBand band; + int wait_result; + eCsrBand currBand = eCSR_BAND_MAX; + eCsrBand connectedBand; + tpAniSirGlobal pMac; + int retval = SEND_CHANNEL_CHANGE_EVENT; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + retval = wlan_hdd_validate_context(pHddCtx); + if (0 != retval) + { + return retval; + } + hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Hal Context is NULL",__func__); + return -EINVAL; + } + pMac = PMAC_STRUCT(hHal); + + switch(ui_band) + { + case WLAN_HDD_UI_BAND_AUTO: + band = eCSR_BAND_ALL; + break; + case WLAN_HDD_UI_BAND_5_GHZ: + band = eCSR_BAND_5G; + break; + case WLAN_HDD_UI_BAND_2_4_GHZ: + band = eCSR_BAND_24; + break; + default: + band = eCSR_BAND_MAX; + } + connectedBand = + hdd_connGetConnectedBand(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)); + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change band to %u", + __func__, band); + + if (band == eCSR_BAND_MAX) + { + /* Received change band request with invalid band value */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid band value %u", __func__, ui_band); + return -EINVAL; + } + + if ( (band == eCSR_BAND_24 && pHddCtx->cfg_ini->nBandCapability==2) || + (band == eCSR_BAND_5G && pHddCtx->cfg_ini->nBandCapability==1) ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: band value %u violate INI settings %u", __func__, + band, pHddCtx->cfg_ini->nBandCapability); + return -EIO; + } + + if (band == eCSR_BAND_ALL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, FL("Auto Band " + "received. Setting band same as ini value %d"), + pHddCtx->cfg_ini->nBandCapability); + band = pHddCtx->cfg_ini->nBandCapability; + } + + if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &currBand)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Failed to get current band config", + __func__); + return -EIO; + } + + if (currBand != band) + { + if ( band == eCSR_BAND_5G ) + { + /* Return failure if current country code is world regulatory domain*/ + if( (pMac->scan.countryCodeCurrent[0] == '0' && + pMac->scan.countryCodeCurrent[1] == '0') ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: failed to set the band value to %u as country code is 00", + __func__, band); + return -EAGAIN; + } + } + + /* Change band request received. + * Abort pending scan requests, flush the existing scan results, + * and change the band capability + */ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Current band value = %u, new setting %u ", + __func__, currBand, band); + + /* We need to change the band and flush the scan results here itself + * as we may get timeout for disconnection in which we will return + * with out doing any of these + */ + if (eHAL_STATUS_SUCCESS != sme_SetFreqBand(hHal, (eCsrBand)band)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: failed to set the band value to %u ", + __func__, band); + return -EINVAL; + } + if(currBand == eCSR_BAND_24 || currBand == eCSR_BAND_5G) + { + tANI_U8 curr_country[WNI_CFG_COUNTRY_CODE_LEN]; + curr_country[0]=pMac->scan.countryCodeCurrent[0]; + curr_country[1]=pMac->scan.countryCodeCurrent[1]; + INIT_COMPLETION(pHddCtx->linux_reg_req); + /* As currunt band is already set to 2.4Ghz/5Ghz we dont have all channel + * information available in NV so to get the channel information from kernel + * we need to send regulatory hint for the currunt country + * And to set the same country again we need to set the dummy country + * first and then the actual country. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + regulatory_hint_user("00", NL80211_USER_REG_HINT_USER); +#else + regulatory_hint_user("00"); +#endif + wait_result = wait_for_completion_interruptible_timeout( + &pHddCtx->linux_reg_req, + msecs_to_jiffies(LINUX_REG_WAIT_TIME)); + + /* if the country information does not exist with the kernel, + then the driver callback would not be called */ + + if (wait_result >= 0) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "runtime country code is found in kernel db"); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "runtime country code is not found" + " in kernel db"); + } + + pMac->roam.configParam.fEnforceCountryCode = eANI_BOOLEAN_TRUE; + + /* + * Update 11dcountry and current country here as the hint + * with 00 results in 11d and current country with 00 + */ + vos_mem_copy(pMac->scan.countryCode11d, curr_country, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCodeCurrent, curr_country, + WNI_CFG_COUNTRY_CODE_LEN); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + regulatory_hint_user(curr_country, NL80211_USER_REG_HINT_USER); +#else + regulatory_hint_user(curr_country); +#endif + wait_result = wait_for_completion_interruptible_timeout( + &pHddCtx->linux_reg_req, + msecs_to_jiffies(LINUX_REG_WAIT_TIME)); + + /* if the country information does not exist with the kernel, + then the driver callback would not be called */ + if (wait_result >= 0) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "runtime country code is found in kernel db"); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "runtime country code is not found" + " in kernel db"); + } + + retval = DO_NOT_SEND_CHANNEL_CHANGE_EVENT; + } + else + { +#ifdef CONFIG_ENABLE_LINUX_REG + vos_update_nv_table_from_wiphy_band((void *)pHddCtx, + (void *)pHddCtx->wiphy, (eCsrBand)band); +#else + wlan_hdd_cfg80211_update_band( pHddCtx->wiphy, (eCsrBand)band ); +#endif + + } + pScanInfo = &pHddCtx->scan_info; + if ((pScanInfo != NULL) && pHddCtx->scan_info.mScanPending) + { + hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId, + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE); + } + sme_FilterScanResults(hHal, pAdapter->sessionId); + + if (band != eCSR_BAND_ALL && + hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)) && + (connectedBand != band)) + { + eHalStatus status = eHAL_STATUS_SUCCESS; + long lrc; + + /* STA already connected on current band, So issue disconnect first, + * then change the band*/ + + hddLog(VOS_TRACE_LEVEL_INFO, + "%s STA connected in band %u, Changing band to %u, Issuing Disconnect." + , __func__, csrGetCurrentBand(hHal), band); + + INIT_COMPLETION(pAdapter->disconnect_comp_var); + + status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + + if ( eHAL_STATUS_SUCCESS != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s csrRoamDisconnect failure, returned %d", + __func__, (int)status ); + return -EINVAL; + } + + lrc = wait_for_completion_interruptible_timeout( + &pAdapter->disconnect_comp_var, + msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT)); + + if (lrc <= 0) { + + hddLog(VOS_TRACE_LEVEL_ERROR,"%s: %s while waiting for csrRoamDisconnect ", + __func__, (0 == lrc) ? "Timeout" : "Interrupt"); + + return (0 == lrc) ? -ETIMEDOUT : -EINTR; + } + } + } + EXIT(); + if (TRUE == pHddCtx->isSetBandByNL) + return 0; + else + return retval; +} + +int hdd_setBand_helper(struct net_device *dev, const char *command) +{ + u8 band; + + /*convert the band value from ascii to integer*/ + band = command[WLAN_HDD_UI_SET_BAND_VALUE_OFFSET] - '0'; + + return hdd_setBand(dev, band); + +} + +static int __iw_set_band_config(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int *value = (int *)extra; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + return hdd_setBand(dev, value[0]); +} + +static int iw_set_band_config(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_band_config(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +static int get_fwr_memdump(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int ret; + ENTER(); + // HddCtx sanity + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + if( !pHddCtx->cfg_ini->enableFwrMemDump || + (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED))) + { + hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported")); + return -EINVAL; + } + ret = wlan_hdd_fw_mem_dump_req(pHddCtx); + + EXIT(); + return ret; +} + +static int __iw_set_power_params_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + char *ptr; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Set power params Private"); + + if (!capable(CAP_NET_ADMIN)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("permission check failed")); + return -EPERM; + } + + /* ODD number is used for set, copy data using copy_from_user */ + ptr = mem_alloc_copy_from_user_helper(wrqu->data.pointer, + wrqu->data.length); + if (NULL == ptr) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "mem_alloc_copy_from_user_helper fail"); + return -ENOMEM; + } + + ret = iw_set_power_params(dev, info, wrqu, ptr, 0); + kfree(ptr); + return ret; +} + +static int iw_set_power_params_priv(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __iw_set_power_params_priv(dev, info, wrqu, extra); + vos_ssr_unprotect(__func__); + + return ret; +} + +/*string based input*/ +VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra, int nOffset) +{ + hdd_adapter_t *pAdapter; + hdd_context_t *pHddCtx; + tSirSetPowerParamsReq powerRequest; + char *ptr; + v_U8_t ucType; + v_U32_t uTotalSize, uValue; + int ret = 0; + + ENTER(); + pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Adapter is NULL",__func__); + return -EINVAL; + } + + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + return ret; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Power Params data len %d data %s", + wrqu->data.length, + extra); + + if (wrqu->data.length <= nOffset ) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "set power param input is not correct"); + return VOS_STATUS_E_FAILURE; + } + + uTotalSize = wrqu->data.length - nOffset; + + /*----------------------------------------------------------------------- + Input is string based and expected to be like this: + + ... + + e.g: + 1 2 2 3 3 0 4 1 5 1 + + e.g. setting just a few: + 1 2 4 1 + + parameter types: + ----------------------------- + 1 - Ignore DTIM + 2 - Listen Interval + 3 - Broadcast Multicas Filter + 4 - Beacon Early Termination + 5 - Beacon Early Termination Interval + -----------------------------------------------------------------------*/ + powerRequest.uIgnoreDTIM = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uListenInterval = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uBcastMcastFilter = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uEnableBET = SIR_NOCHANGE_POWER_VALUE; + powerRequest.uBETInterval = SIR_NOCHANGE_POWER_VALUE; + + ptr = extra + nOffset; + + while ( uTotalSize ) + { + if (1 != sscanf(ptr,"%hhu %n", &(ucType), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter type %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + uTotalSize -= nOffset; + + if (!uTotalSize) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter type : %d with no value at offset %d", + ucType, nOffset); + return VOS_STATUS_E_FAILURE; + } + + ptr += nOffset; + + if (1 != sscanf(ptr,"%u %n", &(uValue), &nOffset)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter value %s",ptr); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Power request parameter %d value %d offset %d", + ucType, uValue, nOffset); + + switch (ucType) + { + case eSIR_IGNORE_DTIM: + powerRequest.uIgnoreDTIM = uValue; + break; + case eSIR_LISTEN_INTERVAL: + powerRequest.uListenInterval = uValue; + break; + case eSIR_MCAST_BCAST_FILTER: + powerRequest.uBcastMcastFilter = uValue; + break; + case eSIR_ENABLE_BET: + powerRequest.uEnableBET = uValue; + break; + case eSIR_BET_INTERVAL: + powerRequest.uBETInterval = uValue; + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Invalid input parameter type : %d with value: %d at offset %d", + ucType, uValue, nOffset); + return VOS_STATUS_E_FAILURE; + } + + uTotalSize -= nOffset; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "Power request parameter %d Total size", + uTotalSize); + ptr += nOffset; + /* This is added for dynamic Tele LI enable (0xF1) /disable (0xF0)*/ + if(!(uTotalSize - nOffset) && + (powerRequest.uListenInterval != SIR_NOCHANGE_POWER_VALUE)) + { + uTotalSize = 0; + } + + }/*Go for as long as we have a valid string*/ + + /* put the device into full power*/ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE); + + /* Apply the power save params*/ + sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest, FALSE); + + /* put the device back to power save*/ + wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO); + + EXIT(); + return VOS_STATUS_SUCCESS; +}/*iw_set_power_params*/ + +// tdlsoffchan +#ifdef FEATURE_WLAN_TDLS + +int iw_set_tdlsoffchannel(hdd_context_t *pHddCtx, int offchannel) +{ + if (offchannel < 0 || offchannel > 165) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Invalid tdls off channel %u", + __func__, offchannel); + return -1; + + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls off channel from %d to %d", + __func__, tdlsOffCh, offchannel); + + tdlsOffCh = offchannel; + return 0; +} + +int iw_set_tdlssecoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset) +{ + if (offchanoffset == 0) + { + tdlsOffChBwOffset = 1; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls secondary off channel offset to %u", + __func__, tdlsOffChBwOffset); + + return 0; + + } + + if ( offchanoffset == 40 ) + { + tdlsOffChBwOffset = 2; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls secondary off channel offset to %u", + __func__, tdlsOffChBwOffset); + + return 0; + + } + if (offchanoffset == -40) + { + tdlsOffChBwOffset = 3; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls secondary off channel offset to %u", + __func__, tdlsOffChBwOffset); + + return 0; + + } + + if ((offchanoffset == 80) && + (TRUE == sme_IsFeatureSupportedByFW(DOT11AC)) && + (TRUE == sme_IsFeatureSupportedByDriver(DOT11AC))) + { + tdlsOffChBwOffset = 4; + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: change tdls secondary off channel offset to %u", + __func__, tdlsOffChBwOffset); + + return 0; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Invalid tdls secondary off channel offset %d", + __func__, offchanoffset); + return -1; +} + +int iw_set_tdlsoffchannelmode(hdd_adapter_t *pAdapter, int offchanmode) +{ + hddTdlsPeer_t *connPeer = NULL; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tSirMacAddr peerMac; + if (offchanmode < 0 || offchanmode > 4) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid tdls off channel mode %d", + __func__, offchanmode); + return -1; + } + + if (eConnectionState_Associated != pHddStaCtx->conn_info.connState) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: tdls off channel mode req in not associated state %d", + __func__, offchanmode); + return -1; + } + + if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode || + eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode) + { + /* Send TDLS Channel Switch Request to connected peer */ + mutex_lock(&pHddCtx->tdls_lock); + connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter); + if (NULL == connPeer) { + mutex_unlock(&pHddCtx->tdls_lock); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: No TDLS Connected Peer", __func__); + return -1; + } + vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr)); + mutex_unlock(&pHddCtx->tdls_lock); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s: TDLS Connection not supported", __func__); + return -1; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + ("%s: TDLS Channel Switch in swmode=%d"), + __func__, offchanmode); + + switch (offchanmode) + { + case 1:/*Enable*/ + case 2:/*Disable*/ + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: change tdls off channel mode %d tdls_off_channel %d offchanoffset %d ", + __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset); + if (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) + { + + sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, peerMac, + tdlsOffCh, tdlsOffChBwOffset, + offchanmode); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: TDLS Off Channel not supported", __func__); + return -1; + } + break; + } + case 3: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: change tdls off channel mode %d REJREQ 3 tdls_off_channel %d offchanoffset %d ", + __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset); + + break; + } + case 4: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: change tdls off channel mode %d UNSOLRESP 4 tdls_off_channel %d offchanoffset %d ", + __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset); + break; + } + default: + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: change tdls off channel mode %d Not SET 0 tdls_off_channel %d offchanoffset %d ", + __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset); + break; + } + + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls off channel mode to %u", + __func__, offchanmode); + return 0; +} +#endif + +// Define the Wireless Extensions to the Linux Network Device structure +// A number of these routines are NULL (meaning they are not implemented.) + +static const iw_handler we_handler[] = +{ + (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */ + (iw_handler) iw_get_name, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) iw_set_freq, /* SIOCSIWFREQ */ + (iw_handler) iw_get_freq, /* SIOCGIWFREQ */ + (iw_handler) iw_set_mode, /* SIOCSIWMODE */ + (iw_handler) iw_get_mode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* SIOCSIWRANGE */ + (iw_handler) iw_get_range, /* SIOCGIWRANGE */ + (iw_handler) iw_set_priv, /* SIOCSIWPRIV */ + (iw_handler) NULL, /* SIOCGIWPRIV */ + (iw_handler) NULL, /* SIOCSIWSTATS */ + (iw_handler) NULL, /* SIOCGIWSTATS */ + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ + (iw_handler) iw_set_ap_address, /* SIOCSIWAP */ + (iw_handler) iw_get_ap_address, /* SIOCGIWAP */ + (iw_handler) iw_set_mlme, /* SIOCSIWMLME */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ + (iw_handler) iw_set_scan, /* SIOCSIWSCAN */ + (iw_handler) iw_get_scan, /* SIOCGIWSCAN */ + (iw_handler) iw_set_essid, /* SIOCSIWESSID */ + (iw_handler) iw_get_essid, /* SIOCGIWESSID */ + (iw_handler) iw_set_nick, /* SIOCSIWNICKN */ + (iw_handler) iw_get_nick, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */ + (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */ + (iw_handler) iw_set_rts_threshold,/* SIOCSIWRTS */ + (iw_handler) iw_get_rts_threshold,/* SIOCGIWRTS */ + (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */ + (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */ + (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */ + (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */ + (iw_handler) iw_set_retry, /* SIOCSIWRETRY */ + (iw_handler) iw_get_retry, /* SIOCGIWRETRY */ + (iw_handler) iw_set_encode, /* SIOCSIWENCODE */ + (iw_handler) iw_get_encode, /* SIOCGIWENCODE */ + (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */ + (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) iw_set_genie, /* SIOCSIWGENIE */ + (iw_handler) iw_get_genie, /* SIOCGIWGENIE */ + (iw_handler) iw_set_auth, /* SIOCSIWAUTH */ + (iw_handler) iw_get_auth, /* SIOCGIWAUTH */ + (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */ + (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */ + (iw_handler) NULL, /* SIOCSIWPMKSA */ +}; + +static const iw_handler we_private[] = { + + [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, //set priv ioctl + [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, //get priv ioctl + [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, //get priv ioctl + [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone, + [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone, + [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, //action priv ioctl + [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_hdd_set_var_ints_getnone, + [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec, + [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec, + [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec, + [WLAN_PRIV_SET_NONE_GET_THREE_INT - SIOCIWFIRSTPRIV] = + iw_setnone_get_threeint, +#ifdef FEATURE_OEM_DATA_SUPPORT + [WLAN_PRIV_SET_OEM_DATA_REQ - SIOCIWFIRSTPRIV] = iw_set_oem_data_req, //oem data req Specifc + [WLAN_PRIV_GET_OEM_DATA_RSP - SIOCIWFIRSTPRIV] = iw_get_oem_data_rsp, //oem data req Specifc +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties, +#endif + [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload, + [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics, + [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] = iw_set_keepalive_params +#ifdef WLAN_FEATURE_PACKET_FILTERING + , + [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_packet_filter_params +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + , + [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno_priv +#endif + , + [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config, + [WLAN_PRIV_SET_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_set_dynamic_mcbc_filter, + [WLAN_PRIV_CLEAR_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_clear_dynamic_mcbc_filter, + [WLAN_SET_POWER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_power_params_priv, + [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed_priv, +}; + +/*Maximum command length can be only 15 */ +static const struct iw_priv_args we_private_args[] = { + + { WE_SET_MONITOR_STATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "monitor" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_SET_11D_STATE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "set11Dstate" }, + + { WE_WOWL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "wowl" }, + + { WE_SET_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setPower" }, + + { WE_SET_MAX_ASSOC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setMaxAssoc" }, + + { WE_SET_SAP_AUTO_CHANNEL_SELECTION, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setAutoChannel" }, + + { WE_SET_DATA_INACTIVITY_TO, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "inactivityTO" }, + + { WE_SET_MAX_TX_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setMaxTxPower" }, + + { WE_SET_MAX_TX_POWER_2_4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower2G" }, + + { WE_SET_MAX_TX_POWER_5_0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower5G" }, + + /* SAP has TxMax whereas STA has MaxTx, adding TxMax for STA + * as well to keep same syntax as in SAP. Now onwards, STA + * will support both */ + { WE_SET_MAX_TX_POWER, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTxMaxPower" }, + + /* set Higher DTIM Transition (DTIM1 to DTIM3) + * 1 = enable and 0 = disable */ + { + WE_SET_HIGHER_DTIM_TRANSITION, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setHDtimTransn" }, + + { WE_SET_TM_LEVEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setTmLevel" }, + + { WE_ENABLE_STRICT_FCC_REG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "setStrictFCCreg" }, + + { WE_SET_DEBUG_LOG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setDbgLvl" }, +#ifdef FEATURE_WLAN_TDLS + { + WE_SET_TDLS_OFF_CHAN, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdlsoffchan" }, + { + WE_SET_TDLS_SEC_OFF_CHAN_OFFSET, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdlsecchnoffst" }, + { + WE_SET_TDLS_OFF_CHAN_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdlsoffchnmode" }, +#endif + + { WE_SET_SCAN_BAND_PREFERENCE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "set_scan_pref" }, + { + WE_GET_FRAME_LOG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "getFrameLogs" }, + + { WE_SET_MIRACAST_VENDOR_CONFIG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setMiracstConf" }, + +#ifdef FEATURE_WLAN_TDLS + { + WE_SET_TDLS_2040_BSS_COEXISTENCE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdls_2040bsscox" }, +#endif + { WE_SET_RTS_CTS_HTVHT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setRtsCtsHtVht" }, + { WE_SET_PKT_STATS_ENABLE_DISABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setPktStats" }, + { WE_SET_PROXIMITY_ENABLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setProximity" }, + +#ifdef WLAN_FEATURE_TSF + { WE_CAP_TSF, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "cap_tsf" }, +#endif + { WE_SET_MODULATED_DTIM, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setModDTIM" }, + { + WLAN_SET_DYNNAMIC_AGGREGATION, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, "setAggregation" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_NONE_GET_INT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "" }, + + /* handlers for sub-ioctl */ + { WE_GET_11D_STATE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get11Dstate" }, + + { WE_IBSS_STATUS, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getAdhocStatus" }, + + { WE_PMC_STATE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "pmcState" }, + + { WE_GET_WLAN_DBG, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getwlandbg" }, + + { WE_GET_MAX_ASSOC, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getMaxAssoc" }, + + { WE_GET_WDI_DBG, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getwdidbg" }, + + { WE_GET_SAP_AUTO_CHANNEL_SELECTION, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getAutoChannel" }, + + { WE_GET_CONCURRENCY_MODE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getconcurrency" }, + + { WE_GET_SCAN_BAND_PREFERENCE, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "get_scan_pref"}, + + { WE_GET_ANTENA_DIVERSITY_SELECTION, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getCurAnt"}, + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_CHAR_GET_NONE, + IW_PRIV_TYPE_CHAR| 512, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_WOWL_ADD_PTRN, + IW_PRIV_TYPE_CHAR| 512, + 0, + "wowlAddPtrn" }, + + { WE_WOWL_DEL_PTRN, + IW_PRIV_TYPE_CHAR| 512, + 0, + "wowlDelPtrn" }, + +#if defined WLAN_FEATURE_VOWIFI + /* handlers for sub-ioctl */ + { WE_NEIGHBOR_REPORT_REQUEST, + IW_PRIV_TYPE_CHAR | 512, + 0, + "neighbor" }, +#endif + { WE_SET_AP_WPS_IE, + IW_PRIV_TYPE_CHAR| 512, + 0, + "set_ap_wps_ie" }, + + { WE_SET_CONFIG, + IW_PRIV_TYPE_CHAR| 512, + 0, + "setConfig" }, + + { WE_SET_ENCRYPT_MSG, + IW_PRIV_TYPE_CHAR| 512, + 0, + "encryptMsg" }, + + + /* handlers for main ioctl */ + { WLAN_PRIV_SET_THREE_INT_GET_NONE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_SET_WLAN_DBG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setwlandbg" }, + + { WE_SET_WDI_DBG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setwdidbg" }, + + { WE_SET_SAP_CHANNELS, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + 0, + "setsapchannels" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_GET_CHAR_SET_NONE, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "" }, + + /* handlers for sub-ioctl */ + { WE_WLAN_VERSION, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "version" }, + { WE_GET_STATS, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getStats" }, + { WE_GET_STATES, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getHostStates" }, + { WE_GET_CFG, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getConfig" }, +#ifdef WLAN_FEATURE_11AC + { WE_GET_RSSI, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getRSSI" }, +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + { WE_GET_ROAM_RSSI, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getRoamRSSI" }, +#endif + { WE_GET_WMM_STATUS, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getWmmStatus" }, + { + WE_GET_CHANNEL_LIST, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getChannelList" }, +#ifdef FEATURE_WLAN_TDLS + { + WE_GET_TDLS_PEERS, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getTdlsPeers" }, +#endif +#ifdef WLAN_FEATURE_11W + { + WE_GET_11W_INFO, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getPMFInfo" }, +#endif +#ifdef WLAN_FEATURE_RMC + { + WE_GET_IBSS_STA_INFO, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getIbssSTAs" }, +#endif + { WE_GET_SNR, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getSNR" }, +#ifdef FEATURE_OEM_DATA_SUPPORT + { + WE_GET_OEM_DATA_CAP, + 0, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + "getOemDataCap" }, +#endif /* FEATURE_OEM_DATA_SUPPORT */ + /* handlers for main ioctl */ + { WLAN_PRIV_SET_NONE_GET_NONE, + 0, + 0, + "" }, + + /* handlers for sub-ioctl */ + { WE_CLEAR_STATS, + 0, + 0, + "clearStats" }, + { WE_INIT_AP, + 0, + 0, + "initAP" }, +#ifdef WLAN_FEATURE_RMC + { + WE_IBSS_GET_PEER_INFO_ALL, + 0, + 0, + "ibssPeerInfoAll" }, +#endif + { WE_STOP_AP, + 0, + 0, + "exitAP" }, +#ifdef WLAN_BTAMP_FEATURE + { WE_ENABLE_AMP, + 0, + 0, + "enableAMP" }, + { WE_DISABLE_AMP, + 0, + 0, + "disableAMP" }, +#endif /* WLAN_BTAMP_FEATURE */ + { WE_ENABLE_DXE_STALL_DETECT, + 0, + 0, + "dxeStallDetect" }, + { WE_DISPLAY_DXE_SNAP_SHOT, + 0, + 0, + "dxeSnapshot" }, + { WE_DISPLAY_DATAPATH_SNAP_SHOT, + 0, + 0, + "dataSnapshot"}, + { + WE_SET_REASSOC_TRIGGER, + 0, + 0, + "reassoc" }, + { + WE_STOP_OBSS_SCAN, + 0, + 0, + "stopOBSSScan" }, + { + WE_DUMP_ROAM_TIMER_LOG, + 0, + 0, + "dumpRoamDelay" }, + { + WE_RESET_ROAM_TIMER_LOG, + 0, + 0, + "resetRoamDelay" }, + { + WE_GET_FW_LOGS, + 0, + 0, + "getFwLogs" }, + { + WE_GET_FW_MEMDUMP, + 0, + 0, + "getFwMemDump" }, + /* handlers for main ioctl */ + { WLAN_PRIV_SET_VAR_INT_GET_NONE, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "" }, + + + + /* handlers for sub-ioctl */ + { WE_LOG_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dump" }, +#ifdef WLAN_FEATURE_RMC + { WE_IBSS_GET_PEER_INFO, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "ibssPeerInfo" }, +#endif + + /* handlers for sub-ioctl */ + { WE_MTRACE_SELECTIVE_MODULE_LOG_ENABLE_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setdumplog" }, + + { WE_MTRACE_DUMP_CMD, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "dumplog" }, + + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_CREDENTIAL, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccCrdnl" }, + + /* handlers for sub ioctl */ + { + WE_MCC_CONFIG_PARAMS, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setMccConfig" }, + +#ifdef FEATURE_WLAN_TDLS + /* handlers for sub ioctl */ + { + WE_TDLS_CONFIG_PARAMS, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "setTdlsConfig" }, +#endif + + { + WE_CONFIGURE_MONITOR_MODE, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "MonitorModeConf" }, + + { + WE_SET_MONITOR_MODE_FILTER, + IW_PRIV_TYPE_INT | MAX_VAR_ARGS, + 0, + "MonitorFilter" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_ADD_TSPEC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "addTspec" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_DEL_TSPEC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "delTspec" }, + + /* handlers for main ioctl */ + { WLAN_PRIV_GET_TSPEC, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + "getTspec" }, + /* handlers for main ioctl */ + { WLAN_PRIV_SET_NONE_GET_THREE_INT, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + "" }, +#ifdef WLAN_FEATURE_TSF + { WE_GET_TSF, + 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + "get_tsf" }, +#endif +#ifdef FEATURE_OEM_DATA_SUPPORT + /* handlers for main ioctl - OEM DATA */ + { + WLAN_PRIV_SET_OEM_DATA_REQ, + IW_PRIV_TYPE_BYTE | sizeof(struct iw_oem_data_req) | IW_PRIV_SIZE_FIXED, + 0, + "set_oem_data_req" }, + + /* handlers for main ioctl - OEM DATA */ + { + WLAN_PRIV_GET_OEM_DATA_RSP, + 0, + IW_PRIV_TYPE_BYTE | MAX_OEM_DATA_RSP_LEN, + "get_oem_data_rsp" }, +#endif + + /* handlers for main ioctl - host offload */ + { + WLAN_PRIV_SET_HOST_OFFLOAD, + IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest), + 0, + "setHostOffload" }, + + { + WLAN_GET_WLAN_STATISTICS, + 0, + IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN, + "getWlanStats" }, + + { + WLAN_SET_KEEPALIVE_PARAMS, + IW_PRIV_TYPE_BYTE | sizeof(tKeepAliveRequest) | + IW_PRIV_SIZE_FIXED, + 0, + "setKeepAlive" }, +#ifdef WLAN_FEATURE_PACKET_FILTERING + { + WLAN_SET_PACKET_FILTER_PARAMS, + IW_PRIV_TYPE_BYTE | sizeof(tPacketFilterCfg), + 0, + "setPktFilter" }, +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + { + WLAN_SET_PNO, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + 0, + "setpno" }, +#endif + { + WLAN_SET_BAND_CONFIG, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "SETBAND" }, + /* handlers for dynamic MC BC ioctl */ + { + WLAN_PRIV_SET_MCBC_FILTER, + IW_PRIV_TYPE_BYTE | sizeof(tRcvFltMcAddrList), + 0, + "setMCBCFilter" }, + { + WLAN_PRIV_CLEAR_MCBC_FILTER, + 0, + 0, + "clearMCBCFilter" }, + { + WLAN_SET_POWER_PARAMS, + IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN, + 0, + "setpowerparams" }, + { + WLAN_GET_LINK_SPEED, + IW_PRIV_TYPE_CHAR | 18, + IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed" }, + { + WLAN_PRIV_SET_FTIES, + IW_PRIV_TYPE_CHAR | MAX_FTIE_SIZE, + 0, "set_ft_ies"}, +}; + + + +const struct iw_handler_def we_handler_def = { + .num_standard = sizeof(we_handler) / sizeof(we_handler[0]), + .num_private = sizeof(we_private) / sizeof(we_private[0]), + .num_private_args = sizeof(we_private_args) / sizeof(we_private_args[0]), + + .standard = (iw_handler *)we_handler, + .private = (iw_handler *)we_private, + .private_args = we_private_args, + .get_wireless_stats = get_wireless_stats, +}; + +int hdd_validate_mcc_config(hdd_adapter_t *pAdapter, v_UINT_t staId, v_UINT_t arg1, v_UINT_t arg2, v_UINT_t arg3) +{ + v_U32_t cmd = 288; //Command to RIVA + hdd_context_t *pHddCtx = NULL; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + /* + *configMccParam : specify the bit which needs to be modified + *allowed to update based on wlan_qcom_cfg.ini + * configuration + * Bit 0 : SCHEDULE_TIME_SLICE MIN : 5 MAX : 20 + * Bit 1 : MAX_NULL_SEND_TIME MIN : 1 MAX : 10 + * Bit 2 : TX_EARLY_STOP_TIME MIN : 1 MAX : 10 + * Bit 3 : RX_DRAIN_TIME MIN : 1 MAX : 10 + * Bit 4 : CHANNEL_SWITCH_TIME MIN : 1 MAX : 20 + * Bit 5 : MIN_CHANNEL_TIME MIN : 5 MAX : 20 + * Bit 6 : PARK_BEFORE_TBTT MIN : 1 MAX : 5 + * Bit 7 : MIN_AFTER_DTIM MIN : 5 MAX : 15 + * Bit 8 : TOO_CLOSE_MARGIN MIN : 1 MAX : 3 + * Bit 9 : Reserved + */ + switch (arg1) + { + //Update MCC SCHEDULE_TIME_SLICE parameter + case MCC_SCHEDULE_TIME_SLICE_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0001) + { + if((arg2 >= 5) && (arg2 <= 20)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC MAX_NULL_SEND_TIME parameter + case MCC_MAX_NULL_SEND_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0002) + { + if((arg2 >= 1) && (arg2 <= 10)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC TX_EARLY_STOP_TIME parameter + case MCC_TX_EARLY_STOP_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0004) + { + if((arg2 >= 1) && (arg2 <= 10)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC RX_DRAIN_TIME parameter + case MCC_RX_DRAIN_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0008) + { + if((arg2 >= 1) && (arg2 <= 10)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC CHANNEL_SWITCH_TIME parameter + case MCC_CHANNEL_SWITCH_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0010) + { + if((arg2 >= 1) && (arg2 <= 20)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC MIN_CHANNEL_TIME parameter + case MCC_MIN_CHANNEL_TIME_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0020) + { + if((arg2 >= 5) && (arg2 <= 20)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC PARK_BEFORE_TBTT parameter + case MCC_PARK_BEFORE_TBTT_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0040) + { + if((arg2 >= 1) && (arg2 <= 5)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC MIN_AFTER_DTIM parameter + case MCC_MIN_AFTER_DTIM_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0080) + { + if((arg2 >= 5) && (arg2 <= 15)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + //Update MCC TOO_CLOSE_MARGIN parameter + case MCC_TOO_CLOSE_MARGIN_CFG_PARAM : + if( pHddCtx->cfg_ini->configMccParam & 0x0100) + { + if((arg2 >= 1) && (arg2 <= 3)) + { + logPrintf(hHal, cmd, staId, arg1, arg2, arg3); + } + else + { + hddLog(LOGE, "%s : Enter a valid MCC configuration value",__FUNCTION__); + return 0; + } + } + break; + + default : + hddLog(LOGE, "%s : Uknown / Not allowed to configure parameter : %d", + __FUNCTION__,arg1); + break; + } + return 0; +} + +int hdd_set_wext(hdd_adapter_t *pAdapter) +{ + hdd_wext_state_t *pwextBuf; + hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + + // Now configure the roaming profile links. To SSID and bssid. + pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0; + pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID; + + pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0; + pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId; + + /*Set the numOfChannels to zero to scan all the channels*/ + pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0; + pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL; + + /* Default is no encryption */ + pwextBuf->roamProfile.EncryptionType.numEntries = 1; + pwextBuf->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + + pwextBuf->roamProfile.mcEncryptionType.numEntries = 1; + pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + + pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + + /* Default is no authentication */ + pwextBuf->roamProfile.AuthType.numEntries = 1; + pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_TAURUS; + pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + + /*Set the default scan mode*/ + pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN; + + hdd_clearRoamProfileIe(pAdapter); + + return VOS_STATUS_SUCCESS; + + } + +int hdd_register_wext(struct net_device *dev) + { + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); + VOS_STATUS status; + + ENTER(); + + // Zero the memory. This zeros the profile structure. + memset(pwextBuf, 0,sizeof(hdd_wext_state_t)); + + init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->completion_var); + + + status = hdd_set_wext(pAdapter); + + if(!VOS_IS_STATUS_SUCCESS(status)) { + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_wext failed!!")); + return eHAL_STATUS_FAILURE; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->vosevent))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos event init failed!!")); + return eHAL_STATUS_FAILURE; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->scanevent))) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD scan event init failed!!")); + return eHAL_STATUS_FAILURE; + } + + // Register as a wireless device + dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def; + + EXIT(); + return 0; +} + +int hdd_UnregisterWext(struct net_device *dev) +{ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"In %s %p", __func__, dev); + if (dev != NULL) + { + rtnl_lock(); + dev->wireless_handlers = NULL; + rtnl_unlock(); + } + + return 0; +} + + diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wmm.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wmm.c new file mode 100644 index 000000000000..b91f0c8407fa --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wmm.c @@ -0,0 +1,3215 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + @file wlan_hdd_wmm.c + + This module (wlan_hdd_wmm.h interface + wlan_hdd_wmm.c implementation) + houses all the logic for WMM in HDD. + + On the control path, it has the logic to setup QoS, modify QoS and delete + QoS (QoS here refers to a TSPEC). The setup QoS comes in two flavors: an + explicit application invoked and an internal HDD invoked. The implicit QoS + is for applications that do NOT call the custom QCT WLAN OIDs for QoS but + which DO mark their traffic for priortization. It also has logic to start, + update and stop the U-APSD trigger frame generation. It also has logic to + read WMM related config parameters from the registry. + + On the data path, it has the logic to figure out the WMM AC of an egress + packet and when to signal TL to serve a particular AC queue. It also has the + logic to retrieve a packet based on WMM priority in response to a fetch from + TL. + + The remaining functions are utility functions for information hiding. + + +============================================================================*/ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sme_Api.h" +#include "sapInternal.h" +// change logging behavior based upon debug flag +#ifdef HDD_WMM_DEBUG +#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_FATAL +#else +#define WMM_TRACE_LEVEL_FATAL VOS_TRACE_LEVEL_FATAL +#define WMM_TRACE_LEVEL_ERROR VOS_TRACE_LEVEL_ERROR +#define WMM_TRACE_LEVEL_WARN VOS_TRACE_LEVEL_WARN +#define WMM_TRACE_LEVEL_INFO VOS_TRACE_LEVEL_INFO +#define WMM_TRACE_LEVEL_INFO_HIGH VOS_TRACE_LEVEL_INFO_HIGH +#define WMM_TRACE_LEVEL_INFO_LOW VOS_TRACE_LEVEL_INFO_LOW +#endif + + +#define WLAN_HDD_MAX_DSCP 0x3f + +// DHCP Port number +#define DHCP_SOURCE_PORT 0x4400 +#define DHCP_DESTINATION_PORT 0x4300 + +#define HDD_WMM_UP_TO_AC_MAP_SIZE 8 + +#define IPv6_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5],\ + (a)[6], (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13],\ + (a)[14], (a)[15] +#define IPv6_ADDR_STR "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:"\ + "%02x%02x:%02x%02x" + +const v_U8_t hddWmmUpToAcMap[] = { + WLANTL_AC_BE, + WLANTL_AC_BK, + WLANTL_AC_BK, + WLANTL_AC_BE, + WLANTL_AC_VI, + WLANTL_AC_VI, + WLANTL_AC_VO, + WLANTL_AC_VO +}; + +//Linux based UP -> AC Mapping +const v_U8_t hddLinuxUpToAcMap[8] = { + HDD_LINUX_AC_BE, + HDD_LINUX_AC_BK, + HDD_LINUX_AC_BK, + HDD_LINUX_AC_BE, + HDD_LINUX_AC_VI, + HDD_LINUX_AC_VI, + HDD_LINUX_AC_VO, + HDD_LINUX_AC_VO +}; + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/** + @brief hdd_wmm_enable_tl_uapsd() - function which decides whether and + how to update UAPSD parameters in TL + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +static void hdd_wmm_enable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc = NULL; + VOS_STATUS status; + v_U32_t service_interval; + v_U32_t suspension_interval; + sme_QosWmmDirType direction; + v_BOOL_t psb; + + if (acType >= WLANTL_MAX_AC) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid AC: %d", __func__, acType); + return; + } + + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + // The TSPEC must be valid + if (pAc->wmmAcTspecValid == VOS_FALSE) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid TSPEC", + __func__); + return; + } + + // determine the service interval + if (pAc->wmmAcTspecInfo.min_service_interval) + { + service_interval = pAc->wmmAcTspecInfo.min_service_interval; + } + else if (pAc->wmmAcTspecInfo.max_service_interval) + { + service_interval = pAc->wmmAcTspecInfo.max_service_interval; + } + else + { + // no service interval is present in the TSPEC + // this is OK, there just won't be U-APSD + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: No service interval supplied", + __func__); + service_interval = 0; + } + + // determine the suspension interval & direction + suspension_interval = pAc->wmmAcTspecInfo.suspension_interval; + direction = pAc->wmmAcTspecInfo.ts_info.direction; + psb = pAc->wmmAcTspecInfo.ts_info.psb; + + // if we have previously enabled U-APSD, have any params changed? + if ((pAc->wmmAcUapsdInfoValid) && + (pAc->wmmAcUapsdServiceInterval == service_interval) && + (pAc->wmmAcUapsdSuspensionInterval == suspension_interval) && + (pAc->wmmAcUapsdDirection == direction) && + (pAc->wmmAcIsUapsdEnabled == psb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: No change in U-APSD parameters", + __func__); + return; + } + + // are we in the appropriate power save modes? + if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_BEACON_MODE_POWER_SAVE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: BMPS is not enabled", + __func__); + return; + } + + if (!sme_IsPowerSaveEnabled(WLAN_HDD_GET_HAL_CTX(pAdapter), ePMC_UAPSD_MODE_POWER_SAVE)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: U-APSD is not enabled", + __func__); + return; + } + + // everything is in place to notify TL + status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType, + pAc->wmmAcTspecInfo.ts_info.tid, + pAc->wmmAcTspecInfo.ts_info.up, + service_interval, + suspension_interval, + direction); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to enable U-APSD for AC=%d", + __func__, acType ); + return; + } + + // stash away the parameters that were used + pAc->wmmAcUapsdInfoValid = VOS_TRUE; + pAc->wmmAcUapsdServiceInterval = service_interval; + pAc->wmmAcUapsdSuspensionInterval = suspension_interval; + pAc->wmmAcUapsdDirection = direction; + pAc->wmmAcIsUapsdEnabled = psb; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Enabled UAPSD in TL srv_int=%d " + "susp_int=%d dir=%d AC=%d", + __func__, + service_interval, + suspension_interval, + direction, + acType); + +} + +/** + @brief hdd_wmm_disable_tl_uapsd() - function which decides whether + to disable UAPSD parameters in TL + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +static void hdd_wmm_disable_tl_uapsd (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc = NULL; + VOS_STATUS status; + v_U32_t service_interval; + v_U32_t suspension_interval; + v_U8_t uapsd_mask; + v_U8_t ActiveTspec = INVALID_TSPEC; + + if (acType >= WLANTL_MAX_AC) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid AC: %d", __func__, acType); + return; + } + + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + // have we previously enabled UAPSD? + if (pAc->wmmAcUapsdInfoValid == VOS_TRUE) + { + uapsd_mask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask; + + //Finding uapsd_mask as per AC + uapsd_mask = uapsd_mask & (1 << (WLANTL_AC_VO - acType)); + + sme_QosTspecActive((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), acType, + pAdapter->sessionId, &ActiveTspec); + + //Call WLANTL_EnableUAPSDForAC only when static uapsd mask is present and + // no active tspecs. TODO: Need to change naming convention as Enable + // UAPSD function is called in hdd_wmm_disable_tl_uapsd. Purpose of + // calling WLANTL_EnableUAPSDForAC is to update UAPSD intervals to fw + + if(uapsd_mask && !ActiveTspec) + { + switch(acType) + { + case WLANTL_AC_VO: + service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv; + suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv; + break; + case WLANTL_AC_VI: + service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv; + suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv; + break; + case WLANTL_AC_BE: + service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv; + suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv; + break; + case WLANTL_AC_BK: + service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv; + suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv; + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid AC %d", __func__, acType ); + return; + } + + status = WLANTL_EnableUAPSDForAC((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType, + pAc->wmmAcTspecInfo.ts_info.tid, + pAc->wmmAcTspecInfo.ts_info.up, + service_interval, + suspension_interval, + pAc->wmmAcTspecInfo.ts_info.direction); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to update U-APSD params for AC=%d", + __func__, acType ); + } + else + { + // TL no longer has valid UAPSD info + pAc->wmmAcUapsdInfoValid = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Updated UAPSD params in TL for AC=%d", + __func__, + acType); + } + } + } +} + +#endif + +/** + @brief hdd_wmm_free_context() - function which frees a QoS context + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +static void hdd_wmm_free_context (hdd_wmm_qos_context_t* pQosContext) +{ + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + // take the wmmLock since we're manipulating the context list + mutex_lock(&pHddCtx->wmmLock); + + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + // must have been freed in another thread + mutex_unlock(&pHddCtx->wmmLock); + return; + } + + // make sure nobody thinks this is a valid context + pQosContext->magic = 0; + + // unlink the context + list_del(&pQosContext->node); + + // done manipulating the list + mutex_unlock(&pHddCtx->wmmLock); + + // reclaim memory + kfree(pQosContext); + +} + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/** + @brief hdd_wmm_notify_app() - function which notifies an application + changes in state of it flow + + @param pQosContext : [in] the pointer the QoS instance control block + + @return + None +*/ +#define MAX_NOTIFY_LEN 50 +static void hdd_wmm_notify_app (hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter; + union iwreq_data wrqu; + char buf[MAX_NOTIFY_LEN+1]; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + mutex_lock(&pHddCtx->wmmLock); + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + mutex_unlock(&pHddCtx->wmmLock); + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return; + } + // get pointer to the adapter + pAdapter = pQosContext->pAdapter; + mutex_unlock(&pHddCtx->wmmLock); + + // create the event + memset(&wrqu, 0, sizeof(wrqu)); + memset(buf, 0, sizeof(buf)); + + snprintf(buf, MAX_NOTIFY_LEN, "QCOM: TS change[%u: %u]", + (unsigned int)pQosContext->handle, + (unsigned int)pQosContext->lastStatus); + + wrqu.data.pointer = buf; + wrqu.data.length = strlen(buf); + + + + // send the event + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Sending [%s]", __func__, buf); + wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf); +} + + +/** + @brief hdd_wmm_is_access_allowed() - function which determines if access + is allowed for the given AC. this is designed to be called during SME + callback processing since that is when access can be granted or removed + + @param pAdapter : [in] pointer to adapter context + @param pAc : [in] pointer to the per-AC status + + @return : VOS_TRUE - access is allowed + : VOS_FALSE - access is not allowed + None +*/ +static v_BOOL_t hdd_wmm_is_access_allowed(hdd_adapter_t* pAdapter, + hdd_wmm_ac_status_t* pAc) +{ + // if we don't want QoS or the AP doesn't support QoS + // or we don't want to do implicit QoS + // or if AP doesn't require admission for this AC + // then we have access + if (!hdd_wmm_is_active(pAdapter) || + !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled || + !pAc->wmmAcAccessRequired) + { + return VOS_TRUE; + } + + // if implicit QoS has already completed, successfully or not, + // then access is allowed + if (pAc->wmmAcAccessGranted || pAc->wmmAcAccessFailed) + { + return VOS_TRUE; + } + + // admission is required and implicit QoS hasn't completed + // however explicit QoS may have completed and we'll have + // a Tspec + // if we don't have a Tspec then access is not allowed + if (!pAc->wmmAcTspecValid) + { + return VOS_FALSE; + } + + // we have a Tspec -- does it allow upstream or bidirectional traffic? + // if it only allows downstream traffic then access is not allowed + if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK) + { + return VOS_FALSE; + } + + // we meet all of the criteria for access + return VOS_TRUE; +} + +#ifdef FEATURE_WLAN_ESE +/** + @brief hdd_wmm_inactivity_timer_cb() - timer handler function which is + called for every inactivity interval per AC. This function gets the + current transmitted packets on the given AC, and checks if there where + any TX activity from the previous interval. If there was no traffic + then it would delete the TS that was negotiated on that AC. + + @param pUserData : [in] pointer to pQosContext + + @return : NONE +*/ +void hdd_wmm_inactivity_timer_cb( v_PVOID_t pUserData ) +{ + hdd_wmm_qos_context_t* pQosContext = (hdd_wmm_qos_context_t*)pUserData; + hdd_adapter_t* pAdapter; + hdd_wmm_ac_status_t *pAc; + hdd_wlan_wmm_status_e status; + VOS_STATUS vos_status; + v_U32_t currentTrafficCnt = 0; + WLANTL_ACEnumType acType = 0; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + ENTER(); + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid VOS Context", __func__); + return; + } + + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (0 != (wlan_hdd_validate_context(pHddCtx))) + { + return; + } + + mutex_lock(&pHddCtx->wmmLock); + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + mutex_unlock(&pHddCtx->wmmLock); + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return; + } + mutex_unlock(&pHddCtx->wmmLock); + + acType = pQosContext->acType; + pAdapter = pQosContext->pAdapter; + if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("invalid pAdapter: %p"), pAdapter); + return; + } + + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + // Get the Tx stats for this AC. + currentTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType]; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("WMM inactivity Timer for AC=%d, currentCnt=%d, prevCnt=%d"), + acType, (int)currentTrafficCnt, (int)pAc->wmmPrevTrafficCnt); + if (pAc->wmmPrevTrafficCnt == currentTrafficCnt) + { + // If there is no traffic activity, delete the TSPEC for this AC + status = hdd_wmm_delts(pAdapter, pQosContext->handle); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + FL("Deleted TS on AC %d, due to inactivity with status = %d!!!"), + acType, status); + } + else + { + pAc->wmmPrevTrafficCnt = currentTrafficCnt; + if (pAc->wmmInactivityTimer.state == VOS_TIMER_STATE_STOPPED) + { + // Restart the timer + vos_status = vos_timer_start(&pAc->wmmInactivityTimer, pAc->wmmInactivityTime); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Restarting inactivity timer failed on AC %d"), acType); + } + } + else + { + VOS_ASSERT(vos_timer_getCurrentState( + &pAc->wmmInactivityTimer) == VOS_TIMER_STATE_STOPPED); + } + } + + EXIT(); + return; +} + + +/** + @brief hdd_wmm_enable_inactivity_timer() - function to enable the + traffic inactivity timer for the given AC, if the inactivity_interval + specified in the ADDTS parameters is non-zero + + @param pQosContext : [in] pointer to pQosContext + @param inactivityTime: [in] value of the inactivity interval in millisecs + + @return : VOS_STATUS_E_FAILURE + VOS_STATUS_SUCCESS +*/ +VOS_STATUS hdd_wmm_enable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext, v_U32_t inactivityTime) +{ + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc; + + pAdapter = pQosContext->pAdapter; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + + // If QoS-Tspec is successfully setup and if the inactivity timer is non-zero, + // a traffic inactivity timer needs to be started for the given AC + vos_status = vos_timer_init( + &pAc->wmmInactivityTimer, + VOS_TIMER_TYPE_SW, + hdd_wmm_inactivity_timer_cb, + (v_PVOID_t)pQosContext ); + if ( !VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Initializing inactivity timer failed on AC %d"), acType); + return vos_status; + } + + // Start the inactivity timer + vos_status = vos_timer_start( + &pAc->wmmInactivityTimer, + inactivityTime); + if ( !VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + FL("Starting inactivity timer failed on AC %d"), acType); + return vos_status; + } + pAc->wmmInactivityTime = inactivityTime; + // Initialize the current tx traffic count on this AC + pAc->wmmPrevTrafficCnt = pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[pQosContext->acType]; + + return vos_status; +} + +/** + @brief hdd_wmm_enable_inactivity_timer() - function to disable the + traffic inactivity timer for the given AC. This would be called when + deleting the TS. + + @param pQosContext : [in] pointer to pQosContext + + @return : VOS_STATUS_E_FAILURE + VOS_STATUS_SUCCESS +*/ +VOS_STATUS hdd_wmm_disable_inactivity_timer(hdd_wmm_qos_context_t* pQosContext) +{ + hdd_adapter_t* pAdapter = pQosContext->pAdapter; + WLANTL_ACEnumType acType = pQosContext->acType; + hdd_wmm_ac_status_t *pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + + // Clear the timer and the counter + pAc->wmmInactivityTime = 0; + pAc->wmmPrevTrafficCnt = 0; + vos_timer_stop(&pAc->wmmInactivityTimer); + vos_status = vos_timer_destroy(&pAc->wmmInactivityTimer); + + return vos_status; +} +#endif // FEATURE_WLAN_ESE + +/** + @brief hdd_wmm_sme_callback() - callback registered by HDD with SME for receiving + QoS notifications. Even though this function has a static scope it gets called + externally through some function pointer magic (so there is a need for + rigorous parameter checking) + + @param hHal : [in] the HAL handle + @param HddCtx : [in] the HDD specified handle + @param pCurrentQosInfo : [in] the TSPEC params + @param SmeStatus : [in] the QoS related SME status + + @return + eHAL_STATUS_SUCCESS if all good, eHAL_STATUS_FAILURE otherwise +*/ +static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal, + void * hddCtx, + sme_QosWmmTspecInfo* pCurrentQosInfo, + sme_QosStatusType smeStatus, + v_U32_t qosFlowId) +{ + hdd_wmm_qos_context_t* pQosContext = hddCtx; + hdd_adapter_t* pAdapter; + WLANTL_ACEnumType acType; + hdd_wmm_ac_status_t *pAc; + VOS_STATUS status; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return eHAL_STATUS_FAILURE; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return eHAL_STATUS_FAILURE; + } + + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + mutex_lock(&pHddCtx->wmmLock); + if (unlikely((NULL == pQosContext) || + (HDD_WMM_CTX_MAGIC != pQosContext->magic))) + { + mutex_unlock(&pHddCtx->wmmLock); + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return eHAL_STATUS_FAILURE; + } + mutex_unlock(&pHddCtx->wmmLock); + + pAdapter = pQosContext->pAdapter; + acType = pQosContext->acType; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: status %d flowid %d info %p", + __func__, smeStatus, qosFlowId, pCurrentQosInfo); + + switch (smeStatus) + { + + case SME_QOS_STATUS_SETUP_SUCCESS_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Setup is complete", + __func__); + + // there will always be a TSPEC returned with this status, even if + // a TSPEC is not exchanged OTA + if (pCurrentQosInfo) + { + pAc->wmmAcTspecValid = VOS_TRUE; + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + } + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL for TL AC %d", + __func__, acType); + + // this was triggered by implicit QoS so we know packets are pending + // update state + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessPending = VOS_FALSE; + + // notify TL that packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS; + hdd_wmm_notify_app(pQosContext); + } + +#ifdef FEATURE_WLAN_ESE + // Check if the inactivity interval is specified + if (pCurrentQosInfo && pCurrentQosInfo->inactivity_interval) { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Inactivity timer value = %d for AC=%d", + __func__, pCurrentQosInfo->inactivity_interval, acType); + hdd_wmm_enable_inactivity_timer(pQosContext, pCurrentQosInfo->inactivity_interval); + } +#endif // FEATURE_WLAN_ESE + + // notify TL to enable trigger frames if necessary + hdd_wmm_enable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setup is complete (U-APSD set previously)", + __func__); + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // this was triggered by implicit QoS so we know packets are pending + // update state + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessPending = VOS_FALSE; + + // notify TL that packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING; + hdd_wmm_notify_app(pQosContext); + } + + break; + + case SME_QOS_STATUS_SETUP_FAILURE_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup failed", + __func__); + // QoS setup failed + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // we note the failure, but we also mark access as allowed so that + // the packets will flow. Note that the MAC will "do the right thing" + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + + // this was triggered by implicit QoS so we know packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + /* Setting up QoS Failed, QoS context can be released. + * SME is releasing this flow information and if HDD doen't release this context, + * next time if application uses the same handle to set-up QoS, HDD (as it has + * QoS context for this handle) will issue Modify QoS request to SME but SME will + * reject as no it has no information for this flow. + */ + hdd_wmm_free_context(pQosContext); + break; + + case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup Invalid Params, notify TL", + __func__); + // QoS setup failed + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // we note the failure, but we also mark access as allowed so that + // the packets will flow. Note that the MAC will "do the right thing" + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + + // this was triggered by implicit QoS so we know packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP: + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup failed, not a QoS AP", + __func__); + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setup pending", + __func__); + // not a callback status -- ignore if we get it + break; + + case SME_QOS_STATUS_SETUP_MODIFIED_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setup modified", + __func__); + if (pCurrentQosInfo) + { + // update the TSPEC + pAc->wmmAcTspecValid = VOS_TRUE; + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFIED; + hdd_wmm_notify_app(pQosContext); + } + + // need to tell TL to update its UAPSD handling + hdd_wmm_enable_tl_uapsd(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // this was triggered by implicit QoS so we know packets are pending + pAc->wmmAcAccessPending = VOS_FALSE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + + // notify TL that packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING: + // nothing to do for now + break; + + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Setup successful but U-APSD failed", + __func__); + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Implicit Qos, notifying TL", + __func__); + + // QoS setup was successful but setting U=APSD failed + // Since the OTA part of the request was successful, we don't mark + // this as a failure. + // the packets will flow. Note that the MAC will "do the right thing" + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessFailed = VOS_FALSE; + pAc->wmmAcAccessPending = VOS_FALSE; + + // this was triggered by implicit QoS so we know packets are pending + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_SETUP_UAPSD_SET_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + // Since U-APSD portion failed disabled trigger frame generation + hdd_wmm_disable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_RELEASE_SUCCESS_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Release is complete", + __func__); + + if (pCurrentQosInfo) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: flows still active", + __func__); + + // there is still at least one flow active for this AC + // so update the AC state + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + + // need to tell TL to update its UAPSD handling + hdd_wmm_enable_tl_uapsd(pQosContext); + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: last flow", + __func__); + + // this is the last flow active for this AC so update the AC state + pAc->wmmAcTspecValid = VOS_FALSE; + + // need to tell TL to update its UAPSD handling + hdd_wmm_disable_tl_uapsd(pQosContext); + } + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS; + hdd_wmm_notify_app(pQosContext); + } + + // we are done with this flow + hdd_wmm_free_context(pQosContext); + break; + + case SME_QOS_STATUS_RELEASE_FAILURE_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Release failure", + __func__); + + // we don't need to update our state or TL since nothing has changed + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + break; + + case SME_QOS_STATUS_RELEASE_QOS_LOST_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: QOS Lost indication received", + __func__); + + // current TSPEC is no longer valid + pAc->wmmAcTspecValid = VOS_FALSE; + + // need to tell TL to update its UAPSD handling + hdd_wmm_disable_tl_uapsd(pQosContext); + + if (HDD_WMM_HANDLE_IMPLICIT == pQosContext->handle) + { + // we no longer have implicit access granted + pAc->wmmAcAccessGranted = VOS_FALSE; + pAc->wmmAcAccessFailed = VOS_FALSE; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Explicit Qos, notifying userspace", + __func__); + + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_LOST; + hdd_wmm_notify_app(pQosContext); + } + + // we are done with this flow + hdd_wmm_free_context(pQosContext); + break; + + case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Release pending", + __func__); + // not a callback status -- ignore if we get it + break; + + case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Release Invalid Params", + __func__); + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Modification is complete, notify TL", + __func__); + + // there will always be a TSPEC returned with this status, even if + // a TSPEC is not exchanged OTA + if (pCurrentQosInfo) + { + pAc->wmmAcTspecValid = VOS_TRUE; + memcpy(&pAc->wmmAcTspecInfo, + pCurrentQosInfo, + sizeof(pAc->wmmAcTspecInfo)); + } + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS; + hdd_wmm_notify_app(pQosContext); + } + + // notify TL to enable trigger frames if necessary + hdd_wmm_enable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY: + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP: + // the flow modification failed so we'll leave in place + // whatever existed beforehand + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: modification pending", + __func__); + // not a callback status -- ignore if we get it + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + // the flow modification was successful but no QoS changes required + + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP: + // invalid params -- notify the application + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM; + hdd_wmm_notify_app(pQosContext); + } + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING: + // nothing to do for now. when APSD is established we'll have work to do + break; + + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Modify successful but U-APSD failed", + __func__); + + // QoS modification was successful but setting U=APSD failed. + // This will always be an explicit QoS instance, so all we can + // do is notify the application and let it clean up. + if (HDD_WMM_HANDLE_IMPLICIT != pQosContext->handle) + { + // this was triggered by an application + pQosContext->lastStatus = HDD_WLAN_WMM_STATUS_MODIFY_UAPSD_SET_FAILED; + hdd_wmm_notify_app(pQosContext); + } + + // Since U-APSD portion failed disabled trigger frame generation + hdd_wmm_disable_tl_uapsd(pQosContext); + + break; + + case SME_QOS_STATUS_HANDING_OFF: + // no roaming so we won't see this + break; + + case SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND: + // need to tell TL to stop trigger frame generation + hdd_wmm_disable_tl_uapsd(pQosContext); + break; + + case SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND: + // need to tell TL to start sending trigger frames again + hdd_wmm_enable_tl_uapsd(pQosContext); + break; + + default: + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", + __func__, smeStatus ); + VOS_ASSERT(0); + } + + // our access to the particular access category may have changed. + // some of the implicit QoS cases above may have already set this + // prior to invoking TL (so that we will properly service the + // Tx queues) but let's consistently handle all cases here + pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: complete, access for TL AC %d is%sallowed", + __func__, + acType, + pAc->wmmAcAccessAllowed ? " " : " not "); + + return eHAL_STATUS_SUCCESS; +} +#endif + +/**======================================================================== + @brief hdd_wmmps_helper() - Function to set uapsd psb dynamically + + @param pAdapter : [in] pointer to adapter structure + + @param ptr : [in] pointer to command buffer + + @return : Zero on success, appropriate error on failure. + =======================================================================*/ +int hdd_wmmps_helper(hdd_adapter_t *pAdapter, tANI_U8 *ptr) +{ + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: pAdapter is NULL", __func__); + return -EINVAL; + } + if (NULL == ptr) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: ptr is NULL", __func__); + return -EINVAL; + } + /* convert ASCII to integer */ + pAdapter->configuredPsb = ptr[9] - '0'; + pAdapter->psbChanged = HDD_PSB_CHANGED; + + return 0; +} + +/**============================================================================ + @brief hdd_wmm_do_implicit_qos() - Function which will attempt to setup + QoS for any AC requiring it + + @param work : [in] pointer to work structure + + @return : void + ===========================================================================*/ +static void __hdd_wmm_do_implicit_qos(struct work_struct *work) +{ + hdd_wmm_qos_context_t* pQosContext = + container_of(work, hdd_wmm_qos_context_t, wmmAcSetupImplicitQos); + hdd_adapter_t* pAdapter; + WLANTL_ACEnumType acType; + hdd_wmm_ac_status_t *pAc; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + VOS_STATUS status; + sme_QosStatusType smeStatus; +#endif + sme_QosWmmTspecInfo qosInfo; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + int ret = 0; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + + ret = wlan_hdd_validate_context(pHddCtx); + if (0 != ret) + { + hddLog(LOGE, FL("HDD context is invalid")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered, context %p", + __func__, pQosContext); + + mutex_lock(&pHddCtx->wmmLock); + if (unlikely(HDD_WMM_CTX_MAGIC != pQosContext->magic)) + { + mutex_unlock(&pHddCtx->wmmLock); + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid QoS Context", + __func__); + return; + } + mutex_unlock(&pHddCtx->wmmLock); + + pAdapter = pQosContext->pAdapter; + acType = pQosContext->acType; + pAc = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: pAdapter %p acType %d", + __func__, pAdapter, acType); + + if (!pAc->wmmAcAccessNeeded) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: AC %d doesn't need service", + __func__, acType); + pQosContext->magic = 0; + kfree(pQosContext); + return; + } + + pAc->wmmAcAccessPending = VOS_TRUE; + pAc->wmmAcAccessNeeded = VOS_FALSE; + + memset(&qosInfo, 0, sizeof(qosInfo)); + + qosInfo.ts_info.psb = pAdapter->configuredPsb; + + switch (acType) + { + case WLANTL_AC_VO: + qosInfo.ts_info.up = SME_QOS_WMM_UP_VO; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_VO) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVo; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVo; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVo; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVo; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVo; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv; + break; + case WLANTL_AC_VI: + qosInfo.ts_info.up = SME_QOS_WMM_UP_VI; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_VI) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcVi; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcVi; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcVi; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcVi; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcVi; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv; + break; + case WLANTL_AC_BE: + qosInfo.ts_info.up = SME_QOS_WMM_UP_BE; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_BE) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBe; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBe; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBe; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBe; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBe; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv; + break; + case WLANTL_AC_BK: + qosInfo.ts_info.up = SME_QOS_WMM_UP_BK; + /* Check if there is any valid configuration from framework */ + if (HDD_PSB_CFG_INVALID == pAdapter->configuredPsb) + { + qosInfo.ts_info.psb = ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask & + SME_QOS_UAPSD_BK) ? 1 : 0; + } + qosInfo.ts_info.direction = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraDirAcBk; + qosInfo.ts_info.tid = 255; + qosInfo.mean_data_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMeanDataRateAcBk; + qosInfo.min_phy_rate = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraMinPhyRateAcBk; + qosInfo.min_service_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv; + qosInfo.nominal_msdu_size = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraNomMsduSizeAcBk; + qosInfo.surplus_bw_allowance = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraSbaAcBk; + qosInfo.suspension_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv; + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid AC %d", __func__, acType ); + return; + } +#ifdef FEATURE_WLAN_ESE + qosInfo.inactivity_interval = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraInactivityInterval; +#endif + qosInfo.ts_info.burst_size_defn = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->burstSizeDefinition; + + switch ((WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->tsInfoAckPolicy) + { + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK: + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + break; + + case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK: + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK; + break; + + default: + // unknown + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + } + + if(qosInfo.ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) + { + if(!sme_QosIsTSInfoAckPolicyValid((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter), &qosInfo, pAdapter->sessionId)) + { + qosInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK; + } + } + + mutex_lock(&pHddCtx->wmmLock); + list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList); + mutex_unlock(&pHddCtx->wmmLock); + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + &qosInfo, + hdd_wmm_sme_callback, + pQosContext, + qosInfo.ts_info.up, + &pQosContext->qosFlowId); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: sme_QosSetupReq returned %d flowid %d", + __func__, smeStatus, pQosContext->qosFlowId); + + // need to check the return values and act appropriately + switch (smeStatus) + { + case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP: + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING: + // setup is pending, so no more work to do now. + // all further work will be done in hdd_wmm_sme_callback() + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Setup is pending, no further work", + __func__); + + break; + + + case SME_QOS_STATUS_SETUP_FAILURE_RSP: + // we can't tell the difference between when a request fails because + // AP rejected it versus when SME encountered an internal error + + // in either case SME won't ever reference this context so + // free the record + hdd_wmm_free_context(pQosContext); + + // fall through and start packets flowing + case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + // no ACM in effect, no need to setup U-APSD + case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY: + // no ACM in effect, U-APSD is desired but was already setup + + // for these cases everything is already setup so we can + // signal TL that it has work to do + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Setup is complete, notify TL", + __func__); + + pAc->wmmAcAccessAllowed = VOS_TRUE; + pAc->wmmAcAccessGranted = VOS_TRUE; + pAc->wmmAcAccessPending = VOS_FALSE; + + status = WLANTL_STAPktPending( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + acType ); + + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Failed to signal TL for AC=%d", + __func__, acType ); + } + + break; + + + default: + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", + __func__, smeStatus ); + VOS_ASSERT(0); + } +#endif + +} + +static void hdd_wmm_do_implicit_qos(struct work_struct *work) +{ + vos_ssr_protect(__func__); + __hdd_wmm_do_implicit_qos( work ); + vos_ssr_unprotect(__func__); +} + +/**============================================================================ + @brief hdd_wmm_init() - Function which will initialize the WMM configuation + and status to an initial state. The configuration can later be overwritten + via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if successful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter ) +{ + sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap; + v_U8_t dscp; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + // DSCP to User Priority Lookup Table + for (dscp = 0; dscp <= WLAN_HDD_MAX_DSCP; dscp++) + { + hddWmmDscpToUpMap[dscp] = SME_QOS_WMM_UP_BE; + } + hddWmmDscpToUpMap[8] = SME_QOS_WMM_UP_BK; + hddWmmDscpToUpMap[16] = SME_QOS_WMM_UP_RESV; + hddWmmDscpToUpMap[24] = SME_QOS_WMM_UP_EE; + hddWmmDscpToUpMap[32] = SME_QOS_WMM_UP_CL; + hddWmmDscpToUpMap[40] = SME_QOS_WMM_UP_VI; + hddWmmDscpToUpMap[48] = SME_QOS_WMM_UP_VO; + hddWmmDscpToUpMap[56] = SME_QOS_WMM_UP_NC; + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation + and status to an initial state. The configuration can later be overwritten + via application APIs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_init( hdd_adapter_t *pAdapter ) +{ + hdd_wmm_ac_status_t *pAcStatus; + WLANTL_ACEnumType acType; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + pAdapter->hddWmmStatus.wmmQap = VOS_FALSE; + INIT_LIST_HEAD(&pAdapter->hddWmmStatus.wmmContextList); + + for (acType = 0; acType < WLANTL_MAX_AC; acType++) + { + pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + pAcStatus->wmmAcAccessRequired = VOS_FALSE; + pAcStatus->wmmAcAccessNeeded = VOS_FALSE; + pAcStatus->wmmAcAccessPending = VOS_FALSE; + pAcStatus->wmmAcAccessFailed = VOS_FALSE; + pAcStatus->wmmAcAccessGranted = VOS_FALSE; + pAcStatus->wmmAcAccessAllowed = VOS_FALSE; + pAcStatus->wmmAcTspecValid = VOS_FALSE; + pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE; + } + // Invalid value(0xff) to indicate psb not configured through framework initially. + pAdapter->configuredPsb = HDD_PSB_CFG_INVALID; + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_adapter_clear() - Function which will clear the WMM status + for all the ACs + + @param pAdapter : [in] pointer to Adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_clear( hdd_adapter_t *pAdapter ) +{ + hdd_wmm_ac_status_t *pAcStatus; + WLANTL_ACEnumType acType; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + for (acType = 0; acType < WLANTL_MAX_AC; acType++) + { + pAcStatus = &pAdapter->hddWmmStatus.wmmAcStatus[acType]; + pAcStatus->wmmAcAccessRequired = VOS_FALSE; + pAcStatus->wmmAcAccessNeeded = VOS_FALSE; + pAcStatus->wmmAcAccessPending = VOS_FALSE; + pAcStatus->wmmAcAccessFailed = VOS_FALSE; + pAcStatus->wmmAcAccessGranted = VOS_FALSE; + pAcStatus->wmmAcAccessAllowed = VOS_FALSE; + pAcStatus->wmmAcTspecValid = VOS_FALSE; + pAcStatus->wmmAcUapsdInfoValid = VOS_FALSE; + } + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_close() - Function which will perform any necessary work to + to clean up the WMM functionality prior to the kernel module unload + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + + ===========================================================================*/ +VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter ) +{ + hdd_wmm_qos_context_t* pQosContext; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return VOS_STATUS_E_FAILURE; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + // free any context records that we still have linked + while (!list_empty(&pAdapter->hddWmmStatus.wmmContextList)) + { + pQosContext = list_first_entry(&pAdapter->hddWmmStatus.wmmContextList, + hdd_wmm_qos_context_t, node); +#ifdef FEATURE_WLAN_ESE + hdd_wmm_disable_inactivity_timer(pQosContext); +#endif + mutex_lock(&pHddCtx->wmmLock); + if (pQosContext->handle == HDD_WMM_HANDLE_IMPLICIT + && pQosContext->magic == HDD_WMM_CTX_MAGIC) + { + + vos_flush_work(&pQosContext->wmmAcSetupImplicitQos); + } + mutex_unlock(&pHddCtx->wmmLock); + + hdd_wmm_free_context(pQosContext); + } + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_is_dhcp_packet() - Function which will check OS packet for + DHCP packet + + @param skb : [in] pointer to OS packet (sk_buff) + @return : VOS_TRUE if the OS packet is DHCP packet + : otherwise VOS_FALSE + ===========================================================================*/ +v_BOOL_t hdd_is_dhcp_packet(struct sk_buff *skb) +{ + if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT || + *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT) + return VOS_TRUE; + + return VOS_FALSE; +} + +/**============================================================================ + @brief hdd_skb_is_eapol_or_wai_packet() - Function which will check OS packet + for Eapol/Wapi packet + + @param skb : [in] pointer to OS packet (sk_buff) + @return : VOS_TRUE if the OS packet is an Eapol or a Wapi packet + : otherwise VOS_FALSE + ===========================================================================*/ +v_BOOL_t hdd_skb_is_eapol_or_wai_packet(struct sk_buff *skb) +{ + if ((*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET)) + == vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X)) +#ifdef FEATURE_WLAN_WAPI + || (*((u16*)((u8*)skb->data+HDD_ETHERTYPE_802_1_X_FRAME_OFFSET)) + == vos_cpu_to_be16(HDD_ETHERTYPE_WAI)) +#endif + ) + return VOS_TRUE; + + return VOS_FALSE; +} + +/**============================================================================ + @brief hdd_log_ip_addr() - Function to log IP header src and dst address + @param skb : [in] pointer to OS packet (sk_buff) + @return : none + ===========================================================================*/ +void hdd_log_ip_addr(struct sk_buff *skb) +{ + union generic_ethhdr *pHdr; + struct iphdr *pIpHdr; + unsigned char * pPkt; + char *buf; + + pPkt = skb->data; + pHdr = (union generic_ethhdr *)pPkt; + + if (pHdr->eth_II.h_proto == htons(ETH_P_IP)) + { + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)]; + + buf = (char *)&pIpHdr->saddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: src addr %d:%d:%d:%d", __func__, + buf[0], buf[1], buf[2], buf[3]); + + buf = (char *)&pIpHdr->daddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: dst addr %d:%d:%d:%d", __func__, + buf[0], buf[1], buf[2], buf[3]); + } + else if (pHdr->eth_II.h_proto == htons(ETH_P_IPV6)) + { + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)]; + + buf = (char *)&pIpHdr->saddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf)); + + buf = (char *)&pIpHdr->daddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf)); + } + else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) && + (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) && + (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) && + (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL)) + { + if (pHdr->eth_8023.h_proto == htons(ETH_P_IP)) + { + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)]; + + buf = (char *)&pIpHdr->saddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: src addr %d:%d:%d:%d", __func__, + buf[0], buf[1], buf[2], buf[3]); + + buf = (char *)&pIpHdr->daddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: dst addr %d:%d:%d:%d", __func__, + buf[0], buf[1], buf[2], buf[3]); + } + else if (pHdr->eth_8023.h_proto == htons(ETH_P_IPV6)) + { + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)]; + + buf = (char *)&pIpHdr->saddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: src addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf)); + + buf = (char *)&pIpHdr->daddr; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: dst addr "IPv6_ADDR_STR, __func__, IPv6_ADDR_ARRAY(buf)); + } + } +} + +/**============================================================================ + @brief hdd_get_arp_src_ip() - Function to get ARP src IP addr + @param skb : [in] pointer to OS packet (sk_buff) + @return : IP addr + ===========================================================================*/ +uint32_t hdd_get_arp_src_ip(struct sk_buff *skb) +{ + struct arphdr *arp; + unsigned char *arp_ptr; + uint32_t src_ip; + +#define ARP_HDR_SIZE ( sizeof(__be16)*3 + sizeof(unsigned char)*2 ) +#define ARP_SENDER_HW_ADDRESS_SZ (6) +#define ARP_SENDER_IP_ADDRESS_SZ (4) + + arp = (struct arphdr *)skb->data; + + arp_ptr = (unsigned char *)arp + ARP_HDR_SIZE; + arp_ptr += ARP_SENDER_HW_ADDRESS_SZ; + + memcpy(&src_ip, arp_ptr, ARP_SENDER_IP_ADDRESS_SZ); + + src_ip=ntohl(src_ip); + + return src_ip; + +#undef ARP_HDR_SIZE +#undef ARP_SENDER_HW_ADDRESS_SZ +#undef ARP_SENDER_IP_ADDRESS_SZ +} + +/**============================================================================ + @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet + into a WMM AC based on either 802.1Q or DSCP + + @param pAdapter : [in] pointer to adapter context + @param skb : [in] pointer to OS packet (sk_buff) + @param pAcType : [out] pointer to WMM AC type of OS packet + + @return : None + ===========================================================================*/ +v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter, + struct sk_buff *skb, + WLANTL_ACEnumType* pAcType, + sme_QosWmmUpType *pUserPri) +{ + unsigned char * pPkt; + union generic_ethhdr *pHdr; + struct iphdr *pIpHdr; + unsigned char tos; + unsigned char dscp; + sme_QosWmmUpType userPri; + WLANTL_ACEnumType acType; + + // this code is executed for every packet therefore + // all debug code is kept conditional + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); +#endif // HDD_WMM_DEBUG + + pPkt = skb->data; + pHdr = (union generic_ethhdr *)pPkt; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: proto/length is 0x%04x", + __func__, pHdr->eth_II.h_proto); +#endif // HDD_WMM_DEBUG + + if (HDD_WMM_CLASSIFICATION_DSCP == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis) + { + if (pHdr->eth_II.h_proto == htons(ETH_P_IP)) + { + // case 1: Ethernet II IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_II)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Ethernet II IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + + } + else if ((ntohs(pHdr->eth_II.h_proto) < WLAN_MIN_PROTO) && + (pHdr->eth_8023.h_snap.dsap == WLAN_SNAP_DSAP) && + (pHdr->eth_8023.h_snap.ssap == WLAN_SNAP_SSAP) && + (pHdr->eth_8023.h_snap.ctrl == WLAN_SNAP_CTRL) && + (pHdr->eth_8023.h_proto == htons(ETH_P_IP))) + { + // case 2: 802.3 LLC/SNAP IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: 802.3 LLC/SNAP IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + } + else if (pHdr->eth_II.h_proto == htons(ETH_P_8021Q)) + { + // VLAN tagged + + if (pHdr->eth_IIv.h_vlan_encapsulated_proto == htons(ETH_P_IP)) + { + // case 3: Ethernet II vlan-tagged IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_IIv)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Ethernet II VLAN tagged IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + } + else if ((ntohs(pHdr->eth_IIv.h_vlan_encapsulated_proto) < WLAN_MIN_PROTO) && + (pHdr->eth_8023v.h_snap.dsap == WLAN_SNAP_DSAP) && + (pHdr->eth_8023v.h_snap.ssap == WLAN_SNAP_SSAP) && + (pHdr->eth_8023v.h_snap.ctrl == WLAN_SNAP_CTRL) && + (pHdr->eth_8023v.h_proto == htons(ETH_P_IP))) + { + // case 4: 802.3 LLC/SNAP vlan-tagged IP packet + pIpHdr = (struct iphdr *)&pPkt[sizeof(pHdr->eth_8023v)]; + tos = pIpHdr->tos; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: 802.3 LLC/SNAP VLAN tagged IP Packet, tos is %d", + __func__, tos); +#endif // HDD_WMM_DEBUG + } + else + { + // default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: VLAN tagged Unhandled Protocol, using default tos", + __func__); +#endif // HDD_WMM_DEBUG + tos = 0; + } + } + else + { + v_BOOL_t toggleArpBDRates = + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->toggleArpBDRates; + // default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: Unhandled Protocol, using default tos", + __func__); +#endif // HDD_WMM_DEBUG + //Give the highest priority to 802.1x packet + if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X)) + tos = 0xC0; + else if (toggleArpBDRates && + pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_ARP)) + { + tos = TID3; + } + else + tos = 0; + } + + dscp = (tos>>2) & 0x3f; + userPri = pAdapter->hddWmmDscpToUpMap[dscp]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: tos is %d, dscp is %d, up is %d", + __func__, tos, dscp, userPri); +#endif // HDD_WMM_DEBUG + + } + else if (HDD_WMM_CLASSIFICATION_802_1Q == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->PktClassificationBasis) + { + if (pHdr->eth_IIv.h_vlan_proto == htons(ETH_P_8021Q)) + { + // VLAN tagged + userPri = (ntohs(pHdr->eth_IIv.h_vlan_TCI)>>13) & 0x7; +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Tagged frame, UP is %d", + __func__, userPri); +#endif // HDD_WMM_DEBUG + } + else + { + // not VLAN tagged, use default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: Untagged frame, using default UP", + __func__); +#endif // HDD_WMM_DEBUG + //Give the highest priority to 802.1x packet + if (pHdr->eth_II.h_proto == htons(HDD_ETHERTYPE_802_1_X)) + userPri = SME_QOS_WMM_UP_VO; + else + userPri = SME_QOS_WMM_UP_BE; + } + } + else + { + // default +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Unknown classification scheme, using default UP", + __func__); +#endif // HDD_WMM_DEBUG + userPri = SME_QOS_WMM_UP_BE; + } + + acType = hddWmmUpToAcMap[userPri]; + +#ifdef HDD_WMM_DEBUG + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: UP is %d, AC is %d", + __func__, userPri, acType); +#endif // HDD_WMM_DEBUG + + *pUserPri = userPri; + *pAcType = acType; + + return; +} + +/**============================================================================ + @brief hdd_hostapd_select_quueue() - Function which will classify the packet + according to linux qdisc expectation. + + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to os packet + + @return : Qdisc queue index + ===========================================================================*/ +v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0)) + , void *accel_priv +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + , select_queue_fallback_t fallbac +#endif +) +{ + WLANTL_ACEnumType ac; + sme_QosWmmUpType up = SME_QOS_WMM_UP_BE; + v_USHORT_t queueIndex; + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + v_U8_t STAId; + v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext; + ptSapContext pSapCtx = NULL; + int status = 0; + + status = wlan_hdd_validate_context(pHddCtx); + if (status !=0 ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("called during WDReset/unload")); + skb->priority = SME_QOS_WMM_UP_BE; + return HDD_LINUX_AC_BE; + } + + pSapCtx = VOS_GET_SAP_CB(pVosContext); + if(pSapCtx == NULL){ + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL("psapCtx is NULL")); + STAId = HDD_WLAN_INVALID_STA_ID; + goto done; + } + /*Get the Station ID*/ + STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress); + if (STAId == HDD_WLAN_INVALID_STA_ID || STAId >= WLAN_MAX_STA_COUNT) { + VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO, + "%s: Failed to find right station", __func__); + goto done; + } + + spin_lock_bh( &pSapCtx->staInfo_lock ); + if (FALSE == vos_is_macaddr_equal(&pSapCtx->aStaInfo[STAId].macAddrSTA, pDestMacAddress)) + { + VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO, + "%s: Station MAC address does not matching", __func__); + + STAId = HDD_WLAN_INVALID_STA_ID; + goto release_lock; + } + if (pSapCtx->aStaInfo[STAId].isUsed && pSapCtx->aStaInfo[STAId].isQosEnabled && (HDD_WMM_USER_MODE_NO_QOS != pHddCtx->cfg_ini->WmmMode)) + { + /* Get the user priority from IP header & corresponding AC */ + hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up); + //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue + if (pSapCtx->aStaInfo[STAId].vosLowResource && hdd_is_dhcp_packet(skb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: Making priority of DHCP packet as VOICE", __func__); + up = SME_QOS_WMM_UP_VO; + ac = hddWmmUpToAcMap[up]; + } + } + +release_lock: + spin_unlock_bh( &pSapCtx->staInfo_lock ); +done: + skb->priority = up; + if(skb->priority < SME_QOS_WMM_UP_MAX) + queueIndex = hddLinuxUpToAcMap[skb->priority]; + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: up=%d is going beyond max value", __func__, up); + queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE]; + } + + return queueIndex; +} + +/**============================================================================ + @brief hdd_wmm_select_quueue() - Function which will classify the packet + according to linux qdisc expectation. + + + @param dev : [in] pointer to net_device structure + @param skb : [in] pointer to os packet + + @return : Qdisc queue index + ===========================================================================*/ +v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb) +{ + WLANTL_ACEnumType ac; + sme_QosWmmUpType up = SME_QOS_WMM_UP_BE; + v_USHORT_t queueIndex; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status = 0; + + status = wlan_hdd_validate_context(pHddCtx); + if (status !=0) { + skb->priority = SME_QOS_WMM_UP_BE; + return HDD_LINUX_AC_BE; + } + + /*Get the Station ID*/ + if (WLAN_HDD_IBSS == pAdapter->device_mode) + { + v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data; + v_U8_t STAId; + + STAId = hdd_sta_id_find_from_mac_addr(pAdapter, pDestMacAddress); + if ((STAId == HDD_WLAN_INVALID_STA_ID) && + !vos_is_macaddr_broadcast( pDestMacAddress ) && + !vos_is_macaddr_group(pDestMacAddress)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Failed to find right station pDestMacAddress: " + MAC_ADDRESS_STR , __func__, + MAC_ADDR_ARRAY(pDestMacAddress->bytes)); + goto done; + } + } + /* All traffic will get equal opportuniy to transmit data frames. */ + /* Get the user priority from IP header & corresponding AC */ + hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up); + + /* If 3/4th of BE AC Tx queue is full, + * then place the DHCP packet in VOICE AC queue. + * Doing this for IBSS alone, since for STA interface + * types, these packets will be queued to the new queue. + */ + if ((WLAN_HDD_IBSS == pAdapter->device_mode) && + pAdapter->isVosLowResource && hdd_is_dhcp_packet(skb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN, + "%s: BestEffort Tx Queue is 3/4th full" + " Make DHCP packet's pri as VO", __func__); + up = SME_QOS_WMM_UP_VO; + ac = hddWmmUpToAcMap[up]; + } + +done: + skb->priority = up; + if(skb->priority < SME_QOS_WMM_UP_MAX) + queueIndex = hddLinuxUpToAcMap[skb->priority]; + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: up=%d is going beyond max value", __func__, up); + queueIndex = hddLinuxUpToAcMap[SME_QOS_WMM_UP_BE]; + } + + if ((WLAN_HDD_IBSS != pAdapter->device_mode) && + (hdd_is_dhcp_packet(skb) || + hdd_skb_is_eapol_or_wai_packet(skb))) + { + /* If the packet is a DHCP packet or a Eapol packet or + * a Wapi packet, then queue it to the new queue for + * STA interfaces alone. + */ + queueIndex = WLANTL_AC_HIGH_PRIO; + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: up=%d QIndex:%d", __func__, up, queueIndex); + } + + return queueIndex; +} + +/**========================================================================== + @brief hdd_wmm_acquire_access_required() - Function which will determine + acquire admittance for a WMM AC is required or not based on psb configuration + done in framework + + @param pAdapter : [in] pointer to adapter structure + + @param acType : [in] WMM AC type of OS packet + + @return : void + ===========================================================================*/ +void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter, + WLANTL_ACEnumType acType) +{ +/* Each bit in the LSB nibble indicates 1 AC. + * Clearing the particular bit in LSB nibble to indicate + * access required + */ + switch(acType) + { + case WLANTL_AC_BK: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BK_CHANGED_MASK; /* clear first bit */ + break; + case WLANTL_AC_BE: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_BE_CHANGED_MASK; /* clear second bit */ + break; + case WLANTL_AC_VI: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VI_CHANGED_MASK; /* clear third bit */ + break; + case WLANTL_AC_VO: + pAdapter->psbChanged &= ~SME_QOS_UAPSD_CFG_VO_CHANGED_MASK; /* clear fourth bit */ + break; + default: + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Invalid AC Type", __func__); + break; + } +} + +/**============================================================================ + @brief hdd_wmm_acquire_access() - Function which will attempt to acquire + admittance for a WMM AC + + @param pAdapter : [in] pointer to adapter context + @param acType : [in] WMM AC type of OS packet + @param pGranted : [out] pointer to boolean flag when indicates if access + has been granted or not + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_acquire_access( hdd_adapter_t* pAdapter, + WLANTL_ACEnumType acType, + v_BOOL_t * pGranted ) +{ + hdd_wmm_qos_context_t *pQosContext; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered for AC %d", __func__, acType); + + if (!hdd_wmm_is_active(pAdapter) || !(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled) + { + // either we don't want QoS or the AP doesn't support QoS + // or we don't want to do implicit QoS + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: QoS not configured on both ends ", __func__); + + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE; + *pGranted = VOS_TRUE; + return VOS_STATUS_SUCCESS; + } + + // do we already have an implicit QoS request pending for this AC? + if ((pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded) || + (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessPending)) + { + // request already pending so we need to wait for that response + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Implicit QoS for TL AC %d already scheduled", + __func__, acType); + + *pGranted = VOS_FALSE; + return VOS_STATUS_SUCCESS; + } + + // did we already fail to establish implicit QoS for this AC? + // (if so, access should have been granted when the failure was handled) + if (pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessFailed) + { + // request previously failed + // allow access, but we'll be downgraded + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Implicit QoS for TL AC %d previously failed", + __func__, acType); + + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE; + *pGranted = VOS_TRUE; + return VOS_STATUS_SUCCESS; + } + + // we need to establish implicit QoS + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Need to schedule implicit QoS for TL AC %d, pAdapter is %p", + __func__, acType, pAdapter); + + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessNeeded = VOS_TRUE; + + pQosContext = kmalloc(sizeof(*pQosContext), GFP_ATOMIC); + if (NULL == pQosContext) + { + // no memory for QoS context. Nothing we can do but let data flow + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Unable to allocate context", __func__); + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcAccessAllowed = VOS_TRUE; + *pGranted = VOS_TRUE; + return VOS_STATUS_SUCCESS; + } + + pQosContext->acType = acType; + pQosContext->pAdapter = pAdapter; + pQosContext->qosFlowId = 0; + pQosContext->handle = HDD_WMM_HANDLE_IMPLICIT; + pQosContext->magic = HDD_WMM_CTX_MAGIC; + vos_init_work(&pQosContext->wmmAcSetupImplicitQos, + hdd_wmm_do_implicit_qos); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Scheduling work for AC %d, context %p", + __func__, acType, pQosContext); + + schedule_work(&pQosContext->wmmAcSetupImplicitQos); + + // caller will need to wait until the work takes place and + // TSPEC negotiation completes + *pGranted = VOS_FALSE; + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_assoc() - Function which will handle the housekeeping + required by WMM when association takes place + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ) +{ + tANI_U8 uapsdMask; + VOS_STATUS status; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + // when we associate we need to notify TL if it needs to enable + // UAPSD for any access categories + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + if (pRoamInfo->fReassocReq) + { + // when we reassociate we should continue to use whatever + // parameters were previously established. if we are + // reassociating due to a U-APSD change for a particular + // Access Category, then the change will be communicated + // to HDD via the QoS callback associated with the given + // flow, and U-APSD parameters will be updated there + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Reassoc so no work, Exiting", __func__); + + return VOS_STATUS_SUCCESS; + } + + // get the negotiated UAPSD Mask + uapsdMask = pRoamInfo->u.pConnectedProfile->modifyProfileFields.uapsd_mask; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: U-APSD mask is 0x%02x", __func__, (int) uapsdMask); + + if (uapsdMask & HDD_AC_VO) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_VO, + 7, + 7, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSuspIntv, + WLANTL_BI_DIR ); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + if (uapsdMask & HDD_AC_VI) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_VI, + 5, + 5, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSuspIntv, + WLANTL_BI_DIR ); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + if (uapsdMask & HDD_AC_BK) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_BK, + 2, + 2, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSuspIntv, + WLANTL_BI_DIR ); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + if (uapsdMask & HDD_AC_BE) + { + status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], + WLANTL_AC_BE, + 3, + 3, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv, + (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSuspIntv, + WLANTL_BI_DIR ); + + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); + } + + status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, + pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId); + + if (!VOS_IS_STATUS_SUCCESS( status )) + { + hdd_wmm_init( pAdapter ); + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Exiting", __func__); + + return VOS_STATUS_SUCCESS; +} + + + +static const v_U8_t acmMaskBit[WLANTL_MAX_AC] = + { + 0x4, /* WLANTL_AC_BK */ + 0x8, /* WLANTL_AC_BE */ + 0x2, /* WLANTL_AC_VI */ + 0x1 /* WLANTL_AC_VO */ + }; + +/**============================================================================ + @brief hdd_wmm_connect() - Function which will handle the housekeeping + required by WMM when a connection is established + + @param pAdapter : [in] pointer to adapter context + @param pRoamInfo: [in] pointer to roam information + @param eBssType : [in] type of BSS + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter, + tCsrRoamInfo *pRoamInfo, + eCsrRoamBssType eBssType ) +{ + int ac; + v_BOOL_t qap; + v_BOOL_t qosConnection; + v_U8_t acmMask; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered", __func__); + + if ((eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) && + pRoamInfo && + pRoamInfo->u.pConnectedProfile) + { + qap = pRoamInfo->u.pConnectedProfile->qap; + qosConnection = pRoamInfo->u.pConnectedProfile->qosConnection; + acmMask = pRoamInfo->u.pConnectedProfile->acm_mask; + } + else + { + /* TODO: if a non-qos IBSS peer joins the group make qap and qosConnection false. + */ + qap = VOS_TRUE; + qosConnection = VOS_TRUE; + acmMask = 0x0; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: qap is %d, qosConnection is %d, acmMask is 0x%x", + __func__, qap, qosConnection, acmMask); + + pAdapter->hddWmmStatus.wmmQap = qap; + pAdapter->hddWmmStatus.wmmQosConnection = qosConnection; + + for (ac = 0; ac < WLANTL_MAX_AC; ac++) + { + if (qap && + qosConnection && + (acmMask & acmMaskBit[ac])) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: ac %d on", + __func__, ac); + + // admission is required + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE; + //Mark wmmAcAccessAllowed as True if implicit Qos is disabled as there + //is no need to hold packets in queue during hdd_tx_fetch_packet_cbk + if (!(WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->bImplicitQosEnabled) + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = + VOS_TRUE; + else + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = + VOS_FALSE; + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE; + + /* Making TSPEC invalid here so downgrading can be happen while roaming + * It is expected this will be SET in hdd_wmm_sme_callback,once sme is + * done with the AddTspec.Here we avoid 11r and ccx based association. + This change is done only when reassoc to different AP. + */ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + FL( "fReassocReq = %d" +#if defined (FEATURE_WLAN_ESE) + "isESEAssoc = %d" +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) + "is11rAssoc = %d" +#endif + ), + pRoamInfo->fReassocReq +#if defined (FEATURE_WLAN_ESE) + ,pRoamInfo->isESEAssoc +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) + ,pRoamInfo->is11rAssoc +#endif + ); + + if ( !pRoamInfo->fReassocReq +#if defined (WLAN_FEATURE_VOWIFI_11R) + && + !pRoamInfo->is11rAssoc +#endif +#if defined (FEATURE_WLAN_ESE) + && + !pRoamInfo->isESEAssoc +#endif + ) + { + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid = VOS_FALSE; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: ac %d off", + __func__, ac); + // admission is not required so access is allowed + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_FALSE; + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE; + } + + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Exiting", __func__); + + return VOS_STATUS_SUCCESS; +} + +/**============================================================================ + @brief hdd_wmm_get_uapsd_mask() - Function which will calculate the + initial value of the UAPSD mask based upon the device configuration + + @param pAdapter : [in] pointer to adapter context + @param pUapsdMask: [in] pointer to where the UAPSD Mask is to be stored + + @return : VOS_STATUS_SUCCESS if succssful + : other values if failure + ===========================================================================*/ +VOS_STATUS hdd_wmm_get_uapsd_mask( hdd_adapter_t* pAdapter, + tANI_U8 *pUapsdMask ) +{ + tANI_U8 uapsdMask; + + if (HDD_WMM_USER_MODE_NO_QOS == (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode) + { + // no QOS then no UAPSD + uapsdMask = 0; + } + else + { + // start with the default mask + uapsdMask = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask; + + // disable UAPSD for any ACs with a 0 Service Interval + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdVoSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_VO; + } + + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdViSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_VI; + } + + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBkSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_BK; + } + + if( (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->InfraUapsdBeSrvIntv == 0 ) + { + uapsdMask &= ~HDD_AC_BE; + } + } + + // return calculated mask + *pUapsdMask = uapsdMask; + return VOS_STATUS_SUCCESS; +} + + +/**============================================================================ + @brief hdd_wmm_is_active() - Function which will determine if WMM is + active on the current connection + + @param pAdapter : [in] pointer to adapter context + + @return : VOS_TRUE if WMM is enabled + : VOS_FALSE if WMM is not enabled + ===========================================================================*/ +v_BOOL_t hdd_wmm_is_active( hdd_adapter_t* pAdapter ) +{ + if ((!pAdapter->hddWmmStatus.wmmQosConnection) || + (!pAdapter->hddWmmStatus.wmmQap)) + { + return VOS_FALSE; + } + else + { + return VOS_TRUE; + } +} + +/**============================================================================ + @brief hdd_wmm_addts() - Function which will add a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + @param pTspec : [in] pointer to the traffic spec + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_addts( hdd_adapter_t* pAdapter, + v_U32_t handle, + sme_QosWmmTspecInfo* pTspec ) +{ + hdd_wmm_qos_context_t *pQosContext; + hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosStatusType smeStatus; +#endif + v_BOOL_t found = VOS_FALSE; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered with handle 0x%x", __func__, handle); + + // see if a context already exists with the given handle + mutex_lock(&pHddCtx->wmmLock); + list_for_each_entry(pQosContext, + &pAdapter->hddWmmStatus.wmmContextList, + node) + { + if (pQosContext->handle == handle) + { + found = VOS_TRUE; + break; + } + } + mutex_unlock(&pHddCtx->wmmLock); + if (found) + { + // record with that handle already exists + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Record already exists with handle 0x%x", + __func__, handle); + + /* Application is trying to modify some of the Tspec params. Allow it */ + smeStatus = sme_QosModifyReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pTspec, + pQosContext->qosFlowId); + + // need to check the return value and act appropriately + switch (smeStatus) + { + case SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_PENDING; + break; + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_NO_UAPSD; + break; + case SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY: + status = HDD_WLAN_WMM_STATUS_MODIFY_SUCCESS_NO_ACM_UAPSD_EXISTING; + break; + case SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED_BAD_PARAM; + break; + case SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP: + status = HDD_WLAN_WMM_STATUS_MODIFY_FAILED; + break; + case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP: + status = HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM; + break; + default: + // we didn't get back one of the SME_QOS_STATUS_MODIFY_* status codes + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", __func__, smeStatus ); + VOS_ASSERT(0); + return HDD_WLAN_WMM_STATUS_MODIFY_FAILED; + } + + mutex_lock(&pHddCtx->wmmLock); + if (pQosContext->magic == HDD_WMM_CTX_MAGIC) + { + pQosContext->lastStatus = status; + } + mutex_unlock(&pHddCtx->wmmLock); + return status; + } + + pQosContext = kmalloc(sizeof(*pQosContext), GFP_KERNEL); + if (NULL == pQosContext) + { + // no memory for QoS context. Nothing we can do + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: Unable to allocate QoS context", __func__); + return HDD_WLAN_WMM_STATUS_INTERNAL_FAILURE; + } + + // we assume the tspec has already been validated by the caller + + pQosContext->handle = handle; + if (pTspec->ts_info.up < HDD_WMM_UP_TO_AC_MAP_SIZE) + pQosContext->acType = hddWmmUpToAcMap[pTspec->ts_info.up]; + else { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: ts_info.up (%d) larger than max value (%d), " + "use default acType (%d)", + __func__, pTspec->ts_info.up, + HDD_WMM_UP_TO_AC_MAP_SIZE - 1, hddWmmUpToAcMap[0]); + pQosContext->acType = hddWmmUpToAcMap[0]; + } + + pQosContext->pAdapter = pAdapter; + pQosContext->qosFlowId = 0; + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: Setting up QoS, context %p", + __func__, pQosContext); + + mutex_lock(&pHddCtx->wmmLock); + pQosContext->magic = HDD_WMM_CTX_MAGIC; + list_add(&pQosContext->node, &pAdapter->hddWmmStatus.wmmContextList); + mutex_unlock(&pHddCtx->wmmLock); + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + smeStatus = sme_QosSetupReq(WLAN_HDD_GET_HAL_CTX(pAdapter), + pAdapter->sessionId, + pTspec, + hdd_wmm_sme_callback, + pQosContext, + pTspec->ts_info.up, + &pQosContext->qosFlowId); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, + "%s: sme_QosSetupReq returned %d flowid %d", + __func__, smeStatus, pQosContext->qosFlowId); + + // need to check the return value and act appropriately + switch (smeStatus) + { + case SME_QOS_STATUS_SETUP_REQ_PENDING_RSP: + status = HDD_WLAN_WMM_STATUS_SETUP_PENDING; + break; + case SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP: + status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_NO_UAPSD; + break; + case SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY: + status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS_NO_ACM_UAPSD_EXISTING; + break; + case SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING: + status = HDD_WLAN_WMM_STATUS_SETUP_PENDING; + break; + case SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP: + hdd_wmm_free_context(pQosContext); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM; + case SME_QOS_STATUS_SETUP_FAILURE_RSP: + // we can't tell the difference between when a request fails because + // AP rejected it versus when SME encounterd an internal error + hdd_wmm_free_context(pQosContext); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED; + case SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP: + hdd_wmm_free_context(pQosContext); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED_NO_WMM; + default: + // we didn't get back one of the SME_QOS_STATUS_SETUP_* status codes + hdd_wmm_free_context(pQosContext); + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", __func__, smeStatus ); + VOS_ASSERT(0); + return HDD_WLAN_WMM_STATUS_SETUP_FAILED; + } +#endif + + // we were successful, save the status + mutex_lock(&pHddCtx->wmmLock); + if (pQosContext->magic == HDD_WMM_CTX_MAGIC) + { + pQosContext->lastStatus = status; + } + mutex_unlock(&pHddCtx->wmmLock); + + return status; +} + +/**============================================================================ + @brief hdd_wmm_delts() - Function which will delete a traffic spec at the + request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_delts( hdd_adapter_t* pAdapter, + v_U32_t handle ) +{ + hdd_wmm_qos_context_t *pQosContext; + v_BOOL_t found = VOS_FALSE; + WLANTL_ACEnumType acType = 0; + v_U32_t qosFlowId = 0; + hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_SETUP_SUCCESS ; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosStatusType smeStatus; +#endif + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered with handle 0x%x", __func__, handle); + + // locate the context with the given handle + mutex_lock(&pHddCtx->wmmLock); + list_for_each_entry(pQosContext, + &pAdapter->hddWmmStatus.wmmContextList, + node) + { + if (pQosContext->handle == handle) + { + found = VOS_TRUE; + acType = pQosContext->acType; + qosFlowId = pQosContext->qosFlowId; + break; + } + } + mutex_unlock(&pHddCtx->wmmLock); + + if (VOS_FALSE == found) + { + // we didn't find the handle + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: handle 0x%x not found", __func__, handle); + return HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM; + } + + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: found handle 0x%x, flow %d, AC %d, context %p", + __func__, handle, qosFlowId, acType, pQosContext); + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + smeStatus = sme_QosReleaseReq( WLAN_HDD_GET_HAL_CTX(pAdapter), qosFlowId ); + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: SME flow %d released, SME status %d", + __func__, qosFlowId, smeStatus); + + switch(smeStatus) + { + case SME_QOS_STATUS_RELEASE_SUCCESS_RSP: + // this flow is the only one on that AC, so go ahead and update + // our TSPEC state for the AC + pAdapter->hddWmmStatus.wmmAcStatus[acType].wmmAcTspecValid = VOS_FALSE; + + // need to tell TL to stop trigger timer, etc + hdd_wmm_disable_tl_uapsd(pQosContext); + +#ifdef FEATURE_WLAN_ESE + // disable the inactivity timer + hdd_wmm_disable_inactivity_timer(pQosContext); +#endif + // we are done with this context + hdd_wmm_free_context(pQosContext); + + // SME must not fire any more callbacks for this flow since the context + // is no longer valid + + return HDD_WLAN_WMM_STATUS_RELEASE_SUCCESS; + + case SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP: + // do nothing as we will get a response from SME + status = HDD_WLAN_WMM_STATUS_RELEASE_PENDING; + break; + + case SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP: + // nothing we can do with the existing flow except leave it + status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED_BAD_PARAM; + break; + + case SME_QOS_STATUS_RELEASE_FAILURE_RSP: + // nothing we can do with the existing flow except leave it + status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + + default: + // we didn't get back one of the SME_QOS_STATUS_RELEASE_* status codes + VOS_TRACE( VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + "%s: unexpected SME Status=%d", __func__, smeStatus ); + VOS_ASSERT(0); + status = HDD_WLAN_WMM_STATUS_RELEASE_FAILED; + } + +#endif + mutex_lock(&pHddCtx->wmmLock); + if (pQosContext->magic == HDD_WMM_CTX_MAGIC) + { + pQosContext->lastStatus = status; + } + mutex_unlock(&pHddCtx->wmmLock); + return status; +} + +/**============================================================================ + @brief hdd_wmm_checkts() - Function which will return the status of a traffic + spec at the request of an application + + @param pAdapter : [in] pointer to adapter context + @param handle : [in] handle to uniquely identify a TS + + @return : HDD_WLAN_WMM_STATUS_* + ===========================================================================*/ +hdd_wlan_wmm_status_e hdd_wmm_checkts( hdd_adapter_t* pAdapter, + v_U32_t handle ) +{ + hdd_wmm_qos_context_t *pQosContext; + hdd_wlan_wmm_status_e status = HDD_WLAN_WMM_STATUS_LOST; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + hdd_context_t *pHddCtx = NULL; + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("pVosContext is NULL")); + return HDD_WLAN_WMM_STATUS_LOST; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_ERROR, + FL("HddCtx is NULL")); + return HDD_WLAN_WMM_STATUS_LOST; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: Entered with handle 0x%x", __func__, handle); + + // locate the context with the given handle + mutex_lock(&pHddCtx->wmmLock); + list_for_each_entry(pQosContext, + &pAdapter->hddWmmStatus.wmmContextList, + node) + { + if (pQosContext->handle == handle) + { + VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, + "%s: found handle 0x%x, context %p", + __func__, handle, pQosContext); + + status = pQosContext->lastStatus; + break; + } + } + mutex_unlock(&pHddCtx->wmmLock); + return status; +} diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wowl.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wowl.c new file mode 100644 index 000000000000..ad3f5fa1a9bf --- /dev/null +++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_wowl.c @@ -0,0 +1,611 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + * @file wlan_hdd_wowl.c + * + * + * ==========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + +#include +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +#define WOWL_PTRN_MAX_SIZE 128 +#define WOWL_PTRN_MASK_MAX_SIZE 16 +#define WOWL_MAX_PTRNS_ALLOWED 16 +#define WOWL_INTER_PTRN_TOKENIZER ';' +#define WOWL_INTRA_PTRN_TOKENIZER ':' + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +static char *g_hdd_wowl_ptrns[WOWL_MAX_PTRNS_ALLOWED]; //Patterns 0-15 +static v_BOOL_t g_hdd_wowl_ptrns_debugfs[WOWL_MAX_PTRNS_ALLOWED] = {0}; +static v_U8_t g_hdd_wowl_ptrns_count = 0; + +int hdd_parse_hex(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c-'0'; + if (c >= 'a' && c <= 'f') + return c-'a'+10; + if (c >= 'A' && c <= 'F') + return c-'A'+10; + + return 0; +} + +static inline int find_ptrn_len(const char* ptrn) +{ + int len = 0; + while (*ptrn != '\0' && *ptrn != WOWL_INTER_PTRN_TOKENIZER) + { + len++; ptrn++; + } + return len; +} + +static void hdd_wowl_callback( void *pContext, eHalStatus halStatus ) +{ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Return code = (%d)", __func__, halStatus ); +} + +#ifdef WLAN_WAKEUP_EVENTS +static void hdd_wowl_wakeIndication_callback( void *pContext, + tpSirWakeReasonInd pWakeReasonInd ) +{ + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Wake Reason %d", + __func__, pWakeReasonInd->ulReason ); + hdd_exit_wowl( (hdd_adapter_t *)pContext, eWOWL_EXIT_WAKEIND ); +} +#endif + +static void dump_hdd_wowl_ptrn(tSirWowlAddBcastPtrn *ptrn) +{ + int i; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatetrnId = 0x%x", __func__, + ptrn->ucPatternId); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternByteOffset = 0x%x", __func__, + ptrn->ucPatternByteOffset); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternSize = 0x%x", __func__, + ptrn->ucPatternSize); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ucPatternMaskSize = 0x%x", __func__, + ptrn->ucPatternMaskSize); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Pattern: ", __func__); + for(i = 0; i < ptrn->ucPatternSize; i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", ptrn->ucPattern[i]); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: PatternMask: ", __func__); + for(i = 0; iucPatternMaskSize; i++) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%02X", ptrn->ucPatternMask[i]); +} + + +/**============================================================================ + @brief hdd_add_wowl_ptrn() - Function which will add the WoWL pattern to be + used when PBM filtering is enabled + + @param ptrn : [in] pointer to the pattern string to be added + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_add_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn) +{ + tSirWowlAddBcastPtrn localPattern; + int i, first_empty_slot, len, offset; + eHalStatus halStatus; + const char *temp; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_U8_t sessionId = pAdapter->sessionId; + + len = find_ptrn_len(ptrn); + + /* There has to have atleast 1 byte for each field (pattern size, mask size, + * pattern, mask) e.g. PP:QQ:RR:SS ==> 11 chars */ + while ( len >= 11 ) + { + first_empty_slot = -1; + + // Find an empty slot to store the pattern + for (i=0; i SIR_WOWL_BCAST_PATTERN_MAX_SIZE || + localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid length specified. Skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + //compute the offset of tokenizer after the pattern + offset = 5 + 2*localPattern.ucPatternSize + 1; + if(offset >= len || ptrn[offset] != WOWL_INTRA_PTRN_TOKENIZER) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern string..skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + //compute the end of pattern sring + offset = offset + 2*localPattern.ucPatternMaskSize; + if(offset+1 != len) //offset begins with 0 + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed pattern string...skip!", __func__); + ptrn += len; + goto next_ptrn; + } + + temp = ptrn; + + // Now advance to where pattern begins + ptrn += 6; + + // Extract the pattern + for(i=0; i < localPattern.ucPatternSize; i++) + { + localPattern.ucPattern[i] = + (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] ); + ptrn += 2; //skip to next byte + } + + ptrn++; // Skip over the ':' seperator after the pattern + + // Extract the pattern Mask + for(i=0; i < localPattern.ucPatternMaskSize; i++) + { + localPattern.ucPatternMask[i] = + (hdd_parse_hex( ptrn[0] ) * 0x10 ) + hdd_parse_hex( ptrn[1] ); + ptrn += 2; //skip to next byte + } + + //All is good. Store the pattern locally + g_hdd_wowl_ptrns[first_empty_slot] = (char*) kmalloc(len+1, GFP_KERNEL); + if(g_hdd_wowl_ptrns[first_empty_slot] == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: kmalloc failure", __func__); + return VOS_FALSE; + } + + memcpy(g_hdd_wowl_ptrns[first_empty_slot], temp, len); + g_hdd_wowl_ptrns[first_empty_slot][len] = '\0'; + localPattern.ucPatternId = first_empty_slot; + localPattern.ucPatternByteOffset = 0; + + // Register the pattern downstream + halStatus = sme_WowlAddBcastPattern( hHal, &localPattern, sessionId ); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + // Add failed, so invalidate the local storage + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_WowlAddBcastPattern failed with error code (%d)", halStatus ); + kfree(g_hdd_wowl_ptrns[first_empty_slot]); + g_hdd_wowl_ptrns[first_empty_slot] = NULL; + } + + dump_hdd_wowl_ptrn(&localPattern); + + next_ptrn: + if (*ptrn == WOWL_INTER_PTRN_TOKENIZER) + { + ptrn += 1; // move past the tokenizer + len = find_ptrn_len(ptrn); + continue; + } + else + break; + } + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_del_wowl_ptrn() - Function which will remove a WoWL pattern + + @param ptrn : [in] pointer to the pattern string to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn (hdd_adapter_t *pAdapter, const char * ptrn) +{ + tSirWowlDelBcastPtrn delPattern; + unsigned char id; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + v_BOOL_t patternFound = VOS_FALSE; + eHalStatus halStatus; + v_U8_t sessionId = pAdapter->sessionId; + + // Detect pattern + for (id=0; idsessionId; + v_U16_t pattern_len, mask_len, i; + + if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern index %d is out of range (0 ~ %d).", + __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1); + + return VOS_FALSE; + } + + pattern_len = strlen(pattern_buf); + + /* Since the pattern is a hex string, 2 characters represent 1 byte. */ + if (pattern_len % 2) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed WoW pattern!", __func__); + + return VOS_FALSE; + } + else + pattern_len >>= 1; + + if (!pattern_len || pattern_len > WOWL_PTRN_MAX_SIZE) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern length %d is out of range (1 ~ %d).", + __func__, pattern_len, WOWL_PTRN_MAX_SIZE); + + return VOS_FALSE; + } + + localPattern.ucPatternId = pattern_idx; + localPattern.ucPatternByteOffset = pattern_offset; + localPattern.ucPatternSize = pattern_len; + if (localPattern.ucPatternSize > SIR_WOWL_BCAST_PATTERN_MAX_SIZE) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern size (%d) greater than max (%d)", + __func__, localPattern.ucPatternSize, + SIR_WOWL_BCAST_PATTERN_MAX_SIZE); + return VOS_FALSE; + } + /* Extract the pattern */ + for (i = 0; i < localPattern.ucPatternSize; i++) + { + localPattern.ucPattern[i] = + (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]); + + /* Skip to next byte */ + pattern_buf += 2; + } + + /* Get pattern mask size by pattern length */ + localPattern.ucPatternMaskSize = pattern_len >> 3; + if (pattern_len % 8) + localPattern.ucPatternMaskSize += 1; + + mask_len = strlen(pattern_mask); + if ((mask_len % 2) || (localPattern.ucPatternMaskSize != (mask_len >> 1))) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Malformed WoW pattern mask!", __func__); + + return VOS_FALSE; + } + if (localPattern.ucPatternMaskSize > WOWL_PTRN_MASK_MAX_SIZE) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern mask size (%d) greater than max (%d)", + __func__, localPattern.ucPatternMaskSize, WOWL_PTRN_MASK_MAX_SIZE); + return VOS_FALSE; + } + /* Extract the pattern mask */ + for (i = 0; i < localPattern.ucPatternMaskSize; i++) + { + localPattern.ucPatternMask[i] = + (hdd_parse_hex(pattern_mask[0]) << 4) + hdd_parse_hex(pattern_mask[1]); + + /* Skip to next byte */ + pattern_mask += 2; + } + + /* Register the pattern downstream */ + halStatus = sme_WowlAddBcastPattern(hHal, &localPattern, sessionId); + + if (!HAL_STATUS_SUCCESS(halStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_WowlAddBcastPattern failed with error code (%d).", + __func__, halStatus); + + return VOS_FALSE; + } + + /* All is good. */ + if (!g_hdd_wowl_ptrns_debugfs[pattern_idx]) + { + g_hdd_wowl_ptrns_debugfs[pattern_idx] = 1; + g_hdd_wowl_ptrns_count++; + } + + dump_hdd_wowl_ptrn(&localPattern); + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_del_wowl_ptrn_debugfs() - Function which will remove a WoW pattern + sent from debugfs interface + + @param pAdapter : [in] pointer to the adapter + pattern_idx : [in] index of the pattern to be removed + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_del_wowl_ptrn_debugfs(hdd_adapter_t *pAdapter, v_U8_t pattern_idx) +{ + tSirWowlDelBcastPtrn delPattern; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + eHalStatus halStatus; + v_U8_t sessionId = pAdapter->sessionId; + + if (pattern_idx > (WOWL_MAX_PTRNS_ALLOWED - 1)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern index %d is not in the range (0 ~ %d).", + __func__, pattern_idx, WOWL_MAX_PTRNS_ALLOWED - 1); + + return VOS_FALSE; + } + + if (!g_hdd_wowl_ptrns_debugfs[pattern_idx]) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: WoW pattern %d is not in the table.", + __func__, pattern_idx); + + return VOS_FALSE; + } + + delPattern.ucPatternId = pattern_idx; + halStatus = sme_WowlDelBcastPattern(hHal, &delPattern, sessionId); + + if (!HAL_STATUS_SUCCESS(halStatus)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: sme_WowlDelBcastPattern failed with error code (%d).", + __func__, halStatus); + + return VOS_FALSE; + } + + g_hdd_wowl_ptrns_debugfs[pattern_idx] = 0; + g_hdd_wowl_ptrns_count--; + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_enter_wowl() - Function which will enable WoWL. Atleast one + of MP and PBM must be enabled + + @param enable_mp : [in] Whether to enable magic packet WoWL mode + @param enable_pbm : [in] Whether to enable pattern byte matching WoWL mode + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_enter_wowl (hdd_adapter_t *pAdapter, v_BOOL_t enable_mp, v_BOOL_t enable_pbm) +{ + tSirSmeWowlEnterParams wowParams; + eHalStatus halStatus; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + + vos_mem_zero( &wowParams, sizeof( tSirSmeWowlEnterParams ) ); + + wowParams.ucPatternFilteringEnable = enable_pbm; + wowParams.ucMagicPktEnable = enable_mp; + if(enable_mp) + { + vos_copy_macaddr( (v_MACADDR_t *)&(wowParams.magicPtrn), + &(pAdapter->macAddressCurrent) ); + } + +#ifdef WLAN_WAKEUP_EVENTS + wowParams.ucWoWEAPIDRequestEnable = VOS_TRUE; + wowParams.ucWoWEAPOL4WayEnable = VOS_TRUE; + wowParams.ucWowNetScanOffloadMatch = VOS_TRUE; + wowParams.ucWowGTKRekeyError = VOS_TRUE; + wowParams.ucWoWBSSConnLoss = VOS_TRUE; +#endif // WLAN_WAKEUP_EVENTS + + // Request to put Libra into WoWL + halStatus = sme_EnterWowl( hHal, hdd_wowl_callback, + pAdapter, +#ifdef WLAN_WAKEUP_EVENTS + hdd_wowl_wakeIndication_callback, + pAdapter, +#endif // WLAN_WAKEUP_EVENTS + &wowParams, pAdapter->sessionId); + + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + if ( eHAL_STATUS_PMC_PENDING != halStatus ) + { + // We failed to enter WoWL + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_EnterWowl failed with error code (%d)", halStatus ); + return VOS_FALSE; + } + } + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_exit_wowl() - Function which will disable WoWL + + @param wowlExitSrc: To know is wowl exiting because of wakeup pkt or user + explicitly disabling WoWL + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_exit_wowl (hdd_adapter_t*pAdapter, tWowlExitSource wowlExitSrc) +{ + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + eHalStatus halStatus; + + halStatus = sme_ExitWowl( hHal, wowlExitSrc ); + if ( !HAL_STATUS_SUCCESS( halStatus ) ) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "sme_ExitWowl failed with error code (%d)", halStatus ); + return VOS_FALSE; + } + + return VOS_TRUE; +} + +/**============================================================================ + @brief hdd_init_wowl() - Init function which will initialize the WoWL module + and perform any required intial configuration + + @return : FALSE if any errors encountered + : TRUE otherwise + ===========================================================================*/ +v_BOOL_t hdd_init_wowl (hdd_adapter_t*pAdapter) +{ + hdd_context_t *pHddCtx = NULL; + pHddCtx = pAdapter->pHddCtx; + + memset(g_hdd_wowl_ptrns, 0, sizeof(g_hdd_wowl_ptrns)); + + //Add any statically configured patterns + hdd_add_wowl_ptrn(pAdapter, pHddCtx->cfg_ini->wowlPattern); + + return VOS_TRUE; +} diff --git a/drivers/staging/prima/CORE/MAC/inc/aniCompiler.h b/drivers/staging/prima/CORE/MAC/inc/aniCompiler.h new file mode 100644 index 000000000000..aa1388bdcbfd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/aniCompiler.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * Compiler abstraction layer + * + * + * + * This file tries to abstract the differences among compilers. + * Supported compilers are : + * + * - GNU C/C++ compiler + * - Microsoft C/C++ compiler + * - Intel C/C++ compiler + * + * Written by Ho Lee + */ + +#ifndef __ANI_COMPILER_ABSTRACT_H +#define __ANI_COMPILER_ABSTRACT_H + +/* + * 1. GNU C/C++ Compiler + * + * How to detect gcc : __GNUC__ + * How to detect gcc version : + * major version : __GNUC__ (2 = 2.x, 3 = 3.x, 4 = 4.x) + * minor version : __GNUC_MINOR__ + * + * 2. Microsoft C/C++ Compiler + * + * How to detect msc : _MSC_VER + * How to detect msc version : + * _MSC_VER (1200 = MSVC 6.0, 1300 = MSVC 7.0, ...) + * + * 3. Intel C/C++ Compiler + * + * How to detect icc : __INTEL_COMPILER, __ICC (legacy), __ECC (legacy) + * How to detect icc version : + * __INTEL_COMPILER, __ICC, __ECC (700 = 7.0, 900 = 9.0, ...) + * + * 4. Other compilers (not supported) + * + * Borland : __BORLANDC__ + * Greenhills : __ghs + * Metrowerks : __MWERKS__ + * SGI MIPSpro : __sgi + */ + +/* + * Packing directives : These are used to force compiler to pack bits and + * bytes in the data structure. C standard does not regulate this strictly, + * and many things are to compiler implementation. Many compilers support + * compiler specific directives or options that allow different packing + * and alignment. + * + * Alignment directives : Compiler may think packed data structures have + * no specific alignment requirement. Then compiler may generate multiple + * byte accesses to access two byte or four bytes data structures. This + * affects on performance especially for RISC systems. If some data + * structure is located on specific alignment always, alignment directives + * help compiler generate more efficient codes. + */ + +#undef __ANI_COMPILER_PRAGMA_PACK_STACK +#undef __ANI_COMPILER_PRAGMA_PACK + +#if defined(_MSC_VER) +#define __ANI_COMPILER_PRAGMA_PACK_STACK 1 +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(__ECC) +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#elif defined(__GNUC__) +#define __ani_attr_pre_packed +#define __ani_attr_packed __packed +#define __ani_attr_aligned_2 __attribute__((aligned(2))) +#define __ani_attr_aligned_4 __attribute__((aligned(4))) +#define __ani_attr_aligned_8 __attribute__((aligned(8))) +#define __ani_attr_aligned_16 __attribute__((aligned(16))) +#define __ani_attr_aligned_32 __attribute__((aligned(32))) +#elif defined(ANI_COMPILER_TYPE_RVCT) +/* Nothing defined so far */ +#define __ani_attr_packed +#define __ani_attr_pre_packed __packed +#define __ani_attr_aligned_2 __align(2) +#define __ani_attr_aligned_4 __align(4) +#define __ani_attr_aligned_8 __align(8) +#define __ani_attr_aligned_16 __align(16) +#define __ani_attr_aligned_32 __align(32) +#else +#error "Unknown compiler" +#endif + +#if defined(ANI_DATAPATH_SECTION) +#define __DP_SRC_RX __attribute__((section(".dpsrcrx"))) +#define __DP_SRC_TX __attribute__((section(".dpsrctx"))) +#define __DP_SRC __attribute__((section(".dpsrc"))) +#define __ANIHDD_MODULE __attribute__((section(".anihdd"))) +#else +#define __DP_SRC_RX +#define __DP_SRC_TX +#define __DP_SRC +#define __ANIHDD_MODULE +#endif + +#endif + diff --git a/drivers/staging/prima/CORE/MAC/inc/aniDbgTest.h b/drivers/staging/prima/CORE/MAC/inc/aniDbgTest.h new file mode 100644 index 000000000000..3f30dd4435cd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/aniDbgTest.h @@ -0,0 +1,1588 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _ANIDBGTEST_H_ +#define _ANIDBGTEST_H_ + +#include "sirTypes.h" + +#define MAX_PARMS_SIZE 256 +#define MAX_RESPONSE_SIZE 512 +#define MAX_PCI_CFG_WRDS 19 +#define MAX_NUM_TST_STAS_PER_AP 3 + +#define ANI_PCI_CFG_MIN_GNT 4 +#define ANI_PCI_CFG_MAX_LAT 32 +/// EEPROM Product Ids for different types of NICs. +#define EEP_PRODUCT_ID_MPCI_3_2 1 +#define EEP_PRODUCT_ID_MPCI_2_2 2 +#define EEP_PRODUCT_ID_CARDBUS 3 +#define EEP_PRODUCT_ID_HEAP_W_INT 4 +#define EEP_PRODUCT_ID_HEAP_W_EXT 5 +#define EEP_PRODUCT_ID_MRAP 6 + +#define ANI_CARDBUS_EXPECTED_CIS \ + (((0x3416 + sizeof(tPolSystemParameters)) << 3)|1) + + +/// Here is an example of a test structure +typedef enum sANI_TEST_ID +{ + // All DVT test Ids, beginning with BMU, INT, HIF, SP, TFP, RHP, + // RFP, SYS, PHY, SPI, CYG, LO, and EEPROM in the order specified. + ANI_TESTID_NONE = 0, + + // PLEASE PRESERVE THE ORDER; IF YOU NEED TO CHANGE. + // TEST SCRIPTS DEPEND ON THIS ORDER. + + ANI_BUS_ACCESS_TEST, + ANI_MEMORY_TEST, + ANI_INTERRUPT_TEST, + ANI_REG_READ_WRITE_TEST, + ANI_BMU_INIT_PDU_TEST, + ANI_HASH_TBL_ADD_DEL_GET_TEST_ID, + ANI_HASH_TBL_MULT_ENTRY_TEST_ID, + + // Data path tests + ANI_SEND_CONTINUOUS_TEST, + ANI_PKT_ROUTING_TEST, + + ANI_ADD_STA_TEST_ID, + ANI_DELETE_STA_TEST_ID, + + // HIF Tests + ANI_BURST_READ_WRITE_TEST_ID, + ANI_MOVE_ACK_TEST_ID, + ANI_RESET_WQ_TEST_ID, + ANI_HIF_LPBK_TEST_ID, + + // SP Tests + + // TFP Tests + ANI_BCN_GEN_TEST_ID, + + // RHP Tests + + ANI_HASH_TBL_DELETE_TEST_ID, + ANI_HASH_TBL_GET_TEST_ID, + + // RHP Tests + ANI_AGING_TEST_ID, + ANI_COUNTERS_TEST_ID, + + // SYS Tests + ANI_SET_PROMOSCOUS_MODE_TEST_ID, + ANI_SET_SCAN_MODE_TEST_ID, + + // SPI Tests + ANI_SET_CYG_REG_READ_WRITE_TEST_ID, + + // CYG Tests + ANI_SET_BB_CAL_TEST_ID, + + // LO Tests + ANI_SET_LO_CHAN_TEST_ID, + + // EEPROM Tests + + // Cal test + ANI_CAL_TEST_ID, + + // HIF Burst DMA test + ANI_HIF_BURST_DMA_TEST_ID, + + // Add all your test Ids above this. + ANI_TESTS_MAX +} tANI_TEST_ID; + +/// Test IDs for tests directly handled by the HDD +typedef enum sANI_HDD_TEST_ID { + ANI_HDD_TESTS_START = 0x10000, + ANI_PCI_CFG_TEST = ANI_HDD_TESTS_START, + ANI_EEPROM_TEST, + + // Add all your HDD test Ids above this. + ANI_HDD_TESTS_MAX + +} tANI_HDD_TEST_ID; + +/// Test trigger types can be enhanced with this enumeration +typedef enum sANI_TEST_TRIG_TYPE +{ + ANI_TRIG_TYPE_NONE = 0, + + ANI_TRIG_TYPE_CFG, + ANI_TRIG_TYPE_START, + ANI_TRIG_TYPE_GET_RESULTS, + ANI_TRIG_TYPE_STOP, + + ANI_TRIG_TYPE_MAX +} tANI_TEST_TRIG_TYPE; + +/// Test states +typedef enum sANI_DBG_TEST_STATE +{ + ANI_TEST_STATE_IDLE = 0, + ANI_TEST_STATE_IN_PROGRESS, + ANI_TEST_STATE_DONE + +} tANI_DBG_TEST_STATE; + +/** + * The following CFG Types are defined for each type of a parameter that can + * be independently set + */ +typedef enum sANI_DBG_CFG_TYPES +{ + ANI_DBG_CFG_PHY_MODE_RATE, + ANI_DBG_CFG_ROUTING_FLAGS, + ANI_DBG_CFG_STA_ID, + ANI_DBG_CFG_IS_INFRASTRUCTURE_MODE, + ANI_DBG_CFG_USE_REAL_PHY, + ANI_DBG_CFG_PHY_DROPS, + ANI_DBG_CFG_ADD_STA, + ANI_DBG_CFG_DEL_STA, + ANI_DBG_CFG_ENABLE_STA_TX, + ANI_DBG_CFG_DISABLE_STA_TX, + ANI_DBG_CFG_READ_REGISTER, + ANI_DBG_CFG_WRITE_REGISTER, + ANI_DBG_CFG_GET_ARQ_WINDOW_SIZE, + ANI_DBG_CFG_SET_ARQ_WINDOW_SIZE, + ANI_DBG_CFG_SET_CHANNEL, + ANI_DBG_CFG_SET_MAC_ADDRESS, + ANI_DBG_CFG_SET_MEM, + ANI_DBG_CFG_GET_MEM, + ANI_DBG_CFG_CTRL_TXWQ, + ANI_DBG_CFG_GET_ACTIVITY_SET, + ANI_DBG_CFG_SET_ACK_POLICY, + ANI_DBG_CFG_AGING_CMD, + ANI_DBG_CFG_SET_KEY, + ANI_DBG_CFG_SET_PER_STA_KEY, + ANI_DBG_CFG_TFP_ABORT, + ANI_DBG_CFG_GET_ACT_CHAINS, + ANI_DBG_CFG_IS_CHAIN_ACTIVE, + ANI_DBG_CFG_BB_FILTER_CAL, + ANI_DBG_CFG_DCO_CAL, + ANI_DBG_CFG_IQ_CAL, + ANI_DBG_CFG_TX_LO_LEAKAGE_CAL, + ANI_DBG_CFG_SEND_PKTS, + ANI_DBG_CFG_STOP_PKTS, + ANI_DBG_CFG_ENABLE_DISABLE_BEACON_GEN, + ANI_DBG_CFG_DCO_GET, + ANI_DBG_CFG_DCO_SET, + ANI_DBG_CFG_SET_PWR_TEMPL, + ANI_DBG_CFG_GET_PWR_TEMPL, + ANI_DBG_CFG_INIT, + ANI_DBG_CFG_SET_EEPROM_FLD, + ANI_DBG_CFG_GET_EEPROM_FLD, + ANI_DBG_CFG_SET_NUM_TRANSMITTERS, + ANI_DBG_CFG_SET_RX_CHAINS, + ANI_DBG_CFG_HCF_TEST, + ANI_DBG_CFG_POLARIS_REV_ID, + ANI_DBG_CFG_UPDATE_DATA_FROM_EEPROM, + ANI_DBG_CFG_GET_TEMP, + ANI_DBG_CFG_SET_STA_ADDRLST, + ANI_DBG_CFG_GET_PWR_GAIN, + ANI_DBG_CFG_SW_CLOSED_LOOP_TPC, + + ANI_DBG_CFG_TYPE_MAX +} tANI_DBG_CFG_TYPES; + +/** + * The following are the length definitions for each CFG TYPE defined + * in earlier Type enum. + */ + +// first byte mode and second rate +# define ANI_DBG_CFG_PHY_MODE_RATE_LEN 2 + +// MSN is type and LSN is sub-type in the MSB. 4 LSBs are routing flags +# define ANI_DBG_CFG_ROUTING_FLAGS_LEN 5 + +# define ANI_DBG_CFG_STA_ID_LEN 2 + +// ====================================================================== +// +// Following are the structure definitions for the config input parameters +// +// ====================================================================== +// +// -------------------------------------------------------- + +// -------------------------------------------------------- +// Output Params for Read Register Config request +typedef struct sAniDbgCfgGetPolarisVersionResponse +{ + // Output parameters + unsigned int rc; // 0 - SUCCESS + unsigned long version; +} tAniDbgCfgGetPolarisVersionResponse, *tpAniDbgCfgGetPolarisVersionResponse; + +// ------------------------------------------------------------- +// Input Params for the Phy Mode Rate + +typedef struct sAniDbgCfgPhyModeRateParams +{ + unsigned int phyMode; + unsigned int phyRate; +} tAniDbgCfgPhyModeRateParams, *tpAniDbgCfgPhyModeRateParams; + +// -------------------------------------------------------- +// Input Params for the Routing Flags +typedef struct sAniDbgCfgRoutingFlagsParams +{ + unsigned int type; + unsigned int subType; + unsigned int routingFlags; +} tAniDbgCfgRoutingFlagsParams, *tpAniDbgCfgRoutingFlagsParams; + +// -------------------------------------------------------- +// Input Params for the STA ID +typedef struct sAniDbgCfgStaIdParams +{ + unsigned int staId; +} tAniDbgCfgStaIdParams, *tpAniDbgCfgStaIdParams; + +// -------------------------------------------------------- +// Input Params for "Is Infrastructure Mode" +typedef struct sAniDbgCfgIsInfrastructureParams +{ + unsigned int isInfrastructureMode; +} tAniDbgCfgIsInfrastructureParams, *tpAniDbgCfgIsInfrastructureParams; + +// -------------------------------------------------------- +// Input Params for the Real Phy +typedef struct sAniDbgCfgRealPhyParams +{ + unsigned int useRealPhy; +} tAniDbgCfgRealPhyParams, *tpAniDbgCfgRealPhyParams; + +// -------------------------------------------------------- +// Input Params for Phy Drops +typedef struct sAniDbgCfgPhyDropParams +{ + unsigned int usePhyDrops; + unsigned int rate; + unsigned int burstSize; + unsigned int mode; +} tAniDbgCfgPhyDropParams, *tpAniDbgCfgPhyDropParams; + +// -------------------------------------------------------- +// Input Params for Add Sta +typedef struct sAniDbgCfgAddStaParams +{ + unsigned int staId; + unsigned char macAddr[6]; + unsigned int phyMode; + unsigned int rate; + unsigned int skipSP; + unsigned int ackPolicy; +} tAniDbgCfgAddStaParams, *tpAniDbgCfgAddStaParams; + +// -------------------------------------------------------- +// Input Params for Delete Sta +typedef struct sAniDbgCfgDelStaParams +{ + unsigned int staId; + unsigned char macAddr[6]; +} tAniDbgCfgDelStaParams, *tpAniDbgCfgDelStaParams; + +// -------------------------------------------------------- +// Lowest register address allowable for the Read Register calls +#define ANI_TIT_MIN_REG_ADDR 0x02000000 + + +// -------------------------------------------------------- +// Highest register address allowable for the Read Register call +#define ANI_TIT_MAX_REG_ADDR 0x0203ffff + +// -------------------------------------------------------- +// Input Params for Read Register Config request +typedef struct sAniDbgCfgReadRegParams +{ + unsigned long regAddr; +} tAniDbgCfgReadRegParams, *tpAniDbgCfgReadRegParams; + +// -------------------------------------------------------- +// Input Params for Write Register Config request +typedef struct sAniDbgCfgWriteRegParams +{ + unsigned long regAddr; + unsigned long regVal; +} tAniDbgCfgWriteRegParams, *tpAniDbgCfgWriteRegParams; + + + + +// -------------------------------------------------------- +// ANI_DBG_CFG_SET_CAL_TONE, +typedef struct +{ + unsigned long toneID; //0 = -28, 1 = -24, ..., 6 = -4, 7 = +4, 8 = +8, 9 = +12, ..., 13 = +28 +}tAniDbgCfgSetToneId, *tpAniDbgCfgSetToneId; + + +// -------------------------------------------------------- +// Output Params for Read Register Config request +typedef struct sAniDbgCfgRegReadResponse +{ + // Output parameters + unsigned int rc; // 0 - SUCCESS + unsigned long regVal; +} tAniDbgCfgReadRegResponse, *tpAniDbgCfgReadRegResponse; + +// -------------------------------------------------------- +// Output Params for getting ARQ Window +typedef struct sAniDbgCfgGetArqWindowResponse +{ + unsigned int rc; // 0 - SUCCESS + unsigned long val; +} tAniDbgCfgGetArqWindowResponse, *tpAniDbgCfgGetArqWindowResponse; + +// -------------------------------------------------------- +// Input Params for Write Register Config request +typedef struct sAniDbgCfgSetArqWindowParams +{ + unsigned long windowSize; +} tAniDbgCfgSetArqWindowRegParams, *tpAniDbgCfgSetArqWindowParams; + +// -------------------------------------------------------- +// Input Params for Write Register Config request +typedef struct sAniDbgCfgSetChanParams +{ + unsigned long chId; +} tAniDbgCfgSetChanParams, *tpAniDbgCfgSetChanParams; + + +// -------------------------------------------------------- +// Input Params for Write Register Config request +typedef struct sAniDbgCfgSetMacAddrParams +{ + unsigned char macAddr[6]; + unsigned int flag; // 0 - BSSID; 1 - MAC Address of DUT +} tAniDbgCfgSetMacAddrParams, *tpAniDbgCfgSetMacAddrParams; + +// -------------------------------------------------------- +// Input Params for Set Memory request +typedef struct sAniDbgCfgSetMemoryParams +{ + unsigned int fUseBurstDma; + unsigned int numOfWords; + unsigned int ahbAddr; + unsigned int writeData; // Pattern to be written out in memory +} tAniDbgCfgSetMemoryParams, *tpAniDbgCfgSetMemoryParams; + +// -------------------------------------------------------- +// Input Params for Get Memory request +typedef struct sAniDbgCfgGetMemoryParams +{ + unsigned int fUseBurstDma; + unsigned int numOfWords; + unsigned int ahbAddr; +} tAniDbgCfgGetMemoryParams, *tpAniDbgCfgGetMemoryParams; + +// -------------------------------------------------------- +// Response structure for the Get Memory request +typedef struct sAniDbgCfgGetMemoryResponse +{ + unsigned int rc; // 0 - SUCCESS; Otherwise FAILED + unsigned int readData[1]; +} tAniDbgCfgGetMemoryResponse, *tpAniDbgCfgGetMemoryResponse; + + +// -------------------------------------------------------- +// Input Params for Controls Enable/Disable of TX WQ +typedef struct sAniDbgCfgCtrlTxWqParams +{ + unsigned int staId; + unsigned int wqId; + unsigned int action; // 0 - Disable; 1 - Enable + +} tAniDbgCfgCtrlTxWqParams, *tpAniDbgCfgCtrlTxWqParams; + +// -------------------------------------------------------- +// Input Params for Getting TX/RX Activity Set +typedef struct sAniDbgCfgGetAsParams +{ + unsigned int id; // 0 - tx; 1 - rx + +} tAniDbgCfgGetAsParams, *tpAniDbgCfgGetAsParams; + +// Input Params for Getting TX/RX Activity Set +typedef struct sAniDbgCfgGetAsResponse +{ + unsigned int rc; // 0 - Success + unsigned int nEntries; + unsigned int entries[64]; + +} tAniDbgCfgGetAsResponse, *tpAniDbgCfgGetAsResponse; + +// -------------------------------------------------------- +// Input Params for Set ACK Policy +typedef struct sAniDbgCfgSetAckPolicyParams +{ + unsigned int id; // 0 - tx; 1 - rx + unsigned int policy; + unsigned int staId; + unsigned int tcId; + +} tAniDbgCfgSetAckPolicyParams, *tpAniDbgCfgSetAckPolicyParams; + +// -------------------------------------------------------- +// Input Params to Run AGING command +typedef struct sAniDbgCfgAgingCmdParams +{ + unsigned int staId; + unsigned int tcId; + +} tAniDbgCfgAgingCmdParams, *tpAniDbgCfgAgingCmdParams; + +// -------------------------------------------------------- +// Input Params to TFP Abort command +typedef struct sAniDbgCfgTfpAbortParams +{ + unsigned int staId; + +} tAniDbgCfgTfpAbortParams, *tpAniDbgCfgTfpAbortParams; + +// -------------------------------------------------------- +// Input Params to Enable/Disable Beacon command +typedef struct sAniDbgCfgEnableBeaconParams +{ + unsigned int fEnableBeacons; + +} tAniDbgCfgEnableBeaconParams, *tpAniDbgCfgEnableBeaconParams; + +// -------------------------------------------------------- +// Input Params to SET WEP / AES MULTICAST KEY +typedef struct sAniDbgCfgSetKeyParams +{ + unsigned int type; // 0 - WEP; 1 - AES + unsigned int keyId; // If AES, 0 - TX; 1 - RX + unsigned int keyLen; + unsigned char key[16]; + +} tAniDbgCfgSetKeyParams, *tpAniDbgCfgSetKeyParams; + +// -------------------------------------------------------- +// Input Params to SET per STA keys +typedef struct sAniDbgCfgSetPerStaKeyParams +{ + unsigned int staId; + unsigned int id0; + unsigned int id1; + unsigned int keyValid; // 0 - Tx; Anything else Rx + unsigned int useDefaultKey; + unsigned int defaultKeyId; + unsigned int edPolicy; + unsigned char key[16]; + unsigned char keylen; + +} tAniDbgCfgSetPerStaKeyParams, *tpAniDbgCfgSetPerStaKeyParams; + +// -------------------------------------------------------- +// Cal test and Set Chan functions +typedef struct sAniDbgCalTestParams +{ + unsigned int id; // 0 - Cal; 1 - Set Channel + unsigned int chId; // if id == 1; then chId is 1 - 14 or 36 - end of 11a +}tAniDbgCalTestParams, *tpAniDbgCalTestParams; + +typedef struct sAniDbgCalTestResponse +{ + unsigned int rc; +}tAniDbgCalTestResponse, *tpAniDbgCalTestResponse; + +// --------------------------------------------------------- +// Input params to Get DCO params +typedef struct sAniDbgCfgGetDcoParams +{ + unsigned int chain; + unsigned int address; +} tAniDbgCfgGetDcoParams, *tpAniDbgCfgGetDcoParams; + +typedef struct sAniDbgCfgGetDcoResponse +{ + unsigned int rc; + unsigned int val; +} tAniDbgCfgGetDcoResponse, *tpAniDbgCfgGetDcoResponse; + +// -------------------------------------------------------- +// Input params to Get DCO params +typedef struct sAniDbgCfgSetDcoParams +{ + unsigned int chain; + unsigned int address; + unsigned int val; +} tAniDbgCfgSetDcoParams, *tpAniDbgCfgSetDcoParams; + +// -------------------------------------------------------- +// Input params to setting power template +typedef struct sAniDbgCfgSetPwrTemplParams +{ + unsigned int staId; + unsigned int mode; + unsigned int rate; +} tAniDbgCfgSetPwrTemplParams, *tpAniDbgCfgSetPwrTemplParams; + + +// Response struct for Getting power template +typedef struct sAniDbgCfgGetPwrTemplParams +{ + unsigned int staId; +} tAniDbgCfgGetPwrTemplParams, *tpAniDbgCfgGetPwrTemplParams; + +// -------------------------------------------------------- +// Request struct for Setting the init config parameters +typedef struct sAniDbgCfgInitParams +{ + unsigned int mode; // default mode + unsigned int rate; // default rate + unsigned int fIsInfMode; // Set 1 for infrastructure mode + unsigned int staId; + unsigned char ownMacAddr[6]; // Set the configured MAC address + unsigned int fFwd2Host; // Set 1 to Forward data to host + unsigned int fUseRealPhy; // Set 1 to use the real Phy + unsigned int fEnablePhyDrops; // Set 1 to enable Phy drops + unsigned int dropModeRate; // Set this when Phy drops are enabled + unsigned int dropModeSize; // Set this when Phy drops are enabled + unsigned int dropModeMode; // Set this when Phy drops are enabled +} tAniDbgCfgInitParams, *tpAniDbgCfgInitParams; + + +// Response struct for Getting power template +typedef struct sAniDbgCfgGetPwrTemplResponse +{ + unsigned int rc; + unsigned int val; +} tAniDbgCfgGetPwrTemplResponse, *tpAniDbgCfgGetPwrTemplResponse; + + +// -------------------------------------------------------- +// Input params for setting a field in the EEPROM + +typedef union sAniDbgCfgEepByteSetParams +{ + unsigned char mask; + unsigned char value; + +} tAniDbgCfgEepByteSetParams, *tpAniDbgCfgEepByteSetParams; + + +// Request struct for Setting the EEPROM field +typedef struct sAniDbgCfgEepSetParams +{ + unsigned int offset; + unsigned int size; + unsigned int fIsMaskPresent; + unsigned char setParams[1]; +} tAniDbgCfgEepSetParams, *tpAniDbgCfgEepSetParams; + +// The response structure for this particular request is same as +// the generic response structure. + +// ------------------------------------------------------------ +// Input params for getting the value of a field in the EEPROM + +// Request struct for Getting the EEPROM field +typedef struct sAniDbgCfgEepGetParams +{ + unsigned int offset; + unsigned int size; +} tAniDbgCfgEepGetParams, *tpAniDbgCfgEepGetParams; + + +// Response struct for Getting the EEPROM field +typedef struct sAniDbgCfgEepGetResponse +{ + unsigned int rc; + unsigned char value[1]; +} tAniDbgCfgEepGetResponse, *tpAniDbgCfgEepGetResponse; + +// -------------------------------------------------------- +// Input params for setting the number of transmitters + +// Request struct for setting the number of transmitters +typedef struct sAniDbgCfgSetNumTransmitters +{ + unsigned int numTransmitters; + +} tAniDbgCfgSetNumTransmitters, *tpAniDbgCfgSetNumTransmitters; + +// -------------------------------------------------------- +// Input params for Enabling/Disabling Rx chains + +// Request struct for Enabling/Disabling Rx chains +typedef struct sAniDbgCfgSetRxChains +{ + unsigned int numChains; + unsigned char chainIndices[3]; +} tAniDbgCfgSetRxChains, *tpAniDbgCfgSetRxChains; + +// -------------------------------------------------------- +// Input params for enable/disable SW closed loop TPC + +// Request struct for enable/disable SW closed loop TPC +typedef struct sAniDbgCfgSwClosedLoopTpc +{ + unsigned int action; +} tAniDbgCfgSwClosedLoopTpc, *tpAniDbgCfgSwClosedLoopTpc; + +// -------------------------------------------------------- +// Input params for setting the list of test STA MAC address, +// that will be operating with the AP, for the Multi-NIC tests. +typedef struct sAniDbgCfgSetStaAddrLst +{ + unsigned long numStas; + unsigned char macAddrLst[MAX_NUM_TST_STAS_PER_AP][6]; +} tAniDbgCfgSetStaAddrLst, *tpAniDbgCfgSetStaAddrLst; + +// -------------------------------------------------------- +// Output Params for getting the current Power and Gain settings +// for a particular STA. +typedef struct sAniDbgCfgGetPwrGainResponse +{ + unsigned int rc; // 0 - SUCCESS + unsigned long pwrCode; + unsigned long gain0; + unsigned long gain1; +} tAniDbgCfgGetPwrGainResponse, *tpAniDbgCfgGetPwrGainResponse; + +// -------------------------------------------------------- +// Input Params containing the STAID for getting the current Power and Gain settings. +typedef struct sAniDbgCfgGetPwrGainParams +{ + unsigned long staID; +} tAniDbgCfgGetPwrGainParams, *tpAniDbgCfgGetPwrGainParams; + + +// -------------------------------------------------------- +// Output params for getting temperature + +// Response struct for getting temperature of the radio card +// NOTE:- Stop the traffic to measure temperature +typedef struct sAniDbgCfgGetTempRsp +{ + unsigned int rc; // 0 - SUCCESS; Otherwise FAILED + unsigned int temp0; // Chain 0 temperature + unsigned int temp1; // Chain 1 temperature +} tAniDbgCfgGetTempRsp, *tpAniDbgCfgGetTempRsp; + + +// -------------------------------------------------------- +// Generic Response structure for Config requests +typedef struct sAniDbgCfgResponse +{ + unsigned int rc; // 0 - SUCCESS; Otherwise FAILED +} tAniDbgCfgResponse, *tpAniDbgCfgResponse; + +// ==================================================================== +/* + For each test there will be a structure defined in this file with + the following test descriptions of testId, test trigger type, input + parameters and expected output + + This is a template for DBG test structure + + typedef struct sANIAPI_XXXX_TEST_PARAMS + { + // Input paramters + int xyz; // Test specific + } tANIAPI_XXXX_TEST_PARAMS; + + typedef struct sANIAPI_XXXX_TEST_RESPONSE + { + // Output parameters + int rc; // Must be ZERO for success and must have error code + // for failure + int zyx; // Any counters or any debug these will be test spefics + } tANIAPI_XXXX_TEST_RESPONSE; + + ********************************************* */ +// ===================================================================== + +#define ANI_CFG_OPER_GET 0x0 +#define ANI_CFG_OPER_SET 0x1 + + +typedef struct sAniDbgCfg +{ + unsigned char oper; + unsigned char data[124]; // total parms structure must be MAX 128 bytes +} tAniDbgCfg; + +// -------------------------------------------------------------------- + +// Response structures for InitPdu test +// No Input Params for this test +typedef struct sAniDbgInitPduTestResponse +{ + // Output parameters + unsigned int rc; // Must be ZERO for success and must have error code + // for failure + + unsigned int expected; + unsigned int i_current; + unsigned int totalPduCount; +} tAniDbgInitPduTestResponse, *tpAniDbgInitPduTestResponse; + + +// -------------------------------------------------------- +// Response structures for BusAccess/RegReadWrite tests +// No Input Params for this test + +typedef struct sAniDbgRegReadWriteTestResponse +{ + // Output parameters + unsigned int rc; // 0 - SUCCESS; Anything else is an ERROR + unsigned int registerAddress; + unsigned int expected; + unsigned int i_current; +} tAniDbgRegReadWriteTestResponse, *tpAniDbgRegReadWriteTestResponse; + +// -------------------------------------------------------- +// Response structures for Interrupt test +// No Input Params for this test + +typedef struct sAniDbgIntrTestResponse +{ + // Output parameters + unsigned int rc; // 0 - SUCCESS; Anything else is an ERROR + unsigned int status; // Interrupt status register + unsigned int mask; // Interrupt mask in test + unsigned int bmu; // BMU MB status register contents + +} tAniDbgIntrTestResponse, *tpAniDbgIntrTestResponse; + +// -------------------------------------------------------- +// No Input Params for this test + +typedef struct sAniDbgMemoryTestParams +{ + unsigned int startAddress; + unsigned int endAddress; + unsigned int pattern; + unsigned int testLevel; +} tAniDbgMemoryTestParams, *tpAniDbgMemoryTestParams; + +// --------------------------------------------------------------------- + +// Response structures for RegReadWrite test + +typedef struct sAniDbgMemoryTestResponse +{ + // Output parameters + unsigned int rc; // Must be ZERO for success and must have error code + // for failure + unsigned int expected; + unsigned int i_current; + unsigned int currentAddress; + unsigned int testAddress; +} tAniDbgMemoryTestResponse, *tpAniDbgMemoryTestResponse; + +// -------------------------------------------------------- +// Input Parameters for the HIF Burst Read Write test + +typedef struct sAniDbgHIFBurstRdWrtTestParams +{ + unsigned int AHBAddr; + unsigned int size; + unsigned char data[1]; + +} tAniDbgHIFBurstRdWrtTestParams, *tpAniDbgHIFBurstRdWrtTestParams; + +// --------------------------------------------------------------------- + +// Response structure for the HIF Burst Read Write test + +typedef struct sAniDbgHIFBurstRdWrtTestResponse +{ + // Output parameters + unsigned int rc; // Must be ZERO for success and must have error code + // for failure + unsigned char readData[1]; + +} tAniDbgHIFBurstRdWrtTestResponse, *tpAniDbgHIFBurstRdWrtTestResponse; + + +// -------------------------------------------------------- + +// Take the routing flags and number of frames, as Params for this test + +typedef struct sAniDbgSendContinuousTestParams +{ + unsigned int routingFlags; + + // 0 - continuously send packets till it is instructed to stop. + unsigned int numFramesToSend; + + // 1 - TM ring, otherwise the TD ring will be used. + unsigned int fUseTMRing; + + // 1 - loopback packets through the MAC + unsigned int fLoopBkPkts; +} tAniDbgSendContinuousTestParams, *tpAniDbgSendContinuousTestParams; + +// Response structures for SendContinuous test + +typedef struct sAniDbgSendContinuousTestResponse +{ + unsigned int rc; // 0 - Success and anything else is a failure + + unsigned int numPktsSent; + unsigned int numPktsFailed; + // Size of the last frame attempted to be sent, in case of a failure + unsigned int lastFailedPayloadSize; +} tAniDbgSendContinuousTestResponse, *tpAniDbgSendContinuousTestResponse; + +// -------------------------------------------------------- +// Input parameters for the Packet Routing test +typedef struct sAniDbgPktRoutingTestParams +{ + // Routing flags for the test + unsigned int routingFlags; + + // Enter 1 for Hardware Seqno + unsigned int hsBit; + + // Enter unicast ackPolicy(4 for random) + unsigned int ackPolicy; + + // RTS (2 for random) + unsigned int rtsFlag; + + // 0 - continuously send packets till it is instructed to stop. + unsigned int numPktsToSend; + + // 0xffffffff - For random frame types. + unsigned int frameType; + + // 0xffffffff - generates random frame sub-types. + unsigned int frmSubType; + + // 1 - TM ring; Otherwise the TD ring will be used. + unsigned int fUseTMRing; + + // 0 - random payload sizes + unsigned int payloadSize; + + // If "payloadSize" above is set to zero then this is ignored + unsigned int fragSize; + + // This parameter specifies whether a unicast packet should be fragmented. + // Ignored, if "payloadSize" above is set to a non-zero value. + unsigned int fragment; + + // Use a value >3 for random staId generation + unsigned int staId; + + // Use a value >7 for random tcId generation + unsigned int tcId; + + // Enter random STA range (1 for STAs(0-1),3 for STAs(0-3)) + unsigned int staRange; + + // TC range (1 for TCs(0-1),3 for TCs(0-3),7 for TCs(0-7) + unsigned int tcRange; + + // burst size (< 11) + unsigned int burst; + + // Enter 1 to compute CRC + unsigned int crc; + + // Enter 1 to loopback packets through the MAC + unsigned int fLoopBkPkts; + +} tAniDbgPktRoutingTestParams, *tpAniDbgPktRoutingTestParams; + +// Structures where response parameters are constructed by the +// dvtSendPackets() routine + +typedef struct sAniDbgSendPktResponse +{ + // Total packets sent + unsigned int pktGenCount; + + unsigned int fragCnt; + + unsigned int byteCnt; + + unsigned int lowPduCnt; + + unsigned int qFullCnt; + + // Specifies the size of the last frame attempted to be sent + unsigned int lastPayloadSize; + + // Specifies the size of the last frame's fragment size + unsigned int lastFragSize; + + // Immediate ACK + unsigned int cumImmAck; + + // NoACK + unsigned int cumNoAck; + + // RTS + unsigned int cumRTS; + + // No ACK + unsigned int cumNoRTS; + + // TC histogram (pkts) + unsigned int cumTC[8]; + + //Fragments histogram (frags) + unsigned int cumFrag[16]; + + // STA histogram (pkts,frags) + unsigned int cumSTA[4]; + unsigned int cumSTAFrags[4]; + +} tAniDbgSendPktResponse, *tpAniDbgSendPktResponse; + +// Response structures for the Packet Routing test +typedef struct sAniDbgPktRoutingTestResponse +{ + // Output parameters + unsigned int rc; // Must be ZERO for success and must have error code + // for failure + + // Field where response parameters are constructed by the + // dvtSendPackets() routine + tAniDbgSendPktResponse sendPktsRsp; + +} tAniDbgPktRoutingTestResponse, *tpAniDbgPktRoutingTestResponse; + +// -------------------------------------------------------- + +typedef enum sPciCfgTestStatus +{ + ePCI_CFG_TEST_SUCCESS, + ePCI_CFG_TEST_READ_FAILURE, + ePCI_CFG_TEST_VEN_DEV_ID_MISMATCH, + ePCI_CFG_TEST_MIN_GNT_MISMATCH, + ePCI_CFG_TEST_MAX_LAT_MISMATCH, + ePCI_CFG_TEST_CIS_PTR_MISMATCH, + ePCI_CFG_TEST_CIS_CONTENTS_MISMATCH +} tPciCfgTestStatus; + +// Response structures for the PCI Config test +typedef struct sAniDbgPciCfgTestResponse +{ + // Output parameters + unsigned int rc; // Must be ZERO for success and must have error code + // for failure + + // Field where the PCI config words, for Polaris are returned by the HDD + unsigned int pciConfig[MAX_PCI_CFG_WRDS]; + +} tAniDbgPciCfgTestResponse, *tpAniDbgPciCfgTestResponse; + +// -------------------------------------------------------- + +// Various return codes returned for the EEPROM test. +typedef enum sEepromTestStatus +{ + eEEPROM_TEST_SUCCESS, + eEEPROM_TEST_FILE_OPEN_FAILURE, + eEEPROM_TEST_FILE_MAP_FAILURE, + eEEPROM_TEST_INVALID_FILE_SIZE, + eEEPROM_TEST_MEMORY_ALLOC_FAILURE, + eEEPROM_TEST_CRC_MISMATCH_FAILURE +} tEepromTestStatus; + + +// Take the EEPROM filename, as Params for this test + +typedef struct sAniDbgEepromTestParams +{ + // EEPROM File Name. + char eepromFilename[256]; + +} tAniDbgEepromTestParams, *tpAniDbgEepromTestParams; + +// Response structures for SendContinuous test + +typedef struct sAniDbgEepromTestResponse +{ + unsigned int rc; // 0 - Success and anything else is a failure + +} tAniDbgEepromTestResponse, *tpAniDbgEepromTestResponse; + +// --------------------------------------------------------------------- + +// input params for RHP HASH TBL tests + +typedef struct sAniDbgRhpHashTblMultipleEntryTestParams +{ + unsigned int n; // number of entries + +} tAniDbgRhpHashTblMultipleEntryTestParams, + *tpAniDbgRhpHashTblMultipleEntryTestParams; + +typedef struct sAniDbgRhpHashTblTestParams +{ + unsigned int staId; + unsigned char macAddr[6]; + unsigned int flags; + unsigned int hashFlagRsvd; + unsigned int rsvdField; + +} tAniDbgRhpHashTblTestParams, *tpAniDbgRhpHashTblTestParams; + + +typedef struct sAniDbgRhpHashTblTestResponse +{ + unsigned int rc; // 0 For Success +} tAniDbgRhpHashTblTestResponse, *tpAniDbgRhpHashTblTestResponse; + + +// ----------------------------------------------------------- + +// Here both pParms and pResponse structures are interpreted by the +// User of the API based on testId + +typedef struct sANI_DBG_TEST_INFO { + + tANI_TEST_ID testId; + + // This field indicates this test runs synchronously or not. + // If it is not, then, the test originator will have the + // ability to query for intermediate results. + // ANI_START = 1; ANI_GET_RESULTS = 2; ANI_STOP = 3 + tANI_TEST_TRIG_TYPE testTriggerType; + + // test state + tANI_DBG_TEST_STATE testState; + + // This points to a structure which contains parameters for + // test defined by dvtTestId. May be NULL if no parameters + // are needed + unsigned long sizeOfParms; + unsigned char parms[MAX_PARMS_SIZE]; + + // This points to a buffer to hold response from the test + // Response shall be there from the test and it MUST have + // return code ZERO for SUCCESS and error code for test + // failure + unsigned long sizeOfResponse; + unsigned char response[MAX_RESPONSE_SIZE]; + +} tANI_DBG_TEST_INFO; + +// Returns test start function pointer or stop function pointer or +// get info on test function pointer from the function pointer array +// that is initialized during the dvtInitGlobal routine. +#ifdef __cplusplus +extern "C" void* dvtGetFuncPtr(void *, int, int ); +#else +extern void* dvtGetFuncPtr(void *, int, int ); +#endif + + +// declare a function prototype for 'start', 'update' and 'stop' routines +typedef void t_DbgTestRoutine(void *); + +// called by the test routine when it completes +extern void dbgTestCompleted(void *mpAdapterPtr); + + +// DBG/DVT dump information structures & defines + +#define ANI_DBG_GRP_INFO_TYPE_MISC 0x00000001 +#define ANI_DBG_GRP_INFO_TYPE_BMU 0x00000002 +#define ANI_DBG_GRP_INFO_TYPE_TFP 0x00000004 +#define ANI_DBG_GRP_INFO_TYPE_RHP 0x00000008 +#define ANI_DBG_GRP_INFO_TYPE_RFP 0x00000010 +#define ANI_DBG_GRP_INFO_TYPE_STA 0x00000020 +#define ANI_DBG_GRP_INFO_TYPE_FPHY 0x00000040 +#define ANI_DBG_GRP_INFO_TYPE_FPHY_FIFO 0x00000080 +#define ANI_DBG_GRP_INFO_TYPE_RPHY 0x00000100 +#define ANI_DBG_GRP_INFO_TYPE_HCF 0x00000200 +#define ANI_DBG_GRP_INFO_TYPE_SP 0x00000400 +#define ANI_DBG_GRP_INFO_TYPE_CP 0x00000800 + + +#define ANI_DBG_GRP_INFO_TYPE_ALL (ANI_DBG_GRP_INFO_TYPE_MISC | \ + ANI_DBG_GRP_INFO_TYPE_BMU | \ + ANI_DBG_GRP_INFO_TYPE_TFP | \ + ANI_DBG_GRP_INFO_TYPE_RHP | \ + ANI_DBG_GRP_INFO_TYPE_RFP | \ + ANI_DBG_GRP_INFO_TYPE_STA | \ + ANI_DBG_GRP_INFO_TYPE_FPHY| \ + ANI_DBG_GRP_INFO_TYPE_FPHY_FIFO | \ + ANI_DBG_GRP_INFO_TYPE_RPHY | \ + ANI_DBG_GRP_INFO_TYPE_HCF | \ + ANI_DBG_GRP_INFO_TYPE_SP) + + + +typedef struct sANI_DBG_MISC_INFO { + + unsigned long sysMode; + unsigned long sysIntrMask; + unsigned long intrMask; + unsigned long phyIntrMask; + unsigned long intrStatus[32]; + unsigned long phyIntrStatus[16]; + unsigned long eofSofExceptionResets; + unsigned long bmuExceptionResets; + unsigned long lowPduExceptionResets; + unsigned long userTriggeredResets; + unsigned long logPExceptionResets; + +} tANI_DBG_MISC_INFO; + + +typedef struct sANI_DBG_BMU_INFO { + + unsigned long control; + unsigned long fp_hptr; + unsigned long tptr; + unsigned long pdu; + unsigned long exception; + unsigned long exceptionMaster; + unsigned long dropCount; + unsigned long workQueue[10][4]; + +} tANI_DBG_BMU_INFO; + + +typedef struct sANI_DBG_TFP_INFO { + + unsigned long control; + unsigned long modeEnable; + unsigned long templEnable; + unsigned long retryQid; + unsigned long tsfHi; + unsigned long tsfLo; + unsigned long beacon; + unsigned long probeDelay; + unsigned long tbttHi; + unsigned long tbttLo; + unsigned long nav; + unsigned long listenInterval; + unsigned long delayTx; + unsigned long dtimPeriod; + unsigned long rtsCount; + unsigned long rtsFailure; + +} tANI_DBG_TFP_INFO; + + +typedef struct sANI_DBG_RHP_INFO { + + unsigned long sof; + unsigned long sof_chunk; + unsigned long fragCount; + unsigned long dropCount; + unsigned long fcsCount; + unsigned long bssIdMismatch; + unsigned long destMismatch; + unsigned long lengthError; + unsigned long pduError; + unsigned long abortCount; + unsigned long reqRate; + unsigned long delayAB; + unsigned long macAddrHi; + unsigned long macAddrLo; + unsigned long bssIdHi; + unsigned long bssIdLo; + unsigned long relayCount; + unsigned long hash_MissCount; + unsigned long hash_srcHi; + unsigned long hash_srcLo; + unsigned long hash_type; + unsigned long hash_subType; + unsigned long dbg_hangStatus; + unsigned long dbg_fragIgnoreCount; + unsigned long pduCount; + +} tANI_DBG_RHP_INFO; + + +typedef struct sANI_DBG_RFP_INFO { + + unsigned long packets; + unsigned long multicastPackets; + unsigned long dupPackets; + unsigned long byteCount; + unsigned long dropCount; + unsigned long byte64; + unsigned long byte128; + unsigned long byte256; + unsigned long byte512; + unsigned long byte1024; + unsigned long byte1519; + unsigned long byte2048; + unsigned long byte4096; + +} tANI_DBG_RFP_INFO; + +typedef struct sANI_DBG_SP_INFO { + + unsigned long wep_dky0_w0; + unsigned long wep_dky0_w1; + unsigned long wep_default_rc0; + + unsigned long wep_dky1_w0; + unsigned long wep_dky1_w1; + unsigned long wep_default_rc1; + + unsigned long wep_dky2_w0; + unsigned long wep_dky2_w1; + unsigned long wep_default_rc2; + + unsigned long wep_dky3_w0; + unsigned long wep_dky3_w1; + unsigned long wep_default_rc3; + +} tANI_DBG_SP_INFO; + +typedef struct sANI_DBG_CP_INFO { + + unsigned long cp_control; + unsigned long Compression_Expansion_Cnt; + unsigned long Compression_NUM_pkts; + + unsigned long Decompression_NUM_pkts; + unsigned long Compression_50p_NUM_pkts; + unsigned long CP_Error_status; + + unsigned long Cp_maximum_pkt_len; + +} tANI_DBG_CP_INFO; + + +typedef struct sANI_DBG_STA_TX_WQ_INFO { + + unsigned long txWqAddr; + unsigned long txWqDump[4]; + + unsigned long tptr; + unsigned long hptr; + unsigned long aptr; + unsigned long a_tpkts; + unsigned long h_tpkts; + unsigned long frag; + unsigned long bytes; + unsigned long ack; + unsigned long valid; + +} tANI_DBG_STA_TX_WQ_INFO; + + + +typedef struct sANI_DBG_TC_DESC { + + unsigned long valid; + unsigned long rxAckType; + unsigned long newPkt; + unsigned long rxSeqNum; + unsigned long rxPktTimeStamp; + unsigned long SV; + unsigned long ackTimeout; + unsigned long numOfFragsSucessful; + unsigned long rxBDPtr; + unsigned long txReplayCountHi; + unsigned long txReplayCountLo; + unsigned long rxReplayCountHi; + unsigned long rxReplayCountLo; + +} tANI_DBG_TC_DESC; + + +typedef struct sANI_DBG_PWR_TEMPL { + + unsigned long retryPhyMode; + unsigned long retryCb; + unsigned long retryEsf; + unsigned long sb; + unsigned long rate; + unsigned long esf; + unsigned long tifs; + unsigned long edcf; + unsigned long cb; + unsigned long mode; + unsigned long pwrLvl; + unsigned long nTransmitters; + unsigned long retry1rate; + unsigned long retry2rate; + + unsigned long pwrTemplate; //entire value + +} tANI_DBG_PWR_TEMPL; + + +typedef struct sANI_DBG_STA { + + unsigned long staDescAddr; + unsigned long staDump[256]; + + tANI_DBG_TC_DESC tcDesc[9]; // 8 tc Ids and 9th mgmt TC + + unsigned long cbits_hcf; + unsigned long cbits_ps; + unsigned long cbits_ps1; + unsigned long cbits_tx_en; + + unsigned long descStat_aes_sent; + unsigned long descStat_aes_recv; + unsigned long descStat_replays; + unsigned long descStat_formaterr; + unsigned long descStat_aes_decypterr_default; + unsigned long descStat_aes_decypterr_ucast; + + unsigned long tfpStat_failed; + unsigned long tfpStat_retry; + unsigned long tfpStat_multiretry; + unsigned long tfpStat_ackto; + unsigned long tfpStat_frags; + unsigned long tfpStat_rtsBrqs; + unsigned long tfpStat_pkts; + unsigned long tfpStat_ctsBackTimeouts; + + + unsigned long phyStatHi; + unsigned long phyStatLo; + + unsigned long ackToNonPrimRates; + unsigned long nFragSuccNonPrimRates; + +} tANI_DBG_STA; + + +typedef struct sANI_DBG_STA_INFO { + + unsigned long staId; // input + + tANI_DBG_STA sta; + + tANI_DBG_STA_TX_WQ_INFO txwq[8]; + + tANI_DBG_PWR_TEMPL pwrTempl; + +} tANI_DBG_STA_INFO; + + +typedef struct sANI_DBG_FPHY_INFO { + + unsigned long fphy_symPer; + unsigned long cca_delayOffset; + unsigned long cca_startDelay; + unsigned long timeStamp_Hi; + unsigned long timeStamp_Lo; + unsigned long dropRate; + unsigned long burstSize; + unsigned long reg; + unsigned long stat_bytes01; + unsigned long stat_bytes23; + unsigned long stat_bytes45; + unsigned long pkts_tx; + unsigned long pkts_rx; + unsigned long pkts_drops; + unsigned long rxin_sof; + unsigned long rxin_eof; + unsigned long rxout_sof; + unsigned long rxout_eof; + unsigned long txin_sof; + unsigned long txin_eof; + unsigned long txout_sof; + unsigned long txout_eof; + +} tANI_DBG_FPHY_INFO; + + +#define MAX_FIFO_ENTRIES_PER_REQUEST 200 + +typedef struct sAniDvtPhyfEntry +{ + unsigned char bytes[50]; + unsigned char len; + unsigned char mode; + unsigned char phyLen; + unsigned char macLen; + unsigned char dropByte; + unsigned char reserved; + unsigned long sof; + unsigned long eof; +} tAniDvtPhyfEntry; + + +#define ANI_DBG_FIFO_CMD_GET 0x1 +#define ANI_DBG_FIFO_CMD_CLEAR 0x2 + + +typedef struct sANI_DBG_FPHY_FIFO { + + unsigned long command; // set to either 'get' of 'clear' fifo + unsigned long entries; // entries to read + unsigned long offset; // offset to read from + + unsigned long totalBytes; + unsigned long approxEntries; + + unsigned long validEntries; + tAniDvtPhyfEntry Fifo[MAX_FIFO_ENTRIES_PER_REQUEST]; + +} tANI_DBG_FPHY_FIFO; + + +typedef struct sANI_DBG_RPHY_MPI_INFO { + + unsigned long tfp_phy_sof; + unsigned long tfp_phy_eof; + unsigned long phy_tfp_req; + unsigned long txa_mpi_data_req; + unsigned long txb_mpi_data_req; + unsigned long mpi_txa_data_val; + unsigned long mpi_txb_data_val; + unsigned long mpi_txa_pktend; + unsigned long mpi_txb_pktend; + unsigned long mpi_txctl_pktend; + unsigned long mpi_txctl_ctlbytes_val; + +} tANI_DBG_RPHY_MPI_INFO; + + +typedef struct sANI_DBG_RPHY_PMI_INFO { + + unsigned long rxa_mpi_pktstart; + unsigned long rxb_mpi_pktstart; + unsigned long rxa_mpi_pktend; + unsigned long rxb_mpi_pktend; + unsigned long rxa_mpi_data_val; + unsigned long rxb_mpi_data_val; + unsigned long rhp_phy_shutoff; + unsigned long rhp_phy_sof_c; + unsigned long rhp_phy_sof_p; + unsigned long rhp_phy_eof_c; + unsigned long rhp_phy_eof_p; + unsigned long phy_rhp_data_val; + unsigned long pmi_int; + +} tANI_DBG_RPHY_PMI_INFO; + +typedef struct sANI_DBG_RPHY_PHYINT_INFO { + + unsigned long status; + unsigned long fast_mask; + unsigned long slow_mask; + unsigned long host_mask; + +} tANI_DBG_RPHY_PHYINT_INFO; + + +typedef struct sANI_DBG_RPHY_INFO { + + tANI_DBG_RPHY_MPI_INFO mpi; + tANI_DBG_RPHY_PMI_INFO pmi; + tANI_DBG_RPHY_PHYINT_INFO phyint; + +} tANI_DBG_RPHY_INFO; + + +typedef struct sANI_DBG_SCH_INFO +{ + unsigned long curSch; // RO + unsigned long numSch; // RO + unsigned long numInt; // RO + unsigned long numEndInt; // RO + unsigned long numCFB; // RO + unsigned long firstCFB; // RO + + unsigned long fixedSch; // RW + unsigned long gDvtPoll; // RW + unsigned long maxTimeout; // RW + unsigned long minTxop; // RW + unsigned long maxTxop; // RW + unsigned long maxTcid; // RW + unsigned long maxSta; // RW + unsigned long minSta; // RW + unsigned long maxInst; // RW + + unsigned long firstSch; // RO + unsigned long cfbStart; // RO + unsigned long cfbEnd; // RO + unsigned long cumCFB; // RO + unsigned long cumCP; // RO + + unsigned long haltSch; // RW + unsigned long numTim; // RO +} tANI_DBG_SCH_INFO; + + +typedef struct sANI_DBG_HCF_INFO { + + unsigned long bSetInfo; // 0 = read info, 1 = set info + tANI_DBG_SCH_INFO schInfo; + +} tANI_DBG_HCF_INFO; + +typedef struct sANI_DBG_AP_SWITCH_INFO { + + + // Space to hold the SSIDList and the BSSID. + unsigned char SSID_BSSID_BUF[262]; // 262 == WNIAPI_MAX_SSID_LIST_STR + WNIAPI_BSSID_SIZE + + +} tANI_DBG_AP_SWITCH_INFO; + + +typedef struct sANI_DBG_INFO { + + unsigned long dbgInfoMask; // indicates which members are valid + + tANI_DBG_MISC_INFO miscInfo; + tANI_DBG_BMU_INFO bmuInfo; + tANI_DBG_TFP_INFO tfpInfo; + tANI_DBG_RHP_INFO rhpInfo; + tANI_DBG_RFP_INFO rfpInfo; + tANI_DBG_STA_INFO staInfo; + tANI_DBG_FPHY_INFO fphyInfo; + tANI_DBG_FPHY_FIFO fphyFifo; + tANI_DBG_RPHY_INFO rphyInfo; + tANI_DBG_HCF_INFO hcfInfo; + tANI_DBG_SP_INFO spInfo; + tANI_DBG_CP_INFO cpInfo; + +} tANI_DBG_INFO; + +extern tSirRetStatus dvtGetDumpInfo(void *pMac, tANI_DBG_INFO *pDbgInfo ); + +extern tSirRetStatus dvtGetConfigInfo(void *pMac, tANI_DBG_TEST_INFO *pTestInfo ); + +#ifdef __cplusplus +extern "C" void dvtSetStopTestFlag( unsigned char stopTest ); +#else +extern void dvtSetStopTestFlag( unsigned char stopTest ); +#endif + + +#endif // _ANIDBGTEST_H_ diff --git a/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h b/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h new file mode 100644 index 000000000000..5257cfb69814 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/aniGlobal.h @@ -0,0 +1,1116 @@ +/* + * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * aniGlobal.h: MAC Modules Adapter Definitions. + * Author: V. K. Kandarpa + * Date: 10/25/2002 + * + * History:- + * Date: 04/08/2008 Modified by: Santosh Mandiganal + * Modification Information: Added the logDump.h header file and defined the + * dumpTablecurrentId, dumpTableEntry. + * -------------------------------------------------------------------------- + * + */ + +#ifndef _ANIGLOBAL_H +#define _ANIGLOBAL_H + +#include "halTypes.h" +#include "sirCommon.h" +#include "aniSystemDefs.h" +#include "sysDef.h" +#include "dphGlobal.h" +#include "limGlobal.h" +#include "pmmGlobal.h" +#include "schGlobal.h" +#include "sysGlobal.h" +#include "cfgGlobal.h" +#include "utilsGlobal.h" +#include "sirApi.h" + + +#include "wlan_qct_hal.h" + +#include "pmc.h" + +#include "csrApi.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "sme_FTApi.h" +#endif +#include "csrSupport.h" +#include "smeInternal.h" +#include "ccmApi.h" +#include "btcApi.h" +#include "csrInternal.h" + +#ifdef FEATURE_OEM_DATA_SUPPORT +#include "oemDataInternal.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "smeRrmInternal.h" +#include "rrmGlobal.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#include "eseGlobal.h" +#endif +#include "p2p_Api.h" + +#include "limRMC.h" + +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif + + +#ifdef ANI_DVT_DEBUG +#include "dvtModule.h" +#endif + +// New HAL API interface defs. +#include "logDump.h" + +//Check if this definition can actually move here from halInternal.h even for Volans. In that case +//this featurization can be removed. +#define PMAC_STRUCT( _hHal ) ( (tpAniSirGlobal)_hHal ) + +#define ANI_DRIVER_TYPE(pMac) (((tpAniSirGlobal)(pMac))->gDriverType) +// ------------------------------------------------------------------- +// Bss Qos Caps bit map definition +#define LIM_BSS_CAPS_OFFSET_HCF 0 +#define LIM_BSS_CAPS_OFFSET_WME 1 +#define LIM_BSS_CAPS_OFFSET_WSM 2 + +#define LIM_BSS_CAPS_HCF (1 << LIM_BSS_CAPS_OFFSET_HCF) +#define LIM_BSS_CAPS_WME (1 << LIM_BSS_CAPS_OFFSET_WME) +#define LIM_BSS_CAPS_WSM (1 << LIM_BSS_CAPS_OFFSET_WSM) + +// cap should be one of HCF/WME/WSM +#define LIM_BSS_CAPS_GET(cap, val) (((val) & (LIM_BSS_CAPS_ ## cap)) >> LIM_BSS_CAPS_OFFSET_ ## cap) +#define LIM_BSS_CAPS_SET(cap, val) ((val) |= (LIM_BSS_CAPS_ ## cap )) +#define LIM_BSS_CAPS_CLR(cap, val) ((val) &= (~ (LIM_BSS_CAPS_ ## cap))) + +// 40 beacons per heart beat interval is the default + 1 to count the rest +#define MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL 41 + +/* max number of legacy bssid we can store during scan on one channel */ +#define MAX_NUM_LEGACY_BSSID_PER_CHANNEL 10 + +#define P2P_WILDCARD_SSID "DIRECT-" //TODO Put it in proper place; +#define P2P_WILDCARD_SSID_LEN 7 + +#ifdef WLAN_FEATURE_CONCURRENT_P2P +#define MAX_NO_OF_P2P_SESSIONS 5 +#endif //WLAN_FEATURE_CONCURRENT_P2P + +#define SPACE_ASCII_VALUE 32 + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define EQUALS_TO_ASCII_VALUE (61) +#endif + +// ------------------------------------------------------------------- +// Change channel generic scheme +typedef void (*CHANGE_CHANNEL_CALLBACK)(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry); + +/// LIM global definitions +typedef struct sAniSirLimIbss +{ + void *pHdr; + void *pBeacon; +} tAniSirLimIbss; + +typedef struct sDialogueToken +{ + //bytes 0-3 + tANI_U16 assocId; + tANI_U8 token; + tANI_U8 rsvd1; + //Bytes 4-7 + tANI_U16 tid; + tANI_U8 rsvd2[2]; + + struct sDialogueToken* next; +}tDialogueToken, *tpDialogueToken; + +typedef struct sLimTimers +{ + //TIMERS IN LIM ARE NOT SUPPOSED TO BE ZEROED OUT DURING RESET. + //DURING limInitialize DONOT ZERO THEM OUT. + +//STA SPECIFIC TIMERS + // Periodic background scan timer + TX_TIMER gLimBackgroundScanTimer; + + TX_TIMER gLimPreAuthClnupTimer; + //TX_TIMER gLimAuthResponseTimer[HAL_NUM_STA]; + + // Association related timers + TX_TIMER gLimAssocFailureTimer; + TX_TIMER gLimReassocFailureTimer; + + + /// Heartbeat timer on STA + TX_TIMER gLimHeartBeatTimer; + + /// Wait for Probe after Heartbeat failure timer on STA + TX_TIMER gLimProbeAfterHBTimer; + + + // Authentication related timers + TX_TIMER gLimAuthFailureTimer; + + // Join Failure timeout on STA + TX_TIMER gLimJoinFailureTimer; + + // Keepalive timer + TX_TIMER gLimKeepaliveTimer; + + // Scan related timers + TX_TIMER gLimMinChannelTimer; + TX_TIMER gLimMaxChannelTimer; + TX_TIMER gLimPeriodicProbeReqTimer; + + // CNF_WAIT timer + TX_TIMER *gpLimCnfWaitTimer; + + TX_TIMER gLimAddtsRspTimer; // max wait for a response + + // Update OLBC Cache Timer + TX_TIMER gLimUpdateOlbcCacheTimer; + + TX_TIMER gLimChannelSwitchTimer; + // This TIMER is started on the STA, as indicated by the + // AP in its Quiet BSS IE, for the specified interval + TX_TIMER gLimQuietTimer; + // This TIMER is started on the AP, prior to the AP going + // into LEARN mode + // This TIMER is started on the STA, for the specified + // quiet duration + TX_TIMER gLimQuietBssTimer; + +#ifdef WLAN_FEATURE_VOWIFI_11R + TX_TIMER gLimFTPreAuthRspTimer; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + TX_TIMER glim_pre_auth_mbb_rsp_timer; + TX_TIMER glim_reassoc_mbb_rsp_timer; +#endif + +#ifdef FEATURE_WLAN_ESE + TX_TIMER gLimEseTsmTimer; +#endif + TX_TIMER gLimPeriodicJoinProbeReqTimer; + TX_TIMER gLimDisassocAckTimer; + TX_TIMER gLimDeauthAckTimer; + TX_TIMER gLimPeriodicAuthRetryTimer; + // This timer is started when single shot NOA insert msg is sent to FW for scan in P2P GO mode + TX_TIMER gLimP2pSingleShotNoaInsertTimer; + /* This timer is used to convert active channel to + * passive channel when there is no beacon + * for a period of time on a particular DFS channel + */ + TX_TIMER gLimActiveToPassiveChannelTimer; +//********************TIMER SECTION ENDS************************************************** +// ALL THE FIELDS BELOW THIS CAN BE ZEROED OUT in limInitialize +//**************************************************************************************** + +}tLimTimers; + +typedef struct { + void *pMlmDisassocReq; + void *pMlmDeauthReq; +}tLimDisassocDeauthCnfReq; + +typedef struct { + tANI_U32 failed_count[MAX_TIDS]; + v_TIME_t failed_timestamp[MAX_TIDS]; +} tLimStaBAInfo; + +typedef struct sAniSirLim +{ + ////////////////////////////////////// TIMER RELATED START /////////////////////////////////////////// + + tLimTimers limTimers; + /// Flag to track if LIM timers are created or not + tANI_U32 gLimTimersCreated; + + + ////////////////////////////////////// TIMER RELATED END /////////////////////////////////////////// + + ////////////////////////////////////// SCAN/LEARN RELATED START /////////////////////////////////////////// + /** + * This flag when set, will use scan mode instead of + * Learn mode on BP/AP. By default this flag is set + * to true until HIF getting stuck in 0x800 state is + * debugged. + */ + tANI_U32 gLimUseScanModeForLearnMode; + + /** + * This is useful for modules other than LIM + * to see if system is in scan/learn mode or not + */ + tANI_U32 gLimSystemInScanLearnMode; + + // Scan related globals on STA + tANI_U8 gLimReturnAfterFirstMatch; + tANI_U8 gLim24Band11dScanDone; + tANI_U8 gLim50Band11dScanDone; + tANI_U8 gLimReturnUniqueResults; + + // Background Scan related globals on STA + tANI_U32 gLimNumOfBackgroundScanSuccess; + tANI_U32 gLimNumOfConsecutiveBkgndScanFailure; + tANI_U32 gLimNumOfForcedBkgndScan; + tANI_U8 gLimBackgroundScanDisable; //based on BG timer + tANI_U8 gLimForceBackgroundScanDisable; //debug control flag + tANI_U8 gLimBackgroundScanTerminate; //controlled by SME + tANI_U8 gLimReportBackgroundScanResults;//controlled by SME + + /// Place holder for current channel ID + /// being scanned + tANI_U32 gLimCurrentScanChannelId; + + // Hold onto SCAN criteria + /* The below is used in P2P GO case when we need to defer processing SME Req + * to LIM and insert NOA first and process SME req once SNOA is started + */ + tANI_U16 gDeferMsgTypeForNOA; + tANI_U32 *gpDefdSmeMsgForNOA; + + tLimMlmScanReq *gpLimMlmScanReq; + + /// This indicates total length of 'matched' scan results + tANI_U16 gLimMlmScanResultLength; + + /// This indicates total length of 'cached' scan results + tANI_U16 gLimSmeScanResultLength; + + /** + * Hash table definition for storing SCAN results + * This is the placed holder for 'cached' scan results + */ + tLimScanResultNode + *gLimCachedScanHashTable[LIM_MAX_NUM_OF_SCAN_RESULTS]; + + /// This indicates total length of 'matched' scan results + tANI_U16 gLimMlmLfrScanResultLength; + + /// This indicates total length of 'cached' scan results + tANI_U16 gLimSmeLfrScanResultLength; + + /** + * Hash table definition for storing LFR SCAN results + * This is the placed holder for roaming candidates as forwarded + * by FW + */ + tLimScanResultNode + *gLimCachedLfrScanHashTable[LIM_MAX_NUM_OF_SCAN_RESULTS]; + + /// Place holder for current channel ID + /// being scanned during background scanning + tANI_U32 gLimBackgroundScanChannelId; + /// flag to indicate that bacground scan timer has been started + tANI_U8 gLimBackgroundScanStarted; + + /* Used to store the list of legacy bss sta detected during scan on one channel */ + tANI_U16 gLimRestoreCBNumScanInterval; + tANI_U16 gLimRestoreCBCount; + tSirMacAddr gLimLegacyBssidList[MAX_NUM_LEGACY_BSSID_PER_CHANNEL]; + + // + // If this flag is 1, + // then, LIM will "try and trigger" a background + // scan whenever it receives a Quiet BSS IE + // + // If this flag is 0, + // then, LIM will simply shut-off Tx/Rx whenever it + // receives a Quiet BSS IE. + // This is the default behavior when a Quiet BSS IE + // is received and 11H is enabled + // + tANI_U32 gLimTriggerBackgroundScanDuringQuietBss; + + + // This variable store the total duration to do scan + tANI_U32 gTotalScanDuration; + tANI_U32 p2pRemOnChanTimeStamp; + + // abort scan is used to abort an on-going scan + tANI_U8 abortScan; + tLimScanChnInfo scanChnInfo; + + ////////////////////////////////////// SCAN/LEARN RELATED START /////////////////////////////////////////// + tSirMacAddr gSelfMacAddr; //added for BT-AMP Support + tSirMacAddr spoofMacAddr; //added for Mac Addr Spoofing support + tANI_U8 isSpoofingEnabled; + + ////////////////////////////////////////// BSS RELATED END /////////////////////////////////////////// + // Place holder for StartBssReq message + // received by SME state machine + + tANI_U8 gLimCurrentBssUapsd; + + /* This is used for testing sta legacy bss detect feature */ + tANI_U8 gLimForceNoPropIE; + + // + // Store the BSS Index returned by HAL during + // WDA_ADD_BSS_RSP here. + // + // For now: + // This will be used during WDA_SET_BSSKEY_REQ in + // order to set the GTK + // Later: + // There could be other interfaces needing this info + // + + // + // Due to the asynchronous nature of the interface + // between PE <-> HAL, some transient information + // like this needs to be cached. + // This is cached upon receipt of eWNI_SME_SETCONTEXT_REQ. + // This is released while posting LIM_MLM_SETKEYS_CNF + // + void* gpLimMlmSetKeysReq; + void* gpLimMlmRemoveKeyReq; + + //On STA: staid for self generated by HAL and sent as response to 'ADD STA' msg. + //On AP: staid corresponding to BSS generated by HAL and sent as response to 'ADD BSS' msg. + // tANI_U16 gLimStaid; // TO SUPPORT BT-AMP + + ////////////////////////////////////////// BSS RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// IBSS RELATED START /////////////////////////////////////////// + // This indicates whether we've a partner + // that is also transmitting Beacon frame + // in IBSS + //tANI_U8 gLimIbssActive; oct1 review + + //This indicates whether this STA coalesced and adapter to peer's capabilities or not. + tANI_U8 gLimIbssCoalescingHappened; + + /// Definition for storing IBSS peers BSS description + tLimIbssPeerNode *gLimIbssPeerList; + tANI_U32 gLimNumIbssPeers; + tANI_U32 gLimIbssRetryCnt; + + // ibss info - params for which ibss to join while coalescing + tAniSirLimIbss ibssInfo; + + ////////////////////////////////////////// IBSS RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// STATS/COUNTER RELATED START /////////////////////////////////////////// + + tANI_U16 maxStation; + tANI_U16 maxBssId; + + tANI_U32 gLimNumBeaconsRcvd; + tANI_U32 gLimNumBeaconsIgnored; + + tANI_U32 gLimNumDeferredMsgs; + + /// Variable to keep track of number of currently associated STAs + tANI_U16 gLimNumOfAniSTAs; // count of ANI peers + tANI_U16 gLimAssocStaLimit; + + /// This indicates number of RXed Beacons during HB period + // tANI_U8 gLimRxedBeaconCntDuringHB; + + // Heart-Beat interval value + tANI_U32 gLimHeartBeatCount; + tSirMacAddr gLimHeartBeatApMac[2]; + tANI_U8 gLimHeartBeatApMacIndex; + + // Statistics to keep track of no. beacons rcvd in heart beat interval + tANI_U16 gLimHeartBeatBeaconStats[MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL]; + +#ifdef WLAN_DEBUG + // Debug counters + tANI_U32 numTot, numBbt, numProtErr, numLearn, numLearnIgnore; + tANI_U32 numSme, numMAC[4][16]; + + // Debug counter to track number of Assoc Req frame drops + // when received in pStaDs->mlmState other than LINK_ESTABLISED + tANI_U32 gLimNumAssocReqDropInvldState; + // counters to track rejection of Assoc Req due to Admission Control + tANI_U32 gLimNumAssocReqDropACRejectTS; + tANI_U32 gLimNumAssocReqDropACRejectSta; + // Debug counter to track number of Reassoc Req frame drops + // when received in pStaDs->mlmState other than LINK_ESTABLISED + tANI_U32 gLimNumReassocReqDropInvldState; + // Debug counter to track number of Hash Miss event that + // will not cause a sending of de-auth/de-associate frame + tANI_U32 gLimNumHashMissIgnored; + + // Debug counter to track number of Beacon frames + // received in unexpected state + tANI_U32 gLimUnexpBcnCnt; + + // Debug counter to track number of Beacon frames + // received in wt-join-state that do have SSID mismatch + tANI_U32 gLimBcnSSIDMismatchCnt; + + // Debug counter to track number of Link establishments on STA/BP + tANI_U32 gLimNumLinkEsts; + + // Debug counter to track number of Rx cleanup + tANI_U32 gLimNumRxCleanup; + + // Debug counter to track different parse problem + tANI_U32 gLim11bStaAssocRejectCount; + +#endif + + //Time stamp of the last beacon received from the BSS to which STA is connected. + tANI_U64 gLastBeaconTimeStamp; + //RX Beacon count for the current BSS to which STA is connected. + tANI_U32 gCurrentBssBeaconCnt; + tANI_U8 gLastBeaconDtimCount; + tANI_U8 gLastBeaconDtimPeriod; + + + ////////////////////////////////////////// STATS/COUNTER RELATED END /////////////////////////////////////////// + + + ////////////////////////////////////////// STATES RELATED START /////////////////////////////////////////// + // Counts Heartbeat failures + tANI_U8 gLimHBfailureCntInLinkEstState; + tANI_U8 gLimProbeFailureAfterHBfailedCnt; + tANI_U8 gLimHBfailureCntInOtherStates; + + /** + * This variable indicates whether LIM module need to + * send response to host. Used to identify whether a request + * is generated internally within LIM module or by host + */ + tANI_U8 gLimRspReqd; + + /// Previous SME State + tLimSmeStates gLimPrevSmeState; + + /// MLM State visible across all Sirius modules + tLimMlmStates gLimMlmState; + + /// Previous MLM State + tLimMlmStates gLimPrevMlmState; + +#ifdef GEN4_SCAN + // LIM to HAL SCAN Management Message Interface states + tLimLimHalScanState gLimHalScanState; +//WLAN_SUSPEND_LINK Related + SUSPEND_RESUME_LINK_CALLBACK gpLimSuspendCallback; + tANI_U32 *gpLimSuspendData; + SUSPEND_RESUME_LINK_CALLBACK gpLimResumeCallback; + tANI_U32 *gpLimResumeData; +//end WLAN_SUSPEND_LINK Related + tANI_U8 fScanDisabled; + //Can be set to invalid channel. If it is invalid, HAL + //should move to previous valid channel or stay in the + //current channel. CB state goes along with channel to resume to + tANI_U16 gResumeChannel; + ePhyChanBondState gResumePhyCbState; +#endif // GEN4_SCAN + + // Change channel generic scheme + CHANGE_CHANNEL_CALLBACK gpchangeChannelCallback; + tANI_U32 *gpchangeChannelData; + + /// SME State visible across all Sirius modules + tLimSmeStates gLimSmeState; + /// This indicates whether we're an AP, STA in BSS/IBSS + tLimSystemRole gLimSystemRole; + + // Number of STAs that do not support short preamble + tLimNoShortParams gLimNoShortParams; + + // Number of STAs that do not support short slot time + tLimNoShortSlotParams gLimNoShortSlotParams; + + + // OLBC parameters + tLimProtStaParams gLimOverlap11gParams; + + tLimProtStaParams gLimOverlap11aParams; + tLimProtStaParams gLimOverlapHt20Params; + tLimProtStaParams gLimOverlapNonGfParams; + + // + // ---------------- DPH ----------------------- + // these used to live in DPH but are now moved here (where they belong) + tANI_U32 gLimPhyMode; + tANI_U32 propRateAdjustPeriod; + tANI_U32 scanStartTime; // used to measure scan time + + //tANI_U8 gLimBssid[6]; + tANI_U8 gLimMyMacAddr[6]; + tANI_U8 ackPolicy; + + tANI_U8 gLimQosEnabled:1; //11E + tANI_U8 gLimWmeEnabled:1; //WME + tANI_U8 gLimWsmEnabled:1; //WSM + tANI_U8 gLimHcfEnabled:1; + tANI_U8 gLim11dEnabled:1; + tANI_U8 gLimProbeRespDisableFlag:1; // control over probe response + // ---------------- DPH ----------------------- + + ////////////////////////////////////////// STATES RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// MISC RELATED START /////////////////////////////////////////// + + // WDS info + tANI_U32 gLimNumWdsInfoInd; + tANI_U32 gLimNumWdsInfoSet; + tSirWdsInfo gLimWdsInfo; + + // Deferred Queue Paramters + tLimDeferredMsgQParams gLimDeferredMsgQ; + + // addts request if any - only one can be outstanding at any time + tSirAddtsReq gLimAddtsReq; + tANI_U8 gLimAddtsSent; + tANI_U8 gLimAddtsRspTimerCount; + + //protection related config cache + tCfgProtection cfgProtection; + + tANI_U8 gLimProtectionControl; + //RF band to determibe 2.4/5 GHZ + + // alternate radio info used by STA + tSirAlternateRadioInfo gLimAlternateRadio; + + //This flag will remain to be set except while LIM is waiting for specific response messages + //from HAL. e.g when LIM issues ADD_STA req it will clear this flag and when it will receive + //the response the flag will be set. + tANI_U8 gLimProcessDefdMsgs; + + // UAPSD flag used on AP + tANI_U8 gUapsdEnable; + + /* Used on STA, this is a static UAPSD mask setting + * derived from SME_JOIN_REQ and SME_REASSOC_REQ. If a + * particular AC bit is set, it means the AC is both + * trigger enabled and delivery enabled. + */ + tANI_U8 gUapsdPerAcBitmask; + + /* Used on STA, this is a dynamic UPASD mask setting + * derived from AddTS Rsp and DelTS frame. If a + * particular AC bit is set, it means AC is trigger + * enabled. + */ + tANI_U8 gUapsdPerAcTriggerEnableMask; + + /* Used on STA, dynamic UPASD mask setting + * derived from AddTS Rsp and DelTs frame. If + * a particular AC bit is set, it means AC is + * delivery enabled. + */ + tANI_U8 gUapsdPerAcDeliveryEnableMask; + + /* Used on STA for AC downgrade. This is a dynamic mask + * setting which keep tracks of ACs being admitted. + * If bit is set to 0: That partiular AC is not admitted + * If bit is set to 1: That particular AC is admitted + */ + tANI_U8 gAcAdmitMask[SIR_MAC_DIRECTION_DIRECT]; + + //dialogue token List head/tail for Action frames request sent. + tpDialogueToken pDialogueTokenHead; + tpDialogueToken pDialogueTokenTail; + + tLimTspecInfo tspecInfo[LIM_NUM_TSPEC_MAX]; + + // admission control policy information + tLimAdmitPolicyInfo admitPolicyInfo; + vos_lock_t lkPeGlobalLock; + tANI_U8 disableLDPCWithTxbfAP; +#ifdef FEATURE_WLAN_TDLS + tANI_U8 gLimTDLSBufStaEnabled; + tANI_U8 gLimTDLSUapsdMask; + tANI_U8 gLimTDLSOffChannelEnabled; + // TDLS WMM Mode + tANI_U8 gLimTDLSWmmMode; +#endif + + + + ////////////////////////////////////////// MISC RELATED END /////////////////////////////////////////// + + ////////////////////////////////////////// ASSOC RELATED START /////////////////////////////////////////// + // Place holder for JoinReq message + // received by SME state machine + // tpSirSmeJoinReq gpLimJoinReq; + + // Place holder for ReassocReq message + // received by SME state machine + //tpSirSmeReassocReq gpLimReassocReq; sep23 review + + // Current Authentication type used at STA + //tAniAuthType gLimCurrentAuthType; + + // Place holder for current authentication request + // being handled + tLimMlmAuthReq *gpLimMlmAuthReq; + + // Place holder for Join request that we're + // currently attempting + //tLimMlmJoinReq *gpLimMlmJoinReq; + + // Reason code to determine the channel change context while sending + // WDA_CHNL_SWITCH_REQ message to HAL + tANI_U32 channelChangeReasonCode; + + /// MAC level Pre-authentication related globals + tSirMacChanNum gLimPreAuthChannelNumber; + tAniAuthType gLimPreAuthType; + tSirMacAddr gLimPreAuthPeerAddr; + tANI_U32 gLimNumPreAuthContexts; + tLimPreAuthTable gLimPreAuthTimerTable; + + // Placed holder to deauth reason + tANI_U16 gLimDeauthReasonCode; + + // Place holder for Pre-authentication node list + struct tLimPreAuthNode * pLimPreAuthList; + + // Assoc or ReAssoc Response Data/Frame + void *gLimAssocResponseData; + + //One cache for each overlap and associated case. + tCacheParams protStaOverlapCache[LIM_PROT_STA_OVERLAP_CACHE_SIZE]; + tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE]; + + ////////////////////////////////////////// ASSOC RELATED END /////////////////////////////////////////// + + + + // + // For DEBUG purposes + // Primarily for - TITAN BEACON workaround + // Symptom - TFP/PHY gets stuck + // + tANI_U32 gLimScanOverride; + // Holds the desired tSirScanType, as requested by SME + tSirScanType gLimScanOverrideSaved; + + // + // CB State protection, operated upon as follows: + // 1 - CB is enabled in the hardware ONLY WHEN a Titan + // STA associates with the AP + // 0 - CB is enabled/disabled based on the configuration + // received as per eWNI_SME_START_BSS_REQ + // + tANI_U32 gLimCBStateProtection; + + // Count of TITAN STA's currently associated + tANI_U16 gLimTitanStaCount; + + // + // For DEBUG purposes + // Primarily for - TITAN workaround + // Symptom - Avoid NULL data frames + // Applies to AP only + // + tANI_U32 gLimBlockNonTitanSta; + /////////////////////////// TITAN related globals ////////////////////////////////////////// + + + //////////////////////////////// HT RELATED ////////////////////////////////////////// + // + // The following global LIM variables maintain/manage + // the runtime configurations related to 802.11n + + // 802.11n Station detected HT capability in Beacon Frame + tANI_U8 htCapabilityPresentInBeacon; + + // 802.11 HT capability: Enabled or Disabled + tANI_U8 htCapability; + + + tANI_U8 gHTGreenfield; + + tANI_U8 gHTShortGI40Mhz; + tANI_U8 gHTShortGI20Mhz; + + //Set to 0 for 3839 octets + //Set to 1 for 7935 octets + tANI_U8 gHTMaxAmsduLength; + + + // DSSS/CCK at 40 MHz: Enabled 1 or Disabled + tANI_U8 gHTDsssCckRate40MHzSupport; + + // PSMP Support: Enabled 1 or Disabled 0 + tANI_U8 gHTPSMPSupport; + + // L-SIG TXOP Protection used only if peer support available + tANI_U8 gHTLsigTXOPProtection; + + // MIMO Power Save + tSirMacHTMIMOPowerSaveState gHTMIMOPSState; + + // Scan In Power Save + tANI_U8 gScanInPowersave; + + // + // A-MPDU Density + // 000 - No restriction + // 001 - 1/8 usec + // 010 - 1/4 usec + // 011 - 1/2 usec + // 100 - 1 usec + // 101 - 2 usec + // 110 - 4 usec + // 111 - 8 usec + // + tANI_U8 gHTAMpduDensity; + + tANI_BOOLEAN gMaxAmsduSizeEnabled; + // Maximum Tx/Rx A-MPDU factor + tANI_U8 gHTMaxRxAMpduFactor; + + // + // Scheduled PSMP related - Service Interval Granularity + // 000 - 5 ms + // 001 - 10 ms + // 010 - 15 ms + // 011 - 20 ms + // 100 - 25 ms + // 101 - 30 ms + // 110 - 35 ms + // 111 - 40 ms + // + tANI_U8 gHTServiceIntervalGranularity; + + // Indicates whether an AP wants to associate PSMP enabled Stations + tANI_U8 gHTControlledAccessOnly; + + // RIFS Mode. Set if no APSD legacy devices associated + tANI_U8 gHTRifsMode; + // OBss Mode . set when we have Non HT STA is associated or with in overlap bss + tANI_U8 gHTObssMode; + + // Identifies the current Operating Mode + tSirMacHTOperatingMode gHTOperMode; + + // Indicates if PCO is activated in the BSS + tANI_U8 gHTPCOActive; + + // + // If PCO is active, indicates which PCO phase to use + // 0 - switch to 20 MHz phase + // 1 - switch to 40 MHz phase + // + tANI_U8 gHTPCOPhase; + + // + // Used only in beacons. For PR, this is set to 0 + // 0 - Primary beacon + // 1 - Secondary beacon + // + tANI_U8 gHTSecondaryBeacon; + + // + // Dual CTS Protection + // 0 - Use RTS/CTS + // 1 - Dual CTS Protection is used + // + tANI_U8 gHTDualCTSProtection; + + // + // Identifies a single STBC MCS that shall ne used for + // STBC control frames and STBC beacons + // + tANI_U8 gHTSTBCBasicMCS; + + tANI_U8 gHTNonGFDevicesPresent; + + tANI_U8 gAddBA_Declined; // Flag to Decline the BAR if the particular bit (0-7) is being set + + //////////////////////////////// HT RELATED ////////////////////////////////////////// + +#ifdef FEATURE_WLAN_TDLS + tANI_U8 gLimAddStaTdls ; + tANI_U8 gLimTdlsLinkMode ; + //////////////////////////////// TDLS RELATED ////////////////////////////////////////// +#endif + + // wsc info required to form the wsc IE + tLimWscIeInfo wscIeInfo; + tpPESession gpSession ; //Pointer to session table + /* + * sessionID and transactionID from SME is stored here for those messages, for which + * there is no session context in PE, e.g. Scan related messages. + **/ + tANI_U8 gSmeSessionId; + tANI_U16 gTransactionId; + +#ifdef FEATURE_OEM_DATA_SUPPORT +tLimMlmOemDataReq *gpLimMlmOemDataReq; +tLimMlmOemDataRsp *gpLimMlmOemDataRsp; +#endif + + tSirRemainOnChnReq *gpLimRemainOnChanReq; //hold remain on chan request in this buf + vos_list_t gLimMgmtFrameRegistratinQueue; + tANI_U32 mgmtFrameSessionId; + tSirBackgroundScanMode gLimBackgroundScanMode; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tpPESession pSessionEntry; + tANI_U8 reAssocRetryAttempt; +#endif + tLimDisassocDeauthCnfReq limDisassocDeauthCnfReq; + tANI_U8 deferredMsgCnt; + tSirDFSChannelList dfschannelList; + tANI_U8 deauthMsgCnt; + tANI_U8 gLimIbssStaLimit; + tANI_U8 probeCounter; + tANI_U8 maxProbe; + tANI_U8 retryPacketCnt; + + // Flag to debug remain on channel + tANI_BOOLEAN gDebugP2pRemainOnChannel; + /* Sequence number to keep track of + * start and end of remain on channel + * debug marker frame. + */ + tANI_U32 remOnChnSeqNum; + tANI_U32 txBdToken; + tANI_U32 EnableTdls2040BSSCoexIE; + tLimStaBAInfo staBaInfo[WLAN_MAX_STA_COUNT]; +} tAniSirLim, *tpAniSirLim; + +typedef struct sLimMgmtFrameRegistration +{ + vos_list_node_t node; // MUST be first element + tANI_U16 frameType; + tANI_U16 matchLen; + tANI_U16 sessionId; + tANI_U8 matchData[1]; +} tLimMgmtFrameRegistration, *tpLimMgmtFrameRegistration; + +#if defined WLAN_FEATURE_VOWIFI +typedef struct sRrmContext +{ + tRrmSMEContext rrmSmeContext; + tRrmPEContext rrmPEContext; +}tRrmContext, *tpRrmContext; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +typedef struct sFTContext +{ + tftSMEContext ftSmeContext; + tftPEContext ftPEContext; +} tftContext, *tpFTContext; +#endif + +typedef struct assoc_rsp_tx_context +{ + vos_list_node_t node; + tANI_U8 psessionID; + tANI_U16 staId; + tANI_U32 txBdToken; +} assoc_rsp_tx_context; + +//Check if this definition can actually move here even for Volans. In that case +//this featurization can be removed. +/** ------------------------------------------------------------------------- * + + \typedef tDriverType + + \brief Indicate the driver type to the mac, and based on this do + appropriate initialization. + + -------------------------------------------------------------------------- */ + +typedef enum +{ + eDRIVER_TYPE_PRODUCTION = 0, + eDRIVER_TYPE_MFG = 1, + eDRIVER_TYPE_DVT = 2 +} tDriverType; + +/** ------------------------------------------------------------------------- * + + \typedef tMacOpenParameters + + \brief Parameters needed for Enumeration of all status codes returned by the higher level + interface functions. + + -------------------------------------------------------------------------- */ + +typedef struct sMacOpenParameters +{ + tANI_U16 maxStation; + tANI_U16 maxBssId; + tANI_U32 frameTransRequired; + tDriverType driverType; +} tMacOpenParameters; + +typedef struct sHalMacStartParameters +{ + // parametes for the Firmware + //tHalFirmwareParameters FW; + tDriverType driverType; + +} tHalMacStartParameters; + +typedef enum +{ + LIM_AUTH_ACK_NOT_RCD, + LIM_AUTH_ACK_RCD_SUCCESS, + LIM_AUTH_ACK_RCD_FAILURE, +} tAuthAckStatus; + +// ------------------------------------------------------------------- +/// MAC Sirius parameter structure +typedef struct sAniSirGlobal + +{ + tDriverType gDriverType; + + // we should be able to save this hddHandle in here and deprecate + // the pAdapter. For now, compiles are a problem because there + // are dependencides on the header files that are not handling the + // compiler very gracefully. +// tHddHandle hHdd; // Handle to the HDD. + //void *hHdd; + void *pAdapter; // deprecate this pAdapter pointer eventually... + // all interfaces to the HDD should pass hHdd, which + // is stored in this struct above..... + tSirMbMsg* pResetMsg; + tAniSirCfg cfg; + tAniSirLim lim; + tAniSirPmm pmm; + tAniSirSch sch; + tAniSirSys sys; + tAniSirUtils utils; + // PAL/HDD handle + tHddHandle hHdd; + +#ifdef ANI_DVT_DEBUG + tAniSirDvt dvt; +#endif + + tSmeStruct sme; + tCsrScanStruct scan; + tCsrRoamStruct roam; + +#ifdef FEATURE_OEM_DATA_SUPPORT + tOemDataStruct oemData; +#endif + tPmcInfo pmc; + tSmeBtcInfo btc; + + tCcm ccm; + +#if defined WLAN_FEATURE_VOWIFI + tRrmContext rrm; +#endif +#ifdef WLAN_FEATURE_CONCURRENT_P2P + tp2pContext p2pContext[MAX_NO_OF_P2P_SESSIONS]; +#else + tp2pContext p2pContext; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + tftContext ft; +#endif + vos_list_t assoc_rsp_completion_list; + tANI_U32 gCurrentLogSize; + tANI_U32 menuCurrent; + /* logDump specific */ + tANI_U32 dumpTablecurrentId; + /* Instead of static allocation I will dyanamically allocate memory for dumpTableEntry + Thinking of using linkedlist */ + tDumpModuleEntry *dumpTableEntry[MAX_DUMP_TABLE_ENTRY]; +#ifdef FEATURE_WLAN_TDLS + v_BOOL_t isTdlsPowerSaveProhibited; +#endif + tANI_U8 fScanOffload; +#ifdef WLAN_FEATURE_RMC + tLimRmcContext rmcContext; +#endif /* WLAN_FEATURE_RMC */ + tANI_U8 isCoalesingInIBSSAllowed; + tANI_U32 fEnableDebugLog; + tANI_U32 fDeferIMPSTime; + tANI_BOOLEAN deferImps; + +#ifdef WLAN_FEATURE_11AC + /* Alow Mu BFormee session only if MU BF session doesnt exist. + */ + v_BOOL_t isMuBfsessionexist; +#endif + + v_BOOL_t isCoexScoIndSet; + v_U8_t miracast_mode; + v_U8_t fBtcEnableIndTimerVal; + v_U8_t roamDelayStatsEnabled; + tANI_BOOLEAN miracastVendorConfig; + v_BOOL_t fActiveScanOnDFSChannels; + tAuthAckStatus authAckStatus; + sir_mgmt_frame_ind_callback mgmt_frame_ind_cb; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + v_U8_t PERroamCandidatesCnt; + tSirCandidateChanInfo candidateChannelInfo[SIR_PER_ROAM_MAX_CANDIDATE_CNT]; + tSirRoamAPInfo previousRoamApInfo[SIR_PER_ROAM_MAX_CANDIDATE_CNT]; + v_U32_t PERroamTimeout; + v_U32_t currentBssScore; +#endif +#ifdef SAP_AUTH_OFFLOAD + bool sap_auth_offload; + uint32_t sap_auth_offload_sec_type; +#endif /* SAP_AUTH_OFFLOAD */ + bool max_power_cmd_pending; + uint32_t sta_auth_retries_for_code17; +} tAniSirGlobal; + +#ifdef FEATURE_WLAN_TDLS + +#define RFC1042_HDR_LENGTH (6) +#define GET_BE16(x) ((tANI_U16) (((x)[0] << 8) | (x)[1])) +#define ETH_TYPE_89_0d (0x890d) +#define ETH_TYPE_LEN (2) +#define PAYLOAD_TYPE_TDLS_SIZE (1) +#define PAYLOAD_TYPE_TDLS (2) + +#endif + +#endif /* _ANIGLOBAL_H */ + diff --git a/drivers/staging/prima/CORE/MAC/inc/aniParam.h b/drivers/staging/prima/CORE/MAC/inc/aniParam.h new file mode 100644 index 000000000000..26ad80eea0a1 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/aniParam.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * aniParam.h: MAC parameter interface. + * Author: Kevin Nguyen + * Date: 09/09/2002 + * + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ + +#ifndef _ANIPARAM_H +#define _ANIPARAM_H + +#include "halTypes.h" + +/** + * -------------------------------------------------------------------------* + * MAC parameter structure * + * This structure is the only interface passed between the MAC FW and the * + * host driver. * + * * + * Host-to-MAC parameters: * + * ======================= * + * radioId: radio ID (1 or 2) * + * pPacketBufAlloc: function pointer for SKBuffer allocation * + * pPacketBufFree : function pointer for SKBuffer free * + * * + *------------------------------------------------------------------------- + */ +typedef struct +{ + // HDD to MAC parameters + int radioId; + + void (*pPacketBufAlloc)(unsigned short size, void **ppBuf, + void **ppSkb, void *dev); + void (*pPacketBufFree)(void* pBuf, void *pSkb); + + int rx_tasklet; + + // block table allocated by HDD + void * block_table; + + tHalHandle hHalHandle; + +} tAniMacParam; + + +#ifdef ANI_AP_SDK +#define NUM_RADIO 1 +#else +#define NUM_RADIO 2 +#endif + + +#endif /* _ANIPARAM_H */ + + diff --git a/drivers/staging/prima/CORE/MAC/inc/aniSystemDefs.h b/drivers/staging/prima/CORE/MAC/inc/aniSystemDefs.h new file mode 100644 index 000000000000..0eb1cce4205b --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/aniSystemDefs.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file aniSystemDefs.h contains definitions used by + * various ANI entities + * Author: Chandra Modumudi + * Date: 09/18/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __ANI_SYSTEM_DEFS_H +#define __ANI_SYSTEM_DEFS_H + +#include "sirTypes.h" +#include "sirMacProtDef.h" + +#define ANI_OUI 0x000AF5 + +/// Max WDS info length. +#define ANI_WDS_INFO_MAX_LENGTH 64 + + +/// Max number of SSIDs to support Multiple SSID feature +#define ANI_MAX_NUM_OF_SSIDS 16 + +//This is to force compiler to use the maximum of an int for enum +#define SIR_MAX_ENUM_SIZE 0x7FFFFFFF + +/* Max key size including the WAPI and TKIP */ +#define WLAN_MAX_KEY_RSC_LEN 16 +#define WLAN_WAPI_KEY_RSC_LEN 16 + + + +#ifndef FALSE +#undef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#undef TRUE +#define TRUE 1 +#endif + +typedef enum eAniBool +{ + eSIR_FALSE, + eSIR_TRUE, + eSIR_DONOT_USE_BOOL = SIR_MAX_ENUM_SIZE +} tAniBool; + +/// Authentication type enum used with peer +typedef enum eAniAuthType +{ + eSIR_OPEN_SYSTEM, + eSIR_SHARED_KEY, +#if defined WLAN_FEATURE_VOWIFI_11R + eSIR_FT_AUTH, +#endif +#if defined FEATURE_WLAN_ESE + eSIR_LEAP_AUTH = 0x80, +#endif + eSIR_AUTO_SWITCH, + eSIR_DONOT_USE_AUTH_TYPE = SIR_MAX_ENUM_SIZE +} tAniAuthType; + +/// Encryption type enum used with peer +typedef enum eAniEdType +{ + eSIR_ED_NONE, + eSIR_ED_WEP40, + eSIR_ED_WEP104, + eSIR_ED_TKIP, + eSIR_ED_CCMP, +#if defined(FEATURE_WLAN_WAPI) + eSIR_ED_WPI, +#endif + /*DPU HW treats encryption mode 4 plus RMF bit set in TX BD as BIP. + Thus while setting BIP encryption mode in corresponding DPU Desc + eSIR_ED_AES_128_CMAC should be set to eSIR_ED_CCMP*/ + eSIR_ED_AES_128_CMAC, + eSIR_ED_NOT_IMPLEMENTED = SIR_MAX_ENUM_SIZE +} tAniEdType; + + +typedef enum eAniWepType +{ + eSIR_WEP_STATIC, + eSIR_WEP_DYNAMIC, +} tAniWepType; + +/// Enum to specify whether key is used +/// for TX only, RX only or both +typedef enum eAniKeyDirection +{ + eSIR_TX_ONLY, + eSIR_RX_ONLY, + eSIR_TX_RX, + eSIR_TX_DEFAULT, + eSIR_DONOT_USE_KEY_DIRECTION = SIR_MAX_ENUM_SIZE +} tAniKeyDirection; + +/// Enum for rate +typedef enum eAniRate +{ + eSIR_ANY_RATE +} tAniRate; + +typedef struct sAniSSID +{ + tANI_U8 length; + tANI_U8 ssId[SIR_MAC_MAX_SSID_LENGTH]; +} tAniSSID, *tpAniSSID; + +typedef struct sAniApName +{ + tANI_U8 length; + tANI_U8 name[SIR_MAC_MAX_SSID_LENGTH]; +} tAniApName, *tpAniApName; + +/// RSN IE information +typedef struct sSirRSNie +{ + tANI_U16 length; + tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; +} tSirRSNie, *tpSirRSNie; + +/// Additional IE information : +/// This can include WSC IE, P2P IE, and/or FTIE from upper layer. +/// MAC layer transparently convey these IE info between peer STA and upper layer, +/// but never requires to parse it. +typedef struct sSirAddie +{ + tANI_U16 length; + tANI_U8 addIEdata[SIR_MAC_MAX_ADD_IE_LENGTH+2]; +} tSirAddie, *tpSirAddie; + +#ifdef FEATURE_WLAN_ESE + +// The CCKM IE needs to be in the +// Join and Reassoc Req. +typedef struct sSirCCKMie +{ + tANI_U16 length; + tANI_U8 cckmIEdata[SIR_MAC_MAX_IE_LENGTH+2]; +} tSirCCKMie, *tpSirCCKMie; + +#endif + +/// Need to refine structure definitions for Keying material, +/// QoS policy, etc + +/// Definition Quality of Service +typedef struct sSirQos +{ + tANI_U16 temp1; // Need to define later + tANI_U16 temp2; // Need to define later +} tSirQos, *tpSirQos; + +/// Definition for Encryption Keys +typedef struct sSirKeys +{ + tANI_U8 keyId; + tANI_U8 unicast; // 0 for multicast + tAniKeyDirection keyDirection; + tANI_U8 keyRsc[WLAN_MAX_KEY_RSC_LEN]; // Usage is unknown + tANI_U8 paeRole; // =1 for authenticator, + // =0 for supplicant + tANI_U16 keyLength; + tANI_U8 key[SIR_MAC_MAX_KEY_LENGTH]; +} tSirKeys, *tpSirKeys; + +/// Definition for Keying material +typedef struct sSirKeyMaterial +{ + tANI_U16 length; // This is the length of all + // data that follows + tAniEdType edType; // Encryption/Decryption type + tANI_U8 numKeys; + tSirKeys key[1]; +} tSirKeyMaterial, *tpSirKeyMaterial; + +#define SIR_CIPHER_SEQ_CTR_SIZE 6 +/// Definition for MIC failure indication +typedef struct sSirMicFailureInfo +{ + tSirMacAddr srcMacAddr; //address used to compute MIC + tSirMacAddr taMacAddr; //transmitter address + tSirMacAddr dstMacAddr; + tAniBool multicast; + tANI_U8 IV1; // first byte of IV + tANI_U8 keyId; // second byte of IV + tANI_U8 TSC[SIR_CIPHER_SEQ_CTR_SIZE]; // sequence number + tSirMacAddr rxMacAddr; // receive address + +} tSirMicFailureInfo, *tpSirMicFailureInfo; + +typedef struct sSirLostLinkParamsInfo +{ + tANI_U8 bssIdx; + tANI_U8 rssi; + tSirMacAddr selfMacAddr; + tANI_U32 linkFlCnt; + tANI_U32 linkFlTx; + tANI_U32 lastDataRate; + tANI_U32 rsvd1; + tANI_U32 rsvd2; +}tSirLostLinkParamsInfo, *tpSirLostLinkParamsInfo; + +// Boa command. Used mainly for radar info persistance +typedef struct sBoaCommand +{ + tANI_U8 length; + tANI_U8 cmd[64]; +}tBoaCommand; + + +typedef __ani_attr_pre_packed struct sTrafStrmMetrics +{ + tANI_U16 UplinkPktQueueDly; + tANI_U16 UplinkPktQueueDlyHist[4]; + tANI_U32 UplinkPktTxDly; + tANI_U16 UplinkPktLoss; + tANI_U16 UplinkPktCount; + tANI_U8 RoamingCount; + tANI_U16 RoamingDly; +} __ani_attr_packed tTrafStrmMetrics, *tpTrafStrmMetrics; + + +typedef __ani_attr_pre_packed struct sBcnReportFields +{ + tANI_U8 ChanNum; + tANI_U8 Spare; + tANI_U16 MeasDuration; + tANI_U8 PhyType; + tANI_U8 RecvSigPower; + tSirMacAddr Bssid; + tANI_U32 ParentTsf; + tANI_U32 TargetTsf[2]; + tANI_U16 BcnInterval; + tANI_U16 CapabilityInfo; +} __ani_attr_packed tBcnReportFields, *tpBcnReportFields; + + +#endif /* __ANI_SYSTEM_DEFS_H */ + diff --git a/drivers/staging/prima/CORE/MAC/inc/logDump.h b/drivers/staging/prima/CORE/MAC/inc/logDump.h new file mode 100644 index 000000000000..77cfc488d861 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/logDump.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + +logDump.h + +Provides api's for dump commands. + +Author: Santosh Mandiganal +Date: 04/06/2008 +============================================================================*/ + + +#ifndef __LOGDUMP_H__ +#define __LOGDUMP_H__ + +#define MAX_DUMP_CMD 999 +#define MAX_DUMP_TABLE_ENTRY 10 + +typedef char * (*tpFunc)(tpAniSirGlobal, tANI_U32, tANI_U32, tANI_U32, tANI_U32, char *); + +typedef struct sDumpFuncEntry { + tANI_U32 id; + char *description; + tpFunc func; +} tDumpFuncEntry; + +typedef struct sDumpModuleEntry { + tANI_U32 mindumpid; + tANI_U32 maxdumpid; + tANI_U32 nItems; + tDumpFuncEntry *dumpTable; +} tDumpModuleEntry; + +typedef struct sRegList { + tANI_U32 addr; + char *name; +} tLogdRegList; + +int log_sprintf(tpAniSirGlobal pMac, char *pBuf, char *fmt, ... ); + +char * +dump_log_level_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p); + +char * +dump_cfg_set( tpAniSirGlobal pMac, tANI_U32 arg1, + tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p); + +char * +dump_cfg_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p); + +char * +dump_cfg_group_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p); + +void logDumpRegisterTable( tpAniSirGlobal pMac, tDumpFuncEntry *pEntry, + tANI_U32 nItems ); + + +void logDumpInit(tpAniSirGlobal pMac); + +#endif /* __LOGDUMP_H__ */ diff --git a/drivers/staging/prima/CORE/MAC/inc/macInitApi.h b/drivers/staging/prima/CORE/MAC/inc/macInitApi.h new file mode 100644 index 000000000000..d95cce1f5c70 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/macInitApi.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * macInitApi.c - Header file for mac level init functions + * Author: Dinesh Upadhyay + * Date: 04/23/2007 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ +#ifndef __MAC_INIT_API_H +#define __MAC_INIT_API_H + +#include "aniGlobal.h" + +tSirRetStatus macStart(tHalHandle hHal, void* pHalMacStartParams); +tSirRetStatus macStop(tHalHandle hHal, tHalStopType stopType); +tSirRetStatus macOpen(tHalHandle * pHalHandle, tHddHandle hHdd, tMacOpenParameters * pMacOpenParms); +tSirRetStatus macClose(tHalHandle hHal); + +tSirRetStatus macPreStart(tHalHandle hHal); + +#endif //__MAC_INIT_API_H + diff --git a/drivers/staging/prima/CORE/MAC/inc/macTrace.h b/drivers/staging/prima/CORE/MAC/inc/macTrace.h new file mode 100644 index 000000000000..2ee4c7fc02cb --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/macTrace.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file macTrace.h + + \brief definition for trace related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + + + +#ifndef __MAC_TRACE_H +#define __MAC_TRACE_H + +#include "aniGlobal.h" + + +#ifdef TRACE_RECORD + +#define MAC_TRACE_GET_MODULE_ID(data) ((data >> 8) & 0xff) +#define MAC_TRACE_GET_MSG_ID(data) (data & 0xffff) + + +#define eLOG_NODROP_MISSED_BEACON_SCENARIO 0 +#define eLOG_PROC_DEAUTH_FRAME_SCENARIO 1 + +void macTraceReset(tpAniSirGlobal pMac); +void macTrace(tpAniSirGlobal pMac, tANI_U8 code, tANI_U8 session, tANI_U32 data); +void macTraceNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 code, tANI_U8 session, tANI_U32 data); +tANI_U8* macTraceGetCfgMsgString( tANI_U16 cfgMsg ); +tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ); +tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ); +tANI_U8* macTraceGetSmeMsgString( tANI_U16 smeMsg ); +tANI_U8* macTraceGetModuleString( tANI_U8 moduleId); +tANI_U8* macTraceGetInfoLogString( tANI_U16 infoLog ); +eHalStatus pe_AcquireGlobalLock( tAniSirLim *psPe); +eHalStatus pe_ReleaseGlobalLock( tAniSirLim *psPe); + +tANI_U8* macTraceGetHDDWlanConnState(tANI_U16 connState); + +#ifdef WLAN_FEATURE_P2P_DEBUG +tANI_U8* macTraceGetP2PConnState(tANI_U16 connState); +#endif + +tANI_U8* macTraceGetNeighbourRoamState(tANI_U16 neighbourRoamState); +tANI_U8* macTraceGetcsrRoamState(tANI_U16 csrRoamState); +tANI_U8* macTraceGetcsrRoamSubState(tANI_U16 csrRoamSubState); +tANI_U8* macTraceGetLimSmeState(tANI_U16 limState); +tANI_U8* macTraceGetLimMlmState(tANI_U16 mlmState); +tANI_U8* macTraceGetTLState(tANI_U16 tlState); + +#endif + +#endif + diff --git a/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h b/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h new file mode 100644 index 000000000000..07a6af758a88 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/qwlan_version.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef QWLAN_VERSION_H +#define QWLAN_VERSION_H +/*=========================================================================== + +FILE: + qwlan_version.h + +BRIEF DESCRIPTION: + WLAN Host Version file. + Build number automaticly updated by build scripts. + + +===========================================================================*/ + +#define QWLAN_VERSION_MAJOR 3 +#define QWLAN_VERSION_MINOR 0 +#define QWLAN_VERSION_PATCH 11 +#define QWLAN_VERSION_EXTRA "" + +#define QWLAN_VERSION_BUILD 85 + +#define QWLAN_VERSIONSTR "3.0.11.85" + +#endif /* QWLAN_VERSION_H */ diff --git a/drivers/staging/prima/CORE/MAC/inc/sirApi.h b/drivers/staging/prima/CORE/MAC/inc/sirApi.h new file mode 100644 index 000000000000..de0f9cc7ebb7 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/sirApi.h @@ -0,0 +1,6330 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file sirApi.h contains definitions exported by + * Sirius software. + * Author: Chandra Modumudi + * Date: 04/16/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIR_API_H +#define __SIR_API_H + +/* Take care to avoid redefinition of this type, if it is */ +/* already defined in "halWmmApi.h" */ +#if !defined(_HALMAC_WMM_API_H) +typedef struct sAniSirGlobal *tpAniSirGlobal; +#endif + + +#include "sirTypes.h" +#include "sirMacProtDef.h" +#include "aniSystemDefs.h" +#include "sirParams.h" +#include + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseGlobal.h" +#endif + +/// Maximum number of STAs allowed in the BSS +#define SIR_MAX_NUM_STA 256 + +/// Maximum number of Neighbors reported by STA for LB feature +#define SIR_MAX_NUM_NEIGHBOR_BSS 3 + +/// Maximum number of Neighbors reported by STA for LB feature +#define SIR_MAX_NUM_ALTERNATE_RADIOS 5 + +/// Maximum size of SCAN_RSP message +#define SIR_MAX_SCAN_RSP_MSG_LENGTH 2600 + +/// Start of Sirius software/Host driver message types +#define SIR_HAL_HOST_MSG_START 0x1000 + +/// Power save level definitions +#define SIR_MAX_POWER_SAVE 3 +#define SIR_INTERMEDIATE_POWER_SAVE 4 +#define SIR_NO_POWER_SAVE 5 + +/// Max supported channel list +#define SIR_MAX_SUPPORTED_CHANNEL_LIST 96 + +/// Maximum DTIM Factor +#define SIR_MAX_DTIM_FACTOR 32 + +#define SIR_MDIE_SIZE 3 + +/* Max number of channels are 165, but to access 165th element of array, + *array of 166 is required. + */ +#define SIR_MAX_24G_5G_CHANNEL_RANGE 166 +#define SIR_BCN_REPORT_MAX_BSS_DESC 4 + + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define SIR_MAX_SSID_SIZE (32) +#endif + + +#define SIR_NUM_11B_RATES 4 //1,2,5.5,11 +#define SIR_NUM_11A_RATES 8 //6,9,12,18,24,36,48,54 +#define SIR_NUM_POLARIS_RATES 3 //72,96,108 +#define SIR_NUM_TITAN_RATES 26 +#define SIR_NUM_TAURUS_RATES 4 //136.5, 151.7,283.5,315 +#define SIR_NUM_PROP_RATES (SIR_NUM_TITAN_RATES + SIR_NUM_TAURUS_RATES) + +#define SIR_11N_PROP_RATE_136_5 (1<<28) +#define SIR_11N_PROP_RATE_151_7 (1<<29) +#define SIR_11N_PROP_RATE_283_5 (1<<30) +#define SIR_11N_PROP_RATE_315 (1<<31) +#define SIR_11N_PROP_RATE_BITMAP 0x80000000 //only 315MBPS rate is supported today +//Taurus is going to support 26 Titan Rates(no ESF/concat Rates will be supported) +//First 26 bits are reserved for Titan and last 4 bits for Taurus, 2(27 and 28) bits are reserved. +//#define SIR_TITAN_PROP_RATE_BITMAP 0x03FFFFFF +//Disable all Titan rates +#define SIR_TITAN_PROP_RATE_BITMAP 0 +#define SIR_CONVERT_2_U32_BITMAP(nRates) ((nRates + 31)/32) + +/* #tANI_U32's needed for a bitmap representation for all prop rates */ +#define SIR_NUM_U32_MAP_RATES SIR_CONVERT_2_U32_BITMAP(SIR_NUM_PROP_RATES) + + +#define SIR_PM_SLEEP_MODE 0 +#define SIR_PM_ACTIVE_MODE 1 + +// Used by various modules to load ALL CFG's +#define ANI_IGNORE_CFG_ID 0xFFFF + +//hidden SSID options +#define SIR_SCAN_NO_HIDDEN_SSID 0 +#define SIR_SCAN_HIDDEN_SSID_PE_DECISION 1 +#define SIR_SCAN_HIDDEN_SSID 2 + +#define SIR_MAC_ADDR_LEN 6 +#define SIR_IPV4_ADDR_LEN 4 + +typedef tANI_U8 tSirIpv4Addr[SIR_IPV4_ADDR_LEN]; + +#define SIR_VERSION_STRING_LEN 64 +typedef tANI_U8 tSirVersionString[SIR_VERSION_STRING_LEN]; + +/* Periodic Tx pattern offload feature */ +#define PERIODIC_TX_PTRN_MAX_SIZE 1536 +#define MAXNUM_PERIODIC_TX_PTRNS 6 + + +#ifdef WLAN_FEATURE_EXTSCAN + +#define WLAN_EXTSCAN_MAX_CHANNELS 16 +#define WLAN_EXTSCAN_MAX_BUCKETS 16 +#define WLAN_EXTSCAN_MAX_HOTLIST_APS 128 +#define WLAN_EXTSCAN_MAX_RSSI_SAMPLE_SIZE 8 +#endif /* WLAN_FEATURE_EXTSCAN */ + +#define WLAN_DISA_MAX_PAYLOAD_SIZE 1600 + +enum eSirHostMsgTypes +{ + SIR_HAL_APP_SETUP_NTF = SIR_HAL_HOST_MSG_START, + SIR_HAL_INITIAL_CAL_FAILED_NTF, + SIR_HAL_NIC_OPER_NTF, + SIR_HAL_INIT_START_REQ, + SIR_HAL_SHUTDOWN_REQ, + SIR_HAL_SHUTDOWN_CNF, + SIR_HAL_RESET_REQ, + SIR_HAL_RADIO_ON_OFF_IND, + SIR_HAL_RESET_CNF, + SIR_WRITE_TO_TD, + SIR_HAL_HDD_ADDBA_REQ, // MAC -> HDD + SIR_HAL_HDD_ADDBA_RSP, // HDD -> HAL + SIR_HAL_DELETEBA_IND, // MAC -> HDD + SIR_HAL_BA_FAIL_IND, // HDD -> MAC + SIR_TL_HAL_FLUSH_AC_REQ, + SIR_HAL_TL_FLUSH_AC_RSP +}; + + + +/** + * Module ID definitions. + */ +enum { + SIR_BOOT_MODULE_ID = 1, + SIR_HAL_MODULE_ID = 0x10, + SIR_HAL_EXT_MODULE_ID = 0x11, + SIR_CFG_MODULE_ID = 0x12, + SIR_LIM_MODULE_ID, + SIR_ARQ_MODULE_ID, + SIR_SCH_MODULE_ID, + SIR_PMM_MODULE_ID, + SIR_MNT_MODULE_ID, + SIR_DBG_MODULE_ID, + SIR_DPH_MODULE_ID, + SIR_SYS_MODULE_ID, + SIR_SMS_MODULE_ID, + + SIR_PHY_MODULE_ID = 0x20, + + + // Add any modules above this line + SIR_DVT_MODULE_ID +}; + +#define SIR_WDA_MODULE_ID SIR_HAL_MODULE_ID + +/** + * First and last module definition for logging utility + * + * NOTE: The following definitions need to be updated if + * the above list is changed. + */ +#define SIR_FIRST_MODULE_ID SIR_HAL_MODULE_ID +#define SIR_LAST_MODULE_ID SIR_DVT_MODULE_ID + + +// Type declarations used by Firmware and Host software + +// Scan type enum used in scan request +typedef enum eSirScanType +{ + eSIR_PASSIVE_SCAN, + eSIR_ACTIVE_SCAN, + eSIR_BEACON_TABLE, +} tSirScanType; + +typedef enum eSirResultCodes +{ + eSIR_SME_SUCCESS, + + eSIR_EOF_SOF_EXCEPTION, + eSIR_BMU_EXCEPTION, + eSIR_LOW_PDU_EXCEPTION, + eSIR_USER_TRIG_RESET, + eSIR_LOGP_EXCEPTION, + eSIR_CP_EXCEPTION, + eSIR_STOP_BSS, + eSIR_AHB_HANG_EXCEPTION, + eSIR_DPU_EXCEPTION, + eSIR_RPE_EXCEPTION, + eSIR_TPE_EXCEPTION, + eSIR_DXE_EXCEPTION, + eSIR_RXP_EXCEPTION, + eSIR_MCPU_EXCEPTION, + eSIR_MCU_EXCEPTION, + eSIR_MTU_EXCEPTION, + eSIR_MIF_EXCEPTION, + eSIR_FW_EXCEPTION, + eSIR_PS_MUTEX_READ_EXCEPTION, + eSIR_PHY_HANG_EXCEPTION, + eSIR_MAILBOX_SANITY_CHK_FAILED, + eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF, // Only where this switch is present + eSIR_CFB_FLAG_STUCK_EXCEPTION, + + eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS=30, + + eSIR_SME_INVALID_PARAMETERS=500, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, + eSIR_SME_RESOURCES_UNAVAILABLE, + eSIR_SME_SCAN_FAILED, // Unable to find a BssDescription + // matching requested scan criteria + eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED, + eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE, + eSIR_SME_REFUSED, + eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA, + eSIR_SME_JOIN_TIMEOUT_RESULT_CODE, + eSIR_SME_AUTH_TIMEOUT_RESULT_CODE, + eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE, + eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, + eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED, + eSIR_SME_AUTH_REFUSED, + eSIR_SME_INVALID_WEP_DEFAULT_KEY, + eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER, + eSIR_SME_ASSOC_REFUSED, + eSIR_SME_REASSOC_REFUSED, + eSIR_SME_DEAUTH_WHILE_JOIN, //Received Deauth while joining or pre-auhtentication. + eSIR_SME_DISASSOC_WHILE_JOIN, //Received Disassociation while joining. + eSIR_SME_DEAUTH_WHILE_REASSOC, //Received Deauth while ReAssociate. + eSIR_SME_DISASSOC_WHILE_REASSOC, //Received Disassociation while ReAssociate + eSIR_SME_STA_NOT_AUTHENTICATED, + eSIR_SME_STA_NOT_ASSOCIATED, + eSIR_SME_STA_DISASSOCIATED, + eSIR_SME_ALREADY_JOINED_A_BSS, + eSIR_ULA_COMPLETED, + eSIR_ULA_FAILURE, + eSIR_SME_LINK_ESTABLISHED, + eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS, + eSIR_SME_UNABLE_TO_PERFORM_DFS, + eSIR_SME_DFS_FAILED, + eSIR_SME_TRANSFER_STA, // To be used when STA need to be LB'ed + eSIR_SME_INVALID_LINK_TEST_PARAMETERS,// Given in LINK_TEST_START_RSP + eSIR_SME_LINK_TEST_MAX_EXCEEDED, // Given in LINK_TEST_START_RSP + eSIR_SME_UNSUPPORTED_RATE, // Given in LINK_TEST_RSP if peer does + // support requested rate in + // LINK_TEST_REQ + eSIR_SME_LINK_TEST_TIMEOUT, // Given in LINK_TEST_IND if peer does + // not respond before next test packet + // is sent + eSIR_SME_LINK_TEST_COMPLETE, // Given in LINK_TEST_IND at the end + // of link test + eSIR_SME_LINK_TEST_INVALID_STATE, // Given in LINK_TEST_START_RSP + eSIR_SME_LINK_TEST_TERMINATE, // Given in LINK_TEST_START_RSP + eSIR_SME_LINK_TEST_INVALID_ADDRESS, // Given in LINK_TEST_STOP_RSP + eSIR_SME_POLARIS_RESET, // Given in SME_STOP_BSS_REQ + eSIR_SME_SETCONTEXT_FAILED, // Given in SME_SETCONTEXT_REQ when + // unable to plumb down keys + eSIR_SME_BSS_RESTART, // Given in SME_STOP_BSS_REQ + + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW, // Given in SME_SCAN_RSP message + // that more SME_SCAN_RSP + // messages are following. + // SME_SCAN_RSP message with + // eSIR_SME_SUCCESS status + // code is the last one. + eSIR_SME_INVALID_ASSOC_RSP_RXED, // Sent in SME_JOIN/REASSOC_RSP + // messages upon receiving + // invalid Re/Assoc Rsp frame. + eSIR_SME_MIC_COUNTER_MEASURES, // STOP BSS triggered by MIC failures: MAC software to disassoc all stations + // with MIC_FAILURE reason code and perform the stop bss operation + eSIR_SME_ADDTS_RSP_TIMEOUT, // didn't get response from peer within + // timeout interval + eSIR_SME_ADDTS_RSP_FAILED, // didn't get success response from HAL + eSIR_SME_RECEIVED, + // TBA - TSPEC related Result Codes + + eSIR_SME_CHANNEL_SWITCH_FAIL, // failed to send out Channel Switch Action Frame + eSIR_SME_INVALID_STA_ROLE, + eSIR_SME_INVALID_STATE, +#ifdef GEN4_SCAN + eSIR_SME_CHANNEL_SWITCH_DISABLED, // either 11h is disabled or channelSwitch is currently active + eSIR_SME_HAL_SCAN_INIT_FAILED, // SIR_HAL_SIR_HAL_INIT_SCAN_RSP returned failed status + eSIR_SME_HAL_SCAN_START_FAILED, // SIR_HAL_START_SCAN_RSP returned failed status + eSIR_SME_HAL_SCAN_END_FAILED, // SIR_HAL_END_SCAN_RSP returned failed status + eSIR_SME_HAL_SCAN_FINISH_FAILED, // SIR_HAL_FINISH_SCAN_RSP returned failed status + eSIR_SME_HAL_SEND_MESSAGE_FAIL, // Failed to send a message to HAL +#else // GEN4_SCAN + eSIR_SME_CHANNEL_SWITCH_DISABLED, // either 11h is disabled or channelSwitch is currently active + eSIR_SME_HAL_SEND_MESSAGE_FAIL, // Failed to send a message to HAL +#endif // GEN4_SCAN +#ifdef FEATURE_OEM_DATA_SUPPORT + eSIR_SME_HAL_OEM_DATA_REQ_START_FAILED, +#endif + eSIR_SME_STOP_BSS_FAILURE, // Failed to stop the bss + eSIR_SME_STA_ASSOCIATED, + eSIR_SME_INVALID_PMM_STATE, + eSIR_SME_CANNOT_ENTER_IMPS, + eSIR_SME_IMPS_REQ_FAILED, + eSIR_SME_BMPS_REQ_FAILED, + eSIR_SME_BMPS_REQ_REJECT, + eSIR_SME_UAPSD_REQ_FAILED, + eSIR_SME_UAPSD_REQ_INVALID, + eSIR_SME_WOWL_ENTER_REQ_FAILED, + eSIR_SME_WOWL_EXIT_REQ_FAILED, +#if defined WLAN_FEATURE_VOWIFI_11R + eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE, + eSIR_SME_FT_REASSOC_FAILURE, +#endif + eSIR_SME_SEND_ACTION_FAIL, +#ifdef WLAN_FEATURE_PACKET_FILTERING + eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED, +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED, +#endif // WLAN_FEATURE_GTK_OFFLOAD + eSIR_SME_DEAUTH_STATUS, + eSIR_DONOT_USE_RESULT_CODE = SIR_MAX_ENUM_SIZE +} tSirResultCodes; + +/* each station added has a rate mode which specifies the sta attributes */ +typedef enum eStaRateMode { + eSTA_TAURUS = 0, + eSTA_TITAN, + eSTA_POLARIS, + eSTA_11b, + eSTA_11bg, + eSTA_11a, + eSTA_11n, +#ifdef WLAN_FEATURE_11AC + eSTA_11ac, +#endif + eSTA_INVALID_RATE_MODE +} tStaRateMode, *tpStaRateMode; + +//although in tSirSupportedRates each IE is 16bit but PE only passes IEs in 8 bits with MSB=1 for basic rates. +//change the mask for bit0-7 only so HAL gets correct basic rates for setting response rates. +#define IERATE_BASICRATE_MASK 0x80 +#define IERATE_RATE_MASK 0x7f +#define IERATE_IS_BASICRATE(x) ((x) & IERATE_BASICRATE_MASK) +#define ANIENHANCED_TAURUS_RATEMAP_BITOFFSET_START 28 + +const char * lim_BssTypetoString(const v_U8_t bssType); +const char * lim_ScanTypetoString(const v_U8_t scanType); +const char * lim_BackgroundScanModetoString(const v_U8_t mode); +typedef struct sSirSupportedRates { + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + tStaRateMode opRateMode; + // 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps + tANI_U16 llbRates[SIR_NUM_11B_RATES]; + tANI_U16 llaRates[SIR_NUM_11A_RATES]; + tANI_U16 aniLegacyRates[SIR_NUM_POLARIS_RATES]; + + //Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + //First 26 bits are reserved for those Titan rates and + //the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved. + tANI_U32 aniEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + tANI_U8 supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + tANI_U16 rxHighestDataRate; + +#ifdef WLAN_FEATURE_11AC + /*Indicates the Maximum MCS that can be received for each number + of spacial streams */ + tANI_U16 vhtRxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to receive*/ + tANI_U16 vhtRxHighestDataRate; + /*Indicates the Maximum MCS that can be transmitted for each number + of spacial streams */ + tANI_U16 vhtTxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to transmit*/ + tANI_U16 vhtTxHighestDataRate; +#endif +} tSirSupportedRates, *tpSirSupportedRates; + + +typedef enum eSirRFBand +{ + SIR_BAND_UNKNOWN, + SIR_BAND_2_4_GHZ, + SIR_BAND_5_GHZ, +} tSirRFBand; + + +/* +* Specifies which beacons are to be indicated upto the host driver when +* Station is in power save mode. +*/ +typedef enum eBeaconForwarding +{ + ePM_BEACON_FWD_NTH, + ePM_BEACON_FWD_TIM, + ePM_BEACON_FWD_DTIM, + ePM_BEACON_FWD_NONE +} tBeaconForwarding; + + +typedef struct sSirRemainOnChnReq +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr selfMacAddr; + tANI_U8 chnNum; + tANI_U8 phyMode; + tANI_U32 duration; + tANI_U8 isProbeRequestAllowed; + tANI_U8 probeRspIe[1]; +}tSirRemainOnChnReq, *tpSirRemainOnChnReq; + +/* Structure for vendor specific IE of debug marker frame + to debug remain on channel issues */ +typedef struct publicVendorSpecific +{ + tANI_U8 category; + tANI_U8 elementid; + tANI_U8 length; +} publicVendorSpecific; + +typedef struct sSirRegisterMgmtFrame +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tANI_BOOLEAN registerFrame; + tANI_U16 frameType; + tANI_U16 matchLen; + tANI_U8 matchData[1]; +}tSirRegisterMgmtFrame, *tpSirRegisterMgmtFrame; + +// +// Identifies the neighbor BSS' that was(were) detected +// by an STA and reported to the AP +// +typedef struct sAniTitanCBNeighborInfo +{ + // A BSS was found on the Primary + tANI_U8 cbBssFoundPri; + + // A BSS was found on the adjacent Upper Secondary + tANI_U8 cbBssFoundSecUp; + + // A BSS was found on the adjacent Lower Secondary + tANI_U8 cbBssFoundSecDown; + +} tAniTitanCBNeighborInfo, *tpAniTitanCBNeighborInfo; + +/// Generic type for sending a response message +/// with result code to host software +typedef struct sSirSmeRsp +{ + tANI_U16 messageType; // eWNI_SME_*_RSP + tANI_U16 length; + tANI_U8 sessionId; // To support BT-AMP + tANI_U16 transactionId; // To support BT-AMP + tSirResultCodes statusCode; +} tSirSmeRsp, *tpSirSmeRsp; + +/// Definition for kick starting Firmware on STA +typedef struct sSirSmeStartReq +{ + tANI_U16 messageType; // eWNI_SME_START_REQ + tANI_U16 length; + tANI_U8 sessionId; //Added for BT-AMP Support + tANI_U16 transcationId; //Added for BT-AMP Support + tSirMacAddr bssId; //Added For BT-AMP Support + tANI_U32 roamingAtPolaris; + tANI_U32 sendNewBssInd; +} tSirSmeStartReq, *tpSirSmeStartReq; + +/// Definition for indicating all modules ready on STA +typedef struct sSirSmeReadyReq +{ + tANI_U16 messageType; // eWNI_SME_SYS_READY_IND + tANI_U16 length; + tANI_U16 transactionId; +} tSirSmeReadyReq, *tpSirSmeReadyReq; + +/// Definition for response message to previously issued start request +typedef struct sSirSmeStartRsp +{ + tANI_U16 messageType; // eWNI_SME_START_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U16 transactionId; +} tSirSmeStartRsp, *tpSirSmeStartRsp; + + +/// Definition for Load structure +typedef struct sSirLoad +{ + tANI_U16 numStas; + tANI_U16 channelUtilization; +} tSirLoad, *tpSirLoad; + +/// BSS type enum used in while scanning/joining etc +typedef enum eSirBssType +{ + eSIR_INFRASTRUCTURE_MODE, + eSIR_INFRA_AP_MODE, //Added for softAP support + eSIR_IBSS_MODE, + eSIR_BTAMP_STA_MODE, //Added for BT-AMP support + eSIR_BTAMP_AP_MODE, //Added for BT-AMP support + eSIR_AUTO_MODE, + eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE +} tSirBssType; + +/// Definition for WDS Information +typedef struct sSirWdsInfo +{ + tANI_U16 wdsLength; + tANI_U8 wdsBytes[ANI_WDS_INFO_MAX_LENGTH]; +} tSirWdsInfo, *tpSirWdsInfo; + +/// Power Capability info used in 11H +typedef struct sSirMacPowerCapInfo +{ + tANI_U8 minTxPower; + tANI_U8 maxTxPower; +} tSirMacPowerCapInfo, *tpSirMacPowerCapInfo; + +/// Supported Channel info used in 11H +typedef struct sSirSupChnl +{ + tANI_U8 numChnl; + tANI_U8 channelList[SIR_MAX_SUPPORTED_CHANNEL_LIST]; +} tSirSupChnl, *tpSirSupChnl; + +typedef enum eSirNwType +{ + eSIR_11A_NW_TYPE, + eSIR_11B_NW_TYPE, + eSIR_11G_NW_TYPE, + eSIR_11N_NW_TYPE, +#ifdef WLAN_FEATURE_11AC + eSIR_11AC_NW_TYPE, +#endif + eSIR_DONOT_USE_NW_TYPE = SIR_MAX_ENUM_SIZE +} tSirNwType; + +/// Definition for new iBss peer info +typedef struct sSirNewIbssPeerInfo +{ + tSirMacAddr peerAddr; + tANI_U16 aid; +} tSirNewIbssPeerInfo, *tpSirNewIbssPeerInfo; + +/// Definition for Alternate BSS info +typedef struct sSirAlternateRadioInfo +{ + tSirMacAddr bssId; + tANI_U8 channelId; +} tSirAlternateRadioInfo, *tpSirAlternateRadioInfo; + +/// Definition for Alternate BSS list +typedef struct sSirAlternateRadioList +{ + tANI_U8 numBss; + tSirAlternateRadioInfo alternateRadio[1]; +} tSirAlternateRadioList, *tpSirAlternateRadioList; + +/// Definition for kick starting BSS +/// ---> MAC +/** + * Usage of ssId, numSSID & ssIdList: + * --------------------------------- + * 1. ssId.length of zero indicates that Broadcast/Suppress SSID + * feature is enabled. + * 2. If ssId.length is zero, MAC SW will advertise NULL SSID + * and interpret the SSID list from numSSID & ssIdList. + * 3. If ssId.length is non-zero, MAC SW will advertise the SSID + * specified in the ssId field and it is expected that + * application will set numSSID to one (only one SSID present + * in the list) and SSID in the list is same as ssId field. + * 4. Application will always set numSSID >= 1. + */ +//*****NOTE: Please make sure all codes are updated if inserting field into this structure..********** +typedef struct sSirSmeStartBssReq +{ + tANI_U16 messageType; // eWNI_SME_START_BSS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Added for BT-AMP Support + tANI_U16 transactionId; //Added for BT-AMP Support + tSirMacAddr bssId; //Added for BT-AMP Support + tSirMacAddr selfMacAddr; //Added for BT-AMP Support + tANI_U16 beaconInterval; //Added for BT-AMP Support + tANI_U8 dot11mode; + tSirBssType bssType; + tSirMacSSid ssId; + tANI_U8 channelId; + ePhyChanBondState cbMode; + + tANI_U8 privacy; + tANI_U8 apUapsdEnable; + tANI_U8 ssidHidden; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tANI_BOOLEAN protEnabled; + tANI_BOOLEAN obssProtEnabled; + tANI_U16 ht_capab; + tAniAuthType authType; + tANI_U32 dtimPeriod; + tANI_U8 wps_state; + tANI_U8 isCoalesingInIBSSAllowed; //Coalesing on/off knob + tVOS_CON_MODE bssPersona; + + tANI_U8 txLdpcIniFeatureEnabled; + + tSirRSNie rsnIE; // RSN IE to be sent in + // Beacon and Probe + // Response frames + tSirNwType nwType; // Indicates 11a/b/g + tSirMacRateSet operationalRateSet;// Has 11a or 11b rates + tSirMacRateSet extendedRateSet; // Has 11g rates + +#ifdef WLAN_FEATURE_11W + tANI_BOOLEAN pmfCapable; + tANI_BOOLEAN pmfRequired; +#endif + +#ifdef WLAN_FEATURE_AP_HT40_24G + tANI_BOOLEAN apHT40_24GEnabled; +#endif +} tSirSmeStartBssReq, *tpSirSmeStartBssReq; + +#define GET_IE_LEN_IN_BSS(lenInBss) ( lenInBss + sizeof(lenInBss) - \ + ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields))) + +#define WSCIE_PROBE_RSP_LEN (317 + 2) + +typedef struct sSirBssDescription +{ + //offset of the ieFields from bssId. + tANI_U16 length; + tSirMacAddr bssId; + v_TIME_t scanSysTimeMsec; + tANI_U32 timeStamp[2]; + tANI_U16 beaconInterval; + tANI_U16 capabilityInfo; + tSirNwType nwType; // Indicates 11a/b/g + tANI_U8 aniIndicator; + tANI_S8 rssi; + tANI_S8 sinr; + //channelId what peer sent in beacon/probersp. + tANI_U8 channelId; + //channelId on which we are parked at. + //used only in scan case. + tANI_U8 channelIdSelf; + tANI_U8 sSirBssDescriptionRsvd[3]; + v_TIME_t nReceivedTime; //base on a tick count. It is a time stamp, not a relative time. +#if defined WLAN_FEATURE_VOWIFI + tANI_U32 parentTSF; + tANI_U32 startTSF[2]; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 mdiePresent; + tANI_U8 mdie[SIR_MDIE_SIZE]; // MDIE for 11r, picked from the beacons +#endif +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + tANI_U8 QBSSLoad_present; + tANI_U8 QBSS_ChanLoad; + tANI_U16 QBSSLoad_avail; +#endif + + tANI_U8 fProbeRsp; //whether it is from a probe rsp + tANI_U8 reservedPadding1; + tANI_U8 reservedPadding2; + tANI_U8 reservedPadding3; + tANI_U32 WscIeLen; + tANI_U8 WscIeProbeRsp[WSCIE_PROBE_RSP_LEN]; + tANI_U8 HTCapsPresent; + tANI_U8 vhtCapsPresent; + tANI_U8 wmeInfoPresent; + tANI_U8 beacomformingCapable; + tANI_U8 chanWidth; + /* Please keep the structure 4 bytes aligned above the ieFields */ + tANI_U32 ieFields[1]; + +} tSirBssDescription, *tpSirBssDescription; + +/// Definition for response message to previously +/// issued start BSS request +/// MAC ---> +typedef struct sSirSmeStartBssRsp +{ + tANI_U16 messageType; // eWNI_SME_START_BSS_RSP + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 transactionId;//transaction ID for cmd + tSirResultCodes statusCode; + tSirBssType bssType;//Add new type for WDS mode + tANI_U16 beaconInterval;//Beacon Interval for both type + tANI_U32 staId;//Staion ID for Self + tSirBssDescription bssDescription;//Peer BSS description +} tSirSmeStartBssRsp, *tpSirSmeStartBssRsp; + +#ifdef WLAN_FEATURE_APFIND +struct hal_apfind_request +{ + tANI_U16 request_data_len; + tANI_U8 request_data[]; +}; +#endif + +typedef struct sSirChannelList +{ + tANI_U8 numChannels; + tANI_U8 channelNumber[SIR_ESE_MAX_MEAS_IE_REQS]; +} tSirChannelList, *tpSirChannelList; + +typedef struct sSirDFSChannelList +{ + v_TIME_t timeStamp[SIR_MAX_24G_5G_CHANNEL_RANGE]; + +} tSirDFSChannelList, *tpSirDFSChannelList; + +#ifdef FEATURE_WLAN_ESE +typedef struct sTspecInfo { + tANI_U8 valid; + tSirMacTspecIE tspec; +} tTspecInfo; + +#define SIR_ESE_MAX_TSPEC_IES 4 +typedef struct sESETspecTspecInfo { + tANI_U8 numTspecs; + tTspecInfo tspec[SIR_ESE_MAX_TSPEC_IES]; +} tESETspecInfo; +#endif + + +/// Definition for Radar Info +typedef struct sSirRadarInfo +{ + tANI_U8 channelNumber; + tANI_U16 radarPulseWidth; // in usecond + tANI_U16 numRadarPulse; +} tSirRadarInfo, *tpSirRadarInfo; + +#define SIR_RADAR_INFO_SIZE (sizeof(tANI_U8) + 2 *sizeof(tANI_U16)) + +/// Two Background Scan mode +typedef enum eSirBackgroundScanMode +{ + eSIR_AGGRESSIVE_BACKGROUND_SCAN = 0, + eSIR_NORMAL_BACKGROUND_SCAN = 1, + eSIR_ROAMING_SCAN = 2, +} tSirBackgroundScanMode; +typedef enum eSirLinkTrafficCheck +{ + eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN = 0, + eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN = 1, + eSIR_CHECK_ROAMING_SCAN = 2, +} tSirLinkTrafficCheck; + +#define SIR_BG_SCAN_RETURN_CACHED_RESULTS 0x0 +#define SIR_BG_SCAN_PURGE_RESUTLS 0x80 +#define SIR_BG_SCAN_RETURN_FRESH_RESULTS 0x01 +#define SIR_SCAN_MAX_NUM_SSID 0x09 +#define SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS 0x02 +#define SIR_BG_SCAN_PURGE_LFR_RESULTS 0x40 + +/// Definition for scan request +typedef struct sSirSmeScanReq +{ + tANI_U16 messageType; // eWNI_SME_SCAN_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; + tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID]; + tSirMacAddr selfMacAddr; //Added For BT-AMP Support + tSirBssType bssType; + tANI_U8 dot11mode; + tSirScanType scanType; + /** + * minChannelTime. Not used if scanType is passive. + * 0x0 - Dont Use min channel timer. Only max channel timeout will used. + * 11k measurements set this to zero to user only single duration for scan. + * - Timeout value used for min channel timeout. + */ + tANI_U32 minChannelTime; + /** + * maxChannelTime. + * 0x0 - Invalid. In case of active scan. + * In case of passive scan, MAX( maxChannelTime, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME) is used. + * + */ + tANI_U32 maxChannelTime; + /** + * returnAfterFirstMatch can take following values: + * 0x00 - Return SCAN_RSP message after complete channel scan + * 0x01 - Return SCAN_RSP message after collecting BSS description + * that matches scan criteria. + * 0xC0 - Return after collecting first 11d IE from 2.4 GHz & + * 5 GHz band channels + * 0x80 - Return after collecting first 11d IE from 5 GHz band + * channels + * 0x40 - Return after collecting first 11d IE from 2.4 GHz + * band channels + * + * Values of 0xC0, 0x80 & 0x40 are to be used by + * Roaming/application when 11d is enabled. + */ + tANI_U32 min_chntime_btc_esco; //in units of milliseconds + tANI_U32 max_chntime_btc_esco; //in units of milliseconds + tANI_U8 returnAfterFirstMatch; + + /** + * returnUniqueResults can take following values: + * 0 - Collect & report all received BSS descriptions from same BSS. + * 1 - Collect & report unique BSS description from same BSS. + */ + tANI_U8 returnUniqueResults; + + /** + * returnFreshResults can take following values: + * 0x00 - Return background scan results. + * 0x80 - Return & purge background scan results + * 0x01 - Trigger fresh scan instead of returning background scan + * results. + * 0x81 - Trigger fresh scan instead of returning background scan + * results and purge background scan results. + */ + tANI_U8 returnFreshResults; + + /* backgroundScanMode can take following values: + * 0x0 - agressive scan + * 0x1 - normal scan where HAL will check for link traffic + * prior to proceeding with the scan + */ + tSirBackgroundScanMode backgroundScanMode; + + tANI_U8 hiddenSsid; + + /* Number of SSIDs to scan */ + tANI_U8 numSsid; + + //channelList has to be the last member of this structure. Check tSirChannelList for the reason. + /* This MUST be the last field of the structure */ + + + tANI_BOOLEAN p2pSearch; + tANI_U16 uIEFieldLen; + tANI_U16 uIEFieldOffset; + + //channelList MUST be the last field of this structure + tSirChannelList channelList; + /*----------------------------- + tSirSmeScanReq.... + ----------------------------- + uIEFiledLen + ----------------------------- + uIEFiledOffset ----+ + ----------------------------- | + channelList.numChannels | + ----------------------------- | + ... variable size up to | + channelNumber[numChannels-1] | + This can be zero, if | + numChannel is zero. | + ----------------------------- <--+ + ... variable size uIEFiled + up to uIEFieldLen (can be 0) + -----------------------------*/ +} tSirSmeScanReq, *tpSirSmeScanReq; + +typedef struct sSirSmeScanAbortReq +{ + tANI_U16 type; + tANI_U16 msgLen; + tANI_U8 sessionId; +} tSirSmeScanAbortReq, *tpSirSmeScanAbortReq; + +typedef struct sSirSmeScanChanReq +{ + tANI_U16 type; + tANI_U16 msgLen; + tANI_U8 sessionId; + tANI_U16 transcationId; +} tSirSmeGetScanChanReq, *tpSirSmeGetScanChanReq; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +typedef struct sSirOemDataReq +{ + tANI_U16 messageType; //eWNI_SME_OEM_DATA_REQ + tANI_U16 messageLen; + tSirMacAddr selfMacAddr; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tSirOemDataReq, *tpSirOemDataReq; + +typedef struct sSirOemDataRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tSirOemDataRsp, *tpSirOemDataRsp; + +#endif //FEATURE_OEM_DATA_SUPPORT + +/// Definition for response message to previously issued scan request +typedef struct sSirSmeScanRsp +{ + tANI_U16 messageType; // eWNI_SME_SCAN_RSP + tANI_U16 length; + tANI_U8 sessionId; + tSirResultCodes statusCode; + tANI_U16 transcationId; + tSirBssDescription bssDescription[1]; +} tSirSmeScanRsp, *tpSirSmeScanRsp; + +/// Sme Req message to set the Background Scan mode +typedef struct sSirSmeBackgroundScanModeReq +{ + tANI_U16 messageType; // eWNI_SME_BACKGROUND_SCAN_MODE_REQ + tANI_U16 length; + tSirBackgroundScanMode mode; +} tSirSmeBackgroundScanModeReq, *tpSirSmeBackgroundScanModeReq; + +/// Background Scan Statisics +typedef struct sSirBackgroundScanInfo { + tANI_U32 numOfScanSuccess; + tANI_U32 numOfScanFailure; + tANI_U32 reserved; +} tSirBackgroundScanInfo, *tpSirBackgroundScanInfo; + +#define SIR_BACKGROUND_SCAN_INFO_SIZE (3 * sizeof(tANI_U32)) + +/// Definition for Authentication request +typedef struct sSirSmeAuthReq +{ + tANI_U16 messageType; // eWNI_SME_AUTH_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tANI_U8 channelNumber; +} tSirSmeAuthReq, *tpSirSmeAuthReq; + +/// Definition for reponse message to previously issued Auth request +typedef struct sSirSmeAuthRsp +{ + tANI_U16 messageType; // eWNI_SME_AUTH_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tSirResultCodes statusCode; + tANI_U16 protStatusCode; //It holds reasonCode when Pre-Auth fails due to deauth frame. + //Otherwise it holds status code. +} tSirSmeAuthRsp, *tpSirSmeAuthRsp; + + + +/// Definition for Join/Reassoc info - Reshmi: need to check if this is a def which moved from elsehwere. +typedef struct sJoinReassocInfo +{ + tAniTitanCBNeighborInfo cbNeighbors; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; +} tJoinReassocInfo, *tpJoinReassocInfo; + +/// Definition for join request +/// ---> MAC +/// WARNING! If you add a field in JOIN REQ. +/// Make sure to add it in REASSOC REQ +/// The Serdes function is the same and its +/// shared with REASSOC. So if we add a field +// here and dont add it in REASSOC REQ. It will BREAK!!! REASSOC. +typedef struct sSirSmeJoinReq +{ + tANI_U16 messageType; // eWNI_SME_JOIN_REQ + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 transactionId; + tSirMacSSid ssId; + tSirMacAddr selfMacAddr; // self Mac address + tSirBssType bsstype; // add new type for BT -AMP STA and AP Modules + tANI_U8 dot11mode; // to support BT-AMP + tVOS_CON_MODE staPersona; //Persona + tANI_BOOLEAN bOSENAssociation; //HS2.0 + tANI_BOOLEAN bWPSAssociation; //WPS + ePhyChanBondState cbMode; // Pass CB mode value in Join. + + /*This contains the UAPSD Flag for all 4 AC + * B0: AC_VO UAPSD FLAG + * B1: AC_VI UAPSD FLAG + * B2: AC_BK UAPSD FLAG + * B3: AC_BE UASPD FLAG + */ + tANI_U8 uapsdPerAcBitmask; + + tSirMacRateSet operationalRateSet;// Has 11a or 11b rates + tSirMacRateSet extendedRateSet; // Has 11g rates + tANI_U16 rateBitMap; + tSirRSNie rsnIE; // RSN IE to be sent in + // (Re) Association Request +#ifdef FEATURE_WLAN_ESE + tSirCCKMie cckmIE; // CCMK IE to be included as handler for join and reassoc is + // the same. The join will never carry cckm, but will be set to + // 0. +#endif + + tSirAddie addIEScan; // Additional IE to be sent in + // (unicast) Probe Request at the time of join + + tSirAddie addIEAssoc; // Additional IE to be sent in + // (Re) Association Request + + tAniEdType UCEncryptionType; + + tAniEdType MCEncryptionType; + +#ifdef WLAN_FEATURE_11W + tAniEdType MgmtEncryptionType; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + tAniBool is11Rconnection; +#endif +#ifdef FEATURE_WLAN_ESE + tAniBool isESEFeatureIniEnabled; + tAniBool isESEconnection; + tESETspecInfo eseTspecInfo; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + tAniBool isFastTransitionEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + tAniBool isFastRoamIniFeatureEnabled; +#endif + + tANI_U8 txLdpcIniFeatureEnabled; +#ifdef WLAN_FEATURE_11AC + tANI_U8 txBFIniFeatureEnabled; + tANI_U8 txBFCsnValue; + tANI_U8 txMuBformee; +#endif + tANI_U8 isAmsduSupportInAMPDU; + tAniBool isWMEenabled; + tAniBool isQosEnabled; + tAniTitanCBNeighborInfo cbNeighbors; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + bool force_24ghz_in_ht20; + tSirBssDescription bssDescription; + +} tSirSmeJoinReq, *tpSirSmeJoinReq; + +/// Definition for reponse message to previously issued join request +/// MAC ---> +typedef struct sSirSmeJoinRsp +{ + tANI_U16 messageType; // eWNI_SME_JOIN_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tAniAuthType authType; + tANI_U16 protStatusCode; //It holds reasonCode when join fails due to deauth/disassoc frame. + //Otherwise it holds status code. + tANI_U16 aid; + tANI_U32 beaconLength; + tANI_U32 assocReqLength; + tANI_U32 assocRspLength; +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U32 parsedRicRspLen; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U32 tspecIeLen; +#endif + tANI_U32 staId;//Station ID for peer + + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU signature*/ + tANI_U8 ucastSig; + + /*Broadcast DPU signature*/ + tANI_U8 bcastSig; + + /*to report MAX link-speed populate rate-flags from ASSOC RSP frame*/ + tANI_U32 maxRateFlags; + + tDot11fIEHTCaps ht_caps; + tDot11fIEVHTCaps vht_caps; + tDot11fIEHTInfo ht_operation; + tDot11fIEVHTOperation vht_operation; + tDot11fIEhs20vendor_ie hs20vendor_ie; + + tANI_U8 frames[ 1 ]; +} tSirSmeJoinRsp, *tpSirSmeJoinRsp; + +/// Definition for Authentication indication from peer +typedef struct sSirSmeAuthInd +{ + tANI_U16 messageType; // eWNI_SME_AUTH_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tAniAuthType authType; +} tSirSmeAuthInd, *tpSirSmeAuthInd; + +/// probereq from peer, when wsc is enabled +typedef struct sSirSmeProbereq +{ + tANI_U16 messageType; // eWNI_SME_PROBE_REQ + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr peerMacAddr; + tANI_U16 devicePasswdId; +} tSirSmeProbeReq, *tpSirSmeProbeReq; + +/// Definition for Association indication from peer +/// MAC ---> +typedef struct sSirSmeAssocInd +{ + tANI_U16 messageType; // eWNI_SME_ASSOC_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr bssId; // Self BSSID + tANI_U16 staId; // Station ID for peer + tANI_U8 uniSig; // DPU signature for unicast packets + tANI_U8 bcastSig; // DPU signature for broadcast packets + tAniAuthType authType; + tAniSSID ssId; // SSID used by STA to associate + tSirRSNie rsnIE;// RSN IE received from peer + tSirAddie addIE;// Additional IE received from peer, which possibly include WSC IE and/or P2P IE + + // powerCap & supportedChannels are present only when + // spectrumMgtIndicator flag is set + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + tAniBool wmmEnabledSta; /* if present - STA is WMM enabled */ +#ifdef WLAN_FEATURE_AP_HT40_24G + tAniBool HT40MHzIntoEnabledSta; /* if present - STA Enable 40 MHz Intolerant */ +#endif + tAniBool reassocReq; + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + uint32_t rate_flags; +} tSirSmeAssocInd, *tpSirSmeAssocInd; + + +/// Definition for Association confirm +/// ---> MAC +typedef struct sSirSmeAssocCnf +{ + tANI_U16 messageType; // eWNI_SME_ASSOC_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr alternateBssId; + tANI_U8 alternateChannelId; +} tSirSmeAssocCnf, *tpSirSmeAssocCnf; + +/// Definition for Reassociation indication from peer +typedef struct sSirSmeReassocInd +{ + tANI_U16 messageType; // eWNI_SME_REASSOC_IND + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirMacAddr peerMacAddr; + tSirMacAddr oldMacAddr; + tANI_U16 aid; + tSirMacAddr bssId; // Self BSSID + tANI_U16 staId; // Station ID for peer + tAniAuthType authType; + tAniSSID ssId; // SSID used by STA to reassociate + tSirRSNie rsnIE; // RSN IE received from peer + + tSirAddie addIE; // Additional IE received from peer + + // powerCap & supportedChannels are present only when + // spectrumMgtIndicator flag is set + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + // Required for indicating the frames to upper layer + // TODO: use the appropriate names to distinguish between the other similar names used above for station mode of operation + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; +} tSirSmeReassocInd, *tpSirSmeReassocInd; + +/// Definition for Reassociation confirm +/// ---> MAC +typedef struct sSirSmeReassocCnf +{ + tANI_U16 messageType; // eWNI_SME_REASSOC_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr alternateBssId; + tANI_U8 alternateChannelId; +} tSirSmeReassocCnf, *tpSirSmeReassocCnf; + + +/// Enum definition for Wireless medium status change codes +typedef enum eSirSmeStatusChangeCode +{ + eSIR_SME_DEAUTH_FROM_PEER, + eSIR_SME_DISASSOC_FROM_PEER, + eSIR_SME_LOST_LINK_WITH_PEER, + eSIR_SME_CHANNEL_SWITCH, + eSIR_SME_JOINED_NEW_BSS, + eSIR_SME_LEAVING_BSS, + eSIR_SME_IBSS_ACTIVE, + eSIR_SME_IBSS_INACTIVE, + eSIR_SME_IBSS_PEER_DEPARTED, + eSIR_SME_RADAR_DETECTED, + eSIR_SME_IBSS_NEW_PEER, + eSIR_SME_AP_CAPS_CHANGED, + eSIR_SME_BACKGROUND_SCAN_FAIL, + eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP, + eSIR_SME_CB_LEGACY_BSS_FOUND_BY_STA +} tSirSmeStatusChangeCode; + +typedef struct sSirSmeNewBssInfo +{ + tSirMacAddr bssId; + tANI_U8 channelNumber; + tANI_U8 reserved; + tSirMacSSid ssId; +} tSirSmeNewBssInfo, *tpSirSmeNewBssInfo; + +typedef struct sSirSmeApNewCaps +{ + tANI_U16 capabilityInfo; + tSirMacAddr bssId; + tANI_U8 channelId; + tANI_U8 reserved[3]; + tSirMacSSid ssId; +} tSirSmeApNewCaps, *tpSirSmeApNewCaps; + +/** + * Table below indicates what information is passed for each of + * the Wireless Media status change notifications: + * + * Status Change code Status change info + * ---------------------------------------------------------------------- + * eSIR_SME_DEAUTH_FROM_PEER Reason code received in DEAUTH frame + * eSIR_SME_DISASSOC_FROM_PEER Reason code received in DISASSOC frame + * eSIR_SME_LOST_LINK_WITH_PEER None + * eSIR_SME_CHANNEL_SWITCH New channel number + * eSIR_SME_JOINED_NEW_BSS BSSID, SSID and channel number + * eSIR_SME_LEAVING_BSS None + * eSIR_SME_IBSS_ACTIVE Indicates that another STA joined + * IBSS apart from this STA that + * started IBSS + * eSIR_SME_IBSS_INACTIVE Indicates that only this STA is left + * in IBSS + * eSIR_SME_RADAR_DETECTED Indicates that radar is detected + * eSIR_SME_IBSS_NEW_PEER Indicates that a new peer is detected + * eSIR_SME_AP_CAPS_CHANGED Indicates that capabilities of the AP + * that STA is currently associated with + * have changed. + * eSIR_SME_BACKGROUND_SCAN_FAIL Indicates background scan failure + */ + +/// Definition for Wireless medium status change notification +typedef struct sSirSmeWmStatusChangeNtf +{ + tANI_U16 messageType; // eWNI_SME_WM_STATUS_CHANGE_NTF + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirSmeStatusChangeCode statusChangeCode; + tSirMacAddr bssId; // Self BSSID + union + { + tANI_U16 deAuthReasonCode; // eSIR_SME_DEAUTH_FROM_PEER + tANI_U16 disassocReasonCode; // eSIR_SME_DISASSOC_FROM_PEER + // none for eSIR_SME_LOST_LINK_WITH_PEER + tANI_U8 newChannelId; // eSIR_SME_CHANNEL_SWITCH + tSirSmeNewBssInfo newBssInfo; // eSIR_SME_JOINED_NEW_BSS + // none for eSIR_SME_LEAVING_BSS + // none for eSIR_SME_IBSS_ACTIVE + // none for eSIR_SME_IBSS_INACTIVE + tSirNewIbssPeerInfo newIbssPeerInfo; // eSIR_SME_IBSS_NEW_PEER + tSirSmeApNewCaps apNewCaps; // eSIR_SME_AP_CAPS_CHANGED + tSirBackgroundScanInfo bkgndScanInfo; // eSIR_SME_BACKGROUND_SCAN_FAIL + tAniTitanCBNeighborInfo cbNeighbors; // eSIR_SME_CB_LEGACY_BSS_FOUND_BY_STA + } statusChangeInfo; +} tSirSmeWmStatusChangeNtf, *tpSirSmeWmStatusChangeNtf; + +/// Definition for Disassociation request +typedef +__ani_attr_pre_packed +struct sSirSmeDisassocReq +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // Peer BSSID + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U8 doNotSendOverTheAir; //This flag tells LIM whether to send the disassoc OTA or not + //This will be set in while handing off from one AP to other +} +__ani_attr_packed +tSirSmeDisassocReq, *tpSirSmeDisassocReq; + +/// Definition for Tkip countermeasures request +typedef __ani_attr_pre_packed struct sSirSmeTkipCntrMeasReq +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // Peer BSSID + tANI_BOOLEAN bEnable; // Start/stop countermeasures +} __ani_attr_packed tSirSmeTkipCntrMeasReq, *tpSirSmeTkipCntrMeasReq; + +typedef struct sAni64BitCounters +{ + tANI_U32 Hi; + tANI_U32 Lo; +}tAni64BitCounters, *tpAni64BitCounters; + +typedef struct sAniSecurityStat +{ + tAni64BitCounters txBlks; + tAni64BitCounters rxBlks; + tAni64BitCounters formatErrorCnt; + tAni64BitCounters decryptErr; + tAni64BitCounters protExclCnt; + tAni64BitCounters unDecryptableCnt; + tAni64BitCounters decryptOkCnt; + +}tAniSecurityStat, *tpAniSecurityStat; + +typedef struct sAniTxRxCounters +{ + tANI_U32 txFrames; // Incremented for every packet tx + tANI_U32 rxFrames; + tANI_U32 nRcvBytes; + tANI_U32 nXmitBytes; +}tAniTxRxCounters, *tpAniTxRxCounters; + +typedef struct sAniTxRxStats +{ + tAni64BitCounters txFrames; + tAni64BitCounters rxFrames; + tAni64BitCounters nRcvBytes; + tAni64BitCounters nXmitBytes; + +}tAniTxRxStats,*tpAniTxRxStats; + +typedef struct sAniSecStats +{ + tAniSecurityStat aes; + tAni64BitCounters aesReplays; + tAniSecurityStat tkip; + tAni64BitCounters tkipReplays; + tAni64BitCounters tkipMicError; + + tAniSecurityStat wep; +#if defined(FEATURE_WLAN_WAPI) && !defined(LIBRA_WAPI_SUPPORT) + tAniSecurityStat wpi; + tAni64BitCounters wpiReplays; + tAni64BitCounters wpiMicError; +#endif +}tAniSecStats, *tpAniSecStats; + +#define SIR_MAX_RX_CHAINS 3 + +typedef struct sAniStaStatStruct +{ + /* following statistic elements till expandPktRxCntLo are not filled with valid data. + * These are kept as it is, since WSM is using this structure. + * These elements can be removed whenever WSM is updated. + * Phystats is used to hold phystats from BD. + */ + tANI_U32 sentAesBlksUcastHi; + tANI_U32 sentAesBlksUcastLo; + tANI_U32 recvAesBlksUcastHi; + tANI_U32 recvAesBlksUcastLo; + tANI_U32 aesFormatErrorUcastCnts; + tANI_U32 aesReplaysUcast; + tANI_U32 aesDecryptErrUcast; + tANI_U32 singleRetryPkts; + tANI_U32 failedTxPkts; + tANI_U32 ackTimeouts; + tANI_U32 multiRetryPkts; + tANI_U32 fragTxCntsHi; + tANI_U32 fragTxCntsLo; + tANI_U32 transmittedPktsHi; + tANI_U32 transmittedPktsLo; + tANI_U32 phyStatHi; //These are used to fill in the phystats. + tANI_U32 phyStatLo; //This is only for private use. + + tANI_U32 uplinkRssi; + tANI_U32 uplinkSinr; + tANI_U32 uplinkRate; + tANI_U32 downlinkRssi; + tANI_U32 downlinkSinr; + tANI_U32 downlinkRate; + tANI_U32 nRcvBytes; + tANI_U32 nXmitBytes; + + // titan 3c stats + tANI_U32 chunksTxCntHi; // Number of Chunks Transmitted + tANI_U32 chunksTxCntLo; + tANI_U32 compPktRxCntHi; // Number of Packets Received that were actually compressed + tANI_U32 compPktRxCntLo; + tANI_U32 expanPktRxCntHi; // Number of Packets Received that got expanded + tANI_U32 expanPktRxCntLo; + + + /* Following elements are valid and filled in correctly. They have valid values. + */ + + //Unicast frames and bytes. + tAniTxRxStats ucStats; + + //Broadcast frames and bytes. + tAniTxRxStats bcStats; + + //Multicast frames and bytes. + tAniTxRxStats mcStats; + + tANI_U32 currentTxRate; + tANI_U32 currentRxRate; //Rate in 100Kbps + + tANI_U32 maxTxRate; + tANI_U32 maxRxRate; + + tANI_S8 rssi[SIR_MAX_RX_CHAINS]; + + + tAniSecStats securityStats; + + tANI_U8 currentRxRateIdx; //This the softmac rate Index. + tANI_U8 currentTxRateIdx; + +} tAniStaStatStruct, *tpAniStaStatStruct; + +//Statistics that are not maintained per stations. +typedef struct sAniGlobalStatStruct +{ + tAni64BitCounters txError; + tAni64BitCounters rxError; + tAni64BitCounters rxDropNoBuffer; + tAni64BitCounters rxDropDup; + tAni64BitCounters rxCRCError; + + tAni64BitCounters singleRetryPkts; + tAni64BitCounters failedTxPkts; + tAni64BitCounters ackTimeouts; + tAni64BitCounters multiRetryPkts; + tAni64BitCounters fragTxCnts; + tAni64BitCounters fragRxCnts; + + tAni64BitCounters txRTSSuccess; + tAni64BitCounters txCTSSuccess; + tAni64BitCounters rxRTSSuccess; + tAni64BitCounters rxCTSSuccess; + + tAniSecStats securityStats; + + tAniTxRxStats mcStats; + tAniTxRxStats bcStats; + +}tAniGlobalStatStruct,*tpAniGlobalStatStruct; + +typedef enum sPacketType +{ + ePACKET_TYPE_UNKNOWN, + ePACKET_TYPE_11A, + ePACKET_TYPE_11G, + ePACKET_TYPE_11B, + ePACKET_TYPE_11N + +}tPacketType, *tpPacketType; + +typedef struct sAniStatSummaryStruct +{ + tAniTxRxStats uc; //Unicast counters. + tAniTxRxStats bc; //Broadcast counters. + tAniTxRxStats mc; //Multicast counters. + tAni64BitCounters txError; + tAni64BitCounters rxError; + tANI_S8 rssi[SIR_MAX_RX_CHAINS]; //For each chain. + tANI_U32 rxRate; // Rx rate of the last received packet. + tANI_U32 txRate; + tANI_U16 rxMCSId; //MCS index is valid only when packet type is ePACKET_TYPE_11N + tANI_U16 txMCSId; + tPacketType rxPacketType; + tPacketType txPacketType; + tSirMacAddr macAddr; //Mac Address of the station from which above RSSI and rate is from. +}tAniStatSummaryStruct,*tpAniStatSummaryStruct; + +//structure for stats that may be reset, like the ones in sta descriptor +//The stats are saved into here before reset. It should be tANI_U32 aligned. +typedef struct _sPermStaStats +{ + //tANI_U32 sentAesBlksUcastHi; + //tANI_U32 sentAesBlksUcastLo; + //tANI_U32 recvAesBlksUcastHi; + //tANI_U32 recvAesBlksUcastLo; + tANI_U32 aesFormatErrorUcastCnts; + tANI_U32 aesReplaysUcast; + tANI_U32 aesDecryptErrUcast; + tANI_U32 singleRetryPkts; + tANI_U32 failedTxPkts; + tANI_U32 ackTimeouts; + tANI_U32 multiRetryPkts; + tANI_U32 fragTxCntsHi; + tANI_U32 fragTxCntsLo; + tANI_U32 transmittedPktsHi; + tANI_U32 transmittedPktsLo; + + // titan 3c stats + tANI_U32 chunksTxCntHi; // Number of Chunks Transmitted + tANI_U32 chunksTxCntLo; + tANI_U32 compPktRxCntHi; // Number of Packets Received that were actually compressed + tANI_U32 compPktRxCntLo; + tANI_U32 expanPktRxCntHi; // Number of Packets Received that got expanded + tANI_U32 expanPktRxCntLo; +}tPermanentStaStats; + + + + +/// Definition for Disassociation response +typedef struct sSirSmeDisassocRsp +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; + tAniStaStatStruct perStaStats; // STA stats + tANI_U16 staId; +} +__ani_attr_packed + tSirSmeDisassocRsp, *tpSirSmeDisassocRsp; + +/// Definition for Disassociation indication from peer +typedef struct sSirSmeDisassocInd +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_IND + tANI_U16 length; + tANI_U8 sessionId; // Session Identifier + tANI_U16 transactionId; // Transaction Identifier with PE + tSirResultCodes statusCode; + tSirMacAddr bssId; + tSirMacAddr peerMacAddr; + tAniStaStatStruct perStaStats; // STA stats + tANI_U16 staId; + tANI_U16 assocId; + tANI_U32 reasonCode; +} tSirSmeDisassocInd, *tpSirSmeDisassocInd; + +/// Definition for Disassociation confirm +/// MAC ---> +typedef struct sSirSmeDisassocCnf +{ + tANI_U16 messageType; // eWNI_SME_DISASSOC_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; + tSirMacAddr peerMacAddr; + tANI_U16 assocId; +} tSirSmeDisassocCnf, *tpSirSmeDisassocCnf; + +/// Definition for Deauthetication request +typedef struct sSirSmeDeauthReq +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // AP BSSID + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; +} tSirSmeDeauthReq, *tpSirSmeDeauthReq; + +/// Definition for Deauthetication response +typedef struct sSirSmeDeauthRsp +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirSmeDeauthRsp, *tpSirSmeDeauthRsp; + +/// Definition for Deauthetication indication from peer +typedef struct sSirSmeDeauthInd +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_IND + tANI_U16 length; + tANI_U8 sessionId; //Added for BT-AMP + tANI_U16 transactionId; //Added for BT-AMP + tSirResultCodes statusCode; + tSirMacAddr bssId;// AP BSSID + tSirMacAddr peerMacAddr; + + tANI_U16 staId; + tANI_U16 assocId; + tANI_U32 reasonCode; +} tSirSmeDeauthInd, *tpSirSmeDeauthInd; + +/// Definition for Deauthentication confirm +/// MAC ---> +typedef struct sSirSmeDeauthCnf +{ + tANI_U16 messageType; // eWNI_SME_DEAUTH_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr bssId; // AP BSSID + tSirMacAddr peerMacAddr; + tANI_U16 assocId; +} tSirSmeDeauthCnf, *tpSirSmeDeauthCnf; + +typedef struct sSirSmeDisConDoneInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tSirResultCodes reasonCode; + tSirMacAddr peerMacAddr; +}tSirSmeDisConDoneInd, *tpSirSmeDisConDoneInd; + +/// Definition for stop BSS request message +typedef struct sSirSmeStopBssReq +{ + tANI_U16 messageType; // eWNI_SME_STOP_BSS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; //tranSaction ID for cmd + tSirResultCodes reasonCode; + tSirMacAddr bssId; //Self BSSID +} tSirSmeStopBssReq, *tpSirSmeStopBssReq; + +/// Definition for stop BSS response message +typedef struct sSirSmeStopBssRsp +{ + tANI_U16 messageType; // eWNI_SME_STOP_BSS_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd +} tSirSmeStopBssRsp, *tpSirSmeStopBssRsp; + + + +/// Definition for Channel Switch indication for station +/// MAC ---> +typedef struct sSirSmeSwitchChannelInd +{ + tANI_U16 messageType; // eWNI_SME_SWITCH_CHL_REQ + tANI_U16 length; + tANI_U8 sessionId; + tANI_U16 newChannelId; + tSirMacAddr bssId; // BSSID +} tSirSmeSwitchChannelInd, *tpSirSmeSwitchChannelInd; + +/// Definition for ULA complete indication message +typedef struct sirUlaCompleteInd +{ + tANI_U16 messageType; // eWNI_ULA_COMPLETE_IND + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirUlaCompleteInd, *tpSirUlaCompleteInd; + +/// Definition for ULA complete confirmation message +typedef struct sirUlaCompleteCnf +{ + tANI_U16 messageType; // eWNI_ULA_COMPLETE_CNF + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirUlaCompleteCnf, *tpSirUlaCompleteCnf; + +/// Definition for Neighbor BSS indication +/// MAC ---> +/// MAC reports this each time a new I/BSS is detected +typedef struct sSirSmeNeighborBssInd +{ + tANI_U16 messageType; // eWNI_SME_NEIGHBOR_BSS_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirBssDescription bssDescription[1]; +} tSirSmeNeighborBssInd, *tpSirSmeNeighborBssInd; + +/// Definition for MIC failure indication +/// MAC ---> +/// MAC reports this each time a MIC failure occures on Rx TKIP packet +typedef struct sSirSmeMicFailureInd +{ + tANI_U16 messageType; // eWNI_SME_MIC_FAILURE_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr bssId; // BSSID + tSirMicFailureInfo info; +} tSirSmeMicFailureInd, *tpSirSmeMicFailureInd; + +typedef struct sSirSmeLostLinkParamsInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tSirLostLinkParamsInfo info; +} tSirSmeLostLinkParamsInd, *tpSirSmeLostLinkParamsInd; + + +typedef struct sSirSmeMissedBeaconInd +{ + tANI_U16 messageType; // eWNI_SME_MISSED_BEACON_IND + tANI_U16 length; + tANI_U8 bssIdx; +} tSirSmeMissedBeaconInd, *tpSirSmeMissedBeaconInd; + +/// Definition for Set Context request +/// ---> MAC +typedef struct sSirSmeSetContextReq +{ + tANI_U16 messageType; // eWNI_SME_SET_CONTEXT_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; //Transaction ID for cmd + tSirMacAddr peerMacAddr; + tSirMacAddr bssId; // BSSID + // TBD Following QOS fields to be uncommented + //tAniBool qosInfoPresent; + //tSirQos qos; + tSirKeyMaterial keyMaterial; +} tSirSmeSetContextReq, *tpSirSmeSetContextReq; + +/// Definition for Set Context response +/// MAC ---> +typedef struct sSirSmeSetContextRsp +{ + tANI_U16 messageType; // eWNI_SME_SET_CONTEXT_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirSmeSetContextRsp, *tpSirSmeSetContextRsp; + +/// Definition for Remove Key Context request +/// ---> MAC +typedef struct sSirSmeRemoveKeyReq +{ + tANI_U16 messageType; // eWNI_SME_REMOVE_KEY_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssId; // BSSID + tSirMacAddr peerMacAddr; + tANI_U8 edType; + tANI_U8 wepType; + tANI_U8 keyId; + tANI_BOOLEAN unicast; +} tSirSmeRemoveKeyReq, *tpSirSmeRemoveKeyReq; + +/// Definition for Remove Key Context response +/// MAC ---> +typedef struct sSirSmeRemoveKeyRsp +{ + tANI_U16 messageType; // eWNI_SME_REMOVE_KEY_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMacAddr; +} tSirSmeRemoveKeyRsp, *tpSirSmeRemoveKeyRsp; + +/// Definition for Set Power request +/// ---> MAC +typedef struct sSirSmeSetPowerReq +{ + tANI_U16 messageType; // eWNI_SME_SET_POWER_REQ + tANI_U16 length; + tANI_U16 transactionId; // Transaction ID for cmd + tANI_S8 powerLevel; +} tSirSmeSetPowerReq, *tpSirSmeSetPowerReq; + +/// Definition for Set Power response +/// MAC ---> +typedef struct sSirSmeSetPowerRsp +{ + tANI_U16 messageType; // eWNI_SME_SET_POWER_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U16 transactionId; // Transaction ID for cmd +} tSirSmeSetPowerRsp, *tpSirSmeSetPowerRsp; + + +/// Definition for Link Test Start response +/// MAC ---> +typedef struct sSirSmeLinkTestStartRsp +{ + tANI_U16 messageType; // eWNI_SME_LINK_TEST_START_RSP + tANI_U16 length; + tSirMacAddr peerMacAddr; + tSirResultCodes statusCode; +} tSirSmeLinkTestStartRsp, *tpSirSmeLinkTestStartRsp; + +/// Definition for Link Test Stop response +/// WSM ---> MAC +typedef struct sSirSmeLinkTestStopRsp +{ + tANI_U16 messageType; // eWNI_SME_LINK_TEST_STOP_RSP + tANI_U16 length; + tSirMacAddr peerMacAddr; + tSirResultCodes statusCode; +} tSirSmeLinkTestStopRsp, *tpSirSmeLinkTestStopRsp; + +/// Definition for kick starting DFS measurements +typedef struct sSirSmeDFSreq +{ + tANI_U16 messageType; // eWNI_SME_DFS_REQ + tANI_U16 length; + tANI_U16 transactionId; // Transaction ID for cmd +} tSirSmeDFSrequest, *tpSirSmeDFSrequest; + +/// Definition for response message to previously +/// issued DFS request +typedef struct sSirSmeDFSrsp +{ + tANI_U16 messageType; // eWNI_SME_DFS_RSP + tANI_U16 length; + tSirResultCodes statusCode; + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U32 dfsReport[1]; +} tSirSmeDFSrsp, *tpSirSmeDFSrsp; + +/// Statistic definitions +//============================================================= +// Per STA statistic structure; This same struct will be used for Aggregate +// STA stats as well. + +// Clear radio stats and clear per sta stats +typedef enum +{ + eANI_CLEAR_ALL_STATS, // Clears all stats + eANI_CLEAR_RX_STATS, // Clears RX statistics of the radio interface + eANI_CLEAR_TX_STATS, // Clears TX statistics of the radio interface + eANI_CLEAR_RADIO_STATS, // Clears all the radio stats + eANI_CLEAR_PER_STA_STATS, // Clears Per STA stats + eANI_CLEAR_AGGR_PER_STA_STATS, // Clears aggregate stats + + // Used to distinguish between per sta to security stats. + // Used only by AP, FW just returns the same parameter as it received. + eANI_LINK_STATS, // Get Per STA stats + eANI_SECURITY_STATS, // Get Per STA security stats + + eANI_CLEAR_STAT_TYPES_END +} tAniStatSubTypes; + +typedef struct sAniTxCtrs +{ + // add the rate counters here + tANI_U32 tx1Mbps; + tANI_U32 tx2Mbps; + tANI_U32 tx5_5Mbps; + tANI_U32 tx6Mbps; + tANI_U32 tx9Mbps; + tANI_U32 tx11Mbps; + tANI_U32 tx12Mbps; + tANI_U32 tx18Mbps; + tANI_U32 tx24Mbps; + tANI_U32 tx36Mbps; + tANI_U32 tx48Mbps; + tANI_U32 tx54Mbps; + tANI_U32 tx72Mbps; + tANI_U32 tx96Mbps; + tANI_U32 tx108Mbps; + + // tx path radio counts + tANI_U32 txFragHi; + tANI_U32 txFragLo; + tANI_U32 txFrameHi; + tANI_U32 txFrameLo; + tANI_U32 txMulticastFrameHi; + tANI_U32 txMulticastFrameLo; + tANI_U32 txFailedHi; + tANI_U32 txFailedLo; + tANI_U32 multipleRetryHi; + tANI_U32 multipleRetryLo; + tANI_U32 singleRetryHi; + tANI_U32 singleRetryLo; + tANI_U32 ackFailureHi; + tANI_U32 ackFailureLo; + tANI_U32 xmitBeacons; + + // titan 3c stats + tANI_U32 txCbEscPktCntHi; // Total Number of Channel Bonded/Escort Packet Transmitted + tANI_U32 txCbEscPktCntLo; + tANI_U32 txChunksCntHi; // Total Number of Chunks Transmitted + tANI_U32 txChunksCntLo; + tANI_U32 txCompPktCntHi; // Total Number of Compresssed Packet Transmitted + tANI_U32 txCompPktCntLo; + tANI_U32 tx50PerCompPktCntHi; // Total Number of Packets with 50% or more compression + tANI_U32 tx50PerCompPktCntLo; + tANI_U32 txExpanPktCntHi; // Total Number of Packets Transmitted that got expanded + tANI_U32 txExpanPktCntLo; +} tAniTxCtrs, *tpAniTxCtrs; + +typedef struct sAniRxCtrs +{ + // receive frame rate counters + tANI_U32 rx1Mbps; + tANI_U32 rx2Mbps; + tANI_U32 rx5_5Mbps; + tANI_U32 rx6Mbps; + tANI_U32 rx9Mbps; + tANI_U32 rx11Mbps; + tANI_U32 rx12Mbps; + tANI_U32 rx18Mbps; + tANI_U32 rx24Mbps; + tANI_U32 rx36Mbps; + tANI_U32 rx48Mbps; + tANI_U32 rx54Mbps; + tANI_U32 rx72Mbps; + tANI_U32 rx96Mbps; + tANI_U32 rx108Mbps; + + // receive size counters; 'Lte' = Less than or equal to + tANI_U32 rxLte64; + tANI_U32 rxLte128Gt64; + tANI_U32 rxLte256Gt128; + tANI_U32 rxLte512Gt256; + tANI_U32 rxLte1kGt512; + tANI_U32 rxLte1518Gt1k; + tANI_U32 rxLte2kGt1518; + tANI_U32 rxLte4kGt2k; + + // rx radio stats + tANI_U32 rxFrag; + tANI_U32 rxFrame; + tANI_U32 fcsError; + tANI_U32 rxMulticast; + tANI_U32 duplicate; + tANI_U32 rtsSuccess; + tANI_U32 rtsFailed; + tANI_U32 wepUndecryptables; + tANI_U32 drops; + tANI_U32 aesFormatErrorUcastCnts; + tANI_U32 aesReplaysUcast; + tANI_U32 aesDecryptErrUcast; + + // titan 3c stats + tANI_U32 rxDecompPktCntHi; // Total Number of Packets that got decompressed + tANI_U32 rxDecompPktCntLo; + tANI_U32 rxCompPktCntHi; // Total Number of Packets received that were actually compressed + tANI_U32 rxCompPktCntLo; + tANI_U32 rxExpanPktCntHi; // Total Number of Packets received that got expanded + tANI_U32 rxExpanPktCntLo; +} tAniRxCtrs, *tpAniRxCtrs; + +// Radio stats +typedef struct sAniRadioStats +{ + tAniTxCtrs tx; + tAniRxCtrs rx; +} tAniRadioStats, *tpAniRadioStats; + +// Get Radio Stats request structure +// This structure shall be used for both Radio stats and Aggregate stats +// A valid request must contain entire structure with/without valid fields. +// Based on the request type, the valid fields will be checked. +typedef struct sAniGetStatsReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + // only used for clear stats and per sta stats clear + tAniStatSubTypes stat; // Clears the stats of the described types. + tANI_U32 staId; // Per STA stats request must contain valid + // values + tANI_U8 macAddr[6]; +} tAniGetStatsReq, *tpAniGetStatsReq; + +// Get Radio Stats response struct +typedef struct sAniGetRadioStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniRadioStats radio; +} tAniGetRadioStatsRsp, *tpAniGetRadioStatsRsp; + +// Per Sta stats response struct +typedef struct sAniGetPerStaStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniStatSubTypes stat; // Sub type needed by AP. Returns the same value + tAniStaStatStruct sta; + tANI_U32 staId; + tANI_U8 macAddr[6]; +} tAniGetPerStaStatsRsp, *tpAniGetPerStaStatsRsp; + +// Get Aggregate stats +typedef struct sAniGetAggrStaStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniStaStatStruct sta; +} tAniGetAggrStaStatsRsp, *tpAniGetAggrStaStatsRsp; + +// Clear stats request and response structure. 'rc' field is unused in +// request and this field is used in response field. +typedef struct sAniClearStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; // return code - will be filled by FW on + // response. + // Same transaction ID will be returned by the FW + tANI_U16 transactionId; + tAniStatSubTypes stat; // Clears the stats of the described types. + tANI_U32 staId; // Applicable only to PER STA stats clearing + tANI_U8 macAddr[6]; // Applicable only to PER STA stats clearing +} tAniClearStatsRsp, *tpAniClearStatsRsp; + +typedef struct sAniGetGlobalStatsRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 rc; + tANI_U16 transactionId; + tAniGlobalStatStruct global; +} tAniGetGlobalStatsRsp, *tpAniGetGlobalStatsRsp; + +typedef struct sAniGetStatSummaryRsp +{ + tANI_U16 type; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request --Why? + tANI_U32 rc; + tANI_U16 transactionId; + tAniStatSummaryStruct stat; +} tAniGetStatSummaryRsp, *tpAniGetStatSummaryRsp; + +//*************************************************************** + + +/*******************PE Statistics*************************/ +typedef enum +{ + PE_SUMMARY_STATS_INFO = 0x00000001, + PE_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, + PE_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, + PE_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, + PE_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, + PE_PER_STA_STATS_INFO = 0x00000020, + PE_PER_TX_PKT_STATS_INFO = 0x00000040, +}ePEStatsMask; + +/* + * tpAniGetPEStatsReq is tied to + * for SME ==> PE eWNI_SME_GET_STATISTICS_REQ msgId and + * for PE ==> HAL SIR_HAL_GET_STATISTICS_REQ msgId + */ +typedef struct sAniGetPEStatsReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U32 staId; // Per STA stats request must contain valid + tANI_U32 statsMask; // categories of stats requested. look at ePEStatsMask +} tAniGetPEStatsReq, *tpAniGetPEStatsReq; + +/* + * tpAniGetPEStatsRsp is tied to + * for PE ==> SME eWNI_SME_GET_STATISTICS_RSP msgId and + * for HAL ==> PE SIR_HAL_GET_STATISTICS_RSP msgId + */ +typedef struct sAniGetPEStatsRsp +{ + // Common for all types are responses + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request, includes the pStatsBuf length too + tANI_U8 sessionId; + tANI_U32 rc; //success/failure + tANI_U32 staId; // Per STA stats request must contain valid + tANI_U32 statsMask; // categories of stats requested. look at ePEStatsMask +/********************************************************************************************** + //void *pStatsBuf; + The Stats buffer starts here and can be an aggregate of more than one statistics + structure depending on statsMask.The void pointer "pStatsBuf" is commented out + intentionally and the src code that uses this structure should take that into account. +**********************************************************************************************/ +} tAniGetPEStatsRsp, *tpAniGetPEStatsRsp; + +typedef struct sAniGetRssiReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; + tANI_U8 staId; + void *rssiCallback; + void *pDevContext; //device context + void *pVosContext; //voss context + +} tAniGetRssiReq, *tpAniGetRssiReq; + +typedef struct sAniGetSnrReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; + tANI_U8 staId; + void *snrCallback; + void *pDevContext; //device context +} tAniGetSnrReq, *tpAniGetSnrReq; + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +typedef struct sAniGetRoamRssiRsp +{ + // Common for all types are responses + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request, includes the pStatsBuf length too + tANI_U8 sessionId; + tANI_U32 rc; //success/failure + tANI_U32 staId; // Per STA stats request must contain valid + tANI_S8 rssi; + void *rssiReq; //rssi request backup + +} tAniGetRoamRssiRsp, *tpAniGetRoamRssiRsp; + +#endif + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) + +typedef struct sSirTsmIE +{ + tANI_U8 tsid; + tANI_U8 state; + tANI_U16 msmt_interval; +} tSirTsmIE, *tpSirTsmIE; + +typedef struct sSirSmeTsmIEInd +{ + tSirTsmIE tsmIe; + tANI_U8 sessionId; +} tSirSmeTsmIEInd, *tpSirSmeTsmIEInd; + + +typedef struct sAniTrafStrmMetrics +{ + tANI_U16 UplinkPktQueueDly; + tANI_U16 UplinkPktQueueDlyHist[4]; + tANI_U32 UplinkPktTxDly; + tANI_U16 UplinkPktLoss; + tANI_U16 UplinkPktCount; + tANI_U8 RoamingCount; + tANI_U16 RoamingDly; +} tAniTrafStrmMetrics, *tpAniTrafStrmMetrics; + +typedef struct sAniGetTsmStatsReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 staId; + tANI_U8 tid; // traffic id + tSirMacAddr bssId; + void *tsmStatsCallback; + void *pDevContext; //device context + void *pVosContext; //voss context +} tAniGetTsmStatsReq, *tpAniGetTsmStatsReq; + +typedef struct sAniGetTsmStatsRsp +{ + // Common for all types are responses + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request, includes the pStatsBuf length too + tANI_U8 sessionId; + tANI_U32 rc; //success/failure + tANI_U32 staId; // Per STA stats request must contain valid + tAniTrafStrmMetrics tsmMetrics; + void *tsmStatsReq; //tsm stats request backup +} tAniGetTsmStatsRsp, *tpAniGetTsmStatsRsp; + +typedef struct sSirEseBcnReportBssInfo +{ + tBcnReportFields bcnReportFields; + tANI_U8 ieLen; + tANI_U8 *pBuf; +} tSirEseBcnReportBssInfo, *tpSirEseBcnReportBssInfo; + +typedef struct sSirEseBcnReportRsp +{ + tANI_U16 measurementToken; + tANI_U8 flag; /* Flag to report measurement done and more data */ + tANI_U8 numBss; + tSirEseBcnReportBssInfo bcnRepBssInfo[SIR_BCN_REPORT_MAX_BSS_DESC]; +} tSirEseBcnReportRsp, *tpSirEseBcnReportRsp; + +#endif /* FEATURE_WLAN_ESE || FEATURE_WLAN_ESE_UPLOAD */ + +/* Change country code request MSG structure */ +typedef struct sAniChangeCountryCodeReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //3 char country code + tAniBool countryFromUserSpace; + tAniBool sendRegHint; //TRUE if we want to send hint to NL80211 + void *changeCCCallback; + void *pDevContext; //device context + void *pVosContext; //voss context + +} tAniChangeCountryCodeReq, *tpAniChangeCountryCodeReq; + +/* generic country code change request MSG structure */ +typedef struct sAniGenericChangeCountryCodeReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //3 char country code + tANI_U16 domain_index; +} tAniGenericChangeCountryCodeReq, *tpAniGenericChangeCountryCodeReq; + +typedef struct sAniDHCPStopInd +{ + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 device_mode; // Mode of the device(ex:STA, AP) + tSirMacAddr macAddr; + +} tAniDHCPInd, *tpAniDHCPInd; + +#ifdef WLAN_FEATURE_RMC +typedef struct sAniTXFailMonitorInd +{ + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 tx_fail_count; + void *txFailIndCallback; +} tAniTXFailMonitorInd, *tpAniTXFailMonitorInd; +#endif /* WLAN_FEATURE_RMC */ + +typedef struct sAniSummaryStatsInfo +{ + tANI_U32 retry_cnt[4]; //Total number of packets(per AC) that were successfully transmitted with retries + tANI_U32 multiple_retry_cnt[4];//The number of MSDU packets and MMPDU frames per AC that the 802.11 + // station successfully transmitted after more than one retransmission attempt + + tANI_U32 tx_frm_cnt[4]; //Total number of packets(per AC) that were successfully transmitted + //(with and without retries, including multi-cast, broadcast) + //tANI_U32 tx_fail_cnt; + //tANI_U32 num_rx_frm_crc_err; //Total number of received frames with CRC Error + //tANI_U32 num_rx_frm_crc_ok; //Total number of successfully received frames with out CRC Error + tANI_U32 rx_frm_cnt; //Total number of packets that were successfully received + //(after appropriate filter rules including multi-cast, broadcast) + tANI_U32 frm_dup_cnt; //Total number of duplicate frames received successfully + tANI_U32 fail_cnt[4]; //Total number packets(per AC) failed to transmit + tANI_U32 rts_fail_cnt; //Total number of RTS/CTS sequence failures for transmission of a packet + tANI_U32 ack_fail_cnt; //Total number packets failed transmit because of no ACK from the remote entity + tANI_U32 rts_succ_cnt; //Total number of RTS/CTS sequence success for transmission of a packet + tANI_U32 rx_discard_cnt; //The sum of the receive error count and dropped-receive-buffer error count. + //HAL will provide this as a sum of (FCS error) + (Fail get BD/PDU in HW) + tANI_U32 rx_error_cnt; //The receive error count. HAL will provide the RxP FCS error global counter. + tANI_U32 tx_byte_cnt; //The sum of the transmit-directed byte count, transmit-multicast byte count + //and transmit-broadcast byte count. HAL will sum TPE UC/MC/BCAST global counters + //to provide this. +#if 0 + //providing the following stats, in case of wrap around for tx_byte_cnt + tANI_U32 tx_unicast_lower_byte_cnt; + tANI_U32 tx_unicast_upper_byte_cnt; + tANI_U32 tx_multicast_lower_byte_cnt; + tANI_U32 tx_multicast_upper_byte_cnt; + tANI_U32 tx_broadcast_lower_byte_cnt; + tANI_U32 tx_broadcast_upper_byte_cnt; +#endif + +}tAniSummaryStatsInfo, *tpAniSummaryStatsInfo; + +typedef enum eTxRateInfo +{ + eHAL_TX_RATE_LEGACY = 0x1, /* Legacy rates */ + eHAL_TX_RATE_HT20 = 0x2, /* HT20 rates */ + eHAL_TX_RATE_HT40 = 0x4, /* HT40 rates */ + eHAL_TX_RATE_SGI = 0x8, /* Rate with Short guard interval */ + eHAL_TX_RATE_LGI = 0x10, /* Rate with Long guard interval */ + eHAL_TX_RATE_VHT20 = 0x20, /* VHT 20 rates */ + eHAL_TX_RATE_VHT40 = 0x40, /* VHT 40 rates */ + eHAL_TX_RATE_VHT80 = 0x80 /* VHT 80 rates */ +} tTxrateinfoflags; + +typedef struct sAniGlobalClassAStatsInfo +{ + tANI_U32 rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames + tANI_U32 promiscuous_rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames when a promiscuous packet filter was enabled + //tANI_U32 rx_fcs_err; //The number of MPDU frames that the 802.11 station received with FCS errors + tANI_U32 rx_input_sensitivity; //The receiver input sensitivity referenced to a FER of 8% at an MPDU length + //of 1024 bytes at the antenna connector. Each element of the array shall correspond + //to a supported rate and the order shall be the same as the supporteRates parameter. + tANI_U32 max_pwr; //The maximum transmit power in dBm upto one decimal. + //for eg: if it is 10.5dBm, the value would be 105 + //tANI_U32 default_pwr; //The nominal transmit level used after normal power on sequence + tANI_U32 sync_fail_cnt; //Number of times the receiver failed to synchronize with the incoming signal + //after detecting the sync in the preamble of the transmitted PLCP protocol data unit. + tANI_U32 tx_rate; //Legacy transmit rate, in units of + //500 kbit/sec, for the most + //recently transmitted frame + tANI_U32 mcs_index; //mcs index for HT20 and HT40 rates + tANI_U32 tx_rate_flags; //to differentiate between HT20 and + //HT40 rates; short and long guard interval + +}tAniGlobalClassAStatsInfo, *tpAniGlobalClassAStatsInfo; + + +typedef struct sAniGlobalSecurityStats +{ + tANI_U32 rx_wep_unencrypted_frm_cnt; //The number of unencrypted received MPDU frames that the MAC layer discarded when + //the IEEE 802.11 dot11ExcludeUnencrypted management information base (MIB) object + //is enabled + tANI_U32 rx_mic_fail_cnt; //The number of received MSDU packets that that the 802.11 station discarded + //because of MIC failures + tANI_U32 tkip_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a TKIP ICV error + tANI_U32 aes_ccmp_format_err; //The number of received MPDU frames that the 802.11 discarded because of an + //invalid AES-CCMP format + tANI_U32 aes_ccmp_replay_cnt; //The number of received MPDU frames that the 802.11 station discarded because of + //the AES-CCMP replay protection procedure + tANI_U32 aes_ccmp_decrpt_err; //The number of received MPDU frames that the 802.11 station discarded because of + //errors detected by the AES-CCMP decryption algorithm + tANI_U32 wep_undecryptable_cnt; //The number of encrypted MPDU frames received for which a WEP decryption key was + //not available on the 802.11 station + tANI_U32 wep_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a WEP ICV error + tANI_U32 rx_decrypt_succ_cnt; //The number of received encrypted packets that the 802.11 station successfully + //decrypted + tANI_U32 rx_decrypt_fail_cnt; //The number of encrypted packets that the 802.11 station failed to decrypt + +}tAniGlobalSecurityStats, *tpAniGlobalSecurityStats; + +typedef struct sAniGlobalClassBStatsInfo +{ + tAniGlobalSecurityStats ucStats; + tAniGlobalSecurityStats mcbcStats; +}tAniGlobalClassBStatsInfo, *tpAniGlobalClassBStatsInfo; + +typedef struct sAniGlobalClassCStatsInfo +{ + tANI_U32 rx_amsdu_cnt; //This counter shall be incremented for a received A-MSDU frame with the stations + //MAC address in the address 1 field or an A-MSDU frame with a group address in the + //address 1 field + tANI_U32 rx_ampdu_cnt; //This counter shall be incremented when the MAC receives an AMPDU from the PHY + tANI_U32 tx_20_frm_cnt; //This counter shall be incremented when a Frame is transmitted only on the + //primary channel + tANI_U32 rx_20_frm_cnt; //This counter shall be incremented when a Frame is received only on the primary channel + tANI_U32 rx_mpdu_in_ampdu_cnt; //This counter shall be incremented by the number of MPDUs received in the A-MPDU + //when an A-MPDU is received + tANI_U32 ampdu_delimiter_crc_err;//This counter shall be incremented when an MPDU delimiter has a CRC error when this + //is the first CRC error in the received AMPDU or when the previous delimiter has been + //decoded correctly + +}tAniGlobalClassCStatsInfo, *tpAniGlobalClassCStatsInfo; + +typedef struct sAniPerStaStatsInfo +{ + tANI_U32 tx_frag_cnt[4]; //The number of MPDU frames that the 802.11 station transmitted and acknowledged + //through a received 802.11 ACK frame + tANI_U32 tx_ampdu_cnt; //This counter shall be incremented when an A-MPDU is transmitted + tANI_U32 tx_mpdu_in_ampdu_cnt; //This counter shall increment by the number of MPDUs in the AMPDU when an A-MPDU + //is transmitted + +}tAniPerStaStatsInfo, *tpAniPerStaStatsInfo; + +typedef struct sAniPerTxPktStatsInfo +{ + tANI_U32 lastTxRate; // 802.11 data rate at which the last data frame is transmitted. + tANI_U32 txAvgRetry; // Average number of retries per 10 packets. +}tAniPerTxPktStatsInfo, *tpAniPerTxPktStatsInfo; + + +/**********************PE Statistics end*************************/ + + + +typedef struct sSirRSSIThresholds +{ +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_S8 ucRssiThreshold1 : 8; + tANI_S8 ucRssiThreshold2 : 8; + tANI_S8 ucRssiThreshold3 : 8; + tANI_U8 bRssiThres1PosNotify : 1; + tANI_U8 bRssiThres1NegNotify : 1; + tANI_U8 bRssiThres2PosNotify : 1; + tANI_U8 bRssiThres2NegNotify : 1; + tANI_U8 bRssiThres3PosNotify : 1; + tANI_U8 bRssiThres3NegNotify : 1; + tANI_U8 bReserved10 : 2; +#else + tANI_U8 bReserved10 : 2; + tANI_U8 bRssiThres3NegNotify : 1; + tANI_U8 bRssiThres3PosNotify : 1; + tANI_U8 bRssiThres2NegNotify : 1; + tANI_U8 bRssiThres2PosNotify : 1; + tANI_U8 bRssiThres1NegNotify : 1; + tANI_U8 bRssiThres1PosNotify : 1; + tANI_S8 ucRssiThreshold3 : 8; + tANI_S8 ucRssiThreshold2 : 8; + tANI_S8 ucRssiThreshold1 : 8; +#endif + +}tSirRSSIThresholds, *tpSirRSSIThresholds; + +typedef struct sSirRSSINotification +{ +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 bRssiThres1PosCross : 1; + tANI_U32 bRssiThres1NegCross : 1; + tANI_U32 bRssiThres2PosCross : 1; + tANI_U32 bRssiThres2NegCross : 1; + tANI_U32 bRssiThres3PosCross : 1; + tANI_U32 bRssiThres3NegCross : 1; + v_S7_t avgRssi : 8; + tANI_U32 bReserved : 18; +#else + tANI_U32 bReserved : 18; + v_S7_t avgRssi : 8; + tANI_U32 bRssiThres3NegCross : 1; + tANI_U32 bRssiThres3PosCross : 1; + tANI_U32 bRssiThres2NegCross : 1; + tANI_U32 bRssiThres2PosCross : 1; + tANI_U32 bRssiThres1NegCross : 1; + tANI_U32 bRssiThres1PosCross : 1; +#endif + +}tSirRSSINotification, *tpSirRSSINotification; + + +typedef struct sSirP2PNoaStart +{ + tANI_U32 status; + tANI_U32 bssIdx; +} tSirP2PNoaStart, *tpSirP2PNoaStart; + +typedef struct sSirTdlsInd +{ + tANI_U16 status; + tANI_U16 assocId; + tANI_U16 staIdx; + tANI_U16 reasonCode; +} tSirTdlsInd, *tpSirTdlsInd; + +typedef struct sSirP2PNoaAttr +{ +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 index :8; + tANI_U32 oppPsFlag :1; + tANI_U32 ctWin :7; + tANI_U32 rsvd1: 16; +#else + tANI_U32 rsvd1: 16; + tANI_U32 ctWin :7; + tANI_U32 oppPsFlag :1; + tANI_U32 index :8; +#endif + +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 uNoa1IntervalCnt:8; + tANI_U32 rsvd2:24; +#else + tANI_U32 rsvd2:24; + tANI_U32 uNoa1IntervalCnt:8; +#endif + tANI_U32 uNoa1Duration; + tANI_U32 uNoa1Interval; + tANI_U32 uNoa1StartTime; + +#ifdef ANI_BIG_BYTE_ENDIAN + tANI_U32 uNoa2IntervalCnt:8; + tANI_U32 rsvd3:24; +#else + tANI_U32 rsvd3:24; + tANI_U32 uNoa2IntervalCnt:8; +#endif + tANI_U32 uNoa2Duration; + tANI_U32 uNoa2Interval; + tANI_U32 uNoa2StartTime; +} tSirP2PNoaAttr, *tpSirP2PNoaAttr; + +typedef __ani_attr_pre_packed struct sSirTclasInfo +{ + tSirMacTclasIE tclas; + tANI_U8 version; // applies only for classifier type ip + __ani_attr_pre_packed union { + tSirMacTclasParamEthernet eth; + tSirMacTclasParamIPv4 ipv4; + tSirMacTclasParamIPv6 ipv6; + tSirMacTclasParam8021dq t8021dq; + }__ani_attr_packed tclasParams; +} __ani_attr_packed tSirTclasInfo; + + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) +#define TSRS_11AG_RATE_6MBPS 0xC +#define TSRS_11B_RATE_5_5MBPS 0xB + +typedef struct sSirMacESETSRSIE +{ + tANI_U8 tsid; + tANI_U8 rates[8]; +} tSirMacESETSRSIE; + +typedef struct sSirMacESETSMIE +{ + tANI_U8 tsid; + tANI_U8 state; + tANI_U16 msmt_interval; +} tSirMacESETSMIE; + +typedef struct sTSMStats +{ + tANI_U8 tid; + tSirMacAddr bssId; + tTrafStrmMetrics tsmMetrics; +} tTSMStats, *tpTSMStats; + +typedef struct sEseTSMContext +{ + tANI_U8 tid; + tSirMacESETSMIE tsmInfo; + tTrafStrmMetrics tsmMetrics; +} tEseTSMContext, *tpEseTSMContext; + +typedef struct sEsePEContext +{ +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + tEseMeasReq curMeasReq; +#endif + tEseTSMContext tsm; +} tEsePEContext, *tpEsePEContext; + + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + +typedef struct sSirAddtsReqInfo +{ + tANI_U8 dialogToken; + tSirMacTspecIE tspec; + + tANI_U8 numTclas; // number of Tclas elements + tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM]; + tANI_U8 tclasProc; +#if defined(FEATURE_WLAN_ESE) + tSirMacESETSRSIE tsrsIE; + tANI_U8 tsrsPresent:1; +#endif + tANI_U8 wmeTspecPresent:1; + tANI_U8 wsmTspecPresent:1; + tANI_U8 lleTspecPresent:1; + tANI_U8 tclasProcPresent:1; +} tSirAddtsReqInfo, *tpSirAddtsReqInfo; + +typedef struct sSirAddtsRspInfo +{ + tANI_U8 dialogToken; + tSirMacStatusCodes status; + tSirMacTsDelayIE delay; + + tSirMacTspecIE tspec; + tANI_U8 numTclas; // number of Tclas elements + tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM]; + tANI_U8 tclasProc; + tSirMacScheduleIE schedule; +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) + tSirMacESETSMIE tsmIE; + tANI_U8 tsmPresent:1; +#endif + tANI_U8 wmeTspecPresent:1; + tANI_U8 wsmTspecPresent:1; + tANI_U8 lleTspecPresent:1; + tANI_U8 tclasProcPresent:1; + tANI_U8 schedulePresent:1; +} tSirAddtsRspInfo, *tpSirAddtsRspInfo; + +typedef struct sSirDeltsReqInfo +{ + tSirMacTSInfo tsinfo; + tSirMacTspecIE tspec; + tANI_U8 wmeTspecPresent:1; + tANI_U8 wsmTspecPresent:1; + tANI_U8 lleTspecPresent:1; +} tSirDeltsReqInfo, *tpSirDeltsReqInfo; + +/// Add a tspec as defined +typedef struct sSirAddtsReq +{ + tANI_U16 messageType; // eWNI_SME_ADDTS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + tANI_U32 timeout; // in ms + tANI_U8 rspReqd; + tSirAddtsReqInfo req; +} tSirAddtsReq, *tpSirAddtsReq; + +typedef struct sSirAddtsRsp +{ + tANI_U16 messageType; // eWNI_SME_ADDTS_RSP + tANI_U16 length; + tANI_U8 sessionId; // sme sessionId Added for BT-AMP support + tANI_U16 transactionId; //sme transaction Id Added for BT-AMP Support + tANI_U32 rc; // return code + tSirAddtsRspInfo rsp; +} tSirAddtsRsp, *tpSirAddtsRsp; + +typedef struct sSirDeltsReq +{ + tANI_U16 messageType; // eWNI_SME_DELTS_REQ + tANI_U16 length; + tANI_U8 sessionId;//Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + tANI_U16 aid; // use 0 if macAddr is being specified + tANI_U8 macAddr[6]; // only on AP to specify the STA + tANI_U8 rspReqd; + tSirDeltsReqInfo req; +} tSirDeltsReq, *tpSirDeltsReq; + +typedef struct sSirDeltsRsp +{ + tANI_U16 messageType; // eWNI_SME_DELTS_RSP + tANI_U16 length; + tANI_U8 sessionId; // sme sessionId Added for BT-AMP support + tANI_U16 transactionId; //sme transaction Id Added for BT-AMP Support + tANI_U32 rc; + tANI_U16 aid; // use 0 if macAddr is being specified + tANI_U8 macAddr[6]; // only on AP to specify the STA + tSirDeltsReqInfo rsp; +} tSirDeltsRsp, *tpSirDeltsRsp; + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + +#define SIR_QOS_NUM_TSPEC_MAX 2 +#define SIR_QOS_NUM_AC_MAX 4 + +typedef struct sSirAggrQosReqInfo +{ + tANI_U16 tspecIdx; + tSirAddtsReqInfo aggrAddTsInfo[SIR_QOS_NUM_AC_MAX]; +}tSirAggrQosReqInfo, *tpSirAggrQosReqInfo; + +typedef struct sSirAggrQosReq +{ + tANI_U16 messageType; // eWNI_SME_ADDTS_REQ + tANI_U16 length; + tANI_U8 sessionId; //Session ID + tANI_U16 transactionId; + tSirMacAddr bssId; //BSSID + tANI_U32 timeout; // in ms + tANI_U8 rspReqd; + tSirAggrQosReqInfo aggrInfo; +}tSirAggrQosReq, *tpSirAggrQosReq; + +typedef struct sSirAggrQosRspInfo +{ + tANI_U16 tspecIdx; + tSirAddtsRspInfo aggrRsp[SIR_QOS_NUM_AC_MAX]; +} tSirAggrQosRspInfo, *tpSirAggrQosRspInfo; + +typedef struct sSirAggrQosRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; + tSirAggrQosRspInfo aggrInfo; +} tSirAggrQosRsp, *tpSirAggrQosRsp; + +#endif/*WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE*/ + +typedef struct sSirSetTxPowerReq +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr bssId; + tANI_U8 mwPower; + tANI_U8 bssIdx; +} tSirSetTxPowerReq, *tpSirSetTxPowerReq; + +typedef struct sSirSetTxPowerRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U32 status; +} tSirSetTxPowerRsp, *tpSirSetTxPowerRsp; + +typedef struct sSirGetTxPowerReq +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U16 staid; +} tSirGetTxPowerReq, *tpSirGetTxPowerReq; + +typedef struct sSirGetTxPowerRsp +{ + tANI_U16 messageType; + tANI_U16 length; // length of the entire request + tANI_U32 power; // units of milliwatts + tANI_U32 status; +} tSirGetTxPowerRsp, *tpSirGetTxPowerRsp; + + +typedef tANI_U32 tSirMacNoise[3]; + +typedef struct sSirGetNoiseRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacNoise noise; +} tSirGetNoiseRsp, *tpSirGetNoiseRsp; + +typedef struct sSirQosMapSet +{ + tANI_U8 present; + tANI_U8 num_dscp_exceptions; + tANI_U8 dscp_exceptions[21][2]; + tANI_U8 dscp_range[8][2]; +} tSirQosMapSet, *tpSirQosMapSet; + +// +// PMC --> PE --> HAL +// Power save configuration parameters +// +typedef struct sSirPowerSaveCfg +{ + tANI_U16 listenInterval; + + /* Number of consecutive missed beacons before + * hardware generates an interrupt to wake up + * the host. In units of listen interval. + */ + tANI_U32 HeartBeatCount; + + /* specifies which beacons are to be forwarded + * to host when beacon filtering is enabled. + * In units of listen interval. + */ + tANI_U32 nthBeaconFilter; + + /* Maximum number of PS-Poll send before + * firmware sends data null with PM set to 0. + */ + tANI_U32 maxPsPoll; + + /* If the average RSSI value falls below the + * minRssiThreshold, then FW will send an + * interrupt to wake up the host. + */ + tANI_U32 minRssiThreshold; + + /* Number of beacons for which firmware will + * collect the RSSI values and compute the average. + */ + tANI_U8 numBeaconPerRssiAverage; + + /* FW collects the RSSI stats for this period + * in BMPS mode. + */ + tANI_U8 rssiFilterPeriod; + + // Enabling/disabling broadcast frame filter feature + tANI_U8 broadcastFrameFilter; + + // Enabling/disabling the ignore DTIM feature + tANI_U8 ignoreDtim; + + /* The following configuration parameters are kept + * in order to be backward compatible for Gen5. + * These will NOT be used for Gen6 Libra chip + */ + tBeaconForwarding beaconFwd; + tANI_U16 nthBeaconFwd; + tANI_U8 fEnablePwrSaveImmediately; + tANI_U8 fPSPoll; + + // Enabling/disabling Beacon Early Termination feature + tANI_U8 fEnableBeaconEarlyTermination; + tANI_U8 bcnEarlyTermWakeInterval; + +}tSirPowerSaveCfg, *tpSirPowerSaveCfg; + +/* Reason code for requesting Full Power. This reason code is used by + any module requesting full power from PMC and also by PE when it + sends the eWNI_PMC_EXIT_BMPS_IND to PMC*/ +typedef enum eRequestFullPowerReason +{ + eSME_MISSED_BEACON_IND_RCVD, /* PE received a MAX_MISSED_BEACON_IND */ + eSME_BMPS_STATUS_IND_RCVD, /* PE received a SIR_HAL_BMPS_STATUS_IND */ + eSME_BMPS_MODE_DISABLED, /* BMPS mode was disabled by HDD in SME */ + eSME_LINK_DISCONNECTED_BY_HDD, /* Link has been disconnected requested by HDD */ + eSME_LINK_DISCONNECTED_BY_OTHER,/* Disconnect due to linklost or requested by peer */ + eSME_FULL_PWR_NEEDED_BY_HDD, /* HDD request full power for some reason */ + eSME_FULL_PWR_NEEDED_BY_BAP, /* BAP request full power for BT_AMP */ + eSME_FULL_PWR_NEEDED_BY_CSR, /* CSR requests full power */ + eSME_FULL_PWR_NEEDED_BY_QOS, /* QOS requests full power */ + eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH, /* channel switch request full power*/ +#ifdef FEATURE_WLAN_TDLS + eSME_FULL_PWR_NEEDED_BY_TDLS_PEER_SETUP, /* TDLS peer setup*/ +#endif + eSME_REASON_OTHER /* No specific reason. General reason code */ +} tRequestFullPowerReason, tExitBmpsReason; + + + +//This is sent alongwith eWNI_PMC_EXIT_BMPS_REQ message +typedef struct sExitBmpsInfo +{ + tExitBmpsReason exitBmpsReason; /*Reason for exiting BMPS */ +}tExitBmpsInfo, *tpExitBmpsInfo; + + +// MAC SW --> SME +// Message indicating to SME to exit BMPS sleep mode +typedef struct sSirSmeExitBmpsInd +{ + tANI_U16 mesgType; /* eWNI_PMC_EXIT_BMPS_IND */ + tANI_U16 mesgLen; + tSirResultCodes statusCode; + tExitBmpsReason exitBmpsReason; /*Reason for exiting BMPS */ + +} tSirSmeExitBmpsInd, *tpSirSmeExitBmpsInd; + + +// +// HDD -> LIM +// tSirMsgQ.type = eWNI_SME_DEL_BA_PEER_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = instance of tDelBAParams +// +typedef struct sSmeDelBAPeerInd +{ + // Message Type + tANI_U16 mesgType; + + tSirMacAddr bssId;//BSSID + + // Message Length + tANI_U16 mesgLen; + + // Station Index + tANI_U16 staIdx; + + // TID for which the BA session is being deleted + tANI_U8 baTID; + + // DELBA direction + // eBA_INITIATOR - Originator + // eBA_RECEIPIENT - Recipient + tANI_U8 baDirection; +} tSmeDelBAPeerInd, *tpSmeDelBAPeerInd; + +typedef struct sSmeIbssPeerInd +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U8 sessionId; + + tSirMacAddr peerAddr; + tANI_U16 staId; + + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU signature*/ + tANI_U8 ucastSig; + + /*Broadcast DPU signature*/ + tANI_U8 bcastSig; + + //Beacon will be appended for new Peer indication. +}tSmeIbssPeerInd, *tpSmeIbssPeerInd; + +typedef struct sSirIbssPeerInactivityInd +{ + tANI_U8 bssIdx; + tANI_U8 staIdx; + tSirMacAddr peerAddr; +}tSirIbssPeerInactivityInd, *tpSirIbssPeerInactivityInd; + + +typedef struct sLimScanChn +{ + tANI_U16 numTimeScan; //how many time this channel is scan + tANI_U8 channelId; +}tLimScanChn; + +typedef struct sSmeGetScanChnRsp +{ + // Message Type + tANI_U16 mesgType; + // Message Length + tANI_U16 mesgLen; + tANI_U8 sessionId; + tANI_U8 numChn; + tLimScanChn scanChn[1]; +} tSmeGetScanChnRsp, *tpSmeGetScanChnRsp; + +typedef struct sLimScanChnInfo +{ + tANI_U8 numChnInfo; //number of channels in scanChn + tLimScanChn scanChn[SIR_MAX_SUPPORTED_CHANNEL_LIST]; +}tLimScanChnInfo; + +typedef struct sSirSmeGetAssocSTAsReq +{ + tANI_U16 messageType; // eWNI_SME_GET_ASSOC_STAS_REQ + tANI_U16 length; + tSirMacAddr bssId; // BSSID + tANI_U16 modId; + void *pUsrContext; + void *pSapEventCallback; + void *pAssocStasArray;// Pointer to allocated memory passed in WLANSAP_GetAssocStations API +} tSirSmeGetAssocSTAsReq, *tpSirSmeGetAssocSTAsReq; + +typedef struct sSmeMaxAssocInd +{ + tANI_U16 mesgType; // eWNI_SME_MAX_ASSOC_EXCEEDED + tANI_U16 mesgLen; + tANI_U8 sessionId; + tSirMacAddr peerMac; // the new peer that got rejected due to softap max assoc limit reached +} tSmeMaxAssocInd, *tpSmeMaxAssocInd; + +/*--------------------------------------------------------------------*/ +/* BootLoader message definition */ +/*--------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------*/ +/* FW image size */ +/*--------------------------------------------------------------------*/ +#define SIR_FW_IMAGE_SIZE 146332 + + +#define SIR_BOOT_MODULE_ID 1 + +#define SIR_BOOT_SETUP_IND ((SIR_BOOT_MODULE_ID << 8) | 0x11) +#define SIR_BOOT_POST_RESULT_IND ((SIR_BOOT_MODULE_ID << 8) | 0x12) +#define SIR_BOOT_DNLD_RESULT_IND ((SIR_BOOT_MODULE_ID << 8) | 0x13) +#define SIR_BOOT_DNLD_DEV_REQ ((SIR_BOOT_MODULE_ID << 8) | 0x41) +#define SIR_BOOT_DNLD_DEV_RSP ((SIR_BOOT_MODULE_ID << 8) | 0x81) +#define SIR_BOOT_DNLD_REQ ((SIR_BOOT_MODULE_ID << 8) | 0x42) +#define SIR_BOOT_DNLD_RSP ((SIR_BOOT_MODULE_ID << 8) | 0x82) + +/*--------------------------------------------------------------------*/ +/* Bootloader message syntax */ +/*--------------------------------------------------------------------*/ + +// Message header +#define SIR_BOOT_MB_HEADER 0 +#define SIR_BOOT_MB_HEADER2 1 + +#define SIR_BOOT_MSG_HDR_MASK 0xffff0000 +#define SIR_BOOT_MSG_LEN_MASK 0x0000ffff + +// BOOT_SETUP_IND parameter indices +#define SIR_BOOT_SETUP_IND_MBADDR 2 +#define SIR_BOOT_SETUP_IND_MBSIZE 3 +#define SIR_BOOT_SETUP_IND_MEMOPT 4 +#define SIR_BOOT_SETUP_IND_LEN \ + ((SIR_BOOT_SETUP_IND_MEMOPT+1)<<2) + +// BOOT_POST_RESULT_IND parameter indices +#define SIR_BOOT_POST_RESULT_IND_RES 2 +#define SIR_BOOT_POST_RESULT_IND_LEN \ + ((SIR_BOOT_POST_RESULT_IND_RES+1)<<2) + +#define SIR_BOOT_POST_RESULT_IND_SUCCESS 1 +#define SIR_BOOT_POST_RESULT_IND_MB_FAILED 2 +#define SIR_BOOT_POST_RESULT_IND_SDRAM_FAILED 3 +#define SIR_BOOT_POST_RESULT_IND_ESRAM_FAILED 4 + + +// BOOT_DNLD_RESULT_IND parameter indices +#define SIR_BOOT_DNLD_RESULT_IND_RES 2 +#define SIR_BOOT_DNLD_RESULT_IND_LEN \ + ((SIR_BOOT_DNLD_RESULT_IND_RES+1)<<2) + +#define SIR_BOOT_DNLD_RESULT_IND_SUCCESS 1 +#define SIR_BOOT_DNLD_RESULT_IND_HDR_ERR 2 +#define SIR_BOOT_DNLD_RESULT_IND_ERR 3 + +// BOOT_DNLD_DEV_REQ +#define SIR_BOOT_DNLD_DEV_REQ_SDRAMSIZE 2 +#define SIR_BOOT_DNLD_DEV_REQ_FLASHSIZE 3 +#define SIR_BOOT_DNLD_DEV_REQ_LEN \ + ((SIR_BOOT_DNLD_DEV_REQ_FLASHSIZE+1)<<2) + +// BOOT_DNLD_DEV_RSP +#define SIR_BOOT_DNLD_DEV_RSP_DEVTYPE 2 +#define SIR_BOOT_DNLD_DEV_RSP_LEN \ + ((SIR_BOOT_DNLD_DEV_RSP_DEVTYPE+1)<<2) + +#define SIR_BOOT_DNLD_DEV_RSP_SRAM 1 +#define SIR_BOOT_DNLD_DEV_RSP_FLASH 2 + +// BOOT_DNLD_REQ +#define SIR_BOOT_DNLD_REQ_OFFSET 2 +#define SIR_BOOT_DNLD_REQ_WRADDR 3 +#define SIR_BOOT_DNLD_REQ_SIZE 4 +#define SIR_BOOT_DNLD_REQ_LEN ((SIR_BOOT_DNLD_REQ_SIZE+1)<<2) + +// BOOT_DNLD_RSP +#define SIR_BOOT_DNLD_RSP_SIZE 2 +#define SIR_BOOT_DNLD_RSP_LEN ((SIR_BOOT_DNLD_RSP_SIZE+1)<<2) + + +// board capabilities fields are defined here. +typedef __ani_attr_pre_packed struct sSirBoardCapabilities +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U32 concat:1; // 0 - Concat is not supported, 1 - Concat is supported + tANI_U32 compression:1; // 0 - Compression is not supported, 1 - Compression is supported + tANI_U32 chnlBonding:1; // 0 - Channel Bonding is not supported, 1 - Channel Bonding is supported + tANI_U32 reverseFCS:1; // 0 - Reverse FCS is not supported, 1 - Reverse FCS is supported + tANI_U32 rsvd1:2; + // (productId derives sub-category in the following three families) + tANI_U32 cbFamily:1; // 0 - Not CB family, 1 - Cardbus + tANI_U32 apFamily:1; // 0 - Not AP family, 1 - AP + tANI_U32 mpciFamily:1; // 0 - Not MPCI family, 1 - MPCI + tANI_U32 bgOnly:1; // 0 - default a/b/g; 1 - b/g only + tANI_U32 bbChipVer:4; // Baseband chip version + tANI_U32 loType:2; // 0 = no LO, 1 = SILABS, 2 = ORION + tANI_U32 radioOn:2; // Not supported is 3 or 2, 0 = Off and 1 = On + tANI_U32 nReceivers:2; // 0 based. + tANI_U32 nTransmitters:1; // 0 = 1 transmitter, 1 = 2 transmitters + tANI_U32 sdram:1; // 0 = no SDRAM, 1 = SDRAM + tANI_U32 rsvd:1; + tANI_U32 extVsIntAnt:1; // 0 = ext antenna, 1 = internal antenna +#else + + tANI_U32 extVsIntAnt:1; // 0 = ext antenna, 1 = internal antenna + tANI_U32 rsvd:1; + tANI_U32 sdram:1; // 0 = no SDRAM, 1 = SDRAM + tANI_U32 nTransmitters:1; // 0 = 1 transmitter, 1 = 2 transmitters + tANI_U32 nReceivers:2; // 0 based. + tANI_U32 radioOn:2; // Not supported is 3 or 2, 0 = Off and 1 = On + tANI_U32 loType:2; // 0 = no LO, 1 = SILABS, 2 = ORION + tANI_U32 bbChipVer:4; // Baseband chip version + tANI_U32 bgOnly:1; // 0 - default a/b/g; 1 - b/g only + // (productId derives sub-category in the following three families) + tANI_U32 mpciFamily:1; // 0 - Not MPCI family, 1 - MPCI + tANI_U32 apFamily:1; // 0 - Not AP family, 1 - AP + tANI_U32 cbFamily:1; // 0 - Not CB family, 1 - Cardbus + tANI_U32 rsvd1:2; + tANI_U32 reverseFCS:1; // 0 - Reverse FCS is not supported, 1 - Reverse FCS is supported + tANI_U32 chnlBonding:1; // 0 - Channel Bonding is not supported, 1 - Channel Bonding is supported + tANI_U32 compression:1; // 0 - Compression is not supported, 1 - Compression is supported + tANI_U32 concat:1; // 0 - Concat is not supported, 1 - Concat is supported +#endif +} __ani_attr_packed tSirBoardCapabilities, *tpSirBoardCapabilities; + +# define ANI_BCAP_EXT_VS_INT_ANT_MASK 0x1 +# define ANI_BCAP_EXT_VS_INT_ANT_OFFSET 0 + +# define ANI_BCAP_GAL_ON_BOARD_MASK 0x2 +# define ANI_BCAP_GAL_ON_BOARD_OFFSET 1 + +# define ANI_BCAP_SDRAM_MASK 0x4 +# define ANI_BCAP_SDRAM_OFFSET 2 + +# define ANI_BCAP_NUM_TRANSMITTERS_MASK 0x8 +# define ANI_BCAP_NUM_TRANSMITTERS_OFFSET 3 + +# define ANI_BCAP_NUM_RECEIVERS_MASK 0x30 +# define ANI_BCAP_NUM_RECEIVERS_OFFSET 4 + +# define ANI_BCAP_RADIO_ON_MASK 0xC0 +# define ANI_BCAP_RADIO_ON_OFFSET 6 + +# define ANI_BCAP_LO_TYPE_MASK 0x300 +# define ANI_BCAP_LO_TYPE_OFFSET 8 + +# define ANI_BCAP_BB_CHIP_VER_MASK 0xC00 +# define ANI_BCAP_BB_CHIP_VER_OFFSET 10 + +# define ANI_BCAP_CYG_DATE_CODE_MASK 0xFF000 +# define ANI_BCAP_CYG_DATE_CODE_OFFSET 12 + +# define ANI_BCAP_RADIO_OFF 0 +# define ANI_BCAP_RADIO_ON 1 +# define ANI_BCAP_RADIO_ON_NOT_SUPPORTED 3 + + +/// WOW related structures +// SME -> PE <-> HAL +#define SIR_WOWL_BCAST_PATTERN_MAX_SIZE 128 +#define SIR_WOWL_BCAST_MAX_NUM_PATTERNS 16 + +// SME -> PE -> HAL - This is to add WOWL BCAST wake-up pattern. +// SME/HDD maintains the list of the BCAST wake-up patterns. +// This is a pass through message for PE +typedef struct sSirWowlAddBcastPtrn +{ + tANI_U8 ucPatternId; // Pattern ID + // Pattern byte offset from beginning of the 802.11 packet to start of the + // wake-up pattern + tANI_U8 ucPatternByteOffset; + tANI_U8 ucPatternSize; // Non-Zero Pattern size + tANI_U8 ucPattern[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern + tANI_U8 ucPatternMaskSize; // Non-zero pattern mask size + tANI_U8 ucPatternMask[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern mask + // Extra pattern data beyond 128 bytes + tANI_U8 ucPatternExt[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra Pattern + tANI_U8 ucPatternMaskExt[SIR_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra Pattern mask + tSirMacAddr bssId; // BSSID +} tSirWowlAddBcastPtrn, *tpSirWowlAddBcastPtrn; + + +// SME -> PE -> HAL - This is to delete WOWL BCAST wake-up pattern. +// SME/HDD maintains the list of the BCAST wake-up patterns. +// This is a pass through message for PE +typedef struct sSirWowlDelBcastPtrn +{ + /* Pattern ID of the wakeup pattern to be deleted */ + tANI_U8 ucPatternId; + tSirMacAddr bssId; // BSSID +}tSirWowlDelBcastPtrn, *tpSirWowlDelBcastPtrn; + + +// SME->PE: Enter WOWLAN parameters +typedef struct sSirSmeWowlEnterParams +{ + /* Enables/disables magic packet filtering */ + tANI_U8 ucMagicPktEnable; + + /* Magic pattern */ + tSirMacAddr magicPtrn; + + /* Enables/disables packet pattern filtering */ + tANI_U8 ucPatternFilteringEnable; + +#ifdef WLAN_WAKEUP_EVENTS + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + tANI_U8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + tANI_U8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + tANI_U8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + tANI_U8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + tANI_U8 ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + tSirMacAddr bssId; +} tSirSmeWowlEnterParams, *tpSirSmeWowlEnterParams; + + +// PE<->HAL: Enter WOWLAN parameters +typedef struct sSirHalWowlEnterParams +{ + /* Enables/disables magic packet filtering */ + tANI_U8 ucMagicPktEnable; + + /* Magic pattern */ + tSirMacAddr magicPtrn; + + /* Enables/disables packet pattern filtering in firmware. + Enabling this flag enables broadcast pattern matching + in Firmware. If unicast pattern matching is also desired, + ucUcastPatternFilteringEnable flag must be set tot true + as well + */ + tANI_U8 ucPatternFilteringEnable; + + /* Enables/disables unicast packet pattern filtering. + This flag specifies whether we want to do pattern match + on unicast packets as well and not just broadcast packets. + This flag has no effect if the ucPatternFilteringEnable + (main controlling flag) is set to false + */ + tANI_U8 ucUcastPatternFilteringEnable; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Channel Switch Action Frame. + */ + tANI_U8 ucWowChnlSwitchRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Deauthentication Frame. + */ + tANI_U8 ucWowDeauthRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Disassociation Frame. + */ + tANI_U8 ucWowDisassocRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it has missed + * consecutive beacons. This is a hardware register + * configuration (NOT a firmware configuration). + */ + tANI_U8 ucWowMaxMissedBeacons; + + /* This configuration is valid only when magicPktEnable=1. + * This is a timeout value in units of microsec. It requests + * hardware to unconditionally wake up after it has stayed + * in WoWLAN mode for some time. Set 0 to disable this feature. + */ + tANI_U8 ucWowMaxSleepUsec; + +#ifdef WLAN_WAKEUP_EVENTS + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + tANI_U8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + tANI_U8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + tANI_U8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + tANI_U8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + tANI_U8 ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + /* Status code to be filled by HAL when it sends + * SIR_HAL_WOWL_ENTER_RSP to PE. + */ + eHalStatus status; + + /*BSSID to find the current session + */ + tANI_U8 bssIdx; +} tSirHalWowlEnterParams, *tpSirHalWowlEnterParams; + +// PE<->HAL: Exit WOWLAN parameters +typedef struct sSirHalWowlExitParams +{ + /* Status code to be filled by HAL when it sends + * SIR_HAL_WOWL_EXIT_RSP to PE. + */ + eHalStatus status; + + /*BSSIDX to find the current session + */ + tANI_U8 bssIdx; +} tSirHalWowlExitParams, *tpSirHalWowlExitParams; + + +#define SIR_MAX_NAME_SIZE 64 +#define SIR_MAX_TEXT_SIZE 32 + +typedef struct sSirName { + v_U8_t num_name; + v_U8_t name[SIR_MAX_NAME_SIZE]; +} tSirName; + +typedef struct sSirText { + v_U8_t num_text; + v_U8_t text[SIR_MAX_TEXT_SIZE]; +} tSirText; + + +#define SIR_WPS_PROBRSP_VER_PRESENT 0x00000001 +#define SIR_WPS_PROBRSP_STATE_PRESENT 0x00000002 +#define SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT 0x00000004 +#define SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT 0x00000008 +#define SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT 0x00000010 +#define SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT 0x00000040 +#define SIR_WPS_PROBRSP_UUIDE_PRESENT 0x00000080 +#define SIR_WPS_PROBRSP_MANUFACTURE_PRESENT 0x00000100 +#define SIR_WPS_PROBRSP_MODELNAME_PRESENT 0x00000200 +#define SIR_WPS_PROBRSP_MODELNUMBER_PRESENT 0x00000400 +#define SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT 0x00000800 +#define SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT 0x00001000 +#define SIR_WPS_PROBRSP_DEVICENAME_PRESENT 0x00002000 +#define SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT 0x00004000 +#define SIR_WPS_PROBRSP_RF_BANDS_PRESENT 0x00008000 + + +typedef struct sSirWPSProbeRspIE { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t ResponseType; // Response type + v_U8_t UUID_E[16]; // Unique identifier of the AP. + tSirName Manufacture; + tSirText ModelName; + tSirText ModelNumber; + tSirText SerialNumber; + v_U32_t PrimaryDeviceCategory ; // Device Category ID: 1Computer, 2Input Device, ... + v_U8_t PrimaryDeviceOUI[4] ; // Vendor specific OUI for Device Sub Category + v_U32_t DeviceSubCategory ; // Device Sub Category ID: 1-PC, 2-Server if Device Category ID is computer + tSirText DeviceName; + v_U16_t ConfigMethod; // Configuaration method + v_U8_t RFBand; // RF bands available on the AP +} tSirWPSProbeRspIE; + +#define SIR_WPS_BEACON_VER_PRESENT 0x00000001 +#define SIR_WPS_BEACON_STATE_PRESENT 0x00000002 +#define SIR_WPS_BEACON_APSETUPLOCK_PRESENT 0x00000004 +#define SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT 0x00000008 +#define SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT 0x00000010 +#define SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define SIR_WPS_BEACON_UUIDE_PRESENT 0x00000080 +#define SIR_WPS_BEACON_RF_BANDS_PRESENT 0x00000100 + +typedef struct sSirWPSBeaconIE { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t UUID_E[16]; // Unique identifier of the AP. + v_U8_t RFBand; // RF bands available on the AP +} tSirWPSBeaconIE; + +#define SIR_WPS_ASSOCRSP_VER_PRESENT 0x00000001 +#define SIR_WPS_ASSOCRSP_RESPONSETYPE_PRESENT 0x00000002 + +typedef struct sSirWPSAssocRspIE { + v_U32_t FieldPresent; + v_U32_t Version; + v_U8_t ResposeType; +} tSirWPSAssocRspIE; + +typedef struct sSirAPWPSIEs { + tSirWPSProbeRspIE SirWPSProbeRspIE; /*WPS Set Probe Respose IE*/ + tSirWPSBeaconIE SirWPSBeaconIE; /*WPS Set Beacon IE*/ + tSirWPSAssocRspIE SirWPSAssocRspIE; /*WPS Set Assoc Response IE*/ +} tSirAPWPSIEs, *tpSiriAPWPSIEs; + +typedef struct sSirUpdateAPWPSIEsReq +{ + tANI_U16 messageType; // eWNI_SME_UPDATE_APWPSIE_REQ + tANI_U16 length; + tANI_U16 transactionId; //Transaction ID for cmd + tSirMacAddr bssId; // BSSID + tANI_U8 sessionId; //Session ID + tSirAPWPSIEs APWPSIEs; +} tSirUpdateAPWPSIEsReq, *tpSirUpdateAPWPSIEsReq; + +typedef struct sSirUpdateParams +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U8 ssidHidden; // Hide SSID +} tSirUpdateParams, *tpSirUpdateParams; + +//Beacon Interval +typedef struct sSirChangeBIParams +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U16 beaconInterval; // Beacon Interval + tSirMacAddr bssId; + tANI_U8 sessionId; // Session ID +} tSirChangeBIParams, *tpSirChangeBIParams; + +#ifdef WLAN_FEATURE_AP_HT40_24G +typedef struct sSirSetHT2040Mode +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 cbMode; + tSirMacAddr bssId; + tANI_U8 sessionId; // Session ID +} tSirSetHT2040Mode, *tpSirSetHT2040Mode; + +typedef struct sSirHT2040CoexInfoInd +{ + tANI_U16 messageType; // eWNI_SME_2040_COEX_IND + tANI_U16 length; + tANI_U8 sessionId; + tANI_U8 HT40MHzIntolerant; + tANI_U8 HT20MHzBssWidthReq; + tANI_U8 channel_num; + tANI_U8 HT2040BssIntoChanReport [1]; //variable +}tSirHT2040CoexInfoInd, *tpSirHT2040CoexInfoInd; +#endif + +typedef struct sSirOBSSHT40Param +{ + tANI_U16 OBSSScanPassiveDwellTime; + tANI_U16 OBSSScanActiveDwellTime; + tANI_U16 BSSChannelWidthTriggerScanInterval; + tANI_U16 OBSSScanPassiveTotalPerChannel; + tANI_U16 OBSSScanActiveTotalPerChannel; + tANI_U16 BSSWidthChannelTransitionDelayFactor; + tANI_U16 OBSSScanActivityThreshold; +}tSirOBSSHT40Param, *tpOBSSHT40Param; + +#define SIR_WPS_UUID_LEN 16 +#define SIR_WPS_PBC_WALK_TIME 120 // 120 Second + +typedef struct sSirWPSPBCSession { + struct sSirWPSPBCSession *next; + tSirMacAddr addr; + tANI_U8 uuid_e[SIR_WPS_UUID_LEN]; + tANI_TIMESTAMP timestamp; +} tSirWPSPBCSession; + +typedef struct sSirSmeGetWPSPBCSessionsReq +{ + tANI_U16 messageType; // eWNI_SME_GET_WPSPBC_SESSION_REQ + tANI_U16 length; + void *pUsrContext; + void *pSapEventCallback; + tSirMacAddr bssId; // BSSID + tSirMacAddr pRemoveMac; // MAC Address of STA in WPS Session to be removed +} tSirSmeGetWPSPBCSessionsReq, *tpSirSmeGetWPSPBCSessionsReq; + +typedef struct sSirWPSPBCProbeReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 probeReqIELen; + tANI_U8 probeReqIE[512]; +} tSirWPSPBCProbeReq, *tpSirWPSPBCProbeReq; + +// probereq from peer, when wsc is enabled +typedef struct sSirSmeProbeReqInd +{ + tANI_U16 messageType; // eWNI_SME_WPS_PBC_PROBE_REQ_IND + tANI_U16 length; + tANI_U8 sessionId; + tSirMacAddr bssId; + tSirWPSPBCProbeReq WPSPBCProbeReq; +} tSirSmeProbeReqInd, *tpSirSmeProbeReqInd; + +typedef struct sSirUpdateAPWPARSNIEsReq +{ + tANI_U16 messageType; // eWNI_SME_SET_APWPARSNIEs_REQ + tANI_U16 length; + tANI_U16 transactionId; //Transaction ID for cmd + tSirMacAddr bssId; // BSSID + tANI_U8 sessionId; //Session ID + tSirRSNie APWPARSNIEs; +} tSirUpdateAPWPARSNIEsReq, *tpSirUpdateAPWPARSNIEsReq; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define SIR_ROAM_MAX_CHANNELS 80 +#define SIR_ROAM_SCAN_MAX_PB_REQ_SIZE 450 +#define CHANNEL_LIST_STATIC 1 /* Occupied channel list remains static */ +#define CHANNEL_LIST_DYNAMIC_INIT 2 /* Occupied channel list can be learnt after init */ +#define CHANNEL_LIST_DYNAMIC_FLUSH 3 /* Occupied channel list can be learnt after flush */ +#define CHANNEL_LIST_DYNAMIC_UPDATE 4 /* Occupied channel list can be learnt after update */ +#define SIR_ROAM_SCAN_24G_DEFAULT_CH 1 +#define SIR_ROAM_SCAN_5G_DEFAULT_CH 36 + +/*Adaptive Thresholds to be used for FW based scanning*/ +#define LFR_SENSITIVITY_THR_1MBPS -89 +#define LFR_LOOKUP_THR_1MBPS -78 +#define LFR_SENSITIVITY_THR_2MBPS -87 +#define LFR_LOOKUP_THR_2MBPS -78 +#define LFR_SENSITIVITY_THR_5_5MBPS -86 +#define LFR_LOOKUP_THR_5_5MBPS -77 +#define LFR_SENSITIVITY_THR_11MBPS -85 +#define LFR_LOOKUP_THR_11MBPS -76 +#define LFR_SENSITIVITY_THR_6MBPS_2G -83 +#define LFR_LOOKUP_THR_6MBPS_2G -78 +#define LFR_SENSITIVITY_THR_6MBPS_5G -83 +#define LFR_LOOKUP_THR_6MBPS_5G -78 +#define LFR_SENSITIVITY_THR_12MBPS_2G -83 +#define LFR_LOOKUP_THR_12MBPS_2G -78 +#define LFR_SENSITIVITY_THR_12MBPS_5G -81 +#define LFR_LOOKUP_THR_12MBPS_5G -76 +#define LFR_SENSITIVITY_THR_24MBPS_2G -81 +#define LFR_LOOKUP_THR_24MBPS_2G -76 +#define LFR_SENSITIVITY_THR_24MBPS_5G -79 +#define LFR_LOOKUP_THR_24MBPS_5G -74 +#define LFR_SENSITIVITY_THR_DEFAULT 0 +#define LFR_LOOKUP_THR_DEFAULT -78 +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +// SME -> HAL - This is the host offload request. +#define SIR_IPV4_ARP_REPLY_OFFLOAD 0 +#define SIR_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 +#define SIR_IPV6_NS_OFFLOAD 2 +#define SIR_OFFLOAD_DISABLE 0 +#define SIR_OFFLOAD_ENABLE 1 +#define SIR_OFFLOAD_BCAST_FILTER_ENABLE 0x2 +#define SIR_OFFLOAD_MCAST_FILTER_ENABLE 0x4 +#define SIR_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE (SIR_OFFLOAD_ENABLE|SIR_OFFLOAD_BCAST_FILTER_ENABLE) +#define SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE (SIR_OFFLOAD_ENABLE|SIR_OFFLOAD_MCAST_FILTER_ENABLE) + +#ifdef WLAN_NS_OFFLOAD +typedef struct sSirNsOffloadReq +{ + tANI_U8 srcIPv6Addr[16]; + tANI_U8 selfIPv6Addr[16]; + //Only support 2 possible Network Advertisement IPv6 address + tANI_U8 targetIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][16]; + tANI_U8 selfMacAddr[6]; + tANI_U8 srcIPv6AddrValid; + tANI_U8 targetIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]; + tANI_U8 slotIdx; +} tSirNsOffloadReq, *tpSirNsOffloadReq; +#endif //WLAN_NS_OFFLOAD + +typedef struct sSirHostOffloadReq +{ + tANI_U8 offloadType; + tANI_U8 enableOrDisable; + union + { + tANI_U8 hostIpv4Addr [4]; + tANI_U8 hostIpv6Addr [16]; + } params; +#ifdef WLAN_NS_OFFLOAD + tSirNsOffloadReq nsOffloadInfo; +#endif //WLAN_NS_OFFLOAD + tSirMacAddr bssId; +} tSirHostOffloadReq, *tpSirHostOffloadReq; + +/* Packet Types. */ +#define SIR_KEEP_ALIVE_NULL_PKT 1 +#define SIR_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 + +/* Enable or disable offload. */ +#define SIR_KEEP_ALIVE_DISABLE 0 +#define SIR_KEEP_ALIVE_ENABLE 1 + +/* Keep Alive request. */ +typedef struct sSirKeepAliveReq +{ + v_U8_t packetType; + v_U32_t timePeriod; + tSirIpv4Addr hostIpv4Addr; + tSirIpv4Addr destIpv4Addr; + tSirMacAddr destMacAddr; + tSirMacAddr bssId; +} tSirKeepAliveReq, *tpSirKeepAliveReq; + +typedef struct sSirSmeAddStaSelfReq +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSirMacAddr selfMacAddr; + tVOS_CON_MODE currDeviceMode; +}tSirSmeAddStaSelfReq, *tpSirSmeAddStaSelfReq; + +typedef struct sSirSmeDelStaSelfReq +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSirMacAddr selfMacAddr; +}tSirSmeDelStaSelfReq, *tpSirSmeDelStaSelfReq; + +typedef struct sSirSmeAddStaSelfRsp +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U16 status; + tSirMacAddr selfMacAddr; +}tSirSmeAddStaSelfRsp, *tpSirSmeAddStaSelfRsp; + +typedef struct sSirSmeDelStaSelfRsp +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U16 status; + tSirMacAddr selfMacAddr; +}tSirSmeDelStaSelfRsp, *tpSirSmeDelStaSelfRsp; + +typedef enum DFSChanScanType +{ + DFS_CHNL_SCAN_DISABLED, + DFS_CHNL_SCAN_ENABLED_NORMAL, + DFS_CHNL_SCAN_ENABLED_ACTIVE +}eDFSChanScanType; + +/* Coex Indication defines - + should match WLAN_COEX_IND_DATA_SIZE + should match WLAN_COEX_IND_TYPE_DISABLE_HB_MONITOR + should match WLAN_COEX_IND_TYPE_ENABLE_HB_MONITOR */ +#define SIR_COEX_IND_DATA_SIZE (4) +#define SIR_COEX_IND_TYPE_DISABLE_HB_MONITOR (0) +#define SIR_COEX_IND_TYPE_ENABLE_HB_MONITOR (1) +#define SIR_COEX_IND_TYPE_SCAN_COMPROMISED (2) +#define SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED (3) +#define SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4 (4) +#define SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4 (5) +#define SIR_COEX_IND_TYPE_ENABLE_UAPSD (6) +#define SIR_COEX_IND_TYPE_DISABLE_UAPSD (7) +#define SIR_COEX_IND_TYPE_CXM_FEATURES_NOTIFICATION (8) +#define SIR_COEX_IND_TYPE_TDLS_ENABLE (6) +#define SIR_COEX_IND_TYPE_TDLS_DISABLE (7) +#define SIR_COEX_IND_TYPE_HID_CONNECTED_WLAN_CONNECTED_IN_2p4 (9) +#define SIR_COEX_IND_TYPE_HID_DISCONNECTED_WLAN_CONNECTED_IN_2p4 (10) + +typedef struct sSirSmeCoexInd +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U32 coexIndType; + tANI_U32 coexIndData[SIR_COEX_IND_DATA_SIZE]; +}tSirSmeCoexInd, *tpSirSmeCoexInd; + +typedef struct sSirSmeMgmtFrameInd +{ + tANI_U16 frameLen; + tANI_U32 rxChan; + tANI_U8 sessionId; + tANI_U8 frameType; + tANI_S8 rxRssi; + tANI_U8 frameBuf[1]; //variable +}tSirSmeMgmtFrameInd, *tpSirSmeMgmtFrameInd; + +#ifdef WLAN_FEATURE_11W +typedef struct sSirSmeUnprotMgmtFrameInd +{ + tANI_U8 sessionId; + tANI_U8 frameType; + tANI_U8 frameLen; + tANI_U8 frameBuf[1]; //variable +}tSirSmeUnprotMgmtFrameInd, *tpSirSmeUnprotMgmtFrameInd; +#endif + +#define SIR_IS_FULL_POWER_REASON_DISCONNECTED(eReason) \ + ( ( eSME_LINK_DISCONNECTED_BY_HDD == (eReason) ) || \ + ( eSME_LINK_DISCONNECTED_BY_OTHER == (eReason) ) || \ + (eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH == (eReason))) +#define SIR_IS_FULL_POWER_NEEDED_BY_HDD(eReason) \ + ( ( eSME_LINK_DISCONNECTED_BY_HDD == (eReason) ) || ( eSME_FULL_PWR_NEEDED_BY_HDD == (eReason) ) ) + +/* P2P Power Save Related */ +typedef struct sSirNoAParam +{ + tANI_U8 ctWindow:7; + tANI_U8 OppPS:1; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 singleNoADuration; + tANI_U8 psSelection; +}tSirNoAParam, *tpSirNoAParam; + +typedef void(*wlan_suspend_req_cb)(void *ptr, VOS_STATUS status); + +typedef struct sSirWlanSuspendParam +{ + tANI_U8 configuredMcstBcstFilterSetting; + wlan_suspend_req_cb wlan_sus_callback; + void *context; +}tSirWlanSuspendParam,*tpSirWlanSuspendParam; + +typedef struct sSirWlanResumeParam +{ + tANI_U8 configuredMcstBcstFilterSetting; +}tSirWlanResumeParam,*tpSirWlanResumeParam; + +typedef struct sSirWlanSetRxpFilters +{ + tANI_U8 configuredMcstBcstFilterSetting; + tANI_U8 setMcstBcstFilter; +}tSirWlanSetRxpFilters,*tpSirWlanSetRxpFilters; + + +typedef struct sSirUpdateCfgIntParam +{ + tANI_U32 cfgId; +}tSirUpdateCfgIntParam,*tpSirUpdateCfgIntParam; + +typedef struct +{ + //FW mail box address + uint64 logMailBoxAddr; + tANI_U32 status; + //Logging mail box version + tANI_U8 logMailBoxVer; + //Qshrink is enabled + tANI_U8 logCompressEnabled; + /* used to tell fwr mem dump size */ + tANI_U32 fw_mem_dump_max_size; + //Reserved for future purpose + tANI_U32 reserved1; + tANI_U32 reserved2; +}tAniLoggingInitRsp, *tpAniLoggingInitRsp; + +/** + * struct rsp_stats - arp packet stats + * @status: success or failure + * @tx_fw_cnt: tx packets count + * @tx_ack_cnt: tx acknowledgement count + */ +typedef struct { + uint32_t status; + uint16_t dad; + uint16_t tx_fw_cnt; + uint16_t tx_ack_cnt; + uint16_t rx_fw_cnt; +} rsp_stats; + +typedef void(*setArpStatsReqCb)(void *data, VOS_STATUS rsp); + +/** + * struct setArpStatsParams - set/reset arp stats + * @flag: enable/disable stats + * @pkt_type: type of packet(1 - arp) + * @ip_addr: subnet ipv4 address in case of encrypted packets + * @rsp_cb_fn: FW response callback api + * @data_ctx: parameter for callback api + */ +typedef struct { + uint8_t flag; + uint8_t pkt_type; + uint32_t ip_addr; + setArpStatsReqCb rsp_cb_fn; + void *data_ctx; +} setArpStatsParams, *psetArpStatsParams; + +typedef void(*getArpStatsReqCb)(void *data, rsp_stats *rsp); +/** + * struct getArpStatsParams - get arp stats from firmware + * @pkt_type: packet type(1 - ARP) + * @get_rsp_cb_fn: FW response callback api + * @data_ctx: parameter for callback api + */ +typedef struct { + uint8_t pkt_type; + getArpStatsReqCb get_rsp_cb_fn; + void *data_ctx; +} getArpStatsParams, *pgetArpStatsParams; + + +typedef void(*FWLoggingInitReqCb)(void *fwlogInitCbContext, tAniLoggingInitRsp *pRsp); +typedef void ( *tGetFrameLogCallback) (void *pContext); +typedef void(*RssiMonitorReqCb)(void *rssiMonitorCbContext, VOS_STATUS status); +typedef void(*pktFilterReqCb)(void *data, tANI_U32 status); +typedef void(*dhcp_offload_req_cb)(void *rssiMonitorCbContext, + VOS_STATUS status); +typedef void(*mdns_enable_req_cb)(void *mdns_enable_cb_context, + VOS_STATUS status); +typedef void(*mdns_fqdn_req_cb)(void *mdns_fqdn_cb_context, VOS_STATUS status); +typedef void(*mdns_resp_req_cb)(void *mdns_resp_cb_context, VOS_STATUS status); + +typedef struct sAniGetFrameLogReq +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tANI_U8 getFrameLogCmdFlag; +} tAniGetFrameLogReq, *tpAniGetFrameLogReq; + +/** + * struct s_ani_set_tx_max_pwr - Req params to set max tx power + * @bssid: bssid to set the power cap for + * @self_mac_addr:self mac address + * @power: power to set in dB + */ +struct s_ani_set_tx_max_pwr +{ + tSirMacAddr bssid; + tSirMacAddr self_sta_mac_addr; + tPowerdBm power; +}; + + + +typedef struct sSirFWLoggingInitParam +{ + tANI_U8 enableFlag; + tANI_U8 frameType; + tANI_U8 frameSize; + tANI_U8 bufferMode; + tANI_U8 continuousFrameLogging; + tANI_U8 minLogBufferSize; + tANI_U8 maxLogBufferSize; + FWLoggingInitReqCb fwlogInitCallback; + void *fwlogInitCbContext; +}tSirFWLoggingInitParam,*tpSirFWLoggingInitParam; + +/** + * struct sir_allowed_action_frames - Parameters to set Allowed action frames + * @bitmask: Bits to convey the allowed action frames + * @reserved: For future use + */ +struct sir_allowed_action_frames { + uint32_t bitmask; + uint32_t reserved; +}; + +/* + * struct rssi_monitor_req - rssi monitoring + * @request_id: request id + * @session_id: session id + * @min_rssi: minimum rssi + * @max_rssi: maximum rssi + * @control: flag to indicate start or stop + */ +typedef struct sSirRssiMonitorReq +{ + tANI_U32 requestId; + tANI_U32 sessionId; + tANI_S8 minRssi; + tANI_S8 maxRssi; + tANI_U8 currentBssId[6]; + RssiMonitorReqCb rssiMonitorCallback; + void *rssiMonitorCbContext; +}tSirRssiMonitorReq, *tpSirRssiMonitorReq; + + +/** + * struct rssi_breach_event - rssi breached event structure + * @request_id: request id + * @curr_rssi: current rssi + * @curr_bssid: current bssid + */ +struct rssi_breach_event { + tANI_U32 request_id; + v_MACADDR_t curr_bssid; + tANI_S8 curr_rssi; +}; + +typedef struct sSirFatalEventLogsReqParam +{ + tANI_U32 reason_code; +}tSirFatalEventLogsReqParam, *tpSirFatalEventLogsReqParam; + +#ifdef FEATURE_WLAN_SCAN_PNO +// +// PNO Messages +// + +// Set PNO +#define SIR_PNO_MAX_NETW_CHANNELS 26 +#define SIR_PNO_MAX_NETW_CHANNELS_EX 60 +#define SIR_PNO_MAX_SUPP_NETWORKS 16 +#define SIR_PNO_MAX_SCAN_TIMERS 10 + +/*size based of dot11 declaration without extra IEs as we will not carry those for PNO*/ +#define SIR_PNO_MAX_PB_REQ_SIZE 450 + +#define SIR_PNO_24G_DEFAULT_CH 1 +#define SIR_PNO_5G_DEFAULT_CH 36 + +typedef enum +{ + SIR_PNO_MODE_IMMEDIATE, + SIR_PNO_MODE_ON_SUSPEND, + SIR_PNO_MODE_ON_RESUME, + SIR_PNO_MODE_MAX +} eSirPNOMode; + +typedef struct +{ + tSirMacSSid ssId; + tANI_U32 authentication; + tANI_U32 encryption; + tANI_U32 bcastNetwType; + tANI_U8 ucChannelCount; + tANI_U8 aChannels[SIR_PNO_MAX_NETW_CHANNELS_EX]; + tANI_U8 rssiThreshold; +} tSirNetworkType; + +typedef struct +{ + tANI_U32 uTimerValue; + tANI_U32 uTimerRepeat; +}tSirScanTimer; + +typedef struct +{ + tANI_U8 ucScanTimersCount; + tSirScanTimer aTimerValues[SIR_PNO_MAX_SCAN_TIMERS]; +} tSirScanTimersType; + +/*Pref Net Req status */ +typedef void(*PNOReqStatusCb)(void *callbackContext, VOS_STATUS status); + + +typedef struct sSirPNOScanReq +{ + tANI_U8 enable; + PNOReqStatusCb statusCallback; + void *callbackContext; + eSirPNOMode modePNO; + tANI_U8 ucNetworksCount; + tSirNetworkType *aNetworks; + tSirScanTimersType scanTimers; + + /*added by SME*/ + tANI_U16 us24GProbeTemplateLen; + tANI_U8 *p24GProbeTemplate; + tANI_U16 us5GProbeTemplateLen; + tANI_U8 *p5GProbeTemplate; +} tSirPNOScanReq, *tpSirPNOScanReq; + +typedef struct sSirSetRSSIFilterReq +{ + tANI_U8 rssiThreshold; +} tSirSetRSSIFilterReq, *tpSirSetRSSIFilterReq; + + +// Update Scan Params +typedef struct { + tANI_U8 b11dEnabled; + tANI_U8 b11dResolved; + tANI_U8 ucChannelCount; + tANI_U8 aChannels[SIR_PNO_MAX_NETW_CHANNELS_EX]; + tANI_U16 usPassiveMinChTime; + tANI_U16 usPassiveMaxChTime; + tANI_U16 usActiveMinChTime; + tANI_U16 usActiveMaxChTime; + tANI_U8 ucCBState; +} tSirUpdateScanParams, * tpSirUpdateScanParams; + +// Preferred Network Found Indication +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + /* Network that was found with the highest RSSI*/ + tSirMacSSid ssId; + /* Indicates the RSSI */ + tANI_U8 rssi; + /* Length of the beacon or probe response + * corresponding to the candidate found by PNO */ + tANI_U32 frameLength; + /* Index to memory location where the contents of + * beacon or probe response frame will be copied */ + tANI_U8 data[1]; +} tSirPrefNetworkFoundInd, *tpSirPrefNetworkFoundInd; +#endif //FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define SIR_PER_ROAM_MAX_AP_CNT 20 +#define SIR_PER_ROAM_MAX_CANDIDATE_CNT 32 +typedef struct __attribute__((packed)) +{ + tANI_U8 channelNumber; + tANI_U8 channelCCA; + tANI_U8 otherApCount; + tANI_S8 otherApRssi[SIR_PER_ROAM_MAX_AP_CNT]; +} tSirCandidateChanInfo, * tpSirCandidateChanInfo; + +typedef struct sPERRoamScanStart +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tANI_U8 start; +} tPERRoamScanStart, *tpPERRoamScanStart; + +typedef struct sSirRoamAPInfo +{ + tSirMacAddr bssAddr; + unsigned int timeStamp; +} tSirRoamAPInfo, *tpSirRoamAPInfo; + +typedef struct __attribute__((packed)) +{ + tANI_U32 candidateCount; + tSirCandidateChanInfo channelInfo[SIR_PER_ROAM_MAX_CANDIDATE_CNT]; +} tSirPerRoamScanResult, * tpSirPerRoamScanResult; + +typedef struct +{ + tSirMacSSid ssId; + tANI_U8 currAPbssid[WNI_CFG_BSSID_LEN]; + tANI_U32 authentication; + tANI_U8 encryption; + tANI_U8 mcencryption; + tANI_U8 ChannelCount; + tANI_U8 ChannelCache[SIR_ROAM_MAX_CHANNELS]; + +} tSirRoamNetworkType; + +typedef struct SirMobilityDomainInfo +{ + tANI_U8 mdiePresent; + tANI_U16 mobilityDomain; +} tSirMobilityDomainInfo; + +typedef struct sSirRoamOffloadScanReq +{ + eAniBoolean RoamScanOffloadEnabled; + eAniBoolean MAWCEnabled; + tANI_S8 LookupThreshold; + tANI_S8 RxSensitivityThreshold; + tANI_U8 RoamRssiDiff; + tANI_U8 ChannelCacheType; + tANI_U8 Command; + tANI_U8 StartScanReason; + tANI_U16 NeighborScanTimerPeriod; + tANI_U16 NeighborRoamScanRefreshPeriod; + tANI_U16 NeighborScanChannelMinTime; + tANI_U16 NeighborScanChannelMaxTime; + tANI_U16 EmptyRefreshScanPeriod; + tANI_U8 ValidChannelCount; + tANI_U8 ValidChannelList[SIR_ROAM_MAX_CHANNELS]; + eAniBoolean IsESEEnabled; + tANI_U16 us24GProbeTemplateLen; + tANI_U8 p24GProbeTemplate[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; + tANI_U16 us5GProbeTemplateLen; + tANI_U8 p5GProbeTemplate[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; + tANI_U8 nProbes; + tANI_U16 HomeAwayTime; + tANI_U8 WeakZoneRssiThresholdForRoam; + tSirRoamNetworkType ConnectedNetwork; + tSirMobilityDomainInfo MDID; +} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq; + +/** + * struct sSirPERRoamOffloadScanReq - Offload PER config params + * @sessionId: session id + * @rateUpThreshold: rate at which to stop monitoring the rate + * @rateDownThreshold: rate at which to start monitoring + * @isPERRoamCCAEnabled: CCA sensing is enabled or disabled + * @waitPeriodForNextPERScan: time to wait before start monitoring again once a + * scan has been triggered + * @PERtimerThreshold: time to collect stats to trigger roam scan + * @PERroamTriggerPercent: minimum percentage of packets needs to be below + * rateDownThreshold to trigger a roam scan + */ +typedef struct sSirPERRoamOffloadScanReq +{ + tANI_U16 sessionId; + tANI_U16 rateUpThreshold; + tANI_U16 rateDownThreshold; + tANI_U16 isPERRoamCCAEnabled; + tANI_U32 waitPeriodForNextPERScan; + tANI_U32 PERtimerThreshold; + tANI_U32 PERroamTriggerPercent; + tANI_S16 PERRoamFullScanThreshold; +} tSirPERRoamOffloadScanReq, *tpSirPERRoamOffloadScanReq; + +typedef struct sSirPERRoamTriggerScanReq +{ + tANI_BOOLEAN roamScanReq; +} tSirPERRoamTriggerScanReq, *tpSirPERRoamTriggerScanReq; + +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#define SIR_NOCHANGE_POWER_VALUE 0xFFFFFFFF + +//Power Parameters Type +typedef enum +{ + eSIR_IGNORE_DTIM = 1, + eSIR_LISTEN_INTERVAL = 2, + eSIR_MCAST_BCAST_FILTER = 3, + eSIR_ENABLE_BET = 4, + eSIR_BET_INTERVAL = 5 +}tPowerParamType; + +//Power Parameters Value s +typedef struct +{ + /* Ignore DTIM */ + tANI_U32 uIgnoreDTIM; + + /* DTIM Period */ + tANI_U32 uDTIMPeriod; + + /* Listen Interval */ + tANI_U32 uListenInterval; + + /* Broadcast Multicas Filter */ + tANI_U32 uBcastMcastFilter; + + /* Beacon Early Termination */ + tANI_U32 uEnableBET; + + /* Beacon Early Termination Interval */ + tANI_U32 uBETInterval; + + /* MAX LI for modulated DTIM */ + tANI_U32 uMaxLIModulatedDTIM; + +}tSirSetPowerParamsReq, *tpSirSetPowerParamsReq; + +typedef struct sSirTxPerTrackingParam +{ + tANI_U8 ucTxPerTrackingEnable; /* 0: disable, 1:enable */ + tANI_U8 ucTxPerTrackingPeriod; /* Check period, unit is sec. Once tx_stat_chk enable, firmware will check PER in this period periodically */ + tANI_U8 ucTxPerTrackingRatio; /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. for example, 5 means 50% TX failed rate, default is 5. If current TX packet failed rate bigger than this ratio then firmware send WLC_E_TX_STAT_ERROR event to driver */ + tANI_U32 uTxPerTrackingWatermark; /* A watermark of check number, once the tx packet exceed this number, we do the check, default is 5 */ +}tSirTxPerTrackingParam, *tpSirTxPerTrackingParam; + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/*--------------------------------------------------------------------------- + Packet Filtering Parameters +---------------------------------------------------------------------------*/ +#define SIR_IPV4_ADDR_LEN 4 +#define SIR_MAC_ADDR_LEN 6 +#define SIR_MAX_FILTER_TEST_DATA_LEN 8 +#define SIR_MAX_NUM_MULTICAST_ADDRESS 240 +#define SIR_MAX_NUM_FILTERS 20 +#define SIR_MAX_NUM_TESTS_PER_FILTER 10 + +// +// Receive Filter Parameters +// +typedef enum +{ + SIR_RCV_FILTER_TYPE_INVALID, + SIR_RCV_FILTER_TYPE_FILTER_PKT, + SIR_RCV_FILTER_TYPE_BUFFER_PKT, + SIR_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}eSirReceivePacketFilterType; + +typedef enum +{ + SIR_FILTER_HDR_TYPE_INVALID, + SIR_FILTER_HDR_TYPE_MAC, + SIR_FILTER_HDR_TYPE_ARP, + SIR_FILTER_HDR_TYPE_IPV4, + SIR_FILTER_HDR_TYPE_IPV6, + SIR_FILTER_HDR_TYPE_UDP, + SIR_FILTER_HDR_TYPE_MAX +}eSirRcvPktFltProtocolType; + +typedef enum +{ + SIR_FILTER_CMP_TYPE_INVALID, + SIR_FILTER_CMP_TYPE_EQUAL, + SIR_FILTER_CMP_TYPE_MASK_EQUAL, + SIR_FILTER_CMP_TYPE_NOT_EQUAL, + SIR_FILTER_CMP_TYPE_MASK_NOT_EQUAL, + SIR_FILTER_CMP_TYPE_MAX +}eSirRcvPktFltCmpFlagType; + +typedef struct sSirRcvPktFilterFieldParams +{ + eSirRcvPktFltProtocolType protocolLayer; + eSirRcvPktFltCmpFlagType cmpFlag; + /* Length of the data to compare */ + tANI_U16 dataLength; + /* from start of the respective frame header */ + tANI_U8 dataOffset; + /* Reserved field */ + tANI_U8 reserved; + /* Data to compare */ + tANI_U8 compareData[SIR_MAX_FILTER_TEST_DATA_LEN]; + /* Mask to be applied on the received packet data before compare */ + tANI_U8 dataMask[SIR_MAX_FILTER_TEST_DATA_LEN]; +}tSirRcvPktFilterFieldParams, *tpSirRcvPktFilterFieldParams; + +typedef struct sSirRcvPktFilterCfg +{ + tANI_U8 filterId; + eSirReceivePacketFilterType filterType; + tANI_U32 numFieldParams; + tANI_U32 coalesceTime; + tSirMacAddr selfMacAddr; + tSirMacAddr bssId; //Bssid of the connected AP + tSirRcvPktFilterFieldParams paramsData[SIR_MAX_NUM_TESTS_PER_FILTER]; +}tSirRcvPktFilterCfgType, *tpSirRcvPktFilterCfgType; + +// +// Filter Packet Match Count Parameters +// +typedef struct sSirRcvFltPktMatchCnt +{ + tANI_U8 filterId; + tANI_U32 matchCnt; +} tSirRcvFltPktMatchCnt, tpSirRcvFltPktMatchCnt; + +typedef struct sSirRcvFltPktMatchRsp +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + + /* Success or Failure */ + tANI_U32 status; + tSirRcvFltPktMatchCnt filterMatchCnt[SIR_MAX_NUM_FILTERS]; + tSirMacAddr bssId; +} tSirRcvFltPktMatchRsp, *tpSirRcvFltPktMatchRsp; + +// +// Receive Filter Clear Parameters +// +typedef struct sSirRcvFltPktClearParam +{ + tANI_U32 status; /* only valid for response message */ + tANI_U8 filterId; + tSirMacAddr selfMacAddr; + tSirMacAddr bssId; + pktFilterReqCb pktFilterCallback; + void *cbCtx; +}tSirRcvFltPktClearParam, *tpSirRcvFltPktClearParam; + +// +// Multicast Address List Parameters +// +typedef struct sSirRcvFltMcAddrList +{ + tANI_U32 ulMulticastAddrCnt; + tSirMacAddr multicastAddr[SIR_MAX_NUM_MULTICAST_ADDRESS]; + tSirMacAddr selfMacAddr; + tSirMacAddr bssId; +} tSirRcvFltMcAddrList, *tpSirRcvFltMcAddrList; +#endif // WLAN_FEATURE_PACKET_FILTERING + +// +// Generic version information +// +typedef struct +{ + tANI_U8 revision; + tANI_U8 version; + tANI_U8 minor; + tANI_U8 major; +} tSirVersionType; + +typedef struct sAniBtAmpLogLinkReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; //sme Session Id + void *btampHandle; //AMP context + +} tAniBtAmpLogLinkReq, *tpAniBtAmpLogLinkReq; + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/*--------------------------------------------------------------------------- +* WDA_GTK_OFFLOAD_REQ +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U32 ulFlags; /* optional flags */ + tANI_U8 aKCK[16]; /* Key confirmation key */ + tANI_U8 aKEK[16]; /* key encryption key */ + tANI_U64 ullKeyReplayCounter; /* replay counter */ + tSirMacAddr bssId; +} tSirGtkOffloadParams, *tpSirGtkOffloadParams; + +/*--------------------------------------------------------------------------- +* WDA_GTK_OFFLOAD_GETINFO_REQ +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + + tANI_U32 ulStatus; /* success or failure */ + tANI_U64 ullKeyReplayCounter; /* current replay counter value */ + tANI_U32 ulTotalRekeyCount; /* total rekey attempts */ + tANI_U32 ulGTKRekeyCount; /* successful GTK rekeys */ + tANI_U32 ulIGTKRekeyCount; /* successful iGTK rekeys */ + tSirMacAddr bssId; +} tSirGtkOffloadGetInfoRspParams, *tpSirGtkOffloadGetInfoRspParams; +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +/*--------------------------------------------------------------------------- + tSirWakeReasonInd +---------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tANI_U32 ulReason; /* see tWakeReasonType */ + tANI_U32 ulReasonArg; /* argument specific to the reason type */ + tANI_U32 ulStoredDataLen; /* length of optional data stored in this message, in case + HAL truncates the data (i.e. data packets) this length + will be less than the actual length */ + tANI_U32 ulActualDataLen; /* actual length of data */ + tANI_U8 aDataStart[1]; /* variable length start of data (length == storedDataLen) + see specific wake type */ +} tSirWakeReasonInd, *tpSirWakeReasonInd; +#endif // WLAN_WAKEUP_EVENTS + +/*--------------------------------------------------------------------------- + sAniSetTmLevelReq +---------------------------------------------------------------------------*/ +typedef struct sAniSetTmLevelReq +{ + tANI_U16 tmMode; + tANI_U16 newTmLevel; +} tAniSetTmLevelReq, *tpAniSetTmLevelReq; + +#ifdef FEATURE_WLAN_TDLS +/* TDLS Request struct SME-->PE */ +typedef struct sSirTdlsSendMgmtReq +{ + tANI_U16 messageType; // eWNI_SME_TDLS_DISCOVERY_START_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U8 reqType; + tANI_U8 dialog; + tANI_U16 statusCode; + tANI_U8 responder; + tANI_U32 peerCapability; + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; + tANI_U8 addIe[1]; //Variable lenght. Dont add any field after this. +} tSirTdlsSendMgmtReq, *tpSirSmeTdlsSendMgmtReq ; + +typedef enum TdlsAddOper +{ + TDLS_OPER_NONE, + TDLS_OPER_ADD, + TDLS_OPER_UPDATE +} eTdlsAddOper; + +/* TDLS Request struct SME-->PE */ +typedef struct sSirTdlsAddStaReq +{ + tANI_U16 messageType; // eWNI_SME_TDLS_DISCOVERY_START_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + eTdlsAddOper tdlsAddOper; + tSirMacAddr peerMac; + tANI_U16 capability; + tANI_U8 extn_capability[SIR_MAC_MAX_EXTN_CAP]; + tANI_U8 supported_rates_length; + tANI_U8 supported_rates[SIR_MAC_MAX_SUPP_RATES]; + tANI_U8 htcap_present; + tSirHTCap htCap; + tANI_U8 vhtcap_present; + tSirVHTCap vhtCap; + tANI_U8 uapsd_queues; + tANI_U8 max_sp; +} tSirTdlsAddStaReq, *tpSirSmeTdlsAddStaReq ; + +/* TDLS Response struct PE-->SME */ +typedef struct sSirTdlsAddStaRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tSirResultCodes statusCode; + tSirMacAddr peerMac; + tANI_U8 sessionId; // Session ID + tANI_U16 staId ; + tANI_U16 staType ; + tANI_U8 ucastSig; + tANI_U8 bcastSig; + eTdlsAddOper tdlsAddOper; +} tSirTdlsAddStaRsp ; + +/* TDLS Request struct SME-->PE */ +typedef struct +{ + tANI_U16 messageType; // eWNI_SME_TDLS_LINK_ESTABLISH_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U8 uapsdQueues; // Peer's uapsd Queues Information + tANI_U8 maxSp; // Peer's Supported Maximum Service Period + tANI_U8 isBufSta; // Does Peer Support as Buffer Station. + tANI_U8 isOffChannelSupported; // Does Peer Support as TDLS Off Channel. + tANI_U8 isResponder; // Is Peer a responder. + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; + tANI_U8 supportedChannelsLen; + tANI_U8 supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supportedOperClassesLen; + tANI_U8 supportedOperClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +}tSirTdlsLinkEstablishReq, *tpSirTdlsLinkEstablishReq; + +/* TDLS Request struct SME-->PE */ +typedef struct +{ + tANI_U16 messageType; // eWNI_SME_TDLS_LINK_ESTABLISH_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMac; + tANI_U16 sta_idx; +}tSirTdlsLinkEstablishReqRsp, *tpSirTdlsLinkEstablishReqRsp; + +/* TDLS Request struct SME-->PE */ +typedef struct sSirTdlsDelStaReq +{ + tANI_U16 messageType; // eWNI_SME_TDLS_DISCOVERY_START_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; +} tSirTdlsDelStaReq, *tpSirSmeTdlsDelStaReq ; +/* TDLS Response struct PE-->SME */ +typedef struct sSirTdlsDelStaRsp +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirResultCodes statusCode; + tSirMacAddr peerMac; + tANI_U16 staId; +} tSirTdlsDelStaRsp, *tpSirTdlsDelStaRsp; +/* TDLS Delete Indication struct PE-->SME */ +typedef struct sSirTdlsDelStaInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tSirMacAddr peerMac; + tANI_U16 staId; + tANI_U16 reasonCode; +} tSirTdlsDelStaInd, *tpSirTdlsDelStaInd; +typedef struct sSirTdlsDelAllPeerInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID +} tSirTdlsDelAllPeerInd, *tpSirTdlsDelAllPeerInd; +typedef struct sSirMgmtTxCompletionInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U32 txCompleteStatus; +} tSirMgmtTxCompletionInd, *tpSirMgmtTxCompletionInd; + +//tdlsoffchan +/* TDLS Channel Switch struct SME-->PE */ +typedef struct +{ + tANI_U16 messageType; //eWNI_SME_TDLS_CHANNEL_SWITCH_REQ + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tANI_U8 tdlsOffCh; // Target Off Channel + tANI_U8 tdlsOffChBwOffset;// Target Off Channel Bandwidth offset + tANI_U8 tdlsSwMode; // TDLS Off Channel Mode + tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID + tSirMacAddr peerMac; +}tSirTdlsChanSwitch, *tpSirTdlsChanSwitch; + +/* TDLS Resp struct */ +typedef struct +{ + tANI_U16 messageType; // eWNI_SME_TDLS_CHANNEL_SWITCH_RSP + tANI_U16 length; + tANI_U8 sessionId; // Session ID + tANI_U16 transactionId; // Transaction ID for cmd + tSirResultCodes statusCode; + tSirMacAddr peerMac; + tANI_U16 sta_idx; +}tSirTdlsChanSwitchReqRsp, *tpSirTdlsChanSwitchReqRsp; +#endif /* FEATURE_WLAN_TDLS */ + +typedef struct sSirActiveModeSetBcnFilterReq +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 seesionId; + tSirMacAddr bssid; +} tSirSetActiveModeSetBncFilterReq, *tpSirSetActiveModeSetBncFilterReq; + +typedef enum +{ + HT40_OBSS_SCAN_PARAM_START, + HT40_OBSS_SCAN_PARAM_UPDATE +}tHT40OBssScanCmdType; + +typedef struct sSirSmeHT40StopOBSSScanInd +{ + tANI_U16 messageType; + tANI_U16 length; + tANI_U8 seesionId; + tSirMacAddr bssid; +} tSirSmeHT40OBSSStopScanInd, *tpSirSmeHT40OBSSStopScanInd; + +typedef struct sSirSmeHT40OBSSScanInd +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr peerMacAddr; +} tSirSmeHT40OBSSScanInd, *tpSirSmeHT40OBSSScanInd; + +typedef struct sSirHT40OBSSScanInd +{ + tHT40OBssScanCmdType cmdType; + tSirScanType scanType; + tANI_U16 OBSSScanPassiveDwellTime; // In TUs + tANI_U16 OBSSScanActiveDwellTime; // In TUs + tANI_U16 BSSChannelWidthTriggerScanInterval; // In seconds + tANI_U16 OBSSScanPassiveTotalPerChannel; // In TU + tANI_U16 OBSSScanActiveTotalPerChannel; // In TUs + tANI_U16 BSSWidthChannelTransitionDelayFactor; + tANI_U16 OBSSScanActivityThreshold; + tANI_U8 selfStaIdx; + tANI_U8 bssIdx; + tANI_U8 fortyMHZIntolerent; + tANI_U8 channelCount; + tANI_U8 channels[SIR_ROAM_MAX_CHANNELS]; + tANI_U8 currentOperatingClass; + tANI_U16 ieFieldLen; + tANI_U8 ieField[SIR_ROAM_SCAN_MAX_PB_REQ_SIZE]; +} tSirHT40OBSSScanInd, *tpSirHT40OBSSScanInd; + + +//Reset AP Caps Changed +typedef struct sSirResetAPCapsChange +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr bssId; +} tSirResetAPCapsChange, *tpSirResetAPCapsChange; +/// Definition for Candidate found indication from FW +typedef struct sSirSmeCandidateFoundInd +{ + tANI_U16 messageType; // eWNI_SME_CANDIDATE_FOUND_IND + tANI_U16 length; + tANI_U8 sessionId; // Session Identifier +} tSirSmeCandidateFoundInd, *tpSirSmeCandidateFoundInd; + +#ifdef WLAN_FEATURE_11W +typedef struct sSirWlanExcludeUnencryptParam +{ + tANI_BOOLEAN excludeUnencrypt; + tSirMacAddr bssId; +}tSirWlanExcludeUnencryptParam,*tpSirWlanExcludeUnencryptParam; +#endif + +typedef struct sAniHandoffReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 sessionId; + tANI_U8 bssid[WNI_CFG_BSSID_LEN]; + tANI_U8 channel; +#ifndef QCA_WIFI_ISOC + tANI_U8 handoff_src; +#endif +} tAniHandoffReq, *tpAniHandoffReq; + +typedef struct sSirScanOffloadReq { + tANI_U8 sessionId; + tSirMacAddr bssId; + tANI_U8 numSsid; + tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID]; + tANI_U8 hiddenSsid; + tSirMacAddr selfMacAddr; + tSirBssType bssType; + tANI_U8 dot11mode; + tSirScanType scanType; + tANI_U32 minChannelTime; + tANI_U32 maxChannelTime; + tANI_BOOLEAN p2pSearch; + tANI_U16 uIEFieldLen; + tANI_U16 uIEFieldOffset; + tSirChannelList channelList; + /*----------------------------- + sSirScanOffloadReq.... + ----------------------------- + uIEFieldLen + ----------------------------- + uIEFieldOffset ----+ + ----------------------------- | + channelList.numChannels | + ----------------------------- | + ... variable size up to | + channelNumber[numChannels-1] | + This can be zero, if | + numChannel is zero. | + ----------------------------- <--+ + ... variable size uIEField + up to uIEFieldLen (can be 0) + -----------------------------*/ +} tSirScanOffloadReq, *tpSirScanOffloadReq; + +typedef enum sSirScanEventType { + SCAN_EVENT_STARTED=0x1, /* Scan command accepted by FW */ + SCAN_EVENT_COMPLETED=0x2, /* Scan has been completed by FW */ + SCAN_EVENT_BSS_CHANNEL=0x4, /* FW is going to move to HOME channel */ + SCAN_EVENT_FOREIGN_CHANNEL = 0x8,/* FW is going to move to FORIEGN channel */ + SCAN_EVENT_DEQUEUED=0x10, /* scan request got dequeued */ + SCAN_EVENT_PREEMPTED=0x20, /* preempted by other high priority scan */ + SCAN_EVENT_START_FAILED=0x40, /* scan start failed */ + SCAN_EVENT_RESTARTED=0x80, /*scan restarted*/ + SCAN_EVENT_MAX=0x8000 +} tSirScanEventType; + +typedef struct sSirScanOffloadEvent{ + tSirScanEventType event; + tSirResultCodes reasonCode; + tANI_U32 chanFreq; + tANI_U32 requestor; + tANI_U32 scanId; +} tSirScanOffloadEvent, *tpSirScanOffloadEvent; + +typedef struct sSirUpdateChanParam +{ + tANI_U8 chanId; + tANI_U8 pwr; + tANI_BOOLEAN dfsSet; +} tSirUpdateChanParam, *tpSirUpdateChanParam; + +typedef struct sSirUpdateChan +{ + tANI_U8 regId; + tANI_U8 numChan; + tSirUpdateChanParam chanParam[1]; +} tSirUpdateChanList, *tpSirUpdateChanList; + +#ifdef FEATURE_WLAN_LPHB +#define SIR_LPHB_FILTER_LEN 64 + +typedef enum +{ + LPHB_SET_EN_PARAMS_INDID, + LPHB_SET_TCP_PARAMS_INDID, + LPHB_SET_TCP_PKT_FILTER_INDID, + LPHB_SET_UDP_PARAMS_INDID, + LPHB_SET_UDP_PKT_FILTER_INDID, + LPHB_SET_NETWORK_INFO_INDID, +} LPHBIndType; + +typedef struct sSirLPHBEnableStruct +{ + v_U8_t enable; + v_U8_t item; + v_U8_t session; +} tSirLPHBEnableStruct; + +typedef struct sSirLPHBTcpParamStruct +{ + v_U32_t srv_ip; + v_U32_t dev_ip; + v_U16_t src_port; + v_U16_t dst_port; + v_U16_t timeout; + v_U8_t session; + tSirMacAddr gateway_mac; + uint16 timePeriodSec; // in seconds + uint32 tcpSn; +} tSirLPHBTcpParamStruct; + +typedef struct sSirLPHBTcpFilterStruct +{ + v_U16_t length; + v_U8_t offset; + v_U8_t session; + v_U8_t filter[SIR_LPHB_FILTER_LEN]; +} tSirLPHBTcpFilterStruct; + +typedef struct sSirLPHBUdpParamStruct +{ + v_U32_t srv_ip; + v_U32_t dev_ip; + v_U16_t src_port; + v_U16_t dst_port; + v_U16_t interval; + v_U16_t timeout; + v_U8_t session; + tSirMacAddr gateway_mac; +} tSirLPHBUdpParamStruct; + +typedef struct sSirLPHBUdpFilterStruct +{ + v_U16_t length; + v_U8_t offset; + v_U8_t session; + v_U8_t filter[SIR_LPHB_FILTER_LEN]; +} tSirLPHBUdpFilterStruct; + +typedef struct sSirLPHBReq +{ + v_U16_t cmd; + v_U16_t dummy; + union + { + tSirLPHBEnableStruct lphbEnableReq; + tSirLPHBTcpParamStruct lphbTcpParamReq; + tSirLPHBTcpFilterStruct lphbTcpFilterReq; + tSirLPHBUdpParamStruct lphbUdpParamReq; + tSirLPHBUdpFilterStruct lphbUdpFilterReq; + } params; +} tSirLPHBReq; + +typedef struct sSirLPHBInd +{ + v_U8_t sessionIdx; + v_U8_t protocolType; /*TCP or UDP*/ + v_U8_t eventReason; +} tSirLPHBInd; +#endif /* FEATURE_WLAN_LPHB */ + +typedef struct sSirAddPeriodicTxPtrn +{ + /* MAC Address for the adapter */ + tSirMacAddr macAddress; + + tANI_U8 ucPtrnId; // Pattern ID + tANI_U16 ucPtrnSize; // Pattern size + tANI_U32 usPtrnIntervalMs; // In msec + tANI_U8 ucPattern[PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer +} tSirAddPeriodicTxPtrn, *tpSirAddPeriodicTxPtrn; + +typedef struct sSirDelPeriodicTxPtrn +{ + /* MAC Address for the adapter */ + tSirMacAddr macAddress; + + /* Bitmap of pattern IDs that need to be deleted */ + tANI_U32 ucPatternIdBitmap; +} tSirDelPeriodicTxPtrn, *tpSirDelPeriodicTxPtrn; + +typedef struct sSirRateUpdateInd +{ + /* 0 implies RA, positive value implies fixed rate, -1 implies ignore this + * param. + */ + tANI_S32 ucastDataRate; + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags ucastDataRateTxFlag; + + /* BSSID - Optional. 00-00-00-00-00-00 implies apply to all BCAST STAs */ + tSirMacAddr bssid; + + /* + * 0 implies MCAST RA, positive value implies fixed rate, + * -1 implies ignore this param + */ + tANI_S32 rmcDataRate;//unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags rmcDataRateTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10, + * 0 implies ignore + */ + tANI_U32 mcastDataRate24GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags mcastDataRate24GHzTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 5 GHz, + * unit Mbpsx10, 0 implies ignore + */ + tANI_U32 mcastDataRate5GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxrateinfoflags mcastDataRate5GHzTxFlag; + +} tSirRateUpdateInd, *tpSirRateUpdateInd; + +#ifdef WLAN_FEATURE_RMC + +#define SIR_RMC_NUM_MAX_RULERS 8 /* HAL_NUM_MAX_RULERS */ +typedef struct sSirSetRMCReq +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tSirMacAddr mcastTransmitter; +} tSirSetRMCReq, *tpSirSetRMCReq; + +typedef struct sSirRMCInfo +{ + tANI_U32 dialogToken; + tANI_U8 action; + tSirMacAddr mcastRuler; +} tSirRMCInfo, *tpSirRMCInfo; + +typedef struct sSirRmcRulerSelectInd +{ + tANI_U16 status; + tSirMacAddr mcastTransmitter; + tSirMacAddr mcastGroup; + tSirMacAddr ruler[SIR_RMC_NUM_MAX_RULERS]; +} tSirRmcRulerSelectInd, *tpSirRmcRulerSelectInd; + +typedef struct sSirRmcBecomeRulerInd +{ + tANI_U16 status; + tSirMacAddr mcastTransmitter; + tSirMacAddr mcastGroup; +} tSirRmcBecomeRulerInd, *tpSirRmcBecomeRulerInd; + +typedef struct sSirRmcRulerReq +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 cmd; // tRulerReqCmdType + tSirMacAddr mcastTransmitter; + tSirMacAddr mcastGroup; + tSirMacAddr blacklist[SIR_RMC_NUM_MAX_RULERS]; +} tSirRmcRulerReq, *tpSirRmcRulerReq; + +typedef struct sSirRmcUpdateInd +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 indication; // trulerUpdateIndType + tANI_U8 role; // tRoleType + tSirMacAddr mcastTransmitter; + tSirMacAddr mcastGroup; + tSirMacAddr mcastRuler; + tSirMacAddr ruler[SIR_RMC_NUM_MAX_RULERS]; +} tSirRmcUpdateInd, *tpSirRmcUpdateInd; + +/*--------------------------------------------------------------------------- +* tSirIbssGetPeerInfoReqParams +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_BOOLEAN allPeerInfoReqd; // If set, all IBSS peers stats are reported + tANI_U8 staIdx; // If allPeerInfoReqd is not set, only stats + // of peer with staIdx is reported +}tSirIbssGetPeerInfoReqParams, *tpSirIbssGetPeerInfoReqParams; + +/*--------------------------------------------------------------------------- +* tSirIbssGetPeerInfoParams +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U8 staIdx; //StaIdx + tANI_U32 txRate; //Tx Rate + tANI_U32 mcsIndex; //MCS Index + tANI_U32 txRateFlags; //TxRate Flags + tANI_S8 rssi; //RSSI +}tSirIbssPeerInfoParams; + +typedef struct +{ + tANI_U32 status; + tANI_U8 numPeers; + tSirIbssPeerInfoParams peerInfoParams[32]; +}tSirPeerInfoRspParams, *tpSirIbssPeerInfoRspParams; + +/*--------------------------------------------------------------------------- +* tSirIbssGetPeerInfoRspParams +*--------------------------------------------------------------------------*/ +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSirPeerInfoRspParams ibssPeerInfoRspParams; +} tSirIbssGetPeerInfoRspParams, *tpSirIbssGetPeerInfoRspParams; +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +// Set batch scan resposne from FW +typedef struct +{ + /*maximum number of scans which FW can cache*/ + tANI_U32 nScansToBatch; +} tSirSetBatchScanRsp, *tpSirSetBatchScanRsp; + +// Set batch scan request to FW +typedef struct +{ + tANI_U32 scanFrequency; /* how frequent to do scan - default 30Sec*/ + tANI_U32 numberOfScansToBatch; /* number of scans to batch */ + tANI_U32 bestNetwork; /* best networks in terms of rssi */ + tANI_U8 rfBand; /* band to scan : + 0 ->both Band, 1->2.4Ghz Only + and 2-> 5GHz Only */ + tANI_U32 rtt; /* set if required to do RTT it is not + supported in current version */ +} tSirSetBatchScanReq, *tpSirSetBatchScanReq; + + +// Stop batch scan request to FW +typedef struct +{ + tANI_U32 param; +} tSirStopBatchScanInd, *tpSirStopBatchScanInd; + +// Trigger batch scan result indication to FW +typedef struct +{ + tANI_U32 param; +} tSirTriggerBatchScanResultInd, *tpSirTriggerBatchScanResultInd; + +// Batch scan result indication from FW +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssid[6]; /* BSSID */ + tANI_U8 ssid[33]; /* SSID */ + tANI_U8 ch; /* Channel */ + tANI_S8 rssi; /* RSSI or Level */ + /*Timestamp when Network was found. Used to calculate age based on timestamp + in GET_RSP msg header */ + tANI_U32 timestamp; +} tSirBatchScanNetworkInfo, *tpSirBatchScanNetworkInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 scanId; /* Scan List ID. */ + /*No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg*/ + tANI_U32 numNetworksInScanList; + /*Variable data ptr: Number of AP in Scan List*/ + /*Following numNetworkInScanList is data of type tSirBatchScanNetworkInfo + *of sizeof(tSirBatchScanNetworkInfo) * numNetworkInScanList */ + tANI_U8 scanList[1]; +} tSirBatchScanList, *tpSirBatchScanList; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 timestamp; + tANI_U32 numScanLists; + boolean isLastResult; + /* Variable Data ptr: Number of Scan Lists*/ + /* following isLastResult is data of type tSirBatchScanList + * of sizeof(tSirBatchScanList) * numScanLists*/ + tANI_U8 scanResults[1]; +} tSirBatchScanResultIndParam, *tpSirBatchScanResultIndParam; + +#endif // FEATURE_WLAN_BATCH_SCAN + +#ifdef FEATURE_WLAN_CH_AVOID +#define SIR_CH_AVOID_MAX_RANGE 15 + +typedef struct sSirChAvoidFreqType +{ + tANI_U32 startFreq; + tANI_U32 endFreq; +} tSirChAvoidFreqType; + +typedef struct sSirChAvoidIndType +{ + tANI_U32 avoidRangeCount; + tSirChAvoidFreqType avoidFreqRange[SIR_CH_AVOID_MAX_RANGE]; +} tSirChAvoidIndType; +#endif /* FEATURE_WLAN_CH_AVOID */ + +typedef void (*pGetBcnMissRateCB)( tANI_S32 bcnMissRate, + VOS_STATUS status, void *data); +typedef void (*tSirFWStatsCallback)(VOS_STATUS status, + tSirFwStatsResult *fwStatsRsp, void *pContext); +typedef void (*sir_mgmt_frame_ind_callback)(tSirSmeMgmtFrameInd *frame_ind); + +typedef void (*tAntennaDivSelCB)(int antennaId, void *pContext); + +/** + * struct sir_sme_mgmt_frame_cb_req - Register a + * management frame callback req + * @message_type: message id + * @length: msg length + * @callback: callback for management frame indication + */ +struct sir_sme_mgmt_frame_cb_req +{ + tANI_U16 message_type; + tANI_U16 length; + sir_mgmt_frame_ind_callback callback; +}; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 msgLen; + tANI_U8 bssid[WNI_CFG_BSSID_LEN]; + void *callback; + void *data; +}tSirBcnMissRateReq; + +typedef PACKED_PRE struct PACKED_POST +{ + pGetBcnMissRateCB callback; + void *data; +}tSirBcnMissRateInfo; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +typedef struct +{ + u32 reqId; + tSirMacAddr macAddr; + u32 mpduSizeThreshold; + u32 aggressiveStatisticsGathering; +}tSirLLStatsSetReq, *tpSirLLStatsSetReq; + +typedef struct +{ + u32 reqId; + tSirMacAddr macAddr; + u32 paramIdMask; +}tSirLLStatsGetReq, *tpSirLLStatsGetReq; + +typedef struct +{ + u32 reqId; + tSirMacAddr macAddr; + u32 statsClearReqMask; + u8 stopReq; +}tSirLLStatsClearReq, *tpSirLLStatsClearReq; + +typedef PACKED_PRE struct PACKED_POST +{ + u32 stats; + tSirFWStatsCallback callback; + void *data; +}tSirFWStatsGetReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tSirFWStatsCallback callback; + void *data; +}tSirFWStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 status; + tANI_U32 selectedAntennaId; + tANI_U32 reserved; +} tSirAntennaDivSelRsp, *tpSirntennaDivSelRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tAntennaDivSelCB callback; + void *data; + tANI_U32 reserved; +}tSirAntennaDiversitySelectionReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tAntennaDivSelCB callback; + void *data; +}tSirAntennaDiversitySelectionInfo; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_NOTIFY_STATS +---------------------------------------------------------------------------*/ + + +/******************************LINK LAYER Statistics**********************/ + +typedef int tSirWifiRadio; +typedef int tSirWifiChannel; +typedef int tSirwifiTxRate; + +/* channel operating width */ +typedef PACKED_PRE enum PACKED_POST +{ + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, +} tSirWifiChannelWidth; + +typedef PACKED_PRE enum PACKED_POST +{ + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, // if done by firmware/driver + WIFI_EAPOL_COMPLETED = 5, // if done by firmware/driver +} tSirWifiConnectionState; + +typedef PACKED_PRE enum PACKED_POST +{ + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +} tSirWifiRoamState; + +typedef PACKED_PRE enum PACKED_POST +{ + WIFI_INTERFACE_UNKNOWN = -1, + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + } tSirWifiInterfaceMode; + +// set for QOS association +#define WIFI_CAPABILITY_QOS 0x00000001 +// set for protected association (802.11 beacon frame control protected bit set) +#define WIFI_CAPABILITY_PROTECTED 0x00000002 +// set if 802.11 Extended Capabilities element interworking bit is set +#define WIFI_CAPABILITY_INTERWORKING 0x00000004 +// set for HS20 association +#define WIFI_CAPABILITY_HS20 0x00000008 +// set is 802.11 Extended Capabilities element UTF-8 SSID bit is set +#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 +// set is 802.11 Country Element is present +#define WIFI_CAPABILITY_COUNTRY 0x00000020 + +typedef PACKED_PRE struct PACKED_POST +{ + /*tSirWifiInterfaceMode*/ + // interface mode + tANI_S8 mode; + // interface mac address (self) + tSirMacAddr macAddr; + /*tSirWifiConnectionState*/ + // connection state (valid for STA, CLI only) + tANI_U8 state; + /*tSirWifiRoamState*/ + // roaming state + tANI_U8 roaming; + // WIFI_CAPABILITY_XXX (self) + tANI_U32 capabilities; + // null terminated SSID + tANI_U8 ssid[33]; + // bssid + tSirMacAddr bssid; + // country string advertised by AP + tANI_U8 apCountryStr[WNI_CFG_COUNTRY_CODE_LEN]; + // country string for this association + tANI_U8 countryStr[WNI_CFG_COUNTRY_CODE_LEN]; +} tSirWifiInterfaceInfo, *tpSirWifiInterfaceInfo; + +/* channel information */ +typedef PACKED_PRE struct PACKED_POST +{ + // channel width (20, 40, 80, 80+80, 160) + tSirWifiChannelWidth width; + // primary 20 MHz channel + tSirWifiChannel centerFreq; + // center frequency (MHz) first segment + tSirWifiChannel centerFreq0; + // center frequency (MHz) second segment + tSirWifiChannel centerFreq1; +} tSirWifiChannelInfo, *tpSirWifiChannelInfo; + +/* wifi rate info */ +typedef PACKED_PRE struct PACKED_POST +{ + // 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved + tANI_U32 preamble :3; + // 0:1x1, 1:2x2, 3:3x3, 4:4x4 + tANI_U32 nss :2; + // 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz + tANI_U32 bw :3; + // OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps + // HT/VHT it would be mcs index + tANI_U32 rateMcsIdx :8; + // reserved + tANI_U32 reserved :16; + // units of 100 Kbps + tANI_U32 bitrate; +} tSirWifiRate, *tpSirWifiRate; + +/* channel statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + // channel + tSirWifiChannelInfo channel; + // msecs the radio is awake (32 bits number accruing over time) + tANI_U32 onTime; + // msecs the CCA register is busy (32 bits number accruing over time) + tANI_U32 ccaBusyTime; +} tSirWifiChannelStats, *tpSirWifiChannelStats; + +/* radio statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + // wifi radio (if multiple radio supported) + tSirWifiRadio radio; + // msecs the radio is awake (32 bits number accruing over time) + tANI_U32 onTime; + /* msecs the radio is transmitting + * (32 bits number accruing over time) + */ + tANI_U32 txTime; + /* msecs the radio is in active receive + *(32 bits number accruing over time) + */ + tANI_U32 rxTime; + /* msecs the radio is awake due to all scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeScan; + /* msecs the radio is awake due to NAN + * (32 bits number accruing over time) + */ + tANI_U32 onTimeNbd; + /* msecs the radio is awake due to EXTScan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeEXTScan; + /* msecs the radio is awake due to roam?scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeRoamScan; + /* msecs the radio is awake due to PNO scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimePnoScan; + /* msecs the radio is awake due to HS2.0 scans and GAS exchange + * (32 bits number accruing over time) + */ + tANI_U32 onTimeHs20; + // number of channels + tANI_U32 numChannels; + // channel statistics tSirWifiChannelStats + tSirWifiChannelStats channels[1]; +} tSirWifiRadioStat, *tpSirWifiRadioStat; + +/* per rate statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + // rate information + tSirWifiRate rate; + // number of successfully transmitted data pkts (ACK rcvd) + tANI_U32 txMpdu; + // number of received data pkts + tANI_U32 rxMpdu; + // number of data packet losses (no ACK) + tANI_U32 mpduLost; + // total number of data pkt retries * + tANI_U32 retries; + // number of short data pkt retries + tANI_U32 retriesShort; + // number of long data pkt retries + tANI_U32 retriesLong; +} tSirWifiRateStat, *tpSirWifiRateStat; + +/* access categories */ +typedef PACKED_PRE enum PACKED_POST +{ + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +} tSirWifiTrafficAc; + +/* wifi peer type */ +typedef PACKED_PRE enum PACKED_POST +{ + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +} tSirWifiPeerType; + +/* per peer statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + // peer type (AP, TDLS, GO etc.) + tSirWifiPeerType type; + // mac address + tSirMacAddr peerMacAddress; + // peer WIFI_CAPABILITY_XXX + tANI_U32 capabilities; + // number of rates + tANI_U32 numRate; + // per rate statistics, number of entries = num_rate + tSirWifiRateStat rateStats[1]; +} tSirWifiPeerInfo, *tpSirWifiPeerInfo; + +/* per access category statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + /*tSirWifiTrafficAc*/ + // access category (VI, VO, BE, BK) + tANI_U8 ac; + // number of successfully transmitted unicast data pkts (ACK rcvd) + tANI_U32 txMpdu; + // number of received unicast mpdus + tANI_U32 rxMpdu; + // number of succesfully transmitted multicast data packets + // STA case: implies ACK received from AP for the unicast + // packet in which mcast pkt was sent + tANI_U32 txMcast; + // number of received multicast data packets + tANI_U32 rxMcast; + // number of received unicast a-mpdus + tANI_U32 rxAmpdu; + // number of transmitted unicast a-mpdus + tANI_U32 txAmpdu; + // number of data pkt losses (no ACK) + tANI_U32 mpduLost; + // total number of data pkt retries + tANI_U32 retries; + // number of short data pkt retries + tANI_U32 retriesShort; + // number of long data pkt retries + tANI_U32 retriesLong; + // data pkt min contention time (usecs) + tANI_U32 contentionTimeMin; + // data pkt max contention time (usecs) + tANI_U32 contentionTimeMax; + // data pkt avg contention time (usecs) + tANI_U32 contentionTimeAvg; + // num of data pkts used for contention statistics + tANI_U32 contentionNumSamples; +} tSirWifiWmmAcStat, *tpSirWifiWmmAcStat; + +#ifdef FEATURE_EXT_LL_STAT +typedef PACKED_PRE struct PACKED_POST +{ + /* Average Beacon spread offset is the averaged + * time delay between TBTT and beacon TSF + */ + tANI_U64 avg_bcn_spread; + /* Average number of frames received from AP after + * receiving the ACK for a frame with PM=1 + */ + tANI_U32 avg_rx_frms_leaked; + /* Rx leak watch window currently in force to minimize data loss + * because of leaky AP. Rx leak window is the time driver waits + * before shutting down the radio or switching the channel and + * after receiving an ACK for a data frame with PM bit set) + */ + tANI_U32 rx_leak_window; + + /* Takes value of 1 if AP leaks packets after sending + * an ACK for PM=1 otherwise 0 + */ + tANI_U32 is_leaky_ap; + +} tSirWifiIfaceLeakyApStat, *tpSirWifiIfaceLeakyApStat; +#endif + +/* Interface statistics - corresponding to 2nd most + * LSB in wifi statistics bitmap for getting statistics + */ +typedef PACKED_PRE struct PACKED_POST +{ + // current state of the interface + tSirWifiInterfaceInfo info; + // access point beacon received count from connected AP + tANI_U32 beaconRx; + // access point mgmt frames received count from + // connected AP (including Beacon) + tANI_U32 mgmtRx; + // action frames received count + tANI_U32 mgmtActionRx; + // action frames transmit count + tANI_U32 mgmtActionTx; + // access Point Beacon and Management frames RSSI (averaged) + tANI_S32 rssiMgmt; + // access Point Data Frames RSSI (averaged) from connected AP + tANI_S32 rssiData; + // access Point ACK RSSI (averaged) from connected AP + tANI_S32 rssiAck; + // per ac data packet statistics + tSirWifiWmmAcStat AccessclassStats[WIFI_AC_MAX]; +#ifdef FEATURE_EXT_LL_STAT + //Leaky Ap Stats + tSirWifiIfaceLeakyApStat leakyApStat; +#endif +} tSirWifiIfaceStat, *tpSirWifiIfaceStat; + +/* Peer statistics - corresponding to 3rd most LSB in + * wifi statistics bitmap for getting statistics + */ +typedef PACKED_PRE struct PACKED_POST +{ + // number of peers + tANI_U32 numPeers; + // per peer statistics + tSirWifiPeerInfo peerInfo[1]; +} tSirWifiPeerStat, *tpSirWifiPeerStat; + +/* wifi statistics bitmap for getting statistics */ +#define WMI_LINK_STATS_RADIO 0x00000001 +#define WMI_LINK_STATS_IFACE 0x00000002 +#define WMI_LINK_STATS_ALL_PEER 0x00000004 +#define WMI_LINK_STATS_PER_PEER 0x00000008 + +/* wifi statistics bitmap for clearing statistics */ +// all radio statistics +#define WIFI_STATS_RADIO 0x00000001 +// cca_busy_time (within radio statistics) +#define WIFI_STATS_RADIO_CCA 0x00000002 +// all channel statistics (within radio statistics) +#define WIFI_STATS_RADIO_CHANNELS 0x00000004 +// all scan statistics (within radio statistics) +#define WIFI_STATS_RADIO_SCAN 0x00000008 +// all interface statistics +#define WIFI_STATS_IFACE 0x00000010 +// all tx rate statistics (within interface statistics) +#define WIFI_STATS_IFACE_TXRATE 0x00000020 +// all ac statistics (within interface statistics) +#define WIFI_STATS_IFACE_AC 0x00000040 +// all contention (min, max, avg) statistics (within ac statistics) +#define WIFI_STATS_IFACE_CONTENTION 0x00000080 + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 paramId; + tANI_U8 ifaceId; + tANI_U32 respId; + tANI_U32 moreResultToFollow; + tANI_U8 result[1]; +} tSirLLStatsResults, *tpSirLLStatsResults; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + + + +#ifdef WLAN_FEATURE_EXTSCAN + +typedef enum +{ + WIFI_BAND_UNSPECIFIED, + WIFI_BAND_BG = 1, // 2.4 GHz + WIFI_BAND_A = 2, // 5 GHz without DFS + WIFI_BAND_ABG = 3, // 2.4 GHz + 5 GHz; no DFS + WIFI_BAND_A_DFS_ONLY = 4, // 5 GHz DFS only + // 5 is reserved + WIFI_BAND_A_WITH_DFS = 6, // 5 GHz with DFS + WIFI_BAND_ABG_WITH_DFS = 7, // 2.4 GHz + 5 GHz with DFS + + /* Keep it last */ + WIFI_BAND_MAX +} tWifiBand; + +/* wifi scan related events */ +typedef enum +{ + WIFI_SCAN_BUFFER_FULL, + WIFI_SCAN_COMPLETE, +} tWifiScanEventType; + +typedef struct +{ + tSirMacAddr bssid; // AP BSSID + tANI_S32 low; // low threshold + tANI_S32 high; // high threshold +} tSirAPThresholdParam, *tpSirAPThresholdParam; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirGetEXTScanCapabilitiesReqParams, *tpSirGetEXTScanCapabilitiesReqParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U32 status; + + tANI_U32 scanCacheSize; + tANI_U32 scanBuckets; + tANI_U32 maxApPerScan; + tANI_U32 maxRssiSampleSize; + tANI_U32 maxScanReportingThreshold; + + tANI_U32 maxHotlistAPs; + tANI_U32 maxHotlistSSIDs; + + tANI_U32 maxBsidHistoryEntries; + +} tSirEXTScanCapabilitiesEvent, *tpSirEXTScanCapabilitiesEvent; + +/* WLAN_HAL_EXT_SCAN_RESULT_IND */ +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; + + /* + * 1 return cached results and flush it + * 0 return cached results and do not flush + */ + tANI_BOOLEAN flush; +} tSirEXTScanGetCachedResultsReqParams, *tpSirEXTScanGetCachedResultsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirEXTScanGetCachedResultsRspParams, *tpSirEXTScanGetCachedResultsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U64 ts; // time of discovery + tANI_U8 ssid[SIR_MAC_MAX_SSID_LENGTH + 1]; // null terminated SSID + tSirMacAddr bssid; // BSSID + tANI_U32 channel; // channel frequency in MHz + tANI_S32 rssi; // RSSI in dBm + tANI_U32 rtt; // RTT in nanoseconds + tANI_U32 rtt_sd; // standard deviation in rtt + tANI_U16 beaconPeriod; // period advertised in the beacon + tANI_U16 capability; // capabilities advertised in the beacon +} tSirWifiScanResult, *tpSirWifiScanResult; + +/** + * struct tExtscanCachedScanResult - extscan cached scan result + * @scan_id: a unique identifier for the scan unit + * @flags: a bitmask with additional information about scan + * @num_results: number of bssids retrieved by the scan + * @ap: wifi scan bssid results info + */ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 scan_id; + tANI_U8 flags; + tANI_U8 num_results; + + tSirWifiScanResult ap[32]; +} tExtscanCachedScanResult, *tpExtscanCachedScanResult; + +/* WLAN_HAL_BSSID_HOTLIST_RESULT_IND */ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_BOOLEAN bss_found; + tANI_U32 numHotlistBss; // numbers of APs + + /* + * 0 for last fragment + * 1 still more fragment(s) coming + */ + tANI_BOOLEAN moreData; + tSirWifiScanResult bssHotlist[1]; +} tSirEXTScanHotlistMatch, *tpSirEXTScanHotlistMatch; + +#ifdef DHCP_SERVER_OFFLOAD +/** + * sir_dhcp_srv_offload_info_t - dhcp server offload info + * @bssidx: bss index + * @dhcp_srv_offload_enabled: enable or disable + * @dhcp_client_num: number of clients supported + * @dhcp_srv_ip: server ip address + * @start_lsb: lsb of start address of dhcp pool + */ +typedef struct +{ + tANI_U8 bssidx; + tANI_U32 dhcp_srv_offload_enabled; + tANI_U32 dhcp_client_num; + tANI_U32 dhcp_srv_ip; + tANI_U32 start_lsb; + dhcp_offload_req_cb dhcp_offload_callback; + void *dhcp_server_offload_cb_context; +} sir_dhcp_srv_offload_info_t, *sir_dhcp_srv_offload_info; +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +#define MAX_MDNS_FQDN_LEN 64 +#define MAX_MDNS_RESP_LEN 512 + +typedef struct +{ + tANI_U8 bss_idx; + tANI_U32 enable; + mdns_enable_req_cb mdns_enable_callback; + void *mdns_enable_cb_context; +} sir_mdns_offload_info_t, *sir_mdns_offload_info; + +typedef struct +{ + tANI_U8 bss_idx; + tANI_U32 fqdn_type; + tANI_U32 fqdn_len; + tANI_U8 fqdn_data[MAX_MDNS_FQDN_LEN]; + mdns_fqdn_req_cb mdns_fqdn_callback; + void *mdns_fqdn_cb_context; + +} sir_mdns_fqdn_info_t, *sir_mdns_fqdn_info; + +typedef struct +{ + tANI_U8 bss_idx; + tANI_U32 resourceRecord_count; + tANI_U32 resp_len; + tANI_U8 resp_data[MAX_MDNS_RESP_LEN]; + mdns_resp_req_cb mdns_resp_callback; + void *mdns_resp_cb_context; +} sir_mdns_resp_info_t, *sir_mdns_resp_info; + +typedef struct +{ + tANI_U8 bss_idx; +} sir_get_mdns_stats_info_t, *sir_get_mdns_stats_info; +#endif /* MDNS_OFFLOAD */ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + /* + * It gives number of scan ids + */ + tANI_U32 scanResultSize; + + /* + * 0 for last fragment + * 1 still more fragment(s) coming + */ + tANI_BOOLEAN moreData; + tANI_U8 result[1]; +} tSirWifiScanResultEvent, *tpSirWifiScanResultEvent; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 elemId; // Element Identifier + tANI_U8 ieLength; // length of IE data + tANI_U8 *IEs; // IEs +} tSirInformationElement, *tpSirInformationElement; + +/* Reported when each probe response is received, if reportEvents +* enabled in tSirWifiScanCmdReqParams */ +typedef struct +{ + tANI_U32 requestId; + + /* + * 0 for last fragment + * 1 still more fragment(s) coming + */ + tANI_BOOLEAN moreData; + tSirWifiScanResult ap; // only 1 AP info for now + tANI_U32 ieLength; + tSirInformationElement *ie; +} tSirWifiFullScanResultEvent, *tpSirWifiFullScanResultEvent; + + +typedef struct +{ + tANI_U32 channel; // frequency + tANI_U32 dwellTimeMs; // dwell time hint + tANI_U8 passive; // 0 => active, + // 1 => passive scan; ignored for DFS + tANI_U8 chnlClass; +} tSirWifiScanChannelSpec, *tpSirWifiScanChannelSpec; + +typedef struct +{ + tANI_U8 bucket; // bucket index, 0 based + tWifiBand band; // when UNSPECIFIED, use channel list + + /* + * desired period, in millisecond; if this is too + * low, the firmware should choose to generate results as fast as + * it can instead of failing the command byte + */ + tANI_U32 period; + + /* + * 0 => normal reporting (reporting rssi history + * only, when rssi history buffer is % full) + * 1 => same as 0 + report a scan completion event after scanning + * this bucket + * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) + * in real time to HAL + */ + tANI_U8 reportEvents; + + tANI_U32 max_period; + tANI_U32 exponent; + tANI_U32 step_count; + + tANI_U8 numChannels; + + /* + * channels to scan; these may include DFS channels + */ + tSirWifiScanChannelSpec channels[WLAN_EXTSCAN_MAX_CHANNELS]; +} tSirWifiScanBucketSpec, *tpSirWifiScanBucketSpec; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; + tANI_U32 basePeriod; // base timer period + tANI_U32 maxAPperScan; + + /* in %, when buffer is this much full, wake up host */ + tANI_U32 reportThresholdPercent; + tANI_U32 reportThresholdNumScans; + + tANI_U32 homeAwayTime; //in units of milliseconds + + tANI_U8 numBuckets; + tSirWifiScanBucketSpec buckets[WLAN_EXTSCAN_MAX_BUCKETS]; +} tSirEXTScanStartReqParams, *tpSirEXTScanStartReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirEXTScanStartRspParams, *tpSirEXTScanStartRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirEXTScanStopReqParams, *tpSirEXTScanStopReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirEXTScanStopRspParams, *tpSirEXTScanStopRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; // session Id mapped to vdev_id + tANI_U32 lostBssidSampleSize; + tANI_U32 numBssid; // number of hotlist APs + tSirAPThresholdParam ap[WLAN_EXTSCAN_MAX_HOTLIST_APS]; // hotlist APs +} tSirEXTScanSetBssidHotListReqParams, *tpSirEXTScanSetBssidHotListReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirEXTScanSetBssidHotListRspParams, *tpSirEXTScanSetBssidHotListRspParams; + +typedef struct +{ + tANI_U32 requestId; + tANI_U8 sessionId; +} tSirEXTScanResetBssidHotlistReqParams, *tpSirEXTScanResetBssidHotlistReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +} tSirEXTScanResetBssidHotlistRspParams, *tpSirEXTScanResetBssidHotlistRspParams; + +/*--------------------------------------------------------------------------- + * * WLAN_HAL_EXTSCAN_RESULT_AVAILABLE_IND + * *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 numResultsAvailable; +} tSirEXTScanResultsAvailableIndParams, + *tpSirEXTScanResultsAvailableIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 scanEventType; + tANI_U32 status; +} tSirEXTScanOnScanEventIndParams, + *tpSirEXTScanOnScanEventIndParams; + +/*--------------------------------------------------------------------------- + * * WLAN_HAL_EXTSCAN_PROGRESS_IND + * *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE enum PACKED_POST +{ + WLAN_HAL_EXTSCAN_BUFFER_FULL, + WLAN_HAL_EXTSCAN_COMPLETE, +}tSirEXTScanProgressEventType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; + tSirEXTScanProgressEventType extScanEventType; +}tSirEXTScanProgressIndParams, + *tpSirEXTScanProgressIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_BOOLEAN pause; // 1 -> pause, 0 -> unpause + tANI_U32 reserved; //reserved for future use +}tSirHighPriorityDataInfoInd, *tpSirHighPriorityDataInfoInd; + +#endif /* WLAN_FEATURE_EXTSCAN */ + +typedef struct +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr macAddr; +} tSirSpoofMacAddrReq, *tpSirSpoofMacAddrReq; + +typedef struct +{ + //BIT order is most likely little endian. + //This structure is for netowkr-order byte array (or big-endian byte order) +#ifndef WLAN_PAL_BIG_ENDIAN_BIT + tANI_U8 protVer :2; + tANI_U8 type :2; + tANI_U8 subType :4; + + tANI_U8 toDS :1; + tANI_U8 fromDS :1; + tANI_U8 moreFrag :1; + tANI_U8 retry :1; + tANI_U8 powerMgmt :1; + tANI_U8 moreData :1; + tANI_U8 wep :1; + tANI_U8 order :1; + +#else + + tANI_U8 subType :4; + tANI_U8 type :2; + tANI_U8 protVer :2; + + tANI_U8 order :1; + tANI_U8 wep :1; + tANI_U8 moreData :1; + tANI_U8 powerMgmt :1; + tANI_U8 retry :1; + tANI_U8 moreFrag :1; + tANI_U8 fromDS :1; + tANI_U8 toDS :1; + +#endif + +} tSirFC; + +typedef struct +{ + /* Frame control field */ + tSirFC frameCtrl; + /* Duration ID */ + tANI_U16 usDurationId; + /* Address 1 field */ + tSirMacAddr vA1; + /* Address 2 field */ + tSirMacAddr vA2; + /* Address 3 field */ + tSirMacAddr vA3; + /* Sequence control field */ + tANI_U16 sSeqCtrl; + /* Optional A4 address */ + tSirMacAddr optvA4; + /* Optional QOS control field */ + tANI_U16 usQosCtrl; +}tSir80211Header; +// Definition for Encryption Keys +//typedef struct sSirKeys +typedef struct +{ + tANI_U8 keyId; + tANI_U8 unicast; // 0 for multicast + tAniKeyDirection keyDirection; + tANI_U8 keyRsc[WLAN_MAX_KEY_RSC_LEN]; // Usage is unknown + tANI_U8 paeRole; // =1 for authenticator, + // =0 for supplicant + tANI_U16 keyLength; + tANI_U8 key[SIR_MAC_MAX_KEY_LENGTH]; +} tMacKeys, *tpMacKeys; + +typedef enum +{ + eMAC_WEP_STATIC, + eMAC_WEP_DYNAMIC, +} tMacWepType; + +/* + * This is used by PE to configure the key information on a given station. + * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate + * a preconfigured key from a BSS the station assoicated with; otherwise + * a new key descriptor is created based on the key field. + */ +//typedef struct +typedef struct +{ + tANI_U16 staIdx; + tAniEdType encType; // Encryption/Decryption type + tMacWepType wepType; // valid only for WEP + tANI_U8 defWEPIdx; // Default WEP key, valid only for static WEP, must between 0 and 3 + tMacKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; // valid only for non-static WEP encyrptions + tANI_U8 singleTidRc; // 1=Single TID based Replay Count, 0=Per TID based RC + tANI_U8 sessionId; // PE session id for PE<->HAL interface +} tSirSetStaKeyParams, *tpSirSetStaKeyParams; + +//typedef struct +typedef struct +{ + tSirSetStaKeyParams keyParams; + tANI_U8 pn[6]; +}tSirencConfigParams; + +typedef struct +{ + tANI_U16 length; + tANI_U8 data[WLAN_DISA_MAX_PAYLOAD_SIZE]; +}tSirpayload; + +typedef struct +{ + tSir80211Header macHeader; + tSirencConfigParams encParams; + tSirpayload data; +}tSirpkt80211; + +typedef struct +{ + tANI_U32 status; + tSirpayload encryptedPayload; +} tSetEncryptedDataRspParams, *tpSetEncryptedDataRspParams; + +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSetEncryptedDataRspParams encryptedDataRsp; +} tSirEncryptedDataRspParams, *tpSirEncryptedDataRspParams; + +typedef enum eSirAbortScanStatus +{ + eSIR_ABORT_ACTIVE_SCAN_LIST_EMPTY, + eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY, + eSIR_ABORT_SCAN_FAILURE +}tSirAbortScanStatus; + +/* Max number of rates allowed in Supported Rates IE */ +#define MAX_NUM_SUPPORTED_RATES (8) + +typedef struct sSirSmeUpdateMaxRateParams +{ + tANI_U32 maxRateFlag; + tANI_U8 smeSessionId; +}tSirSmeUpdateMaxRateParams, *tpSirSmeUpdateMaxRateParams; + +typedef struct +{ + tANI_U32 event_data_len; + tANI_U8 event_data[1]; +} tSirNanEvent, *tpSirNanEvent; + +typedef struct +{ + tANI_U32 txCompleteStatus; + tANI_U32 txBdToken; +}tSirTxBdStatus, *tpSirTxBdStatus; + +/* enable or disable 20_40 BSS Coexistence IE in TDLS frames*/ +typedef struct +{ + // Common for all types are requests + tANI_U16 msgType; // message type is same as the request type + tANI_U16 msgLen; // length of the entire request + tANI_U8 SetTdls2040BSSCoex; //enabled or disabled +} tAniSetTdls2040BSSCoex, *tpAniSetTdls2040BSSCoex; + +/** + * struct sir_wifi_start_log - Structure to store the params sent to start/ + * stop logging + * @ringId: Attribute which indicates the type of logging like per packet + * statistics, connectivity etc. + * @verboseLevel: Verbose level which can be 0,1,2,3 + * @flag: Flag field for future use + */ +typedef struct sir_wifi_start_log { + tANI_U32 ringId; + tANI_U32 verboseLevel; + tANI_U32 flag; +}tAniWifiStartLog, *tpAniWifiStartLog; + +typedef struct +{ + tANI_U16 mesgType; + tANI_U16 mesgLen; + tSirMacAddr bssid; +}tSirDelAllTdlsPeers, *ptSirDelAllTdlsPeers; + +typedef void (*tSirMonModeCb)(tANI_U32 *magic, struct completion *cmpVar); +typedef struct +{ + tANI_U32 *magic; + struct completion *cmpVar; + void *data; + tSirMonModeCb callback; +}tSirMonModeReq, *ptSirMonModeReq; + +/** + * struct tAniFwrDumpRsp - firmware dump response details. + * + * This structure is used to store the firmware dump + * response from the firmware. + */ +typedef struct +{ + tANI_U32 dump_status; +}tAniFwrDumpRsp, *tpAniFwrDumpRsp; + +typedef void (*FWMemDumpReqCb)(void *fwMemDumpReqContext, tAniFwrDumpRsp *dump_rsp); + +/** + * struct tAniFwrDumpReq - firmware memory dump request details. +.*.@FWMemDumpReqCb - Associated Callback + *.@fwMemDumpReqContext - Callback context + * @reserved - reserved field 1. + * + * This structure carries information about the firmware + * memory dump request. + */ +typedef struct +{ + FWMemDumpReqCb fwMemDumpReqCallback; + void * fwMemDumpReqContext; + tANI_U32 reserved1; +}tAniFwrDumpReq, *tpAniFwrDumpReq; + +/** +* struct tSetWifiConfigParams - Structure to store the wificonfig related params +* @paramType: 1. Average Stats factor 2. Guard type +* @paramvalue: Value to be set in the firmware. +* @bssId: macaddr of the connected BssId +*/ +typedef struct +{ + tANI_U8 paramType; + tANI_U8 sessionId; + tANI_U32 paramValue; + tSirMacAddr bssId; +} tSetWifiConfigParams, *tpSetWifiConfigParams; + +typedef struct { + tANI_U8 param; + tANI_U32 value; +} tModifyRoamParamsReqParams, * tpModifyRoamParamsReqParams; + +#ifdef SAP_AUTH_OFFLOAD +/* 80211 Pre-Share Key length */ +#define SIR_PSK_MAX_LEN 64 + +/** + * enum tSirSecurityType - definition for Software AP Auth Offload + * Security Type + * @eSIR_OFFLOAD_NONE: None type security + * @eSIR_OFFLOAD_WPA2PSK_CCMP: WPA2-PSK + */ +enum tSirSecurityType +{ + eSIR_OFFLOAD_NONE, + eSIR_OFFLOAD_WPA2PSK_CCMP, +}; + +/** + * struct tSirSapOffloadInfo - Structure to store sap offload related params. + * @macAddr: Self mac address + * @sap_auth_offload_enable: tell if sap auth offload is enabled or not. + * @sap_auth_offload_sec_type: tells security type + * 0 - none + * 1 - WPA1-PSK + * @key_len: psk key length + * @key: psk key. + */ +struct tSirSapOffloadInfo +{ + tSirMacAddr macAddr; + bool sap_auth_offload_enable; + uint32_t sap_auth_offload_sec_type; + uint32_t key_len; + uint8_t key[SIR_PSK_MAX_LEN]; +}; + +typedef PACKED_PRE struct PACKED_POST +{ + /** staId returned from firmware for each STA association to SAP */ + tANI_U8 staIdx; + /** bssIdx on which the STA is added */ + tANI_U8 bssIdx; + /** DPU desc index of this station */ + tANI_U8 dpuIndex; + /** Bcast DPU index of this station */ + tANI_U8 bcastDpuIndex; + /** Bcast DPU Management index of this station */ + tANI_U8 bcastMgmtDpuIdx; + + tANI_U8 ucUcastSig; + + tANI_U8 ucBcastSig; + + tANI_U8 ucMgmtSig; + /** aid (association id) of this station */ + tANI_U32 assoc_id; + /** peer station's mac addr */ + tSirMacAddr peer_macaddr; + /** length of association request frame */ + tANI_U32 data_len; + /* Following this structure is the byte stream of a whole + * association request frame of length data_len + */ + tANI_U8 bufp[1]; +} tSapOfldAddStaIndMsg, *tpSapOfldAddStaIndMsg; + +typedef enum +{ + SAP_OFL_DEL_STA_FLAG_NONE = 0x00, + SAP_OFL_DEL_STA_FLAG_RECONNECT = 0x01, +} eSapOfldDelStaFlags; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 staIdx; + /** bssIdx on which the STA is added */ + tANI_U32 bssIdx; + /** aid (association id) of this station */ + tANI_U32 assoc_id; + /** peer station's mac addr */ + tSirMacAddr peer_macaddr; + /** disassociation reason */ + tANI_U32 reason; + /** flags - wmi_sap_ofl_del_sta_flags */ + tANI_U32 flags; +} tSapOfldDelStaIndMsg, *tpSapOfldDelStaIndMsg; + +typedef enum +{ + SAP_OFFLOAD_ADD_STA_IND = 0x00, + SAP_OFFLOAD_DEL_STA_IND = 0x01, +} eSapOfldIndType; + +typedef PACKED_PRE struct PACKED_POST +{ + /* indType will be from eSapOfldIndType */ + tANI_U32 indType; + /* size of this array will be depend on the indication type. + * Indication type can be either ADD_STA_IND or DEL_STA_IND. + * If indication type is ADD_STA_IND, size of this indication + * array will be sizeof(tSapOfldDelStaIndMsg) + * and if indication type is DEL_STA_IND, size of this indication + * arrary will be sizeof(tSapOfldAddStaIndMsg) + */ + tANI_U8 indication[1]; +} tSapOfldInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 num_indications; + /* size of this array will be depend on the number of indications.*/ + tSapOfldInd indications[1]; +}tSapOfldIndications; + +#endif /* SAP_AUTH_OFFLOAD */ + +/** + * struct stsf - the basic stsf structure + * + * @session_id: session id from adapter + * @set_req: set/get request flag. + * @tsf_low: low 32bits of tsf + * @tsf_high: high 32bits of tsf + * + * driver use this struct to store the tsf info + */ +struct stsf { + uint32_t session_id; + bool set_tsf_req; + uint32_t tsf_low; + uint32_t tsf_high; + bool tsf_req_status; +}; + +typedef int(*tsf_rsp_cb)(void *tsf_ctx, struct stsf *pTsf); + +/** + * struct tCapTsfParams - capture tsf request + * @bss_idx: bss index, SAP/STA + * @session_id: adapter session id + * @bssid: bssid for SAP/STA + * @tsf_rsp_cb_func : handler for tsf rsp from fw + * @tsf_rsp_cb_ctx : hdd ctx for tsf rsp handler + */ +typedef struct { + tANI_U8 bss_idx; + tANI_U8 session_id; + tSirMacAddr bssid; + tsf_rsp_cb tsf_rsp_cb_func; + void * tsf_rsp_cb_ctx; +}tSirCapTsfParams,*tpSirCapTsfParams; + +#ifdef WLAN_FEATURE_LFR_MBB + +/** + * enum csr_roam_op_code - Operation to be done by the callback. + * @SIR_ROAMING_DEREGISTER_STA: Deregister the old STA after roaming. + * @SIR_STOP_ROAM_OFFLOAD_SCAN : sends RSO stop + * @SIR_PREPARE_REASSOC_REQ: prepares reassoc request + */ +enum csr_roam_op_code { + SIR_ROAMING_DEREGISTER_STA, + SIR_STOP_ROAM_OFFLOAD_SCAN, + SIR_PREPARE_REASSOC_REQ, +}; + +/** + * enum sir_roam_cleanup_type - Type of cleanup needs to be performed. + * @SIR_MBB_DISCONNECTED: Entire CSR cleanup for connected AP + * needs to be performed + * @SIR_MBB_CONNECTED: No need to perform CSR cleanup for connected AP. + */ +enum sir_roam_cleanup_type { + SIR_MBB_DISCONNECTED, + SIR_MBB_CONNECTED, +}; +#endif + +/** + * struct tDelBaParams - Del BA Session req + * @session_id: adapter session id + */ +typedef struct { + tANI_U8 session_id; +}tDelBaParams,*ptDelBaParams; +#endif /* __SIR_API_H */ diff --git a/drivers/staging/prima/CORE/MAC/inc/sirMacPropExts.h b/drivers/staging/prima/CORE/MAC/inc/sirMacPropExts.h new file mode 100644 index 000000000000..f36257566e60 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/sirMacPropExts.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sirMacPropExts.h contains the MAC protocol + * extensions to support ANI feature set. + * Author: Chandra Modumudi + * Date: 11/27/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __MAC_PROP_EXTS_H +#define __MAC_PROP_EXTS_H + +#include "sirTypes.h" +#include "sirApi.h" +#include "aniSystemDefs.h" + +/// EID (Element ID) definitions + +// Proprietary IEs + +// Types definitions used within proprietary IE +#define SIR_MAC_PROP_EXT_RATES_TYPE 0 +#define SIR_MAC_PROP_AP_NAME_TYPE 1 +#define SIR_MAC_PROP_LOAD_INFO_TYPE 6 +#define SIR_MAC_PROP_ASSOC_TYPE 7 +#define SIR_MAC_PROP_LOAD_BALANCE_TYPE 8 +#define SIR_MAC_PROP_LL_ATTR_TYPE 9 +#define SIR_MAC_PROP_CAPABILITY 10 // proprietary capabilities +#define SIR_MAC_PROP_VERSION 11 // version info +#define SIR_MAC_PROP_EDCAPARAMS 12 // edca params for 11e and wme +#define SIR_MAC_PROP_SRCMAC 13 // sender's mac address +#define SIR_MAC_PROP_TITAN 14 // Advertises a TITAN device +#define SIR_MAC_PROP_CHANNEL_SWITCH 15 // proprietary channel switch info +#define SIR_MAC_PROP_QUIET_BSS 16 // Broadcast's REQ for Quiet BSS +#define SIR_MAC_PROP_TRIG_STA_BK_SCAN 17 // trigger station bk scan during quiet bss duration +#define SIR_MAC_PROP_TAURUS 18 // Advertises a TAURUS device + +// capability ie info +#define SIR_MAC_PROP_CAPABILITY_MIN sizeof(tANI_U16) + +// trigger sta scan ie length defines +#define SIR_MAC_PROP_TRIG_STA_BK_SCAN_EID_MIN 0 +#define SIR_MAC_PROP_TRIG_STA_BK_SCAN_EID_MAX 1 + +// the bit map is also used as a config enable, setting a bit in the +// propIE config variable, enables the corresponding capability in the propIE +// the enables simply result in including the corresponding element in the +// propIE +// Ex: setting the capability bit HCF would result in using the capability bit map for +// hcf instead of including the full HCF element in the IE +// capabilities bit map - bit offsets +// setting 11eQos has effect only if QoS is also enabled. then it overrides +// 11e support and implements it silently (as part of the prop ie) +#define SIR_MAC_PROP_CAPABILITY_HCF WNI_CFG_PROP_CAPABILITY_HCF +#define SIR_MAC_PROP_CAPABILITY_11EQOS WNI_CFG_PROP_CAPABILITY_11EQOS +#define SIR_MAC_PROP_CAPABILITY_WME WNI_CFG_PROP_CAPABILITY_WME +#define SIR_MAC_PROP_CAPABILITY_WSM WNI_CFG_PROP_CAPABILITY_WSM +#define SIR_MAC_PROP_CAPABILITY_EXTRATES WNI_CFG_PROP_CAPABILITY_EXTRATES +// ap->sta only, request STA to stop using prop rates for some time +#define SIR_MAC_PROP_CAPABILITY_EXTRATE_STOP WNI_CFG_PROP_CAPABILITY_EXTRATE_STOP +#define SIR_MAC_PROP_CAPABILITY_TITAN WNI_CFG_PROP_CAPABILITY_TITAN +#define SIR_MAC_PROP_CAPABILITY_TAURUS WNI_CFG_PROP_CAPABILITY_TAURUS +#define SIR_MAC_PROP_CAPABILITY_ESCORT_PKT WNI_CFG_PROP_CAPABILITY_ESCORT_PKT +// unused 9-12 +#define SIR_MAC_PROP_CAPABILITY_EDCAPARAMS WNI_CFG_PROP_CAPABILITY_EDCAPARAMS +#define SIR_MAC_PROP_CAPABILITY_LOADINFO WNI_CFG_PROP_CAPABILITY_LOADINFO +#define SIR_MAC_PROP_CAPABILITY_VERSION WNI_CFG_PROP_CAPABILITY_VERSION +#define SIR_MAC_PROP_CAPABILITY_MAXBITOFFSET WNI_CFG_PROP_CAPABILITY_MAXBITOFFSET + +// macro to set/get a capability bit, bitname is one of HCF/11EQOS/etc... +#define PROP_CAPABILITY_SET(bitname, value) \ + ((value) = (value) | ((tANI_U16)(1 << SIR_MAC_PROP_CAPABILITY_ ## bitname))) + +#define PROP_CAPABILITY_RESET(bitname, value) \ + ((value) = (value) & ~((tANI_U16)(1 << SIR_MAC_PROP_CAPABILITY_ ## bitname))) + +#define PROP_CAPABILITY_GET(bitname, value) \ + (((value) >> SIR_MAC_PROP_CAPABILITY_ ## bitname) & 1) + + +#define IS_DOT11_MODE_PROPRIETARY(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_POLARIS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TITAN) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) + +#define IS_DOT11_MODE_HT(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_11N) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11N_ONLY) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11AC) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) + +#ifdef WLAN_FEATURE_11AC +#define IS_DOT11_MODE_VHT(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_11AC) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) +#endif + /* + * When Titan capabilities can be turned on based on the + * Proprietary Extensions CFG, then this macro can be used. + * Here Titan capabilities can be turned on for 11G/Gonly/N/NOnly mode also. + */ +#define IS_DOT11_MODE_TITAN_ALLOWED(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_TITAN) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11G) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11N) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) + + + /* + * When Taurus capabilities can be turned on based on the + * Proprietary Extensions CFG, then this macro can be used. + * Here Taurus capabilities can be turned on for 11N/Nonly mode also. + */ +#define IS_DOT11_MODE_TAURUS_ALLOWED(dot11Mode) \ + (((dot11Mode == WNI_CFG_DOT11_MODE_TAURUS) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_11N) || \ + (dot11Mode == WNI_CFG_DOT11_MODE_ALL)) ? TRUE: FALSE) + + + +#define IS_DOT11_MODE_POLARIS(dot11Mode) IS_DOT11_MODE_PROPRIETARY(dot11Mode) + +#define IS_DOT11_MODE_11B(dot11Mode) \ + ((dot11Mode == WNI_CFG_DOT11_MODE_11B) ? TRUE : FALSE) + +#define IS_BSS_VHT_CAPABLE(vhtCaps) \ + ((vhtCaps).present && \ + ((vhtCaps).rxMCSMap != 0xFFFF) && \ + ((vhtCaps).txMCSMap != 0xFFFF)) + +/// ANI proprietary Status Codes enum +/// (present in Management response frames) +typedef enum eSirMacPropStatusCodes +{ + dummy +} tSirMacPropStatusCodes; + +/** + * ANI proprietary Reason Codes enum + * (present in Deauthentication/Disassociation Management frames) + */ +typedef enum eSirMacPropReasonCodes +{ + eSIR_MAC_ULA_TIMEOUT_REASON=0xFF00 +} tSirMacPropReasonCodes; + + +/// Proprietary IE definition +typedef struct sSirMacPropIE +{ + tANI_U8 elementID; // SIR_MAC_ANI_PROP_IE_EID + tANI_U8 length; + tANI_U8 oui[3]; // ANI_OUI for Airgo products + tANI_U8 info[1]; +} tSirMacPropIE, *tpSirMacPropIE; + + +typedef struct sSirMacPropRateSet +{ + tANI_U8 numPropRates; + tANI_U8 propRate[8]; +} tSirMacPropRateSet, *tpSirMacPropRateSet; + + +typedef struct sSirMacPropLLSet +{ + tANI_U32 deferThreshold; +} tSirMacPropLLSet, *tpSirMacPropLLSet; + +#define SIR_PROP_VERSION_STR_MAX 20 +typedef struct sSirMacPropVersion +{ + tANI_U32 chip_rev; // board, chipset info + tANI_U8 card_type; // Type of Card + tANI_U8 build_version[SIR_PROP_VERSION_STR_MAX]; //build version string +} tSirMacPropVersion, *tpSirMacPropVersion; +#define SIR_MAC_PROP_VERSION_MIN (SIR_PROP_VERSION_STR_MAX + sizeof(tANI_U32)) + + +// TCID MACRO's +#define TCID_0 0x01 +#define TCID_1 0x02 +#define TCID_2 0x04 +#define TCID_3 0x08 +#define TCID_4 0x10 +#define TCID_5 0x20 +#define TCID_6 0x40 +#define TCID_7 0x80 +#define TCID_ALL 0xFF + +// Get state of Concatenation +#define GET_CONCAT_STATE(ccBitmap,tcid) \ + ((ccBitmap) & (tcid)) + +// Get state of Compression +#define GET_COMPRESSION_STATE(cpBitmap,tcid) \ + ((cpBitmap) & (tcid)) + +// Get/Set the state of Reverse FCS +#define GET_RFCS_OPER_STATE(revFcsState) (revFcsState & 0x01) +#define GET_RFCS_PATTERN_ID(revFcsState) ((revFcsState & 0x0E) >> 1) + +/* STA CB Legacy Bss detect states */ +#define LIM_CB_LEGACY_BSS_DETECT_IDLE 0 +#define LIM_CB_LEGACY_BSS_DETECT_RUNNING 1 + +/* Default value for gLimRestoreCBNumScanInterval */ +#define LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT 2 + +// +// Proprietary Quite BSS IE structure +// +// Based on the setting of the "Titan" proprietary bit +// in the tSirPropIEStruct.capability field (bit #6), +// this IE will be sent appropriately to all the ANI +// peers in the following management frames - +// 1) Beacons +// 2) Probe Rsp +// +typedef struct sQuietBssIEStruct +{ + + // Indicates the number of TBTT's until the next beacon + // interval during which the next quiet interval will + // start + // 1 - Quiet Interval will start during the beacon + // interval starting at the next TBTT + // 0 - Reserved + tANI_U8 quietCount; + + // Shall be set to the number of beacon intervals between + // the start of regularly scheduled quiet intervals + // defined by this Quiet Element + // 0 - No periodic quiet interval is defined + tANI_U8 quietPeriod; + + // Duration of the quiet interval, expressed in TUs + // 1 TU = 1024 microseconds?? + tANI_U16 quietDuration; + + // Set to the offset of the start of the quiet interval + // from the TBTT specified by the quietCount field, + // expressed in TUs. The value of this offset field will + // be less than one beacon interval + // 1 TU = 1024 microseconds?? + tANI_U16 quietOffset; + +} tQuietBssIEStruct, *tpQuietBssIEStruct; + +typedef struct sChannelSwitchPropIEStruct +{ + tANI_U8 mode; + tANI_U8 primaryChannel; + tANI_U8 subBand; + tANI_U8 channelSwitchCount; + +} tChannelSwitchPropIEStruct, *tpChannelSwitchPropIEStruct; + +// generic proprietary IE structure definition +typedef struct sSirPropIEStruct +{ + tANI_U8 aniIndicator; + + tANI_U8 propRatesPresent:1; + tANI_U8 apNamePresent:1; + tANI_U8 loadBalanceInfoPresent:1; + tANI_U8 versionPresent:1; + tANI_U8 edcaParamPresent:1; + tANI_U8 capabilityPresent:1; + tANI_U8 titanPresent:1; + tANI_U8 taurusPresent:1; + tANI_U8 propChannelSwitchPresent:1; + tANI_U8 quietBssPresent:1; + tANI_U8 triggerStaScanPresent:1; + tANI_U8 rsvd:5; + + + tSirMacPropRateSet propRates; + tAniApName apName; // used in beacon/probe only + tSirAlternateRadioInfo alternateRadio; // used in assoc response only + tANI_U16 capability; // capability bit map + tSirMacPropVersion version; + tSirMacEdcaParamSetIE edca; + tChannelSwitchPropIEStruct channelSwitch; + tQuietBssIEStruct quietBss; + tANI_U8 triggerStaScanEnable; + + +} tSirPropIEStruct, *tpSirPropIEStruct; + + + +#endif /* __MAC_PROP_EXTS_H */ diff --git a/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h b/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h new file mode 100644 index 000000000000..52c172a78d70 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/sirMacProtDef.h @@ -0,0 +1,2922 @@ +/* + * Copyright (c) 2011-2016, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file sirMacProtDef.h contains the MAC/PHY protocol + * definitions used across various projects. + * Author: Chandra Modumudi + * Date: 02/27/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __MAC_PROT_DEFS_H +#define __MAC_PROT_DEFS_H + +#include "palTypes.h" +#include "sirTypes.h" +#include "wniCfg.h" +#include "aniCompiler.h" + + +///Capability information related +#define CAPABILITY_INFO_DELAYED_BA_BIT 14 +#define CAPABILITY_INFO_IMMEDIATE_BA_BIT 15 + +/// 11d MAC defaults +#define SIR_11B_CHANNEL_ID_BEGIN 1 +#define SIR_TOTAL_NUM_11B_CHANNELS 14 +#define SIR_11B_DEFAULT_MAX_TRANSMIT_POWER 20 +#define SIR_11A_CHANNEL_ID_BEGIN 240 +#define SIR_TOTAL_NUM_11A_CHANNELS 34 +#define SIR_11A_DEFAULT_MAX_TRANSMIT_POWER 16 + +/// 11h MAC defaults +#define SIR_11A_CHANNEL_BEGIN 34 +#define SIR_11A_CHANNEL_END 165 +#define SIR_11B_CHANNEL_BEGIN 1 +#define SIR_11B_CHANNEL_END 14 +#define SIR_11A_FREQUENCY_OFFSET 4 +#define SIR_11B_FREQUENCY_OFFSET 1 + + +#define PRIM_DEVICE_LEN (8) + +/// Maximum fragment size +#define SIR_MAC_MAX_FRAG_SIZE 2398 + +// maximum 802.11 PDU size +#define SIR_MAC_MAX_PDU_SIZE 2346 + +/// Length of the Frame Check Sum field at the end of every MAC frame +#define SIR_MAC_FCS_LENGTH 4 + +// Sizes of control frames +#define SIR_MAC_ACK_SIZE 14 +#define SIR_MAC_CTS_SIZE 14 +#define SIR_MAC_RTS_SIZE 20 +#define SIR_MAC_BRQ_SIZE 24 +#define SIR_MAC_BACK_SIZE 26 + +/// Current version of 802.11 +#define SIR_MAC_PROTOCOL_VERSION 0 + +// Frame Type definitions + +#define SIR_MAC_MGMT_FRAME 0x0 +#define SIR_MAC_CTRL_FRAME 0x1 +#define SIR_MAC_DATA_FRAME 0x2 + +#define SIR_MAC_FRAME_TYPE_START 0x0 +#define SIR_MAC_FRAME_TYPE_END 0x3 + +// Control frame subtype definitions + +#define SIR_MAC_CTRL_RR 4 +#define SIR_MAC_CTRL_BAR 8 +#define SIR_MAC_CTRL_BA 9 +#define SIR_MAC_CTRL_PS_POLL 10 +#define SIR_MAC_CTRL_RTS 11 +#define SIR_MAC_CTRL_CTS 12 +#define SIR_MAC_CTRL_ACK 13 +#define SIR_MAC_CTRL_CF_END 14 +#define SIR_MAC_CTRL_CF_END_ACK 15 + +#define GEN4_SCAN 1 +#ifdef GEN4_SCAN +#define SIR_MAC_MAX_DURATION_MICRO_SECONDS 32767 +#endif // GEN4_SCAN + +// Data frame subtype definitions +#define SIR_MAC_DATA_DATA 0 +#define SIR_MAC_DATA_DATA_ACK 1 +#define SIR_MAC_DATA_DATA_POLL 2 +#define SIR_MAC_DATA_DATA_ACK_POLL 3 +#define SIR_MAC_DATA_NULL 4 +#define SIR_MAC_DATA_NULL_ACK 5 +#define SIR_MAC_DATA_NULL_POLL 6 +#define SIR_MAC_DATA_NULL_ACK_POLL 7 +#define SIR_MAC_DATA_QOS_DATA 8 +#define SIR_MAC_DATA_QOS_DATA_ACK 9 +#define SIR_MAC_DATA_QOS_DATA_POLL 10 +#define SIR_MAC_DATA_QOS_DATA_ACK_POLL 11 +#define SIR_MAC_DATA_QOS_NULL 12 +#define SIR_MAC_DATA_QOS_NULL_ACK 13 +#define SIR_MAC_DATA_QOS_NULL_POLL 14 +#define SIR_MAC_DATA_QOS_NULL_ACK_POLL 15 + +#define SIR_MAC_FRAME_SUBTYPE_START 0 +#define SIR_MAC_FRAME_SUBTYPE_END 16 + +#define SIR_MAC_DATA_QOS_MASK 8 +#define SIR_MAC_DATA_NULL_MASK 4 +#define SIR_MAC_DATA_POLL_MASK 2 +#define SIR_MAC_DATA_ACK_MASK 1 + +// Management frame subtype definitions + +#define SIR_MAC_MGMT_ASSOC_REQ 0x0 +#define SIR_MAC_MGMT_ASSOC_RSP 0x1 +#define SIR_MAC_MGMT_REASSOC_REQ 0x2 +#define SIR_MAC_MGMT_REASSOC_RSP 0x3 +#define SIR_MAC_MGMT_PROBE_REQ 0x4 +#define SIR_MAC_MGMT_PROBE_RSP 0x5 +#define SIR_MAC_MGMT_BEACON 0x8 +#define SIR_MAC_MGMT_ATIM 0x9 +#define SIR_MAC_MGMT_DISASSOC 0xA +#define SIR_MAC_MGMT_AUTH 0xB +#define SIR_MAC_MGMT_DEAUTH 0xC +#define SIR_MAC_MGMT_ACTION 0xD +#define SIR_MAC_MGMT_RESERVED15 0xF + +// Action frame categories + +#define SIR_MAC_ACTION_SPECTRUM_MGMT 0 +#define SIR_MAC_ACTION_QOS_MGMT 1 +#define SIR_MAC_ACTION_DLP 2 +#define SIR_MAC_ACTION_BLKACK 3 +#define SIR_MAC_ACTION_PUBLIC_USAGE 4 +#define SIR_MAC_ACTION_RRM 5 +#define SIR_MAC_ACTION_FAST_BSS_TRNST 6 +#define SIR_MAC_ACTION_HT 7 +#define SIR_MAC_ACTION_SA_QUERY 8 +#define SIR_MAC_ACTION_PROT_DUAL_PUB 9 +#define SIR_MAC_ACTION_WNM 10 +#define SIR_MAC_ACTION_UNPROT_WNM 11 +#define SIR_MAC_ACTION_TDLS 12 +#define SIR_MAC_ACITON_MESH 13 +#define SIR_MAC_ACTION_MHF 14 +#define SIR_MAC_SELF_PROTECTED 15 +#define SIR_MAC_ACTION_WME 17 +#define SIR_MAC_ACTION_FST 18 +#define SIR_MAC_ACTION_VHT 21 + +#define SIR_MAC_ACTION_TX 1 +#define SIR_MAC_ACTION_RX 2 +// QoS management action codes + +#define SIR_MAC_QOS_ADD_TS_REQ 0 +#define SIR_MAC_QOS_ADD_TS_RSP 1 +#define SIR_MAC_QOS_DEL_TS_REQ 2 +#define SIR_MAC_QOS_SCHEDULE 3 +#define SIR_MAC_QOS_MAP_CONFIGURE 4 +// and these are proprietary +#define SIR_MAC_QOS_DEF_BA_REQ 4 +#define SIR_MAC_QOS_DEF_BA_RSP 5 +#define SIR_MAC_QOS_DEL_BA_REQ 6 +#define SIR_MAC_QOS_DEL_BA_RSP 7 + +#ifdef ANI_SUPPORT_11H +// Spectrum management action codes +#define SIR_MAC_ACTION_MEASURE_REQUEST_ID 0 +#define SIR_MAC_ACTION_MEASURE_REPORT_ID 1 +#define SIR_MAC_ACTION_TPC_REQUEST_ID 2 +#define SIR_MAC_ACTION_TPC_REPORT_ID 3 +#endif //ANI_SUPPORT_11H +#define SIR_MAC_ACTION_CHANNEL_SWITCH_ID 4 + + +#ifdef ANI_SUPPORT_11H +// Measurement Request/Report Type +#define SIR_MAC_BASIC_MEASUREMENT_TYPE 0 +#define SIR_MAC_CCA_MEASUREMENT_TYPE 1 +#define SIR_MAC_RPI_MEASUREMENT_TYPE 2 +#endif //ANI_SUPPORT_11H + +//RRM related. +//Refer IEEE Std 802.11k-2008, Section 7.3.2.21, table 7.29 +#if defined WLAN_FEATURE_VOWIFI + +#define SIR_MAC_RRM_CHANNEL_LOAD_TYPE 3 +#define SIR_MAC_RRM_NOISE_HISTOGRAM_BEACON 4 +#define SIR_MAC_RRM_BEACON_TYPE 5 +#define SIR_MAC_RRM_FRAME_TYPE 6 +#define SIR_MAC_RRM_STA_STATISTICS_TYPE 7 +#define SIR_MAC_RRM_LCI_TYPE 8 +#define SIR_MAC_RRM_TSM_TYPE 9 + +//RRM action codes +#define SIR_MAC_RRM_RADIO_MEASURE_REQ 0 +#define SIR_MAC_RRM_RADIO_MEASURE_RPT 1 +#define SIR_MAC_RRM_LINK_MEASUREMENT_REQ 2 +#define SIR_MAC_RRM_LINK_MEASUREMENT_RPT 3 +#define SIR_MAC_RRM_NEIGHBOR_REQ 4 +#define SIR_MAC_RRM_NEIGHBOR_RPT 5 + +#endif + +//VHT Action Field +#ifdef WLAN_FEATURE_11AC +#define SIR_MAC_VHT_OPMODE_NOTIFICATION 2 +#endif + +// HT Action Field Codes +#define SIR_MAC_SM_POWER_SAVE 1 + +// DLP action frame types +#define SIR_MAC_DLP_REQ 0 +#define SIR_MAC_DLP_RSP 1 +#define SIR_MAC_DLP_TEARDOWN 2 + +// block acknowledgement action frame types +#define SIR_MAC_BLKACK_ADD_REQ 0 +#define SIR_MAC_BLKACK_ADD_RSP 1 +#define SIR_MAC_BLKACK_DEL 2 +#define SIR_MAC_ACTION_VENDOR_SPECIFIC 9 +#define SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F +#define SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP 2 + +// Public Action for 20/40 BSS Coexistence +#ifdef WLAN_FEATURE_AP_HT40_24G +#define SIR_MAC_ACTION_2040_BSS_COEXISTENCE 0 +#endif + + +#ifdef WLAN_FEATURE_11W +//11w SA query request/response action frame category code +#define SIR_MAC_SA_QUERY_REQ 0 +#define SIR_MAC_SA_QUERY_RSP 1 +#endif + +#ifdef FEATURE_WLAN_TDLS +#define SIR_MAC_TDLS_SETUP_REQ 0 +#define SIR_MAC_TDLS_SETUP_RSP 1 +#define SIR_MAC_TDLS_SETUP_CNF 2 +#define SIR_MAC_TDLS_TEARDOWN 3 +#define SIR_MAC_TDLS_PEER_TRAFFIC_IND 4 +#define SIR_MAC_TDLS_CH_SWITCH_REQ 5 +#define SIR_MAC_TDLS_CH_SWITCH_RSP 6 +#define SIR_MAC_TDLS_PEER_TRAFFIC_RSP 9 +#define SIR_MAC_TDLS_DIS_REQ 10 +#define SIR_MAC_TDLS_DIS_RSP 14 +#endif + +/* WNM Action field values; IEEE Std 802.11-2012, 8.5.14.1, Table 8-250 */ +#define SIR_MAC_WNM_BSS_TM_QUERY 6 +#define SIR_MAC_WNM_BSS_TM_REQUEST 7 +#define SIR_MAC_WNM_BSS_TM_RESPONSE 8 +#define SIR_MAC_WNM_NOTIF_REQUEST 26 +#define SIR_MAC_WNM_NOTIF_RESPONSE 27 + +#define SIR_MAC_MAX_RANDOM_LENGTH 2306 + +//----------------------------------------------------------------------------- +// EID (Element ID) definitions +// and their min/max lengths +//----------------------------------------------------------------------------- + +#define SIR_MAC_SSID_EID 0 +#define SIR_MAC_SSID_EID_MIN 0 +#define SIR_MAC_SSID_EID_MAX 32 +#define SIR_MAC_RATESET_EID 1 +#define SIR_MAC_RATESET_EID_MIN 1 +#define SIR_MAC_RATESET_EID_MAX 12 +#define SIR_MAC_FH_PARAM_SET_EID 2 +#define SIR_MAC_FH_PARAM_SET_EID_MIN 5 +#define SIR_MAC_FH_PARAM_SET_EID_MAX 5 +#define SIR_MAC_DS_PARAM_SET_EID 3 +#define SIR_MAC_DS_PARAM_SET_EID_MIN 1 +#define SIR_MAC_DS_PARAM_SET_EID_MAX 1 +#define SIR_MAC_CF_PARAM_SET_EID 4 +#define SIR_MAC_CF_PARAM_SET_EID_MIN 6 +#define SIR_MAC_CF_PARAM_SET_EID_MAX 6 +#define SIR_MAC_TIM_EID 5 +#define SIR_MAC_TIM_EID_MIN 3 +#define SIR_MAC_TIM_EID_MAX 254 +#define SIR_MAC_IBSS_PARAM_SET_EID 6 +#define SIR_MAC_IBSS_PARAM_SET_EID_MIN 2 +#define SIR_MAC_IBSS_PARAM_SET_EID_MAX 2 +#define SIR_MAC_COUNTRY_EID 7 +#define SIR_MAC_COUNTRY_EID_MIN 6 +#define SIR_MAC_COUNTRY_EID_MAX 254 +#define SIR_MAC_FH_PARAMS_EID 8 +#define SIR_MAC_FH_PARAMS_EID_MIN 4 +#define SIR_MAC_FH_PARAMS_EID_MAX 4 +#define SIR_MAC_FH_PATTERN_EID 9 +#define SIR_MAC_FH_PATTERN_EID_MIN 4 +#define SIR_MAC_FH_PATTERN_EID_MAX 254 +#define SIR_MAC_REQUEST_EID 10 +#define SIR_MAC_REQUEST_EID_MIN 1 +#define SIR_MAC_REQUEST_EID_MAX 255 +#define SIR_MAC_QBSS_LOAD_EID 11 +#define SIR_MAC_QBSS_LOAD_EID_MIN 5 +#define SIR_MAC_QBSS_LOAD_EID_MAX 5 +#define SIR_MAC_EDCA_PARAM_SET_EID 12 // EDCA parameter set +#define SIR_MAC_EDCA_PARAM_SET_EID_MIN 18 +#define SIR_MAC_EDCA_PARAM_SET_EID_MAX 20 // TBD temp - change backto 18 +#define SIR_MAC_TSPEC_EID 13 +#define SIR_MAC_TSPEC_EID_MIN 55 +#define SIR_MAC_TSPEC_EID_MAX 55 +#define SIR_MAC_TCLAS_EID 14 +#define SIR_MAC_TCLAS_EID_MIN 4 +#define SIR_MAC_TCLAS_EID_MAX 255 +#define SIR_MAC_QOS_SCHEDULE_EID 15 +#define SIR_MAC_QOS_SCHEDULE_EID_MIN 14 +#define SIR_MAC_QOS_SCHEDULE_EID_MAX 14 +#define SIR_MAC_CHALLENGE_TEXT_EID 16 +#define SIR_MAC_CHALLENGE_TEXT_EID_MIN 1 +#define SIR_MAC_CHALLENGE_TEXT_EID_MAX 253 +// reserved 17-31 +#define SIR_MAC_PWR_CONSTRAINT_EID 32 +#define SIR_MAC_PWR_CONSTRAINT_EID_MIN 1 +#define SIR_MAC_PWR_CONSTRAINT_EID_MAX 1 +#define SIR_MAC_PWR_CAPABILITY_EID 33 +#define SIR_MAC_PWR_CAPABILITY_EID_MIN 2 +#define SIR_MAC_PWR_CAPABILITY_EID_MAX 2 +#define SIR_MAC_TPC_REQ_EID 34 +#define SIR_MAC_TPC_REQ_EID_MIN 0 +#define SIR_MAC_TPC_REQ_EID_MAX 255 +// SIR_MAC_EXTENDED_CAP_EID 35 +#define SIR_MAC_TPC_RPT_EID 35 +#define SIR_MAC_TPC_RPT_EID_MIN 2 +#define SIR_MAC_TPC_RPT_EID_MAX 2 +#define SIR_MAC_SPRTD_CHNLS_EID 36 +#define SIR_MAC_SPRTD_CHNLS_EID_MIN 2 +#define SIR_MAC_SPRTD_CHNLS_EID_MAX 254 +#define SIR_MAC_CHNL_SWITCH_ANN_EID 37 +#define SIR_MAC_CHNL_SWITCH_ANN_EID_MIN 3 +#define SIR_MAC_CHNL_SWITCH_ANN_EID_MAX 3 +#define SIR_MAC_MEAS_REQ_EID 38 +#define SIR_MAC_MEAS_REQ_EID_MIN 3 +#define SIR_MAC_MEAS_REQ_EID_MAX 255 +#define SIR_MAC_MEAS_RPT_EID 39 +#define SIR_MAC_MEAS_RPT_EID_MIN 3 +#define SIR_MAC_MEAS_RPT_EID_MAX 255 +#define SIR_MAC_QUIET_EID 40 +#define SIR_MAC_QUIET_EID_MIN 6 +#define SIR_MAC_QUIET_EID_MAX 6 +#define SIR_MAC_IBSS_DFS_EID 41 +#define SIR_MAC_IBSS_DFS_EID_MIN 7 +#define SIR_MAC_IBSS_DFS_EID_MAX 255 +#define SIR_MAC_ERP_INFO_EID 42 +#define SIR_MAC_ERP_INFO_EID_MIN 0 +#define SIR_MAC_ERP_INFO_EID_MAX 255 +#define SIR_MAC_TS_DELAY_EID 43 +#define SIR_MAC_TS_DELAY_EID_MIN 4 +#define SIR_MAC_TS_DELAY_EID_MAX 4 +#define SIR_MAC_TCLAS_PROC_EID 44 +#define SIR_MAC_TCLAS_PROC_EID_MIN 1 +#define SIR_MAC_TCLAS_PROC_EID_MAX 1 +#define SIR_MAC_QOS_CAPABILITY_EID 46 +#define SIR_MAC_QOS_CAPABILITY_EID_MIN 1 +#define SIR_MAC_QOS_CAPABILITY_EID_MAX 1 +#define SIR_MAC_RSN_EID 48 +#define SIR_MAC_RSN_EID_MIN 4 +#define SIR_MAC_RSN_EID_MAX 254 + +//using reserved EID for Qos Action IE for now, +//need to check 11e spec for the actual EID +#define SIR_MAC_QOS_ACTION_EID 49 +#define SIR_MAC_QOS_ACTION_EID_MIN 4 +#define SIR_MAC_QOS_ACTION_EID_MAX 255 +#define SIR_MAC_EXTENDED_RATE_EID 50 +#define SIR_MAC_EXTENDED_RATE_EID_MIN 0 +#define SIR_MAC_EXTENDED_RATE_EID_MAX 255 +// reserved 51-69 +#define SIR_MAC_RM_ENABLED_CAPABILITY_EID 70 +#define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MIN 5 +#define SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX 5 +// reserved 71-220 +#define SIR_MAC_WPA_EID 221 +#define SIR_MAC_WPA_EID_MIN 0 +#define SIR_MAC_WPA_EID_MAX 255 + +#define SIR_MAC_EID_VENDOR 221 + +// reserved 222-254 +#define SIR_MAC_HT_CAPABILITIES_EID 45 +#define SIR_MAC_HT_CAPABILITIES_EID_MIN 0 +#define SIR_MAC_HT_CAPABILITIES_EID_MAX 255 +#define SIR_MAC_HT_INFO_EID 61 +#define SIR_MAC_HT_INFO_EID_MIN 0 +#define SIR_MAC_HT_INFO_EID_MAX 255 +#define SIR_MAC_OBSS_SCAN_PARAMETERS_EID 74 +#define SIR_MAC_EXTENDED_CAPABILITIES_EID 127 + +#ifdef WLAN_FEATURE_11AC +#define SIR_MAC_VHT_CAPABILITIES_EID 191 +#define SIR_MAC_VHT_OPERATION_EID 192 +#define SIR_MAC_VHT_EXT_BSS_LOAD_EID 193 +#define SIR_MAC_VHT_OPMODE_EID 199 +#endif +#define SIR_MAC_MAX_SUPPORTED_MCS_SET 16 + +/// Workaround IE to change beacon length when it is 4*n+1 +#define SIR_MAC_ANI_WORKAROUND_EID 255 +#define SIR_MAC_ANI_WORKAROUND_EID_MIN 0 +#define SIR_MAC_ANI_WORKAROUND_EID_MAX 255 + +#define SIR_MAC_MAX_ADD_IE_LENGTH 500 +/// Maximum length of each IE +#define SIR_MAC_MAX_IE_LENGTH 255 + +/// Maximum length of each IE +#define SIR_MAC_RSN_IE_MAX_LENGTH 255 +#define SIR_MAC_WPA_IE_MAX_LENGTH 255 +/// Minimum length of each IE +#define SIR_MAC_RSN_IE_MIN_LENGTH 2 +#define SIR_MAC_WPA_IE_MIN_LENGTH 6 + +#ifdef FEATURE_WLAN_ESE +#define ESE_VERSION_4 4 +#define ESE_VERSION_SUPPORTED ESE_VERSION_4 + +// When station sends Radio Management Cap. +// State should be normal=1 +// Mbssid Mask should be 0 +#define RM_STATE_NORMAL 1 +#endif + +#define SIR_MAC_OUI_VERSION_1 1 + +// OUI and type definition for WPA IE in network byte order +#define SIR_MAC_WPA_OUI 0x01F25000 +#define SIR_MAC_WME_OUI 0x02F25000 +#define SIR_MAC_WSM_OUI SIR_MAC_WME_OUI +#define SIR_MAC_WSC_OUI "\x00\x50\xf2\x04" +#define SIR_MAC_WSC_OUI_SIZE 4 +#define SIR_MAC_P2P_OUI "\x50\x6f\x9a\x09" +#define SIR_MAC_P2P_OUI_SIZE 4 +#define SIR_P2P_NOA_ATTR 12 +#define SIR_MAX_NOA_ATTR_LEN 31 +#define SIR_MAX_NOA_DESCR 2 +#define SIR_P2P_IE_HEADER_LEN 6 + +#define SIR_MAC_CISCO_OUI "\x00\x40\x96" +#define SIR_MAC_CISCO_OUI_SIZE 3 + +// min size of wme oui header: oui(3) + type + subtype + version +#define SIR_MAC_OUI_WME_HDR_MIN 6 + +// OUI subtype and their lengths +#define SIR_MAC_OUI_SUBTYPE_WME_INFO 0 +#define SIR_MAC_OUI_WME_INFO_MIN 7 +#define SIR_MAC_OUI_WME_INFO_MAX 7 + +#define SIR_MAC_OUI_SUBTYPE_WME_PARAM 1 +#define SIR_MAC_OUI_WME_PARAM_MIN 24 +#define SIR_MAC_OUI_WME_PARAM_MAX 24 + +#define SIR_MAC_OUI_SUBTYPE_WME_TSPEC 2 +#define SIR_MAC_OUI_WME_TSPEC_MIN 61 +#define SIR_MAC_OUI_WME_TSPEC_MAX 61 + +#define SIR_MAC_OUI_SUBTYPE_WSM_TSPEC 2 // same as WME TSPEC +#define SIR_MAC_OUI_WSM_TSPEC_MIN 61 +#define SIR_MAC_OUI_WSM_TSPEC_MAX 61 + +// reserved subtypes 3-4 +// WSM capability +#define SIR_MAC_OUI_SUBTYPE_WSM_CAPABLE 5 +#define SIR_MAC_OUI_WSM_CAPABLE_MIN 7 +#define SIR_MAC_OUI_WSM_CAPABLE_MAX 7 +// WSM classifier +#define SIR_MAC_OUI_SUBTYPE_WSM_TCLAS 6 +#define SIR_MAC_OUI_WSM_TCLAS_MIN 10 +#define SIR_MAC_OUI_WSM_TCLAS_MAX 255 +// classifier processing element +#define SIR_MAC_OUI_SUBTYPE_WSM_TCLASPROC 7 +#define SIR_MAC_OUI_WSM_TCLASPROC_MIN 7 +#define SIR_MAC_OUI_WSM_TCLASPROC_MAX 7 +// tspec delay element +#define SIR_MAC_OUI_SUBTYPE_WSM_TSDELAY 8 +#define SIR_MAC_OUI_WSM_TSDELAY_MIN 10 +#define SIR_MAC_OUI_WSM_TSDELAY_MAX 10 +// schedule element +#define SIR_MAC_OUI_SUBTYPE_WSM_SCHEDULE 9 +#define SIR_MAC_OUI_WSM_SCHEDULE_MIN 20 +#define SIR_MAC_OUI_WSM_SCHEDULE_MAX 20 + +#ifdef WLAN_NS_OFFLOAD +#define SIR_MAC_NS_OFFLOAD_SIZE 1 //support only one IPv6 offload +#define SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA 2 //Number of target IP in NA frames. It must be at least 2 +#define SIR_MAC_IPV6_ADDR_LEN 16 +#define SIR_IPV6_ADDR_VALID 1 +#endif //WLAN_NS_OFFLOAD +#define SIR_MAC_ARP_OFFLOAD_SIZE 1 + +// total length of an Info element including T/L fields +#define EID_LEN(eid) (2 + (eid)) + +// support for radar Detect, Channel Switch +#define CHANNEL_SWITCH_MAX_FRAME_SIZE 256 + + +// Length of Channel Switch related message +#define SIR_SME_CHANNEL_SWITCH_SIZE (sizeof(tANI_U8) + 2 *sizeof(tANI_U16) + sizeof(tANI_U32) + sizeof(ePhyChanBondState)) +#define SIR_CHANNEL_SWITCH_IE_SIZE EID_LEN(SIR_MAC_CHNL_SWITCH_ANN_EID_MIN) + +//Measurement Request/Report messages +#define SIR_MEAS_REQ_FIELD_SIZE 11 +#define SIR_MEAS_REQ_IE_SIZE (5 + SIR_MEAS_REQ_FIELD_SIZE) +#define SIR_MEAS_REQ_ACTION_FRAME_SIZE (3 + SIR_MEAS_REQ_IE_SIZE) +#define SIR_MEAS_MAX_FRAME_SIZE 256 +#define SIR_MEAS_REPORT_MIN_FRAME_SIZE (3 + EID_LEN(SIR_MAC_MEAS_RPT_EID_MIN)) + +#define SIR_MAC_SET_MEAS_REQ_ENABLE(x) (((tANI_U8) x) | 2) +#define SIR_MAC_SET_MEAS_REQ_REQUEST(x) (((tANI_U8) x) | 4) +#define SIR_MAC_SET_MEAS_REQ_REPORT(x) (((tANI_U8) x) | 8) + +#define SIR_MAC_SET_MEAS_REPORT_LATE(x) (((tANI_U8) x) | 1) +#define SIR_MAC_SET_MEAS_REPORT_INCAPABLE(x) (((tANI_U8) x) | 2) +#define SIR_MAC_SET_MEAS_REPORT_REFUSE(x) (((tANI_U8) x) | 4) + +// Length of TPC Request Action Frame +#define SIR_TPC_REQ_ACTION_FRAME_SIZE (3 + EID_LEN(SIR_MAC_TPC_REQ_EID_MIN)) +#define SIR_TPC_REPORT_ACTION_FRAME_SIZE (3 + EID_LEN(SIR_MAC_TPC_RPT_EID_MIN)) +#define SIR_TPC_MAX_FRAME_SIZE 256 +//----------------------------------------------------------------------------- + +// OFFSET definitions for fixed fields in Management frames + +// Beacon/Probe Response offsets +#define SIR_MAC_TS_OFFSET 0 +#define SIR_MAC_BEACON_INT_OFFSET 8 // Beacon Interval offset +#define SIR_MAC_B_PR_CAPAB_OFFSET 10 +#define SIR_MAC_B_PR_SSID_OFFSET 12 + +// Association/Reassociation offsets +#define SIR_MAC_ASSOC_CAPAB_OFFSET 0 +#define SIR_MAC_LISTEN_INT_OFFSET 2 // Listen Interval offset +#define SIR_MAC_ASSOC_SSID_OFFSET 4 +#define SIR_MAC_CURRENT_AP_OFFSET 4 +#define SIR_MAC_REASSOC_SSID_OFFSET 10 +#define SIR_MAC_ASSOC_STATUS_CODE_OFFSET 2 +#define SIR_MAC_ASSOC_AID_OFFSET 4 +#define SIR_MAC_ASSOC_RSP_RATE_OFFSET 6 + +// Disassociation/Deauthentication offsets +#define SIR_MAC_REASON_CODE_OFFSET 0 + +// Probe Request offset +#define SIR_MAC_PROBE_REQ_SSID_OFFSET 0 + +// Authentication offsets +#define SIR_MAC_AUTH_ALGO_OFFSET 0 +#define SIR_MAC_AUTH_XACT_SEQNUM_OFFSET 2 +#define SIR_MAC_AUTH_STATUS_CODE_OFFSET 4 +#define SIR_MAC_AUTH_CHALLENGE_OFFSET 6 + +/// Transaction sequence number definitions (used in Authentication frames) +#define SIR_MAC_AUTH_FRAME_1 1 +#define SIR_MAC_AUTH_FRAME_2 2 +#define SIR_MAC_AUTH_FRAME_3 3 +#define SIR_MAC_AUTH_FRAME_4 4 + +/// Protocol defined MAX definitions +#define SIR_MAC_ADDR_LENGTH 6 +#define SIR_MAC_MAX_SSID_LENGTH 32 +#define SIR_MAC_MAX_NUMBER_OF_RATES 12 +#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4 +#define SIR_MAC_KEY_LENGTH 13 // WEP Maximum key length size +#define SIR_MAC_AUTH_CHALLENGE_LENGTH 253 +#define SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH 128 +#define SIR_MAC_WEP_IV_LENGTH 4 +#define SIR_MAC_WEP_ICV_LENGTH 4 +#define SIR_MAC_CHALLENGE_ID_LEN 2 + +/* 2 bytes each for auth algo number, transaction number and status code */ +#define SIR_MAC_AUTH_FRAME_INFO_LEN 6 + +/// MAX key length when ULA is used +#define SIR_MAC_MAX_KEY_LENGTH 32 + +/// Macro definitions for get/set on FC fields +#define SIR_MAC_GET_PROT_VERSION(x) ((((tANI_U16) x) & 0x0300) >> 8) +#define SIR_MAC_GET_FRAME_TYPE(x) ((((tANI_U16) x) & 0x0C00) >> 8) +#define SIR_MAC_GET_FRAME_SUB_TYPE(x) ((((tANI_U16) x) & 0xF000) >> 12) +#define SIR_MAC_GET_WEP_BIT_IN_FC(x) (((tANI_U16) x) & 0x0040) +#define SIR_MAC_SET_PROT_VERSION(x) ((tANI_U16) x) +#define SIR_MAC_SET_FRAME_TYPE(x) (((tANI_U16) x) << 2) +#define SIR_MAC_SET_FRAME_SUB_TYPE(x) (((tANI_U16) x) << 4) +#define SIR_MAC_SET_WEP_BIT_IN_FC(x) (((tANI_U16) x) << 14) + +/// Macro definitions for get/set on capabilityInfo bits +#define SIR_MAC_GET_ESS(x) (((tANI_U16) x) & 0x0001) +#define SIR_MAC_GET_IBSS(x) ((((tANI_U16) x) & 0x0002) >> 1) +#define SIR_MAC_GET_CF_POLLABLE(x) ((((tANI_U16) x) & 0x0004) >> 2) +#define SIR_MAC_GET_CF_POLL_REQ(x) ((((tANI_U16) x) & 0x0008) >> 3) +#define SIR_MAC_GET_PRIVACY(x) ((((tANI_U16) x) & 0x0010) >> 4) +#define SIR_MAC_GET_SHORT_PREAMBLE(x) ((((tANI_U16) x) & 0x0020) >> 5) +#define SIR_MAC_GET_SPECTRUM_MGMT(x) ((((tANI_U16) x) & 0x0100) >> 8) +#define SIR_MAC_GET_QOS(x) ((((tANI_U16) x) & 0x0200) >> 9) +#define SIR_MAC_GET_SHORT_SLOT_TIME(x) ((((tANI_U16) x) & 0x0400) >> 10) +#define SIR_MAC_GET_APSD(x) ((((tANI_U16) x) & 0x0800) >> 11) +#if defined WLAN_FEATURE_VOWIFI +#define SIR_MAC_GET_RRM(x) ((((tANI_U16) x) & 0x1000) >> 12) +#endif +#define SIR_MAC_GET_BLOCK_ACK(x) ((((tANI_U16) x) & 0xc000) >> CAPABILITY_INFO_DELAYED_BA_BIT) +#define SIR_MAC_SET_ESS(x) (((tANI_U16) x) | 0x0001) +#define SIR_MAC_SET_IBSS(x) (((tANI_U16) x) | 0x0002) +#define SIR_MAC_SET_CF_POLLABLE(x) (((tANI_U16) x) | 0x0004) +#define SIR_MAC_SET_CF_POLL_REQ(x) (((tANI_U16) x) | 0x0008) +#define SIR_MAC_SET_PRIVACY(x) (((tANI_U16) x) | 0x0010) +#define SIR_MAC_SET_SHORT_PREAMBLE(x) (((tANI_U16) x) | 0x0020) +#define SIR_MAC_SET_SPECTRUM_MGMT(x) (((tANI_U16) x) | 0x0100) +#define SIR_MAC_SET_QOS(x) (((tANI_U16) x) | 0x0200) +#define SIR_MAC_SET_SHORT_SLOT_TIME(x) (((tANI_U16) x) | 0x0400) +#define SIR_MAC_SET_APSD(x) (((tANI_U16) x) | 0x0800) +#if defined WLAN_FEATURE_VOWIFI +#define SIR_MAC_SET_RRM(x) (((tANI_U16) x) | 0x1000) +#endif +#define SIR_MAC_SET_GROUP_ACK(x) (((tANI_U16) x) | 0x4000) + +// bitname must be one of the above, eg ESS, CF_POLLABLE, etc. +#define SIR_MAC_CLEAR_CAPABILITY(u16value, bitname) \ + ((u16value) &= (~(SIR_MAC_SET_##bitname(0)))) + +#define IS_WES_MODE_ENABLED(x) \ + ((x)->roam.configParam.isWESModeEnabled) + +#define BA_RECIPIENT 1 +#define BA_INITIATOR 2 +#define BA_BOTH_DIRECTIONS 3 + +/// Status Code (present in Management response frames) enum + +typedef enum eSirMacStatusCodes +{ + eSIR_MAC_SUCCESS_STATUS = 0, //Reserved + eSIR_MAC_UNSPEC_FAILURE_STATUS = 1, //Unspecified reason + // 802.11 reserved 2-9 + /* + WMM status codes(standard 1.1 table 9) + Table 9 ADDTS Response Status Codes + Value Operation + 0 Admission accepted + 1 Invalid parameters + 2 Reserved + 3 Refused + 4-255 Reserved + */ + eSIR_MAC_WME_INVALID_PARAMS_STATUS = 1, // ?? + eSIR_MAC_WME_REFUSED_STATUS = 3, // ?? + eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS = 10, //Cannot support all requested capabilities in the Capability Information field + eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS = 11, //Reassociation denied due to inability to confirm that association exists + eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS = 12, //Association denied due to reason outside the scope of this standard + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS = 13, //Responding station does not support the specified authentication algorithm + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS = 14, //Received an Authentication frame with authentication transaction sequence number + //out of expected sequence + eSIR_MAC_CHALLENGE_FAILURE_STATUS = 15, //Authentication rejected because of challenge failure + eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS = 16, //Authentication rejected due to timeout waiting for next frame in sequence + eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS = 17, //Association denied because AP is unable to handle additional associated stations + eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS = 18, //Association denied due to requesting station not supporting all of the data rates in the + //BSSBasicRateSet parameter + eSIR_MAC_SHORT_PREAMBLE_NOT_SUPPORTED_STATUS = 19, //Association denied due to requesting station not supporting the short preamble + //option + eSIR_MAC_PBCC_NOT_SUPPORTED_STATUS = 20, //Association denied due to requesting station not supporting the PBCC modulation + //option + eSIR_MAC_CHANNEL_AGILITY_NOT_SUPPORTED_STATUS = 21, //Association denied due to requesting station not supporting the Channel Agility + //option + eSIR_MAC_SPECTRUM_MGMT_REQD_STATUS = 22, //Association request rejected because Spectrum Management capability is required + eSIR_MAC_PWR_CAPABILITY_BAD_STATUS = 23, //Association request rejected because the information in the Power Capability + //element is unacceptable + eSIR_MAC_SPRTD_CHANNELS_BAD_STATUS = 24, //Association request rejected because the information in the Supported Channels + //element is unacceptable + eSIR_MAC_SHORT_SLOT_NOT_SUPORTED_STATUS = 25, //Association denied due to requesting station not supporting the Short Slot Time + //option + eSIR_MAC_DSSS_OFDM_NOT_SUPPORTED_STATUS = 26, //Association denied due to requesting station not supporting the DSSS-OFDM option + // reserved 27-29 + eSIR_MAC_TRY_AGAIN_LATER = 30, //Association request rejected temporarily, try again later + // reserved 31 + eSIR_MAC_QOS_UNSPECIFIED_FAILURE_STATUS = 32, //Unspecified, QoS-related failure + eSIR_MAC_QAP_NO_BANDWIDTH_STATUS = 33, //Association denied because QoS AP has insufficient bandwidth to handle another + //QoS STA + eSIR_MAC_XS_FRAME_LOSS_STATUS = 34, //Association denied due to excessive frame loss rates and/or poor conditions on cur- + //rent operating channel + eSIR_MAC_STA_QOS_NOT_SUPPORTED_STATUS = 35, //Association (with QoS BSS) denied because the requesting STA does not support the + //QoS facility + eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS = 36, //Reserved + eSIR_MAC_REQ_DECLINED_STATUS = 37, //The request has been declined + eSIR_MAC_INVALID_PARAM_STATUS = 38, //The request has not been successful as one or more parameters have invalid values + eSIR_MAC_TS_NOT_HONOURED_STATUS = 39, //The TS has not been created because the request cannot be honored; however, a suggested + //TSPEC is provided so that the initiating STA may attempt to set another TS + //with the suggested changes to the TSPEC + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS = 40, //Invalid information element, i.e., an information element defined in this standard for + //which the content does not meet the specifications in Clause 7 + eSIR_MAC_INVALID_GROUP_CIPHER_STATUS = 41, //Invalid group cipher + eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS = 42, //Invalid pairwise cipher + eSIR_MAC_INVALID_AKMP_STATUS = 43, //Invalid AKMP + eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS = 44, //Unsupported RSN information element version + eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS = 45, //Invalid RSN information element capabilities + eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS = 46, //Cipher suite rejected because of security policy + eSIR_MAC_TS_NOT_CREATED_STATUS = 47, //The TS has not been created; however, the HC may be capable of creating a TS, in + //response to a request, after the time indicated in the TS Delay element + eSIR_MAC_DL_NOT_ALLOWED_STATUS = 48, //Direct link is not allowed in the BSS by policy + eSIR_MAC_DEST_STA_NOT_KNOWN_STATUS = 49, //The Destination STA is not present within this BSS + eSIR_MAC_DEST_STA_NOT_QSTA_STATUS = 50, //The Destination STA is not a QoS STA + eSIR_MAC_INVALID_LISTEN_INTERVAL_STATUS = 51, //Association denied because the ListenInterval is too large + + eSIR_MAC_DSSS_CCK_RATE_MUST_SUPPORT_STATUS = 52, //FIXME: + eSIR_MAC_DSSS_CCK_RATE_NOT_SUPPORT_STATUS = 53, + eSIR_MAC_PSMP_CONTROLLED_ACCESS_ONLY_STATUS = 54, +#ifdef FEATURE_WLAN_ESE + eSIR_MAC_ESE_UNSPECIFIED_QOS_FAILURE_STATUS = 200, //ESE-Unspecified, QoS related failure in (Re)Assoc response frames + eSIR_MAC_ESE_TSPEC_REQ_REFUSED_STATUS = 201, //ESE-TSPEC request refused due to AP's policy configuration in AddTs Rsp, (Re)Assoc Rsp. + eSIR_MAC_ESE_ASSOC_DENIED_INSUFF_BW_STATUS = 202, //ESE-Assoc denied due to insufficient bandwidth to handle new TS in (Re)Assoc Rsp. + eSIR_MAC_ESE_INVALID_PARAMETERS_STATUS = 203, //ESE-Invalid parameters. (Re)Assoc request had one or more TSPEC parameters with + //invalid values. +#endif + +} tSirMacStatusCodes; + +/** + * Reason Code (present in Deauthentication/Disassociation + * Management frames) enum + */ +typedef enum eSirMacReasonCodes +{ + eSIR_MAC_UNSPEC_FAILURE_REASON = 1, //Unspecified reason + eSIR_MAC_PREV_AUTH_NOT_VALID_REASON = 2, //Previous authentication no longer valid + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON = 3, //Deauthenticated because sending station is leaving (or has left) IBSS or ESS + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON = 4, //Disassociated due to inactivity + eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON = 5, //Disassociated because AP is unable to handle all currently associated stations + eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON = 6, //Class 2 frame received from nonauthenticated station + eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON = 7, //Class 3 frame received from nonassociated station + eSIR_MAC_DISASSOC_LEAVING_BSS_REASON = 8, //Disassociated because sending station is leaving (or has left) BSS + eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON = 9, //Station requesting (re)association is not authenticated with responding station + eSIR_MAC_PWR_CAPABILITY_BAD_REASON = 10, //Disassociated because the information in the Power Capability element is unacceptable + eSIR_MAC_SPRTD_CHANNELS_BAD_REASON = 11, //Disassociated because the information in the Supported Channels element is unacceptable + // reserved 12 + eSIR_MAC_INVALID_IE_REASON = 13, //Invalid information element, i.e., an information element defined in this standard for + //which the content does not meet the specifications in Clause 7 + eSIR_MAC_MIC_FAILURE_REASON = 14, //Message integrity code (MIC) failure + eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON = 15, //4-Way Handshake timeout + eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON = 16, //Group Key Handshake timeout + eSIR_MAC_RSN_IE_MISMATCH_REASON = 17, //Information element in 4-Way Handshake different from (Re)Association Request/Probe + //Response/Beacon frame + eSIR_MAC_INVALID_MC_CIPHER_REASON = 18, //Invalid group cipher + eSIR_MAC_INVALID_UC_CIPHER_REASON = 19, //Invalid pairwise cipher + eSIR_MAC_INVALID_AKMP_REASON = 20, //Invalid AKMP + eSIR_MAC_UNSUPPORTED_RSN_IE_VER_REASON = 21, //Unsupported RSN information element version + eSIR_MAC_INVALID_RSN_CAPABILITIES_REASON = 22, //Invalid RSN information element capabilities + eSIR_MAC_1X_AUTH_FAILURE_REASON = 23, //IEEE 802.1X authentication failed + eSIR_MAC_CIPHER_SUITE_REJECTED_REASON = 24, //Cipher suite rejected because of the security policy +#ifdef FEATURE_WLAN_TDLS + eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE = 25, //TDLS direct link teardown due to TDLS peer STA unreachable via the TDLS direct link + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON = 26, //TDLS direct link teardown for unspecified reason +#endif + // reserved 27 - 30 +#ifdef WLAN_FEATURE_11W + eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION = 31, //Robust management frames policy violation +#endif + eSIR_MAC_QOS_UNSPECIFIED_REASON = 32, //Disassociated for unspecified, QoS-related reason + eSIR_MAC_QAP_NO_BANDWIDTH_REASON = 33, //Disassociated because QoS AP lacks sufficient bandwidth for this QoS STA + eSIR_MAC_XS_UNACKED_FRAMES_REASON = 34, //Disassociated because excessive number of frames need to be acknowledged, but are not + //acknowledged due to AP transmissions and/or poor channel conditions + eSIR_MAC_BAD_TXOP_USE_REASON = 35, //Disassociated because STA is transmitting outside the limits of its TXOPs + eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON = 36, //Requested from peer STA as the STA is leaving the BSS (or resetting) + eSIR_MAC_PEER_REJECT_MECHANISIM_REASON = 37, //Requested from peer STA as it does not want to use the mechanism + eSIR_MAC_MECHANISM_NOT_SETUP_REASON = 38, //Requested from peer STA as the STA received frames using the mechanism for which a + //setup is required + eSIR_MAC_PEER_TIMEDOUT_REASON = 39, //Requested from peer STA due to timeout + eSIR_MAC_CIPHER_NOT_SUPPORTED_REASON = 45, //Peer STA does not support the requested cipher suite + eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON = 46, //FT reason + //reserved 47 - 65535. + eSIR_BEACON_MISSED = 65534, //We invented this to tell beacon missed case +} tSirMacReasonCodes; + + +typedef enum eSirMacChannelType +{ + eSIR_MAC_11A_BAND, + eSIR_MAC_11B_BAND, + eSIR_MAC_UNKNOWN_BAND +} tSirMacChannelType; + +// BA Initiator v/s Recipient +typedef enum eBADirection +{ + eBA_RECIPIENT, + eBA_INITIATOR +} tBADirection; + +// A-MPDU/BA Enable/Disable in Tx/Rx direction +typedef enum eBAEnable +{ + eBA_DISABLE, + eBA_ENABLE +} tBAEnable; + +// A-MPDU/BA Policy +typedef enum eBAPolicy +{ + eBA_UNCOMPRESSED, + eBA_COMPRESSED +} tBAPolicy; + +// A-MPDU/BA Policy +typedef enum eBAPolicyType +{ + eBA_POLICY_DELAYED, + eBA_POLICY_IMMEDIATE +} tBAPolicyType; + +#ifdef WLAN_FEATURE_VOWIFI +/* Based on table 7-43a from 802.11k Spec */ +typedef enum eRrmNeighborReachability +{ + eREACHABILITY_RESERVED, + eREACHABILITY_NOT_REACHABLE, + eREACHABILITY_UNKNOWN, + eREACHABILITY_REACHABLE, +} tRrmNeighborReachability; +#endif /* WLAN_FEATURE_VOWIFI */ + +/// Frame control field format (2 bytes) +typedef __ani_attr_pre_packed struct sSirMacFrameCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 subType :4; + tANI_U8 type :2; + tANI_U8 protVer :2; + + tANI_U8 order :1; + tANI_U8 wep :1; + tANI_U8 moreData :1; + tANI_U8 powerMgmt :1; + tANI_U8 retry :1; + tANI_U8 moreFrag :1; + tANI_U8 fromDS :1; + tANI_U8 toDS :1; + +#else + + tANI_U8 protVer :2; + tANI_U8 type :2; + tANI_U8 subType :4; + + tANI_U8 toDS :1; + tANI_U8 fromDS :1; + tANI_U8 moreFrag :1; + tANI_U8 retry :1; + tANI_U8 powerMgmt :1; + tANI_U8 moreData :1; + tANI_U8 wep :1; + tANI_U8 order :1; + +#endif + +} __ani_attr_packed tSirMacFrameCtl, *tpSirMacFrameCtl; + +/// Sequence control field +typedef __ani_attr_pre_packed struct sSirMacSeqCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 seqNumLo : 4; + tANI_U8 fragNum : 4; + + tANI_U8 seqNumHi : 8; + +#else + + tANI_U8 fragNum : 4; + tANI_U8 seqNumLo : 4; + tANI_U8 seqNumHi : 8; + +#endif +} __ani_attr_packed tSirMacSeqCtl, *tpSirMacSeqCtl; + +// ACK policies + +typedef enum eSirMacAckPolicy +{ + eSIR_MAC_IMMEDIATE_ACK=0 , + eSIR_MAC_NO_ACK, + eSIR_MAC_NO_EXPLICIT_ACK, + eSIR_MAC_BURST_ACK +} tSirMacAckPolicy; + +/// QoS control field +typedef __ani_attr_pre_packed struct sSirMacQosCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 rsvd : 1; + tANI_U8 ackPolicy : 2; + tANI_U8 esop_txopUnit : 1; + tANI_U8 tid : 4; + + tANI_U8 txop : 8; + +#else + + tANI_U8 tid : 4; + tANI_U8 esop_txopUnit : 1; + tANI_U8 ackPolicy : 2; + tANI_U8 rsvd : 1; + + tANI_U8 txop : 8; + +#endif +} __ani_attr_packed tSirMacQosCtl, *tpSirMacQosCtl; + +/// Length (in bytes) of MAC header in 3 address format +#define SIR_MAC_HDR_LEN_3A 24 + +/// Length (in bytes) of MAC header in 4 address format +#define SIR_MAC_HDR_LEN_4A 30 + +/// Length (in bytes) of the QoS control field in the MAC header +#define SIR_MAC_QOS_CTL_LEN 2 + +/// 3 address MAC data header format (24/26 bytes) +typedef __ani_attr_pre_packed struct sSirMacDot3Hdr +{ + tANI_U8 da[6]; + tANI_U8 sa[6]; + tANI_U16 length; +} __ani_attr_packed tSirMacDot3Hdr, *tpSirMacDot3Hdr; + + +/// 3 address MAC data header format (24/26 bytes) +typedef __ani_attr_pre_packed struct sSirMacDataHdr3a +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 addr1[6]; + tANI_U8 addr2[6]; + tANI_U8 addr3[6]; + tSirMacSeqCtl seqControl; + tSirMacQosCtl qosControl; +} __ani_attr_packed tSirMacDataHdr3a, *tpSirMacDataHdr3a; + +/// 4 address MAC data header format (30/32 bytes) +typedef __ani_attr_pre_packed struct sSirMacDataHdr4a +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 addr1[6]; + tANI_U8 addr2[6]; + tANI_U8 addr3[6]; + tSirMacSeqCtl seqControl; + tANI_U8 addr4[6]; + tSirMacQosCtl qosControl; +} __ani_attr_packed tSirMacDataHdr4a, *tpSirMacDataHdr4a; + +/// Management header format +typedef __ani_attr_pre_packed struct sSirMacMgmtHdr +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 da[6]; + tANI_U8 sa[6]; + tANI_U8 bssId[6]; + tSirMacSeqCtl seqControl; +} __ani_attr_packed tSirMacMgmtHdr, *tpSirMacMgmtHdr; + +/// PS-poll header format +typedef __ani_attr_pre_packed struct sSirMacPSpoll +{ + tSirMacFrameCtl fc; + tANI_U8 aidLo; + tANI_U8 aidHi; + tANI_U8 bssId[6]; + tANI_U8 ta[6]; + tANI_U8 fcs[4]; +} __ani_attr_packed tSirMacPSpoll, *tpSirMacPSpoll; + +/// ERP information field +typedef __ani_attr_pre_packed struct sSirMacErpInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved:5; + tANI_U8 barkerPreambleMode:1; + tANI_U8 useProtection:1; + tANI_U8 nonErpPresent:1; +#else + tANI_U8 nonErpPresent:1; + tANI_U8 useProtection:1; + tANI_U8 barkerPreambleMode:1; + tANI_U8 reserved:5; +#endif +} __ani_attr_packed tSirMacErpInfo, *tpSirMacErpInfo; + +/// Capability information field +typedef __ani_attr_pre_packed struct sSirMacCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 immediateBA:1; + tANI_U16 delayedBA:1; + tANI_U16 dsssOfdm:1; + tANI_U16 rrm:1; + tANI_U16 apsd:1; + tANI_U16 shortSlotTime:1; + tANI_U16 qos:1; + tANI_U16 spectrumMgt:1; + tANI_U16 channelAgility:1; + tANI_U16 pbcc:1; + tANI_U16 shortPreamble:1; + tANI_U16 privacy:1; + tANI_U16 cfPollReq:1; + tANI_U16 cfPollable:1; + tANI_U16 ibss:1; + tANI_U16 ess:1; +#else + tANI_U16 ess:1; + tANI_U16 ibss:1; + tANI_U16 cfPollable:1; + tANI_U16 cfPollReq:1; + tANI_U16 privacy:1; + tANI_U16 shortPreamble:1; + tANI_U16 pbcc:1; + tANI_U16 channelAgility:1; + tANI_U16 spectrumMgt:1; + tANI_U16 qos:1; + tANI_U16 shortSlotTime:1; + tANI_U16 apsd:1; + tANI_U16 rrm:1; + tANI_U16 dsssOfdm:1; + tANI_U16 delayedBA:1; + tANI_U16 immediateBA:1; +#endif +} __ani_attr_packed tSirMacCapabilityInfo, *tpSirMacCapabilityInfo; + +typedef __ani_attr_pre_packed struct sSirMacCfParamSet +{ + tANI_U8 cfpCount; + tANI_U8 cfpPeriod; + tANI_U16 cfpMaxDuration; + tANI_U16 cfpDurRemaining; +} __ani_attr_packed tSirMacCfParamSet; + +typedef __ani_attr_pre_packed struct sSirMacTim +{ + tANI_U8 dtimCount; + tANI_U8 dtimPeriod; + tANI_U8 bitmapControl; + tANI_U8 bitmapLength; + tANI_U8 bitmap[251]; +} __ani_attr_packed tSirMacTim; + +//12 Bytes long because this structure can be used to represent rate +//and extended rate set IEs +//The parser assume this to be at least 12 +typedef __ani_attr_pre_packed struct sSirMacRateSet +{ + tANI_U8 numRates; + tANI_U8 rate[SIR_MAC_RATESET_EID_MAX]; +} __ani_attr_packed tSirMacRateSet; + + +typedef __ani_attr_pre_packed struct sSirMacSSid +{ + tANI_U8 length; + tANI_U8 ssId[32]; +} __ani_attr_packed tSirMacSSid; + +typedef __ani_attr_pre_packed struct sSirMacWpaInfo +{ + tANI_U8 length; + tANI_U8 info[SIR_MAC_MAX_IE_LENGTH]; +} __ani_attr_packed tSirMacWpaInfo, *tpSirMacWpaInfo, tSirMacRsnInfo, *tpSirMacRsnInfo; + +typedef __ani_attr_pre_packed struct sSirMacFHParamSet +{ + tANI_U16 dwellTime; + tANI_U8 hopSet; + tANI_U8 hopPattern; + tANI_U8 hopIndex; +} tSirMacFHParamSet, *tpSirMacFHParamSet; + +typedef __ani_attr_pre_packed struct sSirMacIBSSParams +{ + tANI_U16 atim; +} tSirMacIBSSParams, *tpSirMacIBSSParams; + +typedef __ani_attr_pre_packed struct sSirMacRRMEnabledCap +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved: 6; + tANI_U8 AntennaInformation: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 MeasurementPilot: 3; + tANI_U8 nonOperatinChanMax: 3; + tANI_U8 operatingChanMax: 3; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 APChanReport: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 statistics: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 repeated: 1; + tANI_U8 parallel: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 LinkMeasurement: 1; + tANI_U8 present; +#else + tANI_U8 present; + tANI_U8 LinkMeasurement: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 parallel: 1; + tANI_U8 repeated: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 statistics: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 APChanReport: 1; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 operatingChanMax: 3; + tANI_U8 nonOperatinChanMax: 3; + tANI_U8 MeasurementPilot: 3; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 AntennaInformation: 1; + tANI_U8 reserved: 6; +#endif +} tSirMacRRMEnabledCap, *tpSirMacRRMEnabledCap; + + +/* ---------------- + * EDCA Profiles + * --------------- + */ + +#define EDCA_AC_BE 0 +#define EDCA_AC_BK 1 +#define EDCA_AC_VI 2 +#define EDCA_AC_VO 3 +#define AC_MGMT_LO 4 +#define AC_MGMT_HI 5 +#define MAX_NUM_AC 4 +#define TOT_NUM_AC (MAX_NUM_AC + 2) /* +2 for AC_MGMT_xx */ + +/* +#define EDCA_INDEX_0_RSVD 0 +#define EDCA_INDEX_1_BEACON 1 +#define EDCA_INDEX_2_MGMT_PROBERSP 2 +#define EDCA_INDEX_3_MGMT_OTHER 3 +#define EDCA_INDEX_4_AC_VO 4 +#define EDCA_INDEX_5_AC_VI 5 +#define EDCA_INDEX_6_AC_BE 6 +#define EDCA_INDEX_7_AC_BK 7 +*/ +// access categories +#define SIR_MAC_EDCAACI_BESTEFFORT (EDCA_AC_BE) +#define SIR_MAC_EDCAACI_BACKGROUND (EDCA_AC_BK) +#define SIR_MAC_EDCAACI_VIDEO (EDCA_AC_VI) +#define SIR_MAC_EDCAACI_VOICE (EDCA_AC_VO) + +// access category record +typedef __ani_attr_pre_packed struct sSirMacAciAifsn +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd : 1; + tANI_U8 aci : 2; + tANI_U8 acm : 1; + tANI_U8 aifsn : 4; +#else + tANI_U8 aifsn : 4; + tANI_U8 acm : 1; + tANI_U8 aci : 2; + tANI_U8 rsvd : 1; +#endif +} __ani_attr_packed tSirMacAciAifsn; + +// contention window size +typedef __ani_attr_pre_packed struct sSirMacCW +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 max : 4; + tANI_U8 min : 4; +#else + tANI_U8 min : 4; + tANI_U8 max : 4; +#endif +} __ani_attr_packed tSirMacCW; + +typedef __ani_attr_pre_packed struct sSirMacEdcaParamRecord +{ + tSirMacAciAifsn aci; + tSirMacCW cw; + tANI_U16 txoplimit; +} __ani_attr_packed tSirMacEdcaParamRecord; + +typedef __ani_attr_pre_packed struct sSirMacQosInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 uapsd : 1; + tANI_U8 txopreq : 1; + tANI_U8 qreq : 1; + tANI_U8 qack : 1; + tANI_U8 count : 4; +#else + tANI_U8 count : 4; + tANI_U8 qack : 1; + tANI_U8 qreq : 1; + tANI_U8 txopreq : 1; + tANI_U8 uapsd : 1; +#endif +} __ani_attr_packed tSirMacQosInfo; + + +typedef __ani_attr_pre_packed struct sSirMacQosInfoStation +{ +#ifdef ANI_LITTLE_BIT_ENDIAN + tANI_U8 acvo_uapsd:1; + tANI_U8 acvi_uapsd:1; + tANI_U8 acbk_uapsd:1; + tANI_U8 acbe_uapsd:1; + tANI_U8 qack:1; + tANI_U8 maxSpLen:2; + tANI_U8 moreDataAck:1; +#else + tANI_U8 moreDataAck:1; + tANI_U8 maxSpLen:2; + tANI_U8 qack:1; + tANI_U8 acbe_uapsd:1; + tANI_U8 acbk_uapsd:1; + tANI_U8 acvi_uapsd:1; + tANI_U8 acvo_uapsd:1; +#endif +} __ani_attr_packed tSirMacQosInfoStation, *tpSirMacQosInfoStation; + + + +typedef __ani_attr_pre_packed struct sSirMacEdcaParamSetIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacQosInfo qosInfo; + tANI_U8 rsvd; + tSirMacEdcaParamRecord acbe; // best effort + tSirMacEdcaParamRecord acbk; // background + tSirMacEdcaParamRecord acvi; // video + tSirMacEdcaParamRecord acvo; // voice +} __ani_attr_packed tSirMacEdcaParamSetIE; + +typedef __ani_attr_pre_packed struct sSirMacQoSParams +{ + tANI_U8 count; + tANI_U16 limit; + tANI_U8 CWmin[8]; + tANI_U8 AIFS[8]; +} __ani_attr_packed tSirMacQoSParams; + +typedef __ani_attr_pre_packed struct sSirMacQbssLoadIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U16 staCount; + tANI_U8 chnlUtil; + tANI_U16 admitCapacity; +} __ani_attr_packed tSirMacQbssLoadIE; + +// ts info direction field can take any of these values +#define SIR_MAC_DIRECTION_UPLINK 0 +#define SIR_MAC_DIRECTION_DNLINK 1 +#define SIR_MAC_DIRECTION_DIRECT 2 +#define SIR_MAC_DIRECTION_BIDIR 3 + +// access policy +// reserved 0 +#define SIR_MAC_ACCESSPOLICY_EDCA 1 +#define SIR_MAC_ACCESSPOLICY_HCCA 2 +#define SIR_MAC_ACCESSPOLICY_BOTH 3 + +#define SIR_MAC_HCCA_TSID_MIN 8 // valid HCCA tsid's are 8 or higher +#define SIR_MAC_TID_MAX 15 +#define MAC_BA_TID_MAX 8 + +typedef __ani_attr_pre_packed struct sSirMacTSInfoTfc +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 burstSizeDefn : 1; + tANI_U8 reserved :7; +#else + tANI_U8 reserved :7; + tANI_U8 burstSizeDefn : 1; +#endif + +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 ackPolicy : 2; + tANI_U16 userPrio : 3; + tANI_U16 psb : 1; + tANI_U16 aggregation : 1; + tANI_U16 accessPolicy : 2; + tANI_U16 direction : 2; + tANI_U16 tsid : 4; + tANI_U16 trafficType : 1; +#else + tANI_U16 trafficType : 1; + tANI_U16 tsid : 4; + tANI_U16 direction : 2; + tANI_U16 accessPolicy : 2; + tANI_U16 aggregation : 1; + tANI_U16 psb : 1; + tANI_U16 userPrio : 3; + tANI_U16 ackPolicy : 2; +#endif +} __ani_attr_packed tSirMacTSInfoTfc; + +typedef __ani_attr_pre_packed struct sSirMacTSInfoSch +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd : 7; + tANI_U8 schedule : 1; +#else + tANI_U8 schedule : 1; + tANI_U8 rsvd : 7; +#endif +} __ani_attr_packed tSirMacTSInfoSch; + +typedef __ani_attr_pre_packed struct sSirMacTSInfo +{ + tSirMacTSInfoTfc traffic; + tSirMacTSInfoSch schedule; +} __ani_attr_packed tSirMacTSInfo; + +typedef __ani_attr_pre_packed struct sSirMacTspecIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacTSInfo tsinfo; + tANI_U16 nomMsduSz; + tANI_U16 maxMsduSz; + tANI_U32 minSvcInterval; + tANI_U32 maxSvcInterval; + tANI_U32 inactInterval; + tANI_U32 suspendInterval; + tANI_U32 svcStartTime; + tANI_U32 minDataRate; + tANI_U32 meanDataRate; + tANI_U32 peakDataRate; + tANI_U32 maxBurstSz; + tANI_U32 delayBound; + tANI_U32 minPhyRate; + tANI_U16 surplusBw; + tANI_U16 mediumTime; +} +__ani_attr_packed tSirMacTspecIE; + +// max size of the classifier params in the tclas IE +#define SIR_MAC_CLSPARAM_LEN 253 + +// frame classifier types +#define SIR_MAC_TCLASTYPE_ETHERNET 0 +#define SIR_MAC_TCLASTYPE_TCPUDPIP 1 +#define SIR_MAC_TCLASTYPE_8021DQ 2 +// reserved 3-255 + +#define SIR_MAC_TCLAS_PARAM_ETHERNET_MIN 14 +typedef __ani_attr_pre_packed struct sSirMacTclasParamEthernet +{ + tANI_U8 srcAddr[6]; + tANI_U8 dstAddr[6]; + tANI_U16 type; +}__ani_attr_packed tSirMacTclasParamEthernet; + +#define SIR_MAC_TCLAS_PARAM_IPV4_MIN 16 +typedef __ani_attr_pre_packed struct sSirMacTclasParamIPv4 +{ + tANI_U8 version; + tANI_U8 srcIpAddr[4]; + tANI_U8 dstIpAddr[4]; + tANI_U16 srcPort; + tANI_U16 dstPort; + tANI_U8 dscp; + tANI_U8 protocol; + tANI_U8 rsvd; +} __ani_attr_packed tSirMacTclasParamIPv4; + +#define SIR_MAC_TCLAS_IPV4 4 +#define SIR_MAC_TCLAS_IPV6 6 + +#define SIR_MAC_TCLAS_PARAM_IPV6_MIN 40 +typedef __ani_attr_pre_packed struct sSirMacTclasParamIPv6 +{ + tANI_U8 version; + tANI_U8 srcIpAddr[16]; + tANI_U8 dstIpAddr[16]; + tANI_U16 srcPort; + tANI_U16 dstPort; + tANI_U8 flowLabel[3]; +} __ani_attr_packed tSirMacTclasParamIPv6; + +#define SIR_MAC_TCLAS_PARAM_8021DQ_MIN 2 +typedef __ani_attr_pre_packed struct sSirMacTclasParam8021dq +{ + tANI_U16 tag; +} __ani_attr_packed tSirMacTclasParam8021dq; + +typedef __ani_attr_pre_packed struct sSirMacTclasIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 userPrio; + tANI_U8 classifierType; + tANI_U8 classifierMask; +} __ani_attr_packed tSirMacTclasIE; + +typedef __ani_attr_pre_packed struct sSirMacTsDelayIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U32 delay; +} __ani_attr_packed tSirMacTsDelayIE; + +typedef __ani_attr_pre_packed struct sSirMacTclasProcIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 processing; +} __ani_attr_packed tSirMacTclasProcIE; + +typedef __ani_attr_pre_packed struct sSirMacScheduleInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 rsvd : 9; + tANI_U16 direction : 2; + tANI_U16 tsid : 4; + tANI_U16 aggregation : 1; +#else + tANI_U16 aggregation : 1; + tANI_U16 tsid : 4; + tANI_U16 direction : 2; + tANI_U16 rsvd : 9; +#endif +} __ani_attr_packed tSirMacScheduleInfo; + +typedef __ani_attr_pre_packed struct sSirMacScheduleIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacScheduleInfo info; + tANI_U32 svcStartTime; + tANI_U32 svcInterval; + tANI_U16 maxSvcDuration; + tANI_U16 specInterval; +} __ani_attr_packed tSirMacScheduleIE; + +typedef __ani_attr_pre_packed struct sSirMacQosCapabilityIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacQosInfo qosInfo; +} __ani_attr_packed tSirMacQosCapabilityIE; + +typedef __ani_attr_pre_packed struct sSirMacQosCapabilityStaIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacQosInfoStation qosInfo; +} __ani_attr_packed tSirMacQosCapabilityStaIE; + + +#define ADDTS +typedef __ani_attr_pre_packed struct sSirMacQosActionIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 qosAction; + tANI_U8 qosBody[1]; +} __ani_attr_packed tSirMacQosActionIE; + +typedef tANI_U32 tSirMacTimeStamp[2]; + +typedef tANI_U16 tSirMacBeaconInterval; + +typedef tANI_U16 tSirMacListenInterval; + +typedef tANI_U8 tSirMacChanNum; + +typedef tANI_U8 tSirMacAddr[6]; + + +// IE definitions +typedef __ani_attr_pre_packed struct sSirMacIE +{ + tANI_U8 elementID; + tANI_U8 length; + tANI_U8 info[1]; +} __ani_attr_packed tSirMacIE; + +typedef __ani_attr_pre_packed struct sSirMacSSidIE +{ + tANI_U8 type; + tSirMacSSid ssId; +} __ani_attr_packed tSirMacSSidIE; + +typedef __ani_attr_pre_packed struct sSirMacRateSetIE +{ + tANI_U8 type; + tSirMacRateSet supportedRateSet; +} __ani_attr_packed tSirMacRateSetIE; + +typedef __ani_attr_pre_packed struct sSirMacDsParamSetIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacChanNum channelNumber; +} __ani_attr_packed tSirMacDsParamSetIE; + +typedef __ani_attr_pre_packed struct sSirMacCfParamSetIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacCfParamSet cfParams; +} __ani_attr_packed tSirMacCfParamSetIE; + +typedef __ani_attr_pre_packed struct sSirMacChanInfo +{ + tSirMacChanNum firstChanNum; + tANI_U8 numChannels; + tANI_S8 maxTxPower; +} __ani_attr_packed tSirMacChanInfo; + +typedef __ani_attr_pre_packed struct sSirMacCountry +{ + tANI_U8 countryString[3]; // This from CFG_COUNTRY_STRING + tANI_U8 numChanInfo; + tSirMacChanInfo chanInfo[1]; +} __ani_attr_packed tSirMacCountry; + +typedef __ani_attr_pre_packed struct sSirMacCountryIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacCountry country; +} __ani_attr_packed tSirMacCountryIE; + +typedef __ani_attr_pre_packed struct sSirMacNonErpPresentIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 erp; +} __ani_attr_packed tSirMacNonErpPresentIE; + +typedef __ani_attr_pre_packed struct sSirMacWpaIE +{ + tANI_U8 type; + tSirMacWpaInfo wpa; +} __ani_attr_packed tSirMacWpaIE; + +typedef struct sSirMacPowerCapabilityIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 minTxPower; + tANI_U8 maxTxPower; +} tSirMacPowerCapabilityIE; + +typedef struct sSirMacSupportedChannelIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 supportedChannels[96]; +} tSirMacSupportedChannelIE; + +typedef struct sSirMacMeasReqField +{ + tANI_U8 channelNumber; + tANI_U8 measStartTime[8]; + tANI_U16 measDuration; +} tSirMacMeasReqField, *tpSirMacMeasReqField; + +typedef struct sSirMacMeasReqIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 measToken; + tANI_U8 measReqMode; + tANI_U8 measType; + tSirMacMeasReqField measReqField; +} tSirMacMeasReqIE, *tpSirMacMeasReqIE; + +// Basic Measurement Report +typedef struct sSirMacBasicReport +{ + tANI_U8 channelNumber; + tANI_U8 measStartTime[8]; + tANI_U16 measDuration; + tANI_U8 mapField; +} tSirMacBasicReport, *tpSirMacBasicReport; + +typedef struct sSirMacBasicReportIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 measToken; + tANI_U8 measReportMode; + tANI_U8 measType; + tSirMacBasicReport basicReport; +} tSirMacBasicReportIE, *tpSirMacBasicReportIE; + +// CCA Measurement Report +typedef struct sSirMacCcaReport +{ + tANI_U8 channelNumber; + tANI_U8 measStartTime[8]; + tANI_U16 measDuration; + tANI_U8 ccaBusyFraction; +} tSirMacCcaReport, *tpSirMacCcaReport; + +typedef struct sSirMacCcaReportIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 measToken; + tANI_U8 measReportMode; + tANI_U8 measType; + tSirMacCcaReport ccaReport; +} tSirMacCcaReportIE, *tpSirMacCcaReportIE; + +// RPI Histogram Measurement Report +typedef struct sSirMacRpiReport +{ + tANI_U8 channelNumber; + tANI_U8 measStartTime[8]; + tANI_U16 measDuration; + tANI_U8 rpiDensity[8]; +} tSirMacRpiReport, *tpSirMacRpiReport; + +typedef struct sSirMacRpiReportIE +{ + tANI_U8 type; + tANI_U8 length; + tANI_U8 measToken; + tANI_U8 measReportMode; + tANI_U8 measType; + tSirMacRpiReport rpiReport; +} tSirMacRpiReportIE, *tpSirMacRpiReportIE; + +#define SIR_MAC_MAX_SUPP_RATES 32 + +#define SIR_MAC_MAX_SUPP_CHANNELS 100 +#define SIR_MAC_MAX_SUPP_OPER_CLASSES 32 + +#define SIR_MAC_MAX_EXTN_CAP 8 + +// VHT Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacVHTCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U32 reserved1: 2; + tANI_U32 txAntPattern: 1; + tANI_U32 rxAntPattern: 1; + tANI_U32 vhtLinkAdaptCap: 2; + tANI_U32 maxAMPDULenExp: 3; + tANI_U32 htcVHTCap: 1; + tANI_U32 vhtTXOPPS: 1; + tANI_U32 muBeamformeeCap: 1; + tANI_U32 muBeamformerCap: 1; + tANI_U32 numSoundingDim: 3; + tANI_U32 csnofBeamformerAntSup: 3; + tANI_U32 suBeamformeeCap: 1; + tANI_U32 suBeamFormerCap: 1; + tANI_U32 rxSTBC: 3; + tANI_U32 txSTBC: 1; + tANI_U32 shortGI160and80plus80MHz: 1; + tANI_U32 shortGI80MHz: 1; + tANI_U32 ldpcCodingCap: 1; + tANI_U32 supportedChannelWidthSet: 2; + tANI_U32 maxMPDULen: 2; +#else + tANI_U32 maxMPDULen: 2; + tANI_U32 supportedChannelWidthSet: 2; + tANI_U32 ldpcCodingCap: 1; + tANI_U32 shortGI80MHz: 1; + tANI_U32 shortGI160and80plus80MHz: 1; + tANI_U32 txSTBC: 1; + tANI_U32 rxSTBC: 3; + tANI_U32 suBeamFormerCap: 1; + tANI_U32 suBeamformeeCap: 1; + tANI_U32 csnofBeamformerAntSup: 3; + tANI_U32 numSoundingDim: 3; + tANI_U32 muBeamformerCap: 1; + tANI_U32 muBeamformeeCap: 1; + tANI_U32 vhtTXOPPS: 1; + tANI_U32 htcVHTCap: 1; + tANI_U32 maxAMPDULenExp: 3; + tANI_U32 vhtLinkAdaptCap: 2; + tANI_U32 rxAntPattern: 1; + tANI_U32 txAntPattern: 1; + tANI_U32 reserved1: 2; +#endif +} __ani_attr_packed tSirMacVHTCapabilityInfo; + +typedef __ani_attr_pre_packed struct sSirMacVHTTxSupDataRateInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved: 3; + tANI_U16 txSupDataRate: 13; +#else + tANI_U16 txSupDataRate: 13; + tANI_U16 reserved: 3; +#endif +}__ani_attr_packed tSirMacVHTTxSupDataRateInfo; + +typedef __ani_attr_pre_packed struct sSirMacVHTRxSupDataRateInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved: 3; + tANI_U16 rxSupDataRate: 13; +#else + tANI_U16 rxSupDataRate: 13; + tANI_U16 reserved: 3; +#endif +}__ani_attr_packed tSirMacVHTRxSupDataRateInfo; + +/** + * struct sSirVhtMcsInfo - VHT MCS information + * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams + * @rx_highest: Indicates highest long GI VHT PPDU data rate + * STA can receive. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams + * @tx_highest: Indicates highest long GI VHT PPDU data rate + * STA can transmit. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest TX data rate supported. + */ +typedef struct sSirVhtMcsInfo { + tANI_U16 rxMcsMap; + tANI_U16 rxHighest; + tANI_U16 txMcsMap; + tANI_U16 txHighest; +}tSirVhtMcsInfo; + +/** + * struct sSirVHtCap - VHT capabilities + * + * This structure is the "VHT capabilities element" as + * described in 802.11ac D3.0 8.4.2.160 + * @vht_cap_info: VHT capability info + * @supp_mcs: VHT MCS supported rates + */ +typedef struct sSirVHtCap { + tANI_U32 vhtCapInfo; + tSirVhtMcsInfo suppMcs; +}tSirVHTCap; + +/** + * struct sSirHtCap - HT capabilities + * + * This structure refers to "HT capabilities element" as + * described in 802.11n draft section 7.3.2.52 + */ + + +typedef struct sSirHtCap { + tANI_U16 capInfo; + tANI_U8 ampduParamsInfo; + tANI_U8 suppMcsSet[16]; + tANI_U16 extendedHtCapInfo; + tANI_U32 txBFCapInfo; + tANI_U8 antennaSelectionInfo; +}tSirHTCap; + +// HT Cap and HT IE Size defines +#define HT_CAPABILITY_IE_SIZE 28 +#define HT_INFO_IE_SIZE 24 + +// +// Determines the current operating mode of the 802.11n STA +// +typedef enum eSirMacHTOperatingMode +{ + eSIR_HT_OP_MODE_PURE, // No Protection + eSIR_HT_OP_MODE_OVERLAP_LEGACY, // Overlap Legacy device present, protection is optional + eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT, // No legacy device, but 20 MHz HT present + eSIR_HT_OP_MODE_MIXED // Protetion is required +} tSirMacHTOperatingMode; + + +// Spatial Multiplexing(SM) Power Save mode +typedef enum eSirMacHTMIMOPowerSaveState +{ + eSIR_HT_MIMO_PS_STATIC = 0, // Static SM Power Save mode + eSIR_HT_MIMO_PS_DYNAMIC = 1, // Dynamic SM Power Save mode + eSIR_HT_MIMO_PS_NA = 2, // reserved + eSIR_HT_MIMO_PS_NO_LIMIT = 3 // SM Power Save disabled +} tSirMacHTMIMOPowerSaveState; + + +typedef enum eSirMacHTChannelWidth +{ + eHT_CHANNEL_WIDTH_20MHZ = 0, + eHT_CHANNEL_WIDTH_40MHZ = 1, +#ifdef WLAN_FEATURE_11AC + eHT_CHANNEL_WIDTH_80MHZ = 2, +#endif + eHT_MAX_CHANNEL_WIDTH +} tSirMacHTChannelWidth; + +//Packet struct for HT capability +typedef __ani_attr_pre_packed struct sHtCaps { + tANI_U16 advCodingCap: 1; + tANI_U16 supportedChannelWidthSet: 1; + tANI_U16 mimoPowerSave: 2; + tANI_U16 greenField: 1; + tANI_U16 shortGI20MHz: 1; + tANI_U16 shortGI40MHz: 1; + tANI_U16 txSTBC: 1; + tANI_U16 rxSTBC: 2; + tANI_U16 delayedBA: 1; + tANI_U16 maximalAMSDUsize: 1; + tANI_U16 dsssCckMode40MHz: 1; + tANI_U16 psmp: 1; + tANI_U16 stbcControlFrame: 1; + tANI_U16 lsigTXOPProtection: 1; + tANI_U8 maxRxAMPDUFactor: 2; + tANI_U8 mpduDensity: 3; + tANI_U8 reserved1: 3; + tANI_U8 supportedMCSSet[16]; + tANI_U16 pco: 1; + tANI_U16 transitionTime: 2; + tANI_U16 reserved2: 5; + tANI_U16 mcsFeedback: 2; + tANI_U16 reserved3: 6; + tANI_U32 txBF: 1; + tANI_U32 rxStaggeredSounding: 1; + tANI_U32 txStaggeredSounding: 1; + tANI_U32 rxZLF: 1; + tANI_U32 txZLF: 1; + tANI_U32 implicitTxBF: 1; + tANI_U32 calibration: 2; + tANI_U32 explicitCSITxBF: 1; + tANI_U32 explicitUncompressedSteeringMatrix: 1; + tANI_U32 explicitBFCSIFeedback: 3; + tANI_U32 explicitUncompressedSteeringMatrixFeedback: 3; + tANI_U32 explicitCompressedSteeringMatrixFeedback: 3; + tANI_U32 csiNumBFAntennae: 2; + tANI_U32 uncompressedSteeringMatrixBFAntennae: 2; + tANI_U32 compressedSteeringMatrixBFAntennae: 2; + tANI_U32 reserved4: 7; + tANI_U8 antennaSelection: 1; + tANI_U8 explicitCSIFeedbackTx: 1; + tANI_U8 antennaIndicesFeedbackTx: 1; + tANI_U8 explicitCSIFeedback: 1; + tANI_U8 antennaIndicesFeedback: 1; + tANI_U8 rxAS: 1; + tANI_U8 txSoundingPPDUs: 1; + tANI_U8 reserved5: 1; + +} __ani_attr_packed tHtCaps; + +/* During 11h channel switch, the AP can indicate if the + * STA needs to stop the transmission or continue until the + * channel-switch. + * eSIR_CHANSW_MODE_NORMAL - STA can continue transmission + * eSIR_CHANSW_MODE_SILENT - STA should stop transmission + */ +typedef enum eSirMacChanSwMode +{ + eSIR_CHANSW_MODE_NORMAL = 0, + eSIR_CHANSW_MODE_SILENT = 1 +} tSirMacChanSwitchMode; + + +typedef __ani_attr_pre_packed struct _BarControl { + +#ifndef ANI_BIG_BYTE_ENDIAN + + tANI_U16 barAckPolicy:1; + tANI_U16 multiTID:1; + tANI_U16 bitMap:1; + tANI_U16 rsvd:9; + tANI_U16 numTID:4; + +#else + tANI_U16 numTID:4; + tANI_U16 rsvd:9; + tANI_U16 bitMap:1; + tANI_U16 multiTID:1; + tANI_U16 barAckPolicy:1; + +#endif + +}__ani_attr_packed barCtrlType; + +typedef __ani_attr_pre_packed struct _BARFrmStruct { + tSirMacFrameCtl fc; + tANI_U16 duration; + tSirMacAddr rxAddr; + tSirMacAddr txAddr; + barCtrlType barControl; + tSirMacSeqCtl ssnCtrl; +}__ani_attr_packed BARFrmType; + + +#if 0 +// Typedef for HT Capability IE +// Typedef for HT Capability Info Field +#define SUPPORT_ADVANCE_CODING_1 1 +#define NOT_SUPPORT_ADVANCE_CODING_0 0 +#define SUPPORT_CHANNEL_WIDTH_SET_20_40_MHZ 1 +#define NOT_SUPPORT_CHANNEL_WIDTH_SET_20_MHZ_ONLY 0 +#define DO_NOT_SEND_MIMO_SEQ_STATIC_POWER_SAVE 0 +#define RTS_PRECEDE_MIMO_SEQ_DYN_POWER_SAVE 1 +#define MIMO_POWER_SAVE_NA 2 +#define NO_LIMIT_ON_MIMO_SEQ 3 +#define DEVICE_IS_ABLE_TO_RCVE_PPDU_WITH_GF_PREAMBLE 1 +#define DEVICE_NOT_ABLE_TO_RCVE_PPDU_WITH_GF_PREAMBLE 0 +#define SUPPORT_SHORT_GI_FOR_20_MHZ 1 +#define NOT_SUPPORT_SHORT_GI_FOR_20_MHZ 0 +#define SUPPORT_SHORT_GI_FOR_40_MHZ 1 +#define NOT_SUPPORT_SHORT_GI_FOR_40_MHZ 0 +#define TRANSMITTER_SUPPORT_STBC 1 +#define TRANSMITTER_NOT_SUPPORT_STBC 0 +#define RX_NOT_SUPPORT_STBC 0 +#define RX_SUPPORT_STBC_ONE_SPATIAL_STREAM 1 +#define RX_SUPPORT_STBC_ONE_AND_TWO_SPATIAL_STREAM 2 +#define RX_SUPPORT_STBC_ONE_TWO_THREE_SPATIAL_STREAM 3 +#define SUPPORT_DELAYED_BA 1 +#define NOT_SUPPORT_DELAYED_BA 0 +#define RECEIVER_MAX_A_MSDU_SIZE_7935 1 +#define RECEIVER_MAX_A_MSDU_SIZE_3839 0 +#define BSS_OR_DEVICE_ALLOW_USE_DSSS_CCK 1 +#define BSS_OR_DEVICE_NOT_ALLOW_USE_DSSS_CCK 0 +#define BSS_OR_DEVICE_SUPPORT_USE_PSMP 1 +#define BSS_OR_DEVICE_NOT_SUPPORT_USE_PSMP 0 +#define BSS_OR_DEVICE_SUPPORT_USE_STBC_CONTROL_FRAME 1 +#define BSS_OR_DEVICE_NOT_SUPPORT_USE_STBC_CONTROL_FRAME 0 +#define SUPPORT_L_SIG_TXOP_PROTECTION 1 +#define NOT_SUPPORT_L_SIG_TXOP_PROTECTION 0 + +// Typedef for HT Parameters Info Field +#define MAX_RX_AMPDU_FACTOR_0 0 +#define MAX_RX_AMPDU_FACTOR_1 1 +#define MAX_RX_AMPDU_FACTOR_2 2 +#define MAX_RX_AMPDU_FACTOR_3 3 +#define MPDU_DENSITY_NO_RESTRICTION 0 +#define MPDU_DENSITY_ONE_EIGHTH_USECOND 1 +#define MPDU_DENSITY_ONE_FOURTH_USECOND 2 +#define MPDU_DENSITY_ONE_HALF_USECOND 3 +#define MPDU_DENSITY_ONE_USECOND 4 +#define MPDU_DENSITY_TWO_USECOND 5 +#define MPDU_DENSITY_FOUR_USECOND 6 +#define MPDU_DENSITY_EIGHT_USECOND 7 +#endif + +// Supported MCS set +#define SIZE_OF_SUPPORTED_MCS_SET 16 +#define SIZE_OF_BASIC_MCS_SET 16 +#define VALID_MCS_SIZE 77 //0-76 +#define MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET 10 +// This is not clear, Count 8 based from NV supported MCS count +#define VALID_MAX_MCS_INDEX 8 + +#if 0 +// Typedef Extended HT Capability Info Field +#define SUPPORT_PCO 1 +#define NOT_SUPPORT_PCO 0 +#define TRANSITION_TIME_0 0 +#define STA_DOES_NOT_PROVIDE_MCS_FEEDBACK 0 +#define RESERVE_VALUE_FOR_STA_MCS_FEEDBACK 1 +#define STA_PROVIDE_UNSOLICITED_MCS_FEEDBACK 2 +#define STA_PROVIDE_ON_MRQ_AND_UNSOLICITED_MCS_FEEDBACK 3 + +// Typedef Transmit Beamforming Capability +#define TX_BEAMFORMING_CAPABLE 1 +#define TX_BEAMFORMING_INCAPABLE 0 +#define CAPABLE_RECEIVE_STAGGERED_SOUNDING 1 +#define NOT_CAPABLE_RECEIVE_STAGGERED_SOUNDING 0 +#define CAPABLE_TRANSMIT_STAGGERED_SOUNDING 1 +#define NOT_CAPABLE_TRANSMIT_STAGGERED_SOUNDING 0 +#define CAPABLE_RECEIVE_ZLF 1 +#define NOT_CAPABLE_RECEIVE_ZLF 0 +#define CAPABLE_TRANSMIT_ZLF 1 +#define NOT_CAPABLE_TRANSMIT_ZLF 0 +#define CAPABLE_IMPLICIT_TXBF 1 +#define NOT_CAPABLE_IMPLICIT_TXBF 0 +#define INCAPABLE_CALIBRATION 0 +#define LIMITED_CALIBRATION_CANNOT_INITIATE 1 +#define LIMITED_CALIBRATION_CAN_INITIATE 2 +#define FULLT_CAPABLE_CALIBRATION 3 +#define CAPABLE_EXPLICIT_CSI_TXBF 1 +#define INCAPABLE_EXPLICIT_CSI_TXBF 0 +#define CAPABLE_EXPLICIT_UNCOMPRESSED_STEERING_MATRIX 1 +#define INCAPABLE_EXPLICIT_UNCOMPRESSED_STEERING_MATRIX 0 +#define INCAPABLE_EXPLICIT_BFCI_FEEDBACK 0 +#define CAPABLE_UNSOLICITED_BFCI_FEEDBACK 1 +#define CAPABLE_IMMEDIATE_BFCI_FEEDBACK 2 +#define CAPABLE_AGGREGATE_BFCI_FEEDBACK 4 +#define INCAPABLE_EXPLICIT_UNCOMPRESSED_STEERING_MATRIX_FEEDBAC 0 +#define CAPABLE_UNSOLICITED_UNCOMPRESSED_STEERING_MATRIX 1 +#define CAPABLE_IMMEDIATE_UNCOMPRESSED_STEERING_MATRIX 2 +#define CAPABLE_AGGREGATED_UNCOMPRESSED_STEERING_MATRIX 4 +#define INCAPABLE_EXPLICIT_COMPRESSED_STEERING_MATRIX_FEEDBAC 0 +#define CAPABLE_UNSOLICITED_COMPRESSED_STEERING_MATRIX 1 +#define CAPABLE_IMMEDIATE_COMPRESSED_STEERING_MATRIX 2 +#define CAPABLE_AGGREGATED_COMPRESSED_STEERING_MATRIX 4 +#define SUPPORT_CSI_BEAMFORMING_SINGLE_TX_ANTENNA_SOUNDING 0 +#define SUPPORT_CSI_BEAMFORMING_2_TX_ANTENNA_SOUNDING 1 +#define SUPPORT_CSI_BEAMFORMING_3_TX_ANTENNA_SOUNDING 2 +#define SUPPORT_CSI_BEAMFORMING_4_TX_ANTENNA_SOUNDING 3 +#define SUPPORT_UNCOMPRESSED_STEERING_MATRIX_1_TX_ANTENNA_SOUNDING 0 +#define SUPPORT_UNCOMPRESSED_STEERING_MATRIX_2_TX_ANTENNA_SOUNDING 1 +#define SUPPORT_UNCOMPRESSED_STEERING_MATRIX_3_TX_ANTENNA_SOUNDING 2 +#define SUPPORT_UNCOMPRESSED_STEERING_MATRIX_4_TX_ANTENNA_SOUNDING 3 +#define SUPPORT_COMPRESSED_STEERING_MATRIX_1_TX_ANTENNA_SOUNDING 0 +#define SUPPORT_COMPRESSED_STEERING_MATRIX_2_TX_ANTENNA_SOUNDING 1 +#define SUPPORT_COMPRESSED_STEERING_MATRIX_3_TX_ANTENNA_SOUNDING 2 +#define SUPPORT_COMPRESSED_STEERING_MATRIX_4_TX_ANTENNA_SOUNDING 3 + +// Typedef Antenna Selection Capability +#define CAPABLE_ANTENNA_SELECTION 1 +#define INCAPABLE_ANTENNA_SELECTION 0 +#define CAPABLE_EXPLICIT_CSI_FEEDBACK_BASED_TX_AS 1 +#define INCAPABLE_EXPLICIT_CSI_FEEDBACK_BASED_TX_AS 0 +#define CAPABLE_ANTENNA_INDICES_FEEDBACK_BASED_TX_AS 1 +#define INCAPABLE_ANTENNA_INDICES_FEEDBACK_BASED_TX_AS 0 +#define CAPABLE_EXPLICIT_CSI_FEEDBACK 1 +#define INCAPABLE_EXPLICIT_CSI_FEEDBACK 0 +#define CAPABLE_ANTENNA_INDICES_FEEDBACK_BASED_TX_AS 1 +#define INCAPABLE_ANTENNA_INDICES_FEEDBACK_BASED_TX_AS 0 +#define CAPABLE_RX_AS 1 +#define INCAPABLE_RX_AS 0 +#define CAPABLE_TRANSMIT_SOUNDING_PPDU 1 +#define INCAPABLE_TRANSMIT_SOUNDING_PPDU 0 + +// Typedef Additional HT Infomation Elements +#define CONTROL_CHANNEL_1 1 + +#define OFFSET_NO_EXTENSION_CHANNEL_IS_PRESENT 0 +#define OFFSET_EXTENSION_CHANNEL_ABOVE_CONTROL_CHANNEL 1 +#define OFFSET_EXTENSION_CHANNEL_BELOW_CONTROL_CHANNEL 3 +#define USE_20_MHZ_CONTROL_CHANNEL 0 +#define USE_ANY_SUPPORTED_CHANNEL_WIDTH 1 +#define USE_RIFS_MODE_PROHIBITED 0 +#define USE_RIFS_MODE_PERMITTED 1 +#define CONTROLLED_ACCESS_NOT_ONLY_PSMP 0 +#define CONTROLLED_ACCESS_ONLY_PSMP 1 +#define SERVICE_INTERVAL_GRANULARITY_5MS 0 +#define SERVICE_INTERVAL_GRANULARITY_10MS 1 +#define SERVICE_INTERVAL_GRANULARITY_15MS 2 +#define SERVICE_INTERVAL_GRANULARITY_20MS 3 +#define SERVICE_INTERVAL_GRANULARITY_25MS 4 +#define SERVICE_INTERVAL_GRANULARITY_30MS 5 +#define SERVICE_INTERVAL_GRANULARITY_35MS 6 +#define SERVICE_INTERVAL_GRANULARITY_40MS 7 + +#define OPERATION_MODE_PURE_NO_PROTECTION 0 +#define OPERATION_MODE_OPTIONAL_PROTECTION 1 +#define OPERATION_MODE_NO_LEGACY_STA_40MHZ_PROTECTED 2 +#define OPERATION_MODE_MIXED_PROTECTION 3 + +#define DUAL_CTS_PROTECTION_IS_USED 1 +#define REGULAR_RTS_CTS_IS_USED 0 +#define SECONDARY_BEACON 1 +#define PRIMARY_BEACON 0 +#define LSIG_TXOP_PROTECTION_FULL_SUPPORT 1 +#define LSIG_TXOP_PROTECTION_NOT_FULL_SUPPORT 0 +#define PCO_IS_ACTIVATED_IN_BSS 1 +#define PCO_IS_NOT_ACTIVATED_IN_BSS 0 +#define PCO_PHASE_REQUEST_SWITCH_KEEP_TO_20MHZ 0 +#define PCO_PHASE_REQUEST_SWITCH_KEEP_TO_40MHZ 1 +#endif + +// +// The following enums will be used to get the "current" HT Capabilities of +// the local STA in a generic fashion. In other words, the following enums +// identify the HT capabilities that can be queried or set. +// +typedef enum eHTCapability +{ + eHT_LSIG_TXOP_PROTECTION, + eHT_STBC_CONTROL_FRAME, + eHT_PSMP, + eHT_DSSS_CCK_MODE_40MHZ, + eHT_MAX_AMSDU_LENGTH, + eHT_DELAYED_BA, + eHT_RX_STBC, + eHT_TX_STBC, + eHT_SHORT_GI_40MHZ, + eHT_SHORT_GI_20MHZ, + eHT_GREENFIELD, + eHT_MIMO_POWER_SAVE, + eHT_SUPPORTED_CHANNEL_WIDTH_SET, + eHT_ADVANCED_CODING, + eHT_MAX_RX_AMPDU_FACTOR, + eHT_MPDU_DENSITY, + eHT_PCO, + eHT_TRANSITION_TIME, + eHT_MCS_FEEDBACK, + eHT_TX_BEAMFORMING, + eHT_ANTENNA_SELECTION, + // The following come under Additional HT Capabilities + eHT_SI_GRANULARITY, + eHT_CONTROLLED_ACCESS, + eHT_RIFS_MODE, + eHT_RECOMMENDED_TX_WIDTH_SET, + eHT_EXTENSION_CHANNEL_OFFSET, + eHT_OP_MODE, + eHT_BASIC_STBC_MCS, + eHT_DUAL_CTS_PROTECTION, + eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT, + eHT_PCO_ACTIVE, + eHT_PCO_PHASE +} tHTCapability; + +// HT Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacHTCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 lsigTXOPProtection:1; // Dynamic state + tANI_U16 stbcControlFrame:1; // Static via CFG + tANI_U16 psmp:1; // Static via CFG + tANI_U16 dsssCckMode40MHz:1; // Static via CFG + tANI_U16 maximalAMSDUsize:1; // Static via CFG + tANI_U16 delayedBA:1; // Static via CFG + tANI_U16 rxSTBC:2; // Static via CFG + tANI_U16 txSTBC:1; // Static via CFG + tANI_U16 shortGI40MHz:1; // Static via CFG + tANI_U16 shortGI20MHz:1; // Static via CFG + tANI_U16 greenField:1; // Static via CFG + tANI_U16 mimoPowerSave:2; // Dynamic state + tANI_U16 supportedChannelWidthSet:1; // Static via CFG + tANI_U16 advCodingCap:1; // Static via CFG +#else + tANI_U16 advCodingCap:1; + tANI_U16 supportedChannelWidthSet:1; + tANI_U16 mimoPowerSave:2; + tANI_U16 greenField:1; + tANI_U16 shortGI20MHz:1; + tANI_U16 shortGI40MHz:1; + tANI_U16 txSTBC:1; + tANI_U16 rxSTBC:2; + tANI_U16 delayedBA:1; + tANI_U16 maximalAMSDUsize:1; + tANI_U16 dsssCckMode40MHz:1; + tANI_U16 psmp:1; + tANI_U16 stbcControlFrame:1; + tANI_U16 lsigTXOPProtection:1; +#endif +} __ani_attr_packed tSirMacHTCapabilityInfo; + +// HT Parameters Info +typedef __ani_attr_pre_packed struct sSirMacHTParametersInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved:3; + tANI_U8 mpduDensity:3; // Dynamic state + tANI_U8 maxRxAMPDUFactor:2; // Dynamic state +#else + tANI_U8 maxRxAMPDUFactor:2; + tANI_U8 mpduDensity:3; + tANI_U8 reserved:3; +#endif +} __ani_attr_packed tSirMacHTParametersInfo; + +// Extended HT Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacExtendedHTCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved2:6; + tANI_U16 mcsFeedback:2; // Static via CFG + tANI_U16 reserved1:5; + tANI_U16 transitionTime:2; // Static via CFG + tANI_U16 pco:1; // Static via CFG +#else + tANI_U16 pco:1; + tANI_U16 transitionTime:2; + tANI_U16 reserved1:5; + tANI_U16 mcsFeedback:2; + tANI_U16 reserved2:6; +#endif +} __ani_attr_packed tSirMacExtendedHTCapabilityInfo; + +//IEEE 802.11n/D7.0 - 7.3.2.57.4 +//Part of the "supported MCS set field" +typedef __ani_attr_pre_packed struct sSirMacRxHighestSupportRate +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved : 6; + tANI_U16 rate : 10; +#else + tANI_U16 rate : 10; + tANI_U16 reserved : 6; +#endif +} __ani_attr_packed tSirMacRxHighestSupportRate, *tpSirMacRxHighestSupportRate; + + +// Transmit Beam Forming Capabilities Info +typedef __ani_attr_pre_packed struct sSirMacTxBFCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U32 reserved:7; + tANI_U32 compressedSteeringMatrixBFAntennae:2; // Static via CFG + tANI_U32 uncompressedSteeringMatrixBFAntennae:2; // Static via CFG + tANI_U32 csiNumBFAntennae:2; // Static via CFG + tANI_U32 explicitCompressedSteeringMatrixFeedback:3; // Static via CFG + tANI_U32 explicitUncompressedSteeringMatrixFeedback:3; // Static via CFG + tANI_U32 explicitBFCSIFeedback:3; // Static via CFG + tANI_U32 explicitUncompressedSteeringMatrix:1; // Static via CFG + tANI_U32 explicitCSITxBF:1; // Static via CFG + tANI_U32 calibration:2; // Static via CFG + tANI_U32 implicitTxBF:1; // Static via CFG + tANI_U32 txZLF:1; // Static via CFG + tANI_U32 rxZLF:1; // Static via CFG + tANI_U32 txStaggeredSounding:1; // Static via CFG + tANI_U32 rxStaggeredSounding:1; // Static via CFG + tANI_U32 txBF:1; // Static via CFG +#else + tANI_U32 txBF:1; + tANI_U32 rxStaggeredSounding:1; + tANI_U32 txStaggeredSounding:1; + tANI_U32 rxZLF:1; + tANI_U32 txZLF:1; + tANI_U32 implicitTxBF:1; + tANI_U32 calibration:2; + tANI_U32 explicitCSITxBF:1; + tANI_U32 explicitUncompressedSteeringMatrix:1; + tANI_U32 explicitBFCSIFeedback:3; + tANI_U32 explicitUncompressedSteeringMatrixFeedback:3; + tANI_U32 explicitCompressedSteeringMatrixFeedback:3; + tANI_U32 csiNumBFAntennae:2; + tANI_U32 uncompressedSteeringMatrixBFAntennae:2; + tANI_U32 compressedSteeringMatrixBFAntennae:2; + tANI_U32 reserved:7; +#endif +} __ani_attr_packed tSirMacTxBFCapabilityInfo; + +// Antenna Selection Capability Info +typedef __ani_attr_pre_packed struct sSirMacASCapabilityInfo +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 reserved2:1; + tANI_U8 txSoundingPPDUs:1; // Static via CFG + tANI_U8 rxAS:1; // Static via CFG + tANI_U8 antennaIndicesFeedback:1; // Static via CFG + tANI_U8 explicitCSIFeedback:1; // Static via CFG + tANI_U8 antennaIndicesFeedbackTx:1; // Static via CFG + tANI_U8 explicitCSIFeedbackTx:1; // Static via CFG + tANI_U8 antennaSelection:1; // Static via CFG +#else + tANI_U8 antennaSelection:1; + tANI_U8 explicitCSIFeedbackTx:1; + tANI_U8 antennaIndicesFeedbackTx:1; + tANI_U8 explicitCSIFeedback:1; + tANI_U8 antennaIndicesFeedback:1; + tANI_U8 rxAS:1; + tANI_U8 txSoundingPPDUs:1; + tANI_U8 reserved2:1; +#endif +} __ani_attr_packed tSirMacASCapabilityInfo; + +// Additional HT IE Field1 +typedef __ani_attr_pre_packed struct sSirMacHTInfoField1 +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 serviceIntervalGranularity:3; // Dynamic state + tANI_U8 controlledAccessOnly:1; // Static via CFG + tANI_U8 rifsMode:1; // Dynamic state + tANI_U8 recommendedTxWidthSet:1; // Dynamic state + tANI_U8 secondaryChannelOffset:2; // Dynamic state +#else + tANI_U8 secondaryChannelOffset:2; + tANI_U8 recommendedTxWidthSet:1; + tANI_U8 rifsMode:1; + tANI_U8 controlledAccessOnly:1; + tANI_U8 serviceIntervalGranularity:3; +#endif +} __ani_attr_packed tSirMacHTInfoField1; + +// Additional HT IE Field2 +typedef __ani_attr_pre_packed struct sSirMacHTInfoField2 +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved:11; + tANI_U16 obssNonHTStaPresent:1; /*added for Obss */ + tANI_U16 transmitBurstLimit: 1; + tANI_U16 nonGFDevicesPresent:1; + tANI_U16 opMode:2; // Dynamic state +#else + tANI_U16 opMode:2; + tANI_U16 nonGFDevicesPresent:1; + tANI_U16 transmitBurstLimit: 1; + tANI_U16 obssNonHTStaPresent:1; /*added for Obss */ + tANI_U16 reserved:11; +#endif +} __ani_attr_packed tSirMacHTInfoField2; + +// Additional HT IE Field3 +typedef __ani_attr_pre_packed struct sSirMacHTInfoField3 +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U16 reserved:4; + tANI_U16 pcoPhase:1; // Dynamic state + tANI_U16 pcoActive:1; // Dynamic state + tANI_U16 lsigTXOPProtectionFullSupport:1; // Dynamic state + tANI_U16 secondaryBeacon:1; // Dynamic state + tANI_U16 dualCTSProtection:1; // Dynamic state + tANI_U16 basicSTBCMCS:7; // Dynamic state +#else + tANI_U16 basicSTBCMCS:7; + tANI_U16 dualCTSProtection:1; + tANI_U16 secondaryBeacon:1; + tANI_U16 lsigTXOPProtectionFullSupport:1; + tANI_U16 pcoActive:1; + tANI_U16 pcoPhase:1; + tANI_U16 reserved:4; +#endif +} __ani_attr_packed tSirMacHTInfoField3; + +typedef __ani_attr_pre_packed struct sSirMacProbeReqFrame +{ + tSirMacSSidIE ssIdIE; + tSirMacRateSetIE rateSetIE; + tSirMacRateSetIE extendedRateSetIE; +} __ani_attr_packed tSirMacProbeReqFrame, *tpSirMacProbeReqFrame; + +typedef __ani_attr_pre_packed struct sSirMacProbeRspFrame +{ + tSirMacTimeStamp ts; + tSirMacBeaconInterval beaconInterval; + tSirMacCapabilityInfo capabilityInfo; + tSirMacSSidIE ssIdIE; + tSirMacRateSetIE rateSetIE; + tSirMacRateSetIE extendedRateSetIE; + tSirMacNonErpPresentIE nonErpPresent; + tSirMacDsParamSetIE dsParamsIE; + tSirMacCfParamSetIE cfParamsIE; +} __ani_attr_packed tSirMacProbeRspFrame, *tpSirMacProbeRspFrame; + +typedef __ani_attr_pre_packed struct sSirMacAuthFrameBody +{ + tANI_U16 authAlgoNumber; + tANI_U16 authTransactionSeqNumber; + tANI_U16 authStatusCode; + tANI_U8 type; // = SIR_MAC_CHALLENGE_TEXT_EID + tANI_U8 length; // = SIR_MAC_AUTH_CHALLENGE_LENGTH + tANI_U8 challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH]; +} __ani_attr_packed tSirMacAuthFrameBody, *tpSirMacAuthFrameBody; + +typedef __ani_attr_pre_packed struct sSirMacAuthenticationFrame +{ + tSirMacAuthFrameBody authFrameBody; +} __ani_attr_packed tSirMacAuthFrame, *tpSirMacAuthFrame; + +typedef __ani_attr_pre_packed struct sSirMacAssocReqFrame +{ + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 listenInterval; + tSirMacSSidIE ssIdIE; + tSirMacRateSetIE rateSetIE; + tSirMacRateSetIE extendedRateSetIE; +} __ani_attr_packed tSirMacAssocReqFrame, *tpSirMacAssocReqFrame; + +typedef __ani_attr_pre_packed struct sSirMacAssocRspFrame +{ + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 statusCode; + tANI_U16 aid; + tSirMacRateSetIE supportedRates; + tSirMacRateSetIE extendedRateSetIE; +} __ani_attr_packed tSirMacAssocRspFrame, *tpSirMacAssocRspFrame; + +typedef __ani_attr_pre_packed struct sSirMacDisassocFrame +{ + tANI_U16 reasonCode; +} __ani_attr_packed tSirMacDisassocFrame, *tpSirMacDisassocFrame; + +typedef __ani_attr_pre_packed struct sDSirMacDeauthFrame +{ + tANI_U16 reasonCode; +} __ani_attr_packed tSirMacDeauthFrame, *tpSirMacDeauthFrame; + +/// Common header for all action frames +typedef __ani_attr_pre_packed struct sSirMacActionFrameHdr +{ + tANI_U8 category; + tANI_U8 actionID; +} __ani_attr_packed tSirMacActionFrameHdr, *tpSirMacActionFrameHdr; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +typedef __ani_attr_pre_packed struct sSirMacVendorSpecificFrameHdr +{ + tANI_U8 category; + tANI_U8 Oui[4]; +} __ani_attr_packed tSirMacVendorSpecificFrameHdr, *tpSirMacVendorSpecificFrameHdr; +#endif + +#ifdef WLAN_FEATURE_RMC +typedef __ani_attr_pre_packed struct sSirMacIbssExtNetworkFrameHdr +{ + tANI_U8 category; + tANI_U8 Oui[3]; + tANI_U8 MagicCode[6]; + tANI_U8 version; + tANI_U8 actionID; + tANI_U32 dialogToken; +} __ani_attr_packed tSirMacIbssExtNetworkFrameHdr, *tpSirMacIbssExtNetworkFrameHdr; +#endif /* WLAN_FEATURE_RMC */ + +typedef __ani_attr_pre_packed struct sSirMacVendorSpecificPublicActionFrameHdr +{ + tANI_U8 category; + tANI_U8 actionID; + tANI_U8 Oui[4]; + tANI_U8 OuiSubType; + tANI_U8 dialogToken; +} __ani_attr_packed tSirMacVendorSpecificPublicActionFrameHdr, *tpSirMacVendorSpecificPublicActionFrameHdr; + +typedef __ani_attr_pre_packed struct sSirMacP2PActionFrameHdr +{ + tANI_U8 category; + tANI_U8 Oui[4]; + tANI_U8 OuiSubType; + tANI_U8 dialogToken; +} __ani_attr_packed tSirMacP2PActionFrameHdr, *tpSirMacP2PActionFrameHdr; + + + +typedef struct sSirMacMeasActionFrameHdr +{ + tANI_U8 category; + tANI_U8 actionID; + tANI_U8 dialogToken; +} tSirMacMeasActionFrameHdr, *tpSirMacMeasActionFrameHdr; + + +#ifdef ANI_SUPPORT_11H +typedef struct sSirMacTpcReqActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tANI_U8 type; + tANI_U8 length; +} tSirMacTpcReqActionFrame, *tpSirMacTpcReqActionFrame; + +typedef struct sSirMacMeasReqActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tSirMacMeasReqIE measReqIE; +} tSirMacMeasReqActionFrame, *tpSirMacMeasReqActionFrame; +#endif + +typedef struct sSirMacBasicMeasReportActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tSirMacBasicReportIE measReportIE; +} tSirMacBasicMeasReportActionFrame, *tpSirMacBasicMeasReportActionFrame; + +typedef struct sSirMacCcaMeasReportActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tSirMacCcaReportIE measReportIE; +} tSirMacCcaMeasReportActionFrame, *tpSirMacCcaMeasReportActionFrame; + +typedef struct sSirMacRpiMeasReportActionFrame +{ + tSirMacMeasActionFrameHdr actionHeader; + tSirMacRpiReportIE measReportIE; +} tSirMacRpiMeasReportActionFrame, *tpSirMacRpiMeasReportActionFrame; + +#if defined WLAN_FEATURE_VOWIFI + +typedef struct sSirMacNeighborReportReq +{ + tANI_U8 dialogToken; + tANI_U8 ssid_present; + tSirMacSSid ssid; +} tSirMacNeighborReportReq, *tpSirMacNeighborReportReq; + +typedef struct sSirMacLinkReport +{ + tANI_U8 dialogToken; + tANI_U8 txPower; + tANI_U8 rxAntenna; + tANI_U8 txAntenna; + tANI_U8 rcpi; + tANI_U8 rsni; +} tSirMacLinkReport, *tpSirMacLinkReport; + +#define BEACON_REPORT_MAX_IES 224 //Refer IEEE 802.11k-2008, Table 7-31d +typedef struct sSirMacBeaconReport +{ + tANI_U8 regClass; + tANI_U8 channel; + tANI_U8 measStartTime[8]; + tANI_U8 measDuration; + tANI_U8 phyType; + tANI_U8 bcnProbeRsp; + tANI_U8 rsni; + tANI_U8 rcpi; + tSirMacAddr bssid; + tANI_U8 antennaId; + tANI_U32 parentTSF; + tANI_U8 numIes; + tANI_U8 Ies[BEACON_REPORT_MAX_IES]; + +} tSirMacBeaconReport, *tpSirMacBeaconReport; + +#define RADIO_REPORTS_MAX_IN_A_FRAME 4 +typedef struct sSirMacRadioMeasureReport +{ + tANI_U8 token; + tANI_U8 refused; + tANI_U8 incapable; + tANI_U8 type; + union + { + tSirMacBeaconReport beaconReport; + }report; + +}tSirMacRadioMeasureReport, *tpSirMacRadioMeasureReport; + +#endif + +// QOS action frame definitions + +// max number of possible tclas elements in any frame +#define SIR_MAC_TCLASIE_MAXNUM 2 + +// ADDTS request +typedef __ani_attr_pre_packed struct sSirMacQosAddtsReqAF +{ + tSirMacActionFrameHdr afHdr; + tANI_U8 dlgToken; + tSirMacTspecIE tspec; + tANI_U8 tclas[1]; // variable length element +} __ani_attr_packed tSirMacQosAddtsReqAF; + +// ADDTS response +typedef __ani_attr_pre_packed struct sSirMacQosAddtsRspAF +{ + tSirMacActionFrameHdr afHdr; + tANI_U8 dlgToken; + tSirMacStatusCodes status; + tSirMacTsDelayIE delay; + tSirMacTspecIE tspec; + tANI_U8 tclas[1]; +} __ani_attr_packed tSirMacQosAddtsRspAF; + +// DELTS frame +typedef __ani_attr_pre_packed struct sSirMacQosDeltsAF +{ + tSirMacActionFrameHdr afHdr; + tSirMacTSInfo tsinfo; +} __ani_attr_packed tSirMacQosDeltsAF; + +// Schedule frame +typedef __ani_attr_pre_packed struct sSirMacQosScheduleAF +{ + tSirMacActionFrameHdr afHdr; + tSirMacScheduleIE schedule; +} __ani_attr_packed tSirMacQosScheduleAF; + +// DLP action frame definitions + +// DLP request +typedef __ani_attr_pre_packed struct sSirMacQosDlpReqAF +{ + tSirMacActionFrameHdr afHdr; + tANI_U8 dstMAC[6]; + tANI_U8 srcMAC[6]; + tSirMacQosCapabilityIE qosCapability; + tANI_U16 dlpTimeout; + tSirMacRateSetIE supportedRates; +} __ani_attr_packed tSirMacQosDlpReqAF; + +// DLP response +typedef __ani_attr_pre_packed struct sSirMacQosDlpRspAF +{ + tSirMacActionFrameHdr afHdr; + tANI_U8 dstMAC[6]; + tANI_U8 srcMAC[6]; + tSirMacStatusCodes status; + tSirMacQosCapabilityIE qosCapability; + tSirMacRateSetIE supportedRates; +} __ani_attr_packed tSirMacQosDlpRspAF; + +// DLP teardown +typedef __ani_attr_pre_packed struct sSirMacQosDlpTdnAF +{ + tSirMacActionFrameHdr afHdr; + tANI_U8 dstMAC[6]; + tANI_U8 srcMAC[6]; +} __ani_attr_packed tSirMacQosDlpTdnAF; + + + + +// +/// Common header for all ANI proprietary action frames +typedef __ani_attr_pre_packed struct sSirMacAniActionFrame +{ + tSirMacActionFrameHdr afHdr; + tANI_U8 aniOui[3]; // 00 0A F5 + tANI_U8 type; // 0 - request; 1 - report; 2 - snr +} __ani_attr_packed tSirMacAniActionFrame, *tpSirMacAniActionFrame; + + +typedef __ani_attr_pre_packed struct sSirMacLinkTestReqData +{ + tSirMacAniActionFrame hdr; + tANI_U8 frameStatus; // bit0 - first frame + // bit1 - last frame; + // if both bit0/1 are on, + // intermediate frame + // bit2-7 - reserved + tANI_U8 rate; + tANI_U8 randomData[SIR_MAC_MAX_RANDOM_LENGTH]; +} __ani_attr_packed tSirMacLinkTestReqData, *tpSirMacLinkTestReqData; + +/// SNR report specific fields +typedef __ani_attr_pre_packed struct sSirMacSnrReport +{ + tSirMacAniActionFrame hdr; + tANI_U32 numSamples; + tANI_U32 snr; + tANI_U32 snrComp; + tANI_U32 sq; + tANI_U32 rssi; +} __ani_attr_packed tSirMacSnrReport, *tpSirMacSnrReport; + +typedef __ani_attr_pre_packed struct sSirMacStaCbLegacyBssDetect +{ + tSirMacAniActionFrame hdr; + tANI_U8 channelNum; + tANI_U8 numLegacyBssid; + /* Below is declared as a place holder. Don't add anything after it since LegacyBssidList will take up memory after it */ + tANI_U8 LegacyBssidList[1]; /* Need to declare size 1 cause win build doesn't like size 0 */ +} __ani_attr_packed tSirMacStaCbLegacyBssDetect, *tpSirMacStaCbLegacyBssDetect; + +typedef __ani_attr_pre_packed struct sSirMacQoSDefBAReq +{ + tSirMacActionFrameHdr hdr; + + tANI_U8 rsvd1; + +#ifdef ANI_LITTLE_BIT_ENDIAN + tANI_U8 tid: 4; + tANI_U8 rsvd2: 4; +#else + tANI_U8 rsvd2: 4; + tANI_U8 tid: 4; +#endif +} __ani_attr_packed tSirMacQoSDefBAReq, *tpSirMacQoSDefBAReq; + +typedef __ani_attr_pre_packed struct sSirMacQoSDefBARsp +{ + tSirMacActionFrameHdr hdr; + +#ifdef ANI_LITTLE_BIT_ENDIAN + tANI_U8 tid: 4; + tANI_U8 policy: 1; + tANI_U8 reject: 1; + tANI_U8 rsvd1: 2; +#else + tANI_U8 rsvd1: 2; + tANI_U8 reject: 1; + tANI_U8 policy: 1; + tANI_U8 tid: 4; +#endif + + tANI_U8 bufferSize; +} __ani_attr_packed tSirMacQoSDefBARsp, *tpSirMacQoSDefBARsp; + +typedef __ani_attr_pre_packed struct sSirMacQoSDelBAReq +{ + tSirMacActionFrameHdr hdr; + tANI_U8 rsvd1; + +#ifdef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd2: 3; + tANI_U8 direction: 1; + tANI_U8 tid: 4; +#else + tANI_U8 tid: 4; + tANI_U8 direction: 1; + tANI_U8 rsvd2: 3; +#endif +} __ani_attr_packed tSirMacQoSDelBAReq, *tpSirMacQoSDelBAReq; + +typedef __ani_attr_pre_packed struct sSirMacQoSDelBARsp +{ + tSirMacActionFrameHdr hdr; + +#ifdef ANI_LITTLE_BIT_ENDIAN + tANI_U8 tid: 4; + tANI_U8 policy: 1; + tANI_U8 reject: 1; + tANI_U8 rsvd1: 2; +#else + tANI_U8 rsvd1: 2; + tANI_U8 reject: 1; + tANI_U8 policy: 1; + tANI_U8 tid: 4; +#endif + +} __ani_attr_packed tSirMacQoSDelBARsp, *tpSirMacQoSDelBARsp; + + + +// 11b rate encoding in MAC format + +#define SIR_MAC_RATE_1 0x02 +#define SIR_MAC_RATE_2 0x04 +#define SIR_MAC_RATE_5_5 0x0B +#define SIR_MAC_RATE_11 0x16 + +// 11a/g rate encoding in MAC format + +#define SIR_MAC_RATE_6 0x0C +#define SIR_MAC_RATE_9 0x12 +#define SIR_MAC_RATE_12 0x18 +#define SIR_MAC_RATE_18 0x24 +#define SIR_MAC_RATE_24 0x30 +#define SIR_MAC_RATE_36 0x48 +#define SIR_MAC_RATE_48 0x60 +#define SIR_MAC_RATE_54 0x6C + +// ANI legacy supported rates +#define SIR_MAC_RATE_72 0x01 +#define SIR_MAC_RATE_96 0x03 +#define SIR_MAC_RATE_108 0x05 + +// ANI enhanced rates +#define SIR_MAC_RATE_42 1000 +#define SIR_MAC_RATE_84 1001 +#define SIR_MAC_RATE_126 1002 +#define SIR_MAC_RATE_144 1003 +#define SIR_MAC_RATE_168 1004 +#define SIR_MAC_RATE_192 1005 +#define SIR_MAC_RATE_216 1006 +#define SIR_MAC_RATE_240 1007 + +#define SIR_MAC_RATE_1_BITMAP (1<<0) +#define SIR_MAC_RATE_2_BITMAP (1<<1) +#define SIR_MAC_RATE_5_5_BITMAP (1<<2) +#define SIR_MAC_RATE_11_BITMAP (1<<3) +#define SIR_MAC_RATE_6_BITMAP (1<<4) +#define SIR_MAC_RATE_9_BITMAP (1<<5) +#define SIR_MAC_RATE_12_BITMAP (1<<6) +#define SIR_MAC_RATE_18_BITMAP (1<<7) +#define SIR_MAC_RATE_24_BITMAP (1<<8) +#define SIR_MAC_RATE_36_BITMAP (1<<9) +#define SIR_MAC_RATE_48_BITMAP (1<<10) +#define SIR_MAC_RATE_54_BITMAP (1<<11) + +#define sirIsArate(x) ((((tANI_U8)x)==SIR_MAC_RATE_6) || \ + (((tANI_U8)x)==SIR_MAC_RATE_9) || \ + (((tANI_U8)x)==SIR_MAC_RATE_12)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_18)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_24)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_36)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_48)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_54)) + +#define sirIsBrate(x) ((((tANI_U8)x)==SIR_MAC_RATE_1) || \ + (((tANI_U8)x)==SIR_MAC_RATE_2) || \ + (((tANI_U8)x)==SIR_MAC_RATE_5_5)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_11)) + +#define sirIsGrate(x) ((((tANI_U8)x)==SIR_MAC_RATE_1) || \ + (((tANI_U8)x)==SIR_MAC_RATE_2) || \ + (((tANI_U8)x)==SIR_MAC_RATE_5_5)|| \ + (((tANI_U8)x)==SIR_MAC_RATE_11) || \ + (((tANI_U8)x)==SIR_MAC_RATE_6) || \ + (((tANI_U8)x)==SIR_MAC_RATE_9) || \ + (((tANI_U8)x)==SIR_MAC_RATE_12) || \ + (((tANI_U8)x)==SIR_MAC_RATE_18) || \ + (((tANI_U8)x)==SIR_MAC_RATE_24) || \ + (((tANI_U8)x)==SIR_MAC_RATE_36) || \ + (((tANI_U8)x)==SIR_MAC_RATE_48) || \ + (((tANI_U8)x)==SIR_MAC_RATE_54)) + +#define sirIsProprate(x) ((((tANI_U8)x)==SIR_MAC_RATE_72) || \ + (((tANI_U8)x)==SIR_MAC_RATE_96) || \ + (((tANI_U8)x)==SIR_MAC_RATE_108)) + +#define sirIsEnhancedRate(x) \ + (((x)==SIR_MAC_RATE_42) || \ + ((x)==SIR_MAC_RATE_84) || \ + ((x)==SIR_MAC_RATE_126) || \ + ((x)==SIR_MAC_RATE_144) || \ + ((x)==SIR_MAC_RATE_168) || \ + ((x)==SIR_MAC_RATE_192) || \ + ((x)==SIR_MAC_RATE_216) || \ + ((x)==SIR_MAC_RATE_240)) + +/// Table that has MAC<-->PHY rate encodings +typedef __ani_attr_pre_packed struct sSirMacPhyRates +{ + tANI_U8 rateId; + tANI_U8 phyRate; // Rate in PHY encoding format + tANI_U16 macRate; // Rate in MAC encoding format +} __ani_attr_packed tSirMacPhyRates, *tpSirMacPhyRates; + + +typedef __ani_attr_pre_packed struct sSirPhy11aHdr +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 lengthLo : 3; + tANI_U8 reserved : 1; + tANI_U8 rate : 4; + + tANI_U8 lengthMid : 8; + + tANI_U8 tail: 6; + tANI_U8 parity : 1; + tANI_U8 lengthHi : 1; + + tANI_U8 serviceLo; + tANI_U8 serviceHi; +#else + tANI_U8 rate : 4; + tANI_U8 reserved : 1; + tANI_U8 lengthLo : 3; + + tANI_U8 lengthMid : 8; + + tANI_U8 lengthHi : 1; + tANI_U8 parity : 1; + tANI_U8 tail: 6; + + tANI_U8 serviceLo; + tANI_U8 serviceHi; +#endif +} __ani_attr_packed tSirPhy11aHdr, *tpSirPhy11aHdr; + +#define SIR_MAC_MIN_IE_LEN 2 // Minimum IE length for IE validation + +#ifdef WLAN_FEATURE_RMC + +// RMC action codes +#define SIR_MAC_RMC_ENABLE_REQ 0 +#define SIR_MAC_RMC_DISABLE_REQ 1 +#define SIR_MAC_RMC_RULER_INFORM_SELECTED 2 +#define SIR_MAC_RMC_RULER_INFORM_CANCELLED 3 + +// RMC protocol version +#define SIR_MAC_RMC_VER 0x01 + +// Organization Identifier +#define SIR_MAC_RMC_OUI "\x00\x16\x32" +#define SIR_MAC_RMC_OUI_SIZE 3 + +#define SIR_MAC_RMC_MCAST_ADDRESS "\x01\x00\x5E\x00\x02\x0A" + +#endif /* WLAN_FEATURE_RMC */ + +#define SIR_MAC_TI_TYPE_REASSOC_DEADLINE 1 +#define SIR_MAC_TI_TYPE_KEY_LIFETIME 2 +#define SIR_MAC_TI_TYPE_ASSOC_COMEBACK 3 + +#endif /* __MAC_PROT_DEFS_H */ diff --git a/drivers/staging/prima/CORE/MAC/inc/sirTypes.h b/drivers/staging/prima/CORE/MAC/inc/sirTypes.h new file mode 100644 index 000000000000..6854cbafd9b9 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/sirTypes.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file sirTypes.h contains the common types + * + * Author: V. K. Kandarpa + * Date: 04/12/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIR_TYPES_H +#define __SIR_TYPES_H + +#include "halTypes.h" + +/* ********************************************** * + * * + * SIRIUS ERROR Codes / Return Codes * + * * + * ********************************************** */ + +/// Return status type +typedef enum eSirRetStatus +{ + eSIR_SUCCESS, + eSIR_FAILURE, + + /// System Errors + eSIR_SYS_ERROR_BASE=0x100, + eSIR_SYS_TX_THREAD_CREATE_FAILED, + eSIR_SYS_TX_THREAD_RESUME_FAILED, + eSIR_SYS_TX_MSG_Q_CREATE_FAILED, + eSIR_SYS_TX_Q_SEND_FAILED, + eSIR_SYS_TX_Q_RECV_FAILED, + eSIR_SYS_TX_TIMER_ACTIVATE_FAILED, + eSIR_SYS_TX_TIMER_CHANGE_FAILED, + eSIR_SYS_TX_TIMER_CREATE_FAILED, + eSIR_MEM_ALLOC_FAILED, + eSIR_PCI_ERROR, + + // Driver Return Codes + eSIR_HAL_ERROR_BASE=0x1000, + eSIR_HAL_STAID_INVALID, // 1 + eSIR_HAL_TCDESC_INVALID, // 2 + eSIR_HAL_TX_WQ_NOT_VALID, // 3 + eSIR_HAL_PREV_BMU_CMD_INCOMPLETE, // 4 + eSIR_HAL_EEPROM_CRC_FAILED, // 5 + eSIR_HAL_PCI_REVID_INVALID, // 6 + eSIR_HAL_STA_TC_ID_INVALID, // 7 + eSIR_HAL_TXWQ_EMPTY, // 8 + eSIR_HAL_ROUT_TBL_TYPE_STYPE_INVALID, // 9 + eSIR_HAL_TFP_ENABLE_FAILED, // a + eSIR_HAL_TFP_ABORT_CMD_FAILED, // b + eSIR_HAL_TFP_TEMPL_BCNLEN_INVALID, // c + eSIR_HAL_TFP_TEMPL_SCHLEN_INVALID, // d + eSIR_HAL_TFP_TEMPL_CFENDLEN_INVALID, // e + eSIR_HAL_TFP_TEMPL_RRLEN_INVALID, // f + eSIR_HAL_TFP_TEMPL_PSPOLLLEN_INVALID, // 10 + eSIR_HAL_TFP_TEMPL_CTSLEN_INVALID, // 11 + eSIR_HAL_TFP_TEMPL_CFPOLLLEN_INVALID, // 12 + eSIR_HAL_TFP_TEMPL_BACKLEN_INVALID, // 13 + eSIR_HAL_INPUT_INVALID, // 14 + eSIR_HAL_GET_PDU_FAILED, // 15 + eSIR_HAL_ADD_STA_ACK_POLICY_INVALID, // 16 + eSIR_HAL_STA_EXISTS, // 17 + eSIR_HAL_STA_DOES_NOT_EXIST, // 18 + eSIR_HAL_MASTER_WQ_ID_INVALID, // 19 + eSIR_HAL_WQ_NOT_EMPTY, // 1a + eSIR_HAL_WQ_EMPTY, // 1b + eSIR_HAL_PDUCNT_AND_NEXTPTR_MISMATCH, // 1c + eSIR_HAL_ERR_NUM_BYTES_TO_BE_SET_TOO_BIG, // 1d + eSIR_HAL_GET_PKT_LENGTH_INVALID, // 1e + eSIR_HAL_AS_CNT_INVALID, // 1f + eSIR_HAL_RFP_AGE_CMD_SEQFAIL, // 20 + eSIR_HAL_RFP_AGE_CMD_AGE_CMD_TCFAIL, // 21 + eSIR_HAL_RFP_AGE_CMD_PASS, // 22 + eSIR_HAL_RFP_AGE_CMD_TIMEDOUT, // 23 + eSIR_HAL_RHP_HASH_CMD_TIMEOUT, // 24 + eSIR_HAL_RHP_ROUTING_TBL_SET_FAILED, // 25 + eSIR_HAL_RHP_ROUTING_TBL_GET_FAILED, // 26 + + eSIR_HAL_CAL_STATUS_CHK_FAILED, + + eSIR_HAL_SYS_ARM_DBG_MODE_SET_FAILED, + eSIR_HAL_TFP_BCN_SENT, + eSIR_HAL_TFP_BCN_NOT_SENT, + eSIR_HAL_TFP_BKOF_ID_INVALID, + eSIR_HAL_TFP_CFB_ENABLE_INPUT_INVALID, + eSIR_HAL_TFP_EDCF_TXOP_INVALID, + eSIR_HAL_TFP_TEMPL_LEN_INVALID, + eSIR_HAL_KEY_ID_INVALID, + eSIR_HAL_KEY_LEN_INVALID, + eSIR_HAL_CHID_INVALID, + eSIR_HAL_HIF_BURST_READ_FAILED, + eSIR_HAL_HIF_BURST_WRITE_FAILED, + eSIR_HAL_HIF_BURST_LEN_REQ_INVALID, + eSIR_HAL_HIF_TX_NO_FRAG_DESC, + + eSIR_HAL_INVALID_PRODUCT_ID, // 44 + + eSIR_HAL_INVALID_CAPABILITY, // 48 + eSIR_HAL_CB_NOT_ENABLED, // 49 + eSIR_HAL_MAC_RATE_INVALID, // 4a + eSIR_HAL_RHP_HANG, // 4b + eSIR_HAL_UNSUPPORTED, // 4c + eSIR_HAL_TSPEC_INVALID, // 4d + + // NIM Return Codes + eSIR_NIM_ERROR_BASE=0x2000, + eSIR_NIM_ERR_INVALID_EVENT, + + + // MMH Return Codes + eSIR_NIM_MMH_ERROR_BASE=0x2100, + eSIR_NIM_MMH_ERR_INV_EVENT, + eSIR_NIM_MMH_ERR_MSG_LEN, + eSIR_NIM_MMH_ERR_IN_Q_TYPE, + + // MNT Return Codes + eSIR_NIM_MNT_ERROR_BASE=0x2140, + + // WDT Errors + eSIR_NIM_WDT_ERROR_BASE=0x2180, + + // LIM Return Codes + eSIR_LIM_ERROR_BASE=0x2200, + eSIR_LIM_IGNORE_BEACON, + eSIR_LIM_INVALID_STA, + eSIR_LIM_MAX_STA_REACHED_ERROR, + + // SCH Return Codes + eSIR_SCH_ERROR_BASE=0x2300, + + // PMM Return Codes + eSIR_PMM_ERROR_BASE=0x2400, + eSIR_PMM_INVALID_MODE, + eSIR_PMM_INVALID_STATE, + eSIR_PMM_INVALID_ROLE, + eSIR_PMM_STA_NOT_ASSOCIATED, + eSIR_PMM_HEART_BEAT_TMOUT, + eSIR_PMM_NTH_BEACON_DELIVERY, + eSIR_PMM_INVALID_REQ, + + // ARQ Return Codes + eSIR_ARQ_ERROR_BASE=0x2500, + + // CFG Return Codes + eSIR_CFG_ERROR_BASE=2600, + eSIR_CFG_INVALID_ID, + eSIR_CFG_INVALID_LEN, + + // parser Return Codes + eSIR_PRS_ERROR_BASE=0x2700, + eSIR_IGNORE_IE, + + // Put all your return codes above this line + eSIR_ERROR_LAST + +} tSirRetStatus; + +typedef enum +{ + FW_UBSP_STATS = 1, + FW_STATS_MAX, +}tSirFwStatsType; + + +typedef struct +{ + v_U32_t ubsp_enter_cnt; + v_U32_t ubsp_jump_ddr_cnt; +}tSirUbspFwStats; + +typedef struct +{ + tSirFwStatsType type; + /*data*/ + union{ + tSirUbspFwStats ubspStats; + }fwStatsData; +}tSirFwStatsResult; + +# endif // __SIR_TYPES_H diff --git a/drivers/staging/prima/CORE/MAC/inc/wniApi.h b/drivers/staging/prima/CORE/MAC/inc/wniApi.h new file mode 100644 index 000000000000..6445286ce06c --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/wniApi.h @@ -0,0 +1,720 @@ +/* + * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file wniApi.h contains message definitions exported by + * Sirius software modules. + * NOTE: See projects/sirius/include/sirApi.h for structure + * definitions of the host/FW messages. + * + * Author: Chandra Modumudi + * Date: 04/11/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __WNI_API_H +#define __WNI_API_H + +// DPH return error codes +#define ANI_DPH_SUCCESS 0 + +#define ANI_DPH_RX_STA_INVALID 1 + +#define ANI_DPH_DO_TKIP 2 + +#define ANI_DPH_PORT_BLOCKED 3 +#define ANI_DPH_TX_PUSH_ERROR 10 +#define ANI_DPH_TX_MAC_HDR_ERROR 11 +#define ANI_DPH_TX_INVALID_PAYLOAD 12 +#define ANI_DPH_TX_STA_INVALID 13 +#define ANI_DPH_TX_HASH_MISS 14 +#define ANI_DPH_TX_UNINITIALIZED 15 +#define ANI_DPH_TX_RADIO_IN_DIAG_MODE 16 +#define ANI_DPH_WMM_DROP 17 +#define ANI_DPH_APSD_DROP 18 +#define ANI_DPH_UNKNOWN_STA 19 + +/// HDD type for special handling of BDs in the TX pkts +/// Used in the structure ani_mod_info_t->bd_spl_proc_type +#define ANI_HDD_NO_SPL_PROC 0 +#define ANI_HDD_DUMMY_PKT_SPL_PROC 1 +#define ANI_HDD_PRE_DUMMY_PKT_SPL_PROC 2 +#define ANI_HDD_WNS_L2_UPDATE_SPL_PROC 3 +#define ANI_HDD_DUMMY_DATA 4 +#ifdef WMM_APSD +#define ANI_HDD_EOSP_PKT 5 +#endif + +/// Message offset for the cmd to enqueue a dummy pkt to HDD TD ring +#define ANI_DUMMY_PKT_MSG_TYPE_OFFSET 0 +#define ANI_DUMMY_PKT_MSG_LEN_OFFSET 2 +#define ANI_DUMMY_PKT_MAC_ADDR_OFFSET 4 +#define ANI_DUMMY_PKT_STA_ID_OFFSET 10 +#define ANI_DUMMY_PKT_RT_FL_OFFSET 12 +#define ANI_DUMMY_PKT_MSG_LEN 16 +#define ANI_DUMMY_DATA_PAYLOAD_OFFSET 10 + +/** + * Product IDs stored in the EEPROM for the different types of AP radio cards + * supported by Polaris + */ +#define AGN1323AR_00 4 +#define AGN1323AR_01 5 +#define AGN1223AR_00 6 +#define AGN1223AR_01 7 +#define AGN1223AR_02 8 +#define AGN_EEP_PRODUCT_ID_MAX 8 + +#define SIR_SME_MODULE_ID 0x16 + +/// Start of Sirius/Host message types +#define WNI_HOST_MSG_START 0x1500 + +enum eWniMsgTypes +{ + /// CFG message types + eWNI_CFG_MSG_TYPES_BEGIN=WNI_HOST_MSG_START, + eWNI_CFG_MSG_TYPES_END=eWNI_CFG_MSG_TYPES_BEGIN+0xFF, + + /// SME message types + eWNI_SME_MSG_TYPES_BEGIN=eWNI_CFG_MSG_TYPES_END, + eWNI_SME_START_REQ, + eWNI_SME_START_RSP, + eWNI_SME_SYS_READY_IND, + eWNI_SME_SCAN_REQ, + eWNI_SME_SCAN_ABORT_IND, + eWNI_SME_SCAN_RSP, +#ifdef FEATURE_OEM_DATA_SUPPORT + eWNI_SME_OEM_DATA_REQ, + eWNI_SME_OEM_DATA_RSP, +#endif + eWNI_SME_JOIN_REQ, + eWNI_SME_JOIN_RSP, + eWNI_SME_SETCONTEXT_REQ, + eWNI_SME_SETCONTEXT_RSP, + eWNI_SME_REASSOC_REQ, + eWNI_SME_REASSOC_RSP, + eWNI_SME_AUTH_REQ, + eWNI_SME_AUTH_RSP, + eWNI_SME_DISASSOC_REQ, + eWNI_SME_DISASSOC_RSP, + eWNI_SME_DISASSOC_IND, + eWNI_SME_DISASSOC_CNF, + eWNI_SME_DEAUTH_REQ, + eWNI_SME_DEAUTH_RSP, + eWNI_SME_DEAUTH_IND, + eWNI_SME_DISCONNECT_DONE_IND, + eWNI_SME_WM_STATUS_CHANGE_NTF, + eWNI_SME_IBSS_NEW_PEER_IND, + eWNI_SME_IBSS_PEER_DEPARTED_IND, + eWNI_SME_START_BSS_REQ, + eWNI_SME_START_BSS_RSP, + eWNI_SME_AUTH_IND, + eWNI_SME_ASSOC_IND, + eWNI_SME_ASSOC_CNF, + eWNI_SME_REASSOC_IND, + eWNI_SME_REASSOC_CNF, + eWNI_SME_SWITCH_CHL_REQ, + eWNI_SME_SWITCH_CHL_RSP, + eWNI_SME_STOP_BSS_REQ, + eWNI_SME_STOP_BSS_RSP, + eWNI_SME_DEL_BA_PEER_IND, + eWNI_SME_DEFINE_QOS_REQ, + eWNI_SME_DEFINE_QOS_RSP, + eWNI_SME_DELETE_QOS_REQ, + eWNI_SME_DELETE_QOS_RSP, + eWNI_SME_PROMISCUOUS_MODE_REQ, + eWNI_SME_PROMISCUOUS_MODE_RSP, + eWNI_SME_LINK_TEST_START_REQ, + eWNI_SME_LINK_TEST_START_RSP, + eWNI_SME_LINK_TEST_STOP_REQ, + eWNI_SME_LINK_TEST_STOP_RSP, + eWNI_SME_LINK_TEST_REPORT_IND, + eWNI_SME_NEIGHBOR_BSS_IND, + eWNI_SME_MEASUREMENT_REQ, + eWNI_SME_MEASUREMENT_RSP, + eWNI_SME_MEASUREMENT_IND, + eWNI_SME_SET_WDS_INFO_REQ, + eWNI_SME_SET_WDS_INFO_RSP, + eWNI_SME_WDS_INFO_IND, + eWNI_SME_SET_POWER_REQ, + eWNI_SME_SET_POWER_RSP, + eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_REQ, + eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_RSP, + eWNI_SME_SELECT_CHANNEL_REQ, + eWNI_SME_SELECT_CHANNEL_RSP, + eWNI_SME_SET_PROPRIETARY_IE_REQ, + eWNI_SME_SET_PROPRIETARY_IE_RSP, // #endif + eWNI_SME_DISCARD_SKB_NTF, // Used to cleanup SKBs by HDD + eWNI_SME_DEAUTH_CNF, + eWNI_SME_MIC_FAILURE_IND, + eWNI_SME_ADDTS_REQ, + eWNI_SME_ADDTS_RSP, + eWNI_SME_ADDTS_CNF, + eWNI_SME_ADDTS_IND, + eWNI_SME_DELTS_REQ, + eWNI_SME_DELTS_RSP, + eWNI_SME_DELTS_IND, + eWNI_SME_SET_BACKGROUND_SCAN_MODE_REQ, + eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ, + eWNI_SME_SWITCH_CHL_CB_PRIMARY_RSP, + eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ, + eWNI_SME_SWITCH_CHL_CB_SECONDARY_RSP, + eWNI_SME_PROBE_REQ, + eWNI_SME_STA_STAT_REQ, + eWNI_SME_STA_STAT_RSP, + eWNI_SME_AGGR_STAT_REQ, + eWNI_SME_AGGR_STAT_RSP, + eWNI_SME_GLOBAL_STAT_REQ, + eWNI_SME_GLOBAL_STAT_RSP, + eWNI_SME_STAT_SUMM_REQ, + eWNI_SME_STAT_SUMM_RSP, + eWNI_SME_REMOVEKEY_REQ, + eWNI_SME_REMOVEKEY_RSP, + eWNI_SME_GET_SCANNED_CHANNEL_REQ, + eWNI_SME_GET_SCANNED_CHANNEL_RSP, + eWNI_SME_SET_TX_POWER_REQ, + eWNI_SME_SET_TX_POWER_RSP, + eWNI_SME_GET_TX_POWER_REQ, + eWNI_SME_GET_TX_POWER_RSP, + eWNI_SME_GET_NOISE_REQ, + eWNI_SME_GET_NOISE_RSP, + eWNI_SME_LOW_RSSI_IND, + eWNI_SME_GET_STATISTICS_REQ, + eWNI_SME_GET_STATISTICS_RSP, + eWNI_SME_GET_RSSI_REQ, + eWNI_SME_GET_ROAM_RSSI_REQ, + eWNI_SME_GET_ROAM_RSSI_RSP, + eWNI_SME_GET_ASSOC_STAS_REQ, + eWNI_SME_TKIP_CNTR_MEAS_REQ, + eWNI_SME_UPDATE_APWPSIE_REQ, + eWNI_SME_GET_WPSPBC_SESSION_REQ, + eWNI_SME_WPS_PBC_PROBE_REQ_IND, + eWNI_SME_SET_APWPARSNIEs_REQ, + eWNI_SME_UPPER_LAYER_ASSOC_CNF, + eWNI_SME_HIDE_SSID_REQ, + eWNI_SME_CHNG_MCC_BEACON_INTERVAL, + eWNI_SME_REMAIN_ON_CHANNEL_REQ, + eWNI_SME_REMAIN_ON_CHN_IND, + eWNI_SME_REMAIN_ON_CHN_RSP, + eWNI_SME_REMAIN_ON_CHN_RDY_IND, + eWNI_SME_SEND_ACTION_FRAME_IND, + eWNI_SME_ACTION_FRAME_SEND_CNF, + eWNI_SME_ABORT_REMAIN_ON_CHAN_IND, + eWNI_SME_UPDATE_NOA, + eWNI_SME_CLEAR_DFS_CHANNEL_LIST, + eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER, + eWNI_SME_GET_SNR_REQ, + eWNI_SME_LOST_LINK_PARAMS_IND, + //General Power Save Messages + eWNI_PMC_MSG_TYPES_BEGIN, + eWNI_PMC_PWR_SAVE_CFG, + + //BMPS Messages + eWNI_PMC_ENTER_BMPS_REQ, + eWNI_PMC_ENTER_BMPS_RSP, + eWNI_PMC_EXIT_BMPS_REQ, + eWNI_PMC_EXIT_BMPS_RSP, + eWNI_PMC_EXIT_BMPS_IND, + + //IMPS Messages. + eWNI_PMC_ENTER_IMPS_REQ, + eWNI_PMC_ENTER_IMPS_RSP, + eWNI_PMC_EXIT_IMPS_REQ, + eWNI_PMC_EXIT_IMPS_RSP, + + //UAPSD Messages + eWNI_PMC_ENTER_UAPSD_REQ, + eWNI_PMC_ENTER_UAPSD_RSP, + eWNI_PMC_EXIT_UAPSD_REQ, + eWNI_PMC_EXIT_UAPSD_RSP, + + //WOWL Messages + eWNI_PMC_SMPS_STATE_IND, + + //WoWLAN Messages + eWNI_PMC_WOWL_ADD_BCAST_PTRN, + eWNI_PMC_WOWL_DEL_BCAST_PTRN, + eWNI_PMC_ENTER_WOWL_REQ, + eWNI_PMC_ENTER_WOWL_RSP, + eWNI_PMC_EXIT_WOWL_REQ, + eWNI_PMC_EXIT_WOWL_RSP, + +#ifdef WLAN_FEATURE_PACKET_FILTERING + eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP, +#endif // WLAN_FEATURE_PACKET_FILTERING + +#if defined WLAN_FEATURE_VOWIFI + eWNI_SME_RRM_MSG_TYPE_BEGIN, + + eWNI_SME_NEIGHBOR_REPORT_REQ_IND, + eWNI_SME_NEIGHBOR_REPORT_IND, + eWNI_SME_BEACON_REPORT_REQ_IND, + eWNI_SME_BEACON_REPORT_RESP_XMIT_IND, + +#endif + eWNI_SME_ADD_STA_SELF_REQ, + eWNI_SME_ADD_STA_SELF_RSP, + eWNI_SME_DEL_STA_SELF_REQ, + eWNI_SME_DEL_STA_SELF_RSP, + +#if defined WLAN_FEATURE_VOWIFI_11R + eWNI_SME_FT_PRE_AUTH_REQ, + eWNI_SME_FT_PRE_AUTH_RSP, + eWNI_SME_FT_UPDATE_KEY, + eWNI_SME_FT_AGGR_QOS_REQ, + eWNI_SME_FT_AGGR_QOS_RSP, +#endif + +#if defined FEATURE_WLAN_ESE + eWNI_SME_ESE_ADJACENT_AP_REPORT, +#endif + + eWNI_SME_REGISTER_MGMT_FRAME_REQ, + + eWNI_SME_COEX_IND, + +#ifdef FEATURE_WLAN_SCAN_PNO + eWNI_SME_PREF_NETWORK_FOUND_IND, +#endif // FEATURE_WLAN_SCAN_PNO + + eWNI_SME_TX_PER_HIT_IND, + + eWNI_SME_CHANGE_COUNTRY_CODE, + eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE, + eWNI_SME_PRE_SWITCH_CHL_IND, + eWNI_SME_POST_SWITCH_CHL_IND, + + eWNI_SME_MAX_ASSOC_EXCEEDED, + + eWNI_SME_BTAMP_LOG_LINK_IND,//to serialize the create/accpet LL req from HCI + + +#ifdef WLAN_WAKEUP_EVENTS + eWNI_SME_WAKE_REASON_IND, +#endif // WLAN_WAKEUP_EVENTS + eWNI_SME_EXCLUDE_UNENCRYPTED, + eWNI_SME_RSSI_IND, //RSSI indication from TL to be serialized on MC thread +#ifdef FEATURE_WLAN_TDLS + eWNI_SME_TDLS_SEND_MGMT_REQ, + eWNI_SME_TDLS_SEND_MGMT_RSP, + eWNI_SME_TDLS_ADD_STA_REQ, + eWNI_SME_TDLS_ADD_STA_RSP, + eWNI_SME_TDLS_DEL_STA_REQ, + eWNI_SME_TDLS_DEL_STA_RSP, + eWNI_SME_TDLS_DEL_STA_IND, + eWNI_SME_TDLS_DEL_ALL_PEER_IND, + eWNI_SME_MGMT_FRM_TX_COMPLETION_IND, + eWNI_SME_TDLS_LINK_ESTABLISH_REQ, + eWNI_SME_TDLS_LINK_ESTABLISH_RSP, +// tdlsoffchan + eWNI_SME_TDLS_CHANNEL_SWITCH_REQ, + eWNI_SME_TDLS_CHANNEL_SWITCH_RSP, +#endif + //NOTE: If you are planning to add more mesages, please make sure that + //SIR_LIM_ITC_MSG_TYPES_BEGIN is moved appropriately. It is set as + //SIR_LIM_MSG_TYPES_BEGIN+0xB0 = 12B0 (which means max of 176 messages and + //eWNI_SME_TDLS_DEL_STA_RSP = 175. + //Should fix above issue to enable TDLS_INTERNAL + eWNI_SME_SET_BCN_FILTER_REQ, + eWNI_SME_RESET_AP_CAPS_CHANGED, +#ifdef WLAN_FEATURE_11W + eWNI_SME_UNPROT_MGMT_FRM_IND, +#endif +#ifdef WLAN_FEATURE_GTK_OFFLOAD + eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP, +#endif // WLAN_FEATURE_GTK_OFFLOAD + eWNI_SME_CANDIDATE_FOUND_IND, /*ROAM candidate indication from FW*/ + eWNI_SME_HANDOFF_REQ,/*upper layer requested handoff to driver in STA mode*/ + eWNI_SME_ROAM_SCAN_OFFLOAD_RSP,/*Fwd the LFR scan offload rsp from FW to SME*/ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + eWNI_SME_ROAM_SCAN_TRIGGER_RSP, +#endif +#ifdef FEATURE_WLAN_LPHB + eWNI_SME_LPHB_IND, +#endif /* FEATURE_WLAN_LPHB */ +#ifdef WLAN_FEATURE_RMC + eWNI_SME_ENABLE_RMC_REQ, + eWNI_SME_DISABLE_RMC_REQ, + eWNI_SME_IBSS_PEER_INFO_RSP, +#endif /* WLAN_FEATURE_RMC */ + eWNI_SME_GET_TSM_STATS_REQ, + eWNI_SME_GET_TSM_STATS_RSP, + eWNI_SME_TSM_IE_IND, + +#ifdef FEATURE_WLAN_CH_AVOID + eWNI_SME_CH_AVOID_IND, +#endif /* FEATURE_WLAN_CH_AVOID */ + eWNI_SME_HT40_OBSS_SCAN_IND, /* START and UPDATE OBSS SCAN Indication*/ + eWNI_SME_HT40_STOP_OBSS_SCAN_IND, /* STOP OBSS SCAN indication */ +#ifdef WLAN_FEATURE_AP_HT40_24G + eWNI_SME_SET_HT_2040_MODE, /* HT 20/40 indication in SAP case for 2.4GHz*/ + eWNI_SME_2040_COEX_IND, /* HT20/40 Coex indication in SAP case for 2.4GHz*/ +#endif + eWNI_SME_MAC_SPOOF_ADDR_IND, + eWNI_SME_ENCRYPT_MSG_RSP, + eWNI_SME_UPDATE_MAX_RATE_IND, + eWNI_SME_NAN_EVENT, + eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ, + eWNI_SME_DEL_ALL_TDLS_PEERS, + eWNI_SME_REGISTER_MGMT_FRAME_CB, + eWNI_SME_CAP_TSF_REQ, + eWNI_SME_GET_TSF_REQ, + +#ifdef WLAN_FEATURE_LFR_MBB + eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ, + eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP, +#endif + + eWNI_SME_DEL_BA_SES_REQ, + eWNI_SME_MSG_TYPES_END +}; + +#define WNI_CFG_MSG_TYPES_BEGIN 0x1200 + +/*---------------------------------------------------------------------*/ +/* CFG Module Definitions */ +/*---------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------*/ +/* CFG message definitions */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_MSG_HDR_MASK 0xffff0000 +#define WNI_CFG_MSG_LEN_MASK 0x0000ffff +#define WNI_CFG_MB_HDR_LEN 4 +#define WNI_CFG_MAX_PARAM_NUM 32 + + +/*---------------------------------------------------------------------*/ +/* CFG to HDD message types */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_PARAM_UPDATE_IND (WNI_CFG_MSG_TYPES_BEGIN | 0x00) +#define WNI_CFG_DNLD_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x01) +#define WNI_CFG_DNLD_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x02) +#define WNI_CFG_GET_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x03) +#define WNI_CFG_SET_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x04) +#define WNI_CFG_GET_ATTRIB_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x05) +#define WNI_CFG_ADD_GRP_ADDR_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x06) +#define WNI_CFG_DEL_GRP_ADDR_CNF (WNI_CFG_MSG_TYPES_BEGIN | 0x07) + +#define ANI_CFG_GET_RADIO_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x08) +#define ANI_CFG_GET_PER_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x09) +#define ANI_CFG_GET_AGG_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0a) +#define ANI_CFG_CLEAR_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0b) + + +/*---------------------------------------------------------------------*/ +/* CFG to HDD message paramter indices */ + +/* The followings are word indices starting from the message body */ + +/* WNI_CFG_xxxx_xxxx_xxxx: index of parameter */ +/* */ +/* WNI_CFG_xxxx_xxxx_NUM: number of parameters in message */ +/* */ +/* WNI_CFG_xxxx_xxxx_LEN: byte length of message including */ +/* MB header */ +/* */ +/* WNI_CFG_xxxx_xxxx_PARTIAL_LEN: byte length of message including */ +/* parameters and MB header but */ +/* excluding variable data length */ +/*---------------------------------------------------------------------*/ + +// Parameter update indication +#define WNI_CFG_PARAM_UPDATE_IND_PID 0 + +#define WNI_CFG_PARAM_UPDATE_IND_NUM 1 +#define WNI_CFG_PARAM_UPDATE_IND_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_PARAM_UPDATE_IND_NUM << 2)) + +// Configuration download request +#define WNI_CFG_DNLD_REQ_NUM 0 +#define WNI_CFG_DNLD_REQ_LEN WNI_CFG_MB_HDR_LEN + +// Configuration download confirm +#define WNI_CFG_DNLD_CNF_RES 0 + +#define WNI_CFG_DNLD_CNF_NUM 1 +#define WNI_CFG_DNLD_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DNLD_CNF_NUM << 2)) +// Get response +#define WNI_CFG_GET_RSP_RES 0 +#define WNI_CFG_GET_RSP_PID 1 +#define WNI_CFG_GET_RSP_PLEN 2 + +#define WNI_CFG_GET_RSP_NUM 3 +#define WNI_CFG_GET_RSP_PARTIAL_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_RSP_NUM << 2)) +// Set confirm +#define WNI_CFG_SET_CNF_RES 0 +#define WNI_CFG_SET_CNF_PID 1 + +#define WNI_CFG_SET_CNF_NUM 2 +#define WNI_CFG_SET_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_SET_CNF_NUM << 2)) +// Get attribute response +#define WNI_CFG_GET_ATTRIB_RSP_RES 0 +#define WNI_CFG_GET_ATTRIB_RSP_PID 1 +#define WNI_CFG_GET_ATTRIB_RSP_TYPE 2 +#define WNI_CFG_GET_ATTRIB_RSP_PLEN 3 +#define WNI_CFG_GET_ATTRIB_RSP_RW 4 + +#define WNI_CFG_GET_ATTRIB_RSP_NUM 5 +#define WNI_CFG_GET_ATTRIB_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_ATTRIB_RSP_NUM << 2)) + +// Add group address confirm +#define WNI_CFG_ADD_GRP_ADDR_CNF_RES 0 + +#define WNI_CFG_ADD_GRP_ADDR_CNF_NUM 1 +#define WNI_CFG_ADD_GRP_ADDR_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_ADD_GRP_ADDR_CNF_NUM << 2)) + +// Delete group address confirm +#define WNI_CFG_DEL_GRP_ADDR_CNF_RES 0 + +#define WNI_CFG_DEL_GRP_ADDR_CNF_NUM 1 +#define WNI_CFG_DEL_GRP_ADDR_CNF_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DEL_GRP_ADDR_CNF_NUM <<2)) + + +#define IS_CFG_MSG(msg) ((msg & 0xff00) == WNI_CFG_MSG_TYPES_BEGIN) + +// Clear stats types. +#define ANI_CLEAR_ALL_STATS 0 +#define ANI_CLEAR_RX_STATS 1 +#define ANI_CLEAR_TX_STATS 2 +#define ANI_CLEAR_PER_STA_STATS 3 +#define ANI_CLEAR_AGGR_PER_STA_STATS 4 +#define ANI_CLEAR_STAT_TYPES_END 5 + +/*---------------------------------------------------------------------*/ +/* HDD to CFG message types */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_DNLD_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x80) +#define WNI_CFG_GET_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x81) +#define WNI_CFG_SET_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x82) +#define WNI_CFG_SET_REQ_NO_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x83) //No RSP for this set + +// Shall be removed after stats integration + + +/*---------------------------------------------------------------------*/ +/* HDD to CFG message paramter indices */ +/* */ +/* The followings are word indices starting from the message body */ +/* */ +/* WNI_CFG_xxxx_xxxx_xxxx: index of parameter */ +/* */ +/* WNI_CFG_xxxx_xxxx_NUM: number of parameters in message */ +/* */ +/* WNI_CFG_xxxx_xxxx_LEN: byte length of message including */ +/* MB header */ +/* */ +/* WNI_CFG_xxxx_xxxx_PARTIAL_LEN: byte length of message including */ +/* parameters and MB header but */ +/* excluding variable data length */ +/*---------------------------------------------------------------------*/ + +// Download response +#define WNI_CFG_DNLD_RSP_BIN_LEN 0 + +#define WNI_CFG_DNLD_RSP_NUM 1 +#define WNI_CFG_DNLD_RSP_PARTIAL_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DNLD_RSP_NUM << 2)) + +// Set parameter request +#define WNI_CFG_SET_REQ_PID 0 +#define WNI_CFG_SET_REQ_PLEN 1 + +/* +// Get attribute request +//#define WNI_CFG_GET_ATTRIB_REQ_PID 0 + +//#define WNI_CFG_GET_ATTRIB_REQ_NUM 1 +//#define WNI_CFG_GET_ATTRIB_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_ATTRIB_REQ_NUM << 2)) +// Add group address request +#define WNI_CFG_ADD_GRP_ADDR_REQ_MAC_ADDR 0 + +#define WNI_CFG_ADD_GRP_ADDR_REQ_NUM 1 +#define WNI_CFG_ADD_GRP_ADDR_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_ADD_GRP_ADDR_REQ_NUM << 2)) +// Delete group address request +#define WNI_CFG_DEL_GRP_ADDR_REQ_MAC_ADDR 0 + +#define WNI_CFG_DEL_GRP_ADDR_REQ_NUM 1 +#define WNI_CFG_DEL_GRP_ADDR_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_DEL_GRP_ADDR_REQ_NUM << 2)) +*/ + + +/*---------------------------------------------------------------------*/ +/* CFG return values */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_SUCCESS 1 +#define WNI_CFG_NOT_READY 2 +#define WNI_CFG_INVALID_PID 3 +#define WNI_CFG_INVALID_LEN 4 +#define WNI_CFG_RO_PARAM 5 +#define WNI_CFG_WO_PARAM 6 +#define WNI_CFG_INVALID_STAID 7 +#define WNI_CFG_OTHER_ERROR 8 +#define WNI_CFG_NEED_RESTART 9 +#define WNI_CFG_NEED_RELOAD 10 + + +/*---------------------------------------------------------------------*/ +/* CFG definitions */ +/*---------------------------------------------------------------------*/ +#define WNI_CFG_TYPE_STR 0x0000000 +#define WNI_CFG_TYPE_INT 0x0000001 +#define WNI_CFG_HOST_RE 0x0000002 +#define WNI_CFG_HOST_WE 0x0000004 + + +// Shall be removed after integration of stats. +// Get statistic response +#define WNI_CFG_GET_STAT_RSP_RES 0 +#define WNI_CFG_GET_STAT_RSP_PARAMID 1 +#define WNI_CFG_GET_STAT_RSP_VALUE 2 + +#define WNI_CFG_GET_STAT_RSP_NUM 3 +#define WNI_CFG_GET_STAT_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_STAT_RSP_NUM <<2)) +// Get per station statistic response +#define WNI_CFG_GET_PER_STA_STAT_RSP_RES 0 +#define WNI_CFG_GET_PER_STA_STAT_RSP_STAID 1 +#define WNI_CFG_GET_PER_STA_STAT_RSP_FIRST_PARAM 2 + +// Per STA statistic structure +typedef struct sAniCfgPerStaStatStruct +{ + unsigned long sentAesBlksUcastHi; + unsigned long sentAesBlksUcastLo; + + unsigned long recvAesBlksUcastHi; + unsigned long recvAesBlksUcastLo; + + unsigned long aesFormatErrorUcastCnts; + + unsigned long aesReplaysUcast; + + unsigned long aesDecryptErrUcast; + + unsigned long singleRetryPkts; + + unsigned long failedTxPkts; + + unsigned long ackTimeouts; + + unsigned long multiRetryPkts; + + unsigned long fragTxCntsHi; + unsigned long fragTxCntsLo; + + unsigned long transmittedPktsHi; + unsigned long transmittedPktsLo; + + unsigned long phyStatHi; + unsigned long phyStatLo; +} tCfgPerStaStatStruct, *tpAniCfgPerStaStatStruct; + +#define WNI_CFG_GET_PER_STA_STAT_RSP_NUM 23 +#define WNI_CFG_GET_PER_STA_STAT_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_PER_STA_STAT_RSP_NUM << 2)) + + +// Shall be removed after integrating stats. +#define WNI_CFG_GET_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x08) +#define WNI_CFG_GET_PER_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x09) +#define WNI_CFG_GET_AGG_STA_STAT_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0a) +#define WNI_CFG_GET_TX_RATE_CTR_RSP (WNI_CFG_MSG_TYPES_BEGIN | 0x0b) + +#define WNI_CFG_GET_AGG_STA_STAT_RSP_NUM 21 +#define WNI_CFG_GET_AGG_STA_STAT_RSP_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_AGG_STA_STAT_RSP_NUM << 2)) +#define WNI_CFG_GET_AGG_STA_STAT_RSP_RES 0 + + // Get TX rate based stats +#define WNI_CFG_GET_TX_RATE_CTR_RSP_RES 0 + +typedef struct sAniCfgTxRateCtrs +{ +// add the rate counters here + unsigned long TxFrames_1Mbps; + unsigned long TxFrames_2Mbps; + unsigned long TxFrames_5_5Mbps; + unsigned long TxFrames_6Mbps; + unsigned long TxFrames_9Mbps; + unsigned long TxFrames_11Mbps; + unsigned long TxFrames_12Mbps; + unsigned long TxFrames_18Mbps; + unsigned long TxFrames_24Mbps; + unsigned long TxFrames_36Mbps; + unsigned long TxFrames_48Mbps; + unsigned long TxFrames_54Mbps; + unsigned long TxFrames_72Mbps; + unsigned long TxFrames_96Mbps; + unsigned long TxFrames_108Mbps; + +} tAniCfgTxRateCtrs, *tpAniCfgTxRateCtrs; + + +#define WNI_CFG_GET_STAT_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x86) +#define WNI_CFG_GET_PER_STA_STAT_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x87) +#define WNI_CFG_GET_AGG_STA_STAT_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x88) +#define WNI_CFG_GET_TX_RATE_CTR_REQ (WNI_CFG_MSG_TYPES_BEGIN | 0x89) + +// Get statistic request +#define WNI_CFG_GET_STAT_REQ_PARAMID 0 + +#define WNI_CFG_GET_STAT_REQ_NUM 1 +#define WNI_CFG_GET_STAT_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_STAT_REQ_NUM << 2)) + + // Get per station statistic request +#define WNI_CFG_GET_PER_STA_STAT_REQ_STAID 0 + +#define WNI_CFG_GET_PER_STA_STAT_REQ_NUM 1 +#define WNI_CFG_GET_PER_STA_STAT_REQ_LEN (WNI_CFG_MB_HDR_LEN + \ + (WNI_CFG_GET_PER_STA_STAT_REQ_NUM << 2)) + + + + +#define DYNAMIC_CFG_TYPE_SELECTED_REGISTRAR (0) +#define DYNAMIC_CFG_TYPE_WPS_STATE (1) + +#endif /* __WNI_API_H */ + diff --git a/drivers/staging/prima/CORE/MAC/inc/wniCfg.h b/drivers/staging/prima/CORE/MAC/inc/wniCfg.h new file mode 100644 index 000000000000..4db2054360c2 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/wniCfg.h @@ -0,0 +1,1956 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef __WNICFG_H +#define __WNICFG_H + +/* + * Configuration Parameter ID for STA + */ + +enum { + WNI_CFG_STA_ID, + WNI_CFG_CF_POLLABLE, + WNI_CFG_CFP_PERIOD, + WNI_CFG_CFP_MAX_DURATION, + WNI_CFG_SSID, + WNI_CFG_BEACON_INTERVAL, + WNI_CFG_DTIM_PERIOD, + WNI_CFG_WEP_KEY_LENGTH, + WNI_CFG_WEP_DEFAULT_KEY_1, + WNI_CFG_WEP_DEFAULT_KEY_2, + WNI_CFG_WEP_DEFAULT_KEY_3, + WNI_CFG_WEP_DEFAULT_KEY_4, + WNI_CFG_WEP_DEFAULT_KEYID, + WNI_CFG_EXCLUDE_UNENCRYPTED, + WNI_CFG_RTS_THRESHOLD, + WNI_CFG_SHORT_RETRY_LIMIT, + WNI_CFG_LONG_RETRY_LIMIT, + WNI_CFG_FRAGMENTATION_THRESHOLD, + WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME, + WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + WNI_CFG_JOIN_FAILURE_TIMEOUT, + WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, + WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS, + WNI_CFG_PS_ENABLE_BCN_FILTER, + WNI_CFG_PS_ENABLE_HEART_BEAT, + WNI_CFG_PS_ENABLE_RSSI_MONITOR, + WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, + WNI_CFG_RF_SETTLING_TIME_CLK, + WNI_CFG_SUPPORTED_RATES_11B, + WNI_CFG_SUPPORTED_RATES_11A, + WNI_CFG_PHY_MODE, + WNI_CFG_DOT11_MODE, + WNI_CFG_OPERATIONAL_RATE_SET, + WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + WNI_CFG_BSSID, + WNI_CFG_LISTEN_INTERVAL, + WNI_CFG_VALID_CHANNEL_LIST, + WNI_CFG_CURRENT_CHANNEL, + WNI_CFG_DEFAULT_RATE_INDEX_5GHZ, + WNI_CFG_DEFAULT_RATE_INDEX_24GHZ, + WNI_CFG_RATE_ADAPTATION_TYPE, + WNI_CFG_FIXED_RATE, + WNI_CFG_FIXED_RATE_MULTICAST_24GHZ, + WNI_CFG_FIXED_RATE_MULTICAST_5GHZ, + WNI_CFG_RETRYRATE_POLICY, + WNI_CFG_RETRYRATE_SECONDARY, + WNI_CFG_RETRYRATE_TERTIARY, + WNI_CFG_APSD_ENABLED, + WNI_CFG_SHARED_KEY_AUTH_ENABLE, + WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE, + WNI_CFG_AUTHENTICATION_TYPE, + WNI_CFG_CF_POLL_REQUEST, + WNI_CFG_PRIVACY_ENABLED, + WNI_CFG_SHORT_PREAMBLE, + WNI_CFG_SHORT_SLOT_TIME, + WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY, + WNI_CFG_QOS_ENABLED, + WNI_CFG_HCF_ENABLED, + WNI_CFG_RSN_ENABLED, + WNI_CFG_BACKGROUND_SCAN_PERIOD, + WNI_CFG_MAX_NUM_PRE_AUTH, + WNI_CFG_PREAUTH_CLNUP_TIMEOUT, + WNI_CFG_RELEASE_AID_TIMEOUT, + WNI_CFG_HEART_BEAT_THRESHOLD, + WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT, + WNI_CFG_MANUFACTURER_OUI, + WNI_CFG_MANUFACTURER_NAME, + WNI_CFG_MODEL_NUMBER, + WNI_CFG_MODEL_NAME, + WNI_CFG_MANUFACTURER_PRODUCT_NAME, + WNI_CFG_MANUFACTURER_PRODUCT_VERSION, + WNI_CFG_11D_ENABLED, + WNI_CFG_MAX_TX_POWER_2_4, + WNI_CFG_MAX_TX_POWER_5, + WNI_CFG_NETWORK_DENSITY, + WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM, + WNI_CFG_CURRENT_TX_ANTENNA, + WNI_CFG_CURRENT_RX_ANTENNA, + WNI_CFG_CURRENT_TX_POWER_LEVEL, + WNI_CFG_POWER_STATE_PER_CHAIN, + WNI_CFG_NEW_BSS_FOUND_IND, + WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, + WNI_CFG_PROPRIETARY_RATES_ENABLED, + WNI_CFG_AP_NODE_NAME, + WNI_CFG_COUNTRY_CODE, + WNI_CFG_11H_ENABLED, + WNI_CFG_WT_CNF_TIMEOUT, + WNI_CFG_KEEPALIVE_TIMEOUT, + WNI_CFG_PROXIMITY, + WNI_CFG_LOG_LEVEL, + WNI_CFG_OLBC_DETECT_TIMEOUT, + WNI_CFG_PROTECTION_ENABLED, + WNI_CFG_11G_PROTECTION_ALWAYS, + WNI_CFG_FORCE_POLICY_PROTECTION, + WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, + WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, + WNI_CFG_CAL_PERIOD, + WNI_CFG_STATS_PERIOD, + WNI_CFG_CAL_CONTROL, + WNI_CFG_11G_ONLY_POLICY, + WNI_CFG_PACKET_CLASSIFICATION, + WNI_CFG_WME_ENABLED, + WNI_CFG_ADDTS_RSP_TIMEOUT, + WNI_CFG_MAX_SP_LENGTH, + WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD, + WNI_CFG_SEND_SINGLE_SSID_ALWAYS, + WNI_CFG_WSM_ENABLED, + WNI_CFG_PROP_CAPABILITY, + WNI_CFG_EDCA_PROFILE, + WNI_CFG_EDCA_ANI_ACBK_LOCAL, + WNI_CFG_EDCA_ANI_ACBE_LOCAL, + WNI_CFG_EDCA_ANI_ACVI_LOCAL, + WNI_CFG_EDCA_ANI_ACVO_LOCAL, + WNI_CFG_EDCA_ANI_ACBK, + WNI_CFG_EDCA_ANI_ACBE, + WNI_CFG_EDCA_ANI_ACVI, + WNI_CFG_EDCA_ANI_ACVO, + WNI_CFG_EDCA_WME_ACBK_LOCAL, + WNI_CFG_EDCA_WME_ACBE_LOCAL, + WNI_CFG_EDCA_WME_ACVI_LOCAL, + WNI_CFG_EDCA_WME_ACVO_LOCAL, + WNI_CFG_EDCA_WME_ACBK, + WNI_CFG_EDCA_WME_ACBE, + WNI_CFG_EDCA_WME_ACVI, + WNI_CFG_EDCA_WME_ACVO, + WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACBK, + WNI_CFG_EDCA_TIT_DEMO_ACBE, + WNI_CFG_EDCA_TIT_DEMO_ACVI, + WNI_CFG_EDCA_TIT_DEMO_ACVO, + WNI_CFG_RDET_FLAG, + WNI_CFG_RADAR_CHANNEL_LIST, + WNI_CFG_LOCAL_POWER_CONSTRAINT, + WNI_CFG_ADMIT_POLICY, + WNI_CFG_ADMIT_BWFACTOR, + WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, + WNI_CFG_CHANNEL_BONDING_MODE, + WNI_CFG_CB_SECONDARY_CHANNEL_STATE, + WNI_CFG_DYNAMIC_THRESHOLD_ZERO, + WNI_CFG_DYNAMIC_THRESHOLD_ONE, + WNI_CFG_DYNAMIC_THRESHOLD_TWO, + WNI_CFG_TRIG_STA_BK_SCAN, + WNI_CFG_DYNAMIC_PROFILE_SWITCHING, + WNI_CFG_SCAN_CONTROL_LIST, + WNI_CFG_MIMO_ENABLED, + WNI_CFG_BLOCK_ACK_ENABLED, + WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT, + WNI_CFG_HT_RX_STBC, + WNI_CFG_HT_CAP_INFO, + WNI_CFG_HT_AMPDU_PARAMS, + WNI_CFG_SUPPORTED_MCS_SET, + WNI_CFG_EXT_HT_CAP_INFO, + WNI_CFG_TX_BF_CAP, + WNI_CFG_AS_CAP, + WNI_CFG_HT_INFO_FIELD1, + WNI_CFG_HT_INFO_FIELD2, + WNI_CFG_HT_INFO_FIELD3, + WNI_CFG_BASIC_MCS_SET, + WNI_CFG_CURRENT_MCS_SET, + WNI_CFG_GREENFIELD_CAPABILITY, + WNI_CFG_VHT_MAX_MPDU_LENGTH, + WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, + WNI_CFG_VHT_LDPC_CODING_CAP, + WNI_CFG_VHT_SHORT_GI_80MHZ, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + WNI_CFG_VHT_TXSTBC, + WNI_CFG_VHT_RXSTBC, + WNI_CFG_VHT_SU_BEAMFORMER_CAP, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, + WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS, + WNI_CFG_VHT_MU_BEAMFORMER_CAP, + WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + WNI_CFG_VHT_TXOP_PS, + WNI_CFG_VHT_HTC_VHTC_CAP, + WNI_CFG_VHT_AMPDU_LEN_EXPONENT, + WNI_CFG_VHT_LINK_ADAPTATION_CAP, + WNI_CFG_VHT_RX_ANT_PATTERN, + WNI_CFG_VHT_TX_ANT_PATTERN, + WNI_CFG_VHT_RX_MCS_MAP, + WNI_CFG_VHT_TX_MCS_MAP, + WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, + WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, + WNI_CFG_VHT_CHANNEL_WIDTH, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2, + WNI_CFG_VHT_BASIC_MCS_SET, + WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT, + WNI_CFG_VHT_SS_UNDER_UTIL, + WNI_CFG_VHT_40MHZ_UTILIZATION, + WNI_CFG_VHT_80MHZ_UTILIZATION, + WNI_CFG_VHT_160MHZ_UTILIZATION, + WNI_CFG_MAX_AMSDU_LENGTH, + WNI_CFG_MPDU_DENSITY, + WNI_CFG_NUM_BUFF_ADVERT, + WNI_CFG_MAX_RX_AMPDU_FACTOR, + WNI_CFG_SHORT_GI_20MHZ, + WNI_CFG_SHORT_GI_40MHZ, + WNI_CFG_RIFS_ENABLED, + WNI_CFG_MAX_PS_POLL, + WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, + WNI_CFG_RSSI_FILTER_PERIOD, + WNI_CFG_MIN_RSSI_THRESHOLD, + WNI_CFG_NTH_BEACON_FILTER, + WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE, + WNI_CFG_SCAN_IN_POWERSAVE, + WNI_CFG_IGNORE_DTIM, + WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE, + WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE, + WNI_CFG_WOWLAN_DEAUTH_ENABLE, + WNI_CFG_WOWLAN_DISASSOC_ENABLE, + WNI_CFG_WOWLAN_MAX_MISSED_BEACON, + WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD, + WNI_CFG_BA_TIMEOUT, + WNI_CFG_BA_THRESHOLD_HIGH, + WNI_CFG_MAX_BA_BUFFERS, + WNI_CFG_MAX_BA_SESSIONS, + WNI_CFG_BA_AUTO_SETUP, + WNI_CFG_ADDBA_REQ_DECLINE, + WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, + WNI_CFG_BG_SCAN_CHANNEL_LIST, + WNI_CFG_MAX_MEDIUM_TIME, + WNI_CFG_MAX_MPDUS_IN_AMPDU, + WNI_CFG_IBSS_AUTO_BSSID, + WNI_CFG_PROBE_REQ_ADDNIE_FLAG, + WNI_CFG_PROBE_REQ_ADDNIE_DATA, + WNI_CFG_PROBE_RSP_ADDNIE_FLAG, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, + WNI_CFG_ASSOC_RSP_ADDNIE_DATA, + WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG, + WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, + WNI_CFG_WPS_ENABLE, + WNI_CFG_WPS_STATE, + WNI_CFG_WPS_PROBE_REQ_FLAG, + WNI_CFG_WPS_VERSION, + WNI_CFG_WPS_REQUEST_TYPE, + WNI_CFG_WPS_CFG_METHOD, + WNI_CFG_WPS_UUID, + WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY, + WNI_CFG_WPS_PIMARY_DEVICE_OUI, + WNI_CFG_WPS_DEVICE_SUB_CATEGORY, + WNI_CFG_WPS_ASSOCIATION_STATE, + WNI_CFG_WPS_CONFIGURATION_ERROR, + WNI_CFG_WPS_DEVICE_PASSWORD_ID, + WNI_CFG_WPS_ASSOC_METHOD, + WNI_CFG_LOW_GAIN_OVERRIDE, + WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE, + WNI_CFG_RPE_POLLING_THRESHOLD, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG, + WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS, + WNI_CFG_SINGLE_TID_RC, + WNI_CFG_RRM_ENABLED, + WNI_CFG_RRM_OPERATING_CHAN_MAX, + WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, + WNI_CFG_TX_PWR_CTRL_ENABLE, + WNI_CFG_MCAST_BCAST_FILTER_SETTING, + WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK, + WNI_CFG_DYNAMIC_PS_POLL_VALUE, + WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT, + WNI_CFG_TELE_BCN_WAKEUP_EN, + WNI_CFG_TELE_BCN_TRANS_LI, + WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS, + WNI_CFG_TELE_BCN_MAX_LI, + WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS, + WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS, + WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD, + WNI_CFG_ASSOC_STA_LIMIT, + WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, + WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, + WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD, + WNI_CFG_ENABLE_CLOSE_LOOP, + WNI_CFG_ENABLE_LTE_COEX, + WNI_CFG_AP_KEEP_ALIVE_TIMEOUT, + WNI_CFG_GO_KEEP_ALIVE_TIMEOUT, + WNI_CFG_ENABLE_MC_ADDR_LIST, + WNI_CFG_ENABLE_UC_FILTER, + WNI_CFG_ENABLE_LPWR_IMG_TRANSITION, + WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, + WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP, + WNI_CFG_AP_LINK_MONITOR_TIMEOUT, + WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, + WNI_CFG_TDLS_BUF_STA_ENABLED, + WNI_CFG_TDLS_PUAPSD_INACT_TIME, + WNI_CFG_TDLS_RX_FRAME_THRESHOLD, + WNI_CFG_ENABLE_ADAPT_RX_DRAIN, + WNI_CFG_FLEX_CONNECT_POWER_FACTOR, + WNI_CFG_ANTENNA_DIVESITY, + WNI_CFG_GO_LINK_MONITOR_TIMEOUT, + WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY, + WNI_CFG_ATH_DISABLE, + WNI_CFG_BTC_ACTIVE_WLAN_LEN, + WNI_CFG_BTC_ACTIVE_BT_LEN, + WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN, + WNI_CFG_BTC_SAP_ACTIVE_BT_LEN, + WNI_CFG_ASD_PROBE_INTERVAL, + WNI_CFG_ASD_TRIGGER_THRESHOLD, + WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD, + WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL, + WNI_CFG_BTC_CTS2S_DURING_SCO, + WNI_CFG_CHANNEL_BONDING_24G, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL, + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD, + WNI_CFG_TDLS_OFF_CHANNEL_ENABLED, + WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + WNI_CFG_RA_FILTER_ENABLE, + WNI_CFG_RA_RATE_LIMIT_INTERVAL, + WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE, + WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE, + WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD, + WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD, + WNI_CFG_TDLS_WMM_MODE_ENABLED, + WNI_CFG_MAX_UAPSD_CONSEC_SP, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW, + WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE, + WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS, + WNI_CFG_ENABLE_DYNAMIC_WMMPS, + WNI_CFG_BURST_MODE_BE_TXOP_VALUE, + WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE, + WNI_CFG_BTC_FAST_WLAN_CONN_PREF, + WNI_CFG_ENABLE_RTSCTS_HTVHT, + WNI_CFG_TOGGLE_ARP_BDRATES, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN, + WNI_CFG_LINK_FAIL_TIMEOUT, + WNI_CFG_LINK_FAIL_TX_CNT, + WNI_CFG_OPTIMIZE_CA_EVENT, + WNI_CFG_ACTIVE_PASSIVE_CON, + WNI_CFG_EXT_SCAN_CONC_MODE, + WNI_CFG_ENABLE_MAC_ADDR_SPOOFING, + WNI_CFG_DISABLE_BAR_WAKE_UP_HOST, + WNI_CFG_SAR_BOFFSET_SET_CORRECTION, + WNI_CFG_ENABLE_UNITS_BWAIT, + WNI_CFG_ENABLE_CONC_BMISS, + WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL, + WNI_CFG_DISABLE_SCAN_DURING_SCO, + WNI_CFG_ENABLE_TX_RX_AGGREGATION, + WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB +}; + +/* + * String parameter lengths + */ + +#define WNI_CFG_STA_ID_LEN 6 +#define WNI_CFG_SSID_LEN 32 +#define WNI_CFG_WEP_DEFAULT_KEY_1_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_2_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_3_LEN 13 +#define WNI_CFG_WEP_DEFAULT_KEY_4_LEN 13 +#define WNI_CFG_SUPPORTED_RATES_11B_LEN 4 +#define WNI_CFG_SUPPORTED_RATES_11A_LEN 8 +#define WNI_CFG_OPERATIONAL_RATE_SET_LEN 12 +#define WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN 8 +#define WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN 4 +#define WNI_CFG_BSSID_LEN 6 +#define WNI_CFG_MACADDR_LEN 6 +#define WNI_CFG_VALID_CHANNEL_LIST_LEN 100 +#define WNI_CFG_MANUFACTURER_OUI_LEN 3 +#define WNI_CFG_MANUFACTURER_NAME_LEN 65 +#define WNI_CFG_MODEL_NUMBER_LEN 33 +#define WNI_CFG_MODEL_NAME_LEN 33 +#define WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN 33 +#define WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN 33 +#define WNI_CFG_MAX_TX_POWER_2_4_LEN 128 +#define WNI_CFG_MAX_TX_POWER_5_LEN 128 +#define WNI_CFG_AP_NODE_NAME_LEN 32 +#define WNI_CFG_COUNTRY_CODE_LEN 3 +#define WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBK_LEN 20 +#define WNI_CFG_EDCA_ANI_ACBE_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVI_LEN 20 +#define WNI_CFG_EDCA_ANI_ACVO_LEN 20 +#define WNI_CFG_EDCA_WME_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_WME_ACBK_LEN 20 +#define WNI_CFG_EDCA_WME_ACBE_LEN 20 +#define WNI_CFG_EDCA_WME_ACVI_LEN 20 +#define WNI_CFG_EDCA_WME_ACVO_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBK_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACBE_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVI_LEN 20 +#define WNI_CFG_EDCA_TIT_DEMO_ACVO_LEN 20 +#define WNI_CFG_RADAR_CHANNEL_LIST_LEN 20 +#define WNI_CFG_SCAN_CONTROL_LIST_LEN 128 +#define WNI_CFG_SUPPORTED_MCS_SET_LEN 16 +#define WNI_CFG_BASIC_MCS_SET_LEN 16 +#define WNI_CFG_CURRENT_MCS_SET_LEN 16 +#define WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN 100 +#define WNI_CFG_PROBE_REQ_ADDNIE_DATA_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN 255 +#define WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN 255 +#define WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN 255 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA_LEN 255 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN 255 +#define WNI_CFG_WPS_UUID_LEN 16 + +/* + * Integer parameter min/max/default values + */ + +#define WNI_CFG_CFP_PERIOD_STAMIN 0 +#define WNI_CFG_CFP_PERIOD_STAMAX 255 +#define WNI_CFG_CFP_PERIOD_STADEF 1 + +#define WNI_CFG_CFP_MAX_DURATION_STAMIN 0 +#define WNI_CFG_CFP_MAX_DURATION_STAMAX 65535 +#define WNI_CFG_CFP_MAX_DURATION_STADEF 30000 + +#define WNI_CFG_BEACON_INTERVAL_STAMIN 0 +#define WNI_CFG_BEACON_INTERVAL_STAMAX 65535 +#define WNI_CFG_BEACON_INTERVAL_STADEF 100 + +#define WNI_CFG_DTIM_PERIOD_STAMIN 0 +#define WNI_CFG_DTIM_PERIOD_STAMAX 65535 +#define WNI_CFG_DTIM_PERIOD_STADEF 1 + +#define WNI_CFG_WEP_KEY_LENGTH_STAMIN 5 +#define WNI_CFG_WEP_KEY_LENGTH_STAMAX 13 +#define WNI_CFG_WEP_KEY_LENGTH_STADEF 5 + +#define WNI_CFG_WEP_KEY_LENGTH_5 5 +#define WNI_CFG_WEP_KEY_LENGTH_13 13 + +#define WNI_CFG_WEP_DEFAULT_KEYID_STAMIN 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_STAMAX 3 +#define WNI_CFG_WEP_DEFAULT_KEYID_STADEF 0 + +#define WNI_CFG_WEP_DEFAULT_KEYID_0 0 +#define WNI_CFG_WEP_DEFAULT_KEYID_1 1 +#define WNI_CFG_WEP_DEFAULT_KEYID_2 2 +#define WNI_CFG_WEP_DEFAULT_KEYID_3 3 + +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMIN 0 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STAMAX 1 +#define WNI_CFG_EXCLUDE_UNENCRYPTED_STADEF 0 + +#define WNI_CFG_RTS_THRESHOLD_STAMIN 0 +#define WNI_CFG_RTS_THRESHOLD_STAMAX 2347 +#define WNI_CFG_RTS_THRESHOLD_STADEF 2347 + +#define WNI_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define WNI_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define WNI_CFG_SHORT_RETRY_LIMIT_STADEF 6 + +#define WNI_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define WNI_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define WNI_CFG_LONG_RETRY_LIMIT_STADEF 6 + +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STADEF 20 + +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF 40 + +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STADEF 60 + +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN 0 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX 65535 +#define WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF 110 + +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF 3000 + +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STADEF 1000 + +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMIN 0 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMAX 65535 +#define WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STADEF 1000 + +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STADEF 2000 + +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN 0 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX 65535 +#define WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF 1000 + +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMIN 0 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMAX 65535 +#define WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STADEF 1000 + +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define WNI_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMIN 0 +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STAMAX 1 +#define WNI_CFG_PS_ENABLE_HEART_BEAT_STADEF 1 + +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define WNI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 0 + +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMIN 0 +#define WNI_CFG_RF_SETTLING_TIME_CLK_STAMAX 60000 +#define WNI_CFG_RF_SETTLING_TIME_CLK_STADEF 1500 + +#define WNI_CFG_PHY_MODE_STAMIN 0 +#define WNI_CFG_PHY_MODE_STAMAX 3 +#define WNI_CFG_PHY_MODE_STADEF 0 + +#define WNI_CFG_PHY_MODE_11A 0 +#define WNI_CFG_PHY_MODE_11B 1 +#define WNI_CFG_PHY_MODE_11G 2 +#define WNI_CFG_PHY_MODE_NONE 3 + +#define WNI_CFG_DOT11_MODE_STAMIN 0 +#define WNI_CFG_DOT11_MODE_STAMAX 11 +#define WNI_CFG_DOT11_MODE_STADEF 0 + +#define WNI_CFG_DOT11_MODE_ALL 0 +#define WNI_CFG_DOT11_MODE_11A 1 +#define WNI_CFG_DOT11_MODE_11B 2 +#define WNI_CFG_DOT11_MODE_11G 3 +#define WNI_CFG_DOT11_MODE_11N 4 +#define WNI_CFG_DOT11_MODE_POLARIS 5 +#define WNI_CFG_DOT11_MODE_TITAN 6 +#define WNI_CFG_DOT11_MODE_TAURUS 7 +#define WNI_CFG_DOT11_MODE_11G_ONLY 8 +#define WNI_CFG_DOT11_MODE_11N_ONLY 9 +#define WNI_CFG_DOT11_MODE_11AC 10 +#define WNI_CFG_DOT11_MODE_11AC_ONLY 11 + +#define WNI_CFG_LISTEN_INTERVAL_STAMIN 0 +#define WNI_CFG_LISTEN_INTERVAL_STAMAX 65535 +#define WNI_CFG_LISTEN_INTERVAL_STADEF 1 + +#define WNI_CFG_CURRENT_CHANNEL_STAMIN 0 +#define WNI_CFG_CURRENT_CHANNEL_STAMAX 165 +#define WNI_CFG_CURRENT_CHANNEL_STADEF 1 + +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX 11 +#define WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF 5 + +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX 31 +#define WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_STAMIN 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_STAMAX 2 +#define WNI_CFG_RATE_ADAPTATION_TYPE_STADEF 1 + +#define WNI_CFG_RATE_ADAPTATION_TYPE_FIXED 0 +#define WNI_CFG_RATE_ADAPTATION_TYPE_AUTO 1 +#define WNI_CFG_RATE_ADAPTATION_TYPE_SNR_BASED 2 + +#define WNI_CFG_FIXED_RATE_STAMIN 0 +#define WNI_CFG_FIXED_RATE_STAMAX 44 +#define WNI_CFG_FIXED_RATE_STADEF 0 + +#define WNI_CFG_FIXED_RATE_AUTO 0 +#define WNI_CFG_FIXED_RATE_1MBPS 1 +#define WNI_CFG_FIXED_RATE_2MBPS 2 +#define WNI_CFG_FIXED_RATE_5_5MBPS 3 +#define WNI_CFG_FIXED_RATE_11MBPS 4 +#define WNI_CFG_FIXED_RATE_6MBPS 5 +#define WNI_CFG_FIXED_RATE_9MBPS 6 +#define WNI_CFG_FIXED_RATE_12MBPS 7 +#define WNI_CFG_FIXED_RATE_18MBPS 8 +#define WNI_CFG_FIXED_RATE_24MBPS 9 +#define WNI_CFG_FIXED_RATE_36MBPS 10 +#define WNI_CFG_FIXED_RATE_48MBPS 11 +#define WNI_CFG_FIXED_RATE_54MBPS 12 +#define WNI_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define WNI_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define WNI_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define WNI_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define WNI_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define WNI_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define WNI_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define WNI_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define WNI_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define WNI_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define WNI_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define WNI_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define WNI_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define WNI_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define WNI_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define WNI_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define WNI_CFG_FIXED_RATE_0_25MBPS_SLR_20MHZ_SIMO 29 +#define WNI_CFG_FIXED_RATE_0_5MBPS_SLR_20MHZ_SIMO 30 +#define WNI_CFG_FIXED_RATE_68_25MBPS_QC_PROP_20MHZ_SIMO 31 +#define WNI_CFG_FIXED_RATE_54MBPS_MCS3_40MHZ_SIMO 32 +#define WNI_CFG_FIXED_RATE_81MBPS_MCS4_40MHZ_SIMO 33 +#define WNI_CFG_FIXED_RATE_108MBPS_MCS5_40MHZ_SIMO 34 +#define WNI_CFG_FIXED_RATE_121_5MBPS_MCS6_40MHZ_SIMO 35 +#define WNI_CFG_FIXED_RATE_135MBPS_MCS7_40MHZ_SIMO 36 +#define WNI_CFG_FIXED_RATE_15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#define WNI_CFG_FIXED_RATE_30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#define WNI_CFG_FIXED_RATE_45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#define WNI_CFG_FIXED_RATE_60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#define WNI_CFG_FIXED_RATE_90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#define WNI_CFG_FIXED_RATE_120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#define WNI_CFG_FIXED_RATE_135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#define WNI_CFG_FIXED_RATE_150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF 1 + +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX 31 +#define WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF 5 + +#define WNI_CFG_RETRYRATE_POLICY_STAMIN 0 +#define WNI_CFG_RETRYRATE_POLICY_STAMAX 255 +#define WNI_CFG_RETRYRATE_POLICY_STADEF 4 + +#define WNI_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define WNI_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define WNI_CFG_RETRYRATE_POLICY_RESERVED 2 +#define WNI_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define WNI_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define WNI_CFG_RETRYRATE_POLICY_MAX 5 + +#define WNI_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define WNI_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define WNI_CFG_RETRYRATE_SECONDARY_STADEF 0 + +#define WNI_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define WNI_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define WNI_CFG_RETRYRATE_TERTIARY_STADEF 0 + +#define WNI_CFG_APSD_ENABLED_STAMIN 0 +#define WNI_CFG_APSD_ENABLED_STAMAX 1 +#define WNI_CFG_APSD_ENABLED_STADEF 0 + +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMIN 0 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMAX 1 +#define WNI_CFG_SHARED_KEY_AUTH_ENABLE_STADEF 1 + +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMIN 0 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMAX 1 +#define WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STADEF 1 + +#define WNI_CFG_AUTHENTICATION_TYPE_STAMIN 0 +#define WNI_CFG_AUTHENTICATION_TYPE_STAMAX 65535 +#define WNI_CFG_AUTHENTICATION_TYPE_STADEF 0 + +#define WNI_CFG_PRIVACY_ENABLED_STAMIN 0 +#define WNI_CFG_PRIVACY_ENABLED_STAMAX 1 +#define WNI_CFG_PRIVACY_ENABLED_STADEF 0 + +#define WNI_CFG_SHORT_PREAMBLE_STAMIN 0 +#define WNI_CFG_SHORT_PREAMBLE_STAMAX 1 +#define WNI_CFG_SHORT_PREAMBLE_STADEF 1 + +#define WNI_CFG_SHORT_SLOT_TIME_STAMIN 0 +#define WNI_CFG_SHORT_SLOT_TIME_STAMAX 1 +#define WNI_CFG_SHORT_SLOT_TIME_STADEF 1 + +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMIN 0 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMAX 1 +#define WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STADEF 0 + +#define WNI_CFG_QOS_ENABLED_STAMIN 0 +#define WNI_CFG_QOS_ENABLED_STAMAX 1 +#define WNI_CFG_QOS_ENABLED_STADEF 0 + +#define WNI_CFG_HCF_ENABLED_STAMIN 0 +#define WNI_CFG_HCF_ENABLED_STAMAX 1 +#define WNI_CFG_HCF_ENABLED_STADEF 0 + +#define WNI_CFG_RSN_ENABLED_STAMIN 0 +#define WNI_CFG_RSN_ENABLED_STAMAX 1 +#define WNI_CFG_RSN_ENABLED_STADEF 0 + +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMIN 0 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMAX 180000 +#define WNI_CFG_BACKGROUND_SCAN_PERIOD_STADEF 5000 + +#define WNI_CFG_MAX_NUM_PRE_AUTH_STAMIN 0 +#define WNI_CFG_MAX_NUM_PRE_AUTH_STAMAX 256 +#define WNI_CFG_MAX_NUM_PRE_AUTH_STADEF 64 + +#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN 0 +#define WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX 256 +#define WNI_CFG_HEART_BEAT_THRESHOLD_STADEF 40 + +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMIN 10 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMAX 10000 +#define WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STADEF 40 + +#define WNI_CFG_11D_ENABLED_STAMIN 0 +#define WNI_CFG_11D_ENABLED_STAMAX 1 +#define WNI_CFG_11D_ENABLED_STADEF 1 + +#define WNI_CFG_NETWORK_DENSITY_STAMIN 0 +#define WNI_CFG_NETWORK_DENSITY_STAMAX 3 +#define WNI_CFG_NETWORK_DENSITY_STADEF 3 + +#define WNI_CFG_NETWORK_DENSITY_LOW 0 +#define WNI_CFG_NETWORK_DENSITY_MEDIUM 1 +#define WNI_CFG_NETWORK_DENSITY_HIGH 2 +#define WNI_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMIN 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMAX 2 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STADEF 2 + +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CARRIER 1 +#define WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_CORRELATION 2 + +#define WNI_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define WNI_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +#define WNI_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define WNI_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define WNI_CFG_CURRENT_RX_ANTENNA_STADEF 2 + +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN 0 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX 128 +#define WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF 27 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define WNI_CFG_POWER_STATE_PER_CHAIN_STADEF 785 + +#define WNI_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define WNI_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define WNI_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define WNI_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define WNI_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +#define WNI_CFG_NEW_BSS_FOUND_IND_STAMIN 0 +#define WNI_CFG_NEW_BSS_FOUND_IND_STAMAX 1 +#define WNI_CFG_NEW_BSS_FOUND_IND_STADEF 0 + +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMIN 0 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMAX 1 +#define WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STADEF 0 + +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMIN 0 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMAX 1 +#define WNI_CFG_PROPRIETARY_RATES_ENABLED_STADEF 0 + +#define WNI_CFG_11H_ENABLED_STAMIN 0 +#define WNI_CFG_11H_ENABLED_STAMAX 1 +#define WNI_CFG_11H_ENABLED_STADEF 1 + +#define WNI_CFG_WT_CNF_TIMEOUT_STAMIN 10 +#define WNI_CFG_WT_CNF_TIMEOUT_STAMAX 3000 +#define WNI_CFG_WT_CNF_TIMEOUT_STADEF 1000 + +#define WNI_CFG_KEEPALIVE_TIMEOUT_STAMIN 0 +#define WNI_CFG_KEEPALIVE_TIMEOUT_STAMAX 3600000 +#define WNI_CFG_KEEPALIVE_TIMEOUT_STADEF 0 + +#define WNI_CFG_PROXIMITY_STAMIN 0 +#define WNI_CFG_PROXIMITY_STAMAX 1 +#define WNI_CFG_PROXIMITY_STADEF 0 + +#define WNI_CFG_PROXIMITY_OFF 0 +#define WNI_CFG_PROXIMITY_ON 1 + +#define WNI_CFG_LOG_LEVEL_STAMIN 0 +#define WNI_CFG_LOG_LEVEL_STAMAX 7 +#define WNI_CFG_LOG_LEVEL_STADEF 4 + +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STAMIN 1000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STAMAX 30000 +#define WNI_CFG_OLBC_DETECT_TIMEOUT_STADEF 10000 + +#define WNI_CFG_PROTECTION_ENABLED_STAMIN 0 +#define WNI_CFG_PROTECTION_ENABLED_STAMAX 65535 +#define WNI_CFG_PROTECTION_ENABLED_STADEF 65535 + +#define WNI_CFG_PROTECTION_ENABLED_FROM_llA 0 +#define WNI_CFG_PROTECTION_ENABLED_FROM_llB 1 +#define WNI_CFG_PROTECTION_ENABLED_FROM_llG 2 +#define WNI_CFG_PROTECTION_ENABLED_HT_20 3 +#define WNI_CFG_PROTECTION_ENABLED_NON_GF 4 +#define WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP 5 +#define WNI_CFG_PROTECTION_ENABLED_RIFS 6 +#define WNI_CFG_PROTECTION_ENABLED_OBSS 7 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llA 8 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llB 9 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_FROM_llG 10 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_HT20 11 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_NON_GF 12 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_LSIG_TXOP 13 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_RIFS 14 +#define WNI_CFG_PROTECTION_ENABLED_OLBC_OBSS 15 + +#define WNI_CFG_11G_PROTECTION_ALWAYS_STAMIN 0 +#define WNI_CFG_11G_PROTECTION_ALWAYS_STAMAX 1 +#define WNI_CFG_11G_PROTECTION_ALWAYS_STADEF 0 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define WNI_CFG_FORCE_POLICY_PROTECTION_STADEF 5 + +#define WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define WNI_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define WNI_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define WNI_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define WNI_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define WNI_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMIN 0 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMAX 1 +#define WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STADEF 0 + +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMIN 0 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMAX 1 +#define WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STADEF 1 + +#define WNI_CFG_CAL_PERIOD_STAMIN 2 +#define WNI_CFG_CAL_PERIOD_STAMAX 10 +#define WNI_CFG_CAL_PERIOD_STADEF 5 + +#define WNI_CFG_STATS_PERIOD_STAMIN 1 +#define WNI_CFG_STATS_PERIOD_STAMAX 10 +#define WNI_CFG_STATS_PERIOD_STADEF 10 + +#define WNI_CFG_CAL_CONTROL_STAMIN 0 +#define WNI_CFG_CAL_CONTROL_STAMAX 1 +#define WNI_CFG_CAL_CONTROL_STADEF 0 + +#define WNI_CFG_CAL_CONTROL_CAL_ON 0 +#define WNI_CFG_CAL_CONTROL_CAL_OFF 1 + +#define WNI_CFG_11G_ONLY_POLICY_STAMIN 0 +#define WNI_CFG_11G_ONLY_POLICY_STAMAX 1 +#define WNI_CFG_11G_ONLY_POLICY_STADEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_STAMIN 0 +#define WNI_CFG_PACKET_CLASSIFICATION_STAMAX 3 +#define WNI_CFG_PACKET_CLASSIFICATION_STADEF 0 + +#define WNI_CFG_PACKET_CLASSIFICATION_DISABLED 0 +#define WNI_CFG_PACKET_CLASSIFICATION_DSCP 1 +#define WNI_CFG_PACKET_CLASSIFICATION_8021P 2 +#define WNI_CFG_PACKET_CLASSIFICATION_ALL 3 + +#define WNI_CFG_WME_ENABLED_STAMIN 0 +#define WNI_CFG_WME_ENABLED_STAMAX 1 +#define WNI_CFG_WME_ENABLED_STADEF 1 + +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STAMIN 0 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STAMAX 65535 +#define WNI_CFG_ADDTS_RSP_TIMEOUT_STADEF 1000 + +#define WNI_CFG_MAX_SP_LENGTH_STAMIN 0 +#define WNI_CFG_MAX_SP_LENGTH_STAMAX 3 +#define WNI_CFG_MAX_SP_LENGTH_STADEF 0 + +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMIN 0 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMAX 1 +#define WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STADEF 0 + +#define WNI_CFG_WSM_ENABLED_STAMIN 0 +#define WNI_CFG_WSM_ENABLED_STAMAX 1 +#define WNI_CFG_WSM_ENABLED_STADEF 0 + +#define WNI_CFG_PROP_CAPABILITY_STAMIN 0 +#define WNI_CFG_PROP_CAPABILITY_STAMAX 65535 +#define WNI_CFG_PROP_CAPABILITY_STADEF 57535 + +#define WNI_CFG_PROP_CAPABILITY_HCF 0 +#define WNI_CFG_PROP_CAPABILITY_11EQOS 1 +#define WNI_CFG_PROP_CAPABILITY_WME 2 +#define WNI_CFG_PROP_CAPABILITY_WSM 3 +#define WNI_CFG_PROP_CAPABILITY_EXTRATES 4 +#define WNI_CFG_PROP_CAPABILITY_EXTRATE_STOP 5 +#define WNI_CFG_PROP_CAPABILITY_TITAN 6 +#define WNI_CFG_PROP_CAPABILITY_TAURUS 7 +#define WNI_CFG_PROP_CAPABILITY_EDCAPARAMS 13 +#define WNI_CFG_PROP_CAPABILITY_LOADINFO 14 +#define WNI_CFG_PROP_CAPABILITY_VERSION 15 +#define WNI_CFG_PROP_CAPABILITY_MAXBITOFFSET 15 + +#define WNI_CFG_EDCA_PROFILE_STAMIN 0 +#define WNI_CFG_EDCA_PROFILE_STAMAX 255 +#define WNI_CFG_EDCA_PROFILE_STADEF 1 + +#define WNI_CFG_EDCA_PROFILE_ANI 0 +#define WNI_CFG_EDCA_PROFILE_WMM 1 +#define WNI_CFG_EDCA_PROFILE_TIT_DEMO 2 +#define WNI_CFG_EDCA_PROFILE_MAX 3 +#define WNI_CFG_EDCA_PROFILE_ACM_IDX 0 +#define WNI_CFG_EDCA_PROFILE_AIFSN_IDX 1 +#define WNI_CFG_EDCA_PROFILE_CWMINA_IDX 2 +#define WNI_CFG_EDCA_PROFILE_CWMAXA_IDX 4 +#define WNI_CFG_EDCA_PROFILE_TXOPA_IDX 6 +#define WNI_CFG_EDCA_PROFILE_CWMINB_IDX 7 +#define WNI_CFG_EDCA_PROFILE_CWMAXB_IDX 9 +#define WNI_CFG_EDCA_PROFILE_TXOPB_IDX 11 +#define WNI_CFG_EDCA_PROFILE_CWMING_IDX 12 +#define WNI_CFG_EDCA_PROFILE_CWMAXG_IDX 14 +#define WNI_CFG_EDCA_PROFILE_TXOPG_IDX 16 + +#define WNI_CFG_RDET_FLAG_STAMIN 0 +#define WNI_CFG_RDET_FLAG_STAMAX 1 +#define WNI_CFG_RDET_FLAG_STADEF 0 + +#define WNI_CFG_RDET_FLAG_ENABLE 1 +#define WNI_CFG_RDET_FLAG_DISABLE 0 + +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN 0 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX 255 +#define WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF 0 + +#define WNI_CFG_ADMIT_POLICY_STAMIN 0 +#define WNI_CFG_ADMIT_POLICY_STAMAX 2 +#define WNI_CFG_ADMIT_POLICY_STADEF 0 + +#define WNI_CFG_ADMIT_POLICY_ADMIT_ALL 0 +#define WNI_CFG_ADMIT_POLICY_REJECT_ALL 1 +#define WNI_CFG_ADMIT_POLICY_BW_FACTOR 2 + +#define WNI_CFG_ADMIT_BWFACTOR_STAMIN 0 +#define WNI_CFG_ADMIT_BWFACTOR_STAMAX 100 +#define WNI_CFG_ADMIT_BWFACTOR_STADEF 20 + +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMIN 0 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMAX 256 +#define WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STADEF 60 + +#define WNI_CFG_CHANNEL_BONDING_MODE_STAMIN 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_STAMAX 10 +#define WNI_CFG_CHANNEL_BONDING_MODE_STADEF 0 + +#define WNI_CFG_CHANNEL_BONDING_MODE_DISABLE 0 +#define WNI_CFG_CHANNEL_BONDING_MODE_ENABLE 1 +#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_BSS 2 +#define WNI_CFG_CHANNEL_BONDING_MODE_IF_NO_LEGACY_ALL 3 +#define WNI_CFG_CHANNEL_BONDING_MODE_INTELLIGENT 4 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMIN 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMAX 10 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STADEF 0 + +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_NONE 0 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_LOWER 1 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_HIGHER 2 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_CENTERED 3 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_CENTERED_40MHZ_CENTERED 4 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_CENTERED 5 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_LOW 6 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_LOW 7 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_LOW_40MHZ_HIGH 8 +#define WNI_CFG_CB_SECONDARY_CHANNEL_STATE_11AC_20MHZ_HIGH_40MHZ_HIGH 9 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 2 + +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 4 + +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define WNI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 6 + +#define WNI_CFG_TRIG_STA_BK_SCAN_STAMIN 0 +#define WNI_CFG_TRIG_STA_BK_SCAN_STAMAX 1 +#define WNI_CFG_TRIG_STA_BK_SCAN_STADEF 0 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMIN 0 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMAX 255 +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STADEF 255 + +#define WNI_CFG_DYNAMIC_PROFILE_SWITCHING_UNUSED 255 + +#define WNI_CFG_MIMO_ENABLED_STAMIN 0 +#define WNI_CFG_MIMO_ENABLED_STAMAX 1 +#define WNI_CFG_MIMO_ENABLED_STADEF 1 + +#define WNI_CFG_MIMO_ENABLED_ENABLE 1 +#define WNI_CFG_MIMO_ENABLED_DISABLE 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_STAMIN 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_STAMAX 3 +#define WNI_CFG_BLOCK_ACK_ENABLED_STADEF 0 + +#define WNI_CFG_BLOCK_ACK_ENABLED_DELAYED 0 +#define WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE 1 + +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMIN 0 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMAX 65535 +#define WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STADEF 1000 + +#define WNI_CFG_HT_RX_STBC_STAMIN 0 +#define WNI_CFG_HT_RX_STBC_STAMAX 3 +#define WNI_CFG_HT_RX_STBC_STADEF 1 + +#define WNI_CFG_HT_CAP_INFO_STAMIN 0 +#define WNI_CFG_HT_CAP_INFO_STAMAX 65535 +#define WNI_CFG_HT_CAP_INFO_STADEF 364 + +#define WNI_CFG_HT_CAP_INFO_ADVANCE_CODING 0 +#define WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET 1 +#define WNI_CFG_HT_CAP_INFO_SM_POWER_SAVE 2 +#define WNI_CFG_HT_CAP_INFO_GREEN_FIELD 4 +#define WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ 5 +#define WNI_CFG_HT_CAP_INFO_SHORT_GI_40MHZ 6 +#define WNI_CFG_HT_CAP_INFO_TX_STBC 7 +#define WNI_CFG_HT_CAP_INFO_RX_STBC 8 +#define WNI_CFG_HT_CAP_INFO_DELAYED_BA 10 +#define WNI_CFG_HT_CAP_INFO_MAX_AMSDU_SIZE 11 +#define WNI_CFG_HT_CAP_INFO_DSSS_CCK_MODE_40MHZ 12 +#define WNI_CFG_HT_CAP_INFO_PSMP 13 +#define WNI_CFG_HT_CAP_INFO_STBC_CONTROL_FRAME 14 +#define WNI_CFG_HT_CAP_INFO_LSIG_TXOP_PROTECTION 15 + +#define WNI_CFG_HT_AMPDU_PARAMS_STAMIN 0 +#define WNI_CFG_HT_AMPDU_PARAMS_STAMAX 255 +#define WNI_CFG_HT_AMPDU_PARAMS_STADEF 0 + +#define WNI_CFG_HT_AMPDU_PARAMS_MAX_RX_AMPDU_FACTOR 0 +#define WNI_CFG_HT_AMPDU_PARAMS_MPDU_DENSITY 2 +#define WNI_CFG_HT_AMPDU_PARAMS_RESERVED 5 + +#define WNI_CFG_EXT_HT_CAP_INFO_STAMIN 0 +#define WNI_CFG_EXT_HT_CAP_INFO_STAMAX 65535 +#define WNI_CFG_EXT_HT_CAP_INFO_STADEF 1024 + +#define WNI_CFG_EXT_HT_CAP_INFO_PCO 0 +#define WNI_CFG_EXT_HT_CAP_INFO_TRANSITION_TIME 1 +#define WNI_CFG_EXT_HT_CAP_INFO_RESERVED1 3 +#define WNI_CFG_EXT_HT_CAP_INFO_MCS_FEEDBACK 8 +#define WNI_CFG_EXT_HT_CAP_INFO_HTC_SUPPORT 10 +#define WNI_CFG_EXT_HT_CAP_INFO_RD_RESPONDER 11 +#define WNI_CFG_EXT_HT_CAP_INFO_RESERVED2 12 + +#define WNI_CFG_TX_BF_CAP_STAMIN 0 +#define WNI_CFG_TX_BF_CAP_STAMAX 4294967295 +#define WNI_CFG_TX_BF_CAP_STADEF 0 + +#define WNI_CFG_AS_CAP_STAMIN 0 +#define WNI_CFG_AS_CAP_STAMAX 255 +#define WNI_CFG_AS_CAP_STADEF 0 + +#define WNI_CFG_AS_CAP_ANTENNA_SELECTION 0 +#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK_TX 1 +#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK_TX 2 +#define WNI_CFG_AS_CAP_EXPLICIT_CSI_FEEDBACK 3 +#define WNI_CFG_AS_CAP_ANTENNA_INDICES_FEEDBACK 4 +#define WNI_CFG_AS_CAP_RX_AS 5 +#define WNI_CFG_AS_CAP_TX_SOUNDING_PPDUS 6 +#define WNI_CFG_AS_CAP_RESERVED 7 + +#define WNI_CFG_HT_INFO_FIELD1_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD1_STAMAX 255 +#define WNI_CFG_HT_INFO_FIELD1_STADEF 15 + +#define WNI_CFG_HT_INFO_FIELD1_SECONDARY_CHANNEL_OFFSET 0 +#define WNI_CFG_HT_INFO_FIELD1_RECOMMENDED_CHANNEL_WIDTH 2 +#define WNI_CFG_HT_INFO_FIELD1_RIFS_MODE 3 +#define WNI_CFG_HT_INFO_FIELD1_PSMP_ACCESS_ONLY 4 +#define WNI_CFG_HT_INFO_FIELD1_SERVICE_INTERVAL_GRANULARITY 5 + +#define WNI_CFG_HT_INFO_FIELD2_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD2_STAMAX 65535 +#define WNI_CFG_HT_INFO_FIELD2_STADEF 0 + +#define WNI_CFG_HT_INFO_FIELD2_OP_MODE 0 +#define WNI_CFG_HT_INFO_FIELD2_NON_GF_DEVICES_PRESENT 2 +#define WNI_CFG_HT_INFO_FIELD2_RESERVED 3 + +#define WNI_CFG_HT_INFO_FIELD3_STAMIN 0 +#define WNI_CFG_HT_INFO_FIELD3_STAMAX 65535 +#define WNI_CFG_HT_INFO_FIELD3_STADEF 0 + +#define WNI_CFG_HT_INFO_FIELD3_BASIC_STBC_MCS 0 +#define WNI_CFG_HT_INFO_FIELD3_DUAL_STBC_PROTECTION 7 +#define WNI_CFG_HT_INFO_FIELD3_SECONDARY_BEACON 8 +#define WNI_CFG_HT_INFO_FIELD3_LSIG_TXOP_PROTECTION_FULL_SUPPORT 9 +#define WNI_CFG_HT_INFO_FIELD3_PCO_ACTIVE 10 +#define WNI_CFG_HT_INFO_FIELD3_PCO_PHASE 11 +#define WNI_CFG_HT_INFO_FIELD3_RESERVED 12 + +#define WNI_CFG_GREENFIELD_CAPABILITY_STAMIN 0 +#define WNI_CFG_GREENFIELD_CAPABILITY_STAMAX 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_STADEF 0 + +#define WNI_CFG_GREENFIELD_CAPABILITY_ENABLE 1 +#define WNI_CFG_GREENFIELD_CAPABILITY_DISABLE 0 + +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMIN 0 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMAX 2 +#define WNI_CFG_VHT_MAX_MPDU_LENGTH_STADEF 0 + +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMIN 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMAX 0 +#define WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STADEF 0 + +#define WNI_CFG_VHT_LDPC_CODING_CAP_STAMIN 0 +#define WNI_CFG_VHT_LDPC_CODING_CAP_STAMAX 1 +#define WNI_CFG_VHT_LDPC_CODING_CAP_STADEF 0 + +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STAMIN 0 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STAMAX 1 +#define WNI_CFG_VHT_SHORT_GI_80MHZ_STADEF 1 + +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMIN 0 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMAX 1 +#define WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STADEF 0 + +#define WNI_CFG_VHT_TXSTBC_STAMIN 0 +#define WNI_CFG_VHT_TXSTBC_STAMAX 1 +#define WNI_CFG_VHT_TXSTBC_STADEF 0 + +#define WNI_CFG_VHT_RXSTBC_STAMIN 0 +#define WNI_CFG_VHT_RXSTBC_STAMAX 1 +#define WNI_CFG_VHT_RXSTBC_STADEF 1 + +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMER_CAP_STADEF 0 + +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN 0 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX 1 +#define WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF 1 + +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN 0 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX 4 +#define WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STADEF 0 + +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMIN 0 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMAX 3 +#define WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STADEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMER_CAP_STADEF 0 + +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMIN 0 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMAX 1 +#define WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STADEF 0 + +#define WNI_CFG_VHT_TXOP_PS_STAMIN 0 +#define WNI_CFG_VHT_TXOP_PS_STAMAX 1 +#define WNI_CFG_VHT_TXOP_PS_STADEF 0 + +#define WNI_CFG_VHT_HTC_VHTC_CAP_STAMIN 0 +#define WNI_CFG_VHT_HTC_VHTC_CAP_STAMAX 1 +#define WNI_CFG_VHT_HTC_VHTC_CAP_STADEF 0 + +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMIN 0 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMAX 7 +#define WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STADEF 3 + +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMIN 0 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMAX 3 +#define WNI_CFG_VHT_LINK_ADAPTATION_CAP_STADEF 0 + +#define WNI_CFG_VHT_RX_ANT_PATTERN_STAMIN 0 +#define WNI_CFG_VHT_RX_ANT_PATTERN_STAMAX 1 +#define WNI_CFG_VHT_RX_ANT_PATTERN_STADEF 1 + +#define WNI_CFG_VHT_TX_ANT_PATTERN_STAMIN 0 +#define WNI_CFG_VHT_TX_ANT_PATTERN_STAMAX 1 +#define WNI_CFG_VHT_TX_ANT_PATTERN_STADEF 1 + +#define WNI_CFG_VHT_RX_MCS_MAP_STAMIN 0 +#define WNI_CFG_VHT_RX_MCS_MAP_STAMAX 65535 +#define WNI_CFG_VHT_RX_MCS_MAP_STADEF 65534 + +#define WNI_CFG_VHT_TX_MCS_MAP_STAMIN 0 +#define WNI_CFG_VHT_TX_MCS_MAP_STAMAX 65535 +#define WNI_CFG_VHT_TX_MCS_MAP_STADEF 65534 + +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN 0 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX 390 +#define WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STADEF 0 + +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN 0 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX 390 +#define WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_STAMAX 3 +#define WNI_CFG_VHT_CHANNEL_WIDTH_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ 0 +#define WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ 1 +#define WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ 2 +#define WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ 3 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMAX 256 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STADEF 0 + +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMIN 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMAX 0 +#define WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STADEF 0 + +#define WNI_CFG_VHT_BASIC_MCS_SET_STAMIN 0 +#define WNI_CFG_VHT_BASIC_MCS_SET_STAMAX 65535 +#define WNI_CFG_VHT_BASIC_MCS_SET_STADEF 65534 + +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMIN 0 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMAX 4 +#define WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STADEF 0 + +#define WNI_CFG_VHT_SS_UNDER_UTIL_STAMIN 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_STAMAX 0 +#define WNI_CFG_VHT_SS_UNDER_UTIL_STADEF 0 + +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_40MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STAMIN 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STAMAX 0 +#define WNI_CFG_VHT_160MHZ_UTILIZATION_STADEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_STAMIN 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_STAMAX 1 +#define WNI_CFG_MAX_AMSDU_LENGTH_STADEF 0 + +#define WNI_CFG_MAX_AMSDU_LENGTH_SHORT_3839_BYTES 0 +#define WNI_CFG_MAX_AMSDU_LENGTH_LONG_7935__BYTES 1 + +#define WNI_CFG_MPDU_DENSITY_STAMIN 0 +#define WNI_CFG_MPDU_DENSITY_STAMAX 7 +#define WNI_CFG_MPDU_DENSITY_STADEF 0 + +#define WNI_CFG_NUM_BUFF_ADVERT_STAMIN 0 +#define WNI_CFG_NUM_BUFF_ADVERT_STAMAX 128 +#define WNI_CFG_NUM_BUFF_ADVERT_STADEF 64 + +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN 0 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX 3 +#define WNI_CFG_MAX_RX_AMPDU_FACTOR_STADEF 3 + +#define WNI_CFG_SHORT_GI_20MHZ_STAMIN 0 +#define WNI_CFG_SHORT_GI_20MHZ_STAMAX 1 +#define WNI_CFG_SHORT_GI_20MHZ_STADEF 1 + +#define WNI_CFG_SHORT_GI_20MHZ_ENABLE 1 +#define WNI_CFG_SHORT_GI_20MHZ_DISABLE 0 + +#define WNI_CFG_SHORT_GI_40MHZ_STAMIN 0 +#define WNI_CFG_SHORT_GI_40MHZ_STAMAX 1 +#define WNI_CFG_SHORT_GI_40MHZ_STADEF 0 + +#define WNI_CFG_SHORT_GI_40MHZ_ENABLE 1 +#define WNI_CFG_SHORT_GI_40MHZ_DISABLE 0 + +#define WNI_CFG_RIFS_ENABLED_STAMIN 0 +#define WNI_CFG_RIFS_ENABLED_STAMAX 1 +#define WNI_CFG_RIFS_ENABLED_STADEF 1 + +#define WNI_CFG_RIFS_ENABLED_ENABLE 1 +#define WNI_CFG_RIFS_ENABLED_DISABLE 0 + +#define WNI_CFG_MAX_PS_POLL_STAMIN 0 +#define WNI_CFG_MAX_PS_POLL_STAMAX 255 +#define WNI_CFG_MAX_PS_POLL_STADEF 0 + +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +#define WNI_CFG_RSSI_FILTER_PERIOD_STAMIN 0 +#define WNI_CFG_RSSI_FILTER_PERIOD_STAMAX 255 +#define WNI_CFG_RSSI_FILTER_PERIOD_STADEF 5 + +#define WNI_CFG_MIN_RSSI_THRESHOLD_STAMIN 0 +#define WNI_CFG_MIN_RSSI_THRESHOLD_STAMAX 10 +#define WNI_CFG_MIN_RSSI_THRESHOLD_STADEF 10 + +#define WNI_CFG_NTH_BEACON_FILTER_STAMIN 0 +#define WNI_CFG_NTH_BEACON_FILTER_STAMAX 255 +#define WNI_CFG_NTH_BEACON_FILTER_STADEF 10 + +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STADEF 0 + +#define WNI_CFG_SCAN_IN_POWERSAVE_STAMIN 0 +#define WNI_CFG_SCAN_IN_POWERSAVE_STAMAX 1 +#define WNI_CFG_SCAN_IN_POWERSAVE_STADEF 1 + +#define WNI_CFG_IGNORE_DTIM_STAMIN 0 +#define WNI_CFG_IGNORE_DTIM_STAMAX 1 +#define WNI_CFG_IGNORE_DTIM_STADEF 0 + +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_DEAUTH_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMIN 0 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMAX 1 +#define WNI_CFG_WOWLAN_DISASSOC_ENABLE_STADEF 1 + +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMIN 0 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMAX 65535 +#define WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STADEF 40 + +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMIN 0 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMAX 65535 +#define WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STADEF 65535 + +#define WNI_CFG_BA_TIMEOUT_STAMIN 0 +#define WNI_CFG_BA_TIMEOUT_STAMAX 65535 +#define WNI_CFG_BA_TIMEOUT_STADEF 0 + +#define WNI_CFG_BA_THRESHOLD_HIGH_STAMIN 0 +#define WNI_CFG_BA_THRESHOLD_HIGH_STAMAX 65535 +#define WNI_CFG_BA_THRESHOLD_HIGH_STADEF 128 + +#define WNI_CFG_MAX_BA_BUFFERS_STAMIN 0 +#define WNI_CFG_MAX_BA_BUFFERS_STAMAX 2560 +#define WNI_CFG_MAX_BA_BUFFERS_STADEF 2560 + +#define WNI_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define WNI_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define WNI_CFG_MAX_BA_SESSIONS_STADEF 40 + +#define WNI_CFG_BA_AUTO_SETUP_STAMIN 0 +#define WNI_CFG_BA_AUTO_SETUP_STAMAX 1 +#define WNI_CFG_BA_AUTO_SETUP_STADEF 1 + +#define WNI_CFG_BA_AUTO_SETUP_ENABLE 1 +#define WNI_CFG_BA_AUTO_SETUP_DISABLE 0 + +#define WNI_CFG_ADDBA_REQ_DECLINE_STAMIN 0 +#define WNI_CFG_ADDBA_REQ_DECLINE_STAMAX 255 +#define WNI_CFG_ADDBA_REQ_DECLINE_STADEF 0 + +#define WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC_STAMIN 0 +#define WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC_STAMAX 1 +#define WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC_STADEF 0 + +#define WNI_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define WNI_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define WNI_CFG_MAX_MEDIUM_TIME_STADEF 2048 + +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define WNI_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +#define WNI_CFG_IBSS_AUTO_BSSID_STAMIN 0 +#define WNI_CFG_IBSS_AUTO_BSSID_STAMAX 1 +#define WNI_CFG_IBSS_AUTO_BSSID_STADEF 1 + +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STADEF 0 + +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMIN 0 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMAX 1 +#define WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STADEF 0 + +#define WNI_CFG_WPS_ENABLE_STAMIN 0 +#define WNI_CFG_WPS_ENABLE_STAMAX 255 +#define WNI_CFG_WPS_ENABLE_STADEF 0 + +#define WNI_CFG_WPS_ENABLE_AP 1 +#define WNI_CFG_WPS_ENABLE_STA 2 + +#define WNI_CFG_WPS_STATE_STAMIN 0 +#define WNI_CFG_WPS_STATE_STAMAX 255 +#define WNI_CFG_WPS_STATE_STADEF 1 + +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STAMIN 0 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STAMAX 1 +#define WNI_CFG_WPS_PROBE_REQ_FLAG_STADEF 0 + +#define WNI_CFG_WPS_VERSION_STAMIN 0 +#define WNI_CFG_WPS_VERSION_STAMAX 255 +#define WNI_CFG_WPS_VERSION_STADEF 16 + +#define WNI_CFG_WPS_REQUEST_TYPE_STAMIN 0 +#define WNI_CFG_WPS_REQUEST_TYPE_STAMAX 255 +#define WNI_CFG_WPS_REQUEST_TYPE_STADEF 0 + +#define WNI_CFG_WPS_CFG_METHOD_STAMIN 0 +#define WNI_CFG_WPS_CFG_METHOD_STAMAX 4294967295 +#define WNI_CFG_WPS_CFG_METHOD_STADEF 8 + +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMIN 0 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMAX 65535 +#define WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STADEF 1 + +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMIN 0 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMAX 4294967295 +#define WNI_CFG_WPS_PIMARY_DEVICE_OUI_STADEF 5304836 + +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMIN 0 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMAX 65535 +#define WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STADEF 1 + +#define WNI_CFG_WPS_ASSOCIATION_STATE_STAMIN 0 +#define WNI_CFG_WPS_ASSOCIATION_STATE_STAMAX 65535 +#define WNI_CFG_WPS_ASSOCIATION_STATE_STADEF 0 + +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STAMIN 0 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STAMAX 65535 +#define WNI_CFG_WPS_CONFIGURATION_ERROR_STADEF 0 + +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMIN 0 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMAX 4294967295 +#define WNI_CFG_WPS_DEVICE_PASSWORD_ID_STADEF 0 + +#define WNI_CFG_WPS_ASSOC_METHOD_STAMIN 0 +#define WNI_CFG_WPS_ASSOC_METHOD_STAMAX 65535 +#define WNI_CFG_WPS_ASSOC_METHOD_STADEF 0 + +#define WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define WNI_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMIN 0 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMAX 128 +#define WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STADEF 128 + +#define WNI_CFG_RPE_POLLING_THRESHOLD_STAMIN 0 +#define WNI_CFG_RPE_POLLING_THRESHOLD_STAMAX 65535 +#define WNI_CFG_RPE_POLLING_THRESHOLD_STADEF 10 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF 30 + +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN 0 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX 65535 +#define WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF 30 + +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN 0 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX 2 +#define WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF 1 + +#define WNI_CFG_SINGLE_TID_RC_STAMIN 0 +#define WNI_CFG_SINGLE_TID_RC_STAMAX 1 +#define WNI_CFG_SINGLE_TID_RC_STADEF 1 + +#define WNI_CFG_RRM_ENABLED_STAMIN 0 +#define WNI_CFG_RRM_ENABLED_STAMAX 1 +#define WNI_CFG_RRM_ENABLED_STADEF 0 + +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMIN 0 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMAX 8 +#define WNI_CFG_RRM_OPERATING_CHAN_MAX_STADEF 0 + +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMIN 0 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMAX 8 +#define WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STADEF 0 + +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STAMIN 0 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STAMAX 1 +#define WNI_CFG_TX_PWR_CTRL_ENABLE_STADEF 1 + +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN 0 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX 3 +#define WNI_CFG_MCAST_BCAST_FILTER_SETTING_STADEF 0 + +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMIN 0 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMAX 255 +#define WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STADEF 0 + +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN 0 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX 255 +#define WNI_CFG_DYNAMIC_PS_POLL_VALUE_STADEF 0 + +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN 0 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX 80 +#define WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF 0 + +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN 0 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX 1 +#define WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF 0 + +#define WNI_CFG_TELE_BCN_TRANS_LI_STAMIN 0 +#define WNI_CFG_TELE_BCN_TRANS_LI_STAMAX 7 +#define WNI_CFG_TELE_BCN_TRANS_LI_STADEF 3 + +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN 5 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX 255 +#define WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF 10 + +#define WNI_CFG_TELE_BCN_MAX_LI_STAMIN 0 +#define WNI_CFG_TELE_BCN_MAX_LI_STAMAX 7 +#define WNI_CFG_TELE_BCN_MAX_LI_STADEF 5 + +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN 5 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX 255 +#define WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF 15 + +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMIN 0 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMAX 255 +#define WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STADEF 7 + +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN 0 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX 65535 +#define WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF 0 + +#define WNI_CFG_ASSOC_STA_LIMIT_STAMIN 1 +#define WNI_CFG_ASSOC_STA_LIMIT_STAMAX 32 +#define WNI_CFG_ASSOC_STA_LIMIT_STADEF 10 + +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STADEF 1 + +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN 1 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX 252 +#define WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STADEF 11 + +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN 0 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX 5 +#define WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STADEF 0 + +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN 0 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX 65535 +#define WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF 5 + +#define WNI_CFG_ENABLE_CLOSE_LOOP_STAMIN 0 +#define WNI_CFG_ENABLE_CLOSE_LOOP_STAMAX 1 +#define WNI_CFG_ENABLE_CLOSE_LOOP_STADEF 0 + +#define WNI_CFG_ENABLE_LTE_COEX_STAMIN 0 +#define WNI_CFG_ENABLE_LTE_COEX_STAMAX 1 +#define WNI_CFG_ENABLE_LTE_COEX_STADEF 0 + +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMIN 1 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMAX 255 +#define WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STADEF 20 + +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMIN 1 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMAX 255 +#define WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STADEF 20 + +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STAMIN 0 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STAMAX 1 +#define WNI_CFG_ENABLE_MC_ADDR_LIST_STADEF 0 + +#define WNI_CFG_ENABLE_UC_FILTER_STAMIN 0 +#define WNI_CFG_ENABLE_UC_FILTER_STAMAX 1 +#define WNI_CFG_ENABLE_UC_FILTER_STADEF 0 + +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMIN 0 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMAX 1 +#define WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STADEF 0 + +#define WNI_CFG_ENABLE_CONC_BMISS_STAMIN 2 +#define WNI_CFG_ENABLE_CONC_BMISS_STAMAX 10 +#define WNI_CFG_ENABLE_CONC_BMISS_STADEF 5 + +#define WNI_CFG_ENABLE_UNITS_BWAIT_STAMIN 2 +#define WNI_CFG_ENABLE_UNITS_BWAIT_STAMAX 10 +#define WNI_CFG_ENABLE_UNITS_BWAIT_STADEF 2 + +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN 0 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX 1 +#define WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF 0 + +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN 0 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX 1 +#define WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF 0 + +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMIN 1 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMAX 255 +#define WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STADEF 3 + +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMIN 0 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMAX 15 +#define WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STADEF 0 + +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_BUF_STA_ENABLED_STADEF 0 + +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMIN 0 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMAX 10 +#define WNI_CFG_TDLS_PUAPSD_INACT_TIME_STADEF 0 + +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMIN 10 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMAX 20 +#define WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STADEF 10 + +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN 0 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX 1 +#define WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF 1 + +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMIN 0 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMAX 9 +#define WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STADEF 0 + +#define WNI_CFG_ANTENNA_DIVESITY_STAMIN 0 +#define WNI_CFG_ANTENNA_DIVESITY_STAMAX 3 +#define WNI_CFG_ANTENNA_DIVESITY_STADEF 0 + +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMIN 3 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX 50 +#define WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF 10 + +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN 100 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX 1000 +#define WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF 300 + +#define WNI_CFG_ATH_DISABLE_STAMIN 0 +#define WNI_CFG_ATH_DISABLE_STAMAX 1 +#define WNI_CFG_ATH_DISABLE_STADEF 0 + +#define WNI_CFG_BTC_ACTIVE_WLAN_LEN_STAMIN 0 +#define WNI_CFG_BTC_ACTIVE_WLAN_LEN_STAMAX 250000 +#define WNI_CFG_BTC_ACTIVE_WLAN_LEN_STADEF 60000 + +#define WNI_CFG_BTC_ACTIVE_BT_LEN_STAMIN 0 +#define WNI_CFG_BTC_ACTIVE_BT_LEN_STAMAX 250000 +#define WNI_CFG_BTC_ACTIVE_BT_LEN_STADEF 90000 + +#define WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN_STAMIN 0 +#define WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN_STAMAX 250000 +#define WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN_STADEF 30000 + +#define WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMIN 0 +#define WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMAX 250000 +#define WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STADEF 30000 + +#define WNI_CFG_ASD_PROBE_INTERVAL_STAMIN 1 +#define WNI_CFG_ASD_PROBE_INTERVAL_STAMAX 500 +#define WNI_CFG_ASD_PROBE_INTERVAL_STADEF 50 + +#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMIN -100 +#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMAX -10 +#define WNI_CFG_ASD_TRIGGER_THRESHOLD_STADEF -60 + +#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMIN 0 +#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMAX 5 +#define WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STADEF 3 + +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMIN 0 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMAX 1 +#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STADEF 0 + +#define WNI_CFG_BTC_CTS2S_DURING_SCO_STAMIN 0 +#define WNI_CFG_BTC_CTS2S_DURING_SCO_STAMAX 1 +#define WNI_CFG_BTC_CTS2S_DURING_SCO_STADEF 0 + +#define WNI_CFG_CHANNEL_BONDING_24G_STAMIN 0 +#define WNI_CFG_CHANNEL_BONDING_24G_STAMAX 1 +#define WNI_CFG_CHANNEL_BONDING_24G_STADEF 0 + +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN 5 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX 1000 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STADEF 20 + +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN 10 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX 1000 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STADEF 10 + +#define WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN 10 +#define WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX 900 +#define WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STADEF 200 + +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN 200 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX 10000 +#define WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STADEF 200 + +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN 20 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX 10000 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STADEF 20 + +#define WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STAMIN 5 +#define WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STAMAX 100 +#define WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STADEF 5 + +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN 0 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX 100 +#define WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STADEF 25 + +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STADEF 0 + +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMIN 0 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMAX 20 +#define WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STADEF 5 + +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN 10 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMAX 2000 +#define WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF 200 + +#define WNI_CFG_RA_FILTER_ENABLE_STAMIN 0 +#define WNI_CFG_RA_FILTER_ENABLE_STAMAX 1 +#define WNI_CFG_RA_FILTER_ENABLE_STADEF 0 + +#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMIN 0 +#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMAX 3600 +#define WNI_CFG_RA_RATE_LIMIT_INTERVAL_STADEF 60 + +#define WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STAMIN 0 +#define WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STAMAX 2 +#define WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STADEF 2 + +#define WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_STAMIN 0 +#define WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_STAMAX 1 +#define WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_STADEF 1 + +#define WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_STAMIN 0 +#define WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_STAMAX 1 +#define WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_STADEF 0 + +#define WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_STAMIN 0 +#define WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_STAMAX 3 +#define WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_STADEF 1 + +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMIN 0 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX 1 +#define WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF 0 + +#define WNI_CFG_MAX_UAPSD_CONSEC_SP_STAMIN 0 +#define WNI_CFG_MAX_UAPSD_CONSEC_SP_STAMAX 500 +#define WNI_CFG_MAX_UAPSD_CONSEC_SP_STADEF 10 + +#define WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_STAMIN 0 +#define WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_STAMAX 5000 +#define WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_STADEF 50 + +#define WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_STAMIN 0 +#define WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_STAMAX 5000 +#define WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_STADEF 50 + +#define WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_STAMIN 50 +#define WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_STAMAX 50000 +#define WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_STADEF 500 + +#define WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_STAMIN 50 +#define WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_STAMAX 50000 +#define WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_STADEF 500 + +#define WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_STAMIN 0 +#define WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_STAMAX 255 +#define WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_STADEF 0 + +#define WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_STAMIN 1 +#define WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_STAMAX 255 +#define WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_STADEF 10 + +#define WNI_CFG_ENABLE_DYNAMIC_WMMPS_STAMIN 0 +#define WNI_CFG_ENABLE_DYNAMIC_WMMPS_STAMAX 1 +#define WNI_CFG_ENABLE_DYNAMIC_WMMPS_STADEF 1 + +#define WNI_CFG_BURST_MODE_BE_TXOP_VALUE_STAMIN 0 +#define WNI_CFG_BURST_MODE_BE_TXOP_VALUE_STAMAX 12288 +#define WNI_CFG_BURST_MODE_BE_TXOP_VALUE_STADEF 0 + +#define WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE_STAMIN 0 +#define WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE_STAMAX 65535 +#define WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE_STADEF 0 + +#define WNI_CFG_BTC_FAST_WLAN_CONN_PREF_STAMIN 0 +#define WNI_CFG_BTC_FAST_WLAN_CONN_PREF_STAMAX 5 +#define WNI_CFG_BTC_FAST_WLAN_CONN_PREF_STADEF 1 + +/* Bit mask value to enable RTS/CTS for different modes + * for 2.4 GHz, HT20 - 0x0001, for 2.4 GHz, HT40 - 0x0002 + * for 2.4 GHz, VHT20 - 0x0004, for 2.4 GHz, VHT40 - 0x0008 + * for 5 GHz, HT20 - 0x0100, for 5 GHz, HT40 - 0x0200 + * for 5 GHz, VHT20 - 0x0400, for 5 GHz, VHT40 - 0x0800 + * for 5 GHz, VHT80 - 0x1000 + */ +#define WNI_CFG_ENABLE_RTSCTS_HTVHT_MIN 0x0000 +#define WNI_CFG_ENABLE_RTSCTS_HTVHT_MAX 0x1f0f +#define WNI_CFG_ENABLE_RTSCTS_HTVHT_DEF 0x0000 + +#define WNI_CFG_TOGGLE_ARP_BDRATES_MIN 0 +#define WNI_CFG_TOGGLE_ARP_BDRATES_MAX 2 +#define WNI_CFG_TOGGLE_ARP_BDRATES_DEF 0 + +#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MIN 0 +#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MAX 250000 +#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_DEF 40000 + +#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MIN 0 +#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX 250000 +#define WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEF 40000 + +#define WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN 0 +#define WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX 1 +#define WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEF 0 + +#define WNI_CFG_LINK_FAIL_TIMEOUT_MIN 1000 +#define WNI_CFG_LINK_FAIL_TIMEOUT_MAX 60000 +#define WNI_CFG_LINK_FAIL_TIMEOUT_DEF 6000 + +#define WNI_CFG_LINK_FAIL_TX_CNT_MIN 50 +#define WNI_CFG_LINK_FAIL_TX_CNT_MAX 1000 +#define WNI_CFG_LINK_FAIL_TX_CNT_DEF 200 + +#define WNI_CFG_OPTIMIZE_CA_EVENT_DISABLE 0 +#define WNI_CFG_OPTIMIZE_CA_EVENT_ENABLE 1 +#define WNI_CFG_OPTIMIZE_CA_EVENT_DEFAULT 0 + +#define WNI_CFG_ACTIVE_PASSIVE_CON_MIN 0 +#define WNI_CFG_ACTIVE_PASSIVE_CON_MAX 1 +#define WNI_CFG_ACTIVE_PASSIVE_CON_DEF 1 + +#define WNI_CFG_EXT_SCAN_CONC_MODE_MIN 0 +#define WNI_CFG_EXT_SCAN_CONC_MODE_MAX 2 +#define WNI_CFG_EXT_SCAN_CONC_MODE_DEF 1 + +#define WNI_CFG_ENABLE_MAC_ADDR_SPOOFING_MIN 0 +#define WNI_CFG_ENABLE_MAC_ADDR_SPOOFING_MAX 2 +#define WNI_CFG_ENABLE_MAC_ADDR_SPOOFING_DEF 1 + +#define WNI_CFG_DISABLE_BAR_WAKE_UP_HOST_MIN 0 +#define WNI_CFG_DISABLE_BAR_WAKE_UP_HOST_MAX 1 +#define WNI_CFG_DISABLE_BAR_WAKE_UP_HOST_DEF 0 + +#define WNI_CFG_SAR_BOFFSET_SET_CORRECTION_MIN 0 +#define WNI_CFG_SAR_BOFFSET_SET_CORRECTION_MAX 1 +#define WNI_CFG_SAR_BOFFSET_SET_CORRECTION_DEFAULT 0 + +#define WNI_CFG_DISABLE_SCAN_DURING_SCO_MIN 0 +#define WNI_CFG_DISABLE_SCAN_DURING_SCO_MAX 1 +#define WNI_CFG_DISABLE_SCAN_DURING_SCO_DEF 0 + +#define WNI_CFG_ENABLE_TX_RX_AGGREGATION_MIN 0 +#define WNI_CFG_ENABLE_TX_RX_AGGREGATION_MAX 1 +#define WNI_CFG_ENABLE_TX_RX_AGGREGATION_DEF 1 + +#define WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN 0 +#define WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX 1 +#define WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEF 0 + +#define CFG_PARAM_MAX_NUM 364 +#define CFG_STA_IBUF_MAX_SIZE 298 +#define CFG_STA_SBUF_MAX_SIZE 3389 + +#define CFG_STA_MAGIC_DWORD 0xbeefbeef + + +#endif diff --git a/drivers/staging/prima/CORE/MAC/inc/wniStat.h b/drivers/staging/prima/CORE/MAC/inc/wniStat.h new file mode 100644 index 000000000000..2ab4924b937b --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/inc/wniStat.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file wniStat.h contains statistics related definitions + * exported by Sirius software modules. + * + * Author: Kevin Nguyen + * Date: 08/21/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef _WNISTAT_H +#define _WNISTAT_H + + +// WNI Statistic Parameter ID +#define WNI_STAT_RTS_SUCC_CNT 1 +#define WNI_STAT_RTS_FAILED_CNT 2 +#define WNI_STAT_PACKET_CNT 3 +#define WNI_STAT_MULTI_CNT 4 +#define WNI_STAT_DUPL_FRAG_CNT 5 +#define WNI_STAT_TOTAL_BYTE_CNT 6 +#define WNI_STAT_PKT_DROP_CNT 7 +#define WNI_STAT_PKT64_CNT 8 +#define WNI_STAT_PKT127_CNT 9 +#define WNI_STAT_PKT255_CNT 10 +#define WNI_STAT_PKT511_CNT 11 +#define WNI_STAT_PKT1023_CNT 12 +#define WNI_STAT_PKT1518_CNT 13 +#define WNI_STAT_PKT2047_CNT 14 +#define WNI_STAT_PKT4095_CNT 15 +#define WNI_STAT_FRAG_CNT 16 +#define WNI_STAT_FCS_CNT 17 +#define WNI_STAT_BSSID_MISS_CNT 18 +#define WNI_STAT_PDU_ERR_CNT 19 +#define WNI_STAT_DST_MISS_CNT 20 +#define WNI_STAT_DROP_CNT 21 +#define WNI_STAT_ABORT_CNT 22 +#define WNI_STAT_RELAY_CNT 23 +#define WNI_STAT_HASH_MISS_CNT 24 +#define WNI_STAT_PLCP_CRC_ERR_CNT 25 +#define WNI_STAT_PLCP_SIG_ERR_CNT 26 +#define WNI_STAT_PLCP_SVC_ERR_CNT 27 +#define WNI_STAT_BEACONS_RECEIVED_CNT 28 +#define WNI_STAT_BEACONS_TRANSMITTED_CNT 29 +#define WNI_STAT_CURRENT_TX_RATE 30 + +#define WNI_STAT_LAST_ID WNI_STAT_CURRENT_TX_RATE + + +#endif + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c new file mode 100644 index 000000000000..b4c260b96b9e --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgApi.c @@ -0,0 +1,1198 @@ +/* + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file contains the source code for CFG API functions. + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ + +#include "palTypes.h" +#include "cfgPriv.h" +#include "cfgDebug.h" +#include "wlan_qct_wda.h" + +//--------------------------------------------------------------------- +// Static Variables +//---------------------------------------------------------------------- +static tCfgCtl __gCfgEntry[CFG_PARAM_MAX_NUM] ; +static tANI_U32 __gCfgIBufMin[CFG_STA_IBUF_MAX_SIZE] ; +static tANI_U32 __gCfgIBufMax[CFG_STA_IBUF_MAX_SIZE] ; +static tANI_U32 __gCfgIBuf[CFG_STA_IBUF_MAX_SIZE] ; +static tANI_U8 __gCfgSBuf[CFG_STA_SBUF_MAX_SIZE] ; +static tANI_U8 __gSBuffer[CFG_MAX_STR_LEN] ; + + +static void Notify(tpAniSirGlobal, tANI_U16, tANI_U32); + +extern tAniSirCfgStaticString cfgStaticString[CFG_MAX_STATIC_STRING]; +extern tAniSirCgStatic cfgStatic[CFG_PARAM_MAX_NUM] ; +//--------------------------------------------------------------------- +tANI_U32 cfgNeedRestart(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return 0; + } + return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RESTART) ; +} + +// --------------------------------------------------------------------- +tANI_U32 cfgNeedReload(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return 0; + } + return !!(pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_RELOAD) ; +} + +// --------------------------------------------------------------------- +/** + * wlan_cfgInit() + * + * FUNCTION: + * CFG initialization function. + * + * LOGIC: + * Please see Configuration & Statistic Collection Micro-Architecture + * specification for the pseudocode. + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * This function must be called during system initialization. + * + * @param None + * @return None. + */ + +void +wlan_cfgInit(tpAniSirGlobal pMac) +{ + // Set status to not-ready + pMac->cfg.gCfgStatus = CFG_INCOMPLETE; + + // Send CFG_DNLD_REQ to host + PELOGW(cfgLog(pMac, LOGW, FL("Sending CFG_DNLD_REQ"));) + cfgSendHostMsg(pMac, WNI_CFG_DNLD_REQ, WNI_CFG_DNLD_REQ_LEN, + WNI_CFG_DNLD_REQ_NUM, 0, 0, 0); + +} /*** end wlan_cfgInit() ***/ + +void cfgGetStrIndex(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + tANI_U16 i = 0; + + for(i = 0; i < CFG_MAX_STATIC_STRING; i++) + { + if(cfgId == cfgStaticString[i].cfgId) + break; + } + if(i == CFG_MAX_STATIC_STRING) + { + PELOGE(cfgLog(pMac, LOGE, FL("Entry not found for cfg id :%d"), cfgId);) + cfgStatic[cfgId].pStrData = NULL; + return; + } + cfgStatic[cfgId].pStrData = &cfgStaticString[i]; +} + +//--------------------------------------------------------------------- +tSirRetStatus cfgInit(tpAniSirGlobal pMac) +{ + tANI_U16 i = 0; + pMac->cfg.gCfgIBufMin = __gCfgIBufMin; + pMac->cfg.gCfgIBufMax = __gCfgIBufMax; + pMac->cfg.gCfgIBuf = __gCfgIBuf; + pMac->cfg.gCfgSBuf = __gCfgSBuf; + pMac->cfg.gSBuffer = __gSBuffer; + pMac->cfg.gCfgEntry = __gCfgEntry; + + for(i=0; icfg.gCfgIBufMin = NULL; + pMac->cfg.gCfgIBufMax = NULL; + pMac->cfg.gCfgIBuf = NULL; + pMac->cfg.gCfgSBuf = NULL; + pMac->cfg.gSBuffer = NULL; + pMac->cfg.gCfgEntry = NULL; +} + +// --------------------------------------------------------------------- +/** + * cfgSetInt() + * + * FUNCTION: + * This function is called to update an integer parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Range checking is performed by the calling function. In case this + * function call is being triggered by a request from host, then host + * is responsible for performing range checking before sending the + * request. + * + * - Host RW permission checking should already be done prior to calling + * this function by the message processing function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param value: 32-bit unsigned value + * + * @return eSIR_SUCCESS : request completed successfully \n + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID \n + */ + +tSirRetStatus +cfgSetInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 value) +{ + tANI_U32 index; + tANI_U32 control, mask; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + return eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_IBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else if ((pMac->cfg.gCfgIBufMin[index] < pMac->cfg.gCfgIBufMax[index]) && + ((pMac->cfg.gCfgIBufMin[index] > value) || + (pMac->cfg.gCfgIBufMax[index] < value))) + { + PELOGE(cfgLog(pMac, LOGE, FL("Value %u out of range [%u,%u] cfgid %hu"), + value, pMac->cfg.gCfgIBufMin[index], + pMac->cfg.gCfgIBufMax[index], cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else if (!(pMac->cfg.gCfgIBufMin[index] < pMac->cfg.gCfgIBufMax[index]) && + (((tANI_S32)(pMac->cfg.gCfgIBufMin[index]) > (tANI_S32)value) || + ((tANI_S32)(pMac->cfg.gCfgIBufMax[index]) < (tANI_S32)value))) + { + PELOGE(cfgLog(pMac, LOGE, FL("Value %d out of range [%d,%d] cfgid %hu"), + value, pMac->cfg.gCfgIBufMin[index], + pMac->cfg.gCfgIBufMax[index], cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + // Write integer value + pMac->cfg.gCfgIBuf[index] = value; + + // Update hardware if necessary + mask = control & CFG_CTL_NTF_MASK; + if ((mask & CFG_CTL_NTF_HW) != 0) + PELOGE(cfgLog(pMac, LOGE, FL("CFG Notify HW not supported!!!"));) + + // Notify other modules if necessary + if ((mask & CFG_CTL_NTF_MASK) != 0) + Notify(pMac, cfgId, mask); + + } + + return (retVal); + +} /*** end cfgSetInt ***/ + +// --------------------------------------------------------------------- +/** + * cfgCheckValid() + * + * FUNCTION: + * This function is called to check if a parameter is valid + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + */ + +tSirRetStatus +cfgCheckValid(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ + tANI_U32 control; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOG3(cfgLog(pMac, LOG3, FL("Invalid cfg id %d"), cfgId);) + return(eSIR_CFG_INVALID_ID); + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOG3(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + return(eSIR_CFG_INVALID_ID); + } + else + return(eSIR_SUCCESS); + +} /*** end cfgCheckValid() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetInt() + * + * FUNCTION: + * This function is called to read an integer parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pVal: address where parameter value will be written + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + */ + +tSirRetStatus +wlan_cfgGetInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pValue) +{ + tANI_U32 index; + tANI_U32 control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_IBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else { + // Get integer value + if (index < CFG_STA_IBUF_MAX_SIZE) + *pValue = pMac->cfg.gCfgIBuf[index]; + } + + return (retVal); + +} /*** end wlan_cfgGetInt() ***/ + +#ifdef NOT_CURRENTLY_USED +// --------------------------------------------------------------------- +/** + * cfgIncrementInt() + * + * FUNCTION: + * This function is called to increment an integer parameter by n. + * + * LOGIC: + * + * ASSUMPTIONS: + * - No range checking will be performed. + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param value: increment value + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + */ + +tSirRetStatus +cfgIncrementInt(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 value) +{ + tANI_U32 index; + tANI_U32 control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + // Increment integer value + pMac->cfg.gCfgIBuf[index] += value; + + } + + return (retVal); +} +#endif // NOT_CURRENTLY_USED + +// --------------------------------------------------------------------- +/** + * cfgSetStr() + * + * FUNCTION: + * This function is called to set a string parameter. + * + * LOGIC: + * This function invokes the cfgSetStrNotify function passing the notify + * boolean value set to TRUE. This basically means that HAL needs to be + * notified. This is true in the case of non-integrated SOC's or Libra/Volans. + * In the case of Prima the cfgSetStrNotify is invoked with the boolean value + * set to FALSE. + * + * ASSUMPTIONS: + * - always Notify has to be called + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pStr: address of string data + * @param len: string length + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * @return eSIR_CFG_INVALID_LEN: invalid parameter length + * + */ + +tSirRetStatus cfgSetStr(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pStr, + tANI_U32 length) +{ + return cfgSetStrNotify( pMac, cfgId, pStr, length, TRUE ); +} + +// --------------------------------------------------------------------- +/** + * cfgSetStrNotify() + * + * FUNCTION: + * This function is called to set a string parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * - No length checking will be performed. Should be done by calling + * module. + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pStr: address of string data + * @param len: string length + * @param notifyMod. Notify respective Module + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * @return eSIR_CFG_INVALID_LEN: invalid parameter length + * + */ + +tSirRetStatus +cfgSetStrNotify(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pStr, + tANI_U32 length, int notifyMod) +{ + tANI_U8 *pDst, *pDstEnd; + tANI_U32 index, paramLen, control, mask; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + return eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else if (index >= CFG_STA_SBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid Sbuf index %d (max size %d)"), + index, CFG_STA_SBUF_MAX_SIZE);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + pDst = &pMac->cfg.gCfgSBuf[index]; + paramLen = *pDst++; + if (length > paramLen) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid length %d (>%d) cfg id %d"), + length, paramLen, cfgId);) + retVal = eSIR_CFG_INVALID_LEN; + } + else + { + *pDst++ = (tANI_U8)length; + pDstEnd = pDst + length; + while (pDst < pDstEnd) + { + *pDst++ = *pStr++; + } + + if(notifyMod) + { + // Update hardware if necessary + mask = control & CFG_CTL_NTF_MASK; + if ((mask & CFG_CTL_NTF_HW) != 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("CFG Notify HW not supported!!!"));) + } + + // Notify other modules if necessary + if ( (mask & CFG_CTL_NTF_MASK) != 0) + { + Notify(pMac, cfgId, mask); + } + } + } + + } + + return (retVal); + +} /*** end cfgSetStrNotify() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetStr() + * + * FUNCTION: + * This function is called to get a string parameter. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pBuf: address of string buffer + * @param pLen: address of max buffer length + * actual length will be returned at this address + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * @return eSIR_CFG_INVALID_LEN: invalid parameter length + * + */ + +tSirRetStatus +wlan_cfgGetStr(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength) +{ + tANI_U8 *pSrc, *pSrcEnd; + tANI_U32 index, control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_SBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + // Get string + pSrc = &pMac->cfg.gCfgSBuf[index]; + pSrc++; // skip over max length + if (*pLength < *pSrc) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid length %d (<%d) cfg id %d"), + *pLength, *pSrc, cfgId);) + retVal = eSIR_CFG_INVALID_LEN; + } + else + { + *pLength = *pSrc++; // save parameter length + pSrcEnd = pSrc + *pLength; + while (pSrc < pSrcEnd) + *pBuf++ = *pSrc++; + } + } + + return (retVal); + +} /*** end wlan_cfgGetStr() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetStrMaxLen() + * + * FUNCTION: + * This function is called to get a string maximum length. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pLen: maximum length will be returned at this address + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * + */ + +tSirRetStatus +wlan_cfgGetStrMaxLen(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pLength) +{ + tANI_U32 index, control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_SBUF_MAX_SIZE) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + *pLength = pMac->cfg.gCfgSBuf[index]; + } + + return (retVal); + +} /*** end wlan_cfgGetStrMaxLen() ***/ + +// --------------------------------------------------------------------- +/** + * wlan_cfgGetStrLen() + * + * FUNCTION: + * This function is called to get a string length. + * + * LOGIC: + * + * ASSUMPTIONS: + * - Host RW permission should be checked prior to calling this + * function. + * + * NOTE: + * + * @param cfgId: 16-bit CFG parameter ID + * @param pLen: current length will be returned at this address + * + * @return eSIR_SUCCESS: request completed successfully + * @return eSIR_CFG_INVALID_ID: invalid CFG parameter ID + * + */ + +tSirRetStatus +wlan_cfgGetStrLen(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 *pLength) +{ + tANI_U32 index, control; + tSirRetStatus retVal; + + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + if (!pMac->cfg.gCfgEntry) + { + PELOGE(cfgLog(pMac, LOGE, FL("gCfgEntry is NULL"));) + return eSIR_CFG_INVALID_ID; + } + + control = pMac->cfg.gCfgEntry[cfgId].control; + index = control & CFG_BUF_INDX_MASK; + retVal = eSIR_SUCCESS; + + if (index >= CFG_STA_SBUF_MAX_SIZE-1) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg index out of bounds %d"), index);) + retVal = eSIR_CFG_INVALID_ID; + return retVal; + } + + // Check if parameter is valid + if ((control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOG3, FL("Not valid cfg id %d"), cfgId);) + retVal = eSIR_CFG_INVALID_ID; + } + else + { + *pLength = pMac->cfg.gCfgSBuf[index+1]; + } + + return (retVal); + +} /*** end wlan_cfgGetStrLen() ***/ + + + +/*------------------------------------------------------------- +\fn cfgGetDot11dTransmitPower +\brief This function returns the regulatory max transmit power +\param pMac +\return tPowerdBm - Power +\-------------------------------------------------------------*/ +static tPowerdBm +cfgGetDot11dTransmitPower(tpAniSirGlobal pMac, tANI_U16 cfgId, + tANI_U32 cfgLength, tANI_U8 channel) +{ + tANI_U8 *pCountryInfo = NULL; + tANI_U8 count = 0; + tPowerdBm maxTxPwr = WDA_MAX_TXPOWER_INVALID; + + /* At least one element is present */ + if(cfgLength < sizeof(tSirMacChanInfo)) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid CFGLENGTH %d while getting 11d txpower"), cfgLength);) + goto error; + } + + pCountryInfo = vos_mem_malloc(cfgLength); + if ( NULL == pCountryInfo ) + { + cfgLog(pMac, LOGP, FL(" failed to allocate memory")); + goto error; + } + /* The CSR will always update this CFG. The contents will be from country IE if regulatory domain + * is enabled on AP else will contain EEPROM contents + */ + if (wlan_cfgGetStr(pMac, cfgId, pCountryInfo, &cfgLength) != eSIR_SUCCESS) + { + vos_mem_free(pCountryInfo); + pCountryInfo = NULL; + + cfgLog(pMac, LOGP, FL("Failed to retrieve 11d configuration parameters while retrieving 11d tuples")); + goto error; + } + /* Identify the channel and maxtxpower */ + while(count <= (cfgLength - (sizeof(tSirMacChanInfo)))) + { + tANI_U8 firstChannel, maxChannels; + + firstChannel = pCountryInfo[count++]; + maxChannels = pCountryInfo[count++]; + maxTxPwr = pCountryInfo[count++]; + + if((channel >= firstChannel) && + (channel < (firstChannel + maxChannels))) + { + break; + } + } + +error: + if (NULL != pCountryInfo) + vos_mem_free(pCountryInfo); + + return maxTxPwr; +} + + +/**---------------------------------------------------------------------- +\fn cfgGetRegulatoryMaxTransmitPower + +\brief Gets regulatory tx power on the current channel. + +\param pMac +\param channel +\param rfBand + -----------------------------------------------------------------------*/ +tPowerdBm cfgGetRegulatoryMaxTransmitPower(tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_U32 cfgLength = 0; + tANI_U16 cfgId = 0; + tPowerdBm maxTxPwr; + eRfBandMode rfBand = eRF_BAND_UNKNOWN; + + if ((channel >= SIR_11A_CHANNEL_BEGIN) && + (channel <= SIR_11A_CHANNEL_END)) + rfBand = eRF_BAND_5_GHZ; + else + rfBand = eRF_BAND_2_4_GHZ; + + + /* Get the max transmit power for current channel for the current regulatory domain */ + switch (rfBand) + { + case eRF_BAND_2_4_GHZ: + cfgId = WNI_CFG_MAX_TX_POWER_2_4; + cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN; + PELOG2(cfgLog(pMac, LOG2, FL("HAL: Reading CFG for 2.4 GHz channels to get regulatory max tx power"));) + break; + + case eRF_BAND_5_GHZ: + cfgId = WNI_CFG_MAX_TX_POWER_5; + cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN; + PELOG2(cfgLog(pMac, LOG2, FL("HAL: Reading CFG for 5.0 GHz channels to get regulatory max tx power"));) + break; + + case eRF_BAND_UNKNOWN: + default: + PELOG2(cfgLog(pMac, LOG2, FL("HAL: Invalid current working band for the device"));) + return WDA_MAX_TXPOWER_INVALID; //Its return, not break. + } + + maxTxPwr = cfgGetDot11dTransmitPower(pMac, cfgId, cfgLength, channel); + + return (maxTxPwr); +} + +// --------------------------------------------------------------------- +/** + * cfgGetCapabilityInfo + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tSirRetStatus +cfgGetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 *pCap,tpPESession sessionEntry) +{ + tANI_U32 val = 0; + tpSirMacCapabilityInfo pCapInfo; + tLimSystemRole systemRole = limGetSystemRole(sessionEntry); + + *pCap = 0; + pCapInfo = (tpSirMacCapabilityInfo) pCap; + + if (systemRole == eLIM_STA_IN_IBSS_ROLE) + pCapInfo->ibss = 1; // IBSS bit + else if ( (systemRole == eLIM_AP_ROLE) ||(systemRole == eLIM_BT_AMP_AP_ROLE)||(systemRole == eLIM_BT_AMP_STA_ROLE) || + (systemRole == eLIM_STA_ROLE) ) + pCapInfo->ess = 1; // ESS bit + else if (limGetSystemRole(sessionEntry) == eLIM_P2P_DEVICE_ROLE ) + { + pCapInfo->ess = 0; + pCapInfo->ibss = 0; + } + else + cfgLog(pMac, LOGP, FL("can't get capability, role is UNKNOWN!!")); + + + if(systemRole == eLIM_AP_ROLE) + { + val = sessionEntry->privacy; +#ifdef SAP_AUTH_OFFLOAD + /* Support SAP Authentication Offload feature, + * If Auth offload security Type is not disabled + * driver need to enable privacy bit in beacon + */ + if (pMac->sap_auth_offload && pMac->sap_auth_offload_sec_type) + { + val = 1; + } +#endif + + } + else + { + // PRIVACY bit + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_PRIVACY_ENABLED failed")); + return eSIR_FAILURE; + } + } + if (val) + pCapInfo->privacy = 1; + + // Short preamble bit + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_SHORT_PREAMBLE failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->shortPreamble = 1; + + + // PBCC bit + pCapInfo->pbcc = 0; + + // Channel agility bit + pCapInfo->channelAgility = 0; + //If STA/AP operating in 11B mode, don't set rest of the capability info bits. + if(sessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11B) + return eSIR_SUCCESS; + + // Short slot time bit + if (systemRole == eLIM_AP_ROLE) + { + pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported; + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val) + != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, + FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed")); + return eSIR_FAILURE; + } + /* When in STA mode, we need to check if short slot is enabled as well as check if the current operating + * mode is short slot time and then decide whether to enable short slot or not. It is safe to check both + * cfg values to determine short slot value in this funcn since this funcn is always used after assoc when + * these cfg values are already set based on peer's capability. Even in case of IBSS, its value is set to + * correct value either in delBSS as part of deleting the previous IBSS or in start BSS as part of coalescing + */ + if (val) + { + pCapInfo->shortSlotTime = sessionEntry->shortSlotTimeSupported; + } + } + + // Spectrum Management bit + if((eLIM_STA_IN_IBSS_ROLE != systemRole) && (eLIM_AP_ROLE != systemRole) && + sessionEntry->lim11hEnable ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_11H_ENABLED failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->spectrumMgt = 1; + } + + // QoS bit + if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_QOS_ENABLED failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->qos = 1; + + // APSD bit + if (wlan_cfgGetInt(pMac, WNI_CFG_APSD_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_APSD_ENABLED failed")); + return eSIR_FAILURE; + } + if (val) + pCapInfo->apsd = 1; + +#if defined WLAN_FEATURE_VOWIFI + if ((limGetSystemRole(sessionEntry) == eLIM_STA_ROLE) ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_RRM_ENABLED failed")); + return eSIR_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + PELOGE(cfgLog( pMac, LOG1, "RRM = %d",val );) +#endif + if (val) + pCapInfo->rrm = 1; + } +#endif + //DSSS-OFDM + //FIXME : no config defined yet. + + // Block ack bit + if (wlan_cfgGetInt(pMac, WNI_CFG_BLOCK_ACK_ENABLED, &val) != eSIR_SUCCESS) + { + cfgLog(pMac, LOGP, FL("cfg get WNI_CFG_BLOCK_ACK_ENABLED failed")); + return eSIR_FAILURE; + } + pCapInfo->delayedBA = (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1); + pCapInfo->immediateBA = (tANI_U16)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * cfgSetCapabilityInfo + * + * FUNCTION: + * This function is called on BP based on the capabilities + * received in SME_JOIN/REASSOC_REQ message. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: 1. ESS/IBSS capabilities are based on system role. + * 2. Since PBCC, Channel agility and Extended capabilities + * are not supported, they're not set at CFG + * + * @param pMac Pointer to global MAC structure + * @param caps 16-bit Capability Info field + * @return None + */ + +void +cfgSetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 caps) +{ +} + + +// --------------------------------------------------------------------- +/** + * cfgCleanup() + * + * FUNCTION: + * CFG cleanup function. + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * This function must be called during system shutdown. + * + * @param None + * + * @return None. + * + */ + +void +cfgCleanup(tpAniSirGlobal pMac) +{ + // Set status to not-ready + pMac->cfg.gCfgStatus = CFG_INCOMPLETE; + +} /*** end CfgCleanup() ***/ + +// --------------------------------------------------------------------- +/** + * Notify() + * + * FUNCTION: + * This function is called to notify other modules of parameter update. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param cfgId: configuration parameter ID + * @param mask: notification mask + * + * @return None. + * + */ + +static void +Notify(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 ntfMask) +{ + + tSirMsgQ mmhMsg; + + mmhMsg.type = SIR_CFG_PARAM_UPDATE_IND; + mmhMsg.bodyval = (tANI_U32)cfgId; + mmhMsg.bodyptr = NULL; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + + if ((ntfMask & CFG_CTL_NTF_SCH) != 0) + schPostMessage(pMac, &mmhMsg); + + if ((ntfMask & CFG_CTL_NTF_LIM) != 0) + limPostMsgApi(pMac, &mmhMsg); + + if ((ntfMask & CFG_CTL_NTF_HAL) != 0) + wdaPostCtrlMsg(pMac, &mmhMsg); + + // Notify ARQ + +} /*** end Notify() ***/ + +// --------------------------------------------------------------------- + + + + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.c new file mode 100644 index 000000000000..43982f54355c --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file cfgDebug.c + + \brief implementation for log Debug related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + +#include "cfgDebug.h" + +void cfgLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + // Verify against current log level + if (loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_CFG_MODULE_ID )]) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_CFG_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.h b/drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.h new file mode 100644 index 000000000000..20c87027527f --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgDebug.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ + +#ifndef __CFG_DEBUG_H__ +#define __CFG_DEBUG_H__ + +#include "sirDebug.h" +#include "utilsApi.h" +#include "limTrace.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) cfgLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...); + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgDef.h b/drivers/staging/prima/CORE/MAC/src/cfg/cfgDef.h new file mode 100644 index 000000000000..0b40d30bffcb --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgDef.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This is the private header file for CFG module. + * + * Author: Kevin Nguyen + * Date: 03/20/02 + * History:- + * 03/20/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGDEF_H +#define __CFGDEF_H + +/* + * CFG Control Flag definitions + */ +#define CFG_CTL_VALID 0x00010000 +#define CFG_CTL_RE 0x00020000 +#define CFG_CTL_WE 0x00040000 +#define CFG_CTL_INT 0x00080000 +#define CFG_CTL_SAVE 0x00100000 +#define CFG_CTL_RESTART 0x00200000 +#define CFG_CTL_RELOAD 0x00400000 +#define CFG_CTL_NTF_PHY 0x00800000 +#define CFG_CTL_NTF_MAC 0x01000000 +#define CFG_CTL_NTF_LOG 0x02000000 +#define CFG_CTL_NTF_HAL 0x04000000 +#define CFG_CTL_NTF_DPH 0x08000000 +#define CFG_CTL_NTF_ARQ 0x10000000 +#define CFG_CTL_NTF_SCH 0x20000000 +#define CFG_CTL_NTF_LIM 0x40000000 +#define CFG_CTL_NTF_HDD 0x80000000 +#define CFG_CTL_NTF_MASK 0xFFE00000 + +#define CFG_CTL_NTF_TFP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_RHP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_RFP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_SP CFG_CTL_NTF_MAC +#define CFG_CTL_NTF_HW (CFG_CTL_NTF_MAC | CFG_CTL_NTF_PHY) + +#define CFG_BUF_INDX_MASK 0x00000fff + + +#endif /* __CFGDEF_H */ + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgParamName.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgParamName.c new file mode 100644 index 000000000000..5fda17064fae --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgParamName.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * DO NOT EDIT - This file is generated automatically + */ + +/* + * IMPORTANT: This file is for system that supports STA mode ONLY. + */ +#include "cfgPriv.h" + +unsigned char *gCfgParamName[] = { + (unsigned char *)"STA_ID", + (unsigned char *)"CF_POLLABLE", + (unsigned char *)"CFP_PERIOD", + (unsigned char *)"CFP_MAX_DURATION", + (unsigned char *)"SSID", + (unsigned char *)"BEACON_INTERVAL", + (unsigned char *)"DTIM_PERIOD", + (unsigned char *)"WEP_KEY_LENGTH", + (unsigned char *)"WEP_DEFAULT_KEY_1", + (unsigned char *)"WEP_DEFAULT_KEY_2", + (unsigned char *)"WEP_DEFAULT_KEY_3", + (unsigned char *)"WEP_DEFAULT_KEY_4", + (unsigned char *)"WEP_DEFAULT_KEYID", + (unsigned char *)"EXCLUDE_UNENCRYPTED", + (unsigned char *)"RTS_THRESHOLD", + (unsigned char *)"SHORT_RETRY_LIMIT", + (unsigned char *)"LONG_RETRY_LIMIT", + (unsigned char *)"FRAGMENTATION_THRESHOLD", + (unsigned char *)"ACTIVE_MINIMUM_CHANNEL_TIME", + (unsigned char *)"ACTIVE_MAXIMUM_CHANNEL_TIME", + (unsigned char *)"PASSIVE_MINIMUM_CHANNEL_TIME", + (unsigned char *)"PASSIVE_MAXIMUM_CHANNEL_TIME", + (unsigned char *)"JOIN_FAILURE_TIMEOUT", + (unsigned char *)"AUTHENTICATE_FAILURE_TIMEOUT", + (unsigned char *)"AUTHENTICATE_RSP_TIMEOUT", + (unsigned char *)"ASSOCIATION_FAILURE_TIMEOUT", + (unsigned char *)"REASSOCIATION_FAILURE_TIMEOUT", + (unsigned char *)"RA_PERIODICITY_TIMEOUT_IN_PS", + (unsigned char *)"PS_ENABLE_BCN_FILTER", + (unsigned char *)"PS_ENABLE_HEART_BEAT", + (unsigned char *)"PS_ENABLE_RSSI_MONITOR", + (unsigned char *)"PS_DATA_INACTIVITY_TIMEOUT", + (unsigned char *)"RF_SETTLING_TIME_CLK", + (unsigned char *)"SUPPORTED_RATES_11B", + (unsigned char *)"SUPPORTED_RATES_11A", + (unsigned char *)"PHY_MODE", + (unsigned char *)"DOT11_MODE", + (unsigned char *)"OPERATIONAL_RATE_SET", + (unsigned char *)"EXTENDED_OPERATIONAL_RATE_SET", + (unsigned char *)"PROPRIETARY_OPERATIONAL_RATE_SET", + (unsigned char *)"BSSID", + (unsigned char *)"LISTEN_INTERVAL", + (unsigned char *)"VALID_CHANNEL_LIST", + (unsigned char *)"CURRENT_CHANNEL", + (unsigned char *)"DEFAULT_RATE_INDEX_5GHZ", + (unsigned char *)"DEFAULT_RATE_INDEX_24GHZ", + (unsigned char *)"RATE_ADAPTATION_TYPE", + (unsigned char *)"FIXED_RATE", + (unsigned char *)"FIXED_RATE_MULTICAST_24GHZ", + (unsigned char *)"FIXED_RATE_MULTICAST_5GHZ", + (unsigned char *)"RETRYRATE_POLICY", + (unsigned char *)"RETRYRATE_SECONDARY", + (unsigned char *)"RETRYRATE_TERTIARY", + (unsigned char *)"APSD_ENABLED", + (unsigned char *)"SHARED_KEY_AUTH_ENABLE", + (unsigned char *)"OPEN_SYSTEM_AUTH_ENABLE", + (unsigned char *)"AUTHENTICATION_TYPE", + (unsigned char *)"CF_POLL_REQUEST", + (unsigned char *)"PRIVACY_ENABLED", + (unsigned char *)"SHORT_PREAMBLE", + (unsigned char *)"SHORT_SLOT_TIME", + (unsigned char *)"ACCEPT_SHORT_SLOT_ASSOC_ONLY", + (unsigned char *)"QOS_ENABLED", + (unsigned char *)"HCF_ENABLED", + (unsigned char *)"RSN_ENABLED", + (unsigned char *)"BACKGROUND_SCAN_PERIOD", + (unsigned char *)"MAX_NUM_PRE_AUTH", + (unsigned char *)"PREAUTH_CLNUP_TIMEOUT", + (unsigned char *)"RELEASE_AID_TIMEOUT", + (unsigned char *)"HEART_BEAT_THRESHOLD", + (unsigned char *)"PROBE_AFTER_HB_FAIL_TIMEOUT", + (unsigned char *)"MANUFACTURER_OUI", + (unsigned char *)"MANUFACTURER_NAME", + (unsigned char *)"MODEL_NUMBER", + (unsigned char *)"MODEL_NAME", + (unsigned char *)"MANUFACTURER_PRODUCT_NAME", + (unsigned char *)"MANUFACTURER_PRODUCT_VERSION", + (unsigned char *)"11D_ENABLED", + (unsigned char *)"MAX_TX_POWER_2_4", + (unsigned char *)"MAX_TX_POWER_5", + (unsigned char *)"NETWORK_DENSITY", + (unsigned char *)"ADAPTIVE_THRESHOLD_ALGORITHM", + (unsigned char *)"CURRENT_TX_ANTENNA", + (unsigned char *)"CURRENT_RX_ANTENNA", + (unsigned char *)"CURRENT_TX_POWER_LEVEL", + (unsigned char *)"POWER_STATE_PER_CHAIN", + (unsigned char *)"NEW_BSS_FOUND_IND", + (unsigned char *)"PROPRIETARY_ANI_FEATURES_ENABLED", + (unsigned char *)"PROPRIETARY_RATES_ENABLED", + (unsigned char *)"AP_NODE_NAME", + (unsigned char *)"COUNTRY_CODE", + (unsigned char *)"11H_ENABLED", + (unsigned char *)"WT_CNF_TIMEOUT", + (unsigned char *)"KEEPALIVE_TIMEOUT", + (unsigned char *)"PROXIMITY", + (unsigned char *)"LOG_LEVEL", + (unsigned char *)"OLBC_DETECT_TIMEOUT", + (unsigned char *)"PROTECTION_ENABLED", + (unsigned char *)"11G_PROTECTION_ALWAYS", + (unsigned char *)"FORCE_POLICY_PROTECTION", + (unsigned char *)"11G_SHORT_PREAMBLE_ENABLED", + (unsigned char *)"11G_SHORT_SLOT_TIME_ENABLED", + (unsigned char *)"CAL_PERIOD", + (unsigned char *)"STATS_PERIOD", + (unsigned char *)"CAL_CONTROL", + (unsigned char *)"11G_ONLY_POLICY", + (unsigned char *)"PACKET_CLASSIFICATION", + (unsigned char *)"WME_ENABLED", + (unsigned char *)"ADDTS_RSP_TIMEOUT", + (unsigned char *)"MAX_SP_LENGTH", + (unsigned char *)"KEEP_ALIVE_STA_LIMIT_THRESHOLD", + (unsigned char *)"SEND_SINGLE_SSID_ALWAYS", + (unsigned char *)"WSM_ENABLED", + (unsigned char *)"PROP_CAPABILITY", + (unsigned char *)"EDCA_PROFILE", + (unsigned char *)"EDCA_ANI_ACBK_LOCAL", + (unsigned char *)"EDCA_ANI_ACBE_LOCAL", + (unsigned char *)"EDCA_ANI_ACVI_LOCAL", + (unsigned char *)"EDCA_ANI_ACVO_LOCAL", + (unsigned char *)"EDCA_ANI_ACBK", + (unsigned char *)"EDCA_ANI_ACBE", + (unsigned char *)"EDCA_ANI_ACVI", + (unsigned char *)"EDCA_ANI_ACVO", + (unsigned char *)"EDCA_WME_ACBK_LOCAL", + (unsigned char *)"EDCA_WME_ACBE_LOCAL", + (unsigned char *)"EDCA_WME_ACVI_LOCAL", + (unsigned char *)"EDCA_WME_ACVO_LOCAL", + (unsigned char *)"EDCA_WME_ACBK", + (unsigned char *)"EDCA_WME_ACBE", + (unsigned char *)"EDCA_WME_ACVI", + (unsigned char *)"EDCA_WME_ACVO", + (unsigned char *)"EDCA_TIT_DEMO_ACBK_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACBE_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACVI_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACVO_LOCAL", + (unsigned char *)"EDCA_TIT_DEMO_ACBK", + (unsigned char *)"EDCA_TIT_DEMO_ACBE", + (unsigned char *)"EDCA_TIT_DEMO_ACVI", + (unsigned char *)"EDCA_TIT_DEMO_ACVO", + (unsigned char *)"RDET_FLAG", + (unsigned char *)"RADAR_CHANNEL_LIST", + (unsigned char *)"LOCAL_POWER_CONSTRAINT", + (unsigned char *)"ADMIT_POLICY", + (unsigned char *)"ADMIT_BWFACTOR", + (unsigned char *)"MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE", + (unsigned char *)"CHANNEL_BONDING_MODE", + (unsigned char *)"CB_SECONDARY_CHANNEL_STATE", + (unsigned char *)"DYNAMIC_THRESHOLD_ZERO", + (unsigned char *)"DYNAMIC_THRESHOLD_ONE", + (unsigned char *)"DYNAMIC_THRESHOLD_TWO", + (unsigned char *)"TRIG_STA_BK_SCAN", + (unsigned char *)"DYNAMIC_PROFILE_SWITCHING", + (unsigned char *)"SCAN_CONTROL_LIST", + (unsigned char *)"MIMO_ENABLED", + (unsigned char *)"BLOCK_ACK_ENABLED", + (unsigned char *)"BA_ACTIVITY_CHECK_TIMEOUT", + (unsigned char *)"HT_RX_STBC", + (unsigned char *)"HT_CAP_INFO", + (unsigned char *)"HT_AMPDU_PARAMS", + (unsigned char *)"SUPPORTED_MCS_SET", + (unsigned char *)"EXT_HT_CAP_INFO", + (unsigned char *)"TX_BF_CAP", + (unsigned char *)"AS_CAP", + (unsigned char *)"HT_INFO_FIELD1", + (unsigned char *)"HT_INFO_FIELD2", + (unsigned char *)"HT_INFO_FIELD3", + (unsigned char *)"BASIC_MCS_SET", + (unsigned char *)"CURRENT_MCS_SET", + (unsigned char *)"GREENFIELD_CAPABILITY", + (unsigned char *)"VHT_MAX_MPDU_LENGTH", + (unsigned char *)"VHT_SUPPORTED_CHAN_WIDTH_SET", + (unsigned char *)"VHT_LDPC_CODING_CAP", + (unsigned char *)"VHT_SHORT_GI_80MHZ", + (unsigned char *)"VHT_SHORT_GI_160_AND_80_PLUS_80MHZ", + (unsigned char *)"VHT_TXSTBC", + (unsigned char *)"VHT_RXSTBC", + (unsigned char *)"VHT_SU_BEAMFORMER_CAP", + (unsigned char *)"VHT_SU_BEAMFORMEE_CAP", + (unsigned char *)"VHT_CSN_BEAMFORMEE_ANT_SUPPORTED", + (unsigned char *)"VHT_NUM_SOUNDING_DIMENSIONS", + (unsigned char *)"VHT_MU_BEAMFORMER_CAP", + (unsigned char *)"VHT_MU_BEAMFORMEE_CAP", + (unsigned char *)"VHT_TXOP_PS", + (unsigned char *)"VHT_HTC_VHTC_CAP", + (unsigned char *)"VHT_AMPDU_LEN_EXPONENT", + (unsigned char *)"VHT_LINK_ADAPTATION_CAP", + (unsigned char *)"VHT_RX_ANT_PATTERN", + (unsigned char *)"VHT_TX_ANT_PATTERN", + (unsigned char *)"VHT_RX_MCS_MAP", + (unsigned char *)"VHT_TX_MCS_MAP", + (unsigned char *)"VHT_RX_HIGHEST_SUPPORTED_DATA_RATE", + (unsigned char *)"VHT_TX_HIGHEST_SUPPORTED_DATA_RATE", + (unsigned char *)"VHT_CHANNEL_WIDTH", + (unsigned char *)"VHT_CHANNEL_CENTER_FREQ_SEGMENT1", + (unsigned char *)"VHT_CHANNEL_CENTER_FREQ_SEGMENT2", + (unsigned char *)"VHT_BASIC_MCS_SET", + (unsigned char *)"VHT_MU_MIMO_CAP_STA_COUNT", + (unsigned char *)"VHT_SS_UNDER_UTIL", + (unsigned char *)"VHT_40MHZ_UTILIZATION", + (unsigned char *)"VHT_80MHZ_UTILIZATION", + (unsigned char *)"VHT_160MHZ_UTILIZATION", + (unsigned char *)"MAX_AMSDU_LENGTH", + (unsigned char *)"MPDU_DENSITY", + (unsigned char *)"NUM_BUFF_ADVERT", + (unsigned char *)"MAX_RX_AMPDU_FACTOR", + (unsigned char *)"SHORT_GI_20MHZ", + (unsigned char *)"SHORT_GI_40MHZ", + (unsigned char *)"RIFS_ENABLED", + (unsigned char *)"MAX_PS_POLL", + (unsigned char *)"NUM_BEACON_PER_RSSI_AVERAGE", + (unsigned char *)"RSSI_FILTER_PERIOD", + (unsigned char *)"MIN_RSSI_THRESHOLD", + (unsigned char *)"NTH_BEACON_FILTER", + (unsigned char *)"BROADCAST_FRAME_FILTER_ENABLE", + (unsigned char *)"SCAN_IN_POWERSAVE", + (unsigned char *)"IGNORE_DTIM", + (unsigned char *)"WOWLAN_UCAST_PATTERN_FILTER_ENABLE", + (unsigned char *)"WOWLAN_CHANNEL_SWITCH_ENABLE", + (unsigned char *)"WOWLAN_DEAUTH_ENABLE", + (unsigned char *)"WOWLAN_DISASSOC_ENABLE", + (unsigned char *)"WOWLAN_MAX_MISSED_BEACON", + (unsigned char *)"WOWLAN_MAX_SLEEP_PERIOD", + (unsigned char *)"BA_TIMEOUT", + (unsigned char *)"BA_THRESHOLD_HIGH", + (unsigned char *)"MAX_BA_BUFFERS", + (unsigned char *)"MAX_BA_SESSIONS", + (unsigned char *)"BA_AUTO_SETUP", + (unsigned char *)"ADDBA_REQ_DECLINE", + (unsigned char *)"DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC", + (unsigned char *)"BG_SCAN_CHANNEL_LIST", + (unsigned char *)"MAX_MEDIUM_TIME", + (unsigned char *)"MAX_MPDUS_IN_AMPDU", + (unsigned char *)"IBSS_AUTO_BSSID", + (unsigned char *)"PROBE_REQ_ADDNIE_FLAG", + (unsigned char *)"PROBE_REQ_ADDNIE_DATA", + (unsigned char *)"PROBE_RSP_ADDNIE_FLAG", + (unsigned char *)"PROBE_RSP_ADDNIE_DATA1", + (unsigned char *)"PROBE_RSP_ADDNIE_DATA2", + (unsigned char *)"PROBE_RSP_ADDNIE_DATA3", + (unsigned char *)"ASSOC_RSP_ADDNIE_FLAG", + (unsigned char *)"ASSOC_RSP_ADDNIE_DATA", + (unsigned char *)"PROBE_REQ_ADDNP2PIE_FLAG", + (unsigned char *)"PROBE_REQ_ADDNP2PIE_DATA", + (unsigned char *)"PROBE_RSP_BCN_ADDNIE_FLAG", + (unsigned char *)"PROBE_RSP_BCN_ADDNIE_DATA", + (unsigned char *)"WPS_ENABLE", + (unsigned char *)"WPS_STATE", + (unsigned char *)"WPS_PROBE_REQ_FLAG", + (unsigned char *)"WPS_VERSION", + (unsigned char *)"WPS_REQUEST_TYPE", + (unsigned char *)"WPS_CFG_METHOD", + (unsigned char *)"WPS_UUID", + (unsigned char *)"WPS_PRIMARY_DEVICE_CATEGORY", + (unsigned char *)"WPS_PIMARY_DEVICE_OUI", + (unsigned char *)"WPS_DEVICE_SUB_CATEGORY", + (unsigned char *)"WPS_ASSOCIATION_STATE", + (unsigned char *)"WPS_CONFIGURATION_ERROR", + (unsigned char *)"WPS_DEVICE_PASSWORD_ID", + (unsigned char *)"WPS_ASSOC_METHOD", + (unsigned char *)"LOW_GAIN_OVERRIDE", + (unsigned char *)"ENABLE_PHY_AGC_LISTEN_MODE", + (unsigned char *)"RPE_POLLING_THRESHOLD", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC0_REG", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC1_REG", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC2_REG", + (unsigned char *)"RPE_AGING_THRESHOLD_FOR_AC3_REG", + (unsigned char *)"NO_OF_ONCHIP_REORDER_SESSIONS", + (unsigned char *)"SINGLE_TID_RC", + (unsigned char *)"RRM_ENABLED", + (unsigned char *)"RRM_OPERATING_CHAN_MAX", + (unsigned char *)"RRM_NON_OPERATING_CHAN_MAX", + (unsigned char *)"TX_PWR_CTRL_ENABLE", + (unsigned char *)"MCAST_BCAST_FILTER_SETTING", + (unsigned char *)"BTC_DHCP_BT_SLOTS_TO_BLOCK", + (unsigned char *)"DYNAMIC_PS_POLL_VALUE", + (unsigned char *)"PS_NULLDATA_AP_RESP_TIMEOUT", + (unsigned char *)"TELE_BCN_WAKEUP_EN", + (unsigned char *)"TELE_BCN_TRANS_LI", + (unsigned char *)"TELE_BCN_TRANS_LI_IDLE_BCNS", + (unsigned char *)"TELE_BCN_MAX_LI", + (unsigned char *)"TELE_BCN_MAX_LI_IDLE_BCNS", + (unsigned char *)"BTC_A2DP_DHCP_BT_SUB_INTERVALS", + (unsigned char *)"INFRA_STA_KEEP_ALIVE_PERIOD", + (unsigned char *)"ASSOC_STA_LIMIT", + (unsigned char *)"SAP_CHANNEL_SELECT_START_CHANNEL", + (unsigned char *)"SAP_CHANNEL_SELECT_END_CHANNEL", + (unsigned char *)"SAP_CHANNEL_SELECT_OPERATING_BAND", + (unsigned char *)"AP_DATA_AVAIL_POLL_PERIOD", + (unsigned char *)"ENABLE_CLOSE_LOOP", + (unsigned char *)"ENABLE_LTE_COEX", + (unsigned char *)"AP_KEEP_ALIVE_TIMEOUT", + (unsigned char *)"GO_KEEP_ALIVE_TIMEOUT", + (unsigned char *)"ENABLE_MC_ADDR_LIST", + (unsigned char *)"ENABLE_UC_FILTER", + (unsigned char *)"ENABLE_LPWR_IMG_TRANSITION", + (unsigned char *)"ENABLE_MCC_ADAPTIVE_SCHED", + (unsigned char *)"DISABLE_LDPC_WITH_TXBF_AP", + (unsigned char *)"AP_LINK_MONITOR_TIMEOUT", + (unsigned char *)"TDLS_QOS_WMM_UAPSD_MASK", + (unsigned char *)"TDLS_BUF_STA_ENABLED", + (unsigned char *)"TDLS_PUAPSD_INACT_TIME", + (unsigned char *)"TDLS_RX_FRAME_THRESHOLD", + (unsigned char *)"ENABLE_ADAPT_RX_DRAIN", + (unsigned char *)"FLEX_CONNECT_POWER_FACTOR", + (unsigned char *)"ANTENNA_DIVESITY", + (unsigned char *)"GO_LINK_MONITOR_TIMEOUT", + (unsigned char *)"RMC_ACTION_PERIOD_FREQUENCY", + (unsigned char *)"ATH_DISABLE", + (unsigned char *)"BTC_ACTIVE_WLAN_LEN", + (unsigned char *)"BTC_ACTIVE_BT_LEN", + (unsigned char *)"BTC_SAP_ACTIVE_WLAN_LEN", + (unsigned char *)"BTC_SAP_ACTIVE_BT_LEN", + (unsigned char *)"ASD_PROBE_INTERVAL", + (unsigned char *)"ASD_TRIGGER_THRESHOLD", + (unsigned char *)"ASD_RTT_RSSI_HYST_THRESHOLD", + (unsigned char *)"DEBUG_P2P_REMAIN_ON_CHANNEL", + (unsigned char *)"BTC_CTS2S_DURING_SCO", + (unsigned char *)"CHANNEL_BONDING_24G", + (unsigned char *)"OBSS_HT40_SCAN_PASSIVE_DWELL_TIME", + (unsigned char *)"OBSS_HT40_SCAN_ACTIVE_DWELL_TIME", + (unsigned char *)"OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL", + (unsigned char *)"OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL", + (unsigned char *)"OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL", + (unsigned char *)"OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR", + (unsigned char *)"OBSS_HT40_SCAN_ACTIVITY_THRESHOLD", + (unsigned char *)"TDLS_OFF_CHANNEL_ENABLED", + (unsigned char *)"PMF_SA_QUERY_MAX_RETRIES", + (unsigned char *)"PMF_SA_QUERY_RETRY_INTERVAL", + (unsigned char *)"RA_FILTER_ENABLE", + (unsigned char *)"RA_RATE_LIMIT_INTERVAL", + (unsigned char *)"BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE", + (unsigned char *)"BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE", + (unsigned char *)"BTC_DYN_A2DP_TX_QUEUE_THOLD", + (unsigned char *)"BTC_DYN_OPP_TX_QUEUE_THOLD", + (unsigned char *)"TDLS_WMM_MODE_ENABLED", + (unsigned char *)"BURST_MODE_BE_TXOP_VALUE", + (unsigned char *)"EXT_SCAN_CONC_MODE", +}; + + + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgPriv.h b/drivers/staging/prima/CORE/MAC/src/cfg/cfgPriv.h new file mode 100644 index 000000000000..acfa786930ad --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgPriv.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This is the private header file for CFG module. + * + * Author: Kevin Nguyen + * Date: 03/20/02 + * History:- + * 03/20/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGPRIV_H +#define __CFGPRIV_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "cfgDef.h" + + #include + +/*--------------------------------------------------------------------*/ +/* CFG miscellaneous definition */ +/*--------------------------------------------------------------------*/ + +// Function index bit mask +#define CFG_FUNC_INDX_MASK 0x7f +#define CFG_GET_FUNC_INDX(val) (val & CFG_FUNC_INDX_MASK) + +// Macro to convert return code to debug string index +#define CFG_GET_DBG_INDX(val) (val - eCFG_SUCCESS - 1) + + +/*--------------------------------------------------------------------*/ +/* Binary header structure */ +/*--------------------------------------------------------------------*/ +typedef struct sCfgBinHdr +{ + tANI_U32 hdrInfo; + tANI_U32 controlSize; + tANI_U32 iBufSize; + tANI_U32 sBufSize; +} tCfgBinHdr, *tpCfgBinHdr; + + +/*--------------------------------------------------------------------*/ +/* Polaris HW counter access structure */ +/*--------------------------------------------------------------------*/ +typedef struct +{ + tANI_U32 addr; + tANI_U32 mask; + tANI_U32 shift; +} tCfgHwCnt; + + +#define CFG_STAT_CNT_LO_MASK 0x0000ffff +#define CFG_STAT_CNT_HI_MASK 0xffff0000 +#define CFG_STAT_CNT_HI_INCR 0x00010000 + +/*--------------------------------------------------------------------*/ +/* CFG function prototypes */ +/*--------------------------------------------------------------------*/ + +extern void cfgSendHostMsg(tpAniSirGlobal, tANI_U16, tANI_U32, tANI_U32, tANI_U32*, tANI_U32, tANI_U32*); + + + + + + +#endif /* __CFGPRIV_H */ + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c new file mode 100644 index 000000000000..43bcf084824e --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgProcMsg.c @@ -0,0 +1,2791 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file contains CFG functions for processing host messages. + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "cfgPriv.h" +#include "cfgDebug.h" +#include "wlan_qct_wda.h" + +tAniSirCgStatic cfgStatic[CFG_PARAM_MAX_NUM] = +{ + {WNI_CFG_STA_ID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RELOAD | CFG_CTL_NTF_HAL, + 0, 255, 1}, + {WNI_CFG_CF_POLLABLE, + CFG_CTL_RE | CFG_CTL_INT | CFG_CTL_RESTART, + 0, 255, 1}, + {WNI_CFG_CFP_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT, + WNI_CFG_CFP_PERIOD_STAMIN, + WNI_CFG_CFP_PERIOD_STAMAX, + WNI_CFG_CFP_PERIOD_STADEF}, + {WNI_CFG_CFP_MAX_DURATION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT, + WNI_CFG_CFP_MAX_DURATION_STAMIN, + WNI_CFG_CFP_MAX_DURATION_STAMAX, + WNI_CFG_CFP_MAX_DURATION_STADEF}, + {WNI_CFG_SSID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 255, 6}, + {WNI_CFG_BEACON_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_SCH, + WNI_CFG_BEACON_INTERVAL_STAMIN, + WNI_CFG_BEACON_INTERVAL_STAMAX, + WNI_CFG_BEACON_INTERVAL_STADEF}, + {WNI_CFG_DTIM_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT, + WNI_CFG_DTIM_PERIOD_STAMIN, + WNI_CFG_DTIM_PERIOD_STAMAX, + WNI_CFG_DTIM_PERIOD_STADEF}, + {WNI_CFG_WEP_KEY_LENGTH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_WEP_KEY_LENGTH_STAMIN, + WNI_CFG_WEP_KEY_LENGTH_STAMAX, + WNI_CFG_WEP_KEY_LENGTH_STADEF}, + {WNI_CFG_WEP_DEFAULT_KEY_1, + CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 65535, 0}, + {WNI_CFG_WEP_DEFAULT_KEY_2, + CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART, + 1, 1, 1}, + {WNI_CFG_WEP_DEFAULT_KEY_3, + CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 5, 5}, + {WNI_CFG_WEP_DEFAULT_KEY_4, + CFG_CTL_VALID | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 1, 0}, + {WNI_CFG_WEP_DEFAULT_KEYID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WEP_DEFAULT_KEYID_STAMIN, + WNI_CFG_WEP_DEFAULT_KEYID_STAMAX, + WNI_CFG_WEP_DEFAULT_KEYID_STADEF}, + {WNI_CFG_EXCLUDE_UNENCRYPTED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_EXCLUDE_UNENCRYPTED_STAMIN, + WNI_CFG_EXCLUDE_UNENCRYPTED_STAMAX, + WNI_CFG_EXCLUDE_UNENCRYPTED_STADEF}, + {WNI_CFG_RTS_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RTS_THRESHOLD_STAMIN, + WNI_CFG_RTS_THRESHOLD_STAMAX, + WNI_CFG_RTS_THRESHOLD_STADEF}, + {WNI_CFG_SHORT_RETRY_LIMIT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_SHORT_RETRY_LIMIT_STAMIN, + WNI_CFG_SHORT_RETRY_LIMIT_STAMAX, + WNI_CFG_SHORT_RETRY_LIMIT_STADEF}, + {WNI_CFG_LONG_RETRY_LIMIT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_LONG_RETRY_LIMIT_STAMIN, + WNI_CFG_LONG_RETRY_LIMIT_STAMAX, + WNI_CFG_LONG_RETRY_LIMIT_STADEF}, + {WNI_CFG_FRAGMENTATION_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN, + WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX, + WNI_CFG_FRAGMENTATION_THRESHOLD_STADEF}, + {WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMIN, + WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STAMAX, + WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME_STADEF}, + {WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMIN, + WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STAMAX, + WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME_STADEF}, + {WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMIN, + WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STAMAX, + WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME_STADEF}, + {WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMIN, + WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STAMAX, + WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF}, + {WNI_CFG_JOIN_FAILURE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMIN, + WNI_CFG_JOIN_FAILURE_TIMEOUT_STAMAX, + WNI_CFG_JOIN_FAILURE_TIMEOUT_STADEF}, + {WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMIN, + WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STAMAX, + WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT_STADEF}, + {WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMIN, + WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STAMAX, + WNI_CFG_AUTHENTICATE_RSP_TIMEOUT_STADEF}, + {WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMIN, + WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STAMAX, + WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT_STADEF}, + {WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMIN, + WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STAMAX, + WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT_STADEF}, + {WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMIN, + WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STAMAX, + WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS_STADEF}, + {WNI_CFG_PS_ENABLE_BCN_FILTER, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PS_ENABLE_BCN_FILTER_STAMIN, + WNI_CFG_PS_ENABLE_BCN_FILTER_STAMAX, + WNI_CFG_PS_ENABLE_BCN_FILTER_STADEF}, + {WNI_CFG_PS_ENABLE_HEART_BEAT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PS_ENABLE_HEART_BEAT_STAMIN, + WNI_CFG_PS_ENABLE_HEART_BEAT_STAMAX, + WNI_CFG_PS_ENABLE_HEART_BEAT_STADEF}, + {WNI_CFG_PS_ENABLE_RSSI_MONITOR, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN, + WNI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX, + WNI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF}, + {WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN, + WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX, + WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF}, + {WNI_CFG_RF_SETTLING_TIME_CLK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RF_SETTLING_TIME_CLK_STAMIN, + WNI_CFG_RF_SETTLING_TIME_CLK_STAMAX, + WNI_CFG_RF_SETTLING_TIME_CLK_STADEF}, + {WNI_CFG_SUPPORTED_RATES_11B, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 3, 1}, + {WNI_CFG_SUPPORTED_RATES_11A, CFG_CTL_VALID | CFG_CTL_RE, + 0, 255, 15}, + {WNI_CFG_PHY_MODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_PHY_MODE_STAMIN, + WNI_CFG_PHY_MODE_STAMAX, + WNI_CFG_PHY_MODE_STADEF}, + {WNI_CFG_DOT11_MODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_DOT11_MODE_STAMIN, + WNI_CFG_DOT11_MODE_STAMAX, + WNI_CFG_DOT11_MODE_STADEF}, + {WNI_CFG_OPERATIONAL_RATE_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 1, 1}, + {WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 65535, 65534}, + {WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_BSSID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0,0,0}, + {WNI_CFG_LISTEN_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_LISTEN_INTERVAL_STAMIN, + WNI_CFG_LISTEN_INTERVAL_STAMAX, + WNI_CFG_LISTEN_INTERVAL_STADEF}, + {WNI_CFG_VALID_CHANNEL_LIST, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + 0, 1, 1}, + {WNI_CFG_CURRENT_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT, + WNI_CFG_CURRENT_CHANNEL_STAMIN, + WNI_CFG_CURRENT_CHANNEL_STAMAX, + WNI_CFG_CURRENT_CHANNEL_STADEF}, + {WNI_CFG_DEFAULT_RATE_INDEX_5GHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN, + WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX, + WNI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF}, + {WNI_CFG_DEFAULT_RATE_INDEX_24GHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN, + WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX, + WNI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF}, + {WNI_CFG_RATE_ADAPTATION_TYPE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_SCH, + WNI_CFG_RATE_ADAPTATION_TYPE_STAMIN, + WNI_CFG_RATE_ADAPTATION_TYPE_STAMAX, + WNI_CFG_RATE_ADAPTATION_TYPE_STADEF}, + {WNI_CFG_FIXED_RATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_FIXED_RATE_STAMIN, + WNI_CFG_FIXED_RATE_STAMAX, + WNI_CFG_FIXED_RATE_STADEF}, + {WNI_CFG_FIXED_RATE_MULTICAST_24GHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN, + WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX, + WNI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF}, + {WNI_CFG_FIXED_RATE_MULTICAST_5GHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN, + WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX, + WNI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF}, + {WNI_CFG_RETRYRATE_POLICY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RETRYRATE_POLICY_STAMIN, + WNI_CFG_RETRYRATE_POLICY_STAMAX, + WNI_CFG_RETRYRATE_POLICY_STADEF}, + {WNI_CFG_RETRYRATE_SECONDARY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RETRYRATE_SECONDARY_STAMIN, + WNI_CFG_RETRYRATE_SECONDARY_STAMAX, + WNI_CFG_RETRYRATE_SECONDARY_STADEF}, + {WNI_CFG_RETRYRATE_TERTIARY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RETRYRATE_TERTIARY_STAMIN, + WNI_CFG_RETRYRATE_TERTIARY_STAMAX, + WNI_CFG_RETRYRATE_TERTIARY_STADEF}, + {WNI_CFG_APSD_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_APSD_ENABLED_STAMIN, + WNI_CFG_APSD_ENABLED_STAMAX, + WNI_CFG_APSD_ENABLED_STADEF}, + {WNI_CFG_SHARED_KEY_AUTH_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMIN, + WNI_CFG_SHARED_KEY_AUTH_ENABLE_STAMAX, + WNI_CFG_SHARED_KEY_AUTH_ENABLE_STADEF}, + {WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMIN, + WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STAMAX, + WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE_STADEF}, + {WNI_CFG_AUTHENTICATION_TYPE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_AUTHENTICATION_TYPE_STAMIN, + WNI_CFG_AUTHENTICATION_TYPE_STAMAX, + WNI_CFG_AUTHENTICATION_TYPE_STADEF}, + {WNI_CFG_CF_POLL_REQUEST, + CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + 0, 255, 1}, + {WNI_CFG_PRIVACY_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_PRIVACY_ENABLED_STAMIN, + WNI_CFG_PRIVACY_ENABLED_STAMAX, + WNI_CFG_PRIVACY_ENABLED_STADEF}, + {WNI_CFG_SHORT_PREAMBLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_SHORT_PREAMBLE_STAMIN, + WNI_CFG_SHORT_PREAMBLE_STAMAX, + WNI_CFG_SHORT_PREAMBLE_STADEF}, + {WNI_CFG_SHORT_SLOT_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SHORT_SLOT_TIME_STAMIN, + WNI_CFG_SHORT_SLOT_TIME_STAMAX, + WNI_CFG_SHORT_SLOT_TIME_STADEF}, + {WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMIN, + WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STAMAX, + WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY_STADEF}, + {WNI_CFG_QOS_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_QOS_ENABLED_STAMIN, + WNI_CFG_QOS_ENABLED_STAMAX, + WNI_CFG_QOS_ENABLED_STADEF}, + {WNI_CFG_HCF_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_HCF_ENABLED_STAMIN, + WNI_CFG_HCF_ENABLED_STAMAX, + WNI_CFG_HCF_ENABLED_STADEF}, + {WNI_CFG_RSN_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_RSN_ENABLED_STAMIN, + WNI_CFG_RSN_ENABLED_STAMAX, + WNI_CFG_RSN_ENABLED_STADEF}, + {WNI_CFG_BACKGROUND_SCAN_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMIN, + WNI_CFG_BACKGROUND_SCAN_PERIOD_STAMAX, + WNI_CFG_BACKGROUND_SCAN_PERIOD_STADEF}, + {WNI_CFG_MAX_NUM_PRE_AUTH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_MAX_NUM_PRE_AUTH_STAMIN, + WNI_CFG_MAX_NUM_PRE_AUTH_STAMAX, + WNI_CFG_MAX_NUM_PRE_AUTH_STADEF}, + {WNI_CFG_PREAUTH_CLNUP_TIMEOUT, + CFG_CTL_INT, + 0, 255, 1}, + {WNI_CFG_RELEASE_AID_TIMEOUT, + CFG_CTL_INT, + 0, 255, 1}, + {WNI_CFG_HEART_BEAT_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN, + WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX, + WNI_CFG_HEART_BEAT_THRESHOLD_STADEF}, + {WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMIN, + WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STAMAX, + WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT_STADEF}, + {WNI_CFG_MANUFACTURER_OUI, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 0, 0}, + {WNI_CFG_MANUFACTURER_NAME, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 0, 0}, + {WNI_CFG_MODEL_NUMBER, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 0, 0}, + {WNI_CFG_MODEL_NAME, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 0, 0}, + {WNI_CFG_MANUFACTURER_PRODUCT_NAME, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 0, 0}, + {WNI_CFG_MANUFACTURER_PRODUCT_VERSION, + CFG_CTL_VALID | CFG_CTL_RE, + 0, 0, 0}, + {WNI_CFG_11D_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_11D_ENABLED_STAMIN, + WNI_CFG_11D_ENABLED_STAMAX, + WNI_CFG_11D_ENABLED_STADEF}, + {WNI_CFG_MAX_TX_POWER_2_4, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_MAX_TX_POWER_5, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_NETWORK_DENSITY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_NETWORK_DENSITY_STAMIN, + WNI_CFG_NETWORK_DENSITY_STAMAX, + WNI_CFG_NETWORK_DENSITY_STADEF}, + {WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMIN, + WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STAMAX, + WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM_STADEF}, + {WNI_CFG_CURRENT_TX_ANTENNA, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_CURRENT_TX_ANTENNA_STAMIN, + WNI_CFG_CURRENT_TX_ANTENNA_STAMAX, + WNI_CFG_CURRENT_TX_ANTENNA_STADEF}, + {WNI_CFG_CURRENT_RX_ANTENNA, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_CURRENT_RX_ANTENNA_STAMIN, + WNI_CFG_CURRENT_RX_ANTENNA_STAMAX, + WNI_CFG_CURRENT_RX_ANTENNA_STADEF}, + {WNI_CFG_CURRENT_TX_POWER_LEVEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT, + WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMIN, + WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX, + WNI_CFG_CURRENT_TX_POWER_LEVEL_STADEF}, + {WNI_CFG_POWER_STATE_PER_CHAIN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_POWER_STATE_PER_CHAIN_STAMIN, + WNI_CFG_POWER_STATE_PER_CHAIN_STAMAX, + WNI_CFG_POWER_STATE_PER_CHAIN_STADEF}, + {WNI_CFG_NEW_BSS_FOUND_IND, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_NEW_BSS_FOUND_IND_STAMIN, + WNI_CFG_NEW_BSS_FOUND_IND_STAMAX, + WNI_CFG_NEW_BSS_FOUND_IND_STADEF}, + {WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMIN, + WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STAMAX, + WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED_STADEF}, + {WNI_CFG_PROPRIETARY_RATES_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMIN, + WNI_CFG_PROPRIETARY_RATES_ENABLED_STAMAX, + WNI_CFG_PROPRIETARY_RATES_ENABLED_STADEF}, + {WNI_CFG_AP_NODE_NAME, + CFG_CTL_RE, + 0, 255, 1}, + {WNI_CFG_COUNTRY_CODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_11H_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_11H_ENABLED_STAMIN, + WNI_CFG_11H_ENABLED_STAMAX, + WNI_CFG_11H_ENABLED_STADEF}, + {WNI_CFG_WT_CNF_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WT_CNF_TIMEOUT_STAMIN, + WNI_CFG_WT_CNF_TIMEOUT_STAMAX, + WNI_CFG_WT_CNF_TIMEOUT_STADEF}, + {WNI_CFG_KEEPALIVE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_KEEPALIVE_TIMEOUT_STAMIN, + WNI_CFG_KEEPALIVE_TIMEOUT_STAMAX, + WNI_CFG_KEEPALIVE_TIMEOUT_STADEF}, + {WNI_CFG_PROXIMITY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PROXIMITY_STAMIN, + WNI_CFG_PROXIMITY_STAMAX, + WNI_CFG_PROXIMITY_STADEF}, + {WNI_CFG_LOG_LEVEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_LOG_LEVEL_STAMIN, + WNI_CFG_LOG_LEVEL_STAMAX, + WNI_CFG_LOG_LEVEL_STADEF}, + {WNI_CFG_OLBC_DETECT_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OLBC_DETECT_TIMEOUT_STAMIN, + WNI_CFG_OLBC_DETECT_TIMEOUT_STAMAX, + WNI_CFG_OLBC_DETECT_TIMEOUT_STADEF}, + {WNI_CFG_PROTECTION_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_PROTECTION_ENABLED_STAMIN, + WNI_CFG_PROTECTION_ENABLED_STAMAX, + WNI_CFG_PROTECTION_ENABLED_STADEF}, + {WNI_CFG_11G_PROTECTION_ALWAYS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_11G_PROTECTION_ALWAYS_STAMIN, + WNI_CFG_11G_PROTECTION_ALWAYS_STAMAX, + WNI_CFG_11G_PROTECTION_ALWAYS_STADEF}, + {WNI_CFG_FORCE_POLICY_PROTECTION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_HAL, + WNI_CFG_FORCE_POLICY_PROTECTION_STAMIN, + WNI_CFG_FORCE_POLICY_PROTECTION_STAMAX, + WNI_CFG_FORCE_POLICY_PROTECTION_STADEF}, + {WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMIN, + WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STAMAX, + WNI_CFG_11G_SHORT_PREAMBLE_ENABLED_STADEF}, + {WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMIN, + WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STAMAX, + WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED_STADEF}, + {WNI_CFG_CAL_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_CAL_PERIOD_STAMIN, + WNI_CFG_CAL_PERIOD_STAMAX, + WNI_CFG_CAL_PERIOD_STADEF}, + {WNI_CFG_STATS_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_STATS_PERIOD_STAMIN, + WNI_CFG_STATS_PERIOD_STAMAX, + WNI_CFG_STATS_PERIOD_STADEF}, + {WNI_CFG_CAL_CONTROL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_CAL_CONTROL_STAMIN, + WNI_CFG_CAL_CONTROL_STAMAX, + WNI_CFG_CAL_CONTROL_STADEF}, + {WNI_CFG_11G_ONLY_POLICY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_11G_ONLY_POLICY_STAMIN, + WNI_CFG_11G_ONLY_POLICY_STAMAX, + WNI_CFG_11G_ONLY_POLICY_STADEF}, + {WNI_CFG_PACKET_CLASSIFICATION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PACKET_CLASSIFICATION_STAMIN, + WNI_CFG_PACKET_CLASSIFICATION_STAMAX, + WNI_CFG_PACKET_CLASSIFICATION_STADEF}, + {WNI_CFG_WME_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_WME_ENABLED_STAMIN, + WNI_CFG_WME_ENABLED_STAMAX, + WNI_CFG_WME_ENABLED_STADEF}, + {WNI_CFG_ADDTS_RSP_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ADDTS_RSP_TIMEOUT_STAMIN, + WNI_CFG_ADDTS_RSP_TIMEOUT_STAMAX, + WNI_CFG_ADDTS_RSP_TIMEOUT_STADEF}, + {WNI_CFG_MAX_SP_LENGTH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_MAX_SP_LENGTH_STAMIN, + WNI_CFG_MAX_SP_LENGTH_STAMAX, + WNI_CFG_MAX_SP_LENGTH_STADEF}, + {WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD, + CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + 0, 255, 1}, + {WNI_CFG_SEND_SINGLE_SSID_ALWAYS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMIN, + WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STAMAX, + WNI_CFG_SEND_SINGLE_SSID_ALWAYS_STADEF}, + {WNI_CFG_WSM_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WSM_ENABLED_STAMIN, + WNI_CFG_WSM_ENABLED_STAMAX, + WNI_CFG_WSM_ENABLED_STADEF}, + {WNI_CFG_PROP_CAPABILITY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PROP_CAPABILITY_STAMIN, + WNI_CFG_PROP_CAPABILITY_STAMAX, + WNI_CFG_PROP_CAPABILITY_STADEF}, + {WNI_CFG_EDCA_PROFILE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_SCH, + WNI_CFG_EDCA_PROFILE_STAMIN, + WNI_CFG_EDCA_PROFILE_STAMAX, + WNI_CFG_EDCA_PROFILE_STADEF}, + {WNI_CFG_EDCA_ANI_ACBK_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACBE_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACVI_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACVO_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACBK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACBE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACVI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ANI_ACVO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACBK_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACBE_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACVI_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACVO_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACBK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACBE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACVI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_WME_ACVO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACBK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACBE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACVI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_TIT_DEMO_ACVO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_RDET_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_RDET_FLAG_STAMIN, + WNI_CFG_RDET_FLAG_STAMAX, + WNI_CFG_RDET_FLAG_STADEF}, + {WNI_CFG_RADAR_CHANNEL_LIST, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_LOCAL_POWER_CONSTRAINT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMIN, + WNI_CFG_LOCAL_POWER_CONSTRAINT_STAMAX, + WNI_CFG_LOCAL_POWER_CONSTRAINT_STADEF}, + {WNI_CFG_ADMIT_POLICY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_ADMIT_POLICY_STAMIN, + WNI_CFG_ADMIT_POLICY_STAMAX, + WNI_CFG_ADMIT_POLICY_STADEF}, + {WNI_CFG_ADMIT_BWFACTOR, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_ADMIT_BWFACTOR_STAMIN, + WNI_CFG_ADMIT_BWFACTOR_STAMAX, + WNI_CFG_ADMIT_BWFACTOR_STADEF}, + {WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMIN, + WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STAMAX, + WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE_STADEF}, + {WNI_CFG_CHANNEL_BONDING_MODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_CHANNEL_BONDING_MODE_STAMIN, + WNI_CFG_CHANNEL_BONDING_MODE_STAMAX, + WNI_CFG_CHANNEL_BONDING_MODE_STADEF}, + {WNI_CFG_CB_SECONDARY_CHANNEL_STATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMIN, + WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STAMAX, + WNI_CFG_CB_SECONDARY_CHANNEL_STATE_STADEF}, + {WNI_CFG_DYNAMIC_THRESHOLD_ZERO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN, + WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX, + WNI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF}, + {WNI_CFG_DYNAMIC_THRESHOLD_ONE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN, + WNI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX, + WNI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF}, + {WNI_CFG_DYNAMIC_THRESHOLD_TWO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN, + WNI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX, + WNI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF}, + {WNI_CFG_TRIG_STA_BK_SCAN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TRIG_STA_BK_SCAN_STAMIN, + WNI_CFG_TRIG_STA_BK_SCAN_STAMAX, + WNI_CFG_TRIG_STA_BK_SCAN_STADEF}, + {WNI_CFG_DYNAMIC_PROFILE_SWITCHING, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMIN, + WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STAMAX, + WNI_CFG_DYNAMIC_PROFILE_SWITCHING_STADEF}, + {WNI_CFG_SCAN_CONTROL_LIST, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_MIMO_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RELOAD, + WNI_CFG_MIMO_ENABLED_STAMIN, + WNI_CFG_MIMO_ENABLED_STAMAX, + WNI_CFG_MIMO_ENABLED_STADEF}, + {WNI_CFG_BLOCK_ACK_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_BLOCK_ACK_ENABLED_STAMIN, + WNI_CFG_BLOCK_ACK_ENABLED_STAMAX, + WNI_CFG_BLOCK_ACK_ENABLED_STADEF}, + {WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMIN, + WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STAMAX, + WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT_STADEF}, + {WNI_CFG_HT_RX_STBC, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_HT_RX_STBC_STAMIN, + WNI_CFG_HT_RX_STBC_STAMAX, + WNI_CFG_HT_RX_STBC_STADEF}, + {WNI_CFG_HT_CAP_INFO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_HT_CAP_INFO_STAMIN, + WNI_CFG_HT_CAP_INFO_STAMAX, + WNI_CFG_HT_CAP_INFO_STADEF}, + {WNI_CFG_HT_AMPDU_PARAMS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_HT_AMPDU_PARAMS_STAMIN, + WNI_CFG_HT_AMPDU_PARAMS_STAMAX, + WNI_CFG_HT_AMPDU_PARAMS_STADEF}, + {WNI_CFG_SUPPORTED_MCS_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_SAVE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_EXT_HT_CAP_INFO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_EXT_HT_CAP_INFO_STAMIN, + WNI_CFG_EXT_HT_CAP_INFO_STAMAX, + WNI_CFG_EXT_HT_CAP_INFO_STADEF}, + {WNI_CFG_TX_BF_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_TX_BF_CAP_STAMIN, + 4294967295u, + WNI_CFG_TX_BF_CAP_STADEF}, + {WNI_CFG_AS_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_AS_CAP_STAMIN, + WNI_CFG_AS_CAP_STAMAX, + WNI_CFG_AS_CAP_STADEF}, + {WNI_CFG_HT_INFO_FIELD1, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_HT_INFO_FIELD1_STAMIN, + WNI_CFG_HT_INFO_FIELD1_STAMAX, + WNI_CFG_HT_INFO_FIELD1_STADEF}, + {WNI_CFG_HT_INFO_FIELD2, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE | CFG_CTL_NTF_LIM, + WNI_CFG_HT_INFO_FIELD2_STAMIN, + WNI_CFG_HT_INFO_FIELD2_STAMAX, + WNI_CFG_HT_INFO_FIELD2_STADEF}, + {WNI_CFG_HT_INFO_FIELD3, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_SAVE | CFG_CTL_NTF_LIM, + WNI_CFG_HT_INFO_FIELD3_STAMIN, + WNI_CFG_HT_INFO_FIELD3_STAMAX, + WNI_CFG_HT_INFO_FIELD3_STADEF}, + {WNI_CFG_BASIC_MCS_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_SAVE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_CURRENT_MCS_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_SAVE | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_GREENFIELD_CAPABILITY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_GREENFIELD_CAPABILITY_STAMIN, + WNI_CFG_GREENFIELD_CAPABILITY_STAMAX, + WNI_CFG_GREENFIELD_CAPABILITY_STADEF}, + {WNI_CFG_VHT_MAX_MPDU_LENGTH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMIN, + WNI_CFG_VHT_MAX_MPDU_LENGTH_STAMAX, + WNI_CFG_VHT_MAX_MPDU_LENGTH_STADEF}, + {WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMIN, + WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STAMAX, + WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET_STADEF}, + {WNI_CFG_VHT_LDPC_CODING_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_LDPC_CODING_CAP_STAMIN, + WNI_CFG_VHT_LDPC_CODING_CAP_STAMAX, + WNI_CFG_VHT_LDPC_CODING_CAP_STADEF}, + {WNI_CFG_VHT_SHORT_GI_80MHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_SHORT_GI_80MHZ_STAMIN, + WNI_CFG_VHT_SHORT_GI_80MHZ_STAMAX, + WNI_CFG_VHT_SHORT_GI_80MHZ_STADEF}, + {WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMIN, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STAMAX, + WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ_STADEF}, + {WNI_CFG_VHT_TXSTBC, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_TXSTBC_STAMIN, + WNI_CFG_VHT_TXSTBC_STAMAX, + WNI_CFG_VHT_TXSTBC_STADEF}, + {WNI_CFG_VHT_RXSTBC, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_RXSTBC_STAMIN, + WNI_CFG_VHT_RXSTBC_STAMAX, + WNI_CFG_VHT_RXSTBC_STADEF}, + {WNI_CFG_VHT_SU_BEAMFORMER_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMIN, + WNI_CFG_VHT_SU_BEAMFORMER_CAP_STAMAX, + WNI_CFG_VHT_SU_BEAMFORMER_CAP_STADEF}, + {WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMIN, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STAMAX, + WNI_CFG_VHT_SU_BEAMFORMEE_CAP_STADEF}, + {WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMIN, + WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STAMAX, + WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_STADEF}, + {WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMIN, + WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STAMAX, + WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS_STADEF}, + {WNI_CFG_VHT_MU_BEAMFORMER_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMIN, + WNI_CFG_VHT_MU_BEAMFORMER_CAP_STAMAX, + WNI_CFG_VHT_MU_BEAMFORMER_CAP_STADEF}, + {WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMIN, + WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STAMAX, + WNI_CFG_VHT_MU_BEAMFORMEE_CAP_STADEF}, + {WNI_CFG_VHT_TXOP_PS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_TXOP_PS_STAMIN, + WNI_CFG_VHT_TXOP_PS_STAMAX, + WNI_CFG_VHT_TXOP_PS_STADEF}, + {WNI_CFG_VHT_HTC_VHTC_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_HTC_VHTC_CAP_STAMIN, + WNI_CFG_VHT_HTC_VHTC_CAP_STAMAX, + WNI_CFG_VHT_HTC_VHTC_CAP_STADEF}, + {WNI_CFG_VHT_AMPDU_LEN_EXPONENT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMIN, + WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STAMAX, + WNI_CFG_VHT_AMPDU_LEN_EXPONENT_STADEF}, + {WNI_CFG_VHT_LINK_ADAPTATION_CAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMIN, + WNI_CFG_VHT_LINK_ADAPTATION_CAP_STAMAX, + WNI_CFG_VHT_LINK_ADAPTATION_CAP_STADEF}, + {WNI_CFG_VHT_RX_ANT_PATTERN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_RX_ANT_PATTERN_STAMIN, + WNI_CFG_VHT_RX_ANT_PATTERN_STAMAX, + WNI_CFG_VHT_RX_ANT_PATTERN_STADEF}, + {WNI_CFG_VHT_TX_ANT_PATTERN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_TX_ANT_PATTERN_STAMIN, + WNI_CFG_VHT_TX_ANT_PATTERN_STAMAX, + WNI_CFG_VHT_TX_ANT_PATTERN_STADEF}, + {WNI_CFG_VHT_RX_MCS_MAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_RX_MCS_MAP_STAMIN, + WNI_CFG_VHT_RX_MCS_MAP_STAMAX, + WNI_CFG_VHT_RX_MCS_MAP_STADEF}, + {WNI_CFG_VHT_TX_MCS_MAP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_TX_MCS_MAP_STAMIN, + WNI_CFG_VHT_TX_MCS_MAP_STAMAX, + WNI_CFG_VHT_TX_MCS_MAP_STADEF}, + {WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN, + WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX, + WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_STADEF}, + {WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMIN, + WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STAMAX, + WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_STADEF}, + {WNI_CFG_VHT_CHANNEL_WIDTH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_CHANNEL_WIDTH_STAMIN, + WNI_CFG_VHT_CHANNEL_WIDTH_STAMAX, + WNI_CFG_VHT_CHANNEL_WIDTH_STADEF}, + {WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMIN, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STAMAX, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1_STADEF}, + {WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMIN, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STAMAX, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2_STADEF}, + {WNI_CFG_VHT_BASIC_MCS_SET, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_BASIC_MCS_SET_STAMIN, + WNI_CFG_VHT_BASIC_MCS_SET_STAMAX, + WNI_CFG_VHT_BASIC_MCS_SET_STADEF}, + {WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMIN, + WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STAMAX, + WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT_STADEF}, + {WNI_CFG_VHT_SS_UNDER_UTIL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_SS_UNDER_UTIL_STAMIN, + WNI_CFG_VHT_SS_UNDER_UTIL_STAMAX, + WNI_CFG_VHT_SS_UNDER_UTIL_STADEF}, + {WNI_CFG_VHT_40MHZ_UTILIZATION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_40MHZ_UTILIZATION_STAMIN, + WNI_CFG_VHT_40MHZ_UTILIZATION_STAMAX, + WNI_CFG_VHT_40MHZ_UTILIZATION_STADEF}, + {WNI_CFG_VHT_80MHZ_UTILIZATION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_80MHZ_UTILIZATION_STAMIN, + WNI_CFG_VHT_80MHZ_UTILIZATION_STAMAX, + WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF}, + {WNI_CFG_VHT_160MHZ_UTILIZATION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_VHT_80MHZ_UTILIZATION_STADEF, + WNI_CFG_VHT_160MHZ_UTILIZATION_STAMAX, + WNI_CFG_VHT_160MHZ_UTILIZATION_STADEF}, + {WNI_CFG_MAX_AMSDU_LENGTH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_MAX_AMSDU_LENGTH_STAMIN, + WNI_CFG_MAX_AMSDU_LENGTH_STAMAX, + WNI_CFG_MAX_AMSDU_LENGTH_STADEF}, + {WNI_CFG_MPDU_DENSITY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_MPDU_DENSITY_STAMIN, + WNI_CFG_MPDU_DENSITY_STAMAX, + WNI_CFG_MPDU_DENSITY_STADEF}, + {WNI_CFG_NUM_BUFF_ADVERT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_NUM_BUFF_ADVERT_STAMIN, + WNI_CFG_NUM_BUFF_ADVERT_STAMAX, + WNI_CFG_NUM_BUFF_ADVERT_STADEF}, + {WNI_CFG_MAX_RX_AMPDU_FACTOR, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMIN, + WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX, + WNI_CFG_MAX_RX_AMPDU_FACTOR_STAMAX}, + {WNI_CFG_SHORT_GI_20MHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_SHORT_GI_20MHZ_STAMIN, + WNI_CFG_SHORT_GI_20MHZ_STAMAX, + WNI_CFG_SHORT_GI_20MHZ_STADEF}, + {WNI_CFG_SHORT_GI_40MHZ, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_SHORT_GI_40MHZ_STAMIN, + WNI_CFG_SHORT_GI_40MHZ_STAMAX, + WNI_CFG_SHORT_GI_40MHZ_STADEF}, + {WNI_CFG_RIFS_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_RIFS_ENABLED_STAMIN, + WNI_CFG_RIFS_ENABLED_STAMAX, + WNI_CFG_RIFS_ENABLED_STADEF}, + {WNI_CFG_MAX_PS_POLL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_MAX_PS_POLL_STAMIN, + WNI_CFG_MAX_PS_POLL_STAMAX, + WNI_CFG_MAX_PS_POLL_STADEF}, + {WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN, + WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX, + WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF}, + {WNI_CFG_RSSI_FILTER_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_RSSI_FILTER_PERIOD_STAMIN, + WNI_CFG_RSSI_FILTER_PERIOD_STAMAX, + WNI_CFG_RSSI_FILTER_PERIOD_STADEF}, + {WNI_CFG_MIN_RSSI_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_MIN_RSSI_THRESHOLD_STAMIN, + WNI_CFG_MIN_RSSI_THRESHOLD_STAMAX, + WNI_CFG_MIN_RSSI_THRESHOLD_STADEF}, + {WNI_CFG_NTH_BEACON_FILTER, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_NTH_BEACON_FILTER_STAMIN, + WNI_CFG_NTH_BEACON_FILTER_STAMAX, + WNI_CFG_NTH_BEACON_FILTER_STADEF}, + {WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMIN, + WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STAMAX, + WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE_STADEF}, + {WNI_CFG_SCAN_IN_POWERSAVE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_SCAN_IN_POWERSAVE_STAMIN, + WNI_CFG_SCAN_IN_POWERSAVE_STAMAX, + WNI_CFG_SCAN_IN_POWERSAVE_STADEF}, + {WNI_CFG_IGNORE_DTIM, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_IGNORE_DTIM_STAMIN, + WNI_CFG_IGNORE_DTIM_STAMAX, + WNI_CFG_IGNORE_DTIM_STADEF}, + {WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMIN, + WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STAMAX, + WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE_STADEF}, + {WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMIN, + WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STAMAX, + WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE_STADEF}, + {WNI_CFG_WOWLAN_DEAUTH_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMIN, + WNI_CFG_WOWLAN_DEAUTH_ENABLE_STAMAX, + WNI_CFG_WOWLAN_DEAUTH_ENABLE_STADEF}, + {WNI_CFG_WOWLAN_DISASSOC_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMIN, + WNI_CFG_WOWLAN_DISASSOC_ENABLE_STAMAX, + WNI_CFG_WOWLAN_DISASSOC_ENABLE_STADEF}, + {WNI_CFG_WOWLAN_MAX_MISSED_BEACON, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMIN, + WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STAMAX, + WNI_CFG_WOWLAN_MAX_MISSED_BEACON_STADEF}, + {WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMIN, + WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STAMAX, + WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD_STADEF}, + {WNI_CFG_BA_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_HAL, + WNI_CFG_BA_TIMEOUT_STAMIN, + WNI_CFG_BA_TIMEOUT_STAMAX, + WNI_CFG_BA_TIMEOUT_STADEF}, + {WNI_CFG_BA_THRESHOLD_HIGH, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_HAL, + WNI_CFG_BA_THRESHOLD_HIGH_STAMIN, + WNI_CFG_BA_THRESHOLD_HIGH_STAMAX, + WNI_CFG_BA_THRESHOLD_HIGH_STADEF}, + {WNI_CFG_MAX_BA_BUFFERS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_BA_BUFFERS_STAMIN, + WNI_CFG_MAX_BA_BUFFERS_STAMAX, + WNI_CFG_MAX_BA_BUFFERS_STADEF}, + {WNI_CFG_MAX_BA_SESSIONS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_BA_SESSIONS_STAMIN, + WNI_CFG_MAX_BA_SESSIONS_STAMAX, + WNI_CFG_MAX_BA_SESSIONS_STADEF}, + {WNI_CFG_BA_AUTO_SETUP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_HAL, + WNI_CFG_BA_AUTO_SETUP_STAMIN, + WNI_CFG_BA_AUTO_SETUP_STAMAX, + WNI_CFG_BA_AUTO_SETUP_STADEF}, + {WNI_CFG_ADDBA_REQ_DECLINE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_ADDBA_REQ_DECLINE_STAMIN, + WNI_CFG_ADDBA_REQ_DECLINE_STAMAX, + WNI_CFG_ADDBA_REQ_DECLINE_STADEF}, + {WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC_STAMIN, + WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC_STAMAX, + WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC_STADEF}, + {WNI_CFG_BG_SCAN_CHANNEL_LIST, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_MAX_MEDIUM_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_MEDIUM_TIME_STAMIN, + WNI_CFG_MAX_MEDIUM_TIME_STAMAX, + WNI_CFG_MAX_MEDIUM_TIME_STADEF}, + {WNI_CFG_MAX_MPDUS_IN_AMPDU, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN, + WNI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX, + WNI_CFG_MAX_MPDUS_IN_AMPDU_STADEF}, + {WNI_CFG_IBSS_AUTO_BSSID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_IBSS_AUTO_BSSID_STAMIN, + WNI_CFG_IBSS_AUTO_BSSID_STAMAX, + WNI_CFG_IBSS_AUTO_BSSID_STADEF}, + {WNI_CFG_PROBE_REQ_ADDNIE_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMIN, + WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STAMAX, + WNI_CFG_PROBE_REQ_ADDNIE_FLAG_STADEF}, + {WNI_CFG_PROBE_REQ_ADDNIE_DATA, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_PROBE_RSP_ADDNIE_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMIN, + WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STAMAX, + WNI_CFG_PROBE_RSP_ADDNIE_FLAG_STADEF}, + {WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMIN, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STAMAX, + WNI_CFG_ASSOC_RSP_ADDNIE_FLAG_STADEF}, + {WNI_CFG_ASSOC_RSP_ADDNIE_DATA, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMIN, + WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STAMAX, + WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG_STADEF}, + {WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE, + 0, 0, 0}, + {WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMIN, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STAMAX, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG_STADEF}, + {WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_WPS_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_ENABLE_STAMIN, + WNI_CFG_WPS_ENABLE_STAMAX, + WNI_CFG_WPS_ENABLE_STADEF}, + {WNI_CFG_WPS_STATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_STATE_STAMIN, + WNI_CFG_WPS_STATE_STAMAX, + WNI_CFG_WPS_STATE_STADEF}, + {WNI_CFG_WPS_PROBE_REQ_FLAG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_PROBE_REQ_FLAG_STAMIN, + WNI_CFG_WPS_PROBE_REQ_FLAG_STAMAX, + WNI_CFG_WPS_PROBE_REQ_FLAG_STADEF}, + {WNI_CFG_WPS_VERSION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_VERSION_STAMIN, + WNI_CFG_WPS_VERSION_STAMAX, + WNI_CFG_WPS_VERSION_STADEF}, + {WNI_CFG_WPS_REQUEST_TYPE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_REQUEST_TYPE_STAMIN, + WNI_CFG_WPS_REQUEST_TYPE_STAMAX, + WNI_CFG_WPS_REQUEST_TYPE_STADEF}, + {WNI_CFG_WPS_CFG_METHOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_CFG_METHOD_STAMIN, + 4294967295u, + WNI_CFG_WPS_CFG_METHOD_STADEF}, + {WNI_CFG_WPS_UUID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_NTF_LIM, + 0, 0, 0}, + {WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMIN, + WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STAMAX, + WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY_STADEF}, + {WNI_CFG_WPS_PIMARY_DEVICE_OUI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_PIMARY_DEVICE_OUI_STAMIN, + 4294967295u, + WNI_CFG_WPS_PIMARY_DEVICE_OUI_STADEF}, + {WNI_CFG_WPS_DEVICE_SUB_CATEGORY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMIN, + WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STAMAX, + WNI_CFG_WPS_DEVICE_SUB_CATEGORY_STADEF}, + {WNI_CFG_WPS_ASSOCIATION_STATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_ASSOCIATION_STATE_STAMIN, + WNI_CFG_WPS_ASSOCIATION_STATE_STAMAX, + WNI_CFG_WPS_ASSOCIATION_STATE_STADEF}, + {WNI_CFG_WPS_CONFIGURATION_ERROR, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_CONFIGURATION_ERROR_STAMIN, + WNI_CFG_WPS_CONFIGURATION_ERROR_STAMAX, + WNI_CFG_WPS_CONFIGURATION_ERROR_STADEF}, + {WNI_CFG_WPS_DEVICE_PASSWORD_ID, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_DEVICE_PASSWORD_ID_STAMIN, + 4294967295u, + WNI_CFG_WPS_DEVICE_PASSWORD_ID_STADEF}, + {WNI_CFG_WPS_ASSOC_METHOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_WPS_ASSOC_METHOD_STAMIN, + WNI_CFG_WPS_ASSOC_METHOD_STAMAX, + WNI_CFG_WPS_ASSOC_METHOD_STADEF}, + {WNI_CFG_LOW_GAIN_OVERRIDE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_LOW_GAIN_OVERRIDE_STAMIN, + WNI_CFG_LOW_GAIN_OVERRIDE_STAMAX, + WNI_CFG_LOW_GAIN_OVERRIDE_STADEF}, + {WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMIN, + WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STAMAX, + WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE_STADEF}, + {WNI_CFG_RPE_POLLING_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RPE_POLLING_THRESHOLD_STAMIN, + WNI_CFG_RPE_POLLING_THRESHOLD_STAMAX, + WNI_CFG_RPE_POLLING_THRESHOLD_STADEF}, + {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF}, + {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF}, + {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF}, + {WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX, + WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF}, + {WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN, + WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX, + WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF}, + {WNI_CFG_SINGLE_TID_RC, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SINGLE_TID_RC_STAMIN, + WNI_CFG_SINGLE_TID_RC_STAMAX, + WNI_CFG_SINGLE_TID_RC_STADEF}, + {WNI_CFG_RRM_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_RRM_ENABLED_STAMIN, + WNI_CFG_RRM_ENABLED_STAMAX, + WNI_CFG_RRM_ENABLED_STADEF}, + {WNI_CFG_RRM_OPERATING_CHAN_MAX, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMIN, + WNI_CFG_RRM_OPERATING_CHAN_MAX_STAMAX, + WNI_CFG_RRM_OPERATING_CHAN_MAX_STADEF}, + {WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMIN, + WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STAMAX, + WNI_CFG_RRM_NON_OPERATING_CHAN_MAX_STADEF}, + {WNI_CFG_TX_PWR_CTRL_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_TX_PWR_CTRL_ENABLE_STAMIN, + WNI_CFG_TX_PWR_CTRL_ENABLE_STAMAX, + WNI_CFG_TX_PWR_CTRL_ENABLE_STADEF}, + {WNI_CFG_MCAST_BCAST_FILTER_SETTING, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN, + WNI_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX, + WNI_CFG_MCAST_BCAST_FILTER_SETTING_STADEF}, + {WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMIN, + WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STAMAX, + WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_STADEF}, + {WNI_CFG_DYNAMIC_PS_POLL_VALUE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN, + WNI_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX, + WNI_CFG_DYNAMIC_PS_POLL_VALUE_STADEF}, + {WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN, + WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX, + WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF}, + {WNI_CFG_TELE_BCN_WAKEUP_EN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_TELE_BCN_WAKEUP_EN_STAMIN, + WNI_CFG_TELE_BCN_WAKEUP_EN_STAMAX, + WNI_CFG_TELE_BCN_WAKEUP_EN_STADEF}, + {WNI_CFG_TELE_BCN_TRANS_LI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_TELE_BCN_TRANS_LI_STAMIN, + WNI_CFG_TELE_BCN_TRANS_LI_STAMAX, + WNI_CFG_TELE_BCN_TRANS_LI_STADEF}, + {WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN, + WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX, + WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF}, + {WNI_CFG_TELE_BCN_MAX_LI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_TELE_BCN_MAX_LI_STAMIN, + WNI_CFG_TELE_BCN_MAX_LI_STAMAX, + WNI_CFG_TELE_BCN_MAX_LI_STADEF}, + {WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN, + WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX, + WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF}, + {WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMIN, + WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STAMAX, + WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_STADEF}, + {WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN, + WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX, + WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF}, + {WNI_CFG_ASSOC_STA_LIMIT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_ASSOC_STA_LIMIT_STAMIN, + WNI_CFG_ASSOC_STA_LIMIT_STAMAX, + WNI_CFG_ASSOC_STA_LIMIT_STADEF}, + {WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN, + WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX, + WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STADEF}, + {WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN, + WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX, + WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STADEF}, + {WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN, + WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX, + WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STADEF}, + {WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMIN, + WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STAMAX, + WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD_STADEF}, + {WNI_CFG_ENABLE_CLOSE_LOOP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_CLOSE_LOOP_STAMIN, + WNI_CFG_ENABLE_CLOSE_LOOP_STAMAX, + WNI_CFG_ENABLE_CLOSE_LOOP_STADEF}, + {WNI_CFG_ENABLE_LTE_COEX, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_LTE_COEX_STAMIN, + WNI_CFG_ENABLE_LTE_COEX_STAMAX, + WNI_CFG_ENABLE_LTE_COEX_STADEF}, + {WNI_CFG_AP_KEEP_ALIVE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMIN, + WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STAMAX, + WNI_CFG_AP_KEEP_ALIVE_TIMEOUT_STADEF}, + {WNI_CFG_GO_KEEP_ALIVE_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMIN, + WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STAMAX, + WNI_CFG_GO_KEEP_ALIVE_TIMEOUT_STADEF}, + {WNI_CFG_ENABLE_MC_ADDR_LIST, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_MC_ADDR_LIST_STAMIN, + WNI_CFG_ENABLE_MC_ADDR_LIST_STAMAX, + WNI_CFG_ENABLE_MC_ADDR_LIST_STADEF}, + {WNI_CFG_ENABLE_UC_FILTER, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_UC_FILTER_STAMIN, + WNI_CFG_ENABLE_UC_FILTER_STAMAX, + WNI_CFG_ENABLE_UC_FILTER_STADEF}, + {WNI_CFG_ENABLE_LPWR_IMG_TRANSITION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMIN, + WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STAMAX, + WNI_CFG_ENABLE_LPWR_IMG_TRANSITION_STADEF}, + {WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMIN, + WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STAMAX, + WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED_STADEF}, + {WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMIN, + WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STAMAX, + WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP_STADEF}, + {WNI_CFG_AP_LINK_MONITOR_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMIN, + WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STAMAX, + WNI_CFG_AP_LINK_MONITOR_TIMEOUT_STADEF}, + {WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMIN, + WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STAMAX, + WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK_STADEF}, + {WNI_CFG_TDLS_BUF_STA_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TDLS_BUF_STA_ENABLED_STAMIN, + WNI_CFG_TDLS_BUF_STA_ENABLED_STAMAX, + WNI_CFG_TDLS_BUF_STA_ENABLED_STADEF}, + {WNI_CFG_TDLS_PUAPSD_INACT_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMIN, + WNI_CFG_TDLS_PUAPSD_INACT_TIME_STAMAX, + WNI_CFG_TDLS_PUAPSD_INACT_TIME_STADEF}, + {WNI_CFG_TDLS_RX_FRAME_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMIN, + WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STAMAX, + WNI_CFG_TDLS_RX_FRAME_THRESHOLD_STADEF}, + {WNI_CFG_ENABLE_ADAPT_RX_DRAIN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMIN, + WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STAMAX, + WNI_CFG_ENABLE_ADAPT_RX_DRAIN_STADEF}, + {WNI_CFG_FLEX_CONNECT_POWER_FACTOR, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMIN, + WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STAMAX, + WNI_CFG_FLEX_CONNECT_POWER_FACTOR_STADEF}, + {WNI_CFG_ANTENNA_DIVESITY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ANTENNA_DIVESITY_STAMIN, + WNI_CFG_ANTENNA_DIVESITY_STAMAX, + WNI_CFG_ANTENNA_DIVESITY_STADEF}, + {WNI_CFG_GO_LINK_MONITOR_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMIN, + WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STAMAX, + WNI_CFG_GO_LINK_MONITOR_TIMEOUT_STADEF}, + {WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMIN, + WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STAMAX, + WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY_STADEF}, + + {WNI_CFG_ATH_DISABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ATH_DISABLE_STAMIN, + WNI_CFG_ATH_DISABLE_STAMAX, + WNI_CFG_ATH_DISABLE_STADEF}, + {WNI_CFG_BTC_ACTIVE_WLAN_LEN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_ACTIVE_WLAN_LEN_STAMIN, + WNI_CFG_BTC_ACTIVE_WLAN_LEN_STAMAX, + WNI_CFG_BTC_ACTIVE_WLAN_LEN_STADEF}, + {WNI_CFG_BTC_ACTIVE_BT_LEN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_ACTIVE_BT_LEN_STAMIN, + WNI_CFG_BTC_ACTIVE_BT_LEN_STAMAX, + WNI_CFG_BTC_ACTIVE_BT_LEN_STADEF}, + {WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN_STAMIN, + WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN_STAMAX, + WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN_STADEF}, + {WNI_CFG_BTC_SAP_ACTIVE_BT_LEN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMIN, + WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STAMAX, + WNI_CFG_BTC_SAP_ACTIVE_BT_LEN_STADEF}, + {WNI_CFG_ASD_PROBE_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ASD_PROBE_INTERVAL_STAMIN, + WNI_CFG_ASD_PROBE_INTERVAL_STAMAX, + WNI_CFG_ASD_PROBE_INTERVAL_STADEF}, + {WNI_CFG_ASD_TRIGGER_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMIN, + WNI_CFG_ASD_TRIGGER_THRESHOLD_STAMAX, + WNI_CFG_ASD_TRIGGER_THRESHOLD_STADEF}, + {WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMIN, + WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STAMAX, + WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_STADEF}, + {WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMIN, + WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STAMAX, + WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL_STADEF}, + {WNI_CFG_BTC_CTS2S_DURING_SCO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_CTS2S_DURING_SCO_STAMIN, + WNI_CFG_BTC_CTS2S_DURING_SCO_STAMAX, + WNI_CFG_BTC_CTS2S_DURING_SCO_STADEF}, + {WNI_CFG_CHANNEL_BONDING_24G, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART | CFG_CTL_NTF_LIM, + WNI_CFG_CHANNEL_BONDING_24G_STAMIN, + WNI_CFG_CHANNEL_BONDING_24G_STAMAX, + WNI_CFG_CHANNEL_BONDING_24G_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STADEF}, + {WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STAMIN, + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STAMAX, + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STADEF}, + {WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX, + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STADEF}, + {WNI_CFG_TDLS_OFF_CHANNEL_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMIN, + WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STAMAX, + WNI_CFG_TDLS_OFF_CHANNEL_ENABLED_STADEF}, + {WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMIN, + WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STAMAX, + WNI_CFG_PMF_SA_QUERY_MAX_RETRIES_STADEF}, + {WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_RESTART, + WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN, + WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMAX, + WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF}, + {WNI_CFG_RA_FILTER_ENABLE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RA_FILTER_ENABLE_STAMIN, + WNI_CFG_RA_FILTER_ENABLE_STAMAX, + WNI_CFG_RA_FILTER_ENABLE_STADEF}, + {WNI_CFG_RA_RATE_LIMIT_INTERVAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMIN, + WNI_CFG_RA_RATE_LIMIT_INTERVAL_STAMAX, + WNI_CFG_RA_RATE_LIMIT_INTERVAL_STADEF}, + {WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STAMIN, + WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STAMAX, + WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE_STADEF}, + {WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_STAMIN, + WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_STAMAX, + WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE_STADEF}, + {WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_STAMIN, + WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_STAMAX, + WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD_STADEF}, + {WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_STAMIN, + WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_STAMAX, + WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD_STADEF}, + {WNI_CFG_TDLS_WMM_MODE_ENABLED, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_LIM, + WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMIN, + WNI_CFG_TDLS_WMM_MODE_ENABLED_STAMAX, + WNI_CFG_TDLS_WMM_MODE_ENABLED_STADEF}, + + + {WNI_CFG_MAX_UAPSD_CONSEC_SP, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_UAPSD_CONSEC_SP_STAMIN, + WNI_CFG_MAX_UAPSD_CONSEC_SP_STAMAX, + WNI_CFG_MAX_UAPSD_CONSEC_SP_STADEF}, + {WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_STAMIN, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_STAMAX, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_STADEF}, + {WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_STAMIN, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_STAMAX, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_STADEF}, + {WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_STAMIN, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_STAMAX, + WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_STADEF}, + {WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_STAMIN, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_STAMAX, + WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_STADEF}, + {WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_STAMIN, + WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_STAMAX, + WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_STADEF}, + {WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_STAMIN, + WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_STAMAX, + WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_STADEF}, + {WNI_CFG_ENABLE_DYNAMIC_WMMPS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_DYNAMIC_WMMPS_STAMIN, + WNI_CFG_ENABLE_DYNAMIC_WMMPS_STAMAX, + WNI_CFG_ENABLE_DYNAMIC_WMMPS_STADEF}, + {WNI_CFG_BURST_MODE_BE_TXOP_VALUE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BURST_MODE_BE_TXOP_VALUE_STAMIN, + WNI_CFG_BURST_MODE_BE_TXOP_VALUE_STAMAX, + WNI_CFG_BURST_MODE_BE_TXOP_VALUE_STADEF}, + {WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE_STAMIN, + WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE_STAMAX, + WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE_STADEF}, + {WNI_CFG_BTC_FAST_WLAN_CONN_PREF, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_FAST_WLAN_CONN_PREF_STAMIN, + WNI_CFG_BTC_FAST_WLAN_CONN_PREF_STAMAX, + WNI_CFG_BTC_FAST_WLAN_CONN_PREF_STADEF}, + {WNI_CFG_ENABLE_RTSCTS_HTVHT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_RTSCTS_HTVHT_MIN, + WNI_CFG_ENABLE_RTSCTS_HTVHT_MAX, + WNI_CFG_ENABLE_RTSCTS_HTVHT_DEF}, + {WNI_CFG_TOGGLE_ARP_BDRATES, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_TOGGLE_ARP_BDRATES_MIN, + WNI_CFG_TOGGLE_ARP_BDRATES_MAX, + WNI_CFG_TOGGLE_ARP_BDRATES_DEF}, + {WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MIN, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MAX, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_DEF}, + {WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MIN, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX, + WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEF}, + {WNI_CFG_LINK_FAIL_TIMEOUT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_LINK_FAIL_TIMEOUT_MIN, + WNI_CFG_LINK_FAIL_TIMEOUT_MAX, + WNI_CFG_LINK_FAIL_TIMEOUT_DEF}, + {WNI_CFG_LINK_FAIL_TX_CNT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_LINK_FAIL_TX_CNT_MIN, + WNI_CFG_LINK_FAIL_TX_CNT_MAX, + WNI_CFG_LINK_FAIL_TX_CNT_DEF}, + {WNI_CFG_OPTIMIZE_CA_EVENT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_OPTIMIZE_CA_EVENT_DISABLE, + WNI_CFG_OPTIMIZE_CA_EVENT_ENABLE, + WNI_CFG_OPTIMIZE_CA_EVENT_DEFAULT}, + {WNI_CFG_ACTIVE_PASSIVE_CON, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ACTIVE_PASSIVE_CON_MIN, + WNI_CFG_ACTIVE_PASSIVE_CON_MAX, + WNI_CFG_ACTIVE_PASSIVE_CON_DEF}, + {WNI_CFG_EXT_SCAN_CONC_MODE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_EXT_SCAN_CONC_MODE_MIN, + WNI_CFG_EXT_SCAN_CONC_MODE_MAX, + WNI_CFG_EXT_SCAN_CONC_MODE_DEF}, + {WNI_CFG_ENABLE_MAC_ADDR_SPOOFING, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_ENABLE_MAC_ADDR_SPOOFING_MIN, + WNI_CFG_ENABLE_MAC_ADDR_SPOOFING_MAX, + WNI_CFG_ENABLE_MAC_ADDR_SPOOFING_DEF}, + {WNI_CFG_DISABLE_BAR_WAKE_UP_HOST, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_DISABLE_BAR_WAKE_UP_HOST_MIN, + WNI_CFG_DISABLE_BAR_WAKE_UP_HOST_MAX, + WNI_CFG_DISABLE_BAR_WAKE_UP_HOST_DEF}, + {WNI_CFG_SAR_BOFFSET_SET_CORRECTION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_SAR_BOFFSET_SET_CORRECTION_MIN, + WNI_CFG_SAR_BOFFSET_SET_CORRECTION_MAX, + WNI_CFG_SAR_BOFFSET_SET_CORRECTION_DEFAULT}, + {WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN, + WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX, + WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEF}, + {WNI_CFG_DISABLE_SCAN_DURING_SCO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT | CFG_CTL_NTF_HAL, + WNI_CFG_DISABLE_SCAN_DURING_SCO_MIN, + WNI_CFG_DISABLE_SCAN_DURING_SCO_MAX, + WNI_CFG_DISABLE_SCAN_DURING_SCO_DEF}, + {WNI_CFG_ENABLE_CONC_BMISS, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_CONC_BMISS_STAMIN, + WNI_CFG_ENABLE_CONC_BMISS_STAMAX, + WNI_CFG_ENABLE_CONC_BMISS_STADEF}, + {WNI_CFG_ENABLE_UNITS_BWAIT, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_UNITS_BWAIT_STAMIN, + WNI_CFG_ENABLE_UNITS_BWAIT_STAMAX, + WNI_CFG_ENABLE_UNITS_BWAIT_STADEF}, + {WNI_CFG_ENABLE_TX_RX_AGGREGATION, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_ENABLE_TX_RX_AGGREGATION_MIN, + WNI_CFG_ENABLE_TX_RX_AGGREGATION_MAX, + WNI_CFG_ENABLE_TX_RX_AGGREGATION_DEF}, + {WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MIN, + WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_MAX, + WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB_DEF}, +}; + +tAniSirCfgStaticString cfgStaticString[CFG_MAX_STATIC_STRING] = +{ + +{WNI_CFG_STA_ID, + WNI_CFG_STA_ID_LEN, + 6, + {0x22, 0x22, 0x44, 0x44, 0x33, 0x33}}, +{WNI_CFG_SSID, + WNI_CFG_SSID_LEN, + 10, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}}, +{WNI_CFG_WEP_DEFAULT_KEY_1, + WNI_CFG_WEP_DEFAULT_KEY_1_LEN, + 0, + {0}}, +{WNI_CFG_WEP_DEFAULT_KEY_2, + WNI_CFG_WEP_DEFAULT_KEY_2_LEN, + 0, + {0}}, +{WNI_CFG_WEP_DEFAULT_KEY_3, + WNI_CFG_WEP_DEFAULT_KEY_3_LEN, + 0, + {0}}, +{WNI_CFG_WEP_DEFAULT_KEY_4, + WNI_CFG_WEP_DEFAULT_KEY_4_LEN, + 0, + {0}}, +{WNI_CFG_SUPPORTED_RATES_11B, + WNI_CFG_SUPPORTED_RATES_11B_LEN, + 4, + {2, 4, 11, 22}}, +{WNI_CFG_SUPPORTED_RATES_11A, + WNI_CFG_SUPPORTED_RATES_11A_LEN, + 8, + {12, 18, 24, 36, 48, 72, 96, 108}}, +{WNI_CFG_OPERATIONAL_RATE_SET, + WNI_CFG_OPERATIONAL_RATE_SET_LEN, + 0, + {0}}, +{WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN, + 0, + {0}}, +{WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN, + 4, + {1, 3, 5, 7}}, +{WNI_CFG_BSSID, + WNI_CFG_BSSID_LEN, + 6, + {0x22, 0x22, 0x11, 0x11, 0x33, 0x33}}, +{WNI_CFG_VALID_CHANNEL_LIST, + WNI_CFG_VALID_CHANNEL_LIST_LEN, + 55, +{36, 40, 44, 48, 52, 56, 60, 64, 1, 6, 11, 34, 38, 42, 46, 2, 3, 4, 5, 7, 8, + 9, 10, 12, 13, 14, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + 149, 151, 153, 155, 157, 159, 161, 50, 54, 58, 62, 240, 242, 244, 246, 248, + 250, 252}}, + +{WNI_CFG_MANUFACTURER_OUI, + WNI_CFG_MANUFACTURER_OUI_LEN, + 3, + {0x0, 0xa, 0xf5}}, +{WNI_CFG_MANUFACTURER_NAME, + WNI_CFG_MANUFACTURER_NAME_LEN, + 8, + {0x51, 0x75, 0x61, 0x6c, 0x63, 0x6f, 0x6d, 0x6d}}, +{WNI_CFG_MODEL_NUMBER, + WNI_CFG_MODEL_NUMBER_LEN, + 6, + {0x4d, 0x4e, 0x31, 0x32, 0x33, 0x34}}, +{WNI_CFG_MODEL_NAME, + WNI_CFG_MODEL_NAME_LEN, + 7, + {0x57, 0x46, 0x52, 0x34, 0x30, 0x33, 0x31}}, +{WNI_CFG_MANUFACTURER_PRODUCT_NAME, + WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN, + 6, + {0x31, 0x31, 0x6e, 0x2d, 0x41, 0x50}}, +{WNI_CFG_MANUFACTURER_PRODUCT_VERSION, + WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN, + 6, + {0x53, 0x4e, 0x31, 0x32, 0x33, 0x34}}, +{WNI_CFG_MAX_TX_POWER_2_4, + WNI_CFG_MAX_TX_POWER_2_4_LEN, + 3, + {0x1, 0xe, 0x14}}, +{WNI_CFG_MAX_TX_POWER_5, + WNI_CFG_MAX_TX_POWER_5_LEN, + 3, + {0x24, 0x7e, 0x14}}, +{WNI_CFG_AP_NODE_NAME, + WNI_CFG_AP_NODE_NAME_LEN, + 0, + {0}}, +{WNI_CFG_COUNTRY_CODE, + WNI_CFG_COUNTRY_CODE_LEN, + 0, + {0}}, +{WNI_CFG_EDCA_ANI_ACBK_LOCAL, + WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN, + 17, + {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0}}, +{WNI_CFG_EDCA_ANI_ACBE_LOCAL, + WNI_CFG_EDCA_ANI_ACBE_LOCAL_LEN, + 17, + {0x0, 0x2, 0x0, 0xf, 0x3, 0xff, 0x64, 0x0, 0x1f, 0x3, 0xff, 0x64, 0x0, 0xf, 0x3, 0xff, 0x64}}, +{WNI_CFG_EDCA_ANI_ACVI_LOCAL, + WNI_CFG_EDCA_ANI_ACVI_LOCAL_LEN, + 17, + {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0xc8, 0x0, 0xf, 0x0, 0x1f, 0xbc, 0x0, 0x7, 0x0, 0xf, 0xc8}}, +{WNI_CFG_EDCA_ANI_ACVO_LOCAL, + WNI_CFG_EDCA_ANI_ACVO_LOCAL_LEN, + 17, + {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x64, 0x0, 0x7, 0x0, 0xf, 0x66, 0x0, 0x3, 0x0, 0x7, 0x64}}, +{WNI_CFG_EDCA_ANI_ACBK, + WNI_CFG_EDCA_ANI_ACBK_LEN, + 17, + {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0}}, +{WNI_CFG_EDCA_ANI_ACBE, + WNI_CFG_EDCA_ANI_ACBE_LEN, + 17, + {0x0, 0x2, 0x0, 0xf, 0x3, 0xff, 0x64, 0x0, 0x1f, 0x3, 0xff, 0x64, 0x0, 0xf, 0x3, 0xff, 0x64}}, +{WNI_CFG_EDCA_ANI_ACVI, + WNI_CFG_EDCA_ANI_ACVI_LEN, + 17, + {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0xc8, 0x0, 0xf, 0x0, 0x1f, 0xbc, 0x0, 0x7, 0x0, 0xf, 0xc8}}, +{WNI_CFG_EDCA_ANI_ACVO, + WNI_CFG_EDCA_ANI_ACVO_LEN, + 17, + {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x64, 0x0, 0x7, 0x0, 0xf, 0x66, 0x0, 0x3, 0x0, 0x7, 0x64}}, +{WNI_CFG_EDCA_WME_ACBK_LOCAL, + WNI_CFG_EDCA_WME_ACBK_LOCAL_LEN, + 17, + {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0}}, +{WNI_CFG_EDCA_WME_ACBE_LOCAL, + WNI_CFG_EDCA_WME_ACBE_LOCAL_LEN, + 17, + {0x0, 0x3, 0x0, 0xf, 0x0, 0x3f, 0x0, 0x0, 0x1f, 0x3, 0xff,0x0, 0x0, 0xf, 0x0, 0x3f, 0x0}}, +{WNI_CFG_EDCA_WME_ACVI_LOCAL, + WNI_CFG_EDCA_WME_ACVI_LOCAL_LEN, + 17, + {0x0, 0x1, 0x0, 0x7, 0x0, 0xf, 0x5e, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7, 0x0, 0xf, 0x5e}}, +{WNI_CFG_EDCA_WME_ACVO_LOCAL, + WNI_CFG_EDCA_WME_ACVO_LOCAL_LEN, + 17, + {0x0, 0x1, 0x0, 0x3, 0x0, 0x7, 0x2f, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3, 0x0, 0x7, 0x2f}}, +{WNI_CFG_EDCA_WME_ACBK, + WNI_CFG_EDCA_WME_ACBK_LEN, + 17, + {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0}}, +{WNI_CFG_EDCA_WME_ACBE, + WNI_CFG_EDCA_WME_ACBE_LEN, + 17, + {0x0, 0x3, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, 0xf, 0x3, 0xff, 0x0}}, +{WNI_CFG_EDCA_WME_ACVI, + WNI_CFG_EDCA_WME_ACVI_LEN, + 17, + {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0x5e, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, 0x7, 0x0, 0xf, 0x5e}}, +{WNI_CFG_EDCA_WME_ACVO, + WNI_CFG_EDCA_WME_ACVO_LEN, + 17, + {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x2f, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, 0x3, 0x0, 0x7, 0x2f}}, +{WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL_LEN, + 17, + {0x0, 0x7, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x1f, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL_LEN, + 17, + {0x0, 0x2, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x1f, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL_LEN, + 17, + {0x0, 0x2, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL_LEN, + 17, + {0x0, 0x2, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACBK, + WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL_LEN, + 17, + {0x0, 0x7, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0,0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACBE, + WNI_CFG_EDCA_TIT_DEMO_ACBE_LEN, + 17, + {0x0, 0x2, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACVI, + WNI_CFG_EDCA_TIT_DEMO_ACVI_LEN, + 17, + {0x0, 0x2, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_EDCA_TIT_DEMO_ACVO, + WNI_CFG_EDCA_TIT_DEMO_ACVO_LEN, + 17, + {0x0, 0x2, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8, 0x0, 0x8, 0x0, 0xff, 0xc8}}, +{WNI_CFG_RADAR_CHANNEL_LIST, + WNI_CFG_RADAR_CHANNEL_LIST_LEN, + 15, + {0x34, 0x38, 0x3c, 0x40, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x84, 0x88, 0x8c}}, +{WNI_CFG_SCAN_CONTROL_LIST, + WNI_CFG_SCAN_CONTROL_LIST_LEN, + 114, + {0x1, 0x1, 0x2, 0x1, 0x3, 0x1, 0x4, 0x1, 0x5, 0x1, 0x6, 0x1, 0x7, 0x1, 0x8, + 0x1, 0x9,0x1, 0xa, 0x1, 0xb, 0x1, 0xc, 0x1, 0xd, 0x1, 0xe, 0x1, 0x22, 0x1, + 0x24, 0x1, 0x26, 0x1, 0x28,0x1, 0x2a, 0x1, 0x2c, 0x1, 0x2e, 0x1, 0x30, 0x1, + 0x32, 0x1, 0x34, 0x0, 0x36, 0x0, 0x38, 0x0,0x3a, 0x0, 0x3c, 0x0, 0x3e, 0x0, + 0x40, 0x0, 0x64, 0x0, 0x68, 0x0, 0x6c, 0x0, 0x70, 0x0, 0x74,0x0, 0x78, 0x0, + 0x7c, 0x0, 0x80, 0x0, 0x84, 0x0, 0x88, 0x0, 0x8c, 0x0, 0x90, 0x0,0x95, 0x1, + 0x97, 0x1, 0x99, 0x1, 0x9b, 0x1, 0x9d, 0x1, 0x9f, 0x1, 0xa1, 0x1,0xa5, 0x1, + 0xf0, 0x1, 0xf2, 0x1, 0xf4, 0x1, 0xf6, 0x1, 0xf8, 0x1, 0xfa, 0x1, 0xfc, 0x1}}, +{WNI_CFG_SUPPORTED_MCS_SET, + WNI_CFG_SUPPORTED_MCS_SET_LEN, + 16, + {0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, +{WNI_CFG_BASIC_MCS_SET, + WNI_CFG_BASIC_MCS_SET_LEN, + 16, + {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, +{WNI_CFG_CURRENT_MCS_SET, + WNI_CFG_CURRENT_MCS_SET_LEN, + 16, + {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, +{WNI_CFG_BG_SCAN_CHANNEL_LIST, + WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN, + 55, + {0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c,0x40, 0x1, 0x6, 0xb, 0x22, 0x26, + 0x2a, 0x2e, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8, 0x9, 0xa, 0xc, 0xd, 0xe, 0x64, + 0x68, 0x6c, 0x70, 0x74,0x78, 0x7c, 0x80, 0x84, 0x88, 0x8c, 0x95, 0x97, + 0x99, 0x9b, 0x9d, 0x9f, 0xa1, 0x32, 0x36,0x3a, 0x3e, 0xf0, 0xf2, 0xf4, + 0xf6, 0xf8, 0xfa, 0xfc}}, +{WNI_CFG_PROBE_REQ_ADDNIE_DATA, + WNI_CFG_PROBE_REQ_ADDNIE_DATA_LEN, + 0, + {0}}, +{WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN, + 0, + {0}}, +{WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN, + 0, + {0}}, +{WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN, + 0, + {0}}, +{WNI_CFG_ASSOC_RSP_ADDNIE_DATA, + WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN, + 0, + {0}}, +{WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA, + WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA_LEN, + 0, + {0}}, +{WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN, + 0, + {0}}, +{WNI_CFG_WPS_UUID, + WNI_CFG_WPS_UUID_LEN, + 6, + {0xa, 0xb, 0xc, 0xd, 0xe, 0xf}} +}; + +/*--------------------------------------------------------------------*/ +/* Static function prototypes */ +/*--------------------------------------------------------------------*/ +static void ProcDnldRsp (tpAniSirGlobal, tANI_U16, tANI_U32*); +static void ProcGetReq (tpAniSirGlobal, tANI_U16, tANI_U32*); +static void ProcSetReq (tpAniSirGlobal, tANI_U16, tANI_U32*); +static void ProcSetReqNoRsp (tpAniSirGlobal, tANI_U16, tANI_U32*); + +static tANI_U8 CheckParam(tpAniSirGlobal, tANI_U16, tANI_U32, tANI_U32, tANI_U32*); +static void GetStrValue(tANI_U8*, tANI_U8*, tANI_U32); + + +/*--------------------------------------------------------------------*/ +/* Module global variables */ +/*--------------------------------------------------------------------*/ + +// CFG function table +void (*gCfgFunc[])(tpAniSirGlobal, tANI_U16, tANI_U32*) = +{ ProcDnldRsp, + ProcGetReq, + ProcSetReq, + ProcSetReqNoRsp +}; + +/**--------------------------------------------------------------------- + * cfgProcessMbMsg() + * + *FUNCTION: + * CFG mailbox message processing function. + * + *LOGIC: + * + *ASSUMPTIONS: + * None. + * + *NOTE: + * + * @param pMsg Message pointer + * + * @return None. + * + */ +void +cfgProcessMbMsg(tpAniSirGlobal pMac, tSirMbMsg *pMsg) +{ + tANI_U16 index; + tANI_U16 len; + tANI_U32 *pParam; + + // Use type[7:0] as index to function table + index = CFG_GET_FUNC_INDX(pMsg->type); + + if (index >= (sizeof(gCfgFunc) / sizeof(gCfgFunc[0]))) + { + vos_mem_free(pMsg); + return; + } + len = pMsg->msgLen - WNI_CFG_MB_HDR_LEN; + pParam = ((tANI_U32*)pMsg) + 1; + + // Call processing function + gCfgFunc[index](pMac, len, pParam); + + // Free up buffer + vos_mem_free(pMsg); + +} /*** end cfgProcessMbMsg() ***/ + +/**--------------------------------------------------------------------- + * ProcDnldRsp() + * + * FUNCTION: + * This function processes CFG_DNLD_RSP message from host. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param length: message length + * @param pParam: parameter list pointer + * + * @return None + * + */ +static void +ProcDnldRsp(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + tANI_S32 i; + + tANI_U32 expLen, retVal, bufStart, bufEnd; + tANI_U32 *pSrc, *pDst, *pDstEnd; + tANI_U32 strSize, j; + tANI_U8 pStr[CFG_MAX_STR_LEN]; + tpCfgBinHdr pHdr; + tANI_U32 logLevel; + tSirMsgQ mmhMsg; + tANI_U32 paramList[WNI_CFG_DNLD_CNF_NUM]; + + // First Dword must contain the AP or STA magic dword + PELOGW(cfgLog(pMac, LOGW, FL("CFG size %d bytes MAGIC dword is 0x%x"), + length, sirReadU32N((tANI_U8*)pParam) );) + + // if the string is not correct, return failure + if (*pParam == CFG_STA_MAGIC_DWORD) {} + + + + + else + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid magic dword 0x%x"),sirReadU32N((tANI_U8*)pParam) );) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + pParam++; + length -= 4; + + // Verify message length + { + pMac->cfg.gCfgMaxIBufSize = CFG_STA_IBUF_MAX_SIZE; + pMac->cfg.gCfgMaxSBufSize = CFG_STA_SBUF_MAX_SIZE; + } + + // Parse the Cfg header + pHdr = (tpCfgBinHdr) pParam; + pParam += (sizeof(tCfgBinHdr) >> 2); + PELOGW(cfgLog(pMac, LOGW, FL("CFG hdr totParams %d intParams %d strBufSize %d/%d"), + pHdr->controlSize, pHdr->iBufSize, pHdr->sBufSize, pMac->cfg.gCfgMaxSBufSize);) + + expLen = ((CFG_PARAM_MAX_NUM + 3 * pMac->cfg.gCfgMaxIBufSize) << 2) + + pHdr->sBufSize + sizeof(tCfgBinHdr); + + if (length != expLen) + { + PELOGE(cfgLog(pMac, LOGE, FL(" DNLD_RSP invalid length %d (exp %d)"), + length, expLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + + if (pHdr->controlSize != CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL(" Total parameter count mismatch"));) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + if (pHdr->iBufSize != pMac->cfg.gCfgMaxIBufSize) + { + PELOGE(cfgLog(pMac, LOGE, FL(" Integer parameter count mismatch"));) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + + // Copy control array + pDst = (tANI_U32*)pMac->cfg.gCfgEntry; + pDstEnd = pDst + CFG_PARAM_MAX_NUM; + pSrc = pParam; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + // Copy default values + pDst = pMac->cfg.gCfgIBuf; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy min values + pDst = pMac->cfg.gCfgIBufMin; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + // Copy max values + pDst = pMac->cfg.gCfgIBufMax; + pDstEnd = pDst + pMac->cfg.gCfgMaxIBufSize; + while (pDst < pDstEnd) + { + *pDst++ = *pSrc++; + } + + for (i=0; icfg.gCfgMaxIBufSize; i++) + if (pMac->cfg.gCfgIBuf[i] < pMac->cfg.gCfgIBufMin[i] || + pMac->cfg.gCfgIBuf[i] > pMac->cfg.gCfgIBufMax[i]) + { + PELOGE(cfgLog(pMac, LOGE, FL("cfg id %d Invalid def value %d " + "min %d max %d"), + i, pMac->cfg.gCfgIBuf[i], pMac->cfg.gCfgIBufMin[i], + pMac->cfg.gCfgIBufMax[i]);) + } + + // Calculate max string buffer lengths for all string parameters + bufEnd = pMac->cfg.gCfgMaxSBufSize; + for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) + { + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) + continue; + + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0) + continue; + + bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK; + pMac->cfg.gCfgSBuf[bufStart] = (tANI_U8)(bufEnd - bufStart - 2); + + PELOG1(cfgLog(pMac, LOG1, FL("id %d max %d bufStart %d bufEnd %d"), + i, pMac->cfg.gCfgSBuf[bufStart], bufStart, bufEnd);) + + bufEnd = bufStart; + } + + // Initialize string defaults + strSize = pHdr->sBufSize; + while (strSize) + { + tANI_U32 paramId, paramLen, paramLenCeil4; + + if (strSize < 4) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error parsing str defaults, rem %d bytes"), strSize);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + paramId = *pSrc >> 16; + paramLen = *pSrc & 0xff; + pSrc++; + strSize -= 4; + + paramLenCeil4 = ((paramLen + 3) >> 2); + if (strSize < paramLenCeil4 << 2) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error parsing str defaults, rem %d bytes"), strSize);) + PELOGE(cfgLog(pMac, LOGE, FL("param id %d len %d bytes"), paramId, paramLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + for (j=0; j < paramLenCeil4; j++) + { + pStr[4*j] = (tANI_U8) (*pSrc >> 24) & 0xff; + pStr[4*j+1] = (tANI_U8) (*pSrc >> 16) & 0xff; + pStr[4*j+2] = (tANI_U8) (*pSrc >> 8) & 0xff; + pStr[4*j+3] = (tANI_U8) (*pSrc) & 0xff; + + pSrc++; + strSize -= 4; + } + + PELOG1(cfgLog(pMac, LOG1, FL("set str id %d len %d"), paramId, paramLen);) + + if (cfgSetStr(pMac, (tANI_U16) paramId, pStr, paramLen) != eSIR_SUCCESS) + { + PELOGE(cfgLog(pMac, LOGE, FL("Error setting str default param %d len %d"), paramId, paramLen);) + retVal = WNI_CFG_INVALID_LEN; + goto end; + } + } + + // Set the default log level based on config + wlan_cfgGetInt(pMac, WNI_CFG_LOG_LEVEL, &logLevel); + for (i = 0; i < LOG_ENTRY_NUM; i++) + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = logLevel; + + // Set status to READY + pMac->cfg.gCfgStatus = CFG_SUCCESS; + retVal = WNI_CFG_SUCCESS; + PELOG1(cfgLog(pMac, LOG1, " Completed successfully");) + + end: + + if ( retVal != WNI_CFG_SUCCESS ) + pMac->cfg.gCfgStatus = CFG_FAILURE; + + // Send response message to host + paramList[WNI_CFG_DNLD_CNF_RES] = retVal; + cfgSendHostMsg(pMac, WNI_CFG_DNLD_CNF, WNI_CFG_DNLD_CNF_LEN, + WNI_CFG_DNLD_CNF_NUM, paramList, 0, 0); + + // Notify WDA that the config has downloaded + mmhMsg.type = SIR_CFG_DOWNLOAD_COMPLETE_IND; + mmhMsg.bodyptr = NULL; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + if (wdaPostCtrlMsg(pMac, &mmhMsg) != eSIR_SUCCESS) + { + PELOGE(cfgLog(pMac, LOGE, FL("WDAPostMsgApi failed!"));) + } + +} /*** end procDnldRsp() ***/ + + +/**--------------------------------------------------------------------- + * ProcGetReq() + * + * FUNCTION: + * This function processes CFG_GET_REQ message from host. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * For every parameter ID specified on the list, CFG will send a separate + * CFG_GET_RSP back to host. + * + * @param length: message length + * @param pParam: parameter list pointer + * + * @return None + * + */ +static void +ProcGetReq(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + tANI_U16 cfgId, i; + tANI_U32 value, valueLen, result; + tANI_U32 *pValue; + tANI_U32 paramList[WNI_CFG_GET_RSP_NUM]; + + PELOG1(cfgLog(pMac, LOG1, FL("Rcvd cfg get request %d bytes"), length);) + for (i=0; icfg.gCfgStatus) + { + cfgId = (tANI_U16)sirReadU32N((tANI_U8*)pParam); + PELOGE(cfgLog(pMac, LOGE, FL("CFG not ready, param %d"), cfgId);) + paramList[WNI_CFG_GET_RSP_RES] = WNI_CFG_NOT_READY; + paramList[WNI_CFG_GET_RSP_PID] = cfgId; + paramList[WNI_CFG_GET_RSP_PLEN] = 0; + cfgSendHostMsg(pMac, WNI_CFG_GET_RSP, WNI_CFG_GET_RSP_PARTIAL_LEN, + WNI_CFG_GET_RSP_NUM, paramList, 0, 0); + } + else + { + // Process all parameter ID's on the list + while (length >= sizeof(tANI_U32)) + { + cfgId = (tANI_U16)*pParam++; + pValue = 0; + valueLen = 0; + + PELOG1(cfgLog(pMac, LOG1, FL("Cfg get param %d"), cfgId);) + + // Check for valid parameter ID, etc... + if (CheckParam(pMac, cfgId, CFG_CTL_RE, WNI_CFG_WO_PARAM, &result)) + { + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0) + { + // Get integer parameter + result = (wlan_cfgGetInt(pMac, cfgId, &value) == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + pValue = &value; + valueLen = sizeof(tANI_U32); + } + else + { + // Get string parameter + valueLen = sizeof(pMac->cfg.gSBuffer); + result = (wlan_cfgGetStr(pMac, cfgId, pMac->cfg.gSBuffer, &valueLen) + == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + pValue = (tANI_U32*)pMac->cfg.gSBuffer; + } + } + else + { + PELOGE(cfgLog(pMac, LOGE, FL("Check param failed, param %d"), cfgId);) + result = WNI_CFG_INVALID_LEN; + } + + // Send response message to host + paramList[WNI_CFG_GET_RSP_RES] = result; + paramList[WNI_CFG_GET_RSP_PID] = cfgId; + paramList[WNI_CFG_GET_RSP_PLEN] = valueLen; + + // We need to round up buffer length to word-increment + valueLen = (((valueLen + 3) >> 2) << 2); + cfgSendHostMsg(pMac, WNI_CFG_GET_RSP, + WNI_CFG_GET_RSP_PARTIAL_LEN + valueLen, + WNI_CFG_GET_RSP_NUM, paramList, valueLen, pValue); + + // Decrement length + length -= sizeof(tANI_U32); + } + } + +} /*** end procGetReq() ***/ + + + +/**--------------------------------------------------------------------- + * ProcSetReqInternal() + * + * FUNCTION: + * This function processes CFG_SET_REQ message from host. + * + * LOGIC: + * + * ASSUMPTIONS: + * - The message content is coded in TLV format. + * - For string parameter, the length field is byte accurate. However, + * the next TLV set will begin on the next word boundary. + * + * NOTE: + * - For every parameter ID specified on the list, CFG will send a separate + * CFG_SET_RSP back to host. + * + * @param length: message length + * @param pParam: parameter list pointer + * @param fRsp: whether to send response to host. TRUE means sending. + * @return None + * + */ +static void +ProcSetReqInternal(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam, tANI_BOOLEAN fRsp) +{ + tANI_U16 cfgId, valueLen, valueLenRoundedUp4; + tANI_U32 value, result; + tANI_U32 paramList[WNI_CFG_SET_CNF_NUM]; + + PELOG1(cfgLog(pMac, LOG1, FL("Rcvd cfg set request %d bytes"), length);) + //for (i=0; icfg.gCfgStatus) + { + cfgId = (tANI_U16)sirReadU32N((tANI_U8*)pParam); + cfgLog(pMac, LOGW, FL("CFG not ready, param %d"), cfgId); + if (fRsp) + { + paramList[WNI_CFG_SET_CNF_RES] = WNI_CFG_NOT_READY; + paramList[WNI_CFG_SET_CNF_PID] = cfgId; + cfgSendHostMsg(pMac, WNI_CFG_SET_CNF, WNI_CFG_SET_CNF_LEN, + WNI_CFG_SET_CNF_NUM, paramList, 0, 0); + } + } + else + { + // Process all TLVs in buffer + while (length >= (sizeof(tANI_U32) * 2)) + { + cfgId = (tANI_U16) *pParam++; + valueLen = (tANI_U16) *pParam++; + length -= (sizeof(tANI_U32) * 2); + // value length rounded up to a 4 byte multiple + valueLenRoundedUp4 = (((valueLen + 3) >> 2) << 2); + + // Check for valid request before proceeding + if (CheckParam(pMac, cfgId, CFG_CTL_WE, WNI_CFG_RO_PARAM, &result)) + { + PELOG1(cfgLog(pMac, LOGW, (char *) gCfgParamName[cfgId]);) + // Process integer parameter + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0) + { + // Set VALUE + if (valueLen != sizeof(tANI_U32)) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid value length %d in set param %d (tot %d)"), + valueLen, cfgId, length);) + result = WNI_CFG_INVALID_LEN; + } + else + { + value = *pParam; + PELOG1(cfgLog(pMac, LOGW, FL("Cfg set int %d len %d(%d) val %d"), + cfgId, valueLen, valueLenRoundedUp4, value);) + result = (cfgSetInt(pMac, cfgId, value) == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + if (result == WNI_CFG_SUCCESS) + { + if (cfgNeedRestart(pMac, cfgId)) + { + result = WNI_CFG_NEED_RESTART ; + } + else + if (cfgNeedReload(pMac, cfgId)) + { + result = WNI_CFG_NEED_RELOAD ; + } + } + } + } + // Process string parameter + else + { + if (valueLenRoundedUp4 > length) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid string length %d" + "in set param %d (tot %d)"), valueLen, + cfgId, length);) + result = WNI_CFG_INVALID_LEN; + } + else + { + GetStrValue((tANI_U8*)pParam, pMac->cfg.gSBuffer, valueLen); + PELOG1(cfgLog(pMac, LOGW, FL("Cfg set str %d len %d(%d) bytes"), + cfgId, valueLen, valueLenRoundedUp4);) + result = (cfgSetStr(pMac, cfgId, pMac->cfg.gSBuffer, valueLen) == eSIR_SUCCESS ? + WNI_CFG_SUCCESS : WNI_CFG_OTHER_ERROR); + if (result == WNI_CFG_SUCCESS) + { + if (cfgNeedRestart(pMac, cfgId)) + { + result = WNI_CFG_NEED_RESTART ; + } + else + if (cfgNeedReload(pMac, cfgId)) + { + result = WNI_CFG_NEED_RELOAD ; + } + } + } + } + } + else + { + PELOGE(cfgLog(pMac, LOGE, FL("Check param failed, param %d"), cfgId);) + result = WNI_CFG_INVALID_LEN; + } + + if (fRsp) + { + /* Send confirm message to host */ + paramList[WNI_CFG_SET_CNF_RES] = result; + paramList[WNI_CFG_SET_CNF_PID] = cfgId; + cfgSendHostMsg(pMac, WNI_CFG_SET_CNF, WNI_CFG_SET_CNF_LEN, + WNI_CFG_SET_CNF_NUM, paramList, 0, 0); + } + else + { + PELOGW(cfgLog( pMac, LOG2, " CFGID %d no rsp", cfgId);) + } + + if (valueLenRoundedUp4 > length) + length = 0; + else + { + length -= valueLenRoundedUp4; + pParam += (valueLenRoundedUp4 >> 2); + } + } + } +} + + + +static void +ProcSetReq(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + ProcSetReqInternal( pMac, length, pParam, eANI_BOOLEAN_TRUE ); +} + +static void +ProcSetReqNoRsp(tpAniSirGlobal pMac, tANI_U16 length, tANI_U32 *pParam) +{ + ProcSetReqInternal( pMac, length, pParam, eANI_BOOLEAN_FALSE ); +} + + + +/**--------------------------------------------------------------------- + * CheckParam() + * + * FUNCTION: + * This function is called to perform various check on a parameter. + * + * LOGIC: + * - If cfgId is out of bound or parameter is not valid, result + * WNI_CFG_INVALID_PID is returned at address specified in pResult. + * + * - If specified 'flag' is not set in the parameter control entry, + * 'failedResult' is returned at address specified in pResult. + * + * ASSUMPTIONS: + * Since this function is used internally, 'pResult' is always valid. + * + * NOTE: + * + * @param None + * + * @return true: Parameter is valid and matches checked condition \n + * @return false: Parameter either is not valid or does not match + * checked condition. + * + */ +static tANI_U8 +CheckParam(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 flag, tANI_U32 failedResult, tANI_U32 *pResult) +{ + // Check if parameter ID is out of bound + if (cfgId >= CFG_PARAM_MAX_NUM) + { + PELOGE(cfgLog(pMac, LOGE, FL("Invalid param id %d"), cfgId);) + *pResult = WNI_CFG_INVALID_PID; + } + else + { + // Check if parameter is valid + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_VALID) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Param id %d not valid"), cfgId);) + *pResult = WNI_CFG_INVALID_PID; + } + else + { + // Check control field against flag + if ((pMac->cfg.gCfgEntry[cfgId].control & flag) == 0) + { + PELOGE(cfgLog(pMac, LOGE, FL("Param id %d wrong permissions %x"), + cfgId, pMac->cfg.gCfgEntry[cfgId].control);) + *pResult = failedResult; + } + else + return(true); + } + } + return(false); + +} /*** cfgParamCheck() ***/ + + +/**--------------------------------------------------------------------- + * GetStrValue() + * + * FUNCTION: + * This function copies a string value from the specified buffer. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pBuf: input data buffer + * @param pValue: address where data is returned + * @param length: number of bytes to copy + * + * @return None + * + */ +static void +GetStrValue(tANI_U8 *pBuf, tANI_U8 *pValue, tANI_U32 length) +{ + tANI_U8 *pEnd; + + pEnd = pValue + length; + while (pValue < pEnd) + *pValue++ = *pBuf++; +} /*** end GetStrValue() ***/ + + +/**--------------------------------------------------------------------- + * processCfgDownloadReq() + * + * FUNCTION: This function reads the cfgStatic array and + * populates the cfg data structure. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac: Pointer to Mac Structure + * + * @return None + * + */ + +void +processCfgDownloadReq(tpAniSirGlobal pMac) +{ + tANI_S32 i; + tANI_U32 index; + tANI_U8 *pDstTest, *pSrcTest; + tANI_U8 len; + tAniSirCfgStaticString *pStrCfg; + tANI_U32 bufStart, bufEnd; + tANI_U32 logLevel, retVal; + tANI_U32 iCount = 0; + tANI_U32 sCount = 0; + + + for (i=0; imaxLen + 1 + 1; + } + else + { + index = iCount & CFG_BUF_INDX_MASK; + iCount++; + } + } + else + { + index = 0; + } + pMac->cfg.gCfgEntry[i].control = cfgStatic[i].control | index; + } + + /*Fill the SBUF wih maxLength*/ + bufEnd = pMac->cfg.gCfgMaxSBufSize; + for (i = CFG_PARAM_MAX_NUM - 1; i >= 0; i--) + { + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) + continue; + + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0) + continue; + + bufStart = pMac->cfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK; + pMac->cfg.gCfgSBuf[bufStart] = (tANI_U8)(bufEnd - bufStart - 2); + + PELOG1(cfgLog(pMac, LOG1, FL("id %d max %d bufStart %d bufEnd %d"), + i, pMac->cfg.gCfgSBuf[bufStart], bufStart, bufEnd);) + bufEnd = bufStart; + } + + for(i=0; icfg.gCfgEntry[i].control & CFG_BUF_INDX_MASK; + + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_INT) != 0) + { + pMac->cfg.gCfgIBufMin[index] = cfgStatic[i].cfgIMin; + pMac->cfg.gCfgIBufMax[index] = cfgStatic[i].cfgIMax; + pMac->cfg.gCfgIBuf[index] = cfgStatic[i].cfgIVal; + } + else + { + tANI_U8 maxSavedLen; + if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0) + continue; + if (index >= CFG_STA_SBUF_MAX_SIZE) + continue; + + pDstTest = &pMac->cfg.gCfgSBuf[index]; + pStrCfg = (tAniSirCfgStaticString *)cfgStatic[i].pStrData; + pSrcTest = pStrCfg->data; + if ((pDstTest == NULL) || (pStrCfg == NULL) || (pSrcTest == NULL)) + continue; + maxSavedLen = *pDstTest; + len = pStrCfg->length; + if (len > maxSavedLen) + continue; + *pDstTest++ = pStrCfg->maxLen; + *pDstTest++ = len; + while(len) + { + *pDstTest++ = *pSrcTest++; + len--; + } + } + } + + // Set the default log level based on config + wlan_cfgGetInt(pMac, WNI_CFG_LOG_LEVEL, &logLevel); + for (i = 0; i < LOG_ENTRY_NUM; i++) + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = logLevel; + + // Set status to READY + pMac->cfg.gCfgStatus = CFG_SUCCESS; + retVal = WNI_CFG_SUCCESS; + PELOG1(cfgLog(pMac, LOG1, " Completed successfully");) + +} /*** end ProcessDownloadReq() ***/ + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgSendMsg.c b/drivers/staging/prima/CORE/MAC/src/cfg/cfgSendMsg.c new file mode 100644 index 000000000000..e5a28bfdb0bf --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgSendMsg.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file contains the source code for composing and sending messages + * to host. + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + */ +#include "palTypes.h" +#include "cfgPriv.h" +#include "limTrace.h" +#include "cfgDebug.h" + +extern void SysProcessMmhMsg(tpAniSirGlobal pMac, tSirMsgQ* pMsg); + +/*--------------------------------------------------------------------*/ +/* ATTENTION: The functions contained in this module are to be used */ +/* by CFG module ONLY. */ +/*--------------------------------------------------------------------*/ + + +/**--------------------------------------------------------------------- + * cfgSendHostMsg() + * + * FUNCTION: + * Send CNF/RSP to host. + * + * LOGIC: + * Please see Configuration & Statistic Collection Micro-Architecture + * specification for details. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param msgType: message type + * @param msgLen: message length + * @param paramNum: number of parameters + * @param pParamList: pointer to parameter list + * @param dataLen: data length + * @param pData: pointer to additional data + * + * @return None. + * + */ +void +cfgSendHostMsg(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 msgLen, tANI_U32 paramNum, tANI_U32 *pParamList, + tANI_U32 dataLen, tANI_U32 *pData) +{ + tANI_U32 *pMsg, *pEnd; + tSirMsgQ mmhMsg; + + // sanity + if ((paramNum > 0) && (NULL == pParamList)) + { + PELOGE(cfgLog(pMac, LOGE, + FL("pParamList NULL when paramNum greater than 0!"));) + return; + } + if ((dataLen > 0) && (NULL == pData)) + { + PELOGE(cfgLog(pMac, LOGE, + FL("pData NULL when dataLen greater than 0!"));) + return; + } + + // Allocate message buffer + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + PELOGE(cfgLog(pMac, LOGE, + FL("Memory allocation failure!"));) + return; + } + + // Fill in message details + mmhMsg.type = msgType; + mmhMsg.bodyptr = pMsg; + mmhMsg.bodyval = 0; + ((tSirMbMsg*)pMsg)->type = msgType; + ((tSirMbMsg*)pMsg)->msgLen = (tANI_U16)msgLen; + + switch (msgType) + { + case WNI_CFG_GET_RSP: + case WNI_CFG_PARAM_UPDATE_IND: + case WNI_CFG_DNLD_REQ: + case WNI_CFG_DNLD_CNF: + case WNI_CFG_SET_CNF: + // Fill in parameters + pMsg++; + if (NULL != pParamList) + { + pEnd = pMsg + paramNum; + while (pMsg < pEnd) + { + *pMsg++ = *pParamList++; + } + } + // Copy data if there is any + if (NULL != pData) + { + pEnd = pMsg + (dataLen >> 2); + while (pMsg < pEnd) + { + *pMsg++ = *pData++; + } + } + break; + + default: + PELOGE(cfgLog(pMac, LOGE, + FL("Unknown msg %d!"), (int) msgType);) + vos_mem_free( pMsg); + return; + } + + // Ship it + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + SysProcessMmhMsg(pMac, &mmhMsg); + +} /*** end cfgSendHostMsg() ***/ + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/cfg.txt b/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/cfg.txt new file mode 100644 index 000000000000..c08458fe10bb --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/cfg.txt @@ -0,0 +1,5031 @@ + * + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + + * + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + * + +* + +* +* +* This is the data definition file for the CFG module. +* Author: Kevin Nguyen +* Date: 03/18/02 +* History:- +* 03/18/02 Created. +* 08/10/05 ww: add maoe channels to have a complete channel listing: (see WNI_CFG_VALID_CHANNEL_LIST) +* 08/10/05 ww: WNI_CFG_SCAN_CONTROL_LIST has a new contents +* -------------------------------------------------------------------- + +********************************************************************** +* +* This file contains the descriptions of all configuration parameters +* for both STA and AP. +* +* OUTPUT: +* ------- +* The output files are: +* wniCfgSta.h - C header file for STA mode only +* wniCfgAp.h - C header file for both STA and AP +* wniCfgSta.bin - Control and default values for STA system +* wniCfgAp.bin - Control and default values for AP system +* +* PARAMETER DESCRIPTION: +* ---------------------- +* For each parameter, the description must be on separate lines and +* exactly as specified below. [] are comments and should not be included. +* +* [Common info] parameter_name type maxLen semIndx +* [STA flags] valid RW P/NP RESTART/RELOAD +* [STA_NTF] notification_mask +* [STA values] min max value [for integer] +* length byte1 byte2 ... [for string] +* [AP flags] valid RW/RO/WO P/NP RESTART/RELOAD +* [AP_NTF] notification_mask +* [AP values] min max value [for integer] +* length byte1 byte2 ... [for string] +* +* parameter_name: +* This will be used as the base name for C macro definition. +* Therefore, C syntax rule must be observed. +* +* type: +* Specifies parameter type +* S - variable-length string +* I - integer +* +* maxLen: +* Specifies maximum parameter length in bytes. +* +* semIndx: +* Specifies semaphore index to use for locking this parameter. +* More than one parameters (those belonging to the same group) +* can share the same semaphore index. +* +* valid: +* Specifies if this parameter will be valid in current mode. +* V - Valid +* NV - Not valid +* +* RW: +* Specifies Read/Write mode. +* RO - Read only +* RW - Read/Write +* WO - Write only +* XX - Not accessible from host +* +* P: +* Specifies persistent memory option +* P - Save to persistent memory +* NP - No save +* +* RELOAD: +* Specifies whether setting this requires reloading the MAC module +* This attribute can be changed only when SME is in OFFLINE or SUSPEND(OFFLINE) state +* +* RESTART: +* Specifies whether setting this requires (re)assoc at STA and restart at AP +* This attribute can be changed only when SME is in OFFLINE, SUSPEND(OFFLINE), +* IDLE or SUSPEND(IDLE) states +* +* STA_notification: +* Lists modules to be notified in STA mode. Valid modules are: +* HDD, LIM, SCH, ARQ, DPH, NIM, SP, RFP, RHP, TFP. More than one +* modules can be listed on the same line using space or tab as the +* separator. If no notification is required, 'NONE' must be specified. +* +* AP_notification: +* Lists module to be notified in AP mode. Valid modules are: +* HDD, LIM, SCH, ARQ, DPH, NIM, SP, RFP, RHP, TFP. More than one +* modules can be listed on the same line using space or tab as the +* separator. If no notification is required, 'NONE' must be specified. +* +* STA/AP integer values: +* min: +* Specifies minimum value for an integer parameter. This field is +* ignored if the parameter type is string. However, this field must +* not be omitted. +* +* max: +* Specifies maximum value for an integer parameter. This field is +* ignored if the parameter type is string. However, this field must +* not be omitted. +* +* default: +* Specifies default value for an integer parameter. This field is +* ignored if the parameter type is string. However, this field must +* not be omitted. +* +* STA/AP string values: +* len: +* The actual length of the string +* +* bytei: +* byte i of the string where i varies from 1 to len +* +* TABLE GENERATION: +* ----------------- +* Table can be generated using keywords '#TABLE' and '#END' as below: +* +* #TABLE table_name number_of_row +* WNI_CFG_xxxx +* ....... +* ....... +* #END +* +* The CFG utility will generate the following output: +* WNI_CFG_table_xxx_ID xxx +* WNI_CFG_table_xxx_ROW number_of_rows +* WNI_CFG_table_xxx_COL number_of_columns +* +* These will be followed by the parameter definition for each entry in +* the table. Table is organized in column-major order. +* +* #ENTRY_VALUES 1 +* 0 4 1 +* 0 0 0 +* #ENTRY_VALUES 2 +* 0 4 2 +* 0 0 0 +* #ENTRY_VALUES 3 +* 0 4 3 +* 0 0 0 +* #ENTRY_VALUES 4 +* 0 4 4 +* 0 0 0 +* +* +* ENUMERATION +* ----------- +* Enumerations can be define using keyword '#ENUM' +* +* #ENUM xxx val +* +* The cfg utility will generate the following output in the header file +* #define paramname_xxx val +* + + +* +* Station ID (changing requires restart) +* + +WNI_CFG_STA_ID S 6 1 +V RW NP RELOAD +HAL +6 0x22 0x22 0x44 0x44 0x33 0x33 +V RW NP RELOAD +HAL +6 0x22 0x22 0x11 0x11 0x33 0x33 + +* +* CF Pollable +* + +WNI_CFG_CF_POLLABLE I 4 1 +NV RO NP RESTART +NONE +0 0 0 +V RO NP RESTART +NONE +0 1 0 + +* +* CFP Period +* + +WNI_CFG_CFP_PERIOD I 4 1 +V RO NP +NONE +0 255 1 +V RW NP +SCH +0 255 1 + +* +* CFP Max Duration +* + +WNI_CFG_CFP_MAX_DURATION I 4 1 +V RO NP +NONE +0 65535 30000 +V RW NP +HAL +0 65535 30000 + +* +* SSID (changing requires restart) +* + +WNI_CFG_SSID S 32 1 +V RW NP RESTART +NONE +10 1 2 3 4 5 6 7 8 9 0 +V RW NP RESTART +NONE +10 1 2 3 4 5 6 7 8 9 0 + +* +* Beacon Period +* Can't be changed on STA in infrastructure, ignore notification at SCH +* + +WNI_CFG_BEACON_INTERVAL I 4 2 +V RW NP +SCH +0 65535 100 +V RW NP +SCH +0 65535 100 + +* +* DTIM Period +* + +WNI_CFG_DTIM_PERIOD I 4 2 +V RO NP +NONE +0 65535 1 +V RW NP +SCH +0 65535 1 + + +* +* WEP Key Length (5 or 13 bytes) +* + +WNI_CFG_WEP_KEY_LENGTH I 4 5 +V RW NP RESTART +NONE +5 13 5 +V RW NP RESTART +NONE +5 13 5 + +#ENUM 5 5 +#ENUM 13 13 + +* +* Default Key Table +* + +#TABLE WNI_CFG_WEP_DEFAULT_KEY_TABLE 4 + +WNI_CFG_WEP_DEFAULT_KEY S 13 4 +V WO NP RESTART +NONE +0 +V WO NP RESTART +NONE +0 + +#END + +* +* WEP Default Key id +* + +WNI_CFG_WEP_DEFAULT_KEYID I 4 5 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +#ENUM 0 0 +#ENUM 1 1 +#ENUM 2 2 +#ENUM 3 3 + +* +* Exclude unencrypted frames (WEP) +* + +WNI_CFG_EXCLUDE_UNENCRYPTED I 4 5 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* RTS Threshold +* + +WNI_CFG_RTS_THRESHOLD I 4 6 +V RW NP +HAL +0 2347 2347 +V RW NP +HAL +0 2347 2347 + +* +* Short Retry Limit +* + +WNI_CFG_SHORT_RETRY_LIMIT I 4 6 +V RW NP +HAL +0 255 6 +V RW NP +HAL +0 255 6 + +* +* Long Retry Limit +* + +WNI_CFG_LONG_RETRY_LIMIT I 4 6 +V RW NP +HAL +0 255 6 +V RW NP +HAL +0 255 6 + + +* +* Fragmentation Threshold +* + +WNI_CFG_FRAGMENTATION_THRESHOLD I 4 6 +V RW NP +HAL +256 8000 8000 +V RW NP +HAL +256 8000 8000 + + +* +* Minimum Channel Time (TU) +* + +WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 20 +V RW NP +NONE +0 65535 20 + +* +* Maximum Channel Time (TU) +* + +WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 40 +V RW NP +NONE +0 65535 40 +* +* Minimum Channel Time (TU) +* + +WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 60 +V RW NP +NONE +0 65535 60 + +* +* Maximum Channel Time (TU) +* + +WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME I 4 9 +V RW NP +NONE +0 65535 110 +V RW NP +NONE +0 65535 110 + +* +* Join Failure Timeout (TU) +* + +WNI_CFG_JOIN_FAILURE_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 3000 +V RW NP +NONE +0 65535 3000 + +* +* Authenticate Failure Timeout (TU) +* + +WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 1000 + +* +* Authenticate Response Timeout (TU) +* + +WNI_CFG_AUTHENTICATE_RSP_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 1000 + +* +* Assocation Failure Timeout (TU) +* + +WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT I 4 8 +V RW NP +LIM +0 65535 2000 +V RW NP +LIM +0 65535 3000 + +* +* Reassociation Failure Timeout (TU) +* + +WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT I 4 7 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 3000 + + +* +* RA periodicity Timeout (TU) +* + +WNI_CFG_RA_PERIODICITY_TIMEOUT_IN_PS I 4 7 +V RW NP +HAL +0 65535 1000 +NV RW NP +NONE +0 0 0 + +* +* Beacon Filter Enable/Disable (TU) +* + +WNI_CFG_PS_ENABLE_BCN_FILTER I 4 7 +V RW NP +HAL +0 1 1 +NV RW NP +NONE +0 1 1 + +* +* Heart Beat Enable/Disable (TU) +* + +WNI_CFG_PS_ENABLE_HEART_BEAT I 4 7 +V RW NP +HAL +0 1 1 +NV RW NP +NONE +0 1 1 + +* +* RSSI Monitor Enable/Disable (TU) +* + +WNI_CFG_PS_ENABLE_RSSI_MONITOR I 4 7 +V RW NP +HAL +0 1 0 +NV RW NP +NONE +0 1 0 + + +* +* PS Data InActivity Timeout (TU) +* + +WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT I 4 7 +V RW NP +HAL +1 255 20 +NV RW NP +NONE +1 255 20 + + +* +* RF Settling Time Clk (In US) +* + +WNI_CFG_RF_SETTLING_TIME_CLK I 4 7 +V RW NP +HAL +0 60000 1500 +NV RW NP +NONE +0 60000 1500 + +* +* Supported Rate Set for 11b +* + +WNI_CFG_SUPPORTED_RATES_11B S 4 2 +V RO NP +NONE +4 2 4 11 22 +V RO NP +NONE +4 2 4 11 22 + +* +* Supported Rate Set for 11a +* + +WNI_CFG_SUPPORTED_RATES_11A S 8 7 +V RO NP +NONE +8 12 18 24 36 48 72 96 108 +V RO NP +NONE +8 12 18 24 36 48 72 96 108 + + +* +* PHY Mode +* + +WNI_CFG_PHY_MODE I 4 9 +V RW NP RESTART +NONE +0 3 0 +V RW NP RESTART +NONE +0 3 0 + +#ENUM 11A 0 +#ENUM 11B 1 +#ENUM 11G 2 +#ENUM NONE 3 + + +* +*The Dot11 mode can change dynamically on STA +* +WNI_CFG_DOT11_MODE I 4 9 +V RW NP RESTART +LIM +0 11 0 +V RW NP RESTART +LIM +0 11 0 + +#ENUM ALL 0 +#ENUM 11A 1 +#ENUM 11B 2 +#ENUM 11G 3 +#ENUM 11N 4 +#ENUM POLARIS 5 +#ENUM TITAN 6 +#ENUM TAURUS 7 +#ENUM 11G_ONLY 8 +#ENUM 11N_ONLY 9 +#ENUM 11AC 10 +#ENUM 11AC_ONLY 11 + + + + + + +* +* Operational Rate Set (goes in beacon, probe rsp and assoc req) +* + +WNI_CFG_OPERATIONAL_RATE_SET S 12 2 +V RW NP RESTART +NONE +0 +V RW NP RESTART +NONE +4 0x82 0x84 11 22 +* 8 0x8c 18 24 36 48 72 96 108 + +* +* Extended Operational Rate Set (goes in beacon, assoc req) +* required for 11g +* + +WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET S 8 7 +V RW NP RESTART +NONE +0 +V RW NP RESTART +NONE +0 + +* +* Proprietary Operational Rate Set +* + +WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET S 4 7 +V RW NP RESTART +NONE +4 1 3 5 7 +V RW NP RESTART +NONE +4 1 3 5 7 + +* +* BSSID +* In IBSS, this can be changed for coalescing, should SME go into IDLE state? +* + +WNI_CFG_BSSID S 6 7 +V RW NP RESTART +NONE +6 0x22 0x22 0x11 0x11 0x33 0x33 +V RW NP RESTART +NONE +6 0x22 0x22 0x11 0x11 0x33 0x33 + + +* +* Listen Interval +* + +WNI_CFG_LISTEN_INTERVAL I 4 7 +V RW NP RESTART +NONE +0 65535 1 +V RO NP +NONE +0 65535 1 + +* +* Valid Channel List +* + +WNI_CFG_VALID_CHANNEL_LIST S 100 8 +V RW NP RESTART +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 +V RW NP RESTART +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 + +* +* Current Channel +* + +WNI_CFG_CURRENT_CHANNEL I 4 9 +V RO NP +NONE +0 165 1 +V RO NP +NONE +0 165 1 + + +* +* For 11a or pure 11g, use 6Mbps(rateindex 11) +* as the default beaconRateIndex and +* nonBeaconRateIndex. +* +WNI_CFG_DEFAULT_RATE_INDEX_5GHZ I 4 9 +V RW NP +NONE +0 11 5 +V RW NP +NONE +0 11 5 + +* +* For 11b/g, use 1Mbps +* as the default beaconRateIndex and +* nonBeaconRateIndex. +* +WNI_CFG_DEFAULT_RATE_INDEX_24GHZ I 4 9 +V RW NP +NONE +0 31 1 +V RW NP +NONE +0 31 1 + + +* ********************************************************* +* +* Rate adaptation type +* + +WNI_CFG_RATE_ADAPTATION_TYPE I 4 0 +V RW NP +SCH +0 2 1 +V RW NP +SCH +0 2 1 + +#ENUM FIXED 0 +#ENUM AUTO 1 +#ENUM SNR_BASED 2 + +* +* Rate adaptation fixed rate +* Used to determine the rate for all peer stations +* +* + +WNI_CFG_FIXED_RATE I 4 0 +V RW NP +HAL +0 44 0 +V RW NP +HAL +0 44 0 + +#ENUM AUTO 0 + +#ENUM 1MBPS 1 +#ENUM 2MBPS 2 +#ENUM 5_5MBPS 3 +#ENUM 11MBPS 4 + +#ENUM 6MBPS 5 +#ENUM 9MBPS 6 +#ENUM 12MBPS 7 +#ENUM 18MBPS 8 +#ENUM 24MBPS 9 +#ENUM 36MBPS 10 +#ENUM 48MBPS 11 +#ENUM 54MBPS 12 + +#ENUM 6_5MBPS_MCS0_20MHZ_SIMO 13 +#ENUM 13MBPS_MCS1_20MHZ_SIMO 14 +#ENUM 19_5MBPS_MCS2_20MHZ_SIMO 15 +#ENUM 26MBPS_MCS3_20MHZ_SIMO 16 +#ENUM 39MBPS_MCS4_20MHZ_SIMO 17 +#ENUM 52MBPS_MCS5_20MHZ_SIMO 18 +#ENUM 58_5MBPS_MCS6_20MHZ_SIMO 19 +#ENUM 65MBPS_MCS7_20MHZ_SIMO 20 + +#ENUM 7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#ENUM 14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#ENUM 21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#ENUM 28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#ENUM 43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#ENUM 57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#ENUM 65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#ENUM 72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 + +#ENUM 0_25MBPS_SLR_20MHZ_SIMO 29 +#ENUM 0_5MBPS_SLR_20MHZ_SIMO 30 + +#ENUM 68_25MBPS_QC_PROP_20MHZ_SIMO 31 +#ENUM 54MBPS_MCS3_40MHZ_SIMO 32 +#ENUM 81MBPS_MCS4_40MHZ_SIMO 33 +#ENUM 108MBPS_MCS5_40MHZ_SIMO 34 +#ENUM 121_5MBPS_MCS6_40MHZ_SIMO 35 +#ENUM 135MBPS_MCS7_40MHZ_SIMO 36 +#ENUM 15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#ENUM 30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#ENUM 45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#ENUM 60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#ENUM 90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#ENUM 120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#ENUM 135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#ENUM 150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +* ********************************************************* +* +* Broadcast/mutlicast rates for 2.4GHZ +* uses the same rate indices definition as WNI_CFG_FIXED_RATE +* default value corresponds to 1M + +WNI_CFG_FIXED_RATE_MULTICAST_24GHZ I 4 8 +V RW NP +HAL +0 31 1 +V RW NP +HAL +0 31 1 + +* ********************************************************* +* +* Broadcast/mutlicast rates for 5 GHZ +* uses the same rate indices definition as WNI_CFG_FIXED_RATE +* default value corresponds to 6M + +WNI_CFG_FIXED_RATE_MULTICAST_5GHZ I 4 8 +V RW NP +HAL +0 31 5 +V RW NP +HAL +0 31 5 + +* +* retry rate selection policy +* 0 => use the minimum supported rate +* 1 => use the same rate as the chosen primary rate +* 2 => use the rate specified in RETRYRATE_SECONDARY +* 3 => use the rate closest to the primary +* 4 => autoselect the retry rate based on RA algorithm +* + +WNI_CFG_RETRYRATE_POLICY I 4 0 +V RW NP +HAL +0 255 4 +V RW NP +HAL +0 255 4 + +#ENUM MIN_SUPPORTED 0 +#ENUM PRIMARY 1 +#ENUM RESERVED 2 +#ENUM CLOSEST 3 +#ENUM AUTOSELECT 4 +#ENUM MAX 5 + +* +* the following two CFG's are +* used only if the retryrate policy == 2 +* These should be set to one of the values used +* for configuring fixed rates (see enumerated rates) +* + +WNI_CFG_RETRYRATE_SECONDARY I 4 0 +V RW NP +HAL +0 255 0 +V RW NP +HAL +0 255 0 + +WNI_CFG_RETRYRATE_TERTIARY I 4 0 +V RW NP +HAL +0 255 0 +V RW NP +HAL +0 255 0 + +* ********************************************************* +* +* Automatic Power Save Delivery capability +* + +WNI_CFG_APSD_ENABLED I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Shared key authentication supported +* + +WNI_CFG_SHARED_KEY_AUTH_ENABLE I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* Open system authentication supported +* + +WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* Authentication Type (change requires restart) +* + +WNI_CFG_AUTHENTICATION_TYPE I 4 8 +V RW NP RESTART +NONE +0 65535 0 +V RW NP RESTART +NONE +0 65535 0 + +* +* CF Poll Request (change requires restart) +* + +WNI_CFG_CF_POLL_REQUEST I 4 8 +NV RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* Privacy Enabled (change requires restart) +* + +WNI_CFG_PRIVACY_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* Short Preamble (change requires restart) +* + +WNI_CFG_SHORT_PREAMBLE I 4 8 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* Short Slot time +* This is the operational state of the BSS + +WNI_CFG_SHORT_SLOT_TIME I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 0 + + +* +* ACCEPT Short Slot Association only +* +* 1: If AP supports shortSlot, then AP will accept +* association only from stations that supports +* supports short slot +* 0: AP supports shortSlot, but AP will accept association +* from stations regardless of whether station supports +* short slot or long slot +* +WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY I 4 9 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + + +* +* QOS Enabled (change requires restart) +* + +WNI_CFG_QOS_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* HCF Enabled (change requires restart) +* + +WNI_CFG_HCF_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* RSN (11i/WPA) Enabled +* + +WNI_CFG_RSN_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* Background scanning periodicity (kilo usec) +* + +WNI_CFG_BACKGROUND_SCAN_PERIOD I 4 8 +V RW NP +LIM +0 180000 5000 +V RW NP +LIM +0 18000 5000 + +* +* Max number of Preauthentication +* + +WNI_CFG_MAX_NUM_PRE_AUTH I 4 8 +V RW NP RESTART +NONE +0 256 64 +V RW NP RESTART +NONE +0 256 64 + +* +* Preauthentication Cleanup Timeout (kilo usec) +* + +WNI_CFG_PREAUTH_CLNUP_TIMEOUT I 4 8 +NV XX NP +NONE +0 0 0 +V RW NP +LIM +0 120000 30000 + +* +* Release AID Timeout +* + +WNI_CFG_RELEASE_AID_TIMEOUT I 4 8 +NV XX NP +NONE +0 0 0 +V RW NP +LIM +0 100000 1000 +* +* Heartbeat Threshold +* + +WNI_CFG_HEART_BEAT_THRESHOLD I 4 8 +V RW NP +LIM +0 65535 40 +NV RW NP +NONE +0 65535 40 + +* +* Probe response wait time out after heartbeat failure +* + +WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT I 4 8 +V RW NP +NONE +10 10000 40 +V RW NP +NONE +10 10000 40 + +* +* Manufacturer OUI (from eeprom) +* + +WNI_CFG_MANUFACTURER_OUI S 3 8 +V RO NP +NONE +3 0x0 0xa 0xf5 +V RO NP +NONE +3 0x0 0xa 0xf5 + +* +* Manufacture Name (from eeprom) +* + +WNI_CFG_MANUFACTURER_NAME S 65 8 +V RO NP +NONE +8 0x51 0x75 0x61 0x6c 0x63 0x6f 0x6D 0x6D +V RO NP +NONE +8 0x51 0x75 0x61 0x6c 0x63 0x6f 0x6D 0x6D + +* +* Model Number (from eeprom) +* + +WNI_CFG_MODEL_NUMBER S 33 8 +V RO NP +NONE +6 0x4d 0x4e 0x31 0x32 0x33 0x34 +V RO NP +NONE +6 0x4d 0x4e 0x31 0x32 0x33 0x34 + + + +* +* Model Name (from eeprom) +* WFR4031 +* + +WNI_CFG_MODEL_NAME S 33 8 +V RO NP +NONE +7 0x57 0x46 0x52 0x34 0x30 0x33 0x31 +V RO NP +NONE +7 0x57 0x46 0x52 0x34 0x30 0x33 0x31 + + + + +* +* Manufacture Product Name (from eeprom) +* + +WNI_CFG_MANUFACTURER_PRODUCT_NAME S 33 8 +V RO NP +NONE +6 0x31 0x31 0x6e 0x2D 0x41 0x50 +V RO NP +NONE +6 0x31 0x31 0x6e 0x2D 0x41 0x50 + + +* +* Manufacture Product Version (from eeprom) +* + +WNI_CFG_MANUFACTURER_PRODUCT_VERSION S 33 8 +V RO NP +NONE +6 0x53 0x4e 0x31 0x32 0x33 0x34 +V RO NP +NONE +6 0x53 0x4e 0x31 0x32 0x33 0x34 + +* +* Multi Domain Capability (11d) Enable +* + +WNI_CFG_11D_ENABLED I 4 9 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 0 + +* +* per channel Max power transmit (in dBm) +* this parameter correspond to the MAX_COUNTRY_EID +* table of (Channel Number/num channel/max tx power) +* +* There is one table for 5GHz channels and one table for 2.4GHz channels +* + +WNI_CFG_MAX_TX_POWER_2_4 S 128 8 +V RW NP +NONE +3 1 14 20 +V RW NP +NONE +3 1 14 20 + +WNI_CFG_MAX_TX_POWER_5 S 128 8 +V RW NP +NONE +3 36 126 20 +V RW NP +NONE +3 36 126 20 + +* +* Cell size configurations. These are canned configurations for a specified +* cell size. +* +WNI_CFG_NETWORK_DENSITY I 4 9 +V RW NP +HAL +0 3 3 +V RW NP +HAL +0 3 0 + +#ENUM LOW 0 +#ENUM MEDIUM 1 +#ENUM HIGH 2 +#ENUM ADAPTIVE 3 + + +* +* Adaptive Threshold Algorithm +* +WNI_CFG_ADAPTIVE_THRESHOLD_ALGORITHM I 4 9 +V RW NP +HAL +1 2 2 +V RW NP +HAL +1 2 2 + +#ENUM CARRIER 1 +#ENUM CORRELATION 2 + + + +* +* Current TX Antenna +* + +WNI_CFG_CURRENT_TX_ANTENNA I 4 9 +V RW NP +HAL +1 1 1 +V RW NP +HAL +1 2 2 + +* +* Current RX Antenna +* + +WNI_CFG_CURRENT_RX_ANTENNA I 4 9 +V RW NP +HAL +1 2 2 +V RW NP +HAL +1 3 3 + +* +* Current TX Power Level +* + +WNI_CFG_CURRENT_TX_POWER_LEVEL I 4 9 +V RO NP +NONE +0 128 27 +V RO NP +NONE +0 128 27 + + +* +* Radio Power State for each Chain +* +* This CFG is invoked when user issues the Apple setPower() +* command, which configures the power state for each chain. Currently, +* Taurus supports up to three chains, and each chain can be configured +* to one of the 4 following possible power states: +* POWER_OFF = 0x0 +* POWER_ON = 0x1 +* POWER_TX = 0x2 +* POWER_RX = 0x3 +* +* The power state of each chain is expressed in nibble: +* bit[0:3] - chain 0 +* bit[4:7] - chain 1 +* bit[8:11] - chain 2 +* bit[12:15] - not used at the moment +* +* Examples: +* 0x001 - 1x1 (chain 1 is for both tx and rcv. chain 1,2 are turned off) +* 0x031 - 1x2 (chain 0 is for both tx and rcv. chain 1 is rcv only. chain 2 is turned off) +* 0x011 - 2x2 (chain 0,1 are used for both tx and rcv) +* 0x311 - 2x3 (chain 0,1 are used for both tx and rcv. chain 2 is for rcv only) +* 0x333 - all 3 chains are set to RX +* + +WNI_CFG_POWER_STATE_PER_CHAIN I 4 9 +V RW NP +HAL +0 0xffff 0x311 +V RW NP +HAL +0 0xffff 0x311 + +#ENUM OFF 0 +#ENUM ON 1 +#ENUM TX 2 +#ENUM RX 3 +#ENUM MASK 0xf +#ENUM CHAIN_0_OFFSET 0 +#ENUM CHAIN_1_OFFSET 4 +#ENUM CHAIN_2_OFFSET 8 + + +* +* Parameter to indicate or not new BSS found +* + +WNI_CFG_NEW_BSS_FOUND_IND I 4 9 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Proprietary ANI features enable/disable +* + +WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED I 4 12 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + + +* +* Qualcomm Prop Rates are disabled by default +* +WNI_CFG_PROPRIETARY_RATES_ENABLED I 4 12 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + + +* +* AP node Name +* + +WNI_CFG_AP_NODE_NAME S 32 8 +NV RO NP +NONE +0 +V RW NP RESTART +NONE +0 + +* +* Country code (from EEPROM) +* + +WNI_CFG_COUNTRY_CODE S 3 8 +V RW NP +NONE +0 +V RW NP +NONE +3 0x11 0x22 0x33 + +* +* Spectrum Management (11h) enable/disable +* + +WNI_CFG_11H_ENABLED I 4 12 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + + +* +* Wait for CNF Timeout. CNF include (RE)ASSOC, DISASSOC, AUTH, DEAUTH, +* DUMMY packet +* + +WNI_CFG_WT_CNF_TIMEOUT I 4 12 +V RW NP +NONE +10 3000 1000 +V RW NP +NONE +10 3000 1000 + +* +* Keepalive Timeout. A Null data frame is sent out every timeout. +* Applicable to both AP and STA +* + +WNI_CFG_KEEPALIVE_TIMEOUT I 4 12 +V RW NP +NONE +0 3600000 0 +V RW NP +NONE +0 3600000 3000 + +* +* Proximity, set it for very short distances +* Proxmity setting is applied via halPhySetNwDensity() +* +* close proximity off = densityOn is true. network density config applies. +* close proximity on = densityOn is false. Don't care about network density config. +* + +WNI_CFG_PROXIMITY I 4 12 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +#ENUM OFF 0 +#ENUM ON 1 + +* +* Default LOG level +* + +WNI_CFG_LOG_LEVEL I 4 12 +V RW NP +NONE +0 7 4 +V RW NP +NONE +0 7 4 + +* +* OLBC detection timeout +* + +WNI_CFG_OLBC_DETECT_TIMEOUT I 4 12 +V RW NP +NONE +1000 30000 10000 +V RW NP +NONE +1000 30000 10000 + +********************************** +* Protection Enable +* +*LOWER byte for associated stations +*UPPER byte for overlapping stations. +*11g ==> protection from 11g +*11b ==> protection from 11b +*each byte will have the following info +*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 +*reserved reserved RIFS Lsig n-GF ht20 11g 11b +********************************** +WNI_CFG_PROTECTION_ENABLED I 4 9 +V RW NP RESTART +LIM +0 0xffff 0xffff +V RW NP RESTART +LIM +0 0xffff 0xffff + +#ENUM FROM_llA 0 +#ENUM FROM_llB 1 +#ENUM FROM_llG 2 +#ENUM HT_20 3 +#ENUM NON_GF 4 +#ENUM LSIG_TXOP 5 +#ENUM RIFS 6 +#ENUM OBSS 7 +#ENUM OLBC_FROM_llA 8 +#ENUM OLBC_FROM_llB 9 +#ENUM OLBC_FROM_llG 10 +#ENUM OLBC_HT20 11 +#ENUM OLBC_NON_GF 12 +#ENUM OLBC_LSIG_TXOP 13 +#ENUM OLBC_RIFS 14 +#ENUM OLBC_OBSS 15 + + +* **************************************** +* +* 11G Protection Enable Always +* Valid only if protection is enabled +* forces uses of protection regardless of legacy stations +* + +WNI_CFG_11G_PROTECTION_ALWAYS I 4 9 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +********************************************* +* Force protection +* 0 : disable protection +* 1 : CTS +* 2 : RTS by threshold (threshold nonzero) +* 3 : dual CTS (not supported right now) +* 4 : RTS (threshold 0) +* 5 : auto + +WNI_CFG_FORCE_POLICY_PROTECTION I 4 9 +V RW NP RESTART +HAL +0 5 5 +V RW NP RESTART +HAL +0 5 5 + +#ENUM DISABLE 0 +#ENUM CTS 1 +#ENUM RTS 2 +#ENUM DUAL_CTS 3 +#ENUM RTS_ALWAYS 4 +#ENUM AUTO 5 + + + + + + +******************************************** +* 11G Short Preamble Enable +* + +WNI_CFG_11G_SHORT_PREAMBLE_ENABLED I 4 9 +V RW NP RESTART +NONE +0 1 0 +V RW NP RESTART +NONE +0 1 0 + +* +* 11G Short Slot Time Enable (change requires restart) +* This is the admin state of short slot support. + +WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED I 4 9 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* Calibration periodicity (minutes) +* + +WNI_CFG_CAL_PERIOD I 4 12 +V RW NP +HAL +2 10 5 +V RW NP +HAL +2 10 5 + +* +* Statistics collection periodicity (seconds) +* + +WNI_CFG_STATS_PERIOD I 4 12 +V RW NP +HAL +1 10 10 +V RW NP +HAL +1 10 10 + +* +* Calibration on/off control +* + +WNI_CFG_CAL_CONTROL I 4 12 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +#ENUM CAL_ON 0 +#ENUM CAL_OFF 1 + + +* +* Parameter to allow 11g only STAs while operating in 11g mode +* + +WNI_CFG_11G_ONLY_POLICY I 4 12 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Packet Classification +* This flag is a bitmask used to indicate which +* frame classifier to be enabled: +* b0: DSCP +* b1: 802.1P +* + +WNI_CFG_PACKET_CLASSIFICATION I 4 12 +V RW NP +HAL +0 3 0 +V RW NP +HAL +0 3 0 + +#ENUM DISABLED 0 +#ENUM DSCP 1 +#ENUM 8021P 2 +#ENUM ALL 3 + +* +* WME Enabled (change requires restart) +* + +WNI_CFG_WME_ENABLED I 4 8 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +* +* ADDTS response timeout (in ms) +* + +WNI_CFG_ADDTS_RSP_TIMEOUT I 4 8 +V RW NP +NONE +0 65535 1000 +V RW NP +NONE +0 65535 1000 + + + * Max SP Length indicates the max number of + * total buffered MSDUs and MMPDUs the WMM AP + * may deliver to WMM STA during any service period + * triggered by WMM STA. + * 1) If AP sends WMM IE with the UAPSD bit 0, max_sp_length=0 + * 2) If WMM STA's all 4 UAPSD flag are set to 0, max_sp_length=0 + * 3) If AP sends WMM IE with UAPSD=1, and at least one of stations + * UAPSD flag is set to 1, then max_sp_length can be set to: + * [b5:b6]=0x00: WMM AP may deliver all buffered frames + * [b5:b6]=0x10: WMM AP may deliver max 2 buffered frames + * [b5:b6]=0x01: WMM AP may deliver max 4 buffered frames + * [b5:b6]=0x11: WMM AP may deliver max 6 buffered frames + +WNI_CFG_MAX_SP_LENGTH I 4 8 +V RW NP +NONE +0 3 0 +V RW NP +NONE +0 3 0 + + +* +* KEEP ALIVE STA Limit Threshold , used in AP to delete the STA +* from Station Table which didn't respond to Probe Response Messages +* + +WNI_CFG_KEEP_ALIVE_STA_LIMIT_THRESHOLD I 4 8 +NV RW NP +NONE +0 32 0 +V RW NP +NONE +0 32 0 + +* +* Parameter that specifies whether to send SSID +* in Probe Response when SSID is suppressed +* + +WNI_CFG_SEND_SINGLE_SSID_ALWAYS I 4 12 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* WSM Enabled (change requires restart) +* Takes effect only if WME is also enabled +* + +WNI_CFG_WSM_ENABLED I 4 8 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* **************************************** +* +* Proprietary IE capability enable +* bit mapped: +* 0:HCF 1:11eQos 2:WME 3:WSM 4:EXT_RATES +* 5:EXTRATE_STOP +* 6:Titan device 7:Taurus Device +* 13:EDCA 14:LOADINFO 15:VERSION +* + +WNI_CFG_PROP_CAPABILITY I 4 8 +V RW NP +NONE +0 0xffff 0xe0bf +V RW NP +NONE +0 0xffff 0xc0a9 + +#ENUM HCF 0 +#ENUM 11EQOS 1 +#ENUM WME 2 +#ENUM WSM 3 +#ENUM EXTRATES 4 +#ENUM EXTRATE_STOP 5 +#ENUM TITAN 6 +#ENUM TAURUS 7 +#ENUM EDCAPARAMS 13 +#ENUM LOADINFO 14 +#ENUM VERSION 15 +#ENUM MAXBITOFFSET 15 + +* **************************************** +* +* Background Channel List +* Contains pairs of {channelNumber, scanType} +* where scanType = 0 indicates active scan and +* = 1 indicates passive scan +* +* +*WNI_CFG_BACKGROUND_SCAN_LIST S 128 8 +*V RW NP RESTART +*LIM +*60 36 0 40 0 44 0 48 0 52 0 56 0 60 0 64 0 1 0 6 0 11 0 34 0 38 0 42 0 46 0 2 0 3 0 4 0 5 0 7 0 8 0 9 0 10 0 12 0 13 0 14 0 149 0 153 0 157 0 161 0 +*V RW NP RESTART +*LIM +*60 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 34 0 36 0 38 0 40 0 42 0 44 0 46 0 48 0 52 0 56 0 60 0 64 0 149 0 153 0 157 0 161 0 +* + +* **************************************** +* EDCA paramters are contained in profiles - each profile contains +* the parameters [ACM, AIFSN, CWmin, CWmax, TxOp] for four +* access categories (i.e., four sets). Two such sets of four parameters +* make a single profile: One set is used locally by the AP, the other set +* is broadcast for use by stations. +* +* Cwmin and Cwmax are two bytes each, MSB first. So Cwmin of [3 255] is +* equivalent to 0x3ff, i.e. 3*256+255=1023 +* +* The profile to use is selected based on the valus of the profile select param +* See ENUMs below for definitions of profile values +* + +WNI_CFG_EDCA_PROFILE I 4 8 +V RW NP +SCH +0 255 1 +V RW NP +SCH +0 255 1 + +#ENUM ANI 0 +#ENUM WMM 1 +#ENUM TIT_DEMO 2 +#ENUM MAX 3 + +#ENUM ACM_IDX 0 +#ENUM AIFSN_IDX 1 +#ENUM CWMINA_IDX 2 +#ENUM CWMAXA_IDX 4 +#ENUM TXOPA_IDX 6 +#ENUM CWMINB_IDX 7 +#ENUM CWMAXB_IDX 9 +#ENUM TXOPB_IDX 11 +#ENUM CWMING_IDX 12 +#ENUM CWMAXG_IDX 14 +#ENUM TXOPG_IDX 16 + + +* **************************************** +* Profile 0 (Airgo) parameters - AC_BK Local +* ACM, AIFSN, [CWminH, CWminL, CWmaxH, CWmaxL, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBK_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 + +* +* Profile 0 (Airgo) parameters AC_BE Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBE_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 + +* +* Profile 0 (Airgo) parameters AC_VI Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVI_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 + +* +* Profile 0 (Airgo) parameters AC_VO Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVO_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 + +* +* Profile 0 (Airgo) parameters - AC_BK Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBK S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 + +* +* Profile 0 (Airgo) parameters AC_BE Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACBE S 20 8 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 +V RW NP RESTART +NONE +17 0 2 0 15 3 255 100 0 31 3 255 100 0 15 3 255 100 + +* +* Profile 0 (Airgo) parameters AC_VI Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVI S 20 8 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 200 0 15 0 31 188 0 7 0 15 200 + +* +* Profile 0 (Airgo) parameters AC_VO Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_ANI_ACVO S 20 8 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 100 0 7 0 15 102 0 3 0 7 100 + + +* **************************************** +* Profile 1 (WME) parameters - AC_BK Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBK_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 31 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 + + +* +* Profile 1 (WME) parameters AC_BE Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBE_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 3 0 15 0 63 0 0 31 3 255 0 0 15 0 63 0 +V RW NP RESTART +NONE +17 0 3 0 15 0 63 0 0 15 0 63 0 0 15 0 63 0 + +* +* Profile 1 (WME) parameters AC_VI Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVI_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 1 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 +V RW NP RESTART +NONE +17 0 1 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 + +* +* Profile 1 (WME) parameters AC_VO Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVO_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 1 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 +V RW NP RESTART +NONE +17 0 1 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 + +* +* Profile 1 (WME) parameters - AC_BK Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBK S 20 8 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 7 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 + +* +* Profile 1 (WME) parameters AC_BE Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACBE S 20 8 +V RW NP RESTART +NONE +17 0 3 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 +V RW NP RESTART +NONE +17 0 3 0 15 3 255 0 0 15 3 255 0 0 15 3 255 0 + +* +* Profile 1 (WME) parameters AC_VI Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVI S 20 8 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 +V RW NP RESTART +NONE +17 0 2 0 7 0 15 94 0 7 0 15 188 0 7 0 15 94 + +* +* Profile 1 (WME) parameters AC_VO Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_WME_ACVO S 20 8 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 +V RW NP RESTART +NONE +17 0 2 0 3 0 7 47 0 3 0 7 102 0 3 0 7 47 + +* **************************************** +* Profile 2(Titan Demo) parameters - AC_BK Local +* ACM, AIFSN, [CWminH, CWminL, CWmaxH, CWmaxL, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_BE Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 31 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VI Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VO Local +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters - AC_BK Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBK S 20 8 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 7 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_BE Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACBE S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VI Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVI S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Profile 2(Titan Demo) parameters AC_VO Broadcast +* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G +* + +WNI_CFG_EDCA_TIT_DEMO_ACVO S 20 8 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 +V RW NP RESTART +NONE +17 0 2 0 8 0 255 200 0 8 0 255 200 0 8 0 255 200 + +* +* Radar detector flag enable/disable +* + +WNI_CFG_RDET_FLAG I 4 9 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + +WNI_CFG_RADAR_CHANNEL_LIST S 20 8 +V RW NP RESTART +NONE +15 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 +V RW NP RESTART +NONE +15 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 + +* +* Local Power Constraint (dBm) +* + +WNI_CFG_LOCAL_POWER_CONSTRAINT I 4 12 +V RW NP RESTART +NONE +0 255 0 +V RW NP RESTART +NONE +0 255 0 + +* ********************************************************* +* +* Admission Control Policy +* used for admitting tspec's when either edca or hcca are in use +* + +WNI_CFG_ADMIT_POLICY I 4 8 +V RW NP RESTART +NONE +0 2 0 +V RW NP +SCH +0 2 0 + +#ENUM ADMIT_ALL 0 +#ENUM REJECT_ALL 1 +#ENUM BW_FACTOR 2 + +* +* Oversubscription factor for admission control +* valid only when admit policy is set to BW_FACTOR +* units are in terms of 1/10th of available bandwidth +* + +WNI_CFG_ADMIT_BWFACTOR I 4 8 +V RW NP RESTART +NONE +0 100 20 +V RW NP +SCH +0 100 20 + +* ********************************************************* +* +* Number of "consecutive" Background Scan Failure needed +* before LIM is forced to perform 1 aggressive background scan +* +WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE I 4 8 +V RW NP RESTART +NONE +0 256 60 +V RW NP RESTART +NONE +0 256 60 + + +************************************* +* Feature: Channel Bonding +************************************* +* +* Global flag to enable/disable Channel Bonding +* 0 - Disable: Force disable channel bonding for all TC-ids +* 1 - Enable: Force enable channel bonding for all TC-ids +* 2 - no legacy bss: Enable channel bonding if no legacy BSS are present +* 3 - no legacy all: Enable channel bonding if no legacy BSS or devices are present +* 4 - intelligent: Enable channel bonding depending on load level on secondary channel +* +WNI_CFG_CHANNEL_BONDING_MODE I 4 12 +V RW NP RESTART +LIM +0 10 0 +V RW NP RESTART +LIM +0 10 0 + +#ENUM DISABLE 0 +#ENUM ENABLE 1 +#ENUM IF_NO_LEGACY_BSS 2 +#ENUM IF_NO_LEGACY_ALL 3 +#ENUM INTELLIGENT 4 + + +* +* When the channel is 40MHz wide, this CFG indicates +* if the secondary channel is located above (at +* a higher frequency), or located below (at a +* lower frequency). +* +* 0 - There is no secondary channel. The channel is 20Mhz +* 1 - LOWER: Secondary channel 40MHZ is located below the primary channel +* 2 - CENTERED:Secondary channel and primary located at centered +* 3 - HIGHER: Secondary channel 40 MHZ is located above the primary channel +* 4 - 80MHZ_LOW_CENTERED : 20/40MHZ offset LOW 40/80MHZ offset CENTERED +* 5 - 80MHZ_CENTERED_CENTERED : 20/40MHZ offset CENTERED 40/80MHZ offset CENTERED +* 6 - 80MHZ_HIGH_CENTERED : 20/40MHZ offset HIGH 40/80MHZ offset CENTERED +* 7 - 80MHZ_LOW_LOW: 20/40MHZ offset LOW 40/80MHZ offset LOW +* 8 - 80MHZ_HIGH_LOW: 20/40MHZ offset HIGH 40/80MHZ offset LOW +* 9 - 80MHZ_LOW_HIGH: 20/40MHZ offset LOW 40/80MHZ offset HIGH +* 10 - 80MHZ_HIGH_HIGH: 20/40MHZ offset HIGH 40/80MHZ offset HIGH +* +WNI_CFG_CB_SECONDARY_CHANNEL_STATE I 4 12 +V RW NP +NONE +0 10 0 +V RW NP +NONE +0 10 0 + +#ENUM NONE 0 +#ENUM LOWER 1 +#ENUM HIGHER 2 +#ENUM 11AC_20MHZ_LOW_40MHZ_CENTERED 3 +#ENUM 11AC_20MHZ_CENTERED_40MHZ_CENTERED 4 +#ENUM 11AC_20MHZ_HIGH_40MHZ_CENTERED 5 +#ENUM 11AC_20MHZ_LOW_40MHZ_LOW 6 +#ENUM 11AC_20MHZ_HIGH_40MHZ_LOW 7 +#ENUM 11AC_20MHZ_LOW_40MHZ_HIGH 8 +#ENUM 11AC_20MHZ_HIGH_40MHZ_HIGH 9 + +************************************* +* Feature: Dynamic Retry Rates +************************************* +* +* When the short/long retry count reach the +* adaptive_retry_threshold(0), then the retry0 +* template shall be used +* +WNI_CFG_DYNAMIC_THRESHOLD_ZERO I 4 12 +V RW NP +HAL +0 255 2 +V RW NP +HAL +0 255 2 + +* +* When the short/long retry count reach the +* adaptive_retry_threshold(1), then the retry1 +* template shall be used +* +WNI_CFG_DYNAMIC_THRESHOLD_ONE I 4 12 +V RW NP +HAL +0 255 4 +V RW NP +HAL +0 255 4 + +* +* When the short/long retry count reach the +* adaptive_retry_threshold(2), then the retry2 +* template shall be used +* +WNI_CFG_DYNAMIC_THRESHOLD_TWO I 4 12 +V RW NP +HAL +0 255 6 +V RW NP +HAL +0 255 6 + + +* +* Trigger Station Background Scan Flag +* +WNI_CFG_TRIG_STA_BK_SCAN I 4 12 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 1 + +* ********************************************************* +* control of dynamic EDCA parameter profile switching +* +* OOB, we would like to support WMM standard edca profile +* However, when Airgo STA's join the BSS, we would like +* to switch the profile to Airgo high-performance edca parameters +* +* This cfg supports that behaviour. It is used only if 11e qos +* has been enabled and is ignored otherwise. +* +* When set to any value (other than unused), it determines the +* edca profile to switch to when an Airgo STA joins the BSS. +* +* By default, we choose to switch to Airgo profile. +* +* NOTE: This parameter applies only to an AP +* + +WNI_CFG_DYNAMIC_PROFILE_SWITCHING I 4 8 +V RW NP RESTART +NONE +0 255 255 +V RW NP RESTART +NONE +0 255 1 + +#ENUM UNUSED 255 + +* ********************************************************* +* +* Scan control list +* Contains pairs of {channelNumber, activeScanAllowedFlag} +* where scanType = 1 indicates active scan is allowed, and +* = 0 indicates passive scan is used +* If a channel is not on this list, active scan is NOT allowed. So it is +* sufficient to inlude only those channels where active scan is allowed +* on this list. +* +* The list determines only whether active scan is allowed or not; it does not +* determine which type of scan is actually performed. +* + +WNI_CFG_SCAN_CONTROL_LIST S 128 8 +V RW NP RESTART +LIM +112 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 0 54 0 56 0 58 0 60 0 62 0 64 0 100 0 104 0 108 0 112 0 116 0 120 0 124 0 128 0 132 0 136 0 140 0 149 1 151 1 153 1 155 1 157 1 159 1 161 1 165 1 240 1 242 1 244 1 246 1 248 1 250 1 252 1 +V RW NP RESTART +LIM +112 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 34 1 36 1 38 1 40 1 42 1 44 1 46 1 48 1 50 1 52 0 54 0 56 0 58 0 60 0 62 0 64 0 100 0 104 0 108 0 112 0 116 0 120 0 124 0 128 0 132 0 136 0 140 0 149 1 151 1 153 1 155 1 157 1 159 1 161 1 165 1 240 1 242 1 244 1 246 1 248 1 250 1 252 1 + + +* **************************************** +* +* MIMO rates enabled (for rate adaptation, to start) +* + +WNI_CFG_MIMO_ENABLED I 4 9 +V RW NP RELOAD +NONE +0 1 1 +V RW NP RELOAD +NIM +0 1 1 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + + +* +* BLOCK ACK Enabled (change requires restart) +* change default to ON +* bit 0 ==> delayed BA +* bit 1 ==> immediate BA +WNI_CFG_BLOCK_ACK_ENABLED I 4 8 +V RW NP RESTART +LIM +0 3 0 +V RW NP RESTART +LIM +0 3 0 + +#ENUM DELAYED 0 +#ENUM IMMEDIATE 1 + + +* +*BA Activity check global timer +* +WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT I 4 7 +V RW NP +HAL +0 65535 1000 +V RW NP +HAL +0 65535 1000 + + +* +* Rx STBC support +* +WNI_CFG_HT_RX_STBC I 4 7 +V RW NP RESTART +LIM +0 3 1 +V RW NP RESTART +LIM +0 3 1 + + +* +* 1. HT capabilities Info: 2 bytes size +* +* Supported channel Width is set to 1 (40 Mhz) +* SM Power Save is disabled. +* GreenField support is enabled. +* Short GI for 20 and 40Mhz is enabled. +* Max AMSDU Size is set to 0(3839 Octets) +* DSSS-CCK Mode is enabled. +* LSIG TXOP Protection is disabled +* Rest of the features are not supported at this moment. +* +* fedc ba98 7654 3210 +* 0000 0001 0010 0000 +* +WNI_CFG_HT_CAP_INFO I 4 10 +V RW NP RESTART +LIM +0 0xffff 0x016c +V RW NP RESTART +LIM +0 0xffff 0x106e + +#ENUM ADVANCE_CODING 0 +#ENUM SUPPORTED_CHAN_WIDTH_SET 1 +#ENUM SM_POWER_SAVE 2 +#ENUM GREEN_FIELD 4 +#ENUM SHORT_GI_20MHZ 5 +#ENUM SHORT_GI_40MHZ 6 +#ENUM TX_STBC 7 +#ENUM RX_STBC 8 +#ENUM DELAYED_BA 10 +#ENUM MAX_AMSDU_SIZE 11 +#ENUM DSSS_CCK_MODE_40MHZ 12 +#ENUM PSMP 13 +#ENUM STBC_CONTROL_FRAME 14 +#ENUM LSIG_TXOP_PROTECTION 15 + +* +* 2. HT Parameters Info: 1 byte size +* +* Max AMPDU Rx Factor is defined using bit #0 and #1 +* MPDU Density is defined using bit #2 thru #4. +* The default values are, +* 7654 3210 +* 0000 0010 --> 2 for RX AMPDU Factor, 0 for MPDU density +* +WNI_CFG_HT_AMPDU_PARAMS I 4 7 +V RW NP RESTART +LIM +0 0xff 0x00 +V RW NP RESTART +LIM +0 0xff 0x02 + +#ENUM MAX_RX_AMPDU_FACTOR 0 +#ENUM MPDU_DENSITY 2 +#ENUM RESERVED 5 + +* +* 3. Supported MCS Set: 16 bytes size +* +* MCS #0-15 and #32 is supported. +* +WNI_CFG_SUPPORTED_MCS_SET S 16 7 +V RW P RESTART +LIM +16 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +V RW P RESTART +LIM +16 255 255 0 0 1 0 0 0 0 0 0 0 0 0 0 0 + +* +* 4. Extended HT Capabilities Info: 2 bytes size +* +* Only HTC Support is enabled, rest all features are not +* supported at this moment. +* +* fedc ba98 7654 3210 +* 0000 0100 0000 0000 +* +WNI_CFG_EXT_HT_CAP_INFO I 4 10 +V RW P RESTART +LIM +0 0xffff 0x0400 +V RW P RESTART +LIM +0 0xffff 0x0400 + +#ENUM PCO 0 +#ENUM TRANSITION_TIME 1 +#ENUM RESERVED1 3 +#ENUM MCS_FEEDBACK 8 +#ENUM HTC_SUPPORT 10 +#ENUM RD_RESPONDER 11 +#ENUM RESERVED2 12 + + +* +* 5. Transmit Beam Forming Capabiliries Info: 4 bytes size +* +WNI_CFG_TX_BF_CAP I 4 7 +V RO NP RESTART +LIM +0 0xffffffff 0x00000000 +V RO NP RESTART +LIM +0 0xffffffff 0x00000000 + +* +* 6. Antenna Selection Capabilities: 1 byte size +* +WNI_CFG_AS_CAP I 4 7 +V RW P RESTART +LIM +0 0xff 0x00 +V RW P RESTART +LIM +0 0xff 0x00 + +#ENUM ANTENNA_SELECTION 0 +#ENUM EXPLICIT_CSI_FEEDBACK_TX 1 +#ENUM ANTENNA_INDICES_FEEDBACK_TX 2 +#ENUM EXPLICIT_CSI_FEEDBACK 3 +#ENUM ANTENNA_INDICES_FEEDBACK 4 +#ENUM RX_AS 5 +#ENUM TX_SOUNDING_PPDUS 6 +#ENUM RESERVED 7 + +************************************************** +* Beacon HT (High Through) Info IE +*************************************************** +* +* 3. HT Info Field1: 1 byte size. +* +* Secondary Channel Offset is set to 3 (Down) by default and will +* be updated dynamically by DFS algorithm. +* Channel Width is set to 1 (40 Mhz) +* RIFS Mode is enabled +* Rest of the features are not supported at this moment. +* +* 7654 3210 +* 0000 1111 +* +WNI_CFG_HT_INFO_FIELD1 I 4 10 +V RW NP RESTART +LIM +0 0xff 0x0f +V RW NP RESTART +LIM +0 0xff 0x0f + +#ENUM SECONDARY_CHANNEL_OFFSET 0 +#ENUM RECOMMENDED_CHANNEL_WIDTH 2 +#ENUM RIFS_MODE 3 +#ENUM PSMP_ACCESS_ONLY 4 +#ENUM SERVICE_INTERVAL_GRANULARITY 5 + +* +* 4. HT Info Field2: 2 bytes +* +* Operation mode is set to 0(Pure, GF) to begin with and +* will be updated dynamically. +* 'NonGF Devices present is also set to zero and +* will be updated dynamically. +* +* fedc ba98 7654 3210 +* 0000 0000 0000 0000 +* +WNI_CFG_HT_INFO_FIELD2 I 4 10 +V RW P +LIM +0 0xffff 0x00 +V RW P +LIM +0 0xffff 0x00 + +#ENUM OP_MODE 0 +#ENUM NON_GF_DEVICES_PRESENT 2 +#ENUM RESERVED 3 + +* +* 5. HT Info Field3: 2 bytes +* +* fedc ba98 7654 3210 +* 0000 0000 0000 0000 +* +* LSIG TXOP Full Protection will be zero to begin with and +* updated dynamically. +* Everything else is not supported at this moment. +* +WNI_CFG_HT_INFO_FIELD3 I 4 10 +V RW P +LIM +0 0xffff 0x0000 +V RW P +LIM +0 0xffff 0x0000 + +#ENUM BASIC_STBC_MCS 0 +#ENUM DUAL_STBC_PROTECTION 7 +#ENUM SECONDARY_BEACON 8 +#ENUM LSIG_TXOP_PROTECTION_FULL_SUPPORT 9 +#ENUM PCO_ACTIVE 10 +#ENUM PCO_PHASE 11 +#ENUM RESERVED 12 + +* +* 6. Basic MCS Set: 16 bytes size +* +* For now set this to zero and don't put any restrictions. +* +WNI_CFG_BASIC_MCS_SET S 16 7 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +* +* 7. Current supported MCS Set: 16 bytes size +* +* For now set this to zero and don't put any restrictions. +* +WNI_CFG_CURRENT_MCS_SET S 16 7 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +V RW P RESTART +LIM +16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + + +* +* Greenfield Capability +* By default Greenfield is enabled +* +WNI_CFG_GREENFIELD_CAPABILITY I 4 7 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 0 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + +* +* Maximum AMPDU Length +* By default set to zero for 3895 octets +* +WNI_CFG_VHT_MAX_MPDU_LENGTH I 4 19 +V RW NP +LIM +0 2 0 +V RW NP +LIM +0 2 0 + +* +* Supported Channel Width Set +* By default set to zero for +* STAs does not support either 160 or 80+80MHz +* +WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* LDPC Coding Capability +* Riva/Pronto supports, default set to 1 +* +WNI_CFG_VHT_LDPC_CODING_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Short GI for 80MHz +* Riva/Pronto supports, default set to 1 +* +WNI_CFG_VHT_SHORT_GI_80MHZ I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* Short GI for 160MHz and 80+80MHz +* Riva/Pronto does not supports, default set to 0 +* +WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Support for Transmission of 2x1 STBC +* Riva/Pronto does not supports, default set to 0 +* +WNI_CFG_VHT_TXSTBC I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Support for Reception of PPDUs using STBC +* Riva/Pronto supports, default set to 1 +* +WNI_CFG_VHT_RXSTBC I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* Support for Operating as SU Beamformer +* Riva/Pronto does not supports, default set to 0 +* +WNI_CFG_VHT_SU_BEAMFORMER_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Support for Operating as SU Beamformee +* Riva does not support, But Pronto supports, default set to 0 +* +WNI_CFG_VHT_SU_BEAMFORMEE_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Compressed Steering Number of Beamformer Antennas Supported +* Riva does not support,Pronto supports, default set to 0 +* +WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED I 4 19 +V RW NP +LIM +0 4 0 +V RW NP +LIM +0 4 0 + +* +* Number of Sounding Dimensions indicates Number +* of antennas used by the beamformer when sending beamformed transmissions +* Riva/Pronto does not support beamformer, default set to 0 +* +WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS I 4 19 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +* +* MU Beamformer Capable +* Riva/Pronto does not support, default set to 0 +* +WNI_CFG_VHT_MU_BEAMFORMER_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* MU Beamformee Capable +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_MU_BEAMFORMEE_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* VHT TXOP PS +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_TXOP_PS I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* +HTC-VHT Capable +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_HTC_VHTC_CAP I 4 19 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Maximum AMPDU Length exponent range 0-7 +* 2^(13+Max AMPDU Length)-1, default set to 0 +* +WNI_CFG_VHT_AMPDU_LEN_EXPONENT I 4 19 +V RW NP +LIM +0 7 3 +V RW NP +LIM +0 7 3 + +* +* VHT Link Adaptation Capable +* Riva does not support but pronto supports, default set to 0 +* +WNI_CFG_VHT_LINK_ADAPTATION_CAP I 4 19 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +* +* VHT Rx Antenna Pattern Consistency +* +WNI_CFG_VHT_RX_ANT_PATTERN I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* VHT Tx Antenna Pattern Consistency +* +WNI_CFG_VHT_TX_ANT_PATTERN I 4 19 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + +* +* RxMCS Map is 16 bits, The 2bit Max MCS for n SS field. +* Indicates the maximum MCS that can be received for each +* number of spacial streams. Riva supports MCS 0-9 +* +WNI_CFG_VHT_RX_MCS_MAP I 4 19 +V RW NP +LIM +0 0xFFFF 0xFFFE +V RW NP +LIM +0 0xFFFF 0xFFFE + +* TxMCS Map is 16 bits, The 2bit Max MCS for n SS field. +* Indicates the maximum MCS that can be transmitted for each +* number of spacial streams. +* +WNI_CFG_VHT_TX_MCS_MAP I 4 19 +V RW NP +LIM +0 0xFFFF 0xFFFE +V RW NP +LIM +0 0xFFFF 0xFFFE + +* +* Rx Highest supported data rate. +* +WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE I 4 19 +V RW NP +LIM +0 390 0 +V RW NP +LIM +0 390 0 + +* +* Tx Highest supported data rate. +* +WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE I 4 19 +V RW NP +LIM +0 390 0 +V RW NP +LIM +0 390 0 + +* +* VHT Operation Information +* Channel Width set to zero for 20/40MHz. +* set to 1 for 80MHz. 2->160Mhz, 3->80+80MHz +* +WNI_CFG_VHT_CHANNEL_WIDTH I 4 19 +V RW NP +LIM +0 3 0 +V RW NP +LIM +0 3 0 + +#ENUM 20_40MHZ 0 +#ENUM 80MHZ 1 +#ENUM 160MHZ 2 +#ENUM 80_PLUS_80MHZ 3 +* +* Channel center freq Seg1 +* +WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1 I 4 19 +V RW NP +LIM +0 256 0 +V RW NP +LIM +0 256 0 + +* +* Channel center freq Seg2 for 80+80 Mhz +* +WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2 I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Basic MCS Set +* +WNI_CFG_VHT_BASIC_MCS_SET I 4 19 +V RW NP +LIM +0 0xFFFF 0xFFFE +V RW NP +LIM +0 0xFFFF 0xFFFE + +* +* MU-MIMO Capable STA Count +* +WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT I 4 19 +V RW NP +LIM +0 4 0 +V RW NP +LIM +0 4 0 + +* +* Spatial Stream Under-Utilization +* +WNI_CFG_VHT_SS_UNDER_UTIL I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Forty MHZ Utilization +* +WNI_CFG_VHT_40MHZ_UTILIZATION I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Eighty MHz Utilization +* +WNI_CFG_VHT_80MHZ_UTILIZATION I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Hundred Sixty MHz Utilization +* +WNI_CFG_VHT_160MHZ_UTILIZATION I 4 19 +V RW NP +LIM +0 0 0 +V RW NP +LIM +0 0 0 + +* +* Maximum AMSDU length +* User can set it to either 3839 or 7935 bytes. +* +WNI_CFG_MAX_AMSDU_LENGTH I 4 7 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 0 + +#ENUM SHORT_3839_BYTES 0 +#ENUM LONG_7935__BYTES 1 + + +* +* Minimum MPDU Start Spacing +* Determines the minimum time between the start of adjacent MPDUs within an AMPDU. +* Set to 0 for no restriction +* Set to 1 for 1/4 s +* Set to 2 for 1/2 s +* Set to 3 for 1 s +* Set to 4 for 2 s +* Set to 5 for 4 s +* Set to 6 for 8 s +* Set to 7 for 16 s +* default is set to 0 +WNI_CFG_MPDU_DENSITY I 4 7 +V RW NP RESTART +LIM +0 7 0 +V RW NP RESTART +LIM +0 7 0 + +* +* NUM BUFFERS ADVERTISED +* Defines number of buffers advertised in ADDBA +* +WNI_CFG_NUM_BUFF_ADVERT I 4 7 +V RW NP +LIM +0 128 64 +V RW NP +LIM +0 128 64 + +* +* Maximum Rx AMPDU Factor +* Indicates the maximum length of A-MPDU +* that the STA can receive. +* The Maximum Rx A-MPDU defined by this field is equal to (2 ^ (13 + MAX RX AMPDU FActor))-1 octets. +* Maximum Rx A-MPDU Factor is an integer in the range 0 to 3. +* default is set to 2 for 32K max RX side. +* +WNI_CFG_MAX_RX_AMPDU_FACTOR I 4 7 +V RW NP RESTART +LIM +0 3 3 +V RW NP RESTART +LIM +0 3 3 + + +* +* Short GI support for the reception of 20Mhz packets +* By default it is enabled +* +WNI_CFG_SHORT_GI_20MHZ I 4 7 +V RW NP RESTART +LIM +0 1 1 +V RW NP RESTART +LIM +0 1 1 + + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + +* +* Short GI support for the reception of 40Mhz packets +* By default it is enabled +* +WNI_CFG_SHORT_GI_40MHZ I 4 7 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 1 + + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + +* +* RIFS support on TX Side +* on RX side it is always supported, it is mandatory +* +WNI_CFG_RIFS_ENABLED I 4 7 +V RW NP RESTART +NONE +0 1 1 +V RW NP RESTART +NONE +0 1 1 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + + +* ********************************************************* +* +* Power Save Configuration +* +WNI_CFG_MAX_PS_POLL I 4 5 +V RW NP +LIM +0 255 0 +NV RW NP +LIM +0 255 0 + + +WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE I 4 5 +V RW NP +LIM +1 20 20 +NV RW NP +LIM +1 20 20 + + +* +* Period for which Firmware will collect the +* RSSI stats. Its in units of beacon interval. +* Rssi Filter period should always be >= +* the num_beacon_per_rssi_average. +* +WNI_CFG_RSSI_FILTER_PERIOD I 4 5 +V RW NP +LIM +0 255 5 +NV RW NP +LIM +0 255 5 + + +WNI_CFG_MIN_RSSI_THRESHOLD I 4 5 +V RW NP +LIM +0 10 10 +NV RW NP +LIM +0 10 10 + + +WNI_CFG_NTH_BEACON_FILTER I 4 5 +V RW NP +LIM +0 255 10 +NV RW NP +LIM +0 255 10 + + +WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE I 4 5 +V RW NP +LIM +0 1 0 +NV RW NP +LIM +0 1 0 + + +WNI_CFG_SCAN_IN_POWERSAVE I 4 5 +V RW NP +LIM +0 1 1 +V RW NP +LIM +0 1 1 + + +* +* Ignore DTIM support - If disabled(value=0), HAL will +* try to align the Listen Interval to the DTIM +* period and the following rules will be applied: +* 1) If LI=DTIM, then set LI=DTIM +* 2) If LIDTIM, then set LI=DTIM +* +WNI_CFG_IGNORE_DTIM I 4 5 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* ********************************************************* +* +* WoWLAN Configuration The following configurations +* are valid only when magicPktEnable = 1. +* +WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_DEAUTH_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_DISASSOC_ENABLE I 4 5 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 0 + + +WNI_CFG_WOWLAN_MAX_MISSED_BEACON I 4 5 +V RW NP +NONE +0 65535 40 +NV RW NP +NONE +0 65535 40 + +* +* Timeout value in units of us. It requests +* hardware to unconditionally wake up after +* it has stayed in WoWLAN mode for some time. +* +WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD I 4 5 +V RW NP +NONE +0 65535 65535 +NV RW NP +NONE +0 65535 65535 + + +* +* BA timeout in TUs, set to 1 minute = approx 58593 TUs +* 16 bit wide +* +WNI_CFG_BA_TIMEOUT I 4 7 +V RW NP RESTART +HAL +0 0xffff 0 +V RW NP +HAL +0 0xffff 0 + + +* +* This threshold is registered with a traffic monitoring interface (probably HAL), +* on a per-STA, per-TID basis. Once this threshold has been reached, +* HAL will indicate to PE that the threshold has been reached for that TID. +* PE is then free to negotiate a BA session for that peer +* defaults to 128 +* 16 bit wide +* +WNI_CFG_BA_THRESHOLD_HIGH I 4 7 +V RW NP RESTART +HAL +0 0xffff 0x80 +V RW NP +HAL +0 0xffff 0x80 + + +* +* MAX BA Buffers to be allocated. +* This count is system wide. +* 16 bit wide +* +WNI_CFG_MAX_BA_BUFFERS I 4 7 +V RW NP RESTART +HAL +0 2560 2560 +V RW NP +HAL +0 2560 2560 + + +* +* MAX BA Sessions. +* This count is system wide. +* 16 bit wide +* +WNI_CFG_MAX_BA_SESSIONS I 4 7 +V RW NP RESTART +HAL +0 64 40 +V RW NP +HAL +0 64 40 + + +* +* BA setup based on Traffic +* +WNI_CFG_BA_AUTO_SETUP I 4 7 +V RW NP RESTART +HAL +0 1 1 +V RW NP RESTART +HAL +0 1 1 + +#ENUM ENABLE 1 +#ENUM DISABLE 0 + +* +* Decline an ADDBA Request +* +WNI_CFG_ADDBA_REQ_DECLINE I 4 7 +V RW NP RESTART +LIM +0 0xff 0 +V RW NP RESTART +LIM +0 0xff 0 + +* +* Delete all Rx BA sessions in 2.4 GHz +* when BTC requests to disable agg. +* +WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + + +* +* Valid Channel List +* + +WNI_CFG_BG_SCAN_CHANNEL_LIST S 100 8 +V RW NP +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 +V RW NP +LIM +55 36 40 44 48 52 56 60 64 1 6 11 34 38 42 46 2 3 4 5 7 8 9 10 12 13 14 100 104 108 112 116 120 124 128 132 136 140 149 151 153 155 157 159 161 50 54 58 62 240 242 244 246 248 250 252 + + +* +* AMPDU default TX medium Time (in us) +* +WNI_CFG_MAX_MEDIUM_TIME I 4 8 +V RW NP +HAL +0 65535 2048 +V RW NP +HAL +0 65535 2048 + + +* +* Maximum number of MPDUs in single A-MPDU. +* +WNI_CFG_MAX_MPDUS_IN_AMPDU I 4 8 +V RW NP +HAL +0 65535 64 +V RW NP +HAL +0 65535 64 + + +* +* Auto BSSID - When set, BSSID is generated automatically in IBSS, else BSSID in cfg will be used. +* + +WNI_CFG_IBSS_AUTO_BSSID I 4 0 +V RW NP +NONE +0 1 1 +NV RW NP +NONE +0 1 1 + +* +* Include Additional IEs in probe request. +* +WNI_CFG_PROBE_REQ_ADDNIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional IE in probe request. +* +WNI_CFG_PROBE_REQ_ADDNIE_DATA S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IEs in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional IE in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_DATA1 S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IE in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_DATA2 S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IE in probe response. +* +WNI_CFG_PROBE_RSP_ADDNIE_DATA3 S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional IEs in assoc response. +* +WNI_CFG_ASSOC_RSP_ADDNIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional IE in assoc response. +* +WNI_CFG_ASSOC_RSP_ADDNIE_DATA S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + +* +* Include Additional P2P IEs in probe request. +* +WNI_CFG_PROBE_REQ_ADDNP2PIE_FLAG I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* Include Additional P2P IE in probe request. +* +WNI_CFG_PROBE_REQ_ADDNP2PIE_DATA S 255 0 +V RW NP +NONE +0 0 +V RW NP +NONE +0 0 + + +* +* Include Additional IEs in probe response/beacon. +* +WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG I 4 0 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + + +* +* Include Additional IEs in probe response/beacon. +* +WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA S 255 0 +V RW NP +LIM +0 0 +V RW NP +LIM +0 0 + + +* +* wpsApEnable and wpsStaEnable is specified in here +* wpsApEnable is bit #0 and wpsStaEnable is bit #1 +* +WNI_CFG_WPS_ENABLE I 4 7 +V RW NP +LIM +0 0xff 0 +V RW NP +LIM +0 0xff 0 + +#ENUM AP 1 +#ENUM STA 2 + +WNI_CFG_WPS_STATE I 4 7 +V RW NP +LIM +0 0xff 1 +V RW NP +LIM +0 0xff 1 + +* +* TRUE => include this information in Probe Requests, FALSE => omit it +* + +WNI_CFG_WPS_PROBE_REQ_FLAG I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* Wi-Fi Protected Setup Version +* +* This one-byte field is broken into a four-bit major +* part using the top MSBs and four-bit minor part +* using the LSBs. As an example, version 3.2 would be 0x32. +* + +WNI_CFG_WPS_VERSION I 4 7 +V RW NP +LIM +0 0xff 0x10 +V RW NP +LIM +0 0xff 0x10 + +* +* Wi-Fi Protected Setup Request type +* 0x00: Enrollee, Info only +* 0x01: Enrollee, open 802.1X +* 0x02: Registrar +* 0x03: WLAN Manager Registrar + +WNI_CFG_WPS_REQUEST_TYPE I 4 7 +V RW NP +LIM +0 0xff 0x00 +V RW NP +LIM +0 0xff 0x03 + +* Configuration Method(s) +* +* The Config Methods Data component lists the configuration methods +* the Enrollee or Registrar supports. The list is a bitwise OR of +* values from the table below. In addition to Config Methods, APs and +* STAs that support the UPnP Management Interface must support the +* Permitted Config Methods attribute, which is used to control the +* Config Methods that are enabled on that AP. +* +* Value Hardware Interface +* 0x0001 USBA (Flash Drive) +* 0x0002 Ethernet +* 0x0004 Label +* 0x0008 Display +* 0x0010 External NFC Token +* 0x0020 Integrated NFC Token +* 0x0040 NFC Interface +* 0x0080 PushButton +* 0x0100 Keypad +* +* The bottom 16 bits contain the configuration method(s) when acting +* as an Enrollee, and the top 16 when acting as a Registrar. +* +* QNE-TODO: Merge this with the inappropriately named +* 'WNI_CFG_WSC_AP_CFG_METHOD'-- this one can serve both puposes. +* + +WNI_CFG_WPS_CFG_METHOD I 4 7 +V RW NP +LIM +0 0xFFFFFFFF 0x00000008 +V RW NP +LIM +0 0xFFFFFFFF 0x018c018e + +* UUID +* The universally unique identifier (UUID) element is a unique +* GUID generated by the Enrollee or Registrar. It uniquely identifies +* an operational device and should survive reboots and resets. The +* UUID is provided in binary format. If the device also supports UPnP, +* then the UUID corresponds to the UPnP UUID. +* +* QNE-TODO: Re-name their cfg from 'WNI_CFG_UUID' + +WNI_CFG_WPS_UUID S 16 8 +V RW NP +LIM +6 0xa 0xb 0xc 0xd 0xe 0xf +V RW NP +LIM +6 0xa 0xb 0xc 0xd 0xe 0xf + +************************************************************************ +* The following cfgs contains the primary type of the device. Its format +* follows: +* +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Attribute ID | Length | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Category ID | OUI (1-2) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | OUI (3-4) | Sub Category ID | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* Vendor-specific sub-categories are designated by setting the OUI to the +* value associated with that vendor. Note that a four-byte subdivided OUI +* is used. For the predefined values, the Wi-Fi Alliance OUI of 00 50 F2 04 +* is used. The predefined values for Category ID and Sub Category ID are +* provided in the next table. There is no way to indicate a vendor-specific +* main device category. The OUI applies only to the interpretation of the +* Sub Category. If a vendor does not use sub categories for their OUI, the +* three-byte OUI occupies the first three bytes of the OUI field and the +* fourth byte is set to zero. +* +* Category ID Value Sub Category ID Value +* Computer 1 PC 1 +* Server 2 +* Media Center 3 +* Input Device 2 +* Printers, Scanners, Printer 1 +* Faxes and Copiers 3 Scanner 2 +* Camera 4 Digital Still Camera 1 +* Storage 5 NAS 1 +* Network AP 1 +* Infrastructure 6 Router 2 +* Switch 3 +* Displays 7 Television 1 +* Electronic Picture Frame 2 +* Projector 3 +* Multimedia Devices 8 DAR 1 +* PVR 2 +* MCX 3 +* Gaming Devices 9 Xbox 1 +* Xbox360 2 +* Playstation 3 +* Telephone 10 Windows Mobile 1 +* +************************************************************************ + +* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_CATEGORY' +WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY I 4 7 +V RW NP +LIM +0 0xffff 1 +V RW NP +LIM +0 0xffff 6 + +* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_OUI' +WNI_CFG_WPS_PIMARY_DEVICE_OUI I 4 7 +V RW NP +LIM +0 0xffffffff 0x0050f204 +V RW NP +LIM +0 0xffffffff 0x0050f204 + +* QNE-TODO: Rename their cfg from 'WNI_CFG_PRIM_DEVICE_SUB_CATEGORY' +WNI_CFG_WPS_DEVICE_SUB_CATEGORY I 4 7 +V RW NP +LIM +0 0xffff 1 +V RW NP +LIM +0 0xffff 1 + +* Association State +* + +* The Association State component shows the configuration and previous +* association state of the wireless station when sending a Discovery +* request. +* +* Association State Description +* 0 Not Associated +* 1 Connection Success +* 2 Configuration Failure +* 3 Association Failure +* 4 IP Failure + +WNI_CFG_WPS_ASSOCIATION_STATE I 4 7 +V RW NP +LIM +0 0xffff 0 +V RW NP +LIM +0 0xffff 0 + +* Configuration Error +* +* The Configuration Error component shows the result of the device +* attempting to configure itself and to associate with the WLAN. +* +* Configuration Error Description +* 0 No Error +* 1 OOB Interface Read Error +* 2 Decryption CRC Failure +* 3 2.4 channel not supported +* 4 5.0 channel not supported +* 5 Signal too weak +* 6 Network auth failure +* 7 Network association failure +* 8 No DHCP response +* 9 Failed DHCP config +* 10 IP address conflict +* 11 Couldnt connect to Registrar +* 12 Multiple PBC sessions detected +* 13 Rogue activity suspected +* 14 Device busy +* 15 Setup locked +* 16 Message Timeout +* 17 Registration Session Timeout +* 18 Device Password Auth Failure +* +* The Device busy error is returned if the sending device is unable to +* respond to the request due to some internal conflict or resource +* contention issue. For example, if a device is only capable of +* performing a single instance of the Registration Protocol at a time, +* it may return this error in response to attempts to start another +* instance in the middle of an active session. + +WNI_CFG_WPS_CONFIGURATION_ERROR I 4 7 +V RW NP +LIM +0 0xffff 0 +V RW NP +LIM +0 0xffff 0 + +* Device Password ID +* + +* This attribute is used to identify a device password. There are six +* predefined values and ten reserved values. If the Device Password ID is +* Default, the Enrollee should use its PIN password (from the label or +* display). This password may correspond to the label, display, or a +* user-defined password that has been configured to replace the original +* device password. +* +* User-specified indicates that the user has overridden the password with a +* manually selected value. Machine-specified indicates that the original +* PIN password has been overridden by a strong, machinegenerated device +* password value. The Rekey value indicates that the device's 256-bit +* rekeying password will be used. The PushButton value indicates that the +* PIN is the all-zero value reserved for the PushButton Configuration +* method. +* +* The Registrar-specified value indicates a PIN that has been obtained from +* the Registrar (via a display or other out-of-band method). This value may +* be further augmented with the optional 'Identity' attribute in M1. This +* augmentation is useful when multiple predefined UserID/PIN pairs have been +* established by a Registrar such as an authenticator used for Hotspot +* access. If the Device Password ID in M1 is not one of the predefined or +* reserved values, it corresponds to a password given to the Registrar as an +* OOB Device Password. +* +* Value Description +* 0x0000 Default (PIN) +* 0x0001 User-specified +* 0x0002 Machine-specified +* 0x0003 Rekey +* 0x0004 PushButton +* 0x0005 Registrar-specified +* 0x0006 - 0x000F Reserved' +* + +WNI_CFG_WPS_DEVICE_PASSWORD_ID I 4 7 +V RW NP +LIM +0 0xffffffff 0 +V RW NP +LIM +0 0xffffffff 0 + +* +* WPS Association +* +* Wi-Fi Protected Setup requires a prospective enrollee to associate to +* an AP in the network in which the STA would like to enroll. Once +* associated, the enrollment takes place over an EAPOL conversation +* (there's actually a new EAP method: EAP-WSC). The STA would +* presumably send an EAPOL-Start over his new link, to which the AP +* would respond with an EAP Identity Request. When the STA sends back +* "WSC-Enrollee-1" as his EAP Identity, the AP knows that he's got a WPS +* supplicant on his hands, and proceeds to talk EAP-WSC. +* +* Toward the end of the specification's development, a problem came up. +* Microsoft's EAP supplicant on XP SP1 & SP2 will send an EAPOL-Start, +* no matter what. Even if the AP is beaconing WPA-PSK, say, the MS +* supplicant will send an EAPOL-Start. If it receives an EAP Identity +* Request in return, it decides that the AP is really using 802.1x +* authentication, and proceeds on that assumption. +* +* Now, imagine an AP that is configured for WPA-PSK, and is WPS-capable. +* It receives an association request from some STA, and then sees an +* EAPOL-Start from the newly joined STA. It naturally sends back an EAP +* Identity Request to see if the new STA wants to talk EAP-WSC. On +* Windows XP SP1 & SP2, the supplicant will take that to mean that this +* AP is using 802.1x authentication, and will never let the user provide +* the PSK. Consequently, WZC will never be able to associate with this +* AP. +* +* Naturally, Microsoft's solution was to have the world change to +* accommodate them. After a lot of back & forth, the WFA decided on the +* following change to the WPS spec: when associating for purposes of WPS +* enrollment, "A client that intends to use the EAP-WSC method with a +* WSC enabled AP may include a WSC IE in its 802.11 (re)association +* request. If a WSC IE is present in the (re)association request, the AP +* shall engage in EAP-WSC with the station and must not attempt other +* security handshake. If the client does not include a WSC IE in its +* 802.11 (re)association request, it must send its 802.11 Authentication +* frame with Authentication set to open and an 802.11 Association +* Request frame without an RSN IE or SSN IE, regardless of the network +* type that is hosted by the AP. On successful association, the client +* will then send an EAPOL-Start to the AP and wait for +* EAP-Request/Identity. When the client receives an EAP Request/ +* Identity, it will respond with EAP-Response/Identity and the +* appropriate WSC string to indicate if it is an Enrollee or Registrar. +* ' +* +* This configuration variable contains a bitvector: +* +* 0x0001 Incldue the WPS Information Element in Assoc Request frames +* 0x0002 Elide the the WPA and RSN Information Elements from the +* Assoc Request frame +* + +WNI_CFG_WPS_ASSOC_METHOD I 4 7 +V RW NP +LIM +0 0xffff 0 +V RW NP +LIM +0 0xffff 0 + +* +* Low gain override +* + +WNI_CFG_LOW_GAIN_OVERRIDE I 4 9 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +* +* Listen Mode Enable/Disable +* + +WNI_CFG_ENABLE_PHY_AGC_LISTEN_MODE I 4 7 +V RW NP +HAL +0 128 128 +V RW NP +HAL +0 128 128 + +* +* On chip reodering polling threshold +* + +WNI_CFG_RPE_POLLING_THRESHOLD I 4 2 +V RW NP +HAL +0 65535 10 +V RW NP +HAL +0 65535 10 + +* +* On chip reodering aging threshold for AC0 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* On chip reodering aging threshold for AC1 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* On chip reodering aging threshold for AC2 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* On chip reodering aging threshold for AC3 +* + +WNI_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG I 4 2 +V RW NP +HAL +0 65535 30 +V RW NP +HAL +0 65535 30 + +* +* Number of On-Chip reorder sessions +* + +WNI_CFG_NO_OF_ONCHIP_REORDER_SESSIONS I 4 2 +V RW NP +HAL +0 2 1 +V RW NP +HAL +0 2 1 + + +* +* Single RC for all TID +* + +WNI_CFG_SINGLE_TID_RC I 4 7 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* RRM Enabled +* + +WNI_CFG_RRM_ENABLED I 4 8 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* RRM measurement max duration. Section 11.10.3 802.11k-2008. +* Max Duration represented as maxDuration inTUs = 2^(*WNI_CFG_RRM_IN_CHAN_MAX - 4) * bcnIntvl +* Operating channel max measurement duration. +* + +WNI_CFG_RRM_OPERATING_CHAN_MAX I 4 8 +V RW NP +NONE +0 8 0 +V RW NP +NONE +0 8 0 + +* +* Non-Operating channel max measurement duration. +* + +WNI_CFG_RRM_NON_OPERATING_CHAN_MAX I 4 8 +V RW NP +NONE +0 8 0 +V RW NP +NONE +0 8 0 + +* +* TX power control feature +* + +WNI_CFG_TX_PWR_CTRL_ENABLE I 4 8 +V RW NP +NONE +0 1 1 +V RW NP +NONE +0 1 1 + +* +* MCAST BCAST filter Setting +* 0: No filter, 1: Block Mcast, 2: Block Bcast, 3: Block Mcast and Bcast +* + +WNI_CFG_MCAST_BCAST_FILTER_SETTING I 4 7 +V RW NP +HAL +0 3 0 +V RW NP +HAL +0 3 0 + +* +* BTC DHCP No of Bt slots to block +* +WNI_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK I 4 7 +V RW NP +HAL +0 0xFF 0 +V RW NP +HAL +0 0xFF 0 + +* +* Config parameter to Enable/Disable Dynamic PS-Poll mechanism +* 0: Disable, x: FW will send x number of NULL frames before switching to PS-Poll mexhanism +* +WNI_CFG_DYNAMIC_PS_POLL_VALUE I 4 7 +V RW NP +HAL +0 0xFF 0 +V RW NP +HAL +0 0xFF 0 + +* +* PS Data InActivity Timeout (TU) +* + +WNI_CFG_PS_NULLDATA_AP_RESP_TIMEOUT I 4 7 +V RW NP +HAL +0 80 0 +NV RW NP +NONE +0 80 0 + +* +* Config parameter to Enable/Disable Telescopic Bcn Wakeups +* 0: Disable, 1: Enable +* + +WNI_CFG_TELE_BCN_WAKEUP_EN I 4 7 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + + +* +* Config parameter for Transient LI +* 0: Disable, x: Transient LI +* + +WNI_CFG_TELE_BCN_TRANS_LI I 4 7 +V RW NP +HAL +0 7 3 +V RW NP +HAL +0 7 3 + +* +* Config parameter for Idle bcns for Transient LI +* x: Num Idle bcns before switch to trans LI +* + +WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS I 4 7 +V RW NP +HAL +5 255 10 +V RW NP +HAL +5 255 10 + +* +* Config parameter for Max LI +* 0: Disable, x: Max LI +* + +WNI_CFG_TELE_BCN_MAX_LI I 4 7 +V RW NP +HAL +0 7 5 +V RW NP +HAL +0 7 5 + +* +* Config parameter for Idle bcns for max LI +* x: Num Idle bcns before switch to max LI +* + +WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS I 4 7 +V RW NP +HAL +5 255 15 +V RW NP +HAL +5 255 15 + +* +* BTC DHCP No of Bt sub interval during DHCP +* +WNI_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS I 4 7 +V RW NP +HAL +0 0xFF 7 +V RW NP +HAL +0 0xFF 7 + +* +* Infra STA mode Keep alive period (in secs) for +* sending keep alive (Qos)Null frames to the AP. +* 0 = disabled. Recommended values is 30 secs +* +WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD I 4 7 +V RW NP +HAL +0 65535 0 +V RW NP +HAL +0 65535 0 + +* Limit on number of associated stations +* (applies to peer stations in IBSS, SoftAP, BT-AMP AP, & P2P-GO modes) +* + +WNI_CFG_ASSOC_STA_LIMIT I 4 8 +V RW NP +LIM +1 32 10 +V RW NP +LIM +1 32 10 + +* +* SAP channel select start channel number +* +WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL I 4 7 +V RW NP +NONE +1 0xFC 1 +V RW NP +NONE +1 0xFC 1 + +* +* SAP channel select end channel number +* +WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL I 4 7 +V RW NP +NONE +1 0xFC 11 +V RW NP +NONE +1 0xFC 11 + +* +* SAP channel select operating band +* 0- 2.4GHZ / 1- Low 5GHZ /2-MID /3-HIGH/4-Japan4.9GHZ +* +WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND I 4 7 +V RW NP +NONE +0 0x4 0 +V RW NP +NONE +0 0x4 0 + +* +* Softap data available poll period (in milliseconds) for +* queueing (Qos)Null frames to the station if there +* is no data available and PS-Poll/Trigger frame is pending. +* 0 = disabled. Recommended values is 5ms +* +WNI_CFG_AP_DATA_AVAIL_POLL_PERIOD I 4 8 +V RW NP +NONE +0 65535 5 +V RW NP +NONE +0 65535 5 + +* +* Close loop power control will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_CLOSE_LOOP I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* LTE Coexistence will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_LTE_COEX I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* AP Keep Alive Timeout (TU) +* +WNI_CFG_AP_KEEP_ALIVE_TIMEOUT I 4 7 +V RW NP +HAL +1 255 20 +V RW NP +HAL +1 255 20 + +* +* GO Keep Alive Timeout (TU) +* +WNI_CFG_GO_KEEP_ALIVE_TIMEOUT I 4 7 +V RW NP +HAL +1 255 20 +V RW NP +HAL +1 255 20 + +* +* MC Addr List power control will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_MC_ADDR_LIST I 4 0 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +* +* UC Filter will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_UC_FILTER I 4 0 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 + +* +* Low Power Image Transition will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_LPWR_IMG_TRANSITION I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* MCC Adaptive Scheduler will be enabled if value is set to 1 +* +* +* +WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 +* +*Disable LDPC in STA mode when AP is TXBF capable +* +* +* +WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP I 4 0 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* +* AP Link Monitor Timeout (TU) +* +WNI_CFG_AP_LINK_MONITOR_TIMEOUT I 4 7 +V RW NP +HAL +1 255 3 +V RW NP +HAL +1 255 3 + +* +*TDLS Station's UAPSD MASK Configuration +* +* +* +WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK I 4 7 +V RW NP +LIM +0 15 0 +V RW NP +LIM +0 15 0 +* +*TDLS Stations Buffer STA Capability +* +* +* +WNI_CFG_TDLS_BUF_STA_ENABLED I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 +*TDLS Stations PUAPSD Inactivity Timer +* +* +* +WNI_CFG_TDLS_PUAPSD_INACT_TIME I 4 7 +V RW NP +LIM +0 10 0 +V RW NP +LIM +0 10 0 +*TDLS Stations PUAPSD RX Frame Threshold +* +* +* +WNI_CFG_TDLS_RX_FRAME_THRESHOLD I 4 7 +V RW NP +LIM +10 20 10 +V RW NP +LIM +10 20 10 +* +*MCC ENABLE/DISABLE ADAPTIVE RX Drain feature +* +* +* +WNI_CFG_ENABLE_ADAPT_RX_DRAIN I 4 7 +V RW NP +HAL +0 1 1 +NV RW NP +HAL +0 1 1 +* +* FlexConnect Power Factor +* Default is set to 0 (disable) +* +* +WNI_CFG_FLEX_CONNECT_POWER_FACTOR I 4 0 +V RW NP +NONE +0 9 0 +V RW NP +NONE +0 9 0 + +* +* Antenna Diversity +* +* 0 = disabled +* 1 = Ant 1 +* 2 = Ant 2 +* 3 = Adaptive +* +WNI_CFG_ANTENNA_DIVESITY I 4 7 +V RW NP +HAL +0 3 0 +V RW NP +HAL +0 3 0 + +* GO Link Monitor Timeout (TU) +* +WNI_CFG_GO_LINK_MONITOR_TIMEOUT I 4 7 +V RW NP +HAL +3 50 10 +V RW NP +HAL +3 50 10 +* +* + +* RMC action period frequency (milli seconds) +* +WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY I 4 7 +V RW NP +HAL +100 1000 300 +V RW NP +HAL +100 1000 300 +* +* + +* +WNI_CFG_ATH_DISABLE I 4 7 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 +* BTC Active WLAN Len +* +WNI_CFG_BTC_ACTIVE_WLAN_LEN I 4 7 +V RW NP +HAL +0 250000 60000 +V RW NP +HAL +0 250000 60000 +* +* + +* BTC Active BT Len +* +WNI_CFG_BTC_ACTIVE_BT_LEN I 4 7 +V RW NP +HAL +0 250000 90000 +V RW NP +HAL +0 250000 90000 +* +* + +* BTC SAP Active WLAN Len +* +WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN I 4 7 +V RW NP +HAL +0 250000 30000 +V RW NP +HAL +0 250000 30000 +* +* + +* BTC SAP Active BT Len +* +WNI_CFG_BTC_SAP_ACTIVE_BT_LEN I 4 7 +V RW NP +HAL +0 250000 30000 +V RW NP +HAL +0 250000 30000 +* +* + +* Rssi probe interval (milli seconds) +* +WNI_CFG_ASD_PROBE_INTERVAL I 4 7 +V RW NP +HAL +10 100 50 +V RW NP +HAL +10 100 50 +* +* + +*Rssi threshold to trigger probing and slecting +* +WNI_CFG_ASD_TRIGGER_THRESHOLD I 4 7 +V RW NP +HAL +0 120 45 +V RW NP +HAL +0 120 45 +* +* + +*Rssi Hysteresis threshold for RSSI-RTT +* +WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD I 4 7 +V RW NP +HAL +0 100 0 +V RW NP +HAL +0 100 0 +* +* + +* Debug p2p remain on channel +* +WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL I 4 7 +V RW NP +NONE +0 1 0 +V RW NP +NONE +0 1 0 + +* BTC CTS2S during SCO +* +WNI_CFG_BTC_CTS2S_DURING_SCO I 4 7 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 +* +* + +************************************* +* Feature: Channel Bonding 2.4G +************************************* + +WNI_CFG_CHANNEL_BONDING_24G I 4 12 +V RW NP RESTART +LIM +0 1 0 +V RW NP RESTART +LIM +0 1 0 + +* +* OBSS PASSIVE Channel Time (TU) +* + +WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME I 4 9 +V RW NP +NONE +5 1000 20 +V RW NP +NONE +5 1000 20 + +* +* OBSS ACTIVE Channel Time (TU) +* + +WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME I 4 9 +V RW NP +NONE +10 1000 10 +V RW NP +NONE +10 1000 10 + +* +* OBSS SCAN WIDTH TRIGGER Interval (TU) +* + +WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL I 4 9 +V RW NP +NONE +10 900 200 +V RW NP +NONE +10 900 200 + +* +* OBSS SCAN passive total per chanenl (TU) +* + +WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL I 4 9 +V RW NP +NONE +200 10000 200 +V RW NP +NONE +200 10000 200 + +* +* OBSS SCAN active total per Channel (TU) +* + +WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL I 4 9 +V RW NP +NONE +20 10000 20 +V RW NP +NONE +20 10000 20 + +* +* OBSS Width Channel Transition Delay Factor +* + +WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR I 4 9 +V RW NP +NONE +5 100 5 +V RW NP +NONE +5 100 5 + +* +* OBSS SCAN Activity Threshold(TU) +* + +WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD I 4 9 +V RW NP +NONE +0 100 25 +V RW NP +NONE +0 100 25 + +* +* TDLS Off Channel Implementation +* +WNI_CFG_TDLS_OFF_CHANNEL_ENABLED I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +* +* PMF SA Query Maximum Retries +* + +WNI_CFG_PMF_SA_QUERY_MAX_RETRIES I 4 1 +V RW NP RESTART +NONE +0 20 5 +V RW NP RESTART +NONE +0 20 5 + +* +* PMF SA Query Retry Interval (in TUs) +* + +WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL I 4 1 +V RW NP RESTART +NONE +10 2000 200 +V RW NP RESTART +NONE +10 2000 200 + +* RA filter enable/disable +* +WNI_CFG_RA_FILTER_ENABLE I 4 7 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 +* +* + +* RA filter rate interval +* +WNI_CFG_RA_RATE_LIMIT_INTERVAL I 4 7 +V RW NP +HAL +0 60 60 +V RW NP +HAL +0 60 60 + +* BTC Fatal HID sniff block +* +WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE I 4 7 +V RW NP +HAL +0 2 2 +V RW NP +HAL +0 2 2 +* +* + +* BTC Critical HID sniff block +* +WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE I 4 7 +V RW NP +HAL +0 1 1 +V RW NP +HAL +0 1 1 +* +* + +* BTC DYN A2DP tx Q threshold +* +WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD I 4 7 +V RW NP +HAL +0 1 0 +V RW NP +HAL +0 1 0 +* +* + +* BTC DYN OPP tx Q threshold +* +WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD I 4 7 +V RW NP +HAL +0 3 1 +V RW NP +HAL +0 3 1 +* +* + +* +*TDLS WMM Mode +* +* +WNI_CFG_TDLS_WMM_MODE_ENABLED I 4 7 +V RW NP +LIM +0 1 0 +V RW NP +LIM +0 1 0 + +WNI_CFG_MAX_UAPSD_CONSEC_SP I 4 7 +V RW NP +HAL +0 100 10 +V RW NP +HAL +0 100 10 +* +* + +WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT I 4 7 +V RW NP +HAL +0 100 10 +V RW NP +HAL +0 100 10 +* +* + +WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT I 4 7 +V RW NP +HAL +0 100 10 +V RW NP +HAL +0 100 10 +* +* + +WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW I 4 7 +V RW NP +HAL +0 100 10 +V RW NP +HAL +0 100 10 +* +* + +WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW I 4 7 +V RW NP +HAL +0 100 10 +V RW NP +HAL +0 100 10 +* +* + +WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE I 4 7 +V RW NP +HAL +0 255 0 +V RW NP +HAL +0 255 0 +* +* + +WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS I 4 7 +V RW NP +HAL +0 255 20 +V RW NP +HAL +0 255 20 +* +* + +WNI_CFG_ENABLE_DYNAMIC_WMMPS I 4 7 +V RW NP +HAL +0 1 1 +V RW NP +HAL +0 1 1 +* +* + +WNI_CFG_BURST_MODE_BE_TXOP_VALUE I 4 7 +V RW NP +HAL +0 12288 0 +V RW NP +HAL +0 12288 0 +* +* diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms b/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms new file mode 100644 index 000000000000..3c125e9e9bdd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/cfgUtil/dot11f.frms @@ -0,0 +1,4277 @@ +/* + * Copyright (c) 2006-2007 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * \file dot11f.frms + * + * \brief Primary 'frames' file for the MAC parser + * + * + * This file defines several 802.11 frames (along with their associated + * constituents) in a little language called "frames". When run through the + * 'framesc' program, it will generate C code for working with these frames: + * C structs representing the 802.11 frame together with functions for + * packing & unpacking them. + * + * For more information on the "frames" language, run 'framesc --help'... + * + * + */ + + +// Tell framesc what types to use for... +%8-bit-type tANI_U8 // 8, +%16-bit-type tANI_U16 // 16, +%32-bit-type tANI_U32 // & 32-bit unsigned integral types. These can also + // be specified on the command line. + +// Define some mnemonic constants; these are just for our use with the frames +// files we're compiling. IOW, they won't result in any C code being +// emitted. + +const EID_SSID = 0; +const EID_SUPP_RATES = 1; +const EID_FH_PARAM_SET = 2; +const EID_DS_PARAM_SET = 3; +const EID_CF_PARAM_SET = 4; +const EID_TIM = 5; +const EID_IBSS_PARAM_SET = 6; +const EID_COUNTRY = 7; +const EID_FH_PATTERN = 8; +const EID_FH_PATT_TABLE = 9; +const EID_REQUEST = 10; +const EID_QBSS_LOAD = 11; +const EID_EDCA_PARAM_SET = 12; +const EID_TSPEC = 13; +const EID_TCLAS = 14; +const EID_SCHEDULE = 15; +const EID_CHALLENGE_TEXT = 16; +const EID_POWER_CONSTRAINTS = 32; +const EID_POWER_CAPABILITY = 33; +const EID_TPC_REQUEST = 34; +const EID_TPC_REPORT = 35; +const EID_SUPPORTED_CHANNELS = 36; +const EID_CHANNEL_SWITCH_ANN = 37; +const EID_MEAS_REQUEST = 38; +const EID_MEAS_REPORT = 39; +const EID_QUIET = 40; +const EID_ERP_INFO = 42; +const EID_TS_DELAY = 43; +const EID_TCLASS_PROC = 44; +const EID_HT_CAPABILITIES = 45; +const EID_QOS_CAPABILITY = 46; +const EID_RSN = 48; +const EID_EXT_SUPP_RATES = 50; +const EID_AP_CHAN_REPORT = 51; +const EID_NEIGHBOR_REPORT = 52; +const EID_RCPI = 53; +const EID_FT_MOBILITY_DOMAIN = 54; +const EID_FT_INFO = 55; +const EID_TIMEOUT_INTERVAL = 56; +const EID_FT_RIC_DATA = 57; +const EID_SUPPORTED_OPER_CLASSES = 59; +const EID_HT_INFO = 61; +const EID_EXT_CHANNEL_SWITCH_ANN = 62; +const EID_RSNI = 65; +const EID_RRM_MEAS_PILOT_TX_INFO = 66; +const EID_WAPI = 68; +const EID_RRM_ENABLED_CAPS = 70; +const EID_MULTIPLE_BSSID = 71; +const EID_20_40_BSS_COEXISTENCE = 72; +const EID_20_40_BSS_INTOLERANT_REPORT= 73; +const EID_OBSS_SCAN_PARAMETERS = 74; +const EID_FT_RIC_DESCRIPTOR = 75; +const EID_LINK_IDENTIFIER = 101; +const EID_PTI_CONTROL = 105; +const EID_PU_BUFFER_STATUS = 106; +const EID_QOS_MAP_SET = 110; +const EID_ESE_SPECIFIC = 150; +const EID_ESE_CCKM_SPECIFIC = 156; +const EID_VHT_CAPABILITIES = 191; +const EID_VHT_OPERATION_ELEMENT = 192; +const EID_VHT_EXT_BSS_LOAD = 193; +const EID_AID = 197; +const EID_EXT_CAP = 127; +const EID_OPERATING_MODE = 199; +const EID_WIDER_BW_CHANNEL_SWITCH_ANN= 194; +const EID_VENDOR_SPECIFIC = 221; + +const SIR_MAC_PROP_EXT_RATES_TYPE = 0; +const SIR_MAC_PROP_AP_NAME_TYPE = 1; +const SIR_MAC_PROP_HCF_TYPE = 2; +const SIR_MAC_PROP_WDS_TYPE = 3; +const SIR_MAC_PROP_BP_IND_TYPE = 4; +const SIR_MAC_PROP_NEIGHBOR_BSS_TYPE = 5; +const SIR_MAC_PROP_LOAD_INFO_TYPE = 6; +const SIR_MAC_PROP_ASSOC_TYPE = 7; +const SIR_MAC_PROP_LOAD_BALANCE_TYPE = 8; +const SIR_MAC_PROP_LL_ATTR_TYPE = 9; +const SIR_MAC_PROP_CAPABILITY = 10; +const SIR_MAC_PROP_VERSION = 11; +const SIR_MAC_PROP_EDCAPARAMS = 12; +const SIR_MAC_PROP_TITAN = 14; +const SIR_MAC_PROP_CHANNEL_SWITCH = 15; +const SIR_MAC_PROP_QUIET_BSS = 16; +const SIR_MAC_PROP_TRIG_STA_BK_SCAN = 17; +const SIR_MAC_PROP_TAURUS = 18; + +const ANI_WDS_INFO_MAX_LENGTH = 64; +const SIR_MAC_MAX_NUMBER_OF_RATES = 12; +const HT_MAX_SUPPORTED_MCS_SET = 16; + +///////////////////////////////////////////////////////////////////////////// +// Wi-Fi Protected Setup TLV Identifiers // +// WSC Version 2.0.0 Table 28 // +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// Wi-Fi Simple Configuration TLV Identifiers // +// WFA Vendor Extension Subelements // +///////////////////////////////////////////////////////////////////////////// +const TLV_VERSION2 = 0; +const TLV_AUTHORIZED_MAC = 1; +const TLV_NETWORK_KEY_SHAREABLE = 2; +const TLV_REQUEST_TO_ENROLL = 3; +const TLV_SETTINGS_DELAY_TIME = 4; + +const TLV_VERSION = 0x104A; +const TLV_WI_FI_SIMPLE_CONFIG_STATE = 0x1044; +const TLV_AP_SETUP_LOCKED = 0x1057; +const TLV_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053; +const TLV_DEVICE_PASSWORD_ID = 0x1012; +const TLV_UUID_E = 0x1047; +const TLV_UUID_R = 0x1048; +const TLV_RF_BANDS = 0x103C; +const TLV_REQUEST_TYPE = 0x103A; +const TLV_RESPONSE_TYPE = 0x103B; +const TLV_CONFIG_METHODS = 0x1008; +const TLV_PRIMARY_DEVICE_TYPE = 0x1054; +const TLV_ASSOCIATION_STATE = 0x1002; +const TLV_CONFIGURATION_ERROR = 0x1009; +const TLV_MANUFACTURER = 0x1021; +const TLV_MODEL_NAME = 0x1023; +const TLV_MODEL_NUMBER = 0x1024; +const TLV_SERIAL_NUMBER = 0x1042; +const TLV_DEVICE_NAME = 0x1011; +const TLV_SELECTED_REGISTRAR = 0x1041; +const TLV_VENDOR_EXTENSION = 0x1049; +const TLV_REQUESTED_DEVICE_TYPE = 0x106A; + +///////////////////////////////////////////////////////////////////////////// +// Wi-Fi Direct/P2P TLV Identifiers // +///////////////////////////////////////////////////////////////////////////// +const TLV_P2P_STATUS = 0; +const TLV_MINOR_REASON_CODE = 1; +const TLV_P2P_CAPABILITY = 2; +const TLV_P2P_DEVICE_ID = 3; +const TLV_P2P_GROUP_OWNER_INTENT = 4; +const TLV_CONFIGURATION_TIMEOUT = 5; +const TLV_LISTEN_CHANNEL = 6; +const TLV_P2P_GROUP_BSSID = 7; +const TLV_EXTENDED_LISTEN_TIMING = 8; +const TLV_INTENDED_P2P_INTERFACE_ADDRESS = 9; +const TLV_P2P_MANAGEABILITY = 10; +const TLV_CHANNEL_LIST = 11; +const TLV_NOTICE_OF_ABSENCE = 12; +const TLV_P2P_DEVICE_INFO = 13; +const TLV_P2P_GROUP_INFO = 14; +const TLV_P2P_GROUP_ID = 15; +const TLV_P2P_INTERFACE = 16; +const TLV_OPERATING_CHANNEL = 17; +const TLV_INVITATION_FLAGS = 18; +const TLV_P2P_VENDOR_SPECIFIC = 221; + +///////////////////////////////////////////////////////////////////////////// +// Fixed Fields + +FF AuthAlgo (2) // C.f. Sec. 7.3.1.1 +{ + algo, 2; +} + +FF AuthSeqNo (2) // 7.3.1.2 +{ + no, 2; +} + +FF BeaconInterval (2) // 7.3.1.3 +{ + interval, 2; +} + +FF Capabilities (2) // 7.3.1.4 +{ + { + ess: 1; + ibss: 1; + cfPollable: 1; + cfPollReq: 1; + privacy: 1; + shortPreamble: 1; + pbcc: 1; + channelAgility: 1; + spectrumMgt: 1; + qos: 1; + shortSlotTime: 1; + apsd: 1; + rrm: 1; + dsssOfdm: 1; + delayedBA: 1; + immediateBA: 1; + } +} + +FF CurrentAPAddress(6) // 7.3.1.5 +{ + mac[6]; +} + +FF ListenInterval (2) // 7.3.1.6 +{ + interval, 2; +} + +FF Reason (2) // 7.3.1.7 +{ + code, 2; +} + +FF AID (2) // 7.3.1.8 +{ + associd, 2; +} + +FF Status (2) // 7.3.1.9 +{ + status, 2; +} + +FF TimeStamp (8) // 7.3.1.10 +{ + timestamp, 8; +} + +FF Category (1) // 7.3.1.11 +{ + category, 1; +} + +FF Action (1) // 7.3.1.11 +{ + action, 1; +} + +FF TransactionId (2) // 7.3.1.11 +{ + transId[2]; +} + +FF DialogToken (1) // 7.3.1.12 +{ + token, 1; +} + +FF StatusCode (1) // WMM Spec 2.2.10 +{ + statusCode, 1; +} + +FF OperatingMode (1) +{ + { + //Operating Mode field + chanWidth: 2; + reserved: 2; + rxNSS: 3; + rxNSSType: 1; + } +} +FF AddBAParameterSet (2) // 7.3.1.14 +{ + { + amsduSupported: 1; + policy: 1; + tid: 4; + bufferSize: 10; + } +} + +FF BATimeout (2) // 7.3.1.15 +{ + timeout, 2; +} + +FF BAStartingSequenceControl (2) // 7.2.1.7 +{ + { + fragNumber: 4; + ssn: 12; + } +} + +FF DelBAParameterSet (2) // 7.3.1.16 +{ + { + reserved: 11; + initiator: 1; + tid: 4; + } +} + +FF SMPowerModeSet (1) //7.3.1.25 +{ + { + PowerSave_En: 1; + Mode: 1; + reserved: 6; + } +} + +FF TSInfo (3) // 7.3.2.30 +{ + { + traffic_type: 1; + tsid: 4; + direction: 2; + access_policy: 2; + aggregation: 1; + psb: 1; + user_priority: 3; + tsinfo_ack_pol: 2; + schedule: 1; + unused: 15; + } +} + +FF NumOfRepetitions (2) +{ + repetitions, 2; +} + +FF TxPower (1) +{ + txPower, 1; +} + +FF MaxTxPower (1) +{ + maxTxPower, 1; +} +FF TPCEleID (1) +{ + TPCId, 1; +} +FF TPCEleLen (1) +{ + TPCLen, 1; +} +FF LinkMargin (1) +{ + linkMargin, 1; +} +FF RxAntennaId (1) +{ + antennaId, 1; +} +FF TxAntennaId (1) +{ + antennaId, 1; +} +FF RCPI (1) +{ + rcpi, 1; +} +FF RSNI (1) +{ + rsni, 1; +} + +FF P2POUI (4) +{ + oui, 4; +} + +FF P2POUISubType (1) +{ + ouiSubtype, 1; +} + +FF RMCOUI (3) +{ + oui[3]; +} + +FF MagicCode (6) +{ + magic[6]; +} + +FF RMCVersion (1) +{ + version, 1; +} + +FF RMCDialogToken (4) +{ + token, 4; +} + +FF Ruler (6) +{ + mac[6]; +} + +FF VhtMembershipStatusArray(8) // 8.4.1.51 +{ + membershipStatusArray[8]; +} + +FF VhtUserPositionArray(16) // 8.4.1.52 +{ + userPositionArray[16]; +} + + +///////////////////////////////////////////////////////////////////////////// +// TLVs // +///////////////////////////////////////////////////////////////////////////// + +/** + * \brief Version + * + * WPS 1.0h + * Version specifies the Easy Setup version. The one-byte field is broken + * into a four-bit major part using the top MSBs and four-bit minor part + * using the LSBs. As an example, version 3.2 would be 0x32. + * + * WSC 2.0.0 + * Deprecated Version mechanism. This attribute is always set to value 0x10 + * (version 1.0) for backwards compatibility. Version 1.0h of the specification + * did not fully describe the version negotiation mechanism and version 2.0 + * introduced a new subelement (Version2) for indicating the version number + * to avoid potential interoperability issues with deployed 1.0h-based devices. + * + */ + +TLV Version( TLV_VERSION ) ( 2 : 2 ) MSB +{ + { + minor: 4; + major: 4; + } +} + +/// Wi-Fi Protected Setup State +TLV WPSState( TLV_WI_FI_SIMPLE_CONFIG_STATE ) ( 2 : 2 ) MSB +{ + state, 1; +} + +/** + * \brief AP Setup Locked + * + * + * This variable indicates that the AP has entered a state in which it will + * refuse to allow an external Registrar to attempt to run the Registration + * Protocol using the AP?s PIN (with the AP acting as Enrollee). The AP + * should enter this state if it believes a brute force attack is underway + * against the AP?s PIN. + * + * When the AP is in this state, it MUST continue to allow other Enrollees to + * connect and run the Registration Protocol with any external Registrars or + * the AP's built-in Registrar (if any). It is only the use of the AP' PIN + * for adding external Registrars that is disabled in this state. + * + * The AP Setup Locked state can be reset to FALSE through an authenticated + * call to SetAPSettings. APs may provide other implementation-specific + * methods of resetting the AP Setup Locked state as well. + * + * + */ + +TLV APSetupLocked( TLV_AP_SETUP_LOCKED ) ( 2 : 2 ) MSB +{ + fLocked, 1; +} + +/** + * \brief Selected Registrar Config Methods + * + * + * This attribute has the same values that Config Methods have. It is used in + * Probe Response messages to convey the Config Methods of the selected + * Registrar. + * + * + */ + +TLV SelectedRegistrarConfigMethods ( TLV_SELECTED_REGISTRAR_CONFIG_METHODS ) ( 2 : 2 ) MSB +{ + methods, 2; +} + +/** + * \brief UUID-E + * + * + * The universally unique identifier (UUID) element is a unique GUID + * generated by the Enrollee. It uniquely identifies an operational device + * and should survive reboots and resets. The UUID is provided in binary + * format. If the device also supports UPnP, then the UUID corresponds to the + * UPnP UUID. + * + * + */ + +TLV UUID_E ( TLV_UUID_E ) ( 2 : 2 ) MSB +{ + uuid[ 16 ]; +} + +/** + * \brief UUID-R + * + * + * The universally unique identifier (UUID) element is a unique GUID + * generated by the Registrar. It uniquely identifies an operational device + * and should survive reboots and resets. The UUID is provided in binary + * format. If the device also supports UPnP, then the UUID corresponds to the + * UPnP UUID. + * + * + */ + +TLV UUID_R ( TLV_UUID_R ) ( 2 : 2 ) MSB +{ + uuid[ 16 ]; +} + +/** + * \brief RF Bands + * + * + \code + + 0x01 2.4GHz + 0x02 5.0GHz + + \endcode + * + * + */ + +TLV RFBands ( TLV_RF_BANDS ) ( 2 : 2 ) MSB +{ + bands, 1; +} + + +/** + * \brief Selected Registrar + * + * + * This field indicates that a Registrar has been selected by a user and that + * an Enrollee should proceed with setting up an 802.1X uncontrolled data + * port with the Registrar. + * + * + */ + +TLV SelectedRegistrar ( TLV_SELECTED_REGISTRAR ) ( 2 : 2 ) MSB +{ + selected, 1; +} + +/** + * \brief Config Methods + * + * + * The Config Methods Data component lists the configuration methods the + * Enrollee or Registrar supports. The list is a bitwise OR of values from + * the table below. In addition to Config Methods, APs and STAs that support + * the UPnP Management Interface must support the Permitted Config Methods + * attribute, which is used to control the Config Methods that are enabled on + * that AP. + * + \code + + Value Hardware Interface + 0x0001 USBA (Flash Drive) + 0x0002 Ethernet + 0x0004 Label + 0x0008 Display + 0x0010 External NFC Token + 0x0020 Integrated NFC Token + 0x0040 NFC Interface + 0x0080 PushButton + 0x0100 Keypad + + \endcode + * + * + */ + +TLV ConfigMethods ( TLV_CONFIG_METHODS ) ( 2 : 2 ) MSB +{ + methods, 2; +} + +/** + * \brief Association State + * + * + * The Association State component shows the configuration and previous + * association state of the wireless station when sending a Discovery + * request. + * + \code + + Association State Description + 0 Not Associated + 1 Connection Success + 2 Configuration Failure + 3 Association Failure + 4 IP Failure + + \endcode + * + * + */ + +TLV AssociationState ( TLV_ASSOCIATION_STATE ) ( 2 : 2 ) MSB +{ + state, 2; +} + +/** + * \brief Configuration Error + * + * + * The Configuration Error component shows the result of the device + * attempting to configure itself and to associate with the WLAN. + * + \code + + Configuration Error Description + 0 No Error + 1 OOB Interface Read Error + 2 Decryption CRC Failure + 3 2.4 channel not supported + 4 5.0 channel not supported + 5 Signal too weak + 6 Network auth failure + 7 Network association failure + 8 No DHCP response + 9 Failed DHCP config + 10 IP address conflict + 11 Couldn't connect to Registrar + 12 Multiple PBC sessions detected + 13 Rogue activity suspected + 14 Device busy + 15 Setup locked + 16 Message Timeout + 17 Registration Session Timeout + 18 Device Password Auth Failure + + \endcode + * + * The Device busy error is returned if the sending device is unable to + * respond to the request due to some internal conflict or resource + * contention issue. For example, if a device is only capable of performing a + * single instance of the Registration Protocol at a time, it may return this + * error in response to attempts to start another instance in the middle of + * an active session. + * + * + */ + +TLV ConfigurationError ( TLV_CONFIGURATION_ERROR ) ( 2 : 2 ) MSB +{ + error, 2; +} + +TLV Manufacturer ( TLV_MANUFACTURER ) ( 2 : 2 ) MSB +{ + name[ 0..64 ]; +} + +TLV ModelName ( TLV_MODEL_NAME ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +TLV ModelNumber ( TLV_MODEL_NUMBER ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +TLV SerialNumber ( TLV_SERIAL_NUMBER ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +TLV DeviceName ( TLV_DEVICE_NAME ) ( 2 : 2 ) MSB +{ + text[ 0..32 ]; +} + +/** + * \brief Device Password ID + * + * + * This attribute is used to identify a device password. There are six + * predefined values and ten reserved values. If the Device Password ID is + * Default, the Enrollee should use its PIN password (from the label or + * display). This password may correspond to the label, display, or a + * user-defined password that has been configured to replace the original + * device password. + * + * User-specified indicates that the user has overridden the password with a + * manually selected value. Machine-specified indicates that the original + * PIN password has been overridden by a strong, machinegenerated device + * password value. The Rekey value indicates that the device's 256-bit + * rekeying password will be used. The PushButton value indicates that the + * PIN is the all-zero value reserved for the PushButton Configuration + * method. + * + * The Registrar-specified value indicates a PIN that has been obtained from + * the Registrar (via a display or other out-of-band method). This value may + * be further augmented with the optional 'Identity' attribute in M1. This + * augmentation is useful when multiple predefined UserID/PIN pairs have been + * established by a Registrar such as an authenticator used for Hotspot + * access. If the Device Password ID in M1 is not one of the predefined or + * reserved values, it corresponds to a password given to the Registrar as an + * OOB Device Password. + * + \code + + Value Description + + 0x0000 Default (PIN) + 0x0001 User-specified + 0x0002 Machine-specified + 0x0003 Rekey + 0x0004 PushButton + 0x0005 Registrar-specified + 0x0006 - 0x000F Reserved + + \endcode + * + * + */ + +TLV DevicePasswordID ( TLV_DEVICE_PASSWORD_ID ) ( 2 : 2 ) MSB +{ + id, 2; +} + + +/** + * \brief Primary Device Type + * + * + * This attribute contains the primary type of the device. Its format + * follows: + * + \code + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Attribute ID | Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Category ID | OUI (1-2) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | OUI (3-4) | Sub Category ID | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + \endcode + * + * Vendor-specific sub-categories are designated by setting the OUI to the + * value associated with that vendor. Note that a four-byte subdivided OUI + * is used. For the predefined values, the Wi-Fi Alliance OUI of 00 50 F2 04 + * is used. The predefined values for Category ID and Sub Category ID are + * provided in the next table. There is no way to indicate a vendor-specific + * main device category. The OUI applies only to the interpretation of the + * Sub Category. If a vendor does not use sub categories for their OUI, the + * three-byte OUI occupies the first three bytes of the OUI field and the + * fourth byte is set to zero. + * + * + \code + + Category ID Value Sub Category ID Value + Computer 1 PC 1 + Server 2 + Media Center 3 + Input Device 2 + Printers, Scanners, Printer 1 + Faxes and Copiers 3 Scanner 2 + Camera 4 Digital Still Camera 1 + Storage 5 NAS 1 + Network AP 1 + Infrastructure 6 Router 2 + Switch 3 + Displays 7 Television 1 + Electronic Picture Frame 2 + Projector 3 + Multimedia Devices 8 DAR 1 + PVR 2 + MCX 3 + Gaming Devices 9 Xbox 1 + Xbox360 2 + Playstation 3 + Telephone 10 Windows Mobile 1 + + \endcode + * + * + */ + +TLV PrimaryDeviceType ( TLV_PRIMARY_DEVICE_TYPE ) ( 2 : 2 ) MSB +{ + primary_category, 2; + oui[ 4 ]; + sub_category, 2; +} + + +/** + * \brief Request Type + * + * + * The Request Type component specifies the mode in which the device will + * operate in for this setup exchange. If the device is an Enrollee, it may + * send only discovery messages or it may also request that the Registrar + * proceed with opening a data connection. This protocol allows Enrollees to + * more efficiently discover devices on the network. + + * If the device indicates that it intends to engage setup either as a + * Registrar or an Enrollee, the Access Point continues to indicate that it + * will operate as an AP in the response. The Request Type attribute is + * carried throughout the 802.1X data channel setup process in the Wi-Fi + * Protected Setup IE. There are two sub-types of Registrars: WLAN Manager + * Registrar indicates that this Registrar intends to manage the AP or STA + * settings using UPnP. It will derive a UPnP AP or STA Management key. The + * ordinary Registrar type indicates that this Registrar does not intend to + * subsequently manage the Enrollee's settings. APs must not derive AP + * Management Keys for an ordinary Registrar. If a Registrar does not intend + * to be a WLAN Manager Registrar, it should set the Request Type to + * Registrar. Doing so avoids needlessly consuming resources on the AP. + + \code + + Request Type Value Description + 0x00 Enrollee, Info only + 0x01 Enrollee, open 802.1X + 0x02 Registrar + 0x03 WLAN Manager Registrar + + \endcode + * + * + */ + +TLV RequestType ( TLV_REQUEST_TYPE ) ( 2 : 2 ) MSB +{ + reqType, 1; +} + +/** + * \brief Response Type + * + * + * The Response Type component specifies the operational mode of the + * device for this setup exchange. The Response Type IE is carried + * throughout the 802.1X data channel setup process. + + \code + + Response Type Value Description + 0x00 Enrollee, Info only + 0x01 Enrollee, open 802.1X + 0x02 Registrar + 0x03 AP + +\endcode + * + * + */ + +TLV ResponseType ( TLV_RESPONSE_TYPE ) ( 2 : 2 ) MSB +{ + resType, 1; +} + + +/////////////////////////////////////////////////////////////////////////// +// WiFi Direct/P2P TLVs // +/////////////////////////////////////////////////////////////////////////// + +/** + * \brief P2P Status Attribute + */ + +TLV P2PStatus ( TLV_P2P_STATUS ) ( 1 : 2 ) LSB +{ + status, 1; +} + + +/** + * \brief Minor Reason Code Attribute + */ + +TLV MinorReasonCode ( TLV_MINOR_REASON_CODE ) ( 1 : 2 ) LSB +{ + minorReasonCode, 1; +} + + +/** + * \brief P2P Capability Attribute + */ + +TLV P2PCapability ( TLV_P2P_CAPABILITY ) ( 1 : 2 ) LSB +{ + deviceCapability, 1; + groupCapability, 1; +} + + +/** + * \brief P2P Device Id Attribute + */ + +TLV P2PDeviceId ( TLV_P2P_DEVICE_ID ) ( 1 : 2 ) LSB +{ + P2PDeviceAddress[6]; +} + + +/** + * \brief Group Owner Intent Attribute + */ + +TLV GOIntent ( TLV_P2P_GROUP_OWNER_INTENT ) ( 1 : 2 ) LSB +{ + GOIntent, 1; +} + + +/** + * \brief Configuration Timeout Attribute + */ + +TLV ConfigurationTimeout ( TLV_CONFIGURATION_TIMEOUT ) ( 1 : 2 ) LSB +{ + GOConfigTimeout, 1; + CLConfigTimeout, 1; +} + + +/** + * \brief Listen Channel Attribute + */ + +TLV ListenChannel ( TLV_LISTEN_CHANNEL ) ( 1 : 2 ) LSB +{ + countryString[3]; + regulatoryClass, 1; + channel, 1; +} + + +/** + * \brief P2P Group BSSID Attribute + */ + +TLV P2PGroupBssid ( TLV_P2P_GROUP_BSSID ) ( 1 : 2 ) LSB +{ + P2PGroupBssid[6]; +} + + +/** + * \brief Extended Listen Attribute + */ + +TLV ExtendedListenTiming ( TLV_EXTENDED_LISTEN_TIMING ) ( 1 : 2 ) LSB +{ + availibilityPeriod, 2; + availibilityInterval, 2; +} + + +/** + * \brief Intended P2P Interface Address Attribute + */ + +TLV IntendedP2PInterfaceAddress ( TLV_INTENDED_P2P_INTERFACE_ADDRESS ) ( 1 : 2 ) LSB +{ + P2PInterfaceAddress[6]; +} + + +/** + * \brief P2P Manageability Attribute + */ + +TLV P2PManageability ( TLV_P2P_MANAGEABILITY ) ( 1 : 2 ) LSB +{ + manageability, 1; +} + + +/** + * \brief ChannelList Attribute + */ + +TLV ChannelList ( TLV_CHANNEL_LIST ) ( 1 : 2 ) LSB +{ + countryString[3]; + channelList[0..251]; +} + + +/** + * \brief Notice of Absence + */ + +TLV NoticeOfAbsence ( TLV_NOTICE_OF_ABSENCE ) ( 1 : 2 ) LSB +{ + index, 1; + CTSWindowOppPS, 1; + NoADesc[0..36]; +} + +/** + * \brief P2P Device Info Attribute + */ + +TLV P2PDeviceInfo ( TLV_P2P_DEVICE_INFO ) ( 1 : 2 ) LSB +{ + P2PDeviceAddress[6]; + configMethod, 2 , FLIPBYTEORDER; + primaryDeviceType[8]; + MANDATORYTLV DeviceName; +} + + +/** + * \brief P2P Group Info Attribute + */ + +TLV P2PGroupInfo ( TLV_P2P_GROUP_INFO ) ( 1 : 2 ) LSB +{ + P2PClientInfoDesc[0..1024]; +} + + +/** + * \brief P2P Group Id Attribute + */ + +TLV P2PGroupId ( TLV_P2P_GROUP_ID ) ( 1 : 2 ) LSB +{ + deviceAddress[6]; + ssid[0..32]; +} + + +/** + * \brief P2P Interface Attribute + */ + +TLV P2PInterface ( TLV_P2P_INTERFACE ) ( 1 : 2 ) LSB +{ + P2PDeviceAddress[6]; +} + + +/** + * \brief Operating Channel Attribute + */ + +TLV OperatingChannel ( TLV_OPERATING_CHANNEL ) ( 1 : 2 ) LSB +{ + countryString[3]; + regulatoryClass, 1; + channel, 1; +} + + +/** + * \brief Invitation Flags Attribute + */ + +TLV InvitationFlags ( TLV_INVITATION_FLAGS ) ( 1 : 2 ) LSB +{ + invitationFlags, 1; +} + +/** + * \brief Vendor Extension + * + * This variable permits vendor extensions in the Wi-Fi Simple + * Configuration TLV framework. The Vendor Extension figure + * illustrates the implementation of vendor extensions. Vendor + * ID is the SMI network management private enterprise code + * + * +-----------+----------------------+ + * | Vendor ID | Vendor Data | + * +-----------+----------------------+ + * |<--- 3 --->|<----- 1 - 1021 ----->| + * + */ + +TLV VendorExtension ( TLV_VENDOR_EXTENSION ) ( 2 : 2 ) MSB +{ + /* + * vendorId is the SMI network management private enterprise code. + * WFA Vendor ID 0x00372A + * + */ + vendorId[ 3 ]; + + /** + * \breif Version2 + * + * The Version2 field specifies the version Wi-Fi Simple + * Configuration implemented by the device sending this attribute. + * The one-byte field is broken into a four-bit major part using + * the top MSBs and four-bit minor part using the LSBs. As an example, + * version 3.2 would be 0x32. This subelement was added in the + * specification version 2.0 and if the subelement is not included + * in a message, the transmitter of the message is assumed to + * use version 1.0. + * + */ + OPTIONALTLV TLV Version2 ( TLV_VERSION2 ) ( 1 : 1 ) MSB + { + { + minor: 4; + major: 4; + } + } + /** + * \brief AuthorizedMACs + * + * This subelement contains a list of Enrollee MAC addresses (each + * being six bytes in length) that have been registered to start WSC. + * The AP includes this field in Beacon and Probe Response frames so + * Enrollees can tell if they have been registered to start WSC. There + * may be multiple Enrollees active on the network, but not all of them have + * been registered to start WSC. This element allows an Enrollee to detect + * if they should start WSC with the AP. The AuthorizedMACs field augments + * the use of the Selected Registrar. + * + */ + OPTIONALTLV TLV AuthorizedMACs ( TLV_AUTHORIZED_MAC ) ( 1 : 1 ) MSB + { + mac[6]; + } + + /** + * \brief Request to Enroll + * + * This optional subelement in the WSC IE in Probe Request or M1 indicates + * the desire to enroll in the network by setting its value to TRUE. If the + * Registrar gets this subelement it can use this as a trigger that a device + * wants to enroll (maybe an indication can be shown to the user). The device + * must set it to FALSE after the registration protocol completion. + * + */ + OPTIONALTLV TLV RequestToEnroll( TLV_REQUEST_TO_ENROLL ) ( 1 : 1 ) MSB + { + req, 1; + } +} + +/** + * \brief Requested Device Type + * + * This attribute contains the requested device type of a Wi-Fi + * Direct device. + * + * This attribute allows a device to specify the Primary Device Type + * or the Secondary Device Type of other devices it is interested in. + * Only a device that receives a Probe Request containing a WSC IE with + * this attribute and with a Primary Device Type or Secondary Device Type + * that matches the Requested Device Type will respond with a Probe Response. + * + * Its format and contents is identical to the 'Primary Device Type'. + * + * Both the Category ID and Sub Category ID can be used as a filter. If only + * looking for devices with a certain Category ID, the OUI and Sub Category ID + * fields will have to be set to zero. + * + */ +TLV RequestDeviceType ( TLV_REQUESTED_DEVICE_TYPE ) ( 2 : 2 ) MSB +{ + primary_category, 2; + oui[ 4 ]; + sub_category, 2; +} + +///////////////////////////////////////////////////////////////////////////// +// Information Elements + +IE SSID (EID_SSID) // C.f. Sec. 7.3.2.1 +{ + ssid[0..32]; +} + +IE SuppRates (EID_SUPP_RATES) // 7.3.2.2 +{ + rates[0..SIR_MAC_MAX_NUMBER_OF_RATES]; +} + +IE FHParamSet (EID_FH_PARAM_SET) // 7.3.2.3 +{ + dwell_time, 2; + hop_set, 1; + hop_pattern, 1; + hop_index, 1; +} + +IE DSParams (EID_DS_PARAM_SET) // 7.3.2.4 +{ + curr_channel, 1; +} + +IE CFParams (EID_CF_PARAM_SET) // 7.3.2.5 +{ + cfp_count, 1; + cfp_period, 1; + cfp_maxduration, 2; + cfp_durremaining, 2; +} + +IE TIM (EID_TIM) // 7.3.2.6 +{ + dtim_count, 1; + dtim_period, 1; + bmpctl, 1; + vbmp[1..251]; +} + +IE IBSSParams (EID_IBSS_PARAM_SET) // 7.3.2.7 +{ + atim, 2; +} + +IE ChallengeText (EID_CHALLENGE_TEXT) // 7.3.2.8 +{ + text[1..253]; +} + +IE RequestedInfo (EID_REQUEST) // 7.3.2.12 +{ + requested_eids[0..255]; +} + +IE Country (EID_COUNTRY) // 7.3.2.9 +{ + country[3]; + OPTIONAL triplets[3][0..84]; +} + +IE FHParams (EID_FH_PATTERN) // 7.3.2.10 +{ + radix, 1; + nchannels, 1; +} + +IE FHPattTable (EID_FH_PATT_TABLE) // 7.3.2.11 +{ + flag, 1; + nsets, 1; + modulus, 1; + offset, 1; + randtable[0..251]; +} + +IE ERPInfo (EID_ERP_INFO) // 7.3.2.13 +{ + { + non_erp_present : 1; + use_prot: 1; + barker_preamble: 1; + unused: 5; + } +} + +IE ExtSuppRates (EID_EXT_SUPP_RATES) // 7.3.2.14 +{ + rates[1..SIR_MAC_MAX_NUMBER_OF_RATES]; +} + +IE PowerConstraints (EID_POWER_CONSTRAINTS) // 7.3.2.15 +{ + localPowerConstraints, 1; +} + +IE PowerCaps (EID_POWER_CAPABILITY) // 7.3.2.16 +{ + minTxPower, 1; + maxTxPower, 1; +} + +IE TPCRequest (EID_TPC_REQUEST) // 7.3.2.17 +{ } + +IE TPCReport (EID_TPC_REPORT) // 7.3.2.18 +{ + tx_power, 1; + link_margin, 1; +} + +IE SuppChannels (EID_SUPPORTED_CHANNELS) // 7.2.3.19 +{ + bands[2][1..48]; +} + +IE SuppOperatingClasses (EID_SUPPORTED_OPER_CLASSES) +{ + classes[1..32]; +} + +IE ChanSwitchAnn (EID_CHANNEL_SWITCH_ANN) // 7.3.2.20 +{ + switchMode, 1; + newChannel, 1; + switchCount, 1; +} + +IE ExtChanSwitchAnn (EID_EXT_CHANNEL_SWITCH_ANN) // 7.3.2.20a +{ + secondaryChannelOffset, 1; +} + +IE Quiet (EID_QUIET) // 7.3.2.23 +{ + count, 1; + period, 1; + duration, 2; + offset, 2; +} + +IE RSN (EID_RSN) // 7.3.2.25 +{ + // The version is 2 octets, and we only support version 1. + version, 2 MUSTBE 1; + // The next four octets will be the Group Cipher Suite + gp_cipher_suite[4]; + // The IE *may* stop here; if there's any more, we should see two more + // octets giving the number of Pairwise Cipher Suites + OPTIONAL pwise_cipher_suite_count, 2; + // I don't see anything in the Standard limiting the number of Pairwise + // Cypher Suites, other than the maximum length of an IE, which limits us + // to 61. However, that seems needlessly wasteful of space. + pwise_cipher_suites[4][0..4] COUNTIS pwise_cipher_suite_count; + // Optional count of AKM suite selectors + OPTIONAL akm_suite_count, 2; + // Again, I see nothing in the Standard explicitly limiting the number of + // AKM suite selectors other than the maximum size of an IE. + akm_suites[4][0..4] COUNTIS akm_suite_count; + OPTIONAL RSN_Cap[2]; + // Finally, the IE may contain zero or more PMKIDs: + OPTIONAL pmkid_count, 2; + pmkid[16][0..4] COUNTIS pmkid_count; + OPTIONAL gp_mgmt_cipher_suite[4]; +} + +IE RSNOpaque (EID_RSN) // 7.3.2.25 +{ + data[ 6..253 ]; +} + +IE WAPI (EID_WAPI) // 7.3.2.25 +{ + // The version is 2 octets, and we only support version 1. + version, 2 MUSTBE 1; + // count of AKM suite selectors + akm_suite_count, 2; + // Again, I see nothing in the Standard explicitly limiting the number of + // AKM suite selectors other than the maximum size of an IE. + akm_suites[4][0..4] COUNTIS akm_suite_count; + // we should see two more + // octets giving the number of Unicast Cipher Suites + unicast_cipher_suite_count, 2; + // I don't see anything in the Standard limiting the number of Pairwise + // Cypher Suites, other than the maximum length of an IE, which limits us + // to 61. However, that seems needlessly wasteful of space. + unicast_cipher_suites[4][0..4] COUNTIS unicast_cipher_suite_count; + // The next four octets will be the Multicast Cipher Suite + multicast_cipher_suite[4]; + // WAPI capabilities + { + preauth: 1; + reserved: 15; + } + // Finally, the IE may contain zero or more BKIDs: + OPTIONAL bkid_count, 2; + bkid[16][0..4] COUNTIS bkid_count; +} + +IE WAPIOpaque (EID_WAPI) // 7.3.2.25 +{ + data[ 6..253 ]; +} + +IE QBSSLoad (EID_QBSS_LOAD) // 7.3.2.28 +{ + stacount, 2; + chautil, 1; + avail, 2; +} + +IE EDCAParamSet (EID_EDCA_PARAM_SET) // 7.3.2.29 +{ + qos, 1; // ToDo: This is a bitfield whose format + // depends on whether this is from an AP + // or a STA, information which I'm not + // sure we have at parse time... + reserved, 1; + { + acbe_aifsn: 4; + acbe_acm: 1; + acbe_aci: 2; + unused1: 1; + } + { + acbe_acwmin: 4; + acbe_acwmax: 4; + } + acbe_txoplimit, 2; + { + acbk_aifsn: 4; + acbk_acm: 1; + acbk_aci: 2; + unused2: 1; + } + { + acbk_acwmin: 4; + acbk_acwmax: 4; + } + acbk_txoplimit, 2; + { + acvi_aifsn: 4; + acvi_acm: 1; + acvi_aci: 2; + unused3: 1; + } + { + acvi_acwmin: 4; + acvi_acwmax: 4; + } + acvi_txoplimit, 2; + { + acvo_aifsn: 4; + acvo_acm: 1; + acvo_aci: 2; + unused4: 1; + } + { + acvo_acwmin: 4; + acvo_acwmax: 4; + } + acvo_txoplimit, 2; +} + +IE TSPEC (EID_TSPEC) // 7.3.2.30 +{ + + // TS Info + { + traffic_type: 1; + tsid: 4; + direction: 2; + access_policy: 2; + aggregation: 1; + psb: 1; + user_priority: 3; + tsinfo_ack_pol: 2; + } + { + schedule: 1; + unused: 7; + } + + // Nominal MSDU Size + { + size: 15; + fixed: 1; + } + + max_msdu_size, 2; + min_service_int, 4; + max_service_int, 4; + inactivity_int, 4; + suspension_int, 4; + service_start_time, 4; + min_data_rate, 4; + mean_data_rate, 4; + peak_data_rate, 4; + burst_size, 4; + delay_bound, 4; + min_phy_rate, 4; + surplus_bw_allowance, 2; + medium_time, 2; + +} // End IE TSPEC. + +IE TCLAS (EID_TCLAS) // 7.3.2.31 +{ + user_priority, 1; + classifier_type, 1; + classifier_mask, 1; + UNION info (DISCRIMINATOR classifier_type) + { + EthParams (classifier_type IS 0) + { + source[6]; + dest[6]; + type, 2; + } + IpParams (classifier_type IS 1) + { + version, 1; + UNION params (DISCRIMINATOR version) + { + IpV4Params (version IS 4) + { + source[4]; + dest[4]; + src_port, 2; + dest_port, 2; + DSCP, 1; + proto, 1; + reserved, 1; + } + IpV6Params (version IS 6) + { + source[16]; + dest[16]; + src_port, 2; + dest_port, 2; + flow_label[3]; + } + }; + } + Params8021dq (classifier_type IS 2) + { + tag_type, 2; + } + }; +} // End IE TCLASS + +const EID_RRM_BEACON_REPORTING = 1; +const EID_RRM_BCN_REPORTING_DETAIL = 2; + +IE BeaconReporting (EID_RRM_BEACON_REPORTING) +{ + reportingCondition, 1; + threshold, 1; +} + +IE BcnReportingDetail (EID_RRM_BCN_REPORTING_DETAIL) +{ + reportingDetail, 1; +} + +IE APChannelReport (EID_AP_CHAN_REPORT) +{ + regulatoryClass, 1; + channelList[0..50]; +} + +IE MeasurementRequest (EID_MEAS_REQUEST) // 7.3.2.21 +{ + measurement_token, 1; + + // Measurement Request Mode + { + parallel: 1; + enable: 1; + request: 1; + report: 1; + durationMandatory: 1; + unused: 3; + } + + measurement_type, 1; + UNION measurement_request (DISCRIMINATOR measurement_type) + { + Basic (measurement_type IS 0) + { + channel_no, 1; + meas_start_time[8]; + meas_duration, 2; + } + CCA (measurement_type IS 1) + { + channel_no, 1; + meas_start_time[8]; + meas_duration, 2; + } + RPIHistogram (measurement_type IS 2) + { + channel_no, 1; + meas_start_time[8]; + meas_duration, 2; + } + Beacon (measurement_type IS 5) + { + regClass, 1; + channel, 1; + randomization, 2; + meas_duration, 2; + meas_mode, 1; + BSSID[6]; + OPTIE SSID; + OPTIE BeaconReporting; + OPTIE BcnReportingDetail; + OPTIE RequestedInfo; + OPTIE APChannelReport[0..2]; + //OPTIONAL vendor_specific[1..239]; + } + + }; +} + +const EID_BCN_REPORT_FRAME_BODY = 1; +IE BeaconReportFrmBody (EID_BCN_REPORT_FRAME_BODY) +{ + reportedFields[0..224]; +} + +IE MeasurementReport (EID_MEAS_REPORT) // 7.3.2.22 +{ + token, 1; + // Measurement Report Mode + { + late: 1; + incapable: 1; + refused: 1; + unused: 5; + } + type, 1; + OPTIONAL UNION report (DISCRIMINATOR type) + { + Basic (type IS 0) // 7.3.2.22.1 + { + channel, 1; + meas_start_time, 8; + meas_duration, 2; + // Map + { + bss: 1; + ofdm_preamble: 1; + unid_signal: 1; + rader: 1; + unmeasured: 1; + unused: 3; + } + } + CCA (type IS 1) + { + channel, 1; + meas_start_time, 8; + meas_duration, 2; + cca_busy_fraction, 1; + } + RPIHistogram (type IS 2) + { + channel, 1; + meas_start_time, 8; + meas_duration, 2; + rpi0_density, 1; + rpi1_density, 1; + rpi2_density, 1; + rpi3_density, 1; + rpi4_density, 1; + rpi5_density, 1; + rpi6_density, 1; + rpi7_density, 1; + } + Beacon (type IS 5) + { + regClass, 1; + channel, 1; + meas_start_time, 8; + meas_duration, 2; + // reported_frame_info, + { + condensed_PHY: 7; + reported_frame_type: 1; + } + RCPI, 1; + RSNI, 1; + BSSID[6]; + antenna_id, 1; + parent_TSF, 4; + OPTIE BeaconReportFrmBody; + //IE vendor_specific + } + }; +} + +IE TSDelay (EID_TS_DELAY) // 7.3.2.32 +{ + delay, 4; +} + +IE TCLASSPROC (EID_TCLASS_PROC) // 7.3.2.33 +{ + processing, 1; +} + +IE Schedule (EID_SCHEDULE) // 7.3.2.34 +{ + { + aggregation: 1; + tsid: 4; + direction: 2; + reserved: 9; + } + service_start_time, 4; + service_interval, 4; + max_service_dur, 2; + spec_interval, 2; +} + +IE QOSCapsAp (EID_QOS_CAPABILITY) // 7.3.2.35 +{ + { + count: 4; + qack: 1; + qreq: 1; + txopreq: 1; + reserved: 1; + } +} + +IE QOSCapsStation (EID_QOS_CAPABILITY) // 7.3.2.35 +{ + { + acvo_uapsd: 1; + acvi_uapsd: 1; + acbk_uapsd: 1; + acbe_uapsd: 1; + qack: 1; + max_sp_length: 2; + more_data_ack: 1; + } +} + +IE LinkIdentifier (EID_LINK_IDENTIFIER) // 7.3.2.62 +{ + bssid[6]; + InitStaAddr[6]; + RespStaAddr[6]; +} + +IE WPA (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01) +{ + // This IE's first two octets should be interpreted as a version number; + // we only support version 1. + version, 2 MUSTBE 1; + // A four-octet Multicast Cipher may or may not appear next (hence the + // OPTIONAL keyword) + OPTIONAL multicast_cipher[4]; + // Optional Unicast Cipher count + OPTIONAL unicast_cipher_count, 2; + // Next comes an array of four-octet Cipher Suite selectors; the COUNTIS + // clause indicates that the actual number of selectors seen is in the + // member 'unicast_cipher_count'. + unicast_ciphers[4][0..4] COUNTIS unicast_cipher_count; + // (Optional) Authentication suites: + OPTIONAL auth_suite_count, 2; + auth_suites[4][0..4] COUNTIS auth_suite_count; + // This field is declared optional as per bugs 15234, 14755, & 14991. + OPTIONAL caps, 2; +} + +IE WPAOpaque (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x01) +{ + data[ 2..249 ]; +} + +IE WMMInfoStation (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00) +{ + // This IE contains the QoS Info field when sent from WMM Station + version, 1; + { + acvo_uapsd: 1; + acvi_uapsd: 1; + acbk_uapsd: 1; + acbe_uapsd: 1; + reserved1: 1; + max_sp_length: 2; + reserved2: 1; + } +} + +IE WMMInfoAp (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x00) +{ + // This IE contains the QoS Info field when sent from WMM AP + version, 1; + { + param_set_count: 4; + reserved: 3; + uapsd: 1; + } +} + + +IE WMMParams (EID_VENDOR_SPECIFIC) OUI(0x00, 0x50, 0xF2, 0x02, 0x01) +{ + version, 1 MUSTBE 1; + qosInfo, 1; // ToDo: This is actually a + // bitfield, but it's format + // varies depending on whether + // the sender is a STA or AP... + reserved2, 1; + { + acbe_aifsn: 4; + acbe_acm: 1; + acbe_aci: 2; + unused1: 1; + } + { + acbe_acwmin: 4; + acbe_acwmax: 4; + } + acbe_txoplimit, 2; + { + acbk_aifsn: 4; + acbk_acm: 1; + acbk_aci: 2; + unused2: 1; + } + { + acbk_acwmin: 4; + acbk_acwmax: 4; + } + acbk_txoplimit, 2; + { + acvi_aifsn: 4; + acvi_acm: 1; + acvi_aci: 2; + unused3: 1; + } + { + acvi_acwmin: 4; + acvi_acwmax: 4; + } + acvi_txoplimit, 2; + { + acvo_aifsn: 4; + acvo_acm: 1; + acvo_aci: 2; + unused4: 1; + } + { + acvo_acwmin: 4; + acvo_acwmax: 4; + } + acvo_txoplimit, 2; +} + +IE WMMTSPEC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xf2, 0x02, 0x02) +{ + version, 1 MUSTBE 1; + + // TS Info + { + traffic_type: 1; + tsid: 4; + direction: 2; + access_policy: 2; + aggregation: 1; + psb: 1; + user_priority: 3; + tsinfo_ack_pol: 2; + } + { + tsinfo_rsvd: 7; + burst_size_defn: 1; + } + + // Nominal MSDU Size + { + size: 15; + fixed: 1; + } + + max_msdu_size, 2; + min_service_int, 4; + max_service_int, 4; + inactivity_int, 4; + suspension_int, 4; + service_start_time, 4; + min_data_rate, 4; + mean_data_rate, 4; + peak_data_rate, 4; + burst_size, 4; + delay_bound, 4; + min_phy_rate, 4; + surplus_bw_allowance, 2; + medium_time, 2; + +} // End IE WMMTSpec. + +IE WMMCaps (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x05) +{ + version, 1 MUSTBE 1; + { + reserved: 4; + qack: 1; + queue_request: 1; + txop_request: 1; + more_ack: 1; + } +} + +IE WMMTCLAS (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x06) +{ + version, 1 MUSTBE 1; + + user_priority, 1; + classifier_type, 1; + classifier_mask, 1; + UNION info (DISCRIMINATOR classifier_type) + { + EthParams (classifier_type IS 0) + { + source[6]; + dest[6]; + type, 2; + } + IpParams (classifier_type IS 1) + { + version, 1; + UNION params (DISCRIMINATOR version) + { + IpV4Params (version IS 4) + { + source[4]; + dest[4]; + src_port, 2; + dest_port, 2; + DSCP, 1; + proto, 1; + reserved, 1; + } + IpV6Params (version IS 6) + { + source[16]; + dest[16]; + src_port, 2; + dest_port, 2; + flow_label[3]; + } + }; + } + Params8021dq (classifier_type IS 2) + { + tag_type, 2; + } + }; + +} + +IE WMMTCLASPROC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x07) +{ + version, 1 MUSTBE 1; + processing, 1; +} + +IE WMMTSDelay (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x08) +{ + version, 1 MUSTBE 1; + delay, 4; +} + +IE WMMSchedule (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x02, 0x09) +{ + version, 1 MUSTBE 1; + + { + aggregation: 1; + tsid: 4; + direction: 2; + reserved: 9; + } + + service_start_time, 4; + service_interval, 4; + max_service_dur, 2; + spec_interval, 2; +} + +IE ESERadMgmtCap (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x01) +{ + + mgmt_state, 1; + + { + mbssid_mask: 3; + reserved: 5; + } + +} + +IE hs20vendor_ie (EID_VENDOR_SPECIFIC) OUI (0x50, 0x6F, 0x9A, 0x10) +{ + /* hotspot_configurations */ + { + dgaf_dis: 1; + hs_id_present: 2; + reserved: 1; + release_num: 4; + } + OPTIONAL UNION hs_id (DISCRIMINATOR hs_id_present) + { + pps_mo (hs_id_present IS 1) + { + pps_mo_id, 2; + } + anqp_domain (hs_id_present IS 2) + { + anqp_domain_id, 2; + } + }; +} + +IE ESETrafStrmMet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x07) +{ + tsid, 1; + state, 1; + msmt_interval, 2; +} + +IE ESETrafStrmRateSet (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x08) +{ + tsid, 1; + tsrates[0..8]; +} + +IE ESEVersion (EID_VENDOR_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x03) +{ + version, 1; +} + +IE ESETxmitPower (EID_ESE_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00) +{ + power_limit, 1; + reserved, 1; +} + +IE ESECckmOpaque (EID_ESE_CCKM_SPECIFIC) OUI (0x00, 0x40, 0x96, 0x00) +{ + data[ 6..20 ]; +} + +IE RRMEnabledCap (EID_RRM_ENABLED_CAPS) +{ + //Capability bitmap + { + LinkMeasurement: 1; + NeighborRpt: 1; + parallel: 1; + repeated: 1; + BeaconPassive: 1; + BeaconActive: 1; + BeaconTable: 1; + BeaconRepCond: 1; + } + { + FrameMeasurement: 1; + ChannelLoad: 1; + NoiseHistogram: 1; + statistics: 1; + LCIMeasurement: 1; + LCIAzimuth: 1; + TCMCapability: 1; + triggeredTCM: 1; + } + { + APChanReport: 1; + RRMMIBEnabled: 1; + operatingChanMax: 3; + nonOperatinChanMax: 3; + } + { + MeasurementPilot: 3; + MeasurementPilotEnabled: 1; + NeighborTSFOffset: 1; + RCPIMeasurement: 1; + RSNIMeasurement: 1; + BssAvgAccessDelay: 1; + } + { + BSSAvailAdmission: 1; + AntennaInformation: 1; + reserved: 6; + } +} + +IE MeasurementPilot (EID_RRM_MEAS_PILOT_TX_INFO) +{ + measurementPilot, 1; + vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now. +} + +IE MultiBssid (EID_MULTIPLE_BSSID) +{ + maxBSSIDIndicator, 1; + vendorSpecific[0..255]; +} + +IE OBSSScanParameters (EID_OBSS_SCAN_PARAMETERS) +{ + obssScanPassiveDwell, 2; + obssScanActiveDwell, 2; + bssChannelWidthTriggerScanInterval, 2; + obssScanPassiveTotalPerChannel, 2; + obssScanActiveTotalPerChannel, 2; + bssWidthChannelTransitionDelayFactor, 2; + obssScanActivityThreshold, 2; +} + +IE HT2040BSSCoexistence (EID_20_40_BSS_COEXISTENCE) +{ + // 20/40 BSS Coexistence Information + { + infoRequest: 1; + fortyMHzIntolerant: 1; + twentyMHzBssWidthReq: 1; + obssScanExemptionReq: 1; + obssScanExemptionGrant: 1; + unused: 3; + } +} + +IE HT2040BSSIntolerantReport (EID_20_40_BSS_INTOLERANT_REPORT) +{ + operatingClass, 1; + channelList[0..50]; +} + +const EID_RRM_NBR_RPT_TSF = 1; +const EID_RRM_NBR_CD_COUNTRY = 2; +const EID_RRM_NBR_MSMT_PILOT_TX_INFO = 66; + +IE NeighborReport (EID_NEIGHBOR_REPORT) +{ + bssid[6]; + //Bssid Info + { + APReachability: 2; + Security: 1; + KeyScope: 1; + //Capabilities + SpecMgmtCap: 1; + QosCap: 1; + apsd: 1; + rrm: 1; + } + //Capabilities contd. + { + DelayedBA: 1; + ImmBA: 1; + //Capabilities end. + MobilityDomain: 1; + reserved: 5; + } + + reserved1, 2; //part of BSSID Info. + + regulatoryClass, 1; + channel, 1; + PhyType, 1; + OPTIE IE TSFInfo (EID_RRM_NBR_RPT_TSF) + { + TsfOffset, 2; + BeaconIntvl, 2; + } + OPTIE IE CondensedCountryStr (EID_RRM_NBR_CD_COUNTRY) + { + countryStr[2]; + } + OPTIE IE MeasurementPilot; // (EID_RRM_NBR_MSMT_PILOT_TX_INFO) +// { +// measurementPilot, 1; +// vendorSpecific[0..255]; //Should be an IE. But currently only one level of nesting allowed. Can ignore for now. +// } + OPTIE IE RRMEnabledCap; + OPTIE IE MultiBssid; + //Ignoring vendor specific. +} + +IE RCPIIE (EID_RCPI) +{ + rcpi, 1; +} + +IE RSNIIE (EID_RSNI) +{ + rsni, 1; +} + +IE WFATPC (EID_VENDOR_SPECIFIC) OUI (0x00, 0x50, 0xF2, 0x08, 0x00) +{ + txPower, 1; + linkMargin, 1; +} + +IE MobilityDomain (EID_FT_MOBILITY_DOMAIN) +{ + MDID, 2; + //FT Capability and policy + { + overDSCap: 1; + resourceReqCap: 1; + reserved: 6; + } +} +const SUB_EID_FT_R1KH_ID = 1; +const SUB_EID_FT_GTK = 2; +const SUB_EID_FT_R0KH_ID = 3; +const SUB_EID_FT_IGTK = 4; +IE FTInfo (EID_FT_INFO) +{ + // MicControl, 2; + { + reserved: 8; + IECount: 8; + } + MIC[16]; + Anonce[32]; + Snonce[32]; + + OPTIE IE R1KH_ID (SUB_EID_FT_R1KH_ID) + { + PMK_R1_ID[6]; + } + + OPTIE IE GTK (SUB_EID_FT_GTK) + { + //Key Info + { + keyId: 2; + reserved: 14; + } + keyLength, 1; + RSC[8]; + key[5..32]; + } + + OPTIE IE R0KH_ID (SUB_EID_FT_R0KH_ID) + { + PMK_R0_ID[1..48]; + } + + OPTIE IE IGTK (SUB_EID_FT_IGTK) + { + //Key Info + keyID[2]; + IPN[6]; + keyLength, 1; + key[24]; + } +} + +IE TimeoutInterval (EID_TIMEOUT_INTERVAL) +{ + timeoutType, 1; + timeoutValue, 4; +} + +//TODO: need to define this properly. +IE RICData (EID_FT_RIC_DATA) +{ + Identifier, 1; + resourceDescCount, 1; + statusCode, 2; +} + +IE RICDescriptor (EID_FT_RIC_DESCRIPTOR) +{ + resourceType, 1; + variableData[0..255]; //Block ack param set...TODO: +} + +IE WscIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x00, 0x50, 0xF2, 0x04 ) +{ + data[ 2..249 ]; +} + +IE P2PIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x09 ) +{ + data[ 2..249 ]; +} + +IE WFDIEOpaque (EID_VENDOR_SPECIFIC) OUI ( 0x50, 0x6F, 0x9A, 0x0A ) +{ + data[ 2..249 ]; +} + +IE PTIControl (EID_PTI_CONTROL) // 7.3.2.65 +{ + tid, 1; + sequence_control, 2; +} + +IE PUBufferStatus (EID_PU_BUFFER_STATUS) // 7.3.2.66 +{ + { + ac_bk_traffic_aval: 1; + ac_be_traffic_aval: 1; + ac_vi_traffic_aval: 1; + ac_vo_traffic_aval: 1; + reserved: 4; + } +} + + +///////////////////////////////////////////////////////////////////////////// +// Airgo Information Elements + + +IE Airgo (EID_VENDOR_SPECIFIC) OUI (0x00, 0x0A, 0xF5) +{ + // N.B. The fact that these IEs are defined inside the Airgo IE indicates + // that they can *only* occur inside the Airgo IE. + + OPTIE IE PropSuppRates (SIR_MAC_PROP_EXT_RATES_TYPE) + { + rates[1..12]; + } + + OPTIE IE APName (SIR_MAC_PROP_AP_NAME_TYPE) + { + name[1..32]; + } + + OPTIE IE HCF (SIR_MAC_PROP_HCF_TYPE) + { + enabled, 1; + } + + OPTIE IE WDS (SIR_MAC_PROP_WDS_TYPE) + { + wdsData[0..ANI_WDS_INFO_MAX_LENGTH]; + } + + OPTIE IE BPIndicator (SIR_MAC_PROP_BP_IND_TYPE) + { + indicator, 1; + type, 1; + } + + + // In Progress: I think SIR_MAC_PROP_NEIGHBOR_BSS_TYPE is going to need a + // custom parser... + + + OPTIE IE LoadInfo (SIR_MAC_PROP_LOAD_INFO_TYPE) MSB + { + num_stas, 2; + channel_util, 2; + } + + OPTIE IE LoadBalance (SIR_MAC_PROP_LOAD_BALANCE_TYPE) + { + bssid[6]; + channel, 1; + } + + OPTIE IE PropAssocType (SIR_MAC_PROP_ASSOC_TYPE) + { + type, 1; + } + + OPTIE IE LLAttr (SIR_MAC_PROP_LL_ATTR_TYPE) MSB + { + defer_threshold, 4; + } + + OPTIE IE PropCapability (SIR_MAC_PROP_CAPABILITY) + { + capability, 2; + } + + OPTIE IE Version (SIR_MAC_PROP_VERSION) + { + chip_rev, 4; + card_type, 1; + build_version[0..20]; + } + + OPTIE IE PropEDCAParams (SIR_MAC_PROP_EDCAPARAMS) + { + qos, 1; // ToDo: This is a bitfield whose format + // depends on whether this is from an AP + // or a STA, information which I'm not + // sure we have at parse time... + reserved, 1; + + // Best Effort + { + acbe_aifsn: 4; + acbe_acm: 1; + acbe_aci: 2; + unused1: 1; + } + { + acbe_min: 4; + acbe_max: 4; + } + acbe_txoplimit, 2; + + // Background + { + acbk_aifsn: 4; + acbk_acm: 1; + acbk_aci: 2; + unused2: 1; + } + { + acbk_min: 4; + acbk_max: 4; + } + acbk_txoplimit, 2; + + // Video + { + acvi_aifsn: 4; + acvi_acm: 1; + acvi_aci: 2; + unused3: 1; + } + { + acvi_min: 4; + acvi_max: 4; + } + acvi_txoplimit, 2; + + // Voice + { + acvo_aifsn: 4; + acvo_acm: 1; + acvo_aci: 2; + unused4: 1; + } + { + acvo_min: 4; + acvo_max: 4; + } + acvo_txoplimit, 2; + + } // End IE PropEDCAParams. + + /** + * \ie Titan + * + * \brief Proprietary Next Generation (TITAN) IE structure + * + * + * Based on the setting of the "Titan" proprietary bit in the + * tSirPropIEStruct.capability field (bit #6), this IE will be sent + * appropriately to all the ANIpeers in the following management frames - + * + * - Beacons + * - Assoc Req/Rsp + * - Reassoc Req/Rsp + * - Probe Req/Rsp + * + */ + + OPTIE IE Titan (SIR_MAC_PROP_TITAN) + { + concat_tcid_bitmap, 1; + compression_tcid_bitmap, 1; + + // Identifies the OPERATIONAL state of Channel Bonding + // This info is encoded as a bitmap as follows: + // + // b7 b6 b5 b4 b3 b2 b1 b0 + // -------------------------------------- + // |CCA_CB |CCA |ICE | AU|CS|U/D| O | A | + // -------------------------------------- + // where, + // A - Admin state of CB - [enabled(1)/disabled(0)] + // O - Oper state of CB - [on(1)/off(0)] + // U/D - Indicates where the secondary CB channel is + // parked - Up(1)/Down(0) from the primary + // CS - Channel Switch announcement in progress with + // respect to the secondary CB channel + // CS_on(1)/CS_off(0) + // This applies to an AP only + // AU - Autonomous updates. This indicates to an STA + // that it can send an unsolicited CB Report + // regarding its neighbor BSS during an Assoc/ + // ReAssoc REQ. + // AU_on(1)/AU_off(0) + // This applies to an AP only + // ICE - Intelligent Channel Expansion mode enable/disable + // ICE_on(1)/ICE_off(0) + // CCA - CCA mode to be used + // CCA_20MHz(0)/CCA_40MHz(1) + // CCA_CB - channel bonding enable/disable based on cca monitoring + // enable(1)/disable(0) + + cb_state, 1; + + // Identifies Reverse FCS pattern and state + // This info is encoded as a bitmap as follows: + // + // b7 b6 b5 b4 b3 b2 b1 b0 + // --------------------------------- + // | X | X | X | X | P | P | P | O | + // --------------------------------- + // where, + // O - Oper state of Reverse FCS - [on(1)/off(0)] + // P - Identifies the pattern ID to be used + // NOTE - These bits are used only during Assoc Req/Rsp + // management frames. Thus, the pattern ID needs to be + // looked up only during Assoc Req/Rsp. In other words, + // the pattern ID between an AP/STA is negotiated via + // the revFcsState during Assoc Req/Rsp + + rev_fcs_state, 1; + } + + OPTIE IE PropChannSwitchAnn (SIR_MAC_PROP_CHANNEL_SWITCH) + { + mode, 1; + primary_channel, 1; + sub_band, 1; + channel_switch_count, 1; + } + + /** + * \ie PropQuietBSS + * + * \brief Proprietary Quite BSS IE structure + * + * + * Based on the setting of the "Titan" proprietary bit in the + * tSirPropIEStruct.capability field (bit #6), this IE will be sent + * appropriately to all the ANI peers in the following management + * frames + * + * - Beacons + * - Probe Rsp + * + */ + + OPTIE IE PropQuietBSS (SIR_MAC_PROP_QUIET_BSS) + { + // Indicates the number of TBTT's until the next beacon + // interval during which the next quiet interval will + // start + // 1 - Quiet Interval will start during the beacon + // interval starting at the next TBTT + // 0 - Reserved + quiet_count, 1; + + // Shall be set to the number of beacon intervals between + // the start of regularly scheduled quiet intervals + // defined by this Quiet Element + // 0 - No periodic quiet interval is defined + quiet_period, 1; + + // Duration of the quiet interval, expressed in TUs + // 1 TU = 1024 microseconds?? + quiet_duration, 2; + + // Set to the offset of the start of the quiet interval + // from the TBTT specified by the quietCount field, + // expressed in TUs. The value of this offset field will + // be less than one beacon interval + // 1 TU = 1024 microseconds?? + quiet_offset, 2; + + } + + OPTIE IE TriggerStaBgScan (SIR_MAC_PROP_TRIG_STA_BK_SCAN) + { + enable, 1; + } + + OPTIE IE Taurus (SIR_MAC_PROP_TAURUS) + { + // TID bitmap indicating the TIDs for which BA is setup. + // bit0 for TID0, bit1 for TID1 and so on. + baTIDBitmap, 2; + + // Block Ack Policy: 0-Delayed BA 1-Immediate BA. + // One bit for each TID + baPolicy, 2; + + // Buffer size for each AC, in exponential notation. + // 3 bits reserved for each AC. + // bit0-2 for AC0[TID 0 and 3], bit3-5 for AC1[TID 1 and 2] + // and so on. + + // TID 8 & 11 will use AC0, TID 9 & 10 will use AC1, so use of AC is + // overloaded. This is done to reduce the size of IE in the beacons. + { + baBufferSize: 12; + rsvd: 4; + } + } + +} // End IE Airgo. + +IE VHTCaps (EID_VHT_CAPABILITIES) +{ + //VHT Capability Info + { + maxMPDULen: 2; + supportedChannelWidthSet: 2; + ldpcCodingCap: 1; + shortGI80MHz: 1; + shortGI160and80plus80MHz: 1; + txSTBC: 1; + rxSTBC: 3; + suBeamFormerCap: 1; + suBeamformeeCap: 1; + csnofBeamformerAntSup: 3; + numSoundingDim: 3; + muBeamformerCap: 1; + muBeamformeeCap: 1; + vhtTXOPPS: 1; + htcVHTCap: 1; + maxAMPDULenExp: 3; + vhtLinkAdaptCap: 2; + rxAntPattern: 1; + txAntPattern: 1; + reserved1: 2; + } + rxMCSMap, 2; + { + rxHighSupDataRate: 13; + reserved2: 3; + } + txMCSMap, 2; + { + txSupDataRate: 13; + reserved3: 3; + } +} + +IE VHTOperation (EID_VHT_OPERATION_ELEMENT) +{ + chanWidth, 1; + chanCenterFreqSeg1, 1; + chanCenterFreqSeg2, 1; + basicMCSSet, 2; +} + +IE VHTExtBssLoad (EID_VHT_EXT_BSS_LOAD) +{ + muMIMOCapStaCount, 1; + ssUnderUtil, 1; + FortyMHzUtil, 1; + EightyMHzUtil, 1; + OneSixtyMHzUtil, 1; +} + +IE AID (EID_AID) +{ + assocId, 2; +} + +IE WiderBWChanSwitchAnn (EID_WIDER_BW_CHANNEL_SWITCH_ANN) +{ + newChanWidth, 1; + newCenterChanFreq0, 1; + newCenterChanFreq1, 1; +} + +IE ExtCap (EID_EXT_CAP) +{ + bytes[1..9]; +} + +IE HTCaps (EID_HT_CAPABILITIES) +{ + // HT Capability Info + { + advCodingCap: 1; + supportedChannelWidthSet: 1; + mimoPowerSave: 2; + greenField: 1; + shortGI20MHz: 1; + shortGI40MHz: 1; + txSTBC: 1; + rxSTBC: 2; + delayedBA: 1; + maximalAMSDUsize: 1; + dsssCckMode40MHz: 1; + psmp: 1; + stbcControlFrame: 1; + lsigTXOPProtection: 1; + } + // HT Parameters Info; + { + maxRxAMPDUFactor: 2; + mpduDensity: 3; + reserved1: 3; + } + + supportedMCSSet[ HT_MAX_SUPPORTED_MCS_SET ]; + + // Extended HT Capability Info + { + pco: 1; + transitionTime: 2; + reserved2: 5; + mcsFeedback: 2; + reserved3: 6; + } + // TXBF Capability Info + { + txBF: 1; + rxStaggeredSounding: 1; + txStaggeredSounding: 1; + rxZLF: 1; + txZLF: 1; + implicitTxBF: 1; + calibration: 2; + explicitCSITxBF: 1; + explicitUncompressedSteeringMatrix: 1; + explicitBFCSIFeedback: 3; + explicitUncompressedSteeringMatrixFeedback: 3; + explicitCompressedSteeringMatrixFeedback: 3; + csiNumBFAntennae: 2; + uncompressedSteeringMatrixBFAntennae: 2; + compressedSteeringMatrixBFAntennae: 2; + reserved4: 7; + } + // AS Capability Info + { + antennaSelection: 1; + explicitCSIFeedbackTx: 1; + antennaIndicesFeedbackTx: 1; + explicitCSIFeedback: 1; + antennaIndicesFeedback: 1; + rxAS: 1; + txSoundingPPDUs: 1; + reserved5: 1; + } + //TODO: take it out when generic fix to remove extra bytes in IE is available. + //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE. + rsvd[0..32]; + +} // End IE HTCaps. + +IE HTInfo (EID_HT_INFO) +{ + primaryChannel, 1; + + // ahtInfoField1 + { + secondaryChannelOffset: 2; + recommendedTxWidthSet: 1; + rifsMode: 1; + controlledAccessOnly: 1; + serviceIntervalGranularity: 3; + } + + // ahtInfoField2 + + + // ahtInfoField2 + { + opMode: 2; + nonGFDevicesPresent: 1; + transmitBurstLimit: 1; + obssNonHTStaPresent:1; + reserved: 11; + } + + + // ahtInfoField3 + { + basicSTBCMCS: 7; + dualCTSProtection: 1; + secondaryBeacon: 1; + lsigTXOPProtectionFullSupport: 1; + pcoActive: 1; + pcoPhase: 1; + reserved2: 4; + } + + basicMCSSet[ HT_MAX_SUPPORTED_MCS_SET ]; + + //TODO: take it out when generic fix to remove extra bytes in IE is available. + //This is required to interop with Dlink AP which is sending 2 bytes extra in HTInfo IE. + rsvd[0..32]; + +} // End IE HTInfo. + + +IE OperatingMode (EID_OPERATING_MODE) +{ + { //Operating Mode field + chanWidth: 2; + reserved: 2; + rxNSS: 3; + rxNSSType: 1; + } +} + +IE QosMapSet (EID_QOS_MAP_SET) +{ + dscp_exceptions[0..60]; +} + +CONTAINERIE RICDataDesc +{ + MANDIE RICData; + OPTIE RICDescriptor; + OPTIE TSPEC; + OPTIE TCLAS[0..2]; + OPTIE TCLASSPROC; + OPTIE TSDelay; + OPTIE Schedule; + OPTIE WMMTSPEC; + OPTIE WMMTCLAS[0..2]; + OPTIE WMMTCLASPROC; + OPTIE WMMTSDelay; + OPTIE WMMSchedule; +} + +///////////////////////////////////////////////////////////////////////////// +// MULTIIEs // +///////////////////////////////////////////////////////////////////////////// + +MULTIIE WSC ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // Must be 0x10 + OPTIONALTLV WPSState; + OPTIONALTLV APSetupLocked; + OPTIONALTLV SelectedRegistrarConfigMethods; + OPTIONALTLV UUID_E; + OPTIONALTLV UUID_R; + OPTIONALTLV RFBands; + OPTIONALTLV SelectedRegistrar; + OPTIONALTLV ConfigMethods; + OPTIONALTLV AssociationState; + OPTIONALTLV ConfigurationError; + OPTIONALTLV Manufacturer; + OPTIONALTLV ModelName; + OPTIONALTLV ModelNumber; + OPTIONALTLV SerialNumber; + OPTIONALTLV DeviceName; + OPTIONALTLV DevicePasswordID; + OPTIONALTLV PrimaryDeviceType; + OPTIONALTLV RequestType; + OPTIONALTLV ResponseType; + OPTIONALTLV VendorExtension; + OPTIONALTLV RequestDeviceType; +} + +MULTIIE WscBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV WPSState; // 1 = unconfigured, 2 = + // configured + OPTIONALTLV APSetupLocked; // Must be included if value + // is TRUE + OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the + // user has recently + // activated a Registrar to + // add an Enrollee. + OPTIONALTLV DevicePasswordID; // Device Password ID + // indicates the method or + // identifies the specific + // password that the + // selected Registrar + // intends to use. + OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains + // the config methods active + // on the selected + // Registrar. + OPTIONALTLV UUID_E; // The AP's UUID is provided + // only when the AP is a + // dual-band AP in push + // button mode and + // indicating push button + // mode on both radios + OPTIONALTLV RFBands; // Indicates all RF bands + // available on the AP. A + // dual-band AP must provide + // this attribute. + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs + +} // End Multi-IE WscBeacon. + +MULTIIE WscAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV RequestType; // + // + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 + +} // End Multi-IE WscAssocReq. + + +MULTIIE WscAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV ResponseType; // + // + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 + +} // End Multi-IE WscAssocRes. + +MULTIIE WscReassocRes ( 221 ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV ResponseType; // + // + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 + +} // End Multi-IE WscReassocRes + +MULTIIE WscProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV RequestType; // + // + MANDATORYTLV ConfigMethods; // Configuration methods the + // Enrollee or Registrar + // supports + MANDATORYTLV UUID_E; // unique GUID generated by + // the Enrollee. + MANDATORYTLV PrimaryDeviceType; + MANDATORYTLV RFBands; // Specific RF bands used + // for this message + MANDATORYTLV AssociationState; // Configuration and previous + // association state + MANDATORYTLV ConfigurationError; + MANDATORYTLV DevicePasswordID; + + // WSC 2.0 + OPTIONALTLV Manufacturer; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV ModelName; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV ModelNumber; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV DeviceName; // Must be included in ver 2.0 + // or higher. + OPTIONALTLV VendorExtension; // Version2 and RequestToEntroll + + OPTIONALTLV RequestDeviceType; // When a device receives a Probe + // Request containing this type, + // It will only reponse if Primary + // or Secondary Device Type matches. + +} // End Multi-IE WscProbeReq. + +MULTIIE WscProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + MANDATORYTLV WPSState; // 1 = unconfigured, 2 = + // configured + OPTIONALTLV APSetupLocked; // Must be included if value + // is TRUE + OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the + // user has recently + // activated a Registrar to + // add an Enrollee. + OPTIONALTLV DevicePasswordID; // Device Password ID + // indicates the method or + // identifies the specific + // password that the + // selected Registrar + // intends to use. + OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains + // the config methods active + // on the selected + // Registrar. + MANDATORYTLV ResponseType; + MANDATORYTLV UUID_E; // unique identifier of AP + MANDATORYTLV Manufacturer; + MANDATORYTLV ModelName; + MANDATORYTLV ModelNumber; + MANDATORYTLV SerialNumber; + MANDATORYTLV PrimaryDeviceType; + MANDATORYTLV DeviceName; // User-friendly description + // of device + MANDATORYTLV ConfigMethods; // Config Methods corresponds + // to the methods the AP + // supports as an Enrollee + // for adding external + // Registrars. + OPTIONALTLV RFBands; // Indicates all RF bands + // available on the AP. A + // dual-band AP must provide + // this attribute. + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs + +} // WscProbeRes. + +// This MULTIIE combines the fields from the WSC IEs as they appear in +// Beacons *and* in Probe Responses, with the difference that they're all +// optional. In our device drivers, we combine Probe Responses and Beacons +// into one list, and parse their IEs later (c.f. frame BeaconIEs). Because +// the WSC IE differs in those two frames, we'd often see warning messages +// about either unexpected fields showing up (if we thought we were parsing a +// Beacon, and we in fact had data from a Probe Response) or mandatory fields +// missing (if we thought we were parsing a Probe Response, and in fact had +// data from a Beacon). + +// I created this MULTIIE to stuff into the BeaconIEs frames to avoid this. +// It's intended to be used on unpack only, and to do so in a very forgiving +// way. + +MULTIIE WscBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + OPTIONALTLV Version; // 0x10 = version 1.0, 0x11 + // = version 1.1, etc. + OPTIONALTLV WPSState; // 1 = unconfigured, 2 = + // configured + OPTIONALTLV APSetupLocked; // Must be included if value + // is TRUE + OPTIONALTLV SelectedRegistrar; // BOOL: indicates if the + // user has recently + // activated a Registrar to + // add an Enrollee. + OPTIONALTLV DevicePasswordID; // Device Password ID + // indicates the method or + // identifies the specific + // password that the + // selected Registrar + // intends to use. + OPTIONALTLV SelectedRegistrarConfigMethods; // This attribute contains + // the config methods active + // on the selected + // Registrar. + OPTIONALTLV ResponseType; + OPTIONALTLV UUID_E; // unique identifier of AP + OPTIONALTLV Manufacturer; + OPTIONALTLV ModelName; + OPTIONALTLV ModelNumber; + OPTIONALTLV SerialNumber; + OPTIONALTLV PrimaryDeviceType; + OPTIONALTLV DeviceName; // User-friendly description + // of device + OPTIONALTLV ConfigMethods; // Config Methods corresponds + // to the methods the AP + // supports as an Enrollee + // for adding external + // Registrars. + OPTIONALTLV RFBands; // Indicates all RF bands + // available on the AP. A + // dual-band AP must provide + // this attribute. + // WSC 2.0 + OPTIONALTLV VendorExtension; // Version2 and AuthorizedMACs + +} // WscProbeRes. +///////////////////////////////////////////////////////////////////////////// +// MULTIIEs // +///////////////////////////////////////////////////////////////////////////// + +MULTIIE P2PBeacon ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; // Contains P2P Device + // and P2P Group Capability + MANDATORYTLV P2PDeviceId; // Contains P2P Device + // Address + OPTIONALTLV NoticeOfAbsence; // Indicates Notice of + // Absence schedule and + // CT Window + +} // End P2PBeacon + + +MULTIIE P2PAssocReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; // Contains P2P Device + // and P2P Group Capability + OPTIONALTLV ExtendedListenTiming; + MANDATORYTLV P2PDeviceInfo; + +} // End P2PAssocReq + + +MULTIIE P2PAssocRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + OPTIONALTLV ExtendedListenTiming; + +} // End P2PAssocRes + + +MULTIIE P2PProbeReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + OPTIONALTLV P2PDeviceId; + MANDATORYTLV ListenChannel; + OPTIONALTLV ExtendedListenTiming; + OPTIONALTLV OperatingChannel; +} // End P2PProbeReq + + +MULTIIE P2PProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + OPTIONALTLV ExtendedListenTiming; + OPTIONALTLV NoticeOfAbsence; + MANDATORYTLV P2PDeviceInfo; + OPTIONALTLV P2PGroupInfo; + +} // End P2PProbeRes + + +MULTIIE P2PBeaconProbeRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + OPTIONALTLV P2PCapability; + OPTIONALTLV P2PDeviceId; + OPTIONALTLV ExtendedListenTiming; + OPTIONALTLV NoticeOfAbsence; + OPTIONALTLV P2PDeviceInfo; + OPTIONALTLV P2PGroupInfo; + +} // End P2PBeaconProbeRes + + +MULTIIE P2PGONegReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + MANDATORYTLV GOIntent; + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV ListenChannel; + OPTIONALTLV ExtendedListenTiming; + MANDATORYTLV IntendedP2PInterfaceAddress; + MANDATORYTLV ChannelList; + MANDATORYTLV P2PDeviceInfo; + MANDATORYTLV OperatingChannel; + +} // End P2PGONegReq + + +MULTIIE P2PGONegRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV P2PCapability; + MANDATORYTLV GOIntent; + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV OperatingChannel; + MANDATORYTLV IntendedP2PInterfaceAddress; + MANDATORYTLV ChannelList; + MANDATORYTLV P2PDeviceInfo; + OPTIONALTLV P2PGroupId; + +} // End P2PGONegRes + + +MULTIIE P2PGONegCnf ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV P2PCapability; + MANDATORYTLV OperatingChannel; + MANDATORYTLV ChannelList; + OPTIONALTLV P2PGroupId; + +} // End P2PGONegCnf + + +MULTIIE P2PGONegWPS ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV Version; + MANDATORYTLV DevicePasswordID; + +} // End P2PGONegWPS + + +MULTIIE P2PDeAuth ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV MinorReasonCode; +} + + +MULTIIE P2PDisAssoc ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV MinorReasonCode; +} + + +MULTIIE P2PInvitationReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV InvitationFlags; + MANDATORYTLV OperatingChannel; + MANDATORYTLV P2PGroupBssid; + MANDATORYTLV ChannelList; + MANDATORYTLV P2PGroupId; + MANDATORYTLV P2PDeviceInfo; +} + + +MULTIIE P2PInvitationRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV ConfigurationTimeout; + MANDATORYTLV OperatingChannel; + MANDATORYTLV P2PGroupBssid; + MANDATORYTLV ChannelList; +} + + +MULTIIE P2PDeviceDiscoverabilityReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PDeviceId; + MANDATORYTLV P2PGroupId; +} + + +MULTIIE P2PDeviceDiscoverabilityRes ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; +} + + +MULTIIE P2PProvisionDiscoveryReq ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PCapability; + MANDATORYTLV P2PDeviceInfo; + MANDATORYTLV P2PGroupId; +} + +MULTIIE P2PWSCProvisionDiscoveryRes ( EID_VENDOR_SPECIFIC ) OUI( 0x00, 0x50, 0xF2, 0x04 ) +{ + MANDATORYTLV ConfigMethods; +} + + +MULTIIE P2PNoticeOfAbsence ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV NoticeOfAbsence; +} + + +MULTIIE P2PPresenceResponse ( EID_VENDOR_SPECIFIC ) OUI( 0x50, 0x6F, 0x9A, 0x09 ) +{ + MANDATORYTLV P2PStatus; + MANDATORYTLV NoticeOfAbsence; +} + + +///////////////////////////////////////////////////////////////////////////// +// Frames + +FRAME Beacon // C.f. Sec. 7.2.3.1 +{ + FF TimeStamp; + FF BeaconInterval; + FF Capabilities; + MANDIE SSID; + MANDIE SuppRates; + OPTIE FHParamSet; + OPTIE DSParams; + OPTIE CFParams; + OPTIE IBSSParams; + OPTIE TIM; + OPTIE Country; + OPTIE FHParams; + OPTIE FHPattTable; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSN; + OPTIE QBSSLoad; + OPTIE EDCAParamSet; + OPTIE QOSCapsAp; + OPTIE APChannelReport; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE WAPI; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + + OPTIE Airgo; + OPTIE WscBeacon; + OPTIE P2PBeacon; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE WiderBWChanSwitchAnn; + OPTIE OBSSScanParameters; + OPTIE hs20vendor_ie; +} // End frame Beacon. + +// Ok, here's the story on Beacon1 & Beacon2. We presumably beacon a lot +// more than we change configuration. So it makes sense to keep the beacon +// we plan to send next in serialized format. We do this in struct schMisc. +// Whenever our config changes in a way that would affect our beacons, we +// just update our internal datastructures & re-generate the serialized +// beacon. + +// The problem is that there are *some* fields that need to be updated at +// send time, specifically the CF Param Set & the TIM. So, what we do is +// this: whenever our config changes, call schSetFixedBeaconFields. There, +// we serialize the following Beacon fields into gSchBeaconFrameBegin (after +// the power template & MAC header): TimeStamp, BeaconInterval, Capabilities, +// SSID, SuppRates, DSParams, & IBSSParams. It sets gSchBeaconOffsetBegin to +// the length of this buffer (incl. power template & MAC header). + +// Next, it serializes the following fields into gSchBeaconFrameEnd: Country, +// EDCAParamSet, PowerConstraints, TPCReport, ChannelSwitchAnn, Quiet, +// ERPInfo, HTCaps, HTInfo, ExtSuppRates, Airgo (via +// sirFillPropIEsInBeaconPR), WPA, RSN, WMMInfo, WMMParams, WMMCaps. The +// length of *this* buffer is kept in gSchBeaconOffsetEnd. + +// Then, in 'schBeaconInterruptHandler', we write CFParams & TIM at the end +// of gSchBeaconFrameBegin, keeping track of the (new) size of this buffer in +// the local 'beaconSize'. + +// After that, we call 'specialBeaconProcessing'. Note that this may +// actually call schSetFixedBeaconFields repeatedly! The comments say they +// try to avoid this, but... + +// Finally, we call writeBeaconToTFP, where the first thing we do is copy the +// gSchBeaconFrameEnd buffer after the end of gSchBeaconFrameBegin. + +FRAME Beacon1 +{ + FF TimeStamp; + FF BeaconInterval; + FF Capabilities; + MANDIE SSID; + MANDIE SuppRates; + OPTIE DSParams; + OPTIE IBSSParams; +} + +FRAME Beacon2 +{ + OPTIE Country; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSNOpaque; + OPTIE EDCAParamSet; + OPTIE APChannelReport; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE Airgo; + OPTIE WscBeacon; + OPTIE WAPI; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + OPTIE P2PBeacon; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE WiderBWChanSwitchAnn; + OPTIE OBSSScanParameters; + OPTIE hs20vendor_ie; +} + +// This frame is just Beacon with its Fixed Fields stripped out. It's handy +// for use with struct 'tSirBssDescription', which has members corresponding +// to some fixed fields, but keeps its IEs in un-parsed format. + +// Note that it also includes the IE 'WscBeaconProbeRes'. + +FRAME BeaconIEs +{ + + MANDIE SSID; + MANDIE SuppRates; + OPTIE FHParamSet; + OPTIE DSParams; + OPTIE CFParams; + OPTIE IBSSParams; + OPTIE TIM; + OPTIE Country; + OPTIE FHParams; + OPTIE FHPattTable; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSN; + OPTIE QBSSLoad; + OPTIE EDCAParamSet; + OPTIE QOSCapsAp; + OPTIE APChannelReport; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE WAPI; + OPTIE ESEVersion; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + + OPTIE Airgo; + OPTIE WscBeaconProbeRes; + OPTIE P2PBeaconProbeRes; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE WiderBWChanSwitchAnn; + OPTIE OBSSScanParameters; + OPTIE hs20vendor_ie; + +} // End frame BeaconIEs. + +FRAME Disassociation // 7.3.3.3 +{ + FF Reason; + OPTIE P2PDisAssoc; +} + +FRAME AssocRequest // 7.2.3.4 +{ + FF Capabilities; + FF ListenInterval; + MANDIE SSID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE PowerCaps; + OPTIE SuppChannels; + OPTIE RSNOpaque; + OPTIE QOSCapsStation; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE WPAOpaque; + OPTIE HTCaps; + OPTIE WMMCaps; + OPTIE WMMInfoStation; + OPTIE Airgo; + OPTIE WscIEOpaque; + OPTIE WAPIOpaque; + OPTIE ESERadMgmtCap; + OPTIE ESEVersion; + OPTIE P2PIEOpaque; + OPTIE WFDIEOpaque; + OPTIE VHTCaps; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE QosMapSet; + OPTIE hs20vendor_ie; +} // End frame AssocRequest. + +FRAME AssocResponse // 7.2.3.5 +{ + FF Capabilities; + FF Status; + FF AID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE EDCAParamSet; + OPTIE RCPIIE; + OPTIE RSNIIE; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE RICDataDesc[2]; + OPTIE WPA; + OPTIE TimeoutInterval; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + OPTIE WMMTSPEC[0..4]; + OPTIE Airgo; + OPTIE WscAssocRes; + OPTIE P2PAssocRes; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE ExtCap; + OPTIE OBSSScanParameters; + OPTIE QosMapSet; +} // End frame AssocResponse. + +FRAME ReAssocRequest // 7.2.3.6 +{ + FF Capabilities; + FF ListenInterval; + FF CurrentAPAddress; + MANDIE SSID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE PowerCaps; + OPTIE SuppChannels; + OPTIE RSNOpaque; + OPTIE QOSCapsStation; + OPTIE RRMEnabledCap; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE RICDataDesc[2]; + OPTIE WPAOpaque; + OPTIE HTCaps; + OPTIE WMMCaps; + OPTIE WMMInfoStation; + OPTIE Airgo; + OPTIE WscIEOpaque; + OPTIE WAPIOpaque; + OPTIE ESERadMgmtCap; + OPTIE ESEVersion; + OPTIE ESECckmOpaque; + OPTIE WMMTSPEC[0..4]; + OPTIE ESETrafStrmRateSet; + OPTIE P2PIEOpaque; + OPTIE WFDIEOpaque; + OPTIE VHTCaps; + OPTIE ExtCap; + OPTIE OperatingMode; + OPTIE QosMapSet; + OPTIE hs20vendor_ie; +} // End frame ReAssocRequest. + +FRAME ReAssocResponse // 7.2.3.7 +{ + FF Capabilities; + FF Status; + FF AID; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE EDCAParamSet; + OPTIE RCPIIE; + OPTIE RSNIIE; + OPTIE RRMEnabledCap; + OPTIE RSNOpaque; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE RICDataDesc[2]; + OPTIE WPA; + OPTIE TimeoutInterval; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE WMMParams; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + OPTIE WMMTSPEC[0..4]; + OPTIE ESETrafStrmRateSet; + OPTIE Airgo; + OPTIE WscReassocRes; + OPTIE P2PAssocRes; + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE ExtCap; + OPTIE OBSSScanParameters; + OPTIE QosMapSet; +} // End frame ReAssocResponse. + +FRAME ProbeRequest // 7.2.3.8 +{ + MANDIE SSID; + MANDIE SuppRates; + OPTIE RequestedInfo; + OPTIE ExtSuppRates; + OPTIE DSParams; + OPTIE HTCaps; + OPTIE WscProbeReq; + OPTIE WFATPC; + OPTIE P2PProbeReq; + OPTIE VHTCaps; +} // End frame ProbeRequest. + +FRAME ProbeResponse // 7.2.3.9 +{ + FF TimeStamp; + FF BeaconInterval; + FF Capabilities; + MANDIE SSID; + MANDIE SuppRates; + OPTIE FHParamSet; + OPTIE DSParams; + OPTIE CFParams; + OPTIE IBSSParams; + OPTIE Country; + OPTIE FHParams; + OPTIE FHPattTable; + OPTIE PowerConstraints; + OPTIE ChanSwitchAnn; + OPTIE Quiet; + OPTIE TPCReport; + OPTIE ERPInfo; + OPTIE ExtSuppRates; + OPTIE RSNOpaque; + OPTIE QBSSLoad; + OPTIE EDCAParamSet; + OPTIE RRMEnabledCap; + OPTIE APChannelReport; + OPTIE MobilityDomain; + OPTIE WPA; + OPTIE HTCaps; + OPTIE HTInfo; + OPTIE ExtChanSwitchAnn; + OPTIE WMMInfoAp; + OPTIE WMMParams; + OPTIE WMMCaps; + OPTIE WAPI; + OPTIE ESERadMgmtCap; + OPTIE ESETrafStrmMet; + OPTIE ESETxmitPower; + + OPTIE Airgo; + OPTIE WscProbeRes; + OPTIE P2PProbeRes; + + OPTIE VHTCaps; + OPTIE VHTOperation; + OPTIE VHTExtBssLoad; + OPTIE ExtCap; + OPTIE OBSSScanParameters; + OPTIE hs20vendor_ie; +} // End frame ProbeResponse. + +FRAME Authentication // 7.2.3.10 +{ + FF AuthAlgo; + FF AuthSeqNo; + FF Status; + OPTIE ChallengeText; + OPTIE RSNOpaque; + OPTIE MobilityDomain; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICDataDesc[2]; +} // End frame Auth. + +FRAME DeAuth // 7.2.3.11 +{ + FF Reason; + OPTIE P2PDeAuth; +} + +FRAME AddTSRequest // 7.4.2.1 +{ + + FF Category; + FF Action; + FF DialogToken; + MANDIE TSPEC; + OPTIE TCLAS[0..2]; + OPTIE TCLASSPROC; + + // These IEs aren't in the spec, but our extant code *will* parse them if + // they're present. I included them to preserve that capability + + OPTIE WMMTSPEC; + OPTIE WMMTCLAS[0..2]; + OPTIE WMMTCLASPROC; + OPTIE ESETrafStrmRateSet; + +} // End frame AddTSRequest. + +FRAME WMMAddTSRequest +{ + FF Category; + FF Action; + FF DialogToken; + FF StatusCode; + MANDIE WMMTSPEC; + OPTIE ESETrafStrmRateSet; +} // End Frame WMMAddTSRequest + +FRAME AddTSResponse // 7.4.2.2 +{ + + FF Category; + FF Action; + FF DialogToken; + FF Status; + MANDIE TSDelay; + MANDIE TSPEC; + OPTIE TCLAS[0..2]; + OPTIE TCLASSPROC; + OPTIE Schedule; + + // These IEs aren't in the spec, but our extant code *will* parse them if + // they're present. I included them to preserve that capability + OPTIE WMMTSDelay; + OPTIE WMMSchedule; + OPTIE WMMTSPEC; + OPTIE WMMTCLAS[0..2]; + OPTIE WMMTCLASPROC; + OPTIE ESETrafStrmMet; + +} // End frame AddTSResponse. + +FRAME WMMAddTSResponse +{ + + FF Category; + FF Action; + FF DialogToken; + FF StatusCode; + OPTIE WMMTSPEC; + OPTIE ESETrafStrmMet; + +} // End frame WMMAddTSResponse. + +FRAME DelTS // 7.4.2.3 +{ + FF Category; + FF Action; + FF TSInfo; + FF Reason; +} + +FRAME WMMDelTS +{ + FF Category; + FF Action; + FF DialogToken; + FF StatusCode; + MANDIE WMMTSPEC; +} + +FRAME TPCRequest +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE TPCRequest; +} + +FRAME TPCReport +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE TPCReport; +} + +FRAME ChannelSwitch +{ + FF Category; + FF Action; + MANDIE ChanSwitchAnn; + OPTIE ExtChanSwitchAnn; + OPTIE WiderBWChanSwitchAnn; +} + +FRAME MeasurementRequest +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE MeasurementRequest[1..4]; +} + +FRAME MeasurementReport +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE MeasurementReport; +} + +FRAME AddBAReq +{ + FF Category; + FF Action; + FF DialogToken; + FF AddBAParameterSet; + FF BATimeout; + FF BAStartingSequenceControl; +} + +FRAME AddBARsp +{ + FF Category; + FF Action; + FF DialogToken; + FF Status; + FF AddBAParameterSet; + FF BATimeout; +} + +FRAME DelBAInd +{ + FF Category; + FF Action; + FF DelBAParameterSet; + FF Reason; +} + +FRAME SMPowerSave +{ + FF Category; + FF Action; + FF SMPowerModeSet; +} + +FRAME RadioMeasurementRequest +{ + FF Category; + FF Action; + FF DialogToken; + FF NumOfRepetitions; + //Measurement Request IE. + MANDIE MeasurementRequest[1..2]; +} + +FRAME RadioMeasurementReport +{ + FF Category; + FF Action; + FF DialogToken; + //Measurement Report elements. + MANDIE MeasurementReport[1..4]; +} + +FRAME LinkMeasurementRequest +{ + FF Category; + FF Action; + FF DialogToken; + FF TxPower; + FF MaxTxPower; + //Optional Sub Ies +} + +FRAME LinkMeasurementReport +{ + FF Category; + FF Action; + FF DialogToken; + FF TPCEleID; + FF TPCEleLen; + FF TxPower; + FF LinkMargin; + FF RxAntennaId; + FF TxAntennaId; + FF RCPI; + FF RSNI; + //Optional Vendor specific IEs ... ignoring +} + +FRAME NeighborReportRequest +{ + FF Category; + FF Action; + FF DialogToken; + OPTIE SSID; + //Optional vendor specific IE...ignoring. +} + +FRAME NeighborReportResponse +{ + FF Category; + FF Action; + FF DialogToken; + OPTIE NeighborReport[1..4]; +} + +FRAME GONegReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PGONegWPS; + MANDIE P2PGONegReq; +} + +FRAME GONegRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PGONegWPS; + MANDIE P2PGONegRes; +} + + +FRAME GONegCnf +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PGONegCnf; +} + + +FRAME InvitationReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PInvitationReq; +} + + +FRAME InvitationRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PInvitationRes; +} + + +FRAME DeviceDiscoverabilityReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PDeviceDiscoverabilityReq; +} + + +FRAME DeviceDiscoverabilityRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PDeviceDiscoverabilityRes; +} + + + +FRAME ProvisionDiscoveryReq +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PProvisionDiscoveryReq; +} + + +FRAME ProvisionDiscoveryRes +{ + FF Category; + FF Action; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PWSCProvisionDiscoveryRes; +} + + +FRAME NoticeOfAbs +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PNoticeOfAbsence; +} + + +FRAME PresenceReq +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PNoticeOfAbsence; +} + + +FRAME PresenceRes +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; + MANDIE P2PPresenceResponse; +} + + +FRAME GODiscoverabilityReq +{ + FF Category; + FF P2POUI; + FF P2POUISubType; + FF DialogToken; +} + +FRAME OperatingMode +{ + FF Category; + FF Action; + //Operating Mode field + FF OperatingMode; +} + +FRAME TDLSDisReq +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE LinkIdentifier; +} + +FRAME TDLSDisRsp +{ + FF Category; + FF Action; + FF DialogToken; + FF Capabilities; + MANDIE SuppRates; + OPTIE ExtSuppRates; + OPTIE SuppChannels; + OPTIE SuppOperatingClasses; + OPTIE RSN; + OPTIE ExtCap; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICData; + OPTIE HTCaps; + OPTIE HT2040BSSCoexistence; + MANDIE LinkIdentifier; + OPTIE VHTCaps; +} + +FRAME TDLSSetupReq +{ + FF Category; + FF Action; + FF DialogToken; + FF Capabilities; + MANDIE SuppRates; + OPTIE Country; + OPTIE ExtSuppRates; + OPTIE SuppChannels; + OPTIE RSN; + OPTIE ExtCap; + OPTIE SuppOperatingClasses; + OPTIE QOSCapsStation; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICData; + OPTIE HTCaps; + OPTIE HT2040BSSCoexistence; + MANDIE LinkIdentifier; + OPTIE WMMInfoStation; + OPTIE AID; + OPTIE VHTCaps; +} + +FRAME TDLSSetupRsp +{ + FF Category; + FF Action; + FF Status; + FF DialogToken; + FF Capabilities ; + OPTIE SuppRates; + OPTIE Country; + OPTIE ExtSuppRates; + OPTIE SuppChannels; + OPTIE RSN; + OPTIE ExtCap; + OPTIE SuppOperatingClasses; + OPTIE QOSCapsStation; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE RICData; + OPTIE HTCaps; + OPTIE HT2040BSSCoexistence; + OPTIE LinkIdentifier; + OPTIE WMMInfoStation; + OPTIE AID; + OPTIE VHTCaps; + OPTIE OperatingMode; +} + +FRAME TDLSSetupCnf +{ + FF Category; + FF Action; + FF Status; + FF DialogToken; + OPTIE RSN; + OPTIE EDCAParamSet; + OPTIE FTInfo; + OPTIE TimeoutInterval; + OPTIE HTInfo; + OPTIE HT2040BSSCoexistence; + OPTIE LinkIdentifier; + OPTIE WMMParams; + OPTIE VHTOperation; + OPTIE OperatingMode; +} +FRAME TDLSTeardown +{ + FF Category; + FF Action; + FF Reason; + OPTIE FTInfo; + MANDIE LinkIdentifier; +} + +FRAME TDLSPeerTrafficInd +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE LinkIdentifier; + OPTIE PTIControl; + MANDIE PUBufferStatus; +} + +FRAME TDLSPeerTrafficRsp +{ + FF Category; + FF Action; + FF DialogToken; + MANDIE LinkIdentifier; +} + +FRAME SaQueryReq +{ + FF Category; + FF Action; + FF TransactionId; +} + +FRAME SaQueryRsp +{ + FF Category; + FF Action; + FF TransactionId; +} + +FRAME QosMapConfigure +{ + FF Category; + FF Action; + MANDIE QosMapSet; +} + +FRAME RMC +{ + FF Category; + FF RMCOUI; + FF MagicCode; + FF RMCVersion; + FF Action; + FF RMCDialogToken; + FF Ruler; +} + +FRAME VHTGidManagementActionFrame +{ + FF Category; + FF Action; + FF VhtMembershipStatusArray; + FF VhtUserPositionArray; +} + +FRAME HT2040BSSCoexistenceManagementActionFrame +{ + FF Category; + FF Action; + MANDIE HT2040BSSCoexistence; + MANDIE HT2040BSSIntolerantReport; +} + +// Local Variables: +// mode: c++ +// fill-column: 77 +// comment-column: 42 +// indent-tabs-mode: nil +// show-trailing-whitespace: t +// End: + +// parser.frms ends here. diff --git a/drivers/staging/prima/CORE/MAC/src/cfg/polFile.h b/drivers/staging/prima/CORE/MAC/src/cfg/polFile.h new file mode 100644 index 000000000000..7cf897857d1e --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/cfg/polFile.h @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//================================================================== +// +// File: polFile.h +// +// Description: Structures that define the firmware file format. +// +// Author: Larry Cawley +// +// +// +// Change History: +// 04/09/2002 - LAC - Initial version. +// +//=================================================================== +#if !defined( __polFile_h__ ) +#define __polFile_h__ + + + + +// File format +// +// byte 0 1 2 3 +// +// +---------+---------+--------+-------+ <----+ +// | Major | Minor | | | | +// | Version | Version | Suffix | Build | FileVersion | +// +---------+---------+--------+-------+ | +// | Major | Minor | | | | +// | Version | Version | Suffix | Build | HwCapabilities | tPolFileHeader +// +---------+---------+--------+-------+ | +// | | | +// | FileLength | FileLength | +// +------------------------------------+ | +// | | | +// | Number of Directory Entries | NumDirectoryEntries | +// +------------------------------------+ <----+ +// | | | +// | Directory Entry 1 Type | DirEntryType | +// +------------------------------------+ | +// | | | tPolFileDirEntry 1 +// | Directory Entry 1 File Offset | DirEntryFileOffset | +// +------------------------------------+ | +// | | | +// | Directory Entry 1 Length | DirEntryLength | +// +------------------------------------+ <----+ +// | . . . | . . . +// +------------------------------------+ <----+ +// | | | +// | Directory Entry n Type | | +// +------------------------------------+ | +// | | | tpolFileDirEntry n +// | Directory Entry n File Offset | | +// +------------------------------------+ | +// | | | +// | Directory Entry n Length | | +// +------------------------------------+ <----+ +// | | +// | | +// | File data described by | +// | directory entry 1 | +// | | +// | | +// +------------------------------------+ +// | . . . | +// +------------------------------------+ +// | | +// | | +// | File data described by | +// | directory entry n | +// | | +// | | +// +---------+---------+----------------+ +// | | +// | File Checksum | +// +---------+---------+ +// +// +// +// + + +#pragma pack( push ) +#pragma pack( 1 ) + +typedef struct sPolFileVersion { + + unsigned char MajorVersion; + unsigned char MinorVersion; + unsigned char Suffix; + unsigned char Build; + +} tPolFileVersion; + + +typedef struct sPolFileHeader { + + tPolFileVersion FileVersion; + tPolFileVersion HWCapabilities; + unsigned int FileLength; + unsigned int NumDirectoryEntries; + +} tPolFileHeader; + + +typedef enum ePolFileDirTypes { + + ePOL_DIR_TYPE_BOOTLOADER = 0, + ePOL_DIR_TYPE_STA_FIRMWARE, + ePOL_DIR_TYPE_AP_FIRMWARE, + ePOL_DIR_TYPE_DIAG_FIRMWARE, + ePOL_DIR_TYPE_STA_CONFIG, + ePOL_DIR_TYPE_AP_CONFIG + +} tPolFileDirTypes; + + +typedef struct sPolFileDirEntry { + + unsigned int DirEntryType; + unsigned int DirEntryFileOffset; + unsigned int DirEntryLength; + +} tPolFileDirEntry; + + +#pragma pack( pop ) + + +__inline unsigned short polFileChkSum( unsigned short *FileData, unsigned long NumWords ) +{ + unsigned long Sum; + + for ( Sum = 0; NumWords > 0; NumWords-- ) { + + Sum += *FileData++; + } + + Sum = (Sum >> 16) + (Sum & 0xffff); // add carry + Sum += (Sum >> 16); // maybe last unsigned short + + return( (unsigned short)( ~Sum ) ); +} + + + +#endif + diff --git a/drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.c b/drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.c new file mode 100644 index 000000000000..f73bcb8a0be9 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.c @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file dphHashTable.cc implements the member functions of + * DPH hash table class. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "cfgApi.h" +#include "schApi.h" +#include "dphGlobal.h" +#include "limDebug.h" + + +#include "halMsgApi.h" + +// --------------------------------------------------------------------- +/** + * dphHashTableClass() + * + * FUNCTION: + * Constructor function + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void dphHashTableClassInit(tpAniSirGlobal pMac, dphHashTableClass* pDphHashTable) +{ + tANI_U16 i; + + for (i=0; isize; i++) + { + pDphHashTable->pHashTable[i] = 0; + } + + for (i=0; isize; i++) + { + pDphHashTable->pDphNodeArray[i].valid = 0; + pDphHashTable->pDphNodeArray[i].added = 0; + pDphHashTable->pDphNodeArray[i].assocId = i; + } + +} + +// --------------------------------------------------------------------- +/** + * hashFunction + * + * FUNCTION: + * Hashing function + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @return None + */ + +tANI_U16 hashFunction(tpAniSirGlobal pMac, tANI_U8 staAddr[], tANI_U16 numSta) +{ + int i; + tANI_U16 sum = 0; + + for (i=0; i<6; i++) + sum += staAddr[i]; + + return (sum % numSta); +} + +// --------------------------------------------------------------------- +/** + * dphLookupHashEntry + * + * FUNCTION: + * Look up an entry in hash table + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @param pStaId pointer to the Station ID assigned to the station + * @return pointer to STA hash entry if lookup was a success \n + * NULL if lookup was a failure + */ + +tpDphHashNode dphLookupHashEntry(tpAniSirGlobal pMac, tANI_U8 staAddr[], tANI_U16 *pAssocId, + dphHashTableClass* pDphHashTable) +{ + tpDphHashNode ptr = NULL; + tANI_U16 index = hashFunction(pMac, staAddr, pDphHashTable->size); + + if (!pDphHashTable->pHashTable) + { + limLog(pMac, LOGE, FL(" pHashTable is NULL ")); + return ptr; + } + + for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) + { + if (dphCompareMacAddr(staAddr, ptr->staAddr)) + { + *pAssocId = ptr->assocId; + break; + } + } + return ptr; +} + +// --------------------------------------------------------------------- +/** + * dphGetHashEntry + * + * FUNCTION: + * Get a pointer to the hash node + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staId Station ID + * @return pointer to STA hash entry if lookup was a success \n + * NULL if lookup was a failure + */ + +tpDphHashNode dphGetHashEntry(tpAniSirGlobal pMac, tANI_U16 peerIdx, dphHashTableClass* pDphHashTable) +{ + if (peerIdx < pDphHashTable->size) + { + if (pDphHashTable->pDphNodeArray[peerIdx].added) + return &pDphHashTable->pDphNodeArray[peerIdx]; + else + return NULL; + } + else + return NULL; + +} + +static inline tpDphHashNode getNode(tpAniSirGlobal pMac, tANI_U8 assocId, dphHashTableClass* pDphHashTable) +{ + return &pDphHashTable->pDphNodeArray[assocId]; +} + + + + +// --------------------------------------------------------------------- +/** + * dphLookupAssocId + * + * FUNCTION: + * This function looks up assocID given the station Id. It traverses the complete table to do this. + * Need to find an efficient way to do this. + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to global Mac structure. + * @param staIdx station ID + * @param *assocId pointer to associd to be returned by this function. + * @return pointer to the dph node. + */ +tpDphHashNode dphLookupAssocId(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U16* assocId, dphHashTableClass* pDphHashTable) +{ + tANI_U8 i; + + for(i=0; isize; i++) + { + if( (pDphHashTable->pDphNodeArray[i].added) && + (pDphHashTable->pDphNodeArray[i].staIndex == staIdx)) + { + *assocId = i; + break; + } + + } + if(i==pDphHashTable->size) + return NULL; + return &pDphHashTable->pDphNodeArray[i]; + +} + + + + +/** ------------------------------------------------------------- +\fn dphInitStaState +\brief Initialize STA state. this function saves the staId from the current entry in the DPH table with given assocId +\ if validStaIdx flag is set. Otherwise it sets the staId to invalid. +\param tpAniSirGlobal pMac +\param tSirMacAddr staAddr +\param tANI_U16 assocId +\param tANI_U8 validStaIdx - true ==> the staId in the DPH entry with given assocId is valid and restore it back. +\ false ==> set the staId to invalid. +\return tpDphHashNode - DPH hash node if found. + -------------------------------------------------------------*/ + +tpDphHashNode dphInitStaState(tpAniSirGlobal pMac, tSirMacAddr staAddr, + tANI_U16 assocId, tANI_U8 validStaIdx, dphHashTableClass* pDphHashTable) +{ + tANI_U32 val; + + tpDphHashNode pStaDs; + tANI_U16 staIdx = HAL_STA_INVALID_IDX; + + if (assocId >= pDphHashTable->size) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid Assoc Id %d"), assocId);) + return NULL; + } + + pStaDs = getNode(pMac, (tANI_U8) assocId, pDphHashTable); + staIdx = pStaDs->staIndex; + + PELOG1(limLog(pMac, LOG1, FL("Assoc Id %d, Addr %08X"), assocId, pStaDs);) + + // Clear the STA node except for the next pointer (last 4 bytes) + vos_mem_set( (tANI_U8 *) pStaDs, sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0); + + // Initialize the assocId + pStaDs->assocId = assocId; + if(true == validStaIdx) + pStaDs->staIndex = staIdx; + else + pStaDs->staIndex = HAL_STA_INVALID_IDX; + + // Initialize STA mac address + vos_mem_copy( pStaDs->staAddr, staAddr, sizeof(tSirMacAddr)); + + // Initialize fragmentation threshold + if (wlan_cfgGetInt(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve fragmentation threshold")); + else + pStaDs->fragSize = (tANI_U16) val; + + pStaDs->added = 1; + pStaDs->encPolicy = HAL_ENC_POLICY_NULL; + +#ifdef WMM_APSD + pStaDs->stopQueue = 0; + pStaDs->spStatus = 0; + pStaDs->apsdMaxSpLen = 0; + pStaDs->acMode[0] = pStaDs->acMode[1] = pStaDs->acMode[2] = pStaDs->acMode[3] = 0; +#endif /* WMM_APSD */ + pStaDs->isDisassocDeauthInProgress = 0; +#ifdef WLAN_FEATURE_11W + pStaDs->last_assoc_received_time = 0; +#endif + pStaDs->sta_deletion_in_progress = false; + pStaDs->valid = 1; + return pStaDs; +} + +// --------------------------------------------------------------------- +/** + * dphAddHashEntry + * + * FUNCTION: + * Add entry to hash table + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @param staId Station ID assigned to the station + * @return Pointer to STA hash entry + */ + +tpDphHashNode dphAddHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 assocId, dphHashTableClass* pDphHashTable) +{ + tpDphHashNode ptr, node; + tANI_U16 index = hashFunction(pMac, staAddr, pDphHashTable->size); + + limLog(pMac, LOG1, FL("assocId %d index %d STA addr"), + assocId, index); + dphPrintMacAddr(pMac, staAddr, LOG1); + + if (assocId >= pDphHashTable->size) + { + PELOGE(limLog(pMac, LOGE, FL("invalid STA id %d"), assocId);) + return NULL; + } + + if (pDphHashTable->pDphNodeArray[assocId].added) + { + PELOGE(limLog(pMac, LOGE, FL("already added STA %d"), assocId);) + return NULL; + } + + for (ptr = pDphHashTable->pHashTable[index]; ptr; ptr = ptr->next) + { + if (ptr == ptr->next) + { + PELOGE(limLog(pMac, LOGE, FL("Infinite Loop"));) + return NULL; + } + + if (dphCompareMacAddr(staAddr, ptr->staAddr) || ptr->assocId== assocId) + break; + } + + if (ptr) + { + // Duplicate entry + limLog(pMac, LOGE, FL("assocId %d hashIndex %d entry exists"), + assocId, index); + return NULL; + } + else + { + if (dphInitStaState(pMac, staAddr, assocId, false, pDphHashTable) == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("could not Init STAid=%d"), assocId);) + return NULL; + } + + // Add the node to the link list + pDphHashTable->pDphNodeArray[assocId].next = pDphHashTable->pHashTable[index]; + pDphHashTable->pHashTable[index] = &pDphHashTable->pDphNodeArray[assocId]; + + node = pDphHashTable->pHashTable[index]; + return node; + } +} + +// --------------------------------------------------------------------- +/** + * dphDeleteHashEntry + * + * FUNCTION: + * Delete entry from hash table + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param staAddr MAC address of the station + * @param staId Station ID assigned to the station + * @return eSIR_SUCCESS if successful,\n + * eSIR_FAILURE otherwise + */ + +tSirRetStatus dphDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 assocId, dphHashTableClass* pDphHashTable) +{ + tpDphHashNode ptr, prev; + tANI_U16 index = hashFunction(pMac, staAddr, pDphHashTable->size); + + + limLog(pMac, LOG1, FL("assocId %d index %d STA addr"), + assocId, index); + dphPrintMacAddr(pMac, staAddr, LOG1); + + if (assocId >= pDphHashTable->size) + { + PELOGE(limLog(pMac, LOGE, FL("invalid STA id %d"), assocId);) + return eSIR_FAILURE; + } + + if (pDphHashTable->pDphNodeArray[assocId].added == 0) + { + PELOGE(limLog(pMac, LOGE, FL("STA %d never added"), assocId);) + return eSIR_FAILURE; + } + + + for (prev = 0, ptr = pDphHashTable->pHashTable[index]; + ptr; + prev = ptr, ptr = ptr->next) + { + if (dphCompareMacAddr(staAddr, ptr->staAddr)) + break; + if (prev == ptr) + { + PELOGE(limLog(pMac, LOGE, FL("Infinite Loop"));) + return eSIR_FAILURE; + } + } + + if (ptr) + { + /// Delete the entry after invalidating it + ptr->valid = 0; + memset(ptr->staAddr, 0, sizeof(ptr->staAddr)); + if (prev == 0) + pDphHashTable->pHashTable[index] = ptr->next; + else + prev->next = ptr->next; + ptr->added = 0; + ptr->isDisassocDeauthInProgress = 0; +#ifdef WLAN_FEATURE_11W + ptr->last_assoc_received_time = 0; +#endif + ptr->sta_deletion_in_progress = false; + ptr->next = 0; + } + else + { + /// Entry not present + PELOGE(limLog(pMac, LOGE, FL("Entry not present STA addr")); + dphPrintMacAddr(pMac, staAddr, LOGE);) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +// --------------------------------------------------------------------- +/** + * dphPrintMacAddr + * + * FUNCTION: + * Print a MAC address + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param addr MAC address + * @return None + */ + +void +dphPrintMacAddr(tpAniSirGlobal pMac, tANI_U8 addr[], tANI_U32 level) +{ + limLog(pMac, (tANI_U16) level, FL("MAC ADDR = %02x:%02x:%02x:%02x:%02x:%02x"), + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); +} + +// --------------------------------------------------------------------- diff --git a/drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.h b/drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.h new file mode 100644 index 000000000000..9e4b454c5587 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/dph/dphHashTable.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file dphHashTable.h contains the definition of the scheduler class. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __DPH_HASH_TABLE_H__ +#define __DPH_HASH_TABLE_H__ + +#include "aniGlobal.h" +/// Compare MAC addresses, return true if same +static inline tANI_U8 +dphCompareMacAddr(tANI_U8 addr1[], tANI_U8 addr2[]) +{ + return((addr1[0] == addr2[0]) && + (addr1[1] == addr2[1]) && + (addr1[2] == addr2[2]) && + (addr1[3] == addr2[3]) && + (addr1[4] == addr2[4]) && + (addr1[5] == addr2[5])); +} + +/// Hash table class +typedef struct +{ + + /// The hash table itself + tpDphHashNode *pHashTable; + + /// The state array + tDphHashNode *pDphNodeArray; + tANI_U16 size; +} dphHashTableClass; + +/// The hash table object +extern dphHashTableClass dphHashTable; + +/// Print MAC addresse +extern void dphPrintMacAddr(struct sAniSirGlobal *pMac, tANI_U8 addr[], tANI_U32); + +tpDphHashNode dphLookupHashEntry(tpAniSirGlobal pMac, tANI_U8 staAddr[], tANI_U16 *pStaId, dphHashTableClass* pDphHashTable); +tpDphHashNode dphLookupAssocId(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U16* assocId, dphHashTableClass* pDphHashTable); + + +/// Get a pointer to the hash node +extern tpDphHashNode dphGetHashEntry(tpAniSirGlobal pMac, tANI_U16 staId, dphHashTableClass* pDphHashTable); + +/// Add an entry to the hash table +extern tpDphHashNode dphAddHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId, dphHashTableClass* pDphHashTable); + +/// Delete an entry from the hash table +extern tSirRetStatus dphDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId, dphHashTableClass* pDphHashTable); + +void dphHashTableClassInit(tpAniSirGlobal pMac, dphHashTableClass* pDphHashTable); +/// Initialize STA state +extern tpDphHashNode dphInitStaState(tpAniSirGlobal pMac, tSirMacAddr staAddr, + tANI_U16 staId, tANI_U8 validStaIdx, dphHashTableClass* pDphHashTable); + + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/include/cfgApi.h b/drivers/staging/prima/CORE/MAC/src/include/cfgApi.h new file mode 100644 index 000000000000..8d1e84d9a1d5 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/cfgApi.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Kevin Nguyen + * Date: 04/09/02 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGAPI_H +#define __CFGAPI_H + +#include +#include +#include +#include +#include + + +/*---------------------------------------------------------------------*/ +/* CFG definitions */ +/*---------------------------------------------------------------------*/ +#define CFG_TYPE_STR 0x0000000 +#define CFG_TYPE_INT 0x0000001 +#define CFG_HOST_RE 0x0000002 +#define CFG_HOST_WE 0x0000004 + +// CFG status +typedef enum eCfgStatusTypes { + CFG_INCOMPLETE, + CFG_SUCCESS, + CFG_FAILURE +} tCfgStatusTypes; + +// WEP key mapping table row structure +typedef struct +{ + tANI_U8 keyMappingAddr[SIR_MAC_ADDR_LENGTH]; + tANI_U32 wepOn; + tANI_U8 key[SIR_MAC_KEY_LENGTH]; + tANI_U32 status; +} tCfgWepKeyEntry; + + +/*---------------------------------------------------------------------*/ +/* CFG function prototypes */ +/*---------------------------------------------------------------------*/ + +tANI_U32 cfgNeedRestart(tpAniSirGlobal pMac, tANI_U16 cfgId) ; +tANI_U32 cfgNeedReload(tpAniSirGlobal pMac, tANI_U16 cfgId) ; + +/// CFG initialization function +void wlan_cfgInit(tpAniSirGlobal); + +/// Process host message +void cfgProcessMbMsg(tpAniSirGlobal, tSirMbMsg*); + +/// Set integer parameter value +tSirRetStatus cfgSetInt(tpAniSirGlobal, tANI_U16, tANI_U32); + +/// Check if the parameter is valid +tSirRetStatus cfgCheckValid(tpAniSirGlobal, tANI_U16); + +/// Get integer parameter value +tSirRetStatus wlan_cfgGetInt(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Increment integer parameter +tSirRetStatus cfgIncrementInt(tpAniSirGlobal, tANI_U16, tANI_U32); + +/// Set string parameter value +tSirRetStatus cfgSetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32); + +tSirRetStatus cfgSetStrNotify(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32, int); + +//Cfg Download function for Prima or Integrated solutions. +void processCfgDownloadReq(tpAniSirGlobal); + +/// Get string parameter value +tSirRetStatus wlan_cfgGetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32*); + +/// Get string parameter maximum length +tSirRetStatus wlan_cfgGetStrMaxLen(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Get string parameter maximum length +tSirRetStatus wlan_cfgGetStrLen(tpAniSirGlobal, tANI_U16, tANI_U32*); + +/// Get the regulatory tx power on given channel +tPowerdBm cfgGetRegulatoryMaxTransmitPower(tpAniSirGlobal pMac, tANI_U8 channel); + +/// Dump CFG data to memory +void cfgDump(tANI_U32*); + +/// Save parameters with P flag set +void cfgSave(void); + +/// Get capability info +extern tSirRetStatus cfgGetCapabilityInfo(tpAniSirGlobal pMac, tANI_U16 *pCap,tpPESession psessionEntry); + +/// Set capability info +extern void cfgSetCapabilityInfo(tpAniSirGlobal, tANI_U16); + +/// Cleanup CFG module +void cfgCleanup(tpAniSirGlobal pMac); + +extern tANI_U8 *gCfgParamName[]; + +#endif /* __CFGAPI_H */ + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/include/cfgGlobal.h b/drivers/staging/prima/CORE/MAC/src/include/cfgGlobal.h new file mode 100644 index 000000000000..742c50fe9d55 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/cfgGlobal.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/09/03 + * History:- + * 04/09/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __CFGGLOBAL_H +#define __CFGGLOBAL_H + +#include "sirCommon.h" +#include "sirTypes.h" +#include "wniCfg.h" + +#define CFG_MAX_NUM_STA SIR_MAX_NUM_STA_IN_IBSS + +#define CFG_MAX_STATIC_STRING 70 +#define CFG_MAX_STR_LEN 256 // as the number of channels grows, 128 is not big enough + +/*--------------------------------------------------------------------*/ +/* Configuration Control Structure */ +/*--------------------------------------------------------------------*/ +typedef struct +{ + tANI_U32 control; +} tCfgCtl; + +typedef struct sAniSirCfgStaticString +{ + tANI_U16 cfgId; + tANI_U8 maxLen; + tANI_U8 length; + tANI_U8 data[255]; +}tAniSirCfgStaticString; + +typedef struct sAniSirCfgStatic +{ + tANI_U16 cfgId; + tANI_U32 control; + tANI_U32 cfgIMin; + tANI_U32 cfgIMax; + tANI_U32 cfgIVal; + void *pStrData; +}tAniSirCgStatic; + +typedef struct sAniSirCfg +{ + // CFG module status + tANI_U8 gCfgStatus; + + tCfgCtl *gCfgEntry; + tANI_U32 *gCfgIBufMin; + tANI_U32 *gCfgIBufMax; + tANI_U32 *gCfgIBuf; + tANI_U8 *gCfgSBuf; + + tANI_U16 gCfgMaxIBufSize; + tANI_U16 gCfgMaxSBufSize; + + // Static buffer for string parameter (must be word-aligned) + tANI_U8 *gSBuffer; +} tAniSirCfg, *tpAniSirCfg; + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/include/dot11f.h b/drivers/staging/prima/CORE/MAC/src/include/dot11f.h new file mode 100644 index 000000000000..585d2b3151e0 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/dot11f.h @@ -0,0 +1,7938 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef DOT11F_H +#define DOT11F_H +/** + * \file dot11f.h + * + * \brief Structures, function prototypes & definitions + * for working with 802.11 Frames + * + * + * + * This file was automatically generated by 'framesc' + * Wed Jul 12 16:02:49 2017 from the following file(s): + * + * dot11f.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * Instead, please update the input files & re-run + * 'framesc' For more information on 'framesc' & the + * frames language, run 'framesc --help'. + * + * + */ + +typedef tANI_U32 tDOT11F_U64[2]; + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4214) /* nonstandard extension used */ +#endif /* Microsoft C/C++ bit field types other than int */ + +/* + * Frames Return Codes: + * + * Success is indicated by a return value of zero. Failure is indicated + * by the presence of the high bit. Warnings encountered in the course + * of a successful parse are indicated by various bits in the lower 31 + * being turned on. + * + * For instance, a return value of 0x0000000a would indicate that the + * parse succeeded, but that a mandatory IE wasn't present, and some IE + * was found to be corrupt. + * + * + */ + +#define DOT11F_PARSE_SUCCESS ( 0x00000000 ) +#define DOT11F_UNKNOWN_IES ( 0x00000001 ) +#define DOT11F_MANDATORY_IE_MISSING ( 0x00000002 ) +#define DOT11F_INCOMPLETE_IE ( 0x00000004 ) +#define DOT11F_SKIPPED_BAD_IE ( 0x00000008 ) +#define DOT11F_LAST_IE_TOO_LONG ( 0x00000010 ) +#define DOT11F_DUPLICATE_IE ( 0x00000020 ) +#define DOT11F_BAD_FIXED_VALUE ( 0x00000040 ) +#define DOT11F_INCOMPLETE_TLV ( 0x00000080 ) +#define DOT11F_INVALID_TLV_LENGTH ( 0x00000100 ) +#define DOT11F_SKIPPED_BAD_TLV ( 0x00000200 ) +#define DOT11F_UNKNOWN_TLVS ( 0x00000400 ) +#define DOT11F_LAST_TLV_TOO_LONG ( 0x00000800 ) +#define DOT11F_INTERNAL_ERROR ( 0x10000001 ) +#define DOT11F_MISSING_FIXED_FIELD ( 0x10000002 ) +#define DOT11F_BAD_INPUT_BUFFER ( 0x10000003 ) +#define DOT11F_BAD_OUTPUT_BUFFER ( 0x10000004 ) +#define DOT11F_BUFFER_OVERFLOW ( 0x10000005 ) +#define DOT11F_MANDATORY_TLV_MISSING ( 0x00001000 ) +#define DOT11F_FAILED(code) ( (code) & 0x10000000 ) +#define DOT11F_SUCCEEDED(code) ( (code) == 0 ) +#define DOT11F_WARNED(code) (!DOT11F_SUCCEEDED(code) && !DOT11F_FAILED(code)) + +/********************************************************************* + * Fixed Fields * + ********************************************************************/ + +typedef struct sDot11fFfAID { + tANI_U16 associd; +} tDot11fFfAID; + +#define DOT11F_FF_AID_LEN ( 2 ) + +void dot11fUnpackFfAID(tpAniSirGlobal, tANI_U8*, tDot11fFfAID*); + +void dot11fPackFfAID(tpAniSirGlobal, tDot11fFfAID*, tANI_U8*); + +typedef struct sDot11fFfAction { + tANI_U8 action; +} tDot11fFfAction; + +#define DOT11F_FF_ACTION_LEN ( 1 ) + +void dot11fUnpackFfAction(tpAniSirGlobal, tANI_U8*, tDot11fFfAction*); + +void dot11fPackFfAction(tpAniSirGlobal, tDot11fFfAction*, tANI_U8*); + +typedef struct sDot11fFfAddBAParameterSet { + tANI_U16 amsduSupported: 1; + tANI_U16 policy: 1; + tANI_U16 tid: 4; + tANI_U16 bufferSize: 10; +} tDot11fFfAddBAParameterSet; + +#define DOT11F_FF_ADDBAPARAMETERSET_LEN ( 2 ) + +void dot11fUnpackFfAddBAParameterSet(tpAniSirGlobal, tANI_U8*, tDot11fFfAddBAParameterSet*); + +void dot11fPackFfAddBAParameterSet(tpAniSirGlobal, tDot11fFfAddBAParameterSet*, tANI_U8*); + +#define ADDBAPARAMETERSET_AMSDUSUPPORTED_OFFSET 0 +#define ADDBAPARAMETERSET_AMSDUSUPPORTED_WIDTH 1 +#define ADDBAPARAMETERSET_POLICY_OFFSET 1 +#define ADDBAPARAMETERSET_POLICY_WIDTH 1 +#define ADDBAPARAMETERSET_TID_OFFSET 2 +#define ADDBAPARAMETERSET_TID_WIDTH 4 +#define ADDBAPARAMETERSET_BUFFERSIZE_OFFSET 6 +#define ADDBAPARAMETERSET_BUFFERSIZE_WIDTH 10 + +typedef struct sDot11fFfAuthAlgo { + tANI_U16 algo; +} tDot11fFfAuthAlgo; + +#define DOT11F_FF_AUTHALGO_LEN ( 2 ) + +void dot11fUnpackFfAuthAlgo(tpAniSirGlobal, tANI_U8*, tDot11fFfAuthAlgo*); + +void dot11fPackFfAuthAlgo(tpAniSirGlobal, tDot11fFfAuthAlgo*, tANI_U8*); + +typedef struct sDot11fFfAuthSeqNo { + tANI_U16 no; +} tDot11fFfAuthSeqNo; + +#define DOT11F_FF_AUTHSEQNO_LEN ( 2 ) + +void dot11fUnpackFfAuthSeqNo(tpAniSirGlobal, tANI_U8*, tDot11fFfAuthSeqNo*); + +void dot11fPackFfAuthSeqNo(tpAniSirGlobal, tDot11fFfAuthSeqNo*, tANI_U8*); + +typedef struct sDot11fFfBAStartingSequenceControl { + tANI_U16 fragNumber: 4; + tANI_U16 ssn: 12; +} tDot11fFfBAStartingSequenceControl; + +#define DOT11F_FF_BASTARTINGSEQUENCECONTROL_LEN ( 2 ) + +void dot11fUnpackFfBAStartingSequenceControl(tpAniSirGlobal, tANI_U8*, tDot11fFfBAStartingSequenceControl*); + +void dot11fPackFfBAStartingSequenceControl(tpAniSirGlobal, tDot11fFfBAStartingSequenceControl*, tANI_U8*); + +#define BASTARTINGSEQUENCECONTROL_FRAGNUMBER_OFFSET 0 +#define BASTARTINGSEQUENCECONTROL_FRAGNUMBER_WIDTH 4 +#define BASTARTINGSEQUENCECONTROL_SSN_OFFSET 4 +#define BASTARTINGSEQUENCECONTROL_SSN_WIDTH 12 + +typedef struct sDot11fFfBATimeout { + tANI_U16 timeout; +} tDot11fFfBATimeout; + +#define DOT11F_FF_BATIMEOUT_LEN ( 2 ) + +void dot11fUnpackFfBATimeout(tpAniSirGlobal, tANI_U8*, tDot11fFfBATimeout*); + +void dot11fPackFfBATimeout(tpAniSirGlobal, tDot11fFfBATimeout*, tANI_U8*); + +typedef struct sDot11fFfBeaconInterval { + tANI_U16 interval; +} tDot11fFfBeaconInterval; + +#define DOT11F_FF_BEACONINTERVAL_LEN ( 2 ) + +void dot11fUnpackFfBeaconInterval(tpAniSirGlobal, tANI_U8*, tDot11fFfBeaconInterval*); + +void dot11fPackFfBeaconInterval(tpAniSirGlobal, tDot11fFfBeaconInterval*, tANI_U8*); + +typedef struct sDot11fFfCapabilities { + tANI_U16 ess: 1; + tANI_U16 ibss: 1; + tANI_U16 cfPollable: 1; + tANI_U16 cfPollReq: 1; + tANI_U16 privacy: 1; + tANI_U16 shortPreamble: 1; + tANI_U16 pbcc: 1; + tANI_U16 channelAgility: 1; + tANI_U16 spectrumMgt: 1; + tANI_U16 qos: 1; + tANI_U16 shortSlotTime: 1; + tANI_U16 apsd: 1; + tANI_U16 rrm: 1; + tANI_U16 dsssOfdm: 1; + tANI_U16 delayedBA: 1; + tANI_U16 immediateBA: 1; +} tDot11fFfCapabilities; + +#define DOT11F_FF_CAPABILITIES_LEN ( 2 ) + +void dot11fUnpackFfCapabilities(tpAniSirGlobal, tANI_U8*, tDot11fFfCapabilities*); + +void dot11fPackFfCapabilities(tpAniSirGlobal, tDot11fFfCapabilities*, tANI_U8*); + +#define CAPABILITIES_ESS_OFFSET 0 +#define CAPABILITIES_ESS_WIDTH 1 +#define CAPABILITIES_IBSS_OFFSET 1 +#define CAPABILITIES_IBSS_WIDTH 1 +#define CAPABILITIES_CFPOLLABLE_OFFSET 2 +#define CAPABILITIES_CFPOLLABLE_WIDTH 1 +#define CAPABILITIES_CFPOLLREQ_OFFSET 3 +#define CAPABILITIES_CFPOLLREQ_WIDTH 1 +#define CAPABILITIES_PRIVACY_OFFSET 4 +#define CAPABILITIES_PRIVACY_WIDTH 1 +#define CAPABILITIES_SHORTPREAMBLE_OFFSET 5 +#define CAPABILITIES_SHORTPREAMBLE_WIDTH 1 +#define CAPABILITIES_PBCC_OFFSET 6 +#define CAPABILITIES_PBCC_WIDTH 1 +#define CAPABILITIES_CHANNELAGILITY_OFFSET 7 +#define CAPABILITIES_CHANNELAGILITY_WIDTH 1 +#define CAPABILITIES_SPECTRUMMGT_OFFSET 8 +#define CAPABILITIES_SPECTRUMMGT_WIDTH 1 +#define CAPABILITIES_QOS_OFFSET 9 +#define CAPABILITIES_QOS_WIDTH 1 +#define CAPABILITIES_SHORTSLOTTIME_OFFSET 10 +#define CAPABILITIES_SHORTSLOTTIME_WIDTH 1 +#define CAPABILITIES_APSD_OFFSET 11 +#define CAPABILITIES_APSD_WIDTH 1 +#define CAPABILITIES_RRM_OFFSET 12 +#define CAPABILITIES_RRM_WIDTH 1 +#define CAPABILITIES_DSSSOFDM_OFFSET 13 +#define CAPABILITIES_DSSSOFDM_WIDTH 1 +#define CAPABILITIES_DELAYEDBA_OFFSET 14 +#define CAPABILITIES_DELAYEDBA_WIDTH 1 +#define CAPABILITIES_IMMEDIATEBA_OFFSET 15 +#define CAPABILITIES_IMMEDIATEBA_WIDTH 1 + +typedef struct sDot11fFfCategory { + tANI_U8 category; +} tDot11fFfCategory; + +#define DOT11F_FF_CATEGORY_LEN ( 1 ) + +void dot11fUnpackFfCategory(tpAniSirGlobal, tANI_U8*, tDot11fFfCategory*); + +void dot11fPackFfCategory(tpAniSirGlobal, tDot11fFfCategory*, tANI_U8*); + +typedef struct sDot11fFfCurrentAPAddress { + tANI_U8 mac[6]; +} tDot11fFfCurrentAPAddress; + +#define DOT11F_FF_CURRENTAPADDRESS_LEN ( 6 ) + +void dot11fUnpackFfCurrentAPAddress(tpAniSirGlobal, tANI_U8*, tDot11fFfCurrentAPAddress*); + +void dot11fPackFfCurrentAPAddress(tpAniSirGlobal, tDot11fFfCurrentAPAddress*, tANI_U8*); + +typedef struct sDot11fFfDelBAParameterSet { + tANI_U16 reserved: 11; + tANI_U16 initiator: 1; + tANI_U16 tid: 4; +} tDot11fFfDelBAParameterSet; + +#define DOT11F_FF_DELBAPARAMETERSET_LEN ( 2 ) + +void dot11fUnpackFfDelBAParameterSet(tpAniSirGlobal, tANI_U8*, tDot11fFfDelBAParameterSet*); + +void dot11fPackFfDelBAParameterSet(tpAniSirGlobal, tDot11fFfDelBAParameterSet*, tANI_U8*); + +#define DELBAPARAMETERSET_RESERVED_OFFSET 0 +#define DELBAPARAMETERSET_RESERVED_WIDTH 11 +#define DELBAPARAMETERSET_INITIATOR_OFFSET 11 +#define DELBAPARAMETERSET_INITIATOR_WIDTH 1 +#define DELBAPARAMETERSET_TID_OFFSET 12 +#define DELBAPARAMETERSET_TID_WIDTH 4 + +typedef struct sDot11fFfDialogToken { + tANI_U8 token; +} tDot11fFfDialogToken; + +#define DOT11F_FF_DIALOGTOKEN_LEN ( 1 ) + +void dot11fUnpackFfDialogToken(tpAniSirGlobal, tANI_U8*, tDot11fFfDialogToken*); + +void dot11fPackFfDialogToken(tpAniSirGlobal, tDot11fFfDialogToken*, tANI_U8*); + +typedef struct sDot11fFfLinkMargin { + tANI_U8 linkMargin; +} tDot11fFfLinkMargin; + +#define DOT11F_FF_LINKMARGIN_LEN ( 1 ) + +void dot11fUnpackFfLinkMargin(tpAniSirGlobal, tANI_U8*, tDot11fFfLinkMargin*); + +void dot11fPackFfLinkMargin(tpAniSirGlobal, tDot11fFfLinkMargin*, tANI_U8*); + +typedef struct sDot11fFfListenInterval { + tANI_U16 interval; +} tDot11fFfListenInterval; + +#define DOT11F_FF_LISTENINTERVAL_LEN ( 2 ) + +void dot11fUnpackFfListenInterval(tpAniSirGlobal, tANI_U8*, tDot11fFfListenInterval*); + +void dot11fPackFfListenInterval(tpAniSirGlobal, tDot11fFfListenInterval*, tANI_U8*); + +typedef struct sDot11fFfMagicCode { + tANI_U8 magic[6]; +} tDot11fFfMagicCode; + +#define DOT11F_FF_MAGICCODE_LEN ( 6 ) + +void dot11fUnpackFfMagicCode(tpAniSirGlobal, tANI_U8*, tDot11fFfMagicCode*); + +void dot11fPackFfMagicCode(tpAniSirGlobal, tDot11fFfMagicCode*, tANI_U8*); + +typedef struct sDot11fFfMaxTxPower { + tANI_U8 maxTxPower; +} tDot11fFfMaxTxPower; + +#define DOT11F_FF_MAXTXPOWER_LEN ( 1 ) + +void dot11fUnpackFfMaxTxPower(tpAniSirGlobal, tANI_U8*, tDot11fFfMaxTxPower*); + +void dot11fPackFfMaxTxPower(tpAniSirGlobal, tDot11fFfMaxTxPower*, tANI_U8*); + +typedef struct sDot11fFfNumOfRepetitions { + tANI_U16 repetitions; +} tDot11fFfNumOfRepetitions; + +#define DOT11F_FF_NUMOFREPETITIONS_LEN ( 2 ) + +void dot11fUnpackFfNumOfRepetitions(tpAniSirGlobal, tANI_U8*, tDot11fFfNumOfRepetitions*); + +void dot11fPackFfNumOfRepetitions(tpAniSirGlobal, tDot11fFfNumOfRepetitions*, tANI_U8*); + +typedef struct sDot11fFfOperatingMode { + tANI_U8 chanWidth: 2; + tANI_U8 reserved: 2; + tANI_U8 rxNSS: 3; + tANI_U8 rxNSSType: 1; +} tDot11fFfOperatingMode; + +#define DOT11F_FF_OPERATINGMODE_LEN ( 1 ) + +void dot11fUnpackFfOperatingMode(tpAniSirGlobal, tANI_U8*, tDot11fFfOperatingMode*); + +void dot11fPackFfOperatingMode(tpAniSirGlobal, tDot11fFfOperatingMode*, tANI_U8*); + +#define OPERATINGMODE_CHANWIDTH_OFFSET 0 +#define OPERATINGMODE_CHANWIDTH_WIDTH 2 +#define OPERATINGMODE_RESERVED_OFFSET 2 +#define OPERATINGMODE_RESERVED_WIDTH 2 +#define OPERATINGMODE_RXNSS_OFFSET 4 +#define OPERATINGMODE_RXNSS_WIDTH 3 +#define OPERATINGMODE_RXNSSTYPE_OFFSET 7 +#define OPERATINGMODE_RXNSSTYPE_WIDTH 1 + +typedef struct sDot11fFfP2POUI { + tANI_U32 oui; +} tDot11fFfP2POUI; + +#define DOT11F_FF_P2POUI_LEN ( 4 ) + +void dot11fUnpackFfP2POUI(tpAniSirGlobal, tANI_U8*, tDot11fFfP2POUI*); + +void dot11fPackFfP2POUI(tpAniSirGlobal, tDot11fFfP2POUI*, tANI_U8*); + +typedef struct sDot11fFfP2POUISubType { + tANI_U8 ouiSubtype; +} tDot11fFfP2POUISubType; + +#define DOT11F_FF_P2POUISUBTYPE_LEN ( 1 ) + +void dot11fUnpackFfP2POUISubType(tpAniSirGlobal, tANI_U8*, tDot11fFfP2POUISubType*); + +void dot11fPackFfP2POUISubType(tpAniSirGlobal, tDot11fFfP2POUISubType*, tANI_U8*); + +typedef struct sDot11fFfRCPI { + tANI_U8 rcpi; +} tDot11fFfRCPI; + +#define DOT11F_FF_RCPI_LEN ( 1 ) + +void dot11fUnpackFfRCPI(tpAniSirGlobal, tANI_U8*, tDot11fFfRCPI*); + +void dot11fPackFfRCPI(tpAniSirGlobal, tDot11fFfRCPI*, tANI_U8*); + +typedef struct sDot11fFfRMCDialogToken { + tANI_U32 token; +} tDot11fFfRMCDialogToken; + +#define DOT11F_FF_RMCDIALOGTOKEN_LEN ( 4 ) + +void dot11fUnpackFfRMCDialogToken(tpAniSirGlobal, tANI_U8*, tDot11fFfRMCDialogToken*); + +void dot11fPackFfRMCDialogToken(tpAniSirGlobal, tDot11fFfRMCDialogToken*, tANI_U8*); + +typedef struct sDot11fFfRMCOUI { + tANI_U8 oui[3]; +} tDot11fFfRMCOUI; + +#define DOT11F_FF_RMCOUI_LEN ( 3 ) + +void dot11fUnpackFfRMCOUI(tpAniSirGlobal, tANI_U8*, tDot11fFfRMCOUI*); + +void dot11fPackFfRMCOUI(tpAniSirGlobal, tDot11fFfRMCOUI*, tANI_U8*); + +typedef struct sDot11fFfRMCVersion { + tANI_U8 version; +} tDot11fFfRMCVersion; + +#define DOT11F_FF_RMCVERSION_LEN ( 1 ) + +void dot11fUnpackFfRMCVersion(tpAniSirGlobal, tANI_U8*, tDot11fFfRMCVersion*); + +void dot11fPackFfRMCVersion(tpAniSirGlobal, tDot11fFfRMCVersion*, tANI_U8*); + +typedef struct sDot11fFfRSNI { + tANI_U8 rsni; +} tDot11fFfRSNI; + +#define DOT11F_FF_RSNI_LEN ( 1 ) + +void dot11fUnpackFfRSNI(tpAniSirGlobal, tANI_U8*, tDot11fFfRSNI*); + +void dot11fPackFfRSNI(tpAniSirGlobal, tDot11fFfRSNI*, tANI_U8*); + +typedef struct sDot11fFfReason { + tANI_U16 code; +} tDot11fFfReason; + +#define DOT11F_FF_REASON_LEN ( 2 ) + +void dot11fUnpackFfReason(tpAniSirGlobal, tANI_U8*, tDot11fFfReason*); + +void dot11fPackFfReason(tpAniSirGlobal, tDot11fFfReason*, tANI_U8*); + +typedef struct sDot11fFfRuler { + tANI_U8 mac[6]; +} tDot11fFfRuler; + +#define DOT11F_FF_RULER_LEN ( 6 ) + +void dot11fUnpackFfRuler(tpAniSirGlobal, tANI_U8*, tDot11fFfRuler*); + +void dot11fPackFfRuler(tpAniSirGlobal, tDot11fFfRuler*, tANI_U8*); + +typedef struct sDot11fFfRxAntennaId { + tANI_U8 antennaId; +} tDot11fFfRxAntennaId; + +#define DOT11F_FF_RXANTENNAID_LEN ( 1 ) + +void dot11fUnpackFfRxAntennaId(tpAniSirGlobal, tANI_U8*, tDot11fFfRxAntennaId*); + +void dot11fPackFfRxAntennaId(tpAniSirGlobal, tDot11fFfRxAntennaId*, tANI_U8*); + +typedef struct sDot11fFfSMPowerModeSet { + tANI_U8 PowerSave_En: 1; + tANI_U8 Mode: 1; + tANI_U8 reserved: 6; +} tDot11fFfSMPowerModeSet; + +#define DOT11F_FF_SMPOWERMODESET_LEN ( 1 ) + +void dot11fUnpackFfSMPowerModeSet(tpAniSirGlobal, tANI_U8*, tDot11fFfSMPowerModeSet*); + +void dot11fPackFfSMPowerModeSet(tpAniSirGlobal, tDot11fFfSMPowerModeSet*, tANI_U8*); + +#define SMPOWERMODESET_POWERSAVE_EN_OFFSET 0 +#define SMPOWERMODESET_POWERSAVE_EN_WIDTH 1 +#define SMPOWERMODESET_MODE_OFFSET 1 +#define SMPOWERMODESET_MODE_WIDTH 1 +#define SMPOWERMODESET_RESERVED_OFFSET 2 +#define SMPOWERMODESET_RESERVED_WIDTH 6 + +typedef struct sDot11fFfStatus { + tANI_U16 status; +} tDot11fFfStatus; + +#define DOT11F_FF_STATUS_LEN ( 2 ) + +void dot11fUnpackFfStatus(tpAniSirGlobal, tANI_U8*, tDot11fFfStatus*); + +void dot11fPackFfStatus(tpAniSirGlobal, tDot11fFfStatus*, tANI_U8*); + +typedef struct sDot11fFfStatusCode { + tANI_U8 statusCode; +} tDot11fFfStatusCode; + +#define DOT11F_FF_STATUSCODE_LEN ( 1 ) + +void dot11fUnpackFfStatusCode(tpAniSirGlobal, tANI_U8*, tDot11fFfStatusCode*); + +void dot11fPackFfStatusCode(tpAniSirGlobal, tDot11fFfStatusCode*, tANI_U8*); + +typedef struct sDot11fFfTPCEleID { + tANI_U8 TPCId; +} tDot11fFfTPCEleID; + +#define DOT11F_FF_TPCELEID_LEN ( 1 ) + +void dot11fUnpackFfTPCEleID(tpAniSirGlobal, tANI_U8*, tDot11fFfTPCEleID*); + +void dot11fPackFfTPCEleID(tpAniSirGlobal, tDot11fFfTPCEleID*, tANI_U8*); + +typedef struct sDot11fFfTPCEleLen { + tANI_U8 TPCLen; +} tDot11fFfTPCEleLen; + +#define DOT11F_FF_TPCELELEN_LEN ( 1 ) + +void dot11fUnpackFfTPCEleLen(tpAniSirGlobal, tANI_U8*, tDot11fFfTPCEleLen*); + +void dot11fPackFfTPCEleLen(tpAniSirGlobal, tDot11fFfTPCEleLen*, tANI_U8*); + +typedef struct sDot11fFfTSInfo { + tANI_U32 traffic_type: 1; + tANI_U32 tsid: 4; + tANI_U32 direction: 2; + tANI_U32 access_policy: 2; + tANI_U32 aggregation: 1; + tANI_U32 psb: 1; + tANI_U32 user_priority: 3; + tANI_U32 tsinfo_ack_pol: 2; + tANI_U32 schedule: 1; + tANI_U32 unused: 15; +} tDot11fFfTSInfo; + +#define DOT11F_FF_TSINFO_LEN ( 3 ) + +void dot11fUnpackFfTSInfo(tpAniSirGlobal, tANI_U8*, tDot11fFfTSInfo*); + +void dot11fPackFfTSInfo(tpAniSirGlobal, tDot11fFfTSInfo*, tANI_U8*); + +#define TSINFO_TRAFFIC_TYPE_OFFSET 0 +#define TSINFO_TRAFFIC_TYPE_WIDTH 1 +#define TSINFO_TSID_OFFSET 1 +#define TSINFO_TSID_WIDTH 4 +#define TSINFO_DIRECTION_OFFSET 5 +#define TSINFO_DIRECTION_WIDTH 2 +#define TSINFO_ACCESS_POLICY_OFFSET 7 +#define TSINFO_ACCESS_POLICY_WIDTH 2 +#define TSINFO_AGGREGATION_OFFSET 9 +#define TSINFO_AGGREGATION_WIDTH 1 +#define TSINFO_PSB_OFFSET 10 +#define TSINFO_PSB_WIDTH 1 +#define TSINFO_USER_PRIORITY_OFFSET 11 +#define TSINFO_USER_PRIORITY_WIDTH 3 +#define TSINFO_TSINFO_ACK_POL_OFFSET 14 +#define TSINFO_TSINFO_ACK_POL_WIDTH 2 +#define TSINFO_SCHEDULE_OFFSET 16 +#define TSINFO_SCHEDULE_WIDTH 1 +#define TSINFO_UNUSED_OFFSET 17 +#define TSINFO_UNUSED_WIDTH 15 + +typedef struct sDot11fFfTimeStamp { + tDOT11F_U64 timestamp; +} tDot11fFfTimeStamp; + +#define DOT11F_FF_TIMESTAMP_LEN ( 8 ) + +void dot11fUnpackFfTimeStamp(tpAniSirGlobal, tANI_U8*, tDot11fFfTimeStamp*); + +void dot11fPackFfTimeStamp(tpAniSirGlobal, tDot11fFfTimeStamp*, tANI_U8*); + +typedef struct sDot11fFfTransactionId { + tANI_U8 transId[2]; +} tDot11fFfTransactionId; + +#define DOT11F_FF_TRANSACTIONID_LEN ( 2 ) + +void dot11fUnpackFfTransactionId(tpAniSirGlobal, tANI_U8*, tDot11fFfTransactionId*); + +void dot11fPackFfTransactionId(tpAniSirGlobal, tDot11fFfTransactionId*, tANI_U8*); + +typedef struct sDot11fFfTxAntennaId { + tANI_U8 antennaId; +} tDot11fFfTxAntennaId; + +#define DOT11F_FF_TXANTENNAID_LEN ( 1 ) + +void dot11fUnpackFfTxAntennaId(tpAniSirGlobal, tANI_U8*, tDot11fFfTxAntennaId*); + +void dot11fPackFfTxAntennaId(tpAniSirGlobal, tDot11fFfTxAntennaId*, tANI_U8*); + +typedef struct sDot11fFfTxPower { + tANI_U8 txPower; +} tDot11fFfTxPower; + +#define DOT11F_FF_TXPOWER_LEN ( 1 ) + +void dot11fUnpackFfTxPower(tpAniSirGlobal, tANI_U8*, tDot11fFfTxPower*); + +void dot11fPackFfTxPower(tpAniSirGlobal, tDot11fFfTxPower*, tANI_U8*); + +typedef struct sDot11fFfVhtMembershipStatusArray { + tANI_U8 membershipStatusArray[8]; +} tDot11fFfVhtMembershipStatusArray; + +#define DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN ( 8 ) + +void dot11fUnpackFfVhtMembershipStatusArray(tpAniSirGlobal, tANI_U8*, tDot11fFfVhtMembershipStatusArray*); + +void dot11fPackFfVhtMembershipStatusArray(tpAniSirGlobal, tDot11fFfVhtMembershipStatusArray*, tANI_U8*); + +typedef struct sDot11fFfVhtUserPositionArray { + tANI_U8 userPositionArray[16]; +} tDot11fFfVhtUserPositionArray; + +#define DOT11F_FF_VHTUSERPOSITIONARRAY_LEN ( 16 ) + +void dot11fUnpackFfVhtUserPositionArray(tpAniSirGlobal, tANI_U8*, tDot11fFfVhtUserPositionArray*); + +void dot11fPackFfVhtUserPositionArray(tpAniSirGlobal, tDot11fFfVhtUserPositionArray*, tANI_U8*); + +/********************************************************************* + * TLVs * + ********************************************************************/ + +// ID 1 (0x0001) +typedef struct sDot11fTLVAuthorizedMACs { + tANI_U8 present; + tANI_U8 mac[6]; +} tDot11fTLVAuthorizedMACs; + +#define DOT11F_TLV_AUTHORIZEDMACS ( 1 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_AUTHORIZEDMACS_MIN_LEN ( 6 ) + +#define DOT11F_TLV_AUTHORIZEDMACS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvAuthorizedMACs(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVAuthorizedMACs*); + +tANI_U32 dot11fPackTlvAuthorizedMACs(tpAniSirGlobal, tDot11fTLVAuthorizedMACs*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvAuthorizedMACs(tpAniSirGlobal, tDot11fTLVAuthorizedMACs*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3 (0x0003) +typedef struct sDot11fTLVRequestToEnroll { + tANI_U8 present; + tANI_U8 req; +} tDot11fTLVRequestToEnroll; + +#define DOT11F_TLV_REQUESTTOENROLL ( 3 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_REQUESTTOENROLL_MIN_LEN ( 1 ) + +#define DOT11F_TLV_REQUESTTOENROLL_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRequestToEnroll(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRequestToEnroll*); + +tANI_U32 dot11fPackTlvRequestToEnroll(tpAniSirGlobal, tDot11fTLVRequestToEnroll*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRequestToEnroll(tpAniSirGlobal, tDot11fTLVRequestToEnroll*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 0 (0x0000) +typedef struct sDot11fTLVVersion2 { + tANI_U8 present; + tANI_U8 minor: 4; + tANI_U8 major: 4; +} tDot11fTLVVersion2; + +#define DOT11F_TLV_VERSION2 ( 0 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_VERSION2_MIN_LEN ( 1 ) + +#define DOT11F_TLV_VERSION2_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvVersion2(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVVersion2*); + +tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal, tDot11fTLVVersion2*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvVersion2(tpAniSirGlobal, tDot11fTLVVersion2*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4183 (0x1057) +typedef struct sDot11fTLVAPSetupLocked { + tANI_U8 present; + tANI_U8 fLocked; +} tDot11fTLVAPSetupLocked; + +#define DOT11F_TLV_APSETUPLOCKED ( 4183 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_APSETUPLOCKED_MIN_LEN ( 3 ) + +#define DOT11F_TLV_APSETUPLOCKED_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvAPSetupLocked(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVAPSetupLocked*); + +tANI_U32 dot11fPackTlvAPSetupLocked(tpAniSirGlobal, tDot11fTLVAPSetupLocked*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvAPSetupLocked(tpAniSirGlobal, tDot11fTLVAPSetupLocked*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4098 (0x1002) +typedef struct sDot11fTLVAssociationState { + tANI_U8 present; + tANI_U16 state; +} tDot11fTLVAssociationState; + +#define DOT11F_TLV_ASSOCIATIONSTATE ( 4098 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_ASSOCIATIONSTATE_MIN_LEN ( 4 ) + +#define DOT11F_TLV_ASSOCIATIONSTATE_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvAssociationState(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVAssociationState*); + +tANI_U32 dot11fPackTlvAssociationState(tpAniSirGlobal, tDot11fTLVAssociationState*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvAssociationState(tpAniSirGlobal, tDot11fTLVAssociationState*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 11 (0x000b) +typedef struct sDot11fTLVChannelList { + tANI_U8 present; + tANI_U8 countryString[3]; + tANI_U8 num_channelList; + tANI_U8 channelList[251]; +} tDot11fTLVChannelList; + +#define DOT11F_TLV_CHANNELLIST ( 11 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CHANNELLIST_MIN_LEN ( 4 ) + +#define DOT11F_TLV_CHANNELLIST_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvChannelList(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVChannelList*); + +tANI_U32 dot11fPackTlvChannelList(tpAniSirGlobal, tDot11fTLVChannelList*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvChannelList(tpAniSirGlobal, tDot11fTLVChannelList*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4104 (0x1008) +typedef struct sDot11fTLVConfigMethods { + tANI_U8 present; + tANI_U16 methods; +} tDot11fTLVConfigMethods; + +#define DOT11F_TLV_CONFIGMETHODS ( 4104 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CONFIGMETHODS_MIN_LEN ( 4 ) + +#define DOT11F_TLV_CONFIGMETHODS_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvConfigMethods(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVConfigMethods*); + +tANI_U32 dot11fPackTlvConfigMethods(tpAniSirGlobal, tDot11fTLVConfigMethods*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvConfigMethods(tpAniSirGlobal, tDot11fTLVConfigMethods*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4105 (0x1009) +typedef struct sDot11fTLVConfigurationError { + tANI_U8 present; + tANI_U16 error; +} tDot11fTLVConfigurationError; + +#define DOT11F_TLV_CONFIGURATIONERROR ( 4105 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CONFIGURATIONERROR_MIN_LEN ( 4 ) + +#define DOT11F_TLV_CONFIGURATIONERROR_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvConfigurationError(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVConfigurationError*); + +tANI_U32 dot11fPackTlvConfigurationError(tpAniSirGlobal, tDot11fTLVConfigurationError*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvConfigurationError(tpAniSirGlobal, tDot11fTLVConfigurationError*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 5 (0x0005) +typedef struct sDot11fTLVConfigurationTimeout { + tANI_U8 present; + tANI_U8 GOConfigTimeout; + tANI_U8 CLConfigTimeout; +} tDot11fTLVConfigurationTimeout; + +#define DOT11F_TLV_CONFIGURATIONTIMEOUT ( 5 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_CONFIGURATIONTIMEOUT_MIN_LEN ( 3 ) + +#define DOT11F_TLV_CONFIGURATIONTIMEOUT_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvConfigurationTimeout(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVConfigurationTimeout*); + +tANI_U32 dot11fPackTlvConfigurationTimeout(tpAniSirGlobal, tDot11fTLVConfigurationTimeout*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvConfigurationTimeout(tpAniSirGlobal, tDot11fTLVConfigurationTimeout*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4113 (0x1011) +typedef struct sDot11fTLVDeviceName { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVDeviceName; + +#define DOT11F_TLV_DEVICENAME ( 4113 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_DEVICENAME_MIN_LEN ( 2 ) + +#define DOT11F_TLV_DEVICENAME_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvDeviceName(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVDeviceName*); + +tANI_U32 dot11fPackTlvDeviceName(tpAniSirGlobal, tDot11fTLVDeviceName*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvDeviceName(tpAniSirGlobal, tDot11fTLVDeviceName*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4114 (0x1012) +typedef struct sDot11fTLVDevicePasswordID { + tANI_U8 present; + tANI_U16 id; +} tDot11fTLVDevicePasswordID; + +#define DOT11F_TLV_DEVICEPASSWORDID ( 4114 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_DEVICEPASSWORDID_MIN_LEN ( 4 ) + +#define DOT11F_TLV_DEVICEPASSWORDID_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvDevicePasswordID(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVDevicePasswordID*); + +tANI_U32 dot11fPackTlvDevicePasswordID(tpAniSirGlobal, tDot11fTLVDevicePasswordID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvDevicePasswordID(tpAniSirGlobal, tDot11fTLVDevicePasswordID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 8 (0x0008) +typedef struct sDot11fTLVExtendedListenTiming { + tANI_U8 present; + tANI_U16 availibilityPeriod; + tANI_U16 availibilityInterval; +} tDot11fTLVExtendedListenTiming; + +#define DOT11F_TLV_EXTENDEDLISTENTIMING ( 8 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_EXTENDEDLISTENTIMING_MIN_LEN ( 5 ) + +#define DOT11F_TLV_EXTENDEDLISTENTIMING_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvExtendedListenTiming(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVExtendedListenTiming*); + +tANI_U32 dot11fPackTlvExtendedListenTiming(tpAniSirGlobal, tDot11fTLVExtendedListenTiming*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvExtendedListenTiming(tpAniSirGlobal, tDot11fTLVExtendedListenTiming*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4 (0x0004) +typedef struct sDot11fTLVGOIntent { + tANI_U8 present; + tANI_U8 GOIntent; +} tDot11fTLVGOIntent; + +#define DOT11F_TLV_GOINTENT ( 4 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_GOINTENT_MIN_LEN ( 2 ) + +#define DOT11F_TLV_GOINTENT_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvGOIntent(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVGOIntent*); + +tANI_U32 dot11fPackTlvGOIntent(tpAniSirGlobal, tDot11fTLVGOIntent*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvGOIntent(tpAniSirGlobal, tDot11fTLVGOIntent*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 9 (0x0009) +typedef struct sDot11fTLVIntendedP2PInterfaceAddress { + tANI_U8 present; + tANI_U8 P2PInterfaceAddress[6]; +} tDot11fTLVIntendedP2PInterfaceAddress; + +#define DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS ( 9 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS_MIN_LEN ( 7 ) + +#define DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVIntendedP2PInterfaceAddress*); + +tANI_U32 dot11fPackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal, tDot11fTLVIntendedP2PInterfaceAddress*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvIntendedP2PInterfaceAddress(tpAniSirGlobal, tDot11fTLVIntendedP2PInterfaceAddress*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 18 (0x0012) +typedef struct sDot11fTLVInvitationFlags { + tANI_U8 present; + tANI_U8 invitationFlags; +} tDot11fTLVInvitationFlags; + +#define DOT11F_TLV_INVITATIONFLAGS ( 18 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_INVITATIONFLAGS_MIN_LEN ( 2 ) + +#define DOT11F_TLV_INVITATIONFLAGS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvInvitationFlags(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVInvitationFlags*); + +tANI_U32 dot11fPackTlvInvitationFlags(tpAniSirGlobal, tDot11fTLVInvitationFlags*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvInvitationFlags(tpAniSirGlobal, tDot11fTLVInvitationFlags*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 6 (0x0006) +typedef struct sDot11fTLVListenChannel { + tANI_U8 present; + tANI_U8 countryString[3]; + tANI_U8 regulatoryClass; + tANI_U8 channel; +} tDot11fTLVListenChannel; + +#define DOT11F_TLV_LISTENCHANNEL ( 6 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_LISTENCHANNEL_MIN_LEN ( 6 ) + +#define DOT11F_TLV_LISTENCHANNEL_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvListenChannel(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVListenChannel*); + +tANI_U32 dot11fPackTlvListenChannel(tpAniSirGlobal, tDot11fTLVListenChannel*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvListenChannel(tpAniSirGlobal, tDot11fTLVListenChannel*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4129 (0x1021) +typedef struct sDot11fTLVManufacturer { + tANI_U8 present; + tANI_U8 num_name; + tANI_U8 name[64]; +} tDot11fTLVManufacturer; + +#define DOT11F_TLV_MANUFACTURER ( 4129 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MANUFACTURER_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MANUFACTURER_MAX_LEN ( 66 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvManufacturer(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVManufacturer*); + +tANI_U32 dot11fPackTlvManufacturer(tpAniSirGlobal, tDot11fTLVManufacturer*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvManufacturer(tpAniSirGlobal, tDot11fTLVManufacturer*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 1 (0x0001) +typedef struct sDot11fTLVMinorReasonCode { + tANI_U8 present; + tANI_U8 minorReasonCode; +} tDot11fTLVMinorReasonCode; + +#define DOT11F_TLV_MINORREASONCODE ( 1 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MINORREASONCODE_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MINORREASONCODE_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvMinorReasonCode(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVMinorReasonCode*); + +tANI_U32 dot11fPackTlvMinorReasonCode(tpAniSirGlobal, tDot11fTLVMinorReasonCode*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvMinorReasonCode(tpAniSirGlobal, tDot11fTLVMinorReasonCode*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4131 (0x1023) +typedef struct sDot11fTLVModelName { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVModelName; + +#define DOT11F_TLV_MODELNAME ( 4131 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MODELNAME_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MODELNAME_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvModelName(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVModelName*); + +tANI_U32 dot11fPackTlvModelName(tpAniSirGlobal, tDot11fTLVModelName*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvModelName(tpAniSirGlobal, tDot11fTLVModelName*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4132 (0x1024) +typedef struct sDot11fTLVModelNumber { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVModelNumber; + +#define DOT11F_TLV_MODELNUMBER ( 4132 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_MODELNUMBER_MIN_LEN ( 2 ) + +#define DOT11F_TLV_MODELNUMBER_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvModelNumber(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVModelNumber*); + +tANI_U32 dot11fPackTlvModelNumber(tpAniSirGlobal, tDot11fTLVModelNumber*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvModelNumber(tpAniSirGlobal, tDot11fTLVModelNumber*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 12 (0x000c) +typedef struct sDot11fTLVNoticeOfAbsence { + tANI_U8 present; + tANI_U8 index; + tANI_U8 CTSWindowOppPS; + tANI_U8 num_NoADesc; + tANI_U8 NoADesc[36]; +} tDot11fTLVNoticeOfAbsence; + +#define DOT11F_TLV_NOTICEOFABSENCE ( 12 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_NOTICEOFABSENCE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_NOTICEOFABSENCE_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvNoticeOfAbsence(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVNoticeOfAbsence*); + +tANI_U32 dot11fPackTlvNoticeOfAbsence(tpAniSirGlobal, tDot11fTLVNoticeOfAbsence*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvNoticeOfAbsence(tpAniSirGlobal, tDot11fTLVNoticeOfAbsence*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 17 (0x0011) +typedef struct sDot11fTLVOperatingChannel { + tANI_U8 present; + tANI_U8 countryString[3]; + tANI_U8 regulatoryClass; + tANI_U8 channel; +} tDot11fTLVOperatingChannel; + +#define DOT11F_TLV_OPERATINGCHANNEL ( 17 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_OPERATINGCHANNEL_MIN_LEN ( 6 ) + +#define DOT11F_TLV_OPERATINGCHANNEL_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvOperatingChannel(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVOperatingChannel*); + +tANI_U32 dot11fPackTlvOperatingChannel(tpAniSirGlobal, tDot11fTLVOperatingChannel*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvOperatingChannel(tpAniSirGlobal, tDot11fTLVOperatingChannel*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 2 (0x0002) +typedef struct sDot11fTLVP2PCapability { + tANI_U8 present; + tANI_U8 deviceCapability; + tANI_U8 groupCapability; +} tDot11fTLVP2PCapability; + +#define DOT11F_TLV_P2PCAPABILITY ( 2 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PCAPABILITY_MIN_LEN ( 3 ) + +#define DOT11F_TLV_P2PCAPABILITY_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PCapability(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PCapability*); + +tANI_U32 dot11fPackTlvP2PCapability(tpAniSirGlobal, tDot11fTLVP2PCapability*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PCapability(tpAniSirGlobal, tDot11fTLVP2PCapability*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 3 (0x0003) +typedef struct sDot11fTLVP2PDeviceId { + tANI_U8 present; + tANI_U8 P2PDeviceAddress[6]; +} tDot11fTLVP2PDeviceId; + +#define DOT11F_TLV_P2PDEVICEID ( 3 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PDEVICEID_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PDEVICEID_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PDeviceId(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PDeviceId*); + +tANI_U32 dot11fPackTlvP2PDeviceId(tpAniSirGlobal, tDot11fTLVP2PDeviceId*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PDeviceId(tpAniSirGlobal, tDot11fTLVP2PDeviceId*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 13 (0x000d) +typedef struct sDot11fTLVP2PDeviceInfo { + tANI_U8 present; + tANI_U8 P2PDeviceAddress[6]; + tANI_U16 configMethod; + tANI_U8 primaryDeviceType[8]; + tDot11fTLVDeviceName DeviceName; +} tDot11fTLVP2PDeviceInfo; + +#define DOT11F_TLV_P2PDEVICEINFO ( 13 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PDEVICEINFO_MIN_LEN ( 17 ) + +#define DOT11F_TLV_P2PDEVICEINFO_MAX_LEN ( 53 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PDeviceInfo(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PDeviceInfo*); + +tANI_U32 dot11fPackTlvP2PDeviceInfo(tpAniSirGlobal, tDot11fTLVP2PDeviceInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PDeviceInfo(tpAniSirGlobal, tDot11fTLVP2PDeviceInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 7 (0x0007) +typedef struct sDot11fTLVP2PGroupBssid { + tANI_U8 present; + tANI_U8 P2PGroupBssid[6]; +} tDot11fTLVP2PGroupBssid; + +#define DOT11F_TLV_P2PGROUPBSSID ( 7 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PGROUPBSSID_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PGROUPBSSID_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PGroupBssid(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PGroupBssid*); + +tANI_U32 dot11fPackTlvP2PGroupBssid(tpAniSirGlobal, tDot11fTLVP2PGroupBssid*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PGroupBssid(tpAniSirGlobal, tDot11fTLVP2PGroupBssid*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 15 (0x000f) +typedef struct sDot11fTLVP2PGroupId { + tANI_U8 present; + tANI_U8 deviceAddress[6]; + tANI_U8 num_ssid; + tANI_U8 ssid[32]; +} tDot11fTLVP2PGroupId; + +#define DOT11F_TLV_P2PGROUPID ( 15 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PGROUPID_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PGROUPID_MAX_LEN ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PGroupId(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PGroupId*); + +tANI_U32 dot11fPackTlvP2PGroupId(tpAniSirGlobal, tDot11fTLVP2PGroupId*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PGroupId(tpAniSirGlobal, tDot11fTLVP2PGroupId*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 14 (0x000e) +typedef struct sDot11fTLVP2PGroupInfo { + tANI_U8 present; + tANI_U8 num_P2PClientInfoDesc; + tANI_U8 P2PClientInfoDesc[1024]; +} tDot11fTLVP2PGroupInfo; + +#define DOT11F_TLV_P2PGROUPINFO ( 14 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PGROUPINFO_MIN_LEN ( 1 ) + +#define DOT11F_TLV_P2PGROUPINFO_MAX_LEN ( 1025 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PGroupInfo(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PGroupInfo*); + +tANI_U32 dot11fPackTlvP2PGroupInfo(tpAniSirGlobal, tDot11fTLVP2PGroupInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PGroupInfo(tpAniSirGlobal, tDot11fTLVP2PGroupInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 0 (0x0000) +typedef struct sDot11fTLVP2PStatus { + tANI_U8 present; + tANI_U8 status; +} tDot11fTLVP2PStatus; + +#define DOT11F_TLV_P2PSTATUS ( 0 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PSTATUS_MIN_LEN ( 2 ) + +#define DOT11F_TLV_P2PSTATUS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PStatus(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PStatus*); + +tANI_U32 dot11fPackTlvP2PStatus(tpAniSirGlobal, tDot11fTLVP2PStatus*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PStatus(tpAniSirGlobal, tDot11fTLVP2PStatus*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4180 (0x1054) +typedef struct sDot11fTLVPrimaryDeviceType { + tANI_U8 present; + tANI_U16 primary_category; + tANI_U8 oui[4]; + tANI_U16 sub_category; +} tDot11fTLVPrimaryDeviceType; + +#define DOT11F_TLV_PRIMARYDEVICETYPE ( 4180 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_PRIMARYDEVICETYPE_MIN_LEN ( 10 ) + +#define DOT11F_TLV_PRIMARYDEVICETYPE_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvPrimaryDeviceType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVPrimaryDeviceType*); + +tANI_U32 dot11fPackTlvPrimaryDeviceType(tpAniSirGlobal, tDot11fTLVPrimaryDeviceType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvPrimaryDeviceType(tpAniSirGlobal, tDot11fTLVPrimaryDeviceType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4156 (0x103c) +typedef struct sDot11fTLVRFBands { + tANI_U8 present; + tANI_U8 bands; +} tDot11fTLVRFBands; + +#define DOT11F_TLV_RFBANDS ( 4156 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_RFBANDS_MIN_LEN ( 3 ) + +#define DOT11F_TLV_RFBANDS_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRFBands(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRFBands*); + +tANI_U32 dot11fPackTlvRFBands(tpAniSirGlobal, tDot11fTLVRFBands*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRFBands(tpAniSirGlobal, tDot11fTLVRFBands*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4202 (0x106a) +typedef struct sDot11fTLVRequestDeviceType { + tANI_U8 present; + tANI_U16 primary_category; + tANI_U8 oui[4]; + tANI_U16 sub_category; +} tDot11fTLVRequestDeviceType; + +#define DOT11F_TLV_REQUESTDEVICETYPE ( 4202 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_REQUESTDEVICETYPE_MIN_LEN ( 10 ) + +#define DOT11F_TLV_REQUESTDEVICETYPE_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRequestDeviceType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRequestDeviceType*); + +tANI_U32 dot11fPackTlvRequestDeviceType(tpAniSirGlobal, tDot11fTLVRequestDeviceType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRequestDeviceType(tpAniSirGlobal, tDot11fTLVRequestDeviceType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4154 (0x103a) +typedef struct sDot11fTLVRequestType { + tANI_U8 present; + tANI_U8 reqType; +} tDot11fTLVRequestType; + +#define DOT11F_TLV_REQUESTTYPE ( 4154 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_REQUESTTYPE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_REQUESTTYPE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvRequestType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVRequestType*); + +tANI_U32 dot11fPackTlvRequestType(tpAniSirGlobal, tDot11fTLVRequestType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvRequestType(tpAniSirGlobal, tDot11fTLVRequestType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4155 (0x103b) +typedef struct sDot11fTLVResponseType { + tANI_U8 present; + tANI_U8 resType; +} tDot11fTLVResponseType; + +#define DOT11F_TLV_RESPONSETYPE ( 4155 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_RESPONSETYPE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_RESPONSETYPE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvResponseType(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVResponseType*); + +tANI_U32 dot11fPackTlvResponseType(tpAniSirGlobal, tDot11fTLVResponseType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvResponseType(tpAniSirGlobal, tDot11fTLVResponseType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4161 (0x1041) +typedef struct sDot11fTLVSelectedRegistrar { + tANI_U8 present; + tANI_U8 selected; +} tDot11fTLVSelectedRegistrar; + +#define DOT11F_TLV_SELECTEDREGISTRAR ( 4161 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_SELECTEDREGISTRAR_MIN_LEN ( 3 ) + +#define DOT11F_TLV_SELECTEDREGISTRAR_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvSelectedRegistrar(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVSelectedRegistrar*); + +tANI_U32 dot11fPackTlvSelectedRegistrar(tpAniSirGlobal, tDot11fTLVSelectedRegistrar*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvSelectedRegistrar(tpAniSirGlobal, tDot11fTLVSelectedRegistrar*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4179 (0x1053) +typedef struct sDot11fTLVSelectedRegistrarConfigMethods { + tANI_U8 present; + tANI_U16 methods; +} tDot11fTLVSelectedRegistrarConfigMethods; + +#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS ( 4179 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MIN_LEN ( 4 ) + +#define DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvSelectedRegistrarConfigMethods(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVSelectedRegistrarConfigMethods*); + +tANI_U32 dot11fPackTlvSelectedRegistrarConfigMethods(tpAniSirGlobal, tDot11fTLVSelectedRegistrarConfigMethods*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvSelectedRegistrarConfigMethods(tpAniSirGlobal, tDot11fTLVSelectedRegistrarConfigMethods*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4162 (0x1042) +typedef struct sDot11fTLVSerialNumber { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[32]; +} tDot11fTLVSerialNumber; + +#define DOT11F_TLV_SERIALNUMBER ( 4162 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_SERIALNUMBER_MIN_LEN ( 2 ) + +#define DOT11F_TLV_SERIALNUMBER_MAX_LEN ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvSerialNumber(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVSerialNumber*); + +tANI_U32 dot11fPackTlvSerialNumber(tpAniSirGlobal, tDot11fTLVSerialNumber*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvSerialNumber(tpAniSirGlobal, tDot11fTLVSerialNumber*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4167 (0x1047) +typedef struct sDot11fTLVUUID_E { + tANI_U8 present; + tANI_U8 uuid[16]; +} tDot11fTLVUUID_E; + +#define DOT11F_TLV_UUID_E ( 4167 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_UUID_E_MIN_LEN ( 18 ) + +#define DOT11F_TLV_UUID_E_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvUUID_E(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVUUID_E*); + +tANI_U32 dot11fPackTlvUUID_E(tpAniSirGlobal, tDot11fTLVUUID_E*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvUUID_E(tpAniSirGlobal, tDot11fTLVUUID_E*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4168 (0x1048) +typedef struct sDot11fTLVUUID_R { + tANI_U8 present; + tANI_U8 uuid[16]; +} tDot11fTLVUUID_R; + +#define DOT11F_TLV_UUID_R ( 4168 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_UUID_R_MIN_LEN ( 18 ) + +#define DOT11F_TLV_UUID_R_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvUUID_R(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVUUID_R*); + +tANI_U32 dot11fPackTlvUUID_R(tpAniSirGlobal, tDot11fTLVUUID_R*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvUUID_R(tpAniSirGlobal, tDot11fTLVUUID_R*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4169 (0x1049) +typedef struct sDot11fTLVVendorExtension { + tANI_U8 present; + tANI_U8 vendorId[3]; + tDot11fTLVVersion2 Version2; + tDot11fTLVAuthorizedMACs AuthorizedMACs; + tDot11fTLVRequestToEnroll RequestToEnroll; +} tDot11fTLVVendorExtension; + +#define DOT11F_TLV_VENDOREXTENSION ( 4169 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_VENDOREXTENSION_MIN_LEN ( 5 ) + +#define DOT11F_TLV_VENDOREXTENSION_MAX_LEN ( 19 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvVendorExtension(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVVendorExtension*); + +tANI_U32 dot11fPackTlvVendorExtension(tpAniSirGlobal, tDot11fTLVVendorExtension*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvVendorExtension(tpAniSirGlobal, tDot11fTLVVendorExtension*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4170 (0x104a) +typedef struct sDot11fTLVVersion { + tANI_U8 present; + tANI_U8 minor: 4; + tANI_U8 major: 4; +} tDot11fTLVVersion; + +#define DOT11F_TLV_VERSION ( 4170 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_VERSION_MIN_LEN ( 3 ) + +#define DOT11F_TLV_VERSION_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvVersion(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVVersion*); + +tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal, tDot11fTLVVersion*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvVersion(tpAniSirGlobal, tDot11fTLVVersion*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 4164 (0x1044) +typedef struct sDot11fTLVWPSState { + tANI_U8 present; + tANI_U8 state; +} tDot11fTLVWPSState; + +#define DOT11F_TLV_WPSSTATE ( 4164 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_WPSSTATE_MIN_LEN ( 3 ) + +#define DOT11F_TLV_WPSSTATE_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvWPSState(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVWPSState*); + +tANI_U32 dot11fPackTlvWPSState(tpAniSirGlobal, tDot11fTLVWPSState*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvWPSState(tpAniSirGlobal, tDot11fTLVWPSState*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 16 (0x0010) +typedef struct sDot11fTLVP2PInterface { + tANI_U8 present; + tANI_U8 P2PDeviceAddress[6]; +} tDot11fTLVP2PInterface; + +#define DOT11F_TLV_P2PINTERFACE ( 16 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PINTERFACE_MIN_LEN ( 7 ) + +#define DOT11F_TLV_P2PINTERFACE_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PInterface(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PInterface*); + +tANI_U32 dot11fPackTlvP2PInterface(tpAniSirGlobal, tDot11fTLVP2PInterface*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PInterface(tpAniSirGlobal, tDot11fTLVP2PInterface*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// ID 10 (0x000a) +typedef struct sDot11fTLVP2PManageability { + tANI_U8 present; + tANI_U8 manageability; +} tDot11fTLVP2PManageability; + +#define DOT11F_TLV_P2PMANAGEABILITY ( 10 ) + +// N.B. These #defines do *not* include the ID & length +#define DOT11F_TLV_P2PMANAGEABILITY_MIN_LEN ( 2 ) + +#define DOT11F_TLV_P2PMANAGEABILITY_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackTlvP2PManageability(tpAniSirGlobal, tANI_U8*,tANI_U16, tDot11fTLVP2PManageability*); + +tANI_U32 dot11fPackTlvP2PManageability(tpAniSirGlobal, tDot11fTLVP2PManageability*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedTlvP2PManageability(tpAniSirGlobal, tDot11fTLVP2PManageability*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +/********************************************************************* + * Information Elements * + ********************************************************************/ + +// EID 1 (0x01) +typedef struct sDot11fIEAPName { + tANI_U8 present; + tANI_U8 num_name; + tANI_U8 name[32]; +} tDot11fIEAPName; + +#define DOT11F_EID_APNAME ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_APNAME_MIN_LEN ( 1 ) + +#define DOT11F_IE_APNAME_MAX_LEN ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAPName(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAPName*); + +tANI_U32 dot11fPackIeAPName(tpAniSirGlobal, tDot11fIEAPName*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAPName(tpAniSirGlobal, tDot11fIEAPName*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 4 (0x04) +typedef struct sDot11fIEBPIndicator { + tANI_U8 present; + tANI_U8 indicator; + tANI_U8 type; +} tDot11fIEBPIndicator; + +#define DOT11F_EID_BPINDICATOR ( 4 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BPINDICATOR_MIN_LEN ( 2 ) + +#define DOT11F_IE_BPINDICATOR_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBPIndicator(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBPIndicator*); + +tANI_U32 dot11fPackIeBPIndicator(tpAniSirGlobal, tDot11fIEBPIndicator*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBPIndicator(tpAniSirGlobal, tDot11fIEBPIndicator*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIECondensedCountryStr { + tANI_U8 present; + tANI_U8 countryStr[2]; +} tDot11fIECondensedCountryStr; + +#define DOT11F_EID_CONDENSEDCOUNTRYSTR ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MIN_LEN ( 2 ) + +#define DOT11F_IE_CONDENSEDCOUNTRYSTR_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeCondensedCountryStr(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIECondensedCountryStr*); + +tANI_U32 dot11fPackIeCondensedCountryStr(tpAniSirGlobal, tDot11fIECondensedCountryStr*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIECondensedCountryStr(tpAniSirGlobal, tDot11fIECondensedCountryStr*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEGTK { + tANI_U8 present; + tANI_U16 keyId: 2; + tANI_U16 reserved: 14; + tANI_U8 keyLength; + tANI_U8 RSC[8]; + tANI_U8 num_key; + tANI_U8 key[32]; +} tDot11fIEGTK; + +#define DOT11F_EID_GTK ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_GTK_MIN_LEN ( 16 ) + +#define DOT11F_IE_GTK_MAX_LEN ( 43 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeGTK(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEGTK*); + +tANI_U32 dot11fPackIeGTK(tpAniSirGlobal, tDot11fIEGTK*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEGTK(tpAniSirGlobal, tDot11fIEGTK*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEHCF { + tANI_U8 present; + tANI_U8 enabled; +} tDot11fIEHCF; + +#define DOT11F_EID_HCF ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HCF_MIN_LEN ( 1 ) + +#define DOT11F_IE_HCF_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHCF(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHCF*); + +tANI_U32 dot11fPackIeHCF(tpAniSirGlobal, tDot11fIEHCF*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHCF(tpAniSirGlobal, tDot11fIEHCF*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 4 (0x04) +typedef struct sDot11fIEIGTK { + tANI_U8 present; + tANI_U8 keyID[2]; + tANI_U8 IPN[6]; + tANI_U8 keyLength; + tANI_U8 key[24]; +} tDot11fIEIGTK; + +#define DOT11F_EID_IGTK ( 4 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_IGTK_MIN_LEN ( 33 ) + +#define DOT11F_IE_IGTK_MAX_LEN ( 33 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeIGTK(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEIGTK*); + +tANI_U32 dot11fPackIeIGTK(tpAniSirGlobal, tDot11fIEIGTK*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEIGTK(tpAniSirGlobal, tDot11fIEIGTK*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 9 (0x09) +typedef struct sDot11fIELLAttr { + tANI_U8 present; + tANI_U32 defer_threshold; +} tDot11fIELLAttr; + +#define DOT11F_EID_LLATTR ( 9 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LLATTR_MIN_LEN ( 4 ) + +#define DOT11F_IE_LLATTR_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLLAttr(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELLAttr*); + +tANI_U32 dot11fPackIeLLAttr(tpAniSirGlobal, tDot11fIELLAttr*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELLAttr(tpAniSirGlobal, tDot11fIELLAttr*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 8 (0x08) +typedef struct sDot11fIELoadBalance { + tANI_U8 present; + tANI_U8 bssid[6]; + tANI_U8 channel; +} tDot11fIELoadBalance; + +#define DOT11F_EID_LOADBALANCE ( 8 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LOADBALANCE_MIN_LEN ( 7 ) + +#define DOT11F_IE_LOADBALANCE_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLoadBalance(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELoadBalance*); + +tANI_U32 dot11fPackIeLoadBalance(tpAniSirGlobal, tDot11fIELoadBalance*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELoadBalance(tpAniSirGlobal, tDot11fIELoadBalance*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 6 (0x06) +typedef struct sDot11fIELoadInfo { + tANI_U8 present; + tANI_U16 num_stas; + tANI_U16 channel_util; +} tDot11fIELoadInfo; + +#define DOT11F_EID_LOADINFO ( 6 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LOADINFO_MIN_LEN ( 4 ) + +#define DOT11F_IE_LOADINFO_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLoadInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELoadInfo*); + +tANI_U32 dot11fPackIeLoadInfo(tpAniSirGlobal, tDot11fIELoadInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELoadInfo(tpAniSirGlobal, tDot11fIELoadInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 7 (0x07) +typedef struct sDot11fIEPropAssocType { + tANI_U8 present; + tANI_U8 type; +} tDot11fIEPropAssocType; + +#define DOT11F_EID_PROPASSOCTYPE ( 7 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPASSOCTYPE_MIN_LEN ( 1 ) + +#define DOT11F_IE_PROPASSOCTYPE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropAssocType(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropAssocType*); + +tANI_U32 dot11fPackIePropAssocType(tpAniSirGlobal, tDot11fIEPropAssocType*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropAssocType(tpAniSirGlobal, tDot11fIEPropAssocType*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 10 (0x0a) +typedef struct sDot11fIEPropCapability { + tANI_U8 present; + tANI_U16 capability; +} tDot11fIEPropCapability; + +#define DOT11F_EID_PROPCAPABILITY ( 10 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPCAPABILITY_MIN_LEN ( 2 ) + +#define DOT11F_IE_PROPCAPABILITY_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropCapability(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropCapability*); + +tANI_U32 dot11fPackIePropCapability(tpAniSirGlobal, tDot11fIEPropCapability*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropCapability(tpAniSirGlobal, tDot11fIEPropCapability*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 15 (0x0f) +typedef struct sDot11fIEPropChannSwitchAnn { + tANI_U8 present; + tANI_U8 mode; + tANI_U8 primary_channel; + tANI_U8 sub_band; + tANI_U8 channel_switch_count; +} tDot11fIEPropChannSwitchAnn; + +#define DOT11F_EID_PROPCHANNSWITCHANN ( 15 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPCHANNSWITCHANN_MIN_LEN ( 4 ) + +#define DOT11F_IE_PROPCHANNSWITCHANN_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropChannSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropChannSwitchAnn*); + +tANI_U32 dot11fPackIePropChannSwitchAnn(tpAniSirGlobal, tDot11fIEPropChannSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropChannSwitchAnn(tpAniSirGlobal, tDot11fIEPropChannSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 12 (0x0c) +typedef struct sDot11fIEPropEDCAParams { + tANI_U8 present; + tANI_U8 qos; + tANI_U8 reserved; + tANI_U8 acbe_aifsn: 4; + tANI_U8 acbe_acm: 1; + tANI_U8 acbe_aci: 2; + tANI_U8 unused1: 1; + tANI_U8 acbe_min: 4; + tANI_U8 acbe_max: 4; + tANI_U16 acbe_txoplimit; + tANI_U8 acbk_aifsn: 4; + tANI_U8 acbk_acm: 1; + tANI_U8 acbk_aci: 2; + tANI_U8 unused2: 1; + tANI_U8 acbk_min: 4; + tANI_U8 acbk_max: 4; + tANI_U16 acbk_txoplimit; + tANI_U8 acvi_aifsn: 4; + tANI_U8 acvi_acm: 1; + tANI_U8 acvi_aci: 2; + tANI_U8 unused3: 1; + tANI_U8 acvi_min: 4; + tANI_U8 acvi_max: 4; + tANI_U16 acvi_txoplimit; + tANI_U8 acvo_aifsn: 4; + tANI_U8 acvo_acm: 1; + tANI_U8 acvo_aci: 2; + tANI_U8 unused4: 1; + tANI_U8 acvo_min: 4; + tANI_U8 acvo_max: 4; + tANI_U16 acvo_txoplimit; +} tDot11fIEPropEDCAParams; + +#define DOT11F_EID_PROPEDCAPARAMS ( 12 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPEDCAPARAMS_MIN_LEN ( 18 ) + +#define DOT11F_IE_PROPEDCAPARAMS_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropEDCAParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropEDCAParams*); + +tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal, tDot11fIEPropEDCAParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropEDCAParams(tpAniSirGlobal, tDot11fIEPropEDCAParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 16 (0x10) +typedef struct sDot11fIEPropQuietBSS { + tANI_U8 present; + tANI_U8 quiet_count; + tANI_U8 quiet_period; + tANI_U16 quiet_duration; + tANI_U16 quiet_offset; +} tDot11fIEPropQuietBSS; + +#define DOT11F_EID_PROPQUIETBSS ( 16 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPQUIETBSS_MIN_LEN ( 6 ) + +#define DOT11F_IE_PROPQUIETBSS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropQuietBSS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropQuietBSS*); + +tANI_U32 dot11fPackIePropQuietBSS(tpAniSirGlobal, tDot11fIEPropQuietBSS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropQuietBSS(tpAniSirGlobal, tDot11fIEPropQuietBSS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 0 (0x00) +typedef struct sDot11fIEPropSuppRates { + tANI_U8 present; + tANI_U8 num_rates; + tANI_U8 rates[12]; +} tDot11fIEPropSuppRates; + +#define DOT11F_EID_PROPSUPPRATES ( 0 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PROPSUPPRATES_MIN_LEN ( 1 ) + +#define DOT11F_IE_PROPSUPPRATES_MAX_LEN ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePropSuppRates(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPropSuppRates*); + +tANI_U32 dot11fPackIePropSuppRates(tpAniSirGlobal, tDot11fIEPropSuppRates*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPropSuppRates(tpAniSirGlobal, tDot11fIEPropSuppRates*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 3 (0x03) +typedef struct sDot11fIER0KH_ID { + tANI_U8 present; + tANI_U8 num_PMK_R0_ID; + tANI_U8 PMK_R0_ID[48]; +} tDot11fIER0KH_ID; + +#define DOT11F_EID_R0KH_ID ( 3 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_R0KH_ID_MIN_LEN ( 1 ) + +#define DOT11F_IE_R0KH_ID_MAX_LEN ( 48 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeR0KH_ID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIER0KH_ID*); + +tANI_U32 dot11fPackIeR0KH_ID(tpAniSirGlobal, tDot11fIER0KH_ID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIER0KH_ID(tpAniSirGlobal, tDot11fIER0KH_ID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIER1KH_ID { + tANI_U8 present; + tANI_U8 PMK_R1_ID[6]; +} tDot11fIER1KH_ID; + +#define DOT11F_EID_R1KH_ID ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_R1KH_ID_MIN_LEN ( 6 ) + +#define DOT11F_IE_R1KH_ID_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeR1KH_ID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIER1KH_ID*); + +tANI_U32 dot11fPackIeR1KH_ID(tpAniSirGlobal, tDot11fIER1KH_ID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIER1KH_ID(tpAniSirGlobal, tDot11fIER1KH_ID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIETSFInfo { + tANI_U8 present; + tANI_U16 TsfOffset; + tANI_U16 BeaconIntvl; +} tDot11fIETSFInfo; + +#define DOT11F_EID_TSFINFO ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TSFINFO_MIN_LEN ( 4 ) + +#define DOT11F_IE_TSFINFO_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTSFInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETSFInfo*); + +tANI_U32 dot11fPackIeTSFInfo(tpAniSirGlobal, tDot11fIETSFInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETSFInfo(tpAniSirGlobal, tDot11fIETSFInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 18 (0x12) +typedef struct sDot11fIETaurus { + tANI_U8 present; + tANI_U16 baTIDBitmap; + tANI_U16 baPolicy; + tANI_U16 baBufferSize: 12; + tANI_U16 rsvd: 4; +} tDot11fIETaurus; + +#define DOT11F_EID_TAURUS ( 18 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TAURUS_MIN_LEN ( 6 ) + +#define DOT11F_IE_TAURUS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTaurus(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETaurus*); + +tANI_U32 dot11fPackIeTaurus(tpAniSirGlobal, tDot11fIETaurus*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETaurus(tpAniSirGlobal, tDot11fIETaurus*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 14 (0x0e) +typedef struct sDot11fIETitan { + tANI_U8 present; + tANI_U8 concat_tcid_bitmap; + tANI_U8 compression_tcid_bitmap; + tANI_U8 cb_state; + tANI_U8 rev_fcs_state; +} tDot11fIETitan; + +#define DOT11F_EID_TITAN ( 14 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TITAN_MIN_LEN ( 4 ) + +#define DOT11F_IE_TITAN_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTitan(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETitan*); + +tANI_U32 dot11fPackIeTitan(tpAniSirGlobal, tDot11fIETitan*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETitan(tpAniSirGlobal, tDot11fIETitan*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 17 (0x11) +typedef struct sDot11fIETriggerStaBgScan { + tANI_U8 present; + tANI_U8 enable; +} tDot11fIETriggerStaBgScan; + +#define DOT11F_EID_TRIGGERSTABGSCAN ( 17 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TRIGGERSTABGSCAN_MIN_LEN ( 1 ) + +#define DOT11F_IE_TRIGGERSTABGSCAN_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTriggerStaBgScan(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETriggerStaBgScan*); + +tANI_U32 dot11fPackIeTriggerStaBgScan(tpAniSirGlobal, tDot11fIETriggerStaBgScan*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETriggerStaBgScan(tpAniSirGlobal, tDot11fIETriggerStaBgScan*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 11 (0x0b) +typedef struct sDot11fIEVersion { + tANI_U8 present; + tANI_U32 chip_rev; + tANI_U8 card_type; + tANI_U8 num_build_version; + tANI_U8 build_version[20]; +} tDot11fIEVersion; + +#define DOT11F_EID_VERSION ( 11 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VERSION_MIN_LEN ( 5 ) + +#define DOT11F_IE_VERSION_MAX_LEN ( 25 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVersion(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVersion*); + +tANI_U32 dot11fPackIeVersion(tpAniSirGlobal, tDot11fIEVersion*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVersion(tpAniSirGlobal, tDot11fIEVersion*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 3 (0x03) +typedef struct sDot11fIEWDS { + tANI_U8 present; + tANI_U8 num_wdsData; + tANI_U8 wdsData[64]; +} tDot11fIEWDS; + +#define DOT11F_EID_WDS ( 3 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WDS_MIN_LEN ( 0 ) + +#define DOT11F_IE_WDS_MAX_LEN ( 64 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWDS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWDS*); + +tANI_U32 dot11fPackIeWDS(tpAniSirGlobal, tDot11fIEWDS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWDS(tpAniSirGlobal, tDot11fIEWDS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 51 (0x33) +typedef struct sDot11fIEAPChannelReport { + tANI_U8 present; + tANI_U8 regulatoryClass; + tANI_U8 num_channelList; + tANI_U8 channelList[50]; +} tDot11fIEAPChannelReport; + +#define DOT11F_EID_APCHANNELREPORT ( 51 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_APCHANNELREPORT_MIN_LEN ( 1 ) + +#define DOT11F_IE_APCHANNELREPORT_MAX_LEN ( 51 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAPChannelReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAPChannelReport*); + +tANI_U32 dot11fPackIeAPChannelReport(tpAniSirGlobal, tDot11fIEAPChannelReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAPChannelReport(tpAniSirGlobal, tDot11fIEAPChannelReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEBcnReportingDetail { + tANI_U8 present; + tANI_U8 reportingDetail; +} tDot11fIEBcnReportingDetail; + +#define DOT11F_EID_BCNREPORTINGDETAIL ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BCNREPORTINGDETAIL_MIN_LEN ( 1 ) + +#define DOT11F_IE_BCNREPORTINGDETAIL_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBcnReportingDetail(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBcnReportingDetail*); + +tANI_U32 dot11fPackIeBcnReportingDetail(tpAniSirGlobal, tDot11fIEBcnReportingDetail*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBcnReportingDetail(tpAniSirGlobal, tDot11fIEBcnReportingDetail*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIEBeaconReportFrmBody { + tANI_U8 present; + tANI_U8 num_reportedFields; + tANI_U8 reportedFields[224]; +} tDot11fIEBeaconReportFrmBody; + +#define DOT11F_EID_BEACONREPORTFRMBODY ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BEACONREPORTFRMBODY_MIN_LEN ( 0 ) + +#define DOT11F_IE_BEACONREPORTFRMBODY_MAX_LEN ( 224 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBeaconReportFrmBody(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBeaconReportFrmBody*); + +tANI_U32 dot11fPackIeBeaconReportFrmBody(tpAniSirGlobal, tDot11fIEBeaconReportFrmBody*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBeaconReportFrmBody(tpAniSirGlobal, tDot11fIEBeaconReportFrmBody*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIEBeaconReporting { + tANI_U8 present; + tANI_U8 reportingCondition; + tANI_U8 threshold; +} tDot11fIEBeaconReporting; + +#define DOT11F_EID_BEACONREPORTING ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_BEACONREPORTING_MIN_LEN ( 2 ) + +#define DOT11F_IE_BEACONREPORTING_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeBeaconReporting(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEBeaconReporting*); + +tANI_U32 dot11fPackIeBeaconReporting(tpAniSirGlobal, tDot11fIEBeaconReporting*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEBeaconReporting(tpAniSirGlobal, tDot11fIEBeaconReporting*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 66 (0x42) +typedef struct sDot11fIEMeasurementPilot { + tANI_U8 present; + tANI_U8 measurementPilot; + tANI_U8 num_vendorSpecific; + tANI_U8 vendorSpecific[255]; +} tDot11fIEMeasurementPilot; + +#define DOT11F_EID_MEASUREMENTPILOT ( 66 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MEASUREMENTPILOT_MIN_LEN ( 1 ) + +#define DOT11F_IE_MEASUREMENTPILOT_MAX_LEN ( 256 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMeasurementPilot(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMeasurementPilot*); + +tANI_U32 dot11fPackIeMeasurementPilot(tpAniSirGlobal, tDot11fIEMeasurementPilot*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMeasurementPilot(tpAniSirGlobal, tDot11fIEMeasurementPilot*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 71 (0x47) +typedef struct sDot11fIEMultiBssid { + tANI_U8 present; + tANI_U8 maxBSSIDIndicator; + tANI_U8 num_vendorSpecific; + tANI_U8 vendorSpecific[255]; +} tDot11fIEMultiBssid; + +#define DOT11F_EID_MULTIBSSID ( 71 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MULTIBSSID_MIN_LEN ( 1 ) + +#define DOT11F_IE_MULTIBSSID_MAX_LEN ( 256 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMultiBssid(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMultiBssid*); + +tANI_U32 dot11fPackIeMultiBssid(tpAniSirGlobal, tDot11fIEMultiBssid*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMultiBssid(tpAniSirGlobal, tDot11fIEMultiBssid*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 57 (0x39) +typedef struct sDot11fIERICData { + tANI_U8 present; + tANI_U8 Identifier; + tANI_U8 resourceDescCount; + tANI_U16 statusCode; +} tDot11fIERICData; + +#define DOT11F_EID_RICDATA ( 57 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RICDATA_MIN_LEN ( 4 ) + +#define DOT11F_IE_RICDATA_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRICData(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERICData*); + +tANI_U32 dot11fPackIeRICData(tpAniSirGlobal, tDot11fIERICData*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERICData(tpAniSirGlobal, tDot11fIERICData*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 75 (0x4b) +typedef struct sDot11fIERICDescriptor { + tANI_U8 present; + tANI_U8 resourceType; + tANI_U8 num_variableData; + tANI_U8 variableData[255]; +} tDot11fIERICDescriptor; + +#define DOT11F_EID_RICDESCRIPTOR ( 75 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RICDESCRIPTOR_MIN_LEN ( 1 ) + +#define DOT11F_IE_RICDESCRIPTOR_MAX_LEN ( 256 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRICDescriptor(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERICDescriptor*); + +tANI_U32 dot11fPackIeRICDescriptor(tpAniSirGlobal, tDot11fIERICDescriptor*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERICDescriptor(tpAniSirGlobal, tDot11fIERICDescriptor*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 70 (0x46) +typedef struct sDot11fIERRMEnabledCap { + tANI_U8 present; + tANI_U8 LinkMeasurement: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 parallel: 1; + tANI_U8 repeated: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 statistics: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 APChanReport: 1; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 operatingChanMax: 3; + tANI_U8 nonOperatinChanMax: 3; + tANI_U8 MeasurementPilot: 3; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 AntennaInformation: 1; + tANI_U8 reserved: 6; +} tDot11fIERRMEnabledCap; + +#define DOT11F_EID_RRMENABLEDCAP ( 70 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RRMENABLEDCAP_MIN_LEN ( 5 ) + +#define DOT11F_IE_RRMENABLEDCAP_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERRMEnabledCap*); + +tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal, tDot11fIERRMEnabledCap*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERRMEnabledCap(tpAniSirGlobal, tDot11fIERRMEnabledCap*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 10 (0x0a) +typedef struct sDot11fIERequestedInfo { + tANI_U8 present; + tANI_U8 num_requested_eids; + tANI_U8 requested_eids[255]; +} tDot11fIERequestedInfo; + +#define DOT11F_EID_REQUESTEDINFO ( 10 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_REQUESTEDINFO_MIN_LEN ( 0 ) + +#define DOT11F_IE_REQUESTEDINFO_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRequestedInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERequestedInfo*); + +tANI_U32 dot11fPackIeRequestedInfo(tpAniSirGlobal, tDot11fIERequestedInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERequestedInfo(tpAniSirGlobal, tDot11fIERequestedInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 0 (0x00) +typedef struct sDot11fIESSID { + tANI_U8 present; + tANI_U8 num_ssid; + tANI_U8 ssid[32]; +} tDot11fIESSID; + +#define DOT11F_EID_SSID ( 0 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SSID_MIN_LEN ( 0 ) + +#define DOT11F_IE_SSID_MAX_LEN ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSSID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESSID*); + +tANI_U32 dot11fPackIeSSID(tpAniSirGlobal, tDot11fIESSID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESSID(tpAniSirGlobal, tDot11fIESSID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 15 (0x0f) +typedef struct sDot11fIESchedule { + tANI_U8 present; + tANI_U16 aggregation: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 reserved: 9; + tANI_U32 service_start_time; + tANI_U32 service_interval; + tANI_U16 max_service_dur; + tANI_U16 spec_interval; +} tDot11fIESchedule; + +#define DOT11F_EID_SCHEDULE ( 15 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SCHEDULE_MIN_LEN ( 14 ) + +#define DOT11F_IE_SCHEDULE_MAX_LEN ( 14 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSchedule(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESchedule*); + +tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal, tDot11fIESchedule*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESchedule(tpAniSirGlobal, tDot11fIESchedule*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 14 (0x0e) +typedef struct sDot11fIETCLAS { + tANI_U8 present; + tANI_U8 user_priority; + tANI_U8 classifier_type; + tANI_U8 classifier_mask; + union + { + struct + { + tANI_U8 source[6]; + tANI_U8 dest[6]; + tANI_U16 type; + } EthParams; /* classifier_type = 0 */ + struct + { + tANI_U8 version; + union + { + struct + { + tANI_U8 source[4]; + tANI_U8 dest[4]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 DSCP; + tANI_U8 proto; + tANI_U8 reserved; + } IpV4Params; /* version = 4 */ + struct + { + tANI_U8 source[16]; + tANI_U8 dest[16]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 flow_label[3]; + } IpV6Params; /* version = 6 */ + } params; + } IpParams; /* classifier_type = 1 */ + struct + { + tANI_U16 tag_type; + } Params8021dq; /* classifier_type = 2 */ + } info; +} tDot11fIETCLAS; + +#define DOT11F_EID_TCLAS ( 14 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TCLAS_MIN_LEN ( 5 ) + +#define DOT11F_IE_TCLAS_MAX_LEN ( 43 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTCLAS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETCLAS*); + +tANI_U32 dot11fPackIeTCLAS(tpAniSirGlobal, tDot11fIETCLAS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETCLAS(tpAniSirGlobal, tDot11fIETCLAS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 44 (0x2c) +typedef struct sDot11fIETCLASSPROC { + tANI_U8 present; + tANI_U8 processing; +} tDot11fIETCLASSPROC; + +#define DOT11F_EID_TCLASSPROC ( 44 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TCLASSPROC_MIN_LEN ( 1 ) + +#define DOT11F_IE_TCLASSPROC_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTCLASSPROC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETCLASSPROC*); + +tANI_U32 dot11fPackIeTCLASSPROC(tpAniSirGlobal, tDot11fIETCLASSPROC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETCLASSPROC(tpAniSirGlobal, tDot11fIETCLASSPROC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 43 (0x2b) +typedef struct sDot11fIETSDelay { + tANI_U8 present; + tANI_U32 delay; +} tDot11fIETSDelay; + +#define DOT11F_EID_TSDELAY ( 43 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TSDELAY_MIN_LEN ( 4 ) + +#define DOT11F_IE_TSDELAY_MAX_LEN ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTSDelay(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETSDelay*); + +tANI_U32 dot11fPackIeTSDelay(tpAniSirGlobal, tDot11fIETSDelay*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETSDelay(tpAniSirGlobal, tDot11fIETSDelay*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 13 (0x0d) +typedef struct sDot11fIETSPEC { + tANI_U8 present; + tANI_U16 traffic_type: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 access_policy: 2; + tANI_U16 aggregation: 1; + tANI_U16 psb: 1; + tANI_U16 user_priority: 3; + tANI_U16 tsinfo_ack_pol: 2; + tANI_U8 schedule: 1; + tANI_U8 unused: 7; + tANI_U16 size: 15; + tANI_U16 fixed: 1; + tANI_U16 max_msdu_size; + tANI_U32 min_service_int; + tANI_U32 max_service_int; + tANI_U32 inactivity_int; + tANI_U32 suspension_int; + tANI_U32 service_start_time; + tANI_U32 min_data_rate; + tANI_U32 mean_data_rate; + tANI_U32 peak_data_rate; + tANI_U32 burst_size; + tANI_U32 delay_bound; + tANI_U32 min_phy_rate; + tANI_U16 surplus_bw_allowance; + tANI_U16 medium_time; +} tDot11fIETSPEC; + +#define DOT11F_EID_TSPEC ( 13 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TSPEC_MIN_LEN ( 55 ) + +#define DOT11F_IE_TSPEC_MAX_LEN ( 55 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTSPEC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETSPEC*); + +tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal, tDot11fIETSPEC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETSPEC(tpAniSirGlobal, tDot11fIETSPEC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x09} +typedef struct sDot11fIEWMMSchedule { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U16 aggregation: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 reserved: 9; + tANI_U32 service_start_time; + tANI_U32 service_interval; + tANI_U16 max_service_dur; + tANI_U16 spec_interval; +} tDot11fIEWMMSchedule; + +#define DOT11F_EID_WMMSCHEDULE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMSCHEDULE_MIN_LEN ( 20 ) + +#define DOT11F_IE_WMMSCHEDULE_MAX_LEN ( 20 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMSchedule*); + +tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal, tDot11fIEWMMSchedule*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMSchedule(tpAniSirGlobal, tDot11fIEWMMSchedule*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x06} +typedef struct sDot11fIEWMMTCLAS { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 user_priority; + tANI_U8 classifier_type; + tANI_U8 classifier_mask; + union + { + struct + { + tANI_U8 source[6]; + tANI_U8 dest[6]; + tANI_U16 type; + } EthParams; /* classifier_type = 0 */ + struct + { + tANI_U8 version; + union + { + struct + { + tANI_U8 source[4]; + tANI_U8 dest[4]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 DSCP; + tANI_U8 proto; + tANI_U8 reserved; + } IpV4Params; /* version = 4 */ + struct + { + tANI_U8 source[16]; + tANI_U8 dest[16]; + tANI_U16 src_port; + tANI_U16 dest_port; + tANI_U8 flow_label[3]; + } IpV6Params; /* version = 6 */ + } params; + } IpParams; /* classifier_type = 1 */ + struct + { + tANI_U16 tag_type; + } Params8021dq; /* classifier_type = 2 */ + } info; +} tDot11fIEWMMTCLAS; + +#define DOT11F_EID_WMMTCLAS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTCLAS_MIN_LEN ( 11 ) + +#define DOT11F_IE_WMMTCLAS_MAX_LEN ( 49 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTCLAS*); + +tANI_U32 dot11fPackIeWMMTCLAS(tpAniSirGlobal, tDot11fIEWMMTCLAS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTCLAS(tpAniSirGlobal, tDot11fIEWMMTCLAS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x07} +typedef struct sDot11fIEWMMTCLASPROC { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 processing; +} tDot11fIEWMMTCLASPROC; + +#define DOT11F_EID_WMMTCLASPROC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTCLASPROC_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMTCLASPROC_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTCLASPROC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTCLASPROC*); + +tANI_U32 dot11fPackIeWMMTCLASPROC(tpAniSirGlobal, tDot11fIEWMMTCLASPROC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTCLASPROC(tpAniSirGlobal, tDot11fIEWMMTCLASPROC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x08} +typedef struct sDot11fIEWMMTSDelay { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U32 delay; +} tDot11fIEWMMTSDelay; + +#define DOT11F_EID_WMMTSDELAY ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTSDELAY_MIN_LEN ( 10 ) + +#define DOT11F_IE_WMMTSDELAY_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTSDelay(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTSDelay*); + +tANI_U32 dot11fPackIeWMMTSDelay(tpAniSirGlobal, tDot11fIEWMMTSDelay*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTSDelay(tpAniSirGlobal, tDot11fIEWMMTSDelay*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x02} +typedef struct sDot11fIEWMMTSPEC { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U16 traffic_type: 1; + tANI_U16 tsid: 4; + tANI_U16 direction: 2; + tANI_U16 access_policy: 2; + tANI_U16 aggregation: 1; + tANI_U16 psb: 1; + tANI_U16 user_priority: 3; + tANI_U16 tsinfo_ack_pol: 2; + tANI_U8 tsinfo_rsvd: 7; + tANI_U8 burst_size_defn: 1; + tANI_U16 size: 15; + tANI_U16 fixed: 1; + tANI_U16 max_msdu_size; + tANI_U32 min_service_int; + tANI_U32 max_service_int; + tANI_U32 inactivity_int; + tANI_U32 suspension_int; + tANI_U32 service_start_time; + tANI_U32 min_data_rate; + tANI_U32 mean_data_rate; + tANI_U32 peak_data_rate; + tANI_U32 burst_size; + tANI_U32 delay_bound; + tANI_U32 min_phy_rate; + tANI_U16 surplus_bw_allowance; + tANI_U16 medium_time; +} tDot11fIEWMMTSPEC; + +#define DOT11F_EID_WMMTSPEC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMTSPEC_MIN_LEN ( 61 ) + +#define DOT11F_IE_WMMTSPEC_MAX_LEN ( 61 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMTSPEC*); + +tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal, tDot11fIEWMMTSPEC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMTSPEC(tpAniSirGlobal, tDot11fIEWMMTSPEC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 197 (0xc5) +typedef struct sDot11fIEAID { + tANI_U8 present; + tANI_U16 assocId; +} tDot11fIEAID; + +#define DOT11F_EID_AID ( 197 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_AID_MIN_LEN ( 2 ) + +#define DOT11F_IE_AID_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAID(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAID*); + +tANI_U32 dot11fPackIeAID(tpAniSirGlobal, tDot11fIEAID*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAID(tpAniSirGlobal, tDot11fIEAID*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x0a, 0xf5} +typedef struct sDot11fIEAirgo { + tANI_U8 present; + tDot11fIEPropSuppRates PropSuppRates; + tDot11fIEAPName APName; + tDot11fIEHCF HCF; + tDot11fIEWDS WDS; + tDot11fIEBPIndicator BPIndicator; + tDot11fIELoadInfo LoadInfo; + tDot11fIELoadBalance LoadBalance; + tDot11fIEPropAssocType PropAssocType; + tDot11fIELLAttr LLAttr; + tDot11fIEPropCapability PropCapability; + tDot11fIEVersion Version; + tDot11fIEPropEDCAParams PropEDCAParams; + tDot11fIETitan Titan; + tDot11fIEPropChannSwitchAnn PropChannSwitchAnn; + tDot11fIEPropQuietBSS PropQuietBSS; + tDot11fIETriggerStaBgScan TriggerStaBgScan; + tDot11fIETaurus Taurus; +} tDot11fIEAirgo; + +#define DOT11F_EID_AIRGO ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_AIRGO_MIN_LEN ( 3 ) + +#define DOT11F_IE_AIRGO_MAX_LEN ( 230 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeAirgo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEAirgo*); + +tANI_U32 dot11fPackIeAirgo(tpAniSirGlobal, tDot11fIEAirgo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEAirgo(tpAniSirGlobal, tDot11fIEAirgo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 4 (0x04) +typedef struct sDot11fIECFParams { + tANI_U8 present; + tANI_U8 cfp_count; + tANI_U8 cfp_period; + tANI_U16 cfp_maxduration; + tANI_U16 cfp_durremaining; +} tDot11fIECFParams; + +#define DOT11F_EID_CFPARAMS ( 4 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CFPARAMS_MIN_LEN ( 6 ) + +#define DOT11F_IE_CFPARAMS_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeCFParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIECFParams*); + +tANI_U32 dot11fPackIeCFParams(tpAniSirGlobal, tDot11fIECFParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIECFParams(tpAniSirGlobal, tDot11fIECFParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 16 (0x10) +typedef struct sDot11fIEChallengeText { + tANI_U8 present; + tANI_U8 num_text; + tANI_U8 text[253]; +} tDot11fIEChallengeText; + +#define DOT11F_EID_CHALLENGETEXT ( 16 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CHALLENGETEXT_MIN_LEN ( 1 ) + +#define DOT11F_IE_CHALLENGETEXT_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeChallengeText(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEChallengeText*); + +tANI_U32 dot11fPackIeChallengeText(tpAniSirGlobal, tDot11fIEChallengeText*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEChallengeText(tpAniSirGlobal, tDot11fIEChallengeText*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 37 (0x25) +typedef struct sDot11fIEChanSwitchAnn { + tANI_U8 present; + tANI_U8 switchMode; + tANI_U8 newChannel; + tANI_U8 switchCount; +} tDot11fIEChanSwitchAnn; + +#define DOT11F_EID_CHANSWITCHANN ( 37 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_CHANSWITCHANN_MIN_LEN ( 3 ) + +#define DOT11F_IE_CHANSWITCHANN_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeChanSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEChanSwitchAnn*); + +tANI_U32 dot11fPackIeChanSwitchAnn(tpAniSirGlobal, tDot11fIEChanSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEChanSwitchAnn(tpAniSirGlobal, tDot11fIEChanSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 7 (0x07) +typedef struct sDot11fIECountry { + tANI_U8 present; + tANI_U8 country[3]; + tANI_U8 num_triplets; + tANI_U8 triplets[84][3]; +} tDot11fIECountry; + +#define DOT11F_EID_COUNTRY ( 7 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_COUNTRY_MIN_LEN ( 3 ) + +#define DOT11F_IE_COUNTRY_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeCountry(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIECountry*); + +tANI_U32 dot11fPackIeCountry(tpAniSirGlobal, tDot11fIECountry*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIECountry(tpAniSirGlobal, tDot11fIECountry*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 3 (0x03) +typedef struct sDot11fIEDSParams { + tANI_U8 present; + tANI_U8 curr_channel; +} tDot11fIEDSParams; + +#define DOT11F_EID_DSPARAMS ( 3 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_DSPARAMS_MIN_LEN ( 1 ) + +#define DOT11F_IE_DSPARAMS_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeDSParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEDSParams*); + +tANI_U32 dot11fPackIeDSParams(tpAniSirGlobal, tDot11fIEDSParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEDSParams(tpAniSirGlobal, tDot11fIEDSParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 12 (0x0c) +typedef struct sDot11fIEEDCAParamSet { + tANI_U8 present; + tANI_U8 qos; + tANI_U8 reserved; + tANI_U8 acbe_aifsn: 4; + tANI_U8 acbe_acm: 1; + tANI_U8 acbe_aci: 2; + tANI_U8 unused1: 1; + tANI_U8 acbe_acwmin: 4; + tANI_U8 acbe_acwmax: 4; + tANI_U16 acbe_txoplimit; + tANI_U8 acbk_aifsn: 4; + tANI_U8 acbk_acm: 1; + tANI_U8 acbk_aci: 2; + tANI_U8 unused2: 1; + tANI_U8 acbk_acwmin: 4; + tANI_U8 acbk_acwmax: 4; + tANI_U16 acbk_txoplimit; + tANI_U8 acvi_aifsn: 4; + tANI_U8 acvi_acm: 1; + tANI_U8 acvi_aci: 2; + tANI_U8 unused3: 1; + tANI_U8 acvi_acwmin: 4; + tANI_U8 acvi_acwmax: 4; + tANI_U16 acvi_txoplimit; + tANI_U8 acvo_aifsn: 4; + tANI_U8 acvo_acm: 1; + tANI_U8 acvo_aci: 2; + tANI_U8 unused4: 1; + tANI_U8 acvo_acwmin: 4; + tANI_U8 acvo_acwmax: 4; + tANI_U16 acvo_txoplimit; +} tDot11fIEEDCAParamSet; + +#define DOT11F_EID_EDCAPARAMSET ( 12 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EDCAPARAMSET_MIN_LEN ( 18 ) + +#define DOT11F_IE_EDCAPARAMSET_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEEDCAParamSet*); + +tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal, tDot11fIEEDCAParamSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEEDCAParamSet(tpAniSirGlobal, tDot11fIEEDCAParamSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 42 (0x2a) +typedef struct sDot11fIEERPInfo { + tANI_U8 present; + tANI_U8 non_erp_present: 1; + tANI_U8 use_prot: 1; + tANI_U8 barker_preamble: 1; + tANI_U8 unused: 5; +} tDot11fIEERPInfo; + +#define DOT11F_EID_ERPINFO ( 42 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ERPINFO_MIN_LEN ( 1 ) + +#define DOT11F_IE_ERPINFO_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeERPInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEERPInfo*); + +tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal, tDot11fIEERPInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEERPInfo(tpAniSirGlobal, tDot11fIEERPInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 156 (0x9c) {OUI 0x00, 0x40, 0x96, 0x00} +typedef struct sDot11fIEESECckmOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[20]; +} tDot11fIEESECckmOpaque; + +#define DOT11F_EID_ESECCKMOPAQUE ( 156 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESECCKMOPAQUE_MIN_LEN ( 10 ) + +#define DOT11F_IE_ESECCKMOPAQUE_MAX_LEN ( 24 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESECckmOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESECckmOpaque*); + +tANI_U32 dot11fPackIeESECckmOpaque(tpAniSirGlobal, tDot11fIEESECckmOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESECckmOpaque(tpAniSirGlobal, tDot11fIEESECckmOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x01} +typedef struct sDot11fIEESERadMgmtCap { + tANI_U8 present; + tANI_U8 mgmt_state; + tANI_U8 mbssid_mask: 3; + tANI_U8 reserved: 5; +} tDot11fIEESERadMgmtCap; + +#define DOT11F_EID_ESERADMGMTCAP ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESERADMGMTCAP_MIN_LEN ( 6 ) + +#define DOT11F_IE_ESERADMGMTCAP_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESERadMgmtCap(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESERadMgmtCap*); + +tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal, tDot11fIEESERadMgmtCap*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESERadMgmtCap(tpAniSirGlobal, tDot11fIEESERadMgmtCap*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x07} +typedef struct sDot11fIEESETrafStrmMet { + tANI_U8 present; + tANI_U8 tsid; + tANI_U8 state; + tANI_U16 msmt_interval; +} tDot11fIEESETrafStrmMet; + +#define DOT11F_EID_ESETRAFSTRMMET ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESETRAFSTRMMET_MIN_LEN ( 8 ) + +#define DOT11F_IE_ESETRAFSTRMMET_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESETrafStrmMet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESETrafStrmMet*); + +tANI_U32 dot11fPackIeESETrafStrmMet(tpAniSirGlobal, tDot11fIEESETrafStrmMet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESETrafStrmMet(tpAniSirGlobal, tDot11fIEESETrafStrmMet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x08} +typedef struct sDot11fIEESETrafStrmRateSet { + tANI_U8 present; + tANI_U8 tsid; + tANI_U8 num_tsrates; + tANI_U8 tsrates[8]; +} tDot11fIEESETrafStrmRateSet; + +#define DOT11F_EID_ESETRAFSTRMRATESET ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESETRAFSTRMRATESET_MIN_LEN ( 5 ) + +#define DOT11F_IE_ESETRAFSTRMRATESET_MAX_LEN ( 13 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESETrafStrmRateSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESETrafStrmRateSet*); + +tANI_U32 dot11fPackIeESETrafStrmRateSet(tpAniSirGlobal, tDot11fIEESETrafStrmRateSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESETrafStrmRateSet(tpAniSirGlobal, tDot11fIEESETrafStrmRateSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 150 (0x96) {OUI 0x00, 0x40, 0x96, 0x00} +typedef struct sDot11fIEESETxmitPower { + tANI_U8 present; + tANI_U8 power_limit; + tANI_U8 reserved; +} tDot11fIEESETxmitPower; + +#define DOT11F_EID_ESETXMITPOWER ( 150 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESETXMITPOWER_MIN_LEN ( 6 ) + +#define DOT11F_IE_ESETXMITPOWER_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESETxmitPower(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESETxmitPower*); + +tANI_U32 dot11fPackIeESETxmitPower(tpAniSirGlobal, tDot11fIEESETxmitPower*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESETxmitPower(tpAniSirGlobal, tDot11fIEESETxmitPower*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x40, 0x96, 0x03} +typedef struct sDot11fIEESEVersion { + tANI_U8 present; + tANI_U8 version; +} tDot11fIEESEVersion; + +#define DOT11F_EID_ESEVERSION ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_ESEVERSION_MIN_LEN ( 5 ) + +#define DOT11F_IE_ESEVERSION_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeESEVersion(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEESEVersion*); + +tANI_U32 dot11fPackIeESEVersion(tpAniSirGlobal, tDot11fIEESEVersion*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEESEVersion(tpAniSirGlobal, tDot11fIEESEVersion*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 127 (0x7f) +typedef struct sDot11fIEExtCap { + tANI_U8 present; + tANI_U8 num_bytes; + tANI_U8 bytes[9]; +} tDot11fIEExtCap; + +#define DOT11F_EID_EXTCAP ( 127 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EXTCAP_MIN_LEN ( 1 ) + +#define DOT11F_IE_EXTCAP_MAX_LEN ( 9 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeExtCap(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEExtCap*); + +tANI_U32 dot11fPackIeExtCap(tpAniSirGlobal, tDot11fIEExtCap*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEExtCap(tpAniSirGlobal, tDot11fIEExtCap*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 62 (0x3e) +typedef struct sDot11fIEExtChanSwitchAnn { + tANI_U8 present; + tANI_U8 secondaryChannelOffset; +} tDot11fIEExtChanSwitchAnn; + +#define DOT11F_EID_EXTCHANSWITCHANN ( 62 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EXTCHANSWITCHANN_MIN_LEN ( 1 ) + +#define DOT11F_IE_EXTCHANSWITCHANN_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeExtChanSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEExtChanSwitchAnn*); + +tANI_U32 dot11fPackIeExtChanSwitchAnn(tpAniSirGlobal, tDot11fIEExtChanSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEExtChanSwitchAnn(tpAniSirGlobal, tDot11fIEExtChanSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 50 (0x32) +typedef struct sDot11fIEExtSuppRates { + tANI_U8 present; + tANI_U8 num_rates; + tANI_U8 rates[12]; +} tDot11fIEExtSuppRates; + +#define DOT11F_EID_EXTSUPPRATES ( 50 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_EXTSUPPRATES_MIN_LEN ( 1 ) + +#define DOT11F_IE_EXTSUPPRATES_MAX_LEN ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeExtSuppRates(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEExtSuppRates*); + +tANI_U32 dot11fPackIeExtSuppRates(tpAniSirGlobal, tDot11fIEExtSuppRates*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEExtSuppRates(tpAniSirGlobal, tDot11fIEExtSuppRates*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 2 (0x02) +typedef struct sDot11fIEFHParamSet { + tANI_U8 present; + tANI_U16 dwell_time; + tANI_U8 hop_set; + tANI_U8 hop_pattern; + tANI_U8 hop_index; +} tDot11fIEFHParamSet; + +#define DOT11F_EID_FHPARAMSET ( 2 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FHPARAMSET_MIN_LEN ( 5 ) + +#define DOT11F_IE_FHPARAMSET_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFHParamSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFHParamSet*); + +tANI_U32 dot11fPackIeFHParamSet(tpAniSirGlobal, tDot11fIEFHParamSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFHParamSet(tpAniSirGlobal, tDot11fIEFHParamSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 8 (0x08) +typedef struct sDot11fIEFHParams { + tANI_U8 present; + tANI_U8 radix; + tANI_U8 nchannels; +} tDot11fIEFHParams; + +#define DOT11F_EID_FHPARAMS ( 8 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FHPARAMS_MIN_LEN ( 2 ) + +#define DOT11F_IE_FHPARAMS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFHParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFHParams*); + +tANI_U32 dot11fPackIeFHParams(tpAniSirGlobal, tDot11fIEFHParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFHParams(tpAniSirGlobal, tDot11fIEFHParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 9 (0x09) +typedef struct sDot11fIEFHPattTable { + tANI_U8 present; + tANI_U8 flag; + tANI_U8 nsets; + tANI_U8 modulus; + tANI_U8 offset; + tANI_U8 num_randtable; + tANI_U8 randtable[251]; +} tDot11fIEFHPattTable; + +#define DOT11F_EID_FHPATTTABLE ( 9 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FHPATTTABLE_MIN_LEN ( 4 ) + +#define DOT11F_IE_FHPATTTABLE_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFHPattTable(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFHPattTable*); + +tANI_U32 dot11fPackIeFHPattTable(tpAniSirGlobal, tDot11fIEFHPattTable*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFHPattTable(tpAniSirGlobal, tDot11fIEFHPattTable*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 55 (0x37) +typedef struct sDot11fIEFTInfo { + tANI_U8 present; + tANI_U16 reserved: 8; + tANI_U16 IECount: 8; + tANI_U8 MIC[16]; + tANI_U8 Anonce[32]; + tANI_U8 Snonce[32]; + tDot11fIER1KH_ID R1KH_ID; + tDot11fIEGTK GTK; + tDot11fIER0KH_ID R0KH_ID; + tDot11fIEIGTK IGTK; +} tDot11fIEFTInfo; + +#define DOT11F_EID_FTINFO ( 55 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_FTINFO_MIN_LEN ( 82 ) + +#define DOT11F_IE_FTINFO_MAX_LEN ( 220 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeFTInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEFTInfo*); + +tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal, tDot11fIEFTInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEFTInfo(tpAniSirGlobal, tDot11fIEFTInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 72 (0x48) +typedef struct sDot11fIEHT2040BSSCoexistence { + tANI_U8 present; + tANI_U8 infoRequest: 1; + tANI_U8 fortyMHzIntolerant: 1; + tANI_U8 twentyMHzBssWidthReq: 1; + tANI_U8 obssScanExemptionReq: 1; + tANI_U8 obssScanExemptionGrant: 1; + tANI_U8 unused: 3; +} tDot11fIEHT2040BSSCoexistence; + +#define DOT11F_EID_HT2040BSSCOEXISTENCE ( 72 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HT2040BSSCOEXISTENCE_MIN_LEN ( 1 ) + +#define DOT11F_IE_HT2040BSSCOEXISTENCE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHT2040BSSCoexistence(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHT2040BSSCoexistence*); + +tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal, tDot11fIEHT2040BSSCoexistence*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHT2040BSSCoexistence(tpAniSirGlobal, tDot11fIEHT2040BSSCoexistence*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 73 (0x49) +typedef struct sDot11fIEHT2040BSSIntolerantReport { + tANI_U8 present; + tANI_U8 operatingClass; + tANI_U8 num_channelList; + tANI_U8 channelList[50]; +} tDot11fIEHT2040BSSIntolerantReport; + +#define DOT11F_EID_HT2040BSSINTOLERANTREPORT ( 73 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HT2040BSSINTOLERANTREPORT_MIN_LEN ( 1 ) + +#define DOT11F_IE_HT2040BSSINTOLERANTREPORT_MAX_LEN ( 51 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHT2040BSSIntolerantReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHT2040BSSIntolerantReport*); + +tANI_U32 dot11fPackIeHT2040BSSIntolerantReport(tpAniSirGlobal, tDot11fIEHT2040BSSIntolerantReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHT2040BSSIntolerantReport(tpAniSirGlobal, tDot11fIEHT2040BSSIntolerantReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 45 (0x2d) +typedef struct sDot11fIEHTCaps { + tANI_U8 present; + tANI_U16 advCodingCap: 1; + tANI_U16 supportedChannelWidthSet: 1; + tANI_U16 mimoPowerSave: 2; + tANI_U16 greenField: 1; + tANI_U16 shortGI20MHz: 1; + tANI_U16 shortGI40MHz: 1; + tANI_U16 txSTBC: 1; + tANI_U16 rxSTBC: 2; + tANI_U16 delayedBA: 1; + tANI_U16 maximalAMSDUsize: 1; + tANI_U16 dsssCckMode40MHz: 1; + tANI_U16 psmp: 1; + tANI_U16 stbcControlFrame: 1; + tANI_U16 lsigTXOPProtection: 1; + tANI_U8 maxRxAMPDUFactor: 2; + tANI_U8 mpduDensity: 3; + tANI_U8 reserved1: 3; + tANI_U8 supportedMCSSet[16]; + tANI_U16 pco: 1; + tANI_U16 transitionTime: 2; + tANI_U16 reserved2: 5; + tANI_U16 mcsFeedback: 2; + tANI_U16 reserved3: 6; + tANI_U32 txBF: 1; + tANI_U32 rxStaggeredSounding: 1; + tANI_U32 txStaggeredSounding: 1; + tANI_U32 rxZLF: 1; + tANI_U32 txZLF: 1; + tANI_U32 implicitTxBF: 1; + tANI_U32 calibration: 2; + tANI_U32 explicitCSITxBF: 1; + tANI_U32 explicitUncompressedSteeringMatrix: 1; + tANI_U32 explicitBFCSIFeedback: 3; + tANI_U32 explicitUncompressedSteeringMatrixFeedback: 3; + tANI_U32 explicitCompressedSteeringMatrixFeedback: 3; + tANI_U32 csiNumBFAntennae: 2; + tANI_U32 uncompressedSteeringMatrixBFAntennae: 2; + tANI_U32 compressedSteeringMatrixBFAntennae: 2; + tANI_U32 reserved4: 7; + tANI_U8 antennaSelection: 1; + tANI_U8 explicitCSIFeedbackTx: 1; + tANI_U8 antennaIndicesFeedbackTx: 1; + tANI_U8 explicitCSIFeedback: 1; + tANI_U8 antennaIndicesFeedback: 1; + tANI_U8 rxAS: 1; + tANI_U8 txSoundingPPDUs: 1; + tANI_U8 reserved5: 1; + tANI_U8 num_rsvd; + tANI_U8 rsvd[32]; +} tDot11fIEHTCaps; + +#define DOT11F_EID_HTCAPS ( 45 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HTCAPS_MIN_LEN ( 26 ) + +#define DOT11F_IE_HTCAPS_MAX_LEN ( 58 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHTCaps*); + +tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal, tDot11fIEHTCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHTCaps(tpAniSirGlobal, tDot11fIEHTCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 61 (0x3d) +typedef struct sDot11fIEHTInfo { + tANI_U8 present; + tANI_U8 primaryChannel; + tANI_U8 secondaryChannelOffset: 2; + tANI_U8 recommendedTxWidthSet: 1; + tANI_U8 rifsMode: 1; + tANI_U8 controlledAccessOnly: 1; + tANI_U8 serviceIntervalGranularity: 3; + tANI_U16 opMode: 2; + tANI_U16 nonGFDevicesPresent: 1; + tANI_U16 transmitBurstLimit: 1; + tANI_U16 obssNonHTStaPresent: 1; + tANI_U16 reserved: 11; + tANI_U16 basicSTBCMCS: 7; + tANI_U16 dualCTSProtection: 1; + tANI_U16 secondaryBeacon: 1; + tANI_U16 lsigTXOPProtectionFullSupport: 1; + tANI_U16 pcoActive: 1; + tANI_U16 pcoPhase: 1; + tANI_U16 reserved2: 4; + tANI_U8 basicMCSSet[16]; + tANI_U8 num_rsvd; + tANI_U8 rsvd[32]; +} tDot11fIEHTInfo; + +#define DOT11F_EID_HTINFO ( 61 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HTINFO_MIN_LEN ( 22 ) + +#define DOT11F_IE_HTINFO_MAX_LEN ( 54 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEHTInfo*); + +tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal, tDot11fIEHTInfo*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEHTInfo(tpAniSirGlobal, tDot11fIEHTInfo*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 6 (0x06) +typedef struct sDot11fIEIBSSParams { + tANI_U8 present; + tANI_U16 atim; +} tDot11fIEIBSSParams; + +#define DOT11F_EID_IBSSPARAMS ( 6 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_IBSSPARAMS_MIN_LEN ( 2 ) + +#define DOT11F_IE_IBSSPARAMS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeIBSSParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEIBSSParams*); + +tANI_U32 dot11fPackIeIBSSParams(tpAniSirGlobal, tDot11fIEIBSSParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEIBSSParams(tpAniSirGlobal, tDot11fIEIBSSParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 101 (0x65) +typedef struct sDot11fIELinkIdentifier { + tANI_U8 present; + tANI_U8 bssid[6]; + tANI_U8 InitStaAddr[6]; + tANI_U8 RespStaAddr[6]; +} tDot11fIELinkIdentifier; + +#define DOT11F_EID_LINKIDENTIFIER ( 101 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_LINKIDENTIFIER_MIN_LEN ( 18 ) + +#define DOT11F_IE_LINKIDENTIFIER_MAX_LEN ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeLinkIdentifier(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIELinkIdentifier*); + +tANI_U32 dot11fPackIeLinkIdentifier(tpAniSirGlobal, tDot11fIELinkIdentifier*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIELinkIdentifier(tpAniSirGlobal, tDot11fIELinkIdentifier*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 39 (0x27) +typedef struct sDot11fIEMeasurementReport { + tANI_U8 present; + tANI_U8 token; + tANI_U8 late: 1; + tANI_U8 incapable: 1; + tANI_U8 refused: 1; + tANI_U8 unused: 5; + tANI_U8 type; + union + { + struct + { + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 bss: 1; + tANI_U8 ofdm_preamble: 1; + tANI_U8 unid_signal: 1; + tANI_U8 rader: 1; + tANI_U8 unmeasured: 1; + tANI_U8 unused: 3; + } Basic; /* type = 0 */ + struct + { + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 cca_busy_fraction; + } CCA; /* type = 1 */ + struct + { + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 rpi0_density; + tANI_U8 rpi1_density; + tANI_U8 rpi2_density; + tANI_U8 rpi3_density; + tANI_U8 rpi4_density; + tANI_U8 rpi5_density; + tANI_U8 rpi6_density; + tANI_U8 rpi7_density; + } RPIHistogram; /* type = 2 */ + struct + { + tANI_U8 regClass; + tANI_U8 channel; + tDOT11F_U64 meas_start_time; + tANI_U16 meas_duration; + tANI_U8 condensed_PHY: 7; + tANI_U8 reported_frame_type: 1; + tANI_U8 RCPI; + tANI_U8 RSNI; + tANI_U8 BSSID[6]; + tANI_U8 antenna_id; + tANI_U32 parent_TSF; + tDot11fIEBeaconReportFrmBody BeaconReportFrmBody; + } Beacon; /* type = 5 */ + } report; +} tDot11fIEMeasurementReport; + +#define DOT11F_EID_MEASUREMENTREPORT ( 39 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MEASUREMENTREPORT_MIN_LEN ( 3 ) + +#define DOT11F_IE_MEASUREMENTREPORT_MAX_LEN ( 29 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMeasurementReport*); + +tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal, tDot11fIEMeasurementReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMeasurementReport(tpAniSirGlobal, tDot11fIEMeasurementReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 38 (0x26) +typedef struct sDot11fIEMeasurementRequest { + tANI_U8 present; + tANI_U8 measurement_token; + tANI_U8 parallel: 1; + tANI_U8 enable: 1; + tANI_U8 request: 1; + tANI_U8 report: 1; + tANI_U8 durationMandatory: 1; + tANI_U8 unused: 3; + tANI_U8 measurement_type; + union + { + struct + { + tANI_U8 channel_no; + tANI_U8 meas_start_time[8]; + tANI_U16 meas_duration; + } Basic; /* measurement_type = 0 */ + struct + { + tANI_U8 channel_no; + tANI_U8 meas_start_time[8]; + tANI_U16 meas_duration; + } CCA; /* measurement_type = 1 */ + struct + { + tANI_U8 channel_no; + tANI_U8 meas_start_time[8]; + tANI_U16 meas_duration; + } RPIHistogram; /* measurement_type = 2 */ + struct + { + tANI_U8 regClass; + tANI_U8 channel; + tANI_U16 randomization; + tANI_U16 meas_duration; + tANI_U8 meas_mode; + tANI_U8 BSSID[6]; + tDot11fIESSID SSID; + tDot11fIEBeaconReporting BeaconReporting; + tDot11fIEBcnReportingDetail BcnReportingDetail; + tDot11fIERequestedInfo RequestedInfo; + tANI_U16 num_APChannelReport; + tDot11fIEAPChannelReport APChannelReport[2]; + } Beacon; /* measurement_type = 5 */ + } measurement_request; +} tDot11fIEMeasurementRequest; + +#define DOT11F_EID_MEASUREMENTREQUEST ( 38 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN ( 14 ) + +#define DOT11F_IE_MEASUREMENTREQUEST_MAX_LEN ( 16 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMeasurementRequest(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMeasurementRequest*); + +tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal, tDot11fIEMeasurementRequest*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMeasurementRequest(tpAniSirGlobal, tDot11fIEMeasurementRequest*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 54 (0x36) +typedef struct sDot11fIEMobilityDomain { + tANI_U8 present; + tANI_U16 MDID; + tANI_U8 overDSCap: 1; + tANI_U8 resourceReqCap: 1; + tANI_U8 reserved: 6; +} tDot11fIEMobilityDomain; + +#define DOT11F_EID_MOBILITYDOMAIN ( 54 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_MOBILITYDOMAIN_MIN_LEN ( 3 ) + +#define DOT11F_IE_MOBILITYDOMAIN_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeMobilityDomain(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEMobilityDomain*); + +tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal, tDot11fIEMobilityDomain*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEMobilityDomain(tpAniSirGlobal, tDot11fIEMobilityDomain*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 52 (0x34) +typedef struct sDot11fIENeighborReport { + tANI_U8 present; + tANI_U8 bssid[6]; + tANI_U8 APReachability: 2; + tANI_U8 Security: 1; + tANI_U8 KeyScope: 1; + tANI_U8 SpecMgmtCap: 1; + tANI_U8 QosCap: 1; + tANI_U8 apsd: 1; + tANI_U8 rrm: 1; + tANI_U8 DelayedBA: 1; + tANI_U8 ImmBA: 1; + tANI_U8 MobilityDomain: 1; + tANI_U8 reserved: 5; + tANI_U16 reserved1; + tANI_U8 regulatoryClass; + tANI_U8 channel; + tANI_U8 PhyType; + tDot11fIETSFInfo TSFInfo; + tDot11fIECondensedCountryStr CondensedCountryStr; + tDot11fIEMeasurementPilot MeasurementPilot; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMultiBssid MultiBssid; +} tDot11fIENeighborReport; + +#define DOT11F_EID_NEIGHBORREPORT ( 52 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_NEIGHBORREPORT_MIN_LEN ( 13 ) + +#define DOT11F_IE_NEIGHBORREPORT_MAX_LEN ( 546 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIENeighborReport*); + +tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal, tDot11fIENeighborReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIENeighborReport(tpAniSirGlobal, tDot11fIENeighborReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 74 (0x4a) +typedef struct sDot11fIEOBSSScanParameters { + tANI_U8 present; + tANI_U16 obssScanPassiveDwell; + tANI_U16 obssScanActiveDwell; + tANI_U16 bssChannelWidthTriggerScanInterval; + tANI_U16 obssScanPassiveTotalPerChannel; + tANI_U16 obssScanActiveTotalPerChannel; + tANI_U16 bssWidthChannelTransitionDelayFactor; + tANI_U16 obssScanActivityThreshold; +} tDot11fIEOBSSScanParameters; + +#define DOT11F_EID_OBSSSCANPARAMETERS ( 74 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_OBSSSCANPARAMETERS_MIN_LEN ( 14 ) + +#define DOT11F_IE_OBSSSCANPARAMETERS_MAX_LEN ( 14 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeOBSSScanParameters(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEOBSSScanParameters*); + +tANI_U32 dot11fPackIeOBSSScanParameters(tpAniSirGlobal, tDot11fIEOBSSScanParameters*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEOBSSScanParameters(tpAniSirGlobal, tDot11fIEOBSSScanParameters*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 199 (0xc7) +typedef struct sDot11fIEOperatingMode { + tANI_U8 present; + tANI_U8 chanWidth: 2; + tANI_U8 reserved: 2; + tANI_U8 rxNSS: 3; + tANI_U8 rxNSSType: 1; +} tDot11fIEOperatingMode; + +#define DOT11F_EID_OPERATINGMODE ( 199 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_OPERATINGMODE_MIN_LEN ( 1 ) + +#define DOT11F_IE_OPERATINGMODE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeOperatingMode(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEOperatingMode*); + +tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal, tDot11fIEOperatingMode*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEOperatingMode(tpAniSirGlobal, tDot11fIEOperatingMode*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PAssocReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; +} tDot11fIEP2PAssocReq; + +#define DOT11F_EID_P2PASSOCREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PASSOCREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PASSOCREQ_MAX_LEN ( 71 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PAssocReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PAssocReq*); + +tANI_U32 dot11fPackIeP2PAssocReq(tpAniSirGlobal, tDot11fIEP2PAssocReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PAssocReq(tpAniSirGlobal, tDot11fIEP2PAssocReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PAssocRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; +} tDot11fIEP2PAssocRes; + +#define DOT11F_EID_P2PASSOCRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PASSOCRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PASSOCRES_MAX_LEN ( 15 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PAssocRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PAssocRes*); + +tANI_U32 dot11fPackIeP2PAssocRes(tpAniSirGlobal, tDot11fIEP2PAssocRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PAssocRes(tpAniSirGlobal, tDot11fIEP2PAssocRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PBeacon { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; +} tDot11fIEP2PBeacon; + +#define DOT11F_EID_P2PBEACON ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PBEACON_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PBEACON_MAX_LEN ( 59 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PBeacon(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PBeacon*); + +tANI_U32 dot11fPackIeP2PBeacon(tpAniSirGlobal, tDot11fIEP2PBeacon*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PBeacon(tpAniSirGlobal, tDot11fIEP2PBeacon*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PBeaconProbeRes { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupInfo P2PGroupInfo; +} tDot11fIEP2PBeaconProbeRes; + +#define DOT11F_EID_P2PBEACONPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PBEACONPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PBEACONPROBERES_MAX_LEN ( 1148 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PBeaconProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PBeaconProbeRes*); + +tANI_U32 dot11fPackIeP2PBeaconProbeRes(tpAniSirGlobal, tDot11fIEP2PBeaconProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PBeaconProbeRes(tpAniSirGlobal, tDot11fIEP2PBeaconProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDeAuth { + tANI_U8 present; + tDot11fTLVMinorReasonCode MinorReasonCode; +} tDot11fIEP2PDeAuth; + +#define DOT11F_EID_P2PDEAUTH ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDEAUTH_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDEAUTH_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDeAuth(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDeAuth*); + +tANI_U32 dot11fPackIeP2PDeAuth(tpAniSirGlobal, tDot11fIEP2PDeAuth*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDeAuth(tpAniSirGlobal, tDot11fIEP2PDeAuth*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDeviceDiscoverabilityReq { + tANI_U8 present; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PDeviceDiscoverabilityReq; + +#define DOT11F_EID_P2PDEVICEDISCOVERABILITYREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYREQ_MAX_LEN ( 54 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDeviceDiscoverabilityReq*); + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityReq(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDeviceDiscoverabilityRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; +} tDot11fIEP2PDeviceDiscoverabilityRes; + +#define DOT11F_EID_P2PDEVICEDISCOVERABILITYRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDEVICEDISCOVERABILITYRES_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDeviceDiscoverabilityRes*); + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityRes(tpAniSirGlobal, tDot11fIEP2PDeviceDiscoverabilityRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PDisAssoc { + tANI_U8 present; + tDot11fTLVMinorReasonCode MinorReasonCode; +} tDot11fIEP2PDisAssoc; + +#define DOT11F_EID_P2PDISASSOC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PDISASSOC_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PDISASSOC_MAX_LEN ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PDisAssoc(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PDisAssoc*); + +tANI_U32 dot11fPackIeP2PDisAssoc(tpAniSirGlobal, tDot11fIEP2PDisAssoc*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PDisAssoc(tpAniSirGlobal, tDot11fIEP2PDisAssoc*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PGONegCnf { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PGONegCnf; + +#define DOT11F_EID_P2PGONEGCNF ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGCNF_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGCNF_MAX_LEN ( 319 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegCnf(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegCnf*); + +tANI_U32 dot11fPackIeP2PGONegCnf(tpAniSirGlobal, tDot11fIEP2PGONegCnf*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegCnf(tpAniSirGlobal, tDot11fIEP2PGONegCnf*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PGONegReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVGOIntent GOIntent; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVListenChannel ListenChannel; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVIntendedP2PInterfaceAddress IntendedP2PInterfaceAddress; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVOperatingChannel OperatingChannel; +} tDot11fIEP2PGONegReq; + +#define DOT11F_EID_P2PGONEGREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGREQ_MAX_LEN ( 362 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegReq*); + +tANI_U32 dot11fPackIeP2PGONegReq(tpAniSirGlobal, tDot11fIEP2PGONegReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegReq(tpAniSirGlobal, tDot11fIEP2PGONegReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PGONegRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVGOIntent GOIntent; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVIntendedP2PInterfaceAddress IntendedP2PInterfaceAddress; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PGONegRes; + +#define DOT11F_EID_P2PGONEGRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGRES_MAX_LEN ( 392 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegRes*); + +tANI_U32 dot11fPackIeP2PGONegRes(tpAniSirGlobal, tDot11fIEP2PGONegRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegRes(tpAniSirGlobal, tDot11fIEP2PGONegRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEP2PGONegWPS { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVDevicePasswordID DevicePasswordID; +} tDot11fIEP2PGONegWPS; + +#define DOT11F_EID_P2PGONEGWPS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PGONEGWPS_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PGONEGWPS_MAX_LEN ( 15 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PGONegWPS(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PGONegWPS*); + +tANI_U32 dot11fPackIeP2PGONegWPS(tpAniSirGlobal, tDot11fIEP2PGONegWPS*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PGONegWPS(tpAniSirGlobal, tDot11fIEP2PGONegWPS*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} +typedef struct sDot11fIEP2PIEOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEP2PIEOpaque; + +#define DOT11F_EID_P2PIEOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PIEOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_P2PIEOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PIEOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PIEOpaque*); + +tANI_U32 dot11fPackIeP2PIEOpaque(tpAniSirGlobal, tDot11fIEP2PIEOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PIEOpaque(tpAniSirGlobal, tDot11fIEP2PIEOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PInvitationReq { + tANI_U8 present; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVInvitationFlags InvitationFlags; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVP2PGroupBssid P2PGroupBssid; + tDot11fTLVChannelList ChannelList; + tDot11fTLVP2PGroupId P2PGroupId; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; +} tDot11fIEP2PInvitationReq; + +#define DOT11F_EID_P2PINVITATIONREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PINVITATIONREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PINVITATIONREQ_MAX_LEN ( 383 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PInvitationReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PInvitationReq*); + +tANI_U32 dot11fPackIeP2PInvitationReq(tpAniSirGlobal, tDot11fIEP2PInvitationReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PInvitationReq(tpAniSirGlobal, tDot11fIEP2PInvitationReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PInvitationRes { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVConfigurationTimeout ConfigurationTimeout; + tDot11fTLVOperatingChannel OperatingChannel; + tDot11fTLVP2PGroupBssid P2PGroupBssid; + tDot11fTLVChannelList ChannelList; +} tDot11fIEP2PInvitationRes; + +#define DOT11F_EID_P2PINVITATIONRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PINVITATIONRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PINVITATIONRES_MAX_LEN ( 287 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PInvitationRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PInvitationRes*); + +tANI_U32 dot11fPackIeP2PInvitationRes(tpAniSirGlobal, tDot11fIEP2PInvitationRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PInvitationRes(tpAniSirGlobal, tDot11fIEP2PInvitationRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PNoticeOfAbsence { + tANI_U8 present; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; +} tDot11fIEP2PNoticeOfAbsence; + +#define DOT11F_EID_P2PNOTICEOFABSENCE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PNOTICEOFABSENCE_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PNOTICEOFABSENCE_MAX_LEN ( 45 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PNoticeOfAbsence(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PNoticeOfAbsence*); + +tANI_U32 dot11fPackIeP2PNoticeOfAbsence(tpAniSirGlobal, tDot11fIEP2PNoticeOfAbsence*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PNoticeOfAbsence(tpAniSirGlobal, tDot11fIEP2PNoticeOfAbsence*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PPresenceResponse { + tANI_U8 present; + tDot11fTLVP2PStatus P2PStatus; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; +} tDot11fIEP2PPresenceResponse; + +#define DOT11F_EID_P2PPRESENCERESPONSE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPRESENCERESPONSE_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPRESENCERESPONSE_MAX_LEN ( 49 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PPresenceResponse(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PPresenceResponse*); + +tANI_U32 dot11fPackIeP2PPresenceResponse(tpAniSirGlobal, tDot11fIEP2PPresenceResponse*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PPresenceResponse(tpAniSirGlobal, tDot11fIEP2PPresenceResponse*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PProbeReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceId P2PDeviceId; + tDot11fTLVListenChannel ListenChannel; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVOperatingChannel OperatingChannel; +} tDot11fIEP2PProbeReq; + +#define DOT11F_EID_P2PPROBEREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPROBEREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPROBEREQ_MAX_LEN ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PProbeReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PProbeReq*); + +tANI_U32 dot11fPackIeP2PProbeReq(tpAniSirGlobal, tDot11fIEP2PProbeReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PProbeReq(tpAniSirGlobal, tDot11fIEP2PProbeReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PProbeRes { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVExtendedListenTiming ExtendedListenTiming; + tDot11fTLVNoticeOfAbsence NoticeOfAbsence; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupInfo P2PGroupInfo; +} tDot11fIEP2PProbeRes; + +#define DOT11F_EID_P2PPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPROBERES_MAX_LEN ( 1139 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PProbeRes*); + +tANI_U32 dot11fPackIeP2PProbeRes(tpAniSirGlobal, tDot11fIEP2PProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PProbeRes(tpAniSirGlobal, tDot11fIEP2PProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x09} (Multi-IE) +typedef struct sDot11fIEP2PProvisionDiscoveryReq { + tANI_U8 present; + tDot11fTLVP2PCapability P2PCapability; + tDot11fTLVP2PDeviceInfo P2PDeviceInfo; + tDot11fTLVP2PGroupId P2PGroupId; +} tDot11fIEP2PProvisionDiscoveryReq; + +#define DOT11F_EID_P2PPROVISIONDISCOVERYREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PPROVISIONDISCOVERYREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PPROVISIONDISCOVERYREQ_MAX_LEN ( 105 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PProvisionDiscoveryReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PProvisionDiscoveryReq*); + +tANI_U32 dot11fPackIeP2PProvisionDiscoveryReq(tpAniSirGlobal, tDot11fIEP2PProvisionDiscoveryReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PProvisionDiscoveryReq(tpAniSirGlobal, tDot11fIEP2PProvisionDiscoveryReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEP2PWSCProvisionDiscoveryRes { + tANI_U8 present; + tDot11fTLVConfigMethods ConfigMethods; +} tDot11fIEP2PWSCProvisionDiscoveryRes; + +#define DOT11F_EID_P2PWSCPROVISIONDISCOVERYRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_P2PWSCPROVISIONDISCOVERYRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_P2PWSCPROVISIONDISCOVERYRES_MAX_LEN ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEP2PWSCProvisionDiscoveryRes*); + +tANI_U32 dot11fPackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal, tDot11fIEP2PWSCProvisionDiscoveryRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(tpAniSirGlobal, tDot11fIEP2PWSCProvisionDiscoveryRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 105 (0x69) +typedef struct sDot11fIEPTIControl { + tANI_U8 present; + tANI_U8 tid; + tANI_U16 sequence_control; +} tDot11fIEPTIControl; + +#define DOT11F_EID_PTICONTROL ( 105 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PTICONTROL_MIN_LEN ( 3 ) + +#define DOT11F_IE_PTICONTROL_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePTIControl(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPTIControl*); + +tANI_U32 dot11fPackIePTIControl(tpAniSirGlobal, tDot11fIEPTIControl*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPTIControl(tpAniSirGlobal, tDot11fIEPTIControl*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 106 (0x6a) +typedef struct sDot11fIEPUBufferStatus { + tANI_U8 present; + tANI_U8 ac_bk_traffic_aval: 1; + tANI_U8 ac_be_traffic_aval: 1; + tANI_U8 ac_vi_traffic_aval: 1; + tANI_U8 ac_vo_traffic_aval: 1; + tANI_U8 reserved: 4; +} tDot11fIEPUBufferStatus; + +#define DOT11F_EID_PUBUFFERSTATUS ( 106 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_PUBUFFERSTATUS_MIN_LEN ( 1 ) + +#define DOT11F_IE_PUBUFFERSTATUS_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePUBufferStatus(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPUBufferStatus*); + +tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal, tDot11fIEPUBufferStatus*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPUBufferStatus(tpAniSirGlobal, tDot11fIEPUBufferStatus*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 33 (0x21) +typedef struct sDot11fIEPowerCaps { + tANI_U8 present; + tANI_U8 minTxPower; + tANI_U8 maxTxPower; +} tDot11fIEPowerCaps; + +#define DOT11F_EID_POWERCAPS ( 33 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_POWERCAPS_MIN_LEN ( 2 ) + +#define DOT11F_IE_POWERCAPS_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePowerCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPowerCaps*); + +tANI_U32 dot11fPackIePowerCaps(tpAniSirGlobal, tDot11fIEPowerCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPowerCaps(tpAniSirGlobal, tDot11fIEPowerCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 32 (0x20) +typedef struct sDot11fIEPowerConstraints { + tANI_U8 present; + tANI_U8 localPowerConstraints; +} tDot11fIEPowerConstraints; + +#define DOT11F_EID_POWERCONSTRAINTS ( 32 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_POWERCONSTRAINTS_MIN_LEN ( 1 ) + +#define DOT11F_IE_POWERCONSTRAINTS_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIePowerConstraints(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEPowerConstraints*); + +tANI_U32 dot11fPackIePowerConstraints(tpAniSirGlobal, tDot11fIEPowerConstraints*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEPowerConstraints(tpAniSirGlobal, tDot11fIEPowerConstraints*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 11 (0x0b) +typedef struct sDot11fIEQBSSLoad { + tANI_U8 present; + tANI_U16 stacount; + tANI_U8 chautil; + tANI_U16 avail; +} tDot11fIEQBSSLoad; + +#define DOT11F_EID_QBSSLOAD ( 11 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QBSSLOAD_MIN_LEN ( 5 ) + +#define DOT11F_IE_QBSSLOAD_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQBSSLoad(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQBSSLoad*); + +tANI_U32 dot11fPackIeQBSSLoad(tpAniSirGlobal, tDot11fIEQBSSLoad*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQBSSLoad(tpAniSirGlobal, tDot11fIEQBSSLoad*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 46 (0x2e) +typedef struct sDot11fIEQOSCapsAp { + tANI_U8 present; + tANI_U8 count: 4; + tANI_U8 qack: 1; + tANI_U8 qreq: 1; + tANI_U8 txopreq: 1; + tANI_U8 reserved: 1; +} tDot11fIEQOSCapsAp; + +#define DOT11F_EID_QOSCAPSAP ( 46 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QOSCAPSAP_MIN_LEN ( 1 ) + +#define DOT11F_IE_QOSCAPSAP_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQOSCapsAp(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQOSCapsAp*); + +tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal, tDot11fIEQOSCapsAp*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQOSCapsAp(tpAniSirGlobal, tDot11fIEQOSCapsAp*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 46 (0x2e) +typedef struct sDot11fIEQOSCapsStation { + tANI_U8 present; + tANI_U8 acvo_uapsd: 1; + tANI_U8 acvi_uapsd: 1; + tANI_U8 acbk_uapsd: 1; + tANI_U8 acbe_uapsd: 1; + tANI_U8 qack: 1; + tANI_U8 max_sp_length: 2; + tANI_U8 more_data_ack: 1; +} tDot11fIEQOSCapsStation; + +#define DOT11F_EID_QOSCAPSSTATION ( 46 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QOSCAPSSTATION_MIN_LEN ( 1 ) + +#define DOT11F_IE_QOSCAPSSTATION_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQOSCapsStation(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQOSCapsStation*); + +tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal, tDot11fIEQOSCapsStation*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQOSCapsStation(tpAniSirGlobal, tDot11fIEQOSCapsStation*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 110 (0x6e) +typedef struct sDot11fIEQosMapSet { + tANI_U8 present; + tANI_U8 num_dscp_exceptions; + tANI_U8 dscp_exceptions[60]; +} tDot11fIEQosMapSet; + +#define DOT11F_EID_QOSMAPSET ( 110 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QOSMAPSET_MIN_LEN ( 0 ) + +#define DOT11F_IE_QOSMAPSET_MAX_LEN ( 60 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQosMapSet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQosMapSet*); + +tANI_U32 dot11fPackIeQosMapSet(tpAniSirGlobal, tDot11fIEQosMapSet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQosMapSet(tpAniSirGlobal, tDot11fIEQosMapSet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 40 (0x28) +typedef struct sDot11fIEQuiet { + tANI_U8 present; + tANI_U8 count; + tANI_U8 period; + tANI_U16 duration; + tANI_U16 offset; +} tDot11fIEQuiet; + +#define DOT11F_EID_QUIET ( 40 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_QUIET_MIN_LEN ( 6 ) + +#define DOT11F_IE_QUIET_MAX_LEN ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeQuiet(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEQuiet*); + +tANI_U32 dot11fPackIeQuiet(tpAniSirGlobal, tDot11fIEQuiet*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEQuiet(tpAniSirGlobal, tDot11fIEQuiet*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 53 (0x35) +typedef struct sDot11fIERCPIIE { + tANI_U8 present; + tANI_U8 rcpi; +} tDot11fIERCPIIE; + +#define DOT11F_EID_RCPIIE ( 53 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RCPIIE_MIN_LEN ( 1 ) + +#define DOT11F_IE_RCPIIE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRCPIIE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERCPIIE*); + +tANI_U32 dot11fPackIeRCPIIE(tpAniSirGlobal, tDot11fIERCPIIE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERCPIIE(tpAniSirGlobal, tDot11fIERCPIIE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 57 (0x39) +typedef struct sDot11fIERICDataDesc { + tANI_U8 present; + tDot11fIERICData RICData; + tDot11fIERICDescriptor RICDescriptor; + tDot11fIETSPEC TSPEC; + tANI_U16 num_TCLAS; + tDot11fIETCLAS TCLAS[2]; + tDot11fIETCLASSPROC TCLASSPROC; + tDot11fIETSDelay TSDelay; + tDot11fIESchedule Schedule; + tDot11fIEWMMTSPEC WMMTSPEC; + tANI_U16 num_WMMTCLAS; + tDot11fIEWMMTCLAS WMMTCLAS[2]; + tDot11fIEWMMTCLASPROC WMMTCLASPROC; + tDot11fIEWMMTSDelay WMMTSDelay; + tDot11fIEWMMSchedule WMMSchedule; +} tDot11fIERICDataDesc; + +#define DOT11F_EID_RICDATADESC ( 57 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RICDATADESC_MIN_LEN ( 0 ) + +#define DOT11F_IE_RICDATADESC_MAX_LEN ( 548 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRICDataDesc(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERICDataDesc*); + +tANI_U32 dot11fPackIeRICDataDesc(tpAniSirGlobal, tDot11fIERICDataDesc*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERICDataDesc(tpAniSirGlobal, tDot11fIERICDataDesc*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 48 (0x30) +typedef struct sDot11fIERSN { + tANI_U8 present; + tANI_U16 version /* Must be 1! */; + tANI_U8 gp_cipher_suite[4]; + tANI_U16 pwise_cipher_suite_count; + tANI_U8 pwise_cipher_suites[4][4]; + tANI_U16 akm_suite_count; + tANI_U8 akm_suites[4][4]; + tANI_U8 RSN_Cap[2]; + tANI_U16 pmkid_count; + tANI_U8 pmkid[4][16]; + tANI_U8 gp_mgmt_cipher_suite[4]; +} tDot11fIERSN; + +#define DOT11F_EID_RSN ( 48 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RSN_MIN_LEN ( 6 ) + +#define DOT11F_IE_RSN_MAX_LEN ( 255 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERSN*); + +tANI_U32 dot11fPackIeRSN(tpAniSirGlobal, tDot11fIERSN*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERSN(tpAniSirGlobal, tDot11fIERSN*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 65 (0x41) +typedef struct sDot11fIERSNIIE { + tANI_U8 present; + tANI_U8 rsni; +} tDot11fIERSNIIE; + +#define DOT11F_EID_RSNIIE ( 65 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RSNIIE_MIN_LEN ( 1 ) + +#define DOT11F_IE_RSNIIE_MAX_LEN ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRSNIIE(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERSNIIE*); + +tANI_U32 dot11fPackIeRSNIIE(tpAniSirGlobal, tDot11fIERSNIIE*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERSNIIE(tpAniSirGlobal, tDot11fIERSNIIE*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 48 (0x30) +typedef struct sDot11fIERSNOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[253]; +} tDot11fIERSNOpaque; + +#define DOT11F_EID_RSNOPAQUE ( 48 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_RSNOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_RSNOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeRSNOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIERSNOpaque*); + +tANI_U32 dot11fPackIeRSNOpaque(tpAniSirGlobal, tDot11fIERSNOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIERSNOpaque(tpAniSirGlobal, tDot11fIERSNOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 36 (0x24) +typedef struct sDot11fIESuppChannels { + tANI_U8 present; + tANI_U8 num_bands; + tANI_U8 bands[48][2]; +} tDot11fIESuppChannels; + +#define DOT11F_EID_SUPPCHANNELS ( 36 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SUPPCHANNELS_MIN_LEN ( 2 ) + +#define DOT11F_IE_SUPPCHANNELS_MAX_LEN ( 96 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSuppChannels(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESuppChannels*); + +tANI_U32 dot11fPackIeSuppChannels(tpAniSirGlobal, tDot11fIESuppChannels*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESuppChannels(tpAniSirGlobal, tDot11fIESuppChannels*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 59 (0x3b) +typedef struct sDot11fIESuppOperatingClasses { + tANI_U8 present; + tANI_U8 num_classes; + tANI_U8 classes[32]; +} tDot11fIESuppOperatingClasses; + +#define DOT11F_EID_SUPPOPERATINGCLASSES ( 59 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SUPPOPERATINGCLASSES_MIN_LEN ( 1 ) + +#define DOT11F_IE_SUPPOPERATINGCLASSES_MAX_LEN ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSuppOperatingClasses(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESuppOperatingClasses*); + +tANI_U32 dot11fPackIeSuppOperatingClasses(tpAniSirGlobal, tDot11fIESuppOperatingClasses*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESuppOperatingClasses(tpAniSirGlobal, tDot11fIESuppOperatingClasses*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 1 (0x01) +typedef struct sDot11fIESuppRates { + tANI_U8 present; + tANI_U8 num_rates; + tANI_U8 rates[12]; +} tDot11fIESuppRates; + +#define DOT11F_EID_SUPPRATES ( 1 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_SUPPRATES_MIN_LEN ( 0 ) + +#define DOT11F_IE_SUPPRATES_MAX_LEN ( 12 ) + +#define DOT11F_IS_BG_RATE(_x) (((_x) == 02) || \ + ((_x) == 04) || \ + ((_x) == 11) || \ + ((_x) == 22) || \ + ((_x) == 12) || \ + ((_x) == 18) || \ + ((_x) == 24) || \ + ((_x) == 36) || \ + ((_x) == 48) || \ + ((_x) == 72) || \ + ((_x) == 96) || \ + ((_x) == 108)) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeSuppRates(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIESuppRates*); + +tANI_U32 dot11fPackIeSuppRates(tpAniSirGlobal, tDot11fIESuppRates*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIESuppRates(tpAniSirGlobal, tDot11fIESuppRates*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 5 (0x05) +typedef struct sDot11fIETIM { + tANI_U8 present; + tANI_U8 dtim_count; + tANI_U8 dtim_period; + tANI_U8 bmpctl; + tANI_U8 num_vbmp; + tANI_U8 vbmp[251]; +} tDot11fIETIM; + +#define DOT11F_EID_TIM ( 5 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TIM_MIN_LEN ( 4 ) + +#define DOT11F_IE_TIM_MAX_LEN ( 254 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTIM(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETIM*); + +tANI_U32 dot11fPackIeTIM(tpAniSirGlobal, tDot11fIETIM*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETIM(tpAniSirGlobal, tDot11fIETIM*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 35 (0x23) +typedef struct sDot11fIETPCReport { + tANI_U8 present; + tANI_U8 tx_power; + tANI_U8 link_margin; +} tDot11fIETPCReport; + +#define DOT11F_EID_TPCREPORT ( 35 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TPCREPORT_MIN_LEN ( 2 ) + +#define DOT11F_IE_TPCREPORT_MAX_LEN ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTPCReport(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETPCReport*); + +tANI_U32 dot11fPackIeTPCReport(tpAniSirGlobal, tDot11fIETPCReport*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETPCReport(tpAniSirGlobal, tDot11fIETPCReport*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 34 (0x22) +typedef struct sDot11fIETPCRequest { + tANI_U8 present; +} tDot11fIETPCRequest; + +#define DOT11F_EID_TPCREQUEST ( 34 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TPCREQUEST_MIN_LEN ( 0 ) + +#define DOT11F_IE_TPCREQUEST_MAX_LEN ( 0 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTPCRequest(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETPCRequest*); + +tANI_U32 dot11fPackIeTPCRequest(tpAniSirGlobal, tDot11fIETPCRequest*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETPCRequest(tpAniSirGlobal, tDot11fIETPCRequest*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 56 (0x38) +typedef struct sDot11fIETimeoutInterval { + tANI_U8 present; + tANI_U8 timeoutType; + tANI_U32 timeoutValue; +} tDot11fIETimeoutInterval; + +#define DOT11F_EID_TIMEOUTINTERVAL ( 56 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_TIMEOUTINTERVAL_MIN_LEN ( 5 ) + +#define DOT11F_IE_TIMEOUTINTERVAL_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeTimeoutInterval(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIETimeoutInterval*); + +tANI_U32 dot11fPackIeTimeoutInterval(tpAniSirGlobal, tDot11fIETimeoutInterval*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIETimeoutInterval(tpAniSirGlobal, tDot11fIETimeoutInterval*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 191 (0xbf) +typedef struct sDot11fIEVHTCaps { + tANI_U8 present; + tANI_U32 maxMPDULen: 2; + tANI_U32 supportedChannelWidthSet: 2; + tANI_U32 ldpcCodingCap: 1; + tANI_U32 shortGI80MHz: 1; + tANI_U32 shortGI160and80plus80MHz: 1; + tANI_U32 txSTBC: 1; + tANI_U32 rxSTBC: 3; + tANI_U32 suBeamFormerCap: 1; + tANI_U32 suBeamformeeCap: 1; + tANI_U32 csnofBeamformerAntSup: 3; + tANI_U32 numSoundingDim: 3; + tANI_U32 muBeamformerCap: 1; + tANI_U32 muBeamformeeCap: 1; + tANI_U32 vhtTXOPPS: 1; + tANI_U32 htcVHTCap: 1; + tANI_U32 maxAMPDULenExp: 3; + tANI_U32 vhtLinkAdaptCap: 2; + tANI_U32 rxAntPattern: 1; + tANI_U32 txAntPattern: 1; + tANI_U32 reserved1: 2; + tANI_U16 rxMCSMap; + tANI_U16 rxHighSupDataRate: 13; + tANI_U16 reserved2: 3; + tANI_U16 txMCSMap; + tANI_U16 txSupDataRate: 13; + tANI_U16 reserved3: 3; +} tDot11fIEVHTCaps; + +#define DOT11F_EID_VHTCAPS ( 191 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VHTCAPS_MIN_LEN ( 12 ) + +#define DOT11F_IE_VHTCAPS_MAX_LEN ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVHTCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVHTCaps*); + +tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal, tDot11fIEVHTCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVHTCaps(tpAniSirGlobal, tDot11fIEVHTCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 193 (0xc1) +typedef struct sDot11fIEVHTExtBssLoad { + tANI_U8 present; + tANI_U8 muMIMOCapStaCount; + tANI_U8 ssUnderUtil; + tANI_U8 FortyMHzUtil; + tANI_U8 EightyMHzUtil; + tANI_U8 OneSixtyMHzUtil; +} tDot11fIEVHTExtBssLoad; + +#define DOT11F_EID_VHTEXTBSSLOAD ( 193 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VHTEXTBSSLOAD_MIN_LEN ( 5 ) + +#define DOT11F_IE_VHTEXTBSSLOAD_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVHTExtBssLoad(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVHTExtBssLoad*); + +tANI_U32 dot11fPackIeVHTExtBssLoad(tpAniSirGlobal, tDot11fIEVHTExtBssLoad*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVHTExtBssLoad(tpAniSirGlobal, tDot11fIEVHTExtBssLoad*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 192 (0xc0) +typedef struct sDot11fIEVHTOperation { + tANI_U8 present; + tANI_U8 chanWidth; + tANI_U8 chanCenterFreqSeg1; + tANI_U8 chanCenterFreqSeg2; + tANI_U16 basicMCSSet; +} tDot11fIEVHTOperation; + +#define DOT11F_EID_VHTOPERATION ( 192 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_VHTOPERATION_MIN_LEN ( 5 ) + +#define DOT11F_IE_VHTOPERATION_MAX_LEN ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeVHTOperation(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEVHTOperation*); + +tANI_U32 dot11fPackIeVHTOperation(tpAniSirGlobal, tDot11fIEVHTOperation*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEVHTOperation(tpAniSirGlobal, tDot11fIEVHTOperation*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 68 (0x44) +typedef struct sDot11fIEWAPI { + tANI_U8 present; + tANI_U16 version /* Must be 1! */; + tANI_U16 akm_suite_count; + tANI_U8 akm_suites[4][4]; + tANI_U16 unicast_cipher_suite_count; + tANI_U8 unicast_cipher_suites[4][4]; + tANI_U8 multicast_cipher_suite[4]; + tANI_U16 preauth: 1; + tANI_U16 reserved: 15; + tANI_U16 bkid_count; + tANI_U8 bkid[4][16]; +} tDot11fIEWAPI; + +#define DOT11F_EID_WAPI ( 68 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WAPI_MIN_LEN ( 12 ) + +#define DOT11F_IE_WAPI_MAX_LEN ( 110 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWAPI*); + +tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal, tDot11fIEWAPI*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWAPI(tpAniSirGlobal, tDot11fIEWAPI*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 68 (0x44) +typedef struct sDot11fIEWAPIOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[253]; +} tDot11fIEWAPIOpaque; + +#define DOT11F_EID_WAPIOPAQUE ( 68 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WAPIOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WAPIOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWAPIOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWAPIOpaque*); + +tANI_U32 dot11fPackIeWAPIOpaque(tpAniSirGlobal, tDot11fIEWAPIOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWAPIOpaque(tpAniSirGlobal, tDot11fIEWAPIOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x08, 0x00} +typedef struct sDot11fIEWFATPC { + tANI_U8 present; + tANI_U8 txPower; + tANI_U8 linkMargin; +} tDot11fIEWFATPC; + +#define DOT11F_EID_WFATPC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WFATPC_MIN_LEN ( 7 ) + +#define DOT11F_IE_WFATPC_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWFATPC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWFATPC*); + +tANI_U32 dot11fPackIeWFATPC(tpAniSirGlobal, tDot11fIEWFATPC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWFATPC(tpAniSirGlobal, tDot11fIEWFATPC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x0a} +typedef struct sDot11fIEWFDIEOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEWFDIEOpaque; + +#define DOT11F_EID_WFDIEOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WFDIEOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WFDIEOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWFDIEOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWFDIEOpaque*); + +tANI_U32 dot11fPackIeWFDIEOpaque(tpAniSirGlobal, tDot11fIEWFDIEOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWFDIEOpaque(tpAniSirGlobal, tDot11fIEWFDIEOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x05} +typedef struct sDot11fIEWMMCaps { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 reserved: 4; + tANI_U8 qack: 1; + tANI_U8 queue_request: 1; + tANI_U8 txop_request: 1; + tANI_U8 more_ack: 1; +} tDot11fIEWMMCaps; + +#define DOT11F_EID_WMMCAPS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMCAPS_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMCAPS_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMCaps(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMCaps*); + +tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal, tDot11fIEWMMCaps*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMCaps(tpAniSirGlobal, tDot11fIEWMMCaps*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} +typedef struct sDot11fIEWMMInfoAp { + tANI_U8 present; + tANI_U8 version; + tANI_U8 param_set_count: 4; + tANI_U8 reserved: 3; + tANI_U8 uapsd: 1; +} tDot11fIEWMMInfoAp; + +#define DOT11F_EID_WMMINFOAP ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMINFOAP_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMINFOAP_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMInfoAp(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMInfoAp*); + +tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal, tDot11fIEWMMInfoAp*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMInfoAp(tpAniSirGlobal, tDot11fIEWMMInfoAp*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x00} +typedef struct sDot11fIEWMMInfoStation { + tANI_U8 present; + tANI_U8 version; + tANI_U8 acvo_uapsd: 1; + tANI_U8 acvi_uapsd: 1; + tANI_U8 acbk_uapsd: 1; + tANI_U8 acbe_uapsd: 1; + tANI_U8 reserved1: 1; + tANI_U8 max_sp_length: 2; + tANI_U8 reserved2: 1; +} tDot11fIEWMMInfoStation; + +#define DOT11F_EID_WMMINFOSTATION ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMINFOSTATION_MIN_LEN ( 7 ) + +#define DOT11F_IE_WMMINFOSTATION_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMInfoStation(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMInfoStation*); + +tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal, tDot11fIEWMMInfoStation*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMInfoStation(tpAniSirGlobal, tDot11fIEWMMInfoStation*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x02, 0x01} +typedef struct sDot11fIEWMMParams { + tANI_U8 present; + tANI_U8 version /* Must be 1! */; + tANI_U8 qosInfo; + tANI_U8 reserved2; + tANI_U8 acbe_aifsn: 4; + tANI_U8 acbe_acm: 1; + tANI_U8 acbe_aci: 2; + tANI_U8 unused1: 1; + tANI_U8 acbe_acwmin: 4; + tANI_U8 acbe_acwmax: 4; + tANI_U16 acbe_txoplimit; + tANI_U8 acbk_aifsn: 4; + tANI_U8 acbk_acm: 1; + tANI_U8 acbk_aci: 2; + tANI_U8 unused2: 1; + tANI_U8 acbk_acwmin: 4; + tANI_U8 acbk_acwmax: 4; + tANI_U16 acbk_txoplimit; + tANI_U8 acvi_aifsn: 4; + tANI_U8 acvi_acm: 1; + tANI_U8 acvi_aci: 2; + tANI_U8 unused3: 1; + tANI_U8 acvi_acwmin: 4; + tANI_U8 acvi_acwmax: 4; + tANI_U16 acvi_txoplimit; + tANI_U8 acvo_aifsn: 4; + tANI_U8 acvo_acm: 1; + tANI_U8 acvo_aci: 2; + tANI_U8 unused4: 1; + tANI_U8 acvo_acwmin: 4; + tANI_U8 acvo_acwmax: 4; + tANI_U16 acvo_txoplimit; +} tDot11fIEWMMParams; + +#define DOT11F_EID_WMMPARAMS ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WMMPARAMS_MIN_LEN ( 24 ) + +#define DOT11F_IE_WMMPARAMS_MAX_LEN ( 24 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWMMParams*); + +tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal, tDot11fIEWMMParams*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWMMParams(tpAniSirGlobal, tDot11fIEWMMParams*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} +typedef struct sDot11fIEWPA { + tANI_U8 present; + tANI_U16 version /* Must be 1! */; + tANI_U8 multicast_cipher_present; //field added to fix the bug in dot11fPackIEWPA + tANI_U8 multicast_cipher[4]; + tANI_U16 unicast_cipher_count; + tANI_U8 unicast_ciphers[4][4]; + tANI_U16 auth_suite_count; + tANI_U8 auth_suites[4][4]; + tANI_U16 caps; +} tDot11fIEWPA; + +#define DOT11F_EID_WPA ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WPA_MIN_LEN ( 6 ) + +#define DOT11F_IE_WPA_MAX_LEN ( 48 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWPA*); + +tANI_U32 dot11fPackIeWPA(tpAniSirGlobal, tDot11fIEWPA*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWPA(tpAniSirGlobal, tDot11fIEWPA*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x01} +typedef struct sDot11fIEWPAOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEWPAOpaque; + +#define DOT11F_EID_WPAOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WPAOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WPAOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWPAOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWPAOpaque*); + +tANI_U32 dot11fPackIeWPAOpaque(tpAniSirGlobal, tDot11fIEWPAOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWPAOpaque(tpAniSirGlobal, tDot11fIEWPAOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWSC { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVUUID_R UUID_R; + tDot11fTLVRFBands RFBands; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVAssociationState AssociationState; + tDot11fTLVConfigurationError ConfigurationError; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVSerialNumber SerialNumber; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVRequestType RequestType; + tDot11fTLVResponseType ResponseType; + tDot11fTLVVendorExtension VendorExtension; + tDot11fTLVRequestDeviceType RequestDeviceType; +} tDot11fIEWSC; + +#define DOT11F_EID_WSC ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSC_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSC_MAX_LEN ( 366 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWSC(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWSC*); + +tANI_U32 dot11fPackIeWSC(tpAniSirGlobal, tDot11fIEWSC*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWSC(tpAniSirGlobal, tDot11fIEWSC*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 194 (0xc2) +typedef struct sDot11fIEWiderBWChanSwitchAnn { + tANI_U8 present; + tANI_U8 newChanWidth; + tANI_U8 newCenterChanFreq0; + tANI_U8 newCenterChanFreq1; +} tDot11fIEWiderBWChanSwitchAnn; + +#define DOT11F_EID_WIDERBWCHANSWITCHANN ( 194 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WIDERBWCHANSWITCHANN_MIN_LEN ( 3 ) + +#define DOT11F_IE_WIDERBWCHANSWITCHANN_MAX_LEN ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWiderBWChanSwitchAnn(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWiderBWChanSwitchAnn*); + +tANI_U32 dot11fPackIeWiderBWChanSwitchAnn(tpAniSirGlobal, tDot11fIEWiderBWChanSwitchAnn*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWiderBWChanSwitchAnn(tpAniSirGlobal, tDot11fIEWiderBWChanSwitchAnn*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscAssocReq { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVRequestType RequestType; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscAssocReq; + +#define DOT11F_EID_WSCASSOCREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCASSOCREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCASSOCREQ_MAX_LEN ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscAssocReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscAssocReq*); + +tANI_U32 dot11fPackIeWscAssocReq(tpAniSirGlobal, tDot11fIEWscAssocReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscAssocReq(tpAniSirGlobal, tDot11fIEWscAssocReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscAssocRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVResponseType ResponseType; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscAssocRes; + +#define DOT11F_EID_WSCASSOCRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCASSOCRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCASSOCRES_MAX_LEN ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscAssocRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscAssocRes*); + +tANI_U32 dot11fPackIeWscAssocRes(tpAniSirGlobal, tDot11fIEWscAssocRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscAssocRes(tpAniSirGlobal, tDot11fIEWscAssocRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscBeacon { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVRFBands RFBands; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscBeacon; + +#define DOT11F_EID_WSCBEACON ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCBEACON_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCBEACON_MAX_LEN ( 82 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscBeacon(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscBeacon*); + +tANI_U32 dot11fPackIeWscBeacon(tpAniSirGlobal, tDot11fIEWscBeacon*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscBeacon(tpAniSirGlobal, tDot11fIEWscBeacon*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscBeaconProbeRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVResponseType ResponseType; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVSerialNumber SerialNumber; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVRFBands RFBands; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscBeaconProbeRes; + +#define DOT11F_EID_WSCBEACONPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCBEACONPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCBEACONPROBERES_MAX_LEN ( 317 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscBeaconProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscBeaconProbeRes*); + +tANI_U32 dot11fPackIeWscBeaconProbeRes(tpAniSirGlobal, tDot11fIEWscBeaconProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscBeaconProbeRes(tpAniSirGlobal, tDot11fIEWscBeaconProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} +typedef struct sDot11fIEWscIEOpaque { + tANI_U8 present; + tANI_U8 num_data; + tANI_U8 data[249]; +} tDot11fIEWscIEOpaque; + +#define DOT11F_EID_WSCIEOPAQUE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCIEOPAQUE_MIN_LEN ( 6 ) + +#define DOT11F_IE_WSCIEOPAQUE_MAX_LEN ( 253 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscIEOpaque(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscIEOpaque*); + +tANI_U32 dot11fPackIeWscIEOpaque(tpAniSirGlobal, tDot11fIEWscIEOpaque*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscIEOpaque(tpAniSirGlobal, tDot11fIEWscIEOpaque*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscProbeReq { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVRequestType RequestType; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVRFBands RFBands; + tDot11fTLVAssociationState AssociationState; + tDot11fTLVConfigurationError ConfigurationError; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVVendorExtension VendorExtension; + tDot11fTLVRequestDeviceType RequestDeviceType; +} tDot11fIEWscProbeReq; + +#define DOT11F_EID_WSCPROBEREQ ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCPROBEREQ_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCPROBEREQ_MAX_LEN ( 284 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscProbeReq(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscProbeReq*); + +tANI_U32 dot11fPackIeWscProbeReq(tpAniSirGlobal, tDot11fIEWscProbeReq*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscProbeReq(tpAniSirGlobal, tDot11fIEWscProbeReq*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscProbeRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVWPSState WPSState; + tDot11fTLVAPSetupLocked APSetupLocked; + tDot11fTLVSelectedRegistrar SelectedRegistrar; + tDot11fTLVDevicePasswordID DevicePasswordID; + tDot11fTLVSelectedRegistrarConfigMethods SelectedRegistrarConfigMethods; + tDot11fTLVResponseType ResponseType; + tDot11fTLVUUID_E UUID_E; + tDot11fTLVManufacturer Manufacturer; + tDot11fTLVModelName ModelName; + tDot11fTLVModelNumber ModelNumber; + tDot11fTLVSerialNumber SerialNumber; + tDot11fTLVPrimaryDeviceType PrimaryDeviceType; + tDot11fTLVDeviceName DeviceName; + tDot11fTLVConfigMethods ConfigMethods; + tDot11fTLVRFBands RFBands; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscProbeRes; + +#define DOT11F_EID_WSCPROBERES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCPROBERES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCPROBERES_MAX_LEN ( 317 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscProbeRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscProbeRes*); + +tANI_U32 dot11fPackIeWscProbeRes(tpAniSirGlobal, tDot11fIEWscProbeRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscProbeRes(tpAniSirGlobal, tDot11fIEWscProbeRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x00, 0x50, 0xf2, 0x04} (Multi-IE) +typedef struct sDot11fIEWscReassocRes { + tANI_U8 present; + tDot11fTLVVersion Version; + tDot11fTLVResponseType ResponseType; + tDot11fTLVVendorExtension VendorExtension; +} tDot11fIEWscReassocRes; + +#define DOT11F_EID_WSCREASSOCRES ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_WSCREASSOCRES_MIN_LEN ( 4 ) + +#define DOT11F_IE_WSCREASSOCRES_MAX_LEN ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIeWscReassocRes(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEWscReassocRes*); + +tANI_U32 dot11fPackIeWscReassocRes(tpAniSirGlobal, tDot11fIEWscReassocRes*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEWscReassocRes(tpAniSirGlobal, tDot11fIEWscReassocRes*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +// EID 221 (0xdd) {OUI 0x50, 0x6f, 0x9a, 0x10} +typedef struct sDot11fIEhs20vendor_ie { + tANI_U8 present; + tANI_U8 dgaf_dis: 1; + tANI_U8 hs_id_present: 2; + tANI_U8 reserved: 1; + tANI_U8 release_num: 4; + union + { + struct + { + tANI_U16 pps_mo_id; + } pps_mo; /* hs_id_present = 1 */ + struct + { + tANI_U16 anqp_domain_id; + } anqp_domain; /* hs_id_present = 2 */ + } hs_id; +} tDot11fIEhs20vendor_ie; + +#define DOT11F_EID_HS20VENDOR_IE ( 221 ) + +// N.B. These #defines do *not* include the EID & length +#define DOT11F_IE_HS20VENDOR_IE_MIN_LEN ( 5 ) + +#define DOT11F_IE_HS20VENDOR_IE_MAX_LEN ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ +tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal, tANI_U8*,tANI_U8, tDot11fIEhs20vendor_ie*); + +tANI_U32 dot11fPackIehs20vendor_ie(tpAniSirGlobal, tDot11fIEhs20vendor_ie*, tANI_U8*, tANI_U32, tANI_U32*); + +tANI_U32 dot11fGetPackedIEhs20vendor_ie(tpAniSirGlobal, tDot11fIEhs20vendor_ie*, tANI_U32*); + +#ifdef __cplusplus +}; /* End extern "C". */ +#endif /* C++ */ +/************************************************************************ + * Frames + **********************************************************************/ + +typedef struct sDot11fAddBAReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfAddBAParameterSet AddBAParameterSet; + tDot11fFfBATimeout BATimeout; + tDot11fFfBAStartingSequenceControl BAStartingSequenceControl; +} tDot11fAddBAReq; + +#define DOT11F_ADDBAREQ ( 1 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddBAReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBAReq *pFrm); +tANI_U32 dot11fPackAddBAReq(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddBAReqSize(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAddBARsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatus Status; + tDot11fFfAddBAParameterSet AddBAParameterSet; + tDot11fFfBATimeout BATimeout; +} tDot11fAddBARsp; + +#define DOT11F_ADDBARSP ( 2 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddBARsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBARsp *pFrm); +tANI_U32 dot11fPackAddBARsp(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddBARspSize(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAddTSRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIETSPEC TSPEC; + tANI_U16 num_TCLAS; + tDot11fIETCLAS TCLAS[2]; + tDot11fIETCLASSPROC TCLASSPROC; + tDot11fIEWMMTSPEC WMMTSPEC; + tANI_U16 num_WMMTCLAS; + tDot11fIEWMMTCLAS WMMTCLAS[2]; + tDot11fIEWMMTCLASPROC WMMTCLASPROC; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; +} tDot11fAddTSRequest; + +#define DOT11F_ADDTSREQUEST ( 3 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSRequest *pFrm); +tANI_U32 dot11fPackAddTSRequest(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAddTSResponse{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatus Status; + tDot11fIETSDelay TSDelay; + tDot11fIETSPEC TSPEC; + tANI_U16 num_TCLAS; + tDot11fIETCLAS TCLAS[2]; + tDot11fIETCLASSPROC TCLASSPROC; + tDot11fIESchedule Schedule; + tDot11fIEWMMTSDelay WMMTSDelay; + tDot11fIEWMMSchedule WMMSchedule; + tDot11fIEWMMTSPEC WMMTSPEC; + tANI_U16 num_WMMTCLAS; + tDot11fIEWMMTCLAS WMMTCLAS[2]; + tDot11fIEWMMTCLASPROC WMMTCLASPROC; + tDot11fIEESETrafStrmMet ESETrafStrmMet; +} tDot11fAddTSResponse; + +#define DOT11F_ADDTSRESPONSE ( 4 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSResponse *pFrm); +tANI_U32 dot11fPackAddTSResponse(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAssocRequest{ + tDot11fFfCapabilities Capabilities; + tDot11fFfListenInterval ListenInterval; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEPowerCaps PowerCaps; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPAOpaque WPAOpaque; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAirgo Airgo; + tDot11fIEWscIEOpaque WscIEOpaque; + tDot11fIEWAPIOpaque WAPIOpaque; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESEVersion ESEVersion; + tDot11fIEP2PIEOpaque P2PIEOpaque; + tDot11fIEWFDIEOpaque WFDIEOpaque; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEQosMapSet QosMapSet; + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tDot11fAssocRequest; + +#define DOT11F_ASSOCREQUEST ( 5 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocRequest *pFrm); +tANI_U32 dot11fPackAssocRequest(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAssocRequestSize(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAssocResponse{ + tDot11fFfCapabilities Capabilities; + tDot11fFfStatus Status; + tDot11fFfAID AID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIERCPIIE RCPIIE; + tDot11fIERSNIIE RSNIIE; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIEWPA WPA; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tANI_U16 num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEAirgo Airgo; + tDot11fIEWscAssocRes WscAssocRes; + tDot11fIEP2PAssocRes P2PAssocRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEQosMapSet QosMapSet; +} tDot11fAssocResponse; + +#define DOT11F_ASSOCRESPONSE ( 6 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocResponse *pFrm); +tANI_U32 dot11fPackAssocResponse(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAssocResponseSize(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fAuthentication{ + tDot11fFfAuthAlgo AuthAlgo; + tDot11fFfAuthSeqNo AuthSeqNo; + tDot11fFfStatus Status; + tDot11fIEChallengeText ChallengeText; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; +} tDot11fAuthentication; + +#define DOT11F_AUTHENTICATION ( 7 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackAuthentication(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAuthentication *pFrm); +tANI_U32 dot11fPackAuthentication(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedAuthenticationSize(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeacon{ + tDot11fFfTimeStamp TimeStamp; + tDot11fFfBeaconInterval BeaconInterval; + tDot11fFfCapabilities Capabilities; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEFHParamSet FHParamSet; + tDot11fIEDSParams DSParams; + tDot11fIECFParams CFParams; + tDot11fIEIBSSParams IBSSParams; + tDot11fIETIM TIM; + tDot11fIECountry Country; + tDot11fIEFHParams FHParams; + tDot11fIEFHPattTable FHPattTable; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSN RSN; + tDot11fIEQBSSLoad QBSSLoad; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEQOSCapsAp QOSCapsAp; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEAirgo Airgo; + tDot11fIEWscBeacon WscBeacon; + tDot11fIEP2PBeacon P2PBeacon; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tDot11fBeacon; + +#define DOT11F_BEACON ( 8 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon *pFrm); +tANI_U32 dot11fPackBeacon(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeaconSize(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeacon1{ + tDot11fFfTimeStamp TimeStamp; + tDot11fFfBeaconInterval BeaconInterval; + tDot11fFfCapabilities Capabilities; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEDSParams DSParams; + tDot11fIEIBSSParams IBSSParams; +} tDot11fBeacon1; + +#define DOT11F_BEACON1 ( 9 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeacon1(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon1 *pFrm); +tANI_U32 dot11fPackBeacon1(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeacon1Size(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeacon2{ + tDot11fIECountry Country; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEAirgo Airgo; + tDot11fIEWscBeacon WscBeacon; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEP2PBeacon P2PBeacon; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tDot11fBeacon2; + +#define DOT11F_BEACON2 ( 10 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon2 *pFrm); +tANI_U32 dot11fPackBeacon2(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeacon2Size(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fBeaconIEs{ + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEFHParamSet FHParamSet; + tDot11fIEDSParams DSParams; + tDot11fIECFParams CFParams; + tDot11fIEIBSSParams IBSSParams; + tDot11fIETIM TIM; + tDot11fIECountry Country; + tDot11fIEFHParams FHParams; + tDot11fIEFHPattTable FHPattTable; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSN RSN; + tDot11fIEQBSSLoad QBSSLoad; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEQOSCapsAp QOSCapsAp; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWAPI WAPI; + tDot11fIEESEVersion ESEVersion; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEAirgo Airgo; + tDot11fIEWscBeaconProbeRes WscBeaconProbeRes; + tDot11fIEP2PBeaconProbeRes P2PBeaconProbeRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tDot11fBeaconIEs; + +#define DOT11F_BEACONIES ( 11 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackBeaconIEs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeaconIEs *pFrm); +tANI_U32 dot11fPackBeaconIEs(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedBeaconIEsSize(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fChannelSwitch{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; +} tDot11fChannelSwitch; + +#define DOT11F_CHANNELSWITCH ( 12 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackChannelSwitch(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fChannelSwitch *pFrm); +tANI_U32 dot11fPackChannelSwitch(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedChannelSwitchSize(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDeAuth{ + tDot11fFfReason Reason; + tDot11fIEP2PDeAuth P2PDeAuth; +} tDot11fDeAuth; + +#define DOT11F_DEAUTH ( 13 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDeAuth(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeAuth *pFrm); +tANI_U32 dot11fPackDeAuth(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDeAuthSize(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDelBAInd{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDelBAParameterSet DelBAParameterSet; + tDot11fFfReason Reason; +} tDot11fDelBAInd; + +#define DOT11F_DELBAIND ( 14 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDelBAInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelBAInd *pFrm); +tANI_U32 dot11fPackDelBAInd(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDelBAIndSize(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDelTS{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfTSInfo TSInfo; + tDot11fFfReason Reason; +} tDot11fDelTS; + +#define DOT11F_DELTS ( 15 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelTS *pFrm); +tANI_U32 dot11fPackDelTS(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDelTSSize(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDeviceDiscoverabilityReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PDeviceDiscoverabilityReq P2PDeviceDiscoverabilityReq; +} tDot11fDeviceDiscoverabilityReq; + +#define DOT11F_DEVICEDISCOVERABILITYREQ ( 16 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityReq *pFrm); +tANI_U32 dot11fPackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDeviceDiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDeviceDiscoverabilityRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PDeviceDiscoverabilityRes P2PDeviceDiscoverabilityRes; +} tDot11fDeviceDiscoverabilityRes; + +#define DOT11F_DEVICEDISCOVERABILITYRES ( 17 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityRes *pFrm); +tANI_U32 dot11fPackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDeviceDiscoverabilityResSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fDisassociation{ + tDot11fFfReason Reason; + tDot11fIEP2PDisAssoc P2PDisAssoc; +} tDot11fDisassociation; + +#define DOT11F_DISASSOCIATION ( 18 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackDisassociation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDisassociation *pFrm); +tANI_U32 dot11fPackDisassociation(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedDisassociationSize(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGODiscoverabilityReq{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; +} tDot11fGODiscoverabilityReq; + +#define DOT11F_GODISCOVERABILITYREQ ( 19 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGODiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGODiscoverabilityReq *pFrm); +tANI_U32 dot11fPackGODiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGODiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGONegCnf{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PGONegCnf P2PGONegCnf; +} tDot11fGONegCnf; + +#define DOT11F_GONEGCNF ( 20 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGONegCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegCnf *pFrm); +tANI_U32 dot11fPackGONegCnf(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGONegCnfSize(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGONegReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PGONegWPS P2PGONegWPS; + tDot11fIEP2PGONegReq P2PGONegReq; +} tDot11fGONegReq; + +#define DOT11F_GONEGREQ ( 21 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGONegReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegReq *pFrm); +tANI_U32 dot11fPackGONegReq(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGONegReqSize(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fGONegRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PGONegWPS P2PGONegWPS; + tDot11fIEP2PGONegRes P2PGONegRes; +} tDot11fGONegRes; + +#define DOT11F_GONEGRES ( 22 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackGONegRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegRes *pFrm); +tANI_U32 dot11fPackGONegRes(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedGONegResSize(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fHT2040BSSCoexistenceManagementActionFrame{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIEHT2040BSSIntolerantReport HT2040BSSIntolerantReport; +} tDot11fHT2040BSSCoexistenceManagementActionFrame; + +#define DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME ( 23 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm); +tANI_U32 dot11fPackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedHT2040BSSCoexistenceManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fInvitationReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PInvitationReq P2PInvitationReq; +} tDot11fInvitationReq; + +#define DOT11F_INVITATIONREQ ( 24 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackInvitationReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationReq *pFrm); +tANI_U32 dot11fPackInvitationReq(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedInvitationReqSize(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fInvitationRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PInvitationRes P2PInvitationRes; +} tDot11fInvitationRes; + +#define DOT11F_INVITATIONRES ( 25 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackInvitationRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationRes *pFrm); +tANI_U32 dot11fPackInvitationRes(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedInvitationResSize(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fLinkMeasurementReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfTPCEleID TPCEleID; + tDot11fFfTPCEleLen TPCEleLen; + tDot11fFfTxPower TxPower; + tDot11fFfLinkMargin LinkMargin; + tDot11fFfRxAntennaId RxAntennaId; + tDot11fFfTxAntennaId TxAntennaId; + tDot11fFfRCPI RCPI; + tDot11fFfRSNI RSNI; +} tDot11fLinkMeasurementReport; + +#define DOT11F_LINKMEASUREMENTREPORT ( 26 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackLinkMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementReport *pFrm); +tANI_U32 dot11fPackLinkMeasurementReport(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedLinkMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fLinkMeasurementRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfTxPower TxPower; + tDot11fFfMaxTxPower MaxTxPower; +} tDot11fLinkMeasurementRequest; + +#define DOT11F_LINKMEASUREMENTREQUEST ( 27 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackLinkMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementRequest *pFrm); +tANI_U32 dot11fPackLinkMeasurementRequest(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedLinkMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fMeasurementReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIEMeasurementReport MeasurementReport; +} tDot11fMeasurementReport; + +#define DOT11F_MEASUREMENTREPORT ( 28 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementReport *pFrm); +tANI_U32 dot11fPackMeasurementReport(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fMeasurementRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tANI_U16 num_MeasurementRequest; + tDot11fIEMeasurementRequest MeasurementRequest[4]; +} tDot11fMeasurementRequest; + +#define DOT11F_MEASUREMENTREQUEST ( 29 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementRequest *pFrm); +tANI_U32 dot11fPackMeasurementRequest(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fNeighborReportRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIESSID SSID; +} tDot11fNeighborReportRequest; + +#define DOT11F_NEIGHBORREPORTREQUEST ( 30 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackNeighborReportRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportRequest *pFrm); +tANI_U32 dot11fPackNeighborReportRequest(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedNeighborReportRequestSize(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fNeighborReportResponse{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tANI_U16 num_NeighborReport; + tDot11fIENeighborReport NeighborReport[4]; +} tDot11fNeighborReportResponse; + +#define DOT11F_NEIGHBORREPORTRESPONSE ( 31 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackNeighborReportResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportResponse *pFrm); +tANI_U32 dot11fPackNeighborReportResponse(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedNeighborReportResponseSize(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fNoticeOfAbs{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PNoticeOfAbsence P2PNoticeOfAbsence; +} tDot11fNoticeOfAbs; + +#define DOT11F_NOTICEOFABS ( 32 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackNoticeOfAbs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNoticeOfAbs *pFrm); +tANI_U32 dot11fPackNoticeOfAbs(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedNoticeOfAbsSize(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fOperatingMode{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfOperatingMode OperatingMode; +} tDot11fOperatingMode; + +#define DOT11F_OPERATINGMODE ( 33 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fOperatingMode *pFrm); +tANI_U32 dot11fPackOperatingMode(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedOperatingModeSize(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fPresenceReq{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PNoticeOfAbsence P2PNoticeOfAbsence; +} tDot11fPresenceReq; + +#define DOT11F_PRESENCEREQ ( 34 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackPresenceReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceReq *pFrm); +tANI_U32 dot11fPackPresenceReq(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedPresenceReqSize(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fPresenceRes{ + tDot11fFfCategory Category; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PPresenceResponse P2PPresenceResponse; +} tDot11fPresenceRes; + +#define DOT11F_PRESENCERES ( 35 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackPresenceRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceRes *pFrm); +tANI_U32 dot11fPackPresenceRes(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedPresenceResSize(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProbeRequest{ + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIERequestedInfo RequestedInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEDSParams DSParams; + tDot11fIEHTCaps HTCaps; + tDot11fIEWscProbeReq WscProbeReq; + tDot11fIEWFATPC WFATPC; + tDot11fIEP2PProbeReq P2PProbeReq; + tDot11fIEVHTCaps VHTCaps; +} tDot11fProbeRequest; + +#define DOT11F_PROBEREQUEST ( 36 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProbeRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeRequest *pFrm); +tANI_U32 dot11fPackProbeRequest(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProbeRequestSize(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProbeResponse{ + tDot11fFfTimeStamp TimeStamp; + tDot11fFfBeaconInterval BeaconInterval; + tDot11fFfCapabilities Capabilities; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEFHParamSet FHParamSet; + tDot11fIEDSParams DSParams; + tDot11fIECFParams CFParams; + tDot11fIEIBSSParams IBSSParams; + tDot11fIECountry Country; + tDot11fIEFHParams FHParams; + tDot11fIEFHPattTable FHPattTable; + tDot11fIEPowerConstraints PowerConstraints; + tDot11fIEChanSwitchAnn ChanSwitchAnn; + tDot11fIEQuiet Quiet; + tDot11fIETPCReport TPCReport; + tDot11fIEERPInfo ERPInfo; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQBSSLoad QBSSLoad; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEAPChannelReport APChannelReport; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEWPA WPA; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEExtChanSwitchAnn ExtChanSwitchAnn; + tDot11fIEWMMInfoAp WMMInfoAp; + tDot11fIEWMMParams WMMParams; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWAPI WAPI; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tDot11fIEAirgo Airgo; + tDot11fIEWscProbeRes WscProbeRes; + tDot11fIEP2PProbeRes P2PProbeRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tDot11fProbeResponse; + +#define DOT11F_PROBERESPONSE ( 37 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProbeResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeResponse *pFrm); +tANI_U32 dot11fPackProbeResponse(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProbeResponseSize(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProvisionDiscoveryReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PProvisionDiscoveryReq P2PProvisionDiscoveryReq; +} tDot11fProvisionDiscoveryReq; + +#define DOT11F_PROVISIONDISCOVERYREQ ( 38 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryReq *pFrm); +tANI_U32 dot11fPackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProvisionDiscoveryReqSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fProvisionDiscoveryRes{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfP2POUI P2POUI; + tDot11fFfP2POUISubType P2POUISubType; + tDot11fFfDialogToken DialogToken; + tDot11fIEP2PWSCProvisionDiscoveryRes P2PWSCProvisionDiscoveryRes; +} tDot11fProvisionDiscoveryRes; + +#define DOT11F_PROVISIONDISCOVERYRES ( 39 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryRes *pFrm); +tANI_U32 dot11fPackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedProvisionDiscoveryResSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fQosMapConfigure{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fIEQosMapSet QosMapSet; +} tDot11fQosMapConfigure; + +#define DOT11F_QOSMAPCONFIGURE ( 40 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackQosMapConfigure(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fQosMapConfigure *pFrm); +tANI_U32 dot11fPackQosMapConfigure(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedQosMapConfigureSize(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fRMC{ + tDot11fFfCategory Category; + tDot11fFfRMCOUI RMCOUI; + tDot11fFfMagicCode MagicCode; + tDot11fFfRMCVersion RMCVersion; + tDot11fFfAction Action; + tDot11fFfRMCDialogToken RMCDialogToken; + tDot11fFfRuler Ruler; +} tDot11fRMC; + +#define DOT11F_RMC ( 41 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackRMC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRMC *pFrm); +tANI_U32 dot11fPackRMC(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedRMCSize(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fRadioMeasurementReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tANI_U16 num_MeasurementReport; + tDot11fIEMeasurementReport MeasurementReport[4]; +} tDot11fRadioMeasurementReport; + +#define DOT11F_RADIOMEASUREMENTREPORT ( 42 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackRadioMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementReport *pFrm); +tANI_U32 dot11fPackRadioMeasurementReport(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedRadioMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fRadioMeasurementRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfNumOfRepetitions NumOfRepetitions; + tANI_U16 num_MeasurementRequest; + tDot11fIEMeasurementRequest MeasurementRequest[2]; +} tDot11fRadioMeasurementRequest; + +#define DOT11F_RADIOMEASUREMENTREQUEST ( 43 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackRadioMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementRequest *pFrm); +tANI_U32 dot11fPackRadioMeasurementRequest(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedRadioMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fReAssocRequest{ + tDot11fFfCapabilities Capabilities; + tDot11fFfListenInterval ListenInterval; + tDot11fFfCurrentAPAddress CurrentAPAddress; + tDot11fIESSID SSID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEPowerCaps PowerCaps; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIEWPAOpaque WPAOpaque; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMCaps WMMCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAirgo Airgo; + tDot11fIEWscIEOpaque WscIEOpaque; + tDot11fIEWAPIOpaque WAPIOpaque; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESEVersion ESEVersion; + tDot11fIEESECckmOpaque ESECckmOpaque; + tANI_U16 num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; + tDot11fIEP2PIEOpaque P2PIEOpaque; + tDot11fIEWFDIEOpaque WFDIEOpaque; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tDot11fIEQosMapSet QosMapSet; + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tDot11fReAssocRequest; + +#define DOT11F_REASSOCREQUEST ( 44 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackReAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocRequest *pFrm); +tANI_U32 dot11fPackReAssocRequest(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedReAssocRequestSize(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fReAssocResponse{ + tDot11fFfCapabilities Capabilities; + tDot11fFfStatus Status; + tDot11fFfAID AID; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIERCPIIE RCPIIE; + tDot11fIERSNIIE RSNIIE; + tDot11fIERRMEnabledCap RRMEnabledCap; + tDot11fIERSNOpaque RSNOpaque; + tDot11fIEMobilityDomain MobilityDomain; + tDot11fIEFTInfo FTInfo; + tANI_U16 num_RICDataDesc; + tDot11fIERICDataDesc RICDataDesc[2]; + tDot11fIEWPA WPA; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEWMMParams WMMParams; + tDot11fIEESERadMgmtCap ESERadMgmtCap; + tDot11fIEESETrafStrmMet ESETrafStrmMet; + tDot11fIEESETxmitPower ESETxmitPower; + tANI_U16 num_WMMTSPEC; + tDot11fIEWMMTSPEC WMMTSPEC[4]; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; + tDot11fIEAirgo Airgo; + tDot11fIEWscReassocRes WscReassocRes; + tDot11fIEP2PAssocRes P2PAssocRes; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEQosMapSet QosMapSet; +} tDot11fReAssocResponse; + +#define DOT11F_REASSOCRESPONSE ( 45 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackReAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocResponse *pFrm); +tANI_U32 dot11fPackReAssocResponse(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedReAssocResponseSize(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fSMPowerSave{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfSMPowerModeSet SMPowerModeSet; +} tDot11fSMPowerSave; + +#define DOT11F_SMPOWERSAVE ( 46 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackSMPowerSave(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSMPowerSave *pFrm); +tANI_U32 dot11fPackSMPowerSave(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedSMPowerSaveSize(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fSaQueryReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfTransactionId TransactionId; +} tDot11fSaQueryReq; + +#define DOT11F_SAQUERYREQ ( 47 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackSaQueryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryReq *pFrm); +tANI_U32 dot11fPackSaQueryReq(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedSaQueryReqSize(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fSaQueryRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfTransactionId TransactionId; +} tDot11fSaQueryRsp; + +#define DOT11F_SAQUERYRSP ( 48 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackSaQueryRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryRsp *pFrm); +tANI_U32 dot11fPackSaQueryRsp(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedSaQueryRspSize(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSDisReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIELinkIdentifier LinkIdentifier; +} tDot11fTDLSDisReq; + +#define DOT11F_TDLSDISREQ ( 49 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSDisReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisReq *pFrm); +tANI_U32 dot11fPackTDLSDisReq(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSDisReqSize(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSDisRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfCapabilities Capabilities; + tDot11fIESuppRates SuppRates; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIESuppChannels SuppChannels; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIERSN RSN; + tDot11fIEExtCap ExtCap; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIERICData RICData; + tDot11fIEHTCaps HTCaps; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEVHTCaps VHTCaps; +} tDot11fTDLSDisRsp; + +#define DOT11F_TDLSDISRSP ( 50 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSDisRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisRsp *pFrm); +tANI_U32 dot11fPackTDLSDisRsp(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSDisRspSize(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSPeerTrafficInd{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEPTIControl PTIControl; + tDot11fIEPUBufferStatus PUBufferStatus; +} tDot11fTDLSPeerTrafficInd; + +#define DOT11F_TDLSPEERTRAFFICIND ( 51 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficInd *pFrm); +tANI_U32 dot11fPackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSPeerTrafficIndSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSPeerTrafficRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIELinkIdentifier LinkIdentifier; +} tDot11fTDLSPeerTrafficRsp; + +#define DOT11F_TDLSPEERTRAFFICRSP ( 52 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficRsp *pFrm); +tANI_U32 dot11fPackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSPeerTrafficRspSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSSetupCnf{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfStatus Status; + tDot11fFfDialogToken DialogToken; + tDot11fIERSN RSN; + tDot11fIEEDCAParamSet EDCAParamSet; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIEHTInfo HTInfo; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEWMMParams WMMParams; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEOperatingMode OperatingMode; +} tDot11fTDLSSetupCnf; + +#define DOT11F_TDLSSETUPCNF ( 53 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSSetupCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupCnf *pFrm); +tANI_U32 dot11fPackTDLSSetupCnf(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSSetupCnfSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSSetupReq{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfCapabilities Capabilities; + tDot11fIESuppRates SuppRates; + tDot11fIECountry Country; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSN RSN; + tDot11fIEExtCap ExtCap; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIERICData RICData; + tDot11fIEHTCaps HTCaps; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAID AID; + tDot11fIEVHTCaps VHTCaps; +} tDot11fTDLSSetupReq; + +#define DOT11F_TDLSSETUPREQ ( 54 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSSetupReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupReq *pFrm); +tANI_U32 dot11fPackTDLSSetupReq(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSSetupReqSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSSetupRsp{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfStatus Status; + tDot11fFfDialogToken DialogToken; + tDot11fFfCapabilities Capabilities; + tDot11fIESuppRates SuppRates; + tDot11fIECountry Country; + tDot11fIEExtSuppRates ExtSuppRates; + tDot11fIESuppChannels SuppChannels; + tDot11fIERSN RSN; + tDot11fIEExtCap ExtCap; + tDot11fIESuppOperatingClasses SuppOperatingClasses; + tDot11fIEQOSCapsStation QOSCapsStation; + tDot11fIEFTInfo FTInfo; + tDot11fIETimeoutInterval TimeoutInterval; + tDot11fIERICData RICData; + tDot11fIEHTCaps HTCaps; + tDot11fIEHT2040BSSCoexistence HT2040BSSCoexistence; + tDot11fIELinkIdentifier LinkIdentifier; + tDot11fIEWMMInfoStation WMMInfoStation; + tDot11fIEAID AID; + tDot11fIEVHTCaps VHTCaps; + tDot11fIEOperatingMode OperatingMode; +} tDot11fTDLSSetupRsp; + +#define DOT11F_TDLSSETUPRSP ( 55 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSSetupRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupRsp *pFrm); +tANI_U32 dot11fPackTDLSSetupRsp(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSSetupRspSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTDLSTeardown{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfReason Reason; + tDot11fIEFTInfo FTInfo; + tDot11fIELinkIdentifier LinkIdentifier; +} tDot11fTDLSTeardown; + +#define DOT11F_TDLSTEARDOWN ( 56 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTDLSTeardown(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSTeardown *pFrm); +tANI_U32 dot11fPackTDLSTeardown(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTDLSTeardownSize(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTPCReport{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIETPCReport TPCReport; +} tDot11fTPCReport; + +#define DOT11F_TPCREPORT ( 57 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCReport *pFrm); +tANI_U32 dot11fPackTPCReport(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTPCReportSize(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fTPCRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fIETPCRequest TPCRequest; +} tDot11fTPCRequest; + +#define DOT11F_TPCREQUEST ( 58 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackTPCRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCRequest *pFrm); +tANI_U32 dot11fPackTPCRequest(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedTPCRequestSize(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fVHTGidManagementActionFrame{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfVhtMembershipStatusArray VhtMembershipStatusArray; + tDot11fFfVhtUserPositionArray VhtUserPositionArray; +} tDot11fVHTGidManagementActionFrame; + +#define DOT11F_VHTGIDMANAGEMENTACTIONFRAME ( 59 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fVHTGidManagementActionFrame *pFrm); +tANI_U32 dot11fPackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedVHTGidManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fWMMAddTSRequest{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatusCode StatusCode; + tDot11fIEWMMTSPEC WMMTSPEC; + tDot11fIEESETrafStrmRateSet ESETrafStrmRateSet; +} tDot11fWMMAddTSRequest; + +#define DOT11F_WMMADDTSREQUEST ( 60 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackWMMAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSRequest *pFrm); +tANI_U32 dot11fPackWMMAddTSRequest(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedWMMAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fWMMAddTSResponse{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatusCode StatusCode; + tDot11fIEWMMTSPEC WMMTSPEC; + tDot11fIEESETrafStrmMet ESETrafStrmMet; +} tDot11fWMMAddTSResponse; + +#define DOT11F_WMMADDTSRESPONSE ( 61 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackWMMAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSResponse *pFrm); +tANI_U32 dot11fPackWMMAddTSResponse(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedWMMAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +typedef struct sDot11fWMMDelTS{ + tDot11fFfCategory Category; + tDot11fFfAction Action; + tDot11fFfDialogToken DialogToken; + tDot11fFfStatusCode StatusCode; + tDot11fIEWMMTSPEC WMMTSPEC; +} tDot11fWMMDelTS; + +#define DOT11F_WMMDELTS ( 62 ) + +#ifdef __cplusplus +extern "C" { +#endif /* C++ */ + +tANI_U32 dot11fUnpackWMMDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMDelTS *pFrm); +tANI_U32 dot11fPackWMMDelTS(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed); +tANI_U32 dot11fGetPackedWMMDelTSSize(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U32 *pnNeeded); + +#ifdef __cplusplus +} /* End extern "C". */ +#endif /* C++ */ + +#endif /* DOT11F_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h b/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h new file mode 100644 index 000000000000..e6e7d98878e8 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/dphGlobal.h @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2011-2013, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + + * Date: 02/25/02 + + * History:- + + * Date Modified by Modification Information + + * -------------------------------------------------------------------- + + * + + */ + + +#ifndef __DPH_GLOBAL_H__ + +#define __DPH_GLOBAL_H__ + + +#include "limGlobal.h" + +//#include "parserApi.h" + +#include "sirMacProtDef.h" + +#include "sirMacPropExts.h" + +#include "sirApi.h" + + +/// Following determines whether statistics are maintained or not + +#define DPH_STATS + + +/// traffic category not allowed + +#define DPH_TID_NOTALLOWED 0xFF + + +/// Periodicity of invocation of rate adaptation (in ms) + +#define DPH_RATE_ADAPTATION_PERIOD 20 + + +// Rate indices + +#define DPH_PHY_RATE_1_INDEX 0 + +#define DPH_PHY_RATE_2_INDEX 1 + +#define DPH_PHY_RATE_5_5_INDEX 2 + +#define DPH_PHY_RATE_11_INDEX 3 + +#define DPH_PHY_RATE_6_INDEX 4 + +#define DPH_PHY_RATE_9_INDEX 5 + +#define DPH_PHY_RATE_12_INDEX 6 + +#define DPH_PHY_RATE_18_INDEX 7 + +#define DPH_PHY_RATE_24_INDEX 8 + +#define DPH_PHY_RATE_36_INDEX 9 + +#define DPH_PHY_RATE_48_INDEX 10 + +#define DPH_PHY_RATE_54_INDEX 11 + +#define DPH_PHY_RATE_72_INDEX 12 + +#define DPH_PHY_RATE_96_INDEX 13 + +#define DPH_PHY_RATE_108_INDEX 14 + +#define DPH_PHY_RATE_144_INDEX 15 + +#define DPH_PHY_RATE_MAX_INDEX 16 + + +/// Maximum time to wait for a management packet to go out (ms) + +#define DPH_MAX_MGMT_WAIT_TIME 10000 + + +/// Step size for the wait time histogram (ms) + +#define DPH_WAIT_HIST_STEP 20 + + +/// Number of entries in wait time histogram + +#define DPH_WAIT_HIST_SIZE 100 + + +/// TCID for Management & Keep Alive Mgmt frames + +#define DPH_MGMT_TCID 4 + +#define DPH_KEEPALIVE_PROBE_RESPONSE_TCID 0 + + +/// STAID for Management frames + +#define DPH_USE_MGMT_STAID -1 + + +// Keep Alive frames + +#define DPH_NON_KEEPALIVE_FRAME 0 + +#define DPH_KEEPALIVE_FRAME 1 + + +/// Mask for subtype, type, protocol version, order and wep fields in the mac frame control + +#define DPH_FC_BD_FILL_MASK 0xFFCC + + +/// Enable/Disable Txop generation in TFP for HCF mode + +#define DPH_ENABLE_HCF_TXOP_GEN_AT_TFP 0x00 + +#define DPH_DISABLE_HCF_TXOP_GEN_AT_TFP 0x02 + + +/// Enable/Disable Txop generation in TFP for EDCF mode + +#define DPH_ENABLE_EDCF_TXOP_GEN_AT_TFP 0x00 + +#define DPH_DISABLE_EDCF_TXOP_GEN_AT_TFP 0x01 + + +#define DPH_DUMP_ALL_STA_ID -1 + +#define DPH_DUMP_RX_BD 0 + +#define DPH_DUMP_TX_BD 1 + +#define DPH_DUMP_TX_MGMT_BD 2 + + +//DPH Hash Index for BSS(STA's Peer) on station. + +#define DPH_STA_HASH_INDEX_PEER 1 + + +#ifdef WLAN_FEATURE_11W +//DPH PMF SA Query state for station + +#define DPH_SA_QUERY_NOT_IN_PROGRESS 1 + +#define DPH_SA_QUERY_IN_PROGRESS 2 + +#define DPH_SA_QUERY_TIMED_OUT 3 +#endif + + +typedef struct sDphRateBasedCtr + +{ + + tANI_U32 hi; + + tANI_U32 lo; + +} tDphRateBasedCtr; + + +typedef struct sDphPhyRates + +{ + + tANI_U8 dataRateX2; + + tANI_U8 ackRateX2; + + tANI_U8 rtsRateX2; + +} tDphPhyRates; + + +typedef struct sDphIFSValues + +{ + + tANI_U8 sifs; + + tANI_U8 pifs; + + tANI_U8 difs; + + tANI_U8 preamble; + +} tDphIFSValues; + + +typedef struct sDphQosParams + +{ + + tANI_U8 addtsPresent; + + tSirAddtsReqInfo addts; + + tSirMacQosCapabilityStaIE capability; + +} tDphQosParams; + + +/// Queue attribute structure + +typedef struct sDphQueueAttr + +{ + + tANI_U16 valid : 1; + + tANI_U16 seqNum : 12; + + tANI_U16 ackPolicy : 2; + + tANI_U16 rsvd : 1; + +} tDphQueueAttr, *tpDphQueueAttr; + + + +typedef struct sCfgTrafficClass { + + //Use Block ACK on this STA/TID + + // Fields used to store the default TC parameters for this TSPEC. + + // They will be used when the TSPEC is deleted. + + tANI_U8 fDisableTx:1; + + tANI_U8 fDisableRx:1; + + tANI_U8 fUseBATx:1; + + tANI_U8 fUseBARx:1; + + + // 1: expect to see frames with compressed BA coming from this peer MAC + + tANI_U8 fRxCompBA:1; + + tANI_U8 fTxCompBA:1; + + + // immediate ACK or delayed ACK for frames from this peer MAC + + tANI_U8 fRxBApolicy:1; + + + // immediate ACK or delayed ACK for frames to this peer MAC + + tANI_U8 fTxBApolicy:1; + + + //Initiator or recipient + + tANI_U8 role; + + + //Max # of MSDU received from this STA, negotiated at ADDBA + + // used for maintaining block ack state info + + tANI_U16 rxBufSize; + + + //Max # of MSDU send to this STA, negotiated at ADDBA + + tANI_U16 txBufSize; + + + //BA timeout negotiated at ADDBA. Unit: TU + + tANI_U16 tuTxBAWaitTimeout; //Time for Tx to wait for BA. 0 means no timeout + + + tANI_U16 tuRxBAWaitTimeout; //Time for Rx to wait for explicit/implicit BAR. 0 means no timeout + + +} tCfgTrafficClass; + + +/** + * struct parsed_ies: Parsed IE's of BSS capability + * @ht_caps: HT caps IE + * @vht_caps: VHT caps IE + * @ht_operation: HT operation IE + * @vht_operation: VHT operation IE + * @hs20vendor_ie: HS2.0 vendor IE + * + * This structure holds the parsed IE of connected BSS + * and this is not the intersection of BSS and STA + * capability. For example, if BSS supports 80 MHz + * and STA connects to BSS in 20 MHz, this structure + * holds 80 MHz as peer capability. + */ +struct parsed_ies { + tDot11fIEHTCaps ht_caps; + tDot11fIEVHTCaps vht_caps; + tDot11fIEHTInfo ht_operation; + tDot11fIEVHTOperation vht_operation; + tDot11fIEhs20vendor_ie hs20vendor_ie; +}; + +/// STA state node + +typedef struct sDphHashNode + +{ + + + //BYTE 0 + + // HASH ENTRY FIELDS NOT NEEDED IN HAL. + + /// This STA valid or not + + tANI_U8 valid : 1; + + tANI_U8 encPolicy : 3; + + tANI_U8 defaultKey : 1; + + tANI_U8 defaultKeyId : 2; + + tANI_U8 qosMode : 1; + + + //BYTE 1 + + tANI_U8 erpEnabled : 1; + + tANI_U8 added : 1; // This has been added to the dph hash table + + tANI_U8 linkTestOn : 1; + + tANI_U8 shortPreambleEnabled : 1; + + tANI_U8 shortSlotTimeEnabled : 1; + + tANI_U8 stopTx:1; + + tANI_U8 wmeEnabled: 1; // set if both ap and sta are wme capable + + tANI_U8 lleEnabled: 1; // set if both ap and sta are 11e capable + + + //BYTE 2 + + tANI_U8 wsmEnabled: 1; // set if both ap and sta are wsm capable + + tANI_U8 versionPresent:1; // station gave version info + + tANI_U8 burstEnableForce:1; // allow bursting regardless of qosMode + + tANI_U8 staAuthenticated:1; + + /// Whether the peer is ANI or not + + tANI_U8 aniPeer:1; + + tANI_U8 titanPeer:1; // flag to indicate if its a titan peer + + tANI_U8 fAniCount:1; + + tANI_U8 rmfEnabled:1; + + + /// Fragmentation size + + tANI_U16 fragSize; + + + /// LIM state + + tLimMlmStaContext mlmStaContext; + + + /// Number of Tim to wait if the STA doesn't respond / fetch data + + tANI_U8 timWaitCount; + + + /// Number of Successfull MPDU's being sent + + tANI_U32 curTxMpduCnt; + + + + + /// number of consecutive TIMs sent without response + + tANI_U8 numTimSent; + + + // qos parameter info + + tDphQosParams qos; + + + // station version info - valid only if versionPresent is set + + tSirMacPropVersion version; + + // station proprietary capability + + tANI_U16 propCapability; + + +#ifdef PLM_WDS + + tANI_U8 wdsIndex; + + tANI_U8 wdsPeerBeaconSeen; + +#endif + + + //Taurus capabilities + + tANI_U16 baPolicyFlag; //BA Policy for each TID. + + + /* + + * All the legacy and airgo supported rates. + + */ + + tSirSupportedRates supportedRates; + + + tANI_U8 htGreenfield:1; + + tANI_U8 htShortGI40Mhz:1; + + tANI_U8 htShortGI20Mhz:1; + + // DSSS/CCK at 40 MHz: Enabled 1 or Disabled + + tANI_U8 htDsssCckRate40MHzSupport:1; + + // L-SIG TXOP Protection used only if peer support available + + tANI_U8 htLsigTXOPProtection:1; + + // A-MPDU Density + + // 000 - No restriction + + // 001 - 1/8 usec + + // 010 - 1/4 usec + + // 011 - 1/2 usec + + // 100 - 1 usec + + // 101 - 2 usec + + // 110 - 4 usec + + // 111 - 8 usec + + // + + tANI_U8 htAMpduDensity:3; + + + + + //Set to 0 for 3839 octets + + //Set to 1 for 7935 octets + + tANI_U8 htMaxAmsduLength; + + + + + // MIMO Power Save + + tSirMacHTMIMOPowerSaveState htMIMOPSState; + + + // + + + // Maximum Rx A-MPDU factor + + tANI_U8 htMaxRxAMpduFactor:2; + + // + + // Recommended Tx Width Set + + // 0 - use 20 MHz channel (control channel) + + // 1 - use 40 Mhz channel + + // + + tANI_U8 htSupportedChannelWidthSet:1; + tANI_U8 htSecondaryChannelOffset:2; + tANI_U8 rsvd1:3; + + + /////////////////////////////////////////////////////////////////////// + + // DPH HASH ENTRY FIELDS NEEDED IN HAL ONLY + + /////////////////////////////////////////////////////////////////////// + + tANI_U8 dpuSig:4; // DPU signiture + + tANI_U8 staSig:4; // STA signature + + tANI_U8 staType; + + + tANI_U16 bssId; // BSSID + + tANI_U16 assocId; // Association ID + + + + + //This is the real sta index generated by HAL + + tANI_U16 staIndex; + + tANI_U8 staAddr[6]; + + /*The DPU signatures will be sent eventually to TL to help it determine the + + association to which a packet belongs to*/ + + /*Unicast DPU signature*/ + + tANI_U8 ucUcastSig; + + + /*Broadcast DPU signature*/ + + tANI_U8 ucBcastSig; + + + // + + // PE needs this info on a per-STA, per-TID basis + + // At any point in time, when this data is sampled, + + // it gives a measure of: + + // a) All the active bA sessions + + // b) And the BA configuration itself + + // + + tCfgTrafficClass tcCfg[STACFG_MAX_TC]; + + + // Block Ack state + + // This is used between PE and HAL only. + + // can be set to one of the values from the following enum + + /*typedef enum eLimBAState + + { + + eLIM_BA_STATE_IDLE, // we are not waiting for anything from HAL. + + eLIM_BA_STATE_WT_ADD_RSP, //We are waiting for Add rsponse from HAL. + + eLIM_BA_STATE_WT_DEL_RSP // We are waiting for Del response from HAL. + + } tLimBAState; */ + + + + + //BA state bitmap 2 bits per tid + + // BA state for tid i = (baState >> tid*2) & 0x3 + + tANI_U32 baState; + +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtSupportedChannelWidthSet; + tANI_U8 vhtBeamFormerCapable; +#endif + +#ifdef WLAN_FEATURE_11W + tANI_U8 pmfSaQueryState; + tANI_U8 pmfSaQueryRetryCount; + tANI_U16 pmfSaQueryCurrentTransId; + tANI_U16 pmfSaQueryStartTransId; + TX_TIMER pmfSaQueryTimer; + v_TIME_t last_unprot_deauth_disassoc; + tANI_U8 proct_deauh_disassoc_cnt; + v_TIME_t last_assoc_received_time; +#endif + + tANI_U8 htLdpcCapable; + tANI_U8 vhtLdpcCapable; + /* key installed for this STA or not in the firmware */ + tANI_U8 isKeyInstalled; + /* When a station with already an existing dph entry tries to + + * associate again, the old dph entry will be zeroed out except + + * for the next pointer. The next pointer must be defined at the + + * end of the structure. + + */ + tANI_U8 isDisassocDeauthInProgress; + bool sta_deletion_in_progress; + struct parsed_ies parsed_ies; +#ifdef SAP_AUTH_OFFLOAD + tANI_U8 dpuIndex; + tANI_U8 bcastDpuIndex; + tANI_U8 bcastMgmtDpuIdx; + tANI_U8 ucMgmtSig; +#endif + struct sDphHashNode *next; + + +} tDphHashNode, *tpDphHashNode; + + +#include "dphHashTable.h" + + +// ------------------------------------------------------------------- + + +// get protection overrides from config variable + +// bit0: force cts to self protection for tx to Airgo peers + +// bit1: force cts to self protection for tx to non Airgo peers + +#define DPH_PROT_OVERRIDE_NONANI_PEER_GET(cfgval) ((cfgval) & 1) + +#define DPH_PROT_OVERRIDE_ANI_PEER_GET(cfgval) (((cfgval) & 2) >> 1) + + +typedef struct sAniSirDph + +{ + + /// The hash table object + + dphHashTableClass dphHashTable; + +} tAniSirDph, *tpAniSirDph; + + +#endif + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/include/parserApi.h b/drivers/staging/prima/CORE/MAC/src/include/parserApi.h new file mode 100644 index 000000000000..fac5c0712729 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/parserApi.h @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file parserApi.h contains the definitions used + * for parsing received 802.11 frames + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __PARSE_H__ +#define __PARSE_H__ + +#include +#include "sirMacPropExts.h" +#include "dot11f.h" +#include "limSession.h" + +#define COUNTRY_STRING_LENGTH ( 3 ) +#define COUNTRY_INFO_MAX_CHANNEL ( 84 ) +#define MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE (COUNTRY_STRING_LENGTH * COUNTRY_INFO_MAX_CHANNEL) +#define HIGHEST_24GHZ_CHANNEL_NUM ( 14 ) + +#define IS_24G_CH(__chNum) ((__chNum > 0) && (__chNum < 14)) +#define IS_5G_CH(__chNum) ((__chNum >= 36) && (__chNum <= 165)) + +#define SIZE_OF_FIXED_PARAM 12 +#define SIZE_OF_TAG_PARAM_NUM 1 +#define SIZE_OF_TAG_PARAM_LEN 1 +#define RSNIEID 0x30 +#define RSNIE_CAPABILITY_LEN 2 +#define DEFAULT_RSNIE_CAP_VAL 0x00 + +typedef struct sSirCountryInformation +{ + tANI_U8 countryString[COUNTRY_STRING_LENGTH]; + tANI_U8 numIntervals; //number of channel intervals + struct channelPowerLim + { + tANI_U8 channelNumber; + tANI_U8 numChannel; + tANI_U8 maxTransmitPower; + } channelTransmitPower[COUNTRY_INFO_MAX_CHANNEL]; +} tSirCountryInformation,*tpSirCountryInformation; + + +/// Structure common to Beaons & Probe Responses +typedef struct sSirProbeRespBeacon +{ + tSirMacTimeStamp timeStamp; + tANI_U16 beaconInterval; + tSirMacCapabilityInfo capabilityInfo; + + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tSirMacChanNum channelNumber; + tSirMacCfParamSet cfParamSet; + tSirMacTim tim; + tSirMacEdcaParamSetIE edcaParams; + tSirMacQosCapabilityIE qosCapability; + + tSirCountryInformation countryInfoParam; + tSirMacWpaInfo wpa; + tSirMacRsnInfo rsn; + + tSirMacErpInfo erpIEInfo; + + tSirPropIEStruct propIEinfo; + tDot11fIEPowerConstraints localPowerConstraint; + tDot11fIETPCReport tpcReport; + tDot11fIEChanSwitchAnn channelSwitchIE; + tDot11fIEExtChanSwitchAnn extChannelSwitchIE; + tSirMacAddr bssid; + tDot11fIEQuiet quietIE; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; + tDot11fIEP2PProbeRes P2PProbeRes; +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 mdie[SIR_MDIE_SIZE]; +#endif +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) +#ifdef FEATURE_WLAN_ESE + tDot11fIEESETxmitPower eseTxPwr; +#endif + tDot11fIEQBSSLoad QBSSLoad; +#endif + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + tANI_U8 cfPresent; + tANI_U8 dsParamsPresent; + tANI_U8 timPresent; + + tANI_U8 edcaPresent; + tANI_U8 qosCapabilityPresent; + tANI_U8 wmeEdcaPresent; + tANI_U8 wmeInfoPresent; + tANI_U8 wsmCapablePresent; + + tANI_U8 countryInfoPresent; + tANI_U8 wpaPresent; + tANI_U8 rsnPresent; + tANI_U8 erpPresent; + tANI_U8 channelSwitchPresent; + tANI_U8 extChannelSwitchPresent; + tANI_U8 quietIEPresent; + tANI_U8 tpcReportPresent; + tANI_U8 powerConstraintPresent; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 mdiePresent; +#endif + +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; + tDot11fIEVHTExtBssLoad VHTExtBssLoad; + tDot11fIEExtCap ExtCap; + tDot11fIEOperatingMode OperatingMode; + tANI_U8 WiderBWChanSwitchAnnPresent; + tDot11fIEWiderBWChanSwitchAnn WiderBWChanSwitchAnn; +#endif + tDot11fIEOBSSScanParameters OBSSScanParameters; + tDot11fIEhs20vendor_ie hs20vendor_ie; + +} tSirProbeRespBeacon, *tpSirProbeRespBeacon; + +// probe Request structure +typedef struct sSirProbeReq +{ + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tDot11fIEWscProbeReq probeReqWscIeInfo; + tDot11fIEHTCaps HTCaps; + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + tANI_U8 wscIePresent; + tANI_U8 p2pIePresent; +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; +#endif + + +} tSirProbeReq, *tpSirProbeReq; + +/// Association Request structure (one day to be replaced by +/// tDot11fAssocRequest) +typedef struct sSirAssocReq +{ + + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 listenInterval; + tSirMacAddr currentApAddr; /* only in reassoc frames */ + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + + tSirAddtsReqInfo addtsReq; + tSirMacQosCapabilityStaIE qosCapability; + + tSirMacWpaInfo wpa; + tSirMacRsnInfo rsn; + tSirAddie addIE; + + tSirPropIEStruct propIEinfo; + tSirMacPowerCapabilityIE powerCapability; + tSirMacSupportedChannelIE supportedChannels; + tDot11fIEHTCaps HTCaps; + tDot11fIEWMMInfoStation WMMInfoStation; + /// This is set if the frame is a reassoc request: + tANI_U8 reassocRequest; + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + + tANI_U8 wmeInfoPresent; + tANI_U8 qosCapabilityPresent; + tANI_U8 addtsPresent; + tANI_U8 wsmCapablePresent; + + tANI_U8 wpaPresent; + tANI_U8 rsnPresent; + tANI_U8 addIEPresent; + + tANI_U8 powerCapabilityPresent; + tANI_U8 supportedChannelsPresent; + // keeing copy of assoction request received, this is + // required for indicating the frame to upper layers + tANI_U32 assocReqFrameLength; + tANI_U8* assocReqFrame; +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tDot11fIEOperatingMode operMode; +#endif + tDot11fIEhs20vendor_ie hs20vendor_ie; +} tSirAssocReq, *tpSirAssocReq; + + +/// Association Response structure (one day to be replaced by +/// tDot11fAssocRequest) +typedef struct sSirAssocRsp +{ + + tSirMacCapabilityInfo capabilityInfo; + tANI_U16 aid; + tANI_U16 statusCode; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tSirPropIEStruct propIEinfo; + tSirMacEdcaParamSetIE edca; + tSirAddtsRspInfo addtsRsp; + tDot11fIEHTCaps HTCaps; + tDot11fIEHTInfo HTInfo; +#if defined WLAN_FEATURE_VOWIFI_11R + tDot11fIEFTInfo FTInfo; + tANI_U8 mdie[SIR_MDIE_SIZE]; + tANI_U8 num_RICData; + tDot11fIERICDataDesc RICData[2]; +#endif + +#ifdef FEATURE_WLAN_ESE + tANI_U8 num_tspecs; + tDot11fIEWMMTSPEC TSPECInfo[SIR_ESE_MAX_TSPEC_IES]; + tSirMacESETSMIE tsmIE; +#endif + + tANI_U8 suppRatesPresent; + tANI_U8 extendedRatesPresent; + + tANI_U8 edcaPresent; + tANI_U8 wmeEdcaPresent; + tANI_U8 addtsPresent; + tANI_U8 wsmCapablePresent; +#if defined WLAN_FEATURE_VOWIFI_11R + tANI_U8 ftinfoPresent; + tANI_U8 mdiePresent; + tANI_U8 ricPresent; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U8 tspecPresent; + tANI_U8 tsmPresent; +#endif +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tDot11fIEVHTOperation VHTOperation; +#endif + tDot11fIEExtCap ExtCap; + tDot11fIEOBSSScanParameters OBSSScanParameters; + tSirQosMapSet QosMapSet; +} tSirAssocRsp, *tpSirAssocRsp; + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +// Structure to hold Ese Beacon report mandatory IEs +typedef struct sSirEseBcnReportMandatoryIe +{ + tSirMacSSid ssId; + tSirMacRateSet supportedRates; + tSirMacFHParamSet fhParamSet; + tSirMacDsParamSetIE dsParamSet; + tSirMacCfParamSet cfParamSet; + tSirMacIBSSParams ibssParamSet; + tSirMacTim tim; + tSirMacRRMEnabledCap rmEnabledCapabilities; + + tANI_U8 ssidPresent; + tANI_U8 suppRatesPresent; + tANI_U8 fhParamPresent; + tANI_U8 dsParamsPresent; + tANI_U8 cfPresent; + tANI_U8 ibssParamPresent; + tANI_U8 timPresent; + tANI_U8 rrmPresent; +} tSirEseBcnReportMandatoryIe, *tpSirEseBcnReportMandatoryIe; +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +struct s_ext_cap { + uint8_t bssCoexistMgmtSupport: 1; + uint8_t reserved1: 1; + uint8_t extChanSwitch: 1; + uint8_t reserved2: 1; + uint8_t psmpCap: 1; + uint8_t reserved3: 1; + uint8_t spsmpCap: 1; + uint8_t event: 1; + uint8_t diagnostics: 1; + uint8_t multiDiagnostics: 1; + uint8_t locTracking: 1; + uint8_t FMS: 1; + uint8_t proxyARPService: 1; + uint8_t coLocIntfReporting: 1; + uint8_t civicLoc: 1; + uint8_t geospatialLoc: 1; + uint8_t TFS: 1; + uint8_t wnmSleepMode: 1; + uint8_t timBroadcast: 1; + uint8_t bssTransition: 1; + uint8_t qosTrafficCap: 1; + uint8_t acStaCnt: 1; + uint8_t multiBSSID: 1; + uint8_t timingMeas: 1; + uint8_t chanUsage: 1; + uint8_t ssidList: 1; + uint8_t DMS: 1; + uint8_t UTCTSFOffset: 1; + uint8_t TDLSPeerUAPSDBufferSTA: 1; + uint8_t TDLSPeerPSMSupp: 1; + uint8_t TDLSChannelSwitching: 1; + uint8_t interworkingService: 1; + uint8_t qosMap: 1; + uint8_t EBR: 1; + uint8_t sspnInterface: 1; + uint8_t reserved4: 1; + uint8_t msgCFCap: 1; + uint8_t TDLSSupport: 1; + uint8_t TDLSProhibited: 1; + uint8_t TDLSChanSwitProhibited: 1; + uint8_t rejectUnadmittedTraffic: 1; + uint8_t serviceIntervalGranularity: 3; + uint8_t identifierLoc: 1; + uint8_t uapsdCoexistence: 1; + uint8_t wnmNotification: 1; + uint8_t QABcapbility: 1; + uint8_t UTF8SSID: 1; + uint8_t QMFActivated: 1; + uint8_t QMFreconAct: 1; + uint8_t RobustAVStreaming: 1; + uint8_t AdvancedGCR: 1; + uint8_t MeshGCR: 1; + uint8_t SCS: 1; + uint8_t QLoadReport: 1; + uint8_t AlternateEDCA: 1; + uint8_t UnprotTXOPneg: 1; + uint8_t ProtTXOPneg: 1; + uint8_t reserved6: 1; + uint8_t ProtQLoadReport: 1; + uint8_t TDLSWiderBW: 1; + uint8_t operModeNotification: 1; + uint8_t maxNumOfMSDU_bit1: 1; + uint8_t maxNumOfMSDU_bit2: 1; + uint8_t ChanSchMgmt: 1; + uint8_t GeoDBInbandEnSignal: 1; + uint8_t NwChanControl: 1; + uint8_t WhiteSpaceMap: 1; + uint8_t ChanAvailQuery: 1; + uint8_t fineTimingMeas: 1; + uint8_t reserved7: 1; +}; + +tANI_U8 +sirIsPropCapabilityEnabled(struct sAniSirGlobal *pMac, tANI_U32 bitnum); + +tSirRetStatus +sirGetCfgPropCaps(struct sAniSirGlobal *, tANI_U16 *); + +void dot11fLog(tpAniSirGlobal pMac, int nSev, const char *lpszFormat, ...); + +#define CFG_GET_INT(nStatus, pMac, nItem, cfg ) do { \ + (nStatus) = wlan_cfgGetInt( (pMac), (nItem), & (cfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return nStatus; \ + } \ + } while (0) + +#define CFG_GET_INT_NO_STATUS(nStatus, pMac, nItem, cfg ) do { \ + (nStatus) = wlan_cfgGetInt( (pMac), (nItem), & (cfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return; \ + } \ + } while (0) + +#define CFG_GET_STR(nStatus, pMac, nItem, cfg, nCfg, nMaxCfg) do { \ + (nCfg) = (nMaxCfg); \ + (nStatus) = wlan_cfgGetStr( (pMac), (nItem), (cfg), & (nCfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return nStatus; \ + } \ + } while (0) + +#define CFG_GET_STR_NO_STATUS(nStatus, pMac, nItem, cfg, nCfg, \ + nMaxCfg) do { \ + (nCfg) = (nMaxCfg); \ + (nStatus) = wlan_cfgGetStr( (pMac), (nItem), (cfg), & (nCfg) ); \ + if ( eSIR_SUCCESS != (nStatus) ) \ + { \ + dot11fLog( (pMac), LOGP, FL("Failed to retrieve " \ + #nItem " from CFG (%d)."), \ + (nStatus) ); \ + return; \ + } \ + } while (0) + +void swapBitField16(tANI_U16 in, tANI_U16 *out); + +// Currently implemented as "shims" between callers & the new framesc- +// generated code: + +tSirRetStatus +sirConvertProbeReqFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tpSirProbeReq probe); + +tSirRetStatus +sirConvertProbeFrame2Struct(struct sAniSirGlobal *pMac, tANI_U8 *frame, + tANI_U32 len, + tpSirProbeRespBeacon probe); + +tSirRetStatus +sirConvertAssocReqFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirAssocReq assoc); + +tSirRetStatus +sirConvertAssocRespFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirAssocRsp assoc); + +tSirRetStatus +sirConvertReassocReqFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirAssocReq assoc); + +tSirRetStatus +sirParseBeaconIE(struct sAniSirGlobal *pMac, + tpSirProbeRespBeacon pBeaconStruct, + tANI_U8 *pPayload, + tANI_U32 payloadLength); + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +tSirRetStatus +sirFillBeaconMandatoryIEforEseBcnReport(tpAniSirGlobal pMac, + tANI_U8 *pPayload, + const tANI_U32 payloadLength, + tANI_U8 **outIeBuf, + tANI_U32 *pOutIeLen); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +tSirRetStatus +sirConvertBeaconFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *pBeaconFrame, + tpSirProbeRespBeacon pBeaconStruct); + +tSirRetStatus +sirConvertAuthFrame2Struct(struct sAniSirGlobal *pMac, + tANI_U8 * frame, + tANI_U32 len, + tpSirMacAuthFrameBody auth); + +tSirRetStatus +sirConvertAddtsReq2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tSirAddtsReqInfo *addTs); + +tSirRetStatus +sirConvertAddtsRsp2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tSirAddtsRspInfo *addts); + +tSirRetStatus +sirConvertDeltsReq2Struct(struct sAniSirGlobal *pMac, + tANI_U8 *frame, + tANI_U32 len, + tSirDeltsReqInfo *delTs); +tSirRetStatus +sirConvertQosMapConfigureFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirQosMapSet *pQosMapSet); + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +sirConvertTpcReqFrame2Struct(struct sAniSirGlobal *, tANI_U8 *, + tpSirMacTpcReqActionFrame, tANI_U32); + +tSirRetStatus +sirConvertMeasReqFrame2Struct(struct sAniSirGlobal *, tANI_U8 *, + tpSirMacMeasReqActionFrame, tANI_U32); +#endif + + +/** + * \brief Populated a tDot11fFfCapabilities + * + * \sa PopulatedDot11fCapabilities2 + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param pDot11f Address of a tDot11fFfCapabilities to be filled in + * + * + * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled, we'll clear the QOS + * bit in pDot11f + * + * + */ + +tSirRetStatus +PopulateDot11fCapabilities(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + tpPESession psessionEntry); + +/** + * \brief Populated a tDot11fFfCapabilities + * + * \sa PopulatedDot11fCapabilities2 + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param pDot11f Address of a tDot11fFfCapabilities to be filled in + * + * \param pSta Pointer to a tDphHashNode representing a peer + * + * + * \note If SIR_MAC_PROP_CAPABILITY_11EQOS is enabled on our peer, we'll + * clear the QOS bit in pDot11f + * + * + */ + +struct sDphHashNode; + +tSirRetStatus +PopulateDot11fCapabilities2(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + struct sDphHashNode *pSta, + tpPESession psessionEntry); + +/// Populate a tDot11fIEChanSwitchAnn +void +PopulateDot11fChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEChanSwitchAnn *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11fIEChanSwitchAnn +void +PopulateDot11fExtChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEExtChanSwitchAnn *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11fIECountry +tSirRetStatus +PopulateDot11fCountry(tpAniSirGlobal pMac, + tDot11fIECountry *pDot11f, tpPESession psessionEntry); + +/// Populated a PopulateDot11fDSParams +tSirRetStatus +PopulateDot11fDSParams(tpAniSirGlobal pMac, + tDot11fIEDSParams *pDot11f, tANI_U8 channel, + tpPESession psessionEntry); + + +/// Populated a tDot11fIEEDCAParamSet +void +PopulateDot11fEDCAParamSet(tpAniSirGlobal pMac, + tDot11fIEEDCAParamSet *pDot11f, + tpPESession psessionEntry); + +tSirRetStatus +PopulateDot11fERPInfo(tpAniSirGlobal pMac, + tDot11fIEERPInfo *pDot11f, tpPESession psessionEntry); + +tSirRetStatus +PopulateDot11fExtSuppRates(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, tDot11fIEExtSuppRates *pDot11f, + tpPESession psessionEntry); + +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus +PopulateDot11fBeaconReport(tpAniSirGlobal pMac, + tDot11fIEMeasurementReport *pDot11f, + tSirMacBeaconReport *pBeaconReport ); +#endif + +/** + * \brief Populate a tDot11fIEExtSuppRates + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param nChannelNum Channel on which the enclosing frame will be going out + * + * \param pDot11f Address of a tDot11fIEExtSuppRates struct to be filled in. + * + * + * This method is a NOP if the channel is greater than 14. + * + * + */ + +tSirRetStatus +PopulateDot11fExtSuppRates1(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIEExtSuppRates *pDot11f); + +tSirRetStatus +PopulateDot11fHCF(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEHCF *pDot11f); + +tSirRetStatus +PopulateDot11fHTCaps(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEHTCaps *pDot11f); + +tSirRetStatus +PopulateDot11fHTInfo(tpAniSirGlobal pMac, + tDot11fIEHTInfo *pDot11f, + tpPESession psessionEntry); + +#ifdef WLAN_FEATURE_AP_HT40_24G +tSirRetStatus +PopulateDot11fOBSSScanParameters(tpAniSirGlobal pMac, + tDot11fIEOBSSScanParameters *pDot11f, + tpPESession psessionEntry); +#endif + +void PopulateDot11fIBSSParams(tpAniSirGlobal pMac, + tDot11fIEIBSSParams *pDot11f, tpPESession psessionEntry); + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +PopulateDot11fMeasurementReport0(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f); + +/// Populate a tDot11fIEMeasurementReport when the report type is CCA +tSirRetStatus +PopulateDot11fMeasurementReport1(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f); + +/// Populate a tDot11fIEMeasurementReport when the report type is RPI Hist +tSirRetStatus +PopulateDot11fMeasurementReport2(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f); +#endif //ANI_SUPPORT_11H + +/// Populate a tDot11fIEPowerCaps +void +PopulateDot11fPowerCaps(tpAniSirGlobal pMac, + tDot11fIEPowerCaps *pCaps, + tANI_U8 nAssocType,tpPESession psessionEntry); + +/// Populate a tDot11fIEPowerConstraints +tSirRetStatus +PopulateDot11fPowerConstraints(tpAniSirGlobal pMac, + tDot11fIEPowerConstraints *pDot11f); + +tSirRetStatus +PopulateDot11fPropCapability(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEPropCapability *pDot11f); + +void +PopulateDot11fPropChannSwitchAnn(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEPropChannSwitchAnn *pDot11f); + +void +PopulateDot11fPropEDCAParams(tpAniSirGlobal pMac, + tANI_U16 caps, + tDot11fIEPropEDCAParams *pDot11f); + +tSirRetStatus +PopulateDot11fPropSuppRates(tpAniSirGlobal pMac, + tANI_U32 capEnable, + tDot11fIEPropSuppRates *pDot11f); + +void +PopulateDot11fQOSCapsAp(tpAniSirGlobal pMac, + tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry); + +void +PopulateDot11fQOSCapsStation(tpAniSirGlobal pMac, + tDot11fIEQOSCapsStation *pDot11f); + +tSirRetStatus +PopulateDot11fRSN(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSN *pDot11f); + +tSirRetStatus +PopulateDot11fRSNOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSNOpaque *pDot11f ); + +#if defined(FEATURE_WLAN_WAPI) + +tSirRetStatus +PopulateDot11fWAPI(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPI *pDot11f); + +tSirRetStatus PopulateDot11fWAPIOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPIOpaque *pDot11f ); + +#endif //defined(FEATURE_WLAN_WAPI) + +/// Populate a tDot11fIESSID given a tSirMacSSid +void +PopulateDot11fSSID(tpAniSirGlobal pMac, + tSirMacSSid *pInternal, + tDot11fIESSID *pDot11f); + +/// Populate a tDot11fIESSID from CFG +tSirRetStatus +PopulateDot11fSSID2(tpAniSirGlobal pMac, + tDot11fIESSID *pDot11f); + + +/** + * \brief Populate a tDot11fIESchedule + * + * \sa PopulateDot11fWMMSchedule + * + * + * \param pSchedule Address of a tSirMacScheduleIE struct + * + * \param pDot11f Address of a tDot11fIESchedule to be filled in + * + * + */ + +void +PopulateDot11fSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIESchedule *pDot11f); + +void +PopulateDot11fSuppChannels(tpAniSirGlobal pMac, + tDot11fIESuppChannels *pDot11f, + tANI_U8 nAssocType,tpPESession psessionEntry); + +/** + * \brief Populated a tDot11fIESuppRates + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param nChannelNum Channel the enclosing frame will be going out on; see + * below + * + * \param pDot11f Address of a tDot11fIESuppRates struct to be filled in. + * + * + * If nChannelNum is greater than 13, the supported rates will be + * WNI_CFG_SUPPORTED_RATES_11B. If it is less than or equal to 13, the + * supported rates will be WNI_CFG_SUPPORTED_RATES_11A. If nChannelNum is + * set to the sentinel value POPULATE_DOT11F_RATES_OPERATIONAL, the struct + * will be populated with WNI_CFG_OPERATIONAL_RATE_SET. + * + * + */ + +#define POPULATE_DOT11F_RATES_OPERATIONAL ( 0xff ) + +tSirRetStatus +PopulateDot11fSuppRates(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIESuppRates *pDot11f,tpPESession); + +tSirRetStatus +PopulateDot11fRatesTdls(tpAniSirGlobal p_mac, + tDot11fIESuppRates *p_supp_rates, + tDot11fIEExtSuppRates *p_ext_supp_rates, + tANI_U8 curr_oper_channel); + +tSirRetStatus PopulateDot11fTPCReport(tpAniSirGlobal pMac, + tDot11fIETPCReport *pDot11f, + tpPESession psessionEntry); + +/// Populate a tDot11FfTSInfo +void PopulateDot11fTSInfo(tSirMacTSInfo *pInfo, + tDot11fFfTSInfo *pDot11f); + + +void PopulateDot11fWMM(tpAniSirGlobal pMac, + tDot11fIEWMMInfoAp *pInfo, + tDot11fIEWMMParams *pParams, + tDot11fIEWMMCaps *pCaps, + tpPESession psessionEntry); + +void PopulateDot11fWMMCaps(tDot11fIEWMMCaps *pCaps); + +#if defined(FEATURE_WLAN_ESE) +// Fill the ESE version IE +void PopulateDot11fESEVersion(tDot11fIEESEVersion *pESEVersion); +// Fill the Radio Management Capability +void PopulateDot11fESERadMgmtCap(tDot11fIEESERadMgmtCap *pESERadMgmtCap); +// Fill the CCKM IE +tSirRetStatus PopulateDot11fESECckmOpaque( tpAniSirGlobal pMac, + tpSirCCKMie pCCKMie, + tDot11fIEESECckmOpaque *pDot11f ); + +void PopulateDot11TSRSIE(tpAniSirGlobal pMac, + tSirMacESETSRSIE *pOld, + tDot11fIEESETrafStrmRateSet *pDot11f, + tANI_U8 rate_length); +void PopulateDot11fReAssocTspec(tpAniSirGlobal pMac, tDot11fReAssocRequest *pReassoc, tpPESession psessionEntry); +#endif + +void PopulateDot11fWMMInfoAp(tpAniSirGlobal pMac, + tDot11fIEWMMInfoAp *pInfo, + tpPESession psessionEntry); + +void PopulateDot11fWMMInfoStation(tpAniSirGlobal pMac, + tDot11fIEWMMInfoStation *pInfo); + +void PopulateDot11fWMMParams(tpAniSirGlobal pMac, + tDot11fIEWMMParams *pParams, + tpPESession psessionEntry); + +/** + * \brief Populate a tDot11fIEWMMSchedule + * + * \sa PopulatedDot11fSchedule + * + * + * \param pSchedule Address of a tSirMacScheduleIE struct + * + * \param pDot11f Address of a tDot11fIEWMMSchedule to be filled in + * + * + */ + +void +PopulateDot11fWMMSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIEWMMSchedule *pDot11f); + +tSirRetStatus +PopulateDot11fWPA(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPA *pDot11f); + +tSirRetStatus +PopulateDot11fWPAOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPAOpaque *pDot11f ); + +void +PopulateDot11fTSPEC(tSirMacTspecIE *pOld, + tDot11fIETSPEC *pDot11f); + +void +PopulateDot11fWMMTSPEC(tSirMacTspecIE *pOld, + tDot11fIEWMMTSPEC *pDot11f); + +tSirRetStatus +PopulateDot11fTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIETCLAS *pDot11f); + +tSirRetStatus +PopulateDot11fWMMTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIEWMMTCLAS *pDot11f); + + +tSirRetStatus PopulateDot11fWsc(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f); + +tSirRetStatus PopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f); + +tSirRetStatus DePopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f); + +tSirRetStatus PopulateDot11fProbeResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscProbeRes *pDot11f, tpPESession psessionEntry); +tSirRetStatus PopulateDot11fAssocResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscAssocRes *pDot11f, tpPESession psessionEntry); +tSirRetStatus PopulateDot11fBeaconWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscBeacon *pDot11f, tpPESession psessionEntry); + +tSirRetStatus PopulateDot11fWscInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f); + +tSirRetStatus PopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f); + +tSirRetStatus DePopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f); + + +tSirRetStatus PopulateDot11fAssocResWscIE(tpAniSirGlobal pMac, + tDot11fIEWscAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq); + +tSirRetStatus PopulateDot11AssocResP2PIE(tpAniSirGlobal pMac, + tDot11fIEP2PAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq); + +tSirRetStatus PopulateDot11fWscInAssocRes(tpAniSirGlobal pMac, + tDot11fIEWscAssocRes *pDot11f); + + +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus PopulateDot11fWFATPC( tpAniSirGlobal pMac, + tDot11fIEWFATPC *pDot11f, tANI_U8 txPower, tANI_U8 linkMargin ); + +tSirRetStatus PopulateDot11fRRMIe( tpAniSirGlobal pMac, + tDot11fIERRMEnabledCap *pDot11f, + tpPESession psessionEntry ); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +void PopulateMDIE( tpAniSirGlobal pMac, + tDot11fIEMobilityDomain *pDot11f, tANI_U8 mdie[] ); +void PopulateFTInfo( tpAniSirGlobal pMac, + tDot11fIEFTInfo *pDot11f ); +#endif + +void PopulateDot11fAssocRspRates ( tpAniSirGlobal pMac, tDot11fIESuppRates *pSupp, + tDot11fIEExtSuppRates *pExt, tANI_U16 *_11bRates, tANI_U16 *_11aRates ); + +int FindIELocation( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tANI_U8 EID); + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +PopulateDot11fVHTCaps(tpAniSirGlobal pMac, tDot11fIEVHTCaps *pDot11f, + tANI_U8 nChannelNum, tAniBool isProbeRspAssocRspBeacon); + +tSirRetStatus +PopulateDot11fVHTOperation(tpAniSirGlobal pMac, + tDot11fIEVHTOperation *pDot11f, tANI_U8 nChannelNum); + +tSirRetStatus +PopulateDot11fVHTExtBssLoad(tpAniSirGlobal pMac, tDot11fIEVHTExtBssLoad *pDot11f); + +tSirRetStatus +PopulateDot11fExtCap(tpAniSirGlobal pMac, tDot11fIEExtCap * pDot11f, + tPESession *sessionEntry); + +tSirRetStatus +PopulateDot11fOperatingMode(tpAniSirGlobal pMac, tDot11fIEOperatingMode *pDot11f, tpPESession psessionEntry ); + +void +PopulateDot11fWiderBWChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEWiderBWChanSwitchAnn *pDot11f, + tpPESession psessionEntry); +#endif + +void PopulateDot11fTimeoutInterval( tpAniSirGlobal pMac, + tDot11fIETimeoutInterval *pDot11f, + tANI_U8 type, tANI_U32 value ); + +tSirRetStatus ValidateAndRectifyIEs(tpAniSirGlobal pMac, + tANI_U8 *pMgmtFrame, + tANI_U32 nFrameBytes, + tANI_U32 *nMissingRsnBytes); +#ifdef SAP_AUTH_OFFLOAD +void +sap_auth_offload_update_rsn_ie(tpAniSirGlobal pmac, + tDot11fIERSNOpaque *pdot11f); +#endif /* SAP_AUTH_OFFLOAD */ + +/** + * sir_copy_hs20_ie() - Update HS 2.0 Information Element. + * @dest: dest HS IE buffer to be updated + * @src: src HS IE buffer + * + * Update HS2.0 IE info from src to dest + * + * Return: void + */ +void sir_copy_hs20_ie(tDot11fIEhs20vendor_ie *dest, + tDot11fIEhs20vendor_ie *src); +#endif /* __PARSE_H__ */ diff --git a/drivers/staging/prima/CORE/MAC/src/include/phyGlobal.h b/drivers/staging/prima/CORE/MAC/src/include/phyGlobal.h new file mode 100644 index 000000000000..5859e1e4f7c7 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/phyGlobal.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * + * + * phyGlobal.h: Holds all globals for the phy, rf, and asic layers in hal + * Author: Mark Nelson + * Date: 4/9/05 + * + * History - + * Date Modified by Modification Information + -------------------------------------------------------------------------- + */ + +#ifndef PHYGLOBAL_H +#define PHYGLOBAL_H + +#include "halPhyVos.h" +#include "wlan_rf.h" +#include "wlan_phy.h" +#include "phyTxPower.h" +#include +#include "asic.h" +#include "wlan_nv.h" + + + +//#define ANI_MANF_DIAG //temporary until this is part of manfDiag build - aniGlobal.h needs this to build the ptt globals + +#ifdef VOLANS_VSWR_WORKAROUND +#define OPEN_LOOP_TX_HIGH_GAIN_OVERRIDE 6 //used for RVR tests in open loop mode +#else +#define OPEN_LOOP_TX_HIGH_GAIN_OVERRIDE 10 //used for RVR tests in open loop mode +#endif +#define OPEN_LOOP_TX_LOW_GAIN_OVERRIDE 3 //used for throughput tests in open loop mode + +// Function pointer for to the CB function after set channel response from FW +typedef void (*funcHalSetChanCB)(tpAniSirGlobal, void*, tANI_U32, tANI_U16); + +// Structure to save the context from where the set channel is called +typedef struct sPhySetChanCntx { + tANI_U8 newChannel; + tANI_U8 newRfBand; + tANI_U8 newCbState; + tANI_U8 newCalReqd; + void* pData; + funcHalSetChanCB pFunc; + tANI_U16 dialog_token; +} tPhySetChanCntx, *tpPhySetChanCntx; + + +typedef struct +{ + sHalNv nvCache; + void *nvTables[NUM_NV_TABLE_IDS]; + + //event object for blocked wait around halPhySetChannel + HAL_PHY_SET_CHAN_EVENT_TYPE setChanEvent; + tANI_U32 fwSetChannelStatus; + + tPhySetChanCntx setChanCntx; + + //physical layer data - corresponds to individual modules + tPhy phy; + tAsicTxFir txfir; + //tPhyTxPower phyTPC; + tRF rf; + tAsicAgc agc; + + tANI_BOOLEAN wfm_clk80; //=ON if 20MHZ clock samples, =OFF for 80MHZ clock samples + tANI_U8 calPeriodTicks; //counts peiodic interrupts since last periodic calibration + tANI_BOOLEAN densityEnabled; + ePhyNwDensity nwDensity20MHz; // Network density value for 20MHz channel width + ePhyNwDensity nwDensity40MHz; // Network density value for 40MHz channel width + ePhyRxDisabledPktTypes modTypes; //current disabled packet types + volatile tANI_BOOLEAN setPhyMsgEvent; + tANI_U32 hdetResidualDCO; +}tAniSirPhy; + +#endif /* PHYGLOBAL_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/include/sirCommon.h b/drivers/staging/prima/CORE/MAC/src/include/sirCommon.h new file mode 100644 index 000000000000..7271a357dbdd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/sirCommon.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file sirCommon.h contains the common definitions used by all + * Firmware modules. + * + * Author: V. K. Kandarpa + * Date: 04/12/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIRCOMMON_H +#define __SIRCOMMON_H + +#include "sirApi.h" +#include "sirParams.h" +#include "VossWrapper.h" + +/* ********************************************* * + * * + * SIRIUS SYSTEM EXTERNAL GLOBALS * + * * + * ********************************************* */ + + +// All the following are resource definitions + +#endif /* __SIRCOMMON_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/include/sirDebug.h b/drivers/staging/prima/CORE/MAC/src/include/sirDebug.h new file mode 100644 index 000000000000..3fc15df66ab3 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/sirDebug.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __POL_DEBUG_H__ +#define __POL_DEBUG_H__ + +#define LOGOFF 0 +#define LOGP 1 +#define LOGE 2 +#define LOGW 3 +#define LOG1 4 +#define LOG2 5 +#define LOG3 6 +#define LOG4 7 + +#ifdef ANI_DEBUG +#define PMM_LOG_LEVEL LOG4 +#define SCH_LOG_LEVEL LOG4 +#define ARQ_LOG_LEVEL LOG4 +#define LIM_LOG_LEVEL LOG4 +#define HAL_LOG_LEVEL LOG4 +#define SYS_LOG_LEVEL LOG4 +#define CFG_LOG_LEVEL LOG4 +#define DPH_LOG_LEVEL LOG4 +#else +#define PMM_LOG_LEVEL LOGW +#define SCH_LOG_LEVEL LOGW +#define ARQ_LOG_LEVEL LOGW +#define LIM_LOG_LEVEL LOGW +#define HAL_LOG_LEVEL LOGW +#define SYS_LOG_LEVEL LOGW +#define CFG_LOG_LEVEL LOGW +#define DPH_LOG_LEVEL LOGW +#endif + + +#ifdef WLAN_MDM_CODE_REDUCTION_OPT +#ifdef PE_DEBUG_LOGE +#define PELOGE(p) { p } +#else +#define PELOGE(p) { } +#endif + +#ifdef PE_DEBUG_LOGW +#define PELOGW(p) { p } +#else +#define PELOGW(p) { } +#endif + +#define PELOG1(p) { } +#define PELOG2(p) { } +#define PELOG3(p) { } +#define PELOG4(p) { } + + +#else /* WLAN_MDM_CODE_REDUCTION_OPT */ + +#ifdef PE_DEBUG_LOGE +#define PELOGE(p) { p } +#else +#define PELOGE(p) { } +#endif + +#ifdef PE_DEBUG_LOGW +#define PELOGW(p) { p } +#else +#define PELOGW(p) { } +#endif + +#ifdef PE_DEBUG_LOG1 +#define PELOG1(p) { p } +#else +#define PELOG1(p) { } +#endif + +#ifdef PE_DEBUG_LOG2 +#define PELOG2(p) { p } +#else +#define PELOG2(p) { } +#endif + +#ifdef PE_DEBUG_LOG3 +#define PELOG3(p) { p } +#else +#define PELOG3(p) { } +#endif + +#ifdef PE_DEBUG_LOG4 +#define PELOG4(p) { p } +#else +#define PELOG4(p) { } +#endif + +#endif /* WLAN_MDM_CODE_REDUCTION_OPT */ + +#define FL(x) "%s: %d: "\ + x, __func__, __LINE__ + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/include/sirParams.h b/drivers/staging/prima/CORE/MAC/src/include/sirParams.h new file mode 100644 index 000000000000..dca671d347e6 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/sirParams.h @@ -0,0 +1,985 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file sirParams.h contains the common parameter definitions, which + * are not dependent on threadX API. These can be used by all Firmware + * modules. + * + * Author: Sandesh Goel + * Date: 04/13/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SIRPARAMS_H +#define __SIRPARAMS_H + +# include "sirTypes.h" + +// Firmware wide constants + +#define SIR_MAX_PACKET_SIZE 2048 +#define SIR_MAX_NUM_CHANNELS 64 +#define SIR_MAX_NUM_STA_IN_IBSS 16 +#define SIR_MAX_NUM_STA_IN_BSS 256 +#define SIR_ESE_MAX_MEAS_IE_REQS 8 + +typedef enum +{ + PHY_SINGLE_CHANNEL_CENTERED = 0, // 20MHz IF bandwidth centered on IF carrier + PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, // 40MHz IF bandwidth with lower 20MHz supporting the primary channel + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, // 40MHz IF bandwidth with higher 20MHz supporting the primary channel +#ifdef WLAN_FEATURE_11AC + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + PHY_CHANNEL_BONDING_STATE_MAX = 11 +}ePhyChanBondState; + +#define SIR_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define SIR_MAX(a,b) (((a) > (b)) ? (a) : (b)) + +typedef enum { + MCC = 0, + P2P = 1, + DOT11AC = 2, + SLM_SESSIONIZATION = 3, + DOT11AC_OPMODE = 4, + SAP32STA = 5, + TDLS = 6, + P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7, + WLANACTIVE_OFFLOAD = 8, + RTT = 20, + WOW = 22, +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WLAN_ROAM_SCAN_OFFLOAD = 23, +#endif + IBSS_HEARTBEAT_OFFLOAD = 26, + WLAN_PERIODIC_TX_PTRN = 28, +#ifdef FEATURE_WLAN_TDLS + ADVANCE_TDLS = 29, +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + BATCH_SCAN = 30, +#endif + FW_IN_TX_PATH = 31, + EXTENDED_NSOFFLOAD_SLOT = 32, + CH_SWITCH_V1 = 33, + HT40_OBSS_SCAN = 34, + UPDATE_CHANNEL_LIST = 35, + WLAN_MCADDR_FLT = 36, + WLAN_CH144 = 37, + NAN = 38, +#ifdef FEATURE_WLAN_TDLS + TDLS_SCAN_COEXISTENCE = 39, +#endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + LINK_LAYER_STATS_MEAS = 40, +#endif + + MU_MIMO = 41, +#ifdef WLAN_FEATURE_EXTSCAN + EXTENDED_SCAN = 42, +#endif + + DYNAMIC_WMM_PS = 43, + MAC_SPOOFED_SCAN = 44, + BMU_ERROR_GENERIC_RECOVERY = 45, + DISA = 46, + FW_STATS = 47, + WPS_PRBRSP_TMPL = 48, + BCN_IE_FLT_DELTA = 49, +#ifdef FEATURE_WLAN_TDLS + TDLS_OFF_CHANNEL = 51, +#endif + RTT3 = 52, + MGMT_FRAME_LOGGING = 53, + ENHANCED_TXBD_COMPLETION = 54, + LOGGING_ENHANCEMENT = 55, + +#ifdef WLAN_FEATURE_EXTSCAN + EXT_SCAN_ENHANCED = 56, +#endif + + MEMORY_DUMP_SUPPORTED = 57, + PER_PKT_STATS_SUPPORTED = 58, + EXT_LL_STAT = 60, + WIFI_CONFIG = 61, + ANTENNA_DIVERSITY_SELECTION = 62, +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + PER_BASED_ROAMING = 63, +#endif + SAP_MODE_WOW = 64, + /* SAP_OFFLOADS flag will be used for + * SAP auth offload, SAP DHCP offload and + * SAP DNS offload. + */ + SAP_OFFLOADS = 65, + SAP_BUFF_ALLOC = 66, +#ifdef WLAN_FEATURE_LFR_MBB + MAKE_BEFORE_BREAK = 67, +#endif + NUD_DEBUG = 68, + FATAL_EVENT_LOGGING = 69, + /*70 reserved for WIFI_DUAL_BAND_ENABLE */ + PROBE_RSP_TEMPLATE_VER1 = 71, + //MAX_FEATURE_SUPPORTED = 128 +} placeHolderInCapBitmap; + +typedef enum eSriLinkState { + eSIR_LINK_IDLE_STATE = 0, + eSIR_LINK_PREASSOC_STATE = 1, + eSIR_LINK_POSTASSOC_STATE = 2, + eSIR_LINK_AP_STATE = 3, + eSIR_LINK_IBSS_STATE = 4, + // BT-AMP Case + eSIR_LINK_BTAMP_PREASSOC_STATE = 5, + eSIR_LINK_BTAMP_POSTASSOC_STATE = 6, + eSIR_LINK_BTAMP_AP_STATE = 7, + eSIR_LINK_BTAMP_STA_STATE = 8, + + // Reserved for HAL internal use + eSIR_LINK_LEARN_STATE = 9, + eSIR_LINK_SCAN_STATE = 10, + eSIR_LINK_FINISH_SCAN_STATE = 11, + eSIR_LINK_INIT_CAL_STATE = 12, + eSIR_LINK_FINISH_CAL_STATE = 13, + eSIR_LINK_LISTEN_STATE = 14, + eSIR_LINK_SEND_ACTION_STATE = 15, + +#ifdef WLAN_FEATURE_LFR_MBB + eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17, +#endif + +} tSirLinkState; + + +/// Message queue structure used across Sirius project. +/// NOTE: this structure should be multiples of a word size (4bytes) +/// as this is used in tx_queue where it expects to be multiples of 4 bytes. +typedef struct sSirMsgQ +{ + tANI_U16 type; + /* + * This field can be used as sequence number/dialog token for matching + * requests and responses. + */ + tANI_U16 reserved; + /** + * Based on the type either a bodyptr pointer into + * memory or bodyval as a 32 bit data is used. + * bodyptr: is always a freeable pointer, one should always + * make sure that bodyptr is always freeable. + * + * Messages should use either bodyptr or bodyval; not both !!!. + */ + void *bodyptr; + tANI_U32 bodyval; + + /* + * Some messages provide a callback function. The function signature + * must be agreed upon between the two entities exchanging the message + */ + void *callback; + +} tSirMsgQ, *tpSirMsgQ; + +/// Mailbox Message Structure Define +typedef struct sSirMbMsg +{ + tANI_U16 type; + + /** + * This length includes 4 bytes of header, that is, + * 2 bytes type + 2 bytes msgLen + n*4 bytes of data. + * This field is byte length. + */ + tANI_U16 msgLen; + + /** + * This is the first data word in the mailbox message. + * It is followed by n words of data. + * NOTE: data[1] is not a place holder to store data + * instead to dereference the message body. + */ + tANI_U32 data[1]; +} tSirMbMsg, *tpSirMbMsg; + +/// Mailbox Message Structure for P2P +typedef struct sSirMbMsgP2p +{ + tANI_U16 type; + + /** + * This length includes 4 bytes of header, that is, + * 2 bytes type + 2 bytes msgLen + n*4 bytes of data. + * This field is byte length. + */ + tANI_U16 msgLen; + + tANI_U8 sessionId; + tANI_U8 noack; + tANI_U16 wait; + + /** + * This is the first data word in the mailbox message. + * It is followed by n words of data. + * NOTE: data[1] is not a place holder to store data + * instead to dereference the message body. + */ + tANI_U32 data[1]; +} tSirMbMsgP2p, *tpSirMbMsgP2p; + +/// Message queue definitions +// msgtype(2bytes) reserved(2bytes) bodyptr(4bytes) bodyval(4bytes) +// NOTE tSirMsgQ should be always multiples of WORD(4Bytes) +// All Queue Message Size are multiples of word Size (4 bytes) +#define SYS_MSG_SIZE (sizeof(tSirMsgQ)/4) + +/// gHalMsgQ + +#define SYS_HAL_MSG_SIZE SYS_MSG_SIZE + +/// gMMHhiPriorityMsgQ + +#define SYS_MMH_HI_PRI_MSG_SIZE SYS_MSG_SIZE + +/// gMMHprotocolMsgQ + +#define SYS_MMH_PROT_MSG_SIZE SYS_MSG_SIZE + +/// gMMHdebugMsgQ + +#define SYS_MMH_DEBUG_MSG_SIZE SYS_MSG_SIZE + +/// gMAINTmsgQ + +#define SYS_MNT_MSG_SIZE SYS_MSG_SIZE + +/// LIM Message Queue + +#define SYS_LIM_MSG_SIZE SYS_MSG_SIZE + +/// ARQ Message Queue + +#define SYS_ARQ_MSG_SIZE SYS_MSG_SIZE + +/// Scheduler Message Queue + +#define SYS_SCH_MSG_SIZE SYS_MSG_SIZE + +/// PMM Message Queue + +#define SYS_PMM_MSG_SIZE SYS_MSG_SIZE + +/// TX Message Queue + +#define SYS_TX_MSG_SIZE (sizeof(void *)/4) // Message pointer size + +/// RX Message Queue + +#define SYS_RX_MSG_SIZE (sizeof(void *)/4) // Message pointer size + +/// PTT Message Queue +#define SYS_NIM_PTT_MSG_SIZE SYS_MSG_SIZE // Message pointer size + + + +/* *************************************** * + * * + * Block pool configuration * + * * + * *************************************** */ + +// The following values specify the number of blocks to be created +// for each block pool size. + +#define SIR_BUF_BLK_32_NUM 64 +#define SIR_BUF_BLK_64_NUM 128 +#define SIR_BUF_BLK_96_NUM 16 +#define SIR_BUF_BLK_128_NUM 128 +#define SIR_BUF_BLK_160_NUM 8 +#define SIR_BUF_BLK_192_NUM 0 +#define SIR_BUF_BLK_224_NUM 0 +#define SIR_BUF_BLK_256_NUM 128 +#define SIR_BUF_BLK_512_NUM 0 +#define SIR_BUF_BLK_768_NUM 0 +#define SIR_BUF_BLK_1024_NUM 2 +#define SIR_BUF_BLK_1280_NUM 0 +#define SIR_BUF_BLK_1536_NUM 2 +#define SIR_BUF_BLK_1792_NUM 0 +#define SIR_BUF_BLK_2048_NUM 2 +#define SIR_BUF_BLK_2304_NUM 0 + +/* ******************************************* * + * * + * SIRIUS MESSAGE TYPES * + * * + * ******************************************* */ + + +/* + * The following message types have bounds defined for each module for + * inter thread/module communications. + * Each module will get 256 message types in total. + * Note that message type definitions for mailbox messages for + * communication with Host are in wniApi.h file. + * + * Any addition/deletion to this message list should also be + * reflected in the halUtil_getMsgString() routine. + */ + +// HAL message types +#define SIR_HAL_MSG_TYPES_BEGIN (SIR_HAL_MODULE_ID << 8) +#define SIR_HAL_EXT_MSG_TYPES_BEGIN (SIR_HAL_EXT_MODULE_ID << 8) +#define SIR_HAL_ITC_MSG_TYPES_BEGIN (SIR_HAL_MSG_TYPES_BEGIN+0x20) +#define SIR_HAL_RADAR_DETECTED_IND SIR_HAL_ITC_MSG_TYPES_BEGIN +#define SIR_HAL_WDT_KAM_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 1) +#define SIR_HAL_TIMER_TEMP_MEAS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 2) +#define SIR_HAL_TIMER_PERIODIC_STATS_COLLECT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 3) +#define SIR_HAL_CAL_REQ_NTF (SIR_HAL_ITC_MSG_TYPES_BEGIN + 4) +#define SIR_HAL_MNT_OPEN_TPC_TEMP_MEAS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 5) +#define SIR_HAL_CCA_MONITOR_INTERVAL_TO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 6) +#define SIR_HAL_CCA_MONITOR_DURATION_TO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 7) +#define SIR_HAL_CCA_MONITOR_START (SIR_HAL_ITC_MSG_TYPES_BEGIN + 8) +#define SIR_HAL_CCA_MONITOR_STOP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 9) +#define SIR_HAL_CCA_CHANGE_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 10) +#define SIR_HAL_TIMER_WRAP_AROUND_STATS_COLLECT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 11) + +/* + * New Taurus related messages + */ +#define SIR_HAL_ADD_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 13) +#define SIR_HAL_ADD_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 14) +#define SIR_HAL_DELETE_STA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 15) +#define SIR_HAL_DELETE_STA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 16) +#define SIR_HAL_ADD_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 17) +#define SIR_HAL_ADD_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 18) +#define SIR_HAL_DELETE_BSS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 19) +#define SIR_HAL_DELETE_BSS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 20) +#define SIR_HAL_INIT_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 21) +#define SIR_HAL_INIT_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 22) +#define SIR_HAL_START_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 23) +#define SIR_HAL_START_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 24) +#define SIR_HAL_END_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 25) +#define SIR_HAL_END_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 26) +#define SIR_HAL_FINISH_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 27) +#define SIR_HAL_FINISH_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 28) +#define SIR_HAL_SEND_BEACON_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 29) +#define SIR_HAL_SEND_BEACON_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 30) + +#define SIR_HAL_INIT_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 31) +#define SIR_HAL_INIT_CFG_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 32) + +#define SIR_HAL_INIT_WM_CFG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 33) +#define SIR_HAL_INIT_WM_CFG_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 34) + +#define SIR_HAL_SET_BSSKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 35) +#define SIR_HAL_SET_BSSKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 36) +#define SIR_HAL_SET_STAKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 37) +#define SIR_HAL_SET_STAKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 38) +#define SIR_HAL_DPU_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 39) +#define SIR_HAL_DPU_STATS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 40) +#define SIR_HAL_GET_DPUINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 41) +#define SIR_HAL_GET_DPUINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 42) + +#define SIR_HAL_UPDATE_EDCA_PROFILE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 43) + +#define SIR_HAL_UPDATE_STARATEINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 45) +#define SIR_HAL_UPDATE_STARATEINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 46) + +#define SIR_HAL_UPDATE_BEACON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 47) +#define SIR_HAL_UPDATE_CF_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 48) +#define SIR_HAL_CHNL_SWITCH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 49) +#define SIR_HAL_ADD_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 50) +#define SIR_HAL_DEL_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 51) +#define SIR_HAL_SOFTMAC_TXSTAT_REPORT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 52) + +#define SIR_HAL_MBOX_SENDMSG_COMPLETE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 61) +#define SIR_HAL_EXIT_BMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 53) +#define SIR_HAL_EXIT_BMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 54) +#define SIR_HAL_EXIT_BMPS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 55) +#define SIR_HAL_ENTER_BMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 56) +#define SIR_HAL_ENTER_BMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 57) +#define SIR_HAL_BMPS_STATUS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 58) +#define SIR_HAL_MISSED_BEACON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 59) + +#define SIR_HAL_SWITCH_CHANNEL_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 60) +#define SIR_HAL_PWR_SAVE_CFG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 62) + +#define SIR_HAL_REGISTER_PE_CALLBACK (SIR_HAL_ITC_MSG_TYPES_BEGIN + 63) +#define SIR_HAL_SOFTMAC_MEM_READREQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 64) +#define SIR_HAL_SOFTMAC_MEM_WRITEREQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 65) + +#define SIR_HAL_SOFTMAC_MEM_READRESPONSE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 66) +#define SIR_HAL_SOFTMAC_BULKREGWRITE_CONFIRM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 67) +#define SIR_HAL_SOFTMAC_BULKREGREAD_RESPONSE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 68) +#define SIR_HAL_SOFTMAC_HOSTMESG_MSGPROCESSRESULT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 69) + +#define SIR_HAL_ADDBA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 70) +#define SIR_HAL_ADDBA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 71) +#define SIR_HAL_DELBA_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 72) +#define SIR_HAL_DEL_BA_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 73) + +//message from sme to initiate delete block ack session. +#define SIR_HAL_DELBA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 74) +#define SIR_HAL_IBSS_STA_ADD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 75) +#define SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 76) +#define SIR_HAL_SET_LINK_STATE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 77) +#define SIR_HAL_ENTER_IMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 78) +#define SIR_HAL_ENTER_IMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 79) +#define SIR_HAL_EXIT_IMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 80) +#define SIR_HAL_EXIT_IMPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 81) +#define SIR_HAL_SOFTMAC_HOSTMESG_PS_STATUS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 82) +#define SIR_HAL_POSTPONE_ENTER_IMPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 83) +#define SIR_HAL_STA_STAT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 84) +#define SIR_HAL_GLOBAL_STAT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 85) +#define SIR_HAL_AGGR_STAT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 86) +#define SIR_HAL_STA_STAT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 87) +#define SIR_HAL_GLOBAL_STAT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 88) +#define SIR_HAL_AGGR_STAT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 89) +#define SIR_HAL_STAT_SUMM_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 90) +#define SIR_HAL_STAT_SUMM_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 92) +#define SIR_HAL_REMOVE_BSSKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 93) +#define SIR_HAL_REMOVE_BSSKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 94) +#define SIR_HAL_REMOVE_STAKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 95) +#define SIR_HAL_REMOVE_STAKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 96) +#define SIR_HAL_SET_STA_BCASTKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 97) +#define SIR_HAL_SET_STA_BCASTKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 98) +#define SIR_HAL_REMOVE_STA_BCASTKEY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 99) +#define SIR_HAL_REMOVE_STA_BCASTKEY_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 100) +#define SIR_HAL_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 101) +#define SIR_HAL_DPU_MIC_ERROR (SIR_HAL_ITC_MSG_TYPES_BEGIN + 102) +#define SIR_HAL_TIMER_BA_ACTIVITY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 103) +#define SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 104) +#define SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 105) +#define SIR_HAL_TIMER_ADC_RSSI_STATS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 106) +#define SIR_HAL_MIC_FAILURE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 107) +#define SIR_HAL_UPDATE_UAPSD_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 108) +#define SIR_HAL_SET_MIMOPS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 109) +#define SIR_HAL_SET_MIMOPS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 110) +#define SIR_HAL_SYS_READY_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 111) +#define SIR_HAL_SET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 112) +#define SIR_HAL_SET_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 113) +#define SIR_HAL_GET_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 114) +#define SIR_HAL_GET_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 115) +#define SIR_HAL_GET_NOISE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 116) +#define SIR_HAL_GET_NOISE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 117) + +/* Messages to support transmit_halt and transmit_resume */ +#define SIR_HAL_TRANSMISSION_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 118) +/* Indication from LIM to HAL to Initialize radar interrupt */ +#define SIR_HAL_INIT_RADAR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 119) + +#define SIR_HAL_BEACON_PRE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 120) +#define SIR_HAL_ENTER_UAPSD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 121) +#define SIR_HAL_ENTER_UAPSD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 122) +#define SIR_HAL_EXIT_UAPSD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 123) +#define SIR_HAL_EXIT_UAPSD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 124) +#define SIR_HAL_LOW_RSSI_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 125) +#define SIR_HAL_BEACON_FILTER_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 126) +/// PE <-> HAL WOWL messages +#define SIR_HAL_WOWL_ADD_BCAST_PTRN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 127) +#define SIR_HAL_WOWL_DEL_BCAST_PTRN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 128) +#define SIR_HAL_WOWL_ENTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 129) +#define SIR_HAL_WOWL_ENTER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 130) +#define SIR_HAL_WOWL_EXIT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 131) +#define SIR_HAL_WOWL_EXIT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 132) +#define SIR_HAL_TX_COMPLETE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 133) +#define SIR_HAL_TIMER_RA_COLLECT_AND_ADAPT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 134) +/// PE <-> HAL statistics messages +#define SIR_HAL_GET_STATISTICS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 135) +#define SIR_HAL_GET_STATISTICS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 136) +#define SIR_HAL_SET_KEY_DONE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 137) + +/// PE <-> HAL BTC messages +#define SIR_HAL_BTC_SET_CFG (SIR_HAL_ITC_MSG_TYPES_BEGIN + 138) +#define SIR_HAL_SIGNAL_BT_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 139) +#define SIR_HAL_HANDLE_FW_MBOX_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 140) +#define SIR_HAL_UPDATE_PROBE_RSP_TEMPLATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 141) + +/* PE <-> HAL addr2 mismatch message */ +#define SIR_LIM_ADDR2_MISS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 142) +#ifdef FEATURE_OEM_DATA_SUPPORT +/* PE <-> HAL OEM_DATA RELATED MESSAGES */ +#define SIR_HAL_START_OEM_DATA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 143) +#define SIR_HAL_START_OEM_DATA_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 144) +#define SIR_HAL_FINISH_OEM_DATA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 145) +#endif + +#define SIR_HAL_SET_MAX_TX_POWER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 146) +#define SIR_HAL_SET_MAX_TX_POWER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 147) + +#define SIR_HAL_SEND_MSG_COMPLETE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 148) + +/// PE <-> HAL Host Offload message +#define SIR_HAL_SET_HOST_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 149) + +#define SIR_HAL_ADD_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 150) +#define SIR_HAL_ADD_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 151) +#define SIR_HAL_DEL_STA_SELF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 152) +#define SIR_HAL_DEL_STA_SELF_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 153) +#define SIR_HAL_SIGNAL_BTAMP_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 154) + +#define SIR_HAL_CFG_RXP_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 155) +#define SIR_HAL_CFG_RXP_FILTER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 156) + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define SIR_HAL_AGGR_ADD_TS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 157) +#define SIR_HAL_AGGR_ADD_TS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 158) +#define SIR_HAL_AGGR_QOS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 159) +#define SIR_HAL_AGGR_QOS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160) +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* P2P <-> HAL P2P msg */ +#define SIR_HAL_SET_P2P_GO_NOA_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) +#define SIR_HAL_P2P_NOA_ATTR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 162) +#define SIR_HAL_P2P_NOA_START_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 163) + +#define SIR_HAL_SET_LINK_STATE_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 165) + + +#define SIR_HAL_WLAN_SUSPEND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 166) +#define SIR_HAL_WLAN_RESUME_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 167) + +/// PE <-> HAL Keep Alive message +#define SIR_HAL_SET_KEEP_ALIVE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 168) + +#ifdef WLAN_NS_OFFLOAD +#define SIR_HAL_SET_NS_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 169) +#endif //WLAN_NS_OFFLOAD + +#ifdef FEATURE_WLAN_SCAN_PNO +#define SIR_HAL_SET_PNO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 170) +#define SIR_HAL_SET_PNO_CHANGED_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 171) +#define SIR_HAL_UPDATE_SCAN_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 172) +#define SIR_HAL_SET_RSSI_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 173) +#endif // FEATURE_WLAN_SCAN_PNO + + +#define SIR_HAL_SET_TX_PER_TRACKING_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 174) + +#ifdef WLAN_FEATURE_PACKET_FILTERING +#define SIR_HAL_8023_MULTICAST_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 175) +#define SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 176) +#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 177) +#define SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 178) +#define SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 179) +#endif // WLAN_FEATURE_PACKET_FILTERING + +#define SIR_HAL_SET_POWER_PARAMS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 180) + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define SIR_HAL_GTK_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 181) +#define SIR_HAL_GTK_OFFLOAD_GETINFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 182) +#define SIR_HAL_GTK_OFFLOAD_GETINFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 183) +#endif //WLAN_FEATURE_GTK_OFFLOAD + +#ifdef FEATURE_WLAN_ESE +#define SIR_HAL_TSM_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 184) +#define SIR_HAL_TSM_STATS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 185) +#endif + + +#ifdef WLAN_WAKEUP_EVENTS +#define SIR_HAL_WAKE_REASON_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 186) +#endif //WLAN_WAKEUP_EVENTS + +#define SIR_HAL_SET_TM_LEVEL_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 187) + +#ifdef WLAN_FEATURE_11AC +#define SIR_HAL_UPDATE_OP_MODE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 188) +#endif + +#ifdef FEATURE_WLAN_TDLS +/// PE <-> HAL TDLS messages +#define SIR_HAL_TDLS_LINK_ESTABLISH (SIR_HAL_ITC_MSG_TYPES_BEGIN + 189) +#define SIR_HAL_TDLS_LINK_TEARDOWN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 190) +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define SIR_HAL_ROAM_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 191) +#define SIR_HAL_ROAM_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 192) +#endif +#define SIR_HAL_GET_ROAM_RSSI_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 193) +#define SIR_HAL_GET_ROAM_RSSI_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 194) + +#define SIR_HAL_TRAFFIC_STATS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 195) + +#ifdef WLAN_FEATURE_11W +#define SIR_HAL_EXCLUDE_UNENCRYPTED_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 196) +#endif +#ifdef FEATURE_WLAN_TDLS +/// PE <-> HAL TDLS messages +#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 197) +#define SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 198) +#define SIR_HAL_TDLS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 199) +#endif + +#define SIR_HAL_UPDATE_CHAN_LIST_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 200) +#define SIR_HAL_STOP_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 201) +#define SIR_HAL_STOP_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 202) +#define SIR_HAL_RX_SCAN_EVENT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 203) +#define SIR_HAL_DHCP_START_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 204) +#define SIR_HAL_DHCP_STOP_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 205) +#define SIR_HAL_IBSS_PEER_INACTIVITY_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 206) + +#define SIR_HAL_LPHB_CONF_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 207) +#define SIR_HAL_LPHB_WAIT_EXPIRE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 208) + +#define SIR_HAL_ADD_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 209) +#define SIR_HAL_DEL_PERIODIC_TX_PTRN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 210) + +#ifdef WLAN_FEATURE_RMC +#define SIR_HAL_RMC_BECOME_RULER (SIR_HAL_ITC_MSG_TYPES_BEGIN + 211) +#define SIR_HAL_RMC_RULER_SELECT_RESP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 212) +#define SIR_HAL_RMC_RULER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 213) +#define SIR_HAL_RMC_UPDATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 214) + +/* For IBSS peer info related messages */ +#define SIR_HAL_IBSS_PEER_INFO_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 215) +#define SIR_HAL_IBSS_PEER_INFO_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 216) +#endif /* WLAN_FEATURE_RMC */ + +#define SIR_HAL_RATE_UPDATE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 217) + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define SIR_HAL_SET_BATCH_SCAN_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 218) +#define SIR_HAL_SET_BATCH_SCAN_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 219) +#define SIR_HAL_STOP_BATCH_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 220) +#define SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 221) +#endif + +#define SIR_HAL_START_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 223) +#define SIR_HAL_START_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 224) +#define SIR_HAL_UPDATE_CHAN_LIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 225) + +#ifdef WLAN_FEATURE_RMC +#define SIR_HAL_TX_FAIL_MONITOR_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 226) +#endif /* WLAN_FEATURE_RMC */ + +/* OBSS Scan start Indication to FW*/ +#define SIR_HAL_HT40_OBSS_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN +227) +/* OBSS Scan stop Indication to FW*/ +#define SIR_HAL_HT40_OBSS_STOP_SCAN_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN +228) + +#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ \ + (SIR_HAL_ITC_MSG_TYPES_BEGIN + 229) +#define SIR_HAL_SET_MAX_TX_POWER_PER_BAND_RSP \ + (SIR_HAL_ITC_MSG_TYPES_BEGIN + 230) + +#define SIR_HAL_BCN_MISS_RATE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 231) + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define SIR_HAL_LL_STATS_CLEAR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 232) +#define SIR_HAL_LL_STATS_SET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 233) +#define SIR_HAL_LL_STATS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 234) +#define SIR_HAL_LL_STATS_RESULTS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 235) +#endif + +#ifdef WLAN_FEATURE_EXTSCAN +#define SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 236) +#define SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 237) +#define SIR_HAL_EXTSCAN_START_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 238) +#define SIR_HAL_EXTSCAN_START_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 239) +#define SIR_HAL_EXTSCAN_STOP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 240) +#define SIR_HAL_EXTSCAN_STOP_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 241) +#define SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 242) +#define SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 243) +#define SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 244) +#define SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 245) +#define SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 246) +#define SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 247) +#define SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 248) +#define SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 249) + +#define SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 250) +#define SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 251) + +#define SIR_HAL_EXTSCAN_PROGRESS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 252) +#define SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 253) +#define SIR_HAL_EXTSCAN_SCAN_RESULT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 254) +#define SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 255) +#define SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 256) + +#define SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 257) + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef FEATURE_WLAN_TDLS +/// PE <-> HAL TDLS messages +// tdlsoffchan +#define SIR_HAL_TDLS_CHAN_SWITCH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 258) +#define SIR_HAL_TDLS_CHAN_SWITCH_REQ_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 259) +#endif +#define SIR_HAL_SPOOF_MAC_ADDR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 260) +#define SIR_HAL_SPOOF_MAC_ADDR_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 261) + +#define SIR_HAL_FW_STATS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 262) + +#define SIR_HAL_ENCRYPT_MSG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 263) +#define SIR_HAL_ENCRYPT_MSG_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 264) + +#define SIR_HAL_MGMT_LOGGING_INIT_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 265) +#define SIR_HAL_GET_FRAME_LOG_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 266) + +#define SIR_HAL_NAN_REQUEST (SIR_HAL_ITC_MSG_TYPES_BEGIN + 267) + +#define SIR_HAL_SET_RTS_CTS_HTVHT (SIR_HAL_ITC_MSG_TYPES_BEGIN + 268) +#define SIR_HAL_MON_START_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 269) +#define SIR_HAL_MON_STOP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 270) +#define SIR_HAL_FATAL_EVENT_LOGS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 271) +#define SIR_HAL_SEND_LOG_DONE_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 272) +#define SIR_HAL_LOST_LINK_PARAMS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 273) +#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 274) +#define SIR_HAL_FW_MEM_DUMP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 275) +#define SIR_HAL_RSSI_MON_START_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 276) +#define SIR_HAL_RSSI_MON_STOP_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 277) +#define SIR_HAL_HIGH_PRIORITY_DATA_INFO_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 278) +#define SIR_HAL_WIFI_CONFIG_PARAMS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 279) +#define SIR_HAL_START_OEM_DATA_REQ_IND_NEW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 280) +#define SIR_HAL_START_OEM_DATA_RSP_IND_NEW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 281) +#define SIR_HAL_ANTENNA_DIVERSITY_SELECTION_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 282) +#define SIR_HAL_MODIFY_ROAM_PARAMS_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 283) +#define SIR_HAL_SET_ALLOWED_ACTION_FRAMES (SIR_HAL_ITC_MSG_TYPES_BEGIN + 284) +#define SIR_HAL_PAUSE_TL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 285) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define SIR_HAL_PER_ROAM_SCAN_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 286) +#define SIR_HAL_PER_ROAM_SCAN_OFFLOAD_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 287) +#define SIR_HAL_PER_ROAM_SCAN_TRIGGER_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 288) +#define SIR_HAL_PER_ROAM_SCAN_TRIGGER_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 289) +#endif +#define SIR_HAL_UPDATE_CFG_INT_PARAM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 290) + +#ifdef SAP_AUTH_OFFLOAD +#define SIR_HAL_SET_SAP_AUTH_OFL (SIR_HAL_ITC_MSG_TYPES_BEGIN + 291) +#define SIR_HAL_SAP_OFL_ADD_STA (SIR_HAL_ITC_MSG_TYPES_BEGIN + 292) +#define SIR_HAL_SAP_OFL_DEL_STA (SIR_HAL_ITC_MSG_TYPES_BEGIN + 293) +#endif +#ifdef DHCP_SERVER_OFFLOAD +#define SIR_HAL_SET_DHCP_SERVER_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 294) +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD +#define SIR_HAL_SET_MDNS_OFFLOAD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 295) +#define SIR_HAL_SET_MDNS_FQDN (SIR_HAL_ITC_MSG_TYPES_BEGIN + 296) +#define SIR_HAL_SET_MDNS_RESPONSE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 297) +#define SIR_HAL_GET_MDNS_STATUS (SIR_HAL_ITC_MSG_TYPES_BEGIN + 298) +#endif /* MDNS_OFFLOAD */ +#ifdef WLAN_FEATURE_APFIND +#define SIR_HAL_APFIND_SET_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 299) +#define SIR_HAL_AP_FIND_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 300) +#endif/* WLAN_FEATURE_APFIND */ + +#define SIR_HAL_CAP_TSF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 301) +#define SIR_HAL_GET_TSF_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 302) + +/* ARP Debug stats */ +#define SIR_HAL_SET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 303) +#define SIR_HAL_GET_ARP_STATS_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 304) + +#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) + +// CFG message types +#define SIR_CFG_MSG_TYPES_BEGIN (SIR_CFG_MODULE_ID << 8) +#define SIR_CFG_ITC_MSG_TYPES_BEGIN (SIR_CFG_MSG_TYPES_BEGIN+0xB0) +#define SIR_CFG_PARAM_UPDATE_IND (SIR_CFG_ITC_MSG_TYPES_BEGIN) +#define SIR_CFG_DOWNLOAD_COMPLETE_IND (SIR_CFG_ITC_MSG_TYPES_BEGIN + 1) +#define SIR_CFG_MSG_TYPES_END (SIR_CFG_MSG_TYPES_BEGIN+0xFF) + +// LIM message types +#define SIR_LIM_MSG_TYPES_BEGIN (SIR_LIM_MODULE_ID << 8) +#define SIR_LIM_ITC_MSG_TYPES_BEGIN (SIR_LIM_MSG_TYPES_BEGIN+0xB0) + +// Messages to/from HAL +// Removed as part of moving HAL down to FW + +// Message from ISR upon TFP retry interrupt +#define SIR_LIM_RETRY_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 3) +// Message from BB Transport +#define SIR_BB_XPORT_MGMT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 4) +// UNUSED SIR_LIM_ITC_MSG_TYPES_BEGIN + 6 +// Message from ISR upon SP's Invalid session key interrupt +#define SIR_LIM_INV_KEY_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 7) +// Message from ISR upon SP's Invalid key ID interrupt +#define SIR_LIM_KEY_ID_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 8) +// Message from ISR upon SP's Replay threshold reached interrupt +#define SIR_LIM_REPLAY_THRES_INTERRUPT_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 9) +// Message from HDD after the TD dummy packet is cleaned up +#define SIR_LIM_TD_DUMMY_CALLBACK_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xA) +// Message from SCH when the STA is ready to be deleted +#define SIR_LIM_SCH_CLEAN_MSG (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xB) +// Message from ISR upon Radar Detection +#define SIR_LIM_RADAR_DETECT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xC) + +///////////////////////////////////// +// message id Available +//////////////////////////////////// + + +// Message from Hal to send out a DEL-TS indication +#define SIR_LIM_DEL_TS_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xE) +//Message from HAL to send BA global timer timeout +#define SIR_LIM_ADD_BA_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0xF) +//Indication from HAL to delete all the BA sessions when the BA activity check timer is disabled +#define SIR_LIM_DEL_BA_ALL_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x10) +//Indication from HAL to delete Station context +#define SIR_LIM_DELETE_STA_CONTEXT_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x11) +//Indication from HAL to delete BA +#define SIR_LIM_DEL_BA_IND (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x12) +#define SIR_LIM_UPDATE_BEACON (SIR_LIM_ITC_MSG_TYPES_BEGIN + 0x13) + + +// LIM Timeout messages +#define SIR_LIM_TIMEOUT_MSG_START ((SIR_LIM_MODULE_ID << 8) + 0xD0) +#define SIR_LIM_MIN_CHANNEL_TIMEOUT SIR_LIM_TIMEOUT_MSG_START +#define SIR_LIM_MAX_CHANNEL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 1) +#define SIR_LIM_JOIN_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 2) +#define SIR_LIM_AUTH_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 3) +#define SIR_LIM_AUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 4) +#define SIR_LIM_ASSOC_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 5) +#define SIR_LIM_REASSOC_FAIL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 6) +#define SIR_LIM_HEART_BEAT_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 7) +// currently unused SIR_LIM_TIMEOUT_MSG_START + 0x8 +// Link Monitoring Messages +#define SIR_LIM_CHANNEL_SCAN_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xA) +#define SIR_LIM_PROBE_HB_FAILURE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xB) +#define SIR_LIM_ADDTS_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0xC) +#define SIR_LIM_LINK_TEST_DURATION_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x13) +#define SIR_LIM_CNF_WAIT_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x17) +#define SIR_LIM_KEEPALIVE_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x18) +#define SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x19) +#define SIR_LIM_CHANNEL_SWITCH_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1A) +#define SIR_LIM_QUIET_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1B) +#define SIR_LIM_QUIET_BSS_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1C) + +#define SIR_LIM_WPS_OVERLAP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1D) +#ifdef WLAN_FEATURE_VOWIFI_11R +#define SIR_LIM_FT_PREAUTH_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1E) +#endif +#define SIR_LIM_REMAIN_CHN_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x1F) +#define SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x20) + +#ifdef WMM_APSD +#define SIR_LIM_WMM_APSD_SP_START_MSG_TYPE (SIR_LIM_TIMEOUT_MSG_START + 0x21) +#define SIR_LIM_WMM_APSD_SP_END_MSG_TYPE (SIR_LIM_TIMEOUT_MSG_START + 0x22) +#endif +#define SIR_LIM_BEACON_GEN_IND (SIR_LIM_TIMEOUT_MSG_START + 0x23) +#define SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x24) + +#define SIR_LIM_ESE_TSM_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x25) + +#define SIR_LIM_DISASSOC_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x26) +#define SIR_LIM_DEAUTH_ACK_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x27) +#define SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x28) + +#ifdef WLAN_FEATURE_LFR_MBB +#define SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x29) +#define SIR_LIM_REASSOC_MBB_RSP_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2A) +#endif + +#define SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE (SIR_LIM_TIMEOUT_MSG_START + 0x2C) +#define SIR_LIM_AUTH_RETRY_TIMEOUT (SIR_LIM_TIMEOUT_MSG_START + 0x2D) + +#define SIR_LIM_MSG_TYPES_END (SIR_LIM_MSG_TYPES_BEGIN+0xFF) + +// SCH message types +#define SIR_SCH_MSG_TYPES_BEGIN (SIR_SCH_MODULE_ID << 8) +#define SIR_SCH_CHANNEL_SWITCH_REQUEST (SIR_SCH_MSG_TYPES_BEGIN) +#define SIR_SCH_START_SCAN_REQ (SIR_SCH_MSG_TYPES_BEGIN + 1) +#define SIR_SCH_START_SCAN_RSP (SIR_SCH_MSG_TYPES_BEGIN + 2) +#define SIR_SCH_END_SCAN_NTF (SIR_SCH_MSG_TYPES_BEGIN + 3) +#define SIR_SCH_MSG_TYPES_END (SIR_SCH_MSG_TYPES_BEGIN+0xFF) + +// PMM message types +#define SIR_PMM_MSG_TYPES_BEGIN (SIR_PMM_MODULE_ID << 8) +#define SIR_PMM_CHANGE_PM_MODE (SIR_PMM_MSG_TYPES_BEGIN) +#define SIR_PMM_CHANGE_IMPS_MODE (SIR_PMM_MSG_TYPES_BEGIN + 1) //for Idle mode power save +#define SIR_PMM_MSG_TYPES_END (SIR_PMM_MSG_TYPES_BEGIN+0xFF) + +// MNT message types +#define SIR_MNT_MSG_TYPES_BEGIN (SIR_MNT_MODULE_ID << 8) +#define SIR_MNT_RELEASE_BD (SIR_MNT_MSG_TYPES_BEGIN + 0) +#define SIR_MNT_MSG_TYPES_END (SIR_MNT_MSG_TYPES_BEGIN + 0xFF) + +// DVT message types +#define SIR_DVT_MSG_TYPES_BEGIN (SIR_DVT_MODULE_ID << 8) +#define SIR_DVT_ITC_MSG_TYPES_BEGIN (SIR_DVT_MSG_TYPES_BEGIN+0x0F) +#define SIR_DVT_MSG_TYPES_END (SIR_DVT_ITC_MSG_TYPES_BEGIN+0xFFF) + + +//PTT message types +#define SIR_PTT_MSG_TYPES_BEGIN 0x3000 +#define SIR_PTT_MSG_TYPES_END 0x3300 + + +/* ****************************************** * + * * + * EVENT TYPE Defintions * + * * + * ****************************************** */ + +// MMH Events that are used in other modules to post events to MMH +# define SIR_HAL_MMH_TXMB_READY_EVT 0x00000002 +# define SIR_HAL_MMH_RXMB_DONE_EVT 0x00000004 +# define SIR_HAL_MMH_MSGQ_NE_EVT 0x00000008 + +# define SIR_HSTEMUL_TXMB_DONE_EVT 0x00000100 +# define SIR_HSTEMUL_RXMB_READY_EVT 0x00000200 +# define SIR_HSTEMUL_MSGQ_NE_EVT 0x00000400 + +# define SIR_TST_XMIT_MSG_QS_EMPTY_EVT 0x00000080 + +//added for OBSS + +//Param Change Bitmap sent to HAL +#define PARAM_BCN_INTERVAL_CHANGED (1 << 0) +#define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) +#define PARAM_SHORT_SLOT_TIME_CHANGED (1 << 2) +#define PARAM_llACOEXIST_CHANGED (1 << 3) +#define PARAM_llBCOEXIST_CHANGED (1 << 4) +#define PARAM_llGCOEXIST_CHANGED (1 << 5) +#define PARAM_HT20MHZCOEXIST_CHANGED (1<<6) +#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7) +#define PARAM_RIFS_MODE_CHANGED (1<<8) +#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9) +#define PARAM_OBSS_MODE_CHANGED (1<<10) +#define PARAM_BEACON_UPDATE_MASK (PARAM_BCN_INTERVAL_CHANGED|PARAM_SHORT_PREAMBLE_CHANGED|PARAM_SHORT_SLOT_TIME_CHANGED|PARAM_llACOEXIST_CHANGED |PARAM_llBCOEXIST_CHANGED|\ + PARAM_llGCOEXIST_CHANGED|PARAM_HT20MHZCOEXIST_CHANGED|PARAM_NON_GF_DEVICES_PRESENT_CHANGED|PARAM_RIFS_MODE_CHANGED|PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED| PARAM_OBSS_MODE_CHANGED) + + + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/include/sysGlobal.h b/drivers/staging/prima/CORE/MAC/src/include/sysGlobal.h new file mode 100644 index 000000000000..7f26e9be9321 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/sysGlobal.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __SYS_GLOBAL_H__ +#define __SYS_GLOBAL_H__ + +typedef struct sAniSirSys +{ + tANI_U32 abort; /* system is aborting and will be unloaded, only MMH thread is running */ + + tANI_U32 gSysFrameCount[4][16]; + tANI_U32 gSysBbtReceived; + tANI_U32 gSysBbtPendingMgmtCount; + tANI_U32 gSysBbtPostedToLim; + tANI_U32 gSysBbtPostedToSch; + tANI_U32 gSysBbtPostedToPmm; + tANI_U32 gSysBbtPostedToHal; + tANI_U32 gSysBbtDropped; + tANI_U32 gSysBbtNonLearnFrameInv; + tANI_U32 gSysBbtLearnFrameInv; + tANI_U32 gSysBbtCrcFail; + tANI_U32 gSysBbtDuplicates; + tANI_U32 gSysReleaseCount; + tANI_U32 probeError, probeBadSsid, probeIgnore, probeRespond; + + tANI_U32 gSysEnableLearnMode; + tANI_U32 gSysEnableScanMode; + tANI_U32 gSysEnableLinkMonitorMode; + vos_spin_lock_t lock; +} tAniSirSys, *tpAniSirSys; + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/include/utilsApi.h b/drivers/staging/prima/CORE/MAC/src/include/utilsApi.h new file mode 100644 index 000000000000..3a1754733787 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/utilsApi.h @@ -0,0 +1,739 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Kevin Nguyen + * Date: 02/27/02 + * History:- + * 02/12/02 Created. + * -------------------------------------------------------------------- + * + */ + +#ifndef __UTILSAPI_H +#define __UTILSAPI_H + +#include +#include +#include "aniGlobal.h" +#include "utilsGlobal.h" +#include "VossWrapper.h" + +#define LOG_INDEX_FOR_MODULE( modId ) ( ( modId ) - LOG_FIRST_MODULE_ID ) +#define GET_MIN_VALUE(__val1, __val2) ((__val1 < __val2) ? __val1 : __val2) + +// The caller must check loglevel. This API assumes loglevel is good +extern void logDebug(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr, va_list marker); + +extern void logDbg(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr,...); + +extern tANI_U32 gPktAllocCnt, gPktFreeCnt; + +extern VOS_TRACE_LEVEL getVosDebugLevel(tANI_U32 debugLevel); + +/// Debug dumps +extern void logPrintf(tpAniSirGlobal, tANI_U32, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4); + +/// RTAI dump +extern int logRtaiDump(tpAniSirGlobal, tANI_U32, tANI_U32, tANI_U32, tANI_U32, tANI_U32, tANI_U8 *); + +/// Log initialization +extern tSirRetStatus logInit (tpAniSirGlobal); + +extern void +logDeinit(tpAniSirGlobal ); + +extern tSirRetStatus cfgInit(tpAniSirGlobal); +extern void cfgDeInit(tpAniSirGlobal); + +// ------------------------------------------------------------------- +/** + * sirDumpBuf() + * + * FUNCTION: + * This function is called to dump a buffer with a certain level + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBuf: buffer pointer + * @return None. + */ + +void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size); + + +// -------------------------------------------------------------------- +/** + * sirSwapU16() + * + * FUNCTION: + * This function is called to swap two U8s of an tANI_U16 value + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U16 value to be tANI_U8 swapped + * @return Swapped tANI_U16 value + */ + +static inline tANI_U16 +sirSwapU16(tANI_U16 val) +{ + return(((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8)); +}/*** end sirSwapU16() ***/ + +// -------------------------------------------------------------------- +/** + * sirSwapU16ifNeeded() + * + * FUNCTION: + * This function is called to swap two U8s of an tANI_U16 value depending + * on endiannes of the target processor/compiler the software is + * running on + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U16 value to be tANI_U8 swapped + * @return Swapped tANI_U16 value + */ + +static inline tANI_U16 +sirSwapU16ifNeeded(tANI_U16 val) +{ +#ifndef ANI_LITTLE_BYTE_ENDIAN + return sirSwapU16(val); +#else + return val; +#endif +}/*** end sirSwapU16ifNeeded() ***/ + +// -------------------------------------------------------------------- +/** + * sirSwapU32() + * + * FUNCTION: + * This function is called to swap four U8s of an tANI_U32 value + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U32 value to be tANI_U8 swapped + * @return Swapped tANI_U32 value + */ + +static inline tANI_U32 +sirSwapU32(tANI_U32 val) +{ + return((val << 24) | + (val >> 24) | + ((val & 0x0000FF00) << 8) | + ((val & 0x00FF0000) >> 8)); +}/*** end sirSwapU32() ***/ + +// -------------------------------------------------------------------- +/** + * sirSwapU32ifNeeded() + * + * FUNCTION: + * This function is called to swap U8s of an tANI_U32 value depending + * on endiannes of the target processor/compiler the software is + * running on + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param val tANI_U32 value to be tANI_U8 swapped + * @return Swapped tANI_U32 value + */ + +static inline tANI_U32 +sirSwapU32ifNeeded(tANI_U32 val) +{ +#ifndef ANI_LITTLE_BYTE_ENDIAN + return sirSwapU32(val); +#else + return val; +#endif +}/*** end sirSwapU32ifNeeded() ***/ + + + + +// ------------------------------------------------------------------- +/** + * sirSwapU32Buf + * + * FUNCTION: + * It swaps N dwords into the same buffer + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of tANI_U32 array + * @return void + * + */ + +static inline void +sirSwapU32Buf(tANI_U32 *ptr, tANI_U32 nWords) +{ + tANI_U32 i; + + for (i=0; i < nWords; i++) + ptr[i] = sirSwapU32(ptr[i]); +} + +// -------------------------------------------------------------------- +/** + * sirSwapU32BufIfNeeded() + * + * FUNCTION: + * This function is called to swap U8s of U32s in the buffer depending + * on endiannes of the target processor/compiler the software is + * running on + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBuf Buffer that will get swapped + * @param nWords Number DWORDS will be swapped + * @return void + */ + +static inline void +sirSwapU32BufIfNeeded(tANI_U32* pBuf, tANI_U32 nWords) +{ +#ifdef ANI_LITTLE_BYTE_ENDIAN + sirSwapU32Buf(pBuf, nWords); +#endif +}/*** end sirSwapU32ifNeeded() ***/ + + +// -------------------------------------------------------------------- +/** + * sirSwapBDIfNeeded + * + * FUNCTION: + * Byte swap all the dwords in the BD, except the PHY/MAC headers + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBd BD that will get swapped + * @return void + */ + +static inline void +sirSwapBDIfNeeded(tANI_U32 *pBd) +{ + sirSwapU32BufIfNeeded(pBd, 6); + sirSwapU32BufIfNeeded(pBd+18, 14); +} + + +// ------------------------------------------------------------------- +/** + * sirStoreU16N + * + * FUNCTION: + * It stores a 16 bit number into the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU16N(tANI_U8 *ptr, tANI_U16 val) +{ + *ptr++ = (val >> 8) & 0xff; + *ptr = val & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU32N + * + * FUNCTION: + * It stores a 32 bit number into the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU32N(tANI_U8 *ptr, tANI_U32 val) +{ + *ptr++ = (tANI_U8) (val >> 24) & 0xff; + *ptr++ = (tANI_U8) (val >> 16) & 0xff; + *ptr++ = (tANI_U8) (val >> 8) & 0xff; + *ptr = (tANI_U8) (val) & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU16 + * + * FUNCTION: + * It stores a 16 bit number into the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU16(tANI_U8 *ptr, tANI_U16 val) +{ + *ptr++ = val & 0xff; + *ptr = (val >> 8) & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU32 + * + * FUNCTION: + * It stores a 32 bit number into the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of destination byte array + * @param val value to store + * @return None + */ + +static inline void +sirStoreU32(tANI_U8 *ptr, tANI_U32 val) +{ + *ptr++ = (tANI_U8) val & 0xff; + *ptr++ = (tANI_U8) (val >> 8) & 0xff; + *ptr++ = (tANI_U8) (val >> 16) & 0xff; + *ptr = (tANI_U8) (val >> 24) & 0xff; +} + +// ------------------------------------------------------------------- +/** + * sirStoreU32BufN + * + * FUNCTION: + * It stores a 32 bit number into the byte array in network byte order + * i.e. the least significant byte first. It performs the above operation + * on entire buffer and writes to the dst buffer + * + * LOGIC: + * + * ASSUMPTIONS: + * Assumes that the pSrc buffer is of all tANI_U32 data type fields. + * + * NOTE: + * Must be used if all the fields in the buffer must be of tANI_U32 types. + * + * @param pDst address of destination byte array + * @param pSrc address of the source DWORD array + * @param length number of DWORDs + * @return None + */ + +static inline void +sirStoreBufN(tANI_U8* pDst, tANI_U32* pSrc, tANI_U32 length) +{ + while (length) + { + sirStoreU32N(pDst, *pSrc); + pDst += 4; + pSrc++; + length--; + } +} + +// ------------------------------------------------------------------- +/** + * sirReadU16N + * + * FUNCTION: + * It reads a 16 bit number from the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 16 bit value + */ + +static inline tANI_U16 +sirReadU16N(tANI_U8 *ptr) +{ + return(((*ptr) << 8) | + (*(ptr+1))); +} +/** + * sirSwapU32Buf + * + * FUNCTION: + * It swaps N dwords into the same buffer + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of tANI_U32 array + * @return void + * + */ + +static inline void +sirSwapNStore(tANI_U32 *src, tANI_U32 *dst, tANI_U32 nWords) +{ + tANI_U32 i; + + for (i=0; i < nWords; i++) + dst[i] = sirSwapU32(src[i]); +} + +// ------------------------------------------------------------------- +/** + * sirReadU32N + * + * FUNCTION: + * It reads a 32 bit number from the byte array in network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 32 bit value + */ + +static inline tANI_U32 +sirReadU32N(tANI_U8 *ptr) +{ + return((*(ptr) << 24) | + (*(ptr+1) << 16) | + (*(ptr+2) << 8) | + (*(ptr+3))); +} + +// ------------------------------------------------------------------- +/** + * sirReadU16 + * + * FUNCTION: + * It reads a 16 bit number from the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 16 bit value + */ + +static inline tANI_U16 +sirReadU16(tANI_U8 *ptr) +{ + return((*ptr) | + (*(ptr+1) << 8)); +} + +// ------------------------------------------------------------------- +/** + * sirReadU32 + * + * FUNCTION: + * It reads a 32 bit number from the byte array in NON-network byte order + * i.e. the least significant byte first + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param ptr address of byte array + * @return 32 bit value + */ + +static inline tANI_U32 +sirReadU32(tANI_U8 *ptr) +{ + return((*(ptr)) | + (*(ptr+1) << 8) | + (*(ptr+2) << 16) | + (*(ptr+3) << 24)); +} + +// ------------------------------------------------------------------- + + +/// Copy a MAC address from 'from' to 'to' +static inline void +sirCopyMacAddr(tANI_U8 to[], tANI_U8 from[]) +{ +#if defined( _X86_ ) + tANI_U32 align = (0x3 & ((tANI_U32) to | (tANI_U32) from )); + if( align ==0){ + *((tANI_U16 *) &(to[4])) = *((tANI_U16 *) &(from[4])); + *((tANI_U32 *) to) = *((tANI_U32 *) from); + }else if (align == 2){ + *((tANI_U16 *) &to[4]) = *((tANI_U16 *) &from[4]); + *((tANI_U16 *) &to[2]) = *((tANI_U16 *) &from[2]); + *((tANI_U16 *) &to[0]) = *((tANI_U16 *) &from[0]); + }else{ + to[5] = from[5]; + to[4] = from[4]; + to[3] = from[3]; + to[2] = from[2]; + to[1] = from[1]; + to[0] = from[0]; + } +#else + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; +#endif +} + +static inline tANI_U8 +sirCompareMacAddr(tANI_U8 addr1[], tANI_U8 addr2[]) +{ +#if defined( _X86_ ) + tANI_U32 align = (0x3 & ((tANI_U32) addr1 | (tANI_U32) addr2 )); + + if( align ==0){ + return ((*((tANI_U16 *) &(addr1[4])) == *((tANI_U16 *) &(addr2[4])))&& + (*((tANI_U32 *) addr1) == *((tANI_U32 *) addr2))); + }else if(align == 2){ + return ((*((tANI_U16 *) &addr1[4]) == *((tANI_U16 *) &addr2[4])) && + (*((tANI_U16 *) &addr1[2]) == *((tANI_U16 *) &addr2[2])) && + (*((tANI_U16 *) &addr1[0]) == *((tANI_U16 *) &addr2[0]))); + }else{ + return ( (addr1[5]==addr2[5])&& + (addr1[4]==addr2[4])&& + (addr1[3]==addr2[3])&& + (addr1[2]==addr2[2])&& + (addr1[1]==addr2[1])&& + (addr1[0]==addr2[0])); + } +#else + return ( (addr1[0]==addr2[0])&& + (addr1[1]==addr2[1])&& + (addr1[2]==addr2[2])&& + (addr1[3]==addr2[3])&& + (addr1[4]==addr2[4])&& + (addr1[5]==addr2[5])); +#endif +} + + +/* +* converts tANI_U16 CW value to 4 bit value to be inserted in IE +*/ +static inline tANI_U8 convertCW(tANI_U16 cw) +{ + tANI_U8 val = 0; + while (cw > 0) + { + val++; + cw >>= 1; + } + if (val > 15) + return 0xF; + return val; +} + +/* The user priority to AC mapping is such: + * UP(1, 2) ---> AC_BK(1) + * UP(0, 3) ---> AC_BE(0) + * UP(4, 5) ---> AC_VI(2) + * UP(6, 7) ---> AC_VO(3) + */ +#define WLAN_UP_TO_AC_MAP 0x33220110 +#define upToAc(up) ((WLAN_UP_TO_AC_MAP >> ((up) << 2)) & 0x03) + + +// ------------------------------------------------------------------- + +/// Parse the next IE in a message +extern tSirRetStatus sirParseNextIE(tpAniSirGlobal, tANI_U8 *pPayload, + tANI_U16 payloadLength, tANI_S16 lastType, + tANI_U8 *pType, tANI_U8 *pLength); + +/// Check if the given channel is 11b channel +#define SIR_IS_CHANNEL_11B(chId) (chId <= 14) + +// ------------------------------------------------------------------- +/** + * halRoundS32 + * + * FUNCTION: + * Performs integer rounding like returns 12346 for 123456 or -12346 for -123456 + * Note that a decimal place is lost. + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param tANI_S32 input + * @return rounded number + */ +static inline tANI_S32 +halRoundS32(tANI_S32 p) +{ + tANI_S32 k, i, j; + + i = p/10; + j = p%10; + if (p > 0) + k = i + (j > 4 ? 1 : 0); + else if (p < 0) + k = i + (j < -5 ? -1 : 0); + else + k = p; + + return(k); +} + +// New functions for endianess conversion +#ifdef ANI_LITTLE_BYTE_ENDIAN +#define ani_cpu_to_be16(x) sirSwapU16((x)) +#define ani_cpu_to_le16(x) (x) +#define ani_cpu_to_be32(x) sirSwapU32((x)) +#define ani_cpu_to_le32(x) (x) +#else // ANI_LITTLE_BYTE_ENDIAN +#define ani_cpu_to_be16(x) (x) +#define ani_cpu_to_le16(x) sirSwapU16((x)) +#define ani_cpu_to_be32(x) (x) +#define ani_cpu_to_le32(x) sirSwapU32((x)) +#endif // ANI_LITTLE_BYTE_ENDIAN + +#define ani_le16_to_cpu(x) ani_cpu_to_le16(x) +#define ani_le32_to_cpu(x) ani_cpu_to_le32(x) +#define ani_be16_to_cpu(x) ani_cpu_to_be16(x) +#define ani_be32_to_cpu(x) ani_cpu_to_be32(x) + +void ConverttoBigEndian(void *ptr, tANI_U16 size); +void CreateScanCtsFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tSirMacAddr selfMac); +void CreateScanDataNullFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, + tANI_U8 pwrMgmt, tSirMacAddr bssid, + tSirMacAddr selfMacAddr); +void CreateInitScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role); +void CreateFinishScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role); + +#endif /* __UTILSAPI_H */ + + diff --git a/drivers/staging/prima/CORE/MAC/src/include/utilsGlobal.h b/drivers/staging/prima/CORE/MAC/src/include/utilsGlobal.h new file mode 100644 index 000000000000..fd778f63f6f1 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/include/utilsGlobal.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __UTILS_GLOBAL_H__ +#define __UTILS_GLOBAL_H__ + +#include "sirParams.h" + +/* + * Current debug and event log level + */ +#define LOG_FIRST_MODULE_ID SIR_FIRST_MODULE_ID +#define LOG_LAST_MODULE_ID SIR_LAST_MODULE_ID +#define LOG_ENTRY_NUM (LOG_LAST_MODULE_ID - LOG_FIRST_MODULE_ID + 1) + +typedef struct sAniSirUtils +{ + tANI_U32 gLogEvtLevel[LOG_ENTRY_NUM]; + tANI_U32 gLogDbgLevel[LOG_ENTRY_NUM]; + +} tAniSirUtils, *tpAniSirUtils; + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limAdmitControl.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limAdmitControl.h new file mode 100644 index 000000000000..b33afeee4729 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limAdmitControl.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Dinesh Upadhyay + * Date: 10/24/06 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_ADMIT_CONTROL_H__ +#define __LIM_ADMIT_CONTROL_H__ + +#include "sirCommon.h" +#include "sirMacProtDef.h" + +#include "aniGlobal.h" + +tSirRetStatus +limTspecFindByAssocId(tpAniSirGlobal, tANI_U16, tSirMacTspecIE*, tpLimTspecInfo, tpLimTspecInfo *); + +// Add TSPEC in lim local table +tSirRetStatus limTspecAdd( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tANI_U16 assocId, + tSirMacTspecIE *pTspec, + tANI_U32 interval, + tpLimTspecInfo *ppInfo); + + +// admit control interface +extern tSirRetStatus +limAdmitControlAddTS( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tSirAddtsReqInfo *addts, + tSirMacQosCapabilityStaIE *qos, + tANI_U16 assocId, + tANI_U8 alloc, + tSirMacScheduleIE *pSch, + tANI_U8 *pTspecIdx ,//index to the lim tspec table. + tpPESession psessionEntry + ); + +static inline tSirRetStatus +limAdmitControlAddSta( + tpAniSirGlobal pMac, + tANI_U8 *staAddr, + tANI_U8 alloc) +{ return eSIR_SUCCESS;} + +extern tSirRetStatus +limAdmitControlDeleteSta( + tpAniSirGlobal pMac, + tANI_U16 assocId); + +extern tSirRetStatus +limAdmitControlDeleteTS( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTSInfo *tsinfo, + tANI_U8 *tsStatus, + tANI_U8 *tspecIdx); + +extern tSirRetStatus +limUpdateAdmitPolicy( + tpAniSirGlobal pMac); + +tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac); + +tSirRetStatus limSendHalMsgAddTs(tpAniSirGlobal pMac, tANI_U16 staIdx, tANI_U8 tspecIdx, tSirMacTspecIE tspecIE, tANI_U8 sessionId); +tSirRetStatus limSendHalMsgDelTs(tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirDeltsReqInfo delts, + tANI_U8 sessionId, + tANI_U8 *bssId); +void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h new file mode 100644 index 000000000000..88bca93e8def --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limApi.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2011-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limApi.h contains the definitions exported by + * LIM module. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_API_H +#define __LIM_API_H +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "schGlobal.h" +#include "utilsApi.h" +#include "limGlobal.h" +#include "halMsgApi.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_wda.h" +#define LIM_POL_SYS_SCAN_MODE 0 +#define LIM_POL_SYS_LEARN_MODE 1 + +/* Macro to count heartbeat */ +#define limResetHBPktCount(psessionEntry) (psessionEntry->LimRxedBeaconCntDuringHB = 0) + +/* Useful macros for fetching various states in pMac->lim */ +/* gLimSystemRole */ +#define GET_LIM_SYSTEM_ROLE(psessionEntry) (psessionEntry->limSystemRole) +#define LIM_IS_AP_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_AP_ROLE) +#define LIM_IS_STA_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_ROLE) +#define LIM_IS_IBSS_ROLE(psessionEntry) (GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) +/* gLimSmeState */ +#define GET_LIM_SME_STATE(pMac) (pMac->lim.gLimSmeState) +#define SET_LIM_SME_STATE(pMac, state) (pMac->lim.gLimSmeState = state) +/* gLimMlmState */ +#define GET_LIM_MLM_STATE(pMac) (pMac->lim.gLimMlmState) +#define SET_LIM_MLM_STATE(pMac, state) (pMac->lim.gLimMlmState = state) +/*tpdphHashNode mlmStaContext*/ +#define GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs) (pStaDs->mlmStaContext.mlmState) +#define SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, state) (pStaDs->mlmStaContext.mlmState = state) +/* gLimQuietState */ +#define GET_LIM_QUIET_STATE(pMac) (pMac->lim.gLimSpecMgmt.quietState) +#define SET_LIM_QUIET_STATE(pMac, state) (pMac->lim.gLimSpecMgmt.quietState = state) +#define LIM_IS_CONNECTION_ACTIVE(psessionEntry) (psessionEntry->LimRxedBeaconCntDuringHB) +/*pMac->lim.gLimProcessDefdMsgs*/ +#define GET_LIM_PROCESS_DEFD_MESGS(pMac) (pMac->lim.gLimProcessDefdMsgs) +#define SET_LIM_PROCESS_DEFD_MESGS(pMac, val) (pMac->lim.gLimProcessDefdMsgs = val) +// LIM exported function templates +//inline tANI_U16 +//limGetNumAniPeersInBss(tpAniSirGlobal pMac) +//{ return pMac->lim.gLimNumOfAniSTAs; } +#define LIM_IS_RADAR_DETECTED(pMac) (pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan) +#define LIM_SET_RADAR_DETECTED(pMac, val) (pMac->lim.gLimSpecMgmt.fRadarDetCurOperChan = val) +#define LIM_MIN_BCN_PR_LENGTH 12 +#define LIM_BCN_PR_CAPABILITY_OFFSET 10 +#define DEFAULT_MIN_CHAN_TIME_DURING_MIRACAST 20 +#define DEFAULT_MAX_CHAN_TIME_DURING_MIRACAST 20 + +typedef enum eMgmtFrmDropReason +{ + eMGMT_DROP_NO_DROP, + eMGMT_DROP_NOT_LAST_IBSS_BCN, + eMGMT_DROP_INFRA_BCN_IN_IBSS, + eMGMT_DROP_SCAN_MODE_FRAME, + eMGMT_DROP_NON_SCAN_MODE_FRAME, + eMGMT_DROP_INVALID_SIZE, + eMGMT_DROP_SPURIOUS_FRAME, +}tMgmtFrmDropReason; + + +/// During TD ring clean up at HDD in RTAI, will call this call back +extern void limPostTdDummyPktCallbak(void* pMacGlobals, unsigned int* pBd); +/** + * Function to initialize LIM state machines. + * This called upon LIM thread creation. + */ +extern tSirRetStatus limInitialize(tpAniSirGlobal); +tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam); +tSirRetStatus peClose(tpAniSirGlobal pMac); +tSirRetStatus limStart(tpAniSirGlobal pMac); +/** + * Function to Initialize radar interrupts. + */ +void limRadarInit(tpAniSirGlobal pMac); +tSirRetStatus peStart(tpAniSirGlobal pMac); +void peStop(tpAniSirGlobal pMac); +tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ* pMsg); +tSirRetStatus peProcessMsg(tpAniSirGlobal pMac, tSirMsgQ* limMsg); +void limDumpInit(tpAniSirGlobal pMac); +/** + * Function to cleanup LIM state. + * This called upon reset/persona change etc + */ +extern void limCleanup(tpAniSirGlobal); +/// Function to post messages to LIM thread +extern tANI_U32 limPostMsgApi(tpAniSirGlobal, tSirMsgQ *); +tANI_U32 limPostMsgApiHighPri(tpAniSirGlobal, tSirMsgQ *); + +/** + * Function to process messages posted to LIM thread + * and dispatch to various sub modules within LIM module. + */ +extern void limMessageProcessor(tpAniSirGlobal, tpSirMsgQ); +extern void limProcessMessages(tpAniSirGlobal, tpSirMsgQ); // DT test alt deferred 2 +/** + * Function to check the LIM state if system is in Scan/Learn state. + */ +extern tANI_U8 limIsSystemInScanState(tpAniSirGlobal); +/** + * Function to handle IBSS coalescing. + * Beacon Processing module to call this. + */ +extern tSirRetStatus limHandleIBSScoalescing(tpAniSirGlobal, + tpSchBeaconStruct, + tANI_U8 *,tpPESession); +/// Function used by other Sirius modules to read global SME state + static inline tLimSmeStates +limGetSmeState(tpAniSirGlobal pMac) { return pMac->lim.gLimSmeState; } +/// Function used by other Sirius modules to read global system role + static inline tLimSystemRole +limGetSystemRole(tpPESession psessionEntry) { return psessionEntry->limSystemRole; } +//limGetAID(tpPESession psessionEntry) { return psessionEntry->limAID; } +extern void limReceivedHBHandler(tpAniSirGlobal, tANI_U8, tpPESession); +//extern void limResetHBPktCount(tpPESession); +extern void limCheckAndQuietBSS(tpAniSirGlobal); +/// Function to send WDS info to WSM if needed +extern void limProcessWdsInfo(tpAniSirGlobal, tSirPropIEStruct); +/// Function to initialize WDS info params +extern void limInitWdsInfoParams(tpAniSirGlobal); +/// Function that triggers STA context deletion +extern void limTriggerSTAdeletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry); + +#ifdef FEATURE_WLAN_TDLS +// Function that sends TDLS Del Sta indication to SME +extern void limSendSmeTDLSDelStaInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry, tANI_U16 reasonCode); +#endif + +/// Function that checks for change in AP's capabilties on STA +extern void limDetectChangeInApCapabilities(tpAniSirGlobal, + tpSirProbeRespBeacon,tpPESession); +tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBeacon, + tpUpdateBeaconParams pBeaconParams,tpPESession); + +/// creates an addts request action frame and sends it out to staid +extern void limSendAddtsReq (tpAniSirGlobal pMac, tANI_U16 staid, tANI_U8 tsid, tANI_U8 userPrio, tANI_U8 wme); +/// creates a delts request action frame and sends it out to staid +extern void limSendDeltsReq (tpAniSirGlobal pMac, tANI_U16 staid, tANI_U8 tsid, tANI_U8 userPrio, tANI_U8 wme); +/// creates a SM Power State Mode update request action frame and sends it out to staid +extern void limPostStartLearnModeMsgToSch(tpAniSirGlobal pMac); +#ifdef WLAN_FEATURE_11AC +extern ePhyChanBondState limGet11ACPhyCBState(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 htSecondaryChannelOffset, tANI_U8 CenterChan,tpPESession ); +#endif +tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac); +#if 0 /* Currently, this function is not used but keep it around for when we do need it */ +tSirRetStatus limUpdateGlobalChannelBonding(tpAniSirGlobal pMac, tHalBitVal cbBit); +#endif /* 0 */ + +void limHandleLowRssiInd(tpAniSirGlobal pMac); +void limHandleBmpsStatusInd(tpAniSirGlobal pMac); +#ifdef WLAN_FEATURE_APFIND +void limHandleAPFindInd(tpAniSirGlobal pMac); +#endif +void limHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType); +boolean limIsDeauthDiassocForDrop(tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo); +#ifdef WLAN_FEATURE_11W +bool lim_is_assoc_req_for_drop(tpAniSirGlobal mac, uint8_t *rx_pkt_info); +#endif +void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); + +void limProcessLostLinkParamsInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void limUpdateLostLinkParams(tpAniSirGlobal pMac, + tpPESession psessionEntry, tANI_U8 *pRxPacketInfo); + + +/* ----------------------------------------------------------------------- */ +// These used to be in DPH +extern void limSetBssid(tpAniSirGlobal pMac, tANI_U8 *bssId); +extern void limGetBssid(tpAniSirGlobal pMac, tANI_U8 *bssId); +extern void limGetMyMacAddr(tpAniSirGlobal pMac, tANI_U8 *mac); +extern tSirRetStatus limCheckRxSeqNumber(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo); +#define limGetQosMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limQosEnabled) +#define limGetWmeMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWmeEnabled) +#define limGetWsmMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->limWsmEnabled) +#define limGet11dMode(psessionEntry, pVal) (*(pVal) = (psessionEntry)->lim11dEnabled) +#define limGetAckPolicy(pMac, pVal) (*(pVal) = pMac->lim.ackPolicy) +/* ----------------------------------------------------------------------- */ +static inline void limGetPhyMode(tpAniSirGlobal pMac, tANI_U32 *phyMode, tpPESession psessionEntry) +{ + *phyMode = psessionEntry ? psessionEntry->gLimPhyMode : pMac->lim.gLimPhyMode; +} + +/* ----------------------------------------------------------------------- */ +static inline void limGetRfBand(tpAniSirGlobal pMac, tSirRFBand *band, tpPESession psessionEntry) +{ + *band = psessionEntry ? psessionEntry->limRFBand : SIR_BAND_UNKNOWN; +} + +/*-------------------------------------------------------------------------- + + \brief peProcessMessages() - Message Processor for PE + + Voss calls this function to dispatch the message to PE + + \param pMac - Pointer to Global MAC structure + \param pMsg - Pointer to the message structure + + \return tANI_U32 - TX_SUCCESS for success. + + --------------------------------------------------------------------------*/ +tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg); +/** ------------------------------------------------------------- +\fn peFreeMsg +\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs) +\ to free a given PE message on the TX and MC thread. +\ This happens when there are messages pending in the PE +\ queue when system is being stopped and reset. +\param tpAniSirGlobal pMac +\param tSirMsgQ pMsg +\return none +-----------------------------------------------------------------*/ +v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg); +/************************************************************/ +#endif /* __LIM_API_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h new file mode 100644 index 000000000000..bf4dd64b4088 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limFT.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if defined WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + Macros and Function prototypes FT and 802.11R purposes + + ========================================================================*/ + +#ifndef __LIMFT_H__ +#define __LIMFT_H__ + + +#include +#include +#include +#include +#include + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +extern void limFTOpen(tpAniSirGlobal pMac); +extern void limFTCleanup(tpAniSirGlobal pMac); +extern void limFTInit(tpAniSirGlobal pMac); +extern int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +extern void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry); +void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limPerformPostFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry); +void limFTResumeLinkCb(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); +void limPostFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length, + tpPESession psessionEntry); +void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_len, + tpPESession psessionEntry); +void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf, + tpPESession psessionEntry); +void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac); + +tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ); +tSirRetStatus limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ); +void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +#endif /* __LIMFT_H__ */ + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h new file mode 100644 index 000000000000..9e856594c59c --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limFTDefs.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if defined WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + Macros and Function prototypes FT and 802.11R purposes + + ========================================================================*/ + +#ifndef __LIMFTDEFS_H__ +#define __LIMFTDEFS_H__ + + +#include +#include "halMsgApi.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define SIR_MDIE_SIZE 3 // MD ID(2 bytes), Capability(1 byte) +#define MAX_TIDS 8 +#define MAX_FTIE_SIZE 384 // Max size limited to 384, on acct. of IW custom events + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + FT Pre Auth Req SME<->PE + ------------------------------------------------------------------------*/ +typedef struct sSirFTPreAuthReq +{ + tANI_U16 messageType; // eWNI_SME_FT_PRE_AUTH_REQ + tANI_U16 length; + tANI_U32 dot11mode; + tANI_BOOLEAN bPreAuthRspProcessed; /* Track if response is processed for this request + We expect only one response per request. */ + tANI_U8 preAuthchannelNum; + tSirMacAddr currbssId; // BSSID currently associated to suspend the link + tSirMacAddr preAuthbssId; // BSSID to preauth to + tANI_U16 ft_ies_length; + tANI_U8 ft_ies[MAX_FTIE_SIZE]; + tpSirBssDescription pbssDescription; +} tSirFTPreAuthReq, *tpSirFTPreAuthReq; + +/*------------------------------------------------------------------------- + FT Pre Auth Rsp PE<->SME + ------------------------------------------------------------------------*/ +typedef struct sSirFTPreAuthRsp +{ + tANI_U16 messageType; // eWNI_SME_FT_PRE_AUTH_RSP + tANI_U16 length; + tANI_U8 smeSessionId; + tSirMacAddr preAuthbssId; // BSSID to preauth to + tSirRetStatus status; + tANI_U16 ft_ies_length; + tANI_U8 ft_ies[MAX_FTIE_SIZE]; + tANI_U16 ric_ies_length; + tANI_U8 ric_ies[MAX_FTIE_SIZE]; +#ifdef WLAN_FEATURE_LFR_MBB + enum sir_roam_cleanup_type reason; + tCsrRoamInfo *roam_info; +#endif +} tSirFTPreAuthRsp, *tpSirFTPreAuthRsp; + +/*-------------------------------------------------------------------------- + FT Pre Auth Rsp Key SME<->PE + ------------------------------------------------------------------------*/ +typedef struct sSirFTUpdateKeyInfo +{ + tANI_U16 messageType; + tANI_U16 length; + tSirMacAddr bssId; + tSirKeyMaterial keyMaterial; +} tSirFTUpdateKeyInfo, *tpSirFTUpdateKeyInfo; + +/*-------------------------------------------------------------------------- + FT Pre Auth Rsp Key SME<->PE + ------------------------------------------------------------------------*/ +typedef struct sSirFTPreAuthKeyInfo +{ + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +} tSirFTPreAuthKeyInfo, *tpSirFTPreAuthKeyInfo; + +/*------------------------------------------------------------------------- + Global FT Information + ------------------------------------------------------------------------*/ +typedef struct sFTPEContext +{ + tpSirFTPreAuthReq pFTPreAuthReq; // Saved FT Pre Auth Req + void *psavedsessionEntry; + tSirRetStatus ftPreAuthStatus; + tANI_U16 saved_auth_rsp_length; + tANI_U8 saved_auth_rsp[MAX_FTIE_SIZE]; + tSirFTPreAuthKeyInfo *pPreAuthKeyInfo; + // Items created for the new FT, session + void *pftSessionEntry; // Saved session created for pre-auth + void *pAddBssReq; // Save add bss req. + void *pAddStaReq; // Save add sta req. + +} tftPEContext, *tpftPEContext; + + +#endif /* __LIMFTDEFS_H__ */ + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limGlobal.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limGlobal.h new file mode 100644 index 000000000000..1ed099653c67 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limGlobal.h @@ -0,0 +1,720 @@ +/* + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limGlobal.h contains the definitions exported by + * LIM module. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_GLOBAL_H +#define __LIM_GLOBAL_H + +#include "wniApi.h" +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "sirMacPropExts.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "wniCfg.h" +#include "csrApi.h" +#include "sapApi.h" +#include "dot11f.h" + +/// Maximum number of scan hash table entries +#define LIM_MAX_NUM_OF_SCAN_RESULTS 256 + +// Link Test Report Status. This appears in the report frame +#define LINK_TEST_STATUS_SUCCESS 0x1 +#define LINK_TEST_STATUS_UNSUPPORTED_RATE 0x2 +#define LINK_TEST_STATUS_INVALID_ADDR 0x3 + +// Amount of time in nanosec to be sleep-waited before +// enabling RHP (1 millisec) +#define LIM_RHP_WORK_AROUND_DURATION 1000000 + +// Maximum amount of Quiet duration in millisec +#define LIM_MAX_QUIET_DURATION 32 + +#define LIM_TX_WQ_EMPTY_SLEEP_NS 100000 + +// Deferred Message Queue Length +#define MAX_DEFERRED_QUEUE_LEN 20 + +// Maximum Buffer size +#define LIM_MAX_BUF_SIZE 8192 + +// Maximum number of PS - TIM's to be sent with out wakeup from STA +#define LIM_TIM_WAIT_COUNT_FACTOR 5 + +/** Use this count if (LIM_TIM_WAIT_FACTOR * ListenInterval) is less than LIM_MIN_TIM_WAIT_CNT*/ +#define LIM_MIN_TIM_WAIT_COUNT 50 + +#define GET_TIM_WAIT_COUNT(LIntrvl) ((LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) > LIM_MIN_TIM_WAIT_COUNT ? \ + (LIntrvl * LIM_TIM_WAIT_COUNT_FACTOR) : LIM_MIN_TIM_WAIT_COUNT) +#define IS_5G_BAND(__rfBand) ((__rfBand & 0x3) == 0x2) +#define IS_24G_BAND(__rfBand) ((__rfBand & 0x3) == 0x1) + +// enums exported by LIM are as follows + +/// System role definition +typedef enum eLimSystemRole +{ + eLIM_UNKNOWN_ROLE, + eLIM_AP_ROLE, + eLIM_STA_IN_IBSS_ROLE, + eLIM_STA_ROLE, + eLIM_BT_AMP_STA_ROLE, + eLIM_BT_AMP_AP_ROLE, + eLIM_P2P_DEVICE_ROLE, + eLIM_P2P_DEVICE_GO, + eLIM_P2P_DEVICE_CLIENT +} tLimSystemRole; + +/** + * SME state definition accessible across all Sirius modules. + * AP only states are LIM_SME_CHANNEL_SCAN_STATE & + * LIM_SME_NORMAL_CHANNEL_SCAN_STATE. + * Note that these states may also be present in STA + * side too when DFS support is present for a STA in IBSS mode. + */ +typedef enum eLimSmeStates +{ + eLIM_SME_OFFLINE_STATE, + eLIM_SME_IDLE_STATE, + eLIM_SME_SUSPEND_STATE, + eLIM_SME_WT_SCAN_STATE, + eLIM_SME_WT_JOIN_STATE, + eLIM_SME_WT_AUTH_STATE, + eLIM_SME_WT_ASSOC_STATE, + eLIM_SME_WT_REASSOC_STATE, + eLIM_SME_WT_REASSOC_LINK_FAIL_STATE, + eLIM_SME_JOIN_FAILURE_STATE, + eLIM_SME_ASSOCIATED_STATE, + eLIM_SME_REASSOCIATED_STATE, + eLIM_SME_LINK_EST_STATE, + eLIM_SME_LINK_EST_WT_SCAN_STATE, + eLIM_SME_WT_PRE_AUTH_STATE, + eLIM_SME_WT_DISASSOC_STATE, + eLIM_SME_WT_DEAUTH_STATE, + eLIM_SME_WT_START_BSS_STATE, + eLIM_SME_WT_STOP_BSS_STATE, + eLIM_SME_NORMAL_STATE, + eLIM_SME_CHANNEL_SCAN_STATE, + eLIM_SME_NORMAL_CHANNEL_SCAN_STATE +} tLimSmeStates; + +/** + * MLM state definition. + * While these states are present on AP too when it is + * STA mode, per-STA MLM state exclusive to AP is: + * eLIM_MLM_WT_AUTH_FRAME3. + */ +typedef enum eLimMlmStates +{ + eLIM_MLM_OFFLINE_STATE, + eLIM_MLM_IDLE_STATE, + eLIM_MLM_WT_PROBE_RESP_STATE, + eLIM_MLM_PASSIVE_SCAN_STATE, + eLIM_MLM_WT_JOIN_BEACON_STATE, + eLIM_MLM_JOINED_STATE, + eLIM_MLM_BSS_STARTED_STATE, + eLIM_MLM_WT_AUTH_FRAME2_STATE, + eLIM_MLM_WT_AUTH_FRAME3_STATE, + eLIM_MLM_WT_AUTH_FRAME4_STATE, + eLIM_MLM_AUTH_RSP_TIMEOUT_STATE, + eLIM_MLM_AUTHENTICATED_STATE, + eLIM_MLM_WT_ASSOC_RSP_STATE, + eLIM_MLM_WT_REASSOC_RSP_STATE, + eLIM_MLM_ASSOCIATED_STATE, + eLIM_MLM_REASSOCIATED_STATE, + eLIM_MLM_LINK_ESTABLISHED_STATE, + eLIM_MLM_WT_ASSOC_CNF_STATE, + eLIM_MLM_LEARN_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_STATE, + eLIM_MLM_WT_DEL_BSS_RSP_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE, + eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE, + eLIM_MLM_WT_ADD_STA_RSP_STATE, + eLIM_MLM_WT_DEL_STA_RSP_STATE, + //MLM goes to this state when LIM initiates DELETE_STA as processing of Assoc req because + //the entry already exists. LIM comes out of this state when DELETE_STA response from + //HAL is received. LIM needs to maintain this state so that ADD_STA can be issued while + //processing DELETE_STA response from HAL. + eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE, + eLIM_MLM_WT_SET_BSS_KEY_STATE, + eLIM_MLM_WT_SET_STA_KEY_STATE, + eLIM_MLM_WT_SET_STA_BCASTKEY_STATE, + eLIM_MLM_WT_ADDBA_RSP_STATE, + eLIM_MLM_WT_REMOVE_BSS_KEY_STATE, + eLIM_MLM_WT_REMOVE_STA_KEY_STATE, + eLIM_MLM_WT_SET_MIMOPS_STATE, +#if defined WLAN_FEATURE_VOWIFI_11R + eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE, + eLIM_MLM_WT_FT_REASSOC_RSP_STATE, +#endif + eLIM_MLM_P2P_LISTEN_STATE, +} tLimMlmStates; + +// 11h channel quiet states +/* This enum indicates in which state the device is in + * when it receives quiet element in beacon or probe-response. + * The default quiet state of the device is always INIT + * eLIM_QUIET_BEGIN - When Quiet period is started + * eLIM_QUIET_CHANGED - When Quiet period is updated + * eLIM_QUIET_RUNNING - Between two successive Quiet updates + * eLIM_QUIET_END - When quiet period ends + */ +typedef enum eLimQuietStates +{ + eLIM_QUIET_INIT, + eLIM_QUIET_BEGIN, + eLIM_QUIET_CHANGED, + eLIM_QUIET_RUNNING, + eLIM_QUIET_END +} tLimQuietStates; + +// 11h channel switch states +/* This enum indicates in which state the channel-swith + * is presently operating. + * eLIM_11H_CHANSW_INIT - Default state + * eLIM_11H_CHANSW_RUNNING - When channel switch is running + * eLIM_11H_CHANSW_END - After channel switch is complete + */ +typedef enum eLimDot11hChanSwStates +{ + eLIM_11H_CHANSW_INIT, + eLIM_11H_CHANSW_RUNNING, + eLIM_11H_CHANSW_END +} tLimDot11hChanSwStates; + +#ifdef GEN4_SCAN + +//WLAN_SUSPEND_LINK Related +typedef void (*SUSPEND_RESUME_LINK_CALLBACK)(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); + +// LIM to HAL SCAN Management Message Interface states +typedef enum eLimHalScanState +{ + eLIM_HAL_IDLE_SCAN_STATE, + eLIM_HAL_INIT_SCAN_WAIT_STATE, + eLIM_HAL_START_SCAN_WAIT_STATE, + eLIM_HAL_END_SCAN_WAIT_STATE, + eLIM_HAL_FINISH_SCAN_WAIT_STATE, + eLIM_HAL_INIT_LEARN_WAIT_STATE, + eLIM_HAL_START_LEARN_WAIT_STATE, + eLIM_HAL_END_LEARN_WAIT_STATE, + eLIM_HAL_FINISH_LEARN_WAIT_STATE, + eLIM_HAL_SCANNING_STATE, +//WLAN_SUSPEND_LINK Related + eLIM_HAL_SUSPEND_LINK_WAIT_STATE, + eLIM_HAL_SUSPEND_LINK_STATE, + eLIM_HAL_RESUME_LINK_WAIT_STATE, +//end WLAN_SUSPEND_LINK Related +} tLimLimHalScanState; +#endif // GEN4_SCAN + +// LIM states related to A-MPDU/BA +// This is used for maintaining the state between PE and HAL only. +typedef enum eLimBAState +{ + eLIM_BA_STATE_IDLE, // we are not waiting for anything from HAL. + eLIM_BA_STATE_WT_ADD_RSP, //We are waiting for Add rsponse from HAL. + eLIM_BA_STATE_WT_DEL_RSP // We are waiting for Del response from HAL. +} tLimBAState; + + + + + +// MLM Req/Cnf structure definitions +typedef struct sLimMlmAuthReq +{ + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tANI_U32 authFailureTimeout; + tANI_U8 sessionId; +} tLimMlmAuthReq, *tpLimMlmAuthReq; + +typedef struct sLimMlmJoinReq +{ + tANI_U32 joinFailureTimeout; + tSirMacRateSet operationalRateSet; + tANI_U8 sessionId; + tSirBssDescription bssDescription; +} tLimMlmJoinReq, *tpLimMlmJoinReq; + +typedef struct sLimMlmScanReq +{ + tSirBssType bssType; + tSirMacAddr bssId; + tSirMacSSid ssId[SIR_SCAN_MAX_NUM_SSID]; + tSirScanType scanType; + tANI_U32 minChannelTime; + tANI_U32 maxChannelTime; + tANI_U32 min_chntime_btc_esco; + tANI_U32 max_chntime_btc_esco; + tSirBackgroundScanMode backgroundScanMode; + tANI_U32 dot11mode; + /* Number of SSIDs to scan(send Probe request) */ + tANI_U8 numSsid; + + tANI_BOOLEAN p2pSearch; + tANI_U16 uIEFieldLen; + tANI_U16 uIEFieldOffset; + + //channelList MUST be the last field of this structure + tSirChannelList channelList; + /*----------------------------- + tLimMlmScanReq.... + ----------------------------- + uIEFiledLen + ----------------------------- + uIEFiledOffset ----+ + ----------------------------- | + channelList.numChannels | + ----------------------------- | + ... variable size up to | + channelNumber[numChannels-1] | + This can be zero, if | + numChannel is zero. | + ----------------------------- <--+ + ... variable size uIEFiled + up to uIEFieldLen (can be 0) + -----------------------------*/ +} tLimMlmScanReq, *tpLimMlmScanReq; + +typedef struct tLimScanResultNode tLimScanResultNode; +struct tLimScanResultNode +{ + tLimScanResultNode *next; + tSirBssDescription bssDescription; +}; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +// OEM Data related structure definitions +typedef struct sLimMlmOemDataReq +{ + tSirMacAddr selfMacAddr; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tLimMlmOemDataReq, *tpLimMlmOemDataReq; + +typedef struct sLimMlmOemDataRsp +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tLimMlmOemDataRsp, *tpLimMlmOemDataRsp; +#endif + +// Pre-authentication structure definition +typedef struct tLimPreAuthNode +{ + struct tLimPreAuthNode *next; + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tLimMlmStates mlmState; + tANI_U8 authNodeIdx; + tANI_U8 challengeText[SIR_MAC_AUTH_CHALLENGE_LENGTH]; + tANI_U8 fTimerStarted:1; + tANI_U8 fSeen:1; + tANI_U8 fFree:1; + tANI_U8 rsvd:5; + TX_TIMER timer; + tANI_U16 seqNo; + v_TIME_t timestamp; +}tLimPreAuthNode, *tpLimPreAuthNode; + +// Pre-authentication table definition +typedef struct tLimPreAuthTable +{ + tANI_U32 numEntry; + tpLimPreAuthNode pTable; +}tLimPreAuthTable, *tpLimPreAuthTable; + +/// Per STA context structure definition +typedef struct sLimMlmStaContext +{ + tLimMlmStates mlmState; + tAniAuthType authType; + tANI_U16 listenInterval; + tSirMacCapabilityInfo capabilityInfo; + tSirMacPropRateSet propRateSet; + tSirMacReasonCodes disassocReason; + tANI_U16 cleanupTrigger; + + tSirResultCodes resultCode; + tANI_U16 protStatusCode; + + tANI_U8 subType:1; // Indicates ASSOC (0) or REASSOC (1) + tANI_U8 updateContext:1; + tANI_U8 schClean:1; + // 802.11n HT Capability in Station: Enabled 1 or DIsabled 0 + tANI_U8 htCapability:1; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapability:1; +#endif +} tLimMlmStaContext, *tpLimMlmStaContext; + +// Structure definition to hold deferred messages queue parameters +typedef struct sLimDeferredMsgQParams +{ + tSirMsgQ deferredQueue[MAX_DEFERRED_QUEUE_LEN]; + tANI_U16 size; + tANI_U16 read; + tANI_U16 write; +} tLimDeferredMsgQParams, *tpLimDeferredMsgQParams; + +typedef struct sLimTraceQ +{ + tANI_U32 type; + tLimSmeStates smeState; + tLimMlmStates mlmState; + tANI_U32 value; + tANI_U32 value2; +} tLimTraceQ; + +typedef struct sLimTraceParams +{ + tLimTraceQ traceQueue[1024]; + tANI_U16 write; + tANI_U16 enabled; +} tLimTraceParams; + +typedef struct sCfgProtection +{ + tANI_U32 overlapFromlla:1; + tANI_U32 overlapFromllb:1; + tANI_U32 overlapFromllg:1; + tANI_U32 overlapHt20:1; + tANI_U32 overlapNonGf:1; + tANI_U32 overlapLsigTxop:1; + tANI_U32 overlapRifs:1; + tANI_U32 overlapOBSS:1; /* added for obss */ + tANI_U32 fromlla:1; + tANI_U32 fromllb:1; + tANI_U32 fromllg:1; + tANI_U32 ht20:1; + tANI_U32 nonGf:1; + tANI_U32 lsigTxop:1; + tANI_U32 rifs:1; + tANI_U32 obss:1; /* added for Obss */ +}tCfgProtection, *tpCfgProtection; + +typedef enum eLimProtStaCacheType +{ + eLIM_PROT_STA_CACHE_TYPE_INVALID, + eLIM_PROT_STA_CACHE_TYPE_llB, + eLIM_PROT_STA_CACHE_TYPE_llG, + eLIM_PROT_STA_CACHE_TYPE_HT20 +}tLimProtStaCacheType; + +typedef struct sCacheParams +{ + tANI_U8 active; + tSirMacAddr addr; + tLimProtStaCacheType protStaCacheType; + +} tCacheParams, *tpCacheParams; + +#define LIM_PROT_STA_OVERLAP_CACHE_SIZE HAL_NUM_ASSOC_STA +#define LIM_PROT_STA_CACHE_SIZE HAL_NUM_ASSOC_STA + +typedef struct sLimProtStaParams +{ + tANI_U8 numSta; + tANI_U8 protectionEnabled; +} tLimProtStaParams, *tpLimProtStaParams; + + +typedef struct sLimNoShortParams +{ + tANI_U8 numNonShortPreambleSta; + tCacheParams staNoShortCache[LIM_PROT_STA_CACHE_SIZE]; +} tLimNoShortParams, *tpLimNoShortParams; + +typedef struct sLimNoShortSlotParams +{ + tANI_U8 numNonShortSlotSta; + tCacheParams staNoShortSlotCache[LIM_PROT_STA_CACHE_SIZE]; +} tLimNoShortSlotParams, *tpLimNoShortSlotParams; + + +typedef struct tLimIbssPeerNode tLimIbssPeerNode; +struct tLimIbssPeerNode +{ + tLimIbssPeerNode *next; + tSirMacAddr peerMacAddr; + tANI_U8 aniIndicator:1; + tANI_U8 extendedRatesPresent:1; + tANI_U8 edcaPresent:1; + tANI_U8 wmeEdcaPresent:1; + tANI_U8 wmeInfoPresent:1; + tANI_U8 htCapable:1; + tANI_U8 vhtCapable:1; + tANI_U8 rsvd:1; + tANI_U8 htSecondaryChannelOffset; + tSirMacCapabilityInfo capabilityInfo; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tANI_U8 supportedMCSSet[SIZE_OF_SUPPORTED_MCS_SET]; + tSirMacEdcaParamSetIE edcaParams; + tANI_U16 propCapability; + tANI_U8 erpIePresent; + + //HT Capabilities of IBSS Peer + tANI_U8 htGreenfield; + tANI_U8 htShortGI40Mhz; + tANI_U8 htShortGI20Mhz; + + // DSSS/CCK at 40 MHz: Enabled 1 or Disabled + tANI_U8 htDsssCckRate40MHzSupport; + + // MIMO Power Save + tSirMacHTMIMOPowerSaveState htMIMOPSState; + + // + // A-MPDU Density + // 000 - No restriction + // 001 - 1/8 usec + // 010 - 1/4 usec + // 011 - 1/2 usec + // 100 - 1 usec + // 101 - 2 usec + // 110 - 4 usec + // 111 - 8 usec + // + tANI_U8 htAMpduDensity; + + // Maximum Rx A-MPDU factor + tANI_U8 htMaxRxAMpduFactor; + + //Set to 0 for 3839 octets + //Set to 1 for 7935 octets + tANI_U8 htMaxAmsduLength; + + // + // Recommended Tx Width Set + // 0 - use 20 MHz channel (control channel) + // 1 - use 40 Mhz channel + // + tANI_U8 htSupportedChannelWidthSet; + + tANI_U8 beaconHBCount; + tANI_U8 heartbeatFailure; + + tANI_U8 *beacon; //Hold beacon to be sent to HDD/CSR + tANI_U16 beaconLen; + +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps VHTCaps; + tANI_U8 vhtSupportedChannelWidthSet; + tANI_U8 vhtBeamFormerCapable; +#endif +}; + +// Enums used for channel switching. +typedef enum eLimChannelSwitchState +{ + eLIM_CHANNEL_SWITCH_IDLE, + eLIM_CHANNEL_SWITCH_PRIMARY_ONLY, + eLIM_CHANNEL_SWITCH_SECONDARY_ONLY, + eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY +} tLimChannelSwitchState; + + +// Channel Switch Info +typedef struct sLimChannelSwitchInfo +{ + tLimChannelSwitchState state; + tANI_U8 primaryChannel; + ePhyChanBondState secondarySubBand; + tANI_U32 switchCount; + tANI_U32 switchTimeoutValue; + tANI_U8 switchMode; +} tLimChannelSwitchInfo, *tpLimChannelSwitchInfo; + +#ifdef WLAN_FEATURE_11AC +typedef struct sLimOperatingModeInfo +{ + tANI_U8 present; + tANI_U8 chanWidth: 2; + tANI_U8 reserved: 2; + tANI_U8 rxNSS: 3; + tANI_U8 rxNSSType: 1; +}tLimOperatingModeInfo, *tpLimOperatingModeInfo; + +typedef struct sLimWiderBWChannelSwitch +{ + tANI_U8 newChanWidth; + tANI_U8 newCenterChanFreq0; + tANI_U8 newCenterChanFreq1; +}tLimWiderBWChannelSwitchInfo, *tpLimWiderBWChannelSwitchInfo; +#endif +// Enums used when stopping the Tx. +typedef enum eLimQuietTxMode +{ + eLIM_TX_ALL = 0, /* Stops/resumes the transmission of all stations, Uses the global flag. */ + eLIM_TX_STA, /* Stops/resumes the transmission of specific stations identified by staId. */ + eLIM_TX_BSS, /* Stops/resumes the transmission of all the packets in BSS */ + eLIM_TX_BSS_BUT_BEACON /* Stops/resumes the transmission of all packets except beacons in BSS + * This is used when radar is detected in the current operating channel. + * Beacon has to be sent to notify the stations associated about the + * scheduled channel switch */ +} tLimQuietTxMode; + +typedef enum eLimControlTx +{ + eLIM_RESUME_TX = 0, + eLIM_STOP_TX +} tLimControlTx; + + +// -------------------------------------------------------------------- + +typedef __ani_attr_pre_packed struct sLimTspecInfo +{ + tANI_U8 inuse; // 0==free, else used + tANI_U8 idx; // index in list + tANI_U8 staAddr[6]; + tANI_U16 assocId; + tSirMacTspecIE tspec; + tANI_U8 numTclas; // number of Tclas elements + tSirTclasInfo tclasInfo[SIR_MAC_TCLASIE_MAXNUM]; + tANI_U8 tclasProc; + tANI_U8 tclasProcPresent:1; //tclassProc is valid only if this is set to 1. +} __ani_attr_packed tLimTspecInfo, *tpLimTspecInfo; + +typedef struct sLimAdmitPolicyInfo +{ + tANI_U8 type; // admit control policy type + tANI_U8 bw_factor; // oversubscription factor : 0 means nothing is allowed + // valid only when 'type' is set BW_FACTOR +} tLimAdmitPolicyInfo, *tpLimAdmitPolicyInfo; + + +typedef enum eLimWscEnrollState +{ + eLIM_WSC_ENROLL_NOOP, + eLIM_WSC_ENROLL_BEGIN, + eLIM_WSC_ENROLL_IN_PROGRESS, + eLIM_WSC_ENROLL_END + +} tLimWscEnrollState; + +#define WSC_PASSWD_ID_PUSH_BUTTON (0x0004) + +typedef struct sLimWscIeInfo +{ + tANI_BOOLEAN apSetupLocked; + tANI_BOOLEAN selectedRegistrar; + tANI_U16 selectedRegistrarConfigMethods; + tLimWscEnrollState wscEnrollmentState; + tLimWscEnrollState probeRespWscEnrollmentState; + tANI_U8 reqType; + tANI_U8 respType; +} tLimWscIeInfo, *tpLimWscIeInfo; + +// maximum number of tspec's supported +#define LIM_NUM_TSPEC_MAX 15 + + +//structure to hold all 11h specific data +typedef struct sLimSpecMgmtInfo +{ + tLimQuietStates quietState; + tANI_U32 quietCount; + tANI_U32 quietDuration; /* This is in units of system TICKS */ + tANI_U32 quietDuration_TU; /* This is in units of TU, for over the air transmission */ + tANI_U32 quietTimeoutValue; /* After this timeout, actual quiet starts */ + tANI_BOOLEAN fQuietEnabled; /* Used on AP, if quiet is enabled during learning */ + + tLimDot11hChanSwStates dot11hChanSwState; + + tANI_BOOLEAN fRadarDetCurOperChan; /* Radar detected in cur oper chan on AP */ + tANI_BOOLEAN fRadarIntrConfigured; /* Whether radar interrupt has been configured */ +}tLimSpecMgmtInfo, *tpLimSpecMgmtInfo; + +#ifdef FEATURE_WLAN_TDLS +/* + * Peer info needed for TDLS setup.. + */ +typedef struct tLimTDLSPeerSta +{ + struct tLimTDLSPeerSta *next; + tANI_U8 dialog ; + tSirMacAddr peerMac; + tSirMacCapabilityInfo capabilityInfo; + tSirMacRateSet supportedRates; + tSirMacRateSet extendedRates; + tSirMacQosCapabilityStaIE qosCaps; + tSirMacEdcaParamSetIE edcaParams; + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + tANI_U8 tdls_bIsResponder ; + /* HT Capabilties */ + tDot11fIEHTCaps tdlsPeerHTCaps ; + tDot11fIEExtCap tdlsPeerExtCaps; + tANI_U8 tdls_flags ; + tANI_U8 tdls_link_state ; + tANI_U8 tdls_prev_link_state ; + tANI_U8 tdls_sessionId; + tANI_U8 ExtRatesPresent ; + TX_TIMER gLimTdlsLinkSetupRspTimeoutTimer ; + TX_TIMER gLimTdlsLinkSetupCnfTimeoutTimer ; +}tLimTdlsLinkSetupPeer, *tpLimTdlsLinkSetupPeer ; + +typedef struct tLimTdlsLinkSetupInfo +{ + tLimTdlsLinkSetupPeer *tdlsLinkSetupList ; + tANI_U8 num_tdls_peers ; + tANI_U8 tdls_flags ; + tANI_U8 tdls_state ; + tANI_U8 tdls_prev_state ; +}tLimTdlsLinkSetupInfo, *tpLimTdlsLinkSetupInfo ; + +typedef enum tdlsLinkMode +{ + TDLS_LINK_MODE_BG, + TDLS_LINK_MODE_N, + TDLS_LINK_MODE_AC, + TDLS_LINK_MODE_NONE +} eLimTdlsLinkMode ; +#endif /* FEATURE_WLAN_TDLS */ + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h new file mode 100644 index 000000000000..21b75bfb4bab --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limSession.h @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __LIM_SESSION_H ) +#define __LIM_SESSION_H + + +/**========================================================================= + + \file limSession.h + + \brief prototype for lim Session related APIs + + \author Sunit Bhatia + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define NUM_WEP_KEYS 4 + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct +{ + tSirMacBeaconInterval beaconInterval; + tANI_U8 fShortPreamble; + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20Coexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fRIFSMode; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 gHTObssMode; +}tBeaconParams, *tpBeaconParams; + +typedef struct sPESession // Added to Support BT-AMP +{ + /* To check session table is in use or free*/ + tANI_U8 available; + tANI_U8 peSessionId; + tANI_U8 smeSessionId; + tANI_U16 transactionId; + + //In AP role: BSSID and selfMacAddr will be the same. + //In STA role: they will be different + tSirMacAddr bssId; + tSirMacAddr selfMacAddr; + tSirMacSSid ssId; + tANI_U8 bssIdx; + tANI_U8 valid; + tLimMlmStates limMlmState; //MLM State + tLimMlmStates limPrevMlmState; //Previous MLM State + tLimSmeStates limSmeState; //SME State + tLimSmeStates limPrevSmeState; //Previous SME State + tLimSystemRole limSystemRole; + tSirBssType bssType; + tANI_U8 operMode; // AP - 0; STA - 1 ; + tSirNwType nwType; + tpSirSmeStartBssReq pLimStartBssReq; //handle to smestart bss req + tANI_BOOLEAN bOSENAssociation; //handle to OSEN assoc req + tANI_BOOLEAN bWPSAssociation; //WPS Registration + tpSirSmeJoinReq pLimJoinReq; // handle to sme join req + tpSirSmeJoinReq pLimReAssocReq; //handle to sme reassoc req + tpLimMlmJoinReq pLimMlmJoinReq; //handle to MLM join Req +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + void *pLimMlmReassocRetryReq; //keep reasoc req for retry +#endif + void *pLimMlmReassocReq; //handle to MLM reassoc Req + tANI_U16 channelChangeReasonCode; + tANI_U16 channelChangeCSA; // channel change flag for CSA + tANI_U8 dot11mode; + tANI_U8 htCapability; + /* Supported Channel Width Set: 0-20MHz 1 - 40MHz */ + tANI_U8 htSupportedChannelWidthSet; + /* Recommended Tx Width Set + * 0 - use 20 MHz channel (control channel) + * 1 - use channel width enabled under Supported Channel Width Set + */ + tANI_U8 htRecommendedTxWidthSet; + /* Identifies the 40 MHz extension channel */ + ePhyChanBondState htSecondaryChannelOffset; + tSirRFBand limRFBand; + tANI_U8 limIbssActive; //TO SUPPORT CONCURRENCY + + /* These global varibales moved to session Table to support BT-AMP : Oct 9th review */ + tAniAuthType limCurrentAuthType; + tANI_U16 limCurrentBssCaps; + tANI_U8 limCurrentBssQosCaps; + tANI_U16 limCurrentBssPropCap; + tANI_U8 limSentCapsChangeNtf; + tANI_U16 limAID; + + /* Parameters For Reassociation */ + tSirMacAddr limReAssocbssId; + tSirMacChanNum limReassocChannelId; + /* CB paramaters required/duplicated for Reassoc since re-assoc mantains its own params in lim */ + tANI_U8 reAssocHtSupportedChannelWidthSet; + tANI_U8 reAssocHtRecommendedTxWidthSet; + ePhyChanBondState reAssocHtSecondaryChannelOffset; + tSirMacSSid limReassocSSID; + tANI_U16 limReassocBssCaps; + tANI_U8 limReassocBssQosCaps; + tANI_U16 limReassocBssPropCap; + + // Assoc or ReAssoc Response Data/Frame + void *limAssocResponseData; + + + + /** BSS Table parameters **/ + + + /* + * staId: Start BSS: this is the Sta Id for the BSS. + Join: this is the selfStaId + In both cases above, the peer STA ID wll be stored in dph hash table. + */ + tANI_U16 staId; + tANI_U16 statypeForBss; //to know session is for PEER or SELF + tANI_U8 shortSlotTimeSupported; + tANI_U8 dtimPeriod; + tSirMacRateSet rateSet; + tSirMacRateSet extRateSet; + tSirMacHTOperatingMode htOperMode; + tANI_U8 currentOperChannel; + tANI_U8 currentReqChannel; + tANI_U8 LimRxedBeaconCntDuringHB; + + //Time stamp of the last beacon received from the BSS to which STA is connected. + tANI_U64 lastBeaconTimeStamp; + //RX Beacon count for the current BSS to which STA is connected. + tANI_U32 currentBssBeaconCnt; + tANI_U8 lastBeaconDtimCount; + tANI_U8 lastBeaconDtimPeriod; + + tANI_U32 bcnLen; + tANI_U8 *beacon; //Used to store last beacon / probe response before assoc. + + tANI_U32 assocReqLen; + tANI_U8 *assocReq; //Used to store association request frame sent out while associating. + + tANI_U32 assocRspLen; + tANI_U8 *assocRsp; //Used to store association response received while associating + tAniSirDph dph; + void * *parsedAssocReq; //Used to store parsed assoc req from various requesting station +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U32 RICDataLen; //Used to store the Ric data received in the assoc response + tANI_U8 *ricData; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U32 tspecLen; //Used to store the TSPEC IEs received in the assoc response + tANI_U8 *tspecIes; +#endif + tANI_U32 encryptType; + + tANI_BOOLEAN bTkipCntrMeasActive; // Used to keep record of TKIP counter measures start/stop + + tANI_U8 gLimProtectionControl; //used for 11n protection + + tANI_U8 gHTNonGFDevicesPresent; + + //protection related config cache + tCfgProtection cfgProtection; + + // Number of legacy STAs associated + tLimProtStaParams gLim11bParams; + + // Number of 11A STAs associated + tLimProtStaParams gLim11aParams; + + // Number of non-ht non-legacy STAs associated + tLimProtStaParams gLim11gParams; + + //Number of nonGf STA associated + tLimProtStaParams gLimNonGfParams; + + //Number of HT 20 STAs associated + tLimProtStaParams gLimHt20Params; + + //Number of Lsig Txop not supported STAs associated + tLimProtStaParams gLimLsigTxopParams; + + // Number of STAs that do not support short preamble + tLimNoShortParams gLimNoShortParams; + + // Number of STAs that do not support short slot time + tLimNoShortSlotParams gLimNoShortSlotParams; + + + // OLBC parameters + tLimProtStaParams gLimOlbcParams; + + // OLBC parameters + tLimProtStaParams gLimOverlap11gParams; + + tLimProtStaParams gLimOverlap11aParams; + tLimProtStaParams gLimOverlapHt20Params; + tLimProtStaParams gLimOverlapNonGfParams; + + //cache for each overlap + tCacheParams protStaCache[LIM_PROT_STA_CACHE_SIZE]; + + tANI_U8 privacy; + tAniAuthType authType; + tSirKeyMaterial WEPKeyMaterial[NUM_WEP_KEYS]; + + tDot11fIERSN gStartBssRSNIe; + tDot11fIEWPA gStartBssWPAIe; + tSirAPWPSIEs APWPSIEs; + tANI_U8 apUapsdEnable; + tSirWPSPBCSession *pAPWPSPBCSession; + tANI_U32 DefProbeRspIeBitmap[8]; + tANI_U32 proxyProbeRspEn; + tDot11fProbeResponse probeRespFrame; + tANI_U8 ssidHidden; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tANI_U8 wps_state; + + tANI_U8 limQosEnabled:1; //11E + tANI_U8 limWmeEnabled:1; //WME + tANI_U8 limWsmEnabled:1; //WSM + tANI_U8 limHcfEnabled:1; + tANI_U8 lim11dEnabled:1; +#ifdef WLAN_FEATURE_11W + tANI_U8 limRmfEnabled:1; //11W +#endif + tANI_U32 lim11hEnable; + + tPowerdBm maxTxPower; //MIN (Regulatory and local power constraint) + tVOS_CON_MODE pePersona; +#if defined WLAN_FEATURE_VOWIFI + tPowerdBm txMgmtPower; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + tAniBool is11Rconnection; +#endif + +#ifdef FEATURE_WLAN_ESE + tAniBool isESEconnection; + tEsePEContext eseContext; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + tAniBool isFastTransitionEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + tAniBool isFastRoamIniFeatureEnabled; +#endif + tSirNoAParam p2pNoA; + tSirP2PNoaAttr p2pGoPsUpdate; + tANI_U32 defaultAuthFailureTimeout; + tSirP2PNoaStart p2pGoPsNoaStartInd; + + /* EDCA QoS parameters + * gLimEdcaParams - These EDCA parameters are used locally on AP or STA. + * If STA, then these are values taken from the Assoc Rsp when associating, + * or Beacons/Probe Response after association. If AP, then these are + * values originally set locally on AP. + * + * gLimEdcaParamsBC - These EDCA parameters are use by AP to broadcast + * to other STATIONs in the BSS. + * + * gLimEdcaParamsActive: These EDCA parameters are what's actively being + * used on station. Specific AC values may be downgraded depending on + * admission control for that particular AC. + */ + tSirMacEdcaParamRecord gLimEdcaParams[MAX_NUM_AC]; //used locally + tSirMacEdcaParamRecord gLimEdcaParamsBC[MAX_NUM_AC]; //used for broadcast + tSirMacEdcaParamRecord gLimEdcaParamsActive[MAX_NUM_AC]; + + tANI_U8 gLimEdcaParamSetCount; + + tBeaconParams beaconParams; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapability; + tANI_U8 vhtTxChannelWidthSet; + tLimOperatingModeInfo gLimOperatingMode; + tLimWiderBWChannelSwitchInfo gLimWiderBWChannelSwitch; + tANI_U8 vhtCapabilityPresentInBeacon; + tANI_U8 apCenterChan; + tANI_U8 apChanWidth; + tANI_U8 txBFIniFeatureEnabled; + tANI_U8 txMuBformee; +#endif + tANI_U8 spectrumMgtEnabled; + /* *********************11H related*****************************/ + //tANI_U32 gLim11hEnable; + tLimSpecMgmtInfo gLimSpecMgmt; + // CB Primary/Secondary Channel Switch Info + tLimChannelSwitchInfo gLimChannelSwitch; + /* *********************End 11H related*****************************/ + + /*Flag to Track Status/Indicate HBFailure on this session */ + tANI_BOOLEAN LimHBFailureStatus; + tANI_U32 gLimPhyMode; + tANI_U8 amsduSupportedInBA; + tANI_U8 txLdpcIniFeatureEnabled; + /** + * Following is the place holder for free peer index pool. + * A non-zero value indicates that peer index is available + * for assignment. + */ + tANI_U8 *gpLimPeerIdxpool; + tANI_U8 freePeerIdxHead; + tANI_U8 freePeerIdxTail; + tANI_U16 gLimNumOfCurrentSTAs; +#ifdef FEATURE_WLAN_TDLS + tANI_U32 peerAIDBitmap[2]; + tANI_BOOLEAN tdlsChanSwitProhibited; +#endif + tANI_BOOLEAN fWaitForProbeRsp; + tANI_BOOLEAN fIgnoreCapsChange; + tANI_BOOLEAN fDeauthReceived; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM + tANI_S8 rssi; +#endif + tANI_U8 isAmsduSupportInAMPDU; + tANI_U8 isCoalesingInIBSSAllowed; + tANI_BOOLEAN isCiscoVendorAP; + /* To hold OBSS Scan IE Parameters */ + tSirOBSSHT40Param obssHT40ScanParam; + /* HS 2.0 Indication */ + tDot11fIEhs20vendor_ie hs20vendor_ie; + /* flag to indicate country code in beacon */ + tANI_U8 countryInfoPresent; + /* DSCP to UP mapping for HS 2.0 */ + tSirQosMapSet QosMapSet; + tANI_U8 isKeyInstalled; + tANI_BOOLEAN is11Gonly; + tANI_BOOLEAN addBssfailed; + tDot11fIEExtCap ExtCap; + uint32_t sta_auth_retries_for_code17; + tDot11fIEHTCaps ht_caps; + tDot11fIEVHTCaps vht_caps; + tDot11fIEHTInfo ht_operation; + tDot11fIEVHTOperation vht_operation; + bool force_24ghz_in_ht20; +}tPESession, *tpPESession; + +#define LIM_MAX_ACTIVE_SESSIONS 4 + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + + \brief peCreateSession() - creates a new PE session given the BSSID + + This function returns the session context and the session ID if the session + corresponding to the passed BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the new session + \param sessionId -session ID is returned here, if session is created. + + \return tpPESession - pointer to the session context or NULL if session can not be created. + + \sa + + --------------------------------------------------------------------------*/ +tpPESession peCreateSession(tpAniSirGlobal pMac, tANI_U8 *bssid , tANI_U8* sessionId, tANI_U16 numSta); + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssid() - looks up the PE session given the BSSID. + + This function returns the session context and the session ID if the session + corresponding to the given BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_U8* sessionId); + + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssIdx() - looks up the PE session given the bssIdx. + + This function returns the session context if the session + corresponding to the given bssIdx is found in the PE session table. + \param pMac - pointer to global adapter context + \param bssIdx - bss index of the session + \return tpPESession - pointer to the session context or NULL if session is not found. + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssIdx(tpAniSirGlobal pMac, tANI_U8 bssIdx); + + +tANI_S8 limGetInfraSessionId(tpAniSirGlobal pMac); + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByPeerSta() - looks up the PE session given the Peer Station Address. + + This function returns the session context and the session ID if the session + corresponding to the given destination address is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sa - Peer STA Address of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByPeerSta(tpAniSirGlobal pMac, tANI_U8* sa, tANI_U8* sessionId); + +/*-------------------------------------------------------------------------- + \brief peFindSessionBySessionId() - looks up the PE session given the session ID. + + This function returns the session context if the session + corresponding to the given session ID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sessionId -session ID for which session context needs to be looked up. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ + tpPESession peFindSessionBySessionId(tpAniSirGlobal pMac , tANI_U8 sessionId); + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssid() - looks up the PE session given staid. + + This function returns the session context and the session ID if the session + corresponding to the given StaId is found in the PE session table. + + \param pMac - pointer to global adapter context + \param staid - StaId of the session + \param sessionId - session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + +--------------------------------------------------------------------------*/ + tpPESession peFindSessionByStaId(tpAniSirGlobal pMac, tANI_U8 staid, tANI_U8* sessionId); + + + + + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - deletes the PE session given the session ID. + + + \param pMac - pointer to global adapter context + \param sessionId -session ID of the session which needs to be deleted. + + \sa + --------------------------------------------------------------------------*/ +void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry); + + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - Returns the SME session ID and Transaction ID . + + + \param pMac - pointer to global adapter context + \param sessionId -session ID of the session which needs to be deleted. + + \sa + --------------------------------------------------------------------------*/ + +int peFindBssIdxFromSmeSessionId(tpAniSirGlobal pMac, tANI_U8 sme_sessionId); +#endif //#if !defined( __LIM_SESSION_H ) diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/limTrace.h b/drivers/staging/prima/CORE/MAC/src/pe/include/limTrace.h new file mode 100644 index 000000000000..24ffb8cf6e36 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/limTrace.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + +* \file limTrace.h + +* \brief definition for trace related APIs + +* \author Sunit Bhatia + + + ========================================================================*/ + + + +#ifndef __LIM_TRACE_H +#define __LIM_TRACE_H + +#include "limGlobal.h" +#include "macTrace.h" +#include "vos_trace.h" +#ifdef LIM_TRACE_RECORD + + + +#define LIM_TRACE_GET_SSN(data) (((data) >> 16) & 0xff) +#define LIM_TRACE_GET_SUBTYPE(data) (data & 0xff) +#define LIM_TRACE_GET_DEFERRED(data) (data & 0x80000000) +#define LIM_TRACE_GET_DEFRD_OR_DROPPED(data) (data & 0xc0000000) + +#define LIM_MSG_PROCESSED 0 +#define LIM_MSG_DEFERRED 1 +#define LIM_MSG_DROPPED 2 + +#define LIM_TRACE_MAKE_RXMGMT(type, ssn) \ + ((ssn << 16) | (type) ) +#define LIM_TRACE_MAKE_RXMSG(msg, action) \ + ((msg) | (action << 30) ) + + + + +enum { + TRACE_CODE_MLM_STATE, + TRACE_CODE_SME_STATE, + TRACE_CODE_TX_MGMT, + TRACE_CODE_RX_MGMT, + TRACE_CODE_RX_MGMT_TSF, + TRACE_CODE_TX_COMPLETE, + TRACE_CODE_TX_SME_MSG, + TRACE_CODE_RX_SME_MSG, + TRACE_CODE_TX_WDA_MSG, + TRACE_CODE_RX_WDA_MSG, + TRACE_CODE_TX_LIM_MSG, + TRACE_CODE_RX_LIM_MSG, + TRACE_CODE_TX_CFG_MSG, + TRACE_CODE_RX_CFG_MSG, + TRACE_CODE_RX_MGMT_DROP, + + TRACE_CODE_TIMER_ACTIVATE, + TRACE_CODE_TIMER_DEACTIVATE, + TRACE_CODE_INFO_LOG +}; + + + + + + +void limTraceInit(tpAniSirGlobal pMac); +void lim_register_debug_callback(void); +void limTraceReset(tpAniSirGlobal pMac); +void limTraceUpdateMgmtStat(tpAniSirGlobal pMac, tANI_U8 subtype); +void limTraceDumpMgmtStat(tpAniSirGlobal pMac, tANI_U8 subtype); +tANI_U8* limTraceGetMlmStateString( tANI_U32 mlmState ); +tANI_U8* limTraceGetSmeStateString( tANI_U32 smeState ); +void limTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex); +void macTraceMsgTx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data); +void macTraceMsgRx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data); + +void macTraceMsgRxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data); +void macTraceMsgTxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data); +#endif //endof LIM_TRACE_RECORD MACRO + +#endif + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h b/drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h new file mode 100644 index 000000000000..770263ef1e0c --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/lim_mbb.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac); +void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg); +void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac, + tSirRetStatus status, tpPESession session_entry); +void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac); +void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac, + tpPESession session_entry); +void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac, + tpPESession session_entry, tpSirAssocRsp assoc_rsp, tpDphHashNode sta_ds); +void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ lim_msg, tpPESession session_entry); +void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ lim_msg, tpPESession session_entry); +void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ limMsgQ,tpPESession session_entry); +void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ limMsgQ,tpPESession session_entry); +eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac, + tpPESession session_entry); diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/pmmApi.h b/drivers/staging/prima/CORE/MAC/src/pe/include/pmmApi.h new file mode 100644 index 000000000000..aa3a13bf260c --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/pmmApi.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __PMM_API_H__ +#define __PMM_API_H__ + +#include "sirCommon.h" +#include "schApi.h" +#include "halMsgApi.h" + + +/// Initialize PMM +extern tSirRetStatus pmmInitialize(tpAniSirGlobal pMac); + +/// Post a message to PMM module +extern tSirRetStatus pmmPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg); + +/// Reset PMM beacon mode power save statistics +extern void pmmResetStats(void *pvMac); + +/// Process the next PM message +extern void pmmProcessMessage(tpAniSirGlobal, tpSirMsgQ); + +extern void pmmProcessPSPoll(tpAniSirGlobal, tANI_U8 *); +extern void pmmUpdatePSPollState(tpAniSirGlobal); +extern void pmmProcessRxActivity(tpAniSirGlobal, tANI_U16, tANI_U8); + +extern void pmmGenerateTIM(tpAniSirGlobal, tANI_U8 **, tANI_U16 *, tANI_U8); + + +void pmmUpdateTIM(tpAniSirGlobal pMac, tpBeaconGenParams pBeaconGenParams); + +/// Update the PM mode +extern void pmmUpdatePMMode(tpAniSirGlobal pMac, tANI_U16 staId, tANI_U8 pmMode); + +/// Update Power Mode +extern void pmmUpdatePollablePMMode(tpAniSirGlobal, tANI_U16, tANI_U8, tANI_U16); +extern void pmmUpdateNonPollablePMMode(tpAniSirGlobal, tANI_U16, tANI_U8, tANI_U16); + +/** Monitor the STA in PS*/ +void pmmHandleTimBasedDisassociation(tpAniSirGlobal pMac, tpPESession psessionEntry); + +//go into sleep state +void pmmInitBmpsPwrSave(tpAniSirGlobal pMac); +tSirRetStatus pmmSendInitPowerSaveMsg(tpAniSirGlobal pMac,tpPESession); +void pmmInitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus pmmSendChangePowerSaveMsg(tpAniSirGlobal pMac); +tSirRetStatus pmmSendSleepIndicationToHal(tpAniSirGlobal pMac); + +//go into wakeup state +void pmmExitBmpsRequestHandler(tpAniSirGlobal pMac, tpExitBmpsInfo pExitBmpsInfo); +void pmmExitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) ; +void pmmMissedBeaconHandler(tpAniSirGlobal pMac); + +//handlling all UAPSD messages +void pmmEnterUapsdRequestHandler (tpAniSirGlobal pMac); +void pmmEnterUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void pmmExitUapsdRequestHandler (tpAniSirGlobal pMac); +void pmmExitUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode); + +// handling of all idle mode power save messages +void pmmEnterImpsRequestHandler(tpAniSirGlobal pMac); +void pmmEnterImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus); +void pmmExitImpsRequestHandler(tpAniSirGlobal pMac); +void pmmExitImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus); + +// handling WOWLAN messages +void pmmSendWowlAddBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void pmmSendWowlDelBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void pmmEnterWowlRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +tSirRetStatus pmmSendWowlEnterRequest(tpAniSirGlobal pMac, tpSirHalWowlEnterParams pHalWowlParams); +void pmmEnterWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus pmmSendExitWowlReq(tpAniSirGlobal pMac, tpSirHalWowlExitParams pHalWowlParams); +void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac); +void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +// update idle mode statistics +void pmmImpsUpdatePwrSaveStats(tpAniSirGlobal pMac); +void pmmImpsUpdateWakeupStats(tpAniSirGlobal pMac); +tSirRetStatus pmmImpsSendChangePwrSaveMsg(tpAniSirGlobal pMac, tANI_U8 mode); +void pmmImpsUpdateSleepErrStats(tpAniSirGlobal pMac, tSirRetStatus retStatus); +void pmmImpsUpdateWakeupErrStats(tpAniSirGlobal pMac, tSirRetStatus retStatus); +void pmmImpsUpdateErrStateStats(tpAniSirGlobal pMac); +void pmmImpsUpdatePktDropStats(tpAniSirGlobal pMac); + +void pmmUpdatePwrSaveStats(tpAniSirGlobal pMac); +void pmmUpdateWakeupStats(tpAniSirGlobal pMac); +void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac); +void pmmBmpsUpdateHalReqFailureCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateInitFailureCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateInvalidStateCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac); +void pmmBmpsUpdateReqInInvalidRoleCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateSleepReqFailureCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateWakeupIndCnt(tpAniSirGlobal pMac); +void pmmBmpsUpdateWakeupReqFailureCnt(tpAniSirGlobal pMac); +void pmmResetPmmState(tpAniSirGlobal pMac); +void pmmSendMessageToLim(tpAniSirGlobal pMac, tANI_U32 msgId); + +//Power Save CFG +tSirRetStatus pmmSendPowerSaveCfg(tpAniSirGlobal pMac, tpSirPowerSaveCfg pUpdatedPwrSaveCfg); + +//Handle Low RSSI Indication +void pmmLowRssiHandler(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +void pmmFilterMatchCountResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void pmmGTKOffloadGetInfoResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/pmmGlobal.h b/drivers/staging/prima/CORE/MAC/src/pe/include/pmmGlobal.h new file mode 100644 index 000000000000..2fcf02cc6496 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/pmmGlobal.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __PMM_GLOBAL_H__ +#define __PMM_GLOBAL_H__ + +#include "sirApi.h" + +typedef struct sPmmStaState +{ + /// Whether this STA is in powersave or not + tANI_U8 powerSave : 1; + /// Whether this STA is CF-pollable or not + tANI_U8 cfPollable : 1; + /// counter to indicate PS state update due to asynchronous PS Poll + tANI_U8 psPollUpdate:2; + + /// Reserved + tANI_U8 rsvd : 4; + + /// Index of the next STA in PS closest to this one + tANI_U8 nextPS; +} tPmmStaState, *tpPmmStaState; + + +#define NO_STATE_CHANGE 0xFF + +typedef enum ePmmState +{ + ePMM_STATE_INVALID, + ePMM_STATE_READY, + //BMPS + ePMM_STATE_BMPS_WT_INIT_RSP, + ePMM_STATE_BMPS_WT_SLEEP_RSP, + ePMM_STATE_BMPS_SLEEP, + ePMM_STATE_BMPS_WT_WAKEUP_RSP, + ePMM_STATE_BMPS_WAKEUP, + //IMPS + ePMM_STATE_IMPS_WT_SLEEP_RSP, + ePMM_STATE_IMPS_SLEEP, + ePMM_STATE_IMPS_WT_WAKEUP_RSP, + ePMM_STATE_IMPS_WAKEUP, + //UAPSD + ePMM_STATE_UAPSD_WT_SLEEP_RSP, + ePMM_STATE_UAPSD_SLEEP, + ePMM_STATE_UAPSD_WT_WAKEUP_RSP, + + //WOWLAN + ePMM_STATE_WOWLAN, + + ePMM_STATE_ERROR, + ePMM_STATE_LAST, +}tPmmState; + +typedef struct sPmmStaInfo +{ + tANI_U16 assocId; + tANI_U32 staTxAckCnt; +}tPmmStaInfo, *tpPmmStaInfo; + +typedef struct sPmmTim +{ + tANI_U8 *pTim; /** Tim Bit Array*/ + tANI_U8 minAssocId; + tANI_U8 maxAssocId; + tANI_U8 dtimCount; + /** Remaining Members are needed for LinkMonitaring of the STA in PS*/ + tANI_U8 numStaWithData; /** Number of stations in power save, who have data pending*/ + tpPmmStaInfo pStaInfo; /** Points to 1st Instant of the Array of MaxSTA StaInfo */ +} tPmmTim, *tpPmmTim; + +typedef struct sAniSirPmm +{ + + + //tANI_U32 disModeBeforeSleeping; + //tANI_U32 txMCastCtrl; + //tANI_U32 nListenBeforeSleeping; + //tANI_U32 txTrafficIdleThreshold; + //tANI_U32 rxTrafficIdleThreshold; + //tANI_U32 ledInfoBeforeSleeping; + + + tANI_U64 BmpsmaxSleepTime; + tANI_U64 BmpsavgSleepTime; + tANI_U64 BmpsminSleepTime; + tANI_U64 BmpscntSleep; + + tANI_U64 BmpsmaxTimeAwake; + tANI_U64 BmpsavgTimeAwake; + tANI_U64 BmpsminTimeAwake; + tANI_U64 BmpscntAwake; + + tANI_U64 BmpsWakeupTimeStamp; + tANI_U64 BmpsSleepTimeStamp; + + // debug statistics + tANI_U64 BmpsPktDrpInSleepMode; + tANI_U64 BmpsInitFailCnt; + tANI_U64 BmpsSleeReqFailCnt; + tANI_U64 BmpsWakeupReqFailCnt; + tANI_U64 BmpsInvStateCnt; + tANI_U64 BmpsWakeupIndCnt; + tANI_U64 BmpsHalReqFailCnt; + tANI_U64 BmpsReqInInvalidRoleCnt; + + /* Add wakeup and sleep time stamps here */ + tANI_U64 ImpsWakeupTimeStamp; + tANI_U64 ImpsSleepTimeStamp; + + tANI_U64 ImpsMaxTimeAwake; + tANI_U64 ImpsMinTimeAwake; + tANI_U64 ImpsAvgTimeAwake; + tANI_U64 ImpsCntAwake; + + tANI_U64 ImpsCntSleep; + tANI_U64 ImpsMaxSleepTime; + tANI_U64 ImpsMinSleepTime; + tANI_U64 ImpsAvgSleepTime; + + tANI_U64 ImpsSleepErrCnt; + tANI_U64 ImpsWakeupErrCnt; + tANI_U64 ImpsLastErr; + + tANI_U64 ImpsInvalidStateCnt; + tANI_U64 ImpsPktDrpInSleepMode; + + + /// Next STA to be serviced in PS state + tANI_U16 gPmmNextSta; + + /// Next CF-pollable STA to be serviced in PS state + tANI_U16 gPmmNextCFPSta; + + /// Number of STAs in PS state + tANI_U16 gPmmNumSta; + + tANI_U8 gPmmPsPollUpdate:1; // set when any sta state is update due to PS-Poll + tANI_U8 rsvd: 7; + + /// STA Power management state array + /** + * An entry in this array records the power save state for an STA + * It also points to the next closest STA in power save state. + */ + + tANI_U32 gPmmBeaconInterval; //pmm keeps its won copy of beacon interval, default to 100ms + tSirPowerSaveCfg gPmmCfg; //pmm keeps a copy of Power Save config parameters sent to softmac. + /// Current PM state of the station + tPmmState gPmmState; + /// Flag to track if we are in a missed beacon scenario + tANI_U8 inMissedBeaconScenario; + + tPmmTim gPmmTim; + + + //Reason for which PMC is sending an EXIT_BMPS_REQ to PE + tExitBmpsReason gPmmExitBmpsReasonCode; + tANI_U8 sessionId; //This sessio Id is added to know the bsstype , infra/btamp .......in power save mode + +} tAniSirPmm, *tpAniSirPmm; + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/rrmApi.h b/drivers/staging/prima/CORE/MAC/src/pe/include/rrmApi.h new file mode 100644 index 000000000000..3786a923ce1f --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/rrmApi.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/**========================================================================= + + \file rrmApi.h + + \brief RRM APIs + + ========================================================================*/ + +/* $Header$ */ + +#ifndef __RRM_API_H__ +#define __RRM_API_H__ + +#define RRM_MIN_TX_PWR_CAP 13 +#define RRM_MAX_TX_PWR_CAP 19 + +#define RRM_BCN_RPT_NO_BSS_INFO 0 +#define RRM_BCN_RPT_MIN_RPT 1 + +tANI_U8 rrmGetMinOfMaxTxPower(tpAniSirGlobal pMac, tPowerdBm regMax, tPowerdBm apTxPower); + +extern tSirRetStatus rrmInitialize(tpAniSirGlobal pMac); + +extern tSirRetStatus rrmCleanup(tpAniSirGlobal pMac); + + +extern tSirRetStatus rrmProcessLinkMeasurementRequest( tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo, + tDot11fLinkMeasurementRequest *pLinkReq, + tpPESession pSessionEntry ); + +extern tSirRetStatus rrmProcessRadioMeasurementRequest( tpAniSirGlobal pMac, + tSirMacAddr peer, + tDot11fRadioMeasurementRequest *pRRMReq, + tpPESession pSessionEntry ); + +extern tSirRetStatus rrmProcessNeighborReportResponse( tpAniSirGlobal pMac, + tDot11fNeighborReportResponse *pNeighborRep, + tpPESession pSessionEntry ); + +extern void rrmProcessMessage(tpAniSirGlobal pMac, + tpSirMsgQ pMsg); + +extern tSirRetStatus rrmSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, + tPowerdBm txPower, + tpPESession pSessionEntry ); + +extern tPowerdBm rrmGetMgmtTxPower ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ); + +extern void rrmCacheMgmtTxPower ( tpAniSirGlobal pMac, + tPowerdBm txPower, + tpPESession pSessionEntry ); + +extern tpRRMCaps rrmGetCapabilities ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ); + +extern void rrmUpdateConfig ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ); + +extern void rrmGetStartTSF ( tpAniSirGlobal pMac, + tANI_U32 *pStartTSF ); + +extern void rrmUpdateStartTSF ( tpAniSirGlobal pMac, + tANI_U32 startTSF[2] ); + +extern tSirRetStatus rrmSetMaxTxPowerRsp ( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ); + +extern tSirRetStatus +rrmProcessNeighborReportReq( tpAniSirGlobal pMac, + tpSirNeighborReportReqInd pNeighborReq ); +extern tSirRetStatus +rrmProcessBeaconReportXmit( tpAniSirGlobal pMac, + tpSirBeaconReportXmitInd pBcnReport); +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/rrmGlobal.h b/drivers/staging/prima/CORE/MAC/src/pe/include/rrmGlobal.h new file mode 100644 index 000000000000..ab2b30d30a7e --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/rrmGlobal.h @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2011-2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + +#if !defined( __RRMGLOBAL_H ) +#define __RRMGLOBAL_H + +/**========================================================================= + + \file rrmGlobal.h + + \brief Definitions for SME APIs + + + ========================================================================*/ + +typedef enum eRrmRetStatus +{ + eRRM_SUCCESS, + eRRM_INCAPABLE, + eRRM_REFUSED, + eRRM_FAILURE +} tRrmRetStatus; + +typedef enum eRrmMsgReqSource +{ + eRRM_MSG_SOURCE_LEGACY_ESE = 1, /* legacy ese */ + eRRM_MSG_SOURCE_11K = 2, /* 11k */ + eRRM_MSG_SOURCE_ESE_UPLOAD = 3 /* ese upload approach */ +} tRrmMsgReqSource; + +typedef struct sSirChannelInfo +{ + tANI_U8 regulatoryClass; + tANI_U8 channelNum; +} tSirChannelInfo, * tpSirChannelInfo; + +typedef struct sSirBeaconReportReqInd +{ + tANI_U16 messageType; // eWNI_SME_BEACON_REPORT_REQ_IND + tANI_U16 length; + tSirMacAddr bssId; + tANI_U16 measurementDuration[SIR_ESE_MAX_MEAS_IE_REQS]; //ms + tANI_U16 randomizationInterval; //ms + tSirChannelInfo channelInfo; + tSirMacAddr macaddrBssid; //0: wildcard + tANI_U8 fMeasurementtype[SIR_ESE_MAX_MEAS_IE_REQS]; //0:Passive, 1: Active, 2: table mode + tAniSSID ssId; //May be wilcard. + tANI_U16 uDialogToken; + tSirChannelList channelList; //From AP channel report. + tRrmMsgReqSource msgSource; +} tSirBeaconReportReqInd, * tpSirBeaconReportReqInd; + + +typedef struct sSirBeaconReportXmitInd +{ + tANI_U16 messageType; // eWNI_SME_BEACON_REPORT_RESP_XMIT_IND + tANI_U16 length; + tSirMacAddr bssId; + tANI_U16 uDialogToken; + tANI_U8 fMeasureDone; + tANI_U16 duration; + tANI_U8 regClass; + tANI_U8 numBssDesc; + tpSirBssDescription pBssDescription[SIR_BCN_REPORT_MAX_BSS_DESC]; +} tSirBeaconReportXmitInd, * tpSirBeaconReportXmitInd; + +typedef struct sSirNeighborReportReqInd +{ + tANI_U16 messageType; // eWNI_SME_NEIGHBOR_REPORT_REQ_IND + tANI_U16 length; + tSirMacAddr bssId; //For the session. + tANI_U16 noSSID; //TRUE - dont include SSID in the request. + //FALSE include the SSID. It may be null (wildcard) + tSirMacSSid ucSSID; +} tSirNeighborReportReqInd, * tpSirNeighborReportReqInd; + + +typedef struct sSirNeighborBssDescription +{ + tANI_U16 length; + tSirMacAddr bssId; + tANI_U8 regClass; + tANI_U8 channel; + tANI_U8 phyType; + union sSirNeighborBssidInfo { + struct _rrmInfo { + tANI_U32 fApPreauthReachable:2; //see IEEE 802.11k Table 7-43a + tANI_U32 fSameSecurityMode:1; + tANI_U32 fSameAuthenticator:1; + tANI_U32 fCapSpectrumMeasurement:1; //see IEEE 802.11k Table 7-95d + tANI_U32 fCapQos:1; + tANI_U32 fCapApsd:1; + tANI_U32 fCapRadioMeasurement:1; + tANI_U32 fCapDelayedBlockAck:1; + tANI_U32 fCapImmediateBlockAck:1; + tANI_U32 fMobilityDomain:1; + tANI_U32 reserved:21; + } rrmInfo; + struct _eseInfo { + tANI_U32 channelBand:8; + tANI_U32 minRecvSigPower:8; + tANI_U32 apTxPower:8; + tANI_U32 roamHysteresis:8; + tANI_U32 adaptScanThres:8; + + tANI_U32 transitionTime:8; + tANI_U32 tsfOffset:16; + + tANI_U32 beaconInterval:16; + tANI_U32 reserved: 16; + } eseInfo; + } bssidInfo; + + //Optional sub IEs....ignoring for now. +}tSirNeighborBssDescription, *tpSirNeighborBssDescripton; + +typedef struct sSirNeighborReportInd +{ + tANI_U16 messageType; // eWNI_SME_NEIGHBOR_REPORT_IND + tANI_U16 length; + tANI_U16 numNeighborReports; + tSirMacAddr bssId; //For the session. + //tSirResultCodes statusCode; + tSirNeighborBssDescription sNeighborBssDescription[1]; +} tSirNeighborReportInd, * tpSirNeighborReportInd; + +typedef struct sRRMBeaconReportRequestedIes +{ + tANI_U8 num; + tANI_U8 *pElementIds; +}tRRMBeaconReportRequestedIes, *tpRRMBeaconReportRequestedIes; + +//Reporting detail defines. +//Reference - IEEE Std 802.11k-2008 section 7.3.2.21.6 Table 7-29h +#define BEACON_REPORTING_DETAIL_NO_FF_IE 0 +#define BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE 1 +#define BEACON_REPORTING_DETAIL_ALL_FF_IE 2 + + +typedef struct sRRMReq +{ + tANI_U8 dialog_token; //In action frame; + tANI_U8 token; //Within individual request; + tANI_U8 type; + union { + struct { + tANI_U8 reportingDetail; + tRRMBeaconReportRequestedIes reqIes; + }Beacon; + }request; + tANI_U8 sendEmptyBcnRpt; +}tRRMReq, *tpRRMReq; + +typedef struct sRRMCaps +{ + tANI_U8 LinkMeasurement: 1; + tANI_U8 NeighborRpt: 1; + tANI_U8 parallel: 1; + tANI_U8 repeated: 1; + tANI_U8 BeaconPassive: 1; + tANI_U8 BeaconActive: 1; + tANI_U8 BeaconTable: 1; + tANI_U8 BeaconRepCond: 1; + tANI_U8 FrameMeasurement: 1; + tANI_U8 ChannelLoad: 1; + tANI_U8 NoiseHistogram: 1; + tANI_U8 statistics: 1; + tANI_U8 LCIMeasurement: 1; + tANI_U8 LCIAzimuth: 1; + tANI_U8 TCMCapability: 1; + tANI_U8 triggeredTCM: 1; + tANI_U8 APChanReport: 1; + tANI_U8 RRMMIBEnabled: 1; + tANI_U8 MeasurementPilotEnabled: 1; + tANI_U8 NeighborTSFOffset: 1; + tANI_U8 RCPIMeasurement: 1; + tANI_U8 RSNIMeasurement: 1; + tANI_U8 BssAvgAccessDelay: 1; + tANI_U8 BSSAvailAdmission: 1; + tANI_U8 AntennaInformation: 1; + + tANI_U8 operatingChanMax; + tANI_U8 nonOperatingChanMax; + tANI_U8 MeasurementPilot; +}tRRMCaps, *tpRRMCaps; + +typedef struct sRrmPEContext +{ + tANI_U8 rrmEnable; + //tChannelList APchannelReport; + tANI_U32 startTSF[2]; //Used during scan/measurement to store the start TSF. this is not used directly in beacon reports. + //This value is stored into bssdescription and beacon report gets it from bss decsription. + tRRMCaps rrmEnabledCaps; + tPowerdBm txMgmtPower; + tANI_U8 DialogToken; //Dialog token for the request initiated from station. + tpRRMReq pCurrentReq; +}tRrmPEContext, *tpRrmPEContext; + +// 2008 11k spec reference: 18.4.8.5 RCPI Measurement +#define RCPI_LOW_RSSI_VALUE (-110) +#define RCPI_MAX_VALUE (220) +#define CALCULATE_RCPI(rssi) (((rssi) + 110) * 2) + + +#endif //#if defined __RRMGLOBAL_H diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/schApi.h b/drivers/staging/prima/CORE/MAC/src/pe/include/schApi.h new file mode 100644 index 000000000000..da3f0e3c5af3 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/schApi.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_API_H__ +#define __SCH_API_H__ + +#include "sirCommon.h" +#include "sirMacProtDef.h" + +#include "aniGlobal.h" + +/// Send start scan response message +extern void schSendStartScanRsp(tpAniSirGlobal pMac); + +// update only the broadcast qos params +extern void schQosUpdateBroadcast(tpAniSirGlobal pMac, tpPESession psessionEntry); + +// fill in the default local edca parameter into gLimEdcaParams[] +extern void schSetDefaultEdcaParams(tpAniSirGlobal pMac, tpPESession psessionE); + +// update only local qos params +extern void schQosUpdateLocal(tpAniSirGlobal pMac, tpPESession psessionEntry); + +// update the edca profile parameters +extern void schEdcaProfileUpdate(tpAniSirGlobal pMac, tpPESession psessionEntry); + +/// Set the fixed fields in a beacon frame +extern tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry); + +/// Initializations +extern void schInitialize(tpAniSirGlobal pMac); + +/// Initialize globals +extern void schInitGlobals(tpAniSirGlobal pMac); + +/// Initialize CF Poll template +extern void schInitializeCfPollTemplate(tpAniSirGlobal pMac); + +/// Initialize CF End template +extern void schInitializeCfEndTemplate(tpAniSirGlobal pMac); + +/// Process the scheduler messages +extern void schProcessMessage(tpAniSirGlobal pMac,tpSirMsgQ pSchMsg); + +/// The beacon Indication handler function +extern void schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg); + +/// Post a message to the scheduler message queue +extern tSirRetStatus schPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg); + + +extern void schBeaconProcess(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry); +extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry); + + +#define SCH_RR_TIMEOUT (SCH_RR_TIMEOUT_MS / SYS_TICK_DUR_MS) + +void schSetBeaconInterval(tpAniSirGlobal pMac,tpPESession psessionEntry); + +tSirRetStatus schSendBeaconReq( tpAniSirGlobal, tANI_U8 *, tANI_U16, tpPESession psessionEntry ); + +tSirRetStatus limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal, + tDot11fBeacon1*, tpPESession psessionEntry); +void limUpdateProbeRspTemplateIeBitmapBeacon2(tpAniSirGlobal,tDot11fBeacon2*,tANI_U32*,tDot11fProbeResponse*); +void SetProbeRspIeBitmap(tANI_U32*,tANI_U32); +tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal,tpPESession, + tANI_U32*); + + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/schGlobal.h b/drivers/staging/prima/CORE/MAC/src/pe/include/schGlobal.h new file mode 100644 index 000000000000..7bfcede922c0 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/schGlobal.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_GLOBAL_H__ +#define __SCH_GLOBAL_H__ + +#include "sirMacPropExts.h" +#include "limGlobal.h" + +#include "parserApi.h" + + +#define ANI_SCH_ADAPTIVE_THRESHOLD_TH_CD 0x00000001 +#define ANI_SCH_ADAPTIVE_THRESHOLD_TH_D0 0x00000002 + +#define ANI_SCH_ADAPTIVE_THRESHOLD_ALL (ANI_SCH_ADAPTIVE_THRESHOLD_TH_CD | ANI_SCH_ADAPTIVE_THRESHOLD_TH_D0) + +#define ANI_SCH_ADAPTIVE_ALGO_BAND_2GHZ 0x00000001 +#define ANI_SCH_ADAPTIVE_ALGO_BAND_5GHZ 0x00000002 + +#define ANI_SCH_ADAPTIVE_ALGO_BAND_ALL (ANI_SCH_ADAPTIVE_ALGO_BAND_2GHZ | ANI_SCH_ADAPTIVE_ALGO_BAND_5GHZ) + + +// Diagnostic bitmap defines + +#define SCH_DIAG_RR_TIMEOUT_DELETE 0x1 +#define SCH_DIAG_RR_LOWER_RATE 0x2 + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define TIM_IE_SIZE 0xB +#else +#define TIM_IE_SIZE 0x7 +#endif + +// ----------------------- Beacon processing ------------------------ + +/// Beacon structure +#define tSchBeaconStruct tSirProbeRespBeacon +#define tpSchBeaconStruct struct sSirProbeRespBeacon * + +// ------------------------------------------------------------------- + +//****************** MISC defs ********************************* + +/// Maximum allowable size of a beacon frame +#define SCH_MAX_BEACON_SIZE 512 + +#define SCH_MAX_PROBE_RESP_SIZE 512 + +struct schMisc { + + tANI_U8 *gSchProbeRspTemplate; + + /// Beginning portion of the beacon frame to be written to TFP + tANI_U8 *gSchBeaconFrameBegin; + + /// Trailing portion of the beacon frame to be written to TFP + tANI_U8 *gSchBeaconFrameEnd; + + /// Size of the beginning portion + tANI_U16 gSchBeaconOffsetBegin; + /// Size of the trailing portion + tANI_U16 gSchBeaconOffsetEnd; + + tANI_U16 gSchBeaconInterval; + + /// Current CFP count + tANI_U8 gSchCFPCount; + + /// CFP Duration remaining + tANI_U8 gSchCFPDurRemaining; + + /// CFP Maximum Duration + tANI_U8 gSchCFPMaxDuration; + + /// Current DTIM count + tANI_U8 gSchDTIMCount; + + /// Whether we have initiated a CFP or not + tANI_U8 gSchCFPInitiated; + + /// Whether we have initiated a CFB or not + tANI_U8 gSchCFBInitiated; + + /// CFP is enabled and AP is configured as HCF + tANI_U8 gSchCFPEnabled; + + /// CFB is enabled and AP is configured as HCF + tANI_U8 gSchCFBEnabled; + + // --------- STA ONLY state ----------- + + /// Indicates whether RR timer is running or not + tANI_U8 rrTimer[8]; + + /// Indicates the remaining RR timeout value if the RR timer is running + tANI_U16 rrTimeout[8]; + + /// Number of RRs transmitted + tANI_U16 numRR[8]; + tANI_U16 numRRtimeouts[8]; + + /// flag to indicate that beacon template has been updated + tANI_U8 fBeaconChanged; + + tANI_U16 p2pIeOffset; + +}; + +//****************** MISC defs ********************************* + +typedef struct schStaWaitList +{ + tANI_U16 staId; + tANI_U16 count; +} tStaWaitList, *tpStaWaitList; + + +/// Global SCH structure +typedef struct sAniSirSch +{ + /// The scheduler object + struct schMisc schObject; + + // schQoSClass unsolicited; + + /// Whether HCF is enabled or not + tANI_U8 gSchHcfEnabled; + + /// Whether scan is requested by LIM or not + tANI_U8 gSchScanRequested; + + /// Whether scan request is received by SCH or not + tANI_U8 gSchScanReqRcvd; + + + /// Debug flag to disable beacon generation + tANI_U32 gSchGenBeacon; + +#define SCH_MAX_ARR 100 + tANI_U32 gSchBeaconsWritten; + tANI_U32 gSchBeaconsSent; + tANI_U32 gSchBBXportRcvCnt; + tANI_U32 gSchRRRcvCnt, qosNullCnt; + tANI_U32 gSchBcnRcvCnt; + tANI_U32 gSchUnknownRcvCnt; + + tANI_U32 gSchBcnParseErrorCnt; + tANI_U32 gSchBcnIgnored; + + // tTmpInstBuffer TIB; + // tANI_U16 gSchQuantum[8]; + + tANI_U32 numPoll, numData, numCorrupt; + tANI_U32 numBogusInt, numTxAct0; + +#define SCH_MAX_NUM_SCH 21 + // tANI_U32 numSchHist[SCH_MAX_NUM_SCH]; + // tANI_U32 defaultTxop; + + tANI_U32 lastBeaconLength; + tANI_U16 rrTimeout; + tANI_U32 pollPeriod; + tANI_U32 keepAlive; + tANI_U32 multipleSched; + tANI_U32 pollFeedbackHist[8]; + tANI_U32 dataFeedbackHist[8]; + tANI_U32 maxPollTimeouts; + tANI_U32 checkCfbFlagStuck; + + /// Sta Wait list + tpStaWaitList pStaWaitList; + + /// Pointer to next available entry in sta wait list + tANI_U16 staWaitListIn; + /// Pointer to first waiting sta in sta wait list + tANI_U16 staWaitListOut; + /// Total number of waiting STAs in sta wait list + tANI_U16 staWaitListCount; + /// Total number of schedules to be waited + tANI_U16 staWaitListTotalWait; + + /// Number of entries in DPH activity queue that were ignored + tANI_U32 ignoreDph; + +} tAniSirSch, *tpAniSirSch; + + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/include/wmmApsd.h b/drivers/staging/prima/CORE/MAC/src/pe/include/wmmApsd.h new file mode 100644 index 000000000000..ea41ded7fc5d --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/include/wmmApsd.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WMMAPSD_H__ +#define __WMMAPSD_H__ + +#include "aniGlobal.h" + +// WMM Info Element OUI subtypes +#define WMM_APSD_INFO_ELEMENT 0 +#define WMM_APSD_PARAM_ELEMENT 1 + +// Length of IEs (Including the EID byte). +#define WMM_INFO_ELEMENT_LENGTH_TOTAL 8 +#define WMM_PARAM_ELEMENT_LENGTH_TOTAL 25 + +// IE lenght. +#define WMM_INFO_ELEMENT_LENGTH 7 +#define WMM_PARAM_ELEMENT_LENGTH 24 + + +// UAPSD Flag for each AC (WMM spec 2.2.1) +#define LIM_UAPSD_BITOFFSET_ACVO 0 +#define LIM_UAPSD_BITOFFSET_ACVI 1 +#define LIM_UAPSD_BITOFFSET_ACBK 2 +#define LIM_UAPSD_BITOFFSET_ACBE 3 + +#define LIM_UAPSD_FLAG_ACVO (1 << LIM_UAPSD_BITOFFSET_ACVO) +#define LIM_UAPSD_FLAG_ACVI (1 << LIM_UAPSD_BITOFFSET_ACVI) +#define LIM_UAPSD_FLAG_ACBK (1 << LIM_UAPSD_BITOFFSET_ACBK) +#define LIM_UAPSD_FLAG_ACBE (1 << LIM_UAPSD_BITOFFSET_ACBE) + +#define LIM_UAPSD_GET(ac, mask) (((mask) & (LIM_UAPSD_FLAG_ ## ac)) >> LIM_UAPSD_BITOFFSET_ ## ac) + +// Definitions for AC mode. +#define AC_DELIVERY_ENABLED 0x1 +#define AC_TRIGGER_ENABLED 0x2 +#define ALL_AC_UAPSD_SET 0x0F + +// Definition for setting/clearing Uapsd Mask +#define SET_UAPSD_MASK 1 +#define CLEAR_UAPSD_MASK 0 + +#define ac2tcId(ac) (ac << 1) + +// Function prototypes. +extern void apsdSendQosNull(tpAniSirGlobal pMac, tANI_U16 staId, tANI_U8 tcId, tANI_U8 *staAddr); + + +#endif /* __WMMAPSD_H__ */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAIDmgmt.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAIDmgmt.c new file mode 100644 index 000000000000..f90598aff439 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAIDmgmt.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limAIDmgmt.cc contains the functions related to + * AID pool management like initialization, assignment etc. + * Author: Chandra Modumudi + * Date: 03/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "palTypes.h" +#include "wniCfg.h" +#include "aniGlobal.h" +#include "cfgApi.h" +#include "sirParams.h" +#include "limUtils.h" +#include "limTimerUtils.h" +#include "limSession.h" +#include "limSessionUtils.h" + +#define LIM_START_PEER_IDX 1 + +/** + * limInitPeerIdxpool() + * + *FUNCTION: + * This function is called while starting a BSS at AP + * to initialize AID pool. This may also be called while + * starting/joining an IBSS if 'Association' is allowed + * in IBSS. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitPeerIdxpool(tpAniSirGlobal pMac,tpPESession pSessionEntry) +{ + tANI_U8 i; + tANI_U8 maxAssocSta = pMac->lim.gLimAssocStaLimit; + + pSessionEntry->gpLimPeerIdxpool[0]=0; + +#ifdef FEATURE_WLAN_TDLS + //In station role, DPH_STA_HASH_INDEX_PEER (index 1) is reserved for peer + //station index corresponding to AP. Avoid choosing that index and get index + //starting from (DPH_STA_HASH_INDEX_PEER + 1) (index 2) for TDLS stations; + if (pSessionEntry->limSystemRole == eLIM_STA_ROLE ) + { + pSessionEntry->freePeerIdxHead = DPH_STA_HASH_INDEX_PEER + 1; + } + else +#endif + { + pSessionEntry->freePeerIdxHead=LIM_START_PEER_IDX; + } + + for (i=pSessionEntry->freePeerIdxHead;igpLimPeerIdxpool[i] = i+1; + } + pSessionEntry->gpLimPeerIdxpool[i] = 0; + + pSessionEntry->freePeerIdxTail=i; + +} + + +/** + * limAssignPeerIdx() + * + *FUNCTION: + * This function is called to get a peer station index. This index is + * used during Association/Reassociation + * frame handling to assign association ID (aid) to a STA. + * In case of TDLS, this is used to assign a index into the Dph hash entry. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return peerIdx - assigned peer Station IDx for STA + */ + +tANI_U16 +limAssignPeerIdx(tpAniSirGlobal pMac, tpPESession pSessionEntry) +{ + tANI_U16 peerId; + + // make sure we haven't exceeded the configurable limit on associations + // This count is global to ensure that it doesnt exceed the hardware limits. + if (peGetCurrentSTAsCount(pMac) >= pMac->lim.gLimAssocStaLimit) + { + // too many associations already active + return 0; + } + + /* return head of free list */ + + if (pSessionEntry->freePeerIdxHead) + { + peerId=pSessionEntry->freePeerIdxHead; + pSessionEntry->freePeerIdxHead = pSessionEntry->gpLimPeerIdxpool[pSessionEntry->freePeerIdxHead]; + if (pSessionEntry->freePeerIdxHead==0) + pSessionEntry->freePeerIdxTail=0; + pSessionEntry->gLimNumOfCurrentSTAs++; + //PELOG2(limLog(pMac, LOG2,FL("Assign aid %d, numSta %d, head %d tail %d "),aid,pSessionEntry->gLimNumOfCurrentSTAs,pSessionEntry->freeAidHead,pSessionEntry->freeAidTail);) + return peerId; + } + + return 0; /* no more free peer index */ +} + + +/** + * limReleasePeerIdx() + * + *FUNCTION: + * This function is called when a STA context is removed + * at AP (or at a STA in IBSS mode or TDLS) to return peer Index + * to free pool. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param peerIdx - peer station index that need to return to free pool + * + * @return None + */ + +void +limReleasePeerIdx(tpAniSirGlobal pMac, tANI_U16 peerIdx, tpPESession pSessionEntry) +{ + pSessionEntry->gLimNumOfCurrentSTAs--; + + /* insert at tail of free list */ + if (pSessionEntry->freePeerIdxTail) + { + pSessionEntry->gpLimPeerIdxpool[pSessionEntry->freePeerIdxTail]=(tANI_U8)peerIdx; + pSessionEntry->freePeerIdxTail=(tANI_U8)peerIdx; + } + else + { + pSessionEntry->freePeerIdxTail=pSessionEntry->freePeerIdxHead=(tANI_U8)peerIdx; + } + pSessionEntry->gpLimPeerIdxpool[(tANI_U8)peerIdx]=0; + //PELOG2(limLog(pMac, LOG2,FL("Release aid %d, numSta %d, head %d tail %d "),aid,pMac->lim.gLimNumOfCurrentSTAs,pMac->lim.freeAidHead,pMac->lim.freeAidTail);) + +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAdmitControl.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAdmitControl.c new file mode 100644 index 000000000000..9f3cb9dd4540 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAdmitControl.c @@ -0,0 +1,1265 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file contains TSPEC and STA admit control related functions + * NOTE: applies only to AP builds + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "limDebug.h" +#include "sysDef.h" +#include "limApi.h" +#include "cfgApi.h" // wlan_cfgGetInt() +#include "limTrace.h" +#include "limSendSmeRspMessages.h" +#include "limTypes.h" + + +#define ADMIT_CONTROL_LOGLEVEL LOG1 +#define ADMIT_CONTROL_POLICY_LOGLEVEL LOG1 +#define ADMIT_CONTROL_MIN_INTERVAL 1000 // min acceptable service interval 1mSec + +/* total available bandwidth in bps in each phy mode + * these should be defined in hal or dph - replace these later + */ +#define LIM_TOTAL_BW_11A 54000000 +#define LIM_MIN_BW_11A 6000000 +#define LIM_TOTAL_BW_11B 11000000 +#define LIM_MIN_BW_11B 1000000 +#define LIM_TOTAL_BW_11G LIM_TOTAL_BW_11A +#define LIM_MIN_BW_11G LIM_MIN_BW_11B + +// conversion factors +#define LIM_CONVERT_SIZE_BITS(numBytes) ((numBytes) * 8) +#define LIM_CONVERT_RATE_MBPS(rate) ((rate)/1000000) + +/* ANI sta's support enhanced rates, so the effective medium time used is + * half that of other stations. This is the same as if they were requesting + * half the badnwidth - so we adjust ANI sta's accordingly for bandwidth + * calculations. Also enhanced rates apply only in case of non 11B mode. + */ +#define LIM_STA_BW_ADJUST(aniPeer, phyMode, bw) \ + (((aniPeer) && ((phyMode) != WNI_CFG_PHY_MODE_11B)) \ + ? ((bw)/2) : (bw)) + + +//------------------------------------------------------------------------------ +// local protos + +static tSirRetStatus +limCalculateSvcInt(tpAniSirGlobal, tSirMacTspecIE *, tANI_U32 *); +#if 0 //only EDCA is supported now +static tSirRetStatus +limValidateTspecHcca(tpAniSirGlobal, tSirMacTspecIE *); +#endif +static tSirRetStatus +limValidateTspecEdca(tpAniSirGlobal, tSirMacTspecIE *, tpPESession); +static tSirRetStatus +limValidateTspec(tpAniSirGlobal, tSirMacTspecIE *, tpPESession); +static void +limComputeMeanBwUsed(tpAniSirGlobal, tANI_U32 *, tANI_U32, tpLimTspecInfo, tpPESession); +static void +limGetAvailableBw(tpAniSirGlobal, tANI_U32 *, tANI_U32 *, tANI_U32, tANI_U32); +static tSirRetStatus +limAdmitPolicyOversubscription(tpAniSirGlobal, tSirMacTspecIE *, tpLimAdmitPolicyInfo, tpLimTspecInfo, tpPESession); +static tSirRetStatus +limTspecFindByStaAddr(tpAniSirGlobal, tANI_U8 *, tSirMacTspecIE*, tpLimTspecInfo, tpLimTspecInfo *); +static tSirRetStatus +limValidateAccessPolicy(tpAniSirGlobal, tANI_U8, tANI_U16, tpPESession); + + +/** ------------------------------------------------------------- +\fn limCalculateSvcInt +\brief TSPEC validation and servcie interval determination +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\param tANI_U32 *pSvcInt +\return eSirRetStatus - status of the comparison + -------------------------------------------------------------*/ + +static tSirRetStatus +limCalculateSvcInt( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tANI_U32 *pSvcInt) +{ + tANI_U32 msduSz, dataRate; + *pSvcInt = 0; + + // if a service interval is already specified, we are done + if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0)) + { + *pSvcInt = (pTspec->maxSvcInterval != 0) + ? pTspec->maxSvcInterval : pTspec->minSvcInterval; + return eSIR_SUCCESS; + } + + /* Masking off the fixed bits according to definition of MSDU size + * in IEEE 802.11-2007 spec (section 7.3.2.30). Nominal MSDU size + * is defined as: Bit[0:14]=Size, Bit[15]=Fixed + */ + if (pTspec->nomMsduSz != 0) + msduSz = (pTspec->nomMsduSz & 0x7fff); + else if (pTspec->maxMsduSz != 0) + msduSz = pTspec->maxMsduSz; + else + { + PELOGE(limLog(pMac, LOGE, FL("MsduSize not specified"));) + return eSIR_FAILURE; + } + + /* need to calculate a reasonable service interval + * this is simply the msduSz/meanDataRate + */ + if (pTspec->meanDataRate != 0) dataRate = pTspec->meanDataRate; + else if (pTspec->peakDataRate != 0) dataRate = pTspec->peakDataRate; + else if (pTspec->minDataRate != 0) dataRate = pTspec->minDataRate; + else + { + PELOGE(limLog(pMac, LOGE, FL("DataRate not specified"));) + return eSIR_FAILURE; + } + + *pSvcInt = LIM_CONVERT_SIZE_BITS(msduSz) / LIM_CONVERT_RATE_MBPS(dataRate); + return eSIR_FAILURE; +} + +#if 0 //only EDCA is supported now +/** ------------------------------------------------------------- +\fn limValidateTspecHcca +\brief validate the parameters in the hcca tspec + mandatory fields are derived from 11e Annex I (Table I.1) +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ +static tSirRetStatus +limValidateTspecHcca( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec) +{ + tANI_U32 maxPhyRate, minPhyRate; + tANI_U32 phyMode; + + tSirRetStatus retval = eSIR_SUCCESS; + /* make sure a TSID is being requested */ + if (pTspec->tsinfo.traffic.tsid < SIR_MAC_HCCA_TSID_MIN) + { + limLog(pMac, LOGW, FL("tsid %d must be >%d)"), + pTspec->tsinfo.traffic.tsid, SIR_MAC_HCCA_TSID_MIN); + retval = eSIR_FAILURE; + } + /* + * With Polaris, there is a limitation in that the tsid cannot be arbitary + * but is based on the qid. Thus, we cannot have a tspec which requests + * a tsid of 13 and userPrio of 7, the bottom three bits of the tsid must + * correspond to the userPrio + */ + if (pTspec->tsinfo.traffic.userPrio != + (pTspec->tsinfo.traffic.tsid - SIR_MAC_HCCA_TSID_MIN)) + { + limLog(pMac, LOGE, FL("TSid=0x%x, userPrio=%d: is not allowed"), + pTspec->tsinfo.traffic.tsid, pTspec->tsinfo.traffic.userPrio); + retval = eSIR_FAILURE; + } + // an inactivity interval is mandatory + if (pTspec->inactInterval == 0) + { + PELOGW(limLog(pMac, LOGW, FL("inactInterval unspecified!"));) + retval = eSIR_FAILURE; + } + // surplus BW must be specified if a delay Bound is specified + if ((pTspec->delayBound != 0) && (pTspec->surplusBw == 0)) + { + limLog(pMac, LOGW, FL("delayBound %d, but surplusBw unspecified!"), + pTspec->delayBound); + retval = eSIR_FAILURE; + } + // minPhyRate must always be specified and cannot exceed maximum supported + limGetPhyMode(pMac, &phyMode); + //limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, pMac->dph.gDphPhyMode, + // 1 /* bandwidth mult factor */); + limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode, + 1 /* bandwidth mult factor */); + if ((pTspec->minPhyRate == 0) + || (pTspec->minPhyRate > maxPhyRate) + || (pTspec->minPhyRate < minPhyRate)) + { + limLog(pMac, LOGW, FL("minPhyRate (%d) invalid"), + pTspec->minPhyRate); + retval = eSIR_FAILURE; + } + /* NOTE: we will require all Tspec's to specify a mean data rate (and so + * also the min and peak data rates) + */ + if ((pTspec->minDataRate == 0) || + (pTspec->meanDataRate == 0) || + (pTspec->peakDataRate == 0)) + { + limLog(pMac, LOGW, FL("DataRate must be specified (min %d, mean %d, peak %d)"), + pTspec->minDataRate, pTspec->meanDataRate, pTspec->peakDataRate); + retval = eSIR_FAILURE; + } + + // mean data rate can't be more than the min phy rate + if (pTspec->meanDataRate > pTspec->minPhyRate) + { + limLog(pMac, LOGW, FL("Data rate (%d) is more than Phyrate %d"), + pTspec->meanDataRate, pTspec->minPhyRate); + return eSIR_FAILURE; + } + + /* if the tspec specifies a service interval, we won't accept tspec's + * with service interval less than our allowed minimum, also either both + * min and max must be specified or neither should be specified (in which + * case, HC determines the appropriate service interval + */ + if ((pTspec->minSvcInterval != 0) || (pTspec->maxSvcInterval != 0)) + { + // max < min is ridiculous + if (pTspec->maxSvcInterval < pTspec->minSvcInterval) + { + limLog(pMac, LOGW, FL("maxSvcInt %d > minSvcInterval %d!!"), + pTspec->maxSvcInterval, pTspec->minSvcInterval); + retval = eSIR_FAILURE; + } + if (pTspec->maxSvcInterval < ADMIT_CONTROL_MIN_INTERVAL) + { + limLog(pMac, LOGW, FL("maxSvcInt %d must be >%d"), + pTspec->maxSvcInterval, ADMIT_CONTROL_MIN_INTERVAL); + retval = eSIR_FAILURE; + } + } + else // min and max both unspecified + { + /* no service interval is specified, so make sure the parameters + * needed to determine one are specified in the tspec + * minPhyRate, meanDataRate and nomMsduSz are needed, only nomMsduSz + * must be checked here since the other two are already validated + */ + if (pTspec->nomMsduSz == 0) + { + PELOGW(limLog(pMac, LOGW, FL("No svcInt and no MsduSize specified"));) + retval = eSIR_FAILURE; + } + } + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d"), retval); + return retval; +} + +#endif //only edca is supported now. + +/** ------------------------------------------------------------- +\fn limValidateTspecEdca +\brief validate the parameters in the edca tspec + mandatory fields are derived from 11e Annex I (Table I.1) +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ +static tSirRetStatus +limValidateTspecEdca( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpPESession psessionEntry) +{ + tANI_U32 maxPhyRate, minPhyRate; + tANI_U32 phyMode; + tSirRetStatus retval = eSIR_SUCCESS; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + //limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, pMac->dph.gDphPhyMode, + // 1 /* bandwidth mult factor */); + limGetAvailableBw(pMac, &maxPhyRate, &minPhyRate, phyMode, + 1 /* bandwidth mult factor */); + // mandatory fields are derived from 11e Annex I (Table I.1) + if ((pTspec->nomMsduSz == 0) || + (pTspec->meanDataRate == 0) || + (pTspec->surplusBw == 0) || + (pTspec->minPhyRate == 0) || + (pTspec->minPhyRate > maxPhyRate)) + { + limLog(pMac, LOGW, FL("Invalid EDCA Tspec: NomMsdu %d, meanDataRate %d, surplusBw %d, minPhyRate %d"), + pTspec->nomMsduSz, pTspec->meanDataRate, pTspec->surplusBw, pTspec->minPhyRate); + retval = eSIR_FAILURE; + } + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("return status %d"), retval); + return retval; +} + +/** ------------------------------------------------------------- +\fn limValidateTspec +\brief validate the offered tspec +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static tSirRetStatus +limValidateTspec( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpPESession psessionEntry) +{ + tSirRetStatus retval = eSIR_SUCCESS; + switch (pTspec->tsinfo.traffic.accessPolicy) + { + case SIR_MAC_ACCESSPOLICY_EDCA: + if ((retval = limValidateTspecEdca(pMac, pTspec, psessionEntry)) != eSIR_SUCCESS) + PELOGW(limLog(pMac, LOGW, FL("EDCA tspec invalid"));) + break; + + case SIR_MAC_ACCESSPOLICY_HCCA: +#if 0 //Not supported right now. + if ((retval = limValidateTspecHcca(pMac, pTspec)) != eSIR_SUCCESS) + PELOGW(limLog(pMac, LOGW, FL("HCCA tspec invalid"));) + break; +#endif + case SIR_MAC_ACCESSPOLICY_BOTH: + // TBD: should we support hybrid tspec as well?? for now, just fall through + default: + limLog(pMac, LOGW, FL("AccessType %d not supported"), + pTspec->tsinfo.traffic.accessPolicy); + retval = eSIR_FAILURE; + break; + } + return retval; +} + +//----------------------------------------------------------------------------- +// Admit Control Policy + + +/** ------------------------------------------------------------- +\fn limComputeMeanBwUsed +\brief determime the used/allocated bandwidth +\param tpAniSirGlobal pMac +\param tANI_U32 *pBw +\param tANI_U32 phyMode +\param tpLimTspecInfo pTspecInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static void +limComputeMeanBwUsed( + tpAniSirGlobal pMac, + tANI_U32 *pBw, + tANI_U32 phyMode, + tpLimTspecInfo pTspecInfo, + tpPESession psessionEntry) +{ + tANI_U32 ctspec; + *pBw = 0; + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) + { + if (pTspecInfo->inuse) + { + tpDphHashNode pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + // maybe we should delete the tspec?? + limLog(pMac, LOGE, FL("Tspec %d (assocId %d): dphNode not found"), + ctspec, pTspecInfo->assocId); + continue; + } + //FIXME: need to take care of taurusPeer, titanPeer, 11npeer too. + *pBw += LIM_STA_BW_ADJUST(pSta->aniPeer, phyMode, pTspecInfo->tspec.meanDataRate); + } + } +} + +/** ------------------------------------------------------------- +\fn limGetAvailableBw +\brief based on the phy mode and the bw_factor, determine the total bandwidth that + can be supported +\param tpAniSirGlobal pMac +\param tANI_U32 *pMaxBw +\param tANI_U32 *pMinBw +\param tANI_U32 phyMode +\param tANI_U32 bw_factor +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static void +limGetAvailableBw( + tpAniSirGlobal pMac, + tANI_U32 *pMaxBw, + tANI_U32 *pMinBw, + tANI_U32 phyMode, + tANI_U32 bw_factor) +{ + switch (phyMode) + { + case WNI_CFG_PHY_MODE_11B: + *pMaxBw = LIM_TOTAL_BW_11B; + *pMinBw = LIM_MIN_BW_11B; + break; + + case WNI_CFG_PHY_MODE_11A: + *pMaxBw = LIM_TOTAL_BW_11A; + *pMinBw = LIM_MIN_BW_11A; + break; + + case WNI_CFG_PHY_MODE_11G: + case WNI_CFG_PHY_MODE_NONE: + default: + *pMaxBw = LIM_TOTAL_BW_11G; + *pMinBw = LIM_MIN_BW_11G; + break; + } + *pMaxBw *= bw_factor; +} + +/** ------------------------------------------------------------- +\fn limAdmitPolicyOversubscription +\brief simple admission control policy based on oversubscription + if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then + reject the tspec, else admit it. The phy-bw is the peak available bw in the + current phy mode. The 'factor' is the configured oversubscription factor. +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\param tpLimAdmitPolicyInfo pAdmitPolicy +\param tpLimTspecInfo pTspecInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +/* + * simple admission control policy based on oversubscription + * if the total bandwidth of all admitted tspec's exceeds (factor * phy-bw) then + * reject the tspec, else admit it. The phy-bw is the peak available bw in the + * current phy mode. The 'factor' is the configured oversubscription factor. + */ +static tSirRetStatus +limAdmitPolicyOversubscription( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpLimAdmitPolicyInfo pAdmitPolicy, + tpLimTspecInfo pTspecInfo, + tpPESession psessionEntry) +{ + tANI_U32 totalbw, minbw, usedbw; + tANI_U32 phyMode; + + // determine total bandwidth used so far + limGetPhyMode(pMac, &phyMode, psessionEntry); + + //limComputeMeanBwUsed(pMac, &usedbw, pMac->dph.gDphPhyMode, pTspecInfo); + limComputeMeanBwUsed(pMac, &usedbw, phyMode, pTspecInfo, psessionEntry); + + // determine how much bandwidth is available based on the current phy mode + //limGetAvailableBw(pMac, &totalbw, &minbw, pMac->dph.gDphPhyMode, pAdmitPolicy->bw_factor); + limGetAvailableBw(pMac, &totalbw, &minbw, phyMode, pAdmitPolicy->bw_factor); + + if (usedbw > totalbw) // this can't possibly happen + return eSIR_FAILURE; + + if ((totalbw - usedbw) < pTspec->meanDataRate) + { + limLog(pMac, ADMIT_CONTROL_POLICY_LOGLEVEL, + FL("Total BW %d, Used %d, Tspec request %d not possible"), + totalbw, usedbw, pTspec->meanDataRate); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limAdmitPolicy +\brief determine the current admit control policy and apply it for the offered tspec +\param tpAniSirGlobal pMac +\param tSirMacTspecIE *pTspec +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus limAdmitPolicy( + tpAniSirGlobal pMac, + tSirMacTspecIE *pTspec, + tpPESession psessionEntry) +{ + tSirRetStatus retval = eSIR_FAILURE; + tpLimAdmitPolicyInfo pAdmitPolicy = &pMac->lim.admitPolicyInfo; + + switch (pAdmitPolicy->type) + { + case WNI_CFG_ADMIT_POLICY_ADMIT_ALL: + retval = eSIR_SUCCESS; + break; + + case WNI_CFG_ADMIT_POLICY_BW_FACTOR: + retval = limAdmitPolicyOversubscription(pMac, pTspec, + &pMac->lim.admitPolicyInfo, &pMac->lim.tspecInfo[0], psessionEntry); + if (retval != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("rejected by BWFactor policy"));) + break; + + case WNI_CFG_ADMIT_POLICY_REJECT_ALL: + retval = eSIR_FAILURE; + break; + + default: + retval = eSIR_SUCCESS; + limLog(pMac, LOGE, FL("Admit Policy %d unknown, admitting all traffic"), + pAdmitPolicy->type); + break; + } + return retval; +} + +/** ------------------------------------------------------------- +\fn limTspecDelete +\brief delete the specified tspec +\param tpAniSirGlobal pMac +\param tpLimTspecInfo pInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +//----------------------------------------------------------------------------- +// delete the specified tspec +void limTspecDelete(tpAniSirGlobal pMac, tpLimTspecInfo pInfo) +{ + if (pInfo == NULL) + return; + //pierre + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tspec entry = %d"), pInfo->idx); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("delete tspec %p"), pInfo); + pInfo->inuse = 0; + + // clear the hcca/parameterized queue indicator +#if 0 + if ((pInfo->tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) || + (pInfo->tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)) + queue[pInfo->staid][pInfo->tspec.tsinfo.traffic.userPrio][SCH_UL_QUEUE].ts = 0; +#endif + + return; +} + +/** ------------------------------------------------------------- +\fn limTspecFindByStaAddr +\brief Send halMsg_AddTs to HAL +\param tpAniSirGlobal pMac +\param \param tANI_U8 *pAddr +\param tSirMacTspecIE *pTspecIE +\param tpLimTspecInfo pTspecList +\param tpLimTspecInfo *ppInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +// find the specified tspec in the list +static tSirRetStatus +limTspecFindByStaAddr( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tSirMacTspecIE *pTspecIE, + tpLimTspecInfo pTspecList, + tpLimTspecInfo *ppInfo) +{ + int ctspec; + + *ppInfo = NULL; + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if ((pTspecList->inuse) + && (vos_mem_compare(pAddr, pTspecList->staAddr, sizeof(pTspecList->staAddr))) + && (vos_mem_compare((tANI_U8 *) pTspecIE, (tANI_U8 *) &pTspecList->tspec, + sizeof(tSirMacTspecIE)))) + { + *ppInfo = pTspecList; + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limTspecFindByAssocId +\brief find tspec with matchin staid and Tspec +\param tpAniSirGlobal pMac +\param tANI_U32 staid +\param tSirMacTspecIE *pTspecIE +\param tpLimTspecInfo pTspecList +\param tpLimTspecInfo *ppInfo +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limTspecFindByAssocId( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTspecIE *pTspecIE, + tpLimTspecInfo pTspecList, + tpLimTspecInfo *ppInfo) +{ + int ctspec; + + *ppInfo = NULL; + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d"), assocId); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d"), + pTspecIE->tsinfo.traffic.direction, pTspecIE->tsinfo.traffic.tsid); + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if ((pTspecList->inuse) + && (assocId == pTspecList->assocId) + && (vos_mem_compare((tANI_U8 *)pTspecIE, (tANI_U8 *)&pTspecList->tspec, + sizeof(tSirMacTspecIE)))) + { + *ppInfo = pTspecList; + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limFindTspec +\brief finding a TSPEC entry with assocId, tsinfo.direction and tsinfo.tsid +\param tANI_U16 assocId +\param tpAniSirGlobal pMac +\param tSirMacTSInfo *pTsInfo +\param tpLimTspecInfo pTspecList +\param tpLimTspecInfo *ppInfo +\return eSirRetStatus - status of the comparison + -------------------------------------------------------------*/ + +tSirRetStatus +limFindTspec( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTSInfo *pTsInfo, + tpLimTspecInfo pTspecList, + tpLimTspecInfo *ppInfo) +{ + int ctspec; + + *ppInfo = NULL; + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Trying to find tspec entry for assocId = %d"), assocId); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("pTsInfo->traffic.direction = %d, pTsInfo->traffic.tsid = %d"), + pTsInfo->traffic.direction, pTsInfo->traffic.tsid); + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if ((pTspecList->inuse) + && (assocId == pTspecList->assocId) + && (pTsInfo->traffic.direction == pTspecList->tspec.tsinfo.traffic.direction) + && (pTsInfo->traffic.tsid == pTspecList->tspec.tsinfo.traffic.tsid)) + { + *ppInfo = pTspecList; + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limTspecAdd +\brief add or update the specified tspec to the tspec list +\param tpAniSirGlobal pMac +\param tANI_U8 *pAddr +\param tANI_U16 assocId +\param tSirMacTspecIE *pTspec +\param tANI_U32 interval +\param tpLimTspecInfo *ppInfo + +\return eSirRetStatus - status of the comparison + -------------------------------------------------------------*/ + +tSirRetStatus limTspecAdd( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tANI_U16 assocId, + tSirMacTspecIE *pTspec, + tANI_U32 interval, + tpLimTspecInfo *ppInfo) +{ + tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0]; + *ppInfo = NULL; + + // validate the assocId + if (assocId >= pMac->lim.maxStation) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid assocId 0x%x"), assocId);) + return eSIR_FAILURE; + } + + //decide whether to add/update + { + *ppInfo = NULL; + + if(eSIR_SUCCESS == limFindTspec(pMac, assocId, &pTspec->tsinfo, pTspecList, ppInfo)) + { + //update this entry. + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("updating TSPEC table entry = %d"), + (*ppInfo)->idx); + } + else + { + /* We didn't find one to update. So find a free slot in the + * LIM TSPEC list and add this new entry + */ + tANI_U8 ctspec = 0; + for (ctspec = 0 , pTspecList = &pMac->lim.tspecInfo[0]; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if (! pTspecList->inuse) + { + limLog(pMac, LOG1, FL("Found free slot in TSPEC list. Add to TSPEC table entry %d"), ctspec); + break; + } + } + + if (ctspec >= LIM_NUM_TSPEC_MAX) + return eSIR_FAILURE; + + //Record the new index entry + pTspecList->idx = ctspec; + } + } + + // update the tspec info + pTspecList->tspec = *pTspec; + pTspecList->assocId = assocId; + vos_mem_copy(pTspecList->staAddr, pAddr, sizeof(pTspecList->staAddr)); + + // for edca tspec's, we are all done + if (pTspec->tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) + { + pTspecList->inuse = 1; + *ppInfo = pTspecList; + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for EDCA AccessPolicy")); + return eSIR_SUCCESS; + } + + /* + * for hcca tspec's, must set the parameterized bit in the queues + * the 'ts' bit in the queue data structure indicates that the queue is + * parameterized (hcca). When the schedule is written this bit is used + * in the tsid field (bit 3) and the other three bits (0-2) are simply + * filled in as the user priority (or qid). This applies only to uplink + * polls where the qos control field must contain the tsid specified in the + * tspec. + */ +#if 0 + if ((pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) || + (pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR)) + queue[staid][pTspec->tsinfo.traffic.userPrio][SCH_UL_QUEUE].ts = 1; +#endif + pTspecList->inuse = 1; + *ppInfo = pTspecList; + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("added entry for HCCA AccessPolicy")); + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limValidateAccessPolicy +\brief Validates Access policy +\param tpAniSirGlobal pMac +\param tANI_U8 accessPolicy +\param tANI_U16 assocId +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +static tSirRetStatus +limValidateAccessPolicy( + tpAniSirGlobal pMac, + tANI_U8 accessPolicy, + tANI_U16 assocId, + tpPESession psessionEntry) +{ + tSirRetStatus retval = eSIR_FAILURE; + tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if ((pSta == NULL) || (! pSta->valid)) + { + PELOGE(limLog(pMac, LOGE, FL("invalid station address passed"));) + return eSIR_FAILURE; + } + + switch (accessPolicy) + { + case SIR_MAC_ACCESSPOLICY_EDCA: + if (pSta->wmeEnabled || pSta->lleEnabled) + retval = eSIR_SUCCESS; + break; + + case SIR_MAC_ACCESSPOLICY_HCCA: + case SIR_MAC_ACCESSPOLICY_BOTH: +#if 0 //only EDCA supported for now. + // TBD: check wsm doesn't support the hybrid access policy + if (pSta->wsmEnabled || pSta->lleEnabled) + retval = eSIR_SUCCESS; + break; +#endif //only EDCA supported for now. + default: + PELOGE(limLog(pMac, LOGE, FL("Invalid accessPolicy %d"), accessPolicy);) + break; + } + + if (retval != eSIR_SUCCESS) + limLog(pMac, LOGW, FL("failed (accPol %d, staId %d, lle %d, wme %d, wsm %d)"), + accessPolicy, pSta->staIndex, pSta->lleEnabled, pSta->wmeEnabled, pSta->wsmEnabled); + + return retval; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlAddTS +\brief Determine if STA with the specified TSPEC can be admitted. If it can, + a schedule element is provided +\param tpAniSirGlobal pMac +\param tANI_U8 *pAddr, +\param tSirAddtsReqInfo *pAddts, +\param tSirMacQosCapabilityIE *pQos, +\param tANI_U16 assocId, // assocId, valid only if alloc==true +\param tANI_U8 alloc, // true=>allocate bw for this tspec, + // else determine only if space is available +\param tSirMacScheduleIE *pSch, +\param tANI_U8 *pTspecIdx //index to the lim tspec table. +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus limAdmitControlAddTS( + tpAniSirGlobal pMac, + tANI_U8 *pAddr, + tSirAddtsReqInfo *pAddts, + tSirMacQosCapabilityStaIE *pQos, + tANI_U16 assocId, // assocId, valid only if alloc==true + tANI_U8 alloc, // true=>allocate bw for this tspec, + // else determine only if space is available + tSirMacScheduleIE *pSch, + tANI_U8 *pTspecIdx, //index to the lim tspec table. + tpPESession psessionEntry + ) +{ + tpLimTspecInfo pTspecInfo; + tSirRetStatus retval; + tANI_U32 svcInterval; + (void) pQos; + + // TBD: modify tspec as needed + // EDCA: need to fill in the medium time and the minimum phy rate + // to be consistent with the desired traffic parameters. + + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("tsid %d, directn %d, start %d, intvl %d, accPolicy %d, up %d"), + pAddts->tspec.tsinfo.traffic.tsid, pAddts->tspec.tsinfo.traffic.direction, + pAddts->tspec.svcStartTime, pAddts->tspec.minSvcInterval, + pAddts->tspec.tsinfo.traffic.accessPolicy, pAddts->tspec.tsinfo.traffic.userPrio); + + // check for duplicate tspec + retval = (alloc) + ? limTspecFindByAssocId(pMac, assocId, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo) + : limTspecFindByStaAddr(pMac, pAddr, &pAddts->tspec, &pMac->lim.tspecInfo[0], &pTspecInfo); + + if (retval == eSIR_SUCCESS) + { + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("duplicate tspec (index %d)!"), pTspecInfo->idx); + return eSIR_FAILURE; + } + + // check that the tspec's are well formed and acceptable + if (limValidateTspec(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("tspec validation failed"));) + return eSIR_FAILURE; + } + + // determine a service interval for the tspec + if (limCalculateSvcInt(pMac, &pAddts->tspec, &svcInterval) != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("SvcInt calculate failed"));) + return eSIR_FAILURE; + } + + // determine if the tspec can be admitted or not based on current policy + if (limAdmitPolicy(pMac, &pAddts->tspec, psessionEntry) != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("tspec rejected by admit control policy"));) + return eSIR_FAILURE; + } + + // fill in a schedule if requested + if (pSch != NULL) + { + vos_mem_set((tANI_U8 *) pSch, sizeof(*pSch), 0); + pSch->svcStartTime = pAddts->tspec.svcStartTime; + pSch->svcInterval = svcInterval; + pSch->maxSvcDuration = (tANI_U16) pSch->svcInterval; // use SP = SI + pSch->specInterval = 0x1000; // fixed for now: TBD + + pSch->info.direction = pAddts->tspec.tsinfo.traffic.direction; + pSch->info.tsid = pAddts->tspec.tsinfo.traffic.tsid; + pSch->info.aggregation = 0; // no support for aggregation for now: TBD + } + + // if no allocation is requested, done + if (! alloc) + return eSIR_SUCCESS; + + // check that we are in the proper mode to deal with the tspec type + if (limValidateAccessPolicy(pMac, (tANI_U8) pAddts->tspec.tsinfo.traffic.accessPolicy, assocId, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGW, FL("AccessPolicy %d is not valid in current mode"), + pAddts->tspec.tsinfo.traffic.accessPolicy); + return eSIR_FAILURE; + } + + // add tspec to list + if (limTspecAdd(pMac, pAddr, assocId, &pAddts->tspec, svcInterval, &pTspecInfo) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("no space in tspec list"));) + return eSIR_FAILURE; + } + + //passing lim tspec table index to the caller + *pTspecIdx = pTspecInfo->idx; + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlDeleteTS +\brief Delete the specified Tspec for the specified STA +\param tpAniSirGlobal pMac +\param tANI_U16 assocId +\param tSirMacTSInfo *pTsInfo +\param tANI_U8 *pTsStatus +\param tANI_U8 *ptspecIdx +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limAdmitControlDeleteTS( + tpAniSirGlobal pMac, + tANI_U16 assocId, + tSirMacTSInfo *pTsInfo, + tANI_U8 *pTsStatus, + tANI_U8 *ptspecIdx) +{ + tpLimTspecInfo pTspecInfo = NULL; + + if (pTsStatus != NULL) + *pTsStatus = 0; + + if (limFindTspec(pMac, assocId, pTsInfo, &pMac->lim.tspecInfo[0], &pTspecInfo) == eSIR_SUCCESS) + { + if(pTspecInfo != NULL) + { + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Tspec entry %d found"), pTspecInfo->idx); + + *ptspecIdx = pTspecInfo->idx; + limTspecDelete(pMac, pTspecInfo); + return eSIR_SUCCESS; + } + } + return eSIR_FAILURE; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlDeleteSta +\brief Delete all TSPEC for the specified STA +\param tpAniSirGlobal pMac +\param tANI_U16 assocId +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limAdmitControlDeleteSta( + tpAniSirGlobal pMac, + tANI_U16 assocId) +{ + tpLimTspecInfo pTspecInfo = &pMac->lim.tspecInfo[0]; + int ctspec; + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecInfo++) + { + if (assocId == pTspecInfo->assocId) + { + limTspecDelete(pMac, pTspecInfo); + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("Deleting TSPEC %d for assocId %d"), + ctspec, assocId); + } + } + limLog(pMac, ADMIT_CONTROL_LOGLEVEL, FL("assocId %d done"), assocId); + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limAdmitControlInit +\brief init tspec table +\param tpAniSirGlobal pMac +\return eSirRetStatus - status + -------------------------------------------------------------*/ +tSirRetStatus limAdmitControlInit(tpAniSirGlobal pMac) +{ + vos_mem_set(pMac->lim.tspecInfo, LIM_NUM_TSPEC_MAX * sizeof(tLimTspecInfo), 0); + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limUpdateAdmitPolicy +\brief Set the admit control policy based on CFG parameters +\param tpAniSirGlobal pMac +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus limUpdateAdmitPolicy(tpAniSirGlobal pMac) +{ + tANI_U32 val; + if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_POLICY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_POLICY")); + return eSIR_FAILURE; + } + pMac->lim.admitPolicyInfo.type = (tANI_U8) val; + if (wlan_cfgGetInt(pMac, WNI_CFG_ADMIT_BWFACTOR, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get CFG_ADMIT_BWFACTOR")); + return eSIR_FAILURE; + } + pMac->lim.admitPolicyInfo.bw_factor = (tANI_U8) val; + + PELOG1(limLog(pMac, LOG1, FL("LIM: AdmitPolicy %d, bw_factor %d"), + pMac->lim.admitPolicyInfo.type, pMac->lim.admitPolicyInfo.bw_factor);) + + return eSIR_SUCCESS; +} + + +/** ------------------------------------------------------------- +\fn limSendHalMsgAddTs +\brief Send halMsg_AddTs to HAL +\param tpAniSirGlobal pMac +\param tANI_U16 staIdx +\param tANI_U8 tspecIdx +\param tSirMacTspecIE tspecIE +\param tSirTclasInfo *tclasInfo +\param tANI_U8 tclasProc +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limSendHalMsgAddTs( + tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirMacTspecIE tspecIE, + tANI_U8 sessionId) +{ + tSirMsgQ msg; + tpAddTsParams pAddTsParam; + + pAddTsParam = vos_mem_malloc(sizeof(tAddTsParams)); + if (NULL == pAddTsParam) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set((tANI_U8 *)pAddTsParam, sizeof(tAddTsParams), 0); + pAddTsParam->staIdx = staIdx; + pAddTsParam->tspecIdx = tspecIdx; + vos_mem_copy(&pAddTsParam->tspec, &tspecIE, sizeof(tSirMacTspecIE)); + pAddTsParam->sessionId = sessionId; + + msg.type = WDA_ADD_TS_REQ; + msg.bodyptr = pAddTsParam; + msg.bodyval = 0; + + /* We need to defer any incoming messages until we get a + * WDA_ADD_TS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, sessionId, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed"));) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAddTsParam); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limSendHalMsgDelTs +\brief Send halMsg_AddTs to HAL +\param tpAniSirGlobal pMac +\param tANI_U16 staIdx +\param tANI_U8 tspecIdx +\param tSirAddtsReqInfo addts +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limSendHalMsgDelTs( + tpAniSirGlobal pMac, + tANI_U16 staIdx, + tANI_U8 tspecIdx, + tSirDeltsReqInfo delts, + tANI_U8 sessionId, + tANI_U8 *bssId) +{ + tSirMsgQ msg; + tpDelTsParams pDelTsParam; + + pDelTsParam = vos_mem_malloc(sizeof(tDelTsParams)); + if (NULL == pDelTsParam) + { + limLog(pMac, LOGP, FL("AllocateMemory() failed")); + return eSIR_MEM_ALLOC_FAILED; + } + + msg.type = WDA_DEL_TS_REQ; + msg.bodyptr = pDelTsParam; + msg.bodyval = 0; + vos_mem_set((tANI_U8 *)pDelTsParam, sizeof(tDelTsParams), 0); + + //filling message parameters. + pDelTsParam->staIdx = staIdx; + pDelTsParam->tspecIdx = tspecIdx; + vos_mem_copy(&pDelTsParam->bssId, bssId, sizeof(tSirMacAddr)); + + PELOGW(limLog(pMac, LOGW, FL("calling wdaPostCtrlMsg()"));) + MTRACE(macTraceMsgTx(pMac, sessionId, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed"));) + vos_mem_free(pDelTsParam); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limProcessHalAddTsRsp +\brief This function process the WDA_ADD_TS_RSP from HAL. +\ If response is successful, then send back SME_ADDTS_RSP. +\ Otherwise, send DELTS action frame to peer and then +\ then send back SME_ADDTS_RSP. +\ +\param tpAniSirGlobal pMac +\param tpSirMsgQ limMsg +-------------------------------------------------------------*/ +void limProcessHalAddTsRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpAddTsParams pAddTsRspMsg = NULL; + tpDphHashNode pSta = NULL; + tANI_U16 assocId =0; + tSirMacAddr peerMacAddr; + tANI_U8 rspReqd = 1; + tpPESession psessionEntry = NULL; + + + /* Need to process all the deferred messages enqueued + * since sending the WDA_ADD_TS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (NULL == limMsg->bodyptr) + { + limLog(pMac, LOGP, FL("Received WDA_ADD_TS_RSP with NULL ")); + goto end; + } + + pAddTsRspMsg = (tpAddTsParams) (limMsg->bodyptr); + + // 090803: Use peFindSessionBySessionId() to obtain the PE session context + // from the sessionId in the Rsp Msg from HAL + psessionEntry = peFindSessionBySessionId(pMac, pAddTsRspMsg->sessionId); + + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId :%d "), pAddTsRspMsg->sessionId);) + limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec, + pMac->lim.gLimAddtsReq.sessionId, pMac->lim.gLimAddtsReq.transactionId); + goto end; + } + + if(pAddTsRspMsg->status == eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOG1, FL("Received successful ADDTS response from HAL ")); + // Use the smesessionId and smetransactionId from the PE session context + limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_SUCCESS, psessionEntry, pAddTsRspMsg->tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + goto end; + } + else + { + limLog(pMac, LOG1, FL("Received failure ADDTS response from HAL ")); + + // Send DELTS action frame to AP + // 090803: Get peer MAC addr from session +#if 0 + cfgLen = sizeof(tSirMacAddr); + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMacAddr, &cfgLen) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve BSSID ")); + goto end; + } +#endif //TO SUPPORT BT-AMP + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + // 090803: Add the SME Session ID + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &pAddTsRspMsg->tspec.tsinfo, &pAddTsRspMsg->tspec, + //psessionEntry->smeSessionId); + psessionEntry); + + // Delete TSPEC + // 090803: Pull the hash table from the session + pSta = dphLookupAssocId(pMac, pAddTsRspMsg->staIdx, &assocId, + &psessionEntry->dph.dphHashTable); + if (pSta != NULL) + limAdmitControlDeleteTS(pMac, assocId, &pAddTsRspMsg->tspec.tsinfo, NULL, (tANI_U8 *)&pAddTsRspMsg->tspecIdx); + + // Send SME_ADDTS_RSP + // 090803: Use the smesessionId and smetransactionId from the PE session context + limSendSmeAddtsRsp(pMac, rspReqd, eSIR_SME_ADDTS_RSP_FAILED, psessionEntry, pAddTsRspMsg->tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + goto end; + } + +end: + if( pAddTsRspMsg != NULL ) + vos_mem_free(pAddTsRspMsg); + return; +} + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c new file mode 100644 index 000000000000..b21ad3aeef54 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limApi.c @@ -0,0 +1,2860 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file limApi.cc contains the functions that are + * exported by LIM to other modules. + * + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniCfg.h" +#include "wniApi.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "utilsApi.h" +#include "limApi.h" +#include "limGlobal.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" +#include "limIbssPeerMgmt.h" +#include "limAdmitControl.h" +#include "pmmApi.h" +#include "logDump.h" +#include "limSendSmeRspMessages.h" +#include "wmmApsd.h" +#include "limTrace.h" +#include "limSession.h" +#include "wlan_qct_wda.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#include +#include "vos_types.h" +#include "vos_packet.h" +#include "wlan_qct_tl.h" +#include "sysStartup.h" + + +static void __limInitScanVars(tpAniSirGlobal pMac) +{ + pMac->lim.gLimUseScanModeForLearnMode = 1; + + pMac->lim.gLimSystemInScanLearnMode = 0; + + // Scan related globals on STA + pMac->lim.gLimReturnAfterFirstMatch = 0; + pMac->lim.gLim24Band11dScanDone = 0; + pMac->lim.gLim50Band11dScanDone = 0; + pMac->lim.gLimReturnUniqueResults = 0; + + // Background Scan related globals on STA + pMac->lim.gLimNumOfBackgroundScanSuccess = 0; + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0; + pMac->lim.gLimNumOfForcedBkgndScan = 0; + pMac->lim.gLimBackgroundScanDisable = false; //based on BG timer + pMac->lim.gLimForceBackgroundScanDisable = false; //debug control flag + pMac->lim.gLimBackgroundScanTerminate = TRUE; //controlled by SME + pMac->lim.gLimReportBackgroundScanResults = FALSE; //controlled by SME + + pMac->lim.gLimCurrentScanChannelId = 0; + pMac->lim.gpLimMlmScanReq = NULL; + pMac->lim.gDeferMsgTypeForNOA = 0; + pMac->lim.gpDefdSmeMsgForNOA = NULL; + pMac->lim.gLimMlmScanResultLength = 0; + pMac->lim.gLimSmeScanResultLength = 0; + + vos_mem_set(pMac->lim.gLimCachedScanHashTable, + sizeof(pMac->lim.gLimCachedScanHashTable), 0); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + + pMac->lim.gLimMlmLfrScanResultLength = 0; + pMac->lim.gLimSmeLfrScanResultLength = 0; + + vos_mem_set(pMac->lim.gLimCachedLfrScanHashTable, + sizeof(pMac->lim.gLimCachedLfrScanHashTable), 0); +#endif + pMac->lim.gLimBackgroundScanChannelId = 0; + pMac->lim.gLimBackgroundScanStarted = 0; + pMac->lim.gLimRestoreCBNumScanInterval = LIM_RESTORE_CB_NUM_SCAN_INTERVAL_DEFAULT; + pMac->lim.gLimRestoreCBCount = 0; + vos_mem_set(pMac->lim.gLimLegacyBssidList, + sizeof(pMac->lim.gLimLegacyBssidList), 0); + + /* Fill in default values */ + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = 0; + + + // abort scan is used to abort an on-going scan + pMac->lim.abortScan = 0; + vos_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0); + vos_mem_set(&pMac->lim.dfschannelList, sizeof(tSirDFSChannelList), 0); + +//WLAN_SUSPEND_LINK Related + pMac->lim.gpLimSuspendCallback = NULL; + pMac->lim.gpLimResumeCallback = NULL; +//end WLAN_SUSPEND_LINK Related +} + + +static void __limInitBssVars(tpAniSirGlobal pMac) +{ + + vos_mem_set((void*)pMac->lim.gpSession, + sizeof(*pMac->lim.gpSession)*pMac->lim.maxBssId, 0); + + + //pMac->lim.gpLimStartBssReq = NULL; + + + + +/* These global variables are moved to session table and intialization is done during session creation Oct 9th Review */ +#if 0 + + // Place holder for BSS description that we're + // currently joined with + vos_mem_set(&pMac->lim.gLimCurrentBssId, sizeof(tSirMacAddr), 0); + pMac->lim.gLimCurrentChannelId = HAL_INVALID_CHANNEL_ID; + vos_mem_set(&pMac->lim.gLimCurrentSSID, sizeof(tSirMacSSid), 0); + pMac->lim.gLimCurrentBssCaps = 0; + QosCaps is a bit map of various qos capabilities - see defn above + pMac->lim.gLimCurrentBssQosCaps = 0; + pMac->lim.gLimCurrentBssPropCap = 0; + pMac->lim.gLimSentCapsChangeNtf = 0; + + // Place holder for BSS description that + // we're currently Reassociating + vos_mem_set(&pMac->lim.gLimReassocBssId, sizeof(tSirMacAddr), 0); + pMac->lim.gLimReassocChannelId = 0; + vos_mem_set(&pMac->lim.gLimReassocSSID, sizeof(tSirMacSSid), 0); + pMac->lim.gLimReassocBssCaps = 0; + pMac->lim.gLimReassocBssQosCaps = 0; + pMac->lim.gLimReassocBssPropCap = 0; + #endif + + /* This is for testing purposes only, be default should always be off */ + pMac->lim.gLimForceNoPropIE = 0; + + // pMac->lim.gLimBssIdx = 0; + + pMac->lim.gpLimMlmSetKeysReq = NULL; + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + // pMac->lim.gLimStaid = 0; //TO SUPPORT BT-AMP + +} + + +static void __limInitStatsVars(tpAniSirGlobal pMac) +{ + pMac->lim.gLimNumBeaconsRcvd = 0; + pMac->lim.gLimNumBeaconsIgnored = 0; + + pMac->lim.gLimNumDeferredMsgs = 0; + + /// Variable to keep track of number of currently associated STAs + //pMac->lim.gLimNumOfCurrentSTAs = 0; + pMac->lim.gLimNumOfAniSTAs = 0; // count of ANI peers + + /// This indicates number of RXed Beacons during HB period + //pMac->lim.gLimRxedBeaconCntDuringHB = 0; + + // Heart-Beat interval value + pMac->lim.gLimHeartBeatCount = 0; + + vos_mem_zero(pMac->lim.gLimHeartBeatApMac[0], + sizeof(tSirMacAddr)); + vos_mem_zero(pMac->lim.gLimHeartBeatApMac[1], + sizeof(tSirMacAddr)); + pMac->lim.gLimHeartBeatApMacIndex = 0; + + // Statistics to keep track of no. beacons rcvd in heart beat interval + vos_mem_set(pMac->lim.gLimHeartBeatBeaconStats, + sizeof(pMac->lim.gLimHeartBeatBeaconStats), 0); + +#ifdef WLAN_DEBUG + // Debug counters + pMac->lim.numTot = 0; + pMac->lim.numBbt = 0; + pMac->lim.numProtErr = 0; + pMac->lim.numLearn = 0; + pMac->lim.numLearnIgnore = 0; + pMac->lim.numSme = 0; + vos_mem_set(pMac->lim.numMAC, sizeof(pMac->lim.numMAC), 0); + pMac->lim.gLimNumAssocReqDropInvldState = 0; + pMac->lim.gLimNumAssocReqDropACRejectTS = 0; + pMac->lim.gLimNumAssocReqDropACRejectSta = 0; + pMac->lim.gLimNumReassocReqDropInvldState = 0; + pMac->lim.gLimNumHashMissIgnored = 0; + pMac->lim.gLimUnexpBcnCnt = 0; + pMac->lim.gLimBcnSSIDMismatchCnt = 0; + pMac->lim.gLimNumLinkEsts = 0; + pMac->lim.gLimNumRxCleanup = 0; + pMac->lim.gLim11bStaAssocRejectCount = 0; +#endif +} + + + +static void __limInitStates(tpAniSirGlobal pMac) +{ + // Counts Heartbeat failures + pMac->lim.gLimHBfailureCntInLinkEstState = 0; + pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0; + pMac->lim.gLimHBfailureCntInOtherStates = 0; + pMac->lim.gLimRspReqd = 0; + pMac->lim.gLimPrevSmeState = eLIM_SME_OFFLINE_STATE; + + /// MLM State visible across all Sirius modules + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, eLIM_MLM_IDLE_STATE)); + pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE; + + /// Previous MLM State + pMac->lim.gLimPrevMlmState = eLIM_MLM_OFFLINE_STATE; + +#ifdef GEN4_SCAN + // LIM to HAL SCAN Management Message Interface states + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; +#endif // GEN4_SCAN + + /** + * Initialize state to eLIM_SME_OFFLINE_STATE + */ + pMac->lim.gLimSmeState = eLIM_SME_OFFLINE_STATE; + + /** + * By default assume 'unknown' role. This will be updated + * when SME_START_BSS_REQ is received. + */ + + vos_mem_set(&pMac->lim.gLimOverlap11gParams, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimOverlap11aParams, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimOverlapHt20Params, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimOverlapNonGfParams, sizeof(tLimProtStaParams), 0); + vos_mem_set(&pMac->lim.gLimNoShortParams, sizeof(tLimNoShortParams), 0); + vos_mem_set(&pMac->lim.gLimNoShortSlotParams, sizeof(tLimNoShortSlotParams), 0); + + pMac->lim.gLimPhyMode = 0; + pMac->lim.scanStartTime = 0; // used to measure scan time + + vos_mem_set(pMac->lim.gLimMyMacAddr, sizeof(pMac->lim.gLimMyMacAddr), 0); + pMac->lim.ackPolicy = 0; + +#if 0 /* Moving all these to session specific elements */ + pMac->lim.gLimQosEnabled = 0; //11E + pMac->lim.gLimWmeEnabled = 0; //WME + pMac->lim.gLimWsmEnabled = 0; //WSM + pMac->lim.gLimHcfEnabled = 0; + pMac->lim.gLim11dEnabled = 0; +#endif + + pMac->lim.gLimProbeRespDisableFlag = 0; // control over probe response +} + +static void __limInitVars(tpAniSirGlobal pMac) +{ + + + // Place holder for Measurement Req/Rsp/Ind related info + + // WDS info + pMac->lim.gLimNumWdsInfoInd = 0; + pMac->lim.gLimNumWdsInfoSet = 0; + vos_mem_set(&pMac->lim.gLimWdsInfo, sizeof(tSirWdsInfo), 0); + /* initialize some parameters */ + limInitWdsInfoParams(pMac); + + // Deferred Queue Paramters + vos_mem_set(&pMac->lim.gLimDeferredMsgQ, sizeof(tSirAddtsReq), 0); + + // addts request if any - only one can be outstanding at any time + vos_mem_set(&pMac->lim.gLimAddtsReq, sizeof(tSirAddtsReq) , 0); + pMac->lim.gLimAddtsSent = 0; + pMac->lim.gLimAddtsRspTimerCount = 0; + + //protection related config cache + vos_mem_set(&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0); + pMac->lim.gLimProtectionControl = 0; + vos_mem_set(&pMac->lim.gLimAlternateRadio, sizeof(tSirAlternateRadioInfo), 0); + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + +#if 0 + // 11h Spectrum Management Related Flag + LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE); + pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE; +#endif + // WMM Related Flag + pMac->lim.gUapsdEnable = 0; + pMac->lim.gUapsdPerAcBitmask = 0; + pMac->lim.gUapsdPerAcTriggerEnableMask = 0; + pMac->lim.gUapsdPerAcDeliveryEnableMask = 0; + + // QoS-AC Downgrade: Initially, no AC is admitted + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] = 0; + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] = 0; + + //dialogue token List head/tail for Action frames request sent. + pMac->lim.pDialogueTokenHead = NULL; + pMac->lim.pDialogueTokenTail = NULL; + + vos_mem_set(&pMac->lim.tspecInfo, + sizeof(tLimTspecInfo) * LIM_NUM_TSPEC_MAX, 0); + + // admission control policy information + vos_mem_set(&pMac->lim.admitPolicyInfo, sizeof(tLimAdmitPolicyInfo), 0); + + pMac->lim.gLastBeaconDtimCount = 0; + pMac->lim.gLastBeaconDtimPeriod = 0; + + //Scan in Power Save Flag + pMac->lim.gScanInPowersave = 0; + pMac->lim.probeCounter = 0; + pMac->lim.maxProbe = 0; + pMac->lim.txBdToken = 0; + + pMac->lim.EnableTdls2040BSSCoexIE = 1; +} + +static void __limInitAssocVars(tpAniSirGlobal pMac) +{ + tANI_U32 val; +#if 0 + vos_mem_set(pMac->lim.gpLimAIDpool, + sizeof(*pMac->lim.gpLimAIDpool) * (WNI_CFG_ASSOC_STA_LIMIT_STAMAX+1), 0); + pMac->lim.freeAidHead = 0; + pMac->lim.freeAidTail = 0; +#endif + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS) + { + limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" )); + } + pMac->lim.gLimAssocStaLimit = val; + pMac->lim.gLimIbssStaLimit = val; + + // Place holder for current authentication request + // being handled + pMac->lim.gpLimMlmAuthReq = NULL; + //pMac->lim.gpLimMlmJoinReq = NULL; + + /// MAC level Pre-authentication related globals + pMac->lim.gLimPreAuthChannelNumber = 0; + pMac->lim.gLimPreAuthType = eSIR_OPEN_SYSTEM; + vos_mem_set(&pMac->lim.gLimPreAuthPeerAddr, sizeof(tSirMacAddr), 0); + pMac->lim.gLimNumPreAuthContexts = 0; + vos_mem_set(&pMac->lim.gLimPreAuthTimerTable, sizeof(tLimPreAuthTable), 0); + + // Placed holder to deauth reason + pMac->lim.gLimDeauthReasonCode = 0; + + // Place holder for Pre-authentication node list + pMac->lim.pLimPreAuthList = NULL; + + //One cache for each overlap and associated case. + vos_mem_set(pMac->lim.protStaOverlapCache, + sizeof(tCacheParams) * LIM_PROT_STA_OVERLAP_CACHE_SIZE, 0); + vos_mem_set(pMac->lim.protStaCache, + sizeof(tCacheParams) * LIM_PROT_STA_CACHE_SIZE, 0); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->lim.pSessionEntry = NULL; + pMac->lim.reAssocRetryAttempt = 0; +#endif + +} + + +static void __limInitTitanVars(tpAniSirGlobal pMac) +{ +#if 0 + vos_mem_set(&pMac->lim.gLimChannelSwitch, sizeof(tLimChannelSwitchInfo), 0); + pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE; + pMac->lim.gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED; +#endif + // Debug workaround for BEACON's + // State change triggered by "dump 222" + pMac->lim.gLimScanOverride = 1; + pMac->lim.gLimScanOverrideSaved = eSIR_ACTIVE_SCAN; + pMac->lim.gLimTitanStaCount = 0; + pMac->lim.gLimBlockNonTitanSta = 0; +} + +static void __limInitHTVars(tpAniSirGlobal pMac) +{ + pMac->lim.htCapabilityPresentInBeacon = 0; + pMac->lim.gHTGreenfield = 0; + pMac->lim.gHTShortGI40Mhz = 0; + pMac->lim.gHTShortGI20Mhz = 0; + pMac->lim.gHTMaxAmsduLength = 0; + pMac->lim.gHTDsssCckRate40MHzSupport = 0; + pMac->lim.gHTPSMPSupport = 0; + pMac->lim.gHTLsigTXOPProtection = 0; + pMac->lim.gHTMIMOPSState = eSIR_HT_MIMO_PS_STATIC; + pMac->lim.gHTAMpduDensity = 0; + + pMac->lim.gMaxAmsduSizeEnabled = false; + pMac->lim.gHTMaxRxAMpduFactor = 0; + pMac->lim.gHTServiceIntervalGranularity = 0; + pMac->lim.gHTControlledAccessOnly = 0; + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + pMac->lim.gHTPCOActive = 0; + + pMac->lim.gHTPCOPhase = 0; + pMac->lim.gHTSecondaryBeacon = 0; + pMac->lim.gHTDualCTSProtection = 0; + pMac->lim.gHTSTBCBasicMCS = 0; + pMac->lim.gAddBA_Declined = 0; // Flag to Decline the BAR if the particular bit (0-7) is being set + vos_mem_set(&pMac->lim.staBaInfo, sizeof(pMac->lim.staBaInfo), 0); +} + +static tSirRetStatus __limInitConfig( tpAniSirGlobal pMac ) +{ + tANI_U32 val1, val2, val3; + tANI_U16 val16; + tANI_U8 val8; + tSirMacHTCapabilityInfo *pHTCapabilityInfo; + tSirMacHTInfoField1 *pHTInfoField1; + tpSirPowerSaveCfg pPowerSaveConfig; + tSirMacHTParametersInfo *pAmpduParamInfo; + + /* Read all the CFGs here that were updated before peStart is called */ + /* All these CFG READS/WRITES are only allowed in init, at start when there is no session + * and they will be used throughout when there is no session + */ + + if(wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + return eSIR_FAILURE; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Channel Bonding CFG"));) + return eSIR_FAILURE; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + + //channel bonding mode could be set to anything from 0 to 4(Titan had these + // modes But for Taurus we have only two modes: enable(>0) or disable(=0) + pHTCapabilityInfo->supportedChannelWidthSet = val2 ? + WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + return eSIR_FAILURE; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT INFO Field1 CFG"));) + return eSIR_FAILURE; + } + + val8 = ( tANI_U8 ) val1; + pHTInfoField1 = ( tSirMacHTInfoField1* ) &val8; + pHTInfoField1->recommendedTxWidthSet = + (tANI_U8)pHTCapabilityInfo->supportedChannelWidthSet; + if(cfgSetInt(pMac, WNI_CFG_HT_INFO_FIELD1, *(tANI_U8*)pHTInfoField1) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT Info Field"));) + return eSIR_FAILURE; + } + + /* WNI_CFG_HEART_BEAT_THRESHOLD */ + + if( wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG"));) + return eSIR_FAILURE; + } + if(!val1) + { + limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER); + pMac->sys.gSysEnableLinkMonitorMode = 0; + } + else + { + //No need to activate the timer during init time. + pMac->sys.gSysEnableLinkMonitorMode = 1; + } + + /* WNI_CFG_SHORT_GI_20MHZ */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG"));) + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val3) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG"));) + return eSIR_FAILURE; + } + + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2; + pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val3; + + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != + eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + return eSIR_FAILURE; + } + + /* WNI_CFG_MAX_RX_AMPDU_FACTOR */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));) + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG"));) + return eSIR_FAILURE; + } + val16 = ( tANI_U16 ) val1; + pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16; + pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != + eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG"));) + return eSIR_FAILURE; + } + + /* WNI_CFG_SHORT_PREAMBLE - this one is not updated in + limHandleCFGparamUpdate do we want to update this? */ + if(wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val1) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("cfg get short preamble failed")); + return eSIR_FAILURE; + } + + /* WNI_CFG_MAX_PS_POLL */ + + /* Allocate and fill in power save configuration. */ + pPowerSaveConfig = vos_mem_malloc(sizeof(tSirPowerSaveCfg)); + if (NULL == pPowerSaveConfig) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: Cannot allocate memory for power save " + "configuration"));) + return eSIR_FAILURE; + } + + /* This context should be valid if power-save configuration message has been + * already dispatched during initialization process. Re-using the present + * configuration mask + */ + vos_mem_copy(pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg, sizeof(tSirPowerSaveCfg)); + + /* Note: it is okay to do this since DAL/HAL is alrady started */ + if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: pmmSendPowerSaveCfg() failed "));) + return eSIR_FAILURE; + } + + /* WNI_CFG_BG_SCAN_CHANNEL_LIST_CHANNEL_LIST */ + + PELOG1(limLog(pMac, LOG1, + FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel"));) + pMac->lim.gLimBackgroundScanChannelId = 0; + + /* WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA - not needed */ + + /* This was initially done after resume notification from HAL. Now, DAL is + started before PE so this can be done here */ + handleHTCapabilityandHTInfo(pMac, NULL); + if(wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_LDPC_WITH_TXBF_AP,(tANI_U32 *) &pMac->lim.disableLDPCWithTxbfAP) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get disableLDPCWithTxbfAP failed")); + return eSIR_FAILURE; + } +#ifdef FEATURE_WLAN_TDLS + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_BUF_STA_ENABLED,(tANI_U32 *) &pMac->lim.gLimTDLSBufStaEnabled) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSBufStaEnabled failed")); + return eSIR_FAILURE; + } + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK,(tANI_U32 *) &pMac->lim.gLimTDLSUapsdMask) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed")); + return eSIR_FAILURE; + } + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED,(tANI_U32 *) &pMac->lim.gLimTDLSOffChannelEnabled) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSUapsdMask failed")); + return eSIR_FAILURE; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_WMM_MODE_ENABLED,(tANI_U32 *) &pMac->lim.gLimTDLSWmmMode) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get LimTDLSWmmMode failed")); + return eSIR_FAILURE; + } +#endif + + if (eSIR_SUCCESS != + wlan_cfgGetInt(pMac, WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL, + (tANI_U32 *)&pMac->lim.gDebugP2pRemainOnChannel)) + { + limLog( pMac, LOGE, + "%s: Couldn't get WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL value", + __func__); + pMac->lim.gDebugP2pRemainOnChannel = 0; + } + return eSIR_SUCCESS; +} + +/* + limStart + This function is to replace the __limProcessSmeStartReq since there is no + eWNI_SME_START_REQ post to PE. +*/ +tSirRetStatus limStart(tpAniSirGlobal pMac) +{ + tSirResultCodes retCode = eSIR_SUCCESS; + + limLog(pMac, LOG1, FL(" enter")); + + if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + { + pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + + // By default do not return after first scan match + pMac->lim.gLimReturnAfterFirstMatch = 0; + + // Initialize MLM state machine + limInitMlm(pMac); + + // By default return unique scan results + pMac->lim.gLimReturnUniqueResults = true; + pMac->lim.gLimSmeScanResultLength = 0; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pMac->lim.gLimSmeLfrScanResultLength = 0; +#endif + } + else + { + /** + * Should not have received eWNI_SME_START_REQ in states + * other than OFFLINE. Return response to host and + * log error + */ + limLog(pMac, LOGE, FL("Invalid SME state %d"),pMac->lim.gLimSmeState ); + retCode = eSIR_FAILURE; + } + + return retCode; +} + +static void +limInitAssocRspCompletiontionList(tpAniSirGlobal pMac) +{ + vos_list_init(&pMac->assoc_rsp_completion_list); +} + +static void +limDestroyAssocRspCompletiontionList(tpAniSirGlobal pMac) +{ + vos_list_destroy(&pMac->assoc_rsp_completion_list); +} + +/** + * limInitialize() + * + *FUNCTION: + * This function is called from LIM thread entry function. + * LIM related global data structures are initialized in this function. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @return None + */ + +tSirRetStatus +limInitialize(tpAniSirGlobal pMac) +{ + tSirRetStatus status = eSIR_SUCCESS; + + __limInitAssocVars(pMac); + __limInitVars(pMac); + __limInitStates(pMac); + __limInitStatsVars(pMac); + __limInitBssVars(pMac); + __limInitScanVars(pMac); + __limInitHTVars(pMac); + __limInitTitanVars(pMac); + + status = limStart(pMac); + if(eSIR_SUCCESS != status) + { + return status; + } + + /* + * MLM will be intitalized when 'START' request comes from SME. + * limInitMlm calls limCreateTimers, which actually relies on + * CFG to be downloaded. So it should not be called as part of + * peStart, as CFG download is happening after peStart. + */ + //limInitMlm(pMac); + // Initializations for maintaining peers in IBSS + limIbssInit(pMac); + + limInitAssocRspCompletiontionList(pMac); + pmmInitialize(pMac); + + +#if defined WLAN_FEATURE_VOWIFI + rrmInitialize(pMac); +#endif +#if defined WLAN_FEATURE_VOWIFI_11R + limFTOpen(pMac); +#endif + +#ifdef WLAN_FEATURE_RMC + limRmcInit(pMac); +#endif /* WLAN_FEATURE_RMC */ + + vos_list_init(&pMac->lim.gLimMgmtFrameRegistratinQueue); + +#if 0 + + vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR); + vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN); + vos_trace_setLevel(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL); + + vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_WARN); + vos_trace_setLevel(VOS_MODULE_ID_HAL, VOS_TRACE_LEVEL_ERROR); + + vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN); + vos_trace_setLevel(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR); + vos_trace_setLevel(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR); + + vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR); + + vos_trace_setLevel(VOS_MODULE_ID_SSC, VOS_TRACE_LEVEL_ERROR); + + vos_trace_setLevel(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR); + vos_trace_setLevel(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR); + + vos_trace_setLevel(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR); + + + vos_trace_setLevel(VOS_MODULE_ID_BAL, VOS_TRACE_LEVEL_ERROR); + + vos_trace_setLevel(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR); +#endif + + //Initialize the configurations needed by PE + if( eSIR_FAILURE == __limInitConfig(pMac)) + { + //We need to undo everything in limStart + limCleanupMlm(pMac); + return eSIR_FAILURE; + } + + //initialize the TSPEC admission control table. + //Note that this was initially done after resume notification from HAL. + //Now, DAL is started before PE so this can be done here + limAdmitControlInit(pMac); + limRegisterHalIndCallBack(pMac); + + return status; + +} /*** end limInitialize() ***/ + + + +/** + * limCleanup() + * + *FUNCTION: + * This function is called upon reset or persona change + * to cleanup LIM state + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limCleanup(tpAniSirGlobal pMac) +{ + v_PVOID_t pvosGCTx; + VOS_STATUS retStatus; + +//Before destroying the list making sure all the nodes have been deleted. +//Which should be the normal case, but a memory leak has been reported. + + tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL; + + while(vos_list_remove_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t**)&pLimMgmtRegistration) == VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("Fixing leak! Deallocating pLimMgmtRegistration node")); + + vos_mem_free(pLimMgmtRegistration); + } + + vos_list_destroy(&pMac->lim.gLimMgmtFrameRegistratinQueue); + + limCleanupMlm(pMac); + limCleanupLmm(pMac); + +#ifdef WLAN_FEATURE_RMC + limRmcCleanup(pMac); +#endif /* WLAN_FEATURE_RMC */ + + // free up preAuth table + if (pMac->lim.gLimPreAuthTimerTable.pTable != NULL) + { + vos_mem_vfree(pMac->lim.gLimPreAuthTimerTable.pTable); + pMac->lim.gLimPreAuthTimerTable.pTable = NULL; + pMac->lim.gLimPreAuthTimerTable.numEntry = 0; + } + + if(NULL != pMac->lim.pDialogueTokenHead) + { + limDeleteDialogueTokenList(pMac); + } + + if(NULL != pMac->lim.pDialogueTokenTail) + { + vos_mem_free(pMac->lim.pDialogueTokenTail); + pMac->lim.pDialogueTokenTail = NULL; + } + + # if 0 + if (pMac->lim.gpLimStartBssReq != NULL) + { + vos_mem_free(pMac->lim.gpLimStartBssReq); + pMac->lim.gpLimStartBssReq = NULL; + } + #endif + + if (pMac->lim.gpLimMlmSetKeysReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmSetKeysReq); + pMac->lim.gpLimMlmSetKeysReq = NULL; + } + + #if 0 + if (pMac->lim.gpLimJoinReq != NULL) + { + vos_mem_free(pMac->lim.gpLimJoinReq); + pMac->lim.gpLimJoinReq = NULL; + } + #endif + + if (pMac->lim.gpLimMlmAuthReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmAuthReq); + pMac->lim.gpLimMlmAuthReq = NULL; + } + +#if 0 + if (pMac->lim.gpLimMlmJoinReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmJoinReq); + pMac->lim.gpLimMlmJoinReq = NULL; + } +#endif + + #if 0 + if (pMac->lim.gpLimReassocReq != NULL) + { + vos_mem_free(pMac->lim.gpLimReassocReq); + pMac->lim.gpLimReassocReq = NULL; + } + #endif + + if (pMac->lim.gpLimMlmRemoveKeyReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + } + + if (pMac->lim.gpDefdSmeMsgForNOA != NULL) + { + vos_mem_free(pMac->lim.gpDefdSmeMsgForNOA); + pMac->lim.gpDefdSmeMsgForNOA = NULL; + } + + if (pMac->lim.gpLimMlmScanReq != NULL) + { + vos_mem_free(pMac->lim.gpLimMlmScanReq); + pMac->lim.gpLimMlmScanReq = NULL; + } + limDestroyAssocRspCompletiontionList(pMac); +#if 0 + if(NULL != pMac->lim.beacon) + { + vos_mem_free((void*) pMac->lim.beacon); + pMac->lim.beacon = NULL; + } +#endif + #if 0 + if(NULL != pMac->lim.assocReq) + { + vos_mem_free((void*) pMac->lim.assocReq); + pMac->lim.assocReq= NULL; + } + #endif + +#if 0 + if(NULL != pMac->lim.assocRsp) + { + vos_mem_free((void*) pMac->lim.assocRsp); + pMac->lim.assocRsp= NULL; + } +#endif + // Now, finally reset the deferred message queue pointers + limResetDeferredMsgQ(pMac); + + + pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + retStatus = WLANTL_DeRegisterMgmtFrmClient(pvosGCTx); + + if ( retStatus != VOS_STATUS_SUCCESS ) + PELOGE(limLog(pMac, LOGE, FL("DeRegistering the PE Handle with TL has failed bailing out..."));) + +#if defined WLAN_FEATURE_VOWIFI + rrmCleanup(pMac); +#endif +#if defined WLAN_FEATURE_VOWIFI_11R + limFTCleanup(pMac); +#endif + +} /*** end limCleanup() ***/ + + +/** ------------------------------------------------------------- +\fn peOpen +\brief will be called in Open sequence from macOpen +\param tpAniSirGlobal pMac +\param tHalOpenParameters *pHalOpenParam +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam) +{ + if (eDRIVER_TYPE_MFG == pMacOpenParam->driverType) + return eSIR_SUCCESS; + pMac->lim.maxBssId = pMacOpenParam->maxBssId; + pMac->lim.maxStation = pMacOpenParam->maxStation; + vos_spin_lock_init( &pMac->sys.lock ); + + if ((pMac->lim.maxBssId == 0) || (pMac->lim.maxStation == 0)) + { + PELOGE(limLog(pMac, LOGE, FL("max number of Bssid or Stations cannot be zero!"));) + return eSIR_FAILURE; + } + + pMac->lim.limTimers.gpLimCnfWaitTimer = vos_mem_vmalloc(sizeof(TX_TIMER) * pMac->lim.maxStation); + if (NULL == pMac->lim.limTimers.gpLimCnfWaitTimer) + { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));) + return eSIR_FAILURE; + } + + pMac->lim.gpSession = vos_mem_vmalloc(sizeof(tPESession)* pMac->lim.maxBssId); + if (NULL == pMac->lim.gpSession) + { + limLog(pMac, LOGE, FL("memory allocate failed!")); + vos_mem_vfree(pMac->lim.limTimers.gpLimCnfWaitTimer); + return eSIR_FAILURE; + } + + vos_mem_set(pMac->lim.gpSession, sizeof(tPESession)*pMac->lim.maxBssId, 0); + + pMac->pmm.gPmmTim.pTim = vos_mem_malloc(sizeof(tANI_U8)*pMac->lim.maxStation); + if (NULL == pMac->pmm.gPmmTim.pTim) + { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed for pTim!"));) + vos_mem_vfree(pMac->lim.limTimers.gpLimCnfWaitTimer); + vos_mem_vfree(pMac->lim.gpSession); + return eSIR_FAILURE; + } + vos_mem_set(pMac->pmm.gPmmTim.pTim, sizeof(tANI_U8)*pMac->lim.maxStation, 0); + + pMac->lim.mgmtFrameSessionId = 0xff; + pMac->lim.deferredMsgCnt = 0; + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pMac->lim.lkPeGlobalLock ) ) ) + { + PELOGE(limLog(pMac, LOGE, FL("pe lock init failed!"));) + vos_mem_vfree(pMac->lim.limTimers.gpLimCnfWaitTimer); + pMac->lim.limTimers.gpLimCnfWaitTimer = NULL; + vos_mem_vfree(pMac->lim.gpSession); + pMac->lim.gpSession = NULL; + vos_mem_free(pMac->pmm.gPmmTim.pTim); + pMac->pmm.gPmmTim.pTim = NULL; + return eSIR_FAILURE; + } + pMac->lim.deauthMsgCnt = 0; + pMac->lim.retryPacketCnt = 0; + pMac->lim.gLimIbssRetryCnt = 0; + + /* + * peOpen is successful by now, so it is right time to initialize + * MTRACE for PE module. if LIM_TRACE_RECORD is not defined in build file + * then nothing will be logged for PE module. + */ +#ifdef LIM_TRACE_RECORD + MTRACE(limTraceInit(pMac)); +#endif + lim_register_debug_callback(); + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn peClose +\brief will be called in close sequence from macClose +\param tpAniSirGlobal pMac +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus peClose(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + if (ANI_DRIVER_TYPE(pMac) == eDRIVER_TYPE_MFG) + return eSIR_SUCCESS; + + vos_spin_lock_destroy( &pMac->sys.lock ); + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + peDeleteSession(pMac,&pMac->lim.gpSession[i]); + } + } + vos_mem_vfree(pMac->lim.limTimers.gpLimCnfWaitTimer); + pMac->lim.limTimers.gpLimCnfWaitTimer = NULL; + vos_mem_vfree(pMac->lim.gpSession); + pMac->lim.gpSession = NULL; + + vos_mem_free(pMac->pmm.gPmmTim.pTim); + pMac->pmm.gPmmTim.pTim = NULL; + if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pMac->lim.lkPeGlobalLock ) ) ) + { + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn peStart +\brief will be called in start sequence from macStart +\param tpAniSirGlobal pMac +\return none + -------------------------------------------------------------*/ + +tSirRetStatus peStart(tpAniSirGlobal pMac) +{ + tSirRetStatus status = eSIR_SUCCESS; + + status = limInitialize(pMac); +#if defined(ANI_LOGDUMP) + limDumpInit(pMac); +#endif //#if defined(ANI_LOGDUMP) + + return status; +} + +/** ------------------------------------------------------------- +\fn peStop +\brief will be called in stop sequence from macStop +\param tpAniSirGlobal pMac +\return none + -------------------------------------------------------------*/ + +void peStop(tpAniSirGlobal pMac) +{ + limCleanup(pMac); + SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE); + return; +} + +/** ------------------------------------------------------------- +\fn peFreeMsg +\brief Called by VOS scheduler (function vos_sched_flush_mc_mqs) +\ to free a given PE message on the TX and MC thread. +\ This happens when there are messages pending in the PE +\ queue when system is being stopped and reset. +\param tpAniSirGlobal pMac +\param tSirMsgQ pMsg +\return none +-----------------------------------------------------------------*/ +v_VOID_t peFreeMsg( tpAniSirGlobal pMac, tSirMsgQ* pMsg) +{ + if (pMsg != NULL) + { + if (NULL != pMsg->bodyptr) + { + if (SIR_BB_XPORT_MGMT_MSG == pMsg->type) + { + vos_pkt_return_packet((vos_pkt_t *)pMsg->bodyptr); + } + else + { + vos_mem_free((v_VOID_t*)pMsg->bodyptr); + } + } + pMsg->bodyptr = 0; + pMsg->bodyval = 0; + pMsg->type = 0; + } + return; +} + + +/** + * The function checks if a particular timer should be allowed + * into LIM while device is sleeping + */ +tANI_U8 limIsTimerAllowedInPowerSaveState(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tANI_U8 retStatus = TRUE; + + if(!limIsSystemInActiveState(pMac)) + { + switch(pMsg->type) + { + /* Don't allow following timer messages if in sleep */ + case SIR_LIM_MIN_CHANNEL_TIMEOUT: + case SIR_LIM_MAX_CHANNEL_TIMEOUT: + case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT: + retStatus = FALSE; + break; + /* May allow following timer messages in sleep mode */ + + /* Safe to allow as of today, this triggers background scan + * which will not be started if the device is in power-save mode + * might need to block in the future if we decide to implement + * spectrum management + */ + case SIR_LIM_QUIET_TIMEOUT: + + /* Safe to allow as of today, this triggers background scan + * which will not be started if the device is in power-save mode + * might need to block in the future if we decide to implement + * spectrum management + */ + case SIR_LIM_QUIET_BSS_TIMEOUT: + + /* Safe to allow this timermessage, triggers background scan + * which is blocked in sleep mode + */ + case SIR_LIM_CHANNEL_SCAN_TIMEOUT: + + /* Safe to allow this timer, since, while in IMPS this timer will not + * be started. In case of BMPS sleep, SoftMAC handles the heart-beat + * when heart-beat control is handled back to PE, device would have + * already woken-up due to EXIT_BMPS_IND mesage from SoftMAC + */ + case SIR_LIM_HEART_BEAT_TIMEOUT: + case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT: + + /* Safe to allow, PE is not handling this message as of now. May need + * to block it, basically, free the buffer and restart the timer + */ + case SIR_LIM_REASSOC_FAIL_TIMEOUT: + case SIR_LIM_JOIN_FAIL_TIMEOUT: + case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: + case SIR_LIM_ASSOC_FAIL_TIMEOUT: + case SIR_LIM_AUTH_FAIL_TIMEOUT: + case SIR_LIM_ADDTS_RSP_TIMEOUT: + case SIR_LIM_AUTH_RETRY_TIMEOUT: + retStatus = TRUE; + break; + + /* by default allow rest of messages */ + default: + retStatus = TRUE; + break; + + + } + } + + return retStatus; + +} + + + +/** + * limPostMsgApi() + * + *FUNCTION: + * This function is called from other thread while posting a + * message to LIM message Queue gSirLimMsgQ. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg - Pointer to the message structure + * @return None + */ + +tANI_U32 +limPostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + return vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg); + + +} /*** end limPostMsgApi() ***/ + +/** + * limPostMsgApiHighPri() + * + * FUNCTION: + * This function is called from other thread while posting a + * message to LIM message Queue gSirLimMsgQ. + * + * LOGIC: + * NA + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg - Pointer to the message structure + * @return None + */ + +tANI_U32 +limPostMsgApiHighPri(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + return vos_mq_post_message_high_pri(VOS_MQ_ID_PE, (vos_msg_t *) pMsg); + + +} /*** end limPostMsgApi() ***/ + + +/*-------------------------------------------------------------------------- + + \brief pePostMsgApi() - A wrapper function to post message to Voss msg queues + + This function can be called by legacy code to post message to voss queues OR + legacy code may keep on invoking 'limPostMsgApi' to post the message to voss queue + for dispatching it later. + + \param pMac - Pointer to Global MAC structure + \param pMsg - Pointer to the message structure + + \return tANI_U32 - TX_SUCCESS for success. + + --------------------------------------------------------------------------*/ + +tSirRetStatus pePostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + return (tSirRetStatus)limPostMsgApi(pMac, pMsg); +} + +/*-------------------------------------------------------------------------- + + \brief peProcessMessages() - Message Processor for PE + + Voss calls this function to dispatch the message to PE + + \param pMac - Pointer to Global MAC structure + \param pMsg - Pointer to the message structure + + \return tANI_U32 - TX_SUCCESS for success. + + --------------------------------------------------------------------------*/ + +tSirRetStatus peProcessMessages(tpAniSirGlobal pMac, tSirMsgQ* pMsg) +{ + if(pMac->gDriverType == eDRIVER_TYPE_MFG) + { + return eSIR_SUCCESS; + } + /** + * If the Message to be handled is for CFG Module call the CFG Msg Handler and + * for all the other cases post it to LIM + */ + if ( SIR_CFG_PARAM_UPDATE_IND != pMsg->type && IS_CFG_MSG(pMsg->type)) + cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr); + else + limMessageProcessor(pMac, pMsg); + return eSIR_SUCCESS; +} + +#define RSRVD_MGMT_RX_PACKETS 10 + +// --------------------------------------------------------------------------- +/** + * peHandleMgmtFrame + * + * FUNCTION: + * Process the Management frames from TL + * + * LOGIC: + * + * ASSUMPTIONS: TL sends the packet along with the VOS GlobalContext + * + * NOTE: + * + * @param pvosGCtx Global Vos Context + * @param vossBuff Packet + * @return None + */ + +VOS_STATUS peHandleMgmtFrame( v_PVOID_t pvosGCtx, v_PVOID_t vosBuff) +{ + tpAniSirGlobal pMac; + tpSirMacMgmtHdr mHdr; + tSirMsgQ msg; + vos_pkt_t *pVosPkt; + VOS_STATUS vosStatus; + v_U8_t *pRxPacketInfo; + + pVosPkt = (vos_pkt_t *)vosBuff; + if (NULL == pVosPkt) + { + return VOS_STATUS_E_FAILURE; + } + + pMac = (tpAniSirGlobal)vos_get_context(VOS_MODULE_ID_PE, pvosGCtx); + if (NULL == pMac) + { + // cannot log a failure without a valid pMac + vos_pkt_return_packet(pVosPkt); + return VOS_STATUS_E_FAILURE; + } + + vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (void *)&pRxPacketInfo, VOS_FALSE ); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + vos_pkt_return_packet(pVosPkt); + return VOS_STATUS_E_FAILURE; + } + + + // + // The MPDU header is now present at a certain "offset" in + // the BD and is specified in the BD itself + // + mHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + if(mHdr->fc.type == SIR_MAC_MGMT_FRAME) + { + PELOG1(limLog( pMac, LOG1, + FL ( "RxBd=%p mHdr=%p Type: %d Subtype: %d Sizes:FC%d Mgmt%d"), + pRxPacketInfo, mHdr, mHdr->fc.type, mHdr->fc.subType, sizeof(tSirMacFrameCtl), sizeof(tSirMacMgmtHdr) );) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) + limLog(pMac, LOG1, FL("roamCandidateInd %d"), + WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)); + + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + limLog(pMac, LOG1, FL("offloadScanLearn %d"), + WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)); +#endif + } + + + // Forward to MAC via mesg = SIR_BB_XPORT_MGMT_MSG + msg.type = SIR_BB_XPORT_MGMT_MSG; + msg.bodyptr = vosBuff; + msg.bodyval = 0; + + vos_spin_lock_acquire( &pMac->sys.lock ); + if( pMac->sys.gSysBbtPendingMgmtCount > (vos_pkt_get_num_of_rx_raw_pkts()/4) ) + { + vos_spin_lock_release( &pMac->sys.lock ); + // drop all management packets + limLog( pMac, LOGW, + FL ( "Management queue 1/4th full, dropping management packets" )); + vos_pkt_return_packet(pVosPkt); + return VOS_STATUS_SUCCESS; + } + + if( pMac->sys.gSysBbtPendingMgmtCount > ( vos_pkt_get_num_of_rx_raw_pkts()/4 + - RSRVD_MGMT_RX_PACKETS )) + { + // drop all probereq, proberesp and beacons + if( mHdr->fc.subType == SIR_MAC_MGMT_BEACON || mHdr->fc.subType == + SIR_MAC_MGMT_PROBE_REQ || mHdr->fc.subType == SIR_MAC_MGMT_PROBE_RSP ) + { + vos_spin_lock_release( &pMac->sys.lock ); + limLog( pMac, LOGW, + FL ( "Dropping probe req, probe resp or beacon" )); + vos_pkt_return_packet(pVosPkt); + return VOS_STATUS_SUCCESS; + } + } + pMac->sys.gSysBbtPendingMgmtCount++; + vos_spin_lock_release( &pMac->sys.lock ); + + if( eSIR_SUCCESS != sysBbtProcessMessageCore( pMac, + &msg, + mHdr->fc.type, + mHdr->fc.subType )) + { + vos_pkt_return_packet(pVosPkt); + + /* Decrement gSysBbtPendingMgmtCount if packet + * is dropped before posting to LIM + */ + limDecrementPendingMgmtCount(pMac); + limLog( pMac, LOGW, + FL ( "sysBbtProcessMessageCore failed to process SIR_BB_XPORT_MGMT_MSG" )); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +// --------------------------------------------------------------------------- +/** + * peRegisterTLHandle + * + * FUNCTION: + * Registers the Handler which, process the Management frames from TL + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @return None + */ + +void peRegisterTLHandle(tpAniSirGlobal pMac) +{ + v_PVOID_t pvosGCTx; + VOS_STATUS retStatus; + + pvosGCTx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + + retStatus = WLANTL_RegisterMgmtFrmClient(pvosGCTx, peHandleMgmtFrame); + + if (retStatus != VOS_STATUS_SUCCESS) + limLog( pMac, LOGP, FL("Registering the PE Handle with TL has failed bailing out...")); + +} + + +/** + * limIsSystemInScanState() + * + *FUNCTION: + * This function is called by various MAC software modules to + * determine if System is in Scan/Learn state + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return true - System is in Scan/Learn state + * false - System is NOT in Scan/Learn state + */ + +tANI_U8 +limIsSystemInScanState(tpAniSirGlobal pMac) +{ + switch (pMac->lim.gLimSmeState) + { + case eLIM_SME_CHANNEL_SCAN_STATE: + case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: + case eLIM_SME_LINK_EST_WT_SCAN_STATE: + case eLIM_SME_WT_SCAN_STATE: + // System is in Learn mode + return true; + + default: + // System is NOT in Learn mode + return false; + } +} /*** end limIsSystemInScanState() ***/ + + + +/** + * limIsSystemInActiveState() + * + *FUNCTION: + * This function is called by various MAC software modules to + * determine if System is in Active/Wakeup state + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return true - System is in Active state + * false - System is not in Active state + */ + +tANI_U8 limIsSystemInActiveState(tpAniSirGlobal pMac) +{ + switch (pMac->pmm.gPmmState) + { + case ePMM_STATE_BMPS_WAKEUP: + case ePMM_STATE_IMPS_WAKEUP: + case ePMM_STATE_READY: + // System is in Active mode + return true; + default: + return false; + // System is NOT in Active mode + } +} + + + + + +/** +*\brief limReceivedHBHandler() +* +* This function is called by schBeaconProcess() upon +* receiving a Beacon on STA. This also gets called upon +* receiving Probe Response after heat beat failure is +* detected. +* +* param pMac - global mac structure +* param channel - channel number indicated in Beacon, Probe Response +* return - none +*/ + + +void +limReceivedHBHandler(tpAniSirGlobal pMac, tANI_U8 channelId, tpPESession psessionEntry) +{ + if((channelId == 0 ) || (channelId == psessionEntry->currentOperChannel) ) + psessionEntry->LimRxedBeaconCntDuringHB++; + + pMac->pmm.inMissedBeaconScenario = FALSE; +} /*** end limReceivedHBHandler() ***/ + + + +#if 0 +void limResetHBPktCount(tpPESession psessionEntry) +{ + psessionEntry->LimRxedBeaconCntDuringHB = 0; +} +#endif + + +/* + * limProcessWdsInfo() + * + *FUNCTION: + * This function is called from schBeaconProcess in BP + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * @param propIEInfo - proprietary IE info + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * + *RETURNS: + * + */ + +void limProcessWdsInfo(tpAniSirGlobal pMac, + tSirPropIEStruct propIEInfo) +{ +} + + + +/** + * limInitWdsInfoParams() + * + *FUNCTION: + * This function is called while processing + * START_BSS/JOIN/REASSOC_REQ to initialize WDS info + * ind/set related parameters. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +void +limInitWdsInfoParams(tpAniSirGlobal pMac) +{ + pMac->lim.gLimWdsInfo.wdsLength = 0; + pMac->lim.gLimNumWdsInfoInd = 0; + pMac->lim.gLimNumWdsInfoSet = 0; +} /*** limInitWdsInfoParams() ***/ + + +/** ------------------------------------------------------------- +\fn limUpdateOverlapStaParam +\brief Updates overlap cache and param data structure +\param tpAniSirGlobal pMac +\param tSirMacAddr bssId +\param tpLimProtStaParams pStaParams +\return None + -------------------------------------------------------------*/ +void +limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams) +{ + int i; + if (!pStaParams->numSta) + { + vos_mem_copy(pMac->lim.protStaOverlapCache[0].addr, + bssId, + sizeof(tSirMacAddr)); + pMac->lim.protStaOverlapCache[0].active = true; + + pStaParams->numSta = 1; + + return; + } + + for (i=0; ilim.protStaOverlapCache[i].active) + { + if (vos_mem_compare( pMac->lim.protStaOverlapCache[i].addr, + bssId, + sizeof(tSirMacAddr))) { + return; } + } + else + break; + } + + if (i == LIM_PROT_STA_OVERLAP_CACHE_SIZE) + { + PELOG1(limLog(pMac, LOGW, FL("Overlap cache is full"));) + } + else + { + vos_mem_copy(pMac->lim.protStaOverlapCache[i].addr, + bssId, + sizeof(tSirMacAddr)); + pMac->lim.protStaOverlapCache[i].active = true; + + pStaParams->numSta++; + } +} + + +/** + * limHandleIBSScoalescing() + * + *FUNCTION: + * This function is called upon receiving Beacon/Probe Response + * while operating in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pRxPacketInfo - Pointer to RX packet info structure + * + * @return Status whether to process or ignore received Beacon Frame + */ + +tSirRetStatus +limHandleIBSScoalescing( + tpAniSirGlobal pMac, + tpSchBeaconStruct pBeacon, + tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tSirRetStatus retCode; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + if ( (!pBeacon->capabilityInfo.ibss) || + ( psessionEntry->privacy != + (tANI_U8)pBeacon->capabilityInfo.privacy ) || + (limCmpSSid(pMac, &pBeacon->ssId,psessionEntry) != true) || + (psessionEntry->currentOperChannel != pBeacon->channelNumber) ) + /* Received SSID does not match => Ignore received Beacon frame. */ + retCode = eSIR_LIM_IGNORE_BEACON; + else + { + tANI_U32 ieLen; + tANI_U16 tsfLater; + tANI_U8 *pIEs; + ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + tsfLater = WDA_GET_RX_TSF_LATER(pRxPacketInfo); + pIEs = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + limLog(pMac, LOG1, FL("BEFORE Coalescing tsfLater val :%d"), tsfLater); + retCode = limIbssCoalesce(pMac, pHdr, pBeacon, pIEs, ieLen, tsfLater,psessionEntry); + } + return retCode; +} /*** end limHandleIBSScoalescing() ***/ + +tAniBool limEncTypeMatched(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon, + tpPESession pSession) +{ + if (!pBeacon || !pSession) + return eSIR_FALSE; + + limLog(pMac, LOG1, + FL("Beacon/Probe:: Privacy :%d WPA Present:%d RSN Present: %d"), + pBeacon->capabilityInfo.privacy, pBeacon->wpaPresent, + pBeacon->rsnPresent); + limLog(pMac, LOG1, + FL("pSession:: Privacy :%d EncyptionType: %d WPS %d OSEN %d"), + SIR_MAC_GET_PRIVACY(pSession->limCurrentBssCaps), + pSession->encryptType, pSession->bWPSAssociation, + pSession->bOSENAssociation); + + /* This is handled by sending probe req due to IOT issues so return TRUE + */ + if ( (pBeacon->capabilityInfo.privacy) != + SIR_MAC_GET_PRIVACY(pSession->limCurrentBssCaps)) + { + limLog(pMac, LOG1, FL("Return for Privacy bit miss match, As " + "for this driver need to send the probe request to handle" + " IOT issues ")); + return eSIR_TRUE; + } + + /*Open*/ + if( (pBeacon->capabilityInfo.privacy == 0) && + (pSession->encryptType == eSIR_ED_NONE)) + return eSIR_TRUE; + + /* WEP */ + if ( (pBeacon->capabilityInfo.privacy == 1) && (pBeacon->wpaPresent == 0) && + (pBeacon->rsnPresent == 0) && + ( ( pSession->encryptType == eSIR_ED_WEP40 ) || + ( pSession->encryptType == eSIR_ED_WEP104 ) +#ifdef FEATURE_WLAN_WAPI + || ( pSession->encryptType == eSIR_ED_WPI ) +#endif + )) + return eSIR_TRUE; + + /* WPA OR RSN*/ + if ( (pBeacon->capabilityInfo.privacy == 1) && + ( (pBeacon->wpaPresent == 1) || + ( pBeacon->rsnPresent == 1)) && + ( (pSession->encryptType == eSIR_ED_TKIP) || + (pSession->encryptType == eSIR_ED_CCMP) || + (pSession->encryptType == eSIR_ED_AES_128_CMAC))) + return eSIR_TRUE; + + /* For HS2.0, RSN ie is not present + * in beacon. Therefore no need to + * check for security type in case + * OSEN session. + * For WPS registration session no need to detect + * security mismatch as it wont match and + * driver may end up sending probe request without + * WPS IE during WPS registartion process. + */ + /*TODO: AP capability mismatch + * is not checked here because + * no logic for beacon parsing + * is avilable for HS2.0. + */ + if (pSession->bOSENAssociation || + pSession->bWPSAssociation) + return eSIR_TRUE; + + return eSIR_FALSE; +} + + +/** + * limDetectChangeInApCapabilities() + * + *FUNCTION: + * This function is called while SCH is processing + * received Beacon from AP on STA to detect any + * change in AP's capabilities. If there any change + * is detected, Roaming is informed of such change + * so that it can trigger reassociation. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * Notification is enabled for STA product only since + * it is not a requirement on BP side. + * + * @param pMac Pointer to Global MAC structure + * @param pBeacon Pointer to parsed Beacon structure + * @return None + */ + +void +limDetectChangeInApCapabilities(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBeacon, + tpPESession psessionEntry) +{ + tANI_U8 len; + tSirSmeApNewCaps apNewCaps; + tANI_U8 newChannel; + tSirRetStatus status = eSIR_SUCCESS; + tAniBool securityCapsMatched = eSIR_TRUE; + + apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo); + newChannel = (tANI_U8) pBeacon->channelNumber; + + securityCapsMatched = limEncTypeMatched(pMac, pBeacon, psessionEntry); + + if ( ( false == psessionEntry->limSentCapsChangeNtf ) && + ( ( ( !limIsNullSsid(&pBeacon->ssId) ) && + ( false == limCmpSSid(pMac, &pBeacon->ssId, psessionEntry) ) ) || + ( (SIR_MAC_GET_ESS(apNewCaps.capabilityInfo) != + SIR_MAC_GET_ESS(psessionEntry->limCurrentBssCaps) ) || + ( SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) != + SIR_MAC_GET_PRIVACY(psessionEntry->limCurrentBssCaps) ) || + ( SIR_MAC_GET_SHORT_PREAMBLE(apNewCaps.capabilityInfo) != + SIR_MAC_GET_SHORT_PREAMBLE(psessionEntry->limCurrentBssCaps) ) || + ( SIR_MAC_GET_QOS(apNewCaps.capabilityInfo) != + SIR_MAC_GET_QOS(psessionEntry->limCurrentBssCaps) ) || + ( newChannel != psessionEntry->currentOperChannel ) || + (eSIR_FALSE == securityCapsMatched) + ) ) ) + { + if ( false == psessionEntry->fWaitForProbeRsp ) + { + /* If Beacon capabilities is not matching with the current capability, + * then send unicast probe request to AP and take decision after + * receiving probe response */ + if ( true == psessionEntry->fIgnoreCapsChange ) + { + limLog(pMac, LOGW, FL("Ignoring the Capability change as it is false alarm")); + return; + } + psessionEntry->fWaitForProbeRsp = true; + limLog(pMac, LOGW, FL("AP capabilities are not matching," + "sending directed probe request.. ")); + status = limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId, + psessionEntry->currentOperChannel,psessionEntry->selfMacAddr, + psessionEntry->dot11mode, 0, NULL); + + if ( eSIR_SUCCESS != status ) + { + limLog(pMac, LOGE, FL("send ProbeReq failed")); + psessionEntry->fWaitForProbeRsp = false; + } + return; + } + /** + * BSS capabilities have changed. + * Inform Roaming. + */ + len = sizeof(tSirMacCapabilityInfo) + + sizeof(tSirMacAddr) + sizeof(tANI_U8) + + 3 * sizeof(tANI_U8) + // reserved fields + pBeacon->ssId.length + 1; + + vos_mem_copy(apNewCaps.bssId, + psessionEntry->bssId, + sizeof(tSirMacAddr)); + if (newChannel != psessionEntry->currentOperChannel) + { + PELOGE(limLog(pMac, LOGE, FL("Channel Change from %d --> %d - " + "Ignoring beacon!"), + psessionEntry->currentOperChannel, newChannel);) + return; + } + + /** + * When Cisco 1262 Enterprise APs are configured with WPA2-PSK with + * AES+TKIP Pairwise ciphers and WEP-40 Group cipher, they do not set + * the privacy bit in Beacons (wpa/rsnie is still present in beacons), + * the privacy bit is set in Probe and association responses. + * Due to this anomaly, we detect a change in + * AP capabilities when we receive a beacon after association and + * disconnect from the AP. The following check makes sure that we can + * connect to such APs + */ + else if ((SIR_MAC_GET_PRIVACY(apNewCaps.capabilityInfo) == 0) && + (pBeacon->rsnPresent || pBeacon->wpaPresent)) + { + PELOGE(limLog(pMac, LOGE, FL("BSS Caps (Privacy) bit 0 in beacon," + " but WPA or RSN IE present, Ignore Beacon!"));) + return; + } + else + apNewCaps.channelId = psessionEntry->currentOperChannel; + vos_mem_copy((tANI_U8 *) &apNewCaps.ssId, + (tANI_U8 *) &pBeacon->ssId, + pBeacon->ssId.length + 1); + + psessionEntry->fIgnoreCapsChange = false; + psessionEntry->fWaitForProbeRsp = false; + psessionEntry->limSentCapsChangeNtf = true; + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_AP_CAPS_CHANGED, + (tANI_U32 *) &apNewCaps, + len, psessionEntry->smeSessionId); + } + else if ( true == psessionEntry->fWaitForProbeRsp ) + { + /* Only for probe response frames and matching capabilities the control + * will come here. If beacon is with broadcast ssid then fWaitForProbeRsp + * will be false, the control will not come here*/ + + limLog(pMac, LOG1, FL("capabilities in probe response are" + "matching with the current setting," + "Ignoring subsequent capability" + "mismatch")); + psessionEntry->fIgnoreCapsChange = true; + psessionEntry->fWaitForProbeRsp = false; + } + +} /*** limDetectChangeInApCapabilities() ***/ + + + + +// --------------------------------------------------------------------- +/** + * limUpdateShortSlot + * + * FUNCTION: + * Enable/Disable short slot + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param enable Flag to enable/disable short slot + * @return None + */ + +tSirRetStatus limUpdateShortSlot(tpAniSirGlobal pMac, tpSirProbeRespBeacon pBeacon, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + + tSirSmeApNewCaps apNewCaps; + tANI_U32 nShortSlot; + tANI_U32 val = 0; + tANI_U32 phyMode; + + // Check Admin mode first. If it is disabled just return + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("cfg get WNI_CFG_11G_SHORT_SLOT_TIME failed")); + return eSIR_FAILURE; + } + if (val == false) + return eSIR_SUCCESS; + + // Check for 11a mode or 11b mode. In both cases return since slot time is constant and cannot/should not change in beacon + limGetPhyMode(pMac, &phyMode, psessionEntry); + if ((phyMode == WNI_CFG_PHY_MODE_11A) || (phyMode == WNI_CFG_PHY_MODE_11B)) + return eSIR_SUCCESS; + + apNewCaps.capabilityInfo = limGetU16((tANI_U8 *) &pBeacon->capabilityInfo); + + // Earlier implementation: determine the appropriate short slot mode based on AP advertised modes + // when erp is present, apply short slot always unless, prot=on && shortSlot=off + // if no erp present, use short slot based on current ap caps + + // Issue with earlier implementation : Cisco 1231 BG has shortSlot = 0, erpIEPresent and useProtection = 0 (Case4); + + //Resolution : always use the shortSlot setting the capability info to decide slot time. + // The difference between the earlier implementation and the new one is only Case4. + /* + ERP IE Present | useProtection | shortSlot = QC STA Short Slot + Case1 1 1 1 1 //AP should not advertise this combination. + Case2 1 1 0 0 + Case3 1 0 1 1 + Case4 1 0 0 0 + Case5 0 1 1 1 + Case6 0 1 0 0 + Case7 0 0 1 1 + Case8 0 0 0 0 + */ + nShortSlot = SIR_MAC_GET_SHORT_SLOT_TIME(apNewCaps.capabilityInfo); + + if (nShortSlot != psessionEntry->shortSlotTimeSupported) + { + // Short slot time capability of AP has changed. Adopt to it. + limLog(pMac, LOG1, FL("Shortslot capability of AP changed: %d"), nShortSlot); + ((tpSirMacCapabilityInfo)&psessionEntry->limCurrentBssCaps)->shortSlotTime = (tANI_U16)nShortSlot; + psessionEntry->shortSlotTimeSupported = nShortSlot; + pBeaconParams->fShortSlotTime = (tANI_U8) nShortSlot; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + } + return eSIR_SUCCESS; +} + + + + + + + +/** ----------------------------------------------------------------- + \brief limHandleLowRssiInd() - handles low rssi indication + + This function process the SIR_HAL_LOW_RSSI_IND message from + HAL, and sends a eWNI_SME_LOW_RSSI_IND to CSR. + + \param pMac - global mac structure + + \return + + \sa + ----------------------------------------------------------------- */ +void limHandleLowRssiInd(tpAniSirGlobal pMac) +{ +#if 0 //RSSI related indications will now go to TL and not PE + if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) || + (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)|| + (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) ) + { + PELOG1(limLog(pMac, LOG1, FL("Sending LOW_RSSI_IND to SME "));) + limSendSmeRsp(pMac, eWNI_SME_LOW_RSSI_IND, eSIR_SME_SUCCESS, 0, 0); + } + else + { + limLog(pMac, LOGE, + FL("Received SIR_HAL_LOW_RSSI_IND while in incorrect state: %d"), + pMac->pmm.gPmmState); + } + return; +#endif +} + + +/** ----------------------------------------------------------------- + \brief limHandleBmpsStatusInd() - handles BMPS status indication + + This function process the SIR_HAL_BMPS_STATUS_IND message from HAL, + and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND + to SME with reason code 'eSME_EXIT_BMPS_IND_RCVD'. + + HAL sends this message when Firmware fails to enter BMPS mode 'AFTER' + HAL had already send PE a SIR_HAL_ENTER_BMPS_RSP with status + code "success". Hence, HAL needs to notify PE to get out of BMPS mode. + This message can also come from FW anytime after we have entered BMPS. + This means we should handle it in WoWL and UAPSD states as well + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ +void limHandleBmpsStatusInd(tpAniSirGlobal pMac) +{ + switch(pMac->pmm.gPmmState) + { + case ePMM_STATE_BMPS_SLEEP: + case ePMM_STATE_UAPSD_WT_SLEEP_RSP: + case ePMM_STATE_UAPSD_SLEEP: + case ePMM_STATE_UAPSD_WT_WAKEUP_RSP: + case ePMM_STATE_WOWLAN: + limLog(pMac, LOG1, FL("Sending EXIT_BMPS_IND to SME ")); + limSendExitBmpsInd(pMac, eSME_BMPS_STATUS_IND_RCVD); + break; + + default: + limLog(pMac, LOGE, + FL("Received SIR_HAL_BMPS_STATUS_IND while in incorrect state: %d"), + pMac->pmm.gPmmState); + break; + } + return; +} + +#ifdef WLAN_FEATURE_APFIND +void limHandleAPFindInd(tpAniSirGlobal pMac) +{ + tANI_S8 pe_sessionid = -1; + /* Find STA connection session */ + pe_sessionid = limGetInfraSessionId(pMac); + if (pe_sessionid != -1) + limTearDownLinkWithAp(pMac, + pe_sessionid, + eSIR_BEACON_MISSED); + else + limLog(pMac, LOGE, + FL("session id doesn't exist for infra")); +} +#endif + +/** ----------------------------------------------------------------- + \brief limHandleMissedBeaconInd() - handles missed beacon indication + + This function process the SIR_HAL_MISSED_BEACON_IND message from HAL, + and invokes limSendExitBmpsInd( ) to send an eWNI_PMC_EXIT_BMPS_IND + to SME with reason code 'eSME_MISSED_BEACON_IND_RCVD'. + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ +void limHandleMissedBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + tpSirSmeMissedBeaconInd pSirMissedBeaconInd = + (tpSirSmeMissedBeaconInd)pMsg->bodyptr; + tpPESession psessionEntry = peFindSessionByBssIdx(pMac,pSirMissedBeaconInd->bssIdx); + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given BSSIdx:%d"), + pSirMissedBeaconInd->bssIdx); + return; + } +#endif + if (pMac->pmm.inMissedBeaconScenario == TRUE) { + limLog(pMac, LOGW, + FL("beacon miss handling is already going on for BSSIdx:%d"), + pSirMissedBeaconInd->bssIdx); + return; + } + if ( (pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) || + (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)|| + (pMac->pmm.gPmmState == ePMM_STATE_WOWLAN) ) + { + pMac->pmm.inMissedBeaconScenario = TRUE; + PELOGE(limLog(pMac, LOGE, + FL("Sending EXIT_BMPS_IND to SME due to Missed beacon from FW"));) + limSendExitBmpsInd(pMac, eSME_MISSED_BEACON_IND_RCVD); + } +/* ACTIVE_MODE_HB_OFFLOAD */ +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + else if(((pMac->pmm.gPmmState == ePMM_STATE_READY) || + (pMac->pmm.gPmmState == ePMM_STATE_BMPS_WAKEUP)) && + (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + pMac->pmm.inMissedBeaconScenario = TRUE; + PELOGE(limLog(pMac, LOGE, FL("Received Heart Beat Failure"));) + limMissedBeaconInActiveMode(pMac, psessionEntry); + } +#endif + else + { + limLog(pMac, LOGE, + FL("Received SIR_HAL_MISSED_BEACON_IND while in incorrect state: %d"), + pMac->pmm.gPmmState); + } + return; +} + + +void limUpdateLostLinkParams(tpAniSirGlobal pMac, + tpPESession psessionEntry, tANI_U8 *pRxPacketInfo) +{ + tpSirSmeLostLinkParamsInd pSmeLostLinkParams; + tSirMsgQ mmhMsg; + if (NULL == pRxPacketInfo) + { + return; + } + pSmeLostLinkParams = + (tpSirSmeLostLinkParamsInd)vos_mem_malloc(sizeof(tSirSmeLostLinkParamsInd)); + if (NULL == pSmeLostLinkParams) + { + limLog(pMac, LOGP, + FL("Failed to alloc mem of size %zu for tSirSmeLostLinkParamsInd"), + sizeof(*pSmeLostLinkParams)); + return; + } + vos_mem_set(pSmeLostLinkParams, sizeof(tSirSmeLostLinkParamsInd), 0); + pSmeLostLinkParams->messageType = eWNI_SME_LOST_LINK_PARAMS_IND; + pSmeLostLinkParams->length = sizeof(tSirSmeLostLinkParamsInd); + pSmeLostLinkParams->sessionId = psessionEntry->smeSessionId; + pSmeLostLinkParams->info.bssIdx = psessionEntry->bssIdx; + + /* + * Since FW adds 100 to RSSI, here also we are adding 100 so that + * HDD has common logic to subtract 100 from RSSI received + */ + pSmeLostLinkParams->info.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo) + 100; + vos_mem_copy(pSmeLostLinkParams->info.selfMacAddr, + psessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + pSmeLostLinkParams->info.lastDataRate = 0; + pSmeLostLinkParams->info.linkFlCnt = 0; + pSmeLostLinkParams->info.linkFlTx = 0; + pSmeLostLinkParams->info.rsvd1 = 0; + pSmeLostLinkParams->info.rsvd2 = 0; + + mmhMsg.type = eWNI_SME_LOST_LINK_PARAMS_IND; + mmhMsg.bodyptr = pSmeLostLinkParams; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +/** ----------------------------------------------------------------- + \brief limProcessLostLinkParamsInd() - handles lost link params indication + + This function process the SIR_HAL_LOST_LINK_PARAMS_IND message from HAL, + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ + +void limProcessLostLinkParamsInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeLostLinkParamsInd pSmeLostLinkParamsInd; + tpSirSmeLostLinkParamsInd pLostLInkParamsInd = (tpSirSmeLostLinkParamsInd)pMsg->bodyptr; + tpPESession psessionEntry ; + tSirMsgQ mmhMsg; + + if (NULL == pLostLInkParamsInd) + { + limLog(pMac, LOGE, + FL("pLostLInkParamsInd is NULL")); + return; + } + + psessionEntry = peFindSessionByBssIdx(pMac,pLostLInkParamsInd->info.bssIdx); + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for bdssIdx : %d"), + pLostLInkParamsInd->info.bssIdx); + + return; + } + pSmeLostLinkParamsInd = vos_mem_malloc(sizeof(tSirSmeLostLinkParamsInd)); + if (pSmeLostLinkParamsInd == NULL) + { + limLog(pMac, LOGP, + FL("memory allocate failed for eWNI_SME_LOST_LINK_PARAMD_IND")); + return; + } + pSmeLostLinkParamsInd->messageType = eWNI_SME_LOST_LINK_PARAMS_IND; + pSmeLostLinkParamsInd->length = sizeof(tSirSmeLostLinkParamsInd); + pSmeLostLinkParamsInd->sessionId = psessionEntry->smeSessionId; + pSmeLostLinkParamsInd->info.bssIdx = pLostLInkParamsInd->info.bssIdx; + pSmeLostLinkParamsInd->info.rssi = pLostLInkParamsInd->info.rssi; + vos_mem_copy(pSmeLostLinkParamsInd->info.selfMacAddr, + pLostLInkParamsInd->info.selfMacAddr, + sizeof(tSirMacAddr)); + pSmeLostLinkParamsInd->info.linkFlCnt = pLostLInkParamsInd->info.linkFlCnt; + pSmeLostLinkParamsInd->info.linkFlTx = pLostLInkParamsInd->info.linkFlTx; + pSmeLostLinkParamsInd->info.lastDataRate = pLostLInkParamsInd->info.lastDataRate; + pSmeLostLinkParamsInd->info.rsvd1 = pLostLInkParamsInd->info.rsvd1; + pSmeLostLinkParamsInd->info.rsvd2 = pLostLInkParamsInd->info.rsvd2; + + mmhMsg.type = eWNI_SME_LOST_LINK_PARAMS_IND; + mmhMsg.bodyptr = pSmeLostLinkParamsInd; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + +/** ----------------------------------------------------------------- + \brief limMicFailureInd() - handles mic failure indication + + This function process the SIR_HAL_MIC_FAILURE_IND message from HAL, + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ +void limMicFailureInd(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeMicFailureInd pSirSmeMicFailureInd; + tpSirSmeMicFailureInd pSirMicFailureInd = (tpSirSmeMicFailureInd)pMsg->bodyptr; + tSirMsgQ mmhMsg; + tpPESession psessionEntry ; + tANI_U8 sessionId; + + if((psessionEntry = peFindSessionByBssid(pMac,pSirMicFailureInd->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given BSSId")); + return; + } + + pSirSmeMicFailureInd = vos_mem_malloc(sizeof(tSirSmeMicFailureInd)); + if (NULL == pSirSmeMicFailureInd) + { + // Log error + limLog(pMac, LOGP, + FL("memory allocate failed for eWNI_SME_MIC_FAILURE_IND")); + return; + } + + pSirSmeMicFailureInd->messageType = eWNI_SME_MIC_FAILURE_IND; + pSirSmeMicFailureInd->length = sizeof(*pSirSmeMicFailureInd); + pSirSmeMicFailureInd->sessionId = psessionEntry->smeSessionId; + + vos_mem_copy(pSirSmeMicFailureInd->bssId, + pSirMicFailureInd->bssId, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.srcMacAddr, + pSirMicFailureInd->info.srcMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.taMacAddr, + pSirMicFailureInd->info.taMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.dstMacAddr, + pSirMicFailureInd->info.dstMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pSirSmeMicFailureInd->info.rxMacAddr, + pSirMicFailureInd->info.rxMacAddr, + sizeof(tSirMacAddr)); + + pSirSmeMicFailureInd->info.multicast = + pSirMicFailureInd->info.multicast; + + pSirSmeMicFailureInd->info.keyId= + pSirMicFailureInd->info.keyId; + + pSirSmeMicFailureInd->info.IV1= + pSirMicFailureInd->info.IV1; + + vos_mem_copy(pSirSmeMicFailureInd->info.TSC, + pSirMicFailureInd->info.TSC,SIR_CIPHER_SEQ_CTR_SIZE); + + mmhMsg.type = eWNI_SME_MIC_FAILURE_IND; + mmhMsg.bodyptr = pSirSmeMicFailureInd; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + +#ifdef WLAN_FEATURE_11W +/** -------------------------------------------------------------------- + * lim_is_assoc_req_for_drop()- function to decides to drop assoc\reassoc + * frames. + * @mac: pointer to global mac structure + * @rx_pkt_info: rx packet meta information + * + * This function is called before enqueuing the frame to PE queue to + * drop flooded assoc/reassoc frames getting into PE Queue. + * + * Return: true for dropping the frame otherwise false +----------------------------------------------------------------------*/ + +bool lim_is_assoc_req_for_drop(tpAniSirGlobal pMac, uint8_t *rx_pkt_info) +{ + tANI_U8 session_id; + tANI_U16 aid; + tpPESession session_entry; + tpSirMacMgmtHdr pMacHdr; + tpDphHashNode sta_ds; + + pMacHdr = WDA_GET_RX_MAC_HEADER(rx_pkt_info); + session_entry = peFindSessionByBssid(pMac, pMacHdr->bssId, &session_id); + if (!session_entry) + { + PELOG1(limLog(pMac, LOG1, + FL("session does not exist for given STA [%pM]"), + pMacHdr->sa);); + return false; + } + sta_ds = dphLookupHashEntry(pMac, pMacHdr->sa, &aid, + &session_entry->dph.dphHashTable); + if (!sta_ds) + { + PELOG1(limLog(pMac, LOG1, FL("pStaDs is NULL"));); + return false; + } + + if (!sta_ds->rmfEnabled) + return false; + + if (sta_ds->pmfSaQueryState == DPH_SA_QUERY_IN_PROGRESS) + return true; + + if (sta_ds->last_assoc_received_time && + ((vos_timer_get_system_time() - + sta_ds->last_assoc_received_time) < 1000)) + return true; + + sta_ds->last_assoc_received_time = vos_timer_get_system_time(); + return false; +} +#endif + +/** ---------------------------------------------------------------------- + *\brief limIsDeauthDiassocForDrop()..decides to drop deauth\diassoc frames. + *This function is called before enqueuing the frame to PE queue. + *This prevents deauth/diassoc frames getting into PE Queue. + +------------------------------------------------------------------------ */ + + +boolean limIsDeauthDiassocForDrop(tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo) +{ + tANI_U8 sessionId; + tANI_U16 aid; + tpPESession psessionEntry; + tpSirMacMgmtHdr pMacHdr; + tpDphHashNode pStaDs; + eHalStatus lock_status = eHAL_STATUS_SUCCESS; + boolean ret = FALSE; + + pMacHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + psessionEntry = peFindSessionByBssid(pMac,pMacHdr->bssId,&sessionId); + if (!psessionEntry) + { + PELOG1(sysLog(pMac, LOG1, + FL("session does not exist for given STA [%pM]"), + pMacHdr->sa);); + return TRUE; + } + + lock_status = pe_AcquireGlobalLock(&pMac->lim); + if (lock_status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("pe_AcquireGlobalLock error")); + return TRUE; + } + + pStaDs = dphLookupHashEntry(pMac, pMacHdr->sa, &aid, + &psessionEntry->dph.dphHashTable); + if (!pStaDs) + { + PELOG1(sysLog(pMac, LOG1,FL("pStaDs is NULL"));); + ret = TRUE; + goto end; + } +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + if ((WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & + DPU_FEEDBACK_UNPROTECTED_ERROR)) + { + /* It may be possible that deauth/diassoc frames from a spoofy + * AP is received. So if all further deauth/diassoc frmaes are + * dropped, then it may result in lossing deauth/diassoc frames + * from genuine AP. So process all deauth/diassoc frames with + * a time difference of 1 sec. + */ + if (vos_timer_get_system_time() - pStaDs->last_unprot_deauth_disassoc < 1000) + { + ret = TRUE; + goto end; + } + pStaDs->last_unprot_deauth_disassoc = + vos_timer_get_system_time(); + } +/* PMF enabed, Management frames are protected */ + else + { + if (pStaDs->proct_deauh_disassoc_cnt) + { + ret = TRUE; + goto end; + } + else + pStaDs->proct_deauh_disassoc_cnt++; + } + } + else +#endif +/* PMF disabled */ + { + if (pStaDs->isDisassocDeauthInProgress) + { + ret = TRUE; + goto end; + } + else + pStaDs->isDisassocDeauthInProgress++; + } + +end: + pe_ReleaseGlobalLock(&pMac->lim); + return ret; +} +/** ----------------------------------------------------------------- + \brief limIsPktCandidateForDrop() - decides whether to drop the frame or not + + This function is called before enqueuing the frame to PE queue for further processing. + This prevents unnecessary frames getting into PE Queue and drops them right away. + Frames will be droped in the following scenarios: + + - In Scan State, drop the frames which are not marked as scan frames + - In non-Scan state, drop the frames which are marked as scan frames. + - Drop INFRA Beacons and Probe Responses in IBSS Mode + - Drop the Probe Request in IBSS mode, if STA did not send out the last beacon + + \param pMac - global mac structure + \return - none + \sa + ----------------------------------------------------------------- */ + +tMgmtFrmDropReason limIsPktCandidateForDrop(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U32 subType) +{ + tANI_U32 framelen; + tANI_U8 *pBody; + tSirMacCapabilityInfo capabilityInfo; + + /* + * + * In scan mode, drop only Beacon/Probe Response which are NOT marked as scan-frames. + * In non-scan mode, drop only Beacon/Probe Response which are marked as scan frames. + * Allow other mgmt frames, they must be from our own AP, as we don't allow + * other than beacons or probe responses in scan state. + */ + if( (subType == SIR_MAC_MGMT_BEACON) || + (subType == SIR_MAC_MGMT_PROBE_RSP)) + { + if(pMac->pmm.inMissedBeaconScenario) + { + MTRACE(macTrace(pMac, TRACE_CODE_INFO_LOG, 0, eLOG_NODROP_MISSED_BEACON_SCENARIO)); + return eMGMT_DROP_NO_DROP; + } + if (limIsSystemInScanState(pMac)) + { + return eMGMT_DROP_NO_DROP; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + else if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) + { + return eMGMT_DROP_NO_DROP; + } +#endif +#ifdef WLAN_FEATURE_EXTSCAN + else if (WDA_GET_EXTSCANFULLSCANRESIND(pRxPacketInfo)) + { + return eMGMT_DROP_NO_DROP; + } +#endif + else if (WDA_IS_RX_IN_SCAN(pRxPacketInfo)) + { + return eMGMT_DROP_SCAN_MODE_FRAME; + } + } + + framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + /* Note sure if this is sufficient, basically this condition allows all probe responses and + * beacons from an infrastructure network + */ + *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET); + if(!capabilityInfo.ibss) + return eMGMT_DROP_NO_DROP; +#if 0 + //Allow the mgmt frames to be queued if STA not in IBSS mode. + if (pMac->lim.gLimSystemRole != eLIM_STA_IN_IBSS_ROLE) + return eMGMT_DROP_NO_DROP; +#endif + +#ifdef WLAN_FEATURE_11W + if ((subType == SIR_MAC_MGMT_ASSOC_REQ || + subType == SIR_MAC_MGMT_REASSOC_REQ) && + lim_is_assoc_req_for_drop(pMac, pRxPacketInfo)) + return eMGMT_DROP_SPURIOUS_FRAME; +#endif + //Drop INFRA Beacons and Probe Responses in IBSS Mode + if( (subType == SIR_MAC_MGMT_BEACON) || + (subType == SIR_MAC_MGMT_PROBE_RSP)) + { + //drop the frame if length is less than 12 + if(framelen < LIM_MIN_BCN_PR_LENGTH) + return eMGMT_DROP_INVALID_SIZE; + + *((tANI_U16*) &capabilityInfo) = sirReadU16(pBody+ LIM_BCN_PR_CAPABILITY_OFFSET); + + //This can be enhanced to even check the SSID before deciding to enque the frame. + if(capabilityInfo.ess) + return eMGMT_DROP_INFRA_BCN_IN_IBSS; + } + else if( (subType == SIR_MAC_MGMT_PROBE_REQ) && + (!WDA_GET_RX_BEACON_SENT(pRxPacketInfo))) + { + //Drop the Probe Request in IBSS mode, if STA did not send out the last beacon + //In IBSS, the node which sends out the beacon, is supposed to respond to ProbeReq + return eMGMT_DROP_NOT_LAST_IBSS_BCN; + } + + return eMGMT_DROP_NO_DROP; +} + +eHalStatus pe_AcquireGlobalLock( tAniSirLim *psPe) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if(psPe) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psPe->lkPeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} +eHalStatus pe_ReleaseGlobalLock( tAniSirLim *psPe) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + if(psPe) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psPe->lkPeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} +/** + * lim_process_sme_cap_tsf_req()- send cap tsf request to WDA + * Get bss_idx from PE and fill in cap tsf request. + * @pMac:Mac ctx + * @pMsgBuf: message buffer from sme + * Returns success on post to WDA, otherwise failure + */ + +tSirRetStatus lim_process_sme_cap_tsf_req(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + tSirCapTsfParams *pMsg = NULL; + tpPESession psessionEntry = NULL; + uint8_t sessionId; + tSirMsgQ msg; + tSirCapTsfParams *cap_tsf_params; + + pMsg = (tSirCapTsfParams*)pMsgBuf; + if (pMsg == NULL) { + limLog(pMac, LOGE, FL("NULL pMsg")); + return eSIR_FAILURE; + } + + psessionEntry = peFindSessionByBssid(pMac, pMsg->bssid, &sessionId); + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("NULL psessionEntry")); + return eSIR_FAILURE; + } + cap_tsf_params = (tSirCapTsfParams *) + vos_mem_malloc(sizeof(*cap_tsf_params)); + if (!cap_tsf_params) { + limLog(pMac, LOGE, FL(" Unable to allocate memory for cap tsf params")); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy (cap_tsf_params, pMsg, sizeof(*cap_tsf_params)); + cap_tsf_params->bss_idx = psessionEntry->bssIdx; + + msg.type = WDA_CAP_TSF_REQ; + msg.reserved = 0; + msg.bodyptr = cap_tsf_params; + msg.bodyval = 0; + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("lim_process_sme_cap_tsf_req failed\n")); + vos_mem_free(cap_tsf_params); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +/** + * lim_process_sme_get_tsf_req()- send get tsf request to WDA + * Get bss_idx from PE and fill in cap tsf request. + * @pMac:Mac ctx + * @pMsgBuf: message buffer from sme + * Returns success on post to WDA, otherwise failure + */ +tSirRetStatus lim_process_sme_get_tsf_req(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + tSirCapTsfParams *pMsg = NULL; + tpPESession psessionEntry = NULL; + uint8_t sessionId; + tSirMsgQ msg; + tSirCapTsfParams *get_tsf_params; + + pMsg = (tSirCapTsfParams*)pMsgBuf; + if (pMsg == NULL) { + limLog(pMac, LOGE, FL("NULL pMsg")); + return eSIR_FAILURE; + } + + psessionEntry = peFindSessionByBssid(pMac, pMsg->bssid, &sessionId); + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("NULL psessionEntry")); + return eSIR_FAILURE; + } + get_tsf_params = (tSirCapTsfParams *) + vos_mem_malloc(sizeof(*get_tsf_params)); + if (!get_tsf_params) { + limLog(pMac, LOGE, FL(" Unable to allocate memory for cap tsf params")); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy (get_tsf_params, pMsg, sizeof(*get_tsf_params)); + get_tsf_params->bss_idx = psessionEntry->bssIdx; + + msg.type = WDA_GET_TSF_REQ; + msg.reserved = 0; + msg.bodyptr = get_tsf_params; + msg.bodyval = 0; + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("lim_process_sme_cap_tsf_req failed\n")); + vos_mem_free(get_tsf_params); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +/** + * lim_process_sme_del_ba_ses_req()- process del ba req + * @pMac:Mac ctx + * @pMsgBuf: message buffer from sme + * Returns success on taking action based on cfg value, otherwise failure + */ +tSirRetStatus lim_process_sme_del_ba_ses_req(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + tDelBaParams *pMsg = NULL; + tpPESession psessionEntry = NULL; + int val; + + pMsg = (tDelBaParams*)pMsgBuf; + if (pMsg == NULL) { + limLog(pMac, LOGE, FL("NULL pMsg")); + return eSIR_FAILURE; + } + + psessionEntry = peFindSessionBySessionId(pMac, pMsg->session_id); + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("NULL psessionEntry")); + return eSIR_FAILURE; + } + + if (wlan_cfgGetInt + (pMac, WNI_CFG_ENABLE_TX_RX_AGGREGATION, &val) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL( "Unable to get WNI_CFG_ENABLE_TX_RX_AGGREGATION")); + return eSIR_FAILURE; + } + + if (!val) + { + limLog(pMac, LOGW, + FL("user requested to disable all RX BA sessions")); + limDeleteBASessions(pMac, psessionEntry, BA_BOTH_DIRECTIONS, + eSIR_MAC_PEER_TIMEDOUT_REASON); + } + + return eSIR_SUCCESS; +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c new file mode 100644 index 000000000000..ed44ecea4244 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -0,0 +1,4828 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limAssocUtils.cc contains the utility functions + * LIM uses while processing (Re) Association messages. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "wniApi.h" +#include "sirCommon.h" + +#include "wniCfg.h" +#include "pmmApi.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limStaHashApi.h" +#include "limAdmitControl.h" +#include "limSendMessages.h" +#include "limIbssPeerMgmt.h" +#include "limSession.h" + +#include "vos_types.h" +#include "wlan_qct_wda.h" + +/* + * fill up the rate info properly based on what is actually supported by the peer + * TBD TBD TBD + */ +void +limFillSupportedRatesInfo( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpSirSupportedRates pRates, + tpPESession psessionEntry) +{ + //pSta will be NULL for self entry, so get the opRateMode based on the self mode. + //For the peer entry get it from the peer Capabilities present in hash table + if(pSta == NULL) + pRates->opRateMode = limGetStaRateMode((tANI_U8)psessionEntry->dot11mode); + else + pRates->opRateMode = limGetStaPeerType(pMac, pSta, psessionEntry); + +} + + +/** + * limCmpSSid() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether received SSid is same as SSID in use. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param *prxSSid - pointer to SSID structure + * + * @return status - true for SSID match else false. + */ + +tANI_U8 +limCmpSSid(tpAniSirGlobal pMac, tSirMacSSid *prxSSid,tpPESession psessionEntry) +{ + + if (vos_mem_compare((tANI_U8* ) prxSSid, (tANI_U8 *) &psessionEntry->ssId, + (tANI_U8) (psessionEntry->ssId.length + 1))) + return true; + else + return false; + +} /****** end limCmpSSid() ******/ + + + +/** + * limCompareCapabilities() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received capabilities + * match with local capabilities or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pAssocReq - Pointer to received Assoc Req frame + * @param pLocalCapabs - Pointer to local capabilities + * + * @return status - true for Capabilitity match else false. + */ + +tANI_U8 +limCompareCapabilities(tpAniSirGlobal pMac, + tSirAssocReq *pAssocReq, + tSirMacCapabilityInfo *pLocalCapabs,tpPESession psessionEntry) +{ + tANI_U32 val; + + + if ( ((psessionEntry->limSystemRole == eLIM_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && + (pAssocReq->capabilityInfo.ibss) ) + { + // Requesting STA asserting IBSS capability. + limLog(pMac, LOG1,FL("Requesting STA asserting IBSS capability")); + return false; + } + + // Compare CF capabilities + if (pAssocReq->capabilityInfo.cfPollable || + pAssocReq->capabilityInfo.cfPollReq) + { + // AP does not support PCF functionality + limLog(pMac, LOG1,FL(" AP does not support PCF functionality")); + return false; + } + +#if 0 //See CR24696 for analysis + // Compare privacy capability + if (pAssocReq->capabilityInfo.privacy != pLocalCapabs->privacy) + { + // AP does not support privacy + return false; + } +#endif + + // Compare short preamble capability + if (pAssocReq->capabilityInfo.shortPreamble && + (pAssocReq->capabilityInfo.shortPreamble != + pLocalCapabs->shortPreamble)) + { + + // Allowing a STA requesting short preamble while + // AP does not support it +#if 0 + // AP does not support short preamable + return false; +#endif + } + + + limLog(pMac, LOG1, "QoS in AssocReq: %d, local capabs qos: %d", + pAssocReq->capabilityInfo.qos, + pLocalCapabs->qos); + + // Compare QoS capability + if (pAssocReq->capabilityInfo.qos && + (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos)) + { + /*Temporary hack for UPF to skip 11e capability check in order to interop with + CSR - proper fix needs to be put in place*/ + if ( 0 != vos_get_skip_11e_check()) + { + limLog(pMac, LOG1, FL("Received unmatched QOS but cfg to suppress" + " - continuing")); + } + else + { + // AP does not support QoS capability + limLog(pMac, LOG1,FL("AP does not support QoS capability")); + return false; + } + } + + + /* + * If AP supports shortSlot and if apple user has + * enforced association only from shortSlot station, + * then AP must reject any station that does not support + * shortSlot + */ + if ( ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && (pLocalCapabs->shortSlotTime == 1) ) + + { + if (wlan_cfgGetInt(pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY ")); + return false; + } + if(val) + { + if (pAssocReq->capabilityInfo.shortSlotTime != pLocalCapabs->shortSlotTime) + { + limLog(pMac, LOG1,FL("Received shortSlotTime %d does not " + "match with local %d"),pAssocReq->capabilityInfo.shortSlotTime, + pLocalCapabs->shortSlotTime); + return false; + } + } + } + + return true; +} /****** end limCompareCapabilities() ******/ + + +/** + * limCheckRxBasicRates() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received rates in + * Assoc/Reassoc request frames include all BSS basic rates + * or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param rxRateSet - pointer to SSID structure + * + * @return status - true if ALL BSS basic rates are present in the + * received rateset else false. + */ + +tANI_U8 +limCheckRxBasicRates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,tpPESession psessionEntry) +{ + tSirMacRateSet *pRateSet, basicRate; + tANI_U8 i, j, k, match; + + pRateSet = vos_mem_malloc(sizeof(tSirMacRateSet)); + if (NULL == pRateSet) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for RATESET")); + + return false; + } + + + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pRateSet->rate, + (tANI_U32 *) &cfgLen) != eSIR_SUCCESS) + { + /// Could not get Operational rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve Operational rateset")); + + // Free up memory allocated for rateset + vos_mem_free((tANI_U8 *) pRateSet); + + return false; + } + #endif //TO SUPPORT BT-AMP + + /* Copy operational rate set from session Entry */ + vos_mem_copy(pRateSet->rate, (psessionEntry->rateSet.rate), + psessionEntry->rateSet.numRates); + + pRateSet->numRates = psessionEntry->rateSet.numRates; + + // Extract BSS basic rateset from operational rateset + for (i = 0, j = 0; ((i < pRateSet->numRates) && (i < SIR_MAC_RATESET_EID_MAX)) ; i++) + { + if ((pRateSet->rate[i] & 0x80) == 0x80) + { + // msb is set, so this is a basic rate + basicRate.rate[j++] = pRateSet->rate[i]; + } + } + + /* + * For each BSS basic rate, find if it is present in the + * received rateset. + */ + for (k = 0; k < j; k++) + { + match = 0; + for (i = 0; ((i < rxRateSet.numRates) && (i < SIR_MAC_RATESET_EID_MAX)); i++) + { + if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k]) + match = 1; + } + + if (!match) + { + // Free up memory allocated for rateset + vos_mem_free((tANI_U8 *)pRateSet); + + return false; + } + } + + // Free up memory allocated for rateset + vos_mem_free((tANI_U8 *)pRateSet); + + return true; +} /****** end limCheckRxBasicRates() ******/ + + + +/** + * limCheckMCSSet() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received MCS rates in + * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param supportedMCSSet - pointer to Supported MCS Rate Set + * + * @return status - true if ALL MCS Basic Rate Set rates are present in the + * received rateset else false. + */ + +tANI_U8 +limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet) +{ + tANI_U8 basicMCSSet[SIZE_OF_BASIC_MCS_SET] = {0}; + tANI_U32 cfgLen = 0; + tANI_U8 i; + tANI_U8 validBytes; + tANI_U8 lastByteMCSMask = 0x1f; + + + cfgLen = WNI_CFG_BASIC_MCS_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_BASIC_MCS_SET, + (tANI_U8 *) basicMCSSet, + (tANI_U32 *) &cfgLen) != eSIR_SUCCESS) + { + /// Could not get Basic MCS rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve Basic MCS rateset")); + return false; + } + + validBytes = VALID_MCS_SIZE/8; + + //check if all the Basic MCS Bits are set in supported MCS bitmap + for(i=0; igStartBssRSNIe; + + // Check groupwise cipher suite + for (i = 0; i < sizeof(rxRSNIe.gp_cipher_suite); i++) + { + if (pRSNIe->gp_cipher_suite[i] != rxRSNIe.gp_cipher_suite[i]) + { + limLog(pMac, LOG1, FL("RSN group cipher suite does not match local" + " %d recieved %d"),pRSNIe->gp_cipher_suite[i], + rxRSNIe.gp_cipher_suite[i]); + return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS; + } + } + + /* + * For each Pairwise cipher suite check whether we support + * received pairwise + */ + match = 0; + for (i = 0; i < rxRSNIe.pwise_cipher_suite_count; i++) + { + for(j = 0; j < pRSNIe->pwise_cipher_suite_count; j++) + { + if (vos_mem_compare(&rxRSNIe.pwise_cipher_suites[i], + &pRSNIe->pwise_cipher_suites[j], + sizeof(pRSNIe->pwise_cipher_suites[j]))) + { + match = 1; + break; + } + } + + if ((staIsHT) +#ifdef ANI_LITTLE_BYTE_ENDIAN + &&( (rxRSNIe.pwise_cipher_suites[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#else + &&( (rxRSNIe.pwise_cipher_suites[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#endif + { + onlyNonHtCipher=0; + } + + } + + if ((!match) || ((staIsHT) && onlyNonHtCipher)) + { + limLog(pMac, LOG1, FL("pairwise cipher suite does not match(%d)" + "staIsHT %d onlyNonHtCipher %d"),match,staIsHT, + onlyNonHtCipher); + return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS; + } + /* Check RSN capabilities + * Bit 0 of First Byte - PreAuthentication Capability + */ + if(((rxRSNIe.RSN_Cap[0] >> 0) & 0x1) == true) //this is supported by AP only + { + limLog(pMac, LOG1, FL("Preuthentication Capability is set")); + return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS; + } + + *pmfConnection = eANI_BOOLEAN_FALSE; + +#ifdef WLAN_FEATURE_11W + weArePMFCapable = pSessionEntry->pLimStartBssReq->pmfCapable; + weRequirePMF = pSessionEntry->pLimStartBssReq->pmfRequired; + theyArePMFCapable = (rxRSNIe.RSN_Cap[0] >> 7) & 0x1; + theyRequirePMF = (rxRSNIe.RSN_Cap[0] >> 6) & 0x1; + + if ((theyRequirePMF && theyArePMFCapable && !weArePMFCapable) || + (weRequirePMF && !theyArePMFCapable)) + { + limLog(pMac, LOG1, FL("Association fail, robust management frames " + "policy violation theyRequirePMF =%d theyArePMFCapable %d " + "weArePMFCapable %d weRequirePMF %d theyArePMFCapable %d"), + theyRequirePMF,theyArePMFCapable,weArePMFCapable,weRequirePMF, + theyArePMFCapable); + return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION; + } + + if(theyArePMFCapable && weArePMFCapable) + *pmfConnection = eANI_BOOLEAN_TRUE; + + limLog(pMac, LOG1, FL("weAreCapable %d, weRequire %d, theyAreCapable %d, " + "theyRequire %d, PMFconnection %d"), + weArePMFCapable, weRequirePMF, theyArePMFCapable, theyRequirePMF, *pmfConnection); +#endif + + return eSIR_SUCCESS; +} /****** end limCheckRxRSNIeMatch() ******/ + +/** + * limCheckRxWPAIeMatch() + * + *FUNCTION: + * This function is called during Association/Reassociation + * frame handling to determine whether received RSN in + * Assoc/Reassoc request frames include supported cipher suites or not. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param rxWPAIe - Received WPA IE in (Re)Assco req + * + * @return status - true if ALL BSS basic rates are present in the + * received rateset else false. + */ + +tANI_U8 +limCheckRxWPAIeMatch(tpAniSirGlobal pMac, tDot11fIEWPA rxWPAIe,tpPESession pSessionEntry, tANI_U8 staIsHT) +{ + tDot11fIEWPA *pWPAIe; + tANI_U8 i, j, match, onlyNonHtCipher = 1; + + // WPA IE should be received from PE + pWPAIe = &pSessionEntry->gStartBssWPAIe; + + // Check groupwise cipher suite + for (i = 0; i < 4; i++) + { + if (pWPAIe->multicast_cipher[i] != rxWPAIe.multicast_cipher[i]) + { + limLog(pMac, LOG1, FL("WPA group cipher suite does not match local" + " %d recieved %d"),pWPAIe->multicast_cipher[i], + rxWPAIe.multicast_cipher[i]); + return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS; + } + } + + /* + * For each Pairwise cipher suite check whether we support + * received pairwise + */ + match = 0; + for (i = 0; i < rxWPAIe.unicast_cipher_count; i++) + { + for(j = 0; j < pWPAIe->unicast_cipher_count; j++) + { + if (vos_mem_compare(rxWPAIe.unicast_ciphers[i], + pWPAIe->unicast_ciphers[j], + 4)) + { + match = 1; + break; + } + } + + if ((staIsHT) +#ifdef ANI_LITTLE_BYTE_ENDIAN + &&( (rxWPAIe.unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#else + &&( (rxWPAIe.unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) == SECURITY_SUITE_TYPE_CCMP)) +#endif + { + onlyNonHtCipher=0; + } + + } + + if ((!match) || ((staIsHT) && onlyNonHtCipher)) + { + limLog(pMac, LOG1, FL("pairwise cipher suite does not match(%d)" + "staIsHT %d onlyNonHtCipher %d"),match,staIsHT, + onlyNonHtCipher); + return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS; + } + + return eSIR_SUCCESS; +} /****** end limCheckRxWPAIeMatch() ******/ + + +/** + * limCleanupRxPath() + * + *FUNCTION: + * This function is called to cleanup STA state at SP & RFP. + * + *LOGIC: + * To circumvent RFP's handling of dummy packet when it does not + * have an incomplete packet for the STA to be deleted, a packet + * with 'more framgents' bit set will be queued to RFP's WQ before + * queuing 'dummy packet'. + * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010 + * (Disassociation frame) and routing flags in BD set to eCPU's + * Low Priority WQ. + * RFP cleans up its local context for the STA id mentioned in the + * BD and then pushes BD to eCPU's low priority WQ. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pStaDs Pointer to the per STA data structure + * initialized by LIM and maintained at DPH + * + * @return None + */ + +tSirRetStatus +limCleanupRxPath(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + + + limLog( pMac, LOG1, FL("Cleanup Rx Path for AID : %d" + "psessionEntry->limSmeState : %d, mlmState : %d"), + pStaDs->assocId, psessionEntry->limSmeState, + pStaDs->mlmStaContext.mlmState); + + limAbortBackgroundScan( pMac ); + psessionEntry->isCiscoVendorAP = FALSE; + if (pMac->lim.gLimAddtsSent) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER)); + tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer); + } + + if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) + { + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, + pStaDs->assocId); + + if (!pStaDs->mlmStaContext.updateContext) + { + /** + * There is no context at Polaris to delete. + * Release our assigned AID back to the free pool + */ + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + limDelSta(pMac, pStaDs, false, psessionEntry); + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + } + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry); + return retCode; + } + } + + //delete all tspecs associated with this sta. + limAdmitControlDeleteSta(pMac, pStaDs->assocId); + + + /** + * Make STA hash entry invalid at eCPU so that DPH + * does not process any more data packets and + * releases those BDs + */ + pStaDs->valid = 0; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + /* Deactivating probe after heart beat timer */ + limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER); + pMac->lim.gLastBeaconDtimCount = 0; + pMac->lim.gLastBeaconDtimPeriod = 0; + +#ifdef FEATURE_WLAN_ESE +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); +#else + limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + + /** + * Update the status for PMM module + */ + pmmResetPmmState(pMac); + } +#ifdef WLAN_DEBUG + // increment a debug count + pMac->lim.gLimNumRxCleanup++; +#endif + + /* Do DEL BSS or DEL STA only if ADD BSS was success */ + if (!psessionEntry->addBssfailed) + { + if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) + retCode = limDelBss( pMac, pStaDs, + psessionEntry->bssIdx, psessionEntry); + else + retCode = limDelSta( pMac, pStaDs, true, psessionEntry); + } + return retCode; + +} /*** end limCleanupRxPath() ***/ + + +/** + * limSendDelStaCnf() + * + *FUNCTION: + * This function is called to send appropriate CNF message to SME + * + *LOGIC: + * + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param tpAniSirGlobal pMac, + * @param tSirMacAddr staDsAddr, + * @param tANI_U16 staDsAssocId, + * @param tLimMlmStaContext mlmStaContext, + * @param tSirResultCodes statusCode + * + * @return None + */ + +void +limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr, + tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry) +{ + + tLimMlmDisassocCnf mlmDisassocCnf; + tLimMlmDeauthCnf mlmDeauthCnf; + tLimMlmPurgeStaInd mlmPurgeStaInd; + + limLog(pMac, LOG1, FL("Sessionid: %d staDsAssocId: %d Trigger: %d " + "statusCode: %d staDsAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId, + staDsAssocId, mlmStaContext.cleanupTrigger, statusCode, + MAC_ADDR_ARRAY(staDsAddr)); + + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + // Set BSSID at CFG to null + tSirMacAddr nullAddr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + #if 0 + if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) &nullAddr, + sizeof(tSirMacAddr)) != eSIR_SUCCESS) + { + /// Could not update BSSID at CFG. Log error. + limLog(pMac, LOGP, FL("could not update BSSID at CFG")); + + return; + } + #endif//TO SUPPORT BT-AMP + + sirCopyMacAddr(nullAddr,psessionEntry->bssId); + + // Free up buffer allocated for JoinReq held by + // MLM state machine + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + psessionEntry->limAID = 0; + + } + + if ((mlmStaContext.cleanupTrigger == + eLIM_HOST_DISASSOC) || + (mlmStaContext.cleanupTrigger == + eLIM_PROMISCUOUS_MODE_DISASSOC) || + (mlmStaContext.cleanupTrigger == + eLIM_LINK_MONITORING_DISASSOC)) + { + /** + * Host or LMM driven Disassociation. + * Issue Disassoc Confirm to SME. + */ + limLog( pMac, LOGW, FL("Lim Posting DISASSOC_CNF to Sme.Trigger: %d"), + mlmStaContext.cleanupTrigger); + + + vos_mem_copy((tANI_U8 *) &mlmDisassocCnf.peerMacAddr, + (tANI_U8 *) staDsAddr, + sizeof(tSirMacAddr)); + mlmDisassocCnf.resultCode = statusCode; + mlmDisassocCnf.aid = staDsAssocId; + mlmDisassocCnf.disassocTrigger = + mlmStaContext.cleanupTrigger; + /* Update PE session Id*/ + mlmDisassocCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_DISASSOC_CNF, + (tANI_U32 *) &mlmDisassocCnf); + } + else if ((mlmStaContext.cleanupTrigger == eLIM_HOST_DEAUTH) || + (mlmStaContext.cleanupTrigger == eLIM_LINK_MONITORING_DEAUTH)) + { + /** + * Host or LMM driven Deauthentication. + * Issue Deauth Confirm to SME. + */ + limLog( pMac, LOGW, FL("Lim Posting DEAUTH_CNF to Sme.Trigger: %d"), + mlmStaContext.cleanupTrigger); + vos_mem_copy((tANI_U8 *) &mlmDeauthCnf.peerMacAddr, + (tANI_U8 *) staDsAddr, + sizeof(tSirMacAddr)); + mlmDeauthCnf.resultCode = statusCode; + mlmDeauthCnf.aid = staDsAssocId; + mlmDeauthCnf.deauthTrigger = + mlmStaContext.cleanupTrigger; + /* PE session Id */ + mlmDeauthCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_CNF, + (tANI_U32 *) &mlmDeauthCnf); + } + else if ((mlmStaContext.cleanupTrigger == + eLIM_PEER_ENTITY_DISASSOC) || + (mlmStaContext.cleanupTrigger == + eLIM_PEER_ENTITY_DEAUTH)) + { + /** + * Received Disassociation/Deauthentication from peer. + * Issue Purge Ind to SME. + */ + limLog( pMac, LOGW, FL("Lim Posting PURGE_STA_IND to Sme.Trigger: %d"), + mlmStaContext.cleanupTrigger) ; + vos_mem_copy((tANI_U8 *) &mlmPurgeStaInd.peerMacAddr, + (tANI_U8 *) staDsAddr, + sizeof(tSirMacAddr)); + mlmPurgeStaInd.reasonCode = (tANI_U8) mlmStaContext.disassocReason; + mlmPurgeStaInd.aid = staDsAssocId; + mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger; + mlmPurgeStaInd.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_PURGE_STA_IND, + (tANI_U32 *) &mlmPurgeStaInd); + } + else if(mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE) + { + //PE setup the peer entry in HW upfront, right after join is completed. + //If there is a failure during rest of the assoc sequence, this context needs to be cleaned up. + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + tLimSmeStates tempLimSmeState = eLIM_SME_IDLE_STATE; + + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + + tempLimSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + //if it is a reassoc failure to join new AP + //eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA result code is used + //during assoc and reassoc, so sme state req to distinguish them + if((mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE) || + (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE) || + (mlmStaContext.resultCode == eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE) || + (mlmStaContext.resultCode == eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA + && tempLimSmeState == eLIM_SME_WT_REASSOC_STATE) + ) + { + limLog( pMac, LOG1, FL("Lim Posting eWNI_SME_REASSOC_RSP to SME" + "resultCode: %d, statusCode: %d," + "sessionId: %d"), + mlmStaContext.resultCode, + mlmStaContext.protStatusCode, + psessionEntry->peSessionId); + if(mlmStaContext.resultCode != eSIR_SME_SUCCESS ) + { + peDeleteSession(pMac, psessionEntry); + psessionEntry = NULL; + } + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, + mlmStaContext.resultCode, mlmStaContext.protStatusCode, psessionEntry, + smesessionId, smetransactionId); + } + else + { + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + + limLog( pMac, LOG1, FL("Lim Posting eWNI_SME_JOIN_RSP to SME." + "resultCode: %d,statusCode: %d," + "sessionId: %d"), + mlmStaContext.resultCode, + mlmStaContext.protStatusCode, + psessionEntry->peSessionId); + if(mlmStaContext.resultCode != eSIR_SME_SUCCESS) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + + limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, mlmStaContext.resultCode, mlmStaContext.protStatusCode, + psessionEntry, smesessionId, smetransactionId); + } + + } + + if((NULL != psessionEntry) + && (eLIM_AP_ROLE != psessionEntry->limSystemRole ) + ) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } +} + +/** + * limRejectAssociation() + * + *FUNCTION: + * This function is called whenever Re/Association Request need + * to be rejected due to failure in assigning an AID or failure + * in adding STA context at Polaris or reject by applications. + * + *LOGIC: + * Resources allocated if any are freedup and (Re) Association + * Response frame is sent to requesting STA. Pre-Auth context + * will be added for this STA if it does not exist already + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param *pBd - A pointer to Buffer descriptor + associated PDUs + * @param subType - Indicates whether it is Association Request (=0) or + * Reassociation Request (=1) frame + * @param addPreAuthContext - Indicates whether pre-auth context + * to be added for this STA + * @param authType - Indicates auth type to be added + * @param staId - Indicates staId of the STA being rejected + * association + * @param deleteSta - Indicates whether to delete STA context + * at Polaris + * @param rCode - Indicates what reasonCode to be sent in + * Re/Assoc response to STA + * + * @return None + */ + +void +limRejectAssociation(tpAniSirGlobal pMac, tSirMacAddr peerAddr, tANI_U8 subType, + tANI_U8 addPreAuthContext, tAniAuthType authType, + tANI_U16 staId, tANI_U8 deleteSta, tSirResultCodes rCode, tpPESession psessionEntry ) +{ + tpDphHashNode pStaDs; + assoc_rsp_tx_context *tx_complete_context = NULL; + vos_list_node_t *pNode= NULL; + + limLog(pMac, LOG1, FL("Sessionid: %d authType: %d subType: %d " + "addPreAuthContext: %d staId: %d deleteSta: %d rCode : %d " + "peerAddr: "MAC_ADDRESS_STR),psessionEntry->peSessionId, + authType, subType, addPreAuthContext, staId, deleteSta, rCode, + MAC_ADDR_ARRAY(peerAddr)); + + if (addPreAuthContext) + { + // Create entry for this STA in pre-auth list + struct tLimPreAuthNode *pAuthNode; + + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + + if (pAuthNode) + { + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + peerAddr, + sizeof(tSirMacAddr)); + pAuthNode->fTimerStarted = 0; + pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE; + pAuthNode->authType = (tAniAuthType) authType; + pAuthNode->timestamp = vos_timer_get_system_ticks(); + limAddPreAuthNode(pMac, pAuthNode); + } + } + + if (deleteSta == true) + { + pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + limLog(pMac, LOGW, + FL("No STA context, yet rejecting Association")); + + return; + } + vos_list_peek_front(&pMac->assoc_rsp_completion_list, &pNode); + + tx_complete_context = vos_mem_malloc(sizeof(*tx_complete_context)); + if (!tx_complete_context) + { + limLog(pMac, LOGW, + FL("Failed to allocate memory")); + + return; + } + tx_complete_context->psessionID = psessionEntry->peSessionId; + tx_complete_context->staId = staId; + + if (pNode) + vos_list_insert_back(&pMac->assoc_rsp_completion_list, + &tx_complete_context->node); + else + vos_list_insert_front(&pMac->assoc_rsp_completion_list, + &tx_complete_context->node); + + /** + * Polaris has state for this STA. + * Trigger cleanup. + */ + pStaDs->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT; + // Send Re/Association Response with + // status code to requesting STA. + limSendAssocRspMgmtFrame(pMac, + rCode, + 0, + peerAddr, + subType, 0,psessionEntry, tx_complete_context); + + if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL) + { + // Assoction confirmation is complete, free the copy of association request frame + if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame) + { + vos_mem_free(((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL; + } + vos_mem_free(psessionEntry->parsedAssocReq[pStaDs->assocId]); + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } + } + else + { + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS, + 1, + peerAddr, + subType, 0,psessionEntry, NULL); + // Log error + limLog(pMac, LOGW, + FL("received Re/Assoc req when max associated STAs reached from ")); + limPrintMacAddr(pMac, peerAddr, LOGW); + limSendSmeMaxAssocExceededNtf(pMac, peerAddr, psessionEntry->smeSessionId); + } +} /*** end limRejectAssociation() ***/ + + +/** ------------------------------------------------------------- +\fn limDecideApProtectionOnHt20Delete +\brief protection related function while HT20 station is getting deleted. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limDecideApProtectionOnHt20Delete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + tANI_U32 i = 0; + PELOG1( limLog(pMac, LOG1, FL("(%d) A HT 20 STA is disassociated. Addr is "), + psessionEntry->gLimHt20Params.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimHt20Params.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare(psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimHt20Params.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimHt20Params.numSta == 0) + { + // disable protection + limLog(pMac, LOG1, FL("No 11B STA exists, PESessionID %d"), + psessionEntry->peSessionId); + limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry); + } +} +/** ------------------------------------------------------------- +\fn limDecideApProtectionOnDelete +\brief Decides about protection related settings when a station is getting deleted. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limDecideApProtectionOnDelete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + tANI_U32 phyMode; + tHalBitVal erpEnabled = eHAL_CLEAR; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 i; + + if(NULL == pStaDs) + return; + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_5_GHZ == rfBand) + { + //we are HT. if we are 11A, then protection is not required. + if(true == psessionEntry->htCapability) + { + //we are HT and 11A station is leaving. + //protection consideration required. + //HT station leaving ==> this case is commonly handled between both the bands below. + if((psessionEntry->beaconParams.llaCoexist) && + (false == pStaDs->mlmStaContext.htCapability)) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A 11A STA is disassociated. Addr is "), + psessionEntry->gLim11aParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLim11aParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11aParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if(psessionEntry->gLim11aParams.numSta == 0) + { + // disable protection + limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + } + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + + erpEnabled = pStaDs->erpEnabled; + //we are HT or 11G and 11B station is getting deleted. + if (((phyMode == WNI_CFG_PHY_MODE_11G) || + psessionEntry->htCapability) && + (erpEnabled == eHAL_CLEAR)) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A legacy STA is disassociated. Addr is "), + psessionEntry->gLim11bParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLim11bParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11bParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLim11bParams.numSta == 0) + { + // disable protection + limEnable11gProtection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + //(non-11B station is leaving) or (we are not 11G or HT AP) + else if(psessionEntry->htCapability) + { //we are HT AP and non-11B station is leaving. + + //11g station is leaving + if(!pStaDs->mlmStaContext.htCapability) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A 11g STA is disassociated. Addr is "), + psessionEntry->gLim11bParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLim11gParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11gParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLim11gParams.numSta == 0) + { + // disable protection + limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry); + } + } + } + } + + //LSIG TXOP not supporting staiton leaving. applies to 2.4 as well as 5 GHZ. + if((true == psessionEntry->htCapability) && + (true == pStaDs->mlmStaContext.htCapability)) + { + //HT non-GF leaving + if(!pStaDs->htGreenfield) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A non-GF STA is disassociated. Addr is "), + psessionEntry->gLimNonGfParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimNonGfParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimNonGfParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimNonGfParams.numSta == 0) + { + // disable protection + limEnableHTNonGfProtection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + //HT 20Mhz station leaving. + if(psessionEntry->beaconParams.ht20Coexist && + (eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet)) + { + limDecideApProtectionOnHt20Delete(pMac, pStaDs, pBeaconParams,psessionEntry); + } + + if(false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport && + (false == pStaDs->htLsigTXOPProtection)) + { + PELOG1( limLog(pMac, LOG1, FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is "), + psessionEntry->gLimLsigTxopParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimLsigTxopParams.numSta > 0) + { + for (i=0; iprotStaCache[i].active) + { + if (vos_mem_compare( psessionEntry->protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimLsigTxopParams.numSta--; + psessionEntry->protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimLsigTxopParams.numSta == 0) + { + // disable protection + limEnableHTLsigTxopProtection(pMac, true, false, pBeaconParams,psessionEntry); + } + } + } +} + + + +/** ------------------------------------------------------------- +\fn limDecideShortPreamble +\brief Decides about any short preamble reated change because of new station joining. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void limDecideShortPreamble(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry ) +{ + tANI_U32 i; + + if (pStaDs->shortPreambleEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short preamble STA is disassociated. Addr is "), + psessionEntry->gLimNoShortParams.numNonShortPreambleSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta > 0) + { + for (i=0; igLimNoShortParams.staNoShortCache[i].active) + { + if (vos_mem_compare( psessionEntry->gLimNoShortParams.staNoShortCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimNoShortParams.numNonShortPreambleSta--; + psessionEntry->gLimNoShortParams.staNoShortCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLimNoShortParams.numNonShortPreambleSta == 0) + { + // enable short preamble + //reset the cache + vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortParams, + sizeof(tLimNoShortParams), 0); + if (limEnableShortPreamble(pMac, true, pBeaconParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Cannot enable short preamble"));) + } + } +} + +/** ------------------------------------------------------------- +\fn limDecideShortSlot +\brief Decides about any short slot time related change because of station leaving the BSS. +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\return None + -------------------------------------------------------------*/ + +void +limDecideShortSlot(tpAniSirGlobal pMac, tpDphHashNode pStaDs, + tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U32 i, val; + if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac, LOG1, FL("(%d) A non-short slottime STA is disassociated. Addr is "), + pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1);) + + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta> 0) + { + for (i=0; igLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare(psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta--; + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = false; + break; + } + } + } + } + else + { + if (pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta> 0) + { + for (i=0; ilim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare(pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta--; + pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = false; + break; + } + } + } + } + } + + wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val); + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta == 0)) + { + // enable short slot time + //reset the cache + vos_mem_set((tANI_U8 *)&psessionEntry->gLimNoShortSlotParams, + sizeof(tLimNoShortSlotParams), 0); + // in case of AP set SHORT_SLOT_TIME to enable + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + pBeaconParams->fShortSlotTime = true; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + psessionEntry->shortSlotTimeSupported = true; + } + } + else + { + if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta == 0) + { + // enable short slot time + //reset the cache + vos_mem_set((tANI_U8 *)&pMac->lim.gLimNoShortSlotParams, + sizeof(tLimNoShortSlotParams), 0); + // in case of AP set SHORT_SLOT_TIME to enable + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + pBeaconParams->fShortSlotTime = true; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + psessionEntry->shortSlotTimeSupported = true; + } + } + } + } +} + +void +limPostReassocFailure(tpAniSirGlobal pMac, + tSirResultCodes resultCode, + tANI_U16 protStatusCode,tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; + + psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); + + mlmReassocCnf.resultCode = resultCode; + mlmReassocCnf.protStatusCode = protStatusCode; + /* Update PE session Id */ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, + LIM_MLM_REASSOC_CNF, + (tANI_U32 *) &mlmReassocCnf); +} /*** end limPostReassocFailure() ***/ + +/** + * limRestorePreReassocState() + * + *FUNCTION: + * This function is called on STA role whenever Reasociation + * Response with a reject code is received from AP. + * + *LOGIC: + * Reassociation failure timer is stopped, Old (or current) AP's + * context is restored both at Polaris & software + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param resultCode - Result code that specifies why Reassociation + * attemp failed + * + * @return None + */ + +void +limRestorePreReassocState(tpAniSirGlobal pMac, + tSirResultCodes resultCode, + tANI_U16 protStatusCode,tpPESession psessionEntry) +{ + tANI_U8 chanNum, secChanOffset; + tLimMlmReassocCnf mlmReassocCnf; + + limLog(pMac, LOG1, FL("sessionid: %d protStatusCode: %d resultCode: %d"), + psessionEntry->smeSessionId, protStatusCode, resultCode); + + psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); + + // Update BSSID at CFG database + #if 0 + if (cfgSetStr(pMac, WNI_CFG_BSSID, + pMac->lim.gLimCurrentBssId, + sizeof(tSirMacAddr)) != eSIR_SUCCESS) + { + /// Could not update BSSID at CFG. Log error. + limLog(pMac, LOGP, FL("could not update BSSID at CFG")); + return; + } + #endif + + // chanNum = pMac->lim.gLimCurrentChannelId; + + /* To support BT-AMP */ + chanNum = psessionEntry->currentOperChannel; + secChanOffset = psessionEntry->htSecondaryChannelOffset; + + limSetChannel(pMac, chanNum, secChanOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); + + /** @ToDo : Need to Integrate the STOP the DataTransfer to the AP from 11H code */ + + mlmReassocCnf.resultCode = resultCode; + mlmReassocCnf.protStatusCode = protStatusCode; + /* Update PE session Id */ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, + LIM_MLM_REASSOC_CNF, + (tANI_U32 *) &mlmReassocCnf); +} /*** end limRestorePreReassocState() ***/ + + + +/** + * limIsReassocInProgress() + * + *FUNCTION: + * This function is called to see if STA is in wt-reassoc-rsp state. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return eANI_BOOLEAN_TRUE When STA is waiting for Reassoc response from AP \n + * else eANI_BOOLEAN_FALSE + */ + +eAniBoolean +limIsReassocInProgress(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + if (psessionEntry == NULL) + { + return eANI_BOOLEAN_FALSE; + } + if(((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + ((psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) || + (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_LINK_FAIL_STATE))) + return eANI_BOOLEAN_TRUE; + + return eANI_BOOLEAN_FALSE; +} /*** end limIsReassocInProgress() ***/ + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tDot11fIEVHTCaps *pPeerVHTCaps, + tpPESession psessionEntry) +{ + tANI_U32 val; + tANI_U32 selfStaDot11Mode=0; + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode); + +// if(IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) + if (IS_DOT11_MODE_VHT(selfStaDot11Mode)) + { + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_MCS_MAP,&val) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX MCS MAP"));) + goto error; + } + pRates->vhtRxMCSMap = (tANI_U16)val; + + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_MCS_MAP,&val ) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT TX MCS MAP"));) + goto error; + } + pRates->vhtTxMCSMap = (tANI_U16)val; + + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,&val ) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));) + goto error; + } + pRates->vhtRxHighestDataRate = (tANI_U16)val; + + if ( wlan_cfgGetInt( pMac,WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,&val ) != + eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve VHT RX Supported data rate MAP"));) + goto error; + } + pRates->vhtTxHighestDataRate = (tANI_U16)val; + + if( pPeerVHTCaps != NULL) + { + pRates->vhtTxHighestDataRate = SIR_MIN(pRates->vhtTxHighestDataRate, pPeerVHTCaps->txSupDataRate); + pRates->vhtRxHighestDataRate = SIR_MIN(pRates->vhtRxHighestDataRate, pPeerVHTCaps->rxHighSupDataRate); + + // Acquire PEER MCS map if we exceed. + // We compare/update only the last 2 bits of the map as we support only single BSS. + // Firmware takes care of this comparison + pRates->vhtRxMCSMap &= ~(0x3); // Clearing the last 2 bits in the bitmap + pRates->vhtRxMCSMap |= (pPeerVHTCaps->rxMCSMap & 0x3); // Updating the last 2 bits in the bitmap + + // Firmware takes care of this comparison + pRates->vhtTxMCSMap &= ~(0x3); // Clearing the last 2 bits in the bitmap + pRates->vhtTxMCSMap |= (pPeerVHTCaps->txMCSMap & 0x3); // Updating the last 2 bits in the bitmap + } + } + return eSIR_SUCCESS; +error: + + return eSIR_FAILURE; + +} +#endif + +/** + * limPopulateOwnRateSet + * + * FUNCTION: + * This function is called by limProcessAssocRsp() or + * limAddStaInIBSS() + * - It creates a combined rate set of 12 rates max which + * comprises the basic and extended rates read from CFG + * - It sorts the combined rate Set and copy it in the + * rate array of the pSTA descriptor + * - It sets the erpEnabled bit of the STA descriptor + * + * NOTE: + * ERP bit is set iff the dph PHY mode is 11G and there is at least + * an A rate in the supported or extended rate sets + * + * @param pMac - Pointer to Global MAC structure + * @param basicOnly - When passed value is true, only basic + * rates are copied to DPH node else + * all supported rates are copied + * @return eSIR_SUCCESS or eSIR_FAILURE + * + */ +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) +#else +tSirRetStatus +limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry) +#endif + +{ + tSirMacRateSet tempRateSet; + tSirMacRateSet tempRateSet2; + tANI_U32 i,j,val,min,isArate; + tANI_U32 phyMode = 0; + tANI_U32 selfStaDot11Mode=0; + + isArate = 0; + + wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + /* Include 11b rates only when the device configured in + auto, 11a/b/g or 11b_only */ + if ( (selfStaDot11Mode == WNI_CFG_DOT11_MODE_ALL) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11A) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11AC) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11N) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11G) || + (selfStaDot11Mode == WNI_CFG_DOT11_MODE_11B) ) + { + val = WNI_CFG_SUPPORTED_RATES_11B_LEN; + wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11B, + (tANI_U8 *)&tempRateSet.rate, &val ); + tempRateSet.numRates = (tANI_U8) val; + } + else + tempRateSet.numRates = 0; + + /* Include 11a rates when the device configured in non-11b mode */ + if (!IS_DOT11_MODE_11B(selfStaDot11Mode)) + { + val = WNI_CFG_SUPPORTED_RATES_11A_LEN; + wlan_cfgGetStr( pMac, WNI_CFG_SUPPORTED_RATES_11A, + (tANI_U8 *)&tempRateSet2.rate, &val ); + tempRateSet2.numRates = (tANI_U8) val; + } + else + tempRateSet2.numRates = 0; + + if ((tempRateSet.numRates + tempRateSet2.numRates) > 12) + { + //we are in big trouble + limLog(pMac, LOGP, FL("more than 12 rates in CFG")); + //panic + goto error; + } + + //copy all rates in tempRateSet, there are 12 rates max + for (i = 0;i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i]; + tempRateSet.numRates += tempRateSet2.numRates; + + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in pSupportedRates + */ + { + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + + vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0); + for(i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + isArate = 0; + for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++) + { + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + } + + if (sirIsArate(tempRateSet.rate[min] & 0x7f)) + isArate = 1; + + /* + * HAL needs to know whether the rate is basic rate or not, as it needs to + * update the response rate table accordingly. e.g. if one of the 11a rates is + * basic rate, then that rate can be used for sending control frames. + * HAL updates the response rate table whenever basic rate set is changed. + */ + if (basicOnly) + { + if (tempRateSet.rate[min] & 0x80) + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + } + else + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + tempRateSet.rate[min] = 0xff; + } + + } + + + //if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + if (IS_DOT11_MODE_HT(selfStaDot11Mode)) + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + pRates->supportedMCSSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));) + goto error; + } + + + //if supported MCS Set of the peer is passed in, then do the intersection + //else use the MCS set from local CFG. + + if(pSupportedMCSSet != NULL) + { + for(i=0; isupportedMCSSet[i] &= pSupportedMCSSet[i]; + + } + + limLog(pMac, LOG1, FL("MCS Rate Set Bitmap: ")); + for(i=0; isupportedMCSSet[i]); + } + +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, pRates , pVHTCaps,psessionEntry); +#endif + + return eSIR_SUCCESS; + + error: + + return eSIR_FAILURE; +} /*** limPopulateOwnRateSet() ***/ + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulatePeerRateSet(tpAniSirGlobal pMac, + + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) +#else +tSirRetStatus +limPopulatePeerRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry) +#endif +{ + tSirMacRateSet tempRateSet; + tSirMacRateSet tempRateSet2; + tANI_U32 i,j,val,min,isArate; + isArate = 0; + + /* copy operational rate set from psessionEntry */ + if ( psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX ) + { + vos_mem_copy((tANI_U8 *)tempRateSet.rate, + (tANI_U8*)(psessionEntry->rateSet.rate), + psessionEntry->rateSet.numRates); + tempRateSet.numRates = psessionEntry->rateSet.numRates; + } + else + { + limLog(pMac, LOGE, FL("more than SIR_MAC_RATESET_EID_MAX rates\n")); + goto error; + } + if ((psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) || + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11A) || + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N)) + { + + if (psessionEntry->extRateSet.numRates <= SIR_MAC_RATESET_EID_MAX) + { + vos_mem_copy((tANI_U8 *)tempRateSet2.rate, + (tANI_U8*)(psessionEntry->extRateSet.rate), + psessionEntry->extRateSet.numRates); + tempRateSet2.numRates = psessionEntry->extRateSet.numRates; + } + else { + limLog(pMac, LOGE, FL("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates\n")); + goto error; + } + } + else + tempRateSet2.numRates = 0; + if ((tempRateSet.numRates + tempRateSet2.numRates) > SIR_MAC_RATESET_EID_MAX) + { + //we are in big trouble + limLog(pMac, LOGP, FL("more than 12 rates in CFG")); + goto error; + } + + + //copy all rates in tempRateSet, there are 12 rates max + for (i = 0;i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i]; + tempRateSet.numRates += tempRateSet2.numRates; + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in pSupportedRates + */ + { + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + vos_mem_set((tANI_U8 *) pRates, sizeof(tSirSupportedRates), 0); + for(i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + isArate = 0; + for(j = 0; (j < tempRateSet.numRates) && (j < SIR_MAC_RATESET_EID_MAX); j++) + { + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + } + if (sirIsArate(tempRateSet.rate[min] & 0x7f)) + isArate = 1; + /* + * HAL needs to know whether the rate is basic rate or not, as it needs to + * update the response rate table accordingly. e.g. if one of the 11a rates is + * basic rate, then that rate can be used for sending control frames. + * HAL updates the response rate table whenever basic rate set is changed. + */ + if (basicOnly) + { + if (tempRateSet.rate[min] & 0x80) + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + } + else + { + if (isArate) + pRates->llaRates[aRateIndex++] = tempRateSet.rate[min]; + else + pRates->llbRates[bRateIndex++] = tempRateSet.rate[min]; + } + tempRateSet.rate[min] = 0xff; + } + } + + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + pRates->supportedMCSSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve supportedMCSSet"));) + goto error; + } + //if supported MCS Set of the peer is passed in, then do the intersection + //else use the MCS set from local CFG. + if(pSupportedMCSSet != NULL) + { + for(i=0; isupportedMCSSet[i] &= pSupportedMCSSet[i]; + } + limLog(pMac, LOG1, FL("MCS Rate Set Bitmap: ")); + for(i=0; isupportedMCSSet[i]); + } +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, pRates , pVHTCaps,psessionEntry); +#endif + return eSIR_SUCCESS; + error: + return eSIR_FAILURE; +} /*** limPopulatePeerRateSet() ***/ + +/** + * limPopulateMatchingRateSet + * FUNCTION: + * This is called at the time of Association Request + * processing on AP and while adding peer's context + * in IBSS role to process the CFG rate sets and + * the rate sets received in the Assoc request on AP + * or Beacon/Probe Response from peer in IBSS. + * + * LOGIC: + * 1. It makes the intersection between our own rate Sat + * and extemcded rate set and the ones received in the + * association request. + * 2. It creates a combined rate set of 12 rates max which + * comprised the basic and extended rates + * 3. It sorts the combined rate Set and copy it in the + * rate array of the pSTA descriptor + * + * ASSUMPTION: + * The parser has already ensured unicity of the rates in the + * association request structure + * + * @param: pMac - Pointer to Global MAC structure + * pStaDs - Pointer to DPH node + * pOperRateSet - Pointer to peer's supported rateset + * pExtRateSet - Pointer to peer's extended rateset + * + * @return: eSIR_SUCCESS or eSIR_FAILURE + */ +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tSirMacRateSet *pOperRateSet, + tSirMacRateSet *pExtRateSet, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) + +#else +tSirRetStatus +limPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tSirMacRateSet *pOperRateSet, + tSirMacRateSet *pExtRateSet, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry) +#endif +{ + tSirMacRateSet tempRateSet; + tSirMacRateSet tempRateSet2; + tANI_U32 i,j,val,min,isArate; + tANI_U32 phyMode; + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + + isArate=0; + + // limGetPhyMode(pMac, &phyMode); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + // get own rate set + // val = WNI_CFG_OPERATIONAL_RATE_SET_LEN; + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, + (tANI_U8 *) &tempRateSet.rate, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve rateset")); + } + + #endif // TO SUPPORT BT-AMP + + /* copy operational rate set from psessionEntry */ + vos_mem_copy((tempRateSet.rate), (psessionEntry->rateSet.rate), + psessionEntry->rateSet.numRates); + tempRateSet.numRates = (tANI_U8) psessionEntry->rateSet.numRates; + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + + #if 0 + // get own extended rate set + val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + (tANI_U8 *) &tempRateSet2.rate, + &val) != eSIR_SUCCESS) + #endif + vos_mem_copy((tempRateSet2.rate), (psessionEntry->extRateSet.rate), + psessionEntry->extRateSet.numRates); + tempRateSet2.numRates = (tANI_U8) psessionEntry->extRateSet.numRates; + } + else + tempRateSet2.numRates = 0; + + if ((tempRateSet.numRates + tempRateSet2.numRates) > 12) + { + PELOGE(limLog(pMac, LOGE, FL("more than 12 rates in CFG"));) + goto error; + } + + /** + * Handling of the rate set IEs is the following: + * - keep only rates that we support and that the station supports + * - sort and the rates into the pSta->rate array + */ + + // Copy all rates in tempRateSet, there are 12 rates max + for(i = 0; i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = + tempRateSet2.rate[i]; + + tempRateSet.numRates += tempRateSet2.numRates; + + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in tempRateSet2 + */ + tempRateSet2.numRates = 0; + + for(i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + + for(j = 0;j < tempRateSet.numRates; j++) + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + + tempRateSet2.rate[tempRateSet2.numRates++] = + tempRateSet.rate[min]; + tempRateSet.rate[min] = 0xff; + } + + + /** + * Copy received rates in tempRateSet, the parser has ensured + * unicity of the rates so there cannot be more than 12 + */ + for(i = 0; (i < pOperRateSet->numRates && i < SIR_MAC_RATESET_EID_MAX) ; i++) + { + tempRateSet.rate[i] = pOperRateSet->rate[i]; + } + + tempRateSet.numRates = pOperRateSet->numRates; + + if (pExtRateSet->numRates) + { + if((tempRateSet.numRates + pExtRateSet->numRates) > 12 ) + { + limLog( pMac, LOG1, + "Sum of SUPPORTED and EXTENDED Rate Set (%1d) exceeds 12!", + tempRateSet.numRates + pExtRateSet->numRates ); + + if( tempRateSet.numRates < 12 ) + { + int found = 0; + int tail = tempRateSet.numRates; + + for( i = 0; (i < pExtRateSet->numRates && i < SIR_MAC_RATESET_EID_MAX); i++ ) + { + found = 0; + for( j = 0; j < (tANI_U32) tail; j++ ) + { + if((tempRateSet.rate[j] & 0x7F) == + (pExtRateSet->rate[i] & 0x7F)) + { + found = 1; + break; + } + } + + if( !found ) + { + tempRateSet.rate[tempRateSet.numRates++] = + pExtRateSet->rate[i]; + + if( tempRateSet.numRates >= 12 ) + break; + } + } + } + else + limLog( pMac, LOG1, + "Relying only on the SUPPORTED Rate Set IE..." ); + } + else + { + for(j = 0; ((j < pExtRateSet->numRates) && (j < SIR_MAC_RATESET_EID_MAX) && ((i+j) < SIR_MAC_RATESET_EID_MAX)); j++) + tempRateSet.rate[i+j] = pExtRateSet->rate[j]; + + tempRateSet.numRates += pExtRateSet->numRates; + } + } + + { + tpSirSupportedRates rates = &pStaDs->supportedRates; + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + vos_mem_set((tANI_U8 *) rates, sizeof(tSirSupportedRates), 0); + for(i = 0;(i < tempRateSet2.numRates && i < SIR_MAC_RATESET_EID_MAX ); i++) + { + for(j = 0;(j < tempRateSet.numRates && j < SIR_MAC_RATESET_EID_MAX); j++) + { + if ((tempRateSet2.rate[i] & 0x7F) == + (tempRateSet.rate[j] & 0x7F)) + { + if (sirIsArate(tempRateSet2.rate[i] & 0x7f)) + { + isArate=1; + if (aRateIndex < SIR_NUM_11A_RATES) + rates->llaRates[aRateIndex++] = tempRateSet2.rate[i]; + } + else + { + if (bRateIndex < SIR_NUM_11B_RATES) + rates->llbRates[bRateIndex++] = tempRateSet2.rate[i]; + } + break; + } + } + } + + + //Now add the Polaris rates only when Proprietary rates are enabled. + val = 0; + if(wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_RATES_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve prop rate enabled flag from CFG")); + } + else if(val) + { + for(i=0; inumPropRates; i++) + rates->aniLegacyRates[i] = pAniLegRateSet->propRate[i]; + } + + } + + + //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n +#ifdef FEATURE_WLAN_TDLS + if(pStaDs->mlmStaContext.htCapability) +#else + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pStaDs->mlmStaContext.htCapability)) +#endif + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + mcsSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet")); + goto error; + } + + for(i=0; isupportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i]; + + limLog(pMac, LOG1, FL(" MCS Rate Set Bitmap from CFG and DPH : ")); + for(i=0; isupportedRates.supportedMCSSet[i]); + } + } + +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, psessionEntry); +#endif + /** + * Set the erpEnabled bit iff the phy is in G mode and at least + * one A rate is supported + */ + if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate) + pStaDs->erpEnabled = eHAL_SET; + + + + return eSIR_SUCCESS; + + error: + + return eSIR_FAILURE; +} /*** limPopulateMatchingRateSet() ***/ + + + +/** + * limAddSta() + * + *FUNCTION: + * This function is called to add an STA context at hardware + * whenever a STA is (Re) Associated. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limAddSta( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tANI_U8 updateEntry, tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMacAddr staMac, *pStaAddr; + tANI_U8 i; + tpSirAssocReq pAssocReq; + tANI_U8 *p2pIe = NULL; + #if 0 + retCode = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, staMac, &cfg); + if (retCode != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve STA MAC")); + #endif //To SUPPORT BT-AMP + + + sirCopyMacAddr(staMac,psessionEntry->selfMacAddr); + + limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), + psessionEntry->smeSessionId, updateEntry, psessionEntry->limSystemRole); + + pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams)); + if (NULL == pAddStaParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); + + if ((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_BT_AMP_AP_ROLE) ) + pStaAddr = &pStaDs->staAddr; +#ifdef FEATURE_WLAN_TDLS + /* SystemRole shouldn't be matter if staType is TDLS peer */ + else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + pStaAddr = &pStaDs->staAddr ; + } +#endif + else + pStaAddr = &staMac; + + limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": Subtype(Assoc/Reassoc): %d "), + MAC_ADDR_ARRAY(*pStaAddr), pStaDs->mlmStaContext.subType); + + vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, + (tANI_U8 *) *pStaAddr, sizeof(tSirMacAddr)); + vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, + psessionEntry->bssId, sizeof(tSirMacAddr)); + + limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry); + + //Copy legacy rates + vos_mem_copy ((tANI_U8*)&pAddStaParams->supportedRates, + (tANI_U8*)&pStaDs->supportedRates, sizeof(tSirSupportedRates)); + + pAddStaParams->assocId = pStaDs->assocId; + + pAddStaParams->wmmEnabled = pStaDs->qosMode; + pAddStaParams->listenInterval = pStaDs->mlmStaContext.listenInterval; + pAddStaParams->shortPreambleSupported = pStaDs->shortPreambleEnabled; + pAddStaParams->currentOperChan = psessionEntry->currentOperChannel; + if((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) && (pStaDs->mlmStaContext.subType == LIM_REASSOC)) + { + /* TBD - need to remove this REASSOC check after fixinf rmmod issue */ + pAddStaParams->updateSta = pStaDs->mlmStaContext.updateContext; + } + pStaDs->valid = 0; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + + limLog(pMac, LOG1, FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d" + " shortPreambleSupported: %d "), pAddStaParams->assocId, + pAddStaParams->wmmEnabled, pAddStaParams->listenInterval, + pAddStaParams->shortPreambleSupported); + // This will indicate HAL to "allocate" a new STA index +#ifdef FEATURE_WLAN_TDLS + /* As there is corner case in-between add_sta and change_sta,if del_sta for other staIdx happened, + * firmware return wrong staIdx (recently removed staIdx). Until we get a confirmation from the + * firmware team it is now return correct staIdx for same sta_mac_addr for update case, we want + * to get around it by passing valid staIdx given by add_sta time. + */ + if((STA_ENTRY_TDLS_PEER == pStaDs->staType) && + (true == updateEntry)) + { + pAddStaParams->staIdx = pStaDs->staIndex; + } + else +#endif +#ifdef SAP_AUTH_OFFLOAD + if (!pMac->sap_auth_offload) + pAddStaParams->staIdx = HAL_STA_INVALID_IDX; + else + pAddStaParams->staIdx = pStaDs->staIndex; +#else + pAddStaParams->staIdx = HAL_STA_INVALID_IDX; +#endif + + pAddStaParams->staType = pStaDs->staType; + + pAddStaParams->updateSta = updateEntry; + + pAddStaParams->status = eHAL_STATUS_SUCCESS; + pAddStaParams->respReqd = 1; + //Update HT Capability + + if ((limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) ||(limGetSystemRole(psessionEntry) == eLIM_BT_AMP_AP_ROLE) || (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)) + { + pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability; +#endif + } +#ifdef FEATURE_WLAN_TDLS + /* SystemRole shouldn't be matter if staType is TDLS peer */ + else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + pAddStaParams->htCapable = pStaDs->mlmStaContext.htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = pStaDs->mlmStaContext.vhtCapability; +#endif + } +#endif + else + { + pAddStaParams->htCapable = psessionEntry->htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = psessionEntry->vhtCapability; +#endif + + } +#ifdef WLAN_FEATURE_11AC + limLog(pMac, LOG1, FL("vhtCapable: %d "), pAddStaParams->vhtCapable); +#endif + limLog(pMac, LOG1, FL(" StaIdx: %d updateSta = %d htcapable = %d "), + pAddStaParams->staIdx,pAddStaParams->updateSta, + pAddStaParams->htCapable); + + pAddStaParams->greenFieldCapable = pStaDs->htGreenfield; + pAddStaParams->maxAmpduDensity= pStaDs->htAMpduDensity; + pAddStaParams->maxAmpduSize = pStaDs->htMaxRxAMpduFactor; + pAddStaParams->fDsssCckMode40Mhz = pStaDs->htDsssCckRate40MHzSupport; + pAddStaParams->fShortGI20Mhz = pStaDs->htShortGI20Mhz; + pAddStaParams->fShortGI40Mhz = pStaDs->htShortGI40Mhz; + pAddStaParams->lsigTxopProtection = pStaDs->htLsigTXOPProtection; + pAddStaParams->maxAmsduSize = pStaDs->htMaxAmsduLength; + pAddStaParams->txChannelWidthSet = pStaDs->htSupportedChannelWidthSet; + pAddStaParams->mimoPS = pStaDs->htMIMOPSState; + + limLog(pMac, LOG1, FL(" greenFieldCapable: %d maxAmpduDensity = %d " + "maxAmpduDensity = %d"), pAddStaParams->greenFieldCapable, + pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize); + + limLog(pMac, LOG1, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d " + "fShortGI40Mhz: %d"), pAddStaParams->fDsssCckMode40Mhz, + pAddStaParams->fShortGI20Mhz, pAddStaParams->fShortGI40Mhz); + + limLog(pMac, LOG1, FL("lsigTxopProtection: %d maxAmsduSize: %d " + "txChannelWidthSet: %d mimoPS: %d "), pAddStaParams->lsigTxopProtection, + pAddStaParams->maxAmsduSize,pAddStaParams->txChannelWidthSet, + pAddStaParams->mimoPS); + +#ifdef WLAN_FEATURE_11AC + if(pAddStaParams->vhtCapable) + { + pAddStaParams->vhtTxChannelWidthSet = pStaDs->vhtSupportedChannelWidthSet; + pAddStaParams->vhtTxBFCapable = +#ifdef FEATURE_WLAN_TDLS + (( STA_ENTRY_PEER == pStaDs->staType ) || (STA_ENTRY_TDLS_PEER == pStaDs->staType)) ? + pStaDs->vhtBeamFormerCapable : psessionEntry->txBFIniFeatureEnabled ; +#else + ( STA_ENTRY_PEER == pStaDs->staType ) ? pStaDs->vhtBeamFormerCapable : + psessionEntry->txBFIniFeatureEnabled ; +#endif + limLog(pMac, LOG1, FL("vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), + pAddStaParams->vhtTxChannelWidthSet,pAddStaParams->vhtTxBFCapable); + } +#endif + +#ifdef FEATURE_WLAN_TDLS + if((STA_ENTRY_PEER == pStaDs->staType) || + (STA_ENTRY_TDLS_PEER == pStaDs->staType)) +#else + if (STA_ENTRY_PEER == pStaDs->staType) +#endif + { + /* peer STA get the LDPC capability from pStaDs, which populated from + * HT/VHT capability*/ + if(pAddStaParams->vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP) + { + pAddStaParams->htLdpcCapable = 0; + pAddStaParams->vhtLdpcCapable = 0; + } + else + { + if (psessionEntry->txLdpcIniFeatureEnabled & 0x1) + pAddStaParams->htLdpcCapable = pStaDs->htLdpcCapable; + else + pAddStaParams->htLdpcCapable = 0; + if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) + pAddStaParams->vhtLdpcCapable = pStaDs->vhtLdpcCapable; + else + pAddStaParams->vhtLdpcCapable = 0; + } + } + else if( STA_ENTRY_SELF == pStaDs->staType) + { + /* For Self STA get the LDPC capability from config.ini*/ + pAddStaParams->htLdpcCapable = + (psessionEntry->txLdpcIniFeatureEnabled & 0x01); + pAddStaParams->vhtLdpcCapable = + ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); + } + + /* Update PE session ID*/ + pAddStaParams->sessionId = psessionEntry->peSessionId; + + if (psessionEntry->parsedAssocReq != NULL) + { + // Get a copy of the already parsed Assoc Request + pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId]; + if ( pAssocReq && pAssocReq->addIEPresent && pAssocReq->addIE.length ) { + p2pIe = limGetP2pIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + } + pAddStaParams->p2pCapableSta = (p2pIe != NULL); + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddStaParams->staTCParams[i].txUseBA = eBA_DISABLE; + pAddStaParams->staTCParams[i].rxUseBA = eBA_DISABLE; + } + +#ifdef FEATURE_WLAN_TDLS + if(pStaDs->wmeEnabled && \ + ((eLIM_AP_ROLE == psessionEntry->limSystemRole) || (STA_ENTRY_TDLS_PEER == pStaDs->staType)) ) +#else + if(pStaDs->wmeEnabled && (eLIM_AP_ROLE == psessionEntry->limSystemRole)) +#endif + { + pAddStaParams->uAPSD = 0; + /* update UAPSD and send it to LIM to add STA */ + // bitmap MSB <- LSB MSB 4 bits are for + // trigger enabled AC setting and LSB 4 bits + // are for delivery enabled AC setting + // 7 6 5 4 3 2 1 0 + // BE BK VI VO BE BK VI VO + pAddStaParams->uAPSD |= pStaDs->qos.capability.qosInfo.acvo_uapsd; + pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acvi_uapsd << 1); + pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbk_uapsd << 2); + pAddStaParams->uAPSD |= (pStaDs->qos.capability.qosInfo.acbe_uapsd << 3); + //making delivery enabled and trigger enabled setting the same. + pAddStaParams->uAPSD |= pAddStaParams->uAPSD << 4; + + pAddStaParams->maxSPLen = pStaDs->qos.capability.qosInfo.maxSpLen; + limLog( pMac, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"), + pAddStaParams->uAPSD, pAddStaParams->maxSPLen); + } + +#ifdef WLAN_FEATURE_11W + pAddStaParams->rmfEnabled = pStaDs->rmfEnabled; + limLog( pMac, LOG1, FL( "PMF enabled %d"), pAddStaParams->rmfEnabled); +#endif + + limLog(pMac, LOG1, FL("htLdpcCapable: %d vhtLdpcCapable: %d " + "p2pCapableSta: %d"), pAddStaParams->htLdpcCapable, + pAddStaParams->vhtLdpcCapable, pAddStaParams->p2pCapableSta); + +#ifdef SAP_AUTH_OFFLOAD + if (pMac->sap_auth_offload) { + pAddStaParams->dpuIndex = pStaDs->dpuIndex; + pAddStaParams->bcastDpuIndex = pStaDs->bcastDpuIndex; + pAddStaParams->bcastMgmtDpuIdx = pStaDs->bcastMgmtDpuIdx; + pAddStaParams->ucUcastSig = pStaDs->ucUcastSig; + pAddStaParams->ucBcastSig = pStaDs->ucBcastSig; + pAddStaParams->ucMgmtSig = pStaDs->ucMgmtSig; + pAddStaParams->bssIdx = pStaDs->bssId; + } +#endif + + //we need to defer the message until we get the response back from HAL. + if (pAddStaParams->respReqd) + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + +#ifdef SAP_AUTH_OFFLOAD + if (pMac->sap_auth_offload && LIM_IS_AP_ROLE(psessionEntry)) + msgQ.type = WDA_SAP_OFL_ADD_STA; + else + msgQ.type = WDA_ADD_STA_REQ; +#else + msgQ.type = WDA_ADD_STA_REQ; +#endif + + msgQ.reserved = 0; + msgQ.bodyptr = pAddStaParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL( "Sending SIR_HAL_ADD_STA_REQ for assocId %d" ), + pStaDs->assocId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + if (pAddStaParams->respReqd) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog( pMac, LOGE, FL("ADD_STA_REQ for aId %d failed (reason %X)"), + pStaDs->assocId, retCode ); + vos_mem_free(pAddStaParams); + } + + return retCode; +} + + +/** + * limDelSta() + * + *FUNCTION: + * This function is called to delete an STA context at hardware + * whenever a STA is disassociated + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @param fRespReqd - flag to indicate whether the delete is synchronous (true) + * or not (false) + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limDelSta( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_BOOLEAN fRespReqd, + tpPESession psessionEntry) +{ + tpDeleteStaParams pDelStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + pDelStaParams = vos_mem_malloc(sizeof( tDeleteStaParams )); + if (NULL == pDelStaParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set((tANI_U8 *) pDelStaParams, sizeof(tDeleteStaParams), 0); + + // + // DPH contains the STA index only for "peer" STA entries. + // LIM global contains "self" STA index + // Thus, + // if( STA role ) + // get STA index from LIM global + // else + // get STA index from DPH + // + +#if 0 + /* Since we have not created any STA, no need to send msg to delete + * STA to HAL */ + if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) { + pDelStaParams->staIdx = 1; /* TODO : This is workaround. Need to find right STA Index before sending to HAL */ + //return retCode; + } +#endif + +#ifdef FEATURE_WLAN_TDLS + if( ((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) && (pStaDs->staType != STA_ENTRY_TDLS_PEER)) ||(eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ) +#else + if( (eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ||(eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ) +#endif + pDelStaParams->staIdx= psessionEntry->staId; + + else + pDelStaParams->staIdx= pStaDs->staIndex; + + pDelStaParams->assocId = pStaDs->assocId; + pStaDs->valid = 0; + + if (! fRespReqd) + pDelStaParams->respReqd = 0; + else + { + //when limDelSta is called from processSmeAssocCnf then mlmState is already set properly. + if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs)) + { + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs, eLIM_MLM_WT_DEL_STA_RSP_STATE); + } + if ( (eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) || + (eLIM_BT_AMP_STA_ROLE == GET_LIM_SYSTEM_ROLE(psessionEntry)) ) + { + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + + psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + } + pDelStaParams->respReqd = 1; + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + } + + /* Update PE session ID*/ + pDelStaParams->sessionId = psessionEntry->peSessionId; + + pDelStaParams->status = eHAL_STATUS_SUCCESS; +#ifdef SAP_AUTH_OFFLOAD + if (pMac->sap_auth_offload && LIM_IS_AP_ROLE(psessionEntry)) + msgQ.type = WDA_SAP_OFL_DEL_STA; + else + msgQ.type = WDA_DELETE_STA_REQ; +#else + msgQ.type = WDA_DELETE_STA_REQ; +#endif + msgQ.reserved = 0; + msgQ.bodyptr = pDelStaParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL( "Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ " + "for STAID: %X and AssocID: %d MAC : "MAC_ADDRESS_STR ), + pDelStaParams->sessionId, + pDelStaParams->staIdx, pDelStaParams->assocId, + MAC_ADDR_ARRAY(pStaDs->staAddr)); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + if(fRespReqd) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog( pMac, LOGE, FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"), + retCode ); + vos_mem_free(pDelStaParams); + } + + return retCode; +} + +#if defined WLAN_FEATURE_VOWIFI_11R +/*------------------------------------------------------------------------ + * limAddFTStaSelf() + * + * FUNCTION: + * + * This function is called to add a STA once we have connected with a new + * AP, that we have performed an FT to. + * + * The Add STA Response is created and now after the ADD Bss Is Successful + * we add the self sta. We update with the association id from the reassoc + * response from the AP. + *------------------------------------------------------------------------ + */ +tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId, tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + pAddStaParams = pMac->ft.ftPEContext.pAddStaReq; + pAddStaParams->assocId = assocId; + + msgQ.type = SIR_HAL_ADD_STA_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pAddStaParams; + msgQ.bodyval = 0; + + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL( "Sending SIR_HAL_ADD_STA_REQ... (aid %d)" ), pAddStaParams->assocId); +#endif + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE)); + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, FL("Posting ADD_STA_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pAddStaParams); + } + // + // Dont need it any more + pMac->ft.ftPEContext.pAddStaReq = NULL; + return retCode; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + * limAddStaSelf() + * + *FUNCTION: + * This function is called to add an STA context at hardware + * whenever a STA is (Re) Associated. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limAddStaSelf(tpAniSirGlobal pMac,tANI_U16 staIdx, tANI_U8 updateSta, tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMacAddr staMac; + tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF; + tANI_U32 shortGi20MhzSupport; + tANI_U32 shortGi40MhzSupport; + tANI_U32 val; + /*This self Sta dot 11 mode comes from the cfg and the expectation here is + * that cfg carries the systemwide capability that device under + * consideration can support. This capability gets plumbed into the cfg + * cache at system initialization time via the .dat and .ini file override + * mechanisms and will not change. If it does change, it is the + * responsibility of SME to evict the selfSta and reissue a new AddStaSelf + * command.*/ + tANI_U32 selfStaDot11Mode=0, selfTxWidth=0; + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfStaDot11Mode); + limLog( pMac, LOG1, FL("cfgDot11Mode %d"),(int)selfStaDot11Mode); + wlan_cfgGetInt(pMac,WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,&selfTxWidth); + limLog( pMac, LOG1, FL("SGI 20 %d"),(int)selfTxWidth); + limLog( pMac, LOG1, FL("Roam Channel Bonding Mode %d"),(int)pMac->roam.configParam.uCfgDot11Mode); + + #if 0 + retCode =wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, staMac, &cfg); + if (retCode != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve STA MAC")); + return retCode; + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(staMac,psessionEntry->selfMacAddr); + limLog(pMac, LOG1, FL(MAC_ADDRESS_STR": "),MAC_ADDR_ARRAY(staMac)); + pAddStaParams = vos_mem_malloc(sizeof(tAddStaParams)); + if (NULL == pAddStaParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); + + /// Add STA context at MAC HW (BMU, RHP & TFP) + vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, + (tANI_U8 *) staMac, sizeof(tSirMacAddr)); + + vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, + psessionEntry->bssId, sizeof(tSirMacAddr)); + + pAddStaParams->assocId = psessionEntry->limAID; + pAddStaParams->staType = STA_ENTRY_SELF; + pAddStaParams->status = eHAL_STATUS_SUCCESS; + pAddStaParams->respReqd = 1; + pAddStaParams->currentOperChan = psessionEntry->currentOperChannel; + /* Update PE session ID */ + pAddStaParams->sessionId = psessionEntry->peSessionId; + + // This will indicate HAL to "allocate" a new STA index + pAddStaParams->staIdx = staIdx; + pAddStaParams->updateSta = updateSta; + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Get short preamble failed. Set Default value")); + pAddStaParams->shortPreambleSupported = 1; + } + pAddStaParams->shortPreambleSupported = val; + +#ifdef WLAN_FEATURE_11AC + limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry,NULL); +#else + limPopulateOwnRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry); +#endif +// if( psessionEntry->htCapability)---> old check + /*We used to check if the session is htCapable before setting the htCapable + * flag. The check limited us from operating */ + if ( IS_DOT11_MODE_HT(selfStaDot11Mode) ) + { + pAddStaParams->htCapable = TRUE ; +#ifdef DISABLE_GF_FOR_INTEROP + /* + * To resolve the interop problem with Broadcom AP, + * where TQ STA could not pass traffic with GF enabled, + * TQ STA will do Greenfield only with TQ AP, for + * everybody else it will be turned off. + */ + if( (psessionEntry->pLimJoinReq != NULL) && (!psessionEntry->pLimJoinReq->bssDescription.aniIndicator)) + { + limLog( pMac, LOGE, FL(" Turning off Greenfield, when adding self entry")); + pAddStaParams->greenFieldCapable = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } + else +#endif + { + pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); + pAddStaParams->txChannelWidthSet = + pMac->roam.configParam.channelBondingMode5GHz; + // pAddStaParams->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); + pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry ); + pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry ); + pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry ); + pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry ); + pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry ); + pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry); + pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry ); + pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); + /* + * We will read the gShortGI20Mhz from ini file, and if it is set + * to 1 then we will tell Peer that we support 40Mhz short GI + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_20MHZ, + &shortGi20MhzSupport))) + { + if (VOS_TRUE == shortGi20MhzSupport) + { + pAddStaParams->fShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STAMAX; + //pAddStaParams->fShortGI20Mhz = + //limGetHTCapability(pMac, eHT_SHORT_GI_20MHZ, + // psessionEntry); + } + else + { + pAddStaParams->fShortGI20Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" + "CFG,setting value to default"));) + pAddStaParams->fShortGI20Mhz = WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + /* + * We will read the gShortGI40Mhz from ini file, and if it is set + * to 1 then we will tell Peer that we support 40Mhz short GI + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_40MHZ, + &shortGi40MhzSupport))) + { + if (VOS_TRUE == shortGi40MhzSupport) + { + pAddStaParams->fShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STAMAX; + //pAddStaParams->fShortGI40Mhz = + //limGetHTCapability(pMac, eHT_SHORT_GI_40MHZ, + // psessionEntry); + } + else + { + pAddStaParams->fShortGI40Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" + "CFG,setting value to default"));) + pAddStaParams->fShortGI40Mhz = WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + limLog(pMac, LOG1, FL(" greenFieldCapable: %d maxAmpduDensity = %d " + "maxAmpduSize = %d"), pAddStaParams->greenFieldCapable, + pAddStaParams->maxAmpduDensity, pAddStaParams->maxAmpduSize); + + limLog(pMac, LOG1, FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d " + "fShortGI40Mhz: %d lsigTxopProtection: %d"), + pAddStaParams->fDsssCckMode40Mhz, pAddStaParams->fShortGI20Mhz, + pAddStaParams->fShortGI40Mhz, pAddStaParams->lsigTxopProtection); + + limLog(pMac, LOG1, FL(" maxAmsduSize: %d txChannelWidthSet: %d " + "mimoPS: %d rifsMode %d delBASupport %d"), + pAddStaParams->maxAmsduSize, + pAddStaParams->txChannelWidthSet, pAddStaParams->mimoPS, + pAddStaParams->rifsMode, pAddStaParams->delBASupport ); + } + } +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode); + if (pAddStaParams->vhtCapable){ + pAddStaParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; + limLog( pMac, LOG1, FL("VHT WIDTH SET %d"),pAddStaParams->vhtTxChannelWidthSet); + } + pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled; + limLog(pMac, LOG1, FL("vhtCapable: %d vhtTxBFCapable %d "), + pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable); +#endif + + /* For Self STA get the LDPC capability from session i.e config.ini*/ + pAddStaParams->htLdpcCapable = + (psessionEntry->txLdpcIniFeatureEnabled & 0x01); + pAddStaParams->vhtLdpcCapable = + ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); + + if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); + pAddStaParams->listenInterval = (tANI_U16)listenInterval; + + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona) + { + pAddStaParams->p2pCapableSta = 1; + } + + //limFillSupportedRatesInfo(pMac, NULL, &pAddStaParams->supportedRates,psessionEntry); + pAddStaParams->supportedRates.opRateMode = limGetStaRateMode((tANI_U8)selfStaDot11Mode); + + limLog(pMac, LOG1, FL(" StaIdx: %d updateSta = %d htcapable = %d "), + pAddStaParams->staIdx,pAddStaParams->updateSta, + pAddStaParams->htCapable); + + limLog(pMac, LOG1, FL("htLdpcCapable: %d vhtLdpcCapable: %d " + "p2pCapableSta: %d"), + pAddStaParams->htLdpcCapable,pAddStaParams->vhtLdpcCapable, + pAddStaParams->p2pCapableSta); + + limLog(pMac, LOG1, FL(" sessionid: %d Assoc ID: %d listenInterval = %d" + " shortPreambleSupported: %d "), psessionEntry->smeSessionId, + pAddStaParams->assocId, pAddStaParams->listenInterval, + pAddStaParams->shortPreambleSupported); + + msgQ.type = WDA_ADD_STA_REQ; + // + // FIXME_GEN4 + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pAddStaParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, FL(MAC_ADDRESS_STR":Sessionid %d : " + "Sending SIR_HAL_ADD_STA_REQ... (aid %d)" ), + MAC_ADDR_ARRAY(pAddStaParams->staMac), + pAddStaParams->sessionId, + pAddStaParams->assocId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, FL("Posting ADD_STA_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pAddStaParams); + } + return retCode; +} + + +/** + * limTeardownInfraBSS() + * + *FUNCTION: + * This function is called by various LIM functions to teardown + * an established Infrastructure BSS + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limTeardownInfraBss(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + /** + * Send Broadcast Disassociate frame with + * 'leaving BSS' reason. + */ + limSendDisassocMgmtFrame(pMac, + eSIR_MAC_DISASSOC_LEAVING_BSS_REASON, + bcAddr,psessionEntry, FALSE); +} /*** end limTeardownInfraBss() ***/ + + +/** + * limHandleCnfWaitTimeout() + * + *FUNCTION: + * This function is called by limProcessMessageQueue to handle + * various confirmation failure cases. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to a sta descriptor + * @return None + */ + +void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId) +{ + tpDphHashNode pStaDs; + tLimSystemRole systemRole; + tpPESession psessionEntry = NULL; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + systemRole = limGetSystemRole(psessionEntry); + pStaDs = dphGetHashEntry(pMac, staId, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + PELOGW(limLog(pMac, LOGW, FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT."));) + return; + } + + switch (pStaDs->mlmStaContext.mlmState) { + case eLIM_MLM_WT_ASSOC_CNF_STATE: + PELOGW(limLog(pMac, LOGW, FL("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d"), pStaDs->assocId);) + limPrintMacAddr(pMac, pStaDs->staAddr, LOGW); + + if ( (systemRole == eLIM_AP_ROLE)|| (systemRole == eLIM_BT_AMP_AP_ROLE) ) + { + limRejectAssociation( + pMac, + pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, + pStaDs->mlmStaContext.authType, + pStaDs->assocId, + true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry); + } + break; + + default: + limLog(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d"), + pStaDs->mlmStaContext.mlmState); + } +} + + +/** + * limDeleteDphHashEntry() + * + *FUNCTION: + * This function is called whenever we need to delete + * the dph hash entry + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tANI_U16 staId + * @return None + */ + +void +limDeleteDphHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId,tpPESession psessionEntry) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tUpdateBeaconParams beaconParams; + tLimSystemRole systemRole; + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + beaconParams.paramChangeBitmap = 0; + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, staId); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("NULL psessionEntry"));) + return; + } + systemRole = limGetSystemRole(psessionEntry); + beaconParams.bssIdx = psessionEntry->bssIdx; + pStaDs = dphLookupHashEntry(pMac, staAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + PELOGW(limLog(pMac, LOGW, FL("Deleting DPH Hash entry for STAID: %X\n "), staId);) + // update the station count and perform associated actions + // do this before deleting the dph hash entry + limUtilCountStaDel(pMac, pStaDs, psessionEntry); + + if((eLIM_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole)) + { + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE){ + limDecideApProtectionOnDelete(pMac, pStaDs, &beaconParams,psessionEntry); + } + } + + if(eLIM_STA_IN_IBSS_ROLE == systemRole) + limIbssDecideProtectionOnDelete(pMac, pStaDs, &beaconParams, psessionEntry); + + limDecideShortPreamble(pMac, pStaDs, &beaconParams, psessionEntry); + limDecideShortSlot(pMac, pStaDs, &beaconParams, psessionEntry); + + //Send message to HAL about beacon parameter change. + PELOGW(limLog(pMac, LOGW, FL("param bitmap = %d "), beaconParams.paramChangeBitmap);) + if(beaconParams.paramChangeBitmap) + { + schSetFixedBeaconFields(pMac,psessionEntry); + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + +#ifdef WLAN_FEATURE_11W + tx_timer_delete(&pStaDs->pmfSaQueryTimer); +#endif + } + if (dphDeleteHashEntry(pMac, staAddr, staId, &psessionEntry->dph.dphHashTable) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("error deleting hash entry")); + } +} + + + +/** + * limCheckAndAnnounceJoinSuccess() + * + *FUNCTION: + * This function is called upon receiving Beacon/Probe Response + * frame in WT_JOIN_BEACON_STATE to check if the received + * Beacon/Probe Response is from the BSS that we're attempting + * to join. + * + *LOGIC: + * If the Beacon/Probe Response is indeed from the BSS we're + * attempting to join, join success is sent to SME. + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pBPR Pointer to received Beacon/Probe Response + * @param pHdr Pointer to received Beacon/Probe Response + * MAC header + * @return None + */ + +void +limCheckAndAnnounceJoinSuccess(tpAniSirGlobal pMac, + tSirProbeRespBeacon *pBPR, + tpSirMacMgmtHdr pHdr,tpPESession psessionEntry) +{ + tSirMacSSid currentSSID; + tLimMlmJoinCnf mlmJoinCnf; + tANI_U32 val = 0; + tANI_U32 *noa1DurationFromBcn = NULL; + tANI_U32 *noa2DurationFromBcn = NULL; + tANI_U32 noa; + tANI_U32 TotalNum_NoADesc = 0; + + vos_mem_copy(currentSSID.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + + currentSSID.length = (tANI_U8)psessionEntry->ssId.length ; + + if ( + /* Check for SSID only in probe response. Beacons may not carry + SSID information in hidden SSID case */ + ( (SIR_MAC_MGMT_FRAME == pHdr->fc.type) && + (SIR_MAC_MGMT_PROBE_RSP == pHdr->fc.subType) ) && + currentSSID.length && + (!vos_mem_compare((tANI_U8 *) &pBPR->ssId, + (tANI_U8 *) ¤tSSID, + (tANI_U8) (1 + currentSSID.length)) )) + { + /** + * Received SSID does not match with the one we've. + * Ignore received Beacon frame + */ + limLog(pMac, LOG1, FL("SSID received in Beacon does not match")); +#ifdef WLAN_DEBUG + pMac->lim.gLimBcnSSIDMismatchCnt++; +#endif + return; + } + + if( (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_STA_ROLE)) + { + limLog(pMac, LOG1, FL("Received Beacon/PR with matching BSSID" + MAC_ADDRESS_STR "PESessionID %d"), + MAC_ADDR_ARRAY(psessionEntry->bssId), + psessionEntry->peSessionId ); + // Deactivate Join Failure timer + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + // Deactivate Periodic Join timer + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && + pBPR->P2PProbeRes.NoticeOfAbsence.present) + { + + noa1DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + 1); + + if(pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc) + TotalNum_NoADesc = pBPR->P2PProbeRes.NoticeOfAbsence.num_NoADesc/SIZE_OF_NOA_DESCRIPTOR; + + noa = *noa1DurationFromBcn; + + if(TotalNum_NoADesc > 1) + { + noa2DurationFromBcn = (tANI_U32*)(pBPR->P2PProbeRes.NoticeOfAbsence.NoADesc + SIZE_OF_NOA_DESCRIPTOR + 1); + noa += *noa2DurationFromBcn; + } + + /*If MAX Noa exceeds 3 secs we will consider only 3 secs to + * avoid arbitary values in noa duration field + */ + noa = noa > MAX_NOA_PERIOD_IN_MICROSECS ? MAX_NOA_PERIOD_IN_MICROSECS : noa; + noa = noa/1000; //Convert to ms + + if( wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,&val) == eSIR_SUCCESS ) + { + psessionEntry->defaultAuthFailureTimeout = val; + ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT ,val + noa, NULL, eANI_BOOLEAN_FALSE); + } + } + else + { + psessionEntry->defaultAuthFailureTimeout = 0; + } + + // Update Beacon Interval at CFG database + + if ( pBPR->HTCaps.present ) + limUpdateStaRunTimeHTCapability( pMac, &pBPR->HTCaps ); + if ( pBPR->HTInfo.present ) + limUpdateStaRunTimeHTInfo( pMac, &pBPR->HTInfo, psessionEntry); + psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_JOINED_STATE)); + + /* update the capability info based on recently + * received beacon/probe response frame */ + psessionEntry->limCurrentBssCaps = limGetU16((tANI_U8 *) &pBPR->capabilityInfo); + + /** + * Announce join success by sending + * Join confirm to SME. + */ + mlmJoinCnf.resultCode = eSIR_SME_SUCCESS; + mlmJoinCnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS; + /* Update PE sessionId*/ + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); + } // if ((pMac->lim.gLimSystemRole == IBSS.... + + /* Update HS 2.0 Information Element */ + sir_copy_hs20_ie(&psessionEntry->hs20vendor_ie, &pBPR->hs20vendor_ie); +} + +/** + * limExtractApCapabilities() + * + *FUNCTION: + * This function is called to extract all of the AP's capabilities + * from the IEs received from it in Beacon/Probe Response frames + * + *LOGIC: + * This routine mimics the limExtractApCapability() API. The difference here + * is that this API returns the entire tSirProbeRespBeacon info as is. It is + * left to the caller of this API to use this info as required + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pIE Pointer to starting IE in Beacon/Probe Response + * @param ieLen Length of all IEs combined + * @param beaconStruct A pointer to tSirProbeRespBeacon that needs to be + * populated + * @return status A status reporting eSIR_SUCCESS or eSIR_FAILURE + */ +tSirRetStatus limExtractApCapabilities( tpAniSirGlobal pMac, + tANI_U8 *pIE, + tANI_U16 ieLen, + tpSirProbeRespBeacon beaconStruct ) +{ + vos_mem_set((tANI_U8 *) beaconStruct, sizeof( tSirProbeRespBeacon ), 0); + + PELOG3(limLog( pMac, LOG3, + FL( "In limExtractApCapabilities: The IE's being received are:" )); + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );) + + // Parse the Beacon IE's, Don't try to parse if we dont have anything in IE + if (ieLen > 0) { + if( eSIR_SUCCESS != sirParseBeaconIE( pMac, beaconStruct, pIE, (tANI_U32)ieLen )) + { + limLog( pMac, LOGE, FL("APCapExtract: Beacon parsing error!")); + return eSIR_FAILURE; + } + } + + return eSIR_SUCCESS; +} + + +/** + * limDelBss() + * + *FUNCTION: + * This function is called to delete BSS context at hardware + * whenever a STA is disassociated + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the STA datastructure created by + * LIM and maintained by DPH + * @return retCode - Indicates success or failure return code + */ + +tSirRetStatus +limDelBss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tANI_U16 bssIdx,tpPESession psessionEntry) +{ + tpDeleteBssParams pDelBssParams = NULL; + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + pDelBssParams = vos_mem_malloc(sizeof(tDeleteBssParams)); + if (NULL == pDelBssParams) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_BSS" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) pDelBssParams, sizeof(tDeleteBssParams), 0); + + + pDelBssParams->sessionId = psessionEntry->peSessionId; //update PE session Id + + //DPH was storing the AssocID in staID field, + //staID is actually assigned by HAL when AddSTA message is sent. + if (pStaDs != NULL) + { + pDelBssParams->bssIdx= pStaDs->bssId; + pStaDs->valid = 0; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; + } + else + pDelBssParams->bssIdx = bssIdx; + psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE)); + + if((psessionEntry->peSessionId == pMac->lim.limTimers.gLimJoinFailureTimer.sessionId) && + (VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) + { + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + } + + pDelBssParams->status= eHAL_STATUS_SUCCESS; + pDelBssParams->respReqd = 1; + + PELOGW(limLog( pMac, LOGW, FL("Sessionid %d : Sending HAL_DELETE_BSS_REQ " + "for bss idx: %X BSSID:"MAC_ADDRESS_STR), pDelBssParams->sessionId, + pDelBssParams->bssIdx, + MAC_ADDR_ARRAY(psessionEntry->bssId));) + + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_DELETE_BSS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pDelBssParams; + msgQ.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog( pMac, LOGE, FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pDelBssParams); + } + + return retCode; +} + + + +/** + * limSendAddBss() + * + *FUNCTION: + * + *LOGIC: + * 1) LIM receives eWNI_SME_JOIN_REQ + * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends + * SIR_HAL_ADD_BSS_REQ to HAL + * + *ASSUMPTIONS: + * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq + * ADD BSS parameters can be obtained from two sources: + * 1) pMac->lim.gLimMlmJoinReq + * 2) beaconStruct, passed as paramter + * So, if a reqd parameter is found in bssDescriptions + * then it is given preference over beaconStruct + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * pAssocRsp contains the structured assoc/reassoc Response got from AP + * beaconstruct Has the ProbeRsp/Beacon structured details + * bssDescription bssDescription passed to PE from the SME + * @return None + */ + +tSirRetStatus limStaSendAddBss( tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp, + tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry, + tpPESession psessionEntry) + +{ + tSirMsgQ msgQ; + tpAddBssParams pAddBssParams = NULL; + tANI_U32 retCode; + tANI_U8 i; + tpDphHashNode pStaDs = NULL; + tANI_U8 chanWidthSupp = 0; + tANI_U32 shortGi20MhzSupport; + tANI_U32 shortGi40MhzSupport; + // Package SIR_HAL_ADD_BSS_REQ message parameters + pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); + if (NULL == pAddBssParams) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during ADD_BSS" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + else + vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); + + vos_mem_copy(pAddBssParams->bssId,bssDescription->bssId, + sizeof(tSirMacAddr)); + // Fill in tAddBssParams selfMacAddr + vos_mem_copy(pAddBssParams->selfMacAddr, + psessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + + limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), + psessionEntry->smeSessionId,updateEntry,psessionEntry->limSystemRole); + + limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddBssParams->bssId)); + + if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + pAddBssParams->bssType = eSIR_BTAMP_AP_MODE; + } + else + { + pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE; + } + + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + + /* Update PE session ID */ + pAddBssParams->sessionId = psessionEntry->peSessionId; + + pAddBssParams->beaconInterval = bssDescription->beaconInterval; + + pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; + pAddBssParams->updateBss = updateEntry; + + + pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining; + + pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pAssocRsp->supportedRates.rate, pAssocRsp->supportedRates.numRates); + + pAddBssParams->nwType = bssDescription->nwType; + + pAddBssParams->shortSlotTimeSupported = (tANI_U8)pAssocRsp->capabilityInfo.shortSlotTime; + pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist; + pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist; + pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist; + pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist; + + limLog(pMac, LOG1, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d " + "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval, + pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount); + + limLog(pMac, LOG1, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:" + " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod, + pAddBssParams->cfParamSet.cfpMaxDuration, + pAddBssParams->cfParamSet.cfpDurRemaining, + pAddBssParams->rateSet.numRates); + + limLog(pMac, LOG1, FL("nwType:%d shortSlotTimeSupported: %d" + "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"), + pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported, + pAddBssParams->llaCoexist, pAddBssParams->llbCoexist, + pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist); + + // Use the advertised capabilities from the received beacon/PR + + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pAssocRsp->HTCaps.present )) + { + pAddBssParams->htCapable = pAssocRsp->HTCaps.present; + limLog(pMac, LOG1, FL("htCapable: %d"),pAddBssParams->htCapable); + if ( pBeaconStruct->HTInfo.present ) + { + pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pAssocRsp->HTInfo.opMode; + pAddBssParams->dualCTSProtection = ( tANI_U8 ) pAssocRsp->HTInfo.dualCTSProtection; + chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); + if( (pAssocRsp->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet; + pAddBssParams->currentExtChannel = pAssocRsp->HTInfo.secondaryChannelOffset; + } + else + { + pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; + } + pAddBssParams->llnNonGFCoexist = (tANI_U8)pAssocRsp->HTInfo.nonGFDevicesPresent; + pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pAssocRsp->HTInfo.lsigTXOPProtectionFullSupport; + pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode; + + limLog(pMac, LOG1, FL("htOperMode: %d dualCTSProtection: %d " + "txChannelWidthSet: %d currentExtChannel: %d "), + pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection, + pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel); + + limLog(pMac, LOG1, FL("llnNonGFCoexist: %d " + "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"), + pAddBssParams->llnNonGFCoexist, + pAddBssParams->fLsigTXOPProtectionFullSupport, + pAddBssParams->fRIFSMode); + } + } + + pAddBssParams->currentOperChannel = bssDescription->channelId; + limLog(pMac, LOG1, FL("currentOperChannel %d"), + pAddBssParams->currentOperChannel); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && ( pAssocRsp->VHTCaps.present )) + { + pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present; + pAddBssParams->vhtTxChannelWidthSet = pAssocRsp->VHTOperation.chanWidth; + pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, + pAddBssParams->currentOperChannel, + pAddBssParams->currentExtChannel, + psessionEntry->apCenterChan, + psessionEntry); + } + else + { + pAddBssParams->vhtCapable = 0; + } + limLog(pMac, LOG1, FL("vhtCapable %d vhtTxChannelWidthSet %d " + "currentExtChannel %d"),pAddBssParams->vhtCapable, + pAddBssParams->vhtTxChannelWidthSet, + pAddBssParams->currentExtChannel); +#endif + + + // Populate the STA-related parameters here + // Note that the STA here refers to the AP + { + /* staType = PEER*/ + pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA + + vos_mem_copy(pAddBssParams->staContext.bssId, + bssDescription->bssId, + sizeof( tSirMacAddr)); + pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval; + + /* Fill Assoc id from the dph table */ + pStaDs = dphLookupHashEntry(pMac, pAddBssParams->staContext.bssId, + &pAddBssParams->staContext.assocId, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Couldn't get assoc id for " + "MAC ADDR: " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac));) + } + pAddBssParams->staContext.uAPSD = 0; + pAddBssParams->staContext.maxSPLen = 0; + pAddBssParams->staContext.shortPreambleSupported = + psessionEntry->beaconParams.fShortPreamble; + pAddBssParams->staContext.updateSta = updateEntry; + + limLog(pMac, LOG1, FL("StaContext: "MAC_ADDRESS_STR + " shortPreambleSupported: %d"), + MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac), + pAddBssParams->staContext.shortPreambleSupported); + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && pBeaconStruct->HTCaps.present) + { + pAddBssParams->staContext.us32MaxAmpduDuration = 0; + pAddBssParams->staContext.htCapable = 1; + pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 )pAssocRsp->HTCaps.greenField; + pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 )pAssocRsp->HTCaps.lsigTXOPProtection; + limLog(pMac, LOG1,FL("StaContext htCapable: %d greenFieldCapable: %d " + "lsigTxopProtection: %d"), pAddBssParams->staContext.htCapable, + pAddBssParams->staContext.greenFieldCapable, + pAddBssParams->staContext.lsigTxopProtection); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->staContext.vhtCapable = 1; + if ((pAssocRsp->VHTCaps.suBeamFormerCap || + pAssocRsp->VHTCaps.muBeamformerCap) && + psessionEntry->txBFIniFeatureEnabled) + { + pAddBssParams->staContext.vhtTxBFCapable = 1; + } + if (pAssocRsp->VHTCaps.muBeamformerCap && + psessionEntry->txMuBformee ) + { + pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; + limLog(pMac, LOG1,FL("Enabling MUBformeeCapable for peer")); + /* Dont allow any other MuBf session as concurrency + * is not supported + */ + pMac->isMuBfsessionexist = TRUE; + } + } +#endif + if( (pAssocRsp->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pAssocRsp->HTInfo.recommendedTxWidthSet; +#ifdef WLAN_FEATURE_11AC + if (pAddBssParams->staContext.vhtCapable) + { + pAddBssParams->staContext.vhtTxChannelWidthSet = pAssocRsp->VHTOperation.chanWidth; //pMac->lim.apChanWidth; + } + limLog(pMac, LOG1,FL("StaContext vhtCapable %d " + "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), + pAddBssParams->staContext.vhtCapable, + pAddBssParams->staContext.vhtTxChannelWidthSet, + pAddBssParams->staContext.vhtTxBFCapable); +#endif + } + else + { + pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave; + pAddBssParams->staContext.delBASupport = ( tANI_U8 )pAssocRsp->HTCaps.delayedBA; + pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 )pAssocRsp->HTCaps.maximalAMSDUsize; + pAddBssParams->staContext.maxAmpduDensity = pAssocRsp->HTCaps.mpduDensity; + pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz; + /* + * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. + * if they are set then we will use what ever Assoc response coming + * from AP supports. If these values are set as 0 in ini file then + * we will hardcode this values to 0. + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_20MHZ, + &shortGi20MhzSupport))) + { + if (VOS_TRUE == shortGi20MhzSupport) + { + pAddBssParams->staContext.fShortGI20Mhz = + (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz; + } + else + { + pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_40MHZ, + &shortGi40MhzSupport))) + { + if (VOS_TRUE == shortGi40MhzSupport) + { + pAddBssParams->staContext.fShortGI40Mhz = + (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz; + } + else + { + pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + + pAddBssParams->staContext.maxAmpduSize= pAssocRsp->HTCaps.maxRxAMPDUFactor; + if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP ) + { + pAddBssParams->staContext.htLdpcCapable = 0; + pAddBssParams->staContext.vhtLdpcCapable = 0; + } + else + { + if (psessionEntry->txLdpcIniFeatureEnabled & 0x1) + pAddBssParams->staContext.htLdpcCapable = + (tANI_U8)pAssocRsp->HTCaps.advCodingCap; + else + pAddBssParams->staContext.htLdpcCapable = 0; + if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) + pAddBssParams->staContext.vhtLdpcCapable = + (tANI_U8)pAssocRsp->VHTCaps.ldpcCodingCap; + else + pAddBssParams->staContext.vhtLdpcCapable = 0; + } + + if( pBeaconStruct->HTInfo.present ) + pAddBssParams->staContext.rifsMode = pAssocRsp->HTInfo.rifsMode; + + limLog(pMac, LOG1, FL("StaContext txChannelWidthSet: %d mimoPS: %d" + " delBASupport: %d maxAmsduSize: %d"), + pAddBssParams->staContext.txChannelWidthSet, + pAddBssParams->staContext.mimoPS, + pAddBssParams->staContext.delBASupport, + pAddBssParams->staContext.maxAmsduSize); + + limLog(pMac, LOG1, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d " + "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity, + pAddBssParams->staContext.fDsssCckMode40Mhz, + pAddBssParams->staContext.fShortGI20Mhz); + + limLog(pMac, LOG1, FL("fShortGI40Mh: %d maxAmpduSize: %d " + "htLdpcCapable: %d vhtLdpcCapable: %d"), + pAddBssParams->staContext.fShortGI40Mhz, + pAddBssParams->staContext.maxAmpduSize, + pAddBssParams->staContext.htLdpcCapable, + pAddBssParams->staContext.vhtLdpcCapable); + } + + //If WMM IE or 802.11E IE is not present and AP is HT AP then enable WMM + if ((psessionEntry->limWmeEnabled && (pAssocRsp->wmeEdcaPresent || pAddBssParams->htCapable)) || + (psessionEntry->limQosEnabled && (pAssocRsp->edcaPresent || pAddBssParams->htCapable))) + pAddBssParams->staContext.wmmEnabled = 1; + else + pAddBssParams->staContext.wmmEnabled = 0; + + //Update the rates + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + limFillSupportedRatesInfo(pMac, pStaDs, &pStaDs->supportedRates,psessionEntry); + vos_mem_copy((tANI_U8*)&pAddBssParams->staContext.supportedRates, + (tANI_U8*)&pStaDs->supportedRates, + sizeof(tSirSupportedRates)); + } + else + PELOGE(limLog(pMac, LOGE, FL("could not Update the supported rates."));) + + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE; + pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE; + } + + pAddBssParams->staContext.encryptType = psessionEntry->encryptType; + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = psessionEntry->maxTxPower; + limLog(pMac, LOG1,FL("maxTxPower: %d"), + pAddBssParams->maxTxPower); +#endif + // FIXME_GEN4 - Any other value that can be used for initialization? + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = true; + + pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona + + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona) + { + pAddBssParams->staContext.p2pCapableSta = 1; + } + + pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled; + +#if defined WLAN_FEATURE_VOWIFI_11R + pAddBssParams->extSetStaKeyParamValid = 0; + limLog(pMac, LOG1,FL("extSetStaKeyParamValid: %d"), + pAddBssParams->extSetStaKeyParamValid); +#endif + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + pAddBssParams->rmfEnabled = 1; + pAddBssParams->staContext.rmfEnabled = 1; + } +#endif + + // Set a new state for MLME + if( eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState ) + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE; + else + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limLog(pMac, LOG1, FL("staContext wmmEnabled: %d encryptType: %d " + "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled, + pAddBssParams->staContext.encryptType, + pAddBssParams->staContext.p2pCapableSta); + + limLog(pMac, LOG1, FL("bSpectrumMgtEnabled: %d halPersona: %d setting " + "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled, + pAddBssParams->halPersona, psessionEntry->limMlmState); + + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_ADD_BSS_REQ; + /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/ + msgQ.reserved = 0; + msgQ.bodyptr = pAddBssParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL("SessionId:%d Sending SIR_HAL_ADD_BSS_REQ" ), + psessionEntry->peSessionId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAddBssParams); + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), + retCode ); + goto returnFailure; + + } + else + return retCode; + + returnFailure: + // Clean-up will be done by the caller... + return retCode; +} + + + + +tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tpAddBssParams pAddBssParams = NULL; + tANI_U32 retCode; + tANI_U8 i; + tSchBeaconStruct *pBeaconStruct; + tANI_U8 chanWidthSupp = 0; + tANI_U32 shortGi20MhzSupport; + tANI_U32 shortGi40MhzSupport; + tpSirBssDescription bssDescription = &psessionEntry->pLimJoinReq->bssDescription; + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("Unable to allocate memory during ADD_BSS") ); + return eSIR_MEM_ALLOC_FAILED; + } + + + // Package SIR_HAL_ADD_BSS_REQ message parameters + pAddBssParams = vos_mem_malloc(sizeof(tAddBssParams)); + if (NULL == pAddBssParams) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during ADD_BSS" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); + + + limExtractApCapabilities( pMac, + (tANI_U8 *) bssDescription->ieFields, + GET_IE_LEN_IN_BSS(bssDescription->length), + pBeaconStruct ); + + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + vos_mem_copy(pAddBssParams->bssId, bssDescription->bssId, + sizeof(tSirMacAddr)); + + // Fill in tAddBssParams selfMacAddr + vos_mem_copy(pAddBssParams->selfMacAddr, + psessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + limLog(pMac, LOG1, FL("sessionid: %d updateEntry = %d limsystemrole = %d "), + psessionEntry->smeSessionId,updateEntry,psessionEntry->limSystemRole); + + limLog(pMac, LOG1, FL("BSSID: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddBssParams->bssId)); + /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on + * top of an already established Infra link. This lead to issues in + * concurrent data transfer. + */ + + pAddBssParams->bssType = psessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE; + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + + pAddBssParams->beaconInterval = bssDescription->beaconInterval; + + pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; + pAddBssParams->updateBss = updateEntry; + + + pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining; + + + pAddBssParams->rateSet.numRates = pBeaconStruct->supportedRates.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates); + + pAddBssParams->nwType = bssDescription->nwType; + + pAddBssParams->shortSlotTimeSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortSlotTime; + pAddBssParams->llaCoexist = (tANI_U8) psessionEntry->beaconParams.llaCoexist; + pAddBssParams->llbCoexist = (tANI_U8) psessionEntry->beaconParams.llbCoexist; + pAddBssParams->llgCoexist = (tANI_U8) psessionEntry->beaconParams.llgCoexist; + pAddBssParams->ht20Coexist = (tANI_U8) psessionEntry->beaconParams.ht20Coexist; + + limLog(pMac, LOG1, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d " + "cfpCount: %d"),pAddBssParams->bssType, pAddBssParams->beaconInterval, + pAddBssParams->dtimPeriod, pAddBssParams->cfParamSet.cfpCount); + + limLog(pMac, LOG1, FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:" + " %d numRates: %d "),pAddBssParams->cfParamSet.cfpPeriod, + pAddBssParams->cfParamSet.cfpMaxDuration, + pAddBssParams->cfParamSet.cfpDurRemaining, + pAddBssParams->rateSet.numRates); + + limLog(pMac, LOG1, FL("nwType:%d shortSlotTimeSupported: %d" + "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"), + pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported, + pAddBssParams->llaCoexist, pAddBssParams->llbCoexist, + pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist); + // Use the advertised capabilities from the received beacon/PR + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; + limLog(pMac, LOG1, FL("htCapable: %d"),pAddBssParams->htCapable); + if ( pBeaconStruct->HTInfo.present ) + { + pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pBeaconStruct->HTInfo.opMode; + pAddBssParams->dualCTSProtection = ( tANI_U8 ) pBeaconStruct->HTInfo.dualCTSProtection; + + chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry); + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->txChannelWidthSet = ( tANI_U8 ) pBeaconStruct->HTInfo.recommendedTxWidthSet; + pAddBssParams->currentExtChannel = pBeaconStruct->HTInfo.secondaryChannelOffset; + } + else + { + pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; + } + pAddBssParams->llnNonGFCoexist = (tANI_U8)pBeaconStruct->HTInfo.nonGFDevicesPresent; + pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pBeaconStruct->HTInfo.lsigTXOPProtectionFullSupport; + pAddBssParams->fRIFSMode = pBeaconStruct->HTInfo.rifsMode; + + limLog(pMac, LOG1, FL("htOperMode: %d dualCTSProtection: %d " + "txChannelWidthSet: %d currentExtChannel: %d "), + pAddBssParams->htOperMode, pAddBssParams->dualCTSProtection, + pAddBssParams->txChannelWidthSet,pAddBssParams->currentExtChannel); + + limLog(pMac, LOG1, FL("llnNonGFCoexist: %d " + "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"), + pAddBssParams->llnNonGFCoexist, + pAddBssParams->fLsigTXOPProtectionFullSupport, + pAddBssParams->fRIFSMode); + } + } + + pAddBssParams->currentOperChannel = bssDescription->channelId; + limLog(pMac, LOG1, FL("currentOperChannel %d"), + pAddBssParams->currentOperChannel); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present; + pAddBssParams->vhtTxChannelWidthSet = pBeaconStruct->VHTOperation.chanWidth; + pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, + pAddBssParams->currentOperChannel, + pAddBssParams->currentExtChannel, + psessionEntry->apCenterChan, + psessionEntry); + } + else + { + pAddBssParams->vhtCapable = 0; + } + limLog(pMac, LOG1, FL("vhtCapable %d vhtTxChannelWidthSet %d " + "currentExtChannel %d"),pAddBssParams->vhtCapable, + pAddBssParams->vhtTxChannelWidthSet, + pAddBssParams->currentExtChannel); +#endif + + // Populate the STA-related parameters here + // Note that the STA here refers to the AP + { + pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA + + vos_mem_copy(pAddBssParams->staContext.bssId, + bssDescription->bssId, + sizeof(tSirMacAddr)); + pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval; + + pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this? + pAddBssParams->staContext.uAPSD = 0; + pAddBssParams->staContext.maxSPLen = 0; + pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortPreamble; + pAddBssParams->staContext.updateSta = updateEntry; + + limLog(pMac, LOG1, FL("StaContext: "MAC_ADDRESS_STR + " shortPreambleSupported: %d"), + MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac), + pAddBssParams->staContext.shortPreambleSupported); + + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->staContext.us32MaxAmpduDuration = 0; + pAddBssParams->staContext.htCapable = 1; + pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) pBeaconStruct->HTCaps.greenField; + pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) pBeaconStruct->HTCaps.lsigTXOPProtection; + limLog(pMac, LOG1, FL("StaContext htCapable: %d " + "greenFieldCapable: %d lsigTxopProtection: %d"), + pAddBssParams->staContext.htCapable, + pAddBssParams->staContext.greenFieldCapable, + pAddBssParams->staContext.lsigTxopProtection); +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->staContext.vhtCapable = 1; + if ((pBeaconStruct->VHTCaps.suBeamFormerCap || + pBeaconStruct->VHTCaps.muBeamformerCap) && + psessionEntry->txBFIniFeatureEnabled ) + { + pAddBssParams->staContext.vhtTxBFCapable = 1; + } + if (pBeaconStruct->VHTCaps.muBeamformerCap && + psessionEntry->txMuBformee ) + { + pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; + limLog(pMac, LOG1,FL("Enabling MUBformeeCapable for peer")); + /* Dont allow any other MuBf session as concurrency + * is not supported + */ + pMac->isMuBfsessionexist = TRUE; + } + + } +#endif + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet; +#ifdef WLAN_FEATURE_11AC + if (pAddBssParams->staContext.vhtCapable) + { + pAddBssParams->staContext.vhtTxChannelWidthSet = + pBeaconStruct->VHTOperation.chanWidth; + } + limLog(pMac, LOG1,FL("StaContext vhtCapable %d " + "vhtTxChannelWidthSet: %d vhtTxBFCapable: %d"), + pAddBssParams->staContext.vhtCapable, + pAddBssParams->staContext.vhtTxChannelWidthSet, + pAddBssParams->staContext.vhtTxBFCapable); +#endif + } + else + { + pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pBeaconStruct->HTCaps.mimoPowerSave; + pAddBssParams->staContext.delBASupport = ( tANI_U8 ) pBeaconStruct->HTCaps.delayedBA; + pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) pBeaconStruct->HTCaps.maximalAMSDUsize; + pAddBssParams->staContext.maxAmpduDensity = pBeaconStruct->HTCaps.mpduDensity; + pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pBeaconStruct->HTCaps.dsssCckMode40MHz; + /* + * We will check gShortGI20Mhz and gShortGI40Mhz from ini file. + * if they are set then we will use what ever Beacon coming from AP + * supports. If these values are set as 0 in ini file then + * we will hardcode this values to 0. + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_20MHZ, + &shortGi20MhzSupport))) + { + if (VOS_TRUE == shortGi20MhzSupport) + { + pAddBssParams->staContext.fShortGI20Mhz = + (tANI_U8)pBeaconStruct->HTCaps.shortGI20MHz; + } + else + { + pAddBssParams->staContext.fShortGI20Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI20Mhz = + WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + if (HAL_STATUS_SUCCESS(ccmCfgGetInt + (pMac, WNI_CFG_SHORT_GI_40MHZ, + &shortGi40MhzSupport))) + { + if (VOS_TRUE == shortGi40MhzSupport) + { + pAddBssParams->staContext.fShortGI40Mhz = + (tANI_U8)pBeaconStruct->HTCaps.shortGI40MHz; + } + else + { + pAddBssParams->staContext.fShortGI40Mhz = VOS_FALSE; + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz" + "CFG,setting value to default"));) + pAddBssParams->staContext.fShortGI40Mhz = + WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + + pAddBssParams->staContext.maxAmpduSize= pBeaconStruct->HTCaps.maxRxAMPDUFactor; + if( pAddBssParams->staContext.vhtTxBFCapable && pMac->lim.disableLDPCWithTxbfAP ) + { + pAddBssParams->staContext.htLdpcCapable = 0; + pAddBssParams->staContext.vhtLdpcCapable = 0; + } + else + { + if (psessionEntry->txLdpcIniFeatureEnabled & 0x1) + pAddBssParams->staContext.htLdpcCapable = + (tANI_U8)pBeaconStruct->HTCaps.advCodingCap; + else + pAddBssParams->staContext.htLdpcCapable = 0; + if (psessionEntry->txLdpcIniFeatureEnabled & 0x2) + pAddBssParams->staContext.vhtLdpcCapable = + (tANI_U8)pBeaconStruct->VHTCaps.ldpcCodingCap; + else + pAddBssParams->staContext.vhtLdpcCapable = 0; + } + + if( pBeaconStruct->HTInfo.present ) + pAddBssParams->staContext.rifsMode = pBeaconStruct->HTInfo.rifsMode; + limLog(pMac, LOG1, FL("StaContext txChannelWidthSet: %d mimoPS: %d" + " delBASupport: %d maxAmsduSize: %d"), + pAddBssParams->staContext.txChannelWidthSet, + pAddBssParams->staContext.mimoPS, + pAddBssParams->staContext.delBASupport, + pAddBssParams->staContext.maxAmsduSize); + + limLog(pMac, LOG1, FL("maxAmpduDensity: %d fDsssCckMode40Mhz: %d " + "fShortGI20Mhz: %d "),pAddBssParams->staContext.maxAmpduDensity, + pAddBssParams->staContext.fDsssCckMode40Mhz, + pAddBssParams->staContext.fShortGI20Mhz); + + limLog(pMac, LOG1, FL("fShortGI40Mh: %d maxAmpduSize: %d " + "htLdpcCapable: %d vhtLdpcCapable: %d"), + pAddBssParams->staContext.fShortGI40Mhz, + pAddBssParams->staContext.maxAmpduSize, + pAddBssParams->staContext.htLdpcCapable, + pAddBssParams->staContext.vhtLdpcCapable); + } + + //If WMM IE or 802.11E IE is not present and AP is HT AP then enable WMM + if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent || pAddBssParams->staContext.htCapable)) || + (psessionEntry->limQosEnabled && (pBeaconStruct->edcaPresent || pAddBssParams->staContext.htCapable))) + pAddBssParams->staContext.wmmEnabled = 1; + else + pAddBssParams->staContext.wmmEnabled = 0; + + //Update the rates +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry, + &pBeaconStruct->VHTCaps); +#else + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + pBeaconStruct->HTCaps.supportedMCSSet, false,psessionEntry); +#endif + limFillSupportedRatesInfo(pMac, NULL, &pAddBssParams->staContext.supportedRates,psessionEntry); + + } + + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE; + pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE; + } + + pAddBssParams->staContext.encryptType = psessionEntry->encryptType; + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = psessionEntry->maxTxPower; + limLog(pMac, LOG1,FL("maxTxPower: %d"), + pAddBssParams->maxTxPower); +#endif + + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = true; + + pAddBssParams->staContext.sessionId = psessionEntry->peSessionId; + pAddBssParams->sessionId = psessionEntry->peSessionId; + + pAddBssParams->halPersona = (tANI_U8)psessionEntry->pePersona; //update persona + + pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled; + +#if defined WLAN_FEATURE_VOWIFI_11R + pAddBssParams->extSetStaKeyParamValid = 0; + limLog(pMac, LOG1,FL("extSetStaKeyParamValid: %d"), + pAddBssParams->extSetStaKeyParamValid); +#endif + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + pAddBssParams->rmfEnabled = 1; + pAddBssParams->staContext.rmfEnabled = 1; + } +#endif + + // Set a new state for MLME + + //pMac->lim.gLimMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE; + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limLog(pMac, LOG1, FL("staContext wmmEnabled: %d encryptType: %d " + "p2pCapableSta: %d"),pAddBssParams->staContext.wmmEnabled, + pAddBssParams->staContext.encryptType, + pAddBssParams->staContext.p2pCapableSta); + + limLog(pMac, LOG1, FL("bSpectrumMgtEnabled: %d halPersona: %d setting " + "LimMlm state to %d"), pAddBssParams->bSpectrumMgtEnabled, + pAddBssParams->halPersona, psessionEntry->limMlmState); + + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_ADD_BSS_REQ; + /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/ + msgQ.reserved = 0; + msgQ.bodyptr = pAddBssParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL( "SessionId:%d Sending SIR_HAL_ADD_BSS_REQ" ), + psessionEntry->peSessionId); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAddBssParams); + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), + retCode ); + goto returnFailure; + + } + else + { + vos_mem_free(pBeaconStruct); + return retCode; + } + + returnFailure: + // Clean-up will be done by the caller... + vos_mem_free(pBeaconStruct); + return retCode; +} + + + + + + +/** ------------------------------------------------------------- +\fn limPrepareAndSendDelStaCnf +\brief deletes DPH entry + changes the MLM mode for station. + calls limSendDelStaCnf +\param tpAniSirGlobal pMac +\param tpDphHashNode pStaDs +\return none + -------------------------------------------------------------*/ + + +void +limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession psessionEntry) +{ + tANI_U16 staDsAssocId = 0; + tSirMacAddr staDsAddr; + tLimMlmStaContext mlmStaContext; + + if(pStaDs == NULL) + { + PELOGW(limLog(pMac, LOGW, FL("pStaDs is NULL"));) + return; + } + staDsAssocId = pStaDs->assocId; + vos_mem_copy((tANI_U8 *)staDsAddr, + pStaDs->staAddr, + sizeof(tSirMacAddr)); + + mlmStaContext = pStaDs->mlmStaContext; + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + } + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry); + + if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + } + limSendDelStaCnf(pMac, staDsAddr, staDsAssocId, mlmStaContext, statusCode,psessionEntry); +} + +/** ------------------------------------------------------------- +\fn limGetStaRateMode +\brief Gets the Station Rate Mode. +\param tANI_U8 dot11Mode +\return none + -------------------------------------------------------------*/ +tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode) +{ + switch(dot11Mode) + { + case WNI_CFG_DOT11_MODE_11A: + return eSTA_11a; + case WNI_CFG_DOT11_MODE_11B: + return eSTA_11b; + case WNI_CFG_DOT11_MODE_11G: + return eSTA_11bg; + case WNI_CFG_DOT11_MODE_11N: + return eSTA_11n; +#ifdef WLAN_FEATURE_11AC + case WNI_CFG_DOT11_MODE_11AC: + return eSTA_11ac; +#endif + case WNI_CFG_DOT11_MODE_ALL: + default: + return eSTA_11n; + + } +} + +/** ------------------------------------------------------------- +\fn limInitPreAuthTimerTable +\brief Initialize the Pre Auth Tanle and creates the timer for + each node for the timeout value got from cfg. +\param tpAniSirGlobal pMac +\param tpLimPreAuthTable pPreAuthTimerTable +\return none + -------------------------------------------------------------*/ +void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable) +{ + tANI_U32 cfgValue; + tANI_U32 authNodeIdx; + tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable; + + // Get AUTH_RSP Timers value + + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /* + ** Could not get AUTH_RSP timeout value + ** from CFG. Log error. + **/ + limLog(pMac, LOGP, + FL("could not retrieve AUTH_RSP timeout value")); + return; + } + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + for(authNodeIdx=0; authNodeIdxnumEntry; authNodeIdx++, pAuthNode++) + { + if (tx_timer_create(&pAuthNode->timer, + "AUTH RESPONSE TIMEOUT", + limAuthResponseTimerHandler, + authNodeIdx, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Cannot create timer. Log error. + limLog(pMac, LOGP, FL("Cannot create Auth Rsp timer of Index :%d."), authNodeIdx); + return; + } + pAuthNode->authNodeIdx = (tANI_U8)authNodeIdx; + pAuthNode->fFree = 1; + } + +} + +/** ------------------------------------------------------------- +\fn limAcquireFreePreAuthNode +\brief Retrives a free Pre Auth node from Pre Auth Table. +\param tpAniSirGlobal pMac +\param tpLimPreAuthTable pPreAuthTimerTable +\return none + -------------------------------------------------------------*/ +tLimPreAuthNode * limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable) +{ + tANI_U32 i; + tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable; + for (i=0; inumEntry; i++,pTempNode++) + { + if (pTempNode->fFree == 1) + { + pTempNode->fFree = 0; + return pTempNode; + } + } + + return NULL; +} + +/** ------------------------------------------------------------- +\fn limGetPreAuthNodeFromIndex +\brief Depending on the Index this retrives the pre auth node. +\param tpAniSirGlobal pMac +\param tpLimPreAuthTable pAuthTable +\param tANI_U32 authNodeIdx +\return none + -------------------------------------------------------------*/ +tLimPreAuthNode * limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac, + tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx) +{ + if ((authNodeIdx >= pAuthTable->numEntry) || (pAuthTable->pTable == NULL)) + { + limLog(pMac, LOGE, FL("Invalid Auth Timer Index : %d NumEntry : %d"), + authNodeIdx, pAuthTable->numEntry); + return NULL; + } + + return pAuthTable->pTable + authNodeIdx; +} + +/* Util API to check if the channels supported by STA is within range */ +tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc) +{ + /* + * Allow all the stations to join with us. + * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs + * as an input into an algorithm used to select a new channel for the BSS. + * The specification of the algorithm is beyond the scope of this amendment. + */ + + return (eSIR_SUCCESS); +} + +/* Util API to check if the txpower supported by STA is within range */ +tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession psessionEntry) +{ + tPowerdBm localMaxTxPower; + tANI_U32 localPwrConstraint; + + localMaxTxPower = cfgGetRegulatoryMaxTransmitPower(pMac, psessionEntry->currentOperChannel); + + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" )); + return eSIR_FAILURE; + } + localMaxTxPower -= (tPowerdBm)localPwrConstraint; + + /** + * The min Tx Power of the associating station should not be greater than (regulatory + * max tx power - local power constraint configured on AP). + */ + if(assoc->powerCapability.minTxPower > localMaxTxPower) + { + limLog(pMac, LOGW, FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d"), + assoc->powerCapability.minTxPower, localMaxTxPower); + return (eSIR_FAILURE); + } + + return (eSIR_SUCCESS); +} + +/** ------------------------------------------------------------- +\fn limFillRxHighestSupportedRate +\brief Fills in the Rx Highest Supported Data Rate field from +\ the 'supported MCS set' field in HT capability element. +\param tpAniSirGlobal pMac +\param tpSirSupportedRates pRates +\param tANI_U8* pSupportedMCSSet +\return none + -------------------------------------------------------------*/ +void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet) +{ + tSirMacRxHighestSupportRate *pRxHighestRate; + tANI_U8 *pBuf; + tANI_U16 rate=0; + + pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET; + rate = limGetU16(pBuf); + + pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate; + *rxHighestRate = pRxHighestRate->rate; + + return; +} + +#ifdef WLAN_FEATURE_11W +/** ------------------------------------------------------------- +\fn limSendSmeUnprotectedMgmtFrameInd +\brief Forwards the unprotected management frame to SME. +\param tpAniSirGlobal pMac +\param frameType - 802.11 frame type +\param frame - frame buffer +\param sessionId - id for the current session +\param psessionEntry - PE session context +\return none + -------------------------------------------------------------*/ +void limSendSmeUnprotectedMgmtFrameInd( + tpAniSirGlobal pMac, tANI_U8 frameType, + tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, + tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirSmeUnprotMgmtFrameInd * pSirSmeMgmtFrame = NULL; + tANI_U16 length; + + length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen; + + pSirSmeMgmtFrame = vos_mem_malloc(length); + if (NULL == pSirSmeMgmtFrame) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd")); + return; + } + vos_mem_set((void*)pSirSmeMgmtFrame, length, 0); + + pSirSmeMgmtFrame->sessionId = sessionId; + pSirSmeMgmtFrame->frameType = frameType; + + vos_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen); + pSirSmeMgmtFrame->frameLen = frameLen; + + mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND; + mmhMsg.bodyptr = pSirSmeMgmtFrame; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/** ------------------------------------------------------------- +\fn limSendSmeTsmIEInd +\brief Forwards the TSM IE information to SME. +\param tpAniSirGlobal pMac +\param psessionEntry - PE session context +\param tid - traffic id +\param state - tsm state (enabled/disabled) +\param measurementInterval - measurement interval +\return none + -------------------------------------------------------------*/ +void limSendSmeTsmIEInd(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval) +{ + tSirMsgQ mmhMsg; + tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL; + + if (!pMac || !psessionEntry) + { + return; + } + pSirSmeTsmIeInd = vos_mem_malloc(sizeof(tSirSmeTsmIEInd)); + if (NULL == pSirSmeTsmIeInd) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for tSirSmeTsmIEInd")); + return; + } + vos_mem_set((void*)pSirSmeTsmIeInd, sizeof(tSirSmeTsmIEInd), 0); + + pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId; + pSirSmeTsmIeInd->tsmIe.tsid = tid; + pSirSmeTsmIeInd->tsmIe.state= state; + pSirSmeTsmIeInd->tsmIe.msmt_interval= measInterval; + + mmhMsg.type = eWNI_SME_TSM_IE_IND; + mmhMsg.bodyptr = pSirSmeTsmIeInd; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h new file mode 100644 index 000000000000..8b4705a8dda4 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limAssocUtils.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limAssocUtils.h contains the utility definitions + * LIM uses while processing Re/Association messages. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ +#ifndef __LIM_ASSOC_UTILS_H +#define __LIM_ASSOC_UTILS_H + +#include "sirApi.h" +#include "sirDebug.h" +#include "cfgApi.h" + +#include "limTypes.h" + + +tANI_U8 limCmpSSid(tpAniSirGlobal, tSirMacSSid *,tpPESession); +tANI_U8 limCompareCapabilities(tpAniSirGlobal, + tSirAssocReq *, + tSirMacCapabilityInfo *,tpPESession); +tANI_U8 limCheckRxBasicRates(tpAniSirGlobal, tSirMacRateSet,tpPESession); +tANI_U8 limCheckRxRSNIeMatch(tpAniSirGlobal, tDot11fIERSN, tpPESession, tANI_U8, tANI_BOOLEAN *); +tANI_U8 limCheckRxWPAIeMatch(tpAniSirGlobal, tDot11fIEWPA, tpPESession, tANI_U8); +tANI_U8 limCheckMCSSet(tpAniSirGlobal pMac, tANI_U8* supportedMCSSet); +void limPostDummyToTmRing(tpAniSirGlobal, tpDphHashNode); +void limPostPacketToTdRing(tpAniSirGlobal, + tpDphHashNode, + tANI_U8); +tSirRetStatus limCleanupRxPath(tpAniSirGlobal, tpDphHashNode,tpPESession); +void limRejectAssociation(tpAniSirGlobal , tSirMacAddr, tANI_U8, + tANI_U8 , tAniAuthType, + tANI_U16, tANI_U8, tSirResultCodes, tpPESession); + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limPopulatePeerRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps); +#else +tSirRetStatus limPopulatePeerRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry); +#endif + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps); + +#else +tSirRetStatus limPopulateOwnRateSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tANI_U8* pSupportedMCSSet, + tANI_U8 basicOnly, + tpPESession psessionEntry); +#endif + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tSirMacRateSet *pOperRateSet, + tSirMacRateSet *pExtRateSet, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps); +#else +tSirRetStatus limPopulateMatchingRateSet(tpAniSirGlobal, + tpDphHashNode, + tSirMacRateSet *, + tSirMacRateSet *, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *, tpPESession); + + +#endif +tSirRetStatus limAddSta(tpAniSirGlobal, tpDphHashNode, tANI_U8, tpPESession); +tSirRetStatus limDelBss(tpAniSirGlobal, tpDphHashNode, tANI_U16, tpPESession); +tSirRetStatus limDelSta(tpAniSirGlobal, tpDphHashNode, tANI_BOOLEAN, tpPESession); +#ifdef WLAN_FEATURE_VOWIFI_11R +tSirRetStatus limAddFTStaSelf(tpAniSirGlobal pMac, tANI_U16 assocId, + tpPESession psessionEntry); +#endif /* WLAN_FEATURE_VOWIFI_11R */ +tSirRetStatus limAddStaSelf(tpAniSirGlobal, tANI_U16, tANI_U8, tpPESession); +tStaRateMode limGetStaRateMode(tANI_U8 dot11Mode); + + +void limTeardownInfraBss(tpAniSirGlobal,tpPESession); +void limRestorePreReassocState(tpAniSirGlobal, + tSirResultCodes, + tANI_U16,tpPESession); +void limPostReassocFailure(tpAniSirGlobal, + tSirResultCodes, + tANI_U16,tpPESession); +eAniBoolean limIsReassocInProgress(tpAniSirGlobal,tpPESession); +void +limSendDelStaCnf(tpAniSirGlobal pMac, tSirMacAddr staDsAddr, + tANI_U16 staDsAssocId, tLimMlmStaContext mlmStaContext, tSirResultCodes statusCode,tpPESession psessionEntry); + +void limHandleCnfWaitTimeout(tpAniSirGlobal pMac, tANI_U16 staId); +void limDeleteDphHashEntry(tpAniSirGlobal, tSirMacAddr, tANI_U16,tpPESession); +void limCheckAndAnnounceJoinSuccess(tpAniSirGlobal, + tSirProbeRespBeacon *, + tpSirMacMgmtHdr,tpPESession); +void limUpdateReAssocGlobals(tpAniSirGlobal pMac, + tpSirAssocRsp pAssocRsp,tpPESession psessionEntry); + +void limUpdateAssocStaDatas(tpAniSirGlobal pMac, + tpDphHashNode pStaDs,tpSirAssocRsp pAssocRsp,tpPESession psessionEntry); +void +limFillSupportedRatesInfo( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpSirSupportedRates pRates, + tpPESession psessionEntry); + +tSirRetStatus limStaSendAddBss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp, + tpSchBeaconStruct pBeaconStruct, tpSirBssDescription bssDescription, tANI_U8 updateEntry, tpPESession psessionEntry); +tSirRetStatus limStaSendAddBssPreAssoc( tpAniSirGlobal pMac, tANI_U8 updateEntry, tpPESession psessionEntry); + +void limPrepareAndSendDelStaCnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tSirResultCodes statusCode,tpPESession); +tSirRetStatus limExtractApCapabilities(tpAniSirGlobal pMac, tANI_U8 * pIE, tANI_U16 ieLen, tpSirProbeRespBeacon beaconStruct); +void limInitPreAuthTimerTable(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable); +tpLimPreAuthNode limAcquireFreePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthTable pPreAuthTimerTable); +tpLimPreAuthNode limGetPreAuthNodeFromIndex(tpAniSirGlobal pMac, tpLimPreAuthTable pAuthTable, tANI_U32 authNodeIdx); + +/* Util API to check if the channels supported by STA is within range */ +tSirRetStatus limIsDot11hSupportedChannelsValid(tpAniSirGlobal pMac, tSirAssocReq *assoc); + +/* Util API to check if the txpower supported by STA is within range */ +tSirRetStatus limIsDot11hPowerCapabilitiesInRange(tpAniSirGlobal pMac, tSirAssocReq *assoc,tpPESession); + +/* API to re-add the same BSS during re-association */ +void limHandleAddBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry); + +/* API to fill in RX Highest Supported data Rate */ +void limFillRxHighestSupportedRate(tpAniSirGlobal pMac, tANI_U16 *rxHighestRate, tANI_U8* pSupportedMCSSet); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +void limSendRetryReassocReqFrame(tpAniSirGlobal pMac, tLimMlmReassocReq *pMlmReassocReq, tpPESession psessionEntry); +#endif +#ifdef WLAN_FEATURE_11W +void limSendSmeUnprotectedMgmtFrameInd(tpAniSirGlobal pMac, tANI_U8 frameType, + tANI_U8 *frame, tANI_U32 frameLen, tANI_U16 sessionId, tpPESession psessionEntry); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void limSendSmeTsmIEInd( tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 tid, tANI_U8 state, tANI_U16 measInterval); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +tANI_U16 __limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf); + +#endif /* __LIM_ASSOC_UTILS_H */ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.c new file mode 100644 index 000000000000..4d2dcc5530ad --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limDebug.c + + \brief implementation for log Debug related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + +#include "limDebug.h" + +void limLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + // Verify against current log level + if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_LIM_MODULE_ID )] ) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_LIM_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.h new file mode 100644 index 000000000000..0025964dc0a9 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limDebug.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limDebug.h contains log function called by LIM module. + * + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_DEBUG_H__ +#define __LIM_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) limLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...); + +/* define this to show more message in the LIM during TDLS development */ +#define LIM_DEBUG_TDLS + +#ifdef LIM_DEBUG_TDLS +#define LIM_LOG_TDLS(x0) x0 +#else +#define LIM_LOG_TDLS(x0) +#endif + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c new file mode 100644 index 000000000000..ba78826ae709 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limFT.c @@ -0,0 +1,1755 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + \brief implementation for PE 11r VoWiFi FT Protocol + + ========================================================================*/ + +/* $Header$ */ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wmmApsd.h" +#include "vos_utils.h" + +#define LIM_FT_RIC_BA_SSN 1 +#define LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 248 +#define LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA 1 +#define LIM_FT_RIC_DESCRIPTOR_MAX_VAR_DATA_LEN 255 + +/*-------------------------------------------------------------------------- + Initialize the FT variables. + ------------------------------------------------------------------------*/ +void limFTOpen(tpAniSirGlobal pMac) +{ + pMac->ft.ftPEContext.pFTPreAuthReq = NULL; + pMac->ft.ftPEContext.psavedsessionEntry = NULL; +} + +/*-------------------------------------------------------------------------- + Cleanup FT variables. + ------------------------------------------------------------------------*/ +void limFTCleanup(tpAniSirGlobal pMac) +{ + if (pMac->ft.ftPEContext.pFTPreAuthReq) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Freeing pFTPreAuthReq= %p", + __func__, pMac->ft.ftPEContext.pFTPreAuthReq);) +#endif + if (pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) + { + vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription); + pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq); + pMac->ft.ftPEContext.pFTPreAuthReq = NULL; + } + + // This is the old session, should be deleted else where. + // We should not be cleaning it here, just set it to NULL. + if (pMac->ft.ftPEContext.psavedsessionEntry) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL", + __func__, pMac->ft.ftPEContext.psavedsessionEntry);) +#endif + pMac->ft.ftPEContext.psavedsessionEntry = NULL; + } + + // This is the extra session we added as part of Auth resp + // clean it up. + if (pMac->ft.ftPEContext.pftSessionEntry) + { + if ((((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->valid) && + (((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->limSmeState == eLIM_SME_WT_REASSOC_STATE)) + { + PELOGE(limLog( pMac, LOGE, "%s: Deleting Preauth Session %d", __func__, ((tpPESession)pMac->ft.ftPEContext.pftSessionEntry)->peSessionId);) + peDeleteSession(pMac, pMac->ft.ftPEContext.pftSessionEntry); + } +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Setting pftSessionEntry= %p to NULL", + __func__, pMac->ft.ftPEContext.pftSessionEntry);) +#endif + pMac->ft.ftPEContext.pftSessionEntry = NULL; + } + + if (pMac->ft.ftPEContext.pAddBssReq) + { + vos_mem_zero(pMac->ft.ftPEContext.pAddBssReq, sizeof(tAddBssParams)); + vos_mem_free(pMac->ft.ftPEContext.pAddBssReq); + pMac->ft.ftPEContext.pAddBssReq = NULL; + } + + if (pMac->ft.ftPEContext.pAddStaReq) + { + vos_mem_free(pMac->ft.ftPEContext.pAddStaReq); + pMac->ft.ftPEContext.pAddStaReq = NULL; + } + + vos_mem_zero(&pMac->ft.ftPEContext, sizeof(tftPEContext)); +} + +/*-------------------------------------------------------------------------- + Init FT variables. + ------------------------------------------------------------------------*/ +void limFTInit(tpAniSirGlobal pMac) +{ + if (pMac->ft.ftPEContext.pFTPreAuthReq) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Freeing pFTPreAuthReq= %p", + __func__, pMac->ft.ftPEContext.pFTPreAuthReq);) +#endif + if (pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) + { + vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription); + pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + + vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq); + pMac->ft.ftPEContext.pFTPreAuthReq = NULL; + } + + // This is the old session, should be deleted else where. + // We should not be cleaning it here, just set it to NULL. + if (pMac->ft.ftPEContext.psavedsessionEntry) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Setting psavedsessionEntry= %p to NULL", + __func__, pMac->ft.ftPEContext.psavedsessionEntry);) +#endif + pMac->ft.ftPEContext.psavedsessionEntry = NULL; + } + + // This is the extra session we added as part of Auth resp + // clean it up. + if (pMac->ft.ftPEContext.pftSessionEntry) + { + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Deleting session = %p ", + __func__, pMac->ft.ftPEContext.pftSessionEntry);) +#endif + /* Delete the previous valid preauth pesession if it is still in + * mMlmState= eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE + * and limSmeState = eLIM_SME_WT_REASSOC_STATE. This means last + * preauth didnt went through and its Session was not deleted. + */ + if ((((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->valid) && + (((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->limSmeState + == eLIM_SME_WT_REASSOC_STATE) && + (((tpPESession)(pMac->ft.ftPEContext.pftSessionEntry))->limMlmState + == eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE) ) + { + limLog( pMac, LOGE, FL("Deleting Preauth Session %d"), + ((tpPESession)pMac->ft.ftPEContext.pftSessionEntry)->peSessionId); + peDeleteSession(pMac, pMac->ft.ftPEContext.pftSessionEntry); + } + + pMac->ft.ftPEContext.pftSessionEntry = NULL; + } + + if (pMac->ft.ftPEContext.pAddBssReq) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Freeing AddBssReq = %p ", + __func__, pMac->ft.ftPEContext.pAddBssReq);) +#endif + vos_mem_free(pMac->ft.ftPEContext.pAddBssReq); + pMac->ft.ftPEContext.pAddBssReq = NULL; + } + + + if (pMac->ft.ftPEContext.pAddStaReq) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: Freeing AddStaReq = %p ", + __func__, pMac->ft.ftPEContext.pAddStaReq);) +#endif + vos_mem_free(pMac->ft.ftPEContext.pAddStaReq); + pMac->ft.ftPEContext.pAddStaReq = NULL; + } + + pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_SUCCESS; + +} + +/*------------------------------------------------------------------ + * + * This is the handler after suspending the link. + * We suspend the link and then now proceed to switch channel. + * + *------------------------------------------------------------------*/ +void FTPreAuthSuspendLinkHandler(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data) +{ + tpPESession psessionEntry; + + // The link is suspended of not ? + if (status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog( pMac, LOGE, "%s: Returning ", __func__);) + // Post the FT Pre Auth Response to SME + limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, (tpPESession)data); + + return; + } + + psessionEntry = (tpPESession)data; + // Suspended, now move to a different channel. + // Perform some sanity check before proceeding. + if ((pMac->ft.ftPEContext.pFTPreAuthReq) && psessionEntry) + { + limChangeChannelWithCallback(pMac, + pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum, + limPerformFTPreAuth, NULL, psessionEntry); + return; + } + + // Else return error. + limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); +} + + +/*-------------------------------------------------------------------------- + In this function, we process the FT Pre Auth Req. + We receive Pre-Auth + Suspend link + Register a call back + In the call back, we will need to accept frames from the new bssid + Send out the auth req to new AP. + Start timer and when the timer is done or if we receive the Auth response + We change channel + Resume link + ------------------------------------------------------------------------*/ +int limProcessFTPreAuthReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + int bufConsumed = FALSE; + tpPESession psessionEntry; + tANI_U8 sessionId; + + // Now we are starting fresh make sure all's cleanup. + limFTInit(pMac); + // Can set it only after sending auth + pMac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE; + + // We need information from the Pre-Auth Req. Lets save that + pMac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)pMsg->bodyptr; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, "%s: PRE Auth ft_ies_length=%02x%02x%02x", __func__, + pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[0], + pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[1], + pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[2]);) +#endif + + // Get the current session entry + psessionEntry = peFindSessionByBssid(pMac, + pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &sessionId); + if (psessionEntry == NULL) + { + PELOGE(limLog( pMac, LOGE, "%s: Unable to find session for the following bssid", + __func__);) + limPrintMacAddr( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE ); + // Post the FT Pre Auth Response to SME + limPostFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, NULL); + + /* return FALSE, since the Pre-Auth Req will be freed in + * limPostFTPreAuthRsp on failure + */ + return bufConsumed; + } + + // Dont need to suspend if APs are in same channel + if (psessionEntry->currentOperChannel != pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) + { + // Need to suspend link only if the channels are different + limLog(pMac, LOG1, FL(" Performing pre-auth on different" + " channel (session %p)"), psessionEntry); + limSuspendLink(pMac, eSIR_CHECK_ROAMING_SCAN, FTPreAuthSuspendLinkHandler, + (tANI_U32 *)psessionEntry); + } + else + { + limLog(pMac, LOG1, FL(" Performing pre-auth on same" + " channel (session %p)"), psessionEntry); + // We are in the same channel. Perform pre-auth + limPerformFTPreAuth(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry); + } + + return bufConsumed; +} + +/*------------------------------------------------------------------ + * Send the Auth1 + * Receive back Auth2 + *------------------------------------------------------------------*/ +void limPerformFTPreAuth(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry) +{ + tSirMacAuthFrameBody authFrame; + + if (psessionEntry->is11Rconnection) + { + // Only 11r assoc has FT IEs. + if (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies == NULL) + { + PELOGE(limLog( pMac, LOGE, + "%s: FTIEs for Auth Req Seq 1 is absent", + __func__);) + goto preauth_fail; + } + } + if (status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog( pMac, LOGE, + "%s: Change channel not successful for FT pre-auth", + __func__);) + goto preauth_fail; + } + pMac->ft.ftPEContext.psavedsessionEntry = psessionEntry; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("Entered wait auth2 state for FT" + " (old session %p)"), + pMac->ft.ftPEContext.psavedsessionEntry); +#endif + + + if (psessionEntry->is11Rconnection) + { + // Now we are on the right channel and need to send out Auth1 and + // receive Auth2. + authFrame.authAlgoNumber = eSIR_FT_AUTH; // Set the auth type to FT + } +#if defined FEATURE_WLAN_ESE || defined FEATURE_WLAN_LFR + else + { + // Will need to make isESEconnection a enum may be for further + // improvements to this to match this algorithm number + authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM; // For now if its ESE and 11r FT. + } +#endif + authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; + authFrame.authStatusCode = 0; + + // Start timer here to come back to operating channel. + pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId = psessionEntry->peSessionId; + if(TX_SUCCESS != tx_timer_activate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer)) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "%s: FT Auth Rsp Timer Start Failed", __func__);) +#endif + pMac->ft.ftPEContext.psavedsessionEntry = NULL; + goto preauth_fail; + } +MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_FT_PREAUTH_RSP_TIMER)); + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, "%s: FT Auth Rsp Timer Started", __func__);) +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, + pMac->lim.pSessionEntry, eSIR_SUCCESS, eSIR_SUCCESS); +#endif + + limSendAuthMgmtFrame(pMac, &authFrame, + pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + LIM_NO_WEP_IN_FC, psessionEntry, eSIR_FALSE); + + return; +preauth_fail: + limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); + return; +} + + +/*------------------------------------------------------------------ + * + * Create the new Add Bss Req to the new AP. + * This will be used when we are ready to FT to the new AP. + * The newly created ft Session entry is passed to this function + * + *------------------------------------------------------------------*/ +tSirRetStatus limFTPrepareAddBssReq( tpAniSirGlobal pMac, + tANI_U8 updateEntry, tpPESession pftSessionEntry, + tpSirBssDescription bssDescription ) +{ + tpAddBssParams pAddBssParams = NULL; + tANI_U8 i; + tANI_U8 chanWidthSupp = 0; + tSchBeaconStruct *pBeaconStruct; + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("Unable to allocate memory for creating ADD_BSS") ); + return eSIR_MEM_ALLOC_FAILED; + } + + // Package SIR_HAL_ADD_BSS_REQ message parameters + pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); + if (NULL == pAddBssParams) + { + vos_mem_free(pBeaconStruct); + limLog( pMac, LOGP, + FL( "Unable to allocate memory for creating ADD_BSS" )); + return (eSIR_MEM_ALLOC_FAILED); + } + + vos_mem_set((tANI_U8 *) pAddBssParams, sizeof( tAddBssParams ), 0); + + + limExtractApCapabilities( pMac, + (tANI_U8 *) bssDescription->ieFields, + GET_IE_LEN_IN_BSS(bssDescription->length), pBeaconStruct); + + if (pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, pftSessionEntry); + + vos_mem_copy(pAddBssParams->bssId, bssDescription->bssId, + sizeof(tSirMacAddr)); + + // Fill in tAddBssParams selfMacAddr + vos_mem_copy(pAddBssParams->selfMacAddr, pftSessionEntry->selfMacAddr, + sizeof(tSirMacAddr)); + + pAddBssParams->bssType = pftSessionEntry->bssType;//eSIR_INFRASTRUCTURE_MODE; + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + + pAddBssParams->beaconInterval = bssDescription->beaconInterval; + + pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod; + pAddBssParams->updateBss = updateEntry; + + + pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pBeaconStruct->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pBeaconStruct->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pBeaconStruct->cfParamSet.cfpDurRemaining; + + + pAddBssParams->rateSet.numRates = pBeaconStruct->supportedRates.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates); + + pAddBssParams->nwType = bssDescription->nwType; + + pAddBssParams->shortSlotTimeSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortSlotTime; + pAddBssParams->llaCoexist = (tANI_U8) pftSessionEntry->beaconParams.llaCoexist; + pAddBssParams->llbCoexist = (tANI_U8) pftSessionEntry->beaconParams.llbCoexist; + pAddBssParams->llgCoexist = (tANI_U8) pftSessionEntry->beaconParams.llgCoexist; + pAddBssParams->ht20Coexist = (tANI_U8) pftSessionEntry->beaconParams.ht20Coexist; + + // Use the advertised capabilities from the received beacon/PR + if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->htCapable = pBeaconStruct->HTCaps.present; + + if ( pBeaconStruct->HTInfo.present ) + { + pAddBssParams->htOperMode = (tSirMacHTOperatingMode)pBeaconStruct->HTInfo.opMode; + pAddBssParams->dualCTSProtection = ( tANI_U8 ) pBeaconStruct->HTInfo.dualCTSProtection; + + chanWidthSupp = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, pftSessionEntry); + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->txChannelWidthSet = ( tANI_U8 ) pBeaconStruct->HTInfo.recommendedTxWidthSet; + pAddBssParams->currentExtChannel = pBeaconStruct->HTInfo.secondaryChannelOffset; + } + else + { + pAddBssParams->txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pAddBssParams->currentExtChannel = PHY_SINGLE_CHANNEL_CENTERED; + } + pAddBssParams->llnNonGFCoexist = (tANI_U8)pBeaconStruct->HTInfo.nonGFDevicesPresent; + pAddBssParams->fLsigTXOPProtectionFullSupport = (tANI_U8)pBeaconStruct->HTInfo.lsigTXOPProtectionFullSupport; + pAddBssParams->fRIFSMode = pBeaconStruct->HTInfo.rifsMode; + } + } + + pAddBssParams->currentOperChannel = bssDescription->channelId; + pftSessionEntry->htSecondaryChannelOffset = pAddBssParams->currentExtChannel; + +#ifdef WLAN_FEATURE_11AC + if (pftSessionEntry->vhtCapability && pftSessionEntry->vhtCapabilityPresentInBeacon) + { + pAddBssParams->vhtCapable = pBeaconStruct->VHTCaps.present; + pAddBssParams->vhtTxChannelWidthSet = pBeaconStruct->VHTOperation.chanWidth; + pAddBssParams->currentExtChannel = limGet11ACPhyCBState ( pMac, + pAddBssParams->currentOperChannel, + pAddBssParams->currentExtChannel, + pftSessionEntry->apCenterChan, + pftSessionEntry); + } + else + { + pAddBssParams->vhtCapable = 0; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL( "SIR_HAL_ADD_BSS_REQ with channel = %d..." ), + pAddBssParams->currentOperChannel); +#endif + + + // Populate the STA-related parameters here + // Note that the STA here refers to the AP + { + pAddBssParams->staContext.staType = STA_ENTRY_OTHER; // Identifying AP as an STA + + vos_mem_copy(pAddBssParams->staContext.bssId, + bssDescription->bssId, + sizeof(tSirMacAddr)); + pAddBssParams->staContext.listenInterval = bssDescription->beaconInterval; + + pAddBssParams->staContext.assocId = 0; // Is SMAC OK with this? + pAddBssParams->staContext.uAPSD = 0; + pAddBssParams->staContext.maxSPLen = 0; + pAddBssParams->staContext.shortPreambleSupported = (tANI_U8)pBeaconStruct->capabilityInfo.shortPreamble; + pAddBssParams->staContext.updateSta = updateEntry; + pAddBssParams->staContext.encryptType = pftSessionEntry->encryptType; + + if (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) && ( pBeaconStruct->HTCaps.present )) + { + pAddBssParams->staContext.us32MaxAmpduDuration = 0; + pAddBssParams->staContext.htCapable = 1; + pAddBssParams->staContext.greenFieldCapable = ( tANI_U8 ) pBeaconStruct->HTCaps.greenField; + pAddBssParams->staContext.lsigTxopProtection = ( tANI_U8 ) pBeaconStruct->HTCaps.lsigTXOPProtection; + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->staContext.txChannelWidthSet = ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet; + } + else + { + pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } +#ifdef WLAN_FEATURE_11AC + if (pftSessionEntry->vhtCapability && + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)) + { + pAddBssParams->staContext.vhtCapable = 1; + if ((pBeaconStruct->VHTCaps.suBeamFormerCap || + pBeaconStruct->VHTCaps.muBeamformerCap) && + pftSessionEntry->txBFIniFeatureEnabled) + { + pAddBssParams->staContext.vhtTxBFCapable = 1; + } + if (pBeaconStruct->VHTCaps.muBeamformerCap && + pftSessionEntry->txMuBformee ) + { + pAddBssParams->staContext.vhtTxMUBformeeCapable = 1; + limLog(pMac, LOG1, FL("Enabling MUBformee for peer")); + } + } +#endif + if( (pBeaconStruct->HTCaps.supportedChannelWidthSet) && + (chanWidthSupp) ) + { + pAddBssParams->staContext.txChannelWidthSet = + ( tANI_U8 )pBeaconStruct->HTInfo.recommendedTxWidthSet; +#ifdef WLAN_FEATURE_11AC + if (pAddBssParams->staContext.vhtCapable) + { + pAddBssParams->staContext.vhtTxChannelWidthSet = + pBeaconStruct->VHTOperation.chanWidth; + } +#endif + } + else + { + pAddBssParams->staContext.txChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + pAddBssParams->staContext.mimoPS = (tSirMacHTMIMOPowerSaveState)pBeaconStruct->HTCaps.mimoPowerSave; + pAddBssParams->staContext.delBASupport = ( tANI_U8 ) pBeaconStruct->HTCaps.delayedBA; + pAddBssParams->staContext.maxAmsduSize = ( tANI_U8 ) pBeaconStruct->HTCaps.maximalAMSDUsize; + pAddBssParams->staContext.maxAmpduDensity = pBeaconStruct->HTCaps.mpduDensity; + pAddBssParams->staContext.fDsssCckMode40Mhz = (tANI_U8)pBeaconStruct->HTCaps.dsssCckMode40MHz; + pAddBssParams->staContext.fShortGI20Mhz = (tANI_U8)pBeaconStruct->HTCaps.shortGI20MHz; + pAddBssParams->staContext.fShortGI40Mhz = (tANI_U8)pBeaconStruct->HTCaps.shortGI40MHz; + pAddBssParams->staContext.maxAmpduSize= pBeaconStruct->HTCaps.maxRxAMPDUFactor; + + if( pBeaconStruct->HTInfo.present ) + pAddBssParams->staContext.rifsMode = pBeaconStruct->HTInfo.rifsMode; + } + + if ((pftSessionEntry->limWmeEnabled && pBeaconStruct->wmeEdcaPresent) || + (pftSessionEntry->limQosEnabled && pBeaconStruct->edcaPresent)) + pAddBssParams->staContext.wmmEnabled = 1; + else + pAddBssParams->staContext.wmmEnabled = 0; + + //Update the rates +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + pBeaconStruct->HTCaps.supportedMCSSet, + false,pftSessionEntry,&pBeaconStruct->VHTCaps); +#else + limPopulatePeerRateSet(pMac, &pAddBssParams->staContext.supportedRates, + beaconStruct.HTCaps.supportedMCSSet, false,pftSessionEntry); +#endif + if (pftSessionEntry->htCapability) + { + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11n; + if (pftSessionEntry->vhtCapability) + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11ac; + } + else + { + if (pftSessionEntry->limRFBand == SIR_BAND_5_GHZ) + { + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11a; + } + else + { + pAddBssParams->staContext.supportedRates.opRateMode = eSTA_11bg; + } + } + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pAddBssParams->staContext.staTCParams[i].txUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].rxUseBA = eBA_DISABLE; + pAddBssParams->staContext.staTCParams[i].txBApolicy = eBA_POLICY_IMMEDIATE; + pAddBssParams->staContext.staTCParams[i].rxBApolicy = eBA_POLICY_IMMEDIATE; + } + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = pftSessionEntry->maxTxPower; +#endif + +#ifdef WLAN_FEATURE_11W + if (pftSessionEntry->limRmfEnabled) + { + pAddBssParams->rmfEnabled = 1; + pAddBssParams->staContext.rmfEnabled = 1; + } +#endif + + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = true; + + pAddBssParams->staContext.sessionId = pftSessionEntry->peSessionId; + pAddBssParams->sessionId = pftSessionEntry->peSessionId; + + // Set a new state for MLME + + pftSessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, pftSessionEntry->peSessionId, eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE)); + pAddBssParams->halPersona=(tANI_U8)pftSessionEntry->pePersona; //pass on the session persona to hal + + pMac->ft.ftPEContext.pAddBssReq = pAddBssParams; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL( "Saving SIR_HAL_ADD_BSS_REQ for pre-auth ap..." )); +#endif + + vos_mem_free(pBeaconStruct); + return 0; +} + +/*------------------------------------------------------------------ + * + * Setup the new session for the pre-auth AP. + * Return the newly created session entry. + * + *------------------------------------------------------------------*/ +tpPESession limFillFTSession(tpAniSirGlobal pMac, + tpSirBssDescription pbssDescription, tpPESession psessionEntry) +{ + tpPESession pftSessionEntry; + tANI_U8 currentBssUapsd; + tPowerdBm localPowerConstraint; + tPowerdBm regMax; + tSchBeaconStruct *pBeaconStruct; + ePhyChanBondState cbMode; + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("Unable to allocate memory for creating limFillFTSession") ); + return NULL; + } + + + + /* Retrieve the session that has already been created and update the entry */ + pftSessionEntry = pMac->ft.ftPEContext.pftSessionEntry; +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + limPrintMacAddr(pMac, pbssDescription->bssId, LOG1); +#endif + pftSessionEntry->limWmeEnabled = psessionEntry->limWmeEnabled; + pftSessionEntry->limQosEnabled = psessionEntry->limQosEnabled; + pftSessionEntry->limWsmEnabled = psessionEntry->limWsmEnabled; + pftSessionEntry->lim11hEnable = psessionEntry->lim11hEnable; + + // Fields to be filled later + pftSessionEntry->pLimJoinReq = NULL; + pftSessionEntry->smeSessionId = 0; + pftSessionEntry->transactionId = 0; + + limExtractApCapabilities( pMac, + (tANI_U8 *) pbssDescription->ieFields, + GET_IE_LEN_IN_BSS(pbssDescription->length), + pBeaconStruct ); + + pftSessionEntry->rateSet.numRates = pBeaconStruct->supportedRates.numRates; + vos_mem_copy(pftSessionEntry->rateSet.rate, + pBeaconStruct->supportedRates.rate, pBeaconStruct->supportedRates.numRates); + + pftSessionEntry->extRateSet.numRates = pBeaconStruct->extendedRates.numRates; + vos_mem_copy(pftSessionEntry->extRateSet.rate, + pBeaconStruct->extendedRates.rate, pftSessionEntry->extRateSet.numRates); + + + pftSessionEntry->ssId.length = pBeaconStruct->ssId.length; + vos_mem_copy(pftSessionEntry->ssId.ssId, pBeaconStruct->ssId.ssId, + pftSessionEntry->ssId.length); + + pftSessionEntry->dot11mode = pMac->ft.ftPEContext.pFTPreAuthReq->dot11mode; + limLog(pMac, LOG1, FL("dot11mode %d"), pftSessionEntry->dot11mode); + pftSessionEntry->vhtCapability = + (IS_DOT11_MODE_VHT(pftSessionEntry->dot11mode) + && IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); + pftSessionEntry->htCapability = (IS_DOT11_MODE_HT(pftSessionEntry->dot11mode) + && pBeaconStruct->HTCaps.present); +#ifdef WLAN_FEATURE_11AC + if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) + && pBeaconStruct->VHTOperation.present) + { + pftSessionEntry->vhtCapabilityPresentInBeacon = 1; + pftSessionEntry->apCenterChan = pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + pftSessionEntry->apChanWidth = pBeaconStruct->VHTOperation.chanWidth; + + pftSessionEntry->txBFIniFeatureEnabled = + pMac->roam.configParam.txBFEnable; + + limLog(pMac, LOG1, FL("txBFIniFeatureEnabled=%d"), + pftSessionEntry->txBFIniFeatureEnabled); + + if (pftSessionEntry->txBFIniFeatureEnabled) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + pftSessionEntry->txBFIniFeatureEnabled) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not set " + "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG")); + } + limLog(pMac, LOG1, FL("txBFCsnValue=%d"), + pMac->roam.configParam.txBFCsnValue); + + if (cfgSetInt(pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, + pMac->roam.configParam.txBFCsnValue) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not set " + "WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED at CFG")); + } + + if (IS_MUMIMO_BFORMEE_CAPABLE) + pftSessionEntry->txMuBformee = + pMac->roam.configParam.txMuBformee; + } + + limLog(pMac, LOG1, FL("txMuBformee = %d"), + pftSessionEntry->txMuBformee); + + if (cfgSetInt(pMac, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, + pftSessionEntry->txMuBformee) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not set " + "WNI_CFG_VHT_MU_BEAMFORMEE_CAP at CFG")); + } + } + else + { + pftSessionEntry->vhtCapabilityPresentInBeacon = 0; + } +#endif + // Self Mac + sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr); + sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId); +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + limPrintMacAddr(pMac, pftSessionEntry->limReAssocbssId, LOG1); +#endif + + /* Store beaconInterval */ + pftSessionEntry->beaconParams.beaconInterval = pbssDescription->beaconInterval; + pftSessionEntry->bssType = psessionEntry->bssType; + + pftSessionEntry->statypeForBss = STA_ENTRY_PEER; + pftSessionEntry->nwType = pbssDescription->nwType; + + /* Copy The channel Id to the session Table */ + pftSessionEntry->limReassocChannelId = pbssDescription->channelId; + pftSessionEntry->currentOperChannel = pbssDescription->channelId; + + + if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) + { + pftSessionEntry->limSystemRole = eLIM_STA_ROLE; + } + else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + } + else + { + /* Throw an error and return and make sure to delete the session.*/ + limLog(pMac, LOGE, FL("Invalid bss type")); + } + + pftSessionEntry->limCurrentBssCaps = pbssDescription->capabilityInfo; + pftSessionEntry->limReassocBssCaps = pbssDescription->capabilityInfo; + if( pMac->roam.configParam.shortSlotTime && + SIR_MAC_GET_SHORT_SLOT_TIME(pftSessionEntry->limReassocBssCaps)) + { + pftSessionEntry->shortSlotTimeSupported = TRUE; + } + + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, pftSessionEntry->currentOperChannel ); + localPowerConstraint = regMax; + limExtractApCapability(pMac, (tANI_U8 *) pbssDescription->ieFields, + GET_IE_LEN_IN_BSS(pbssDescription->length), + &pftSessionEntry->limCurrentBssQosCaps, + &pftSessionEntry->limCurrentBssPropCap, + ¤tBssUapsd , &localPowerConstraint, psessionEntry); + + pftSessionEntry->limReassocBssQosCaps = + pftSessionEntry->limCurrentBssQosCaps; + pftSessionEntry->limReassocBssPropCap = + pftSessionEntry->limCurrentBssPropCap; + + +#ifdef FEATURE_WLAN_ESE + pftSessionEntry->maxTxPower = limGetMaxTxPower(regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap); +#else + pftSessionEntry->maxTxPower = VOS_MIN( regMax , (localPowerConstraint) ); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, "%s: Regulatory max = %d, local power constraint = %d, ini tx power = %d, max tx = %d", + __func__, regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap, pftSessionEntry->maxTxPower ); +#endif + + pftSessionEntry->limRFBand = limGetRFBand(pftSessionEntry->currentOperChannel); + + pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState; + pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, pftSessionEntry->peSessionId, pftSessionEntry->limSmeState)); + + pftSessionEntry->encryptType = psessionEntry->encryptType; + + if (pftSessionEntry->limRFBand == SIR_BAND_2_4_GHZ) + { + cbMode = pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + cbMode = pMac->roam.configParam.channelBondingMode5GHz; + } + pftSessionEntry->htSupportedChannelWidthSet = + cbMode && pBeaconStruct->HTCaps.supportedChannelWidthSet; + pftSessionEntry->htRecommendedTxWidthSet = + pftSessionEntry->htSupportedChannelWidthSet; + if ((pftSessionEntry->limRFBand == SIR_BAND_2_4_GHZ)&& + (pftSessionEntry->htSupportedChannelWidthSet == 1)) + { + limInitOBSSScanParams(pMac, pftSessionEntry); + } + vos_mem_free(pBeaconStruct); + return pftSessionEntry; +} + +/*------------------------------------------------------------------ + * + * Setup the session and the add bss req for the pre-auth AP. + * + *------------------------------------------------------------------*/ +void limFTSetupAuthSession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tpPESession pftSessionEntry; + + // Prepare the session right now with as much as possible. + pftSessionEntry = limFillFTSession(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription, psessionEntry); + + if (pftSessionEntry) + { + pftSessionEntry->is11Rconnection = psessionEntry->is11Rconnection; +#ifdef FEATURE_WLAN_ESE + pftSessionEntry->isESEconnection = psessionEntry->isESEconnection; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + pftSessionEntry->isFastTransitionEnabled = psessionEntry->isFastTransitionEnabled; +#endif + +#ifdef FEATURE_WLAN_LFR + pftSessionEntry->isFastRoamIniFeatureEnabled = psessionEntry->isFastRoamIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_11W + pftSessionEntry->limRmfEnabled = psessionEntry->limRmfEnabled; +#endif + limFTPrepareAddBssReq( pMac, FALSE, pftSessionEntry, + pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription ); + pMac->ft.ftPEContext.pftSessionEntry = pftSessionEntry; + } +} + +/*------------------------------------------------------------------ + * Resume Link Call Back + *------------------------------------------------------------------*/ +void limFTProcessPreAuthResult(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data) +{ + tpPESession psessionEntry; + + if (!pMac->ft.ftPEContext.pFTPreAuthReq) + return; + + psessionEntry = (tpPESession)data; + + if (pMac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) + { + limFTSetupAuthSession(pMac, psessionEntry); + } + + // Post the FT Pre Auth Response to SME + limPostFTPreAuthRsp(pMac, pMac->ft.ftPEContext.ftPreAuthStatus, + pMac->ft.ftPEContext.saved_auth_rsp, + pMac->ft.ftPEContext.saved_auth_rsp_length, psessionEntry); + +} + +/*------------------------------------------------------------------ + * Resume Link Call Back + *------------------------------------------------------------------*/ +void limPerformPostFTPreAuthAndChannelChange(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data, + tpPESession psessionEntry) +{ + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limResumeLink(pMac, limFTProcessPreAuthResult, (tANI_U32 *)psessionEntry); +} + +tSirRetStatus limCreateRICBlockAckIE(tpAniSirGlobal pMac, tANI_U8 tid, tCfgTrafficClass *pTrafficClass, + tANI_U8 *ric_ies, tANI_U32 *ieLength) +{ + /* BlockACK + RIC is not supported now, TODO later to support this */ +#if 0 + tDot11fIERICDataDesc ricIe; + tDot11fFfBAStartingSequenceControl baSsnControl; + tDot11fFfAddBAParameterSet baParamSet; + tDot11fFfBATimeout baTimeout; + + vos_mem_zero(&ricIe, sizeof(tDot11fIERICDataDesc)); + vos_mem_zero(&baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl)); + vos_mem_zero(&baParamSet, sizeof(tDot11fFfAddBAParameterSet)); + vos_mem_zero(&baTimeout, sizeof(tDot11fFfBATimeout)); + + ricIe.present = 1; + ricIe.RICData.present = 1; + ricIe.RICData.resourceDescCount = 1; + ricIe.RICData.Identifier = LIM_FT_RIC_BA_DIALOG_TOKEN_TID_0 + tid; + ricIe.RICDescriptor.present = 1; + ricIe.RICDescriptor.resourceType = LIM_FT_RIC_DESCRIPTOR_RESOURCE_TYPE_BA; + baParamSet.tid = tid; + baParamSet.policy = pTrafficClass->fTxBApolicy; // Immediate Block Ack + baParamSet.bufferSize = pTrafficClass->txBufSize; + vos_mem_copy((v_VOID_t *)&baTimeout, (v_VOID_t *)&pTrafficClass->tuTxBAWaitTimeout, sizeof(baTimeout)); + baSsnControl.fragNumber = 0; + baSsnControl.ssn = LIM_FT_RIC_BA_SSN; + if (ricIe.RICDescriptor.num_variableData < sizeof (ricIe.RICDescriptor.variableData)) { + dot11fPackFfAddBAParameterSet(pMac, &baParamSet, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]); + //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baParamSet, sizeof(tDot11fFfAddBAParameterSet)); + ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfAddBAParameterSet); + } + if (ricIe.RICDescriptor.num_variableData < sizeof (ricIe.RICDescriptor.variableData)) { + dot11fPackFfBATimeout(pMac, &baTimeout, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]); + //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baTimeout, sizeof(tDot11fFfBATimeout)); + ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBATimeout); + } + if (ricIe.RICDescriptor.num_variableData < sizeof (ricIe.RICDescriptor.variableData)) { + dot11fPackFfBAStartingSequenceControl(pMac, &baSsnControl, &ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData]); + //vos_mem_copy(&ricIe.RICDescriptor.variableData[ricIe.RICDescriptor.num_variableData], &baSsnControl, sizeof(tDot11fFfBAStartingSequenceControl)); + ricIe.RICDescriptor.num_variableData += sizeof(tDot11fFfBAStartingSequenceControl); + } + return (tSirRetStatus) dot11fPackIeRICDataDesc(pMac, &ricIe, ric_ies, sizeof(tDot11fIERICDataDesc), ieLength); +#endif + + return eSIR_FAILURE; +} + +tSirRetStatus limFTFillRICBlockAckInfo(tpAniSirGlobal pMac, tANI_U8 *ric_ies, tANI_U32 *ric_ies_length) +{ + tANI_U8 tid = 0; + tpDphHashNode pSta; + tANI_U16 numBA = 0, aid = 0; + tpPESession psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry; + tANI_U32 offset = 0, ieLength = 0; + tSirRetStatus status = eSIR_SUCCESS; + + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, &aid, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + PELOGE(limLog( pMac, LOGE, + FL( "STA context not found for saved session's BSSID " MAC_ADDRESS_STR ), + MAC_ADDR_ARRAY(pMac->ft.ftPEContext.pFTPreAuthReq->currbssId));) + return eSIR_FAILURE; + } + + for (tid = 0; tid < STACFG_MAX_TC; tid++) + { + if (pSta->tcCfg[tid].fUseBATx) + { + status = limCreateRICBlockAckIE(pMac, tid, &pSta->tcCfg[tid], ric_ies + offset, &ieLength); + if (eSIR_SUCCESS == status) + { + // TODO RIC + if ( ieLength > MAX_FTIE_SIZE ) + { + ieLength = 0; + return status; + } + offset += ieLength; + *ric_ies_length += ieLength; + numBA++; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("BA RIC IE creation for TID %d failed with status %d"), tid, status);) + } + } + } + + PELOGE(limLog(pMac, LOGE, FL("Number of BA RIC IEs created = %d: Total length = %d"), numBA, *ric_ies_length);) + return status; +} + +/*------------------------------------------------------------------ + * + * Will post pre auth response to SME. + * + *------------------------------------------------------------------*/ +void limPostFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length, + tpPESession psessionEntry) +{ + tpSirFTPreAuthRsp pFTPreAuthRsp; + tSirMsgQ mmhMsg; + tANI_U16 rspLen = sizeof(tSirFTPreAuthRsp); + // TODO: RIC Support + //tSirRetStatus sirStatus = eSIR_SUCCESS; + + pFTPreAuthRsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rspLen); + if (NULL == pFTPreAuthRsp) + { + PELOGE(limLog( pMac, LOGE, "Failed to allocate memory");) + VOS_ASSERT(pFTPreAuthRsp != NULL); + return; + } + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, FL("Auth Rsp = %p"), pFTPreAuthRsp);) +#endif + + vos_mem_zero(pFTPreAuthRsp, rspLen); + pFTPreAuthRsp->messageType = eWNI_SME_FT_PRE_AUTH_RSP; + pFTPreAuthRsp->length = (tANI_U16) rspLen; + pFTPreAuthRsp->status = status; + if (psessionEntry) + pFTPreAuthRsp->smeSessionId = psessionEntry->smeSessionId; + + // The bssid of the AP we are sending Auth1 to. + if (pMac->ft.ftPEContext.pFTPreAuthReq) + sirCopyMacAddr(pFTPreAuthRsp->preAuthbssId, + pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId); + + // Attach the auth response now back to SME + pFTPreAuthRsp->ft_ies_length = 0; + if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) + { + // Only 11r assoc has FT IEs. + vos_mem_copy(pFTPreAuthRsp->ft_ies, auth_rsp, auth_rsp_length); + pFTPreAuthRsp->ft_ies_length = auth_rsp_length; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ((psessionEntry) && (psessionEntry->is11Rconnection)) + { + /* TODO: RIC SUPPORT Fill in the Block Ack RIC IEs in the preAuthRsp */ + /* + sirStatus = limFTFillRICBlockAckInfo(pMac, pFTPreAuthRsp->ric_ies, + (tANI_U32 *)&pFTPreAuthRsp->ric_ies_length); + if (eSIR_SUCCESS != sirStatus) + { + PELOGE(limLog(pMac, LOGE, FL("Fill RIC BA Info failed with status %d"), sirStatus);) + } + */ + } +#endif + + if (status != eSIR_SUCCESS) + { + /* Ensure that on Pre-Auth failure the cached Pre-Auth Req and + * other allocated memory is freed up before returning. + */ + limLog(pMac, LOG1, "Pre-Auth Failed, Cleanup!"); + limFTCleanup(pMac); + } + + mmhMsg.type = pFTPreAuthRsp->messageType; + mmhMsg.bodyptr = pFTPreAuthRsp; + mmhMsg.bodyval = 0; + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, "Posted Auth Rsp to SME with status of 0x%x", status);) +#endif + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +/*------------------------------------------------------------------ + * + * Send the FT Pre Auth Response to SME when ever we have a status + * ready to be sent to SME + * + * SME will be the one to send it up to the supplicant to receive + * FTIEs which will be required for Reassoc Req. + * + *------------------------------------------------------------------*/ +void limHandleFTPreAuthRsp(tpAniSirGlobal pMac, tSirRetStatus status, + tANI_U8 *auth_rsp, tANI_U16 auth_rsp_length, + tpPESession psessionEntry) +{ + + tpPESession pftSessionEntry; + tANI_U8 sessionId; + tpSirBssDescription pbssDescription; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, + psessionEntry, status, eSIR_SUCCESS); +#endif + + // Save the status of pre-auth + pMac->ft.ftPEContext.ftPreAuthStatus = status; + + // Save the auth rsp, so we can send it to + // SME once we resume link. + pMac->ft.ftPEContext.saved_auth_rsp_length = 0; + if ((auth_rsp != NULL) && (auth_rsp_length < MAX_FTIE_SIZE)) + { + vos_mem_copy(pMac->ft.ftPEContext.saved_auth_rsp, + auth_rsp, auth_rsp_length); + pMac->ft.ftPEContext.saved_auth_rsp_length = auth_rsp_length; + } + + /* Create FT session for the re-association at this point */ + if (pMac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) + { + pbssDescription = pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription; + if((pftSessionEntry = peCreateSession(pMac, pbssDescription->bssId, + &sessionId, pMac->lim.maxStation)) == NULL) + { + limLog(pMac, LOGE, FL("Session Can not be created for pre-auth 11R AP")); + status = eSIR_FAILURE; + pMac->ft.ftPEContext.ftPreAuthStatus = status; + goto out; + } + pftSessionEntry->peSessionId = sessionId; + sirCopyMacAddr(pftSessionEntry->selfMacAddr, psessionEntry->selfMacAddr); + sirCopyMacAddr(pftSessionEntry->limReAssocbssId, pbssDescription->bssId); + pftSessionEntry->bssType = psessionEntry->bssType; + + if (pftSessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) + { + pftSessionEntry->limSystemRole = eLIM_STA_ROLE; + } + else if(pftSessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + pftSessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + } + else + { + limLog(pMac, LOGE, FL("Invalid bss type")); + } + pftSessionEntry->limPrevSmeState = pftSessionEntry->limSmeState; + pftSessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + pMac->ft.ftPEContext.pftSessionEntry = pftSessionEntry; + PELOGE(limLog(pMac, LOG1,"%s:created session (%p) with id = %d", + __func__, pftSessionEntry, pftSessionEntry->peSessionId);) + + /* Update the ReAssoc BSSID of the current session */ + sirCopyMacAddr(psessionEntry->limReAssocbssId, pbssDescription->bssId); + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOG1); + } +out: + if (psessionEntry->currentOperChannel != + pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) + { + // Need to move to the original AP channel + limChangeChannelWithCallback(pMac, psessionEntry->currentOperChannel, + limPerformPostFTPreAuthAndChannelChange, NULL, psessionEntry); + } + else + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOG1, "Pre auth on same channel as connected AP channel %d", + pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum);) +#endif + limFTProcessPreAuthResult(pMac, status, (tANI_U32 *)psessionEntry); + } +} + +/*------------------------------------------------------------------ + * + * This function handles the 11R Reassoc Req from SME + * + *------------------------------------------------------------------*/ +void limProcessMlmFTReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf, + tpPESession psessionEntry) +{ + tANI_U8 smeSessionId = 0; + tANI_U16 transactionId = 0; + tANI_U8 chanNum = 0; + tLimMlmReassocReq *pMlmReassocReq; + tANI_U16 caps; + tANI_U32 val; + tSirMsgQ msgQ; + tSirRetStatus retCode; + tANI_U32 teleBcnEn = 0; + + chanNum = psessionEntry->currentOperChannel; + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId); + psessionEntry->smeSessionId = smeSessionId; + psessionEntry->transactionId = transactionId; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOCIATING, psessionEntry, 0, 0); +#endif + + if (NULL == pMac->ft.ftPEContext.pAddBssReq) + { + limLog(pMac, LOGE, FL("pAddBssReq is NULL")); + return; + } + pMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if (NULL == pMlmReassocReq) + { + // Log error + limLog(pMac, LOGE, FL("call to AllocateMemory failed for mlmReassocReq")); + return; + } + + vos_mem_copy(pMlmReassocReq->peerMacAddr, + psessionEntry->bssId, + sizeof(tSirMacAddr)); + + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve ReassocFailureTimeout value")); + vos_mem_free(pMlmReassocReq); + return; + } + + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) + { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve Capabilities value")); + vos_mem_free(pMlmReassocReq); + return; + } + + lim_update_caps_info_for_bss(pMac, &caps, + psessionEntry->pLimReAssocReq->bssDescription.capabilityInfo); + + limLog(pMac, LOG1, FL("Capabilities info FT Reassoc: 0x%X"), caps); + + pMlmReassocReq->capabilityInfo = caps; + + /* Update PE sessionId*/ + pMlmReassocReq->sessionId = psessionEntry->peSessionId; + + /* If telescopic beaconing is enabled, set listen interval to WNI_CFG_TELE_BCN_MAX_LI */ + if (wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != + eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); + vos_mem_free(pMlmReassocReq); + return; + } + + if (teleBcnEn) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve ListenInterval")); + vos_mem_free(pMlmReassocReq); + return; + } + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve ListenInterval")); + vos_mem_free(pMlmReassocReq); + return; + } + } + if (limSetLinkState(pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + vos_mem_free(pMlmReassocReq); + return; + } + + pMlmReassocReq->listenInterval = (tANI_U16) val; + + psessionEntry->pLimMlmReassocReq = pMlmReassocReq; + + + //we need to defer the message until we get the response back from HAL. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = SIR_HAL_ADD_BSS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pMac->ft.ftPEContext.pAddBssReq; + msgQ.bodyval = 0; + + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL( "Sending SIR_HAL_ADD_BSS_REQ..." )); +#endif + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + vos_mem_free(pMac->ft.ftPEContext.pAddBssReq); + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), + retCode ); + } + // Dont need this anymore + pMac->ft.ftPEContext.pAddBssReq = NULL; + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_LIM_ADD_BS_REQ, NULL, 0); + } + return; +} + +/*------------------------------------------------------------------ + * + * This function is called if preauth response is not received from the AP + * within this timeout while FT in progress + * + *------------------------------------------------------------------*/ +void limProcessFTPreauthRspTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + + // We have failed pre auth. We need to resume link and get back on + // home channel. + limLog(pMac, LOG1, FL("FT Pre-Auth Time Out!!!!")); + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId))== NULL) + { + limLog(pMac, LOGE, FL("Session Does not exist for given sessionID")); + return; + } + + /* To handle the race condition where we recieve preauth rsp after + * timer has expired. + */ + + if (pMac->ft.ftPEContext.pFTPreAuthReq == NULL) + { + limLog(pMac, LOGE, FL("Auth Rsp might already be posted to SME" + " and ftcleanup done! sessionId:%d"), + pMac->lim.limTimers.gLimFTPreAuthRspTimer.sessionId); + return; + } + + if (eANI_BOOLEAN_TRUE == + pMac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) + { + limLog(pMac,LOGE,FL("Auth rsp already posted to SME" + " (session %p)"), psessionEntry); + return; + } + else + { + /* Here we are sending preauth rsp with failure state + * and which is forwarded to SME. Now, if we receive an preauth + * resp from AP with success it would create a FT pesession, but + * will be dropped in SME leaving behind the pesession. + * Mark Preauth rsp processed so that any rsp from AP is dropped in + * limProcessAuthFrameNoSession. + */ + limLog(pMac,LOG1,FL("Auth rsp not yet posted to SME" + " (session %p)"), psessionEntry); + pMac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = + eANI_BOOLEAN_TRUE; + } + // Ok, so attempted at Pre-Auth and failed. If we are off channel. We need + // to get back. + limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); +} + + +/*------------------------------------------------------------------ + * + * This function is called to process the update key request from SME + * + *------------------------------------------------------------------*/ +tANI_BOOLEAN limProcessFTUpdateKey(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ) +{ + tAddBssParams * pAddBssParams; + tSirFTUpdateKeyInfo * pKeyInfo; + tANI_U32 val = 0; + + /* Sanity Check */ + if( pMac == NULL || pMsgBuf == NULL ) + { + return TRUE; + } + if(pMac->ft.ftPEContext.pAddBssReq == NULL) + { + limLog( pMac, LOGE, + FL( "pAddBssReq is NULL" )); + return TRUE; + } + + pAddBssParams = pMac->ft.ftPEContext.pAddBssReq; + pKeyInfo = (tSirFTUpdateKeyInfo *)pMsgBuf; + + /* Store the key information in the ADD BSS parameters */ + pAddBssParams->extSetStaKeyParamValid = 1; + pAddBssParams->extSetStaKeyParam.encType = pKeyInfo->keyMaterial.edType; + vos_mem_copy((tANI_U8 *) &pAddBssParams->extSetStaKeyParam.key, + (tANI_U8 *) &pKeyInfo->keyMaterial.key, sizeof(tSirKeys)); + if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val)) + { + limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC" )); + } + + pAddBssParams->extSetStaKeyParam.singleTidRc = val; + limLog(pMac, LOG1, FL("Key valid %d key len = %d"), + pAddBssParams->extSetStaKeyParamValid, + pAddBssParams->extSetStaKeyParam.key[0].keyLength); + + pAddBssParams->extSetStaKeyParam.staIdx = 0; + + limLog(pMac, LOG1, + FL("BSSID = "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pKeyInfo->bssId)); + + return TRUE; +} + +tSirRetStatus +limProcessFTAggrQosReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf ) +{ + tSirMsgQ msg; + tSirAggrQosReq * aggrQosReq = (tSirAggrQosReq *)pMsgBuf; + tpAggrAddTsParams pAggrAddTsParam; + tpPESession psessionEntry = NULL; + tpLimTspecInfo tspecInfo; + tANI_U8 ac; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U8 sessionId; + int i; + + pAggrAddTsParam = vos_mem_malloc(sizeof(tAggrAddTsParams)); + if (NULL == pAggrAddTsParam) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory() failed"));) + return eSIR_MEM_ALLOC_FAILED; + } + + psessionEntry = peFindSessionByBssid(pMac, aggrQosReq->bssId, &sessionId); + + if (psessionEntry == NULL) { + PELOGE(limLog(pMac, LOGE, FL("psession Entry Null for sessionId = %d"), aggrQosReq->sessionId);) + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + pSta = dphLookupHashEntry(pMac, aggrQosReq->bssId, &aid, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp"));) + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + vos_mem_set((tANI_U8 *)pAggrAddTsParam, + sizeof(tAggrAddTsParams), 0); + pAggrAddTsParam->staIdx = psessionEntry->staId; + // Fill in the sessionId specific to PE + pAggrAddTsParam->sessionId = sessionId; + pAggrAddTsParam->tspecIdx = aggrQosReq->aggrInfo.tspecIdx; + + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + if (aggrQosReq->aggrInfo.tspecIdx & (1<aggrInfo.aggrAddTsInfo[i].tspec; + /* Since AddTS response was successful, check for the PSB flag + * and directional flag inside the TS Info field. + * An AC is trigger enabled AC if the PSB subfield is set to 1 + * in the uplink direction. + * An AC is delivery enabled AC if the PSB subfield is set to 1 + * in the downlink direction. + * An AC is trigger and delivery enabled AC if the PSB subfield + * is set to 1 in the bi-direction field. + */ + if (pTspec->tsinfo.traffic.psb == 1) + { + limSetTspecUapsdMask(pMac, &pTspec->tsinfo, SET_UAPSD_MASK); + } + else + { + limSetTspecUapsdMask(pMac, &pTspec->tsinfo, CLEAR_UAPSD_MASK); + } + /* ADDTS success, so AC is now admitted. We shall now use the default + * EDCA parameters as advertised by AP and send the updated EDCA params + * to HAL. + */ + ac = upToAc(pTspec->tsinfo.traffic.userPrio); + if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + } + else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + else if(pTspec->tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + if (pSta->aniPeer == eANI_BOOLEAN_TRUE) + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_TRUE); + } + else + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pSta->bssId, eANI_BOOLEAN_FALSE); + } + + if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, pTspec, 0, &tspecInfo)) + { + PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed "));) + pMac->lim.gLimAddtsSent = false; + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status. + } + + // Copy the TSPEC paramters + pAggrAddTsParam->tspec[i] = aggrQosReq->aggrInfo.aggrAddTsInfo[i].tspec; + } + } + + msg.type = WDA_AGGR_QOS_REQ; + msg.bodyptr = pAggrAddTsParam; + msg.bodyval = 0; + + /* We need to defer any incoming messages until we get a + * WDA_AGGR_QOS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg() failed"));) + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pAggrAddTsParam); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +void +limFTSendAggrQosRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, + tpAggrAddTsParams aggrQosRsp, tANI_U8 smesessionId) +{ + tpSirAggrQosRsp rsp; + int i = 0; + + if (! rspReqd) + { + return; + } + + rsp = vos_mem_malloc(sizeof(tSirAggrQosRsp)); + if (NULL == rsp) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for tSirAggrQosRsp")); + return; + } + + vos_mem_set((tANI_U8 *) rsp, sizeof(*rsp), 0); + rsp->messageType = eWNI_SME_FT_AGGR_QOS_RSP; + rsp->sessionId = smesessionId; + rsp->length = sizeof(*rsp); + rsp->aggrInfo.tspecIdx = aggrQosRsp->tspecIdx; + + for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ ) + { + if( (1 << i) & aggrQosRsp->tspecIdx ) + { + rsp->aggrInfo.aggrRsp[i].status = aggrQosRsp->status[i]; + rsp->aggrInfo.aggrRsp[i].tspec = aggrQosRsp->tspec[i]; + } + } + + limSendSmeAggrQosRsp(pMac, rsp, smesessionId); + return; +} + + +void limProcessFTAggrQoSRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpAggrAddTsParams pAggrQosRspMsg = NULL; + //tpAggrQosParams pAggrQosRspMsg = NULL; + tAddTsParams addTsParam = {0}; + tpDphHashNode pSta = NULL; + tANI_U16 assocId =0; + tSirMacAddr peerMacAddr; + tANI_U8 rspReqd = 1; + tpPESession psessionEntry = NULL; + int i = 0; + + limLog(pMac, LOG1, FL(" Received AGGR_QOS_RSP from HAL")); + + /* Need to process all the deferred messages enqueued since sending the + SIR_HAL_AGGR_ADD_TS_REQ */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pAggrQosRspMsg = (tpAggrAddTsParams) (limMsg->bodyptr); + if (NULL == pAggrQosRspMsg) + { + PELOGE(limLog(pMac, LOGE, FL("NULL pAggrQosRspMsg"));) + return; + } + + psessionEntry = peFindSessionBySessionId(pMac, pAggrQosRspMsg->sessionId); + if (NULL == psessionEntry) + { + // Cant find session entry + PELOGE(limLog(pMac, LOGE, FL("Cant find session entry for %s"), __func__);) + if( pAggrQosRspMsg != NULL ) + { + vos_mem_free(pAggrQosRspMsg); + } + return; + } + + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + if((((1 << i) & pAggrQosRspMsg->tspecIdx)) && + (pAggrQosRspMsg->status[i] != eHAL_STATUS_SUCCESS)) + { + /* send DELTS to the station */ + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + addTsParam.staIdx = pAggrQosRspMsg->staIdx; + addTsParam.sessionId = pAggrQosRspMsg->sessionId; + addTsParam.tspec = pAggrQosRspMsg->tspec[i]; + addTsParam.tspecIdx = pAggrQosRspMsg->tspecIdx; + + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, + &addTsParam.tspec.tsinfo, + &addTsParam.tspec, psessionEntry); + + pSta = dphLookupAssocId(pMac, addTsParam.staIdx, &assocId, + &psessionEntry->dph.dphHashTable); + if (pSta != NULL) + { + limAdmitControlDeleteTS(pMac, assocId, &addTsParam.tspec.tsinfo, + NULL, (tANI_U8 *)&addTsParam.tspecIdx); + } + } + } + + /* Send the Aggr QoS response to SME */ + + limFTSendAggrQosRsp(pMac, rspReqd, pAggrQosRspMsg, + psessionEntry->smeSessionId); + if( pAggrQosRspMsg != NULL ) + { + vos_mem_free(pAggrQosRspMsg); + } + return; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c new file mode 100644 index 000000000000..4ca42d3df0c3 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.c @@ -0,0 +1,1913 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file limIbssPeerMgmt.cc contains the utility functions + * LIM uses to maintain peers in IBSS. + * Author: Chandra Modumudi + * Date: 03/12/04 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "sirCommon.h" +#include "wniCfg.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limStaHashApi.h" +#include "schApi.h" // schSetFixedBeaconFields for IBSS coalesce +#include "limSecurityUtils.h" +#include "limSendMessages.h" +#include "limSession.h" +#include "limIbssPeerMgmt.h" +#ifdef WLAN_FEATURE_RMC +#include "limRMC.h" +#endif + + +/** + * ibss_peer_find + * + *FUNCTION: + * This function is called while adding a context at + * DPH & Polaris for a peer in IBSS. + * If peer is found in the list, capabilities from the + * returned BSS description are used at DPH node & Polaris. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param macAddr - MAC address of the peer + * + * @return Pointer to peer node if found, else NULL + */ + +static tLimIbssPeerNode * +ibss_peer_find( + tpAniSirGlobal pMac, + tSirMacAddr macAddr) +{ + tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList; + + while (pTempNode != NULL) + { + if (vos_mem_compare((tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr))) + break; + pTempNode = pTempNode->next; + } + return pTempNode; +} /*** end ibss_peer_find() ***/ + +/** + * ibss_peer_add + * + *FUNCTION: + * This is called on a STA in IBSS upon receiving Beacon/ + * Probe Response from a peer. + * + *LOGIC: + * Node is always added to the front of the list + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pPeerNode - Pointer to peer node to be added to the list. + * + * @return None + */ + +static tSirRetStatus +ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode) +{ +#ifdef ANI_SIR_IBSS_PEER_CACHING + tANI_U32 numIbssPeers = (2 * pMac->lim.maxStation); + + if (pMac->lim.gLimNumIbssPeers >= numIbssPeers) + { + /** + * Reached max number of peers to be maintained. + * Delete last entry & add new entry at the beginning. + */ + tLimIbssPeerNode *pTemp, *pPrev; + pTemp = pPrev = pMac->lim.gLimIbssPeerList; + while (pTemp->next != NULL) + { + pPrev = pTemp; + pTemp = pTemp->next; + } + if(pTemp->beacon) + { + vos_mem_free(pTemp->beacon); + } + + vos_mem_free(pTemp); + pPrev->next = NULL; + } + else +#endif + pMac->lim.gLimNumIbssPeers++; + + pPeerNode->next = pMac->lim.gLimIbssPeerList; + pMac->lim.gLimIbssPeerList = pPeerNode; + + return eSIR_SUCCESS; + +} /*** end limAddIbssPeerToList() ***/ + +/** + * ibss_peer_collect + * + *FUNCTION: + * This is called to collect IBSS peer information + * from received Beacon/Probe Response frame from it. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pBD - Pointer to received BD + * @param pPeer - Pointer to IBSS peer node + * + * @return None + */ + +static void +ibss_peer_collect( + tpAniSirGlobal pMac, + tpSchBeaconStruct pBeacon, + tpSirMacMgmtHdr pHdr, + tLimIbssPeerNode *pPeer, + tpPESession psessionEntry) +{ + vos_mem_copy(pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr)); + + pPeer->capabilityInfo = pBeacon->capabilityInfo; + pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent; + pPeer->edcaPresent = pBeacon->edcaPresent; + pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent; + pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent; + + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pBeacon->HTCaps.present)) + { + pPeer->htCapable = pBeacon->HTCaps.present; + vos_mem_copy((tANI_U8 *)pPeer->supportedMCSSet, + (tANI_U8 *)pBeacon->HTCaps.supportedMCSSet, + sizeof(pPeer->supportedMCSSet)); + pPeer->htGreenfield = (tANI_U8)pBeacon->HTCaps.greenField; + pPeer->htSupportedChannelWidthSet = ( tANI_U8 ) pBeacon->HTCaps.supportedChannelWidthSet; + pPeer->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pBeacon->HTCaps.mimoPowerSave; + pPeer->htMaxAmsduLength = ( tANI_U8 ) pBeacon->HTCaps.maximalAMSDUsize; + pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity; + pPeer->htDsssCckRate40MHzSupport = (tANI_U8)pBeacon->HTCaps.dsssCckMode40MHz; + pPeer->htShortGI20Mhz = (tANI_U8)pBeacon->HTCaps.shortGI20MHz; + pPeer->htShortGI40Mhz = (tANI_U8)pBeacon->HTCaps.shortGI40MHz; + pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor; + pPeer->htSecondaryChannelOffset = pBeacon->HTInfo.secondaryChannelOffset; + } + + /* Collect peer VHT capabilities based on the received beacon from the peer */ +#ifdef WLAN_FEATURE_11AC + if (IS_BSS_VHT_CAPABLE(pBeacon->VHTCaps)) + { + pPeer->vhtSupportedChannelWidthSet = pBeacon->VHTOperation.chanWidth; + pPeer->vhtCapable = pBeacon->VHTCaps.present; + + // Collect VHT capabilities from beacon + vos_mem_copy((tANI_U8 *) &pPeer->VHTCaps, + (tANI_U8 *) &pBeacon->VHTCaps, + sizeof(tDot11fIEVHTCaps)); + } +#endif + pPeer->erpIePresent = pBeacon->erpPresent; + + vos_mem_copy((tANI_U8 *) &pPeer->supportedRates, + (tANI_U8 *) &pBeacon->supportedRates, + pBeacon->supportedRates.numRates + 1); + if (pPeer->extendedRatesPresent) + vos_mem_copy((tANI_U8 *) &pPeer->extendedRates, + (tANI_U8 *) &pBeacon->extendedRates, + pBeacon->extendedRates.numRates + 1); + else + pPeer->extendedRates.numRates = 0; + + // TBD copy EDCA parameters + // pPeer->edcaParams; + + pPeer->next = NULL; +} /*** end ibss_peer_collect() ***/ + +// handle change in peer qos/wme capabilities +static void +ibss_sta_caps_update( + tpAniSirGlobal pMac, + tLimIbssPeerNode *pPeerNode, + tpPESession psessionEntry) +{ + tANI_U16 peerIdx; + tpDphHashNode pStaDs; + + pPeerNode->beaconHBCount++; //Update beacon count. + + // if the peer node exists, update its qos capabilities + if ((pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable)) == NULL) + return; + + + //Update HT Capabilities + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable; + if (pPeerNode->htCapable) + { + pStaDs->htGreenfield = pPeerNode->htGreenfield; + pStaDs->htSupportedChannelWidthSet = pPeerNode->htSupportedChannelWidthSet; + pStaDs->htSecondaryChannelOffset = pPeerNode->htSecondaryChannelOffset; + pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState; + pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength; + pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity; + pStaDs->htDsssCckRate40MHzSupport = pPeerNode->htDsssCckRate40MHzSupport; + pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz; + pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz; + pStaDs->htMaxRxAMpduFactor = pPeerNode->htMaxRxAMpduFactor; + // In the future, may need to check for "delayedBA" + // For now, it is IMMEDIATE BA only on ALL TID's + pStaDs->baPolicyFlag = 0xFF; + } + } +#ifdef WLAN_FEATURE_11AC + if ( IS_DOT11_MODE_VHT(psessionEntry->dot11mode) ) + { + pStaDs->mlmStaContext.vhtCapability = pPeerNode->vhtCapable; + if ( pPeerNode->vhtCapable ) + { + pStaDs->vhtSupportedChannelWidthSet = pPeerNode->vhtSupportedChannelWidthSet; + } + } +#endif + + if(IS_DOT11_MODE_PROPRIETARY(psessionEntry->dot11mode) && + pPeerNode->aniIndicator) + { + pStaDs->aniPeer = pPeerNode->aniIndicator; + pStaDs->propCapability = pPeerNode->propCapability; + } + + + // peer is 11e capable but is not 11e enabled yet + // some STA's when joining Airgo IBSS, assert qos capability even when + // they don't suport qos. however, they do not include the edca parameter + // set. so let's check for edcaParam in addition to the qos capability + if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled) && pPeerNode->edcaPresent) + { + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 0; + if (! pStaDs->lleEnabled) + { + pStaDs->lleEnabled = 1; + //dphSetACM(pMac, pStaDs); + } + return; + } + // peer is not 11e capable now but was 11e enabled earlier + else if (pStaDs->lleEnabled) + { + pStaDs->qosMode = 0; + pStaDs->lleEnabled = 0; + } + + // peer is wme capable but is not wme enabled yet + if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled) + { + pStaDs->qosMode = 1; + pStaDs->lleEnabled = 0; + if (! pStaDs->wmeEnabled) + { + pStaDs->wmeEnabled = 1; + //dphSetACM(pMac, pStaDs); + } + return; + } + /* When the peer device supports EDCA parameters, then we were not + considering. Added this code when we saw that one of the Peer Device + was advertising WMM param where we were not honouring that. CR# 210756 + */ + if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) { + pStaDs->qosMode = 1; + pStaDs->lleEnabled = 0; + if (! pStaDs->wmeEnabled) { + pStaDs->wmeEnabled = 1; + } + return; + } + + // peer is not wme capable now but was wme enabled earlier + else if (pStaDs->wmeEnabled) + { + pStaDs->qosMode = 0; + pStaDs->wmeEnabled = 0; + } + +} + +static void +ibss_sta_rates_update( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tLimIbssPeerNode *pPeer, + tpPESession psessionEntry) +{ +#ifdef WLAN_FEATURE_11AC + limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates, + &pPeer->extendedRates, pPeer->supportedMCSSet, + &pStaDs->mlmStaContext.propRateSet,psessionEntry, &pPeer->VHTCaps); +#else + // Populate supported rateset + limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates, + &pPeer->extendedRates, pPeer->supportedMCSSet, + &pStaDs->mlmStaContext.propRateSet,psessionEntry); +#endif + + pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo; +} /*** end ibss_sta_info_update() ***/ + +/** + * ibss_sta_info_update + * + *FUNCTION: + * This is called to program both SW & Polaris context + * for peer in IBSS. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to DPH node + * @param pPeer - Pointer to IBSS peer node + * + * @return None + */ + +static void +ibss_sta_info_update( + tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tLimIbssPeerNode *pPeer, + tpPESession psessionEntry) +{ + pStaDs->staType = STA_ENTRY_PEER; + ibss_sta_caps_update(pMac, pPeer,psessionEntry); + ibss_sta_rates_update(pMac, pStaDs, pPeer,psessionEntry); +} /*** end ibss_sta_info_update() ***/ + +static void +ibss_coalesce_free( + tpAniSirGlobal pMac) +{ + if (pMac->lim.ibssInfo.pHdr != NULL) + vos_mem_free(pMac->lim.ibssInfo.pHdr); + if (pMac->lim.ibssInfo.pBeacon != NULL) + vos_mem_free(pMac->lim.ibssInfo.pBeacon); + + pMac->lim.ibssInfo.pHdr = NULL; + pMac->lim.ibssInfo.pBeacon = NULL; +} + +/* + * save the beacon params for use when adding the bss + */ +static void +ibss_coalesce_save( + tpAniSirGlobal pMac, + tpSirMacMgmtHdr pHdr, + tpSchBeaconStruct pBeacon) +{ + // get rid of any saved info + ibss_coalesce_free(pMac); + + pMac->lim.ibssInfo.pHdr = vos_mem_malloc(sizeof(*pHdr)); + if (NULL == pMac->lim.ibssInfo.pHdr) + { + PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pHdr"));) + return; + } + pMac->lim.ibssInfo.pBeacon = vos_mem_malloc(sizeof(*pBeacon)); + if (NULL == pMac->lim.ibssInfo.pBeacon) + { + PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pBeacon"));) + ibss_coalesce_free(pMac); + return; + } + + vos_mem_copy(pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr)); + vos_mem_copy(pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon)); +} + +/* + * tries to add a new entry to dph hash node + * if necessary, an existing entry is eliminated + */ +static tSirRetStatus +ibss_dph_entry_add( + tpAniSirGlobal pMac, + tSirMacAddr peerAddr, + tpDphHashNode *ppSta, + tpPESession psessionEntry) +{ + tANI_U16 peerIdx; + tpDphHashNode pStaDs; + + *ppSta = NULL; + + pStaDs = dphLookupHashEntry(pMac, peerAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + /* Trying to add context for already existing STA in IBSS */ + PELOGE(limLog(pMac, LOGE, FL("STA exists already "));) + limPrintMacAddr(pMac, peerAddr, LOGE); + return eSIR_FAILURE; + } + + /** + * Assign an AID, delete context existing with that + * AID and then add an entry to hash table maintained + * by DPH module. + */ + peerIdx = limAssignPeerIdx(pMac, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx,psessionEntry); + } + + pStaDs = dphAddHashEntry(pMac, peerAddr, peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for peerIdx/aid=%d MACaddr:"), peerIdx);) + limPrintMacAddr(pMac, peerAddr, LOGE); + return eSIR_FAILURE; + } + + *ppSta = pStaDs; + return eSIR_SUCCESS; +} + +// send a status change notification +static void +ibss_status_chg_notify( + tpAniSirGlobal pMac, + tSirMacAddr peerAddr, + tANI_U16 staIndex, + tANI_U8 ucastSig, + tANI_U8 bcastSig, + tANI_U16 status, + tANI_U8 sessionId) +{ + + tLimIbssPeerNode *peerNode; + tANI_U8 *beacon = NULL; + tANI_U16 bcnLen = 0; + + + peerNode = ibss_peer_find(pMac,peerAddr); + if(peerNode != NULL) + { + if(peerNode->beacon == NULL) peerNode->beaconLen = 0; + beacon = peerNode->beacon; + bcnLen = peerNode->beaconLen; + peerNode->beacon = NULL; + peerNode->beaconLen = 0; + } + + limSendSmeIBSSPeerInd(pMac,peerAddr, staIndex, ucastSig, bcastSig, + beacon, bcnLen, status, sessionId); + + if(beacon != NULL) + { + vos_mem_free(beacon); + } +} + + +static void +ibss_bss_add( + tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tLimMlmStartReq mlmStartReq; + tANI_U32 cfg; + tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr; + tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon; + tANI_U8 numExtRates = 0; + + if ((pHdr == NULL) || (pBeacon == NULL)) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to add BSS (no cached BSS info)"));) + return; + } + + vos_mem_copy(psessionEntry->bssId, pHdr->bssId, + sizeof(tSirMacAddr)); + + #if 0 + if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) pHdr->bssId, sizeof(tSirMacAddr)) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not update BSSID at CFG")); + #endif //TO SUPPORT BT-AMP + + sirCopyMacAddr(pHdr->bssId,psessionEntry->bssId); + /* We need not use global Mac address since per seesion BSSID is available */ + //limSetBssid(pMac, pHdr->bssId); + +#if 0 + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &cfg) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Can't read beacon interval")); +#endif //TO SUPPORT BT-AMP + /* Copy beacon interval from sessionTable */ + cfg = psessionEntry->beaconParams.beaconInterval; + if (cfg != pBeacon->beaconInterval) + #if 0 + if (cfgSetInt(pMac, WNI_CFG_BEACON_INTERVAL, pBeacon->beaconInterval) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Can't update beacon interval")); + #endif//TO SUPPORT BT-AMP + psessionEntry->beaconParams.beaconInterval = pBeacon->beaconInterval; + + /* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to + * adapt to peer's capability with respect to short slot time. Changes have been made to limApplyConfiguration() + * so that the IBSS doesnt blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt + * to peer's short slot using code below. + */ + /* If cfg is already set to current peer's capability then no need to set it again */ + if (psessionEntry->shortSlotTimeSupported != pBeacon->capabilityInfo.shortSlotTime) + { + psessionEntry->shortSlotTimeSupported = pBeacon->capabilityInfo.shortSlotTime; + } + vos_mem_copy((tANI_U8 *) &psessionEntry->pLimStartBssReq->operationalRateSet, + (tANI_U8 *) &pBeacon->supportedRates, + pBeacon->supportedRates.numRates); + + #if 0 + if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pMac->lim.gpLimStartBssReq->operationalRateSet.rate, + pMac->lim.gpLimStartBssReq->operationalRateSet.numRates) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not update OperRateset at CFG")); + #endif //TO SUPPORT BT-AMP + + /** + * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when + * there is no extended rate IE present in beacon. This is especially important when + * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce. + * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to + * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile. + * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued. + * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12. + */ + + if(pBeacon->extendedRatesPresent) + numExtRates = pBeacon->extendedRates.numRates; + if (cfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pBeacon->extendedRates.rate, numExtRates) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not update ExtendedOperRateset at CFG")); + return; + } + + + /* + * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities + * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities + * leaves the IBSS. e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode + * even though all the nodes are capable of doing CB. + * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop. + */ + vos_mem_set((void *) &mlmStartReq, sizeof(mlmStartReq), 0); + + vos_mem_copy(mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr)); + mlmStartReq.rateSet.numRates = psessionEntry->pLimStartBssReq->operationalRateSet.numRates; + vos_mem_copy(&mlmStartReq.rateSet.rate[0], + &psessionEntry->pLimStartBssReq->operationalRateSet.rate[0], + mlmStartReq.rateSet.numRates); + mlmStartReq.bssType = eSIR_IBSS_MODE; + mlmStartReq.beaconPeriod = pBeacon->beaconInterval; + mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType; //psessionEntry->nwType is also OK???? + mlmStartReq.htCapable = psessionEntry->htCapability; + mlmStartReq.htOperMode = pMac->lim.gHTOperMode; + mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection; + mlmStartReq.txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet; + + #if 0 + if (wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_CHANNEL, &cfg) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("CurrentChannel CFG get fialed!")); + #endif + + //mlmStartReq.channelNumber = (tSirMacChanNum) cfg; + + /* reading the channel num from session Table */ + mlmStartReq.channelNumber = psessionEntry->currentOperChannel; + + mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode; + + // Copy the SSID for RxP filtering based on SSID. + vos_mem_copy((tANI_U8 *) &mlmStartReq.ssId, + (tANI_U8 *) &psessionEntry->pLimStartBssReq->ssId, + psessionEntry->pLimStartBssReq->ssId.length + 1); + + limLog(pMac, LOG1, FL("invoking ADD_BSS as part of coalescing!")); + if (limMlmAddBss(pMac, &mlmStartReq,psessionEntry) != eSIR_SME_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("AddBss failure"));) + return; + } + + // Update fields in Beacon + if (schSetFixedBeaconFields(pMac,psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("*** Unable to set fixed Beacon fields ***"));) + return; + } + +} + + + +/* delete the current BSS */ +static void +ibss_bss_delete( + tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tSirRetStatus status; + PELOGW(limLog(pMac, LOGW, FL("Initiating IBSS Delete BSS"));) + if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) + { + limLog(pMac, LOGW, FL("Incorrect LIM MLM state for delBss (%d)"), + psessionEntry->limMlmState); + return; + } + status = limDelBss(pMac, NULL, psessionEntry->bssIdx, psessionEntry); + if (status != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d"), psessionEntry->bssIdx);) +} + +/** + * limIbssInit + * + *FUNCTION: + * This function is called while starting an IBSS + * to initialize list used to maintain IBSS peers. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limIbssInit( + tpAniSirGlobal pMac) +{ + //pMac->lim.gLimIbssActive = 0; + pMac->lim.gLimIbssCoalescingHappened = 0; + pMac->lim.gLimIbssPeerList = NULL; + pMac->lim.gLimNumIbssPeers = 0; + + // ibss info - params for which ibss to join while coalescing + vos_mem_set(&pMac->lim.ibssInfo, sizeof(tAniSirLimIbss), 0); +} /*** end limIbssInit() ***/ + +/** + * limIbssDeleteAllPeers + * + *FUNCTION: + * This function is called to delete all peers. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limIbssDeleteAllPeers( tpAniSirGlobal pMac ,tpPESession psessionEntry) +{ + tLimIbssPeerNode *pCurrNode, *pTempNode; + tpDphHashNode pStaDs; + tANI_U16 peerIdx; + + pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList; + + while (pCurrNode != NULL) + { + if (!pMac->lim.gLimNumIbssPeers) + { + limLog(pMac, LOGP, + FL("Number of peers in the list is zero and node present")); + return; + } + /* Delete the dph entry for the station + * Since it is called to remove all peers, just delete from dph, + * no need to do any beacon related params i.e., dont call limDeleteDphHashEntry + */ + pStaDs = dphLookupHashEntry(pMac, pCurrNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if( pStaDs ) + { + + ibss_status_chg_notify( pMac, pCurrNode->peerMacAddr, pStaDs->staIndex, + pStaDs->ucUcastSig, pStaDs->ucBcastSig, + eWNI_SME_IBSS_PEER_DEPARTED_IND, psessionEntry->smeSessionId ); + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + dphDeleteHashEntry(pMac, pStaDs->staAddr, peerIdx, &psessionEntry->dph.dphHashTable); + } + + pTempNode = pCurrNode->next; + + /* TODO :Sessionize this code */ + /* Fix CR 227642: PeerList should point to the next node since the current node is being + * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this + * peer list to find the next peer. So this list needs to be updated with the no of peers left + * after each iteration in this while loop since one by one peers are deleted (freed) in this + * loop causing the lim.gLimIbssPeerList to point to some freed memory. + */ + pMac->lim.gLimIbssPeerList = pTempNode; + + if(pCurrNode->beacon) + { + vos_mem_free(pCurrNode->beacon); + } + vos_mem_free(pCurrNode); + if (pMac->lim.gLimNumIbssPeers > 0) // be paranoid + pMac->lim.gLimNumIbssPeers--; + pCurrNode = pTempNode; + } + + if (pMac->lim.gLimNumIbssPeers) + limLog(pMac, LOGP, FL("Number of peers[%d] in the list is non-zero"), + pMac->lim.gLimNumIbssPeers); + + pMac->lim.gLimNumIbssPeers = 0; + pMac->lim.gLimIbssPeerList = NULL; + +} +/** + * limIbssDelete + * + *FUNCTION: + * This function is called while tearing down an IBSS. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limIbssDelete( + tpAniSirGlobal pMac,tpPESession psessionEntry) +{ +#ifdef WLAN_FEATURE_RMC + limRmcIbssDelete(pMac); +#endif /* WLAN_FEATURE_RMC */ + + limIbssDeleteAllPeers(pMac,psessionEntry); + + ibss_coalesce_free(pMac); +} /*** end limIbssDelete() ***/ + +/** Commenting this Code as from no where it is being invoked */ +#if 0 +/** + * limIbssPeerDelete + * + *FUNCTION: + * This may be called on a STA in IBSS to delete a peer + * from the list. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param peerMacAddr - MAC address of the peer STA that + * need to be deleted from peer list. + * + * @return None + */ + +void +limIbssPeerDelete(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + tLimIbssPeerNode *pPrevNode, *pTempNode; + + pTempNode = pPrevNode = pMac->lim.gLimIbssPeerList; + + if (pTempNode == NULL) + return; + + while (pTempNode != NULL) + { + if (vos_mem_compare((tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + // Found node to be deleted + if (pMac->lim.gLimIbssPeerList == pTempNode) /** First Node to be deleted*/ + pMac->lim.gLimIbssPeerList = pTempNode->next; + else + pPrevNode->next = pTempNode->next; + + if(pTempNode->beacon) + { + vos_mem_free(pTempNode->beacon); + pTempNode->beacon = NULL; + } + vos_mem_free(pTempNode); + pMac->lim.gLimNumIbssPeers--; + return; + } + + pPrevNode = pTempNode; + pTempNode = pTempNode->next; + } + + // Should not be here + PELOGE(limLog(pMac, LOGE, FL("peer not found in the list, addr= "));) + limPrintMacAddr(pMac, macAddr, LOGE); +} /*** end limIbssPeerDelete() ***/ + +#endif + + +/** ------------------------------------------------------------- +\fn limIbssSetProtection +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limIbssSetProtection(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + + if(!pMac->lim.cfgProtection.fromllb) + { + limLog(pMac, LOG1, FL("protection from 11b is disabled")); + return; + } + + if (enable) + { + psessionEntry->gLim11bParams.protectionEnabled = true; + if(false == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/) + { + PELOGE(limLog(pMac, LOGE, FL("=> IBSS: Enable Protection "));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/) + { + psessionEntry->gLim11bParams.protectionEnabled = false; + PELOGE(limLog(pMac, LOGE, FL("===> IBSS: Disable protection "));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + return; +} + + +/** ------------------------------------------------------------- +\fn limIbssUpdateProtectionParams +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limIbssUpdateProtectionParams(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType, + tpPESession psessionEntry) +{ + tANI_U32 i; + + limLog(pMac,LOG1, FL("A STA is associated:")); + limLog(pMac,LOG1, FL("Addr : ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1); + + for (i=0; ilim.protStaCache[i].active) + { + limLog(pMac, LOG1, FL("Addr: ")); + limPrintMacAddr(pMac, pMac->lim.protStaCache[i].addr, LOG1); + + if (vos_mem_compare(pMac->lim.protStaCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + { + limLog(pMac, LOG1, FL("matching cache entry at %d already active."), i); + return; + } + } + } + + for (i=0; ilim.protStaCache[i].active) + break; + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache"));) + return; + } + + vos_mem_copy(pMac->lim.protStaCache[i].addr, + peerMacAddr, + sizeof(tSirMacAddr)); + + pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType; + pMac->lim.protStaCache[i].active = true; + if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) + { + psessionEntry->gLim11bParams.numSta++; + } + else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) + { + psessionEntry->gLim11gParams.numSta++; + } +} + + +/** ------------------------------------------------------------- +\fn limIbssDecideProtection +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +static void +limIbssDecideProtection(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode; + tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID; + + pBeaconParams->paramChangeBitmap = 0; + + if(NULL == pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("pStaDs is NULL"));) + return; + } + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_2_4_GHZ== rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + + //We are 11G or 11n. Check if we need protection from 11b Stations. + if ((phyMode == WNI_CFG_PHY_MODE_11G) || (psessionEntry->htCapability)) + { + /* As we found in the past, it is possible that a 11n STA sends + * Beacon with HT IE but not ERP IE. So the absense of ERP IE + * in the Beacon is not enough to conclude that STA is 11b. + */ + if ((pStaDs->erpEnabled == eHAL_CLEAR) && + (!pStaDs->mlmStaContext.htCapability)) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB; + PELOGE(limLog(pMac, LOGE, FL("Enable protection from 11B"));) + limIbssSetProtection(pMac, true, pBeaconParams,psessionEntry); + } + } + } + limIbssUpdateProtectionParams(pMac, pStaDs->staAddr, protStaCacheType, psessionEntry); + return; +} + + +/** + * limIbssStaAdd() + * + *FUNCTION: + * This function is called to add an STA context in IBSS role + * whenever a data frame is received from/for a STA that failed + * hash lookup at DPH. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param peerAdddr MAC address of the peer being added + * @return retCode Indicates success or failure return code + * @return + */ + +tSirRetStatus +limIbssStaAdd( + tpAniSirGlobal pMac, + void *pBody, + tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tpDphHashNode pStaDs; + tLimIbssPeerNode *pPeerNode; + tLimMlmStates prevState; + tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody; + tUpdateBeaconParams beaconParams; + + vos_mem_set((tANI_U8 *) &beaconParams, sizeof(tUpdateBeaconParams), 0); + + if (pBody == 0) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid IBSS AddSta"));) + return eSIR_FAILURE; + } + + PELOGE(limLog(pMac, LOGE, FL("Rx Add-Ibss-Sta for MAC:"));) + limPrintMacAddr(pMac, *pPeerAddr, LOGE); + + pPeerNode = ibss_peer_find(pMac, *pPeerAddr); + if (NULL != pPeerNode) + { + retCode = ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs, psessionEntry); + if (eSIR_SUCCESS == retCode) + { + prevState = pStaDs->mlmStaContext.mlmState; + pStaDs->erpEnabled = pPeerNode->erpIePresent; + + ibss_sta_info_update(pMac, pStaDs, pPeerNode, psessionEntry); + PELOGW(limLog(pMac, LOGW, FL("initiating ADD STA for the IBSS peer."));) + retCode = limAddSta(pMac, pStaDs, false, psessionEntry); + if (retCode != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("ibss-sta-add failed (reason %x)"), + retCode);) + limPrintMacAddr(pMac, *pPeerAddr, LOGE); + pStaDs->mlmStaContext.mlmState = prevState; + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, + &psessionEntry->dph.dphHashTable); + } + else + { + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limIbssDecideProtection(pMac, pStaDs, &beaconParams , psessionEntry); + + if(beaconParams.paramChangeBitmap) + { + PELOGE(limLog(pMac, LOGE, FL("---> Update Beacon Params "));) + schSetFixedBeaconFields(pMac, psessionEntry); + beaconParams.bssIdx = psessionEntry->bssIdx; + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("hashTblAdd failed (reason %x)"), retCode);) + limPrintMacAddr(pMac, *pPeerAddr, LOGE); + } + } + else + { + retCode = eSIR_FAILURE; + } + + return retCode; +} + +static void +__limIbssSearchAndDeletePeer(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacAddr macAddr) +{ + tLimIbssPeerNode *pTempNode, *pPrevNode; + tLimIbssPeerNode *pTempNextNode = NULL; + tpDphHashNode pStaDs=NULL; + tANI_U16 peerIdx=0; + tANI_U16 staIndex=0; + tANI_U8 ucUcastSig; + tANI_U8 ucBcastSig; + + pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList; + + limLog(pMac, LOG1, + FL(" PEER ADDR :" MAC_ADDRESS_STR ),MAC_ADDR_ARRAY(macAddr)); + + /** Compare Peer */ + while (NULL != pTempNode) + { + pTempNextNode = pTempNode->next; + + /* Delete the STA with MAC address */ + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + pStaDs = dphLookupHashEntry(pMac, macAddr, + &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + staIndex = pStaDs->staIndex; + ucUcastSig = pStaDs->ucUcastSig; + ucBcastSig = pStaDs->ucBcastSig; + +#ifdef WLAN_FEATURE_RMC + limRmcTransmitterDelete(pMac, pStaDs->staAddr); +#endif /* WLAN_FEATURE_RMC */ + + /* Send DEL STA only if STA id is valid, mean ADD STA was + * success. + */ + if(HAL_STA_INVALID_IDX != staIndex) + limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry); + limDeleteDphHashEntry(pMac, + pStaDs->staAddr, peerIdx, psessionEntry); + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + + /* Send indication to upper layers only if ADD STA was success + * i.e staid is Valid. + */ + if(HAL_STA_INVALID_IDX != staIndex) + ibss_status_chg_notify(pMac, macAddr, staIndex, + ucUcastSig, ucBcastSig, + eWNI_SME_IBSS_PEER_DEPARTED_IND, + psessionEntry->smeSessionId ); + if (pTempNode == pMac->lim.gLimIbssPeerList) + { + pMac->lim.gLimIbssPeerList = pTempNode->next; + pPrevNode = pMac->lim.gLimIbssPeerList; + } + else + pPrevNode->next = pTempNode->next; + + vos_mem_free(pTempNode); + pMac->lim.gLimNumIbssPeers--; + + pTempNode = pTempNextNode; + break; + } + } + pPrevNode = pTempNode; + pTempNode = pTempNextNode; + } + /* + * if it is the last peer walking out, we better + * we set IBSS state to inactive. + */ + if (0 == pMac->lim.gLimNumIbssPeers) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "Last STA from IBSS walked out"); + psessionEntry->limIbssActive = false; + } +} + +/* handle the response from HAL for an ADD STA request */ +tSirRetStatus +limIbssAddStaRsp( + tpAniSirGlobal pMac, + void *msg,tpPESession psessionEntry) +{ + tpDphHashNode pStaDs; + tANI_U16 peerIdx; + tpAddStaParams pAddStaParams = (tpAddStaParams) msg; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if (pAddStaParams == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP with no body!"));) + return eSIR_FAILURE; + } + + pStaDs = dphLookupHashEntry(pMac, + pAddStaParams->staMac, &peerIdx, + &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + limLog(pMac, LOGE, + FL("IBSS: ADD_STA_RSP for unknown MAC addr: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddStaParams->staMac)); + vos_mem_free(pAddStaParams); + return eSIR_FAILURE; + } + + if (pAddStaParams->status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, + FL("IBSS: ADD_STA_RSP error (%x) from MAC: " MAC_ADDRESS_STR), + pAddStaParams->status, MAC_ADDR_ARRAY(pAddStaParams->staMac)); + __limIbssSearchAndDeletePeer(pMac, + psessionEntry, pAddStaParams->staMac); + vos_mem_free(pAddStaParams); + return eSIR_FAILURE; + } + + pStaDs->bssId = pAddStaParams->bssIdx; + pStaDs->staIndex = pAddStaParams->staIdx; + pStaDs->ucUcastSig = pAddStaParams->ucUcastSig; + pStaDs->ucBcastSig = pAddStaParams->ucBcastSig; + pStaDs->valid = 1; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + + PELOGW(limLog(pMac, LOGW, FL("IBSS: sending IBSS_NEW_PEER msg to SME!"));) + + ibss_status_chg_notify(pMac, pAddStaParams->staMac, pStaDs->staIndex, + pStaDs->ucUcastSig, pStaDs->ucBcastSig, + eWNI_SME_IBSS_NEW_PEER_IND, + psessionEntry->smeSessionId); + +#ifdef WLAN_FEATURE_RMC + limRmcTriggerRulerSelection(pMac, psessionEntry->selfMacAddr); +#endif + + vos_mem_free(pAddStaParams); + + return eSIR_SUCCESS; +} + + + +void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg,tpPESession psessionEntry) +{ + tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg; + + PELOGW(limLog(pMac, LOGW, FL("IBSS: DEL_BSS_RSP Rcvd during coalescing!"));) + + if (pDelBss == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) with no body!"));) + goto end; + } + + if (pDelBss->status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) error (%x) Bss %d "), + pDelBss->status, pDelBss->bssIdx); + goto end; + } + //Delete peer entries. + limIbssDeleteAllPeers(pMac,psessionEntry); + + /* add the new bss */ + ibss_bss_add(pMac,psessionEntry); + + end: + if(pDelBss != NULL) + vos_mem_free(pDelBss); +} + + + +void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg, tpPESession pSessionEntry) +{ + tANI_U8 infoLen; + tSirSmeNewBssInfo newBssInfo; + + tpAddBssParams pAddBss = (tpAddBssParams) msg; + + tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr; + tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon; + + if ((pHdr == NULL) || (pBeacon == NULL)) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)"));) + goto end; + } + + // Inform Host of IBSS coalescing + infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) + + sizeof(tANI_U8) + pBeacon->ssId.length + 1; + + vos_mem_set((void *) &newBssInfo, sizeof(newBssInfo), 0); + vos_mem_copy(newBssInfo.bssId, pHdr->bssId, sizeof(tSirMacAddr)); + newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel; + vos_mem_copy((tANI_U8 *) &newBssInfo.ssId, + (tANI_U8 *) &pBeacon->ssId, pBeacon->ssId.length + 1); + + PELOGW(limLog(pMac, LOGW, FL("Sending JOINED_NEW_BSS notification to SME."));) + + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_JOINED_NEW_BSS, + (tANI_U32 *) &newBssInfo, + infoLen,pSessionEntry->smeSessionId); + { + //Configure beacon and send beacons to HAL + limSendBeaconInd(pMac, pSessionEntry); + } + + end: + ibss_coalesce_free(pMac); +} + +void +limIbssDelBssRsp( + tpAniSirGlobal pMac, + void *msg,tpPESession psessionEntry) +{ + tSirResultCodes rc = eSIR_SME_SUCCESS; + tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if (pDelBss == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP with no body!"));) + rc = eSIR_SME_REFUSED; + goto end; + } + + if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + goto end; + } + + + /* + * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true. + * BSS has to be added again in this scenario, so this case needs to be handled separately. + * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to + * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME. + */ + if(true == pMac->lim.gLimIbssCoalescingHappened) + { + + limIbssDelBssRspWhenCoalescing(pMac,msg,psessionEntry); + return; + } + + + + if (pDelBss->status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP error (%x) Bss %d "), + pDelBss->status, pDelBss->bssIdx);) + rc = eSIR_SME_STOP_BSS_FAILURE; + goto end; + } + + + + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP setLinkState failed"));) + rc = eSIR_SME_REFUSED; + goto end; + } + + limIbssDelete(pMac,psessionEntry); + + dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable); + limDeletePreAuthList(pMac); + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + psessionEntry->limSystemRole = eLIM_STA_ROLE; + + /* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra + * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from limApplyConfiguration + */ + psessionEntry->shortSlotTimeSupported = WNI_CFG_SHORT_SLOT_TIME_STADEF; + + end: + if(pDelBss != NULL) + vos_mem_free(pDelBss); + /* Delete PE session once BSS is deleted */ + if (NULL != psessionEntry) { + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,psessionEntry->smeSessionId,psessionEntry->transactionId); + peDeleteSession(pMac, psessionEntry); + psessionEntry = NULL; + } +} + +/** + * limIbssCoalesce() + * + *FUNCTION: + * This function is called upon receiving Beacon/Probe Response + * while operating in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pBeacon - Parsed Beacon Frame structure + * @param pBD - Pointer to received BD + * + * @return Status whether to process or ignore received Beacon Frame + */ + +tSirRetStatus +limIbssCoalesce( + tpAniSirGlobal pMac, + tpSirMacMgmtHdr pHdr, + tpSchBeaconStruct pBeacon, + tANI_U8 *pIEs, + tANI_U32 ieLen, + tANI_U16 fTsfLater, + tpPESession psessionEntry) +{ + tANI_U16 peerIdx; + tSirMacAddr currentBssId; + tLimIbssPeerNode *pPeerNode; + tpDphHashNode pStaDs; + tUpdateBeaconParams beaconParams; + + vos_mem_set((tANI_U8 *)&beaconParams, sizeof(tUpdateBeaconParams), 0); + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + limLog(pMac, LOG1, FL("Current BSSID :" MAC_ADDRESS_STR " Received BSSID :" MAC_ADDRESS_STR ), + MAC_ADDR_ARRAY(currentBssId), MAC_ADDR_ARRAY(pHdr->bssId)); + + /* Check for IBSS Coalescing only if Beacon is from different BSS */ + if ( !vos_mem_compare(currentBssId, pHdr->bssId, sizeof( tSirMacAddr )) + && psessionEntry->isCoalesingInIBSSAllowed) + { + /* + * If STA entry is already available in the LIM hash table, then it is + * possible that the peer may have left and rejoined within the heartbeat + * timeout. In the offloaded case with 32 peers, the HB timeout is whopping + * 128 seconds. In that case, the FW will not let any frames come in until + * atleast the last sequence number is received before the peer is left + * Hence, if the coalescing peer is already there in the peer list and if + * the BSSID matches then, invoke delSta() to cleanup the entries. We will + * let the peer coalesce when we receive next beacon from the peer + */ + pPeerNode = ibss_peer_find(pMac, pHdr->sa); + if (NULL != pPeerNode) + { + __limIbssSearchAndDeletePeer (pMac, psessionEntry, pHdr->sa); + PELOGW(limLog(pMac, LOGW, + FL("** Peer attempting to reconnect before HB timeout, deleted **"));) + return eSIR_LIM_IGNORE_BEACON; + } + + if (! fTsfLater) // No Coalescing happened. + { + PELOGW(limLog(pMac, LOGW, FL("No Coalescing happened"));) + return eSIR_LIM_IGNORE_BEACON; + } + /* + * IBSS Coalescing happened. + * save the received beacon, and delete the current BSS. The rest of the + * processing will be done in the delBss response processing + */ + pMac->lim.gLimIbssCoalescingHappened = true; + PELOGW(limLog(pMac, LOGW, FL("IBSS Coalescing happened"));) + ibss_coalesce_save(pMac, pHdr, pBeacon); + limLog(pMac, LOGW, FL("Delete BSSID :" MAC_ADDRESS_STR ), + MAC_ADDR_ARRAY(currentBssId)); + ibss_bss_delete(pMac,psessionEntry); + return eSIR_SUCCESS; + } + else + { + if (!vos_mem_compare(currentBssId, pHdr->bssId, sizeof( tSirMacAddr ))) + return eSIR_LIM_IGNORE_BEACON; + } + + + // STA in IBSS mode and SSID matches with ours + pPeerNode = ibss_peer_find(pMac, pHdr->sa); + if (pPeerNode == NULL) + { + /* Peer not in the list - Collect BSS description & add to the list */ + tANI_U32 frameLen; + tSirRetStatus retCode; + + /* + * Limit the Max number of IBSS Peers allowed as the max + * number of STA's allowed + * pMac->lim.gLimNumIbssPeers will be increamented after exiting + * this function. so we will add additional 1 to compare against + * pMac->lim.gLimIbssStaLimit + */ + if ((pMac->lim.gLimNumIbssPeers+1) >= pMac->lim.gLimIbssStaLimit) + { /*Print every 100th time */ + if (pMac->lim.gLimIbssRetryCnt % 100 == 0) + { + limLog(pMac, LOG1, FL("**** MAX STA LIMIT HAS REACHED ****")); + } + pMac->lim.gLimIbssRetryCnt++; + return eSIR_LIM_MAX_STA_REACHED_ERROR; + } + PELOGW(limLog(pMac, LOGW, FL("IBSS Peer node does not exist, adding it***"));) + frameLen = sizeof(tLimIbssPeerNode) + ieLen - sizeof(tANI_U32); + + pPeerNode = vos_mem_malloc((tANI_U16)frameLen); + if (NULL == pPeerNode) + { + limLog(pMac, LOGP, FL("alloc fail (%d bytes) storing IBSS peer info"), + frameLen); + return eSIR_MEM_ALLOC_FAILED; + } + + pPeerNode->beacon = NULL; + pPeerNode->beaconLen = 0; + + ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,psessionEntry); + pPeerNode->beacon = vos_mem_malloc(ieLen); + if (NULL == pPeerNode->beacon) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));) + } + else + { + vos_mem_copy(pPeerNode->beacon, pIEs, ieLen); + pPeerNode->beaconLen = (tANI_U16)ieLen; + } + ibss_peer_add(pMac, pPeerNode); + + pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + /// DPH node already exists for the peer + limLog(pMac, LOG1, FL("DPH Node present for just learned peer")); + limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOG1); + ibss_sta_info_update(pMac, pStaDs, pPeerNode,psessionEntry); + return eSIR_SUCCESS; + } + retCode = limIbssStaAdd(pMac, pPeerNode->peerMacAddr,psessionEntry); + if (retCode != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("lim-ibss-sta-add failed (reason %x)"), retCode);) + limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOGE); + return retCode; + } + + // Decide protection mode + pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limIbssDecideProtection(pMac, pStaDs, &beaconParams, psessionEntry); + + if(beaconParams.paramChangeBitmap) + { + PELOGE(limLog(pMac, LOGE, FL("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params "));) + schSetFixedBeaconFields(pMac, psessionEntry); + beaconParams.bssIdx = psessionEntry->bssIdx; + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + } + else + ibss_sta_caps_update(pMac, pPeerNode,psessionEntry); + + if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) + return eSIR_SUCCESS; + + // Received Beacon from same IBSS we're + // currently part of. Inform Roaming algorithm + // if not already that IBSS is active. + if (psessionEntry->limIbssActive == false) + { + limResetHBPktCount(psessionEntry); + PELOGW(limLog(pMac, LOGW, FL("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME"));) + psessionEntry->limIbssActive = true; + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0, psessionEntry->smeSessionId); + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if (limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate Heartbeat timer")); + } + + return eSIR_SUCCESS; +} /*** end limHandleIBSScoalescing() ***/ + + +void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tLimIbssPeerNode *pTempNode, *pPrevNode; + tLimIbssPeerNode *pTempNextNode = NULL; + tANI_U16 peerIdx=0; + tpDphHashNode pStaDs=0; + tANI_U32 threshold=0; + tANI_U16 staIndex=0; + tANI_U8 ucUcastSig=0; + tANI_U8 ucBcastSig=0; + + /** MLM BSS is started and if PE in scanmode then MLM state will be waiting for probe resp. + * If Heart beat timeout triggers during this corner case then we need to reactivate HeartBeat timer + */ + if(psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) { + /****** + * Note: Use this code once you have converted all + * limReactivateHeartBeatTimer() calls to + * limReactivateTimer() calls. + * + ******/ + //limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER, psessionEntry); + limReactivateHeartBeatTimer(pMac, psessionEntry); + return; + } + /** If LinkMonitor is Disabled */ + if(!pMac->sys.gSysEnableLinkMonitorMode) + return; + + pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList; + threshold = (pMac->lim.gLimNumIbssPeers / 4 ) + 1; + + /** Monitor the HeartBeat with the Individual PEERS in the IBSS */ + while (pTempNode != NULL) + { + pTempNextNode = pTempNode->next; + if(pTempNode->beaconHBCount) //There was a beacon for this peer during heart beat. + { + pTempNode->beaconHBCount = 0; + pTempNode->heartbeatFailure = 0; + } + else //There wasnt any beacon received during heartbeat timer. + { + pTempNode->heartbeatFailure++; + PELOGE(limLog(pMac, LOGE, FL("Heartbeat fail = %d thres = %d"), pTempNode->heartbeatFailure, pMac->lim.gLimNumIbssPeers);) + if(pTempNode->heartbeatFailure >= threshold ) + { + //Remove this entry from the list. + pStaDs = dphLookupHashEntry(pMac, pTempNode->peerMacAddr, &peerIdx, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + staIndex = pStaDs->staIndex; + ucUcastSig = pStaDs->ucUcastSig; + ucBcastSig = pStaDs->ucBcastSig; + +#ifdef WLAN_FEATURE_RMC + limRmcTransmitterDelete(pMac, pStaDs->staAddr); +#endif /* WLAN_FEATURE_RMC */ + + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, peerIdx,psessionEntry); + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + //Send indication. + ibss_status_chg_notify( pMac, pTempNode->peerMacAddr, staIndex, + ucUcastSig, ucBcastSig, + eWNI_SME_IBSS_PEER_DEPARTED_IND, + psessionEntry->smeSessionId ); + } + if(pTempNode == pMac->lim.gLimIbssPeerList) + { + pMac->lim.gLimIbssPeerList = pTempNode->next; + pPrevNode = pMac->lim.gLimIbssPeerList; + } + else + pPrevNode->next = pTempNode->next; + + vos_mem_free(pTempNode); + pMac->lim.gLimNumIbssPeers--; + + pTempNode = pTempNextNode; //Since we deleted current node, prevNode remains same. + continue; + } + } + + pPrevNode = pTempNode; + pTempNode = pTempNextNode; + } + + /** General IBSS Activity Monitor, check if in IBSS Mode we are received any Beacons */ + if(pMac->lim.gLimNumIbssPeers) + { + if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL) + pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++; + else + pMac->lim.gLimHeartBeatBeaconStats[0]++; + + limReactivateHeartBeatTimer(pMac, psessionEntry); + + // Reset number of beacons received + limResetHBPktCount(psessionEntry); + return; + } + else + { + + PELOGW(limLog(pMac, LOGW, FL("Heartbeat Failure"));) + pMac->lim.gLimHBfailureCntInLinkEstState++; + + if (psessionEntry->limIbssActive == true) + { + // We don't receive Beacon frames from any + // other STA in IBSS. Announce IBSS inactive + // to Roaming algorithm + PELOGW(limLog(pMac, LOGW, FL("Alone in IBSS"));) + psessionEntry->limIbssActive = false; + + limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_INACTIVE, + NULL, 0, psessionEntry->smeSessionId); + } + } +} + + +/** ------------------------------------------------------------- +\fn limIbssDecideProtectionOnDelete +\brief Decides all the protection related information. +\ +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U32 phyMode; + tHalBitVal erpEnabled = eHAL_CLEAR; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 i; + + if(NULL == pStaDs) + return; + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_2_4_GHZ == rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + erpEnabled = pStaDs->erpEnabled; + //we are HT or 11G and 11B station is getting deleted. + if ( ((phyMode == WNI_CFG_PHY_MODE_11G) || psessionEntry->htCapability) + && (erpEnabled == eHAL_CLEAR)) + { + PELOGE(limLog(pMac, LOGE, FL("(%d) A legacy STA is disassociated. Addr is "), + psessionEntry->gLim11bParams.numSta); + limPrintMacAddr(pMac, pStaDs->staAddr, LOGE);) + if (psessionEntry->gLim11bParams.numSta > 0) + { + for (i=0; ilim.protStaCache[i].active) + { + if (vos_mem_compare(pMac->lim.protStaCache[i].addr, + pStaDs->staAddr, sizeof(tSirMacAddr))) + { + psessionEntry->gLim11bParams.numSta--; + pMac->lim.protStaCache[i].active = false; + break; + } + } + } + } + + if (psessionEntry->gLim11bParams.numSta == 0) + { + PELOGE(limLog(pMac, LOGE, FL("No more 11B STA exists. Disable protection. "));) + limIbssSetProtection(pMac, false, pBeaconParams,psessionEntry); + } + } + } +} + +/** ----------------------------------------------------------------- +\fn __limIbssPeerInactivityHandler +\brief Internal function. Deletes FW indicated peer which is inactive +\ +\param tpAniSirGlobal pMac +\param tpPESession psessionEntry +\param tpSirIbssPeerInactivityInd peerInactivityInd +\return None + -----------------------------------------------------------------*/ +static void +__limIbssPeerInactivityHandler(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tpSirIbssPeerInactivityInd peerInactivityInd) +{ + if(psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + return; + } + + /* delete the peer for which heartbeat is observed */ + __limIbssSearchAndDeletePeer (pMac, psessionEntry, peerInactivityInd->peerAddr); + +} + +/** ------------------------------------------------------------- +\fn limProcessIbssPeerInactivity +\brief Peer inactivity message handler +\ +\param tpAniSirGlobal pMac +\param void* buf +\return None + -------------------------------------------------------------*/ +void +limProcessIbssPeerInactivity(tpAniSirGlobal pMac, void *buf) +{ + /* + * --------------- HEARTBEAT OFFLOAD CASE ------------------ + * This message handler is executed when the firmware identifies + * inactivity from one or more peer devices. We will come here + * for every inactive peer device + */ + tANI_U8 i; + + tSirIbssPeerInactivityInd *peerInactivityInd = + (tSirIbssPeerInactivityInd *) buf; + + /* + * If IBSS is not started or heartbeat offload is not enabled + * we should not handle this request + */ + if (eLIM_STA_IN_IBSS_ROLE != pMac->lim.gLimSystemRole && + !IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) + { + return; + } + + /** If LinkMonitor is Disabled */ + if (!pMac->sys.gSysEnableLinkMonitorMode) + { + return; + } + + for (i = 0; i < pMac->lim.maxBssId; i++) + { + if (VOS_TRUE == pMac->lim.gpSession[i].valid && + eSIR_IBSS_MODE == pMac->lim.gpSession[i].bssType) + { + __limIbssPeerInactivityHandler(pMac, + &pMac->lim.gpSession[i], + peerInactivityInd); + break; + } + } +} + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h new file mode 100644 index 000000000000..919bbee78269 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limIbssPeerMgmt.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limIbssPeerMgmt.h contains prototypes for + * the utility functions LIM uses to maintain peers in IBSS. + * Author: Chandra Modumudi + * Date: 03/12/04 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "sirCommon.h" +#include "limUtils.h" + +#define IBSS_STATIONS_USED_DURING_INIT 4 //(broadcast + self + p2p + softap) + +void limIbssInit(tpAniSirGlobal); +void limIbssDelete(tpAniSirGlobal,tpPESession psessionEntry); +tSirRetStatus limIbssCoalesce(tpAniSirGlobal, tpSirMacMgmtHdr, tpSchBeaconStruct, tANI_U8*,tANI_U32, tANI_U16,tpPESession); +tSirRetStatus limIbssStaAdd(tpAniSirGlobal, void *,tpPESession); +tSirRetStatus limIbssAddStaRsp( tpAniSirGlobal, void *,tpPESession); +void limIbssDelBssRsp( tpAniSirGlobal, void *,tpPESession); +void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal, void *,tpPESession); +void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void * msg, tpPESession pSessionEntry); +void limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams,tpPESession pSessionEntry); +void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry); +void limProcessIbssPeerInactivity(tpAniSirGlobal pMac, void *buf); diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c new file mode 100644 index 000000000000..d60902a0e9dc --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limLinkMonitoringAlgo.cc contains the code for + * Link monitoring algorithm on AP and heart beat failure + * handling on STA. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "aniGlobal.h" +#include "wniCfg.h" +#include "cfgApi.h" + + +#include "schApi.h" +#include "pmmApi.h" +#include "utilsApi.h" +#include "limAssocUtils.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limPropExtsUtils.h" + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT +#include "limSession.h" +#include "limSerDesUtils.h" +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + +/** + * limSendKeepAliveToPeer() + * + *FUNCTION: + * This function is called to send Keep alive message to peer + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limSendKeepAliveToPeer(tpAniSirGlobal pMac) +{ + +} /*** limSendKeepAliveToPeer() ***/ + + +/** --------------------------------------------------------- +\fn limDeleteStaContext +\brief This function handles the message from HAL: +\ WDA_DELETE_STA_CONTEXT_IND. This function +\ validates that the given station id exist, and if so, +\ deletes the station by calling limTriggerSTAdeletion. +\param tpAniSirGlobal pMac +\param tpSirMsgQ limMsg +\return none + -----------------------------------------------------------*/ +void +limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpDeleteStaContext pMsg = (tpDeleteStaContext)limMsg->bodyptr; + tpDphHashNode pStaDs; + tpPESession psessionEntry ; + tANI_U8 sessionId; + + if(NULL == pMsg) + { + PELOGE(limLog(pMac, LOGE,FL("Invalid body pointer in message"));) + return; + } + if((psessionEntry = peFindSessionByBssid(pMac,pMsg->bssId,&sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + vos_mem_free(pMsg); + return; + } + +#ifdef WLAN_FEATURE_LFR_MBB + if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) + { + limLog(pMac, LOGE, + FL("Ignore delete sta as LFR MBB in progress")); + return; + } +#endif + + switch(pMsg->reasonCode) + { + case HAL_DEL_STA_REASON_CODE_KEEP_ALIVE: + case HAL_DEL_STA_REASON_CODE_TIM_BASED: + PELOGE(limLog(pMac, LOGE, FL(" Deleting station: staId = %d, reasonCode = %d"), pMsg->staId, pMsg->reasonCode);) + if (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) + { + vos_mem_free(pMsg); + return; + } + + pStaDs = dphLookupAssocId(pMac, pMsg->staId, &pMsg->assocId, &psessionEntry->dph.dphHashTable); + + if (!pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("Skip STA deletion (invalid STA) limSystemRole=%d"),psessionEntry->limSystemRole);) + vos_mem_free(pMsg); + return; + } + + /* check and see if same staId. This is to avoid the scenario + * where we're trying to delete a staId we just added. + */ + if (pStaDs->staIndex != pMsg->staId) + { + PELOGE(limLog(pMac, LOGE, FL("staid mismatch: %d vs %d "), pStaDs->staIndex, pMsg->staId);) + vos_mem_free(pMsg); + return; + } + + if((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_AP_ROLE == psessionEntry->limSystemRole)) + { + limLog(pMac, LOG1, FL("SAP:lim Delete Station Context (staId: %d, assocId: %d) "), + pMsg->staId, pMsg->assocId); + /* + * Check if Deauth/Disassoc is triggered from Host. + * If mlmState is in some transient state then + * don't trigger STA deletion to avoid the race + * condition. + */ + if ((pStaDs && + ((pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_WT_ASSOC_CNF_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_ASSOCIATED_STATE)))) + { + PELOGE(limLog(pMac, LOGE, FL("SAP:received Del STA context in some transit state(staId: %d, assocId: %d)"), + pMsg->staId, pMsg->assocId);) + vos_mem_free(pMsg); + return; + } + else + { + limSendDisassocMgmtFrame(pMac, + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON, + pStaDs->staAddr, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + } + } + else + { +#ifdef FEATURE_WLAN_TDLS + if(eLIM_STA_ROLE == psessionEntry->limSystemRole && + STA_ENTRY_TDLS_PEER == pStaDs->staType) + { + //TeardownLink with PEER + //Reason code HAL_DEL_STA_REASON_CODE_KEEP_ALIVE means + //eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE + limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry, + /*pMsg->reasonCode*/ eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE); + } + else + { +#endif + //TearDownLink with AP + tLimMlmDeauthInd mlmDeauthInd; + PELOGW(limLog(pMac, LOGW, FL("lim Delete Station Context (staId: %d, assocId: %d) "), + pMsg->staId, pMsg->assocId);) + if ((pStaDs && + ((pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_WT_ASSOC_CNF_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_ASSOCIATED_STATE)))) + { + /** + * Received WDA_DELETE_STA_CONTEXT_IND for STA that does not + * have context or in some transit state. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received WDA_DELETE_STA_CONTEXT_IND for STA that either has no context or in some transit state, Addr= " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMsg->bssId));) + vos_mem_free(pMsg); + return; + } + + if( pMac->roam.configParam.sendDeauthBeforeCon ) + { + tANI_U8 apCount = pMac->lim.gLimHeartBeatApMacIndex; + + if(pMac->lim.gLimHeartBeatApMacIndex) + pMac->lim.gLimHeartBeatApMacIndex = 0; + else + pMac->lim.gLimHeartBeatApMacIndex = 1; + + limLog(pMac, LOG1, FL("lim Delete Station Context for MAC " + MAC_ADDRESS_STR" Store it on Index %d"), + MAC_ADDR_ARRAY(pStaDs->staAddr),apCount); + + sirCopyMacAddr(pMac->lim.gLimHeartBeatApMac[apCount],pStaDs->staAddr); + } + pStaDs->mlmStaContext.disassocReason = + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DEAUTH; + + if (pStaDs->isDisassocDeauthInProgress) + { + limLog(pMac, LOGE, FL("No need to cleanup as already" + "disassoc or deauth in progress")); + return; + } + else + pStaDs->isDisassocDeauthInProgress++; + + // Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pStaDs->staAddr, sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDeauthInd.deauthTrigger = pStaDs->mlmStaContext.cleanupTrigger; + +#ifdef FEATURE_WLAN_TDLS + /* Delete all TDLS peers connected before leaving BSS*/ + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd); + + limSendSmeDeauthInd(pMac, pStaDs, psessionEntry); +#ifdef FEATURE_WLAN_TDLS + } +#endif + } + break; + + case HAL_DEL_STA_REASON_CODE_UNKNOWN_A2: + PELOGE(limLog(pMac, LOGE, FL(" Deleting Unknown station "));) + limPrintMacAddr(pMac, pMsg->addr2, LOGE); + limSendDeauthMgmtFrame( pMac, eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON, pMsg->addr2, psessionEntry, FALSE); + break; + + default: + PELOGE(limLog(pMac, LOGE, FL(" Unknown reason code "));) + break; + + } + vos_mem_free(pMsg); + return; +} + + +/** + * limTriggerSTAdeletion() + * + *FUNCTION: + * This function is called to trigger STA context deletion + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param pStaDs - Pointer to internal STA Datastructure + * @return None + */ +void +limTriggerSTAdeletion(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tLimMlmDisassocInd mlmDisassocInd; + + + if (!pStaDs) + { + PELOGW(limLog(pMac, LOGW, FL("Skip STA deletion (invalid STA)"));) + return; + } + + if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)|| + pStaDs->sta_deletion_in_progress) { + /* Already in the process of deleting context for the peer */ + limLog(pMac, LOG1, + FL("Deletion is in progress (%d) for peer:%p in mlmState %d"), + pStaDs->sta_deletion_in_progress, pStaDs->staAddr, + pStaDs->mlmStaContext.mlmState); + return; + } + pStaDs->sta_deletion_in_progress = true; + pStaDs->mlmStaContext.disassocReason = + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DISASSOC; + vos_mem_copy(&mlmDisassocInd.peerMacAddr, pStaDs->staAddr, + sizeof(tSirMacAddr)); + mlmDisassocInd.reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + mlmDisassocInd.disassocTrigger = eLIM_LINK_MONITORING_DISASSOC; + + /* Update PE session Id */ + mlmDisassocInd.sessionId = psessionEntry->peSessionId; + limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND, + (tANI_U32 *) &mlmDisassocInd); + // Issue Disassoc Indication to SME. + limSendSmeDisassocInd(pMac, pStaDs, psessionEntry); +} /*** end limTriggerSTAdeletion() ***/ + + + +/** + * limTearDownLinkWithAp() + * + *FUNCTION: + * This function is called when heartbeat (beacon reception) + * fails on STA + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limTearDownLinkWithAp(tpAniSirGlobal pMac, tANI_U8 sessionId, tSirMacReasonCodes reasonCode) +{ + tpDphHashNode pStaDs = NULL; + + //tear down the following sessionEntry + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + /** + * Heart beat failed for upto threshold value + * and AP did not respond for Probe request. + * Trigger link tear down. + */ + + pMac->pmm.inMissedBeaconScenario = FALSE; + limLog(pMac, LOGW, + FL("No ProbeRsp from AP after HB failure. Tearing down link")); + + // Deactivate heartbeat timer + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + + // Announce loss of link to Roaming algorithm + // and cleanup by sending SME_DISASSOC_REQ to SME + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + + if (pStaDs != NULL) + { + tLimMlmDeauthInd mlmDeauthInd; + +#ifdef FEATURE_WLAN_TDLS + /* Delete all TDLS peers connected before leaving BSS*/ + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + + pStaDs->mlmStaContext.disassocReason = reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_LINK_MONITORING_DEAUTH; + + /// Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pStaDs->staAddr, + sizeof(tSirMacAddr)); + /* if sendDeauthBeforeCon is enabled and reasoncode is Beacon Missed + * Store the MAC of AP in the flip flop buffer. This MAC will be + * used to send Deauth before connection, if we connect to same AP + * after HB failure. + */ + if(pMac->roam.configParam.sendDeauthBeforeCon && + eSIR_BEACON_MISSED == reasonCode) + { + int apCount = pMac->lim.gLimHeartBeatApMacIndex; + + if(pMac->lim.gLimHeartBeatApMacIndex) + pMac->lim.gLimHeartBeatApMacIndex = 0; + else + pMac->lim.gLimHeartBeatApMacIndex = 1; + + limLog(pMac, LOGE, FL("HB Failure on MAC " + MAC_ADDRESS_STR" Store it on Index %d"), + MAC_ADDR_ARRAY(pStaDs->staAddr),apCount); + + sirCopyMacAddr(pMac->lim.gLimHeartBeatApMac[apCount],pStaDs->staAddr); + } + mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDeauthInd.deauthTrigger = pStaDs->mlmStaContext.cleanupTrigger; + + limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd); + + limSendSmeDeauthInd(pMac, pStaDs, psessionEntry); + } +} /*** limTearDownLinkWithAp() ***/ + + + + +/** + * limHandleHeartBeatFailure() + * + *FUNCTION: + * This function is called when heartbeat (beacon reception) + * fails on STA + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limHandleHeartBeatFailure(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + vos_log_beacon_update_pkt_type *log_ptr = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* If gLimHeartBeatTimer fires between the interval of sending WDA_ENTER_BMPS_REQUEST + * to the HAL and receiving WDA_ENTER_BMPS_RSP from the HAL, then LIM (PE) tries to Process the + * SIR_LIM_HEAR_BEAT_TIMEOUT message but The PE state is ePMM_STATE_BMPS_SLEEP so PE dont + * want to handle heartbeat timeout in the BMPS, because Firmware handles it in BMPS. + * So just return from heartbeatfailure handler + */ + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE && (!limIsSystemInActiveState(pMac))) + return; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_beacon_update_pkt_type, LOG_WLAN_BEACON_UPDATE_C); + if(log_ptr) + log_ptr->bcn_rx_cnt = psessionEntry->LimRxedBeaconCntDuringHB; + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Ensure HB Status for the session has been reseted */ + psessionEntry->LimHBFailureStatus = eANI_BOOLEAN_FALSE; + +#ifdef WLAN_FEATURE_LFR_MBB + if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) + { + limLog(pMac, LOGE, + FL("Ignore Heartbeat failure as LFR MBB in progress")); + return; + } +#endif + + if (((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)&& + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + if (!pMac->sys.gSysEnableLinkMonitorMode) + return; + /* Ignore HB if channel switch is in progress */ + if (psessionEntry->gLimSpecMgmt.dot11hChanSwState == + eLIM_11H_CHANSW_RUNNING) { + limLog(pMac, LOGE, + FL("Ignore Heartbeat failure as Channel switch is in progress")); + pMac->pmm.inMissedBeaconScenario = false; + return; + } + + /** + * Beacon frame not received within heartbeat timeout. + */ + limLog(pMac, LOGW, FL("Heartbeat Failure")); + pMac->lim.gLimHBfailureCntInLinkEstState++; + + /** + * Check if connected on the DFS channel, if not connected on + * DFS channel then only send the probe request otherwise tear down the link + */ + if(!limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel)) + { + /*** Detected continuous Beacon Misses ***/ + psessionEntry->LimHBFailureStatus= eANI_BOOLEAN_TRUE; + /*Reset the HB packet count before sending probe*/ + limResetHBPktCount(psessionEntry); + /** + * Send Probe Request frame to AP to see if + * it is still around. Wait until certain + * timeout for Probe Response from AP. + */ + PELOGW(limLog(pMac, LOGW, FL("Heart Beat missed from AP. Sending Probe Req"));) + /* for searching AP, we don't include any additional IE */ + limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, psessionEntry->bssId, + psessionEntry->currentOperChannel,psessionEntry->selfMacAddr, + psessionEntry->dot11mode, 0, NULL); + } + else + { + PELOGW(limLog(pMac, LOGW, + FL("Heart Beat missed from AP on DFS chanel moving to passive"));) + if (psessionEntry->currentOperChannel < SIR_MAX_24G_5G_CHANNEL_RANGE){ + limCovertChannelScanType(pMac, psessionEntry->currentOperChannel, false); + pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] = 0; + } + /* Connected on DFS channel so should not send the probe request + * tear down the link directly */ + limTearDownLinkWithAp(pMac, psessionEntry->peSessionId, eSIR_BEACON_MISSED); + } + } + else + { + /** + * Heartbeat timer may have timed out + * while we're doing background scanning/learning + * or in states other than link-established state. + * Log error. + */ + limLog(pMac, LOG1, FL("received heartbeat timeout in state %d"), + psessionEntry->limMlmState); + limPrintMlmState(pMac, LOG1, psessionEntry->limMlmState); + pMac->lim.gLimHBfailureCntInOtherStates++; + limReactivateHeartBeatTimer(pMac, psessionEntry); + } +} /*** limHandleHeartBeatFailure() ***/ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c new file mode 100644 index 000000000000..9280c7d1c0f8 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limLogDump.c @@ -0,0 +1,2594 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*============================================================================ +limLogDump.c + +Implements the dump commands specific to the lim module. + + ============================================================================*/ + +#include "vos_types.h" +#include "limApi.h" + +#if defined(ANI_LOGDUMP) + + +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "schApi.h" +#include "limSerDesUtils.h" +#include "limAssocUtils.h" +#include "limSendMessages.h" +#include "logDump.h" +#include "limTrace.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif +#include "smeInside.h" +#include "wlan_qct_wda.h" +#ifdef WLAN_FEATURE_RMC +#include "wlan_qct_tl.h" +#include "limRMC.h" +#endif +#include "wlan_qct_wdi_dts.h" + +void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA); +#ifdef WLANTL_DEBUG +extern void WLANTLPrintPktsRcvdPerRssi(v_PVOID_t pAdapter, v_U8_t staId, v_BOOL_t flush); +extern void WLANTLPrintPktsRcvdPerRateIdx(v_PVOID_t pAdapter, v_U8_t staId, v_BOOL_t flush); +#endif + +static char *getRole( tLimSystemRole role ) +{ + switch (role) + { + case eLIM_UNKNOWN_ROLE: + return "eLIM_UNKNOWN_ROLE"; + case eLIM_AP_ROLE: + return "eLIM_AP_ROLE"; + case eLIM_STA_IN_IBSS_ROLE: + return "eLIM_STA_IN_IBSS_ROLE"; + case eLIM_STA_ROLE: + return "eLIM_STA_ROLE"; + case eLIM_BT_AMP_STA_ROLE: + return "eLIM_BT_AMP_STA_ROLE"; + case eLIM_BT_AMP_AP_ROLE: + return "eLIM_BT_AMP_AP_ROLE"; + default: + return "UNKNOWN"; + } +} + + + +char *dumpLim( tpAniSirGlobal pMac, char *p, tANI_U32 sessionId) +{ + #ifdef FIXME_GEN6 + //iterate through the sessionTable and dump sta entries for each session. + //Keep this code under 'WLAN_DEBUG' compile flag. + + tANI_U16 i, j; + + tpPESession psessionEntry = peFindSessionBySessionId(pMac, sessionId); + + if (psessionEntry == NULL) + { + p += log_sprintf( pMac, p, "Invalid sessionId: %d \n ", sessionId); + return p; + } + + p += log_sprintf( pMac,p, "\n ----- LIM Debug Information ----- \n"); + p += log_sprintf( pMac,p, "LIM Role = (%d) %s\n", + pMac->lim.gLimSystemRole, getRole(pMac->lim.gLimSystemRole)); + p += log_sprintf( pMac,p, "SME State = (%d) %s", + pMac->lim.gLimSmeState, limSmeStateStr(pMac->lim.gLimSmeState)); + p += log_sprintf( pMac,p, "MLM State = (%d) %s", + pMac->lim.gLimMlmState, limMlmStateStr(pMac->lim.gLimMlmState)); + p += log_sprintf( pMac,p, "802.11n session HT Capability: %s\n", + (psessionEntry->htCapability == 1) ? "Enabled" : "Disabled"); + p += log_sprintf( pMac,p, "gLimProcessDefdMsgs: %s\n", + (pMac->lim.gLimProcessDefdMsgs == 1) ? "Enabled" : "Disabled"); + + if (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) + { + p += log_sprintf( pMac,p, "AID = %X\t\t\n", pMac->lim.gLimAID); + p += log_sprintf( pMac,p, "SSID mismatch in Beacon Count = %d\n", + pMac->lim.gLimBcnSSIDMismatchCnt); + p += log_sprintf( pMac,p, "Number of link establishments = %d\n", + pMac->lim.gLimNumLinkEsts); + } + else if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) + { + p += log_sprintf( pMac,p, "Num of STAs associated = %d\n", + peGetCurrentSTAsCount(pMac)); + + p += log_sprintf( pMac,p, "Num of Pre-auth contexts = %d\n", + pMac->lim.gLimNumPreAuthContexts); + + p += log_sprintf( pMac,p, "Num of AssocReq dropped in invalid State = %d\n", + pMac->lim.gLimNumAssocReqDropInvldState); + + p += log_sprintf( pMac,p, "Num of ReassocReq dropped in invalid State = %d\n", + pMac->lim.gLimNumReassocReqDropInvldState); + + p += log_sprintf( pMac,p, "Num of Hash Miss Event ignored = %d\n", + pMac->lim.gLimNumHashMissIgnored); + } + + p += log_sprintf( pMac,p, "Num of RxCleanup Count = %d\n", + pMac->lim.gLimNumRxCleanup); + p += log_sprintf( pMac,p, "Unexpected Beacon Count = %d\n", + pMac->lim.gLimUnexpBcnCnt); + p += log_sprintf( pMac,p, "Number of Re/Assoc rejects of 11b STAs = %d\n", + pMac->lim.gLim11bStaAssocRejectCount); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in LinkEst State = %d\n", + pMac->lim.gLimHBfailureCntInLinkEstState); + p += log_sprintf( pMac,p, "No. of Probe Failures after HB failed = %d\n", + pMac->lim.gLimProbeFailureAfterHBfailedCnt); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in Other States = %d\n", + pMac->lim.gLimHBfailureCntInOtherStates); + p += log_sprintf( pMac,p, "No. of Beacons Rxed During HB Interval = %d\n", + pMac->lim.gLimRxedBeaconCntDuringHB); + p += log_sprintf( pMac,p, "Self Operating Mode = %s\n", limDot11ModeStr(pMac, (tANI_U8)pMac->lim.gLimDot11Mode)); + p += log_sprintf( pMac,p, "\n"); + + if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) + i = 2; + else + i = 1; + + + for (; i< pMac->lim.maxStation; i++) + { + tpDphHashNode pSta = dphGetHashEntry(pMac, (unsigned short)i); + if (pSta && pSta->added) + { + p += log_sprintf( pMac,p, "\nSTA AID: %d STA ID: %d Valid: %d AuthType: %d MLM State: %s", + i, pSta->staIndex, pSta->valid, + pSta->mlmStaContext.authType, + limMlmStateStr(pSta->mlmStaContext.mlmState)); + + p += log_sprintf( pMac,p, "\tAID:%-2d OpRateMode:%s ShPrmbl:%d HT:%d GF:%d TxChWidth:%d MimoPS:%d LsigProt:%d\n", + pSta->assocId, limStaOpRateModeStr(pSta->supportedRates.opRateMode), + pSta->shortPreambleEnabled, pSta->mlmStaContext.htCapability, + pSta->htGreenfield, pSta->htSupportedChannelWidthSet, + pSta->htMIMOPSState, pSta->htLsigTXOPProtection); + + p += log_sprintf( pMac,p, "\tAMPDU [MaxSz(Factor):%d, Dens: %d] AMSDU-MaxLen: %d\n", + pSta->htMaxRxAMpduFactor, pSta->htAMpduDensity,pSta->htMaxAmsduLength); + p += log_sprintf( pMac,p, "\tDSSCCkMode40Mhz: %d, SGI20: %d, SGI40: %d\n", + pSta->htDsssCckRate40MHzSupport, pSta->htShortGI20Mhz, + pSta->htShortGI40Mhz); + + p += log_sprintf( pMac,p, "\t11b Rates: "); + for(j=0; jsupportedRates.llbRates[j] > 0) + p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.llbRates[j]); + + p += log_sprintf( pMac,p, "\n\t11a Rates: "); + for(j=0; jsupportedRates.llaRates[j] > 0) + p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.llaRates[j]); + + p += log_sprintf( pMac,p, "\n\tPolaris Rates: "); + for(j=0; jsupportedRates.aniLegacyRates[j] > 0) + p += log_sprintf( pMac,p, "%d ", pSta->supportedRates.aniLegacyRates[j]); + + p += log_sprintf( pMac,p, "\n\tTitan and Taurus Proprietary Rate Bitmap: %08x\n", + pSta->supportedRates.aniEnhancedRateBitmap); + p += log_sprintf( pMac,p, "\tMCS Rate Set Bitmap: "); + for(j=0; jsupportedRates.supportedMCSSet[j]); + + } + } + p += log_sprintf( pMac,p, "\nProbe response disable = %d\n", + pMac->lim.gLimProbeRespDisableFlag); + + p += log_sprintf( pMac,p, "Scan mode enable = %d\n", + pMac->sys.gSysEnableScanMode); + p += log_sprintf( pMac,p, "BackgroundScanDisable = %d\n", + pMac->lim.gLimBackgroundScanDisable); + p += log_sprintf( pMac,p, "ForceBackgroundScanDisable = %d\n", + pMac->lim.gLimForceBackgroundScanDisable); + p += log_sprintf( pMac,p, "LinkMonitor mode enable = %d\n", + pMac->sys.gSysEnableLinkMonitorMode); + p += log_sprintf( pMac,p, "Qos Capable = %d\n", + SIR_MAC_GET_QOS(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Wme Capable = %d\n", + LIM_BSS_CAPS_GET(WME, pMac->lim.gLimCurrentBssQosCaps)); + p += log_sprintf( pMac,p, "Wsm Capable = %d\n", + LIM_BSS_CAPS_GET(WSM, pMac->lim.gLimCurrentBssQosCaps)); + if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + p += log_sprintf( pMac,p, "Number of peers in IBSS = %d\n", + pMac->lim.gLimNumIbssPeers); + if (pMac->lim.gLimNumIbssPeers) + { + tLimIbssPeerNode *pTemp; + pTemp = pMac->lim.gLimIbssPeerList; + p += log_sprintf( pMac,p, "MAC-Addr Ani Edca WmeInfo HT Caps #S,#E(Rates)\n"); + while (pTemp != NULL) + { + p += log_sprintf( pMac,p, "%02X:%02X:%02X:%02X:%02X:%02X ", + pTemp->peerMacAddr[0], + pTemp->peerMacAddr[1], + pTemp->peerMacAddr[2], + pTemp->peerMacAddr[3], + pTemp->peerMacAddr[4], + pTemp->peerMacAddr[5]); + p += log_sprintf( pMac,p, " %d %d,%d %d %d %04X %d,%d\n", + pTemp->aniIndicator, + pTemp->edcaPresent, pTemp->wmeEdcaPresent, + pTemp->wmeInfoPresent, + pTemp->htCapable, + pTemp->capabilityInfo, + pTemp->supportedRates.numRates, + pTemp->extendedRates.numRates); + pTemp = pTemp->next; + } + } + } + p += log_sprintf( pMac,p, "System Scan/Learn Mode bit = %d\n", + pMac->lim.gLimSystemInScanLearnMode); + p += log_sprintf( pMac,p, "Scan override = %d\n", + pMac->lim.gLimScanOverride); + p += log_sprintf( pMac,p, "CB State protection = %d\n", + pMac->lim.gLimCBStateProtection); + p += log_sprintf( pMac,p, "Count of Titan STA's = %d\n", + pMac->lim.gLimTitanStaCount); + + //current BSS capability + p += log_sprintf( pMac,p, "**********Current BSS Capability********\n"); + p += log_sprintf( pMac,p, "Ess = %d, ", SIR_MAC_GET_ESS(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Privacy = %d, ", SIR_MAC_GET_PRIVACY(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Short Preamble = %d, ", SIR_MAC_GET_SHORT_PREAMBLE(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Short Slot = %d, ", SIR_MAC_GET_SHORT_SLOT_TIME(pMac->lim.gLimCurrentBssCaps)); + p += log_sprintf( pMac,p, "Qos = %d\n", SIR_MAC_GET_QOS(pMac->lim.gLimCurrentBssCaps)); + + //Protection related information + p += log_sprintf( pMac,p, "*****Protection related information******\n"); + p += log_sprintf( pMac,p, "Protection %s\n", pMac->lim.gLimProtectionControl ? "Enabled" : "Disabled"); + + p += log_sprintf( pMac,p, "OBSS MODE = %d\n", pMac->lim.gHTObssMode); + p += log_sprintf( pMac, p, "HT operating Mode = %d, llbCoexist = %d, llgCoexist = %d, ht20Coexist = %d, nonGfPresent = %d, RifsMode = %d, lsigTxop = %d\n", + pMac->lim.gHTOperMode, pMac->lim.llbCoexist, pMac->lim.llgCoexist, + pMac->lim.ht20MhzCoexist, pMac->lim.gHTNonGFDevicesPresent, + pMac->lim.gHTRifsMode, pMac->lim.gHTLSigTXOPFullSupport); + p += log_sprintf(pMac, p, "2nd Channel offset = %d\n", + psessionEntry->hHTSecondaryChannelOffset); +#endif + return p; +} + +/******************************************* + * FUNCTION: triggerBeaconGen() + * + * This logdump sends SIR_SCH_BEACON_GEN_IND to SCH. + * SCH then proceeds to generate a beacon template + * and copy it to the Host/SoftMAC shared memory + * + * TODO - This routine can safely be deleted once + * beacon generation is working + ******************************************/ +char *triggerBeaconGen( tpAniSirGlobal pMac, char *p ) +{ + tSirMsgQ mesg = { (tANI_U16) SIR_LIM_BEACON_GEN_IND, (tANI_U16) 0, (tANI_U32) 0 }; + + pMac->lim.gLimSmeState = eLIM_SME_NORMAL_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + pMac->lim.gLimSystemRole = eLIM_AP_ROLE; + + p += log_sprintf( pMac, p, + "Posted SIR_LIM_BEACON_GEN_IND with result = %s\n", + (eSIR_SUCCESS == limPostMsgApi( pMac, &mesg ))? + "Success": "Failure" ); + + return p; +} + + +/******************************************* + * FUNCTION: testLimSendProbeRsp() + * + * This logdump sends SIR_MAC_MGMT_PROBE_RSP + * + * TODO - This routine can safely be deleted once + * the MGMT frame transmission is working + ******************************************/ +char *testLimSendProbeRsp( tpAniSirGlobal pMac, char *p ) +{ + tSirMacAddr peerMacAddr = { 0, 1, 2, 3, 4, 5 }; + tAniSSID ssId; + tANI_U32 len = SIR_MAC_MAX_SSID_LENGTH; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + + + if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, + WNI_CFG_SSID, + (tANI_U8 *) &ssId.ssId, + (tANI_U32 *) &len )) + { + // Could not get SSID from CFG. Log error. + p += log_sprintf( pMac, p, "Unable to retrieve SSID\n" ); + return p; + } + else + ssId.length = (tANI_U8) len; + + p += log_sprintf( pMac, p, "Calling limSendProbeRspMgmtFrame...\n" ); + limSendProbeRspMgmtFrame( pMac, peerMacAddr, &ssId, -1, 1, psessionEntry , 0); + + return p; +} + + +static char *sendSmeScanReq(tpAniSirGlobal pMac, char *p) +{ + tSirMsgQ msg; + tSirSmeScanReq scanReq, *pScanReq; + + p += log_sprintf( pMac,p, "sendSmeScanReq: Preparing eWNI_SME_SCAN_REQ message\n"); + + pScanReq = (tSirSmeScanReq *) &scanReq; + + pScanReq = vos_mem_malloc(sizeof(tSirSmeScanReq)); + if (NULL == pScanReq) + { + p += log_sprintf( pMac,p,"sendSmeScanReq: AllocateMemory() failed \n"); + return p; + } + + pScanReq->messageType = eWNI_SME_SCAN_REQ; + pScanReq->minChannelTime = 30; + pScanReq->maxChannelTime = 130; + pScanReq->bssType = eSIR_INFRASTRUCTURE_MODE; + limGetMyMacAddr(pMac, pScanReq->bssId); + pScanReq->numSsid = 1; + vos_mem_copy((void *) &pScanReq->ssId[0].ssId, (void *)"Ivan", 4); + pScanReq->ssId[0].length = 4; + pScanReq->scanType = eSIR_ACTIVE_SCAN; + pScanReq->returnAfterFirstMatch = 0; + pScanReq->returnUniqueResults = 0; + pScanReq->returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS; + pScanReq->channelList.numChannels = 1; + pScanReq->channelList.channelNumber[0] = 6; + pScanReq->uIEFieldLen = 0; + pScanReq->uIEFieldOffset = sizeof(tSirSmeScanReq); + pScanReq->sessionId = 0; + + msg.type = eWNI_SME_SCAN_REQ; + msg.bodyptr = pScanReq; + msg.bodyval = 0; + p += log_sprintf( pMac,p, "sendSmeScanReq: limPostMsgApi(eWNI_SME_SCAN_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + +static char *sendSmeDisAssocReq(tpAniSirGlobal pMac, char *p,tANI_U32 arg1 ,tANI_U32 arg2) +{ + + tpDphHashNode pStaDs; + tSirMsgQ msg; + tSirSmeDisassocReq *pDisAssocReq; + tpPESession psessionEntry; + + //arg1 - assocId + //arg2 - sessionId + if( arg1 < 1 ) + { + p += log_sprintf( pMac,p,"Invalid session OR Assoc ID \n"); + return p; + } + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + return p; + } + + pStaDs = dphGetHashEntry(pMac, (tANI_U16)arg1, &psessionEntry->dph.dphHashTable); + + if(NULL == pStaDs) + { + p += log_sprintf( pMac,p, "Could not find station with assocId = %d\n", arg1); + return p; + } + + pDisAssocReq = vos_mem_malloc(sizeof(tSirSmeDisassocReq)); + if (NULL == pDisAssocReq) + { + p += log_sprintf( pMac,p,"sendSmeDisAssocReq: AllocateMemory() failed \n"); + return p; + } + + if( ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry ->limSystemRole == eLIM_BT_AMP_STA_ROLE) ) && + (psessionEntry->statypeForBss == STA_ENTRY_PEER)) + { + sirCopyMacAddr(pDisAssocReq->bssId,psessionEntry->bssId); + sirCopyMacAddr(pDisAssocReq->peerMacAddr,psessionEntry->bssId); + } + if((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + { + sirCopyMacAddr(pDisAssocReq->peerMacAddr,pStaDs->staAddr); + sirCopyMacAddr(pDisAssocReq->bssId,psessionEntry->bssId); + } + + pDisAssocReq->messageType = eWNI_SME_DISASSOC_REQ; + + pDisAssocReq->length = sizeof(tSirSmeDisassocReq); + + pDisAssocReq->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + + pDisAssocReq->sessionId = 0; + + pDisAssocReq->transactionId = 0; + + msg.type = eWNI_SME_DISASSOC_REQ; + msg.bodyptr = pDisAssocReq; + msg.bodyval = 0; + + p += log_sprintf( pMac,p, "sendSmeDisAssocReq: limPostMsgApi(eWNI_SME_DISASSOC_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + + +static char *sendSmeStartBssReq(tpAniSirGlobal pMac, char *p,tANI_U32 arg1) +{ + tSirMsgQ msg; + tSirSmeStartBssReq *pStartBssReq; + unsigned char *pBuf; + ePhyChanBondState cbMode; + tSirNwType nwType; + + p += log_sprintf( pMac,p, "sendSmeStartBssReq: Preparing eWNI_SME_START_BSS_REQ message\n"); + + if(arg1 > 2) + { + p += log_sprintf( pMac,p,"Invalid Argument1 \n"); + return p; + } + + pStartBssReq = vos_mem_malloc(sizeof(tSirSmeStartBssReq)); + if (NULL == pStartBssReq) + { + p += log_sprintf( pMac,p,"sendSmeStartBssReq: AllocateMemory() failed \n"); + return p; + } + + pStartBssReq->messageType = eWNI_SME_START_BSS_REQ; + pStartBssReq->length = 29; // 0x1d + + if(arg1 == 0) //BTAMP STATION + { + pStartBssReq->bssType = eSIR_BTAMP_STA_MODE; + + pStartBssReq->ssId.length = 5; + vos_mem_copy((void *) &pStartBssReq->ssId.ssId, (void *)"BTSTA", 5); + } + else if(arg1 == 1) //BTAMP AP + { + pStartBssReq->bssType = eSIR_BTAMP_AP_MODE; + pStartBssReq->ssId.length = 4; + vos_mem_copy((void *) &pStartBssReq->ssId.ssId, (void *)"BTAP", 4); + } + else //IBSS + { + pStartBssReq->bssType = eSIR_IBSS_MODE; + pStartBssReq->ssId.length = 4; + vos_mem_copy((void *) &pStartBssReq->ssId.ssId, (void *)"Ibss", 4); + } + + // Filling in channel ID 6 + pBuf = &(pStartBssReq->ssId.ssId[pStartBssReq->ssId.length]); + *pBuf = 6; + pBuf++; + + // Filling in CB mode + cbMode = PHY_SINGLE_CHANNEL_CENTERED; + vos_mem_copy(pBuf, (tANI_U8 *)&cbMode, sizeof(ePhyChanBondState)); + pBuf += sizeof(ePhyChanBondState); + + // Filling in RSN IE Length to zero + vos_mem_set(pBuf, sizeof(tANI_U16), 0); //tSirRSNie->length + pBuf += sizeof(tANI_U16); + + // Filling in NW Type + nwType = eSIR_11G_NW_TYPE; + vos_mem_copy(pBuf, (tANI_U8 *)&nwType, sizeof(tSirNwType)); + pBuf += sizeof(tSirNwType); + + /* ---- To be filled by LIM later ---- + pStartBssReq->operationalRateSet + pStartBssReq->extendedRateSet + pStartBssReq->dot11mode + pStartBssReq->bssId + pStartBssReq->selfMacAddr + pStartBssReq->beaconInterval + pStartBssReq->sessionId = 0; + pStartBssReq->transactionId = 0; + * ------------------------------------ */ + + msg.type = eWNI_SME_START_BSS_REQ; + msg.bodyptr = pStartBssReq; + msg.bodyval = 0; + p += log_sprintf( pMac,p, "sendSmeStartBssReq: limPostMsgApi(eWNI_SME_START_BSS_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + +static char *sendSmeStopBssReq(tpAniSirGlobal pMac, char *p, tANI_U32 sessionId) +{ + tSirMsgQ msg; + tSirSmeStopBssReq stopBssReq, *pStopBssReq; + tANI_U16 msgLen = 0; + tpPESession psessionEntry; + + psessionEntry = peFindSessionBySessionId(pMac, (tANI_U8)sessionId); + if ( psessionEntry == NULL ) + { + limLog(pMac, LOGP, FL("Session entry does not exist for given sessionID \n")); + return p; + } + + p += log_sprintf( pMac,p, "sendSmeStopBssReq: Preparing eWNI_SME_STOP_BSS_REQ message\n"); + pStopBssReq = (tSirSmeStopBssReq *) &stopBssReq; + + pStopBssReq = vos_mem_malloc(sizeof(tSirSmeStopBssReq)); + if (NULL == pStopBssReq) + { + p += log_sprintf( pMac,p,"sendSmeStopBssReq: AllocateMemory() failed \n"); + return p; + } + + pStopBssReq->messageType = eWNI_SME_STOP_BSS_REQ; + msgLen += sizeof(tANI_U32); // msgType + length + + pStopBssReq->reasonCode = eSIR_SME_SUCCESS; + msgLen += sizeof(tSirResultCodes); + + vos_mem_copy((void *) &pStopBssReq->bssId, (void *)psessionEntry->bssId, 6); + msgLen += sizeof(tSirMacAddr); + + pStopBssReq->sessionId = (tANI_U8)sessionId; + msgLen += sizeof(tANI_U8); + + pStopBssReq->transactionId = 0; + msgLen += sizeof(tANI_U16); + + pStopBssReq->length = msgLen; + + msg.type = eWNI_SME_STOP_BSS_REQ; + msg.bodyptr = pStopBssReq; + msg.bodyval = 0; + p += log_sprintf( pMac,p, "sendSmeStopBssReq: limPostMsgApi(eWNI_SME_STOP_BSS_REQ) \n"); + limPostMsgApi(pMac, &msg); + + return p; +} + +static char *sendSmeJoinReq(tpAniSirGlobal pMac, char *p) +{ + tSirMsgQ msg; + tSirSmeJoinReq *pJoinReq; + unsigned char *pBuf; + tANI_U16 msgLen = 307; + + tANI_U8 msgDump[307] = { + 0x06, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, + 0xDE, 0xAD, 0xBA, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x21, 0x04, 0x02, 0x00, 0x00, + 0x00, 0x01, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0xA8, 0x85, 0x4F, 0x7A, 0x00, 0x06, 0x41, + 0x6E, 0x69, 0x4E, 0x65, 0x74, 0x01, 0x04, 0x82, 0x84, 0x8B, + 0x96, 0x03, 0x01, 0x06, 0x07, 0x06, 0x55, 0x53, 0x49, 0x01, + 0x0E, 0x1E, 0x2A, 0x01, 0x00, 0x32, 0x08, 0x0C, 0x12, 0x18, + 0x24, 0x30, 0x48, 0x60, 0x6C, 0x2D, 0x1A, 0xEE, 0x11, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3D, 0x16, 0x06, 0x07, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x18, 0x00, + 0x50, 0xF2, 0x02, 0x01, 0x01, 0x01, 0x00, 0x03, 0xA4, 0x00, + 0x00, 0x27, 0xA4, 0x00, 0x00, 0x42, 0x43, 0x5E, 0x00, 0x62, + 0x32, 0x2F, 0x00, 0xDD, 0x14, 0x00, 0x0A, 0xF5, 0x00, 0x03, + 0x01, 0x03, 0x05, 0x0A, 0x02, 0x80, 0xC0, 0x12, 0x06, 0xFF, + 0xFF, 0xFF, 0xFF, 0xB6, 0x0D, 0xDD, 0x6E, 0x00, 0x50, 0xF2, + 0x04, 0x10, 0x4A, 0x00, 0x01, 0x10, 0x10, 0x44, 0x00, 0x01, + 0x01, 0x10, 0x3B, 0x00, 0x01, 0x03, 0x10, 0x47, 0x00, 0x10, + 0xDB, 0xC6, 0x77, 0x28, 0xB9, 0xF3, 0xD8, 0x58, 0x86, 0xFF, + 0xFC, 0x6B, 0xB6, 0xB9, 0x27, 0x79, 0x10, 0x21, 0x00, 0x08, + 0x51, 0x75, 0x61, 0x6C, 0x63, 0x6F, 0x6D, 0x6D, 0x10, 0x23, + 0x00, 0x07, 0x57, 0x46, 0x52, 0x34, 0x30, 0x33, 0x31, 0x10, + 0x24, 0x00, 0x06, 0x4D, 0x4E, 0x31, 0x32, 0x33, 0x34, 0x10, + 0x42, 0x00, 0x06, 0x53, 0x4E, 0x31, 0x32, 0x33, 0x34, 0x10, + 0x54, 0x00, 0x08, 0x00, 0x06, 0x00, 0x50, 0xF2, 0x04, 0x00, + 0x01, 0x10, 0x11, 0x00, 0x06, 0x31, 0x31, 0x6E, 0x2D, 0x41, + 0x50, 0x10, 0x08, 0x00, 0x02, 0x01, 0x8E + }; + + pJoinReq = vos_mem_malloc(msgLen); + if (NULL == pJoinReq) + { + p += log_sprintf( pMac,p,"sendSmeJoinReq: AllocateMemory() failed \n"); + return p; + } + + pBuf = (unsigned char *)pJoinReq; + vos_mem_copy(pBuf, (tANI_U8 *)msgDump, msgLen); + + msg.type = eWNI_SME_JOIN_REQ; + msg.bodyptr = pJoinReq; + msg.bodyval = 0; + limPostMsgApi(pMac, &msg); + + return p; +} + + +static char *printSessionInfo(tpAniSirGlobal pMac, char *p) +{ + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + tANI_U8 i; + + p += log_sprintf( pMac, p, "Dump PE Session \n"); + + for(i=0; i < pMac->lim.maxBssId; i++) + { + if( pMac->lim.gpSession[i].valid ) + { + psessionEntry = &pMac->lim.gpSession[i]; + p += log_sprintf( pMac,p, "*****************************************\n"); + p += log_sprintf( pMac,p, " PE Session [%d] \n", i); + p += log_sprintf( pMac,p, "available: %d \n", psessionEntry->available); + p += log_sprintf( pMac,p, "peSessionId: %d, smeSessionId: %d, transactionId: %d \n", + psessionEntry->peSessionId, psessionEntry->smeSessionId, psessionEntry->smeSessionId); + p += log_sprintf( pMac,p, "bssId: %02X:%02X:%02X:%02X:%02X:%02X \n", + psessionEntry->bssId[0], psessionEntry->bssId[1], psessionEntry->bssId[2], + psessionEntry->bssId[3], psessionEntry->bssId[4], psessionEntry->bssId[5]); + p += log_sprintf( pMac,p, "selfMacAddr: %02X:%02X:%02X:%02X:%02X:%02X \n", + psessionEntry->selfMacAddr[0], psessionEntry->selfMacAddr[1], psessionEntry->selfMacAddr[2], + psessionEntry->selfMacAddr[3], psessionEntry->selfMacAddr[4], psessionEntry->selfMacAddr[5]); + p += log_sprintf( pMac,p, "bssIdx: %d \n", psessionEntry->bssIdx); + p += log_sprintf( pMac,p, "valid: %d \n", psessionEntry->valid); + p += log_sprintf( pMac,p, "limMlmState: (%d) %s ", psessionEntry->limMlmState, limMlmStateStr(psessionEntry->limMlmState) ); + p += log_sprintf( pMac,p, "limPrevMlmState: (%d) %s ", psessionEntry->limPrevMlmState, limMlmStateStr(psessionEntry->limMlmState) ); + p += log_sprintf( pMac,p, "limSmeState: (%d) %s ", psessionEntry->limSmeState, limSmeStateStr(psessionEntry->limSmeState) ); + p += log_sprintf( pMac,p, "limPrevSmeState: (%d) %s ", psessionEntry->limPrevSmeState, limSmeStateStr(psessionEntry->limPrevSmeState) ); + p += log_sprintf( pMac,p, "limSystemRole: (%d) %s \n", psessionEntry->limSystemRole, getRole(psessionEntry->limSystemRole) ); + p += log_sprintf( pMac,p, "bssType: (%d) %s \n", psessionEntry->bssType, limBssTypeStr(psessionEntry->bssType)); + p += log_sprintf( pMac,p, "operMode: %d \n", psessionEntry->operMode); + p += log_sprintf( pMac,p, "dot11mode: %d \n", psessionEntry->dot11mode); + p += log_sprintf( pMac,p, "htCapability: %d \n", psessionEntry->htCapability); + p += log_sprintf( pMac,p, "limRFBand: %d \n", psessionEntry->limRFBand); + p += log_sprintf( pMac,p, "limIbssActive: %d \n", psessionEntry->limIbssActive); + p += log_sprintf( pMac,p, "limCurrentAuthType: %d \n", psessionEntry->limCurrentAuthType); + p += log_sprintf( pMac,p, "limCurrentBssCaps: %d \n", psessionEntry->limCurrentBssCaps); + p += log_sprintf( pMac,p, "limCurrentBssQosCaps: %d \n", psessionEntry->limCurrentBssQosCaps); + p += log_sprintf( pMac,p, "limCurrentBssPropCap: %d \n", psessionEntry->limCurrentBssPropCap); + p += log_sprintf( pMac,p, "limSentCapsChangeNtf: %d \n", psessionEntry->limSentCapsChangeNtf); + p += log_sprintf( pMac,p, "LimAID: %d \n", psessionEntry->limAID); + p += log_sprintf( pMac,p, "ReassocbssId: %02X:%02X:%02X:%02X:%02X:%02X \n", + psessionEntry->limReAssocbssId[0], psessionEntry->limReAssocbssId[1], psessionEntry->limReAssocbssId[2], + psessionEntry->limReAssocbssId[3], psessionEntry->limReAssocbssId[4], psessionEntry->limReAssocbssId[5]); + p += log_sprintf( pMac,p, "limReassocChannelId: %d \n", psessionEntry->limReassocChannelId); + p += log_sprintf( pMac,p, "limReassocBssCaps: %d \n", psessionEntry->limReassocBssCaps); + p += log_sprintf( pMac,p, "limReassocBssQosCaps: %d \n", psessionEntry->limReassocBssQosCaps); + p += log_sprintf( pMac,p, "limReassocBssPropCap: %d \n", psessionEntry->limReassocBssPropCap); + p += log_sprintf( pMac,p, "********************************************\n"); + } + } + return p; +} + +void +limSetEdcaBcastACMFlag(tpAniSirGlobal pMac, tANI_U32 ac, tANI_U32 acmFlag) +{ + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + psessionEntry->gLimEdcaParamsBC[ac].aci.acm = (tANI_U8)acmFlag; + psessionEntry->gLimEdcaParamSetCount++; + schSetFixedBeaconFields(pMac,psessionEntry); +} + +static char * +limDumpEdcaParams(tpAniSirGlobal pMac, char *p) +{ + tANI_U8 i = 0; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + p += log_sprintf( pMac,p, "EDCA parameter set count = %d\n", psessionEntry->gLimEdcaParamSetCount); + p += log_sprintf( pMac,p, "Broadcast parameters\n"); + p += log_sprintf( pMac,p, "AC\tACI\tACM\tAIFSN\tCWMax\tCWMin\tTxopLimit\t\n"); + for(i = 0; i < MAX_NUM_AC; i++) + { + //right now I am just interested in ACM bit. this can be extended for all other EDCA paramters. + p += log_sprintf( pMac,p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i, + psessionEntry->gLimEdcaParamsBC[i].aci.aci, psessionEntry->gLimEdcaParamsBC[i].aci.acm, + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn, psessionEntry->gLimEdcaParamsBC[i].cw.max, + psessionEntry->gLimEdcaParamsBC[i].cw.min, psessionEntry->gLimEdcaParamsBC[i].txoplimit); + } + + p += log_sprintf( pMac,p, "\nLocal parameters\n"); + p += log_sprintf( pMac,p, "AC\tACI\tACM\tAIFSN\tCWMax\tCWMin\tTxopLimit\t\n"); + for(i = 0; i < MAX_NUM_AC; i++) + { + //right now I am just interested in ACM bit. this can be extended for all other EDCA paramters. + p += log_sprintf( pMac,p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i, + psessionEntry->gLimEdcaParams[i].aci.aci, psessionEntry->gLimEdcaParams[i].aci.acm, + psessionEntry->gLimEdcaParams[i].aci.aifsn, psessionEntry->gLimEdcaParams[i].cw.max, + psessionEntry->gLimEdcaParams[i].cw.min, psessionEntry->gLimEdcaParams[i].txoplimit); + } + + return p; +} + + +static char* limDumpTspecEntry(tpAniSirGlobal pMac, char *p, tANI_U32 tspecEntryNo) +{ + tpLimTspecInfo pTspecList; + if(tspecEntryNo >= LIM_NUM_TSPEC_MAX) + { + p += log_sprintf( pMac,p, "Tspec Entry no. %d is out of allowed range(0 .. %d)\n", + tspecEntryNo, (LIM_NUM_TSPEC_MAX - 1)); + return p; + } + pTspecList = &pMac->lim.tspecInfo[tspecEntryNo]; + if (pTspecList->inuse) + p += log_sprintf( pMac,p, "Entry %d is VALID\n", tspecEntryNo); + else + { + p += log_sprintf( pMac,p, "Entry %d is UNUSED\n", tspecEntryNo); + return p; + } + p += log_sprintf( pMac,p, "\tSta %0x:%0x:%0x:%0x:%0x:%0x, AID %d, Index %d\n", + pTspecList->staAddr[0], pTspecList->staAddr[1], + pTspecList->staAddr[2], pTspecList->staAddr[3], + pTspecList->staAddr[4], pTspecList->staAddr[5], + pTspecList->assocId, pTspecList->idx); + p += log_sprintf( pMac,p, "\tType %d, Length %d, ackPolicy %d, userPrio %d, accessPolicy = %d, Dir %d, tsid %d\n", + pTspecList->tspec.type, pTspecList->tspec.length, + pTspecList->tspec.tsinfo.traffic.ackPolicy, pTspecList->tspec.tsinfo.traffic.userPrio, + pTspecList->tspec.tsinfo.traffic.accessPolicy, pTspecList->tspec.tsinfo.traffic.direction, + pTspecList->tspec.tsinfo.traffic.tsid); + p += log_sprintf( pMac,p, "\tPsb %d, Agg %d, TrafficType %d, schedule %d; msduSz: nom %d, max %d\n", + pTspecList->tspec.tsinfo.traffic.psb, pTspecList->tspec.tsinfo.traffic.aggregation, + pTspecList->tspec.tsinfo.traffic.trafficType, pTspecList->tspec.tsinfo.schedule.schedule, + pTspecList->tspec.nomMsduSz, pTspecList->tspec.maxMsduSz); + p += log_sprintf( pMac,p, "\tSvcInt: Min %d, Max %d; dataRate: Min %d, mean %d, peak %d\n", + pTspecList->tspec.minSvcInterval, pTspecList->tspec.maxSvcInterval, + pTspecList->tspec.minDataRate, pTspecList->tspec.meanDataRate, + pTspecList->tspec.peakDataRate); + p += log_sprintf( pMac,p, "\tmaxBurstSz %d, delayBound %d, minPhyRate %d, surplusBw %d, mediumTime %d\n", + pTspecList->tspec.maxBurstSz, pTspecList->tspec.delayBound, + pTspecList->tspec.minPhyRate, pTspecList->tspec.surplusBw, + pTspecList->tspec.mediumTime); + + return p; +} + +static char* dumpTspecTableSummary(tpAniSirGlobal pMac, tpLimTspecInfo pTspecList, char *p, int ctspec) +{ + p += log_sprintf( pMac, p, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + ctspec, pTspecList->idx, pTspecList->assocId, + pTspecList->tspec.tsinfo.traffic.ackPolicy, pTspecList->tspec.tsinfo.traffic.userPrio, + pTspecList->tspec.tsinfo.traffic.psb, pTspecList->tspec.tsinfo.traffic.aggregation, + pTspecList->tspec.tsinfo.traffic.accessPolicy, pTspecList->tspec.tsinfo.traffic.direction, + pTspecList->tspec.tsinfo.traffic.tsid, pTspecList->tspec.tsinfo.traffic.trafficType); + + return p; +} + + +static char* limDumpDphTableSummary(tpAniSirGlobal pMac,char *p) +{ + tANI_U8 i, j; + p += log_sprintf( pMac,p, "DPH Table dump\n"); + + for(j=0; j < pMac->lim.maxBssId; j++) + { + /* Find first free room in session table */ + if(pMac->lim.gpSession[j].valid) + { + p += log_sprintf( pMac,p, "aid staId bssid encPol qosMode wme 11e wsm staaddr\n"); + for(i = 0; i < pMac->lim.gpSession[j].dph.dphHashTable.size; i++) + { + if (pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].added) + { + p += log_sprintf( pMac,p, "%d %d %d %d %d %d %d %d %x:%x:%x:%x:%x:%x\n", + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].assocId, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staIndex, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].bssId, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].encPolicy, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].qosMode, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].wmeEnabled, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].lleEnabled, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].wsmEnabled, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAuthenticated, + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[0], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[1], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[2], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[3], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[4], + pMac->lim.gpSession[j].dph.dphHashTable.pDphNodeArray[i].staAddr[5]); + } + } + } + } + return p; +} + +// add the specified tspec to the tspec list +static char* limDumpTsecTable( tpAniSirGlobal pMac, char* p) +{ + int ctspec; + tpLimTspecInfo pTspecList = &pMac->lim.tspecInfo[0]; + + p += log_sprintf( pMac,p, "=======LIM TSPEC TABLE DUMP\n"); + p += log_sprintf( pMac,p, "Num\tIdx\tAID\tAckPol\tUP\tPSB\tAgg\tAccessPol\tDir\tTSID\ttraffic\n"); + + for (ctspec = 0; ctspec < LIM_NUM_TSPEC_MAX; ctspec++, pTspecList++) + { + if (pTspecList->inuse) + p = dumpTspecTableSummary(pMac, pTspecList, p, ctspec); + } + return p; +} + +static char * +dump_lim_tspec_table( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = limDumpTsecTable(pMac, p); + return p; +} + +static char * +dump_lim_tspec_entry( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = limDumpTspecEntry(pMac, p, arg1); + return p; +} + +static char * +dump_lim_dph_table_summary( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = limDumpDphTableSummary(pMac, p); + return p; +} + + +static char * +dump_lim_link_monitor_stats( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 ind, val; + + (void) arg2; (void) arg3; (void) arg4; + p += log_sprintf( pMac,p, "\n ----- LIM Heart Beat Stats ----- \n"); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in LinkEst State = %d\n", + pMac->lim.gLimHBfailureCntInLinkEstState); + p += log_sprintf( pMac,p, "No. of Probe Failures after HB failed = %d\n", + pMac->lim.gLimProbeFailureAfterHBfailedCnt); + p += log_sprintf( pMac,p, "No. of HeartBeat Failures in Other States = %d\n", + pMac->lim.gLimHBfailureCntInOtherStates); + + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val) == eSIR_SUCCESS) + p += log_sprintf( pMac,p, "Cfg HeartBeat Threshold = %d\n", val); + + p += log_sprintf( pMac,p, "# Beacons Rcvd in HB interval # of times\n"); + + for (ind = 1; ind < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL; ind++) + { + p += log_sprintf( pMac,p, "\t\t\t\t\t\t\t\t%2d\t\t\t\t\t\t\t\t\t\t\t%8d\n", ind, + pMac->lim.gLimHeartBeatBeaconStats[ind]); + } + p += log_sprintf( pMac,p, "\t\t\t\t\t\t\t\t%2d>\t\t\t\t\t\t\t\t\t\t%8d\n", + MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL-1, + pMac->lim.gLimHeartBeatBeaconStats[0]); + + if (arg1 != 0) + { + for (ind = 0; ind < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL; ind++) + pMac->lim.gLimHeartBeatBeaconStats[ind] = 0; + + pMac->lim.gLimHBfailureCntInLinkEstState = 0; + pMac->lim.gLimProbeFailureAfterHBfailedCnt = 0; + pMac->lim.gLimHBfailureCntInOtherStates = 0; + + p += log_sprintf( pMac,p, "\nReset HeartBeat Statistics\n"); + } + return p; +} + +static char * +dump_lim_edca_params( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = limDumpEdcaParams(pMac, p); + return p; +} + +static char * +dump_lim_acm_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg3; (void) arg4; + limSetEdcaBcastACMFlag(pMac, arg1 /*ac(0..3)*/, arg2 /*(acmFlag = 1 to set ACM*/); + return p; +} + +static char * +dump_lim_bgscan_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->lim.gLimForceBackgroundScanDisable = (arg1 == 0) ? 1 : 0; + p += log_sprintf( pMac,p, "Bgnd scan is now %s\n", + (pMac->lim.gLimForceBackgroundScanDisable) ? "Disabled" : "On"); + return p; +} + +static char * +dump_lim_linkmonitor_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->sys.gSysEnableLinkMonitorMode = (arg1 == 0) ? 0 : 1; + p += log_sprintf( pMac,p, "LinkMonitor mode enable = %s\n", + (pMac->sys.gSysEnableLinkMonitorMode) ? "On" : "Off"); + return p; +} + +static char * +dump_lim_proberesp_toggle( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->lim.gLimProbeRespDisableFlag = (arg1 == 0) ? 0 : 1; + p += log_sprintf( pMac,p, "ProbeResponse mode disable = %s\n", + (pMac->lim.gLimProbeRespDisableFlag) ? "On" : "Off"); + return p; +} + +static char * +dump_lim_add_sta( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +#ifdef FIXME_GEN6 + tpDphHashNode pStaDs; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + tSirMacAddr staMac = {0}; + tANI_U16 peerIdx; + if(arg2 > 5) + goto addStaFail; + peerIdx = limAssignPeerIdx(pMac, psessionEntry); + pStaDs = dphGetHashEntry(pMac, peerIdx); + if(NULL == pStaDs) + { + staMac[5] = (tANI_U8) arg1; + pStaDs = dphAddHashEntry(pMac, staMac, peerIdx, &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + goto addStaFail; + + pStaDs->staType = STA_ENTRY_PEER; + switch(arg2) + { + //11b station + case 0: + { + pStaDs->mlmStaContext.htCapability = 0; + pStaDs->erpEnabled = 0; + p += log_sprintf( pMac,p, "11b"); + } + break; + //11g station + case 1: + { + pStaDs->mlmStaContext.htCapability = 0; + pStaDs->erpEnabled = 1; + p += log_sprintf( pMac,p, "11g"); + } + break; + //ht20 station non-GF + case 2: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 0; + pStaDs->htGreenfield = 0; + p += log_sprintf( pMac,p, "HT20 non-GF"); + } + break; + //ht20 station GF + case 3: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 0; + pStaDs->htGreenfield = 1; + p += log_sprintf( pMac,p, "HT20 GF"); + } + break; + //ht40 station non-GF + case 4: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 1; + pStaDs->htGreenfield = 0; + p += log_sprintf( pMac,p, "HT40 non-GF"); + } + break; + //ht40 station GF + case 5: + { + pStaDs->mlmStaContext.htCapability = 1; + pStaDs->erpEnabled = 1; + pStaDs->htSupportedChannelWidthSet = 1; + pStaDs->htGreenfield = 1; + p += log_sprintf( pMac,p, "HT40 GF"); + } + break; + default: + { + p += log_sprintf( pMac,p, "arg2 not in range [0..3]. Station not added.\n"); + goto addStaFail; + } + break; + } + + pStaDs->added = 1; + p += log_sprintf( pMac,p, " station with mac address 00:00:00:00:00:%x added.\n", (tANI_U8)arg1); + limAddSta(pMac, pStaDs,psessionEntry); + } + else + { +addStaFail: + p += log_sprintf( pMac,p, "Could not add station\n"); + p += log_sprintf( pMac,p, "arg1: 6th byte of the station MAC address\n"); + p += log_sprintf( pMac,p, "arg2[0..5] : station type as described below\n"); + p += log_sprintf( pMac,p, "\t 0: 11b, 1: 11g, 2: HT20 non-GF, 3: HT20 GF, 4: HT40 non-GF, 5: HT40 GF\n"); + } +#endif + return p; +} + +static char * +dump_lim_del_sta( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + tpDphHashNode pStaDs; + tLimMlmDisassocInd mlmDisassocInd; + tpPESession psessionEntry; + tANI_U8 reasonCode = eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + return p; + } + + pStaDs = dphGetHashEntry(pMac, (tANI_U16)arg1, &psessionEntry->dph.dphHashTable); + + if(NULL == pStaDs) + { + p += log_sprintf( pMac,p, "Could not find station with assocId = %d\n", arg1); + return p; + } + + if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + { + p += log_sprintf( pMac,p, "received Disassoc frame from peer that is in state %X \n", pStaDs->mlmStaContext.mlmState); + return p; + } + + pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode; + + // Issue Disassoc Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr, + (tANI_U8 *) pStaDs->staAddr, sizeof(tSirMacAddr)); + mlmDisassocInd.reasonCode = reasonCode; + mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC; + + mlmDisassocInd.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND, (tANI_U32 *) &mlmDisassocInd); + // Receive path cleanup + limCleanupRxPath(pMac, pStaDs,psessionEntry); + return p; +} + + + + +static char * +set_lim_prot_cfg( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + +/********************************** +* Protection Enable +* +*LOWER byte for associated stations +*UPPER byte for overlapping stations. +*11g ==> protection from 11g +*11b ==> protection from 11b +*each byte will have the following info +*bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 +*reserved reserved RIFS Lsig n-GF ht20 11g 11b +********************************** +WNI_CFG_PROTECTION_ENABLED I 4 9 +V RW NP RESTART +LIM +0 0xff 0xff +V RW NP RESTART +LIM +0 0xffff 0xffff + +#ENUM FROM_llB 0 +#ENUM FROM_llG 1 +#ENUM HT_20 2 +#ENUM NON_GF 3 +#ENUM LSIG_TXOP 4 +#ENUM RIFS 5 +#ENUM OLBC_FROM_llB 8 +#ENUM OLBC_FROM_llG 9 +#ENUM OLBC_HT20 10 +#ENUM OLBC_NON_GF 11 +#ENUM OLBC_LSIG_TXOP 12 +#ENUM OLBC_RIFS 13 +******************************************/ + if(1 == arg1) + dump_cfg_set(pMac, WNI_CFG_PROTECTION_ENABLED, 0xff, arg3, arg4, p); + else if(2 == arg1) + dump_cfg_set(pMac, WNI_CFG_PROTECTION_ENABLED, arg2 & 0xff, arg3, arg4, p); + else + { + p += log_sprintf( pMac,p, "To set protection config:\n"); + p += log_sprintf( pMac,p, "arg1: operation type(1 -> set to Default 0xff, 2-> set to a arg2, else print help)\n"); + } + return p; +} + + +static char * +dump_lim_set_protection_control( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + dump_cfg_set(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, arg1, arg2, arg3, p); + limSetCfgProtection(pMac, NULL); + return p; +} + + +static char * +dump_lim_send_SM_Power_Mode( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirMsgQ msg; + tpSirMbMsg pMBMsg; + tSirMacHTMIMOPowerSaveState state; + + p += log_sprintf( pMac,p, "%s: Verifying the Arguments\n", __func__); + if ((arg1 > 3) || (arg1 == 2)) + { + p += log_sprintf( pMac,p, "Invalid Argument , enter one of the valid states\n"); + return p; + } + + state = (tSirMacHTMIMOPowerSaveState) arg1; + + pMBMsg = vos_mem_malloc(WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState)); + if (NULL == pMBMsg) + { + p += log_sprintf( pMac,p, "pMBMsg is NULL\n"); + return p; + } + pMBMsg->type = eWNI_PMC_SMPS_STATE_IND; + pMBMsg->msgLen = (tANI_U16)(WNI_CFG_MB_HDR_LEN + sizeof(tSirMacHTMIMOPowerSaveState)); + vos_mem_copy(pMBMsg->data, &state, sizeof(tSirMacHTMIMOPowerSaveState)); + + msg.type = eWNI_PMC_SMPS_STATE_IND; + msg.bodyptr = pMBMsg; + msg.bodyval = 0; + + if (limPostMsgApi(pMac, &msg) != TX_SUCCESS) + { + p += log_sprintf( pMac,p, "Updating the SMPower Request has failed \n"); + vos_mem_free(pMBMsg); + } + else + { + p += log_sprintf( pMac,p, "Updating the SMPower Request is Done \n"); + } + + return p; +} + + + + +static char * +dump_lim_addba_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +tSirRetStatus status; +tpDphHashNode pSta; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + + + (void) arg4; + + // Get DPH Sta entry for this ASSOC ID + pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + p += log_sprintf( pMac, p, + "\n%s: Could not find entry in DPH table for assocId = %d\n", + __func__, + arg1 ); + } + else + { + status = limPostMlmAddBAReq( pMac, pSta, (tANI_U8) arg2, (tANI_U16) arg3,psessionEntry); + p += log_sprintf( pMac, p, + "\n%s: Attempted to send an ADDBA Req to STA Index %d, for TID %d. Send Status = %s\n", + __func__, + pSta->staIndex, + arg2, + limResultCodeStr( status )); + } + + return p; +} + +static char * +dump_lim_delba_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +tSirRetStatus status; +tpDphHashNode pSta; + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + + // Get DPH Sta entry for this ASSOC ID + pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable ); + if( NULL == pSta ) + { + p += log_sprintf( pMac, p, + "\n%s: Could not find entry in DPH table for assocId = %d\n", + __func__, + arg1 ); + } + else + { + status = limPostMlmDelBAReq( pMac, pSta, (tANI_U8) arg2, (tANI_U8) arg3, (tANI_U16) arg4 ,psessionEntry); + p += log_sprintf( pMac, p, + "\n%s: Attempted to send a DELBA Ind to STA Index %d, " + "as the BA \"%s\" for TID %d, with Reason code %d. " + "Send Status = %s\n", + __func__, + pSta->staIndex, + (arg2 == 1)? "Initiator": "Recipient", + arg3, // TID + arg4, // Reason Code + limResultCodeStr( status )); + } + + return p; +} + +static char * +dump_lim_ba_timeout( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + +/* FIXME: NO HAL IN UMAC for PRIMA */ + + p += log_sprintf( pMac, p, + "\n%s: Attempted to trigger a BA Timeout Ind to STA Index %d, for TID %d, Direction %d\n", + __func__, + arg1, // STA index + arg2, // TID + arg3 ); // BA Direction + + return p; +} + +static char * +dump_lim_list_active_ba( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ +tANI_U32 i; +tpDphHashNode pSta; + +//TBD-RAJESH HOW TO GET sessionEntry????? + +tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH + + (void) arg2; (void) arg3; (void) arg4; + + // Get DPH Sta entry for this ASSOC ID + pSta = dphGetHashEntry( pMac, (tANI_U16) arg1, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + p += log_sprintf( pMac, p, + "\n%s: Could not find entry in DPH table for assocId = %d\n", + __func__, + arg1 ); + } + else + { + p += log_sprintf( pMac, p, + "\nList of Active BA sessions for STA Index %d with Assoc ID %d\n", + pSta->staIndex, + arg1 ); + + p += log_sprintf( pMac, p, "TID\tRxBA\tTxBA\tRxBufferSize\tTxBufferSize\tRxBATimeout\tTxBATimeout\n"); + for( i = 0; i < STACFG_MAX_TC; i ++ ) + p += log_sprintf( pMac, p, + "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + i, // TID + pSta->tcCfg[i].fUseBARx, + pSta->tcCfg[i].fUseBATx, + pSta->tcCfg[i].rxBufSize, + pSta->tcCfg[i].txBufSize, + pSta->tcCfg[i].tuRxBAWaitTimeout, + pSta->tcCfg[i].tuTxBAWaitTimeout ); + } + + return p; +} + + +static char * +dump_lim_AddBA_DeclineStat( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + int Tid, Enable=(arg1 & 0x1); + tANI_U8 val; + + if (arg1 > 1) { + log_sprintf( pMac,p, "%s:Invalid Value is entered for Enable/Disable \n", __func__ ); + arg1 &= 1; + } + + val = pMac->lim.gAddBA_Declined; + + if (arg2 > 7) { + log_sprintf( pMac,p, "%s:Invalid Value is entered for Tid \n", __func__ ); + Tid = arg2 & 0x7; + } else + Tid = arg2; + + + if ( Enable) + val |= Enable << Tid; + else + val &= ~(0x1 << Tid); + + if (cfgSetInt(pMac, (tANI_U16)WNI_CFG_ADDBA_REQ_DECLINE, (tANI_U32) val) != eSIR_SUCCESS) + log_sprintf( pMac,p, "%s:Config Set for ADDBA REQ Decline has failed \n", __func__ ); + + log_sprintf( pMac,p, "%s:Decline value %d is being set for TID %d ,\n \tAddBA_Decline Cfg value is %d \n", __func__ , arg1, Tid, (int) val); + + return p; +} +static char * +dump_lim_set_dot11_mode( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + + tpPESession psessionEntry =&pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + dump_cfg_set(pMac, WNI_CFG_DOT11_MODE, arg1, arg2, arg3, p); + if ( (limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)) + schSetFixedBeaconFields(pMac,psessionEntry); + p += log_sprintf( pMac,p, "The Dot11 Mode is set to %s", limDot11ModeStr(pMac, (tANI_U8)psessionEntry->dot11mode)); + return p; +} + + +static char* dump_lim_update_cb_Mode(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 localPwrConstraint; + tpPESession psessionEntry = peFindSessionBySessionId(pMac, arg1); + + if (psessionEntry == NULL) + { + p += log_sprintf( pMac, p, "Invalid sessionId: %d \n ", arg1); + return p; + } + + if ( !psessionEntry->htCapability ) + { + p += log_sprintf( pMac,p, "Error: Dot11 mode is non-HT, can not change the CB mode.\n"); + return p; + } + + psessionEntry->htSupportedChannelWidthSet = arg2?1:0; + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + psessionEntry->htSecondaryChannelOffset = arg2; + + if(eSIR_SUCCESS != cfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, + arg2 ? WNI_CFG_CHANNEL_BONDING_MODE_ENABLE : WNI_CFG_CHANNEL_BONDING_MODE_DISABLE)) + p += log_sprintf(pMac,p, "cfgSetInt failed for WNI_CFG_CHANNEL_BONDING_MODE\n"); + + wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint); + + limSendSwitchChnlParams(pMac, psessionEntry->currentOperChannel, psessionEntry->htSecondaryChannelOffset, + (tPowerdBm) localPwrConstraint, psessionEntry->peSessionId); + if ( (limGetSystemRole(psessionEntry) == eLIM_AP_ROLE) || + (limGetSystemRole(psessionEntry) == eLIM_STA_IN_IBSS_ROLE)) + schSetFixedBeaconFields(pMac,psessionEntry); + return p; + +} + +static char* dump_lim_abort_scan(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + //csrScanAbortMacScan(pMac); + return p; + +} + +static char* dump_lim_start_stop_bg_scan(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + } + + if(arg1 == 1) + { + if (tx_timer_activate( + &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + pMac->lim.gLimBackgroundScanTerminate = TRUE; + } + else + { + pMac->lim.gLimBackgroundScanTerminate = FALSE; + pMac->lim.gLimBackgroundScanDisable = false; + pMac->lim.gLimForceBackgroundScanDisable = false; + } + } + else + { + pMac->lim.gLimBackgroundScanTerminate = TRUE; + pMac->lim.gLimBackgroundScanChannelId = 0; + pMac->lim.gLimBackgroundScanDisable = true; + pMac->lim.gLimForceBackgroundScanDisable = true; + } + return p; + +} + +static char* +dump_lim_get_pe_statistics(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpAniGetPEStatsReq pReq; + tANI_U32 statsMask; + + (void) arg2; (void) arg3; (void) arg4; + + + switch(arg1) + { + case 1: + statsMask = PE_SUMMARY_STATS_INFO; + break; + case 2: + statsMask = PE_GLOBAL_CLASS_A_STATS_INFO; + break; + case 3: + statsMask = PE_GLOBAL_CLASS_B_STATS_INFO; + break; + case 4: + statsMask = PE_GLOBAL_CLASS_C_STATS_INFO; + break; + case 5: + statsMask = PE_PER_STA_STATS_INFO; + break; + case 6: + statsMask = PE_PER_TX_PKT_STATS_INFO; + default: + return p; + } + + pReq = vos_mem_malloc(sizeof(tAniGetPEStatsReq)); + if (NULL == pReq) + { + p += log_sprintf( pMac,p, "Error: Unable to allocate memory.\n"); + return p; + } + + vos_mem_set(pReq, sizeof(*pReq), 0); + + pReq->msgType = eWNI_SME_GET_STATISTICS_REQ; + pReq->statsMask = statsMask; + pReq->staId = (tANI_U16)arg2; + + pMac->lim.gLimRspReqd = eANI_BOOLEAN_TRUE; + limPostSmeMessage(pMac, eWNI_SME_GET_STATISTICS_REQ, (tANI_U32 *) pReq); + + return p; + +} + +extern char* setLOGLevel( tpAniSirGlobal pMac, char *p, tANI_U32 module, tANI_U32 level ); +static char * +dump_lim_set_log_level( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + p = setLOGLevel(pMac, p, arg1, arg2); + return p; +} + +static char * +dump_lim_update_log_level( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + vos_trace_setLevel( arg1, arg2 ); + return p; +} + +static char * +dump_lim_scan_req_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = sendSmeScanReq(pMac, p); + return p; +} + +static char * +dump_lim_send_start_bss_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = sendSmeStartBssReq(pMac, p,arg1); + return p; +} + +static char * +dump_lim_send_join_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = sendSmeJoinReq(pMac, p); + return p; +} + +static char * +dump_lim_send_disassoc_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + + p = sendSmeDisAssocReq(pMac, p, arg1 ,arg2); + return p; +} + +static char * +dump_lim_stop_bss_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = sendSmeStopBssReq(pMac, p, arg1); + return p; +} + + +static char * +dump_lim_session_print( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = printSessionInfo(pMac, p); + return p; +} + +static char * +dump_lim_sme_reassoc_req( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 sessionId = arg1; + tCsrRoamModifyProfileFields modifyProfileFields; + tANI_U32 roamId; + + (void) arg2; (void) arg3; (void) arg4; + + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme ))) + { + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + csrReassoc( pMac, sessionId, &modifyProfileFields, &roamId, 0); + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + else + { + p += log_sprintf( pMac,p, "Invalid session = %d\n", sessionId); + } + + return p; +} + +static char * +dump_lim_dot11h_stats( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + return p; +} + +static char * +dump_lim_enable_measurement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + if (arg1) + { + pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_TRUE; + p += log_sprintf(pMac, p, "Measurement enabled\n"); + } + else + { + pMac->sys.gSysEnableLearnMode = eANI_BOOLEAN_FALSE; + p += log_sprintf(pMac, p, "Measurement disabled\n"); + } + + return p; +} + +static char * +dump_lim_enable_quietIE( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; +#if 0 + if (arg1) + { + pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_TRUE; + p += log_sprintf(pMac, p, "QuietIE enabled\n"); + } + else + { + pMac->lim.gLimSpecMgmt.fQuietEnabled = eANI_BOOLEAN_FALSE; + p += log_sprintf(pMac, p, "QuietIE disabled\n"); + } +#endif + + return p; +} + +static char * +dump_lim_disable_enable_scan( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + + if (arg1) + { + pMac->lim.fScanDisabled = 1; + p += log_sprintf(pMac, p, "Scan disabled\n"); + } + else + { + pMac->lim.fScanDisabled = 0; + p += log_sprintf(pMac, p, "scan enabled\n"); + } + + return p; +} + +static char *finishScan(tpAniSirGlobal pMac, char *p) +{ + tSirMsgQ msg; + + p += log_sprintf( pMac,p, "logDump finishScan \n"); + + msg.type = SIR_LIM_MIN_CHANNEL_TIMEOUT; + msg.bodyval = 0; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); + return p; +} + + +static char * +dump_lim_info( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + p = dumpLim( pMac, p, arg1); + return p; +} + +static char * +dump_lim_finishscan_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = finishScan(pMac, p); + return p; +} + +static char * +dump_lim_prb_rsp_send( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = testLimSendProbeRsp( pMac, p ); + return p; +} + +static char * +dump_sch_beacon_trigger( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = triggerBeaconGen(pMac, p); + return p; +} + +static char* dump_lim_set_scan_in_powersave( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + p += log_sprintf( pMac,p, "logDump set scan in powersave to %d \n", arg1); + dump_cfg_set(pMac, WNI_CFG_SCAN_IN_POWERSAVE, arg1, arg2, arg3, p); + return p; +} + +#if defined WLAN_FEATURE_VOWIFI +static char * +dump_lim_send_rrm_action( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tSirMacRadioMeasureReport *pRRMReport = + vos_mem_malloc(4*sizeof(tSirMacRadioMeasureReport)); + tANI_U8 num = (tANI_U8)(arg4 > 4 ? 4 : arg4); + tANI_U8 i; + + if (!pRRMReport) + { + p += log_sprintf(pMac, p, + "Unable to allocate memory to process command\n"); + goto done; + } + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + goto done; + } + switch (arg3) + { + case 0: + /* send two reports with incapable bit set */ + pRRMReport[0].type = 6; + pRRMReport[1].type = 7; + limSendRadioMeasureReportActionFrame( pMac, 1, 2, &pRRMReport[0], psessionEntry->bssId, psessionEntry ); + break; + case 1: + for ( i = 0 ; i < num ; i++ ) + { + pRRMReport[i].type = 5; + if ( i == 3 ) + pRRMReport[i].refused = 1; + else + pRRMReport[i].refused = 0; + + pRRMReport[i].report.beaconReport.regClass = 32; + pRRMReport[i].report.beaconReport.channel = i; + pRRMReport[i].report.beaconReport.measDuration = 23; + pRRMReport[i].report.beaconReport.phyType = i << 4; //some value. + pRRMReport[i].report.beaconReport.bcnProbeRsp = 1; + pRRMReport[i].report.beaconReport.rsni = 10; + pRRMReport[i].report.beaconReport.rcpi = 40; + + pRRMReport[i].report.beaconReport.bssid[0] = 0x00; + pRRMReport[i].report.beaconReport.bssid[1] = 0xAA; + pRRMReport[i].report.beaconReport.bssid[2] = 0xBB; + pRRMReport[i].report.beaconReport.bssid[3] = 0xCC; + pRRMReport[i].report.beaconReport.bssid[4] = 0x00; + pRRMReport[i].report.beaconReport.bssid[5] = 0x01 << i; + + + pRRMReport[i].report.beaconReport.antennaId = 10; + pRRMReport[i].report.beaconReport.parentTSF = 0x1234; + + pRRMReport[i].report.beaconReport.numIes = i * 10; + { + tANI_U8 j; + for( j = 0; j < pRRMReport[i].report.beaconReport.numIes ; j++ ) + { + pRRMReport[i].report.beaconReport.Ies[j] = j + i; //Junk values. + } + } + + } + limSendRadioMeasureReportActionFrame( pMac, 1, num, &pRRMReport[0], psessionEntry->bssId, psessionEntry ); + break; + case 2: + //send Neighbor request. + { + tSirMacNeighborReportReq neighbor; + neighbor.dialogToken = 2; + neighbor.ssid_present = (tANI_U8) arg4; + neighbor.ssid.length = 5; + vos_mem_copy(neighbor.ssid.ssId, "abcde", 5); + + limSendNeighborReportRequestFrame( pMac, &neighbor, psessionEntry->bssId, psessionEntry ); + + } + + break; + case 3: + //send Link measure report. + { + tSirMacLinkReport link; + link.dialogToken = 4; + link.txPower = 34; + link.rxAntenna = 2; + link.txAntenna = 1; + link.rcpi = 9; + link.rsni = 3; + limSendLinkReportActionFrame( pMac, &link, psessionEntry->bssId, psessionEntry ); + } + break; + default: + break; + } + +done: + vos_mem_free(pRRMReport); + return p; +} + +static char * +dump_lim_unpack_rrm_action( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tANI_U32 status; + + tANI_U8 size[] = { + 0x2C, + 0x2F, + 0x25, + 0x2C, + 0x1C, + 0x05 + }; + + tANI_U8 pBody[][100] = { + { + /*Beacon Request 0*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x25, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0x01, 0x30, 0x00, 0x14, 0x00, 0x01, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID + 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31, + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x1, + //Request IE + 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD + }, + { + /*Beacon Request 1*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x28, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0xFF, 0x30, 0x00, 0x14, 0x00, 0x01, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID +/* 0x00, 0x08, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, */ + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x1, + //Request IE + 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD, + //AP channel report + 0x33, 0x03, 0x0C, 0x01, 0x06, + 0x33, 0x03, 0x0C, 0x24, 0x30, + }, + { + /*Beacon Request 2*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x1E, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0x00, 0x30, 0x00, 0x14, 0x00, 0x02, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID + 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31, + //0x00, 0x08, 0x41, 0x53, 0x54, 0x2D, 0x57, 0x41, 0x50, 0x49, + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x0 + //Request IE + }, + { + /*Beacon Request 3*/ + 0x05, 0x00, 0x01, 0x00, 0x00, + //Measurement request IE + 0x26, 0x25, 0x01, 0x00, + //Beacon request type + 0x05, + //Beacon request starts here + 0x0C, 0x01, 0x30, 0x00, 0x69, 0x00, 0x00, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //SSID + 0x00, 0x05, 0x57, 0x69, 0x46, 0x69, 0x31, + //Reporting Condition + 0x01, 0x02, 0x00, 0x00, + //Reporting Detail + 0x02, 0x01, 0x1, + //Request IE + 0x0A, 0x05, 0x00, 0x30, 0x46, 0x36, 0xDD + }, + { + /*Neighbor report*/ + 0x05, 0x05, 0x01, + //Measurement request IE + 0x34, 0x17, + //BSSID + 0xFF, 0xFF, 0xFF, 0xFF, 0xff, 0xFF, + //BSSID INFOo + 0xED, 0x01, 0x00, 0x00, + //Reg class, channel, Phy type + 0x20, 0x01, 0x02, + //TSF Info + 0x01, 0x04, 0x02, 0x00, 0x60, 0x00, + //Condensed country + 0x02, 0x02, 0x62, 0x63 + }, + { + /* Link measurement request */ + 0x05, 0x02, 0x00, + //Txpower used + 0x00, + //Max Tx Power + 0x00 + } + }; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac,p,"Session does not exist for given session Id \n"); + return p; + } + switch (arg2) + { + case 0: + case 1: + case 2: + case 3: + { + tDot11fRadioMeasurementRequest *frm = + vos_mem_malloc(sizeof(tDot11fRadioMeasurementRequest)); + if (!frm) + { + p += log_sprintf(pMac, p, + "Unable to allocate memory to process command\n"); + break; + } + if( (status = dot11fUnpackRadioMeasurementRequest( pMac, &pBody[arg2][0], size[arg2], frm )) != 0 ) + p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status); + else + rrmProcessRadioMeasurementRequest( pMac, psessionEntry->bssId, frm, psessionEntry ); + vos_mem_free(frm); + } + break; + case 4: + { + tDot11fNeighborReportResponse *frm = + vos_mem_malloc(sizeof(tDot11fNeighborReportResponse)); + if (!frm) + { + p += log_sprintf(pMac, p, + "Unable to allocate memory to process command\n"); + break; + } + pBody[arg2][2] = (tANI_U8)arg3; //Dialog Token + if( (status = dot11fUnpackNeighborReportResponse( pMac, &pBody[arg2][0], size[arg2], frm )) != 0 ) + p += log_sprintf( pMac, p, "failed to unpack.....status = %x\n", status); + else + rrmProcessNeighborReportResponse( pMac, frm, psessionEntry ); + vos_mem_free(frm); + } + break; + case 5: + { +// FIXME. + } + break; + case 6: + { + tPowerdBm localConstraint = (tPowerdBm) arg3; + tPowerdBm maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); + maxTxPower = VOS_MIN( maxTxPower, maxTxPower-localConstraint ); + if( maxTxPower != psessionEntry->maxTxPower ) + { + rrmSendSetMaxTxPowerReq( pMac, maxTxPower, psessionEntry ); + psessionEntry->maxTxPower = maxTxPower; + } + } + break; + default: + p += log_sprintf( pMac, p, "Invalid option" ); + break; + } + return p; +} +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#ifdef RSSI_HACK +/* This dump command is needed to set the RSSI values in TL while testing handoff. Handoff code was tested + * using this dump command. Whatever the value gives as the first parameter will be considered as the average + * RSSI by TL and invokes corresponding callback registered by the clients */ +extern int dumpCmdRSSI; +static char * +dump_lim_set_tl_data_pkt_rssi( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + dumpCmdRSSI = arg1; + limLog(pMac, LOGE, FL("Setting TL data packet RSSI to %d"), dumpCmdRSSI); + return p; +} +#endif +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +/* This command is used to trigger FT Preauthentication with the AP with BSSID below */ +static char * +dump_lim_ft_event( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + static tANI_U8 macAddr[6] = {0x00, 0xde, 0xad, 0xaf, 0xaf, 0x04}; + tpPESession psessionEntry; + tSirMsgQ msg; + tpSirFTPreAuthReq pftPreAuthReq; + tANI_U16 auth_req_len = 0; + tCsrRoamConnectedProfile Profile; + + csrRoamCopyConnectProfile(pMac, arg2, &Profile); + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg2) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 363 <0> sessionid channel \n"); + return p; + } + + switch (arg1) + { + case 0: + // Send Pre-auth event + { + /*----------------*/ + p += log_sprintf( pMac,p, "Preparing Pre Auth Req message\n"); + auth_req_len = sizeof(tSirFTPreAuthReq); + + pftPreAuthReq = vos_mem_malloc(auth_req_len); + if (NULL == pftPreAuthReq) + { + p += log_sprintf( pMac,p,"Pre auth dump: AllocateMemory() failed \n"); + return p; + } + pftPreAuthReq->pbssDescription = vos_mem_malloc(sizeof(Profile.pBssDesc->length)+ + Profile.pBssDesc->length); + + pftPreAuthReq->messageType = eWNI_SME_FT_PRE_AUTH_REQ; + pftPreAuthReq->length = auth_req_len + sizeof(Profile.pBssDesc->length) + + Profile.pBssDesc->length; + pftPreAuthReq->preAuthchannelNum = 6; + + vos_mem_copy((void *) &pftPreAuthReq->currbssId, + (void *)psessionEntry->bssId, 6); + vos_mem_copy((void *) &pftPreAuthReq->preAuthbssId, + (void *)macAddr, 6); + pftPreAuthReq->ft_ies_length = (tANI_U16)pMac->ft.ftSmeContext.auth_ft_ies_length; + + // Also setup the mac address in sme context. + vos_mem_copy(pMac->ft.ftSmeContext.preAuthbssId, macAddr, 6); + + vos_mem_copy(pftPreAuthReq->ft_ies, pMac->ft.ftSmeContext.auth_ft_ies, + pMac->ft.ftSmeContext.auth_ft_ies_length); + + vos_mem_copy(Profile.pBssDesc->bssId, macAddr, 6); + + p += log_sprintf( pMac,p, "\n ----- LIM Debug Information ----- \n"); + p += log_sprintf( pMac, p, "%s: length = %d\n", __func__, + (int)pMac->ft.ftSmeContext.auth_ft_ies_length); + p += log_sprintf( pMac, p, "%s: length = %02x\n", __func__, + (int)pMac->ft.ftSmeContext.auth_ft_ies[0]); + p += log_sprintf( pMac, p, "%s: Auth Req %02x %02x %02x\n", + __func__, pftPreAuthReq->ft_ies[0], + pftPreAuthReq->ft_ies[1], pftPreAuthReq->ft_ies[2]); + + p += log_sprintf( pMac, p, "%s: Session %02x %02x %02x\n", __func__, + psessionEntry->bssId[0], + psessionEntry->bssId[1], psessionEntry->bssId[2]); + p += log_sprintf( pMac, p, "%s: Session %02x %02x %02x %p\n", __func__, + pftPreAuthReq->currbssId[0], + pftPreAuthReq->currbssId[1], + pftPreAuthReq->currbssId[2], pftPreAuthReq); + + Profile.pBssDesc->channelId = (tANI_U8)arg3; + vos_mem_copy((void *)pftPreAuthReq->pbssDescription, (void *)Profile.pBssDesc, + Profile.pBssDesc->length); + + msg.type = eWNI_SME_FT_PRE_AUTH_REQ; + msg.bodyptr = pftPreAuthReq; + msg.bodyval = 0; + + p += log_sprintf( pMac, p, "limPostMsgApi(eWNI_SME_FT_PRE_AUTH_REQ) \n"); + limPostMsgApi(pMac, &msg); + } + break; + + default: + break; + } + return p; +} +#endif +static char * +dump_lim_channel_switch_announcement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tANI_U8 nMode = arg2; + tANI_U8 nNewChannel = arg3; + tANI_U8 nCount = arg4; + tANI_U8 peer[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 363 <0> sessionid channel \n"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,"Session Not found!!!!"); + return p; + } + + limSendChannelSwitchMgmtFrame( pMac, peer, nMode, nNewChannel, nCount, psessionEntry ); + + psessionEntry->gLimChannelSwitch.switchCount = nCount; + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING; + psessionEntry->gLimChannelSwitch.switchMode = nMode; + psessionEntry->gLimChannelSwitch.primaryChannel = nNewChannel; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + +#ifdef WLAN_FEATURE_11AC +static char * +dump_lim_vht_opmode_notification(tpAniSirGlobal pMac, tANI_U32 arg1,tANI_U32 arg2,tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U8 peer[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + tANI_U8 nMode = arg2; + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 366 <0> sessionid channel \n"); + return p; + } + + limSendVHTOpmodeNotificationFrame(pMac, peer, nMode,psessionEntry); + + psessionEntry->gLimOperatingMode.present = 1; + psessionEntry->gLimOperatingMode.chanWidth = nMode; + psessionEntry->gLimOperatingMode.rxNSS = 0; + psessionEntry->gLimOperatingMode.rxNSSType = 0; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + +static char * +dump_lim_vht_channel_switch_notification(tpAniSirGlobal pMac, tANI_U32 arg1,tANI_U32 arg2,tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + tANI_U8 nChanWidth = arg2; + tANI_U8 nNewChannel = arg3; + tANI_U8 ncbMode = arg4; + tANI_U8 peer[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 367 <0> sessionid channel \n"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,"Session Not found!!!!"); + return p; + } + + limSendVHTChannelSwitchMgmtFrame( pMac, peer, nChanWidth, nNewChannel, (ncbMode+1), psessionEntry ); + + psessionEntry->gLimChannelSwitch.switchCount = 0; + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING; + psessionEntry->gLimChannelSwitch.switchMode = 1; + psessionEntry->gLimChannelSwitch.primaryChannel = nNewChannel; + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = nChanWidth; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = limGetCenterChannel(pMac,nNewChannel,(ncbMode+1),nChanWidth); + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = 0; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + +#endif +static char * +dump_lim_cancel_channel_switch_announcement( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac,(tANI_U8)arg1) )== NULL) + { + p += log_sprintf( pMac, + p,"Session does not exist usage: 363 <0> sessionid channel \n"); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN,"Session Not found!!!!"); + return p; + } + psessionEntry->gLimChannelSwitch.switchCount = 0; + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT; + psessionEntry->gLimChannelSwitch.switchMode = 0; + psessionEntry->gLimChannelSwitch.primaryChannel = 0; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return p; +} + + +static char * +dump_lim_mcc_policy_maker(tpAniSirGlobal pMac, tANI_U32 arg1,tANI_U32 arg2,tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL, "dump_lim_mcc_policy_maker arg = %d",arg1); + + if(arg1 == 0) //Disable feature completely + { + WDA_TrafficStatsTimerActivate(FALSE); + if (ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, FALSE, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + limLog( pMac, LOGE, FL("Could not get WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED")); + } + } + else if(arg1 == 1) //Enable feature + { + if (ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, TRUE, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + limLog( pMac, LOGE, FL("Could not set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED")); + } + } + else if(arg1 == 2) //Enable feature and activate periodic timer + { + if (ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, TRUE, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + limLog( pMac, LOGE, FL("Could not set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED")); + } + WDA_TrafficStatsTimerActivate(TRUE); + } + else if(arg1 == 3) //Enable only stats collection - Used for unit testing + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_FATAL, "Enabling Traffic Stats in DTS"); + WDI_DS_ActivateTrafficStats(); + } + else if(arg1 == 4) //Send current stats snapshot to Riva -- Used for unit testing + { + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tWDA_CbContext *pWDA = vos_get_context(VOS_MODULE_ID_WDA, pVosContext); + ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, TRUE, NULL, eANI_BOOLEAN_FALSE); + if(pWDA != NULL) + { + WDA_TimerTrafficStatsInd(pWDA); + } + WDA_TrafficStatsTimerActivate(FALSE); + ccmCfgSetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, FALSE,NULL, eANI_BOOLEAN_FALSE); + } + else if (arg1 == 5) //Change the periodicity of TX stats timer + { + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tWDA_CbContext *pWDA = vos_get_context(VOS_MODULE_ID_WDA, pVosContext); + if (pWDA != NULL && tx_timer_change(&pWDA->wdaTimers.trafficStatsTimer, arg2/10, arg2/10) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Disable timer before changing timeout value")); + } + } + return p; +} + +#ifdef WLANTL_DEBUG +/* API to print number of pkts received based on rate index */ +/* arg1 = station Id */ +/* arg2 = BOOLEAN value to either or not flush the counters */ +static char * +dump_lim_get_pkts_rcvd_per_rate_idx( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + /* if anything other than 1, then we need not flush the counters */ + if( arg2 != 1) + arg2 = FALSE; + + WLANTLPrintPktsRcvdPerRateIdx(pMac->roam.gVosContext, (tANI_U8)arg1, (v_BOOL_t)arg2); + return p; +} + +/* API to print number of pkts received based on rssi */ +/* arg1 = station Id */ +/* arg2 = BOOLEAN value to either or not flush the counters */ +static char * +dump_lim_get_pkts_rcvd_per_rssi_values( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + /* if anything other than 1, then we need not flush the counters */ + if( arg2 != 1) + arg2 = FALSE; + + WLANTLPrintPktsRcvdPerRssi(pMac->roam.gVosContext, (tANI_U8)arg1, (v_BOOL_t)arg2); + return p; +} +#endif + +#ifdef WLAN_FEATURE_RMC + +static char * +dump_lim_enable_rmc_data_path +( + tpAniSirGlobal pMac, + tANI_U32 arg1, + tANI_U32 arg2, + tANI_U32 arg3, + tANI_U32 arg4, + char *p +) +{ + v_MACADDR_t rmcTransmitterAddr; + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + + rmcTransmitterAddr.bytes[0] = (tANI_U8)((arg1 & 0xFF000000) >> 24); + rmcTransmitterAddr.bytes[1] = (tANI_U8)((arg1 & 0x00FF0000) >> 16); + rmcTransmitterAddr.bytes[2] = (tANI_U8)((arg1 & 0x0000FF00) >> 8); + rmcTransmitterAddr.bytes[3] = (tANI_U8)((arg1 & 0x000000FF)); + rmcTransmitterAddr.bytes[4] = (tANI_U8)((arg2 & 0xFF000000) >> 24); + rmcTransmitterAddr.bytes[5] = (tANI_U8)((arg2 & 0x00FF0000) >> 16); + + limLog(pMac, LOGE, + FL("Enable RMC data path for MCAST transmitter:" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY( rmcTransmitterAddr.bytes)); + + /*Input format is in MAC address fromat for example + iwpriv wlan0 dump 0xaabbccdd 0xeeff0000 translates into enable RMC for + MAC address 0xaa:0xbb:0xcc:0xdd:0xee:0xff*/ + + /*Enable TL data path*/ + WLANTL_EnableRMC( pVosContext, &rmcTransmitterAddr ); + + return p; +} + +static char * +dump_lim_disable_rmc_data_path +( + tpAniSirGlobal pMac, + tANI_U32 arg1, + tANI_U32 arg2, + tANI_U32 arg3, + tANI_U32 arg4, + char *p +) +{ + v_MACADDR_t rmcTransmitterAddr; + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + + rmcTransmitterAddr.bytes[0] = (tANI_U8)((arg1 & 0xFF000000) >> 24); + rmcTransmitterAddr.bytes[1] = (tANI_U8)((arg1 & 0x00FF0000) >> 16); + rmcTransmitterAddr.bytes[2] = (tANI_U8)((arg1 & 0x0000FF00) >> 8); + rmcTransmitterAddr.bytes[3] = (tANI_U8)((arg1 & 0x000000FF)); + rmcTransmitterAddr.bytes[4] = (tANI_U8)((arg2 & 0xFF000000) >> 24); + rmcTransmitterAddr.bytes[5] = (tANI_U8)((arg2 & 0x00FF0000) >> 16); + + + limLog(pMac, LOGE, + FL("Disable RMC data path for MCAST transmitter:" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY( rmcTransmitterAddr.bytes)); + + /*Input format is in MAC address fromat for example + iwpriv wlan0 dump 0xaabbccdd 0xeeff0000 translates into enable RMC for + MAC address 0xaa:0xbb:0xcc:0xdd:0xee:0xff*/ + + /*Disable TL data path*/ + WLANTL_DisableRMC( pVosContext, &rmcTransmitterAddr ); + + return p; +} + +static char * +dump_lim_rmc_status(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + limRmcDumpStatus(pMac); + return p; +} + +static char * +dump_set_mcast_dup_detect(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + v_U8_t enable; + + enable = (tANI_U8)arg1; + + /* Enable or Disable Multicast Duplicate Detection */ + WLANTL_SetMcastDuplicateDetection( pVosContext, enable); + + return p; +} +#endif /* WLAN_FEATURE_RMC */ + +static char * +dump_set_max_probe_req(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + if ((arg1 <= 0) || (arg1 > 4)){ + limLog(pMac, LOGE, + FL("invalid number. valid range 1 - 4 \n")); + return p; + } + pMac->lim.maxProbe = arg1; + return p; +} +/* API to fill Rate Info based on mac efficiency + * arg 1: mac efficiency to be used to calculate mac thorughput for a given rate index + * arg 2: starting rateIndex to apply the macEfficiency to + * arg 3: ending rateIndex to apply the macEfficiency to + */ +static char * +dump_limRateInfoBasedOnMacEff(tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + limLog(pMac, LOGE, FL("arg1 %u, arg2 %u, arg3 %u"), arg1, arg2, arg3); + WDTS_FillRateInfo((tANI_U8)(arg1), (tANI_U16)(arg2), (tANI_U16)(arg3)); + return p; +} + +static tDumpFuncEntry limMenuDumpTable[] = { + {0, "PE (300-499)", NULL}, + {300, "LIM: Dump state(s)/statistics ", dump_lim_info}, + {301, "PE.LIM: dump TSPEC Table", dump_lim_tspec_table}, + {302, "PE.LIM: dump specified TSPEC entry (id)", dump_lim_tspec_entry}, + {303, "PE.LIM: dump EDCA params", dump_lim_edca_params}, + {304, "PE.LIM: dump DPH table summary", dump_lim_dph_table_summary}, + {305, "PE.LIM: dump link monitor stats", dump_lim_link_monitor_stats}, + {306, "PE.LIM:dump Set the BAR Decline stat(arg1= 1/0 (enable/disable) arg2 =TID", dump_lim_AddBA_DeclineStat}, + {307, "PE: LIM: dump CSR Send ReAssocReq", dump_lim_sme_reassoc_req}, + {308, "PE:LIM: dump all 11H related data", dump_lim_dot11h_stats}, + {309, "PE:LIM: dump to enable Measurement on AP", dump_lim_enable_measurement}, + {310, "PE:LIM: dump to enable QuietIE on AP", dump_lim_enable_quietIE}, + {311, "PE:LIM: disable/enable scan 1(disable)", dump_lim_disable_enable_scan}, + {320, "PE.LIM: send sme scan request", dump_lim_scan_req_send}, + + + /*FIXME_GEN6*/ + /* This dump command is more of generic dump cmd and hence it should + * be moved to logDump.c + */ + {321, "PE:LIM: Set Log Level ", dump_lim_update_log_level}, + {331, "PE.LIM: Send finish scan to LIM", dump_lim_finishscan_send}, + {332, "PE.LIM: force probe rsp send from LIM", dump_lim_prb_rsp_send}, + {333, "PE.SCH: Trigger to generate a beacon", dump_sch_beacon_trigger}, + {335, "PE.LIM: set ACM flag (0..3)", dump_lim_acm_set}, + {336, "PE.LIM: Send an ADDBA Req to peer MAC arg1=aid,arg2=tid, arg3=ssn", dump_lim_addba_req}, + {337, "PE.LIM: Send a DELBA Ind to peer MAC arg1=aid,arg2=recipient(0)/initiator(1),arg3=tid,arg4=reasonCode", dump_lim_delba_req}, + {338, "PE.LIM: Trigger a BA timeout for STA index", dump_lim_ba_timeout}, + {339, "PE.LIM: List active BA session(s) for AssocID", dump_lim_list_active_ba}, + {340, "PE.LIM: Set background scan flag (0-disable, 1-enable)",dump_lim_bgscan_toggle}, + {341, "PE.LIM: Set link monitoring mode", dump_lim_linkmonitor_toggle}, + {342, "PE.LIM: AddSta <6th byte of station Mac>", dump_lim_add_sta}, + {343, "PE.LIM: DelSta ", dump_lim_del_sta}, + {344, "PE.LIM: Set probe respond flag", dump_lim_proberesp_toggle}, + {345, "PE.LIM: set protection config bitmap", set_lim_prot_cfg}, + {346, "PE:LIM: Set the Dot11 Mode", dump_lim_set_dot11_mode}, + {347, "PE:Enable or Disable Protection", dump_lim_set_protection_control}, + {348, "PE:LIM: Send SM Power Mode Action frame", dump_lim_send_SM_Power_Mode}, + {349, "PE: LIM: Change CB Mode ",dump_lim_update_cb_Mode}, + {350, "PE: LIM: abort scan", dump_lim_abort_scan}, + {351, "PE: LIM: Start stop BG scan", dump_lim_start_stop_bg_scan}, + {352, "PE: LIM: PE statistics ", dump_lim_get_pe_statistics}, + {353, "PE: LIM: Set MAC log level ", dump_lim_set_log_level}, + {354, "PE: LIM: Set Scan in Power Save <0-disable, 1-enable>", dump_lim_set_scan_in_powersave}, + {355, "PE.LIM: send sme start BSS request", dump_lim_send_start_bss_req}, + {356, "PE.LIM: dump pesession info ", dump_lim_session_print}, + {357, "PE.LIM: send DisAssocRequest", dump_lim_send_disassoc_req}, + {358, "PE.LIM: send sme stop bss request ", dump_lim_stop_bss_req}, + {359, "PE.LIM: send sme join request", dump_lim_send_join_req}, +#if defined WLAN_FEATURE_VOWIFI + {360, "PE.LIM: send an RRM action frame", dump_lim_send_rrm_action}, + {361, "PE.LIM: unpack an RRM action frame", dump_lim_unpack_rrm_action}, +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#ifdef RSSI_HACK + {362, "TL Set current RSSI", dump_lim_set_tl_data_pkt_rssi}, +#endif +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + {363, "PE.LIM: trigger pre auth/reassoc event", dump_lim_ft_event}, +#endif + {364, "PE.LIM: Send a channel switch announcement", dump_lim_channel_switch_announcement}, + {365, "PE.LIM: Cancel channel switch announcement", dump_lim_cancel_channel_switch_announcement}, +#ifdef WLAN_FEATURE_11AC + {366, "PE.LIM: Send a VHT OPMode Action Frame", dump_lim_vht_opmode_notification}, + {367, "PE.LIM: Send a VHT Channel Switch Announcement", dump_lim_vht_channel_switch_notification}, + {368, "PE.LIM: MCC Policy Maker", dump_lim_mcc_policy_maker}, +#endif +#ifdef WLANTL_DEBUG + {369, "PE.LIM: pkts/rateIdx: iwpriv wlan0 dump 368 ", dump_lim_get_pkts_rcvd_per_rate_idx}, + {370, "PE.LIM: pkts/rssi: : iwpriv wlan0 dump 369 ", dump_lim_get_pkts_rcvd_per_rssi_values}, +#endif +#ifdef WLAN_FEATURE_RMC + {371, "PE.LIM: Enable RMC data path in TL for input MCAST addr", + dump_lim_enable_rmc_data_path }, + {372, "PE.LIM: Disable RMC data path in TL for input MCAST addr", + dump_lim_disable_rmc_data_path }, + {373, "PE.LIM: Dump RMC transmitter and ruler status", dump_lim_rmc_status }, +#endif /* WLAN_FEATURE_RMC */ + {374, "PE.LIM: MAS RX stats MAC eff ", dump_limRateInfoBasedOnMacEff}, +#ifdef WLAN_FEATURE_RMC + {375, "PE.LIM: Enable(1)/Disable(0) RMC duplicate detection", dump_set_mcast_dup_detect }, +#endif /* WLAN_FEATURE_RMC */ + {376, "PE.LIM: max number of probe per scan", dump_set_max_probe_req }, +}; + + + +void limDumpInit(tpAniSirGlobal pMac) +{ + logDumpRegisterTable( pMac, &limMenuDumpTable[0], + sizeof(limMenuDumpTable)/sizeof(limMenuDumpTable[0]) ); +} + + +#endif //#if defined(ANI_LOGDUMP) + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limP2P.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limP2P.c new file mode 100644 index 000000000000..b420404340ec --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limP2P.c @@ -0,0 +1,1289 @@ +/* + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + L I M _ P 2 P . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Protocol Engine for + P2P. + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2011-05-02 djindal Corrected file indentation and changed remain on channel + handling for concurrency. +===========================================================================*/ + + +#include "limUtils.h" +#include "limSessionUtils.h" +#include "wlan_qct_wda.h" + +#define PROBE_RSP_IE_OFFSET 36 +#define BSSID_OFFSET 16 +#define ADDR2_OFFSET 10 +#define ACTION_OFFSET 24 + +/* A DFS channel can be ACTIVE for max 9000 msec, from the last + received Beacon/Prpbe Resp. */ +#define MAX_TIME_TO_BE_ACTIVE_CHANNEL 9000 + +#define REMAIN_ON_CHANNEL_UNKNOWN_ACTION_CATEGORY 0x20 +#define VENDOR_SPECIFIC_ELEMENT_ID 221 +#define REMAIN_ON_CHANNEL_MSG_SIZE 55 +#define REMAIN_ON_CHANNEL_FIRST_MARKER_FRAME 1 +#define REMAIN_ON_CHANNEL_SECOND_MARKER_FRAME 2 + +void limRemainOnChnlSuspendLinkHdlr(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data); +void limRemainOnChnlSetLinkStat(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry); +void limExitRemainOnChannel(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry); +void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); +extern tSirRetStatus limSetLinkState( + tpAniSirGlobal pMac, tSirLinkState state, + tSirMacAddr bssId, tSirMacAddr selfMacAddr, + tpSetLinkStateCallback callback, void *callbackArg); + +static tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession); +eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, void *pData); + +/*---------------------------------------------------------------------------- + * + * The function limSendRemainOnChannelDebugMarkerFrame, prepares Marker frame + * for Start and End of remain on channel with RemainOnChannelMsg as Vendor + * Specific information element of the frame. + * + *----------------------------------------------------------------------------*/ +tSirRetStatus limSendRemainOnChannelDebugMarkerFrame(tpAniSirGlobal pMac, + tANI_U8 *remainOnChannelMsg) +{ + tSirMacAddr magicMacAddr= {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + tANI_U32 nBytes, nPayload; + tSirRetStatus nSirStatus; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + publicVendorSpecific *pPublicVendorSpecific; + + pPublicVendorSpecific = vos_mem_malloc(sizeof(publicVendorSpecific)); + if( pPublicVendorSpecific == NULL ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory for Vendor specific information" + " element" ) ); + return eSIR_MEM_ALLOC_FAILED; + } + // Assigning Action category code as unknown as this is debug marker frame + pPublicVendorSpecific->category = REMAIN_ON_CHANNEL_UNKNOWN_ACTION_CATEGORY; + pPublicVendorSpecific->elementid = VENDOR_SPECIFIC_ELEMENT_ID; + pPublicVendorSpecific->length = strlen(remainOnChannelMsg); + + nPayload = sizeof(publicVendorSpecific) + pPublicVendorSpecific->length; + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to allocate %d bytes for a Remain" + " on channel action frame."), nBytes ); + nSirStatus = eSIR_MEM_ALLOC_FAILED; + goto end; + } + vos_mem_zero( pFrame, nBytes ); + + // Populate frame with MAC header + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, magicMacAddr, + pMac->lim.gSelfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descriptor for a" + " Action frame for remain on channel.") ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + + // Copy Public Vendor specific fields to frame's information element + vos_mem_copy( (pFrame + (sizeof( tSirMacMgmtHdr ))), + pPublicVendorSpecific, sizeof(publicVendorSpecific) ); + // Copy Remain On channel message to Vendor Specific information field + vos_mem_copy( (pFrame + (nBytes - pPublicVendorSpecific->length)), + remainOnChannelMsg, pPublicVendorSpecific->length ); + + halstatus = halTxFrame( pMac, pPacket, + ( tANI_U16 ) sizeof(tSirMacMgmtHdr) + nPayload, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("could not send marker frame for" + " remain on channel!" )); + //Pkt will be freed up by the callback + nSirStatus = eSIR_FAILURE; + goto end; + } + + nSirStatus = eSIR_SUCCESS; + +end: + vos_mem_free( pPublicVendorSpecific ); + return nSirStatus; +} + +/*------------------------------------------------------------------------- + * + * This function forms message for start of remain on channel with channel + * number, duration and sequence number. This message is added as data of + * vendor specific information element of Debug Marker Frame. Message will + * be in form "START-REMAIN-ON-CHANNEL-CHN=" + * "-FOR-DUR=-SEQ=" + * + *-------------------------------------------------------------------------*/ +eHalStatus limPrepareAndSendStartRemainOnChannelMsg(tpAniSirGlobal pMac, + tSirRemainOnChnReq *MsgRemainonChannel, tANI_U8 id) +{ + tANI_U8 *startRemainOnChannelMsg; + eHalStatus status = eHAL_STATUS_SUCCESS; + + startRemainOnChannelMsg = vos_mem_malloc( REMAIN_ON_CHANNEL_MSG_SIZE ); + if( NULL == startRemainOnChannelMsg ) + { + limLog(pMac, LOGE, + FL("Unable to allocate memory for remain on channel message")); + return eHAL_STATUS_FAILURE; + } + + snprintf(startRemainOnChannelMsg, REMAIN_ON_CHANNEL_MSG_SIZE, + "START-REMAIN-ON-CHANNEL%d-CHN=%d-FOR-DUR=%d-SEQ=%d", + id, MsgRemainonChannel->chnNum, MsgRemainonChannel->duration, + pMac->lim.remOnChnSeqNum); + + if( eSIR_FAILURE == limSendRemainOnChannelDebugMarkerFrame(pMac, + startRemainOnChannelMsg) ) + { + limLog( pMac, LOGE, + "%s: Could not send %d debug marker frame at start" + " of remain on channel", __func__, id); + status = eHAL_STATUS_FAILURE; + } + vos_mem_free( startRemainOnChannelMsg ); + + return status; + +} + +/*---------------------------------------------------------------------------- + * + * This function forms message for cancel of remain on channel. This message + * is added as data of Vendor Specific information element of debug marker + * frame.Message will be in form "CANCEL-REMAIN-ON-CHANNEL" + * "-SEQ=" + * + *----------------------------------------------------------------------------*/ +eHalStatus limPrepareAndSendCancelRemainOnChannelMsg(tpAniSirGlobal pMac, + tANI_U8 id) +{ + tANI_U8 *cancelRemainOnChannelMsg; + eHalStatus status = eHAL_STATUS_SUCCESS; + + cancelRemainOnChannelMsg = vos_mem_malloc( REMAIN_ON_CHANNEL_MSG_SIZE ); + if( NULL == cancelRemainOnChannelMsg ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory for end of" + " remain on channel message" )); + return eHAL_STATUS_FAILURE; + } + + snprintf(cancelRemainOnChannelMsg, REMAIN_ON_CHANNEL_MSG_SIZE, + "CANCEL-REMAIN-ON-CHANNEL%d-SEQ=%d", + id, pMac->lim.remOnChnSeqNum); + if( eSIR_FAILURE == limSendRemainOnChannelDebugMarkerFrame(pMac, + cancelRemainOnChannelMsg) ) + { + limLog( pMac, LOGE, + "%s: Could not send %d marker frame to debug cancel" + " remain on channel", __func__, id); + status = eHAL_STATUS_FAILURE; + } + vos_mem_free( cancelRemainOnChannelMsg ); + + return status; + +} + +/*------------------------------------------------------------------ + * + * Below function is callback function, it is called when + * WDA_SET_LINK_STATE_RSP is received from WDI. callback function for + * P2P of limSetLinkState + * + *------------------------------------------------------------------*/ +void limSetLinkStateP2PCallback(tpAniSirGlobal pMac, void *callbackArg) +{ + tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq; + + //Send Ready on channel indication to SME + if(pMac->lim.gpLimRemainOnChanReq) + { + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RDY_IND, eHAL_STATUS_SUCCESS, + pMac->lim.gpLimRemainOnChanReq->sessionId, 0); + if(pMac->lim.gDebugP2pRemainOnChannel) + { + if( eHAL_STATUS_SUCCESS == limPrepareAndSendStartRemainOnChannelMsg( + pMac, + MsgRemainonChannel, + REMAIN_ON_CHANNEL_SECOND_MARKER_FRAME) ) + { + limLog( pMac, LOGE, + "%s: Successfully sent 2nd Marker frame " + "seq num = %d on start ROC", __func__, + pMac->lim.remOnChnSeqNum); + } + } + } + else + { + //This is possible in case remain on channel is aborted + limLog( pMac, LOGE, FL(" NULL pointer of gpLimRemainOnChanReq") ); + } +} + +/*------------------------------------------------------------------ + * + * Remain on channel req handler. Initiate the INIT_SCAN, CHN_CHANGE + * and SET_LINK Request from SME, chnNum and duration to remain on channel. + * + *------------------------------------------------------------------*/ + + +int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + + + tSirRemainOnChnReq *MsgBuff = (tSirRemainOnChnReq *)pMsg; + pMac->lim.gpLimRemainOnChanReq = MsgBuff; + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + pMac->lim.gLimMlmState = eLIM_MLM_P2P_LISTEN_STATE; + + pMac->lim.gTotalScanDuration = MsgBuff->duration; + + /* 1st we need to suspend link with callback to initiate change channel */ + limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, + limRemainOnChnlSuspendLinkHdlr, NULL); + return FALSE; + +} + + +tSirRetStatus limCreateSessionForRemainOnChn(tpAniSirGlobal pMac, tPESession **ppP2pSession) +{ + tSirRetStatus nSirStatus = eSIR_FAILURE; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U32 val; + + if(pMac->lim.gpLimRemainOnChanReq && ppP2pSession) + { + if((psessionEntry = peCreateSession(pMac, + pMac->lim.gpLimRemainOnChanReq->selfMacAddr, &sessionId, 1)) == NULL) + { + limLog(pMac, LOGE, FL("Session Can not be created ")); + /* send remain on chn failure */ + return nSirStatus; + } + /* Store PE sessionId in session Table */ + psessionEntry->peSessionId = sessionId; + /* Store SME session Id in sessionTable */ + psessionEntry->smeSessionId = pMac->lim.gpLimRemainOnChanReq->sessionId; + psessionEntry->limSystemRole = eLIM_P2P_DEVICE_ROLE; + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, + psessionEntry->rateSet.rate, val , SIR_MAC_MAX_NUMBER_OF_RATES ); + psessionEntry->rateSet.numRates = val; + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + psessionEntry->extRateSet.rate, val, + WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN ); + psessionEntry->extRateSet.numRates = val; + + sirCopyMacAddr(psessionEntry->selfMacAddr, + pMac->lim.gpLimRemainOnChanReq->selfMacAddr); + + psessionEntry->currentOperChannel = pMac->lim.gpLimRemainOnChanReq->chnNum; + nSirStatus = eSIR_SUCCESS; + *ppP2pSession = psessionEntry; + } + + return nSirStatus; +} + + +/*------------------------------------------------------------------ + * + * limSuspenLink callback, on success link suspend, trigger change chn + * + * + *------------------------------------------------------------------*/ + +tSirRetStatus limRemainOnChnlChangeChnReq(tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *data) +{ + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + tSirRetStatus nSirStatus = eSIR_FAILURE; + + if( NULL == pMac->lim.gpLimRemainOnChanReq ) + { + //RemainOnChannel may have aborted + PELOGE(limLog( pMac, LOGE, FL(" gpLimRemainOnChanReq is NULL") );) + return nSirStatus; + } + + /* The link is not suspended */ + if (status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog( pMac, LOGE, FL(" Suspend link Failure ") );) + goto error; + } + + + if((psessionEntry = peFindSessionByBssid( + pMac,pMac->lim.gpLimRemainOnChanReq->selfMacAddr, &sessionId)) != NULL) + { + goto change_channel; + } + else /* Session Entry does not exist for given BSSId */ + { + /* Try to Create a new session */ + if(eSIR_SUCCESS != limCreateSessionForRemainOnChn(pMac, &psessionEntry)) + { + limLog(pMac, LOGE, FL("Session Can not be created ")); + /* send remain on chn failure */ + goto error; + } + } + +change_channel: + /* change channel to the requested by RemainOn Chn*/ + limChangeChannelWithCallback(pMac, + pMac->lim.gpLimRemainOnChanReq->chnNum, + limRemainOnChnlSetLinkStat, NULL, psessionEntry); + return eSIR_SUCCESS; + +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + return eSIR_FAILURE; +} + +void limRemainOnChnlSuspendLinkHdlr(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data) +{ + limRemainOnChnlChangeChnReq(pMac, status, data); + return; +} + +/*------------------------------------------------------------------ + * + * Set the LINK state to LISTEN to allow only PROBE_REQ and Action frames + * + *------------------------------------------------------------------*/ +void limRemainOnChnlSetLinkStat(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if (status != eHAL_STATUS_SUCCESS) + { + limLog( pMac, LOGE, FL("Change channel not successful")); + goto error; + } + + // Start timer here to come back to operating channel. + pMac->lim.p2pRemOnChanTimeStamp = vos_timer_get_system_time(); + pMac->lim.gTotalScanDuration = MsgRemainonChannel->duration; + if (pMac->lim.gDebugP2pRemainOnChannel) + { + pMac->lim.remOnChnSeqNum++; + if( eHAL_STATUS_SUCCESS == limPrepareAndSendStartRemainOnChannelMsg( + pMac, MsgRemainonChannel, + REMAIN_ON_CHANNEL_FIRST_MARKER_FRAME) ) + { + limLog( pMac, LOGE, + "%s: Successfully sent 1st marker frame with seq num = %d" + " on start ROC", __func__, pMac->lim.remOnChnSeqNum); + } + } + + if ((limSetLinkState(pMac, MsgRemainonChannel->isProbeRequestAllowed? + eSIR_LINK_LISTEN_STATE:eSIR_LINK_SEND_ACTION_STATE,nullBssid, + pMac->lim.gSelfMacAddr, limSetLinkStateP2PCallback, + NULL)) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + goto error; + } + + return; +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + return; +} + +/*------------------------------------------------------------------ + * + * lim Insert NOA timer timeout callback - when timer fires, deactivate it and send + * scan rsp to csr/hdd + * + *------------------------------------------------------------------*/ +void limProcessInsertSingleShotNOATimeout(tpAniSirGlobal pMac) +{ + /* timeout means start NOA did not arrive; we need to deactivate and change the timer for + * future activations + */ + limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER); + + /* Even if insert NOA timedout, go ahead and process/send stored SME request */ + limProcessRegdDefdSmeReqAfterNOAStart(pMac); + + return; +} + +/*----------------------------------------------------------------- + * lim Insert Timer callback function to check active DFS channels + * and convert them to passive channels if there was no + * beacon/proberesp for MAX_TIME_TO_BE_ACTIVE_CHANNEL time + *------------------------------------------------------------------*/ +void limConvertActiveChannelToPassiveChannel(tpAniSirGlobal pMac ) +{ + v_TIME_t currentTime; + v_TIME_t lastTime = 0; + v_TIME_t timeDiff; + tANI_U8 i; + currentTime = vos_timer_get_system_time(); + for (i = 1; i < SIR_MAX_24G_5G_CHANNEL_RANGE ; i++) + { + if ((pMac->lim.dfschannelList.timeStamp[i]) != 0) + { + lastTime = pMac->lim.dfschannelList.timeStamp[i]; + if (currentTime >= lastTime) + { + timeDiff = (currentTime - lastTime); + } + else + { + timeDiff = (0xFFFFFFFF - lastTime) + currentTime; + } + + if (timeDiff >= MAX_TIME_TO_BE_ACTIVE_CHANNEL) + { + limCovertChannelScanType( pMac, i,FALSE); + pMac->lim.dfschannelList.timeStamp[i] = 0; + } + } + } + /* lastTime is zero if there is no DFS active channels in the list. + * If this is non zero then we have active DFS channels so restart the timer. + */ + if (lastTime != 0) + { + if (tx_timer_activate( + &pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) + != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("Could not activate Active to Passive Channel timer")); + } + } + + return; + +} + +/*------------------------------------------------------------------ + * + * limSetLinkState callback function. + * + *------------------------------------------------------------------*/ +void limSetlinkStateCallback(tpAniSirGlobal pMac, void *callbackArg) +{ + if(pMac->lim.gDebugP2pRemainOnChannel) + { + if (eHAL_STATUS_SUCCESS == limPrepareAndSendCancelRemainOnChannelMsg( + pMac, + REMAIN_ON_CHANNEL_SECOND_MARKER_FRAME)) + { + limLog( pMac, LOGE, + "%s: Successfully sent 2nd marker frame with seq num=%d" + " on cancel ROC", __func__, pMac->lim.remOnChnSeqNum); + } + } + + return; + +} + +/*------------------------------------------------------------------ + * + * limchannelchange callback, on success channel change, set the + * link_state to LISTEN + * + *------------------------------------------------------------------*/ + +void limProcessRemainOnChnTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + tANI_U8 sessionId; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + + if (NULL == pMac->lim.gpLimRemainOnChanReq) + { + limLog( pMac, LOGE, "No Remain on channel pending"); + return; + } + + if(pMac->lim.gDebugP2pRemainOnChannel) + { + if (eHAL_STATUS_SUCCESS == limPrepareAndSendCancelRemainOnChannelMsg( + pMac, + REMAIN_ON_CHANNEL_FIRST_MARKER_FRAME)) + { + limLog( pMac, LOGE, + "%s: Successfully sent 1st marker frame with seqnum = %d" + " on cancel ROC", __func__, pMac->lim.remOnChnSeqNum); + } + } + + /* get the previous valid LINK state */ + if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + pMac->lim.gSelfMacAddr, limSetlinkStateCallback, NULL) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + return; + } + + if (pMac->lim.gLimMlmState != eLIM_MLM_P2P_LISTEN_STATE ) + { + limRemainOnChnRsp(pMac,eHAL_STATUS_SUCCESS, NULL); + } + else + { + /* get the session */ + if((psessionEntry = peFindSessionByBssid( + pMac,pMac->lim.gpLimRemainOnChanReq->selfMacAddr, &sessionId)) == NULL) + { + limLog(pMac, LOGE, + FL("Session Does not exist for given sessionID")); + goto error; + } + + limExitRemainOnChannel(pMac, eHAL_STATUS_SUCCESS, NULL, psessionEntry); + return; +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + } + return; +} + + +/*------------------------------------------------------------------ + * + * limchannelchange callback, on success channel change, set the link_state + * to LISTEN + * + *------------------------------------------------------------------*/ + +void limExitRemainOnChannel(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + + if (status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog( pMac, LOGE, "Remain on Channel Failed");) + goto error; + } + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limResumeLink(pMac, limRemainOnChnRsp, NULL); + return; +error: + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + return; +} + +/*------------------------------------------------------------------ + * + * Send remain on channel respone: Success/ Failure + * + *------------------------------------------------------------------*/ +void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data) +{ + tpPESession psessionEntry; + tANI_U8 sessionId; + tSirRemainOnChnReq *MsgRemainonChannel = pMac->lim.gpLimRemainOnChanReq; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + tANI_U32 txStatus = 0; + tSirTxBdStatus txBdStatus = {0}; + + if ( NULL == MsgRemainonChannel ) + { + PELOGE(limLog( pMac, LOGP, + "%s: No Pointer for Remain on Channel Req", __func__);) + return; + } + + limLog( pMac, LOG1, "Remain on channel rsp with status %d", status); + + //Incase of the Remain on Channel Failure Case + //Cleanup Everything + if(eHAL_STATUS_FAILURE == status) + { + //Set the Link State to Idle + /* get the previous valid LINK state */ + if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + pMac->lim.gSelfMacAddr, NULL, NULL) != eSIR_SUCCESS) + { + limLog( pMac, LOGE, "Unable to change link state"); + } + + pMac->lim.gLimSystemInScanLearnMode = 0; + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + } + + /* delete the session */ + if((psessionEntry = peFindSessionByBssid(pMac, + MsgRemainonChannel->selfMacAddr,&sessionId)) != NULL) + { + if ( eLIM_P2P_DEVICE_ROLE == psessionEntry->limSystemRole ) + { + peDeleteSession( pMac, psessionEntry); + } + } + + /* Post the meessage to Sme */ + limSendSmeRsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP, status, + MsgRemainonChannel->sessionId, 0); + + vos_mem_free(pMac->lim.gpLimRemainOnChanReq); + pMac->lim.gpLimRemainOnChanReq = NULL; + + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + + /* If remain on channel timer expired and action frame is pending then + * indicaiton confirmation with status failure */ + if (pMac->lim.mgmtFrameSessionId != 0xff) + { + limLog(pMac, LOGE, + FL("Remain on channel expired, Action frame status failure")); + + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + limP2PActionCnf(pMac, &txBdStatus); + else + limP2PActionCnf(pMac, &txStatus); + } + + return; +} + +/*------------------------------------------------------------------ + * + * Indicate the Mgmt Frame received to SME to HDD callback + * handle Probe_req/Action frame currently + * + *------------------------------------------------------------------*/ +void limSendSmeMgmtFrameInd( + tpAniSirGlobal pMac, tANI_U16 sessionId, + tANI_U8 *pRxPacketInfo, tpPESession psessionEntry, + tANI_S8 rxRssi) +{ + tpSirSmeMgmtFrameInd pSirSmeMgmtFrame = NULL; + tANI_U16 length; + tANI_U8 frameType; + tpSirMacMgmtHdr frame; + tANI_U32 frameLen; + tANI_U8 rfBand = 0; + tANI_U32 rxChannel; + + frame = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) + sizeof(tSirMacMgmtHdr); + length = sizeof(tSirSmeMgmtFrameInd) + frameLen; + frameType = frame->fc.subType; + rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); + rxChannel = WDA_GET_RX_CH( pRxPacketInfo ); + + pSirSmeMgmtFrame = vos_mem_malloc(length); + if (NULL == pSirSmeMgmtFrame) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for eWNI_SME_LISTEN_RSP")); + return; + } + vos_mem_set((void*)pSirSmeMgmtFrame, length, 0); + + pSirSmeMgmtFrame->frameLen = frameLen; + pSirSmeMgmtFrame->sessionId = sessionId; + pSirSmeMgmtFrame->frameType = frameType; + pSirSmeMgmtFrame->rxRssi = rxRssi; + + if (( IS_5G_BAND(rfBand))) + { + rxChannel = limUnmapChannel(rxChannel); + limLog(pMac, LOG1, + FL("rxChannel after unmapping is %d"), rxChannel); + if ( !rxChannel ) + { + tpPESession pTempSessionEntry = limIsApSessionActive(pMac); + if(pMac->lim.gpLimRemainOnChanReq != NULL) + { + rxChannel = pMac->lim.gpLimRemainOnChanReq->chnNum; + limLog(pMac, LOG1, + FL("ROC timer is running." + " Assign ROC channel to rxChannel i.e., %d"), rxChannel); + } + else if ( (pTempSessionEntry != NULL) && + (SIR_BAND_5_GHZ != + limGetRFBand(pTempSessionEntry->currentOperChannel)) ) + limLog(pMac, LOGW, + FL("No active p2p GO in 5GHz" + " but recvd Action frame in 5GHz")); + } + } + + /* + * Work around to address LIM sending wrong channel to HDD for p2p action + * frames(In case of auto GO) recieved on 5GHz channel. + * As RXP has only 4bits to store the channel, we need some mechanism to + * to distinguish between 2.4Ghz/5GHz channel. if gLimRemainOnChannelTImer + * is not running and if we get a frame then pass the Go session + * operating channel to HDD. Some vendors create separate p2p interface + * after group formation. In that case LIM session entry will be NULL for + * p2p device address. So search for p2p go session and pass it's + * operating channel. + * Need to revisit this path in case of GO+CLIENT concurrency. + */ + if (NULL == pMac->lim.gpLimRemainOnChanReq) + { + tpPESession pTempSessionEntry = psessionEntry; + if( ( (NULL != pTempSessionEntry) || + (pTempSessionEntry = limIsApSessionActive(pMac)) ) && + (SIR_BAND_5_GHZ == limGetRFBand(pTempSessionEntry->currentOperChannel)) ) + { + rxChannel = pTempSessionEntry->currentOperChannel; + limLog(pMac, LOG1, + FL("Invalid rxChannel." + " Assign GO session op channel to rxChannel i.e., %d"), rxChannel); + } + } + + pSirSmeMgmtFrame->rxChan = rxChannel; + + vos_mem_zero(pSirSmeMgmtFrame->frameBuf, frameLen); + vos_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen); + + if (pMac->mgmt_frame_ind_cb) + pMac->mgmt_frame_ind_cb(pSirSmeMgmtFrame); + else + { + limLog(pMac, LOGW, + FL("Management indication callback not registered!!")); + } + vos_mem_free(pSirSmeMgmtFrame); + return; +} /*** end limSendSmeListenRsp() ***/ + + +eHalStatus limP2PActionCnf(tpAniSirGlobal pMac, void *pData) +{ + tANI_U32 txCompleteSuccess; + tpSirTxBdStatus pTxBdStatus; + + if (!pData) + { + limLog(pMac, LOG1, + FL(" pData is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + pTxBdStatus = (tpSirTxBdStatus) pData; + txCompleteSuccess = pTxBdStatus->txCompleteStatus; + + limLog(pMac, LOG1, + FL("txCompleteSuccess %d, Token %u, Session Id %d"), + txCompleteSuccess, pTxBdStatus->txBdToken, + pMac->lim.mgmtFrameSessionId); + } + else + { + txCompleteSuccess = *((tANI_U32*) pData); + + limLog(pMac, LOG1, + FL(" %s txCompleteSuccess %d, Session Id %d"), + __func__, txCompleteSuccess, pMac->lim.mgmtFrameSessionId); + } + + if (pMac->lim.mgmtFrameSessionId != 0xff) + { + /* The session entry might be invalid(0xff) action confirmation received after + * remain on channel timer expired */ + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + (txCompleteSuccess ? eSIR_SME_SUCCESS : eSIR_SME_SEND_ACTION_FAIL), + pMac->lim.mgmtFrameSessionId, 0); + pMac->lim.mgmtFrameSessionId = 0xff; + } + + return eHAL_STATUS_SUCCESS; +} + + +void limSetHtCaps(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 *pIeStartPtr,tANI_U32 nBytes) +{ + v_U8_t *pIe=NULL; + tDot11fIEHTCaps dot11HtCap; + + PopulateDot11fHTCaps(pMac, psessionEntry, &dot11HtCap); + + pIe = limGetIEPtr(pMac,pIeStartPtr, nBytes, + DOT11F_EID_HTCAPS,ONE_BYTE); + limLog( pMac, LOG2, FL("pIe %p dot11HtCap.supportedMCSSet[0]=0x%x"), + pIe, dot11HtCap.supportedMCSSet[0]); + if(pIe) + { + tHtCaps *pHtcap = (tHtCaps *)&pIe[2]; //convert from unpacked to packed structure + pHtcap->advCodingCap = dot11HtCap.advCodingCap; + pHtcap->supportedChannelWidthSet = dot11HtCap.supportedChannelWidthSet; + pHtcap->mimoPowerSave = dot11HtCap.mimoPowerSave; + pHtcap->greenField = dot11HtCap.greenField; + pHtcap->shortGI20MHz = dot11HtCap.shortGI20MHz; + pHtcap->shortGI40MHz = dot11HtCap.shortGI40MHz; + pHtcap->txSTBC = dot11HtCap.txSTBC; + pHtcap->rxSTBC = dot11HtCap.rxSTBC; + pHtcap->delayedBA = dot11HtCap.delayedBA ; + pHtcap->maximalAMSDUsize = dot11HtCap.maximalAMSDUsize; + pHtcap->dsssCckMode40MHz = dot11HtCap.dsssCckMode40MHz; + pHtcap->psmp = dot11HtCap.psmp; + pHtcap->stbcControlFrame = dot11HtCap.stbcControlFrame; + pHtcap->lsigTXOPProtection = dot11HtCap.lsigTXOPProtection; + pHtcap->maxRxAMPDUFactor = dot11HtCap.maxRxAMPDUFactor; + pHtcap->mpduDensity = dot11HtCap.mpduDensity; + vos_mem_copy((void *)pHtcap->supportedMCSSet, + (void *)(dot11HtCap.supportedMCSSet), + sizeof(pHtcap->supportedMCSSet)); + pHtcap->pco = dot11HtCap.pco; + pHtcap->transitionTime = dot11HtCap.transitionTime; + pHtcap->mcsFeedback = dot11HtCap.mcsFeedback; + pHtcap->txBF = dot11HtCap.txBF; + pHtcap->rxStaggeredSounding = dot11HtCap.rxStaggeredSounding; + pHtcap->txStaggeredSounding = dot11HtCap.txStaggeredSounding; + pHtcap->rxZLF = dot11HtCap.rxZLF; + pHtcap->txZLF = dot11HtCap.txZLF; + pHtcap->implicitTxBF = dot11HtCap.implicitTxBF; + pHtcap->calibration = dot11HtCap.calibration; + pHtcap->explicitCSITxBF = dot11HtCap.explicitCSITxBF; + pHtcap->explicitUncompressedSteeringMatrix = + dot11HtCap.explicitUncompressedSteeringMatrix; + pHtcap->explicitBFCSIFeedback = dot11HtCap.explicitBFCSIFeedback; + pHtcap->explicitUncompressedSteeringMatrixFeedback = + dot11HtCap.explicitUncompressedSteeringMatrixFeedback; + pHtcap->explicitCompressedSteeringMatrixFeedback = + dot11HtCap.explicitCompressedSteeringMatrixFeedback; + pHtcap->csiNumBFAntennae = dot11HtCap.csiNumBFAntennae; + pHtcap->uncompressedSteeringMatrixBFAntennae = + dot11HtCap.uncompressedSteeringMatrixBFAntennae; + pHtcap->compressedSteeringMatrixBFAntennae = + dot11HtCap.compressedSteeringMatrixBFAntennae; + pHtcap->antennaSelection = dot11HtCap.antennaSelection; + pHtcap->explicitCSIFeedbackTx = dot11HtCap.explicitCSIFeedbackTx; + pHtcap->antennaIndicesFeedbackTx = dot11HtCap.antennaIndicesFeedbackTx; + pHtcap->explicitCSIFeedback = dot11HtCap.explicitCSIFeedback; + pHtcap->antennaIndicesFeedback = dot11HtCap.antennaIndicesFeedback; + pHtcap->rxAS = dot11HtCap.rxAS; + pHtcap->txSoundingPPDUs = dot11HtCap.txSoundingPPDUs; + } +} + + +void limSendP2PActionFrame(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tSirMbMsgP2p *pMbMsg = (tSirMbMsgP2p *)pMsg->bodyptr; + tANI_U32 nBytes; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + tpSirMacFrameCtl pFc = (tpSirMacFrameCtl ) pMbMsg->data; + tANI_U8 noaLen = 0; + tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + (2*SIR_P2P_IE_HEADER_LEN)]; + tANI_U8 origLen = 0; + tANI_U8 sessionId = 0; + v_U8_t *pP2PIe = NULL; + tpPESession psessionEntry; + v_U8_t *pPresenceRspNoaAttr = NULL; + v_U8_t *pNewP2PIe = NULL; + v_U16_t remainLen = 0; +#ifdef WLAN_FEATURE_11W + tpSirMacMgmtHdr pMacHdr; + tpSirMacActionFrameHdr pActionHdr; +#endif + nBytes = pMbMsg->msgLen - sizeof(tSirMbMsg); + + limLog( pMac, LOG1, FL("sending pFc->type=%d pFc->subType=%d"), + pFc->type, pFc->subType); + + psessionEntry = peFindSessionByBssid(pMac, + (tANI_U8*)pMbMsg->data + BSSID_OFFSET, &sessionId); + + /* Check for session corresponding to ADDR2 As Supplicant is filling + ADDR2 with BSSID */ + if( NULL == psessionEntry ) + { + psessionEntry = peFindSessionByBssid(pMac, + (tANI_U8*)pMbMsg->data + ADDR2_OFFSET, &sessionId); + } + + if( NULL == psessionEntry ) + { + tANI_U8 isSessionActive = 0; + tANI_U8 i; + + /* If we are not able to find psessionEntry entry, then try to find + active session, if found any active sessions then send the + action frame, If no active sessions found then drop the frame */ + for (i =0; i < pMac->lim.maxBssId;i++) + { + psessionEntry = peFindSessionBySessionId(pMac,i); + if ( NULL != psessionEntry) + { + isSessionActive = 1; + break; + } + } + if( !isSessionActive ) + { + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + return; + } + } + + if ((SIR_MAC_MGMT_FRAME == pFc->type)&& + ((SIR_MAC_MGMT_PROBE_RSP == pFc->subType)|| + (SIR_MAC_MGMT_ACTION == pFc->subType))) + { + //if this is a probe RSP being sent from wpa_supplicant + if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) + { + //get proper offset for Probe RSP + pP2PIe = limGetP2pIEPtr(pMac, + (tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET, + nBytes - PROBE_RSP_IE_OFFSET); + while ((NULL != pP2PIe) && (SIR_MAC_MAX_IE_LENGTH == pP2PIe[1])) + { + remainLen = nBytes - (pP2PIe - (tANI_U8*)pMbMsg->data); + if (remainLen > 2) + { + pNewP2PIe = limGetP2pIEPtr(pMac, + pP2PIe+SIR_MAC_MAX_IE_LENGTH + 2, remainLen); + } + if (pNewP2PIe) + { + pP2PIe = pNewP2PIe; + pNewP2PIe = NULL; + } + else + { + break; + } + } //end of while + } + else + { + if (SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY == + *((v_U8_t *)pMbMsg->data+ACTION_OFFSET)) + { + tpSirMacP2PActionFrameHdr pActionHdr = + (tpSirMacP2PActionFrameHdr)((v_U8_t *)pMbMsg->data + + ACTION_OFFSET); + if (vos_mem_compare( pActionHdr->Oui, + SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE ) && + (SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP == + pActionHdr->OuiSubType)) + { //In case of Presence RSP response + pP2PIe = limGetP2pIEPtr(pMac, + (v_U8_t *)pMbMsg->data + ACTION_OFFSET + + sizeof(tSirMacP2PActionFrameHdr), + (nBytes - ACTION_OFFSET - + sizeof(tSirMacP2PActionFrameHdr))); + if( NULL != pP2PIe ) + { + //extract the presence of NoA attribute inside P2P IE + pPresenceRspNoaAttr = + limGetIEPtr(pMac,pP2PIe + SIR_P2P_IE_HEADER_LEN, + pP2PIe[1], SIR_P2P_NOA_ATTR,TWO_BYTE); + } + } + } + } + + if (pP2PIe != NULL) + { + //get NoA attribute stream P2P IE + noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); + //need to append NoA attribute in P2P IE + if (noaLen > 0) + { + origLen = pP2PIe[1]; + //if Presence Rsp has NoAttr + if (pPresenceRspNoaAttr) + { + v_U16_t noaAttrLen = pPresenceRspNoaAttr[1] | + (pPresenceRspNoaAttr[2]<<8); + /*One byte for attribute, 2bytes for length*/ + origLen -= (noaAttrLen + 1 + 2); + //remove those bytes to copy + nBytes -= (noaAttrLen + 1 + 2); + //remove NoA from original Len + pP2PIe[1] = origLen; + } + if ((pP2PIe[1] + (tANI_U16)noaLen)> SIR_MAC_MAX_IE_LENGTH) + { + //Form the new NoA Byte array in multiple P2P IEs + noaLen = limGetNoaAttrStreamInMultP2pIes(pMac, noaStream, + noaLen,((pP2PIe[1] + (tANI_U16)noaLen)- + SIR_MAC_MAX_IE_LENGTH)); + pP2PIe[1] = SIR_MAC_MAX_IE_LENGTH; + } + else + { + pP2PIe[1] += noaLen; //increment the length of P2P IE + } + nBytes += noaLen; + limLog( pMac, LOGE, + FL("noaLen=%d origLen=%d pP2PIe=%p" + " nBytes=%d nBytesToCopy=%zu"), + noaLen,origLen, pP2PIe, nBytes, + ((pP2PIe + origLen + 2) - (v_U8_t *)pMbMsg->data)); + } + } + + if (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) + { + limSetHtCaps( pMac, psessionEntry, (tANI_U8*)pMbMsg->data + PROBE_RSP_IE_OFFSET, + nBytes - PROBE_RSP_IE_OFFSET); + } + if ((SIR_MAC_MGMT_ACTION == pFc->subType) && + (0 != pMbMsg->wait)) + { + if (pMac->lim.gpLimRemainOnChanReq == NULL) + { + limLog( pMac, LOGE, + FL("Failed to Send Action frame")); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + eHAL_STATUS_FAILURE, pMbMsg->sessionId, 0); + return; + } + } + } + + + // Ok-- try to allocate some memory: + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16)nBytes, ( void** ) &pFrame, (void**) &pPacket); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to allocate %d bytes for a Probe" + " Request."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set(pFrame, nBytes, 0); + + if ((noaLen > 0) && (noaLen<(SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN))) + { + // Add 2 bytes for length and Arribute field + v_U32_t nBytesToCopy = ((pP2PIe + origLen + 2 ) - + (v_U8_t *)pMbMsg->data); + vos_mem_copy(pFrame, pMbMsg->data, nBytesToCopy); + vos_mem_copy((pFrame + nBytesToCopy), noaStream, noaLen); + vos_mem_copy((pFrame + nBytesToCopy + noaLen), + pMbMsg->data + nBytesToCopy, nBytes - nBytesToCopy - noaLen); + + } + else + { + vos_mem_copy(pFrame, pMbMsg->data, nBytes); + } + +#ifdef WLAN_FEATURE_11W + pActionHdr = (tpSirMacActionFrameHdr) (pFrame + sizeof(tSirMacMgmtHdr)); + pMacHdr = (tpSirMacMgmtHdr)pFrame; + + /* + * Setting Protected bit only for Robust Action Frames + * This has to be based on the current Connection with the station + * limSetProtectedBit API will set the protected bit if connection is PMF + */ + if ((SIR_MAC_MGMT_ACTION == pFc->subType) && + psessionEntry->limRmfEnabled && (!limIsGroupAddr(pMacHdr->da)) && + lim_is_robust_mgmt_action_frame(pActionHdr->category)) { + /* All psession checks are already done at start */ + limSetProtectedBit(pMac, psessionEntry, pMacHdr->da, pMacHdr); + + } +#endif + + /* Use BD rate 2 for all P2P related frames. As these frames need to go + * at OFDM rates. And BD rate2 we configured at 6Mbps. + */ + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + + if (SIR_MAC_MGMT_ACTION == pFc->subType) + { + limLog( pMac, LOG1, FL("Sending Action Frame over WQ5")); + txFlag |= HAL_USE_FW_IN_TX_PATH; + } + + if ( (SIR_MAC_MGMT_PROBE_RSP == pFc->subType) || + (pMbMsg->noack) + ) + { + halstatus = halTxFrame( pMac, pPacket, (tANI_U16)nBytes, + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7,/*SMAC_SWBD_TX_TID_MGMT_HIGH */ limTxComplete, pFrame, + txFlag ); + + if (!pMbMsg->noack) + { + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, + halstatus, pMbMsg->sessionId, 0); + } + pMac->lim.mgmtFrameSessionId = 0xff; + } + else + { + pMac->lim.mgmtFrameSessionId = 0xff; + halstatus = halTxFrameWithTxComplete( pMac, pPacket, (tANI_U16)nBytes, + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7,/*SMAC_SWBD_TX_TID_MGMT_HIGH */ limTxComplete, pFrame, + limP2PActionCnf, txFlag, pMac->lim.txBdToken++ ); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("could not send action frame!" )); + limSendSmeRsp(pMac, eWNI_SME_ACTION_FRAME_SEND_CNF, halstatus, + pMbMsg->sessionId, 0); + pMac->lim.mgmtFrameSessionId = 0xff; + } + else + { + pMac->lim.mgmtFrameSessionId = pMbMsg->sessionId; + limLog( pMac, LOG2, FL("lim.actionFrameSessionId = %u" ), + pMac->lim.mgmtFrameSessionId); + + } + } + + return; +} + + +void limAbortRemainOnChan(tpAniSirGlobal pMac) +{ + limProcessRemainOnChnTimeout(pMac); + limLog( pMac, LOG1, FL("Abort ROC !!!" )); + return; +} + +/* Power Save Related Functions */ +tSirRetStatus __limProcessSmeNoAUpdate(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpP2pPsConfig pNoA; + tpP2pPsParams pMsgNoA; + tSirMsgQ msg; + + pNoA = (tpP2pPsConfig) pMsgBuf; + + pMsgNoA = vos_mem_malloc(sizeof( tP2pPsConfig )); + if (NULL == pMsgNoA) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during NoA Update" )); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set((tANI_U8 *)pMsgNoA, sizeof(tP2pPsConfig), 0); + pMsgNoA->opp_ps = pNoA->opp_ps; + pMsgNoA->ctWindow = pNoA->ctWindow; + pMsgNoA->duration = pNoA->duration; + pMsgNoA->interval = pNoA->interval; + pMsgNoA->count = pNoA->count; + pMsgNoA->single_noa_duration = pNoA->single_noa_duration; + pMsgNoA->psSelection = pNoA->psSelection; + + msg.type = WDA_SET_P2P_GO_NOA_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgNoA; + msg.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("halPostMsgApi failed")); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end __limProcessSmeGoNegReq() ***/ + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c new file mode 100644 index 000000000000..387e32eac8ea --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessActionFrame.c @@ -0,0 +1,2786 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file limProcessActionFrame.cc contains the code + * for processing Action Frame. + * Author: Michael Lui + * Date: 05/23/03 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "wniCfg.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSendSmeRspMessages.h" +#include "parserApi.h" +#include "limAdmitControl.h" +#include "wmmApsd.h" +#include "limSendMessages.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#include "limSessionUtils.h" +#ifdef WLAN_FEATURE_RMC +#include "limRMC.h" +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif +#include "wlan_qct_wda.h" + +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + +#define BA_DEFAULT_TX_BUFFER_SIZE 64 + +typedef enum +{ + LIM_ADDBA_RSP = 0, + LIM_ADDBA_REQ = 1 +}tLimAddBaValidationReqType; + +/* Note: The test passes if the STAUT stops sending any frames, and no further + frames are transmitted on this channel by the station when the AP has sent + the last 6 beacons, with the channel switch information elements as seen + with the sniffer.*/ +#define SIR_CHANSW_TX_STOP_MAX_COUNT 6 +/**----------------------------------------------------------------- +\fn limStopTxAndSwitchChannel +\brief Stops the transmission if channel switch mode is silent and + starts the channel switch timer. + +\param pMac +\return NONE +-----------------------------------------------------------------*/ +void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 isFullPowerRequested = 0; + tpPESession psessionEntry; + + psessionEntry = peFindSessionBySessionId( pMac , sessionId ); + + if( NULL == psessionEntry ) + { + limLog(pMac, LOGE, FL("Session %d not active\n "), sessionId); + return; + } + + if(pMac->ft.ftPEContext.pFTPreAuthReq) + { + limLog(pMac, LOGE, + FL("Avoid Switch Channel req during pre auth")); + return; + } + + limLog(pMac, LOG1, FL("Channel switch Mode == %d"), + psessionEntry->gLimChannelSwitch.switchMode); + + if (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT || + psessionEntry->gLimChannelSwitch.switchCount <= SIR_CHANSW_TX_STOP_MAX_COUNT) + { + /* Freeze the transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX); + + /*Request for Full power only if the device is in powersave*/ + if(!limIsSystemInActiveState(pMac)) + { + /* Request Full Power */ + limSendSmePreChannelSwitchInd(pMac); + isFullPowerRequested = 1; + } + } + else + { + /* Resume the transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + } + + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId = sessionId; + /* change the channel immediatly only if the channel switch count is 0 and the + * device is not in powersave + * If the device is in powersave channel switch should happen only after the + * device comes out of the powersave */ + if (psessionEntry->gLimChannelSwitch.switchCount == 0) + { + if(limIsSystemInActiveState(pMac)) + { + limProcessChannelSwitchTimeout(pMac); + } + else if(!isFullPowerRequested) + { + /* If the Full power is already not requested + * Request Full Power so the channel switch happens + * after device comes to full power */ + limSendSmePreChannelSwitchInd(pMac); + } + return; + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_CHANNEL_SWITCH_TIMER)); + + + if (tx_timer_activate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_activate failed")); + } + return; +} + +/**------------------------------------------------------------ +\fn limStartChannelSwitch +\brief Switches the channel if switch count == 0, otherwise + starts the timer for channel switch and stops BG scan + and heartbeat timer tempororily. + +\param pMac +\param psessionEntry +\return NONE +------------------------------------------------------------*/ +tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + limLog(pMac, LOG1, FL(" ENTER")); + +#ifdef WLAN_FEATURE_LFR_MBB + if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) + { + limLog(pMac, LOGE, + FL("Ignore channel switch as LFR MBB in progress")); + return eSIR_SUCCESS; + } +#endif + + /*If channel switch is already running and it is on a different session, just return*/ + /*This need to be removed for MCC */ + if( limIsChanSwitchRunning (pMac) && + psessionEntry->gLimSpecMgmt.dot11hChanSwState != eLIM_11H_CHANSW_RUNNING ) + { + limLog(pMac, LOGW, FL("Ignoring channel switch on session %d"), psessionEntry->peSessionId); + return eSIR_SUCCESS; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_CHANNEL_SWITCH_ANOUNCEMENT, + psessionEntry, eSIR_SUCCESS, LIM_SWITCH_CHANNEL_CSA); +#endif + + psessionEntry->channelChangeCSA = LIM_SWITCH_CHANNEL_CSA; + /* Deactivate and change reconfigure the timeout value */ + //limDeactivateAndChangeTimer(pMac, eLIM_CHANNEL_SWITCH_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed!")); + return eSIR_FAILURE; + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer, + psessionEntry->gLimChannelSwitch.switchTimeoutValue, + 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_change failed ")); + return eSIR_FAILURE; + } + + /* Follow the channel switch, forget about the previous quiet. */ + //If quiet is running, chance is there to resume tx on its timeout. + //so stop timer for a safer side. + if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed")); + return eSIR_FAILURE; + } + } + else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed")); + return eSIR_FAILURE; + } + } + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + + /* Prepare for 11h channel switch */ + limPrepareFor11hChannelSwitch(pMac, psessionEntry); + + /** Dont add any more statements here as we posted finish scan request + * to HAL, wait till we get the response + */ + return eSIR_SUCCESS; +} + + +/** + * __limProcessChannelSwitchActionFrame + * + *FUNCTION: + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +static void + +__limProcessChannelSwitchActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tDot11fChannelSwitch *pChannelSwitchFrame; + tANI_U16 beaconPeriod; + tANI_U32 val; + tANI_U32 frameLen; + tANI_U32 nStatus; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + limLog(pMac, LOG1, FL("Received Channel switch action frame")); + if (!psessionEntry->lim11hEnable) + return; + + pChannelSwitchFrame = vos_mem_malloc(sizeof(*pChannelSwitchFrame)); + if (NULL == pChannelSwitchFrame) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed")); + return; + } + + /* Unpack channel switch frame */ + nStatus = dot11fUnpackChannelSwitch(pMac, pBody, frameLen, pChannelSwitchFrame); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + vos_mem_free(pChannelSwitchFrame); + return; + } + else if(DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + } + + if (vos_mem_compare((tANI_U8 *) &psessionEntry->bssId, + (tANI_U8 *) &pHdr->sa, + sizeof(tSirMacAddr))) + { + #if 0 + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &val) != eSIR_SUCCESS) + { + vos_mem_free(pChannelSwitchFrame); + limLog(pMac, LOGP, FL("could not retrieve Beacon interval")); + return; + } + #endif// TO SUPPORT BT-AMP + + /* copy the beacon interval from psessionEntry*/ + val = psessionEntry->beaconParams.beaconInterval; + + beaconPeriod = (tANI_U16) val; + + psessionEntry->gLimChannelSwitch.primaryChannel = pChannelSwitchFrame->ChanSwitchAnn.newChannel; + psessionEntry->gLimChannelSwitch.switchCount = pChannelSwitchFrame->ChanSwitchAnn.switchCount; + psessionEntry->gLimChannelSwitch.switchTimeoutValue = SYS_MS_TO_TICKS(beaconPeriod) * + psessionEntry->gLimChannelSwitch.switchCount; + psessionEntry->gLimChannelSwitch.switchMode = pChannelSwitchFrame->ChanSwitchAnn.switchMode; +#ifdef WLAN_FEATURE_11AC + if ( pChannelSwitchFrame->WiderBWChanSwitchAnn.present && psessionEntry->vhtCapability) + { + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = pChannelSwitchFrame->WiderBWChanSwitchAnn.newChanWidth; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = pChannelSwitchFrame->WiderBWChanSwitchAnn.newCenterChanFreq0; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = pChannelSwitchFrame->WiderBWChanSwitchAnn.newCenterChanFreq1; + } +#endif + + limLog(pMac, LOG1, FL("Rcv Chnl Swtch Frame: Timeout in %d ticks"), + psessionEntry->gLimChannelSwitch.switchTimeoutValue); + + /* Only primary channel switch element is present */ + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + psessionEntry->gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED; + + if (psessionEntry->htSupportedChannelWidthSet) + { + if ((pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset; + } +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability && pChannelSwitchFrame->WiderBWChanSwitchAnn.present) + { + if (pChannelSwitchFrame->WiderBWChanSwitchAnn.newChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + if (pChannelSwitchFrame->ExtChanSwitchAnn.present && ((pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY))) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = + limGet11ACPhyCBState(pMac, + psessionEntry->gLimChannelSwitch.primaryChannel, + pChannelSwitchFrame->ExtChanSwitchAnn.secondaryChannelOffset, + pChannelSwitchFrame->WiderBWChanSwitchAnn.newCenterChanFreq0, + psessionEntry); + } + } + } +#endif + } + + } + else + { + limLog(pMac, LOG1, FL("LIM: Received action frame not from our BSS, dropping...")); + } + + if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry)) + { + limLog(pMac, LOG1, FL("Could not start channel switch")); + } + + vos_mem_free(pChannelSwitchFrame); + return; +} /*** end limProcessChannelSwitchActionFrame() ***/ + + +#ifdef WLAN_FEATURE_11AC +static void +__limProcessOperatingModeActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tDot11fOperatingMode *pOperatingModeframe; + tANI_U32 frameLen; + tANI_U32 nStatus; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U8 operMode; + tANI_U32 channelBondingMode; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + limLog(pMac, LOG1, FL("Received Operating Mode action frame")); + + if( RF_CHAN_14 >= psessionEntry->currentOperChannel ) + { + channelBondingMode = pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + channelBondingMode = pMac->roam.configParam.channelBondingMode5GHz; + } + + /* Do not update the channel bonding mode if channel bonding + * mode is disabled in INI. + */ + if(WNI_CFG_CHANNEL_BONDING_MODE_DISABLE == channelBondingMode) + { + limLog(pMac, LOGW, + FL("channel bonding disabled")); + return; + } + + if (( RF_CHAN_14 >= psessionEntry->currentOperChannel )&& + !IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + { + limLog(pMac, LOGW, + FL("channel bonding disabled as FW doesn't supoort CB in 2.4gz")); + return; + } + + pOperatingModeframe = vos_mem_malloc(sizeof(*pOperatingModeframe)); + if (NULL == pOperatingModeframe) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed")); + return; + } + + /* Unpack channel switch frame */ + nStatus = dot11fUnpackOperatingMode(pMac, pBody, frameLen, pOperatingModeframe); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + vos_mem_free(pOperatingModeframe); + return; + } + else if(DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an 11h-CHANSW Request (0x%08x, %d bytes):"), + nStatus, + frameLen); + } + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Station context not found"));) + return; + } + + operMode = pSta->vhtSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_80MHZ : pSta->htSupportedChannelWidthSet ? eHT_CHANNEL_WIDTH_40MHZ: eHT_CHANNEL_WIDTH_20MHZ; + if( operMode != pOperatingModeframe->OperatingMode.chanWidth) + { + limLog(pMac, LOGE, + FL(" received Chanwidth %d, staIdx = %d"), + (pOperatingModeframe->OperatingMode.chanWidth ), + pSta->staIndex); + + limLog(pMac, LOGE, + FL(" MAC - %0x:%0x:%0x:%0x:%0x:%0x"), + pHdr->sa[0], + pHdr->sa[1], + pHdr->sa[2], + pHdr->sa[3], + pHdr->sa[4], + pHdr->sa[5]); + + if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if(pOperatingModeframe->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_20MHZ) + { + pSta->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pSta->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + } + limCheckVHTOpModeChange( pMac, psessionEntry, + (pOperatingModeframe->OperatingMode.chanWidth), pSta->staIndex);\ + } + vos_mem_free(pOperatingModeframe); + return; +} +#endif + +static void +__limProcessAddTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ +} + + +static void +__limProcessAddTsRsp(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tSirAddtsRspInfo addts; + tSirRetStatus retval; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U32 frameLen; + tANI_U8 *pBody; + tpLimTspecInfo tspecInfo; + tANI_U8 ac; + tpDphHashNode pStaDs = NULL; + tANI_U8 rspReqd = 1; + tANI_U32 cfgLen; + tSirMacAddr peerMacAddr; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + + PELOGW(limLog(pMac, LOGW, "Recv AddTs Response");) + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp recvd at AP: ignoring"));) + return; + } + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring AddTsRsp"));) + return; + } + + retval = sirConvertAddtsRsp2Struct(pMac, pBody, frameLen, &addts); + if (retval != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp parsing failed (error %d)"), retval);) + return; + } + + // don't have to check for qos/wme capabilities since we wouldn't have this + // flag set otherwise + if (! pMac->lim.gLimAddtsSent) + { + // we never sent an addts request! + PELOGW(limLog(pMac, LOGW, "Recvd AddTsRsp but no request was ever sent - ignoring");) + return; + } + + if (pMac->lim.gLimAddtsReq.req.dialogToken != addts.dialogToken) + { + limLog(pMac, LOGW, "AddTsRsp: token mismatch (got %d, exp %d) - ignoring", + addts.dialogToken, pMac->lim.gLimAddtsReq.req.dialogToken); + return; + } + + /* + * for successful addts reponse, try to add the classifier. + * if this fails for any reason, we should send a delts request to the ap + * for now, its ok not to send a delts since we are going to add support for + * multiple tclas soon and until then we won't send any addts requests with + * multiple tclas elements anyway. + * In case of addClassifier failure, we just let the addts timer run out + */ + if (((addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (addts.tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) && + (addts.status == eSIR_MAC_SUCCESS_STATUS)) + { + // add the classifier - this should always succeed + if (addts.numTclas > 1) // currently no support for multiple tclas elements + { + limLog(pMac, LOGE, FL("Sta %d: Too many Tclas (%d), only 1 supported"), + aid, addts.numTclas); + return; + } + else if (addts.numTclas == 1) + { + limLog(pMac, LOGW, "AddTs Response from STA %d: tsid %d, UP %d, OK!", aid, + addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio); + } + } + limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d ", + addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio, + addts.status); + + // deactivate the response timer + limDeactivateAndChangeTimer(pMac, eLIM_ADDTS_RSP_TIMER); + + if (addts.status != eSIR_MAC_SUCCESS_STATUS) + { + limLog(pMac, LOGW, "Recv AddTsRsp: tsid %d, UP %d, status %d ", + addts.tspec.tsinfo.traffic.tsid, addts.tspec.tsinfo.traffic.userPrio, + addts.status); + limSendSmeAddtsRsp(pMac, true, addts.status, psessionEntry, addts.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + + // clear the addts flag + pMac->lim.gLimAddtsSent = false; + + return; + } +#ifdef FEATURE_WLAN_ESE + if (addts.tsmPresent) + { + limLog(pMac, LOGW, "TSM IE Present"); + psessionEntry->eseContext.tsm.tid = addts.tspec.tsinfo.traffic.userPrio; + vos_mem_copy(&psessionEntry->eseContext.tsm.tsmInfo, + &addts.tsmIE,sizeof(tSirMacESETSMIE)); +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, addts.tsmIE.tsid, + addts.tsmIE.state, addts.tsmIE.msmt_interval); +#else + limActivateTSMStatsTimer(pMac, psessionEntry); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + } +#endif + /* Since AddTS response was successful, check for the PSB flag + * and directional flag inside the TS Info field. + * An AC is trigger enabled AC if the PSB subfield is set to 1 + * in the uplink direction. + * An AC is delivery enabled AC if the PSB subfield is set to 1 + * in the downlink direction. + * An AC is trigger and delivery enabled AC if the PSB subfield + * is set to 1 in the bi-direction field. + */ + if (addts.tspec.tsinfo.traffic.psb == 1) + limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, SET_UAPSD_MASK); + else + limSetTspecUapsdMask(pMac, &addts.tspec.tsinfo, CLEAR_UAPSD_MASK); + + + /* ADDTS success, so AC is now admitted. We shall now use the default + * EDCA parameters as advertised by AP and send the updated EDCA params + * to HAL. + */ + ac = upToAc(addts.tspec.tsinfo.traffic.userPrio); + if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + } + else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + else if(addts.tspec.tsinfo.traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] |= (1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] |= (1 << ac); + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + limLog(pMac, LOGE, FL("Self entry missing in Hash Table ")); + + + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + //if schedule is not present then add TSPEC with svcInterval as 0. + if(!addts.schedulePresent) + addts.schedule.svcInterval = 0; + if(eSIR_SUCCESS != limTspecAdd(pMac, pSta->staAddr, pSta->assocId, &addts.tspec, addts.schedule.svcInterval, &tspecInfo)) + { + PELOGE(limLog(pMac, LOGE, FL("Adding entry in lim Tspec Table failed "));) + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec, + psessionEntry); + pMac->lim.gLimAddtsSent = false; + return; //Error handling. send the response with error status. need to send DelTS to tear down the TSPEC status. + } + if((addts.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA) || + ((upToAc(addts.tspec.tsinfo.traffic.userPrio) < MAX_NUM_AC))) + { + retval = limSendHalMsgAddTs(pMac, pSta->staIndex, tspecInfo->idx, addts.tspec, psessionEntry->peSessionId); + if(eSIR_SUCCESS != retval) + { + limAdmitControlDeleteTS(pMac, pSta->assocId, &addts.tspec.tsinfo, NULL, &tspecInfo->idx); + + // Send DELTS action frame to AP + cfgLen = sizeof(tSirMacAddr); + limSendDeltsReqActionFrame(pMac, peerMacAddr, rspReqd, &addts.tspec.tsinfo, &addts.tspec, + psessionEntry); + limSendSmeAddtsRsp(pMac, true, retval, psessionEntry, addts.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + pMac->lim.gLimAddtsSent = false; + return; + } + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)"), + addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);) + } + else + { + PELOGW(limLog(pMac, LOGW, FL("AddTsRsp received successfully(UP %d, TSID %d)"), + addts.tspec.tsinfo.traffic.userPrio, addts.tspec.tsinfo.traffic.tsid);) + PELOGW(limLog(pMac, LOGW, FL("no ACM: Bypass sending WDA_ADD_TS_REQ to HAL "));) + // Use the smesessionId and smetransactionId from the PE session context + limSendSmeAddtsRsp(pMac, true, eSIR_SME_SUCCESS, psessionEntry, addts.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); + } + + // clear the addts flag + pMac->lim.gLimAddtsSent = false; + return; +} + + +static void +__limProcessDelTsReq(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tSirRetStatus retval; + tSirDeltsReqInfo delts; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pSta; + tANI_U32 frameLen; + tANI_U16 aid; + tANI_U8 *pBody; + tANI_U8 tsStatus; + tSirMacTSInfo *tsinfo; + tANI_U8 tspecIdx; + tANI_U8 ac; + tpDphHashNode pStaDs = NULL; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Station context not found - ignoring DelTs"));) + return; + } + + // parse the delts request + retval = sirConvertDeltsReq2Struct(pMac, pBody, frameLen, &delts); + if (retval != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("DelTs parsing failed (error %d)"), retval);) + return; + } + + if (delts.wmeTspecPresent) + { + if ((!psessionEntry->limWmeEnabled) || (! pSta->wmeEnabled)) + { + PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: wme not enabled/capable"));) + return; + } + limLog(pMac, LOG1, FL("WME Delts received")); + } + else if ((psessionEntry->limQosEnabled) && pSta->lleEnabled) + { + limLog(pMac, LOG1, FL("11e QoS Delts received")); + } + else if ((psessionEntry->limWsmEnabled) && pSta->wsmEnabled) + { + limLog(pMac, LOG1, FL("WSM Delts received")); + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Ignoring delts request: qos not enabled/capable"));) + return; + } + + tsinfo = delts.wmeTspecPresent ? &delts.tspec.tsinfo : &delts.tsinfo; + + // if no Admit Control, ignore the request + if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA)) + { + + if (upToAc(tsinfo->traffic.userPrio) >= MAX_NUM_AC) + { + limLog(pMac, LOGW, FL("DelTs with UP %d has no AC - ignoring request"), + tsinfo->traffic.userPrio); + return; + } + } + + if ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && + (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) + limSendSmeDeltsInd(pMac, &delts, aid,psessionEntry); + + // try to delete the TS + if (eSIR_SUCCESS != limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx)) + { + PELOGW(limLog(pMac, LOGW, FL("Unable to Delete TS"));) + return; + } + + else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) + { + //Edca only for now. + } + else + { + //send message to HAL to delete TS + if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, + pSta->staIndex, + tspecIdx, + delts, + psessionEntry->peSessionId, + psessionEntry->bssId)) + { + limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request"), + tsinfo->traffic.userPrio); + return; + } + } + + /* We successfully deleted the TSPEC. Update the dynamic UAPSD Mask. + * The AC for this TSPEC is no longer trigger enabled if this Tspec + * was set-up in uplink direction only. + * The AC for this TSPEC is no longer delivery enabled if this Tspec + * was set-up in downlink direction only. + * The AC for this TSPEC is no longer triiger enabled and delivery + * enabled if this Tspec was a bidirectional TSPEC. + */ + limSetTspecUapsdMask(pMac, tsinfo, CLEAR_UAPSD_MASK); + + + /* We're deleting the TSPEC. + * The AC for this TSPEC is no longer admitted in uplink/downlink direction + * if this TSPEC was set-up in uplink/downlink direction only. + * The AC for this TSPEC is no longer admitted in both uplink and downlink + * directions if this TSPEC was a bi-directional TSPEC. + * If ACM is set for this AC and this AC is admitted only in downlink + * direction, PE needs to downgrade the EDCA parameter + * (for the AC for which TS is being deleted) to the + * next best AC for which ACM is not enabled, and send the + * updated values to HAL. + */ + ac = upToAc(tsinfo->traffic.userPrio); + + if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + } + else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + else if(tsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + limLog(pMac, LOGE, FL("Self entry missing in Hash Table ")); + + limLog(pMac, LOG1, FL("DeleteTS succeeded")); + +#ifdef FEATURE_WLAN_ESE +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); +#else + limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + +} + +static void +__limProcessQosMapConfigureFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tANI_U8 *pBody; + tSirRetStatus retval; + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + retval = sirConvertQosMapConfigureFrame2Struct(pMac, pBody, frameLen, + &psessionEntry->QosMapSet); + if (retval != eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGE, + FL("QosMapConfigure frame parsing failed (error %d)"), retval);) + return; + } + limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId, + pRxPacketInfo, psessionEntry, + WDA_GET_RX_RSSI_DB(pRxPacketInfo)); +} + +#ifdef ANI_SUPPORT_11H +/** + * limProcessBasicMeasReq + * + *FUNCTION: + * This function is called by limProcessMeasurementRequestFrame() + * when it received a Basic measurement Request action frame. + * Station/BP receiving this should perform basic measurements + * and then send Basic Measurement Report. AP should not perform + * any measurements, and send report indicating refusal. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pMeasReqFrame - A pointer to Basic Meas. Req structure + * @return None + */ +static void +__limProcessBasicMeasReq(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peerMacAddr) +{ + // TBD - Station shall perform basic measurements + + if (limSendMeasReportFrame(pMac, + pMeasReqFrame, + peerMacAddr) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send Basic Meas report "));) + return; + } +} + + +/** + * limProcessCcaMeasReq + * + *FUNCTION: + * This function is called by limProcessMeasurementRequestFrame() + * when it received a CCA measurement Request action frame. + * Station/BP receiving this should perform CCA measurements + * and then send CCA Measurement Report. AP should not perform + * any measurements, and send report indicating refusal. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pMeasReqFrame - A pointer to CCA Meas. Req structure + * @return None + */ +static void +__limProcessCcaMeasReq(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peerMacAddr) +{ + // TBD - Station shall perform cca measurements + + if (limSendMeasReportFrame(pMac, + pMeasReqFrame, + peerMacAddr) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send CCA Meas report "));) + return; + } +} + + +/** + * __limProcessRpiMeasReq + * + *FUNCTION: + * This function is called by limProcessMeasurementRequestFrame() + * when it received a RPI measurement Request action frame. + * Station/BP/AP receiving this shall not perform any measurements, + * and send report indicating refusal. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pMeasReqFrame - A pointer to RPI Meas. Req structure + * @return None + */ +static void +__limProcessRpiMeasReq(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peerMacAddr) +{ + if (limSendMeasReportFrame(pMac, + pMeasReqFrame, + peerMacAddr) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send RPI Meas report "));) + return; + } +} + + +/** + * __limProcessMeasurementRequestFrame + * + *FUNCTION: + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +static void +__limProcessMeasurementRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpSirMacMeasReqActionFrame pMeasReqFrame; + tANI_U32 frameLen; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + pMeasReqFrame = vos_mem_malloc(sizeof( tSirMacMeasReqActionFrame )); + if (NULL == pMeasReqFrame) + { + limLog(pMac, LOGE, + FL("limProcessMeasurementRequestFrame: AllocateMemory failed ")); + return; + } + + if (sirConvertMeasReqFrame2Struct(pMac, pBody, pMeasReqFrame, frameLen) != + eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Rcv invalid Measurement Request Action Frame "));) + return; + } + + + switch(pMeasReqFrame->measReqIE.measType) + { + case SIR_MAC_BASIC_MEASUREMENT_TYPE: + __limProcessBasicMeasReq(pMac, pMeasReqFrame, pHdr->sa); + break; + + case SIR_MAC_CCA_MEASUREMENT_TYPE: + __limProcessCcaMeasReq(pMac, pMeasReqFrame, pHdr->sa); + break; + + case SIR_MAC_RPI_MEASUREMENT_TYPE: + __limProcessRpiMeasReq(pMac, pMeasReqFrame, pHdr->sa); + break; + + default: + limLog(pMac, LOG1, FL("Unknown Measurement Type %d "), + pMeasReqFrame->measReqIE.measType); + break; + } + +} /*** end limProcessMeasurementRequestFrame ***/ + + +/** + * limProcessTpcRequestFrame + * + *FUNCTION: + * This function is called upon receiving Tpc Request frame. + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +static void +__limProcessTpcRequestFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpSirMacTpcReqActionFrame pTpcReqFrame; + tANI_U32 frameLen; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + limLog(pMac, LOG1, FL("****LIM: Processing TPC Request from peer ****")); + + pTpcReqFrame = vos_mem_malloc(sizeof( tSirMacTpcReqActionFrame )); + if (NULL == pTpcReqFrame) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed "));) + return; + } + + if (sirConvertTpcReqFrame2Struct(pMac, pBody, pTpcReqFrame, frameLen) != + eSIR_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Rcv invalid TPC Req Action Frame "));) + return; + } + + if (limSendTpcReportFrame(pMac, + pTpcReqFrame, + pHdr->sa) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send TPC Report Frame. "));) + return; + } +} +#endif + + +/** + * \brief Validate an ADDBA Req from peer with respect + * to our own BA configuration + * + * \sa __limValidateAddBAParameterSet + * + * \param pMac The global tpAniSirGlobal object + * + * \param baParameterSet The ADDBA Parameter Set. + * + * \param pDelBAFlag this parameter is NULL except for call from processAddBAReq + * delBAFlag is set when entry already exists. + * + * \param reqType ADDBA Req v/s ADDBA Rsp + * 1 - ADDBA Req + * 0 - ADDBA Rsp + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ + +static tSirMacStatusCodes +__limValidateAddBAParameterSet( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tDot11fFfAddBAParameterSet baParameterSet, + tANI_U8 dialogueToken, + tLimAddBaValidationReqType reqType , + tANI_U8* pDelBAFlag /*this parameter is NULL except for call from processAddBAReq*/) +{ + if(baParameterSet.tid >= STACFG_MAX_TC) + { + return eSIR_MAC_WME_INVALID_PARAMS_STATUS; + } + + //check if there is already a BA session setup with this STA/TID while processing AddBaReq + if((true == pSta->tcCfg[baParameterSet.tid].fUseBARx) && + (LIM_ADDBA_REQ == reqType)) + { + //There is already BA session setup for STA/TID. + limLog( pMac, LOGE, + FL( "AddBAReq rcvd when there is already a session for this StaId = %d, tid = %d\n " ), + pSta->staIndex, baParameterSet.tid); + limPrintMacAddr( pMac, pSta->staAddr, LOGW ); + + if(pDelBAFlag) + *pDelBAFlag = true; + } + return eSIR_MAC_SUCCESS_STATUS; +} + +/** + * \brief Validate a DELBA Ind from peer with respect + * to our own BA configuration + * + * \sa __limValidateDelBAParameterSet + * + * \param pMac The global tpAniSirGlobal object + * + * \param baParameterSet The DELBA Parameter Set. + * + * \param pSta Runtime, STA-related configuration cached + * in the HashNode object + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +static tSirMacStatusCodes +__limValidateDelBAParameterSet( tpAniSirGlobal pMac, + tDot11fFfDelBAParameterSet baParameterSet, + tpDphHashNode pSta ) +{ +tSirMacStatusCodes statusCode = eSIR_MAC_STA_BLK_ACK_NOT_SUPPORTED_STATUS; + + if (!(baParameterSet.tid < STACFG_MAX_TC)) + return statusCode; + + // Validate if a BA is active for the requested TID + if( pSta->tcCfg[baParameterSet.tid].fUseBATx || + pSta->tcCfg[baParameterSet.tid].fUseBARx ) + { + statusCode = eSIR_MAC_SUCCESS_STATUS; + + limLog( pMac, LOGW, + FL("Valid DELBA Ind received. Time to send WDA_DELBA_IND to HAL...")); + } + else + limLog( pMac, LOGW, + FL("Received an INVALID DELBA Ind for TID %d..."), + baParameterSet.tid ); + + return statusCode; +} + +/** + * \brief Process an ADDBA REQ + * + * \sa limProcessAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pRxPacketInfo Handle to the Rx packet info from HDD + * + * \return none + * + */ +static void +__limProcessAddBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tDot11fAddBAReq frmAddBAReq; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pSta; + tSirMacStatusCodes status = eSIR_MAC_SUCCESS_STATUS; + tANI_U16 aid; + tANI_U32 frameLen, nStatus,val, val1; + tANI_U8 *pBody; + tANI_U8 delBAFlag =0; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + val = 0; + val1 = 0; + + // Unpack the received frame + nStatus = dot11fUnpackAddBAReq( pMac, pBody, frameLen, &frmAddBAReq ); + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL("Failed to unpack and parse an ADDBA Request (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + + // Without an unpacked request we cannot respond, so silently ignore the request + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an ADDBA Request (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + psessionEntry->amsduSupportedInBA = frmAddBAReq.AddBAParameterSet.amsduSupported; + + pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring ADDBA from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGE ); + + // FIXME - Should we do this? + status = eSIR_MAC_INABLITY_TO_CONFIRM_ASSOC_STATUS; + goto returnAfterError; + } + limLog( pMac, LOG1, FL( "ADDBA Req from STA "MAC_ADDRESS_STR " with AID %d" + " tid = %d policy = %d buffsize = %d" + " amsduSupported = %d"), MAC_ADDR_ARRAY(pHdr->sa), + aid, frmAddBAReq.AddBAParameterSet.tid, + frmAddBAReq.AddBAParameterSet.policy, + frmAddBAReq.AddBAParameterSet.bufferSize, + frmAddBAReq.AddBAParameterSet.amsduSupported); + + limLog( pMac, LOG1, FL( "ssn = %d fragNumber = %d" ), + frmAddBAReq.BAStartingSequenceControl.ssn, + frmAddBAReq.BAStartingSequenceControl.fragNumber); + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // we can only do BA on "hard" STAs + if (!(IS_HWSTA_IDX(pSta->staIndex))) + { + status = eSIR_MAC_REQ_DECLINED_STATUS; + limLog( pMac, LOG1, + FL( "ta Id is not HW Sta Id, Status code is %d " ), status); + goto returnAfterError; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_TX_RX_AGGREGATION, &val1) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("Unable to get WNI_CFG_ENABLE_TX_RX_AGGREGATION")); + val1 = 1; + } + if (!val1) + { + limLog(pMac, LOGE, + FL("aggregation disabled - ignoring ADDBA")); + goto returnAfterError; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, &val) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("Unable to get WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC")); + val = 0; + } + if ((SIR_BAND_2_4_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) && + val) + { + limLog( pMac, LOGW, + FL( "BTC disabled aggregation - ignoring ADDBA from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + + status = eSIR_MAC_REQ_DECLINED_STATUS; + goto returnAfterError; + } + + // Now, validate the ADDBA Req + if( eSIR_MAC_SUCCESS_STATUS != + (status = __limValidateAddBAParameterSet( pMac, pSta, + frmAddBAReq.AddBAParameterSet, + 0, //dialogue token is don't care in request validation. + LIM_ADDBA_REQ, &delBAFlag))) + { + limLog( pMac, LOGE, + FL( "ADDBA parameters validation failed with status %d" ), status); + goto returnAfterError; + } + + //BA already set, so we need to delete it before adding new one. + if(delBAFlag) + { + if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac, + pSta, + (tANI_U8)frmAddBAReq.AddBAParameterSet.tid, + eBA_RECIPIENT,psessionEntry)) + { + status = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limLog( pMac, LOGE, + FL( "Deletion of Existing BA session failed with status %d" ), + status); + goto returnAfterError; + } + } + + // Check if the ADD BA Declined configuration is Disabled + if ((pMac->lim.gAddBA_Declined & ( 1 << frmAddBAReq.AddBAParameterSet.tid ) )) { + limLog( pMac, LOGE, FL( "Declined the ADDBA Req for the TID %d " ), + frmAddBAReq.AddBAParameterSet.tid); + status = eSIR_MAC_REQ_DECLINED_STATUS; + goto returnAfterError; + } + + // + // Post WDA_ADDBA_REQ to HAL. + // If HAL/HDD decide to allow this ADDBA Req session, + // then this BA session is termed active + // + + // Change the Block Ack state of this STA to wait for + // ADDBA Rsp from HAL + LIM_SET_STA_BA_STATE(pSta, frmAddBAReq.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP); + + if (wlan_cfgGetInt(pMac, WNI_CFG_NUM_BUFF_ADVERT , &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get WNI_CFG_NUM_BUFF_ADVERT")); + return ; + } + + + if (frmAddBAReq.AddBAParameterSet.bufferSize) + { + frmAddBAReq.AddBAParameterSet.bufferSize = + VOS_MIN(val, frmAddBAReq.AddBAParameterSet.bufferSize); + } + else + { + frmAddBAReq.AddBAParameterSet.bufferSize = val; + } + limLog( pMac, LOG1, FL( "ADDBAREQ NUMBUFF %d" ), + frmAddBAReq.AddBAParameterSet.bufferSize); + + if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac, + pSta, + (tANI_U8) frmAddBAReq.DialogToken.token, + (tANI_U8) frmAddBAReq.AddBAParameterSet.tid, + (tANI_U8) frmAddBAReq.AddBAParameterSet.policy, + frmAddBAReq.AddBAParameterSet.bufferSize, + frmAddBAReq.BATimeout.timeout, + (tANI_U16) frmAddBAReq.BAStartingSequenceControl.ssn, + eBA_RECIPIENT,psessionEntry)) + { + status = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limLog( pMac, LOGE, + FL( "Request to setup new BA session with peer " + " "MAC_ADDRESS_STR " failed" ), MAC_ADDR_ARRAY(pSta->staAddr)); + } + else + return; + +returnAfterError: + + // + // Package LIM_MLM_ADDBA_RSP to MLME, with proper + // status code. MLME will then send an ADDBA RSP + // over the air to the peer MAC entity + // + if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac, + pHdr->sa, + status, + frmAddBAReq.DialogToken.token, + (tANI_U8) frmAddBAReq.AddBAParameterSet.tid, + (tANI_U8) frmAddBAReq.AddBAParameterSet.policy, + frmAddBAReq.AddBAParameterSet.bufferSize, + frmAddBAReq.BATimeout.timeout,psessionEntry)) + { + limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_ADDBA_RSP to " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + } + +} + +/** + * \brief Process an ADDBA RSP + * + * \sa limProcessAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param pRxPacketInfo Handle to the packet info structure from HDD + * + * \return none + * + */ +static void +__limProcessAddBARsp( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ +tDot11fAddBARsp frmAddBARsp; +tpSirMacMgmtHdr pHdr; +tpDphHashNode pSta; +tSirMacReasonCodes reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; +tANI_U16 aid; +tANI_U32 frameLen, nStatus; +tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring ADDBA from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + return; + } + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // We can only do BA on "hard" STAs. We should not have issued an ADDBA + // Request, so we should never be processing a ADDBA Response + if (!(IS_HWSTA_IDX(pSta->staIndex))) + { + limLog( pMac, LOGE, FL( "Sta Id is not HW Sta Id " )); + return; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + + // Unpack the received frame + nStatus = dot11fUnpackAddBARsp( pMac, pBody, frameLen, &frmAddBARsp ); + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse an ADDBA Response (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + goto returnAfterError; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking an ADDBA Response (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + limLog( pMac, LOG1, FL( "ADDBA Rsp from STA "MAC_ADDRESS_STR " with AID %d " + "tid = %d policy = %d buffsize = %d " + "amsduSupported = %d status = %d"), + MAC_ADDR_ARRAY(pHdr->sa), aid, + frmAddBARsp.AddBAParameterSet.tid, + frmAddBARsp.AddBAParameterSet.policy, + frmAddBARsp.AddBAParameterSet.bufferSize, + frmAddBARsp.AddBAParameterSet.amsduSupported, + frmAddBARsp.Status.status); + //if there is no matchin dialougue token then ignore the response. + + if(eSIR_SUCCESS != limSearchAndDeleteDialogueToken(pMac, frmAddBARsp.DialogToken.token, + pSta->assocId, frmAddBARsp.AddBAParameterSet.tid)) + { + limLog(pMac, LOGE, + FL("dialogueToken in received addBARsp did not match with outstanding requests")); + return; + } + + // Check first if the peer accepted the ADDBA Req + if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status ) + { + tANI_U32 val; + pMac->lim.staBaInfo[pSta->staIndex]. + failed_count[frmAddBARsp.AddBAParameterSet.tid] = 0; + pMac->lim.staBaInfo[pSta->staIndex]. + failed_timestamp[frmAddBARsp.AddBAParameterSet.tid] = 0; + if (wlan_cfgGetInt(pMac, WNI_CFG_NUM_BUFF_ADVERT , &val) != eSIR_SUCCESS) + { + limLog(pMac, LOG1, FL("Unable to get WNI_CFG_NUM_BUFF_ADVERT")); + goto returnAfterError; + } + if (0 == frmAddBARsp.AddBAParameterSet.bufferSize) + frmAddBARsp.AddBAParameterSet.bufferSize = val; + else + frmAddBARsp.AddBAParameterSet.bufferSize = + VOS_MIN(val, frmAddBARsp.AddBAParameterSet.bufferSize); + limLog( pMac, LOG1, + FL( "ADDBA RSP Buffsize = %d" ), + frmAddBARsp.AddBAParameterSet.bufferSize); + // Now, validate the ADDBA Rsp + if( eSIR_MAC_SUCCESS_STATUS != + __limValidateAddBAParameterSet( pMac, pSta, + frmAddBARsp.AddBAParameterSet, + (tANI_U8)frmAddBARsp.DialogToken.token, + LIM_ADDBA_RSP, NULL)) + { + limLog( pMac, LOGE, + FL( "ADDBA parameters validation failed" )); + goto returnAfterError; + } + } + else + { + pMac->lim.staBaInfo[pSta->staIndex]. + failed_count[frmAddBARsp.AddBAParameterSet.tid]++; + pMac->lim.staBaInfo[pSta->staIndex].failed_timestamp[ + frmAddBARsp.AddBAParameterSet.tid] = jiffies_to_msecs(jiffies); + goto returnAfterError; + } + // Change STA state to wait for ADDBA Rsp from HAL + LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_WT_ADD_RSP); + + // + // Post WDA_ADDBA_REQ to HAL. + // If HAL/HDD decide to allow this ADDBA Rsp session, + // then this BA session is termed active + // + + if( eSIR_SUCCESS != limPostMsgAddBAReq( pMac, + pSta, + (tANI_U8) frmAddBARsp.DialogToken.token, + (tANI_U8) frmAddBARsp.AddBAParameterSet.tid, + (tANI_U8) frmAddBARsp.AddBAParameterSet.policy, + frmAddBARsp.AddBAParameterSet.bufferSize, + frmAddBARsp.BATimeout.timeout, + 0, + eBA_INITIATOR,psessionEntry)) + { + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + limLog( pMac, LOGE, + FL( "Request to setup new BA session with peer " + " "MAC_ADDRESS_STR " failed" ), MAC_ADDR_ARRAY(pSta->staAddr)); + } + else + return; + +returnAfterError: + + // TODO: Do we need to signal an error status to SME, + // if status != eSIR_MAC_SUCCESS_STATUS + + // Restore STA "BA" State + LIM_SET_STA_BA_STATE(pSta, frmAddBARsp.AddBAParameterSet.tid, eLIM_BA_STATE_IDLE); + // + // Need to send a DELBA IND to peer, who + // would have setup a BA session with this STA + // + if( eSIR_MAC_SUCCESS_STATUS == frmAddBARsp.Status.status ) + { + // + // Package LIM_MLM_DELBA_REQ to MLME, with proper + // status code. MLME will then send a DELBA IND + // over the air to the peer MAC entity + // + if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac, + pSta, + eBA_INITIATOR, + (tANI_U8) frmAddBARsp.AddBAParameterSet.tid, + reasonCode, psessionEntry)) + { + limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_DELBA_REQ to " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + } + } +} + +/** + * \brief Process a DELBA Indication + * + * \sa limProcessDelBAInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param pRxPacketInfo Handle to the Rx packet info from HDD + * + * \return none + * + */ +static void +__limProcessDelBAReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ +tDot11fDelBAInd frmDelBAInd; +tpSirMacMgmtHdr pHdr; +tpDphHashNode pSta; +tANI_U16 aid; +tANI_U32 frameLen, nStatus; +tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pSta = dphLookupHashEntry( pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) + { + limLog( pMac, LOGE, FL( "STA context not found - ignoring DELBA from ")); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + return; + } + + limLog( pMac, LOG1, FL( "DELBA Ind from STA with AID %d" ), aid ); + + // Unpack the received frame + nStatus = dot11fUnpackDelBAInd( pMac, pBody, frameLen, &frmDelBAInd ); + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to unpack and parse a DELBA Indication (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, + FL( "There were warnings while unpacking a DELBA Indication (0x%08x, %d bytes):"), + nStatus, + frameLen ); + + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + limLog( pMac, LOG1, + FL( "Received DELBA from: "MAC_ADDRESS_STR" for TID %d, Reason code %d" ), + MAC_ADDR_ARRAY(pHdr->sa), + frmDelBAInd.DelBAParameterSet.tid, + frmDelBAInd.Reason.code ); + + // Now, validate the DELBA Ind + if( eSIR_MAC_SUCCESS_STATUS != __limValidateDelBAParameterSet( pMac, + frmDelBAInd.DelBAParameterSet, + pSta )) + { + limLog( pMac, LOGE, + FL( "ADDBA parameters validation failed " )); + return; + } + // + // Post WDA_DELBA_IND to HAL and delete the + // existing BA session + // + // NOTE - IEEE 802.11-REVma-D8.0, Section 7.3.1.16 + // is kind of confusing... + // + if( eSIR_SUCCESS != limPostMsgDelBAInd( pMac, + pSta, + (tANI_U8) frmDelBAInd.DelBAParameterSet.tid, + (eBA_RECIPIENT == frmDelBAInd.DelBAParameterSet.initiator)? + eBA_INITIATOR: eBA_RECIPIENT,psessionEntry)) + limLog( pMac, LOGE, FL( "Posting WDA_DELBA_IND to HAL failed ")); + + return; + +} + +static void +__limProcessSMPowerSaveUpdate(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry) +{ + +#if 0 + tpSirMacMgmtHdr pHdr; + tDot11fSMPowerSave frmSMPower; + tSirMacHTMIMOPowerSaveState state; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = SIR_MAC_BD_TO_MPDUHEADER( pBd ); + pBody = SIR_MAC_BD_TO_MPDUDATA( pBd ); + frameLen = SIR_MAC_BD_TO_PAYLOAD_LEN( pBd ); + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable ); + if( pSta == NULL ) { + limLog( pMac, LOGE,FL( "STA context not found - ignoring UpdateSM PSave Mode from " )); + limPrintMacAddr( pMac, pHdr->sa, LOGW ); + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackSMPowerSave( pMac, pBody, frameLen, &frmSMPower); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Update SM Power (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a SMPower Save update (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with PS_Enable:%d" + "PS Mode: %d"), frmSMPower.SMPowerModeSet.PowerSave_En, + frmSMPower.SMPowerModeSet.Mode); + + /** Update in the DPH Table about the Update in the SM Power Save mode*/ + if (frmSMPower.SMPowerModeSet.PowerSave_En && frmSMPower.SMPowerModeSet.Mode) + state = eSIR_HT_MIMO_PS_DYNAMIC; + else if ((frmSMPower.SMPowerModeSet.PowerSave_En) && (frmSMPower.SMPowerModeSet.Mode ==0)) + state = eSIR_HT_MIMO_PS_STATIC; + else if ((frmSMPower.SMPowerModeSet.PowerSave_En == 0) && (frmSMPower.SMPowerModeSet.Mode == 0)) + state = eSIR_HT_MIMO_PS_NO_LIMIT; + else { + PELOGW(limLog(pMac, LOGW, FL("Received SM Power save Mode update Frame with invalid mode"));) + return; + } + + if (state == pSta->htMIMOPSState) { + PELOGE(limLog(pMac, LOGE, FL("The PEER is already set in the same mode"));) + return; + } + + /** Update in the HAL Station Table for the Update of the Protection Mode */ + pSta->htMIMOPSState = state; + limPostSMStateUpdate(pMac,pSta->staIndex, pSta->htMIMOPSState); + +#endif + +} + +#if defined WLAN_FEATURE_VOWIFI + +static void +__limProcessRadioMeasureRequest( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry ) +{ + tpSirMacMgmtHdr pHdr; + tDot11fRadioMeasurementRequest frm; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + if( psessionEntry == NULL ) + { + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackRadioMeasurementRequest( pMac, pBody, frameLen, &frm ); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Radio Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a Radio Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + // Call rrm function to handle the request. + + rrmProcessRadioMeasurementRequest( pMac, pHdr->sa, &frm, psessionEntry ); +} + +static void +__limProcessLinkMeasurementReq( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry ) +{ + tpSirMacMgmtHdr pHdr; + tDot11fLinkMeasurementRequest frm; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + if( psessionEntry == NULL ) + { + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackLinkMeasurementRequest( pMac, pBody, frameLen, &frm ); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Link Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a Link Measure request (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + // Call rrm function to handle the request. + + rrmProcessLinkMeasurementRequest( pMac, pRxPacketInfo, &frm, psessionEntry ); + +} + +static void +__limProcessNeighborReport( tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo ,tpPESession psessionEntry ) +{ + tpSirMacMgmtHdr pHdr; + tDot11fNeighborReportResponse *pFrm; + tANI_U32 frameLen, nStatus; + tANI_U8 *pBody; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pFrm = vos_mem_malloc(sizeof(tDot11fNeighborReportResponse)); + if (NULL == pFrm) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in __limProcessNeighborReport") ); + return; + } + + if(psessionEntry == NULL) + { + vos_mem_free(pFrm); + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackNeighborReportResponse( pMac, pBody, frameLen,pFrm ); + + if( DOT11F_FAILED( nStatus )) { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a Neighbor report response (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + vos_mem_free(pFrm); + return; + }else if ( DOT11F_WARNED( nStatus ) ) { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a Neighbor report response (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + //Call rrm function to handle the request. + rrmProcessNeighborReportResponse( pMac, pFrm, psessionEntry ); + + vos_mem_free(pFrm); +} + +#endif + +#ifdef WLAN_FEATURE_AP_HT40_24G +static void +__limProcess2040bssCoexistenceActionFrame(tpAniSirGlobal pMac, + tANI_U16 sessionId, tANI_U8 *pRxPacketInfo, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody , i; + tANI_U32 frameLen, nStatus; + tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm; + tpSirHT2040CoexInfoInd pSirSmeHT2040CoexInfoInd = NULL; + tANI_U16 length; + tSirMsgQ mmhMsg; + tANI_U8 num_channelList; + + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + pBody = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + frameLen = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + pFrm = + vos_mem_malloc(sizeof(tDot11fHT2040BSSCoexistenceManagementActionFrame)); + + if (NULL == pFrm) + { + limLog(pMac, LOGE, FL("Unable to allocate memory")); + return; + } + + if(psessionEntry == NULL) + { + vos_mem_free(pFrm); + return; + } + + /**Unpack the received frame */ + nStatus = dot11fUnpackHT2040BSSCoexistenceManagementActionFrame( pMac, + pBody, frameLen, pFrm ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, FL( "Failed to unpack and parse a 20/40" + "Coex Action Frame (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + vos_mem_free(pFrm); + return; + } + else if ( DOT11F_WARNED( nStatus )) + { + limLog(pMac, LOGW, FL( "There were warnings while unpacking a" + " 20/40 Coex Action Frame (0x%08x, %d bytes):"), + nStatus, frameLen ); + PELOG2(sirDumpBuf( pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen );) + } + + num_channelList = pFrm->HT2040BSSIntolerantReport.num_channelList; + + if (num_channelList > 0) + { + length = (sizeof(tSirHT2040CoexInfoInd) - sizeof(tANI_U8) + + (num_channelList * sizeof(tANI_U8))); + } + else + length = sizeof(tSirHT2040CoexInfoInd); + + limLog(pMac, LOGW,FL("tSirHT2040CoexInfoInd: Length: %d"),length); + + pSirSmeHT2040CoexInfoInd = vos_mem_malloc(length); + + if (NULL == pSirSmeHT2040CoexInfoInd) + { + limLog(pMac, LOGP, + FL("AllocateMemory failed for eWNI_SME_2040_COEX_IND")); + vos_mem_free(pFrm); + return; + } + + vos_mem_set((void*)pSirSmeHT2040CoexInfoInd, length, 0); + + pSirSmeHT2040CoexInfoInd->messageType = eWNI_SME_2040_COEX_IND; + pSirSmeHT2040CoexInfoInd->sessionId = sessionId; + pSirSmeHT2040CoexInfoInd->length = length; + + if (pFrm->HT2040BSSCoexistence.present) + { + + limLog(pMac, LOGW, FL("infoRequest: %d fortyMHzIntolerant: %d" + " twentyMHzBssWidthReq: %d obssScanExemptionReq: %d" + " obssScanExemptionGrant: %d "), + pFrm->HT2040BSSCoexistence.infoRequest, + pFrm->HT2040BSSCoexistence.fortyMHzIntolerant, + pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq, + pFrm->HT2040BSSCoexistence.obssScanExemptionReq, + pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + + pSirSmeHT2040CoexInfoInd->HT40MHzIntolerant = + pFrm->HT2040BSSCoexistence.fortyMHzIntolerant; + pSirSmeHT2040CoexInfoInd->HT20MHzBssWidthReq = + pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq; + } + + if (pFrm->HT2040BSSIntolerantReport.present) + { + limLog(pMac, LOGW, FL("operatingClass: %d num_channelList: %d "), + pFrm->HT2040BSSIntolerantReport.operatingClass, + num_channelList); + + if (num_channelList > 0) + { + vos_mem_zero(pSirSmeHT2040CoexInfoInd->HT2040BssIntoChanReport, + num_channelList); + vos_mem_copy(pSirSmeHT2040CoexInfoInd->HT2040BssIntoChanReport, + pFrm->HT2040BSSIntolerantReport.channelList, + num_channelList); + + pSirSmeHT2040CoexInfoInd->channel_num = num_channelList; + } + + for(i=0; i < num_channelList; i++) + { + limLog(pMac, LOGW, FL("Channel : %d "), + pSirSmeHT2040CoexInfoInd->HT2040BssIntoChanReport[i]); + } + } + + mmhMsg.type = eWNI_SME_2040_COEX_IND; + mmhMsg.bodyptr = pSirSmeHT2040CoexInfoInd; + mmhMsg.bodyval = 0; + limLog(pMac, LOGW, FL("Posting eWNI_SME_2040_COEX_IND Message to SME ")); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + vos_mem_free(pFrm); +} +#endif + +#ifdef WLAN_FEATURE_11W +/** + * limProcessSAQueryRequestActionFrame + * + *FUNCTION: + * This function is called by limProcessActionFrame() upon + * SA query request Action frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - Handle to the Rx packet info + * @param psessionEntry - PE session entry + * + * @return None + */ +static void __limProcessSAQueryRequestActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tANI_U8 transId[2]; + + /* Prima --- Below Macro not available in prima + pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd); + pBody = SIR_MAC_BD_TO_MPDUDATA(pBd); */ + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + /* If this is an unprotected SA Query Request, then ignore it. */ + if (pHdr->fc.wep == 0) + return; + + /*Extract 11w trsansId from SA query request action frame + In SA query response action frame we will send same transId + In SA query request action frame: + Category : 1 byte + Action : 1 byte + Transaction ID : 2 bytes */ + vos_mem_copy(&transId[0], &pBody[2], 2); + + //Send 11w SA query response action frame + if (limSendSaQueryResponseFrame(pMac, + transId, + pHdr->sa,psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("fail to send SA query response action frame."));) + return; + } +} + +/** + * __limProcessSAQueryResponseActionFrame + * + *FUNCTION: + * This function is called by limProcessActionFrame() upon + * SA query response Action frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - Handle to the Rx packet info + * @param psessionEntry - PE session entry + * @return None + */ +static void __limProcessSAQueryResponseActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpDphHashNode pSta; + tANI_U16 aid; + tANI_U16 transId; + tANI_U8 retryNum; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("SA Query Response received...")) ; + + /* When a station, supplicant handles SA Query Response. + Forward to SME to HDD to wpa_supplicant. */ + if (eLIM_STA_ROLE == psessionEntry->limSystemRole) + { + limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId, + pRxPacketInfo, psessionEntry, + WDA_GET_RX_RSSI_DB(pRxPacketInfo)); + return; + } + + /* If this is an unprotected SA Query Response, then ignore it. */ + if (pHdr->fc.wep == 0) + return; + + pSta = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (NULL == pSta) + return; + + limLog(pMac, LOG1, + FL("SA Query Response source addr - %0x:%0x:%0x:%0x:%0x:%0x"), + pHdr->sa[0], pHdr->sa[1], pHdr->sa[2], pHdr->sa[3], + pHdr->sa[4], pHdr->sa[5]); + limLog(pMac, LOG1, + FL("SA Query state for station - %d"), pSta->pmfSaQueryState); + + if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState) + return; + + /* Extract 11w trsansId from SA query reponse action frame + In SA query response action frame: + Category : 1 byte + Action : 1 byte + Transaction ID : 2 bytes */ + vos_mem_copy(&transId, &pBody[2], 2); + + /* If SA Query is in progress with the station and the station + responds then the association request that triggered the SA + query is from a rogue station, just go back to initial state. */ + for (retryNum = 0; retryNum <= pSta->pmfSaQueryRetryCount; retryNum++) + if (transId == pSta->pmfSaQueryStartTransId + retryNum) + { + limLog(pMac, LOG1, + FL("Found matching SA Query Request - transaction ID %d"), transId); + tx_timer_deactivate(&pSta->pmfSaQueryTimer); + pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + break; + } +} +#endif + +#ifdef WLAN_FEATURE_11W +/** + * limDropUnprotectedActionFrame + * + *FUNCTION: + * This function checks if an Action frame should be dropped since it is + * a Robust Managment Frame, it is unprotected, and it is received on a + * connection where PMF is enabled. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Global MAC structure + * @param psessionEntry - PE session entry + * @param pHdr - Frame header + * @param category - Action frame category + * @return TRUE if frame should be dropped + */ + +static tANI_BOOLEAN +limDropUnprotectedActionFrame (tpAniSirGlobal pMac, tpPESession psessionEntry, + tpSirMacMgmtHdr pHdr, tANI_U8 category) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tANI_BOOLEAN rmfConnection = eANI_BOOLEAN_FALSE; + + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + if (pStaDs->rmfEnabled) + rmfConnection = eANI_BOOLEAN_TRUE; + } + else if (psessionEntry->limRmfEnabled) + rmfConnection = eANI_BOOLEAN_TRUE; + + if (rmfConnection && (pHdr->fc.wep == 0)) + { + PELOGE(limLog(pMac, LOGE, FL("Dropping unprotected Action category %d frame " + "since RMF is enabled."), category);) + return eANI_BOOLEAN_TRUE; + } + else + return eANI_BOOLEAN_FALSE; +} +#endif + +/** + * limProcessActionFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Action frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to packet info structure + * @return None + */ + +void +limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + tpSirMacActionFrameHdr pActionHdr = (tpSirMacActionFrameHdr) pBody; +#ifdef WLAN_FEATURE_11W + tpSirMacMgmtHdr pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + if (lim_is_robust_mgmt_action_frame(pActionHdr->category) && + limDropUnprotectedActionFrame(pMac, psessionEntry, pHdr, + pActionHdr->category)) { + limLog(pMac, LOGE, + FL("Don't send unprotect action frame to upper layer categ %d "), + pActionHdr->category); + return; + } +#endif + + switch (pActionHdr->category) + { + + /* + * WARNING: If you add Action frame category case here, set the + * corresponding bit to 1 in sme_set_allowed_action_frames() for + * the FW to hand over that frame to host without dropping itself + */ + case SIR_MAC_ACTION_QOS_MGMT: + if ( (psessionEntry->limQosEnabled) || + (pActionHdr->actionID == SIR_MAC_QOS_MAP_CONFIGURE) ) + { + switch (pActionHdr->actionID) + { + case SIR_MAC_QOS_ADD_TS_REQ: + __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_ADD_TS_RSP: + __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_DEL_TS_REQ: + __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_MAP_CONFIGURE: + __limProcessQosMapConfigureFrame(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + default: + limLog(pMac, LOG1, + FL("Qos action %d not handled"), + pActionHdr->actionID); + break; + } + break ; + } + + break; + + case SIR_MAC_ACTION_SPECTRUM_MGMT: + switch (pActionHdr->actionID) + { +#ifdef ANI_SUPPORT_11H + case SIR_MAC_ACTION_MEASURE_REQUEST_ID: + if(psessionEntry->lim11hEnable) + { + __limProcessMeasurementRequestFrame(pMac, pRxPacketInfo); + } + break; + + case SIR_MAC_ACTION_TPC_REQUEST_ID: + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (pessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + if(psessionEntry->lim11hEnable) + { + __limProcessTpcRequestFrame(pMac, pRxPacketInfo); + } + } + break; + +#endif + case SIR_MAC_ACTION_CHANNEL_SWITCH_ID: + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + __limProcessChannelSwitchActionFrame(pMac, pRxPacketInfo,psessionEntry); + } + break; + default: + limLog(pMac, LOG1, + FL("Spectrum mgmt action id %d not handled"), + pActionHdr->actionID); + break; + } + break; + + case SIR_MAC_ACTION_WME: + if (! psessionEntry->limWmeEnabled) + { + limLog(pMac, LOGW, FL("WME mode disabled - dropping action frame %d"), + pActionHdr->actionID); + break; + } + switch(pActionHdr->actionID) + { + case SIR_MAC_QOS_ADD_TS_REQ: + __limProcessAddTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_ADD_TS_RSP: + __limProcessAddTsRsp(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_DEL_TS_REQ: + __limProcessDelTsReq(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_QOS_MAP_CONFIGURE: + __limProcessQosMapConfigureFrame(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + default: + limLog(pMac, LOG1, FL("WME action %d not handled"), + pActionHdr->actionID); + break; + } + break; + + case SIR_MAC_ACTION_BLKACK: + // Determine the "type" of BA Action Frame + switch(pActionHdr->actionID) + { + case SIR_MAC_BLKACK_ADD_REQ: + __limProcessAddBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_BLKACK_ADD_RSP: + __limProcessAddBARsp( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_BLKACK_DEL: + __limProcessDelBAReq( pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + + default: + break; + } + + break; + case SIR_MAC_ACTION_HT: + /** Type of HT Action to be performed*/ + switch(pActionHdr->actionID) { + case SIR_MAC_SM_POWER_SAVE: + __limProcessSMPowerSaveUpdate(pMac, (tANI_U8 *) pRxPacketInfo,psessionEntry); + break; + default: + limLog(pMac, LOG1, + FL("Action ID %d not handled in HT Action category"), + pActionHdr->actionID); + break; + } + break; + + case SIR_MAC_ACTION_WNM: + { + PELOGE(limLog(pMac, LOG1, FL("WNM Action category %d action %d."), + pActionHdr->category, pActionHdr->actionID);) + switch (pActionHdr->actionID) + { + case SIR_MAC_WNM_BSS_TM_QUERY: + case SIR_MAC_WNM_BSS_TM_REQUEST: + case SIR_MAC_WNM_BSS_TM_RESPONSE: + case SIR_MAC_WNM_NOTIF_REQUEST: + case SIR_MAC_WNM_NOTIF_RESPONSE: + { + tpSirMacMgmtHdr pHdr; + tANI_S8 rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo); + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + /* Forward to the SME to HDD to wpa_supplicant */ + limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId, + pRxPacketInfo, + psessionEntry, rssi); + break; + } + } + break; + } +#if defined WLAN_FEATURE_VOWIFI + case SIR_MAC_ACTION_RRM: + /* Ignore RRM measurement request until DHCP is set */ + if(pMac->rrm.rrmPEContext.rrmEnable && + pMac->roam.roamSession[psessionEntry->smeSessionId].dhcp_done) + { + switch(pActionHdr->actionID) { + case SIR_MAC_RRM_RADIO_MEASURE_REQ: + __limProcessRadioMeasureRequest( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry ); + break; + case SIR_MAC_RRM_LINK_MEASUREMENT_REQ: + __limProcessLinkMeasurementReq( pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry ); + break; + case SIR_MAC_RRM_NEIGHBOR_RPT: + __limProcessNeighborReport( pMac, (tANI_U8*) pRxPacketInfo, psessionEntry ); + break; + default: + limLog( pMac, LOG1, FL("Action ID %d not handled in RRM"), + pActionHdr->actionID); + break; + + } + } + else + { + // Else we will just ignore the RRM messages. + limLog( pMac, LOG1, + FL("RRM Action frame ignored as rrmEnable is %d or DHCP not completed %d"), + pMac->rrm.rrmPEContext.rrmEnable, + pMac->roam.roamSession[psessionEntry->smeSessionId].dhcp_done); + } + break; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) \ + || defined (WLAN_FEATURE_RMC) + case SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY: + { + tpSirMacVendorSpecificFrameHdr pVendorSpecific = (tpSirMacVendorSpecificFrameHdr) pActionHdr; + tpSirMacMgmtHdr pHdr; + tANI_U8 Oui[] = { 0x00, 0x00, 0xf0 }; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + //Check if it is a vendor specific action frame. + if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && + (VOS_TRUE == vos_mem_compare(psessionEntry->selfMacAddr, + &pHdr->da[0], sizeof(tSirMacAddr))) && + IS_WES_MODE_ENABLED(pMac) && + vos_mem_compare(pVendorSpecific->Oui, Oui, 3)) + { + PELOGE( limLog( pMac, LOGW, FL("Received Vendor specific action frame, OUI %x %x %x"), + pVendorSpecific->Oui[0], pVendorSpecific->Oui[1], pVendorSpecific->Oui[2]);) + /* Forward to the SME to HDD to wpa_supplicant */ + // type is ACTION + limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId, + pRxPacketInfo, + psessionEntry, 0); + } +#if defined (WLAN_FEATURE_RMC) + else if ((eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) && + ((VOS_TRUE == vos_mem_compare(SIR_MAC_RMC_MCAST_ADDRESS, + &pHdr->da[0], sizeof(tSirMacAddr))) || + (VOS_TRUE == vos_mem_compare(psessionEntry->selfMacAddr, + &pHdr->da[0], sizeof(tSirMacAddr)))) && + vos_mem_compare(pVendorSpecific->Oui, SIR_MAC_RMC_OUI, 3)) + { + tANI_U8 MagicCode[] = + { 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e }; + tpSirMacIbssExtNetworkFrameHdr pIbssExtHdr = + (tpSirMacIbssExtNetworkFrameHdr) pActionHdr; + + if (vos_mem_compare(pIbssExtHdr->MagicCode, + MagicCode, sizeof(MagicCode)) && + pIbssExtHdr->version == SIR_MAC_RMC_VER ) + { + switch (pIbssExtHdr->actionID) + { + default: + PELOGE(limLog(pMac, LOGE, + FL("Action RMC actionID %d not handled"), + pIbssExtHdr->actionID);) + break; + case SIR_MAC_RMC_RULER_INFORM_SELECTED: + limLog(pMac, LOG1, + FL("Action RMC RULER_INFORM_SELECTED.")); + limProcessRMCMessages(pMac, + eLIM_RMC_OTA_RULER_INFORM_SELECTED, + (tANI_U32 *)pRxPacketInfo); + break; + case SIR_MAC_RMC_RULER_INFORM_CANCELLED: + limLog(pMac, LOG1, + FL("Action RMC RULER_INFORM_CANCELLED.")); + limProcessRMCMessages(pMac, + eLIM_RMC_OTA_RULER_INFORM_CANCELLED, + (tANI_U32 *)pRxPacketInfo); + break; + } + } + else + { + limLog( pMac, LOG1, + FL("Dropping the vendor specific action frame in IBSS " + "mode because of Ibss Ext Magic mismatch " + MAC_ADDRESS_STR " or Version mismatch = %d"), + MAC_ADDR_ARRAY(pIbssExtHdr->MagicCode), + pIbssExtHdr->version ); + } + } +#endif /* WLAN_FEATURE_RMC */ + else + { + limLog( pMac, LOG1, + FL("Dropping the vendor specific action frame because of( " + "WES Mode not enabled (WESMODE = %d) or OUI mismatch (%02x %02x %02x) or " + "not received with SelfSta Mac address) system role = %d"), + IS_WES_MODE_ENABLED(pMac), + pVendorSpecific->Oui[0], pVendorSpecific->Oui[1], + pVendorSpecific->Oui[2], + psessionEntry->limSystemRole ); + } + } + break; +#endif /* WLAN_FEATURE_VOWIFI_11R || FEATURE_WLAN_ESE || + FEATURE_WLAN_LFR || WLAN_FEATURE_RMC */ + case SIR_MAC_ACTION_PUBLIC_USAGE: + switch(pActionHdr->actionID) { + case SIR_MAC_ACTION_VENDOR_SPECIFIC: + { + tpSirMacVendorSpecificPublicActionFrameHdr pPubAction = (tpSirMacVendorSpecificPublicActionFrameHdr) pActionHdr; + tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 }; + + //Check if it is a P2P public action frame. + if (vos_mem_compare(pPubAction->Oui, P2POui, 4)) + { + /* Forward to the SME to HDD to wpa_supplicant */ + // type is ACTION + limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId, + pRxPacketInfo, + psessionEntry, + WDA_GET_RX_RSSI_DB(pRxPacketInfo)); + } + else + { + limLog( pMac, LOG1, + FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x"), + pPubAction->Oui[0], pPubAction->Oui[1], + pPubAction->Oui[2], pPubAction->Oui[3] ); + } + } + break; +#ifdef WLAN_FEATURE_AP_HT40_24G + case SIR_MAC_ACTION_2040_BSS_COEXISTENCE: + { + if (pMac->roam.configParam.apHT40_24GEnabled) + { + limLog( pMac, LOGW, FL("Public Action 20/40 BSS" + "Coexistence Management frame")); + + __limProcess2040bssCoexistenceActionFrame(pMac, + psessionEntry->smeSessionId, (tANI_U8 *) pRxPacketInfo, + psessionEntry); + } + break; + } +#endif +#ifdef FEATURE_WLAN_TDLS + case SIR_MAC_TDLS_DIS_RSP: + { + tANI_S8 rssi; + + rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("Public Action TDLS Discovery RSP ..")) ; + limSendSmeMgmtFrameInd(pMac, psessionEntry->smeSessionId, + pRxPacketInfo, + psessionEntry, rssi); + } + break; +#endif + + default: + limLog(pMac, LOG1, FL("Unhandled public action frame -- %x "), + pActionHdr->actionID); + break; + } + break; + +#ifdef WLAN_FEATURE_11W + case SIR_MAC_ACTION_SA_QUERY: + { + PELOGE(limLog(pMac, LOG1, FL("SA Query Action category %d action %d."), pActionHdr->category, pActionHdr->actionID);) + switch (pActionHdr->actionID) + { + case SIR_MAC_SA_QUERY_REQ: + /**11w SA query request action frame received**/ + /* Respond directly to the incoming request in LIM */ + __limProcessSAQueryRequestActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry ); + break; + case SIR_MAC_SA_QUERY_RSP: + /**11w SA query response action frame received**/ + /* Handle based on the current SA Query state */ + __limProcessSAQueryResponseActionFrame(pMac,(tANI_U8*) pRxPacketInfo, psessionEntry ); + break; + default: + break; + } + break; + } +#endif +#ifdef WLAN_FEATURE_11AC + case SIR_MAC_ACTION_VHT: + { + if (psessionEntry->vhtCapability) + { + switch (pActionHdr->actionID) + { + case SIR_MAC_VHT_OPMODE_NOTIFICATION: + __limProcessOperatingModeActionFrame(pMac,pRxPacketInfo,psessionEntry); + break; + default: + break; + } + } + break; + } +#endif + default: + limLog(pMac, LOG1, + FL("Action category %d not handled"), pActionHdr->category); + break; + } +} + +/** + * limProcessActionFrameNoSession + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Action frame reception and no session. + * Currently only public action frames can be received from + * a non-associated station. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pBd - A pointer to Buffer descriptor + associated PDUs + * @return None + */ + +void +limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd) +{ + tANI_U8 *pBody = WDA_GET_RX_MPDU_DATA(pBd); + tpSirMacVendorSpecificPublicActionFrameHdr pActionHdr = (tpSirMacVendorSpecificPublicActionFrameHdr) pBody; + + limLog( pMac, LOG1, "Received a Action frame -- no session"); + + switch ( pActionHdr->category ) + { + case SIR_MAC_ACTION_PUBLIC_USAGE: + switch(pActionHdr->actionID) { + case SIR_MAC_ACTION_VENDOR_SPECIFIC: + { + tANI_U8 P2POui[] = { 0x50, 0x6F, 0x9A, 0x09 }; + + //Check if it is a P2P public action frame. + if (vos_mem_compare(pActionHdr->Oui, P2POui, 4)) + { + /* Forward to the SME to HDD to wpa_supplicant */ + // type is ACTION + limSendSmeMgmtFrameInd(pMac, 0, pBd, NULL, + WDA_GET_RX_RSSI_DB(pBd)); + } + else + { + limLog( pMac, LOG1, + FL("Unhandled public action frame (Vendor specific). OUI %x %x %x %x"), + pActionHdr->Oui[0], pActionHdr->Oui[1], + pActionHdr->Oui[2], pActionHdr->Oui[3]); + } + } + break; + default: + limLog(pMac, LOG1, + FL("Unhandled public action frame -- %x "), pActionHdr->actionID); + break; + } + break; + default: + limLog(pMac, LOG1, + FL("Unhandled action frame without session -- %x "), + pActionHdr->category); + break; + + } +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c new file mode 100644 index 000000000000..e1b7978999c8 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocReqFrame.c @@ -0,0 +1,1809 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessAssocReqFrame.cc contains the code + * for processing Re/Association Request Frame. + * Author: Chandra Modumudi + * Date: 03/18/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "wniCfg.h" +#include "sirApi.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "pmmApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limStaHashApi.h" +#include "limAdmitControl.h" +#include "palApi.h" +#include "limSessionUtils.h" + + +#include "vos_types.h" +/** + * limConvertSupportedChannels + * + *FUNCTION: + * This function is called by limProcessAssocReqFrame() to + * parse the channel support IE in the Assoc/Reassoc Request + * frame, and send relevant information in the SME_ASSOC_IND + * + *NOTE: + * + * @param pMac - A pointer to Global MAC structure + * @param pMlmAssocInd - A pointer to SME ASSOC/REASSOC IND + * @param assocReq - A pointer to ASSOC/REASSOC Request frame + * + * @return None + */ +static void +limConvertSupportedChannels(tpAniSirGlobal pMac, + tpLimMlmAssocInd pMlmAssocInd, + tSirAssocReq *assocReq) +{ + + tANI_U16 i, j, index=0; + tANI_U8 firstChannelNumber; + tANI_U8 numberOfChannel; + tANI_U8 nextChannelNumber; + + if(assocReq->supportedChannels.length >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + limLog(pMac, LOG1, FL("Number of supported channels:%d is more than " + "MAX"), assocReq->supportedChannels.length); + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + + for(i=0; i < (assocReq->supportedChannels.length); i++) + { + // Get First Channel Number + firstChannelNumber = assocReq->supportedChannels.supportedChannels[i]; + pMlmAssocInd->supportedChannels.channelList[index] = firstChannelNumber; + i++; + index++; + if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + // Get Number of Channels in a Subband + numberOfChannel = assocReq->supportedChannels.supportedChannels[i]; + PELOG2(limLog(pMac, LOG2, FL("Rcv AssocReq: chnl=%d, numOfChnl=%d "), + firstChannelNumber, numberOfChannel);) + + if (numberOfChannel > 1) + { + nextChannelNumber = firstChannelNumber; + if(SIR_BAND_5_GHZ == limGetRFBand(firstChannelNumber)) + { + for (j=1; j < numberOfChannel; j++) + { + nextChannelNumber += SIR_11A_FREQUENCY_OFFSET; + pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber; + index++; + if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + } + } + else if(SIR_BAND_2_4_GHZ == limGetRFBand(firstChannelNumber)) + { + for (j=1; j < numberOfChannel; j++) + { + nextChannelNumber += SIR_11B_FREQUENCY_OFFSET; + pMlmAssocInd->supportedChannels.channelList[index] = nextChannelNumber; + index++; + if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMlmAssocInd->supportedChannels.numChnl = 0; + return; + } + } + } + } + } + + pMlmAssocInd->supportedChannels.numChnl = (tANI_U8) index; + PELOG2(limLog(pMac, LOG2, + FL("Send AssocInd to WSM: spectrum ON, minPwr %d, maxPwr %d, " + "numChnl %d"), + pMlmAssocInd->powerCap.minTxPower, + pMlmAssocInd->powerCap.maxTxPower, + pMlmAssocInd->supportedChannels.numChnl);) +} + + +/**--------------------------------------------------------------- +\fn limProcessAssocReqFrame +\brief This function is called by limProcessMessageQueue() +\ upon Re/Association Request frame reception in +\ BTAMP AP or Soft AP role. +\ +\param pMac +\param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs +\param subType - Indicates whether it is Association Request(=0) +\ or Reassociation Request(=1) frame +\return None +------------------------------------------------------------------*/ +void +limProcessAssocReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, + tANI_U8 subType, tpPESession psessionEntry) +{ + tANI_U8 updateContext; + tANI_U8 *pBody; + tANI_U16 peerIdx, temp; + tANI_U32 val; + tANI_S32 framelen; + tSirRetStatus status; + tpSirMacMgmtHdr pHdr; + struct tLimPreAuthNode *pStaPreAuthContext; + tAniAuthType authType; + tSirMacCapabilityInfo localCapabilities; + tpDphHashNode pStaDs = NULL; + tpSirAssocReq pAssocReq; + tLimMlmStates mlmPrevState; + tDot11fIERSN Dot11fIERSN; + tDot11fIEWPA Dot11fIEWPA; + tANI_U32 phyMode; + tHalBitVal qosMode; + tHalBitVal wsmMode, wmeMode; + tANI_U8 *wpsIe = NULL; + tSirMacRateSet basicRates; + tANI_U8 i = 0, j = 0; + tANI_BOOLEAN pmfConnection = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_11W + tPmfSaQueryTimerId timerId; + tANI_U32 retryInterval; +#endif + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + limGetQosMode(psessionEntry, &qosMode); + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + framelen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + limLog(pMac, LOG1, FL("Received %s Req Frame on sessionid: %d systemrole %d" + " limMlmState %d from: "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + psessionEntry->peSessionId, psessionEntry->limSystemRole, + psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->sa)); + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE ) + { + limLog(pMac, LOGE, FL("received unexpected ASSOC REQ on sessionid: %d " + "sys subType=%d for role=%d from: "MAC_ADDRESS_STR), + psessionEntry->peSessionId, + subType, psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pHdr->sa)); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, + WDA_GET_RX_MPDU_DATA(pRxPacketInfo), framelen); + return; + } + + /* + * If a STA is already present in DPH and it + * is initiating a Assoc re-transmit, do not + * process it. This can happen when first Assoc Req frame + * is received but ACK lost at STA side. The ACK for this + * dropped Assoc Req frame should be sent by HW. Host simply + * does not process it once the entry for the STA is already + * present in DPH. + */ + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &peerIdx, + &psessionEntry->dph.dphHashTable); + if (NULL != pStaDs) + { + if (pHdr->fc.retry > 0) + { + /* Ignore the Retry */ + limLog(pMac, LOGE, + FL("STA is initiating Assoc Req after ACK lost. " + "So, do not Process sessionid: %d sys subType=%d " + "for role=%d from: "MAC_ADDRESS_STR), + psessionEntry->peSessionId, subType, + psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pHdr->sa)); + return; + } + else + { +#ifdef WLAN_FEATURE_11W + /* Do not send Assoc rsp for duplicate assoc req in case of PMF + * enabled STA, as driver needs to start SA Querry in this case + */ + if (!pStaDs->rmfEnabled) +#endif + { + /* STA might have missed the assoc response, + * so it is sending assoc request frame again. + */ + limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, + pStaDs->assocId, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, pStaDs, + psessionEntry, NULL); + limLog(pMac, LOGE, + FL("DUT already received an assoc request frame " + "and STA is sending another assoc req.So, do not " + "Process sessionid: %d sys subType=%d for role=%d " + "from: "MAC_ADDRESS_STR), + psessionEntry->peSessionId, subType, + psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pHdr->sa)); + return; + } + } + } + + // Get pointer to Re/Association Request frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Re/Assoc Req frame from a BC/MC address + // Log error and ignore it + limLog(pMac, LOGE, FL("Received %s Req on sessionid: %d frame from a " + "BC/MC address"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + psessionEntry->peSessionId, + MAC_ADDR_ARRAY(pHdr->sa)); + return; + } + + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, (tANI_U8 *) pBody, framelen); + + if (vos_mem_compare((tANI_U8* ) pHdr->sa, (tANI_U8 *) pHdr->da, + (tANI_U8) (sizeof(tSirMacAddr)))) + { + limLog(pMac, LOGE, FL("Rejected Assoc Req frame Since same mac as" + " SAP/GO")); + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + return ; + } + + // If TKIP counter measures active send Assoc Rsp frame to station with eSIR_MAC_MIC_FAILURE_REASON + if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + limLog(pMac, LOGE, FL("TKIP counter measure is active")); + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_MIC_FAILURE_REASON, + 1, + pHdr->sa, + subType, 0, psessionEntry, NULL); + return; + } + + // Allocate memory for the Assoc Request frame + pAssocReq = vos_mem_malloc(sizeof(*pAssocReq)); + if (NULL == pAssocReq) + { + limLog(pMac, LOGP, FL("Allocate Memory failed in AssocReq")); + return; + } + vos_mem_set((void *)pAssocReq , sizeof(*pAssocReq), 0); + + // Parse Assoc Request frame + if (subType == LIM_ASSOC) + status = sirConvertAssocReqFrame2Struct(pMac, pBody, framelen, pAssocReq); + else + status = sirConvertReassocReqFrame2Struct(pMac, pBody, framelen, pAssocReq); + + if (status != eSIR_SUCCESS) + { + limLog(pMac, LOGW, + FL("Parse error AssocRequest, length=%d from "MAC_ADDRESS_STR), + framelen, MAC_ADDR_ARRAY(pHdr->sa)); + limSendAssocRspMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS, 1, + pHdr->sa, subType, 0, psessionEntry, NULL); + goto error; + } + + pAssocReq->assocReqFrame = vos_mem_malloc(framelen); + if ( NULL == pAssocReq->assocReqFrame ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory for the assoc req, " + "length=%d from "),framelen); + goto error; + } + + vos_mem_copy((tANI_U8 *) pAssocReq->assocReqFrame, + (tANI_U8 *) pBody, framelen); + pAssocReq->assocReqFrameLength = framelen; + + if (cfgGetCapabilityInfo(pMac, &temp,psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve Capabilities")); + goto error; + } + limCopyU16((tANI_U8 *) &localCapabilities, temp); + + if (limCompareCapabilities(pMac, + pAssocReq, + &localCapabilities,psessionEntry) == false) + { + limLog(pMac, LOGE, FL("local caps mismatch received caps")); + limLog(pMac, LOGE, FL("Received %s Req with unsupported " + "capabilities from"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + /** + * Capabilities of requesting STA does not match with + * local capabilities. Respond with 'unsupported capabilities' + * status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry ,NULL); + + goto error; + } + + updateContext = false; + + if (limCmpSSid(pMac, &pAssocReq->ssId, psessionEntry) == false) + { + limLog(pMac, LOGE, FL("Received %s Req with unmatched ssid ( Received" + " SSID: %.*s current SSID: %.*s ) from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", pAssocReq->ssId.length, + pAssocReq->ssId.ssId, psessionEntry->ssId.length, + psessionEntry->ssId.ssId, MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * Received Re/Association Request with either + * Broadcast SSID OR with SSID that does not + * match with local one. + * Respond with unspecified status code. + */ + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_UNSPEC_FAILURE_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + } + + /*************************************************************** + ** Verify if the requested rates are available in supported rate + ** set or Extended rate set. Some APs are adding basic rates in + ** Extended rateset IE + ***************************************************************/ + basicRates.numRates = 0; + + for(i = 0; i < pAssocReq->supportedRates.numRates && (i < SIR_MAC_RATESET_EID_MAX); i++) + { + basicRates.rate[i] = pAssocReq->supportedRates.rate[i]; + basicRates.numRates++; + } + + for(j = 0; (j < pAssocReq->extendedRates.numRates) && (i < SIR_MAC_RATESET_EID_MAX); i++,j++) + { + basicRates.rate[i] = pAssocReq->extendedRates.rate[j]; + basicRates.numRates++; + } + if (limCheckRxBasicRates(pMac, basicRates, psessionEntry) == false) + { + limLog(pMac, LOGE, FL("Received %s Req with unsupported " + "rates from"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + /** + * Requesting STA does not support ALL BSS basic + * rates. Respond with 'basic rates not supported' + * status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + } + + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) && + ((!pAssocReq->extendedRatesPresent ) || (pAssocReq->HTCaps.present))) + { + limLog(pMac, LOGE, FL("SOFTAP was in 11G only mode, rejecting legacy " + "STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, pHdr->sa, subType, 0, psessionEntry, NULL); + goto error; + + }//end if phyMode == 11G_only + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) && + (!pAssocReq->HTCaps.present)) + { + limLog(pMac, LOGE, FL("SOFTAP was in 11N only mode, rejecting legacy " + "STA : "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + limSendAssocRspMgmtFrame( pMac, eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS, + 1, pHdr->sa, subType, 0, psessionEntry, NULL); + goto error; + }//end if PhyMode == 11N_only + + + /* Spectrum Management (11h) specific checks */ + if (localCapabilities.spectrumMgt) + { + tSirRetStatus status = eSIR_SUCCESS; + + /* If station is 11h capable, then it SHOULD send all mandatory + * IEs in assoc request frame. Let us verify that + */ + if (pAssocReq->capabilityInfo.spectrumMgt) + { + if (!((pAssocReq->powerCapabilityPresent) && (pAssocReq->supportedChannelsPresent))) + { + /* One or more required information elements are missing, log the peers error */ + if (!pAssocReq->powerCapabilityPresent) + { + limLog(pMac, LOG1, FL("LIM Info: Missing Power capability " + "IE in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + } + if (!pAssocReq->supportedChannelsPresent) + { + limLog(pMac, LOGW, FL("LIM Info: Missing Supported channel " + "IE in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + } + } + else + { + /* Assoc request has mandatory fields */ + status = limIsDot11hPowerCapabilitiesInRange(pMac, pAssocReq, psessionEntry); + if (eSIR_SUCCESS != status) + { + limLog(pMac, LOGW, FL("LIM Info: MinTxPower(STA) > " + "MaxTxPower(AP) in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + } + status = limIsDot11hSupportedChannelsValid(pMac, pAssocReq); + if (eSIR_SUCCESS != status) + { + limLog(pMac, LOGW, FL("LIM Info: wrong supported " + "channels (STA) in %s Req from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + } + /* IEs are valid, use them if needed */ + } + } //if(assoc.capabilityInfo.spectrumMgt) + else + { + /* As per the capabiities, the spectrum management is not enabled on the station + * The AP may allow the associations to happen even if spectrum management is not + * allowed, if the transmit power of station is below the regulatory maximum + */ + + /* TODO: presently, this is not handled. In the current implemetation, the AP would + * allow the station to associate even if it doesn't support spectrum management. + */ + } + }// end of spectrum management related processing + + if ( (pAssocReq->HTCaps.present) && (limCheckMCSSet(pMac, pAssocReq->HTCaps.supportedMCSSet) == false)) + { + limLog(pMac, LOGE, FL("received %s req with unsupported" + "MCS Rate Set from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * Requesting STA does not support ALL BSS MCS basic Rate set rates. + * Spec does not define any status code for this scenario. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + } + + //if (pMac->dph.gDphPhyMode == WNI_CFG_PHY_MODE_11G) + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_ONLY_POLICY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve 11g-only flag")); + goto error; + } + + if (!pAssocReq->extendedRatesPresent && val) + { + limLog(pMac, LOGE, FL("Rejecting Re/Assoc req from 11b STA: " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + /** + * Received Re/Association Request from + * 11b STA when 11g only policy option + * is set. + * Reject with unspecified status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + +#ifdef WLAN_DEBUG + pMac->lim.gLim11bStaAssocRejectCount++; +#endif + goto error; + } + } + +#ifdef WMM_APSD + // Save the QOS info element in assoc request.. + limGetWmeMode(pMac, &wmeMode); + if (wmeMode == eHAL_SET) + { + tpQosInfoSta qInfo; + + qInfo = (tpQosInfoSta) (pAssocReq->qosCapability.qosInfo); + + if ((pMac->lim.gWmmApsd.apsdEnable == 0) && (qInfo->ac_be || qInfo->ac_bk || qInfo->ac_vo || qInfo->ac_vi)) + { + limLog(pMac, LOGW, + FL("Rejecting Re/Assoc req from STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + limLog(pMac, LOGE, FL("APSD not enabled, qosInfo - 0x%x"), *qInfo); + + /** + * Received Re/Association Request from + * 11b STA when 11g only policy option + * is set. + * Reject with unspecified status code. + */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_WME_REFUSED_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + } + } +#endif + + // Check for 802.11n HT caps compatibility; are HT Capabilities + // turned on in lim? + if ( psessionEntry->htCapability ) + { + // There are; are they turned on in the STA? + if ( pAssocReq->HTCaps.present ) + { + // The station *does* support 802.11n HT capability... + + limLog( pMac, LOG1, FL( "AdvCodingCap:%d ChaWidthSet:%d " + "PowerSave:%d greenField:%d " + "shortGI20:%d shortGI40:%d" + "txSTBC:%d rxSTBC:%d delayBA:%d" + "maxAMSDUsize:%d DSSS/CCK:%d " + "PSMP:%d stbcCntl:%d lsigTXProt:%d"), + pAssocReq->HTCaps.advCodingCap, + pAssocReq->HTCaps.supportedChannelWidthSet, + pAssocReq->HTCaps.mimoPowerSave, + pAssocReq->HTCaps.greenField, + pAssocReq->HTCaps.shortGI20MHz, + pAssocReq->HTCaps.shortGI40MHz, + pAssocReq->HTCaps.txSTBC, + pAssocReq->HTCaps.rxSTBC, + pAssocReq->HTCaps.delayedBA, + pAssocReq->HTCaps.maximalAMSDUsize, + pAssocReq->HTCaps.dsssCckMode40MHz, + pAssocReq->HTCaps.psmp, + pAssocReq->HTCaps.stbcControlFrame, + pAssocReq->HTCaps.lsigTXOPProtection ); + + // Make sure the STA's caps are compatible with our own: + //11.15.2 Support of DSSS/CCK in 40 MHz + //the AP shall refuse association requests from an HT STA that has the DSSS/CCK + //Mode in 40 MHz subfield set to 1; + + //FIXME_BTAMP_AP : Need to be enabled + /* + if ( !pMac->lim.gHTDsssCckRate40MHzSupport && pAssocReq->HTCaps.dsssCckMode40MHz ) + { + statusCode = eSIR_MAC_DSSS_CCK_RATE_NOT_SUPPORT_STATUS; + limLog( pMac, LOGW, FL( "AP DSSS/CCK is disabled; " + "STA rejected." ) ); + // Reject association + limSendAssocRspMgmtFrame( pMac, statusCode, 1, pHdr->sa, subType, 0,psessionEntry); + goto error; + } + */ + } + } // End if on HT caps turned on in lim. + + /* Clear the buffers so that frame parser knows that there isn't a previously decoded IE in these buffers */ + vos_mem_set((tANI_U8*)&Dot11fIERSN, sizeof( Dot11fIERSN ), 0); + vos_mem_set((tANI_U8*)&Dot11fIEWPA, sizeof( Dot11fIEWPA ), 0); + + /* if additional IE is present, check if it has WscIE */ + if( pAssocReq->addIEPresent && pAssocReq->addIE.length ) + wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + /* when wpsIe is present, RSN/WPA IE is ignored */ + if( wpsIe == NULL ) + { + /** check whether as RSN IE is present */ + if(psessionEntry->limSystemRole == eLIM_AP_ROLE + && psessionEntry->pLimStartBssReq->privacy + && psessionEntry->pLimStartBssReq->rsnIE.length) + { + limLog(pMac, LOG1, + FL("RSN enabled auth, Re/Assoc req from STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + if(pAssocReq->rsnPresent) + { + if(pAssocReq->rsn.length) + { + // Unpack the RSN IE + if (dot11fUnpackIeRSN(pMac, + &pAssocReq->rsn.info[0], + pAssocReq->rsn.length, + &Dot11fIERSN) != DOT11F_PARSE_SUCCESS) + { + limLog(pMac, LOGE, + FL("Invalid RSNIE received")); + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS, + 1, pHdr->sa, subType, 0,psessionEntry, NULL); + goto error; + } + + /* Check RSN version is supported or not */ + if(SIR_MAC_OUI_VERSION_1 == Dot11fIERSN.version) + { + /* check the groupwise and pairwise cipher suites */ + if(eSIR_SUCCESS != (status = limCheckRxRSNIeMatch(pMac, Dot11fIERSN, psessionEntry, + pAssocReq->HTCaps.present, &pmfConnection))) + { + limLog(pMac, LOGE, FL("RSN Mismatch. Rejecting Re/Assoc req from " + "STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + /* some IE is not properly sent */ + /* received Association req frame with RSN IE but length is 0 */ + limSendAssocRspMgmtFrame( + pMac, + status, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + + } + } + else + { + limLog(pMac, LOGE, FL("RSN Version mismatch. " + "Rejecting Re/Assoc req from " + "STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + /* received Association req frame with RSN IE version wrong */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + goto error; + + } + } + else + { + limLog(pMac, LOGW, FL("RSN length not correct. " + "Rejecting Re/Assoc req from STA:" + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + /* received Association req frame with RSN IE but length is 0 */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + + } + } /* end - if(pAssocReq->rsnPresent) */ + if((!pAssocReq->rsnPresent) && pAssocReq->wpaPresent) + { + // Unpack the WPA IE + if(pAssocReq->wpa.length) + { + if (dot11fUnpackIeWPA(pMac, + &pAssocReq->wpa.info[4], //OUI is not taken care + pAssocReq->wpa.length, + &Dot11fIEWPA) != DOT11F_PARSE_SUCCESS) + { + limLog(pMac, LOGE, FL("Invalid WPA IE")); + limSendAssocRspMgmtFrame(pMac, + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS, + 1, pHdr->sa, subType, 0,psessionEntry, NULL); + goto error; + } + /* check the groupwise and pairwise cipher suites */ + if(eSIR_SUCCESS != (status = limCheckRxWPAIeMatch(pMac, Dot11fIEWPA, psessionEntry, pAssocReq->HTCaps.present))) + { + limLog(pMac, LOGW, FL("WPA IE mismatch. " + "Rejecting Re/Assoc req from " + "STA: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + /* received Association req frame with WPA IE but mismatch */ + limSendAssocRspMgmtFrame( + pMac, + status, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + goto error; + + } + } + else + { + limLog(pMac, LOGW, FL("WPA len incorrect. " + "Rejecting Re/Assoc req from STA: " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + /* received Association req frame with invalid WPA IE */ + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); + + goto error; + }/* end - if(pAssocReq->wpa.length) */ + } /* end - if(pAssocReq->wpaPresent) */ + } /* end of if(psessionEntry->pLimStartBssReq->privacy + && psessionEntry->pLimStartBssReq->rsnIE->length) */ + + } /* end of if( ! pAssocReq->wscInfo.present ) */ + + /** + * Extract 'associated' context for STA, if any. + * This is maintained by DPH and created by LIM. + */ + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &peerIdx, &psessionEntry->dph.dphHashTable); + + /// Extract pre-auth context for the STA, if any. + pStaPreAuthContext = limSearchPreAuthList(pMac, pHdr->sa); + + if (pStaDs == NULL) + { + /// Requesting STA is not currently associated + if (peGetCurrentSTAsCount(pMac) == pMac->lim.maxStation) + { + /** + * Maximum number of STAs that AP can handle reached. + * Send Association response to peer MAC entity + */ + limLog(pMac, LOGE, FL("Max Sta count reached : %d"), + pMac->lim.maxStation); + limRejectAssociation(pMac, pHdr->sa, + subType, false, + (tAniAuthType) 0, 0, + false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + goto error; + } + + /// Check if STA is pre-authenticated. + if ((pStaPreAuthContext == NULL) || + (pStaPreAuthContext && + (pStaPreAuthContext->mlmState != + eLIM_MLM_AUTHENTICATED_STATE))) + { + /** + * STA is not pre-authenticated yet requesting + * Re/Association before Authentication. + * OR STA is in the process of getting authenticated + * and sent Re/Association request. + * Send Deauthentication frame with 'prior + * authentication required' reason code. + */ + limSendDeauthMgmtFrame( + pMac, + eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON, //=9 + pHdr->sa, psessionEntry, FALSE); + + limLog(pMac, LOGE, FL("received %s req on sessionid: %d from STA " + "that does not have pre-auth context"MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", + psessionEntry->peSessionId, + MAC_ADDR_ARRAY(pHdr->sa)); + goto error; + } + + /// Delete 'pre-auth' context of STA + authType = pStaPreAuthContext->authType; + limDeletePreAuthNode(pMac, pHdr->sa); + + // All is well. Assign AID (after else part) + + } // if (pStaDs == NULL) + else + { + // STA context does exist for this STA + + if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + { + /** + * Requesting STA is in some 'transient' state? + * Ignore the Re/Assoc Req frame by incrementing + * debug counter & logging error. + */ + if (subType == LIM_ASSOC) + { + +#ifdef WLAN_DEBUG + pMac->lim.gLimNumAssocReqDropInvldState++; +#endif + limLog(pMac, LOGE, FL("received Assoc req in state " + "%d from "), pStaDs->mlmStaContext.mlmState); + } + else + { +#ifdef WLAN_DEBUG + pMac->lim.gLimNumReassocReqDropInvldState++; +#endif + limLog(pMac, LOGE, FL("received ReAssoc req in state %d" + " from "), pStaDs->mlmStaContext.mlmState); + } + limPrintMacAddr(pMac, pHdr->sa, LOG1); + limPrintMlmState(pMac, LOG1, (tLimMlmStates) pStaDs->mlmStaContext.mlmState); + + goto error; + } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + + /* STA sent association Request frame while already in + * 'associated' state */ + +#ifdef WLAN_FEATURE_11W + limLog(pMac, LOG1, FL("Re/Assoc request from station that is already associated")); + limLog(pMac, LOG1, FL("PMF enabled %d, SA Query state %d"), pStaDs->rmfEnabled, + pStaDs->pmfSaQueryState); + if (pStaDs->rmfEnabled) + { + switch (pStaDs->pmfSaQueryState) + { + + // start SA Query procedure, respond to Association Request + // with try again later + case DPH_SA_QUERY_NOT_IN_PROGRESS: + /* + * We should reset the retry counter before we start + * the SA query procedure, otherwise in next set of SA query + * procedure we will end up using the stale value. + */ + pStaDs->pmfSaQueryRetryCount = 0; + limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1, + pHdr->sa, subType, pStaDs, + psessionEntry, NULL); + limSendSaQueryRequestFrame( + pMac, (tANI_U8 *)&(pStaDs->pmfSaQueryCurrentTransId), + pHdr->sa, psessionEntry); + pStaDs->pmfSaQueryStartTransId = pStaDs->pmfSaQueryCurrentTransId; + pStaDs->pmfSaQueryCurrentTransId++; + + // start timer for SA Query retry + if (tx_timer_activate(&pStaDs->pmfSaQueryTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("PMF SA Query timer activation failed!")); + goto error; + } + + pStaDs->pmfSaQueryState = DPH_SA_QUERY_IN_PROGRESS; + goto error; + + // SA Query procedure still going, respond to Association + // Request with try again later + case DPH_SA_QUERY_IN_PROGRESS: + limSendAssocRspMgmtFrame(pMac, eSIR_MAC_TRY_AGAIN_LATER, 1, + pHdr->sa, subType, 0, psessionEntry, + NULL); + goto error; + + // SA Query procedure timed out, accept Association Request + // normally + case DPH_SA_QUERY_TIMED_OUT: + pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + break; + } + } +#endif + + /* no change in the capability so drop the frame */ + if ((VOS_TRUE == vos_mem_compare(&pStaDs->mlmStaContext.capabilityInfo, + &pAssocReq->capabilityInfo, + sizeof(tSirMacCapabilityInfo)))&& + (subType == LIM_ASSOC)) + { + limLog(pMac, LOGE, FL(" Received Assoc req in state %d STAid=%d"), + pStaDs->mlmStaContext.mlmState,peerIdx); + goto error; + } + else + { + /** + * STA sent Re/association Request frame while already in + * 'associated' state. Update STA capabilities and + * send Association response frame with same AID + */ + limLog(pMac, LOG1, FL("Received Assoc req from STA already connected" + " UpdateConext")); + pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo; + if (pStaPreAuthContext && + (pStaPreAuthContext->mlmState == + eLIM_MLM_AUTHENTICATED_STATE)) + { + /// STA has triggered pre-auth again + authType = pStaPreAuthContext->authType; + limDeletePreAuthNode(pMac, pHdr->sa); + } + else + authType = pStaDs->mlmStaContext.authType; + + updateContext = true; + if (dphInitStaState(pMac, pHdr->sa, peerIdx, true, &psessionEntry->dph.dphHashTable) + == NULL) + { + limLog(pMac, LOGE, FL("could not Init STAid=%d"), peerIdx); + goto error; + } + } + goto sendIndToSme; + } // end if (lookup for STA in perStaDs fails) + + + + // check if sta is allowed per QoS AC rules + //if (pMac->dph.gDphQosEnabled || pMac->dph.gDphWmeEnabled) + limGetWmeMode(psessionEntry, &wmeMode); + if ((qosMode == eHAL_SET) || (wmeMode == eHAL_SET)) + { + // for a qsta, check if the requested Traffic spec + // is admissible + // for a non-qsta check if the sta can be admitted + if (pAssocReq->addtsPresent) + { + tANI_U8 tspecIdx = 0; //index in the sch tspec table. + if (limAdmitControlAddTS(pMac, pHdr->sa, &(pAssocReq->addtsReq), + &(pAssocReq->qosCapability), 0, false, NULL, &tspecIdx, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("AdmitControl: TSPEC rejected")); + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_QAP_NO_BANDWIDTH_REASON, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); +#ifdef WLAN_DEBUG + pMac->lim.gLimNumAssocReqDropACRejectTS++; +#endif + goto error; + } + } + else if (limAdmitControlAddSta(pMac, pHdr->sa, false) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("AdmitControl: Sta rejected")); + limSendAssocRspMgmtFrame( + pMac, + eSIR_MAC_QAP_NO_BANDWIDTH_REASON, + 1, + pHdr->sa, + subType, 0,psessionEntry, NULL); +#ifdef WLAN_DEBUG + pMac->lim.gLimNumAssocReqDropACRejectSta++; +#endif + goto error; + } + + // else all ok + limLog(pMac, LOG1, FL("AdmitControl: Sta OK!")); + } + + /** + * STA is Associated ! + */ + limLog(pMac, LOGE, FL("Received %s Req successful from "MAC_ADDRESS_STR), + (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc", MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * AID for this association will be same as the peer Index used in DPH table. + * Assign unused/least recently used peer Index from perStaDs. + * NOTE: limAssignPeerIdx() assigns AID values ranging + * between 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT) + */ + + peerIdx = limAssignPeerIdx(pMac, psessionEntry); + + if (!peerIdx) + { + // Could not assign AID + // Reject association + limLog(pMac, LOGE, FL("PeerIdx not avaialble. Reject associaton")); + + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, + peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + goto error; + } + + /** + * Add an entry to hash table maintained by DPH module + */ + + pStaDs = dphAddHashEntry(pMac, pHdr->sa, peerIdx, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + // Could not add hash table entry at DPH + limLog(pMac, LOGE, + FL("could not add hash entry at DPH for aid=%d, MacAddr:" + MAC_ADDRESS_STR), + peerIdx,MAC_ADDR_ARRAY(pHdr->sa)); + + // Release AID + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + goto error; + } + + +sendIndToSme: + + psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq; + + pStaDs->mlmStaContext.htCapability = pAssocReq->HTCaps.present; +#ifdef WLAN_FEATURE_11AC + pStaDs->mlmStaContext.vhtCapability = pAssocReq->VHTCaps.present; +#endif + pStaDs->qos.addtsPresent = (pAssocReq->addtsPresent==0) ? false : true; + pStaDs->qos.addts = pAssocReq->addtsReq; + pStaDs->qos.capability = pAssocReq->qosCapability; + pStaDs->versionPresent = 0; + /* short slot and short preamble should be updated before doing limaddsta */ + pStaDs->shortPreambleEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortPreamble; + pStaDs->shortSlotTimeEnabled = (tANI_U8)pAssocReq->capabilityInfo.shortSlotTime; + + if (pAssocReq->propIEinfo.versionPresent) //update STA version info + { + pStaDs->versionPresent = 1; + pStaDs->version = pAssocReq->propIEinfo.version; + } + pStaDs->propCapability = 0; + if (pAssocReq->propIEinfo.capabilityPresent) + { + if (sirGetCfgPropCaps(pMac, &pStaDs->propCapability)) + pStaDs->propCapability &= pAssocReq->propIEinfo.capability; + } + + pStaDs->valid = 0; + pStaDs->mlmStaContext.authType = authType; + pStaDs->staType = STA_ENTRY_PEER; + + //TODO: If listen interval is more than certain limit, reject the association. + //Need to check customer requirements and then implement. + pStaDs->mlmStaContext.listenInterval = pAssocReq->listenInterval; + pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo; + + /* The following count will be used to knock-off the station if it doesn't + * come back to receive the buffered data. The AP will wait for numTimSent number + * of beacons after sending TIM information for the station, before assuming that + * the station is no more associated and disassociates it + */ + + /** timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/ + pStaDs->timWaitCount = (tANI_U8)GET_TIM_WAIT_COUNT(pAssocReq->listenInterval); + + /** Initialise the Current successful MPDU's tranfered to this STA count as 0 */ + pStaDs->curTxMpduCnt = 0; + + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pAssocReq->HTCaps.present)) + { + pStaDs->htGreenfield = (tANI_U8)pAssocReq->HTCaps.greenField; + pStaDs->htAMpduDensity = pAssocReq->HTCaps.mpduDensity; + pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocReq->HTCaps.dsssCckMode40MHz; + pStaDs->htLsigTXOPProtection = (tANI_U8)pAssocReq->HTCaps.lsigTXOPProtection; + pStaDs->htMaxAmsduLength = (tANI_U8)pAssocReq->HTCaps.maximalAMSDUsize; + pStaDs->htMaxRxAMpduFactor = pAssocReq->HTCaps.maxRxAMPDUFactor; + pStaDs->htMIMOPSState = pAssocReq->HTCaps.mimoPowerSave; + + /* pAssocReq will be copied to psessionEntry->parsedAssocReq later */ + /* check whether AP is enabled with shortGI */ + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val) != + eSIR_SUCCESS) { + limLog(pMac, LOGE, + FL("could not retrieve shortGI 20Mhz CFG")); + goto error; + } + if (val) { + pStaDs->htShortGI20Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI20MHz; + } else { + /* Unset htShortGI20Mhz in ht_caps*/ + pAssocReq->HTCaps.shortGI20MHz = 0; + pStaDs->htShortGI20Mhz = 0; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val) != + eSIR_SUCCESS) { + limLog(pMac, LOGE, + FL("could not retrieve shortGI 40Mhz CFG")); + goto error; + } + if (val) { + pStaDs->htShortGI40Mhz = (tANI_U8)pAssocReq->HTCaps.shortGI40MHz; + } else { + /* Unset htShortGI40Mhz in ht_caps */ + pAssocReq->HTCaps.shortGI40MHz = 0; + pStaDs->htShortGI40Mhz = 0; + } + pStaDs->htSupportedChannelWidthSet = (tANI_U8)pAssocReq->HTCaps.supportedChannelWidthSet; + /* peer just follows AP; so when we are softAP/GO, we just store our session entry's secondary channel offset here in peer INFRA STA + * However, if peer's 40MHz channel width support is disabled then secondary channel will be zero + */ + pStaDs->htSecondaryChannelOffset = (pStaDs->htSupportedChannelWidthSet)?psessionEntry->htSecondaryChannelOffset:0; +#ifdef WLAN_FEATURE_11AC + if(pAssocReq->operMode.present) + { + pStaDs->vhtSupportedChannelWidthSet = (tANI_U8)((pAssocReq->operMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) ? WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ : WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ); + pStaDs->htSupportedChannelWidthSet = (tANI_U8)(pAssocReq->operMode.chanWidth ? eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ); + } + else if (pAssocReq->VHTCaps.present) + { + // Check if STA has enabled it's channel bonding mode. + // If channel bonding mode is enabled, we decide based on SAP's current configuration. + // else, we set it to VHT20. + pStaDs->vhtSupportedChannelWidthSet = (tANI_U8)((pStaDs->htSupportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) ? + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ : + psessionEntry->vhtTxChannelWidthSet ); + } + + // Lesser among the AP and STA bandwidth of operation. + pStaDs->htSupportedChannelWidthSet = + (pStaDs->htSupportedChannelWidthSet < psessionEntry->htSupportedChannelWidthSet) ? + pStaDs->htSupportedChannelWidthSet : psessionEntry->htSupportedChannelWidthSet ; + +#endif + pStaDs->baPolicyFlag = 0xFF; + pStaDs->htLdpcCapable = (tANI_U8)pAssocReq->HTCaps.advCodingCap; + } + + if(pAssocReq->VHTCaps.present) + { + pStaDs->vhtLdpcCapable = (tANI_U8)pAssocReq->VHTCaps.ldpcCodingCap; + } + +#ifdef WLAN_FEATURE_11AC +if (limPopulateMatchingRateSet(pMac, + pStaDs, + &(pAssocReq->supportedRates), + &(pAssocReq->extendedRates), + pAssocReq->HTCaps.supportedMCSSet, + &(pAssocReq->propIEinfo.propRates), + psessionEntry , &pAssocReq->VHTCaps) + != eSIR_SUCCESS) +#else + + if (limPopulateMatchingRateSet(pMac, + pStaDs, + &(pAssocReq->supportedRates), + &(pAssocReq->extendedRates), + pAssocReq->HTCaps.supportedMCSSet, + &(pAssocReq->propIEinfo.propRates), psessionEntry) != eSIR_SUCCESS) +#endif + { + // Could not update hash table entry at DPH with rateset + limLog(pMac, LOGE, + FL("could not update hash entry at DPH for aid=%d, MacAddr: " + MAC_ADDRESS_STR), + peerIdx, MAC_ADDR_ARRAY(pHdr->sa)); + + // Release AID + limReleasePeerIdx(pMac, peerIdx, psessionEntry); + + + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, peerIdx, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + + vos_mem_copy((tANI_U8 *) &pStaDs->mlmStaContext.propRateSet, + (tANI_U8 *) &(pAssocReq->propIEinfo.propRates), + pAssocReq->propIEinfo.propRates.numPropRates + 1); + + /// Add STA context at MAC HW (BMU, RHP & TFP) + + pStaDs->qosMode = eANI_BOOLEAN_FALSE; + pStaDs->lleEnabled = eANI_BOOLEAN_FALSE; + if (pAssocReq->capabilityInfo.qos && (qosMode == eHAL_SET)) + { + pStaDs->lleEnabled = eANI_BOOLEAN_TRUE; + pStaDs->qosMode = eANI_BOOLEAN_TRUE; + } + + pStaDs->wmeEnabled = eANI_BOOLEAN_FALSE; + pStaDs->wsmEnabled = eANI_BOOLEAN_FALSE; + limGetWmeMode(psessionEntry, &wmeMode); + //if ((! pStaDs->lleEnabled) && assoc.wmeInfoPresent && pMac->dph.gDphWmeEnabled) + if ((! pStaDs->lleEnabled) && pAssocReq->wmeInfoPresent && (wmeMode == eHAL_SET)) + { + pStaDs->wmeEnabled = eANI_BOOLEAN_TRUE; + pStaDs->qosMode = eANI_BOOLEAN_TRUE; + limGetWsmMode(psessionEntry, &wsmMode); + /* WMM_APSD - WMM_SA related processing should be separate; WMM_SA and WMM_APSD + can coexist */ + if( pAssocReq->WMMInfoStation.present) + { + /* check whether AP supports or not */ + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) + && (psessionEntry->apUapsdEnable == 0) && (pAssocReq->WMMInfoStation.acbe_uapsd + || pAssocReq->WMMInfoStation.acbk_uapsd + || pAssocReq->WMMInfoStation.acvo_uapsd + || pAssocReq->WMMInfoStation.acvi_uapsd)) + { + + /** + * Received Re/Association Request from + * STA when UPASD is not supported. + */ + limLog( pMac, LOGE, FL( "AP do not support UAPSD so reply " + "to STA accordingly" )); + /* update UAPSD and send it to LIM to add STA */ + pStaDs->qos.capability.qosInfo.acbe_uapsd = 0; + pStaDs->qos.capability.qosInfo.acbk_uapsd = 0; + pStaDs->qos.capability.qosInfo.acvo_uapsd = 0; + pStaDs->qos.capability.qosInfo.acvi_uapsd = 0; + pStaDs->qos.capability.qosInfo.maxSpLen = 0; + + } + else + { + /* update UAPSD and send it to LIM to add STA */ + pStaDs->qos.capability.qosInfo.acbe_uapsd = pAssocReq->WMMInfoStation.acbe_uapsd; + pStaDs->qos.capability.qosInfo.acbk_uapsd = pAssocReq->WMMInfoStation.acbk_uapsd; + pStaDs->qos.capability.qosInfo.acvo_uapsd = pAssocReq->WMMInfoStation.acvo_uapsd; + pStaDs->qos.capability.qosInfo.acvi_uapsd = pAssocReq->WMMInfoStation.acvi_uapsd; + pStaDs->qos.capability.qosInfo.maxSpLen = pAssocReq->WMMInfoStation.max_sp_length; + } + } + //if (assoc.wsmCapablePresent && pMac->dph.gDphWsmEnabled) + if (pAssocReq->wsmCapablePresent && (wsmMode == eHAL_SET)) + pStaDs->wsmEnabled = eANI_BOOLEAN_TRUE; + + } + + // Re/Assoc Response frame to requesting STA + pStaDs->mlmStaContext.subType = subType; + + if (pAssocReq->propIEinfo.aniIndicator) + pStaDs->aniPeer = 1; + +#ifdef WLAN_FEATURE_11W + pStaDs->rmfEnabled = (pmfConnection) ? 1 : 0; + pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + timerId.fields.sessionId = psessionEntry->peSessionId; + timerId.fields.peerIdx = peerIdx; + if (wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + &retryInterval) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Could not retrieve PMF SA Query retry interval value")); + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, + peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + goto error; + } + if (WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN > retryInterval) + { + retryInterval = WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF; + } + if (tx_timer_create(&pStaDs->pmfSaQueryTimer, "PMF SA Query timer", + limPmfSaQueryTimerHandler, timerId.value, + SYS_MS_TO_TICKS((retryInterval * 1024) / 1000), + 0, TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not create PMF SA Query timer")); + limRejectAssociation(pMac, pHdr->sa, + subType, true, authType, + peerIdx, false, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + goto error; + } +#endif + + // BTAMP: Storing the parsed assoc request in the psessionEntry array + psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq; + + /* BTAMP: If STA context already exist (ie. updateContext = 1) + * for this STA, then we should delete the old one, and add + * the new STA. This is taken care of in the limDelSta() routine. + * + * Prior to BTAMP, we were setting this flag so that when + * PE receives SME_ASSOC_CNF, and if this flag is set, then + * PE shall delete the old station and then add. But now in + * BTAMP, we're directly adding station before waiting for + * SME_ASSOC_CNF, so we can do this now. + */ + if (!updateContext) + { + pStaDs->mlmStaContext.updateContext = 0; + + // BTAMP: Add STA context at HW - issue WDA_ADD_STA_REQ to HAL + if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not Add STA with assocId=%d"), + pStaDs->assocId); + limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, pStaDs->assocId, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + } + else + { + pStaDs->mlmStaContext.updateContext = 1; + + mlmPrevState = pStaDs->mlmStaContext.mlmState; + + /* As per the HAL/FW needs the reassoc req need not be calling limDelSta */ + if(subType != LIM_REASSOC) + { + //we need to set the mlmState here in order differentiate in limDelSta. + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE; + if(limDelSta(pMac, pStaDs, true, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not DEL STA with assocId=%d staId %d"), + pStaDs->assocId, pStaDs->staIndex); + limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + //Restoring the state back. + pStaDs->mlmStaContext.mlmState = mlmPrevState; + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + } + else + { + /* mlmState is changed in limAddSta context */ + /* use the same AID, already allocated */ + if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL( "Could not AddSta with assocId= %d staId %d"), + pStaDs->assocId, pStaDs->staIndex); + limRejectAssociation( pMac, pStaDs->staAddr, pStaDs->mlmStaContext.subType, true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true,(tSirResultCodes) eSIR_MAC_WME_REFUSED_STATUS, psessionEntry); + + //Restoring the state back. + pStaDs->mlmStaContext.mlmState = mlmPrevState; + pAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId]; + goto error; + } + + } + + } + + return; + +error: + if (pAssocReq != NULL) + { + if ( pAssocReq->assocReqFrame ) + { + vos_mem_free(pAssocReq->assocReqFrame); + pAssocReq->assocReqFrame = NULL; + } + + vos_mem_free(pAssocReq); + } + + /* If it is not duplicate Assoc request then only make to Null */ + if ((pStaDs != NULL) && + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + + return; + +} /*** end limProcessAssocReqFrame() ***/ + + + +/**--------------------------------------------------------------- +\fn limSendMlmAssocInd +\brief This function sends either LIM_MLM_ASSOC_IND +\ or LIM_MLM_REASSOC_IND to SME. +\ +\param pMac +\param *pStaDs - Station DPH hash entry +\param psessionEntry - PE session entry +\return None + + * ?????? How do I get + * - subtype =====> psessionEntry->parsedAssocReq.reassocRequest + * - aid =====> pStaDs->assocId + * - pHdr->sa =====> pStaDs->staAddr + * - authType + * - pHdr->seqControl =====> no longer needed + * - pStaDs +------------------------------------------------------------------*/ +void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tpLimMlmAssocInd pMlmAssocInd = NULL; + tpLimMlmReassocInd pMlmReassocInd; + tpSirAssocReq pAssocReq; + tANI_U16 temp; + tANI_U32 phyMode; + tANI_U8 subType; + tANI_U8 *wpsIe = NULL; + tANI_U32 tmp; +// tANI_U16 statusCode; + tANI_U16 i, j=0; + + // Get a copy of the already parsed Assoc Request + pAssocReq = (tpSirAssocReq) psessionEntry->parsedAssocReq[pStaDs->assocId]; + + // Get the phyMode + limGetPhyMode(pMac, &phyMode, psessionEntry); + // Extract pre-auth context for the peer BTAMP-STA, if any. + + // Determiine if its Assoc or ReAssoc Request + if (pAssocReq->reassocRequest == 1) + subType = LIM_REASSOC; + else + subType = LIM_ASSOC; + + limLog(pMac, LOG1, FL("Sessionid %d ssid %s subtype %d Associd %d staAddr " + MAC_ADDRESS_STR), psessionEntry->peSessionId, pAssocReq->ssId.ssId, + subType,pStaDs->assocId,MAC_ADDR_ARRAY(pStaDs->staAddr)); + + if (subType == LIM_ASSOC || subType == LIM_REASSOC) + { + temp = sizeof(tLimMlmAssocInd); + + pMlmAssocInd = vos_mem_malloc(temp); + if (NULL == pMlmAssocInd) + { + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + limLog(pMac, LOGP, FL("AllocateMemory failed for pMlmAssocInd")); + return; + } + vos_mem_set(pMlmAssocInd, temp ,0); + + vos_mem_copy((tANI_U8 *)pMlmAssocInd->peerMacAddr, + (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr)); + + pMlmAssocInd->aid = pStaDs->assocId; + vos_mem_copy((tANI_U8 *)&pMlmAssocInd->ssId, + (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1); + pMlmAssocInd->sessionId = psessionEntry->peSessionId; + pMlmAssocInd->authType = pStaDs->mlmStaContext.authType; + + pMlmAssocInd->capabilityInfo = pAssocReq->capabilityInfo; + + // Fill in RSN IE information + pMlmAssocInd->rsnIE.length = 0; + // if WPS IE is present, ignore RSN IE + if (pAssocReq->addIEPresent && pAssocReq->addIE.length ) { + wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + } + if (pAssocReq->rsnPresent && (NULL == wpsIe)) + { + limLog(pMac, LOG2, FL("Assoc Req RSN IE len = %d"), + pAssocReq->rsn.length); + pMlmAssocInd->rsnIE.length = 2 + pAssocReq->rsn.length; + pMlmAssocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID; + pMlmAssocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length; + vos_mem_copy(&pMlmAssocInd->rsnIE.rsnIEdata[2], + pAssocReq->rsn.info, + pAssocReq->rsn.length); + } + + // Fill in 802.11h related info + if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent) + { + pMlmAssocInd->spectrumMgtIndicator = eSIR_TRUE; + pMlmAssocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower; + pMlmAssocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower; + limConvertSupportedChannels(pMac, pMlmAssocInd, pAssocReq); + } + else + pMlmAssocInd->spectrumMgtIndicator = eSIR_FALSE; + + + /* This check is to avoid extra Sec IEs present incase of WPS */ + if (pAssocReq->wpaPresent && (NULL == wpsIe)) + { + if((pMlmAssocInd->rsnIE.length + pAssocReq->wpa.length) >= SIR_MAC_MAX_IE_LENGTH) + { + PELOGE(limLog(pMac, LOGE, FL("rsnIEdata index out of bounds %d"), + pMlmAssocInd->rsnIE.length);) + vos_mem_free(pMlmAssocInd); + return; + } + pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length] = SIR_MAC_WPA_EID; + pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 1] = pAssocReq->wpa.length; + vos_mem_copy(&pMlmAssocInd->rsnIE.rsnIEdata[pMlmAssocInd->rsnIE.length + 2], + pAssocReq->wpa.info, + pAssocReq->wpa.length); + pMlmAssocInd->rsnIE.length += 2 + pAssocReq->wpa.length; + } + + + pMlmAssocInd->addIE.length = 0; + if (pAssocReq->addIEPresent) + { + vos_mem_copy(&pMlmAssocInd->addIE.addIEdata, + pAssocReq->addIE.addIEdata, + pAssocReq->addIE.length); + + pMlmAssocInd->addIE.length = pAssocReq->addIE.length; + } + + if(pAssocReq->wmeInfoPresent) + { + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d"), + WNI_CFG_WME_ENABLED ); + + /* check whether AP is enabled with WMM */ + if(tmp) + { + pMlmAssocInd->WmmStaInfoPresent = 1; + } + else + { + pMlmAssocInd->WmmStaInfoPresent= 0; + } + /* Note: we are not rejecting association here because IOT will fail */ + + } +#ifdef WLAN_FEATURE_AP_HT40_24G + if(pAssocReq->HTCaps.present) + { + limLog(pMac, LOGW, FL("HT40MHzInto: %d"), + pAssocReq->HTCaps.stbcControlFrame); + pMlmAssocInd->HT40MHzIntoPresent = + pAssocReq->HTCaps.stbcControlFrame; + } +#endif + + // Required for indicating the frames to upper layer + pMlmAssocInd->assocReqLength = pAssocReq->assocReqFrameLength; + pMlmAssocInd->assocReqPtr = pAssocReq->assocReqFrame; + + pMlmAssocInd->beaconPtr = psessionEntry->beacon; + pMlmAssocInd->beaconLength = psessionEntry->bcnLen; + + pMlmAssocInd->rate_flags = + limGetMaxRateFlags(pStaDs, psessionEntry); + + limPostSmeMessage(pMac, LIM_MLM_ASSOC_IND, (tANI_U32 *) pMlmAssocInd); + vos_mem_free(pMlmAssocInd); + } + else + { + // If its of Reassociation Request, then post LIM_MLM_REASSOC_IND + temp = sizeof(tLimMlmReassocInd); + + pMlmReassocInd = vos_mem_malloc(temp); + if (NULL == pMlmReassocInd) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for " + "pMlmReassocInd")); + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry); + return; + } + vos_mem_set(pMlmReassocInd, temp, 0); + + vos_mem_copy((tANI_U8 *) pMlmReassocInd->peerMacAddr, + (tANI_U8 *)pStaDs->staAddr, sizeof(tSirMacAddr)); + vos_mem_copy((tANI_U8 *) pMlmReassocInd->currentApAddr, + (tANI_U8 *)&(pAssocReq->currentApAddr), sizeof(tSirMacAddr)); + pMlmReassocInd->aid = pStaDs->assocId; + pMlmReassocInd->authType = pStaDs->mlmStaContext.authType; + vos_mem_copy((tANI_U8 *)&pMlmReassocInd->ssId, + (tANI_U8 *)&(pAssocReq->ssId), pAssocReq->ssId.length + 1); + + if (pAssocReq->propIEinfo.aniIndicator) + pStaDs->aniPeer = 1; + + pMlmReassocInd->capabilityInfo = pAssocReq->capabilityInfo; + pMlmReassocInd->rsnIE.length = 0; + + if (pAssocReq->addIEPresent && pAssocReq->addIE.length ) + wpsIe = limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata, pAssocReq->addIE.length); + + if (pAssocReq->rsnPresent && (NULL == wpsIe)) + { + limLog(pMac, LOG2, FL("Assoc Req: RSN IE length = %d"), + pAssocReq->rsn.length); + pMlmReassocInd->rsnIE.length = 2 + pAssocReq->rsn.length; + pMlmReassocInd->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID; + pMlmReassocInd->rsnIE.rsnIEdata[1] = pAssocReq->rsn.length; + vos_mem_copy(&pMlmReassocInd->rsnIE.rsnIEdata[2], + pAssocReq->rsn.info, pAssocReq->rsn.length); + } + + // 802.11h support + if (pAssocReq->powerCapabilityPresent && pAssocReq->supportedChannelsPresent) + { + pMlmReassocInd->spectrumMgtIndicator = eSIR_TRUE; + pMlmReassocInd->powerCap.minTxPower = pAssocReq->powerCapability.minTxPower; + pMlmReassocInd->powerCap.maxTxPower = pAssocReq->powerCapability.maxTxPower; + pMlmReassocInd->supportedChannels.numChnl = (tANI_U8)(pAssocReq->supportedChannels.length / 2); + + limLog(pMac, LOG1, + FL("Sending Reassoc Ind: spectrum ON, minPwr %d, " + "maxPwr %d, numChnl %d"), + pMlmReassocInd->powerCap.minTxPower, + pMlmReassocInd->powerCap.maxTxPower, + pMlmReassocInd->supportedChannels.numChnl); + + for(i=0; i < pMlmReassocInd->supportedChannels.numChnl; i++) + { + pMlmReassocInd->supportedChannels.channelList[i] = pAssocReq->supportedChannels.supportedChannels[j]; + limLog(pMac, LOG1, FL("Sending ReassocInd: chn[%d] = %d "), + i, pMlmReassocInd->supportedChannels.channelList[i]); + j+=2; + } + } + else + pMlmReassocInd->spectrumMgtIndicator = eSIR_FALSE; + + + /* This check is to avoid extra Sec IEs present incase of WPS */ + if (pAssocReq->wpaPresent && (NULL == wpsIe)) + { + limLog(pMac, LOG2, FL("Received WPA IE length in Assoc Req is %d"), + pAssocReq->wpa.length); + pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length] = SIR_MAC_WPA_EID; + pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 1] = pAssocReq->wpa.length; + vos_mem_copy(&pMlmReassocInd->rsnIE.rsnIEdata[pMlmReassocInd->rsnIE.length + 2], + pAssocReq->wpa.info, + pAssocReq->wpa.length); + pMlmReassocInd->rsnIE.length += 2 + pAssocReq->wpa.length; + } + + pMlmReassocInd->addIE.length = 0; + if (pAssocReq->addIEPresent) + { + vos_mem_copy(&pMlmReassocInd->addIE.addIEdata, + pAssocReq->addIE.addIEdata, + pAssocReq->addIE.length); + + pMlmReassocInd->addIE.length = pAssocReq->addIE.length; + } + + if(pAssocReq->wmeInfoPresent) + { + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WME_ENABLED, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("wlan_cfgGetInt failed for id %d"), + WNI_CFG_WME_ENABLED ); + + /* check whether AP is enabled with WMM */ + if(tmp) + { + pMlmReassocInd->WmmStaInfoPresent = 1; + } + else + { + pMlmReassocInd->WmmStaInfoPresent = 0; + } + /* Note: we are not rejecting Re-association here because IOT will fail */ + + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if(pAssocReq->HTCaps.present) + { + limLog(pMac, LOGW, FL("RASSOC HT40MHzInto: %d"), + pAssocReq->HTCaps.stbcControlFrame); + pMlmReassocInd->HT40MHzIntoPresent = + pAssocReq->HTCaps.stbcControlFrame; + } +#endif + + // Required for indicating the frames to upper layer + pMlmReassocInd->assocReqLength = pAssocReq->assocReqFrameLength; + pMlmReassocInd->assocReqPtr = pAssocReq->assocReqFrame; + + pMlmReassocInd->beaconPtr = psessionEntry->beacon; + pMlmReassocInd->beaconLength = psessionEntry->bcnLen; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_IND, (tANI_U32 *) pMlmReassocInd); + vos_mem_free(pMlmReassocInd); + } + + return; + +} /*** end limSendMlmAssocInd() ***/ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c new file mode 100644 index 000000000000..ccc8ec710419 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c @@ -0,0 +1,1037 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessAssocRspFrame.cc contains the code + * for processing Re/Association Response Frame. + * Author: Chandra Modumudi + * Date: 03/18/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniApi.h" +#include "wniCfg.h" +#include "aniGlobal.h" +#include "cfgApi.h" + +#include "utilsApi.h" +#include "pmmApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limStaHashApi.h" +#include "limSendMessages.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + +extern tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry); + + +/** + * @function : limUpdateAssocStaDatas + * + * @brief : This function is called to Update the Station Descriptor (dph) Details from + * Association / ReAssociation Response Frame + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Station Descriptor in DPH + * @param pAssocRsp - Pointer to Association Response Structure + * + * @return None + */ +void limUpdateAssocStaDatas(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpSirAssocRsp pAssocRsp,tpPESession psessionEntry) +{ + tANI_U32 prop; + tANI_U32 phyMode; + tANI_U32 val; + //tpSirBoardCapabilities pBoardCaps; + tANI_BOOLEAN qosMode; + tANI_U16 rxHighestRate = 0; + uint32_t shortgi_20mhz_support; + uint32_t shortgi_40mhz_support; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + pStaDs->staType= STA_ENTRY_SELF; + + limGetQosMode(psessionEntry, &qosMode); + // set the ani peer bit, if self mode is one of the proprietary modes + if(IS_DOT11_MODE_PROPRIETARY(psessionEntry->dot11mode)) + { + wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, &prop); + + if (prop) + { + pStaDs->aniPeer = eHAL_SET; + pStaDs->propCapability = pAssocRsp->propIEinfo.capability; + } + } + + //pMac->lim.gLimMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + pStaDs->mlmStaContext.authType = psessionEntry->limCurrentAuthType; + + // Add capabilities information, rates and AID + pStaDs->mlmStaContext.capabilityInfo = pAssocRsp->capabilityInfo; + pStaDs->shortPreambleEnabled= (tANI_U8)pAssocRsp->capabilityInfo.shortPreamble; + + //Update HT Capabilites only when the self mode supports HT + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) { + pStaDs->mlmStaContext.htCapability = pAssocRsp->HTCaps.present; + + if ( pAssocRsp->HTCaps.present ) { + pStaDs->htGreenfield = ( tANI_U8 ) pAssocRsp->HTCaps.greenField; + if (psessionEntry->htSupportedChannelWidthSet) + { + pStaDs->htSupportedChannelWidthSet = ( tANI_U8 ) (pAssocRsp->HTCaps.supportedChannelWidthSet ? + pAssocRsp->HTInfo.recommendedTxWidthSet : + pAssocRsp->HTCaps.supportedChannelWidthSet ); + } + else + { + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + } + pStaDs->htLsigTXOPProtection = ( tANI_U8 ) pAssocRsp->HTCaps.lsigTXOPProtection; + pStaDs->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pAssocRsp->HTCaps.mimoPowerSave; + pStaDs->htMaxAmsduLength = ( tANI_U8 ) pAssocRsp->HTCaps.maximalAMSDUsize; + pStaDs->htAMpduDensity = pAssocRsp->HTCaps.mpduDensity; + pStaDs->htDsssCckRate40MHzSupport = (tANI_U8)pAssocRsp->HTCaps.dsssCckMode40MHz; + pStaDs->htMaxRxAMpduFactor = pAssocRsp->HTCaps.maxRxAMPDUFactor; + limFillRxHighestSupportedRate(pMac, &rxHighestRate, pAssocRsp->HTCaps.supportedMCSSet); + pStaDs->supportedRates.rxHighestDataRate = rxHighestRate; + /* This is for AP as peer STA and we are INFRA STA. We will put APs offset in dph node which is peer STA */ + pStaDs->htSecondaryChannelOffset = (tANI_U8)pAssocRsp->HTInfo.secondaryChannelOffset; + + //FIXME_AMPDU + // In the future, may need to check for "assoc.HTCaps.delayedBA" + // For now, it is IMMEDIATE BA only on ALL TID's + pStaDs->baPolicyFlag = 0xFF; + + /* + * Check if we have support for gShortGI20Mhz and + * gShortGI40Mhz from ini file. + */ + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, + WNI_CFG_SHORT_GI_20MHZ, + &shortgi_20mhz_support))) { + if (VOS_TRUE == shortgi_20mhz_support) + pStaDs->htShortGI20Mhz = + (tANI_U8)pAssocRsp->HTCaps.shortGI20MHz; + else + pStaDs->htShortGI20Mhz = VOS_FALSE; + } else { + limLog(pMac, LOGE, + FL("could not retrieve shortGI 20Mhz CFG," + "setting value to default")); + pStaDs->htShortGI20Mhz = WNI_CFG_SHORT_GI_20MHZ_STADEF; + } + + if (HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, + WNI_CFG_SHORT_GI_40MHZ, + &shortgi_40mhz_support))) { + if (VOS_TRUE == shortgi_40mhz_support) + pStaDs->htShortGI40Mhz = + (tANI_U8)pAssocRsp->HTCaps.shortGI40MHz; + else + pStaDs->htShortGI40Mhz = VOS_FALSE; + } else { + limLog(pMac, LOGE, + FL("could not retrieve shortGI 40Mhz CFG," + "setting value to default")); + pStaDs->htShortGI40Mhz = WNI_CFG_SHORT_GI_40MHZ_STADEF; + } + + } + } + +#ifdef WLAN_FEATURE_11AC + if(IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) + { + pStaDs->mlmStaContext.vhtCapability = pAssocRsp->VHTCaps.present; + if (pAssocRsp->VHTCaps.present && psessionEntry->htSupportedChannelWidthSet) + pStaDs->vhtSupportedChannelWidthSet = pAssocRsp->VHTOperation.chanWidth; + } + if (limPopulatePeerRateSet(pMac, &pStaDs->supportedRates, + pAssocRsp->HTCaps.supportedMCSSet, + false,psessionEntry , &pAssocRsp->VHTCaps) != eSIR_SUCCESS) +#else + if (limPopulatePeerRateSet(pMac, &pStaDs->supportedRates, pAssocRsp->HTCaps.supportedMCSSet, false,psessionEntry) != eSIR_SUCCESS) +#endif + { + limLog(pMac, LOGP, FL("could not get rateset and extended rate set")); + return; + } + + //If one of the rates is 11g rates, set the ERP mode. + if ((phyMode == WNI_CFG_PHY_MODE_11G) && sirIsArate(pStaDs->supportedRates.llaRates[0] & 0x7f)) + pStaDs->erpEnabled = eHAL_SET; + + + val = WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pStaDs->mlmStaContext.propRateSet.propRate, + &val) != eSIR_SUCCESS) { + /// Could not get prop rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve prop rateset")); + return; + } + pStaDs->mlmStaContext.propRateSet.numPropRates = (tANI_U8) val; + + pStaDs->qosMode = 0; + pStaDs->lleEnabled = 0; + + // update TSID to UP mapping + //if (pMac->lim.gLimQosEnabled) + if (qosMode) { + if (pAssocRsp->edcaPresent) { + tSirRetStatus status; + status = schBeaconEdcaProcess(pMac,&pAssocRsp->edca, psessionEntry); + PELOG2(limLog(pMac, LOG2, "Edca set update based on AssocRsp: status %d", + status);) + if (status != eSIR_SUCCESS) { + PELOGE(limLog(pMac, LOGE, FL("Edca error in AssocResp "));) + } else { // update default tidmap based on ACM + pStaDs->qosMode = 1; + pStaDs->lleEnabled = 1; + } + } + } + + pStaDs->wmeEnabled = 0; + pStaDs->wsmEnabled = 0; + if (psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) + { + tSirRetStatus status; + status = schBeaconEdcaProcess(pMac,&pAssocRsp->edca, psessionEntry); + PELOGW(limLog(pMac, LOGW, "WME Edca set update based on AssocRsp: status %d", status);) + + if (status != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("WME Edca error in AssocResp - ignoring"));) + else { // update default tidmap based on HashACM + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 1; + } + } + else { + /* We received assoc rsp from a legacy AP. So fill in the default + * local EDCA params. This is needed (refer to bug #14989) as we'll + * be passing the gLimEdcaParams to HAL in limProcessStaMlmAddBssRsp(). + */ + schSetDefaultEdcaParams(pMac, psessionEntry); + } + + if(qosMode && (!pStaDs->qosMode) && pStaDs->mlmStaContext.htCapability) + { + // Enable QOS for all HT AP's even though WMM or 802.11E IE is not present + pStaDs->qosMode = 1; + pStaDs->wmeEnabled = 1; + } + +#ifdef WLAN_FEATURE_11W + if(psessionEntry->limRmfEnabled) + { + pStaDs->rmfEnabled = 1; + } +#endif +} + +/** + * @function : limUpdateReAssocGlobals + * + * @brief : This function is called to Update the Globals (LIM) during ReAssoc. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pAssocRsp - Pointer to Association Response Structure + * + * @return None + */ + +void limUpdateReAssocGlobals(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,tpPESession psessionEntry) +{ + /** + * Update the status for PMM module + */ + pmmResetPmmState(pMac); + + // Update the current Bss Information + vos_mem_copy(psessionEntry->bssId, + psessionEntry->limReAssocbssId, sizeof(tSirMacAddr)); + psessionEntry->currentOperChannel = psessionEntry->limReassocChannelId; + psessionEntry->htSecondaryChannelOffset = psessionEntry->reAssocHtSupportedChannelWidthSet; + psessionEntry->htRecommendedTxWidthSet = psessionEntry->reAssocHtRecommendedTxWidthSet; + psessionEntry->htSecondaryChannelOffset = psessionEntry->reAssocHtSecondaryChannelOffset; + psessionEntry->limCurrentBssCaps = psessionEntry->limReassocBssCaps; + psessionEntry->limCurrentBssQosCaps = psessionEntry->limReassocBssQosCaps; + psessionEntry->limCurrentBssPropCap = psessionEntry->limReassocBssPropCap; + + vos_mem_copy((tANI_U8 *) &psessionEntry->ssId, + (tANI_U8 *) &psessionEntry->limReassocSSID, + psessionEntry->limReassocSSID.length+1); + + // Store assigned AID for TIM processing + psessionEntry->limAID = pAssocRsp->aid & 0x3FFF; + /** Set the State Back to ReAssoc Rsp*/ + psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + +} + +/** + * @function : limProcessAssocRspFrame + * + * @brief : This function is called by limProcessMessageQueue() upon + * Re/Association Response frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Rx packet info structure + * @param subType - Indicates whether it is Association Response (=0) or + * Reassociation Response (=1) frame + * + * @return None + */ + +void +limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 subType,tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U16 caps; + tANI_U32 frameLen; + tSirMacAddr currentBssId; + tpSirMacMgmtHdr pHdr; + tSirMacCapabilityInfo localCapabilities; + tpDphHashNode pStaDs; + tpSirAssocRsp pAssocRsp; + tLimMlmAssocCnf mlmAssocCnf; + + tSchBeaconStruct *pBeaconStruct; + + //Initialize status code to success. + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + mlmAssocCnf.resultCode = eSIR_SME_SUCCESS; + /* Update PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + limLog(pMac, LOG1, + FL("received Re/Assoc(%d) resp on sessionid: %d with systemrole: %d " + "and mlmstate: %d RSSI %d from "MAC_ADDRESS_STR),subType, + psessionEntry->peSessionId, + psessionEntry->limSystemRole,psessionEntry->limMlmState, + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo)), + MAC_ADDR_ARRAY(pHdr->sa)); + + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("Unable to allocate memory") ); + return; + } + + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE ) + { + // Should not have received Re/Association Response + // frame on AP. Log error + limLog(pMac, LOGE, + FL("Should not recieved Re/Assoc Response in role %d "), + psessionEntry->limSystemRole); + + vos_mem_free(pBeaconStruct); + return; + } + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (((subType == LIM_ASSOC) && + (psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE)) || + ((subType == LIM_REASSOC) && + ((psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + && (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE) +#endif + ))) + { + /// Received unexpected Re/Association Response frame + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("Recieved Re/Assoc rsp in unexpected " + "state %d on session=%d"), + psessionEntry->limMlmState, psessionEntry->peSessionId); +#endif + // Log error + if (!pHdr->fc.retry) + { + if ( !(pMac->lim.retryPacketCnt & 0xf)) + { + limLog(pMac, LOGE, + FL("received Re/Assoc rsp frame is not a retry frame, " + "frame count %d"), ++pMac->lim.retryPacketCnt); + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + } + else + { + pMac->lim.retryPacketCnt++; + } + + } + vos_mem_free(pBeaconStruct); + return; + } +#if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != + eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + vos_mem_free(pBeaconStruct); + return; + } +#endif //TO SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if (subType == LIM_ASSOC) + { + if (!vos_mem_compare(pHdr->sa, currentBssId, sizeof(tSirMacAddr))) + { + /** + * Received Association Response frame from an entity + * other than one to which request was initiated. + * Ignore this and wait until Association Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received AssocRsp frame from unexpected peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + vos_mem_free(pBeaconStruct); + return; + } + } + else + { + if (!vos_mem_compare(pHdr->sa, psessionEntry->limReAssocbssId, sizeof(tSirMacAddr))) + { + /** + * Received Reassociation Response frame from an entity + * other than one to which request was initiated. + * Ignore this and wait until Reassociation Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received ReassocRsp frame from unexpected peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + vos_mem_free(pBeaconStruct); + + return; + } + } + + pAssocRsp = vos_mem_malloc(sizeof(*pAssocRsp)); + if (NULL == pAssocRsp) + { + limLog(pMac, LOGP, FL("Allocate Memory failed in AssocRsp")); + vos_mem_free(pBeaconStruct); + + return; + } + + // Get pointer to Re/Association Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + // parse Re/Association Response frame. + if (sirConvertAssocRespFrame2Struct( + pMac, pBody, frameLen, pAssocRsp) == eSIR_FAILURE) + { + vos_mem_free(pAssocRsp); + PELOGE(limLog(pMac, LOGE, FL("Parse error Assoc resp subtype %d," + "length=%d"), frameLen,subType);) + vos_mem_free(pBeaconStruct); + + return; + } + if(pAssocRsp->ExtCap.present) + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *) + pAssocRsp->ExtCap.bytes; + limLog(pMac, LOG1, + FL("Filling tdls prohibited in session entry")); + psessionEntry->tdlsChanSwitProhibited = + p_ext_cap->TDLSChanSwitProhibited; + } + if(!pAssocRsp->suppRatesPresent) + { + PELOGE(limLog(pMac, LOGE, FL("assoc response does not have supported rate set"));) + vos_mem_copy(&pAssocRsp->supportedRates, + &psessionEntry->rateSet, sizeof(tSirMacRateSet)); + } + + mlmAssocCnf.protStatusCode = pAssocRsp->statusCode; + + if( psessionEntry->assocRsp != NULL ) + { + limLog(pMac, LOGW, FL("psessionEntry->assocRsp is not NULL freeing it " + "and setting NULL")); + vos_mem_free(psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } + + if (frameLen) { + psessionEntry->assocRsp = vos_mem_malloc(frameLen); + if (NULL == psessionEntry->assocRsp) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response, len = %d"), frameLen);) + } + else + { + //Store the Assoc response. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->assocRsp, pBody, frameLen); + psessionEntry->assocRspLen = frameLen; + } + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (psessionEntry->ricData != NULL) + { + vos_mem_free(psessionEntry->ricData); + psessionEntry->ricData = NULL; + } + if(pAssocRsp->ricPresent) + { + psessionEntry->RICDataLen = pAssocRsp->num_RICData * sizeof(tDot11fIERICDataDesc); + if (psessionEntry->RICDataLen) + { + psessionEntry->ricData = vos_mem_malloc(psessionEntry->RICDataLen); + if ( NULL == psessionEntry->ricData ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));) + psessionEntry->RICDataLen = 0; + } + else + { + vos_mem_copy(psessionEntry->ricData, + &pAssocRsp->RICData[0], psessionEntry->RICDataLen); + } + } + } + else + { + limLog(pMac, LOG1, FL("Ric is not present Setting RICDataLen 0 and ricData " + "as NULL")); + psessionEntry->RICDataLen = 0; + psessionEntry->ricData = NULL; + } +#endif + +#ifdef FEATURE_WLAN_ESE + if (psessionEntry->tspecIes != NULL) + { + vos_mem_free(psessionEntry->tspecIes); + psessionEntry->tspecIes = NULL; + } + if(pAssocRsp->tspecPresent) + { + psessionEntry->tspecLen = pAssocRsp->num_tspecs * sizeof(tDot11fIEWMMTSPEC); + psessionEntry->tspecIes = vos_mem_malloc(psessionEntry->tspecLen); + if ( NULL == psessionEntry->tspecIes ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc response"));) + psessionEntry->tspecLen = 0; + } + else + { + vos_mem_copy(psessionEntry->tspecIes, + &pAssocRsp->TSPECInfo[0], psessionEntry->tspecLen); + } + limLog(pMac, LOG1, FL(" Tspec EID present in assoc rsp ")); + } + else + { + psessionEntry->tspecLen = 0; + psessionEntry->tspecIes = NULL; + limLog(pMac, LOG1, FL(" Tspec EID *NOT* present in assoc rsp ")); + } +#endif + + if (pAssocRsp->capabilityInfo.ibss) + { + /** + * Received Re/Association Response from peer + * with IBSS capability set. + * Ignore the frame and wait until Re/assoc + * failure timeout. + */ + + // Log error + limLog(pMac, LOGE, + FL("received Re/AssocRsp frame with IBSS capability")); + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + + return; + } + + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) + { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + + limLog(pMac, LOGP, FL("could not retrieve Capabilities value")); + return; + } + limCopyU16((tANI_U8 *) &localCapabilities, caps); + + if (subType == LIM_ASSOC) // Stop Association failure timer + limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER); + else // Stop Reassociation failure timer + { +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_MBB_RSP_TIMER); +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->lim.reAssocRetryAttempt = 0; + if ((NULL != pMac->lim.pSessionEntry) && (NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq)) + { + vos_mem_free(pMac->lim.pSessionEntry->pLimMlmReassocRetryReq); + pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL; + } +#endif + + /* Dactivate timer when it is not LFR MBB */ + if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb) + limDeactivateAndChangeTimer(pMac, eLIM_REASSOC_FAIL_TIMER); + } + + if (pAssocRsp->statusCode != eSIR_MAC_SUCCESS_STATUS) + { + // Re/Association response was received + // either with failure code. + // Log error. + PELOGE(limLog(pMac, LOGE, FL("received Re/AssocRsp frame failure code %d"), pAssocRsp->statusCode);) + // Need to update 'association failure' error counter + // along with STATUS CODE + + // Return Assoc confirm to SME with received failure code + + if (pAssocRsp->propIEinfo.loadBalanceInfoPresent) + { + mlmAssocCnf.resultCode = eSIR_SME_TRANSFER_STA; + vos_mem_copy(pMac->lim.gLimAlternateRadio.bssId, + pAssocRsp->propIEinfo.alternateRadio.bssId, sizeof(tSirMacAddr)); + pMac->lim.gLimAlternateRadio.channelId = + pAssocRsp->propIEinfo.alternateRadio.channelId; + }else + mlmAssocCnf.resultCode = eSIR_SME_ASSOC_REFUSED; + + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) + goto assocReject; + + // Delete Pre-auth context for the associated BSS + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + goto assocReject; + } + else if ((pAssocRsp->aid & 0x3FFF) > 2007) + { + // Re/Association response was received + // with invalid AID value + // Log error + PELOGW(limLog(pMac, LOGE, FL("received Re/AssocRsp frame with" + "invalid aid %X"), pAssocRsp->aid);) + mlmAssocCnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + // Send advisory Disassociation frame to AP + limSendDisassocMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + pHdr->sa, psessionEntry, FALSE); + + goto assocReject; + } + // Association Response received with success code + /* + * Set the link state to POSTASSOC now that we have received + * assoc/reassoc response + * NOTE: for BTAMP case, it is being handled in limProcessMlmAssocReq + */ + if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + if (!((psessionEntry->bssType == eSIR_BTAMP_STA_MODE) || + ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) && + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)))) + { + if (limSetLinkState(pMac, eSIR_LINK_POSTASSOC_STATE, + psessionEntry->bssId, + psessionEntry->selfMacAddr, + NULL, NULL) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Set link state to POSTASSOC failed"));) + vos_mem_free(pBeaconStruct); + vos_mem_free(pAssocRsp); + return; + } + } + } + if (subType == LIM_REASSOC) + { + // Log success + limLog(pMac, LOG1, FL("Successfully Reassociated with BSS")); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, + psessionEntry, eSIR_SUCCESS, eSIR_SUCCESS); +#endif +#ifdef FEATURE_WLAN_ESE + { + tANI_U8 cnt = 0; + if (pAssocRsp->tsmPresent) + { + limLog(pMac, LOG1, "TSM IE Present in Reassoc Rsp"); + // Start the TSM timer only if the TSPEC Ie is present in the reassoc rsp + if (pAssocRsp->tspecPresent) { + // Find the TSPEC IE with VO user priority + for (cnt=0; cntnum_tspecs; cnt++) { + if ( upToAc(pAssocRsp->TSPECInfo[cnt].user_priority) == EDCA_AC_VO) { + psessionEntry->eseContext.tsm.tid = pAssocRsp->TSPECInfo[cnt].user_priority; + vos_mem_copy(&psessionEntry->eseContext.tsm.tsmInfo, + &pAssocRsp->tsmIE, sizeof(tSirMacESETSMIE)); +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, + psessionEntry, + pAssocRsp->tsmIE.tsid, + pAssocRsp->tsmIE.state, + pAssocRsp->tsmIE.msmt_interval); +#else + limActivateTSMStatsTimer(pMac, psessionEntry); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + if(psessionEntry->eseContext.tsm.tsmInfo.state) { + psessionEntry->eseContext.tsm.tsmMetrics.RoamingCount++; + } + break; + } + } + } else { + limLog(pMac, LOGE, "TSM present but TSPEC IE not present in Reassoc Rsp"); + } + } + } +#endif + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + psessionEntry->limAssocResponseData = (void *) pAssocRsp; /** Store the ReAssocRsp Frame in DphTable to be used + during processing DelSta nd DelBss to send AddBss again*/ + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + if(!pStaDs) + { + PELOGE(limLog(pMac, LOGE, FL("could not get hash entry at DPH for"));) + limPrintMacAddr(pMac, pHdr->sa, LOGE); + mlmAssocCnf.resultCode = eSIR_SME_INVALID_ASSOC_RSP_RXED; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + // Send advisory Disassociation frame to AP + limSendDisassocMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + pHdr->sa, psessionEntry, FALSE); + + goto assocReject; + } + +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + limLog(pMac, LOG1, FL("Reassoc success for LFR MBB in state %d"), + psessionEntry->limMlmState); + if (psessionEntry->limMlmState == + eLIM_MLM_WT_REASSOC_RSP_STATE) { + lim_handle_reassoc_mbb_success(pMac, psessionEntry, + pAssocRsp, pStaDs); + return; + } + goto assocReject; + } +#endif + + +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("Sending self sta"));) +#endif + pmmResetPmmState(pMac); + + limUpdateAssocStaDatas(pMac, pStaDs, pAssocRsp,psessionEntry); + + // Store assigned AID for TIM processing + psessionEntry->limAID = pAssocRsp->aid & 0x3FFF; + + // Downgrade the EDCA parameters if needed + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + // Send the active EDCA parameters to HAL + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + } + else + { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + limAddFTStaSelf(pMac, (pAssocRsp->aid & 0x3FFF), psessionEntry); + vos_mem_free(pBeaconStruct); + + return; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + /* If we're re-associating to the same BSS, we don't want to invoke delete + * STA, delete BSS, as that would remove the already established TSPEC. + * Just go ahead and re-add the BSS, STA with new capability information. + * However, if we're re-associating to a different BSS, then follow thru + * with del STA, del BSS, add BSS, add STA. + */ + if (sirCompareMacAddr( psessionEntry->bssId, psessionEntry->limReAssocbssId)) + limHandleAddBssInReAssocContext(pMac, pStaDs, psessionEntry); + else + { + // reset the uapsd mask settings since we're re-associating to new AP + pMac->lim.gUapsdPerAcDeliveryEnableMask = 0; + pMac->lim.gUapsdPerAcTriggerEnableMask = 0; + + if (limCleanupRxPath(pMac, pStaDs,psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Could not cleanup the rx path"));) + goto assocReject; + } + } + vos_mem_free(pBeaconStruct); + + return; + } + + // Log success + limLog(pMac, LOG1, FL("Successfully Associated with BSS "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); +#ifdef FEATURE_WLAN_ESE + if(psessionEntry->eseContext.tsm.tsmInfo.state) + { + psessionEntry->eseContext.tsm.tsmMetrics.RoamingCount = 0; + } +#endif + /** + * Update the status for PMM module + */ + pmmResetPmmState(pMac); + + // Store assigned AID for TIM processing + psessionEntry->limAID = pAssocRsp->aid & 0x3FFF; + + + //STA entry was created during pre-assoc state. + if ((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not get hash entry at DPH for "));) + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmAssocCnf.protStatusCode = eSIR_SME_SUCCESS; + + + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, + (tANI_U32 *) &mlmAssocCnf); + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + + return; + } + + // Delete Pre-auth context for the associated BSS + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + limUpdateAssocStaDatas(pMac, pStaDs, pAssocRsp,psessionEntry); + // Extract the AP capabilities from the beacon that was received earlier + // TODO - Watch out for an error response! + limExtractApCapabilities(pMac, + (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields, + GET_IE_LEN_IN_BSS(psessionEntry->pLimJoinReq->bssDescription.length), + pBeaconStruct); + + if (pBeaconStruct->VHTCaps.present) + pStaDs->parsed_ies.vht_caps = pBeaconStruct->VHTCaps; + if (pBeaconStruct->HTCaps.present) + pStaDs->parsed_ies.ht_caps = pBeaconStruct->HTCaps; + if (pBeaconStruct->hs20vendor_ie.present) + pStaDs->parsed_ies.hs20vendor_ie = + pBeaconStruct->hs20vendor_ie; + if (pBeaconStruct->HTInfo.present) + pStaDs->parsed_ies.ht_operation = pBeaconStruct->HTInfo; + if (pBeaconStruct->VHTOperation.present) + pStaDs->parsed_ies.vht_operation = pBeaconStruct->VHTOperation; + + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + + if(pBeaconStruct->erpPresent) { + if (pBeaconStruct->erpIEInfo.barkerPreambleMode) + psessionEntry->beaconParams.fShortPreamble = false; + else + psessionEntry->beaconParams.fShortPreamble = true; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_CONNECTED, psessionEntry, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + + if(pAssocRsp->OBSSScanParameters.present) + { + limUpdateOBSSScanParams(psessionEntry , &pAssocRsp->OBSSScanParameters); + } + + if( pAssocRsp->QosMapSet.present ) + { + vos_mem_copy(&psessionEntry->QosMapSet, + &pAssocRsp->QosMapSet, + sizeof(tSirQosMapSet)); + } + else + { + vos_mem_zero(&psessionEntry->QosMapSet, sizeof(tSirQosMapSet)); + } + + //Update the BSS Entry, this entry was added during preassoc. + if( eSIR_SUCCESS == limStaSendAddBss( pMac, pAssocRsp, pBeaconStruct, + &psessionEntry->pLimJoinReq->bssDescription, true, psessionEntry)) + { + vos_mem_free(pAssocRsp); + vos_mem_free(pBeaconStruct); + return; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("could not update the bss entry"));) + mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + } + + + +assocReject: + if ((subType == LIM_ASSOC) +#ifdef WLAN_FEATURE_VOWIFI_11R + || ((subType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)) +#endif + ) { + PELOGE(limLog(pMac, LOGE, FL("Assoc Rejected by the peer. " + "mlmestate: %d sessionid %d Reason: %d MACADDR:" + MAC_ADDRESS_STR), psessionEntry->limMlmState, + psessionEntry->peSessionId, mlmAssocCnf.resultCode, + MAC_ADDR_ARRAY(pHdr->sa));) + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + if (subType == LIM_ASSOC) + { + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + } +#ifdef WLAN_FEATURE_VOWIFI_11R + else + { + mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + } else { +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_handle_reassoc_mbb_fail(pMac, psessionEntry); + vos_mem_free(pBeaconStruct); + vos_mem_free(pAssocRsp); + return; + } +#endif + limRestorePreReassocState( pMac, + eSIR_SME_REASSOC_REFUSED, mlmAssocCnf.protStatusCode,psessionEntry); + } + + /* CR: vos packet memory is leaked when assoc rsp timeouted/failed. */ + /* notify TL that association is failed so that TL can flush the cached frame */ + limLog(pMac, LOG1, FL("notify TL that association is failed")); + WLANTL_AssocFailed (psessionEntry->staId); + + vos_mem_free(pBeaconStruct); + vos_mem_free(pAssocRsp); + return; +} /*** end limProcessAssocRspFrame() ***/ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c new file mode 100644 index 000000000000..04d676d81394 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessAuthFrame.c @@ -0,0 +1,2021 @@ +/* + * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessAuthFrame.cc contains the code + * for processing received Authentication Frame. + * Author: Chandra Modumudi + * Date: 03/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/12/2010 js To support Shared key authentication at AP side + * + */ + +#include "wniApi.h" +#include "wniCfg.h" +#include "aniGlobal.h" +#include "cfgApi.h" + +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "limFT.h" +#endif +#include "vos_utils.h" +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + +/** + * isAuthValid + * + *FUNCTION: + * This function is called by limProcessAuthFrame() upon Authentication + * frame reception. + * + *LOGIC: + * This function is used to test validity of auth frame: + * - AUTH1 and AUTH3 must be received in AP mode + * - AUTH2 and AUTH4 must be received in STA mode + * - AUTH3 and AUTH4 must have challenge text IE, that is,'type' field has been set to + * SIR_MAC_CHALLENGE_TEXT_EID by parser + * - + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param *auth - Pointer to extracted auth frame body + * + * @return 0 or 1 (Valid) + */ + + +static inline unsigned int isAuthValid(tpAniSirGlobal pMac, tpSirMacAuthFrameBody auth,tpPESession sessionEntry) { + unsigned int valid; + valid=1; + + if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_1)|| + (auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)) && + ((sessionEntry->limSystemRole == eLIM_STA_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))) + valid=0; + + if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_2)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&& + ((sessionEntry->limSystemRole == eLIM_AP_ROLE)||(sessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE))) + valid=0; + + if ( ((auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_3)||(auth->authTransactionSeqNumber==SIR_MAC_AUTH_FRAME_4))&& + (auth->type!=SIR_MAC_CHALLENGE_TEXT_EID)&&(auth->authAlgoNumber != eSIR_SHARED_KEY)) + valid=0; + + return valid; +} + + +/** + * limProcessAuthFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon Authentication + * frame reception. + * + *LOGIC: + * This function processes received Authentication frame and responds + * with either next Authentication frame in sequence to peer MAC entity + * or LIM_MLM_AUTH_IND on AP or LIM_MLM_AUTH_CNF on STA. + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Authentication failures are reported to SME with same status code + * received from the peer MAC entity. + * 2. Authentication frame2/4 received with alogirthm number other than + * one requested in frame1/3 are logged with an error and auth confirm + * will be sent to SME only after auth failure timeout. + * 3. Inconsistency in the spec: + * On receiving Auth frame2, specs says that if WEP key mapping key + * or default key is NULL, Auth frame3 with a status code 15 (challenge + * failure to be returned to peer entity. However, section 7.2.3.10, + * table 14 says that status code field is 'reserved' for frame3 ! + * In the current implementation, Auth frame3 is returned with status + * code 15 overriding section 7.2.3.10. + * 4. If number pre-authentications reach configrable max limit, + * Authentication frame with 'unspecified failure' status code is + * returned to requesting entity. + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Rx packet info structure + * @return None + */ + +void +limProcessAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tANI_U8 *pBody, keyId, cfgPrivacyOptImp, + defaultKey[SIR_MAC_KEY_LENGTH], + *encrAuthFrame = NULL, + *plainBody = NULL; + tANI_U16 frameLen; + //tANI_U32 authRspTimeout, maxNumPreAuth, val; + tANI_U32 maxNumPreAuth, val; + tSirMacAuthFrameBody *pRxAuthFrameBody, + *rxAuthFrame = NULL, + *authFrame = NULL; + tpSirMacMgmtHdr pHdr; + tCfgWepKeyEntry *pKeyMapEntry = NULL; + struct tLimPreAuthNode *pAuthNode; + tLimMlmAuthInd mlmAuthInd; + tANI_U8 decryptResult; + tANI_U8 *pChallenge; + tANI_U32 key_length=8; + tANI_U8 *challengeTextArray = NULL; + tpDphHashNode pStaDs = NULL; + tANI_U16 assocId = 0; + tANI_U16 currSeqNo = 0; + /* Added For BT -AMP support */ + // Get pointer to Authentication frame header and body + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (!frameLen) + { + // Log error + limLog(pMac, LOGE, + FL("received Authentication frame with no body from ")); + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + return; + } + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Auth frame from a BC/MC address + // Log error and ignore it + limLog(pMac, LOGE, + FL("received Auth frame from a BC/MC address - ")); + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + return; + } + currSeqNo = (pHdr->seqControl.seqNumHi << 4) | (pHdr->seqControl.seqNumLo); + limLog(pMac, LOG1, + FL("Sessionid: %d System role : %d limMlmState: %d :Auth " + "Frame Received: BSSID: "MAC_ADDRESS_STR " (RSSI %d)"), + psessionEntry->peSessionId, psessionEntry->limSystemRole, + psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo))); + + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + //PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, (tANI_U8*)pBd, ((tpHalBufDesc) pBd)->mpduDataOffset + frameLen);) + + //Restore default failure timeout + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && psessionEntry->defaultAuthFailureTimeout) + { + limLog(pMac, LOG1, FL("Restore default failure timeout")); + ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT , + psessionEntry->defaultAuthFailureTimeout, NULL, eANI_BOOLEAN_FALSE); + } + + rxAuthFrame = vos_mem_malloc(sizeof(tSirMacAuthFrameBody)); + if (!rxAuthFrame) { + limLog(pMac, LOGE, FL("Failed to allocate memory")); + return; + } + + authFrame = vos_mem_malloc(sizeof(tSirMacAuthFrameBody)); + if (!authFrame) { + limLog(pMac, LOGE, FL("failed to allocate memory")); + goto free; + } + + plainBody = vos_mem_malloc(LIM_ENCR_AUTH_BODY_LEN); + if (!plainBody) { + limLog(pMac, LOGE, FL("failed to allocate memory")); + goto free; + } + + challengeTextArray = vos_mem_malloc(SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH); + if(!challengeTextArray) { + limLog(pMac, LOGE, FL("failed to allocate memory")); + goto free; + } + + vos_mem_set(rxAuthFrame, sizeof(tSirMacAuthFrameBody), 0); + vos_mem_set(authFrame, sizeof(tSirMacAuthFrameBody), 0); + vos_mem_set(plainBody, LIM_ENCR_AUTH_BODY_LEN, 0); + vos_mem_set(challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH, 0); + + /// Determine if WEP bit is set in the FC or received MAC header + if (pHdr->fc.wep) + { + /** + * WEP bit is set in FC of MAC header. + */ + + // If TKIP counter measures enabled issue Deauth frame to station + if ((psessionEntry->bTkipCntrMeasActive) && (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + PELOGE( limLog(pMac, LOGE, + FL("Tkip counter measures Enabled, sending Deauth frame to")); ) + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + limSendDeauthMgmtFrame( pMac, eSIR_MAC_MIC_FAILURE_REASON, + pHdr->sa, psessionEntry, FALSE ); + goto free; + } + + // Extract key ID from IV (most 2 bits of 4th byte of IV) + + keyId = (*(pBody + 3)) >> 6; + + /** + * On STA in infrastructure BSS, Authentication frames received + * with WEP bit set in the FC must be rejected with challenge + * failure status code (wierd thing in the spec - this should have + * been rejected with unspecified failure or unexpected assertion + * of wep bit (this status code does not exist though) or + * Out-of-sequence-Authentication-Frame status code. + */ + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) + { + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = eSIR_MAC_CHALLENGE_FAILURE_STATUS; + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame with wep bit set on " + "role=%d "MAC_ADDRESS_STR), + psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pHdr->sa) );) + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + goto free; + } + + if (frameLen < LIM_ENCR_AUTH_BODY_LEN_SAP) + { + // Log error + limLog(pMac, LOGE, + FL("Not enough size [%d] to decrypt received Auth frame"), + frameLen); + limPrintMacAddr(pMac, pHdr->sa, LOGE); + + goto free; + } + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + val = psessionEntry->privacy; + } + else + // Accept Authentication frame only if Privacy is implemented + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Privacy option + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve Privacy option")); + } + + cfgPrivacyOptImp = (tANI_U8)val; + if (cfgPrivacyOptImp) + { + /** + * Privacy option is implemented. + * Check if the received frame is Authentication + * frame3 and there is a context for requesting STA. + * If not, reject with unspecified failure status code + */ + pAuthNode = limSearchPreAuthList(pMac, pHdr->sa); + + if (pAuthNode == NULL) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that has " + "no preauth context with WEP bit set "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * No 'pre-auth' context exists for this STA that sent + * an Authentication frame with FC bit set. + * Send Auth frame4 with 'out of sequence' status code. + */ + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + else + { + /// Change the auth-response timeout + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + + /// 'Pre-auth' status exists for STA + if ((pAuthNode->mlmState != + eLIM_MLM_WT_AUTH_FRAME3_STATE) && + (pAuthNode->mlmState != + eLIM_MLM_AUTH_RSP_TIMEOUT_STATE)) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that is " + "in state %d "MAC_ADDRESS_STR), + pAuthNode->mlmState, MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Should not have received Authentication frame + * with WEP bit set in FC in other states. + * Reject by sending Authenticaton frame with + * out of sequence Auth frame status code. + */ + + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + } + + /** + * Check if there exists a key mappping key + * for the STA that sent Authentication frame + */ + pKeyMapEntry = limLookUpKeyMappings(pHdr->sa); + + if (pKeyMapEntry) + { + if (!pKeyMapEntry->wepOn) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer that has NULL " + "key map entry " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Key Mapping entry has null key. + * Send Authentication frame + * with challenge failure status code + */ + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } // if (!pKeyMapEntry->wepOn) + else + { + decryptResult = limDecryptAuthFrame(pMac, pKeyMapEntry->key, + pBody, + plainBody, + key_length, + (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH)); + if (decryptResult == LIM_DECRYPT_ICV_FAIL) + { + /// ICV failure + PELOGW(limLog(pMac, LOGW, FL("=====> decryptResult == " + "LIM_DECRYPT_ICV_FAIL ..."));) + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer " + "that failed decryption, Addr " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + limDeletePreAuthNode(pMac, + pHdr->sa); + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + + goto free; + } + + if ( ( sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8, + rxAuthFrame)!=eSIR_SUCCESS ) || + ( !isAuthValid(pMac, rxAuthFrame,psessionEntry) ) ) + { + PELOGE(limLog(pMac, LOGE, + FL("failed to convert Auth Frame to structure " + "or Auth is not valid "));) + goto free; + } + + + } // end if (pKeyMapEntry->key == NULL) + } // if keyMappings has entry + else + { + + val = SIR_MAC_KEY_LENGTH; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + tpSirKeys pKey; + pKey = &psessionEntry->WEPKeyMaterial[keyId].key[0]; + vos_mem_copy(defaultKey, pKey->key, pKey->keyLength); + val = pKey->keyLength; + } + else + if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId), + defaultKey, &val) != eSIR_SUCCESS) + { + /// Could not get Default key from CFG. + //Log error. + limLog(pMac, LOGP, + FL("could not retrieve Default key")); + + /** + * Send Authentication frame + * with challenge failure status code + */ + + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + + key_length=val; + + decryptResult = limDecryptAuthFrame(pMac, defaultKey, + pBody, + plainBody, + key_length, + (tANI_U16) (frameLen-SIR_MAC_WEP_IV_LENGTH)); + if (decryptResult == LIM_DECRYPT_ICV_FAIL) + { + PELOGW(limLog(pMac, LOGW, FL("=====> decryptResult == " + "LIM_DECRYPT_ICV_FAIL ..."));) + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer that " + "failed decryption: " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + /// ICV failure + limDeletePreAuthNode(pMac, + pHdr->sa); + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + if ( ( sirConvertAuthFrame2Struct(pMac, plainBody, frameLen-8, + rxAuthFrame)!=eSIR_SUCCESS ) || + ( !isAuthValid(pMac, rxAuthFrame, psessionEntry) ) ) + { + limLog(pMac, LOGE, + FL("failed to convert Auth Frame to structure " + "or Auth is not valid ")); + goto free; + } + } // End of check for Key Mapping/Default key presence + } + else + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame3 from peer that while " + "privacy option is turned OFF " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + /** + * Privacy option is not implemented. + * So reject Authentication frame received with + * WEP bit set by sending Authentication frame + * with 'challenge failure' status code. This is + * another strange thing in the spec. Status code + * should have been 'unsupported algorithm' status code. + */ + + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } // else if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + } // if (fc.wep) + else + { + + + if ( ( sirConvertAuthFrame2Struct(pMac, pBody, + frameLen, rxAuthFrame)!=eSIR_SUCCESS ) || + ( !isAuthValid(pMac, rxAuthFrame,psessionEntry) ) ) + { + PELOGE(limLog(pMac, LOGE, + FL("failed to convert Auth Frame to structure or Auth is " + "not valid "));) + goto free; + } + } + + + pRxAuthFrameBody = rxAuthFrame; + + PELOGW(limLog(pMac, LOGW, + FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"), + (tANI_U32) pRxAuthFrameBody->authAlgoNumber, + (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber, + (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);) + + // IOT Workaround: with invalid WEP password, some APs reply AUTH frame 4 + // with invalid seqNumber. This AUTH frame will be dropped by driver, + // thus driver sends the generic status code instead of protocol status code. + // As a workaround, assign the correct seqNumber for the AUTH frame 4. + if (psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME4_STATE && + pRxAuthFrameBody->authTransactionSeqNumber != SIR_MAC_AUTH_FRAME_1 && + pRxAuthFrameBody->authTransactionSeqNumber != SIR_MAC_AUTH_FRAME_2 && + pRxAuthFrameBody->authTransactionSeqNumber != SIR_MAC_AUTH_FRAME_3) { + PELOGE(limLog(pMac, LOGE, FL("Workaround: Assign a correct seqNumber=4 " + "for AUTH frame 4"));) + pRxAuthFrameBody->authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_4; + } + + switch (pRxAuthFrameBody->authTransactionSeqNumber) + { + case SIR_MAC_AUTH_FRAME_1: + // AuthFrame 1 + + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, + &assocId, &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + tLimMlmDisassocReq *pMlmDisassocReq = NULL; + tLimMlmDeauthReq *pMlmDeauthReq = NULL; + tAniBool isConnected = eSIR_TRUE; + + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + if (pMlmDisassocReq && + (vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + PELOGE(limLog(pMac, LOGE, FL("TODO:Ack for disassoc " + "frame is pending Issue delsta for " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr));) + limProcessDisassocAckTimeout(pMac); + isConnected = eSIR_FALSE; + } + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if (pMlmDeauthReq && + (vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + PELOGE(limLog(pMac, LOGE, FL("TODO:Ack for deauth frame " + "is pending Issue delsta for " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + limProcessDeauthAckTimeout(pMac); + isConnected = eSIR_FALSE; + } + + /* pStaDS != NULL and isConnected = 1 means the STA is already + * connected, But SAP received the Auth from that station. + * For non PMF connection send Deauth frame as STA will retry + * to connect back. + * + * For PMF connection the AP should not tear down or otherwise + * modify the state of the existing association until the + * SA-Query procedure determines that the original SA is + * invalid. + */ + if (isConnected +#ifdef WLAN_FEATURE_11W + && !pStaDs->rmfEnabled +#endif + ) + { + limLog(pMac, LOGE, + FL("STA is already connected but received auth frame" + "Send the Deauth and lim Delete Station Context" + "(staId: %d, assocId: %d) "), + pStaDs->staIndex, assocId); + limSendDeauthMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + (tANI_U8 *) pHdr->sa, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + goto free; + } + } + + /// Check if there exists pre-auth context for this STA + pAuthNode = limSearchPreAuthList(pMac, pHdr->sa); + if (pAuthNode) + { + /// Pre-auth context exists for the STA + if (pHdr->fc.retry == 0 || pAuthNode->seqNo != currSeqNo) + { + /** + * STA is initiating brand-new Authentication + * sequence after local Auth Response timeout. + * Or STA retrying to transmit First Auth frame due to packet drop OTA + * Delete Pre-auth node and fall through. + */ + if(pAuthNode->fTimerStarted) + { + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + } + PELOGE(limLog(pMac, LOGE, FL("STA is initiating brand-new " + "Authentication ..."));) + limDeletePreAuthNode(pMac, + pHdr->sa); + /** + * SAP Mode:Disassociate the station and + * delete its entry if we have its entry + * already and received "auth" from the + * same station. + */ + + for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8 + { + pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if (NULL == pStaDs) + continue; + + if (pStaDs->valid) + { + if (vos_mem_compare((tANI_U8 *) &pStaDs->staAddr, + (tANI_U8 *) &(pHdr->sa), (tANI_U8) (sizeof(tSirMacAddr))) ) + break; + } + + pStaDs = NULL; + } + + if (NULL != pStaDs +#ifdef WLAN_FEATURE_11W + && !pStaDs->rmfEnabled +#endif + ) + { + PELOGE(limLog(pMac, LOGE, FL("lim Delete Station " + "Context (staId: %d, assocId: %d) "),pStaDs->staIndex, + assocId);) + limSendDeauthMgmtFrame(pMac, + eSIR_MAC_UNSPEC_FAILURE_REASON, (tANI_U8 *) pAuthNode->peerMacAddr, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pStaDs, psessionEntry); + goto free; + } + } + else + { + /* + * This can happen when first authentication frame is received + * but ACK lost at STA side, in this case 2nd auth frame is already + * in transmission queue + * */ + PELOGE(limLog(pMac, LOGE, FL("STA is initiating " + "Authentication after ACK lost..."));) + goto free; + } + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH, + (tANI_U32 *) &maxNumPreAuth) != eSIR_SUCCESS) + { + /** + * Could not get MaxNumPreAuth + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve MaxNumPreAuth")); + } + + if (pMac->lim.gLimNumPreAuthContexts == maxNumPreAuth && + !limDeleteOpenAuthPreAuthNode(pMac)) + { + PELOGE(limLog(pMac, LOGE, FL("Max number of " + "preauth context reached"));) + /** + * Maximum number of pre-auth contexts + * reached. Send Authentication frame + * with unspecified failure + */ + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_UNSPEC_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + /// No Pre-auth context exists for the STA. + if (limIsAuthAlgoSupported( + pMac, + (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber, psessionEntry)) + { + switch (pRxAuthFrameBody->authAlgoNumber) + { + case eSIR_OPEN_SYSTEM: + PELOGW(limLog(pMac, LOGW, FL("=======> eSIR_OPEN_SYSTEM ..."));) + /// Create entry for this STA in pre-auth list + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + goto free; + } + + limLog(pMac, LOG1, + FL("Alloc new data: peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pHdr->sa, + sizeof(tSirMacAddr)); + + pAuthNode->mlmState = + eLIM_MLM_AUTHENTICATED_STATE; + pAuthNode->authType = (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + pAuthNode->fSeen = 0; + pAuthNode->fTimerStarted = 0; + pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) | + (pHdr->seqControl.seqNumLo)); + pAuthNode->timestamp = vos_timer_get_system_ticks(); + limAddPreAuthNode(pMac, pAuthNode); + + /** + * Send Authenticaton frame with Success + * status code. + */ + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = eSIR_MAC_SUCCESS_STATUS; + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + /// Send Auth indication to SME + + vos_mem_copy((tANI_U8 *) mlmAuthInd.peerMacAddr, + (tANI_U8 *) pHdr->sa, + sizeof(tSirMacAddr)); + mlmAuthInd.authType = (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + mlmAuthInd.sessionId = psessionEntry->smeSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_AUTH_IND, + (tANI_U32 *) &mlmAuthInd); + break; + + case eSIR_SHARED_KEY: + PELOGW(limLog(pMac, LOGW, FL("=======> eSIR_SHARED_KEY ..."));) + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + val = psessionEntry->privacy; + } + else + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Privacy option + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Privacy option")); + } + cfgPrivacyOptImp = (tANI_U8)val; + if (!cfgPrivacyOptImp) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame for unsupported auth algorithm %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Authenticator does not have WEP + * implemented. + * Reject by sending Authentication frame + * with Auth algorithm not supported status + * code. + */ + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + else + { + // Create entry for this STA + //in pre-auth list + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + goto free; + } + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pHdr->sa, + sizeof(tSirMacAddr)); + + pAuthNode->mlmState = + eLIM_MLM_WT_AUTH_FRAME3_STATE; + pAuthNode->authType = + (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + pAuthNode->fSeen = 0; + pAuthNode->fTimerStarted = 0; + pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) | + (pHdr->seqControl.seqNumLo)); + pAuthNode->timestamp = vos_timer_get_system_ticks(); + limAddPreAuthNode(pMac, pAuthNode); + + limLog(pMac, LOG1, + FL("Alloc new data: id %d peer "MAC_ADDRESS_STR), + pAuthNode->authNodeIdx, MAC_ADDR_ARRAY(pHdr->sa)); + + /// Create and activate Auth Response timer + if (tx_timer_change_context(&pAuthNode->timer, pAuthNode->authNodeIdx) != TX_SUCCESS) + { + /// Could not start Auth response timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to chg context auth response timer for peer ")); + limPrintMacAddr(pMac, pHdr->sa, LOGP); + + /** + * Send Authenticaton frame with + * unspecified failure status code. + */ + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_UNSPEC_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + limDeletePreAuthNode(pMac, pHdr->sa); + goto free; + } + + limActivateAuthRspTimer(pMac, pAuthNode); + + pAuthNode->fTimerStarted = 1; + + /* + * get random bytes and use as challenge text + */ + if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH ) ) ) + { + limLog(pMac, LOGE,FL("Challenge text " + "preparation failed in limProcessAuthFrame")); + goto free; + } + + pChallenge = pAuthNode->challengeText; + + vos_mem_copy(pChallenge, + (tANI_U8 *) challengeTextArray, + sizeof(challengeTextArray)); + + /** + * Sending Authenticaton frame with challenge. + */ + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_SUCCESS_STATUS; + authFrame->type = SIR_MAC_CHALLENGE_TEXT_EID; + authFrame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH; + vos_mem_copy(authFrame->challengeText, + pAuthNode->challengeText, + SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH); + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + } // if (wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + + break; + + default: + // Log error + PELOGE( limLog(pMac, LOGE, + FL("received Auth frame for unsupported auth " + "algorithm %d "MAC_ADDRESS_STR), + pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Responding party does not support the + * authentication algorithm requested by + * sending party. + * Reject by sending Authentication frame + * with auth algorithm not supported status code + */ + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } // end switch(pRxAuthFrameBody->authAlgoNumber) + } // if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber)) + else + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame for unsupported auth " + "algorithm %d "MAC_ADDRESS_STR), + pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Responding party does not support the + * authentication algorithm requested by sending party. + * Reject Authentication with StatusCode=13. + */ + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } //end if (limIsAuthAlgoSupported(pRxAuthFrameBody->authAlgoNumber)) + break; + + case SIR_MAC_AUTH_FRAME_2: + // AuthFrame 2 + + if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME2_STATE) + { + /** + * Received Authentication frame2 in an unexpected state. + * Log error and ignore the frame. + */ + + // Log error + limLog(pMac, LOG1, + FL("received Auth frame2 from peer in state %d, addr "), + psessionEntry->limMlmState); + limPrintMacAddr(pMac, pHdr->sa, LOG1); + + goto free; + } + + if ( !vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + /** + * Received Authentication frame from an entity + * other than one request was initiated. + * Wait until Authentication Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received Auth frame2 from unexpected peer " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authStatusCode == + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS) + { + /** + * Interoperability workaround: Linksys WAP4400N is returning + * wrong authType in OpenAuth response in case of + * SharedKey AP configuration. Pretend we don't see that, + * so upper layer can fallback to SharedKey authType, + * and successfully connect to the AP. + */ + if (pRxAuthFrameBody->authAlgoNumber != + pMac->lim.gpLimMlmAuthReq->authType) + { + pRxAuthFrameBody->authAlgoNumber = + pMac->lim.gpLimMlmAuthReq->authType; + } + } + + if (pRxAuthFrameBody->authAlgoNumber != + pMac->lim.gpLimMlmAuthReq->authType) + { + /** + * Received Authentication frame with an auth + * algorithm other than one requested. + * Wait until Authentication Failure Timeout. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received Auth frame2 for unexpected auth algo number %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authStatusCode == + eSIR_MAC_SUCCESS_STATUS) + { + if (pRxAuthFrameBody->authAlgoNumber == + eSIR_OPEN_SYSTEM) + { + psessionEntry->limCurrentAuthType = eSIR_OPEN_SYSTEM; + + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + goto free; + } + + limLog(pMac, LOG1, + FL("Alloc new data: peer "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + pAuthNode->fTimerStarted = 0; + pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType; + pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) | + (pHdr->seqControl.seqNumLo)); + pAuthNode->timestamp = vos_timer_get_system_ticks(); + limAddPreAuthNode(pMac, pAuthNode); + + limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS, + pRxAuthFrameBody->authStatusCode,psessionEntry); + } // if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) + else + { + // Shared key authentication + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + val = psessionEntry->privacy; + } + else + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Privacy option + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Privacy option")); + } + cfgPrivacyOptImp = (tANI_U8)val; + if (!cfgPrivacyOptImp) + { + /** + * Requesting STA does not have WEP implemented. + * Reject with unsupported authentication algorithm + * Status code and wait until auth failure timeout + */ + + // Log error + PELOGE( limLog(pMac, LOGE, + FL("received Auth frame from peer for " + "unsupported auth algo %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + goto free; + } + else + { + + if (pRxAuthFrameBody->type != + SIR_MAC_CHALLENGE_TEXT_EID) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame with invalid " + "challenge text IE"));) + + goto free; + } + + /** + * Check if there exists a key mappping key + * for the STA that sent Authentication frame + */ + pKeyMapEntry = limLookUpKeyMappings( + pHdr->sa); + + if (pKeyMapEntry) + { + if (pKeyMapEntry->key == NULL) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from peer when " + "key mapping key is NULL"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Key Mapping entry has null key. + * Send Auth frame with + * challenge failure status code + */ + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + limRestoreFromAuthState(pMac, eSIR_SME_NO_KEY_MAPPING_KEY_FOR_PEER, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry); + + goto free; + } // if (pKeyMapEntry->key == NULL) + else + { + ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber = + sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber); + ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber = + sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1)); + ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS; + ((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID; + ((tpSirMacAuthFrameBody) plainBody)->length = pRxAuthFrameBody->length; + vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText, + pRxAuthFrameBody->challengeText, + pRxAuthFrameBody->length); + + encrAuthFrame = vos_mem_malloc(pRxAuthFrameBody->length + + LIM_ENCR_AUTH_INFO_LEN); + if (!encrAuthFrame) { + limLog(pMac, LOGE, FL("failed to allocate memory")); + goto free; + } + vos_mem_set(encrAuthFrame, pRxAuthFrameBody->length + + LIM_ENCR_AUTH_INFO_LEN, 0); + + limEncryptAuthFrame(pMac, 0, + pKeyMapEntry->key, + plainBody, + encrAuthFrame,key_length); + + psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME4_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limSendAuthMgmtFrame(pMac, + (tpSirMacAuthFrameBody) encrAuthFrame, + pHdr->sa, + pRxAuthFrameBody->length, + psessionEntry, eSIR_FALSE); + + break; + } // end if (pKeyMapEntry->key == NULL) + } // if (pKeyMapEntry) + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Default keyId + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Default keyId")); + } + keyId = (tANI_U8)val; + + val = SIR_MAC_KEY_LENGTH; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + tpSirKeys pKey; + pKey = &psessionEntry->WEPKeyMaterial[keyId].key[0]; + vos_mem_copy(defaultKey, pKey->key, pKey->keyLength); + } + else + if (wlan_cfgGetStr(pMac, (tANI_U16) (WNI_CFG_WEP_DEFAULT_KEY_1 + keyId), + defaultKey, + &val) + != eSIR_SUCCESS) + { + /// Could not get Default key from CFG. + //Log error. + limLog(pMac, LOGP, + FL("could not retrieve Default key")); + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + pRxAuthFrameBody->authTransactionSeqNumber + 1; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + limRestoreFromAuthState(pMac, eSIR_SME_INVALID_WEP_DEFAULT_KEY, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry); + + break; + } + key_length=val; + ((tpSirMacAuthFrameBody) plainBody)->authAlgoNumber = + sirSwapU16ifNeeded(pRxAuthFrameBody->authAlgoNumber); + ((tpSirMacAuthFrameBody) plainBody)->authTransactionSeqNumber = + sirSwapU16ifNeeded((tANI_U16) (pRxAuthFrameBody->authTransactionSeqNumber + 1)); + ((tpSirMacAuthFrameBody) plainBody)->authStatusCode = eSIR_MAC_SUCCESS_STATUS; + ((tpSirMacAuthFrameBody) plainBody)->type = SIR_MAC_CHALLENGE_TEXT_EID; + ((tpSirMacAuthFrameBody) plainBody)->length = pRxAuthFrameBody->length; + vos_mem_copy((tANI_U8 *) ((tpSirMacAuthFrameBody) plainBody)->challengeText, + pRxAuthFrameBody->challengeText, + pRxAuthFrameBody->length); + + encrAuthFrame = vos_mem_malloc(pRxAuthFrameBody->length + + LIM_ENCR_AUTH_INFO_LEN); + if (!encrAuthFrame) { + limLog(pMac, LOGE, FL("failed to allocate memory")); + goto free; + } + vos_mem_set(encrAuthFrame, pRxAuthFrameBody->length + + LIM_ENCR_AUTH_INFO_LEN, 0); + + limEncryptAuthFrame(pMac, keyId, + defaultKey, + plainBody, + encrAuthFrame,key_length); + + psessionEntry->limMlmState = + eLIM_MLM_WT_AUTH_FRAME4_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limSendAuthMgmtFrame(pMac, + (tpSirMacAuthFrameBody) encrAuthFrame, + pHdr->sa, + pRxAuthFrameBody->length, + psessionEntry, eSIR_FALSE); + + break; + } // end if (pKeyMapEntry) + } // end if (!wlan_cfgGetInt(CFG_PRIVACY_OPTION_IMPLEMENTED)) + } // end if (pRxAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) + } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) + else + { + /** + * Authentication failure. + * Return Auth confirm with received failure code to SME + */ + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from peer with failure code %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authStatusCode, + MAC_ADDR_ARRAY(pHdr->sa));) + + limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED, + pRxAuthFrameBody->authStatusCode,psessionEntry); + } // end if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) + + break; + + case SIR_MAC_AUTH_FRAME_3: + // AuthFrame 3 + + if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer with auth algo " + "number %d "MAC_ADDRESS_STR), + pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * Received Authentication frame3 with algorithm other than + * Shared Key authentication type. Reject with Auth frame4 + * with 'out of sequence' status code. + */ + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + /** + * Check if wep bit was set in FC. If not set, + * reject with Authentication frame4 with + * 'challenge failure' status code. + */ + if (!pHdr->fc.wep) + { + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer with no WEP bit " + "set "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + /// WEP bit is not set in FC of Auth Frame3 + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + + pAuthNode = limSearchPreAuthList(pMac, + pHdr->sa); + if (pAuthNode == NULL) + { + // Log error + PELOGE(limLog(pMac, LOGW, + FL("received AuthFrame3 from peer that has no " + "preauth context "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + + /** + * No 'pre-auth' context exists for + * this STA that sent an Authentication + * frame3. + * Send Auth frame4 with 'out of sequence' + * status code. + */ + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_AUTH_FRAME_OUT_OF_SEQ_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + + if (pAuthNode->mlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE) + { + // Log error + limLog(pMac, LOGW, + FL("auth response timer timedout for peer " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + /** + * Received Auth Frame3 after Auth Response timeout. + * Reject by sending Auth Frame4 with + * Auth respone timeout Status Code. + */ + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_AUTH_RSP_TIMEOUT_STATUS; + + limSendAuthMgmtFrame( + pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + /// Delete pre-auth context of STA + limDeletePreAuthNode(pMac, + pHdr->sa); + + goto free; + } // end switch (pAuthNode->mlmState) + + if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS) + { + /** + * Received Authenetication Frame 3 with status code + * other than success. Wait until Auth response timeout + * to delete STA context. + */ + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame3 from peer with status code %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authStatusCode, + MAC_ADDR_ARRAY(pHdr->sa));) + + goto free; + } + + /** + * Check if received challenge text is same as one sent in + * Authentication frame3 + */ + + if (vos_mem_compare(pRxAuthFrameBody->challengeText, + pAuthNode->challengeText, + SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH)) + { + /// Challenge match. STA is autheticated ! + + /// Delete Authentication response timer if running + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + + pAuthNode->fTimerStarted = 0; + pAuthNode->mlmState = eLIM_MLM_AUTHENTICATED_STATE; + + /** + * Send Authentication Frame4 with 'success' Status Code. + */ + authFrame->authAlgoNumber = eSIR_SHARED_KEY; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = eSIR_MAC_SUCCESS_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + /// Send Auth indication to SME + vos_mem_copy((tANI_U8 *) mlmAuthInd.peerMacAddr, + (tANI_U8 *) pHdr->sa, + sizeof(tSirMacAddr)); + mlmAuthInd.authType = (tAniAuthType) + pRxAuthFrameBody->authAlgoNumber; + mlmAuthInd.sessionId = psessionEntry->smeSessionId; + + limPostSmeMessage(pMac, + LIM_MLM_AUTH_IND, + (tANI_U32 *) &mlmAuthInd); + + break; + } + else + { + // Log error + PELOGE( limLog(pMac, LOGW, + FL("Challenge failure for peer " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + /** + * Challenge Failure. + * Send Authentication frame4 with 'challenge failure' + * status code and wait until Auth response timeout to + * delete STA context. + */ + + authFrame->authAlgoNumber = + pRxAuthFrameBody->authAlgoNumber; + authFrame->authTransactionSeqNumber = + SIR_MAC_AUTH_FRAME_4; + authFrame->authStatusCode = + eSIR_MAC_CHALLENGE_FAILURE_STATUS; + + limSendAuthMgmtFrame(pMac, authFrame, + pHdr->sa, + LIM_NO_WEP_IN_FC, + psessionEntry, eSIR_FALSE); + + goto free; + } + } // if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE || ... + + break; + + case SIR_MAC_AUTH_FRAME_4: + // AuthFrame 4 + if (psessionEntry->limMlmState != eLIM_MLM_WT_AUTH_FRAME4_STATE) + { + /** + * Received Authentication frame4 in an unexpected state. + * Log error and ignore the frame. + */ + + // Log error + limLog(pMac, LOG1, + FL("received unexpected Auth frame4 from peer in state " + "%d, addr "MAC_ADDRESS_STR), psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pHdr->sa)); + + goto free; + } + + if (pRxAuthFrameBody->authAlgoNumber != eSIR_SHARED_KEY) + { + /** + * Received Authentication frame4 with algorithm other than + * Shared Key authentication type. + * Wait until Auth failure timeout to report authentication + * failure to SME. + */ + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame4 from peer with invalid auth " + "algo %d "MAC_ADDRESS_STR), pRxAuthFrameBody->authAlgoNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + goto free; + } + + if ( !vos_mem_compare((tANI_U8 *) pHdr->sa, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + /** + * Received Authentication frame from an entity + * other than one to which request was initiated. + * Wait until Authentication Failure Timeout. + */ + + // Log error + PELOGE(limLog(pMac, LOGW, + FL("received Auth frame4 from unexpected peer " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authAlgoNumber != + pMac->lim.gpLimMlmAuthReq->authType) + { + /** + * Received Authentication frame with an auth algorithm + * other than one requested. + * Wait until Authentication Failure Timeout. + */ + + PELOGE(limLog(pMac, LOGE, + FL("received Authentication frame from peer with " + "invalid auth seq number %d " + MAC_ADDRESS_STR), pRxAuthFrameBody->authTransactionSeqNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + + if (pRxAuthFrameBody->authStatusCode == + eSIR_MAC_SUCCESS_STATUS) + { + /** + * Authentication Success ! + * Inform SME of same. + */ + psessionEntry->limCurrentAuthType = eSIR_SHARED_KEY; + + pAuthNode = limAcquireFreePreAuthNode(pMac, &pMac->lim.gLimPreAuthTimerTable); + if (pAuthNode == NULL) + { + // Log error + limLog(pMac, LOGW, + FL("Max pre-auth nodes reached ")); + limPrintMacAddr(pMac, pHdr->sa, LOGW); + + goto free; + } + limLog(pMac, LOG1, + FL("Alloc new data: peer " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + vos_mem_copy((tANI_U8 *) pAuthNode->peerMacAddr, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + pAuthNode->fTimerStarted = 0; + pAuthNode->authType = pMac->lim.gpLimMlmAuthReq->authType; + pAuthNode->seqNo = ((pHdr->seqControl.seqNumHi << 4) | + (pHdr->seqControl.seqNumLo)); + pAuthNode->timestamp = vos_timer_get_system_ticks(); + limAddPreAuthNode(pMac, pAuthNode); + + limRestoreFromAuthState(pMac, eSIR_SME_SUCCESS, + pRxAuthFrameBody->authStatusCode,psessionEntry); + + } // if (pRxAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS) + else + { + /** + * Authentication failure. + * Return Auth confirm with received failure code to SME + */ + + // Log error + PELOGE(limLog(pMac, LOGE, FL("Authentication failure from peer " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));) + + limRestoreFromAuthState(pMac, eSIR_SME_AUTH_REFUSED, + pRxAuthFrameBody->authStatusCode,psessionEntry); + } // end if (pRxAuthFrameBody->Status == 0) + + break; + + default: + /// Invalid Authentication Frame received. Ignore it. + + // Log error + PELOGE(limLog(pMac, LOGE, + FL("received Auth frame from peer with invalid auth seq " + "number %d " MAC_ADDRESS_STR), + pRxAuthFrameBody->authTransactionSeqNumber, + MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } // end switch (pRxAuthFrameBody->authTransactionSeqNumber) + +free: + if (authFrame) + vos_mem_free(authFrame); + if (rxAuthFrame) + vos_mem_free(rxAuthFrame); + if (encrAuthFrame) + vos_mem_free(encrAuthFrame); + if (plainBody) + vos_mem_free(plainBody); + if (challengeTextArray) + vos_mem_free(challengeTextArray); + +} /*** end limProcessAuthFrame() ***/ + + + + + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/*---------------------------------------------------------------------- + * + * Pass the received Auth frame. This is possibly the pre-auth from the + * neighbor AP, in the same mobility domain. + * This will be used in case of 11r FT. + * + * !!!! This is going to be renoved for the next checkin. We will be creating + * the session before sending out the Auth. Thus when auth response + * is received we will have a session in progress. !!!!! + *---------------------------------------------------------------------- + */ +tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pBd, void *body) +{ + tpSirMacMgmtHdr pHdr; + tpPESession psessionEntry = NULL; + tANI_U8 *pBody; + tANI_U16 frameLen; + tSirMacAuthFrameBody rxAuthFrame; + tSirMacAuthFrameBody *pRxAuthFrameBody = NULL; + tSirRetStatus ret_status = eSIR_FAILURE; + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + pBody = WDA_GET_RX_MPDU_DATA(pBd); + frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd); + + limLog(pMac, LOG1, FL("Auth Frame Received: BSSID " MAC_ADDRESS_STR + " (RSSI %d)"),MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pBd))); + // Check for the operating channel and see what needs to be done next. + psessionEntry = pMac->ft.ftPEContext.psavedsessionEntry; + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, FL("Error: Unable to find session id while in " + "pre-auth phase for FT")); + return eSIR_FAILURE; + } + + if (pMac->ft.ftPEContext.pFTPreAuthReq == NULL) + { + limLog(pMac, LOGE, FL("Error: No FT")); + // No FT in progress. + return eSIR_FAILURE; + } + + if (frameLen == 0) + { + limLog(pMac, LOGE, FL("Error: Frame len = 0")); + return eSIR_FAILURE; + } +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limPrintMacAddr(pMac, pHdr->bssId, LOG2); + limPrintMacAddr(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOG2); + limLog(pMac,LOG2,FL("seqControl 0x%X"), + ((pHdr->seqControl.seqNumHi << 8) | + (pHdr->seqControl.seqNumLo << 4) | + (pHdr->seqControl.fragNum))); +#endif + + // Check that its the same bssId we have for preAuth + if (!vos_mem_compare(pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + pHdr->bssId, sizeof( tSirMacAddr ))) + { + limLog(pMac, LOGE, FL("Error: NOT same bssid as preauth BSSID")); + // In this case SME if indeed has triggered a + // pre auth it will time out. + return eSIR_FAILURE; + } + + if (eANI_BOOLEAN_TRUE == + pMac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) + { + /* + * This is likely a duplicate for the same pre-auth request. + * PE/LIM already posted a response to SME. Hence, drop it. + * TBD: + * 1) How did we even receive multiple auth responses? + * 2) Do we need to delete pre-auth session? Suppose we + * previously received an auth resp with failure which + * would not have created the session and forwarded to SME. + * And, we subsequently received an auth resp with success + * which would have created the session. This will now be + * dropped without being forwarded to SME! However, it is + * very unlikely to receive auth responses from the same + * AP with different reason codes. + * NOTE: return eSIR_SUCCESS so that the packet is dropped + * as this was indeed a response from the BSSID we tried to + * pre-auth. + */ + PELOGE(limLog(pMac,LOG1,"Auth rsp already posted to SME" + " (session %p, FT session %p)", psessionEntry, + pMac->ft.ftPEContext.pftSessionEntry);); + return eSIR_SUCCESS; + } + else + { + PELOGE(limLog(pMac,LOGW,"Auth rsp not yet posted to SME" + " (session %p, FT session %p)", psessionEntry, + pMac->ft.ftPEContext.pftSessionEntry);); + pMac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = + eANI_BOOLEAN_TRUE; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("Pre-Auth response received from neighbor")); + limLog(pMac, LOG1, FL("Pre-Auth done state")); +#endif + + limLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"), + pMac->ft.ftSmeContext.is_preauth_lfr_mbb); + + // Stopping timer now, that we have our unicast from the AP + // of our choice. + if (!pMac->ft.ftSmeContext.is_preauth_lfr_mbb) + limDeactivateAndChangeTimer(pMac, eLIM_FT_PREAUTH_RSP_TIMER); + +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) + limDeactivateAndChangeTimer(pMac, eLIM_PREAUTH_MBB_RSP_TIMER); +#endif + + + // Save off the auth resp. + if ((sirConvertAuthFrame2Struct(pMac, pBody, frameLen, &rxAuthFrame) != eSIR_SUCCESS)) + { + limLog(pMac, LOGE, FL("failed to convert Auth frame to struct")); + +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_handle_pre_auth_mbb_rsp(pMac, eSIR_FAILURE, psessionEntry); + return eSIR_FAILURE; + } +#endif + + limHandleFTPreAuthRsp(pMac, eSIR_FAILURE, NULL, 0, psessionEntry); + return eSIR_FAILURE; + } + pRxAuthFrameBody = &rxAuthFrame; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, + FL("Received Auth frame with type=%d seqnum=%d, status=%d (%d)"), + (tANI_U32) pRxAuthFrameBody->authAlgoNumber, + (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber, + (tANI_U32) pRxAuthFrameBody->authStatusCode,(tANI_U32)pMac->lim.gLimNumPreAuthContexts);) +#endif + + switch (pRxAuthFrameBody->authTransactionSeqNumber) + { + case SIR_MAC_AUTH_FRAME_2: + if (pRxAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "Auth status code received is %d", + (tANI_U32) pRxAuthFrameBody->authStatusCode);); +#endif + if (eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS == pRxAuthFrameBody->authStatusCode) + ret_status = eSIR_LIM_MAX_STA_REACHED_ERROR; + } + else + { + ret_status = eSIR_SUCCESS; + } + break; + + default: +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog( pMac, LOGE, "Seq. no incorrect expected 2 received %d", + (tANI_U32) pRxAuthFrameBody->authTransactionSeqNumber);) +#endif + break; + } + +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_handle_pre_auth_mbb_rsp(pMac, ret_status, psessionEntry); + return ret_status; + } +#endif + + // Send the Auth response to SME + limHandleFTPreAuthRsp(pMac, ret_status, pBody, frameLen, psessionEntry); + + return ret_status; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c new file mode 100644 index 000000000000..6e1b64f6a246 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessBeaconFrame.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessBeaconFrame.cc contains the code + * for processing Received Beacon Frame. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniCfg.h" +#include "aniGlobal.h" +#include "cfgApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" + +/** + * limProcessBeaconFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon Beacon + * frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Beacons received in 'normal' state in IBSS are handled by + * Beacon Processing module. + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to RX packet info structure + * @return None + */ + +void +limProcessBeaconFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pHdr; + tSchBeaconStruct *pBeacon; + + pMac->lim.gLimNumBeaconsRcvd++; + + /* here is it required to increment session specific heartBeat beacon counter */ + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + + limLog(pMac, LOG2, FL("Received Beacon frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2); + + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + return; + } + + /** + * Expect Beacon only when + * 1. STA is in Scan mode waiting for Beacon/Probe response or + * 2. STA is waiting for Beacon/Probe Respose Frame + * to announce join success. + * 3. STA/AP is in Learn mode + */ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) || + (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + || pMac->fScanOffload + ) + { + pBeacon = vos_mem_vmalloc(sizeof(tSchBeaconStruct)); + if ( NULL == pBeacon ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessBeaconFrame") ); + return; + } + + // Parse received Beacon + if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, + pBeacon) != eSIR_SUCCESS) + { + // Received wrongly formatted/invalid Beacon. + // Ignore it and move on. + limLog(pMac, LOGW, + FL("Received invalid Beacon in state %d"), + psessionEntry->limMlmState); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + if ((!psessionEntry->currentBssBeaconCnt) && + (sirCompareMacAddr( psessionEntry->bssId, pHdr->sa))) + limParseBeaconForTim(pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry); + + vos_mem_vfree(pBeacon); + return; + } + /*during scanning, when any session is active, and beacon/Pr belongs to + one of the session, fill up the following, TBD - HB couter */ + if ((!psessionEntry->lastBeaconDtimPeriod) && + (sirCompareMacAddr( psessionEntry->bssId, pBeacon->bssid))) + { + vos_mem_copy(( tANI_U8* )&psessionEntry->lastBeaconTimeStamp, + ( tANI_U8* )pBeacon->timeStamp, sizeof(tANI_U64) ); + psessionEntry->lastBeaconDtimCount = pBeacon->tim.dtimCount; + psessionEntry->lastBeaconDtimPeriod= pBeacon->tim.dtimPeriod; + psessionEntry->currentBssBeaconCnt++; + } + + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, pBeacon->timeStamp[0]);) + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, 0, pBeacon->timeStamp[1]);) + + if (pMac->fScanOffload) + { + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + + } + + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)) + { + //If we are scanning for P2P, only accept probe rsp + if((pMac->lim.gLimHalScanState != eLIM_HAL_SCANNING_STATE) || (NULL == pMac->lim.gpLimMlmScanReq) + || !pMac->lim.gpLimMlmScanReq->p2pSearch ) + { + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, + ((pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) ? eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE), + eANI_BOOLEAN_FALSE); + + } + /* Calling dfsChannelList which will convert DFS channel + * to Active channel for x secs if this channel is DFS channel */ + limSetDFSChannelList(pMac, pBeacon->channelNumber, + &pMac->lim.dfschannelList); + } + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) + { + } + else if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + { + if( psessionEntry->beacon != NULL ) + { + vos_mem_free(psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + psessionEntry->bcnLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + psessionEntry->beacon = vos_mem_malloc(psessionEntry->bcnLen); + if ( NULL == psessionEntry->beacon ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));) + } + else + { + //Store the Beacon/ProbeRsp. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->beacon, WDA_GET_RX_MPDU_DATA(pRxPacketInfo), + psessionEntry->bcnLen); + + } + + // STA in WT_JOIN_BEACON_STATE (IBSS) + limCheckAndAnnounceJoinSuccess(pMac, pBeacon, pHdr,psessionEntry); + } // if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) + vos_mem_vfree(pBeacon); + } // if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || ... + else + { + // Ignore Beacon frame in all other states + if (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE || + psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME3_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME4_STATE || + psessionEntry->limMlmState == eLIM_MLM_AUTH_RSP_TIMEOUT_STATE || + psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_ASSOC_RSP_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_REASSOC_RSP_STATE || + psessionEntry->limMlmState == eLIM_MLM_ASSOCIATED_STATE || + psessionEntry->limMlmState == eLIM_MLM_REASSOCIATED_STATE || + psessionEntry->limMlmState == eLIM_MLM_WT_ASSOC_CNF_STATE || + limIsReassocInProgress(pMac,psessionEntry)) { + // nothing unexpected about beacon in these states + pMac->lim.gLimNumBeaconsIgnored++; + } + else + { + limLog(pMac, LOG1, FL("Received Beacon in unexpected state %d"), + psessionEntry->limMlmState); + limPrintMlmState(pMac, LOG1, psessionEntry->limMlmState); +#ifdef WLAN_DEBUG + pMac->lim.gLimUnexpBcnCnt++; +#endif + } + } + + return; +} /*** end limProcessBeaconFrame() ***/ + + +/**--------------------------------------------------------------- +\fn limProcessBeaconFrameNoSession +\brief This function is called by limProcessMessageQueue() +\ upon Beacon reception. +\ +\param pMac +\param *pRxPacketInfo - A pointer to Rx packet info structure +\return None +------------------------------------------------------------------*/ +void +limProcessBeaconFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tpSirMacMgmtHdr pHdr; + tSchBeaconStruct *pBeacon; + + pMac->lim.gLimNumBeaconsRcvd++; + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + limLog(pMac, LOG2, FL("Received Beacon frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2); + + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + return; + } + + /** + * No session has been established. Expect Beacon only when + * 1. STA is in Scan mode waiting for Beacon/Probe response or + * 2. STA/AP is in Learn mode + */ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE)) + { + pBeacon = vos_mem_vmalloc(sizeof(tSchBeaconStruct)); + if ( NULL == pBeacon ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessBeaconFrameNoSession") ); + return; + } + + if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, pBeacon) != eSIR_SUCCESS) + { + // Received wrongly formatted/invalid Beacon. Ignore and move on. + limLog(pMac, LOGW, FL("Received invalid Beacon in global MLM state %d"), pMac->lim.gLimMlmState); + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + vos_mem_vfree(pBeacon); + return; + } + + if ( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ) + { + //If we are scanning for P2P, only accept probe rsp + if((pMac->lim.gLimHalScanState != eLIM_HAL_SCANNING_STATE) || (NULL == pMac->lim.gpLimMlmScanReq) + || !pMac->lim.gpLimMlmScanReq->p2pSearch ) + { + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_FALSE); + } + /* Calling dfsChannelList which will convert DFS channel + * to Active channel for x secs if this channel is DFS channel */ + limSetDFSChannelList(pMac, pBeacon->channelNumber, + &pMac->lim.dfschannelList); + } + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) + { + } // end of eLIM_MLM_LEARN_STATE) + vos_mem_vfree(pBeacon); + } // end of (eLIM_MLM_WT_PROBE_RESP_STATE) || (eLIM_MLM_PASSIVE_SCAN_STATE) + else + { + limLog(pMac, LOG1, FL("Rcvd Beacon in unexpected MLM state %s (%d)"), + limMlmStateStr(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState); + limPrintMlmState(pMac, LOG1, pMac->lim.gLimMlmState); +#ifdef WLAN_DEBUG + pMac->lim.gLimUnexpBcnCnt++; +#endif + } + + return; +} /*** end limProcessBeaconFrameNoSession() ***/ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c new file mode 100644 index 000000000000..3e3cc3776e23 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c @@ -0,0 +1,800 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessCfgUpdates.cc contains the utility functions + * to handle various CFG parameter update events + * Author: Chandra Modumudi + * Date: 01/20/03 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "aniGlobal.h" + +#include "wniCfg.h" +#include "sirMacProtDef.h" +#include "cfgApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limPropExtsUtils.h" +#include "schApi.h" +#include "pmmApi.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +static void limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry); + +#if 0 +/** + * limGetCfgIdOfDefaultKeyid() + * + *FUNCTION: + * This function is called to get CFG ID of default key id + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param dkid - Value of default key id + * @return dkCfgId - CFG ID of key corresponding to default key Id + */ + +static tANI_U32 +limGetCfgIdOfDefaultKeyid(tANI_U32 dkid) +{ + if (dkid == WNI_CFG_WEP_DEFAULT_KEYID_0) + return WNI_CFG_WEP_DEFAULT_KEY_1; + else if (dkid == WNI_CFG_WEP_DEFAULT_KEYID_1) + return WNI_CFG_WEP_DEFAULT_KEY_2; + else if (dkid == WNI_CFG_WEP_DEFAULT_KEYID_2) + return WNI_CFG_WEP_DEFAULT_KEY_3; + else // dkid == WNI_CFG_WEP_DEFAULT_KEYID_3 + return WNI_CFG_WEP_DEFAULT_KEY_4; +} /*** end limGetCfgIdOfDefaultKeyid() ***/ +#endif + + +/** + * limSetDefaultKeyIdAndKeys() + * + *FUNCTION: + * This function is called while applying configuration + * during JOIN/REASSOC/START_BSS. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +static void +limSetDefaultKeyIdAndKeys(tpAniSirGlobal pMac) +{ +#ifdef FIXME_GEN6 + tANI_U32 val; + tANI_U32 dkCfgId; + + PELOG1(limLog(pMac, LOG1, FL("Setting default keys at SP"));) + + if (wlan_cfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, + &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve defaultKeyId from CFG")); + } + dkCfgId = limGetCfgIdOfDefaultKeyid(val); +#endif + +} /*** end limSetDefaultKeyIdAndKeys() ***/ + +/** ------------------------------------------------------------- +\fn limSetCfgProtection +\brief sets lim global cfg cache from the config. +\param tpAniSirGlobal pMac +\return None + -------------------------------------------------------------*/ +void limSetCfgProtection(tpAniSirGlobal pMac, tpPESession pesessionEntry) +{ + tANI_U32 val = 0; + + if(( pesessionEntry != NULL ) && (pesessionEntry->limSystemRole == eLIM_AP_ROLE )){ + if (pesessionEntry->gLimProtectionControl == WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE ) + vos_mem_set((void *)&pesessionEntry->cfgProtection, sizeof(tCfgProtection), 0); + else{ + limLog(pMac, LOG1, FL(" frm11a = %d, from11b = %d, frm11g = %d, " + "ht20 = %d, nongf = %d, lsigTxop = %d, " + "rifs = %d, obss = %d"), + pesessionEntry->cfgProtection.fromlla, + pesessionEntry->cfgProtection.fromllb, + pesessionEntry->cfgProtection.fromllg, + pesessionEntry->cfgProtection.ht20, + pesessionEntry->cfgProtection.nonGf, + pesessionEntry->cfgProtection.lsigTxop, + pesessionEntry->cfgProtection.rifs, + pesessionEntry->cfgProtection.obss); + } + } + else{ + if (wlan_cfgGetInt(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("reading WNI_CFG_FORCE_POLICY_PROTECTION cfg failed")); + return; + } + else + pMac->lim.gLimProtectionControl = (tANI_U8)val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROTECTION_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("reading protection cfg failed")); + return; + } + + if (pMac->lim.gLimProtectionControl == WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + vos_mem_set((void *)&pMac->lim.cfgProtection, sizeof(tCfgProtection), 0); + else + { + pMac->lim.cfgProtection.fromlla = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llA) & 1; + pMac->lim.cfgProtection.fromllb = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llB) & 1; + pMac->lim.cfgProtection.fromllg = (val >> WNI_CFG_PROTECTION_ENABLED_FROM_llG) & 1; + pMac->lim.cfgProtection.ht20 = (val >> WNI_CFG_PROTECTION_ENABLED_HT_20) & 1; + pMac->lim.cfgProtection.nonGf = (val >> WNI_CFG_PROTECTION_ENABLED_NON_GF) & 1; + pMac->lim.cfgProtection.lsigTxop = (val >> WNI_CFG_PROTECTION_ENABLED_LSIG_TXOP) & 1; + pMac->lim.cfgProtection.rifs = (val >> WNI_CFG_PROTECTION_ENABLED_RIFS) & 1; + pMac->lim.cfgProtection.obss= (val >> WNI_CFG_PROTECTION_ENABLED_OBSS) & 1; + + } + } +} + + + +/** + * limUpdateTriggerStaBkScanFlag + * + * FUNCTION: + * This function updates the lim global gLimTriggerBackgroundScanDuringQuietBss + * based on cfg configuration. Usually triggered after a cfgSetInt call. + * + * PARAMS: + * pMac - Pointer to Global MAC structure + * + */ +static tSirRetStatus limUpdateTriggerStaBkScanFlag(tpAniSirGlobal pMac) +{ + tANI_U32 val; + tANI_U8 flag; + + if(wlan_cfgGetInt(pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val) != eSIR_SUCCESS) + { + PELOG1(limLog(pMac, LOG1, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN from cfg"));) + return eSIR_FAILURE; + } + + flag = (val) ? 1 : 0; + if(flag != pMac->lim.gLimTriggerBackgroundScanDuringQuietBss) + { + /* Update global flag */ + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = flag; + /*Update beacon prop IE also if we're an AP */ + + //call a wrapper and if the session role is other than the sta call this function schsetfixedbeacon fields function + limUpdateBeacon(pMac); + + } + + return eSIR_FAILURE; +} + + +/** + * limHandleCFGparamUpdate() + * + *FUNCTION: + * This function is called by limProcessMessages() to + * whenever SIR_CFG_PARAM_UPDATE_IND message is posted + * to LIM (due to a set operation on a CFG parameter). + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param cfgId - ID of CFG parameter that got updated + * @return None + */ + +void +limHandleCFGparamUpdate(tpAniSirGlobal pMac, tANI_U32 cfgId) +{ + tANI_U32 val1, val2; + tANI_U16 val16; + tSirMacHTCapabilityInfo *pHTCapabilityInfo; + tSirMacHTParametersInfo *pAmpduParamInfo; + + PELOG3(limLog(pMac, LOG3, FL("Handling CFG parameter id %X update"), cfgId);) + switch (cfgId) + { + case WNI_CFG_WEP_DEFAULT_KEYID: + + // !!LAC - when the default KeyID is changed, force all of the + // keys and the keyID to be reprogrammed. this allows the + // keys to change after the initial setting of the keys when the CFG was + // applied at association time through CFG changes of the keys. + limSetDefaultKeyIdAndKeys( pMac ); + + break; + + case WNI_CFG_EXCLUDE_UNENCRYPTED: + if (wlan_cfgGetInt(pMac, WNI_CFG_EXCLUDE_UNENCRYPTED, + &val1) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve excludeUnencr from CFG")); + } +#if 0 + halSetSpExclUndecrypted(pMac, (tHalBitVal) val); +#else + limLog(pMac, LOGE, + FL("Unsupported CFG: WNI_CFG_EXCLUDE_UNENCRYPTED")); +#endif + + break; + + case WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT: + if (pMac->lim.gLimMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) + { + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, + eLIM_ASSOC_FAIL_TIMER); + } + + break; + + case WNI_CFG_BACKGROUND_SCAN_PERIOD: + + + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, &val1) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve Background scan period value")); + break; + } + if (val1 == 0) + break; + + + + if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) || + ( (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (pMac->lim.gLimSmeState == eLIM_SME_NORMAL_STATE))) + { + // Reactivate Background scan timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER)); + if (tx_timer_activate( + &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + /// Could not activate background scan timer. + // Log error + limLog(pMac, LOGP, + FL("could not activate background scan timer")); + pMac->lim.gLimBackgroundScanStarted = FALSE; + pMac->lim.gLimBackgroundScanTerminate = TRUE; + } + else + { + pMac->lim.gLimBackgroundScanStarted = TRUE; + pMac->lim.gLimBackgroundScanTerminate = FALSE; + } + + PELOG3(limLog(pMac, LOG3, + FL("Updated Background scan period"));) + } + + break; + + case WNI_CFG_BG_SCAN_CHANNEL_LIST: + PELOG1(limLog(pMac, LOG1, + FL("VALID_CHANNEL_LIST has changed, reset next bg scan channel"));) + pMac->lim.gLimBackgroundScanChannelId = 0; + + break; + + case WNI_CFG_TRIG_STA_BK_SCAN: + if(limUpdateTriggerStaBkScanFlag(pMac) != eSIR_SUCCESS) + { + PELOG2(limLog(pMac, LOG2, + FL("Updating lim trigger sta bk scan global flag failed!"));) + } + break; + + case WNI_CFG_PROTECTION_ENABLED: + limSetCfgProtection(pMac, NULL); + break; + case WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG: + { + tSirMsgQ msg = {0}; + tANI_U32 status; + + msg.type = SIR_LIM_UPDATE_BEACON; + + status = limPostMsgApi(pMac, &msg); + + if (status != TX_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed limPostMsgApi %u"), status);) + break; + } + case WNI_CFG_GREENFIELD_CAPABILITY: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap Info CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_GREENFIELD_CAPABILITY, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve GreenField CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->greenField = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + + case WNI_CFG_HT_RX_STBC: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HT_CAP_INFO "));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_RX_STBC, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HT_RX_STBC"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->rxSTBC = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + + case WNI_CFG_MAX_AMSDU_LENGTH: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap Info CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_AMSDU_LENGTH, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max AMSDU Length CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->maximalAMSDUsize = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + + case WNI_CFG_SHORT_GI_20MHZ: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_20MHZ, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 20Mhz CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->shortGI20MHz = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + case WNI_CFG_SHORT_GI_40MHZ: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT Cap CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_GI_40MHZ, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve shortGI 40Mhz CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pHTCapabilityInfo = ( tSirMacHTCapabilityInfo* ) &val16; + pHTCapabilityInfo->shortGI40MHz = (tANI_U16)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT Cap Info CFG"));) + break; + case WNI_CFG_MPDU_DENSITY: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MPDU_DENSITY, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve MPDU Density CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16; + pAmpduParamInfo->mpduDensity = (tANI_U8)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG"));) + + break; + case WNI_CFG_MAX_RX_AMPDU_FACTOR: + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve HT AMPDU Param CFG"));) + break; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_RX_AMPDU_FACTOR, &val2) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve AMPDU Factor CFG"));) + break; + } + val16 = ( tANI_U16 ) val1; + pAmpduParamInfo = ( tSirMacHTParametersInfo* ) &val16; + pAmpduParamInfo->maxRxAMPDUFactor = (tANI_U8)val2; + if(cfgSetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, *(tANI_U8*)pAmpduParamInfo) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not update HT AMPDU Param CFG"));) + break; + + case WNI_CFG_HEART_BEAT_THRESHOLD: + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve WNI_CFG_HEART_BEAT_THRESHOLD CFG"));) + break; + } + if(!val1) + { + limDeactivateAndChangeTimer(pMac, eLIM_HEART_BEAT_TIMER); + pMac->sys.gSysEnableLinkMonitorMode = 0; + } + else + { + tANI_U16 sessionId; + pMac->sys.gSysEnableLinkMonitorMode = 1; + for(sessionId = 0; sessionId < pMac->lim.maxBssId; sessionId++) + { + if( (pMac->lim.gpSession[sessionId].valid )&& + (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[sessionId].limMlmState) && + ( pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + PELOG2(limLog(pMac, LOG2, "HB link monitoring reactivated" + " for session=%d", sessionId);) + PELOGW(limLog(pMac, LOGW, "Before reactivating HB timer; parameters are" + " session=%d limMlmState=%d pmmState=%d", sessionId, + pMac->lim.gpSession[sessionId].limMlmState, + pMac->pmm.gPmmState);) + limReactivateHeartBeatTimer(pMac, &pMac->lim.gpSession[sessionId]); + } + else if ( pMac->lim.gpSession[sessionId].valid ) + { + PELOGW(limLog(pMac, LOGW, "HB link monitoring not reactivated-" + "session=%d, limMlmState=%d, gPmmState=%d", + sessionId, pMac->lim.gpSession[sessionId].limMlmState, + pMac->pmm.gPmmState);) + } + } + } + case WNI_CFG_MAX_PS_POLL: + case WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE: + case WNI_CFG_MIN_RSSI_THRESHOLD: + case WNI_CFG_NTH_BEACON_FILTER: + case WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE: + { + tpSirPowerSaveCfg pPowerSaveConfig; + + /* Allocate and fill in power save configuration. */ + pPowerSaveConfig = vos_mem_malloc(sizeof(tSirPowerSaveCfg)); + if ( NULL == pPowerSaveConfig ) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: Cannot allocate memory for power save configuration"));) + break; + } + + /* This context should be valid if power-save configuration message has been already dispathed + * during initialization process. Re-using the present configuration mask + */ + vos_mem_copy(pPowerSaveConfig, (tANI_U8 *)&pMac->pmm.gPmmCfg, sizeof(tSirPowerSaveCfg)); + + if ( (pmmSendPowerSaveCfg(pMac, pPowerSaveConfig)) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: pmmSendPowerSaveCfg() failed "));) + } + } + break; + + + case WNI_CFG_DOT11_MODE: + if (wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &val1) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Dot11 Mode CFG"));) + break; + } + /* TODO */ + //psessionEntry->dot11mode = val1; //// un comment this line ...FORBUILD -TEMPFIX.. HOW TO GET sessionEntry????? + break; + case WNI_CFG_ADDBA_REQ_DECLINE: + if(wlan_cfgGetInt(pMac, WNI_CFG_ADDBA_REQ_DECLINE, &val1) != eSIR_SUCCESS) { + limLog( pMac, LOGE, FL( "Unable to get ADDBA_REQ_DECLINE cfg" )); + break; + } + pMac->lim.gAddBA_Declined = (tANI_U8)val1; + break; + + case WNI_CFG_SCAN_IN_POWERSAVE: + if(wlan_cfgGetInt(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val1) != eSIR_SUCCESS) { + limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_SCAN_IN_POWERSAVE " )); + break; + } + pMac->lim.gScanInPowersave = (tANI_U8)val1; + break; + + + case WNI_CFG_ASSOC_STA_LIMIT: + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val1) != eSIR_SUCCESS) { + limLog( pMac, LOGE, FL( "Unable to get WNI_CFG_ASSOC_STA_LIMIT" )); + break; + } + pMac->lim.gLimAssocStaLimit = (tANI_U16)val1; + break; + + case WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC: + if (wlan_cfgGetInt + (pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, &val1) != + eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL( "Unable to get WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC")); + break; + } + if (val1) + { + limLog(pMac, LOGW, + FL("BTC requested to disable all RX BA sessions")); + limDelPerBssBASessionsBtc(pMac); + } + else + { + limLog(pMac, LOGW, + FL("Resetting the WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC")); + } + break; + + default: + break; + } +} /*** end limHandleCFGparamUpdate() ***/ + + + +/** + * limApplyConfiguration() + * + *FUNCTION: + * This function is called to apply the configured parameters + * before joining or reassociating with a BSS or starting a BSS. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limApplyConfiguration(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tANI_U32 val=0, phyMode; + + limLog(pMac, LOG2, FL("Applying config")); + + limInitWdsInfoParams(pMac); + + psessionEntry->limSentCapsChangeNtf = false; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + // Set default keyId and keys + limSetDefaultKeyIdAndKeys(pMac); + + limUpdateConfig(pMac,psessionEntry); + + limGetShortSlotFromPhyMode(pMac, psessionEntry, phyMode, + &psessionEntry->shortSlotTimeSupported); + + limSetCfgProtection(pMac, psessionEntry); + + + /* Added for BT - AMP Support */ + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ) + { + /* This check is required to ensure the beacon generation is not done + as a part of join request for a BT-AMP station */ + + if(psessionEntry->statypeForBss == STA_ENTRY_SELF) + { + PELOG1(limLog(pMac, LOG1, FL("Initializing BT-AMP beacon generation"));) + schSetBeaconInterval(pMac,psessionEntry); + schSetFixedBeaconFields(pMac,psessionEntry); + } + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_SCAN_IN_POWERSAVE, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve WNI_CFG_SCAN_IN_POWERSAVE")); + return; + } + + pMac->lim.gScanInPowersave = (tANI_U8) val; + limLog(pMac, LOG1, FL("pMac->lim.gScanInPowersave = %hu"), + pMac->lim.gScanInPowersave); + + +} /*** end limApplyConfiguration() ***/ + + +/** + * limUpdateConfig + * + * FUNCTION: + * Update the local state from CFG database + * (This used to be dphUpdateConfig) + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +static void +limUpdateConfig(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tANI_U32 val; + + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, pMac->lim.gLimMyMacAddr, &len) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get sta id failed")); + #endif //To SUPPORT BT-AMP + sirCopyMacAddr(pMac->lim.gLimMyMacAddr,psessionEntry->selfMacAddr); + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get short preamble failed")); + psessionEntry->beaconParams.fShortPreamble = (val) ? 1 : 0; + + /* In STA case this parameter is filled during the join request */ + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_WME_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get wme enabled failed")); + psessionEntry->limWmeEnabled = (val) ? 1 : 0; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_WSM_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get wsm enabled failed")); + psessionEntry->limWsmEnabled = (val) ? 1 : 0; + + if ((! psessionEntry->limWmeEnabled) && (psessionEntry->limWsmEnabled)) + { + PELOGE(limLog(pMac, LOGE, FL("Can't enable WSM without WME"));) + psessionEntry->limWsmEnabled = 0; + } + /* In STA , this parameter is filled during the join request */ + if (psessionEntry->limSystemRole== eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_QOS_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get qos enabled failed")); + psessionEntry->limQosEnabled = (val) ? 1 : 0; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_HCF_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get hcf enabled failed")); + psessionEntry->limHcfEnabled = (val) ? 1 : 0; + + // Update the ADD BA Declined configuration + if(wlan_cfgGetInt(pMac, WNI_CFG_ADDBA_REQ_DECLINE, &val) != eSIR_SUCCESS) + limLog( pMac, LOGP, FL( "Unable to get ADDBA_REQ_DECLINE cfg" )); + pMac->lim.gAddBA_Declined = (val) ? 0xff : 0x0; + + // AP: WSM should enable HCF as well, for STA enable WSM only after + // association response is received + if (psessionEntry->limWsmEnabled && psessionEntry->limSystemRole == eLIM_AP_ROLE) + psessionEntry->limHcfEnabled = 1; + + if (wlan_cfgGetInt(pMac, WNI_CFG_11D_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get 11d enabled failed")); + psessionEntry->lim11dEnabled = (val) ? 1 : 0; + + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, &val) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" )); + } + if( (!WDI_getFwWlanFeatCaps(SAP32STA)) && (val >= WNI_CFG_ASSOC_STA_LIMIT_STAMAX)) + { + if(ccmCfgSetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, WNI_CFG_ASSOC_STA_LIMIT_STADEF, + NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS) + { + limLog( pMac, LOGP, FL( "cfg get assoc sta limit failed" )); + } + val = WNI_CFG_ASSOC_STA_LIMIT_STADEF; + } + pMac->lim.gLimAssocStaLimit = (tANI_U16)val; + +#if defined WLAN_FEATURE_VOWIFI + rrmUpdateConfig( pMac, psessionEntry ); +#endif + PELOG1(limLog(pMac, LOG1, FL("Updated Lim shadow state based on CFG"));) + + +} + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c new file mode 100644 index 000000000000..ef1056e7392c --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "palTypes.h" +#include "aniGlobal.h" + +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "schApi.h" +#include "limSendMessages.h" +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + + +/** + * limProcessDeauthFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Deauthentication frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs + * @return None + */ + +void +limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U16 aid, reasonCode; + tpSirMacMgmtHdr pHdr; + tLimMlmAssocCnf mlmAssocCnf; + tLimMlmDeauthInd mlmDeauthInd; + tpDphHashNode pStaDs; + tpPESession pRoamSessionEntry=NULL; + tANI_U8 roamSessionId; +#ifdef WLAN_FEATURE_11W + tANI_U32 frameLen; +#endif + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if ((eLIM_STA_ROLE == psessionEntry->limSystemRole) && (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState)) + { + /*Every 15th deauth frame will be logged in kmsg*/ + if(!(pMac->lim.deauthMsgCnt & 0xF)) + { + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in DEAUTH_WT_STATE" + "(already processing previously received DEAUTH frame).." + "Dropping this.. Deauth Failed %d"),++pMac->lim.deauthMsgCnt);) + } + else + { + pMac->lim.deauthMsgCnt++; + } + return; + } + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Deauth frame from a BC/MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame from a BC/MC address"));) + + return; + } + + if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da)) + { + // Received Deauth frame for a MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame for a MC address"));) + + return; + } + +#ifdef WLAN_FEATURE_11W + /* PMF: If this session is a PMF session, then ensure that this frame was protected */ + if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR)) + { + PELOGE(limLog(pMac, LOGE, FL("received an unprotected deauth from AP"));) + // If the frame received is unprotected, forward it to the supplicant to initiate + // an SA query + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + //send the unprotected frame indication to SME + limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)), + psessionEntry->smeSessionId, psessionEntry); + return; + } +#endif + + // Get reasonCode from Deauthentication frame body + reasonCode = sirReadU16(pBody); + + PELOGE(limLog(pMac, LOGE, + FL("Received Deauth frame for Addr: "MAC_ADDRESS_STR" (mlm state = %s," + " sme state = %d systemrole = %d) with reason code %d from " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da), + limMlmStateStr(psessionEntry->limMlmState), psessionEntry->limSmeState, + psessionEntry->limSystemRole, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + + if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa)) + { + PELOGE(limLog(pMac, LOGE, + FL("Ignore the Deauth received, while waiting for ack of " + "disassoc/deauth"));) + limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1); + return; + } + + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE )||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + // Valid reasonCode in received Deauthentication frame + break; + + default: + // Invalid reasonCode in received Deauthentication frame + // Log error and ignore the frame + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame with invalid reasonCode %d from " + MAC_ADDRESS_STR), reasonCode, MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + } + else if (psessionEntry->limSystemRole == eLIM_STA_ROLE ||psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON: + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON: + case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON: + case eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON: + // Valid reasonCode in received Deauth frame + break; + + default: + // Invalid reasonCode in received Deauth frame + // Log error and ignore the frame + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame with invalid reasonCode %d from " + MAC_ADDRESS_STR), reasonCode, MAC_ADDR_ARRAY(pHdr->sa));) + + break; + } + } + else + { + // Received Deauth frame in either IBSS + // or un-known role. Log and ignore it + limLog(pMac, LOGE, + FL("received Deauth frame with reasonCode %d in role %d from " + MAC_ADDRESS_STR),reasonCode, psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pHdr->sa)); + + return; + } + + /** If we are in the middle of ReAssoc, a few things could happen: + * - STA is reassociating to current AP, and receives deauth from: + * a) current AP + * b) other AP + * - STA is reassociating to a new AP, and receives deauth from: + * c) current AP + * d) reassoc AP + * e) other AP + * + * The logic is: + * 1) If rcv deauth from an AP other than the one we're trying to + * reassociate with, then drop the deauth frame (case b, c, e) + * 2) If rcv deauth from the "new" reassoc AP (case d), then restore + * context with previous AP and send SME_REASSOC_RSP failure. + * 3) If rcv deauth from the reassoc AP, which is also the same + * AP we're currently associated with (case a), then proceed + * with normal deauth processing. + */ + if ( psessionEntry->limReAssocbssId!=NULL ) + { + pRoamSessionEntry = peFindSessionByBssid(pMac, psessionEntry->limReAssocbssId, &roamSessionId); + } + +#ifdef WLAN_FEATURE_LFR_MBB + if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) { + limLog(pMac, LOGE, FL("Ignore Deauth frame as LFR MBB in progress")); + return; + } +#endif + + if (limIsReassocInProgress(pMac,psessionEntry) || limIsReassocInProgress(pMac,pRoamSessionEntry)) { + if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from unknown/different " + "AP while ReAssoc. Ignore "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + PELOGE(limLog(pMac, LOGE, FL(" limReAssocbssId : "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(psessionEntry->limReAssocbssId));) + return; + } + + /** Received deauth from the new AP to which we tried to ReAssociate. + * Drop ReAssoc and Restore the Previous context( current connected AP). + */ + if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("received DeAuth from the New AP to " + "which ReAssoc is sent "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));) + PELOGE(limLog(pMac, LOGE, FL(" psessionEntry->bssId: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(psessionEntry->bssId));) + limRestorePreReassocState(pMac, + eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry); + return; + } + } + + + /* If received DeAuth from AP other than the one we're trying to join with + * nor associated with, then ignore deauth and delete Pre-auth entry. + */ + if(psessionEntry->limSystemRole != eLIM_AP_ROLE ){ + if (!IS_CURRENT_BSSID(pMac, pHdr->bssId, psessionEntry)) + { + PELOGE(limLog(pMac, LOGE, FL("received DeAuth from an AP other " + "than we're trying to join. Ignore. "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa));) + if (limSearchPreAuthList(pMac, pHdr->sa)) + { + limLog(pMac, LOG1, FL("Preauth entry exist. " + "Deleting... ")); + limDeletePreAuthNode(pMac, pHdr->sa); + } + return; + } + } + + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + + // Check for pre-assoc states + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + switch (psessionEntry->limMlmState) + { + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + /** + * AP sent Deauth frame while waiting + * for Auth frame2. Report Auth failure + * to SME. + */ + + // Log error + limLog(pMac, LOG1, + FL("received Deauth frame state %d with failure " + "code %d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + + limRestoreFromAuthState(pMac, eSIR_SME_DEAUTH_WHILE_JOIN, + reasonCode,psessionEntry); + + return; + + case eLIM_MLM_AUTHENTICATED_STATE: + limLog(pMac, LOG1, + FL("received Deauth frame state %d with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + /// Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pHdr->sa, + sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = reasonCode; + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_IND, + (tANI_U32 *) &mlmDeauthInd); + return; + + case eLIM_MLM_WT_ASSOC_RSP_STATE: + /** + * AP may have 'aged-out' our Pre-auth + * context. Delete local pre-auth context + * if any and issue ASSOC_CNF to SME. + */ + limLog(pMac, LOG1, + FL("received Deauth frame state %d with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + mlmAssocCnf.resultCode = eSIR_SME_DEAUTH_WHILE_JOIN; + mlmAssocCnf.protStatusCode = reasonCode; + + /* PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + + psessionEntry->limMlmState = + psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + // Deactive Association response timeout + limDeactivateAndChangeTimer( + pMac, + eLIM_ASSOC_FAIL_TIMER); + + limPostSmeMessage( + pMac, + LIM_MLM_ASSOC_CNF, + (tANI_U32 *) &mlmAssocCnf); + + return; + + case eLIM_MLM_WT_ADD_STA_RSP_STATE: + psessionEntry->fDeauthReceived = true; + PELOGW(limLog(pMac, LOGW, + FL("Received Deauth frame in state %d with Reason " + "Code %d from Peer"MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + return ; + + case eLIM_MLM_IDLE_STATE: + case eLIM_MLM_LINK_ESTABLISHED_STATE: +#ifdef FEATURE_WLAN_TDLS + if ((NULL != pStaDs) && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) + { + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in state %d with " + "reason code %d from Tdls peer" + MAC_ADDRESS_STR), + psessionEntry->limMlmState,reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry, + reasonCode); + return; + } + else + { + + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + /** + * This could be Deauthentication frame from + * a BSS with which pre-authentication was + * performed. Delete Pre-auth entry if found. + */ + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); +#ifdef FEATURE_WLAN_TDLS + } +#endif + break; + + case eLIM_MLM_WT_REASSOC_RSP_STATE: + limLog(pMac, LOGE, + FL("received Deauth frame state %d with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa)); + break; + + case eLIM_MLM_WT_FT_REASSOC_RSP_STATE: + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in FT state %d with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + break; + + default: + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame in state %d with " + "reasonCode=%d from "MAC_ADDRESS_STR), + psessionEntry->limMlmState, reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + return; + } + break; + + case eLIM_STA_IN_IBSS_ROLE: + break; + + case eLIM_AP_ROLE: + break; + + default: // eLIM_AP_ROLE or eLIM_BT_AMP_AP_ROLE + + + return; + } // end switch (pMac->lim.gLimSystemRole) + + + + /** + * Extract 'associated' context for STA, if any. + * This is maintained by DPH and created by LIM. + */ + if (NULL == pStaDs) + { + limLog(pMac, LOGE, FL("pStaDs is NULL")); + return; + } + + if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) + { + /** + * Already in the process of deleting context for the peer + * and received Deauthentication frame. Log and Ignore. + */ + PELOGE(limLog(pMac, LOGE, + FL("received Deauth frame from peer that is in state %d, addr " + MAC_ADDRESS_STR", isDisassocDeauthInProgress : %d\n"), + pStaDs->mlmStaContext.mlmState,MAC_ADDR_ARRAY(pHdr->sa), + pStaDs->isDisassocDeauthInProgress);) + return; + } + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes)reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH; + + + /* send the LOST_LINK_PARAMS_IND to SME*/ + limUpdateLostLinkParams(pMac, psessionEntry, pRxPacketInfo); + + /// Issue Deauth Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDeauthInd.peerMacAddr, + pStaDs->staAddr, + sizeof(tSirMacAddr)); + mlmDeauthInd.reasonCode = (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDeauthInd.deauthTrigger = eLIM_PEER_ENTITY_DEAUTH; + + + /* + * If we're in the middle of ReAssoc and received deauth from + * the ReAssoc AP, then notify SME by sending REASSOC_RSP with + * failure result code. SME will post the disconnect to the + * supplicant and the latter would start a fresh assoc. + */ + if (limIsReassocInProgress(pMac,psessionEntry)) { + /** + * AP may have 'aged-out' our Pre-auth + * context. Delete local pre-auth context + * if any and issue REASSOC_CNF to SME. + */ + if (limSearchPreAuthList(pMac, pHdr->sa)) + limDeletePreAuthNode(pMac, pHdr->sa); + + if (psessionEntry->limAssocResponseData) { + vos_mem_free(psessionEntry->limAssocResponseData); + psessionEntry->limAssocResponseData = NULL; + } + + PELOGE(limLog(pMac, LOGE, FL("Rcv Deauth from ReAssoc AP. " + "Issue REASSOC_CNF. "));) + /* + * TODO: Instead of overloading eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE + * it would have been good to define/use a different failure type. + * Using eSIR_SME_FT_REASSOC_FAILURE does not seem to clean-up + * properly and we end up seeing "transmit queue timeout". + */ + limPostReassocFailure(pMac, eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE, + eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + return; + } + /* reset the deauthMsgCnt here since we are able to Process + * the deauth frame and sending up the indication as well */ + if(pMac->lim.deauthMsgCnt != 0) + { + pMac->lim.deauthMsgCnt = 0; + } + /// Deauthentication from peer MAC entity + limPostSmeMessage(pMac, LIM_MLM_DEAUTH_IND, (tANI_U32 *) &mlmDeauthInd); + + // send eWNI_SME_DEAUTH_IND to SME + limSendSmeDeauthInd(pMac, pStaDs, psessionEntry); + return; + +} /*** end limProcessDeauthFrame() ***/ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c new file mode 100644 index 000000000000..88585abac913 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessDisassocFrame.cc contains the code + * for processing Disassocation Frame. + * Author: Chandra Modumudi + * Date: 03/24/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "wniCfg.h" + +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSendMessages.h" +#include "schApi.h" +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + +/** + * limProcessDisassocFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Disassociation frame reception. + * + *LOGIC: + * + *ASSUMPTIONS: + * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'. + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param *pRxPacketInfo - A pointer to Rx packet info structure + * @return None + */ +void +limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U16 aid, reasonCode; + tpSirMacMgmtHdr pHdr; + tpDphHashNode pStaDs; + tLimMlmDisassocInd mlmDisassocInd; +#ifdef WLAN_FEATURE_11W + tANI_U32 frameLen; +#endif + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (limIsGroupAddr(pHdr->sa)) + { + // Received Disassoc frame from a BC/MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOG1, + FL("received Disassoc frame from a BC/MC address"));) + + return; + } + + if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da)) + { + // Received Disassoc frame for a MC address + // Log error and ignore it + PELOGE(limLog(pMac, LOG1, + FL("received Disassoc frame for a MC address"));) + + return; + } + +#ifdef WLAN_FEATURE_11W + /* PMF: If this session is a PMF session, then ensure that this frame was protected */ + if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR)) + { + PELOGE(limLog(pMac, LOG1, FL("received an unprotected disassoc from AP"));) + // If the frame received is unprotected, forward it to the supplicant to initiate + // an SA query + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + //send the unprotected frame indication to SME + limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType, + (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)), + psessionEntry->smeSessionId, psessionEntry); + return; + } +#endif + + // Get reasonCode from Disassociation frame body + reasonCode = sirReadU16(pBody); + + limLog(pMac, LOGE, + FL("Received Disassoc frame for Addr: "MAC_ADDRESS_STR + "(mlm state=%s, sme state=%d)," + "with reason code %d from "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da), + limMlmStateStr(psessionEntry->limMlmState), psessionEntry->limSmeState, + reasonCode, MAC_ADDR_ARRAY(pHdr->sa)); + + /** + * Extract 'associated' context for STA, if any. + * This is maintained by DPH and created by LIM. + */ + pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + /** + * Disassociating STA is not associated. + * Log error. + */ + PELOGE(limLog(pMac, LOG1, + FL("received Disassoc frame from STA that does not have context " + "reasonCode=%d, addr "MAC_ADDRESS_STR), + reasonCode,MAC_ADDR_ARRAY(pHdr->sa));) + + return; + } + + if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa)) + { + PELOGE(limLog(pMac, LOG1, + FL("Ignore the DisAssoc received, while waiting " + "for ack of disassoc/deauth"));) + limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1); + return; + } + +#ifdef WLAN_FEATURE_LFR_MBB + if (lim_is_mbb_reassoc_in_progress(pMac, psessionEntry)) { + limLog(pMac, LOGE, FL("Ignore Disassoc frame as LFR MBB in progress")); + return; + } +#endif + + /** If we are in the Wait for ReAssoc Rsp state */ + if (limIsReassocInProgress(pMac,psessionEntry)) { + /** If we had received the DisAssoc from, + * a. the Current AP during ReAssociate to different AP in same ESS + * b. Unknown AP + * drop/ignore the DisAssoc received + */ + if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("Ignore the DisAssoc received, while " + "Processing ReAssoc with different/unknown AP"));) + return; + } + /** If the Disassoc is received from the new AP to which we tried to ReAssociate + * Drop ReAssoc and Restore the Previous context( current connected AP). + */ + if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) { + PELOGE(limLog(pMac, LOGE, FL("received Disassoc from the New AP to " + "which ReAssoc is sent "));) + limRestorePreReassocState(pMac, + eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry); + return; + } + } + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: + case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON: + case eSIR_MAC_MIC_FAILURE_REASON: + case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON: + case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON: + case eSIR_MAC_RSN_IE_MISMATCH_REASON: + case eSIR_MAC_1X_AUTH_FAILURE_REASON: + // Valid reasonCode in received Disassociation frame + break; + + default: + // Invalid reasonCode in received Disassociation frame + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame with invalid reasonCode " + "%d from "MAC_ADDRESS_STR), + reasonCode, MAC_ADDR_ARRAY(pHdr->sa));) + break; + } + } + else if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) )) + { + switch (reasonCode) + { + case eSIR_MAC_UNSPEC_FAILURE_REASON: + case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON: + case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON: + case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON: + case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON: + case eSIR_MAC_MIC_FAILURE_REASON: + case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON: + case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON: + case eSIR_MAC_RSN_IE_MISMATCH_REASON: + case eSIR_MAC_1X_AUTH_FAILURE_REASON: + case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON: + case eSIR_MAC_PEER_REJECT_MECHANISIM_REASON: + // Valid reasonCode in received Disassociation frame + break; + + case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON: + case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON: + // Valid reasonCode in received Disassociation frame + // as long as we're not about to channel switch + if(psessionEntry->gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE) + { + limLog(pMac, LOGE, + FL("Ignoring disassoc frame due to upcoming " + "channel switch, from "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa)); + return; + } + break; + + default: + // Invalid reasonCode in received Disassociation frame + // Log error and ignore the frame + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame with invalid reasonCode " + "%d from "MAC_ADDRESS_STR), reasonCode, + MAC_ADDR_ARRAY(pHdr->sa));) + break; + } + } + else + { + // Received Disassociation frame in either IBSS + // or un-known role. Log and ignore it + limLog(pMac, LOG1, + FL("received Disassoc frame with invalid reasonCode %d in role " + "%d in sme state %d from "MAC_ADDRESS_STR), reasonCode, + psessionEntry->limSystemRole, psessionEntry->limSmeState, + MAC_ADDR_ARRAY(pHdr->sa)); + + return; + } + + if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) + { + /** + * Already in the process of deleting context for the peer + * and received Disassociation frame. Log and Ignore. + */ + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame in state %d from "MAC_ADDRESS_STR + ",isDisassocDeauthInProgress : %d\n"), + pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa), + pStaDs->isDisassocDeauthInProgress);) + + return; + } + + if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + { + /** + * Requesting STA is in some 'transient' state? + * Log error. + */ + if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) + pStaDs->mlmStaContext.updateContext = 1; + + PELOGE(limLog(pMac, LOGE, + FL("received Disassoc frame from peer that is in state %d, addr " + MAC_ADDRESS_STR), + pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));) + + } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) + + pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode; + + // Issue Disassoc Indication to SME. + vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr, + (tANI_U8 *) pStaDs->staAddr, + sizeof(tSirMacAddr)); + mlmDisassocInd.reasonCode = + (tANI_U8) pStaDs->mlmStaContext.disassocReason; + mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC; + + /* Update PE session Id */ + mlmDisassocInd.sessionId = psessionEntry->peSessionId; + + if (limIsReassocInProgress(pMac,psessionEntry)) { + + /* If we're in the middle of ReAssoc and received disassoc from + * the ReAssoc AP, then notify SME by sending REASSOC_RSP with + * failure result code. By design, SME will then issue "Disassoc" + * and cleanup will happen at that time. + */ + PELOGE(limLog(pMac, LOGE, FL("received Disassoc from AP while waiting " + "for Reassoc Rsp"));) + + if (psessionEntry->limAssocResponseData) { + vos_mem_free(psessionEntry->limAssocResponseData); + psessionEntry->limAssocResponseData = NULL; + } + + limRestorePreReassocState(pMac,eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry); + return; + } + limUpdateLostLinkParams(pMac, psessionEntry, pRxPacketInfo); + limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND, + (tANI_U32 *) &mlmDisassocInd); + + + // send eWNI_SME_DISASSOC_IND to SME + limSendSmeDisassocInd(pMac, pStaDs,psessionEntry); + + return; +} /*** end limProcessDisassocFrame() ***/ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessLmmMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessLmmMessages.c new file mode 100644 index 000000000000..3b17bf80cbdd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessLmmMessages.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessLmmMessages.cc contains the code + * for processing SME/LMM messages related to ANI feature set. + * Author: Chandra Modumudi + * Date: 10/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "aniGlobal.h" +#include "wniApi.h" +#include "wniCfg.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSerDesUtils.h" +#include "limPropExtsUtils.h" +#include "limSession.h" + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c new file mode 100644 index 000000000000..ddb9f5fa4812 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -0,0 +1,2800 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file lim ProcessMessageQueue.cc contains the code + * for processing LIM message Queue. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniApi.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_wda.h" + +#include "wniCfg.h" +#include "cfgApi.h" +#include "sirCommon.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" + +#include "limAdmitControl.h" +#include "pmmApi.h" +#include "limIbssPeerMgmt.h" +#include "schApi.h" +#include "limSession.h" +#include "limSendMessages.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +#include "limFT.h" +#endif + +#ifdef WMM_APSD +#include "wmmApsd.h" +#endif + +#ifdef WLAN_FEATURE_RMC +#include "limRMC.h" +#endif + +#include "vos_types.h" +#include "vos_packet.h" +#include "vos_memory.h" + +/* This value corresponds to 500 ms */ +#define MAX_PROBEREQ_TIME 50 + +#ifdef WLAN_FEATURE_EXTSCAN +#define SIZE_OF_FIXED_PARAM 12 +#endif + +#define CHECK_BIT(value, mask) ((value) & (1 << (mask))) + +void limLogSessionStates(tpAniSirGlobal pMac); + +/** ------------------------------------------------------------- +\fn defMsgDecision +\brief The function decides whether to defer a message or not in limProcessMessage function +\param tpAniSirGlobal pMac +\param tSirMsgQ limMsg +\param tSirMacTspecIE *ppInfo +\return none + -------------------------------------------------------------*/ + +tANI_U8 static +defMsgDecision(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + + +/* this function should not changed */ + if(pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + { + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, limMsgStr(limMsg->type), pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limHandleDeferMsgError(pMac, limMsg); + } + return true; + } + + //When defer is requested then defer all the messages except HAL responses. + if((!limIsSystemInScanState(pMac)) && (true != GET_LIM_PROCESS_DEFD_MESGS(pMac)) && + !pMac->lim.gLimSystemInScanLearnMode) + { + if((limMsg->type != WDA_ADD_BSS_RSP) && + (limMsg->type != WDA_DELETE_BSS_RSP) && + (limMsg->type != WDA_ADD_STA_RSP) && + (limMsg->type != WDA_ADD_STA_SELF_RSP) && + (limMsg->type != WDA_DEL_STA_SELF_RSP) && + (limMsg->type != WDA_DELETE_STA_RSP)&& + (limMsg->type != WDA_SET_BSSKEY_RSP)&& + (limMsg->type != WDA_SET_STAKEY_RSP)&& + (limMsg->type != WDA_SET_STA_BCASTKEY_RSP) && + (limMsg->type != eWNI_SME_START_REQ) && + (limMsg->type != WDA_AGGR_QOS_RSP) && + (limMsg->type != WDA_REMOVE_BSSKEY_RSP) && + (limMsg->type != WDA_REMOVE_STAKEY_RSP) && + (limMsg->type != WDA_SET_MIMOPS_RSP)&& + (limMsg->type != WDA_ADDBA_RSP) && + (limMsg->type != WDA_ENTER_BMPS_RSP) && + (limMsg->type != WDA_EXIT_BMPS_RSP) && + (limMsg->type != WDA_ENTER_IMPS_RSP) && + (limMsg->type != WDA_EXIT_IMPS_RSP) && + (limMsg->type != WDA_ENTER_UAPSD_RSP) && + (limMsg->type != WDA_EXIT_UAPSD_RSP) && + (limMsg->type != WDA_WOWL_ENTER_RSP) && + (limMsg->type != WDA_WOWL_EXIT_RSP) && + (limMsg->type != WDA_SWITCH_CHANNEL_RSP) && + (limMsg->type != WDA_P2P_NOA_ATTR_IND) && + (limMsg->type != WDA_P2P_NOA_START_IND) && +#ifdef FEATURE_OEM_DATA_SUPPORT + (limMsg->type != WDA_START_OEM_DATA_RSP) && +#endif + (limMsg->type != WDA_ADD_TS_RSP) && + + /* LIM won't process any defer queue commands if gLimAddtsSent is set to + TRUE. gLimAddtsSent will be set TRUE to while sending ADDTS REQ. Say, + when deferring is enabled, if SIR_LIM_ADDTS_RSP_TIMEOUT is posted + (because of not receiving ADDTS RSP) then this command will be added + to defer queue and as gLimAddtsSent is set TRUE LIM will never + process any commands from defer queue, including + SIR_LIM_ADDTS_RSP_TIMEOUT. Hence allowing SIR_LIM_ADDTS_RSP_TIMEOUT + command to be processed with deferring enabled, so that this will be + processed immediately and sets gLimAddtsSent to FALSE. + */ + (limMsg->type != SIR_LIM_ADDTS_RSP_TIMEOUT) && + (limMsg->type != WDA_LOST_LINK_PARAMS_IND) && + /* Allow processing of RX frames while awaiting reception of + ADD TS response over the air. This logic particularly handles the + case when host sends ADD BA request to FW after ADD TS request + is sent over the air and ADD TS response received over the air */ + !(limMsg->type == SIR_BB_XPORT_MGMT_MSG && pMac->lim.gLimAddtsSent)) + { + PELOG1(limLog(pMac, LOG1, FL("Defer the current message %s , gLimProcessDefdMsgs is false and system is not in scan/learn mode"), + limMsgStr(limMsg->type));) + + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("Unable to Defer message(0x%X) %s limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, limMsgStr(limMsg->type), pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limHandleDeferMsgError(pMac, limMsg); + + } + return true; + } + } + return false; +} + +/* +* Beacon Handling Cases: +* during scanning, when no session is active: +* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked. +* during scanning, when any session is active, but beacon/Pr does not belong to that session, psessionEntry will be null. +* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked. +* during scanning, when any session is active, and beacon/Pr belongs to one of the session, psessionEntry will not be null. +* handled by limHandleFramesInScanState before __limHandleBeacon call is invoked. +* Not scanning, no session: +* there should not be any beacon coming, if coming, should be dropped. +* Not Scanning, +*/ +static void +__limHandleBeacon(tpAniSirGlobal pMac, tpSirMsgQ pMsg, tpPESession psessionEntry) +{ + /* checking for global SME state...*/ + tANI_U8 *pRxPacketInfo; + limGetBDfromRxPacket(pMac, pMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo); + + //This function should not be called if beacon is received in scan state. + //So not doing any checks for the global state. + + if(psessionEntry == NULL) + { + schBeaconProcess(pMac, pRxPacketInfo, NULL); + } + else if( (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) || + (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE)) + { + schBeaconProcess(pMac, pRxPacketInfo, psessionEntry); + } + else + limProcessBeaconFrame(pMac, pRxPacketInfo, psessionEntry); + + return; +} + + +//Fucntion prototype +void limProcessNormalHddMsg(tpAniSirGlobal pMac, tSirMsgQ *pLimMsg, tANI_U8 fRspReqd); + +/** + * limDeferMsg() + * + *FUNCTION: + * This function is called to defer the messages received + * during Learn mode + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg of type tSirMsgQ - Pointer to the message structure + * @return None + */ + +tANI_U32 +limDeferMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tANI_U32 retCode = TX_SUCCESS; + + retCode = limWriteDeferredMsgQ(pMac, pMsg); + + if (retCode == TX_SUCCESS) + { + limLog(pMac, LOG1, + FL("Deferred message(0x%X) limSmeState %d (prev sme state %d)" + " sysRole %d mlm state %d (prev mlm state %d)"), + pMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, + pMac->lim.gLimPrevMlmState); + MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DEFERRED));) + } + else + { + limLog(pMac, LOG1, FL("Dropped lim message (0x%X)"), pMsg->type); + MTRACE(macTraceMsgRx(pMac, NO_SESSION, LIM_TRACE_MAKE_RXMSG(pMsg->type, LIM_MSG_DROPPED));) + } + + return retCode; +} /*** end limDeferMsg() ***/ + + + +/** + * limHandleFramesInScanState() + * + *FUNCTION: + * This function is called to process 802.11 frames + * received by LIM in scan state. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Received message + * @param pRxPacketInfo - Pointer to Rx packet info structure + * @param deferMsg - Indicates whether the frame shall be deferred + * @return None + */ + +static void +limHandleFramesInScanState(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pRxPacketInfo, tANI_U8 *deferMsg, tpPESession psessionEntry) +{ + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr; + + *deferMsg = false; + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + fc = pHdr->fc; + limLog( pMac, LOG2, FL("ProtVersion %d, Type %d, Subtype %d"), + fc.protVer, fc.type, fc.subType ); + + // defer all message in scan state except for Beacons and Probe Response + if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_BEACON)) + { + if (psessionEntry == NULL) + limProcessBeaconFrameNoSession(pMac, pRxPacketInfo); + else + limProcessBeaconFrame(pMac, pRxPacketInfo,psessionEntry); + } + else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_PROBE_RSP)) + { + if (psessionEntry == NULL) + limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo); + else + limProcessProbeRspFrame(pMac, pRxPacketInfo,psessionEntry); + } + else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_PROBE_REQ)) + { + limProcessProbeReqFrame_multiple_BSS(pMac, pRxPacketInfo, psessionEntry); + } + else if ((fc.type == SIR_MAC_MGMT_FRAME) && (fc.subType == SIR_MAC_MGMT_ACTION)) + { + limProcessActionFrameNoSession( pMac, pRxPacketInfo); + } + else + { + *deferMsg = true; + return; + } + + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr); + return; + +} /*** end limHandleFramesInScanState() ***/ + +/** ------------------------------------------------------------ +\brief This function handles Unknown Unicast (A2 Index) +\ packets. +\param tpAniSirGlobal pMac Global Mac data structure +\param void *pRxPacketInfo Pointer to Buffer Descriptor +\return none +\ +\ -------------------------------------------------------------- */ +static void limHandleUnknownA2IndexFrames(tpAniSirGlobal pMac, void *pRxPacketInfo,tpPESession psessionEntry) +{ + /* addr2 mismatch interrupt occurred this means previous + disassociation was not successful + In Volans pRxPacketInfo only contains pointer 48-bit address2 field */ + /*Send disassociation message again*/ + //Dinesh need one more arguement. + //limSendDisassocMgmtFrame(pMac, eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON,(tANI_U8 *) pRxPacketInfo); + //TODO: verify this + //This could be a public action frame. + if( psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE ) + limProcessActionFrameNoSession(pMac, (tANI_U8 *) pRxPacketInfo); + +#ifdef FEATURE_WLAN_TDLS + { + tpSirMacDataHdr3a pMacHdr; + pMacHdr = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo); + + if (limIsGroupAddr(pMacHdr->addr2)) + { + limLog(pMac, LOG1, FL("Ignoring A2 Invalid Packet received for MC/BC:")); + limPrintMacAddr(pMac, pMacHdr->addr2, LOG1); + + return; + } + /* TDLS_hklee: move down here to reject Addr2 == Group (first checking above) + and also checking if SystemRole == STA */ + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + /* ADD handling of Public Action Frame */ + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, \ + ("limHandleUnknownA2IndexFrames: type=0x%x, subtype=0x%x"),pMacHdr->fc.type, pMacHdr->fc.subType)); + switch (pMacHdr->fc.type) + { + case SIR_MAC_MGMT_FRAME: + { + switch (pMacHdr->fc.subType) + { + case SIR_MAC_MGMT_ACTION: + { + limProcessActionFrame(pMac, pRxPacketInfo, psessionEntry) ; + break ; + } + default: + { + break ; + } + } + } + default: + { + break ; + } + } + } + } +#endif + + + return; +} + +/** + * limCheckMgmtRegisteredFrames() + * + *FUNCTION: + * This function is called to process to check if received frame match with + * any of the registered frame from HDD. If yes pass this frame to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pBd Pointer to the received Buffer Descriptor+payload + * @param *psessionEntry Pointer to session on which packet is received + * @return None + */ +static tANI_BOOLEAN +limCheckMgmtRegisteredFrames(tpAniSirGlobal pMac, tANI_U8 *pBd, + tpPESession psessionEntry) +{ + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr; + tANI_U8 *pBody; + tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL; + tANI_U16 frameType; + tANI_U16 framelen; + tANI_U8 type,subType; + tANI_BOOLEAN match = VOS_FALSE; + VOS_STATUS vosStatus; + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + fc = pHdr->fc; + frameType = (fc.type << 2 ) | (fc.subType << 4); + pBody = WDA_GET_RX_MPDU_DATA(pBd); + framelen = WDA_GET_RX_PAYLOAD_LEN(pBd); + + vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t**)&pLimMgmtRegistration); + + while(pLimMgmtRegistration != NULL) + { + type = (pLimMgmtRegistration->frameType >> 2) & 0x03; + subType = (pLimMgmtRegistration->frameType >> 4) & 0x0f; + if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME) + && (subType == SIR_MAC_MGMT_RESERVED15) ) + { + limLog( pMac, LOG3, + FL("rcvd frame match with SIR_MAC_MGMT_RESERVED15")); + match = VOS_TRUE; + break; + } + + if (pLimMgmtRegistration->frameType == frameType) + { + if (pLimMgmtRegistration->matchLen > 0) + { + if (pLimMgmtRegistration->matchLen <= framelen) + { + if (vos_mem_compare(pLimMgmtRegistration->matchData, + pBody, pLimMgmtRegistration->matchLen)) + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + } + else + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + + vosStatus = + vos_list_peek_next ( &pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t*) pLimMgmtRegistration, + (vos_list_node_t**) &pNext ); + pLimMgmtRegistration = pNext; + pNext = NULL; + } + + if (match) + { + limLog( pMac, LOG1, + FL("rcvd frame match with registered frame params")); + + /* Indicate this to SME */ + limSendSmeMgmtFrameInd( pMac, pLimMgmtRegistration->sessionId, + pBd, psessionEntry, WDA_GET_RX_RSSI_DB(pBd)); + + if ( (type == SIR_MAC_MGMT_FRAME) && (fc.type == SIR_MAC_MGMT_FRAME) + && (subType == SIR_MAC_MGMT_RESERVED15) ) + { + // These packets needs to be processed by PE/SME as well as HDD. + // If it returns TRUE here, the packet is forwarded to HDD only. + match = VOS_FALSE; + } + } + + return match; +} /*** end limCheckMgmtRegisteredFrames() ***/ + +#ifdef WLAN_FEATURE_EXTSCAN + +void +limProcessEXTScanRealTimeData(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tpSirMacMgmtHdr pHdr = NULL; + eHalStatus status; + void *pCallbackContext; + tANI_U8 rfBand = 0; + tANI_U8 rxChannelInBD = 0; + tSirMacFrameCtl fc; + tDot11fBeacon *pBeacon = NULL; + tDot11fProbeResponse *pProbeResponse = NULL; + tSirWifiFullScanResultEvent tEXTScanFullScanResult; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + fc = pHdr->fc; + + limLog(pMac, LOG2, + FL("Received EXTScan Real Time data with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + + limPrintMacAddr(pMac, pHdr->sa, LOG2); + + vos_mem_set((tANI_U8 *) &tEXTScanFullScanResult, + sizeof(tSirWifiFullScanResultEvent), 0); + + tEXTScanFullScanResult.ap.ts = vos_get_monotonic_boottime(); + + vos_mem_copy(&tEXTScanFullScanResult.ap.bssid, + pHdr->bssId, sizeof(tSirMacAddr)); + + limPrintMacAddr(pMac, pHdr->bssId, LOG2); + + + rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); + rxChannelInBD = WDA_GET_RX_CH(pRxPacketInfo); + + if ((!rfBand) || IS_5G_BAND(rfBand)) + { + rxChannelInBD = limUnmapChannel(rxChannelInBD); + } + + tEXTScanFullScanResult.ap.channel = + (tANI_U32)vos_chan_to_freq(rxChannelInBD); + tEXTScanFullScanResult.ap.rssi = WDA_GET_RX_RSSI_DB(pRxPacketInfo); + + if (fc.subType == SIR_MAC_MGMT_BEACON) + { + limLog( pMac, LOG2, FL("Beacon ")); + + pBeacon = vos_mem_malloc(sizeof(tDot11fBeacon)); + if ( NULL == pBeacon ){ + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return; + } + + vos_mem_set( ( tANI_U8* )pBeacon, sizeof(tDot11fBeacon), 0 ); + // delegate to the framesc-generated code, + status = dot11fUnpackBeacon( pMac, + (tANI_U8 *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo), + WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo), pBeacon ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Beacons" + "(%d)"), status); + vos_mem_free(pBeacon); + return; + } + if ( pBeacon->SSID.present ) + { + vos_mem_copy(tEXTScanFullScanResult.ap.ssid, + pBeacon->SSID.ssid, + pBeacon->SSID.num_ssid); + } + //NULL Terminate the string. + tEXTScanFullScanResult.ap.ssid[pBeacon->SSID.num_ssid] = 0; + tEXTScanFullScanResult.ap.beaconPeriod = + pBeacon->BeaconInterval.interval; + tEXTScanFullScanResult.ap.capability = + *((tANI_U16 *)&pBeacon->Capabilities); + vos_mem_free(pBeacon); + } + else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP) + { + limLog( pMac, LOG2, FL("Probe rsp ")); + + pProbeResponse = vos_mem_malloc(sizeof(tDot11fProbeResponse)); + if ( NULL == pProbeResponse ){ + limLog(pMac, LOGE, FL("Failed to allocate memory\n") ); + return; + } + + vos_mem_set( ( tANI_U8* )pProbeResponse, + sizeof(tDot11fProbeResponse), 0); + //delegate to the framesc-generated code, + status = dot11fUnpackProbeResponse( pMac, + (tANI_U8 *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo), + WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo), pProbeResponse ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Probe" + "Response (%d"), status); + vos_mem_free(pProbeResponse); + return; + } + if ( pProbeResponse->SSID.present ) + { + vos_mem_copy(tEXTScanFullScanResult.ap.ssid, + pProbeResponse->SSID.ssid, + pProbeResponse->SSID.num_ssid); + } + //NULL Terminate the string. + tEXTScanFullScanResult.ap.ssid[pProbeResponse->SSID.num_ssid] = 0; + tEXTScanFullScanResult.ap.beaconPeriod = + pProbeResponse->BeaconInterval.interval; + tEXTScanFullScanResult.ap.capability = + *(((tANI_U16 *)&pProbeResponse->Capabilities)); + + vos_mem_free(pProbeResponse); + } + else + { + limLog( pMac, LOGE, FL("Wrong frame Type %d, Subtype %d for LFR"), + fc.type, fc.subType); + VOS_ASSERT(0); + return; + } + + tEXTScanFullScanResult.requestId = pMac->sme.extScanStartReqId; + tEXTScanFullScanResult.ieLength = + WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIZE_OF_FIXED_PARAM; + tEXTScanFullScanResult.ie =(tSirInformationElement *) + ((tANI_U8 *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo) + SIZE_OF_FIXED_PARAM); + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + if(pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, + SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND, + (tANI_U8 *)&tEXTScanFullScanResult); + } + + return; +} /*** end limProcessEXTScanRealTimeData() ***/ +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef SAP_AUTH_OFFLOAD +/* + * lim_process_sap_offload_indication: function to process add sta/ del sta + * indication for SAP auth offload. + * + * @pMac: mac context + * @pRxPacketInfo: rx buffer + * + * This Function will go through buffer and if + * indication type is ADD_STA_IND, function will extract all data related to + * client and will call limAddSta + * and if indication type is DEL_STA_IND, function will call + * limSendSmeDisassocInd to do cleanup for station. + * + * Return : none + */ +static void lim_process_sap_offload_indication(tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo) +{ + int i = 0; + tSapOfldIndications *sap_offload_indication_rx_buf = + (tSapOfldIndications *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + tSapOfldInd *sap_offload_ind = + (tSapOfldInd*)sap_offload_indication_rx_buf->indications; + + limLog( pMac, LOG1, + FL("Notify SME with Sap Offload ind and indication type is %d num_indication %d \n"), + sap_offload_ind->indType, + (tANI_U8) sap_offload_indication_rx_buf->num_indications); + + for (i=1; i <= (tANI_U8)(sap_offload_indication_rx_buf->num_indications); + i++) + { + if (sap_offload_ind->indType == SAP_OFFLOAD_ADD_STA_IND) + { + tSapOfldAddStaIndMsg *add_sta; + limLog( pMac, LOG1, + FL("Indication type is SAP_OFFLOAD_ADD_STA_IND")); + add_sta = (tSapOfldAddStaIndMsg *)sap_offload_ind->indication; + lim_sap_offload_add_sta(pMac, add_sta); + if (sap_offload_indication_rx_buf->num_indications > 1) + sap_offload_ind = + (tSapOfldInd *)((tANI_U8 *)sap_offload_ind + + sizeof(tSapOfldAddStaIndMsg) - sizeof(tANI_U8)+ + add_sta->data_len + sizeof(tANI_U32)); + } + else if (sap_offload_ind->indType == SAP_OFFLOAD_DEL_STA_IND) + { + tSapOfldDelStaIndMsg *del_sta; + limLog( pMac, LOG1, + FL("Indication type is SAP_OFFLOAD_DEL_STA_IND")); + del_sta = (tSapOfldDelStaIndMsg *)sap_offload_ind->indication; + lim_sap_offload_del_sta(pMac, del_sta); + sap_offload_ind = (tSapOfldInd *)((tANI_U8 *)sap_offload_ind + + sizeof(tSapOfldDelStaIndMsg) + sizeof(tANI_U32)); + } + else + { + limLog(pMac, LOGE, FL("No Valid indication for connected station")); + } + } + +} +#endif + +/** + * limHandle80211Frames() + * + *FUNCTION: + * This function is called to process 802.11 frames + * received by LIM. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pMsg of type tSirMsgQ - Pointer to the message structure + * @return None + */ + +static void + +limHandle80211Frames(tpAniSirGlobal pMac, tpSirMsgQ limMsg, tANI_U8 *pDeferMsg) +{ + tANI_U8 *pRxPacketInfo = NULL; + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr=NULL; + tpPESession psessionEntry=NULL; + tANI_U8 sessionId; + tAniBool isFrmFt = FALSE; + tANI_U16 fcOffset = WLANHAL_RX_BD_HEADER_SIZE; + tANI_S8 pe_sessionid = -1; + + *pDeferMsg= false; + limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo); + +#ifdef SAP_AUTH_OFFLOAD + if ((WDA_GET_SAP_AUTHOFFLOADIND(pRxPacketInfo) == 1) && + pMac->sap_auth_offload) + { + lim_process_sap_offload_indication(pMac, pRxPacketInfo); + goto end; + } +#endif + +#ifdef WLAN_FEATURE_EXTSCAN + + if ( WDA_GET_EXTSCANFULLSCANRESIND(pRxPacketInfo)) + { + limLog( pMac, LOG2, FL("Notify EXTSCAN scan results to the HDD")); + limProcessEXTScanRealTimeData(pMac, pRxPacketInfo); + goto end; + } +#endif //WLAN_FEATURE_EXTSCAN + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + isFrmFt = WDA_GET_RX_FT_DONE(pRxPacketInfo); + fcOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(pRxPacketInfo); + fc = pHdr->fc; + +#ifdef WLAN_DUMP_MGMTFRAMES + limLog( pMac, LOGE, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"), + fc.protVer, fc.type, fc.subType, + WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo)); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, pHdr, + WDA_GET_RX_MPDU_HEADER_LEN(pRxPacketInfo)); +#endif + + if ((fc.type == SIR_MAC_MGMT_FRAME) && + (fc.subType != SIR_MAC_MGMT_BEACON)) + { + limLog(pMac, LOG1, FL("RX MGMT - Type %hu, SubType %hu," + "Seq.no %d, Source mac-addr " + MAC_ADDRESS_STR), fc.type, fc.subType, + ((pHdr->seqControl.seqNumHi << 4) | + (pHdr->seqControl.seqNumLo)), + MAC_ADDR_ARRAY(pHdr->sa)); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo)) + { + limLog( pMac, LOGW, FL("Notify SME with candidate ind")); + + if (WDA_IF_PER_ROAMCANDIDATEIND(pRxPacketInfo) && + IS_FEATURE_SUPPORTED_BY_FW(PER_BASED_ROAMING) && + pMac->roam.configParam.isPERRoamEnabled) + { + tSirPerRoamScanResult *candidateChanInfo = + (tSirPerRoamScanResult *)WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + int chanInfoLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) + - sizeof(tANI_U32); + + /* Translate network buffer into system buffer */ + vos_buff_to_hl_buff((v_U8_t *)candidateChanInfo, + WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo)); + + /* Max candidates allowed */ + if (candidateChanInfo->candidateCount > + SIR_PER_ROAM_MAX_CANDIDATE_CNT) + { + limLog(pMac, LOGE, + FL("Got maximum candidates as %d, setting count as %d"), + candidateChanInfo->candidateCount, + SIR_PER_ROAM_MAX_CANDIDATE_CNT); + candidateChanInfo->candidateCount = + SIR_PER_ROAM_MAX_CANDIDATE_CNT; + } + + vos_mem_set(&pMac->candidateChannelInfo, + sizeof(tSirCandidateChanInfo) * + SIR_PER_ROAM_MAX_CANDIDATE_CNT, 0); + + vos_mem_copy(&pMac->candidateChannelInfo, + candidateChanInfo->channelInfo, + (sizeof(tSirCandidateChanInfo) * + SIR_PER_ROAM_MAX_CANDIDATE_CNT) < chanInfoLen ? + (sizeof(tSirCandidateChanInfo) * + SIR_PER_ROAM_MAX_CANDIDATE_CNT): + chanInfoLen); + + limLog(pMac, LOG1, + FL("PER based Roam candidates %d"), + candidateChanInfo->candidateCount); + + pMac->PERroamCandidatesCnt = candidateChanInfo->candidateCount; + } else + { + /* Normal RSSI based roaming */ + pMac->PERroamCandidatesCnt = 0; + } + + pe_sessionid = limGetInfraSessionId(pMac); + if (pe_sessionid != -1) { + psessionEntry = peFindSessionBySessionId(pMac, pe_sessionid); + if (psessionEntry != NULL) + { + if ((psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) || + (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE)) + { + limLog(pMac, LOG1, + FL("Drop candidate ind as deauth/disassoc in progress")); + goto end; + } + } + } + else + limLog(pMac, LOGE, + FL("session id doesn't exist for infra")); + + //send a session 0 for now - TBD + limSendSmeCandidateFoundInd(pMac, 0); + goto end; + } + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + { + if (fc.subType == SIR_MAC_MGMT_BEACON) + { + limLog( pMac, LOG2, FL("Save this beacon in LFR cache")); + __limHandleBeacon(pMac, limMsg, NULL); + } + else if (fc.subType == SIR_MAC_MGMT_PROBE_RSP) + { + limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache")); + limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo); + } + else + { + limLog( pMac, LOGE, FL("Wrong frame Type %d, Subtype %d for LFR"), + fc.type, fc.subType); + } + goto end; + } +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#ifdef FEATURE_WLAN_ESE + if (fc.type == SIR_MAC_DATA_FRAME && isFrmFt) + { +#if 0 // Ese TBD Need to PORT + tpSirMacDot3Hdr pDataFrmHdr; + + pDataFrmHdr = (tpSirMacDot3Hdr)((tANI_U8 *)pBD+ WLANHAL_RX_BD_GET_MPDU_H_OFFSET(pBD)); + if((psessionEntry = peFindSessionByBssid(pMac,pDataFrmHdr->sa,&sessionId))== NULL) + { + limLog( pMac, LOGE, FL("Session not found for Frm type %d, subtype %d, SA: "), fc.type, fc.subType); + limPrintMacAddr(pMac, pDataFrmHdr->sa, LOGE); + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pBD, limMsg->bodyptr); + return; + } + + if (!psessionEntry->isESEconnection) + { + limLog( pMac, LOGE, FL("LIM received Type %d, Subtype %d in Non ESE connection"), + fc.type, fc.subType); + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pBD, limMsg->bodyptr); + return; + } + limLog( pMac, LOGE, FL("Processing IAPP Frm from SA:")); + limPrintMacAddr(pMac, pDataFrmHdr->sa, LOGE); +#else + printk("%s: Need to port handling of IAPP frames to PRIMA for ESE", __func__); +#endif + + + } else +#endif + + if ((fc.type == SIR_MAC_MGMT_FRAME) && + (fc.subType == SIR_MAC_MGMT_PROBE_RSP) && + pMac->lim.isSpoofingEnabled) + { + limLog( pMac, LOG2, FL("Probe Rsp recieved with DA: "MAC_ADDRESS_STR + " and selfMac Addr:"MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da), + MAC_ADDR_ARRAY(pMac->lim.gSelfMacAddr)); + if (VOS_TRUE == vos_mem_compare((v_VOID_t*) pHdr->da, + (v_VOID_t*) pMac->lim.spoofMacAddr, VOS_MAC_ADDRESS_LEN)) + { + vos_mem_copy(pHdr->da, pMac->lim.gSelfMacAddr, VOS_MAC_ADDRESS_LEN); + } + } + + /* Added For BT-AMP Support */ + if((psessionEntry = peFindSessionByBssid(pMac,pHdr->bssId,&sessionId))== NULL) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + if (fc.subType == SIR_MAC_MGMT_AUTH) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL("ProtVersion %d, Type %d, Subtype %d rateIndex=%d"), + fc.protVer, fc.type, fc.subType, WDA_GET_RX_MAC_RATE_IDX(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->bssId, LOG1); +#endif + if (limProcessAuthFrameNoSession(pMac, pRxPacketInfo, limMsg->bodyptr) == eSIR_SUCCESS) + { + goto end; + } + } +#endif + if((fc.subType != SIR_MAC_MGMT_PROBE_RSP )&& + (fc.subType != SIR_MAC_MGMT_BEACON)&& + (fc.subType != SIR_MAC_MGMT_PROBE_REQ) + && (fc.subType != SIR_MAC_MGMT_ACTION ) //Public action frame can be received from non-associated stations. + ) + { + + if((psessionEntry = peFindSessionByPeerSta(pMac,pHdr->sa,&sessionId))== NULL) + { + limLog(pMac, LOG1, FL("session does not exist for given bssId")); + goto end; + } + else + limLog(pMac,LOG1,"SessionId:%d Session Exist for given Bssid", + psessionEntry->peSessionId); + } + // For p2p resp frames search for valid session with DA as + // BSSID will be SA and session will be present with DA only + if(fc.subType == SIR_MAC_MGMT_ACTION ) + { + psessionEntry = peFindSessionByBssid(pMac,pHdr->da,&sessionId); + } + } + + + /* Check if frame is registered by HDD */ + if(limCheckMgmtRegisteredFrames(pMac, pRxPacketInfo, psessionEntry)) + { + limLog( pMac, LOG1, FL("Received frame is passed to SME")); + goto end; + } + + + + if (fc.protVer != SIR_MAC_PROTOCOL_VERSION) + { // Received Frame with non-zero Protocol Version + limLog(pMac, LOGE, FL("Unexpected frame with protVersion %d received"), + fc.protVer); +#ifdef WLAN_DEBUG + pMac->lim.numProtErr++; +#endif + goto end; + } + + if (!pMac->fScanOffload) + { + if (limIsSystemInScanState(pMac)) + { + limHandleFramesInScanState(pMac, limMsg, pRxPacketInfo, pDeferMsg, psessionEntry); + return; + } + } + +/* Chance of crashing : to be done BT-AMP ........happens when broadcast probe req is received */ + +#if 0 + if (psessionEntry->limSystemRole == eLIM_UNKNOWN_ROLE) { + limLog( pMac, LOGW, FL( "gLimSystemRole is %d. Exiting..." ),psessionEntry->limSystemRole ); + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr); + +#ifdef WLAN_DEBUG + pMac->lim.numProtErr++; +#endif + return; + } + #endif //HACK to continue scanning + + +#ifdef WLAN_DEBUG + pMac->lim.numMAC[fc.type][fc.subType]++; +#endif + + switch (fc.type) + { + case SIR_MAC_MGMT_FRAME: + { + #if 0 //TBD-RAJESH fix this + if (limIsReassocInProgress( pMac,psessionEntry) && (fc.subType != SIR_MAC_MGMT_DISASSOC) && + (fc.subType != SIR_MAC_MGMT_DEAUTH) && (fc.subType != SIR_MAC_MGMT_REASSOC_RSP)) + { + limLog(pMac, LOGE, FL("Frame with Type - %d, Subtype - %d received in ReAssoc Wait state, dropping..."), + fc.type, fc.subType); + return; + } + #endif //HACK to continue scanning + // Received Management frame + switch (fc.subType) + { + case SIR_MAC_MGMT_ASSOC_REQ: + // Make sure the role supports Association + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_ASSOC, psessionEntry); + + else + { + // Unwanted messages - Log error + limLog(pMac, LOGE, FL("unexpected message received %X"),limMsg->type); + limPrintMsgName(pMac, LOGE, limMsg->type); + } + break; + + case SIR_MAC_MGMT_ASSOC_RSP: + limProcessAssocRspFrame(pMac, pRxPacketInfo, LIM_ASSOC,psessionEntry); + break; + + case SIR_MAC_MGMT_REASSOC_REQ: + // Make sure the role supports Reassociation + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ){ + limProcessAssocReqFrame(pMac, pRxPacketInfo, LIM_REASSOC, psessionEntry); + } + else + { + // Unwanted messages - Log error + limLog(pMac, LOGE, FL("unexpected message received %X"),limMsg->type); + limPrintMsgName(pMac, LOGE, limMsg->type); + } + break; + + case SIR_MAC_MGMT_REASSOC_RSP: + limProcessAssocRspFrame(pMac, pRxPacketInfo, LIM_REASSOC,psessionEntry); + break; + + case SIR_MAC_MGMT_PROBE_REQ: + limProcessProbeReqFrame_multiple_BSS(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_PROBE_RSP: + if(psessionEntry == NULL) + limProcessProbeRspFrameNoSession(pMac, pRxPacketInfo); + else + limProcessProbeRspFrame(pMac, pRxPacketInfo, psessionEntry); + break; + + case SIR_MAC_MGMT_BEACON: + __limHandleBeacon(pMac, limMsg,psessionEntry); + break; + + case SIR_MAC_MGMT_DISASSOC: + limProcessDisassocFrame(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_AUTH: + limProcessAuthFrame(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_DEAUTH: + limProcessDeauthFrame(pMac, pRxPacketInfo,psessionEntry); + break; + + case SIR_MAC_MGMT_ACTION: + if(psessionEntry == NULL) + limProcessActionFrameNoSession(pMac, pRxPacketInfo); + else + { + if (WDA_GET_RX_UNKNOWN_UCAST(pRxPacketInfo)) + limHandleUnknownA2IndexFrames(pMac, pRxPacketInfo,psessionEntry); + else + limProcessActionFrame(pMac, pRxPacketInfo,psessionEntry); + } + break; + default: + // Received Management frame of 'reserved' subtype + break; + } // switch (fc.subType) + + } + break; + case SIR_MAC_DATA_FRAME: + { +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + /* We accept data frame (IAPP frame) only if Session is + * present and ese connection is established on that + * session + */ + if (psessionEntry && psessionEntry->isESEconnection) { + limProcessIappFrame(pMac, pRxPacketInfo, psessionEntry); + } +#endif + } + break; + default: + // Received frame of type 'reserved' + break; + + } // switch (fc.type) + +end: + limPktFree(pMac, HAL_TXRX_FRM_802_11_MGMT, pRxPacketInfo, (void *) limMsg->bodyptr) ; + return; +} /*** end limHandle80211Frames() ***/ + +/** + * limSendStopScanOffloadReq() + * + *FUNCTION: + * This function will be called to abort the ongoing offloaded scan + * request. + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return eHAL_STATUS_SUCCESS or eHAL_STATUS_FAILURE + */ +eHalStatus limSendStopScanOffloadReq(tpAniSirGlobal pMac, tANI_U8 SessionId) +{ + tSirMsgQ msg; + tSirRetStatus rc = eSIR_SUCCESS; + tAbortScanParams *pAbortScanParams; + + pAbortScanParams = vos_mem_malloc(sizeof(tAbortScanParams)); + if (NULL == pAbortScanParams) + { + limLog(pMac, LOGP, FL("Memory allocation failed for AbortScanParams")); + return eHAL_STATUS_FAILURE; + } + + pAbortScanParams->SessionId = SessionId; + msg.type = WDA_STOP_SCAN_OFFLOAD_REQ; + msg.bodyptr = pAbortScanParams; + msg.bodyval = 0; + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure")); + vos_mem_free(pAbortScanParams); + return eHAL_STATUS_FAILURE; + } + + limLog(pMac, LOG1, FL("Abort ongoing offload scan.")); + return eHAL_STATUS_SUCCESS; + +} + +/** + * limProcessAbortScanInd() + * + *FUNCTION: + * This function is called from HDD to abort the scan which is presently being run + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +void +limProcessAbortScanInd(tpAniSirGlobal pMac, tANI_U8 SessionId) +{ +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Deactivate the gLimBackgroundScanTimer as part of the abort scan. + * SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication + * to start the background scan again + */ + limLog(pMac, LOG1, FL("Processing AbortScan Ind")); + + limAbortBackgroundScan(pMac); + + if (pMac->fScanOffload) + { + /* send stop scan cmd to fw if scan offload is enabled. */ + limSendStopScanOffloadReq(pMac, SessionId); + } + else + { + /* Abort the scan if its running, else just return */ + if(limIsSystemInScanState(pMac)) + { + if( (eLIM_HAL_INIT_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) || + (eLIM_HAL_START_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) || + (eLIM_HAL_END_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState ) || + (eLIM_HAL_FINISH_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState) ) + { + //Simply signal we need to abort + limLog( pMac, LOGW, FL(" waiting for HAL, simply signal abort gLimHalScanState = %d"), pMac->lim.gLimHalScanState ); + pMac->lim.abortScan = 1; + } + else + { + //Force abort + limLog( pMac, LOGW, FL(" Force aborting scan") ); + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + } + } + return; +} + +/** + * limMessageProcessor + * + *FUNCTION: + * Wrapper function for limProcessMessages when handling messages received by LIM. + * Could either defer messages or process them. + * @param pMac Pointer to Global MAC structure + * @param limMsg Received LIM message + * @return None + */ + +void limMessageProcessor(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + if (eLIM_MLM_OFFLINE_STATE == pMac->lim.gLimMlmState) + { + peFreeMsg(pMac, limMsg); + return; + } + + if (!defMsgDecision(pMac, limMsg)) + { + limProcessMessages(pMac, limMsg); + // process deferred message queue if allowed + { + if ( (! (pMac->lim.gLimAddtsSent)) + && + (! (limIsSystemInScanState(pMac))) + ) + { + if (true == GET_LIM_PROCESS_DEFD_MESGS(pMac)) + limProcessDeferredMessageQueue(pMac); + } + } + } +} + +#ifdef FEATURE_OEM_DATA_SUPPORT + +void limOemDataRspHandleResumeLinkRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* mlmOemDataRsp) +{ + if(status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("OEM Data Rsp failed to get the response for resume link")); + } + + if(NULL != pMac->lim.gpLimMlmOemDataReq) + { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + //"Failure" status doesn't mean that Oem Data Rsp did not happen + //and hence we need to respond to upper layers. Only Resume link is failed, but + //we got the oem data response already. + //Post the meessage to MLM + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)(mlmOemDataRsp)); + + return; +} + +void limProcessOemDataRsp(tpAniSirGlobal pMac, tANI_U32* body) +{ + tpLimMlmOemDataRsp mlmOemDataRsp = NULL; + tpStartOemDataRsp oemDataRsp = NULL; + + //Process all the messages for the lim queue + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + oemDataRsp = (tpStartOemDataRsp)(body); + + mlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( NULL == mlmOemDataRsp ) + { + limLog(pMac, LOGP, FL("could not allocate memory for mlmOemDataRsp")); + return; + } + + //copy the memory into tLimMlmOemDataRsp and free the tStartOemDataRsp + //the structures tStartOemDataRsp and tLimMlmOemDataRsp have the same structure + vos_mem_copy((void*)(mlmOemDataRsp), (void*)(oemDataRsp), + sizeof(tLimMlmOemDataRsp)); + + //Now free the incoming memory + vos_mem_free(oemDataRsp); + + limResumeLink(pMac, limOemDataRspHandleResumeLinkRsp, (tANI_U32*)mlmOemDataRsp); + + return; +} + +#endif + +static tANI_BOOLEAN limAgeOutProbeReq( tpAniSirGlobal pMac, tpSirMsgQ limMsg, + vos_pkt_t *pVosPkt ) +{ + tANI_U8 *pRxPacketInfo = NULL; + tSirMacFrameCtl fc; + tpSirMacMgmtHdr pHdr=NULL; + tANI_BOOLEAN match = VOS_FALSE; + + limGetBDfromRxPacket(pMac, limMsg->bodyptr, (tANI_U32 **)&pRxPacketInfo); + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + fc = pHdr->fc; + if ( fc.subType == SIR_MAC_MGMT_PROBE_REQ ) + { + if( vos_timer_get_system_ticks() - pVosPkt->timestamp >= MAX_PROBEREQ_TIME ) + { + // drop packet + limLog(pMac, LOGE, + FL("Dropping Aged Out probe requests. Peer MAC is "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->sa)); + + vos_pkt_return_packet(pVosPkt); + match = VOS_TRUE; + } + } + return match; +} + +/** + * limProcessMessages + * + *FUNCTION: + * This function is called by limProcessMessageQueue function. This + * function processes messages received by LIM. + * + *LOGIC: + * Depending on the message type, corresponding function will be + * called, for example limProcessSmeMessages() will be called to + * process SME messages received from HDD/Upper layer software module. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param limMsg Received LIM message + * @return None + */ + +void +limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tANI_U8 deferMsg = false; + tLinkStateParams *linkStateParams; +#if defined WLAN_FEATURE_VOWIFI_11R + tpPESession pSession; +#endif +#if defined(ANI_DVT_DEBUG) + tSirMsgQ msgQ; +#endif + if(pMac->gDriverType == eDRIVER_TYPE_MFG) + { + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } +#ifdef WLAN_DEBUG + pMac->lim.numTot++; +#endif + + + PELOG3(limLog(pMac, LOG3, FL("rcvd msgType = %s, sme state = %s, mlm state = %s"), + limMsgStr(limMsg->type), limSmeStateStr(pMac->lim.gLimSmeState), + limMlmStateStr(pMac->lim.gLimMlmState));) + + /* + * MTRACE logs not captured for events received from SME + * SME enums (eWNI_SME_START_REQ) starts with 0x16xx. + * Compare received SME events with SIR_SME_MODULE_ID + */ + + if (SIR_SME_MODULE_ID == (tANI_U8)MAC_TRACE_GET_MODULE_ID(limMsg->type)) + { + MTRACE(macTrace(pMac, TRACE_CODE_RX_SME_MSG, NO_SESSION, limMsg->type)); + } + else + { + /* Omitting below message types as these are too frequent and when crash + * happens we loose critical trace logs if these are also logged + */ + if (limMsg->type != SIR_LIM_MAX_CHANNEL_TIMEOUT && + limMsg->type != SIR_LIM_MIN_CHANNEL_TIMEOUT && + limMsg->type != SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT && + limMsg->type != SIR_CFG_PARAM_UPDATE_IND && + limMsg->type != SIR_BB_XPORT_MGMT_MSG) + MTRACE(macTraceMsgRx(pMac, NO_SESSION, + LIM_TRACE_MAKE_RXMSG(limMsg->type, LIM_MSG_PROCESSED));) + } + switch (limMsg->type) + { + + case SIR_LIM_UPDATE_BEACON: + limUpdateBeacon(pMac); + break; + + case SIR_CFG_PARAM_UPDATE_IND: + /// CFG parameter updated + if (limIsSystemInScanState(pMac)) + { + // System is in DFS (Learn) mode + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + if(!(pMac->lim.deferredMsgCnt & 0xF)) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + } + limLogSessionStates(pMac); + limPrintMsgName(pMac, LOGE, limMsg->type); + } + } + else + { + limHandleCFGparamUpdate(pMac, limMsg->bodyval); + } + + break; + + case WDA_INIT_SCAN_RSP: + limProcessInitScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_START_SCAN_RSP: + limProcessStartScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_END_SCAN_RSP: + limProcessEndScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_FINISH_SCAN_RSP: + limProcessFinishScanRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDA_START_OEM_DATA_RSP: + limProcessOemDataRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#endif + + case WDA_SWITCH_CHANNEL_RSP: + limProcessSwitchChannelRsp(pMac, limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + +#ifdef ANI_SIR_IBSS_PEER_CACHING + case WDA_IBSS_STA_ADD: + limIbssStaAdd(pMac, limMsg->bodyptr); + break; +#endif + case SIR_BB_XPORT_MGMT_MSG: + // These messages are from Peer MAC entity. +#ifdef WLAN_DEBUG + pMac->lim.numBbt++; +#endif + { + v_U16_t pktLen = 0; + vos_pkt_t *pVosPkt; + VOS_STATUS vosStatus; + tSirMsgQ limMsgNew; + /* The original limMsg which we were deferring have the + * bodyPointer point to 'BD' instead of 'Vos pkt'. If we don't make a copy + * of limMsg, then vos_pkt_peek_data will overwrite the limMsg->bodyPointer. + * and next time when we try to process the msg, we will try to use 'BD' as + * 'Vos Pkt' which will cause a crash + */ + vos_mem_copy((tANI_U8*)&limMsgNew, (tANI_U8*)limMsg, + sizeof(tSirMsgQ)); + pVosPkt = (vos_pkt_t *)limMsgNew.bodyptr; + vos_pkt_get_packet_length(pVosPkt, &pktLen); + + vosStatus = WDA_DS_PeekRxPacketInfo( pVosPkt, (v_PVOID_t *)&limMsgNew.bodyptr, VOS_FALSE ); + + if( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + limDecrementPendingMgmtCount(pMac); + vos_pkt_return_packet(pVosPkt); + break; + + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_ROAMCANDIDATEIND(limMsgNew.bodyptr)) + limLog(pMac, LOG1, FL("roamCandidateInd %d"), + WDA_GET_ROAMCANDIDATEIND(limMsgNew.bodyptr)); + + if (WDA_GET_OFFLOADSCANLEARN(limMsgNew.bodyptr)) + limLog(pMac, LOG1, FL("offloadScanLearn %d"), + WDA_GET_OFFLOADSCANLEARN(limMsgNew.bodyptr)); +#endif + + /* + * putting a check for age out probe request frames + * such that any probe req more than 0.5 sec old can directly + * be dropped. With this, there won't be blocking of MC thread. + */ + + if( limAgeOutProbeReq ( pMac, &limMsgNew, pVosPkt )) + { + limDecrementPendingMgmtCount(pMac); + break; + } + + + limHandle80211Frames(pMac, &limMsgNew, &deferMsg); + + if ( deferMsg == true ) + { + limLog(pMac, LOG2, FL("Defer message type=%X "), + limMsg->type); + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limPrintMsgName(pMac, LOGE, limMsg->type); + limDecrementPendingMgmtCount(pMac); + vos_pkt_return_packet(pVosPkt); + } + } + else + { + /* PE is not deferring this 802.11 frame so we need to call vos_pkt_return. + * Asumption here is when Rx mgmt frame processing is done, + * voss packet could be freed here. + */ + limDecrementPendingMgmtCount(pMac); + vos_pkt_return_packet(pVosPkt); + } + } + break; + case eWNI_SME_SCAN_REQ: + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + case eWNI_SME_DISASSOC_REQ: + case eWNI_SME_DEAUTH_REQ: + case eWNI_SME_GET_SCANNED_CHANNEL_REQ: +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: +#endif +#ifdef FEATURE_WLAN_TDLS + case eWNI_SME_TDLS_SEND_MGMT_REQ: + case eWNI_SME_TDLS_ADD_STA_REQ: + case eWNI_SME_TDLS_DEL_STA_REQ: + case eWNI_SME_TDLS_LINK_ESTABLISH_REQ: +// tdlsoffchan + case eWNI_SME_TDLS_CHANNEL_SWITCH_REQ: +#endif + case eWNI_SME_RESET_AP_CAPS_CHANGED: + // These messages are from HDD + limProcessNormalHddMsg(pMac, limMsg, true); //need to response to hdd + break; + + case eWNI_SME_SCAN_ABORT_IND: + { + tANI_U8 *pSessionId = (tANI_U8 *)limMsg->bodyptr; + limProcessAbortScanInd(pMac, *pSessionId); + vos_mem_free((v_VOID_t *)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + } + case eWNI_SME_START_REQ: + case eWNI_SME_SYS_READY_IND: +#ifndef WNI_ASKEY_NON_SUPPORT_FEATURE + case eWNI_SME_JOIN_REQ: +#endif + case eWNI_SME_AUTH_REQ: + case eWNI_SME_REASSOC_REQ: + case eWNI_SME_START_BSS_REQ: + case eWNI_SME_STOP_BSS_REQ: + case eWNI_SME_SWITCH_CHL_REQ: + case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ: + case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ: + case eWNI_SME_SETCONTEXT_REQ: + case eWNI_SME_REMOVEKEY_REQ: +#ifndef WNI_ASKEY_NON_SUPPORT_FEATURE + case eWNI_SME_PROMISCUOUS_MODE_REQ: +#endif + case eWNI_SME_DISASSOC_CNF: + case eWNI_SME_DEAUTH_CNF: + case eWNI_SME_ASSOC_CNF: + case eWNI_SME_REASSOC_CNF: + case eWNI_SME_ADDTS_REQ: + case eWNI_SME_DELTS_REQ: + case eWNI_SME_DEL_BA_PEER_IND: + case eWNI_SME_SET_TX_POWER_REQ: + case eWNI_SME_GET_TX_POWER_REQ: + case eWNI_SME_GET_NOISE_REQ: + case eWNI_SME_GET_ASSOC_STAS_REQ: + case eWNI_SME_TKIP_CNTR_MEAS_REQ: + case eWNI_SME_UPDATE_APWPSIE_REQ: + case eWNI_SME_HIDE_SSID_REQ: + case eWNI_SME_GET_WPSPBC_SESSION_REQ: + case eWNI_SME_SET_APWPARSNIEs_REQ: + case eWNI_SME_CHNG_MCC_BEACON_INTERVAL: +#if defined WLAN_FEATURE_VOWIFI + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: +#endif +#if defined FEATURE_WLAN_ESE + case eWNI_SME_ESE_ADJACENT_AP_REPORT: +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_UPDATE_KEY: + case eWNI_SME_FT_PRE_AUTH_REQ: + case eWNI_SME_FT_AGGR_QOS_REQ: +#endif +#ifdef WLAN_FEATURE_LFR_MBB + case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ: +#endif + case eWNI_SME_ADD_STA_SELF_REQ: + case eWNI_SME_DEL_STA_SELF_REQ: + case eWNI_SME_REGISTER_MGMT_FRAME_REQ: + case eWNI_SME_UPDATE_NOA: + case eWNI_SME_CLEAR_DFS_CHANNEL_LIST: + case eWNI_SME_STA_STAT_REQ: + case eWNI_SME_AGGR_STAT_REQ: + case eWNI_SME_GLOBAL_STAT_REQ: + case eWNI_SME_STAT_SUMM_REQ: + case eWNI_SME_GET_STATISTICS_REQ: +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_REQ: +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_REQ: +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eWNI_SME_MAC_SPOOF_ADDR_IND: + case eWNI_SME_REGISTER_MGMT_FRAME_CB: + // These messages are from HDD + limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd + break; + + //Power Save Messages From HDD + case eWNI_PMC_PWR_SAVE_CFG: + case eWNI_PMC_ENTER_BMPS_REQ: + case eWNI_PMC_EXIT_BMPS_REQ: + case eWNI_PMC_ENTER_IMPS_REQ: + case eWNI_PMC_EXIT_IMPS_REQ: + case eWNI_PMC_ENTER_UAPSD_REQ: + case eWNI_PMC_EXIT_UAPSD_REQ: + case eWNI_PMC_ENTER_WOWL_REQ: + case eWNI_PMC_EXIT_WOWL_REQ: + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + pmmProcessMessage(pMac, limMsg); + break; + + case eWNI_PMC_SMPS_STATE_IND : + { + if(limMsg->bodyptr){ + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + } + break; + case eWNI_SME_SEND_ACTION_FRAME_IND: + limSendP2PActionFrame(pMac, limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + case eWNI_SME_ABORT_REMAIN_ON_CHAN_IND: + limAbortRemainOnChan(pMac); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + +#ifdef WLAN_FEATURE_RMC + case eWNI_SME_ENABLE_RMC_REQ: + case eWNI_SME_DISABLE_RMC_REQ: + /* + * These messages are from HDD + * No need to response to hdd + */ + limProcessSmeReqMessages(pMac,limMsg); + break; +#endif /* WLAN_FEATURE_RMC */ + + case SIR_HAL_P2P_NOA_START_IND: + { + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + tANI_U8 i; + tANI_U8 p2pGOExists = 0; + + limLog(pMac, LOG1, "LIM received NOA start %x", limMsg->type); + + /* Since insert NOA is done and NOA start msg received, we should deactivate the Insert NOA timer */ + limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER); + + for(i=0; i < pMac->lim.maxBssId; i++) + { + psessionEntry = &pMac->lim.gpSession[i]; + if ( (psessionEntry != NULL) && (psessionEntry->valid) && + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { //Save P2P NOA start attributes for P2P Go persona + p2pGOExists = 1; + vos_mem_copy(&psessionEntry->p2pGoPsNoaStartInd, limMsg->bodyptr, + sizeof(tSirP2PNoaStart)); + if (psessionEntry->p2pGoPsNoaStartInd.status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGW, FL("GO NOA start failure status %d reported by FW." + " - still go ahead with deferred sme req. This is just info"), + psessionEntry->p2pGoPsNoaStartInd.status); + } + break; + } + } + + if (p2pGOExists == 0) + { + limLog(pMac, LOGW, FL("By the time, we received NOA start, GO is already removed." + " - still go ahead with deferred sme req. This is just info")); + } + + /* We received the NOA start indication. Now we can send down the SME request which requires off-channel operation */ + limProcessRegdDefdSmeReqAfterNOAStart(pMac); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; +#ifdef FEATURE_WLAN_TDLS + case SIR_HAL_TDLS_IND: + { + tSirTdlsInd *pTdlsInd = (tpSirTdlsInd)limMsg->bodyptr ; + tpDphHashNode pStaDs = NULL ; + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + if((psessionEntry = peFindSessionByStaId(pMac,pTdlsInd->staIdx,&sessionId))== NULL) + { + limLog(pMac, LOG1, FL("session does not exist for given bssId\n")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + if ((pStaDs = dphGetHashEntry(pMac, pTdlsInd->assocId, &psessionEntry->dph.dphHashTable)) == NULL) + { + limLog(pMac, LOG1, FL("pStaDs Does not exist for given staId\n")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + + if ((STA_ENTRY_TDLS_PEER == pStaDs->staType)) + { + limLog(pMac, LOGE, + FL("received TDLS Indication from the Firmware with Reason Code %d "), + pTdlsInd->reasonCode); + limSendSmeTDLSDelStaInd(pMac, pStaDs, psessionEntry, + pTdlsInd->reasonCode); + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; +#endif + case SIR_HAL_P2P_NOA_ATTR_IND: + { + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + tANI_U8 i; + + limLog(pMac, LOGW, FL("Received message Noa_ATTR %x"), limMsg->type); + for(i=0; i < pMac->lim.maxBssId; i++) + { + psessionEntry = &pMac->lim.gpSession[i]; + if ( (psessionEntry != NULL) && (psessionEntry->valid) && + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { //Save P2P attributes for P2P Go persona + + vos_mem_copy(&psessionEntry->p2pGoPsUpdate, limMsg->bodyptr, + sizeof(tSirP2PNoaAttr)); + + limLog(pMac, LOG2, FL(" &psessionEntry->bssId " + MAC_ADDRESS_STR " ctWin=%d oppPsFlag=%d"), + MAC_ADDR_ARRAY(psessionEntry->bssId), + psessionEntry->p2pGoPsUpdate.ctWin, + psessionEntry->p2pGoPsUpdate.oppPsFlag); + + limLog(pMac, LOG2, FL(" uNoa1IntervalCnt=%d uNoa1Duration=%d uNoa1Interval=%d uNoa1StartTime=%d"), + psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt, + psessionEntry->p2pGoPsUpdate.uNoa1Duration, + psessionEntry->p2pGoPsUpdate.uNoa1Interval, + psessionEntry->p2pGoPsUpdate.uNoa1StartTime); + + + break; + } + } + + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + + break; + + + /* eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER Message comes after the + * device comes out of full power for the full power request sent + * because of channel switch with switch count as 0, so call the same + * function used in timeout case(i.e SIR_LIM_CHANNEL_SWITCH_TIMEOUT) + * for switching the channel*/ + case eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER: + if ( !tx_timer_running(&pMac->lim.limTimers.gLimChannelSwitchTimer) ) + { + limProcessChannelSwitchTimeout(pMac); + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + //Power Save Related Messages From HAL + case WDA_ENTER_BMPS_RSP: + case WDA_EXIT_BMPS_RSP: + case WDA_EXIT_BMPS_IND: + case WDA_ENTER_IMPS_RSP: + case WDA_EXIT_IMPS_RSP: + case WDA_ENTER_UAPSD_RSP: + case WDA_EXIT_UAPSD_RSP: + case WDA_WOWL_ENTER_RSP: + case WDA_WOWL_EXIT_RSP: + pmmProcessMessage(pMac, limMsg); + break; + + case WDA_LOW_RSSI_IND: + //limHandleLowRssiInd(pMac); + break; + + case WDA_BMPS_STATUS_IND: + limHandleBmpsStatusInd(pMac); + break; + +#ifdef WLAN_FEATURE_APFIND + case WDA_AP_FIND_IND: + limHandleAPFindInd(pMac); + break; +#endif + case WDA_MISSED_BEACON_IND: + limHandleMissedBeaconInd(pMac, limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + case WDA_MIC_FAILURE_IND: + limMicFailureInd(pMac, limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case WDA_LOST_LINK_PARAMS_IND: + limProcessLostLinkParamsInd(pMac,limMsg); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case SIR_LIM_ADDTS_RSP_TIMEOUT: + limProcessSmeReqMessages(pMac,limMsg); + break; +#ifdef FEATURE_WLAN_ESE + case SIR_LIM_ESE_TSM_TIMEOUT: +#ifndef FEATURE_WLAN_ESE_UPLOAD + limProcessTsmTimeoutHandler(pMac,limMsg); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + break; + case WDA_TSM_STATS_RSP: +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmePEEseTsmRsp(pMac, (tAniGetTsmStatsRsp *)limMsg->bodyptr); +#else + limProcessHalEseTsmRsp(pMac, limMsg); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + break; +#endif + case WDA_ADD_TS_RSP: + limProcessHalAddTsRsp(pMac, limMsg); + break; + + case SIR_LIM_DEL_TS_IND: + limProcessDelTsInd(pMac, limMsg); + break; + case SIR_LIM_ADD_BA_IND: + limProcessAddBaInd(pMac, limMsg); + break; + case SIR_LIM_DEL_BA_ALL_IND: + limDelAllBASessions(pMac); + break; + case SIR_LIM_DEL_BA_IND: + limProcessMlmHalBADeleteInd( pMac, limMsg ); + break; + + case SIR_LIM_BEACON_GEN_IND: { + + if( pMac->lim.gLimSystemRole != eLIM_AP_ROLE ) + schProcessPreBeaconInd(pMac, limMsg); + + } + break; + + case SIR_LIM_DELETE_STA_CONTEXT_IND: + limDeleteStaContext(pMac, limMsg); + break; + + case SIR_LIM_MIN_CHANNEL_TIMEOUT: + case SIR_LIM_MAX_CHANNEL_TIMEOUT: + case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT: + case SIR_LIM_JOIN_FAIL_TIMEOUT: + case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: + case SIR_LIM_AUTH_FAIL_TIMEOUT: + case SIR_LIM_AUTH_RSP_TIMEOUT: + case SIR_LIM_ASSOC_FAIL_TIMEOUT: + case SIR_LIM_REASSOC_FAIL_TIMEOUT: +#ifdef WLAN_FEATURE_VOWIFI_11R + case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: +#endif + case SIR_LIM_REMAIN_CHN_TIMEOUT: + case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT: + case SIR_LIM_DISASSOC_ACK_TIMEOUT: + case SIR_LIM_DEAUTH_ACK_TIMEOUT: + case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE: + case SIR_LIM_AUTH_RETRY_TIMEOUT: +#ifdef WLAN_FEATURE_LFR_MBB + case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT: + case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT: +#endif + // These timeout messages are handled by MLM sub module + + limProcessMlmReqMessages(pMac, + limMsg); + + break; + + case SIR_LIM_HEART_BEAT_TIMEOUT: + /** check if heart beat failed, even if one Beacon + * is rcvd within the Heart Beat interval continue + * normal processing + */ + + #if 0 + PELOG1(limLog(pMac, LOG1, FL("Heartbeat timeout, SME %d, MLME %d, #bcn %d"), + pMac->lim.gLimSmeState, pMac->lim.gLimMlmState, + pMac->lim.gLimRxedBeaconCntDuringHB);) + + if(pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) + limIbssHeartBeatHandle(pMac); //HeartBeat for peers. + else + /** + * Heartbeat failure occurred on STA + * This is handled by LMM sub module. + */ + limHandleHeartBeatFailure(pMac); + + break; + #endif //TO SUPPORT BT-AMP + if (limIsSystemInScanState(pMac)) + { + // System is in DFS (Learn) mode + // Defer processsing this message + if (limDeferMsg(pMac, limMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + limMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + } + } + else + { + if (NULL == limMsg->bodyptr) + { + limHandleHeartBeatTimeout(pMac); + } + else + { + limHandleHeartBeatTimeoutForSession(pMac, (tpPESession)limMsg->bodyptr); + } + } + break; + + case SIR_LIM_PROBE_HB_FAILURE_TIMEOUT: + limHandleHeartBeatFailureTimeout(pMac); + break; + + case SIR_LIM_CHANNEL_SCAN_TIMEOUT: + /** + * Background scan timeout occurred on STA. + * This is handled by LMM sub module. + */ + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + + //We will do background scan even in bcnps mode + //if (pMac->sys.gSysEnableScanMode) + pMac->lim.gLimReportBackgroundScanResults = FALSE; + limTriggerBackgroundScan(pMac); + break; + + case SIR_LIM_CNF_WAIT_TIMEOUT: + + /* + ** Does not receive CNF or dummy packet + **/ + limHandleCnfWaitTimeout(pMac, (tANI_U16) limMsg->bodyval); + + break; + + case SIR_LIM_KEEPALIVE_TIMEOUT: + limSendKeepAliveToPeer(pMac); + + break; + + case SIR_LIM_RETRY_INTERRUPT_MSG: + // Message from ISR upon TFP's max retry limit interrupt + + break; + + case SIR_LIM_INV_KEY_INTERRUPT_MSG: + // Message from ISR upon SP's Invalid session key interrupt + + break; + + case SIR_LIM_KEY_ID_INTERRUPT_MSG: + // Message from ISR upon SP's Invalid key ID interrupt + + break; + + case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG: + // Message from ISR upon SP's Replay threshold interrupt + + break; + + case SIR_LIM_CHANNEL_SWITCH_TIMEOUT: + limProcessChannelSwitchTimeout(pMac); + break; + + case SIR_LIM_QUIET_TIMEOUT: + limProcessQuietTimeout(pMac); + break; + + case SIR_LIM_QUIET_BSS_TIMEOUT: + limProcessQuietBssTimeout(pMac); + break; + + case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT: + limHandleUpdateOlbcCache(pMac); + break; +#if 0 + case SIR_LIM_WPS_OVERLAP_TIMEOUT: + limProcessWPSOverlapTimeout(pMac); + break; +#endif + case WDA_ADD_BSS_RSP: + limProcessMlmAddBssRsp( pMac, limMsg ); + break; + + case WDA_ADD_STA_RSP: + + //call a wrapper by paasing bodyptr, their get sessionID and and call proper function from there. + limProcessAddStaRsp(pMac,limMsg); + break; + + case WDA_DELETE_STA_RSP: + limProcessMlmDelStaRsp(pMac, limMsg); + break; + + case WDA_ADD_STA_SELF_RSP: + limProcessAddStaSelfRsp(pMac, limMsg); + break; + case WDA_DEL_STA_SELF_RSP: + limProcessDelStaSelfRsp(pMac, limMsg); + break; + + case WDA_DELETE_BSS_RSP: + limHandleDeleteBssRsp(pMac,limMsg); //wrapper routine to handle delete bss response + break; + + case WDA_SET_BSSKEY_RSP: + case WDA_SET_STA_BCASTKEY_RSP: + limProcessMlmSetBssKeyRsp( pMac, limMsg ); + break; + case WDA_SET_STAKEY_RSP: + limProcessMlmSetStaKeyRsp( pMac, limMsg ); + break; + case WDA_REMOVE_BSSKEY_RSP: + case WDA_REMOVE_STAKEY_RSP: + limProcessMlmRemoveKeyRsp( pMac, limMsg ); + break; + case WDA_ADDBA_RSP: + limProcessMlmHalAddBARsp( pMac, limMsg ); + break; + + case WDA_STA_STAT_RSP: + case WDA_AGGR_STAT_RSP: + case WDA_GLOBAL_STAT_RSP: + case WDA_STAT_SUMM_RSP: + limSendSmeStatsRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr); + break; + + case WDA_GET_STATISTICS_RSP: + limSendSmePEStatisticsRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr); + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WDA_GET_ROAM_RSSI_RSP: + limSendSmePEGetRoamRssiRsp ( pMac, limMsg->type, (void *)limMsg->bodyptr); + break; +#endif + + + case WDA_SET_MIMOPS_RSP: //limProcessSetMimoRsp(pMac, limMsg); + case WDA_SET_TX_POWER_RSP: //limProcessSetTxPowerRsp(pMac, limMsg); + case WDA_GET_TX_POWER_RSP: //limProcessGetTxPowerRsp(pMac, limMsg); + case WDA_GET_NOISE_RSP: + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + //limProcessGetNoiseRsp(pMac, limMsg); + break; + + case WDA_SET_MAX_TX_POWER_RSP: +#if defined WLAN_FEATURE_VOWIFI + rrmSetMaxTxPowerRsp( pMac, limMsg ); +#endif + if(limMsg->bodyptr != NULL) + { + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; + + case SIR_LIM_ADDR2_MISS_IND: + { + limLog(pMac, LOGE, + FL("Addr2 mismatch interrupt received %X"), + limMsg->type); + /*a message from HAL indicating addr2 mismatch interrupt occurred + limMsg->bodyptr contains only pointer to 48-bit addr2 field*/ + //Dinesh fix this. the third parameter should be sessionentry. + //limHandleUnknownA2IndexFrames(pMac, (void *)limMsg->bodyptr); + + /*Free message body pointer*/ + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + case WDA_AGGR_QOS_RSP: + limProcessFTAggrQoSRsp( pMac, limMsg ); + break; +#endif + + case WDA_SET_LINK_STATE_RSP: + linkStateParams = (tLinkStateParams *)limMsg->bodyptr; +#if defined WLAN_FEATURE_VOWIFI_11R + pSession = linkStateParams->session; + if(linkStateParams->ft) + { + limSendReassocReqWithFTIEsMgmtFrame(pMac, + pSession->pLimMlmReassocReq, + pSession); + } +#endif + if( linkStateParams->callback ) + { + linkStateParams->callback( pMac, linkStateParams->callbackArg ); + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: + pmmProcessMessage(pMac, limMsg); + break; +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDA_GTK_OFFLOAD_GETINFO_RSP: + pmmProcessMessage(pMac, limMsg); + break; +#endif // WLAN_FEATURE_GTK_OFFLOAD + case eWNI_SME_SET_BCN_FILTER_REQ: + { +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + tpPESession psessionEntry; + tANI_U8 sessionId; + tSirSetActiveModeSetBncFilterReq *bcnFilterReq = + (tSirSetActiveModeSetBncFilterReq *)limMsg->bodyptr; + psessionEntry = peFindSessionByBssid(pMac, bcnFilterReq->bssid, + &sessionId); + if(psessionEntry != NULL && IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + // sending beacon filtering information down to HAL + if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to send Beacon Filter Info ")); + } + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; +#endif + } + break; + case eWNI_SME_HT40_OBSS_SCAN_IND: + { + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + tSirSmeHT40OBSSScanInd *ht40ScanInd = + (tSirSmeHT40OBSSScanInd *)limMsg->bodyptr; + + psessionEntry = peFindSessionByBssid(pMac, ht40ScanInd->peerMacAddr, + &sessionId); + + if (psessionEntry != NULL) + { + if( IS_HT40_OBSS_SCAN_FEATURE_ENABLE && + psessionEntry->htSupportedChannelWidthSet == + WNI_CFG_CHANNEL_BONDING_MODE_ENABLE ) + { + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + "OBSS Scan Start Req: session id %d" + "htSupportedChannelWidthSet %d", psessionEntry->peSessionId, + psessionEntry->htSupportedChannelWidthSet); + limSendHT40OBSSScanInd(pMac, psessionEntry); + } + else + { + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + "OBSS Scan not started: htSupportedChannelWidthSet- %d" + " session id %d", psessionEntry->htSupportedChannelWidthSet, + psessionEntry->peSessionId); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + "OBSS Scan not started: session id is NULL"); + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + } + break; + case eWNI_SME_HT40_STOP_OBSS_SCAN_IND: + { + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + tSirSmeHT40OBSSStopScanInd *ht40StopScanInd = + (tSirSmeHT40OBSSStopScanInd *)limMsg->bodyptr; + + psessionEntry = peFindSessionByBssid(pMac, + ht40StopScanInd->bssid, &sessionId);; + /* Sending LIM STOP OBSS SCAN Indication + Stop command support is only for debugging purpose */ + if (psessionEntry && IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + limSendHT40OBSSStopScanInd(pMac, psessionEntry); + else + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_ERROR, + "OBSS Scan Stop not started "); + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#ifdef WLAN_FEATURE_AP_HT40_24G + case eWNI_SME_SET_HT_2040_MODE: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; +#endif + +#ifdef FEATURE_WLAN_TDLS + case WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP: + { + tpPESession psessionEntry; + tANI_U8 sessionId; + tDphHashNode *pStaDs = NULL; + int i, aid; + tTdlsLinkEstablishParams *pTdlsLinkEstablishParams; + pTdlsLinkEstablishParams = (tTdlsLinkEstablishParams*) limMsg->bodyptr; + + if((psessionEntry = peFindSessionByStaId(pMac, + pTdlsLinkEstablishParams->staIdx, + &sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session %u does not exist"), sessionId); + /* Still send the eWNI_SME_TDLS_LINK_ESTABLISH_RSP message to SME + with session id as zero and status as FAILURE so, that message + queued in SME queue can be freed to prevent the SME cmd buffer leak */ + limSendSmeTdlsLinkEstablishReqRsp(pMac, + 0, + NULL, + NULL, + eSIR_FAILURE); + } + else + { + for (i = 0; + i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); + i++) { + for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) { + if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) { + pStaDs = dphGetHashEntry(pMac, + (aid + i*(sizeof(tANI_U32) << 3)), + &psessionEntry->dph.dphHashTable); + if ((NULL != pStaDs) && + (pTdlsLinkEstablishParams->staIdx == + pStaDs->staIndex)) + goto send_link_resp; + } + } + } +send_link_resp: + if (pStaDs) + limSendSmeTdlsLinkEstablishReqRsp(pMac, + psessionEntry->smeSessionId, + pStaDs->staAddr, + pStaDs, + pTdlsLinkEstablishParams->status) ; + else + limSendSmeTdlsLinkEstablishReqRsp(pMac, + psessionEntry->smeSessionId, + NULL, NULL, + pTdlsLinkEstablishParams->status) ; + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } + + case WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP: + { + tpPESession psessionEntry; + tANI_U8 sessionId; + tDphHashNode *pStaDs = NULL; + int i, aid; + tTdlsChanSwitchParams *pTdlsChanSwitchParams; + pTdlsChanSwitchParams = (tTdlsChanSwitchParams*) limMsg->bodyptr; + + if((psessionEntry = peFindSessionByStaId(pMac, + pTdlsChanSwitchParams->staIdx, + &sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session %u does not exist"), sessionId); + /* Still send the eWNI_SME_TDLS_LINK_ESTABLISH_RSP message to SME + with session id as zero and status as FAILURE so, that message + queued in SME queue can be freed to prevent the SME cmd buffer leak */ + limSendSmeTdlsChanSwitchReqRsp(pMac, + 0, + NULL, + NULL, + eSIR_FAILURE); + } + else + { + for (i = 0; + i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); + i++) { + for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) { + if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) { + pStaDs = dphGetHashEntry(pMac, + (aid + i*(sizeof(tANI_U32) << 3)), + &psessionEntry->dph.dphHashTable); + if ((NULL != pStaDs) && + (pTdlsChanSwitchParams->staIdx == + pStaDs->staIndex)) + goto send_chan_switch_resp; + } + } + } +send_chan_switch_resp: + if (pStaDs) + limSendSmeTdlsChanSwitchReqRsp(pMac, + psessionEntry->smeSessionId, + pStaDs->staAddr, + pStaDs, + pTdlsChanSwitchParams->status); + else + limSendSmeTdlsChanSwitchReqRsp(pMac, + psessionEntry->smeSessionId, + NULL, NULL, + pTdlsChanSwitchParams->status); + } + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } +#endif + + case WDA_RX_SCAN_EVENT: + limProcessRxScanEvent(pMac, limMsg->bodyptr); + break; + + case WDA_IBSS_PEER_INACTIVITY_IND: + { + limProcessIbssPeerInactivity(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t *)(limMsg->bodyptr)); + limMsg->bodyptr = NULL; + break; + } +#ifdef WLAN_FEATURE_RMC + case WDA_RMC_BECOME_RULER: + limProcessRMCMessages(pMac, eLIM_RMC_BECOME_RULER_RESP, + (void *)limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break ; + + case WDA_RMC_RULER_SELECT_RESP: + limProcessRMCMessages(pMac, eLIM_RMC_RULER_SELECT_RESP, + (void *)limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break ; + + case WDA_RMC_UPDATE_IND: + limProcessRMCMessages(pMac, eLIM_RMC_RULER_PICK_NEW, + (void *)limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break ; +#endif /* WLAN_FEATURE_RMC */ + + case WDA_SPOOF_MAC_ADDR_RSP: + limProcessMlmSpoofMacAddrRsp(pMac, (tSirRetStatus)limMsg->bodyval); + break; + + case eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ: + limProcessSmeSetTdls2040BSSCoexReq(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_DEL_ALL_TDLS_PEERS: + limProcessSmeDelAllTdlsPeers(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_CAP_TSF_REQ: + lim_process_sme_cap_tsf_req(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + + case eWNI_SME_GET_TSF_REQ: + lim_process_sme_get_tsf_req(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + case eWNI_SME_DEL_BA_SES_REQ: + lim_process_sme_del_ba_ses_req(pMac, limMsg->bodyptr); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + default: + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + // Unwanted messages + // Log error + limLog(pMac, LOGE, + FL("Discarding unexpected message received %X"), + limMsg->type); + limPrintMsgName(pMac, LOGE, limMsg->type); + break; + + } // switch (limMsg->type) + + PELOG2(limLog(pMac, LOG2, FL("Done Processing msgType = %d, sme state = %s, mlm state = %s"), + limMsg->type, limSmeStateStr(pMac->lim.gLimSmeState), + limMlmStateStr(pMac->lim.gLimMlmState));) + +} /*** end limProcessMessages() ***/ + + + +/** + * limProcessDeferredMessageQueue + * + *FUNCTION: + * This function is called by LIM while exiting from Learn + * mode. This function fetches messages posted to the LIM + * deferred message queue limDeferredMsgQ. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limProcessDeferredMessageQueue(tpAniSirGlobal pMac) +{ + tSirMsgQ limMsg = { 0, 0, 0 }; + + tSirMsgQ *readMsg; + tANI_U16 size; + + /* + ** check any deferred messages need to be processed + **/ + size = pMac->lim.gLimDeferredMsgQ.size; + if (size > 0) + { + while ((readMsg = limReadDeferredMsgQ(pMac)) != NULL) + { + vos_mem_copy((tANI_U8*) &limMsg, + (tANI_U8*) readMsg, sizeof(tSirMsgQ)); + size--; + limProcessMessages(pMac, &limMsg); + + if((limIsSystemInScanState(pMac)) || (true != GET_LIM_PROCESS_DEFD_MESGS(pMac)) || + (pMac->lim.gLimSystemInScanLearnMode) || pMac->lim.gLimAddtsSent) + break; + } + } +} /*** end limProcessDeferredMessageQueue() ***/ + + +/* + * limProcessNormalHddMsg + * Function: this function checks the current lim state and decide whether the message passed shall be deffered. + * @param pMac - Pointer to Global MAC structure + * pLimMsg -- the message need to be processed + * fRspReqd -- whether return result to hdd + * @return None + */ +void limProcessNormalHddMsg(tpAniSirGlobal pMac, tSirMsgQ *pLimMsg, tANI_U8 fRspReqd) +{ + tANI_BOOLEAN fDeferMsg = eANI_BOOLEAN_TRUE; + + /* Added For BT-AMP Support */ + if ((pMac->lim.gLimSystemRole == eLIM_AP_ROLE) ||(pMac->lim.gLimSystemRole == eLIM_BT_AMP_AP_ROLE ) + ||(pMac->lim.gLimSystemRole == eLIM_BT_AMP_STA_ROLE) + ||(pMac->lim.gLimSystemRole == eLIM_UNKNOWN_ROLE)) + { + /** This check is required only for the AP and in 2 cases. + * 1. If we are in learn mode and we receive any of these messages, + * you have to come out of scan and process the message, hence dont + * defer the message here. In handler, these message could be defered + * till we actually come out of scan mode. + * 2. If radar is detected, you might have to defer all of these + * messages except Stop BSS request/ Switch channel request. This + * decision is also made inside its handler. + * + * Please be careful while using the flag fDeferMsg. Possibly you + * might end up in an infinite loop. + **/ + if (((pLimMsg->type == eWNI_SME_START_BSS_REQ) || + (pLimMsg->type == eWNI_SME_STOP_BSS_REQ) || + (pLimMsg->type == eWNI_SME_SWITCH_CHL_REQ) || + (pLimMsg->type == eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ) || + (pLimMsg->type == eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ))) + { + fDeferMsg = eANI_BOOLEAN_FALSE; + } + } + + /* limInsystemInscanState() refers the psessionEntry, how to get session Entry????*/ + if (((pMac->lim.gLimAddtsSent) || (limIsSystemInScanState(pMac)) /*|| + (LIM_IS_RADAR_DETECTED(pMac))*/) && fDeferMsg) + { + // System is in DFS (Learn) mode or awaiting addts response + // or if radar is detected, Defer processsing this message + if (limDeferMsg(pMac, pLimMsg) != TX_SUCCESS) + { +#ifdef WLAN_DEBUG + pMac->lim.numSme++; +#endif + PELOGE(limLog(pMac, LOGE, FL("Unable to Defer message(0x%X) limSmeState %d (prev sme state %d) sysRole %d mlm state %d (prev mlm state %d)"), + pLimMsg->type, pMac->lim.gLimSmeState, pMac->lim.gLimPrevSmeState, + pMac->lim.gLimSystemRole, pMac->lim.gLimMlmState, pMac->lim.gLimPrevMlmState);) + limLogSessionStates(pMac); + limPrintMsgName(pMac, LOGE, pLimMsg->type); + // Release body + vos_mem_free(pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } + } + else + { + if(fRspReqd) + { + // These messages are from HDD + // Since these requests may also be generated + // internally within LIM module, need to + // distinquish and send response to host + pMac->lim.gLimRspReqd = eANI_BOOLEAN_TRUE; + } +#ifdef WLAN_DEBUG + pMac->lim.numSme++; +#endif + if(limProcessSmeReqMessages(pMac, pLimMsg)) + { + // Release body + // limProcessSmeReqMessage consumed the buffer. We can free it. + vos_mem_free(pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } + } +} + +void +handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac, tpPESession psessionEntry) +{ + tSirMacHTCapabilityInfo macHTCapabilityInfo; + tSirMacHTParametersInfo macHTParametersInfo; + tSirMacHTInfoField1 macHTInfoField1; + tSirMacHTInfoField2 macHTInfoField2; + tSirMacHTInfoField3 macHTInfoField3; + tANI_U32 cfgValue; + tANI_U8 *ptr; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_CAP_INFO value")); + return ; + } + ptr = (tANI_U8 *) &macHTCapabilityInfo; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + pMac->lim.gHTLsigTXOPProtection = (tANI_U8)macHTCapabilityInfo.lsigTXOPProtection; + pMac->lim.gHTMIMOPSState = (tSirMacHTMIMOPowerSaveState) macHTCapabilityInfo.mimoPowerSave; + pMac->lim.gHTGreenfield = (tANI_U8)macHTCapabilityInfo.greenField; + pMac->lim.gHTMaxAmsduLength = (tANI_U8)macHTCapabilityInfo.maximalAMSDUsize; + pMac->lim.gHTShortGI20Mhz = (tANI_U8)macHTCapabilityInfo.shortGI20MHz; + pMac->lim.gHTShortGI40Mhz = (tANI_U8)macHTCapabilityInfo.shortGI40MHz; + pMac->lim.gHTPSMPSupport = (tANI_U8)macHTCapabilityInfo.psmp; + pMac->lim.gHTDsssCckRate40MHzSupport = (tANI_U8)macHTCapabilityInfo.dsssCckMode40MHz; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_AMPDU_PARAMS, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_PARAM_INFO value")); + return ; + } + ptr = (tANI_U8 *) &macHTParametersInfo; + *ptr = (tANI_U8) (cfgValue & 0xff); + pMac->lim.gHTAMpduDensity = (tANI_U8)macHTParametersInfo.mpduDensity; + pMac->lim.gHTMaxRxAMpduFactor = (tANI_U8)macHTParametersInfo.maxRxAMPDUFactor; + + // Get HT IE Info + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD1, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD1 value")); + return ; + } + ptr = (tANI_U8 *) &macHTInfoField1; + *((tANI_U8 *)ptr) = (tANI_U8) (cfgValue & 0xff); + pMac->lim.gHTServiceIntervalGranularity = (tANI_U8)macHTInfoField1.serviceIntervalGranularity; + pMac->lim.gHTControlledAccessOnly = (tANI_U8)macHTInfoField1.controlledAccessOnly; + pMac->lim.gHTRifsMode = (tANI_U8)macHTInfoField1.rifsMode; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD2, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD2 value")); + return ; + } + ptr = (tANI_U8 *) &macHTInfoField2; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + pMac->lim.gHTOperMode = (tSirMacHTOperatingMode) macHTInfoField2.opMode; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_INFO_FIELD3, &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to retrieve WNI_CFG_HT_INFO_FIELD3 value")); + return ; + } + ptr = (tANI_U8 *) &macHTInfoField3; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + pMac->lim.gHTPCOActive = (tANI_U8)macHTInfoField3.pcoActive; + pMac->lim.gHTPCOPhase = (tANI_U8)macHTInfoField3.pcoPhase; + pMac->lim.gHTSecondaryBeacon = (tANI_U8)macHTInfoField3.secondaryBeacon; + pMac->lim.gHTDualCTSProtection = (tANI_U8)macHTInfoField3.dualCTSProtection; + pMac->lim.gHTSTBCBasicMCS = (tANI_U8)macHTInfoField3.basicSTBCMCS; + + /* The lim globals for channelwidth and secondary chnl have been removed and should not be used during no session; + * instead direct cfg is read and used when no session for transmission of mgmt frames (same as old); + * For now, we might come here during init and join with sessionEntry = NULL; in that case just fill the globals which exist + * Sessionized entries values will be filled in join or add bss req. The ones which are missed in join are filled below + */ + if (psessionEntry != NULL) + { + psessionEntry->htCapability = + IS_DOT11_MODE_HT(psessionEntry->dot11mode); + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = + (tANI_U8)macHTInfoField3.lsigTXOPProtectionFullSupport; + limInitOBSSScanParams(pMac, psessionEntry); + } +} + +void limLogSessionStates(tpAniSirGlobal pMac) +{ +#ifdef WLAN_DEBUG + int i; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + limLog(pMac, LOG1, FL("Session[%d] sysRole(%d) limSmeState %d " + "(prev sme state %d) mlm state %d (prev mlm state %d)"), + i, pMac->lim.gpSession[i].limSystemRole, + pMac->lim.gpSession[i].limSmeState, + pMac->lim.gpSession[i].limPrevSmeState, + pMac->lim.gpSession[i].limMlmState, + pMac->lim.gpSession[i].limPrevMlmState); + } + } +#endif //ifdef WLAN_DEBUG +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c new file mode 100644 index 000000000000..2e382d9dee9d --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c @@ -0,0 +1,5215 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessMlmMessages.cc contains the code + * for processing MLM request messages. + * Author: Chandra Modumudi + * Date: 02/12/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "wniCfg.h" +#include "aniGlobal.h" +#include "sirApi.h" +#include "sirParams.h" +#include "cfgApi.h" + +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSecurityUtils.h" +#include "limSendMessages.h" +#include "pmmApi.h" +#include "limSendMessages.h" +//#include "limSessionUtils.h" +#include "limSessionUtils.h" +#ifdef WLAN_FEATURE_VOWIFI_11R +#include +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM +#include "vos_diag_core_log.h" +#endif +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + +// MLM REQ processing function templates +static void limProcessMlmStartReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmScanReq(tpAniSirGlobal, tANI_U32 *); +#ifdef FEATURE_OEM_DATA_SUPPORT +static void limProcessMlmOemDataReq(tpAniSirGlobal, tANI_U32 *); +#endif +static void limProcessMlmJoinReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmAuthReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmAssocReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmReassocReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmDisassocReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmDeauthReq(tpAniSirGlobal, tANI_U32 *); +static void limProcessMlmSetKeysReq(tpAniSirGlobal, tANI_U32 *); + +static void limProcessMlmAddBAReq( tpAniSirGlobal, tANI_U32 * ); +static void limProcessMlmAddBARsp( tpAniSirGlobal, tANI_U32 * ); +static void limProcessMlmDelBAReq( tpAniSirGlobal, tANI_U32 * ); + +// MLM Timeout event handler templates +static void limProcessMinChannelTimeout(tpAniSirGlobal); +static void limProcessMaxChannelTimeout(tpAniSirGlobal); +static void limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac); +static void limProcessJoinFailureTimeout(tpAniSirGlobal); +static void limProcessAuthFailureTimeout(tpAniSirGlobal); +static void limProcessAuthRspTimeout(tpAniSirGlobal, tANI_U32); +static void limProcessAssocFailureTimeout(tpAniSirGlobal, tANI_U32); +static void limProcessPeriodicJoinProbeReqTimer(tpAniSirGlobal); +static void limProcessAuthRetryTimer(tpAniSirGlobal); + + +static void limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf); +void +limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId); +#define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_AGGRESSIVE_BACKGROUND_SCAN) +#define IS_MLM_SCAN_REQ_BACKGROUND_SCAN_NORMAL(pMac) (pMac->lim.gpLimMlmScanReq->backgroundScanMode == eSIR_NORMAL_BACKGROUND_SCAN) + +/** + * limProcessMlmReqMessages() + * + *FUNCTION: + * This function is called by limPostMlmMessage(). This + * function handles MLM primitives invoked by SME. + * + *LOGIC: + * Depending on the message type, corresponding function will be + * called. + * + *ASSUMPTIONS: + * 1. Upon receiving Beacon in WT_JOIN_STATE, MLM module invokes + * APIs exposed by Beacon Processing module for setting parameters + * at MAC hardware. + * 2. If attempt to Reassociate with an AP fails, link with current + * AP is restored back. + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM primitive message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ + +void +limProcessMlmReqMessages(tpAniSirGlobal pMac, tpSirMsgQ Msg) +{ + switch (Msg->type) + { + case LIM_MLM_START_REQ: limProcessMlmStartReq(pMac, Msg->bodyptr); break; + case LIM_MLM_SCAN_REQ: limProcessMlmScanReq(pMac, Msg->bodyptr); break; +#ifdef FEATURE_OEM_DATA_SUPPORT + case LIM_MLM_OEM_DATA_REQ: limProcessMlmOemDataReq(pMac, Msg->bodyptr); break; +#endif + case LIM_MLM_JOIN_REQ: limProcessMlmJoinReq(pMac, Msg->bodyptr); break; + case LIM_MLM_AUTH_REQ: limProcessMlmAuthReq(pMac, Msg->bodyptr); break; + case LIM_MLM_ASSOC_REQ: limProcessMlmAssocReq(pMac, Msg->bodyptr); break; + case LIM_MLM_REASSOC_REQ: limProcessMlmReassocReq(pMac, Msg->bodyptr); break; + case LIM_MLM_DISASSOC_REQ: limProcessMlmDisassocReq(pMac, Msg->bodyptr); break; + case LIM_MLM_DEAUTH_REQ: limProcessMlmDeauthReq(pMac, Msg->bodyptr); break; + case LIM_MLM_SETKEYS_REQ: limProcessMlmSetKeysReq(pMac, Msg->bodyptr); break; + case LIM_MLM_REMOVEKEY_REQ: limProcessMlmRemoveKeyReq(pMac, Msg->bodyptr); break; + case SIR_LIM_MIN_CHANNEL_TIMEOUT: limProcessMinChannelTimeout(pMac); break; + case SIR_LIM_MAX_CHANNEL_TIMEOUT: limProcessMaxChannelTimeout(pMac); break; + case SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT: + limProcessPeriodicProbeReqTimer(pMac); break; + case SIR_LIM_JOIN_FAIL_TIMEOUT: limProcessJoinFailureTimeout(pMac); break; + case SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT: + limProcessPeriodicJoinProbeReqTimer(pMac); break; + case SIR_LIM_AUTH_FAIL_TIMEOUT: limProcessAuthFailureTimeout(pMac); break; + case SIR_LIM_AUTH_RSP_TIMEOUT: limProcessAuthRspTimeout(pMac, Msg->bodyval); break; + case SIR_LIM_ASSOC_FAIL_TIMEOUT: limProcessAssocFailureTimeout(pMac, Msg->bodyval); break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT:limProcessFTPreauthRspTimeout(pMac); break; +#endif +#ifdef WLAN_FEATURE_LFR_MBB + case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT: + lim_process_preauth_mbb_rsp_timeout(pMac); + break; + case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT: + lim_process_reassoc_mbb_rsp_timeout(pMac); + break; +#endif + case SIR_LIM_REMAIN_CHN_TIMEOUT: limProcessRemainOnChnTimeout(pMac); break; + case SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT: + limProcessInsertSingleShotNOATimeout(pMac); break; + case SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE: + limConvertActiveChannelToPassiveChannel(pMac); break; + case SIR_LIM_AUTH_RETRY_TIMEOUT: + limProcessAuthRetryTimer(pMac); + break; + case SIR_LIM_DISASSOC_ACK_TIMEOUT: limProcessDisassocAckTimeout(pMac); break; + case SIR_LIM_DEAUTH_ACK_TIMEOUT: limProcessDeauthAckTimeout(pMac); break; + case LIM_MLM_ADDBA_REQ: limProcessMlmAddBAReq( pMac, Msg->bodyptr ); break; + case LIM_MLM_ADDBA_RSP: limProcessMlmAddBARsp( pMac, Msg->bodyptr ); break; + case LIM_MLM_DELBA_REQ: limProcessMlmDelBAReq( pMac, Msg->bodyptr ); break; + case LIM_MLM_TSPEC_REQ: + default: + break; + } // switch (msgType) +} /*** end limProcessMlmReqMessages() ***/ + + +/** + * limSetScanMode() + * + *FUNCTION: + * This function is called to setup system into Scan mode + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limSetScanMode(tpAniSirGlobal pMac) +{ + tSirLinkTrafficCheck checkTraffic; + + /// Set current scan channel id to the first in the channel list + pMac->lim.gLimCurrentScanChannelId = 0; + + if ( IS_MLM_SCAN_REQ_BACKGROUND_SCAN_AGGRESSIVE(pMac) ) + { + checkTraffic = eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN; + } + else if (IS_MLM_SCAN_REQ_BACKGROUND_SCAN_NORMAL(pMac)) + { + checkTraffic = eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN; + } + else + checkTraffic = eSIR_CHECK_ROAMING_SCAN; + + limLog(pMac, LOG1, FL("Calling limSendHalInitScanReq")); + limSendHalInitScanReq(pMac, eLIM_HAL_INIT_SCAN_WAIT_STATE, checkTraffic); + + return ; +} /*** end limSetScanMode() ***/ + +//WLAN_SUSPEND_LINK Related + +/* limIsLinkSuspended() + * + *FUNCTION: + * This function returns is link is suspended or not. + * + *LOGIC: + * Since Suspend link uses init scan, it just returns + * gLimSystemInScanLearnMode flag. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ +tANI_U8 +limIsLinkSuspended(tpAniSirGlobal pMac) +{ + return pMac->lim.gLimSystemInScanLearnMode; +} +/** + * limSuspendLink() + * + *FUNCTION: + * This function is called to suspend traffic. Internally this function uses WDA_INIT_SCAN_REQ. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param trafficCheck - Takes value from enum tSirLinkTrafficCheck. + * @param callback - Callback function to be called after suspending the link. + * @param data - Pointer to any buffer that will be passed to callback. + * @return None + */ +void +limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data) +{ + if( NULL == callback ) + { + limLog( pMac, LOGE, "%s:%d: Invalid parameters", __func__, __LINE__ ); + return; + } + + if( pMac->lim.gpLimSuspendCallback || + pMac->lim.gLimSystemInScanLearnMode ) + { + limLog( pMac, LOGE, FL("Something is wrong, SuspendLinkCbk:%p " + "IsSystemInScanLearnMode:%d"), pMac->lim.gpLimSuspendCallback, + pMac->lim.gLimSystemInScanLearnMode ); + callback( pMac, eHAL_STATUS_FAILURE, data ); + return; + } + + pMac->lim.gLimSystemInScanLearnMode = 1; + pMac->lim.gpLimSuspendCallback = callback; + pMac->lim.gpLimSuspendData = data; + limSendHalInitScanReq(pMac, eLIM_HAL_SUSPEND_LINK_WAIT_STATE, trafficCheck ); + + WDA_TrafficStatsTimerActivate(FALSE); +} + +/** + * limResumeLink() + * + *FUNCTION: + * This function is called to Resume traffic after a suspend. Internally this function uses WDA_FINISH_SCAN_REQ. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param callback - Callback function to be called after Resuming the link. + * @param data - Pointer to any buffer that will be passed to callback. + * @return None + */ +void +limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data) +{ + if( NULL == callback ) + { + limLog( pMac, LOGE, "%s:%d: Invalid parameters", __func__, __LINE__ ); + return; + } + + if( pMac->lim.gpLimResumeCallback ) + { + limLog( pMac, LOGE, "%s:%d: gLimResumeLink callback is not NULL...something is wrong", __func__, __LINE__ ); + callback( pMac, eHAL_STATUS_FAILURE, data ); + return; + } + + pMac->lim.gpLimResumeCallback = callback; + pMac->lim.gpLimResumeData = data; + + /* eLIM_HAL_IDLE_SCAN_STATE state indicate limSendHalInitScanReq failed. + * In case limSendHalInitScanReq is success, Scanstate would be + * eLIM_HAL_SUSPEND_LINK_STATE + */ + if( eLIM_HAL_IDLE_SCAN_STATE != pMac->lim.gLimHalScanState ) + { + limSendHalFinishScanReq(pMac, eLIM_HAL_RESUME_LINK_WAIT_STATE ); + } + else + { + limLog(pMac, LOGW, FL("Init Scan failed, we will not call finish scan." + " calling the callback with failure status")); + pMac->lim.gpLimResumeCallback( pMac, eSIR_FAILURE, pMac->lim.gpLimResumeData); + pMac->lim.gpLimResumeCallback = NULL; + pMac->lim.gpLimResumeData = NULL; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + + if(limIsInMCC(pMac)) + { + WDA_TrafficStatsTimerActivate(TRUE); + } +} +//end WLAN_SUSPEND_LINK Related + + +/** + * + * limChangeChannelWithCallback() + * + * FUNCTION: + * This function is called to change channel and perform off channel operation + * if required. The caller registers a callback to be called at the end of the + * channel change. + * + */ +void +limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel, + CHANGE_CHANNEL_CALLBACK callback, + tANI_U32 *cbdata, tpPESession psessionEntry) +{ + // Sanity checks for the current and new channel +#if defined WLAN_VOWIFI_DEBUG + PELOGE(limLog( pMac, LOGE, "Switching channel to %d", newChannel);) +#endif + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + + pMac->lim.gpchangeChannelCallback = callback; + pMac->lim.gpchangeChannelData = cbdata; + + limSendSwitchChnlParams(pMac, newChannel, + PHY_SINGLE_CHANNEL_CENTERED, + psessionEntry->maxTxPower, psessionEntry->peSessionId); + + return; +} + + +/** + * limContinuePostChannelScan() + * + *FUNCTION: + * This function is called to scan the current channel. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ + +void limContinuePostChannelScan(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + tANI_U8 i = 0; + tSirRetStatus status = eSIR_SUCCESS; + + if( pMac->lim.abortScan || (NULL == pMac->lim.gpLimMlmScanReq ) || + (pMac->lim.gLimCurrentScanChannelId > + (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1))) + { + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + return; + } + + channelNum = limGetCurrentScanChannel(pMac); + + if (channelNum == limGetCurrentOperatingChannel(pMac) && + limIsconnectedOnDFSChannel(channelNum)) + { + limCovertChannelScanType(pMac, channelNum, true); + } + + if ((pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) && + (limActiveScanAllowed(pMac, channelNum))) + { + TX_TIMER *periodicScanTimer; + + pMac->lim.probeCounter++; + /* Prepare and send Probe Request frame for all + * the SSIDs present in the saved MLM + */ + do + { + tSirMacAddr gSelfMacAddr; + + /* Send self MAC as src address if + * MAC spoof is not enabled OR + * spoofMacAddr is all 0 OR + * disableP2PMacSpoof is enabled and scan is P2P scan + * else use the spoofMac as src address + */ + if ((pMac->lim.isSpoofingEnabled != TRUE) || + (TRUE == + vos_is_macaddr_zero((v_MACADDR_t *)&pMac->lim.spoofMacAddr)) || + (pMac->roam.configParam.disableP2PMacSpoofing && + pMac->lim.gpLimMlmScanReq->p2pSearch)) { + vos_mem_copy(gSelfMacAddr, pMac->lim.gSelfMacAddr, VOS_MAC_ADDRESS_LEN); + } else { + vos_mem_copy(gSelfMacAddr, pMac->lim.spoofMacAddr, VOS_MAC_ADDRESS_LEN); + } + limLog(pMac, LOG1, + FL(" Mac Addr "MAC_ADDRESS_STR " used in sending ProbeReq number %d, for SSID %s on channel: %d"), + MAC_ADDR_ARRAY(gSelfMacAddr) ,i, pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum); + // include additional IE if there is + status = limSendProbeReqMgmtFrame( pMac, &pMac->lim.gpLimMlmScanReq->ssId[i], + pMac->lim.gpLimMlmScanReq->bssId, channelNum, gSelfMacAddr, + pMac->lim.gpLimMlmScanReq->dot11mode, + pMac->lim.gpLimMlmScanReq->uIEFieldLen, + (tANI_U8 *)(pMac->lim.gpLimMlmScanReq)+pMac->lim.gpLimMlmScanReq->uIEFieldOffset); + + if ( status != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID %s on channel: %d"), + pMac->lim.gpLimMlmScanReq->ssId[i].ssId, channelNum);) + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + return; + } + i++; + } while (i < pMac->lim.gpLimMlmScanReq->numSsid); + + { +#if defined WLAN_FEATURE_VOWIFI + //If minChannelTime is set to zero, SME is requesting scan to not use min channel timer. + //This is used in 11k to request for beacon measurement request with a fixed duration in + //max channel time. + if( pMac->lim.gpLimMlmScanReq->minChannelTime != 0 ) + { +#endif + /// TXP has sent Probe Request + /// Activate minChannelTimer + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + +#ifdef GEN6_TODO + /* revisit this piece of code to assign the appropriate sessionId + * below priority - LOW/might not be needed + */ + pMac->lim.limTimers.gLimMinChannelTimer.sessionId = sessionId; +#endif + if (tx_timer_activate(&pMac->lim.limTimers.gLimMinChannelTimer) != + TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not start min channel timer")); + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limSendHalEndScanReq(pMac, channelNum, + eLIM_HAL_END_SCAN_WAIT_STATE); + return; + } + + // Initialize max timer too + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); +#if defined WLAN_FEATURE_VOWIFI + } + else + { +#if defined WLAN_VOWIFI_DEBUG + PELOGE(limLog( pMac, LOGE, "Min channel time == 0, Use only max chan timer" );) +#endif + //No Need to start Min channel timer. Start Max Channel timer. + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) + == TX_TIMER_ERROR) + { + /// Could not activate max channel timer. + // Log error + limLog(pMac,LOGE, FL("could not start max channel timer")); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + limSendHalEndScanReq(pMac, + channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + return; + } + + } +#endif + } + /* Start peridic timer which will trigger probe req based on min/max + channel timer */ + periodicScanTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer; + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER); + if (tx_timer_activate(periodicScanTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not start periodic probe req " + "timer")); + } + periodicScanTimer->sessionId = channelNum; + } + else + { + tANI_U32 val; + limLog(pMac, LOG1, FL("START PASSIVE Scan chan %d"), channelNum); + + /// Passive Scanning. Activate maxChannelTimer + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer) + != TX_SUCCESS) + { + // Could not deactivate max channel timer. + // Log error + limLog(pMac, LOGE, FL("Unable to deactivate max channel timer")); + limSendHalEndScanReq(pMac, channelNum, + eLIM_HAL_END_SCAN_WAIT_STATE); + } + else + { + if (pMac->miracast_mode) + { + val = DEFAULT_MIN_CHAN_TIME_DURING_MIRACAST + + DEFAULT_MAX_CHAN_TIME_DURING_MIRACAST; + } + else if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + &val) != eSIR_SUCCESS) + { + /** + * Could not get max channel value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve passive max chan value, Use Def val")); + val= WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF; + } + + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer, + val, 0) != TX_SUCCESS) + { + // Could not change max channel timer. + // Log error + limLog(pMac, LOGE, FL("Unable to change max channel timer")); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + limSendHalEndScanReq(pMac, channelNum, + eLIM_HAL_END_SCAN_WAIT_STATE); + return; + } + else if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) + != TX_SUCCESS) + { + + limLog(pMac, LOGE, FL("could not start max channel timer")); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + limSendHalEndScanReq(pMac, channelNum, + eLIM_HAL_END_SCAN_WAIT_STATE); + return; + } + } + // Wait for Beacons to arrive + } // if (pMac->lim.gLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) + + limAddScanChannelInfo(pMac, channelNum); + return; +} + + + + + +/* limCovertChannelScanType() + * + *FUNCTION: + * This function is called to get the list, change the channel type and set again. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: If a channel is ACTIVE, this function will make it as PASSIVE + * If a channel is PASSIVE, this fucntion will make it as ACTIVE + * NA + * + * @param pMac - Pointer to Global MAC structure + * channelNum - Channel which need to be convert + PassiveToActive - Boolean flag to convert channel + * + * @return None + */ + + +void limCovertChannelScanType(tpAniSirGlobal pMac,tANI_U8 channelNum, tANI_BOOLEAN passiveToActive) +{ + + tANI_U32 i; + tANI_U8 channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN]; + tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN; + + if (wlan_cfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to get scan control list"));) + return ; + } + if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) + { + limLog(pMac, LOGE, FL("Invalid scan control list length:%d"), len); + return ; + } + if (pMac->fActiveScanOnDFSChannels) + { + limLog(pMac, LOG1, FL("DFS feature triggered," + "block scan type conversion")); + return ; + } + for (i=0; (i+1) < len; i+=2) + { + if (channelPair[i] == channelNum) + { + if ((eSIR_PASSIVE_SCAN == channelPair[i+1]) && TRUE == passiveToActive) + { + limLog(pMac, LOG1, FL("Channel %d changed from Passive to Active"), + channelNum); + channelPair[i+1] = eSIR_ACTIVE_SCAN; + break ; + } + if ((eSIR_ACTIVE_SCAN == channelPair[i+1]) && FALSE == passiveToActive) + { + limLog(pMac, LOG1, FL("Channel %d changed from Active to Passive"), + channelNum); + channelPair[i+1] = eSIR_PASSIVE_SCAN; + break ; + } + } + } + + cfgSetStrNotify(pMac, WNI_CFG_SCAN_CONTROL_LIST, (tANI_U8 *)channelPair, len, FALSE); + return ; +} + + + + +/* limSetDFSChannelList() + * + *FUNCTION: + * This function is called to convert DFS channel list to active channel list when any + * beacon is present on that channel. This function store time for passive channels + * which help to know that for how much time channel has been passive. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: If a channel is ACTIVE, it won't store any time + * If a channel is PAssive, it will store time as timestamp + * NA + * + * @param pMac - Pointer to Global MAC structure + * dfsChannelList - DFS channel list. + * @return None + */ + +void limSetDFSChannelList(tpAniSirGlobal pMac,tANI_U8 channelNum, tSirDFSChannelList *dfsChannelList) +{ + + tANI_BOOLEAN passiveToActive = TRUE; + tANI_U32 cfgVal; + + if (eSIR_SUCCESS == wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_PASSIVE_CON, + &cfgVal)) + { + limLog(pMac, LOG1, FL("WNI_CFG_ACTIVE_PASSIVE_CON: %d"), cfgVal); + if (!cfgVal) + return; + } + + if ((1 <= channelNum) && (165 >= channelNum)) + { + if (eANI_BOOLEAN_TRUE == limIsconnectedOnDFSChannel(channelNum)) + { + if (dfsChannelList->timeStamp[channelNum] == 0) + { + //Received first beacon; Convert DFS channel to Active channel. + limLog(pMac, LOG1, FL("Received first beacon on DFS channel: %d"), channelNum); + limCovertChannelScanType(pMac,channelNum, passiveToActive); + } + + if (!pMac->fActiveScanOnDFSChannels && + dfsChannelList->timeStamp[channelNum] && + !limActiveScanAllowed(pMac, channelNum)) + limLog(pMac, LOGE, + FL("Received beacon on DFS channel %d with dfs time stamp %lu, but channel is still DFS"), + channelNum, dfsChannelList->timeStamp[channelNum]); + + dfsChannelList->timeStamp[channelNum] = vos_timer_get_system_time(); + } + else + { + return; + } + if (!tx_timer_running(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer)) + { + tx_timer_activate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + } + } + else + { + PELOGE(limLog(pMac, LOGE, FL("Invalid Channel: %d"), channelNum);) + return; + } + + return; +} + +void limDoSendAuthMgmtFrame(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tSirMacAuthFrameBody authFrameBody; + + //Prepare & send Authentication frame + authFrameBody.authAlgoNumber = + (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType; + authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; + authFrameBody.authStatusCode = 0; + pMac->authAckStatus = LIM_AUTH_ACK_NOT_RCD; + limSendAuthMgmtFrame(pMac, + &authFrameBody, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + LIM_NO_WEP_IN_FC, psessionEntry, eSIR_TRUE); + if (tx_timer_activate(&pMac->lim.limTimers.gLimAuthFailureTimer) + != TX_SUCCESS) { + //Could not start Auth failure timer. + //Log error + limLog(pMac, LOGP, + FL("could not start Auth failure timer")); + //Cleanup as if auth timer expired + limProcessAuthFailureTimeout(pMac); + } else { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_AUTH_RETRY_TIMER)); + //Activate Auth Retry timer + if (tx_timer_activate + (&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer) + != TX_SUCCESS) { + limLog(pMac, LOGP, + FL("could not activate Auth Retry timer")); + } + } + return; +} + +/* +* Creates a Raw frame to be sent before every Scan, if required. +* If only infra link is active (mlmState = Link Estb), then send Data Null +* If only BT-AMP-AP link is active(mlmState = BSS_STARTED), then send CTS2Self frame. +* If only BT-AMP-STA link is active(mlmState = BSS_STARTED or Link Est) then send CTS2Self +* If Only IBSS link is active, then send CTS2Self +* for concurrent scenario: Infra+BT or Infra+IBSS, always send CTS2Self, no need to send Data Null +* +*/ +static void __limCreateInitScanRawFrame(tpAniSirGlobal pMac, + tpInitScanParams pInitScanParam) +{ + tANI_U8 i; + pInitScanParam->scanEntry.activeBSScnt = 0; + + /* Don't send CTS to self as we have issue with BTQM queues where BTQM can + * not handle transmition of CTS2self frames. Sending CTS 2 self at this + * juncture also doesn't serve much purpose as probe request frames go out + * immediately, No need to notify BSS in IBSS case. + * */ + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) && + (pInitScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID)) + { + pInitScanParam->scanEntry.bssIdx[pInitScanParam->scanEntry.activeBSScnt] + = pMac->lim.gpSession[i].bssIdx; + pInitScanParam->scanEntry.activeBSScnt++; + + } + } + else if( (eLIM_AP_ROLE == pMac->lim.gpSession[i].limSystemRole ) + && ( VOS_P2P_GO_MODE == pMac->lim.gpSession[i].pePersona ) + ) + { + pInitScanParam->useNoA = TRUE; + } + } + } + if (pInitScanParam->scanEntry.activeBSScnt) + { + pInitScanParam->notifyBss = TRUE; + pInitScanParam->frameType = SIR_MAC_DATA_FRAME; + pInitScanParam->frameLength = 0; + } +} + +/* +* Creates a Raw frame to be sent during finish scan, if required. +* Send data null frame, only when there is just one session active and that session is +* in 'link Estb' state. +* if more than one session is active, don't send any frame. +* for concurrent scenario: Infra+BT or Infra+IBSS, no need to send Data Null +* +*/ +static void __limCreateFinishScanRawFrame(tpAniSirGlobal pMac, + tpFinishScanParams pFinishScanParam) +{ + tANI_U8 i; + pFinishScanParam->scanEntry.activeBSScnt = 0; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + //BT-STA can either be in LINK-ESTB state or BSS_STARTED State + //for BT, need to send CTS2Self + if ((pMac->lim.gpSession[i].limSystemRole != eLIM_BT_AMP_STA_ROLE) && + (pFinishScanParam->scanEntry.activeBSScnt < HAL_NUM_BSSID)) + { + pFinishScanParam->scanEntry.bssIdx[pFinishScanParam->scanEntry.activeBSScnt] + = pMac->lim.gpSession[i].bssIdx; + pFinishScanParam->scanEntry.activeBSScnt++; + } + } + } + } + + if (pFinishScanParam->scanEntry.activeBSScnt) + { + pFinishScanParam->notifyBss = TRUE; + pFinishScanParam->frameType = SIR_MAC_DATA_FRAME; + pFinishScanParam->frameLength = 0; + } +} + +void +limSendHalInitScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState, tSirLinkTrafficCheck trafficCheck) +{ + + + tSirMsgQ msg; + tpInitScanParams pInitScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + pInitScanParam = vos_mem_malloc(sizeof(*pInitScanParam)); + if ( NULL == pInitScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + /*Initialize the pInitScanParam with 0*/ + vos_mem_set((tANI_U8 *)pInitScanParam, sizeof(*pInitScanParam), 0); + + msg.type = WDA_INIT_SCAN_REQ; + msg.bodyptr = pInitScanParam; + msg.bodyval = 0; + + vos_mem_set((tANI_U8 *)&pInitScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr), 0); + if (nextState == eLIM_HAL_INIT_LEARN_WAIT_STATE) + { + pInitScanParam->notifyBss = TRUE; + pInitScanParam->notifyHost = FALSE; + if (eSIR_CHECK_ROAMING_SCAN == trafficCheck) + { + pInitScanParam->scanMode = eHAL_SYS_MODE_ROAM_SCAN; + } + else + { + pInitScanParam->scanMode = eHAL_SYS_MODE_LEARN; + } + + pInitScanParam->frameType = SIR_MAC_CTRL_CTS; + __limCreateInitScanRawFrame(pMac, pInitScanParam); + pInitScanParam->checkLinkTraffic = trafficCheck; + } + else + { + if(nextState == eLIM_HAL_SUSPEND_LINK_WAIT_STATE) + { + if (eSIR_CHECK_ROAMING_SCAN == trafficCheck) + { + pInitScanParam->scanMode = eHAL_SYS_MODE_ROAM_SUSPEND_LINK; + } + else + { + pInitScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK; + } + + } + else + { + if (eSIR_CHECK_ROAMING_SCAN == trafficCheck) + { + pInitScanParam->scanMode = eHAL_SYS_MODE_ROAM_SCAN; + } + else + { + pInitScanParam->scanMode = eHAL_SYS_MODE_SCAN; + } + } + __limCreateInitScanRawFrame(pMac, pInitScanParam); + if (pInitScanParam->useNoA) + { + pInitScanParam->scanDuration = pMac->lim.gTotalScanDuration; + } + /* Inform HAL whether it should check for traffic on the link + * prior to performing a background scan + */ + pInitScanParam->checkLinkTraffic = trafficCheck; + } + + pMac->lim.gLimHalScanState = nextState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + PELOG3(limLog(pMac, LOG3, FL("wdaPostCtrlMsg() return eSIR_SUCCESS pMac=%x nextState=%d"), + pMac, pMac->lim.gLimHalScanState);) + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pInitScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + +error: + switch(nextState) + { + case eLIM_HAL_START_SCAN_WAIT_STATE: + case eLIM_HAL_INIT_SCAN_WAIT_STATE: + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + break; + + + //WLAN_SUSPEND_LINK Related + case eLIM_HAL_SUSPEND_LINK_WAIT_STATE: + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + if( pMac->lim.gpLimSuspendCallback ) + { + pMac->lim.gpLimSuspendCallback( pMac, rc, pMac->lim.gpLimSuspendData ); + pMac->lim.gpLimSuspendCallback = NULL; + pMac->lim.gpLimSuspendData = NULL; + } + pMac->lim.gLimSystemInScanLearnMode = 0; + break; + //end WLAN_SUSPEND_LINK Related + default: + break; + } + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + + return ; +} + +void +limSendHalStartScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState) +{ + tSirMsgQ msg; + tpStartScanParams pStartScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + /** + * The Start scan request to be sent only if Start Scan is not already requested + */ + if(pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE) + { + + pStartScanParam = vos_mem_malloc(sizeof(*pStartScanParam)); + if ( NULL == pStartScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + msg.type = WDA_START_SCAN_REQ; + msg.bodyptr = pStartScanParam; + msg.bodyval = 0; + pStartScanParam->status = eHAL_STATUS_SUCCESS; + pStartScanParam->scanChannel = (tANI_U8)channelNum; + + pMac->lim.gLimHalScanState = nextState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pStartScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + +error: + switch(nextState) + { + case eLIM_HAL_START_SCAN_WAIT_STATE: + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + break; + + + default: + break; + } + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Invalid state for START_SCAN_REQ message=%d"), pMac->lim.gLimHalScanState);) + } + + return; +} + +void limSendHalEndScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanState nextState) +{ + tSirMsgQ msg; + tpEndScanParams pEndScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + /** + * The End scan request to be sent only if End Scan is not already requested or + * Start scan is not already requestd. + * after finish scan rsp from firmware host is sending endscan request so adding + * check for IDLE SCAN STATE also added to avoid this issue + */ + if((pMac->lim.gLimHalScanState != eLIM_HAL_END_SCAN_WAIT_STATE) && + (pMac->lim.gLimHalScanState != eLIM_HAL_IDLE_SCAN_STATE) && + (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) && + (pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) && + (pMac->lim.gLimHalScanState != eLIM_HAL_START_SCAN_WAIT_STATE)) + { + pEndScanParam = vos_mem_malloc(sizeof(*pEndScanParam)); + if ( NULL == pEndScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + msg.type = WDA_END_SCAN_REQ; + msg.bodyptr = pEndScanParam; + msg.bodyval = 0; + pEndScanParam->status = eHAL_STATUS_SUCCESS; + pEndScanParam->scanChannel = (tANI_U8)channelNum; + + pMac->lim.gLimHalScanState = nextState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pEndScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + + error: + switch(nextState) + { + case eLIM_HAL_END_SCAN_WAIT_STATE: + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_END_FAILED); + break; + + + default: + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg Rcvd invalid nextState %d"), nextState);) + break; + } + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Invalid state for END_SCAN_REQ message=%d"), pMac->lim.gLimHalScanState);) + } + + + return; +} + + +void limSendTLPauseInd(tpAniSirGlobal pMac, uint16_t staId) +{ + tSirMsgQ msg; + tSirRetStatus rc = eSIR_SUCCESS; + + msg.type = WDA_PAUSE_TL_IND; + msg.bodyval = staId; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + + limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc); + + return; +} + +/** + * limSendHalFinishScanReq() + * + *FUNCTION: + * This function is called to finish scan/learn request.. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param nextState - this parameters determines whether this call is for scan or learn + * + * @return None + */ +void limSendHalFinishScanReq(tpAniSirGlobal pMac, tLimLimHalScanState nextState) +{ + + tSirMsgQ msg; + tpFinishScanParams pFinishScanParam; + tSirRetStatus rc = eSIR_SUCCESS; + + if(pMac->lim.gLimHalScanState == nextState) + { + /* + * PE may receive multiple probe responses, while waiting for HAL to send 'FINISH_SCAN_RSP' message + * PE was sending multiple finish scan req messages to HAL + * this check will avoid that. + * If PE is already waiting for the 'finish_scan_rsp' message from HAL, it will ignore this request. + */ + PELOGW(limLog(pMac, LOGW, FL("Next Scan State is same as the current state: %d "), nextState);) + return; + } + + pFinishScanParam = vos_mem_malloc(sizeof(*pFinishScanParam)); + if ( NULL == pFinishScanParam ) + { + PELOGW(limLog(pMac, LOGW, FL("AllocateMemory() failed"));) + goto error; + } + + msg.type = WDA_FINISH_SCAN_REQ; + msg.bodyptr = pFinishScanParam; + msg.bodyval = 0; + + peGetResumeChannel(pMac, &pFinishScanParam->currentOperChannel, &pFinishScanParam->cbState); + + vos_mem_set((tANI_U8 *)&pFinishScanParam->macMgmtHdr, sizeof(tSirMacMgmtHdr), 0); + + if (nextState == eLIM_HAL_FINISH_LEARN_WAIT_STATE) + { + //AP - No pkt need to be transmitted + pFinishScanParam->scanMode = eHAL_SYS_MODE_LEARN; + pFinishScanParam->notifyBss = FALSE; + pFinishScanParam->notifyHost = FALSE; + pFinishScanParam->frameType = 0; + + pFinishScanParam->frameLength = 0; + pMac->lim.gLimHalScanState = nextState; + } + else + { + /* If STA is associated with an AP (ie. STA is in + * LINK_ESTABLISHED state), then STA need to inform + * the AP via either DATA-NULL + */ + if (nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE) + { + pFinishScanParam->scanMode = eHAL_SYS_MODE_SUSPEND_LINK; + } + else + { + pFinishScanParam->scanMode = eHAL_SYS_MODE_SCAN; + } + pFinishScanParam->notifyHost = FALSE; + __limCreateFinishScanRawFrame(pMac, pFinishScanParam); + //WLAN_SUSPEND_LINK Related + pMac->lim.gLimHalScanState = nextState; + //end WLAN_SUSPEND_LINK Related + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc == eSIR_SUCCESS) { + return; + } + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pFinishScanParam); + PELOGW(limLog(pMac, LOGW, FL("wdaPostCtrlMsg failed, error code %d"), rc);) + + error: + if(nextState == eLIM_HAL_FINISH_SCAN_WAIT_STATE) + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_FINISH_FAILED); + //WLAN_SUSPEND_LINK Related + else if ( nextState == eLIM_HAL_RESUME_LINK_WAIT_STATE ) + { + if( pMac->lim.gpLimResumeCallback ) + { + pMac->lim.gpLimResumeCallback( pMac, rc, pMac->lim.gpLimResumeData ); + pMac->lim.gpLimResumeCallback = NULL; + pMac->lim.gpLimResumeData = NULL; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + } + //end WLAN_SUSPEND_LINK Related + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + return; +} + +/** + * limContinueChannelScan() + * + *FUNCTION: + * This function is called by limPerformChannelScan(). + * This function is called to continue channel scanning when + * Beacon/Probe Response frame are received. + * + *LOGIC: + * Scan criteria stored in pMac->lim.gLimMlmScanReq is used + * to perform channel scan. In this function MLM sub module + * makes channel switch, sends PROBE REQUEST frame in case of + * ACTIVE SCANNING, starts min/max channel timers, programs + * NAV to probeDelay timer and waits for Beacon/Probe Response. + * Once all required channels are scanned, LIM_MLM_SCAN_CNF + * primitive is used to send Scan results to SME sub module. + * + *ASSUMPTIONS: + * 1. In case of Active scanning, start MAX channel time iff + * MIN channel timer expired and activity is observed on + * the channel. + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ +void +limContinueChannelScan(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + + if (pMac->lim.gLimCurrentScanChannelId > + (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1) + || pMac->lim.abortScan) + { + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + + /// Done scanning all required channels + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + return; + } + + /// Atleast one more channel is to be scanned + + if ((pMac->lim.gLimReturnAfterFirstMatch & 0x40) || + (pMac->lim.gLimReturnAfterFirstMatch & 0x80)) + { + while (pMac->lim.gLimCurrentScanChannelId <= + (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + if (((limGetCurrentScanChannel(pMac) <= 14) && + pMac->lim.gLim24Band11dScanDone) || + ((limGetCurrentScanChannel(pMac) > 14) && + pMac->lim.gLim50Band11dScanDone)) + { + limLog(pMac, LOGW, FL("skipping chan %d"), + limGetCurrentScanChannel(pMac)); + pMac->lim.gLimCurrentScanChannelId++; + } + else + break; + } + + if (pMac->lim.gLimCurrentScanChannelId > + (tANI_U32) (pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + /// Done scanning all required channels + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + return; + } + } + + channelNum = limGetCurrentScanChannel(pMac); + limLog(pMac, LOG1, FL("Current Channel to be scanned is %d"), + channelNum); + + limSendHalStartScanReq(pMac, channelNum, eLIM_HAL_START_SCAN_WAIT_STATE); + return; +} /*** end limContinueChannelScan() ***/ + + + +/** + * limRestorePreScanState() + * + *FUNCTION: + * This function is called by limContinueChannelScan() + * to restore HW state prior to entering 'scan state' + * + *LOGIC + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ +void +limRestorePreScanState(tpAniSirGlobal pMac) +{ + int i; + + /// Deactivate MIN/MAX channel timers if running + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + + /* Re-activate Heartbeat timers for connected sessions as scan + * is done if the DUT is in active mode + * AND it is not a ROAMING ("background") scan */ + if(((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) || + (ePMM_STATE_READY == pMac->pmm.gPmmState)) + && (pMac->lim.gLimBackgroundScanMode != eSIR_ROAMING_SCAN )) + { + for(i=0;ilim.maxBssId;i++) + { + if((peFindSessionBySessionId(pMac,i) != NULL) && + (pMac->lim.gpSession[i].valid == TRUE) && + (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + limReactivateHeartBeatTimer(pMac, peFindSessionBySessionId(pMac,i)); + } + } + } + + /** + * clean up message queue. + * If SME messages, redirect to deferred queue. + * The rest will be discarded. + */ + //limCleanupMsgQ(pMac); + + pMac->lim.gLimSystemInScanLearnMode = 0; + limLog(pMac, LOG1, FL("Scan ended, took %ld tu"), + (tx_time_get() - pMac->lim.scanStartTime)); +} /*** limRestorePreScanState() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +void limSendHalOemDataReq(tpAniSirGlobal pMac) +{ + tSirMsgQ msg; + tpStartOemDataReq pStartOemDataReq = NULL; + tSirRetStatus rc = eSIR_SUCCESS; + tpLimMlmOemDataRsp pMlmOemDataRsp; + tANI_U32 reqLen = 0; + if(NULL == pMac->lim.gpLimMlmOemDataReq) + { + PELOGE(limLog(pMac, LOGE, FL("Null pointer"));) + goto error; + } + + reqLen = sizeof(tStartOemDataReq); + + pStartOemDataReq = vos_mem_malloc(reqLen); + if ( NULL == pStartOemDataReq ) + { + PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: Could not allocate memory for pStartOemDataReq"));) + goto error; + } + + vos_mem_set((tANI_U8*)(pStartOemDataReq), reqLen, 0); + + //Now copy over the information to the OEM DATA REQ to HAL + vos_mem_copy(pStartOemDataReq->selfMacAddr, + pMac->lim.gpLimMlmOemDataReq->selfMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy(pStartOemDataReq->oemDataReq, + pMac->lim.gpLimMlmOemDataReq->oemDataReq, + OEM_DATA_REQ_SIZE); + + //Create the message to be passed to HAL + msg.type = WDA_START_OEM_DATA_REQ; + msg.bodyptr = pStartOemDataReq; + msg.bodyval = 0; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + rc = wdaPostCtrlMsg(pMac, &msg); + if(rc == eSIR_SUCCESS) + { + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_free(pStartOemDataReq); + PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: posting WDA_START_OEM_DATA_REQ to HAL failed"));) + +error: + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + pMlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( NULL == pMlmOemDataRsp ) + { + limLog(pMac->hHdd, LOGP, FL("OEM_DATA: memory allocation for pMlmOemDataRsp failed under suspend link failure")); + return; + } + + if(NULL != pMac->lim.gpLimMlmOemDataReq) + { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp); + + return; +} +/** + * limSetOemDataReqModeFailed() + * + * FUNCTION: + * This function is used as callback to resume link after the suspend fails while + * starting oem data req mode. + * LOGIC: + * NA + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limSetOemDataReqModeFailed(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data) +{ + tpLimMlmOemDataRsp pMlmOemDataRsp; + + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + pMlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( NULL == pMlmOemDataRsp ) + { + limLog(pMac->hHdd, LOGP, FL("OEM_DATA: memory allocation for pMlmOemDataRsp failed under suspend link failure")); + return; + } + + if (NULL != pMac->lim.gpLimMlmOemDataReq) + { + vos_mem_free(pMac->lim.gpLimMlmOemDataReq); + pMac->lim.gpLimMlmOemDataReq = NULL; + } + + vos_mem_set(pMlmOemDataRsp, sizeof(tLimMlmOemDataRsp), 0); + + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp); + + return; +} + +/** + * limSetOemDataReqMode() + * + *FUNCTION: + * This function is called to setup system into OEM DATA REQ mode + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void limSetOemDataReqMode(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data) +{ + if(status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("OEM_DATA: failed in suspend link")); + /* If failed to suspend the link, there is no need + * to resume link. Return failure. + */ + limSetOemDataReqModeFailed(pMac, status, data); + } + else + { + PELOGE(limLog(pMac, LOGE, FL("OEM_DATA: Calling limSendHalOemDataReq"));) + limSendHalOemDataReq(pMac); + } + + return; +} /*** end limSendHalOemDataReq() ***/ + +#endif //FEATURE_OEM_DATA_SUPPORT + +static void +mlm_add_sta( + tpAniSirGlobal pMac, + tpAddStaParams pSta, + tANI_U8 *pBssid, + tANI_U8 htCapable, + tpPESession psessionEntry) //psessionEntry may required in future +{ + tANI_U32 val; + int i; + + + pSta->staType = STA_ENTRY_SELF; // Identifying self + + vos_mem_copy(pSta->bssId, pBssid, sizeof( tSirMacAddr )); + vos_mem_copy(pSta->staMac, psessionEntry->selfMacAddr, sizeof(tSirMacAddr)); + + /* Configuration related parameters to be changed to support BT-AMP */ + + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_LISTEN_INTERVAL, &val )) + limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); + + pSta->listenInterval = (tANI_U16) val; + + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) ) + limLog(pMac, LOGP, FL("Couldn't get SHORT_PREAMBLE")); + pSta->shortPreambleSupported = (tANI_U8)val; + + pSta->assocId = 0; // Is SMAC OK with this? + pSta->wmmEnabled = 0; + pSta->uAPSD = 0; + pSta->maxSPLen = 0; + pSta->us32MaxAmpduDuration = 0; + pSta->maxAmpduSize = 0; // 0: 8k, 1: 16k,2: 32k,3: 64k + + + /* For Self STA get the LDPC capability from config.ini*/ + pSta->htLdpcCapable = + (psessionEntry->txLdpcIniFeatureEnabled & 0x01); + pSta->vhtLdpcCapable = + ((psessionEntry->txLdpcIniFeatureEnabled >> 1)& 0x01); + + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + pSta->htCapable = htCapable; + pSta->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); + pSta->txChannelWidthSet = limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry ); + pSta->mimoPS = (tSirMacHTMIMOPowerSaveState)limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry ); + pSta->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry ); + pSta->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry ); + pSta->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry ); + pSta->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry ); + pSta->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry ); + pSta->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); + pSta->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry); + pSta->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry); + } +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability) + { + pSta->vhtCapable = VOS_TRUE; + pSta->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled; + } +#endif +#ifdef WLAN_FEATURE_11AC + limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry,NULL); +#else + limPopulateOwnRateSet(pMac, &pSta->supportedRates, NULL, false,psessionEntry); +#endif + limFillSupportedRatesInfo(pMac, NULL, &pSta->supportedRates,psessionEntry); + + limLog( pMac, LOGE, FL( "GF: %d, ChnlWidth: %d, MimoPS: %d, lsigTXOP: %d, dsssCCK: %d, SGI20: %d, SGI40%d") , + pSta->greenFieldCapable, pSta->txChannelWidthSet, pSta->mimoPS, pSta->lsigTxopProtection, + pSta->fDsssCckMode40Mhz,pSta->fShortGI20Mhz, pSta->fShortGI40Mhz); + + if (VOS_P2P_GO_MODE == psessionEntry->pePersona) + { + pSta->p2pCapableSta = 1; + } + + //Disable BA. It will be set as part of ADDBA negotiation. + for( i = 0; i < STACFG_MAX_TC; i++ ) + { + pSta->staTCParams[i].txUseBA = eBA_DISABLE; + pSta->staTCParams[i].rxUseBA = eBA_DISABLE; + } + +} + +// +// New HAL interface - WDA_ADD_BSS_REQ +// Package WDA_ADD_BSS_REQ to HAL, in order to start a BSS +// +tSirResultCodes +limMlmAddBss ( + tpAniSirGlobal pMac, + tLimMlmStartReq *pMlmStartReq, + tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tpAddBssParams pAddBssParams = NULL; + tANI_U32 retCode; + + // Package WDA_ADD_BSS_REQ message parameters + + pAddBssParams = vos_mem_malloc(sizeof( tAddBssParams )); + if ( NULL == pAddBssParams ) + { + limLog( pMac, LOGE, FL( "Unable to allocate memory during ADD_BSS" )); + // Respond to SME with LIM_MLM_START_CNF + return eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + + vos_mem_set(pAddBssParams, sizeof(tAddBssParams), 0); + + // Fill in tAddBssParams members + vos_mem_copy(pAddBssParams->bssId, pMlmStartReq->bssId, + sizeof( tSirMacAddr )); + + // Fill in tAddBssParams selfMacAddr + vos_mem_copy (pAddBssParams->selfMacAddr, + psessionEntry->selfMacAddr, + sizeof( tSirMacAddr )); + + pAddBssParams->bssType = pMlmStartReq->bssType; + if ((pMlmStartReq->bssType == eSIR_IBSS_MODE) || + (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE)|| + (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE)) { + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA; + } + else if (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE){ + pAddBssParams->operMode = BSS_OPERATIONAL_MODE_AP; + } + + pAddBssParams->shortSlotTimeSupported = psessionEntry->shortSlotTimeSupported; + + pAddBssParams->beaconInterval = pMlmStartReq->beaconPeriod; + pAddBssParams->dtimPeriod = pMlmStartReq->dtimPeriod; + pAddBssParams->cfParamSet.cfpCount = pMlmStartReq->cfParamSet.cfpCount; + pAddBssParams->cfParamSet.cfpPeriod = pMlmStartReq->cfParamSet.cfpPeriod; + pAddBssParams->cfParamSet.cfpMaxDuration = pMlmStartReq->cfParamSet.cfpMaxDuration; + pAddBssParams->cfParamSet.cfpDurRemaining = pMlmStartReq->cfParamSet.cfpDurRemaining; + + pAddBssParams->rateSet.numRates = pMlmStartReq->rateSet.numRates; + vos_mem_copy(pAddBssParams->rateSet.rate, + pMlmStartReq->rateSet.rate, pMlmStartReq->rateSet.numRates); + + pAddBssParams->nwType = pMlmStartReq->nwType; + + pAddBssParams->htCapable = pMlmStartReq->htCapable; +#ifdef WLAN_FEATURE_11AC + pAddBssParams->vhtCapable = psessionEntry->vhtCapability; + pAddBssParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; +#endif + pAddBssParams->htOperMode = pMlmStartReq->htOperMode; + pAddBssParams->dualCTSProtection = pMlmStartReq->dualCTSProtection; + pAddBssParams->txChannelWidthSet = pMlmStartReq->txChannelWidthSet; + + pAddBssParams->currentOperChannel = pMlmStartReq->channelNumber; + pAddBssParams->currentExtChannel = pMlmStartReq->cbMode; + +#ifdef WLAN_FEATURE_11W + pAddBssParams->rmfEnabled = psessionEntry->limRmfEnabled; +#endif + + /* Update PE sessionId*/ + pAddBssParams->sessionId = pMlmStartReq->sessionId; + + //Send the SSID to HAL to enable SSID matching for IBSS + vos_mem_copy(&(pAddBssParams->ssId.ssId), + pMlmStartReq->ssId.ssId, + pMlmStartReq->ssId.length); + pAddBssParams->ssId.length = pMlmStartReq->ssId.length; + pAddBssParams->bHiddenSSIDEn = pMlmStartReq->ssidHidden; + limLog( pMac, LOGE, FL( "TRYING TO HIDE SSID %d" ),pAddBssParams->bHiddenSSIDEn); + // CR309183. Disable Proxy Probe Rsp. Host handles Probe Requests. Until FW fixed. + pAddBssParams->bProxyProbeRespEn = 0; + pAddBssParams->obssProtEnabled = pMlmStartReq->obssProtEnabled; + +#if defined WLAN_FEATURE_VOWIFI + pAddBssParams->maxTxPower = psessionEntry->maxTxPower; +#endif + mlm_add_sta(pMac, &pAddBssParams->staContext, + pAddBssParams->bssId, pAddBssParams->htCapable,psessionEntry); + + pAddBssParams->status = eHAL_STATUS_SUCCESS; + pAddBssParams->respReqd = 1; + + // Set a new state for MLME + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + pAddBssParams->halPersona=psessionEntry->pePersona; //pass on the session persona to hal + + pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled; + +#if defined WLAN_FEATURE_VOWIFI_11R + pAddBssParams->extSetStaKeyParamValid = 0; +#endif + + // + // FIXME_GEN4 + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.type = WDA_ADD_BSS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pAddBssParams; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + limLog( pMac, LOGW, FL( "Sending WDA_ADD_BSS_REQ..." )); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pAddBssParams); + return eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + + return eSIR_SME_SUCCESS; +} + + +/** + * limProcessMlmStartReq() + * + *FUNCTION: + * This function is called to process MLM_START_REQ message + * from SME + * + *LOGIC: + * 1) MLME receives LIM_MLM_START_REQ from LIM + * 2) MLME sends WDA_ADD_BSS_REQ to HAL + * 3) MLME changes state to eLIM_MLM_WT_ADD_BSS_RSP_STATE + * MLME now waits for HAL to send WDA_ADD_BSS_RSP + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmStartReq *pMlmStartReq; + tLimMlmStartCnf mlmStartCnf; + tpPESession psessionEntry = NULL; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmStartReq = (tLimMlmStartReq *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmStartReq->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + mlmStartCnf.resultCode = eSIR_SME_REFUSED; + goto end; + } + + if (psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE) + { + /** + * Should not have received Start req in states other than idle. + * Return Start confirm with failure code. + */ + PELOGE(limLog(pMac, LOGE, FL("received unexpected MLM_START_REQ in state %X"),psessionEntry->limMlmState);) + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + goto end; + } + + #if 0 + if (cfgSetInt(pMac, WNI_CFG_CURRENT_CHANNEL, pMlmStartReq->channelNumber)!= eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not set CURRENT_CHANNEL at CFG")); + + pMac->lim.gLimCurrentChannelId = pMlmStartReq->channelNumber; + #endif //TO SUPPORT BT-AMP + + + // Update BSSID & SSID at CFG database + #if 0 //We are not using the BSSID and SSID from the config file, instead we are reading form the session table + if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) pMlmStartReq->bssId, sizeof(tSirMacAddr)) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not update BSSID at CFG")); + + + + vos_mem_copy( pMac->lim.gLimCurrentBssId, + pMlmStartReq->bssId, + sizeof(tSirMacAddr)); + #endif //TO SUPPORT BT-AMP + + #if 0 + if (cfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *) &pMlmStartReq->ssId.ssId, pMlmStartReq->ssId.length) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not update SSID at CFG")); + #endif //To SUPPORT BT-AMP + + + // pMac->lim.gLimCurrentSSID.length = pMlmStartReq->ssId.length; + + #if 0 + if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, + (tANI_U8 *) &pMac->lim.gpLimStartBssReq->operationalRateSet.rate, + pMac->lim.gpLimStartBssReq->operationalRateSet.numRates) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not update Operational Rateset at CFG")); + #endif //TO SUPPORT BT-AMP + + + +#if 0 // Periodic timer for remove WPS PBC proble response entry in PE is disbaled now. + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if(pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated == eANI_BOOLEAN_FALSE) + { + if (tx_timer_create(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer, + "PS OVERLAP Timer", + limWPSOverlapTimerHandler, + SIR_LIM_WPS_OVERLAP_TIMEOUT, // expiration_input + SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS), // initial_ticks + SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS), // reschedule_ticks + TX_AUTO_ACTIVATE /* TX_NO_ACTIVATE*/) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create WPS overlap Timer")); + } + + pMac->lim.limTimers.gLimWPSOverlapTimerObj.sessionId = pMlmStartReq->sessionId; + pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated = eANI_BOOLEAN_TRUE; + limLog(pMac, LOGE, FL("Create WPS overlap Timer, session=%d"), pMlmStartReq->sessionId); + + if (tx_timer_activate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_activate failed")); + } + } + } +#endif + + + + mlmStartCnf.resultCode = limMlmAddBss(pMac, pMlmStartReq,psessionEntry); + +end: + /* Update PE session Id */ + mlmStartCnf.sessionId = pMlmStartReq->sessionId; + + /// Free up buffer allocated for LimMlmScanReq + vos_mem_free(pMsgBuf); + + // + // Respond immediately to LIM, only if MLME has not been + // successfully able to send WDA_ADD_BSS_REQ to HAL. + // Else, LIM_MLM_START_CNF will be sent after receiving + // WDA_ADD_BSS_RSP from HAL + // + if( eSIR_SME_SUCCESS != mlmStartCnf.resultCode ) + limPostSmeMessage(pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf); +} /*** limProcessMlmStartReq() ***/ + + +/* +* This function checks if Scan is allowed or not. +* It checks each session and if any session is not in the normal state, +* it will return false. +* Note: BTAMP_STA can be in LINK_EST as well as BSS_STARTED State, so +* both cases are handled below. +*/ + +static tANI_U8 __limMlmScanAllowed(tpAniSirGlobal pMac) +{ + int i; + + if(pMac->lim.gLimMlmState != eLIM_MLM_IDLE_STATE) + { + return FALSE; + } + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(!( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )|| + + ( ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&& + (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) ) + || ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE) + && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) ) + || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ) + && (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_BSS_STARTED_STATE) ) + )) + { + return FALSE; + + } + } + } + + return TRUE; +} + + + +/** + * limProcessMlmScanReq() + * + *FUNCTION: + * This function is called to process MLM_SCAN_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmScanCnf mlmScanCnf; + tANI_U8 i = 0; + tANI_U32 val = 0; + + if (pMac->lim.gLimSystemInScanLearnMode) + { + PELOGE(limLog(pMac, LOGE, + FL("Sending START_SCAN from LIM while one req is pending"));) + vos_mem_free(pMsgBuf); + /*Send back a failure*/ + mlmScanCnf.resultCode = eSIR_SME_SCAN_FAILED; + mlmScanCnf.scanResultLength = 0; + limPostSmeMessage(pMac, + LIM_MLM_SCAN_CNF, + (tANI_U32 *) &mlmScanCnf); + return; + } + + if(__limMlmScanAllowed(pMac) && + (((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels != 0)) + + { + /// Hold onto SCAN REQ criteria + pMac->lim.gpLimMlmScanReq = (tLimMlmScanReq *) pMsgBuf; + + limLog(pMac, LOG1, FL("Number of channels to scan are %d "), + pMac->lim.gpLimMlmScanReq->channelList.numChannels); + + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + + if (pMac->lim.gpLimMlmScanReq->scanType == eSIR_ACTIVE_SCAN) + pMac->lim.gLimMlmState = eLIM_MLM_WT_PROBE_RESP_STATE; + else // eSIR_PASSIVE_SCAN + pMac->lim.gLimMlmState = eLIM_MLM_PASSIVE_SCAN_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + pMac->lim.gLimSystemInScanLearnMode = 1; + + /* temporary fix to handle case where NOA duration calculation is incorrect + * for scanning on DFS channels */ + + pMac->lim.gTotalScanDuration = 0; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS) + { + /* + * Could not get max channel value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve passive max channel value use def")); + /* use a default value */ + val= WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME_STADEF; + } + + for (i = 0; i < pMac->lim.gpLimMlmScanReq->channelList.numChannels; i++) { + tANI_U8 channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[i]; + + if (pMac->miracast_mode) { + pMac->lim.gTotalScanDuration += (DEFAULT_MIN_CHAN_TIME_DURING_MIRACAST + + DEFAULT_MAX_CHAN_TIME_DURING_MIRACAST); + } else if (limActiveScanAllowed(pMac, channelNum)) { + /* Use min + max channel time to calculate the total duration of scan */ + pMac->lim.gTotalScanDuration += pMac->lim.gpLimMlmScanReq->minChannelTime + pMac->lim.gpLimMlmScanReq->maxChannelTime; + } else { + /* using the value from WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME as is done in + * void limContinuePostChannelScan(tpAniSirGlobal pMac) + */ + pMac->lim.gTotalScanDuration += val; + } + } + + /* Adding an overhead of 5ms to account for the scan messaging delays */ + pMac->lim.gTotalScanDuration += 5; + limSetScanMode(pMac); + } + else + { + /** + * Should not have received SCAN req in other states + * OR should not have received LIM_MLM_SCAN_REQ with + * zero number of channels + * Log error + */ + limLog(pMac, LOGW, + FL("received unexpected MLM_SCAN_REQ in state %d OR zero number of channels: %d"), + pMac->lim.gLimMlmState, ((tLimMlmScanReq *) pMsgBuf)->channelList.numChannels); + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + + /// Free up buffer allocated for + /// pMac->lim.gLimMlmScanReq + vos_mem_free(pMsgBuf); + + /// Return Scan confirm with INVALID_PARAMETERS + + mlmScanCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmScanCnf.scanResultLength = 0; + limPostSmeMessage(pMac, + LIM_MLM_SCAN_CNF, + (tANI_U32 *) &mlmScanCnf); + } +} /*** limProcessMlmScanReq() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT +static void limProcessMlmOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmOemDataRsp* pMlmOemDataRsp; + + if (((pMac->lim.gLimMlmState == eLIM_MLM_IDLE_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_JOINED_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_AUTHENTICATED_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_BSS_STARTED_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE))) + { + //Hold onto the oem data request criteria + pMac->lim.gpLimMlmOemDataReq = (tLimMlmOemDataReq*)pMsgBuf; + + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + //Now request for link suspension + limSuspendLink(pMac, eSIR_CHECK_LINK_TRAFFIC_BEFORE_SCAN, limSetOemDataReqMode, NULL); + } + else + { + /** + * Should not have received oem data req in other states + * Log error + */ + + PELOGW(limLog(pMac, LOGW, FL("OEM_DATA: unexpected LIM_MLM_OEM_DATA_REQ in invalid state %d"),pMac->lim.gLimMlmState);) + + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + + /// Free up buffer allocated + vos_mem_free(pMsgBuf); + + /// Return Meas confirm with INVALID_PARAMETERS + pMlmOemDataRsp = vos_mem_malloc(sizeof(tLimMlmOemDataRsp)); + if ( pMlmOemDataRsp != NULL) + { + limPostSmeMessage(pMac, LIM_MLM_OEM_DATA_CNF, (tANI_U32*)pMlmOemDataRsp); + vos_mem_free(pMlmOemDataRsp); + } + else + { + limLog(pMac, LOGP, FL("Could not allocate memory for pMlmOemDataRsp")); + return; + } + } + + return; +} +#endif //FEATURE_OEM_DATA_SUPPORT + + +/** + * limProcessMlmPostJoinSuspendLink() + * + *FUNCTION: + * This function is called after the suspend link while joining + * off channel. + * + *LOGIC: + * Check for suspend state. + * If success, proceed with setting link state to recieve the + * probe response/beacon from intended AP. + * Switch to the APs channel. + * On an error case, send the MLM_JOIN_CNF with error status. + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param status status of suspend link. + * @param ctx passed while calling suspend link(psessionEntry) + * @return None + */ +static void +limProcessMlmPostJoinSuspendLink(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *ctx) +{ + tANI_U8 chanNum, secChanOffset; + tLimMlmJoinCnf mlmJoinCnf; + tpPESession psessionEntry = (tpPESession)ctx; + tSirLinkState linkState; + + if( eHAL_STATUS_SUCCESS != status ) + { + limLog(pMac, LOGE, FL("Sessionid %d Suspend link(NOTIFY_BSS) failed. " + "still proceeding with join"),psessionEntry->peSessionId); + } + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_JOIN_BEACON_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limLog(pMac, LOG1, FL("Sessionid %d prev lim state %d new lim state %d " + "systemrole = %d"), psessionEntry->peSessionId, + psessionEntry->limPrevMlmState, + psessionEntry->limMlmState,psessionEntry->limSystemRole); + + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + + //assign appropriate sessionId to the timer object + pMac->lim.limTimers.gLimJoinFailureTimer.sessionId = psessionEntry->peSessionId; + + linkState = ((psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) ? eSIR_LINK_BTAMP_PREASSOC_STATE : eSIR_LINK_PREASSOC_STATE); + limLog(pMac, LOG1, FL("[limProcessMlmJoinReq]: linkState:%d"),linkState); + + if (limSetLinkState(pMac, linkState, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + { + limLog(pMac, LOGE, + FL("SessionId:%d limSetLinkState to eSIR_LINK_PREASSOC_STATE" + " Failed!!"),psessionEntry->peSessionId); + limPrintMacAddr(pMac, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId,LOGE); + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + goto error; + } + + /** Derive channel from BSS description and store it in the CFG */ + // chanNum = pMac->lim.gpLimMlmJoinReq->bssDescription.channelId; + + chanNum = psessionEntry->currentOperChannel; + secChanOffset = psessionEntry->htSecondaryChannelOffset; + //store the channel switch sessionEntry in the lim global var + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_JOIN; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + psessionEntry->pLimMlmReassocRetryReq = NULL; +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_CHANNEL_SWITCH_ANOUNCEMENT, + psessionEntry, eSIR_SUCCESS, LIM_SWITCH_CHANNEL_JOIN); +#endif + + limLog(pMac, LOG1, FL("[limProcessMlmJoinReq]: suspend link success(%d) " + "on sessionid: %d setting channel to: %d with secChanOffset:%d " + "and maxtxPower: %d"), status, psessionEntry->peSessionId, + chanNum, secChanOffset, psessionEntry->maxTxPower); + limSetChannel(pMac, chanNum, secChanOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); + + return; +error: + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); + +} + + + +/** + * limProcessMlmJoinReq() + * + *FUNCTION: + * This function is called to process MLM_JOIN_REQ message + * from SME + * + *LOGIC: + * 1) Initialize LIM, HAL, DPH + * 2) Configure the BSS for which the JOIN REQ was received + * a) Send WDA_ADD_BSS_REQ to HAL - + * This will identify the BSS that we are interested in + * --AND-- + * Add a STA entry for the AP (in a STA context) + * b) Wait for WDA_ADD_BSS_RSP + * c) Send WDA_ADD_STA_REQ to HAL + * This will add the "local STA" entry to the STA table + * 3) Continue as before, i.e, + * a) Send a PROBE REQ + * b) Wait for PROBE RSP/BEACON containing the SSID that + * we are interested in + * c) Then start an AUTH seq + * d) Followed by the ASSOC seq + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmJoinCnf mlmJoinCnf; + tANI_U8 sessionId; + tpPESession psessionEntry; + + sessionId = ((tpLimMlmJoinReq)pMsgBuf)->sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac,sessionId))== NULL) + { + limLog(pMac, LOGE, FL("SessionId:%d session does not exist"),sessionId); + goto error; + } + + if (( (psessionEntry->limSystemRole != eLIM_AP_ROLE ) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE )) && + ( (psessionEntry->limMlmState == eLIM_MLM_IDLE_STATE) || + (psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE)) && + (SIR_MAC_GET_ESS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo) != + SIR_MAC_GET_IBSS( ((tpLimMlmJoinReq) pMsgBuf)->bssDescription.capabilityInfo))) + { + #if 0 + if (pMac->lim.gpLimMlmJoinReq) + vos_mem_free(pMac->lim.gpLimMlmJoinReq); + #endif //TO SUPPORT BT-AMP , review 23sep + + /// Hold onto Join request parameters + + psessionEntry->pLimMlmJoinReq =(tpLimMlmJoinReq) pMsgBuf; + + if( isLimSessionOffChannel(pMac, sessionId) ) + { + //suspend link + limLog(pMac, LOG1, FL("Suspend link as LimSession on sessionid %d" + "is off channel"),sessionId); + if (limIsLinkSuspended(pMac)) + { + limLog(pMac, LOGE, FL("Link is already suspended for some other" + " reason. Return failure on sessionId:%d"), sessionId); + goto error; + } + limSuspendLink(pMac, eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN, + limProcessMlmPostJoinSuspendLink, (tANI_U32*)psessionEntry ); + } + else + { + //No need to suspend link. + limLog(pMac,LOG1,"SessionId:%d Join request on current channel", + sessionId); + limProcessMlmPostJoinSuspendLink( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) psessionEntry ); + } + + return; + } + else + { + /** + * Should not have received JOIN req in states other than + * Idle state or on AP. + * Return join confirm with invalid parameters code. + */ + limLog(pMac, LOGE, + FL("SessionId:%d Unexpected Join request for role %d state %d "), + psessionEntry->peSessionId,psessionEntry->limSystemRole, + psessionEntry->limMlmState); + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + } + +error: + vos_mem_free(pMsgBuf); + if (psessionEntry != NULL) + psessionEntry->pLimMlmJoinReq = NULL; + + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmJoinCnf.sessionId = sessionId; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); +} /*** limProcessMlmJoinReq() ***/ + + + +/** + * limProcessMlmAuthReq() + * + *FUNCTION: + * This function is called to process MLM_AUTH_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmAuthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 numPreAuthContexts; + tSirMacAddr currentBssId; + tLimMlmAuthCnf mlmAuthCnf; + struct tLimPreAuthNode *preAuthNode; + tpDphHashNode pStaDs; + tANI_U8 sessionId; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMac->lim.gpLimMlmAuthReq = (tLimMlmAuthReq *) pMsgBuf; + sessionId = pMac->lim.gpLimMlmAuthReq->sessionId; + if((psessionEntry= peFindSessionBySessionId(pMac,sessionId) )== NULL) + { + limLog(pMac, LOGP, FL("SessionId:%d Session Does not exist"),sessionId); + return; + } + + limLog(pMac, LOG1,FL("Process Auth Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR" with authtype %d"), sessionId, + psessionEntry->limSystemRole,psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMac->lim.gpLimMlmAuthReq->peerMacAddr), + pMac->lim.gpLimMlmAuthReq->authType); + + + /** + * Expect Auth request only when: + * 1. STA joined/associated with a BSS or + * 2. STA is in IBSS mode + * and STA is going to authenticate with a unicast + * adress and requested authentication algorithm is + * supported. + */ + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != + eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //To SuppoRT BT-AMP + + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if (((((psessionEntry->limSystemRole== eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + ((psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) || + (psessionEntry->limMlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE))) || + ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE))) && + (limIsGroupAddr(pMac->lim.gpLimMlmAuthReq->peerMacAddr) + == false) && + (limIsAuthAlgoSupported( + pMac, + pMac->lim.gpLimMlmAuthReq->authType, + psessionEntry) == true) + ) + { + /** + * This is a request for pre-authentication. + * Check if there exists context already for + * the requested peer OR + * if this request is for the AP we're currently + * associated with. + * If yes, return auth confirm immediately when + * requested auth type is same as the one used before. + */ + if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) )&& + (psessionEntry->limMlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (((pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) != NULL) && + (pMac->lim.gpLimMlmAuthReq->authType == + pStaDs->mlmStaContext.authType)) && + (vos_mem_compare(pMac->lim.gpLimMlmAuthReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)) )) || + (((preAuthNode = + limSearchPreAuthList( + pMac, + pMac->lim.gpLimMlmAuthReq->peerMacAddr)) != NULL) && + (preAuthNode->authType == + pMac->lim.gpLimMlmAuthReq->authType))) + { + limLog(pMac, LOG2, + FL("Already have pre-auth context with peer: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMac->lim.gpLimMlmAuthReq->peerMacAddr)); + + mlmAuthCnf.resultCode = (tSirResultCodes) + eSIR_MAC_SUCCESS_STATUS; + + + goto end; + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH, + (tANI_U32 *) &numPreAuthContexts) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Could not retrieve NumPreAuthLimit from CFG")); + } + + if (pMac->lim.gLimNumPreAuthContexts == numPreAuthContexts) + { + PELOGW(limLog(pMac, LOGW, + FL("Number of pre-auth reached max limit"));) + + /// Return Auth confirm with reject code + mlmAuthCnf.resultCode = + eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED; + + goto end; + } + } + + // Delete pre-auth node if exists + if (preAuthNode) + limDeletePreAuthNode(pMac, + pMac->lim.gpLimMlmAuthReq->peerMacAddr); + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_AUTH_FRAME2_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + //assign appropriate sessionId to the timer object + pMac->lim.limTimers.gLimAuthFailureTimer.sessionId = sessionId; + /* assign appropriate sessionId to the timer object */ + pMac->lim.limTimers.gLimPeriodicAuthRetryTimer.sessionId = sessionId; + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER); + // Activate Auth failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_AUTH_FAIL_TIMER)); + + limDoSendAuthMgmtFrame(pMac, psessionEntry); + return; + } + else + { + /** + * Unexpected auth request. + * Return Auth confirm with Invalid parameters code. + */ + mlmAuthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + +end: + vos_mem_copy((tANI_U8 *) &mlmAuthCnf.peerMacAddr, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + + mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType; + mlmAuthCnf.sessionId = sessionId; + + /// Free up buffer allocated + /// for pMac->lim.gLimMlmAuthReq + vos_mem_free( pMac->lim.gpLimMlmAuthReq); + pMac->lim.gpLimMlmAuthReq = NULL; + limLog(pMac,LOG1,"SessionId:%d LimPostSme LIM_MLM_AUTH_CNF ",sessionId); + limPostSmeMessage(pMac, LIM_MLM_AUTH_CNF, (tANI_U32 *) &mlmAuthCnf); +} /*** limProcessMlmAuthReq() ***/ + + + +/** + * limProcessMlmAssocReq() + * + *FUNCTION: + * This function is called to process MLM_ASSOC_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmAssocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMacAddr currentBssId; + tLimMlmAssocReq *pMlmAssocReq; + tLimMlmAssocCnf mlmAssocCnf; + tpPESession psessionEntry; + // tANI_U8 sessionId; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmAssocReq = (tLimMlmAssocReq *) pMsgBuf; + + if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmAssocReq->sessionId) )== NULL) + { + limLog(pMac, LOGP,FL("SessionId:%d Session Does not exist"), + pMlmAssocReq->sessionId); + vos_mem_free(pMlmAssocReq); + return; + } + + limLog(pMac, LOG1,FL("Process Assoc Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmAssocReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmAssocReq->peerMacAddr)); + + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != + eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if ( (psessionEntry->limSystemRole != eLIM_AP_ROLE && psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_AUTHENTICATED_STATE || psessionEntry->limMlmState == eLIM_MLM_JOINED_STATE) && + (vos_mem_compare(pMlmAssocReq->peerMacAddr, currentBssId, sizeof(tSirMacAddr))) ) + { + + /// map the session entry pointer to the AssocFailureTimer + pMac->lim.limTimers.gLimAssocFailureTimer.sessionId = pMlmAssocReq->sessionId; + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_ASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog(pMac,LOG1,"SessionId:%d Sending Assoc_Req Frame", + psessionEntry->peSessionId); + + /// Prepare and send Association request frame + limSendAssocReqMgmtFrame(pMac, pMlmAssocReq,psessionEntry); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ASSOC_REQ_EVENT, psessionEntry, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + + + //Set the link state to postAssoc, so HW can start receiving frames from AP. + if ((psessionEntry->bssType == eSIR_BTAMP_STA_MODE)|| + ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE) && (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))) + { + if(limSetLinkState(pMac, eSIR_LINK_BTAMP_POSTASSOC_STATE, currentBssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState"));) + } + /// Start association failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_ASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimAssocFailureTimer) + != TX_SUCCESS) + { + /// Could not start Assoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("SessionId:%d could not start Association failure timer"), + psessionEntry->peSessionId); + // Cleanup as if assoc timer expired + limProcessAssocFailureTimeout(pMac,LIM_ASSOC ); + + } + + return; + } + else + { + /** + * Received Association request either in invalid state + * or to a peer MAC entity whose address is different + * from one that STA is currently joined with or on AP. + * Return Assoc confirm with Invalid parameters code. + */ + + // Log error + PELOGW(limLog(pMac, LOGW, + FL("received unexpected MLM_ASSOC_CNF in state %d for role=%d, MAC addr= " + MAC_ADDRESS_STR), psessionEntry->limMlmState, + psessionEntry->limSystemRole, MAC_ADDR_ARRAY(pMlmAssocReq->peerMacAddr));) + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + + mlmAssocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + goto end; + } + +end: + /* Update PE session Id*/ + mlmAssocCnf.sessionId = pMlmAssocReq->sessionId; + + /// Free up buffer allocated for assocReq + vos_mem_free(pMlmAssocReq); + + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); +} /*** limProcessMlmAssocReq() ***/ + + + +/** + * limProcessMlmReassocReq() + * + *FUNCTION: + * This function is called to process MLM_REASSOC_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U8 chanNum, secChannelOffset; + struct tLimPreAuthNode *pAuthNode; + tLimMlmReassocReq *pMlmReassocReq; + tLimMlmReassocCnf mlmReassocCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmReassocReq = (tLimMlmReassocReq *) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmReassocReq->sessionId)) == NULL) + { + limLog(pMac, LOGE,FL("Session Does not exist for given sessionId %d"), + pMlmReassocReq->sessionId); + vos_mem_free(pMlmReassocReq); + return; + } + + limLog(pMac, LOG1,FL("Process ReAssoc Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmReassocReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmReassocReq->peerMacAddr)); + + if (((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) && + (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) + { + if (psessionEntry->pLimMlmReassocReq) + vos_mem_free(psessionEntry->pLimMlmReassocReq); + + /* Hold Re-Assoc request as part of Session, knock-out pMac */ + /// Hold onto Reassoc request parameters + psessionEntry->pLimMlmReassocReq = pMlmReassocReq; + + // See if we have pre-auth context with new AP + pAuthNode = limSearchPreAuthList(pMac, psessionEntry->limReAssocbssId); + + if (!pAuthNode && + (!vos_mem_compare(pMlmReassocReq->peerMacAddr, + psessionEntry->bssId, + sizeof(tSirMacAddr)) )) + { + // Either pre-auth context does not exist AND + // we are not reassociating with currently + // associated AP. + // Return Reassoc confirm with not authenticated + mlmReassocCnf.resultCode = eSIR_SME_STA_NOT_AUTHENTICATED; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + goto end; + } + + //assign the sessionId to the timer object + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = pMlmReassocReq->sessionId; + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + +#if 0 + // Update BSSID at CFG database + if (wlan_cfgSetStr(pMac, WNI_CFG_BSSID, + pMac->lim.gLimReassocBssId, + sizeof(tSirMacAddr)) != eSIR_SUCCESS) + { + /// Could not update BSSID at CFG. Log error. + limLog(pMac, LOGP, FL("could not update BSSID at CFG")); + } +#endif //TO SUPPORT BT-AMP + + /* Copy Global Reassoc ID*/ + // sirCopyMacAddr(psessionEntry->reassocbssId,pMac->lim.gLimReAssocBssId); + + /** + * Derive channel from BSS description and + * store it at CFG. + */ + + chanNum = psessionEntry->limReassocChannelId; + secChannelOffset = psessionEntry->reAssocHtSecondaryChannelOffset; + + /* To Support BT-AMP .. read channel number from psessionEntry*/ + //chanNum = psessionEntry->currentOperChannel; + + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + + //store the channel switch sessionEntry in the lim global var + /* We have already saved the ReAssocreq Pointer abobe */ + //psessionEntry->pLimReAssocReq = (void *)pMlmReassocReq; + psessionEntry->channelChangeReasonCode = LIM_SWITCH_CHANNEL_REASSOC; + + /** Switch channel to the new Operating channel for Reassoc*/ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_CHANNEL_SWITCH_ANOUNCEMENT, + psessionEntry, eSIR_SUCCESS, LIM_SWITCH_CHANNEL_REASSOC); +#endif + + limSetChannel(pMac, chanNum, secChannelOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); + + return; + } + else + { + /** + * Received Reassoc request in invalid state or + * in AP role.Return Reassoc confirm with Invalid + * parameters code. + */ + + // Log error + limLog(pMac, LOGW, + FL("received unexpected MLM_REASSOC_CNF in state %d for role=%d, " + "MAC addr= " + MAC_ADDRESS_STR), psessionEntry->limMlmState, + psessionEntry->limSystemRole, + MAC_ADDR_ARRAY(pMlmReassocReq->peerMacAddr)); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + + mlmReassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + goto end; + } + +end: + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE sessio Id*/ + mlmReassocCnf.sessionId = pMlmReassocReq->sessionId; + /// Free up buffer allocated for reassocReq + vos_mem_free(pMlmReassocReq); + psessionEntry->pLimReAssocReq = NULL; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} /*** limProcessMlmReassocReq() ***/ + + +static void +limProcessMlmDisassocReqNtf(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf) +{ + tANI_U16 aid; + tSirMacAddr currentBssId; + tpDphHashNode pStaDs; + tLimMlmDisassocReq *pMlmDisassocReq; + tLimMlmDisassocCnf mlmDisassocCnf; + tpPESession psessionEntry; + extern tANI_BOOLEAN sendDisassocFrame; + tSirSmeDisassocRsp *pSirSmeDisassocRsp; + tANI_U32 *pMsg; + tANI_U8 *pBuf; + + if(eHAL_STATUS_SUCCESS != suspendStatus) + { + PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X"), suspendStatus);) +#if 0 + //It can ignore the status and proceed with the disassoc processing. + mlmDisassocCnf.resultCode = eSIR_SME_REFUSED; + goto end; +#endif + } + + pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocReq->sessionId))== NULL) + { + + limLog(pMac, LOGE, + FL("session does not exist for given sessionId %d"), + pMlmDisassocReq->sessionId); + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + limLog(pMac, LOG1,FL("Process DisAssoc Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmDisassocReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr)); + + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != + eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //BT-AMP Support + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + if ( !vos_mem_compare(pMlmDisassocReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)) ) + { + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DISASSOC_REQ with invalid BSS id from: " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr));) + + /// Prepare and Send LIM_MLM_DISASSOC_CNF + + mlmDisassocCnf.resultCode = + eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + + break; + + case eLIM_STA_IN_IBSS_ROLE: + + break; + + default: // eLIM_AP_ROLE + + // Fall through + break; + + } // end switch (psessionEntry->limSystemRole) + + /** + * Check if there exists a context for the peer entity + * to be disassociated with. + */ + pStaDs = dphLookupHashEntry(pMac, pMlmDisassocReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if ((pStaDs == NULL) || + (pStaDs && + ((pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_WT_ASSOC_CNF_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_ASSOCIATED_STATE)))) + { + /** + * Received LIM_MLM_DISASSOC_REQ for STA that does not + * have context or in some transit state. + * Log error + */ + limLog(pMac, LOGE, + FL("received MLM_DISASSOC_REQ for STA that either has no context " + "or in some transit state, Addr= " + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr)); + if (pStaDs != NULL) + limLog(pMac, LOGE, FL("Sta MlmState : %d"), + pStaDs->mlmStaContext.mlmState); + + /* + * Disassociation response due to + * host triggered disassociation + */ + + pSirSmeDisassocRsp = vos_mem_malloc(sizeof(tSirSmeDisassocRsp)); + if ( NULL == pSirSmeDisassocRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DISASSOC_RSP")); + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with " + "retCode: %d for "MAC_ADDRESS_STR),eSIR_SME_DEAUTH_STATUS, + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr)); + pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP; + pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp); + pSirSmeDisassocRsp->sessionId = pMlmDisassocReq->sessionId; + pSirSmeDisassocRsp->transactionId = 0; + pSirSmeDisassocRsp->statusCode = eSIR_SME_DEAUTH_STATUS; + + pBuf = (tANI_U8 *) pSirSmeDisassocRsp->peerMacAddr; + vos_mem_copy( pBuf, pMlmDisassocReq->peerMacAddr, sizeof(tSirMacAddr)); + + pMsg = (tANI_U32*) pSirSmeDisassocRsp; + + limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pMsg ); + return; + + } + + //pStaDs->mlmStaContext.rxPurgeReq = 1; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) + pMlmDisassocReq->reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = pMlmDisassocReq->disassocTrigger; + /** Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE + * This is to address the issue of race condition between + * disconnect request from the HDD and deauth from AP + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + /// Send Disassociate frame to peer entity + if (sendDisassocFrame && (pMlmDisassocReq->reasonCode != eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) + { + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = pMlmDisassocReq; + if (IS_FW_IN_TX_PATH_FEATURE_ENABLE) + { + limSendDisassocMgmtFrame(pMac, pMlmDisassocReq->reasonCode, + pMlmDisassocReq->peerMacAddr, + psessionEntry, FALSE); + /* Send Disassoc CNF and receive path cleanup */ + limSendDisassocCnf(pMac); + } + else + { + limSendDisassocMgmtFrame(pMac, pMlmDisassocReq->reasonCode, + pMlmDisassocReq->peerMacAddr, + psessionEntry, TRUE); + } + } + else + { + /* Disassoc frame is not sent OTA */ + sendDisassocFrame = 1; + // Receive path cleanup with dummy packet + if(eSIR_SUCCESS != limCleanupRxPath(pMac, pStaDs,psessionEntry)) + { + mlmDisassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + // Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + } + + return; + +end: + vos_mem_copy((tANI_U8 *) &mlmDisassocCnf.peerMacAddr, + (tANI_U8 *) pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDisassocCnf.aid = pMlmDisassocReq->aid; + mlmDisassocCnf.disassocTrigger = pMlmDisassocReq->disassocTrigger; + + /* Update PE session ID*/ + mlmDisassocCnf.sessionId = pMlmDisassocReq->sessionId; + + /// Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + + limPostSmeMessage(pMac, + LIM_MLM_DISASSOC_CNF, + (tANI_U32 *) &mlmDisassocCnf); +} + +tANI_BOOLEAN limCheckDisassocDeauthAckPending(tpAniSirGlobal pMac, + tANI_U8 *staMac + ) +{ + tLimMlmDisassocReq *pMlmDisassocReq; + tLimMlmDeauthReq *pMlmDeauthReq; + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if ( + (pMlmDisassocReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)))) + || + (pMlmDeauthReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)))) + ) + { + PELOG1(limLog(pMac, LOG1, FL("Disassoc/Deauth ack pending"));) + return eANI_BOOLEAN_TRUE; + } + else + { + PELOG1(limLog(pMac, LOG1, FL("Disassoc/Deauth Ack not pending"));) + return eANI_BOOLEAN_FALSE; + } +} + +void limCleanUpDisassocDeauthReq(tpAniSirGlobal pMac, + tANI_U8 *staMac, + tANI_BOOLEAN cleanRxPath) +{ + tLimMlmDisassocReq *pMlmDisassocReq; + tLimMlmDeauthReq *pMlmDeauthReq; + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + if (pMlmDisassocReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + if (cleanRxPath) + { + limProcessDisassocAckTimeout(pMac); + } + else + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDisassocAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DISASSOC_ACK_TIMER); + } + vos_mem_free(pMlmDisassocReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; + } + } + + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if (pMlmDeauthReq && + (vos_mem_compare((tANI_U8 *) staMac, + (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)))) + { + if (cleanRxPath) + { + limProcessDeauthAckTimeout(pMac); + } + else + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DEAUTH_ACK_TIMER); + } + vos_mem_free(pMlmDeauthReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL; + } + } +} + +void limProcessDisassocAckTimeout(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("")); + limSendDisassocCnf(pMac); +} + +/** + * limProcessMlmDisassocReq() + * + *FUNCTION: + * This function is called to process MLM_DISASSOC_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDisassocReq *pMlmDisassocReq; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmDisassocReq = (tLimMlmDisassocReq *) pMsgBuf; + + limLog(pMac, LOG1,FL("Process DisAssoc Req on sessionID %d " + "from: "MAC_ADDRESS_STR), pMlmDisassocReq->sessionId, + MAC_ADDR_ARRAY(pMlmDisassocReq->peerMacAddr)); + + limProcessMlmDisassocReqNtf( pMac, eHAL_STATUS_SUCCESS, (tANI_U32*) pMsgBuf ); + +} /*** limProcessMlmDisassocReq() ***/ + +static void +limProcessMlmDeauthReqNtf(tpAniSirGlobal pMac, eHalStatus suspendStatus, tANI_U32 *pMsgBuf) +{ + tANI_U16 aid; + tSirMacAddr currentBssId; + tpDphHashNode pStaDs; + struct tLimPreAuthNode *pAuthNode; + tLimMlmDeauthReq *pMlmDeauthReq; + tLimMlmDeauthCnf mlmDeauthCnf; + tpPESession psessionEntry; + tSirSmeDeauthRsp *pSirSmeDeauthRsp; + tANI_U8 *pBuf; + tANI_U32 *pMsg; + + + if(eHAL_STATUS_SUCCESS != suspendStatus) + { + PELOGE(limLog(pMac, LOGE,FL("Suspend Status is not success %X"), suspendStatus);) +#if 0 + //It can ignore the status and proceed with the disassoc processing. + mlmDisassocCnf.resultCode = eSIR_SME_REFUSED; + goto end; +#endif + } + + pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL) + { + + limLog(pMac, LOGE, FL("session does not exist for given sessionId %d"), + pMlmDeauthReq->sessionId); + vos_mem_free(pMlmDeauthReq); + return; + } + limLog(pMac, LOG1,FL("Process Deauth Req on sessionID %d Systemrole %d" + "mlmstate %d from: "MAC_ADDRESS_STR), pMlmDeauthReq->sessionId, + psessionEntry->limSystemRole, psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr)); + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != + eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + switch (psessionEntry->limMlmState) + { + case eLIM_MLM_IDLE_STATE: + // Attempting to Deauthenticate + // with a pre-authenticated peer. + // Deauthetiate with peer if there + // exists a pre-auth context below. + break; + + case eLIM_MLM_AUTHENTICATED_STATE: + case eLIM_MLM_WT_ASSOC_RSP_STATE: + case eLIM_MLM_LINK_ESTABLISHED_STATE: + if (!vos_mem_compare(pMlmDeauthReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)) ) + { + limLog(pMac, LOGE, + FL("received MLM_DEAUTH_REQ with invalid BSS id " + "Peer MAC: "MAC_ADDRESS_STR " CFG BSSID Addr : " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr), + MAC_ADDR_ARRAY(currentBssId)); + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + + goto end; + } + + if ((psessionEntry->limMlmState == + eLIM_MLM_AUTHENTICATED_STATE) || + (psessionEntry->limMlmState == + eLIM_MLM_WT_ASSOC_RSP_STATE)) + { + // Send Deauthentication frame + // to peer entity + limSendDeauthMgmtFrame( + pMac, + pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, FALSE); + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS; + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + goto end; + } + else + { + // LINK_ESTABLISED_STATE + // Cleanup RX & TX paths + // below + } + + break; + + default: + + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DEAUTH_REQ with in state %d for peer "MAC_ADDRESS_STR), + psessionEntry->limMlmState,MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + + /// Prepare and Send LIM_MLM_DEAUTH_CNF + mlmDeauthCnf.resultCode = + eSIR_SME_STA_NOT_AUTHENTICATED; + + goto end; + } + + break; + + case eLIM_STA_IN_IBSS_ROLE: + limLog(pMac, LOGE, + FL("received MLM_DEAUTH_REQ IBSS Mode ")); + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + default: // eLIM_AP_ROLE + break; + + } // end switch (psessionEntry->limSystemRole) + + /** + * Check if there exists a context for the peer entity + * to be deauthenticated with. + */ + pStaDs = dphLookupHashEntry(pMac, pMlmDeauthReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + /// Check if there exists pre-auth context for this STA + pAuthNode = limSearchPreAuthList(pMac, + pMlmDeauthReq->peerMacAddr); + + if (pAuthNode == NULL) + { + /** + * Received DEAUTH REQ for a STA that is neither + * Associated nor Pre-authenticated. Log error, + * Prepare and Send LIM_MLM_DEAUTH_CNF + */ + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DEAUTH_REQ in mlme state %d for STA that " + "does not have context, Addr="MAC_ADDRESS_STR), + psessionEntry->limMlmState, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + + mlmDeauthCnf.resultCode = + eSIR_SME_STA_NOT_AUTHENTICATED; + } + else + { + mlmDeauthCnf.resultCode = eSIR_SME_SUCCESS; + + /// Delete STA from pre-auth STA list + limDeletePreAuthNode(pMac, pMlmDeauthReq->peerMacAddr); + + /// Send Deauthentication frame to peer entity + limSendDeauthMgmtFrame(pMac, + pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, FALSE); + } + + goto end; + } + else if ((pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_WT_ASSOC_CNF_STATE)) + { + /** + * Received LIM_MLM_DEAUTH_REQ for STA that is n + * some transit state. Log error. + */ + PELOGW(limLog(pMac, LOGW, + FL("received MLM_DEAUTH_REQ for STA that either has no context or in some transit state, Addr=" + MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr));) + + /* + * Deauthentication response to host triggered + * deauthentication. + */ + pSirSmeDeauthRsp = vos_mem_malloc(sizeof(tSirSmeDeauthRsp)); + if ( NULL == pSirSmeDeauthRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with " + "retCode: %d for"MAC_ADDRESS_STR),eSIR_SME_DEAUTH_STATUS, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr)); + pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP; + pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp); + pSirSmeDeauthRsp->statusCode = eSIR_SME_DEAUTH_STATUS; + pSirSmeDeauthRsp->sessionId = pMlmDeauthReq->sessionId; + pSirSmeDeauthRsp->transactionId = 0; + + pBuf = (tANI_U8 *) pSirSmeDeauthRsp->peerMacAddr; + vos_mem_copy( pBuf, pMlmDeauthReq->peerMacAddr, sizeof(tSirMacAddr)); + + pMsg = (tANI_U32*)pSirSmeDeauthRsp; + + limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pMsg ); + + return; + + } + + //pStaDs->mlmStaContext.rxPurgeReq = 1; + pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) + pMlmDeauthReq->reasonCode; + pStaDs->mlmStaContext.cleanupTrigger = pMlmDeauthReq->deauthTrigger; + + pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = pMlmDeauthReq; + + /* Set state to mlm State to eLIM_MLM_WT_DEL_STA_RSP_STATE + * This is to address the issue of race condition between + * disconnect request from the HDD and disassoc from + * inactivity timer. This will make sure that we will not + * process disassoc if deauth is in progress for the station + * and thus mlmStaContext.cleanupTrigger will not be overwritten. + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + + /// Send Deauthentication frame to peer entity + /* If FW_IN_TX_PATH feature is enabled + do not wait for ACK */ + if( IS_FW_IN_TX_PATH_FEATURE_ENABLE ) + { + limSendDeauthMgmtFrame(pMac, pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, FALSE); + + /* Send Deauth CNF and receive path cleanup */ + limSendDeauthCnf(pMac); + } + else + { + limSendDeauthMgmtFrame(pMac, pMlmDeauthReq->reasonCode, + pMlmDeauthReq->peerMacAddr, + psessionEntry, TRUE); + } + + return; + +end: + vos_mem_copy((tANI_U8 *) &mlmDeauthCnf.peerMacAddr, + (tANI_U8 *) pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger; + mlmDeauthCnf.aid = pMlmDeauthReq->aid; + mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId; + + // Free up buffer allocated + // for mlmDeauthReq + vos_mem_free(pMlmDeauthReq); + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_CNF, + (tANI_U32 *) &mlmDeauthCnf); + +} + + +void limProcessDeauthAckTimeout(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("")); + limSendDeauthCnf(pMac); +} + +/** + * limProcessMlmDeauthReq() + * + *FUNCTION: + * This function is called to process MLM_DEAUTH_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ +// tANI_U16 aid; +// tSirMacAddr currentBssId; +// tpDphHashNode pStaDs; +// struct tLimPreAuthNode *pAuthNode; + tLimMlmDeauthReq *pMlmDeauthReq; +// tLimMlmDeauthCnf mlmDeauthCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmDeauthReq = (tLimMlmDeauthReq *) pMsgBuf; + + limLog(pMac, LOG1,FL("Process Deauth Req on sessionID %d " + "from: "MAC_ADDRESS_STR), pMlmDeauthReq->sessionId, + MAC_ADDR_ARRAY(pMlmDeauthReq->peerMacAddr)); + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthReq->sessionId))== NULL) + { + + limLog(pMac, LOGE, FL("session does not exist for given sessionId %d"), + pMlmDeauthReq->sessionId); + return; + } + limProcessMlmDeauthReqNtf( pMac, eHAL_STATUS_SUCCESS, (tANI_U32*) pMsgBuf ); + +} /*** limProcessMlmDeauthReq() ***/ + + + +/** + * @function : limProcessMlmSetKeysReq() + * + * @brief : This function is called to process MLM_SETKEYS_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmSetKeysReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ +tANI_U16 aid; +tANI_U16 staIdx = 0; +tANI_U32 defaultKeyId = 0; +tSirMacAddr currentBssId; +tpDphHashNode pStaDs; +tLimMlmSetKeysReq *pMlmSetKeysReq; +tLimMlmSetKeysCnf mlmSetKeysCnf; +tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + + pMlmSetKeysReq = (tLimMlmSetKeysReq *) pMsgBuf; + // Hold onto the SetKeys request parameters + pMac->lim.gpLimMlmSetKeysReq = (void *) pMlmSetKeysReq; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmSetKeysReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + return; + } + + limLog( pMac, LOGW, + FL( "Received MLM_SETKEYS_REQ with parameters:" + "AID [%d], ED Type [%d], # Keys [%d] & Peer MAC Addr - "), + pMlmSetKeysReq->aid, + pMlmSetKeysReq->edType, + pMlmSetKeysReq->numKeys ); + limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW ); + + #if 0 + if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID, currentBssId, &cfg )) { + limLog( pMac, LOGP, FL("Could not retrieve BSSID")); + return; + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch( psessionEntry->limSystemRole ) { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + //In case of TDLS, peerMac address need not be BssId. Skip this check + //if TDLS is enabled. +#ifndef FEATURE_WLAN_TDLS + if((!limIsAddrBC( pMlmSetKeysReq->peerMacAddr ) ) && + (!vos_mem_compare(pMlmSetKeysReq->peerMacAddr, + currentBssId, sizeof(tSirMacAddr))) ){ + limLog( pMac, LOGW, FL("Received MLM_SETKEYS_REQ with invalid BSSID")); + limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_SETKEYS_CNF with error code + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } +#endif + // Fall thru' & 'Plumb' keys below + break; + case eLIM_STA_IN_IBSS_ROLE: + default: // others + // Fall thru... + break; + } + + /** + * Use the "unicast" parameter to determine if the "Group Keys" + * are being set. + * pMlmSetKeysReq->key.unicast = 0 -> Multicast/broadcast + * pMlmSetKeysReq->key.unicast - 1 -> Unicast keys are being set + */ + if( limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) { + limLog( pMac, LOG1, FL("Trying to set Group Keys...%d "), pMlmSetKeysReq->sessionId); + /** When trying to set Group Keys for any + * security mode other than WEP, use the + * STA Index corresponding to the AP... + */ + switch( pMlmSetKeysReq->edType ) { + case eSIR_ED_CCMP: + +#ifdef WLAN_FEATURE_11W + case eSIR_ED_AES_128_CMAC: +#endif + staIdx = psessionEntry->staId; + break; + + default: + break; + } + }else { + limLog( pMac, LOG1, FL("Trying to set Unicast Keys...")); + /** + * Check if there exists a context for the + * peer entity for which keys need to be set. + */ + + + pStaDs = dphLookupHashEntry( pMac, pMlmSetKeysReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable); + + if ((pStaDs == NULL) || + ((pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) && (psessionEntry->limSystemRole != eLIM_AP_ROLE))) { + /** + * Received LIM_MLM_SETKEYS_REQ for STA + * that does not have context or in some + * transit state. Log error. + */ + limLog( pMac, LOG1, + FL("Received MLM_SETKEYS_REQ for STA that either has no context or in some transit state, Addr = ")); + limPrintMacAddr( pMac, pMlmSetKeysReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_SETKEYS_CNF + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } else + staIdx = pStaDs->staIndex; + } + + if ((pMlmSetKeysReq->numKeys == 0) && (pMlmSetKeysReq->edType != eSIR_ED_NONE)) { + // + // Broadcast/Multicast Keys (for WEP!!) are NOT sent + // via this interface!! + // + // This indicates to HAL that the WEP Keys need to be + // extracted from the CFG and applied to hardware + defaultKeyId = 0xff; + }else if(pMlmSetKeysReq->key[0].keyId && + ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) || + (pMlmSetKeysReq->edType == eSIR_ED_WEP104))){ + /* If the Key Id is non zero and encryption mode is WEP, + * the key index is coming from the upper layers so that key only + * need to be used as the default tx key, This is being used only + * in case of WEP mode in HAL */ + defaultKeyId = pMlmSetKeysReq->key[0].keyId; + }else + defaultKeyId = 0; + + limLog( pMac, LOG1, + FL( "Trying to set keys for STA Index [%d], using defaultKeyId [%d]" ), + staIdx, + defaultKeyId ); + + if(limIsAddrBC( pMlmSetKeysReq->peerMacAddr )) { + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_SET_BSS_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog( pMac, LOG1, FL("Trying to set Group Keys...%d "), + psessionEntry->peSessionId); + + // Package WDA_SET_BSSKEY_REQ message parameters + limSendSetBssKeyReq(pMac, pMlmSetKeysReq,psessionEntry); + return; + }else { + // Package WDA_SET_STAKEY_REQ / WDA_SET_STA_BCASTKEY_REQ message parameters + limSendSetStaKeyReq(pMac, pMlmSetKeysReq, staIdx, (tANI_U8) defaultKeyId,psessionEntry); + return; + } + +end: + mlmSetKeysCnf.sessionId= pMlmSetKeysReq->sessionId; + limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf ); + +} /*** limProcessMlmSetKeysReq() ***/ + +/** + * limProcessMlmRemoveKeyReq() + * + *FUNCTION: + * This function is called to process MLM_REMOVEKEY_REQ message + * from SME + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the MLM message buffer + * @return None + */ + +static void +limProcessMlmRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ +tANI_U16 aid; +tANI_U16 staIdx = 0; +tSirMacAddr currentBssId; +tpDphHashNode pStaDs; +tLimMlmRemoveKeyReq *pMlmRemoveKeyReq; +tLimMlmRemoveKeyCnf mlmRemoveKeyCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmRemoveKeyReq = (tLimMlmRemoveKeyReq *) pMsgBuf; + + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + vos_mem_free(pMsgBuf); + return; + } + + + if( pMac->lim.gpLimMlmRemoveKeyReq != NULL ) + { + // Free any previous requests. + vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + } + // Hold onto the RemoveKeys request parameters + pMac->lim.gpLimMlmRemoveKeyReq = (void *) pMlmRemoveKeyReq; + + #if 0 + if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, + WNI_CFG_BSSID, + currentBssId, + &cfg )) + limLog( pMac, LOGP, FL("Could not retrieve BSSID")); + #endif //TO-SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + switch( psessionEntry->limSystemRole ) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + if (( limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr ) != true ) && + (!vos_mem_compare(pMlmRemoveKeyReq->peerMacAddr, + currentBssId, + sizeof(tSirMacAddr)))) + { + limLog( pMac, LOGW, + FL("Received MLM_REMOVEKEY_REQ with invalid BSSID")); + limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_REMOVEKEY_CNF with error code + mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + break; + + case eLIM_STA_IN_IBSS_ROLE: + default: // eLIM_AP_ROLE + // Fall thru... + break; + } + + + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + if(limIsAddrBC( pMlmRemoveKeyReq->peerMacAddr )) //Second condition for IBSS or AP role. + { + psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_BSS_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + // Package WDA_REMOVE_BSSKEY_REQ message parameters + limSendRemoveBssKeyReq( pMac,pMlmRemoveKeyReq,psessionEntry); + return; + } + + /** + * Check if there exists a context for the + * peer entity for which keys need to be removed. + */ + pStaDs = dphLookupHashEntry( pMac, pMlmRemoveKeyReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable ); + if ((pStaDs == NULL) || + (pStaDs && + (pStaDs->mlmStaContext.mlmState != + eLIM_MLM_LINK_ESTABLISHED_STATE))) + { + /** + * Received LIM_MLM_REMOVEKEY_REQ for STA + * that does not have context or in some + * transit state. Log error. + */ + limLog( pMac, LOGW, + FL("Received MLM_REMOVEKEYS_REQ for STA that either has no context or in some transit state, Addr = ")); + limPrintMacAddr( pMac, pMlmRemoveKeyReq->peerMacAddr, LOGW ); + + // Prepare and Send LIM_MLM_REMOVEKEY_CNF + mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + mlmRemoveKeyCnf.sessionId = pMlmRemoveKeyReq->sessionId; + + + goto end; + } + else + staIdx = pStaDs->staIndex; + + + + psessionEntry->limMlmState = eLIM_MLM_WT_REMOVE_STA_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + // Package WDA_REMOVE_STAKEY_REQ message parameters + limSendRemoveStaKeyReq( pMac,pMlmRemoveKeyReq,staIdx,psessionEntry); + return; + +end: + limPostSmeRemoveKeyCnf( pMac, + psessionEntry, + pMlmRemoveKeyReq, + &mlmRemoveKeyCnf ); + +} /*** limProcessMlmRemoveKeyReq() ***/ + + +/** + * limProcessMinChannelTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessMinChannelTimeout(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + +#ifdef GEN6_TODO + //if the min Channel is maintained per session, then use the below seesionEntry + //priority - LOW/might not be needed + + //TBD-RAJESH HOW TO GET sessionEntry????? + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimMinChannelTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } +#endif + + /*do not process if we are in finish scan wait state i.e. + scan is aborted or finished*/ + if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE && + pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) + { + /// Min channel timer timed out + pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER); + pMac->lim.probeCounter = 0; + if (pMac->lim.gLimCurrentScanChannelId <= + (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + channelNum = (tANI_U8)limGetCurrentScanChannel(pMac); + } + else + { + // This shouldn't be the case, but when this happens, this timeout should be for the last channelId. + // Get the channelNum as close to correct as possible. + if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber) + { + channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1]; + } + else + { + channelNum = 1; + } + } + + limLog(pMac, LOGW, + FL("Sending End Scan req from MIN_CH_TIMEOUT in state %d ch-%d"), + pMac->lim.gLimMlmState,channelNum); + limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + } + else + { + /** + * MIN channel timer should not have timed out + * in states other than wait_probe_response. + * Log error. + */ + limLog(pMac, LOGW, + FL("received unexpected MIN channel timeout in mlme state %d and hal scan State %d"), + pMac->lim.gLimMlmState,pMac->lim.gLimHalScanState); + limPrintMlmState(pMac, LOGE, pMac->lim.gLimMlmState); + } +} /*** limProcessMinChannelTimeout() ***/ + + + +/** + * limProcessMaxChannelTimeout() + * + *FUNCTION: + * This function is called to process Max Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessMaxChannelTimeout(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + + /*do not process if we are in finish scan wait state i.e. + scan is aborted or finished*/ + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE || + pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) && + pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) + { + limLog(pMac, LOG1, FL("Scanning : Max channel timed out")); + /** + * MAX channel timer timed out + * Continue channel scan. + */ + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_PROBE_REQ_TIMER); + pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff; + pMac->lim.probeCounter = 0; + + if (pMac->lim.gLimCurrentScanChannelId <= + (tANI_U32)(pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1)) + { + channelNum = limGetCurrentScanChannel(pMac); + } + else + { + if(pMac->lim.gpLimMlmScanReq->channelList.channelNumber) + { + channelNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber[pMac->lim.gpLimMlmScanReq->channelList.numChannels - 1]; + } + else + { + channelNum = 1; + } + } + limLog(pMac, LOGW, + FL("Sending End Scan req from MAX_CH_TIMEOUT in state %d on ch-%d"), + pMac->lim.gLimMlmState,channelNum); + limSendHalEndScanReq(pMac, channelNum, eLIM_HAL_END_SCAN_WAIT_STATE); + } + else + { + /** + * MAX channel timer should not have timed out + * in states other than wait_scan. + * Log error. + */ + limLog(pMac, LOGW, + FL("received unexpected MAX channel timeout in mlme state %d and hal scan state %d"), + pMac->lim.gLimMlmState, pMac->lim.gLimHalScanState); + limPrintMlmState(pMac, LOGW, pMac->lim.gLimMlmState); + } +} /*** limProcessMaxChannelTimeout() ***/ + +/** + * limProcessPeriodicProbeReqTimer() + * + *FUNCTION: + * This function is called to process periodic probe request + * to send during scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessPeriodicProbeReqTimer(tpAniSirGlobal pMac) +{ + tANI_U8 channelNum; + tANI_U8 i = 0; + tSirRetStatus status = eSIR_SUCCESS; + TX_TIMER *pPeriodicProbeReqTimer; + pPeriodicProbeReqTimer = &pMac->lim.limTimers.gLimPeriodicProbeReqTimer; + + if(vos_timer_getCurrentState(&pPeriodicProbeReqTimer->vosTimer) + != VOS_TIMER_STATE_STOPPED) + { + limLog(pMac, LOG1, FL("Invalid state of timer")); + return; + } + + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && + (pPeriodicProbeReqTimer->sessionId != 0xff) && (pMac->lim.probeCounter < pMac->lim.maxProbe)) + { + tLimMlmScanReq *pLimMlmScanReq = pMac->lim.gpLimMlmScanReq; + pMac->lim.probeCounter++; + /** + * Periodic channel timer timed out + * to send probe request. + */ + channelNum = limGetCurrentScanChannel(pMac); + /* Prepare and send Probe Request frame for all the SSIDs + * present in the saved MLM + */ + do + { + tSirMacAddr gSelfMacAddr; + + /* Send self MAC as src address if + * MAC spoof is not enabled OR + * spoofMacAddr is all 0 OR + * disableP2PMacSpoof is enabled and scan is P2P scan + * else use the spoofMac as src address + */ + if ((pMac->lim.isSpoofingEnabled != TRUE) || + (TRUE == + vos_is_macaddr_zero((v_MACADDR_t *)&pMac->lim.spoofMacAddr)) || + (pMac->roam.configParam.disableP2PMacSpoofing && + pMac->lim.gpLimMlmScanReq->p2pSearch)) { + vos_mem_copy(gSelfMacAddr, pMac->lim.gSelfMacAddr, VOS_MAC_ADDRESS_LEN); + } else { + vos_mem_copy(gSelfMacAddr, pMac->lim.spoofMacAddr, VOS_MAC_ADDRESS_LEN); + } + limLog( pMac, LOG1, FL("Mac Addr used in Probe Req is :"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(gSelfMacAddr)); + + /* + * PELOGE(limLog(pMac, LOGW, FL("sending ProbeReq number %d," + * " for SSID %s on channel: %d"), + * i, pLimMlmScanReq->ssId[i].ssId, + * channelNum);) + */ + status = limSendProbeReqMgmtFrame( pMac, &pLimMlmScanReq->ssId[i], + pLimMlmScanReq->bssId, channelNum, gSelfMacAddr, + pLimMlmScanReq->dot11mode, pLimMlmScanReq->uIEFieldLen, + (tANI_U8 *)(pLimMlmScanReq) + pLimMlmScanReq->uIEFieldOffset); + + + if ( status != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("send ProbeReq failed for SSID " + "%s on channel: %d"), + pLimMlmScanReq->ssId[i].ssId, + channelNum);) + return; + } + i++; + } while (i < pLimMlmScanReq->numSsid); + + /* Activate timer again */ + if (tx_timer_activate(pPeriodicProbeReqTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not start periodic probe" + " req timer")); + return; + } + } + else + { + /** + * Periodic scan is timeout is happening in + * in states other than wait_scan. + * Log error. + */ + limLog(pMac, LOG1, + FL("received unexpected Periodic scan timeout in state %d"), + pMac->lim.gLimMlmState); + } +} /*** limProcessPeriodicProbeReqTimer() ***/ + +/** + * limProcessJoinFailureTimeout() + * + *FUNCTION: + * This function is called to process JoinFailureTimeout + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessJoinFailureTimeout(tpAniSirGlobal pMac) +{ + tLimMlmJoinCnf mlmJoinCnf; + tSirMacAddr bssid; + tANI_U32 len; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + vos_log_rssi_pkt_type *pRssiLog = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + //fetch the sessionEntry based on the sessionId + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimJoinFailureTimer.sessionId))== NULL) + { + limLog(pMac, LOGE, FL("Session Does not exist for given sessionID")); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + WLAN_VOS_DIAG_LOG_ALLOC(pRssiLog, + vos_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); + if (pRssiLog) + { + pRssiLog->rssi = psessionEntry->rssi; + } + WLAN_VOS_DIAG_LOG_REPORT(pRssiLog); +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + { + len = sizeof(tSirMacAddr); + + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, bssid, &len) != + eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + return; + } + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_JOIN_FAIL_TIMER); + // Change Periodic probe req timer for future activation + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + /** + * Issue MLM join confirm with timeout reason code + */ + PELOGE(limLog(pMac, LOGE, FL(" In state eLIM_MLM_WT_JOIN_BEACON_STATE."));) + PELOGE(limLog(pMac, LOGE, FL(" Join Failure Timeout occurred for session %d with BSS "), + psessionEntry->peSessionId); + limPrintMacAddr(pMac, psessionEntry->bssId, LOGE);) + + mlmJoinCnf.resultCode = eSIR_SME_JOIN_TIMEOUT_RESULT_CODE; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState"));) + /* Update PE session Id */ + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + + + // Freeup buffer allocated to join request + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + limPostSmeMessage(pMac, + LIM_MLM_JOIN_CNF, + (tANI_U32 *) &mlmJoinCnf); + + return; + } + else + { + /** + * Join failure timer should not have timed out + * in states other than wait_join_beacon state. + * Log error. + */ + limLog(pMac, LOGW, + FL("received unexpected JOIN failure timeout in state %d"),psessionEntry->limMlmState); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + } +} /*** limProcessJoinFailureTimeout() ***/ + + +/** + * limProcessPeriodicJoinProbeReqTimer() + * + *FUNCTION: + * This function is called to process periodic probe request + * send during joining process. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void limProcessPeriodicJoinProbeReqTimer(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + tSirMacSSid ssId; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given SessionId : %d"), + pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId); + return; + } + + if((VOS_TRUE == tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer)) && + (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE)) + { + vos_mem_copy(ssId.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + ssId.length = psessionEntry->ssId.length; + + limSendProbeReqMgmtFrame( pMac, &ssId, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, psessionEntry->currentOperChannel/*chanNum*/, + psessionEntry->selfMacAddr, psessionEntry->dot11mode, + psessionEntry->pLimJoinReq->addIEScan.length, psessionEntry->pLimJoinReq->addIEScan.addIEdata); + + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + + // Activate Join Periodic Probe Req timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not activate Periodic Join req failure timer")); + return; + } + } + return; +} /*** limProcessPeriodicJoinProbeReqTimer() ***/ + +/** + * limProcessAuthRetryTimer() + * + *FUNCTION: + * This function is called to process Auth Retry request + * send during joining process. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void limProcessAuthRetryTimer(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + limLog(pMac, LOG1, FL(" ENTER ")); + if ((psessionEntry = + peFindSessionBySessionId(pMac, + pMac->lim.limTimers.gLimPeriodicAuthRetryTimer.sessionId)) == NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given SessionId : %d"), + pMac->lim.limTimers.gLimPeriodicAuthRetryTimer.sessionId); + return; + } + + if ((VOS_TRUE == + tx_timer_running(&pMac->lim.limTimers.gLimAuthFailureTimer)) && + (psessionEntry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) && + (LIM_AUTH_ACK_RCD_SUCCESS != pMac->authAckStatus)) + { + tSirMacAuthFrameBody authFrameBody; + + /* Send the auth retry only in case we have received ack failure + * else just restart the retry timer. + */ + if (LIM_AUTH_ACK_RCD_FAILURE == pMac->authAckStatus) + { + /// Prepare & send Authentication frame + authFrameBody.authAlgoNumber = + (tANI_U8) pMac->lim.gpLimMlmAuthReq->authType; + authFrameBody.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; + authFrameBody.authStatusCode = 0; + limLog(pMac, LOGW, FL("Retry Auth ")); + pMac->authAckStatus = LIM_AUTH_ACK_NOT_RCD; + limSendAuthMgmtFrame(pMac, + &authFrameBody, + pMac->lim.gpLimMlmAuthReq->peerMacAddr, + LIM_NO_WEP_IN_FC, psessionEntry, eSIR_TRUE); + } + + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER); + + // Activate Auth Retry timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer) + != TX_SUCCESS) + { + limLog(pMac, LOGE, + FL("could not activate Auth Retry failure timer")); + return; + } + } + return; +} /*** limProcessAuthRetryTimer() ***/ + + +/** + * limProcessAuthFailureTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessAuthFailureTimeout(tpAniSirGlobal pMac) +{ + //fetch the sessionEntry based on the sessionId + tpPESession psessionEntry; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + vos_log_rssi_pkt_type *pRssiLog = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAuthFailureTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + limLog(pMac, LOGE, FL("received AUTH failure timeout in sessionid %d " + "limMlmstate %d limSmeState %d"), psessionEntry->peSessionId, + psessionEntry->limMlmState, psessionEntry->limSmeState); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + WLAN_VOS_DIAG_LOG_ALLOC(pRssiLog, + vos_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); + if (pRssiLog) + { + pRssiLog->rssi = psessionEntry->rssi; + } + WLAN_VOS_DIAG_LOG_REPORT(pRssiLog); +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + switch (psessionEntry->limMlmState) + { + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + case eLIM_MLM_WT_AUTH_FRAME4_STATE: + /** + * Requesting STA did not receive next auth frame + * before Auth Failure timeout. + * Issue MLM auth confirm with timeout reason code + */ + //Restore default failure timeout + if (VOS_P2P_CLIENT_MODE == psessionEntry->pePersona && psessionEntry->defaultAuthFailureTimeout) + { + ccmCfgSetInt(pMac,WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT , + psessionEntry->defaultAuthFailureTimeout, NULL, eANI_BOOLEAN_FALSE); + } + limRestoreFromAuthState(pMac,eSIR_SME_AUTH_TIMEOUT_RESULT_CODE,eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry); + break; + + default: + /** + * Auth failure timer should not have timed out + * in states other than wt_auth_frame2/4 + * Log error. + */ + PELOGE(limLog(pMac, LOGE, FL("received unexpected AUTH failure timeout in state %d"), psessionEntry->limMlmState);) + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + + break; + } + /* Reinit scan results to remove the unreachable BSS */ + limReInitScanResults(pMac); +} /*** limProcessAuthFailureTimeout() ***/ + + + +/** + * limProcessAuthRspTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessAuthRspTimeout(tpAniSirGlobal pMac, tANI_U32 authIndex) +{ + struct tLimPreAuthNode *pAuthNode; + tpPESession psessionEntry; + tANI_U8 sessionId; + + pAuthNode = limGetPreAuthNodeFromIndex(pMac, &pMac->lim.gLimPreAuthTimerTable, authIndex); + + if (NULL == pAuthNode) + { + limLog(pMac, LOGW, FL("Invalid auth node")); + return; + } + + if ((psessionEntry = peFindSessionByBssid(pMac, pAuthNode->peerMacAddr, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("session does not exist for given BSSID ")); + return; + } + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || + psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (pAuthNode->mlmState != eLIM_MLM_WT_AUTH_FRAME3_STATE) + { + /** + * Authentication response timer timedout + * in unexpected state. Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received AUTH rsp timeout in unexpected state " + "for MAC address: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAuthNode->peerMacAddr));) + } + else + { + // Authentication response timer + // timedout for an STA. + pAuthNode->mlmState = eLIM_MLM_AUTH_RSP_TIMEOUT_STATE; + pAuthNode->fTimerStarted = 0; + limLog(pMac, LOG1, + FL("AUTH rsp timedout for MAC address "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAuthNode->peerMacAddr)); + + // Change timer to reactivate it in future + limDeactivateAndChangePerStaIdTimer(pMac, + eLIM_AUTH_RSP_TIMER, + pAuthNode->authNodeIdx); + + limDeletePreAuthNode(pMac, pAuthNode->peerMacAddr); + } + } +} /*** limProcessAuthRspTimeout() ***/ + + +/** + * limProcessAssocFailureTimeout() + * + *FUNCTION: + * This function is called to process Min Channel Timeout + * during channel scan. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +limProcessAssocFailureTimeout(tpAniSirGlobal pMac, tANI_U32 MsgType) +{ + + tLimMlmAssocCnf mlmAssocCnf; + tpPESession psessionEntry; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + vos_log_rssi_pkt_type *pRssiLog = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + //to fetch the lim/mlm state based on the sessionId, use the below sessionEntry + tANI_U8 sessionId; + + if(MsgType == LIM_ASSOC) + { + sessionId = pMac->lim.limTimers.gLimAssocFailureTimer.sessionId; + } + else + { + sessionId = pMac->lim.limTimers.gLimReassocFailureTimer.sessionId; + } + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT_LIM + WLAN_VOS_DIAG_LOG_ALLOC(pRssiLog, + vos_log_rssi_pkt_type, LOG_WLAN_RSSI_UPDATE_C); + if (pRssiLog) + { + pRssiLog->rssi = psessionEntry->rssi; + } + WLAN_VOS_DIAG_LOG_REPORT(pRssiLog); +#endif //FEATURE_WLAN_DIAG_SUPPORT_LIM + + /** + * Expected Re/Association Response frame + * not received within Re/Association Failure Timeout. + */ + + + + + /* + * CR: vos packet memory is leaked when assoc rsp timeouted/failed. + * notify TL that association is failed so that TL can flush the + * cached frame + */ + WLANTL_AssocFailed (psessionEntry->staId); + + /* Log error */ + limLog(pMac, LOG1, + FL("Re/Association Response not received before timeout ")); + + /* + * Send Deauth to handle the scenareo where association timeout happened + * when device has missed the assoc resp sent by peer. + * By sending deauth try to clear the session created on peer device. + */ + limLog(pMac, LOGE, + FL("Sessionid: %d try sending Send deauth on channel %d to BSSID: " + MAC_ADDRESS_STR ), psessionEntry->peSessionId, + psessionEntry->currentOperChannel, + MAC_ADDR_ARRAY(psessionEntry->bssId)); + + limSendDeauthMgmtFrame(pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + psessionEntry->bssId, + psessionEntry, FALSE); + + if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )|| + ((psessionEntry->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) && + (psessionEntry->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) && + (psessionEntry->limMlmState != eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) + { + /** + * Re/Assoc failure timer should not have timedout on AP + * or in a state other than wt_re/assoc_response. + */ + + // Log error + limLog(pMac, LOGW, + FL("received unexpected REASSOC failure timeout in state %d for role %d"), + psessionEntry->limMlmState, psessionEntry->limSystemRole); + limPrintMlmState(pMac, LOGW, psessionEntry->limMlmState); + } + else + { + + if ((MsgType == LIM_ASSOC) || + ((MsgType == LIM_REASSOC) && (psessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE))) + { + PELOGE(limLog(pMac, LOGE, FL("(Re)Assoc Failure Timeout occurred."));) + + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_ASSOC_FAIL_TIMER); + + // Free up buffer allocated for JoinReq held by + // MLM state machine + if (psessionEntry->pLimMlmJoinReq) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + } + + //To remove the preauth node in case of fail to associate + if (limSearchPreAuthList(pMac, psessionEntry->bssId)) + { + limLog(pMac, LOG1, FL(" delete pre auth node for " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(psessionEntry->bssId)); + limDeletePreAuthNode(pMac, psessionEntry->bssId); + } + + mlmAssocCnf.resultCode = + eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE; + mlmAssocCnf.protStatusCode = + eSIR_MAC_UNSPEC_FAILURE_STATUS; + + /* Update PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + if (MsgType == LIM_ASSOC) + limPostSmeMessage(pMac, LIM_MLM_ASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + else + { + /* Will come here only in case of 11r, ESE, FT when reassoc rsp + is not received and we receive a reassoc - timesout */ + mlmAssocCnf.resultCode = eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE; + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmAssocCnf); + } + } + else + { + /** + * Restore pre-reassoc req state. + * Set BSSID to currently associated AP address. + */ + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limRestorePreReassocState(pMac, + eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry); + } + } + /* Reinit scan results to remove the unreachable BSS */ + limReInitScanResults(pMac); +} /*** limProcessAssocFailureTimeout() ***/ + + + +/** + * limCompleteMlmScan() + * + *FUNCTION: + * This function is called to send MLM_SCAN_CNF message + * to SME state machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param retCode Result code to be sent + * @return None + */ + +void +limCompleteMlmScan(tpAniSirGlobal pMac, tSirResultCodes retCode) +{ + tLimMlmScanCnf mlmScanCnf; + + /// Restore previous MLM state + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + limRestorePreScanState(pMac); + + // Free up pMac->lim.gLimMlmScanReq + if( NULL != pMac->lim.gpLimMlmScanReq ) + { + vos_mem_free(pMac->lim.gpLimMlmScanReq); + pMac->lim.gpLimMlmScanReq = NULL; + } + + mlmScanCnf.resultCode = retCode; + mlmScanCnf.scanResultLength = pMac->lim.gLimMlmScanResultLength; + + limPostSmeMessage(pMac, LIM_MLM_SCAN_CNF, (tANI_U32 *) &mlmScanCnf); + +} /*** limCompleteMlmScan() ***/ + +/** + * \brief Setup an A-MPDU/BA session + * + * \sa limProcessMlmAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMsgBuf The MLME ADDBA Req message buffer + * + * \return none + */ +void limProcessMlmAddBAReq( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ +tSirRetStatus status = eSIR_SUCCESS; +tpLimMlmAddBAReq pMlmAddBAReq; +tpLimMlmAddBACnf pMlmAddBACnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmAddBAReq = (tpLimMlmAddBAReq) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBAReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + vos_mem_free(pMsgBuf); + return; + } + + + // Send ADDBA Req over the air + status = limSendAddBAReq( pMac, pMlmAddBAReq,psessionEntry); + + // + // Respond immediately to LIM, only if MLME has not been + // successfully able to send WDA_ADDBA_REQ to HAL. + // Else, LIM_MLM_ADDBA_CNF will be sent after receiving + // ADDBA Rsp from peer entity + // + if( eSIR_SUCCESS != status ) + { + // Allocate for LIM_MLM_ADDBA_CNF + + pMlmAddBACnf = vos_mem_malloc(sizeof( tLimMlmAddBACnf )); + if ( NULL == pMlmAddBACnf ) + { + limLog( pMac, LOGP, + FL("AllocateMemory failed")); + vos_mem_free(pMsgBuf); + return; + } + else + { + vos_mem_set((void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ), 0); + vos_mem_copy((void *) pMlmAddBACnf->peerMacAddr, + (void *) pMlmAddBAReq->peerMacAddr, + sizeof( tSirMacAddr )); + + pMlmAddBACnf->baDialogToken = pMlmAddBAReq->baDialogToken; + pMlmAddBACnf->baTID = pMlmAddBAReq->baTID; + pMlmAddBACnf->baPolicy = pMlmAddBAReq->baPolicy; + pMlmAddBACnf->baBufferSize = pMlmAddBAReq->baBufferSize; + pMlmAddBACnf->baTimeout = pMlmAddBAReq->baTimeout; + pMlmAddBACnf->sessionId = pMlmAddBAReq->sessionId; + + // Update the result code + pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + + limPostSmeMessage( pMac, + LIM_MLM_ADDBA_CNF, + (tANI_U32 *) pMlmAddBACnf ); + } + + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + } + + // Free the buffer allocated for tLimMlmAddBAReq + vos_mem_free(pMsgBuf); + +} + +/** + * \brief Send an ADDBA Rsp to peer STA in response + * to an ADDBA Req received earlier + * + * \sa limProcessMlmAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMsgBuf The MLME ADDBA Rsp message buffer + * + * \return none + */ +void limProcessMlmAddBARsp( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ +tpLimMlmAddBARsp pMlmAddBARsp; + tANI_U16 aid; + tpDphHashNode pSta; + tpPESession psessionEntry; + + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + pMlmAddBARsp = (tpLimMlmAddBARsp) pMsgBuf; + + if(( psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBARsp->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given session ID"));) + vos_mem_free(pMsgBuf); + return; + } + + + // Send ADDBA Rsp over the air + if( eSIR_SUCCESS != limSendAddBARsp( pMac,pMlmAddBARsp,psessionEntry)) + { + limLog( pMac, LOGE, + FL("Failed to send ADDBA Rsp to peer ")); + limPrintMacAddr( pMac, pMlmAddBARsp->peerMacAddr, LOGE ); + /* Clean the BA context maintained by HAL and TL on failure */ + pSta = dphLookupHashEntry( pMac, pMlmAddBARsp->peerMacAddr, &aid, + &psessionEntry->dph.dphHashTable); + if( NULL != pSta ) + { + limPostMsgDelBAInd( pMac, pSta, pMlmAddBARsp->baTID, eBA_RECIPIENT, + psessionEntry); + } + } + + // Time to post a WDA_DELBA_IND to HAL in order + // to cleanup the HAL and SoftMAC entries + + + // Free the buffer allocated for tLimMlmAddBARsp + vos_mem_free(pMsgBuf); + +} + +/** + * \brief Setup an A-MPDU/BA session + * + * \sa limProcessMlmDelBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMsgBuf The MLME DELBA Req message buffer + * + * \return none + */ +void limProcessMlmDelBAReq( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpLimMlmDelBAReq pMlmDelBAReq; + tpLimMlmDelBACnf pMlmDelBACnf; + tpPESession psessionEntry; + + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + + // TODO - Need to validate MLME state + pMlmDelBAReq = (tpLimMlmDelBAReq) pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDelBAReq->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));) + vos_mem_free(pMsgBuf); + return; + } + + // Send DELBA Ind over the air + if( eSIR_SUCCESS != + (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry))) + status = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + else + { + tANI_U16 aid; + tpDphHashNode pSta; + + // Time to post a WDA_DELBA_IND to HAL in order + // to cleanup the HAL and SoftMAC entries + pSta = dphLookupHashEntry( pMac, pMlmDelBAReq->peerMacAddr, &aid , &psessionEntry->dph.dphHashTable); + if( NULL != pSta ) + { + status = limPostMsgDelBAInd( pMac, + pSta, + pMlmDelBAReq->baTID, + pMlmDelBAReq->baDirection,psessionEntry); + + } + } + + // + // Respond immediately to SME with DELBA CNF using + // LIM_MLM_DELBA_CNF with appropriate status + // + + // Allocate for LIM_MLM_DELBA_CNF + + pMlmDelBACnf = vos_mem_malloc(sizeof( tLimMlmDelBACnf )); + if ( NULL == pMlmDelBACnf ) + { + limLog( pMac, LOGP, FL("AllocateMemory failed")); + vos_mem_free(pMsgBuf); + return; + } + else + { + vos_mem_set((void *) pMlmDelBACnf, sizeof( tLimMlmDelBACnf ), 0); + + vos_mem_copy((void *) pMlmDelBACnf, + (void *) pMlmDelBAReq, + sizeof( tLimMlmDelBAReq )); + + // Update DELBA result code + pMlmDelBACnf->delBAReasonCode = pMlmDelBAReq->delBAReasonCode; + + /* Update PE session Id*/ + pMlmDelBACnf->sessionId = pMlmDelBAReq->sessionId; + + limPostSmeMessage( pMac, + LIM_MLM_DELBA_CNF, + (tANI_U32 *) pMlmDelBACnf ); + } + + // Free the buffer allocated for tLimMlmDelBAReq + vos_mem_free(pMsgBuf); + +} + +/** + * @function : limSMPowerSaveStateInd( ) + * + * @brief : This function is called upon receiving the PMC Indication to update the STA's MimoPs State. + * + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Lim Message structure object with the MimoPSparam in body + * @return None + */ + +tSirRetStatus +limSMPowerSaveStateInd(tpAniSirGlobal pMac, tSirMacHTMIMOPowerSaveState state) +{ +#if 0 + tSirRetStatus retStatus = eSIR_SUCCESS; +#if 0 + tANI_U32 cfgVal1; + tANI_U16 cfgVal2; + tSirMacHTCapabilityInfo *pHTCapabilityInfo; + tpDphHashNode pSta = NULL; + + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + /** Verify the Mode of operation */ + if (pMac->lim.gLimSystemRole != eSYSTEM_STA_ROLE) { + PELOGE(limLog(pMac, LOGE, FL("Got PMC indication when System not in the STA Role"));) + return eSIR_FAILURE; + } + + if ((pMac->lim.gHTMIMOPSState == state) || (state == eSIR_HT_MIMO_PS_NA )) { + PELOGE(limLog(pMac, LOGE, FL("Got Indication when already in the same mode or State passed is NA:%d "), state);) + return eSIR_FAILURE; + } + + if (!pMac->lim.htCapability){ + PELOGW(limLog(pMac, LOGW, FL(" Not in 11n or HT capable mode"));) + return eSIR_FAILURE; + } + + /** Update the CFG about the default MimoPS State */ + if (wlan_cfgGetInt(pMac, WNI_CFG_HT_CAP_INFO, &cfgVal1) != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("could not retrieve HT Cap CFG ")); + return eSIR_FAILURE; + } + + cfgVal2 = (tANI_U16)cfgVal1; + pHTCapabilityInfo = (tSirMacHTCapabilityInfo *) &cfgVal2; + pHTCapabilityInfo->mimoPowerSave = state; + + if(cfgSetInt(pMac, WNI_CFG_HT_CAP_INFO, *(tANI_U16*)pHTCapabilityInfo) != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("could not update HT Cap Info CFG")); + return eSIR_FAILURE; + } + + PELOG2(limLog(pMac, LOG2, FL(" The HT Capability for Mimo Pwr is updated to State: %u "),state);) + if (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) { + PELOG2(limLog(pMac, LOG2,FL(" The STA is not in the Connected/Link Est Sme_State: %d "), pMac->lim.gLimSmeState);) + /** Update in the LIM the MIMO PS state of the SELF */ + pMac->lim.gHTMIMOPSState = state; + return eSIR_SUCCESS; + } + + pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (!pSta->mlmStaContext.htCapability) { + limLog( pMac, LOGE,FL( "limSendSMPowerState: Peer is not HT Capable " )); + return eSIR_FAILURE; + } + + if (isEnteringMimoPS(pMac->lim.gHTMIMOPSState, state)) { + tSirMacAddr macAddr; + /** Obtain the AP's Mac Address */ + vos_mem_copy((tANI_U8 *)macAddr, psessionEntry->bssId, sizeof(tSirMacAddr)); + /** Send Action Frame with the corresponding mode */ + retStatus = limSendSMPowerStateFrame(pMac, macAddr, state); + if (retStatus != eSIR_SUCCESS) { + PELOGE(limLog(pMac, LOGE, "Update SM POWER: Sending Action Frame has failed");) + return retStatus; + } + } + + /** Update MlmState about the SetMimoPS State */ + pMac->lim.gLimPrevMlmState = pMac->lim.gLimMlmState; + pMac->lim.gLimMlmState = eLIM_MLM_WT_SET_MIMOPS_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState)); + + /** Update the HAL and s/w mac about the mode to be set */ + retStatus = limPostSMStateUpdate( pMac,psessionEntry->staId, state); + + PELOG2(limLog(pMac, LOG2, " Updated the New SMPS State");) + /** Update in the LIM the MIMO PS state of the SELF */ + pMac->lim.gHTMIMOPSState = state; +#endif + return retStatus; +#endif +return eSIR_SUCCESS; +} + +#ifdef WLAN_FEATURE_11AC +ePhyChanBondState limGet11ACPhyCBState(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 htSecondaryChannelOffset,tANI_U8 peerCenterChan, tpPESession psessionEntry) +{ + ePhyChanBondState cbState = PHY_SINGLE_CHANNEL_CENTERED; + + if(!psessionEntry->apChanWidth) + { + return htSecondaryChannelOffset; + } + + if ( (htSecondaryChannelOffset + == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) + ) + { + if ((channel + 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + else if ((channel + 6 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + else if ((channel - 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + else + limLog (pMac, LOGP, + FL("Invalid Channel Number = %d Center Chan = %d "), + channel, peerCenterChan); + } + if ( (htSecondaryChannelOffset + == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + ) + { + if ((channel - 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + else if ((channel + 2 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + else if ((channel - 6 ) == peerCenterChan ) + cbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + else + limLog (pMac, LOGP, + FL("Invalid Channel Number = %d Center Chan = %d "), + channel, peerCenterChan); + } + return cbState; +} + +#endif + +void +limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId) +{ +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + tpPESession peSession; + + peSession = peFindSessionBySessionId (pMac, peSessionId); + + if ( NULL == peSession) + { + limLog (pMac, LOGP, FL("Invalid PE session = %d"), peSessionId); + return; + } +#if defined WLAN_FEATURE_VOWIFI +#ifdef WLAN_FEATURE_11AC + if ( peSession->vhtCapability ) + { + limSendSwitchChnlParams( pMac, channel, limGet11ACPhyCBState( pMac,channel,secChannelOffset,peSession->apCenterChan, peSession), maxTxPower, peSessionId); + } + else +#endif + { + limSendSwitchChnlParams( pMac, channel, secChannelOffset, maxTxPower, peSessionId); + } +#else + if (wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("could not read WNI_CFG_LOCAL_POWER_CONSTRAINT from CFG")); + return; + } + // Send WDA_CHNL_SWITCH_IND to HAL +#ifdef WLAN_FEATURE_11AC + if ( peSession->vhtCapability && peSession->vhtCapabilityPresentInBeacon) + { + limSendSwitchChnlParams( pMac, channel, limGet11ACPhyCBState( pMac,channel,secChannelOffset,peSession->apCenterChan, peSession), maxTxPower, peSessionId); + } + else +#endif + { + limSendSwitchChnlParams( pMac, channel, secChannelOffset, (tPowerdBm)localPwrConstraint, peSessionId); + } +#endif + + } diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c new file mode 100644 index 000000000000..feb52accaf55 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c @@ -0,0 +1,5324 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessMlmRspMessages.cc contains the code + * for processing response messages from MLM state machine. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "wniApi.h" +#include "wniCfg.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limTimerUtils.h" +#include "limSendMessages.h" +#include "limAdmitControl.h" +#include "limSendMessages.h" +#include "limIbssPeerMgmt.h" +#include "limSession.h" +#include "limSessionUtils.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif +#include "wlan_qct_wda.h" +#include "vos_utils.h" + +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + +static void limHandleSmeJoinResult(tpAniSirGlobal, tSirResultCodes, tANI_U16,tpPESession); +static void limHandleSmeReaasocResult(tpAniSirGlobal, tSirResultCodes, tANI_U16, tpPESession); +void limProcessMlmScanCnf(tpAniSirGlobal, tANI_U32 *); +#ifdef FEATURE_OEM_DATA_SUPPORT +void limProcessMlmOemDataReqCnf(tpAniSirGlobal, tANI_U32 *); +#endif +void limProcessMlmJoinCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAuthCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmStartCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAuthInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAssocInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAssocCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmReassocCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmReassocInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmSetKeysCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDisassocInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDisassocCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDeauthInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDeauthCnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmPurgeStaInd(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmAddBACnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmDelBACnf(tpAniSirGlobal, tANI_U32 *); +void limProcessMlmRemoveKeyCnf(tpAniSirGlobal pMac, tANI_U32 * pMsgBuf); +static void limHandleDelBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry); +void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *); +static void +limProcessBtampAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry); + +void limSwitchChannelResumeLinkRsp(tpAniSirGlobal pMac, + eHalStatus status, tANI_U32* mlmAddBssRsp); + +/** + * limProcessMlmRspMessages() + * + *FUNCTION: + * This function is called to processes various MLM response (CNF/IND + * messages from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmRspMessages(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + MTRACE(macTrace(pMac, TRACE_CODE_TX_LIM_MSG, 0, msgType)); + switch (msgType) + { + case LIM_MLM_SCAN_CNF: + limProcessMlmScanCnf(pMac, pMsgBuf); + break; + +#ifdef FEATURE_OEM_DATA_SUPPORT + case LIM_MLM_OEM_DATA_CNF: + limProcessMlmOemDataReqCnf(pMac, pMsgBuf); + pMsgBuf = NULL; + break; +#endif + + case LIM_MLM_AUTH_CNF: + limProcessMlmAuthCnf(pMac, pMsgBuf); + break; + case LIM_MLM_AUTH_IND: + limProcessMlmAuthInd(pMac, pMsgBuf); + break; + case LIM_MLM_ASSOC_CNF: + limProcessMlmAssocCnf(pMac, pMsgBuf); + break; + case LIM_MLM_START_CNF: + limProcessMlmStartCnf(pMac, pMsgBuf); + break; + case LIM_MLM_JOIN_CNF: + limProcessMlmJoinCnf(pMac, pMsgBuf); + break; + case LIM_MLM_ASSOC_IND: + limProcessMlmAssocInd(pMac, pMsgBuf); + break; + case LIM_MLM_REASSOC_CNF: + limProcessMlmReassocCnf(pMac, pMsgBuf); + break; + case LIM_MLM_REASSOC_IND: + limProcessMlmReassocInd(pMac, pMsgBuf); + break; + case LIM_MLM_DISASSOC_CNF: + limProcessMlmDisassocCnf(pMac, pMsgBuf); + break; + case LIM_MLM_DISASSOC_IND: + limProcessMlmDisassocInd(pMac, pMsgBuf); + break; + case LIM_MLM_PURGE_STA_IND: + limProcessMlmPurgeStaInd(pMac, pMsgBuf); + break; + case LIM_MLM_DEAUTH_CNF: + limProcessMlmDeauthCnf(pMac, pMsgBuf); + break; + case LIM_MLM_DEAUTH_IND: + limProcessMlmDeauthInd(pMac, pMsgBuf); + break; + case LIM_MLM_SETKEYS_CNF: + limProcessMlmSetKeysCnf(pMac, pMsgBuf); + break; + case LIM_MLM_REMOVEKEY_CNF: + limProcessMlmRemoveKeyCnf(pMac, pMsgBuf); + break; + case LIM_MLM_TSPEC_CNF: + break; + case LIM_MLM_ADDBA_CNF: + limProcessMlmAddBACnf( pMac, pMsgBuf ); + pMsgBuf = NULL; + break; + case LIM_MLM_DELBA_CNF: + limProcessMlmDelBACnf( pMac, pMsgBuf ); + pMsgBuf = NULL; + break; + default: + break; + } // switch (msgType) + return; +} /*** end limProcessMlmRspMessages() ***/ + +/** + * limProcessMlmScanCnf() + * + *FUNCTION: + * This function is called to processes MLM_SCAN_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmScanCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + switch(pMac->lim.gLimSmeState) + { + case eLIM_SME_WT_SCAN_STATE: + //case eLIM_SME_LINK_EST_WT_SCAN_STATE: //TO SUPPORT BT-AMP + //case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: //TO SUPPORT BT-AMP + pMac->lim.gLimSmeState = pMac->lim.gLimPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + pMac->lim.gLimSystemInScanLearnMode = 0; + break; + default: + /** + * Should not have received scan confirm + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_SCAN_CNF in state %d"), + pMac->lim.gLimSmeState);) + return; + } + + /// Process received scan confirm + /// Increment length of cached scan results + pMac->lim.gLimSmeScanResultLength += + ((tLimMlmScanCnf *) pMsgBuf)->scanResultLength; + if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults) + { + tANI_U16 scanRspLen = 0; + /// Need to send response to Host + pMac->lim.gLimRspReqd = false; + if ((((tLimMlmScanCnf *) pMsgBuf)->resultCode == + eSIR_SME_SUCCESS) || + pMac->lim.gLimSmeScanResultLength) + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + } + else + { + scanRspLen = sizeof(tSirSmeScanRsp); + } + if(pMac->lim.gLimReportBackgroundScanResults) + { + pMac->lim.gLimBackgroundScanTerminate = TRUE; + } + if (pMac->lim.gLimSmeScanResultLength == 0) + { + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, pMac->lim.gSmeSessionId, pMac->lim.gTransactionId); + } + else + { + limSendSmeScanRsp(pMac, scanRspLen, + eSIR_SME_SUCCESS,pMac->lim.gSmeSessionId, pMac->lim.gTransactionId); + } + } // if (pMac->lim.gLimRspReqd) + //check to see whether we need to run bgScan timer + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + if (tx_timer_activate( + &pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + /// Could not activate background scan timer. + // Log error + limLog(pMac, LOGP, + FL("could not activate background scan timer")); + pMac->lim.gLimBackgroundScanStarted = FALSE; + } + else + { + pMac->lim.gLimBackgroundScanStarted = TRUE; + } + } +} /*** end limProcessMlmScanCnf() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** + * limProcessMlmOemDataReqCnf() + * + *FUNCTION: + * This function is called to processes LIM_MLM_OEM_DATA_REQ_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ + +void limProcessMlmOemDataReqCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmOemDataRsp* measRsp; + + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + measRsp = (tLimMlmOemDataRsp*)(pMsgBuf); + + //Now send the meas confirm message to the sme + limSendSmeOemDataRsp(pMac, (tANI_U32*)measRsp, resultCode); + + //Dont free the memory here. It will be freed up by the callee + + return; +} +#endif + +/** + * limProcessMlmStartCnf() + * + *FUNCTION: + * This function is called to processes MLM_START_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmStartCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry = NULL; + tLimMlmStartCnf *pLimMlmStartCnf; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pLimMlmStartCnf = (tLimMlmStartCnf*)pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmStartCnf->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Session does Not exist with given sessionId "));) + return; + } + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + + if (psessionEntry->limSmeState != eLIM_SME_WT_START_BSS_STATE) + { + /** + * Should not have received Start confirm from MLM + * in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_START_CNF in state %d"), + psessionEntry->limSmeState);) + return; + } + if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == + eSIR_SME_SUCCESS) + { + + /** + * Update global SME state so that Beacon Generation + * module starts writing Beacon frames into TFP's + * Beacon file register. + */ + psessionEntry->limSmeState = eLIM_SME_NORMAL_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + if(psessionEntry->bssType == eSIR_BTAMP_STA_MODE) + { + limLog(pMac, LOG1, FL("*** Started BSS in BT_AMP STA SIDE***")); + } + else if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + limLog(pMac, LOG1, FL("*** Started BSS in BT_AMP AP SIDE***")); + } + else if(psessionEntry->bssType == eSIR_INFRA_AP_MODE) + { + limLog(pMac, LOG1, FL("*** Started BSS in INFRA AP SIDE***")); + } + else + limLog(pMac, LOG1, FL("*** Started BSS ***")); + } + else + { + /// Start BSS is a failure + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + PELOGE(limLog(pMac, LOGE,FL("Start BSS Failed "));) + } + /// Send response to Host + limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP, + ((tLimMlmStartCnf *) pMsgBuf)->resultCode,psessionEntry, + smesessionId,smetransactionId); + if (((tLimMlmStartCnf *) pMsgBuf)->resultCode == eSIR_SME_SUCCESS) + { + //Configure beacon and send beacons to HAL + limSendBeaconInd(pMac, psessionEntry); + } +} + + /*** end limProcessMlmStartCnf() ***/ + +/** + * limProcessMlmJoinCnf() + * + *FUNCTION: + * This function is called to processes MLM_JOIN_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmJoinCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes resultCode; + tLimMlmJoinCnf *pLimMlmJoinCnf; + tpPESession psessionEntry; + pLimMlmJoinCnf = (tLimMlmJoinCnf*)pMsgBuf; + if( (psessionEntry = peFindSessionBySessionId(pMac,pLimMlmJoinCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("SessionId:%d Session does not exist"), + pLimMlmJoinCnf->sessionId);) + return; + } + + if (psessionEntry->limSmeState!= eLIM_SME_WT_JOIN_STATE) + { + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_JOIN_CNF in state %d"), + psessionEntry->limSmeState);) + return; + } + + resultCode = ((tLimMlmJoinCnf *) pMsgBuf)->resultCode ; + /// Process Join confirm from MLM + if (resultCode == eSIR_SME_SUCCESS) + { + limLog(pMac, LOG1, FL("***SessionId: %d Joined ESS ***"), + pLimMlmJoinCnf->sessionId); + //Setup hardware upfront + //Done: 7-27-2009. JIM_FIX_ME sessionize the following function + if(limStaSendAddBssPreAssoc( pMac, false, psessionEntry) == eSIR_SUCCESS) + return; + else + resultCode = eSIR_SME_REFUSED; + } + { + /// Join failure + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + /// Send Join response to Host + limHandleSmeJoinResult(pMac, resultCode, ((tLimMlmJoinCnf *) pMsgBuf)->protStatusCode, psessionEntry ); + } +} /*** end limProcessMlmJoinCnf() ***/ + +/** + * limProcessMlmAuthCnf() + * + *FUNCTION: + * This function is called to processes MLM_AUTH_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAuthCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 caps; + tANI_U32 val; + tAniAuthType cfgAuthType, authMode; + tLimMlmAuthReq *pMlmAuthReq; + tLimMlmAssocReq *pMlmAssocReq; + tLimMlmAuthCnf *pMlmAuthCnf; + tpPESession psessionEntry; + tANI_U32 teleBcnEn = 0; +// tANI_U8 sessionId; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmAuthCnf = (tLimMlmAuthCnf*)pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAuthCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE, FL("SessionId:%d session does not exist"), + pMlmAuthCnf->sessionId);) + return; + } + + if (((psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_PRE_AUTH_STATE)) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + /** + * Should not have received AUTH confirm + * from MLM in other states or on AP. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("SessionId:%d received unexpected MLM_AUTH_CNF in state %d"), + psessionEntry->peSessionId,psessionEntry->limSmeState);) + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_AUTH_COMP_EVENT, psessionEntry, + pMlmAuthCnf->resultCode, + pMlmAuthCnf->protStatusCode); +#endif + + /// Process AUTH confirm from MLM + if (pMlmAuthCnf->resultCode != eSIR_SME_SUCCESS) + { + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE, + (tANI_U32 *) &cfgAuthType) != eSIR_SUCCESS) + { + /** + * Could not get AuthType value from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthType value")); + } + } + else + cfgAuthType = pMac->lim.gLimPreAuthType; + + if ((cfgAuthType == eSIR_AUTO_SWITCH) && + (pMlmAuthCnf->authType == eSIR_SHARED_KEY) + && ((eSIR_MAC_AUTH_ALGO_NOT_SUPPORTED_STATUS == + pMlmAuthCnf->protStatusCode) || + (pMlmAuthCnf->resultCode == eSIR_SME_AUTH_TIMEOUT_RESULT_CODE))) + { + /** + * When Shared authentication fails with reason code "13" and + * authType set to 'auto switch', Try with Open Authentication + */ + authMode = eSIR_OPEN_SYSTEM; + // Trigger MAC based Authentication + pMlmAuthReq = vos_mem_malloc(sizeof(tLimMlmAuthReq)); + if ( NULL == pMlmAuthReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmAuthReq")); + return; + } + vos_mem_set((tANI_U8 *) pMlmAuthReq, sizeof(tLimMlmAuthReq), 0); + val = sizeof(tSirMacAddr); + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + sirCopyMacAddr(pMlmAuthReq->peerMacAddr,psessionEntry->bssId); + } + else + vos_mem_copy((tANI_U8 *) &pMlmAuthReq->peerMacAddr, + (tANI_U8 *) &pMac->lim.gLimPreAuthPeerAddr, + sizeof(tSirMacAddr)); + pMlmAuthReq->authType = authMode; + /* Update PE session Id*/ + pMlmAuthReq->sessionId = pMlmAuthCnf->sessionId; + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmAuthReq->authFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout value from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + limPostMlmMessage(pMac, + LIM_MLM_AUTH_REQ, + (tANI_U32 *) pMlmAuthReq); + return; + } + else + { + // MAC based authentication failure + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + PELOGE(limLog(pMac, LOGE, FL("Auth Failure occurred."));) + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + /** + * Need to send Join response with + * auth failure to Host. + */ + limHandleSmeJoinResult(pMac, pMlmAuthCnf->resultCode, + pMlmAuthCnf->protStatusCode, psessionEntry); + } + else + { + /** + * Pre-authentication failure. + * Send Pre-auth failure response to host + */ + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limSendSmeAuthRsp( + pMac, pMlmAuthCnf->resultCode, + pMlmAuthCnf->peerMacAddr, pMlmAuthCnf->authType, + pMlmAuthCnf->protStatusCode, psessionEntry, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + } // end if (cfgAuthType == eAUTO_SWITCH) + } // if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != ... + else + { + if (psessionEntry->limSmeState == eLIM_SME_WT_AUTH_STATE) + { + /** + * Successful MAC based authentication + * Trigger Association with BSS + */ + limLog(pMac, LOG1, + FL("SessionId: %d Authenticated with BSS"), + psessionEntry->peSessionId); + pMlmAssocReq = vos_mem_malloc(sizeof(tLimMlmAssocReq)); + if ( NULL == pMlmAssocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmAssocReq")); + return; + } + val = sizeof(tSirMacAddr); + #if 0 + if (cfgGetStr(pMac, WNI_CFG_BSSID, + pMlmAssocReq->peerMacAddr, + &val) != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //SUPPORT BT-AMP + sirCopyMacAddr(pMlmAssocReq->peerMacAddr,psessionEntry->bssId); + if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmAssocReq->assocFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get AssocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AssocFailureTimeout value")); + } + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) + { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + /*Clear spectrum management bit if AP doesn't support it*/ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & LIM_SPECTRUM_MANAGEMENT_BIT_MASK)) + { + /*AP doesn't support spectrum management clear spectrum management bit*/ + caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK); + } + + /* Clear rrm bit if AP doesn't support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo + & LIM_RRM_BIT_MASK)) + { + caps &= (~LIM_RRM_BIT_MASK); + } + + /* Clear short preamble bit if AP does not support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & + (LIM_SHORT_PREAMBLE_BIT_MASK))) + { + caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK); + limLog(pMac, LOG1, FL("Clearing short preamble:no AP support")); + } + + /* Clear immediate block ack bit if AP does not support it */ + if(!(psessionEntry->pLimJoinReq->bssDescription.capabilityInfo & + (LIM_IMMEDIATE_BLOCK_ACK_MASK))) + { + caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK); + limLog(pMac, LOG1, FL("Clearing Immed Blk Ack:no AP support")); + } + + pMlmAssocReq->capabilityInfo = caps; + PELOG3(limLog(pMac, LOG3, + FL("Capabilities to be used in AssocReq=0x%X, privacy bit=%x shortSlotTime %x"), + caps, + ((tpSirMacCapabilityInfo) &pMlmAssocReq->capabilityInfo)->privacy, + ((tpSirMacCapabilityInfo) &pMlmAssocReq->capabilityInfo)->shortSlotTime);) + + /* If telescopic beaconing is enabled, set listen interval to + WNI_CFG_TELE_BCN_MAX_LI */ + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != + eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); + + val = WNI_CFG_LISTEN_INTERVAL_STADEF; + + if(teleBcnEn) + { + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != + eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + + pMlmAssocReq->listenInterval = (tANI_U16)val; + /* Update PE session ID*/ + pMlmAssocReq->sessionId = psessionEntry->peSessionId; + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_ASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limLog(pMac,LOG1,"SessionId:%d PostMLMMessage: LIM_MLM_ASSOC_REQ", + psessionEntry->peSessionId); + limPostMlmMessage(pMac, + LIM_MLM_ASSOC_REQ, + (tANI_U32 *) pMlmAssocReq); + } + else + { + /** + * Successful Pre-authentication. + * Send Pre-auth response to host + */ + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limSendSmeAuthRsp(pMac, pMlmAuthCnf->resultCode, + pMlmAuthCnf->peerMacAddr, pMlmAuthCnf->authType, + pMlmAuthCnf->protStatusCode, psessionEntry, + psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + } // end if (((tLimMlmAuthCnf *) pMsgBuf)->resultCode != ... +} /*** end limProcessMlmAuthCnf() ***/ + +/** + * limProcessMlmAssocCnf() + * + *FUNCTION: + * This function is called to processes MLM_ASSOC_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAssocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry; + tLimMlmAssocCnf *pLimMlmAssocCnf; + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + pLimMlmAssocCnf = (tLimMlmAssocCnf*)pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmAssocCnf->sessionId)) == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("SessionId:%d Session does not exist"), + pLimMlmAssocCnf->sessionId);) + return; + } + if (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE || + psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry ->limSystemRole == eLIM_BT_AMP_AP_ROLE) + { + /** + * Should not have received Assocication confirm + * from MLM in other states OR on AP. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("SessionId:%d Received unexpected MLM_ASSOC_CNF in state %d"), + psessionEntry->peSessionId,psessionEntry->limSmeState);) + return; + } + if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != eSIR_SME_SUCCESS) + { + // Association failure + limLog(pMac, LOG1, + FL("SessionId: %d Association failure resultCode: %d" + "limSmeState: %d"), psessionEntry->peSessionId, + ((tLimMlmAssocCnf *) pMsgBuf)->resultCode, + psessionEntry->limSmeState); + + /* If driver gets deauth when its waiting for ADD_STA_RSP then we need + * to do DEL_STA followed by DEL_BSS. So based on below reason-code here + * we decide whether to do only DEL_BSS or DEL_STA + DEL_BSS + */ + if(((tLimMlmAssocCnf *) pMsgBuf)->resultCode + != eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA) + { + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + } + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, + pMac->lim.gLimSmeState)); + /** + * Need to send Join response with + * Association failure to Host. + */ + limHandleSmeJoinResult(pMac, + ((tLimMlmAssocCnf *) pMsgBuf)->resultCode, + ((tLimMlmAssocCnf *) pMsgBuf)->protStatusCode,psessionEntry); + } // if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != ... + else + { + // Successful Association + limLog(pMac, LOG1, FL("SessionId: %d Associated with BSS"), + psessionEntry->peSessionId); + psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + /** + * Need to send Join response with + * Association success to Host. + */ + limHandleSmeJoinResult(pMac, + ((tLimMlmAssocCnf *) pMsgBuf)->resultCode, + ((tLimMlmAssocCnf *) pMsgBuf)->protStatusCode,psessionEntry); + } // end if (((tLimMlmAssocCnf *) pMsgBuf)->resultCode != .... +} /*** end limProcessMlmAssocCnf() ***/ + +/** + * limProcessMlmReassocCnf() + * + *FUNCTION: + * This function is called to processes MLM_REASSOC_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmReassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry; + tLimMlmReassocCnf *pLimMlmReassocCnf; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pLimMlmReassocCnf = (tLimMlmReassocCnf*) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pLimMlmReassocCnf->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE, FL("session Does not exist for given session Id"));) + return; + } + if ((psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) + { + /** + * Should not have received Reassocication confirm + * from MLM in other states OR on AP. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("Rcv unexpected MLM_REASSOC_CNF in role %d, sme state %d"), + psessionEntry->limSystemRole, psessionEntry->limSmeState);) + return; + } + if (psessionEntry->pLimReAssocReq) { + vos_mem_free(psessionEntry->pLimReAssocReq); + psessionEntry->pLimReAssocReq = NULL; + } + + /* Upon Reassoc success or failure, freeup the cached + * preauth request, to ensure that channel switch is now + * allowed following any change in HT params. + */ + if (pMac->ft.ftPEContext.pFTPreAuthReq) + { + limLog(pMac, LOG1, "%s: Freeing pFTPreAuthReq= %p", __func__, + pMac->ft.ftPEContext.pFTPreAuthReq); + if (pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) + { + vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription); + pMac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(pMac->ft.ftPEContext.pFTPreAuthReq); + pMac->ft.ftPEContext.pFTPreAuthReq = NULL; + } + + PELOGE(limLog(pMac, LOG1, FL("Rcv MLM_REASSOC_CNF with result code %d"), pLimMlmReassocCnf->resultCode);) + if (pLimMlmReassocCnf->resultCode == eSIR_SME_SUCCESS) { + // Successful Reassociation + limLog(pMac, LOG1, FL("*** Reassociated with new BSS ***")); + + psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /** + * Need to send Reassoc response with + * Reassociation success to Host. + */ + limSendSmeJoinReassocRsp( + pMac, eWNI_SME_REASSOC_RSP, + pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry, + psessionEntry->smeSessionId,psessionEntry->transactionId); + }else if (pLimMlmReassocCnf->resultCode == eSIR_SME_REASSOC_REFUSED) { + /** Reassociation failure With the New AP + * but we still have the link with the Older AP + */ + psessionEntry->limSmeState = eLIM_SME_LINK_EST_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /** + * Need to send Reassoc response with + * Association failure to Host. + */ + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, + pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode,psessionEntry, + psessionEntry->smeSessionId,psessionEntry->transactionId); + }else { + /* If driver gets deauth when its waiting for ADD_STA_RSP then we need + * to do DEL_STA followed by DEL_BSS. So based on below reason-code here + * we decide whether to do only DEL_BSS or DEL_STA + DEL_BSS + */ + if(pLimMlmReassocCnf->resultCode + != eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA) + { + // Reassociation failure + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + } + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + /** + * Need to send Reassoc response with + * Association failure to Host. + */ + limHandleSmeReaasocResult(pMac, pLimMlmReassocCnf->resultCode, pLimMlmReassocCnf->protStatusCode, psessionEntry); + } +} /*** end limProcessMlmReassocCnf() ***/ + +/** + * limProcessMlmReassocInd() + * + *FUNCTION: + * This function is called to processes MLM_REASSOC_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmReassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 len; + tSirMsgQ msgQ; + tSirSmeReassocInd *pSirSmeReassocInd; + tpDphHashNode pStaDs=0; + tpPESession psessionEntry; + tANI_U8 sessionId; + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + if((psessionEntry = peFindSessionByBssid(pMac,((tpLimMlmReassocInd)pMsgBuf)->peerMacAddr, &sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + return; + } + /// Inform Host of STA reassociation + len = sizeof(tSirSmeReassocInd); + pSirSmeReassocInd = vos_mem_malloc(len); + if ( NULL == pSirSmeReassocInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_REASSOC_IND")); + return; + + } + sirStoreU16N((tANI_U8 *) &pSirSmeReassocInd->messageType, + eWNI_SME_REASSOC_IND); + if (limReassocIndSerDes(pMac, (tpLimMlmReassocInd) pMsgBuf, + (tANI_U8 *) &(pSirSmeReassocInd->length), + psessionEntry, sizeof(tSirSmeReassocInd)) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE,FL(" Received SME message with invalid rem length")); + vos_mem_free(pSirSmeReassocInd); + return; + } + + // Required for indicating the frames to upper layer + pSirSmeReassocInd->assocReqLength = ((tpLimMlmReassocInd) pMsgBuf)->assocReqLength; + pSirSmeReassocInd->assocReqPtr = ((tpLimMlmReassocInd) pMsgBuf)->assocReqPtr; + pSirSmeReassocInd->beaconPtr = psessionEntry->beacon; + pSirSmeReassocInd->beaconLength = psessionEntry->bcnLen; + + msgQ.type = eWNI_SME_REASSOC_IND; + msgQ.bodyptr = pSirSmeReassocInd; + msgQ.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + pStaDs = dphGetHashEntry(pMac, ((tpLimMlmReassocInd) pMsgBuf)->aid, &psessionEntry->dph.dphHashTable); + if (! pStaDs) + { + limLog( pMac, LOGP, FL("MLM ReAssocInd: Station context no longer valid (aid %d)"), + ((tpLimMlmReassocInd) pMsgBuf)->aid); + vos_mem_free(pSirSmeReassocInd); + return; + } + + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); + limLog(pMac, LOG1, + FL("Create CNF_WAIT_TIMER after received LIM_MLM_REASSOC_IND")); + /* + ** turn on a timer to detect the loss of REASSOC CNF + **/ + limActivateCnfTimer(pMac, + (tANI_U16) ((tpLimMlmReassocInd) pMsgBuf)->aid, psessionEntry); +} /*** end limProcessMlmReassocInd() ***/ + +/** + * limProcessMlmAuthInd() + * + *FUNCTION: + * This function is called to processes MLM_AUTH_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAuthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msgQ; + tSirSmeAuthInd *pSirSmeAuthInd; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pSirSmeAuthInd = vos_mem_malloc(sizeof(tSirSmeAuthInd)); + if ( NULL == pSirSmeAuthInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_AUTH_IND")); + return; + } + limCopyU16((tANI_U8 *) &pSirSmeAuthInd->messageType, eWNI_SME_AUTH_IND); + if (limAuthIndSerDes(pMac, (tpLimMlmAuthInd) pMsgBuf, + (tANI_U8 *) &(pSirSmeAuthInd->length), + sizeof(tSirSmeAuthInd)) != eSIR_SUCCESS) + { + limLog(pMac, LOGE,FL(" Received SME message with invalid rem length")); + vos_mem_free(pSirSmeAuthInd); + return; + } + msgQ.type = eWNI_SME_AUTH_IND; + msgQ.bodyptr = pSirSmeAuthInd; + msgQ.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_AUTH_IND_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); +} /*** end limProcessMlmAuthInd() ***/ + + + + +void +limFillAssocIndParams(tpAniSirGlobal pMac, tpLimMlmAssocInd pAssocInd, + tSirSmeAssocInd *pSirSmeAssocInd, + tpPESession psessionEntry) +{ + pSirSmeAssocInd->length = sizeof(tSirSmeAssocInd); + pSirSmeAssocInd->sessionId = psessionEntry->smeSessionId; + + // Required for indicating the frames to upper layer + pSirSmeAssocInd->assocReqLength = pAssocInd->assocReqLength; + pSirSmeAssocInd->assocReqPtr = pAssocInd->assocReqPtr; + + pSirSmeAssocInd->beaconPtr = psessionEntry->beacon; + pSirSmeAssocInd->beaconLength = psessionEntry->bcnLen; + + // Fill in peerMacAddr + vos_mem_copy(pSirSmeAssocInd->peerMacAddr, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + + // Fill in aid + pSirSmeAssocInd->aid = pAssocInd->aid; + // Fill in bssId + vos_mem_copy(pSirSmeAssocInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + // Fill in staId + //pSirSmeAssocInd->staId = psessionEntry->staId; + // Fill in authType + pSirSmeAssocInd->authType = pAssocInd->authType; + // Fill in ssId + vos_mem_copy((tANI_U8*)&pSirSmeAssocInd->ssId, + (tANI_U8 *) &(pAssocInd->ssId), pAssocInd->ssId.length + 1); + pSirSmeAssocInd->rsnIE.length = pAssocInd->rsnIE.length; + vos_mem_copy((tANI_U8*) &pSirSmeAssocInd->rsnIE.rsnIEdata, + (tANI_U8 *) &(pAssocInd->rsnIE.rsnIEdata), + pAssocInd->rsnIE.length); + + pSirSmeAssocInd->addIE.length = pAssocInd->addIE.length; + vos_mem_copy((tANI_U8*) &pSirSmeAssocInd->addIE.addIEdata, + (tANI_U8 *) &(pAssocInd->addIE.addIEdata), + pAssocInd->addIE.length); + + // Copy the new TITAN capabilities + pSirSmeAssocInd->spectrumMgtIndicator = pAssocInd->spectrumMgtIndicator; + if (pAssocInd->spectrumMgtIndicator == eSIR_TRUE) + { + pSirSmeAssocInd->powerCap.minTxPower = pAssocInd->powerCap.minTxPower; + pSirSmeAssocInd->powerCap.maxTxPower = pAssocInd->powerCap.maxTxPower; + pSirSmeAssocInd->supportedChannels.numChnl = pAssocInd->supportedChannels.numChnl; + vos_mem_copy((tANI_U8*) &pSirSmeAssocInd->supportedChannels.channelList, + (tANI_U8 *) &(pAssocInd->supportedChannels.channelList), + pAssocInd->supportedChannels.numChnl); + } + // Fill in WmmInfo + pSirSmeAssocInd->wmmEnabledSta = pAssocInd->WmmStaInfoPresent; +#ifdef WLAN_FEATURE_AP_HT40_24G + pSirSmeAssocInd->HT40MHzIntoEnabledSta = pAssocInd->HT40MHzIntoPresent; + limLog(pMac, LOGW, FL("HT40MHzIntoPresent: %d"), + pSirSmeAssocInd->HT40MHzIntoEnabledSta); +#endif + // Fill in rate flags + pSirSmeAssocInd->rate_flags = pAssocInd->rate_flags; +} /*** end limAssocIndSerDes() ***/ + + + +/** + * limProcessMlmAssocInd() + * + *FUNCTION: + * This function is called to processes MLM_ASSOC_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmAssocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 len; + tSirMsgQ msgQ; + tSirSmeAssocInd *pSirSmeAssocInd; + tpDphHashNode pStaDs=0; + tpPESession psessionEntry; + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + if((psessionEntry = peFindSessionBySessionId(pMac,((tpLimMlmAssocInd) pMsgBuf)->sessionId))== NULL) + { + limLog( pMac, LOGE, FL( "Session Does not exist for given sessionId" )); + return; + } + /// Inform Host of STA association + len = sizeof(tSirSmeAssocInd); + pSirSmeAssocInd = vos_mem_malloc(len); + if ( NULL == pSirSmeAssocInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_ASSOC_IND")); + return; + } + + pSirSmeAssocInd->messageType = eWNI_SME_ASSOC_IND; + limFillAssocIndParams(pMac, (tpLimMlmAssocInd) pMsgBuf, pSirSmeAssocInd, psessionEntry); + msgQ.type = eWNI_SME_ASSOC_IND; + msgQ.bodyptr = pSirSmeAssocInd; + msgQ.bodyval = 0; + pStaDs = dphGetHashEntry(pMac, + ((tpLimMlmAssocInd) pMsgBuf)->aid, &psessionEntry->dph.dphHashTable); + if (! pStaDs) + { // good time to panic... + limLog(pMac, LOGE, FL("MLM AssocInd: Station context no longer valid (aid %d)"), + ((tpLimMlmAssocInd) pMsgBuf)->aid); + vos_mem_free(pSirSmeAssocInd); + + return; + } + pSirSmeAssocInd->staId = pStaDs->staIndex; + pSirSmeAssocInd->reassocReq = pStaDs->mlmStaContext.subType; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, psessionEntry->peSessionId, + msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ASSOC_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); + + limLog(pMac, LOG1, + FL("Create CNF_WAIT_TIMER after received LIM_MLM_ASSOC_IND")); + /* + ** turn on a timer to detect the loss of ASSOC CNF + **/ + limActivateCnfTimer(pMac, (tANI_U16) ((tpLimMlmAssocInd) pMsgBuf)->aid, psessionEntry); + +// Enable this Compile flag to test the BT-AMP -AP assoc sequence +#ifdef TEST_BTAMP_AP +//tANI_U32 *pMsgBuf; +{ + tpSirSmeAssocCnf pSmeAssoccnf; + pSmeAssoccnf = vos_mem_malloc(sizeof(tSirSmeAssocCnf)); + if ( NULL == pSmeAssoccnf ) + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for pSmeAssoccnf "));) + pSmeAssoccnf->messageType = eWNI_SME_ASSOC_CNF; + pSmeAssoccnf->length = sizeof(tSirSmeAssocCnf); + vos_mem_copy(pSmeAssoccnf->peerMacAddr, + ((tpLimMlmAssocInd)pMsgBuf)->peerMacAddr, 6); + pSmeAssoccnf->statusCode = eSIR_SME_SUCCESS; + pSmeAssoccnf->aid = ((tpLimMlmAssocInd)pMsgBuf)->aid; + vos_mem_copy(pSmeAssoccnf->alternateBssId, + pSmeAssoccnf->peerMacAddr, sizeof(tSirMacAddr)); + pSmeAssoccnf->alternateChannelId = 6; + vos_mem_copy(pSmeAssoccnf->bssId, psessionEntry->selfMacAddr, 6); + pMsgBuf = (tANI_U32)pSmeAssoccnf; + __limProcessSmeAssocCnfNew(pMac, eWNI_SME_ASSOC_CNF, pMsgBuf); + vos_mem_free(pSmeAssoccnf); +} +#endif + + +} /*** end limProcessMlmAssocInd() ***/ + + + + +/** + * limProcessMlmDisassocInd() + * + *FUNCTION: + * This function is called to processes MLM_DISASSOC_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDisassocInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDisassocInd *pMlmDisassocInd; + tpPESession psessionEntry; + pMlmDisassocInd = (tLimMlmDisassocInd *) pMsgBuf; + if( (psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocInd->sessionId) )== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_IN_IBSS_ROLE: + break; + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + psessionEntry->limSmeState = eLIM_SME_WT_DISASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + break; + default: // eLIM_AP_ROLE //eLIM_BT_AMP_AP_ROLE + limLog(pMac, LOG1, + FL("*** Peer staId = %d Disassociated ***"), + pMlmDisassocInd->aid); + // Send SME_DISASOC_IND after Polaris cleanup + // (after receiving LIM_MLM_PURGE_STA_IND) + break; + } // end switch (psessionEntry->limSystemRole) +} /*** end limProcessMlmDisassocInd() ***/ + +/** + * limProcessMlmDisassocCnf() + * + *FUNCTION: + * This function is called to processes MLM_DISASSOC_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes resultCode; + tLimMlmDisassocCnf *pMlmDisassocCnf; + tpPESession psessionEntry; + pMlmDisassocCnf = (tLimMlmDisassocCnf *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDisassocCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session Does not exist for given session Id"));) + return; + } + resultCode = (tSirResultCodes) + (pMlmDisassocCnf->disassocTrigger == + eLIM_LINK_MONITORING_DISASSOC) ? + eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE : + pMlmDisassocCnf->resultCode; + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + // Disassociate Confirm from MLM + if ( (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) ) + { + /** + * Should not have received + * Disassocate confirm + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_DISASSOC_CNF in state %d"),psessionEntry->limSmeState);) + return; + } + if (pMac->lim.gLimRspReqd) + pMac->lim.gLimRspReqd = false; + if (pMlmDisassocCnf->disassocTrigger == + eLIM_PROMISCUOUS_MODE_DISASSOC) + { + if (pMlmDisassocCnf->resultCode != eSIR_SME_SUCCESS) + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + else + psessionEntry->limSmeState = eLIM_SME_OFFLINE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + // Send Promiscuous mode response to host + limSendSmePromiscuousModeRsp(pMac); + } + else + { + if (pMlmDisassocCnf->resultCode != eSIR_SME_SUCCESS) + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + else + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limSendSmeDisassocNtf(pMac, pMlmDisassocCnf->peerMacAddr, + resultCode, + pMlmDisassocCnf->disassocTrigger, + pMlmDisassocCnf->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + } + } + else if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + limSendSmeDisassocNtf(pMac, pMlmDisassocCnf->peerMacAddr, + resultCode, + pMlmDisassocCnf->disassocTrigger, + pMlmDisassocCnf->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + } +} /*** end limProcessMlmDisassocCnf() ***/ + +/** + * limProcessMlmDeauthInd() + * + *FUNCTION: + * This function is called to processes MLM_DEAUTH_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDeauthInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tLimMlmDeauthInd *pMlmDeauthInd; + tpPESession psessionEntry; + tANI_U8 sessionId; + pMlmDeauthInd = (tLimMlmDeauthInd *) pMsgBuf; + if((psessionEntry = peFindSessionByBssid(pMac,pMlmDeauthInd->peerMacAddr,&sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for Addr:" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMlmDeauthInd->peerMacAddr));) + return; + } + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_IN_IBSS_ROLE: + break; + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + default: // eLIM_AP_ROLE + { + limLog(pMac, LOG1, + FL("*** Received Deauthentication from staId=%d ***"), + pMlmDeauthInd->aid); + } + // Send SME_DEAUTH_IND after Polaris cleanup + // (after receiving LIM_MLM_PURGE_STA_IND) + break; + } // end switch (psessionEntry->limSystemRole) +} /*** end limProcessMlmDeauthInd() ***/ + +/** + * limProcessMlmDeauthCnf() + * + *FUNCTION: + * This function is called to processes MLM_DEAUTH_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmDeauthCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 aid; + tSirResultCodes resultCode; + tLimMlmDeauthCnf *pMlmDeauthCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmDeauthCnf = (tLimMlmDeauthCnf *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmDeauthCnf->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given session Id "));) + return; + } + + resultCode = (tSirResultCodes) + (pMlmDeauthCnf->deauthTrigger == + eLIM_LINK_MONITORING_DEAUTH) ? + eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE : + pMlmDeauthCnf->resultCode; + aid = (psessionEntry->limSystemRole == eLIM_AP_ROLE) ? + pMlmDeauthCnf->aid : 1; + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + // Deauth Confirm from MLM + if ((psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + /** + * Should not have received Deauth confirm + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_DEAUTH_CNF in state %d"), + psessionEntry->limSmeState);) + return; + } + if (pMlmDeauthCnf->resultCode == eSIR_SME_SUCCESS) + { + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + limLog(pMac, LOG1, + FL("*** Deauthenticated with BSS ***")); + } + else + psessionEntry->limSmeState = psessionEntry->limPrevSmeState; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + if (pMac->lim.gLimRspReqd) + pMac->lim.gLimRspReqd = false; + } + // On STA or on BASIC AP, send SME_DEAUTH_RSP to host + limSendSmeDeauthNtf(pMac, pMlmDeauthCnf->peerMacAddr, + resultCode, + pMlmDeauthCnf->deauthTrigger, + aid,psessionEntry->smeSessionId,psessionEntry->transactionId); +} /*** end limProcessMlmDeauthCnf() ***/ + +/** + * limProcessMlmPurgeStaInd() + * + *FUNCTION: + * This function is called to processes MLM_PURGE_STA_IND + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmPurgeStaInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes resultCode; + tpLimMlmPurgeStaInd pMlmPurgeStaInd; + tpPESession psessionEntry; + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmPurgeStaInd = (tpLimMlmPurgeStaInd) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmPurgeStaInd->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));) + return; + } + // Purge STA indication from MLM + resultCode = (tSirResultCodes) pMlmPurgeStaInd->reasonCode; + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_IN_IBSS_ROLE: + break; + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + default: // eLIM_AP_ROLE + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) && + (psessionEntry->limSmeState != + eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + /** + * Should not have received + * Purge STA indication + * from MLM in other states. + * Log error + */ + PELOGE(limLog(pMac, LOGE, + FL("received unexpected MLM_PURGE_STA_IND in state %d"), + psessionEntry->limSmeState);) + break; + } + PELOG1(limLog(pMac, LOG1, + FL("*** Polaris cleanup completed for staId=%d ***"), + pMlmPurgeStaInd->aid);) + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + } + if (pMlmPurgeStaInd->purgeTrigger == eLIM_PEER_ENTITY_DEAUTH) + { + limSendSmeDeauthNtf(pMac, + pMlmPurgeStaInd->peerMacAddr, + resultCode, + pMlmPurgeStaInd->purgeTrigger, + pMlmPurgeStaInd->aid,psessionEntry->smeSessionId,psessionEntry->transactionId); + } + else + limSendSmeDisassocNtf(pMac, + pMlmPurgeStaInd->peerMacAddr, + resultCode, + pMlmPurgeStaInd->purgeTrigger, + pMlmPurgeStaInd->aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + } // end switch (psessionEntry->limSystemRole) +} /*** end limProcessMlmPurgeStaInd() ***/ + +/** + * limProcessMlmSetKeysCnf() + * + *FUNCTION: + * This function is called to processes MLM_SETKEYS_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmSetKeysCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + // Prepare and send SME_SETCONTEXT_RSP message + tLimMlmSetKeysCnf *pMlmSetKeysCnf; + tpPESession psessionEntry; + tANI_U16 aid; + tpDphHashNode pStaDs; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmSetKeysCnf = (tLimMlmSetKeysCnf *) pMsgBuf; + if ((psessionEntry = peFindSessionBySessionId(pMac, pMlmSetKeysCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId "));) + return; + } + psessionEntry->isKeyInstalled = 0; + limLog( pMac, LOG1, + FL("Received MLM_SETKEYS_CNF with resultCode = %d"), + pMlmSetKeysCnf->resultCode ); + /* if the status is success keys are installed in the + * Firmware so we can set the protection bit + */ + if (eSIR_SME_SUCCESS == pMlmSetKeysCnf->resultCode) { + psessionEntry->isKeyInstalled = 1; + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) { + pStaDs = dphLookupHashEntry(pMac, pMlmSetKeysCnf->peerMacAddr, &aid, + &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + pStaDs->isKeyInstalled = 1; + } + } + limSendSmeSetContextRsp(pMac, + pMlmSetKeysCnf->peerMacAddr, + 1, + (tSirResultCodes) pMlmSetKeysCnf->resultCode,psessionEntry,psessionEntry->smeSessionId, + psessionEntry->transactionId); +} /*** end limProcessMlmSetKeysCnf() ***/ +/** + * limProcessMlmRemoveKeyCnf() + * + *FUNCTION: + * This function is called to processes MLM_REMOVEKEY_CNF + * message from MLM State machine. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +void +limProcessMlmRemoveKeyCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + // Prepare and send SME_REMOVECONTEXT_RSP message + tLimMlmRemoveKeyCnf *pMlmRemoveKeyCnf; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmRemoveKeyCnf = (tLimMlmRemoveKeyCnf *) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmRemoveKeyCnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session Does not exist for given session Id"));) + return; + } + limLog( pMac, LOG1, + FL("Received MLM_REMOVEKEYS_CNF with resultCode = %d"), + pMlmRemoveKeyCnf->resultCode ); + limSendSmeRemoveKeyRsp(pMac, + pMlmRemoveKeyCnf->peerMacAddr, + (tSirResultCodes) pMlmRemoveKeyCnf->resultCode,psessionEntry, + psessionEntry->smeSessionId,psessionEntry->transactionId); +} /*** end limProcessMlmRemoveKeyCnf() ***/ + + +/** + * limHandleSmeJoinResult() + * + *FUNCTION: + * This function is called to process join/auth/assoc failures + * upon receiving MLM_JOIN/AUTH/ASSOC_CNF with a failure code or + * MLM_ASSOC_CNF with a success code in case of STA role and + * MLM_JOIN_CNF with success in case of STA in IBSS role. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param resultCode Failure code to be sent + * + * + * @return None + */ +static void +limHandleSmeJoinResult(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode, tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + /* Newly Added on oct 11 th*/ + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("psessionEntry is NULL "));) + return; + } + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + /* When associations is failed , delete the session created and pass NULL to limsendsmeJoinReassocRsp() */ + if(resultCode != eSIR_SME_SUCCESS) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_JOIN_FAILURE; + pStaDs->mlmStaContext.resultCode = resultCode; + pStaDs->mlmStaContext.protStatusCode = protStatusCode; + //Done: 7-27-2009. JIM_FIX_ME: at the end of limCleanupRxPath, make sure PE is sending eWNI_SME_JOIN_RSP to SME + limCleanupRxPath(pMac, pStaDs, psessionEntry); + /* Cleanup if add bss failed */ + if(psessionEntry->addBssfailed) + { + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, + &psessionEntry->dph.dphHashTable); + goto error; + } + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + return; + } + } + +error: + vos_mem_free(psessionEntry->pLimJoinReq); + psessionEntry->pLimJoinReq = NULL; + //Delete teh session if JOIN failure occurred. + if(resultCode != eSIR_SME_SUCCESS) + { + if(NULL != psessionEntry) + { + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState."));) + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + } + limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, resultCode, protStatusCode,psessionEntry, + smesessionId, smetransactionId); +} /*** end limHandleSmeJoinResult() ***/ + +/** + * limHandleSmeReaasocResult() + * + *FUNCTION: + * This function is called to process reassoc failures + * upon receiving REASSOC_CNF with a failure code or + * MLM_REASSOC_CNF with a success code in case of STA role + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param resultCode Failure code to be sent + * + * + * @return None + */ +static void +limHandleSmeReaasocResult(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode, tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + if(psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("psessionEntry is NULL "));) + return; + } + smesessionId = psessionEntry->smeSessionId; + smetransactionId = psessionEntry->transactionId; + /* When associations is failed , delete the session created and pass NULL to limsendsmeJoinReassocRsp() */ + if(resultCode != eSIR_SME_SUCCESS) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + pStaDs->mlmStaContext.disassocReason = eSIR_MAC_UNSPEC_FAILURE_REASON; + pStaDs->mlmStaContext.cleanupTrigger = eLIM_JOIN_FAILURE; + pStaDs->mlmStaContext.resultCode = resultCode; + pStaDs->mlmStaContext.protStatusCode = protStatusCode; + limCleanupRxPath(pMac, pStaDs, psessionEntry); + /* Cleanup if add bss failed */ + if(psessionEntry->addBssfailed) + { + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, + &psessionEntry->dph.dphHashTable); + goto error; + } + return; + } + } +error: + //Delete teh session if REASSOC failure occurred. + if(resultCode != eSIR_SME_SUCCESS) + { + if(NULL != psessionEntry) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + } + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, resultCode, protStatusCode,psessionEntry, + smesessionId, smetransactionId); +} /*** end limHandleSmeReassocResult() ***/ + +/** + * limProcessMlmAddStaRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_STA_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Determines the "state" in which this message was received + * > Forwards it to the appropriate callback + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry ) +{ + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + { + limProcessBtAmpApMlmAddStaRsp(pMac, limMsgQ,psessionEntry); + return; + } +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_process_sta_mlm_add_sta_rsp_mbb(pMac, limMsgQ, psessionEntry); + return; + } +#endif + limProcessStaMlmAddStaRsp(pMac, limMsgQ,psessionEntry); +} +void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry) +{ + tLimMlmAssocCnf mlmAssocCnf; + tpDphHashNode pStaDs; + tANI_U32 mesgType = LIM_MLM_ASSOC_CNF; + tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr; + + if(NULL == pAddStaParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + return; + } + + if (true == psessionEntry->fDeauthReceived) + { + PELOGE(limLog(pMac, LOGE, + FL("Received Deauth frame in ADD_STA_RESP state"));) + + if (eHAL_STATUS_SUCCESS == pAddStaParams->status) + { + PELOGE(limLog(pMac, LOGE, + FL("ADD_STA success, send update result code with" + "eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA staIdx: %d" + "limMlmState: %d"), pAddStaParams->staIdx, + psessionEntry->limMlmState);) + if(psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + mesgType = LIM_MLM_REASSOC_CNF; + //We are sending result code eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA + //which will trigger proper cleanup (DEL_STA/DEL_BSS both required) in + //either assoc cnf or reassoc cnf handler. + mlmAssocCnf.resultCode = + (tSirResultCodes) eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA; + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + psessionEntry->staId = pAddStaParams->staIdx; + goto end; + } + } + + if ( eHAL_STATUS_SUCCESS == pAddStaParams->status ) + { + if ( eLIM_MLM_WT_ADD_STA_RSP_STATE != psessionEntry->limMlmState) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, + FL( "Received unexpected WDA_ADD_STA_RSP in state %d" ), + psessionEntry->limMlmState); + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + goto end; + } + + if(psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + mesgType = LIM_MLM_REASSOC_CNF; + // + // Update the DPH Hash Entry for this STA + // with proper state info + // + pStaDs = dphGetHashEntry( pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if( NULL != pStaDs) + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + else + limLog( pMac, LOGW, + FL( "Unable to get the DPH Hash Entry for AID - %d" ), + DPH_STA_HASH_INDEX_PEER); + psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + /* + * Storing the self StaIndex(Generated by HAL) in session context, + * instead of storing it in DPH Hash entry for Self STA. + * DPH entry for the self STA stores the sta index for the BSS entry + * to which the STA is associated. + */ + psessionEntry->staId = pAddStaParams->staIdx; + //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) +#endif + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_KEEPALIVE_TIMER)); + + //assign the sessionId to the timer Object + pMac->lim.limTimers.gLimKeepaliveTimer.sessionId = psessionEntry->peSessionId; + if (tx_timer_activate(&pMac->lim.limTimers.gLimKeepaliveTimer) != TX_SUCCESS) + limLog(pMac, LOGP, FL("Cannot activate keepalive timer.")); +#ifdef WLAN_DEBUG + pMac->lim.gLimNumLinkEsts++; +#endif +#ifdef FEATURE_WLAN_TDLS + /* initialize TDLS peer related data */ + limInitTdlsData(pMac,psessionEntry); +#endif + // Return Assoc confirm to SME with success + // FIXME_GEN4 - Need the correct ASSOC RSP code to + // be passed in here.... + //mlmAssocCnf.resultCode = (tSirResultCodes) assoc.statusCode; + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_SUCCESS; + } + else + { + limLog( pMac, LOGE, FL( "ADD_STA failed!")); + if(psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + { + mesgType = LIM_MLM_REASSOC_CNF; + mlmAssocCnf.resultCode = (tSirResultCodes)eSIR_SME_FT_REASSOC_FAILURE; + } + else + { + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + } + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + } +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddStaParams); + limMsgQ->bodyptr = NULL; + } + /* Updating PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage( pMac, mesgType, (tANI_U32 *) &mlmAssocCnf ); + if (true == psessionEntry->fDeauthReceived) + { + psessionEntry->fDeauthReceived = false; + } + return; +} +void limProcessMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + // tpPESession psessionEntry; + // tpDeleteBssParams pDeleteBssParams =( tpDeleteBssParams)limMsgQ->bodyptr; + // if((psessionEntry = peFindSessionBySessionId(pMac,pDeleteBssParams->sessionId)) == NULL) + // { + // limLog( pMac, LOGE, FL( "Session deos not exist with given sessionId" )); + // return; + // } + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) && + (psessionEntry->statypeForBss == STA_ENTRY_SELF)) + { + limProcessBtAmpApMlmDelBssRsp(pMac, limMsgQ,psessionEntry); + return; + } + limProcessStaMlmDelBssRsp(pMac, limMsgQ,psessionEntry); + + if(!limIsInMCC(pMac)) + { + WDA_TrafficStatsTimerActivate(FALSE); + } + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + if ( eSIR_SUCCESS != limSendExcludeUnencryptInd(pMac, TRUE, psessionEntry) ) + { + limLog( pMac, LOGE, + FL( "Could not send down Exclude Unencrypted Indication!" ) ); + } + } +#endif +} + +void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpDeleteBssParams pDelBssParams = (tpDeleteBssParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + tSirResultCodes statusCode = eSIR_SME_SUCCESS; + +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_process_sta_mlm_del_bss_rsp_mbb(pMac, limMsgQ, psessionEntry); + return; + } +#endif + + if (NULL == pDelBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + if( eHAL_STATUS_SUCCESS == pDelBssParams->status ) + { + PELOGW(limLog( pMac, LOGW, + FL( "STA received the DEL_BSS_RSP for BSSID: %X."),pDelBssParams->bssIdx);) + if (limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + + { + PELOGE(limLog( pMac, LOGE, FL( "Failure in setting link state to IDLE"));) + statusCode = eSIR_SME_REFUSED; + goto end; + } + if(pStaDs == NULL) + { + limLog( pMac, LOGE, FL( "DPH Entry for STA 1 missing.")); + statusCode = eSIR_SME_REFUSED; + goto end; + } + if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != pStaDs->mlmStaContext.mlmState) + { + PELOGE(limLog( pMac, LOGE, FL( "Received unexpected WDA_DEL_BSS_RSP in state %d" ), + pStaDs->mlmStaContext.mlmState);) + statusCode = eSIR_SME_REFUSED; + goto end; + } + limLog( pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId ); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1); + } + else + { + /* If DelBSS response is failure, go ahead and + * post response to SME + */ + limLog( pMac, LOGE, FL( "DEL BSS failed! Status:%d" ), + pDelBssParams->status ); + statusCode = eSIR_SME_REFUSED; + } + +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pDelBssParams); + limMsgQ->bodyptr = NULL; + } + if(pStaDs == NULL) + return; + if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE && + psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE) && + pStaDs->mlmStaContext.cleanupTrigger != eLIM_JOIN_FAILURE) + { + /** The Case where the DelBss is invoked from + * context of other than normal DisAssoc / Deauth OR + * as part of Join Failure. + */ + limHandleDelBssInReAssocContext(pMac, pStaDs,psessionEntry); + return; + } + limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry); + return; +} + +void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tSirResultCodes rc = eSIR_SME_SUCCESS; + tSirRetStatus status; + tpDeleteBssParams pDelBss = (tpDeleteBssParams) limMsgQ->bodyptr; + tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + if(psessionEntry == NULL) + { + limLog(pMac, LOGE,FL("Session entry passed is NULL")); + if(pDelBss != NULL) + { + vos_mem_free(pDelBss); + limMsgQ->bodyptr = NULL; + } + return; + } + + if (pDelBss == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP with no body!"));) + rc = eSIR_SME_REFUSED; + goto end; + } + pMac->lim.gLimMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + if( eLIM_MLM_WT_DEL_BSS_RSP_STATE != psessionEntry->limMlmState) + { + limLog( pMac, LOGE, + FL( "Received unexpected WDA_DEL_BSS_RSP in state %d" ), + psessionEntry->limMlmState); + rc = eSIR_SME_REFUSED; + goto end; + } + if (pDelBss->status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, FL("BSS: DEL_BSS_RSP error (%x) Bss %d "), + pDelBss->status, pDelBss->bssIdx); + rc = eSIR_SME_STOP_BSS_FAILURE; + goto end; + } + status = limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid, + psessionEntry->selfMacAddr, NULL, NULL); + if (status != eSIR_SUCCESS) + { + rc = eSIR_SME_REFUSED; + goto end; + } + /** Softmac may send all the buffered packets right after resuming the transmission hence + * to occupy the medium during non channel occupancy period. So resume the transmission after + * HAL gives back the response. + */ +#if 0 //TODO: How to handle this per session + if (LIM_IS_RADAR_DETECTED(pMac)) + { + limFrameTransmissionControl(pMac, eLIM_TX_BSS_BUT_BEACON, eLIM_RESUME_TX); + LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE); + } +#endif + dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);//TBD-RAJESH is it needed ? + limDeletePreAuthList(pMac); + //Initialize number of associated stations during cleanup + psessionEntry->gLimNumOfCurrentSTAs = 0; + end: + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc, psessionEntry->smeSessionId, psessionEntry->transactionId); + peDeleteSession(pMac, psessionEntry); + + if(pDelBss != NULL) + { + vos_mem_free(pDelBss); + limMsgQ->bodyptr = NULL; + } +} + +void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + + tpPESession psessionEntry; + tpDeleteStaParams pDeleteStaParams; + pDeleteStaParams = (tpDeleteStaParams)limMsgQ->bodyptr; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(NULL == pDeleteStaParams || + NULL == (psessionEntry = peFindSessionBySessionId(pMac, pDeleteStaParams->sessionId))) + { + limLog(pMac, LOGP,FL("Session Does not exist or invalid body pointer in message")); + if(pDeleteStaParams != NULL) + { + vos_mem_free(pDeleteStaParams); + limMsgQ->bodyptr = NULL; + } + return; + } + + if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE) + ) + { + limProcessBtAmpApMlmDelStaRsp(pMac,limMsgQ,psessionEntry); + return; + } + limProcessStaMlmDelStaRsp(pMac, limMsgQ,psessionEntry); +} + +void limProcessBtAmpApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs; + tSirResultCodes statusCode = eSIR_SME_SUCCESS; + if(limMsgQ->bodyptr == NULL) + { + limLog( pMac, LOGE, + FL( "limMsgQ->bodyptry NULL")); + return; + } + pStaDs = dphGetHashEntry(pMac, pDelStaParams->assocId, &psessionEntry->dph.dphHashTable); + if(pStaDs == NULL) + { + limLog( pMac, LOGE, + FL( "DPH Entry for STA %d missing."), pDelStaParams->assocId); + statusCode = eSIR_SME_REFUSED; + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + + return; + } + limLog( pMac, LOG1, + FL( "Received del Sta Rsp in StaD MlmState : %d"), + pStaDs->mlmStaContext.mlmState); + if( eHAL_STATUS_SUCCESS == pDelStaParams->status ) + { + limLog( pMac, LOGW, + FL( "AP received the DEL_STA_RSP for assocID: %d."), pDelStaParams->assocId); + + if(( eLIM_MLM_WT_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) && + ( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState)) + { + limLog( pMac, LOGE, + FL( "Received unexpected WDA_DEL_STA_RSP in state %s for staId %d assocId %d " ), + limMlmStateStr(pStaDs->mlmStaContext.mlmState), pStaDs->staIndex, pStaDs->assocId); + statusCode = eSIR_SME_REFUSED; + goto end; + } + + limLog( pMac, LOG1, + FL("Deleted STA AssocID %d staId %d MAC "), + pStaDs->assocId, pStaDs->staIndex); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1); + if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE == pStaDs->mlmStaContext.mlmState) + { + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + if (limAddSta(pMac, pStaDs, false, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, + FL("could not Add STA with assocId=%d"), + pStaDs->assocId);) + // delete the TS if it has already been added. + // send the response with error status. + if(pStaDs->qos.addtsPresent) + { + tpLimTspecInfo pTspecInfo; + if(eSIR_SUCCESS == limTspecFindByAssocId(pMac, pStaDs->assocId, + &pStaDs->qos.addts.tspec, &pMac->lim.tspecInfo[0], &pTspecInfo)) + { + limAdmitControlDeleteTS(pMac, pStaDs->assocId, &pStaDs->qos.addts.tspec.tsinfo, + NULL, &pTspecInfo->idx); + } + } + limRejectAssociation(pMac, + pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry); + } + return; + } + } + else + { + limLog( pMac, LOGW, + FL( "DEL STA failed!" )); + statusCode = eSIR_SME_REFUSED; + } + end: + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + if(eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) + { + limPrepareAndSendDelStaCnf(pMac, pStaDs, statusCode,psessionEntry); + } + return; +} + +void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tSirResultCodes statusCode = eSIR_SME_SUCCESS; + tpDeleteStaParams pDelStaParams = (tpDeleteStaParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs = NULL; + +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_process_sta_mlm_del_sta_rsp_mbb(pMac, limMsgQ, psessionEntry); + return; + } +#endif + + if(NULL == pDelStaParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + goto end; + } + + limLog(pMac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"), + pDelStaParams->status, pDelStaParams->assocId); + + if (eHAL_STATUS_SUCCESS != pDelStaParams->status) + { + limLog(pMac, LOGE, FL("Del STA failed! Status:%d, still proceeding" + "with Del BSS"), pDelStaParams->status); + } + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing."), + pDelStaParams->assocId); + statusCode = eSIR_SME_REFUSED; + goto end; + } + + if (eLIM_MLM_WT_DEL_STA_RSP_STATE != psessionEntry->limMlmState) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, FL( "Received unexpected WDA_DELETE_STA_RSP in state %s" ), + limMlmStateStr(psessionEntry->limMlmState)); + statusCode = eSIR_SME_REFUSED; + goto end; + } + + limLog( pMac, LOG1, FL("STA AssocID %d MAC "), pStaDs->assocId ); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1); + + //we must complete all cleanup related to delSta before calling limDelBSS. + if (0 != limMsgQ->bodyptr ) + { + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + } + + // Proceed to do DelBSS even if DelSta resulted in failure + statusCode = (tSirResultCodes) limDelBss(pMac, pStaDs, 0,psessionEntry); + return; + +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pDelStaParams); + limMsgQ->bodyptr = NULL; + } + return; +} + +void limProcessBtAmpApMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpAddStaParams pAddStaParams = (tpAddStaParams) limMsgQ->bodyptr; + tpDphHashNode pStaDs = NULL; + + if (NULL == pAddStaParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + + pStaDs = dphGetHashEntry(pMac, pAddStaParams->assocId, &psessionEntry->dph.dphHashTable); + if(pStaDs == NULL) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, FL( "DPH Entry for STA %X missing."), pAddStaParams->assocId); + goto end; + } + // + // TODO & FIXME_GEN4 + // Need to inspect tSirMsgQ.reserved for a valid Dialog token! + // + //TODO: any check for pMac->lim.gLimMlmState ? + if( eLIM_MLM_WT_ADD_STA_RSP_STATE != pStaDs->mlmStaContext.mlmState) + { + //TODO: any response to be sent out here ? + limLog( pMac, LOGE, + FL( "Received unexpected WDA_ADD_STA_RSP in state %d" ), + pStaDs->mlmStaContext.mlmState); + goto end; + } + if(eHAL_STATUS_SUCCESS != pAddStaParams->status) + { + PELOGE(limLog(pMac, LOGE, FL("Error! rcvd delSta rsp from HAL with status %d"),pAddStaParams->status);) + limRejectAssociation(pMac, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + (tSirResultCodes) eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry); + goto end; + } + pStaDs->bssId = pAddStaParams->bssIdx; + pStaDs->staIndex = pAddStaParams->staIdx; + //if the AssocRsp frame is not acknowledged, then keep alive timer will take care of the state + pStaDs->valid = 1; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_ASSOC_CNF_STATE; + limLog( pMac, LOG1, + FL("AddStaRsp Success.STA AssocID %d staId %d MAC "), + pStaDs->assocId, + pStaDs->staIndex); + limPrintMacAddr(pMac, pStaDs->staAddr, LOG1); + + /* For BTAMP-AP, the flow sequence shall be: + * 1) PE sends eWNI_SME_ASSOC_IND to SME + * 2) PE receives eWNI_SME_ASSOC_CNF from SME + * 3) BTAMP-AP sends Re/Association Response to BTAMP-STA + */ + limSendMlmAssocInd(pMac, pStaDs, psessionEntry); + // fall though to reclaim the original Add STA Response message +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(pAddStaParams); + limMsgQ->bodyptr = NULL; + } + return; +} + +/** + * limProcessApMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Validates the result of WDA_ADD_BSS_REQ + * > Init other remaining LIM variables + * > Init the AID pool, for that BSSID + * > Init the Pre-AUTH list, for that BSSID + * > Create LIM timers, specific to that BSSID + * > Init DPH related parameters that are specific to that BSSID + * > TODO - When do we do the actual change channel? + * + *LOGIC: + * SME sends eWNI_SME_START_BSS_REQ to LIM + * LIM sends LIM_MLM_START_REQ to MLME + * MLME sends WDA_ADD_BSS_REQ to HAL + * HAL responds with WDA_ADD_BSS_RSP to MLME + * MLME responds with LIM_MLM_START_CNF to LIM + * LIM responds with eWNI_SME_START_BSS_RSP to SME + * + *ASSUMPTIONS: + * tSirMsgQ.body is allocated by MLME during limProcessMlmStartReq + * tSirMsgQ.body will now be freed by this routine + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +static void +limProcessApMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ) +{ + tLimMlmStartCnf mlmStartCnf; + tANI_U32 val; + tpPESession psessionEntry; +// tANI_U8 sessionId; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + if(NULL == pAddBssParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + goto end; + } + //TBD: free the memory before returning, do it for all places where lookup fails. + if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + if( NULL != pAddBssParams ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } + return; + } + /* Update PE session Id*/ + mlmStartCnf.sessionId = pAddBssParams->sessionId; + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + limLog(pMac, LOG1, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS")); + if (limSetLinkState(pMac, eSIR_LINK_AP_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + // Set MLME state + psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + if( eSIR_IBSS_MODE == pAddBssParams->bssType ) + { + /** IBSS is 'active' when we receive + * Beacon frames from other STAs that are part of same IBSS. + * Mark internal state as inactive until then. + */ + psessionEntry->limIbssActive = false; + psessionEntry->statypeForBss = STA_ENTRY_PEER; //to know session created for self/peer + limResetHBPktCount( psessionEntry ); + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if (limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate Heartbeat timer")); + } + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + + if ( eSIR_INFRA_AP_MODE == pAddBssParams->bssType ) + psessionEntry->limSystemRole = eLIM_AP_ROLE; + else + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + schEdcaProfileUpdate(pMac, psessionEntry); + limInitPreAuthList(pMac); + limInitPeerIdxpool(pMac,psessionEntry); + // Create timers used by LIM + if (!pMac->lim.gLimTimersCreated) + limCreateTimers(pMac); + + // Start OLBC timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("tx_timer_activate failed")); + } + + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val )) + limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + psessionEntry->staId = pAddBssParams->staContext.staIdx; + mlmStartCnf.resultCode = eSIR_SME_SUCCESS; + } + else + { + limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d" ),pAddBssParams->status ); + mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + + +/** + * limProcessIbssMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Validates the result of WDA_ADD_BSS_REQ + * > Init other remaining LIM variables + * > Init the AID pool, for that BSSID + * > Init the Pre-AUTH list, for that BSSID + * > Create LIM timers, specific to that BSSID + * > Init DPH related parameters that are specific to that BSSID + * > TODO - When do we do the actual change channel? + * + *LOGIC: + * SME sends eWNI_SME_START_BSS_REQ to LIM + * LIM sends LIM_MLM_START_REQ to MLME + * MLME sends WDA_ADD_BSS_REQ to HAL + * HAL responds with WDA_ADD_BSS_RSP to MLME + * MLME responds with LIM_MLM_START_CNF to LIM + * LIM responds with eWNI_SME_START_BSS_RSP to SME + * + *ASSUMPTIONS: + * tSirMsgQ.body is allocated by MLME during limProcessMlmStartReq + * tSirMsgQ.body will now be freed by this routine + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +static void +limProcessIbssMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry) +{ + tLimMlmStartCnf mlmStartCnf; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tANI_U32 val; + + if (NULL == pAddBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + limLog(pMac, LOG1, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS")); + if (limSetLinkState(pMac, eSIR_LINK_IBSS_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + // Set MLME state + psessionEntry->limMlmState = eLIM_MLM_BSS_STARTED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + /** IBSS is 'active' when we receive + * Beacon frames from other STAs that are part of same IBSS. + * Mark internal state as inactive until then. + */ + psessionEntry->limIbssActive = false; + limResetHBPktCount( psessionEntry ); + /* Timer related functions are not modified for BT-AMP : To be Done */ + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if (limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate Heartbeat timer")); + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + psessionEntry->statypeForBss = STA_ENTRY_SELF; + schEdcaProfileUpdate(pMac, psessionEntry); + //TBD-RAJESH limInitPreauthList should re removed for IBSS also ????? + //limInitPreAuthList(pMac); + if (0 == psessionEntry->freePeerIdxHead) + limInitPeerIdxpool(pMac,psessionEntry); + // Create timers used by LIM +#ifdef FIXME_GEN6 //following code may not be required, as limCreateTimers is now invoked from limInitialize (peStart) + if (!pMac->lim.gLimTimersCreated) + limCreateTimers(pMac); +#endif + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val )) + limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + psessionEntry->staId = pAddBssParams->staContext.staIdx; + mlmStartCnf.resultCode = eSIR_SME_SUCCESS; + //If ADD BSS was issued as part of IBSS coalescing, don't send the message to SME, as that is internal to LIM + if(true == pMac->lim.gLimIbssCoalescingHappened) + { + limIbssAddBssRspWhenCoalescing(pMac, limMsgQ->bodyptr, psessionEntry); + goto end; + } + } + else + { + limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d" ), + pAddBssParams->status ); + mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + //Send this message to SME, when ADD_BSS is initiated by SME + //If ADD_BSS is done as part of coalescing, this won't happen. + /* Update PE session Id*/ + mlmStartCnf.sessionId =psessionEntry->peSessionId; + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + +static void +limProcessStaMlmAddBssRspPreAssoc( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, tpPESession psessionEntry ) +{ + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tAniAuthType cfgAuthType, authMode; + tLimMlmAuthReq *pMlmAuthReq; + tpDphHashNode pStaDs = NULL; + + if (NULL == pAddBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto joinFailure; + } + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + if ((pStaDs = dphAddHashEntry(pMac, pAddBssParams->staContext.staMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for "));) + limPrintMacAddr(pMac, pAddBssParams->staContext.staMac, LOGE); + goto joinFailure; + } + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + //Success, handle below + pStaDs->bssId = pAddBssParams->bssIdx; + //STA Index(genr by HAL) for the BSS entry is stored here + pStaDs->staIndex = pAddBssParams->staContext.staIdx; + // Trigger Authentication with AP + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE, + (tANI_U32 *) &cfgAuthType) != eSIR_SUCCESS) + { + /** + * Could not get AuthType from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthType")); + } + if (cfgAuthType == eSIR_AUTO_SWITCH) + authMode = eSIR_SHARED_KEY; // Try Shared Authentication first + else + authMode = cfgAuthType; + + // Trigger MAC based Authentication + pMlmAuthReq = vos_mem_malloc(sizeof(tLimMlmAuthReq)); + if ( NULL == pMlmAuthReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmAuthReq")); + return; + } + #if 0 + val = sizeof(tSirMacAddr); + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, + pMlmAuthReq->peerMacAddr, + &val) != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(pMlmAuthReq->peerMacAddr,psessionEntry->bssId); + + pMlmAuthReq->authType = authMode; + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmAuthReq->authFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout + * value from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + // SUNIT_FIX_ME: Set BOTH? Assume not. Please verify here and below. + //pMac->lim.gLimMlmState = eLIM_MLM_JOINED_STATE; + psessionEntry->limMlmState = eLIM_MLM_JOINED_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_JOINED_STATE)); + pMlmAuthReq->sessionId = psessionEntry->peSessionId; + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_AUTH_STATE; + // remember staId in case of assoc timeout/failure handling + psessionEntry->staId = pAddBssParams->staContext.staIdx; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, + psessionEntry->peSessionId, psessionEntry->limSmeState)); + limLog(pMac,LOG1,"SessionId:%d limPostMlmMessage LIM_MLM_AUTH_REQ" + "with limSmeState:%d",psessionEntry->peSessionId, + psessionEntry->limSmeState); + limPostMlmMessage(pMac, + LIM_MLM_AUTH_REQ, + (tANI_U32 *) pMlmAuthReq); + return; + } + +joinFailure: + { + psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /// Send Join response to Host + limHandleSmeJoinResult(pMac, eSIR_SME_REFUSED, eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + + } + +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*------------------------------------------------------------------------------------------ + * + * Function to handle WDA_ADD_BSS_RSP, in FT reassoc state. + * Function to Send ReAssociation Request. + * + * + *------------------------------------------------------------------------------------------ + */ +static inline void +limProcessStaMlmAddBssRspFT(tpAniSirGlobal pMac, tpSirMsgQ limMsgQ, tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; // keep sme + tpDphHashNode pStaDs = NULL; + tpAddStaParams pAddStaParams = NULL; + tANI_U32 listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tANI_U32 selfStaDot11Mode = 0; +#ifdef FEATURE_WLAN_ESE + tLimMlmReassocReq *pMlmReassocReq; + tANI_U32 val = 0; +#endif + + /* Sanity Checks */ + + if (pAddBssParams == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Invalid parameters"));) + goto end; + } + if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL) + { + limLog( pMac, LOGE, FL( "Session Does not exist for given sessionId" )); + goto end; + } + if ( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE != psessionEntry->limMlmState ) + { + goto end; + } + + if ((pStaDs = dphAddHashEntry(pMac, pAddBssParams->bssId, DPH_STA_HASH_INDEX_PEER, + &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for "));) + limPrintMacAddr(pMac, pAddBssParams->staContext.staMac, LOGE); + goto end; + } + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_LIM_ADD_BS_RSP, NULL, 0); + } + // Prepare and send Reassociation request frame + // start reassoc timer. + + +#ifdef FEATURE_WLAN_ESE + /* + * In case of Ese Reassociation, change the reassoc timer + * value. + */ + pMlmReassocReq = (tLimMlmReassocReq *)(psessionEntry->pLimMlmReassocReq); + if (pMlmReassocReq == NULL) + { + limLog(pMac, LOGE, + FL("Invalid pMlmReassocReq")); + goto end; + } + val = pMlmReassocReq->reassocFailureTimeout; + if (psessionEntry->isESEconnection) + { + val = val/LIM_MAX_REASSOC_RETRY_LIMIT; + } + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer) != + TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to deactivate Reassoc failure timer")); + } + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimReassocFailureTimer, + val, 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to change Reassociation failure timer")); + } +#endif + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId; + /// Start reassociation failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer) + != TX_SUCCESS) + { + /// Could not start reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Reassociation failure timer")); + // Return Reassoc confirm with + // Resources Unavailable + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + goto end; + } + // remember staId + psessionEntry->staId = pAddBssParams->staContext.staIdx; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->lim.pSessionEntry = psessionEntry; + if(NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) + { + /* Take a copy of reassoc request for retrying */ + pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if ( NULL == pMac->lim.pSessionEntry->pLimMlmReassocRetryReq ) goto end; + vos_mem_set(pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, sizeof(tLimMlmReassocReq), 0); + vos_mem_copy(pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, + psessionEntry->pLimMlmReassocReq, + sizeof(tLimMlmReassocReq)); + } + pMac->lim.reAssocRetryAttempt = 0; +#endif + limSendReassocReqWithFTIEsMgmtFrame(pMac, psessionEntry->pLimMlmReassocReq, psessionEntry); + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_LIM_SEND_REASSOC_REQ, NULL, 0); + } + psessionEntry->limPrevMlmState = psessionEntry->limMlmState; + psessionEntry->limMlmState = eLIM_MLM_WT_FT_REASSOC_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, eLIM_MLM_WT_FT_REASSOC_RSP_STATE)); + PELOGE(limLog(pMac, LOG1, FL("Set the mlm state to %d session=%d"), + psessionEntry->limMlmState, psessionEntry->peSessionId);) + + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + + //Success, handle below + pStaDs->bssId = pAddBssParams->bssIdx; + //STA Index(genr by HAL) for the BSS entry is stored here + pStaDs->staIndex = pAddBssParams->staContext.staIdx; + pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig; + pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig; + +#if defined WLAN_FEATURE_VOWIFI + rrmCacheMgmtTxPower( pMac, pAddBssParams->txMgmtPower, psessionEntry ); +#endif + + pAddStaParams = vos_mem_malloc(sizeof( tAddStaParams )); + if ( NULL == pAddStaParams ) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during ADD_STA" )); + goto end; + } + vos_mem_set((tANI_U8 *) pAddStaParams, sizeof(tAddStaParams), 0); + + /// Add STA context at MAC HW (BMU, RHP & TFP) + vos_mem_copy((tANI_U8 *) pAddStaParams->staMac, + (tANI_U8 *) psessionEntry->selfMacAddr, sizeof(tSirMacAddr)); + + vos_mem_copy((tANI_U8 *) pAddStaParams->bssId, + psessionEntry->bssId, sizeof(tSirMacAddr)); + + // Update this when we get reassoc rsp , with success. + // pAddStaParams->assocId = psessionEntry->limAID; + + pAddStaParams->staType = STA_ENTRY_SELF; + pAddStaParams->status = eHAL_STATUS_SUCCESS; + pAddStaParams->respReqd = 1; + + /* Update PE session ID */ + pAddStaParams->sessionId = psessionEntry->peSessionId; + + // This will indicate HAL to "allocate" a new STA index + pAddStaParams->staIdx = HAL_STA_INVALID_IDX; + pAddStaParams->updateSta = FALSE; + + pAddStaParams->shortPreambleSupported = (tANI_U8)psessionEntry->beaconParams.fShortPreamble; +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry, NULL); +#else + limPopulatePeerRateSet(pMac, &pAddStaParams->supportedRates, NULL, false,psessionEntry); +#endif + + if( psessionEntry->htCapability) + { + pAddStaParams->htCapable = psessionEntry->htCapability; +#ifdef WLAN_FEATURE_11AC + pAddStaParams->vhtCapable = psessionEntry->vhtCapability; + pAddStaParams->vhtTxChannelWidthSet = psessionEntry->vhtTxChannelWidthSet; +#endif +#ifdef DISABLE_GF_FOR_INTEROP + /* + * To resolve the interop problem with Broadcom AP, + * where TQ STA could not pass traffic with GF enabled, + * TQ STA will do Greenfield only with TQ AP, for + * everybody else it will be turned off. + */ + if( (psessionEntry->pLimJoinReq != NULL) && (!psessionEntry->pLimJoinReq->bssDescription.aniIndicator)) + { + limLog( pMac, LOGE, FL(" Turning off Greenfield, when adding self entry")); + pAddStaParams->greenFieldCapable = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } + else +#endif + + pAddStaParams->greenFieldCapable = limGetHTCapability( pMac, eHT_GREENFIELD, psessionEntry); + if (psessionEntry->limRFBand == SIR_BAND_2_4_GHZ) + { + pAddStaParams->txChannelWidthSet = + pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + pAddStaParams->txChannelWidthSet = + pMac->roam.configParam.channelBondingMode5GHz; + } + pAddStaParams->mimoPS = limGetHTCapability( pMac, eHT_MIMO_POWER_SAVE, psessionEntry ); + pAddStaParams->rifsMode = limGetHTCapability( pMac, eHT_RIFS_MODE, psessionEntry ); + pAddStaParams->lsigTxopProtection = limGetHTCapability( pMac, eHT_LSIG_TXOP_PROTECTION, psessionEntry ); + pAddStaParams->delBASupport = limGetHTCapability( pMac, eHT_DELAYED_BA, psessionEntry ); + pAddStaParams->maxAmpduDensity = limGetHTCapability( pMac, eHT_MPDU_DENSITY, psessionEntry ); + pAddStaParams->maxAmpduSize = limGetHTCapability(pMac, eHT_MAX_RX_AMPDU_FACTOR, psessionEntry); + pAddStaParams->maxAmsduSize = limGetHTCapability( pMac, eHT_MAX_AMSDU_LENGTH, psessionEntry ); + pAddStaParams->fDsssCckMode40Mhz = limGetHTCapability( pMac, eHT_DSSS_CCK_MODE_40MHZ, psessionEntry); + pAddStaParams->fShortGI20Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_20MHZ, psessionEntry); + pAddStaParams->fShortGI40Mhz = limGetHTCapability( pMac, eHT_SHORT_GI_40MHZ, psessionEntry); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL")); + pAddStaParams->listenInterval = (tANI_U16)listenInterval; + wlan_cfgGetInt(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode); + pAddStaParams->supportedRates.opRateMode = limGetStaRateMode((tANI_U8)selfStaDot11Mode); + // Lets save this for when we receive the Reassoc Rsp + pMac->ft.ftPEContext.pAddStaReq = pAddStaParams; + + if (pAddBssParams != NULL) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + pAddBssParams = NULL; + limMsgQ->bodyptr = NULL; + } + return; + +end: + // Free up buffer allocated for reassocReq + if (psessionEntry != NULL) + if (psessionEntry->pLimMlmReassocReq != NULL) + { + vos_mem_free(psessionEntry->pLimMlmReassocReq); + psessionEntry->pLimMlmReassocReq = NULL; + } + + if (pAddBssParams != NULL) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + pAddBssParams = NULL; + limMsgQ->bodyptr = NULL; + } + + mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE session Id*/ + if (psessionEntry != NULL) + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + else + mlmReassocCnf.sessionId = 0; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ +/** + * limProcessStaMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Validates the result of WDA_ADD_BSS_REQ + * > Now, send an ADD_STA to HAL and ADD the "local" STA itself + * + *LOGIC: + * MLME had sent WDA_ADD_BSS_REQ to HAL + * HAL responded with WDA_ADD_BSS_RSP to MLME + * MLME now sends WDA_ADD_STA_REQ to HAL + * + *ASSUMPTIONS: + * tSirMsgQ.body is allocated by MLME during limProcessMlmJoinReq + * tSirMsgQ.body will now be freed by this routine + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +static void +limProcessStaMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry) +{ + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + tLimMlmAssocCnf mlmAssocCnf; + tANI_U32 mesgType = LIM_MLM_ASSOC_CNF; + tANI_U32 subType = LIM_ASSOC; + tpDphHashNode pStaDs = NULL; + tANI_U16 staIdx = HAL_STA_INVALID_IDX; + tANI_U8 updateSta = false; + mlmAssocCnf.resultCode = eSIR_SME_SUCCESS; + + if(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE == psessionEntry->limMlmState) + { + //Done: 7-28-2009. JIM_FIX_ME: sessionize the following function + limLog(pMac,LOG1,"SessionId:%d limProcessStaMlmAddBssRspPreAssoc", + psessionEntry->peSessionId); + limProcessStaMlmAddBssRspPreAssoc(pMac, limMsgQ, psessionEntry); + goto end; + } + + if(( eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE == psessionEntry->limMlmState ) || + ( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == psessionEntry->limMlmState )) + { + mesgType = LIM_MLM_REASSOC_CNF; + subType = LIM_REASSOC; + //If Reassoc is happening for the same BSS, then use the existing StaId and indicate to HAL + //to update the existing STA entry. + //If Reassoc is happening for the new BSS, then old BSS and STA entry would have been already deleted + //before PE tries to add BSS for the new BSS, so set the updateSta to false and pass INVALID STA Index. + if (sirCompareMacAddr( psessionEntry->bssId, psessionEntry->limReAssocbssId)) + { + staIdx = psessionEntry->staId; + updateSta = true; + } + } + + if(pAddBssParams == 0) + goto end; + + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if( eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == psessionEntry->limMlmState ) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("Mlm=%d %d"), + psessionEntry->limMlmState, + eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE);) +#endif + limProcessStaMlmAddBssRspFT( pMac, limMsgQ, psessionEntry); + goto end; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + // Set MLME state + psessionEntry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + psessionEntry->statypeForBss = STA_ENTRY_PEER; //to know the session started for self or for peer oct6th + // Now, send WDA_ADD_STA_REQ + limLog( pMac, LOGW, FL( "SessionId:%d On STA: ADD_BSS was successful" ), + psessionEntry->peSessionId); + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("SessionId:%d could not Add Self" + "Entry for the station"),psessionEntry->peSessionId);) + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + } + else + { + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + //Success, handle below + pStaDs->bssId = pAddBssParams->bssIdx; + //STA Index(genr by HAL) for the BSS entry is stored here + pStaDs->staIndex = pAddBssParams->staContext.staIdx; + pStaDs->ucUcastSig = pAddBssParams->staContext.ucUcastSig; + pStaDs->ucBcastSig = pAddBssParams->staContext.ucBcastSig; + // Downgrade the EDCA parameters if needed + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + // Send the active EDCA parameters to HAL + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + } else { + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } +#if defined WLAN_FEATURE_VOWIFI + rrmCacheMgmtTxPower( pMac, pAddBssParams->txMgmtPower, psessionEntry ); +#endif + + if (subType == LIM_REASSOC) + limDeactivateAndChangeTimer(pMac, eLIM_KEEPALIVE_TIMER); + if (limAddStaSelf(pMac,staIdx, updateSta, psessionEntry) != eSIR_SUCCESS) + { + // Add STA context at HW + PELOGE(limLog(pMac, LOGE, FL("SessionId:%d could not Add Self" + "Entry for the station"),psessionEntry->peSessionId);) + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + } + } + } + else + { + limLog( pMac, LOGP, FL( "SessionId:%d ADD_BSS failed! mlmState = %d" ), + psessionEntry->peSessionId, psessionEntry->limMlmState); + mlmAssocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + // Return Assoc confirm to SME with failure + if(eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE == psessionEntry->limMlmState) + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_FT_REASSOC_FAILURE; + else + mlmAssocCnf.resultCode = (tSirResultCodes) eSIR_SME_REFUSED; + psessionEntry->addBssfailed = true; + } + + if(mlmAssocCnf.resultCode != eSIR_SME_SUCCESS) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + //Set the RXP mode to IDLE, so it starts filtering the frames. + if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE,psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed to set the LinkState\n"));) + /* Update PE session Id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage( pMac, mesgType, (tANI_U32 *) &mlmAssocCnf ); + } + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + + + +/** + * limProcessMlmAddBssRsp() + * + *FUNCTION: + * This function is called to process a WDA_ADD_BSS_RSP from HAL. + * Upon receipt of this message from HAL, MLME - + * > Determines the "state" in which this message was received + * > Forwards it to the appropriate callback + * + *LOGIC: + * WDA_ADD_BSS_RSP can be received by MLME while the LIM is + * in the following two states: + * 1) As AP, LIM state = eLIM_SME_WT_START_BSS_STATE + * 2) As STA, LIM state = eLIM_SME_WT_JOIN_STATE + * Based on these two states, this API will determine where to + * route the message to + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tLimMlmStartCnf mlmStartCnf; + tpPESession psessionEntry; + tpAddBssParams pAddBssParams = (tpAddBssParams) (limMsgQ->bodyptr); + + if(NULL == pAddBssParams ) + { + limLog( pMac, LOGE, FL( "Encountered NULL Pointer" )); + return; + } + + // + // TODO & FIXME_GEN4 + // Need to inspect tSirMsgQ.reserved for a valid Dialog token! + // + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + // Validate SME/LIM state + // Validate MLME state + if((psessionEntry = peFindSessionBySessionId(pMac,pAddBssParams->sessionId))== NULL) + { + limLog( pMac, LOGE, FL( "SessionId:%d Session Does not exist" ), + pAddBssParams->sessionId); + if( NULL != pAddBssParams ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } + return; + } + /* update PE session Id*/ + mlmStartCnf.sessionId = psessionEntry->peSessionId; + if( eSIR_IBSS_MODE == psessionEntry->bssType ) + limProcessIbssMlmAddBssRsp( pMac, limMsgQ, psessionEntry ); + else + { + if( eLIM_SME_WT_START_BSS_STATE == psessionEntry->limSmeState ) + { + if( eLIM_MLM_WT_ADD_BSS_RSP_STATE != psessionEntry->limMlmState ) + { + // Mesg received from HAL in Invalid state! + limLog( pMac, LOGE,FL( "SessionId:%d Received unexpected" + "WDA_ADD_BSS_RSP in state %d" ), + psessionEntry->peSessionId,psessionEntry->limMlmState); + mlmStartCnf.resultCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + } + else if ((psessionEntry->bssType == eSIR_BTAMP_AP_MODE)||(psessionEntry->bssType == eSIR_BTAMP_STA_MODE)) + { + limProcessBtampAddBssRsp(pMac,limMsgQ,psessionEntry); + } + else + limProcessApMlmAddBssRsp( pMac,limMsgQ); + } + else { +#ifdef WLAN_FEATURE_LFR_MBB + if (pMac->ft.ftSmeContext.is_preauth_lfr_mbb) { + lim_process_sta_mlm_add_bss_rsp_mbb(pMac, limMsgQ, psessionEntry); + return; + } +#endif + /* Called while processing assoc response */ + limProcessStaMlmAddBssRsp( pMac, limMsgQ,psessionEntry); + } + } + + if(limIsInMCC(pMac)) + { + WDA_TrafficStatsTimerActivate(TRUE); + } + +#ifdef WLAN_FEATURE_11W + if (psessionEntry->limRmfEnabled) + { + if ( eSIR_SUCCESS != limSendExcludeUnencryptInd(pMac, FALSE, psessionEntry) ) + { + limLog( pMac, LOGE, + FL( "Could not send down Exclude Unencrypted Indication!" ) ); + } + } +#endif +} +/** + * limProcessMlmSetKeyRsp() + * + *FUNCTION: + * This function is called to process the following two + * messages from HAL: + * 1) WDA_SET_BSSKEY_RSP + * 2) WDA_SET_STAKEY_RSP + * 3) WDA_SET_STA_BCASTKEY_RSP + * Upon receipt of this message from HAL, + * MLME - + * > Determines the "state" in which this message was received + * > Forwards it to the appropriate callback + * + *LOGIC: + * WDA_SET_BSSKEY_RSP/WDA_SET_STAKEY_RSP can be + * received by MLME while in the following state: + * MLME state = eLIM_MLM_WT_SET_BSS_KEY_STATE --OR-- + * MLME state = eLIM_MLM_WT_SET_STA_KEY_STATE --OR-- + * MLME state = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE + * Based on this state, this API will determine where to + * route the message to + * + *ASSUMPTIONS: + * ONLY the MLME state is being taken into account for now. + * This is because, it appears that the handling of the + * SETKEYS REQ is handled symmetrically on both the AP & STA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tANI_U8 respReqd = 1; + tLimMlmSetKeysCnf mlmSetKeysCnf; + tANI_U8 sessionId = 0; + tpPESession psessionEntry; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_set((void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ), 0); + //BTAMP + if( NULL == limMsgQ->bodyptr ) + { + PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is NULL"));) + return; + } + sessionId = ((tpSetStaKeyParams) limMsgQ->bodyptr)->sessionId; + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + vos_mem_zero(limMsgQ->bodyptr, sizeof(tSetStaKeyParams)); + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + if( eLIM_MLM_WT_SET_STA_KEY_STATE != psessionEntry->limMlmState ) + { + // Mesg received from HAL in Invalid state! + limLog( pMac, LOGW, FL( "Received unexpected [Mesg Id - %d] in state %d" ), limMsgQ->type, psessionEntry->limMlmState ); + // There's not much that MLME can do at this stage... + respReqd = 0; + } + else + mlmSetKeysCnf.resultCode = (tANI_U16) (((tpSetStaKeyParams) limMsgQ->bodyptr)->status); + + vos_mem_zero(limMsgQ->bodyptr, sizeof(tSetStaKeyParams)); + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + if( respReqd ) + { + tpLimMlmSetKeysReq lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq; + // Prepare and Send LIM_MLM_SETKEYS_CNF + if( NULL != lpLimMlmSetKeysReq ) + { + vos_mem_copy((tANI_U8 *) &mlmSetKeysCnf.peerMacAddr, + (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + // Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq + vos_mem_zero(pMac->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); + vos_mem_free(pMac->lim.gpLimMlmSetKeysReq); + pMac->lim.gpLimMlmSetKeysReq = NULL; + } + mlmSetKeysCnf.sessionId = sessionId; + limPostSmeMessage(pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf); + } +} +void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tLimMlmSetKeysCnf mlmSetKeysCnf; + tANI_U16 resultCode; + tANI_U8 sessionId = 0; + tpPESession psessionEntry; + tpLimMlmSetKeysReq lpLimMlmSetKeysReq; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_set((void *)&mlmSetKeysCnf, sizeof( tLimMlmSetKeysCnf ), 0); + if ( NULL == limMsgQ->bodyptr ) + { + PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is null"));) + return; + } + sessionId = ((tpSetBssKeyParams) limMsgQ->bodyptr)->sessionId; + if ((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for sessionId %d"), + sessionId); + vos_mem_zero(limMsgQ->bodyptr, sizeof(tSetBssKeyParams)); + vos_mem_free( limMsgQ->bodyptr ); + limMsgQ->bodyptr = NULL; + return; + } + if ( eLIM_MLM_WT_SET_BSS_KEY_STATE == psessionEntry->limMlmState ) + resultCode = (tANI_U16) (((tpSetBssKeyParams) limMsgQ->bodyptr)->status); + else + /* BCAST key also uses tpSetStaKeyParams. Done this way for readabilty */ + resultCode = (tANI_U16) (((tpSetStaKeyParams) limMsgQ->bodyptr)->status); + + if( eLIM_MLM_WT_SET_BSS_KEY_STATE != psessionEntry->limMlmState && + eLIM_MLM_WT_SET_STA_BCASTKEY_STATE != psessionEntry->limMlmState ) + { + /* Mesg received from HAL in Invalid state! */ + limLog( pMac, LOGW, + FL( "Received unexpected [Mesg Id - %d] in state %d" ), + limMsgQ->type, psessionEntry->limMlmState ); + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_STATE; + } + else + mlmSetKeysCnf.resultCode = resultCode; + + vos_mem_zero(limMsgQ->bodyptr, sizeof(tSetBssKeyParams)); + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, + psessionEntry->peSessionId, psessionEntry->limMlmState)); + lpLimMlmSetKeysReq = (tpLimMlmSetKeysReq) pMac->lim.gpLimMlmSetKeysReq; + mlmSetKeysCnf.sessionId = sessionId; + + /* Prepare and Send LIM_MLM_SETKEYS_CNF */ + if( NULL != lpLimMlmSetKeysReq ) + { + vos_mem_copy((tANI_U8 *) &mlmSetKeysCnf.peerMacAddr, + (tANI_U8 *) lpLimMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + /* Free the buffer cached for the global pMac->lim.gpLimMlmSetKeysReq */ + vos_mem_zero(pMac->lim.gpLimMlmSetKeysReq, + sizeof(tLimMlmSetKeysReq)); + vos_mem_free(pMac->lim.gpLimMlmSetKeysReq); + pMac->lim.gpLimMlmSetKeysReq = NULL; + } + limPostSmeMessage(pMac, LIM_MLM_SETKEYS_CNF, (tANI_U32 *) &mlmSetKeysCnf); +} +/** + * limProcessMlmRemoveKeyRsp() + * + *FUNCTION: + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param tSirMsgQ The MsgQ header, which contains the response buffer + * + * @return None + */ +void limProcessMlmRemoveKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tANI_U8 respReqd = 1; + tLimMlmRemoveKeyCnf mlmRemoveCnf; + tANI_U16 resultCode; + tANI_U8 sessionId = 0; + tpPESession psessionEntry; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + vos_mem_set((void *) &mlmRemoveCnf, sizeof( tLimMlmRemoveKeyCnf ), 0); + + if( NULL == limMsgQ->bodyptr ) + { + PELOGE(limLog(pMac, LOGE,FL("limMsgQ bodyptr is NULL"));) + return; + } + + if (limMsgQ->type == WDA_REMOVE_STAKEY_RSP) + sessionId = ((tpRemoveStaKeyParams) limMsgQ->bodyptr)->sessionId; + else if (limMsgQ->type == WDA_REMOVE_BSSKEY_RSP) + sessionId = ((tpRemoveBssKeyParams) limMsgQ->bodyptr)->sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionId"));) + return; + } + + if( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE == psessionEntry->limMlmState ) + resultCode = (tANI_U16) (((tpRemoveBssKeyParams) limMsgQ->bodyptr)->status); + else + resultCode = (tANI_U16) (((tpRemoveStaKeyParams) limMsgQ->bodyptr)->status); + + // Validate MLME state + if( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE != psessionEntry->limMlmState && + eLIM_MLM_WT_REMOVE_STA_KEY_STATE != psessionEntry->limMlmState ) + { + // Mesg received from HAL in Invalid state! + limLog(pMac, LOGW, + FL("Received unexpected [Mesg Id - %d] in state %d"), + limMsgQ->type, + psessionEntry->limMlmState ); + respReqd = 0; + } + else + mlmRemoveCnf.resultCode = resultCode; + + // + // TODO & FIXME_GEN4 + // Need to inspect tSirMsgQ.reserved for a valid Dialog token! + // + vos_mem_zero(limMsgQ->bodyptr, sizeof(tRemoveStaKeyParams)); + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + + // Restore MLME state + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + if( respReqd ) + { + tpLimMlmRemoveKeyReq lpLimMlmRemoveKeyReq = (tpLimMlmRemoveKeyReq) pMac->lim.gpLimMlmRemoveKeyReq; + mlmRemoveCnf.sessionId = sessionId; + + // Prepare and Send LIM_MLM_REMOVEKEY_CNF + if( NULL != lpLimMlmRemoveKeyReq ) + { + vos_mem_copy((tANI_U8 *) &mlmRemoveCnf.peerMacAddr, + (tANI_U8 *) lpLimMlmRemoveKeyReq->peerMacAddr, + sizeof( tSirMacAddr )); + // Free the buffer cached for the global pMac->lim.gpLimMlmRemoveKeyReq + vos_mem_free(pMac->lim.gpLimMlmRemoveKeyReq); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + } + limPostSmeMessage( pMac, LIM_MLM_REMOVEKEY_CNF, (tANI_U32 *) &mlmRemoveCnf ); + } +} + + +/** --------------------------------------------------------------------- +\fn limProcessInitScanRsp +\brief This function is called when LIM receives WDA_INIT_SCAN_RSP +\ message from HAL. If status code is failure, then +\ update the gLimNumOfConsecutiveBkgndScanFailure count. +\param tpAniSirGlobal pMac +\param tANI_U32 body +\return none +\ ----------------------------------------------------------------------- */ +void limProcessInitScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpInitScanParams pInitScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pInitScanParam = (tpInitScanParams) body; + status = pInitScanParam->status; + vos_mem_free(body); + + //Only abort scan if the we are scanning. + if( pMac->lim.abortScan && + (eLIM_HAL_INIT_SCAN_WAIT_STATE == pMac->lim.gLimHalScanState) ) + { + limLog( pMac, LOGW, FL(" abort scan") ); + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + if (status != eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("InitScnRsp failed status=%d"),status);) + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure += 1; + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + return; + } + else + { + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + + } + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_INIT_SCAN_WAIT_STATE: + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("InitScanRsp with failed status= %d"), status);) + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure += 1; + /* + * On Windows eSIR_SME_HAL_SCAN_INIT_FAILED message to CSR may trigger + * another Scan request in the same context (happens when 11d is enabled + * and first scan request with 11d channels fails for whatever reason, then CSR issues next init + * scan in the same context but with bigger channel list), so the state needs to be + * changed before this response message is sent. + */ + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + return; + } + else if (status == eHAL_STATUS_SUCCESS) + { + /* since we have successfully triggered a background scan, + * reset the "consecutive bkgnd scan failure" count to 0 + */ + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure = 0; + pMac->lim.gLimNumOfBackgroundScanSuccess += 1; + pMac->lim.probeCounter = 0; + } + limContinueChannelScan(pMac); + break; +//WLAN_SUSPEND_LINK Related + case eLIM_HAL_SUSPEND_LINK_WAIT_STATE: + if( pMac->lim.gpLimSuspendCallback ) + { + if( eHAL_STATUS_SUCCESS == status ) + { + pMac->lim.gLimHalScanState = eLIM_HAL_SUSPEND_LINK_STATE; + } + else + { + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + + pMac->lim.gpLimSuspendCallback( pMac, status, pMac->lim.gpLimSuspendData ); + pMac->lim.gpLimSuspendCallback = NULL; + pMac->lim.gpLimSuspendData = NULL; + } + else + { + limLog( pMac, LOGP, "No suspend link callback set but station is in suspend state"); + return; + } + break; +//end WLAN_SUSPEND_LINK Related + default: + limLog(pMac, LOGW, FL("limProcessInitScanRsp: Rcvd InitScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +/** + * limProcessSwitchChannelReAssocReq() + * + *FUNCTION: + * This function is called to send the reassoc req mgmt frame after the + * switchChannelRsp message is received from HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure. + * @param psessionEntry - session related information. + * @param status - channel switch success/failure. + * + * @return None + */ +static void limProcessSwitchChannelReAssocReq(tpAniSirGlobal pMac, tpPESession psessionEntry, eHalStatus status) +{ + tLimMlmReassocCnf mlmReassocCnf; + tLimMlmReassocReq *pMlmReassocReq; +#ifdef FEATURE_WLAN_ESE + tANI_U32 val = 0; +#endif + pMlmReassocReq = (tLimMlmReassocReq *)(psessionEntry->pLimMlmReassocReq); + if(pMlmReassocReq == NULL) + { + limLog(pMac, LOGP, FL("pLimMlmReassocReq does not exist for given switchChanSession")); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + + if(status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Change channel failed!!"));) + mlmReassocCnf.resultCode = eSIR_SME_CHANNEL_SWITCH_FAIL; + goto end; + } + +#ifdef FEATURE_WLAN_ESE + /* + * In case of Ese Reassociation, change the reassoc timer + * value. + */ + val = pMlmReassocReq->reassocFailureTimeout; + if (psessionEntry->isESEconnection) + { + val = val/LIM_MAX_REASSOC_RETRY_LIMIT; + } + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer) != + TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to deactivate Reassoc failure timer")); + } + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimReassocFailureTimer, + val, 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to change Reassociation failure timer")); + } +#endif + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId; + /// Start reassociation failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer) + != TX_SUCCESS) + { + /// Could not start reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Reassociation failure timer")); + // Return Reassoc confirm with + // Resources Unavailable + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + /// Prepare and send Reassociation request frame + limSendReassocReqMgmtFrame(pMac, pMlmReassocReq, psessionEntry); + return; +end: + // Free up buffer allocated for reassocReq + if(pMlmReassocReq != NULL) + { + /* Update PE session Id*/ + mlmReassocCnf.sessionId = pMlmReassocReq->sessionId; + vos_mem_free(pMlmReassocReq); + psessionEntry->pLimMlmReassocReq = NULL; + } + else + { + mlmReassocCnf.sessionId = 0; + } + + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE sessio Id*/ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} +/** + * limProcessSwitchChannelJoinReq() + * + *FUNCTION: + * This function is called to send the probe req mgmt frame after the + * switchChannelRsp message is received from HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure. + * @param psessionEntry - session related information. + * @param status - channel switch success/failure. + * + * @return None + */ +static void limProcessSwitchChannelJoinReq(tpAniSirGlobal pMac, tpPESession psessionEntry, eHalStatus status) +{ + tANI_U32 val; + tSirMacSSid ssId; + tLimMlmJoinCnf mlmJoinCnf; + if(status != eHAL_STATUS_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Change channel failed!!"));) + goto error; + } + + if ( (NULL == psessionEntry ) || (NULL == psessionEntry->pLimMlmJoinReq) ) + { + PELOGE(limLog(pMac, LOGE, FL("invalid pointer!!"));) + goto error; + } + + + /* eSIR_BTAMP_AP_MODE stroed as bss type in session Table when join req is received, is to be veified */ + if(psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + if (limSetLinkState(pMac, eSIR_LINK_BTAMP_PREASSOC_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + { + PELOGE(limLog(pMac, LOGE, FL("Sessionid: %d Set link state " + "failed!! BSSID:"MAC_ADDRESS_STR),psessionEntry->peSessionId, + MAC_ADDR_ARRAY(psessionEntry->bssId));) + goto error; + } + } + + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if(wlan_cfgGetInt(pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("failed to get WNI_CFG_TRIG_STA_BK_SCAN cfg value!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac, psessionEntry); + + /* If sendDeauthBeforeCon is enabled, Send Deauth first to AP if last + * disconnection was caused by HB failure. + */ + if(pMac->roam.configParam.sendDeauthBeforeCon) + { + int apCount; + + for(apCount = 0; apCount < 2; apCount++) + { + + if (vos_mem_compare(psessionEntry->pLimMlmJoinReq->bssDescription.bssId, + pMac->lim.gLimHeartBeatApMac[apCount], sizeof(tSirMacAddr))) + { + limLog(pMac, LOGE, FL("Index %d Sessionid: %d Send deauth on " + "channel %d to BSSID: "MAC_ADDRESS_STR ), apCount, + psessionEntry->peSessionId, psessionEntry->currentOperChannel, + MAC_ADDR_ARRAY(psessionEntry->pLimMlmJoinReq->bssDescription.bssId)); + + limSendDeauthMgmtFrame( pMac, eSIR_MAC_UNSPEC_FAILURE_REASON, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, + psessionEntry, FALSE ); + + vos_mem_zero(pMac->lim.gLimHeartBeatApMac[apCount], + sizeof(tSirMacAddr)); + break; + } + } + } + + /// Wait for Beacon to announce join success + vos_mem_copy(ssId.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + ssId.length = psessionEntry->ssId.length; + + limDeactivateAndChangeTimer(pMac, eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + + //assign appropriate sessionId to the timer object + pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer.sessionId = psessionEntry->peSessionId; + limLog(pMac, LOG1, FL("Sessionid: %d Send Probe req on channel %d ssid: %.*s " + "BSSID: "MAC_ADDRESS_STR ), psessionEntry->peSessionId, + psessionEntry->currentOperChannel, ssId.length, ssId.ssId, + MAC_ADDR_ARRAY(psessionEntry->pLimMlmJoinReq->bssDescription.bssId)); + // include additional IE if there is + limSendProbeReqMgmtFrame( pMac, &ssId, + psessionEntry->pLimMlmJoinReq->bssDescription.bssId, psessionEntry->currentOperChannel/*chanNum*/, + psessionEntry->selfMacAddr, psessionEntry->dot11mode, + psessionEntry->pLimJoinReq->addIEScan.length, psessionEntry->pLimJoinReq->addIEScan.addIEdata); + + // Sending mgmt frame is a blocking call activate Join failure timer now + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_JOIN_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimJoinFailureTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not activate Join failure timer")); + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, pMac->lim.gLimMlmState)); + //memory is freed up below. + psessionEntry->pLimMlmJoinReq = NULL; + goto error; + } + + if( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) + { + // Activate Join Periodic Probe Req timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not activate Periodic Join req failure timer")); + goto error; + } + } + + return; +error: + if(NULL != psessionEntry) + { + vos_mem_free(psessionEntry->pLimMlmJoinReq); + psessionEntry->pLimMlmJoinReq = NULL; + mlmJoinCnf.sessionId = psessionEntry->peSessionId; + } + else + { + mlmJoinCnf.sessionId = 0; + } + mlmJoinCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmJoinCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); +} + +/** + * limProcessSwitchChannelRsp() + * + *FUNCTION: + * This function is called to process switchChannelRsp message from HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param body - message body. + * + * @return None + */ +void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body) +{ + tpSwitchChannelParams pChnlParams = NULL; + eHalStatus status; + tANI_U16 channelChangeReasonCode; + tANI_U8 peSessionId; + tpPESession psessionEntry; + //we need to process the deferred message since the initiating req. there might be nested request. + //in the case of nested request the new request initiated from the response will take care of resetting + //the deffered flag. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pChnlParams = (tpSwitchChannelParams) body; + status = pChnlParams->status; + peSessionId = pChnlParams->peSessionId; + if((psessionEntry = peFindSessionBySessionId(pMac, peSessionId))== NULL) + { + vos_mem_free(body); + limLog(pMac, LOGP, FL("session does not exist for given sessionId")); + return; + } +#if defined WLAN_FEATURE_VOWIFI + //HAL fills in the tx power used for mgmt frames in this field. + //Store this value to use in TPC report IE. + rrmCacheMgmtTxPower( pMac, pChnlParams->txMgmtPower, psessionEntry ); +#endif + channelChangeReasonCode = psessionEntry->channelChangeReasonCode; + // initialize it back to invalid id + psessionEntry->channelChangeReasonCode = 0xBAD; + limLog(pMac, LOG1, FL("channelChangeReasonCode %d"),channelChangeReasonCode); + switch(channelChangeReasonCode) + { + case LIM_SWITCH_CHANNEL_REASSOC: + limProcessSwitchChannelReAssocReq(pMac, psessionEntry, status); + break; + case LIM_SWITCH_CHANNEL_JOIN: + limProcessSwitchChannelJoinReq(pMac, psessionEntry, status); + break; + + case LIM_SWITCH_CHANNEL_OPERATION: + /* + * The above code should also use the callback. + * mechanism below, there is scope for cleanup here. + * THat way all this response handler does is call the call back + * We can get rid of the reason code here. + */ + if (pMac->lim.gpchangeChannelCallback) + { + limLog( pMac, LOG1, "Channel changed hence invoke registered call back"); + if (eHAL_CHANNEL_SWITCH_SOURCE_CSA == pChnlParams->channelSwitchSrc ) + { + if (IS_MCC_SUPPORTED && limIsLinkSuspended( pMac ) ) + { + if ( psessionEntry && psessionEntry->limSmeState + == eLIM_SME_LINK_EST_STATE ) + { + peSetResumeChannel( pMac, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset); + } + else + { + peSetResumeChannel( pMac, 0, 0); + } + limResumeLink(pMac, limSwitchChannelResumeLinkRsp, NULL); + } + } + pMac->lim.gpchangeChannelCallback(pMac, status, pMac->lim.gpchangeChannelData, psessionEntry); + } + break; + default: + break; + } + vos_mem_free(body); + body = NULL; + +} +/** + * limProcessStartScanRsp() + * + *FUNCTION: + * This function is called to process startScanRsp message from HAL. If scan/learn was successful + * then it will start scan/learn on the next channel. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param body - message body. + * + * @return None + */ + +void limProcessStartScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpStartScanParams pStartScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pStartScanParam = (tpStartScanParams) body; + status = pStartScanParam->status; +#if defined WLAN_FEATURE_VOWIFI + //HAL fills in the tx power used for mgmt frames in this field. + //Store this value to use in TPC report IE. + rrmCacheMgmtTxPower( pMac, pStartScanParam->txMgmtPower, NULL ); + //Store start TSF of scan start. This will be stored in BSS params. + rrmUpdateStartTSF( pMac, pStartScanParam->startTSF ); +#endif + vos_mem_free(body); + body = NULL; + if( pMac->lim.abortScan ) + { + limLog( pMac, LOGW, FL(" finish scan") ); + pMac->lim.abortScan = 0; + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_START_SCAN_WAIT_STATE: + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("StartScanRsp with failed status= %d"), status);) + // + // FIXME - With this, LIM will try and recover state, but + // eWNI_SME_SCAN_CNF maybe reporting an incorrect + // status back to the SME + // + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + //limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + } + else + { + pMac->lim.gLimHalScanState = eLIM_HAL_SCANNING_STATE; + limContinuePostChannelScan(pMac); + } + break; + default: + limLog(pMac, LOGW, FL("Rcvd StartScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +void limProcessEndScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpEndScanParams pEndScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pEndScanParam = (tpEndScanParams) body; + status = pEndScanParam->status; + vos_mem_free(body); + body = NULL; + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_END_SCAN_WAIT_STATE: + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("EndScanRsp with failed status= %d"), status);) + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + limCompleteMlmScan(pMac, eSIR_SME_HAL_SCAN_INIT_FAILED); + } + else + { + pMac->lim.gLimCurrentScanChannelId++; + limContinueChannelScan(pMac); + } + break; + default: + limLog(pMac, LOGW, FL("Rcvd endScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + return; +} +/** + * limStopTxAndSwitch() + * + *FUNCTION: + * Start channel switch on all sessions that is in channel switch state. + * + * @param pMac - pointer to global adapter context + * + * @return None + * + */ +static void +limStopTxAndSwitch (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + limStopTxAndSwitchChannel(pMac, i); + } + } + return; +} +/** + * limStartQuietOnSession() + * + *FUNCTION: + * This function is called to start quiet timer after finish scan if there is + * qeuieting on any session. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +static void +limStartQuietOnSession (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + limStartQuietTimer(pMac, i); + } + } + return; +} +void limProcessFinishScanRsp(tpAniSirGlobal pMac, void *body) +{ + tpFinishScanParams pFinishScanParam; + eHalStatus status; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + pFinishScanParam = (tpFinishScanParams) body; + status = pFinishScanParam->status; + + limLog(pMac, LOG1, FL("Rcvd FinishScanRsp in state %d channel %d "), + pMac->lim.gLimHalScanState, + pFinishScanParam->currentOperChannel); + + switch(pMac->lim.gLimHalScanState) + { + case eLIM_HAL_FINISH_SCAN_WAIT_STATE: +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_COMP_EVENT, NULL, + status, eSIR_SUCCESS); +#endif + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + if (pMac->lim.abortScan) + pMac->lim.abortScan = 0; + limCompleteMlmScan(pMac, eSIR_SME_SUCCESS); + if (limIsChanSwitchRunning(pMac)) + { + /** Right time to stop tx and start the timer for channel switch */ + /* Sending Session ID 0, may not be correct, since SCAN is global there should not + * be any associated session id + */ + limStopTxAndSwitch(pMac); + } + else if (limIsQuietBegin(pMac)) + { + /** Start the quieting */ + /* Sending Session ID 0, may not be correct, since SCAN is global there should not + * be any associated session id + */ + limStartQuietOnSession(pMac); + } + if (status != (tANI_U32) eHAL_STATUS_SUCCESS) + { + PELOGW(limLog(pMac, LOGW, FL("EndScanRsp with failed status= %d"), status);) + } + break; +//WLAN_SUSPEND_LINK Related + case eLIM_HAL_RESUME_LINK_WAIT_STATE: + if( pMac->lim.gpLimResumeCallback ) + { + pMac->lim.gLimHalScanState = eLIM_HAL_IDLE_SCAN_STATE; + pMac->lim.gpLimResumeCallback( pMac, status, pMac->lim.gpLimResumeData ); + pMac->lim.gpLimResumeCallback = NULL; + pMac->lim.gpLimResumeData = NULL; + pMac->lim.gLimSystemInScanLearnMode = 0; + } + else + { + limLog( pMac, LOGP, "No Resume link callback set but station is in suspend state"); + vos_mem_free(body); + body = NULL; + return; + } + break; +//end WLAN_SUSPEND_LINK Related + + default: + limLog(pMac, LOGE, FL("Rcvd FinishScanRsp not in WAIT State, state %d"), + pMac->lim.gLimHalScanState); + break; + } + vos_mem_free(body); + body = NULL; + return; +} +/** + * @function : limProcessMlmHalAddBARsp + * + * @brief: Process WDA_ADDBA_RSP coming from HAL + * + * + * @param pMac The global tpAniSirGlobal object + * + * @param tSirMsgQ The MsgQ header containing the response buffer + * + * @return none + */ +void limProcessMlmHalAddBARsp( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ) +{ + // Send LIM_MLM_ADDBA_CNF to LIM + tpLimMlmAddBACnf pMlmAddBACnf; + tpPESession psessionEntry = NULL; + tpAddBAParams pAddBAParams = (tpAddBAParams) limMsgQ->bodyptr; + + //now LIM can process any defer message. + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + if (pAddBAParams == NULL) { + PELOGE(limLog(pMac, LOGE,FL("NULL ADD BA Response from HAL"));) + return; + } + if((psessionEntry = peFindSessionBySessionId(pMac, pAddBAParams->sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given sessionID: %d"),pAddBAParams->sessionId );) + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + + // Allocate for LIM_MLM_ADDBA_CNF + pMlmAddBACnf = vos_mem_malloc(sizeof(tLimMlmAddBACnf)); + if ( NULL == pMlmAddBACnf ) { + limLog( pMac, LOGP, FL(" AllocateMemory failed for pMlmAddBACnf")); + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + vos_mem_set((void *) pMlmAddBACnf, sizeof( tLimMlmAddBACnf ), 0); + // Copy the peer MAC + vos_mem_copy(pMlmAddBACnf->peerMacAddr, pAddBAParams->peerMacAddr, + sizeof( tSirMacAddr )); + // Copy other ADDBA Rsp parameters + pMlmAddBACnf->baDialogToken = pAddBAParams->baDialogToken; + pMlmAddBACnf->baTID = pAddBAParams->baTID; + pMlmAddBACnf->baPolicy = pAddBAParams->baPolicy; + pMlmAddBACnf->baBufferSize = pAddBAParams->baBufferSize; + pMlmAddBACnf->baTimeout = pAddBAParams->baTimeout; + pMlmAddBACnf->baDirection = pAddBAParams->baDirection; + pMlmAddBACnf->sessionId = psessionEntry->peSessionId; + if(eHAL_STATUS_SUCCESS == pAddBAParams->status) + pMlmAddBACnf->addBAResultCode = eSIR_MAC_SUCCESS_STATUS; + else + pMlmAddBACnf->addBAResultCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT, psessionEntry, + pAddBAParams->status, pMlmAddBACnf->addBAResultCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + // Send ADDBA CNF to LIM + limPostSmeMessage( pMac, LIM_MLM_ADDBA_CNF, (tANI_U32 *) pMlmAddBACnf ); +} +/** + * \brief Process LIM_MLM_ADDBA_CNF + * + * \sa limProcessMlmAddBACnf + * + * \param pMac The global tpAniSirGlobal object + * + * \param tSirMsgQ The MsgQ header containing the response buffer + * + * \return none + */ +void limProcessMlmAddBACnf( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ +tpLimMlmAddBACnf pMlmAddBACnf; +tpDphHashNode pSta; +tANI_U16 aid; +tLimBAState curBaState; +tpPESession psessionEntry = NULL; +if(pMsgBuf == NULL) +{ + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; +} +pMlmAddBACnf = (tpLimMlmAddBACnf) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac,pMlmAddBACnf->sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + vos_mem_free(pMsgBuf); + return; + } + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pMlmAddBACnf->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if( NULL == pSta ) + { + PELOGE(limLog( pMac, LOGE, + FL( "STA context not found - ignoring ADDBA CNF from HAL" ));) + vos_mem_free(pMsgBuf); + return; + } + LIM_GET_STA_BA_STATE(pSta, pMlmAddBACnf->baTID, &curBaState); + // Need to validate SME state + if( eLIM_BA_STATE_WT_ADD_RSP != curBaState) + { + PELOGE(limLog( pMac, LOGE, + FL( "Received unexpected ADDBA CNF when STA BA state is %d" ), + curBaState );) + vos_mem_free(pMsgBuf); + return; + } + // Restore STA BA state + LIM_SET_STA_BA_STATE(pSta, pMlmAddBACnf->baTID, eLIM_BA_STATE_IDLE); + if( eSIR_MAC_SUCCESS_STATUS == pMlmAddBACnf->addBAResultCode ) + { + // Update LIM internal cache... + if( eBA_RECIPIENT == pMlmAddBACnf->baDirection ) + { + pSta->tcCfg[pMlmAddBACnf->baTID].fUseBARx = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fRxCompBA = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fRxBApolicy = pMlmAddBACnf->baPolicy; + pSta->tcCfg[pMlmAddBACnf->baTID].rxBufSize = pMlmAddBACnf->baBufferSize; + pSta->tcCfg[pMlmAddBACnf->baTID].tuRxBAWaitTimeout = pMlmAddBACnf->baTimeout; + // Package LIM_MLM_ADDBA_RSP to MLME, with proper + // status code. MLME will then send an ADDBA RSP + // over the air to the peer MAC entity + if( eSIR_SUCCESS != limPostMlmAddBARsp( pMac, + pMlmAddBACnf->peerMacAddr, + pMlmAddBACnf->addBAResultCode, + pMlmAddBACnf->baDialogToken, + (tANI_U8) pMlmAddBACnf->baTID, + (tANI_U8) pMlmAddBACnf->baPolicy, + pMlmAddBACnf->baBufferSize, + pMlmAddBACnf->baTimeout,psessionEntry)) + { + PELOGW(limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_ADDBA_RSP to " )); + limPrintMacAddr( pMac, pMlmAddBACnf->peerMacAddr, LOGW );) + } + } + else + { + pSta->tcCfg[pMlmAddBACnf->baTID].fUseBATx = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fTxCompBA = 1; + pSta->tcCfg[pMlmAddBACnf->baTID].fTxBApolicy = pMlmAddBACnf->baPolicy; + pSta->tcCfg[pMlmAddBACnf->baTID].txBufSize = pMlmAddBACnf->baBufferSize; + pSta->tcCfg[pMlmAddBACnf->baTID].tuTxBAWaitTimeout = pMlmAddBACnf->baTimeout; + } + } + // Free the memory allocated for LIM_MLM_ADDBA_CNF + vos_mem_free(pMsgBuf); + pMsgBuf = NULL; +} +/** + * \brief Process LIM_MLM_DELBA_CNF + * + * \sa limProcessMlmDelBACnf + * + * \param pMac The global tpAniSirGlobal object + * + * \param tSirMsgQ The MsgQ header containing the response buffer + * + * \return none + */ +void limProcessMlmDelBACnf( tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf ) +{ + tpLimMlmDelBACnf pMlmDelBACnf; + tpDphHashNode pSta; + tANI_U16 aid; +// tANI_U8 sessionId; + tLimBAState curBaState; + tpPESession psessionEntry; + + if(pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE,FL("Buffer is Pointing to NULL"));) + return; + } + pMlmDelBACnf = (tpLimMlmDelBACnf) pMsgBuf; + if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDelBACnf->sessionId))== NULL) + { + limLog(pMac, LOGP,FL("SessionId:%d Session Does not exist"), + pMlmDelBACnf->sessionId); + vos_mem_free(pMsgBuf); + return; + } + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pMlmDelBACnf->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable ); + if( NULL == pSta ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring DELBA CNF from HAL" )); + vos_mem_free(pMsgBuf); + return; + } + if(NULL == pMlmDelBACnf) + { + limLog( pMac, LOGE, + FL( "pMlmDelBACnf is NULL - ignoring DELBA CNF from HAL" )); + return; + } + // Need to validate baState + LIM_GET_STA_BA_STATE(pSta, pMlmDelBACnf->baTID, &curBaState); + if( eLIM_BA_STATE_WT_DEL_RSP != curBaState ) + { + limLog( pMac, LOGE, + FL( "Received unexpected DELBA CNF when STA BA state is %d" ), + curBaState ); + vos_mem_free(pMsgBuf); + return; + } + // Restore STA BA state + LIM_SET_STA_BA_STATE(pSta, pMlmDelBACnf->baTID, eLIM_BA_STATE_IDLE); + // Free the memory allocated for LIM_MLM_DELBA_CNF + vos_mem_free(pMsgBuf); +} +/** + * \brief Process SIR_LIM_DEL_BA_IND + * + * \sa limProcessMlmHalBADeleteInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param tSirMsgQ The MsgQ header containing the indication buffer + * + * \return none + */ +void limProcessMlmHalBADeleteInd( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpBADeleteParams pBADeleteParams; + tpDphHashNode pSta; + tANI_U16 aid; + tLimBAState curBaState; + tpPESession psessionEntry; + tANI_U8 sessionId; + + pBADeleteParams = (tpBADeleteParams) limMsgQ->bodyptr; + + if((psessionEntry = peFindSessionByBssid(pMac,pBADeleteParams->bssId,&sessionId))== NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given BSSId"));) + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return; + } + // First, extract the DPH entry + pSta = dphLookupHashEntry( pMac, pBADeleteParams->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable ); + if( NULL == pSta ) + { + limLog( pMac, LOGE, + FL( "STA context not found - ignoring BA Delete IND from HAL" )); + goto returnAfterCleanup; + } + + // Need to validate BA state + LIM_GET_STA_BA_STATE(pSta, pBADeleteParams->baTID, &curBaState); + if( eLIM_BA_STATE_IDLE != curBaState ) + { + limLog( pMac, LOGE, + FL( "Received unexpected BA Delete IND when STA BA state is %d" ), + curBaState ); + goto returnAfterCleanup; + } + + // Post DELBA REQ to MLME... + if( eSIR_SUCCESS != + (status = limPostMlmDelBAReq( pMac, + pSta, + pBADeleteParams->baDirection, + pBADeleteParams->baTID, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry ))) + { + limLog( pMac, LOGE, + FL( "Attempt to post LIM_MLM_DELBA_REQ failed with status %d" ), status); + } + else + { + limLog( pMac, LOGE, + FL( "BA Delete - Reason 0x%08x. Attempting to delete BA session for TID %d with peer STA " ), + pBADeleteParams->reasonCode, pBADeleteParams->baTID ); + limPrintMacAddr( pMac, pSta->staAddr, LOGE ); + } +returnAfterCleanup: + // Free the memory allocated for SIR_LIM_DEL_BA_IND + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; +} +/** + * @function : limProcessSetMimoRsp() + * + * @brief : This function is called upon receiving the WDA_SET_MIMOPS_RSP from the HAL + * after Processing the Req from the SME (PMC) + * + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Lim Message structure object with the MimoPSparam in body + * @return None + */ + +void +limProcessSetMimoRsp(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ +#if 0 + tSirRetStatus retStatus; + tpSetMIMOPS pMIMO_PSParams; + + + do { + + pMIMO_PSParams = (tpSetMIMOPS)limMsg->bodyptr; + if( NULL == pMIMO_PSParams ) { + PELOGE(limLog(pMac, LOGE, "Received the WDA_SET_MIMOPS_RSP with NULL as the PS param");) + return; + } + + /** If Updation of the HAL Fail's*/ + if (pMIMO_PSParams->status != eSIR_SUCCESS) { + limLog(pMac, LOGP, FL("Update HAL / SW Mac for MIMO State has Failed")); + break; + } + + if ((pMac->lim.gLimSystemRole != eSYSTEM_STA_ROLE) || + (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) ) + break; + + pMac->lim.gLimMlmState = pMac->lim.gLimPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, 0, pMac->lim.gLimMlmState)); + + /** In the Case of Exiting out of the Powersave (changing from Dynamic/Static mode to SM Enabled) + * send the action Frame to Peer to update the PS State of the STA , for the case of Entering PowerSave + * the Action Frame is being sent at first before setting the internal structures + */ + if (!isEnteringMimoPS(pMac->lim.gHTMIMOPSState, pMIMO_PSParams->htMIMOPSState)) { + tSirMacAddr macAddr; + + /** Obtain the AP's Mac Address */ + vos_mem_copy((tANI_U8 *)macAddr, pMac->lim.gLimBssid, sizeof(tSirMacAddr)); + + /** Send Action Frame with the corresponding mode */ + retStatus = limSendSMPowerStateFrame(pMac, macAddr, pMIMO_PSParams->htMIMOPSState); + if (retStatus != eSIR_SUCCESS) { + PELOGE(limLog(pMac, LOGE, FL("Sending Action Frame has failed"));) + break; + } + } + PELOG1(limLog(pMac, LOG1, FL("The Setting up of LimGlobals is successful for MIMOPS"));) + }while(0); + + vos_mem_free((void *) pMIMO_PSParams); +#endif +} +/** + * @function : limHandleDelBssInReAssocContext + * @brief : While Processing the ReAssociation Response Frame in STA, + * a. immediately after receiving the Reassoc Response the RxCleanUp is + * being issued and the end of DelBSS the new BSS is being added. + * + * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context + * change, We need to update CSR with ReAssocCNF Response with the + * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS + * context only + * + * @param : pMac - tpAniSirGlobal + * pStaDs - Station Descriptor + * + * @return : none + */ +static void +limHandleDelBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; + /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/ + /** Set the MlmState to IDLE*/ + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + /* Update PE session Id*/ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + switch (psessionEntry->limSmeState) { + case eLIM_SME_WT_REASSOC_STATE : + { + tpSirAssocRsp assocRsp; + tpDphHashNode pStaDs; + tSirRetStatus retStatus = eSIR_SUCCESS; + tpSchBeaconStruct pBeaconStruct; + pBeaconStruct = vos_mem_vmalloc(sizeof(tSchBeaconStruct)); + if (NULL == pBeaconStruct) + { + limLog(pMac, LOGE, FL("beaconStruct allocation failed")); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + limDeleteDphHashEntry(pMac, psessionEntry->bssId, + DPH_STA_HASH_INDEX_PEER, psessionEntry); + goto Error; + } + /** Delete the older STA Table entry */ + limDeleteDphHashEntry(pMac, psessionEntry->bssId, DPH_STA_HASH_INDEX_PEER, psessionEntry); + /** + * Add an entry for AP to hash table + * maintained by DPH module + */ + if ((pStaDs = dphAddHashEntry(pMac, psessionEntry->limReAssocbssId, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable)) == NULL) + { + // Could not add hash table entry + PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for "));) + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOGE); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS; + vos_mem_vfree(pBeaconStruct); + goto Error; + } + /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame + * is being stored to be used here for sending ADDBSS + */ + assocRsp = (tpSirAssocRsp)psessionEntry->limAssocResponseData; + limUpdateAssocStaDatas(pMac, pStaDs, assocRsp,psessionEntry); + limUpdateReAssocGlobals(pMac, assocRsp,psessionEntry); + limExtractApCapabilities( pMac, + (tANI_U8 *) + psessionEntry->pLimReAssocReq->bssDescription.ieFields, + GET_IE_LEN_IN_BSS( + psessionEntry->pLimReAssocReq->bssDescription.length), + pBeaconStruct); + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + if(pBeaconStruct->erpPresent) { + if (pBeaconStruct->erpIEInfo.barkerPreambleMode) + psessionEntry->beaconParams.fShortPreamble = 0; + else + psessionEntry->beaconParams.fShortPreamble = 1; + } + //updateBss flag is false, as in this case, PE is first deleting the existing BSS and then adding a new one. + if (eSIR_SUCCESS != limStaSendAddBss( pMac, assocRsp, pBeaconStruct, + &psessionEntry->pLimReAssocReq->bssDescription, false, psessionEntry)) { + limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed ")); + retStatus = eSIR_FAILURE; + } + if (retStatus != eSIR_SUCCESS) + { + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + vos_mem_free(assocRsp); + vos_mem_vfree(pBeaconStruct); + pMac->lim.gLimAssocResponseData = NULL; + goto Error; + } + vos_mem_free(assocRsp); + vos_mem_vfree(pBeaconStruct); + psessionEntry->limAssocResponseData = NULL; + } + break; + case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: + { + /** Case wherein the DisAssoc / Deauth + * being sent as response to ReAssoc Req*/ + /** Send the Reason code as the same received in Disassoc / Deauth Frame*/ + mlmReassocCnf.resultCode = pStaDs->mlmStaContext.disassocReason; + mlmReassocCnf.protStatusCode = pStaDs->mlmStaContext.cleanupTrigger; + /** Set the SME State back to WT_Reassoc State*/ + psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId,psessionEntry); + if((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + } + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); + } + break; + default: + PELOGE(limLog(pMac, LOGE, FL("DelBss is being invoked in the wrong system Role /unhandled SME State"));) + mlmReassocCnf.resultCode = eSIR_SME_REFUSED; + mlmReassocCnf.protStatusCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + goto Error; + } + return; +Error: + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} + +/* Added For BT -AMP Support */ +static void +limProcessBtampAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry) +{ + tLimMlmStartCnf mlmStartCnf; + tANI_U32 val; + tpAddBssParams pAddBssParams = (tpAddBssParams) limMsgQ->bodyptr; + + if (NULL == pAddBssParams) + { + limLog( pMac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + if( eHAL_STATUS_SUCCESS == pAddBssParams->status ) + { + limLog(pMac, LOG2, FL("WDA_ADD_BSS_RSP returned with eHAL_STATUS_SUCCESS")); + if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + if (limSetLinkState(pMac, eSIR_LINK_BTAMP_AP_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + } else if (psessionEntry->bssType == eSIR_BTAMP_STA_MODE) { + if (limSetLinkState(pMac, eSIR_LINK_SCAN_STATE, psessionEntry->bssId, + psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS ) + goto end; + } + + // Set MLME state + psessionEntry->limMlmState= eLIM_MLM_BSS_STARTED_STATE; + psessionEntry->statypeForBss = STA_ENTRY_SELF; // to know session started for peer or for self + psessionEntry->bssIdx = (tANI_U8) pAddBssParams->bssIdx; + schEdcaProfileUpdate(pMac, psessionEntry); + limInitPeerIdxpool(pMac,psessionEntry); + // Create timers used by LIM + if (!pMac->lim.gLimTimersCreated) + limCreateTimers(pMac); + /* Update the lim global gLimTriggerBackgroundScanDuringQuietBss */ + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TRIG_STA_BK_SCAN, &val )) + limLog( pMac, LOGP, FL("Failed to get WNI_CFG_TRIG_STA_BK_SCAN!")); + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss = (val) ? 1 : 0; + // Apply previously set configuration at HW + limApplyConfiguration(pMac,psessionEntry); + psessionEntry->staId = pAddBssParams->staContext.staIdx; + mlmStartCnf.resultCode = eSIR_SME_SUCCESS; + } + else + { + limLog( pMac, LOGE, FL( "WDA_ADD_BSS_REQ failed with status %d" ),pAddBssParams->status ); + mlmStartCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + mlmStartCnf.sessionId = psessionEntry->peSessionId; + limPostSmeMessage( pMac, LIM_MLM_START_CNF, (tANI_U32 *) &mlmStartCnf ); + end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_zero(pAddBssParams, sizeof(tAddBssParams)); + vos_mem_free(pAddBssParams); + limMsgQ->bodyptr = NULL; + } +} + +/** + * @function : limHandleAddBssInReAssocContext + * @brief : While Processing the ReAssociation Response Frame in STA, + * a. immediately after receiving the Reassoc Response the RxCleanUp is + * being issued and the end of DelBSS the new BSS is being added. + * + * b .If an AP rejects the ReAssociation (Disassoc / Deauth) with some context + * change, We need to update CSR with ReAssocCNF Response with the + * ReAssoc Fail and the reason Code, that is also being handled in the DELBSS + * context only + * + * @param : pMac - tpAniSirGlobal + * pStaDs - Station Descriptor + * + * @return : none + */ +void +limHandleAddBssInReAssocContext(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; + /** Skipped the DeleteDPH Hash Entry as we need it for the new BSS*/ + /** Set the MlmState to IDLE*/ + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + switch (psessionEntry->limSmeState) { + case eLIM_SME_WT_REASSOC_STATE : { + tpSirAssocRsp assocRsp; + tpDphHashNode pStaDs; + tSirRetStatus retStatus = eSIR_SUCCESS; + tSchBeaconStruct *pBeaconStruct; + pBeaconStruct = vos_mem_malloc(sizeof(tSchBeaconStruct)); + if ( NULL == pBeaconStruct ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limHandleAddBssInReAssocContext") ); + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto Error; + } + + // Get the AP entry from DPH hash table + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL("Fail to get STA PEER entry from hash"));) + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_SME_SUCCESS; + vos_mem_free(pBeaconStruct); + goto Error; + } + /** While Processing the ReAssoc Response Frame the ReAssocRsp Frame + * is being stored to be used here for sending ADDBSS + */ + assocRsp = (tpSirAssocRsp)psessionEntry->limAssocResponseData; + limUpdateAssocStaDatas(pMac, pStaDs, assocRsp, psessionEntry); + limUpdateReAssocGlobals(pMac, assocRsp, psessionEntry); + limExtractApCapabilities(pMac, + (tANI_U8 *) + psessionEntry->pLimReAssocReq->bssDescription.ieFields, + GET_IE_LEN_IN_BSS( + psessionEntry->pLimReAssocReq->bssDescription.length), + pBeaconStruct); + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideStaProtectionOnAssoc(pMac, pBeaconStruct, psessionEntry); + + if(pBeaconStruct->erpPresent) + { + if (pBeaconStruct->erpIEInfo.barkerPreambleMode) + psessionEntry->beaconParams.fShortPreamble = 0; + else + psessionEntry->beaconParams.fShortPreamble = 1; + } + + if (eSIR_SUCCESS != limStaSendAddBss( pMac, assocRsp, pBeaconStruct, + &psessionEntry->pLimReAssocReq->bssDescription, true, psessionEntry)) { + limLog( pMac, LOGE, FL( "Posting ADDBSS in the ReAssocContext has Failed ")); + retStatus = eSIR_FAILURE; + } + if (retStatus != eSIR_SUCCESS) + { + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + vos_mem_free(assocRsp); + pMac->lim.gLimAssocResponseData = NULL; + vos_mem_free(pBeaconStruct); + goto Error; + } + vos_mem_free(assocRsp); + psessionEntry->limAssocResponseData = NULL; + vos_mem_free(pBeaconStruct); + } + break; + case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: { /** Case wherein the DisAssoc / Deauth + * being sent as response to ReAssoc Req*/ + /** Send the Reason code as the same received in Disassoc / Deauth Frame*/ + mlmReassocCnf.resultCode = pStaDs->mlmStaContext.disassocReason; + mlmReassocCnf.protStatusCode = pStaDs->mlmStaContext.cleanupTrigger; + /** Set the SME State back to WT_Reassoc State*/ + psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry); + if(psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + } + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); + } + break; + default: + PELOGE(limLog(pMac, LOGE, FL("DelBss is being invoked in the wrong system Role /unhandled SME State"));) + mlmReassocCnf.resultCode = eSIR_SME_REFUSED; + mlmReassocCnf.protStatusCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + goto Error; + } +return; +Error: + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} + +#if 0 + static void +limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + tSirSmeAssocCnf assocCnf; + tpDphHashNode pStaDs; + tpPESession psessionEntry; + tANI_U8 sessionId; + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE, FL("pMsgBuf is NULL ")); + goto end; + } + if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + !__limIsSmeAssocCnfValid(&assocCnf)) + { + limLog(pMac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message ")); + goto end; + } + if((psessionEntry = peFindSessionByBssid(pMac, assocCnf.bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given bssId")); + goto end; + } + if ( ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) || + ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) && (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) + { + limLog(pMac, LOGE, FL("Received unexpected message %X in state %X, in role %X"), + msgType, psessionEntry->limSmeState , psessionEntry->limSystemRole); + goto end; + } + pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + limLog(pMac, LOG1, + FL("Received invalid message %X due to no STA context, for aid %d, peer "), + msgType, assocCnf.aid); + limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1); + /* + ** send a DISASSOC_IND message to WSM to make sure + ** the state in WSM and LIM is the same + **/ + limSendSmeDisassocNtf( pMac, assocCnf.peerMacAddr, eSIR_SME_STA_NOT_ASSOCIATED, + eLIM_PEER_ENTITY_DISASSOC, assocCnf.aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + goto end; + } + if ((pStaDs && + (( !vos_mem_compare((tANI_U8 *) pStaDs->staAddr, + (tANI_U8 *) assocCnf.peerMacAddr, + sizeof(tSirMacAddr)) ) || + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) || + ((pStaDs->mlmStaContext.subType == LIM_ASSOC) && + (msgType != eWNI_SME_ASSOC_CNF)) || + ((pStaDs->mlmStaContext.subType == LIM_REASSOC) && + (msgType != eWNI_SME_REASSOC_CNF))))) + { + limLog(pMac, LOG1, + FL("Received invalid message %X due to peerMacAddr mismatched or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer "), + msgType, assocCnf.aid); + limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1); + goto end; + } + /* + ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF + ** has been received + **/ + limLog(pMac, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer")); + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, pStaDs->assocId); + if (assocCnf.statusCode == eSIR_SME_SUCCESS) + { + /* In BTAMP-AP, PE already finished the WDA_ADD_STA sequence + * when it had received Assoc Request frame. Now, PE just needs to send + * Association Response frame to the requesting BTAMP-STA. + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) "), pStaDs->assocId); + limSendAssocRspMgmtFrame( pMac, eSIR_SUCCESS, pStaDs->assocId, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, pStaDs, psessionEntry); + goto end; + } // (assocCnf.statusCode == eSIR_SME_SUCCESS) + else + { + // SME_ASSOC_CNF status is non-success, so STA is not allowed to be associated + limRejectAssociation(pMac, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + assocCnf.statusCode, psessionEntry); + return; + } +end: + if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL ) + { + if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame) + { + vos_mem_free(((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL; + } + + vos_mem_free(psessionEntry->parsedAssocReq[pStaDs->assocId]); + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } +} /*** end __limProcessSmeAssocCnfNew() ***/ +#endif + +void +limSendBeaconInd(tpAniSirGlobal pMac, tpPESession psessionEntry){ + tBeaconGenParams *pBeaconGenParams = NULL; + tSirMsgQ limMsg; + /** Allocate the Memory for Beacon Pre Message and for Stations in PoweSave*/ + if(psessionEntry == NULL ){ + PELOGE( limLog( pMac, LOGE, + FL( "Error:Unable to get the PESessionEntry" ));) + return; + } + pBeaconGenParams = vos_mem_malloc(sizeof(*pBeaconGenParams)); + if ( NULL == pBeaconGenParams ) + { + PELOGE( limLog( pMac, LOGP, + FL( "Unable to allocate memory during sending beaconPreMessage" ));) + return; + } + vos_mem_set(pBeaconGenParams, sizeof(*pBeaconGenParams), 0); + vos_mem_copy((void *) pBeaconGenParams->bssId, + (void *)psessionEntry->bssId, + SIR_MAC_ADDR_LENGTH ); + limMsg.bodyptr = pBeaconGenParams; + schProcessPreBeaconInd(pMac, &limMsg); + return; +} + +void limSendScanOffloadComplete(tpAniSirGlobal pMac, + tSirResultCodes reasonCode) +{ + tANI_U16 scanRspLen = 0; + + pMac->lim.gLimSmeScanResultLength += + pMac->lim.gLimMlmScanResultLength; + pMac->lim.gLimRspReqd = false; + if ((reasonCode == eSIR_SME_SUCCESS) || + pMac->lim.gLimSmeScanResultLength) { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + } + else + scanRspLen = sizeof(tSirSmeScanRsp); + + limSendSmeScanRsp(pMac, scanRspLen, reasonCode, + pMac->lim.gSmeSessionId, + pMac->lim.gTransactionId); +} + + +void limProcessRxScanEvent(tpAniSirGlobal pMac, void *buf) +{ + tSirScanOffloadEvent *pScanEvent = (tSirScanOffloadEvent *) buf; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "scan_id = %u", pScanEvent->scanId); + + switch (pScanEvent->event) + { + case SCAN_EVENT_STARTED: + break; + case SCAN_EVENT_START_FAILED: + case SCAN_EVENT_COMPLETED: + limSendScanOffloadComplete(pMac, pScanEvent->reasonCode); + break; + case SCAN_EVENT_BSS_CHANNEL: + case SCAN_EVENT_FOREIGN_CHANNEL: + case SCAN_EVENT_DEQUEUED: + case SCAN_EVENT_PREEMPTED: + default: + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, + "Received unhandled scan event %u", pScanEvent->event); + } +} + +void limProcessMlmSpoofMacAddrRsp(tpAniSirGlobal pMac, tSirRetStatus rspStatus) +{ + tANI_U32 val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MAC_ADDR_SPOOFING, &val) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("fail to Get WNI_CFG_ENABLE_MAC_ADDR_SPOOFING")); + /*If we here means mac spoofing is enable. So enable both Host and + FW spoofing */ + val = 1; + } + if ((rspStatus != eSIR_SUCCESS) || (val != 1) || + (TRUE == vos_is_macaddr_zero((v_MACADDR_t *)&pMac->lim.spoofMacAddr))) + { + limLog(pMac, LOG1, FL(" LIM Disabling Spoofing %d"), val); + pMac->lim.isSpoofingEnabled = FALSE; + } else { + limLog(pMac, LOG1, FL(" LIM Enabling Spoofing")); + pMac->lim.isSpoofingEnabled = TRUE; + } + + return; +} + +void limSwitchChannelResumeLinkRsp(tpAniSirGlobal pMac, + eHalStatus status, + tANI_U32* mlmAddBssRsp) +{ + if (status != eHAL_STATUS_SUCCESS) + { + limLog(pMac, LOGE, + FL(" CSA failed to get the response for resume link")); + } + return; +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c new file mode 100644 index 000000000000..a3d8ef423d58 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeReqFrame.c @@ -0,0 +1,851 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limProcessProbeReqFrame.cc contains the code + * for processing Probe Request Frame. + * Author: Chandra Modumudi + * Date: 02/28/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniCfg.h" +#include "aniGlobal.h" +#include "cfgApi.h" + +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSerDesUtils.h" +#include "parserApi.h" +#include "limSession.h" + +#ifdef WLAN_FEATURE_P2P_INTERNAL +void limSendP2PProbeResponse(tpAniSirGlobal pMac, tANI_U8 *pBd, + tpPESession psessionEntry); +#endif +void + +limSendSmeProbeReqInd(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tANI_U8 *pProbeReqIE, + tANI_U32 ProbeReqIELen, + tpPESession psessionEntry); + +/** + * limGetWPSPBCSessions + * + *FUNCTION: + * This function is called to query the WPS PBC overlap + * + *LOGIC: + * This function check WPS PBC probe request link list for PBC overlap + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param addr A pointer to probe request source MAC addresss + * @param uuid_e A pointer to UUIDE element of WPS IE in WPS PBC probe request + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +void limGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U8 *addr, + tANI_U8 *uuid_e, eWPSPBCOverlap *overlap, + tpPESession psessionEntry) +{ + int count = 0; + tSirWPSPBCSession *pbc; + tANI_TIMESTAMP curTime; + + curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND); + + vos_mem_set((tANI_U8 *)addr, sizeof(tSirMacAddr), 0); + vos_mem_set((tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN, 0); + + for (pbc = psessionEntry->pAPWPSPBCSession; pbc; pbc = pbc->next) { + + if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) + break; + + count++; + if(count > 1) + break; + + vos_mem_copy((tANI_U8 *)addr, (tANI_U8 *)pbc->addr, sizeof(tSirMacAddr)); + vos_mem_copy((tANI_U8 *)uuid_e, (tANI_U8 *)pbc->uuid_e, SIR_WPS_UUID_LEN); + } + + if (count > 1) + { + *overlap = eSAP_WPSPBC_OVERLAP_IN120S; // Overlap + } + else if(count == 0) + { + *overlap = eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S; // no WPS probe request in 120 second + } else + { + *overlap = eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S; // One WPS probe request in 120 second + } + + PELOGE(limLog(pMac, LOGE, FL("overlap = %d"), *overlap);) + PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, addr, sizeof(tSirMacAddr));) + PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, uuid_e, SIR_WPS_UUID_LEN);) + + return; +} + +/** + * limRemoveTimeoutPBCsessions + * + *FUNCTION: + * This function is called to remove the WPS PBC probe request entires from specific entry to end. + * + *LOGIC: + * + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pbc The beginning entry in WPS PBC probe request link list + * + * @return None + */ +static void limRemoveTimeoutPBCsessions(tpAniSirGlobal pMac, tSirWPSPBCSession *pbc) +{ + tSirWPSPBCSession *prev; + + while (pbc) { + prev = pbc; + pbc = pbc->next; + + PELOG4(limLog(pMac, LOG4, FL("WPS PBC sessions remove"));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, prev->addr, sizeof(tSirMacAddr));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, prev->uuid_e, SIR_WPS_UUID_LEN);) + + vos_mem_free(prev); + } +} + +void limRemovePBCSessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,tpPESession psessionEntry) +{ + tSirWPSPBCSession *pbc, *prev = NULL; + prev = pbc = psessionEntry->pAPWPSPBCSession; + + while (pbc) { + if (vos_mem_compare((tANI_U8 *)pbc->addr, + (tANI_U8 *)pRemoveMac, sizeof(tSirMacAddr))) { + prev->next = pbc->next; + if (pbc == psessionEntry->pAPWPSPBCSession) + psessionEntry->pAPWPSPBCSession = pbc->next; + vos_mem_free(pbc); + return; + } + prev = pbc; + pbc = pbc->next; + } + +} + +/** + * limUpdatePBCSessionEntry + * + *FUNCTION: + * This function is called when probe request with WPS PBC IE is received + * + *LOGIC: + * This function add the WPS PBC probe request in the WPS PBC probe request link list + * The link list is in decreased time order of probe request that is received. + * The entry that is more than 120 second is removed. + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param addr A pointer to probe request source MAC addresss + * @param uuid_e A pointer to UUIDE element of WPS IE + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +static void limUpdatePBCSessionEntry(tpAniSirGlobal pMac, + tANI_U8 *addr, tANI_U8 *uuid_e, + tpPESession psessionEntry) +{ + tSirWPSPBCSession *pbc, *prev = NULL; + + tANI_TIMESTAMP curTime; + + curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND); + + PELOG4(limLog(pMac, LOG4, FL("Receive WPS probe reques curTime=%d"), curTime);) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, addr, sizeof(tSirMacAddr));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, uuid_e, SIR_WPS_UUID_LEN);) + + pbc = psessionEntry->pAPWPSPBCSession; + + while (pbc) { + if (vos_mem_compare((tANI_U8 *)pbc->addr, (tANI_U8 *)addr, sizeof(tSirMacAddr)) && + vos_mem_compare((tANI_U8 *)pbc->uuid_e, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN)) { + if (prev) + prev->next = pbc->next; + else + psessionEntry->pAPWPSPBCSession = pbc->next; + break; + } + prev = pbc; + pbc = pbc->next; + } + + if (!pbc) { + pbc = vos_mem_malloc(sizeof(tSirWPSPBCSession)); + if ( NULL == pbc ) + { + PELOGE(limLog(pMac, LOGE, FL("memory allocate failed!"));) + return; + } + vos_mem_copy((tANI_U8 *)pbc->addr, (tANI_U8 *)addr, sizeof(tSirMacAddr)); + + if (uuid_e) + vos_mem_copy((tANI_U8 *)pbc->uuid_e, (tANI_U8 *)uuid_e, SIR_WPS_UUID_LEN); + } + + pbc->next = psessionEntry->pAPWPSPBCSession; + psessionEntry->pAPWPSPBCSession = pbc; + pbc->timestamp = curTime; + + /* remove entries that have timed out */ + prev = pbc; + pbc = pbc->next; + + while (pbc) { + if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) { + prev->next = NULL; + limRemoveTimeoutPBCsessions(pMac, pbc); + break; + } + prev = pbc; + pbc = pbc->next; + } +} +#if 0 +/** + * limWPSPBCTimeout + * + *FUNCTION: + * This function is called when WPS PBC enrtries clean up timer is expired + * + *LOGIC: + * This function remove all the entryies that more than 120 second old + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_TIMESTAMP curTime; + tSirWPSPBCSession *pbc, *prev = NULL; + + curTime = (tANI_TIMESTAMP)(palGetTickCount(pMac->hHdd) / PAL_TICKS_PER_SECOND); + + PELOG3(limLog(pMac, LOG3, FL("WPS PBC cleanup timeout curTime=%d"), curTime);) + + prev = psessionEntry->pAPWPSPBCSession; + if(prev) + pbc = prev->next; + else + return; + + while (pbc) { + if (curTime > pbc->timestamp + SIR_WPS_PBC_WALK_TIME) { + prev->next = NULL; + limRemoveTimeoutPBCsessions(pMac, pbc); + break; + } + prev = pbc; + pbc = pbc->next; + } + + if(prev) + { + if (curTime > prev->timestamp + SIR_WPS_PBC_WALK_TIME) { + psessionEntry->pAPWPSPBCSession = NULL; + limRemoveTimeoutPBCsessions(pMac, prev); + } + } + +} +#endif +/** + * limWPSPBCClose + * + *FUNCTION: + * This function is called when BSS is closed + * + *LOGIC: + * This function remove all the WPS PBC entries + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param psessionEntry A pointer to station PE session + * + * @return None + */ + +void limWPSPBCClose(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + limRemoveTimeoutPBCsessions(pMac, psessionEntry->pAPWPSPBCSession); + +} + +/** + * limCheck11bRates + * + *FUNCTION: + * This function is called by limProcessProbeReqFrame() upon + * Probe Request frame reception. + * + *LOGIC: + * This function check 11b rates in supportedRates and extendedRates rates + * + *NOTE: + * + * @param rate + * + * @return BOOLEAN + */ + +tANI_BOOLEAN limCheck11bRates(tANI_U8 rate) +{ + if ( ( 0x02 == (rate)) + || ( 0x04 == (rate)) + || ( 0x0b == (rate)) + || ( 0x16 == (rate)) + ) + { + return TRUE; + } + return FALSE; +} + +/** + * limProcessProbeReqFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Probe Request frame reception. + * + *LOGIC: + * This function processes received Probe Request frame and responds + * with Probe Response. + * Only AP or STA in IBSS mode that sent last Beacon will respond to + * Probe Request. + * + *ASSUMPTIONS: + * 1. AP or STA in IBSS mode that sent last Beacon will always respond + * to Probe Request received with broadcast SSID. + * + *NOTE: + * 1. Dunno what to do with Rates received in Probe Request frame + * 2. Frames with out-of-order fields/IEs are dropped. + * + * @param pMac Pointer to Global MAC structure + * @param *pRxPacketInfo A pointer to Buffer descriptor + associated PDUs + * + * @return None + */ + +void +limProcessProbeReqFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tSirProbeReq probeReq; + tAniSSID ssId; + tSirMsgQ msgQ; + tSirSmeProbeReq *pSirSmeProbeReq; + tANI_U32 wpsApEnable=0, tmp; + + do{ + // Don't send probe responses if disabled + if (pMac->lim.gLimProbeRespDisableFlag) + break; + + // Don't send probe response if P2P go is scanning till scan come to idle state. + if((psessionEntry->pePersona == VOS_P2P_GO_MODE) && ((pMac->lim.gpLimRemainOnChanReq ) + || (pMac->lim.gLimHalScanState != eLIM_HAL_IDLE_SCAN_STATE))) + { + limLog(pMac, LOG3, + FL("While GO is scanning, don't send probe response" + " on diff channel")); + break; + } + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)|| + ( (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (WDA_GET_RX_BEACON_SENT(pRxPacketInfo)) ) ) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + PELOG3(limLog(pMac, LOG3, FL("Received Probe Request %d bytes from "), frameLen); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + + // Get pointer to Probe Request frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + // Parse Probe Request frame + if (sirConvertProbeReqFrame2Struct(pMac, pBody, frameLen, &probeReq)==eSIR_FAILURE) + { + PELOGW(limLog(pMac, LOGE, FL("Parse error ProbeRequest," + " length=%d, SA is:" MAC_ADDRESS_STR), + frameLen,MAC_ADDR_ARRAY(pHdr->sa));) + pMac->sys.probeError++; + break; + } + else + { + if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + tANI_U8 i = 0, rate_11b = 0, other_rates = 0; + // Check 11b rates in supported rates + for ( i = 0 ; i < probeReq.supportedRates.numRates; + i++ ) + { + if (limCheck11bRates(probeReq.supportedRates.rate[i] & 0x7f)) + { + rate_11b++; + } + else + { + other_rates++; + } + } + + // Check 11b rates in extended rates + for ( i = 0 ; i < probeReq.extendedRates.numRates; i++ ) + { + if (limCheck11bRates(probeReq.extendedRates.rate[i] & 0x7f)) + { + rate_11b++; + } + else + { + other_rates++; + } + } + + if ( (rate_11b > 0) && (other_rates == 0) ) + { + PELOG3(limLog(pMac, LOG3, + FL("Received a probe request frame with only 11b rates, SA is: ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + return; + } + } + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + + if ( (psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent & + SIR_WPS_PROBRSP_VER_PRESENT) && + (probeReq.wscIePresent == 1) && + (probeReq.probeReqWscIeInfo.DevicePasswordID.id == + WSC_PASSWD_ID_PUSH_BUTTON) && + (probeReq.probeReqWscIeInfo.UUID_E.present == 1)) + { + if(psessionEntry->fwdWPSPBCProbeReq) + { + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, + pHdr->sa, sizeof(tSirMacAddr));) + PELOG4(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBody, frameLen);) + limSendSmeProbeReqInd(pMac, pHdr->sa, pBody, frameLen, psessionEntry); + } + else + { + limUpdatePBCSessionEntry(pMac, + pHdr->sa, probeReq.probeReqWscIeInfo.UUID_E.uuid, psessionEntry); + } + } + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE ); + + wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP; + if ((wpsApEnable) && + (probeReq.wscIePresent == 1) && + (probeReq.probeReqWscIeInfo.DevicePasswordID.id == WSC_PASSWD_ID_PUSH_BUTTON)) + { + // send the probe req to WSM when it is from a PBC station + pSirSmeProbeReq = vos_mem_malloc(sizeof(tSirSmeProbeReq)); + if ( NULL == pSirSmeProbeReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_PROBE_REQ")); + return; + } + msgQ.type = eWNI_SME_PROBE_REQ; + msgQ.bodyval = 0; + msgQ.bodyptr = pSirSmeProbeReq; + + pSirSmeProbeReq->messageType = eWNI_SME_PROBE_REQ; + pSirSmeProbeReq->length = sizeof(tSirSmeProbeReq); + pSirSmeProbeReq->sessionId = psessionEntry->smeSessionId; + vos_mem_copy(pSirSmeProbeReq->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr)); + pSirSmeProbeReq->devicePasswdId = probeReq.probeReqWscIeInfo.DevicePasswordID.id; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, + psessionEntry->peSessionId, msgQ.type)); + if (limSysProcessMmhMsgApi(pMac, &msgQ, ePROT) != eSIR_SUCCESS){ + PELOG3(limLog(pMac, LOG3, FL("couldnt send the probe req to wsm "));) + } + } + } + } + + ssId.length = psessionEntry->ssId.length; + /* Copy the SSID from sessio entry to local variable */ + vos_mem_copy(ssId.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + + // Compare received SSID with current SSID. If they + // match, reply with Probe Response. + if (probeReq.ssId.length) + { + if (!ssId.length) + goto multipleSSIDcheck; + + if (vos_mem_compare((tANI_U8 *) &ssId, + (tANI_U8 *) &(probeReq.ssId), (tANI_U8) (ssId.length + 1)) ) + { + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, + DPH_NON_KEEPALIVE_FRAME, psessionEntry, + probeReq.p2pIePresent); + break; + } + else if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + tANI_U8 direct_ssid[7] = "DIRECT-"; + tANI_U8 direct_ssid_len = 7; + if (vos_mem_compare((tANI_U8 *) &direct_ssid, + (tANI_U8 *) &(probeReq.ssId.ssId), (tANI_U8) (direct_ssid_len)) ) + { + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, + DPH_NON_KEEPALIVE_FRAME, psessionEntry, + probeReq.p2pIePresent); + break; + } + } + else + { + PELOG3(limLog(pMac, LOG3, + FL("Ignoring ProbeReq frame with unmatched SSID received from ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + pMac->sys.probeBadSsid++; + } + } + else + { + { + if ((VOS_P2P_GO_MODE == psessionEntry->pePersona) && + pMac->miracastVendorConfig) + return; + + // Broadcast SSID in the Probe Request. + // Reply with SSID we're configured with. + //Turn off the SSID length to 0 if hidden SSID feature is present + if(psessionEntry->ssidHidden) + /*We are returning from here as probe request contains the broadcast SSID. + So no need to send the probe resp*/ + //ssId.length = 0; + return; + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, + DPH_NON_KEEPALIVE_FRAME, psessionEntry, + probeReq.p2pIePresent); + } + break; + } +multipleSSIDcheck: + { + PELOG3(limLog(pMac, LOG3, + FL("Ignoring ProbeReq frame with unmatched SSID received from ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + pMac->sys.probeBadSsid++; + } + } + else + { + // Ignore received Probe Request frame + PELOG3(limLog(pMac, LOG3, FL("Ignoring Probe Request frame received from ")); + limPrintMacAddr(pMac, pHdr->sa, LOG3);) + pMac->sys.probeIgnore++; + break; + } + }while(0); + + return; +} /*** end limProcessProbeReqFrame() ***/ + +/** + * limIndicateProbeReqToHDD + * + *FUNCTION: + * This function is called by limProcessProbeReqFrame_multiple_BSS() upon + * Probe Request frame reception. + * + *LOGIC: + * This function processes received Probe Request frame and Pass + * Probe Request Frame to HDD. + * + * @param pMac Pointer to Global MAC structure + * @param *pBd A pointer to Buffer descriptor + associated PDUs + * @param psessionEntry A pointer to PE session + * + * @return None + */ + +static void +limIndicateProbeReqToHDD(tpAniSirGlobal pMac, tANI_U8 *pBd, + tpPESession psessionEntry) +{ + limLog( pMac, LOG1, FL("Received a probe request frame")); + + //send the probe req to SME. + limSendSmeMgmtFrameInd( pMac, psessionEntry->smeSessionId, pBd, + psessionEntry, WDA_GET_RX_RSSI_DB(pBd)); +#ifdef WLAN_FEATURE_P2P_INTERNAL + limSendP2PProbeResponse(pMac, pBd, psessionEntry); +#endif +} /*** end limIndicateProbeReqToHDD() ***/ + +/** + * limProcessProbeReqFrame_multiple_BSS + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Probe Request frame reception. + * + *LOGIC: + * This function call limIndicateProbeReqToHDD function to indicate + * Probe Request frame to HDD. It also call limProcessProbeReqFrame + * function which process received Probe Request frame and responds + * with Probe Response. + * + * @param pMac Pointer to Global MAC structure + * @param *pBd A pointer to Buffer descriptor + associated PDUs + * @param psessionEntry A pointer to PE session + * + * @return None + */ + +void +limProcessProbeReqFrame_multiple_BSS(tpAniSirGlobal pMac, tANI_U8 *pBd, tpPESession psessionEntry) +{ + tANI_U8 i; + + if (psessionEntry != NULL) + { + if ((eLIM_AP_ROLE == psessionEntry->limSystemRole) +#ifdef WLAN_FEATURE_P2P_INTERNAL + || (psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE) +#endif + ) + { + limIndicateProbeReqToHDD(pMac, pBd, psessionEntry); + } + limProcessProbeReqFrame(pMac,pBd,psessionEntry); + return; + } + + for(i =0; i < pMac->lim.maxBssId;i++) + { + psessionEntry = peFindSessionBySessionId(pMac,i); + if ( (psessionEntry != NULL) ) + { + if ((eLIM_AP_ROLE == psessionEntry->limSystemRole) +#ifdef WLAN_FEATURE_P2P_INTERNAL + || (psessionEntry->limSystemRole == eLIM_P2P_DEVICE_ROLE) +#endif + ) + { + limIndicateProbeReqToHDD(pMac, pBd, psessionEntry); + } + if ( (eLIM_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) || + (eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) || + (eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole) + ) + { + limProcessProbeReqFrame(pMac,pBd,psessionEntry); + } + } + } + +} /*** end limProcessProbeReqFrame_multiple_BSS() ***/ + +/** + * limSendSmeProbeReqInd() + * + *FUNCTION: + * This function is to send + * eWNI_SME_WPS_PBC_PROBE_REQ_IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_WPS_PBC_PROBE_REQ_IND + * to host. + * + * @param peerMacAddr Indicates the peer MAC addr that the probe request + * is generated. + * @param pProbeReqIE pointer to RAW probe request IE + * @param ProbeReqIELen The length of probe request IE. + * @param psessionEntry A pointer to PE session + * + * @return None + */ +void +limSendSmeProbeReqInd(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tANI_U8 *pProbeReqIE, + tANI_U32 ProbeReqIELen, + tpPESession psessionEntry) +{ + tSirSmeProbeReqInd *pSirSmeProbeReqInd; + tSirMsgQ msgQ; + + pSirSmeProbeReqInd = vos_mem_malloc(sizeof(tSirSmeProbeReqInd)); + if ( NULL == pSirSmeProbeReqInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_PROBE_REQ")); + return; + } + + msgQ.type = eWNI_SME_WPS_PBC_PROBE_REQ_IND; + msgQ.bodyval = 0; + msgQ.bodyptr = pSirSmeProbeReqInd; + + pSirSmeProbeReqInd->messageType = eWNI_SME_WPS_PBC_PROBE_REQ_IND; + pSirSmeProbeReqInd->length = sizeof(tSirSmeProbeReq); + pSirSmeProbeReqInd->sessionId = psessionEntry->smeSessionId; + + vos_mem_copy(pSirSmeProbeReqInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + vos_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.peerMacAddr, peerMacAddr, sizeof(tSirMacAddr)); + + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, psessionEntry->peSessionId, + msgQ.type)); + pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIELen = (tANI_U16)ProbeReqIELen; + vos_mem_copy(pSirSmeProbeReqInd->WPSPBCProbeReq.probeReqIE, pProbeReqIE, ProbeReqIELen); + + if (limSysProcessMmhMsgApi(pMac, &msgQ, ePROT) != eSIR_SUCCESS){ + PELOGE(limLog(pMac, LOGE, FL("couldnt send the probe req to hdd"));) + } + +} /*** end limSendSmeProbeReqInd() ***/ +#ifdef WLAN_FEATURE_P2P_INTERNAL +void limSendP2PProbeResponse(tpAniSirGlobal pMac, tANI_U8 *pBd, + tpPESession psessionEntry) +{ + tAniSSID ssId = { P2P_WILDCARD_SSID_LEN, P2P_WILDCARD_SSID }; + tANI_U8 *pBody; + tpSirMacMgmtHdr pHdr; + tANI_U32 frameLen; + tSirProbeReq probeReq; + + pHdr = WDA_GET_RX_MAC_HEADER(pBd); + // Get pointer to Probe Request frame body + pBody = WDA_GET_RX_MPDU_DATA(pBd); + + if( (pBody[0] == 0) && (pBody[1] == ssId.length) && + (vos_mem_compare(ssId.ssId, pBody + 2, + ssId.length))) + { + // Parse Probe Request frame + frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd); + if (eSIR_FAILURE == sirConvertProbeReqFrame2Struct(pMac, pBody, frameLen, &probeReq)) + { + PELOGW(limLog(pMac, LOGW, FL("Parse error ProbeRequest, length=%d, SA is:"), frameLen);) + limPrintMacAddr(pMac, pHdr->sa, LOGW); + pMac->sys.probeError++; + return; + } + + if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + ssId.length = psessionEntry->ssId.length; + vos_mem_copy(ssId.ssId, psessionEntry->ssId.ssId,psessionEntry->ssId.length); + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, DPH_NON_KEEPALIVE_FRAME, + psessionEntry, probeReq.p2pIePresent ); + } + else + { + limSendProbeRspMgmtFrame(pMac, pHdr->sa, &ssId, DPH_USE_MGMT_STAID, DPH_NON_KEEPALIVE_FRAME, + psessionEntry, probeReq.p2pIePresent ); + } + } +} +#endif //#ifdef WLAN_FEATURE_P2P_INTERNAL diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c new file mode 100644 index 000000000000..528ce8bdfeae --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessProbeRspFrame.c @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limProcessProbeRspFrame.cc contains the code + * for processing Probe Response Frame. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniApi.h" +#include "wniCfg.h" +#include "aniGlobal.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" +#include "limSendMessages.h" + +#include "parserApi.h" + +tSirRetStatus +limValidateIEInformationInProbeRspFrame (tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo) +{ + tSirRetStatus status = eSIR_SUCCESS; + tANI_U8 *pFrame; + tANI_U32 nFrame; + tANI_U32 nMissingRsnBytes; + + /* Validate a Probe response frame for malformed frame. + * If the frame is malformed then do not consider as it + * may cause problem fetching wrong IE values + */ + if (WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) < (SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN)) + { + return eSIR_FAILURE; + } + + pFrame = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + nFrame = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + nMissingRsnBytes = 0; + + status = ValidateAndRectifyIEs(pMac, pFrame, nFrame, &nMissingRsnBytes); + if ( status == eSIR_SUCCESS ) + { + WDA_GET_RX_MPDU_LEN(pRxPacketInfo) += nMissingRsnBytes; + } + + return status; +} + +/** + * limProcessProbeRspFrame + * + *FUNCTION: + * This function is called by limProcessMessageQueue() upon + * Probe Response frame reception. + * + *LOGIC: + * This function processes received Probe Response frame. + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Frames with out-of-order IEs are dropped. + * 2. In case of IBSS, join 'success' makes MLM state machine + * transition into 'BSS started' state. This may have to change + * depending on supporting what kinda Authentication in IBSS. + * + * @param pMac Pointer to Global MAC structure + * @param *pRxPacketInfo A pointer to Buffer descriptor + associated PDUs + * @return None + */ + + +void +limProcessProbeRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession psessionEntry) +{ + tANI_U8 *pBody; + tANI_U32 frameLen = 0; + tSirMacAddr currentBssId; + tpSirMacMgmtHdr pHdr; + tSirProbeRespBeacon *pProbeRsp; + tANI_U8 qosEnabled = false; + tANI_U8 wmeEnabled = false; + + if (!psessionEntry) + { + limLog(pMac, LOGE, FL("psessionEntry is NULL") ); + return; + } + limLog(pMac,LOG1,"SessionId:%d ProbeRsp Frame is received", + psessionEntry->peSessionId); + + + pProbeRsp = vos_mem_vmalloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pProbeRsp ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessProbeRspFrame") ); + return; + } + + pProbeRsp->ssId.length = 0; + pProbeRsp->wpa.length = 0; + pProbeRsp->propIEinfo.apName.length = 0; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + + limLog(pMac, LOG2, + FL("Received Probe Response frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2); + + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + { + vos_mem_vfree(pProbeRsp); + return; + } + } + + // Validate IE information before processing Probe Response Frame + if (limValidateIEInformationInProbeRspFrame(pMac, pRxPacketInfo) + != eSIR_SUCCESS) + { + PELOG1(limLog(pMac, LOG1, + FL("Parse error ProbeResponse, length=%d"), frameLen);) + vos_mem_vfree(pProbeRsp); + return; + } + + /** + * Expect Probe Response only when + * 1. STA is in scan mode waiting for Beacon/Probe response or + * 2. STA is waiting for Beacon/Probe Response to announce + * join success or + * 3. STA is in IBSS mode in BSS started state or + * 4. STA/AP is in learn mode + * 5. STA in link established state. In this state, the probe response is + * expected for two scenarios: + * -- As part of heart beat mechanism, probe req is sent out + * -- If QoS Info IE in beacon has a different count for EDCA Params, + * and EDCA IE is not present in beacon, + * then probe req is sent out to get the EDCA params. + * + * Ignore Probe Response frame in all other states + */ + + // TO SUPPORT BT-AMP + if (((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) || //mlm state check should be global - 18th oct + (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) || + (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) )|| + ((GET_LIM_SYSTEM_ROLE(psessionEntry) == eLIM_STA_IN_IBSS_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)) || + pMac->fScanOffload) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (pMac->lim.gLimBackgroundScanMode == eSIR_ROAMING_SCAN) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Probe Resp Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo))); + } + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE || + !pProbeRsp->ssidPresent) // Enforce Mandatory IEs + { + PELOG1(limLog(pMac, LOG1, + FL("Parse error ProbeResponse, length=%d"), + frameLen);) + vos_mem_vfree(pProbeRsp); + return; + } + + if (pMac->fScanOffload) + { + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + } + + //To Support BT-AMP + if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE)) + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + ((pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE) ? eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE), eANI_BOOLEAN_TRUE); + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) //mlm state check should be global - 18th oct + { + } + else if (psessionEntry->limMlmState == + eLIM_MLM_WT_JOIN_BEACON_STATE) + { + if( psessionEntry->beacon != NULL )//Either Beacon/probe response is required. Hence store it in same buffer. + { + vos_mem_free(psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + psessionEntry->bcnLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + psessionEntry->beacon = vos_mem_malloc(psessionEntry->bcnLen); + if ( NULL == psessionEntry->beacon ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store beacon"));) + } + else + { + //Store the Beacon/ProbeRsp. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->beacon, + WDA_GET_RX_MPDU_DATA(pRxPacketInfo), + psessionEntry->bcnLen); + } + + // STA in WT_JOIN_BEACON_STATE + limCheckAndAnnounceJoinSuccess(pMac, pProbeRsp, pHdr, psessionEntry); + } + else if(psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + tpDphHashNode pStaDs = NULL; + /** + * Check if this Probe Response is for + * our Probe Request sent upon reaching + * heart beat threshold + */ + #if 0 + if (wlan_cfgGetStr(pMac, + WNI_CFG_BSSID, + currentBssId, + &cfg) != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,psessionEntry->bssId); + + if ( !vos_mem_compare(currentBssId, pHdr->bssId, sizeof(tSirMacAddr)) ) + { + vos_mem_vfree(pProbeRsp); + return; + } + + if (!LIM_IS_CONNECTION_ACTIVE(psessionEntry)) + { + limLog(pMac, LOGW, + FL("Received Probe Resp from AP. So it is alive!!")); + + if (pProbeRsp->HTInfo.present) + limReceivedHBHandler(pMac, (tANI_U8)pProbeRsp->HTInfo.primaryChannel, psessionEntry); + else + limReceivedHBHandler(pMac, (tANI_U8)pProbeRsp->channelNumber, psessionEntry); + } + + + if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + { + if (pProbeRsp->channelSwitchPresent || + pProbeRsp->propIEinfo.propChannelSwitchPresent) + { + limUpdateChannelSwitch(pMac, pProbeRsp, psessionEntry); + } + else if (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + limCancelDot11hChannelSwitch(pMac, psessionEntry); + } + } + + + /** + * Now Process EDCA Parameters, if EDCAParamSet count is different. + * -- While processing beacons in link established state if it is determined that + * QoS Info IE has a different count for EDCA Params, + * and EDCA IE is not present in beacon, + * then probe req is sent out to get the EDCA params. + */ + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + limGetQosMode(psessionEntry, &qosEnabled); + limGetWmeMode(psessionEntry, &wmeEnabled); + PELOG2(limLog(pMac, LOG2, + FL("wmeEdcaPresent: %d wmeEnabled: %d, edcaPresent: %d, qosEnabled: %d, edcaParams.qosInfo.count: %d schObject.gLimEdcaParamSetCount: %d"), + pProbeRsp->wmeEdcaPresent, wmeEnabled, pProbeRsp->edcaPresent, qosEnabled, + pProbeRsp->edcaParams.qosInfo.count, psessionEntry->gLimEdcaParamSetCount);) + if (((pProbeRsp->wmeEdcaPresent && wmeEnabled) || + (pProbeRsp->edcaPresent && qosEnabled)) && + (pProbeRsp->edcaParams.qosInfo.count != psessionEntry->gLimEdcaParamSetCount)) + { + if (schBeaconEdcaProcess(pMac, &pProbeRsp->edcaParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("EDCA parameter processing error"));) + else if (pStaDs != NULL) + { + // If needed, downgrade the EDCA parameters + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + PELOGE(limLog(pMac, LOGE, FL("Self Entry missing in Hash Table"));) + + } + + if (psessionEntry->fWaitForProbeRsp == true) + { + limLog(pMac, LOGW, FL("Checking probe response for capability change\n") ); + limDetectChangeInApCapabilities(pMac, pProbeRsp, psessionEntry); + } + } + else if ((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) && + (psessionEntry->limMlmState == eLIM_MLM_BSS_STARTED_STATE)) + limHandleIBSScoalescing(pMac, pProbeRsp, pRxPacketInfo,psessionEntry); + } // if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || ... + + vos_mem_vfree(pProbeRsp); + // Ignore Probe Response frame in all other states + return; +} /*** end limProcessProbeRspFrame() ***/ + + +void +limProcessProbeRspFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo) +{ + tANI_U8 *pBody; + tANI_U32 frameLen = 0; + tpSirMacMgmtHdr pHdr; + tSirProbeRespBeacon *pProbeRsp; + + pProbeRsp = vos_mem_vmalloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pProbeRsp ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limProcessProbeRspFrameNoSession") ); + return; + } + + pProbeRsp->ssId.length = 0; + pProbeRsp->wpa.length = 0; + pProbeRsp->propIEinfo.apName.length = 0; + + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + + + limLog(pMac, LOG2, + FL("Received Probe Response frame with length=%d from "), + WDA_GET_RX_MPDU_LEN(pRxPacketInfo)); + limPrintMacAddr(pMac, pHdr->sa, LOG2); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo) || + WDA_GET_ROAMCANDIDATEIND(pRxPacketInfo))) + { +#endif + if (!pMac->fScanOffload) + { + if (limDeactivateMinChannelTimerDuringScan(pMac) != eSIR_SUCCESS) + { + vos_mem_vfree(pProbeRsp); + return; + } + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + // Validate IE information before processing Probe Response Frame + if (limValidateIEInformationInProbeRspFrame(pMac, pRxPacketInfo) + != eSIR_SUCCESS) + { + PELOG1(limLog(pMac, LOG1,FL("Parse error ProbeResponse, length=%d"), + frameLen);) + vos_mem_vfree(pProbeRsp); + return; + } + /* Since there is no psessionEntry, PE cannot be in the following states: + * - eLIM_MLM_WT_JOIN_BEACON_STATE + * - eLIM_MLM_LINK_ESTABLISHED_STATE + * - eLIM_MLM_BSS_STARTED_STATE + * Hence, expect Probe Response only when + * 1. STA is in scan mode waiting for Beacon/Probe response + * 2. LFR logic in FW sends up candidate frames + * + * Ignore Probe Response frame in all other states + */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (pMac->lim.gLimBackgroundScanMode == eSIR_ROAMING_SCAN) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Probe Resp Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo))); + } + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE) + { + limLog(pMac, LOG1, FL("Parse error ProbeResponse, length=%d\n"), frameLen); + vos_mem_vfree(pProbeRsp); + return; + } + limLog( pMac, LOG2, FL("Save this probe rsp in LFR cache")); + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + } + else +#endif + if (pMac->fScanOffload) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) + == eSIR_FAILURE) + { + limLog(pMac, LOG1, + FL("Parse error ProbeResponse, length=%d\n"), frameLen); + vos_mem_vfree(pProbeRsp); + return; + } + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, + eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + } + else if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) || //mlm state check should be global - 18th oct + (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) ) + { + frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + + if (pMac->lim.gLimBackgroundScanMode == eSIR_ROAMING_SCAN) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Probe Resp Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"), + MAC_ADDR_ARRAY(pHdr->bssId), + (uint)abs((tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo))); + } + + // Get pointer to Probe Response frame body + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + + if (sirConvertProbeFrame2Struct(pMac, pBody, frameLen, pProbeRsp) == eSIR_FAILURE) + { + limLog(pMac, LOG1, FL("Parse error ProbeResponse, length=%d"), frameLen); + vos_mem_vfree(pProbeRsp); + return; + } + + if( (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) || + (pMac->lim.gLimMlmState == eLIM_MLM_PASSIVE_SCAN_STATE) ) + limCheckAndAddBssDescription(pMac, pProbeRsp, pRxPacketInfo, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + else if (pMac->lim.gLimMlmState == eLIM_MLM_LEARN_STATE) + { + } + } + vos_mem_vfree(pProbeRsp); + return; +} /*** end limProcessProbeRspFrameNew() ***/ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c new file mode 100644 index 000000000000..346585cf75ea --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -0,0 +1,5998 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file limProcessSmeReqMessages.cc contains the code + * for processing SME request messages. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniApi.h" +#include "wniCfg.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSmeReqUtils.h" +#include "limIbssPeerMgmt.h" +#include "limAdmitControl.h" +#include "dphHashTable.h" +#include "limSendMessages.h" +#include "limApi.h" +#include "wmmApsd.h" + +#ifdef WLAN_FEATURE_RMC +#include "limRMC.h" +#endif + +#include "sapApi.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +#include +#endif + +#ifdef WLAN_FEATURE_LFR_MBB +#include "lim_mbb.h" +#endif + + +#define JOIN_FAILURE_TIMEOUT 1000 // in msecs +/* This overhead is time for sending NOA start to host in case of GO/sending NULL data & receiving ACK + * in case of P2P Client and starting actual scanning with init scan req/rsp plus in case of concurrency, + * taking care of sending null data and receiving ACK to/from AP/Also SetChannel with calibration is taking + * around 7ms . + */ +#define SCAN_MESSAGING_OVERHEAD 20 // in msecs +#define JOIN_NOA_DURATION 2000 // in msecs +#define OEM_DATA_NOA_DURATION 60 // in msecs +#define DEFAULT_PASSIVE_MAX_CHANNEL_TIME 110 // in msecs + +#define CONV_MS_TO_US 1024 //conversion factor from ms to us + +// SME REQ processing function templates +static void __limProcessSmeStartReq(tpAniSirGlobal, tANI_U32 *); +static tANI_BOOLEAN __limProcessSmeSysReadyInd(tpAniSirGlobal, tANI_U32 *); +static tANI_BOOLEAN __limProcessSmeStartBssReq(tpAniSirGlobal, tpSirMsgQ pMsg); +static void __limProcessSmeScanReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeJoinReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeReassocReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeDisassocReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeDisassocCnf(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeDeauthReq(tpAniSirGlobal, tANI_U32 *); +static void __limProcessSmeSetContextReq(tpAniSirGlobal, tANI_U32 *); +static tANI_BOOLEAN __limProcessSmeStopBssReq(tpAniSirGlobal, tpSirMsgQ pMsg); + +void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *); + +extern void peRegisterTLHandle(tpAniSirGlobal pMac); + + +#ifdef BACKGROUND_SCAN_ENABLED + +// start the background scan timers if it hasn't already started +static void +__limBackgroundScanInitiate(tpAniSirGlobal pMac) +{ + if (pMac->lim.gLimBackgroundScanStarted) + return; + + //make sure timer is created first + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + limLog(pMac, LOGP, FL("could not activate background scan timer")); + pMac->lim.gLimBackgroundScanStarted = true; + pMac->lim.gLimBackgroundScanChannelId = 0; + } +} + +#endif // BACKGROUND_SCAN_ENABLED + +// determine if a fresh scan request must be issued or not +/* +* PE will do fresh scan, if all of the active sessions are in good state (Link Est or BSS Started) +* If one of the sessions is not in one of the above states, then PE does not do fresh scan +* If no session exists (scanning very first time), then PE will always do fresh scan if SME +* asks it to do that. +*/ +static tANI_U8 +__limFreshScanReqd(tpAniSirGlobal pMac, tANI_U8 returnFreshResults) +{ + + tANI_U8 validState = TRUE; + int i; + + if(pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE) + { + limLog(pMac, LOG1, FL("setting fresh scan as false. sme state is %d"), + pMac->lim.gLimSmeState); + return FALSE; + } + for(i =0; i < pMac->lim.maxBssId; i++) + { + + if(pMac->lim.gpSession[i].valid == TRUE) + { + if(!( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (pMac->lim.gpSession[i].limSmeState == eLIM_SME_LINK_EST_STATE) )|| + + ( ( (pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE) )&& + (pMac->lim.gpSession[i].limSmeState == eLIM_SME_NORMAL_STATE) ) + || ( ( ( (pMac->lim.gpSession[i].bssType == eSIR_INFRA_AP_MODE) + && ( pMac->lim.gpSession[i].pePersona == VOS_P2P_GO_MODE) ) + || (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) ) + && (pMac->lim.gpSession[i].limSmeState == eLIM_SME_NORMAL_STATE) ) + )) + { + validState = FALSE; + limLog(pMac, LOG1, FL("setting fresh scan as false." + "bssType is %d system role is %d, smestate is %d"), + pMac->lim.gpSession[i].bssType, + pMac->lim.gpSession[i].limSystemRole, + pMac->lim.gpSession[i].limSmeState); + break; + } + + } + } + limLog(pMac, LOG1, FL("FreshScanReqd: %d "), validState); + + if( (validState) && (returnFreshResults & SIR_BG_SCAN_RETURN_FRESH_RESULTS)) + return TRUE; + + return FALSE; +} + + + +/** + * __limIsSmeAssocCnfValid() + * + *FUNCTION: + * This function is called by limProcessLmmMessages() upon + * receiving SME_ASSOC_CNF. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMeasReq Pointer to Received ASSOC_CNF message + * @return true When received SME_ASSOC_CNF is formatted + * correctly + * false otherwise + */ + +inline static tANI_U8 +__limIsSmeAssocCnfValid(tpSirSmeAssocCnf pAssocCnf) +{ + if (limIsGroupAddr(pAssocCnf->peerMacAddr)) + return false; + else + return true; +} /*** end __limIsSmeAssocCnfValid() ***/ + + +/** + * __limGetSmeJoinReqSizeForAlloc() + * + *FUNCTION: + * This function is called in various places to get IE length + * from tSirBssDescription structure + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBssDescr + * @return Total IE length + */ + +tANI_U16 +__limGetSmeJoinReqSizeForAlloc(tANI_U8 *pBuf) +{ + tANI_U16 len = 0; + + if (!pBuf) + return len; + + pBuf += sizeof(tANI_U16); + len = limGetU16( pBuf ); + return (len + sizeof( tANI_U16 )); +} /*** end __limGetSmeJoinReqSizeForAlloc() ***/ + + +/**---------------------------------------------------------------- +\fn __limIsDeferedMsgForLearn + +\brief Has role only if 11h is enabled. Not used on STA side. + Defers the message if SME is in learn state and brings + the LIM back to normal mode. + +\param pMac +\param pMsg - Pointer to message posted from SME to LIM. +\return TRUE - If defered + FALSE - Otherwise +------------------------------------------------------------------*/ +static tANI_BOOLEAN +__limIsDeferedMsgForLearn(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + if (limIsSystemInScanState(pMac)) + { + if (limDeferMsg(pMac, pMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d"), pMsg->type);) + return eANI_BOOLEAN_FALSE; + } + PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d"), + pMsg->type);) + + /** Send finish scan req to HAL only if LIM is not waiting for any response + * from HAL like init scan rsp, start scan rsp etc. + */ + if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) + { + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_LEARN_WAIT_STATE); + } + + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + +/**---------------------------------------------------------------- +\fn __limIsDeferedMsgForRadar + +\brief Has role only if 11h is enabled. Not used on STA side. + Defers the message if radar is detected. + +\param pMac +\param pMsg - Pointer to message posted from SME to LIM. +\return TRUE - If defered + FALSE - Otherwise +------------------------------------------------------------------*/ +static tANI_BOOLEAN +__limIsDeferedMsgForRadar(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + /** fRadarDetCurOperChan will be set only if we detect radar in current + * operating channel and System Role == AP ROLE */ + //TODO: Need to take care radar detection. + //if (LIM_IS_RADAR_DETECTED(pMac)) + if( 0 ) + { + if (limDeferMsg(pMac, pMsg) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Could not defer Msg = %d"), pMsg->type);) + return eANI_BOOLEAN_FALSE; + } + PELOG1(limLog(pMac, LOG1, FL("Defer the message, in learn mode type = %d"), + pMsg->type);) + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + + +/** + * __limProcessSmeStartReq() + * + *FUNCTION: + * This function is called to process SME_START_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeStartReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + limLog(pMac, LOG1, FL("Received SME_START_REQ")); + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + { + pMac->lim.gLimSmeState = eLIM_SME_IDLE_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, NO_SESSION, pMac->lim.gLimSmeState)); + + /// By default do not return after first scan match + pMac->lim.gLimReturnAfterFirstMatch = 0; + + /// Initialize MLM state machine + limInitMlm(pMac); + + /// By default return unique scan results + pMac->lim.gLimReturnUniqueResults = true; + pMac->lim.gLimSmeScanResultLength = 0; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pMac->lim.gLimSmeLfrScanResultLength = 0; +#endif + + if (((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd) + { + /* + * Need to indicate new BSSs found during background scanning to + * host. Update this parameter at CFG + */ + if (cfgSetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, ((tSirSmeStartReq *) pMsgBuf)->sendNewBssInd) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set NEIGHBOR_BSS_IND at CFG")); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + } + } + } + else + { + /** + * Should not have received eWNI_SME_START_REQ in states + * other than OFFLINE. Return response to host and + * log error + */ + limLog(pMac, LOGE, FL("Invalid SME_START_REQ received in SME state %d"),pMac->lim.gLimSmeState ); + limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + } + limSendSmeRsp(pMac, eWNI_SME_START_RSP, retCode,smesessionId,smetransactionId); +} /*** end __limProcessSmeStartReq() ***/ + + +/** ------------------------------------------------------------- +\fn __limProcessSmeSysReadyInd +\brief handles the notification from HDD. PE just forwards this message to HAL. +\param tpAniSirGlobal pMac +\param tANI_U32* pMsgBuf +\return TRUE-Posting to HAL failed, so PE will consume the buffer. +\ FALSE-Posting to HAL successful, so HAL will consume the buffer. + -------------------------------------------------------------*/ +static tANI_BOOLEAN +__limProcessSmeSysReadyInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + + msg.type = WDA_SYS_READY_IND; + msg.reserved = 0; + msg.bodyptr = pMsgBuf; + msg.bodyval = 0; + + if (pMac->gDriverType != eDRIVER_TYPE_MFG) + { + peRegisterTLHandle(pMac); + } + PELOGW(limLog(pMac, LOGW, FL("sending WDA_SYS_READY_IND msg to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed")); + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + +#ifdef WLAN_FEATURE_11AC + +tANI_U32 limGetCenterChannel(tpAniSirGlobal pMac,tANI_U8 primarychanNum,ePhyChanBondState secondaryChanOffset, tANI_U8 chanWidth) +{ + if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + switch(secondaryChanOffset) + { + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return primarychanNum; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return primarychanNum + 6; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return primarychanNum - 6; + default : + return eSIR_CFG_INVALID_ID; + } + } + else if (chanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + { + switch(secondaryChanOffset) + { + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + return primarychanNum + 2; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return primarychanNum; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return primarychanNum - 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return primarychanNum + 2; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return primarychanNum - 2; + default : + return eSIR_CFG_INVALID_ID; + } + } + return primarychanNum; +} + +#endif +/** + * __limHandleSmeStartBssRequest() + * + *FUNCTION: + * This function is called to process SME_START_BSS_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 size; + tANI_U32 val = 0; + tSirRetStatus retStatus; + tSirMacChanNum channelNumber; + tLimMlmStartReq *pMlmStartReq = NULL; + tpSirSmeStartBssReq pSmeStartBssReq = NULL; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tANI_U32 autoGenBssId = FALSE; //Flag Used in case of IBSS to Auto generate BSSID. + tANI_U8 sessionId; + tpPESession psessionEntry = NULL; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + //Since the session is not created yet, sending NULL. The response should have the correct state. + limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limLog(pMac, LOG1, FL("Received SME_START_BSS_REQ")); + + /* Global Sme state and mlm states are not defined yet, for BT-AMP Suppoprt . TO BE DONE */ + if ( (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) || + (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE)) + { + size = sizeof(tSirSmeStartBssReq) + SIR_MAC_MAX_IE_LENGTH; + + pSmeStartBssReq = vos_mem_malloc(size); + if ( NULL == pSmeStartBssReq ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for pMac->lim.gpLimStartBssReq"));) + /// Send failure response to host + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + + vos_mem_set((void *)pSmeStartBssReq, size, 0); + + if ((limStartBssReqSerDes(pMac, pSmeStartBssReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeStartBssReqValid(pMac, pSmeStartBssReq))) + { + PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ"));) + retCode = eSIR_SME_INVALID_PARAMETERS; + goto free; + } +#if 0 + PELOG3(limLog(pMac, LOG3, + FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d"), + pMac->lim.gpLimStartBssReq->bssType, pMac->lim.gpLimStartBssReq->channelId);) +#endif + + /* This is the place where PE is going to create a session. + * If session is not existed, then create a new session */ + if((psessionEntry = peFindSessionByBssid(pMac,pSmeStartBssReq->bssId,&sessionId)) != NULL) + { + limLog(pMac, LOGW, FL("Session Already exists for given BSSID")); + retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + psessionEntry = NULL; + goto free; + } + else + { + if((psessionEntry = peCreateSession(pMac,pSmeStartBssReq->bssId,&sessionId, pMac->lim.maxStation)) == NULL) + { + limLog(pMac, LOGW, FL("Session Can not be created ")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto free; + } + + } + + /* Store the session related parameters in newly created session */ + psessionEntry->pLimStartBssReq = pSmeStartBssReq; + + /* Store PE sessionId in session Table */ + psessionEntry->peSessionId = sessionId; + + /* Store SME session Id in sessionTable */ + psessionEntry->smeSessionId = pSmeStartBssReq->sessionId; + + psessionEntry->transactionId = pSmeStartBssReq->transactionId; + + sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeStartBssReq->selfMacAddr); + + /* Copy SSID to session table */ + vos_mem_copy( (tANI_U8 *)&psessionEntry->ssId, + (tANI_U8 *)&pSmeStartBssReq->ssId, + (pSmeStartBssReq->ssId.length + 1)); + + psessionEntry->bssType = pSmeStartBssReq->bssType; + + psessionEntry->nwType = pSmeStartBssReq->nwType; + + psessionEntry->beaconParams.beaconInterval = pSmeStartBssReq->beaconInterval; + + /* Store the channel number in session Table */ + psessionEntry->currentOperChannel = pSmeStartBssReq->channelId; + + /*Store Persona */ + psessionEntry->pePersona = pSmeStartBssReq->bssPersona; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,FL("PE PERSONA=%d"), + psessionEntry->pePersona); + + /*Update the phymode*/ + psessionEntry->gLimPhyMode = pSmeStartBssReq->nwType; + + psessionEntry->maxTxPower = cfgGetRegulatoryMaxTransmitPower( pMac, + psessionEntry->currentOperChannel ); + +#ifdef WLAN_FEATURE_AP_HT40_24G + /*Store Overlapping BSS Scan Parameters IEs to session table */ + if (pSmeStartBssReq->apHT40_24GEnabled) + { + limInitOBSSScanParams(pMac, psessionEntry); + } +#endif + /* Store the dot 11 mode in to the session Table*/ + + psessionEntry->dot11mode = pSmeStartBssReq->dot11mode; + psessionEntry->htCapability = IS_DOT11_MODE_HT(psessionEntry->dot11mode); +#ifdef WLAN_FEATURE_11AC + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode); + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + FL("*****psessionEntry->vhtCapability = %d"),psessionEntry->vhtCapability); +#endif + + psessionEntry->txLdpcIniFeatureEnabled = + pSmeStartBssReq->txLdpcIniFeatureEnabled; + +#ifdef WLAN_FEATURE_11W + psessionEntry->limRmfEnabled = pSmeStartBssReq->pmfCapable ? 1 : 0; + limLog(pMac, LOG1, FL("Session RMF enabled: %d"), psessionEntry->limRmfEnabled); +#endif + + vos_mem_copy((void*)&psessionEntry->rateSet, + (void*)&pSmeStartBssReq->operationalRateSet, + sizeof(tSirMacRateSet)); + vos_mem_copy((void*)&psessionEntry->extRateSet, + (void*)&pSmeStartBssReq->extendedRateSet, + sizeof(tSirMacRateSet)); + + switch(pSmeStartBssReq->bssType) + { + case eSIR_INFRA_AP_MODE: + psessionEntry->limSystemRole = eLIM_AP_ROLE; + psessionEntry->privacy = pSmeStartBssReq->privacy; + psessionEntry->fwdWPSPBCProbeReq = pSmeStartBssReq->fwdWPSPBCProbeReq; + psessionEntry->authType = pSmeStartBssReq->authType; + /* Store the DTIM period */ + psessionEntry->dtimPeriod = (tANI_U8)pSmeStartBssReq->dtimPeriod; + /*Enable/disable UAPSD*/ + psessionEntry->apUapsdEnable = pSmeStartBssReq->apUapsdEnable; + if (psessionEntry->pePersona == VOS_P2P_GO_MODE) + { + psessionEntry->proxyProbeRspEn = 0; + } + else + { + /* To detect PBC overlap in SAP WPS mode, Host handles + * Probe Requests. + */ + if(SAP_WPS_DISABLED == pSmeStartBssReq->wps_state) + { + psessionEntry->proxyProbeRspEn = 1; + } + else + { + psessionEntry->proxyProbeRspEn = 0; + } + } + psessionEntry->ssidHidden = pSmeStartBssReq->ssidHidden; + psessionEntry->wps_state = pSmeStartBssReq->wps_state; + limGetShortSlotFromPhyMode(pMac, psessionEntry, + psessionEntry->gLimPhyMode, + &psessionEntry->shortSlotTimeSupported); + break; + case eSIR_IBSS_MODE: + psessionEntry->limSystemRole = eLIM_STA_IN_IBSS_ROLE; + limGetShortSlotFromPhyMode(pMac, psessionEntry, + psessionEntry->gLimPhyMode, + &psessionEntry->shortSlotTimeSupported); + /* In WPA-NONE case we wont get the privacy bit in ibss config + * from supplicant, but we are updating WNI_CFG_PRIVACY_ENABLED + * on basis of Encryption type in csrRoamSetBssConfigCfg. So + * get the privacy info from WNI_CFG_PRIVACY_ENABLED + */ + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, &val) + != eSIR_SUCCESS) + limLog(pMac, LOGE, FL("cfg get WNI_CFG_PRIVACY_ENABLED" + " failed")); + psessionEntry->privacy =(tANI_U8) val; + psessionEntry->isCoalesingInIBSSAllowed = + pSmeStartBssReq->isCoalesingInIBSSAllowed; + break; + + case eSIR_BTAMP_AP_MODE: + psessionEntry->limSystemRole = eLIM_BT_AMP_AP_ROLE; + break; + + case eSIR_BTAMP_STA_MODE: + psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + break; + + /* There is one more mode called auto mode. which is used no where */ + + //FORBUILD -TEMPFIX.. HOW TO use AUTO MODE????? + + + default: + //not used anywhere...used in scan function + break; + } + + // BT-AMP: Allocate memory for the array of parsed (Re)Assoc request structure + if ( (pSmeStartBssReq->bssType == eSIR_BTAMP_AP_MODE) + || (pSmeStartBssReq->bssType == eSIR_INFRA_AP_MODE) + ) + { + psessionEntry->parsedAssocReq = vos_mem_malloc( + psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)); + if ( NULL == psessionEntry->parsedAssocReq ) + { + limLog(pMac, LOGW, FL("AllocateMemory() failed")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto free; + } + vos_mem_set(psessionEntry->parsedAssocReq, + (psessionEntry->dph.dphHashTable.size * sizeof(tpSirAssocReq)), + 0 ); + } + + /* Channel Bonding is not addressd yet for BT-AMP Support.. sunit will address channel bonding */ + if (pSmeStartBssReq->channelId) + { + channelNumber = pSmeStartBssReq->channelId; + psessionEntry->htSupportedChannelWidthSet = (pSmeStartBssReq->cbMode)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + psessionEntry->htSecondaryChannelOffset = pSmeStartBssReq->cbMode; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("cbMode %u"), pSmeStartBssReq->cbMode); +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + tANI_U32 centerChan; + tANI_U32 chanWidth; + + if (wlan_cfgGetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + &chanWidth) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve Channel Width from CFG")); + } + + if(channelNumber <= RF_CHAN_14 && + chanWidth != eHT_CHANNEL_WIDTH_20MHZ) + { + chanWidth = eHT_CHANNEL_WIDTH_20MHZ; + limLog(pMac, LOG1, FL("Setting chanWidth to 20Mhz for" + " channel %d"),channelNumber); + } + + if(chanWidth == eHT_CHANNEL_WIDTH_20MHZ || + chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + " WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + } + if (chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + if (cfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + " WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + + centerChan = limGetCenterChannel( pMac, channelNumber, + pSmeStartBssReq->cbMode, + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ); + if(centerChan != eSIR_CFG_INVALID_ID) + { + limLog(pMac, LOGW, FL("***Center Channel for " + "80MHZ channel width = %d"),centerChan); + psessionEntry->apCenterChan = centerChan; + if (cfgSetInt(pMac, + WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + centerChan) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_CHANNEL_BONDING_MODE at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + } + } + + /* All the translation is done by now for gVhtChannelWidth + * from .ini file to the actual values as defined in spec. + * So, grabing the spec value which is + * updated in .dat file by the above logic */ + if (wlan_cfgGetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, + &chanWidth) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve Channel Width from CFG")); + } + /*For Sta+p2p-Go concurrency + vhtTxChannelWidthSet is used for storing p2p-GO channel width + apChanWidth is used for storing the AP channel width that the Sta is going to associate. + Initialize the apChanWidth same as p2p-GO channel width this gets over written once the station joins the AP + */ + psessionEntry->vhtTxChannelWidthSet = chanWidth; + psessionEntry->apChanWidth = chanWidth; + } + psessionEntry->htSecondaryChannelOffset = limGetHTCBState(pSmeStartBssReq->cbMode); +#endif + } + else + { + PELOGW(limLog(pMac, LOGW, FL("Received invalid eWNI_SME_START_BSS_REQ"));) + retCode = eSIR_SME_INVALID_PARAMETERS; + goto free; + } + + // Delete pre-auth list if any + limDeletePreAuthList(pMac); + + // Delete IBSS peer BSSdescription list if any + //limIbssDelete(pMac); sep 26 review + + + +#ifdef FIXME_GEN6 //following code may not be required. limInitMlm is now being invoked during peStart + /// Initialize MLM state machine + limInitMlm(pMac); +#endif + + psessionEntry->htCapability = IS_DOT11_MODE_HT(pSmeStartBssReq->dot11mode); + + /* keep the RSN/WPA IE information in PE Session Entry + * later will be using this to check when received (Re)Assoc req + * */ + limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac,&pSmeStartBssReq->rsnIE,psessionEntry); + + + //Taken care for only softAP case rest need to be done + if (psessionEntry->limSystemRole == eLIM_AP_ROLE){ + psessionEntry->gLimProtectionControl = pSmeStartBssReq->protEnabled; + /*each byte will have the following info + *bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 + *reserved reserved RIFS Lsig n-GF ht20 11g 11b*/ + vos_mem_copy( (void *) &psessionEntry->cfgProtection, + (void *) &pSmeStartBssReq->ht_capab, + sizeof( tANI_U16 )); + psessionEntry->pAPWPSPBCSession = NULL; // Initialize WPS PBC session link list + } + + // Prepare and Issue LIM_MLM_START_REQ to MLM + pMlmStartReq = vos_mem_malloc(sizeof(tLimMlmStartReq)); + if ( NULL == pMlmStartReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for mlmStartReq")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto free; + } + + vos_mem_set((void *) pMlmStartReq, sizeof(tLimMlmStartReq), 0); + + /* Copy SSID to the MLM start structure */ + vos_mem_copy( (tANI_U8 *) &pMlmStartReq->ssId, + (tANI_U8 *) &pSmeStartBssReq->ssId, + pSmeStartBssReq->ssId.length + 1); + pMlmStartReq->ssidHidden = pSmeStartBssReq->ssidHidden; + pMlmStartReq->obssProtEnabled = pSmeStartBssReq->obssProtEnabled; + + + pMlmStartReq->bssType = psessionEntry->bssType; + + /* Fill PE session Id from the session Table */ + pMlmStartReq->sessionId = psessionEntry->peSessionId; + + if( (pMlmStartReq->bssType == eSIR_BTAMP_STA_MODE) || (pMlmStartReq->bssType == eSIR_BTAMP_AP_MODE ) + || (pMlmStartReq->bssType == eSIR_INFRA_AP_MODE) + ) + { + //len = sizeof(tSirMacAddr); + //retStatus = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, (tANI_U8 *) pMlmStartReq->bssId, &len); + //if (retStatus != eSIR_SUCCESS) + //limLog(pMac, LOGP, FL("could not retrive BSSID, retStatus=%d"), retStatus); + + /* Copy the BSSId from sessionTable to mlmStartReq struct */ + sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId); + } + + else // ibss mode + { + pMac->lim.gLimIbssCoalescingHappened = false; + + if((retStatus = wlan_cfgGetInt(pMac, WNI_CFG_IBSS_AUTO_BSSID, &autoGenBssId)) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not retrieve Auto Gen BSSID, retStatus=%d"), retStatus); + retCode = eSIR_LOGP_EXCEPTION; + goto free; + } + + if(!autoGenBssId) + { + // We're not auto generating BSSID. Instead, get it from session entry + sirCopyMacAddr(pMlmStartReq->bssId,psessionEntry->bssId); + + if(pMlmStartReq->bssId[0] & 0x01) + { + PELOGE(limLog(pMac, LOGE, FL("Request to start IBSS with group BSSID\n Autogenerating the BSSID"));) + autoGenBssId = TRUE; + } + } + + if( autoGenBssId ) + { //if BSSID is not any uc id. then use locally generated BSSID. + //Autogenerate the BSSID + limGetRandomBssid( pMac, pMlmStartReq->bssId); + pMlmStartReq->bssId[0]= 0x02; + + /* Copy randomly generated BSSID to the session Table */ + sirCopyMacAddr(psessionEntry->bssId,pMlmStartReq->bssId); + } + } + /* store the channel num in mlmstart req structure */ + pMlmStartReq->channelNumber = psessionEntry->currentOperChannel; + pMlmStartReq->cbMode = pSmeStartBssReq->cbMode; + pMlmStartReq->beaconPeriod = psessionEntry->beaconParams.beaconInterval; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + pMlmStartReq->dtimPeriod = psessionEntry->dtimPeriod; + pMlmStartReq->wps_state = psessionEntry->wps_state; + + }else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_DTIM_PERIOD, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve DTIM Period")); + pMlmStartReq->dtimPeriod = (tANI_U8)val; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_PERIOD, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve Beacon interval")); + pMlmStartReq->cfParamSet.cfpPeriod = (tANI_U8)val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve CFPMaxDuration")); + pMlmStartReq->cfParamSet.cfpMaxDuration = (tANI_U16) val; + + //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context. + vos_mem_copy((void*)&pMlmStartReq->rateSet, (void*)&psessionEntry->rateSet, + sizeof(tSirMacRateSet)); + + // Now populate the 11n related parameters + pMlmStartReq->nwType = psessionEntry->nwType; + pMlmStartReq->htCapable = psessionEntry->htCapability; + // + // FIXME_GEN4 - Determine the appropriate defaults... + // + pMlmStartReq->htOperMode = pMac->lim.gHTOperMode; + pMlmStartReq->dualCTSProtection = pMac->lim.gHTDualCTSProtection; // Unused + pMlmStartReq->txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet; + + /* sep26 review */ + psessionEntry->limRFBand = limGetRFBand(channelNumber); + + // Initialize 11h Enable Flag + psessionEntry->lim11hEnable = 0; + if((pMlmStartReq->bssType != eSIR_IBSS_MODE) && + (SIR_BAND_5_GHZ == psessionEntry->limRFBand) ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED ")); + psessionEntry->lim11hEnable = val; + } + + if (!psessionEntry->lim11hEnable) + { + if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED ")); + } + + psessionEntry ->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry ->limSmeState = eLIM_SME_WT_START_BSS_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry ->limSmeState)); + + limPostMlmMessage(pMac, LIM_MLM_START_REQ, (tANI_U32 *) pMlmStartReq); + return; + } + else + { + + limLog(pMac, LOGE, FL("Received unexpected START_BSS_REQ, in state %X"),pMac->lim.gLimSmeState); + retCode = eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED; + goto end; + } // if (pMac->lim.gLimSmeState == eLIM_SME_OFFLINE_STATE) + +free: + if ((psessionEntry != NULL) && + (psessionEntry->pLimStartBssReq == pSmeStartBssReq)) + { + psessionEntry->pLimStartBssReq = NULL; + } + vos_mem_free( pSmeStartBssReq); + vos_mem_free( pMlmStartReq); + +end: + + /* This routine should return the sme sessionId and SME transaction Id */ + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId); + + if(NULL != psessionEntry) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + limSendSmeStartBssRsp(pMac, eWNI_SME_START_BSS_RSP, retCode,psessionEntry,smesessionId,smetransactionId); +} /*** end __limHandleSmeStartBssRequest() ***/ + + +/**-------------------------------------------------------------- +\fn __limProcessSmeStartBssReq + +\brief Wrapper for the function __limHandleSmeStartBssRequest + This message will be defered until softmac come out of + scan mode or if we have detected radar on the current + operating channel. +\param pMac +\param pMsg + +\return TRUE - If we consumed the buffer + FALSE - If have defered the message. + ---------------------------------------------------------------*/ +static tANI_BOOLEAN +__limProcessSmeStartBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + if (__limIsDeferedMsgForLearn(pMac, pMsg) || + __limIsDeferedMsgForRadar(pMac, pMsg)) + { + /** + * If message defered, buffer is not consumed yet. + * So return false + */ + return eANI_BOOLEAN_FALSE; + } + + __limHandleSmeStartBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr); + return eANI_BOOLEAN_TRUE; +} + + +/** + * limGetRandomBssid() + * + * FUNCTION:This function is called to process generate the random number for bssid + * This function is called to process SME_SCAN_REQ message + * from HDD or upper layer application. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * 1. geneartes the unique random number for bssid in ibss + * + * @param pMac Pointer to Global MAC structure + * @param *data Pointer to bssid buffer + * @return None + */ +void limGetRandomBssid(tpAniSirGlobal pMac, tANI_U8 *data) +{ + tANI_U32 random[2] ; + random[0] = tx_time_get(); + random[0] |= (random[0] << 15) ; + random[1] = random[0] >> 1; + vos_mem_copy( data, (tANI_U8*)random, sizeof(tSirMacAddr)); +} + +static eHalStatus limSendHalStartScanOffloadReq(tpAniSirGlobal pMac, + tpSirSmeScanReq pScanReq) +{ + tSirScanOffloadReq *pScanOffloadReq; + tANI_U8 *p; + tSirMsgQ msg; + tANI_U16 i, len; + tSirRetStatus rc = eSIR_SUCCESS; + + /* The tSirScanOffloadReq will reserve the space for first channel, + so allocate the memory for (numChannels - 1) and uIEFieldLen */ + len = sizeof(tSirScanOffloadReq) + (pScanReq->channelList.numChannels - 1) + + pScanReq->uIEFieldLen; + + pScanOffloadReq = vos_mem_malloc(len); + if ( NULL == pScanOffloadReq ) + { + limLog(pMac, LOGE, + FL("AllocateMemory failed for pScanOffloadReq")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_set( (tANI_U8 *) pScanOffloadReq, len, 0); + + msg.type = WDA_START_SCAN_OFFLOAD_REQ; + msg.bodyptr = pScanOffloadReq; + msg.bodyval = 0; + + vos_mem_copy((tANI_U8 *) pScanOffloadReq->bssId, + (tANI_U8*) pScanReq->bssId, + sizeof(tSirMacAddr)); + + if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) + { + limLog(pMac, LOGE, + FL("Invalid value (%d) for numSsid"), SIR_SCAN_MAX_NUM_SSID); + vos_mem_free (pScanOffloadReq); + return eHAL_STATUS_FAILURE; + } + + pScanOffloadReq->numSsid = pScanReq->numSsid; + for (i = 0; i < pScanOffloadReq->numSsid; i++) + { + pScanOffloadReq->ssId[i].length = pScanReq->ssId[i].length; + vos_mem_copy((tANI_U8 *) pScanOffloadReq->ssId[i].ssId, + (tANI_U8 *) pScanReq->ssId[i].ssId, + pScanOffloadReq->ssId[i].length); + } + + pScanOffloadReq->hiddenSsid = pScanReq->hiddenSsid; + vos_mem_copy((tANI_U8 *) pScanOffloadReq->selfMacAddr, + (tANI_U8 *) pScanReq->selfMacAddr, + sizeof(tSirMacAddr)); + pScanOffloadReq->bssType = pScanReq->bssType; + pScanOffloadReq->dot11mode = pScanReq->dot11mode; + pScanOffloadReq->scanType = pScanReq->scanType; + pScanOffloadReq->minChannelTime = pScanReq->minChannelTime; + pScanOffloadReq->maxChannelTime = pScanReq->maxChannelTime; + pScanOffloadReq->p2pSearch = pScanReq->p2pSearch; + pScanOffloadReq->sessionId = pScanReq->sessionId; + pScanOffloadReq->channelList.numChannels = + pScanReq->channelList.numChannels; + p = &(pScanOffloadReq->channelList.channelNumber[0]); + for (i = 0; i < pScanOffloadReq->channelList.numChannels; i++) + p[i] = pScanReq->channelList.channelNumber[i]; + + pScanOffloadReq->uIEFieldLen = pScanReq->uIEFieldLen; + pScanOffloadReq->uIEFieldOffset = len - pScanOffloadReq->uIEFieldLen; + vos_mem_copy((tANI_U8 *) p + i, + (tANI_U8 *) pScanReq + pScanReq->uIEFieldOffset, + pScanOffloadReq->uIEFieldLen); + + rc = wdaPostCtrlMsg(pMac, &msg); + if (rc != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() return failure")); + vos_mem_free(pScanOffloadReq); + return eHAL_STATUS_FAILURE; + } + limLog(pMac, LOG1, FL("Processed Offload Scan Request Successfully")); + + return eHAL_STATUS_SUCCESS; +} + +/** + * __limProcessSmeScanReq() + * + *FUNCTION: + * This function is called to process SME_SCAN_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * 1. Periodic scanning should be requesting to return unique + * scan results. + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U32 len; + tLimMlmScanReq *pMlmScanReq; + tpSirSmeScanReq pScanReq; + tANI_U8 i = 0; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + pScanReq = (tpSirSmeScanReq) pMsgBuf; + limLog(pMac, LOG1,FL("SME SCAN REQ numChan %d min %d max %d IELen %d" + "first %d fresh %d unique %d type %s (%d)" + " mode %s (%d)rsp %d"), + pScanReq->channelList.numChannels, + pScanReq->minChannelTime, + pScanReq->maxChannelTime, + pScanReq->uIEFieldLen, + pScanReq->returnAfterFirstMatch, + pScanReq->returnFreshResults, + pScanReq->returnUniqueResults, + lim_ScanTypetoString(pScanReq->scanType), + pScanReq->scanType, + lim_BackgroundScanModetoString(pScanReq->backgroundScanMode), + pScanReq->backgroundScanMode, pMac->lim.gLimRspReqd ? 1 : 0); + + /* Since scan req always requires a response, we will overwrite response required here. + * This is added esp to take care of the condition where in p2p go case, we hold the scan req and + * insert single NOA. We send the held scan request to FW later on getting start NOA ind from FW so + * we lose state of the gLimRspReqd flag for the scan req if any other request comes by then. + * e.g. While unit testing, we found when insert single NOA is done, we see a get stats request which turns the flag + * gLimRspReqd to FALSE; now when we actually start the saved scan req for init scan after getting + * NOA started, the gLimRspReqd being a global flag is showing FALSE instead of TRUE value for + * this saved scan req. Since all scan reqs coming to lim require a response, there is no harm in setting + * the global flag gLimRspReqd to TRUE here. + */ + pMac->lim.gLimRspReqd = TRUE; + + /*copy the Self MAC address from SmeReq to the globalplace, used for sending probe req*/ + sirCopyMacAddr(pMac->lim.gSelfMacAddr, pScanReq->selfMacAddr); + + /* Check if scan req is not valid or link is already suspended*/ + if (!limIsSmeScanReqValid(pMac, pScanReq) || limIsLinkSuspended(pMac)) + { + limLog(pMac, LOGE, + FL("Received SME_SCAN_REQ with invalid params or link is suspended %d"), + limIsLinkSuspended(pMac)); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId); + + } // if (pMac->lim.gLimRspReqd) + + return; + } + + //if scan is disabled then return as invalid scan request. + //if scan in power save is disabled, and system is in power save mode, then ignore scan request. + if( (pMac->lim.fScanDisabled) || (!pMac->lim.gScanInPowersave && !limIsSystemInActiveState(pMac)) ) + { + limLog(pMac, LOGE, FL("SCAN is disabled or SCAN in power save" + " is disabled and system is in power save.")); + limSendSmeScanRsp(pMac, offsetof(tSirSmeScanRsp,bssDescription[0]), eSIR_SME_INVALID_PARAMETERS, pScanReq->sessionId, pScanReq->transactionId); + return; + } + + + /** + * If scan request is received in idle, joinFailed + * states or in link established state (in STA role) + * or in normal state (in STA-in-IBSS/AP role) with + * 'return fresh scan results' request from HDD or + * it is periodic background scanning request, + * trigger fresh scan request to MLM + */ + if (__limFreshScanReqd(pMac, pScanReq->returnFreshResults)) + { + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS) + { + // Discard previously cached scan results + limReInitScanResults(pMac); + } + + pMac->lim.gLim24Band11dScanDone = 0; + pMac->lim.gLim50Band11dScanDone = 0; + pMac->lim.gLimReturnAfterFirstMatch = + pScanReq->returnAfterFirstMatch; + pMac->lim.gLimBackgroundScanMode = + pScanReq->backgroundScanMode; + + pMac->lim.gLimReturnUniqueResults = + ((pScanReq->returnUniqueResults) > 0 ? true : false); + /* De-activate Heartbeat timers for connected sessions while + * scan is in progress if the system is in Active mode * + * AND it is not a ROAMING ("background") scan */ + if(((ePMM_STATE_BMPS_WAKEUP == pMac->pmm.gPmmState) || + (ePMM_STATE_READY == pMac->pmm.gPmmState)) && + (pScanReq->backgroundScanMode != eSIR_ROAMING_SCAN ) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + for(i=0;ilim.maxBssId;i++) + { + if((peFindSessionBySessionId(pMac,i) != NULL) && + (pMac->lim.gpSession[i].valid == TRUE) && + (eLIM_MLM_LINK_ESTABLISHED_STATE == pMac->lim.gpSession[i].limMlmState)) + { + limHeartBeatDeactivateAndChangeTimer(pMac, peFindSessionBySessionId(pMac,i)); + } + } + } + + if (pMac->fScanOffload) + { + if (eHAL_STATUS_SUCCESS != + limSendHalStartScanOffloadReq(pMac, pScanReq)) + { + limLog(pMac, LOGE, FL("Couldn't send Offload scan request")); + limSendSmeScanRsp(pMac, + offsetof(tSirSmeScanRsp, bssDescription[0]), + eSIR_SME_INVALID_PARAMETERS, + pScanReq->sessionId, + pScanReq->transactionId); + return; + } + } + else + { + + /*Change Global SME state */ + /* Store the previous SME state */ + limLog(pMac, LOG1, FL("Non Offload SCAN request ")); + pMac->lim.gLimPrevSmeState = pMac->lim.gLimSmeState; + pMac->lim.gLimSmeState = eLIM_SME_WT_SCAN_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, pScanReq->sessionId, pMac->lim.gLimSmeState)); + + if (pScanReq->channelList.numChannels == 0) + { + tANI_U32 cfg_len; + + limLog(pMac, LOG1, + FL("Scan all channels as Number of channels is 0")); + // Scan all channels + len = sizeof(tLimMlmScanReq) + + (sizeof( pScanReq->channelList.channelNumber ) * (WNI_CFG_VALID_CHANNEL_LIST_LEN - 1)) + + pScanReq->uIEFieldLen; + pMlmScanReq = vos_mem_malloc(len); + if ( NULL == pMlmScanReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmScanReq (%d)"), len); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), + eSIR_SME_RESOURCES_UNAVAILABLE, + pScanReq->sessionId, + pScanReq->transactionId); + } + + return; + } + + // Initialize this buffer + vos_mem_set( (tANI_U8 *) pMlmScanReq, len, 0 ); + + cfg_len = WNI_CFG_VALID_CHANNEL_LIST_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + pMlmScanReq->channelList.channelNumber, + &cfg_len) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Valid channel list")); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), + eSIR_SME_INVALID_PARAMETERS, + pScanReq->sessionId, + pScanReq->transactionId); + } + vos_mem_free(pMlmScanReq); + return; + } + pMlmScanReq->channelList.numChannels = (tANI_U8) cfg_len; + + //Ignore DFS channels if DFS scan is disabled + if(pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_DISABLED) + { + tANI_U8 numChan = 0; + tANI_U8 channel_state; + tANI_U8 *chan_ptr = pMlmScanReq->channelList.channelNumber; + + limLog(pMac, LOG1, + FL("Ignore DFS channels from valid channel list")); + + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + pMlmScanReq->channelList.channelNumber, + pMlmScanReq->channelList.numChannels); + + //Filter DFS channels + for (i = 0; i < cfg_len; i++) + { + channel_state = + vos_nv_getChannelEnabledState(*(chan_ptr + i)); + + //Allow channel if not DFS + if(channel_state != NV_CHANNEL_DFS) + { + *(chan_ptr + numChan) = *(chan_ptr + i); + numChan++; + } + } + pMlmScanReq->channelList.numChannels = (tANI_U8) numChan; + + limLog(pMac, LOG1, FL("No of valid channels %d, No of" + "channels after filtering %d"), cfg_len, numChan); + + limLog(pMac, LOG1, FL("Channel list after filtering: ")); + + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + pMlmScanReq->channelList.channelNumber, + pMlmScanReq->channelList.numChannels); + } + } + else + { + len = sizeof( tLimMlmScanReq ) - sizeof( pScanReq->channelList.channelNumber ) + + (sizeof( pScanReq->channelList.channelNumber ) * pScanReq->channelList.numChannels ) + + pScanReq->uIEFieldLen; + + pMlmScanReq = vos_mem_malloc(len); + if ( NULL == pMlmScanReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmScanReq(%d)"), len); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), + eSIR_SME_RESOURCES_UNAVAILABLE, + pScanReq->sessionId, + pScanReq->transactionId); + } + + return; + } + + // Initialize this buffer + vos_mem_set( (tANI_U8 *) pMlmScanReq, len, 0); + pMlmScanReq->channelList.numChannels = + pScanReq->channelList.numChannels; + + vos_mem_copy( pMlmScanReq->channelList.channelNumber, + pScanReq->channelList.channelNumber, + pScanReq->channelList.numChannels); + } + + pMlmScanReq->uIEFieldLen = pScanReq->uIEFieldLen; + pMlmScanReq->uIEFieldOffset = len - pScanReq->uIEFieldLen; + if(pScanReq->uIEFieldLen) + { + vos_mem_copy( (tANI_U8 *)pMlmScanReq+ pMlmScanReq->uIEFieldOffset, + (tANI_U8 *)pScanReq+(pScanReq->uIEFieldOffset), + pScanReq->uIEFieldLen); + } + + pMlmScanReq->bssType = pScanReq->bssType; + vos_mem_copy( pMlmScanReq->bssId, + pScanReq->bssId, + sizeof(tSirMacAddr)); + pMlmScanReq->numSsid = pScanReq->numSsid; + + i = 0; + while (i < pMlmScanReq->numSsid) + { + vos_mem_copy( (tANI_U8 *) &pMlmScanReq->ssId[i], + (tANI_U8 *) &pScanReq->ssId[i], + pScanReq->ssId[i].length + 1); + + i++; + } + + + pMlmScanReq->scanType = pScanReq->scanType; + pMlmScanReq->backgroundScanMode = pScanReq->backgroundScanMode; + if (pMac->miracast_mode) + { + pMlmScanReq->minChannelTime = DEFAULT_MIN_CHAN_TIME_DURING_MIRACAST; + pMlmScanReq->maxChannelTime = DEFAULT_MAX_CHAN_TIME_DURING_MIRACAST; + } + else + { + pMlmScanReq->minChannelTime = pScanReq->minChannelTime; + pMlmScanReq->maxChannelTime = pScanReq->maxChannelTime; + } + + pMlmScanReq->min_chntime_btc_esco = + pScanReq->min_chntime_btc_esco; + pMlmScanReq->max_chntime_btc_esco = + pScanReq->max_chntime_btc_esco; + pMlmScanReq->dot11mode = pScanReq->dot11mode; + pMlmScanReq->p2pSearch = pScanReq->p2pSearch; + + //Store the smeSessionID and transaction ID for later use. + pMac->lim.gSmeSessionId = pScanReq->sessionId; + pMac->lim.gTransactionId = pScanReq->transactionId; + + // Issue LIM_MLM_SCAN_REQ to MLM + limLog(pMac, LOG1, FL("Issue Scan request command to MLM ")); + limPostMlmMessage(pMac, LIM_MLM_SCAN_REQ, (tANI_U32 *) pMlmScanReq); + } + } // if ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ... + + else + { + /// In all other cases return 'cached' scan results + if ((pMac->lim.gLimRspReqd) || pMac->lim.gLimReportBackgroundScanResults) + { + tANI_U16 scanRspLen = sizeof(tSirSmeScanRsp); + + pMac->lim.gLimRspReqd = false; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pScanReq->returnFreshResults & SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS) + { + pMac->lim.gLimSmeLfrScanResultLength = pMac->lim.gLimMlmLfrScanResultLength; + if (pMac->lim.gLimSmeLfrScanResultLength == 0) + { + limSendSmeLfrScanRsp(pMac, scanRspLen, + eSIR_SME_SUCCESS, + pScanReq->sessionId, + pScanReq->transactionId); + } + else + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeLfrScanResultLength - + sizeof(tSirBssDescription); + limSendSmeLfrScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, + pScanReq->sessionId, pScanReq->transactionId); + } + } + else + { +#endif + if (pMac->lim.gLimSmeScanResultLength == 0) + { + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, + pScanReq->sessionId, pScanReq->transactionId); + } + else + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, + pScanReq->sessionId, pScanReq->transactionId); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + limLog(pMac, LOG1, FL("Cached scan results are returned ")); + + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS) + { + // Discard previously cached scan results + limReInitScanResults(pMac); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_LFR_RESULTS) + { + // Discard previously cached scan results + limReInitLfrScanResults(pMac); + } +#endif + + } // if (pMac->lim.gLimRspReqd) + } // else ((pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) || ... + +#ifdef BACKGROUND_SCAN_ENABLED + // start background scans if needed + // There is a bug opened against softmac. Need to enable when the bug is fixed. + __limBackgroundScanInitiate(pMac); +#endif + +} /*** end __limProcessSmeScanReq() ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +static void __limProcessSmeOemDataReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirOemDataReq pOemDataReq; + tLimMlmOemDataReq* pMlmOemDataReq; + + pOemDataReq = (tpSirOemDataReq) pMsgBuf; + + //post the lim mlm message now + pMlmOemDataReq = vos_mem_malloc(sizeof(tLimMlmOemDataReq)); + if ( NULL == pMlmOemDataReq ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for mlmOemDataReq")); + return; + } + + //Initialize this buffer + vos_mem_set( pMlmOemDataReq, (sizeof(tLimMlmOemDataReq)), 0); + + vos_mem_copy( pMlmOemDataReq->selfMacAddr, pOemDataReq->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy( pMlmOemDataReq->oemDataReq, pOemDataReq->oemDataReq, + OEM_DATA_REQ_SIZE); + + //Issue LIM_MLM_OEM_DATA_REQ to MLM + limPostMlmMessage(pMac, LIM_MLM_OEM_DATA_REQ, (tANI_U32*)pMlmOemDataReq); + + return; + +} /*** end __limProcessSmeOemDataReq() ***/ + +#endif //FEATURE_OEM_DATA_SUPPORT + +/** + * __limProcessClearDfsChannelList() + * + *FUNCTION: + *Clear DFS channel list when country is changed/aquired. +.*This message is sent from SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void __limProcessClearDfsChannelList(tpAniSirGlobal pMac, + tpSirMsgQ pMsg) +{ + vos_mem_set( &pMac->lim.dfschannelList, + sizeof(tSirDFSChannelList), 0); +} + +/** + * __limProcessSmeJoinReq() + * + *FUNCTION: + * This function is called to process SME_JOIN_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeJoinReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + // tANI_U8 *pBuf; + //tANI_U32 len; +// tSirMacAddr currentBssId; + tpSirSmeJoinReq pSmeJoinReq = NULL; + tLimMlmJoinReq *pMlmJoinReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tANI_U32 val = 0; + tANI_U16 nSize; + tANI_U8 sessionId; + tpPESession psessionEntry = NULL; + tANI_U8 smesessionId = 0; + tANI_U16 smetransactionId = 0; + tPowerdBm localPowerConstraint = 0, regMax = 0; + tANI_U16 ieLen; + v_U8_t *vendorIE; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + //Not sending any session, since it is not created yet. The response whould have correct state. + limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limLog(pMac, LOG1, FL("Received SME_JOIN_REQ")); + +#ifdef WLAN_FEATURE_VOWIFI + /* Need to read the CFG here itself as this is used in limExtractAPCapability() below. + * This CFG is actually read in rrmUpdateConfig() which is called later. Because this is not + * read, RRM related path before calling rrmUpdateConfig() is not getting executed causing issues + * like not honoring power constraint on 1st association after driver loading. */ + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("cfg get rrm enabled failed")); + pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0; + val = 0; +#endif /* WLAN_FEATURE_VOWIFI */ + + /** + * Expect Join request in idle state. + * Reassociate request is expected in link established state. + */ + + /* Global SME and LIM states are not defined yet for BT-AMP Support */ + if(pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) + { + nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8*) pMsgBuf); + + pSmeJoinReq = vos_mem_malloc(nSize); + if ( NULL == pSmeJoinReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for " + "pSmeJoinReq")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + (void) vos_mem_set((void *) pSmeJoinReq, nSize, 0); + + if ((limJoinReqSerDes(pMac, pSmeJoinReq, (tANI_U8 *)pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeJoinReqValid(pMac, pSmeJoinReq))) + { + /// Received invalid eWNI_SME_JOIN_REQ + // Log the event + limLog(pMac, LOGW, FL("SessionId:%d Received SME_JOIN_REQ with" + "invalid data"),pSmeJoinReq->sessionId); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + //pMac->lim.gpLimJoinReq = pSmeJoinReq; TO SUPPORT BT-AMP, review os sep 23 + + /* check for the existence of start BSS session */ +#ifdef FIXME_GEN6 + if(pSmeJoinReq->bsstype == eSIR_BTAMP_AP_MODE) + { + if(peValidateBtJoinRequest(pMac)!= TRUE) + { + limLog(pMac, LOGW, FL("SessionId:%d Start Bss session" + "not present::SME_JOIN_REQ in unexpected state"), + pSmeJoinReq->sessionId); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + psessionEntry = NULL; + goto end; + } + } + +#endif + + + if((psessionEntry = peFindSessionByBssid(pMac,pSmeJoinReq->bssDescription.bssId,&sessionId)) != NULL) + { + limLog(pMac, LOGE, FL("Session(%d) Already exists for BSSID: " + MAC_ADDRESS_STR" in limSmeState = %d"),sessionId, + MAC_ADDR_ARRAY(pSmeJoinReq->bssDescription.bssId), + psessionEntry->limSmeState); + + if(psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE) + { + // Received eWNI_SME_JOIN_REQ for same + // BSS as currently associated. + // Log the event and send success + PELOGW(limLog(pMac, LOGW, FL("SessionId:%d Received" + "SME_JOIN_REQ for currently joined BSS"),sessionId);) + /// Send Join success response to host + retCode = eSIR_SME_ALREADY_JOINED_A_BSS; + psessionEntry = NULL; + goto end; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("SME_JOIN_REQ not for" + "currently joined BSS"));) + retCode = eSIR_SME_REFUSED; + psessionEntry = NULL; + goto end; + } + } + else /* Session Entry does not exist for given BSSId */ + { + /* Try to Create a new session */ + if((psessionEntry = peCreateSession(pMac,pSmeJoinReq->bssDescription.bssId,&sessionId, pMac->lim.maxStation)) == NULL) + { + limLog(pMac, LOGE, FL("Session Can not be created ")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + limLog(pMac,LOG1,FL("SessionId:%d New session created"), + sessionId); + } + + if(psessionEntry != NULL && pSmeJoinReq->operationalRateSet.numRates > 0 ){ + if(!limCheck11BRateBitmap(pSmeJoinReq->rateBitMap)){ + psessionEntry->is11Gonly = true; + } + } + + psessionEntry->isAmsduSupportInAMPDU = pSmeJoinReq->isAmsduSupportInAMPDU; + + /* Store Session related parameters */ + /* Store PE session Id in session Table */ + psessionEntry->peSessionId = sessionId; + + /* store the smejoin req handle in session table */ + psessionEntry->pLimJoinReq = pSmeJoinReq; + + /* Store SME session Id in sessionTable */ + psessionEntry->smeSessionId = pSmeJoinReq->sessionId; + + /* Store SME transaction Id in session Table */ + psessionEntry->transactionId = pSmeJoinReq->transactionId; + + /* Store beaconInterval */ + psessionEntry->beaconParams.beaconInterval = pSmeJoinReq->bssDescription.beaconInterval; + + /* Copying of bssId is already done, while creating session */ + //sirCopyMacAddr(psessionEntry->bssId,pSmeJoinReq->bssId); + sirCopyMacAddr(psessionEntry->selfMacAddr,pSmeJoinReq->selfMacAddr); + psessionEntry->bssType = pSmeJoinReq->bsstype; + + psessionEntry->statypeForBss = STA_ENTRY_PEER; + psessionEntry->limWmeEnabled = pSmeJoinReq->isWMEenabled; + psessionEntry->limQosEnabled = pSmeJoinReq->isQosEnabled; + psessionEntry->bOSENAssociation = pSmeJoinReq->bOSENAssociation; + psessionEntry->bWPSAssociation = pSmeJoinReq->bWPSAssociation; + + /* Store vendor specfic IE for CISCO AP */ + ieLen = GET_IE_LEN_IN_BSS(pSmeJoinReq->bssDescription.length); + + vendorIE = limGetVendorIEOuiPtr(pMac, SIR_MAC_CISCO_OUI, + SIR_MAC_CISCO_OUI_SIZE, + ((tANI_U8 *)&pSmeJoinReq->bssDescription.ieFields) , ieLen); + + if ( NULL != vendorIE ) + { + limLog(pMac, LOGE, + FL("DUT is trying to connect to Cisco AP")); + psessionEntry->isCiscoVendorAP = TRUE; + } + else + { + psessionEntry->isCiscoVendorAP = FALSE; + } + + /* Copy the dot 11 mode in to the session table */ + + psessionEntry->dot11mode = pSmeJoinReq->dot11mode; + psessionEntry->nwType = pSmeJoinReq->bssDescription.nwType; +#ifdef WLAN_FEATURE_11AC + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(psessionEntry->dot11mode); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***__limProcessSmeJoinReq: vhtCapability=%d****",psessionEntry->vhtCapability); + if (psessionEntry->vhtCapability ) + { + psessionEntry->txBFIniFeatureEnabled = pSmeJoinReq->txBFIniFeatureEnabled; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***__limProcessSmeJoinReq: txBFIniFeatureEnabled=%d****", + psessionEntry->txBFIniFeatureEnabled); + + if (cfgSetInt(pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, + psessionEntry->txBFIniFeatureEnabled) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_SU_BEAMFORMEE_CAP at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto end; + } + if( psessionEntry->txBFIniFeatureEnabled ) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***__limProcessSmeJoinReq: txBFCsnValue=%d****", + pSmeJoinReq->txBFCsnValue); + + if (cfgSetInt(pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, pSmeJoinReq->txBFCsnValue) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not set " + "WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto end; + } + + if ( FALSE == pMac->isMuBfsessionexist ) + psessionEntry->txMuBformee = pSmeJoinReq->txMuBformee; + } + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "SmeJoinReq:txMuBformee=%d psessionEntry: txMuBformee = %d", + pSmeJoinReq->txMuBformee, psessionEntry->txMuBformee); + + if(cfgSetInt(pMac, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, psessionEntry->txMuBformee) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not set " + "WNI_CFG_VHT_MU_BEAMFORMEE_CAP at CFG")); + retCode = eSIR_LOGP_EXCEPTION; + goto end; + } + + } + +#endif + + /*Phy mode*/ + psessionEntry->gLimPhyMode = pSmeJoinReq->bssDescription.nwType; + + handleHTCapabilityandHTInfo(pMac, psessionEntry); + /* Copy The channel Id to the session Table */ + psessionEntry->currentOperChannel = pSmeJoinReq->bssDescription.channelId; + psessionEntry->force_24ghz_in_ht20 = pSmeJoinReq->force_24ghz_in_ht20; + psessionEntry->htSupportedChannelWidthSet = (pSmeJoinReq->cbMode)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + psessionEntry->htSecondaryChannelOffset = pSmeJoinReq->cbMode; + + /* Record if management frames need to be protected */ +#ifdef WLAN_FEATURE_11W + if(eSIR_ED_AES_128_CMAC == pSmeJoinReq->MgmtEncryptionType) + { + psessionEntry->limRmfEnabled = 1; + } + else + { + psessionEntry->limRmfEnabled = 0; + } +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM + psessionEntry->rssi = pSmeJoinReq->bssDescription.rssi; +#endif + + /*Store Persona */ + psessionEntry->pePersona = pSmeJoinReq->staPersona; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("PE PERSONA=%d cbMode %u force_24ghz_in_ht20 %d"), + psessionEntry->pePersona, + pSmeJoinReq->cbMode, + psessionEntry->force_24ghz_in_ht20); + + /* Copy the SSID from smejoinreq to session entry */ + psessionEntry->ssId.length = pSmeJoinReq->ssId.length; + vos_mem_copy( psessionEntry->ssId.ssId, + pSmeJoinReq->ssId.ssId, psessionEntry->ssId.length); + + // Determin 11r or ESE connection based on input from SME + // which inturn is dependent on the profile the user wants to connect + // to, So input is coming from supplicant +#ifdef WLAN_FEATURE_VOWIFI_11R + psessionEntry->is11Rconnection = pSmeJoinReq->is11Rconnection; +#endif +#ifdef FEATURE_WLAN_ESE + psessionEntry->isESEconnection = pSmeJoinReq->isESEconnection; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + psessionEntry->isFastTransitionEnabled = pSmeJoinReq->isFastTransitionEnabled; +#endif + +#ifdef FEATURE_WLAN_LFR + psessionEntry->isFastRoamIniFeatureEnabled = pSmeJoinReq->isFastRoamIniFeatureEnabled; +#endif + psessionEntry->txLdpcIniFeatureEnabled = pSmeJoinReq->txLdpcIniFeatureEnabled; + + if (psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) + { + psessionEntry->limSystemRole = eLIM_STA_ROLE; + } + else if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) + { + psessionEntry->limSystemRole = eLIM_BT_AMP_STA_ROLE; + } + else + { + /* Throw an error and return and make sure to delete the session.*/ + limLog(pMac, LOGE, FL("received SME_JOIN_REQ with invalid" + " bss type %d"), psessionEntry->bssType); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + if (pSmeJoinReq->addIEScan.length) + { + vos_mem_copy( &psessionEntry->pLimJoinReq->addIEScan, + &pSmeJoinReq->addIEScan, sizeof(tSirAddie)); + } + + if (pSmeJoinReq->addIEAssoc.length) + { + vos_mem_copy( &psessionEntry->pLimJoinReq->addIEAssoc, + &pSmeJoinReq->addIEAssoc, sizeof(tSirAddie)); + } + + val = sizeof(tLimMlmJoinReq) + psessionEntry->pLimJoinReq->bssDescription.length + 2; + pMlmJoinReq = vos_mem_malloc(val); + if ( NULL == pMlmJoinReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory " + "failed for mlmJoinReq")); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + (void) vos_mem_set((void *) pMlmJoinReq, val, 0); + + /* PE SessionId is stored as a part of JoinReq*/ + pMlmJoinReq->sessionId = psessionEntry->peSessionId; + + if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, (tANI_U32 *) &pMlmJoinReq->joinFailureTimeout) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not retrieve JoinFailureTimer value " + "setting it to default value")); + pMlmJoinReq->joinFailureTimeout = JOIN_FAILURE_TIMEOUT; + } + + /* copy operational rate from psessionEntry*/ + vos_mem_copy((void*)&psessionEntry->rateSet, (void*)&pSmeJoinReq->operationalRateSet, + sizeof(tSirMacRateSet)); + vos_mem_copy((void*)&psessionEntry->extRateSet, (void*)&pSmeJoinReq->extendedRateSet, + sizeof(tSirMacRateSet)); + //this may not be needed anymore now, as rateSet is now included in the session entry and MLM has session context. + vos_mem_copy((void*)&pMlmJoinReq->operationalRateSet, (void*)&psessionEntry->rateSet, + sizeof(tSirMacRateSet)); + + psessionEntry->encryptType = pSmeJoinReq->UCEncryptionType; + + pMlmJoinReq->bssDescription.length = psessionEntry->pLimJoinReq->bssDescription.length; + + vos_mem_copy((tANI_U8 *) &pMlmJoinReq->bssDescription.bssId, + (tANI_U8 *) &psessionEntry->pLimJoinReq->bssDescription.bssId, + psessionEntry->pLimJoinReq->bssDescription.length + 2); + + psessionEntry->limCurrentBssCaps = + psessionEntry->pLimJoinReq->bssDescription.capabilityInfo; + + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); + localPowerConstraint = regMax; + limExtractApCapability(pMac, + (tANI_U8 *) psessionEntry->pLimJoinReq->bssDescription.ieFields, + GET_IE_LEN_IN_BSS(psessionEntry->pLimJoinReq->bssDescription.length), + &psessionEntry->limCurrentBssQosCaps, + &psessionEntry->limCurrentBssPropCap, + &pMac->lim.gLimCurrentBssUapsd, + &localPowerConstraint, + psessionEntry); + +#ifdef FEATURE_WLAN_ESE + psessionEntry->maxTxPower = limGetMaxTxPower(regMax, localPowerConstraint, pMac->roam.configParam.nTxPowerCap); +#else + psessionEntry->maxTxPower = VOS_MIN( regMax, (localPowerConstraint) ); +#endif + if (!psessionEntry->maxTxPower) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, FL("Tx power" + "is zero. Setting it to default value %d"), + TX_POWER_DEFAULT); + psessionEntry->maxTxPower = TX_POWER_DEFAULT; + } + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "Regulatory max = %d, local power constraint = %d," + " max tx = %d", regMax, localPowerConstraint, + psessionEntry->maxTxPower ); + + if (pSmeJoinReq->powerCap.maxTxPower > psessionEntry->maxTxPower) + { + pSmeJoinReq->powerCap.maxTxPower = psessionEntry->maxTxPower; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "Update MaxTxPower in join Req to %d", + pSmeJoinReq->powerCap.maxTxPower); + } + + if (pMac->lim.gLimCurrentBssUapsd) + { + pMac->lim.gUapsdPerAcBitmask = psessionEntry->pLimJoinReq->uapsdPerAcBitmask; + limLog( pMac, LOG1, FL("UAPSD flag for all AC - 0x%2x"), + pMac->lim.gUapsdPerAcBitmask); + + // resetting the dynamic uapsd mask + pMac->lim.gUapsdPerAcDeliveryEnableMask = 0; + pMac->lim.gUapsdPerAcTriggerEnableMask = 0; + } + + psessionEntry->limRFBand = limGetRFBand(psessionEntry->currentOperChannel); + + // Initialize 11h Enable Flag + if(SIR_BAND_5_GHZ == psessionEntry->limRFBand) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED ")); + psessionEntry->lim11hEnable = 1; + } + else + psessionEntry->lim11hEnable = val; + } + else + psessionEntry->lim11hEnable = 0; + + //To care of the scenario when STA transitions from IBSS to Infrastructure mode. + pMac->lim.gLimIbssCoalescingHappened = false; + + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_JOIN_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + limLog(pMac, LOG1, FL("SME JoinReq:Sessionid %d SSID len %d SSID : %s " + "Channel %d, BSSID "MAC_ADDRESS_STR), pMlmJoinReq->sessionId, + psessionEntry->ssId.length,psessionEntry->ssId.ssId, + psessionEntry->currentOperChannel, + MAC_ADDR_ARRAY(psessionEntry->bssId)); + + /* Indicate whether spectrum management is enabled*/ + psessionEntry->spectrumMgtEnabled = + pSmeJoinReq->spectrumMgtIndicator; + + /* Enable the spectrum management if this is a DFS channel */ + if (psessionEntry->countryInfoPresent && + limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel)) + { + psessionEntry->spectrumMgtEnabled = TRUE; + } + + limLog(pMac,LOG1,FL("SessionId: %d LIM_MLM_JOIN_REQ is posted to MLM " + "SM"), pMlmJoinReq->sessionId); + /* Issue LIM_MLM_JOIN_REQ to MLM */ + limPostMlmMessage(pMac, LIM_MLM_JOIN_REQ, (tANI_U32 *) pMlmJoinReq); + return; + + } + else + { + /* Received eWNI_SME_JOIN_REQ un expected state */ + limLog(pMac, LOGE, FL("received unexpected SME_JOIN_REQ " + "in state %d"), pMac->lim.gLimSmeState); + limPrintSmeState(pMac, LOGE, pMac->lim.gLimSmeState); + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + psessionEntry = NULL; + goto end; + + } + +end: + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf,&smesessionId,&smetransactionId); + + if(pSmeJoinReq) + { + vos_mem_free(pSmeJoinReq); + pSmeJoinReq = NULL; + if (NULL != psessionEntry) + { + psessionEntry->pLimJoinReq = NULL; + } + } + + if(retCode != eSIR_SME_SUCCESS) + { + if(NULL != psessionEntry) + { + peDeleteSession(pMac,psessionEntry); + psessionEntry = NULL; + } + } + limLog(pMac, LOG1, FL("Sending failure status limSendSmeJoinReassocRsp" + "on sessionid: %d with retCode = %d"),smesessionId, retCode); + limSendSmeJoinReassocRsp(pMac, eWNI_SME_JOIN_RSP, retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS,psessionEntry,smesessionId,smetransactionId); +} /*** end __limProcessSmeJoinReq() ***/ + + +#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI +tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower, tANI_U8 iniTxPower) +{ + tANI_U8 maxTxPower = 0; + tANI_U8 txPower = VOS_MIN( regMax, (apTxPower) ); + txPower = VOS_MIN(txPower, iniTxPower); + if((txPower >= MIN_TX_PWR_CAP) && (txPower <= MAX_TX_PWR_CAP)) + maxTxPower = txPower; + else if (txPower < MIN_TX_PWR_CAP) + maxTxPower = MIN_TX_PWR_CAP; + else + maxTxPower = MAX_TX_PWR_CAP; + + return (maxTxPower); +} +#endif + +/** + * __limProcessSmeReassocReq() + * + *FUNCTION: + * This function is called to process SME_REASSOC_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeReassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 caps; + tANI_U32 val; + tpSirSmeJoinReq pReassocReq = NULL; + tLimMlmReassocReq *pMlmReassocReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + tANI_U8 smeSessionId; + tANI_U16 transactionId; + tPowerdBm localPowerConstraint = 0, regMax = 0; + tANI_U32 teleBcnEn = 0; + tANI_U16 nSize; + + + limLog(pMac, LOG1, FL("Received SME_REASSOC_REQ")); + + nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) pMsgBuf); + pReassocReq = vos_mem_malloc(nSize); + if ( NULL == pReassocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for pReassocReq")); + + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + (void) vos_mem_set((void *) pReassocReq, nSize, 0); + if ((limJoinReqSerDes(pMac, (tpSirSmeJoinReq) pReassocReq, + (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeJoinReqValid(pMac, + (tpSirSmeJoinReq) pReassocReq))) + { + /// Received invalid eWNI_SME_REASSOC_REQ + // Log the event + limLog(pMac, LOGW, + FL("received SME_REASSOC_REQ with invalid data")); + + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac,pReassocReq->bssDescription.bssId,&sessionId))==NULL) + { + limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE); + limLog(pMac, LOGE, FL("Session does not exist for given bssId")); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_REQ_EVENT, psessionEntry, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + //pMac->lim.gpLimReassocReq = pReassocReq;//TO SUPPORT BT-AMP + + /* Store the reassoc handle in the session Table.. 23rd sep review */ + psessionEntry->pLimReAssocReq = pReassocReq; + psessionEntry->dot11mode = pReassocReq->dot11mode; + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(pReassocReq->dot11mode); + + /** + * Reassociate request is expected + * in link established state only. + */ + + if (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE) + { +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) + { + // May be from 11r FT pre-auth. So lets check it before we bail out + limLog(pMac, LOG1, FL("Session in reassoc state is %d"), + psessionEntry->peSessionId); + + // Make sure its our preauth bssid + if (!vos_mem_compare( pReassocReq->bssDescription.bssId, + pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, 6)) + { + limPrintMacAddr(pMac, pReassocReq->bssDescription.bssId, LOGE); + limPrintMacAddr(pMac, pMac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE); + limLog(pMac, LOGP, FL("Unknown bssId in reassoc state")); + retCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + limProcessMlmFTReassocReq(pMac, pMsgBuf, psessionEntry); + return; + } +#endif + /// Should not have received eWNI_SME_REASSOC_REQ + // Log the event + limLog(pMac, LOGE, + FL("received unexpected SME_REASSOC_REQ in state %d"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + goto end; + } + + vos_mem_copy( psessionEntry->limReAssocbssId, + psessionEntry->pLimReAssocReq->bssDescription.bssId, + sizeof(tSirMacAddr)); + + psessionEntry->limReassocChannelId = + psessionEntry->pLimReAssocReq->bssDescription.channelId; + + psessionEntry->reAssocHtSupportedChannelWidthSet = + (psessionEntry->pLimReAssocReq->cbMode)?1:0; + psessionEntry->reAssocHtRecommendedTxWidthSet = + psessionEntry->reAssocHtSupportedChannelWidthSet; + psessionEntry->reAssocHtSecondaryChannelOffset = + psessionEntry->pLimReAssocReq->cbMode; + + psessionEntry->limReassocBssCaps = + psessionEntry->pLimReAssocReq->bssDescription.capabilityInfo; + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); + localPowerConstraint = regMax; + limExtractApCapability(pMac, + (tANI_U8 *) psessionEntry->pLimReAssocReq->bssDescription.ieFields, + GET_IE_LEN_IN_BSS( + psessionEntry->pLimReAssocReq->bssDescription.length), + &psessionEntry->limReassocBssQosCaps, + &psessionEntry->limReassocBssPropCap, + &pMac->lim.gLimCurrentBssUapsd, + &localPowerConstraint, + psessionEntry); + + psessionEntry->maxTxPower = VOS_MIN( regMax, (localPowerConstraint) ); + if (!psessionEntry->maxTxPower) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, FL("Tx power " + "is zero. Setting it to default value %d"), + TX_POWER_DEFAULT); + psessionEntry->maxTxPower = TX_POWER_DEFAULT; + } +#if defined WLAN_VOWIFI_DEBUG + limLog( pMac, LOGE, "Regulatory max = %d, local power constraint " + "= %d, max tx = %d", regMax, localPowerConstraint, + psessionEntry->maxTxPower ); +#endif + { + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_SSID, pMac->lim.gLimReassocSSID.ssId, + &cfgLen) != eSIR_SUCCESS) + { + /// Could not get SSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrive SSID")); + } + #endif//TO SUPPORT BT-AMP + + /* Copy the SSID from sessio entry to local variable */ + #if 0 + vos_mem_copy( pMac->lim.gLimReassocSSID.ssId, + psessionEntry->ssId.ssId, + psessionEntry->ssId.length); + #endif + psessionEntry->limReassocSSID.length = pReassocReq->ssId.length; + vos_mem_copy( psessionEntry->limReassocSSID.ssId, + pReassocReq->ssId.ssId, psessionEntry->limReassocSSID.length); + + } + + if (pMac->lim.gLimCurrentBssUapsd) + { + pMac->lim.gUapsdPerAcBitmask = psessionEntry->pLimReAssocReq->uapsdPerAcBitmask; + limLog( pMac, LOG1, FL("UAPSD flag for all AC - 0x%2x"), + pMac->lim.gUapsdPerAcBitmask); + } + + pMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if ( NULL == pMlmReassocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmReassocReq")); + + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + + vos_mem_copy( pMlmReassocReq->peerMacAddr, + psessionEntry->limReAssocbssId, + sizeof(tSirMacAddr)); + + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + (tANI_U32 *) &pMlmReassocReq->reassocFailureTimeout) + != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve ReassocFailureTimeout value")); + } + + if (cfgGetCapabilityInfo(pMac, &caps,psessionEntry) != eSIR_SUCCESS) + { + /** + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Capabilities value")); + } + + lim_update_caps_info_for_bss(pMac, &caps, + pReassocReq->bssDescription.capabilityInfo); + + limLog(pMac, LOG1, FL("Capabilities info Reassoc: 0x%X"), caps); + + pMlmReassocReq->capabilityInfo = caps; + + /* Update PE sessionId*/ + pMlmReassocReq->sessionId = sessionId; + + /* If telescopic beaconing is enabled, set listen interval to + WNI_CFG_TELE_BCN_MAX_LI */ + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, &teleBcnEn) != + eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Couldn't get WNI_CFG_TELE_BCN_WAKEUP_EN")); + + val = WNI_CFG_LISTEN_INTERVAL_STADEF; + + if(teleBcnEn) + { + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, &val) != + eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + else + { + if (wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &val) != eSIR_SUCCESS) + { + /** + * Could not get ListenInterval value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ListenInterval")); + } + } + + /* Delete all BA sessions before Re-Assoc. + * BA frames are class 3 frames and the session + * is lost upon disassociation and reassociation. + */ + + limDeleteBASessions(pMac, psessionEntry, BA_BOTH_DIRECTIONS, + eSIR_MAC_UNSPEC_FAILURE_REASON); + + pMlmReassocReq->listenInterval = (tANI_U16) val; + + /* Indicate whether spectrum management is enabled*/ + psessionEntry->spectrumMgtEnabled = pReassocReq->spectrumMgtIndicator; + + /* Enable the spectrum management if this is a DFS channel */ + if (psessionEntry->countryInfoPresent && + limIsconnectedOnDFSChannel(psessionEntry->currentOperChannel)) + { + psessionEntry->spectrumMgtEnabled = TRUE; + } + + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + limPostMlmMessage(pMac, + LIM_MLM_REASSOC_REQ, + (tANI_U32 *) pMlmReassocReq); + return; + +end: + if (pReassocReq) + vos_mem_free( pReassocReq); + + if (psessionEntry) + { + // error occurred after we determined the session so extract + // session and transaction info from there + smeSessionId = psessionEntry->smeSessionId; + transactionId = psessionEntry->transactionId; + } + else + { + // error occurred before or during the time we determined the session + // so extract the session and transaction info from the message + limGetSessionInfo(pMac,(tANI_U8*)pMsgBuf, &smeSessionId, &transactionId); + } + + /// Send Reassoc failure response to host + /// (note psessionEntry may be NULL, but that's OK) + limSendSmeJoinReassocRsp(pMac, eWNI_SME_REASSOC_RSP, + retCode, eSIR_MAC_UNSPEC_FAILURE_STATUS, + psessionEntry, smeSessionId, transactionId); + +} /*** end __limProcessSmeReassocReq() ***/ + + +tANI_BOOLEAN sendDisassocFrame = 1; +/** + * __limProcessSmeDisassocReq() + * + *FUNCTION: + * This function is called to process SME_DISASSOC_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeDisassocReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 disassocTrigger, reasonCode; + tLimMlmDisassocReq *pMlmDisassocReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tSirRetStatus status; + tSirSmeDisassocReq smeDisassocReq; + tpPESession psessionEntry = NULL; + tANI_U8 sessionId; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + if (pMsgBuf == NULL) + { + limLog(pMac, LOGE, FL("Buffer is Pointing to NULL")); + return; + } + + limGetSessionInfo(pMac, (tANI_U8 *)pMsgBuf,&smesessionId, &smetransactionId); + + status = limDisassocReqSerDes(pMac, &smeDisassocReq, (tANI_U8 *) pMsgBuf); + + if ( (eSIR_FAILURE == status) || + (!limIsSmeDisassocReqValid(pMac, &smeDisassocReq, psessionEntry)) ) + { + PELOGE(limLog(pMac, LOGE, + FL("received invalid SME_DISASSOC_REQ message"));) + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_INVALID_PARAMETERS; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } + + return; + } + + if((psessionEntry = peFindSessionByBssid(pMac,smeDisassocReq.bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(smeDisassocReq.bssId)); + retCode = eSIR_SME_INVALID_PARAMETERS; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + + } + limLog(pMac, LOG1, FL("received DISASSOC_REQ message on sessionid %d" + "Systemrole %d Reason: %u SmeState: %d from: "MAC_ADDRESS_STR), + smesessionId,psessionEntry->limSystemRole, + smeDisassocReq.reasonCode, pMac->lim.gLimSmeState, + MAC_ADDR_ARRAY(smeDisassocReq.peerMacAddr)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, psessionEntry, 0, smeDisassocReq.reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Update SME session Id and SME transaction ID*/ + + psessionEntry->smeSessionId = smesessionId; + psessionEntry->transactionId = smetransactionId; + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + switch (psessionEntry->limSmeState) + { + case eLIM_SME_ASSOCIATED_STATE: + case eLIM_SME_LINK_EST_STATE: + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "limSmeState: %d "),psessionEntry->limSmeState); + + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE; +#ifdef FEATURE_WLAN_TDLS + /* Delete all TDLS peers connected before leaving BSS*/ + limDeleteTDLSPeers(pMac, psessionEntry); +#endif + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + break; + + case eLIM_SME_WT_DEAUTH_STATE: + /* PE shall still process the DISASSOC_REQ and proceed with + * link tear down even if it had already sent a DEAUTH_IND to + * to SME. pMac->lim.gLimPrevSmeState shall remain the same as + * its been set when PE entered WT_DEAUTH_STATE. + */ + psessionEntry->limSmeState= eLIM_SME_WT_DISASSOC_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "SME_WT_DEAUTH_STATE. ")); + break; + + case eLIM_SME_WT_DISASSOC_STATE: + /* PE Recieved a Disassoc frame. Normally it gets DISASSOC_CNF but it + * received DISASSOC_REQ. Which means host is also trying to disconnect. + * PE can continue processing DISASSOC_REQ and send the response instead + * of failing the request. SME will anyway ignore DEAUTH_IND that was sent + * for disassoc frame. + * + * It will send a disassoc, which is ok. However, we can use the global flag + * sendDisassoc to not send disassoc frame. + */ + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "SME_WT_DISASSOC_STATE. ")); + break; + + case eLIM_SME_JOIN_FAILURE_STATE: { + /** Return Success as we are already in Disconnected State*/ + limLog(pMac, LOG1, FL("Rcvd SME_DISASSOC_REQ while in " + "eLIM_SME_JOIN_FAILURE_STATE. ")); + if (pMac->lim.gLimRspReqd) { + retCode = eSIR_SME_SUCCESS; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } + }break; + default: + /** + * STA is not currently associated. + * Log error and send response to host + */ + limLog(pMac, LOGE, + FL("received unexpected SME_DISASSOC_REQ in state %d"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + if (pMac->lim.gLimRspReqd) + { + if (psessionEntry->limSmeState != + eLIM_SME_WT_ASSOC_STATE) + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } + + return; + } + + break; + + case eLIM_AP_ROLE: + case eLIM_BT_AMP_AP_ROLE: + // Fall through + break; + + case eLIM_STA_IN_IBSS_ROLE: + default: // eLIM_UNKNOWN_ROLE + limLog(pMac, LOGE, + FL("received unexpected SME_DISASSOC_REQ for role %d"), + psessionEntry->limSystemRole); + + retCode = eSIR_SME_UNEXPECTED_REQ_RESULT_CODE; + disassocTrigger = eLIM_HOST_DISASSOC; + goto sendDisassoc; + } // end switch (pMac->lim.gLimSystemRole) + + disassocTrigger = eLIM_HOST_DISASSOC; + reasonCode = smeDisassocReq.reasonCode; + + if (smeDisassocReq.doNotSendOverTheAir) + { + limLog(pMac, LOG1, FL("do not send dissoc over the air")); + sendDisassocFrame = 0; + } + // Trigger Disassociation frame to peer MAC entity + limLog(pMac, LOG1, FL("Sending Disasscoc with disassoc Trigger" + " : %d, reasonCode : %d"), + disassocTrigger, reasonCode); + pMlmDisassocReq = vos_mem_malloc(sizeof(tLimMlmDisassocReq)); + if ( NULL == pMlmDisassocReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmDisassocReq")); + + return; + } + + vos_mem_copy( (tANI_U8 *) &pMlmDisassocReq->peerMacAddr, + (tANI_U8 *) &smeDisassocReq.peerMacAddr, + sizeof(tSirMacAddr)); + + pMlmDisassocReq->reasonCode = reasonCode; + pMlmDisassocReq->disassocTrigger = disassocTrigger; + + /* Update PE session ID*/ + pMlmDisassocReq->sessionId = sessionId; + + limPostMlmMessage(pMac, + LIM_MLM_DISASSOC_REQ, + (tANI_U32 *) pMlmDisassocReq); + return; + +sendDisassoc: + if (psessionEntry) + limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr, + retCode, + disassocTrigger, + 1,smesessionId,smetransactionId,psessionEntry); + else + limSendSmeDisassocNtf(pMac, smeDisassocReq.peerMacAddr, + retCode, + disassocTrigger, + 1, smesessionId, smetransactionId, NULL); + + +} /*** end __limProcessSmeDisassocReq() ***/ + + +/** ----------------------------------------------------------------- + \brief __limProcessSmeDisassocCnf() - Process SME_DISASSOC_CNF + + This function is called to process SME_DISASSOC_CNF message + from HDD or upper layer application. + + \param pMac - global mac structure + \param pStaDs - station dph hash node + \return none + \sa + ----------------------------------------------------------------- */ +static void +__limProcessSmeDisassocCnf(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeDisassocCnf smeDisassocCnf; + tANI_U16 aid; + tpDphHashNode pStaDs; + tSirRetStatus status = eSIR_SUCCESS; + tpPESession psessionEntry; + tANI_U8 sessionId; + + + limLog(pMac, LOG1, FL("received SME_DISASSOC_CNF message")); + + status = limDisassocCnfSerDes(pMac, &smeDisassocCnf,(tANI_U8 *) pMsgBuf); + + if (status == eSIR_FAILURE) + { + PELOGE(limLog(pMac, LOGE, FL("invalid SME_DISASSOC_CNF message"));) + return; + } + + if((psessionEntry = peFindSessionByBssid(pMac, smeDisassocCnf.bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + return; + } + + if (!limIsSmeDisassocCnfValid(pMac, &smeDisassocCnf, psessionEntry)) + { + limLog(pMac, LOGE, FL("received invalid SME_DISASSOC_CNF message")); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + if (smeDisassocCnf.messageType == eWNI_SME_DISASSOC_CNF) + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0); + else if (smeDisassocCnf.messageType == eWNI_SME_DEAUTH_CNF) + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_CNF_EVENT, psessionEntry, (tANI_U16)smeDisassocCnf.statusCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: //To test reconn + if ((psessionEntry->limSmeState != eLIM_SME_IDLE_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + limLog(pMac, LOGE, + FL("received unexp SME_DISASSOC_CNF in state %d"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + return; + } + break; + + case eLIM_AP_ROLE: + // Fall through + break; + + case eLIM_STA_IN_IBSS_ROLE: + default: // eLIM_UNKNOWN_ROLE + limLog(pMac, LOGE, + FL("received unexpected SME_DISASSOC_CNF role %d"), + psessionEntry->limSystemRole); + + return; + } + + + if ( (psessionEntry->limSmeState == eLIM_SME_WT_DISASSOC_STATE) || + (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE) + || (psessionEntry->limSystemRole == eLIM_AP_ROLE ) + ) + { + pStaDs = dphLookupHashEntry(pMac, smeDisassocCnf.peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("received DISASSOC_CNF for a STA that " + "does not have context, addr= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr));) + return; + } + + if(aid != smeDisassocCnf.assocId) + { + PELOGE(limLog(pMac, LOGE, FL("same peerMacAddr but assocId is different " + "aid=%d, assocId=%d, addr= "MAC_ADDRESS_STR), + aid, smeDisassocCnf.assocId, MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr));) + return; + } + /* + * If MlM state is either of del_sta or del_bss state, then no need to + * go ahead and clean up further as there must be some cleanup in + * progress from upper layer disassoc/deauth request. + */ + if((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) + { + limLog(pMac, LOGE, FL("No need to cleanup for addr:"MAC_ADDRESS_STR + "as Mlm state is %d"), + MAC_ADDR_ARRAY(smeDisassocCnf.peerMacAddr), + pStaDs->mlmStaContext.mlmState); + return; + } + + /* Delete FT session if there exists one */ + limFTCleanup(pMac); + limCleanupRxPath(pMac, pStaDs, psessionEntry); + + limCleanUpDisassocDeauthReq(pMac, (char*)&smeDisassocCnf.peerMacAddr, 0); + } + + return; +} + + +/** + * __limProcessSmeDeauthReq() + * + *FUNCTION: + * This function is called to process SME_DEAUTH_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 deauthTrigger, reasonCode; + tLimMlmDeauthReq *pMlmDeauthReq; + tSirSmeDeauthReq smeDeauthReq; + tSirResultCodes retCode = eSIR_SME_SUCCESS; + tSirRetStatus status = eSIR_SUCCESS; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionId + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + status = limDeauthReqSerDes(pMac, &smeDeauthReq,(tANI_U8 *) pMsgBuf); + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + //We need to get a session first but we don't even know if the message is correct. + if((psessionEntry = peFindSessionByBssid(pMac, smeDeauthReq.bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + retCode = eSIR_SME_INVALID_PARAMETERS; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + + } + + if ((status == eSIR_FAILURE) || (!limIsSmeDeauthReqValid(pMac, &smeDeauthReq, psessionEntry))) + { + PELOGE(limLog(pMac, LOGE,FL + ("received invalid SME_DEAUTH_REQ message"));) + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_INVALID_PARAMETERS; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + } + limLog(pMac, LOG1,FL("received DEAUTH_REQ message on sessionid %d " + "Systemrole %d with reasoncode %u in limSmestate %d from " + MAC_ADDRESS_STR), smesessionId, psessionEntry->limSystemRole, + smeDeauthReq.reasonCode, psessionEntry->limSmeState, + MAC_ADDR_ARRAY(smeDeauthReq.peerMacAddr)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_REQ_EVENT, psessionEntry, 0, smeDeauthReq.reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* Update SME session ID and Transaction ID */ + psessionEntry->smeSessionId = smesessionId; + psessionEntry->transactionId = smetransactionId; + + + switch (psessionEntry->limSystemRole) + { + case eLIM_STA_ROLE: + case eLIM_BT_AMP_STA_ROLE: + + switch (psessionEntry->limSmeState) + { + case eLIM_SME_ASSOCIATED_STATE: + case eLIM_SME_LINK_EST_STATE: + case eLIM_SME_WT_ASSOC_STATE: + case eLIM_SME_JOIN_FAILURE_STATE: + case eLIM_SME_IDLE_STATE: + psessionEntry->limPrevSmeState = psessionEntry->limSmeState; + psessionEntry->limSmeState = eLIM_SME_WT_DEAUTH_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + // Send Deauthentication request to MLM below + + break; + case eLIM_SME_WT_DEAUTH_STATE: + /* + * PE Recieved a Deauth frame. Normally it gets + * DEAUTH_CNF but it received DEAUTH_REQ. Which + * means host is also trying to disconnect. + * PE can continue processing DEAUTH_REQ and send + * the response instead of failing the request. + * SME will anyway ignore DEAUTH_IND that was sent + * for deauth frame. + */ + limLog(pMac, LOG1, FL("Rcvd SME_DEAUTH_REQ while in " + "SME_WT_DEAUTH_STATE. ")); + break; + case eLIM_SME_WT_DISASSOC_STATE: + /* + * PE Recieved a Disassoc frame. Normally it gets + * DISASSOC_CNF but it received DEAUTH_REQ. This means + * host is also trying to disconnect. + */ + limLog(pMac, LOG1, FL("Rcvd SME_DEAUTH_REQ while in " + "SME_WT_DISASSOC_STATE. ")); + break; + default: + /** + * STA is not in a state to deauthenticate with + * peer. Log error and send response to host. + */ + limLog(pMac, LOGE, + FL("received unexp SME_DEAUTH_REQ in state %d"), + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_STA_NOT_AUTHENTICATED; + deauthTrigger = eLIM_HOST_DEAUTH; + /** + *here we received deauth request from AP so sme state is + eLIM_SME_WT_DEAUTH_STATE.if we have ISSUED delSta then + mlm state should be eLIM_MLM_WT_DEL_STA_RSP_STATE and if + we got delBSS rsp then mlm state should be eLIM_MLM_IDLE_STATE + so the below condition captures the state where delSta + not done and firmware still in connected state. + */ + if (psessionEntry->limSmeState == eLIM_SME_WT_DEAUTH_STATE && + psessionEntry->limMlmState != eLIM_MLM_IDLE_STATE && + psessionEntry->limMlmState != eLIM_MLM_WT_DEL_STA_RSP_STATE) + { + retCode = eSIR_SME_DEAUTH_STATUS; + } + goto sendDeauth; + } + + return; + } + + break; + + case eLIM_STA_IN_IBSS_ROLE: + limLog(pMac, LOGE,FL("Deauth not allowed in IBSS")); + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + retCode = eSIR_SME_INVALID_PARAMETERS; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + } + return; + + case eLIM_AP_ROLE: + // Fall through + + break; + + default: + limLog(pMac, LOGE, + FL("received unexpected SME_DEAUTH_REQ for role %d"), + psessionEntry->limSystemRole); + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + + retCode = eSIR_SME_INVALID_PARAMETERS; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + } + return; + + } // end switch (pMac->lim.gLimSystemRole) + + if (smeDeauthReq.reasonCode == eLIM_LINK_MONITORING_DEAUTH) + { + /// Deauthentication is triggered by Link Monitoring + limLog(pMac, LOG1, + FL("Deauthentication is triggered by Link Monitoring")); + limLog(pMac, LOG1, + FL("Set Trigger to eLIM_LINK_MONITORING_DEAUTH")); + limLog(pMac, LOG1, + FL("and Reason to eSIR_MAC_UNSPEC_FAILURE_REASON")); + deauthTrigger = eLIM_LINK_MONITORING_DEAUTH; + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + } + else + { + deauthTrigger = eLIM_HOST_DEAUTH; + reasonCode = smeDeauthReq.reasonCode; + } + + // Trigger Deauthentication frame to peer MAC entity + pMlmDeauthReq = vos_mem_malloc(sizeof(tLimMlmDeauthReq)); + if ( NULL == pMlmDeauthReq ) + { + // Log error + limLog(pMac, LOGE, + FL("call to AllocateMemory failed for mlmDeauthReq")); + if (pMac->lim.gLimRspReqd) + { + pMac->lim.gLimRspReqd = false; + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + deauthTrigger = eLIM_HOST_DEAUTH; + goto sendDeauth; + } + return; + } + + vos_mem_copy( (tANI_U8 *) &pMlmDeauthReq->peerMacAddr, + (tANI_U8 *) &smeDeauthReq.peerMacAddr, + sizeof(tSirMacAddr)); + + pMlmDeauthReq->reasonCode = reasonCode; + pMlmDeauthReq->deauthTrigger = deauthTrigger; + + /* Update PE session Id*/ + pMlmDeauthReq->sessionId = sessionId; + + limPostMlmMessage(pMac, + LIM_MLM_DEAUTH_REQ, + (tANI_U32 *) pMlmDeauthReq); + return; + +sendDeauth: + limSendSmeDeauthNtf(pMac, smeDeauthReq.peerMacAddr, + retCode, + deauthTrigger, + 1, + smesessionId, smetransactionId); +} /*** end __limProcessSmeDeauthReq() ***/ + + + +/** + * __limProcessSmeSetContextReq() + * + *FUNCTION: + * This function is called to process SME_SETCONTEXT_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeSetContextReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirSmeSetContextReq pSetContextReq; + tLimMlmSetKeysReq *pMlmSetKeysReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + PELOG1(limLog(pMac, LOG1, + FL("received SETCONTEXT_REQ message"));); + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + pSetContextReq = vos_mem_malloc(sizeof(tSirKeys) * SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS); + if ( NULL == pSetContextReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pSetContextReq")); + return; + } + + if ((limSetContextReqSerDes(pMac, pSetContextReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + (!limIsSmeSetContextReqValid(pMac, pSetContextReq))) + { + limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message")); + goto end; + } + + if(pSetContextReq->keyMaterial.numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + PELOGE(limLog(pMac, LOGE, FL("numKeys:%d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS"), pSetContextReq->keyMaterial.numKeys);) + limSendSmeSetContextRsp(pMac, + pSetContextReq->peerMacAddr, + 1, + eSIR_SME_INVALID_PARAMETERS,NULL, + smesessionId,smetransactionId); + + goto end; + } + + + if((psessionEntry = peFindSessionByBssid(pMac, pSetContextReq->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("Session does not exist for given BSSID")); + limSendSmeSetContextRsp(pMac, + pSetContextReq->peerMacAddr, + 1, + eSIR_SME_INVALID_PARAMETERS,NULL, + smesessionId,smetransactionId); + + goto end; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE) || (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) || + (((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))) + { + // Trigger MLM_SETKEYS_REQ + pMlmSetKeysReq = vos_mem_malloc(sizeof(tLimMlmSetKeysReq)); + if ( NULL == pMlmSetKeysReq ) + { + // Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for mlmSetKeysReq")); + goto end; + } + vos_mem_zero(pMlmSetKeysReq,sizeof(tLimMlmSetKeysReq)); + pMlmSetKeysReq->edType = pSetContextReq->keyMaterial.edType; + pMlmSetKeysReq->numKeys = pSetContextReq->keyMaterial.numKeys; + if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + limLog(pMac, LOGP, FL("Num of keys exceeded max num of default keys limit")); + goto end; + } + vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->peerMacAddr, + (tANI_U8 *) &pSetContextReq->peerMacAddr, + sizeof(tSirMacAddr)); + + + vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->key, + (tANI_U8 *) &pSetContextReq->keyMaterial.key, + sizeof(tSirKeys) * (pMlmSetKeysReq->numKeys ? pMlmSetKeysReq->numKeys : 1)); + + pMlmSetKeysReq->sessionId = sessionId; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, + FL("received SETCONTEXT_REQ message sessionId=%d"), pMlmSetKeysReq->sessionId);); +#endif + + if(((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) || (pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104)) + && (psessionEntry->limSystemRole == eLIM_AP_ROLE)) + { + if(pSetContextReq->keyMaterial.key[0].keyLength) + { + tANI_U8 keyId; + keyId = pSetContextReq->keyMaterial.key[0].keyId; + vos_mem_copy( (tANI_U8 *)&psessionEntry->WEPKeyMaterial[keyId], + (tANI_U8 *) &pSetContextReq->keyMaterial, sizeof(tSirKeyMaterial)); + } + else { + tANI_U32 i; + for( i = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++) + { + vos_mem_copy( (tANI_U8 *) &pMlmSetKeysReq->key[i], + (tANI_U8 *)psessionEntry->WEPKeyMaterial[i].key, sizeof(tSirKeys)); + } + } + } + + limPostMlmMessage(pMac, LIM_MLM_SETKEYS_REQ, (tANI_U32 *) pMlmSetKeysReq); + } + else + { + limLog(pMac, LOGE, + FL("received unexpected SME_SETCONTEXT_REQ for role %d, state=%d"), + psessionEntry->limSystemRole, + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + limSendSmeSetContextRsp(pMac, pSetContextReq->peerMacAddr, + 1, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry, + smesessionId, + smetransactionId); + } + +end: + vos_mem_zero(pSetContextReq, + (sizeof(tSirKeys) * SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS)); + vos_mem_free( pSetContextReq); + return; +} /*** end __limProcessSmeSetContextReq() ***/ + +/** + * __limProcessSmeRemoveKeyReq() + * + *FUNCTION: + * This function is called to process SME_REMOVEKEY_REQ message + * from HDD or upper layer application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeRemoveKeyReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirSmeRemoveKeyReq pRemoveKeyReq; + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + limLog(pMac, LOG1, + FL("received SME_REMOVEKEY_REQ message")); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + pRemoveKeyReq = vos_mem_malloc(sizeof(*pRemoveKeyReq)); + if ( NULL == pRemoveKeyReq ) + { + //Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for pRemoveKeyReq")); + + return; + } + + if ((limRemoveKeyReqSerDes(pMac, + pRemoveKeyReq, + (tANI_U8 *) pMsgBuf) == eSIR_FAILURE)) + { + limLog(pMac, LOGW, + FL("received invalid SME_REMOVECONTEXT_REQ message")); + + /* extra look up is needed since, session entry to be passed il limsendremovekey response */ + + if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + //goto end; + } + + limSendSmeRemoveKeyRsp(pMac, + pRemoveKeyReq->peerMacAddr, + eSIR_SME_INVALID_PARAMETERS,psessionEntry, + smesessionId,smetransactionId); + + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac,pRemoveKeyReq->bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given bssId")); + limSendSmeRemoveKeyRsp(pMac, + pRemoveKeyReq->peerMacAddr, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE, NULL, + smesessionId, smetransactionId); + goto end; + } + + + if ((((psessionEntry->limSystemRole == eLIM_STA_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE))&& + (psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE)) || + (((psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) || + (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE)) && + (psessionEntry->limSmeState == eLIM_SME_NORMAL_STATE))) + { + // Trigger MLM_REMOVEKEYS_REQ + pMlmRemoveKeyReq = vos_mem_malloc(sizeof(tLimMlmRemoveKeyReq)); + if ( NULL == pMlmRemoveKeyReq ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for mlmRemoveKeysReq")); + + goto end; + } + + pMlmRemoveKeyReq->edType = (tAniEdType)pRemoveKeyReq->edType; + pMlmRemoveKeyReq->keyId = pRemoveKeyReq->keyId; + pMlmRemoveKeyReq->wepType = pRemoveKeyReq->wepType; + pMlmRemoveKeyReq->unicast = pRemoveKeyReq->unicast; + + /* Update PE session Id */ + pMlmRemoveKeyReq->sessionId = sessionId; + + vos_mem_copy( (tANI_U8 *) &pMlmRemoveKeyReq->peerMacAddr, + (tANI_U8 *) &pRemoveKeyReq->peerMacAddr, + sizeof(tSirMacAddr)); + + + limPostMlmMessage(pMac, + LIM_MLM_REMOVEKEY_REQ, + (tANI_U32 *) pMlmRemoveKeyReq); + } + else + { + limLog(pMac, LOGE, + FL("received unexpected SME_REMOVEKEY_REQ for role %d, state=%d"), + psessionEntry->limSystemRole, + psessionEntry->limSmeState); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + + limSendSmeRemoveKeyRsp(pMac, + pRemoveKeyReq->peerMacAddr, + eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,psessionEntry, + smesessionId,smetransactionId); + } + +end: + vos_mem_free( pRemoveKeyReq); +} /*** end __limProcessSmeRemoveKeyReq() ***/ + +void limProcessSmeGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ mmhMsg; + tpSmeGetScanChnRsp pSirSmeRsp; + tANI_U16 len = 0; + tANI_U8 sessionId; + tANI_U16 transactionId; + + if(pMac->lim.scanChnInfo.numChnInfo > SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + limLog(pMac, LOGW, FL("numChn is out of bounds %d"), + pMac->lim.scanChnInfo.numChnInfo); + pMac->lim.scanChnInfo.numChnInfo = SIR_MAX_SUPPORTED_CHANNEL_LIST; + } + + limLog(pMac, LOG1, + FL("Sending message %s with number of channels %d"), + limMsgStr(eWNI_SME_GET_SCANNED_CHANNEL_RSP), pMac->lim.scanChnInfo.numChnInfo); + + len = sizeof(tSmeGetScanChnRsp) + (pMac->lim.scanChnInfo.numChnInfo - 1) * sizeof(tLimScanChn); + pSirSmeRsp = vos_mem_malloc(len); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for JOIN/REASSOC_RSP")); + + return; + } + vos_mem_set(pSirSmeRsp, len, 0); + + pSirSmeRsp->mesgType = eWNI_SME_GET_SCANNED_CHANNEL_RSP; + pSirSmeRsp->mesgLen = len; + + if (pMac->fScanOffload) + { + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&sessionId,&transactionId); + pSirSmeRsp->sessionId = sessionId; + } + else + pSirSmeRsp->sessionId = 0; + + if(pMac->lim.scanChnInfo.numChnInfo) + { + pSirSmeRsp->numChn = pMac->lim.scanChnInfo.numChnInfo; + vos_mem_copy( pSirSmeRsp->scanChn, pMac->lim.scanChnInfo.scanChn, + sizeof(tLimScanChn) * pSirSmeRsp->numChn); + } + //Clear the list + limRessetScanChannelInfo(pMac); + + mmhMsg.type = eWNI_SME_GET_SCANNED_CHANNEL_RSP; + mmhMsg.bodyptr = pSirSmeRsp; + mmhMsg.bodyval = 0; + + pMac->lim.gLimRspReqd = false; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + + +void limProcessSmeGetAssocSTAsInfo(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeGetAssocSTAsReq getAssocSTAsReq = {0}; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry = NULL; + tSap_Event sapEvent; + tpWLAN_SAPEventCB pSapEventCallback = NULL; + tpSap_AssocMacAddr pAssocStasTemp = NULL;// #include "sapApi.h" + tANI_U8 sessionId = CSR_SESSION_ID_INVALID; + tANI_U8 assocId = 0; + tANI_U8 staCount = 0; + + if (!limIsSmeGetAssocSTAsReqValid(pMac, &getAssocSTAsReq, (tANI_U8 *) pMsgBuf)) + { + limLog(pMac, LOGE, + FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message")); + return; + } + + switch (getAssocSTAsReq.modId) + { +/** + case VOS_MODULE_ID_HAL: + wdaPostCtrlMsg( pMac, &msgQ ); + return; + + case VOS_MODULE_ID_TL: + Post msg TL + return; +*/ + case VOS_MODULE_ID_PE: + default: + break; + } + + // Get Associated stations from PE + // Find PE session Entry + if ((psessionEntry = peFindSessionByBssid(pMac, getAssocSTAsReq.bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given bssId")); + goto limAssocStaEnd; + } + + if (psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + limLog(pMac, LOGE, + FL("Received unexpected message in state %d, in role %d"), + psessionEntry->limSmeState, psessionEntry->limSystemRole); + goto limAssocStaEnd; + } + + // Retrieve values obtained in the request message + pSapEventCallback = (tpWLAN_SAPEventCB)getAssocSTAsReq.pSapEventCallback; + pAssocStasTemp = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray; + + for (assocId = 0; assocId < psessionEntry->dph.dphHashTable.size; assocId++)// Softap dphHashTable.size = 8 + { + pStaDs = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if ((NULL == pStaDs) || (NULL == pAssocStasTemp)) + continue; + + if (pStaDs->valid) + { + vos_mem_copy((tANI_U8 *)&pAssocStasTemp->staMac, + (tANI_U8 *)&pStaDs->staAddr, + sizeof(v_MACADDR_t)); // Mac address + pAssocStasTemp->assocId = (v_U8_t)pStaDs->assocId; // Association Id + pAssocStasTemp->staId = (v_U8_t)pStaDs->staIndex; // Station Id + + vos_mem_copy((tANI_U8 *)&pAssocStasTemp->supportedRates, + (tANI_U8 *)&pStaDs->supportedRates, + sizeof(tSirSupportedRates)); + pAssocStasTemp->ShortGI40Mhz = pStaDs->htShortGI40Mhz; + pAssocStasTemp->ShortGI20Mhz = pStaDs->htShortGI20Mhz; + pAssocStasTemp->Support40Mhz = pStaDs->htDsssCckRate40MHzSupport; + + limLog(pMac, LOG1, FL("dph Station Number = %d"), staCount+1); + limLog(pMac, LOG1, FL("MAC = " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr)); + limLog(pMac, LOG1, FL("Association Id = %d"),pStaDs->assocId); + limLog(pMac, LOG1, FL("Station Index = %d"),pStaDs->staIndex); + + pAssocStasTemp++; + staCount++; + } + } + +limAssocStaEnd: + // Call hdd callback with sap event to send the list of associated stations from PE + if (pSapEventCallback != NULL) + { + sapEvent.sapHddEventCode = eSAP_ASSOC_STA_CALLBACK_EVENT; + sapEvent.sapevt.sapAssocStaListEvent.module = VOS_MODULE_ID_PE; + sapEvent.sapevt.sapAssocStaListEvent.noOfAssocSta = staCount; + sapEvent.sapevt.sapAssocStaListEvent.pAssocStas = (tpSap_AssocMacAddr)getAssocSTAsReq.pAssocStasArray; + pSapEventCallback(&sapEvent, getAssocSTAsReq.pUsrContext); + } +} + + +/** + * limProcessSmeGetWPSPBCSessions + * + *FUNCTION: + * This function is called when query the WPS PBC overlap message is received + * + *LOGIC: + * This function parses get WPS PBC overlap information message and call callback to pass + * WPS PBC overlap information back to hdd. + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf A pointer to WPS PBC overlap query message +* + * @return None + */ +void limProcessSmeGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeGetWPSPBCSessionsReq GetWPSPBCSessionsReq; + tpPESession psessionEntry = NULL; + tSap_Event sapEvent; + tpWLAN_SAPEventCB pSapEventCallback = NULL; + tANI_U8 sessionId = CSR_SESSION_ID_INVALID; + tSirMacAddr zeroMac = {0,0,0,0,0,0}; + + sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_E_FAULT; + + if (limIsSmeGetWPSPBCSessionsReqValid(pMac, &GetWPSPBCSessionsReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("received invalid eWNI_SME_GET_ASSOC_STAS_REQ message")); + return; + } + + // Get Associated stations from PE + // Find PE session Entry + if ((psessionEntry = peFindSessionByBssid(pMac, GetWPSPBCSessionsReq.bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE, + FL("session does not exist for given bssId")); + goto limGetWPSPBCSessionsEnd; + } + + if (psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + limLog(pMac, LOGE, + FL("Received unexpected message in role %d"), + psessionEntry->limSystemRole); + goto limGetWPSPBCSessionsEnd; + } + + // Call hdd callback with sap event to send the WPS PBC overlap information + sapEvent.sapHddEventCode = eSAP_GET_WPSPBC_SESSION_EVENT; + sapEvent.sapevt.sapGetWPSPBCSessionEvent.module = VOS_MODULE_ID_PE; + + if (vos_mem_compare( zeroMac, GetWPSPBCSessionsReq.pRemoveMac, sizeof(tSirMacAddr))) + { //This is GetWpsSession call + + limGetWPSPBCSessions(pMac, + sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, sapEvent.sapevt.sapGetWPSPBCSessionEvent.UUID_E, + &sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap, psessionEntry); + } + else + { + limRemovePBCSessions(pMac, GetWPSPBCSessionsReq.pRemoveMac,psessionEntry); + /* don't have to inform the HDD/Host */ + return; + } + + PELOG4(limLog(pMac, LOGE, FL("wpsPBCOverlap %d"), sapEvent.sapevt.sapGetWPSPBCSessionEvent.wpsPBCOverlap);) + PELOG4(limPrintMacAddr(pMac, sapEvent.sapevt.sapGetWPSPBCSessionEvent.addr.bytes, LOG4);) + + sapEvent.sapevt.sapGetWPSPBCSessionEvent.status = VOS_STATUS_SUCCESS; + +limGetWPSPBCSessionsEnd: + pSapEventCallback = (tpWLAN_SAPEventCB)GetWPSPBCSessionsReq.pSapEventCallback; + + if (NULL != pSapEventCallback) + pSapEventCallback(&sapEvent, GetWPSPBCSessionsReq.pUsrContext); +} + + + +/** + * __limCounterMeasures() + * + * FUNCTION: + * This function is called to "implement" MIC counter measure + * and is *temporary* only + * + * LOGIC: on AP, disassoc all STA associated thru TKIP, + * we don't do the proper STA disassoc sequence since the + * BSS will be stoped anyway + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +static void +__limCounterMeasures(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tSirMacAddr mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + /* If PMF is enabled then don't send broadcast disassociation */ + if ( ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) +#ifdef WLAN_FEATURE_11W + && !psessionEntry->limRmfEnabled +#endif + ) + limSendDisassocMgmtFrame(pMac, eSIR_MAC_MIC_FAILURE_REASON, mac, psessionEntry, FALSE); + +}; + + +void +limProcessTkipCounterMeasures(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeTkipCntrMeasReq tkipCntrMeasReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionId + + if ( limTkipCntrMeasReqSerDes( pMac, &tkipCntrMeasReq, (tANI_U8 *) pMsgBuf ) != eSIR_SUCCESS ) + { + limLog(pMac, LOGE, + FL("received invalid eWNI_SME_TKIP_CNTR_MEAS_REQ message")); + return; + } + + if ( NULL == (psessionEntry = peFindSessionByBssid( pMac, tkipCntrMeasReq.bssId, &sessionId )) ) + { + limLog(pMac, LOGE, FL("session does not exist for given BSSID ")); + return; + } + + if ( tkipCntrMeasReq.bEnable ) + { + __limCounterMeasures( pMac, psessionEntry ); + } + + psessionEntry->bTkipCntrMeasActive = tkipCntrMeasReq.bEnable; +} + + +static void +__limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSmeStopBssReq stopBssReq; + tSirRetStatus status; + tLimSmeStates prevState; + tANI_U8 sessionId; //PE sessionId + tpPESession psessionEntry; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + tANI_U8 i = 0; + tpDphHashNode pStaDs = NULL; + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + + + if ((limStopBssReqSerDes(pMac, &stopBssReq, (tANI_U8 *) pMsgBuf) != eSIR_SUCCESS) || + !limIsSmeStopBssReqValid(pMsgBuf)) + { + PELOGW(limLog(pMac, LOGW, FL("received invalid SME_STOP_BSS_REQ message"));) + /// Send Stop BSS response to host + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId); + return; + } + + + if((psessionEntry = peFindSessionByBssid(pMac,stopBssReq.bssId,&sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("session does not exist for given BSSID ")); + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_INVALID_PARAMETERS,smesessionId,smetransactionId); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + if ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) || /* Added For BT -AMP Support */ + (psessionEntry->limSystemRole == eLIM_STA_ROLE )) + { + /** + * Should not have received STOP_BSS_REQ in states + * other than 'normal' state or on STA in Infrastructure + * mode. Log error and return response to host. + */ + limLog(pMac, LOGE, + FL("received unexpected SME_STOP_BSS_REQ in state %d, for role %d"), + psessionEntry->limSmeState, psessionEntry->limSystemRole); + limPrintSmeState(pMac, LOGE, psessionEntry->limSmeState); + /// Send Stop BSS response to host + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,smesessionId,smetransactionId); + return; + } + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE ) + { + limWPSPBCClose(pMac, psessionEntry); + } + PELOGW(limLog(pMac, LOGW, FL("RECEIVED STOP_BSS_REQ with reason code=%d"), stopBssReq.reasonCode);) + + prevState = psessionEntry->limSmeState; + + psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + /* Update SME session Id and Transaction Id */ + psessionEntry->smeSessionId = smesessionId; + psessionEntry->transactionId = smetransactionId; + + /* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame. + * If PMF is enabled then don't send broadcast disassociation */ + if ( ( (eLIM_STA_IN_IBSS_ROLE != psessionEntry->limSystemRole) && + (eLIM_BT_AMP_STA_ROLE != psessionEntry->limSystemRole) ) +#ifdef WLAN_FEATURE_11W + && !psessionEntry->limRmfEnabled +#endif + ) + { + tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + if ((stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)) + // Send disassoc all stations associated thru TKIP + __limCounterMeasures(pMac,psessionEntry); + else + limSendDisassocMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, bcAddr, psessionEntry, FALSE); + } + + //limDelBss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. + pMac->lim.gLimIbssCoalescingHappened = false; + + for(i = 1 ; i < pMac->lim.gLimAssocStaLimit ; i++) + { + pStaDs = dphGetHashEntry(pMac, i, &psessionEntry->dph.dphHashTable); + if (NULL == pStaDs) + continue; + status = limDelSta(pMac, pStaDs, false, psessionEntry) ; + if(eSIR_SUCCESS == status) + { + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ; + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ; + } + else + { + limLog(pMac, LOGE, FL("limDelSta failed with Status : %d"), status); + VOS_ASSERT(0) ; + } + } + /* send a delBss to HAL and wait for a response */ + status = limDelBss(pMac, NULL,psessionEntry->bssIdx,psessionEntry); + + if (status != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d"), psessionEntry->bssIdx);) + psessionEntry->limSmeState= prevState; + + MTRACE(macTrace(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId, psessionEntry->limSmeState)); + + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_STOP_BSS_FAILURE,smesessionId,smetransactionId); + } +} + + +/**-------------------------------------------------------------- +\fn __limProcessSmeStopBssReq + +\brief Wrapper for the function __limHandleSmeStopBssRequest + This message will be defered until softmac come out of + scan mode. Message should be handled even if we have + detected radar in the current operating channel. +\param pMac +\param pMsg + +\return TRUE - If we consumed the buffer + FALSE - If have defered the message. + ---------------------------------------------------------------*/ +static tANI_BOOLEAN +__limProcessSmeStopBssReq(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + if (__limIsDeferedMsgForLearn(pMac, pMsg)) + { + /** + * If message defered, buffer is not consumed yet. + * So return false + */ + return eANI_BOOLEAN_FALSE; + } + __limHandleSmeStopBssRequest(pMac, (tANI_U32 *) pMsg->bodyptr); + return eANI_BOOLEAN_TRUE; +} /*** end __limProcessSmeStopBssReq() ***/ + + +void limProcessSmeDelBssRsp( + tpAniSirGlobal pMac, + tANI_U32 body,tpPESession psessionEntry) +{ + + (void) body; + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + //TBD: get the sessionEntry + limIbssDelete(pMac,psessionEntry); + dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable); + limDeletePreAuthList(pMac); + limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, eSIR_SME_SUCCESS,psessionEntry->smeSessionId,psessionEntry->transactionId); + return; +} + + +/**--------------------------------------------------------------- +\fn __limProcessSmeAssocCnfNew +\brief This function handles SME_ASSOC_CNF/SME_REASSOC_CNF +\ in BTAMP AP. +\ +\param pMac +\param msgType - message type +\param pMsgBuf - a pointer to the SME message buffer +\return None +------------------------------------------------------------------*/ + + void +__limProcessSmeAssocCnfNew(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + tSirSmeAssocCnf assocCnf; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry= NULL; + tANI_U8 sessionId; + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE, FL("pMsgBuf is NULL ")); + goto end; + } + + if ((limAssocCnfSerDes(pMac, &assocCnf, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE) || + !__limIsSmeAssocCnfValid(&assocCnf)) + { + limLog(pMac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message ")); + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac, assocCnf.bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given bssId")); + goto end; + } + + if ( ((psessionEntry->limSystemRole != eLIM_AP_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_AP_ROLE)) || + ((psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) && (psessionEntry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) + { + limLog(pMac, LOGE, FL("Received unexpected message %X in state %d, in role %d"), + msgType, psessionEntry->limSmeState, psessionEntry->limSystemRole); + goto end; + } + + pStaDs = dphGetHashEntry(pMac, assocCnf.aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs == NULL) + { + limLog(pMac, LOGE, + FL("Received invalid message %X due to no STA context, " + "for aid %d, peer "), + msgType, assocCnf.aid); + limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1); + + /* + ** send a DISASSOC_IND message to WSM to make sure + ** the state in WSM and LIM is the same + **/ + limSendSmeDisassocNtf( pMac, assocCnf.peerMacAddr, eSIR_SME_STA_NOT_ASSOCIATED, + eLIM_PEER_ENTITY_DISASSOC, assocCnf.aid,psessionEntry->smeSessionId,psessionEntry->transactionId,psessionEntry); + goto end; + } + if ((pStaDs && + (( !vos_mem_compare( (tANI_U8 *) pStaDs->staAddr, + (tANI_U8 *) assocCnf.peerMacAddr, + sizeof(tSirMacAddr)) ) || + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ASSOC_CNF_STATE) || + ((pStaDs->mlmStaContext.subType == LIM_ASSOC) && + (msgType != eWNI_SME_ASSOC_CNF)) || + ((pStaDs->mlmStaContext.subType == LIM_REASSOC) && + (msgType != eWNI_SME_ASSOC_CNF))))) // since softap is passing this as ASSOC_CNF and subtype differs + { + limLog(pMac, LOGE, + FL("Received invalid message %X due to peerMacAddr mismatched " + "or not in eLIM_MLM_WT_ASSOC_CNF_STATE state, for aid %d, peer " + "StaD mlmState : %d"), + msgType, assocCnf.aid, pStaDs->mlmStaContext.mlmState); + limPrintMacAddr(pMac, assocCnf.peerMacAddr, LOG1); + goto end; + } + + /* + ** Deactivate/delet CNF_WAIT timer since ASSOC_CNF + ** has been received + **/ + limLog(pMac, LOG1, FL("Received SME_ASSOC_CNF. Delete Timer")); + limDeactivateAndChangePerStaIdTimer(pMac, eLIM_CNF_WAIT_TIMER, pStaDs->assocId); + + if (assocCnf.statusCode == eSIR_SME_SUCCESS) + { + /* In BTAMP-AP, PE already finished the WDA_ADD_STA sequence + * when it had received Assoc Request frame. Now, PE just needs to send + * Association Response frame to the requesting BTAMP-STA. + */ + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + limLog(pMac, LOG1, FL("sending Assoc Rsp frame to STA (assoc id=%d) "), pStaDs->assocId); + limSendAssocRspMgmtFrame(pMac, eSIR_SUCCESS, pStaDs->assocId, + pStaDs->staAddr, + pStaDs->mlmStaContext.subType, pStaDs, + psessionEntry, NULL); + goto end; + } // (assocCnf.statusCode == eSIR_SME_SUCCESS) + else + { + // SME_ASSOC_CNF status is non-success, so STA is not allowed to be associated + /*Since the HAL sta entry is created for denied STA we need to remove this HAL entry.So to do that set updateContext to 1*/ + if(!pStaDs->mlmStaContext.updateContext) + pStaDs->mlmStaContext.updateContext = 1; + limLog(pMac, LOG1, FL("Receive Assoc Cnf with status Code : %d(assoc id=%d) "), + assocCnf.statusCode, pStaDs->assocId); + limRejectAssociation(pMac, pStaDs->staAddr, + pStaDs->mlmStaContext.subType, + true, pStaDs->mlmStaContext.authType, + pStaDs->assocId, true, + eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); + } + +end: + if((psessionEntry != NULL) && (pStaDs != NULL)) + { + if ( psessionEntry->parsedAssocReq[pStaDs->assocId] != NULL ) + { + if ( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame) + { + vos_mem_free(((tpSirAssocReq) + (psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[pStaDs->assocId]))->assocReqFrame = NULL; + } + + vos_mem_free(psessionEntry->parsedAssocReq[pStaDs->assocId]); + psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL; + } + } + +} /*** end __limProcessSmeAssocCnfNew() ***/ + +#ifdef SAP_AUTH_OFFLOAD +/** + * __lim_process_sme_assoc_offload_cnf() station connection confirmation + * message from SME. + * @pMac: SirGlobal handler + * @msgType: message type + * @pMsgBuf: message body + * + * This function handles the station connect confirm of + * Software AP authentication offload feature + * + * Return: None + */ + static void +__lim_process_sme_assoc_offload_cnf(tpAniSirGlobal pmac, + tANI_U32 msg_type, + tANI_U32 *pmsg_buf) +{ + tSirSmeAssocCnf assoc_cnf; + tpDphHashNode sta_ds = NULL; + tpPESession psession_entry= NULL; + tANI_U8 session_id; + tANI_U16 aid=0; + + if (pmsg_buf == NULL) + { + limLog(pmac, LOGE, FL("pmsg_buf is NULL ")); + return; + } + + if ((limAssocCnfSerDes(pmac, &assoc_cnf, (tANI_U8 *) pmsg_buf) == + eSIR_FAILURE) || !__limIsSmeAssocCnfValid(&assoc_cnf)) + { + limLog(pmac, LOGE, FL("Received invalid SME_RE(ASSOC)_CNF message ")); + return; + } + + if((psession_entry = + peFindSessionByBssid(pmac, assoc_cnf.bssId, &session_id))== NULL) + { + limLog(pmac, LOGE, FL("session does not exist for given bssId")); + goto end; + } + + if ((!LIM_IS_AP_ROLE(psession_entry)) || + ((psession_entry->limSmeState != eLIM_SME_NORMAL_STATE) && + (psession_entry->limSmeState != eLIM_SME_NORMAL_CHANNEL_SCAN_STATE))) + { + limLog(pmac, LOGE, + FL("Received unexpected message %X in state %X, in role %X"), + msg_type, psession_entry->limSmeState, + GET_LIM_SYSTEM_ROLE(psession_entry)); + goto end; + } + sta_ds = dphGetHashEntry(pmac, + assoc_cnf.aid, + &psession_entry->dph.dphHashTable); + if (sta_ds != NULL) + { + aid = sta_ds->assocId; + /* Deactivate/delete CNF_WAIT timer since ASSOC_CNF + * has been received */ + limDeactivateAndChangePerStaIdTimer(pmac, + eLIM_CNF_WAIT_TIMER, + aid); + } + if (assoc_cnf.statusCode == eSIR_SME_SUCCESS) + { + sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + limLog(pmac, LOG1, FL("Set mlmState to eLIM_MLM_LINK_ESTABLISHED_STATE")); + } + +end: + if((psession_entry != NULL) && (sta_ds != NULL)) + { + if ( psession_entry->parsedAssocReq[aid] != NULL ) + { + if ( ((tpSirAssocReq) + (psession_entry->parsedAssocReq[aid]))->assocReqFrame) + { + vos_mem_free(((tpSirAssocReq) + (psession_entry->parsedAssocReq[aid]))->assocReqFrame); + ((tpSirAssocReq) + (psession_entry->parsedAssocReq[aid]))->assocReqFrame = + NULL; + } + vos_mem_free(psession_entry->parsedAssocReq[aid]); + psession_entry->parsedAssocReq[aid] = NULL; + } + } + +} /*** end __lim_process_sme_assoc_offload_cnf() ***/ +#endif /* SAP_AUTH_OFFLOAD */ + + +static void +__limProcessSmeAddtsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpDphHashNode pStaDs; + tSirMacAddr peerMac; + tpSirAddtsReq pSirAddts; + tANI_U32 timeout; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionId + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + pSirAddts = (tpSirAddtsReq) pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac, pSirAddts->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, "Session Does not exist for given bssId"); + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + + /* if sta + * - verify assoc state + * - send addts request to ap + * - wait for addts response from ap + * if ap, just ignore with error log + */ + limLog(pMac, LOG1, + FL("Received SME_ADDTS_REQ (TSid %d, UP %d)"), + pSirAddts->req.tspec.tsinfo.traffic.tsid, + pSirAddts->req.tspec.tsinfo.traffic.userPrio); + + if ((psessionEntry->limSystemRole != eLIM_STA_ROLE)&&(psessionEntry->limSystemRole != eLIM_BT_AMP_STA_ROLE)) + { + PELOGE(limLog(pMac, LOGE, "AddTs received on AP - ignoring");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + if(pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, "Cannot find AP context for addts req");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + if ((! pStaDs->valid) || + (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)) + { + PELOGE(limLog(pMac, LOGE, "AddTs received in invalid MLM state");) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + pSirAddts->req.wsmTspecPresent = 0; + pSirAddts->req.wmeTspecPresent = 0; + pSirAddts->req.lleTspecPresent = 0; + + if ((pStaDs->wsmEnabled) && + (pSirAddts->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA)) + pSirAddts->req.wsmTspecPresent = 1; + else if (pStaDs->wmeEnabled) + pSirAddts->req.wmeTspecPresent = 1; + else if (pStaDs->lleEnabled) + pSirAddts->req.lleTspecPresent = 1; + else + { + PELOGW(limLog(pMac, LOGW, FL("ADDTS_REQ ignore - qos is disabled"));) + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + limLog(pMac, LOGE, "AddTs received in invalid LIMsme state (%d)", + psessionEntry->limSmeState); + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + if (pMac->lim.gLimAddtsSent) + { + limLog(pMac, LOGE, "Addts (token %d, tsid %d, up %d) is still pending", + pMac->lim.gLimAddtsReq.req.dialogToken, + pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid, + pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.userPrio); + limSendSmeAddtsRsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE, psessionEntry, pSirAddts->req.tspec, + smesessionId,smetransactionId); + return; + } + + #if 0 + val = sizeof(tSirMacAddr); + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMac, &val) != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + return; + } + #endif + sirCopyMacAddr(peerMac,psessionEntry->bssId); + + // save the addts request + pMac->lim.gLimAddtsSent = true; + vos_mem_copy( (tANI_U8 *) &pMac->lim.gLimAddtsReq, (tANI_U8 *) pSirAddts, sizeof(tSirAddtsReq)); + + // ship out the message now + limSendAddtsReqActionFrame(pMac, peerMac, &pSirAddts->req, + psessionEntry); + limLog(pMac, LOG1, FL("Sent ADDTS request")); + + // start a timer to wait for the response + if (pSirAddts->timeout) + timeout = pSirAddts->timeout; + else if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &timeout) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get Cfg param %d (Addts Rsp Timeout)"), + WNI_CFG_ADDTS_RSP_TIMEOUT); + return; + } + + timeout = SYS_MS_TO_TICKS(timeout); + if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("AddtsRsp timer change failed!")); + return; + } + pMac->lim.gLimAddtsRspTimerCount++; + if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer, + pMac->lim.gLimAddtsRspTimerCount) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("AddtsRsp timer change failed!")); + return; + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER)); + + //add the sessionId to the timer object + pMac->lim.limTimers.gLimAddtsRspTimer.sessionId = sessionId; + if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("AddtsRsp timer activation failed!")); + return; + } + return; +} + + +static void +__limProcessSmeDeltsReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMacAddr peerMacAddr; + tANI_U8 ac; + tSirMacTSInfo *pTsinfo; + tpSirDeltsReq pDeltsReq = (tpSirDeltsReq) pMsgBuf; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U32 status = eSIR_SUCCESS; + tANI_U8 smesessionId; + tANI_U16 smetransactionId; + + limGetSessionInfo(pMac,(tANI_U8 *)pMsgBuf,&smesessionId,&smetransactionId); + + if((psessionEntry = peFindSessionByBssid(pMac, pDeltsReq->bssId, &sessionId))== NULL) + { + limLog(pMac, LOGE, "Session Does not exist for given bssId"); + status = eSIR_FAILURE; + goto end; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + + if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDeltsReq, peerMacAddr,psessionEntry)) + { + PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed"));) + status = eSIR_FAILURE; + limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_FAILURE,psessionEntry,smesessionId,smetransactionId); + return; + } + + limLog(pMac, LOG1, FL("Sent DELTS request to station with " + "assocId = %d MacAddr = "MAC_ADDRESS_STR), + pDeltsReq->aid, MAC_ADDR_ARRAY(peerMacAddr)); + + limSendDeltsReqActionFrame(pMac, peerMacAddr, pDeltsReq->req.wmeTspecPresent, &pDeltsReq->req.tsinfo, &pDeltsReq->req.tspec, + psessionEntry); + + pTsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo : &pDeltsReq->req.tsinfo; + + /* We've successfully send DELTS frame to AP. Update the + * dynamic UAPSD mask. The AC for this TSPEC to be deleted + * is no longer trigger enabled or delivery enabled + */ + limSetTspecUapsdMask(pMac, pTsinfo, CLEAR_UAPSD_MASK); + + /* We're deleting the TSPEC, so this particular AC is no longer + * admitted. PE needs to downgrade the EDCA + * parameters(for the AC for which TS is being deleted) to the + * next best AC for which ACM is not enabled, and send the + * updated values to HAL. + */ + ac = upToAc(pTsinfo->traffic.userPrio); + + if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_UPLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + } + else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_DNLINK) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + else if(pTsinfo->traffic.direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] &= ~(1 << ac); + pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] &= ~(1 << ac); + } + + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs != NULL) + { + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + status = eSIR_SUCCESS; + } + else + { + limLog(pMac, LOGE, FL("Self entry missing in Hash Table ")); + status = eSIR_FAILURE; + } +#ifdef FEATURE_WLAN_ESE +#ifdef FEATURE_WLAN_ESE_UPLOAD + limSendSmeTsmIEInd(pMac, psessionEntry, 0, 0, 0); +#else + limDeactivateAndChangeTimer(pMac,eLIM_TSM_TIMER); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + + // send an sme response back + end: + limSendSmeDeltsRsp(pMac, pDeltsReq, eSIR_SUCCESS,psessionEntry,smesessionId,smetransactionId); +} + + +void +limProcessSmeAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param) +{ + //fetch the sessionEntry based on the sessionId + tpPESession psessionEntry; + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimAddtsRspTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if ( (psessionEntry->limSystemRole != eLIM_STA_ROLE) && (psessionEntry->limSystemRole != eLIM_BT_AMP_STA_ROLE) ) + { + limLog(pMac, LOGW, "AddtsRspTimeout in non-Sta role (%d)", psessionEntry->limSystemRole); + pMac->lim.gLimAddtsSent = false; + return; + } + + if (! pMac->lim.gLimAddtsSent) + { + PELOGW(limLog(pMac, LOGW, "AddtsRspTimeout but no AddtsSent");) + return; + } + + if (param != pMac->lim.gLimAddtsRspTimerCount) + { + limLog(pMac, LOGE, FL("Invalid AddtsRsp Timer count %d (exp %d)"), + param, pMac->lim.gLimAddtsRspTimerCount); + return; + } + + // this a real response timeout + pMac->lim.gLimAddtsSent = false; + pMac->lim.gLimAddtsRspTimerCount++; + + limSendSmeAddtsRsp(pMac, true, eSIR_SME_ADDTS_RSP_TIMEOUT, psessionEntry, pMac->lim.gLimAddtsReq.req.tspec, + psessionEntry->smeSessionId, psessionEntry->transactionId); +} + + +/** + * __limProcessSmeStatsRequest() + * + *FUNCTION: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpAniGetStatsReq pStatsReq; + tSirMsgQ msgQ; + tpPESession psessionEntry; + tANI_U8 sessionId; + + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pStatsReq = (tpAniGetStatsReq) pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac,pStatsReq->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, FL("session does not exist for given bssId")); + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + return; + } + + + + switch(pStatsReq->msgType) + { + //Add Lim stats here. and send reqsponse. + + //HAL maintained Stats. + case eWNI_SME_STA_STAT_REQ: + msgQ.type = WDA_STA_STAT_REQ; + break; + case eWNI_SME_AGGR_STAT_REQ: + msgQ.type = WDA_AGGR_STAT_REQ; + break; + case eWNI_SME_GLOBAL_STAT_REQ: + msgQ.type = WDA_GLOBAL_STAT_REQ; + break; + case eWNI_SME_STAT_SUMM_REQ: + msgQ.type = WDA_STAT_SUMM_REQ; + break; + default: //Unknown request. + PELOGE(limLog(pMac, LOGE, "Unknown Statistics request");) + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + return; + } + + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + limLog(pMac, LOGP, "Unable to forward request"); + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + return; + } + + return; +} + + +/** + * __limProcessSmeGetStatisticsRequest() + * + *FUNCTION: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeGetStatisticsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpAniGetPEStatsReq pPEStatsReq; + tSirMsgQ msgQ; + + pPEStatsReq = (tpAniGetPEStatsReq) pMsgBuf; + + //pPEStatsReq->msgType should be eWNI_SME_GET_STATISTICS_REQ + + msgQ.type = WDA_GET_STATISTICS_REQ; + + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + limLog(pMac, LOGP, "Unable to forward request"); + return; + } + + return; +} + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/** + *FUNCTION: __limProcessSmeGetTsmStatsRequest() + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeGetTsmStatsRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msgQ; + + msgQ.type = WDA_TSM_STATS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + limLog(pMac, LOGP, "Unable to forward request"); + return; + } +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + * __limProcessSmeGetRoamRssiRequest() + * + *FUNCTION: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeGetRoamRssiRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpAniGetRssiReq pPEGetRoamRssiReq = NULL; + tSirMsgQ msgQ; + + pPEGetRoamRssiReq = (tpAniGetRssiReq) pMsgBuf; + msgQ.type = WDA_GET_ROAM_RSSI_REQ; + + msgQ.reserved = 0; + msgQ.bodyptr = pMsgBuf; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + if( eSIR_SUCCESS != (wdaPostCtrlMsg( pMac, &msgQ ))){ + vos_mem_free( pMsgBuf ); + pMsgBuf = NULL; + limLog(pMac, LOGP, "Unable to forward request"); + return; + } + + return; +} +#endif + + +static void +__limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + + PELOG1(limLog(pMac, LOG1, + FL("received UPDATE_APWPSIEs_REQ message"));); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pUpdateAPWPSIEsReq = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq)); + if ( NULL == pUpdateAPWPSIEsReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pUpdateAPWPSIEsReq")); + return; + } + + if ((limUpdateAPWPSIEsReqSerDes(pMac, pUpdateAPWPSIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE)) + { + limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message")); + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPSIEsReq->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("Session does not exist for given BSSID")); + goto end; + } + + vos_mem_copy( &psessionEntry->APWPSIEs, &pUpdateAPWPSIEsReq->APWPSIEs, sizeof(tSirAPWPSIEs)); + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + +end: + vos_mem_free( pUpdateAPWPSIEsReq); + return; +} /*** end __limProcessSmeUpdateAPWPSIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +static void +__limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirUpdateParams pUpdateParams; + tpPESession psessionEntry; + + limLog(pMac, LOG1, + FL("received SME_HIDE_SSID message")); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pUpdateParams = (tpSirUpdateParams)pMsgBuf; + + if((psessionEntry = peFindSessionBySessionId(pMac, pUpdateParams->sessionId)) == NULL) + { + limLog(pMac, LOGW, "Session does not exist for given sessionId %d", + pUpdateParams->sessionId); + return; + } + + /* Update the session entry */ + psessionEntry->ssidHidden = pUpdateParams->ssidHidden; + + /* Update beacon */ + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + return; +} /*** end __limProcessSmeHideSSID(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +static void +__limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq; + tpPESession psessionEntry; + tANI_U8 sessionId; //PE sessionID + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pUpdateAPWPARSNIEsReq = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq)); + if ( NULL == pUpdateAPWPARSNIEsReq ) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pUpdateAPWPARSNIEsReq")); + return; + } + + if ((limUpdateAPWPARSNIEsReqSerDes(pMac, pUpdateAPWPARSNIEsReq, (tANI_U8 *) pMsgBuf) == eSIR_FAILURE)) + { + limLog(pMac, LOGW, FL("received invalid SME_SETCONTEXT_REQ message")); + goto end; + } + + if((psessionEntry = peFindSessionByBssid(pMac, pUpdateAPWPARSNIEsReq->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGW, FL("Session does not exist for given BSSID")); + goto end; + } + + vos_mem_copy(&psessionEntry->pLimStartBssReq->rsnIE, + &pUpdateAPWPARSNIEsReq->APWPARSNIEs, sizeof(tSirRSNie)); + + limSetRSNieWPAiefromSmeStartBSSReqMessage(pMac, &psessionEntry->pLimStartBssReq->rsnIE, psessionEntry); + + psessionEntry->pLimStartBssReq->privacy = 1; + psessionEntry->privacy = 1; + + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + +end: + vos_mem_free(pUpdateAPWPARSNIEsReq); + return; +} /*** end __limProcessSmeSetWPARSNIEs(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +/* +Update the beacon Interval dynamically if beaconInterval is different in MCC +*/ +static void +__limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirChangeBIParams pChangeBIParams; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + tUpdateBeaconParams beaconParams; + + PELOG1(limLog(pMac, LOG1, + FL("received Update Beacon Interval message"));); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + pChangeBIParams = (tpSirChangeBIParams)pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac, pChangeBIParams->bssId, &sessionId)) == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given BSSID")); + return; + } + + /*Update sessionEntry Beacon Interval*/ + if(psessionEntry->beaconParams.beaconInterval != + pChangeBIParams->beaconInterval ) + { + psessionEntry->beaconParams.beaconInterval = pChangeBIParams->beaconInterval; + } + + /*Update sch beaconInterval*/ + if(pMac->sch.schObject.gSchBeaconInterval != + pChangeBIParams->beaconInterval ) + { + pMac->sch.schObject.gSchBeaconInterval = pChangeBIParams->beaconInterval; + + PELOG1(limLog(pMac, LOG1, + FL("LIM send update BeaconInterval Indication : %d"),pChangeBIParams->beaconInterval);); + + /* Update beacon */ + schSetFixedBeaconFields(pMac, psessionEntry); + + beaconParams.bssIdx = psessionEntry->bssIdx; + //Set change in beacon Interval + beaconParams.beaconInterval = pChangeBIParams->beaconInterval; + beaconParams.paramChangeBitmap = PARAM_BCN_INTERVAL_CHANGED; + limSendBeaconParams(pMac, &beaconParams, psessionEntry); + } + + return; +} /*** end __limProcessSmeChangeBI(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) ***/ + +/** ------------------------------------------------------------- +\fn +\brief handles indication message from HDD to update HT mode +\param tpAniSirGlobal pMac +\param tANI_U32 pMsgBuf +\return None +-------------------------------------------------------------*/ +#ifdef WLAN_FEATURE_AP_HT40_24G +static void __limProcessSmeSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirSetHT2040Mode pSetHT2040Mode; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + tUpdateVHTOpMode *pHtOpMode = NULL; + vos_msg_t msg; + + PELOG1(limLog(pMac, LOGRW, + FL("received Set HT 20/40 mode message"));); + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pSetHT2040Mode = (tpSirSetHT2040Mode)pMsgBuf; + + if((psessionEntry = peFindSessionByBssid(pMac, pSetHT2040Mode->bssId, + &sessionId)) == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given BSSID ")); + limPrintMacAddr(pMac, pSetHT2040Mode->bssId, LOGE); + return; + } + + limLog(pMac, LOGW, FL("Update session entry for cbMod=%d"), + pSetHT2040Mode->cbMode); + + /*Update sessionEntry HT related fields*/ + switch(pSetHT2040Mode->cbMode) + { + case PHY_SINGLE_CHANNEL_CENTERED: + psessionEntry->htSecondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED; + psessionEntry->htRecommendedTxWidthSet = 0; + break; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + psessionEntry->htSecondaryChannelOffset = + PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + psessionEntry->htRecommendedTxWidthSet = 1; + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + psessionEntry->htSecondaryChannelOffset = + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + psessionEntry->htRecommendedTxWidthSet = 1; + break; + default: + limLog(pMac, LOGE,FL("Invalid cbMode")); + return; + } + + limLog(pMac, LOGW, FL("Channel Bonding mode : %d" + " htSecondaryChannelOffset: %d" + " htRecommendedTxWidthSet :%d"), + pSetHT2040Mode->cbMode, + psessionEntry->htSecondaryChannelOffset, + psessionEntry->htRecommendedTxWidthSet); + + limLog(pMac, LOGW, FL("Update Beacon IEs")); + + /* Update beacon */ + schSetFixedBeaconFields(pMac, psessionEntry); + limSendBeaconInd(pMac, psessionEntry); + + /* Update OP Mode */ + pHtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode)); + if ( NULL == pHtOpMode ) + { + limLog(pMac, LOGE, + FL("Not able to allocate memory for setting OP mode")); + return; + } + + pHtOpMode->opMode = (psessionEntry->htSecondaryChannelOffset == + PHY_SINGLE_CHANNEL_CENTERED)? + eHT_CHANNEL_WIDTH_20MHZ:eHT_CHANNEL_WIDTH_40MHZ; + + /* Pass Self STA ID to FW. Based on Self STA ID FW will update the + * operating mode for all connected STA. + */ + + pHtOpMode->staId = psessionEntry->staId; + + msg.type = WDA_UPDATE_OP_MODE; + msg.reserved = 0; + msg.bodyptr = pHtOpMode; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + limLog(pMac, LOGE, + FL("Not able to post WDA_UPDATE_OP_MODE message to WDA")); + vos_mem_free(pHtOpMode); + return; + } + + limLog(pMac, LOGW, + FL("Notifed FW about OP mode: %d for staId=%d"), + pHtOpMode->opMode, pHtOpMode->staId); + + return; +} +#endif + +/** ------------------------------------------------------------- +\fn limProcessSmeDelBaPeerInd +\brief handles indication message from HDD to send delete BA request +\param tpAniSirGlobal pMac +\param tANI_U32 pMsgBuf +\return None +-------------------------------------------------------------*/ +void +limProcessSmeDelBaPeerInd(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tANI_U16 assocId =0; + tpSmeDelBAPeerInd pSmeDelBAPeerInd = (tpSmeDelBAPeerInd)pMsgBuf; + tpDphHashNode pSta; + tpPESession psessionEntry; + tANI_U8 sessionId; + + + + if(NULL == pSmeDelBAPeerInd) + return; + + if ((psessionEntry = peFindSessionByBssid(pMac,pSmeDelBAPeerInd->bssId,&sessionId))==NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given bssId")); + return; + } + limLog(pMac, LOGW, FL("called with staId = %d, tid = %d, baDirection = %d"), + pSmeDelBAPeerInd->staIdx, pSmeDelBAPeerInd->baTID, pSmeDelBAPeerInd->baDirection); + + pSta = dphLookupAssocId(pMac, pSmeDelBAPeerInd->staIdx, &assocId, &psessionEntry->dph.dphHashTable); + if( eSIR_SUCCESS != limPostMlmDelBAReq( pMac, + pSta, + pSmeDelBAPeerInd->baDirection, + pSmeDelBAPeerInd->baTID, + eSIR_MAC_UNSPEC_FAILURE_REASON,psessionEntry)) + { + limLog( pMac, LOGW, + FL( "Failed to post LIM_MLM_DELBA_REQ to " )); + if (pSta) + limPrintMacAddr(pMac, pSta->staAddr, LOGW); + } +} + +// -------------------------------------------------------------------- +/** + * __limProcessReportMessage + * + * FUNCTION: Processes the next received Radio Resource Management message + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void __limProcessReportMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ +#ifdef WLAN_FEATURE_VOWIFI + switch (pMsg->type) + { + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + rrmProcessNeighborReportReq( pMac, pMsg->bodyptr ); + break; + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: + { +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + tpSirBeaconReportXmitInd pBcnReport=NULL; + tpPESession psessionEntry=NULL; + tANI_U8 sessionId; + tpEsePEContext pEseContext = NULL; + + if(pMsg->bodyptr == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + pBcnReport = (tpSirBeaconReportXmitInd )pMsg->bodyptr; + if((psessionEntry = peFindSessionByBssid(pMac, pBcnReport->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE, "Session Does not exist for given bssId"); + return; + } + + pEseContext = &psessionEntry->eseContext; + + if (psessionEntry->isESEconnection && pEseContext->curMeasReq.isValid) + eseProcessBeaconReportXmit( pMac, pMsg->bodyptr); + else +#endif + rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr ); + } + break; + } +#endif +} + +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_VOWIFI) +// -------------------------------------------------------------------- +/** + * limSendSetMaxTxPowerReq + * + * FUNCTION: Send SIR_HAL_SET_MAX_TX_POWER_REQ message to change the max tx power. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param txPower txPower to be set. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry ) +{ + tpMaxTxPowerParams pMaxTxParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if( pSessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, "%s:%d: Inavalid parameters", __func__, __LINE__ );) + return eSIR_FAILURE; + } + + pMaxTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams)); + if ( NULL == pMaxTxParams ) + { + limLog( pMac, LOGP, "%s:%d:Unable to allocate memory for pMaxTxParams ", __func__, __LINE__); + return eSIR_MEM_ALLOC_FAILED; + + } +#if defined(WLAN_VOWIFI_DEBUG) || defined(FEATURE_WLAN_ESE) + limLog( pMac, LOG1, + FL(" Allocated memory for pMaxTxParams, which will be freed in other module")); +#endif + if( pMaxTxParams == NULL ) + { + limLog( pMac, LOGE, FL("pMaxTxParams is NULL")); + return eSIR_FAILURE; + } + pMaxTxParams->power = txPower; + vos_mem_copy( pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) ); + vos_mem_copy( pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) ); + + msgQ.type = WDA_SET_MAX_TX_POWER_REQ; + msgQ.bodyptr = pMaxTxParams; + msgQ.bodyval = 0; + limLog(pMac, LOG1, FL("Posting WDA_SET_MAX_TX_POWER_REQ to WDA")); + MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + PELOGE(limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed"));) + vos_mem_free(pMaxTxParams); + } + return retCode; +} +#endif + +/** + * __limProcessSmeAddStaSelfReq() + * + *FUNCTION: + * This function is called to process SME_ADD_STA_SELF_REQ message + * from SME. It sends a SIR_HAL_ADD_STA_SELF_REQ message to HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeAddStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + tpAddStaSelfParams pAddStaSelfParams; + tpSirSmeAddStaSelfReq pSmeReq = (tpSirSmeAddStaSelfReq) pMsgBuf; + + pAddStaSelfParams = vos_mem_malloc(sizeof(tAddStaSelfParams)); + if ( NULL == pAddStaSelfParams ) + { + limLog( pMac, LOGP, FL("Unable to allocate memory for tAddSelfStaParams") ); + return; + } + + vos_mem_copy( pAddStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) ); + pAddStaSelfParams->currDeviceMode = pSmeReq->currDeviceMode; + msg.type = SIR_HAL_ADD_STA_SELF_REQ; + msg.reserved = 0; + msg.bodyptr = pAddStaSelfParams; + msg.bodyval = 0; + + PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_ADD_STA_SELF_REQ msg to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed")); + } + return; +} /*** end __limProcessAddStaSelfReq() ***/ + + +/** + * __limProcessSmeDelStaSelfReq() + * + *FUNCTION: + * This function is called to process SME_DEL_STA_SELF_REQ message + * from SME. It sends a SIR_HAL_DEL_STA_SELF_REQ message to HAL. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ + +static void +__limProcessSmeDelStaSelfReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + tpDelStaSelfParams pDelStaSelfParams; + tpSirSmeDelStaSelfReq pSmeReq = (tpSirSmeDelStaSelfReq) pMsgBuf; + + pDelStaSelfParams = vos_mem_malloc(sizeof( tDelStaSelfParams)); + if ( NULL == pDelStaSelfParams ) + { + limLog( pMac, LOGP, FL("Unable to allocate memory for tDelStaSelfParams") ); + return; + } + + vos_mem_copy( pDelStaSelfParams->selfMacAddr, pSmeReq->selfMacAddr, sizeof(tSirMacAddr) ); + + msg.type = SIR_HAL_DEL_STA_SELF_REQ; + msg.reserved = 0; + msg.bodyptr = pDelStaSelfParams; + msg.bodyval = 0; + + PELOGW(limLog(pMac, LOG1, FL("sending SIR_HAL_DEL_STA_SELF_REQ msg to HAL"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGP, FL("wdaPostCtrlMsg failed")); + } + return; +} /*** end __limProcessSmeDelStaSelfReq() ***/ + + +/** + * __limProcessSmeRegisterMgmtFrameReq() + * + *FUNCTION: + * This function is called to process eWNI_SME_REGISTER_MGMT_FRAME_REQ message + * from SME. It Register this information within PE. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer + * @return None + */ +static void +__limProcessSmeRegisterMgmtFrameReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + VOS_STATUS vosStatus; + tpSirRegisterMgmtFrame pSmeReq = (tpSirRegisterMgmtFrame)pMsgBuf; + tpLimMgmtFrameRegistration pLimMgmtRegistration = NULL, pNext = NULL; + tANI_BOOLEAN match = VOS_FALSE; + limLog(pMac, LOG1, + FL("registerFrame %d, frameType %d, matchLen %d"), + pSmeReq->registerFrame, pSmeReq->frameType, pSmeReq->matchLen); + + /* First check whether entry exists already*/ + + vos_list_peek_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t**)&pLimMgmtRegistration); + + while(pLimMgmtRegistration != NULL) + { + if (pLimMgmtRegistration->frameType == pSmeReq->frameType) + { + if(pSmeReq->matchLen) + { + if (pLimMgmtRegistration->matchLen == pSmeReq->matchLen) + { + if (vos_mem_compare( pLimMgmtRegistration->matchData, + pSmeReq->matchData, pLimMgmtRegistration->matchLen)) + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + } + else + { + /* found match! */ + match = VOS_TRUE; + break; + } + } + vosStatus = vos_list_peek_next ( + &pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t*) pLimMgmtRegistration, + (vos_list_node_t**) &pNext ); + + pLimMgmtRegistration = pNext; + pNext = NULL; + + } + + if (match) + { + vos_list_remove_node(&pMac->lim.gLimMgmtFrameRegistratinQueue, + (vos_list_node_t*)pLimMgmtRegistration); + vos_mem_free(pLimMgmtRegistration); + } + + if(pSmeReq->registerFrame) + { + pLimMgmtRegistration = vos_mem_malloc(sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen); + if ( pLimMgmtRegistration != NULL) + { + vos_mem_set((void*)pLimMgmtRegistration, + sizeof(tLimMgmtFrameRegistration) + pSmeReq->matchLen, 0 ); + pLimMgmtRegistration->frameType = pSmeReq->frameType; + pLimMgmtRegistration->matchLen = pSmeReq->matchLen; + pLimMgmtRegistration->sessionId = pSmeReq->sessionId; + if(pSmeReq->matchLen) + { + vos_mem_copy(pLimMgmtRegistration->matchData, + pSmeReq->matchData, pSmeReq->matchLen); + } + vos_list_insert_front(&pMac->lim.gLimMgmtFrameRegistratinQueue, + &pLimMgmtRegistration->node); + } + } + + return; +} /*** end __limProcessSmeRegisterMgmtFrameReq() ***/ + +static tANI_BOOLEAN +__limInsertSingleShotNOAForScan(tpAniSirGlobal pMac, tANI_U32 noaDuration) +{ + tpP2pPsParams pMsgNoA; + tSirMsgQ msg; + + pMsgNoA = vos_mem_malloc(sizeof( tP2pPsConfig )); + if ( NULL == pMsgNoA ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during NoA Update" )); + goto error; + } + + vos_mem_set((tANI_U8 *)pMsgNoA, sizeof(tP2pPsConfig), 0); + /* Below params used for opp PS/periodic NOA and are don't care in this case - so initialized to 0 */ + pMsgNoA->opp_ps = 0; + pMsgNoA->ctWindow = 0; + pMsgNoA->duration = 0; + pMsgNoA->interval = 0; + pMsgNoA->count = 0; + + /* Below params used for Single Shot NOA - so assign proper values */ + pMsgNoA->psSelection = P2P_SINGLE_NOA; + pMsgNoA->single_noa_duration = noaDuration; + + /* Start Insert NOA timer + * If insert NOA req fails or NOA rsp fails or start NOA indication doesn't come from FW due to GO session deletion + * or any other failure or reason, we still need to process the deferred SME req. The insert NOA + * timer of 500 ms will ensure the stored SME req always gets processed + */ + if (tx_timer_activate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer) + == TX_TIMER_ERROR) + { + /// Could not activate Insert NOA timer. + // Log error + limLog(pMac, LOGP, FL("could not activate Insert Single Shot NOA during scan timer")); + + // send the scan response back with status failure and do not even call insert NOA + limSendSmeScanRsp(pMac, sizeof(tSirSmeScanRsp), eSIR_SME_SCAN_FAILED, pMac->lim.gSmeSessionId, pMac->lim.gTransactionId); + vos_mem_free(pMsgNoA); + goto error; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_INSERT_SINGLESHOT_NOA_TIMER)); + + msg.type = WDA_SET_P2P_GO_NOA_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgNoA; + msg.bodyval = 0; + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + /* In this failure case, timer is already started, so its expiration will take care of sending scan response */ + limLog(pMac, LOGP, FL("wdaPost Msg failed")); + /* Deactivate the NOA timer in failure case */ + limDeactivateAndChangeTimer(pMac, eLIM_INSERT_SINGLESHOT_NOA_TIMER); + goto error; + } + return FALSE; + +error: + /* In any of the failure cases, just go ahead with the processing of registered deferred SME request without + * worrying about the NOA + */ + limProcessRegdDefdSmeReqAfterNOAStart(pMac); + // msg buffer is consumed and freed in above function so return FALSE + return FALSE; + +} + +static void __limRegisterDeferredSmeReqForNOAStart(tpAniSirGlobal pMac, tANI_U16 msgType, tANI_U32 *pMsgBuf) +{ + limLog(pMac, LOG1, FL("Reg msgType %d"), msgType) ; + pMac->lim.gDeferMsgTypeForNOA = msgType; + pMac->lim.gpDefdSmeMsgForNOA = pMsgBuf; +} + +static void __limDeregisterDeferredSmeReqAfterNOAStart(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("Dereg msgType %d"), pMac->lim.gDeferMsgTypeForNOA) ; + pMac->lim.gDeferMsgTypeForNOA = 0; + if (pMac->lim.gpDefdSmeMsgForNOA != NULL) + { + /* __limProcessSmeScanReq consumed the buffer. We can free it. */ + vos_mem_free(pMac->lim.gpDefdSmeMsgForNOA); + pMac->lim.gpDefdSmeMsgForNOA = NULL; + } +} + +static +tANI_U32 limCalculateNOADuration(tpAniSirGlobal pMac, tANI_U16 msgType, + tANI_U32 *pMsgBuf, tANI_BOOLEAN isPassiveScan) +{ + tANI_U32 noaDuration = 0; + + switch (msgType) + { + case eWNI_SME_SCAN_REQ: + { + tANI_U32 val; + tANI_U8 i; + tpSirSmeScanReq pScanReq = (tpSirSmeScanReq) pMsgBuf; + if (wlan_cfgGetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &val) != eSIR_SUCCESS) + { + /* + * Could not get max channel value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve passive max channel value")); + + /* use a default value of 110ms */ + val = DEFAULT_PASSIVE_MAX_CHANNEL_TIME; + } + + for (i = 0; i < pScanReq->channelList.numChannels; i++) { + tANI_U8 channelNum = pScanReq->channelList.channelNumber[i]; + + if (pMac->miracast_mode) { + noaDuration += DEFAULT_MIN_CHAN_TIME_DURING_MIRACAST + + DEFAULT_MAX_CHAN_TIME_DURING_MIRACAST; + } else if (isPassiveScan || !limActiveScanAllowed(pMac, channelNum)) { + /* using the value from WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME as is done in + * void limContinuePostChannelScan(tpAniSirGlobal pMac) + */ + noaDuration += val; + } else { + /* Use min + max channel time to calculate the total duration of scan */ + noaDuration += pScanReq->minChannelTime + pScanReq->maxChannelTime; + } + } + + /* Adding an overhead of 20ms to account for the scan messaging delays */ + noaDuration += SCAN_MESSAGING_OVERHEAD; + noaDuration *= CONV_MS_TO_US; + + break; + } + + case eWNI_SME_OEM_DATA_REQ: + noaDuration = OEM_DATA_NOA_DURATION*CONV_MS_TO_US; // use 60 msec as default + break; + + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + { + tSirRemainOnChnReq *pRemainOnChnReq = (tSirRemainOnChnReq *) pMsgBuf; + noaDuration = (pRemainOnChnReq->duration)*CONV_MS_TO_US; + break; + } + + case eWNI_SME_JOIN_REQ: + noaDuration = JOIN_NOA_DURATION*CONV_MS_TO_US; + break; + + default: + noaDuration = 0; + break; + + } + limLog(pMac, LOGW, FL("msgType %d noa %d"), msgType, noaDuration); + return noaDuration; +} + +void limProcessRegdDefdSmeReqAfterNOAStart(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN bufConsumed = TRUE; + + limLog(pMac, LOG1, FL("Process defd sme req %d"), pMac->lim.gDeferMsgTypeForNOA); + if ( (pMac->lim.gDeferMsgTypeForNOA != 0) && + (pMac->lim.gpDefdSmeMsgForNOA != NULL) ) + { + switch (pMac->lim.gDeferMsgTypeForNOA) + { + case eWNI_SME_SCAN_REQ: + __limProcessSmeScanReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + break; + case eWNI_SME_OEM_DATA_REQ: + __limProcessSmeOemDataReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + break; + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + bufConsumed = limProcessRemainOnChnlReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + /* limProcessRemainOnChnlReq doesnt want us to free the buffer since + * it is freed in limRemainOnChnRsp. this change is to avoid "double free" + */ + if (FALSE == bufConsumed) + { + pMac->lim.gpDefdSmeMsgForNOA = NULL; + } + break; + case eWNI_SME_JOIN_REQ: + __limProcessSmeJoinReq(pMac, pMac->lim.gpDefdSmeMsgForNOA); + break; + default: + limLog(pMac, LOGE, FL("Unknown deferred msg type %d"), pMac->lim.gDeferMsgTypeForNOA); + break; + } + __limDeregisterDeferredSmeReqAfterNOAStart(pMac); + } + else + { + limLog( pMac, LOGW, FL("start received from FW when no sme deferred msg pending. Do nothing." + "It might happen sometime when NOA start ind and timeout happen at the same time")); + } +} + +static void +__limProcessSmeResetApCapsChange(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirResetAPCapsChange pResetCapsChange; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + if (pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + pResetCapsChange = (tpSirResetAPCapsChange)pMsgBuf; + psessionEntry = peFindSessionByBssid(pMac, pResetCapsChange->bssId, &sessionId); + if (psessionEntry == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given BSSID")); + return; + } + + psessionEntry->limSentCapsChangeNtf = false; + return; +} + +static void +__limProcessSmeSpoofMacAddrRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + tpSpoofMacAddrReqParams pSpoofMacAddrParams; + tpSirSpoofMacAddrReq pSmeReq = (tpSirSpoofMacAddrReq) pMsgBuf; + + pSpoofMacAddrParams = vos_mem_malloc(sizeof( tSpoofMacAddrReqParams)); + if ( NULL == pSpoofMacAddrParams ) + { + limLog( pMac, LOGE, FL("Unable to allocate memory for tDelStaSelfParams") ); + return; + } + + vos_mem_copy( pSpoofMacAddrParams->macAddr, pSmeReq->macAddr, sizeof(tSirMacAddr) ); + + vos_mem_copy(pMac->lim.spoofMacAddr, pSmeReq->macAddr, VOS_MAC_ADDRESS_LEN); + + limLog( pMac, LOG1, FL("Recieved Spoofed Mac Addr request with Addr:" + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMac->lim.spoofMacAddr) ); + + msg.type = WDA_SPOOF_MAC_ADDR_REQ; + msg.reserved = 0; + msg.bodyptr = pSpoofMacAddrParams; + msg.bodyval = 0; + + limLog(pMac, LOG1, FL("sending SIR_HAL_SPOOF_MAC_ADDR_REQ msg to HAL")); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("wdaPostCtrlMsg failed for SIR_HAL_SPOOF_MAC_ADDR_REQ")); + vos_mem_free(pSpoofMacAddrParams); + } + return; +} + +/** + * lim_register_mgmt_frame_ind_cb() - Save the Management frame + * indication callback in PE. + * @pMac: Mac pointer + * @pMsgBuf: Msg pointer containing the callback + * + * This function is used save the Management frame + * indication callback in PE. + * + * Return: None + */ +static void lim_register_mgmt_frame_ind_cb(tpAniSirGlobal pMac, + tANI_U32 *msg_buf) +{ + struct sir_sme_mgmt_frame_cb_req *sme_req = + (struct sir_sme_mgmt_frame_cb_req *)msg_buf; + + if (NULL == msg_buf) + { + limLog(pMac, LOGE, FL("msg_buf is null")); + return; + } + if (sme_req->callback) + pMac->mgmt_frame_ind_cb = + (sir_mgmt_frame_ind_callback)sme_req->callback; + else + limLog(pMac, LOGE, FL("sme_req->callback is null")); +} + +/** + * limProcessSmeReqMessages() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function processes SME request messages from HDD or upper layer + * application. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the SME message type + * @param *pMsgBuf A pointer to the SME message buffer + * @return Boolean - TRUE - if pMsgBuf is consumed and can be freed. + * FALSE - if pMsgBuf is not to be freed. + */ + +tANI_BOOLEAN +limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tANI_BOOLEAN bufConsumed = TRUE; //Set this flag to false within case block of any following message, that doesnt want pMsgBuf to be freed. + tANI_U32 *pMsgBuf = pMsg->bodyptr; + tpSirSmeScanReq pScanReq; + tANI_BOOLEAN isPassiveScan = FALSE; + + PELOG1(limLog(pMac, LOG1, FL("LIM Received SME Message %s(%d) Global LimSmeState:%s(%d) Global LimMlmState: %s(%d)"), + limMsgStr(pMsg->type), pMsg->type, + limSmeStateStr(pMac->lim.gLimSmeState), pMac->lim.gLimSmeState, + limMlmStateStr(pMac->lim.gLimMlmState), pMac->lim.gLimMlmState );) + + pScanReq = (tpSirSmeScanReq) pMsgBuf; + /* Special handling of some SME Req msgs where we have an existing GO session and + * want to insert NOA before processing those msgs. These msgs will be processed later when + * start event happens + */ + switch (pMsg->type) + { + case eWNI_SME_SCAN_REQ: + pScanReq = (tpSirSmeScanReq) pMsgBuf; + isPassiveScan = (pScanReq->scanType == eSIR_PASSIVE_SCAN) ? TRUE : FALSE; + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + + /* If scan is disabled return from here + */ + if (pMac->lim.fScanDisabled) + { + if (pMsg->type == eWNI_SME_SCAN_REQ) + { + limSendSmeScanRsp(pMac, + offsetof(tSirSmeScanRsp,bssDescription[0]), + eSIR_SME_INVALID_PARAMETERS, + pScanReq->sessionId, + pScanReq->transactionId); + + bufConsumed = TRUE; + } + else if (pMsg->type == eWNI_SME_REMAIN_ON_CHANNEL_REQ) + { + pMac->lim.gpDefdSmeMsgForNOA = NULL; + pMac->lim.gpLimRemainOnChanReq = (tpSirRemainOnChnReq )pMsgBuf; + limRemainOnChnRsp(pMac,eHAL_STATUS_FAILURE, NULL); + + /* + * limRemainOnChnRsp will free the buffer this change is to + * avoid "double free" + */ + bufConsumed = FALSE; + } + + limLog(pMac, LOGE, + FL("Error: Scan Disabled." + " Return with error status for SME Message %s(%d)"), + limMsgStr(pMsg->type), pMsg->type); + + return bufConsumed; + } + /* + * Do not add BREAK here + */ + case eWNI_SME_OEM_DATA_REQ: + case eWNI_SME_JOIN_REQ: + /* If we have an existing P2P GO session we need to insert NOA before actually process this SME Req */ + if ((limIsNOAInsertReqd(pMac) == TRUE) && IS_FEATURE_SUPPORTED_BY_FW(P2P_GO_NOA_DECOUPLE_INIT_SCAN)) + { + tANI_U32 noaDuration; + __limRegisterDeferredSmeReqForNOAStart(pMac, pMsg->type, pMsgBuf); + noaDuration = limCalculateNOADuration(pMac, pMsg->type, pMsgBuf, isPassiveScan); + bufConsumed = __limInsertSingleShotNOAForScan(pMac, noaDuration); + return bufConsumed; + } + } + /* If no insert NOA required then execute the code below */ + + switch (pMsg->type) + { + case eWNI_SME_START_REQ: + __limProcessSmeStartReq(pMac, pMsgBuf); + break; + + case eWNI_SME_SYS_READY_IND: + bufConsumed = __limProcessSmeSysReadyInd(pMac, pMsgBuf); + break; + + case eWNI_SME_START_BSS_REQ: + bufConsumed = __limProcessSmeStartBssReq(pMac, pMsg); + break; + + case eWNI_SME_SCAN_REQ: + __limProcessSmeScanReq(pMac, pMsgBuf); + break; + +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: + __limProcessSmeOemDataReq(pMac, pMsgBuf); + break; +#endif + case eWNI_SME_REMAIN_ON_CHANNEL_REQ: + bufConsumed = limProcessRemainOnChnlReq(pMac, pMsgBuf); + break; + + case eWNI_SME_UPDATE_NOA: + __limProcessSmeNoAUpdate(pMac, pMsgBuf); + break; + case eWNI_SME_CLEAR_DFS_CHANNEL_LIST: + __limProcessClearDfsChannelList(pMac, pMsg); + break; + case eWNI_SME_JOIN_REQ: + __limProcessSmeJoinReq(pMac, pMsgBuf); + break; + + case eWNI_SME_AUTH_REQ: + // __limProcessSmeAuthReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_REASSOC_REQ: + __limProcessSmeReassocReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_PROMISCUOUS_MODE_REQ: + //__limProcessSmePromiscuousReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_DISASSOC_REQ: + __limProcessSmeDisassocReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_DISASSOC_CNF: + case eWNI_SME_DEAUTH_CNF: + __limProcessSmeDisassocCnf(pMac, pMsgBuf); + + break; + + case eWNI_SME_DEAUTH_REQ: + __limProcessSmeDeauthReq(pMac, pMsgBuf); + + break; + + + + case eWNI_SME_SETCONTEXT_REQ: + __limProcessSmeSetContextReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_REMOVEKEY_REQ: + __limProcessSmeRemoveKeyReq(pMac, pMsgBuf); + + break; + + case eWNI_SME_STOP_BSS_REQ: + bufConsumed = __limProcessSmeStopBssReq(pMac, pMsg); + break; + + case eWNI_SME_ASSOC_CNF: + case eWNI_SME_REASSOC_CNF: + if (pMsg->type == eWNI_SME_ASSOC_CNF) + limLog(pMac, LOG1, FL("Received ASSOC_CNF message")); + else + limLog(pMac, LOG1, FL("Received REASSOC_CNF message")); +#ifdef SAP_AUTH_OFFLOAD + if (pMac->sap_auth_offload) + __lim_process_sme_assoc_offload_cnf(pMac, pMsg->type, pMsgBuf); + else + __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf); +#else + __limProcessSmeAssocCnfNew(pMac, pMsg->type, pMsgBuf); +#endif /* SAP_AUTH_OFFLOAD */ + break; + + case eWNI_SME_ADDTS_REQ: + limLog(pMac, LOG1, FL("Received ADDTS_REQ message")); + __limProcessSmeAddtsReq(pMac, pMsgBuf); + break; + + case eWNI_SME_DELTS_REQ: + limLog(pMac, LOG1, FL("Received DELTS_REQ message")); + __limProcessSmeDeltsReq(pMac, pMsgBuf); + break; + + case SIR_LIM_ADDTS_RSP_TIMEOUT: + limLog(pMac, LOG1, FL("Received SIR_LIM_ADDTS_RSP_TIMEOUT message ")); + limProcessSmeAddtsRspTimeout(pMac, pMsg->bodyval); + break; + + case eWNI_SME_STA_STAT_REQ: + case eWNI_SME_AGGR_STAT_REQ: + case eWNI_SME_GLOBAL_STAT_REQ: + case eWNI_SME_STAT_SUMM_REQ: + __limProcessSmeStatsRequest( pMac, pMsgBuf); + //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. + bufConsumed = FALSE; + break; + case eWNI_SME_GET_STATISTICS_REQ: + __limProcessSmeGetStatisticsRequest( pMac, pMsgBuf); + //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. + bufConsumed = FALSE; + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_REQ: + __limProcessSmeGetRoamRssiRequest( pMac, pMsgBuf); + //HAL consumes pMsgBuf. It will be freed there. Set bufConsumed to false. + bufConsumed = FALSE; + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_REQ: + __limProcessSmeGetTsmStatsRequest( pMac, pMsgBuf); + bufConsumed = FALSE; + break; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eWNI_SME_DEL_BA_PEER_IND: + limProcessSmeDelBaPeerInd(pMac, pMsgBuf); + break; + case eWNI_SME_GET_SCANNED_CHANNEL_REQ: + limProcessSmeGetScanChannelInfo(pMac, pMsgBuf); + break; + case eWNI_SME_GET_ASSOC_STAS_REQ: + limProcessSmeGetAssocSTAsInfo(pMac, pMsgBuf); + break; + case eWNI_SME_TKIP_CNTR_MEAS_REQ: + limProcessTkipCounterMeasures(pMac, pMsgBuf); + break; + + case eWNI_SME_HIDE_SSID_REQ: + __limProcessSmeHideSSID(pMac, pMsgBuf); + break; + case eWNI_SME_UPDATE_APWPSIE_REQ: + __limProcessSmeUpdateAPWPSIEs(pMac, pMsgBuf); + break; + case eWNI_SME_GET_WPSPBC_SESSION_REQ: + limProcessSmeGetWPSPBCSessions(pMac, pMsgBuf); + break; + + case eWNI_SME_SET_APWPARSNIEs_REQ: + __limProcessSmeSetWPARSNIEs(pMac, pMsgBuf); + break; + + case eWNI_SME_CHNG_MCC_BEACON_INTERVAL: + //Update the beaconInterval + __limProcessSmeChangeBI(pMac, pMsgBuf ); + break; + +#ifdef WLAN_FEATURE_AP_HT40_24G + case eWNI_SME_SET_HT_2040_MODE: + __limProcessSmeSetHT2040Mode(pMac, pMsgBuf); + break; +#endif + +#if defined WLAN_FEATURE_VOWIFI + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: + __limProcessReportMessage(pMac, pMsg); + break; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_PRE_AUTH_REQ: + bufConsumed = (tANI_BOOLEAN)limProcessFTPreAuthReq(pMac, pMsg); + break; + case eWNI_SME_FT_UPDATE_KEY: + limProcessFTUpdateKey(pMac, pMsgBuf); + break; + + case eWNI_SME_FT_AGGR_QOS_REQ: + limProcessFTAggrQosReq(pMac, pMsgBuf); + break; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + case eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ: + lim_process_pre_auth_reassoc_req(pMac, pMsg); + bufConsumed = FALSE; + break; +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_ESE_ADJACENT_AP_REPORT: + limProcessAdjacentAPRepMsg ( pMac, pMsgBuf ); + break; +#endif + case eWNI_SME_ADD_STA_SELF_REQ: + __limProcessSmeAddStaSelfReq( pMac, pMsgBuf ); + break; + case eWNI_SME_DEL_STA_SELF_REQ: + __limProcessSmeDelStaSelfReq( pMac, pMsgBuf ); + break; + + case eWNI_SME_REGISTER_MGMT_FRAME_REQ: + __limProcessSmeRegisterMgmtFrameReq( pMac, pMsgBuf ); + break; +#ifdef FEATURE_WLAN_TDLS + case eWNI_SME_TDLS_SEND_MGMT_REQ: + limProcessSmeTdlsMgmtSendReq(pMac, pMsgBuf); + break; + case eWNI_SME_TDLS_ADD_STA_REQ: + limProcessSmeTdlsAddStaReq(pMac, pMsgBuf); + break; + case eWNI_SME_TDLS_DEL_STA_REQ: + limProcessSmeTdlsDelStaReq(pMac, pMsgBuf); + break; + case eWNI_SME_TDLS_LINK_ESTABLISH_REQ: + limProcesSmeTdlsLinkEstablishReq(pMac, pMsgBuf); + break; +// tdlsoffchan + case eWNI_SME_TDLS_CHANNEL_SWITCH_REQ: + limProcesSmeTdlsChanSwitchReq(pMac, pMsgBuf); + break; +#endif + case eWNI_SME_RESET_AP_CAPS_CHANGED: + __limProcessSmeResetApCapsChange(pMac, pMsgBuf); + break; + + case eWNI_SME_SET_TX_POWER_REQ: + limSendSetTxPowerReq(pMac, pMsgBuf); + break ; + +#ifdef WLAN_FEATURE_RMC + case eWNI_SME_ENABLE_RMC_REQ: + limProcessRMCMessages(pMac, eLIM_RMC_ENABLE_REQ, pMsgBuf); + break ; + + case eWNI_SME_DISABLE_RMC_REQ: + limProcessRMCMessages(pMac, eLIM_RMC_DISABLE_REQ, pMsgBuf); + break ; +#endif /* WLAN_FEATURE_RMC */ + + case eWNI_SME_MAC_SPOOF_ADDR_IND: + __limProcessSmeSpoofMacAddrRequest(pMac, pMsgBuf); + break ; + case eWNI_SME_REGISTER_MGMT_FRAME_CB: + lim_register_mgmt_frame_ind_cb(pMac, pMsgBuf); + break; + default: + vos_mem_free((v_VOID_t*)pMsg->bodyptr); + pMsg->bodyptr = NULL; + break; + } // switch (msgType) + + return bufConsumed; +} /*** end limProcessSmeReqMessages() ***/ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessTdls.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessTdls.c new file mode 100644 index 000000000000..0fd0050f7ad8 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessTdls.c @@ -0,0 +1,3963 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + limProcessTdls.c + + OVERVIEW: + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +05/05/2010 Ashwani Initial Creation, added TDLS action frame functionality, + TDLS message exchange with SME..etc.. + +===========================================================================*/ + + +/** + * \file limProcessTdls.c + * + * \brief Code for preparing,processing and sending 802.11z action frames + * + */ + +#ifdef FEATURE_WLAN_TDLS + +#include "sirApi.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" +#include "cfgApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "dot11f.h" +#include "limStaHashApi.h" +#include "schApi.h" +#include "limSendMessages.h" +#include "utilsParser.h" +#include "limAssocUtils.h" +#include "dphHashTable.h" +#include "wlan_qct_wda.h" + +/* define NO_PAD_TDLS_MIN_8023_SIZE to NOT padding: See CR#447630 +There was IOT issue with cisco 1252 open mode, where it pads +discovery req/teardown frame with some junk value up to min size. +To avoid this issue, we pad QCOM_VENDOR_IE. +If there is other IOT issue because of this bandage, define NO_PAD... +*/ +#ifndef NO_PAD_TDLS_MIN_8023_SIZE +#define MIN_IEEE_8023_SIZE 46 +#define MIN_VENDOR_SPECIFIC_IE_SIZE 5 +#endif + +static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac, + tSirTdlsAddStaReq *pAddStaReq, + tpPESession psessionEntry) ; +void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry, + tDot11fIELinkIdentifier *linkIden, + tSirMacAddr peerMac, tANI_U8 reqType) ; +void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, + tDot11fIEExtCap *extCapability) ; + +void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIESuppChannels *suppChannels, + tDot11fIESuppOperatingClasses *suppOperClasses); + +void limLogVHTCap(tpAniSirGlobal pMac, + tDot11fIEVHTCaps *pDot11f); +tSirRetStatus limPopulateVhtMcsSet(tpAniSirGlobal pMac, + tpSirSupportedRates pRates, + tDot11fIEVHTCaps *pPeerVHTCaps, + tpPESession psessionEntry); +ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode); +/*only 31 op classes are available, 1 entry for current op class*/ +static tDot11fIESuppOperatingClasses op_classes = {0}; + +op_class_map_t global_op_class[] = { + {81, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {82, 25, BW20, {14}}, + {83, 40, BW40PLUS, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {84, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {115, 20, BW20, {36, 40, 44, 48}}, + {116, 40, BW40PLUS, {36, 44}}, + {117, 40, BW40MINUS, {40, 48}}, + {118, 20, BW20, {52, 56, 60, 64}}, + {119, 40, BW40PLUS, {52, 60}}, + {120, 40, BW40MINUS, {56, 64}}, + {121, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {122, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {123, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {125, 20, BW20, {149, 153, 157, 161, 165, 169}}, + {126, 40, BW40PLUS, {149, 157}}, + {127, 40, BW40MINUS, {153, 161}}, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128, 132, 136, 140, 144, + 149, 153, 157, 161}}, + {0, 0, 0, {0}}, + +};/*end global_op_class*/ + +op_class_map_t us_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {2, 20, BW20, {52, 56, 60, 64}}, + {4, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144}}, + {5, 20, BW20, {149, 153, 157, 161, 165}}, + {12, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}, + {22, 40, BW40PLUS, {36, 44}}, + {23, 40, BW40PLUS, {52, 60}}, + {24, 40, BW40PLUS, {100, 108, 116, 124, 132, 140}}, + {26, 40, BW40PLUS, {149, 157}}, + {27, 40, BW40MINUS, {40, 48}}, + {28, 40, BW40MINUS, {56, 64}}, + {29, 40, BW40MINUS, {104, 112, 120, 128, 136, 144}}, + {31, 40, BW40MINUS, {153, 161}}, + {32, 40, BW40PLUS, {1, 2, 3, 4, 5, 6, 7}}, + {33, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11}}, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128, 132, 136, 140, 144, + 149, 153, 157, 161}}, + {0, 0, 0, {0}}, +};/*end us_op_class*/ + +op_class_map_t euro_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {2, 20, BW20, {52, 56, 60, 64}}, + {3, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {4, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {5, 40, BW40PLUS, {36, 44}}, + {6, 40, BW40PLUS, {52, 60}}, + {7, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {8, 40, BW40MINUS, {40, 48}}, + {9, 40, BW40MINUS, {56, 64}}, + {10, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {11, 40, BW40PLUS, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, + {12, 40, BW40MINUS, {5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {17, 20, BW20, {149, 153, 157, 161, 165, 169}}, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128}}, + {0, 0, 0, {0}}, +};/*end euro_op_class*/ + +op_class_map_t japan_op_class[] = { + {1, 20, BW20, {36, 40, 44, 48}}, + {30, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}, + {31, 25, BW20, {14}}, + {32, 20, BW20, {52, 56, 60, 64}}, + {34, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}, + {36, 40, BW40PLUS, {36, 44}}, + {37, 40, BW40PLUS, {52, 60}}, + {39, 40, BW40PLUS, {100, 108, 116, 124, 132}}, + {41, 40, BW40MINUS, {40, 48}}, + {42, 40, BW40MINUS, {56, 64}}, + {44, 40, BW40MINUS, {104, 112, 120, 128, 136}}, + {128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128}}, + {0, 0, 0, {0}}, +};/*end japan_op_class*/ + +/* + * TDLS data frames will go out/come in as non-qos data. + * so, eth_890d_header will be aligned access.. + */ +static const tANI_U8 eth_890d_header[] = +{ + 0xaa, 0xaa, 0x03, 0x00, + 0x00, 0x00, 0x89, 0x0d, +} ; + +/* store tdls self supported channels + * which are non passive */ +#define LIM_TDLS_MAX_NON_DFS_CHANNELS 50 +static tANI_U8 tdlsSelfNumChans = 0; +static tANI_U8 tdlsSelfSupportedChannels[LIM_TDLS_MAX_NON_DFS_CHANNELS] = {0}; + +/* + * type of links used in TDLS + */ +enum tdlsLinks +{ + TDLS_LINK_AP, + TDLS_LINK_DIRECT +} eTdlsLink ; + +/* + * node status in node searching + */ +enum tdlsLinkNodeStatus +{ + TDLS_NODE_NOT_FOUND, + TDLS_NODE_FOUND +} eTdlsLinkNodeStatus ; + + +enum tdlsReqType +{ + TDLS_INITIATOR, + TDLS_RESPONDER +} eTdlsReqType ; + +typedef enum tdlsLinkSetupStatus +{ + TDLS_SETUP_STATUS_SUCCESS = 0, + TDLS_SETUP_STATUS_FAILURE = 37 +}etdlsLinkSetupStatus ; + +/* These maps to Kernel TDLS peer capability + * flags and should get changed as and when necessary + */ +enum tdls_peer_capability { + TDLS_PEER_HT_CAP = 0, + TDLS_PEER_VHT_CAP = 1, + TDLS_PEER_WMM_CAP = 2 +} eTdlsPeerCapability; + +/* some local defines */ +#define LINK_IDEN_BSSID_OFFSET (0) +#define PEER_MAC_OFFSET (12) +#define STA_MAC_OFFSET (6) +#define LINK_IDEN_ELE_ID (101) +//#define LINK_IDEN_LENGTH (18) +#define LINK_IDEN_ADDR_OFFSET(x) (&x.LinkIdentifier) +#define PTI_LINK_IDEN_OFFSET (5) +#define PTI_BUF_STATUS_OFFSET (25) + +/* TODO, Move this parameters to configuration */ +#define PEER_PSM_SUPPORT (0) +#define PEER_BUFFER_STA_SUPPORT (0) +#define CH_SWITCH_SUPPORT (0) +#define TDLS_SUPPORT (1) +#define TDLS_PROHIBITED (0) +#define TDLS_CH_SWITCH_PROHIBITED (1) +/** @brief Set bit manipulation macro */ +#define SET_BIT(value,mask) ((value) |= (1 << (mask))) +/** @brief Clear bit manipulation macro */ +#define CLEAR_BIT(value,mask) ((value) &= ~(1 << (mask))) +/** @brief Check bit manipulation macro */ +#define CHECK_BIT(value, mask) ((value) & (1 << (mask))) + +#define SET_PEER_AID_BITMAP(peer_bitmap, aid) \ + if ((aid) < (sizeof(tANI_U32) << 3)) \ + SET_BIT(peer_bitmap[0], (aid)); \ + else if ((aid) < (sizeof(tANI_U32) << 4)) \ + SET_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3))); + +#define CLEAR_PEER_AID_BITMAP(peer_bitmap, aid) \ + if ((aid) < (sizeof(tANI_U32) << 3)) \ + CLEAR_BIT(peer_bitmap[0], (aid)); \ + else if ((aid) < (sizeof(tANI_U32) << 4)) \ + CLEAR_BIT(peer_bitmap[1], ((aid) - (sizeof(tANI_U32) << 3))); + + +#ifdef LIM_DEBUG_TDLS + +#ifdef FEATURE_WLAN_TDLS +#define WNI_CFG_TDLS_DISCOVERY_RSP_WAIT (100) +#define WNI_CFG_TDLS_LINK_SETUP_RSP_TIMEOUT (800) +#define WNI_CFG_TDLS_LINK_SETUP_CNF_TIMEOUT (200) +#endif + +#define IS_QOS_ENABLED(psessionEntry) ((((psessionEntry)->limQosEnabled) && \ + SIR_MAC_GET_QOS((psessionEntry)->limCurrentBssCaps)) || \ + (((psessionEntry)->limWmeEnabled ) && \ + LIM_BSS_CAPS_GET(WME, (psessionEntry)->limCurrentBssQosCaps))) + +#define TID_AC_VI 4 +#define TID_AC_BK 1 + +const tANI_U8* limTraceTdlsActionString( tANI_U8 tdlsActionCode ) +{ + switch( tdlsActionCode ) + { + CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_REQ); + CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_RSP); + CASE_RETURN_STRING(SIR_MAC_TDLS_SETUP_CNF); + CASE_RETURN_STRING(SIR_MAC_TDLS_TEARDOWN); + CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_IND); + CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_REQ); + CASE_RETURN_STRING(SIR_MAC_TDLS_CH_SWITCH_RSP); + CASE_RETURN_STRING(SIR_MAC_TDLS_PEER_TRAFFIC_RSP); + CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_REQ); + CASE_RETURN_STRING(SIR_MAC_TDLS_DIS_RSP); + } + return (const tANI_U8*)"UNKNOWN"; +} +#endif +#if 0 +static void printMacAddr(tSirMacAddr macAddr) +{ + int i = 0 ; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, (" Mac Addr: ")); + + for(i = 0 ; i < 6; i++) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + (" %02x "), macAddr[i]); + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, ("")); + return ; +} +#endif +/* + * initialize TDLS setup list and related data structures. + */ +void limInitTdlsData(tpAniSirGlobal pMac, tpPESession pSessionEntry) +{ + limInitPeerIdxpool(pMac, pSessionEntry) ; + + return ; +} +#ifdef FEATURE_WLAN_TDLS_NEGATIVE +void limTdlsSetNegativeBehavior(tpAniSirGlobal pMac, tANI_U8 value, tANI_BOOLEAN on) +{ + if(on) { + if(value == 255) + pMac->lim.gLimTdlsNegativeBehavior = 0XFFFFFFFF; + else + pMac->lim.gLimTdlsNegativeBehavior |= (1 << (value-1)); + } + else { + if(value == 255) + pMac->lim.gLimTdlsNegativeBehavior = 0; + else + pMac->lim.gLimTdlsNegativeBehavior &= ~(1 << (value-1)); + } + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,("%d %d -> gLimTdlsNegativeBehavior= 0x%lx"), + value, on, pMac->lim.gLimTdlsNegativeBehavior)); +} +#endif +#if 0 +/* + * This function is used for creating TDLS public Action frame to + * transmit on Direct link + */ +static void limPreparesActionFrameHdr(tpAniSirGlobal pMac, tANI_U8 *pFrame, + tANI_U8 type, tANI_U8 subType, + tANI_U8 *link_iden ) +{ + tpSirMacMgmtHdr pMacHdr ; + tANI_U8 *bssid = link_iden ; +#if 0 + tANI_U8 *staMac = (tANI_U8 *)(bssid + sizeof(tSirMacAddr)) ; + tANI_U8 *peerMac = (tANI_U8 *) (staMac + sizeof(tSirMacAddr)) ; +#else + tANI_U8 *peerMac = (tANI_U8 *) (bssid + sizeof(tSirMacAddr)) ; + tANI_U8 *staMac = (tANI_U8 *)(peerMac + sizeof(tSirMacAddr)) ; +#endif + tANI_U8 toDs = ANI_TXDIR_IBSS ; + + pMacHdr = (tpSirMacMgmtHdr) (pFrame); + + /* + * prepare 802.11 header + */ + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type ; + pMacHdr->fc.subType = subType ; + /* + * TL is not setting up below fields, so we are doing it here + */ + pMacHdr->fc.toDS = toDs ; + pMacHdr->fc.powerMgmt = 0 ; + + + vos_mem_copy( (tANI_U8 *) pMacHdr->da, peerMac, sizeof( tSirMacAddr )); + vos_mem_copy( (tANI_U8 *) pMacHdr->sa, + staMac, sizeof( tSirMacAddr )); + + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + bssid, sizeof( tSirMacAddr )); + + LIM_LOG_TDLS(VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_WARN, ("Preparing TDLS action frame\n%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x:%02x"), + pMacHdr->da[0], pMacHdr->da[1], pMacHdr->da[2], pMacHdr->da[3], pMacHdr->da[4], pMacHdr->da[5], + pMacHdr->sa[0], pMacHdr->sa[1], pMacHdr->sa[2], pMacHdr->sa[3], pMacHdr->sa[4], pMacHdr->sa[5], + pMacHdr->bssId[0], pMacHdr->bssId[1], pMacHdr->bssId[2], + pMacHdr->bssId[3], pMacHdr->bssId[4], pMacHdr->bssId[5])); + + return ; +} +#endif +/* + * prepare TDLS frame header, it includes + * | | | | + * |802.11 header|RFC1042 header|TDLS_PYLOAD_TYPE|PAYLOAD + * | | | | + */ +static tANI_U32 limPrepareTdlsFrameHeader(tpAniSirGlobal pMac, tANI_U8* pFrame, + tDot11fIELinkIdentifier *link_iden, tANI_U8 tdlsLinkType, tANI_U8 reqType, + tANI_U8 tid, tpPESession psessionEntry) +{ + tpSirMacDataHdr3a pMacHdr ; + tANI_U32 header_offset = 0 ; + tANI_U8 *addr1 = NULL ; + tANI_U8 *addr3 = NULL ; + tpDphHashNode pStaDs = NULL; + tANI_U16 aid = 0; + tANI_U8 qosMode = 0; + + tANI_U8 toDs = (tdlsLinkType == TDLS_LINK_AP) + ? ANI_TXDIR_TODS :ANI_TXDIR_IBSS ; + tANI_U8 *peerMac = (reqType == TDLS_INITIATOR) + ? link_iden->RespStaAddr : link_iden->InitStaAddr; + tANI_U8 *staMac = (reqType == TDLS_INITIATOR) + ? link_iden->InitStaAddr : link_iden->RespStaAddr; + pMacHdr = (tpSirMacDataHdr3a) (pFrame); + + /* + * if TDLS frame goes through the AP link, it follows normal address + * pattern, if TDLS frame goes thorugh the direct link, then + * A1--> Peer STA addr, A2-->Self STA address, A3--> BSSID + */ + (tdlsLinkType == TDLS_LINK_AP) ? ((addr1 = (link_iden->bssid)), + (addr3 = (peerMac))) + : ((addr1 = (peerMac)), + (addr3 = (link_iden->bssid))) ; + /* + * prepare 802.11 header + */ + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = SIR_MAC_DATA_FRAME ; + + pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, + &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + qosMode = pStaDs->qosMode; + } + + pMacHdr->fc.subType = ((IS_QOS_ENABLED(psessionEntry) && + (tdlsLinkType == TDLS_LINK_AP)) || + ((tdlsLinkType == TDLS_LINK_DIRECT) && qosMode)) + ? SIR_MAC_DATA_QOS_DATA : SIR_MAC_DATA_DATA; + + /* + * TL is not setting up below fields, so we are doing it here + */ + pMacHdr->fc.toDS = toDs ; + pMacHdr->fc.powerMgmt = 0 ; + pMacHdr->fc.wep = (psessionEntry->encryptType == eSIR_ED_NONE)? 0 : 1; + + + vos_mem_copy( (tANI_U8 *) pMacHdr->addr1, + (tANI_U8 *)addr1, + sizeof( tSirMacAddr )); + vos_mem_copy( (tANI_U8 *) pMacHdr->addr2, + (tANI_U8 *) staMac, + sizeof( tSirMacAddr )); + + vos_mem_copy( (tANI_U8 *) pMacHdr->addr3, + (tANI_U8 *) (addr3), + sizeof( tSirMacAddr )); + + limLog(pMac, LOG1, + FL("Preparing TDLS frame header to %s A1:"MAC_ADDRESS_STR", A2:"MAC_ADDRESS_STR", A3:"MAC_ADDRESS_STR), + (tdlsLinkType == TDLS_LINK_AP) ? "AP" : "DIRECT", + MAC_ADDR_ARRAY(pMacHdr->addr1), + MAC_ADDR_ARRAY(pMacHdr->addr2), + MAC_ADDR_ARRAY(pMacHdr->addr3)); + + //printMacAddr(pMacHdr->bssId) ; + //printMacAddr(pMacHdr->sa) ; + //printMacAddr(pMacHdr->da) ; + + if (((tdlsLinkType == TDLS_LINK_AP) && (IS_QOS_ENABLED(psessionEntry))) || + ((tdlsLinkType == TDLS_LINK_DIRECT) && qosMode)) + { + pMacHdr->qosControl.tid = tid; + header_offset += sizeof(tSirMacDataHdr3a); + } + else + header_offset += sizeof(tSirMacMgmtHdr); + + /* + * Now form RFC1042 header + */ + vos_mem_copy((tANI_U8 *)(pFrame + header_offset), + (tANI_U8 *)eth_890d_header, sizeof(eth_890d_header)) ; + + header_offset += sizeof(eth_890d_header) ; + + /* add payload type as TDLS */ + *(pFrame + header_offset) = PAYLOAD_TYPE_TDLS ; + + return(header_offset += PAYLOAD_TYPE_TDLS_SIZE) ; +} + +/* + * TX Complete for Management frames + */ + eHalStatus limMgmtTXComplete(tpAniSirGlobal pMac, + void *pData) +{ + tANI_U32 txCompleteSuccess = 0; + tpSirTxBdStatus pTxBdStatus = NULL; + + if (!pData) + { + limLog(pMac, LOGE, FL("pData is NULL")); + return eHAL_STATUS_SUCCESS; + } + + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + pTxBdStatus = (tpSirTxBdStatus) pData; + txCompleteSuccess = pTxBdStatus->txCompleteStatus; + limLog(pMac, LOG1, FL("txCompleteSuccess %u, token %u"), + txCompleteSuccess, pTxBdStatus->txBdToken); + } + else + { + txCompleteSuccess = *((tANI_U32*) pData); + limLog(pMac, LOG1, FL("txCompleteSuccess %u"), txCompleteSuccess); + } + + if (0xff != pMac->lim.mgmtFrameSessionId) + { + limSendSmeMgmtTXCompletion(pMac, pMac->lim.mgmtFrameSessionId, + txCompleteSuccess); + pMac->lim.mgmtFrameSessionId = 0xff; + } + return eHAL_STATUS_SUCCESS; +} + +/* + * This function can be used for bacst or unicast discovery request + * We are not differentiating it here, it will all depnds on peer MAC address, + */ +tSirRetStatus limSendTdlsDisReqFrame(tpAniSirGlobal pMac, tSirMacAddr peer_mac, + tANI_U8 dialog, tpPESession psessionEntry) +{ + tDot11fTDLSDisReq tdlsDisReq ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 size = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + tANI_U32 padLen = 0; +#endif + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( (tANI_U8*)&tdlsDisReq, + sizeof( tDot11fTDLSDisReq ), 0 ); + + /* + * setup Fixed fields, + */ + tdlsDisReq.Category.category = SIR_MAC_ACTION_TDLS ; + tdlsDisReq.Action.action = SIR_MAC_TDLS_DIS_REQ ; + tdlsDisReq.DialogToken.token = dialog ; + + + size = sizeof(tSirMacAddr) ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisReq.LinkIdentifier, + peer_mac, TDLS_INITIATOR) ; + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSDisReqSize( pMac, &tdlsDisReq, &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to calculate the packed size for a discovery Request (0x%08x)."), + status); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fTDLSDisReq ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while calculating the packed size for a discovery Request (0x%08x)."), + status); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE ; + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) + Hence AP itself padding some bytes, which caused teardown packet is dropped at + receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 + */ + if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) + { + padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ; + + /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ + if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) + padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; + + nBytes += padLen; + } +#endif + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("Failed to allocate %d bytes for a TDLS Discovery Request."), + nBytes); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsDisReq), TDLS_LINK_AP, TDLS_INITIATOR, TID_AC_VI, psessionEntry) ; + +#ifdef FEATURE_WLAN_TDLS_NEGATIVE + if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_REQ) + { + tdlsDisReq.LinkIdentifier.bssid[4] = 0xde; + tdlsDisReq.LinkIdentifier.bssid[5] = 0xad; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Discovery Req"), + MAC_ADDR_ARRAY(tdlsDisReq.LinkIdentifier.bssid)); + } +#endif + status = dot11fPackTDLSDisReq( pMac, &tdlsDisReq, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to pack a TDLS discovery req (0x%08x)."), + status); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, FL("There were warnings while packing TDLS Discovery Request (0x%08x)."), + status); + } + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + if (padLen != 0) + { + /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ + tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload; + /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ + padVendorSpecific[0] = 221; + padVendorSpecific[1] = padLen - 2; + padVendorSpecific[2] = 0x00; + padVendorSpecific[3] = 0xA0; + padVendorSpecific[4] = 0xC6; + + limLog(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"), padLen); + + /* padding zero if more than 5 bytes are required */ + if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) + vos_mem_set( pFrame + header_offset + nPayload + MIN_VENDOR_SPECIFIC_IE_SIZE, + padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0); + } +#endif + + limLog(pMac, LOG1, + FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR), + SIR_MAC_TDLS_DIS_REQ, + limTraceTdlsActionString(SIR_MAC_TDLS_DIS_REQ), + MAC_ADDR_ARRAY(peer_mac)); + + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME | + HAL_USE_PEER_STA_REQUESTED_MASK, + pMac->lim.txBdToken++); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog(pMac, LOGE, FL("could not send TDLS Discovery Request frame")); + return eSIR_FAILURE; + } + pMac->lim.mgmtFrameSessionId = psessionEntry->smeSessionId; + + return eSIR_SUCCESS; + +} + +/* + * This static function is consistent with any kind of TDLS management + * frames we are sending. Currently it is being used by limSendTdlsDisRspFrame, + * limSendTdlsLinkSetupReqFrame and limSendTdlsSetupRspFrame + */ +static void PopulateDot11fTdlsHtVhtCap(tpAniSirGlobal pMac, uint32 selfDot11Mode, + tDot11fIEHTCaps *htCap, tDot11fIEVHTCaps *vhtCap, + tpPESession psessionEntry) +{ + if (IS_DOT11_MODE_HT(selfDot11Mode)) + { + /* Include HT Capability IE */ + PopulateDot11fHTCaps( pMac, NULL, htCap ); + /* Advertize ht capability and max supported channel + * bandwidth when populating HT IE in TDLS Setup Request/ + * Setup Response/Setup Confirmation frames. + * 11.21.6.2 Setting up a 40 MHz direct link: A 40 MHz off-channel + * direct link may be started if both TDLS peer STAs indicated + * 40 MHz support in the Supported Channel Width Set field of the + * HT Capabilities element (which is included in the TDLS Setup Request + * frame and the TDLS Setup Response frame). Switching to a 40 MHz + * off-channel direct link is achieved by including the following + * information in the TDLS Channel Switch Request + * 11.21.1 General: The channel width of the TDLS direct link on the + * base channel shall not exceed the channel width of the BSS to which + * the TDLS peer STAs are associated.*/ + htCap->present = 1; + htCap->supportedChannelWidthSet = 1; // hardcode it to max + } + else + { + htCap->present = 0; + } + limLog(pMac, LOG1, FL("HT present = %hu, Chan Width = %hu"), + htCap->present, htCap->supportedChannelWidthSet); +#ifdef WLAN_FEATURE_11AC + if (IS_DOT11_MODE_VHT(selfDot11Mode) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* Include VHT Capability IE */ + PopulateDot11fVHTCaps( pMac, vhtCap, + psessionEntry->currentOperChannel, eSIR_FALSE ); + } + else + { + vhtCap->present = 0; + } + limLog(pMac, LOG1, FL("VHT present = %hu"), + vhtCap->present); +#endif +} + +/* + * Send TDLS discovery response frame on direct link. + */ + +static tSirRetStatus limSendTdlsDisRspFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U8 dialog, + tpPESession psessionEntry, tANI_U8 *addIe, + tANI_U16 addIeLen) +{ + tDot11fTDLSDisRsp tdlsDisRsp ; + tANI_U16 caps = 0 ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + uint32 selfDot11Mode; +// Placeholder to support different channel bonding mode of TDLS than AP. +// Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP +// To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE +// As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) +// uint32 tdlsChannelBondingMode; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&tdlsDisRsp, + sizeof( tDot11fTDLSDisRsp ), 0 ); + + /* + * setup Fixed fields, + */ + tdlsDisRsp.Category.category = SIR_MAC_ACTION_PUBLIC_USAGE; + tdlsDisRsp.Action.action = SIR_MAC_TDLS_DIS_RSP ; + tdlsDisRsp.DialogToken.token = dialog ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsDisRsp.LinkIdentifier, + peerMac, TDLS_RESPONDER) ; + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) + { + /* + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve Capabilities value")); + } + swapBitField16(caps, ( tANI_U16* )&tdlsDisRsp.Capabilities ); + + /* populate supported rate and ext supported rate IE */ + if (eSIR_FAILURE == PopulateDot11fRatesTdls(pMac, &tdlsDisRsp.SuppRates, + &tdlsDisRsp.ExtSuppRates, + psessionEntry->currentOperChannel)) + limLog(pMac, LOGE, FL("could not populate supported data rates")); + + /* Populate extended capability IE */ + PopulateDot11fTdlsExtCapability( pMac, &tdlsDisRsp.ExtCap ); + + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode); + + /* Populate HT/VHT Capabilities */ + PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsDisRsp.HTCaps, + &tdlsDisRsp.VHTCaps, psessionEntry ); + + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled ) + PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry, + &tdlsDisRsp.SuppChannels, + &tdlsDisRsp.SuppOperatingClasses); + + if (TRUE == pMac->lim.EnableTdls2040BSSCoexIE) + { + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled && + ( pMac->roam.configParam.bandCapability != eCSR_BAND_24) ) + { + tdlsDisRsp.HT2040BSSCoexistence.present = 1; + tdlsDisRsp.HT2040BSSCoexistence.infoRequest = 1; + } + } + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSDisRspSize( pMac, &tdlsDisRsp, &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to calculate the packed size for a Discovery Response (0x%08x)."), + status); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while calculating the packed size for a Discovery Response (0x%08x)."), + status); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + addIeLen; + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("Failed to allocate %d bytes for a TDLS Discovery Response."), + nBytes); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * response frame + */ + + /* Make public Action Frame */ + +#if 0 + limPreparesActionFrameHdr(pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + LINK_IDEN_ADDR_OFFSET(tdlsDisRsp)) ; +#endif + limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peerMac, psessionEntry->selfMacAddr); + + { + tpSirMacMgmtHdr pMacHdr; + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + pMacHdr->fc.toDS = ANI_TXDIR_IBSS; + pMacHdr->fc.powerMgmt = 0 ; + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + } + +#ifdef FEATURE_WLAN_TDLS_NEGATIVE + if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_DSCV_RSP) + { + tdlsDisRsp.LinkIdentifier.bssid[4] = 0xde; + tdlsDisRsp.LinkIdentifier.bssid[5] = 0xad; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Discovery Rsp"), + MAC_ADDR_ARRAY(tdlsDisRsp.LinkIdentifier.bssid)); + } +#endif + status = dot11fPackTDLSDisRsp( pMac, &tdlsDisRsp, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, + FL("Failed to pack a TDLS Discovery Response (0x%08x)."), + status); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, + FL("There were warnings while packing TDLS Discovery Request (0x%08x)."), + status); + } + +#if 0 + if(pMac->hal.pCBackFnTxComp == NULL) + { + pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsDisRspTxComplete; + + if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer)) + { + status = eHAL_STATUS_FAILURE; + return status; + + } + } +#endif + if (0 != addIeLen) + { + limLog(pMac, LOG1, FL("Copy Additional Ie Len = %d"), addIeLen); + vos_mem_copy(pFrame + sizeof(tSirMacMgmtHdr) + nPayload, addIe, + addIeLen); + } + limLog(pMac, LOG1, + FL("[TDLS] action %d (%s) -DIRECT-> OTA peer="MAC_ADDRESS_STR), + SIR_MAC_TDLS_DIS_RSP, + limTraceTdlsActionString(SIR_MAC_TDLS_DIS_RSP), + MAC_ADDR_ARRAY(peerMac)); + + /* + * Transmit Discovery response and watch if this is delivered to + * peer STA. + */ + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_IBSS, + 0, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_SELF_STA_REQUESTED_MASK, + pMac->lim.txBdToken++); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog(pMac, LOGE, FL("could not send TDLS Discovery Response frame!")); + return eSIR_FAILURE; + } + pMac->lim.mgmtFrameSessionId = psessionEntry->smeSessionId; + + return eSIR_SUCCESS; + +} + +/* + * This static function is currently used by limSendTdlsLinkSetupReqFrame and + * limSendTdlsSetupRspFrame to populate the AID if device is 11ac capable. + */ +static void PopulateDotfTdlsVhtAID(tpAniSirGlobal pMac, uint32 selfDot11Mode, + tSirMacAddr peerMac, tDot11fIEAID *Aid, + tpPESession psessionEntry) +{ + if (((psessionEntry->currentOperChannel <= SIR_11B_CHANNEL_END) && + pMac->roam.configParam.enableVhtFor24GHz) || + (psessionEntry->currentOperChannel >= SIR_11B_CHANNEL_END)) + { + if (IS_DOT11_MODE_VHT(selfDot11Mode) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + + tANI_U16 aid; + tpDphHashNode pStaDs; + + pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, &psessionEntry->dph.dphHashTable); + if (NULL != pStaDs) + { + Aid->present = 1; + Aid->assocId = aid | LIM_AID_MASK; // set bit 14 and 15 1's + } + else + { + Aid->present = 0; + limLog(pMac, LOGE, FL("pStaDs is NULL for " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(peerMac)); + } + } + } + else + { + Aid->present = 0; + limLog(pMac, LOGW, FL("Vht not enable from ini for 2.4GHz.")); + } +} + +/* + * TDLS setup Request frame on AP link + */ + +tSirRetStatus limSendTdlsLinkSetupReqFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry, + tANI_U8 *addIe, tANI_U16 addIeLen) +{ + tDot11fTDLSSetupReq tdlsSetupReq ; + tANI_U16 caps = 0 ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + uint32 selfDot11Mode; + tpSirMacCapabilityInfo pCapInfo; +// Placeholder to support different channel bonding mode of TDLS than AP. +// Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP +// To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE +// As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) +// uint32 tdlsChannelBondingMode; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set(( tANI_U8* )&tdlsSetupReq, sizeof( tDot11fTDLSSetupReq ), 0); + tdlsSetupReq.Category.category = SIR_MAC_ACTION_TDLS ; + tdlsSetupReq.Action.action = SIR_MAC_TDLS_SETUP_REQ ; + tdlsSetupReq.DialogToken.token = dialog ; + + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupReq.LinkIdentifier, + peerMac, TDLS_INITIATOR) ; + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) + { + /* + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve Capabilities value")); + } + + pCapInfo = (tpSirMacCapabilityInfo) ∩︀ + /* Export QOS capability */ + pCapInfo->qos = 1; + + swapBitField16(caps, ( tANI_U16* )&tdlsSetupReq.Capabilities ); + + limLog(pMac, LOG1, FL("Sending operating channel %d and dotl11mode %d\n"), + psessionEntry->currentOperChannel, + psessionEntry->dot11mode); + + /* populate supported rate and ext supported rate IE */ + PopulateDot11fRatesTdls(pMac, &tdlsSetupReq.SuppRates, + &tdlsSetupReq.ExtSuppRates, + psessionEntry->currentOperChannel); + + /* Populate extended capability IE */ + PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupReq.ExtCap ); + + if ( 1 == pMac->lim.gLimTDLSWmmMode ) + { + tANI_U32 val = 0; + + /* include WMM IE */ + tdlsSetupReq.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1; + tdlsSetupReq.WMMInfoStation.acvo_uapsd = + (pMac->lim.gLimTDLSUapsdMask & 0x01); + tdlsSetupReq.WMMInfoStation.acvi_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupReq.WMMInfoStation.acbk_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupReq.WMMInfoStation.acbe_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + limLog(pMac, LOGE, FL("could not retrieve Max SP Length")); + + tdlsSetupReq.WMMInfoStation.max_sp_length = (tANI_U8)val; + tdlsSetupReq.WMMInfoStation.present = 1; + } + else + { + /* + * TODO: we need to see if we have to support conditions where we have + * EDCA parameter info element is needed a) if we need different QOS + * parameters for off channel operations or QOS is not supported on + * AP link and we wanted to QOS on direct link. + */ + /* Populate QOS info, needed for Peer U-APSD session */ + /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and + TDLS doesn't want to depend on AP's capability */ + limLog(pMac, LOG1, FL("populate QOS IE in Setup Request Frame")); + tdlsSetupReq.QOSCapsStation.present = 1; + tdlsSetupReq.QOSCapsStation.max_sp_length = 0; + tdlsSetupReq.QOSCapsStation.qack = 0; + tdlsSetupReq.QOSCapsStation.acbe_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + tdlsSetupReq.QOSCapsStation.acbk_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupReq.QOSCapsStation.acvi_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupReq.QOSCapsStation.acvo_uapsd = (pMac->lim.gLimTDLSUapsdMask & 0x01); + } + + /* + * we will always try to init TDLS link with 11n capabilities + * let TDLS setup response to come, and we will set our caps based + * of peer caps + */ + + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode); + + /* Populate HT/VHT Capabilities */ + PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsSetupReq.HTCaps, + &tdlsSetupReq.VHTCaps, psessionEntry ); + + /* Populate AID */ + PopulateDotfTdlsVhtAID( pMac, selfDot11Mode, peerMac, + &tdlsSetupReq.AID, psessionEntry ); + + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled ) + PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry, + &tdlsSetupReq.SuppChannels, + &tdlsSetupReq.SuppOperatingClasses); + + if (TRUE == pMac->lim.EnableTdls2040BSSCoexIE) + { + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled && + ( pMac->roam.configParam.bandCapability != eCSR_BAND_24)) + { + tdlsSetupReq.HT2040BSSCoexistence.present = 1; + tdlsSetupReq.HT2040BSSCoexistence.infoRequest = 1; + } + } + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSSetupReqSize( pMac, &tdlsSetupReq, + &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to calculate the packed size for a Setup Request (0x%08x)."), + status); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while calculating the packed size for a Setup Request (0x%08x)."), + status); + } + + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("Failed to allocate %d bytes for a TDLS Setup Request."), + nBytes); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsSetupReq), + TDLS_LINK_AP, TDLS_INITIATOR, + TID_AC_VI, psessionEntry) ; + +#ifdef FEATURE_WLAN_TDLS_NEGATIVE + if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_REQ) + { + tdlsSetupReq.LinkIdentifier.bssid[4] = 0xde; + tdlsSetupReq.LinkIdentifier.bssid[5] = 0xad; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Setup Req"), + MAC_ADDR_ARRAY(tdlsSetupReq.LinkIdentifier.bssid)); + } +#endif + limLog( pMac, LOGW, FL("SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"), + tdlsSetupReq.VHTCaps.supportedChannelWidthSet, + tdlsSetupReq.VHTCaps.rxMCSMap, + tdlsSetupReq.VHTCaps.txMCSMap, + tdlsSetupReq.VHTCaps.txSupDataRate); + + status = dot11fPackTDLSSetupReq( pMac, &tdlsSetupReq, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to pack a TDLS Setup Request (0x%08x)."), + status); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while packing TDLS Setup Request (0x%08x)."), + status); + } + + //Copy the additional IE. + //TODO : addIe is added at the end of the frame. This means it doesnt + //follow the order. This should be ok, but we should consider changing this + //if there is any IOT issue. + if( addIeLen != 0 ) + { + limLog(pMac, LOG1, FL("Copy Additional Ie Len = %d"), + addIeLen); + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + + limLog(pMac, LOG1, FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR), + SIR_MAC_TDLS_SETUP_REQ, + limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_REQ), + MAC_ADDR_ARRAY(peerMac)); + + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME | + HAL_USE_PEER_STA_REQUESTED_MASK, + pMac->lim.txBdToken++); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog(pMac, LOGE, FL("could not send TDLS Setup Request frame!")); + return eSIR_FAILURE; + } + pMac->lim.mgmtFrameSessionId = psessionEntry->smeSessionId; + + return eSIR_SUCCESS; + +} +/* + * Send TDLS Teardown frame on Direct link or AP link, depends on reason code. + */ + +tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry, + tANI_U8 *addIe, tANI_U16 addIeLen) +{ + tDot11fTDLSTeardown teardown ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + tANI_U32 padLen = 0; +#endif + tpDphHashNode pStaDs = NULL; + tANI_U16 aid = 0; + tANI_U8 qosMode = 0; + tANI_U8 tdlsLinkType = 0; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&teardown, sizeof( tDot11fTDLSTeardown ), 0 ); + teardown.Category.category = SIR_MAC_ACTION_TDLS ; + teardown.Action.action = SIR_MAC_TDLS_TEARDOWN ; + teardown.Reason.code = reason ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &teardown.LinkIdentifier, + peerMac, (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR) ; + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSTeardownSize( pMac, &teardown, &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to calculate the packed size for Teardown frame (0x%08x)."), + status); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while calculating the packed size for Teardown frame (0x%08x)."), + status); + } + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + pStaDs = dphLookupHashEntry(pMac, peerMac, &aid, + &psessionEntry->dph.dphHashTable); + if (pStaDs) + { + qosMode = pStaDs->qosMode; + } + tdlsLinkType = (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) + ? TDLS_LINK_AP : TDLS_LINK_DIRECT; + nBytes = nPayload + (((IS_QOS_ENABLED(psessionEntry) && + (tdlsLinkType == TDLS_LINK_AP)) || + ((tdlsLinkType == TDLS_LINK_DIRECT) && qosMode)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) + Hence AP itself padding some bytes, which caused teardown packet is dropped at + receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 + */ + if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) + { + padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ; + + /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ + if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) + padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; + + nBytes += padLen; + } +#endif + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("Failed to allocate %d bytes for a TDLS Teardown Frame."), + nBytes); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + limLog(pMac, LOGE, FL("Reason of TDLS Teardown: %d"), reason); + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(teardown), + (reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) + ? TDLS_LINK_AP : TDLS_LINK_DIRECT, + (responder == TRUE) ? TDLS_RESPONDER : TDLS_INITIATOR, + TID_AC_VI, psessionEntry) ; + + status = dot11fPackTDLSTeardown( pMac, &teardown, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TDLS Teardown req (0x%08x)."), + status); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, FL("There were warnings while packing TDLS Teardown frame (0x%08x)."), + status); + } +#if 0 + if(pMac->hal.pCBackFnTxComp == NULL) + { + pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsTeardownTxComplete; + if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer)) + { + status = eHAL_STATUS_FAILURE; + return status; + + } + } + else + { + VOS_ASSERT(0) ; + return status ; + } +#endif + + if( addIeLen != 0 ) + { + limLog(pMac, LOG1, FL("Copy Additional Ie Len = %d"), addIeLen); + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + if (padLen != 0) + { + /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ + tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload + addIeLen; + /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ + padVendorSpecific[0] = 221; + padVendorSpecific[1] = padLen - 2; + padVendorSpecific[2] = 0x00; + padVendorSpecific[3] = 0xA0; + padVendorSpecific[4] = 0xC6; + + limLog(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"), padLen); + + /* padding zero if more than 5 bytes are required */ + if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) + vos_mem_set( pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, + padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0); + } +#endif + limLog(pMac, LOG1, FL("[TDLS] action %d (%s) -%s-> OTA peer="MAC_ADDRESS_STR), + SIR_MAC_TDLS_TEARDOWN, + limTraceTdlsActionString(SIR_MAC_TDLS_TEARDOWN), + ((reason == eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE) ? + "AP": "DIRECT"), + MAC_ADDR_ARRAY(peerMac)); + + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME | + HAL_USE_PEER_STA_REQUESTED_MASK, + pMac->lim.txBdToken++); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog(pMac, LOGE, FL("could not send TDLS Teardown frame")); + return eSIR_FAILURE; + + } + pMac->lim.mgmtFrameSessionId = psessionEntry->smeSessionId; + return eSIR_SUCCESS; + +} + +/* + * Send Setup RSP frame on AP link. + */ +static tSirRetStatus limSendTdlsSetupRspFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U8 dialog, tpPESession psessionEntry, + etdlsLinkSetupStatus setupStatus, tANI_U8 *addIe, tANI_U16 addIeLen ) +{ + tDot11fTDLSSetupRsp tdlsSetupRsp ; + tANI_U32 status = 0 ; + tANI_U16 caps = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + uint32 selfDot11Mode; + tpSirMacCapabilityInfo pCapInfo; +// Placeholder to support different channel bonding mode of TDLS than AP. +// Today, WNI_CFG_CHANNEL_BONDING_MODE will be overwritten when connecting to AP +// To support this feature, we need to introduce WNI_CFG_TDLS_CHANNEL_BONDING_MODE +// As of now, we hardcoded to max channel bonding of dot11Mode (i.e HT80 for 11ac/HT40 for 11n) +// uint32 tdlsChannelBondingMode; + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&tdlsSetupRsp, sizeof( tDot11fTDLSSetupRsp ),0 ); + + /* + * setup Fixed fields, + */ + tdlsSetupRsp.Category.category = SIR_MAC_ACTION_TDLS; + tdlsSetupRsp.Action.action = SIR_MAC_TDLS_SETUP_RSP ; + tdlsSetupRsp.DialogToken.token = dialog; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupRsp.LinkIdentifier, + peerMac, TDLS_RESPONDER) ; + + if (cfgGetCapabilityInfo(pMac, &caps, psessionEntry) != eSIR_SUCCESS) + { + /* + * Could not get Capabilities value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve Capabilities value")); + } + + pCapInfo = (tpSirMacCapabilityInfo) ∩︀ + /* Export QoS capability */ + pCapInfo->qos = 1; + + swapBitField16(caps, ( tANI_U16* )&tdlsSetupRsp.Capabilities ); + + /* populate supported rate and ext supported rate IE */ + PopulateDot11fRatesTdls(pMac, &tdlsSetupRsp.SuppRates, + &tdlsSetupRsp.ExtSuppRates, + psessionEntry->currentOperChannel); + + /* Populate extended capability IE */ + PopulateDot11fTdlsExtCapability( pMac, &tdlsSetupRsp.ExtCap ); + + if ( 1 == pMac->lim.gLimTDLSWmmMode ) + { + tANI_U32 val = 0; + + /* include WMM IE */ + tdlsSetupRsp.WMMInfoStation.version = SIR_MAC_OUI_VERSION_1; + tdlsSetupRsp.WMMInfoStation.acvo_uapsd = + (pMac->lim.gLimTDLSUapsdMask & 0x01); + tdlsSetupRsp.WMMInfoStation.acvi_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupRsp.WMMInfoStation.acbk_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupRsp.WMMInfoStation.acbe_uapsd = + ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + limLog(pMac, LOGE, FL("could not retrieve Max SP Length")); + + tdlsSetupRsp.WMMInfoStation.max_sp_length = (tANI_U8)val; + tdlsSetupRsp.WMMInfoStation.present = 1; + } + else + { + /* + * TODO: we need to see if we have to support conditions where we have + * EDCA parameter info element is needed a) if we need different QOS + * parameters for off channel operations or QOS is not supported on + * AP link and we wanted to QOS on direct link. + */ + /* Populate QOS info, needed for Peer U-APSD session */ + /* TODO: Now hardcoded, because PopulateDot11fQOSCapsStation() depends on AP's capability, and + TDLS doesn't want to depend on AP's capability */ + limLog(pMac, LOG1, FL("populate QOS IE in Setup Response frame")); + tdlsSetupRsp.QOSCapsStation.present = 1; + tdlsSetupRsp.QOSCapsStation.max_sp_length = 0; + tdlsSetupRsp.QOSCapsStation.qack = 0; + tdlsSetupRsp.QOSCapsStation.acbe_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x08) >> 3); + tdlsSetupRsp.QOSCapsStation.acbk_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x04) >> 2); + tdlsSetupRsp.QOSCapsStation.acvi_uapsd = ((pMac->lim.gLimTDLSUapsdMask & 0x02) >> 1); + tdlsSetupRsp.QOSCapsStation.acvo_uapsd = (pMac->lim.gLimTDLSUapsdMask & 0x01); + } + + wlan_cfgGetInt(pMac,WNI_CFG_DOT11_MODE,&selfDot11Mode); + + /* Populate HT/VHT Capabilities */ + PopulateDot11fTdlsHtVhtCap( pMac, selfDot11Mode, &tdlsSetupRsp.HTCaps, + &tdlsSetupRsp.VHTCaps, psessionEntry ); + + /* Populate AID */ + PopulateDotfTdlsVhtAID( pMac, selfDot11Mode, peerMac, + &tdlsSetupRsp.AID, psessionEntry ); + + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled ) + PopulateDot11fTdlsOffchannelParams( pMac, psessionEntry, + &tdlsSetupRsp.SuppChannels, + &tdlsSetupRsp.SuppOperatingClasses); + + tdlsSetupRsp.Status.status = setupStatus ; + + if (TRUE == pMac->lim.EnableTdls2040BSSCoexIE) + { + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled && + ( pMac->roam.configParam.bandCapability != eCSR_BAND_24)) + { + tdlsSetupRsp.HT2040BSSCoexistence.present = 1; + tdlsSetupRsp.HT2040BSSCoexistence.infoRequest = 1; + } + } + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSSetupRspSize( pMac, &tdlsSetupRsp, + &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to calculate the packed size for a Setup Response (0x%08x)."), + status); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while calculating the packed size for Setup Response (0x%08x)."), + status); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("Failed to allocate %d bytes for a TDLS Setup Response."), + nBytes); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsSetupRsp), + TDLS_LINK_AP, TDLS_RESPONDER, + TID_AC_VI, psessionEntry) ; + +#ifdef FEATURE_WLAN_TDLS_NEGATIVE + if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_WRONG_BSSID_IN_SETUP_RSP) + { + tdlsSetupRsp.LinkIdentifier.bssid[4] = 0xde; + tdlsSetupRsp.LinkIdentifier.bssid[5] = 0xad; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("TDLS negative running: wrong BSSID " MAC_ADDRESS_STR " in TDLS Setup Rsp"), + MAC_ADDR_ARRAY(tdlsSetupRsp.LinkIdentifier.bssid)); + } +#endif + limLog(pMac, LOG1, + FL("SupportedChnlWidth %x rxMCSMap %x rxMCSMap %x txSupDataRate %x"), + tdlsSetupRsp.VHTCaps.supportedChannelWidthSet, + tdlsSetupRsp.VHTCaps.rxMCSMap, + tdlsSetupRsp.VHTCaps.txMCSMap, + tdlsSetupRsp.VHTCaps.txSupDataRate); + status = dot11fPackTDLSSetupRsp( pMac, &tdlsSetupRsp, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to pack a TDLS Setup Response (0x%08x)."), + status); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while packing TDLS Setup Response (0x%08x)."), + status); + } + + //Copy the additional IE. + //TODO : addIe is added at the end of the frame. This means it doesnt + //follow the order. This should be ok, but we should consider changing this + //if there is any IOT issue. + if( addIeLen != 0 ) + { + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + + limLog(pMac, LOG1, + FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR), + SIR_MAC_TDLS_SETUP_RSP, + limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_RSP), + MAC_ADDR_ARRAY(peerMac)); + + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + //ANI_TXDIR_IBSS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME | + HAL_USE_PEER_STA_REQUESTED_MASK, + pMac->lim.txBdToken++); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog(pMac, LOGE, FL("could not send TDLS Setup Response")); + return eSIR_FAILURE; + } + pMac->lim.mgmtFrameSessionId = psessionEntry->smeSessionId; + + return eSIR_SUCCESS; + +} + +/* + * Send TDLS setup CNF frame on AP link + */ + +tSirRetStatus limSendTdlsLinkSetupCnfFrame(tpAniSirGlobal pMac, tSirMacAddr peerMac, + tANI_U8 dialog, tANI_U32 peerCapability, tpPESession psessionEntry, tANI_U8* addIe, tANI_U16 addIeLen) +{ + tDot11fTDLSSetupCnf tdlsSetupCnf ; + tANI_U32 status = 0 ; + tANI_U32 nPayload = 0 ; + tANI_U32 nBytes = 0 ; + tANI_U32 header_offset = 0 ; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + tANI_U32 padLen = 0; +#endif + + /* + * The scheme here is to fill out a 'tDot11fProbeRequest' structure + * and then hand it off to 'dot11fPackProbeRequest' (for + * serialization). We start by zero-initializing the structure: + */ + vos_mem_set( ( tANI_U8* )&tdlsSetupCnf, sizeof( tDot11fTDLSSetupCnf ), 0 ); + + /* + * setup Fixed fields, + */ + tdlsSetupCnf.Category.category = SIR_MAC_ACTION_TDLS; + tdlsSetupCnf.Action.action = SIR_MAC_TDLS_SETUP_CNF ; + tdlsSetupCnf.DialogToken.token = dialog ; + + PopulateDot11fLinkIden( pMac, psessionEntry, &tdlsSetupCnf.LinkIdentifier, + peerMac, TDLS_INITIATOR) ; + + /* + * TODO: we need to see if we have to support conditions where we have + * EDCA parameter info element is needed a) if we need different QOS + * parameters for off channel operations or QOS is not supported on + * AP link and we wanted to QOS on direct link. + */ + + /* Check self and peer WMM capable */ + if ((1 == pMac->lim.gLimTDLSWmmMode) && (CHECK_BIT(peerCapability, TDLS_PEER_WMM_CAP))) + { + limLog(pMac, LOG1, FL("populate WMM praram in Setup Confirm")); + PopulateDot11fWMMParams(pMac, &tdlsSetupCnf.WMMParams, psessionEntry); + } + + /* Check peer is VHT capable*/ + if (CHECK_BIT(peerCapability, TDLS_PEER_VHT_CAP)) + { + PopulateDot11fVHTOperation( pMac, &tdlsSetupCnf.VHTOperation, + psessionEntry->currentOperChannel); + PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry ); + } + else if (CHECK_BIT(peerCapability, TDLS_PEER_HT_CAP)) /* Check peer is HT capable */ + { + PopulateDot11fHTInfo( pMac, &tdlsSetupCnf.HTInfo, psessionEntry ); + } + + if (TRUE == pMac->lim.EnableTdls2040BSSCoexIE) + { + if ( 1 == pMac->lim.gLimTDLSOffChannelEnabled && + ( pMac->roam.configParam.bandCapability != eCSR_BAND_24)) + { + tdlsSetupCnf.HT2040BSSCoexistence.present = 1; + tdlsSetupCnf.HT2040BSSCoexistence.infoRequest = 1; + } + } + + /* + * now we pack it. First, how much space are we going to need? + */ + status = dot11fGetPackedTDLSSetupCnfSize( pMac, &tdlsSetupCnf, + &nPayload); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to calculate the packed size for Setup Confirm (0x%08x)."), + status); + /* We'll fall back on the worst case scenario: */ + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while calculating the packed size for Setup Confirm (0x%08x)."), + status); + } + + /* + * This frame is going out from PE as data frames with special ethertype + * 89-0d. + * 8 bytes of RFC 1042 header + */ + + + nBytes = nPayload + ((IS_QOS_ENABLED(psessionEntry)) + ? sizeof(tSirMacDataHdr3a) : sizeof(tSirMacMgmtHdr)) + + sizeof( eth_890d_header ) + + PAYLOAD_TYPE_TDLS_SIZE + + addIeLen; + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + /* IOT issue with some AP : some AP doesn't like the data packet size < minimum 802.3 frame length (64) + Hence AP itself padding some bytes, which caused teardown packet is dropped at + receiver side. To avoid such IOT issue, we added some extra bytes to meet data frame size >= 64 + */ + if (nPayload + PAYLOAD_TYPE_TDLS_SIZE < MIN_IEEE_8023_SIZE) + { + padLen = MIN_IEEE_8023_SIZE - (nPayload + PAYLOAD_TYPE_TDLS_SIZE ) ; + + /* if padLen is less than minimum vendorSpecific (5), pad up to 5 */ + if (padLen < MIN_VENDOR_SPECIFIC_IE_SIZE) + padLen = MIN_VENDOR_SPECIFIC_IE_SIZE; + + nBytes += padLen; + } +#endif + + + /* Ok-- try to allocate memory from MGMT PKT pool */ + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("Failed to allocate %d bytes for a TDLS Setup Confirm."), + nBytes); + return eSIR_MEM_ALLOC_FAILED; + } + + /* zero out the memory */ + vos_mem_set( pFrame, nBytes, 0 ); + + /* + * IE formation, memory allocation is completed, Now form TDLS discovery + * request frame + */ + + /* fill out the buffer descriptor */ + + header_offset = limPrepareTdlsFrameHeader(pMac, pFrame, + LINK_IDEN_ADDR_OFFSET(tdlsSetupCnf), TDLS_LINK_AP, TDLS_INITIATOR, + TID_AC_VI, psessionEntry) ; + +#ifdef FEATURE_WLAN_TDLS_NEGATIVE + if(pMac->lim.gLimTdlsNegativeBehavior & LIM_TDLS_NEGATIVE_STATUS_37_IN_SETUP_CNF) { + tdlsSetupCnf.StatusCode.statusCode = 37; + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + ("TDLS negative running: StatusCode = 37 in TDLS Setup Cnf")); + } +#endif + status = dot11fPackTDLSSetupCnf( pMac, &tdlsSetupCnf, pFrame + + header_offset, nPayload, &nPayload ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, + FL("Failed to pack a TDLS Setup Confirm (0x%08x)."), + status); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog(pMac, LOGW, + FL("There were warnings while packing TDLS Setup Confirm (0x%08x)."), + status); + } +#if 0 + if(pMac->hal.pCBackFnTxComp == NULL) + { + pMac->hal.pCBackFnTxComp = (tpCBackFnTxComp)limTdlsSetupCnfTxComplete; + if(TX_SUCCESS != tx_timer_activate(&pMac->hal.txCompTimer)) + { + status = eHAL_STATUS_FAILURE; + return status; + + } + } + else + { + VOS_ASSERT(0) ; + return status ; + } +#endif + //Copy the additional IE. + //TODO : addIe is added at the end of the frame. This means it doesnt + //follow the order. This should be ok, but we should consider changing this + //if there is any IOT issue. + if( addIeLen != 0 ) + { + vos_mem_copy( pFrame + header_offset + nPayload, addIe, addIeLen ); + } + +#ifndef NO_PAD_TDLS_MIN_8023_SIZE + if (padLen != 0) + { + /* QCOM VENDOR OUI = { 0x00, 0xA0, 0xC6, type = 0x0000 }; */ + tANI_U8 *padVendorSpecific = pFrame + header_offset + nPayload + addIeLen; + /* make QCOM_VENDOR_OUI, and type = 0x0000, and all the payload to be zero */ + padVendorSpecific[0] = 221; + padVendorSpecific[1] = padLen - 2; + padVendorSpecific[2] = 0x00; + padVendorSpecific[3] = 0xA0; + padVendorSpecific[4] = 0xC6; + + limLog(pMac, LOG1, FL("Padding Vendor Specific Ie Len = %d"), padLen); + + /* padding zero if more than 5 bytes are required */ + if (padLen > MIN_VENDOR_SPECIFIC_IE_SIZE) + vos_mem_set( pFrame + header_offset + nPayload + addIeLen + MIN_VENDOR_SPECIFIC_IE_SIZE, + padLen - MIN_VENDOR_SPECIFIC_IE_SIZE, 0); + } +#endif + + + limLog(pMac, LOG1, + FL("[TDLS] action %d (%s) -AP-> OTA peer="MAC_ADDRESS_STR), + SIR_MAC_TDLS_SETUP_CNF, + limTraceTdlsActionString(SIR_MAC_TDLS_SETUP_CNF), + MAC_ADDR_ARRAY(peerMac)); + + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_DATA, + ANI_TXDIR_TODS, + TID_AC_VI, + limTxComplete, pFrame, + limMgmtTXComplete, + HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME | + HAL_USE_PEER_STA_REQUESTED_MASK, + pMac->lim.txBdToken++); + + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + pMac->lim.mgmtFrameSessionId = 0xff; + limLog(pMac, LOGE, FL("could not send TDLS Setup Confirm frame")); + return eSIR_FAILURE; + + } + pMac->lim.mgmtFrameSessionId = psessionEntry->smeSessionId; + + return eSIR_SUCCESS; +} + +/* This Function is similar to PopulateDot11fHTCaps, except that the HT Capabilities + * are considered from the AddStaReq rather from the cfg.dat as in PopulateDot11fHTCaps + */ +static tSirRetStatus limTdlsPopulateDot11fHTCaps(tpAniSirGlobal pMac, tpPESession psessionEntry, + tSirTdlsAddStaReq *pTdlsAddStaReq, tDot11fIEHTCaps *pDot11f) +{ + tANI_U32 nCfgValue; + tANI_U8 nCfgValue8; + tSirMacHTParametersInfo *pHTParametersInfo; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + tSirMacExtendedHTCapabilityInfo extHtCapInfo; + } uHTCapabilityInfo; + + tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo; + tSirMacASCapabilityInfo *pASCapabilityInfo; + + nCfgValue = pTdlsAddStaReq->htCap.capInfo; + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap; + pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave; + pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField; + pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz; + pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz; + pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC; + pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC; + pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA; + pDot11f->maximalAMSDUsize = uHTCapabilityInfo.htCapInfo.maximalAMSDUsize; + pDot11f->dsssCckMode40MHz = uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz; + pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp; + pDot11f->stbcControlFrame = uHTCapabilityInfo.htCapInfo.stbcControlFrame; + pDot11f->lsigTXOPProtection = uHTCapabilityInfo.htCapInfo.lsigTXOPProtection; + + // All sessionized entries will need the check below + if (psessionEntry == NULL) // Only in case of NO session + { + pDot11f->supportedChannelWidthSet = uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet; + } + else + { + pDot11f->supportedChannelWidthSet = psessionEntry->htSupportedChannelWidthSet; + } + + /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is + eHT_CHANNEL_WIDTH_20MHZ */ + if(pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) + { + pDot11f->shortGI40MHz = 0; + } + + limLog(pMac, LOG1, + FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d, shortGI20:%d, shortGI40: %d, dsssCck: %d"), + pDot11f->supportedChannelWidthSet, + pDot11f->mimoPowerSave, + pDot11f->greenField, + pDot11f->shortGI20MHz, + pDot11f->shortGI40MHz, + pDot11f->dsssCckMode40MHz); + + nCfgValue = pTdlsAddStaReq->htCap.ampduParamsInfo; + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + pHTParametersInfo = ( tSirMacHTParametersInfo* ) &nCfgValue8; + + pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor; + pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; + pDot11f->reserved1 = pHTParametersInfo->reserved; + + limLog(pMac, LOG1, FL("AMPDU Param: %x"), nCfgValue); + + vos_mem_copy( pDot11f->supportedMCSSet, pTdlsAddStaReq->htCap.suppMcsSet, + SIZE_OF_SUPPORTED_MCS_SET); + + nCfgValue = pTdlsAddStaReq->htCap.extendedHtCapInfo; + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco; + pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime; + pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback; + + nCfgValue = pTdlsAddStaReq->htCap.txBFCapInfo; + + pTxBFCapabilityInfo = ( tSirMacTxBFCapabilityInfo* ) &nCfgValue; + pDot11f->txBF = pTxBFCapabilityInfo->txBF; + pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding; + pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding; + pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF; + pDot11f->txZLF = pTxBFCapabilityInfo->txZLF; + pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF; + pDot11f->calibration = pTxBFCapabilityInfo->calibration; + pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF; + pDot11f->explicitUncompressedSteeringMatrix = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix; + pDot11f->explicitBFCSIFeedback = pTxBFCapabilityInfo->explicitBFCSIFeedback; + pDot11f->explicitUncompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback; + pDot11f->explicitCompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback; + pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae; + pDot11f->uncompressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae; + pDot11f->compressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae; + + nCfgValue = pTdlsAddStaReq->htCap.antennaSelectionInfo; + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + + pASCapabilityInfo = ( tSirMacASCapabilityInfo* ) &nCfgValue8; + pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection; + pDot11f->explicitCSIFeedbackTx = pASCapabilityInfo->explicitCSIFeedbackTx; + pDot11f->antennaIndicesFeedbackTx = pASCapabilityInfo->antennaIndicesFeedbackTx; + pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback; + pDot11f->antennaIndicesFeedback = pASCapabilityInfo->antennaIndicesFeedback; + pDot11f->rxAS = pASCapabilityInfo->rxAS; + pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs; + + pDot11f->present = pTdlsAddStaReq->htcap_present; + + return eSIR_SUCCESS; + +} + +tSirRetStatus +limTdlsPopulateDot11fVHTCaps(tpAniSirGlobal pMac, + tSirTdlsAddStaReq *pTdlsAddStaReq, + tDot11fIEVHTCaps *pDot11f) +{ + tANI_U32 nCfgValue=0; + union { + tANI_U32 nCfgValue32; + tSirMacVHTCapabilityInfo vhtCapInfo; + } uVHTCapabilityInfo; + union { + tANI_U16 nCfgValue16; + tSirMacVHTTxSupDataRateInfo vhtTxSupDataRateInfo; + tSirMacVHTRxSupDataRateInfo vhtRxsupDataRateInfo; + } uVHTSupDataRateInfo; + + pDot11f->present = pTdlsAddStaReq->vhtcap_present; + + nCfgValue = pTdlsAddStaReq->vhtCap.vhtCapInfo; + uVHTCapabilityInfo.nCfgValue32 = nCfgValue; + + pDot11f->maxMPDULen = uVHTCapabilityInfo.vhtCapInfo.maxMPDULen; + pDot11f->supportedChannelWidthSet = uVHTCapabilityInfo.vhtCapInfo.supportedChannelWidthSet; + pDot11f->ldpcCodingCap = uVHTCapabilityInfo.vhtCapInfo.ldpcCodingCap; + pDot11f->shortGI80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI80MHz; + pDot11f->shortGI160and80plus80MHz = uVHTCapabilityInfo.vhtCapInfo.shortGI160and80plus80MHz; + pDot11f->txSTBC = uVHTCapabilityInfo.vhtCapInfo.txSTBC; + pDot11f->rxSTBC = uVHTCapabilityInfo.vhtCapInfo.rxSTBC; + pDot11f->suBeamFormerCap = uVHTCapabilityInfo.vhtCapInfo.suBeamFormerCap; + pDot11f->suBeamformeeCap = uVHTCapabilityInfo.vhtCapInfo.suBeamformeeCap; + pDot11f->csnofBeamformerAntSup = uVHTCapabilityInfo.vhtCapInfo.csnofBeamformerAntSup; + pDot11f->numSoundingDim = uVHTCapabilityInfo.vhtCapInfo.numSoundingDim; + pDot11f->muBeamformerCap = uVHTCapabilityInfo.vhtCapInfo.muBeamformerCap; + pDot11f->muBeamformeeCap = uVHTCapabilityInfo.vhtCapInfo.muBeamformeeCap; + pDot11f->vhtTXOPPS = uVHTCapabilityInfo.vhtCapInfo.vhtTXOPPS; + pDot11f->htcVHTCap = uVHTCapabilityInfo.vhtCapInfo.htcVHTCap; + pDot11f->maxAMPDULenExp = uVHTCapabilityInfo.vhtCapInfo.maxAMPDULenExp; + pDot11f->vhtLinkAdaptCap = uVHTCapabilityInfo.vhtCapInfo.vhtLinkAdaptCap; + pDot11f->rxAntPattern = uVHTCapabilityInfo.vhtCapInfo.rxAntPattern; + pDot11f->txAntPattern = uVHTCapabilityInfo.vhtCapInfo.txAntPattern; + pDot11f->reserved1= uVHTCapabilityInfo.vhtCapInfo.reserved1; + + pDot11f->rxMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.rxMcsMap; + + nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.rxHighest; + uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; + pDot11f->rxHighSupDataRate = uVHTSupDataRateInfo.vhtRxsupDataRateInfo.rxSupDataRate; + + pDot11f->txMCSMap = pTdlsAddStaReq->vhtCap.suppMcs.txMcsMap; + + nCfgValue = pTdlsAddStaReq->vhtCap.suppMcs.txHighest; + uVHTSupDataRateInfo.nCfgValue16 = nCfgValue & 0xffff; + pDot11f->txSupDataRate = uVHTSupDataRateInfo.vhtTxSupDataRateInfo.txSupDataRate; + + pDot11f->reserved3= uVHTSupDataRateInfo.vhtTxSupDataRateInfo.reserved; + + limLogVHTCap(pMac, pDot11f); + + return eSIR_SUCCESS; + +} + +static tSirRetStatus +limTdlsPopulateMatchingRateSet(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_U8 *pSupportedRateSet, + tANI_U8 supporteRatesLength, + tANI_U8* pSupportedMCSSet, + tSirMacPropRateSet *pAniLegRateSet, + tpPESession psessionEntry, + tDot11fIEVHTCaps *pVHTCaps) + +{ + tSirMacRateSet tempRateSet; + tANI_U32 i,j,val,min,isArate; + tSirMacRateSet tempRateSet2; + tANI_U32 phyMode; + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + isArate=0; + tempRateSet2.numRates = 0; + + // limGetPhyMode(pMac, &phyMode); + limGetPhyMode(pMac, &phyMode, NULL); + + // get own rate set + val = WNI_CFG_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, + (tANI_U8 *) &tempRateSet.rate, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGE, FL("could not retrieve rateset")); + val = 0; + } + tempRateSet.numRates = val; + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + + // get own extended rate set + val = WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + (tANI_U8 *) &tempRateSet2.rate, + &val) != eSIR_SUCCESS) + tempRateSet2.numRates = val; + } + + if ((tempRateSet.numRates + tempRateSet2.numRates) > 12) + { + limLog(pMac, LOGE, FL("more than 12 rates in CFG")); + goto error; + } + + /** + * Handling of the rate set IEs is the following: + * - keep only rates that we support and that the station supports + * - sort and the rates into the pSta->rate array + */ + + // Copy all rates in tempRateSet, there are 12 rates max + for (i = 0; i < tempRateSet2.numRates; i++) + tempRateSet.rate[i + tempRateSet.numRates] = tempRateSet2.rate[i]; + + tempRateSet.numRates += tempRateSet2.numRates; + + /** + * Sort rates in tempRateSet (they are likely to be already sorted) + * put the result in tempRateSet2 + */ + tempRateSet2.numRates = 0; + + for (i = 0;i < tempRateSet.numRates; i++) + { + min = 0; + val = 0xff; + + for(j = 0;j < tempRateSet.numRates; j++) + if ((tANI_U32) (tempRateSet.rate[j] & 0x7f) < val) + { + val = tempRateSet.rate[j] & 0x7f; + min = j; + } + + tempRateSet2.rate[tempRateSet2.numRates++] = tempRateSet.rate[min]; + tempRateSet.rate[min] = 0xff; + } + + /** + * Copy received rates in tempRateSet, the parser has ensured + * unicity of the rates so there cannot be more than 12 . Need to Check this + * TODO Sunil. + */ + if (supporteRatesLength > SIR_MAC_RATESET_EID_MAX) + { + limLog(pMac, LOGW, + FL("Supported rates length %d more than the Max limit, reset to Max"), + supporteRatesLength); + supporteRatesLength = SIR_MAC_RATESET_EID_MAX; + } + for (i = 0; i < supporteRatesLength; i++) + { + tempRateSet.rate[i] = pSupportedRateSet[i]; + } + tempRateSet.numRates = supporteRatesLength; + + { + tpSirSupportedRates rates = &pStaDs->supportedRates; + tANI_U8 aRateIndex = 0; + tANI_U8 bRateIndex = 0; + vos_mem_set( (tANI_U8 *) rates, sizeof(tSirSupportedRates), 0); + + for (i = 0;i < tempRateSet2.numRates; i++) + { + for (j = 0;j < tempRateSet.numRates; j++) + { + if ((tempRateSet2.rate[i] & 0x7F) == + (tempRateSet.rate[j] & 0x7F)) + { + if (sirIsArate(tempRateSet2.rate[i] & 0x7f)) + { + isArate=1; + if (aRateIndex < SIR_NUM_11A_RATES) + rates->llaRates[aRateIndex++] = + tempRateSet2.rate[i]; + } + else + { + if (bRateIndex < SIR_NUM_11B_RATES) + rates->llbRates[bRateIndex++] = + tempRateSet2.rate[i]; + } + break; + } + } + } + } + + + //compute the matching MCS rate set, if peer is 11n capable and self mode is 11n +#ifdef FEATURE_WLAN_TDLS + if (pStaDs->mlmStaContext.htCapability) +#else + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + (pStaDs->mlmStaContext.htCapability)) +#endif + { + val = SIZE_OF_SUPPORTED_MCS_SET; + if (wlan_cfgGetStr(pMac, WNI_CFG_SUPPORTED_MCS_SET, + mcsSet, + &val) != eSIR_SUCCESS) + { + /// Could not get rateset from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve supportedMCSSet")); + goto error; + } + + for (i=0; isupportedRates.supportedMCSSet[i] = mcsSet[i] & pSupportedMCSSet[i]; + + limLog(pMac, LOG1, FL("MCS Rate Set Bitmap from CFG and DPH:")); + for (i=0; isupportedRates.supportedMCSSet[i]); + } + } + +#ifdef WLAN_FEATURE_11AC + limPopulateVhtMcsSet(pMac, &pStaDs->supportedRates, pVHTCaps, psessionEntry); +#endif + /** + * Set the erpEnabled bit iff the phy is in G mode and at least + * one A rate is supported + */ + if ((phyMode == WNI_CFG_PHY_MODE_11G) && isArate) + pStaDs->erpEnabled = eHAL_SET; + + + + return eSIR_SUCCESS; + + error: + + return eSIR_FAILURE; +} + +static int limTdlsSelectCBMode(tDphHashNode *pStaDs, tpPESession psessionEntry) +{ + tANI_U8 channel = psessionEntry->currentOperChannel; + + if ( pStaDs->mlmStaContext.vhtCapability ) + { + if ( channel== 36 || channel == 52 || channel == 100 || + channel == 116 || channel == 149 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1; + } + else if ( channel == 40 || channel == 56 || channel == 104 || + channel == 120 || channel == 153 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1; + } + else if ( channel == 44 || channel == 60 || channel == 108 || + channel == 124 || channel == 157 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1; + } + else if ( channel == 48 || channel == 64 || channel == 112 || + channel == 128 || channel == 161 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1; + } + else if ( channel == 165 ) + { + return 0; + } + } + else if ( pStaDs->mlmStaContext.htCapability ) + { + if ( channel== 40 || channel == 48 || channel == 56 || + channel == 64 || channel == 104 || channel == 112 || + channel == 120 || channel == 128 || channel == 136 || + channel == 144 || channel == 153 || channel == 161 ) + { + return 1; + } + else if ( channel== 36 || channel == 44 || channel == 52 || + channel == 60 || channel == 100 || channel == 108 || + channel == 116 || channel == 124 || channel == 132 || + channel == 140 || channel == 149 || channel == 157 ) + { + return 2; + } + else if ( channel == 165 ) + { + return 0; + } + } + return 0; +} + +/* + * update HASH node entry info + */ +static void limTdlsUpdateHashNodeInfo(tpAniSirGlobal pMac, tDphHashNode *pStaDs, + tSirTdlsAddStaReq *pTdlsAddStaReq, tpPESession psessionEntry) +{ + //tDot11fIEHTCaps *htCaps = &setupPeerInfo->tdlsPeerHTCaps ; + tDot11fIEHTCaps htCap, *htCaps; + tDot11fIEVHTCaps *pVhtCaps = NULL; +#ifdef WLAN_FEATURE_11AC + tDot11fIEVHTCaps vhtCap; + tANI_U8 cbMode; +#endif + tpDphHashNode pSessStaDs = NULL; + tANI_U16 aid; + + if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) + { + PopulateDot11fHTCaps(pMac, psessionEntry, &htCap); + } + else if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) + { + limTdlsPopulateDot11fHTCaps(pMac, NULL, pTdlsAddStaReq, &htCap); + } + htCaps = &htCap; + if (htCaps->present) + { + pStaDs->mlmStaContext.htCapability = 1 ; + pStaDs->htGreenfield = htCaps->greenField ; + /* pStaDs->htSupportedChannelWidthSet should have the base channel + * capability. The htSupportedChannelWidthSet of the TDLS link on + * base channel should be less than or equal to channel width of + * STA-AP link. So take this setting from the psessionEntry. + */ + limLog(pMac, LOG1, + FL("supportedChannelWidthSet %x htSupportedChannelWidthSet %x"), + htCaps->supportedChannelWidthSet, + psessionEntry->htSupportedChannelWidthSet); + + pStaDs->htSupportedChannelWidthSet = + (htCaps->supportedChannelWidthSet < + psessionEntry->htSupportedChannelWidthSet) ? + htCaps->supportedChannelWidthSet : + psessionEntry->htSupportedChannelWidthSet; + + limLog(pMac, LOG1, FL("pStaDs->htSupportedChannelWidthSet %x"), + pStaDs->htSupportedChannelWidthSet); + + pStaDs->htMIMOPSState = htCaps->mimoPowerSave ; + pStaDs->htMaxAmsduLength = htCaps->maximalAMSDUsize; + pStaDs->htAMpduDensity = htCaps->mpduDensity; + pStaDs->htDsssCckRate40MHzSupport = htCaps->dsssCckMode40MHz ; + pStaDs->htShortGI20Mhz = htCaps->shortGI20MHz; + pStaDs->htShortGI40Mhz = htCaps->shortGI40MHz; + pStaDs->htMaxRxAMpduFactor = htCaps->maxRxAMPDUFactor; + limFillRxHighestSupportedRate(pMac, + &pStaDs->supportedRates.rxHighestDataRate, + htCaps->supportedMCSSet); + pStaDs->baPolicyFlag = 0xFF; + pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_N ; + } + else + { + pStaDs->mlmStaContext.htCapability = 0 ; + pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_BG ; + } +#ifdef WLAN_FEATURE_11AC + limTdlsPopulateDot11fVHTCaps(pMac, pTdlsAddStaReq, &vhtCap); + pVhtCaps = &vhtCap; + if (pVhtCaps->present) + { + pStaDs->mlmStaContext.vhtCapability = 1 ; + + pStaDs->vhtSupportedChannelWidthSet = + psessionEntry->vhtTxChannelWidthSet; + + limLog(pMac, LOG1, FL("Vht supported channel width is set to = %d"), + pStaDs->vhtSupportedChannelWidthSet); + + pStaDs->vhtLdpcCapable = pVhtCaps->ldpcCodingCap; + pStaDs->vhtBeamFormerCapable= pVhtCaps->suBeamFormerCap; + // TODO , is it necessary , Sunil??? + pMac->lim.gLimTdlsLinkMode = TDLS_LINK_MODE_AC; + } + else + { + pStaDs->mlmStaContext.vhtCapability = 0 ; + pStaDs->vhtSupportedChannelWidthSet = WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + } +#endif + /*Calculate the Secondary Coannel Offset */ + cbMode = limTdlsSelectCBMode(pStaDs, psessionEntry); + + pStaDs->htSecondaryChannelOffset = cbMode; + +#ifdef WLAN_FEATURE_11AC + if ( pStaDs->mlmStaContext.vhtCapability ) + { + pStaDs->htSecondaryChannelOffset = limGetHTCBState(cbMode); + } +#endif + + pSessStaDs = dphLookupHashEntry(pMac, psessionEntry->bssId, &aid, + &psessionEntry->dph.dphHashTable) ; + + /* Lets enable QOS parameter */ + pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET) || + pTdlsAddStaReq->htcap_present; + pStaDs->wmeEnabled = 1; + pStaDs->lleEnabled = 0; + /* TDLS Dummy AddSTA does not have qosInfo , is it OK ?? + */ + pStaDs->qos.capability.qosInfo = (*(tSirMacQosInfoStation *) &pTdlsAddStaReq->uapsd_queues); + + /* populate matching rate set */ + + /* TDLS Dummy AddSTA does not have HTCap,VHTCap,Rates info , is it OK ?? + */ + limTdlsPopulateMatchingRateSet(pMac, pStaDs, pTdlsAddStaReq->supported_rates, + pTdlsAddStaReq->supported_rates_length, + (tANI_U8 *)pTdlsAddStaReq->htCap.suppMcsSet, + &pStaDs->mlmStaContext.propRateSet, + psessionEntry, pVhtCaps); + + /* TDLS Dummy AddSTA does not have right capability , is it OK ?? + */ + pStaDs->mlmStaContext.capabilityInfo = ( *(tSirMacCapabilityInfo *) &pTdlsAddStaReq->capability); + + return ; +} + +/* + * Add STA for TDLS setup procedure + */ +static tSirRetStatus limTdlsSetupAddSta(tpAniSirGlobal pMac, + tSirTdlsAddStaReq *pAddStaReq, + tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL ; + tSirRetStatus status = eSIR_SUCCESS ; + tANI_U16 aid = 0 ; + + pStaDs = dphLookupHashEntry(pMac, pAddStaReq->peerMac, &aid, + &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + { + aid = limAssignPeerIdx(pMac, psessionEntry) ; + + if( !aid ) + { + limLog(pMac, LOGE, FL("No more free AID for peer " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pAddStaReq->peerMac)); + return eSIR_FAILURE; + } + + /* Set the aid in peerAIDBitmap as it has been assigned to TDLS peer */ + SET_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, aid); + + limLog(pMac, LOG1, FL("Aid = %d, for peer =" MAC_ADDRESS_STR), + aid, MAC_ADDR_ARRAY(pAddStaReq->peerMac)); + pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable); + + if (pStaDs) + { + (void) limDelSta(pMac, pStaDs, false /*asynchronous*/, psessionEntry); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid, psessionEntry); + } + + pStaDs = dphAddHashEntry(pMac, pAddStaReq->peerMac, aid, + &psessionEntry->dph.dphHashTable) ; + + if(NULL == pStaDs) + { + limLog(pMac, LOGE, FL("add hash entry failed")); + VOS_ASSERT(0) ; + return eSIR_FAILURE; + } + } + + limTdlsUpdateHashNodeInfo(pMac, pStaDs, pAddStaReq, psessionEntry) ; + + pStaDs->staType = STA_ENTRY_TDLS_PEER ; + + status = limAddSta(pMac, pStaDs, (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE) ? true: false, psessionEntry); + + if(eSIR_SUCCESS != status) + { + /* should not fail */ + VOS_ASSERT(0) ; + } + return status ; +} + +/* + * Del STA, after Link is teardown or discovery response sent on direct link + */ +static tpDphHashNode limTdlsDelSta(tpAniSirGlobal pMac, tSirMacAddr peerMac, + tpPESession psessionEntry) +{ + tSirRetStatus status = eSIR_SUCCESS ; + tANI_U16 peerIdx = 0 ; + tpDphHashNode pStaDs = NULL ; + + pStaDs = dphLookupHashEntry(pMac, peerMac, &peerIdx, + &psessionEntry->dph.dphHashTable) ; + + if(pStaDs) + { + + limLog(pMac, LOG1, FL("DEL STA peer MAC: "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr)); + limLog(pMac, LOG1, FL("STA type = %x, sta idx = %x"), + pStaDs->staType, + pStaDs->staIndex); + limDeleteBASessions(pMac, psessionEntry, BA_BOTH_DIRECTIONS, + eSIR_MAC_PEER_TIMEDOUT_REASON); + status = limDelSta(pMac, pStaDs, false, psessionEntry) ; + } + + return pStaDs ; +} + +/* + * Once Link is setup with PEER, send Add STA ind to SME + */ +static eHalStatus limSendSmeTdlsAddStaRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tANI_U8 updateSta, + tDphHashNode *pStaDs, tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + tSirTdlsAddStaRsp *addStaRsp = NULL ; + mmhMsg.type = eWNI_SME_TDLS_ADD_STA_RSP ; + + addStaRsp = vos_mem_malloc(sizeof(tSirTdlsAddStaRsp)); + if ( NULL == addStaRsp ) + { + limLog(pMac, LOGE, FL("Failed to allocate memory")); + return eSIR_FAILURE; + } + + addStaRsp->sessionId = sessionId; + addStaRsp->statusCode = status; + if( pStaDs ) + { + addStaRsp->staId = pStaDs->staIndex ; + addStaRsp->ucastSig = pStaDs->ucUcastSig ; + addStaRsp->bcastSig = pStaDs->ucBcastSig ; + } + if( peerMac ) + { + vos_mem_copy( addStaRsp->peerMac, + (tANI_U8 *) peerMac, sizeof(tSirMacAddr)); + } + if (updateSta) + addStaRsp->tdlsAddOper = TDLS_OPER_UPDATE; + else + addStaRsp->tdlsAddOper = TDLS_OPER_ADD; + + addStaRsp->length = sizeof(tSirTdlsAddStaRsp) ; + addStaRsp->messageType = eWNI_SME_TDLS_ADD_STA_RSP ; + + mmhMsg.bodyptr = addStaRsp; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return eSIR_SUCCESS ; + +} +/* + * STA RSP received from HAL + */ +eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, + tpPESession psessionEntry) +{ + tAddStaParams *pAddStaParams = (tAddStaParams *) msg ; + tANI_U8 status = eSIR_SUCCESS ; + tDphHashNode *pStaDs = NULL ; + tANI_U16 aid = 0 ; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + limLog(pMac, LOG1, FL("staIdx=%d, staMac="MAC_ADDRESS_STR), + pAddStaParams->staIdx, + MAC_ADDR_ARRAY(pAddStaParams->staMac)); + + if (pAddStaParams->status != eHAL_STATUS_SUCCESS) + { + VOS_ASSERT(0) ; + limLog(pMac, LOGE, FL("Add sta failed ")); + status = eSIR_FAILURE; + goto add_sta_error; + } + + pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid, + &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + { + limLog(pMac, LOGE, FL("pStaDs is NULL ")); + status = eSIR_FAILURE; + goto add_sta_error; + } + + pStaDs->bssId = pAddStaParams->bssIdx; + pStaDs->staIndex = pAddStaParams->staIdx; + pStaDs->ucUcastSig = pAddStaParams->ucUcastSig; + pStaDs->ucBcastSig = pAddStaParams->ucBcastSig; + pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + pStaDs->valid = 1 ; +add_sta_error: + status = limSendSmeTdlsAddStaRsp(pMac, psessionEntry->smeSessionId, + pAddStaParams->staMac, pAddStaParams->updateSta, pStaDs, status) ; + vos_mem_free( pAddStaParams ); + return status ; +} + +void PopulateDot11fTdlsOffchannelParams(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIESuppChannels *suppChannels, + tDot11fIESuppOperatingClasses *suppOperClasses) +{ + tANI_U32 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN; + tANI_U8 validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 i, j; + tANI_U8 op_class; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + validChan, &numChans) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve valid channel list")); + return; + } + suppChannels->num_bands = (tANI_U8) numChans; + + for ( i = 0U, j = 0U; i < suppChannels->num_bands && + j < LIM_MAX_BANDS; i++) + { + /* don't populate dfs channels in supported channels ie */ + if (!(NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(validChan[i]))) { + suppChannels->bands[j][0] = validChan[i]; + suppChannels->bands[j][1] = 1; + /* store tdls self supported channels */ + tdlsSelfSupportedChannels[j] = validChan[i]; + j++; + } + } + /* update the channel list with new length */ + suppChannels->num_bands = j; + suppChannels->present = 1 ; + /* store tdls self supported channels new length */ + tdlsSelfNumChans = j; + + /*Get present operating class based on current operating channel*/ + op_class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset); + if (op_class == 0) + { + limLog(pMac, LOGE, + FL("Present Operating class is wrong, countryCodeCurrent: %s, currentOperChannel: %d, htSecondaryChannelOffset: %d"), + pMac->scan.countryCodeCurrent, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset); + } + else + { + limLog(pMac, LOG1, + FL("Present Operating channel=%d offset=%d class=%d"), + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset, + op_class); + } + suppOperClasses->present = 1; + suppOperClasses->classes[0] = op_class; + /*Fill operating classes from static array*/ + suppOperClasses->num_classes = op_classes.num_classes; + for ( i = 0U; i < suppOperClasses->num_classes; i++) + { + suppOperClasses->classes[i+1] = op_classes.classes[i]; + + } + /*increment for present operating class*/ + suppOperClasses->num_classes++; + return ; +} + + +/* + * FUNCTION: Populate Link Identifier element IE + * + */ + + +void PopulateDot11fLinkIden(tpAniSirGlobal pMac, tpPESession psessionEntry, + tDot11fIELinkIdentifier *linkIden, + tSirMacAddr peerMac, tANI_U8 reqType) +{ + //tANI_U32 size = sizeof(tSirMacAddr) ; + tANI_U8 *initStaAddr = NULL ; + tANI_U8 *respStaAddr = NULL ; + + (reqType == TDLS_INITIATOR) ? ((initStaAddr = linkIden->InitStaAddr), + (respStaAddr = linkIden->RespStaAddr)) + : ((respStaAddr = linkIden->InitStaAddr ), + (initStaAddr = linkIden->RespStaAddr)) ; + vos_mem_copy( (tANI_U8 *)linkIden->bssid, + (tANI_U8 *) psessionEntry->bssId, sizeof(tSirMacAddr)) ; + + vos_mem_copy( (tANI_U8 *)initStaAddr, + psessionEntry->selfMacAddr, sizeof(tSirMacAddr)) ; + + vos_mem_copy( (tANI_U8 *)respStaAddr, (tANI_U8 *) peerMac, + sizeof( tSirMacAddr )); + + linkIden->present = 1 ; + return ; + +} + +void PopulateDot11fTdlsExtCapability(tpAniSirGlobal pMac, + tDot11fIEExtCap *extCapability) +{ + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extCapability->bytes; + + p_ext_cap->TDLSPeerPSMSupp = PEER_PSM_SUPPORT ; + p_ext_cap->TDLSPeerUAPSDBufferSTA = pMac->lim.gLimTDLSBufStaEnabled; + p_ext_cap->TDLSChannelSwitching = pMac->lim.gLimTDLSOffChannelEnabled ; + p_ext_cap->TDLSSupport = TDLS_SUPPORT ; + p_ext_cap->TDLSProhibited = TDLS_PROHIBITED ; + p_ext_cap->TDLSChanSwitProhibited = TDLS_CH_SWITCH_PROHIBITED ; + + extCapability->present = 1; + extCapability->num_bytes = lim_compute_ext_cap_ie_length(extCapability); + + return ; +} + +/* + * Process Send Mgmt Request from SME and transmit to AP. + */ +tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsSendMgmtReq *pSendMgmtReq = (tSirTdlsSendMgmtReq*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + tSirResultCodes resultCode = eSIR_SME_INVALID_PARAMETERS; + + limLog(pMac, LOG1, FL("Send Mgmt Recieved")); + + if((psessionEntry = peFindSessionByBssid(pMac, pSendMgmtReq->bssid, &sessionId)) + == NULL) + { + limLog(pMac, LOGE, + FL("PE Session does not exist for given sme sessionId %d"), + pSendMgmtReq->sessionId); + goto lim_tdls_send_mgmt_error; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "send mgmt received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_send_mgmt_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, FL("send mgmt received in invalid LIMsme state (%d)"), + psessionEntry->limSmeState); + goto lim_tdls_send_mgmt_error; + } + vos_tdls_tx_rx_mgmt_event(SIR_MAC_ACTION_TDLS, + SIR_MAC_ACTION_TX, SIR_MAC_MGMT_ACTION, + pSendMgmtReq->reqType, pSendMgmtReq->peerMac); + + switch( pSendMgmtReq->reqType ) + { + case SIR_MAC_TDLS_DIS_REQ: + limLog(pMac, LOG1, FL("Transmit Discovery Request Frame")); + /* format TDLS discovery request frame and transmit it */ + limSendTdlsDisReqFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, + psessionEntry) ; + resultCode = eSIR_SME_SUCCESS; + break; + case SIR_MAC_TDLS_DIS_RSP: + { + limLog(pMac, LOG1, FL("Transmit Discovery Response Frame")); + //Send a response mgmt action frame + limSendTdlsDisRspFrame(pMac, pSendMgmtReq->peerMac, + pSendMgmtReq->dialog, psessionEntry, + &pSendMgmtReq->addIe[0], + (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_SETUP_REQ: + { + limLog(pMac, LOG1, FL("Transmit Setup Request Frame")); + limSendTdlsLinkSetupReqFrame(pMac, + pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, + &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_SETUP_RSP: + { + limLog(pMac, LOG1, FL("Transmit Setup Response Frame")); + limSendTdlsSetupRspFrame(pMac, + pSendMgmtReq->peerMac, pSendMgmtReq->dialog, psessionEntry, pSendMgmtReq->statusCode, + &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_SETUP_CNF: + { + limLog(pMac, LOG1, FL("Transmit Setup Confirm Frame")); + limSendTdlsLinkSetupCnfFrame(pMac, pSendMgmtReq->peerMac, pSendMgmtReq->dialog, pSendMgmtReq->peerCapability, + psessionEntry, &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_TEARDOWN: + { + limLog(pMac, LOG1, FL("Transmit Teardown Frame")); + limSendTdlsTeardownFrame(pMac, + pSendMgmtReq->peerMac, pSendMgmtReq->statusCode, pSendMgmtReq->responder, psessionEntry, + &pSendMgmtReq->addIe[0], (pSendMgmtReq->length - sizeof(tSirTdlsSendMgmtReq))); + resultCode = eSIR_SME_SUCCESS; + } + break; + case SIR_MAC_TDLS_PEER_TRAFFIC_IND: + { + } + break; + case SIR_MAC_TDLS_CH_SWITCH_REQ: + { + } + break; + case SIR_MAC_TDLS_CH_SWITCH_RSP: + { + } + break; + case SIR_MAC_TDLS_PEER_TRAFFIC_RSP: + { + } + break; + default: + break; + } + +lim_tdls_send_mgmt_error: + + limSendSmeRsp( pMac, eWNI_SME_TDLS_SEND_MGMT_RSP, + resultCode, pSendMgmtReq->sessionId, pSendMgmtReq->transactionId); + + return eSIR_SUCCESS; +} + +/* + * Send Response to Link Establish Request to SME + */ +void limSendSmeTdlsLinkEstablishReqRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + + tSirTdlsLinkEstablishReqRsp *pTdlsLinkEstablishReqRsp = NULL ; + + pTdlsLinkEstablishReqRsp = vos_mem_malloc(sizeof(tSirTdlsLinkEstablishReqRsp)); + if ( NULL == pTdlsLinkEstablishReqRsp ) + { + limLog(pMac, LOGE, FL("Failed to allocate memory")); + return ; + } + + vos_mem_zero(pTdlsLinkEstablishReqRsp, sizeof(tSirTdlsLinkEstablishReqRsp)); + + pTdlsLinkEstablishReqRsp->statusCode = status ; + if (pStaDs && peerMac) + { + vos_mem_copy(pTdlsLinkEstablishReqRsp->peerMac, peerMac, sizeof(tSirMacAddr)); + pTdlsLinkEstablishReqRsp->sta_idx = pStaDs->staIndex; + } + + pTdlsLinkEstablishReqRsp->sessionId = sessionId; + + mmhMsg.type = eWNI_SME_TDLS_LINK_ESTABLISH_RSP ; + mmhMsg.bodyptr = pTdlsLinkEstablishReqRsp; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return ; + + +} + +/* + * Send Response to Chan Switch Request to SME + */ +void limSendSmeTdlsChanSwitchReqRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + + tSirTdlsChanSwitchReqRsp *pTdlsChanSwitchReqRsp = NULL ; + + pTdlsChanSwitchReqRsp = vos_mem_malloc(sizeof(tSirTdlsChanSwitchReqRsp)); + if ( NULL == pTdlsChanSwitchReqRsp ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return ; + } + + vos_mem_zero(pTdlsChanSwitchReqRsp, sizeof(tSirTdlsChanSwitchReqRsp)); + + pTdlsChanSwitchReqRsp->statusCode = status ; + if (pStaDs && peerMac ) + { + vos_mem_copy(pTdlsChanSwitchReqRsp->peerMac, peerMac, sizeof(tSirMacAddr)); + pTdlsChanSwitchReqRsp->sta_idx = pStaDs->staIndex;; + } + + pTdlsChanSwitchReqRsp->sessionId = sessionId; + + mmhMsg.type = eWNI_SME_TDLS_CHANNEL_SWITCH_RSP ; + mmhMsg.bodyptr = pTdlsChanSwitchReqRsp; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return ; + + +} +/* + * Once link is teardown, send Del Peer Ind to SME + */ +static eHalStatus limSendSmeTdlsDelStaRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status) +{ + tSirMsgQ mmhMsg = {0} ; + tSirTdlsDelStaRsp *pDelSta = NULL ; + mmhMsg.type = eWNI_SME_TDLS_DEL_STA_RSP ; + + pDelSta = vos_mem_malloc(sizeof(tSirTdlsDelStaRsp)); + if ( NULL == pDelSta ) + { + limLog(pMac, LOGE, FL("Failed to allocate memory")); + return eSIR_FAILURE; + } + + pDelSta->sessionId = sessionId; + pDelSta->statusCode = status ; + if( pStaDs ) + { + pDelSta->staId = pStaDs->staIndex ; + } + else + pDelSta->staId = HAL_STA_INVALID_IDX; + + if( peerMac ) + { + vos_mem_copy(pDelSta->peerMac, peerMac, sizeof(tSirMacAddr)); + } + + pDelSta->length = sizeof(tSirTdlsDelStaRsp) ; + pDelSta->messageType = eWNI_SME_TDLS_DEL_STA_RSP ; + + mmhMsg.bodyptr = pDelSta; + + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return eSIR_SUCCESS ; + +} + +/* + * Process Send Mgmt Request from SME and transmit to AP. + */ +tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsAddStaReq *pAddStaReq = (tSirTdlsAddStaReq*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + + limLog(pMac, LOG1, FL("TDLS Add STA Request Recieved")); + + if((psessionEntry = peFindSessionByBssid(pMac, pAddStaReq->bssid, &sessionId)) + == NULL) + { + limLog(pMac, LOGE, + FL("PE Session does not exist for given sme sessionId %d"), + pAddStaReq->sessionId); + goto lim_tdls_add_sta_error; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "send mgmt received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_add_sta_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, + FL("Add STA received in invalid LIMsme state (%d)"), + psessionEntry->limSmeState); + goto lim_tdls_add_sta_error; + } + + pMac->lim.gLimAddStaTdls = true ; + + /* To start with, send add STA request to HAL */ + if (eSIR_FAILURE == limTdlsSetupAddSta(pMac, pAddStaReq, psessionEntry)) + { + limLog(pMac, LOGE, FL("Add TDLS Station request failed")); + goto lim_tdls_add_sta_error; + } + return eSIR_SUCCESS; +lim_tdls_add_sta_error: + limSendSmeTdlsAddStaRsp(pMac, + pAddStaReq->sessionId, pAddStaReq->peerMac, + (pAddStaReq->tdlsAddOper == TDLS_OPER_UPDATE), NULL, eSIR_FAILURE ); + + return eSIR_SUCCESS; +} +/* + * Process Del Sta Request from SME . + */ +tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + tpDphHashNode pStaDs = NULL ; + + limLog(pMac, LOG1, FL("TDLS Delete STA Request Recieved")); + + if((psessionEntry = peFindSessionByBssid(pMac, pDelStaReq->bssid, &sessionId)) + == NULL) + { + limLog(pMac, LOGE, + FL("PE Session does not exist for given sme sessionId %d"), + pDelStaReq->sessionId); + limSendSmeTdlsDelStaRsp(pMac, pDelStaReq->sessionId, pDelStaReq->peerMac, + NULL, eSIR_FAILURE) ; + return eSIR_FAILURE; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "Del sta received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_del_sta_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, FL("Del Sta received in invalid LIMsme state (%d)"), + psessionEntry->limSmeState); + goto lim_tdls_del_sta_error; + } + + pStaDs = limTdlsDelSta(pMac, pDelStaReq->peerMac, psessionEntry) ; + + /* now send indication to SME-->HDD->TL to remove STA from TL */ + + if(pStaDs) + { + limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac, + pStaDs, eSIR_SUCCESS) ; + limReleasePeerIdx(pMac, pStaDs->assocId, psessionEntry) ; + + /* Clear the aid in peerAIDBitmap as this aid is now in freepool */ + CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap, pStaDs->assocId); + limDeleteDphHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, psessionEntry) ; + + return eSIR_SUCCESS; + + } + +lim_tdls_del_sta_error: + limSendSmeTdlsDelStaRsp(pMac, psessionEntry->smeSessionId, pDelStaReq->peerMac, + NULL, eSIR_FAILURE) ; + + return eSIR_SUCCESS; +} + +/* Intersects the two input arrays and outputs an array */ +/* For now the array length of tANI_U8 suffices */ +static void limTdlsGetIntersection(tANI_U8 *input_array1,tANI_U8 input1_length, + tANI_U8 *input_array2,tANI_U8 input2_length, + tANI_U8 *output_array,tANI_U8 *output_length) +{ + tANI_U8 i,j,k=0,flag=0; + + if (input1_length > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + input1_length = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + + for(i=0;ibssid, &sessionId)) + == NULL) + { + limLog(pMac, LOGE, + FL("PE Session does not exist for given sme sessionId %d"), + pTdlsLinkEstablishReq->sessionId); + limSendSmeTdlsLinkEstablishReqRsp(pMac, pTdlsLinkEstablishReq->sessionId, pTdlsLinkEstablishReq->peerMac, + NULL, eSIR_FAILURE) ; + return eSIR_FAILURE; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "TDLS Link Establish Request received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_link_establish_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, + FL("TDLS Link Establish Request received in invalid LIMsme state (%d)"), + psessionEntry->limSmeState); + goto lim_tdls_link_establish_error; + } + /*TODO Sunil , TDLSPeer Entry has the STA ID , Use it */ + pStaDs = dphLookupHashEntry(pMac, pTdlsLinkEstablishReq->peerMac, &peerIdx, + &psessionEntry->dph.dphHashTable) ; + if ( NULL == pStaDs ) + { + limLog(pMac, LOGE, FL( "pStaDs is NULL")); + goto lim_tdls_link_establish_error; + + } + pMsgTdlsLinkEstablishReq = vos_mem_malloc(sizeof( tTdlsLinkEstablishParams )); + if ( NULL == pMsgTdlsLinkEstablishReq ) + { + limLog(pMac, LOGE, + FL("Unable to allocate memory TDLS Link Establish Request")); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set( (tANI_U8 *)pMsgTdlsLinkEstablishReq, sizeof(tTdlsLinkEstablishParams), 0); + + pMsgTdlsLinkEstablishReq->staIdx = pStaDs->staIndex; + pMsgTdlsLinkEstablishReq->isResponder = pTdlsLinkEstablishReq->isResponder; + pMsgTdlsLinkEstablishReq->uapsdQueues = pTdlsLinkEstablishReq->uapsdQueues; + pMsgTdlsLinkEstablishReq->maxSp = pTdlsLinkEstablishReq->maxSp; + pMsgTdlsLinkEstablishReq->isBufsta = pTdlsLinkEstablishReq->isBufSta; + + if (psessionEntry->tdlsChanSwitProhibited) + { + /* If channel switch is prohibited by AP then dut can either + * send a switch channel request with failure status or it can + * ignore the request without sending the response. + * isOffChannelSupported = 0 disables the TDLS off-channel and + * if off-channel support is disabled then FW ignores switch + * channel request sent by TDLS peer */ + pMsgTdlsLinkEstablishReq->isOffChannelSupported = 0; + limLog(pMac, LOG1, FL("Channel Switch Prohibited by AP")); + } + else + { + pMsgTdlsLinkEstablishReq->isOffChannelSupported = + pTdlsLinkEstablishReq->isOffChannelSupported; + } + + if ((pTdlsLinkEstablishReq->supportedChannelsLen > 0) && + (pTdlsLinkEstablishReq->supportedChannelsLen <= SIR_MAC_MAX_SUPP_CHANNELS)) + { + /* check self supported channels and pass them to FW */ + if ((tdlsSelfNumChans > 0) && + (tdlsSelfNumChans < LIM_TDLS_MAX_NON_DFS_CHANNELS)) + { + limTdlsGetIntersection(tdlsSelfSupportedChannels, tdlsSelfNumChans, + pTdlsLinkEstablishReq->supportedChannels, + pTdlsLinkEstablishReq->supportedChannelsLen, + pMsgTdlsLinkEstablishReq->validChannels, + &pMsgTdlsLinkEstablishReq->validChannelsLen); + } + } + vos_mem_copy(pMsgTdlsLinkEstablishReq->validOperClasses, + pTdlsLinkEstablishReq->supportedOperClasses, pTdlsLinkEstablishReq->supportedOperClassesLen); + pMsgTdlsLinkEstablishReq->validOperClassesLen = + pTdlsLinkEstablishReq->supportedOperClassesLen; + + msg.type = WDA_SET_TDLS_LINK_ESTABLISH_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgTdlsLinkEstablishReq; + msg.bodyval = 0; + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("halPostMsgApi failed")); + goto lim_tdls_link_establish_error; + } + return eSIR_SUCCESS; +lim_tdls_link_establish_error: + limSendSmeTdlsLinkEstablishReqRsp(pMac, psessionEntry->smeSessionId, pTdlsLinkEstablishReq->peerMac, + NULL, eSIR_FAILURE) ; + + return eSIR_SUCCESS; +} + + +/* Delete all the TDLS peer connected before leaving the BSS */ +tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tpDphHashNode pStaDs = NULL ; + int i, aid; + + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("NULL psessionEntry")); + return eSIR_FAILURE; + } + + /* Check all the set bit in peerAIDBitmap and delete the peer (with that aid) entry + from the hash table and add the aid in free pool */ + for (i = 0; i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); i++) + { + for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) + { + if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) + { + pStaDs = dphGetHashEntry(pMac, (aid + i*(sizeof(tANI_U32) << 3)), &psessionEntry->dph.dphHashTable); + + if (NULL != pStaDs) + { + limLog(pMac, LOGE, FL("Deleting "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr)); + + limSendDeauthMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + pStaDs->staAddr, psessionEntry, FALSE); + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, &psessionEntry->dph.dphHashTable); + } + limReleasePeerIdx(pMac, (aid + i*(sizeof(tANI_U32) << 3)), psessionEntry) ; + CLEAR_BIT(psessionEntry->peerAIDBitmap[i], aid); + } + } + } + limSendSmeTDLSDeleteAllPeerInd(pMac, psessionEntry); + + return eSIR_SUCCESS; +} + + +tANI_U8 limGetOffChMaxBwOffsetFromChannel(tANI_U8 *country, + tANI_U8 channel, + tANI_U8 peerVHTCapability) +{ + op_class_map_t *class = NULL; + tANI_U16 i = 0; + offset_t offset = BW20, max_allowed = BW80; + + if ((TRUE == peerVHTCapability) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC) && + IS_FEATURE_SUPPORTED_BY_DRIVER(DOT11AC)) + max_allowed = BW80; + else + max_allowed = BW40MINUS; + + if (VOS_TRUE == vos_mem_compare(country,"US", 2)) { + + class = us_op_class; + + } else if (VOS_TRUE == vos_mem_compare(country,"EU", 2)) { + + class = euro_op_class; + + } else if (VOS_TRUE == vos_mem_compare(country,"JP", 2)) { + + class = japan_op_class; + + } else { + + class = global_op_class; + + } + + while (class->op_class) + { + for (i=0; (i < 25 && class->channels[i]); i++) + { + if (channel == class->channels[i] && class->offset <= max_allowed) + offset = class->offset; + } + class++; + } + + return offset; +} + + +tANI_U8 limGetOPClassFromChannel(tANI_U8 *country, + tANI_U8 channel, + tANI_U8 offset) +{ + op_class_map_t *class = NULL; + tANI_U16 i = 0; + + if (VOS_TRUE == vos_mem_compare(country,"US", 2)) { + + class = us_op_class; + + } else if (VOS_TRUE == vos_mem_compare(country,"EU", 2)) { + + class = euro_op_class; + + } else if (VOS_TRUE == vos_mem_compare(country,"JP", 2)) { + + class = japan_op_class; + + } else { + + class = global_op_class; + + } + + while (class->op_class) + { + if ((offset == class->offset) || (offset == BWALL)) + { + for (i=0; (i < 25 && class->channels[i]); i++) + { + if (channel == class->channels[i]) + return class->op_class; + } + } + class++; + } + return 0; +} + +tANI_BOOLEAN CheckAndAddOP(tANI_U8 class) +{ + tANI_U8 i; + + for (i=0; i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); i++) + { + /*0 is an invalid class. If class is already present ignore*/ + if (class == op_classes.classes[i]) + return FALSE; + if(op_classes.classes[i] == 0) + { + return TRUE; + } + } + //limLog(pMac, LOGE, FL("No space left for class = %d"), class); + return FALSE; +} + +void limInitOperatingClasses( tHalHandle hHal ) +{ + + tANI_U8 Index = 0; + tANI_U8 class = 0; + tANI_U8 i = 0; + tANI_U8 j = 0; + tANI_U8 swap = 0; + tANI_U8 numChannels = 0; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + limLog(pMac, LOG1, FL("Current Country = %c%c"), + pMac->scan.countryCodeCurrent[0], + pMac->scan.countryCodeCurrent[1]); + + vos_mem_set(op_classes.classes, sizeof(op_classes.classes), 0); + numChannels = pMac->scan.baseChannels.numChannels; + limLog(pMac, LOG1, "Num of base ch =%d", numChannels); + for ( Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) + { + class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pMac->scan.baseChannels.channelList[ Index ], + BWALL); + limLog(pMac, LOG4, "ch=%d <=> %d=class", + pMac->scan.baseChannels.channelList[ Index ], + class); + if (CheckAndAddOP(class)) + { + op_classes.classes[i]= class; + i++; + } + } + + numChannels = pMac->scan.base20MHzChannels.numChannels; + limLog(pMac, LOG1, "Num of 20MHz ch =%d", numChannels); + for ( Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) + { + class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pMac->scan.base20MHzChannels.channelList[ Index ], + BWALL); + limLog(pMac, LOG4, "ch=%d <=> %d=class", + pMac->scan.base20MHzChannels.channelList[ Index ], + class); + if (CheckAndAddOP(class)) + { + op_classes.classes[i]= class; + i++; + } + } + + numChannels = pMac->scan.base40MHzChannels.numChannels; + limLog(pMac, LOG1, "Num of 40MHz ch =%d", numChannels); + for ( Index = 0; + Index < numChannels && i < (SIR_MAC_MAX_SUPP_OPER_CLASSES - 1); + Index++) + { + class = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pMac->scan.base40MHzChannels.channelList[ Index ], + BWALL); + limLog(pMac, LOG4, "ch=%d <=> %d=class", + pMac->scan.base40MHzChannels.channelList[ Index ], + class); + if (CheckAndAddOP(class)) + { + op_classes.classes[i]= class; + i++; + } + } + + op_classes.num_classes = i; + limLog(pMac, LOG1, "Total number of Unique supported classes =%d", + op_classes.num_classes); + /*as per spec the operating classes should be in ascending order*/ + /*Bubble sort is fine as we don't have many classes*/ + for (i = 0 ; i < ( op_classes.num_classes - 1 ); i++) + { + for (j = 0 ; j < op_classes.num_classes - i - 1; j++) + { + /* For decreasing order use < */ + if (op_classes.classes[j] > op_classes.classes[j+1]) + { + swap = op_classes.classes[j]; + op_classes.classes[j] = op_classes.classes[j+1]; + op_classes.classes[j+1] = swap; + } + } + } + for (i=0; i < op_classes.num_classes; i++) + { + + limLog(pMac, LOG1, "supported op_class[%d]=%d", i, + op_classes.classes[i]); + + } +} + +#endif +// tdlsoffchan +/* + * Process Channel Switch from SME. + */ +tSirRetStatus limProcesSmeTdlsChanSwitchReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + /* get all discovery request parameters */ + tSirTdlsChanSwitch *pTdlsChanSwitch = (tSirTdlsChanSwitch*) pMsgBuf ; + tpPESession psessionEntry; + tANI_U8 sessionId; + tpTdlsChanSwitchParams pMsgTdlsChanSwitch; + tSirMsgQ msg; + tANI_U16 peerIdx = 0; + tpDphHashNode pStaDs = NULL; + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("TDLS Channel Switch Recieved on peer:" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pTdlsChanSwitch->peerMac)); + + psessionEntry = peFindSessionByBssid(pMac, + pTdlsChanSwitch->bssid, + &sessionId); + if (psessionEntry == NULL) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "PE Session does not exist for given sme sessionId %d", + pTdlsChanSwitch->sessionId); + limSendSmeTdlsChanSwitchReqRsp(pMac, pTdlsChanSwitch->sessionId, + pTdlsChanSwitch->peerMac, + NULL, eSIR_FAILURE) ; + return eSIR_FAILURE; + } + + /* check if we are in proper state to work as TDLS client */ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "TDLS Channel Switch received in wrong system Role %d", + psessionEntry->limSystemRole); + goto lim_tdls_chan_switch_error; + } + + /* + * if we are still good, go ahead and check if we are in proper state to + * do TDLS discovery req/rsp/....frames. + */ + if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) + { + + limLog(pMac, LOGE, "TDLS Channel Switch received in invalid LIMsme state (%d)", + psessionEntry->limSmeState); + goto lim_tdls_chan_switch_error; + } + + pStaDs = dphLookupHashEntry(pMac, pTdlsChanSwitch->peerMac, &peerIdx, + &psessionEntry->dph.dphHashTable) ; + if ( NULL == pStaDs ) + { + limLog( pMac, LOGE, FL( "pStaDs is NULL" )); + goto lim_tdls_chan_switch_error; + + } + pMsgTdlsChanSwitch = vos_mem_malloc(sizeof( tTdlsChanSwitchParams )); + if ( NULL == pMsgTdlsChanSwitch ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory TDLS Channel Switch" )); + return eSIR_MEM_ALLOC_FAILED; + } + + vos_mem_set( (tANI_U8 *)pMsgTdlsChanSwitch, sizeof(*pMsgTdlsChanSwitch), 0); + + /* if channel bw offset is not set, + send maximum supported offset in the band */ + if (pTdlsChanSwitch->tdlsOffChBwOffset == 0) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + ("Set TDLS channel Bw Offset")); + + if ((pTdlsChanSwitch->tdlsOffCh >= 1) && + (pTdlsChanSwitch->tdlsOffCh <= 14)) + { + pTdlsChanSwitch->tdlsOffChBwOffset = BW20; + } + else if ((pTdlsChanSwitch->tdlsOffCh >= 36) && + (pTdlsChanSwitch->tdlsOffCh <= 169)) + { + pTdlsChanSwitch->tdlsOffChBwOffset = + limGetOffChMaxBwOffsetFromChannel( + pMac->scan.countryCodeCurrent, + pTdlsChanSwitch->tdlsOffCh, + pStaDs->mlmStaContext.vhtCapability); + } + } + else + { + /* Channel Bandwidth Offset is set through iwpriv ioctl */ + (pTdlsChanSwitch->tdlsOffChBwOffset)--; + } + + pMsgTdlsChanSwitch->staIdx = pStaDs->staIndex; + pMsgTdlsChanSwitch->tdlsOffCh = pTdlsChanSwitch->tdlsOffCh; + pMsgTdlsChanSwitch->tdlsOffChBwOffset = pTdlsChanSwitch->tdlsOffChBwOffset; + pMsgTdlsChanSwitch->tdlsSwMode = pTdlsChanSwitch->tdlsSwMode; + pMsgTdlsChanSwitch->operClass = limGetOPClassFromChannel( + pMac->scan.countryCodeCurrent, + pTdlsChanSwitch->tdlsOffCh, + pTdlsChanSwitch->tdlsOffChBwOffset); + + if(pMsgTdlsChanSwitch->operClass == 0) + { + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + "Invalid Operating class 0 !!!"); + vos_mem_free(pMsgTdlsChanSwitch); + goto lim_tdls_chan_switch_error; + } + else + { + + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: TDLS Channel Switch params: staIdx %d class %d ch %d bw %d" + " mode %d country code %c%c", + __func__, + pMsgTdlsChanSwitch->staIdx, + pMsgTdlsChanSwitch->operClass, + pMsgTdlsChanSwitch->tdlsOffCh, + pMsgTdlsChanSwitch->tdlsOffChBwOffset, + pMsgTdlsChanSwitch->tdlsSwMode, + pMac->scan.countryCodeCurrent[0], + pMac->scan.countryCodeCurrent[1]); + } + + msg.type = WDA_SET_TDLS_CHAN_SWITCH_REQ; + msg.reserved = 0; + msg.bodyptr = pMsgTdlsChanSwitch; + msg.bodyval = 0; + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + limLog(pMac, LOGE, FL("halPostMsgApi failed\n")); + vos_mem_free(pMsgTdlsChanSwitch); + goto lim_tdls_chan_switch_error; + } + + return eSIR_SUCCESS; + +lim_tdls_chan_switch_error: + limSendSmeTdlsChanSwitchReqRsp(pMac, pTdlsChanSwitch->sessionId, + pTdlsChanSwitch->peerMac, + NULL, eSIR_FAILURE); + return eSIR_FAILURE; +} + +/* + * Set 20_40 BSS Coex IE in TDLS frames. + */ +tSirRetStatus limProcessSmeSetTdls2040BSSCoexReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + tAniSetTdls2040BSSCoex *pmsg = NULL; + pmsg = (tAniSetTdls2040BSSCoex*) pMsgBuf ; + + if (NULL != pmsg) { + pMac->lim.EnableTdls2040BSSCoexIE = pmsg->SetTdls2040BSSCoex; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: 20_40 BSS Coex IE in TDLS frames " + "pMac->lim.EnableTdls2040BSSCoexIE %d ", __func__, + pMac->lim.EnableTdls2040BSSCoexIE); + + return eSIR_SUCCESS; +} + +tSirRetStatus limProcessSmeDelAllTdlsPeers(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf) +{ + tSirDelAllTdlsPeers *pMsg = NULL; + tpDphHashNode pStaDs = NULL ; + tpPESession psessionEntry = NULL; + uint8_t sessionId; + int i, aid; + pMsg = (tSirDelAllTdlsPeers*) pMsgBuf ; + + if (pMsg == NULL) { + limLog(pMac, LOGE, FL("NULL pMsg")); + return eSIR_FAILURE; + } + + psessionEntry = peFindSessionByBssid(pMac, pMsg->bssid, &sessionId); + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("NULL psessionEntry")); + return eSIR_FAILURE; + } + + /* Check all the set bit in peerAIDBitmap and delete the + * peer (with that aid) entry from the hash table and add + * the aid in free pool + */ + for (i = 0; i < sizeof(psessionEntry->peerAIDBitmap)/sizeof(tANI_U32); i++) + { + for (aid = 0; aid < (sizeof(tANI_U32) << 3); aid++) + { + if (CHECK_BIT(psessionEntry->peerAIDBitmap[i], aid)) + { + pStaDs = dphGetHashEntry(pMac, + (aid + i*(sizeof(tANI_U32) << 3)), + &psessionEntry->dph.dphHashTable); + if (NULL != pStaDs) + { + limLog(pMac, LOGE, FL("Deleting "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pStaDs->staAddr)); + + limSendDeauthMgmtFrame(pMac, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + pStaDs->staAddr, psessionEntry, + FALSE); + + limTdlsDelSta(pMac, pStaDs->staAddr, psessionEntry); + + dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, + &psessionEntry->dph.dphHashTable); + } + limReleasePeerIdx(pMac, (aid + i*(sizeof(tANI_U32) << 3)), + psessionEntry) ; + CLEAR_BIT(psessionEntry->peerAIDBitmap[i], aid); + } + } + } + + return eSIR_SUCCESS; +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c new file mode 100644 index 000000000000..bd695ed92526 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limPropExtsUtils.cc contains the utility functions + * to populate, parse proprietary extensions required to + * support ANI feature set. + * + * Author: Chandra Modumudi + * Date: 11/27/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "aniGlobal.h" +#include "wniCfg.h" +#include "sirCommon.h" +#include "sirDebug.h" +#include "utilsApi.h" +#include "cfgApi.h" +#include "limApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limPropExtsUtils.h" +#include "limSerDesUtils.h" +#include "limTrace.h" +#include "limSession.h" +#define LIM_GET_NOISE_MAX_TRY 5 +#define LIM_OPERATING_EXT_IDENTIFIER 201 +/** + * limExtractApCapability() + * + *FUNCTION: + * This function is called to extract AP's HCF/WME/WSM capability + * from the IEs received from it in Beacon/Probe Response frames + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pIE Pointer to starting IE in Beacon/Probe Response + * @param ieLen Length of all IEs combined + * @param qosCap Bits are set according to capabilities + * @return 0 - If AP does not assert HCF capability & 1 - otherwise + */ +void +limExtractApCapability(tpAniSirGlobal pMac, tANI_U8 *pIE, tANI_U16 ieLen, + tANI_U8 *qosCap, tANI_U16 *propCap, tANI_U8 *uapsd, + tPowerdBm *localConstraint, + tpPESession psessionEntry + ) +{ + tSirProbeRespBeacon *pBeaconStruct; +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPowerConstraints = 0; +#endif + + pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + + if ( NULL == pBeaconStruct ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limExtractApCapability") ); + return; + } + + vos_mem_set( (tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0); + *qosCap = 0; + *propCap = 0; + *uapsd = 0; + PELOG3(limLog( pMac, LOG3, + FL("In limExtractApCapability: The IE's being received are:")); + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen );) + if (sirParseBeaconIE(pMac, pBeaconStruct, pIE, (tANI_U32)ieLen) == eSIR_SUCCESS) + { + if (pBeaconStruct->wmeInfoPresent || pBeaconStruct->wmeEdcaPresent + || pBeaconStruct->HTCaps.present) + LIM_BSS_CAPS_SET(WME, *qosCap); + if (LIM_BSS_CAPS_GET(WME, *qosCap) && pBeaconStruct->wsmCapablePresent) + LIM_BSS_CAPS_SET(WSM, *qosCap); + if (pBeaconStruct->propIEinfo.aniIndicator && + pBeaconStruct->propIEinfo.capabilityPresent) + *propCap = pBeaconStruct->propIEinfo.capability; + if (pBeaconStruct->HTCaps.present) + pMac->lim.htCapabilityPresentInBeacon = 1; + else + pMac->lim.htCapabilityPresentInBeacon = 0; + +#ifdef WLAN_FEATURE_11AC + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***beacon.VHTCaps.present*****=%d BSS_VHT_CAPABLE:%d", + pBeaconStruct->VHTCaps.present, + IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps)); + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO_MED, + "***beacon.SU Beamformer Capable*****=%d",pBeaconStruct->VHTCaps.suBeamFormerCap); + + if (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) + && pBeaconStruct->VHTOperation.present) + { + psessionEntry->vhtCapabilityPresentInBeacon = 1; + psessionEntry->apCenterChan = pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + psessionEntry->apChanWidth = pBeaconStruct->VHTOperation.chanWidth; + } + else + { + psessionEntry->vhtCapabilityPresentInBeacon = 0; + } +#endif + // Extract the UAPSD flag from WMM Parameter element + if (pBeaconStruct->wmeEdcaPresent) + *uapsd = pBeaconStruct->edcaParams.qosInfo.uapsd; + + /* Get MaxTxPwr from country IE if present. + If the channel number field has a positive integer value less + than 201, then it contains a positive integer value that indicates + the lowest channel number in the subband */ + + if (pBeaconStruct->countryInfoPresent && + pBeaconStruct->countryInfoParam.channelTransmitPower[0].channelNumber < LIM_OPERATING_EXT_IDENTIFIER ) + { + int i; + tANI_U8 firstChannel =0, numChannels =0; + tANI_U8 channel = psessionEntry->currentOperChannel; + + for (i=0; i < pBeaconStruct->countryInfoParam.numIntervals; ++i) + { + if (i >= COUNTRY_INFO_MAX_CHANNEL) + break; + + firstChannel = pBeaconStruct->countryInfoParam.channelTransmitPower[i].channelNumber; + numChannels = pBeaconStruct->countryInfoParam.channelTransmitPower[i].numChannel; + + if ((channel >= firstChannel) && + (channel < (firstChannel + numChannels))) + break; + } + + if (i < pBeaconStruct->countryInfoParam.numIntervals && i < COUNTRY_INFO_MAX_CHANNEL) + { + *localConstraint = pBeaconStruct->countryInfoParam.channelTransmitPower[i].maxTransmitPower; + } + } +#if defined FEATURE_WLAN_ESE + /* If there is Power Constraint Element specifically, + * adapt to it. Hence there is else condition check + * for this if statement. + */ + if ( pBeaconStruct->eseTxPwr.present) + { + *localConstraint = pBeaconStruct->eseTxPwr.power_limit; + } +#endif + if (pBeaconStruct->powerConstraintPresent) + { + *localConstraint -= pBeaconStruct->localPowerConstraint.localPowerConstraints; + } +#if !defined WLAN_FEATURE_VOWIFI + localPowerConstraints = (tANI_U32)pBeaconStruct->localPowerConstraint.localPowerConstraints; + if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, localPowerConstraints) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not update local power constraint to cfg.")); + } +#endif + psessionEntry->countryInfoPresent = FALSE; /* Initializing before first use */ + if (pBeaconStruct->countryInfoPresent) + { + psessionEntry->countryInfoPresent = TRUE; + } + /* Save the Extended caps from AP in probe resp or beacon */ + if (pBeaconStruct->ExtCap.present) + { + vos_mem_copy(&psessionEntry->ExtCap, &pBeaconStruct->ExtCap, sizeof(tDot11fIEExtCap)); + } + + } + + /* Update HS 2.0 Information Element */ + sir_copy_hs20_ie(&psessionEntry->hs20vendor_ie, + &pBeaconStruct->hs20vendor_ie); + vos_mem_free(pBeaconStruct); + return; +} /****** end limExtractApCapability() ******/ + +/** + * limGetHTCBState + * + *FUNCTION: + * This routing provides the translation of Airgo Enum to HT enum for determining + * secondary channel offset. + * Airgo Enum is required for backward compatibility purposes. + * + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return The corresponding HT enumeration + */ +ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode) +{ + switch ( aniCBMode ) + { +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: +#endif + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: +#endif + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return PHY_SINGLE_CHANNEL_CENTERED; +#endif + default : + return PHY_SINGLE_CHANNEL_CENTERED; + } +} + + /* + * limGetStaPeerType + * + *FUNCTION: + * Based on a combination of the following - + * 1) tDphHashNode.aniPeer + * 2) tDphHashNode.propCapability + * this API determines if a given STA is an ANI peer or not + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pStaDs - Pointer to the tpDphHashNode of the STA + * under consideration + * @return tStaRateMode + */ +tStaRateMode limGetStaPeerType( tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tpPESession psessionEntry) +{ +tStaRateMode staPeerType = eSTA_11b; + // Determine the peer-STA type + if( pStaDs->aniPeer ) + { + if(PROP_CAPABILITY_GET( TAURUS, pStaDs->propCapability )) + staPeerType = eSTA_TAURUS; + else if( PROP_CAPABILITY_GET( TITAN, pStaDs->propCapability )) + staPeerType = eSTA_TITAN; + else + staPeerType = eSTA_POLARIS; + } +#ifdef WLAN_FEATURE_11AC + else if(pStaDs->mlmStaContext.vhtCapability) + staPeerType = eSTA_11ac; +#endif + else if(pStaDs->mlmStaContext.htCapability) + staPeerType = eSTA_11n; + else if(pStaDs->erpEnabled) + staPeerType = eSTA_11bg; + else if(psessionEntry->limRFBand == SIR_BAND_5_GHZ) + staPeerType = eSTA_11a; + return staPeerType; +} + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.h new file mode 100644 index 000000000000..f14dfd45b0fd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limPropExtsUtils.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limPropExtsUtils.h contains the definitions + * used by all LIM modules to support proprietary features. + * Author: Chandra Modumudi + * Date: 12/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_PROP_EXTS_UTILS_H +#define __LIM_PROP_EXTS_UTILS_H + + +// Function templates +void limQuietBss(tpAniSirGlobal, tANI_U32); +void limCleanupMeasData(tpAniSirGlobal); +void limDeleteMeasTimers(tpAniSirGlobal); +void limStopMeasTimers(tpAniSirGlobal pMac); +void limCleanupMeasResources(tpAniSirGlobal); +void limRestorePreLearnState(tpAniSirGlobal); +void limCollectMeasurementData(tpAniSirGlobal, + tANI_U32 *, tpSchBeaconStruct); +void limCollectRSSI(tpAniSirGlobal); +void limDeleteCurrentBssWdsNode(tpAniSirGlobal); +tANI_U32 limComputeAvg(tpAniSirGlobal, tANI_U32, tANI_U32); + + +/// Function to extract AP's HCF capability from IE fields +void limExtractApCapability(tpAniSirGlobal, tANI_U8 *, tANI_U16, tANI_U8 *, tANI_U16 *, tANI_U8 *, tPowerdBm*, tpPESession); + +tStaRateMode limGetStaPeerType( tpAniSirGlobal, tpDphHashNode ,tpPESession); +#ifdef WLAN_FEATURE_11AC +ePhyChanBondState limGetHTCBState(ePhyChanBondState aniCBMode) ; +#endif + + +#endif /* __LIM_PROP_EXTS_UTILS_H */ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.c new file mode 100644 index 000000000000..86b302e2a0f7 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.c @@ -0,0 +1,1382 @@ +/* + * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limRMC.c contains the code + * for processing RMC messages + * + */ +#include "wniApi.h" +#include "wniCfg.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limTimerUtils.h" +#include "limSendMessages.h" +#include "limSendMessages.h" +#include "limSession.h" +#include "limSessionUtils.h" +#include "wlan_qct_wda.h" +#include "wlan_qct_tli.h" +#include "limRMC.h" + +#ifdef WLAN_FEATURE_RMC + +static tANI_U8 +__rmcGroupHashFunction(tSirMacAddr transmitter) +{ + tANI_U16 hash; + + /* + * Generate a hash using transmitter address + */ + hash = transmitter[0] + transmitter[1] + transmitter[2] + + transmitter[3] + transmitter[4] + transmitter[5]; + + return hash & (RMC_MCAST_GROUPS_HASH_SIZE - 1); +} + + +static tLimRmcGroupContext * +__rmcGroupLookupHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter) +{ + tANI_U8 index; + tLimRmcGroupContext *entry; + + index = __rmcGroupHashFunction(transmitter); + + /* Pick the correct hash table based on role */ + entry = pMac->rmcContext.rmcGroupRxHashTable[index]; + + PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Lookup:[%d] transmitter " + MAC_ADDRESS_STR ), index, + MAC_ADDR_ARRAY(transmitter));) + while (entry) + { + if (vos_mem_compare(transmitter, entry->transmitter, + sizeof(v_MACADDR_t))) + { + return entry; + } + + entry = entry->next; + } + + return NULL; +} + +static tLimRmcGroupContext * +__rmcGroupInsertHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter) +{ + tANI_U8 index; + tLimRmcGroupContext *entry; + tLimRmcGroupContext **head; + + index = __rmcGroupHashFunction(transmitter); + + PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:[%d] group " MAC_ADDRESS_STR + " transmitter " MAC_ADDRESS_STR), index, + MAC_ADDR_ARRAY(mcastGroupAddr), + MAC_ADDR_ARRAY(transmitter));) + + head = &pMac->rmcContext.rmcGroupRxHashTable[index]; + + entry = __rmcGroupLookupHashEntry(pMac, transmitter); + + if (entry) + { + /* If the entry exists, return it at the end */ + PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:" + MAC_ADDRESS_STR "exists"), MAC_ADDR_ARRAY(transmitter));) + } + else + { + entry = (tLimRmcGroupContext *)vos_mem_malloc(sizeof(*entry)); + + PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Insert:new entry %p"), entry);) + + if (entry) + { + vos_mem_copy(entry->transmitter, transmitter, sizeof(tSirMacAddr)); + entry->isRuler = eRMC_IS_NOT_A_RULER; + + /* chain this entry */ + entry->next = *head; + *head = entry; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Hash Insert:" MAC_ADDRESS_STR + " alloc failed"), MAC_ADDR_ARRAY(transmitter));) + } + } + + return entry; +} + +/** + * __rmcGroupDeleteHashEntry() + * + *FUNCTION: + * This function is called to delete a RMC group entry + * + *LOGIC: + * + *ASSUMPTIONS: + * Should be called with lkRmcLock held. + * + *NOTE: + * Make sure (for the transmitter role) that the entry is + * not in the Pending Response queue. + * + * @param transmitter - address of multicast transmitter + * + * @return status + */ +static tSirRetStatus +__rmcGroupDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr transmitter) +{ + tSirRetStatus status = eSIR_FAILURE; + tANI_U8 index; + tLimRmcGroupContext *entry, *prev, **head; + + index = __rmcGroupHashFunction(transmitter); + + head = &pMac->rmcContext.rmcGroupRxHashTable[index]; + entry = *head; + prev = NULL; + + while (entry) + { + if (vos_mem_compare(transmitter, entry->transmitter, + sizeof(v_MACADDR_t))) + { + if (*head == entry) + { + *head = entry->next; + } + else + { + prev->next = entry->next; + } + + PELOG1(limLog(pMac, LOG1, FL("RMC: Hash Delete: entry %p " + " transmitter " MAC_ADDRESS_STR), entry + MAC_ADDR_ARRAY(transmitter));) + + /* free the group entry */ + vos_mem_free(entry); + + status = eSIR_SUCCESS; + break; + } + + prev = entry; + entry = entry->next; + } + + return status; +} + +static void +__rmcGroupDeleteAllEntries(tpAniSirGlobal pMac) +{ + tLimRmcGroupContext *entry, **head; + int index; + + PELOG1(limLog(pMac, LOG1, FL("RMC: Hash_Delete_All"),);) + + for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++) + { + head = &pMac->rmcContext.rmcGroupRxHashTable[index]; + + entry = *head; + + while (entry) + { + *head = entry->next; + /* free the group entry */ + vos_mem_free(entry); + entry = *head; + } + } +} + +static void +__limPostMsgRulerReq ( tpAniSirGlobal pMac, + tANI_U8 cmd, + tSirMacAddr mcastTransmitter) +{ + tSirMsgQ msg; + tSirRmcRulerReq *pRulerReq; + + pRulerReq = vos_mem_malloc(sizeof(*pRulerReq)); + if (NULL == pRulerReq) + { + limLog(pMac, LOGE, FL("AllocateMemory() failed")); + return; + } + + pRulerReq->cmd = cmd; + + vos_mem_copy(pRulerReq->mcastTransmitter, mcastTransmitter, + sizeof(tSirMacAddr)); + + /* Initialize black list */ + vos_mem_zero(pRulerReq->blacklist, sizeof(pRulerReq->blacklist)); + + if (eRMC_SUGGEST_RULER_CMD == cmd) + { + /* TODO - Set the black list. */ + } + + msg.type = WDA_RMC_RULER_REQ; + msg.bodyptr = pRulerReq; + msg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + vos_mem_free(pRulerReq); + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed")); + } + + return; +} + +static void +__limPostMsgUpdateInd ( tpAniSirGlobal pMac, + tANI_U8 indication, + tANI_U8 role, + tSirMacAddr mcastTransmitter, + tSirMacAddr mcastRuler) +{ + tSirMsgQ msg; + tSirRmcUpdateInd *pUpdateInd; + + pUpdateInd = vos_mem_malloc(sizeof(*pUpdateInd)); + if ( NULL == pUpdateInd ) + { + limLog(pMac, LOGE, FL("AllocateMemory() failed")); + return; + } + + vos_mem_zero(pUpdateInd, sizeof(*pUpdateInd)); + + pUpdateInd->indication = indication; + pUpdateInd->role = role; + + vos_mem_copy(pUpdateInd->mcastTransmitter, + mcastTransmitter, sizeof(tSirMacAddr)); + + vos_mem_copy(pUpdateInd->mcastRuler, + mcastRuler, sizeof(tSirMacAddr)); + + msg.type = WDA_RMC_UPDATE_IND; + msg.bodyptr = pUpdateInd; + msg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + if (eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + vos_mem_free(pUpdateInd); + limLog(pMac, LOGE, FL("wdaPostCtrlMsg() failed")); + } + + return; +} + +static char * +__limRulerMessageToString(eRmcMessageType msgType) +{ + switch (msgType) + { + default: + return "Invalid"; + case eLIM_RMC_ENABLE_REQ: + return "RMC_ENABLE_REQ"; + case eLIM_RMC_DISABLE_REQ: + return "RMC_DISABLE_REQ"; + case eLIM_RMC_RULER_SELECT_RESP: + return "RMC_RULER_SELECT_RESP"; + case eLIM_RMC_RULER_PICK_NEW: + return "RMC_RULER_PICK_NEW"; + case eLIM_RMC_OTA_RULER_INFORM_ACK: + return "RMC_OTA_RULER_INFORM_ACK"; + case eLIM_RMC_OTA_RULER_INFORM_SELECTED: + return "RMC_OTA_RULER_INFORM_SELECTED"; + case eLIM_RMC_BECOME_RULER_RESP: + return "RMC_BECOME_RULER_RESP"; + case eLIM_RMC_OTA_RULER_INFORM_CANCELLED: + return "RMC_OTA_RULER_INFORM_CANCELLED"; + } +} + +static char * +__limRulerStateToString(eRmcRulerState state) +{ + switch (state) + { + default: + return "Invalid"; + case eRMC_IS_NOT_A_RULER: + return "Device Not a Ruler"; + case eRMC_RULER_PENDING: + return "Pending firmware resp"; + case eRMC_IS_A_RULER: + return "Device is Ruler"; + } +} + +static char * +__limMcastTxStateToString(eRmcMcastTxState state) +{ + switch (state) + { + default: + return "Invalid"; + case eRMC_RULER_NOT_SELECTED: + return "Not Selected"; + case eRMC_RULER_ENABLE_REQUESTED: + return "Enable Requested"; + case eRMC_RULER_OTA_REQUEST_SENT: + return "OTA Request Sent"; + case eRMC_RULER_ACTIVE: + return "Active"; + } +} + +/** + * __rmcRulerSelectTimerHandler() + * + *FUNCTION: + * This function is called upon timer expiry. + * + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * Only one entry is processed for every invocation if this routine. + * This allows us to use a single timer and makes sure we do not + * timeout a request too early. + * + * @param param - Message corresponding to the timer that expired + * + * @return None + */ + +void +__rmcRulerSelectTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 }; + tSirRetStatus status; + tSirRMCInfo RMC; + tpPESession psessionEntry; + tANI_U32 cfgValue; + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:__rmcRulerSelectTimerHandler:No active IBSS"));) + return; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get Action Period Frequency value + * from CFG. Log error. + */ + limLog(pMac, LOGE, FL("could not retrieve ActionPeriodFrequency")); + } + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (pMac->rmcContext.rmcTimerValInTicks != cfgValue) + { + limLog(pMac, LOG1, FL("RMC RulerSelect timer value changed")); + if (tx_timer_change(&pMac->rmcContext.gRmcRulerSelectTimer, + cfgValue, 0) != TX_SUCCESS) + { + limLog(pMac, LOGE, + FL("Unable to change RulerSelect Timer val")); + } + pMac->rmcContext.rmcTimerValInTicks = cfgValue; + } + + /* + * If we are in the scanning state then we need to return + * from this function without any further processing + */ + if (eLIM_HAL_SCANNING_STATE == pMac->lim.gLimHalScanState) + { + limLog(pMac, LOG1, FL("In scanning state, can't send action frm")); + if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer) != + TX_SUCCESS) + { + limLog(pMac, LOGE, FL("In scanning state, " + "couldn't activate RMC RulerSelect timer")); + } + return; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("__rmcRulerSelectTimerHandler lock acquire failed")); + if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not activate RMC RulerSelect timer")); + } + return; + } + + vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler, + sizeof(tSirMacAddr)); + + if (VOS_FALSE == vos_mem_compare(&zeroMacAddr, + &pMac->rmcContext.ruler, sizeof(tSirMacAddr))) + { + limLog(pMac, LOG1, + FL("RMC Periodic Ruler_Select Ruler " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMac->rmcContext.ruler)); + /* + * Re-arm timer + */ + if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= + TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not activate RMC Response timer")); + } + + if (!VOS_IS_STATUS_SUCCESS + (vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: __rmcRulerSelectTimerHandler lock release failed")); + } + } + else + { + limLog(pMac, LOGE, + FL("RMC Deactivating timer because no ruler was selected")); + + if (!VOS_IS_STATUS_SUCCESS + (vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: __rmcRulerSelectTimerHandler lock release failed")); + } + + return; + } + + RMC.dialogToken = 0; + RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED; + + status = limSendRMCActionFrame(pMac, + SIR_MAC_RMC_MCAST_ADDRESS, + &RMC, + psessionEntry); + + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:__rmcRulerSelectTimerHandler Action frame send failed"));) + } + + return; +} + +static void +__limProcessRMCEnableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf; + tpPESession psessionEntry; + + if (!setRmcReq) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Enable:NULL message") );) + return; + } + + pMac->rmcContext.rmcEnabled = TRUE; + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Enable RMC request no active IBSS"));) + pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED; + return; + } + + /* Send RULER_REQ to f/w */ + __limPostMsgRulerReq(pMac, eRMC_SUGGEST_RULER_CMD, + setRmcReq->mcastTransmitter); + + pMac->rmcContext.state = eRMC_RULER_ENABLE_REQUESTED; +} + +static void +__limProcessRMCDisableRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpPESession psessionEntry; + tSirRMCInfo RMC; + tSirSetRMCReq *setRmcReq = (tSirSetRMCReq *)pMsgBuf; + tSirRetStatus status; + v_PVOID_t pvosGCtx; + VOS_STATUS vos_status; + v_MACADDR_t vosMcastTransmitter; + + pMac->rmcContext.rmcEnabled = FALSE; + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:No active IBSS"));) + return; + } + + if (!setRmcReq) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Disable:NULL message") );) + return; + } + + /* Cancel pending timer */ + tx_timer_deactivate(&pMac->rmcContext.gRmcRulerSelectTimer); + + vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0]; + vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1]; + vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2]; + vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3]; + vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4]; + vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5]; + + pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + vos_status = WLANTL_DisableRMC(pvosGCtx, &vosMcastTransmitter); + + if (VOS_STATUS_SUCCESS != vos_status) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: TL disable failed"));) + } + + if (pMac->rmcContext.state == eRMC_RULER_ACTIVE) + { + RMC.dialogToken = 0; + RMC.action = SIR_MAC_RMC_RULER_INFORM_CANCELLED; + vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler, sizeof(tSirMacAddr)); + + status = limSendRMCActionFrame(pMac, pMac->rmcContext.ruler, + &RMC, psessionEntry); + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Disable: Action frame send failed"));) + } + + pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED; + } + + __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED, eRMC_TRANSMITTER_ROLE, + setRmcReq->mcastTransmitter, pMac->rmcContext.ruler); + + vos_mem_zero(pMac->rmcContext.ruler, sizeof(tSirMacAddr)); + +} + +static void +__limProcessRMCRulerSelectResponse(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirRmcRulerSelectInd *pRmcRulerSelectInd; + tpPESession psessionEntry; + tSirRetStatus status; + v_PVOID_t pvosGCtx; + VOS_STATUS vos_status; + v_MACADDR_t vosMcastTransmitter; + tSirRMCInfo RMC; + + if (NULL == pMsgBuf) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp:NULL message"));) + return; + } + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:No active IBSS"));) + pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED; + return; + } + + pRmcRulerSelectInd = (tSirRmcRulerSelectInd *)pMsgBuf; + + if (pMac->rmcContext.state != eRMC_RULER_ENABLE_REQUESTED) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp:Bad state %s"), + __limMcastTxStateToString(pMac->rmcContext.state) );) + return; + } + + if (pRmcRulerSelectInd->status) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:FW Status %d"), + pRmcRulerSelectInd->status);) + pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED; + return; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, FL("RMC:Ruler_Select_Resp:lock acquire failed")); + pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED; + return; + } + + vos_mem_copy(&pMac->rmcContext.ruler, &pRmcRulerSelectInd->ruler[0], + sizeof(tSirMacAddr)); + + if (!VOS_IS_STATUS_SUCCESS + (vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, FL("RMC: Ruler_Select_Resp: lock release failed")); + } + + RMC.dialogToken = 0; + RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED; + vos_mem_copy(&RMC.mcastRuler, &pRmcRulerSelectInd->ruler[0], + sizeof(tSirMacAddr)); + + PELOG1(limLog(pMac, LOG1, FL("RMC: Ruler_Select :ruler " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pRmcRulerSelectInd->ruler[0]));) + + status = limSendRMCActionFrame(pMac, + SIR_MAC_RMC_MCAST_ADDRESS, + &RMC, + psessionEntry); + + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Ruler_Select_Resp: Action send failed"));) + } + + __limPostMsgUpdateInd(pMac, eRMC_RULER_ACCEPTED, eRMC_TRANSMITTER_ROLE, + psessionEntry->selfMacAddr, pMac->rmcContext.ruler); + + vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0]; + vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1]; + vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2]; + vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3]; + vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4]; + vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5]; + + /* Enable TL */ + pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + vos_status = WLANTL_EnableRMC(pvosGCtx, &vosMcastTransmitter); + + pMac->rmcContext.state = eRMC_RULER_ACTIVE; + + if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGE, + FL("Ruler_Select_Resp:Activate RMC Response timer failed")); + } +} + +static void +__limProcessRMCRulerPickNew(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirRmcUpdateInd *pRmcUpdateInd; + tpPESession psessionEntry; + tSirRetStatus status; + tSirRMCInfo RMC; + v_PVOID_t pvosGCtx; + VOS_STATUS vos_status; + v_MACADDR_t vosMcastTransmitter; + tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 }; + + if (NULL == pMsgBuf) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Pick_New:NULL message"));) + return; + } + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Pick_New:No active IBSS"));) + return; + } + + pvosGCtx = vos_get_global_context(VOS_MODULE_ID_PE, (v_VOID_t *) pMac); + + pRmcUpdateInd = (tSirRmcUpdateInd *)pMsgBuf; + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, FL("RMC:Ruler_Pick_New:lock acquire failed")); + return; + } + + + /* Fill out Action frame parameters */ + RMC.dialogToken = 0; + + if (VOS_FALSE == vos_mem_compare(&zeroMacAddr, + &pRmcUpdateInd->mcastRuler, + sizeof(tSirMacAddr))) + { + + vos_mem_copy(&RMC.mcastRuler, &pRmcUpdateInd->mcastRuler, + sizeof(tSirMacAddr)); + + RMC.action = SIR_MAC_RMC_RULER_INFORM_CANCELLED; + status = limSendRMCActionFrame(pMac, + pRmcUpdateInd->mcastRuler, + &RMC, psessionEntry); + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:Ruler_Pick_New: Inform_Cancel Action send failed"));) + goto done; + } + + vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0]; + vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1]; + vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2]; + vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3]; + vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4]; + vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5]; + + vos_status = WLANTL_DisableRMC(pvosGCtx, &vosMcastTransmitter); + + if (VOS_STATUS_SUCCESS != vos_status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:Ruler_Pick_New: TL disable failed"));) + } + } + + vos_mem_copy(pMac->rmcContext.ruler, pRmcUpdateInd->ruler[0], + sizeof(tSirMacAddr)); + + pMac->rmcContext.state = eRMC_RULER_NOT_SELECTED; + + if (VOS_TRUE == vos_mem_compare(&zeroMacAddr, + pMac->rmcContext.ruler, + sizeof(tSirMacAddr))) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:Ruler_Pick_New: No candidate rulers available"));) + goto done; + } + + + RMC.action = SIR_MAC_RMC_RULER_INFORM_SELECTED; + vos_mem_copy(&RMC.mcastRuler, &pMac->rmcContext.ruler, + sizeof(tSirMacAddr)); + status = limSendRMCActionFrame(pMac, SIR_MAC_RMC_MCAST_ADDRESS, + &RMC, psessionEntry); + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:Ruler_Pick_New: Inform_Selected Action send failed"));) + goto done; + } + + __limPostMsgUpdateInd(pMac, eRMC_RULER_ACCEPTED, eRMC_TRANSMITTER_ROLE, + psessionEntry->selfMacAddr, pMac->rmcContext.ruler); + + vosMcastTransmitter.bytes[0] = psessionEntry->selfMacAddr[0]; + vosMcastTransmitter.bytes[1] = psessionEntry->selfMacAddr[1]; + vosMcastTransmitter.bytes[2] = psessionEntry->selfMacAddr[2]; + vosMcastTransmitter.bytes[3] = psessionEntry->selfMacAddr[3]; + vosMcastTransmitter.bytes[4] = psessionEntry->selfMacAddr[4]; + vosMcastTransmitter.bytes[5] = psessionEntry->selfMacAddr[5]; + + /* Enable TL */ + vos_status = WLANTL_EnableRMC(pvosGCtx, &vosMcastTransmitter); + + if (VOS_STATUS_SUCCESS != vos_status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:Ruler_Pick_New: TL enable failed"));) + goto done; + } + + pMac->rmcContext.state = eRMC_RULER_ACTIVE; + + if (tx_timer_activate(&pMac->rmcContext.gRmcRulerSelectTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGE, + FL("Ruler_Pick_New:Activate RMC Response timer failed")); + } + +done: + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: Ruler_Pick_New: lock release failed")); + } +} + +static void +__limProcessRMCRulerInformSelected(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pFrameData; + tANI_U32 frameLen; + tLimRmcGroupContext *entry; + tpPESession psessionEntry; + tSirRetStatus status; + + if (!pMsgBuf) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform:NULL msg"));) + return; + } + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:No active IBSS"));) + return; + } + + /* + * Get the frame header + */ + pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf); + + frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf); + if (frameLen < sizeof(tSirMacIbssExtNetworkFrameHdr)) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Ruler_Inform:Bad length %d "), frameLen);) + return; + } + + pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) + + sizeof(tSirMacIbssExtNetworkFrameHdr); + + if (!pFrameData) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform:NULL data"));) + return; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:lock acquire failed")); + return; + } + + /* + * Check if this transmitter exists in our database. + */ + entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa); + + if (VOS_FALSE == vos_mem_compare(pFrameData, psessionEntry->selfMacAddr, + sizeof(tSirMacAddr))) + { + if (entry) + { + PELOG1(limLog(pMac, LOG1, + FL("RMC: Ruler_Inform: Ruler Cancelled"));) + + __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED, + eRMC_RULER_ROLE, pHdr->sa, psessionEntry->selfMacAddr); + + /* + * Delete hash entry for this Group address. + */ + status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa); + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Ruler_Inform:hash delete failed"));) + } + } + } + else + { + if (NULL == entry) + { + /* Add the transmitter address to the hash */ + entry = __rmcGroupInsertHashEntry(pMac, pHdr->sa); + if (entry) + { + if (entry->isRuler != eRMC_RULER_PENDING) + { + __limPostMsgRulerReq(pMac, eRMC_BECOME_RULER_CMD, + pHdr->sa); + entry->isRuler = eRMC_RULER_PENDING; + } + } + else + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Ruler_Inform:Hash insert failed"));) + } + + } + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: Ruler_Inform: lock release failed")); + } + +} + +static void +__limProcessRMCBecomeRulerResp(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirRmcBecomeRulerInd *pRmcBecomeRulerInd; + tLimRmcGroupContext *entry; + tSirRetStatus status = eSIR_SUCCESS; + + if (NULL == pMsgBuf) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp:NULL message"));) + return; + } + + pRmcBecomeRulerInd = (tSirRmcBecomeRulerInd *)pMsgBuf; + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:lock acquire failed")); + return; + } + + /* + * Find the entry for this Group Address. + */ + entry = __rmcGroupLookupHashEntry(pMac, + pRmcBecomeRulerInd->mcastTransmitter); + if (NULL == entry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp: No entry"));) + goto done; + } + + if (pRmcBecomeRulerInd->status) + { + PELOGE(limLog(pMac, LOGE, FL("RMC:Become_Ruler_Resp:FW Status %d"), + pRmcBecomeRulerInd->status);) + status = eSIR_FAILURE; + goto done; + } + + if (entry->isRuler != eRMC_RULER_PENDING) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Become_Ruler_Resp:Bad state: %s"), + __limRulerStateToString(entry->isRuler) );) + status = eSIR_FAILURE; + goto done; + } + + entry->isRuler = eRMC_IS_A_RULER; + +done: + if (eSIR_FAILURE == status) + { + status = __rmcGroupDeleteHashEntry(pMac, + pRmcBecomeRulerInd->mcastTransmitter); + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Become_Ruler_Resp:hash delete failed"));) + } + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: Become_Ruler_Resp: lock release failed")); + } + + return; +} + +static void +__limProcessRMCRulerInformCancelled(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tpSirMacMgmtHdr pHdr; + tANI_U8 *pFrameData; + tANI_U32 frameLen; + tSirRetStatus status; + tLimRmcGroupContext *entry; + tpPESession psessionEntry; + + if (!pMsgBuf) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel:NULL msg"));) + return; + } + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC:Ruler_Inform_Cancel:No active IBSS"));) + return; + } + + pHdr = WDA_GET_RX_MAC_HEADER((tANI_U8 *)pMsgBuf); + + frameLen = WDA_GET_RX_PAYLOAD_LEN((tANI_U8 *)pMsgBuf); + if (frameLen < sizeof(tSirMacIbssExtNetworkFrameHdr)) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Ruler_Inform:Bad length %d "), frameLen);) + return; + } + + pFrameData = WDA_GET_RX_MPDU_DATA((tANI_U8 *)pMsgBuf) + + sizeof(tSirMacIbssExtNetworkFrameHdr); + + if (!pFrameData) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel:NULL data"));) + return; + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, FL("RMC:Ruler_Inform_Cancel lock acquire failed")); + return; + } + + /* + * Find the entry for this Group Address. + */ + entry = __rmcGroupLookupHashEntry(pMac, pHdr->sa); + if (NULL == entry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Ruler_Inform_Cancel: No entry"));) + goto done; + } + + __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED, + eRMC_RULER_ROLE, pHdr->sa, psessionEntry->selfMacAddr); + + /* + * Delete hash entry for this Group address. + */ + status = __rmcGroupDeleteHashEntry(pMac, pHdr->sa); + if (eSIR_FAILURE == status) + { + PELOGE(limLog(pMac, LOGE, + FL("RMC: Ruler_Inform_Cancel:hash delete failed"));) + } + +done: + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: Ruler_Inform_Cancel: lock release failed")); + } + return; +} + +void +limProcessRMCMessages(tpAniSirGlobal pMac, eRmcMessageType msgType, + tANI_U32 *pMsgBuf) +{ + + if (pMsgBuf == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: Buffer is Pointing to NULL"));) + return; + } + + limLog(pMac, LOG1, FL("RMC: limProcessRMCMessages: %s"), + __limRulerMessageToString(msgType)); + + switch (msgType) + { + case eLIM_RMC_ENABLE_REQ: + __limProcessRMCEnableRequest(pMac, pMsgBuf); + break; + + case eLIM_RMC_DISABLE_REQ: + __limProcessRMCDisableRequest(pMac, pMsgBuf); + break; + + case eLIM_RMC_RULER_SELECT_RESP: + __limProcessRMCRulerSelectResponse(pMac, pMsgBuf); + break; + + case eLIM_RMC_RULER_PICK_NEW: + __limProcessRMCRulerPickNew(pMac, pMsgBuf); + break; + + case eLIM_RMC_OTA_RULER_INFORM_SELECTED: + __limProcessRMCRulerInformSelected(pMac, pMsgBuf); + break; + + case eLIM_RMC_BECOME_RULER_RESP: + __limProcessRMCBecomeRulerResp(pMac, pMsgBuf); + break; + + case eLIM_RMC_OTA_RULER_INFORM_CANCELLED: + __limProcessRMCRulerInformCancelled(pMac, pMsgBuf); + break; + + + default: + break; + } // switch (msgType) + return; +} /*** end limProcessRMCMessages() ***/ + +void +limRmcInit(tpAniSirGlobal pMac) +{ + tANI_U32 cfgValue; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RMC_ACTION_PERIOD_FREQUENCY, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get Action Period Frequency value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve ActionPeriodFrequency")); + } + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + vos_mem_zero(&pMac->rmcContext, sizeof(pMac->rmcContext)); + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_init(&pMac->rmcContext.lkRmcLock))) + { + PELOGE(limLog(pMac, LOGE, FL("RMC lock init failed!"));) + } + + if (tx_timer_create(&pMac->rmcContext.gRmcRulerSelectTimer, + "RMC RSP TIMEOUT", + __rmcRulerSelectTimerHandler, + 0 /* param */, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("could not create RMC response timer")); + } + + pMac->rmcContext.rmcTimerValInTicks = cfgValue; +} + +void +limRmcCleanup(tpAniSirGlobal pMac) +{ + limRmcIbssDelete(pMac); + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_destroy(&pMac->rmcContext.lkRmcLock))) + { + PELOGE(limLog(pMac, LOGE, FL("RMC lock destroy failed!"));) + } + + tx_timer_delete(&pMac->rmcContext.gRmcRulerSelectTimer); +} + +void +limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter) +{ + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: limRMCTransmitterDelete lock acquire failed")); + return; + } + + __rmcGroupDeleteHashEntry(pMac, transmitter); + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: limRMCTransmitterDelete lock release failed")); + } + + limLog(pMac, LOG1, FL("RMC: limRmcTransmitterDelete complete")); +} + +void +limRmcIbssDelete(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry; + tSirMacAddr zeroMacAddr = { 0, 0, 0, 0, 0, 0 }; + + /* + * This API relies on a single active IBSS session. + */ + psessionEntry = limIsIBSSSessionActive(pMac); + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("RMC: limRmcIbssDelete:No active IBSS"));) + return; + } + + if (VOS_FALSE == vos_mem_compare(&zeroMacAddr, + &pMac->rmcContext.ruler, sizeof(tSirMacAddr))) + { + __limPostMsgUpdateInd(pMac, eRMC_RULER_CANCELLED, + eRMC_TRANSMITTER_ROLE, psessionEntry->selfMacAddr, + pMac->rmcContext.ruler); + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: limRmcIbssDelete lock acquire failed")); + return; + } + + /* Cancel pending timer */ + tx_timer_deactivate(&pMac->rmcContext.gRmcRulerSelectTimer); + + /* Delete all entries from Ruler database. */ + __rmcGroupDeleteAllEntries(pMac); + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: limRmcIbssDelete lock release failed")); + } + + limLog(pMac, LOG1, FL("RMC: limRmcIbssDelete complete")); +} + +void +limRmcDumpStatus(tpAniSirGlobal pMac) +{ + tLimRmcGroupContext *entry; + int index, count; + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: limRmcDumpStatus lock acquire failed")); + return; + } + + + limLog(pMac, LOGE, FL(" ----- RMC Transmitter Information ----- \n")); + limLog(pMac, LOGE, + FL(" Ruler Address | RMC State \n")); + + if (pMac->rmcContext.state != eRMC_RULER_NOT_SELECTED) + { + limLog(pMac,LOGE, FL( MAC_ADDRESS_STR " | %s\n"), + MAC_ADDR_ARRAY(pMac->rmcContext.ruler), + __limMcastTxStateToString(pMac->rmcContext.state)); + } + + limLog( pMac,LOGE, FL(" ----- RMC Ruler Information ----- \n")); + limLog( pMac,LOGE, FL(" Transmitter Address\n")); + + count = 0; + for (index = 0; index < RMC_MCAST_GROUPS_HASH_SIZE; index++) + { + entry = pMac->rmcContext.rmcGroupRxHashTable[index]; + + while (entry) + { + count++; + limLog( pMac,LOGE, FL("%d. " MAC_ADDRESS_STR " \n"), + count, MAC_ADDR_ARRAY(entry->transmitter)); + entry = entry->next; + } + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&pMac->rmcContext.lkRmcLock))) + { + limLog(pMac, LOGE, + FL("RMC: limRmcDumpStatus lock release failed")); + } + + return; + +} + +VOS_STATUS +limRmcTriggerRulerSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + if ((TRUE == pMac->rmcContext.rmcEnabled) && + (eRMC_RULER_NOT_SELECTED == pMac->rmcContext.state)) + { + limLog(pMac, LOG1, + FL("Ruler selection trigerred in FW")); + + __limPostMsgRulerReq(pMac, eRMC_SUGGEST_RULER_CMD, macAddr); + + pMac->rmcContext.state = eRMC_RULER_ENABLE_REQUESTED; + + return VOS_STATUS_SUCCESS; + } + else + { + limLog(pMac, LOG1, + FL("Could not trigger ruler selection: RMC state %d rmcEnabled %d"), + pMac->rmcContext.state, pMac->rmcContext.rmcEnabled); + + return VOS_STATUS_E_FAILURE; + } +} + +#endif /* WLAN_FEATURE_RMC */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.h new file mode 100644 index 000000000000..1ebf0deb99eb --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limRMC.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Date: 08/15/13 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_RMC_H +#define __LIM_RMC_H + +#ifdef WLAN_FEATURE_RMC + +typedef enum { + eLIM_RMC_ENABLE_REQ = 0, + eLIM_RMC_DISABLE_REQ = 1, + eLIM_RMC_BECOME_RULER_RESP = 2, + eLIM_RMC_RULER_SELECT_RESP = 3, + eLIM_RMC_RULER_PICK_NEW = 4, + eLIM_RMC_OTA_RULER_INFORM_CANCELLED = 5, + eLIM_RMC_OTA_RULER_INFORM_ACK = 6, + eLIM_RMC_OTA_RULER_INFORM_SELECTED = 7, +} eRmcMessageType; + +typedef enum { + eRMC_RULER_NOT_SELECTED = 0, + eRMC_RULER_ENABLE_REQUESTED = 1, + eRMC_RULER_OTA_REQUEST_SENT = 2, + eRMC_RULER_ACTIVE = 3, +} eRmcMcastTxState; + +typedef enum { + eRMC_IS_NOT_A_RULER = 0, + eRMC_RULER_PENDING = 1, + eRMC_IS_A_RULER = 2, +} eRmcRulerState; + +enum { + eRMC_SUGGEST_RULER_CMD = 0, + eRMC_BECOME_RULER_CMD = 1, +}; + +enum { + eRMC_RULER_ACCEPTED = 0, //Host-->FW + eRMC_RULER_CANCELLED = 1, //Host-->FW + eRMC_RULER_PICK_NEW = 2, //FW-->Host +}; + +/* tRoleType; */ +typedef enum +{ + eRMC_RULER_ROLE, + eRMC_TRANSMITTER_ROLE, +} eRmcRole; + +#define RMC_MCAST_GROUPS_HASH_SIZE 32 + +typedef struct sLimRmcGroupContext +{ + tSirMacAddr transmitter; + eRmcRulerState isRuler; + struct sLimRmcGroupContext *next; +} tLimRmcGroupContext, *tpLimRmcGroupContext; + +typedef struct sLimRmcContext +{ + tANI_BOOLEAN rmcEnabled; + tSirMacAddr ruler; + eRmcMcastTxState state; + TX_TIMER gRmcRulerSelectTimer; + tANI_U32 rmcTimerValInTicks; + vos_lock_t lkRmcLock; + tLimRmcGroupContext *rmcGroupRxHashTable[RMC_MCAST_GROUPS_HASH_SIZE]; +} tLimRmcContext, *tpLimRmcContext; + + +void limRmcInit(tpAniSirGlobal pMac); +void limRmcCleanup(tpAniSirGlobal pMac); +void limRmcTransmitterDelete(tpAniSirGlobal pMac, tSirMacAddr transmitter); +void limRmcIbssDelete(tpAniSirGlobal pMac); +void limRmcDumpStatus(tpAniSirGlobal pMac); + +VOS_STATUS +limRmcTriggerRulerSelection(tpAniSirGlobal pMac, tSirMacAddr macAddr); +#endif /* WLAN_FEATURE_RMC */ + +#endif /* __LIM_RMC_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limRoamingAlgo.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limRoamingAlgo.c new file mode 100644 index 000000000000..4a0f06759fd1 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limRoamingAlgo.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limRoamingAlgo.cc contains the code for LIM + * algorithms. + * Author: Chandra Modumudi + * Date: 03/01/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "wniCfg.h" +#include "cfgApi.h" +#include "limTypes.h" +#include "limTimerUtils.h" +#include "limTrace.h" + + + +/** ---------------------------------------------------------------------- +\fn limSelectsBackgroundScanMode() +\brief This function is called by limIsBackgroundScanAllowed(). +\ Here LIM decides whether we shall enforce this background +\ scan or let HAL decide whether to proceed with the background +\ scan as HAL sees fits. LIM shall enforce background scan if: +\ 1) station is not in link established state +\ 2) station is in link established state, but there has been +\ max number of consecutive background scan failure. +\ +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------------------- */ +tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal pMac) +{ + tANI_U32 cfgVal; + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE, &cfgVal) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_MAX_CONSECUTIVE_BACKGROUND_SCAN_FAILURE value")); + return eSIR_NORMAL_BACKGROUND_SCAN; + } + + if (cfgVal == 0) + return eSIR_NORMAL_BACKGROUND_SCAN; + + /* If the "number of consecutive background scan failure" + * exceeds the maximum allowed, then LIM shall trigger an + * aggressive background scan. + */ + if (pMac->lim.gLimNumOfConsecutiveBkgndScanFailure >= cfgVal) + { + pMac->lim.gLimNumOfForcedBkgndScan += 1; + limLog(pMac, LOGE, + FL("Had %d consec scan fail(when expect < %d). Trigger AGGRESSIVE bkgnd scan."), + pMac->lim.gLimNumOfConsecutiveBkgndScanFailure, cfgVal); + return eSIR_AGGRESSIVE_BACKGROUND_SCAN; + } + + return eSIR_NORMAL_BACKGROUND_SCAN; +} + + +/** ----------------------------------------------------------- +\fn limIsBackgroundScanAllowed +\brief This function determines if background scan should be +\ allowed. It is called by limTriggerBackgroundScan(). +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------- */ +static tANI_U8 limIsBackgroundScanAllowed(tpAniSirGlobal pMac) +{ + // if we are in the middle of a scan already, skip the background scan + if (limIsSystemInScanState(pMac) || + (pMac->lim.gLimBackgroundScanDisable) || + (pMac->lim.gLimForceBackgroundScanDisable) || + (pMac->lim.gLimBackgroundScanTerminate)) + return false; + + //need to do background scan in IBSS mode. + if (pMac->lim.gLimSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + if (pMac->lim.gLimSmeState != eLIM_SME_NORMAL_STATE) + return false; + return true; + } + + // If station is not in link established state, then skip background scan + if ( (pMac->lim.gLimSystemRole == eLIM_STA_ROLE) && (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) ) + return false; + + /* now that we have checked for scan state, check for other transitional + * states which should not be interrupted by scans + */ + if ((! (pMac->lim.gLimSmeState == eLIM_SME_IDLE_STATE) ) && + (! (pMac->lim.gLimSmeState == eLIM_SME_JOIN_FAILURE_STATE) ) && + (! (pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_STATE) ) ) + return false; + + return true; +} + + +/** --------------------------------------------------------------- +\fn limTriggerBackgroundScan() +\brief This function is called upon background scan interval +\ when there is an exisiting link with an AP. +\ SME_SCAN_REQ is issued to SME state machine with Active +\ scanning is performed on one channel at a time. +\ +\ Assumptions: +\ Valid channel list at CFG is either populated by Roaming +\ algorithm upon determining/selecting a regulatory domain +\ or by default has all 36 possible channels. +\ +\param tpAniSirGlobal pMac +\return none +\ ----------------------------------------------------------------- */ +void limTriggerBackgroundScan(tpAniSirGlobal pMac) +{ + tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN; + tANI_U32 ssidLen = SIR_MAC_MAX_SSID_LENGTH; + tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN]; + tSirSmeScanReq smeScanReq; + tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + tSirBackgroundScanMode backgroundScan; + + limLog(pMac, LOG1, FL("Background Scan: %d success, %d consec fail "), + pMac->lim.gLimNumOfBackgroundScanSuccess, pMac->lim.gLimNumOfConsecutiveBkgndScanFailure); + + if (! limIsBackgroundScanAllowed(pMac)) + { + PELOG1(limLog(pMac, LOG1, FL("Skipping Background Scan "));) + return; + } + + // Get background scan channel list from CFG + if (wlan_cfgGetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, + (tANI_U8 *) bgScanChannelList, + (tANI_U32 *) &len) != eSIR_SUCCESS) + { + /** + * Could not get Valid channel list from CFG. + * Log error. + */ + PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list"));) + + return; + } + + // Time to perform background scan. Prepare and issue + // SME_SCAN_REQ to SME State machine + smeScanReq.messageType = eWNI_SME_SCAN_REQ; + smeScanReq.length = sizeof(tSirSmeScanReq); + smeScanReq.bssType = eSIR_INFRASTRUCTURE_MODE; + vos_mem_copy( (tANI_U8 *) smeScanReq.bssId, + (tANI_U8 *) &bcAddr, sizeof(tSirMacAddr)); + + if (wlan_cfgGetStr(pMac, WNI_CFG_SSID, + (tANI_U8 *) (smeScanReq.ssId[0].ssId), + (tANI_U32 *) &ssidLen) != eSIR_SUCCESS) + { + /// Could not get SSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve SSID")); + } + smeScanReq.ssId[0].length = (tANI_U8) ssidLen; + smeScanReq.numSsid = 1; + + smeScanReq.scanType = eSIR_ACTIVE_SCAN; + smeScanReq.sessionId = 0; + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + &smeScanReq.minChannelTime) != eSIR_SUCCESS) + { + /// Could not get minChlTime value from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve minChlTime value"));) + + return; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + &smeScanReq.maxChannelTime) != eSIR_SUCCESS) + { + /// Could not get maxChlTime value from CFG. Log error. + PELOGE(limLog(pMac, LOGE, FL("could not retrieve maxChlTime value"));) + + return; + } + + smeScanReq.returnAfterFirstMatch = 0; + smeScanReq.returnUniqueResults = 1; + + //At the first channel scan, clear the cached results + if(pMac->lim.gLimBackgroundScanChannelId == 0) + { + smeScanReq.returnFreshResults = SIR_BG_SCAN_PURGE_RESUTLS|SIR_BG_SCAN_RETURN_FRESH_RESULTS; + } + else + { + smeScanReq.returnFreshResults = SIR_BG_SCAN_RETURN_FRESH_RESULTS; + } + + + smeScanReq.channelList.numChannels = 1; + if (pMac->lim.gLimBackgroundScanChannelId >= len) + { + pMac->lim.gLimBackgroundScanChannelId = 0; + + PELOGE(limLog(pMac, LOGE, FL("Skipping Background Scan since the channel list is exhausted."));) + PELOGE(limLog(pMac, LOGE, FL("SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD indication to start the background scan again."));) + + /* Stop the BG scan timer here. SME should send WNI_CFG_BACKGROUND_SCAN_PERIOD + * indication to start the background scan again. + */ + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_BACKGROUND_SCAN_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer) + != TX_SUCCESS) + { + // Could not deactivate BackgroundScanTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate BackgroundScanTimer timer")); + } + } + + pMac->lim.gLimBackgroundScanTerminate = TRUE; + + PELOGE(limLog(pMac, LOGE, FL("Send dummy scan with returnFreshResults as 0 to report BG scan results to SME."));) + return; + } + smeScanReq.channelList.channelNumber[0] = + bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId++]; + + smeScanReq.uIEFieldLen = 0; + smeScanReq.uIEFieldOffset = sizeof(tSirSmeScanReq); + + backgroundScan = limSelectsBackgroundScanMode(pMac); + PELOG1(limLog(pMac, LOG1, FL("Performing (mode %s (%d)) Background Scan"), + lim_BackgroundScanModetoString(backgroundScan), + backgroundScan);) + smeScanReq.backgroundScanMode = backgroundScan; + + //determine whether to send the results or not, If so, notify the BG scan results to SME + if (pMac->lim.gLimBackgroundScanChannelId >= len) + { + pMac->lim.gLimReportBackgroundScanResults = TRUE; + } + + limPostSmeMessage(pMac, + eWNI_SME_SCAN_REQ, + (tANI_U32 *) &smeScanReq); +} /*** limTriggerBackgroundScan() ***/ + + +/** ---------------------------------------------------------------------- +\fn limAbortBackgroundScan +\brief This function aborts background scan and send scan +\ response to SME. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------------------- */ +void limAbortBackgroundScan(tpAniSirGlobal pMac) +{ + tANI_U16 scanRspLen = 8; + + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + limLog(pMac, LOGE, FL("Abort Background Scan ")); + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + } + + pMac->lim.gLimBackgroundScanTerminate = TRUE; + pMac->lim.gLimBackgroundScanStarted = FALSE; + + if (pMac->lim.gLimSmeScanResultLength == 0) + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0); + else + { + scanRspLen = sizeof(tSirSmeScanRsp) + + pMac->lim.gLimSmeScanResultLength - + sizeof(tSirBssDescription); + limSendSmeScanRsp(pMac, scanRspLen, eSIR_SME_SUCCESS, 0, 0); + } + } + + // reset background scan variables + pMac->lim.gLimBackgroundScanChannelId = 0; + return; +} + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c new file mode 100644 index 000000000000..26b3b5bf55ce --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.c @@ -0,0 +1,1306 @@ +/* + * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limScanResultUtils.cc contains the utility functions + * LIM uses for maintaining and accessing scan results on STA. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "limTypes.h" +#include "limUtils.h" +#include "limSerDesUtils.h" +#include "limApi.h" +#include "limSession.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif +#include "vos_utils.h" + +/** + * limDeactiveMinChannelTimerDuringScan() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to deactivate MIN channel + * timer if running. + * + * This function should be called only when pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return eSIR_SUCCESS in case of success + */ + +tANI_U32 +limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal pMac) +{ + if ((VOS_TRUE == + tx_timer_running(&pMac->lim.limTimers.gLimMinChannelTimer)) && + (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && + (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE)) + { + /** + * Beacon/Probe Response is received during active scanning. + * Deactivate MIN channel timer if running. + */ + + limDeactivateAndChangeTimer(pMac,eLIM_MIN_CHANNEL_TIMER); + if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer) + == TX_TIMER_ERROR) + { + /// Could not activate max channel timer. + // Log error + limLog(pMac,LOGP, FL("could not activate max channel timer")); + + limCompleteMlmScan(pMac, eSIR_SME_RESOURCES_UNAVAILABLE); + return TX_TIMER_ERROR; + } + } + return eSIR_SUCCESS; +} /*** end limDeactivateMinChannelTimerDuringScan() ***/ + + + +/** + * limCollectBssDescription() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to check if the received + * frame matches scan criteria, collect BSS description + * and add it to cached scan results. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBPR - Pointer to parsed Beacon/Probe Response structure + * @param pRxPacketInfo - Pointer to Received frame's BD + * ---------if defined WLAN_FEATURE_VOWIFI------ + * @param fScanning - flag to indicate if it is during scan. + * --------------------------------------------- + * + * @return None + */ +#if defined WLAN_FEATURE_VOWIFI +void +limCollectBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pBssDescr, + tpSirProbeRespBeacon pBPR, + tANI_U8 *pRxPacketInfo, + tANI_U8 fScanning) +#else +void +limCollectBssDescription(tpAniSirGlobal pMac, + tSirBssDescription *pBssDescr, + tpSirProbeRespBeacon pBPR, + tANI_U8 *pRxPacketInfo) +#endif +{ + tANI_U8 *pBody; + tANI_U32 ieLen = 0; + tpSirMacMgmtHdr pHdr; + tANI_U8 channelNum; + tANI_U8 rxChannel; + tANI_U8 rfBand = 0; + + pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + VOS_ASSERT(WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) >= SIR_MAC_B_PR_SSID_OFFSET); + ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET; + rxChannel = WDA_GET_RX_CH(pRxPacketInfo); + pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); + rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); + + + /** + * Length of BSS desription is without length of + * length itself and length of pointer + * that holds ieFields + */ + pBssDescr->length = (tANI_U16)( + ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields)) - + sizeof(pBssDescr->length) + ieLen); + + // Copy BSS Id + vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, + (tANI_U8 *) pHdr->bssId, + sizeof(tSirMacAddr)); + + // Copy Timestamp, Beacon Interval and Capability Info + pBssDescr->scanSysTimeMsec = vos_timer_get_system_time(); + + pBssDescr->timeStamp[0] = pBPR->timeStamp[0]; + pBssDescr->timeStamp[1] = pBPR->timeStamp[1]; + pBssDescr->beaconInterval = pBPR->beaconInterval; + pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo); + + pBssDescr->HTCapsPresent = 0; + pBssDescr->chanWidth = eHT_CHANNEL_WIDTH_20MHZ; + pBssDescr->wmeInfoPresent = 0; + pBssDescr->vhtCapsPresent = 0; + pBssDescr->beacomformingCapable = 0; + /* HT capability */ + if (pBPR->HTCaps.present) { + pBssDescr->HTCapsPresent = 1; + if (pBPR->HTCaps.supportedChannelWidthSet) + pBssDescr->chanWidth = eHT_CHANNEL_WIDTH_40MHZ; + } + if (pBPR->wmeEdcaPresent) + pBssDescr->wmeInfoPresent = 1; + +#ifdef WLAN_FEATURE_11AC + /* VHT Parameters */ + if (pBPR->VHTCaps.present) { + pBssDescr->vhtCapsPresent = 1; + if (pBPR->VHTCaps.muBeamformerCap) + pBssDescr->beacomformingCapable = 1; + } + if (pBPR->VHTOperation.present) + if (pBPR->VHTOperation.chanWidth == 1) + pBssDescr->chanWidth = eHT_CHANNEL_WIDTH_80MHZ; +#endif + if(!pBssDescr->beaconInterval ) + { + limLog(pMac, LOGW, + FL("Beacon Interval is ZERO, making it to default 100 " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->bssId)); + pBssDescr->beaconInterval= 100; + } + /* + * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut + * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz + * band, so not relying on the 'last Scanned Channel' stored in LIM. + * Instead use the value returned by RXP in BD. This the the same value which HAL programs into + * RXP before every channel switch. + * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from + * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen. + * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it + * is not present in the beacon, we go for the channel info present in RXP. + * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel. + * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices. + */ + pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR); + + if (pBssDescr->channelId == 0) + { + /* If the channel Id is not retrieved from Beacon, extract the channel from BD */ + /* Unmapped the channel.This We have to do since we have done mapping in the hal to + overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/ + if ((!rfBand) || IS_5G_BAND(rfBand)) + { + rxChannel = limUnmapChannel(rxChannel); + } + if (!rxChannel) + { + rxChannel = pMac->lim.gLimCurrentScanChannelId; + } + pBssDescr->channelId = rxChannel; + } + + pBssDescr->channelIdSelf = pBssDescr->channelId; + //set the network type in bss description + channelNum = pBssDescr->channelId; + pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR); + + pBssDescr->aniIndicator = pBPR->propIEinfo.aniIndicator; + + // Copy RSSI & SINR from BD + + PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** "); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 ); + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );) + + pBssDescr->rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo); + + //SINR no longer reported by HW + pBssDescr->sinr = 0; + + pBssDescr->nReceivedTime = vos_timer_get_system_time(); + +#if defined WLAN_FEATURE_VOWIFI + if( fScanning ) + { + rrmGetStartTSF( pMac, pBssDescr->startTSF ); + pBssDescr->parentTSF = WDA_GET_RX_TIMESTAMP(pRxPacketInfo); + } +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + // MobilityDomain + pBssDescr->mdie[0] = 0; + pBssDescr->mdie[1] = 0; + pBssDescr->mdie[2] = 0; + pBssDescr->mdiePresent = FALSE; + // If mdie is present in the probe resp we + // fill it in the bss description + if( pBPR->mdiePresent) + { + pBssDescr->mdiePresent = TRUE; + pBssDescr->mdie[0] = pBPR->mdie[0]; + pBssDescr->mdie[1] = pBPR->mdie[1]; + pBssDescr->mdie[2] = pBPR->mdie[2]; + } +#endif + +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + pBssDescr->QBSSLoad_present = FALSE; + pBssDescr->QBSSLoad_avail = 0; + if( pBPR->QBSSLoad.present) + { + pBssDescr->QBSSLoad_present = TRUE; + pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail; + pBssDescr->QBSS_ChanLoad = pBPR->QBSSLoad.chautil; + } +#endif + // Copy IE fields + vos_mem_copy((tANI_U8 *) &pBssDescr->ieFields, + pBody + SIR_MAC_B_PR_SSID_OFFSET, + ieLen); + + //sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGW, (tANI_U8 *) pBssDescr, pBssDescr->length + 2 ); + limLog( pMac, LOG3, + FL("Collected BSS Description for Channel(%1d), length(%u), aniIndicator(%d), IE Fields(%u)"), + pBssDescr->channelId, + pBssDescr->length, + pBssDescr->aniIndicator, + ieLen ); + + return; +} /*** end limCollectBssDescription() ***/ + +/** + * limIsScanRequestedSSID() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to check if the received + * SSID is present in the list of requested SSIDs in scan + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param ssId - SSID Received in beacons/Probe responses that is compared against the + requeusted SSID in scan list + * --------------------------------------------- + * + * @return boolean - TRUE if SSID is present in requested list, FALSE otherwise + */ + +tANI_BOOLEAN limIsScanRequestedSSID(tpAniSirGlobal pMac, tSirMacSSid *ssId) +{ + tANI_U8 i = 0; + + for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++) + { + if ( eANI_BOOLEAN_TRUE == vos_mem_compare((tANI_U8 *) ssId, + (tANI_U8 *) &pMac->lim.gpLimMlmScanReq->ssId[i], + (tANI_U8) (pMac->lim.gpLimMlmScanReq->ssId[i].length + 1))) + { + return eANI_BOOLEAN_TRUE; + } + } + return eANI_BOOLEAN_FALSE; +} + +/** + * limCheckAndAddBssDescription() + * + *FUNCTION: + * This function is called during scan upon receiving + * Beacon/Probe Response frame to check if the received + * frame matches scan criteria, collect BSS description + * and add it to cached scan results. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBPR - Pointer to parsed Beacon/Probe Response structure + * @param pRxPacketInfo - Pointer to Received frame's BD + * @param fScanning - boolean to indicate whether the BSS is from current scan or just happen to receive a beacon + * + * @return None + */ + +void +limCheckAndAddBssDescription(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBPR, + tANI_U8 *pRxPacketInfo, + tANI_BOOLEAN fScanning, + tANI_U8 fProbeRsp) +{ + tLimScanResultNode *pBssDescr; + tANI_U32 frameLen, ieLen = 0; + tANI_U8 rxChannelInBeacon = 0; + eHalStatus status; + tANI_U8 dontUpdateAll = 0; + tANI_U8 rfBand = 0; + tANI_U8 rxChannelInBD = 0; + + tSirMacAddr bssid = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tSirMacAddr bssid_zero = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + tANI_BOOLEAN fFound = FALSE; + tpSirMacDataHdr3a pHdr; + + pHdr = WDA_GET_RX_MPDUHEADER3A((tANI_U8 *)pRxPacketInfo); + + // Check For Null BSSID; Skip in case of P2P. + if (vos_mem_compare(bssid_zero, &pHdr->addr3, 6)) + { + return ; + } + + //Checking if scanning for a particular BSSID + if ((fScanning) && (pMac->lim.gpLimMlmScanReq)) + { + fFound = vos_mem_compare(pHdr->addr3, &pMac->lim.gpLimMlmScanReq->bssId, 6); + if (!fFound) + { + if ((pMac->lim.gpLimMlmScanReq->p2pSearch) && + (vos_mem_compare(pBPR->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, + &pMac->lim.gpLimMlmScanReq->bssId, 6))) + { + fFound = eANI_BOOLEAN_TRUE; + } + } + } + + /** + * Compare SSID with the one sent in + * Probe Request frame, if any. + * If they don't match, ignore the + * Beacon frame. + * pMac->lim.gLimMlmScanReq->ssId.length == 0 + * indicates Broadcast SSID. + * When gLimReturnAfterFirstMatch is set, it means the scan has to match + * a SSID (if it is also set). Ignore the other BSS in that case. + */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) + { +#endif + if ((pMac->lim.gpLimMlmScanReq) && + (((fScanning) && + ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) && + (pMac->lim.gpLimMlmScanReq->numSsid) && + !limIsScanRequestedSSID(pMac, &pBPR->ssId)) || + (!fFound && (pMac->lim.gpLimMlmScanReq && + pMac->lim.gpLimMlmScanReq->bssId) && + !vos_mem_compare(bssid, + &pMac->lim.gpLimMlmScanReq->bssId, 6)))) + { + /** + * Received SSID does not match with + * the one we're scanning for. + * Ignore received Beacon frame + */ + + return; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + /* There is no point in caching & reporting the scan results for APs + * which are in the process of switching the channel. So, we are not + * caching the scan results for APs which are adverzing the channel-switch + * element in their beacons and probe responses. + */ + if(pBPR->channelSwitchPresent) + { + return; + } + + /* If beacon/probe resp DS param channel does not match with + * RX BD channel then don't save the results. It might be a beacon + * from another channel heard as noise on the current scanning channel + */ + + if ((pBPR->dsParamsPresent) || (pBPR->HTInfo.present)) + { + /* This means that we are in 2.4GHz mode or 5GHz 11n mode */ + rxChannelInBeacon = limGetChannelFromBeacon(pMac, pBPR); + rfBand = WDA_GET_RX_RFBAND(pRxPacketInfo); + rxChannelInBD = WDA_GET_RX_CH(pRxPacketInfo); + + if ((!rfBand) || IS_5G_BAND(rfBand)) + { + rxChannelInBD = limUnmapChannel(rxChannelInBD); + } + + if(rxChannelInBD != rxChannelInBeacon) + { + /* BCAST Frame, if CH do not match, Drop */ + if(WDA_IS_RX_BCAST(pRxPacketInfo)) + { + limLog(pMac, LOG3, FL("Beacon/Probe Rsp dropped. Channel in BD %d. " + "Channel in beacon" " %d"), + WDA_GET_RX_CH(pRxPacketInfo),limGetChannelFromBeacon(pMac, pBPR)); + return; + } + /* Unit cast frame, Probe RSP, do not drop */ + else + { + dontUpdateAll = 1; + limLog(pMac, LOG3, FL("SSID %s, CH in ProbeRsp %d, CH in BD %d, miss-match, Do Not Drop"), + pBPR->ssId.ssId, + rxChannelInBeacon, + WDA_GET_RX_CH(pRxPacketInfo)); + WDA_GET_RX_CH(pRxPacketInfo) = rxChannelInBeacon; + } + } + } + + /** + * Allocate buffer to hold BSS description from + * received Beacon frame. + * Include size of fixed fields and IEs length + */ + + ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); + if (ieLen <= SIR_MAC_B_PR_SSID_OFFSET) + { + limLog(pMac, LOGP, + FL("RX packet has invalid length %d"), ieLen); + return; + } + + ieLen -= SIR_MAC_B_PR_SSID_OFFSET; + + frameLen = sizeof(tLimScanResultNode) + ieLen - sizeof(tANI_U32); //Sizeof(tANI_U32) is for ieFields[1] + + pBssDescr = vos_mem_malloc(frameLen); + if ( NULL == pBssDescr ) + { + // Log error + limLog(pMac, LOGP, + FL("call for AllocateMemory failed for storing BSS description")); + + return; + } + + vos_mem_zero(pBssDescr, frameLen); + + // In scan state, store scan result. +#if defined WLAN_FEATURE_VOWIFI + limCollectBssDescription(pMac, &pBssDescr->bssDescription, + pBPR, pRxPacketInfo, fScanning); +#else + limCollectBssDescription(pMac, &pBssDescr->bssDescription, + pBPR, pRxPacketInfo); +#endif + pBssDescr->bssDescription.fProbeRsp = fProbeRsp; + + pBssDescr->next = NULL; + + /** + * Depending on whether to store unique or all + * scan results, pass hash update/add parameter + * For LFR candidates just add them on it's own cache + */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo)) + { + limLog(pMac, LOG1, FL(" pHdr->addr1:"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->addr1)); + limLog(pMac, LOG1, FL(" pHdr->addr2:"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->addr2)); + limLog(pMac, LOG1, FL(" pHdr->addr3:"MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pHdr->addr3)); + limLog( pMac, LOG1, FL("Save this entry in LFR cache")); + status = limLookupNaddLfrHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); + } + else +#endif + //If it is not scanning, only save unique results + if (pMac->lim.gLimReturnUniqueResults || (!fScanning)) + { + status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE, dontUpdateAll); + } + else + { + status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD, dontUpdateAll); + } + + if(fScanning) + { + if ((pBssDescr->bssDescription.channelId <= 14) && + (pMac->lim.gLimReturnAfterFirstMatch & 0x40) && + pBPR->countryInfoPresent) + pMac->lim.gLim24Band11dScanDone = 1; + + if ((pBssDescr->bssDescription.channelId > 14) && + (pMac->lim.gLimReturnAfterFirstMatch & 0x80) && + pBPR->countryInfoPresent) + pMac->lim.gLim50Band11dScanDone = 1; + + if ( ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) || + ( pMac->lim.gLim24Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x40 ) ) || + ( pMac->lim.gLim50Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x80 ) ) || + fFound ) + { + /** + * Stop scanning and return the BSS description(s) + * collected so far. + */ + limLog(pMac, + LOGW, + FL("Completed scan: 24Band11dScan = %d, 50Band11dScan = %d BSS id"), + pMac->lim.gLim24Band11dScanDone, + pMac->lim.gLim50Band11dScanDone); + + //Need to disable the timers. If they fire, they will send END_SCAN + //while we already send FINISH_SCAN here. This may mess up the gLimHalScanState + limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); + limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER); + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + //limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE ); + } + }//(eANI_BOOLEAN_TRUE == fScanning) + + if( eHAL_STATUS_SUCCESS != status ) + { + vos_mem_free( pBssDescr ); + } +} /****** end limCheckAndAddBssDescription() ******/ + + + +/** + * limScanHashFunction() + * + *FUNCTION: + * This function is called during scan hash entry operations + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param bssId - Received BSSid + * + * @return Hash index + */ + +tANI_U8 +limScanHashFunction(tSirMacAddr bssId) +{ + tANI_U16 i, hash = 0; + + for (i = 0; i < sizeof(tSirMacAddr); i++) + hash += bssId[i]; + + return hash % LIM_MAX_NUM_OF_SCAN_RESULTS; +} /****** end limScanHashFunction() ******/ + + + +/** + * limInitHashTable() + * + *FUNCTION: + * This function is called upon receiving SME_START_REQ + * to initialize global cached scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitHashTable(tpAniSirGlobal pMac) +{ + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + pMac->lim.gLimCachedScanHashTable[i] = NULL; +} /****** end limInitHashTable() ******/ + + + +/** + * limLookupNaddHashEntry() + * + *FUNCTION: + * This function is called upon receiving a Beacon or + * Probe Response frame during scan phase to store + * received BSS description into scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBssDescr - Pointer to BSS description to be + * added to the scan result hash table. + * @param action - Indicates action to be performed + * when same BSS description is found. This is + * dependent on whether unique scan result to + * be stored or not. + * + * @return None + */ + +eHalStatus +limLookupNaddHashEntry(tpAniSirGlobal pMac, + tLimScanResultNode *pBssDescr, tANI_U8 action, + tANI_U8 dontUpdateAll) +{ + tANI_U8 index, ssidLen = 0; + tANI_U8 found = false; + tLimScanResultNode *ptemp, *pprev; + tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; + int idx, len; + tANI_U8 *pbIe; + tANI_S8 rssi = 0; + + index = limScanHashFunction(pBssDescr->bssDescription.bssId); + ptemp = pMac->lim.gLimCachedScanHashTable[index]; + + //ieFields start with TLV of SSID IE + ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); + pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; + + for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) + { + //For infrastructure, check BSSID and SSID. For IBSS, check more + pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; + if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first + (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, + (tANI_U8 *) ptemp->bssDescription.bssId, + sizeof(tSirMacAddr))) && //matching BSSID + // matching band to update new channel info + (vos_chan_to_band(pBssDescr->bssDescription.channelId) == + vos_chan_to_band(ptemp->bssDescription.channelId)) && + vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), + ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), + (tANI_U8) (ssidLen + 1)) && + ((pSirCapTemp->ess) || //we are done for infrastructure + //For IBSS, nwType and channelId + (((pBssDescr->bssDescription.nwType == + ptemp->bssDescription.nwType) && + (pBssDescr->bssDescription.channelId == + ptemp->bssDescription.channelId)))) + ) + { + // Found the same BSS description + if (action == LIM_HASH_UPDATE) + { + if(dontUpdateAll) + { + rssi = ptemp->bssDescription.rssi; + } + + if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) + { + //We get a different, save the old frame WSC IE if it is there + idx = 0; + len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + + sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; + pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; + //Save WPS IE if it exists + pBssDescr->bssDescription.WscIeLen = 0; + while(idx < len) + { + if((DOT11F_EID_WSCPROBERES == pbIe[0]) && + (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) + { + //Found it + if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) + { + vos_mem_copy(pBssDescr->bssDescription.WscIeProbeRsp, + pbIe, pbIe[1] + 2); + pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; + } + break; + } + idx += pbIe[1] + 2; + pbIe += pbIe[1] + 2; + } + } + + + if(NULL != pMac->lim.gpLimMlmScanReq) + { + if((pMac->lim.gpLimMlmScanReq->numSsid)&& + ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) + &pBssDescr->bssDescription.ieFields + 1)))) + return eHAL_STATUS_FAILURE; + } + + // Delete this entry + if (ptemp == pMac->lim.gLimCachedScanHashTable[index]) + pprev = pMac->lim.gLimCachedScanHashTable[index] = ptemp->next; + else + pprev->next = ptemp->next; + + pMac->lim.gLimMlmScanResultLength -= + ptemp->bssDescription.length + sizeof(tANI_U16); + + vos_mem_free(ptemp); + } + found = true; + break; + } + } + + //for now, only rssi, we can add more if needed + if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi) + { + pBssDescr->bssDescription.rssi = rssi; + } + + // Add this BSS description at same index + if (pprev == pMac->lim.gLimCachedScanHashTable[index]) + { + pBssDescr->next = pMac->lim.gLimCachedScanHashTable[index]; + pMac->lim.gLimCachedScanHashTable[index] = pBssDescr; + } + else + { + pBssDescr->next = pprev->next; + pprev->next = pBssDescr; + } + pMac->lim.gLimMlmScanResultLength += + pBssDescr->bssDescription.length + sizeof(tANI_U16); + + PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id"), + pBssDescr->bssDescription.length, + pMac->lim.gLimMlmScanResultLength); + limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) + + // Send new BSS found indication to HDD if CFG option is set + if (!found) limSendSmeNeighborBssInd(pMac, pBssDescr); + + // + // TODO: IF applicable, do we need to send: + // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF + // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP + // + return eHAL_STATUS_SUCCESS; +} + + + +/** + * limDeleteHashEntry() + * + *FUNCTION: + * This function is called upon to delete + * a BSS description from scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * Yet to find the utility of the function + * + * @param pBssDescr - Pointer to BSS description to be + * deleted from the scan result hash table. + * + * @return None + */ + +void limDeleteHashEntry(tLimScanResultNode *pBssDescr) +{ +} /****** end limDeleteHashEntry() ******/ + + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * limInitLfrHashTable() + * + *FUNCTION: + * This function is called upon receiving SME_START_REQ + * to initialize global cached Lfr scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitLfrHashTable(tpAniSirGlobal pMac) +{ + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + pMac->lim.gLimCachedLfrScanHashTable[i] = NULL; +} /****** end limInitLfrHashTable() ******/ + + + +/** + * limLookupNaddLfrHashEntry() + * + *FUNCTION: + * This function is called upon receiving a Beacon or + * Probe Response frame during Lfr scan phase from FW to store + * received BSS description into Lfr scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pBssDescr - Pointer to BSS description to be + * added to the Lfr scan result hash table. + * @param action - Indicates action to be performed + * when same BSS description is found. This is + * dependent on whether unique scan result to + * be stored or not. + * + * @return None + */ + +eHalStatus +limLookupNaddLfrHashEntry(tpAniSirGlobal pMac, + tLimScanResultNode *pBssDescr, tANI_U8 action, + tANI_U8 dontUpdateAll) +{ + tANI_U8 index, ssidLen = 0; + tLimScanResultNode *ptemp, *pprev; + tSirMacCapabilityInfo *pSirCap, *pSirCapTemp; + int idx, len; + tANI_U8 *pbIe; + tANI_S8 rssi = 0; + + index = limScanHashFunction(pBssDescr->bssDescription.bssId); + ptemp = pMac->lim.gLimCachedLfrScanHashTable[index]; + + //ieFields start with TLV of SSID IE + ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1); + pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo; + + for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next) + { + //For infrastructure, check BSSID and SSID. For IBSS, check more + pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo; + if ((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first + (vos_mem_compare( (tANI_U8 *) pBssDescr->bssDescription.bssId, + (tANI_U8 *) ptemp->bssDescription.bssId, + sizeof(tSirMacAddr))) && //matching BSSID + (pBssDescr->bssDescription.channelId == + ptemp->bssDescription.channelId) && + vos_mem_compare( ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1), + ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1), + (tANI_U8) (ssidLen + 1)) && + ((pSirCapTemp->ess) || //we are done for infrastructure + //For IBSS, nwType and channelId + (((pBssDescr->bssDescription.nwType == + ptemp->bssDescription.nwType) && + (pBssDescr->bssDescription.channelId == + ptemp->bssDescription.channelId)))) + ) + { + // Found the same BSS description + if (action == LIM_HASH_UPDATE) + { + if(dontUpdateAll) + { + rssi = ptemp->bssDescription.rssi; + } + + if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp) + { + //We get a different, save the old frame WSC IE if it is there + idx = 0; + len = ptemp->bssDescription.length - sizeof(tSirBssDescription) + + sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; + pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields; + //Save WPS IE if it exists + pBssDescr->bssDescription.WscIeLen = 0; + while(idx < len) + { + if((DOT11F_EID_WSCPROBERES == pbIe[0]) && + (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && + (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) + { + //Found it + if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) + { + vos_mem_copy( pBssDescr->bssDescription.WscIeProbeRsp, + pbIe, pbIe[1] + 2); + pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2; + } + break; + } + idx += pbIe[1] + 2; + pbIe += pbIe[1] + 2; + } + } + + + if(NULL != pMac->lim.gpLimMlmScanReq) + { + if((pMac->lim.gpLimMlmScanReq->numSsid)&& + ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *) + &pBssDescr->bssDescription.ieFields + 1)))) + return eHAL_STATUS_FAILURE; + } + + // Delete this entry + if (ptemp == pMac->lim.gLimCachedLfrScanHashTable[index]) + pprev = pMac->lim.gLimCachedLfrScanHashTable[index] = ptemp->next; + else + pprev->next = ptemp->next; + + pMac->lim.gLimMlmLfrScanResultLength -= + ptemp->bssDescription.length + sizeof(tANI_U16); + + vos_mem_free(ptemp); + } + break; + } + } + + //for now, only rssi, we can add more if needed + if ((action == LIM_HASH_UPDATE) && dontUpdateAll && rssi) + { + pBssDescr->bssDescription.rssi = rssi; + } + + // Add this BSS description at same index + if (pprev == pMac->lim.gLimCachedLfrScanHashTable[index]) + { + pBssDescr->next = pMac->lim.gLimCachedLfrScanHashTable[index]; + pMac->lim.gLimCachedLfrScanHashTable[index] = pBssDescr; + } + else + { + pBssDescr->next = pprev->next; + pprev->next = pBssDescr; + } + pMac->lim.gLimMlmLfrScanResultLength += + pBssDescr->bssDescription.length + sizeof(tANI_U16); + + PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"), + pBssDescr->bssDescription.length, + pMac->lim.gLimMlmLfrScanResultLength); + limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);) + + // + // TODO: IF applicable, do we need to send: + // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF + // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP + // + return eHAL_STATUS_SUCCESS; +} + + + +/** + * limDeleteLfrHashEntry() + * + *FUNCTION: + * This function is called upon to delete + * a BSS description from LFR scan result hash table. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * Yet to find the utility of the function + * + * @param pBssDescr - Pointer to BSS description to be + * deleted from the LFR scan result hash table. + * + * @return None + */ + +void limDeleteLfrHashEntry(tLimScanResultNode *pBssDescr) +{ +} /****** end limDeleteLfrHashEntry() ******/ + +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** + * limCopyScanResult() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() while + * sending SME_SCAN_RSP with scan result to HDD. + * + *LOGIC: + * This function traverses the scan list stored in scan hash table + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param pDest - Destination pointer + * + * @return None + */ + +void +limCopyScanResult(tpAniSirGlobal pMac, tANI_U8 *pDest) +{ + tLimScanResultNode *ptemp; + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((ptemp = pMac->lim.gLimCachedScanHashTable[i]) != NULL) + { + while(ptemp) + { + /// Copy entire BSS description including length + vos_mem_copy( pDest, + (tANI_U8 *) &ptemp->bssDescription, + ptemp->bssDescription.length + 2); + pDest += ptemp->bssDescription.length + 2; + ptemp = ptemp->next; + } + } + } +} /****** end limCopyScanResult() ******/ + + + +/** + * limDeleteCachedScanResults() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_SCAN_REQ with fresh scan result flag set. + * + *LOGIC: + * This function traverses the scan list stored in scan hash table + * and deletes the entries if any + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limDeleteCachedScanResults(tpAniSirGlobal pMac) +{ + tLimScanResultNode *pNode, *pNextNode; + tANI_U16 i; + + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) + { + while (pNode) + { + pNextNode = pNode->next; + + // Delete the current node + vos_mem_free(pNode); + + pNode = pNextNode; + } + } + } + + pMac->lim.gLimSmeScanResultLength = 0; +} /****** end limDeleteCachedScanResults() ******/ + + + +/** + * limReInitScanResults() + * + *FUNCTION: + * This function is called delete exisiting scan results + * and initialize the scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limReInitScanResults(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("Re initialize scan hash table.")); + limDeleteCachedScanResults(pMac); + limInitHashTable(pMac); + + // !!LAC - need to clear out the global scan result length + // since the list was just purged from the hash table. + pMac->lim.gLimMlmScanResultLength = 0; + +} /****** end limReInitScanResults() ******/ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * limDeleteCachedLfrScanResults() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_SCAN_REQ with flush scan result flag set for LFR. + * + *LOGIC: + * This function traverses the scan list stored in lfr scan hash + * table and deletes the entries if any + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limDeleteCachedLfrScanResults(tpAniSirGlobal pMac) +{ + tLimScanResultNode *pNode, *pNextNode; + tANI_U16 i; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((pNode = pMac->lim.gLimCachedLfrScanHashTable[i]) != NULL) + { + while (pNode) + { + pNextNode = pNode->next; + + // Delete the current node + vos_mem_free(pNode); + + pNode = pNextNode; + } + } + } + + pMac->lim.gLimSmeLfrScanResultLength = 0; +} /****** end limDeleteCachedLfrScanResults() ******/ + + + +/** + * limReInitLfrScanResults() + * + *FUNCTION: + * This function is called delete exisiting scan results + * and initialize the lfr scan hash table + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limReInitLfrScanResults(tpAniSirGlobal pMac) +{ + limLog(pMac, LOG1, FL("Re initialize lfr scan hash table.")); + limDeleteCachedLfrScanResults(pMac); + limInitLfrHashTable(pMac); + + // !!LAC - need to clear out the global scan result length + // since the list was just purged from the hash table. + pMac->lim.gLimMlmLfrScanResultLength = 0; + +} /****** end limReInitLfrScanResults() ******/ +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h new file mode 100644 index 000000000000..28ea9435a5f5 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limScanResultUtils.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limScanResultUtils.h contains the utility definitions + * LIM uses for maintaining and accessing scan results on STA. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SCAN_UTILS_H +#define __LIM_SCAN_UTILS_H + +#include "parserApi.h" +#include "limTypes.h" + +// Scan result hash related functions +tANI_U8 limScanHashFunction(tSirMacAddr); +void limInitHashTable(tpAniSirGlobal); +eHalStatus + limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); +void limDeleteHashEntry(tLimScanResultNode *); +void limDeleteCachedScanResults(tpAniSirGlobal); +void limRestorePreScanState(tpAniSirGlobal); +void limCopyScanResult(tpAniSirGlobal, tANI_U8 *); +void limReInitScanResults(tpAniSirGlobal); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void limInitLfrHashTable(tpAniSirGlobal); +eHalStatus + limLookupNaddLfrHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); +void limDeleteLfrHashEntry(tLimScanResultNode *); +void limDeleteCachedLfrScanResults(tpAniSirGlobal); +void limReInitLfrScanResults(tpAniSirGlobal); +#endif +tANI_U32 limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal); +void limCheckAndAddBssDescription(tpAniSirGlobal, tpSirProbeRespBeacon, tANI_U8 *, tANI_BOOLEAN, tANI_U8); +#if defined WLAN_FEATURE_VOWIFI +void limCollectBssDescription(tpAniSirGlobal, + tSirBssDescription *, + tpSirProbeRespBeacon, + tANI_U8 *, + tANI_U8); +#else +void limCollectBssDescription(tpAniSirGlobal, + tSirBssDescription *, + tpSirProbeRespBeacon, + tANI_U8 *); +#endif + +#endif /* __LIM_SCAN_UTILS_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c new file mode 100644 index 000000000000..9f88436bf222 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.c @@ -0,0 +1,1386 @@ +/* + * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limUtils.cc contains the utility functions + * LIM uses. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "aniGlobal.h" +#include "wniApi.h" + +#include "sirCommon.h" +#include "wniCfg.h" +#include "cfgApi.h" + + +#include "utilsApi.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "limSession.h" + + +#define LIM_SEED_LENGTH 16 +/** + *preauth node timeout value in interval of 10msec + */ +#define LIM_OPENAUTH_TIMEOUT 500 + +/** + * limIsAuthAlgoSupported() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether passed authentication algorithm is enabled + * or not + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param authType Indicates MAC based authentication type + * (eSIR_OPEN_SYSTEM or eSIR_SHARED_KEY) + * If Shared Key authentication to be used, + * 'Privacy Option Implemented' flag is also + * checked. + * + * @return true if passed authType is enabled else false + */ +tANI_U8 +limIsAuthAlgoSupported(tpAniSirGlobal pMac, tAniAuthType authType, tpPESession psessionEntry) +{ + tANI_U32 algoEnable, privacyOptImp; + + if (authType == eSIR_OPEN_SYSTEM) + { + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if((psessionEntry->authType == eSIR_OPEN_SYSTEM) || (psessionEntry->authType == eSIR_AUTO_SWITCH)) + return true; + else + return false; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_OPEN_SYSTEM_AUTH_ENABLE, + &algoEnable) != eSIR_SUCCESS) + { + /** + * Could not get AuthAlgo1 Enable value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve AuthAlgo1 Enable value")); + + return false; + } + else + return ( (algoEnable > 0 ? true : false) ); + } + else + { + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if((psessionEntry->authType == eSIR_SHARED_KEY) || (psessionEntry->authType == eSIR_AUTO_SWITCH)) + algoEnable = true; + else + algoEnable = false; + + } + else + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHARED_KEY_AUTH_ENABLE, + &algoEnable) != eSIR_SUCCESS) + { + /** + * Could not get AuthAlgo2 Enable value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve AuthAlgo2 Enable value")); + + return false; + } + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + privacyOptImp = psessionEntry->privacy; + } + else + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &privacyOptImp) != eSIR_SUCCESS) + { + /** + * Could not get PrivacyOptionImplemented value + * from CFG. Log error. + */ + limLog(pMac, LOGE, + FL("could not retrieve PrivacyOptImplemented value")); + + return false; + } + return (algoEnable && privacyOptImp); + } +} /****** end limIsAuthAlgoSupported() ******/ + + + +/** + * limInitPreAuthList + * + *FUNCTION: + * This function is called while starting a BSS at AP + * to initialize MAC authenticated STA list. This may also be called + * while joining/starting an IBSS if MAC authentication is allowed + * in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limInitPreAuthList(tpAniSirGlobal pMac) +{ + pMac->lim.pLimPreAuthList = NULL; + +} /*** end limInitPreAuthList() ***/ + + + +/** + * limDeletePreAuthList + * + *FUNCTION: + * This function is called cleanup Pre-auth list either on + * AP or on STA when moving from one persona to other. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limDeletePreAuthList(tpAniSirGlobal pMac) +{ + struct tLimPreAuthNode *pCurrNode, *pTempNode; + + pCurrNode = pTempNode = pMac->lim.pLimPreAuthList; + while (pCurrNode != NULL) + { + pTempNode = pCurrNode->next; + + limLog(pMac, LOG1, FL("=====> limDeletePreAuthList ")); + limReleasePreAuthNode(pMac, pCurrNode); + + pCurrNode = pTempNode; + } + pMac->lim.pLimPreAuthList = NULL; +} /*** end limDeletePreAuthList() ***/ + + + +/** + * limSearchPreAuthList + * + *FUNCTION: + * This function is called when Authentication frame is received + * by AP (or at a STA in IBSS supporting MAC based authentication) + * to search if a STA is in the middle of MAC Authentication + * transaction sequence. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param macAddr - MAC address of the STA that sent + * Authentication frame. + * + * @return Pointer to pre-auth node if found, else NULL + */ + +struct tLimPreAuthNode * +limSearchPreAuthList(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + struct tLimPreAuthNode *pTempNode = pMac->lim.pLimPreAuthList; + + while (pTempNode != NULL) + { + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + break; + + pTempNode = pTempNode->next; + } + + return pTempNode; +} /*** end limSearchPreAuthList() ***/ + +/** + * limDeleteOpenAuthPreAuthNode + * + *FUNCTION: + * This function is called to delete any stale preauth nodes on + * receiving authentication frame and existing preauth nodes + * reached the maximum allowed limit. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return true if any preauthnode deleted else false + */ + +tANI_U8 +limDeleteOpenAuthPreAuthNode(tpAniSirGlobal pMac) +{ + struct tLimPreAuthNode *pPrevNode, *pTempNode, *pFoundNode; + tANI_U8 authNodeFreed = false; + + pTempNode = pPrevNode = pMac->lim.pLimPreAuthList; + + if (pTempNode == NULL) + return authNodeFreed; + + while (pTempNode != NULL) + { + if (pTempNode->mlmState == eLIM_MLM_AUTHENTICATED_STATE && + pTempNode->authType == eSIR_OPEN_SYSTEM && + (vos_timer_get_system_ticks() > + (LIM_OPENAUTH_TIMEOUT + pTempNode->timestamp) || + vos_timer_get_system_ticks() < pTempNode->timestamp)) + { + // Found node to be deleted + authNodeFreed = true; + pFoundNode = pTempNode; + if (pMac->lim.pLimPreAuthList == pTempNode) + { + pPrevNode = pMac->lim.pLimPreAuthList = pTempNode = + pFoundNode->next; + } + else + { + pPrevNode->next = pTempNode->next; + pTempNode = pPrevNode->next; + } + + limReleasePreAuthNode(pMac, pFoundNode); + } + else + { + pPrevNode = pTempNode; + pTempNode = pPrevNode->next; + } + } + + return authNodeFreed; +} + +/** + * limAddPreAuthNode + * + *FUNCTION: + * This function is called at AP while sending Authentication + * frame2. + * This may also be called on a STA in IBSS if MAC authentication is + * allowed in IBSS mode. + * + *LOGIC: + * Node is always added to the front of the list + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pAuthNode - Pointer to pre-auth node to be added to the list. + * + * @return None + */ + +void +limAddPreAuthNode(tpAniSirGlobal pMac, struct tLimPreAuthNode *pAuthNode) +{ + pMac->lim.gLimNumPreAuthContexts++; + + pAuthNode->next = pMac->lim.pLimPreAuthList; + + pMac->lim.pLimPreAuthList = pAuthNode; +} /*** end limAddPreAuthNode() ***/ + + +/** + * limReleasePreAuthNode + * + *FUNCTION: + * This function is called to realease the accquired + * pre auth node from list. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param pAuthNode - Pointer to Pre Auth node to be released + * @return None + */ + +void +limReleasePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode) +{ + pAuthNode->fFree = 1; + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_PRE_AUTH_CLEANUP_TIMER)); + tx_timer_deactivate(&pAuthNode->timer); + pMac->lim.gLimNumPreAuthContexts--; +} /*** end limReleasePreAuthNode() ***/ + + +/** + * limDeletePreAuthNode + * + *FUNCTION: + * This function is called at AP when a pre-authenticated STA is + * Associated/Reassociated or when AuthFrame4 is received after + * Auth Response timeout. + * This may also be called on a STA in IBSS if MAC authentication and + * Association/Reassociation is allowed in IBSS mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param peerMacAddr - MAC address of the STA that need to be deleted + * from pre-auth node list. + * + * @return None + */ + +void +limDeletePreAuthNode(tpAniSirGlobal pMac, tSirMacAddr macAddr) +{ + struct tLimPreAuthNode *pPrevNode, *pTempNode; + + pTempNode = pPrevNode = pMac->lim.pLimPreAuthList; + + if (pTempNode == NULL) + return; + + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + // First node to be deleted + + pMac->lim.pLimPreAuthList = pTempNode->next; + + + limLog(pMac, LOG1, FL(" first node to delete")); + limLog(pMac, LOG1, + FL(" Release data entry:%p idx %d peer: " MAC_ADDRESS_STR), + pTempNode, pTempNode->authNodeIdx, + MAC_ADDR_ARRAY(macAddr)); + limReleasePreAuthNode(pMac, pTempNode); + + return; + } + + pTempNode = pTempNode->next; + + while (pTempNode != NULL) + { + if (vos_mem_compare( (tANI_U8 *) macAddr, + (tANI_U8 *) &pTempNode->peerMacAddr, + sizeof(tSirMacAddr)) ) + { + // Found node to be deleted + + pPrevNode->next = pTempNode->next; + + limLog(pMac, LOG1, FL(" subsequent node to delete")); + limLog(pMac, LOG1, + FL("Release data entry: %p id %d peer: "MAC_ADDRESS_STR), + pTempNode, pTempNode->authNodeIdx, MAC_ADDR_ARRAY(macAddr)); + limReleasePreAuthNode(pMac, pTempNode); + + return; + } + + pPrevNode = pTempNode; + pTempNode = pTempNode->next; + } + + // Should not be here + // Log error + limLog(pMac, LOGP, FL("peer not found in pre-auth list, addr= ")); + limPrintMacAddr(pMac, macAddr, LOGP); + +} /*** end limDeletePreAuthNode() ***/ + +/** + * limRestoreFromPreAuthState + * + *FUNCTION: + * This function is called on STA whenever an Authentication + * sequence is complete and state prior to auth need to be + * restored. + * + *LOGIC: + * MLM_AUTH_CNF is prepared and sent to SME state machine. + * In case of restoring from pre-auth: + * - Channel Id is programmed at LO/RF synthesizer + * - BSSID is programmed at RHP + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param resultCode - result of authentication attempt + * @return None + */ + +void +limRestoreFromAuthState(tpAniSirGlobal pMac, tSirResultCodes resultCode, tANI_U16 protStatusCode,tpPESession sessionEntry) +{ + tSirMacAddr currentBssId; + tLimMlmAuthCnf mlmAuthCnf; + + vos_mem_copy( (tANI_U8 *) &mlmAuthCnf.peerMacAddr, + (tANI_U8 *) &pMac->lim.gpLimMlmAuthReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmAuthCnf.authType = pMac->lim.gpLimMlmAuthReq->authType; + mlmAuthCnf.resultCode = resultCode; + mlmAuthCnf.protStatusCode = protStatusCode; + + /* Update PE session ID*/ + mlmAuthCnf.sessionId = sessionEntry->peSessionId; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState)); + /* Set the authAckStatus status flag as sucess as + * host have received the auth rsp and no longer auth + * retry is needed also cancel the auth rety timer + */ + pMac->authAckStatus = LIM_AUTH_ACK_RCD_SUCCESS; + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER); + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_FAIL_TIMER); + + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, currentBssId, &cfg) != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(currentBssId,sessionEntry->bssId); + + if (sessionEntry->limSmeState == eLIM_SME_WT_PRE_AUTH_STATE) + { + pMac->lim.gLimPreAuthChannelNumber = 0; + } + + if ((protStatusCode == eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS) + && (sessionEntry->sta_auth_retries_for_code17 < + pMac->sta_auth_retries_for_code17)) { + limLog(pMac, LOG1, FL("Retry Auth ")); + limDoSendAuthMgmtFrame(pMac, sessionEntry); + sessionEntry->sta_auth_retries_for_code17++; + } else { + /// Free up buffer allocated + /// for pMac->lim.gLimMlmAuthReq + vos_mem_free(pMac->lim.gpLimMlmAuthReq); + pMac->lim.gpLimMlmAuthReq = NULL; + + sessionEntry->limMlmState = sessionEntry->limPrevMlmState; + + limPostSmeMessage(pMac, + LIM_MLM_AUTH_CNF, + (tANI_U32 *) &mlmAuthCnf); + sessionEntry->sta_auth_retries_for_code17 = 0; + } +} /*** end limRestoreFromAuthState() ***/ + + + +/** + * limLookUpKeyMappings() + * + *FUNCTION: + * This function is called in limProcessAuthFrame() function + * to determine if there exists a Key Mapping key for a given + * MAC address. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param macAddr MAC address of the peer STA for which existence + * of Key Mapping key is to be determined + * + * @return pKeyMapEntry - Pointer to the keyMapEntry returned by CFG + */ + +tCfgWepKeyEntry * +limLookUpKeyMappings(tSirMacAddr macAddr) +{ + return NULL; +} /****** end limLookUpKeyMappings() ******/ + + + +/** + * limEncryptAuthFrame() + * + *FUNCTION: + * This function is called in limProcessAuthFrame() function + * to encrypt Authentication frame3 body. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param keyId key id to used + * @param pKey Pointer to the key to be used for encryption + * @param pPlainText Pointer to the body to be encrypted + * @param pEncrBody Pointer to the encrypted auth frame body + * @param keyLength 8 (WEP40) or 16 (WEP104) + * @return None + */ + +void +limEncryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 keyId, tANI_U8 *pKey, tANI_U8 *pPlainText, + tANI_U8 *pEncrBody, tANI_U32 keyLength) +{ + tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH]; + tANI_U16 frame_len; + + frame_len = ((tpSirMacAuthFrameBody)pPlainText)->length + + SIR_MAC_AUTH_FRAME_INFO_LEN + SIR_MAC_CHALLENGE_ID_LEN; + keyLength += 3; + + // Bytes 0-2 of seed is IV + // Read TSF timestamp into seed to get random IV - 1st 3 bytes + halGetTxTSFtimer(pMac, (tSirMacTimeStamp *) &seed); + + // Bytes 3-7 of seed is key + vos_mem_copy((tANI_U8 *) &seed[3], pKey, keyLength - 3); + + // Compute CRC-32 and place them in last 4 bytes of plain text + limComputeCrc32(icv, pPlainText, frame_len); + + vos_mem_copy( pPlainText + frame_len, + icv, SIR_MAC_WEP_ICV_LENGTH); + + // Run RC4 on plain text with the seed + limRC4(pEncrBody + SIR_MAC_WEP_IV_LENGTH, + (tANI_U8 *) pPlainText, seed, keyLength, + frame_len + SIR_MAC_WEP_ICV_LENGTH); + + // Prepare IV + pEncrBody[0] = seed[0]; + pEncrBody[1] = seed[1]; + pEncrBody[2] = seed[2]; + pEncrBody[3] = keyId << 6; +} /****** end limEncryptAuthFrame() ******/ + + + +/** + * limComputeCrc32() + * + *FUNCTION: + * This function is called to compute CRC-32 on a given source. + * Used while encrypting/decrypting Authentication frame 3. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDest Destination location for computed CRC + * @param pSrc Source location to be CRC computed + * @param len Length over which CRC to be computed + * @return None + */ + +void +limComputeCrc32(tANI_U8 *pDest, tANI_U8 * pSrc, tANI_U16 len) +{ + tANI_U32 crc; + int i; + + crc = 0; + crc = ~crc; + + while(len-- > 0) + crc = limCrcUpdate(crc, *pSrc++); + + crc = ~crc; + + for (i=0; i < SIR_MAC_WEP_IV_LENGTH; i++) + { + pDest[i] = (tANI_U8)crc; + crc >>= 8; + } +} /****** end limComputeCrc32() ******/ + + + +/** + * limRC4() + * + *FUNCTION: + * This function is called to run RC4 algorithm. Called while + * encrypting/decrypting Authentication frame 3. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDest Destination location for encrypted text + * @param pSrc Source location to be encrypted + * @param seed Contains seed (IV + key) for PRNG + * @param keyLength 8 (WEP40) or 16 (WEP104) + * @param frameLen Length of the frame + * + * @return None + */ + +void +limRC4(tANI_U8 *pDest, tANI_U8 *pSrc, tANI_U8 *seed, tANI_U32 keyLength, tANI_U16 frameLen) +{ + typedef struct + { + tANI_U8 i, j; + tANI_U8 sbox[256]; + } tRC4Context; + + tRC4Context ctx; + + { + tANI_U16 i, j, k; + + // + // Initialize sbox using seed + // + + ctx.i = ctx.j = 0; + for (i=0; i<256; i++) + ctx.sbox[i] = (tANI_U8)i; + + j = 0; + k = 0; + for (i=0; i<256; i++) + { + tANI_U8 temp; + if ( k < LIM_SEED_LENGTH ) + j = (tANI_U8)(j + ctx.sbox[i] + seed[k]); + temp = ctx.sbox[i]; + ctx.sbox[i] = ctx.sbox[j]; + ctx.sbox[j] = temp; + + if (++k >= keyLength) + k = 0; + } + } + + { + tANI_U8 i = ctx.i; + tANI_U8 j = ctx.j; + tANI_U16 len = frameLen; + + while (len-- > 0) + { + tANI_U8 temp1, temp2; + + i = (tANI_U8)(i+1); + temp1 = ctx.sbox[i]; + j = (tANI_U8)(j + temp1); + + ctx.sbox[i] = temp2 = ctx.sbox[j]; + ctx.sbox[j] = temp1; + + temp1 = (tANI_U8)(temp1 + temp2); + temp1 = ctx.sbox[temp1]; + temp2 = (tANI_U8)(pSrc ? *pSrc++ : 0); + + *pDest++ = (tANI_U8)(temp1 ^ temp2); + } + + ctx.i = i; + ctx.j = j; + } +} /****** end limRC4() ******/ + + + +/** + * limDecryptAuthFrame() + * + *FUNCTION: + * This function is called in limProcessAuthFrame() function + * to decrypt received Authentication frame3 body. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pKey Pointer to the key to be used for decryption + * @param pEncrBody Pointer to the body to be decrypted + * @param pPlainBody Pointer to the decrypted body + * @param keyLength 8 (WEP40) or 16 (WEP104) + * + * @return Decrypt result - eSIR_SUCCESS for success and + * LIM_DECRYPT_ICV_FAIL for ICV mismatch. + * If decryption is a success, pBody will + * have decrypted auth frame body. + */ + +tANI_U8 +limDecryptAuthFrame(tpAniSirGlobal pMac, tANI_U8 *pKey, tANI_U8 *pEncrBody, + tANI_U8 *pPlainBody, tANI_U32 keyLength, tANI_U16 frameLen) +{ + tANI_U8 seed[LIM_SEED_LENGTH], icv[SIR_MAC_WEP_ICV_LENGTH]; + int i; + keyLength += 3; + + + // Bytes 0-2 of seed is received IV + vos_mem_copy((tANI_U8 *) seed, pEncrBody, SIR_MAC_WEP_IV_LENGTH - 1); + + // Bytes 3-7 of seed is key + vos_mem_copy((tANI_U8 *) &seed[3], pKey, keyLength - 3); + + // Run RC4 on encrypted text with the seed + limRC4(pPlainBody, + pEncrBody + SIR_MAC_WEP_IV_LENGTH, + seed, + keyLength, + frameLen); + + PELOG4(limLog(pMac, LOG4, FL("plainbody is ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pPlainBody, frameLen);) + + // Compute CRC-32 and place them in last 4 bytes of encrypted body + limComputeCrc32(icv, + (tANI_U8 *) pPlainBody, + (frameLen - SIR_MAC_WEP_ICV_LENGTH)); + + // Compare RX_ICV with computed ICV + for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++) + { + PELOG4(limLog(pMac, LOG4, FL(" computed ICV%d[%x], rxed ICV%d[%x]"), + i, icv[i], i, pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]);) + if (icv[i] != pPlainBody[frameLen - SIR_MAC_WEP_ICV_LENGTH + i]) + return LIM_DECRYPT_ICV_FAIL; + } + + return eSIR_SUCCESS; +} /****** end limDecryptAuthFrame() ******/ + +/** + * limPostSmeSetKeysCnf + * + * A utility API to send MLM_SETKEYS_CNF to SME + */ +void limPostSmeSetKeysCnf( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tLimMlmSetKeysCnf *mlmSetKeysCnf) +{ + // Prepare and Send LIM_MLM_SETKEYS_CNF + vos_mem_copy( (tANI_U8 *) &mlmSetKeysCnf->peerMacAddr, + (tANI_U8 *) pMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + + vos_mem_copy( (tANI_U8 *) &mlmSetKeysCnf->peerMacAddr, + (tANI_U8 *) pMlmSetKeysReq->peerMacAddr, + sizeof(tSirMacAddr)); + + + /// Free up buffer allocated for mlmSetKeysReq + vos_mem_zero(pMlmSetKeysReq, sizeof(tLimMlmSetKeysReq)); + vos_mem_free( pMlmSetKeysReq ); + pMac->lim.gpLimMlmSetKeysReq = NULL; + + limPostSmeMessage( pMac, + LIM_MLM_SETKEYS_CNF, + (tANI_U32 *) mlmSetKeysCnf ); +} + +/** + * limPostSmeRemoveKeysCnf + * + * A utility API to send MLM_REMOVEKEY_CNF to SME + */ +void limPostSmeRemoveKeyCnf( tpAniSirGlobal pMac, + tpPESession psessionEntry, + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq, + tLimMlmRemoveKeyCnf *mlmRemoveKeyCnf) +{ + // Prepare and Send LIM_MLM_REMOVEKEYS_CNF + vos_mem_copy( (tANI_U8 *) &mlmRemoveKeyCnf->peerMacAddr, + (tANI_U8 *) pMlmRemoveKeyReq->peerMacAddr, + sizeof(tSirMacAddr)); + + /// Free up buffer allocated for mlmRemoveKeysReq + vos_mem_free( pMlmRemoveKeyReq ); + pMac->lim.gpLimMlmRemoveKeyReq = NULL; + + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; //Restore the state. + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + limPostSmeMessage( pMac, + LIM_MLM_REMOVEKEY_CNF, + (tANI_U32 *) mlmRemoveKeyCnf ); +} + +/** + * limSendSetBssKeyReq() + * + *FUNCTION: + * This function is called from limProcessMlmSetKeysReq(), + * when PE is trying to setup the Group Keys related + * to a specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer + * @return none + */ +void limSendSetBssKeyReq( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tpPESession psessionEntry) +{ +tSirMsgQ msgQ; +tpSetBssKeyParams pSetBssKeyParams = NULL; +tLimMlmSetKeysCnf mlmSetKeysCnf; +tSirRetStatus retCode; +tANI_U32 val = 0; + + if(pMlmSetKeysReq->numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + limLog( pMac, LOG1, + FL( "numKeys = %d is more than SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS" ), pMlmSetKeysReq->numKeys); + + // Respond to SME with error code + mlmSetKeysCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + // Package WDA_SET_BSSKEY_REQ message parameters + + pSetBssKeyParams = vos_mem_malloc(sizeof( tSetBssKeyParams )); + if ( NULL == pSetBssKeyParams ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during SET_BSSKEY" )); + + // Respond to SME with error code + mlmSetKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + vos_mem_set( (void *) pSetBssKeyParams, + sizeof( tSetBssKeyParams ), 0); + + // Update the WDA_SET_BSSKEY_REQ parameters + pSetBssKeyParams->bssIdx = psessionEntry->bssIdx; + pSetBssKeyParams->encType = pMlmSetKeysReq->edType; + + + if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val)) + { + limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC" )); + } + + pSetBssKeyParams->singleTidRc = (tANI_U8)val; + + /* Update PE session Id*/ + pSetBssKeyParams->sessionId = psessionEntry ->peSessionId; + + if(pMlmSetKeysReq->key[0].keyId && + ((pMlmSetKeysReq->edType == eSIR_ED_WEP40) || + (pMlmSetKeysReq->edType == eSIR_ED_WEP104)) + ) + { + /* IF the key id is non-zero and encryption type is WEP, Send all the 4 + * keys to HAL with filling the key at right index in pSetBssKeyParams->key. */ + pSetBssKeyParams->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + vos_mem_copy( (tANI_U8 *) &pSetBssKeyParams->key[pMlmSetKeysReq->key[0].keyId], + (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof(pMlmSetKeysReq->key[0])); + + } + else + { + pSetBssKeyParams->numKeys = pMlmSetKeysReq->numKeys; + vos_mem_copy( (tANI_U8 *) &pSetBssKeyParams->key, + (tANI_U8 *) &pMlmSetKeysReq->key, + sizeof( tSirKeys ) * pMlmSetKeysReq->numKeys ); + } + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + msgQ.type = WDA_SET_BSSKEY_REQ; + // + // FIXME_GEN4 + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pSetBssKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_SET_BSSKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, + FL("Posting SET_BSSKEY to HAL failed, reason=%X"), + retCode ); + + // Respond to SME with LIM_MLM_SETKEYS_CNF + mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + else + return; // Continue after WDA_SET_BSSKEY_RSP... + +end: + limPostSmeSetKeysCnf( pMac, + pMlmSetKeysReq, + &mlmSetKeysCnf ); + +} + +/** + * @function : limSendSetStaKeyReq() + * + * @brief : This function is called from limProcessMlmSetKeysReq(), + * when PE is trying to setup the Unicast Keys related + * to a specified STA with specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmSetKeysReq Pointer to MLM_SETKEYS_REQ buffer + * @param staIdx STA index for which the keys are being set + * @param defWEPIdx The default WEP key index [0..3] + * @return none + */ +void limSendSetStaKeyReq( tpAniSirGlobal pMac, + tLimMlmSetKeysReq *pMlmSetKeysReq, + tANI_U16 staIdx, + tANI_U8 defWEPIdx, + tpPESession sessionEntry) +{ +tSirMsgQ msgQ; +tpSetStaKeyParams pSetStaKeyParams = NULL; +tLimMlmSetKeysCnf mlmSetKeysCnf; +tSirRetStatus retCode; +tANI_U32 val = 0; + + // Package WDA_SET_STAKEY_REQ message parameters + pSetStaKeyParams = vos_mem_malloc(sizeof( tSetStaKeyParams )); + if ( NULL == pSetStaKeyParams ) + { + limLog( pMac, LOGP, FL( "Unable to allocate memory during SET_BSSKEY" )); + return; + } + else + vos_mem_set( (void *) pSetStaKeyParams, sizeof( tSetStaKeyParams ), 0); + + // Update the WDA_SET_STAKEY_REQ parameters + pSetStaKeyParams->staIdx = staIdx; + pSetStaKeyParams->encType = pMlmSetKeysReq->edType; + + + if(eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_SINGLE_TID_RC, &val)) + { + limLog( pMac, LOGP, FL( "Unable to read WNI_CFG_SINGLE_TID_RC" )); + } + + pSetStaKeyParams->singleTidRc = (tANI_U8)val; + + /* Update PE session ID*/ + pSetStaKeyParams->sessionId = sessionEntry->peSessionId; + + /** + * For WEP - defWEPIdx indicates the default WEP + * Key to be used for TX + * For all others, there's just one key that can + * be used and hence it is assumed that + * defWEPIdx = 0 (from the caller) + */ + + pSetStaKeyParams->defWEPIdx = defWEPIdx; + + /** Store the Previous MlmState*/ + sessionEntry->limPrevMlmState = sessionEntry->limMlmState; + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + if(sessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && !pMlmSetKeysReq->key[0].unicast) { + sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_BCASTKEY_STATE; + msgQ.type = WDA_SET_STA_BCASTKEY_REQ; + }else { + sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_KEY_STATE; + msgQ.type = WDA_SET_STAKEY_REQ; + } + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState)); + + /** + * In the Case of WEP_DYNAMIC, ED_TKIP and ED_CCMP + * the Key[0] contains the KEY, so just copy that alone, + * for the case of WEP_STATIC the hal gets the key from cfg + */ + switch( pMlmSetKeysReq->edType ) { + case eSIR_ED_WEP40: + case eSIR_ED_WEP104: + // FIXME! Is this OK? + if( 0 == pMlmSetKeysReq->numKeys ) { + tANI_U32 i; + + for(i=0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS ;i++) + { + vos_mem_copy( (tANI_U8 *) &pSetStaKeyParams->key[i], + (tANI_U8 *) &pMlmSetKeysReq->key[i], sizeof( tSirKeys )); + } + pSetStaKeyParams->wepType = eSIR_WEP_STATIC; + sessionEntry->limMlmState = eLIM_MLM_WT_SET_STA_KEY_STATE; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, sessionEntry->peSessionId, sessionEntry->limMlmState)); + }else { + /*This case the keys are coming from upper layer so need to fill the + * key at the default wep key index and send to the HAL */ + if (defWEPIdx >= SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + { + limLog( pMac, LOGE, FL("WEPIdx length %d more than " + "the Max limit, reset to Max"),defWEPIdx); + vos_mem_free (pSetStaKeyParams); + return; + } + vos_mem_copy((tANI_U8 *) &pSetStaKeyParams->key[defWEPIdx], + (tANI_U8 *) &pMlmSetKeysReq->key[0], + sizeof( pMlmSetKeysReq->key[0] )); + pMlmSetKeysReq->numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + + } + break; + case eSIR_ED_TKIP: + case eSIR_ED_CCMP: +#ifdef FEATURE_WLAN_WAPI + case eSIR_ED_WPI: +#endif + { + vos_mem_copy( (tANI_U8 *) &pSetStaKeyParams->key, + (tANI_U8 *) &pMlmSetKeysReq->key[0], sizeof( tSirKeys )); + } + break; + default: + break; + } + + + // + // FIXME_GEN4 + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pSetStaKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG1, FL( "Sending WDA_SET_STAKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, sessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) { + limLog( pMac, LOGE, FL("Posting SET_STAKEY to HAL failed, reason=%X"), retCode ); + // Respond to SME with LIM_MLM_SETKEYS_CNF + mlmSetKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + }else + return; // Continue after WDA_SET_STAKEY_RSP... + + limPostSmeSetKeysCnf( pMac, pMlmSetKeysReq, &mlmSetKeysCnf ); +} + +/** + * limSendRemoveBssKeyReq() + * + *FUNCTION: + * This function is called from limProcessMlmRemoveReq(), + * when PE is trying to Remove a Group Key related + * to a specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmRemoveKeyReq Pointer to MLM_REMOVEKEY_REQ buffer + * @return none + */ +void limSendRemoveBssKeyReq( tpAniSirGlobal pMac, + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq, + tpPESession psessionEntry) +{ +tSirMsgQ msgQ; +tpRemoveBssKeyParams pRemoveBssKeyParams = NULL; +tLimMlmRemoveKeyCnf mlmRemoveKeysCnf; +tSirRetStatus retCode; + + // Package WDA_REMOVE_BSSKEY_REQ message parameters + pRemoveBssKeyParams = vos_mem_malloc(sizeof( tRemoveBssKeyParams )); + if ( NULL == pRemoveBssKeyParams ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during REMOVE_BSSKEY" )); + + // Respond to SME with error code + mlmRemoveKeysCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + vos_mem_set( (void *) pRemoveBssKeyParams, + sizeof( tRemoveBssKeyParams ), 0); + + // Update the WDA_REMOVE_BSSKEY_REQ parameters + pRemoveBssKeyParams->bssIdx = psessionEntry->bssIdx; + pRemoveBssKeyParams->encType = pMlmRemoveKeyReq->edType; + pRemoveBssKeyParams->keyId = pMlmRemoveKeyReq->keyId; + pRemoveBssKeyParams->wepType = pMlmRemoveKeyReq->wepType; + + /* Update PE session Id*/ + + pRemoveBssKeyParams->sessionId = psessionEntry->peSessionId; + + msgQ.type = WDA_REMOVE_BSSKEY_REQ; + // + // FIXME_GEN4 + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pRemoveBssKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_REMOVE_BSSKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGE, + FL("Posting REMOVE_BSSKEY to HAL failed, reason=%X"), + retCode ); + + // Respond to SME with LIM_MLM_REMOVEKEYS_CNF + mlmRemoveKeysCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + else + return; + +end: + limPostSmeRemoveKeyCnf( pMac, + psessionEntry, + pMlmRemoveKeyReq, + &mlmRemoveKeysCnf ); + +} + +/** + * limSendRemoveStaKeyReq() + * + *FUNCTION: + * This function is called from limProcessMlmRemoveKeysReq(), + * when PE is trying to setup the Unicast Keys related + * to a specified STA with specified encryption type + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMlmRemoveKeysReq Pointer to MLM_REMOVEKEYS_REQ buffer + * @param staIdx STA index for which the keys are being set + * @return none + */ +void limSendRemoveStaKeyReq( tpAniSirGlobal pMac, + tLimMlmRemoveKeyReq *pMlmRemoveKeyReq, + tANI_U16 staIdx, + tpPESession psessionEntry) +{ +tSirMsgQ msgQ; +tpRemoveStaKeyParams pRemoveStaKeyParams = NULL; +tLimMlmRemoveKeyCnf mlmRemoveKeyCnf; +tSirRetStatus retCode; + + pRemoveStaKeyParams = vos_mem_malloc(sizeof( tRemoveStaKeyParams )); + if ( NULL == pRemoveStaKeyParams ) + { + limLog( pMac, LOGE, + FL( "Unable to allocate memory during REMOVE_STAKEY" )); + + // Respond to SME with error code + mlmRemoveKeyCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + goto end; + } + else + vos_mem_set( (void *) pRemoveStaKeyParams, + sizeof( tRemoveStaKeyParams ), 0); + + if( (pMlmRemoveKeyReq->edType == eSIR_ED_WEP104 || pMlmRemoveKeyReq->edType == eSIR_ED_WEP40) && + pMlmRemoveKeyReq->wepType == eSIR_WEP_STATIC ) + { + PELOGE(limLog(pMac, LOGE, FL("Request to remove static WEP keys through station interface\n Should use BSS interface"));) + mlmRemoveKeyCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + // Update the WDA_REMOVEKEY_REQ parameters + pRemoveStaKeyParams->staIdx = staIdx; + pRemoveStaKeyParams->encType = pMlmRemoveKeyReq->edType; + pRemoveStaKeyParams->keyId = pMlmRemoveKeyReq->keyId; + pRemoveStaKeyParams->unicast = pMlmRemoveKeyReq->unicast; + + /* Update PE session ID*/ + pRemoveStaKeyParams->sessionId = psessionEntry->peSessionId; + + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.type = WDA_REMOVE_STAKEY_REQ; + // + // FIXME_GEN4 + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pRemoveStaKeyParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_REMOVE_STAKEY_REQ..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if (eSIR_SUCCESS != retCode) + { + limLog( pMac, LOGE, + FL("Posting REMOVE_STAKEY to HAL failed, reason=%X"), + retCode ); + vos_mem_free(pRemoveStaKeyParams); + pRemoveStaKeyParams = NULL; + + // Respond to SME with LIM_MLM_REMOVEKEY_CNF + mlmRemoveKeyCnf.resultCode = eSIR_SME_HAL_SEND_MESSAGE_FAIL; + } + else + return; + +end: + if (pRemoveStaKeyParams) + { + vos_mem_free(pRemoveStaKeyParams); + } + limPostSmeRemoveKeyCnf( pMac, + psessionEntry, + pMlmRemoveKeyReq, + &mlmRemoveKeyCnf ); + +} + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h new file mode 100644 index 000000000000..2526f4e4c124 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSecurityUtils.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSecurityUtils.h contains the utility definitions + * related to WEP encryption/decryption etc. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SECURITY_UTILS_H +#define __LIM_SECURITY_UTILS_H +#include "sirMacProtDef.h" //for tSirMacAuthFrameBody + +#define LIM_ENCR_AUTH_BODY_LEN (sizeof(tSirMacAuthFrameBody) + \ + SIR_MAC_WEP_IV_LENGTH + \ + SIR_MAC_WEP_ICV_LENGTH) + +#define LIM_ENCR_AUTH_BODY_LEN_SAP (SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + \ + SIR_MAC_CHALLENGE_ID_LEN + \ + SIR_MAC_AUTH_FRAME_INFO_LEN + \ + SIR_MAC_WEP_IV_LENGTH + \ + SIR_MAC_WEP_ICV_LENGTH) + +#define LIM_ENCR_AUTH_INFO_LEN (SIR_MAC_AUTH_FRAME_INFO_LEN +\ + SIR_MAC_WEP_IV_LENGTH + \ + SIR_MAC_WEP_ICV_LENGTH + \ + SIR_MAC_CHALLENGE_ID_LEN) + +struct tLimPreAuthNode; + +tANI_U8 limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType, tpPESession); + +// MAC based authentication related functions +void limInitPreAuthList(tpAniSirGlobal); +void limDeletePreAuthList(tpAniSirGlobal); +struct tLimPreAuthNode *limSearchPreAuthList(tpAniSirGlobal, tSirMacAddr); +void limAddPreAuthNode(tpAniSirGlobal, struct tLimPreAuthNode *); +void limDeletePreAuthNode(tpAniSirGlobal, tSirMacAddr); +void limReleasePreAuthNode(tpAniSirGlobal pMac, tpLimPreAuthNode pAuthNode); +void limRestoreFromAuthState(tpAniSirGlobal, + tSirResultCodes, tANI_U16,tpPESession); +tANI_U8 limDeleteOpenAuthPreAuthNode(tpAniSirGlobal pMac); + +// Encryption/Decryption related functions +tCfgWepKeyEntry *limLookUpKeyMappings(tSirMacAddr); +void limComputeCrc32(tANI_U8 *, tANI_U8 *, tANI_U16); +void limRC4(tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16); +void limEncryptAuthFrame(tpAniSirGlobal, tANI_U8, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32); +tANI_U8 limDecryptAuthFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16); + +void limSendSetBssKeyReq( tpAniSirGlobal, tLimMlmSetKeysReq *,tpPESession ); +void limSendSetStaKeyReq( tpAniSirGlobal, tLimMlmSetKeysReq *, tANI_U16, tANI_U8,tpPESession); +void limPostSmeSetKeysCnf( tpAniSirGlobal, tLimMlmSetKeysReq *, tLimMlmSetKeysCnf * ); + +void limSendRemoveBssKeyReq(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq,tpPESession); +void limSendRemoveStaKeyReq(tpAniSirGlobal pMac, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq, tANI_U16 staIdx,tpPESession); +void limPostSmeRemoveKeyCnf(tpAniSirGlobal pMac, tpPESession psessionEntry, tLimMlmRemoveKeyReq * pMlmRemoveKeyReq, tLimMlmRemoveKeyCnf * mlmRemoveKeyCnf); + +#define PTAPS 0xedb88320 + +static inline tANI_U32 +limCrcUpdate(tANI_U32 crc, tANI_U8 x) +{ + + // Update CRC computation for 8 bits contained in x + // + tANI_U32 z; + tANI_U32 fb; + int i; + + z = crc^x; + for (i=0; i<8; i++) { + fb = z & 1; + z >>= 1; + if (fb) z ^= PTAPS; + } + return z; +} + +#endif /* __LIM_SECURITY_UTILS_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c new file mode 100644 index 000000000000..feb335124a46 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -0,0 +1,7205 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/** + * \file limSendManagementFrames.c + * + * \brief Code for preparing and sending 802.11 Management frames + * + + * + */ + +#include "sirApi.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" +#include "cfgApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "limPropExtsUtils.h" +#include "dot11f.h" +#include "limStaHashApi.h" +#include "schApi.h" +#include "limSendMessages.h" +#include "limAssocUtils.h" +#include "limFT.h" +#ifdef WLAN_FEATURE_11W +#include "wniCfg.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#include "wlan_qct_wda.h" + +#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0) +//////////////////////////////////////////////////////////////////////// + +tSirRetStatus limStripOffExtCapIE(tpAniSirGlobal pMac, + tANI_U8 *addIE, + tANI_U16 *addnIELen, + tANI_U8 *pExtractedExtCapIEBuf ) +{ + tANI_U8* tempbuf = NULL; + tANI_U16 tempLen = 0; + int left = *addnIELen; + tANI_U8 *ptr = addIE; + tANI_U8 elem_id, elem_len; + + if (NULL == addIE) + { + PELOGE(limLog(pMac, LOG1, FL("NULL addIE pointer"));) + return eSIR_IGNORE_IE ; + } + + tempbuf = vos_mem_malloc(left); + if ( NULL == tempbuf ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store addn IE"));) + return eSIR_MEM_ALLOC_FAILED; + } + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if (elem_len > left) + { + limLog( pMac, LOGE, + FL("Invalid IEs eid = %d elem_len=%d left=%d"), + elem_id,elem_len,left); + vos_mem_free(tempbuf); + return eSIR_FAILURE; + } + if ( !(DOT11F_EID_EXTCAP == elem_id) ) + { + vos_mem_copy (tempbuf + tempLen, &ptr[0], elem_len + 2); + tempLen += (elem_len + 2); + } + else + { + if ( NULL != pExtractedExtCapIEBuf ) + { + vos_mem_set(pExtractedExtCapIEBuf, + DOT11F_IE_EXTCAP_MAX_LEN + 2, 0); + if (elem_len <= DOT11F_IE_EXTCAP_MAX_LEN ) + { + vos_mem_copy (pExtractedExtCapIEBuf, &ptr[0], + elem_len + 2); + } + } + } + left -= elem_len; + ptr += (elem_len + 2); + } + vos_mem_copy (addIE, tempbuf, tempLen); + *addnIELen = tempLen; + vos_mem_free(tempbuf); + return eSIR_SUCCESS; +} + +void limUpdateExtCapIEtoStruct(tpAniSirGlobal pMac, + tANI_U8 *pBuf, + tDot11fIEExtCap *pDst) +{ + tANI_U8 pOut[DOT11F_IE_EXTCAP_MAX_LEN]; + tANI_U8 tag, len, *val; + + if ( NULL == pBuf ) + { + limLog( pMac, LOGE, + FL("Invalid Buffer Address")); + return; + } + if(NULL == pDst) + { + PELOGE(limLog(pMac, LOGE, + FL("NULL pDst pointer"));) + return ; + } + + /* Get tlv */ + tag = pBuf[0]; + len = pBuf[1]; + val = &pBuf[2]; + + if ( DOT11F_EID_EXTCAP != tag || + len > DOT11F_IE_EXTCAP_MAX_LEN ) + { + limLog( pMac, LOG1, + FL("Invalid IEs eid = %d elem_len=%d "), tag, len); + return; + } + + vos_mem_zero(pOut, DOT11F_IE_EXTCAP_MAX_LEN); + vos_mem_copy(pOut, val, len); + if ( DOT11F_PARSE_SUCCESS != dot11fUnpackIeExtCap( pMac, + pOut, len, pDst) ) + { + limLog( pMac, LOGE, + FL("dot11fUnpackIeExtCap Parse Error ")); + } +} + +tSirRetStatus limStripOffExtCapIEAndUpdateStruct(tpAniSirGlobal pMac, + tANI_U8* addIE, + tANI_U16 *addnIELen, + tDot11fIEExtCap * pDst ) +{ + tANI_U8 pExtractedExtCapIEBuf[DOT11F_IE_EXTCAP_MAX_LEN + 2]; + tSirRetStatus nSirStatus; + + vos_mem_set(( tANI_U8* )&pExtractedExtCapIEBuf[0], + DOT11F_IE_EXTCAP_MAX_LEN + 2, 0); + nSirStatus = limStripOffExtCapIE(pMac, addIE, addnIELen, + pExtractedExtCapIEBuf); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOG1, FL("Failed to strip off in" + "limStripOffExtCapIE status = (%d)."), + nSirStatus ); + return nSirStatus; + } + /* update the extracted ExtCap to struct*/ + limUpdateExtCapIEtoStruct(pMac, pExtractedExtCapIEBuf, pDst); + return nSirStatus; +} + +void limMergeExtCapIEStruct(tDot11fIEExtCap *pDst, + tDot11fIEExtCap *pSrc, + bool add) +{ + tANI_U8 *tempDst = (tANI_U8 *)pDst->bytes; + tANI_U8 *tempSrc = (tANI_U8 *)pSrc->bytes; + tANI_U8 structlen = DOT11F_IE_EXTCAP_MAX_LEN; + + // if src is not present, nothing to do + if(!pSrc->present) { + return; + } + + // if dst is not present, and add=false, nothing to do + if (!pDst->present && !add) { + return; + } + + // in other cases, need to merge the bits + pDst->present = 1; + while(tempDst && tempSrc && structlen--) + { + if (add) { + *tempDst |= *tempSrc; + } else { + *tempDst &= *tempSrc; + } + tempDst++; + tempSrc++; + } + pDst->num_bytes = lim_compute_ext_cap_ie_length(pDst); + + // if all bits are zero, it means it is not prsent. + if (pDst->num_bytes == 0) { + pDst->present = 0; + } +} + +/** + * + * \brief This function is called by various LIM modules to prepare the + * 802.11 frame MAC header + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pBD Pointer to the frame buffer that needs to be populate + * + * \param type Type of the frame + * + * \param subType Subtype of the frame + * + * \return eHalStatus + * + * + * The pFrameBuf argument points to the beginning of the frame buffer to + * which - a) The 802.11 MAC header is set b) Following this MAC header + * will be the MGMT frame payload The payload itself is populated by the + * caller API + * + * + */ + +tSirRetStatus limPopulateMacHeader( tpAniSirGlobal pMac, + tANI_U8* pBD, + tANI_U8 type, + tANI_U8 subType, + tSirMacAddr peerAddr, tSirMacAddr selfMacAddr) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tpSirMacMgmtHdr pMacHdr; + + /// Prepare MAC management header + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + // Prepare FC + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type; + pMacHdr->fc.subType = subType; + + // Prepare Address 1 + vos_mem_copy( (tANI_U8 *) pMacHdr->da, + (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + + // Prepare Address 2 + sirCopyMacAddr(pMacHdr->sa,selfMacAddr); + + // Prepare Address 3 + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + return statusCode; +} /*** end limPopulateMacHeader() ***/ + +/** + * \brief limSendProbeReqMgmtFrame + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pSsid SSID to be sent in Probe Request frame + * + * \param bssid BSSID to be sent in Probe Request frame + * + * \param nProbeDelay probe delay to be used before sending Probe Request + * frame + * + * \param nChannelNum Channel # on which the Probe Request is going out + * + * \param nAdditionalIELen if non-zero, include pAdditionalIE in the Probe Request frame + * + * \param pAdditionalIE if nAdditionalIELen is non zero, include this field in the Probe Request frame + * + * This function is called by various LIM modules to send Probe Request frame + * during active scan/learn phase. + * Probe request is sent out in the following scenarios: + * --heartbeat failure: session needed + * --join req: session needed + * --foreground scan: no session + * --background scan: no session + * --schBeaconProcessing: to get EDCA parameters: session needed + * + * + */ +tSirRetStatus +limSendProbeReqMgmtFrame(tpAniSirGlobal pMac, + tSirMacSSid *pSsid, + tSirMacAddr bssid, + tANI_U8 nChannelNum, + tSirMacAddr SelfMacAddr, + tANI_U32 dot11mode, + tANI_U32 nAdditionalIELen, + tANI_U8 *pAdditionalIE) +{ + tDot11fProbeRequest pr; + tANI_U32 nStatus, nBytes, nPayload; + tSirRetStatus nSirStatus; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U8 *p2pIe = NULL; + tANI_U32 txFlag = 0; + +#ifndef GEN4_SCAN + return eSIR_FAILURE; +#endif + +#if defined ( ANI_DVT_DEBUG ) + return eSIR_FAILURE; +#endif + + /* The probe req should not send 11ac capabilieties if band is 2.4GHz, + * unless enableVhtFor24GHz is enabled in INI. So if enableVhtFor24GHz + * is false and dot11mode is 11ac set it to 11n. + */ + if ( nChannelNum <= SIR_11B_CHANNEL_END && + ( FALSE == pMac->roam.configParam.enableVhtFor24GHz ) && + ( WNI_CFG_DOT11_MODE_11AC == dot11mode || + WNI_CFG_DOT11_MODE_11AC_ONLY == dot11mode ) ) + dot11mode = WNI_CFG_DOT11_MODE_11N; + /* + * session context may or may not be present, when probe request needs to be sent out. + * following cases exist: + * --heartbeat failure: session needed + * --join req: session needed + * --foreground scan: no session + * --background scan: no session + * --schBeaconProcessing: to get EDCA parameters: session needed + * If session context does not exist, some IEs will be populated from CFGs, + * e.g. Supported and Extended rate set IEs + */ + psessionEntry = peFindSessionByBssid(pMac,bssid,&sessionId); + + // The scheme here is to fill out a 'tDot11fProbeRequest' structure + // and then hand it off to 'dot11fPackProbeRequest' (for + // serialization). We start by zero-initializing the structure: + vos_mem_set(( tANI_U8* )&pr, sizeof( pr ), 0); + + // & delegating to assorted helpers: + PopulateDot11fSSID( pMac, pSsid, &pr.SSID ); + + if( nAdditionalIELen && pAdditionalIE ) + { + p2pIe = limGetP2pIEPtr(pMac, pAdditionalIE, nAdditionalIELen); + } + /* Don't include 11b rate only when device is doing P2P Search */ + if( ( WNI_CFG_DOT11_MODE_11B != dot11mode ) && + ( p2pIe != NULL ) && + /* Don't include 11b rate if it is a P2P serach or probe request is sent by P2P Client */ + ( ( ( pMac->lim.gpLimMlmScanReq != NULL ) && + pMac->lim.gpLimMlmScanReq->p2pSearch ) || + ( ( psessionEntry != NULL ) && + ( VOS_P2P_CLIENT_MODE == psessionEntry->pePersona ) ) + ) + ) + { + /* In the below API pass channel number > 14, do that it fills only + * 11a rates in supported rates */ + PopulateDot11fSuppRates( pMac, 15, &pr.SuppRates,psessionEntry); + } + else + { + PopulateDot11fSuppRates( pMac, nChannelNum, + &pr.SuppRates,psessionEntry); + + if ( WNI_CFG_DOT11_MODE_11B != dot11mode ) + { + PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates ); + } + } + +#if defined WLAN_FEATURE_VOWIFI + //Table 7-14 in IEEE Std. 802.11k-2008 says + //DS params "can" be present in RRM is disabled and "is" present if + //RRM is enabled. It should be ok even if we add it into probe req when + //RRM is not enabled. + PopulateDot11fDSParams( pMac, &pr.DSParams, nChannelNum, psessionEntry ); + //Call RRM module to get the tx power for management used. + { + tANI_U8 txPower = (tANI_U8) rrmGetMgmtTxPower( pMac, psessionEntry ); + PopulateDot11fWFATPC( pMac, &pr.WFATPC, txPower, 0 ); + } +#endif + + if (psessionEntry != NULL ) { + psessionEntry->htCapability = IS_DOT11_MODE_HT(dot11mode); + //Include HT Capability IE + if (psessionEntry->htCapability) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pr.HTCaps ); + } + } else { //psessionEntry == NULL + if (IS_DOT11_MODE_HT(dot11mode)) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pr.HTCaps ); + } + } + + if((nChannelNum <= SIR_11B_CHANNEL_END) + && (!IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + && (!pMac->roam.configParam.channelBondingMode24GHz)) + { + pr.HTCaps.supportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + pr.HTCaps.shortGI40MHz = 0; + } +#ifdef WLAN_FEATURE_11AC + if (psessionEntry != NULL ) { + psessionEntry->vhtCapability = IS_DOT11_MODE_VHT(dot11mode); + //Include HT Capability IE + if (psessionEntry->vhtCapability) + { + PopulateDot11fVHTCaps( pMac, &pr.VHTCaps, + psessionEntry->currentOperChannel , eSIR_FALSE ); + } + } else { + if (IS_DOT11_MODE_VHT(dot11mode)) + { + PopulateDot11fVHTCaps( pMac, &pr.VHTCaps, nChannelNum, eSIR_FALSE ); + } + } +#endif + + + // That's it-- now we pack it. First, how much space are we going to + // need? + nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Probe Request (0x%08x)."), nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for a Probe Request (" + "0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAdditionalIELen; + + // Ok-- try to allocate some memory: + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Pro" + "be Request."), nBytes ); + return eSIR_MEM_ALLOC_FAILED; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_REQ, bssid, SelfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Probe Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; // allocated! + } + + // That done, pack the Probe Request: + nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Probe Request (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a P" + "robe Request (0x%08x)."), nStatus ); + } + + // Append any AddIE if present. + if( nAdditionalIELen ) + { + vos_mem_copy( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, + pAdditionalIE, nAdditionalIELen ); + nPayload += nAdditionalIELen; + } + + /* If this probe request is sent during P2P Search State, then we need + * to send it at OFDM rate. + */ + if( ( SIR_BAND_5_GHZ == limGetRFBand(nChannelNum)) + || (( pMac->lim.gpLimMlmScanReq != NULL) && + pMac->lim.gpLimMlmScanReq->p2pSearch ) + /* For unicast probe req mgmt from Join function + we don't set above variables. So we need to add + one more check whether it is pePersona is P2P_CLIENT or not */ + || ( ( psessionEntry != NULL ) && + ( VOS_P2P_CLIENT_MODE == psessionEntry->pePersona ) ) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if( ( psessionEntry != NULL ) && ( psessionEntry->is11Gonly == true ) && + ( !IS_BROADCAST_MAC(bssid) ) ){ + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) sizeof(tSirMacMgmtHdr) + nPayload, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("could not send Probe Request frame!" )); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} // End limSendProbeReqMgmtFrame. + +tSirRetStatus limGetAddnIeForProbeResp(tpAniSirGlobal pMac, + tANI_U8* addIE, tANI_U16 *addnIELen, + tANI_U8 probeReqP2pIe) +{ + /* If Probe request doesn't have P2P IE, then take out P2P IE + from additional IE */ + if(!probeReqP2pIe) + { + tANI_U8* tempbuf = NULL; + tANI_U16 tempLen = 0; + int left = *addnIELen; + v_U8_t *ptr = addIE; + v_U8_t elem_id, elem_len; + + if(NULL == addIE) + { + PELOGE(limLog(pMac, LOGE, + FL(" NULL addIE pointer"));) + return eSIR_FAILURE; + } + + tempbuf = vos_mem_malloc(left); + if ( NULL == tempbuf ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store addn IE"));) + return eSIR_MEM_ALLOC_FAILED; + } + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + limLog( pMac, LOGE, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + elem_id,elem_len,left); + vos_mem_free(tempbuf); + return eSIR_FAILURE; + } + if ( !( (SIR_MAC_EID_VENDOR == elem_id) && + (memcmp(&ptr[2], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE)==0) ) ) + { + vos_mem_copy (tempbuf + tempLen, &ptr[0], elem_len + 2); + tempLen += (elem_len + 2); + } + left -= elem_len; + ptr += (elem_len + 2); + } + vos_mem_copy (addIE, tempbuf, tempLen); + *addnIELen = tempLen; + vos_mem_free(tempbuf); + } + return eSIR_SUCCESS; +} + +void +limSendProbeRspMgmtFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tpAniSSID pSsid, + short nStaId, + tANI_U8 nKeepAlive, + tpPESession psessionEntry, + tANI_U8 probeReqP2pIe) +{ + tDot11fProbeResponse *pFrm; + tSirRetStatus nSirStatus; + tANI_U32 cfg, nPayload, nStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U8 *pFrame; + void *pPacket; + eHalStatus halstatus; + tANI_U32 addnIEPresent; + tANI_U32 addnIE1Len=0; + tANI_U32 addnIE2Len=0; + tANI_U32 addnIE3Len=0; + tANI_U16 totalAddnIeLen = 0; + tANI_U32 wpsApEnable=0, tmp; + tANI_U32 txFlag = 0; + tANI_U8 *addIE = NULL; + tANI_U8 *pP2pIe = NULL; + tANI_U8 noaLen = 0; + tANI_U8 total_noaLen = 0; + tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + + SIR_P2P_IE_HEADER_LEN]; + tANI_U8 noaIe[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; + tDot11fIEExtCap extractedExtCap; + tANI_BOOLEAN extractedExtCapFlag = eANI_BOOLEAN_TRUE; + tANI_U32 nBytes = 0; + + if(pMac->gDriverType == eDRIVER_TYPE_MFG) // We don't answer requests + { + return; // in this case. + } + + if(NULL == psessionEntry) + { + return; + } + + pFrm = vos_mem_malloc(sizeof(tDot11fProbeResponse)); + if ( NULL == pFrm ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory in limSendProbeRspMgmtFrame") ); + return; + } + + vos_mem_set(( tANI_U8* )&extractedExtCap, sizeof( tDot11fIEExtCap ), 0); + + // Fill out 'frm', after which we'll just hand the struct off to + // 'dot11fPackProbeResponse'. + vos_mem_set(( tANI_U8* )pFrm, sizeof( tDot11fProbeResponse ), 0); + + // Timestamp to be updated by TFP, below. + + // Beacon Interval: + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + pFrm->BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval; + } + else + { + nSirStatus = wlan_cfgGetInt( pMac, WNI_CFG_BEACON_INTERVAL, &cfg); + if (eSIR_SUCCESS != nSirStatus) + { + limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BEACON_INTERVAL from CFG (%d)."), + nSirStatus ); + vos_mem_free(pFrm); + return; + } + pFrm->BeaconInterval.interval = ( tANI_U16 ) cfg; + } + + PopulateDot11fCapabilities( pMac, &pFrm->Capabilities, psessionEntry ); + PopulateDot11fSSID( pMac, ( tSirMacSSid* )pSsid, &pFrm->SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->SuppRates,psessionEntry); + + PopulateDot11fDSParams( pMac, &pFrm->DSParams, psessionEntry->currentOperChannel,psessionEntry); + PopulateDot11fIBSSParams( pMac, &pFrm->IBSSParams, psessionEntry ); + + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if(psessionEntry->wps_state != SAP_WPS_DISABLED) + { + PopulateDot11fProbeResWPSIEs(pMac, &pFrm->WscProbeRes, psessionEntry); + } + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE ); + + wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP; + + if (wpsApEnable) + { + PopulateDot11fWscInProbeRes(pMac, &pFrm->WscProbeRes); + } + + if (pMac->lim.wscIeInfo.probeRespWscEnrollmentState == eLIM_WSC_ENROLL_BEGIN) + { + PopulateDot11fWscRegistrarInfoInProbeRes(pMac, &pFrm->WscProbeRes); + pMac->lim.wscIeInfo.probeRespWscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS; + } + + if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END) + { + DePopulateDot11fWscRegistrarInfoInProbeRes(pMac, &pFrm->WscProbeRes); + pMac->lim.wscIeInfo.probeRespWscEnrollmentState = eLIM_WSC_ENROLL_NOOP; + } + } + + PopulateDot11fCountry( pMac, &pFrm->Country, psessionEntry); + PopulateDot11fEDCAParamSet( pMac, &pFrm->EDCAParamSet, psessionEntry); + + + if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B) + PopulateDot11fERPInfo( pMac, &pFrm->ERPInfo, psessionEntry); + + + // N.B. In earlier implementations, the RSN IE would be placed in + // the frame here, before the WPA IE, if 'RSN_BEFORE_WPA' was defined. + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->ExtSuppRates, psessionEntry ); + + //Populate HT IEs, when operating in 11n or Taurus modes. + if ( psessionEntry->htCapability ) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &pFrm->HTCaps ); + PopulateDot11fHTInfo( pMac, &pFrm->HTInfo, psessionEntry ); + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + /* Populate Overlapping BSS Scan Parameters IEs, + * when operating in HT40 in 2.4GHz. + */ + if ((pMac->roam.configParam.apHT40_24GEnabled) + && (IS_DOT11_MODE_HT(psessionEntry->dot11mode))) + { + PopulateDot11fOBSSScanParameters( pMac, &pFrm->OBSSScanParameters, + psessionEntry); + /* 10.15.8 Support of DSSS/CCK in 40 MHz, An associated HT STA in + * a 20/40 MHz BSS may generate DSSS/CCK transmissions.Set DSSS/CCK + * Mode in 40 MHz bit in HT capablity. + */ + pFrm->HTCaps.dsssCckMode40MHz = 1; + } +#endif + + PopulateDot11fExtCap( pMac, &pFrm->ExtCap, psessionEntry); + +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + limLog( pMac, LOG1, FL("Populate VHT IE in Probe Response")); + PopulateDot11fVHTCaps( pMac, &pFrm->VHTCaps, + psessionEntry->currentOperChannel, eSIR_TRUE ); + PopulateDot11fVHTOperation( pMac, &pFrm->VHTOperation , + psessionEntry->currentOperChannel); + // we do not support multi users yet + //PopulateDot11fVHTExtBssLoad( pMac, &frm.VHTExtBssLoad ); + } +#endif + + + if ( psessionEntry->pLimStartBssReq ) + { + PopulateDot11fWPA( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ), + &pFrm->WPA ); + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ), + &pFrm->RSNOpaque ); + } + + PopulateDot11fWMM( pMac, &pFrm->WMMInfoAp, &pFrm->WMMParams, &pFrm->WMMCaps, psessionEntry ); + +#if defined(FEATURE_WLAN_WAPI) + if( psessionEntry->pLimStartBssReq ) + { + PopulateDot11fWAPI( pMac, &( psessionEntry->pLimStartBssReq->rsnIE ), + &pFrm->WAPI ); + } + +#endif // defined(FEATURE_WLAN_WAPI) + + addnIEPresent = false; + if( pMac->lim.gpLimRemainOnChanReq ) + { + nBytes += (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq ) ); + } + //Only use CFG for non-listen mode. This CFG is not working for concurrency + //In listening mode, probe rsp IEs is passed in the message from SME to PE + else + { + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_ADDNIE_FLAG, + &addnIEPresent) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_FLAG")); + vos_mem_free(pFrm); + return; + } + } + + if (addnIEPresent) + { + + addIE = vos_mem_malloc(WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN*3); + if ( NULL == addIE ) + { + PELOGE(limLog(pMac, LOGE, + FL("Unable to allocate memory to store addn IE"));) + vos_mem_free(pFrm); + return; + } + + //Probe rsp IE available + if ( eSIR_SUCCESS != wlan_cfgGetStrLen(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &addnIE1Len) ) + { + limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + if (addnIE1Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIE1Len && + (nBytes + addnIE1Len) <= SIR_MAX_PACKET_SIZE) + { + if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &addIE[0], + &addnIE1Len) ) + { + limLog(pMac, LOGP, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 String")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + } + + //Probe rsp IE available + if ( eSIR_SUCCESS != wlan_cfgGetStrLen(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, &addnIE2Len) ) + { + limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 length")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + if (addnIE2Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN && addnIE2Len && + (nBytes + addnIE2Len) <= SIR_MAX_PACKET_SIZE) + { + if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, &addIE[addnIE1Len], + &addnIE2Len) ) + { + limLog(pMac, LOGP, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 String")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + } + + //Probe rsp IE available + if ( eSIR_SUCCESS != wlan_cfgGetStrLen(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, &addnIE3Len) ) + { + limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 length")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + if (addnIE3Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN && addnIE3Len && + (nBytes + addnIE3Len) <= SIR_MAX_PACKET_SIZE) + { + if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + &addIE[addnIE1Len + addnIE2Len], + &addnIE3Len) ) + { + limLog(pMac, LOGP, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 String")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + } + totalAddnIeLen = addnIE1Len + addnIE2Len + addnIE3Len; + + if(eSIR_SUCCESS != limGetAddnIeForProbeResp(pMac, addIE, &totalAddnIeLen, probeReqP2pIe)) + { + limLog(pMac, LOGP, + FL("Unable to get final Additional IE for Probe Req")); + vos_mem_free(addIE); + vos_mem_free(pFrm); + return; + } + + nSirStatus = limStripOffExtCapIEAndUpdateStruct(pMac, + addIE, + &totalAddnIeLen, + &extractedExtCap ); + if(eSIR_SUCCESS != nSirStatus ) + { + extractedExtCapFlag = eANI_BOOLEAN_FALSE; + limLog(pMac, LOG1, + FL("Unable to Stripoff ExtCap IE from Probe Rsp")); + } + + nBytes = nBytes + totalAddnIeLen; + limLog(pMac, LOG1, + FL("probe rsp packet size is %d "), nBytes); + if (probeReqP2pIe) + { + pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], totalAddnIeLen); + if (pP2pIe != NULL) + { + //get NoA attribute stream P2P IE + noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); + if (noaLen != 0) + { + total_noaLen = limBuildP2pIe(pMac, &noaIe[0], + &noaStream[0], noaLen); + nBytes = nBytes + total_noaLen; + limLog(pMac, LOG1, + FL("p2p probe rsp packet size is %d, noalength is %d"), + nBytes, total_noaLen); + } + } + } + } + + /*merge ExtCap IE*/ + if (extractedExtCapFlag && extractedExtCap.present) + { + limMergeExtCapIEStruct(&pFrm->ExtCap, &extractedExtCap, true); + } + + nStatus = dot11fGetPackedProbeResponseSize( pMac, pFrm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Probe Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for a Probe Response " + "(0x%08x)."), nStatus ); + } + + nBytes += nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Pro" + "be Response."), nBytes ); + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + vos_mem_free(pFrm); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_RSP, peerMacAddr,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Probe Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + vos_mem_free(pFrm); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + // That done, pack the Probe Response: + nStatus = dot11fPackProbeResponse( pMac, pFrm, pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Probe Response (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + vos_mem_free(pFrm); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a P" + "robe Response (0x%08x)."), nStatus ); + } + + PELOG3(limLog( pMac, LOG3, FL("Sending Probe Response frame to ") ); + limPrintMacAddr( pMac, peerMacAddr, LOG3 );) + + pMac->sys.probeRespond++; + + if( pMac->lim.gpLimRemainOnChanReq ) + { + vos_mem_copy ( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, + pMac->lim.gpLimRemainOnChanReq->probeRspIe, (pMac->lim.gpLimRemainOnChanReq->length - sizeof( tSirRemainOnChnReq )) ); + } + + if ( addnIEPresent ) + { + vos_mem_copy(pFrame+sizeof(tSirMacMgmtHdr)+nPayload, &addIE[0], totalAddnIeLen); + } + if (noaLen != 0) + { + if (total_noaLen > (SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN)) + { + limLog(pMac, LOGE, + FL("Not able to insert NoA because of length constraint." + "Total Length is :%d"),total_noaLen); + vos_mem_free(addIE); + vos_mem_free(pFrm); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else + { + vos_mem_copy( &pFrame[nBytes - (total_noaLen)], + &noaIe[0], total_noaLen); + } + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + // Queue Probe Response frame in high priority WQ + halstatus = halTxFrame( ( tHalHandle ) pMac, pPacket, + ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_LOW, + limTxComplete, pFrame, txFlag ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Could not send Probe Response.") ); + //Pkt will be freed up by the callback + } + + if ( addIE != NULL ) + { + vos_mem_free(addIE); + } + + vos_mem_free(pFrm); + return; + + +} // End limSendProbeRspMgmtFrame. + +void +limSendAddtsReqActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirAddtsReqInfo *pAddTS, + tpPESession psessionEntry) +{ + tANI_U16 i; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tDot11fAddTSRequest AddTSReq; + tDot11fWMMAddTSRequest WMMAddTSReq; + tANI_U32 nPayload, nBytes, nStatus; + tpSirMacMgmtHdr pMacHdr; + void *pPacket; +#ifdef FEATURE_WLAN_ESE + tANI_U32 phyMode; +#endif + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + return; + } + + if ( ! pAddTS->wmeTspecPresent ) + { + vos_mem_set(( tANI_U8* )&AddTSReq, sizeof( AddTSReq ), 0); + + AddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ; + AddTSReq.DialogToken.token = pAddTS->dialogToken; + AddTSReq.Category.category = SIR_MAC_ACTION_QOS_MGMT; + if ( pAddTS->lleTspecPresent ) + { + PopulateDot11fTSPEC( &pAddTS->tspec, &AddTSReq.TSPEC ); + } + else + { + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &AddTSReq.WMMTSPEC ); + } + + if ( pAddTS->lleTspecPresent ) + { + AddTSReq.num_WMMTCLAS = 0; + AddTSReq.num_TCLAS = pAddTS->numTclas; + for ( i = 0; i < pAddTS->numTclas; ++i) + { + PopulateDot11fTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSReq.TCLAS[i] ); + } + } + else + { + AddTSReq.num_TCLAS = 0; + AddTSReq.num_WMMTCLAS = pAddTS->numTclas; + for ( i = 0; i < pAddTS->numTclas; ++i) + { + PopulateDot11fWMMTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSReq.WMMTCLAS[i] ); + } + } + + if ( pAddTS->tclasProcPresent ) + { + if ( pAddTS->lleTspecPresent ) + { + AddTSReq.TCLASSPROC.processing = pAddTS->tclasProc; + AddTSReq.TCLASSPROC.present = 1; + } + else + { + AddTSReq.WMMTCLASPROC.version = 1; + AddTSReq.WMMTCLASPROC.processing = pAddTS->tclasProc; + AddTSReq.WMMTCLASPROC.present = 1; + } + } + + nStatus = dot11fGetPackedAddTSRequestSize( pMac, &AddTSReq, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or an Add TS Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddTSRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for an Add TS Request" + " (0x%08x)."), nStatus ); + } + } + else + { + vos_mem_set(( tANI_U8* )&WMMAddTSReq, sizeof( WMMAddTSReq ), 0); + + WMMAddTSReq.Action.action = SIR_MAC_QOS_ADD_TS_REQ; + WMMAddTSReq.DialogToken.token = pAddTS->dialogToken; + WMMAddTSReq.Category.category = SIR_MAC_ACTION_WME; + + // WMM spec 2.2.10 - status code is only filled in for ADDTS response + WMMAddTSReq.StatusCode.statusCode = 0; + + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &WMMAddTSReq.WMMTSPEC ); +#ifdef FEATURE_WLAN_ESE + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if( phyMode == WNI_CFG_PHY_MODE_11G || phyMode == WNI_CFG_PHY_MODE_11A) + { + pAddTS->tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS; + } + else + { + pAddTS->tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS; + } + PopulateDot11TSRSIE(pMac,&pAddTS->tsrsIE, &WMMAddTSReq.ESETrafStrmRateSet,sizeof(tANI_U8)); +#endif + // fillWmeTspecIE + + nStatus = dot11fGetPackedWMMAddTSRequestSize( pMac, &WMMAddTSReq, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a WMM Add TS Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddTSRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating" + "the packed size for a WMM Add TS Requ" + "est (0x%08x)."), nStatus ); + } + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad" + "d TS Request."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peerMacAddr,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Add TS Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + #if 0 + cfgLen = SIR_MAC_ADDR_LENGTH; + if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID, + ( tANI_U8* )pMacHdr->bssId, &cfgLen ) ) + { + limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil" + "e sending an Add TS Request.") ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + #endif //TO SUPPORT BT-AMP + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peerMacAddr, pMacHdr); +#endif + + // That done, pack the struct: + if ( ! pAddTS->wmeTspecPresent ) + { + nStatus = dot11fPackAddTSRequest( pMac, &AddTSReq, + pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an Add TS Request " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "an Add TS Request (0x%08x)."), nStatus ); + } + } + else + { + nStatus = dot11fPackWMMAddTSRequest( pMac, &WMMAddTSReq, + pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a WMM Add TS Reque" + "st (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a WMM Add TS Request (0x%08x)."), nStatus ); + } + } + + limLog( pMac, LOG1, FL("Sending an Add TS Request frame to ") ); + limPrintMacAddr( pMac, peerMacAddr, LOG1 ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + // Queue Addts Response frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL( "*** Could not send an Add TS Request" + " (%X) ***" ), halstatus ); + //Pkt will be freed up by the callback + } + +} // End limSendAddtsReqActionFrame. + + + +void +limSendAssocRspMgmtFrame(tpAniSirGlobal pMac, + tANI_U16 statusCode, + tANI_U16 aid, + tSirMacAddr peerMacAddr, + tANI_U8 subType, + tpDphHashNode pSta,tpPESession psessionEntry, + assoc_rsp_tx_context *tx_complete_context) +{ + static tDot11fAssocResponse frm; + tANI_U8 *pFrame, *macAddr; + tpSirMacMgmtHdr pMacHdr; + tSirRetStatus nSirStatus; + tANI_U8 lleMode = 0, fAddTS, edcaInclude = 0; + tHalBitVal qosMode, wmeMode; + tANI_U32 nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tUpdateBeaconParams beaconParams; + tANI_U32 txFlag = 0; + tANI_U32 addnIEPresent = false; + tANI_U32 addnIELen=0; + tANI_U8 addIE[WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN]; + tpSirAssocReq pAssocReq = NULL; + tANI_U16 addStripoffIELen = 0; + tDot11fIEExtCap extractedExtCap; + tANI_BOOLEAN extractedExtCapFlag = eANI_BOOLEAN_FALSE; + tANI_U32 nBytes = 0; + +#ifdef WLAN_FEATURE_11W + tANI_U32 retryInterval; + tANI_U32 maxRetries; +#endif + + if(NULL == psessionEntry) + { + limLog( pMac, LOGE, FL("psessionEntry is NULL")); + return; + } + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + limGetQosMode(psessionEntry, &qosMode); + limGetWmeMode(psessionEntry, &wmeMode); + + // An Add TS IE is added only if the AP supports it and the requesting + // STA sent a traffic spec. + fAddTS = ( qosMode && pSta && pSta->qos.addtsPresent ) ? 1 : 0; + + PopulateDot11fCapabilities( pMac, &frm.Capabilities, psessionEntry ); + + frm.Status.status = statusCode; + + frm.AID.associd = aid | LIM_AID_MASK; + + if ( NULL == pSta ) + { + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.SuppRates,psessionEntry); + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &frm.ExtSuppRates, psessionEntry ); + } + else + { + PopulateDot11fAssocRspRates( pMac, &frm.SuppRates, &frm.ExtSuppRates, + pSta->supportedRates.llbRates, pSta->supportedRates.llaRates ); + } + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if( pSta != NULL && eSIR_SUCCESS == statusCode ) + { + pAssocReq = + (tpSirAssocReq) psessionEntry->parsedAssocReq[pSta->assocId]; + /* populate P2P IE in AssocRsp when assocReq from the peer includes P2P IE */ + if( pAssocReq != NULL && pAssocReq->addIEPresent ) { + PopulateDot11AssocResP2PIE(pMac, &frm.P2PAssocRes, pAssocReq); + } + } + } + + if ( NULL != pSta ) + { + if ( eHAL_SET == qosMode ) + { + if ( pSta->lleEnabled ) + { + lleMode = 1; + if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) ) + { + PopulateDot11fEDCAParamSet( pMac, &frm.EDCAParamSet, psessionEntry); + +// FramesToDo:... +// if ( fAddTS ) +// { +// tANI_U8 *pAf = pBody; +// *pAf++ = SIR_MAC_QOS_ACTION_EID; +// tANI_U32 tlen; +// status = sirAddtsRspFill(pMac, pAf, statusCode, &pSta->qos.addts, NULL, +// &tlen, bufLen - frameLen); +// } // End if on Add TS. + } + } // End if on .11e enabled in 'pSta'. + } // End if on QOS Mode on. + + if ( ( ! lleMode ) && ( eHAL_SET == wmeMode ) && pSta->wmeEnabled ) + { + if ( ( ! pSta->aniPeer ) || ( ! PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) ) + { + + PopulateDot11fWMMParams( pMac, &frm.WMMParams, psessionEntry); + + if ( pSta->wsmEnabled ) + { + PopulateDot11fWMMCaps(&frm.WMMCaps ); + } + } + } + + if ( pSta->aniPeer ) + { + if ( ( lleMode && PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) || + ( pSta->wmeEnabled && PROP_CAPABILITY_GET( WME, pSta->propCapability ) ) ) + { + edcaInclude = 1; + } + + } // End if on Airgo peer. + + if ( pSta->mlmStaContext.htCapability && + psessionEntry->htCapability ) + { + limLog(pMac, LOG1, FL("Populate HT IEs in Assoc Response")); + PopulateDot11fHTCaps( pMac, psessionEntry, &frm.HTCaps ); + /* + *Check the STA capability and update the HTCaps accordingly + */ + frm.HTCaps.supportedChannelWidthSet = + (pSta->htSupportedChannelWidthSet < psessionEntry->htSupportedChannelWidthSet) ? + pSta->htSupportedChannelWidthSet : psessionEntry->htSupportedChannelWidthSet ; + + if (!frm.HTCaps.supportedChannelWidthSet) + frm.HTCaps.shortGI40MHz = 0; + + PopulateDot11fHTInfo( pMac, &frm.HTInfo, psessionEntry ); + } + limLog(pMac, LOG1, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d," + "shortGI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"), + frm.HTCaps.supportedChannelWidthSet, frm.HTCaps.mimoPowerSave, + frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz, frm.HTCaps.shortGI40MHz, + frm.HTCaps.dsssCckMode40MHz, frm.HTCaps.maxRxAMPDUFactor); + + + +#ifdef WLAN_FEATURE_AP_HT40_24G + /* Populate Overlapping BSS Scan Parameters IEs, + * when operating in HT40 in 2.4GHz. + */ + if ((pMac->roam.configParam.apHT40_24GEnabled) + && (IS_DOT11_MODE_HT(psessionEntry->dot11mode))) + { + PopulateDot11fOBSSScanParameters( pMac, &frm.OBSSScanParameters, + psessionEntry); + /* 10.15.8 Support of DSSS/CCK in 40 MHz, An associated HT STA in + * a 20/40 MHz BSS may generate DSSS/CCK transmissions.Set DSSS/CCK + * Mode in 40 MHz bit in HT capablity. + */ + frm.HTCaps.dsssCckMode40MHz = 1; + } +#endif + + PopulateDot11fExtCap( pMac, &frm.ExtCap, psessionEntry); +#ifdef WLAN_FEATURE_11AC + if( pSta->mlmStaContext.vhtCapability && + psessionEntry->vhtCapability ) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Assoc Response")); + PopulateDot11fVHTCaps( pMac, &frm.VHTCaps, + psessionEntry->currentOperChannel, eSIR_TRUE ); + PopulateDot11fVHTOperation( pMac, &frm.VHTOperation, + psessionEntry->currentOperChannel); + } +#endif + +#ifdef WLAN_FEATURE_11W + if( eSIR_MAC_TRY_AGAIN_LATER == statusCode ) + { + if ( wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + &maxRetries ) != eSIR_SUCCESS ) + limLog( pMac, LOGE, + FL("Could not retrieve PMF SA Query maximum retries value") ); + else + if ( wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL, + &retryInterval ) != eSIR_SUCCESS) + limLog( pMac, LOGE, + FL("Could not retrieve PMF SA Query timer interval value") ); + else + PopulateDot11fTimeoutInterval( + pMac, &frm.TimeoutInterval, SIR_MAC_TI_TYPE_ASSOC_COMEBACK, + (maxRetries - pSta->pmfSaQueryRetryCount) * retryInterval ); + } +#endif + } // End if on non-NULL 'pSta'. + + vos_mem_set(( tANI_U8* )&beaconParams, sizeof( tUpdateBeaconParams), 0); + + if( psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + if(psessionEntry->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + limDecideApProtection(pMac, peerMacAddr, &beaconParams,psessionEntry); + } + + limUpdateShortPreamble(pMac, peerMacAddr, &beaconParams, psessionEntry); + limUpdateShortSlotTime(pMac, peerMacAddr, &beaconParams, psessionEntry); + + beaconParams.bssIdx = psessionEntry->bssIdx; + + //Send message to HAL about beacon parameter change. + if(beaconParams.paramChangeBitmap) + { + schSetFixedBeaconFields(pMac,psessionEntry); + limSendBeaconParams(pMac, &beaconParams, psessionEntry ); + } + + if ( pAssocReq != NULL ) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, + &addnIEPresent) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get " + "WNI_CFG_ASSOC_RSP_ADDNIE_FLAG")); + return; + } + + if (addnIEPresent) + { + //Assoc rsp IE available + if (wlan_cfgGetStrLen(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_DATA, + &addnIELen) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Unable to get " + "WNI_CFG_ASSOC_RSP_ADDNIE_DATA length")); + return; + } + + if (addnIELen <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN && addnIELen && + (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE) + { + if (wlan_cfgGetStr(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_DATA, + &addIE[0], &addnIELen) == eSIR_SUCCESS) + { + + vos_mem_set(( tANI_U8* )&extractedExtCap, + sizeof( tDot11fIEExtCap ), 0); + addStripoffIELen = addnIELen; + nSirStatus = limStripOffExtCapIEAndUpdateStruct(pMac, + &addIE[0], + &addStripoffIELen, + &extractedExtCap ); + if(eSIR_SUCCESS != nSirStatus) + { + limLog(pMac, LOG1, + FL("Unable to Stripoff ExtCap IE from Assoc Rsp")); + } + else + { + addnIELen = addStripoffIELen; + extractedExtCapFlag = eANI_BOOLEAN_TRUE; + } + nBytes = nBytes + addnIELen; + } + } + } + } + + /* merge the ExtCap struct*/ + if (extractedExtCapFlag && extractedExtCap.present) + { + limMergeExtCapIEStruct(&(frm.ExtCap), &extractedExtCap, true); + } + + nStatus = dot11fGetPackedAssocResponseSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to calculate the packed size f" + "or an Association Response (0x%08x)."), + nStatus ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an Association Re" + "sponse (0x%08x)."), nStatus ); + } + + nBytes += sizeof( tSirMacMgmtHdr ) + nPayload; + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGP, FL("Call to bufAlloc failed for RE/ASSOC RSP.")); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + ( LIM_ASSOC == subType ) ? + SIR_MAC_MGMT_ASSOC_RSP : + SIR_MAC_MGMT_REASSOC_RSP, + peerMacAddr,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + nStatus = dot11fPackAssocResponse( pMac, &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an Association Response" + " (0x%08x)."), nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing an " + "Association Response (0x%08x)."), nStatus ); + } + + macAddr = pMacHdr->da; + + if (subType == LIM_ASSOC) + { + limLog(pMac, LOG1, + FL("*** Sending Assoc Resp status %d aid %d to "), + statusCode, aid); + } + else{ + limLog(pMac, LOG1, + FL("*** Sending ReAssoc Resp status %d aid %d to "), + statusCode, aid); + } + limPrintMacAddr(pMac, pMacHdr->da, LOG1); + + if ( addnIEPresent ) + { + vos_mem_copy ( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, &addIE[0], addnIELen ) ; + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + limLog( pMac, LOG1, FL("Sending Assoc resp over WQ5 to "MAC_ADDRESS_STR + " From " MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + + txFlag |= HAL_USE_FW_IN_TX_PATH; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + limLog(pMac, LOG1, FL("Re/AssocRsp - txBdToken %u"), + pMac->lim.txBdToken); + /// Queue Association Response frame in high priority WQ + if (tx_complete_context) + { + tx_complete_context->txBdToken = pMac->lim.txBdToken; + halstatus = halTxFrameWithTxComplete(pMac, pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limAssocRspTxCompleteCnf, + txFlag, pMac->lim.txBdToken); + } + else + halstatus = halTxFrameWithTxComplete(pMac, pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limTxBdComplete, + txFlag, pMac->lim.txBdToken); + + pMac->lim.txBdToken++; + } + else + { + /// Queue Association Response frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + } + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("*** Could not Send Re/AssocRsp, retCode=%X ***"), + nSirStatus); + + //Pkt will be freed up by the callback + } + + // update the ANI peer station count + //FIXME_PROTECTION : take care of different type of station + // counter inside this function. + limUtilCountStaAdd(pMac, pSta, psessionEntry); + +} // End limSendAssocRspMgmtFrame. + + + +void +limSendAddtsRspActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U16 nStatusCode, + tSirAddtsReqInfo *pAddTS, + tSirMacScheduleIE *pSchedule, + tpPESession psessionEntry) +{ + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tDot11fAddTSResponse AddTSRsp; + tDot11fWMMAddTSResponse WMMAddTSRsp; + tSirRetStatus nSirStatus; + tANI_U32 i, nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + return; + } + + if ( ! pAddTS->wmeTspecPresent ) + { + vos_mem_set( ( tANI_U8* )&AddTSRsp, sizeof( AddTSRsp ), 0 ); + + AddTSRsp.Category.category = SIR_MAC_ACTION_QOS_MGMT; + AddTSRsp.Action.action = SIR_MAC_QOS_ADD_TS_RSP; + AddTSRsp.DialogToken.token = pAddTS->dialogToken; + AddTSRsp.Status.status = nStatusCode; + + // The TsDelay information element is only filled in for a specific + // status code: + if ( eSIR_MAC_TS_NOT_CREATED_STATUS == nStatusCode ) + { + if ( pAddTS->wsmTspecPresent ) + { + AddTSRsp.WMMTSDelay.version = 1; + AddTSRsp.WMMTSDelay.delay = 10; + AddTSRsp.WMMTSDelay.present = 1; + } + else + { + AddTSRsp.TSDelay.delay = 10; + AddTSRsp.TSDelay.present = 1; + } + } + + if ( pAddTS->wsmTspecPresent ) + { + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &AddTSRsp.WMMTSPEC ); + } + else + { + PopulateDot11fTSPEC( &pAddTS->tspec, &AddTSRsp.TSPEC ); + } + + if ( pAddTS->wsmTspecPresent ) + { + AddTSRsp.num_WMMTCLAS = 0; + AddTSRsp.num_TCLAS = pAddTS->numTclas; + for ( i = 0; i < AddTSRsp.num_TCLAS; ++i) + { + PopulateDot11fTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSRsp.TCLAS[i] ); + } + } + else + { + AddTSRsp.num_TCLAS = 0; + AddTSRsp.num_WMMTCLAS = pAddTS->numTclas; + for ( i = 0; i < AddTSRsp.num_WMMTCLAS; ++i) + { + PopulateDot11fWMMTCLAS( pMac, &pAddTS->tclasInfo[i], + &AddTSRsp.WMMTCLAS[i] ); + } + } + + if ( pAddTS->tclasProcPresent ) + { + if ( pAddTS->wsmTspecPresent ) + { + AddTSRsp.WMMTCLASPROC.version = 1; + AddTSRsp.WMMTCLASPROC.processing = pAddTS->tclasProc; + AddTSRsp.WMMTCLASPROC.present = 1; + } + else + { + AddTSRsp.TCLASSPROC.processing = pAddTS->tclasProc; + AddTSRsp.TCLASSPROC.present = 1; + } + } + + // schedule element is included only if requested in the tspec and we are + // using hcca (or both edca and hcca) + // 11e-D8.0 is inconsistent on whether the schedule element is included + // based on tspec schedule bit or not. Sec 7.4.2.2. says one thing but + // pg 46, line 17-18 says something else. So just include it and let the + // sta figure it out + if ((pSchedule != NULL) && + ((pAddTS->tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (pAddTS->tspec.tsinfo.traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH))) + { + if ( pAddTS->wsmTspecPresent ) + { + PopulateDot11fWMMSchedule( pSchedule, &AddTSRsp.WMMSchedule ); + } + else + { + PopulateDot11fSchedule( pSchedule, &AddTSRsp.Schedule ); + } + } + + nStatus = dot11fGetPackedAddTSResponseSize( pMac, &AddTSRsp, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for an Add TS Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddTSResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for an Add TS" + " Response (0x%08x)."), nStatus ); + } + } + else + { + vos_mem_set( ( tANI_U8* )&WMMAddTSRsp, sizeof( WMMAddTSRsp ), 0 ); + + WMMAddTSRsp.Category.category = SIR_MAC_ACTION_WME; + WMMAddTSRsp.Action.action = SIR_MAC_QOS_ADD_TS_RSP; + WMMAddTSRsp.DialogToken.token = pAddTS->dialogToken; + WMMAddTSRsp.StatusCode.statusCode = (tANI_U8)nStatusCode; + + PopulateDot11fWMMTSPEC( &pAddTS->tspec, &WMMAddTSRsp.WMMTSPEC ); + + nStatus = dot11fGetPackedWMMAddTSResponseSize( pMac, &WMMAddTSRsp, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for a WMM Add TS Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fWMMAddTSResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for a WMM Add" + "TS Response (0x%08x)."), nStatus ); + } + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad" + "d TS Response."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Add TS Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + + #if 0 + if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID, + ( tANI_U8* )pMacHdr->bssId, &cfgLen ) ) + { + limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil" + "e sending an Add TS Response.") ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // That done, pack the struct: + if ( ! pAddTS->wmeTspecPresent ) + { + nStatus = dot11fPackAddTSResponse( pMac, &AddTSRsp, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an Add TS Response " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "an Add TS Response (0x%08x)."), nStatus ); + } + } + else + { + nStatus = dot11fPackWMMAddTSResponse( pMac, &WMMAddTSRsp, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a WMM Add TS Response " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a WMM Add TS Response (0x%08x)."), nStatus ); + } + } + + limLog( pMac, LOG1, FL("Sending an Add TS Response (status %d) to "), + nStatusCode ); + limPrintMacAddr( pMac, pMacHdr->da, LOG1 ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + // Queue the frame in high priority WQ: + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Add TS Response (%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + } + +} // End limSendAddtsRspActionFrame. + +void +limSendDeltsReqActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 wmmTspecPresent, + tSirMacTSInfo *pTsinfo, + tSirMacTspecIE *pTspecIe, + tpPESession psessionEntry) +{ + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tDot11fDelTS DelTS; + tDot11fWMMDelTS WMMDelTS; + tSirRetStatus nSirStatus; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + return; + } + + if ( ! wmmTspecPresent ) + { + vos_mem_set( ( tANI_U8* )&DelTS, sizeof( DelTS ), 0 ); + + DelTS.Category.category = SIR_MAC_ACTION_QOS_MGMT; + DelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ; + PopulateDot11fTSInfo( pTsinfo, &DelTS.TSInfo ); + + nStatus = dot11fGetPackedDelTSSize( pMac, &DelTS, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for a Del TS (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDelTS ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for a Del TS" + " (0x%08x)."), nStatus ); + } + } + else + { + vos_mem_set( ( tANI_U8* )&WMMDelTS, sizeof( WMMDelTS ), 0 ); + + WMMDelTS.Category.category = SIR_MAC_ACTION_WME; + WMMDelTS.Action.action = SIR_MAC_QOS_DEL_TS_REQ; + WMMDelTS.DialogToken.token = 0; + WMMDelTS.StatusCode.statusCode = 0; + PopulateDot11fWMMTSPEC( pTspecIe, &WMMDelTS.WMMTSPEC ); + nStatus = dot11fGetPackedWMMDelTSSize( pMac, &WMMDelTS, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed si" + "ze for a WMM Del TS (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDelTS ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calcula" + "ting the packed size for a WMM De" + "l TS (0x%08x)."), nStatus ); + } + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an Ad" + "d TS Response."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, + psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Add TS Response (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + #if 0 + + cfgLen = SIR_MAC_ADDR_LENGTH; + if ( eSIR_SUCCESS != wlan_cfgGetStr( pMac, WNI_CFG_BSSID, + ( tANI_U8* )pMacHdr->bssId, &cfgLen ) ) + { + limLog( pMac, LOGP, FL("Failed to retrieve WNI_CFG_BSSID whil" + "e sending an Add TS Response.") ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(pMacHdr->bssId, psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // That done, pack the struct: + if ( !wmmTspecPresent ) + { + nStatus = dot11fPackDelTS( pMac, &DelTS, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Del TS frame (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a Del TS frame (0x%08x)."), nStatus ); + } + } + else + { + nStatus = dot11fPackWMMDelTS( pMac, &WMMDelTS, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a WMM Del TS frame (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "a WMM Del TS frame (0x%08x)."), nStatus ); + } + } + + limLog(pMac, LOG1, FL("Sending DELTS REQ (size %d) to "), nBytes); + limPrintMacAddr(pMac, pMacHdr->da, LOG1); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Del TS (%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + } + +} // End limSendDeltsReqActionFrame. + +void +limSendAssocReqMgmtFrame(tpAniSirGlobal pMac, + tLimMlmAssocReq *pMlmAssocReq, + tpPESession psessionEntry) +{ + tDot11fAssocRequest *pFrm; + tANI_U16 caps; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus = eSIR_FAILURE; + tLimMlmAssocCnf mlmAssocCnf; + tANI_U32 nPayload, nStatus; + tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled; + void *pPacket; + eHalStatus halstatus; + tANI_U16 nAddIELen; + tANI_U8 *pAddIE; + tANI_U8 *wpsIe = NULL; +#if defined WLAN_FEATURE_VOWIFI + tANI_U8 PowerCapsPopulated = FALSE; +#endif + tANI_U32 txFlag = 0; + tpSirMacMgmtHdr pMacHdr; + tDot11fIEExtCap extractedExtCap; + tANI_BOOLEAN extractedExtCapFlag = eANI_BOOLEAN_TRUE; + tANI_U32 nBytes = 0; + + if(NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("psessionEntry is NULL") ); + return; + } + + /* check this early to avoid unncessary operation */ + if(NULL == psessionEntry->pLimJoinReq) + { + limLog(pMac, LOGE, FL("psessionEntry->pLimJoinReq is NULL") ); + return; + } + nAddIELen = psessionEntry->pLimJoinReq->addIEAssoc.length; + pAddIE = psessionEntry->pLimJoinReq->addIEAssoc.addIEdata; + + pFrm = vos_mem_malloc(sizeof(tDot11fAssocRequest)); + if ( NULL == pFrm ) + { + limLog(pMac, LOGE, FL("Unable to allocate memory") ); + return; + } + + + vos_mem_set( ( tANI_U8* )pFrm, sizeof( tDot11fAssocRequest ), 0 ); + + vos_mem_set(( tANI_U8* )&extractedExtCap, sizeof( tDot11fIEExtCap ), 0); + if (psessionEntry->ExtCap.present) + { + nSirStatus = limStripOffExtCapIEAndUpdateStruct(pMac, pAddIE, + &nAddIELen, + &extractedExtCap ); + } + if(eSIR_SUCCESS != nSirStatus ) + { + extractedExtCapFlag = eANI_BOOLEAN_FALSE; + limLog(pMac, LOG1, + FL("Unable to Stripoff ExtCap IE from Assoc Req")); + } + /* TODO:remove this code once driver provides the call back function + * to supplicant for set_qos_map + */ + else + { + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)extractedExtCap.bytes; + if (p_ext_cap->interworkingService) { + p_ext_cap->qosMap = 1; + } + extractedExtCap.num_bytes = lim_compute_ext_cap_ie_length(&extractedExtCap); + extractedExtCapFlag = (extractedExtCap.num_bytes > 0); + } + + caps = pMlmAssocReq->capabilityInfo; + if ( PROP_CAPABILITY_GET( 11EQOS, psessionEntry->limCurrentBssPropCap ) ) + ((tSirMacCapabilityInfo *) &caps)->qos = 0; +#if defined(FEATURE_WLAN_WAPI) + /* CR: 262463 : + According to WAPI standard: + 7.3.1.4 Capability Information field + In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted + Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and + Reassociation management frames. */ + if ( psessionEntry->encryptType == eSIR_ED_WPI) + ((tSirMacCapabilityInfo *) &caps)->privacy = 0; +#endif + swapBitField16(caps, ( tANI_U16* )&pFrm->Capabilities ); + + pFrm->ListenInterval.interval = pMlmAssocReq->listenInterval; + PopulateDot11fSSID2( pMac, &pFrm->SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->SuppRates,psessionEntry); + + fQosEnabled = ( psessionEntry->limQosEnabled) && + SIR_MAC_GET_QOS( psessionEntry->limCurrentBssCaps ); + + fWmeEnabled = ( psessionEntry->limWmeEnabled ) && + LIM_BSS_CAPS_GET( WME, psessionEntry->limCurrentBssQosCaps ); + + // We prefer .11e asociations: + if ( fQosEnabled ) fWmeEnabled = false; + + fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled && + LIM_BSS_CAPS_GET( WSM, psessionEntry->limCurrentBssQosCaps ); + + if ( psessionEntry->lim11hEnable && + psessionEntry->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE ) + { +#if defined WLAN_FEATURE_VOWIFI + PowerCapsPopulated = TRUE; + + PopulateDot11fPowerCaps( pMac, &pFrm->PowerCaps, LIM_ASSOC,psessionEntry); +#endif + PopulateDot11fSuppChannels( pMac, &pFrm->SuppChannels, LIM_ASSOC,psessionEntry); + + } + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + if (PowerCapsPopulated == FALSE) + { + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps(pMac, &pFrm->PowerCaps, LIM_ASSOC, psessionEntry); + } + } +#endif + + if ( fQosEnabled && + ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limCurrentBssPropCap))) + PopulateDot11fQOSCapsStation( pMac, &pFrm->QOSCapsStation ); + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pFrm->ExtSuppRates, psessionEntry ); + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + PopulateDot11fRRMIe( pMac, &pFrm->RRMEnabledCap, psessionEntry ); + } +#endif + // The join request *should* contain zero or one of the WPA and RSN + // IEs. The payload send along with the request is a + // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // So, we should be able to make the following two calls harmlessly, + // since they do nothing if they don't find the given IE in the + // bytestream with which they're provided. + + // The net effect of this will be to faithfully transmit whatever + // security IE is in the join request. + + // *However*, if we're associating for the purpose of WPS + // enrollment, and we've been configured to indicate that by + // eliding the WPA or RSN IE, we just skip this: + if( nAddIELen && pAddIE ) + { + wpsIe = limGetWscIEPtr (pMac, pAddIE, nAddIELen); + } + if ( NULL == wpsIe ) + { + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ), + &pFrm->RSNOpaque ); + PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ), + &pFrm->WPAOpaque ); +#if defined(FEATURE_WLAN_WAPI) + PopulateDot11fWAPIOpaque( pMac, &( psessionEntry->pLimJoinReq->rsnIE ), + &pFrm->WAPIOpaque ); +#endif // defined(FEATURE_WLAN_WAPI) + } + + // include WME EDCA IE as well + if ( fWmeEnabled ) + { + if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limCurrentBssPropCap ) ) + { + PopulateDot11fWMMInfoStation( pMac, &pFrm->WMMInfoStation ); + } + + if ( fWsmEnabled && + ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limCurrentBssPropCap ))) + { + PopulateDot11fWMMCaps( &pFrm->WMMCaps ); + } + } + + //Populate HT IEs, when operating in 11n or Taurus modes AND + //when AP is also operating in 11n mode. + if ( psessionEntry->htCapability && + pMac->lim.htCapabilityPresentInBeacon) + { + limLog(pMac, LOG1, FL("Populate HT IEs in Assoc Request")); + PopulateDot11fHTCaps( pMac, psessionEntry, &pFrm->HTCaps ); +#ifdef DISABLE_GF_FOR_INTEROP + + /* + * To resolve the interop problem with Broadcom AP, + * where TQ STA could not pass traffic with GF enabled, + * TQ STA will do Greenfield only with TQ AP, for + * everybody else it will be turned off. + */ + + if( (psessionEntry->pLimJoinReq != NULL) && (!psessionEntry->pLimJoinReq->bssDescription.aniIndicator)) + { + limLog( pMac, LOG1, FL("Sending Assoc Req to Non-TQ AP," + " Turning off Greenfield")); + pFrm->HTCaps.greenField = WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } +#endif + + } + + limLog(pMac, LOG1, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d," + "shortGI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"), + pFrm->HTCaps.supportedChannelWidthSet, pFrm->HTCaps.mimoPowerSave, + pFrm->HTCaps.greenField, pFrm->HTCaps.shortGI20MHz, pFrm->HTCaps.shortGI40MHz, + pFrm->HTCaps.dsssCckMode40MHz, pFrm->HTCaps.maxRxAMPDUFactor); + + +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Assoc Request")); + PopulateDot11fVHTCaps( pMac, &pFrm->VHTCaps, + psessionEntry->currentOperChannel, eSIR_FALSE ); + + } +#endif + if (psessionEntry->ExtCap.present) + PopulateDot11fExtCap( pMac, &pFrm->ExtCap, psessionEntry); + +#if defined WLAN_FEATURE_VOWIFI_11R + if (psessionEntry->pLimJoinReq->is11Rconnection) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL("mdie = %02x %02x %02x"), + (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[0], + (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[1], + (unsigned int)psessionEntry->pLimJoinReq->bssDescription.mdie[2]); +#endif + PopulateMDIE( pMac, &pFrm->MobilityDomain, + psessionEntry->pLimJoinReq->bssDescription.mdie); + } + else + { + // No 11r IEs dont send any MDIE + limLog( pMac, LOG1, FL("MDIE not present")); + } +#endif + +#ifdef FEATURE_WLAN_ESE + /* For ESE Associations fill the ESE IEs */ + if (psessionEntry->isESEconnection && + psessionEntry->pLimJoinReq->isESEFeatureIniEnabled) + { +#ifndef FEATURE_DISABLE_RM + PopulateDot11fESERadMgmtCap(&pFrm->ESERadMgmtCap); +#endif + PopulateDot11fESEVersion(&pFrm->ESEVersion); + } +#endif + + /* merge the ExtCap struct*/ + if (extractedExtCapFlag && extractedExtCap.present) + { + limMergeExtCapIEStruct(&pFrm->ExtCap, &extractedExtCap, true); + } + + if (pFrm->ExtCap.present && psessionEntry->ExtCap.present) { + limMergeExtCapIEStruct(&pFrm->ExtCap, &psessionEntry->ExtCap, false); + limLog(pMac, LOG1, + FL("Clear the bits in EXTCAP IE that AP don't support to avoid IoT issues.")); + } + + nStatus = dot11fGetPackedAssocRequestSize( pMac, pFrm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or an Association Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAssocRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an Association Re " + "quest(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an As" + "sociation Request."), nBytes ); + + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + + + /* Update PE session id*/ + mlmAssocCnf.sessionId = psessionEntry->peSessionId; + + mlmAssocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + + limPostSmeMessage( pMac, LIM_MLM_ASSOC_CNF, + ( tANI_U32* ) &mlmAssocCnf); + + vos_mem_free(pFrm); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ASSOC_REQ, psessionEntry->bssId,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + vos_mem_free(pFrm); + return; + } + + // That done, pack the Assoc Request: + nStatus = dot11fPackAssocRequest( pMac, pFrm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Assoc Request (0x%0" + "8x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + vos_mem_free(pFrm); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a Assoc" + "Request (0x%08x)."), nStatus ); + } + + PELOG1(limLog( pMac, LOG1, FL("*** Sending Association Request length %d" + "to "), + nBytes );) + // limPrintMacAddr( pMac, bssid, LOG1 ); + + if( psessionEntry->assocReq != NULL ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if( nAddIELen ) + { + vos_mem_copy( pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + pAddIE, + nAddIELen ); + nPayload += nAddIELen; + } + + psessionEntry->assocReq = vos_mem_malloc(nPayload); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store " + "assoc request"));) + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy( psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload); + psessionEntry->assocReqLen = nPayload; + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if(psessionEntry->pePersona == VOS_P2P_CLIENT_MODE || + psessionEntry->pePersona == VOS_STA_MODE) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ASSOC_START_EVENT, psessionEntry, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + limLog( pMac, LOG1, FL("Sending Assoc req over WQ5 to "MAC_ADDRESS_STR + " From " MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + txFlag |= HAL_USE_FW_IN_TX_PATH; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + + if( ( psessionEntry->is11Gonly == true ) && + ( !IS_BROADCAST_MAC(pMlmAssocReq->peerMacAddr) ) ){ + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + limLog(pMac, LOG1, FL("Assoc Req - txBdToken %u"), pMac->lim.txBdToken); + halstatus = halTxFrameWithTxComplete( pMac, pPacket, + ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload), + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limTxBdComplete, txFlag, + pMac->lim.txBdToken); + pMac->lim.txBdToken++; + } + else + { + halstatus = halTxFrame( pMac, pPacket, + ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload), + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + } + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Association Request (%X)!"), + halstatus ); + //Pkt will be freed up by the callback + vos_mem_free(pFrm); + return; + } + + //Enable caching only if Assoc Request is successfully submitted to the h/w + WLANTL_EnableCaching(psessionEntry->staId); + + // Free up buffer allocated for mlmAssocReq + vos_mem_free(pMlmAssocReq); + pMlmAssocReq = NULL; + vos_mem_free(pFrm); + return; +} // End limSendAssocReqMgmtFrame + + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/*------------------------------------------------------------------------------------ + * + * Send Reassoc Req with FTIEs. + * + *----------------------------------------------------------------------------------- + */ +void +limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry) +{ + static tDot11fReAssocRequest frm; + tANI_U16 caps; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tANI_U32 nBytes, nPayload, nStatus; + tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled; + void *pPacket; + eHalStatus halstatus; +#if defined WLAN_FEATURE_VOWIFI + tANI_U8 PowerCapsPopulated = FALSE; +#endif + tANI_U16 ft_ies_length = 0; + tANI_U8 *pBody; + tANI_U16 nAddIELen; + tANI_U8 *pAddIE; +#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + tANI_U8 *wpsIe = NULL; +#endif + tANI_U32 txFlag = 0; + tpSirMacMgmtHdr pMacHdr; + + if (NULL == psessionEntry) + { + return; + } + + /* check this early to avoid unncessary operation */ + if(NULL == psessionEntry->pLimReAssocReq) + { + return; + } + nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length; + pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata; + limLog( pMac, LOG1, FL("limSendReassocReqWithFTIEsMgmtFrame received in " + "state (%d)."), psessionEntry->limMlmState); + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + caps = pMlmReassocReq->capabilityInfo; + if (PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap)) + ((tSirMacCapabilityInfo *) &caps)->qos = 0; +#if defined(FEATURE_WLAN_WAPI) + /* CR: 262463 : + According to WAPI standard: + 7.3.1.4 Capability Information field + In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted + Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and + Reassociation management frames. */ + if ( psessionEntry->encryptType == eSIR_ED_WPI) + ((tSirMacCapabilityInfo *) &caps)->privacy = 0; +#endif + swapBitField16(caps, ( tANI_U16* )&frm.Capabilities ); + + frm.ListenInterval.interval = pMlmReassocReq->listenInterval; + + // Get the old bssid of the older AP. + vos_mem_copy( ( tANI_U8* )frm.CurrentAPAddress.mac, + pMac->ft.ftPEContext.pFTPreAuthReq->currbssId, 6); + + PopulateDot11fSSID2( pMac, &frm.SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.SuppRates,psessionEntry); + + fQosEnabled = ( psessionEntry->limQosEnabled) && + SIR_MAC_GET_QOS( psessionEntry->limReassocBssCaps ); + + fWmeEnabled = ( psessionEntry->limWmeEnabled ) && + LIM_BSS_CAPS_GET( WME, psessionEntry->limReassocBssQosCaps ); + + fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled && + LIM_BSS_CAPS_GET( WSM, psessionEntry->limReassocBssQosCaps ); + + if ( psessionEntry->lim11hEnable && + psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE ) + { +#if defined WLAN_FEATURE_VOWIFI + PowerCapsPopulated = TRUE; + + PopulateDot11fPowerCaps( pMac, &frm.PowerCaps, LIM_REASSOC,psessionEntry); + PopulateDot11fSuppChannels( pMac, &frm.SuppChannels, LIM_REASSOC,psessionEntry); +#endif + } + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + if (PowerCapsPopulated == FALSE) + { + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_REASSOC, psessionEntry); + } + } +#endif + + if ( fQosEnabled && + ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap ) )) + { + PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation ); + } + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.ExtSuppRates, psessionEntry ); + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limReassocBssCaps ) ) + { + PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry ); + } +#endif + + // Ideally this should be enabled for 11r also. But 11r does + // not follow the usual norm of using the Opaque object + // for rsnie and fties. Instead we just add + // the rsnie and fties at the end of the pack routine for 11r. + // This should ideally! be fixed. +#if defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + // + // The join request *should* contain zero or one of the WPA and RSN + // IEs. The payload send along with the request is a + // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // So, we should be able to make the following two calls harmlessly, + // since they do nothing if they don't find the given IE in the + // bytestream with which they're provided. + + // The net effect of this will be to faithfully transmit whatever + // security IE is in the join request. + + // *However*, if we're associating for the purpose of WPS + // enrollment, and we've been configured to indicate that by + // eliding the WPA or RSN IE, we just skip this: + if (!psessionEntry->is11Rconnection) + { + if( nAddIELen && pAddIE ) + { + wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen); + } + if ( NULL == wpsIe ) + { + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.RSNOpaque ); + PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.WPAOpaque ); + } + +#ifdef FEATURE_WLAN_ESE + if (psessionEntry->pLimReAssocReq->cckmIE.length) + { + PopulateDot11fESECckmOpaque( pMac, &( psessionEntry->pLimReAssocReq->cckmIE ), + &frm.ESECckmOpaque ); + } +#endif //FEATURE_WLAN_ESE + } + +#ifdef FEATURE_WLAN_ESE + // For ESE Associations fill the ESE IEs + if (psessionEntry->isESEconnection && + psessionEntry->pLimReAssocReq->isESEFeatureIniEnabled) + { +#ifndef FEATURE_DISABLE_RM + PopulateDot11fESERadMgmtCap(&frm.ESERadMgmtCap); +#endif + PopulateDot11fESEVersion(&frm.ESEVersion); + } +#endif //FEATURE_WLAN_ESE +#endif //FEATURE_WLAN_ESE || FEATURE_WLAN_LFR + + // include WME EDCA IE as well + if ( fWmeEnabled ) + { + if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limReassocBssPropCap ) ) + { + PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation ); + } + + if ( fWsmEnabled && + ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limReassocBssPropCap ))) + { + PopulateDot11fWMMCaps( &frm.WMMCaps ); + } +#ifdef FEATURE_WLAN_ESE + if (psessionEntry->isESEconnection) + { + PopulateDot11fReAssocTspec(pMac, &frm, psessionEntry); + + // Populate the TSRS IE if TSPEC is included in the reassoc request + if (psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs) + { + tANI_U32 phyMode; + tSirMacESETSRSIE tsrsIE; + limGetPhyMode(pMac, &phyMode, psessionEntry); + + tsrsIE.tsid = 0; + if( phyMode == WNI_CFG_PHY_MODE_11G || phyMode == WNI_CFG_PHY_MODE_11A) + { + tsrsIE.rates[0] = TSRS_11AG_RATE_6MBPS; + } + else + { + tsrsIE.rates[0] = TSRS_11B_RATE_5_5MBPS; + } + PopulateDot11TSRSIE(pMac,&tsrsIE, &frm.ESETrafStrmRateSet, sizeof(tANI_U8)); + } + } +#endif + } + + if ( psessionEntry->htCapability && + pMac->lim.htCapabilityPresentInBeacon) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &frm.HTCaps ); + } + limLog(pMac, LOG1, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d," + "shortGI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"), + frm.HTCaps.supportedChannelWidthSet, frm.HTCaps.mimoPowerSave, + frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz, frm.HTCaps.shortGI40MHz, + frm.HTCaps.dsssCckMode40MHz, frm.HTCaps.maxRxAMPDUFactor); +#if defined WLAN_FEATURE_VOWIFI_11R + if ( psessionEntry->pLimReAssocReq->bssDescription.mdiePresent && + (pMac->ft.ftSmeContext.addMDIE == TRUE) +#if defined FEATURE_WLAN_ESE + && !psessionEntry->isESEconnection +#endif + ) + { + PopulateMDIE( pMac, &frm.MobilityDomain, psessionEntry->pLimReAssocReq->bssDescription.mdie); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Re-Assoc Request")); + PopulateDot11fVHTCaps( pMac, &frm.VHTCaps, + psessionEntry->currentOperChannel, eSIR_FALSE ); + + } +#endif + if (psessionEntry->ExtCap.present) + PopulateDot11fExtCap( pMac, &frm.ExtCap, psessionEntry); + + nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Re-Association Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fReAssocRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Re-Association Re " + "quest(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog( pMac, LOG1, FL("FT IE Reassoc Req (%d)."), + pMac->ft.ftSmeContext.reassoc_ft_ies_length); +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + if (psessionEntry->is11Rconnection) + { + ft_ies_length = pMac->ft.ftSmeContext.reassoc_ft_ies_length; + } +#endif + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes+ft_ies_length, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Re-As" + "sociation Request."), nBytes ); + goto end; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes + ft_ies_length, 0); + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + limPrintMacAddr(pMac, psessionEntry->limReAssocbssId, LOG1); +#endif + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_REASSOC_REQ, + psessionEntry->limReAssocbssId,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + + pMacHdr = (tpSirMacMgmtHdr) pFrame; + // That done, pack the ReAssoc Request: + nStatus = dot11fPackReAssocRequest( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Re-Association Reque" + "st (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a R" + "e-Association Request (0x%08x)."), nStatus ); + } + + PELOG3(limLog( pMac, LOG3, + FL("*** Sending Re-Association Request length %d %d to "), + nBytes, nPayload );) + if( psessionEntry->assocReq != NULL ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if( nAddIELen ) + { + vos_mem_copy( pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + pAddIE, + nAddIELen ); + nPayload += nAddIELen; + } + + psessionEntry->assocReq = vos_mem_malloc(nPayload); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));) + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy( psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload); + psessionEntry->assocReqLen = nPayload; + } + + if (psessionEntry->is11Rconnection) + { + { + int i = 0; + + pBody = pFrame + nBytes; + for (i=0; ift.ftSmeContext.reassoc_ft_ies[i]; + pBody++; + } + } + } + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("Re-assoc Req Frame is: ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, + (tANI_U8 *)pFrame, + (nBytes + ft_ies_length));) +#endif + + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if( NULL != psessionEntry->assocReq ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + if (ft_ies_length) + { + psessionEntry->assocReq = vos_mem_malloc(ft_ies_length); + if (NULL == psessionEntry->assocReq) + { + limLog(pMac, LOGE, + FL("Unable to allocate memory for FT IEs")); + psessionEntry->assocReqLen = 0; + } + else + { + /* Store the FT IEs. This is sent to csr/hdd in join cnf response.*/ + vos_mem_copy(psessionEntry->assocReq, + pMac->ft.ftSmeContext.reassoc_ft_ies, + (ft_ies_length)); + psessionEntry->assocReqLen = ft_ies_length; + } + } + else + { + limLog(pMac, LOG1, FL("FT IEs not present")); + psessionEntry->assocReqLen = 0; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT, psessionEntry, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + limLog( pMac, LOG1, FL("Reassoc req - txBdToken %u"), pMac->lim.txBdToken); + halstatus = halTxFrameWithTxComplete( pMac, pPacket, + ( tANI_U16 ) (nBytes + ft_ies_length), + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limTxBdComplete, txFlag, + pMac->lim.txBdToken); + pMac->lim.txBdToken++; + } + else + { + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (nBytes + ft_ies_length), + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + } + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Re-Association Request" + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + goto end; + } + + // Enable TL cahching in case of roaming + WLANTL_EnableCaching(psessionEntry->staId); + +end: + // Free up buffer allocated for mlmAssocReq + vos_mem_free( pMlmReassocReq ); + psessionEntry->pLimMlmReassocReq = NULL; + +} + +void limSendRetryReassocReqFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq, + tpPESession psessionEntry) +{ + tLimMlmReassocCnf mlmReassocCnf; // keep sme + tLimMlmReassocReq *pTmpMlmReassocReq = NULL; +#ifdef FEATURE_WLAN_ESE + tANI_U32 val=0; +#endif + if (pMlmReassocReq == NULL) + { + limLog(pMac, LOGE, + FL("Invalid pMlmReassocReq")); + goto end; + } + + pTmpMlmReassocReq = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if ( NULL == pTmpMlmReassocReq ) goto end; + vos_mem_set( pTmpMlmReassocReq, sizeof(tLimMlmReassocReq), 0); + vos_mem_copy( pTmpMlmReassocReq, pMlmReassocReq, sizeof(tLimMlmReassocReq)); + + // Prepare and send Reassociation request frame + // start reassoc timer. +#ifdef FEATURE_WLAN_ESE + /* + * In case of Ese Reassociation, change the reassoc timer + * value. + */ + val = pMlmReassocReq->reassocFailureTimeout; + if (psessionEntry->isESEconnection) + { + val = val/LIM_MAX_REASSOC_RETRY_LIMIT; + } + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer) != + TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to deactivate Reassoc failure timer")); + } + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimReassocFailureTimer, + val, 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to change Reassociation failure timer")); + } +#endif + + pMac->lim.limTimers.gLimReassocFailureTimer.sessionId = psessionEntry->peSessionId; + // Start reassociation failure timer + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_REASSOC_FAIL_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimReassocFailureTimer) + != TX_SUCCESS) + { + // Could not start reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not start Reassociation failure timer")); + // Return Reassoc confirm with + // Resources Unavailable + mlmReassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + goto end; + } + + limSendReassocReqWithFTIEsMgmtFrame(pMac, pTmpMlmReassocReq, psessionEntry); + return; + +end: + // Free up buffer allocated for reassocReq + if (pMlmReassocReq != NULL) + { + vos_mem_free(pMlmReassocReq); + pMlmReassocReq = NULL; + } + if (pTmpMlmReassocReq != NULL) + { + vos_mem_free(pTmpMlmReassocReq); + pTmpMlmReassocReq = NULL; + } + mlmReassocCnf.resultCode = eSIR_SME_FT_REASSOC_FAILURE; + mlmReassocCnf.protStatusCode = eSIR_MAC_UNSPEC_FAILURE_STATUS; + /* Update PE sessio Id*/ + mlmReassocCnf.sessionId = psessionEntry->peSessionId; + + limPostSmeMessage(pMac, LIM_MLM_REASSOC_CNF, (tANI_U32 *) &mlmReassocCnf); +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +void +limSendReassocReqMgmtFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry) +{ + static tDot11fReAssocRequest frm; + tANI_U16 caps; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tANI_U32 nBytes, nPayload, nStatus; + tANI_U8 fQosEnabled, fWmeEnabled, fWsmEnabled; + void *pPacket; + eHalStatus halstatus; + tANI_U16 nAddIELen; + tANI_U8 *pAddIE; + tANI_U8 *wpsIe = NULL; + tANI_U32 txFlag = 0; +#if defined WLAN_FEATURE_VOWIFI + tANI_U8 PowerCapsPopulated = FALSE; +#endif + tpSirMacMgmtHdr pMacHdr; + + if(NULL == psessionEntry) + { + return; + } + + /* check this early to avoid unncessary operation */ + if(NULL == psessionEntry->pLimReAssocReq) + { + return; + } + nAddIELen = psessionEntry->pLimReAssocReq->addIEAssoc.length; + pAddIE = psessionEntry->pLimReAssocReq->addIEAssoc.addIEdata; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + caps = pMlmReassocReq->capabilityInfo; + if (PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap)) + ((tSirMacCapabilityInfo *) &caps)->qos = 0; +#if defined(FEATURE_WLAN_WAPI) + /* CR: 262463 : + According to WAPI standard: + 7.3.1.4 Capability Information field + In WAPI, non-AP STAs within an ESS set the Privacy subfield to 0 in transmitted + Association or Reassociation management frames. APs ignore the Privacy subfield within received Association and + Reassociation management frames. */ + if ( psessionEntry->encryptType == eSIR_ED_WPI) + ((tSirMacCapabilityInfo *) &caps)->privacy = 0; +#endif + swapBitField16(caps, ( tANI_U16* )&frm.Capabilities ); + + frm.ListenInterval.interval = pMlmReassocReq->listenInterval; + + vos_mem_copy(( tANI_U8* )frm.CurrentAPAddress.mac, + ( tANI_U8* )psessionEntry->bssId, 6 ); + + PopulateDot11fSSID2( pMac, &frm.SSID ); + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.SuppRates,psessionEntry); + + fQosEnabled = ( psessionEntry->limQosEnabled ) && + SIR_MAC_GET_QOS( psessionEntry->limReassocBssCaps ); + + fWmeEnabled = ( psessionEntry->limWmeEnabled ) && + LIM_BSS_CAPS_GET( WME, psessionEntry->limReassocBssQosCaps ); + + fWsmEnabled = ( psessionEntry->limWsmEnabled ) && fWmeEnabled && + LIM_BSS_CAPS_GET( WSM, psessionEntry->limReassocBssQosCaps ); + + + if ( psessionEntry->lim11hEnable && + psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE ) + { +#if defined WLAN_FEATURE_VOWIFI + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps( pMac, &frm.PowerCaps, LIM_REASSOC,psessionEntry); + PopulateDot11fSuppChannels( pMac, &frm.SuppChannels, LIM_REASSOC,psessionEntry); +#endif + } + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limCurrentBssCaps ) ) + { + if (PowerCapsPopulated == FALSE) + { + PowerCapsPopulated = TRUE; + PopulateDot11fPowerCaps(pMac, &frm.PowerCaps, LIM_REASSOC, psessionEntry); + } + } +#endif + + if ( fQosEnabled && + ( ! PROP_CAPABILITY_GET(11EQOS, psessionEntry->limReassocBssPropCap ) )) + { + PopulateDot11fQOSCapsStation( pMac, &frm.QOSCapsStation ); + } + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &frm.ExtSuppRates, psessionEntry ); + +#if defined WLAN_FEATURE_VOWIFI + if( pMac->rrm.rrmPEContext.rrmEnable && + SIR_MAC_GET_RRM( psessionEntry->limReassocBssCaps ) ) + { + PopulateDot11fRRMIe( pMac, &frm.RRMEnabledCap, psessionEntry ); + } +#endif + // The join request *should* contain zero or one of the WPA and RSN + // IEs. The payload send along with the request is a + // 'tSirSmeJoinReq'; the IE portion is held inside a 'tSirRSNie': + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // So, we should be able to make the following two calls harmlessly, + // since they do nothing if they don't find the given IE in the + // bytestream with which they're provided. + + // The net effect of this will be to faithfully transmit whatever + // security IE is in the join request. + + // *However*, if we're associating for the purpose of WPS + // enrollment, and we've been configured to indicate that by + // eliding the WPA or RSN IE, we just skip this: + if( nAddIELen && pAddIE ) + { + wpsIe = limGetWscIEPtr(pMac, pAddIE, nAddIELen); + } + if ( NULL == wpsIe ) + { + PopulateDot11fRSNOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.RSNOpaque ); + PopulateDot11fWPAOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.WPAOpaque ); +#if defined(FEATURE_WLAN_WAPI) + PopulateDot11fWAPIOpaque( pMac, &( psessionEntry->pLimReAssocReq->rsnIE ), + &frm.WAPIOpaque ); +#endif // defined(FEATURE_WLAN_WAPI) + } + + // include WME EDCA IE as well + if ( fWmeEnabled ) + { + if ( ! PROP_CAPABILITY_GET( WME, psessionEntry->limReassocBssPropCap ) ) + { + PopulateDot11fWMMInfoStation( pMac, &frm.WMMInfoStation ); + } + + if ( fWsmEnabled && + ( ! PROP_CAPABILITY_GET(WSM, psessionEntry->limReassocBssPropCap ))) + { + PopulateDot11fWMMCaps( &frm.WMMCaps ); + } + } + + if ( psessionEntry->htCapability && + pMac->lim.htCapabilityPresentInBeacon) + { + PopulateDot11fHTCaps( pMac, psessionEntry, &frm.HTCaps ); + } + limLog(pMac, LOG1, FL("SupportedChnlWidth: %d, mimoPS: %d, GF: %d," + "shortGI20:%d, shortGI40: %d, dsssCck: %d, AMPDU Param: %x"), + frm.HTCaps.supportedChannelWidthSet, frm.HTCaps.mimoPowerSave, + frm.HTCaps.greenField, frm.HTCaps.shortGI20MHz, frm.HTCaps.shortGI40MHz, + frm.HTCaps.dsssCckMode40MHz, frm.HTCaps.maxRxAMPDUFactor); +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Re-Assoc Request")); + PopulateDot11fVHTCaps( pMac, &frm.VHTCaps, + psessionEntry->currentOperChannel, eSIR_FALSE ); + if (psessionEntry->ExtCap.present) + PopulateDot11fExtCap( pMac, &frm.ExtCap, psessionEntry); + } +#endif + + nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Re-Association Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fReAssocRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Re-Association Re " + "quest(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ) + nAddIELen; + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + psessionEntry->limMlmState = psessionEntry->limPrevMlmState; + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState)); + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Re-As" + "sociation Request."), nBytes ); + goto end; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_REASSOC_REQ, + psessionEntry->limReAssocbssId,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for an Association Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + + pMacHdr = (tpSirMacMgmtHdr) pFrame; + // That done, pack the Probe Request: + nStatus = dot11fPackReAssocRequest( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Re-Association Reque" + "st (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + goto end; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a R" + "e-Association Request (0x%08x)."), nStatus ); + } + + PELOG1(limLog( pMac, LOG1, FL("*** Sending Re-Association Request length %d" + "to "), + nBytes );) + + if( psessionEntry->assocReq != NULL ) + { + vos_mem_free(psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if( nAddIELen ) + { + vos_mem_copy( pFrame + sizeof(tSirMacMgmtHdr) + nPayload, + pAddIE, + nAddIELen ); + nPayload += nAddIELen; + } + + psessionEntry->assocReq = vos_mem_malloc(nPayload); + if ( NULL == psessionEntry->assocReq ) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store assoc request"));) + } + else + { + //Store the Assoc request. This is sent to csr/hdd in join cnf response. + vos_mem_copy(psessionEntry->assocReq, pFrame + sizeof(tSirMacMgmtHdr), nPayload); + psessionEntry->assocReqLen = nPayload; + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if(psessionEntry->pePersona == VOS_P2P_CLIENT_MODE || + psessionEntry->pePersona == VOS_STA_MODE) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_START_EVENT, psessionEntry, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + limLog(pMac, LOG1, FL("Reassoc req - txBdToken %u"), pMac->lim.txBdToken); + halstatus = halTxFrameWithTxComplete( pMac, pPacket, + ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload), + HAL_TXRX_FRM_802_11_MGMT, ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limTxBdComplete, + txFlag, pMac->lim.txBdToken ); + pMac->lim.txBdToken++; + } + else + { + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) (sizeof(tSirMacMgmtHdr) + nPayload), + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + } + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Re-Association Request" + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + goto end; + } + + // enable caching + WLANTL_EnableCaching(psessionEntry->staId); + +end: + // Free up buffer allocated for mlmAssocReq + vos_mem_free( pMlmReassocReq ); + psessionEntry->pLimMlmReassocReq = NULL; + +} // limSendReassocReqMgmtFrame + +eHalStatus limAuthTxCompleteCnf(tpAniSirGlobal pMac, void *pData) +{ + tANI_U32 txCompleteSuccess; + tpSirTxBdStatus pTxBdStatus; + + if (!pData) + { + limLog(pMac, LOG1, + FL(" pData is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + pTxBdStatus = (tpSirTxBdStatus) pData; + txCompleteSuccess = pTxBdStatus->txCompleteStatus; + limLog(pMac, LOG1, FL("txCompleteStatus %u, txBdToken %u"), + pTxBdStatus->txCompleteStatus, pTxBdStatus->txBdToken); + } + else + { + txCompleteSuccess = *((tANI_U32*) pData); + limLog(pMac, LOG1, + FL("txCompleteSuccess= %d"), txCompleteSuccess); + } + + if(txCompleteSuccess) + { + pMac->authAckStatus = LIM_AUTH_ACK_RCD_SUCCESS; + // 'Change' timer for future activations + limDeactivateAndChangeTimer(pMac, eLIM_AUTH_RETRY_TIMER); + } + else + pMac->authAckStatus = LIM_AUTH_ACK_RCD_FAILURE; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_AUTH_START_EVENT, NULL, + pMac->authAckStatus, eSIR_SUCCESS); +#endif + + return eHAL_STATUS_SUCCESS; +} + +/** + * \brief Send an Authentication frame + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pAuthFrameBody Pointer to Authentication frame structure that need + * to be sent + * + * \param peerMacAddr MAC address of the peer entity to which Authentication + * frame is destined + * + * \param wepBit Indicates whether wep bit to be set in FC while sending + * Authentication frame3 + * + * + * This function is called by limProcessMlmMessages(). Authentication frame + * is formatted and sent when this function is called. + * + * + */ + +void +limSendAuthMgmtFrame(tpAniSirGlobal pMac, + tpSirMacAuthFrameBody pAuthFrameBody, + tSirMacAddr peerMacAddr, + tANI_U8 wep_challenge_len, + tpPESession psessionEntry, + tAniBool waitForAck + ) +{ + tANI_U8 *pFrame, *pBody; + tANI_U32 frameLen = 0, bodyLen = 0; + tpSirMacMgmtHdr pMacHdr; + tANI_U16 i; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("Error: psession Entry is NULL")); + return; + } + + limLog(pMac, LOG1, + FL("Sending Auth seq# %d status %d (%d) to "MAC_ADDRESS_STR), + pAuthFrameBody->authTransactionSeqNumber, + pAuthFrameBody->authStatusCode, + (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS), + MAC_ADDR_ARRAY(peerMacAddr)); + if (wep_challenge_len) + { + /// Auth frame3 to be sent with encrypted framebody + /** + * Allocate buffer for Authenticaton frame of size equal + * to management frame header length plus 2 bytes each for + * auth algorithm number, transaction number, status code, + * 128 bytes for challenge text and 4 bytes each for + * IV & ICV. + */ + bodyLen = wep_challenge_len + LIM_ENCR_AUTH_INFO_LEN; + frameLen = sizeof(tSirMacMgmtHdr) + bodyLen; + } // if (wepBit == LIM_WEP_IN_FC) + else + { + switch (pAuthFrameBody->authTransactionSeqNumber) + { + case SIR_MAC_AUTH_FRAME_1: + /** + * Allocate buffer for Authenticaton frame of size + * equal to management frame header length plus 2 bytes + * each for auth algorithm number, transaction number + * and status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + +#if defined WLAN_FEATURE_VOWIFI_11R + if (pAuthFrameBody->authAlgoNumber == eSIR_FT_AUTH) + { + if (0 != pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length) + { + frameLen += pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length; + limLog(pMac, LOG3, FL("Auth frame, FTIES length added=%d"), + pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length); + } + else + { + limLog(pMac, LOG3, FL("Auth frame, Does not contain " + "FTIES!!!")); + frameLen += (2+SIR_MDIE_SIZE); + } + } +#endif + break; + + case SIR_MAC_AUTH_FRAME_2: + if ((pAuthFrameBody->authAlgoNumber == eSIR_OPEN_SYSTEM) || + ((pAuthFrameBody->authAlgoNumber == eSIR_SHARED_KEY) && + (pAuthFrameBody->authStatusCode != eSIR_MAC_SUCCESS_STATUS))) + { + /** + * Allocate buffer for Authenticaton frame of size + * equal to management frame header length plus + * 2 bytes each for auth algorithm number, + * transaction number and status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + } + else + { + // Shared Key algorithm with challenge text + // to be sent + /** + * Allocate buffer for Authenticaton frame of size + * equal to management frame header length plus + * 2 bytes each for auth algorithm number, + * transaction number, status code and 128 bytes + * for challenge text. + */ + + bodyLen = SIR_MAC_AUTH_FRAME_INFO_LEN + + SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + + SIR_MAC_CHALLENGE_ID_LEN; + frameLen = sizeof(tSirMacMgmtHdr) + + bodyLen; + } + + break; + + case SIR_MAC_AUTH_FRAME_3: + /// Auth frame3 to be sent without encrypted framebody + /** + * Allocate buffer for Authenticaton frame of size equal + * to management frame header length plus 2 bytes each + * for auth algorithm number, transaction number and + * status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + + break; + + case SIR_MAC_AUTH_FRAME_4: + /** + * Allocate buffer for Authenticaton frame of size equal + * to management frame header length plus 2 bytes each + * for auth algorithm number, transaction number and + * status code. + */ + + frameLen = sizeof(tSirMacMgmtHdr) + + SIR_MAC_AUTH_CHALLENGE_OFFSET; + bodyLen = SIR_MAC_AUTH_CHALLENGE_OFFSET; + + break; + } // switch (pAuthFrameBody->authTransactionSeqNumber) + } // end if (wepBit == LIM_WEP_IN_FC) + + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )frameLen, ( void** ) &pFrame, ( void** ) &pPacket ); + + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + // Log error + limLog(pMac, LOGP, FL("call to bufAlloc failed for AUTH frame")); + + return; + } + + for (i = 0; i < frameLen; i++) + pFrame[i] = 0; + + // Prepare BD + if (limPopulateMacHeader(pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_AUTH, peerMacAddr,psessionEntry->selfMacAddr) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("call to limPopulateMacHeader failed for " + "AUTH frame")); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + if (wep_challenge_len) + pMacHdr->fc.wep = LIM_WEP_IN_FC; + else + pMacHdr->fc.wep = LIM_NO_WEP_IN_FC; + + // Prepare BSSId + if( (psessionEntry->limSystemRole == eLIM_AP_ROLE)|| (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + } + + /// Prepare Authentication frame body + pBody = pFrame + sizeof(tSirMacMgmtHdr); + + if (wep_challenge_len) + { + vos_mem_copy(pBody, (tANI_U8 *) pAuthFrameBody, bodyLen); + + limLog(pMac, LOG1, + FL("*** Sending Auth seq# 3 status %d (%d) to"MAC_ADDRESS_STR), + pAuthFrameBody->authStatusCode, + (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS), + MAC_ADDR_ARRAY(pMacHdr->da)); + + } + else + { + *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(pAuthFrameBody->authAlgoNumber); + pBody += sizeof(tANI_U16); + bodyLen -= sizeof(tANI_U16); + + *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(pAuthFrameBody->authTransactionSeqNumber); + pBody += sizeof(tANI_U16); + bodyLen -= sizeof(tANI_U16); + + *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(pAuthFrameBody->authStatusCode); + pBody += sizeof(tANI_U16); + bodyLen -= sizeof(tANI_U16); + if ( bodyLen <= (sizeof (pAuthFrameBody->type) + + sizeof (pAuthFrameBody->length) + + sizeof (pAuthFrameBody->challengeText))) + vos_mem_copy(pBody, (tANI_U8 *) &pAuthFrameBody->type, bodyLen); + +#if defined WLAN_FEATURE_VOWIFI_11R + if ((pAuthFrameBody->authAlgoNumber == eSIR_FT_AUTH) && + (pAuthFrameBody->authTransactionSeqNumber == SIR_MAC_AUTH_FRAME_1)) + { + + { + int i = 0; + if (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG2(limLog(pMac, LOG2, FL("Auth1 Frame FTIE is: ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + (tANI_U8 *)pBody, + (pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies_length));) +#endif + for (i=0; ift.ftPEContext.pFTPreAuthReq->ft_ies_length; i++) + { + *pBody = pMac->ft.ftPEContext.pFTPreAuthReq->ft_ies[i]; + pBody++; + } + } + else + { + /* MDID attr is 54*/ + *pBody = 54; + pBody++; + *pBody = SIR_MDIE_SIZE; + pBody++; + for(i=0;ift.ftPEContext.pFTPreAuthReq->pbssDescription->mdie[i]; + pBody++; + } + } + } + } +#endif + + limLog(pMac, LOG1, + FL("*** Sending Auth seq# %d status %d (%d) to "MAC_ADDRESS_STR), + pAuthFrameBody->authTransactionSeqNumber, + pAuthFrameBody->authStatusCode, + (pAuthFrameBody->authStatusCode == eSIR_MAC_SUCCESS_STATUS), + MAC_ADDR_ARRAY(pMacHdr->da)); + } + PELOG2(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, pFrame, frameLen);) + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + || ((NULL != pMac->ft.ftPEContext.pFTPreAuthReq) + && ( SIR_BAND_5_GHZ == limGetRFBand(pMac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum))) +#endif + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + if(psessionEntry->pePersona == VOS_P2P_CLIENT_MODE || + psessionEntry->pePersona == VOS_STA_MODE) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + } + + limLog( pMac, LOG1, + FL("Sending Auth Frame over WQ5 with waitForAck %d to "MAC_ADDRESS_STR + " From " MAC_ADDRESS_STR), waitForAck, MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + + txFlag |= HAL_USE_FW_IN_TX_PATH; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + + if( ( psessionEntry->is11Gonly == true ) && + ( !IS_BROADCAST_MAC(peerMacAddr) ) ){ + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + if(eSIR_TRUE == waitForAck) + { + pMac->authAckStatus = LIM_AUTH_ACK_NOT_RCD; + limLog(pMac, LOG1, FL("Auth frame - txBdToken %u"), + pMac->lim.txBdToken); + halstatus = halTxFrameWithTxComplete( pMac, pPacket, + ( tANI_U16 ) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limAuthTxCompleteCnf, txFlag, + pMac->lim.txBdToken); + pMac->lim.txBdToken++; + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if (!HAL_STATUS_SUCCESS(halstatus)) + { + limLog( pMac, LOGE, + FL("Could not send Auth frame, retCode=%X "), + halstatus ); + pMac->authAckStatus = LIM_AUTH_ACK_RCD_FAILURE; + //Pkt will be freed up by the callback + } + } + else + { + /// Queue Authentication frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog(pMac, LOGE, + FL("*** Could not send Auth frame, retCode=%X ***"), + halstatus); + + //Pkt will be freed up by the callback + } + } + + return; +} /*** end limSendAuthMgmtFrame() ***/ + +eHalStatus limSendDeauthCnf(tpAniSirGlobal pMac) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tLimMlmDeauthReq *pMlmDeauthReq; + tLimMlmDeauthCnf mlmDeauthCnf; + tpPESession psessionEntry; + + pMlmDeauthReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq; + if (pMlmDeauthReq) + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDeauthAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DEAUTH_ACK_TIMER); + } + + if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDeauthReq->sessionId))== NULL) + { + + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + pStaDs = dphLookupHashEntry(pMac, pMlmDeauthReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + mlmDeauthCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + /// Receive path cleanup with dummy packet + limCleanupRxPath(pMac, pStaDs,psessionEntry); + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ( psessionEntry->limSystemRole == eLIM_STA_ROLE ) + { + PELOGE(limLog(pMac, LOG1, + FL("FT Preauth SessionId %d Cleanup" +#ifdef FEATURE_WLAN_ESE + " isESE %d" +#endif +#ifdef FEATURE_WLAN_LFR + " isLFR %d" +#endif + " is11r %d, Deauth reason %d Trigger = %d"), + psessionEntry->peSessionId, +#ifdef FEATURE_WLAN_ESE + psessionEntry->isESEconnection, +#endif +#ifdef FEATURE_WLAN_LFR + psessionEntry->isFastRoamIniFeatureEnabled, +#endif + psessionEntry->is11Rconnection, + pMlmDeauthReq->reasonCode, + pMlmDeauthReq->deauthTrigger);); + + limFTCleanup(pMac); + } +#endif + + /// Free up buffer allocated for mlmDeauthReq + vos_mem_free(pMlmDeauthReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq = NULL; + } + return eHAL_STATUS_SUCCESS; +end: + vos_mem_copy( (tANI_U8 *) &mlmDeauthCnf.peerMacAddr, + (tANI_U8 *) pMlmDeauthReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDeauthCnf.deauthTrigger = pMlmDeauthReq->deauthTrigger; + mlmDeauthCnf.aid = pMlmDeauthReq->aid; + mlmDeauthCnf.sessionId = pMlmDeauthReq->sessionId; + + // Free up buffer allocated + // for mlmDeauthReq + vos_mem_free(pMlmDeauthReq); + + limPostSmeMessage(pMac, + LIM_MLM_DEAUTH_CNF, + (tANI_U32 *) &mlmDeauthCnf); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus limSendDisassocCnf(tpAniSirGlobal pMac) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + tLimMlmDisassocCnf mlmDisassocCnf; + tpPESession psessionEntry; + tLimMlmDisassocReq *pMlmDisassocReq; + + pMlmDisassocReq = pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq; + if (pMlmDisassocReq) + { + if (tx_timer_running(&pMac->lim.limTimers.gLimDisassocAckTimer)) + { + limDeactivateAndChangeTimer(pMac, eLIM_DISASSOC_ACK_TIMER); + } + + if((psessionEntry = peFindSessionBySessionId(pMac, pMlmDisassocReq->sessionId))== NULL) + { + + PELOGE(limLog(pMac, LOGE, + FL("session does not exist for given sessionId"));) + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + pStaDs = dphLookupHashEntry(pMac, pMlmDisassocReq->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + limLog(pMac, LOGE, + FL("StaDs Null")); + mlmDisassocCnf.resultCode = eSIR_SME_INVALID_PARAMETERS; + goto end; + } + + /// Receive path cleanup with dummy packet + if(eSIR_SUCCESS != limCleanupRxPath(pMac, pStaDs, psessionEntry)) + { + mlmDisassocCnf.resultCode = eSIR_SME_RESOURCES_UNAVAILABLE; + limLog(pMac, LOGE, + FL("CleanupRxPath error")); + goto end; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE ) && + (pMlmDisassocReq->reasonCode != + eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON)) + { + PELOGE(limLog(pMac, LOG1, + FL("FT Preauth SessionId %d Cleanup" +#ifdef FEATURE_WLAN_ESE + " isESE %d" +#endif +#ifdef FEATURE_WLAN_LFR + " isLFR %d" +#endif + " is11r %d reason %d"), + psessionEntry->peSessionId, +#ifdef FEATURE_WLAN_ESE + psessionEntry->isESEconnection, +#endif +#ifdef FEATURE_WLAN_LFR + psessionEntry->isFastRoamIniFeatureEnabled, +#endif + psessionEntry->is11Rconnection, + pMlmDisassocReq->reasonCode);); + limFTCleanup(pMac); + } +#endif + + /// Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; + return eHAL_STATUS_SUCCESS; + } + else + { + return eHAL_STATUS_SUCCESS; + } +end: + vos_mem_copy( (tANI_U8 *) &mlmDisassocCnf.peerMacAddr, + (tANI_U8 *) pMlmDisassocReq->peerMacAddr, + sizeof(tSirMacAddr)); + mlmDisassocCnf.aid = pMlmDisassocReq->aid; + mlmDisassocCnf.disassocTrigger = pMlmDisassocReq->disassocTrigger; + + /* Update PE session ID*/ + mlmDisassocCnf.sessionId = pMlmDisassocReq->sessionId; + + if(pMlmDisassocReq != NULL) + { + /// Free up buffer allocated for mlmDisassocReq + vos_mem_free(pMlmDisassocReq); + pMac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq = NULL; + } + + limPostSmeMessage(pMac, + LIM_MLM_DISASSOC_CNF, + (tANI_U32 *) &mlmDisassocCnf); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus limDisassocTxCompleteCnf(tpAniSirGlobal pMac, void *pData) +{ + if (pData && IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + tpSirTxBdStatus pTxBdStatus; + pTxBdStatus = (tpSirTxBdStatus) pData; + limLog(pMac, LOG1, FL("txCompleteStatus %u, txBdToken %u"), + pTxBdStatus->txCompleteStatus, pTxBdStatus->txBdToken); + } + return limSendDisassocCnf(pMac); +} + +eHalStatus limDeauthTxCompleteCnf(tpAniSirGlobal pMac, void *pData) +{ + if (pData && IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + { + tpSirTxBdStatus pTxBdStatus; + pTxBdStatus = (tpSirTxBdStatus) pData; + limLog(pMac, LOG1, FL("txCompleteStatus %u, txBdToken %u"), + pTxBdStatus->txCompleteStatus, pTxBdStatus->txBdToken); + } + return limSendDeauthCnf(pMac); +} + +/** + * \brief This function is called to send Disassociate frame. + * + * + * \param pMac Pointer to Global MAC structure + * + * \param nReason Indicates the reason that need to be sent in + * Disassociation frame + * + * \param peerMacAddr MAC address of the STA to which Disassociation frame is + * sent + * + * + */ + +void +limSendDisassocMgmtFrame(tpAniSirGlobal pMac, + tANI_U16 nReason, + tSirMacAddr peer, + tpPESession psessionEntry, + tANI_BOOLEAN waitForAck) +{ + tDot11fDisassociation frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + tANI_U32 val = 0; + if(NULL == psessionEntry) + { + return; + } + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0); + + frm.Reason.code = nReason; + + nStatus = dot11fGetPackedDisassociationSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Disassociation (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDisassociation ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Disassociation " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Dis" + "association."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_DISASSOC, peer,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Disassociation (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + // Prepare the BSSID + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackDisassociation( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Disassociation (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a D" + "isassociation (0x%08x)."), nStatus ); + } + + limLog( pMac, LOG1, FL("***Sessionid %d Sending Disassociation frame with " + "reason %u and waitForAck %d to "MAC_ADDRESS_STR" ,From " + MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason, waitForAck, + MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + + if( IS_FW_IN_TX_PATH_FEATURE_ENABLE ) + { + /* This frame will be sent on air by firmware, + which will ensure that this frame goes out + even though DEL_STA is sent immediately */ + /* Without this for DEL_STA command there is + risk of flushing frame in BTQM queue without + sending on air */ + limLog( pMac, LOG1, FL("Sending Disassoc Frame over WQ5 to "MAC_ADDRESS_STR + " From " MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + txFlag |= HAL_USE_FW_IN_TX_PATH; + } + + if (waitForAck) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + // Queue Disassociation frame in high priority WQ + /* get the duration from the request */ + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limDisassocTxCompleteCnf, + txFlag, + pMac->lim.txBdToken++); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); + + if (tx_timer_change( + &pMac->lim.limTimers.gLimDisassocAckTimer, val, 0) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to change Disassoc ack Timer val")); + return; + } + else if(TX_SUCCESS != tx_timer_activate( + &pMac->lim.limTimers.gLimDisassocAckTimer)) + { + limLog(pMac, LOGP, + FL("Unable to activate Disassoc ack Timer")); + limDeactivateAndChangeTimer(pMac, eLIM_DISASSOC_ACK_TIMER); + return; + } + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send Disassociation " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return; + } + } +} // End limSendDisassocMgmtFrame. + +/** + * \brief This function is called to send a Deauthenticate frame + * + * + * \param pMac Pointer to global MAC structure + * + * \param nReason Indicates the reason that need to be sent in the + * Deauthenticate frame + * + * \param peeer address of the STA to which the frame is to be sent + * + * + */ + +void +limSendDeauthMgmtFrame(tpAniSirGlobal pMac, + tANI_U16 nReason, + tSirMacAddr peer, + tpPESession psessionEntry, + tANI_BOOLEAN waitForAck) +{ + tDot11fDeAuth frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + tANI_U32 val = 0; +#ifdef FEATURE_WLAN_TDLS + tANI_U16 aid; + tpDphHashNode pStaDs; +#endif + + if(NULL == psessionEntry) + { + return; + } + + vos_mem_set( ( tANI_U8* ) &frm, sizeof( frm ), 0 ); + + frm.Reason.code = nReason; + + nStatus = dot11fGetPackedDeAuthSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a De-Authentication (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDeAuth ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a De-Authentication " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a De-" + "Authentication."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_DEAUTH, peer,psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a De-Authentication (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + // Prepare the BSSID + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackDeAuth( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a DeAuthentication (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a D" + "e-Authentication (0x%08x)."), nStatus ); + } + limLog( pMac, LOG1, FL("***Sessionid %d Sending Deauth frame with " + "reason %u and waitForAck %d to "MAC_ADDRESS_STR" ,From " + MAC_ADDRESS_STR), psessionEntry->peSessionId, nReason, waitForAck, + MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + + if( IS_FW_IN_TX_PATH_FEATURE_ENABLE ) + { + /* This frame will be sent on air by firmware, + which will ensure that this frame goes out + even though DEL_STA is sent immediately */ + /* Without this for DEL_STA command there is + risk of flushing frame in BTQM queue without + sending on air */ + limLog( pMac, LOG1, FL("Sending Deauth Frame over WQ5 to "MAC_ADDRESS_STR + " From " MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pMacHdr->da), + MAC_ADDR_ARRAY(psessionEntry->selfMacAddr)); + txFlag |= HAL_USE_FW_IN_TX_PATH; + } + +#ifdef FEATURE_WLAN_TDLS + pStaDs = dphLookupHashEntry(pMac, peer, &aid, &psessionEntry->dph.dphHashTable); +#endif + + if (waitForAck) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrameWithTxComplete( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, limDeauthTxCompleteCnf, txFlag, + pMac->lim.txBdToken++); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if (!HAL_STATUS_SUCCESS(halstatus)) + { + limLog( pMac, LOGE, FL("Failed to send De-Authentication " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback limTxComplete + + /*Call limProcessDeauthAckTimeout which will send + * DeauthCnf for this frame + */ + limProcessDeauthAckTimeout(pMac); + return; + } + + val = SYS_MS_TO_TICKS(LIM_DISASSOC_DEAUTH_ACK_TIMEOUT); + + if (tx_timer_change( + &pMac->lim.limTimers.gLimDeauthAckTimer, val, 0) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to change Deauth ack Timer val")); + return; + } + else if(TX_SUCCESS != tx_timer_activate( + &pMac->lim.limTimers.gLimDeauthAckTimer)) + { + limLog(pMac, LOGP, + FL("Unable to activate Deauth ack Timer")); + limDeactivateAndChangeTimer(pMac, eLIM_DEAUTH_ACK_TIMER); + return; + } + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); +#ifdef FEATURE_WLAN_TDLS + if ((NULL != pStaDs) && (STA_ENTRY_TDLS_PEER == pStaDs->staType)) + { + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_IBSS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + } + else + { +#endif + // Queue Disassociation frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); +#ifdef FEATURE_WLAN_TDLS + } +#endif + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send De-Authentication " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return; + } + } + +} // End limSendDeauthMgmtFrame. + + +#ifdef ANI_SUPPORT_11H +/** + * \brief Send a Measurement Report Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pMeasReqFrame Address of a tSirMacMeasReqActionFrame + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendMeasReportFrame(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tSirMacAddr peer) +{ + tDot11fMeasurementReport frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus, nCfg; + void *pPacket; + eHalStatus halstatus; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_MEASURE_REPORT_ID; + frm.DialogToken.token = pMeasReqFrame->actionHeader.dialogToken; + + switch ( pMeasReqFrame->measReqIE.measType ) + { + case SIR_MAC_BASIC_MEASUREMENT_TYPE: + nSirStatus = + PopulateDot11fMeasurementReport0( pMac, pMeasReqFrame, + &frm.MeasurementReport ); + break; + case SIR_MAC_CCA_MEASUREMENT_TYPE: + nSirStatus = + PopulateDot11fMeasurementReport1( pMac, pMeasReqFrame, + &frm.MeasurementReport ); + break; + case SIR_MAC_RPI_MEASUREMENT_TYPE: + nSirStatus = + PopulateDot11fMeasurementReport2( pMac, pMeasReqFrame, + &frm.MeasurementReport ); + break; + default: + limLog( pMac, LOGE, FL("Unknown measurement type %d in limSen" + "dMeasReportFrame."), + pMeasReqFrame->measReqIE.measType ); + return eSIR_FAILURE; + } + + if ( eSIR_SUCCESS != nSirStatus ) return eSIR_FAILURE; + + nStatus = dot11fGetPackedMeasurementReportSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Measurement Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fMeasurementReport ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Measurement Rep" + "ort (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a De-" + "Authentication."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Measurement Report (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + nCfg = 6; + nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg ); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from" + " CFG (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackMeasurementReport( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Measurement Report (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a M" + "easurement Report (0x%08x)."), nStatus ); + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, 0 ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Measurement Report " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; // just allocated... + } + + return eSIR_SUCCESS; + +} // End limSendMeasReportFrame. + + +/** + * \brief Send a TPC Request Action frame + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param peer MAC address to which the frame should be sent + * + * + */ + +void +limSendTpcRequestFrame(tpAniSirGlobal pMac, + tSirMacAddr peer) +{ + tDot11fTPCRequest frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus, nCfg; + void *pPacket; + eHalStatus halstatus; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_TPC_REQUEST_ID; + frm.DialogToken.token = 1; + frm.TPCRequest.present = 1; + + nStatus = dot11fGetPackedTPCRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a TPC Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fTPCRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a TPC Request (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Request."), nBytes ); + return; + } + + // Paranoia: + vos_mem_set(pFrame, nBytes,0); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a TPC Request (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + nCfg = 6; + nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg ); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from" + " CFG (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // just allocated... + } + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackTPCRequest( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TPC Request (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a T" + "PC Request (0x%08x)."), nStatus ); + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, 0 ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a TPC Request " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return; + } + +} // End limSendTpcRequestFrame. + + +/** + * \brief Send a TPC Report Action frame + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param pTpcReqFrame Pointer to the received TPC Request + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendTpcReportFrame(tpAniSirGlobal pMac, + tpSirMacTpcReqActionFrame pTpcReqFrame, + tSirMacAddr peer) +{ + tDot11fTPCReport frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus, nCfg; + void *pPacket; + eHalStatus halstatus; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_TPC_REPORT_ID; + frm.DialogToken.token = pTpcReqFrame->actionHeader.dialogToken; + + // FramesToDo: On the Gen4_TVM branch, there was a comment: + // "misplaced this function, need to replace: + // txPower = halGetRateToPwrValue(pMac, staid, + // pMac->lim.gLimCurrentChannelId, 0); + frm.TPCReport.tx_power = 0; + frm.TPCReport.link_margin = 0; + frm.TPCReport.present = 1; + + nStatus = dot11fGetPackedTPCReportSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a TPC Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fTPCReport ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a TPC Report (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a TPC Report (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + nCfg = 6; + nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg ); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from" + " CFG (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackTPCReport( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a TPC Report (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a T" + "PC Report (0x%08x)."), nStatus ); + } + + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, 0 ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + ((psessionEntry)? psessionEntry->peSessionId : NO_SESSION), + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a TPC Report " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; // just allocated... + } + + return eSIR_SUCCESS; + +} // End limSendTpcReportFrame. +#endif //ANI_SUPPORT_11H + + +/** + * \brief Send a Channel Switch Announcement + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param peer MAC address to which this frame will be sent + * + * \param nMode + * + * \param nNewChannel + * + * \param nCount + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendChannelSwitchMgmtFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 nMode, + tANI_U8 nNewChannel, + tANI_U8 nCount, + tpPESession psessionEntry ) +{ + tDot11fChannelSwitch frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus;//, nCfg; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID; + frm.ChanSwitchAnn.switchMode = nMode; + frm.ChanSwitchAnn.newChannel = nNewChannel; + frm.ChanSwitchAnn.switchCount = nCount; + frm.ChanSwitchAnn.present = 1; + + nStatus = dot11fGetPackedChannelSwitchSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Channel Switch (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fChannelSwitch ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Channel Switch (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr); + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Channel Switch (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + +#if 0 + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + nCfg = 6; + nSirStatus = wlan_cfgGetStr( pMac, WNI_CFG_BSSID, pMacHdr->bssId, &nCfg ); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to retrieve WNI_CFG_BSSID from" + " CFG (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } +#endif + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + nStatus = dot11fPackChannelSwitch( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Channel Switch (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a C" + "hannel Switch (0x%08x)."), nStatus ); + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Channel Switch " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End limSendChannelSwitchMgmtFrame. + + + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus +limSendVHTOpmodeNotificationFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 nMode, + tpPESession psessionEntry ) +{ + tDot11fOperatingMode frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload = 0, nStatus;//, nCfg; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_VHT; + frm.Action.action = SIR_MAC_VHT_OPMODE_NOTIFICATION; + frm.OperatingMode.chanWidth = nMode; + frm.OperatingMode.rxNSS = 0; + frm.OperatingMode.rxNSSType = 0; + + nStatus = dot11fGetPackedOperatingModeSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Operating Mode (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fOperatingMode); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Operating Mode (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Operating Mode" + " Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + + // Next, we fill out the buffer descriptor: + if(psessionEntry->pePersona == VOS_STA_SAP_MODE) { + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr); + } else + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, psessionEntry->bssId, psessionEntry->selfMacAddr); + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Operating Mode (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + nStatus = dot11fPackOperatingMode( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Operating Mode (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a Operating Mode" + " (0x%08x)."), nStatus ); + } + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Channel Switch " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +/** + * \brief Send a VHT Channel Switch Announcement + * + * + * \param pMac Pointer to the global MAC datastructure + * + * \param peer MAC address to which this frame will be sent + * + * \param nChanWidth + * + * \param nNewChannel + * + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendVHTChannelSwitchMgmtFrame(tpAniSirGlobal pMac, + tSirMacAddr peer, + tANI_U8 nChanWidth, + tANI_U8 nNewChannel, + tANI_U8 ncbMode, + tpPESession psessionEntry ) +{ + tDot11fChannelSwitch frm; + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus;//, nCfg; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + + frm.Category.category = SIR_MAC_ACTION_SPECTRUM_MGMT; + frm.Action.action = SIR_MAC_ACTION_CHANNEL_SWITCH_ID; + frm.ChanSwitchAnn.switchMode = 1; + frm.ChanSwitchAnn.newChannel = nNewChannel; + frm.ChanSwitchAnn.switchCount = 1; + frm.ExtChanSwitchAnn.secondaryChannelOffset = limGetHTCBState(ncbMode); + frm.ExtChanSwitchAnn.present = 1; + frm.WiderBWChanSwitchAnn.newChanWidth = nChanWidth; + frm.WiderBWChanSwitchAnn.newCenterChanFreq0 = limGetCenterChannel(pMac,nNewChannel,ncbMode,nChanWidth); + frm.WiderBWChanSwitchAnn.newCenterChanFreq1 = 0; + frm.ChanSwitchAnn.present = 1; + frm.WiderBWChanSwitchAnn.present = 1; + + nStatus = dot11fGetPackedChannelSwitchSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Channel Switch (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fChannelSwitch ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Channel Switch (0x" + "%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a TPC" + " Report."), nBytes ); + return eSIR_FAILURE; + } + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peer, psessionEntry->selfMacAddr); + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, + (tANI_U8 *) psessionEntry->bssId, + sizeof( tSirMacAddr )); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Channel Switch (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // just allocated... + } + nStatus = dot11fPackChannelSwitch( pMac, &frm, pFrame + + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack a Channel Switch (0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing a C" + "hannel Switch (0x%08x)."), nStatus ); + } + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL("Failed to send a Channel Switch " + "(%X)!"), + nSirStatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End limSendVHTChannelSwitchMgmtFrame. + + + +#endif + +/** + * \brief Send an ADDBA Req Action Frame to peer + * + * \sa limSendAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMlmAddBAReq A pointer to tLimMlmAddBAReq. This contains + * the necessary parameters reqd by PE send the ADDBA Req Action + * Frame to the peer + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limSendAddBAReq( tpAniSirGlobal pMac, + tpLimMlmAddBAReq pMlmAddBAReq, tpPESession psessionEntry) +{ + tDot11fAddBAReq frmAddBAReq; + tANI_U8 *pAddBAReqBuffer = NULL; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 frameLen = 0, nStatus, nPayload; + tSirRetStatus statusCode; + eHalStatus halStatus; + void *pPacket; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + return eSIR_FAILURE; + } + + vos_mem_set( (void *) &frmAddBAReq, sizeof( frmAddBAReq ), 0); + + // Category - 3 (BA) + frmAddBAReq.Category.category = SIR_MAC_ACTION_BLKACK; + + // Action - 0 (ADDBA Req) + frmAddBAReq.Action.action = SIR_MAC_BLKACK_ADD_REQ; + + // FIXME - Dialog Token, generalize this... + frmAddBAReq.DialogToken.token = pMlmAddBAReq->baDialogToken; + + // Fill the ADDBA Parameter Set + frmAddBAReq.AddBAParameterSet.tid = pMlmAddBAReq->baTID; + frmAddBAReq.AddBAParameterSet.policy = pMlmAddBAReq->baPolicy; + frmAddBAReq.AddBAParameterSet.bufferSize = pMlmAddBAReq->baBufferSize; + + // BA timeout + // 0 - indicates no BA timeout + frmAddBAReq.BATimeout.timeout = pMlmAddBAReq->baTimeout; + + /* Send SSN whatever we get from FW. + */ + frmAddBAReq.BAStartingSequenceControl.ssn = pMlmAddBAReq->baSSN; + + nStatus = dot11fGetPackedAddBAReqSize( pMac, &frmAddBAReq, &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGW, + FL( "Failed to calculate the packed size for " + "an ADDBA Request (0x%08x)."), + nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddBAReq ); + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while calculating " + "the packed size for an ADDBA Req (0x%08x)."), + nStatus ); + } + + // Add the MGMT header to frame length + frameLen = nPayload + sizeof( tSirMacMgmtHdr ); + + // Need to allocate a buffer for ADDBA AF + if( eHAL_STATUS_SUCCESS != + (halStatus = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16) frameLen, + (void **) &pAddBAReqBuffer, + (void **) &pPacket ))) + { + // Log error + limLog( pMac, LOGP, + FL("palPktAlloc FAILED! Length [%d], Status [%d]"), + frameLen, + halStatus ); + + statusCode = eSIR_MEM_ALLOC_FAILED; + goto returnAfterError; + } + + vos_mem_set( (void *) pAddBAReqBuffer, frameLen, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pAddBAReqBuffer, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + pMlmAddBAReq->peerMacAddr,psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pAddBAReqBuffer; + + #if 0 + cfgLen = SIR_MAC_ADDR_LENGTH; + if( eSIR_SUCCESS != cfgGetStr( pMac, + WNI_CFG_BSSID, + (tANI_U8 *) pMacHdr->bssId, + &cfgLen )) + { + limLog( pMac, LOGP, + FL( "Failed to retrieve WNI_CFG_BSSID while" + "sending an ACTION Frame" )); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + #endif//TO SUPPORT BT-AMP + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, pMlmAddBAReq->peerMacAddr, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackAddBAReq( pMac, + &frmAddBAReq, + pAddBAReqBuffer + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an ADDBA Req (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing an ADDBA Req (0x%08x)."), + nStatus ); + } + + limLog( pMac, LOG1, FL( "Sending an ADDBA REQ to "MAC_ADDRESS_STR " with" + " tid = %d policy = %d buffsize = %d " + " amsduSupported = %d"), + MAC_ADDR_ARRAY(pMlmAddBAReq->peerMacAddr), + frmAddBAReq.AddBAParameterSet.tid, + frmAddBAReq.AddBAParameterSet.policy, + frmAddBAReq.AddBAParameterSet.bufferSize, + frmAddBAReq.AddBAParameterSet.amsduSupported); + + limLog( pMac, LOG1, FL( "ssn = %d fragNum = %d" ), + frmAddBAReq.BAStartingSequenceControl.ssn, + frmAddBAReq.BAStartingSequenceControl.fragNumber); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halStatus = halTxFrame( pMac, + pPacket, + (tANI_U16) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pAddBAReqBuffer, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halStatus)); + if( eHAL_STATUS_SUCCESS != halStatus ) + { + limLog( pMac, LOGE, + FL( "halTxFrame FAILED! Status [%d]"), + halStatus ); + + // FIXME - Need to convert eHalStatus to tSirRetStatus + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + +returnAfterError: + + // Release buffer, if allocated + if( NULL != pAddBAReqBuffer ) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) pAddBAReqBuffer, + (void *) pPacket ); + + return statusCode; +} + +/** + * \brief Send an ADDBA Rsp Action Frame to peer + * + * \sa limSendAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param pMlmAddBARsp A pointer to tLimMlmAddBARsp. This contains + * the necessary parameters reqd by PE send the ADDBA Rsp Action + * Frame to the peer + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limSendAddBARsp( tpAniSirGlobal pMac, + tpLimMlmAddBARsp pMlmAddBARsp, + tpPESession psessionEntry) +{ + tDot11fAddBARsp frmAddBARsp; + tANI_U8 *pAddBARspBuffer = NULL; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 frameLen = 0, nStatus, nPayload; + tSirRetStatus statusCode; + eHalStatus halStatus; + void *pPacket; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOGE, FL("Session entry is NULL!!!"));) + return eSIR_FAILURE; + } + + vos_mem_set( (void *) &frmAddBARsp, sizeof( frmAddBARsp ), 0); + + // Category - 3 (BA) + frmAddBARsp.Category.category = SIR_MAC_ACTION_BLKACK; + // Action - 1 (ADDBA Rsp) + frmAddBARsp.Action.action = SIR_MAC_BLKACK_ADD_RSP; + + // Should be same as the one we received in the ADDBA Req + frmAddBARsp.DialogToken.token = pMlmAddBARsp->baDialogToken; + + // ADDBA Req status + frmAddBARsp.Status.status = pMlmAddBARsp->addBAResultCode; + + // Fill the ADDBA Parameter Set as provided by caller + frmAddBARsp.AddBAParameterSet.tid = pMlmAddBARsp->baTID; + frmAddBARsp.AddBAParameterSet.policy = pMlmAddBARsp->baPolicy; + frmAddBARsp.AddBAParameterSet.bufferSize = pMlmAddBARsp->baBufferSize; + + if(psessionEntry->isAmsduSupportInAMPDU) + { + frmAddBARsp.AddBAParameterSet.amsduSupported = + psessionEntry->amsduSupportedInBA; + } + else + { + frmAddBARsp.AddBAParameterSet.amsduSupported = 0; + } + + // BA timeout + // 0 - indicates no BA timeout + frmAddBARsp.BATimeout.timeout = pMlmAddBARsp->baTimeout; + + nStatus = dot11fGetPackedAddBARspSize( pMac, &frmAddBARsp, &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGW, + FL( "Failed to calculate the packed size for " + "an ADDBA Response (0x%08x)."), + nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fAddBARsp ); + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while calculating " + "the packed size for an ADDBA Rsp (0x%08x)."), + nStatus ); + } + + // Need to allocate a buffer for ADDBA AF + frameLen = nPayload + sizeof( tSirMacMgmtHdr ); + + // Allocate shared memory + if( eHAL_STATUS_SUCCESS != + (halStatus = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16) frameLen, + (void **) &pAddBARspBuffer, + (void **) &pPacket ))) + { + // Log error + limLog( pMac, LOGP, + FL("palPktAlloc FAILED! Length [%d], Status [%d]"), + frameLen, + halStatus ); + + statusCode = eSIR_MEM_ALLOC_FAILED; + goto returnAfterError; + } + + vos_mem_set( (void *) pAddBARspBuffer, frameLen, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pAddBARspBuffer, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + pMlmAddBARsp->peerMacAddr,psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + + pMacHdr = ( tpSirMacMgmtHdr ) pAddBARspBuffer; + + #if 0 + cfgLen = SIR_MAC_ADDR_LENGTH; + if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, + WNI_CFG_BSSID, + (tANI_U8 *) pMacHdr->bssId, + &cfgLen )) + { + limLog( pMac, LOGP, + FL( "Failed to retrieve WNI_CFG_BSSID while" + "sending an ACTION Frame" )); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + #endif // TO SUPPORT BT-AMP + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, pMlmAddBARsp->peerMacAddr, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackAddBARsp( pMac, + &frmAddBARsp, + pAddBARspBuffer + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an ADDBA Rsp (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing an ADDBA Rsp (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOG1, FL( "Sending an ADDBA RSP to "MAC_ADDRESS_STR " with" + " tid = %d policy = %d buffsize = %d" + " amsduSupported = %d status %d"), + MAC_ADDR_ARRAY(pMlmAddBARsp->peerMacAddr), + frmAddBARsp.AddBAParameterSet.tid, + frmAddBARsp.AddBAParameterSet.policy, + frmAddBARsp.AddBAParameterSet.bufferSize, + frmAddBARsp.AddBAParameterSet.amsduSupported, + frmAddBARsp.Status.status); + + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halStatus = halTxFrame( pMac, + pPacket, + (tANI_U16) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pAddBARspBuffer, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halStatus)); + if( eHAL_STATUS_SUCCESS != halStatus ) + { + limLog( pMac, LOGE, + FL( "halTxFrame FAILED! Status [%d]" ), + halStatus ); + + // FIXME - HAL error codes are different from PE error + // codes!! And, this routine is returning tSirRetStatus + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + + returnAfterError: + // Release buffer, if allocated + if( NULL != pAddBARspBuffer ) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) pAddBARspBuffer, + (void *) pPacket ); + + return statusCode; +} + +/** + * \brief Send a DELBA Indication Action Frame to peer + * + * \sa limSendDelBAInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param peerMacAddr MAC Address of peer + * + * \param reasonCode Reason for the DELBA notification + * + * \param pBAParameterSet The DELBA Parameter Set. + * This identifies the TID for which the BA session is + * being deleted. + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limSendDelBAInd( tpAniSirGlobal pMac, + tpLimMlmDelBAReq pMlmDelBAReq,tpPESession psessionEntry) +{ + tDot11fDelBAInd frmDelBAInd; + tANI_U8 *pDelBAIndBuffer = NULL; + //tANI_U32 val; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 frameLen = 0, nStatus, nPayload; + tSirRetStatus statusCode; + eHalStatus halStatus; + void *pPacket; + tANI_U32 txFlag = 0; + + if(NULL == psessionEntry) + { + return eSIR_FAILURE; + } + + vos_mem_set( (void *) &frmDelBAInd, sizeof( frmDelBAInd ), 0); + + // Category - 3 (BA) + frmDelBAInd.Category.category = SIR_MAC_ACTION_BLKACK; + // Action - 2 (DELBA) + frmDelBAInd.Action.action = SIR_MAC_BLKACK_DEL; + + // Fill the DELBA Parameter Set as provided by caller + frmDelBAInd.DelBAParameterSet.tid = pMlmDelBAReq->baTID; + frmDelBAInd.DelBAParameterSet.initiator = pMlmDelBAReq->baDirection; + + // BA Starting Sequence Number + // Fragment number will always be zero + frmDelBAInd.Reason.code = pMlmDelBAReq->delBAReasonCode; + + nStatus = dot11fGetPackedDelBAIndSize( pMac, &frmDelBAInd, &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGW, + FL( "Failed to calculate the packed size for " + "an DELBA Indication (0x%08x)."), + nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fDelBAInd ); + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while calculating " + "the packed size for an DELBA Ind (0x%08x)."), + nStatus ); + } + + // Add the MGMT header to frame length + frameLen = nPayload + sizeof( tSirMacMgmtHdr ); + + // Allocate shared memory + if( eHAL_STATUS_SUCCESS != + (halStatus = palPktAlloc( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (tANI_U16) frameLen, + (void **) &pDelBAIndBuffer, + (void **) &pPacket ))) + { + // Log error + limLog( pMac, LOGP, + FL("palPktAlloc FAILED! Length [%d], Status [%d]"), + frameLen, + halStatus ); + + statusCode = eSIR_MEM_ALLOC_FAILED; + goto returnAfterError; + } + + vos_mem_set( (void *) pDelBAIndBuffer, frameLen, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pDelBAIndBuffer, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + pMlmDelBAReq->peerMacAddr,psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pDelBAIndBuffer; + + #if 0 + cfgLen = SIR_MAC_ADDR_LENGTH; + if( eSIR_SUCCESS != cfgGetStr( pMac, + WNI_CFG_BSSID, + (tANI_U8 *) pMacHdr->bssId, + &cfgLen )) + { + limLog( pMac, LOGP, + FL( "Failed to retrieve WNI_CFG_BSSID while" + "sending an ACTION Frame" )); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + #endif //TO SUPPORT BT-AMP + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, pMlmDelBAReq->peerMacAddr, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackDelBAInd( pMac, + &frmDelBAInd, + pDelBAIndBuffer + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an DELBA Ind (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing an DELBA Ind (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOG1, + FL( "Sending a DELBA IND to: "MAC_ADDRESS_STR" with Tid = %d" + " initiator = %d reason = %d" ), + MAC_ADDR_ARRAY(pMlmDelBAReq->peerMacAddr), + frmDelBAInd.DelBAParameterSet.tid, + frmDelBAInd.DelBAParameterSet.initiator, + frmDelBAInd.Reason.code); + + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halStatus = halTxFrame( pMac, + pPacket, + (tANI_U16) frameLen, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pDelBAIndBuffer, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halStatus)); + if( eHAL_STATUS_SUCCESS != halStatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halStatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + + returnAfterError: + + // Release buffer, if allocated + if( NULL != pDelBAIndBuffer ) + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) pDelBAIndBuffer, + (void *) pPacket ); + + return statusCode; +} + +#if defined WLAN_FEATURE_VOWIFI + +/** + * \brief Send a Neighbor Report Request Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pNeighborReq Address of a tSirMacNeighborReportReq + * + * \param peer mac address of peer station. + * + * \param psessionEntry address of session entry. + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendNeighborReportRequestFrame(tpAniSirGlobal pMac, + tpSirMacNeighborReportReq pNeighborReq, + tSirMacAddr peer, + tpPESession psessionEntry + ) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tDot11fNeighborReportRequest frm; + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + if ( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Neighbor Report request action frame") ); + return eSIR_FAILURE; + } + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_RRM; + frm.Action.action = SIR_MAC_RRM_NEIGHBOR_REQ; + frm.DialogToken.token = pNeighborReq->dialogToken; + + + if( pNeighborReq->ssid_present ) + { + PopulateDot11fSSID( pMac, &pNeighborReq->ssid, &frm.SSID ); + } + + nStatus = dot11fGetPackedNeighborReportRequestSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Neighbor Report Request(0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fNeighborReportRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Neighbor Rep" + "ort Request(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Neighbor " + "Report Request."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackNeighborReportRequest( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an Neighbor Report Request (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing Neighbor Report " + "Request (0x%08x)." ), nStatus); + } + + limLog( pMac, LOGW, + FL( "Sending a Neighbor Report Request to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + + return statusCode; +} // End limSendNeighborReportRequestFrame. + +/** + * \brief Send a Link Report Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pLinkReport Address of a tSirMacLinkReport + * + * \param peer mac address of peer station. + * + * \param psessionEntry address of session entry. + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendLinkReportActionFrame(tpAniSirGlobal pMac, + tpSirMacLinkReport pLinkReport, + tSirMacAddr peer, + tpPESession psessionEntry + ) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tDot11fLinkMeasurementReport frm; + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + + if ( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Link Report action frame") ); + return eSIR_FAILURE; + } + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + + frm.Category.category = SIR_MAC_ACTION_RRM; + frm.Action.action = SIR_MAC_RRM_LINK_MEASUREMENT_RPT; + frm.DialogToken.token = pLinkReport->dialogToken; + + + //IEEE Std. 802.11 7.3.2.18. for the report element. + //Even though TPC report an IE, it is represented using fixed fields since it is positioned + //in the middle of other fixed fields in the link report frame(IEEE Std. 802.11k section7.4.6.4 + //and frame parser always expects IEs to come after all fixed fields. It is easier to handle + //such case this way than changing the frame parser. + frm.TPCEleID.TPCId = SIR_MAC_TPC_RPT_EID; + frm.TPCEleLen.TPCLen = 2; + frm.TxPower.txPower = pLinkReport->txPower; + frm.LinkMargin.linkMargin = 0; + + frm.RxAntennaId.antennaId = pLinkReport->rxAntenna; + frm.TxAntennaId.antennaId = pLinkReport->txAntenna; + frm.RCPI.rcpi = pLinkReport->rcpi; + frm.RSNI.rsni = pLinkReport->rsni; + + nStatus = dot11fGetPackedLinkMeasurementReportSize( pMac, &frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Link Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fLinkMeasurementReport ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Link Rep" + "ort (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Link " + "Report."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackLinkMeasurementReport( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an Link Report (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing Link Report (0x%08x)." ), + nStatus ); + } + + limLog( pMac, LOGW, + FL( "Sending a Link Report to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + return statusCode; + } + else + return eSIR_SUCCESS; + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + + return statusCode; +} // End limSendLinkReportActionFrame. + +/** + * \brief Send a Beacon Report Action frame + * + * + * \param pMac Pointer to the global MAC structure + * + * \param dialog_token dialog token to be used in the action frame. + * + * \param num_report number of reports in pRRMReport. + * + * \param pRRMReport Address of a tSirMacRadioMeasureReport. + * + * \param peer mac address of peer station. + * + * \param psessionEntry address of session entry. + * + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + * + * + */ + +tSirRetStatus +limSendRadioMeasureReportActionFrame(tpAniSirGlobal pMac, + tANI_U8 dialog_token, + tANI_U8 num_report, + tpSirMacRadioMeasureReport pRRMReport, + tSirMacAddr peer, + tpPESession psessionEntry + ) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tANI_U8 *pFrame; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 i; + tANI_U32 txFlag = 0; + + tDot11fRadioMeasurementReport *frm = + vos_mem_malloc(sizeof(tDot11fRadioMeasurementReport)); + if (!frm) { + limLog( pMac, LOGE, FL("Not enough memory to allocate tDot11fRadioMeasurementReport") ); + return eSIR_FAILURE; + } + + if ( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("(psession == NULL) in Request to send Beacon Report action frame") ); + vos_mem_free(frm); + return eSIR_FAILURE; + } + vos_mem_set( ( tANI_U8* )frm, sizeof( *frm ), 0 ); + + frm->Category.category = SIR_MAC_ACTION_RRM; + frm->Action.action = SIR_MAC_RRM_RADIO_MEASURE_RPT; + frm->DialogToken.token = dialog_token; + + frm->num_MeasurementReport = (num_report > RADIO_REPORTS_MAX_IN_A_FRAME ) ? RADIO_REPORTS_MAX_IN_A_FRAME : num_report; + + for( i = 0 ; i < frm->num_MeasurementReport ; i++ ) + { + frm->MeasurementReport[i].type = pRRMReport[i].type; + frm->MeasurementReport[i].token = pRRMReport[i].token; + frm->MeasurementReport[i].late = 0; //IEEE 802.11k section 7.3.22. (always zero in rrm) + switch( pRRMReport[i].type ) + { + case SIR_MAC_RRM_BEACON_TYPE: + PopulateDot11fBeaconReport( pMac, &frm->MeasurementReport[i], &pRRMReport[i].report.beaconReport ); + frm->MeasurementReport[i].incapable = pRRMReport[i].incapable; + frm->MeasurementReport[i].refused = pRRMReport[i].refused; + frm->MeasurementReport[i].present = 1; + break; + default: + frm->MeasurementReport[i].incapable = pRRMReport[i].incapable; + frm->MeasurementReport[i].refused = pRRMReport[i].refused; + frm->MeasurementReport[i].present = 1; + break; + } + } + + nStatus = dot11fGetPackedRadioMeasurementReportSize( pMac, frm, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a Radio Measure Report (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fLinkMeasurementReport ); + vos_mem_free(frm); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for a Radio Measure Rep" + "ort (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( tANI_U16 )nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a Radio Measure " + "Report."), nBytes ); + vos_mem_free(frm); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + if( eSIR_SUCCESS != + (statusCode = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr))) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + +#ifdef WLAN_FEATURE_11W + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); +#endif + + // Now, we're ready to "pack" the frames + nStatus = dot11fPackRadioMeasurementReport( pMac, + frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an Radio Measure Report (0x%08x)." ), + nStatus ); + + // FIXME - Need to convert to tSirRetStatus + statusCode = eSIR_FAILURE; + goto returnAfterError; + } + else if( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing Radio " + "Measure Report (0x%08x)." ), nStatus); + } + + limLog( pMac, LOGW, + FL( "Sending a Radio Measure Report to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE) + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + statusCode = eSIR_FAILURE; + //Pkt will be freed up by the callback + vos_mem_free(frm); + return statusCode; + } + else { + vos_mem_free(frm); + return eSIR_SUCCESS; + } + +returnAfterError: + vos_mem_free(frm); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return statusCode; +} // End limSendBeaconReportActionFrame. + +#endif + +#ifdef WLAN_FEATURE_11W +/** + * \brief Send SA query request action frame to peer + * + * \sa limSendSaQueryRequestFrame + * + * + * \param pMac The global tpAniSirGlobal object + * + * \param transId Transaction identifier + * + * \param peer The Mac address of the station to which this action frame is addressed + * + * \param psessionEntry The PE session entry + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ + +tSirRetStatus limSendSaQueryRequestFrame( tpAniSirGlobal pMac, tANI_U8 *transId, + tSirMacAddr peer, tpPESession psessionEntry ) +{ + + tDot11fSaQueryReq frm; // SA query request action frame + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + frm.Category.category = SIR_MAC_ACTION_SA_QUERY; + /* 11w action field is : + action: 0 --> SA Query Request action frame + action: 1 --> SA Query Response action frame */ + frm.Action.action = SIR_MAC_SA_QUERY_REQ; + /* 11w SA Query Request transId */ + vos_mem_copy( &frm.TransactionId.transId[0], &transId[0], 2 ); + + nStatus = dot11fGetPackedSaQueryReqSize(pMac, &frm, &nPayload); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size " + "for an SA Query Request (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fSaQueryReq ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an SA Query Request" + " (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a SA Query Request " + "action frame"), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + nSirStatus = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr ); + if ( eSIR_SUCCESS != nSirStatus ) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + + // Since this is a SA Query Request, set the "protect" (aka WEP) bit + // in the FC + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); + + // Pack 11w SA Query Request frame + nStatus = dot11fPackSaQueryReq( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if ( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an SA Query Request (0x%08x)." ), + nStatus ); + // FIXME - Need to convert to tSirRetStatus + nSirStatus = eSIR_FAILURE; + goto returnAfterError; + } + else if ( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing SA Query Request (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOG1, + FL( "Sending an SA Query Request to " )); + limPrintMacAddr( pMac, peer, LOG1 ); + limPrintMacAddr( pMac, peer, LOGE ); + limLog( pMac, LOGE, + FL( "Sending an SA Query Request from " )); + limPrintMacAddr( pMac, psessionEntry->selfMacAddr, LOGE ); + + if ( ( SIR_BAND_5_GHZ == limGetRFBand( psessionEntry->currentOperChannel ) ) +#ifdef WLAN_FEATURE_P2P + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE ) +#endif + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pFrame, txFlag ); + if ( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + nSirStatus = eSIR_FAILURE; + //Pkt will be freed up by the callback + return nSirStatus; + } + else { + return eSIR_SUCCESS; + } + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; +} // End limSendSaQueryRequestFrame + +/** + * \brief Send SA query response action frame to peer + * + * \sa limSendSaQueryResponseFrame + * + * + * \param pMac The global tpAniSirGlobal object + * + * \param transId Transaction identifier received in SA query request action frame + * + * \param peer The Mac address of the AP to which this action frame is addressed + * + * \param psessionEntry The PE session entry + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ + +tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, tANI_U8 *transId, +tSirMacAddr peer,tpPESession psessionEntry) +{ + + tDot11fSaQueryRsp frm; // SA query reponse action frame + tANI_U8 *pFrame; + tSirRetStatus nSirStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 nBytes, nPayload, nStatus; + void *pPacket; + eHalStatus halstatus; + tANI_U32 txFlag = 0; + + vos_mem_set( ( tANI_U8* )&frm, sizeof( frm ), 0 ); + frm.Category.category = SIR_MAC_ACTION_SA_QUERY; + /*11w action field is : + action: 0 --> SA query request action frame + action: 1 --> SA query response action frame */ + frm.Action.action = SIR_MAC_SA_QUERY_RSP; + /*11w SA query response transId is same as + SA query request transId*/ + vos_mem_copy( &frm.TransactionId.transId[0], &transId[0], 2 ); + + nStatus = dot11fGetPackedSaQueryRspSize(pMac, &frm, &nPayload); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGP, FL("Failed to calculate the packed size f" + "or a SA Query Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fSaQueryRsp ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an SA Query Response" + " (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, nBytes, ( void** ) &pFrame, ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for a SA query response" + " action frame"), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Copy necessary info to BD + nSirStatus = limPopulateMacHeader( pMac, + pFrame, + SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, + peer, psessionEntry->selfMacAddr ); + if ( eSIR_SUCCESS != nSirStatus ) + goto returnAfterError; + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + + sirCopyMacAddr( pMacHdr->bssId, psessionEntry->bssId ); + + // Since this is a SA Query Response, set the "protect" (aka WEP) bit + // in the FC + limSetProtectedBit(pMac, psessionEntry, peer, pMacHdr); + + // Pack 11w SA query response frame + nStatus = dot11fPackSaQueryRsp( pMac, + &frm, + pFrame + sizeof( tSirMacMgmtHdr ), + nPayload, + &nPayload ); + + if ( DOT11F_FAILED( nStatus )) + { + limLog( pMac, LOGE, + FL( "Failed to pack an SA Query Response (0x%08x)." ), + nStatus ); + // FIXME - Need to convert to tSirRetStatus + nSirStatus = eSIR_FAILURE; + goto returnAfterError; + } + else if ( DOT11F_WARNED( nStatus )) + { + limLog( pMac, LOGW, + FL( "There were warnings while packing SA Query Response (0x%08x)." ), + nStatus); + } + + limLog( pMac, LOG1, + FL( "Sending a SA Query Response to " )); + limPrintMacAddr( pMac, peer, LOGW ); + + if ( ( SIR_BAND_5_GHZ == limGetRFBand( psessionEntry->currentOperChannel ) ) +#ifdef WLAN_FEATURE_P2P + || ( psessionEntry->pePersona == VOS_P2P_CLIENT_MODE ) || + ( psessionEntry->pePersona == VOS_P2P_GO_MODE ) +#endif + ) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + halstatus = halTxFrame( pMac, + pPacket, + (tANI_U16) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, + pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( eHAL_STATUS_SUCCESS != halstatus ) + { + PELOGE(limLog( pMac, LOGE, FL( "halTxFrame FAILED! Status [%d]" ), halstatus );) + nSirStatus = eSIR_FAILURE; + //Pkt will be freed up by the callback + return nSirStatus; + } + else { + return eSIR_SUCCESS; + } + +returnAfterError: + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; +} // End limSendSaQueryResponseFrame +#endif + +#ifdef WLAN_FEATURE_RMC +tSirRetStatus +limSendRMCActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirRMCInfo *pRMC, + tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U8 *pFrame; + tDot11fRMC RMC; + tANI_U32 nPayload, nBytes, nStatus; + tpSirMacMgmtHdr pMacHdr; + void *pPacket; + eHalStatus halstatus; + tANI_U8 txFlag = 0; + tANI_U8 MagicCode[] = { 0x4f, 0x58, 0x59, 0x47, 0x45, 0x4e }; + + if (NULL == psessionEntry) + { + return eSIR_FAILURE; + } + + vos_mem_set(( tANI_U8* )&RMC, sizeof( RMC ), 0); + + RMC.Action.action = pRMC->action; + RMC.RMCDialogToken.token = pRMC->dialogToken; + RMC.Category.category = SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY; + RMC.RMCVersion.version = SIR_MAC_RMC_VER; + + vos_mem_copy(&RMC.RMCOUI.oui, SIR_MAC_RMC_OUI, SIR_MAC_RMC_OUI_SIZE); + vos_mem_copy(&RMC.MagicCode.magic, MagicCode, sizeof(MagicCode)); + + vos_mem_copy(&RMC.Ruler.mac, pRMC->mcastRuler, sizeof(tSirMacAddr)); + + nStatus = dot11fGetPackedRMCSize( pMac, &RMC, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to calculate the packed size for " + "an RMC (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fRMC ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while calculating " + "the packed size for an RMC Action Frame" + " (0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + halstatus = palPktAlloc( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( tANI_U16 )nBytes, ( void** ) &pFrame, + ( void** ) &pPacket ); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGP, FL("Failed to allocate %d bytes for an RMC " + "Action Frame."), nBytes ); + return eSIR_FAILURE; + } + + // Paranoia: + vos_mem_set( pFrame, nBytes, 0 ); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_ACTION, peerMacAddr, + psessionEntry->selfMacAddr); + if ( eSIR_SUCCESS != nSirStatus ) + { + limLog( pMac, LOGE, FL("Failed to populate the buffer descriptor " + "for an RMC Action Frame (%d)."), + nSirStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, + ( void* ) pFrame, ( void* ) pPacket ); + return nSirStatus; + } + + // Update A3 with the BSSID + pMacHdr = ( tpSirMacMgmtHdr ) pFrame; + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + // That done, pack the struct: + nStatus = dot11fPackRMC( pMac, &RMC, + pFrame + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + limLog( pMac, LOGE, FL("Failed to pack an RMC " + "(0x%08x)."), + nStatus ); + palPktFree( pMac->hHdd, HAL_TXRX_FRM_802_11_MGMT, ( void* ) pFrame, + ( void* ) pPacket ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + limLog( pMac, LOGW, FL("There were warnings while packing " + "an RMC (0x%08x)."), nStatus ); + } + + limLog( pMac, LOG1, FL("Sending an RMC Action frame to " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(peerMacAddr)); + + /* + * With this masking, RMC action frames will be sent + * at self-sta rates for both 2G and 5G bands. + */ + txFlag |= HAL_USE_SELF_STA_REQUESTED_MASK; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_MGMT, + psessionEntry->peSessionId, + pMacHdr->fc.subType)); + // Queue RMC Action frame in high priority WQ + halstatus = halTxFrame( pMac, pPacket, ( tANI_U16 ) nBytes, + HAL_TXRX_FRM_802_11_MGMT, + ANI_TXDIR_TODS, + 7,//SMAC_SWBD_TX_TID_MGMT_HIGH, + limTxComplete, pFrame, txFlag ); + MTRACE(macTrace(pMac, TRACE_CODE_TX_COMPLETE, + psessionEntry->peSessionId, + halstatus)); + if ( ! HAL_STATUS_SUCCESS ( halstatus ) ) + { + limLog( pMac, LOGE, FL( "*** Could not send an RMC Action frame" + " (%X) ***" ), halstatus ); + //Pkt will be freed up by the callback + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End limSendRMCActionFrame. + +#endif /* WLAN_FEATURE_RMC */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.c new file mode 100644 index 000000000000..3f064aa30131 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.c @@ -0,0 +1,1010 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + + * + * limSendMessages.c: Provides functions to send messages or Indications to HAL. + * Author: Sunit Bhatia + * Date: 09/21/2006 + * History:- + * Date Modified by Modification Information + * + * -------------------------------------------------------------------------- + * + */ +#include "limSendMessages.h" +#include "cfgApi.h" +#include "limTrace.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT +/* When beacon filtering is enabled, firmware will + * analyze the selected beacons received during BMPS, + * and monitor any changes in the IEs as listed below. + * The format of the table is: + * - EID + * - Check for IE presence + * - Byte offset + * - Byte value + * - Bit Mask + * - Byte refrence + */ +static tBeaconFilterIe beaconFilterTable[] = { + {SIR_MAC_DS_PARAM_SET_EID, 0, {0, 0, DS_PARAM_CHANNEL_MASK, 0}}, + {SIR_MAC_ERP_INFO_EID, 0, {0, 0, ERP_FILTER_MASK, 0}}, + {SIR_MAC_EDCA_PARAM_SET_EID, 0, {0, 0, EDCA_FILTER_MASK, 0}}, + {SIR_MAC_QOS_CAPABILITY_EID, 0, {0, 0, QOS_FILTER_MASK, 0}}, + {SIR_MAC_CHNL_SWITCH_ANN_EID, 1, {0, 0, 0, 0}}, + {SIR_MAC_HT_INFO_EID, 0, {0, 0, HT_BYTE0_FILTER_MASK, 0}}, //primary channel + {SIR_MAC_HT_INFO_EID, 0, {1, 0, HT_BYTE1_FILTER_MASK, 0}}, //Secondary Channel + {SIR_MAC_HT_INFO_EID, 0, {2, 0, HT_BYTE2_FILTER_MASK, 0}}, //HT protection + {SIR_MAC_HT_INFO_EID, 0, {5, 0, HT_BYTE5_FILTER_MASK, 0}} +#if defined WLAN_FEATURE_VOWIFI + ,{SIR_MAC_PWR_CONSTRAINT_EID, 0, {0, 0, 0, 0}} +#endif +#ifdef WLAN_FEATURE_11AC + ,{SIR_MAC_VHT_OPMODE_EID, 0, {0, 0, 0, 0}} + ,{SIR_MAC_VHT_OPERATION_EID, 0, {0, 0, VHTOP_CHWIDTH_MASK, 0}} +#endif + ,{SIR_MAC_RSN_EID, 1, {0, 0, 0, 0}} + ,{SIR_MAC_WPA_EID, 1, {0, 0, 0, 0}} +}; + +/** + * limSendCFParams() + * + *FUNCTION: + * This function is called to send CFP Parameters to WDA, when they are changed. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param bssIdx Bss Index of the BSS to which STA is associated. + * @param cfpCount CFP Count, if that is changed. + * @param cfpPeriod CFP Period if that is changed. + * + * @return success if message send is ok, else false. + */ +tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod) +{ + tpUpdateCFParams pCFParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pCFParams = vos_mem_malloc(sizeof( tUpdateCFParams )); + if ( NULL == pCFParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update CF Params" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + vos_mem_set( (tANI_U8 *) pCFParams, sizeof(tUpdateCFParams), 0); + pCFParams->cfpCount = cfpCount; + pCFParams->cfpPeriod = cfpPeriod; + pCFParams->bssIdx = bssIdx; + + msgQ.type = WDA_UPDATE_CF_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pCFParams; + msgQ.bodyval = 0; + limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_CF_IND..." )); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pCFParams); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_CF_IND to WDA failed, reason=%X"), + retCode ); + } +returnFailure: + return retCode; +} + +/** + * limSendBeaconParams() + * + *FUNCTION: + * This function is called to send beacnon interval, short preamble or other + * parameters to WDA, which are changed and indication is received in beacon. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param tpUpdateBeaconParams pointer to the structure, + which contains the beacon parameters which are changed. + * + * @return success if message send is ok, else false. + */ +tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, + tpUpdateBeaconParams pUpdatedBcnParams, + tpPESession psessionEntry ) +{ + tpUpdateBeaconParams pBcnParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pBcnParams = vos_mem_malloc(sizeof(*pBcnParams)); + if ( NULL == pBcnParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update Beacon Params" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *) pBcnParams, pUpdatedBcnParams, sizeof(*pBcnParams)); + msgQ.type = WDA_UPDATE_BEACON_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pBcnParams; + msgQ.bodyval = 0; + PELOG3(limLog( pMac, LOG3, + FL( "Sending WDA_UPDATE_BEACON_IND, paramChangeBitmap in hex = %x" ), + pUpdatedBcnParams->paramChangeBitmap);) + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pBcnParams); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_BEACON_IND to WDA failed, reason=%X"), + retCode ); + } + limSendBeaconInd(pMac, psessionEntry); + return retCode; +} + +/** + * limSendSwitchChnlParams() + * + *FUNCTION: + * This function is called to send Channel Switch Indication to WDA + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param chnlNumber New Channel Number to be switched to. + * @param secondaryChnlOffset an enum for secondary channel offset. + * @param localPowerConstraint 11h local power constraint value + * + * @return success if message send is ok, else false. + */ +#if !defined WLAN_FEATURE_VOWIFI +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, + tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tANI_U8 localPwrConstraint, tANI_U8 peSessionId) +#else +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, + tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tPowerdBm maxTxPower, tANI_U8 peSessionId) +#endif +{ + tpSwitchChannelParams pChnlParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpPESession pSessionEntry; + if((pSessionEntry = peFindSessionBySessionId(pMac, peSessionId)) == NULL) + { + limLog( pMac, LOGP, + FL( "Unable to get Session for session Id %d" ), peSessionId); + return eSIR_FAILURE; + } + pChnlParams = vos_mem_malloc(sizeof( tSwitchChannelParams )); + if ( NULL == pChnlParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Switch Channel Params" )); + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + vos_mem_set((tANI_U8 *) pChnlParams, sizeof(tSwitchChannelParams), 0); + pChnlParams->secondaryChannelOffset = secondaryChnlOffset; + pChnlParams->channelNumber= chnlNumber; +#if defined WLAN_FEATURE_VOWIFI + pChnlParams->maxTxPower = maxTxPower; + vos_mem_copy( pChnlParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr) ); +#else + pChnlParams->localPowerConstraint = localPwrConstraint; +#endif + vos_mem_copy( pChnlParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr) ); + pChnlParams->peSessionId = peSessionId; + + if (LIM_SWITCH_CHANNEL_CSA == pSessionEntry->channelChangeCSA ) + { + pChnlParams->channelSwitchSrc = eHAL_CHANNEL_SWITCH_SOURCE_CSA; + pSessionEntry->channelChangeCSA = 0; + } + //we need to defer the message until we get the response back from WDA. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + msgQ.type = WDA_CHNL_SWITCH_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pChnlParams; + msgQ.bodyval = 0; +#if defined WLAN_FEATURE_VOWIFI + limLog( pMac, LOG1, + FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d," + " ChannelNumber - %d, maxTxPower - %d"), + pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, + pChnlParams->maxTxPower); +#else + limLog( pMac, LOG1, + FL( "Sending WDA_CHNL_SWITCH_REQ with SecondaryChnOffset - %d, " + "ChannelNumber - %d, LocalPowerConstraint - %d"), + pChnlParams->secondaryChannelOffset, pChnlParams->channelNumber, + pChnlParams->localPowerConstraint); +#endif + MTRACE(macTraceMsgTx(pMac, peSessionId, msgQ.type)); + limLog(pMac,LOG1,"SessionId:%d WDA_CHNL_SWITCH_REQ for SSID:%s",peSessionId, + pSessionEntry->ssId.ssId); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pChnlParams); + limLog( pMac, LOGP, + FL("Posting WDA_CHNL_SWITCH_REQ to WDA failed, reason=%X"), + retCode ); + } +returnFailure: + return retCode; +} + +/** + * limSendEdcaParams() + * + *FUNCTION: + * This function is called to send dynamically changing EDCA Parameters to WDA. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param tpUpdatedEdcaParams pointer to the structure which contains + * dynamically changing EDCA parameters. + * @param highPerformance If the peer is Airgo (taurus) then switch to highPerformance is true. + * + * @return success if message send is ok, else false. + */ +tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance) +{ + tEdcaParams *pEdcaParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pEdcaParams = vos_mem_malloc(sizeof(tEdcaParams)); + if ( NULL == pEdcaParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update EDCA Params" )); + retCode = eSIR_MEM_ALLOC_FAILED; + return retCode; + } + pEdcaParams->bssIdx = bssIdx; + pEdcaParams->acbe = pUpdatedEdcaParams[EDCA_AC_BE]; + pEdcaParams->acbk = pUpdatedEdcaParams[EDCA_AC_BK]; + pEdcaParams->acvi = pUpdatedEdcaParams[EDCA_AC_VI]; + pEdcaParams->acvo = pUpdatedEdcaParams[EDCA_AC_VO]; + pEdcaParams->highPerformance = highPerformance; + msgQ.type = WDA_UPDATE_EDCA_PROFILE_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pEdcaParams; + msgQ.bodyval = 0; + { + tANI_U8 i; + PELOG1(limLog( pMac, LOG1,FL("Sending WDA_UPDATE_EDCA_PROFILE_IND with EDCA Parameters:" ));) + for(i=0; igLimEdcaParamsActive[EDCA_AC_BE] = plocalEdcaParams[EDCA_AC_BE]; + psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK] = plocalEdcaParams[EDCA_AC_BK]; + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI] = plocalEdcaParams[EDCA_AC_VI]; + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO] = plocalEdcaParams[EDCA_AC_VO]; + /* An AC requires downgrade if the ACM bit is set, and the AC has not + * yet been admitted in uplink or bi-directions. + * If an AC requires downgrade, it will downgrade to the next beset AC + * for which ACM is not enabled. + * + * - There's no need to downgrade AC_BE since it IS the lowest AC. Hence + * start the for loop with AC_BK. + * - If ACM bit is set for an AC, initially downgrade it to AC_BE. Then + * traverse thru the AC list. If we do find the next best AC which is + * better than AC_BE, then use that one. For example, if ACM bits are set + * such that: BE_ACM=1, BK_ACM=1, VI_ACM=1, VO_ACM=0 + * then all AC will be downgraded to AC_BE. + */ + limLog(pMac, LOG1, FL("adAdmitMask[UPLINK] = 0x%x "), pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] ); + limLog(pMac, LOG1, FL("adAdmitMask[DOWNLINK] = 0x%x "), pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] ); + for (ac = EDCA_AC_BK; ac <= EDCA_AC_VO; ac++) + { + acAdmitted = ( (pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & (1 << ac)) >> ac ); + limLog(pMac, LOG1, FL("For AC[%d]: acm=%d, acAdmit=%d "), ac, plocalEdcaParams[ac].aci.acm, acAdmitted); + if ( (plocalEdcaParams[ac].aci.acm == 1) && (acAdmitted == 0) ) + { + limLog(pMac, LOG1, FL("We need to downgrade AC %d!! "), ac); + newAc = EDCA_AC_BE; + for (i=ac-1; i>0; i--) + { + if (plocalEdcaParams[i].aci.acm == 0) + { + newAc = i; + break; + } + } + limLog(pMac, LOGW, FL("Downgrading AC %d ---> AC %d "), ac, newAc); + psessionEntry->gLimEdcaParamsActive[ac] = plocalEdcaParams[newAc]; + } + } +//log: LOG_WLAN_QOS_EDCA_C +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C); + if(log_ptr) + { + log_ptr->aci_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].aci.aci; + log_ptr->cw_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].cw.min; + log_ptr->txoplimit_be = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BE].txoplimit; + log_ptr->aci_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].aci.aci; + log_ptr->cw_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].cw.min; + log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParamsActive[EDCA_AC_BK].txoplimit; + log_ptr->aci_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].aci.aci; + log_ptr->cw_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].cw.min; + log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VI].txoplimit; + log_ptr->aci_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].aci.aci; + log_ptr->cw_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.max << 4 | + psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].cw.min; + log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParamsActive[EDCA_AC_VO].txoplimit; + } + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + return; + } + +/** --------------------------------------------------------- +\fn limSetLinkState +\brief LIM sends a message to WDA to set the link state +\param tpAniSirGlobal pMac +\param tSirLinkState state +\return None + -----------------------------------------------------------*/ + //Original code with out anu's change +#if 0 +tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId) +{ + tSirMsgQ msg; + tSirRetStatus retCode; + msg.type = WDA_SET_LINK_STATE; + msg.bodyval = (tANI_U32) state; + msg.bodyptr = NULL; + MTRACE(macTraceMsgTx(pMac, 0, msg.type)); + retCode = wdaPostCtrlMsg(pMac, &msg); + if (retCode != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "), retCode); + return retCode; +} +#endif //0 +tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state,tSirMacAddr bssId, + tSirMacAddr selfMacAddr, tpSetLinkStateCallback callback, + void *callbackArg) +{ + tSirMsgQ msgQ; + tSirRetStatus retCode; + tpLinkStateParams pLinkStateParams = NULL; + // Allocate memory. + pLinkStateParams = vos_mem_malloc(sizeof(tLinkStateParams)); + if ( NULL == pLinkStateParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory while sending Set Link State" )); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + return retCode; + } + vos_mem_set((tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams), 0); + pLinkStateParams->state = state; + pLinkStateParams->callback = callback; + pLinkStateParams->callbackArg = callbackArg; + + /* Copy Mac address */ + sirCopyMacAddr(pLinkStateParams->bssid,bssId); + sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr); + + msgQ.type = WDA_SET_LINK_STATE; + msgQ.reserved = 0; + msgQ.bodyptr = pLinkStateParams; + msgQ.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + + retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ); + if (retCode != eSIR_SUCCESS) + { + vos_mem_free(pLinkStateParams); + limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "), + state, retCode); + } + return retCode; +} +#ifdef WLAN_FEATURE_VOWIFI_11R +extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState +state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tSirRetStatus retCode; + tpLinkStateParams pLinkStateParams = NULL; + // Allocate memory. + pLinkStateParams = vos_mem_malloc(sizeof(tLinkStateParams)); + if ( NULL == pLinkStateParams ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory while sending Set Link State" )); + retCode = eSIR_SME_RESOURCES_UNAVAILABLE; + return retCode; + } + vos_mem_set((tANI_U8 *) pLinkStateParams, sizeof(tLinkStateParams), 0); + pLinkStateParams->state = state; + /* Copy Mac address */ + sirCopyMacAddr(pLinkStateParams->bssid,bssId); + sirCopyMacAddr(pLinkStateParams->selfMacAddr, selfMacAddr); + pLinkStateParams->ft = 1; + pLinkStateParams->session = psessionEntry; + + msgQ.type = WDA_SET_LINK_STATE; + msgQ.reserved = 0; + msgQ.bodyptr = pLinkStateParams; + msgQ.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + + retCode = (tANI_U32)wdaPostCtrlMsg(pMac, &msgQ); + if (retCode != eSIR_SUCCESS) + { + vos_mem_free(pLinkStateParams); + limLog(pMac, LOGP, FL("Posting link state %d failed, reason = %x "), + state, retCode); + } + return retCode; +} +#endif + +/** --------------------------------------------------------- +\fn limSendSetTxPowerReq +\brief LIM sends a WDA_SET_TX_POWER_REQ message to WDA +\param tpAniSirGlobal pMac +\param tpSirSetTxPowerReq request message +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) +{ + tSirSetTxPowerReq *txPowerReq; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpPESession psessionEntry; + tANI_U8 sessionId = 0; + + if (NULL == pMsgBuf) + return eSIR_FAILURE; + + txPowerReq = vos_mem_malloc(sizeof(tSirSetTxPowerReq)); + if ( NULL == txPowerReq ) + { + return eSIR_FAILURE; + } + vos_mem_copy(txPowerReq, (tSirSetTxPowerReq *)pMsgBuf, sizeof(tSirSetTxPowerReq)); + + /* Found corresponding seesion to find BSS IDX */ + psessionEntry = peFindSessionByBssid(pMac, txPowerReq->bssId, &sessionId); + if (NULL == psessionEntry) + { + vos_mem_free(txPowerReq); + limLog(pMac, LOGE, FL("Session does not exist for given BSSID")); + return eSIR_FAILURE; + } + + /* FW API requests BSS IDX */ + txPowerReq->bssIdx = psessionEntry->bssIdx; + + msgQ.type = WDA_SET_TX_POWER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = txPowerReq; + msgQ.bodyval = 0; + PELOGW(limLog(pMac, LOGW, FL("Sending WDA_SET_TX_POWER_REQ to WDA"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + limLog(pMac, LOGP, FL("Posting WDA_SET_TX_POWER_REQ to WDA failed, reason=%X"), retCode); + vos_mem_free(txPowerReq); + return retCode; + } + return retCode; +} + +/** --------------------------------------------------------- +\fn limSendHT40OBSSScanInd +\brief LIM sends a WDA_HT40_OBSS_SCAN_IND message to WDA +\param tpAniSirGlobal pMac +\param psessionEntry session Entry +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendHT40OBSSScanInd(tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirHT40OBSSScanInd *ht40OBSSScanInd; + tANI_U32 validChannelNum; + tSirMsgQ msgQ; + tANI_U8 validChanList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 channel24GNum, count; + + ht40OBSSScanInd = vos_mem_malloc(sizeof(tSirHT40OBSSScanInd)); + if ( NULL == ht40OBSSScanInd) + { + return eSIR_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + "OBSS Scan Indication bssIdx- %d staId %d", + psessionEntry->bssIdx, psessionEntry->staId); + + ht40OBSSScanInd->cmdType = HT40_OBSS_SCAN_PARAM_START; + ht40OBSSScanInd->scanType = eSIR_ACTIVE_SCAN; + ht40OBSSScanInd->OBSSScanPassiveDwellTime = + psessionEntry->obssHT40ScanParam.OBSSScanPassiveDwellTime; + ht40OBSSScanInd->OBSSScanActiveDwellTime = + psessionEntry->obssHT40ScanParam.OBSSScanActiveDwellTime; + ht40OBSSScanInd->BSSChannelWidthTriggerScanInterval = + psessionEntry->obssHT40ScanParam.BSSChannelWidthTriggerScanInterval; + ht40OBSSScanInd->OBSSScanPassiveTotalPerChannel = + psessionEntry->obssHT40ScanParam.OBSSScanPassiveTotalPerChannel; + ht40OBSSScanInd->OBSSScanActiveTotalPerChannel = + psessionEntry->obssHT40ScanParam.OBSSScanActiveTotalPerChannel; + ht40OBSSScanInd->BSSWidthChannelTransitionDelayFactor = + psessionEntry->obssHT40ScanParam.BSSWidthChannelTransitionDelayFactor; + ht40OBSSScanInd->OBSSScanActivityThreshold = + psessionEntry->obssHT40ScanParam.OBSSScanActivityThreshold; + /* TODO update it from the associated BSS*/ + ht40OBSSScanInd->currentOperatingClass = 81; + + validChannelNum = WNI_CFG_VALID_CHANNEL_LIST_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + validChanList, + &validChannelNum) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("could not retrieve Valid channel list")); + vos_mem_free(ht40OBSSScanInd); + return eSIR_FAILURE; + } + /* Extract 24G channel list */ + channel24GNum = 0; + for( count =0 ;count < validChannelNum && + (channel24GNum < SIR_ROAM_MAX_CHANNELS);count++) + { + if ((validChanList[count]> RF_CHAN_1) && + (validChanList[count] < RF_CHAN_14)) + { + ht40OBSSScanInd->channels[channel24GNum] = validChanList[count]; + channel24GNum++; + } + } + ht40OBSSScanInd->channelCount = channel24GNum; + /* FW API requests BSS IDX */ + ht40OBSSScanInd->selfStaIdx = psessionEntry->staId; + ht40OBSSScanInd->bssIdx = psessionEntry->bssIdx; + ht40OBSSScanInd->fortyMHZIntolerent = 0; + ht40OBSSScanInd->ieFieldLen = 0; + + msgQ.type = WDA_HT40_OBSS_SCAN_IND; + msgQ.reserved = 0; + msgQ.bodyptr = (void *)ht40OBSSScanInd; + msgQ.bodyval = 0; + limLog(pMac, LOG1, FL("Sending WDA_HT40_OBSS_SCAN_IND to WDA" + "Obss Scan trigger width = %d, delay factor = %d"), + ht40OBSSScanInd->BSSChannelWidthTriggerScanInterval, + ht40OBSSScanInd->BSSWidthChannelTransitionDelayFactor); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + limLog(pMac, LOGP, FL("Posting WDA_HT40_OBSS_SCAN_IND " + "to WDA failed, reason=%X"), retCode); + vos_mem_free(ht40OBSSScanInd); + return retCode; + } + return retCode; +} +/** --------------------------------------------------------- +\fn limSendHT40OBSSScanInd +\brief LIM sends a WDA_HT40_OBSS_SCAN_IND message to WDA +\ Stop command support is only for debugging +\ As per 802.11 spec OBSS scan is mandatory while +\ operating in HT40 on 2.4GHz band +\param tpAniSirGlobal pMac +\param psessionEntry Session entry +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendHT40OBSSStopScanInd(tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tANI_U8 bssIdx; + + bssIdx = psessionEntry->bssIdx; + + VOS_TRACE (VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_INFO, + " Sending STOP OBSS cmd, bssid %d staid %d ", + psessionEntry->bssIdx, psessionEntry->staId); + + msgQ.type = WDA_HT40_OBSS_STOP_SCAN_IND; + msgQ.reserved = 0; + msgQ.bodyptr = (void *)&bssIdx; + msgQ.bodyval = 0; + PELOGW(limLog(pMac, LOGW, + FL("Sending WDA_HT40_OBSS_STOP_SCAN_IND to WDA"));) + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + limLog(pMac, LOGE, FL("Posting WDA_HT40_OBSS_SCAN_IND " + "to WDA failed, reason=%X"), retCode); + return retCode; + } + + return retCode; +} +/** --------------------------------------------------------- +\fn limSendGetTxPowerReq +\brief LIM sends a WDA_GET_TX_POWER_REQ message to WDA +\param tpAniSirGlobal pMac +\param tpSirGetTxPowerReq request message +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac, tpSirGetTxPowerReq pTxPowerReq) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + if (NULL == pTxPowerReq) + return retCode; + msgQ.type = WDA_GET_TX_POWER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pTxPowerReq; + msgQ.bodyval = 0; + PELOGW(limLog(pMac, LOGW, FL( "Sending WDA_GET_TX_POWER_REQ to WDA"));) + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGP, FL("Posting WDA_GET_TX_POWER_REQ to WDA failed, reason=%X"), retCode ); + if (NULL != pTxPowerReq) + { + vos_mem_free(pTxPowerReq); + } + return retCode; + } + return retCode; +} +/** --------------------------------------------------------- +\fn limSendBeaconFilterInfo +\brief LIM sends beacon filtering info to WDA +\param tpAniSirGlobal pMac +\return None + -----------------------------------------------------------*/ +tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tpBeaconFilterMsg pBeaconFilterMsg = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tANI_U8 *ptr; + tANI_U32 i; + tANI_U32 msgSize; + tANI_BOOLEAN ignore_secchannel_bcn_filter = false; + bool filter_skipped = false; + tpBeaconFilterIe pIe; + tpDphHashNode pStaDs; + + if( psessionEntry == NULL ) + { + limLog( pMac, LOGE, FL("Fail to find the right session ")); + retCode = eSIR_FAILURE; + return retCode; + } + /* + * Dont send the WPA and RSN iE in filter if FW doesnt support + * IS_FEATURE_BCN_FLT_DELTA_ENABLE, + * else host will get all beacons which have RSN IE or WPA IE + */ + if(IS_FEATURE_BCN_FLT_DELTA_ENABLE) + msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable); + else + msgSize = sizeof(tBeaconFilterMsg) + sizeof(beaconFilterTable) - (2 * sizeof(tBeaconFilterIe)); + + pBeaconFilterMsg = vos_mem_malloc(msgSize); + if ( NULL == pBeaconFilterMsg ) + { + limLog( pMac, LOGP, FL("Fail to allocate memory for beaconFiilterMsg ")); + retCode = eSIR_MEM_ALLOC_FAILED; + return retCode; + } + vos_mem_set((tANI_U8 *) pBeaconFilterMsg, msgSize, 0); + // Fill in capability Info and mask + //TBD-RAJESH get the BSS capability from session. + //Don't send this message if no active Infra session is found. + pBeaconFilterMsg->capabilityInfo = psessionEntry->limCurrentBssCaps; + pBeaconFilterMsg->capabilityMask = CAPABILITY_FILTER_MASK; + pBeaconFilterMsg->beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval; + // Fill in number of IEs in beaconFilterTable + /* + * Dont send the WPA and RSN iE in filter if FW doesnt support + * IS_FEATURE_BCN_FLT_DELTA_ENABLE, + * else host will get all beacons which have RSN IE or WPA IE + */ + if(IS_FEATURE_BCN_FLT_DELTA_ENABLE) + pBeaconFilterMsg->ieNum = (tANI_U16) (sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe)); + else + pBeaconFilterMsg->ieNum = (tANI_U16) ((sizeof(beaconFilterTable) / sizeof(tBeaconFilterIe)) - 2); + + //Fill the BSSIDX + pBeaconFilterMsg->bssIdx = psessionEntry->bssIdx; + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, + &psessionEntry->dph.dphHashTable); + if((psessionEntry->currentOperChannel <= RF_CHAN_14) && + ((psessionEntry->htSupportedChannelWidthSet == + eHT_CHANNEL_WIDTH_20MHZ) || + (pStaDs != NULL && (pStaDs->htSupportedChannelWidthSet == + eHT_CHANNEL_WIDTH_20MHZ)))) + { + ignore_secchannel_bcn_filter = true; + } + + //Fill message with info contained in the beaconFilterTable + ptr = (tANI_U8 *)pBeaconFilterMsg + sizeof(tBeaconFilterMsg); + for(i=0; i < (pBeaconFilterMsg->ieNum); i++) + { + /* + *Interoperability workaround: TP-LINK TL-WDR6300 + *The value of Secondary Channel Offset in HT Operation element + *of beacon frame switching between 1 and 0, which causes dut(sta) + *to wake up frequently. + */ + if((ignore_secchannel_bcn_filter == true) && + (beaconFilterTable[i].elementId == SIR_MAC_HT_INFO_EID) && + (beaconFilterTable[i].byte.offset == 1) && + (beaconFilterTable[i].byte.bitMask == HT_BYTE1_FILTER_MASK)) + { + limLog( pMac, LOGW, + FL("Skip Secondary Channel bcn filter when channel is 20Mhz")); + filter_skipped = true; + continue; + } + pIe = (tpBeaconFilterIe) ptr; + pIe->elementId = beaconFilterTable[i].elementId; + pIe->checkIePresence = beaconFilterTable[i].checkIePresence; + pIe->byte.offset = beaconFilterTable[i].byte.offset; + pIe->byte.value = beaconFilterTable[i].byte.value; + pIe->byte.bitMask = beaconFilterTable[i].byte.bitMask; + pIe->byte.ref = beaconFilterTable[i].byte.ref; + ptr += sizeof(tBeaconFilterIe); + } + if (filter_skipped) + pBeaconFilterMsg->ieNum--; + + msgQ.type = WDA_BEACON_FILTER_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pBeaconFilterMsg; + msgQ.bodyval = 0; + limLog( pMac, LOG3, FL( "Sending WDA_BEACON_FILTER_IND..." )); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pBeaconFilterMsg); + limLog( pMac, LOGP, + FL("Posting WDA_BEACON_FILTER_IND to WDA failed, reason=%X"), + retCode ); + return retCode; + } + return retCode; +} + +/** + * \brief Send CB mode update to WDA + * + * \param pMac Pointer to the global MAC structure + * + * \param psessionEntry session entry + * pTempParam CB mode + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + */ +tSirRetStatus limSendModeUpdate(tpAniSirGlobal pMac, + tUpdateVHTOpMode *pTempParam, + tpPESession psessionEntry ) +{ + tUpdateVHTOpMode *pVhtOpMode = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pVhtOpMode = vos_mem_malloc(sizeof(tUpdateVHTOpMode)); + if ( NULL == pVhtOpMode ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Update Op Mode" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_copy((tANI_U8 *)pVhtOpMode, pTempParam, sizeof(tUpdateVHTOpMode)); + msgQ.type = WDA_UPDATE_OP_MODE; + msgQ.reserved = 0; + msgQ.bodyptr = pVhtOpMode; + msgQ.bodyval = 0; + limLog( pMac, LOG1, + FL( "Sending WDA_UPDATE_OP_MODE, opMode = %d staid = %d" ), + pVhtOpMode->opMode,pVhtOpMode->staId); + if(NULL == psessionEntry) + { + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + } + else + { + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + } + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pVhtOpMode); + limLog( pMac, LOGP, + FL("Posting WDA_UPDATE_OP_MODE to WDA failed, reason=%X"), + retCode ); + } + + return retCode; +} + +#ifdef WLAN_FEATURE_11W +/** --------------------------------------------------------- +\fn limSendExcludeUnencryptInd +\brief LIM sends a message to HAL to indicate whether to + ignore or indicate the unprotected packet error +\param tpAniSirGlobal pMac +\param tANI_BOOLEAN excludeUnenc - true: ignore, false: + indicate +\param tpPESession psessionEntry - session context +\return status + -----------------------------------------------------------*/ +tSirRetStatus limSendExcludeUnencryptInd(tpAniSirGlobal pMac, + tANI_BOOLEAN excludeUnenc, + tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tSirWlanExcludeUnencryptParam * pExcludeUnencryptParam; + + pExcludeUnencryptParam = vos_mem_malloc(sizeof(tSirWlanExcludeUnencryptParam)); + if ( NULL == pExcludeUnencryptParam ) + { + limLog(pMac, LOGP, + FL( "Unable to allocate memory during limSendExcludeUnencryptInd")); + return eSIR_MEM_ALLOC_FAILED; + } + + pExcludeUnencryptParam->excludeUnencrypt = excludeUnenc; + sirCopyMacAddr(pExcludeUnencryptParam->bssId, psessionEntry->bssId); + + msgQ.type = WDA_EXCLUDE_UNENCRYPTED_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pExcludeUnencryptParam; + msgQ.bodyval = 0; + limLog(pMac, LOG1, + FL("Sending WDA_EXCLUDE_UNENCRYPTED_IND")); + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if (eSIR_SUCCESS != retCode) + { + vos_mem_free(pExcludeUnencryptParam); + limLog(pMac, LOGP, + FL("Posting WDA_EXCLUDE_UNENCRYPTED_IND to WDA failed, reason=%X"), + retCode); + } + + return retCode; +} +#endif + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.h new file mode 100644 index 000000000000..645cc866ad8e --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendMessages.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * limSendMessages.h: Provides functions to send messages or Indications to HAL. + * Author: Sunit Bhatia + * Date: 09/21/2006 + * History:- + * Date Modified by Modification Information + * + * -------------------------------------------------------------------------- + * + */ +#ifndef __LIM_SEND_MESSAGES_H +#define __LIM_SEND_MESSAGES_H + +#include "aniGlobal.h" +#include "limTypes.h" +#include "halMsgApi.h" +#include "sirParams.h" +tSirRetStatus limSendCFParams(tpAniSirGlobal pMac, tANI_U8 bssIdx, tANI_U8 cfpCount, tANI_U8 cfpPeriod); +tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, + tpUpdateBeaconParams pUpdatedBcnParams, + tpPESession psessionEntry ); +//tSirRetStatus limSendBeaconParams(tpAniSirGlobal pMac, tpUpdateBeaconParams pUpdatedBcnParams); +tSirRetStatus limSendModeUpdate(tpAniSirGlobal pMac, + tUpdateVHTOpMode *tempParam, + tpPESession psessionEntry ); + +#ifdef WLAN_FEATURE_11AC +tANI_U32 limGetCenterChannel(tpAniSirGlobal pMac, + tANI_U8 primarychanNum, + ePhyChanBondState secondaryChanOffset, + tANI_U8 chanWidth); +#endif +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tPowerdBm maxTxPower,tANI_U8 peSessionId); +#else +tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, tANI_U8 chnlNumber, + ePhyChanBondState secondaryChnlOffset, + tANI_U8 localPwrConstraint,tANI_U8 peSessionId); +#endif +tSirRetStatus limSendEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *pUpdatedEdcaParams, tANI_U16 bssIdx, tANI_BOOLEAN highPerformance); +tSirRetStatus limSetLinkState(tpAniSirGlobal pMac, tSirLinkState state, tSirMacAddr bssId, + tSirMacAddr selfMac, tpSetLinkStateCallback callback, + void *callbackArg); +#ifdef WLAN_FEATURE_VOWIFI_11R +extern tSirRetStatus limSetLinkStateFT(tpAniSirGlobal pMac, tSirLinkState +state,tSirMacAddr bssId, tSirMacAddr selfMacAddr, int ft, tpPESession psessionEntry); +#endif +tSirRetStatus limSendSetTxPowerReq(tpAniSirGlobal pMac, tANI_U32 *pTxPowerReq); +tSirRetStatus limSendGetTxPowerReq(tpAniSirGlobal pMac, tpSirGetTxPowerReq pTxPowerReq); +void limSetActiveEdcaParams(tpAniSirGlobal pMac, tSirMacEdcaParamRecord *plocalEdcaParams, tpPESession psessionEntry); +tSirRetStatus limSendHT40OBSSScanInd(tpAniSirGlobal pMac, + tpPESession psessionEntry); +tSirRetStatus limSendHT40OBSSStopScanInd(tpAniSirGlobal pMac, + tpPESession psessionEntry); + +#define CAPABILITY_FILTER_MASK 0x73CF +#define ERP_FILTER_MASK 0xF8 +#define EDCA_FILTER_MASK 0xF0 +#define QOS_FILTER_MASK 0xF0 +#define HT_BYTE0_FILTER_MASK 0x0 +#define HT_BYTE1_FILTER_MASK 0xF8 +#define HT_BYTE2_FILTER_MASK 0xEB +#define HT_BYTE5_FILTER_MASK 0xFD +#define DS_PARAM_CHANNEL_MASK 0x0 +#define VHTOP_CHWIDTH_MASK 0xFC + +tSirRetStatus limSendBeaconFilterInfo(tpAniSirGlobal pMac, tpPESession psessionEntry); + +#ifdef WLAN_FEATURE_11W +tSirRetStatus limSendExcludeUnencryptInd(tpAniSirGlobal pMac, + tANI_BOOLEAN excludeUnenc, + tpPESession psessionEntry ); +#endif +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c new file mode 100644 index 000000000000..69d186eedd67 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c @@ -0,0 +1,2993 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limSendSmeRspMessages.cc contains the functions + * for sending SME response/notification messages to applications + * above MAC software. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "vos_types.h" +#include "wniApi.h" +#include "sirCommon.h" +#include "aniGlobal.h" + +#include "wniCfg.h" +#include "sysDef.h" +#include "cfgApi.h" + + +#include "schApi.h" +#include "utilsApi.h" +#include "limUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" +#include "limSendSmeRspMessages.h" +#include "limIbssPeerMgmt.h" +#include "limSessionUtils.h" +#include "lim_mbb.h" + +/** + * limSendSmeRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_START_RSP, eWNI_SME_MEASUREMENT_RSP, eWNI_SME_STOP_BSS_RSP + * or eWNI_SME_SWITCH_CHL_RSP messages to applications above MAC + * Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates message type + * @param resultCode Indicates the result of previously issued + * eWNI_SME_msgType_REQ message + * + * @return None + */ + +void +limSendSmeRsp(tpAniSirGlobal pMac, tANI_U16 msgType, + tSirResultCodes resultCode,tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tSirMsgQ mmhMsg; + tSirSmeRsp *pSirSmeRsp; + + PELOG1(limLog(pMac, LOG1, + FL("Sending message %s with reasonCode %s"), + limMsgStr(msgType), limResultCodeStr(resultCode));) + + pSirSmeRsp = vos_mem_malloc(sizeof(tSirSmeRsp)); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_*_RSP")); + + return; + } + + pSirSmeRsp->messageType = msgType; + pSirSmeRsp->length = sizeof(tSirSmeRsp); + pSirSmeRsp->statusCode = resultCode; + + /* Update SME session Id and Transaction Id */ + pSirSmeRsp->sessionId = smesessionId; + pSirSmeRsp->transactionId = smetransactionId; + + + mmhMsg.type = msgType; + mmhMsg.bodyptr = pSirSmeRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, smesessionId, mmhMsg.type)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + { + tpPESession psessionEntry = peGetValidPowerSaveSession(pMac); + switch(msgType) + { + case eWNI_PMC_ENTER_BMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_BMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_ENTER_IMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_IMPS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_ENTER_UAPSD_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_UAPSD_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_SME_SWITCH_CHL_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT, NULL, (tANI_U16)resultCode, 0); + break; + case eWNI_SME_STOP_BSS_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_STOP_BSS_RSP_EVENT, NULL, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_ENTER_WOWL_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + case eWNI_PMC_EXIT_WOWL_RSP: + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + break; + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeRsp() ***/ + +/** + * lim_add_bss_info() - copy data from session entry to join rsp + * @session_entry: PE Session Info + * @sme_join_rsp: Join response buffer to be filled up + * + * Return: None + */ +void lim_add_bss_info(tpDphHashNode sta_ds, + tpSirSmeJoinRsp sme_join_rsp) +{ + struct parsed_ies *parsed_ies = &sta_ds->parsed_ies; + + if (parsed_ies->hs20vendor_ie.present) + sme_join_rsp->hs20vendor_ie = parsed_ies->hs20vendor_ie; + if (parsed_ies->vht_caps.present) + sme_join_rsp->vht_caps = parsed_ies->vht_caps; + if (parsed_ies->ht_caps.present) + sme_join_rsp->ht_caps = parsed_ies->ht_caps; + if (parsed_ies->ht_operation.present) + sme_join_rsp->ht_operation = parsed_ies->ht_operation; + if (parsed_ies->vht_operation.present) + sme_join_rsp->vht_operation = parsed_ies->vht_operation; +} + +/** + * limSendSmeJoinReassocRspAfterResume() + * + *FUNCTION: + * This function is called to send Join/Reassoc rsp + * message to SME after the resume link. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param status Resume link status + * @param ctx context passed while calling resmune link. + * (join response to be sent) + * + * @return None + */ +static void limSendSmeJoinReassocRspAfterResume( tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *ctx) +{ + tSirMsgQ mmhMsg; + tpSirSmeJoinRsp pSirSmeJoinRsp = (tpSirSmeJoinRsp) ctx; + + mmhMsg.type = pSirSmeJoinRsp->messageType; + mmhMsg.bodyptr = pSirSmeJoinRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +/** + * limGetMaxRateFlags() + * + *FUNCTION: + *This function is called by limSendSmeJoinReassocRsp get rateFlags. + *These rateflags are used when MAX link-speed need to be reported + *to UI. + * + *PARAMS: + * @param pStaDs - Pointer to internal STA Datastructure + * @param psessionEntry - Pointer to the session entry + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @return rateFlags + */ +tANI_U32 limGetMaxRateFlags(tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tANI_U32 rate_flags = 0; + + if (NULL == psessionEntry) + { + return rate_flags; + } + + if(!IS_DOT11_MODE_HT(psessionEntry->dot11mode) && + !IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) + { + rate_flags |= eHAL_TX_RATE_LEGACY; + } + else + { + if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) +#ifdef WLAN_FEATURE_11AC + || IS_DOT11_MODE_VHT(psessionEntry->dot11mode) + ) +#endif + { + if (pStaDs->htShortGI20Mhz || pStaDs->htShortGI40Mhz) + rate_flags |= eHAL_TX_RATE_SGI; + } + +#ifdef WLAN_FEATURE_11AC + if(IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) + { + if (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ == + pStaDs->vhtSupportedChannelWidthSet) + { + rate_flags |= eHAL_TX_RATE_VHT80; + } + else if(WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ == + pStaDs->vhtSupportedChannelWidthSet) + { + if (eHT_CHANNEL_WIDTH_40MHZ == + pStaDs->htSupportedChannelWidthSet) + rate_flags |= eHAL_TX_RATE_VHT40; + else + rate_flags |= eHAL_TX_RATE_VHT20; + } + } + else +#endif + if(IS_DOT11_MODE_HT(psessionEntry->dot11mode)) + { + if (pStaDs->htSupportedChannelWidthSet) + rate_flags |=eHAL_TX_RATE_HT40; + else + rate_flags |=eHAL_TX_RATE_HT20; + } + } + + return rate_flags; +} + +/** + * limSendSmeJoinReassocRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_JOIN_RSP or eWNI_SME_REASSOC_RSP messages to applications + * above MAC Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates message type + * @param resultCode Indicates the result of previously issued + * eWNI_SME_msgType_REQ message + * + * @return None + */ + +void +limSendSmeJoinReassocRsp(tpAniSirGlobal pMac, tANI_U16 msgType, + tSirResultCodes resultCode, tANI_U16 protStatusCode, + tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + tpSirSmeJoinRsp pSirSmeJoinRsp; + tANI_U32 rspLen; + tpDphHashNode pStaDs = NULL; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + if (msgType == eWNI_SME_REASSOC_RSP) + limDiagEventReport(pMac, WLAN_PE_DIAG_REASSOC_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); + else + limDiagEventReport(pMac, WLAN_PE_DIAG_JOIN_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limLog(pMac, LOG1, + FL("Sending message %s with reasonCode %s"), + limMsgStr(msgType), limResultCodeStr(resultCode)); + + if(psessionEntry == NULL) + { + + rspLen = sizeof(tSirSmeJoinRsp); + + pSirSmeJoinRsp = vos_mem_malloc(rspLen); + if ( NULL == pSirSmeJoinRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for JOIN/REASSOC_RSP")); + return; + } + + vos_mem_set((tANI_U8*)pSirSmeJoinRsp, rspLen, 0); + + + pSirSmeJoinRsp->beaconLength = 0; + pSirSmeJoinRsp->assocReqLength = 0; + pSirSmeJoinRsp->assocRspLength = 0; + } + + else + { + rspLen = psessionEntry->assocReqLen + psessionEntry->assocRspLen + + psessionEntry->bcnLen + +#ifdef WLAN_FEATURE_VOWIFI_11R + psessionEntry->RICDataLen + +#endif +#ifdef FEATURE_WLAN_ESE + psessionEntry->tspecLen + +#endif + sizeof(tSirSmeJoinRsp) - sizeof(tANI_U8) ; + + pSirSmeJoinRsp = vos_mem_malloc(rspLen); + if ( NULL == pSirSmeJoinRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for JOIN/REASSOC_RSP")); + + return; + } + + vos_mem_set((tANI_U8*)pSirSmeJoinRsp, rspLen, 0); + + if (resultCode == eSIR_SME_SUCCESS) + { + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("could not Get Self Entry for the station"));) + } + else + { + //Pass the peer's staId + pSirSmeJoinRsp->staId = pStaDs->staIndex; + pSirSmeJoinRsp->ucastSig = pStaDs->ucUcastSig; + pSirSmeJoinRsp->bcastSig = pStaDs->ucBcastSig; + pSirSmeJoinRsp->maxRateFlags = + limGetMaxRateFlags(pStaDs, psessionEntry); + lim_add_bss_info(pStaDs, pSirSmeJoinRsp); + PELOGE(limLog(pMac, LOG1, FL("maxRateFlags: %x"), + pSirSmeJoinRsp->maxRateFlags);) + } + } + + pSirSmeJoinRsp->beaconLength = 0; + pSirSmeJoinRsp->assocReqLength = 0; + pSirSmeJoinRsp->assocRspLength = 0; +#ifdef WLAN_FEATURE_VOWIFI_11R + pSirSmeJoinRsp->parsedRicRspLen = 0; +#endif +#ifdef FEATURE_WLAN_ESE + pSirSmeJoinRsp->tspecIeLen = 0; +#endif + + if(resultCode == eSIR_SME_SUCCESS) + { + + if(psessionEntry->beacon != NULL) + { + pSirSmeJoinRsp->beaconLength = psessionEntry->bcnLen; + vos_mem_copy( pSirSmeJoinRsp->frames, psessionEntry->beacon, + pSirSmeJoinRsp->beaconLength); + vos_mem_free( psessionEntry->beacon); + psessionEntry->beacon = NULL; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("Beacon=%d"), psessionEntry->bcnLen);) +#endif + } + + if(psessionEntry->assocReq != NULL) + { + pSirSmeJoinRsp->assocReqLength = psessionEntry->assocReqLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen, + psessionEntry->assocReq, pSirSmeJoinRsp->assocReqLength); + vos_mem_free( psessionEntry->assocReq); + psessionEntry->assocReq = NULL; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("AssocReq=%d"), psessionEntry->assocReqLen);) +#endif + } + if(psessionEntry->assocRsp != NULL) + { + pSirSmeJoinRsp->assocRspLength = psessionEntry->assocRspLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen + + psessionEntry->assocReqLen, + psessionEntry->assocRsp, + pSirSmeJoinRsp->assocRspLength); + vos_mem_free( psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if(psessionEntry->ricData != NULL) + { + pSirSmeJoinRsp->parsedRicRspLen = psessionEntry->RICDataLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen + + psessionEntry->assocReqLen + psessionEntry->assocRspLen, + psessionEntry->ricData, pSirSmeJoinRsp->parsedRicRspLen); + vos_mem_free(psessionEntry->ricData); + psessionEntry->ricData = NULL; + PELOG1(limLog(pMac, LOG1, FL("RicLength=%d"), pSirSmeJoinRsp->parsedRicRspLen);) + } +#endif +#ifdef FEATURE_WLAN_ESE + if(psessionEntry->tspecIes != NULL) + { + pSirSmeJoinRsp->tspecIeLen = psessionEntry->tspecLen; + vos_mem_copy( pSirSmeJoinRsp->frames + psessionEntry->bcnLen + + psessionEntry->assocReqLen + psessionEntry->assocRspLen + + psessionEntry->RICDataLen, + psessionEntry->tspecIes, pSirSmeJoinRsp->tspecIeLen); + vos_mem_free(psessionEntry->tspecIes); + psessionEntry->tspecIes = NULL; + PELOG1(limLog(pMac, LOG1, FL("ESE-TspecLen=%d"), psessionEntry->tspecLen);) + } +#endif + pSirSmeJoinRsp->aid = psessionEntry->limAID; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOG1(limLog(pMac, LOG1, FL("AssocRsp=%d"), psessionEntry->assocRspLen);) +#endif + } + else + { + + if(psessionEntry->beacon != NULL) + { + vos_mem_free(psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + + if(psessionEntry->assocReq != NULL) + { + vos_mem_free( psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if(psessionEntry->assocRsp != NULL) + { + vos_mem_free( psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if(psessionEntry->ricData != NULL) + { + vos_mem_free( psessionEntry->ricData); + psessionEntry->ricData = NULL; + } +#endif + +#ifdef FEATURE_WLAN_ESE + if(psessionEntry->tspecIes != NULL) + { + vos_mem_free(psessionEntry->tspecIes); + psessionEntry->tspecIes = NULL; + } +#endif + } + } + + + pSirSmeJoinRsp->messageType = msgType; + pSirSmeJoinRsp->length = (tANI_U16) rspLen; + pSirSmeJoinRsp->statusCode = resultCode; + pSirSmeJoinRsp->protStatusCode = protStatusCode; + + /* Update SME session ID and transaction Id */ + pSirSmeJoinRsp->sessionId = smesessionId; + pSirSmeJoinRsp->transactionId = smetransactionId; + + if(IS_MCC_SUPPORTED && limIsLinkSuspended( pMac ) ) + { + if( psessionEntry && psessionEntry->limSmeState == eLIM_SME_LINK_EST_STATE ) + { + +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability) + { + ePhyChanBondState htSecondaryChannelOffset; + /*Get 11ac cbState from 11n cbState*/ + htSecondaryChannelOffset = limGet11ACPhyCBState(pMac, + psessionEntry->currentOperChannel, + psessionEntry->htSecondaryChannelOffset, + psessionEntry->apCenterChan, + psessionEntry); + peSetResumeChannel( pMac, psessionEntry->currentOperChannel, htSecondaryChannelOffset); + } + else +#endif + peSetResumeChannel( pMac, psessionEntry->currentOperChannel, psessionEntry->htSecondaryChannelOffset); + } + else + { + peSetResumeChannel( pMac, 0, 0); + } + limResumeLink( pMac, limSendSmeJoinReassocRspAfterResume, + (tANI_U32*) pSirSmeJoinRsp ); + } + else + { + limSendSmeJoinReassocRspAfterResume( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pSirSmeJoinRsp ); + } +} /*** end limSendSmeJoinReassocRsp() ***/ + + +/** + * limSendSmeStartBssRsp() + * + *FUNCTION: + * This function is called to send eWNI_SME_START_BSS_RSP + * message to applications above MAC Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates message type + * @param resultCode Indicates the result of previously issued + * eWNI_SME_msgType_REQ message + * + * @return None + */ + +void +limSendSmeStartBssRsp(tpAniSirGlobal pMac, + tANI_U16 msgType, tSirResultCodes resultCode,tpPESession psessionEntry, + tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + + + tANI_U16 size = 0; + tSirMsgQ mmhMsg; + tSirSmeStartBssRsp *pSirSmeRsp; + tANI_U16 ieLen; + tANI_U16 ieOffset, curLen; + + limLog(pMac, LOG1, FL("Sending message %s with reasonCode %s"), + limMsgStr(msgType), limResultCodeStr(resultCode)); + + size = sizeof(tSirSmeStartBssRsp); + + if(psessionEntry == NULL) + { + pSirSmeRsp = vos_mem_malloc(size); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP,FL("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP")); + return; + } + vos_mem_set((tANI_U8*)pSirSmeRsp, size, 0); + + } + else + { + //subtract size of beaconLength + Mac Hdr + Fixed Fields before SSID + ieOffset = sizeof(tAniBeaconStruct) + SIR_MAC_B_PR_SSID_OFFSET; + ieLen = pMac->sch.schObject.gSchBeaconOffsetBegin + pMac->sch.schObject.gSchBeaconOffsetEnd - ieOffset; + //calculate the memory size to allocate + size += ieLen; + + pSirSmeRsp = vos_mem_malloc(size); + if ( NULL == pSirSmeRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_START_BSS_RSP")); + + return; + } + vos_mem_set((tANI_U8*)pSirSmeRsp, size, 0); + size = sizeof(tSirSmeStartBssRsp); + if (resultCode == eSIR_SME_SUCCESS) + { + + sirCopyMacAddr(pSirSmeRsp->bssDescription.bssId, psessionEntry->bssId); + + /* Read beacon interval from session */ + pSirSmeRsp->bssDescription.beaconInterval = (tANI_U16) psessionEntry->beaconParams.beaconInterval; + pSirSmeRsp->bssType = psessionEntry->bssType; + + if (cfgGetCapabilityInfo( pMac, &pSirSmeRsp->bssDescription.capabilityInfo,psessionEntry) + != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve Capabilities value")); + + limGetPhyMode(pMac, (tANI_U32 *)&pSirSmeRsp->bssDescription.nwType, psessionEntry); + +#if 0 + if (wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_CHANNEL, &len) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("could not retrieve CURRENT_CHANNEL from CFG")); + +#endif// TO SUPPORT BT-AMP + + pSirSmeRsp->bssDescription.channelId = psessionEntry->currentOperChannel; + + pSirSmeRsp->bssDescription.aniIndicator = 1; + + curLen = pMac->sch.schObject.gSchBeaconOffsetBegin - ieOffset; + vos_mem_copy( (tANI_U8 *) &pSirSmeRsp->bssDescription.ieFields, + pMac->sch.schObject.gSchBeaconFrameBegin + ieOffset, + (tANI_U32)curLen); + + vos_mem_copy( ((tANI_U8 *) &pSirSmeRsp->bssDescription.ieFields) + curLen, + pMac->sch.schObject.gSchBeaconFrameEnd, + (tANI_U32)pMac->sch.schObject.gSchBeaconOffsetEnd); + + + //subtracting size of length indicator itself and size of pointer to ieFields + pSirSmeRsp->bssDescription.length = + ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields)) + - sizeof(pSirSmeRsp->bssDescription.length) + ieLen; + //This is the size of the message, subtracting the size of the pointer to ieFields + size += ieLen - sizeof(tANI_U32); + } + } + + pSirSmeRsp->messageType = msgType; + pSirSmeRsp->length = size; + + /* Update SME session Id and transaction Id */ + pSirSmeRsp->sessionId = smesessionId; + pSirSmeRsp->transactionId = smetransactionId; + pSirSmeRsp->statusCode = resultCode; + if(psessionEntry != NULL ) + pSirSmeRsp->staId = psessionEntry->staId; //else it will be always zero smeRsp StaID = 0 + + + mmhMsg.type = msgType; + mmhMsg.bodyptr = pSirSmeRsp; + mmhMsg.bodyval = 0; + if(psessionEntry == NULL) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, + psessionEntry->peSessionId, mmhMsg.type)); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_START_BSS_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeStartBssRsp() ***/ + +#define LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED 20 +#define LIM_SIZE_OF_EACH_BSS 400 // this is a rough estimate + + +/** + * limSendSmeScanRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_SCAN_RSP message to applications above MAC + * Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param length Indicates length of message + * @param resultCode Indicates the result of previously issued + * eWNI_SME_SCAN_REQ message + * + * @return None + */ + +void +limSendSmeScanRsp(tpAniSirGlobal pMac, tANI_U16 length, + tSirResultCodes resultCode,tANI_U8 smesessionId,tANI_U16 smetranscationId) +{ + tSirMsgQ mmhMsg; + tpSirSmeScanRsp pSirSmeScanRsp=NULL; + tLimScanResultNode *ptemp = NULL; + tANI_U16 msgLen, allocLength, curMsgLen = 0; + tANI_U16 i, bssCount; + tANI_U8 *pbBuf; + tSirBssDescription *pDesc; + + if (resultCode != eSIR_SME_SUCCESS) + { + limPostSmeScanRspMessage(pMac, length, resultCode,smesessionId,smetranscationId); + return; + } + + mmhMsg.type = eWNI_SME_SCAN_RSP; + i = 0; + bssCount = 0; + msgLen = 0; + allocLength = LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED * LIM_SIZE_OF_EACH_BSS; + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP")); + + return; + } + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + //when ptemp is not NULL it is a left over + ptemp = pMac->lim.gLimCachedScanHashTable[i]; + while(ptemp) + { + pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen; + if(0 == bssCount) + { + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + } + else + { + msgLen += ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = (tSirBssDescription *)pbBuf; + } + if( (allocLength < msgLen) || + (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) ) + { + pSirSmeScanRsp->statusCode = + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, + mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP")); + return; + } + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + bssCount = 1; + } + curMsgLen = msgLen; + + pDesc->length + = ptemp->bssDescription.length; + vos_mem_copy( (tANI_U8 *) &pDesc->bssId, + (tANI_U8 *) &ptemp->bssDescription.bssId, + ptemp->bssDescription.length); + + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + ptemp = ptemp->next; + } //while(ptemp) + } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + + if(0 == bssCount) + { + limPostSmeScanRspMessage(pMac, length, resultCode, smesessionId, smetranscationId); + if (NULL != pSirSmeScanRsp) + { + vos_mem_free( pSirSmeScanRsp); + pSirSmeScanRsp = NULL; + } + } + else + { +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, NULL, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + // send last message + pSirSmeScanRsp->statusCode = eSIR_SME_SUCCESS; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + + /* Update SME session Id and SME transcation Id */ + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + mmhMsg.type = eWNI_SME_SCAN_RSP; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + limLog(pMac, LOG1, FL("statusCode : eSIR_SME_SUCCESS")); + } + + return; + +} /*** end limSendSmeScanRsp() ***/ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * limSendSmeLfrScanRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_SCAN_RSP message to applications above MAC Software + * only for sending up the roam candidates. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param length Indicates length of message + * @param resultCode Indicates the result of previously issued + * eWNI_SME_SCAN_REQ message + * + * @return None + */ + +void +limSendSmeLfrScanRsp(tpAniSirGlobal pMac, tANI_U16 length, + tSirResultCodes resultCode,tANI_U8 smesessionId,tANI_U16 smetranscationId) +{ + tSirMsgQ mmhMsg; + tpSirSmeScanRsp pSirSmeScanRsp=NULL; + tLimScanResultNode *ptemp = NULL; + tANI_U16 msgLen, allocLength, curMsgLen = 0; + tANI_U16 i, bssCount; + tANI_U8 *pbBuf; + tSirBssDescription *pDesc; + + PELOG1(limLog(pMac, LOG1, + FL("Sending message SME_SCAN_RSP with length=%d reasonCode %s\n"), + length, limResultCodeStr(resultCode));) + + if (resultCode != eSIR_SME_SUCCESS) + { + limPostSmeScanRspMessage(pMac, length, resultCode,smesessionId,smetranscationId); + return; + } + + mmhMsg.type = eWNI_SME_SCAN_RSP; + i = 0; + bssCount = 0; + msgLen = 0; + allocLength = LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED * LIM_SIZE_OF_EACH_BSS; + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP\n")); + + return; + } + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + //when ptemp is not NULL it is a left over + ptemp = pMac->lim.gLimCachedLfrScanHashTable[i]; + while(ptemp) + { + pbBuf = ((tANI_U8 *)pSirSmeScanRsp) + msgLen; + if(0 == bssCount) + { + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + } + else + { + msgLen += ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = (tSirBssDescription *)pbBuf; + } + if ( (allocLength < msgLen) || + (LIM_MAX_NUM_OF_SCAN_RESULTS_REPORTED <= bssCount++) ) + { + pSirSmeScanRsp->statusCode = + eSIR_SME_MORE_SCAN_RESULTS_FOLLOW; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, + mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + pSirSmeScanRsp = vos_mem_malloc(allocLength); + if ( NULL == pSirSmeScanRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_SCAN_RSP\n")); + return; + } + msgLen = sizeof(tSirSmeScanRsp) - + sizeof(tSirBssDescription) + + ptemp->bssDescription.length + + sizeof(ptemp->bssDescription.length); + pDesc = pSirSmeScanRsp->bssDescription; + bssCount = 1; + } + curMsgLen = msgLen; + + PELOG2(limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d\n"), + msgLen, ptemp->bssDescription.length);) + pDesc->length + = ptemp->bssDescription.length; + vos_mem_copy( (tANI_U8 *) &pDesc->bssId, + (tANI_U8 *) &ptemp->bssDescription.bssId, + ptemp->bssDescription.length); + + PELOG2(limLog(pMac, LOG2, FL("BssId ")); + limPrintMacAddr(pMac, ptemp->bssDescription.bssId, LOG2);) + + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + ptemp = ptemp->next; + } //while(ptemp) + } //for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + + if (0 == bssCount) + { + limPostSmeScanRspMessage(pMac, length, resultCode, smesessionId, smetranscationId); + if (NULL != pSirSmeScanRsp) + { + vos_mem_free( pSirSmeScanRsp); + pSirSmeScanRsp = NULL; + } + } + else + { + // send last message + pSirSmeScanRsp->statusCode = eSIR_SME_SUCCESS; + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = curMsgLen; + + /* Update SME session Id and SME transcation Id */ + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetranscationId; + + mmhMsg.type = eWNI_SME_SCAN_RSP; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + PELOG2(limLog(pMac, LOG2, FL("statusCode : eSIR_SME_SUCCESS\n"));) + } + + return; + +} /*** end limSendSmeLfrScanRsp() ***/ +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/** + * limPostSmeScanRspMessage() + * + *FUNCTION: + * This function is called by limSendSmeScanRsp() to send + * eWNI_SME_SCAN_RSP message with failed result code + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param length Indicates length of message + * @param resultCode failed result code + * + * @return None + */ + +void +limPostSmeScanRspMessage(tpAniSirGlobal pMac, + tANI_U16 length, + tSirResultCodes resultCode,tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tpSirSmeScanRsp pSirSmeScanRsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOG1, + FL("limPostSmeScanRspMessage: send SME_SCAN_RSP (len %d, reasonCode %s). "), + length, limResultCodeStr(resultCode)); + + pSirSmeScanRsp = vos_mem_malloc(length); + if ( NULL == pSirSmeScanRsp ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_SCAN_RSP")); + return; + } + vos_mem_set((void*)pSirSmeScanRsp, length, 0); + + pSirSmeScanRsp->messageType = eWNI_SME_SCAN_RSP; + pSirSmeScanRsp->length = length; + + if(sizeof(tSirSmeScanRsp) <= length) + { + pSirSmeScanRsp->bssDescription->length = sizeof(tSirBssDescription); + } + + pSirSmeScanRsp->statusCode = resultCode; + + /*Update SME session Id and transaction Id */ + pSirSmeScanRsp->sessionId = smesessionId; + pSirSmeScanRsp->transcationId = smetransactionId; + + mmhMsg.type = eWNI_SME_SCAN_RSP; + mmhMsg.bodyptr = pSirSmeScanRsp; + mmhMsg.bodyval = 0; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SCAN_RSP_EVENT, NULL, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; + +} /*** limPostSmeScanRspMessage ***/ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** + * limSendSmeOemDataRsp() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() to send + * eWNI_SME_OEM_DATA_RSP message to applications above MAC + * Software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param pMsgBuf Indicates the mlm message + * @param resultCode Indicates the result of previously issued + * eWNI_SME_OEM_DATA_RSP message + * + * @return None + */ + +void limSendSmeOemDataRsp(tpAniSirGlobal pMac, tANI_U32* pMsgBuf, tSirResultCodes resultCode) +{ + tSirMsgQ mmhMsg; + tSirOemDataRsp* pSirSmeOemDataRsp=NULL; + tLimMlmOemDataRsp* pMlmOemDataRsp=NULL; + tANI_U16 msgLength; + + + //get the pointer to the mlm message + pMlmOemDataRsp = (tLimMlmOemDataRsp*)(pMsgBuf); + + msgLength = sizeof(tSirOemDataRsp); + + //now allocate memory for the char buffer + pSirSmeOemDataRsp = vos_mem_malloc(msgLength); + if (NULL == pSirSmeOemDataRsp) + { + limLog(pMac, LOGP, FL("call to AllocateMemory failed for pSirSmeOemDataRsp")); + return; + } + +#if defined (ANI_LITTLE_BYTE_ENDIAN) + sirStoreU16N((tANI_U8*)&pSirSmeOemDataRsp->length, msgLength); + sirStoreU16N((tANI_U8*)&pSirSmeOemDataRsp->messageType, eWNI_SME_OEM_DATA_RSP); +#else + pSirSmeOemDataRsp->length = msgLength; + pSirSmeOemDataRsp->messageType = eWNI_SME_OEM_DATA_RSP; +#endif + + vos_mem_copy(pSirSmeOemDataRsp->oemDataRsp, pMlmOemDataRsp->oemDataRsp, OEM_DATA_RSP_SIZE); + + //Now free the memory from MLM Rsp Message + vos_mem_free(pMlmOemDataRsp); + + mmhMsg.type = eWNI_SME_OEM_DATA_RSP; + mmhMsg.bodyptr = pSirSmeOemDataRsp; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} /*** limSendSmeOemDataRsp ***/ + +#endif + + +/** + * limSendSmeAuthRsp() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_AUTH_RSP message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param statusCode Indicates the result of previously issued + * eWNI_SME_AUTH_REQ message + * + * @return None + */ +void +limSendSmeAuthRsp(tpAniSirGlobal pMac, + tSirResultCodes statusCode, + tSirMacAddr peerMacAddr, + tAniAuthType authType, + tANI_U16 protStatusCode, + tpPESession psessionEntry,tANI_U8 smesessionId, + tANI_U16 smetransactionId) +{ +#if 0 + tSirMsgQ mmhMsg; + tSirSmeAuthRsp *pSirSmeAuthRsp; + + pSirSmeAuthRsp = vos_mem_malloc(sizeof(tSirSmeAuthRsp)); + if (NULL == pSirSmeAuthRsp) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_AUTH_RSP")); + + return; + } + + + + if(psessionEntry != NULL) + { + vos_mem_copy( (tANI_U8 *) pSirSmeAuthRsp->peerMacAddr, + (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr)); + pSirSmeAuthRsp->authType = authType; + + } + + pSirSmeAuthRsp->messageType = eWNI_SME_AUTH_RSP; + pSirSmeAuthRsp->length = sizeof(tSirSmeAuthRsp); + pSirSmeAuthRsp->statusCode = statusCode; + pSirSmeAuthRsp->protStatusCode = protStatusCode; + + /* Update SME session and transaction Id*/ + pSirSmeAuthRsp->sessionId = smesessionId; + pSirSmeAuthRsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_AUTH_RSP; + mmhMsg.bodyptr = pSirSmeAuthRsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +#endif +} /*** end limSendSmeAuthRsp() ***/ + + +void limSendSmeDisassocDeauthNtf( tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *pCtx ) +{ + tSirMsgQ mmhMsg; + tSirMsgQ *pMsg = (tSirMsgQ*) pCtx; + + mmhMsg.type = pMsg->type; + mmhMsg.bodyptr = pMsg; + mmhMsg.bodyval = 0; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} +/** + * limSendSmeDisassocNtf() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_DISASSOC_RSP/IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_DISASSOC_CNF, + * or eWNI_SME_DISASSOC_IND to host depending on + * disassociation trigger. + * + * @param peerMacAddr Indicates the peer MAC addr to which + * disassociate was initiated + * @param reasonCode Indicates the reason for Disassociation + * @param disassocTrigger Indicates the trigger for Disassociation + * @param aid Indicates the STAID. This parameter is + * present only on AP. + * + * @return None + */ +void +limSendSmeDisassocNtf(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirResultCodes reasonCode, + tANI_U16 disassocTrigger, + tANI_U16 aid, + tANI_U8 smesessionId, + tANI_U16 smetransactionId, + tpPESession psessionEntry) +{ + + tANI_U8 *pBuf; + tSirSmeDisassocRsp *pSirSmeDisassocRsp; + tSirSmeDisassocInd *pSirSmeDisassocInd; + tSirSmeDisConDoneInd *pSirSmeDisConDoneInd; + tANI_U32 *pMsg; + bool failure = FALSE; + + limLog(pMac, LOG1, FL("Disassoc Ntf with trigger : %d" + "reasonCode: %d"), + disassocTrigger, + reasonCode); + + switch (disassocTrigger) + { + case eLIM_HOST_DISASSOC: + /** + * Disassociation response due to + * host triggered disassociation + */ + + pSirSmeDisassocRsp = vos_mem_malloc(sizeof(tSirSmeDisassocRsp)); + if ( NULL == pSirSmeDisassocRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DISASSOC_RSP")); + failure = TRUE; + goto error; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DISASSOC_RSP with " + "retCode: %d for "MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDisassocRsp->messageType = eWNI_SME_DISASSOC_RSP; + pSirSmeDisassocRsp->length = sizeof(tSirSmeDisassocRsp); + //sessionId + pBuf = (tANI_U8 *) &pSirSmeDisassocRsp->sessionId; + *pBuf = smesessionId; + pBuf++; + + //transactionId + limCopyU16(pBuf, smetransactionId); + pBuf += sizeof(tANI_U16); + + //statusCode + limCopyU32(pBuf, reasonCode); + pBuf += sizeof(tSirResultCodes); + + //peerMacAddr + vos_mem_copy( pBuf, peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + // Clear Station Stats + //for sta, it is always 1, IBSS is handled at halInitSta + + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_RSP_EVENT, + psessionEntry, (tANI_U16)reasonCode, 0); +#endif + pMsg = (tANI_U32*) pSirSmeDisassocRsp; + break; + + case eLIM_PEER_ENTITY_DISASSOC: + case eLIM_LINK_MONITORING_DISASSOC: + pSirSmeDisConDoneInd = vos_mem_malloc(sizeof(tSirSmeDisConDoneInd)); + if ( NULL == pSirSmeDisConDoneInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for disconnect indication")); + + return; + } + vos_mem_zero(pSirSmeDisConDoneInd, sizeof(tSirSmeDisConDoneInd)); + limLog(pMac, LOG1, + FL("send eWNI_SME_DISCONNECT_DONE_IND withretCode: %d"), + reasonCode); + pSirSmeDisConDoneInd->messageType = eWNI_SME_DISCONNECT_DONE_IND; + pSirSmeDisConDoneInd->length = sizeof(tSirSmeDisConDoneInd); + vos_mem_copy(pSirSmeDisConDoneInd->peerMacAddr, peerMacAddr, + sizeof(tSirMacAddr)); + pSirSmeDisConDoneInd->sessionId = smesessionId; + + if (reasonCode == eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE) + pSirSmeDisConDoneInd->reasonCode = 0; + else + pSirSmeDisConDoneInd->reasonCode = reasonCode; + + pMsg = (tANI_U32 *)pSirSmeDisConDoneInd; + break; + + default: + /** + * Disassociation indication due to Disassociation + * frame reception from peer entity or due to + * loss of link with peer entity. + */ + pSirSmeDisassocInd = vos_mem_malloc(sizeof(tSirSmeDisassocInd)); + if ( NULL == pSirSmeDisassocInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DISASSOC_IND")); + + failure = TRUE; + goto error; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DISASSOC_IND with " + "retCode: %d for "MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; + pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd); + + /* Update SME session Id and Transaction Id */ + pSirSmeDisassocInd->sessionId = smesessionId; + pSirSmeDisassocInd->transactionId = smetransactionId; + pSirSmeDisassocInd->reasonCode = reasonCode; + pSirSmeDisassocInd->assocId = aid; + pBuf = (tANI_U8 *) &pSirSmeDisassocInd->statusCode; + + limCopyU32(pBuf, reasonCode); + pBuf += sizeof(tSirResultCodes); + + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + vos_mem_copy( pBuf, peerMacAddr, sizeof(tSirMacAddr)); + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, + psessionEntry, (tANI_U16)reasonCode, 0); +#endif + pMsg = (tANI_U32*) pSirSmeDisassocInd; + + break; + } + +error: + /* Delete the PE session Created */ + if((psessionEntry != NULL) && ((psessionEntry ->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry ->limSystemRole == eLIM_BT_AMP_STA_ROLE)) ) + { + peDeleteSession(pMac,psessionEntry); + } + if (failure == FALSE) + limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pMsg ); +} /*** end limSendSmeDisassocNtf() ***/ + + +/** ----------------------------------------------------------------- + \brief limSendSmeDisassocInd() - sends SME_DISASSOC_IND + + After receiving disassociation frame from peer entity, this + function sends a eWNI_SME_DISASSOC_IND to SME with a specific + reason code. + + \param pMac - global mac structure + \param pStaDs - station dph hash node + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmeDisassocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs,tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirSmeDisassocInd *pSirSmeDisassocInd; + + pSirSmeDisassocInd = vos_mem_malloc(sizeof(tSirSmeDisassocInd)); + if ( NULL == pSirSmeDisassocInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_DISASSOC_IND")); + return; + } + + pSirSmeDisassocInd->messageType = eWNI_SME_DISASSOC_IND; + pSirSmeDisassocInd->length = sizeof(tSirSmeDisassocInd); + + pSirSmeDisassocInd->sessionId = psessionEntry->smeSessionId; + pSirSmeDisassocInd->transactionId = psessionEntry->transactionId; + pSirSmeDisassocInd->statusCode = eSIR_SME_DEAUTH_STATUS; + pSirSmeDisassocInd->reasonCode = pStaDs->mlmStaContext.disassocReason; + pSirSmeDisassocInd->assocId = pStaDs->assocId; + + vos_mem_copy( pSirSmeDisassocInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + + vos_mem_copy( pSirSmeDisassocInd->peerMacAddr, pStaDs->staAddr, sizeof(tSirMacAddr)); + + pSirSmeDisassocInd->staId = pStaDs->staIndex; + + mmhMsg.type = eWNI_SME_DISASSOC_IND; + mmhMsg.bodyptr = pSirSmeDisassocInd; + mmhMsg.bodyval = 0; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, psessionEntry->peSessionId, + mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DISASSOC_IND_EVENT, psessionEntry, 0, (tANI_U16)pStaDs->mlmStaContext.disassocReason); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} /*** end limSendSmeDisassocInd() ***/ + + +/** ----------------------------------------------------------------- + \brief limSendSmeDeauthInd() - sends SME_DEAUTH_IND + + After receiving deauthentication frame from peer entity, this + function sends a eWNI_SME_DEAUTH_IND to SME with a specific + reason code. + + \param pMac - global mac structure + \param pStaDs - station dph hash node + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmeDeauthInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirSmeDeauthInd *pSirSmeDeauthInd; + + limSendTLPauseInd(pMac, pStaDs->staIndex); + + pSirSmeDeauthInd = vos_mem_malloc(sizeof(tSirSmeDeauthInd)); + if ( NULL == pSirSmeDeauthInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_DEAUTH_IND ")); + return; + } + + pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; + pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd); + + pSirSmeDeauthInd->sessionId = psessionEntry->smeSessionId; + pSirSmeDeauthInd->transactionId = psessionEntry->transactionId; + pSirSmeDeauthInd->assocId = pStaDs->assocId; + if(eSIR_INFRA_AP_MODE == psessionEntry->bssType) + { + pSirSmeDeauthInd->statusCode = (tSirResultCodes)pStaDs->mlmStaContext.cleanupTrigger; + } + else + { + //Need to indicatet he reascon code over the air + pSirSmeDeauthInd->statusCode = (tSirResultCodes)pStaDs->mlmStaContext.disassocReason; + } + //BSSID + vos_mem_copy( pSirSmeDeauthInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + //peerMacAddr + vos_mem_copy( pSirSmeDeauthInd->peerMacAddr, pStaDs->staAddr, sizeof(tSirMacAddr)); + pSirSmeDeauthInd->reasonCode = pStaDs->mlmStaContext.disassocReason; + + + pSirSmeDeauthInd->staId = pStaDs->staIndex; + + mmhMsg.type = eWNI_SME_DEAUTH_IND; + mmhMsg.bodyptr = pSirSmeDeauthInd; + mmhMsg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, psessionEntry, 0, pStaDs->mlmStaContext.cleanupTrigger); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} /*** end limSendSmeDeauthInd() ***/ + +#ifdef FEATURE_WLAN_TDLS +/** + * limSendSmeTDLSDelStaInd() + * + *FUNCTION: + * This function is called to send the TDLS STA context deletion to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param pStaDs - Pointer to internal STA Datastructure + * @param psessionEntry - Pointer to the session entry + * @param reasonCode - Reason for TDLS sta deletion + * @return None + */ +void +limSendSmeTDLSDelStaInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry, tANI_U16 reasonCode) +{ + tSirMsgQ mmhMsg; + tSirTdlsDelStaInd *pSirTdlsDelStaInd; + + pSirTdlsDelStaInd = vos_mem_malloc(sizeof(tSirTdlsDelStaInd)); + if ( NULL == pSirTdlsDelStaInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_TDLS_DEL_STA_IND ")); + return; + } + + //messageType + pSirTdlsDelStaInd->messageType = eWNI_SME_TDLS_DEL_STA_IND; + pSirTdlsDelStaInd->length = sizeof(tSirTdlsDelStaInd); + + //sessionId + pSirTdlsDelStaInd->sessionId = psessionEntry->smeSessionId; + + //peerMacAddr + vos_mem_copy( pSirTdlsDelStaInd->peerMac, pStaDs->staAddr, sizeof(tSirMacAddr)); + + //staId + limCopyU16((tANI_U8*)(&pSirTdlsDelStaInd->staId), (tANI_U16)pStaDs->staIndex); + + //reasonCode + limCopyU16((tANI_U8*)(&pSirTdlsDelStaInd->reasonCode), reasonCode); + + mmhMsg.type = eWNI_SME_TDLS_DEL_STA_IND; + mmhMsg.bodyptr = pSirTdlsDelStaInd; + mmhMsg.bodyval = 0; + + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +}/*** end limSendSmeTDLSDelStaInd() ***/ + +/** + * limSendSmeTDLSDeleteAllPeerInd() + * + *FUNCTION: + * This function is called to send the eWNI_SME_TDLS_DEL_ALL_PEER_IND + * message to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param psessionEntry - Pointer to the session entry + * @return None + */ +void +limSendSmeTDLSDeleteAllPeerInd(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg; + tSirTdlsDelAllPeerInd *pSirTdlsDelAllPeerInd; + + pSirTdlsDelAllPeerInd = vos_mem_malloc(sizeof(tSirTdlsDelAllPeerInd)); + if ( NULL == pSirTdlsDelAllPeerInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_TDLS_DEL_ALL_PEER_IND")); + return; + } + + //messageType + pSirTdlsDelAllPeerInd->messageType = eWNI_SME_TDLS_DEL_ALL_PEER_IND; + pSirTdlsDelAllPeerInd->length = sizeof(tSirTdlsDelAllPeerInd); + + //sessionId + pSirTdlsDelAllPeerInd->sessionId = psessionEntry->smeSessionId; + + mmhMsg.type = eWNI_SME_TDLS_DEL_ALL_PEER_IND; + mmhMsg.bodyptr = pSirTdlsDelAllPeerInd; + mmhMsg.bodyval = 0; + + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +}/*** end limSendSmeTDLSDeleteAllPeerInd() ***/ + +/** + * limSendSmeMgmtTXCompletion() + * + *FUNCTION: + * This function is called to send the eWNI_SME_MGMT_FRM_TX_COMPLETION_IND + * message to SME. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param pMac - Pointer to global MAC structure + * @param psessionEntry - Pointer to the session entry + * @param txCompleteStatus - TX Complete Status of Mgmt Frames + * @return None + */ +void +limSendSmeMgmtTXCompletion(tpAniSirGlobal pMac, + tANI_U32 smeSessionId, + tANI_U32 txCompleteStatus) +{ + tSirMsgQ mmhMsg; + tSirMgmtTxCompletionInd *pSirMgmtTxCompletionInd; + + pSirMgmtTxCompletionInd = vos_mem_malloc(sizeof(tSirMgmtTxCompletionInd)); + if ( NULL == pSirMgmtTxCompletionInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_MGMT_FRM_TX_COMPLETION_IND")); + return; + } + + //messageType + pSirMgmtTxCompletionInd->messageType = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND; + pSirMgmtTxCompletionInd->length = sizeof(tSirMgmtTxCompletionInd); + + //sessionId + pSirMgmtTxCompletionInd->sessionId = smeSessionId; + + pSirMgmtTxCompletionInd->txCompleteStatus = txCompleteStatus; + + mmhMsg.type = eWNI_SME_MGMT_FRM_TX_COMPLETION_IND; + mmhMsg.bodyptr = pSirMgmtTxCompletionInd; + mmhMsg.bodyval = 0; + + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +}/*** end limSendSmeTDLSDeleteAllPeerInd() ***/ +#endif + + +/** + * limSendSmeDeauthNtf() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_DISASSOC_RSP/IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_DEAUTH_CNF or + * eWNI_SME_DEAUTH_IND to host depending on deauthentication trigger. + * + * @param peerMacAddr Indicates the peer MAC addr to which + * deauthentication was initiated + * @param reasonCode Indicates the reason for Deauthetication + * @param deauthTrigger Indicates the trigger for Deauthetication + * @param aid Indicates the STAID. This parameter is present + * only on AP. + * + * @return None + */ +void +limSendSmeDeauthNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tSirResultCodes reasonCode, + tANI_U16 deauthTrigger, tANI_U16 aid,tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tANI_U8 *pBuf; + tSirSmeDeauthRsp *pSirSmeDeauthRsp; + tSirSmeDeauthInd *pSirSmeDeauthInd; + tSirSmeDisConDoneInd *pSirSmeDisConDoneInd; + tpPESession psessionEntry; + tANI_U8 sessionId; + tANI_U32 *pMsg; + + psessionEntry = peFindSessionByBssid(pMac,peerMacAddr,&sessionId); + switch (deauthTrigger) + { + case eLIM_HOST_DEAUTH: + /** + * Deauthentication response to host triggered + * deauthentication. + */ + pSirSmeDeauthRsp = vos_mem_malloc(sizeof(tSirSmeDeauthRsp)); + if ( NULL == pSirSmeDeauthRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DEAUTH_RSP")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_RSP with " + "retCode: %d for"MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDeauthRsp->messageType = eWNI_SME_DEAUTH_RSP; + pSirSmeDeauthRsp->length = sizeof(tSirSmeDeauthRsp); + pSirSmeDeauthRsp->statusCode = reasonCode; + pSirSmeDeauthRsp->sessionId = smesessionId; + pSirSmeDeauthRsp->transactionId = smetransactionId; + + pBuf = (tANI_U8 *) pSirSmeDeauthRsp->peerMacAddr; + vos_mem_copy( pBuf, peerMacAddr, sizeof(tSirMacAddr)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_RSP_EVENT, + psessionEntry, 0, (tANI_U16)reasonCode); +#endif + pMsg = (tANI_U32*)pSirSmeDeauthRsp; + + break; + + case eLIM_PEER_ENTITY_DEAUTH: + case eLIM_LINK_MONITORING_DEAUTH: + pSirSmeDisConDoneInd = vos_mem_malloc(sizeof(tSirSmeDisConDoneInd)); + if ( NULL == pSirSmeDisConDoneInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for disconnect indication")); + + return; + } + vos_mem_zero(pSirSmeDisConDoneInd, sizeof(tSirSmeDisConDoneInd)); + limLog(pMac, LOG1, + FL("send eWNI_SME_DISCONNECT_DONE_IND withretCode: %d"), + reasonCode); + + pSirSmeDisConDoneInd->messageType = eWNI_SME_DISCONNECT_DONE_IND; + pSirSmeDisConDoneInd->length = sizeof(tSirSmeDisConDoneInd); + vos_mem_copy(pSirSmeDisConDoneInd->peerMacAddr, peerMacAddr, + sizeof(tSirMacAddr)); + pSirSmeDisConDoneInd->sessionId = smesessionId; + + if (reasonCode == eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE) + pSirSmeDisConDoneInd->reasonCode = 0; + else + pSirSmeDisConDoneInd->reasonCode = reasonCode; + + pMsg = (tANI_U32 *)pSirSmeDisConDoneInd; + break; + + default: + /** + * Deauthentication indication due to Deauthentication + * frame reception from peer entity or due to + * loss of link with peer entity. + */ + pSirSmeDeauthInd = vos_mem_malloc(sizeof(tSirSmeDeauthInd)); + if ( NULL == pSirSmeDeauthInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_DEAUTH_Ind")); + + return; + } + limLog(pMac, LOG1, FL("send eWNI_SME_DEAUTH_IND with " + "retCode: %d for "MAC_ADDRESS_STR),reasonCode, + MAC_ADDR_ARRAY(peerMacAddr)); + pSirSmeDeauthInd->messageType = eWNI_SME_DEAUTH_IND; + pSirSmeDeauthInd->length = sizeof(tSirSmeDeauthInd); + pSirSmeDeauthInd->reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + pSirSmeDeauthInd->assocId = aid; + + // sessionId + pBuf = (tANI_U8*) &pSirSmeDeauthInd->sessionId; + *pBuf++ = smesessionId; + + //transaction ID + limCopyU16(pBuf, smetransactionId); + pBuf += sizeof(tANI_U16); + + // status code + limCopyU32(pBuf, reasonCode); + pBuf += sizeof(tSirResultCodes); + + //bssId + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + //peerMacAddr + vos_mem_copy( pSirSmeDeauthInd->peerMacAddr, peerMacAddr, sizeof(tSirMacAddr)); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DEAUTH_IND_EVENT, + psessionEntry, 0, (tANI_U16)reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + pMsg = (tANI_U32*)pSirSmeDeauthInd; + + break; + } + + /*Delete the PE session created */ + if(psessionEntry != NULL) + { + peDeleteSession(pMac,psessionEntry); + } + + limSendSmeDisassocDeauthNtf( pMac, eHAL_STATUS_SUCCESS, + (tANI_U32*) pMsg ); + +} /*** end limSendSmeDeauthNtf() ***/ + + +/** + * limSendSmeWmStatusChangeNtf() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_WM_STATUS_CHANGE_NTF message to host. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param statusChangeCode Indicates the change in the wireless medium. + * @param statusChangeInfo Indicates the information associated with + * change in the wireless medium. + * @param infoLen Indicates the length of status change information + * being sent. + * + * @return None + */ +void +limSendSmeWmStatusChangeNtf(tpAniSirGlobal pMac, tSirSmeStatusChangeCode statusChangeCode, + tANI_U32 *pStatusChangeInfo, tANI_U16 infoLen, tANI_U8 sessionId) +{ + tSirMsgQ mmhMsg; + tSirSmeWmStatusChangeNtf *pSirSmeWmStatusChangeNtf; + pSirSmeWmStatusChangeNtf = vos_mem_malloc(sizeof(tSirSmeWmStatusChangeNtf)); + if ( NULL == pSirSmeWmStatusChangeNtf ) + { + limLog(pMac, LOGE, + FL("call to AllocateMemory failed for eWNI_SME_WM_STATUS_CHANGE_NTF")); + return; + } + + + mmhMsg.type = eWNI_SME_WM_STATUS_CHANGE_NTF; + mmhMsg.bodyval = 0; + mmhMsg.bodyptr = pSirSmeWmStatusChangeNtf; + + switch(statusChangeCode) + { + case eSIR_SME_RADAR_DETECTED: + + break; + + case eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP: + break; + + case eSIR_SME_BACKGROUND_SCAN_FAIL: + limPackBkgndScanFailNotify(pMac, + statusChangeCode, + (tpSirBackgroundScanInfo)pStatusChangeInfo, + pSirSmeWmStatusChangeNtf, sessionId); + break; + + default: + pSirSmeWmStatusChangeNtf->messageType = eWNI_SME_WM_STATUS_CHANGE_NTF; + pSirSmeWmStatusChangeNtf->statusChangeCode = statusChangeCode; + pSirSmeWmStatusChangeNtf->length = sizeof(tSirSmeWmStatusChangeNtf); + pSirSmeWmStatusChangeNtf->sessionId = sessionId; + if(sizeof(pSirSmeWmStatusChangeNtf->statusChangeInfo) >= infoLen) + { + vos_mem_copy( (tANI_U8 *)&pSirSmeWmStatusChangeNtf->statusChangeInfo, + (tANI_U8 *)pStatusChangeInfo, infoLen); + } + limLog(pMac, LOGE, FL("***---*** StatusChg: code %d, length %d ***---***"), + statusChangeCode, infoLen); + break; + } + + + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); + if (eSIR_SUCCESS != limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT)) + { + vos_mem_free(pSirSmeWmStatusChangeNtf); + limLog( pMac, LOGP, FL("limSysProcessMmhMsgApi failed")); + } + +} /*** end limSendSmeWmStatusChangeNtf() ***/ + + +/** + * limSendSmeSetContextRsp() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_SETCONTEXT_RSP message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param peerMacAddr Indicates the peer MAC addr to which + * setContext was performed + * @param aid Indicates the aid corresponding to the peer MAC + * address + * @param resultCode Indicates the result of previously issued + * eWNI_SME_SETCONTEXT_RSP message + * + * @return None + */ +void +limSendSmeSetContextRsp(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, tANI_U16 aid, + tSirResultCodes resultCode, + tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + + tANI_U8 *pBuf; + tSirMsgQ mmhMsg; + tSirSmeSetContextRsp *pSirSmeSetContextRsp; + + pSirSmeSetContextRsp = vos_mem_malloc(sizeof(tSirSmeSetContextRsp)); + if ( NULL == pSirSmeSetContextRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for SmeSetContextRsp")); + + return; + } + + pSirSmeSetContextRsp->messageType = eWNI_SME_SETCONTEXT_RSP; + pSirSmeSetContextRsp->length = sizeof(tSirSmeSetContextRsp); + pSirSmeSetContextRsp->statusCode = resultCode; + + pBuf = pSirSmeSetContextRsp->peerMacAddr; + + vos_mem_copy( pBuf, (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + + /* Update SME session and transaction Id*/ + pSirSmeSetContextRsp->sessionId = smesessionId; + pSirSmeSetContextRsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_SETCONTEXT_RSP; + mmhMsg.bodyptr = pSirSmeSetContextRsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, + mmhMsg.type)); + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, + psessionEntry->peSessionId, mmhMsg.type)); + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT, psessionEntry, (tANI_U16)resultCode, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeSetContextRsp() ***/ + +/** + * limSendSmeRemoveKeyRsp() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_SME_REMOVEKEY_RSP message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param peerMacAddr Indicates the peer MAC addr to which + * Removekey was performed + * @param aid Indicates the aid corresponding to the peer MAC + * address + * @param resultCode Indicates the result of previously issued + * eWNI_SME_REMOVEKEY_RSP message + * + * @return None + */ +void +limSendSmeRemoveKeyRsp(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirResultCodes resultCode, + tpPESession psessionEntry,tANI_U8 smesessionId, + tANI_U16 smetransactionId) +{ + tANI_U8 *pBuf; + tSirMsgQ mmhMsg; + tSirSmeRemoveKeyRsp *pSirSmeRemoveKeyRsp; + + pSirSmeRemoveKeyRsp = vos_mem_malloc(sizeof(tSirSmeRemoveKeyRsp)); + if ( NULL == pSirSmeRemoveKeyRsp ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for SmeRemoveKeyRsp")); + + return; + } + + + + if(psessionEntry != NULL) + { + pBuf = pSirSmeRemoveKeyRsp->peerMacAddr; + vos_mem_copy( pBuf, (tANI_U8 *) peerMacAddr, sizeof(tSirMacAddr)); + } + + pSirSmeRemoveKeyRsp->messageType = eWNI_SME_REMOVEKEY_RSP; + pSirSmeRemoveKeyRsp->length = sizeof(tSirSmeRemoveKeyRsp); + pSirSmeRemoveKeyRsp->statusCode = resultCode; + + /* Update SME session and transaction Id*/ + pSirSmeRemoveKeyRsp->sessionId = smesessionId; + pSirSmeRemoveKeyRsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_REMOVEKEY_RSP; + mmhMsg.bodyptr = pSirSmeRemoveKeyRsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, + psessionEntry->peSessionId, mmhMsg.type)); + } + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} /*** end limSendSmeSetContextRsp() ***/ + + +/** + * limSendSmePromiscuousModeRsp() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to send + * eWNI_PROMISCUOUS_MODE_RSP message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_PROMISCUOUS_MODE_RSP to + * host as a reply to eWNI_SME_PROMISCUOUS_MODE_REQ directive from it. + * + * @param None + * @return None + */ +void +limSendSmePromiscuousModeRsp(tpAniSirGlobal pMac) +{ +#if 0 + tSirMsgQ mmhMsg; + tSirMbMsg *pMbMsg; + + pMbMsg = vos_mem_malloc(sizeof(tSirMbMsg)); + if ( NULL == pMbMsg ) + { + // Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed")); + + return; + } + + pMbMsg->type = eWNI_SME_PROMISCUOUS_MODE_RSP; + pMbMsg->msgLen = 4; + + mmhMsg.type = eWNI_SME_PROMISCUOUS_MODE_RSP; + mmhMsg.bodyptr = pMbMsg; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, 0, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +#endif +} /*** end limSendSmePromiscuousModeRsp() ***/ + + + +/** + * limSendSmeNeighborBssInd() + * + *FUNCTION: + * This function is called by limLookupNaddHashEntry() to send + * eWNI_SME_NEIGHBOR_BSS_IND message to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * This function is used for sending eWNI_SME_NEIGHBOR_BSS_IND to + * host upon detecting new BSS during background scanning if CFG + * option is enabled for sending such indication + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limSendSmeNeighborBssInd(tpAniSirGlobal pMac, + tLimScanResultNode *pBssDescr) +{ + tSirMsgQ msgQ; + tANI_U32 val; + tSirSmeNeighborBssInd *pNewBssInd; + + if ((pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_WT_SCAN_STATE) || + ((pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE) && + pMac->lim.gLimRspReqd)) + { + // LIM is not in background scan state OR + // current scan is initiated by HDD. + // No need to send new BSS indication to HDD + return; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_NEW_BSS_FOUND_IND, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not get NEIGHBOR_BSS_IND from CFG")); + + return; + } + + if (val == 0) + return; + + /** + * Need to indicate new BSSs found during + * background scanning to host. + * Allocate buffer for sending indication. + * Length of buffer is length of BSS description + * and length of header itself + */ + val = pBssDescr->bssDescription.length + sizeof(tANI_U16) + sizeof(tANI_U32) + sizeof(tANI_U8); + pNewBssInd = vos_mem_malloc(val); + if ( NULL == pNewBssInd ) + { + // Log error + limLog(pMac, LOGP, + FL("call to AllocateMemory failed for eWNI_SME_NEIGHBOR_BSS_IND")); + + return; + } + + pNewBssInd->messageType = eWNI_SME_NEIGHBOR_BSS_IND; + pNewBssInd->length = (tANI_U16) val; + pNewBssInd->sessionId = 0; + + vos_mem_copy( (tANI_U8 *) pNewBssInd->bssDescription, + (tANI_U8 *) &pBssDescr->bssDescription, + pBssDescr->bssDescription.length + sizeof(tANI_U16)); + + msgQ.type = eWNI_SME_NEIGHBOR_BSS_IND; + msgQ.bodyptr = pNewBssInd; + msgQ.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, msgQ.type)); + limSysProcessMmhMsgApi(pMac, &msgQ, ePROT); +} /*** end limSendSmeNeighborBssInd() ***/ + +/** ----------------------------------------------------------------- + \brief limSendSmeAddtsRsp() - sends SME ADDTS RSP + \ This function sends a eWNI_SME_ADDTS_RSP to SME. + \ SME only looks at rc and tspec field. + \param pMac - global mac structure + \param rspReqd - is SmeAddTsRsp required + \param status - status code of SME_ADD_TS_RSP + \return tspec + \sa + ----------------------------------------------------------------- */ +void +limSendSmeAddtsRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, tANI_U32 status, tpPESession psessionEntry, + tSirMacTspecIE tspec, tANI_U8 smesessionId, tANI_U16 smetransactionId) +{ + tpSirAddtsRsp rsp; + tSirMsgQ mmhMsg; + + if (! rspReqd) + return; + + rsp = vos_mem_malloc(sizeof(tSirAddtsRsp)); + if ( NULL == rsp ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for ADDTS_RSP")); + return; + } + + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + rsp->messageType = eWNI_SME_ADDTS_RSP; + rsp->rc = status; + rsp->rsp.status = (enum eSirMacStatusCodes) status; + //vos_mem_copy( (tANI_U8 *) &rsp->rsp.tspec, (tANI_U8 *) &addts->tspec, sizeof(addts->tspec)); + rsp->rsp.tspec = tspec; + /* Update SME session Id and transcation Id */ + rsp->sessionId = smesessionId; + rsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_ADDTS_RSP; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, + psessionEntry->peSessionId, mmhMsg.type)); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ADDTS_RSP_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; +} + +void +limSendSmeAddtsInd(tpAniSirGlobal pMac, tpSirAddtsReqInfo addts) +{ + tpSirAddtsRsp rsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOGW, "SendSmeAddtsInd (token %d, tsid %d, up %d)", + addts->dialogToken, + addts->tspec.tsinfo.traffic.tsid, + addts->tspec.tsinfo.traffic.userPrio); + + rsp = vos_mem_malloc(sizeof(tSirAddtsRsp)); + if ( NULL == rsp ) + { + // Log error + limLog(pMac, LOGP, FL("AllocateMemory failed for ADDTS_IND")); + return; + } + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + + rsp->messageType = eWNI_SME_ADDTS_IND; + + vos_mem_copy( (tANI_U8 *) &rsp->rsp, (tANI_U8 *) addts, sizeof(*addts)); + + mmhMsg.type = eWNI_SME_ADDTS_IND; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +void +limSendSmeDeltsRsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, tANI_U32 status,tpPESession psessionEntry,tANI_U8 smesessionId,tANI_U16 smetransactionId) +{ + tpSirDeltsRsp rsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOGW, "SendSmeDeltsRsp (aid %d, tsid %d, up %d) status %d", + delts->aid, + delts->req.tsinfo.traffic.tsid, + delts->req.tsinfo.traffic.userPrio, + status); + if (! delts->rspReqd) + return; + + rsp = vos_mem_malloc(sizeof(tSirDeltsRsp)); + if ( NULL == rsp ) + { + // Log error + limLog(pMac, LOGP, FL("AllocateMemory failed for DELTS_RSP")); + return; + } + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + + if(psessionEntry != NULL) + { + + rsp->aid = delts->aid; + vos_mem_copy( (tANI_U8 *) &rsp->macAddr[0], (tANI_U8 *) &delts->macAddr[0], 6); + vos_mem_copy( (tANI_U8 *) &rsp->rsp, (tANI_U8 *) &delts->req, sizeof(tSirDeltsReqInfo)); + } + + + rsp->messageType = eWNI_SME_DELTS_RSP; + rsp->rc = status; + + /* Update SME session Id and transcation Id */ + rsp->sessionId = smesessionId; + rsp->transactionId = smetransactionId; + + mmhMsg.type = eWNI_SME_DELTS_RSP; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + if(NULL == psessionEntry) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + } + else + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, + psessionEntry->peSessionId, mmhMsg.type)); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_RSP_EVENT, psessionEntry, (tANI_U16)status, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +void +limSendSmeDeltsInd(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, tANI_U16 aid,tpPESession psessionEntry) +{ + tpSirDeltsRsp rsp; + tSirMsgQ mmhMsg; + + limLog(pMac, LOGW, "SendSmeDeltsInd (aid %d, tsid %d, up %d)", + aid, + delts->tsinfo.traffic.tsid, + delts->tsinfo.traffic.userPrio); + + rsp = vos_mem_malloc(sizeof(tSirDeltsRsp)); + if ( NULL == rsp ) + { + // Log error + limLog(pMac, LOGP, FL("AllocateMemory failed for DELTS_IND")); + return; + } + vos_mem_set( (tANI_U8 *) rsp, sizeof(*rsp), 0); + + rsp->messageType = eWNI_SME_DELTS_IND; + rsp->rc = eSIR_SUCCESS; + rsp->aid = aid; + vos_mem_copy( (tANI_U8 *) &rsp->rsp, (tANI_U8 *) delts, sizeof(*delts)); + + /* Update SME session Id and SME transaction Id */ + + rsp->sessionId = psessionEntry->smeSessionId; + rsp->transactionId = psessionEntry->transactionId; + + mmhMsg.type = eWNI_SME_DELTS_IND; + mmhMsg.bodyptr = rsp; + mmhMsg.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_DELTS_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +/** + * limSendSmeStatsRsp() + * + *FUNCTION: + * This function is called to send 802.11 statistics response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request for statistics. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param p80211Stats Statistics sent in response + * @param resultCode TODO: + * + * + * @return none + */ + +void +limSendSmeStatsRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats) +{ + tSirMsgQ mmhMsg; + tSirSmeRsp *pMsgHdr = (tSirSmeRsp*) stats; + + switch(msgType) + { + case WDA_STA_STAT_RSP: + mmhMsg.type = eWNI_SME_STA_STAT_RSP; + break; + case WDA_AGGR_STAT_RSP: + mmhMsg.type = eWNI_SME_AGGR_STAT_RSP; + break; + case WDA_GLOBAL_STAT_RSP: + mmhMsg.type = eWNI_SME_GLOBAL_STAT_RSP; + break; + case WDA_STAT_SUMM_RSP: + mmhMsg.type = eWNI_SME_STAT_SUMM_RSP; + break; + default: + mmhMsg.type = msgType; //Response from within PE + break; + } + + pMsgHdr->messageType = mmhMsg.type; + + mmhMsg.bodyptr = stats; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; + +} /*** end limSendSmeStatsRsp() ***/ + +/** + * limSendSmePEStatisticsRsp() + * + *FUNCTION: + * This function is called to send 802.11 statistics response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request for statistics. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param p80211Stats Statistics sent in response + * @param resultCode TODO: + * + * + * @return none + */ + +void +limSendSmePEStatisticsRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats) +{ + tSirMsgQ mmhMsg; + tANI_U8 sessionId; + tAniGetPEStatsRsp *pPeStats = (tAniGetPEStatsRsp *) stats; + tpPESession pPeSessionEntry; + + //Get the Session Id based on Sta Id + pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId); + + //Fill the Session Id + if(NULL != pPeSessionEntry) + { + //Fill the Session Id + pPeStats->sessionId = pPeSessionEntry->smeSessionId; + } + + pPeStats->msgType = eWNI_SME_GET_STATISTICS_RSP; + + + //msgType should be WDA_GET_STATISTICS_RSP + mmhMsg.type = eWNI_SME_GET_STATISTICS_RSP; + + mmhMsg.bodyptr = stats; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; + +} /*** end limSendSmePEStatisticsRsp() ***/ + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + * limSendSmePEGetRoamRssiRsp() + * + *FUNCTION: + * This function is called to send roam rssi response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request to get roam rssi. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param p80211Stats Statistics sent in response + * @param resultCode TODO: + * + * + * @return none + */ + +void +limSendSmePEGetRoamRssiRsp(tpAniSirGlobal pMac, tANI_U16 msgType, void* stats) +{ + tSirMsgQ mmhMsg; + tANI_U8 sessionId; + tAniGetRoamRssiRsp *pPeStats = (tAniGetRoamRssiRsp *) stats; + tpPESession pPeSessionEntry = NULL; + + //Get the Session Id based on Sta Id + pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId); + + //Fill the Session Id + if(NULL != pPeSessionEntry) + { + //Fill the Session Id + pPeStats->sessionId = pPeSessionEntry->smeSessionId; + } + + pPeStats->msgType = eWNI_SME_GET_ROAM_RSSI_RSP; + + //msgType should be WDA_GET_STATISTICS_RSP + mmhMsg.type = eWNI_SME_GET_ROAM_RSSI_RSP; + + mmhMsg.bodyptr = stats; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; + +} /*** end limSendSmePEGetRoamRssiRsp() ***/ + +#endif + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/** + * limSendSmePEEseTsmRsp() + * + *FUNCTION: + * This function is called to send tsm stats response to HDD. + * This function posts the result back to HDD. This is a response to + * HDD's request to get tsm stats. + * + *PARAMS: + * @param pMac - Pointer to global pMac structure + * @param pStats - Pointer to TSM Stats + * + * @return none + */ + +void +limSendSmePEEseTsmRsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats) +{ + tSirMsgQ mmhMsg; + tANI_U8 sessionId; + tAniGetTsmStatsRsp *pPeStats = (tAniGetTsmStatsRsp *) pStats; + tpPESession pPeSessionEntry = NULL; + + //Get the Session Id based on Sta Id + pPeSessionEntry = peFindSessionByStaId(pMac, pPeStats->staId, &sessionId); + + //Fill the Session Id + if(NULL != pPeSessionEntry) + { + //Fill the Session Id + pPeStats->sessionId = pPeSessionEntry->smeSessionId; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("Session not found for the Sta id(%d)"), + pPeStats->staId);) + return; + } + + pPeStats->msgType = eWNI_SME_GET_TSM_STATS_RSP; + pPeStats->tsmMetrics.RoamingCount = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingCount; + pPeStats->tsmMetrics.RoamingDly = pPeSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly; + + mmhMsg.type = eWNI_SME_GET_TSM_STATS_RSP; + mmhMsg.bodyptr = pStats; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} /*** end limSendSmePEEseTsmRsp() ***/ + +#endif /* FEATURE_WLAN_ESE) && FEATURE_WLAN_ESE_UPLOAD */ + + +void +limSendSmeIBSSPeerInd( + tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tANI_U16 staIndex, + tANI_U8 ucastIdx, + tANI_U8 bcastIdx, + tANI_U8 *beacon, + tANI_U16 beaconLen, + tANI_U16 msgType, + tANI_U8 sessionId) +{ + tSirMsgQ mmhMsg; + tSmeIbssPeerInd *pNewPeerInd; + + pNewPeerInd = vos_mem_malloc(sizeof(tSmeIbssPeerInd) + beaconLen); + if ( NULL == pNewPeerInd ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return; + } + + vos_mem_set((void *) pNewPeerInd, (sizeof(tSmeIbssPeerInd) + beaconLen), 0); + + vos_mem_copy( (tANI_U8 *) pNewPeerInd->peerAddr, + peerMacAddr, sizeof(tSirMacAddr)); + pNewPeerInd->staId= staIndex; + pNewPeerInd->ucastSig = ucastIdx; + pNewPeerInd->bcastSig = bcastIdx; + pNewPeerInd->mesgLen = sizeof(tSmeIbssPeerInd) + beaconLen; + pNewPeerInd->mesgType = msgType; + pNewPeerInd->sessionId = sessionId; + + if ( beacon != NULL ) + { + vos_mem_copy((void*) ((tANI_U8*)pNewPeerInd+sizeof(tSmeIbssPeerInd)), + (void*)beacon, beaconLen); + } + + mmhMsg.type = msgType; +// mmhMsg.bodyval = (tANI_U32) pNewPeerInd; + mmhMsg.bodyptr = pNewPeerInd; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, sessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} + + +/** ----------------------------------------------------------------- + \brief limSendExitBmpsInd() - sends exit bmps indication + + This function sends a eWNI_PMC_EXIT_BMPS_IND with a specific reason + code to SME. This will trigger SME to get out of BMPS mode. + + \param pMac - global mac structure + \param reasonCode - reason for which PE wish to exit BMPS + \return none + \sa + ----------------------------------------------------------------- */ +void limSendExitBmpsInd(tpAniSirGlobal pMac, tExitBmpsReason reasonCode) +{ + tSirMsgQ mmhMsg; + tANI_U16 msgLen = 0; + tpSirSmeExitBmpsInd pExitBmpsInd; + + msgLen = sizeof(tSirSmeExitBmpsInd); + pExitBmpsInd = vos_mem_malloc(msgLen); + if ( NULL == pExitBmpsInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for PMC_EXIT_BMPS_IND ")); + return; + } + vos_mem_set(pExitBmpsInd, msgLen, 0); + + pExitBmpsInd->mesgType = eWNI_PMC_EXIT_BMPS_IND; + pExitBmpsInd->mesgLen = msgLen; + pExitBmpsInd->exitBmpsReason = reasonCode; + pExitBmpsInd->statusCode = eSIR_SME_SUCCESS; + + mmhMsg.type = eWNI_PMC_EXIT_BMPS_IND; + mmhMsg.bodyptr = pExitBmpsInd; + mmhMsg.bodyval = 0; + + limLog(pMac, LOG1, FL("Sending eWNI_PMC_EXIT_BMPS_IND to SME. ")); + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT, peGetValidPowerSaveSession(pMac), 0, (tANI_U16)reasonCode); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + return; + +} /*** end limSendExitBmpsInd() ***/ + + + + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - Handle the Delete BSS Response from HAL. + + + \param pMac - pointer to global adapter context + \param sessionId - Message pointer. + + \sa + --------------------------------------------------------------------------*/ + +void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ) +{ + tpPESession psessionEntry; + tpDeleteBssParams pDelBss = (tpDeleteBssParams)(MsgQ->bodyptr); + if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + limIbssDelBssRsp(pMac, MsgQ->bodyptr,psessionEntry); + } + else if(psessionEntry->limSystemRole == eLIM_UNKNOWN_ROLE) + { + limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry); + } + else + limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry); +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** ----------------------------------------------------------------- + \brief limSendSmeAggrQosRsp() - sends SME FT AGGR QOS RSP + \ This function sends a eWNI_SME_FT_AGGR_QOS_RSP to SME. + \ SME only looks at rc and tspec field. + \param pMac - global mac structure + \param rspReqd - is SmeAddTsRsp required + \param status - status code of eWNI_SME_FT_AGGR_QOS_RSP + \return tspec + \sa + ----------------------------------------------------------------- */ +void +limSendSmeAggrQosRsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp, + tANI_U8 smesessionId) +{ + tSirMsgQ mmhMsg; + + mmhMsg.type = eWNI_SME_FT_AGGR_QOS_RSP; + mmhMsg.bodyptr = aggrQosRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, smesessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} +#endif + +/** ----------------------------------------------------------------- + \brief limSendSmePreChannelSwitchInd() - sends an indication to SME + before switching channels for spectrum manangement. + + This function sends a eWNI_SME_PRE_SWITCH_CHL_IND to SME. + + \param pMac - global mac structure + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmePreChannelSwitchInd(tpAniSirGlobal pMac) +{ + tSirMsgQ mmhMsg; + + mmhMsg.type = eWNI_SME_PRE_SWITCH_CHL_IND; + mmhMsg.bodyptr = NULL; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} + +/** ----------------------------------------------------------------- + \brief limSendSmePostChannelSwitchInd() - sends an indication to SME + after channel switch for spectrum manangement is complete. + + This function sends a eWNI_SME_POST_SWITCH_CHL_IND to SME. + + \param pMac - global mac structure + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmePostChannelSwitchInd(tpAniSirGlobal pMac) +{ + tSirMsgQ mmhMsg; + + mmhMsg.type = eWNI_SME_POST_SWITCH_CHL_IND; + mmhMsg.bodyptr = NULL; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} + +void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tANI_U8 smesessionId) +{ + tSirMsgQ mmhMsg; + tSmeMaxAssocInd *pSmeMaxAssocInd; + + pSmeMaxAssocInd = vos_mem_malloc(sizeof(tSmeMaxAssocInd)); + if ( NULL == pSmeMaxAssocInd ) + { + PELOGE(limLog(pMac, LOGE, FL("Failed to allocate memory"));) + return; + } + vos_mem_set((void *) pSmeMaxAssocInd, sizeof(tSmeMaxAssocInd),0); + vos_mem_copy( (tANI_U8 *)pSmeMaxAssocInd->peerMac, + (tANI_U8 *)peerMacAddr, sizeof(tSirMacAddr)); + pSmeMaxAssocInd->mesgType = eWNI_SME_MAX_ASSOC_EXCEEDED; + pSmeMaxAssocInd->mesgLen = sizeof(tSmeMaxAssocInd); + pSmeMaxAssocInd->sessionId = smesessionId; + mmhMsg.type = pSmeMaxAssocInd->mesgType; + mmhMsg.bodyptr = pSmeMaxAssocInd; + limLog(pMac, LOG1, FL("msgType %s peerMacAddr "MAC_ADDRESS_STR + " sme session id %d"), "eWNI_SME_MAX_ASSOC_EXCEEDED", MAC_ADDR_ARRAY(peerMacAddr),smesessionId); + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, smesessionId, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return; +} +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** ----------------------------------------------------------------- + \brief limSendSmeCandidateFoundInd() - sends + eWNI_SME_CANDIDATE_FOUND_IND + + After receiving candidate found indication frame from FW, this + function sends a eWNI_SME_CANDIDATE_FOUND_IND to SME to notify + roam candidate(s) are available. + + \param pMac - global mac structure + \param psessionEntry - session info + \return none + \sa + ----------------------------------------------------------------- */ +void +limSendSmeCandidateFoundInd(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tSirMsgQ mmhMsg; + tSirSmeCandidateFoundInd *pSirSmeCandidateFoundInd; + + pSirSmeCandidateFoundInd = vos_mem_malloc(sizeof(tSirSmeCandidateFoundInd)); + if ( NULL == pSirSmeCandidateFoundInd ) + { + limLog(pMac, LOGP, FL("AllocateMemory failed for eWNI_SME_CANDIDATE_FOUND_IND\n")); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ROAM_CANDIDATE_FOUND, + NULL, eSIR_SUCCESS, eSIR_SUCCESS); +#endif + + pSirSmeCandidateFoundInd->messageType = eWNI_SME_CANDIDATE_FOUND_IND; + pSirSmeCandidateFoundInd->length = sizeof(tSirSmeCandidateFoundInd); + pSirSmeCandidateFoundInd->sessionId = sessionId; + + + limLog( pMac, LOGE, FL("posting candidate ind to SME")); + mmhMsg.type = eWNI_SME_CANDIDATE_FOUND_IND; + mmhMsg.bodyptr = pSirSmeCandidateFoundInd; + mmhMsg.bodyval = 0; + + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} /*** end limSendSmeCandidateFoundInd() ***/ +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h new file mode 100644 index 000000000000..5f6f6cf14ae5 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSendSmeRspMessages.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limSendSmeRspMessages.h contains the definitions for + * sending SME response/notification messages to applications above + * MAC software. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_SEND_SME_RSP_H +#define __LIM_SEND_SME_RSP_H + +#include "sirCommon.h" +#include "sirApi.h" +#include "sirMacProtDef.h" + + +// Functions for sending responses to Host +void limSendSmeRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U8 , tANI_U16); +void limSendSmeStartBssRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16); +void limSendSmeScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void limSendSmeLfrScanRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8, tANI_U16); +#endif +void limPostSmeScanRspMessage(tpAniSirGlobal, tANI_U16, tSirResultCodes,tANI_U8,tANI_U16); +void limSendSmeAuthRsp(tpAniSirGlobal, tSirResultCodes, + tSirMacAddr, tAniAuthType, tANI_U16,tpPESession,tANI_U8,tANI_U16); + +void limSendSmeJoinReassocRsp(tpAniSirGlobal, tANI_U16, tSirResultCodes, tANI_U16,tpPESession,tANI_U8,tANI_U16); +void limSendSmeDisassocNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16,tANI_U8,tANI_U16,tpPESession); +void limSendSmeDeauthNtf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, tANI_U16, tANI_U16, tANI_U8, tANI_U16); +void limSendSmeDisassocInd(tpAniSirGlobal, tpDphHashNode,tpPESession); +void limSendSmeDeauthInd(tpAniSirGlobal, tpDphHashNode, tpPESession psessionEntry); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void limSendSmeCandidateFoundInd(tpAniSirGlobal, tANI_U8); +#endif + +void limSendSmeWmStatusChangeNtf(tpAniSirGlobal, tSirSmeStatusChangeCode, tANI_U32 *, tANI_U16, tANI_U8); +void limSendSmeSetContextRsp(tpAniSirGlobal, + tSirMacAddr, tANI_U16, tSirResultCodes,tpPESession,tANI_U8,tANI_U16); +void limSendSmePromiscuousModeRsp(tpAniSirGlobal pMac); +void limSendSmeNeighborBssInd(tpAniSirGlobal, + tLimScanResultNode *); +void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ); + +#ifdef WLAN_FEATURE_VOWIFI_11R +void +limSendSmeAggrQosRsp(tpAniSirGlobal pMac, tpSirAggrQosRsp aggrQosRsp, + tANI_U8 smesessionId); +#endif /*WLAN_FEATURE_VOWIFI_11R*/ + + +void limSendSmeAddtsRsp(tpAniSirGlobal pMac, tANI_U8 rspReqd, tANI_U32 status, tpPESession psessionEntry, tSirMacTspecIE tspec, tANI_U8 smesessionId, tANI_U16 smetransactionId); +void limSendSmeAddtsInd(tpAniSirGlobal pMac, tpSirAddtsReqInfo addts); +void limSendSmeDeltsRsp(tpAniSirGlobal pMac, tpSirDeltsReq delts, tANI_U32 status,tpPESession psessionEntry,tANI_U8 smessionId,tANI_U16 smetransactionId); +void limSendSmeDeltsInd(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, tANI_U16 aid,tpPESession); +void limSendSmeStatsRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats); + +void limSendSmePEStatisticsRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats); +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +void limSendSmePEGetRoamRssiRsp(tpAniSirGlobal pMac, tANI_U16 msgtype, void * stats); +#endif +#ifdef FEATURE_WLAN_ESE_UPLOAD +void limSendSmePEEseTsmRsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats); +#endif +void limSendSmeRemoveKeyRsp(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tSirResultCodes resultCode,tpPESession,tANI_U8,tANI_U16); + + +void limSendSmeGetTxPowerRsp(tpAniSirGlobal pMac, tANI_U32 power, tANI_U32 status); +void limSendSmeGetNoiseRsp(tpAniSirGlobal pMac, tSirMacNoise noise); +void limSendSmeIBSSPeerInd(tpAniSirGlobal pMac,tSirMacAddr peerMacAddr,tANI_U16 staIndex,tANI_U8 ucastIdx,tANI_U8 bcastIdx, + tANI_U8 *beacon,tANI_U16 beaconLen, tANI_U16 msgType, tANI_U8 sessionId); +void limSendExitBmpsInd(tpAniSirGlobal pMac, tExitBmpsReason reasonCode); + +#ifdef FEATURE_OEM_DATA_SUPPORT +void limSendSmeOemDataRsp(tpAniSirGlobal pMac, tANI_U32* pMsgBuf, tSirResultCodes resultCode); +#endif + +void limSendSmePreChannelSwitchInd(tpAniSirGlobal pMac); +void limSendSmePostChannelSwitchInd(tpAniSirGlobal pMac); +void limSendSmeMaxAssocExceededNtf(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tANI_U8 smesessionId); +#ifdef FEATURE_WLAN_TDLS +void limSendSmeTdlsDisRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode, tANI_U16 msgType); +void limSendSmeTdlsLinkStartRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode, tSirMacAddr peerMac, tANI_U16 msgType); +void limSendSmeTdlsTeardownRsp(tpAniSirGlobal pMac, tSirResultCodes statusCode, tSirMacAddr peerMac, tANI_U16 msgType); +void limSendSmeTdlsLinkEstablishReqRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status); +void limSendSmeTdlsChanSwitchReqRsp(tpAniSirGlobal pMac, + tANI_U8 sessionId, tSirMacAddr peerMac, tDphHashNode *pStaDs, + tANI_U8 status); +#endif + +#endif /* __LIM_SEND_SME_RSP_H */ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c new file mode 100644 index 000000000000..6e14ba5fe001 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.c @@ -0,0 +1,2917 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSerDesUtils.cc contains the serializer/deserializer + * utility functions LIM uses while communicating with upper layer + * software entities + * Author: Chandra Modumudi + * Date: 10/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "aniSystemDefs.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSerDesUtils.h" + + + +/** + * limCheckRemainingLength() + * + *FUNCTION: + * This function is called while de-serializing received SME_REQ + * message. + * + *LOGIC: + * Remaining message length is checked for > 0. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param len - Remaining message length + * @return retCode - eSIR_SUCCESS if len > 0, else eSIR_FAILURE + */ + +static inline tSirRetStatus +limCheckRemainingLength(tpAniSirGlobal pMac, tANI_S16 len) +{ + if (len > 0) + return eSIR_SUCCESS; + else + { + limLog(pMac, LOGW, + FL("Received SME message with invalid rem length=%d"), + len); + return eSIR_FAILURE; + } +} /*** end limCheckRemainingLength(pMac, ) ***/ + +/** + * limGetBssDescription() + * + *FUNCTION: + * This function is called by various LIM functions to copy + * BSS description from a tANI_U8* buffer pointer to tSirBssDescription + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBssDescription Pointer to the BssDescription to be copied + * @param *pBuf Pointer to the source buffer + * @param rLen Remaining message length being extracted + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * failure (eSIR_FAILURE). + */ + +static tSirRetStatus +limGetBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBssDescription, + tANI_S16 rLen, tANI_S16 *lenUsed, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + pBssDescription->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len = pBssDescription->length; + + if (rLen < (tANI_S16) (len + sizeof(tANI_U16))) + return eSIR_FAILURE; + + *lenUsed = len + sizeof(tANI_U16); + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pBssDescription->bssId, + pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract timer + vos_mem_copy( (tANI_U8 *) (&pBssDescription->scanSysTimeMsec), + pBuf, sizeof(v_TIME_t)); + pBuf += sizeof(v_TIME_t); + len -= sizeof(v_TIME_t); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract timeStamp + vos_mem_copy( (tANI_U8 *) pBssDescription->timeStamp, + pBuf, sizeof(tSirMacTimeStamp)); + pBuf += sizeof(tSirMacTimeStamp); + len -= sizeof(tSirMacTimeStamp); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract beaconInterval + pBssDescription->beaconInterval = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract capabilityInfo + pBssDescription->capabilityInfo = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract nwType + pBssDescription->nwType = (tSirNwType) limGetU32(pBuf); + pBuf += sizeof(tSirNwType); + len -= sizeof(tSirNwType); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract aniIndicator + pBssDescription->aniIndicator = *pBuf++; + len --; + + // Extract rssi + pBssDescription->rssi = (tANI_S8) *pBuf++; + len --; + + // Extract sinr + pBssDescription->sinr = (tANI_S8) *pBuf++; + len --; + + // Extract channelId + pBssDescription->channelId = *pBuf++; + len --; + + // Extract channelIdSelf + pBssDescription->channelIdSelf = *pBuf++; + len --; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract reserved bssDescription + pBuf += sizeof(pBssDescription->sSirBssDescriptionRsvd); + len -= sizeof(pBssDescription->sSirBssDescriptionRsvd); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //pass the timestamp + pBssDescription->nReceivedTime = limGetU32( pBuf ); + pBuf += sizeof(tANI_TIMESTAMP); + len -= sizeof(tANI_TIMESTAMP); + +#if defined WLAN_FEATURE_VOWIFI + //TSF when the beacon received (parent TSF) + pBssDescription->parentTSF = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + + //start TSF of scan during which this BSS desc was updated. + pBssDescription->startTSF[0] = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + + //start TSF of scan during which this BSS desc was updated. + pBssDescription->startTSF[1] = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + // MobilityDomain + pBssDescription->mdiePresent = *pBuf++; + len --; + pBssDescription->mdie[0] = *pBuf++; + len --; + pBssDescription->mdie[1] = *pBuf++; + len --; + pBssDescription->mdie[2] = *pBuf++; + len --; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + PELOGE(limLog(pMac, LOG1, FL("mdie=%02x %02x %02x"), + pBssDescription->mdie[0], + pBssDescription->mdie[1], + pBssDescription->mdie[2]);) +#endif +#endif + +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + /* Extract QBSSLoad_present */ + pBssDescription->QBSSLoad_present = *pBuf++; + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + /* Extract QBSS_ChanLoad */ + pBssDescription->QBSS_ChanLoad = *pBuf++; + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract QBSSLoad_avail + pBssDescription->QBSSLoad_avail = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; +#endif + pBssDescription->fProbeRsp = *pBuf++; + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + /* 3 reserved bytes for padding */ + pBuf += (3 * sizeof(tANI_U8)); + len -= 3; + + pBssDescription->WscIeLen = limGetU32( pBuf ); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + if (WSCIE_PROBE_RSP_LEN < len) + { + /* Do not copy with WscIeLen + * if WscIeLen is not set properly, memory overwrite happen + * Ended up with memory corruption and crash + * Copy with Fixed size */ + vos_mem_copy( (tANI_U8 *) pBssDescription->WscIeProbeRsp, + pBuf, + WSCIE_PROBE_RSP_LEN); + + } + else + { + limLog(pMac, LOGE, + FL("remaining bytes len %d is less than WSCIE_PROBE_RSP_LEN"), + pBssDescription->WscIeLen); + return eSIR_FAILURE; + } + + pBuf += (WSCIE_PROBE_RSP_LEN); + len -= (WSCIE_PROBE_RSP_LEN); + + /* Extract HTCapsPresent */ + pBssDescription->HTCapsPresent = *pBuf++; + len --; + + /* Extract vhtCapsPresent */ + pBssDescription->vhtCapsPresent = *pBuf++; + len --; + + /* Extract wmeInfoPresent */ + pBssDescription->wmeInfoPresent = *pBuf++; + len --; + + /* Extract beacomformingCapable */ + pBssDescription->beacomformingCapable = *pBuf++; + len --; + + /* Extract chanWidth */ + pBssDescription->chanWidth = *pBuf++; + len --; + + if (len > 0) + { + vos_mem_copy( (tANI_U8 *) pBssDescription->ieFields, + pBuf, + len); + } + else if (len < 0) + { + limLog(pMac, LOGE, + FL("remaining length is negative. len = %d, actual length = %d"), + len, pBssDescription->length); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end limGetBssDescription() ***/ + + + +/** + * limCopyBssDescription() + * + *FUNCTION: + * This function is called by various LIM functions to copy + * BSS description to a tANI_U8 buffer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param *pBuf Pointer to the destination buffer + * @param pBssDescription Pointer to the BssDescription being copied + * @return Length of BSSdescription written + */ + +tANI_U16 +limCopyBssDescription(tpAniSirGlobal pMac, tANI_U8 *pBuf, tSirBssDescription *pBssDescription) +{ + tANI_U16 len = 0; + + limCopyU16(pBuf, pBssDescription->length); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + + vos_mem_copy( pBuf, + (tANI_U8 *) pBssDescription->bssId, + sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len += sizeof(tSirMacAddr); + + PELOG3(limLog(pMac, LOG3, + FL("Copying BSSdescr:channel is %d, aniInd is %d, bssId is "), + pBssDescription->channelId, pBssDescription->aniIndicator); + limPrintMacAddr(pMac, pBssDescription->bssId, LOG3);) + + vos_mem_copy( pBuf, + (tANI_U8 *) (&pBssDescription->scanSysTimeMsec), + sizeof(v_TIME_t)); + pBuf += sizeof(v_TIME_t); + len += sizeof(v_TIME_t); + + limCopyU32(pBuf, pBssDescription->timeStamp[0]); + pBuf += sizeof(tANI_U32); + len += sizeof(tANI_U32); + + limCopyU32(pBuf, pBssDescription->timeStamp[1]); + pBuf += sizeof(tANI_U32); + len += sizeof(tANI_U32); + + limCopyU16(pBuf, pBssDescription->beaconInterval); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + + limCopyU16(pBuf, pBssDescription->capabilityInfo); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + + limCopyU32(pBuf, pBssDescription->nwType); + pBuf += sizeof(tANI_U32); + len += sizeof(tANI_U32); + + *pBuf++ = pBssDescription->aniIndicator; + len++; + + *pBuf++ = pBssDescription->rssi; + len++; + + *pBuf++ = pBssDescription->sinr; + len++; + + *pBuf++ = pBssDescription->channelId; + len++; + + vos_mem_copy( pBuf, (tANI_U8 *) &(pBssDescription->ieFields), + GET_IE_LEN_IN_BSS(pBssDescription->length)); + + return (len + sizeof(tANI_U16)); +} /*** end limCopyBssDescription() ***/ + + + + + +/** + * limGetKeysInfo() + * + *FUNCTION: + * This function is called by various LIM functions to copy + * key information from a tANI_U8* buffer pointer to tSirKeys + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param *pKeyInfo Pointer to the keyInfo to be copied + * @param *pBuf Pointer to the source buffer + * + * @return Length of key info extracted + */ + +static tANI_U32 +limGetKeysInfo(tpAniSirGlobal pMac, tpSirKeys pKeyInfo, tANI_U8 *pBuf) +{ + tANI_U32 len = 0; + + pKeyInfo->keyId = *pBuf++; + len++; + pKeyInfo->unicast = *pBuf++; + len++; + pKeyInfo->keyDirection = (tAniKeyDirection) limGetU32(pBuf); + len += sizeof(tAniKeyDirection); + pBuf += sizeof(tAniKeyDirection); + + vos_mem_copy( pKeyInfo->keyRsc, pBuf, WLAN_MAX_KEY_RSC_LEN); + pBuf += WLAN_MAX_KEY_RSC_LEN; + len += WLAN_MAX_KEY_RSC_LEN; + + pKeyInfo->paeRole = *pBuf++; + len++; + + pKeyInfo->keyLength = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len += sizeof(tANI_U16); + vos_mem_copy( pKeyInfo->key, pBuf, pKeyInfo->keyLength); + pBuf += pKeyInfo->keyLength; + len += pKeyInfo->keyLength; + + PELOG3(limLog(pMac, LOG3, + FL("Extracted keyId=%d, keyLength=%d, Key is :"), + pKeyInfo->keyId, pKeyInfo->keyLength); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, + pKeyInfo->key, pKeyInfo->keyLength);) + + return len; +} /*** end limGetKeysInfo() ***/ + + + +/** + * limStartBssReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_START_BSS_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pStartBssReq Pointer to tSirSmeStartBssReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limStartBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStartBssReq pStartBssReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pStartBssReq || !pBuf) + return eSIR_FAILURE; + + pStartBssReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pStartBssReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_START_BSS_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pStartBssReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pStartBssReq->transactionId = limGetU16( pBuf ); + pBuf += sizeof( tANI_U16 ); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pStartBssReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract selfMacAddr + vos_mem_copy( (tANI_U8 *) pStartBssReq->selfMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract beaconInterval + pStartBssReq->beaconInterval = limGetU16( pBuf ); + pBuf += sizeof( tANI_U16 ); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract dot11Mode + pStartBssReq->dot11mode = *pBuf++; + len --; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssType + pStartBssReq->bssType = (tSirBssType) limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract ssId + if (*pBuf > SIR_MAC_MAX_SSID_LENGTH) + { + // SSID length is more than max allowed 32 bytes + PELOGW(limLog(pMac, LOGW, FL("Invalid SSID length, len=%d"), *pBuf);) + return eSIR_FAILURE; + } + + pStartBssReq->ssId.length = *pBuf++; + len--; + if (len < pStartBssReq->ssId.length) + { + limLog(pMac, LOGW, + FL("SSID length is longer that the remaining length. SSID len=%d, remaining len=%d"), + pStartBssReq->ssId.length, len); + return eSIR_FAILURE; + } + + vos_mem_copy( (tANI_U8 *) pStartBssReq->ssId.ssId, + pBuf, + pStartBssReq->ssId.length); + pBuf += pStartBssReq->ssId.length; + len -= pStartBssReq->ssId.length; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract channelId + pStartBssReq->channelId = *pBuf++; + len--; + + // Extract CB secondary channel info + pStartBssReq->cbMode = (ePhyChanBondState)limGetU32( pBuf ); + pBuf += sizeof( tANI_U32 ); + len -= sizeof( tANI_U32 ); + + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + + // Extract privacy setting + pStartBssReq->privacy = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract Uapsd Enable + pStartBssReq->apUapsdEnable = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract SSID hidden + pStartBssReq->ssidHidden = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pStartBssReq->fwdWPSPBCProbeReq = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract HT Protection Enable + pStartBssReq->protEnabled = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + //Extract OBSS Protection Enable + pStartBssReq->obssProtEnabled = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pStartBssReq->ht_capab = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract AuthType + pStartBssReq->authType = (tSirBssType) limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract dtimPeriod + pStartBssReq->dtimPeriod = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract wps state + pStartBssReq->wps_state = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract isCoalesingInIBSSAllowed + pStartBssReq->isCoalesingInIBSSAllowed = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssPersona + pStartBssReq->bssPersona = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + + // Extract txLdpcIniFeatureEnabled + pStartBssReq->txLdpcIniFeatureEnabled = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + +#ifdef WLAN_FEATURE_11W + // Extract MFP capable/required + pStartBssReq->pmfCapable = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + pStartBssReq->pmfRequired = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; +#endif + + // Extract rsnIe + pStartBssReq->rsnIE.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + // Check for RSN IE length (that includes length of type & length + if (pStartBssReq->rsnIE.length > SIR_MAC_MAX_IE_LENGTH + 2) + { + limLog(pMac, LOGW, + FL("Invalid RSN IE length %d in SME_START_BSS_REQ"), + pStartBssReq->rsnIE.length); + return eSIR_FAILURE; + } + + vos_mem_copy( pStartBssReq->rsnIE.rsnIEdata, + pBuf, pStartBssReq->rsnIE.length); + + len -= (sizeof(tANI_U16) + pStartBssReq->rsnIE.length); + pBuf += pStartBssReq->rsnIE.length; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract nwType + pStartBssReq->nwType = (tSirNwType) limGetU32(pBuf); + pBuf += sizeof(tSirNwType); + len -= sizeof(tSirNwType); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract operationalRateSet + pStartBssReq->operationalRateSet.numRates = *pBuf++; + + // Check for number of rates + if (pStartBssReq->operationalRateSet.numRates > + SIR_MAC_MAX_NUMBER_OF_RATES) + { + limLog(pMac, LOGW, FL("Invalid numRates %d in SME_START_BSS_REQ"), + pStartBssReq->operationalRateSet.numRates); + return eSIR_FAILURE; + } + + len--; + if (len < pStartBssReq->operationalRateSet.numRates) + return eSIR_FAILURE; + + vos_mem_copy( (tANI_U8 *) pStartBssReq->operationalRateSet.rate, + pBuf, + pStartBssReq->operationalRateSet.numRates); + pBuf += pStartBssReq->operationalRateSet.numRates; + len -= pStartBssReq->operationalRateSet.numRates; + + // Extract extendedRateSet + if ((pStartBssReq->nwType == eSIR_11G_NW_TYPE) || + (pStartBssReq->nwType == eSIR_11N_NW_TYPE )) + { + pStartBssReq->extendedRateSet.numRates = *pBuf++; + len--; + vos_mem_copy( pStartBssReq->extendedRateSet.rate, + pBuf, pStartBssReq->extendedRateSet.numRates); + pBuf += pStartBssReq->extendedRateSet.numRates; + len -= pStartBssReq->extendedRateSet.numRates; + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + /* extract apHT40_24GEnabled */ + pStartBssReq->apHT40_24GEnabled = *pBuf++; + len--; +#endif + if (len) + { + limLog(pMac, LOGW, FL("Extra bytes left in SME_START_BSS_REQ, len=%d"), len); + } + + return eSIR_SUCCESS; +} /*** end limStartBssReqSerDes() ***/ + + + +/** + * limStopBssReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_STOP_BSS_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pStopBssReq Pointer to tSirSmeStopBssReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limStopBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStopBssReq pStopBssReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + pStopBssReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pStopBssReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_STOP_BSS_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pStopBssReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pStopBssReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + // Extract reasonCode + pStopBssReq->reasonCode = (tSirResultCodes) limGetU32(pBuf); + pBuf += sizeof(tSirResultCodes); + len -= sizeof(tSirResultCodes); + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pStopBssReq->bssId, pBuf, sizeof(tSirMacAddr)); + len -= sizeof(tSirMacAddr); + + if (len) + return eSIR_FAILURE; + else + return eSIR_SUCCESS; + +} /*** end limStopBssReqSerDes() ***/ + + + +/** + * limJoinReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_JOIN_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pJoinReq Pointer to tSirSmeJoinReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limJoinReqSerDes(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + tANI_S16 lenUsed = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pJoinReq || !pBuf) + { + PELOGE(limLog(pMac, LOGE, FL("pJoinReq or pBuf is NULL"));) + return eSIR_FAILURE; + } + + // Extract messageType + pJoinReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + // Extract length + len = pJoinReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (pJoinReq->messageType == eWNI_SME_JOIN_REQ) + PELOG1(limLog(pMac, LOG3, FL("SME_JOIN_REQ length %d bytes is:"), len);) + else + PELOG1(limLog(pMac, LOG3, FL("SME_REASSOC_REQ length %d bytes is:"), + len);) + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + { + PELOGE(limLog(pMac, LOGE, FL("len %d is too short"), len);) + return eSIR_FAILURE; + } + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + // Extract sessionId + pJoinReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + // Extract transactionId + pJoinReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract ssId + pJoinReq->ssId.length = *pBuf++; + len--; + vos_mem_copy( (tANI_U8 *) pJoinReq->ssId.ssId, pBuf, pJoinReq->ssId.length); + pBuf += pJoinReq->ssId.length; + len -= pJoinReq->ssId.length; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract selfMacAddr + vos_mem_copy( pJoinReq->selfMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract bsstype + pJoinReq->bsstype = (tSirBssType) limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract dot11mode + pJoinReq->dot11mode= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract bssPersona + pJoinReq->staPersona = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + pJoinReq->bOSENAssociation = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + pJoinReq->bWPSAssociation = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract cbMode + pJoinReq->cbMode = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + // Extract cbMode + pJoinReq->force_24ghz_in_ht20 = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // Extract uapsdPerAcBitmask + pJoinReq->uapsdPerAcBitmask = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + + // Extract operationalRateSet + pJoinReq->operationalRateSet.numRates= *pBuf++; + len--; + if (pJoinReq->operationalRateSet.numRates) + { + vos_mem_copy( (tANI_U8 *) pJoinReq->operationalRateSet.rate, pBuf, + pJoinReq->operationalRateSet.numRates); + pBuf += pJoinReq->operationalRateSet.numRates; + len -= pJoinReq->operationalRateSet.numRates; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + // Extract extendedRateSet + pJoinReq->extendedRateSet.numRates = *pBuf++; + len--; + if (pJoinReq->extendedRateSet.numRates) + { + vos_mem_copy( pJoinReq->extendedRateSet.rate, pBuf, pJoinReq->extendedRateSet.numRates); + pBuf += pJoinReq->extendedRateSet.numRates; + len -= pJoinReq->extendedRateSet.numRates; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + //Extract rateBitMap + pJoinReq->rateBitMap = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + // Extract RSN IE + pJoinReq->rsnIE.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + if (pJoinReq->rsnIE.length) + { + // Check for RSN IE length (that includes length of type & length) + if ((pJoinReq->rsnIE.length > SIR_MAC_MAX_IE_LENGTH + 2) || + (pJoinReq->rsnIE.length != 2 + *(pBuf + 1))) + { + limLog(pMac, LOGW, + FL("Invalid RSN IE length %d in SME_JOIN_REQ"), + pJoinReq->rsnIE.length); + return eSIR_FAILURE; + } + vos_mem_copy( (tANI_U8 *) pJoinReq->rsnIE.rsnIEdata, + pBuf, pJoinReq->rsnIE.length); + pBuf += pJoinReq->rsnIE.length; + len -= pJoinReq->rsnIE.length; // skip RSN IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + +#ifdef FEATURE_WLAN_ESE + // Extract CCKM IE + pJoinReq->cckmIE.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (pJoinReq->cckmIE.length) + { + // Check for CCKM IE length (that includes length of type & length) + if ((pJoinReq->cckmIE.length > SIR_MAC_MAX_IE_LENGTH) || + (pJoinReq->cckmIE.length != (2 + *(pBuf + 1)))) + { + limLog(pMac, LOGW, + FL("Invalid CCKM IE length %d/%d in SME_JOIN/REASSOC_REQ"), + pJoinReq->cckmIE.length, 2 + *(pBuf + 1)); + return eSIR_FAILURE; + } + vos_mem_copy((tANI_U8 *) pJoinReq->cckmIE.cckmIEdata, + pBuf, pJoinReq->cckmIE.length); + pBuf += pJoinReq->cckmIE.length; + len -= pJoinReq->cckmIE.length; // skip CCKM IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } +#endif + + // Extract Add IE for scan + pJoinReq->addIEScan.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + if (pJoinReq->addIEScan.length) + { + // Check for IE length (that includes length of type & length) + if (pJoinReq->addIEScan.length > SIR_MAC_MAX_ADD_IE_LENGTH + 2) + { + limLog(pMac, LOGE, + FL("Invalid addIE Scan length %d in SME_JOIN_REQ"), + pJoinReq->addIEScan.length); + return eSIR_FAILURE; + } + // Check for P2P IE length (that includes length of type & length) + vos_mem_copy( (tANI_U8 *) pJoinReq->addIEScan.addIEdata, + pBuf, pJoinReq->addIEScan.length); + pBuf += pJoinReq->addIEScan.length; + len -= pJoinReq->addIEScan.length; // skip add IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + pJoinReq->addIEAssoc.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + // Extract Add IE for assoc + if (pJoinReq->addIEAssoc.length) + { + // Check for IE length (that includes length of type & length) + if (pJoinReq->addIEAssoc.length > SIR_MAC_MAX_IE_LENGTH + 2) + { + limLog(pMac, LOGE, + FL("Invalid addIE Assoc length %d in SME_JOIN_REQ"), + pJoinReq->addIEAssoc.length); + return eSIR_FAILURE; + } + // Check for P2P IE length (that includes length of type & length) + vos_mem_copy( (tANI_U8 *) pJoinReq->addIEAssoc.addIEdata, + pBuf, pJoinReq->addIEAssoc.length); + pBuf += pJoinReq->addIEAssoc.length; + len -= pJoinReq->addIEAssoc.length; // skip add IE + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + } + + pJoinReq->UCEncryptionType = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + pJoinReq->MCEncryptionType = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#ifdef WLAN_FEATURE_11W + pJoinReq->MgmtEncryptionType = limGetU32(pBuf); + pBuf += sizeof(tANI_U32); + len -= sizeof(tANI_U32); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + //is11Rconnection; + pJoinReq->is11Rconnection = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#ifdef FEATURE_WLAN_ESE + //ESE version IE + pJoinReq->isESEFeatureIniEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //isESEconnection; + pJoinReq->isESEconnection = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // TSPEC information + pJoinReq->eseTspecInfo.numTspecs = *pBuf++; + len -= sizeof(tANI_U8); + vos_mem_copy((void*)&pJoinReq->eseTspecInfo.tspec[0], pBuf, + (sizeof(tTspecInfo)* pJoinReq->eseTspecInfo.numTspecs)); + pBuf += sizeof(tTspecInfo)*SIR_ESE_MAX_TSPEC_IES; + len -= sizeof(tTspecInfo)*SIR_ESE_MAX_TSPEC_IES; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + //isFastTransitionEnabled; + pJoinReq->isFastTransitionEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + +#ifdef FEATURE_WLAN_LFR + //isFastRoamIniFeatureEnabled; + pJoinReq->isFastRoamIniFeatureEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + + //txLdpcIniFeatureEnabled + pJoinReq->txLdpcIniFeatureEnabled= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#ifdef WLAN_FEATURE_11AC + //txBFIniFeatureEnabled + pJoinReq->txBFIniFeatureEnabled= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //txBFCsnValue + pJoinReq->txBFCsnValue= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + //MuBformee + pJoinReq->txMuBformee= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } +#endif + + pJoinReq->isAmsduSupportInAMPDU= *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + pJoinReq->isWMEenabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pJoinReq->isQosEnabled = (tAniBool)limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract Titan CB Neighbor BSS info + pJoinReq->cbNeighbors.cbBssFoundPri = *pBuf; + pBuf++; + pJoinReq->cbNeighbors.cbBssFoundSecUp = *pBuf; + pBuf++; + pJoinReq->cbNeighbors.cbBssFoundSecDown = *pBuf; + pBuf++; + len -= 3; + + // Extract Spectrum Mgt Indicator + pJoinReq->spectrumMgtIndicator = (tAniBool) limGetU32(pBuf); + pBuf += sizeof(tAniBool); + len -= sizeof(tAniBool); + + pJoinReq->powerCap.minTxPower = *pBuf++; + pJoinReq->powerCap.maxTxPower = *pBuf++; + len -=2; + + pJoinReq->supportedChannels.numChnl = *pBuf++; + len--; + vos_mem_copy( (tANI_U8 *) pJoinReq->supportedChannels.channelList, + pBuf, pJoinReq->supportedChannels.numChnl); + pBuf += pJoinReq->supportedChannels.numChnl; + len-= pJoinReq->supportedChannels.numChnl; + + limLog(pMac, LOG1, + FL("spectrumInd ON: minPower %d, maxPower %d , numChnls %d"), + pJoinReq->powerCap.minTxPower, + pJoinReq->powerCap.maxTxPower, + pJoinReq->supportedChannels.numChnl); + + // Extract uapsdPerAcBitmask + pJoinReq->uapsdPerAcBitmask = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + { + limLog(pMac, LOGE, FL("remaining len %d is too short"), len); + return eSIR_FAILURE; + } + + // + // NOTE - tSirBssDescription is now moved to the end + // of tSirSmeJoinReq structure. This is to accomodate + // the variable length data member ieFields[1] + // + if (limGetBssDescription( pMac, &pJoinReq->bssDescription, + len, &lenUsed, pBuf) == eSIR_FAILURE) + { + PELOGE(limLog(pMac, LOGE, FL("get bss description failed"));) + return eSIR_FAILURE; + } + PELOG3(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, + (tANI_U8 *) &(pJoinReq->bssDescription), + pJoinReq->bssDescription.length + 2);) + pBuf += lenUsed; + len -= lenUsed; + + return eSIR_SUCCESS; +} /*** end limJoinReqSerDes() ***/ + + +/**--------------------------------------------------------------- +\fn limAssocIndSerDes +\brief This function is called by limProcessMlmAssocInd() to +\ populate the SME_ASSOC_IND message based on the received +\ MLM_ASSOC_IND. +\ +\param pMac +\param pAssocInd - Pointer to the received tLimMlmAssocInd +\param pBuf - Pointer to serialized buffer +\param psessionEntry - pointer to PE session entry +\ +\return None +------------------------------------------------------------------*/ +void +limAssocIndSerDes(tpAniSirGlobal pMac, tpLimMlmAssocInd pAssocInd, tANI_U8 *pBuf, tpPESession psessionEntry) +{ + tANI_U8 *pLen = pBuf; + tANI_U16 mLen = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + + mLen = sizeof(tANI_U32); + mLen += sizeof(tANI_U8); + pBuf += sizeof(tANI_U16); + *pBuf = psessionEntry->smeSessionId; + pBuf += sizeof(tANI_U8); + + // Fill in peerMacAddr + vos_mem_copy( pBuf, pAssocInd->peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in aid + limCopyU16(pBuf, pAssocInd->aid); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + + // Fill in bssId + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + + // Fill in staId + limCopyU16(pBuf, psessionEntry->staId); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + + // Fill in authType + limCopyU32(pBuf, pAssocInd->authType); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); + + // Fill in ssId + vos_mem_copy( pBuf, (tANI_U8 *) &(pAssocInd->ssId), pAssocInd->ssId.length + 1); + pBuf += (1 + pAssocInd->ssId.length); + mLen += (1 + pAssocInd->ssId.length); + + // Fill in rsnIE + limCopyU16(pBuf, pAssocInd->rsnIE.length); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + vos_mem_copy( pBuf, (tANI_U8 *) &(pAssocInd->rsnIE.rsnIEdata), + pAssocInd->rsnIE.length); + pBuf += pAssocInd->rsnIE.length; + mLen += pAssocInd->rsnIE.length; + + + limCopyU32(pBuf, pAssocInd->spectrumMgtIndicator); + pBuf += sizeof(tAniBool); + mLen += sizeof(tAniBool); + + if (pAssocInd->spectrumMgtIndicator == eSIR_TRUE) + { + *pBuf = pAssocInd->powerCap.minTxPower; + pBuf++; + *pBuf = pAssocInd->powerCap.maxTxPower; + pBuf++; + mLen += sizeof(tSirMacPowerCapInfo); + + *pBuf = pAssocInd->supportedChannels.numChnl; + pBuf++; + mLen++; + + vos_mem_copy( pBuf, + (tANI_U8 *) &(pAssocInd->supportedChannels.channelList), + pAssocInd->supportedChannels.numChnl); + + + pBuf += pAssocInd->supportedChannels.numChnl; + mLen += pAssocInd->supportedChannels.numChnl; + } + limCopyU32(pBuf, pAssocInd->WmmStaInfoPresent); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); + +#ifdef WLAN_FEATURE_AP_HT40_24G + limCopyU32(pBuf, pAssocInd->HT40MHzIntoPresent); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); +#endif + + // Fill in length of SME_ASSOC_IND message + limCopyU16(pLen, mLen); + + PELOG1(limLog(pMac, LOG1, FL("Sending SME_ASSOC_IND length %d bytes:"), mLen);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);) +} /*** end limAssocIndSerDes() ***/ + + + +/** + * limAssocCnfSerDes() + * + *FUNCTION: + * This function is called by limProcessLmmMessages() when + * SME_ASSOC_CNF or SME_REASSOC_CNF message is received from + * upper layer software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pAssocCnf Pointer to tSirSmeAssocCnf being extracted into + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limAssocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeAssocCnf pAssocCnf, tANI_U8 *pBuf) +{ +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pAssocCnf || !pBuf) + return eSIR_FAILURE; + + pAssocCnf->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + pAssocCnf->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (pAssocCnf->messageType == eWNI_SME_ASSOC_CNF) + { + PELOG1(limLog(pMac, LOG1, FL("SME_ASSOC_CNF length %d bytes is:"), pAssocCnf->length);) + } + else + { + PELOG1(limLog(pMac, LOG1, FL("SME_REASSOC_CNF length %d bytes is:"), pAssocCnf->length);) + } + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, pAssocCnf->length);) + + // status code + pAssocCnf->statusCode = (tSirResultCodes) limGetU32(pBuf); + pBuf += sizeof(tSirResultCodes); + + // bssId + vos_mem_copy( pAssocCnf->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + // peerMacAddr + vos_mem_copy( pAssocCnf->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + + pAssocCnf->aid = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + // alternateBssId + vos_mem_copy( pAssocCnf->alternateBssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + // alternateChannelId + pAssocCnf->alternateChannelId = *pBuf; + pBuf++; + + return eSIR_SUCCESS; +} /*** end limAssocCnfSerDes() ***/ + + + +/** + * limDisassocCnfSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() when + * SME_DISASSOC_CNF message is received from upper layer software. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDisassocCnf Pointer to tSirSmeDisassocCnf being + * extracted into + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limDisassocCnfSerDes(tpAniSirGlobal pMac, tpSirSmeDisassocCnf pDisassocCnf, tANI_U8 *pBuf) +{ +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pDisassocCnf || !pBuf) + return eSIR_FAILURE; + + pDisassocCnf->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + pDisassocCnf->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_DISASSOC_CNF length %d bytes is:"), pDisassocCnf->length);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, pDisassocCnf->length);) + + pDisassocCnf->statusCode = (tSirResultCodes) limGetU32(pBuf); + pBuf += sizeof(tSirResultCodes); + + vos_mem_copy( pDisassocCnf->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + vos_mem_copy( pDisassocCnf->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + + pDisassocCnf->assocId = limGetU16(pBuf); + + return eSIR_SUCCESS; +} /*** end limDisassocCnfSerDes() ***/ + +static inline int CheckRemainingLength(tANI_U16 mLen, tANI_U16 len) +{ + if (mLen > (len - sizeof(tANI_U16))) + return eSIR_FAILURE; + + return eSIR_SUCCESS; +} + +/**--------------------------------------------------------------- +\fn limReassocIndSerDes +\brief This function is called by limProcessMlmReassocInd() to +\ populate the SME_REASSOC_IND message based on the received +\ MLM_REASSOC_IND. +\ +\param pMac +\param pReassocInd - Pointer to the received tLimMlmReassocInd +\param pBuf - Pointer to serialized buffer +\param psessionEntry - pointer to PE session entry +\param len - size of tSirSmeReassocInd structure +\ +\return tSirRietStatus Indicates whether message is successfully +\ de-serialized (eSIR_SUCCESS) or +\ not (eSIR_FAILURE) +------------------------------------------------------------------*/ +tSirRetStatus +limReassocIndSerDes(tpAniSirGlobal pMac, tpLimMlmReassocInd pReassocInd, + tANI_U8 *pBuf, tpPESession psessionEntry, tANI_U16 len) +{ + tANI_U8 *pLen = pBuf; + tANI_U16 mLen = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + + mLen = sizeof(tANI_U32); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pBuf += sizeof(tANI_U16); + *pBuf++ = psessionEntry->smeSessionId; + mLen += sizeof(tANI_U8); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in peerMacAddr + vos_mem_copy( pBuf, pReassocInd->peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in oldMacAddr + vos_mem_copy( pBuf, pReassocInd->currentApAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in aid + limCopyU16(pBuf, pReassocInd->aid); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in bssId + vos_mem_copy( pBuf, psessionEntry->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in staId + limCopyU16(pBuf, psessionEntry->staId); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in authType + limCopyU32(pBuf, pReassocInd->authType); + pBuf += sizeof(tAniAuthType); + mLen += sizeof(tAniAuthType); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in ssId + vos_mem_copy( pBuf, (tANI_U8 *) &(pReassocInd->ssId), + pReassocInd->ssId.length + 1); + pBuf += 1 + pReassocInd->ssId.length; + mLen += pReassocInd->ssId.length + 1; + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in rsnIE + limCopyU16(pBuf, pReassocInd->rsnIE.length); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + vos_mem_copy( pBuf, (tANI_U8 *) &(pReassocInd->rsnIE.rsnIEdata), + pReassocInd->rsnIE.length); + pBuf += pReassocInd->rsnIE.length; + mLen += pReassocInd->rsnIE.length; + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in addIE + limCopyU16(pBuf, pReassocInd->addIE.length); + pBuf += sizeof(tANI_U16); + mLen += sizeof(tANI_U16); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + vos_mem_copy( pBuf, (tANI_U8*) &(pReassocInd->addIE.addIEdata), + pReassocInd->addIE.length); + pBuf += pReassocInd->addIE.length; + mLen += pReassocInd->addIE.length; + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + limCopyU32(pBuf, pReassocInd->spectrumMgtIndicator); + pBuf += sizeof(tAniBool); + mLen += sizeof(tAniBool); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + if (pReassocInd->spectrumMgtIndicator == eSIR_TRUE) + { + *pBuf = pReassocInd->powerCap.minTxPower; + pBuf++; + *pBuf = pReassocInd->powerCap.maxTxPower; + pBuf++; + mLen += sizeof(tSirMacPowerCapInfo); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + *pBuf = pReassocInd->supportedChannels.numChnl; + pBuf++; + mLen++; + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + vos_mem_copy( pBuf, + (tANI_U8 *) &(pReassocInd->supportedChannels.channelList), + pReassocInd->supportedChannels.numChnl); + + pBuf += pReassocInd->supportedChannels.numChnl; + mLen += pReassocInd->supportedChannels.numChnl; + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + } + limCopyU32(pBuf, pReassocInd->WmmStaInfoPresent); + pBuf += sizeof(tANI_U32); + mLen += sizeof(tANI_U32); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Fill in length of SME_REASSOC_IND message + limCopyU16(pLen, mLen); + + PELOG1(limLog(pMac, LOG1, FL("Sending SME_REASSOC_IND length %d bytes:"), mLen);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);) + + return eSIR_SUCCESS; +} /*** end limReassocIndSerDes() ***/ + + +/** + * limAuthIndSerDes() + * + *FUNCTION: + * This function is called by limProcessMlmAuthInd() while sending + * SME_AUTH_IND to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pAuthInd Pointer to tSirSmeAuthInd being sent + * @param pBuf Pointer to serialized buffer + * @param len size of tSirSmeAuthInd structure + * + * @return tSirRetStatus Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limAuthIndSerDes(tpAniSirGlobal pMac, tpLimMlmAuthInd pAuthInd, tANI_U8 *pBuf, tANI_U16 len) +{ + tANI_U8 *pLen = pBuf; + tANI_U16 mLen = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + mLen = sizeof(tANI_U32); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + pBuf += sizeof(tANI_U16); + *pBuf++ = pAuthInd->sessionId; + mLen += sizeof(tANI_U8); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // BTAMP TODO: Fill in bssId + vos_mem_set(pBuf, sizeof(tSirMacAddr), 0); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + vos_mem_copy( pBuf, pAuthInd->peerMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + mLen += sizeof(tSirMacAddr); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + limCopyU32(pBuf, pAuthInd->authType); + pBuf += sizeof(tAniAuthType); + mLen += sizeof(tAniAuthType); + if (CheckRemainingLength(mLen, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + limCopyU16(pLen, mLen); + + PELOG1(limLog(pMac, LOG1, FL("Sending SME_AUTH_IND length %d bytes:"), mLen);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, mLen);) + + return eSIR_SUCCESS; +} /*** end limAuthIndSerDes() ***/ + + + +/** + * limSetContextReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_SETCONTEXT_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pSetContextReq Pointer to tSirSmeSetContextReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limSetContextReqSerDes(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + tANI_U16 totalKeySize = sizeof(tANI_U8); // initialized to sizeof numKeys + tANI_U8 numKeys; + tANI_U8 *pKeys; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + if (!pSetContextReq || !pBuf) + return eSIR_FAILURE; + + pSetContextReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pSetContextReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_SETCONTEXT_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG3, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pSetContextReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pSetContextReq->transactionId = sirReadU16N(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + vos_mem_copy( (tANI_U8 *) pSetContextReq->peerMacAddr, + pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + vos_mem_copy( pSetContextReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + +// pSetContextReq->qosInfoPresent = limGetU32(pBuf); +// pBuf += sizeof(tAniBool); + +// if (pSetContextReq->qosInfoPresent) +// { +// len = limGetQosInfo(&pSetContextReq->qos, pBuf); +// pBuf += len; +// } + + pSetContextReq->keyMaterial.length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pSetContextReq->keyMaterial.edType = (tAniEdType) limGetU32(pBuf); + pBuf += sizeof(tAniEdType); + len -= sizeof(tAniEdType); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + numKeys = pSetContextReq->keyMaterial.numKeys = *pBuf++; + len -= sizeof(numKeys); + + if (numKeys > SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS) + return eSIR_FAILURE; + + /** Initialize the Default Keys if no Keys are being sent from the upper layer*/ + if( limCheckRemainingLength(pMac, len) == eSIR_FAILURE) { + tpSirKeys pKeyinfo = pSetContextReq->keyMaterial.key; + + pKeyinfo->keyId = 0; + pKeyinfo->keyDirection = eSIR_TX_RX; + pKeyinfo->keyLength = 0; + + if (!limIsAddrBC(pSetContextReq->peerMacAddr)) + pKeyinfo->unicast = 1; + else + pKeyinfo->unicast = 0; + }else { + pKeys = (tANI_U8 *) pSetContextReq->keyMaterial.key; + do { + tANI_U32 keySize = limGetKeysInfo(pMac, (tpSirKeys) pKeys, + pBuf); + vos_mem_zero(pBuf, keySize); + pBuf += keySize; + pKeys += sizeof(tSirKeys); + totalKeySize += (tANI_U16) keySize; + if (numKeys == 0) + break; + numKeys--; + }while (numKeys); + } + return eSIR_SUCCESS; +} /*** end limSetContextReqSerDes() ***/ + +/** + * limRemoveKeyReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_REMOVEKEY_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pRemoveKeyReq Pointer to tSirSmeRemoveKeyReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limRemoveKeyReqSerDes(tpAniSirGlobal pMac, tpSirSmeRemoveKeyReq pRemoveKeyReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + if (!pRemoveKeyReq || !pBuf) + return eSIR_FAILURE; + + pRemoveKeyReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pRemoveKeyReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_REMOVEKEY_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + vos_mem_copy( (tANI_U8 *) pRemoveKeyReq->peerMacAddr, + pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + + pRemoveKeyReq->edType = *pBuf; + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pRemoveKeyReq->wepType = *pBuf; + + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pRemoveKeyReq->keyId = *pBuf; + + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pRemoveKeyReq->unicast = *pBuf; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( pRemoveKeyReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pRemoveKeyReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pRemoveKeyReq->transactionId = sirReadU16N(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + return eSIR_SUCCESS; +} /*** end limRemoveKeyReqSerDes() ***/ + + + +/** + * limDisassocReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_DISASSOC_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDisassocReq Pointer to tSirSmeDisassocReq being extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limDisassocReqSerDes(tpAniSirGlobal pMac, tSirSmeDisassocReq *pDisassocReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pDisassocReq || !pBuf) + return eSIR_FAILURE; + + pDisassocReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pDisassocReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_DISASSOC_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionID + pDisassocReq->sessionId = *pBuf; + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionid + pDisassocReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pDisassocReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract peerMacAddr + vos_mem_copy( pDisassocReq->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract reasonCode + pDisassocReq->reasonCode = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + pDisassocReq->doNotSendOverTheAir = *pBuf; + pBuf += sizeof(tANI_U8); + len -= sizeof(tANI_U8); + + + return eSIR_SUCCESS; +} /*** end limDisassocReqSerDes() ***/ + + + +/** + * limDeauthReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * SME_DEAUTH_REQ from host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pDeauthReq Pointer to tSirSmeDeauthReq being extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ +tSirRetStatus +limDeauthReqSerDes(tpAniSirGlobal pMac, tSirSmeDeauthReq *pDeauthReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + if (!pDeauthReq || !pBuf) + return eSIR_FAILURE; + + pDeauthReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pDeauthReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_DEAUTH_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pDeauthReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pDeauthReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( pDeauthReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract peerMacAddr + vos_mem_copy( pDeauthReq->peerMacAddr, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract reasonCode + pDeauthReq->reasonCode = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + + + return eSIR_SUCCESS; +} /*** end limDisassocReqSerDes() ***/ + + + + + + +/** + * limStatSerDes() + * + *FUNCTION: + * This function is called by limSendSmeDisassocNtf() while sending + * SME_DISASSOC_IND/eWNI_SME_DISASSOC_RSP to host + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pAssocInd Pointer to tpAniStaStatStruct being sent + * @param pBuf Pointer to serialized buffer + * + * @return None + */ + +void +limStatSerDes(tpAniSirGlobal pMac, tpAniStaStatStruct pStat, tANI_U8 *pBuf) +{ +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + limCopyU32(pBuf, pStat->sentAesBlksUcastHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->sentAesBlksUcastLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->recvAesBlksUcastHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->recvAesBlksUcastLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->aesFormatErrorUcastCnts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->aesReplaysUcast); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->aesDecryptErrUcast); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->singleRetryPkts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->failedTxPkts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->ackTimeouts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->multiRetryPkts); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->fragTxCntsHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->fragTxCntsLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->transmittedPktsHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->transmittedPktsLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->phyStatHi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->phyStatLo); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->uplinkRssi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->uplinkSinr); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->uplinkRate); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->downlinkRssi); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->downlinkSinr); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->downlinkRate); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->nRcvBytes); + pBuf += sizeof(tANI_U32); + + limCopyU32(pBuf, pStat->nXmitBytes); + pBuf += sizeof(tANI_U32); + + PELOG1(limLog(pMac, LOG1, FL("STAT: length %d bytes is:"), sizeof(tAniStaStatStruct));) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, sizeof(tAniStaStatStruct));) + +} /*** end limStatSerDes() ***/ + + + + +/** + * limPackBkgndScanFailNotify() + * + *FUNCTION: + * This function is called by limSendSmeWmStatusChangeNtf() + * to pack the tSirBackgroundScanInfo message + * + */ +void +limPackBkgndScanFailNotify(tpAniSirGlobal pMac, + tSirSmeStatusChangeCode statusChangeCode, + tpSirBackgroundScanInfo pScanInfo, + tSirSmeWmStatusChangeNtf *pSmeNtf, + tANI_U8 sessionId) +{ + + tANI_U16 length = (sizeof(tANI_U16) * 2) + sizeof(tANI_U8) + + sizeof(tSirSmeStatusChangeCode) + + sizeof(tSirBackgroundScanInfo); + + pSmeNtf->messageType = eWNI_SME_WM_STATUS_CHANGE_NTF; + pSmeNtf->statusChangeCode = statusChangeCode; + pSmeNtf->length = length; + pSmeNtf->sessionId = sessionId; + pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanSuccess = pScanInfo->numOfScanSuccess; + pSmeNtf->statusChangeInfo.bkgndScanInfo.numOfScanFailure = pScanInfo->numOfScanFailure; + pSmeNtf->statusChangeInfo.bkgndScanInfo.reserved = pScanInfo->reserved; +} + + +/** + * limIsSmeGetAssocSTAsReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_GET_ASSOC_STAS_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pBuf - Pointer to a serialized SME_GET_ASSOC_STAS_REQ message + * @param pSmeMsg - Pointer to a tSirSmeGetAssocSTAsReq structure + * @return true if SME_GET_ASSOC_STAS_REQ message is formatted correctly + * false otherwise + */ +tANI_BOOLEAN +limIsSmeGetAssocSTAsReqValid(tpAniSirGlobal pMac, tpSirSmeGetAssocSTAsReq pGetAssocSTAsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + pGetAssocSTAsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pGetAssocSTAsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eANI_BOOLEAN_FALSE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eANI_BOOLEAN_FALSE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pGetAssocSTAsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eANI_BOOLEAN_FALSE; + + // Extract modId + pGetAssocSTAsReq->modId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eANI_BOOLEAN_FALSE; + + // Extract pUsrContext + vos_mem_copy((tANI_U8 *)pGetAssocSTAsReq->pUsrContext, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eANI_BOOLEAN_FALSE; + + // Extract pSapEventCallback + vos_mem_copy((tANI_U8 *)pGetAssocSTAsReq->pSapEventCallback, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eANI_BOOLEAN_FALSE; + + // Extract pAssocStasArray + vos_mem_copy((tANI_U8 *)pGetAssocSTAsReq->pAssocStasArray, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + + PELOG1(limLog(pMac, LOG1, FL("SME_GET_ASSOC_STAS_REQ length consumed %d bytes "), len);) + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_GET_ASSOC_STAS_REQ invalid length"));) + return eANI_BOOLEAN_FALSE; + } + + return eANI_BOOLEAN_TRUE; +} + +/** + * limTkipCntrMeasReqSerDes() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() upon receiving + * eWNI_SME_TKIP_CNTR_MEAS_REQ from host HDD + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param tpSirSmeTkipCntrMeasReq Pointer to tSirSmeTkipCntrMeasReq being extracted + * @param pBuf Pointer to serialized buffer + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ +tSirRetStatus +limTkipCntrMeasReqSerDes(tpAniSirGlobal pMac, tpSirSmeTkipCntrMeasReq pTkipCntrMeasReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + +#ifdef PE_DEBUG_LOG1 + tANI_U8 *pTemp = pBuf; +#endif + + pTkipCntrMeasReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pTkipCntrMeasReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + PELOG1(limLog(pMac, LOG1, FL("SME_TKIP_CNTR_MEAS_REQ length %d bytes is:"), len);) + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pTemp, len);) + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pTkipCntrMeasReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pTkipCntrMeasReq->transactionId = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + len -= sizeof(tANI_U16); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pTkipCntrMeasReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bEnable + pTkipCntrMeasReq->bEnable = *pBuf++; + len --; + + PELOG1(limLog(pMac, LOG1, FL("SME_TKIP_CNTR_MEAS_REQ length consumed %d bytes "), len);) + + if (len) + { + PELOGE(limLog(pMac, LOGE, FL("SME_TKIP_CNTR_MEAS_REQ invalid "));) + return eSIR_FAILURE; + } + else + return eSIR_SUCCESS; +} + +/** + * limIsSmeGetWPSPBCSessionsReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeGetWPSPBCSessions() upon + * receiving query WPS PBC overlap information message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pBuf - Pointer to a serialized SME_GET_WPSPBC_SESSION_REQ message + * @param pGetWPSPBCSessionsReq - Pointer to a tSirSmeGetWPSPBCSessionsReq structure + * @return true if SME_GET_WPSPBC_SESSION_REQ message is formatted correctly + * false otherwise + */ + +tSirRetStatus +limIsSmeGetWPSPBCSessionsReqValid(tpAniSirGlobal pMac, tSirSmeGetWPSPBCSessionsReq *pGetWPSPBCSessionsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirSmeGetWPSPBCSessionsReq));) + + pGetWPSPBCSessionsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pGetWPSPBCSessionsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pUsrContext + vos_mem_copy((tANI_U8 *)pGetWPSPBCSessionsReq->pUsrContext, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract pSapEventCallback + vos_mem_copy((tANI_U8 *)pGetWPSPBCSessionsReq->pSapEventCallback, pBuf, sizeof(void*)); + pBuf += sizeof(void*); + len -= sizeof(void*); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pGetWPSPBCSessionsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + + // Extract MAC address of Station to be removed + vos_mem_copy( (tANI_U8 *) pGetWPSPBCSessionsReq->pRemoveMac, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + + PELOG1(limLog(pMac, LOG1, FL("SME_GET_ASSOC_STAS_REQ length consumed %d bytes "), len);) + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_GET_WPSPBC_SESSION_REQ invalid length"));) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + + +/**--------------------------------------------------------------- +\fn limGetSessionInfo +\brief This function returns the sessionId and transactionId +\ of a message. This assumes that the message structure +\ is of format: +\ tANI_U16 messageType +\ tANI_U16 messageLength +\ tANI_U8 sessionId +\ tANI_U16 transactionId +\param pMac - pMac global structure +\param *pBuf - pointer to the message buffer +\param sessionId - returned session id value +\param transactionId - returned transaction ID value +\return None +------------------------------------------------------------------*/ +void +limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *sessionId, tANI_U16 *transactionId) +{ + if (!pBuf) + { + limLog(pMac, LOGE, FL("NULL ptr received. ")); + return; + } + + pBuf += sizeof(tANI_U16); // skip message type + pBuf += sizeof(tANI_U16); // skip message length + + *sessionId = *pBuf; // get sessionId + pBuf++; + *transactionId = limGetU16(pBuf); // get transactionId + + return; +} + + +/** + * limUpdateAPWPSIEsReqSerDes() + * + *FUNCTION: + * This function is to deserialize UpdateAPWPSIEs message + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pUpdateAPWPSIEsReq Pointer to tSirUpdateAPWPSIEsReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limUpdateAPWPSIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirUpdateAPWPSIEsReq));) + + if (!pUpdateAPWPSIEsReq || !pBuf) + return eSIR_FAILURE; + + pUpdateAPWPSIEsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pUpdateAPWPSIEsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pUpdateAPWPSIEsReq->transactionId = limGetU16( pBuf ); + pBuf += sizeof( tANI_U16 ); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pUpdateAPWPSIEsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pUpdateAPWPSIEsReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract APWPSIEs + vos_mem_copy( (tSirAPWPSIEs *) &pUpdateAPWPSIEsReq->APWPSIEs, pBuf, sizeof(tSirAPWPSIEs)); + pBuf += sizeof(tSirAPWPSIEs); + len -= sizeof(tSirAPWPSIEs); + + PELOG1(limLog(pMac, LOG1, FL("SME_UPDATE_APWPSIE_REQ length consumed %d bytes "), len);) + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_UPDATE_APWPSIE_REQ invalid length"));) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end limSetContextReqSerDes() ***/ + +/** + * limUpdateAPWPARSNIEsReqSerDes () + * + *FUNCTION: + * This function is to deserialize UpdateAPWPSIEs message + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pUpdateAPWPARSNIEsReq Pointer to tpSirUpdateAPWPARSNIEsReq being + * extracted + * @param pBuf Pointer to serialized buffer + * + * @return retCode Indicates whether message is successfully + * de-serialized (eSIR_SUCCESS) or + * not (eSIR_FAILURE) + */ + +tSirRetStatus +limUpdateAPWPARSNIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq, tANI_U8 *pBuf) +{ + tANI_S16 len = 0; + + PELOG1(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG1, pBuf, sizeof(tSirUpdateAPWPARSNIEsReq));) + + if (!pUpdateAPWPARSNIEsReq || !pBuf) + return eSIR_FAILURE; + + pUpdateAPWPARSNIEsReq->messageType = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + len = pUpdateAPWPARSNIEsReq->length = limGetU16(pBuf); + pBuf += sizeof(tANI_U16); + + if (len < (tANI_S16) sizeof(tANI_U32)) + return eSIR_FAILURE; + + len -= sizeof(tANI_U32); // skip message header + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract transactionId + pUpdateAPWPARSNIEsReq->transactionId = limGetU16( pBuf ); + pBuf += sizeof(tANI_U16); + len -= sizeof( tANI_U16 ); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract bssId + vos_mem_copy( (tANI_U8 *) pUpdateAPWPARSNIEsReq->bssId, pBuf, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + len -= sizeof(tSirMacAddr); + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract sessionId + pUpdateAPWPARSNIEsReq->sessionId = *pBuf++; + len--; + if (limCheckRemainingLength(pMac, len) == eSIR_FAILURE) + return eSIR_FAILURE; + + // Extract APWPARSNIEs + vos_mem_copy( (tSirRSNie *) &pUpdateAPWPARSNIEsReq->APWPARSNIEs, pBuf, sizeof(tSirRSNie)); + pBuf += sizeof(tSirRSNie); + len -= sizeof(tSirRSNie); + + if (len < 0) + { + PELOGE(limLog(pMac, LOGE, FL("SME_GET_WPSPBC_SESSION_REQ invalid length"));) + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} /*** end limUpdateAPWPARSNIEsReqSerDes() ***/ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h new file mode 100644 index 000000000000..29aff5a85198 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSerDesUtils.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSerDesUtils.h contains the utility definitions + * LIM uses while processing messages from upper layer software + * modules + * Author: Chandra Modumudi + * Date: 10/20/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SERDES_UTILS_H +#define __LIM_SERDES_UTILS_H + +#include "sirApi.h" +#include "aniSystemDefs.h" +#include "sirMacProtDef.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limPropExtsUtils.h" + +tSirRetStatus limStartBssReqSerDes(tpAniSirGlobal, tpSirSmeStartBssReq, tANI_U8 *); +tSirRetStatus limStopBssReqSerDes(tpAniSirGlobal, tpSirSmeStopBssReq, tANI_U8 *); +tSirRetStatus limJoinReqSerDes(tpAniSirGlobal, tpSirSmeJoinReq, tANI_U8 *); +void limAssocIndSerDes(tpAniSirGlobal, tpLimMlmAssocInd, tANI_U8 *, tpPESession); +tSirRetStatus limReassocIndSerDes(tpAniSirGlobal, tpLimMlmReassocInd, tANI_U8 *, + tpPESession psessionEntry, tANI_U16 len); +tSirRetStatus limAssocCnfSerDes(tpAniSirGlobal, tpSirSmeAssocCnf, tANI_U8 *); +tSirRetStatus limDisassocCnfSerDes(tpAniSirGlobal, tpSirSmeDisassocCnf, tANI_U8 *); +tSirRetStatus limSetContextReqSerDes(tpAniSirGlobal, tpSirSmeSetContextReq, tANI_U8 *); +tSirRetStatus limDisassocReqSerDes(tpAniSirGlobal, tSirSmeDisassocReq *, tANI_U8 *); +tSirRetStatus limDeauthReqSerDes(tpAniSirGlobal, tSirSmeDeauthReq *, tANI_U8 *); +tSirRetStatus limAuthIndSerDes(tpAniSirGlobal, tpLimMlmAuthInd, tANI_U8 *, + tANI_U16 len); +void limStatSerDes(tpAniSirGlobal, tpAniStaStatStruct, tANI_U8 *); +void limGetSessionInfo(tpAniSirGlobal pMac, tANI_U8 *, tANI_U8 *, tANI_U16 *); + + +void limPackBkgndScanFailNotify(tpAniSirGlobal, tSirSmeStatusChangeCode, + tpSirBackgroundScanInfo, tSirSmeWmStatusChangeNtf *, tANI_U8); + + +tSirRetStatus limRemoveKeyReqSerDes(tpAniSirGlobal pMac, tpSirSmeRemoveKeyReq pRemoveKeyReq, tANI_U8 * pBuf); + +tANI_BOOLEAN limIsSmeGetAssocSTAsReqValid(tpAniSirGlobal pMac, tpSirSmeGetAssocSTAsReq pGetAssocSTAsReq, tANI_U8 *pBuf); +tSirRetStatus limTkipCntrMeasReqSerDes(tpAniSirGlobal pMac, tpSirSmeTkipCntrMeasReq ptkipCntrMeasReq, tANI_U8 *pBuf); + +tSirRetStatus limUpdateAPWPSIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPSIEsReq pUpdateAPWPSIEsReq, tANI_U8 *pBuf); +tSirRetStatus limUpdateAPWPARSNIEsReqSerDes(tpAniSirGlobal pMac, tpSirUpdateAPWPARSNIEsReq pUpdateAPWPARSNIEsReq, tANI_U8 *pBuf); + + +// Byte String <--> tANI_U16/tANI_U32 copy functions +static inline void limCopyU16(tANI_U8 *ptr, tANI_U16 u16Val) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + *ptr++ = (tANI_U8) (u16Val & 0xff); + *ptr = (tANI_U8) ((u16Val >> 8) & 0xff); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +static inline tANI_U16 limGetU16(tANI_U8 *ptr) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + return (((tANI_U16) (*(ptr+1) << 8)) | + ((tANI_U16) (*ptr))); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +static inline void limCopyU32(tANI_U8 *ptr, tANI_U32 u32Val) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + *ptr++ = (tANI_U8) (u32Val & 0xff); + *ptr++ = (tANI_U8) ((u32Val >> 8) & 0xff); + *ptr++ = (tANI_U8) ((u32Val >> 16) & 0xff); + *ptr = (tANI_U8) ((u32Val >> 24) & 0xff); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +static inline tANI_U32 limGetU32(tANI_U8 *ptr) +{ +#if ((defined(ANI_OS_TYPE_QNX) && defined(ANI_LITTLE_BYTE_ENDIAN)) || \ + (defined(ANI_OS_TYPE_ANDROID) && defined(ANI_LITTLE_BYTE_ENDIAN))) + return ((*(ptr+3) << 24) | + (*(ptr+2) << 16) | + (*(ptr+1) << 8) | + (*(ptr))); +#else +#error "Unknown combination of OS Type and endianess" +#endif +} + +#endif /* __LIM_SERDES_UTILS_H */ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c new file mode 100644 index 000000000000..23c53bd616d7 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSession.c @@ -0,0 +1,558 @@ +/* + * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limSession.c + + \brief implementation for lim Session related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "aniGlobal.h" +#include "limDebug.h" +#include "limSession.h" +#include "limUtils.h" +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "eseApi.h" +#endif + +/*-------------------------------------------------------------------------- + + \brief peInitBeaconParams() - Initialize the beaconParams structure + + + \param tpPESession - pointer to the session context or NULL if session can not be created. + \return void + \sa + + --------------------------------------------------------------------------*/ + +void peInitBeaconParams(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + psessionEntry->beaconParams.beaconInterval = 0; + psessionEntry->beaconParams.fShortPreamble = 0; + psessionEntry->beaconParams.llaCoexist = 0; + psessionEntry->beaconParams.llbCoexist = 0; + psessionEntry->beaconParams.llgCoexist = 0; + psessionEntry->beaconParams.ht20Coexist = 0; + psessionEntry->beaconParams.llnNonGFCoexist = 0; + psessionEntry->beaconParams.fRIFSMode = 0; + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = 0; + psessionEntry->beaconParams.gHTObssMode = 0; + + // Number of legacy STAs associated + vos_mem_set((void*)&psessionEntry->gLim11bParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLim11aParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLim11gParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimNonGfParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimHt20Params, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimLsigTxopParams, sizeof(tLimProtStaParams), 0); + vos_mem_set((void*)&psessionEntry->gLimOlbcParams, sizeof(tLimProtStaParams), 0); +} + +/*-------------------------------------------------------------------------- + + \brief peCreateSession() - creates a new PE session given the BSSID + + This function returns the session context and the session ID if the session + corresponding to the passed BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the new session + \param sessionId -session ID is returned here, if session is created. + + \return tpPESession - pointer to the session context or NULL if session can not be created. + + \sa + + --------------------------------------------------------------------------*/ +tpPESession peCreateSession(tpAniSirGlobal pMac, tANI_U8 *bssid , tANI_U8* sessionId, tANI_U16 numSta) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + /* Find first free room in session table */ + if(pMac->lim.gpSession[i].valid == FALSE) + { + vos_mem_set((void*)&pMac->lim.gpSession[i], sizeof(tPESession), 0); + + //Allocate space for Station Table for this session. + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = vos_mem_vmalloc( + sizeof(tpDphHashNode)*numSta); + if ( NULL == pMac->lim.gpSession[i].dph.dphHashTable.pHashTable ) + { + limLog(pMac, LOGE, FL("memory allocate for size %lu failed!"), + (long unsigned int) sizeof(tpDphHashNode)*numSta); + return NULL; + } + + pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = vos_mem_vmalloc( + sizeof(tDphHashNode)*numSta); + if ( NULL == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray ) + { + limLog(pMac, LOGE, FL("memory allocate failed for Node array" + "of size %lu"), + (long unsigned int) sizeof(tDphHashNode)*numSta); + vos_mem_vfree(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable); + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL; + return NULL; + } + pMac->lim.gpSession[i].dph.dphHashTable.size = numSta; + + dphHashTableClassInit(pMac, + &pMac->lim.gpSession[i].dph.dphHashTable); + + pMac->lim.gpSession[i].gpLimPeerIdxpool = vos_mem_vmalloc(sizeof( + *pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1)); + if ( NULL == pMac->lim.gpSession[i].gpLimPeerIdxpool ) + { + limLog(pMac, LOGE, FL("memory allocate failed " + "for peerId pool of size %lu!"), (long unsigned int) + sizeof(*pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1)); + vos_mem_vfree(pMac->lim.gpSession[i].dph.dphHashTable.pHashTable); + vos_mem_vfree(pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray); + pMac->lim.gpSession[i].dph.dphHashTable.pHashTable = NULL; + pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray = NULL; + return NULL; + } + vos_mem_set(pMac->lim.gpSession[i].gpLimPeerIdxpool, + sizeof(*pMac->lim.gpSession[i].gpLimPeerIdxpool) * (numSta+1), 0); + pMac->lim.gpSession[i].freePeerIdxHead = 0; + pMac->lim.gpSession[i].freePeerIdxTail = 0; + pMac->lim.gpSession[i].gLimNumOfCurrentSTAs = 0; + + /* Copy the BSSID to the session table */ + sirCopyMacAddr(pMac->lim.gpSession[i].bssId, bssid); + pMac->lim.gpSession[i].valid = TRUE; + + /* Intialize the SME and MLM states to IDLE */ + pMac->lim.gpSession[i].limMlmState = eLIM_MLM_IDLE_STATE; + pMac->lim.gpSession[i].limSmeState = eLIM_SME_IDLE_STATE; + pMac->lim.gpSession[i].limCurrentAuthType = eSIR_OPEN_SYSTEM; + peInitBeaconParams(pMac, &pMac->lim.gpSession[i]); +#ifdef WLAN_FEATURE_VOWIFI_11R + pMac->lim.gpSession[i].is11Rconnection = FALSE; +#endif + +#ifdef FEATURE_WLAN_ESE + pMac->lim.gpSession[i].isESEconnection = FALSE; +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + pMac->lim.gpSession[i].isFastTransitionEnabled = FALSE; +#endif +#ifdef FEATURE_WLAN_LFR + pMac->lim.gpSession[i].isFastRoamIniFeatureEnabled = FALSE; +#endif + *sessionId = i; + + pMac->lim.gpSession[i].gLimPhyMode = WNI_CFG_PHY_MODE_11G; //TODO :Check with the team what should be default mode + /* Initialize CB mode variables when session is created */ + pMac->lim.gpSession[i].htSupportedChannelWidthSet = 0; + pMac->lim.gpSession[i].htRecommendedTxWidthSet = 0; + pMac->lim.gpSession[i].htSecondaryChannelOffset = 0; +#ifdef FEATURE_WLAN_TDLS + vos_mem_set(pMac->lim.gpSession[i].peerAIDBitmap, + sizeof(pMac->lim.gpSession[i].peerAIDBitmap), 0); + pMac->lim.gpSession[i].tdlsChanSwitProhibited = 0; +#endif + pMac->lim.gpSession[i].fWaitForProbeRsp = 0; + pMac->lim.gpSession[i].fIgnoreCapsChange = 0; + limLog(pMac, LOG1, FL("Create a new sessionId (%d) with BSSID: " + MAC_ADDRESS_STR " Max No. of STA %d"), + pMac->lim.gpSession[i].peSessionId, + MAC_ADDR_ARRAY(bssid), numSta); + return(&pMac->lim.gpSession[i]); + } + } + limLog(pMac, LOGE, FL("Session can not be created.. Reached Max permitted sessions ")); + return NULL; +} + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssid() - looks up the PE session given the BSSID. + + This function returns the session context and the session ID if the session + corresponding to the given BSSID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param bssid - BSSID of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssid(tpAniSirGlobal pMac, tANI_U8* bssid, tANI_U8* sessionId) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + /* If BSSID matches return corresponding tables address*/ + if( (pMac->lim.gpSession[i].valid) && (sirCompareMacAddr(pMac->lim.gpSession[i].bssId, bssid))) + { + *sessionId = i; + return(&pMac->lim.gpSession[i]); + } + } + + limLog(pMac, LOG4, FL("Session lookup fails for BSSID: ")); + limPrintMacAddr(pMac, bssid, LOG4); + return(NULL); + +} + +tANI_S8 limGetInfraSessionId(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for (i = 0; i < pMac->lim.maxBssId; i++) + { + if ((pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + return i; + } + } + limLog(pMac, LOG4, FL("Session lookup fails for infra mode")); + return -1; +} + +/*-------------------------------------------------------------------------- + \brief peFindSessionByBssIdx() - looks up the PE session given the bssIdx. + + This function returns the session context if the session + corresponding to the given bssIdx is found in the PE session table. + \param pMac - pointer to global adapter context + \param bssIdx - bss index of the session + \return tpPESession - pointer to the session context or NULL if session is not found. + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByBssIdx(tpAniSirGlobal pMac, tANI_U8 bssIdx) +{ + tANI_U8 i; + for (i = 0; i < pMac->lim.maxBssId; i++) + { + /* If BSSID matches return corresponding tables address*/ + if ( (pMac->lim.gpSession[i].valid) && (pMac->lim.gpSession[i].bssIdx == bssIdx)) + { + return &pMac->lim.gpSession[i]; + } + } + limLog(pMac, LOG4, FL("Session lookup fails for bssIdx: %d"), bssIdx); + return NULL; +} + +/*-------------------------------------------------------------------------- + \brief peFindSessionBySessionId() - looks up the PE session given the session ID. + + This function returns the session context if the session + corresponding to the given session ID is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sessionId -session ID for which session context needs to be looked up. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ + tpPESession peFindSessionBySessionId(tpAniSirGlobal pMac , tANI_U8 sessionId) +{ + if(sessionId >= pMac->lim.maxBssId) + { + limLog(pMac, LOGE, FL("Invalid sessionId: %d "), sessionId); + return(NULL); + } + if((pMac->lim.gpSession[sessionId].valid == TRUE)) + { + return(&pMac->lim.gpSession[sessionId]); + } + return(NULL); + +} + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByStaId() - looks up the PE session given staid. + + This function returns the session context and the session ID if the session + corresponding to the given StaId is found in the PE session table. + + \param pMac - pointer to global adapter context + \param staid - StaId of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ +tpPESession peFindSessionByStaId(tpAniSirGlobal pMac, tANI_U8 staid, tANI_U8* sessionId) +{ + tANI_U8 i, j; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + for(j = 0; j < pMac->lim.gpSession[i].dph.dphHashTable.size; j++) + { + if((pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].valid) && + (pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].added) && + (staid == pMac->lim.gpSession[i].dph.dphHashTable.pDphNodeArray[j].staIndex)) + { + *sessionId = i; + return(&pMac->lim.gpSession[i]); + } + } + } + } + + limLog(pMac, LOG4, FL("Session lookup fails for StaId: %d\n "), staid); + return(NULL); +} + + + +/*-------------------------------------------------------------------------- + \brief peDeleteSession() - deletes the PE session given the session ID. + + + \param pMac - pointer to global adapter context + \param sessionId -session ID of the session which needs to be deleted. + + \sa + --------------------------------------------------------------------------*/ +void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U16 i = 0; + tANI_U16 n; + TX_TIMER *timer_ptr; + eHalStatus lock_status = eHAL_STATUS_SUCCESS; + + limLog(pMac, LOGW, FL("Trying to delete a session %d Opmode %d BssIdx %d" + " BSSID: " MAC_ADDRESS_STR), psessionEntry->peSessionId, + psessionEntry->operMode, psessionEntry->bssIdx, + MAC_ADDR_ARRAY(psessionEntry->bssId)); + + for (n = 0; n < pMac->lim.maxStation; n++) + { + timer_ptr = &pMac->lim.limTimers.gpLimCnfWaitTimer[n]; + + if(psessionEntry->peSessionId == timer_ptr->sessionId) + { + if(VOS_TRUE == tx_timer_running(timer_ptr)) + { + tx_timer_deactivate(timer_ptr); + } + } + } + +#ifdef WLAN_FEATURE_11AC + + /* Unblock the MuBF for other session if the MuBf session is deleted + */ + if(psessionEntry->txMuBformee) + { + pMac->isMuBfsessionexist = FALSE; + } + +#endif + + if (psessionEntry->pLimStartBssReq != NULL) + { + vos_mem_free( psessionEntry->pLimStartBssReq ); + psessionEntry->pLimStartBssReq = NULL; + } + + if(psessionEntry->pLimJoinReq != NULL) + { + vos_mem_free( psessionEntry->pLimJoinReq ); + psessionEntry->pLimJoinReq = NULL; + } + + if(psessionEntry->pLimReAssocReq != NULL) + { + vos_mem_free( psessionEntry->pLimReAssocReq ); + psessionEntry->pLimReAssocReq = NULL; + } + + if(psessionEntry->pLimMlmJoinReq != NULL) + { + vos_mem_free( psessionEntry->pLimMlmJoinReq ); + psessionEntry->pLimMlmJoinReq = NULL; + } + + lock_status = pe_AcquireGlobalLock(&pMac->lim); + if (eHAL_STATUS_SUCCESS == lock_status) + { + if (psessionEntry->dph.dphHashTable.pHashTable != NULL) + { + vos_mem_vfree(psessionEntry->dph.dphHashTable.pHashTable); + psessionEntry->dph.dphHashTable.pHashTable = NULL; + } + } + pe_ReleaseGlobalLock(&pMac->lim); + + if(psessionEntry->dph.dphHashTable.pDphNodeArray != NULL) + { + vos_mem_vfree(psessionEntry->dph.dphHashTable.pDphNodeArray); + psessionEntry->dph.dphHashTable.pDphNodeArray = NULL; + } + + if(psessionEntry->gpLimPeerIdxpool != NULL) + { + vos_mem_vfree(psessionEntry->gpLimPeerIdxpool); + psessionEntry->gpLimPeerIdxpool = NULL; + } + + if(psessionEntry->beacon != NULL) + { + vos_mem_free( psessionEntry->beacon); + psessionEntry->beacon = NULL; + } + + if(psessionEntry->assocReq != NULL) + { + vos_mem_free( psessionEntry->assocReq); + psessionEntry->assocReq = NULL; + } + + if(psessionEntry->assocRsp != NULL) + { + vos_mem_free( psessionEntry->assocRsp); + psessionEntry->assocRsp = NULL; + } + + + if(psessionEntry->parsedAssocReq != NULL) + { + // Cleanup the individual allocation first + for (i=0; i < psessionEntry->dph.dphHashTable.size; i++) + { + if ( psessionEntry->parsedAssocReq[i] != NULL ) + { + if( ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame ) + { + vos_mem_free(((tpSirAssocReq) + (psessionEntry->parsedAssocReq[i]))->assocReqFrame); + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrame = NULL; + ((tpSirAssocReq)(psessionEntry->parsedAssocReq[i]))->assocReqFrameLength = 0; + } + vos_mem_free(psessionEntry->parsedAssocReq[i]); + psessionEntry->parsedAssocReq[i] = NULL; + } + } + // Cleanup the whole block + vos_mem_free(psessionEntry->parsedAssocReq); + psessionEntry->parsedAssocReq = NULL; + } + if (NULL != psessionEntry->limAssocResponseData) + { + vos_mem_free( psessionEntry->limAssocResponseData); + psessionEntry->limAssocResponseData = NULL; + } + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (NULL != psessionEntry->pLimMlmReassocRetryReq) + { + vos_mem_free( psessionEntry->pLimMlmReassocRetryReq); + psessionEntry->pLimMlmReassocRetryReq = NULL; + } +#endif + + if (NULL != psessionEntry->pLimMlmReassocReq) + { + vos_mem_free( psessionEntry->pLimMlmReassocReq); + psessionEntry->pLimMlmReassocReq = NULL; + } + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + limCleanupEseCtxt(pMac, psessionEntry); +#endif + + psessionEntry->valid = FALSE; + return; +} + + +/*-------------------------------------------------------------------------- + \brief peFindSessionByPeerSta() - looks up the PE session given the Station Address. + + This function returns the session context and the session ID if the session + corresponding to the given station address is found in the PE session table. + + \param pMac - pointer to global adapter context + \param sa - Peer STA Address of the session + \param sessionId -session ID is returned here, if session is found. + + \return tpPESession - pointer to the session context or NULL if session is not found. + + \sa + --------------------------------------------------------------------------*/ + + +tpPESession peFindSessionByPeerSta(tpAniSirGlobal pMac, tANI_U8* sa, tANI_U8* sessionId) +{ + tANI_U8 i; + tpDphHashNode pSta; + tANI_U16 aid; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if( (pMac->lim.gpSession[i].valid)) + { + pSta = dphLookupHashEntry(pMac, sa, &aid, &pMac->lim.gpSession[i].dph.dphHashTable); + if (pSta != NULL) + { + *sessionId = i; + return &pMac->lim.gpSession[i]; + } + } + } + + limLog(pMac, LOG1, FL("Session lookup fails for Peer StaId: ")); + limPrintMacAddr(pMac, sa, LOG1); + return NULL; +} + + + + + + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.c new file mode 100644 index 000000000000..023672f48554 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.c @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file limSessionUtils.c + \brief implementation for lim Session Utility APIs + \author Sunit Bhatia + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "aniGlobal.h" +#include "limDebug.h" +#include "limSession.h" +#include "limSessionUtils.h" +#include "limUtils.h" + +/*-------------------------------------------------------------------------- + \brief peGetVhtCapable() - Returns the Vht capable from a valid session. + + This function itrates the session Table and returns the VHT capable from first valid session + if no sessions are valid/present it returns FALSE + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +tANI_U8 peGetVhtCapable(tpAniSirGlobal pMac) + +{ +#ifdef WLAN_FEATURE_11AC + tANI_U8 i; + //assumption here is that all the sessions will be on the same channel. + //This function will not work, once we have multiple channel support. + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + return(pMac->lim.gpSession[i].vhtCapability); + } + } +#endif + return FALSE; +} +/*-------------------------------------------------------------------------- + \brief peGetCurrentChannel() - Returns the channel number for scanning, + from a valid session. + This function itrates the session Table and returns the channel number + from first valid session if no sessions are valid/present it returns zero + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + \sa + --------------------------------------------------------------------------*/ +tANI_U8 peGetCurrentChannel(tpAniSirGlobal pMac) +{ + tANI_U8 i; + //assumption here is that all the sessions will be on the same channel. + //This function will not work, once we have multiple channel support. + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + return(pMac->lim.gpSession[i].currentOperChannel); + } + } + return(HAL_INVALID_CHANNEL_ID); +} + + +/*-------------------------------------------------------------------------- + + \brief peValidateJoinReq() - validates the Join request . + + This function is called to validate the Join Request for a BT-AMP station. If start BSS session is present + this function returns TRUE else returns FALSE. + PE will force SME to first issue ''START_BSS' request for BTAMP_STA, before sending a JOIN request. + + \param pMac - pointer to global adapter context + \return - return TRUE if start BSS session is present else return FALSE. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 peValidateBtJoinRequest(tpAniSirGlobal pMac) +{ + + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if( (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].bssType == eSIR_BTAMP_STA_MODE) && + (pMac->lim.gpSession[i].statypeForBss == STA_ENTRY_SELF)) + { + return(TRUE); + } + + } + return(FALSE); + +} + +/*-------------------------------------------------------------------------- + \brief peGetValidPowerSaveSession() - Fetches the valid session for powersave . + + This function is called to check the valid session for power save, if more than one session is active , this function + it returns NULL. + if there is only one valid "infrastructure" session present in "linkestablished" state this function returns sessionentry. + For all other cases it returns NULL. + + \param pMac - pointer to global adapter context + \return - return session is address if valid session is present else return NULL. + + \sa + --------------------------------------------------------------------------*/ + + +tpPESession peGetValidPowerSaveSession(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tANI_U8 sessioncount = 0; + tANI_U8 sessionId = 0; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + if( (pMac->lim.gpSession[i].valid == TRUE)&& + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)&& + (pMac->lim.gpSession[i].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) { + sessioncount++; + sessionId = i; + + if(sessioncount > 1) + { + return(NULL); + } + } + + } + + if( (pMac->lim.gpSession[sessionId].valid == TRUE)&& + (pMac->lim.gpSession[sessionId].limSystemRole == eLIM_STA_ROLE)&& + (pMac->lim.gpSession[sessionId].limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE)) + + { + return(&pMac->lim.gpSession[sessionId]); + } + return(NULL); + +} +/*-------------------------------------------------------------------------- + \brief peIsAnySessionActive() - checks for the active session presence . + + This function returns TRUE if atleast one valid session is present else it returns FALSE + + \param pMac - pointer to global adapter context + \return - return TRUE if atleast one session is active else return FALSE. + + \sa + --------------------------------------------------------------------------*/ + + +tANI_U8 peIsAnySessionActive(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + return(TRUE); + } + + } + return(FALSE); + +} + +/*-------------------------------------------------------------------------- + \brief pePrintActiveSession() - print all the active pesession present . + + This function print all the active pesession present + + \param pMac - pointer to global adapter context + + \sa + --------------------------------------------------------------------------*/ + + +void pePrintActiveSession(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + limLog(pMac, LOGE, FL("Active sessionId: %d BSID: "MAC_ADDRESS_STR + "opmode = %d bssIdx = %d"), i, + MAC_ADDR_ARRAY(pMac->lim.gpSession[i].bssId), + pMac->lim.gpSession[i].operMode, + pMac->lim.gpSession[i].bssIdx); + } + } + return; +} + +/*-------------------------------------------------------------------------- + \brief isLimSessionOffChannel() - Determines if the there is any other off channel + session. + + This function returns TRUE if the session Id passed needs to be on a different + channel than atleast one session already active. + + \param pMac - pointer to global adapter context + \param sessionId - session ID of the session to be verified. + + \return tANI_U8 - Boolean value for off-channel operation. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 +isLimSessionOffChannel(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 i; + + if(sessionId >= pMac->lim.maxBssId) + { + limLog(pMac, LOGE, FL("Invalid sessionId: %d "), sessionId); + return FALSE; + } + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if( i == sessionId ) + { + //Skip the sessionId that is to be joined. + continue; + } + //if another ession is valid and it is on different channel + //it is an off channel operation. + if( (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].currentOperChannel != + pMac->lim.gpSession[sessionId].currentOperChannel) ) + { + return TRUE; + } + } + + return FALSE; + +} + +/*-------------------------------------------------------------------------- + \brief peGetActiveSessionChannel() - Gets the operating channel of first + valid session. Returns 0 if there is no + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - operating channel. + + \sa + --------------------------------------------------------------------------*/ +void +peGetActiveSessionChannel (tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState) +{ + tANI_U8 i; + ePhyChanBondState prevPhyCbState = PHY_SINGLE_CHANNEL_CENTERED; + + // Initialize the pointers passed to INVALID values in case we don't find a valid session + *resumeChannel = 0; + *resumePhyCbState = 0; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid) + { + *resumeChannel = pMac->lim.gpSession[i].currentOperChannel; + *resumePhyCbState = pMac->lim.gpSession[i].htSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_11AC + if ((pMac->lim.gpSession[i].vhtCapability)) + { + /*Get 11ac cbState from 11n cbState*/ + *resumePhyCbState = limGet11ACPhyCBState(pMac, + pMac->lim.gpSession[i].currentOperChannel, + pMac->lim.gpSession[i].htSecondaryChannelOffset, + pMac->lim.gpSession[i].apCenterChan, + &pMac->lim.gpSession[i]); + } +#endif + *resumePhyCbState = (*resumePhyCbState > prevPhyCbState )? *resumePhyCbState : prevPhyCbState; + prevPhyCbState = *resumePhyCbState; + } + } + return; +} + +/*-------------------------------------------------------------------------- + \brief limIsChanSwitchRunning() - Check if channel switch is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann switching running. + 0 - if chann switching is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsChanSwitchRunning (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + return 1; + } + } + return 0; +} +/*-------------------------------------------------------------------------- + \brief limIsInQuietDuration() - Check if channel quieting is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInQuietDuration (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + { + return 1; + } + } + return 0; +} +/*-------------------------------------------------------------------------- + \brief limIsQuietBegin() - Check if channel quieting is begining on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsQuietBegin (tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid && + pMac->lim.gpSession[i].gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + return 1; + } + } + return 0; +} + +/*-------------------------------------------------------------------------- + \brief limIsInMCC() - Check if Device is in MCC. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - TRUE - if in MCC. + FALSE - NOT in MCC. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInMCC (tpAniSirGlobal pMac) +{ + tANI_U8 i; + tANI_U8 chan = 0; + + for(i = 0; i < pMac->lim.maxBssId; i++) + { + //if another session is valid and it is on different channel + //it is an off channel operation. + if( (pMac->lim.gpSession[i].valid) ) + { + if( chan == 0 ) + { + chan = pMac->lim.gpSession[i].currentOperChannel; + } + else if( chan != pMac->lim.gpSession[i].currentOperChannel) + { + return TRUE; + } + } + } + return FALSE; +} + +/*-------------------------------------------------------------------------- + \brief peGetCurrentSTAsCount() - Returns total stations associated on + all session. + + \param pMac - pointer to global adapter context + \return - Number of station active on all sessions. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 peGetCurrentSTAsCount(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tANI_U8 staCount = 0; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + staCount += pMac->lim.gpSession[i].gLimNumOfCurrentSTAs; + } + } + return staCount; +} + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief limIsFastRoamEnabled() - Check LFR is enabled or not + + This function returns the TRUE if LFR is enabled + + \param pMac - pointer to global adapter context + \param sessionId - session ID is returned here, if session is found. + + \return int - TRUE if enabled or else FALSE + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 limIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + if(TRUE == pMac->lim.gpSession[sessionId].valid) + { + if((eSIR_INFRASTRUCTURE_MODE == pMac->lim.gpSession[sessionId].bssType) && + (pMac->lim.gpSession[sessionId].isFastRoamIniFeatureEnabled)) + { + return TRUE; + } + } + + return FALSE; +} +#endif + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.h new file mode 100644 index 000000000000..7e169f6607d6 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSessionUtils.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if!defined( __LIM_SESSION_UTILS_H ) +#define __LIM_SESSION_UTILS_H + + + +/**========================================================================= + + \file limSessionUtils.h + + \brief prototype for lim Session Utility related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + + \brief peGetVhtCapable() - Returns the Vht capable from a valid session. + + This function iterates the session Table and returns the VHT capable from first valid session + if no sessions are valid/present it returns FALSE + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +tANI_U8 peGetVhtCapable(tpAniSirGlobal pMac); + + +/*-------------------------------------------------------------------------- + \brief peValidateJoinReq() - validates the Join request . + + This function is called to validate the Join Request for a BT-AMP station. If start BSS session is present + this function returns TRUE else returns FALSE. + + \param pMac - pointer to global adapter context + \return - return TRUE if start BSS session is present else return FALSE. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 peValidateBtJoinRequest(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + \brief peGetValidPowerSaveSession() - Fetches the valid session for powersave . + + This function is called to check the valid session for power save, if more than one session is active , this function + it returns NULL. + if there is only one valid "infrastructure" session present in "linkestablished" state this function returns sessionentry. + For all other cases it returns NULL. + + \param pMac - pointer to global adapter context + \return - return session is address if valid session is present else return NULL. + + \sa + --------------------------------------------------------------------------*/ + + +tpPESession peGetValidPowerSaveSession(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + \brief peIsAnySessionActive() - checks for the active session presence . + + This function returns TRUE if atleast one valid session is present else it returns FALSE + + \param pMac - pointer to global adapter context + \return - return TRUE if atleast one session is active else return FALSE. + + \sa + --------------------------------------------------------------------------*/ + +tANI_U8 peIsAnySessionActive(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + \brief pePrintActiveSession() - print all the active pesession present . + + This function print all the active pesession present + + \param pMac - pointer to global adapter context + + \sa + --------------------------------------------------------------------------*/ + +void pePrintActiveSession(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------*/ + + + +/*-------------------------------------------------------------------------- + \brief isLimSessionOffChannel() - Determines if the session is + off channel. + + This function returns TRUE if the session Id passed needs to be on a different + channel than atleast one session already active. + + \param pMac - pointer to global adapter context + \param sessionId - session ID of the session to be verified. + + \return tANI_U8 - Boolean value for off-channel operation. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +isLimSessionOffChannel(tpAniSirGlobal pMac, tANI_U8 sessionId); +/* --------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief peGetActiveSessionChannel() - Gets the first valid sessions primary and secondary + channel. If not found returns invalid channel ID (=0) + \param pMac - pointer to global adapter context + \param resumeChannel - Primary channel of the first valid session. This is an output argument. + \return resumePhyCbState - Secondary channel of the first valid session. This is an output argument. +--------------------------------------------------------------------------*/ +void +peGetActiveSessionChannel(tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState); + +/*-------------------------------------------------------------------------- + \brief limIsChanSwitchRunning() - Check if channel switch is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann switching running. + 0 - if chann switching is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsChanSwitchRunning (tpAniSirGlobal pMac); + +/*-------------------------------------------------------------------------- + \brief limIsInQuietDuration() - Check if channel quieting is running on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInQuietDuration (tpAniSirGlobal pMac); + +/*-------------------------------------------------------------------------- + \brief limIsQuietBegin() - Check if channel quieting is begining on any + valid session. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - 1 - if chann quiet running. + 0 - if chann quiet is not running. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsQuietBegin (tpAniSirGlobal pMac); +/*-------------------------------------------------------------------------- + \brief limIsInMCC() - Check if Device is in MCC. + + \param pMac - pointer to global adapter context + + \return tANI_U8 - TRUE - if in MCC. + FALSE - NOT in MCC. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsInMCC (tpAniSirGlobal pMac); +/*-------------------------------------------------------------------------- + \brief peGetCurrentSTAsCount() - Returns total stations associated on + all session. + + \param pMac - pointer to global adapter context + \return - Number of station active on all sessions. + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +peGetCurrentSTAsCount(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief limIsFastRoamEnabled() - To check Fast roaming is enabled or not + + \param pMac - pointer to global adapter context + \param sessionId - session id + \return - TRUE or FALSE + + \sa + --------------------------------------------------------------------------*/ +tANI_U8 +limIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U8 sessionId); +#endif + + +#endif //#if !defined( __LIM_SESSION_UTILS_H ) + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.c new file mode 100644 index 000000000000..42689a287ff0 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.c @@ -0,0 +1,1155 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSmeReqUtils.cc contains the utility functions + * for processing SME request messages. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * 05/26/10 js WPA handling in (Re)Assoc frames + * + */ + +#include "wniApi.h" +#include "wniCfg.h" +#include "cfgApi.h" +#include "sirApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "limSerDesUtils.h" + + + +/** + * limIsRSNieValidInSmeReqMessage() + * + *FUNCTION: + * This function is called to verify if the RSN IE + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * RSN IE validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pRSNie Pointer to received RSN IE + * @return true when RSN IE is valid, false otherwise + */ + +static tANI_U8 +limIsRSNieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirRSNie pRSNie) +{ + tANI_U8 startPos = 0; + tANI_U32 privacy, val; + int len; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &privacy) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve POI from CFG")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED, + &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve RSN_ENABLED from CFG")); + } + + if (pRSNie->length && (!privacy || !val)) + { + // Privacy & RSN not enabled in CFG. + /** + * In order to allow mixed mode for Guest access + * allow BSS creation/join with no Privacy capability + * yet advertising WPA IE + */ + PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d"), + pRSNie->length, privacy, val);) + } + + if (pRSNie->length) + { + if ((pRSNie->rsnIEdata[0] != DOT11F_EID_RSN) && + (pRSNie->rsnIEdata[0] != DOT11F_EID_WPA) +#ifdef FEATURE_WLAN_WAPI + && (pRSNie->rsnIEdata[0] != DOT11F_EID_WAPI) +#endif + ) + { + limLog(pMac, LOGE, FL("RSN/WPA/WAPI EID %d not [%d || %d]"), + pRSNie->rsnIEdata[0], DOT11F_EID_RSN, + DOT11F_EID_WPA); + return false; + } + + len = pRSNie->length; + startPos = 0; + while(len > 0) + { + // Check validity of RSN IE + if (pRSNie->rsnIEdata[startPos] == DOT11F_EID_RSN) + { + if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_RSN_MAX_LEN) || + (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_RSN_MIN_LEN)) + { + limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]"), + pRSNie->rsnIEdata[startPos+1], DOT11F_IE_RSN_MIN_LEN, + DOT11F_IE_RSN_MAX_LEN); + return false; + } + } + else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WPA) + { + // Check validity of WPA IE + if (SIR_MAC_MAX_IE_LENGTH > startPos) + { + if (startPos <= (SIR_MAC_MAX_IE_LENGTH - sizeof(tANI_U32))) + val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[startPos + 2]); + if((pRSNie->rsnIEdata[startPos + 1] < DOT11F_IE_WPA_MIN_LEN) || + (pRSNie->rsnIEdata[startPos + 1] > DOT11F_IE_WPA_MAX_LEN) || + (SIR_MAC_WPA_OUI != val)) + { + limLog(pMac, LOGE, + FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"), + pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WPA_MIN_LEN, + DOT11F_IE_WPA_MAX_LEN, val, SIR_MAC_WPA_OUI); + + return false; + } + } + } +#ifdef FEATURE_WLAN_WAPI + else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WAPI) + { + if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_WAPI_MAX_LEN) || + (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_WAPI_MIN_LEN)) + { + limLog(pMac, LOGE, + FL("WAPI IE len %d not [%d,%d]"), + pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WAPI_MIN_LEN, + DOT11F_IE_WAPI_MAX_LEN); + + return false; + } + } +#endif + else + { + //we will never be here, simply for completeness + return false; + } + startPos += 2 + pRSNie->rsnIEdata[startPos+1]; //EID + length field + length + len -= startPos; + }//while + + } + + return true; +} /*** end limIsRSNieValidInSmeReqMessage() ***/ + +/** + * limIsAddieValidInSmeReqMessage() + * + *FUNCTION: + * This function is called to verify if the Add IE + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * Add IE validity checks are performed on only length + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pWSCie Pointer to received WSC IE + * @return true when WSC IE is valid, false otherwise + */ + +static tANI_U8 +limIsAddieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirAddie pAddie) +{ + int left = pAddie->length; + tANI_U8 *ptr = pAddie->addIEdata; + tANI_U8 elem_id, elem_len; + + if (left == 0) + return true; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + limLog( pMac, LOGE, + FL("****Invalid Add IEs eid = %d elem_len=%d left=%d*****"), + elem_id,elem_len,left); + return false; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + // there shouldn't be any left byte + + + return true; +} /*** end limIsAddieValidInSmeReqMessage() ***/ + +/** + * limSetRSNieWPAiefromSmeStartBSSReqMessage() + * + *FUNCTION: + * This function is called to verify if the RSN IE + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * RSN IE validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pRSNie Pointer to received RSN IE + * @return true when RSN IE is valid, false otherwise + */ + +tANI_U8 +limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac, + tpSirRSNie pRSNie, + tpPESession pSessionEntry) +{ + tANI_U8 wpaIndex = 0; + tANI_U32 privacy, val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &privacy) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve POI from CFG")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED, + &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve RSN_ENABLED from CFG")); + } + + if (pRSNie->length && (!privacy || !val)) + { + // Privacy & RSN not enabled in CFG. + /** + * In order to allow mixed mode for Guest access + * allow BSS creation/join with no Privacy capability + * yet advertising WPA IE + */ + PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d"), + pRSNie->length, privacy, val);) + } + + if (pRSNie->length) + { + if ((pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID) && + (pRSNie->rsnIEdata[0] != SIR_MAC_WPA_EID)) + { + limLog(pMac, LOGE, FL("RSN/WPA EID %d not [%d || %d]"), + pRSNie->rsnIEdata[0], SIR_MAC_RSN_EID, + SIR_MAC_WPA_EID); + return false; + } + + // Check validity of RSN IE + if ((pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID) && +#if 0 // Comparison always false + (pRSNie->rsnIEdata[1] > SIR_MAC_RSN_IE_MAX_LENGTH) || +#endif + (pRSNie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH)) + { + limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]"), + pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH, + SIR_MAC_RSN_IE_MAX_LENGTH); + return false; + } + + if (pRSNie->length > pRSNie->rsnIEdata[1] + 2) + { + if (pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID) + { + limLog(pMac, + LOGE, + FL("First byte[%d] in rsnIEdata is not RSN_EID"), + pRSNie->rsnIEdata[1]); + return false; + } + + limLog(pMac, + LOG1, + FL("WPA IE is present along with WPA2 IE")); + wpaIndex = 2 + pRSNie->rsnIEdata[1]; + } + else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) && + (pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID)) + { + limLog(pMac, + LOG1, + FL("Only RSN IE is present")); + dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2], + (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe); + } + else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) && + (pRSNie->rsnIEdata[0] == SIR_MAC_WPA_EID)) + { + limLog(pMac, + LOG1, + FL("Only WPA IE is present")); + + dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[6],(tANI_U8)pRSNie->length-4, + &pSessionEntry->gStartBssWPAIe); + } + + // Check validity of WPA IE + if(wpaIndex +4 < SIR_MAC_MAX_IE_LENGTH ) + { + val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[wpaIndex + 2]); + + if ((pRSNie->rsnIEdata[wpaIndex] == SIR_MAC_WPA_EID) && +#if 0 // Comparison always false + (pRSNie->rsnIEdata[wpaIndex + 1] > SIR_MAC_WPA_IE_MAX_LENGTH) || +#endif + ((pRSNie->rsnIEdata[wpaIndex + 1] < SIR_MAC_WPA_IE_MIN_LENGTH) || + (SIR_MAC_WPA_OUI != val))) + { + limLog(pMac, LOGE, + FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"), + pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH, + SIR_MAC_RSN_IE_MAX_LENGTH, val, SIR_MAC_WPA_OUI); + + return false; + } + else + { + /* Both RSN and WPA IEs are present */ + dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2], + (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe); + + dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[wpaIndex + 6], + pRSNie->rsnIEdata[wpaIndex + 1]-4, + &pSessionEntry->gStartBssWPAIe); + + } + } + else + { + return false; + } + } + + return true; +} /*** end limSetRSNieWPAiefromSmeStartBSSReqMessage() ***/ + + + + +/** + * limIsBssDescrValidInSmeReqMessage() + * + *FUNCTION: + * This function is called to verify if the BSS Descr + * received in various SME_REQ messages is valid or not + * + *LOGIC: + * BSS Descritipion validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pBssDescr Pointer to received Bss Descritipion + * @return true when BSS description is valid, false otherwise + */ + +static tANI_U8 +limIsBssDescrValidInSmeReqMessage(tpAniSirGlobal pMac, + tpSirBssDescription pBssDescr) +{ + tANI_U8 valid = true; + + if (limIsAddrBC(pBssDescr->bssId) || + !pBssDescr->channelId) + { + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsBssDescrValidInSmeReqMessage() ***/ + + + +/** + * limIsSmeStartReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_START_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMsg - Pointer to received SME_START_BSS_REQ message + * @return true when received SME_START_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeStartReqValid(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tANI_U8 valid = true; + + if (((tpSirSmeStartReq) pMsg)->length != sizeof(tSirSmeStartReq)) + { + /** + * Invalid length in START_REQ message + * Log error. + */ + limLog(pMac, LOGW, + FL("Invalid length %d in eWNI_SME_START_REQ"), + ((tpSirSmeStartReq) pMsg)->length); + + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsSmeStartReqValid() ***/ + + + +/** + * limIsSmeStartBssReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_START_BSS_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pStartBssReq Pointer to received SME_START_BSS_REQ message + * @return true when received SME_START_BSS_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeStartBssReqValid(tpAniSirGlobal pMac, + tpSirSmeStartBssReq pStartBssReq) +{ + tANI_U8 i = 0; + tANI_U8 valid = true; + + PELOG1(limLog(pMac, LOG1, + FL("Parsed START_BSS_REQ fields are bssType=%s (%d), channelId=%d," + " SSID len=%d, rsnIE len=%d, nwType=%d, rateset len=%d"), + lim_BssTypetoString(pStartBssReq->bssType), + pStartBssReq->bssType, + pStartBssReq->channelId, + pStartBssReq->ssId.length, + pStartBssReq->rsnIE.length, + pStartBssReq->nwType, + pStartBssReq->operationalRateSet.numRates);) + + switch (pStartBssReq->bssType) + { + case eSIR_INFRASTRUCTURE_MODE: + /** + * Should not have received start BSS req with bssType + * Infrastructure on STA. + * Log error. + */ + limLog(pMac, LOGE, + FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"), + pStartBssReq->bssType); + valid = false; + goto end; + break; + + case eSIR_IBSS_MODE: + break; + + /* Added for BT AMP support */ + case eSIR_BTAMP_STA_MODE: + break; + + /* Added for BT AMP support */ + case eSIR_BTAMP_AP_MODE: + break; + + /* Added for SoftAP support */ + case eSIR_INFRA_AP_MODE: + break; + + default: + /** + * Should not have received start BSS req with bssType + * other than Infrastructure/IBSS. + * Log error + */ + limLog(pMac, LOGW, + FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"), + pStartBssReq->bssType); + + valid = false; + goto end; + } + + /* This below code is client specific code. TODO */ + if (pStartBssReq->bssType == eSIR_IBSS_MODE) + { + if (!pStartBssReq->ssId.length || + (pStartBssReq->ssId.length > SIR_MAC_MAX_SSID_LENGTH)) + { + // Invalid length for SSID. + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid SSID length in eWNI_SME_START_BSS_REQ")); + + valid = false; + goto end; + } + } + + + if (!limIsRSNieValidInSmeReqMessage(pMac, &pStartBssReq->rsnIE)) + { + valid = false; + goto end; + } + + if (pStartBssReq->nwType != eSIR_11A_NW_TYPE && + pStartBssReq->nwType != eSIR_11B_NW_TYPE && + pStartBssReq->nwType != eSIR_11G_NW_TYPE) + { + valid = false; + goto end; + } + + if (pStartBssReq->nwType == eSIR_11A_NW_TYPE) + { + for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++) + if (!sirIsArate(pStartBssReq->operationalRateSet.rate[i] & 0x7F)) + { + // Invalid Operational rates + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid operational rates in eWNI_SME_START_BSS_REQ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + pStartBssReq->operationalRateSet.rate, + pStartBssReq->operationalRateSet.numRates); + + valid = false; + goto end; + } + } + // check if all the rates in the operatioal rate set are legal 11G rates + else if (pStartBssReq->nwType == eSIR_11G_NW_TYPE) + { + for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++) + if (!sirIsGrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F)) + { + // Invalid Operational rates + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid operational rates in eWNI_SME_START_BSS_REQ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + pStartBssReq->operationalRateSet.rate, + pStartBssReq->operationalRateSet.numRates); + + valid = false; + goto end; + } + } + else + { + for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++) + if (!sirIsBrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F)) + { + // Invalid Operational rates + // Reject START_BSS_REQ + limLog(pMac, LOGW, + FL("Invalid operational rates in eWNI_SME_START_BSS_REQ")); + sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG2, + pStartBssReq->operationalRateSet.rate, + pStartBssReq->operationalRateSet.numRates); + + valid = false; + goto end; + } + } + +end: + return valid; +} /*** end limIsSmeStartBssReqValid() ***/ + + + +/** + * limIsSmeJoinReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_JOIN_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pJoinReq Pointer to received SME_JOIN_REQ message + * @return true when received SME_JOIN_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeJoinReqValid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq) +{ + tANI_U8 valid = true; + + + if (!limIsRSNieValidInSmeReqMessage(pMac, &pJoinReq->rsnIE)) + { + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid RSNIE")); + valid = false; + goto end; + } + + if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEScan)) + { + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid additional IE for scan")); + valid = false; + goto end; + } + + if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEAssoc)) + { + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid additional IE for assoc")); + valid = false; + goto end; + } + + + if (!limIsBssDescrValidInSmeReqMessage(pMac, + &pJoinReq->bssDescription)) + { + /// Received eWNI_SME_JOIN_REQ with invalid BSS Info + // Log the event + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with invalid bssInfo")); + + valid = false; + goto end; + } + + /* + Reject Join Req if the Self Mac Address and + the Ap's Mac Address is same + */ + if ( vos_mem_compare( (tANI_U8* ) pJoinReq->selfMacAddr, + (tANI_U8 *) pJoinReq->bssDescription.bssId, + (tANI_U8) (sizeof(tSirMacAddr)))) + { + // Log the event + limLog(pMac, LOGE, + FL("received SME_JOIN_REQ with Self Mac and BSSID Same")); + + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsSmeJoinReqValid() ***/ + + + +/** + * limIsSmeDisassocReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_DISASSOC_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pDisassocReq Pointer to received SME_DISASSOC_REQ message + * @return true When received SME_DISASSOC_REQ is formatted + * correctly + * false otherwise + */ + +tANI_U8 +limIsSmeDisassocReqValid(tpAniSirGlobal pMac, + tpSirSmeDisassocReq pDisassocReq, tpPESession psessionEntry) +{ + if (limIsGroupAddr(pDisassocReq->peerMacAddr) && + !limIsAddrBC(pDisassocReq->peerMacAddr)) + return false; + + + return true; +} /*** end limIsSmeDisassocReqValid() ***/ + + + +/** + * limIsSmeDisassocCnfValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_DISASSOC_CNF message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pDisassocCnf Pointer to received SME_DISASSOC_REQ message + * @return true When received SME_DISASSOC_CNF is formatted + * correctly + * false otherwise + */ + +tANI_U8 +limIsSmeDisassocCnfValid(tpAniSirGlobal pMac, + tpSirSmeDisassocCnf pDisassocCnf, tpPESession psessionEntry) +{ + if (limIsGroupAddr(pDisassocCnf->peerMacAddr)) + return false; + + return true; +} /*** end limIsSmeDisassocCnfValid() ***/ + + + +/** + * limIsSmeDeauthReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_DEAUTH_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param pDeauthReq Pointer to received SME_DEAUTH_REQ message + * @return true When received SME_DEAUTH_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeDeauthReqValid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq, tpPESession psessionEntry) +{ + if (limIsGroupAddr(pDeauthReq->peerMacAddr) && + !limIsAddrBC(pDeauthReq->peerMacAddr)) + return false; + + return true; +} /*** end limIsSmeDeauthReqValid() ***/ + + + +/** + * limIsSmeScanReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_SCAN_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pScanReq Pointer to received SME_SCAN_REQ message + * @return true when received SME_SCAN_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq) +{ + tANI_U8 valid = true; + tANI_U8 i = 0; + + if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) + { + valid = false; + limLog(pMac, LOGE, FL("Number of SSIDs > SIR_SCAN_MAX_NUM_SSID")); + goto end; + } + + for (i = 0; i < pScanReq->numSsid; i++) + { + if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH) + { + limLog(pMac, LOGE, + FL("Requested SSID length > SIR_MAC_MAX_SSID_LENGTH")); + valid = false; + goto end; + } + } + if ((pScanReq->bssType < 0) || (pScanReq->bssType > eSIR_AUTO_MODE)) + { + limLog(pMac, LOGE, FL("Invalid BSS Type")); + valid = false; + } + if (limIsGroupAddr(pScanReq->bssId) && !limIsAddrBC(pScanReq->bssId)) + { + valid = false; + limLog(pMac, LOGE, FL("BSSID is group addr and is not Broadcast Addr")); + } + if (!(pScanReq->scanType == eSIR_PASSIVE_SCAN || pScanReq->scanType == eSIR_ACTIVE_SCAN)) + { + valid = false; + limLog(pMac, LOGE, FL("Invalid Scan Type")); + } + if (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS) + { + valid = false; + limLog(pMac, LOGE, FL("Number of Channels > SIR_MAX_NUM_CHANNELS")); + } + + /* + ** check min/max channelTime range + **/ + + if (valid) + { + if ((pScanReq->scanType == eSIR_ACTIVE_SCAN) && + (pScanReq->maxChannelTime < pScanReq->minChannelTime)) + { + limLog(pMac, LOGE, FL("Max Channel Time < Min Channel Time")); + valid = false; + } + } + +end: + return valid; +} /*** end limIsSmeScanReqValid() ***/ + + + +/** + * limIsSmeAuthReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_AUTH_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pAuthReq Pointer to received SME_AUTH_REQ message + * @return true when received SME_AUTH_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeAuthReqValid(tpSirSmeAuthReq pAuthReq) +{ + tANI_U8 valid = true; + + if (limIsGroupAddr(pAuthReq->peerMacAddr) || + (pAuthReq->authType > eSIR_AUTO_SWITCH) || + !pAuthReq->channelNumber) + { + valid = false; + goto end; + } + +end: + return valid; +} /*** end limIsSmeAuthReqValid() ***/ + + + +/** + * limIsSmeSetContextReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_SET_CONTEXT_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMsg - Pointer to received SME_SET_CONTEXT_REQ message + * @return true when received SME_SET_CONTEXT_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeSetContextReqValid(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq) +{ + tANI_U8 i = 0; + tANI_U8 valid = true; + tpSirKeys pKey = pSetContextReq->keyMaterial.key; + + if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) && + (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) && + (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) && +#ifdef FEATURE_WLAN_WAPI + (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) && +#endif + !pSetContextReq->keyMaterial.numKeys) + { + /** + * No keys present in case of TKIP or CCMP + * Log error. + */ + limLog(pMac, LOGW, + FL("No keys present in SME_SETCONTEXT_REQ for edType=%d"), + pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + + if (pSetContextReq->keyMaterial.numKeys && + (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE)) + { + /** + * Keys present in case of no ED policy + * Log error. + */ + limLog(pMac, LOGW, + FL("Keys present in SME_SETCONTEXT_REQ for edType=%d"), + pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + + if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED) + { + /** + * Invalid edType in the message + * Log error. + */ + limLog(pMac, LOGW, + FL("Invalid edType=%d in SME_SETCONTEXT_REQ"), + pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE) + { + tANI_U32 poi; + + if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED, + &poi) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, + FL("Unable to retrieve POI from CFG")); + } + + if (!poi) + { + /** + * Privacy is not enabled + * In order to allow mixed mode for Guest access + * allow BSS creation/join with no Privacy capability + * yet advertising WPA IE + */ + PELOG1(limLog(pMac, LOG1, + FL("Privacy is not enabled, yet non-None EDtype=%d in SME_SETCONTEXT_REQ"), + pSetContextReq->keyMaterial.edType);) + } + } + + for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++) + { + if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) && + (pKey->keyLength != 5)) || + ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) && + (pKey->keyLength != 13)) || + ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) && + (pKey->keyLength != 32)) || +#ifdef FEATURE_WLAN_WAPI + ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) && + (pKey->keyLength != 32)) || +#endif + ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) && + (pKey->keyLength != 16))) + { + /** + * Invalid key length for a given ED type + * Log error. + */ + limLog(pMac, LOGW, + FL("Invalid keyLength =%d for edType=%d in SME_SETCONTEXT_REQ"), + pKey->keyLength, pSetContextReq->keyMaterial.edType); + + valid = false; + goto end; + } + pKey++; + } + +end: + return valid; +} /*** end limIsSmeSetContextReqValid() ***/ + + + +/** + * limIsSmeStopBssReqValid() + * + *FUNCTION: + * This function is called by limProcessSmeReqMessages() upon + * receiving SME_STOP_BSS_REQ message from application. + * + *LOGIC: + * Message validity checks are performed in this function + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMsg - Pointer to received SME_STOP_BSS_REQ message + * @return true when received SME_STOP_BSS_REQ is formatted correctly + * false otherwise + */ + +tANI_U8 +limIsSmeStopBssReqValid(tANI_U32 *pMsg) +{ + tANI_U8 valid = true; + + return valid; +} /*** end limIsSmeStopBssReqValid() ***/ + + +/** + * limGetBssIdFromSmeJoinReqMsg() + * + *FUNCTION: + * This function is called in various places to get BSSID + * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/ + * SME_REASSOC_REQ message. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pBuf - Pointer to received SME_JOIN/SME_REASSOC_REQ + * message + * @return pBssId - Pointer to BSSID + */ + +tANI_U8* +limGetBssIdFromSmeJoinReqMsg(tANI_U8 *pBuf) +{ + if (!pBuf) + return NULL; + + pBuf += sizeof(tANI_U32); // skip message header + + + pBuf += limGetU16(pBuf) + sizeof(tANI_U16); // skip RSN IE + + pBuf += sizeof(tANI_U16); // skip length of BSS description + + return (pBuf); +} /*** end limGetBssIdFromSmeJoinReqMsg() ***/ + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.h new file mode 100644 index 000000000000..da87e1aa1821 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limSmeReqUtils.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limSmeReqUtils.h contains the utility definitions + * LIM uses while processing SME request messsages. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_SME_REQ_UTILS_H +#define __LIM_SME_REQ_UTILS_H + +#include "sirApi.h" +#include "limTypes.h" + + +// LIM SME request messages related utility functions +tANI_U8 limIsSmeStartReqValid(tpAniSirGlobal, tANI_U32 *); +tANI_U8 limIsSmeStartBssReqValid(tpAniSirGlobal, tpSirSmeStartBssReq); +tANI_U8 limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal, + tpSirRSNie, + tpPESession); +tANI_U8 limIsSmeScanReqValid(tpAniSirGlobal, tpSirSmeScanReq); +tANI_U8 limIsSmeJoinReqValid(tpAniSirGlobal, tpSirSmeJoinReq); +tANI_U8 limIsSmeAuthReqValid(tpSirSmeAuthReq); +tANI_U8 limIsSmeDisassocReqValid(tpAniSirGlobal, tpSirSmeDisassocReq, tpPESession); +tANI_U8 limIsSmeDeauthReqValid(tpAniSirGlobal, tpSirSmeDeauthReq, tpPESession); +tANI_U8 limIsSmeSetContextReqValid(tpAniSirGlobal, tpSirSmeSetContextReq); +tANI_U8 limIsSmeStopBssReqValid(tANI_U32 *); +tANI_U8* limGetBssIdFromSmeJoinReqMsg(tANI_U8 *); +tANI_U8 limIsSmeDisassocCnfValid(tpAniSirGlobal, tpSirSmeDisassocCnf, tpPESession); + +#endif /* __LIM_SME_REQ_UTILS_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.c new file mode 100644 index 000000000000..f6d787c51379 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * limStaHashApi.c: Provides access functions to get/set values of station hash entry fields. + * Author: Sunit Bhatia + * Date: 09/19/2006 + * History:- + * Date Modified by Modification Information + * + * -------------------------------------------------------------------------- + * + */ + +#include "limStaHashApi.h" + + +/** + * limGetStaHashBssidx() + * + *FUNCTION: + * This function is called to Get the Bss Index of the currently associated Station. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param assocId AssocID of the Station. + * @param bssidx pointer to the bss index, which will be returned by the function. + * + * @return success if GET operation is ok, else Failure. + */ + +tSirRetStatus limGetStaHashBssidx(tpAniSirGlobal pMac, tANI_U16 assocId, tANI_U8 *bssidx, tpPESession psessionEntry) +{ + tpDphHashNode pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("invalid STA %d"), assocId);) + return eSIR_LIM_INVALID_STA; + } + + *bssidx = (tANI_U8)pSta->bssId; + return eSIR_SUCCESS; +} + + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.h new file mode 100644 index 000000000000..43f3f4374897 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limStaHashApi.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limStaHashApi.h contains the + * function prototypes for accessing station hash entry fields. + * + * Author: Sunit Bhatia + * Date: 09/19/2006 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __LIM_STA_HASH_API_H__ +#define __LIM_STA_HASH_API_H__ + + +#include "aniGlobal.h" +#include "limTypes.h" + +tSirRetStatus limGetStaHashBssidx(tpAniSirGlobal pMac, tANI_U16 assocId, tANI_U8 *bssidx,tpPESession psessionEntry); + +#endif + + + + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c new file mode 100644 index 000000000000..1e474218b129 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.c @@ -0,0 +1,2468 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limTimerUtils.cc contains the utility functions + * LIM uses for handling various timers. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "limTypes.h" +#include "limUtils.h" +#include "limAssocUtils.h" +#include "limSecurityUtils.h" +#include "pmmApi.h" +#include "limApi.h" + +// default value 5000 ms for background scan period when it is disabled +#define LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS 5000 +// channel Switch Timer in ticks +#define LIM_CHANNEL_SWITCH_TIMER_TICKS 1 +// Lim Quite timer in ticks +#define LIM_QUIET_TIMER_TICKS 100 +// Lim Quite BSS timer interval in ticks +#define LIM_QUIET_BSS_TIMER_TICK 100 +// Lim KeepAlive timer default (3000)ms +#define LIM_KEEPALIVE_TIMER_MS 3000 +// Lim JoinProbeRequest Retry timer default (200)ms +#define LIM_JOIN_PROBE_REQ_TIMER_MS 200 +#define LIM_AUTH_RETRY_TIMER_MS 60 + + +//default beacon interval value used in HB timer interval calculation +#define LIM_HB_TIMER_BEACON_INTERVAL 100 + +/* This timer is a periodic timer which expires at every 1 sec to + convert ACTIVE DFS channel to DFS channels */ +#define ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT 1000 + +#ifdef WLAN_FEATURE_LFR_MBB +#define PREAUTH_REASSOC_TIMEOUT 500 +#endif + +/** + * limCreateTimers() + * + *FUNCTION: + * This function is called upon receiving + * 1. SME_START_REQ for STA in ESS role + * 2. SME_START_BSS_REQ for AP role & STA in IBSS role + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ + +v_UINT_t +limCreateTimers(tpAniSirGlobal pMac) +{ + tANI_U32 cfgValue, i=0; + tANI_U32 cfgValue1; + + PELOG1(limLog(pMac, LOG1, FL("Creating Timers used by LIM module in Role %d"), pMac->lim.gLimSystemRole);) + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get MinChannelTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, FL("could not retrieve MinChannelTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create MIN/MAX channel timers and activate them later + if (tx_timer_create(&pMac->lim.limTimers.gLimMinChannelTimer, + "MIN CHANNEL TIMEOUT", + limTimerHandler, SIR_LIM_MIN_CHANNEL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start min channel timer. + // Log error + limLog(pMac, LOGP, FL("could not create MIN channel timer")); + return TX_TIMER_ERROR; + } + PELOG2(limLog(pMac, LOG2, FL("Created MinChannelTimer"));) + + /* Periodic probe request timer value is half of the Min channel + * timer. Probe request sends periodically till min/max channel + * timer expires + */ + + cfgValue1 = cfgValue/2 ; + if( cfgValue1 >= 1) + { + // Create periodic probe request timer and activate them later + if (tx_timer_create(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer, + "Periodic Probe Request Timer", + limTimerHandler, SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT, + cfgValue1, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start Periodic Probe Req timer. + // Log error + limLog(pMac, LOGP, FL("could not create periodic probe timer")); + goto err_timer; + } + } + + + if (wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get MAXChannelTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve MAXChannelTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + /* Limiting max numm of probe req for each channel scan */ + pMac->lim.maxProbe = (cfgValue/cfgValue1); + + if (tx_timer_create(&pMac->lim.limTimers.gLimMaxChannelTimer, + "MAX CHANNEL TIMEOUT", + limTimerHandler, SIR_LIM_MAX_CHANNEL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start max channel timer. + // Log error + limLog(pMac, LOGP, FL("could not create MAX channel timer")); + + goto err_timer; + } + PELOG2(limLog(pMac, LOG2, FL("Created MaxChannelTimer"));) + + if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE) + { + // Create Channel Switch Timer + if (tx_timer_create(&pMac->lim.limTimers.gLimChannelSwitchTimer, + "CHANNEL SWITCH TIMER", + limChannelSwitchTimerHandler, + 0, // expiration_input + LIM_CHANNEL_SWITCH_TIMER_TICKS, // initial_ticks + 0, // reschedule_ticks + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create Channel Switch timer")); + goto err_timer; + } + + // + // Create Quiet Timer + // This is used on the STA to go and shut-off + // Tx/Rx "after" the specified quiteInterval + // + if (tx_timer_create(&pMac->lim.limTimers.gLimQuietTimer, + "QUIET TIMER", + limQuietTimerHandler, + SIR_LIM_QUIET_TIMEOUT, // expiration_input + LIM_QUIET_TIMER_TICKS, // initial_ticks + 0, // reschedule_ticks + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create Quiet Begin Timer")); + goto err_timer; + } + + // + // Create Quiet BSS Timer + // After the specified quiteInterval, determined by + // gLimQuietTimer, this timer, gLimQuietBssTimer, + // trigger and put the STA to sleep for the specified + // gLimQuietDuration + // + if (tx_timer_create(&pMac->lim.limTimers.gLimQuietBssTimer, + "QUIET BSS TIMER", + limQuietBssTimerHandler, + SIR_LIM_QUIET_BSS_TIMEOUT, // expiration_input + LIM_QUIET_BSS_TIMER_TICK, // initial_ticks + 0, // reschedule_ticks + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("failed to create Quiet Begin Timer")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get JoinFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve JoinFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Join failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimJoinFailureTimer, + "JOIN FAILURE TIMEOUT", + limTimerHandler, SIR_LIM_JOIN_FAIL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + + goto err_timer; + } + + //Send unicast probe req frame every 200 ms + if ((tx_timer_create(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, + "Periodic Join Probe Request Timer", + limTimerHandler, SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT, + SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS), 0, + TX_NO_ACTIVATE)) != TX_SUCCESS) + { + /// Could not create Periodic Join Probe Request timer. + // Log error + limLog(pMac, LOGP, FL("could not create Periodic Join Probe Request timer")); + goto err_timer; + } + //Send Auth frame every 60 ms + if ((tx_timer_create(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer, + "Periodic AUTH Timer", + limTimerHandler, SIR_LIM_AUTH_RETRY_TIMEOUT, + SYS_MS_TO_TICKS(LIM_AUTH_RETRY_TIMER_MS), 0, + TX_NO_ACTIVATE)) != TX_SUCCESS) + { + /// Could not create Periodic Join Probe Request timer. + // Log error + limLog(pMac, LOGP, FL("could not create Periodic AUTH Timer timer")); + goto err_timer; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get AssocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AssocFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Association failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimAssocFailureTimer, + "ASSOC FAILURE TIMEOUT", + limAssocFailureTimerHandler, LIM_ASSOC, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Assoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not create Association failure timer")); + + goto err_timer; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve ReassocFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Association failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimReassocFailureTimer, + "REASSOC FAILURE TIMEOUT", + limAssocFailureTimerHandler, LIM_REASSOC, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Reassoc failure timer. + // Log error + limLog(pMac, LOGP, + FL("could not create Reassociation failure timer")); + + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_ADDTS_RSP_TIMEOUT, &cfgValue) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_ADDTS_RSP_TIMEOUT ")); + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Addts response timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimAddtsRspTimer, + "ADDTS RSP TIMEOUT", + limAddtsResponseTimerHandler, + SIR_LIM_ADDTS_RSP_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Auth failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Addts response timer")); + + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + // Create Auth failure timer and activate it later + if (tx_timer_create(&pMac->lim.limTimers.gLimAuthFailureTimer, + "AUTH FAILURE TIMEOUT", + limTimerHandler, + SIR_LIM_AUTH_FAIL_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not create Auth failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Auth failure timer")); + + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get BEACON_INTERVAL value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve BEACON_INTERVAL value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimHeartBeatTimer, + "Heartbeat TIMEOUT", + limTimerHandler, + SIR_LIM_HEART_BEAT_TIMEOUT, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start Heartbeat timer. + // Log error + limLog(pMac, LOGP, + FL("call to create heartbeat timer failed")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get PROBE_AFTER_HB_FAILURE + * value from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value")); + } + + // Change timer to reactivate it in future + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimProbeAfterHBTimer, + "Probe after Heartbeat TIMEOUT", + limTimerHandler, + SIR_LIM_PROBE_HB_FAILURE_TIMEOUT, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not creat wt-probe-after-HeartBeat-failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to create ProbeAfterHBTimer")); + goto err_timer; + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get Background scan period value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Background scan period value")); + } + + /* + * setting period to zero means disabling background scans when associated + * the way we do this is to set a flag indicating this and keeping + * the timer running, since it will be used for PDU leak workarounds + * as well as background scanning during SME idle states + */ + if (cfgValue == 0) + { + cfgValue = LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS; + pMac->lim.gLimBackgroundScanDisable = true; + } + else + pMac->lim.gLimBackgroundScanDisable = false; + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimBackgroundScanTimer, + "Background scan TIMEOUT", + limTimerHandler, + SIR_LIM_CHANNEL_SCAN_TIMEOUT, + cfgValue, + cfgValue, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + /// Could not start background scan timer. + // Log error + limLog(pMac, LOGP, + FL("call to create background scan timer failed")); + goto err_timer; + } + } + + /** + * Create keepalive timer and activate it right away for AP role + */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_KEEPALIVE_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get keepalive timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve keepalive timeout value")); + } + + // A value of zero implies keep alive should be disabled + if (cfgValue == 0) + { + cfgValue = LIM_KEEPALIVE_TIMER_MS; + pMac->sch.keepAlive = 0; + } else + pMac->sch.keepAlive = 1; + + + cfgValue = SYS_MS_TO_TICKS(cfgValue + SYS_TICK_DUR_MS - 1); + + if (tx_timer_create(&pMac->lim.limTimers.gLimKeepaliveTimer, + "KEEPALIVE_TIMEOUT", + limKeepaliveTmerHandler, + 0, + cfgValue, + cfgValue, + (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) ? + TX_AUTO_ACTIVATE : TX_NO_ACTIVATE) + != TX_SUCCESS) + { + // Cannot create keepalive timer. Log error. + limLog(pMac, LOGP, FL("Cannot create keepalive timer.")); + goto err_timer; + } + + /** + * Create all CNF_WAIT Timers upfront + */ + + if (wlan_cfgGetInt(pMac, WNI_CFG_WT_CNF_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get CNF_WAIT timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve CNF timeout value")); + } + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + for (i=0; ilim.maxStation; i++) + { + if (tx_timer_create(&pMac->lim.limTimers.gpLimCnfWaitTimer[i], + "CNF_MISS_TIMEOUT", + limCnfWaitTmerHandler, + (tANI_U32)i, + cfgValue, + 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Cannot create timer. Log error. + limLog(pMac, LOGP, FL("Cannot create CNF wait timer.")); + goto err_timer; + } + } + + /* + ** Alloc and init table for the preAuth timer list + ** + **/ + + // get max number of Preauthentication + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_NUM_PRE_AUTH, + &cfgValue) != eSIR_SUCCESS) + { + /* + ** Could not get max preauth value + ** from CFG. Log error. + **/ + limLog(pMac, LOGP, + FL("could not retrieve mac preauth value")); + } + pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue; + pMac->lim.gLimPreAuthTimerTable.pTable = vos_mem_vmalloc(cfgValue*sizeof(tLimPreAuthNode)); + if(pMac->lim.gLimPreAuthTimerTable.pTable == NULL) + { + limLog(pMac, LOGP, FL("AllocateMemory failed!")); + goto err_timer; + } + + limInitPreAuthTimerTable(pMac, &pMac->lim.gLimPreAuthTimerTable); + PELOG1(limLog(pMac, LOG1, FL("alloc and init table for preAuth timers"));) + + + { + /** + * Create OLBC cache aging timer + */ + if (wlan_cfgGetInt(pMac, WNI_CFG_OLBC_DETECT_TIMEOUT, + &cfgValue) != eSIR_SUCCESS) + { + /** + * Could not get OLBC detect timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve OLBD detect timeout value")); + } + + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create( + &pMac->lim.limTimers.gLimUpdateOlbcCacheTimer, + "OLBC UPDATE CACHE TIMEOUT", + limUpdateOlbcCacheTimerHandler, + SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT, + cfgValue, + cfgValue, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Cannot create update OLBC cache timer + // Log error + limLog(pMac, LOGP, FL("Cannot create update OLBC cache timer")); + goto err_timer; + } + } +#ifdef WLAN_FEATURE_VOWIFI_11R + // In future we need to use the auth timer, cause + // the pre auth session will be introduced before sending + // Auth frame. + // We need to go off channel and come back to home channel + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimFTPreAuthRspTimer, + "FT PREAUTH RSP TIMEOUT", + limTimerHandler, SIR_LIM_FT_PREAUTH_RSP_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + goto err_timer; + } +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + cfgValue = PREAUTH_REASSOC_TIMEOUT; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer, + "PREAUTH MBB RSP TIMEOUT", + limTimerHandler, SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not create PREAUTH_MBB_RSP timer")); + goto err_timer; + } + + cfgValue = PREAUTH_REASSOC_TIMEOUT; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer, + "REASSOC MBB RSP TIMEOUT", + limTimerHandler, SIR_LIM_REASSOC_MBB_RSP_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not create REASSOC_MBB_RSP timer")); + goto err_timer; + } +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + cfgValue = 5000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + + if (tx_timer_create(&pMac->lim.limTimers.gLimEseTsmTimer, + "ESE TSM Stats TIMEOUT", + limTimerHandler, SIR_LIM_ESE_TSM_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + // Could not create Join failure timer. + // Log error + limLog(pMac, LOGP, FL("could not create Join failure timer")); + goto err_timer; + } +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimDisassocAckTimer, + "DISASSOC ACK TIMEOUT", + limTimerHandler, SIR_LIM_DISASSOC_ACK_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not DISASSOC ACK TIMEOUT timer")); + goto err_timer; + } + + cfgValue = 1000; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimDeauthAckTimer, + "DISASSOC ACK TIMEOUT", + limTimerHandler, SIR_LIM_DEAUTH_ACK_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not create DEAUTH ACK TIMEOUT timer")); + goto err_timer; + } + + cfgValue = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE; // (> no of BI* no of TUs per BI * 1TU in msec + p2p start time offset*1 TU in msec = 2*100*1.024 + 5*1.024 = 204.8 + 5.12 = 209.20) + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer, + "Single Shot NOA Insert timeout", + limTimerHandler, SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT, + cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("could not create Single Shot NOA Insert Timeout timer")); + goto err_timer; + } + + cfgValue = WNI_CFG_ACTIVE_PASSIVE_CON_MAX; + if (eSIR_SUCCESS != wlan_cfgGetInt(pMac, WNI_CFG_ACTIVE_PASSIVE_CON, + &cfgValue)) + { + limLog(pMac, LOGP, + FL("could not retrieve WNI_CFG_ACTIVE_PASSIVE_CON")); + } + if (cfgValue) + { + cfgValue = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT; + cfgValue = SYS_MS_TO_TICKS(cfgValue); + if (tx_timer_create(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, + "ACTIVE TO PASSIVE CHANNEL", limTimerHandler, + SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE, cfgValue, 0, + TX_NO_ACTIVATE) != TX_SUCCESS) + { + limLog(pMac, LOGW,FL("could not create timer for passive channel to active channel")); + goto err_timer; + } + } + else + { + limLog(pMac, LOG1, + FL("gLimActiveToPassiveChannelTimer not created %d"), cfgValue); + } + + return TX_SUCCESS; + + err_timer: + tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer); +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer); +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer); +#ifdef WLAN_FEATURE_LFR_MBB + tx_timer_delete(&pMac->lim.limTimers.glim_pre_auth_mbb_rsp_timer); + tx_timer_delete(&pMac->lim.limTimers.glim_reassoc_mbb_rsp_timer); +#endif + tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer); + while(((tANI_S32)--i) >= 0) + { + tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[i]); + } + tx_timer_delete(&pMac->lim.limTimers.gLimKeepaliveTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimBackgroundScanTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimHeartBeatTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMaxChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMinChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + + if(NULL != pMac->lim.gLimPreAuthTimerTable.pTable) + { + vos_mem_vfree(pMac->lim.gLimPreAuthTimerTable.pTable); + pMac->lim.gLimPreAuthTimerTable.pTable = NULL; + } + + return TX_TIMER_ERROR; + +} /****** end limCreateTimers() ******/ + + + +/** + * limTimerHandler() + * + *FUNCTION: + * This function is called upon + * 1. MIN_CHANNEL, MAX_CHANNEL timer expiration during scanning + * 2. JOIN_FAILURE timer expiration while joining a BSS + * 3. AUTH_FAILURE timer expiration while authenticating with a peer + * 4. Heartbeat timer expiration on STA + * 5. Background scan timer expiration on STA + * 6. AID release, Pre-auth cleanup and Link monitoring timer + * expiration on AP + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - Message corresponding to the timer that expired + * + * @return None + */ + +void +limTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tANI_U32 statusCode; + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = (tANI_U16) param; + msg.bodyptr = NULL; + msg.bodyval = 0; + + if ((statusCode = limPostMsgApiHighPri(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting message %X to LIM failed, reason=%d"), + msg.type, statusCode); +} /****** end limTimerHandler() ******/ + + +/** + * limAddtsResponseTimerHandler() + * + *FUNCTION: + * This function is called upon Addts response timer expiration on sta + * + *LOGIC: + * Message SIR_LIM_ADDTS_RSP_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - pointer to pre-auth node + * + * @return None + */ + +void +limAddtsResponseTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_ADDTS_RSP_TIMEOUT; + msg.bodyval = param; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} /****** end limAuthResponseTimerHandler() ******/ + + +/** + * limAuthResponseTimerHandler() + * + *FUNCTION: + * This function is called upon Auth response timer expiration on AP + * + *LOGIC: + * Message SIR_LIM_AUTH_RSP_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - pointer to pre-auth node + * + * @return None + */ + +void +limAuthResponseTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_AUTH_RSP_TIMEOUT; + msg.bodyptr = NULL; + msg.bodyval = (tANI_U32)param; + + limPostMsgApi(pMac, &msg); +} /****** end limAuthResponseTimerHandler() ******/ + + + +/** + * limAssocFailureTimerHandler() + * + *FUNCTION: + * This function is called upon Re/Assoc failure timer expiration + * on STA + * + *LOGIC: + * Message SIR_LIM_ASSOC_FAIL_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - Indicates whether this is assoc or reassoc + * failure timeout + * @return None + */ + +void +limAssocFailureTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if((LIM_REASSOC == param) && + (NULL != pMac->lim.pSessionEntry) && + (pMac->lim.pSessionEntry->limMlmState == eLIM_MLM_WT_FT_REASSOC_RSP_STATE)) + { + limLog(pMac, LOGE, FL("Reassoc timeout happened")); +#ifdef FEATURE_WLAN_ESE + if (((pMac->lim.pSessionEntry->isESEconnection) && + (pMac->lim.reAssocRetryAttempt < + (LIM_MAX_REASSOC_RETRY_LIMIT - 1)))|| + ((!pMac->lim.pSessionEntry->isESEconnection) && + (pMac->lim.reAssocRetryAttempt < LIM_MAX_REASSOC_RETRY_LIMIT)) + ) +#else + if (pMac->lim.reAssocRetryAttempt < LIM_MAX_REASSOC_RETRY_LIMIT) +#endif + { + limSendRetryReassocReqFrame(pMac, pMac->lim.pSessionEntry->pLimMlmReassocRetryReq, pMac->lim.pSessionEntry); + pMac->lim.reAssocRetryAttempt++; + limLog(pMac, LOGW, FL("Reassoc request retry is sent %d times"), pMac->lim.reAssocRetryAttempt); + return; + } + else + { + limLog(pMac, LOGW, FL("Reassoc request retry MAX(%d) reached"), LIM_MAX_REASSOC_RETRY_LIMIT); + if(NULL != pMac->lim.pSessionEntry->pLimMlmReassocRetryReq) + { + vos_mem_free( pMac->lim.pSessionEntry->pLimMlmReassocRetryReq); + pMac->lim.pSessionEntry->pLimMlmReassocRetryReq = NULL; + } + } + } +#endif + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_ASSOC_FAIL_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} /****** end limAssocFailureTimerHandler() ******/ + + +/** + * limUpdateOlbcCacheTimerHandler() + * + *FUNCTION: + * This function is called upon update olbc cache timer expiration + * on STA + * + *LOGIC: + * Message SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT is posted to gSirLimMsgQ + * when this function is executed. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param + * + * @return None + */ +void +limUpdateOlbcCacheTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + + msg.type = SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT; + msg.bodyval = 0; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} /****** end limUpdateOlbcCacheTimerHandler() ******/ + +/** + * limDeactivateAndChangeTimer() + * + *FUNCTION: + * This function is called to deactivate and change a timer + * for future re-activation + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param timerId - enum of timer to be deactivated and changed + * This enum is defined in limUtils.h file + * + * @return None + */ + +void +limDeactivateAndChangeTimer(tpAniSirGlobal pMac, tANI_U32 timerId) +{ + tANI_U32 val=0, val1=0; + tpPESession psessionEntry; + + switch (timerId) + { + case eLIM_ADDTS_RSP_TIMER: + pMac->lim.gLimAddtsRspTimerCount++; + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer) != TX_SUCCESS) + { + // Could not deactivate AddtsRsp Timer + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate AddtsRsp timer")); + } + break; + + case eLIM_MIN_CHANNEL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMinChannelTimer) + != TX_SUCCESS) + { + // Could not deactivate min channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate min channel timer")); + } + +#if 0 + // If a background was triggered via Quiet BSS, + // then we need to adjust the MIN and MAX channel + // timer's accordingly to the Quiet duration that + // was specified + if( eLIM_QUIET_RUNNING == pMac->lim.gLimSpecMgmt.quietState && + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss ) + { + // gLimQuietDuration is already cached in units of + // system ticks. No conversion is reqd... + val = pMac->lim.gLimSpecMgmt.quietDuration; + } + else + { +#endif + if(pMac->lim.gpLimMlmScanReq) + { + val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime); + if (pMac->btc.btc_scan_compromise_esco) + { + if (pMac->lim.gpLimMlmScanReq->min_chntime_btc_esco) + { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->min_chntime_btc_esco); + limLog(pMac, LOG1, FL("Using BTC Min Active Scan time")); + } + else + { + limLog(pMac, LOGE, FL("BTC Active Scan Min Time is Not Set")); + } + } else if (pMac->btc.btc_scan_compromise_sco && + pMac->roam.configParam.min_chntime_btc_sco) { + val = SYS_MS_TO_TICKS( + pMac->roam.configParam.min_chntime_btc_sco); + limLog(pMac, LOG1, + FL("Using BTC SCO Min Active Scan time %d"), val); + } + } + else + { + limLog(pMac, LOGE, FL(" gpLimMlmScanReq is NULL ")); + //No need to change min timer. This is not a scan + break; + } +#if 0 + } +#endif + + if (tx_timer_change(&pMac->lim.limTimers.gLimMinChannelTimer, + val, 0) != TX_SUCCESS) + { + // Could not change min channel timer. + // Log error + limLog(pMac, LOGP, FL("Unable to change min channel timer")); + } + + break; + + case eLIM_PERIODIC_PROBE_REQ_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer) + != TX_SUCCESS) + { + // Could not deactivate min channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate periodic timer")); + } + if(pMac->lim.gpLimMlmScanReq) + { + val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->minChannelTime)/2; + if (pMac->btc.btc_scan_compromise_esco) + { + if (pMac->lim.gpLimMlmScanReq->min_chntime_btc_esco) + { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->min_chntime_btc_esco)/2; + limLog(pMac, LOG1, FL("Using BTC Min Active Scan time")); + } + else + { + limLog(pMac, LOGE, FL("BTC Active Scan Min Time is Not Set")); + } + } else if (pMac->btc.btc_scan_compromise_sco && + pMac->roam.configParam.min_chntime_btc_sco) { + val = SYS_MS_TO_TICKS( + pMac->roam.configParam.min_chntime_btc_sco / 2); + limLog(pMac, LOG1, + FL("Using BTC SCO Min Active Scan time %d"), val); + } + } + /*If val is 0 it means min Channel timer is 0 so take the value from maxChannelTimer*/ + if (!val) + { + + if(pMac->lim.gpLimMlmScanReq) + { + val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->maxChannelTime)/2; + if (pMac->btc.btc_scan_compromise_esco) + { + if (pMac->lim.gpLimMlmScanReq->max_chntime_btc_esco) + { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->max_chntime_btc_esco)/2; + limLog(pMac, LOG1, FL("Using BTC Max Active Scan time")); + } + else + { + limLog(pMac, LOGE, FL("BTC Active Scan Max Time is Not Set")); + } + } else if (pMac->btc.btc_scan_compromise_sco && + pMac->roam.configParam.max_chntime_btc_sco) { + val = SYS_MS_TO_TICKS( + pMac->roam.configParam.max_chntime_btc_sco / 2); + limLog(pMac, LOG1, + FL("Using BTC SCO Max Active Scan time %d"), val); + } + } + else + { + limLog(pMac, LOGE, FL(" gpLimMlmScanReq is NULL ")); + //No need to change max timer. This is not a scan + break; + } + } + if (val) + { + if (tx_timer_change(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer, + val, 0) != TX_SUCCESS) + { + // Could not change min channel timer. + // Log error + limLog(pMac, LOGE, FL("Unable to change periodic timer")); + } + } + else + { + limLog(pMac, LOGE, FL("Do not change gLimPeriodicProbeReqTimer values," + "value = %d minchannel time = %d" + "maxchannel time = %d"), val, + pMac->lim.gpLimMlmScanReq->minChannelTime, + pMac->lim.gpLimMlmScanReq->maxChannelTime); + } + + break; + + case eLIM_MAX_CHANNEL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer) + != TX_SUCCESS) + { + // Could not deactivate max channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate max channel timer")); + } + + // If a background was triggered via Quiet BSS, + // then we need to adjust the MIN and MAX channel + // timer's accordingly to the Quiet duration that + // was specified + if (pMac->lim.gLimSystemRole != eLIM_AP_ROLE) + { +#if 0 + + if( eLIM_QUIET_RUNNING == pMac->lim.gLimSpecMgmt.quietState && + pMac->lim.gLimTriggerBackgroundScanDuringQuietBss ) + { + // gLimQuietDuration is already cached in units of + // system ticks. No conversion is reqd... + val = pMac->lim.gLimSpecMgmt.quietDuration; + } + else + { +#endif + if(pMac->lim.gpLimMlmScanReq) + { + val = SYS_MS_TO_TICKS(pMac->lim.gpLimMlmScanReq->maxChannelTime); + if (pMac->btc.btc_scan_compromise_esco) + { + if (pMac->lim.gpLimMlmScanReq->max_chntime_btc_esco) + { + val = SYS_MS_TO_TICKS( + pMac->lim.gpLimMlmScanReq->max_chntime_btc_esco); + limLog(pMac, LOG1, FL("Using BTC Max Active Scan time")); + } + else + { + limLog(pMac, LOGE, FL("BTC Active Scan Max Time is Not Set")); + } + } else if (pMac->btc.btc_scan_compromise_sco && + pMac->roam.configParam.max_chntime_btc_sco) { + val = SYS_MS_TO_TICKS( + pMac->roam.configParam.max_chntime_btc_sco); + limLog(pMac, LOG1, + FL("Using BTC SCO Max Active Scan time %d"), val); + } + } + else + { + limLog(pMac, LOGE, FL(" gpLimMlmScanReq is NULL ")); + //No need to change max timer. This is not a scan + break; + } +#if 0 + } +#endif + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimMaxChannelTimer, + val, 0) != TX_SUCCESS) + { + // Could not change max channel timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to change max channel timer")); + } + + break; + + case eLIM_JOIN_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimJoinFailureTimer) + != TX_SUCCESS) + { + /** + * Could not deactivate Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, + FL("Unable to deactivate Join Failure timer")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get JoinFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve JoinFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimJoinFailureTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, + FL("Unable to change Join Failure timer")); + } + + break; + + case eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer) + != TX_SUCCESS) + { + // Could not deactivate periodic join req Times. + limLog(pMac, LOGP, + FL("Unable to deactivate periodic join request timer")); + } + + val = SYS_MS_TO_TICKS(LIM_JOIN_PROBE_REQ_TIMER_MS); + if (tx_timer_change(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer, + val, 0) != TX_SUCCESS) + { + // Could not change periodic join req times. + // Log error + limLog(pMac, LOGP, FL("Unable to change periodic join request timer")); + } + + break; + + case eLIM_AUTH_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAuthFailureTimer) + != TX_SUCCESS) + { + // Could not deactivate Auth failure timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate auth failure timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get AuthFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AuthFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimAuthFailureTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Authentication failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change Auth failure timer")); + } + + break; + + case eLIM_AUTH_RETRY_TIMER: + + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer) + != TX_SUCCESS) + { + // Could not deactivate Auth Retry Timer. + limLog(pMac, LOGP, + FL("Unable to deactivate Auth Retry timer")); + } + if ((psessionEntry = peFindSessionBySessionId(pMac, + pMac->lim.limTimers.gLimPeriodicAuthRetryTimer.sessionId)) + == NULL) + { + limLog(pMac, LOGP, + FL("session does not exist for given SessionId : %d"), + pMac->lim.limTimers.gLimPeriodicAuthRetryTimer.sessionId); + break; + } + /* 3/5 of the beacon interval*/ + val = psessionEntry->beaconParams.beaconInterval * 3/5; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Auth Retry timer. + // Log error + limLog(pMac, LOGP, FL("Unable to change Auth Retry timer")); + } + + break; + + case eLIM_ASSOC_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimAssocFailureTimer) != + TX_SUCCESS) + { + // Could not deactivate Association failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate Association failure timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOCIATION_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get AssocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve AssocFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimAssocFailureTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Association failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change Assoc failure timer")); + } + + break; + + case eLIM_REASSOC_FAIL_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer) != + TX_SUCCESS) + { + // Could not deactivate Reassociation failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate Reassoc failure timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get ReassocFailureTimeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve ReassocFailureTimeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimReassocFailureTimer, + val, 0) != TX_SUCCESS) + { + // Could not change Reassociation failure timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change Reassociation failure timer")); + } + + break; + + case eLIM_HEART_BEAT_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer) != + TX_SUCCESS) + { + // Could not deactivate Heartbeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate Heartbeat timer")); + } + else + { + limLog(pMac, LOGW, FL("Deactivated heartbeat link monitoring")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, + &val) != eSIR_SUCCESS) + { + /** + * Could not get BEACON_INTERVAL value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve BEACON_INTERVAL value")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != + eSIR_SUCCESS) + limLog(pMac, LOGP, + FL("could not retrieve heartbeat failure value")); + + // Change timer to reactivate it in future + val = SYS_MS_TO_TICKS(val * val1); + + if (tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, + val, 0) != TX_SUCCESS) + { + // Could not change HeartBeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change HeartBeat timer")); + } + else + { + limLog(pMac, LOGW, FL("HeartBeat timer value is changed = %u"), val); + } + break; + + case eLIM_PROBE_AFTER_HB_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != + TX_SUCCESS) + { + // Could not deactivate Heartbeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate probeAfterHBTimer")); + } + else + { + limLog(pMac, LOG1, FL("Deactivated probe after hb timer")); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_AFTER_HB_FAIL_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get PROBE_AFTER_HB_FAILURE + * value from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve PROBE_AFTER_HB_FAIL_TIMEOUT value")); + } + + // Change timer to reactivate it in future + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimProbeAfterHBTimer, + val, 0) != TX_SUCCESS) + { + // Could not change HeartBeat timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change ProbeAfterHBTimer")); + } + else + { + limLog(pMac, LOGW, FL("Probe after HB timer value is changed = %u"), val); + } + + break; + + case eLIM_KEEPALIVE_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimKeepaliveTimer) + != TX_SUCCESS) + { + // Could not deactivate Keepalive timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate KeepaliveTimer timer")); + } + + // Change timer to reactivate it in future + + if (wlan_cfgGetInt(pMac, WNI_CFG_KEEPALIVE_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get keepalive timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve keepalive timeout value")); + } + if (val == 0) + { + val = 3000; + pMac->sch.keepAlive = 0; + } else + pMac->sch.keepAlive = 1; + + + + val = SYS_MS_TO_TICKS(val + SYS_TICK_DUR_MS - 1); + + if (tx_timer_change(&pMac->lim.limTimers.gLimKeepaliveTimer, + val, val) != TX_SUCCESS) + { + // Could not change KeepaliveTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change KeepaliveTimer timer")); + } + + break; + + case eLIM_BACKGROUND_SCAN_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer) + != TX_SUCCESS) + { + // Could not deactivate BackgroundScanTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to deactivate BackgroundScanTimer timer")); + } + + // Change timer to reactivate it in future + if (wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &val) != eSIR_SUCCESS) + { + /** + * Could not get Background scan period value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve Background scan period value")); + } + if (val == 0) + { + val = LIM_BACKGROUND_SCAN_PERIOD_DEFAULT_MS; + pMac->lim.gLimBackgroundScanDisable = true; + } + else + pMac->lim.gLimBackgroundScanDisable = false; + + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gLimBackgroundScanTimer, + val, val) != TX_SUCCESS) + { + // Could not change BackgroundScanTimer timer. + // Log error + limLog(pMac, LOGP, + FL("unable to change BackgroundScanTimer timer")); + } + + break; + +#if 0 + case eLIM_CHANNEL_SWITCH_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_deactivate failed!")); + return; + } + + if (tx_timer_change(&pMac->lim.limTimers.gLimChannelSwitchTimer, + pMac->lim.gLimChannelSwitch.switchTimeoutValue, + 0) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_change failed ")); + return; + } + break; +#endif + + case eLIM_LEARN_DURATION_TIMER: + break; + +#if 0 + case eLIM_QUIET_BSS_TIMER: + if (TX_SUCCESS != + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)) + { + limLog( pMac, LOGE, + FL("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway...")); + } + + // gLimQuietDuration appears to be in units of ticks + // Use it as is + if (TX_SUCCESS != + tx_timer_change( &pMac->lim.limTimers.gLimQuietBssTimer, + pMac->lim.gLimSpecMgmt.quietDuration, + 0)) + { + limLog( pMac, LOGE, + FL("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway...")); + } + break; + + case eLIM_QUIET_TIMER: + if( TX_SUCCESS != tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer)) + { + limLog( pMac, LOGE, + FL( "Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway..." )); + } + + // Set the NEW timeout value, in ticks + if( TX_SUCCESS != tx_timer_change( &pMac->lim.limTimers.gLimQuietTimer, + SYS_MS_TO_TICKS(pMac->lim.gLimSpecMgmt.quietTimeoutValue), 0)) + { + limLog( pMac, LOGE, + FL( "Unable to change gLimQuietTimer! Will still attempt to re-activate anyway..." )); + } + break; +#endif + +#if 0 + case eLIM_WPS_OVERLAP_TIMER: + { + // Restart Learn Interval timer + + tANI_U32 WPSOverlapTimer = SYS_MS_TO_TICKS(LIM_WPS_OVERLAP_TIMER_MS); + + if (tx_timer_deactivate( + &pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS) + { + // Could not deactivate Learn Interval timer. + // Log error + limLog(pMac, LOGP, + FL("Unable to deactivate WPS overlap timer")); + } + + if (tx_timer_change( + &pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer, + WPSOverlapTimer, 0) != TX_SUCCESS) + { + // Could not change Learn Interval timer. + // Log error + limLog(pMac, LOGP, FL("Unable to change WPS overlap timer")); + + return; + } + + limLog( pMac, LOGE, + FL("Setting WPS overlap TIMER to %d ticks"), + WPSOverlapTimer); + } + break; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + case eLIM_FT_PREAUTH_RSP_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Preauth response Failure timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimFTPreAuthRspTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change Join Failure timer")); + return; + } + break; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + case eLIM_PREAUTH_MBB_RSP_TIMER: + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, + NO_SESSION, eLIM_PREAUTH_MBB_RSP_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers. + glim_pre_auth_mbb_rsp_timer) != TX_SUCCESS) { + limLog(pMac, LOGP, + FL("Unable to deactivate preauth response mbb timer")); + return; + } + break; + case eLIM_REASSOC_MBB_RSP_TIMER: + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, + NO_SESSION, eLIM_REASSOC_MBB_RSP_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers. + glim_reassoc_mbb_rsp_timer) != TX_SUCCESS) { + limLog(pMac, LOGP, + FL("Unable to deactivate reassoc response mbb timer")); + return; + } + break; +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + case eLIM_TSM_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer) + != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("Unable to deactivate TSM timer")); + } + break; +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + + case eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Active to passive channel timer. + ** Log error. + **/ + limLog(pMac, LOGP, FL("Unable to Deactivate " + "Active to passive channel timer")); + return; + } + val = ACTIVE_TO_PASSIVE_CONVERISON_TIMEOUT; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change timer to check scan type for passive channel. + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_DISASSOC_ACK_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDisassocAckTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Disassoc ack timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimDisassocAckTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_DEAUTH_ACK_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate Join Failure + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate Deauth ack timer")); + return; + } + val = 1000; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimDeauthAckTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Join Failure + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + case eLIM_INSERT_SINGLESHOT_NOA_TIMER: + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer) != TX_SUCCESS) + { + /** + ** Could not deactivate SingleShot NOA Insert + ** timer. Log error. + **/ + limLog(pMac, LOGP, FL("Unable to deactivate SingleShot NOA Insert timer")); + return; + } + val = LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE; + val = SYS_MS_TO_TICKS(val); + if (tx_timer_change(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer, + val, 0) != TX_SUCCESS) + { + /** + * Could not change Single Shot NOA Insert + * timer. Log error. + */ + limLog(pMac, LOGP, FL("Unable to change timer")); + return; + } + break; + + default: + // Invalid timerId. Log error + break; + } +} /****** end limDeactivateAndChangeTimer() ******/ + + + +/**--------------------------------------------------------------- +\fn limHeartBeatDeactivateAndChangeTimer +\brief This function deactivates and changes the heart beat +\ timer, eLIM_HEART_BEAT_TIMER. +\ +\param pMac +\param psessionEntry +\return None +------------------------------------------------------------------*/ +void +limHeartBeatDeactivateAndChangeTimer(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 val, val1; + + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("%s: received session id NULL." + " Heartbeat timer config failed"), __func__); + return; + } + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + return; +#endif + + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer) != TX_SUCCESS) + limLog(pMac, LOGP, FL("Fail to deactivate HeartBeatTimer ")); + + /* HB Timer sessionisation: In case of 2 or more sessions, the HB interval keeps + changing. to avoid this problem, HeartBeat interval is made constant, by + fixing beacon interval to 100ms immaterial of the beacon interval of the session */ + + //val = psessionEntry->beaconParams.beaconInterval; + val = LIM_HB_TIMER_BEACON_INTERVAL; + + if (wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &val1) != eSIR_SUCCESS) + limLog(pMac, LOGP, FL("Fail to get WNI_CFG_HEART_BEAT_THRESHOLD ")); + + PELOGW(limLog(pMac,LOGW, + FL("HB Timer Int.=100ms * %d, Beacon Int.=%dms,Session Id=%d "), + val1, psessionEntry->beaconParams.beaconInterval, + psessionEntry->peSessionId);) + + /* The HB timer timeout value of 4 seconds (40 beacon intervals) is not + * enough to judge the peer device inactivity when 32 peers are connected. + * Hence increasing the HB timer timeout to + * HBtimeout = (TBTT * num_beacons * num_peers) + */ + if (eSIR_IBSS_MODE == psessionEntry->bssType && + pMac->lim.gLimNumIbssPeers > 0) + { + val1 = val1 * pMac->lim.gLimNumIbssPeers; + } + + // Change timer to reactivate it in future + val = SYS_MS_TO_TICKS(val * val1); + + if (tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, val, 0) != TX_SUCCESS) + limLog(pMac, LOGP, FL("Fail to change HeartBeatTimer")); + +} /****** end limHeartBeatDeactivateAndChangeTimer() ******/ + + +/**--------------------------------------------------------------- +\fn limReactivateHeartBeatTimer +\brief This function s called to deactivate, change and +\ activate a timer. +\ +\param pMac - Pointer to Global MAC structure +\param psessionEntry +\return None +------------------------------------------------------------------*/ +void +limReactivateHeartBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (NULL == psessionEntry) + { + limLog(pMac, LOGE, FL("%s: received session id NULL." + " Heartbeat timer config failed"), __func__); + return; + } + + PELOG3(limLog(pMac, LOG3, FL("Rxed Heartbeat. Count=%d"), psessionEntry->LimRxedBeaconCntDuringHB);) + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + limLog(pMac, LOGW, FL("Active offload feature is enabled, FW takes care of HB monitoring")); + return; + } +#endif + + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + + //only start the hearbeat-timer if the timeout value is non-zero + if(pMac->lim.limTimers.gLimHeartBeatTimer.initScheduleTimeInMsecs > 0) + { + /* + * There is increasing need to limit the apps wakeup due to WLAN + * activity. During HB monitoring, the beacons from peer are sent to + * the host causing the host to wakeup. Hence, offloading the HB + * monitoring to LMAC + */ + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && + IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) + { + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGP,FL("IBSS HeartBeat Offloaded, Could not deactivate Heartbeat timer")); + } + else + { + limLog(pMac, LOGE, FL("IBSS HeartBeat Offloaded, Deactivated heartbeat link monitoring")); + } + } + else + { + if (tx_timer_activate(&pMac->lim.limTimers.gLimHeartBeatTimer)!= TX_SUCCESS) + { + limLog(pMac, LOGP,FL("could not activate Heartbeat timer")); + } + else + { + limLog(pMac, LOGW, FL("Reactivated heartbeat link monitoring")); + } + } + limResetHBPktCount(psessionEntry); + } + +} /****** end limReactivateHeartBeatTimer() ******/ + + +/** + * limActivateHearBeatTimer() + * + * + * @brief: This function is called to activate heartbeat timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index. + * + * @param pMac - Pointer to Global MAC structure + * @param psessionEntry - Session Entry + * + * @return TX_SUCCESS - timer is activated + * errors - fail to start the timer + */ +v_UINT_t limActivateHearBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + v_UINT_t status = TX_TIMER_ERROR; + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + return (TX_SUCCESS); +#endif + + if(TX_AIRGO_TMR_SIGNATURE == pMac->lim.limTimers.gLimHeartBeatTimer.tmrSignature) + { + //consider 0 interval a ok case + if( pMac->lim.limTimers.gLimHeartBeatTimer.initScheduleTimeInMsecs ) + { + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE && + IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) + { + /* HB offload in IBSS mode */ + status = tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer); + if (TX_SUCCESS != status) + { + PELOGE(limLog(pMac, LOGE, + FL("IBSS HB Offload, Could not deactivate HB timer status(%d)"), + status);) + } + else + { + PELOGE(limLog(pMac, LOGE, + FL("%s] IBSS HB Offloaded, Heartbeat timer deactivated"), + __func__);) + } + + } + else + { + status = tx_timer_activate(&pMac->lim.limTimers.gLimHeartBeatTimer); + if ( TX_SUCCESS != status ) + { + PELOGE(limLog(pMac, LOGE, + FL("could not activate Heartbeat timer status(%d)"), status);) + } + else + { + PELOGE(limLog(pMac, LOGW, + FL("%s] Activated Heartbeat timer status(%d)"), __func__, status);) + } + } + } + else + { + status = TX_SUCCESS; + } + } + + return (status); +} + + + +/** + * limDeactivateAndChangePerStaIdTimer() + * + * + * @brief: This function is called to deactivate and change a per STA timer + * for future re-activation + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index. + * + * @param pMac - Pointer to Global MAC structure + * @param timerId - enum of timer to be deactivated and changed + * This enum is defined in limUtils.h file + * @param staId - staId + * + * @return None + */ + +void +limDeactivateAndChangePerStaIdTimer(tpAniSirGlobal pMac, tANI_U32 timerId, tANI_U16 staId) +{ + tANI_U32 val; + + switch (timerId) + { + case eLIM_CNF_WAIT_TIMER: + + if (tx_timer_deactivate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId]) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("unable to deactivate CNF wait timer")); + + } + + // Change timer to reactivate it in future + + if (wlan_cfgGetInt(pMac, WNI_CFG_WT_CNF_TIMEOUT, + &val) != eSIR_SUCCESS) + { + /** + * Could not get cnf timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve cnf timeout value")); + } + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId], + val, val) != TX_SUCCESS) + { + // Could not change cnf timer. + // Log error + limLog(pMac, LOGP, FL("unable to change cnf wait timer")); + } + + break; + + case eLIM_AUTH_RSP_TIMER: + { + tLimPreAuthNode *pAuthNode; + + pAuthNode = limGetPreAuthNodeFromIndex(pMac, &pMac->lim.gLimPreAuthTimerTable, staId); + + if (pAuthNode == NULL) + { + limLog(pMac, LOGP, FL("Invalid Pre Auth Index passed :%d"), staId); + break; + } + + if (tx_timer_deactivate(&pAuthNode->timer) != TX_SUCCESS) + { + // Could not deactivate auth response timer. + // Log error + limLog(pMac, LOGP, FL("unable to deactivate auth response timer")); + } + + // Change timer to reactivate it in future + + if (wlan_cfgGetInt(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT, &val) != eSIR_SUCCESS) + { + /** + * Could not get auth rsp timeout value + * from CFG. Log error. + */ + limLog(pMac, LOGP, + FL("could not retrieve auth response timeout value")); + } + + val = SYS_MS_TO_TICKS(val); + + if (tx_timer_change(&pAuthNode->timer, val, 0) != TX_SUCCESS) + { + // Could not change auth rsp timer. + // Log error + limLog(pMac, LOGP, FL("unable to change auth rsp timer")); + } + } + break; + + + default: + // Invalid timerId. Log error + break; + + } +} + + +/** + * limActivateCnfTimer() + * + *FUNCTION: + * This function is called to activate a per STA timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param StaId - staId + * + * @return None + */ + +void limActivateCnfTimer(tpAniSirGlobal pMac, tANI_U16 staId, tpPESession psessionEntry) +{ + pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId = psessionEntry->peSessionId; + if (tx_timer_activate(&pMac->lim.limTimers.gpLimCnfWaitTimer[staId]) + != TX_SUCCESS) + { + limLog(pMac, LOGP, + FL("could not activate cnf wait timer")); + } +} + +/** + * limActivateAuthRspTimer() + * + *FUNCTION: + * This function is called to activate a per STA timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param id - id + * + * @return None + */ + +void limActivateAuthRspTimer(tpAniSirGlobal pMac, tLimPreAuthNode *pAuthNode) +{ + if (tx_timer_activate(&pAuthNode->timer) != TX_SUCCESS) + { + /// Could not activate auth rsp timer. + // Log error + limLog(pMac, LOGP, + FL("could not activate auth rsp timer")); + } +} + + +/** + * limAssocCnfWaitTmerHandler() + * + *FUNCTION: + * This function post a message to send a disassociate frame out. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param + * + * @return None + */ + +void +limCnfWaitTmerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tANI_U32 statusCode; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_CNF_WAIT_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting to LIM failed, reason=%d"), statusCode); + +} + +/** + * limKeepaliveTmerHandler() + * + *FUNCTION: + * This function post a message to send a NULL data frame. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * NA + * + * @param + * + * @return None + */ + +void +limKeepaliveTmerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tANI_U32 statusCode; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_KEEPALIVE_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting to LIM failed, reason=%d"), statusCode); + +} + +void +limChannelSwitchTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + limLog(pMac, LOG1, + FL("ChannelSwitch Timer expired. Posting msg to LIM ")); + + msg.type = SIR_LIM_CHANNEL_SWITCH_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + limPostMsgApi(pMac, &msg); +} + +void +limQuietTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_QUIET_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + + limLog(pMac, LOG1, + FL("Post SIR_LIM_QUIET_TIMEOUT msg. ")); + limPostMsgApi(pMac, &msg); +} + +void +limQuietBssTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_QUIET_BSS_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + limLog(pMac, LOG1, + FL("Post SIR_LIM_QUIET_BSS_TIMEOUT msg. ")); + limPostMsgApi(pMac, &msg); +} +#if 0 +void +limWPSOverlapTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + msg.type = SIR_LIM_WPS_OVERLAP_TIMEOUT; + msg.bodyval = (tANI_U32)param; + msg.bodyptr = NULL; + PELOG1(limLog(pMac, LOG1, + FL("Post SIR_LIM_WPS_OVERLAP_TIMEOUT msg. "));) + limPostMsgApi(pMac, &msg); +} +#endif + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +/* ACTIVE_MODE_HB_OFFLOAD */ +/** + * limMissedBeaconInActiveMode() + * + *FUNCTION: + * This function handle beacon miss indication from FW + * in Active mode. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param param - Msg Type + * + * @return None + */ +void +limMissedBeaconInActiveMode(void *pMacGlobal, tpPESession psessionEntry) +{ + tANI_U32 statusCode; + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + + // Prepare and post message to LIM Message Queue + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + msg.type = (tANI_U16) SIR_LIM_HEART_BEAT_TIMEOUT; + msg.bodyptr = psessionEntry; + msg.bodyval = 0; + limLog(pMac, LOGE, + FL("Heartbeat failure from Riva")); + if ((statusCode = limPostMsgApi(pMac, &msg)) != eSIR_SUCCESS) + limLog(pMac, LOGE, + FL("posting message %X to LIM failed, reason=%d"), + msg.type, statusCode); + } +} +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h new file mode 100644 index 000000000000..eba64ac72a72 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTimerUtils.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file limTimerUtils.h contains the utility definitions + * LIM uses for timer handling. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_TIMER_UTILS_H +#define __LIM_TIMER_UTILS_H + +#include "limTypes.h" + + +// Timer related functions +enum +{ + eLIM_MIN_CHANNEL_TIMER, + eLIM_MAX_CHANNEL_TIMER, + eLIM_JOIN_FAIL_TIMER, + eLIM_AUTH_FAIL_TIMER, + eLIM_AUTH_RESP_TIMER, + eLIM_ASSOC_FAIL_TIMER, + eLIM_REASSOC_FAIL_TIMER, + eLIM_PRE_AUTH_CLEANUP_TIMER, + eLIM_HEART_BEAT_TIMER, + eLIM_BACKGROUND_SCAN_TIMER, + eLIM_KEEPALIVE_TIMER, + eLIM_CNF_WAIT_TIMER, + eLIM_AUTH_RSP_TIMER, + eLIM_UPDATE_OLBC_CACHE_TIMER, + eLIM_PROBE_AFTER_HB_TIMER, + eLIM_ADDTS_RSP_TIMER, + eLIM_CHANNEL_SWITCH_TIMER, + eLIM_LEARN_DURATION_TIMER, + eLIM_QUIET_TIMER, + eLIM_QUIET_BSS_TIMER, + eLIM_WPS_OVERLAP_TIMER, +#ifdef WLAN_FEATURE_VOWIFI_11R + eLIM_FT_PREAUTH_RSP_TIMER, +#endif + eLIM_PERIODIC_PROBE_REQ_TIMER, +#ifdef FEATURE_WLAN_ESE + eLIM_TSM_TIMER, +#endif + eLIM_DISASSOC_ACK_TIMER, + eLIM_DEAUTH_ACK_TIMER, + eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER, + eLIM_INSERT_SINGLESHOT_NOA_TIMER, + eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE, + eLIM_AUTH_RETRY_TIMER, +#ifdef WLAN_FEATURE_LFR_MBB + eLIM_PREAUTH_MBB_RSP_TIMER, + eLIM_REASSOC_MBB_RSP_TIMER +#endif +}; + +#define LIM_DISASSOC_DEAUTH_ACK_TIMEOUT 500 +#define LIM_INSERT_SINGLESHOTNOA_TIMEOUT_VALUE 500 + + +// Timer Handler functions +v_UINT_t limCreateTimers(tpAniSirGlobal); +void limTimerHandler(void *, tANI_U32); +void limAuthResponseTimerHandler(void *, tANI_U32); +void limAssocFailureTimerHandler(void *, tANI_U32); +void limReassocFailureTimerHandler(void *, tANI_U32); + +void limDeactivateAndChangeTimer(tpAniSirGlobal, tANI_U32); +void limHeartBeatDeactivateAndChangeTimer(tpAniSirGlobal, tpPESession); +void limReactivateHeartBeatTimer(tpAniSirGlobal, tpPESession); +void limDummyPktExpTimerHandler(void *, tANI_U32); +void limCnfWaitTmerHandler(void *, tANI_U32); +void limKeepaliveTmerHandler(void *, tANI_U32); +void limDeactivateAndChangePerStaIdTimer(tpAniSirGlobal, tANI_U32, tANI_U16); +void limActivateCnfTimer(tpAniSirGlobal, tANI_U16, tpPESession); +void limActivateAuthRspTimer(tpAniSirGlobal, tLimPreAuthNode *); +void limUpdateOlbcCacheTimerHandler(void *, tANI_U32); +void limAddtsResponseTimerHandler(void *, tANI_U32); +void limChannelSwitchTimerHandler(void *, tANI_U32); +void limQuietTimerHandler(void *, tANI_U32); +void limQuietBssTimerHandler(void *, tANI_U32); +void limCBScanIntervalTimerHandler(void *, tANI_U32); +void limCBScanDurationTimerHandler(void *, tANI_U32); +/** + * limActivateHearBeatTimer() + * + * + * @brief: This function is called to activate heartbeat timer + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + * @note staId for eLIM_AUTH_RSP_TIMER is auth Node Index. + * + * @param pMac - Pointer to Global MAC structure + * @param psessionEntry - Pointer to PE session entry + * + * @return TX_SUCCESS - timer is activated + * errors - fail to start the timer + */ +v_UINT_t limActivateHearBeatTimer(tpAniSirGlobal pMac, tpPESession psessionEntry); + +#if 0 +void limWPSOverlapTimerHandler(void *pMacGlobal, tANI_U32 param); +#endif +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +void limMissedBeaconInActiveMode(void *pMacGlobal, tpPESession psessionEntry); +#endif +#endif /* __LIM_TIMER_UTILS_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c new file mode 100644 index 000000000000..d33a33d93c52 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTrace.c @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + + \file limTrace.c + + \brief implementation for trace related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include "aniGlobal.h" //for tpAniSirGlobal + +#include "limTrace.h" +#include "limTimerUtils.h" +#include "vos_trace.h" + + +#ifdef LIM_TRACE_RECORD +tANI_U32 gMgmtFrameStats[14]; + +#define LIM_TRACE_MAX_SUBTYPES 14 + + +static tANI_U8* __limTraceGetTimerString( tANI_U16 timerId ) +{ + switch( timerId ) + { + CASE_RETURN_STRING(eLIM_MIN_CHANNEL_TIMER); + CASE_RETURN_STRING(eLIM_MAX_CHANNEL_TIMER); + CASE_RETURN_STRING(eLIM_JOIN_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_AUTH_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_AUTH_RESP_TIMER); + CASE_RETURN_STRING(eLIM_ASSOC_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_REASSOC_FAIL_TIMER); + CASE_RETURN_STRING(eLIM_PRE_AUTH_CLEANUP_TIMER); + CASE_RETURN_STRING(eLIM_HEART_BEAT_TIMER); + CASE_RETURN_STRING(eLIM_BACKGROUND_SCAN_TIMER); + CASE_RETURN_STRING(eLIM_KEEPALIVE_TIMER); + CASE_RETURN_STRING(eLIM_CNF_WAIT_TIMER); + CASE_RETURN_STRING(eLIM_AUTH_RSP_TIMER); + CASE_RETURN_STRING(eLIM_UPDATE_OLBC_CACHE_TIMER); + CASE_RETURN_STRING(eLIM_PROBE_AFTER_HB_TIMER); + CASE_RETURN_STRING(eLIM_ADDTS_RSP_TIMER); + CASE_RETURN_STRING(eLIM_CHANNEL_SWITCH_TIMER); + CASE_RETURN_STRING(eLIM_LEARN_DURATION_TIMER); + CASE_RETURN_STRING(eLIM_QUIET_TIMER); + CASE_RETURN_STRING(eLIM_QUIET_BSS_TIMER); + CASE_RETURN_STRING(eLIM_WPS_OVERLAP_TIMER); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eLIM_FT_PREAUTH_RSP_TIMER); +#endif + CASE_RETURN_STRING(eLIM_PERIODIC_PROBE_REQ_TIMER); +#ifdef FEATURE_WLAN_ESE + CASE_RETURN_STRING(eLIM_TSM_TIMER); +#endif + CASE_RETURN_STRING(eLIM_DISASSOC_ACK_TIMER); + CASE_RETURN_STRING(eLIM_DEAUTH_ACK_TIMER); + CASE_RETURN_STRING(eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER); + CASE_RETURN_STRING(eLIM_INSERT_SINGLESHOT_NOA_TIMER); + CASE_RETURN_STRING(eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE); + CASE_RETURN_STRING(eLIM_AUTH_RETRY_TIMER); +#ifdef WLAN_FEATURE_LFR_MBB + CASE_RETURN_STRING(eLIM_PREAUTH_MBB_RSP_TIMER); + CASE_RETURN_STRING(eLIM_REASSOC_MBB_RSP_TIMER); +#endif + default: + return( "UNKNOWN" ); + break; + } +} + + +static tANI_U8* __limTraceGetMgmtDropReasonString( tANI_U16 dropReason ) +{ + + switch( dropReason ) + { + CASE_RETURN_STRING(eMGMT_DROP_INFRA_BCN_IN_IBSS); + CASE_RETURN_STRING(eMGMT_DROP_INVALID_SIZE); + CASE_RETURN_STRING(eMGMT_DROP_NON_SCAN_MODE_FRAME); + CASE_RETURN_STRING(eMGMT_DROP_NOT_LAST_IBSS_BCN); + CASE_RETURN_STRING(eMGMT_DROP_NO_DROP); + CASE_RETURN_STRING(eMGMT_DROP_SCAN_MODE_FRAME); + + default: + return( "UNKNOWN" ); + break; + } +} + + + +void limTraceInit(tpAniSirGlobal pMac) +{ + vosTraceRegister(VOS_MODULE_ID_PE, (tpvosTraceCb)&limTraceDump); +} + + + + +void limTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex) +{ + + static char *frameSubtypeStr[LIM_TRACE_MAX_SUBTYPES] = + { + "Association request", + "Association response", + "Reassociation request", + "Reassociation response", + "Probe request", + "Probe response", + NULL, + NULL, + "Beacon", + "ATIM", + "Disassocation", + "Authentication", + "Deauthentication", + "Action" + }; + + + switch (pRecord->code) { + case TRACE_CODE_MLM_STATE: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "MLM State:", + limTraceGetMlmStateString((tANI_U16)pRecord->data), + pRecord->data); + break; + case TRACE_CODE_SME_STATE: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "SME State:", + limTraceGetSmeStateString((tANI_U16)pRecord->data), + pRecord->data); + break; + case TRACE_CODE_TX_MGMT: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "TX Mgmt:", frameSubtypeStr[pRecord->data], pRecord->data); + break; + + case TRACE_CODE_RX_MGMT: + if (LIM_TRACE_MAX_SUBTYPES <= LIM_TRACE_GET_SUBTYPE(pRecord->data)) + { + limLog(pMac, LOG1, "Wrong Subtype - %d", + LIM_TRACE_GET_SUBTYPE(pRecord->data)); + } + else + { + limLog(pMac, + LOG1, "%04d %012u S%d %-14s %-30s(%d) SN: %d ", + recIndex, pRecord->time, pRecord->session, + "RX Mgmt:", + frameSubtypeStr[LIM_TRACE_GET_SUBTYPE(pRecord->data)], + LIM_TRACE_GET_SUBTYPE(pRecord->data), + LIM_TRACE_GET_SSN(pRecord->data)); + } + break; + case TRACE_CODE_RX_MGMT_DROP: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(%d)", + recIndex, pRecord->time, pRecord->session, + "Drop RX Mgmt:", + __limTraceGetMgmtDropReasonString((tANI_U16)pRecord->data), + pRecord->data); + break; + + + case TRACE_CODE_RX_MGMT_TSF: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s0x%x(%d)", + recIndex, pRecord->time, pRecord->session, + "RX Mgmt TSF:", " ", pRecord->data, pRecord->data); + break; + + case TRACE_CODE_TX_COMPLETE: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %d", + recIndex, pRecord->time, pRecord->session, + "TX Complete", pRecord->data); + break; + + case TRACE_CODE_TX_SME_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "TX SME Msg:", + macTraceGetSmeMsgString((tANI_U16)pRecord->data), + pRecord->data ); + break; + case TRACE_CODE_RX_SME_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) + ? "Def/Drp LIM Msg:": "RX Sme Msg:", + macTraceGetSmeMsgString((tANI_U16)pRecord->data), + pRecord->data); + break; + + case TRACE_CODE_TX_WDA_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "TX WDA Msg:", + macTraceGetWdaMsgString((tANI_U16)pRecord->data), + pRecord->data); + break; + + case TRACE_CODE_RX_WDA_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) + ? "Def/Drp LIM Msg:": "RX WDA Msg:", + macTraceGetWdaMsgString((tANI_U16)pRecord->data), + pRecord->data ); + break; + + case TRACE_CODE_TX_LIM_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "TX LIM Msg:", + macTraceGetLimMsgString((tANI_U16)pRecord->data), + pRecord->data); + break; + case TRACE_CODE_RX_LIM_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) + ? "Def/Drp LIM Msg:": "RX LIM Msg", + macTraceGetLimMsgString((tANI_U16)pRecord->data), + pRecord->data ); + break; + case TRACE_CODE_TX_CFG_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "TX CFG Msg:", + macTraceGetCfgMsgString((tANI_U16)pRecord->data), + pRecord->data); + break; + case TRACE_CODE_RX_CFG_MSG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + LIM_TRACE_GET_DEFRD_OR_DROPPED(pRecord->data) + ? "Def/Drp LIM Msg:": "RX CFG Msg:", + macTraceGetCfgMsgString + ((tANI_U16)MAC_TRACE_GET_MSG_ID(pRecord->data)), + pRecord->data); + break; + + case TRACE_CODE_TIMER_ACTIVATE: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "Timer Actvtd", + __limTraceGetTimerString((tANI_U16)pRecord->data), + pRecord->data); + break; + case TRACE_CODE_TIMER_DEACTIVATE: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "Timer DeActvtd", + __limTraceGetTimerString((tANI_U16)pRecord->data), + pRecord->data); + break; + + case TRACE_CODE_INFO_LOG: + limLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + "INFORMATION_LOG", + macTraceGetInfoLogString((tANI_U16)pRecord->data), + pRecord->data); + break; + default : + limLog(pMac, LOG1, "%04d %012u S%d %-14s(%d) (0x%x)", + recIndex, pRecord->time, pRecord->session, + "Unknown Code", pRecord->code, pRecord->data); + break; + } +} + +/** + * lim_state_info_dump() - print state information of lim layer + */ +static void lim_state_info_dump(void) +{ + tHalHandle hal; + tpAniSirGlobal mac; + v_CONTEXT_t vos_ctx_ptr; + + /* get the global voss context */ + vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + + if (NULL == vos_ctx_ptr) { + VOS_ASSERT(0); + return; + } + + hal = vos_get_context(VOS_MODULE_ID_PE, vos_ctx_ptr); + if (NULL == hal) { + VOS_ASSERT(0); + return; + } + + mac = PMAC_STRUCT(hal); + + limLog(mac, LOG1, FL("SmeState: %d PrevSmeState: %d MlmState: %d" + "PrevMlmState: %d SystemInScanLearnMode: %d ProcessDefdMsgs: %d" + "gLimHalScanState: %d"), mac->lim.gLimSmeState, + mac->lim.gLimPrevSmeState, mac->lim.gLimMlmState, + mac->lim.gLimPrevMlmState, mac->lim.gLimSystemInScanLearnMode, + mac->lim.gLimProcessDefdMsgs, mac->lim.gLimHalScanState); +} + +/** + * lim_register_debug_callback() - registration function for lim layer + * to print lim state information + */ +void lim_register_debug_callback() +{ + vos_register_debug_callback(VOS_MODULE_ID_PE, &lim_state_info_dump); +} + +void macTraceMsgTx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data) +{ + + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTrace(pMac, TRACE_CODE_TX_LIM_MSG, session, data); + else + macTrace(pMac, TRACE_CODE_TX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTrace(pMac, TRACE_CODE_TX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTrace(pMac, TRACE_CODE_TX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + + +void macTraceMsgTxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTraceNew(pMac, module, TRACE_CODE_TX_LIM_MSG, session, data); + else + macTraceNew(pMac, module, TRACE_CODE_TX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_TX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_TX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + +/* +* bit31: Rx message defferred or not +* bit 0-15: message ID: +*/ +void macTraceMsgRx(tpAniSirGlobal pMac, tANI_U8 session, tANI_U32 data) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTrace(pMac, TRACE_CODE_RX_LIM_MSG, session, data); + else + macTrace(pMac, TRACE_CODE_RX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTrace(pMac, TRACE_CODE_RX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTrace(pMac, TRACE_CODE_RX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + + + +/* +* bit31: Rx message defferred or not +* bit 0-15: message ID: +*/ +void macTraceMsgRxNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 session, tANI_U32 data) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(data); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(data); + + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + macTraceNew(pMac, module, TRACE_CODE_RX_LIM_MSG, session, data); + else + macTraceNew(pMac, module, TRACE_CODE_RX_SME_MSG, session, data); + break; + case SIR_WDA_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_RX_WDA_MSG, session, data); + break; + case SIR_CFG_MODULE_ID: + macTraceNew(pMac, module, TRACE_CODE_RX_CFG_MSG, session, data); + break; + default: + macTrace(pMac, moduleId, session, data); + break; + } +} + + + +tANI_U8* limTraceGetMlmStateString( tANI_U32 mlmState ) +{ + switch( mlmState ) + { + CASE_RETURN_STRING( eLIM_MLM_OFFLINE_STATE); + CASE_RETURN_STRING( eLIM_MLM_IDLE_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_PROBE_RESP_STATE); + CASE_RETURN_STRING( eLIM_MLM_PASSIVE_SCAN_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_JOIN_BEACON_STATE); + CASE_RETURN_STRING( eLIM_MLM_JOINED_STATE); + CASE_RETURN_STRING( eLIM_MLM_BSS_STARTED_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME2_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME3_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_AUTH_FRAME4_STATE); + CASE_RETURN_STRING( eLIM_MLM_AUTH_RSP_TIMEOUT_STATE); + CASE_RETURN_STRING( eLIM_MLM_AUTHENTICATED_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_REASSOC_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_ASSOCIATED_STATE); + CASE_RETURN_STRING( eLIM_MLM_REASSOCIATED_STATE); + CASE_RETURN_STRING( eLIM_MLM_LINK_ESTABLISHED_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_CNF_STATE); + CASE_RETURN_STRING( eLIM_MLM_LEARN_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_DEL_BSS_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADD_STA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_DEL_STA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_BSS_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_STA_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_STA_BCASTKEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_ADDBA_RSP_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_REMOVE_BSS_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_REMOVE_STA_KEY_STATE); + CASE_RETURN_STRING( eLIM_MLM_WT_SET_MIMOPS_STATE); +#if defined WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_FT_REASSOC_RSP_STATE); +#endif + CASE_RETURN_STRING(eLIM_MLM_P2P_LISTEN_STATE); + default: + return( "UNKNOWN" ); + break; + } +} + + +tANI_U8* limTraceGetSmeStateString( tANI_U32 smeState ) +{ + switch( smeState ) + { + + CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE); + CASE_RETURN_STRING(eLIM_SME_IDLE_STATE); + CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE); + CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE); + CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE); + CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE); + default: + return( "UNKNOWN" ); + break; + } +} + + + + + + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h new file mode 100644 index 000000000000..5fd9ce0702e4 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limTypes.h @@ -0,0 +1,1088 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/* + * This file limTypes.h contains the definitions used by all + * all LIM modules. + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __LIM_TYPES_H +#define __LIM_TYPES_H + +#include "wniApi.h" +#include "sirApi.h" +#include "sirCommon.h" +#include "sirMacProtDef.h" +#include "utilsApi.h" + +#include "wlan_qct_wdi_ds.h" + +#include "limApi.h" +#include "limDebug.h" +#include "limTrace.h" +#include "limSendSmeRspMessages.h" +#include "sysGlobal.h" +#include "dphGlobal.h" +#include "parserApi.h" + +#define LINK_TEST_DEFER 1 + +#define TRACE_EVENT_CNF_TIMER_DEACT 0x6600 +#define TRACE_EVENT_CNF_TIMER_ACT 0x6601 +#define TRACE_EVENT_AUTH_RSP_TIMER_DEACT 0x6602 +#define TRACE_EVENT_AUTH_RSP_TIMER_ACT 0x6603 + +// MLM message types +#define LIM_MLM_MSG_START 1000 +#define LIM_MLM_SCAN_REQ LIM_MLM_MSG_START +#define LIM_MLM_SCAN_CNF (LIM_MLM_MSG_START + 1) +#define LIM_MLM_START_REQ (LIM_MLM_MSG_START + 2) +#define LIM_MLM_START_CNF (LIM_MLM_MSG_START + 3) +#define LIM_MLM_JOIN_REQ (LIM_MLM_MSG_START + 4) +#define LIM_MLM_JOIN_CNF (LIM_MLM_MSG_START + 5) +#define LIM_MLM_AUTH_REQ (LIM_MLM_MSG_START + 6) +#define LIM_MLM_AUTH_CNF (LIM_MLM_MSG_START + 7) +#define LIM_MLM_AUTH_IND (LIM_MLM_MSG_START + 8) +#define LIM_MLM_ASSOC_REQ (LIM_MLM_MSG_START + 9) +#define LIM_MLM_ASSOC_CNF (LIM_MLM_MSG_START + 10) +#define LIM_MLM_ASSOC_IND (LIM_MLM_MSG_START + 11) +#define LIM_MLM_DISASSOC_REQ (LIM_MLM_MSG_START + 12) +#define LIM_MLM_DISASSOC_CNF (LIM_MLM_MSG_START + 13) +#define LIM_MLM_DISASSOC_IND (LIM_MLM_MSG_START + 14) +#define LIM_MLM_REASSOC_REQ (LIM_MLM_MSG_START + 15) +#define LIM_MLM_REASSOC_CNF (LIM_MLM_MSG_START + 16) +#define LIM_MLM_REASSOC_IND (LIM_MLM_MSG_START + 17) +#define LIM_MLM_DEAUTH_REQ (LIM_MLM_MSG_START + 18) +#define LIM_MLM_DEAUTH_CNF (LIM_MLM_MSG_START + 19) +#define LIM_MLM_DEAUTH_IND (LIM_MLM_MSG_START + 20) +#define LIM_MLM_TSPEC_REQ (LIM_MLM_MSG_START + 21) +#define LIM_MLM_TSPEC_CNF (LIM_MLM_MSG_START + 22) +#define LIM_MLM_TSPEC_IND (LIM_MLM_MSG_START + 23) +#define LIM_MLM_SETKEYS_REQ (LIM_MLM_MSG_START + 24) +#define LIM_MLM_SETKEYS_CNF (LIM_MLM_MSG_START + 25) +#define LIM_MLM_LINK_TEST_STOP_REQ (LIM_MLM_MSG_START + 30) +#define LIM_MLM_PURGE_STA_IND (LIM_MLM_MSG_START + 31) +#define LIM_MLM_ADDBA_REQ (LIM_MLM_MSG_START + 32) +#define LIM_MLM_ADDBA_CNF (LIM_MLM_MSG_START + 33) +#define LIM_MLM_ADDBA_IND (LIM_MLM_MSG_START + 34) +#define LIM_MLM_ADDBA_RSP (LIM_MLM_MSG_START + 35) +#define LIM_MLM_DELBA_REQ (LIM_MLM_MSG_START + 36) +#define LIM_MLM_DELBA_CNF (LIM_MLM_MSG_START + 37) +#define LIM_MLM_DELBA_IND (LIM_MLM_MSG_START + 38) +#define LIM_MLM_REMOVEKEY_REQ (LIM_MLM_MSG_START + 39) +#define LIM_MLM_REMOVEKEY_CNF (LIM_MLM_MSG_START + 40) + +#ifdef FEATURE_OEM_DATA_SUPPORT +#define LIM_MLM_OEM_DATA_REQ (LIM_MLM_MSG_START + 41) +#define LIM_MLM_OEM_DATA_CNF (LIM_MLM_MSG_START + 42) +#endif + +#define LIM_HASH_ADD 0 +#define LIM_HASH_UPDATE 1 + +#define LIM_WEP_IN_FC 1 +#define LIM_NO_WEP_IN_FC 0 + +#define LIM_DECRYPT_ICV_FAIL 1 + +/// Definitions to distinquish between Association/Reassociaton +#define LIM_ASSOC 0 +#define LIM_REASSOC 1 + +/// Minimum Memory blocks require for different scenario +#define LIM_MIN_MEM_ASSOC 4 + +/// Verifies whether given mac addr matches the CURRENT Bssid +#define IS_CURRENT_BSSID(pMac, addr,psessionEntry) (vos_mem_compare( addr, \ + psessionEntry->bssId, \ + sizeof(psessionEntry->bssId))) +/// Verifies whether given addr matches the REASSOC Bssid +#define IS_REASSOC_BSSID(pMac, addr,psessionEntry) (vos_mem_compare( addr, \ + psessionEntry->limReAssocbssId, \ + sizeof(psessionEntry->limReAssocbssId))) + +#define REQ_TYPE_REGISTRAR (0x2) +#define REQ_TYPE_WLAN_MANAGER_REGISTRAR (0x3) + +#define RESP_TYPE_REGISTRAR (0x2) +#define RESP_TYPE_ENROLLEE_INFO_ONLY (0x0) +#define RESP_TYPE_ENROLLEE_OPEN_8021X (0x1) +#define RESP_TYPE_AP (0x3) +#define LIM_TX_FRAMES_THRESHOLD_ON_CHIP 300 + + +// enums used by LIM are as follows + +enum eLimDisassocTrigger +{ + eLIM_HOST_DISASSOC, + eLIM_PEER_ENTITY_DISASSOC, + eLIM_LINK_MONITORING_DISASSOC, + eLIM_PROMISCUOUS_MODE_DISASSOC, + eLIM_HOST_DEAUTH, + eLIM_PEER_ENTITY_DEAUTH, + eLIM_LINK_MONITORING_DEAUTH, + eLIM_JOIN_FAILURE, + eLIM_REASSOC_REJECT +}; + +/* Reason code to determine the channel change context while sending + * WDA_CHNL_SWITCH_REQ message to HAL + */ +enum eChannelChangeReasonCodes +{ + LIM_SWITCH_CHANNEL_REASSOC, + LIM_SWITCH_CHANNEL_JOIN, + LIM_SWITCH_CHANNEL_OPERATION, // Generic change channel + LIM_SWITCH_CHANNEL_CSA, +}; + +typedef struct sLimAuthRspTimeout +{ + tSirMacAddr peerMacAddr; +} tLimAuthRspTimeout; + +typedef struct sLimMlmStartReq +{ + tSirMacSSid ssId; + tSirBssType bssType; + tSirMacAddr bssId; + tSirMacBeaconInterval beaconPeriod; + tANI_U8 dtimPeriod; + tSirMacCfParamSet cfParamSet; + tSirMacChanNum channelNumber; + ePhyChanBondState cbMode; + tANI_U16 atimWindow; + tSirMacRateSet rateSet; + tANI_U8 sessionId; //Added For BT-AMP Support + + // Parameters reqd for new HAL (message) interface + tSirNwType nwType; + tANI_U8 htCapable; + tSirMacHTOperatingMode htOperMode; + tANI_U8 dualCTSProtection; + tANI_U8 txChannelWidthSet; + tANI_U8 ssidHidden; + tANI_U8 wps_state; + tANI_U8 obssProtEnabled; +} tLimMlmStartReq, *tpLimMlmStartReq; + +typedef struct sLimMlmStartCnf +{ + tSirResultCodes resultCode; + tANI_U8 sessionId; +} tLimMlmStartCnf, *tpLimMlmStartCnf; + +typedef struct sLimMlmScanCnf +{ + tSirResultCodes resultCode; + tANI_U16 scanResultLength; + tSirBssDescription bssDescription[1]; + tANI_U8 sessionId; +} tLimMlmScanCnf, *tpLimMlmScanCnf; + +typedef struct sLimScanResult +{ + tANI_U16 numBssDescriptions; + tSirBssDescription bssDescription[1]; +} tLimScanResult; + +typedef struct sLimMlmJoinCnf +{ + tSirResultCodes resultCode; + tANI_U16 protStatusCode; + tANI_U8 sessionId; +} tLimMlmJoinCnf, *tpLimMlmJoinCnf; + +typedef struct sLimMlmAssocReq +{ + tSirMacAddr peerMacAddr; + tANI_U32 assocFailureTimeout; + tANI_U16 capabilityInfo; + tSirMacListenInterval listenInterval; + tANI_U8 sessionId; +} tLimMlmAssocReq, *tpLimMlmAssocReq; + +typedef struct sLimMlmAssocCnf +{ + tSirResultCodes resultCode; //Internal status code. + tANI_U16 protStatusCode; //Protocol Status code. + tANI_U8 sessionId; +} tLimMlmAssocCnf, *tpLimMlmAssocCnf; + +typedef struct sLimMlmAssocInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tAniAuthType authType; + tAniSSID ssId; + tSirRSNie rsnIE; + tSirAddie addIE; // additional IE received from the peer, which possibly includes WSC IE and/or P2P IE. + tSirMacCapabilityInfo capabilityInfo; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + tANI_U8 sessionId; + + + tAniBool WmmStaInfoPresent; +#ifdef WLAN_FEATURE_AP_HT40_24G + tAniBool HT40MHzIntoPresent; +#endif + + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + uint32_t rate_flags; +} tLimMlmAssocInd, *tpLimMlmAssocInd; + +typedef struct sLimMlmReassocReq +{ + tSirMacAddr peerMacAddr; + tANI_U32 reassocFailureTimeout; + tANI_U16 capabilityInfo; + tSirMacListenInterval listenInterval; + tANI_U8 sessionId; +} tLimMlmReassocReq, *tpLimMlmReassocReq; + +typedef struct sLimMlmReassocCnf +{ + tSirResultCodes resultCode; + tANI_U16 protStatusCode; //Protocol Status code. + tANI_U8 sessionId; +} tLimMlmReassocCnf, *tpLimMlmReassocCnf; + +typedef struct sLimMlmReassocInd +{ + tSirMacAddr peerMacAddr; + tSirMacAddr currentApAddr; + tANI_U16 aid; + tAniAuthType authType; + tAniSSID ssId; + tSirRSNie rsnIE; + tSirAddie addIE; // additional IE received from the peer, which can be WSC IE and/or P2P IE. + tSirMacCapabilityInfo capabilityInfo; + tAniBool spectrumMgtIndicator; + tSirMacPowerCapInfo powerCap; + tSirSupChnl supportedChannels; + + tAniBool WmmStaInfoPresent; +#ifdef WLAN_FEATURE_AP_HT40_24G + tAniBool HT40MHzIntoPresent; +#endif + + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; +} tLimMlmReassocInd, *tpLimMlmReassocInd; + +typedef struct sLimMlmAuthCnf +{ + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tSirResultCodes resultCode; + tANI_U16 protStatusCode; + tANI_U8 sessionId; +} tLimMlmAuthCnf, *tpLimMlmAuthCnf; + +typedef struct sLimMlmAuthInd +{ + tSirMacAddr peerMacAddr; + tAniAuthType authType; + tANI_U8 sessionId; +} tLimMlmAuthInd, *tpLimMlmAuthInd; + +typedef struct sLimMlmDeauthReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 deauthTrigger; + tANI_U16 aid; + tANI_U8 sessionId; //Added for BT-AMP SUPPORT + +} tLimMlmDeauthReq, *tpLimMlmDeauthReq; + +typedef struct sLimMlmDeauthCnf +{ + tSirMacAddr peerMacAddr; + tSirResultCodes resultCode; + tANI_U16 deauthTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDeauthCnf, *tpLimMLmDeauthCnf; + +typedef struct sLimMlmDeauthInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 deauthTrigger; + tANI_U16 aid; +} tLimMlmDeauthInd, *tpLimMlmDeauthInd; + +typedef struct sLimMlmDisassocReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 disassocTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDisassocReq, *tpLimMlmDisassocReq; + +typedef struct sLimMlmDisassocCnf +{ + tSirMacAddr peerMacAddr; + tSirResultCodes resultCode; + tANI_U16 disassocTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDisassocCnf, *tpLimMlmDisassocCnf; + +typedef struct sLimMlmDisassocInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 disassocTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmDisassocInd, *tpLimMlmDisassocInd; + +typedef struct sLimMlmPurgeStaReq +{ + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tANI_U8 sessionId;//Added For BT-AMP Support +} tLimMlmPurgeStaReq, *tpLimMlmPurgeStaReq; + +typedef struct sLimMlmPurgeStaInd +{ + tSirMacAddr peerMacAddr; + tANI_U16 reasonCode; + tANI_U16 purgeTrigger; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmPurgeStaInd, *tpLimMlmPurgeStaInd; + +typedef struct sLimMlmSetKeysReq +{ + tSirMacAddr peerMacAddr; + tANI_U8 sessionId; //Added For BT-AMP Support + tANI_U16 aid; + tAniEdType edType; // Encryption/Decryption type + tANI_U8 numKeys; + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; +} tLimMlmSetKeysReq, *tpLimMlmSetKeysReq; + +typedef struct sLimMlmSetKeysCnf +{ + tSirMacAddr peerMacAddr; + tANI_U16 resultCode; + tANI_U16 aid; + tANI_U8 sessionId; +} tLimMlmSetKeysCnf, *tpLimMlmSetKeysCnf; + +typedef struct sLimMlmRemoveKeyReq +{ + tSirMacAddr peerMacAddr; + tANI_U8 sessionId; //Added FOr BT-AMP Support + tAniEdType edType; // Encryption/Decryption type + tANI_U8 wepType; //STATIC / DYNAMIC specifier + tANI_U8 keyId; //Key Id To be removed. + tANI_BOOLEAN unicast; +} tLimMlmRemoveKeyReq, *tpLimMlmRemoveKeyReq; + +typedef struct sLimMlmRemoveKeyCnf +{ + tSirMacAddr peerMacAddr; + tANI_U16 resultCode; + tANI_U8 sessionId; +} tLimMlmRemoveKeyCnf, *tpLimMlmRemoveKeyCnf; + + +typedef struct sLimMlmResetReq +{ + tSirMacAddr macAddr; + tANI_U8 performCleanup; + tANI_U8 sessionId; +} tLimMlmResetReq, *tpLimMlmResetReq; + +typedef struct sLimMlmResetCnf +{ + tSirMacAddr macAddr; + tSirResultCodes resultCode; + tANI_U8 sessionId; +} tLimMlmResetCnf, *tpLimMlmResetCnf; + + +typedef struct sLimMlmLinkTestStopReq +{ + tSirMacAddr peerMacAddr; + tANI_U8 sessionId; +} tLimMlmLinkTestStopReq, *tpLimMlmLinkTestStopReq; + + +// +// Block ACK related MLME data structures +// + +typedef struct sLimMlmAddBAReq +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + // ADDBA failure timeout in TU's + // Greater than or equal to 1 + tANI_U16 addBAFailureTimeout; + + // BA Starting Sequence Number + tANI_U16 baSSN; + + tANI_U8 sessionId; + +} tLimMlmAddBAReq, *tpLimMlmAddBAReq; + +typedef struct sLimMlmAddBACnf +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA status code + tSirMacStatusCodes addBAResultCode; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + // ADDBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + tANI_U8 sessionId; + + +} tLimMlmAddBACnf, *tpLimMlmAddBACnf; + +typedef struct sLimMlmAddBAInd +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + +} tLimMlmAddBAInd, *tpLimMlmAddBAInd; + +typedef struct sLimMlmAddBARsp +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + tANI_U8 baDialogToken; + + // ADDBA requested for TID + tANI_U8 baTID; + + // BA status code + tSirMacStatusCodes addBAResultCode; + + // BA policy + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // BA buffer size - (0..127) max size MSDU's + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + //reserved for alignment + tANI_U8 rsvd[2]; + + /* PE session id*/ + tANI_U8 sessionId; + + } tLimMlmAddBARsp, *tpLimMlmAddBARsp; + +// +// NOTE - Overloading DELBA IND and DELBA CNF +// to use the same data structure as DELBA REQ +// as the parameters do not vary too much. +// +typedef struct sLimMlmDelBAReq +{ + + // ADDBA recipient + tSirMacAddr peerMacAddr; + + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + // DELBA requested for TID + tANI_U8 baTID; + + // DELBA reason code + tSirMacReasonCodes delBAReasonCode; + + tANI_U8 sessionId; + +} tLimMlmDelBAReq, *tpLimMlmDelBAReq, tLimMlmDelBAInd, *tpLimMlmDelBAInd, tLimMlmDelBACnf, *tpLimMlmDelBACnf; + +// Function templates + +tANI_BOOLEAN limProcessSmeReqMessages(tpAniSirGlobal, tpSirMsgQ); +void limProcessMlmReqMessages(tpAniSirGlobal, tpSirMsgQ); +void limProcessMlmRspMessages(tpAniSirGlobal, tANI_U32, tANI_U32 *); +void limProcessLmmMessages(tpAniSirGlobal, tANI_U32, tANI_U32 *); +void limProcessSmeDelBssRsp( tpAniSirGlobal , tANI_U32,tpPESession); + +void limGetRandomBssid(tpAniSirGlobal pMac ,tANI_U8 *data); + +// Function to handle HT and HT IE CFG parameter intializations +void handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac, tpPESession psessionEntry); + +// Function to handle CFG parameter updates +void limHandleCFGparamUpdate(tpAniSirGlobal, tANI_U32); + +// Function to apply CFG parameters before join/reassoc/start BSS +void limApplyConfiguration(tpAniSirGlobal,tpPESession); + +void limSetCfgProtection(tpAniSirGlobal pMac, tpPESession pesessionEntry); + + +// Function to Initialize MLM state machine on STA +void limInitMlm(tpAniSirGlobal); + +// Function to cleanup MLM state machine +void limCleanupMlm(tpAniSirGlobal); + +// Function to cleanup LMM state machine +void limCleanupLmm(tpAniSirGlobal); + +// Management frame handling functions +void limProcessBeaconFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessBeaconFrameNoSession(tpAniSirGlobal, tANI_U8 *); +void limProcessProbeReqFrame(tpAniSirGlobal, tANI_U8 *, tpPESession); +void limProcessProbeRspFrame(tpAniSirGlobal, tANI_U8 *, tpPESession); +void limProcessProbeRspFrameNoSession(tpAniSirGlobal, tANI_U8 *); +void limProcessProbeReqFrame_multiple_BSS(tpAniSirGlobal, tANI_U8 *,tpPESession); + + +// Process Auth frame when we have a session in progress. +void limProcessAuthFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +#ifdef WLAN_FEATURE_VOWIFI_11R +tSirRetStatus limProcessAuthFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *, void *body); +#endif + +void limProcessAssocReqFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8, tpPESession); +void limSendMlmAssocInd(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpPESession psessionEntry); + + +void limProcessAssocRspFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8,tpPESession); +void limProcessDisassocFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessDeauthFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessActionFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +void limProcessActionFrameNoSession(tpAniSirGlobal pMac, tANI_U8 *pRxMetaInfo); + + +tSirRetStatus limPopulateMacHeader(tpAniSirGlobal, tANI_U8*, tANI_U8, tANI_U8, tSirMacAddr,tSirMacAddr); +tSirRetStatus limSendProbeReqMgmtFrame(tpAniSirGlobal, tSirMacSSid *, tSirMacAddr, tANI_U8, tSirMacAddr, tANI_U32, tANI_U32, tANI_U8 *); +void limSendProbeRspMgmtFrame(tpAniSirGlobal, tSirMacAddr, tpAniSSID, short, tANI_U8, tpPESession, tANI_U8); +void limSendAuthMgmtFrame(tpAniSirGlobal, tSirMacAuthFrameBody *, tSirMacAddr, + tANI_U8, tpPESession , tAniBool); +void limSendAssocReqMgmtFrame(tpAniSirGlobal, tLimMlmAssocReq *,tpPESession); +void limSendReassocReqMgmtFrame(tpAniSirGlobal, tLimMlmReassocReq *,tpPESession); +#ifdef WLAN_FEATURE_VOWIFI_11R +void limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, + tLimMlmReassocReq *pMlmReassocReq,tpPESession psessionEntry); +#endif +void limSendDeltsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peer, + tANI_U8 wmmTspecPresent, tSirMacTSInfo *pTsinfo, + tSirMacTspecIE *pTspecIe, tpPESession psessionEntry); +void limSendAddtsReqActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tSirAddtsReqInfo *addts,tpPESession); +void limSendAddtsRspActionFrame(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tANI_U16 statusCode, tSirAddtsReqInfo *addts, tSirMacScheduleIE *pSchedule,tpPESession); + +void limSendAssocRspMgmtFrame(tpAniSirGlobal, tANI_U16, tANI_U16, tSirMacAddr, + tANI_U8, tpDphHashNode pSta,tpPESession, + assoc_rsp_tx_context *tx_complete_context); + +void limSendNullDataFrame(tpAniSirGlobal, tpDphHashNode); +void limSendDisassocMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr, tpPESession, tANI_BOOLEAN waitForAck); +void limSendDeauthMgmtFrame(tpAniSirGlobal, tANI_U16, tSirMacAddr, tpPESession, tANI_BOOLEAN waitForAck); +void limSendSmeDisassocDeauthNtf( tpAniSirGlobal pMac, + eHalStatus status, tANI_U32 *pCtx ); +void limDoSendAuthMgmtFrame(tpAniSirGlobal, tpPESession); + +void limContinueChannelScan(tpAniSirGlobal); +tSirResultCodes limMlmAddBss(tpAniSirGlobal, tLimMlmStartReq *,tpPESession psessionEntry); + +tSirRetStatus limSendChannelSwitchMgmtFrame(tpAniSirGlobal, tSirMacAddr, tANI_U8, tANI_U8, tANI_U8, tpPESession); + +#ifdef WLAN_FEATURE_11AC +tSirRetStatus limSendVHTOpmodeNotificationFrame(tpAniSirGlobal pMac,tSirMacAddr peer,tANI_U8 nMode, tpPESession psessionEntry ); +tSirRetStatus limSendVHTChannelSwitchMgmtFrame(tpAniSirGlobal pMac,tSirMacAddr peer,tANI_U8 nChanWidth, tANI_U8 nNewChannel, tANI_U8 ncbMode, tpPESession psessionEntry ); +#endif + +#if defined WLAN_FEATURE_VOWIFI +tSirRetStatus limSendNeighborReportRequestFrame(tpAniSirGlobal, tpSirMacNeighborReportReq, tSirMacAddr, tpPESession); +tSirRetStatus limSendLinkReportActionFrame(tpAniSirGlobal, tpSirMacLinkReport, tSirMacAddr, tpPESession ); +tSirRetStatus limSendRadioMeasureReportActionFrame(tpAniSirGlobal, tANI_U8, tANI_U8, tpSirMacRadioMeasureReport, tSirMacAddr, tpPESession); +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +void limProcessIappFrame(tpAniSirGlobal, tANI_U8 *,tpPESession); +#endif + +#ifdef FEATURE_WLAN_TDLS +void limInitTdlsData(tpAniSirGlobal, tpPESession); +tSirRetStatus limProcessSmeTdlsMgmtSendReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcessSmeTdlsAddStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcesSmeTdlsLinkEstablishReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcessSmeTdlsDelStaReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +void limSendSmeTDLSDeleteAllPeerInd(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limSendSmeMgmtTXCompletion(tpAniSirGlobal pMac, + tANI_U32 smeSessionId, + tANI_U32 txCompleteStatus); +tSirRetStatus limDeleteTDLSPeers(tpAniSirGlobal pMac, tpPESession psessionEntry); +eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, tpPESession); +tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry, + tANI_U8 *addIe, tANI_U16 addIeLen); +// tdlsoffchan +tSirRetStatus limProcesSmeTdlsChanSwitchReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +#endif + +// Algorithms & Link Monitoring related functions +tSirBackgroundScanMode limSelectsBackgroundScanMode(tpAniSirGlobal); +void limTriggerBackgroundScan(tpAniSirGlobal); +void limAbortBackgroundScan(tpAniSirGlobal); + +/// Function that handles heartbeat failure +void limHandleHeartBeatFailure(tpAniSirGlobal,tpPESession); + +/// Function that triggers link tear down with AP upon HB failure +void limTearDownLinkWithAp(tpAniSirGlobal,tANI_U8, tSirMacReasonCodes); + + +/// Function that sends keep alive message to peer(s) +void limSendKeepAliveToPeer(tpAniSirGlobal); + +/// Function that processes Max retries interrupt from TFP +void limHandleMaxRetriesInterrupt(tANI_U32); + +/// Function that processes messages deferred during Learn mode +void limProcessDeferredMessageQueue(tpAniSirGlobal); + +/// Function that defers the messages received +tANI_U32 limDeferMsg(tpAniSirGlobal, tSirMsgQ *); + +/// Function that sets system into scan mode +void limSetScanMode(tpAniSirGlobal pMac); + +/// Function that Switches the Channel and sets the CB Mode +void limSetChannel(tpAniSirGlobal pMac, tANI_U8 channel, tANI_U8 secChannelOffset, tPowerdBm maxTxPower, tANI_U8 peSessionId); + +/// Function that completes channel scan +void limCompleteMlmScan(tpAniSirGlobal, tSirResultCodes); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/// Funtion that sets system into meas mode for oem data req +void limSetOemDataReqMode(tpAniSirGlobal pMac, eHalStatus status, tANI_U32* data); +#endif + +#ifdef ANI_SUPPORT_11H +/// Function that sends Measurement Report action frame +tSirRetStatus limSendMeasReportFrame(tpAniSirGlobal, tpSirMacMeasReqActionFrame, tSirMacAddr); + +/// Function that sends TPC Report action frame +tSirRetStatus limSendTpcReportFrame(tpAniSirGlobal, tpSirMacTpcReqActionFrame, tSirMacAddr); +#endif + +/// Function that sends TPC Request action frame +void limSendTpcRequestFrame(tpAniSirGlobal, tSirMacAddr); + +// Function(s) to handle responses received from HAL +void limProcessMlmAddBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); +void limProcessMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQt,tpPESession psessionEntry); +void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); +void limProcessMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession); +void limProcessStaMlmAddStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry); +void limProcessStaMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry); +void limProcessStaMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ,tpPESession psessionEntry); +void limProcessMlmSetStaKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); +void limProcessMlmSetBssKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); + + + +#ifdef GEN4_SCAN +// Function to process WDA_INIT_SCAN_RSP message +void limProcessInitScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_START_SCAN_RSP message +void limProcessStartScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_END_SCAN_RSP message +void limProcessEndScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_FINISH_SCAN_RSP message +void limProcessFinishScanRsp(tpAniSirGlobal, void * ); + +// Function to process WDA_SWITCH_CHANNEL_RSP message +void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void * ); + +void limSendHalInitScanReq( tpAniSirGlobal, tLimLimHalScanState, tSirLinkTrafficCheck); +void limSendHalStartScanReq( tpAniSirGlobal, tANI_U8, tLimLimHalScanState); +void limSendHalEndScanReq( tpAniSirGlobal, tANI_U8, tLimLimHalScanState); +void limSendTLPauseInd(tpAniSirGlobal pMac, uint16_t staId); +void limSendHalFinishScanReq( tpAniSirGlobal, tLimLimHalScanState); + +void limContinuePostChannelScan(tpAniSirGlobal pMac); +void limCovertChannelScanType(tpAniSirGlobal pMac,tANI_U8 channelNum, tANI_BOOLEAN passiveToActive); +void limSetDFSChannelList(tpAniSirGlobal pMac,tANI_U8 channelNum, tSirDFSChannelList *dfsChannelList); +void limContinueChannelLearn( tpAniSirGlobal ); +//WLAN_SUSPEND_LINK Related +tANI_U8 limIsLinkSuspended(tpAniSirGlobal pMac); +void limSuspendLink(tpAniSirGlobal, tSirLinkTrafficCheck, SUSPEND_RESUME_LINK_CALLBACK, tANI_U32*); +void limResumeLink(tpAniSirGlobal, SUSPEND_RESUME_LINK_CALLBACK, tANI_U32*); +//end WLAN_SUSPEND_LINK Related +#endif // GEN4_SCAN + +tSirRetStatus limSendAddBAReq( tpAniSirGlobal pMac, + tpLimMlmAddBAReq pMlmAddBAReq,tpPESession); + +tSirRetStatus limSendAddBARsp( tpAniSirGlobal pMac, + tpLimMlmAddBARsp pMlmAddBARsp,tpPESession); + +tSirRetStatus limSendDelBAInd( tpAniSirGlobal pMac, + tpLimMlmDelBAReq pMlmDelBAReq ,tpPESession psessionEntry); +#if 0 +tSirRetStatus limSendSMPowerStateFrame( tpAniSirGlobal pMac, + tSirMacAddr peer, tSirMacHTMIMOPowerSaveState State ); +#endif + +void limProcessMlmHalAddBARsp( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ); + +void limProcessMlmHalBADeleteInd( tpAniSirGlobal pMac, + tpSirMsgQ limMsgQ ); + +void limProcessMlmRemoveKeyRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ); + +void limProcessLearnIntervalTimeout(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_11W +//11w send SA query request action frame +tSirRetStatus limSendSaQueryRequestFrame( tpAniSirGlobal pMac, tANI_U8 *transId, + tSirMacAddr peer, tpPESession psessionEntry ); +//11w SA query request action frame handler +tSirRetStatus limSendSaQueryResponseFrame( tpAniSirGlobal pMac, + tANI_U8 *transId, tSirMacAddr peer,tpPESession psessionEntry); +#endif + +#ifdef WLAN_FEATURE_RMC +void limProcessRMCMessages(tpAniSirGlobal pMac, eRmcMessageType msgType, + tANI_U32 *pMsgBuf); +tSirRetStatus limSendRMCActionFrame(tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, tSirRMCInfo *pRMC, + tpPESession psessionEntry); +#endif /* WLAN_FEATURE_RMC */ + +// Inline functions + +/** + * limPostSmeMessage() + * + *FUNCTION: + * This function is called by limProcessMlmMessages(). In this + * function MLM sub-module invokes MLM ind/cnf primitives. + * + *LOGIC: + * Initially MLM makes an SME function call to invoke MLM ind/cnf + * primitive. In future this can be enhanced to 'post' messages to SME. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM primitive message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +static inline void +limPostSmeMessage(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + tSirMsgQ msg; + + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + + msg.type = (tANI_U16)msgType; + msg.bodyptr = pMsgBuf; + msg.bodyval = 0; + if (msgType > eWNI_SME_MSG_TYPES_BEGIN) + { + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, msg.type)); + limProcessSmeReqMessages(pMac, &msg); + } + else + limProcessMlmRspMessages(pMac, msgType, pMsgBuf); +} /*** end limPostSmeMessage() ***/ + +/** + * limPostMlmMessage() + * + *FUNCTION: + * This function is called by limProcessSmeMessages(). In this + * function SME invokes MLME primitives. + * + *PARAMS: + * + *LOGIC: + * Initially SME makes an MLM function call to invoke MLM primitive. + * In future this can be enhanced to 'post' messages to MLM. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @param msgType Indicates the MLM primitive message type + * @param *pMsgBuf A pointer to the MLM message buffer + * + * @return None + */ +static inline void +limPostMlmMessage(tpAniSirGlobal pMac, tANI_U32 msgType, tANI_U32 *pMsgBuf) +{ + + tSirMsgQ msg; + if(pMsgBuf == NULL) + { + limLog(pMac, LOGE,FL("Buffer is Pointing to NULL")); + return; + } + msg.type = (tANI_U16) msgType; + msg.bodyptr = pMsgBuf; + msg.bodyval = 0; + MTRACE(macTraceMsgRx(pMac, NO_SESSION, msg.type)); + limProcessMlmReqMessages(pMac, &msg); +} /*** end limPostMlmMessage() ***/ + + + +/** + * limGetCurrentScanChannel() + * + *FUNCTION: + * This function is called in various places to get current channel + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return Channel number + */ +static inline tANI_U8 +limGetCurrentScanChannel(tpAniSirGlobal pMac) +{ + tANI_U8 *pChanNum = pMac->lim.gpLimMlmScanReq->channelList.channelNumber; + + return (*(pChanNum + pMac->lim.gLimCurrentScanChannelId)); +} /*** end limGetCurrentScanChannel() ***/ + +/** + * limSendBeaconInd() + * + *FUNCTION: + * This function is called to send the beacon indication + * number being scanned. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: +*/ + +void +limSendBeaconInd(tpAniSirGlobal pMac, tpPESession psessionEntry); + + +void limGetWPSPBCSessions(tpAniSirGlobal pMac, tANI_U8 *addr, tANI_U8 *uuid_e, eWPSPBCOverlap *overlap, tpPESession psessionEntry); +void limWPSPBCTimeout(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limWPSPBCClose(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limRemovePBCSessions(tpAniSirGlobal pMac, tSirMacAddr pRemoveMac,tpPESession psessionEntry); + + +tSirRetStatus +limIsSmeGetWPSPBCSessionsReqValid(tpAniSirGlobal pMac, tSirSmeGetWPSPBCSessionsReq *pGetWPSPBCSessionsReq, tANI_U8 *pBuf); + +#define LIM_WPS_OVERLAP_TIMER_MS 10000 + +void +limSuspendLink(tpAniSirGlobal pMac, tSirLinkTrafficCheck trafficCheck, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data); +void +limResumeLink(tpAniSirGlobal pMac, SUSPEND_RESUME_LINK_CALLBACK callback, tANI_U32 *data); + +void +limChangeChannelWithCallback(tpAniSirGlobal pMac, tANI_U8 newChannel, + CHANGE_CHANNEL_CALLBACK callback, tANI_U32 *cbdata, tpPESession psessionEntry); + +void limSendSmeMgmtFrameInd( + tpAniSirGlobal pMac, tANI_U16 sessionId, + tANI_U8 *pRxPacketInfo, + tpPESession psessionEntry, tANI_S8 rxRssi); +void limProcessRemainOnChnTimeout(tpAniSirGlobal pMac); +void limProcessInsertSingleShotNOATimeout(tpAniSirGlobal pMac); +void limConvertActiveChannelToPassiveChannel(tpAniSirGlobal pMac); +void limSendP2PActionFrame(tpAniSirGlobal pMac, tpSirMsgQ pMsg); +void limAbortRemainOnChan(tpAniSirGlobal pMac); +tSirRetStatus __limProcessSmeNoAUpdate(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf); +void limProcessRegdDefdSmeReqAfterNOAStart(tpAniSirGlobal pMac); +void limProcessDisassocAckTimeout(tpAniSirGlobal pMac); +void limProcessDeauthAckTimeout(tpAniSirGlobal pMac); +eHalStatus limSendDisassocCnf(tpAniSirGlobal pMac); +eHalStatus limSendDeauthCnf(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct sSetLinkCbackParams +{ + void * cbackDataPtr; +} tSetLinkCbackParams; +#endif + +void limProcessRxScanEvent(tpAniSirGlobal mac, void *buf); + +int limProcessRemainOnChnlReq(tpAniSirGlobal pMac, tANI_U32 *pMsg); +void limRemainOnChnRsp(tpAniSirGlobal pMac, eHalStatus status, tANI_U32 *data); +void limProcessMlmSpoofMacAddrRsp(tpAniSirGlobal pMac, tSirRetStatus rspStatus); +tSirRetStatus limProcessSmeSetTdls2040BSSCoexReq(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); +tSirRetStatus limProcessSmeDelAllTdlsPeers(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); + +tSirRetStatus lim_process_sme_cap_tsf_req(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); + +tSirRetStatus lim_process_sme_get_tsf_req(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); + +tSirRetStatus lim_process_sme_del_ba_ses_req(tpAniSirGlobal pMac, + tANI_U32 *pMsgBuf); + +#endif /* __LIM_TYPES_H */ + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c new file mode 100644 index 000000000000..ec59de06dd2b --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.c @@ -0,0 +1,9253 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +/* + * This file limUtils.cc contains the utility functions + * LIM uses. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#include "schApi.h" +#include "limUtils.h" +#include "limTypes.h" +#include "limSecurityUtils.h" +#include "limPropExtsUtils.h" +#include "limSendMessages.h" +#include "limSerDesUtils.h" +#include "limAdmitControl.h" +#include "limStaHashApi.h" +#include "dot11f.h" +#include "dot11fdefs.h" +#include "wmmApsd.h" +#include "limTrace.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_event.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT +#include "limIbssPeerMgmt.h" +#include "limSessionUtils.h" +#include "limSession.h" +#include "vos_nvitem.h" +#ifdef WLAN_FEATURE_11W +#include "wniCfg.h" +#endif +#ifdef SAP_AUTH_OFFLOAD +#include "limAssocUtils.h" +#endif + +/* Static global used to mark situations where pMac->lim.gLimTriggerBackgroundScanDuringQuietBss is SET + * and limTriggerBackgroundScanDuringQuietBss() returned failure. In this case, we will stop data + * traffic instead of going into scan. The recover function limProcessQuietBssTimeout() needs to have + * this information. */ +static tAniBool glimTriggerBackgroundScanDuringQuietBss_Status = eSIR_TRUE; + +/* 11A Channel list to decode RX BD channel information */ +static const tANI_U8 abChannel[]= {36,40,44,48,52,56,60,64,100,104,108,112,116, + 120,124,128,132,136,140,149,153,157,161,165,144}; +#define abChannelSize (sizeof(abChannel)/ \ + sizeof(abChannel[0])) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +static const tANI_U8 aUnsortedChannelList[]= {52,56,60,64,100,104,108,112,116, + 120,124,128,132,136,140,36,40,44,48,149,153,157,161,165,144}; +#define aUnsortedChannelListSize (sizeof(aUnsortedChannelList)/ \ + sizeof(aUnsortedChannelList[0])) +#endif + +//#define LIM_MAX_ACTIVE_SESSIONS 3 //defined temporarily for BT-AMP SUPPORT +#define SUCCESS 1 //defined temporarily for BT-AMP + +#define MAX_BA_WINDOW_SIZE_FOR_CISCO 25 +#define MAX_DTIM_PERIOD 15 +#define MAX_DTIM_COUNT 15 +#define DTIM_PERIOD_DEFAULT 1 +#define DTIM_COUNT_DEFAULT 1 +static void +limProcessChannelSwitchSuspendLink(tpAniSirGlobal pMac, + eHalStatus status, + tANI_U32 *ctx); +/** ------------------------------------------------------------- +\fn limCheck11BRateBitmap +\brief Verifies if basic rates are set. +\param tANI_U16 pRateBitmap +\return tANI_BOOLEAN - true or false + -------------------------------------------------------------*/ + +tANI_BOOLEAN limCheck11BRateBitmap(tANI_U16 pRateBitmap) +{ + return ( ( pRateBitmap & ( 1 << 0 ) ) || ( pRateBitmap & ( 1 << 1 ) ) || + ( pRateBitmap & ( 1 << 2 ) ) || + ( pRateBitmap & ( 1 << 3 ) ) ? 1 : 0 ) ; +} + +/** ------------------------------------------------------------- +\fn limAssignDialogueToken +\brief Assigns dialogue token. +\param tpAniSirGlobal pMac +\return tpDialogueToken - dialogueToken data structure. + -------------------------------------------------------------*/ + +tpDialogueToken +limAssignDialogueToken(tpAniSirGlobal pMac) +{ + static tANI_U8 token; + tpDialogueToken pCurrNode; + pCurrNode = vos_mem_malloc(sizeof(tDialogueToken)); + if ( NULL == pCurrNode ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed"));) + return NULL; + } + + vos_mem_set((void *) pCurrNode, sizeof(tDialogueToken), 0); + //first node in the list is being added. + if(NULL == pMac->lim.pDialogueTokenHead) + { + pMac->lim.pDialogueTokenHead = pMac->lim.pDialogueTokenTail = pCurrNode; + } + else + { + pMac->lim.pDialogueTokenTail->next = pCurrNode; + pMac->lim.pDialogueTokenTail = pCurrNode; + } + //assocId and tid of the node will be filled in by caller. + pCurrNode->next = NULL; + pCurrNode->token = token++; + + /* Dialog token should be a non-zero value */ + if (0 == pCurrNode->token) + pCurrNode->token = token; + + PELOG4(limLog(pMac, LOG4, FL("token assigned = %d"), pCurrNode->token);) + return pCurrNode; +} + +/** ------------------------------------------------------------- +\fn limSearchAndDeleteDialogueToken +\brief search dialogue token in the list and deletes it if found. returns failure if not found. +\param tpAniSirGlobal pMac +\param tANI_U8 token +\param tANI_U16 assocId +\param tANI_U16 tid +\return eSirRetStatus - status of the search + -------------------------------------------------------------*/ + + +tSirRetStatus +limSearchAndDeleteDialogueToken(tpAniSirGlobal pMac, tANI_U8 token, tANI_U16 assocId, tANI_U16 tid) +{ + tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead; + tpDialogueToken pPrevNode = pMac->lim.pDialogueTokenHead; + + /* if the list is empty */ + if(NULL == pCurrNode) + return eSIR_FAILURE; + + /* If the matching node is the first node.*/ + if ((token == pCurrNode->token) && + (assocId == pCurrNode->assocId) && + (tid == pCurrNode->tid)) { + pMac->lim.pDialogueTokenHead = pCurrNode->next; + /* There was only one node in the list. + * So tail pointer also needs to be adjusted. + */ + if (NULL == pMac->lim.pDialogueTokenHead) + pMac->lim.pDialogueTokenTail = NULL; + vos_mem_free(pCurrNode); + return eSIR_SUCCESS; + } + + /* first node did not match. so move to the next one. */ + pCurrNode = pCurrNode->next; + + while (NULL != pCurrNode) { + if ((token == pCurrNode->token) && + (assocId == pCurrNode->assocId) && + (tid == pCurrNode->tid)) { + break; + } + pPrevNode = pCurrNode; + pCurrNode = pCurrNode->next; + } + + if (pCurrNode) { + pPrevNode->next = pCurrNode->next; + /* if the node being deleted is the last one + * then we also need to move the tail pointer + * to the prevNode. + */ + if(NULL == pCurrNode->next) + pMac->lim.pDialogueTokenTail = pPrevNode; + vos_mem_free(pCurrNode); + return eSIR_SUCCESS; + } + + limLog(pMac, LOGW, + FL("LIM does not have matching dialogue token node")); + return eSIR_FAILURE; +} + + +/** ------------------------------------------------------------- +\fn limDeleteDialogueTokenList +\brief deletes the complete lim dialogue token linked list. +\param tpAniSirGlobal pMac +\return None + -------------------------------------------------------------*/ +void +limDeleteDialogueTokenList(tpAniSirGlobal pMac) +{ + tpDialogueToken pCurrNode = pMac->lim.pDialogueTokenHead; + + while(NULL != pMac->lim.pDialogueTokenHead) + { + pCurrNode = pMac->lim.pDialogueTokenHead; + pMac->lim.pDialogueTokenHead = pMac->lim.pDialogueTokenHead->next; + vos_mem_free(pCurrNode); + pCurrNode = NULL; + } + pMac->lim.pDialogueTokenTail = NULL; +} + +void +limGetBssidFromBD(tpAniSirGlobal pMac, tANI_U8 * pRxPacketInfo, tANI_U8 *bssId, tANI_U32 *pIgnore) +{ + tpSirMacDataHdr3a pMh = WDA_GET_RX_MPDUHEADER3A(pRxPacketInfo); + *pIgnore = 0; + + if (pMh->fc.toDS == 1 && pMh->fc.fromDS == 0) + { + vos_mem_copy( bssId, pMh->addr1, 6); + *pIgnore = 1; + } + else if (pMh->fc.toDS == 0 && pMh->fc.fromDS == 1) + { + vos_mem_copy ( bssId, pMh->addr2, 6); + *pIgnore = 1; + } + else if (pMh->fc.toDS == 0 && pMh->fc.fromDS == 0) + { + vos_mem_copy( bssId, pMh->addr3, 6); + *pIgnore = 0; + } + else + { + vos_mem_copy( bssId, pMh->addr1, 6); + *pIgnore = 1; + } +} + +char * +limMlmStateStr(tLimMlmStates state) +{ + switch (state) + { + case eLIM_MLM_OFFLINE_STATE: + return "eLIM_MLM_OFFLINE_STATE"; + case eLIM_MLM_IDLE_STATE: + return "eLIM_MLM_IDLE_STATE"; + case eLIM_MLM_WT_PROBE_RESP_STATE: + return "eLIM_MLM_WT_PROBE_RESP_STATE"; + case eLIM_MLM_PASSIVE_SCAN_STATE: + return "eLIM_MLM_PASSIVE_SCAN_STATE"; + case eLIM_MLM_WT_JOIN_BEACON_STATE: + return "eLIM_MLM_WT_JOIN_BEACON_STATE"; + case eLIM_MLM_JOINED_STATE: + return "eLIM_MLM_JOINED_STATE"; + case eLIM_MLM_BSS_STARTED_STATE: + return "eLIM_MLM_BSS_STARTED_STATE"; + case eLIM_MLM_WT_AUTH_FRAME2_STATE: + return "eLIM_MLM_WT_AUTH_FRAME2_STATE"; + case eLIM_MLM_WT_AUTH_FRAME3_STATE: + return "eLIM_MLM_WT_AUTH_FRAME3_STATE"; + case eLIM_MLM_WT_AUTH_FRAME4_STATE: + return "eLIM_MLM_WT_AUTH_FRAME4_STATE"; + case eLIM_MLM_AUTH_RSP_TIMEOUT_STATE: + return "eLIM_MLM_AUTH_RSP_TIMEOUT_STATE"; + case eLIM_MLM_AUTHENTICATED_STATE: + return "eLIM_MLM_AUTHENTICATED_STATE"; + case eLIM_MLM_WT_ASSOC_RSP_STATE: + return "eLIM_MLM_WT_ASSOC_RSP_STATE"; + case eLIM_MLM_WT_REASSOC_RSP_STATE: + return "eLIM_MLM_WT_REASSOC_RSP_STATE"; + case eLIM_MLM_WT_FT_REASSOC_RSP_STATE: + return "eLIM_MLM_WT_FT_REASSOC_RSP_STATE"; + case eLIM_MLM_WT_DEL_STA_RSP_STATE: + return "eLIM_MLM_WT_DEL_STA_RSP_STATE"; + case eLIM_MLM_WT_DEL_BSS_RSP_STATE: + return "eLIM_MLM_WT_DEL_BSS_RSP_STATE"; + case eLIM_MLM_WT_ADD_STA_RSP_STATE: + return "eLIM_MLM_WT_ADD_STA_RSP_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_STATE"; + case eLIM_MLM_REASSOCIATED_STATE: + return "eLIM_MLM_REASSOCIATED_STATE"; + case eLIM_MLM_LINK_ESTABLISHED_STATE: + return "eLIM_MLM_LINK_ESTABLISHED_STATE"; + case eLIM_MLM_WT_ASSOC_CNF_STATE: + return "eLIM_MLM_WT_ASSOC_CNF_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE"; + case eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE: + return "eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE"; + case eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE: + return "eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE"; + case eLIM_MLM_WT_SET_BSS_KEY_STATE: + return "eLIM_MLM_WT_SET_BSS_KEY_STATE"; + case eLIM_MLM_WT_SET_STA_KEY_STATE: + return "eLIM_MLM_WT_SET_STA_KEY_STATE"; + default: + return "INVALID MLM state"; + } +} + +void +limPrintMlmState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimMlmStates state) +{ + limLog(pMac, logLevel, limMlmStateStr(state)); +} + +char * +limSmeStateStr(tLimSmeStates state) +{ +#ifdef FIXME_GEN6 + switch (state) + { + case eLIM_SME_OFFLINE_STATE: + return "eLIM_SME_OFFLINE_STATE"; + case eLIM_SME_IDLE_STATE: + return "eLIM_SME_IDLE_STATE"; + case eLIM_SME_SUSPEND_STATE: + return "eLIM_SME_SUSPEND_STATE"; + case eLIM_SME_WT_SCAN_STATE: + return "eLIM_SME_WT_SCAN_STATE"; + case eLIM_SME_WT_JOIN_STATE: + return "eLIM_SME_WT_JOIN_STATE"; + case eLIM_SME_WT_AUTH_STATE: + return "eLIM_SME_WT_AUTH_STATE"; + case eLIM_SME_WT_ASSOC_STATE: + return "eLIM_SME_WT_ASSOC_STATE"; + case eLIM_SME_WT_REASSOC_STATE: + return "eLIM_SME_WT_REASSOC_STATE"; + case eLIM_SME_WT_REASSOC_LINK_FAIL_STATE: + return "eLIM_SME_WT_REASSOC_LINK_FAIL_STATE"; + case eLIM_SME_JOIN_FAILURE_STATE: + return "eLIM_SME_JOIN_FAILURE_STATE"; + case eLIM_SME_ASSOCIATED_STATE: + return "eLIM_SME_ASSOCIATED_STATE"; + case eLIM_SME_REASSOCIATED_STATE: + return "eLIM_SME_REASSOCIATED_STATE"; + case eLIM_SME_LINK_EST_STATE: + return "eLIM_SME_LINK_EST_STATE"; + case eLIM_SME_LINK_EST_WT_SCAN_STATE: + return "eLIM_SME_LINK_EST_WT_SCAN_STATE"; + case eLIM_SME_WT_PRE_AUTH_STATE: + return "eLIM_SME_WT_PRE_AUTH_STATE"; + case eLIM_SME_WT_DISASSOC_STATE: + return "eLIM_SME_WT_DISASSOC_STATE"; + case eLIM_SME_WT_DEAUTH_STATE: + return "eLIM_SME_WT_DEAUTH_STATE"; + case eLIM_SME_WT_START_BSS_STATE: + return "eLIM_SME_WT_START_BSS_STATE"; + case eLIM_SME_WT_STOP_BSS_STATE: + return "eLIM_SME_WT_STOP_BSS_STATE"; + case eLIM_SME_NORMAL_STATE: + return "eLIM_SME_NORMAL_STATE"; + case eLIM_SME_CHANNEL_SCAN_STATE: + return "eLIM_SME_CHANNEL_SCAN_STATE"; + case eLIM_SME_NORMAL_CHANNEL_SCAN_STATE: + return "eLIM_SME_NORMAL_CHANNEL_SCAN_STATE"; + default: + return "INVALID SME state"; + } +#endif +return ""; +} + + +char* limDot11ModeStr(tpAniSirGlobal pMac, tANI_U8 dot11Mode) +{ +#ifdef FIXME_GEN6 + + switch(dot11Mode) + { + case WNI_CFG_DOT11_MODE_ALL: + return "ALL"; + case WNI_CFG_DOT11_MODE_11A: + return "11A"; + case WNI_CFG_DOT11_MODE_11B: + return "11B"; + case WNI_CFG_DOT11_MODE_11G: + return "11G"; + case WNI_CFG_DOT11_MODE_11N: + return "11N"; + case WNI_CFG_DOT11_MODE_POLARIS: + return "Polaris"; + case WNI_CFG_DOT11_MODE_TITAN: + return "Titan"; + case WNI_CFG_DOT11_MODE_TAURUS: + return "Taurus"; + default: + return "Invalid Dot11 Mode"; + } +#endif +return ""; +} + + +char* limStaOpRateModeStr(tStaRateMode opRateMode) +{ +#ifdef FIXME_GEN6 + + switch(opRateMode) + { + case eSTA_TAURUS: + return "Taurus"; + case eSTA_11a: + return "11A"; + case eSTA_11b: + return "11B"; + case eSTA_11bg: + return "11G"; + case eSTA_11n: + return "11N"; + case eSTA_POLARIS: + return "Polaris"; + case eSTA_TITAN: + return "Titan"; + default: + return "Invalid Dot11 Mode"; + } +#endif +return ""; +} + +char* limBssTypeStr(tSirBssType bssType) +{ + switch(bssType) + { + case eSIR_INFRASTRUCTURE_MODE: + return "eSIR_INFRASTRUCTURE_MODE"; + case eSIR_IBSS_MODE: + return "eSIR_IBSS_MODE"; + case eSIR_BTAMP_STA_MODE: + return "eSIR_BTAMP_STA_MODE"; + case eSIR_BTAMP_AP_MODE: + return "eSIR_BTAMP_AP_MODE"; + case eSIR_AUTO_MODE: + return "eSIR_AUTO_MODE"; + default: + return "Invalid BSS Type"; + } +} + +void +limPrintSmeState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimSmeStates state) +{ + limLog(pMac, logLevel, limSmeStateStr(state)); +} + +char *limMsgStr(tANI_U32 msgType) +{ +#ifdef FIXME_GEN6 + switch (msgType) + { + case eWNI_SME_START_REQ: + return "eWNI_SME_START_REQ"; + case eWNI_SME_START_RSP: + return "eWNI_SME_START_RSP"; + case eWNI_SME_SYS_READY_IND: + return "eWNI_SME_SYS_READY_IND"; + case eWNI_SME_SCAN_REQ: + return "eWNI_SME_SCAN_REQ"; +#ifdef FEATURE_OEM_DATA_SUPPORT + case eWNI_SME_OEM_DATA_REQ: + return "eWNI_SME_OEM_DATA_REQ"; + case eWNI_SME_OEM_DATA_RSP: + return "eWNI_SME_OEM_DATA_RSP"; +#endif + case eWNI_SME_SCAN_RSP: + return "eWNI_SME_SCAN_RSP"; + case eWNI_SME_JOIN_REQ: + return "eWNI_SME_JOIN_REQ"; + case eWNI_SME_JOIN_RSP: + return "eWNI_SME_JOIN_RSP"; + case eWNI_SME_SETCONTEXT_REQ: + return "eWNI_SME_SETCONTEXT_REQ"; + case eWNI_SME_SETCONTEXT_RSP: + return "eWNI_SME_SETCONTEXT_RSP"; + case eWNI_SME_REASSOC_REQ: + return "eWNI_SME_REASSOC_REQ"; + case eWNI_SME_REASSOC_RSP: + return "eWNI_SME_REASSOC_RSP"; + case eWNI_SME_AUTH_REQ: + return "eWNI_SME_AUTH_REQ"; + case eWNI_SME_AUTH_RSP: + return "eWNI_SME_AUTH_RSP"; + case eWNI_SME_DISASSOC_REQ: + return "eWNI_SME_DISASSOC_REQ"; + case eWNI_SME_DISASSOC_RSP: + return "eWNI_SME_DISASSOC_RSP"; + case eWNI_SME_DISASSOC_IND: + return "eWNI_SME_DISASSOC_IND"; + case eWNI_SME_DISASSOC_CNF: + return "eWNI_SME_DISASSOC_CNF"; + case eWNI_SME_DEAUTH_REQ: + return "eWNI_SME_DEAUTH_REQ"; + case eWNI_SME_DEAUTH_RSP: + return "eWNI_SME_DEAUTH_RSP"; + case eWNI_SME_DEAUTH_IND: + return "eWNI_SME_DEAUTH_IND"; + case eWNI_SME_WM_STATUS_CHANGE_NTF: + return "eWNI_SME_WM_STATUS_CHANGE_NTF"; + case eWNI_SME_START_BSS_REQ: + return "eWNI_SME_START_BSS_REQ"; + case eWNI_SME_START_BSS_RSP: + return "eWNI_SME_START_BSS_RSP"; + case eWNI_SME_AUTH_IND: + return "eWNI_SME_AUTH_IND"; + case eWNI_SME_ASSOC_IND: + return "eWNI_SME_ASSOC_IND"; + case eWNI_SME_ASSOC_CNF: + return "eWNI_SME_ASSOC_CNF"; + case eWNI_SME_REASSOC_IND: + return "eWNI_SME_REASSOC_IND"; + case eWNI_SME_REASSOC_CNF: + return "eWNI_SME_REASSOC_CNF"; + case eWNI_SME_SWITCH_CHL_REQ: + return "eWNI_SME_SWITCH_CHL_REQ"; + case eWNI_SME_SWITCH_CHL_RSP: + return "eWNI_SME_SWITCH_CHL_RSP"; + case eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ: + return "eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ"; + case eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ: + return "eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ"; + case eWNI_SME_STOP_BSS_REQ: + return "eWNI_SME_STOP_BSS_REQ"; + case eWNI_SME_STOP_BSS_RSP: + return "eWNI_SME_STOP_BSS_RSP"; + case eWNI_SME_PROMISCUOUS_MODE_REQ: + return "eWNI_SME_PROMISCUOUS_MODE_REQ"; + case eWNI_SME_PROMISCUOUS_MODE_RSP: + return "eWNI_SME_PROMISCUOUS_MODE_RSP"; + case eWNI_SME_NEIGHBOR_BSS_IND: + return "eWNI_SME_NEIGHBOR_BSS_IND"; + case eWNI_SME_MEASUREMENT_REQ: + return "eWNI_SME_MEASUREMENT_REQ"; + case eWNI_SME_MEASUREMENT_RSP: + return "eWNI_SME_MEASUREMENT_RSP"; + case eWNI_SME_MEASUREMENT_IND: + return "eWNI_SME_MEASUREMENT_IND"; + case eWNI_SME_SET_WDS_INFO_REQ: + return "eWNI_SME_SET_WDS_INFO_REQ"; + case eWNI_SME_SET_WDS_INFO_RSP: + return "eWNI_SME_SET_WDS_INFO_RSP"; + case eWNI_SME_WDS_INFO_IND: + return "eWNI_SME_WDS_INFO_IND"; + case eWNI_SME_DEAUTH_CNF: + return "eWNI_SME_DEAUTH_CNF"; + case eWNI_SME_MIC_FAILURE_IND: + return "eWNI_SME_MIC_FAILURE_IND"; + case eWNI_SME_LOST_LINK_PARAMS_IND: + return "eWNI_SME_LOST_LINK_PARAMS_IND"; + case eWNI_SME_ADDTS_REQ: + return "eWNI_SME_ADDTS_REQ"; + case eWNI_SME_ADDTS_RSP: + return "eWNI_SME_ADDTS_RSP"; + case eWNI_SME_ADDTS_CNF: + return "eWNI_SME_ADDTS_CNF"; + case eWNI_SME_ADDTS_IND: + return "eWNI_SME_ADDTS_IND"; + case eWNI_SME_DELTS_REQ: + return "eWNI_SME_DELTS_REQ"; + case eWNI_SME_DELTS_RSP: + return "eWNI_SME_DELTS_RSP"; + case eWNI_SME_DELTS_IND: + return "eWNI_SME_DELTS_IND"; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_REQ: + return "eWNI_SME_GET_ROAM_RSSI_REQ"; + case eWNI_SME_GET_ROAM_RSSI_RSP: + return "eWNI_SME_GET_ROAM_RSSI_RSP"; +#endif + + case WDA_SUSPEND_ACTIVITY_RSP: + return "WDA_SUSPEND_ACTIVITY_RSP"; + case SIR_LIM_RETRY_INTERRUPT_MSG: + return "SIR_LIM_RETRY_INTERRUPT_MSG"; + case SIR_BB_XPORT_MGMT_MSG: + return "SIR_BB_XPORT_MGMT_MSG"; + case SIR_LIM_INV_KEY_INTERRUPT_MSG: + return "SIR_LIM_INV_KEY_INTERRUPT_MSG"; + case SIR_LIM_KEY_ID_INTERRUPT_MSG: + return "SIR_LIM_KEY_ID_INTERRUPT_MSG"; + case SIR_LIM_REPLAY_THRES_INTERRUPT_MSG: + return "SIR_LIM_REPLAY_THRES_INTERRUPT_MSG"; + case SIR_LIM_MIN_CHANNEL_TIMEOUT: + return "SIR_LIM_MIN_CHANNEL_TIMEOUT"; + case SIR_LIM_MAX_CHANNEL_TIMEOUT: + return "SIR_LIM_MAX_CHANNEL_TIMEOUT"; + case SIR_LIM_JOIN_FAIL_TIMEOUT: + return "SIR_LIM_JOIN_FAIL_TIMEOUT"; + case SIR_LIM_AUTH_FAIL_TIMEOUT: + return "SIR_LIM_AUTH_FAIL_TIMEOUT"; + case SIR_LIM_AUTH_RSP_TIMEOUT: + return "SIR_LIM_AUTH_RSP_TIMEOUT"; + case SIR_LIM_ASSOC_FAIL_TIMEOUT: + return "SIR_LIM_ASSOC_FAIL_TIMEOUT"; + case SIR_LIM_REASSOC_FAIL_TIMEOUT: + return "SIR_LIM_REASSOC_FAIL_TIMEOUT"; + case SIR_LIM_HEART_BEAT_TIMEOUT: + return "SIR_LIM_HEART_BEAT_TIMEOUT"; + case SIR_LIM_ADDTS_RSP_TIMEOUT: + return "SIR_LIM_ADDTS_RSP_TIMEOUT"; + case SIR_LIM_CHANNEL_SCAN_TIMEOUT: + return "SIR_LIM_CHANNEL_SCAN_TIMEOUT"; + case SIR_LIM_LINK_TEST_DURATION_TIMEOUT: + return "SIR_LIM_LINK_TEST_DURATION_TIMEOUT"; + case SIR_LIM_KEEPALIVE_TIMEOUT: + return "SIR_LIM_KEEPALIVE_TIMEOUT"; + case SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT: + return "SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT"; + case SIR_LIM_CNF_WAIT_TIMEOUT: + return "SIR_LIM_CNF_WAIT_TIMEOUT"; + case SIR_LIM_RADAR_DETECT_IND: + return "SIR_LIM_RADAR_DETECT_IND"; +#ifdef WLAN_FEATURE_VOWIFI_11R + case SIR_LIM_FT_PREAUTH_RSP_TIMEOUT: + return "SIR_LIM_FT_PREAUTH_RSP_TIMEOUT"; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + case SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT: + return "SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT"; + case SIR_LIM_REASSOC_MBB_RSP_TIMEOUT: + return "SIR_LIM_REASSOC_MBB_RSP_TIMEOUT"; +#endif + + case SIR_HAL_APP_SETUP_NTF: + return "SIR_HAL_APP_SETUP_NTF"; + case SIR_HAL_INITIAL_CAL_FAILED_NTF: + return "SIR_HAL_INITIAL_CAL_FAILED_NTF"; + case SIR_HAL_NIC_OPER_NTF: + return "SIR_HAL_NIC_OPER_NTF"; + case SIR_HAL_INIT_START_REQ: + return "SIR_HAL_INIT_START_REQ"; + case SIR_HAL_SHUTDOWN_REQ: + return "SIR_HAL_SHUTDOWN_REQ"; + case SIR_HAL_SHUTDOWN_CNF: + return "SIR_HAL_SHUTDOWN_CNF"; + case SIR_HAL_RESET_REQ: + return "SIR_HAL_RESET_REQ"; + case SIR_HAL_RESET_CNF: + return "SIR_HAL_RESET_CNF"; + case SIR_WRITE_TO_TD: + return "SIR_WRITE_TO_TD"; + + case WNI_CFG_PARAM_UPDATE_IND: + return "WNI_CFG_PARAM_UPDATE_IND"; + case WNI_CFG_DNLD_REQ: + return "WNI_CFG_DNLD_REQ"; + case WNI_CFG_DNLD_CNF: + return "WNI_CFG_DNLD_CNF"; + case WNI_CFG_GET_RSP: + return "WNI_CFG_GET_RSP"; + case WNI_CFG_SET_CNF: + return "WNI_CFG_SET_CNF"; + case WNI_CFG_GET_ATTRIB_RSP: + return "WNI_CFG_GET_ATTRIB_RSP"; + case WNI_CFG_ADD_GRP_ADDR_CNF: + return "WNI_CFG_ADD_GRP_ADDR_CNF"; + case WNI_CFG_DEL_GRP_ADDR_CNF: + return "WNI_CFG_DEL_GRP_ADDR_CNF"; + case ANI_CFG_GET_RADIO_STAT_RSP: + return "ANI_CFG_GET_RADIO_STAT_RSP"; + case ANI_CFG_GET_PER_STA_STAT_RSP: + return "ANI_CFG_GET_PER_STA_STAT_RSP"; + case ANI_CFG_GET_AGG_STA_STAT_RSP: + return "ANI_CFG_GET_AGG_STA_STAT_RSP"; + case ANI_CFG_CLEAR_STAT_RSP: + return "ANI_CFG_CLEAR_STAT_RSP"; + case WNI_CFG_DNLD_RSP: + return "WNI_CFG_DNLD_RSP"; + case WNI_CFG_GET_REQ: + return "WNI_CFG_GET_REQ"; + case WNI_CFG_SET_REQ: + return "WNI_CFG_SET_REQ"; + case WNI_CFG_SET_REQ_NO_RSP: + return "WNI_CFG_SET_REQ_NO_RSP"; + case eWNI_PMC_ENTER_IMPS_RSP: + return "eWNI_PMC_ENTER_IMPS_RSP"; + case eWNI_PMC_EXIT_IMPS_RSP: + return "eWNI_PMC_EXIT_IMPS_RSP"; + case eWNI_PMC_ENTER_BMPS_RSP: + return "eWNI_PMC_ENTER_BMPS_RSP"; + case eWNI_PMC_EXIT_BMPS_RSP: + return "eWNI_PMC_EXIT_BMPS_RSP"; + case eWNI_PMC_EXIT_BMPS_IND: + return "eWNI_PMC_EXIT_BMPS_IND"; + case eWNI_SME_SET_BCN_FILTER_REQ: + return "eWNI_SME_SET_BCN_FILTER_REQ"; +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_REQ: + return "eWNI_SME_GET_TSM_STATS_REQ"; + case eWNI_SME_GET_TSM_STATS_RSP: + return "eWNI_SME_GET_TSM_STATS_RSP"; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + default: + return "INVALID SME message"; + } +#endif +return ""; +} + + + +char *limResultCodeStr(tSirResultCodes resultCode) +{ + switch (resultCode) + { + case eSIR_SME_SUCCESS: + return "eSIR_SME_SUCCESS"; + case eSIR_EOF_SOF_EXCEPTION: + return "eSIR_EOF_SOF_EXCEPTION"; + case eSIR_BMU_EXCEPTION: + return "eSIR_BMU_EXCEPTION"; + case eSIR_LOW_PDU_EXCEPTION: + return "eSIR_LOW_PDU_EXCEPTION"; + case eSIR_USER_TRIG_RESET: + return"eSIR_USER_TRIG_RESET"; + case eSIR_LOGP_EXCEPTION: + return "eSIR_LOGP_EXCEPTION"; + case eSIR_CP_EXCEPTION: + return "eSIR_CP_EXCEPTION"; + case eSIR_STOP_BSS: + return "eSIR_STOP_BSS"; + case eSIR_AHB_HANG_EXCEPTION: + return "eSIR_AHB_HANG_EXCEPTION"; + case eSIR_DPU_EXCEPTION: + return "eSIR_DPU_EXCEPTION"; + case eSIR_RXP_EXCEPTION: + return "eSIR_RXP_EXCEPTION"; + case eSIR_MCPU_EXCEPTION: + return "eSIR_MCPU_EXCEPTION"; + case eSIR_MCU_EXCEPTION: + return "eSIR_MCU_EXCEPTION"; + case eSIR_MTU_EXCEPTION: + return "eSIR_MTU_EXCEPTION"; + case eSIR_MIF_EXCEPTION: + return "eSIR_MIF_EXCEPTION"; + case eSIR_FW_EXCEPTION: + return "eSIR_FW_EXCEPTION"; + case eSIR_MAILBOX_SANITY_CHK_FAILED: + return "eSIR_MAILBOX_SANITY_CHK_FAILED"; + case eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF: + return "eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF"; + case eSIR_CFB_FLAG_STUCK_EXCEPTION: + return "eSIR_CFB_FLAG_STUCK_EXCEPTION"; + case eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS: + return "eSIR_SME_BASIC_RATES_NOT_SUPPORTED_STATUS"; + case eSIR_SME_INVALID_PARAMETERS: + return "eSIR_SME_INVALID_PARAMETERS"; + case eSIR_SME_UNEXPECTED_REQ_RESULT_CODE: + return "eSIR_SME_UNEXPECTED_REQ_RESULT_CODE"; + case eSIR_SME_RESOURCES_UNAVAILABLE: + return "eSIR_SME_RESOURCES_UNAVAILABLE"; + case eSIR_SME_SCAN_FAILED: + return "eSIR_SME_SCAN_FAILED"; + case eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED: + return "eSIR_SME_BSS_ALREADY_STARTED_OR_JOINED"; + case eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE: + return "eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE"; + case eSIR_SME_REFUSED: + return "eSIR_SME_REFUSED"; + case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE: + return "eSIR_SME_JOIN_TIMEOUT_RESULT_CODE"; + case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE: + return "eSIR_SME_AUTH_TIMEOUT_RESULT_CODE"; + case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE: + return "eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE"; + case eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE: + return "eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE"; + case eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED: + return "eSIR_SME_MAX_NUM_OF_PRE_AUTH_REACHED"; + case eSIR_SME_AUTH_REFUSED: + return "eSIR_SME_AUTH_REFUSED"; + case eSIR_SME_INVALID_WEP_DEFAULT_KEY: + return "eSIR_SME_INVALID_WEP_DEFAULT_KEY"; + case eSIR_SME_ASSOC_REFUSED: + return "eSIR_SME_ASSOC_REFUSED"; + case eSIR_SME_REASSOC_REFUSED: + return "eSIR_SME_REASSOC_REFUSED"; + case eSIR_SME_STA_NOT_AUTHENTICATED: + return "eSIR_SME_STA_NOT_AUTHENTICATED"; + case eSIR_SME_STA_NOT_ASSOCIATED: + return "eSIR_SME_STA_NOT_ASSOCIATED"; + case eSIR_SME_STA_DISASSOCIATED: + return "eSIR_SME_STA_DISASSOCIATED"; + case eSIR_SME_ALREADY_JOINED_A_BSS: + return "eSIR_SME_ALREADY_JOINED_A_BSS"; + case eSIR_ULA_COMPLETED: + return "eSIR_ULA_COMPLETED"; + case eSIR_ULA_FAILURE: + return "eSIR_ULA_FAILURE"; + case eSIR_SME_LINK_ESTABLISHED: + return "eSIR_SME_LINK_ESTABLISHED"; + case eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS: + return "eSIR_SME_UNABLE_TO_PERFORM_MEASUREMENTS"; + case eSIR_SME_UNABLE_TO_PERFORM_DFS: + return "eSIR_SME_UNABLE_TO_PERFORM_DFS"; + case eSIR_SME_DFS_FAILED: + return "eSIR_SME_DFS_FAILED"; + case eSIR_SME_TRANSFER_STA: + return "eSIR_SME_TRANSFER_STA"; + case eSIR_SME_INVALID_LINK_TEST_PARAMETERS: + return "eSIR_SME_INVALID_LINK_TEST_PARAMETERS"; + case eSIR_SME_LINK_TEST_MAX_EXCEEDED: + return "eSIR_SME_LINK_TEST_MAX_EXCEEDED"; + case eSIR_SME_UNSUPPORTED_RATE: + return "eSIR_SME_UNSUPPORTED_RATE"; + case eSIR_SME_LINK_TEST_TIMEOUT: + return "eSIR_SME_LINK_TEST_TIMEOUT"; + case eSIR_SME_LINK_TEST_COMPLETE: + return "eSIR_SME_LINK_TEST_COMPLETE"; + case eSIR_SME_LINK_TEST_INVALID_STATE: + return "eSIR_SME_LINK_TEST_INVALID_STATE"; + case eSIR_SME_LINK_TEST_INVALID_ADDRESS: + return "eSIR_SME_LINK_TEST_INVALID_ADDRESS"; + case eSIR_SME_POLARIS_RESET: + return "eSIR_SME_POLARIS_RESET"; + case eSIR_SME_SETCONTEXT_FAILED: + return "eSIR_SME_SETCONTEXT_FAILED"; + case eSIR_SME_BSS_RESTART: + return "eSIR_SME_BSS_RESTART"; + case eSIR_SME_MORE_SCAN_RESULTS_FOLLOW: + return "eSIR_SME_MORE_SCAN_RESULTS_FOLLOW"; + case eSIR_SME_INVALID_ASSOC_RSP_RXED: + return "eSIR_SME_INVALID_ASSOC_RSP_RXED"; + case eSIR_SME_MIC_COUNTER_MEASURES: + return "eSIR_SME_MIC_COUNTER_MEASURES"; + case eSIR_SME_ADDTS_RSP_TIMEOUT: + return "eSIR_SME_ADDTS_RSP_TIMEOUT"; + case eSIR_SME_RECEIVED: + return "eSIR_SME_RECEIVED"; + case eSIR_SME_CHANNEL_SWITCH_FAIL: + return "eSIR_SME_CHANNEL_SWITCH_FAIL"; +#ifdef GEN4_SCAN + case eSIR_SME_CHANNEL_SWITCH_DISABLED: + return "eSIR_SME_CHANNEL_SWITCH_DISABLED"; + case eSIR_SME_HAL_SCAN_INIT_FAILED: + return "eSIR_SME_HAL_SCAN_INIT_FAILED"; + case eSIR_SME_HAL_SCAN_START_FAILED: + return "eSIR_SME_HAL_SCAN_START_FAILED"; + case eSIR_SME_HAL_SCAN_END_FAILED: + return "eSIR_SME_HAL_SCAN_END_FAILED"; + case eSIR_SME_HAL_SCAN_FINISH_FAILED: + return "eSIR_SME_HAL_SCAN_FINISH_FAILED"; + case eSIR_SME_HAL_SEND_MESSAGE_FAIL: + return "eSIR_SME_HAL_SEND_MESSAGE_FAIL"; +#else // GEN4_SCAN + case eSIR_SME_CHANNEL_SWITCH_DISABLED: + return "eSIR_SME_CHANNEL_SWITCH_DISABLED"; + case eSIR_SME_HAL_SEND_MESSAGE_FAIL: + return "eSIR_SME_HAL_SEND_MESSAGE_FAIL"; +#endif // GEN4_SCAN + + default: + return "INVALID resultCode"; + } +} + +void +limPrintMsgName(tpAniSirGlobal pMac, tANI_U16 logLevel, tANI_U32 msgType) +{ + limLog(pMac, logLevel, limMsgStr(msgType)); +} + +void +limPrintMsgInfo(tpAniSirGlobal pMac, tANI_U16 logLevel, tSirMsgQ *msg) +{ + if (logLevel <= pMac->utils.gLogDbgLevel[SIR_LIM_MODULE_ID - LOG_FIRST_MODULE_ID]) + { + switch (msg->type) + { + case SIR_BB_XPORT_MGMT_MSG: + limPrintMsgName(pMac, logLevel,msg->type); + break; + default: + limPrintMsgName(pMac, logLevel,msg->type); + break; + } + } +} + +/** + * limInitMlm() + * + *FUNCTION: + * This function is called by limProcessSmeMessages() to + * initialize MLM state machine on STA + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ +void +limInitMlm(tpAniSirGlobal pMac) +{ + tANI_U32 retVal; + + pMac->lim.gLimTimersCreated = 0; + + MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION, pMac->lim.gLimMlmState)); + + /// Initialize scan result hash table + limReInitScanResults(pMac); //sep26th review + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /// Initialize lfr scan result hash table + // Could there be a problem in multisession with SAP/P2P GO, when in the + // middle of FW bg scan, SAP started; Again that could be a problem even on + // infra + SAP/P2P GO too - TBD + limReInitLfrScanResults(pMac); +#endif + + /// Initialize number of pre-auth contexts + pMac->lim.gLimNumPreAuthContexts = 0; + + /// Initialize MAC based Authentication STA list + limInitPreAuthList(pMac); + + //pMac->lim.gpLimMlmJoinReq = NULL; + + if (pMac->lim.gLimTimersCreated) + return; + + // Create timers used by LIM + retVal = limCreateTimers(pMac); + if(retVal == TX_SUCCESS) + { + pMac->lim.gLimTimersCreated = 1; + } + else + { + limLog(pMac, LOGP, FL(" limCreateTimers Failed to create lim timers ")); + } +} /*** end limInitMlm() ***/ + + + +/** + * limCleanupMlm() + * + *FUNCTION: + * This function is called to cleanup any resources + * allocated by the MLM state machine. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * It is assumed that BSS is already informed that we're leaving it + * before this function is called. + * + * @param pMac Pointer to Global MAC structure + * @param None + * @return None + */ +void +limCleanupMlm(tpAniSirGlobal pMac) +{ + tANI_U32 n; + tLimPreAuthNode *pAuthNode; +#ifdef WLAN_FEATURE_11W + tANI_U32 bss_entry, sta_entry; + tpDphHashNode pStaDs = NULL; + tpPESession psessionEntry = NULL; +#endif + + if (pMac->lim.gLimTimersCreated == 1) + { + // Deactivate and delete MIN/MAX channel timers. + tx_timer_deactivate(&pMac->lim.limTimers.gLimMinChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMinChannelTimer); + tx_timer_deactivate(&pMac->lim.limTimers.gLimMaxChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimMaxChannelTimer); + tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicProbeReqTimer); + + + // Deactivate and delete channel switch timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimChannelSwitchTimer); + + + // Deactivate and delete addts response timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAddtsRspTimer); + + // Deactivate and delete Join failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimJoinFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimJoinFailureTimer); + + // Deactivate and delete Periodic Join Probe Request timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicJoinProbeReqTimer); + + // Deactivate and delete Auth Retry timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPeriodicAuthRetryTimer); + + // Deactivate and delete Association failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimAssocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAssocFailureTimer); + + // Deactivate and delete Reassociation failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimReassocFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimReassocFailureTimer); + + // Deactivate and delete Authentication failure timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimAuthFailureTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimAuthFailureTimer); + + // Deactivate and delete Heartbeat timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimHeartBeatTimer); + + // Deactivate and delete wait-for-probe-after-Heartbeat timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimProbeAfterHBTimer); + + // Deactivate and delete Quiet timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietTimer); + + // Deactivate and delete Quiet BSS timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimQuietBssTimer); + + // Deactivate and delete LIM background scan timer. + tx_timer_deactivate(&pMac->lim.limTimers.gLimBackgroundScanTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimBackgroundScanTimer); + + + // Deactivate and delete cnf wait timer + for (n = 0; n < pMac->lim.maxStation; n++) + { + tx_timer_deactivate(&pMac->lim.limTimers.gpLimCnfWaitTimer[n]); + tx_timer_delete(&pMac->lim.limTimers.gpLimCnfWaitTimer[n]); + } + + // Deactivate and delete keepalive timer + tx_timer_deactivate(&pMac->lim.limTimers.gLimKeepaliveTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimKeepaliveTimer); + + pAuthNode = pMac->lim.gLimPreAuthTimerTable.pTable; + + //Deactivate any Authentication response timers + limDeletePreAuthList(pMac); + + for (n = 0; n < pMac->lim.gLimPreAuthTimerTable.numEntry; n++,pAuthNode++) + { + // Delete any Authentication response + // timers, which might have been started. + tx_timer_delete(&pAuthNode->timer); + } + + tx_timer_deactivate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer); + tx_timer_deactivate(&pMac->lim.limTimers.gLimPreAuthClnupTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimPreAuthClnupTimer); + +#if 0 // The WPS PBC clean up timer is disabled + if (pMac->lim.gLimSystemRole == eLIM_AP_ROLE) + { + if(pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated == eANI_BOOLEAN_TRUE) + { + tx_timer_deactivate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer); + pMac->lim.limTimers.gLimWPSOverlapTimerObj.isTimerCreated = eANI_BOOLEAN_FALSE; + } + } +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + // Deactivate and delete FT Preauth response timer + tx_timer_deactivate(&pMac->lim.limTimers.gLimFTPreAuthRspTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimFTPreAuthRspTimer); +#endif + + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + // Deactivate and delete TSM + tx_timer_deactivate(&pMac->lim.limTimers.gLimEseTsmTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimEseTsmTimer); +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ + + tx_timer_deactivate(&pMac->lim.limTimers.gLimDisassocAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimDisassocAckTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimDeauthAckTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimDeauthAckTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimP2pSingleShotNoaInsertTimer); + + tx_timer_deactivate(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer); + + pMac->lim.gLimTimersCreated = 0; + } + +#ifdef WLAN_FEATURE_11W + /* + * When SSR is triggered, we need to loop through + * each STA associated per BSSId and deactivate/delete + * the pmfSaQueryTimer for it + */ + if (vos_is_logp_in_progress(VOS_MODULE_ID_PE, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("SSR is detected, proceed to clean up pmfSaQueryTimer")); + for (bss_entry = 0; bss_entry < pMac->lim.maxBssId; bss_entry++) + { + if (pMac->lim.gpSession[bss_entry].valid) + { + for (sta_entry = 1; sta_entry < pMac->lim.gLimAssocStaLimit; + sta_entry++) + { + psessionEntry = &pMac->lim.gpSession[bss_entry]; + pStaDs = dphGetHashEntry(pMac, sta_entry, + &psessionEntry->dph.dphHashTable); + if (NULL == pStaDs) + { + continue; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("Deleting pmfSaQueryTimer for staid[%d]"), + pStaDs->staIndex) ; + tx_timer_deactivate(&pStaDs->pmfSaQueryTimer); + tx_timer_delete(&pStaDs->pmfSaQueryTimer); + } + } + } + } +#endif + + /// Cleanup cached scan list + limReInitScanResults(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /// Cleanup cached scan list + limReInitLfrScanResults(pMac); +#endif + +} /*** end limCleanupMlm() ***/ + + + +/** + * limCleanupLmm() + * + *FUNCTION: + * This function is called to cleanup any resources + * allocated by LMM sub-module. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac Pointer to Global MAC structure + * @return None + */ + +void +limCleanupLmm(tpAniSirGlobal pMac) +{ +} /*** end limCleanupLmm() ***/ + + + +/** + * limIsAddrBC() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether passed MAC address is a broadcast or not + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param macAddr Indicates MAC address that need to be determined + * whether it is Broadcast address or not + * + * @return true if passed address is Broadcast address else false + */ + +tANI_U8 +limIsAddrBC(tSirMacAddr macAddr) +{ + int i; + for (i = 0; i < 6; i++) + { + if ((macAddr[i] & 0xFF) != 0xFF) + return false; + } + + return true; +} /****** end limIsAddrBC() ******/ + + + +/** + * limIsGroupAddr() + * + *FUNCTION: + * This function is called in various places within LIM code + * to determine whether passed MAC address is a group address or not + * + *LOGIC: + * If least significant bit of first octet of the MAC address is + * set to 1, it is a Group address. + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param macAddr Indicates MAC address that need to be determined + * whether it is Group address or not + * + * @return true if passed address is Group address else false + */ + +tANI_U8 +limIsGroupAddr(tSirMacAddr macAddr) +{ + if ((macAddr[0] & 0x01) == 0x01) + return true; + else + return false; +} /****** end limIsGroupAddr() ******/ + +/** + * limPostMsgApiNoWait() + * + *FUNCTION: + * This function is called from other thread while posting a + * message to LIM message Queue gSirLimMsgQ with NO_WAIT option + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMsg - Pointer to the Global MAC structure + * @param pMsg - Pointer to the message structure + * @return None + */ + +tANI_U32 +limPostMsgApiNoWait(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + limProcessMessages(pMac, pMsg); + return TX_SUCCESS; +} /*** end limPostMsgApiNoWait() ***/ + + + +/** + * limPrintMacAddr() + * + *FUNCTION: + * This function is called to print passed MAC address + * in : format. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * @param macAddr - MacAddr to be printed + * @param logLevel - Loglevel to be used + * + * @return None. + */ + +void +limPrintMacAddr(tpAniSirGlobal pMac, tSirMacAddr macAddr, tANI_U8 logLevel) +{ + limLog(pMac, logLevel, + FL(MAC_ADDRESS_STR), MAC_ADDR_ARRAY(macAddr)); +} /****** end limPrintMacAddr() ******/ + + +/* + * limResetDeferredMsgQ() + * + *FUNCTION: + * This function resets the deferred message queue parameters. + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + *RETURNS: + * None + */ + +void limResetDeferredMsgQ(tpAniSirGlobal pMac) +{ + pMac->lim.gLimDeferredMsgQ.size = + pMac->lim.gLimDeferredMsgQ.write = + pMac->lim.gLimDeferredMsgQ.read = 0; + +} + + +#define LIM_DEFERRED_Q_CHECK_THRESHOLD (MAX_DEFERRED_QUEUE_LEN/2) +#define LIM_MAX_NUM_MGMT_FRAME_DEFERRED (MAX_DEFERRED_QUEUE_LEN/2) + +/* + * limWriteDeferredMsgQ() + * + *FUNCTION: + * This function queues up a deferred message for later processing on the + * STA side. + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * @param limMsg - a LIM message + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + *RETURNS: + * None + */ + +tANI_U8 limWriteDeferredMsgQ(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + PELOG1(limLog(pMac, LOG1, + FL("** Queue a deferred message (size %d, write %d) - type 0x%x **"), + pMac->lim.gLimDeferredMsgQ.size, pMac->lim.gLimDeferredMsgQ.write, + limMsg->type);) + + /* + ** check if the deferred message queue is full + **/ + if (pMac->lim.gLimDeferredMsgQ.size >= MAX_DEFERRED_QUEUE_LEN) + { + if (!(pMac->lim.deferredMsgCnt & 0xF)) + { + limLog(pMac, LOGE, + FL("Deferred Message Queue is full. Msg:%d Messages Failed:%d"), + limMsg->type, ++pMac->lim.deferredMsgCnt); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_QUEUE_FULL, + FALSE, TRUE); + } + else + { + pMac->lim.deferredMsgCnt++; + } + return TX_QUEUE_FULL; + } + + /* + ** In the application, there should not be more than 1 message get + ** queued up. If happens, flags a warning. In the future, this can + ** happen. + **/ + if (pMac->lim.gLimDeferredMsgQ.size > 0) + { + PELOGW(limLog(pMac, LOGW, FL("%d Deferred messages (type 0x%x, scan %d, global sme %d, global mlme %d, addts %d)"), + pMac->lim.gLimDeferredMsgQ.size, limMsg->type, + limIsSystemInScanState(pMac), + pMac->lim.gLimSmeState, pMac->lim.gLimMlmState, + pMac->lim.gLimAddtsSent);) + } + + /* + ** To prevent the deferred Q is full of management frames, only give them certain space + **/ + if( SIR_BB_XPORT_MGMT_MSG == limMsg->type ) + { + if( LIM_DEFERRED_Q_CHECK_THRESHOLD < pMac->lim.gLimDeferredMsgQ.size ) + { + tANI_U16 idx, count = 0; + for(idx = 0; idx < pMac->lim.gLimDeferredMsgQ.size; idx++) + { + if( SIR_BB_XPORT_MGMT_MSG == pMac->lim.gLimDeferredMsgQ.deferredQueue[idx].type ) + { + count++; + } + } + if( LIM_MAX_NUM_MGMT_FRAME_DEFERRED < count ) + { + //We reach the quota for management frames, drop this one + PELOGW(limLog(pMac, LOGW, FL("Cannot deferred. Msg: %d Too many (count=%d) already"), limMsg->type, count);) + //Return error, caller knows what to do + return TX_QUEUE_FULL; + } + } + } + + ++pMac->lim.gLimDeferredMsgQ.size; + + /* reset the count here since we are able to defer the message */ + if(pMac->lim.deferredMsgCnt != 0) + { + pMac->lim.deferredMsgCnt = 0; + } + + /* + ** if the write pointer hits the end of the queue, rewind it + **/ + if (pMac->lim.gLimDeferredMsgQ.write >= MAX_DEFERRED_QUEUE_LEN) + pMac->lim.gLimDeferredMsgQ.write = 0; + + /* + ** save the message to the queue and advanced the write pointer + **/ + vos_mem_copy( (tANI_U8 *)&pMac->lim.gLimDeferredMsgQ.deferredQueue[ + pMac->lim.gLimDeferredMsgQ.write++], + (tANI_U8 *)limMsg, + sizeof(tSirMsgQ)); + return TX_SUCCESS; + +} + +/* + * limReadDeferredMsgQ() + * + *FUNCTION: + * This function dequeues a deferred message for processing on the + * STA side. + * + *PARAMS: + * @param pMac - Pointer to Global MAC structure + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * + *RETURNS: + * Returns the message at the head of the deferred message queue + */ + +tSirMsgQ* limReadDeferredMsgQ(tpAniSirGlobal pMac) +{ + tSirMsgQ *msg; + + /* + ** check any messages left. If no, return + **/ + if (pMac->lim.gLimDeferredMsgQ.size <= 0) + return NULL; + + /* + ** decrement the queue size + **/ + pMac->lim.gLimDeferredMsgQ.size--; + + /* + ** retrieve the message from the head of the queue + **/ + msg = &pMac->lim.gLimDeferredMsgQ.deferredQueue[pMac->lim.gLimDeferredMsgQ.read]; + + /* + ** advance the read pointer + **/ + pMac->lim.gLimDeferredMsgQ.read++; + + /* + ** if the read pointer hits the end of the queue, rewind it + **/ + if (pMac->lim.gLimDeferredMsgQ.read >= MAX_DEFERRED_QUEUE_LEN) + pMac->lim.gLimDeferredMsgQ.read = 0; + + PELOG1(limLog(pMac, LOG1, + FL("** DeQueue a deferred message (size %d read %d) - type 0x%x **"), + pMac->lim.gLimDeferredMsgQ.size, pMac->lim.gLimDeferredMsgQ.read, + msg->type);) + + PELOG1(limLog(pMac, LOG1, FL("DQ msg -- scan %d, global sme %d, global mlme %d, addts %d"), + limIsSystemInScanState(pMac), + pMac->lim.gLimSmeState, pMac->lim.gLimMlmState, + pMac->lim.gLimAddtsSent);) + + return(msg); +} + +tSirRetStatus +limSysProcessMmhMsgApi(tpAniSirGlobal pMac, + tSirMsgQ *pMsg, + tANI_U8 qType) +{ +// FIXME + SysProcessMmhMsg(pMac, pMsg); + return eSIR_SUCCESS; +} + +char *limFrameStr(tANI_U32 type, tANI_U32 subType) +{ +#ifdef FIXME_GEN6 + + if (type == SIR_MAC_MGMT_FRAME) + { + switch (subType) + { + case SIR_MAC_MGMT_ASSOC_REQ: + return "MAC_MGMT_ASSOC_REQ"; + case SIR_MAC_MGMT_ASSOC_RSP: + return "MAC_MGMT_ASSOC_RSP"; + case SIR_MAC_MGMT_REASSOC_REQ: + return "MAC_MGMT_REASSOC_REQ"; + case SIR_MAC_MGMT_REASSOC_RSP: + return "MAC_MGMT_REASSOC_RSP"; + case SIR_MAC_MGMT_PROBE_REQ: + return "MAC_MGMT_PROBE_REQ"; + case SIR_MAC_MGMT_PROBE_RSP: + return "MAC_MGMT_PROBE_RSP"; + case SIR_MAC_MGMT_BEACON: + return "MAC_MGMT_BEACON"; + case SIR_MAC_MGMT_ATIM: + return "MAC_MGMT_ATIM"; + case SIR_MAC_MGMT_DISASSOC: + return "MAC_MGMT_DISASSOC"; + case SIR_MAC_MGMT_AUTH: + return "MAC_MGMT_AUTH"; + case SIR_MAC_MGMT_DEAUTH: + return "MAC_MGMT_DEAUTH"; + case SIR_MAC_MGMT_ACTION: + return "MAC_MGMT_ACTION"; + case SIR_MAC_MGMT_RESERVED15: + return "MAC_MGMT_RESERVED15"; + default: + return "Unknown MGMT Frame"; + } + } + + else if (type == SIR_MAC_CTRL_FRAME) + { + switch (subType) + { + case SIR_MAC_CTRL_RR: + return "MAC_CTRL_RR"; + case SIR_MAC_CTRL_BAR: + return "MAC_CTRL_BAR"; + case SIR_MAC_CTRL_BA: + return "MAC_CTRL_BA"; + case SIR_MAC_CTRL_PS_POLL: + return "MAC_CTRL_PS_POLL"; + case SIR_MAC_CTRL_RTS: + return "MAC_CTRL_RTS"; + case SIR_MAC_CTRL_CTS: + return "MAC_CTRL_CTS"; + case SIR_MAC_CTRL_ACK: + return "MAC_CTRL_ACK"; + case SIR_MAC_CTRL_CF_END: + return "MAC_CTRL_CF_END"; + case SIR_MAC_CTRL_CF_END_ACK: + return "MAC_CTRL_CF_END_ACK"; + default: + return "Unknown CTRL Frame"; + } + } + + else if (type == SIR_MAC_DATA_FRAME) + { + switch (subType) + { + case SIR_MAC_DATA_DATA: + return "MAC_DATA_DATA"; + case SIR_MAC_DATA_DATA_ACK: + return "MAC_DATA_DATA_ACK"; + case SIR_MAC_DATA_DATA_POLL: + return "MAC_DATA_DATA_POLL"; + case SIR_MAC_DATA_DATA_ACK_POLL: + return "MAC_DATA_DATA_ACK_POLL"; + case SIR_MAC_DATA_NULL: + return "MAC_DATA_NULL"; + case SIR_MAC_DATA_NULL_ACK: + return "MAC_DATA_NULL_ACK"; + case SIR_MAC_DATA_NULL_POLL: + return "MAC_DATA_NULL_POLL"; + case SIR_MAC_DATA_NULL_ACK_POLL: + return "MAC_DATA_NULL_ACK_POLL"; + case SIR_MAC_DATA_QOS_DATA: + return "MAC_DATA_QOS_DATA"; + case SIR_MAC_DATA_QOS_DATA_ACK: + return "MAC_DATA_QOS_DATA_ACK"; + case SIR_MAC_DATA_QOS_DATA_POLL: + return "MAC_DATA_QOS_DATA_POLL"; + case SIR_MAC_DATA_QOS_DATA_ACK_POLL: + return "MAC_DATA_QOS_DATA_ACK_POLL"; + case SIR_MAC_DATA_QOS_NULL: + return "MAC_DATA_QOS_NULL"; + case SIR_MAC_DATA_QOS_NULL_ACK: + return "MAC_DATA_QOS_NULL_ACK"; + case SIR_MAC_DATA_QOS_NULL_POLL: + return "MAC_DATA_QOS_NULL_POLL"; + case SIR_MAC_DATA_QOS_NULL_ACK_POLL: + return "MAC_DATA_QOS_NULL_ACK_POLL"; + default: + return "Unknown Data Frame"; + } + } + else + return "Unknown"; +#endif +return ""; +} + +void limHandleUpdateOlbcCache(tpAniSirGlobal pMac) +{ + int i; + static int enable; + tUpdateBeaconParams beaconParams; + + tpPESession psessionEntry = limIsApSessionActive(pMac); + + if (psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOGE, FL(" Session not found"));) + return; + } + + vos_mem_set( ( tANI_U8* )&beaconParams, sizeof( tUpdateBeaconParams), 0); + beaconParams.bssIdx = psessionEntry->bssIdx; + + beaconParams.paramChangeBitmap = 0; + /* + ** This is doing a 2 pass check. The first pass is to invalidate + ** all the cache entries. The second pass is to decide whether to + ** disable protection. + **/ + if (!enable) + { + + PELOG2(limLog(pMac, LOG2, FL("Resetting OLBC cache"));) + psessionEntry->gLimOlbcParams.numSta = 0; + psessionEntry->gLimOverlap11gParams.numSta = 0; + psessionEntry->gLimOverlapHt20Params.numSta = 0; + psessionEntry->gLimNonGfParams.numSta = 0; + psessionEntry->gLimLsigTxopParams.numSta = 0; + + for (i=0; i < LIM_PROT_STA_OVERLAP_CACHE_SIZE; i++) + pMac->lim.protStaOverlapCache[i].active = false; + + enable = 1; + } + else + { + + if (!psessionEntry->gLimOlbcParams.numSta) + { + if (psessionEntry->gLimOlbcParams.protectionEnabled) + { + if (!psessionEntry->gLim11bParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no 11B STA detected"));) + limEnable11gProtection(pMac, false, true, &beaconParams, psessionEntry); + } + } + } + + if (!psessionEntry->gLimOverlap11gParams.numSta) + { + if (psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + if (!psessionEntry->gLim11gParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no 11G STA detected"));) + limEnableHtProtectionFrom11g(pMac, false, true, &beaconParams,psessionEntry); + } + } + } + + if (!psessionEntry->gLimOverlapHt20Params.numSta) + { + if (psessionEntry->gLimOverlapHt20Params.protectionEnabled) + { + if (!psessionEntry->gLimHt20Params.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("Overlap cache all clear and no HT20 STA detected"));) + limEnable11gProtection(pMac, false, true, &beaconParams,psessionEntry); + } + } + } + + enable = 0; + } + + if(beaconParams.paramChangeBitmap) + { + schSetFixedBeaconFields(pMac,psessionEntry); + limSendBeaconParams(pMac, &beaconParams, psessionEntry); + } + + // Start OLBC timer + if (tx_timer_activate(&pMac->lim.limTimers.gLimUpdateOlbcCacheTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("tx_timer_activate failed")); + } +} + +/** + * limIsNullSsid() + * + *FUNCTION: + * This function checks if Ssid supplied is Null SSID + * + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param tSirMacSSid * + * + * + * @return true if SSID is Null SSID else false + */ + +tANI_U8 +limIsNullSsid( tSirMacSSid *pSsid ) +{ + tANI_U8 fNullSsid = false; + tANI_U32 SsidLength; + tANI_U8 *pSsidStr; + + do + { + if ( 0 == pSsid->length ) + { + fNullSsid = true; + break; + } + +#define ASCII_SPACE_CHARACTER 0x20 + /* If the first charactes is space and SSID length is 1 + * then consider it as NULL SSID*/ + if ((ASCII_SPACE_CHARACTER == pSsid->ssId[0]) && + (pSsid->length == 1)) + { + fNullSsid = true; + break; + } + else + { + /* check if all the charactes in SSID are NULL*/ + SsidLength = pSsid->length; + pSsidStr = pSsid->ssId; + + while ( SsidLength ) + { + if( *pSsidStr ) + break; + + pSsidStr++; + SsidLength--; + } + + if( 0 == SsidLength ) + { + fNullSsid = true; + break; + } + } + } + while( 0 ); + + return fNullSsid; +} /****** end limIsNullSsid() ******/ + + + + +/** ------------------------------------------------------------- +\fn limUpdateProtStaParams +\brief updates protection related counters. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tLimProtStaCacheType protStaCacheType +\param tHalBitVal gfSupported +\param tHalBitVal lsigTxopSupported +\return None + -------------------------------------------------------------*/ +void +limUpdateProtStaParams(tpAniSirGlobal pMac, +tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType, +tHalBitVal gfSupported, tHalBitVal lsigTxopSupported, +tpPESession psessionEntry) +{ + tANI_U32 i; + + PELOG1(limLog(pMac,LOG1, FL("A STA is associated:")); + limLog(pMac,LOG1, FL("Addr : ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + + for (i=0; iprotStaCache[i].active) + { + PELOG1(limLog(pMac, LOG1, FL("Addr: "));) + PELOG1(limPrintMacAddr(pMac, psessionEntry->protStaCache[i].addr, LOG1);) + + if (vos_mem_compare( + psessionEntry->protStaCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + { + PELOG1(limLog(pMac, LOG1, FL("matching cache entry at %d already active."), i);) + return; + } + } + } + + for (i=0; iprotStaCache[i].active) + break; + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache"));) + return; + } + + vos_mem_copy( psessionEntry->protStaCache[i].addr, + peerMacAddr, + sizeof(tSirMacAddr)); + + psessionEntry->protStaCache[i].protStaCacheType = protStaCacheType; + psessionEntry->protStaCache[i].active = true; + if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) + { + psessionEntry->gLim11bParams.numSta++; + limLog(pMac,LOG1, FL("11B, ")); + } + else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) + { + psessionEntry->gLim11gParams.numSta++; + limLog(pMac,LOG1, FL("11G, ")); + } + else if(eLIM_PROT_STA_CACHE_TYPE_HT20 == protStaCacheType) + { + psessionEntry->gLimHt20Params.numSta++; + limLog(pMac,LOG1, FL("HT20, ")); + } + + if(!gfSupported) + { + psessionEntry->gLimNonGfParams.numSta++; + limLog(pMac,LOG1, FL("NonGf, ")); + } + if(!lsigTxopSupported) + { + psessionEntry->gLimLsigTxopParams.numSta++; + limLog(pMac,LOG1, FL("!lsigTxopSupported")); + } +}// --------------------------------------------------------------------- + +/** ------------------------------------------------------------- +\fn limDecideApProtection +\brief Decides all the protection related staiton coexistence and also sets +\ short preamble and short slot appropriately. This function will be called +\ when AP is ready to send assocRsp tp the station joining right now. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\return None + -------------------------------------------------------------*/ +void +limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + tANI_U16 tmpAid; + tpDphHashNode pStaDs; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode; + tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID; + tHalBitVal gfSupported = eHAL_SET, lsigTxopSupported = eHAL_SET; + + pBeaconParams->paramChangeBitmap = 0; + // check whether to enable protection or not + pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable); + if(NULL == pStaDs) + { + limLog(pMac, LOG1, FL("pStaDs is NULL")); + return; + } + limGetRfBand(pMac, &rfBand, psessionEntry); + //if we are in 5 GHZ band + if(SIR_BAND_5_GHZ == rfBand) + { + //We are 11N. we need to protect from 11A and Ht20. we don't need any other protection in 5 GHZ. + //HT20 case is common between both the bands and handled down as common code. + if(true == psessionEntry->htCapability) + { + //we are 11N and 11A station is joining. + //protection from 11A required. + if(false == pStaDs->mlmStaContext.htCapability) + { + limEnable11aProtection(pMac, true, false, pBeaconParams,psessionEntry); + return; + } + } + } + else if(SIR_BAND_2_4_GHZ== rfBand) + { + limGetPhyMode(pMac, &phyMode, psessionEntry); + + //We are 11G. Check if we need protection from 11b Stations. + if ((phyMode == WNI_CFG_PHY_MODE_11G) && + (false == psessionEntry->htCapability)) + { + + if (pStaDs->erpEnabled== eHAL_CLEAR) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB; + // enable protection + PELOG3(limLog(pMac, LOG3, FL("Enabling protection from 11B"));) + limEnable11gProtection(pMac, true, false, pBeaconParams,psessionEntry); + } + } + + //HT station. + if (true == psessionEntry->htCapability) + { + //check if we need protection from 11b station + if ((pStaDs->erpEnabled == eHAL_CLEAR) && + (!pStaDs->mlmStaContext.htCapability)) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB; + // enable protection + PELOG3(limLog(pMac, LOG3, FL("Enabling protection from 11B"));) + limEnable11gProtection(pMac, true, false, pBeaconParams, psessionEntry); + } + //station being joined is non-11b and non-ht ==> 11g device + else if(!pStaDs->mlmStaContext.htCapability) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llG; + //enable protection + limEnableHtProtectionFrom11g(pMac, true, false, pBeaconParams, psessionEntry); + } + //ERP mode is enabled for the latest station joined + //latest station joined is HT capable + //This case is being handled in common code (commn between both the bands) below. + } + } + + //we are HT and HT station is joining. This code is common for both the bands. + if((true == psessionEntry->htCapability) && + (true == pStaDs->mlmStaContext.htCapability)) + { + if(!pStaDs->htGreenfield) + { + limEnableHTNonGfProtection(pMac, true, false, pBeaconParams, psessionEntry); + gfSupported = eHAL_CLEAR; + } + //Station joining is HT 20Mhz + if(eHT_CHANNEL_WIDTH_20MHZ == pStaDs->htSupportedChannelWidthSet) + { + protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_HT20; + limEnableHT20Protection(pMac, true, false, pBeaconParams, psessionEntry); + } + //Station joining does not support LSIG TXOP Protection + if(!pStaDs->htLsigTXOPProtection) + { + limEnableHTLsigTxopProtection(pMac, false, false, pBeaconParams,psessionEntry); + lsigTxopSupported = eHAL_CLEAR; + } + } + + limUpdateProtStaParams(pMac, peerMacAddr, protStaCacheType, + gfSupported, lsigTxopSupported, psessionEntry); + + return; +} + + +/** ------------------------------------------------------------- +\fn limEnableOverlap11gProtection +\brief wrapper function for setting overlap 11g protection. +\param tpAniSirGlobal pMac +\param tpUpdateBeaconParams pBeaconParams +\param tpSirMacMgmtHdr pMh +\return None + -------------------------------------------------------------*/ +void +limEnableOverlap11gProtection(tpAniSirGlobal pMac, +tpUpdateBeaconParams pBeaconParams, tpSirMacMgmtHdr pMh,tpPESession psessionEntry) +{ + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOlbcParams)); + + if (psessionEntry->gLimOlbcParams.numSta && + !psessionEntry->gLimOlbcParams.protectionEnabled) + { + // enable protection + PELOG1(limLog(pMac, LOG1, FL("OLBC happens!!!"));) + limEnable11gProtection(pMac, true, true, pBeaconParams,psessionEntry); + } +} + + +/** ------------------------------------------------------------- +\fn limUpdateShortPreamble +\brief Updates short preamble if needed when a new station joins. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U16 tmpAid; + tpDphHashNode pStaDs; + tANI_U32 phyMode; + tANI_U16 i; + + // check whether to enable protection or not + pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable); + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if (pStaDs != NULL && phyMode == WNI_CFG_PHY_MODE_11G) + + { + if (pStaDs->shortPreambleEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac,LOG1,FL("Short Preamble is not enabled in Assoc Req from ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + psessionEntry->gLimNoShortParams.staNoShortCache[i].active) + { + if (vos_mem_compare( + psessionEntry->gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if (pMac->lim.gLimNoShortParams.staNoShortCache[i].active) + { + if (vos_mem_compare( + pMac->lim.gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + } + } + } + + + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->gLimNoShortParams.staNoShortCache[i].active) + break; + else + { + if (!pMac->lim.gLimNoShortParams.staNoShortCache[i].active) + break; + } + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + limLog(pMac, LOGE, FL("No space in Short cache (#active %d, #sta %d) for sta "), + i, psessionEntry->gLimNoShortParams.numNonShortPreambleSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + } + else + { + limLog(pMac, LOGE, FL("No space in Short cache (#active %d, #sta %d) for sta "), + i, pMac->lim.gLimNoShortParams.numNonShortPreambleSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + } + + } + + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE){ + vos_mem_copy( psessionEntry->gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + psessionEntry->gLimNoShortParams.staNoShortCache[i].active = true; + psessionEntry->gLimNoShortParams.numNonShortPreambleSta++; + }else + { + vos_mem_copy( pMac->lim.gLimNoShortParams.staNoShortCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + pMac->lim.gLimNoShortParams.staNoShortCache[i].active = true; + pMac->lim.gLimNoShortParams.numNonShortPreambleSta++; + } + + + // enable long preamble + PELOG1(limLog(pMac, LOG1, FL("Disabling short preamble"));) + + if (limEnableShortPreamble(pMac, false, pBeaconParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Cannot enable long preamble"));) + } + } +} + +/** ------------------------------------------------------------- +\fn limUpdateShortSlotTime +\brief Updates short slot time if needed when a new station joins. +\param tpAniSirGlobal pMac +\param tSirMacAddr peerMacAddr +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ + +void +limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, + tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U16 tmpAid; + tpDphHashNode pStaDs; + tANI_U32 phyMode; + tANI_U32 val; + tANI_U16 i; + + // check whether to enable protection or not + pStaDs = dphLookupHashEntry(pMac, peerMacAddr, &tmpAid, &psessionEntry->dph.dphHashTable); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + /* Only in case of softap in 11g mode, slot time might change depending on the STA being added. In 11a case, it should + * be always 1 and in 11b case, it should be always 0 + */ + if (pStaDs != NULL && phyMode == WNI_CFG_PHY_MODE_11G) + { + /* Only when the new STA has short slot time disabled, we need to change softap's overall slot time settings + * else the default for softap is always short slot enabled. When the last long slot STA leaves softAP, we take care of + * it in limDecideShortSlot + */ + if (pStaDs->shortSlotTimeEnabled == eHAL_CLEAR) + { + PELOG1(limLog(pMac, LOG1, FL("Short Slot Time is not enabled in Assoc Req from ")); + limPrintMacAddr(pMac, peerMacAddr, LOG1);) + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare( + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + } + else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + if (pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) + { + if (vos_mem_compare( + pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr))) + return; + } + } + } + + for (i=0; ilimSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active) + break; + else + { + if (!pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active) + break; + } + } + + if (i >= LIM_PROT_STA_CACHE_SIZE) + { + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + limLog(pMac, LOGE, FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "), + i, psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + }else + { + limLog(pMac, LOGE, FL("No space in ShortSlot cache (#active %d, #sta %d) for sta "), + i, pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta); + limPrintMacAddr(pMac, peerMacAddr, LOGE); + return; + } + } + + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + vos_mem_copy( psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + psessionEntry->gLimNoShortSlotParams.staNoShortSlotCache[i].active = true; + psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta++; + }else + { + vos_mem_copy( pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].addr, + peerMacAddr, sizeof(tSirMacAddr)); + pMac->lim.gLimNoShortSlotParams.staNoShortSlotCache[i].active = true; + pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta++; + } + wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, &val); + + /* Here we check if we are AP role and short slot enabled (both admin and oper modes) but we have atleast one STA connected with + * only long slot enabled, we need to change our beacon/pb rsp to broadcast short slot disabled + */ + if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (val && psessionEntry->gLimNoShortSlotParams.numNonShortSlotSta && psessionEntry->shortSlotTimeSupported)) + { + // enable long slot time + pBeaconParams->fShortSlotTime = false; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + PELOG1(limLog(pMac, LOG1, FL("Disable short slot time. Enable long slot time."));) + psessionEntry->shortSlotTimeSupported = false; + } + else if ( psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if (val && pMac->lim.gLimNoShortSlotParams.numNonShortSlotSta && psessionEntry->shortSlotTimeSupported) + { + // enable long slot time + pBeaconParams->fShortSlotTime = false; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_SLOT_TIME_CHANGED; + PELOG1(limLog(pMac, LOG1, FL("Disable short slot time. Enable long slot time."));) + psessionEntry->shortSlotTimeSupported = false; + } + } + } + } +} + + +/** ------------------------------------------------------------- +\fn limDecideStaProtectionOnAssoc +\brief Decide protection related settings on Sta while association. +\param tpAniSirGlobal pMac +\param tpSchBeaconStruct pBeaconStruct +\return None + -------------------------------------------------------------*/ +void +limDecideStaProtectionOnAssoc(tpAniSirGlobal pMac, + tpSchBeaconStruct pBeaconStruct, tpPESession psessionEntry) +{ + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode = WNI_CFG_PHY_MODE_NONE; + + limGetRfBand(pMac, &rfBand, psessionEntry); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if(SIR_BAND_5_GHZ == rfBand) + { + if((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode)) + { + if(pMac->lim.cfgProtection.fromlla) + psessionEntry->beaconParams.llaCoexist = true; + } + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBeaconStruct->HTInfo.opMode) + { + if(pMac->lim.cfgProtection.ht20) + psessionEntry->beaconParams.ht20Coexist = true; + } + + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + //spec 7.3.2.13 + //UseProtection will be set when nonERP STA is associated. + //NonERPPresent bit will be set when: + //--nonERP Sta is associated OR + //--nonERP Sta exists in overlapping BSS + //when useProtection is not set then protection from nonERP stations is optional. + + //CFG protection from 11b is enabled and + //11B device in the BSS + /* TODO, This is not sessionized */ + if (phyMode != WNI_CFG_PHY_MODE_11B) + { + if (pMac->lim.cfgProtection.fromllb && + pBeaconStruct->erpPresent && + (pBeaconStruct->erpIEInfo.useProtection || + pBeaconStruct->erpIEInfo.nonErpPresent)) + { + psessionEntry->beaconParams.llbCoexist = true; + } + //AP has no 11b station associated. + else + { + psessionEntry->beaconParams.llbCoexist = false; + } + } + //following code block is only for HT station. + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + + //Obss Non HT STA present mode + psessionEntry->beaconParams.gHTObssMode = (tANI_U8)htInfo.obssNonHTStaPresent; + + + //CFG protection from 11G is enabled and + //our AP has at least one 11G station associated. + if(pMac->lim.cfgProtection.fromllg && + ((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))&& + (!psessionEntry->beaconParams.llbCoexist)) + { + if(pMac->lim.cfgProtection.fromllg) + psessionEntry->beaconParams.llgCoexist = true; + } + + //AP has only HT stations associated and at least one station is HT 20 + //disable protection from any non-HT devices. + //decision for disabling protection from 11b has already been taken above. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) + { + //Disable protection from 11G station. + psessionEntry->beaconParams.llgCoexist = false; + //CFG protection from HT 20 is enabled. + if(pMac->lim.cfgProtection.ht20) + psessionEntry->beaconParams.ht20Coexist = true; + } + //Disable protection from non-HT and HT20 devices. + //decision for disabling protection from 11b has already been taken above. + if(eSIR_HT_OP_MODE_PURE == htInfo.opMode) + { + psessionEntry->beaconParams.llgCoexist = false; + psessionEntry->beaconParams.ht20Coexist = false; + } + + } + } + + //protection related factors other than HT operating mode. Applies to 2.4 GHZ as well as 5 GHZ. + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + psessionEntry->beaconParams.fRIFSMode = + ( tANI_U8 ) htInfo.rifsMode; + psessionEntry->beaconParams.llnNonGFCoexist = + ( tANI_U8 )htInfo.nonGFDevicesPresent; + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = + ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport; + } +} + + +/** ------------------------------------------------------------- +\fn limDecideStaProtection +\brief Decides protection related settings on Sta while processing beacon. +\param tpAniSirGlobal pMac +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +void +limDecideStaProtection(tpAniSirGlobal pMac, + tpSchBeaconStruct pBeaconStruct, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + tANI_U32 phyMode = WNI_CFG_PHY_MODE_NONE; + + limGetRfBand(pMac, &rfBand, psessionEntry); + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if(SIR_BAND_5_GHZ == rfBand) + { + //we are HT capable. + if((true == psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + //we are HT capable, AP's HT OPMode is mixed / overlap legacy ==> need protection from 11A. + if((eSIR_HT_OP_MODE_MIXED == pBeaconStruct->HTInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBeaconStruct->HTInfo.opMode)) + { + limEnable11aProtection(pMac, true, false, pBeaconParams,psessionEntry); + } + //we are HT capable, AP's HT OPMode is HT20 ==> disable protection from 11A if enabled. enabled + //protection from HT20 if needed. + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT== pBeaconStruct->HTInfo.opMode) + { + limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry); + limEnableHT20Protection(pMac, true, false, pBeaconParams,psessionEntry); + } + else if(eSIR_HT_OP_MODE_PURE == pBeaconStruct->HTInfo.opMode) + { + limEnable11aProtection(pMac, false, false, pBeaconParams,psessionEntry); + limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry); + } + } + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + /* spec 7.3.2.13 + * UseProtection will be set when nonERP STA is associated. + * NonERPPresent bit will be set when: + * --nonERP Sta is associated OR + * --nonERP Sta exists in overlapping BSS + * when useProtection is not set then protection from nonERP stations is optional. + */ + + if (phyMode != WNI_CFG_PHY_MODE_11B) + { + if (pBeaconStruct->erpPresent && + (pBeaconStruct->erpIEInfo.useProtection || + pBeaconStruct->erpIEInfo.nonErpPresent)) + { + limEnable11gProtection(pMac, true, false, pBeaconParams, psessionEntry); + } + //AP has no 11b station associated. + else + { + //disable protection from 11b station + limEnable11gProtection(pMac, false, false, pBeaconParams, psessionEntry); + } + } + + //following code block is only for HT station. + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + //AP has at least one 11G station associated. + if(((eSIR_HT_OP_MODE_MIXED == htInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == htInfo.opMode))&& + (!psessionEntry->beaconParams.llbCoexist)) + { + limEnableHtProtectionFrom11g(pMac, true, false, pBeaconParams,psessionEntry); + + } + + //no HT operating mode change ==> no change in protection settings except for MIXED_MODE/Legacy Mode. + //in Mixed mode/legacy Mode even if there is no change in HT operating mode, there might be change in 11bCoexist + //or 11gCoexist. that is why this check is being done after mixed/legacy mode check. + if ( pMac->lim.gHTOperMode != ( tSirMacHTOperatingMode )htInfo.opMode ) + { + pMac->lim.gHTOperMode = ( tSirMacHTOperatingMode )htInfo.opMode; + + //AP has only HT stations associated and at least one station is HT 20 + //disable protection from any non-HT devices. + //decision for disabling protection from 11b has already been taken above. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == htInfo.opMode) + { + //Disable protection from 11G station. + limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry); + + limEnableHT20Protection(pMac, true, false, pBeaconParams,psessionEntry); + } + //Disable protection from non-HT and HT20 devices. + //decision for disabling protection from 11b has already been taken above. + else if(eSIR_HT_OP_MODE_PURE == htInfo.opMode) + { + limEnableHtProtectionFrom11g(pMac, false, false, pBeaconParams,psessionEntry); + limEnableHT20Protection(pMac, false, false, pBeaconParams,psessionEntry); + + } + } + } + } + + //following code block is only for HT station. ( 2.4 GHZ as well as 5 GHZ) + if((psessionEntry->htCapability) && + (pBeaconStruct->HTInfo.present)) + { + tDot11fIEHTInfo htInfo = pBeaconStruct->HTInfo; + //Check for changes in protection related factors other than HT operating mode. + //Check for changes in RIFS mode, nonGFDevicesPresent, lsigTXOPProtectionFullSupport. + if ( psessionEntry->beaconParams.fRIFSMode != + ( tANI_U8 ) htInfo.rifsMode ) + { + pBeaconParams->fRIFSMode = + psessionEntry->beaconParams.fRIFSMode = + ( tANI_U8 ) htInfo.rifsMode; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + + if ( psessionEntry->beaconParams.llnNonGFCoexist != + htInfo.nonGFDevicesPresent ) + { + pBeaconParams->llnNonGFCoexist = + psessionEntry->beaconParams.llnNonGFCoexist = + ( tANI_U8 )htInfo.nonGFDevicesPresent; + pBeaconParams->paramChangeBitmap |= + PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + + if ( psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport != + ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport ) + { + pBeaconParams->fLsigTXOPProtectionFullSupport = + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = + ( tANI_U8 )htInfo.lsigTXOPProtectionFullSupport; + pBeaconParams->paramChangeBitmap |= + PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + + // For Station just update the global lim variable, no need to send message to HAL + // Station already taking care of HT OPR Mode=01, meaning AP is seeing legacy + //stations in overlapping BSS. + if ( psessionEntry->beaconParams.gHTObssMode != ( tANI_U8 )htInfo.obssNonHTStaPresent ) + psessionEntry->beaconParams.gHTObssMode = ( tANI_U8 )htInfo.obssNonHTStaPresent ; + + } +} + + +/** + * limProcessChannelSwitchTimeout() + * + *FUNCTION: + * This function is invoked when Channel Switch Timer expires at + * the STA. Now, STA must stop traffic, and then change/disable + * primary or secondary channel. + * + * + *NOTE: + * @param pMac - Pointer to Global MAC structure + * @return None + */ +void limProcessChannelSwitchTimeout(tpAniSirGlobal pMac) +{ + tpPESession psessionEntry = NULL; + tANI_U8 channel; // This is received and stored from channelSwitch Action frame + + if ((psessionEntry = peFindSessionBySessionId(pMac, + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId))== NULL) { + limLog(pMac, LOGW,FL("Session Does not exist for given sessionID")); + return; + } + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + { + PELOGW(limLog(pMac, LOGW, "Channel switch can be done only in STA role, Current Role = %d", psessionEntry->limSystemRole);) + return; + } + if (psessionEntry->gLimSpecMgmt.dot11hChanSwState != + eLIM_11H_CHANSW_RUNNING) { + limLog(pMac, LOGW, + FL("Channel switch timer should not have been running in state %d"), + psessionEntry->gLimSpecMgmt.dot11hChanSwState); + return; + } + channel = psessionEntry->gLimChannelSwitch.primaryChannel; + + /* + * This potentially can create issues if the function tries to set + * channel while device is in power-save, hence putting an extra check + * to verify if the device is in power-save or not + */ + if(!limIsSystemInActiveState(pMac)) + { + PELOGW(limLog(pMac, LOGW, FL("Device is not in active state, cannot switch channel"));) + return; + } + + // Restore Channel Switch parameters to default + psessionEntry->gLimChannelSwitch.switchTimeoutValue = 0; + + /* Channel-switch timeout has occurred. reset the state */ + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_END; + + /* + * If Lim allows Switch channel on same channel on which preauth + * is going on then LIM will not post resume link(WDA_FINISH_SCAN) + * during preauth rsp handling hence firmware may crash on ENTER/ + * EXIT BMPS request. + */ + if(pMac->ft.ftPEContext.pFTPreAuthReq) + { + limLog(pMac, LOGE, + FL("Avoid Switch Channel req during pre auth")); + return; + } + /* If link is already suspended mean some off + * channel operation or scan is in progress, Allowing + * Change channel here will lead to either Init Scan + * sent twice or missing Finish scan when change + * channel is completed, this may lead + * to driver in invalid state and crash. + */ + if (limIsLinkSuspended(pMac)) + { + limLog(pMac, LOGE, FL("Link is already suspended for " + "some other reason. Return here for sessionId:%d"), + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId); + return; + } + + /* Check if the AP is switching to a channel that we support. + * Else, just don't bother to switch. Indicate HDD to look for a + * better AP to associate + */ + if(!limIsChannelValidForChannelSwitch(pMac, channel)) + { + /* We need to restore pre-channelSwitch state on the STA */ + if(limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system")); + return; + } + + /* If the channel-list that AP is asking us to switch is invalid, + * then we cannot switch the channel. Just disassociate from AP. + * We will find a better AP !!! + */ + if ((psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)&& + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) { + limLog(pMac, LOGE, FL("Invalid channel!! Disconnect..")); + limTearDownLinkWithAp(pMac, + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId, + eSIR_MAC_UNSPEC_FAILURE_REASON); + } + return; + } + limCovertChannelScanType(pMac, psessionEntry->currentOperChannel, false); + pMac->lim.dfschannelList.timeStamp[psessionEntry->currentOperChannel] = 0; + switch(psessionEntry->gLimChannelSwitch.state) + { + case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY: + case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY: + if ( isLimSessionOffChannel(pMac, + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId) ) + { + limSuspendLink(pMac, + eSIR_DONT_CHECK_LINK_TRAFFIC_BEFORE_SCAN, + limProcessChannelSwitchSuspendLink, + (tANI_U32*)psessionEntry ); + } + else + { + limProcessChannelSwitchSuspendLink(pMac, + eHAL_STATUS_SUCCESS, + (tANI_U32*)psessionEntry); + } + break; + + case eLIM_CHANNEL_SWITCH_SECONDARY_ONLY: + PELOGW(limLog(pMac, LOGW, FL("CHANNEL_SWITCH_SECONDARY_ONLY "));) + limSwitchPrimarySecondaryChannel(pMac, psessionEntry, + psessionEntry->currentOperChannel, + psessionEntry->gLimChannelSwitch.secondarySubBand); + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE; + break; + case eLIM_CHANNEL_SWITCH_IDLE: + default: + PELOGE(limLog(pMac, LOGE, FL("incorrect state "));) + if(limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system")); + } + return; /* Please note, this is 'return' and not 'break' */ + } +} + +/** + * limUpdateChannelSwitch() + * + *FUNCTION: + * This function is invoked whenever Station receives + * either 802.11h channel switch IE or airgo proprietary + * channel switch IE. + * + *NOTE: + * @param pMac - Pointer to Global MAC structure + * @return tpSirProbeRespBeacon - Pointer to Beacon/Probe Rsp + * @param psessionentry + */ +void +limUpdateChannelSwitch(struct sAniSirGlobal *pMac, tpSirProbeRespBeacon pBeacon, tpPESession psessionEntry) +{ + + tANI_U16 beaconPeriod; + tChannelSwitchPropIEStruct *pPropChnlSwitch; + tDot11fIEChanSwitchAnn *pChnlSwitch; +#ifdef WLAN_FEATURE_11AC + tDot11fIEWiderBWChanSwitchAnn *pWiderChnlSwitch; +#endif + + beaconPeriod = psessionEntry->beaconParams.beaconInterval; + + /* STA either received proprietary channel switch IE or 802.11h + * standard channel switch IE. + */ + if (pBeacon->propIEinfo.propChannelSwitchPresent) + { + pPropChnlSwitch = &(pBeacon->propIEinfo.channelSwitch); + + /* Add logic to determine which change this is: */ + /* primary, secondary, both. For now assume both. */ + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.primaryChannel = pPropChnlSwitch->primaryChannel; + psessionEntry->gLimChannelSwitch.secondarySubBand = (ePhyChanBondState)pPropChnlSwitch->subBand; + psessionEntry->gLimChannelSwitch.switchCount = pPropChnlSwitch->channelSwitchCount; + psessionEntry->gLimChannelSwitch.switchTimeoutValue = + SYS_MS_TO_TICKS(beaconPeriod)* (pPropChnlSwitch->channelSwitchCount); + psessionEntry->gLimChannelSwitch.switchMode = pPropChnlSwitch->mode; + } + else + { + pChnlSwitch = &(pBeacon->channelSwitchIE); + psessionEntry->gLimChannelSwitch.primaryChannel = pChnlSwitch->newChannel; + psessionEntry->gLimChannelSwitch.switchCount = pChnlSwitch->switchCount; + psessionEntry->gLimChannelSwitch.switchTimeoutValue = + SYS_MS_TO_TICKS(beaconPeriod)* (pChnlSwitch->switchCount); + psessionEntry->gLimChannelSwitch.switchMode = pChnlSwitch->switchMode; +#ifdef WLAN_FEATURE_11AC + pWiderChnlSwitch = &(pBeacon->WiderBWChanSwitchAnn); + if(pBeacon->WiderBWChanSwitchAnnPresent) + { + psessionEntry->gLimWiderBWChannelSwitch.newChanWidth = pWiderChnlSwitch->newChanWidth; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0 = pWiderChnlSwitch->newCenterChanFreq0; + psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1 = pWiderChnlSwitch->newCenterChanFreq1; + } +#endif + + /* Only primary channel switch element is present */ + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_ONLY; + psessionEntry->gLimChannelSwitch.secondarySubBand = PHY_SINGLE_CHANNEL_CENTERED; + + /* Do not bother to look and operate on extended channel switch element + * if our own channel-bonding state is not enabled + */ + if (psessionEntry->htSupportedChannelWidthSet) + { + if (pBeacon->extChannelSwitchPresent) + { + if ((pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = pBeacon->extChannelSwitchIE.secondaryChannelOffset; + } +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability && pBeacon->WiderBWChanSwitchAnnPresent) + { + if (pWiderChnlSwitch->newChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + if(pBeacon->extChannelSwitchPresent) + { + if ((pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_LOW_PRIMARY) || + (pBeacon->extChannelSwitchIE.secondaryChannelOffset == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)) + { + psessionEntry->gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY; + psessionEntry->gLimChannelSwitch.secondarySubBand = limGet11ACPhyCBState(pMac, + psessionEntry->gLimChannelSwitch.primaryChannel, + pBeacon->extChannelSwitchIE.secondaryChannelOffset, + pWiderChnlSwitch->newCenterChanFreq0, + psessionEntry); + } + } + } + } +#endif + } + } + } + + + if (eSIR_SUCCESS != limStartChannelSwitch(pMac, psessionEntry)) + { + PELOGW(limLog(pMac, LOGW, FL("Could not start Channel Switch"));) + } + + limLog(pMac, LOGW, + FL("session %d primary chl %d, subband %d, count %d (%d ticks) "), + psessionEntry->peSessionId, + psessionEntry->gLimChannelSwitch.primaryChannel, + psessionEntry->gLimChannelSwitch.secondarySubBand, + psessionEntry->gLimChannelSwitch.switchCount, + psessionEntry->gLimChannelSwitch.switchTimeoutValue); + return; +} + +/** + * limCancelDot11hChannelSwitch + * + *FUNCTION: + * This function is called when STA does not send updated channel-swith IE + * after indicating channel-switch start. This will cancel the channel-swith + * timer which is already running. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +void limCancelDot11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + + PELOGW(limLog(pMac, LOGW, FL("Received a beacon without channel switch IE"));) + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_CHANNEL_SWITCH_TIMER)); + + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimChannelSwitchTimer) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed!"));) + } + + /* We need to restore pre-channelSwitch state on the STA */ + if (limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("LIM: Could not restore pre-channelSwitch (11h) state, resetting the system"));) + + } +} + +/**---------------------------------------------- +\fn limCancelDot11hQuiet +\brief Cancel the quieting on Station if latest + beacon doesn't contain quiet IE in it. + +\param pMac +\return NONE +-----------------------------------------------*/ +void limCancelDot11hQuiet(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + + if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_BEGIN) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed"));) + } + } + else if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, psessionEntry->peSessionId, eLIM_QUIET_BSS_TIMER)); + if (tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer) != TX_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("tx_timer_deactivate failed"));) + } + /** + * If the channel switch is already running in silent mode, dont resume the + * transmission. Channel switch timer when timeout, transmission will be resumed. + */ + if(!((psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) && + (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT))) + { + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + limRestorePreQuietState(pMac, psessionEntry); + } + } + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; +} + +/** + * limProcessQuietTimeout + * + * FUNCTION: + * This function is active only on the STA. + * Handles SIR_LIM_QUIET_TIMEOUT + * + * LOGIC: + * This timeout can occur under only one circumstance: + * + * 1) When gLimQuietState = eLIM_QUIET_BEGIN + * This indicates that the timeout "interval" has + * expired. This is a trigger for the STA to now + * shut-off Tx/Rx for the specified gLimQuietDuration + * -> The TIMER object gLimQuietBssTimer is + * activated + * -> With timeout = gLimQuietDuration + * -> gLimQuietState is set to eLIM_QUIET_RUNNING + * + * ASSUMPTIONS: + * Using two TIMER objects - + * gLimQuietTimer & gLimQuietBssTimer + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +void limProcessQuietTimeout(tpAniSirGlobal pMac) +{ + //fetch the sessionEntry based on the sessionId + //priority - MEDIUM + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimQuietTimer.sessionId))== NULL) + { + limLog(pMac, LOGE,FL("Session Does not exist for given sessionID")); + return; + } + + limLog(pMac, LOG1, FL("quietState = %d"), psessionEntry->gLimSpecMgmt.quietState); + switch( psessionEntry->gLimSpecMgmt.quietState ) + { + case eLIM_QUIET_BEGIN: + // Time to Stop data traffic for quietDuration + //limDeactivateAndChangeTimer(pMac, eLIM_QUIET_BSS_TIMER); + if (TX_SUCCESS != + tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietBssTimer)) + { + limLog( pMac, LOGE, + FL("Unable to de-activate gLimQuietBssTimer! Will attempt to activate anyway...")); + } + + // gLimQuietDuration appears to be in units of ticks + // Use it as is + if (TX_SUCCESS != + tx_timer_change( &pMac->lim.limTimers.gLimQuietBssTimer, + psessionEntry->gLimSpecMgmt.quietDuration, + 0)) + { + limLog( pMac, LOGE, + FL("Unable to change gLimQuietBssTimer! Will still attempt to activate anyway...")); + } + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, pMac->lim.limTimers.gLimQuietTimer.sessionId, eLIM_QUIET_BSS_TIMER)); +#ifdef GEN6_TODO + /* revisit this piece of code to assign the appropriate sessionId below + * priority - HIGH + */ + pMac->lim.limTimers.gLimQuietBssTimer.sessionId = sessionId; +#endif + if( TX_SUCCESS != + tx_timer_activate( &pMac->lim.limTimers.gLimQuietBssTimer )) + { + limLog( pMac, LOGW, + FL("Unable to activate gLimQuietBssTimer! The STA will be unable to honor Quiet BSS...")); + } + else + { + // Transition to eLIM_QUIET_RUNNING + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_RUNNING; + + /* If we have sta bk scan triggered and trigger bk scan actually started successfully, */ + /* print message, otherwise, stop data traffic and stay quiet */ + if( pMac->lim.gLimTriggerBackgroundScanDuringQuietBss && + (eSIR_TRUE == (glimTriggerBackgroundScanDuringQuietBss_Status = limTriggerBackgroundScanDuringQuietBss( pMac ))) ) + { + limLog( pMac, LOG2, + FL("Attempting to trigger a background scan...")); + } + else + { + // Shut-off Tx/Rx for gLimSpecMgmt.quietDuration + /* freeze the transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_STOP_TX); + + limLog( pMac, LOG2, + FL("Quiet BSS: STA shutting down for %d ticks"), + psessionEntry->gLimSpecMgmt.quietDuration ); + } + } + break; + + case eLIM_QUIET_RUNNING: + case eLIM_QUIET_INIT: + case eLIM_QUIET_END: + default: + // + // As of now, nothing to be done + // + break; + } +} + +/** + * limProcessQuietBssTimeout + * + * FUNCTION: + * This function is active on the AP and STA. + * Handles SIR_LIM_QUIET_BSS_TIMEOUT + * + * LOGIC: + * On the AP - + * When the SIR_LIM_QUIET_BSS_TIMEOUT is triggered, it is + * an indication for the AP to START sending out the + * Quiet BSS IE. + * If 802.11H is enabled, the Quiet BSS IE is sent as per + * the 11H spec + * If 802.11H is not enabled, the Quiet BSS IE is sent as + * a Proprietary IE. This will be understood by all the + * TITAN STA's + * Transitioning gLimQuietState to eLIM_QUIET_BEGIN will + * initiate the SCH to include the Quiet BSS IE in all + * its subsequent Beacons/PR's. + * The Quiet BSS IE will be included in all the Beacons + * & PR's until the next DTIM period + * + * On the STA - + * When gLimQuietState = eLIM_QUIET_RUNNING + * This indicates that the STA was successfully shut-off + * for the specified gLimQuietDuration. This is a trigger + * for the STA to now resume data traffic. + * -> gLimQuietState is set to eLIM_QUIET_INIT + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +void limProcessQuietBssTimeout( tpAniSirGlobal pMac ) +{ + tpPESession psessionEntry; + + if((psessionEntry = peFindSessionBySessionId(pMac, pMac->lim.limTimers.gLimQuietBssTimer.sessionId))== NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + limLog(pMac, LOG1, FL("quietState = %d"), psessionEntry->gLimSpecMgmt.quietState); + if (eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + } + else + { + // eLIM_STA_ROLE + switch( psessionEntry->gLimSpecMgmt.quietState ) + { + case eLIM_QUIET_RUNNING: + // Transition to eLIM_QUIET_INIT + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + + if( !pMac->lim.gLimTriggerBackgroundScanDuringQuietBss || (glimTriggerBackgroundScanDuringQuietBss_Status == eSIR_FALSE) ) + { + // Resume data traffic only if channel switch is not running in silent mode. + if (!((psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) && + (psessionEntry->gLimChannelSwitch.switchMode == eSIR_CHANSW_MODE_SILENT))) + { + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + limRestorePreQuietState(pMac, psessionEntry); + } + + /* Reset status flag */ + if(glimTriggerBackgroundScanDuringQuietBss_Status == eSIR_FALSE) + glimTriggerBackgroundScanDuringQuietBss_Status = eSIR_TRUE; + + limLog( pMac, LOG2, + FL("Quiet BSS: Resuming traffic...")); + } + else + { + // + // Nothing specific to be done in this case + // A background scan that was triggered during + // SIR_LIM_QUIET_TIMEOUT will complete on its own + // + limLog( pMac, LOG2, + FL("Background scan should be complete now...")); + } + break; + + case eLIM_QUIET_INIT: + case eLIM_QUIET_BEGIN: + case eLIM_QUIET_END: + PELOG2(limLog(pMac, LOG2, FL("Quiet state not in RUNNING"));) + /* If the quiet period has ended, then resume the frame transmission */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + limRestorePreQuietState(pMac, psessionEntry); + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + break; + + default: + // + // As of now, nothing to be done + // + break; + } + } +} +/** + * limProcessWPSOverlapTimeout + * + * FUNCTION: This function call limWPSPBCTimeout() to clean WPS PBC probe request entries + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac - Pointer to Global MAC structure + * + * @return None + */ +#if 0 +void limProcessWPSOverlapTimeout(tpAniSirGlobal pMac) +{ + + tpPESession psessionEntry; + tANI_U32 sessionId; + + if (tx_timer_activate(&pMac->lim.limTimers.gLimWPSOverlapTimerObj.gLimWPSOverlapTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("tx_timer_activate failed")); + } + + sessionId = pMac->lim.limTimers.gLimWPSOverlapTimerObj.sessionId; + + PELOGE(limLog(pMac, LOGE, FL("WPS overlap timeout, sessionId=%d"), sessionId);) + + if((psessionEntry = peFindSessionBySessionId(pMac, sessionId)) == NULL) + { + PELOGE(limLog(pMac, LOGP,FL("Session Does not exist for given sessionID"));) + return; + } + + limWPSPBCTimeout(pMac, psessionEntry); +} +#endif + +/**---------------------------------------------- +\fn limStartQuietTimer +\brief Starts the quiet timer. + +\param pMac +\return NONE +-----------------------------------------------*/ +void limStartQuietTimer(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tpPESession psessionEntry; + psessionEntry = peFindSessionBySessionId(pMac, sessionId); + + if(psessionEntry == NULL) { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + // First, de-activate Timer, if its already active + limCancelDot11hQuiet(pMac, psessionEntry); + + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, sessionId, eLIM_QUIET_TIMER)); + if( TX_SUCCESS != tx_timer_deactivate(&pMac->lim.limTimers.gLimQuietTimer)) + { + limLog( pMac, LOGE, + FL( "Unable to deactivate gLimQuietTimer! Will still attempt to re-activate anyway..." )); + } + + // Set the NEW timeout value, in ticks + if( TX_SUCCESS != tx_timer_change( &pMac->lim.limTimers.gLimQuietTimer, + SYS_MS_TO_TICKS(psessionEntry->gLimSpecMgmt.quietTimeoutValue), 0)) + { + limLog( pMac, LOGE, + FL( "Unable to change gLimQuietTimer! Will still attempt to re-activate anyway..." )); + } + + pMac->lim.limTimers.gLimQuietTimer.sessionId = sessionId; + if( TX_SUCCESS != tx_timer_activate(&pMac->lim.limTimers.gLimQuietTimer)) + { + limLog( pMac, LOGE, + FL("Unable to activate gLimQuietTimer! STA cannot honor Quiet BSS!")); + limRestorePreQuietState(pMac, psessionEntry); + + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + return; + } +} + + +/** ------------------------------------------------------------------------ **/ +/** + * keep track of the number of ANI peers associated in the BSS + * For the first and last ANI peer, we have to update EDCA params as needed + * + * When the first ANI peer joins the BSS, we notify SCH + * When the last ANI peer leaves the BSS, we notfiy SCH + */ +void +limUtilCountStaAdd( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpPESession psessionEntry) +{ + + if ((! pSta) || (! pSta->valid) || (! pSta->aniPeer) || (pSta->fAniCount)) + return; + + pSta->fAniCount = 1; + + if (pMac->lim.gLimNumOfAniSTAs++ != 0) + return; + + // get here only if this is the first ANI peer in the BSS + schEdcaProfileUpdate(pMac, psessionEntry); +} + +void +limUtilCountStaDel( + tpAniSirGlobal pMac, + tpDphHashNode pSta, + tpPESession psessionEntry) +{ + + if ((pSta == NULL) || (pSta->aniPeer == eHAL_CLEAR) || (! pSta->fAniCount)) + return; + + /* Only if sta is invalid and the validInDummyState bit is set to 1, + * then go ahead and update the count and profiles. This ensures + * that the "number of ani station" count is properly incremented/decremented. + */ + if (pSta->valid == 1) + return; + + pSta->fAniCount = 0; + + if (pMac->lim.gLimNumOfAniSTAs <= 0) + { + limLog(pMac, LOGE, FL("CountStaDel: ignoring Delete Req when AniPeer count is %d"), + pMac->lim.gLimNumOfAniSTAs); + return; + } + + pMac->lim.gLimNumOfAniSTAs--; + + if (pMac->lim.gLimNumOfAniSTAs != 0) + return; + + // get here only if this is the last ANI peer in the BSS + schEdcaProfileUpdate(pMac, psessionEntry); +} + +/** + * limSwitchChannelCback() + * + *FUNCTION: + * This is the callback function registered while requesting to switch channel + * after AP indicates a channel switch for spectrum management (11h). + * + *NOTE: + * @param pMac Pointer to Global MAC structure + * @param status Status of channel switch request + * @param data User data + * @param psessionEntry Session information + * @return NONE + */ +void limSwitchChannelCback(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry) +{ + tSirMsgQ mmhMsg = {0}; + tSirSmeSwitchChannelInd *pSirSmeSwitchChInd; + + psessionEntry->currentOperChannel = psessionEntry->currentReqChannel; + + /* We need to restore pre-channelSwitch state on the STA */ + if (limRestorePreChannelSwitchState(pMac, psessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restore pre-channelSwitch (11h) state, resetting the system")); + return; + } + + mmhMsg.type = eWNI_SME_SWITCH_CHL_REQ; + pSirSmeSwitchChInd = vos_mem_malloc(sizeof(tSirSmeSwitchChannelInd)); + if ( NULL == pSirSmeSwitchChInd ) + { + limLog(pMac, LOGP, FL("Failed to allocate buffer for buffer descriptor")); + return; + } + + pSirSmeSwitchChInd->messageType = eWNI_SME_SWITCH_CHL_REQ; + pSirSmeSwitchChInd->length = sizeof(tSirSmeSwitchChannelInd); + pSirSmeSwitchChInd->newChannelId = psessionEntry->gLimChannelSwitch.primaryChannel; + pSirSmeSwitchChInd->sessionId = psessionEntry->smeSessionId; + //BSS ID + vos_mem_copy( pSirSmeSwitchChInd->bssId, psessionEntry->bssId, sizeof(tSirMacAddr)); + mmhMsg.bodyptr = pSirSmeSwitchChInd; + mmhMsg.bodyval = 0; + + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, psessionEntry->peSessionId, + mmhMsg.type)); + SysProcessMmhMsg(pMac, &mmhMsg); +} + +/** + * limSwitchPrimaryChannel() + * + *FUNCTION: + * This function changes the current operating channel + * and sets the new new channel ID in WNI_CFG_CURRENT_CHANNEL. + * + *NOTE: + * @param pMac Pointer to Global MAC structure + * @param newChannel new chnannel ID + * @return NONE + */ +void limSwitchPrimaryChannel(tpAniSirGlobal pMac, tANI_U8 newChannel,tpPESession psessionEntry) +{ +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + + limLog(pMac, LOG1, FL(" old chnl %d --> new chnl %d "), + psessionEntry->currentOperChannel, newChannel); + psessionEntry->currentReqChannel = newChannel; + psessionEntry->limRFBand = limGetRFBand(newChannel); + + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + + pMac->lim.gpchangeChannelCallback = limSwitchChannelCback; + pMac->lim.gpchangeChannelData = NULL; + +#if defined WLAN_FEATURE_VOWIFI + limSendSwitchChnlParams(pMac, newChannel, PHY_SINGLE_CHANNEL_CENTERED, + psessionEntry->maxTxPower, psessionEntry->peSessionId); +#else + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) + { + limLog( pMac, LOGP, FL( "Unable to read Local Power Constraint from cfg" )); + return; + } + limSendSwitchChnlParams(pMac, newChannel, PHY_SINGLE_CHANNEL_CENTERED, + (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId); +#endif + return; +} + +/** + * limSwitchPrimarySecondaryChannel() + * + *FUNCTION: + * This function changes the primary and secondary channel. + * If 11h is enabled and user provides a "new channel ID" + * that is different from the current operating channel, + * then we must set this new channel in WNI_CFG_CURRENT_CHANNEL, + * assign notify LIM of such change. + * + *NOTE: + * @param pMac Pointer to Global MAC structure + * @param newChannel New chnannel ID (or current channel ID) + * @param subband CB secondary info: + * - eANI_CB_SECONDARY_NONE + * - eANI_CB_SECONDARY_UP + * - eANI_CB_SECONDARY_DOWN + * @return NONE + */ +void limSwitchPrimarySecondaryChannel(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 newChannel, ePhyChanBondState subband) +{ +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + +#if !defined WLAN_FEATURE_VOWIFI + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" )); + return; + } +#endif + /* Assign the callback to resume TX once channel is changed. + */ + psessionEntry->currentReqChannel = newChannel; + psessionEntry->limRFBand = limGetRFBand(newChannel); + + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + + pMac->lim.gpchangeChannelCallback = limSwitchChannelCback; + pMac->lim.gpchangeChannelData = NULL; + +#if defined WLAN_FEATURE_VOWIFI + limSendSwitchChnlParams(pMac, newChannel, subband, psessionEntry->maxTxPower, psessionEntry->peSessionId); +#else + limSendSwitchChnlParams(pMac, newChannel, subband, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId); +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_CHANNEL_SWITCH_ANOUNCEMENT, + psessionEntry, eSIR_SUCCESS, LIM_SWITCH_CHANNEL_OPERATION); +#endif + + // Store the new primary and secondary channel in session entries if different + if (psessionEntry->currentOperChannel != newChannel) + { + limLog(pMac, LOGW, + FL("switch old chnl %d --> new chnl %d "), + psessionEntry->currentOperChannel, newChannel); + psessionEntry->currentOperChannel = newChannel; + } + if (psessionEntry->htSecondaryChannelOffset != subband) + { + limLog(pMac, LOGW, + FL("switch old sec chnl %d --> new sec chnl %d "), + psessionEntry->htSecondaryChannelOffset, subband); + psessionEntry->htSecondaryChannelOffset = subband; + if (psessionEntry->htSecondaryChannelOffset == PHY_SINGLE_CHANNEL_CENTERED) + { + psessionEntry->htSupportedChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + } + else + { + psessionEntry->htSupportedChannelWidthSet = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + } + psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet; + } + + return; +} + + +/** + * limActiveScanAllowed() + * + *FUNCTION: + * Checks if active scans are permitted on the given channel + * + *LOGIC: + * The config variable SCAN_CONTROL_LIST contains pairs of (channelNum, activeScanAllowed) + * Need to check if the channelNum matches, then depending on the corresponding + * scan flag, return true (for activeScanAllowed==1) or false (otherwise). + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param channelNum channel number + * @return None + */ + +tANI_U8 limActiveScanAllowed( + tpAniSirGlobal pMac, + tANI_U8 channelNum) +{ + tANI_U32 i; + tANI_U8 channelPair[WNI_CFG_SCAN_CONTROL_LIST_LEN]; + tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN; + if (wlan_cfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, channelPair, &len) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to get scan control list"));) + return false; + } + + if (len > WNI_CFG_SCAN_CONTROL_LIST_LEN) + { + limLog(pMac, LOGE, FL("Invalid scan control list length:%d"), + len); + return false; + } + + for (i=0; (i+1) < len; i+=2) + { + if (channelPair[i] == channelNum) + return ((channelPair[i+1] == eSIR_ACTIVE_SCAN) ? true : false); + } + return false; +} + +/** + * limTriggerBackgroundScanDuringQuietBss() + * + *FUNCTION: + * This function is applicable to the STA only. + * This function is called by limProcessQuietTimeout(), + * when it is time to honor the Quiet BSS IE from the AP. + * + *LOGIC: + * If 11H is enabled: + * We cannot trigger a background scan. The STA needs to + * shut-off Tx/Rx. + * If 11 is not enabled: + * Determine if the next channel that we are going to + * scan is NOT the same channel (or not) on which the + * Quiet BSS was requested. + * If yes, then we cannot trigger a background scan on + * this channel. Return with a false. + * If no, then trigger a background scan. Return with + * a true. + * + *ASSUMPTIONS: + * + *NOTE: + * This API is redundant if the existing API, + * limTriggerBackgroundScan(), were to return a valid + * response instead of returning void. + * If possible, try to revisit this API + * + * @param pMac Pointer to Global MAC structure + * @return eSIR_TRUE, if a background scan was attempted + * eSIR_FALSE, if not + */ +tAniBool limTriggerBackgroundScanDuringQuietBss( tpAniSirGlobal pMac ) +{ + tAniBool bScanTriggered = eSIR_FALSE; + + + + //TBD-RAJESH HOW TO GET sessionEntry????? + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return bScanTriggered; + + if( !psessionEntry->lim11hEnable ) + { + tSirMacChanNum bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN]; + tANI_U32 len = WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN; + + // Determine the next scan channel + + // Get background scan channel list from CFG + if( eSIR_SUCCESS == wlan_cfgGetStr( pMac, + WNI_CFG_BG_SCAN_CHANNEL_LIST, + (tANI_U8 *) bgScanChannelList, + (tANI_U32 *) &len )) + { + // Ensure that we do not go off scanning on the same + // channel on which the Quiet BSS was requested + if( psessionEntry->currentOperChannel!= + bgScanChannelList[pMac->lim.gLimBackgroundScanChannelId] ) + { + // For now, try and attempt a background scan. It will + // be ideal if this API actually returns a success or + // failure instead of having a void return type + limTriggerBackgroundScan( pMac ); + + bScanTriggered = eSIR_TRUE; + } + else + { + limLog( pMac, LOGW, + FL("The next SCAN channel is the current operating channel on which a Quiet BSS is requested.! A background scan will not be triggered during this Quiet BSS period...")); + } + } + else + { + limLog( pMac, LOGW, + FL("Unable to retrieve WNI_CFG_VALID_CHANNEL_LIST from CFG! A background scan will not be triggered during this Quiet BSS period...")); + } + } + return bScanTriggered; +} + + +/** + * limGetHTCapability() + * + *FUNCTION: + * A utility function that returns the "current HT capability state" for the HT + * capability of interest (as requested in the API) + * + *LOGIC: + * This routine will return with the "current" setting of a requested HT + * capability. This state info could be retrieved from - + * a) CFG (for static entries) + * b) Run time info + * - Dynamic state maintained by LIM + * - Configured at radio init time by SME + * + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param htCap The HT capability being queried + * @return tANI_U8 The current state of the requested HT capability is returned in a + * tANI_U8 variable + */ + +tANI_U8 limGetHTCapability( tpAniSirGlobal pMac, + tANI_U32 htCap, tpPESession psessionEntry) +{ +tANI_U8 retVal = 0; +tANI_U8 *ptr; +tANI_U32 cfgValue; +tSirMacHTCapabilityInfo macHTCapabilityInfo = {0}; +tSirMacExtendedHTCapabilityInfo macExtHTCapabilityInfo = {0}; +tSirMacTxBFCapabilityInfo macTxBFCapabilityInfo = {0}; +tSirMacASCapabilityInfo macASCapabilityInfo = {0}; + + // + // Determine which CFG to read from. Not ALL of the HT + // related CFG's need to be read each time this API is + // accessed + // + if( htCap >= eHT_ANTENNA_SELECTION && + htCap < eHT_SI_GRANULARITY ) + { + // Get Antenna Seletion HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_AS_CAP, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macASCapabilityInfo; + *((tANI_U8 *)ptr) = (tANI_U8) (cfgValue & 0xff); + } + else + { + if( htCap >= eHT_TX_BEAMFORMING && + htCap < eHT_ANTENNA_SELECTION ) + { + // Get Transmit Beam Forming HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_TX_BF_CAP, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macTxBFCapabilityInfo; + *((tANI_U32 *)ptr) = (tANI_U32) (cfgValue); + } + else + { + if( htCap >= eHT_PCO && + htCap < eHT_TX_BEAMFORMING ) + { + // Get Extended HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_EXT_HT_CAP_INFO, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macExtHTCapabilityInfo; + *((tANI_U16 *)ptr) = (tANI_U16) (cfgValue & 0xffff); + } + else + { + if( htCap < eHT_MAX_RX_AMPDU_FACTOR ) + { + // Get HT Capabilities + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_HT_CAP_INFO, &cfgValue )) + cfgValue = 0; + ptr = (tANI_U8 *) &macHTCapabilityInfo; + // CR 265282 MDM SoftAP 2.4PL: SoftAP boot up crash in 2.4 PL builds while same WLAN SU is working on 2.1 PL + *ptr++ = cfgValue & 0xff; + *ptr = (cfgValue >> 8) & 0xff; + } + } + } + } + + switch( htCap ) + { + case eHT_LSIG_TXOP_PROTECTION: + retVal = pMac->lim.gHTLsigTXOPProtection; + break; + + case eHT_STBC_CONTROL_FRAME: + retVal = (tANI_U8) macHTCapabilityInfo.stbcControlFrame; + break; + + case eHT_PSMP: + retVal = pMac->lim.gHTPSMPSupport; + break; + + case eHT_DSSS_CCK_MODE_40MHZ: + retVal = pMac->lim.gHTDsssCckRate40MHzSupport; + break; + + case eHT_MAX_AMSDU_LENGTH: + retVal = (tANI_U8) macHTCapabilityInfo.maximalAMSDUsize; + break; + + case eHT_DELAYED_BA: + retVal = (tANI_U8) macHTCapabilityInfo.delayedBA; + break; + + case eHT_RX_STBC: + retVal = (tANI_U8) macHTCapabilityInfo.rxSTBC; + break; + + case eHT_TX_STBC: + retVal = (tANI_U8) macHTCapabilityInfo.txSTBC; + break; + + case eHT_SHORT_GI_40MHZ: + retVal = (tANI_U8) macHTCapabilityInfo.shortGI40MHz; + break; + + case eHT_SHORT_GI_20MHZ: + retVal = (tANI_U8) macHTCapabilityInfo.shortGI20MHz; + break; + + case eHT_GREENFIELD: + retVal = (tANI_U8) macHTCapabilityInfo.greenField; + break; + + case eHT_MIMO_POWER_SAVE: + retVal = (tANI_U8) pMac->lim.gHTMIMOPSState; + break; + + case eHT_SUPPORTED_CHANNEL_WIDTH_SET: + retVal = (tANI_U8) psessionEntry->htSupportedChannelWidthSet; + break; + + case eHT_ADVANCED_CODING: + retVal = (tANI_U8) macHTCapabilityInfo.advCodingCap; + break; + + case eHT_MAX_RX_AMPDU_FACTOR: + retVal = pMac->lim.gHTMaxRxAMpduFactor; + break; + + case eHT_MPDU_DENSITY: + retVal = pMac->lim.gHTAMpduDensity; + break; + + case eHT_PCO: + retVal = (tANI_U8) macExtHTCapabilityInfo.pco; + break; + + case eHT_TRANSITION_TIME: + retVal = (tANI_U8) macExtHTCapabilityInfo.transitionTime; + break; + + case eHT_MCS_FEEDBACK: + retVal = (tANI_U8) macExtHTCapabilityInfo.mcsFeedback; + break; + + case eHT_TX_BEAMFORMING: + retVal = (tANI_U8) macTxBFCapabilityInfo.txBF; + break; + + case eHT_ANTENNA_SELECTION: + retVal = (tANI_U8) macASCapabilityInfo.antennaSelection; + break; + + case eHT_SI_GRANULARITY: + retVal = pMac->lim.gHTServiceIntervalGranularity; + break; + + case eHT_CONTROLLED_ACCESS: + retVal = pMac->lim.gHTControlledAccessOnly; + break; + + case eHT_RIFS_MODE: + retVal = psessionEntry->beaconParams.fRIFSMode; + break; + + case eHT_RECOMMENDED_TX_WIDTH_SET: + retVal = psessionEntry->htRecommendedTxWidthSet; + break; + + case eHT_EXTENSION_CHANNEL_OFFSET: + retVal = psessionEntry->htSecondaryChannelOffset; + break; + + case eHT_OP_MODE: + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ) + retVal = psessionEntry->htOperMode; + else + retVal = pMac->lim.gHTOperMode; + break; + + case eHT_BASIC_STBC_MCS: + retVal = pMac->lim.gHTSTBCBasicMCS; + break; + + case eHT_DUAL_CTS_PROTECTION: + retVal = pMac->lim.gHTDualCTSProtection; + break; + + case eHT_LSIG_TXOP_PROTECTION_FULL_SUPPORT: + retVal = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport; + break; + + case eHT_PCO_ACTIVE: + retVal = pMac->lim.gHTPCOActive; + break; + + case eHT_PCO_PHASE: + retVal = pMac->lim.gHTPCOPhase; + break; + + default: + break; + } + + return retVal; +} + +void limGetMyMacAddr(tpAniSirGlobal pMac, tANI_U8 *mac) +{ + vos_mem_copy( mac, pMac->lim.gLimMyMacAddr, sizeof(tSirMacAddr)); + return; +} + + + + +/** ------------------------------------------------------------- +\fn limEnable11aProtection +\brief based on config setting enables\disables 11a protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnable11aProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(NULL == psessionEntry) + { + PELOG3(limLog(pMac, LOG3, FL("psessionEntry is NULL"));) + return eSIR_FAILURE; + } + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if ((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + (!psessionEntry->cfgProtection.fromlla)) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from 11a is disabled"));) + return eSIR_SUCCESS; + } + } + + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + if(((eLIM_AP_ROLE == psessionEntry->limSystemRole)||(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole))&& + (true == psessionEntry->htCapability)) + { + if(overlap) + { + pMac->lim.gLimOverlap11aParams.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + psessionEntry->gLim11aParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.llaCoexist) + { + PELOG1(limLog(pMac, LOG1, FL(" => protection from 11A Enabled"));) + pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llaCoexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + pMac->lim.gLimOverlap11aParams.protectionEnabled = false; + + //We need to take care of HT OP mode iff we are HT AP. + if(psessionEntry->htCapability) + { + // no HT op mode change if any of the overlap protection enabled. + if(!(pMac->lim.gLimOverlap11aParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled)) + + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + if(psessionEntry->gLimHt20Params.protectionEnabled) + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + else + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11A stations. + psessionEntry->gLim11aParams.protectionEnabled = false; + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Check if any other non-HT protection enabled. + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + + //Change HT OP mode to 01 if any overlap protection enabled + if(pMac->lim.gLimOverlap11aParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled) + + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + if(!pMac->lim.gLimOverlap11aParams.protectionEnabled && + !psessionEntry->gLim11aParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11A Disabled"));) + pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED; + } + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11A Disabled"));) + pBeaconParams->llaCoexist = psessionEntry->beaconParams.llaCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llACOEXIST_CHANGED; + } + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnable11gProtection +\brief based on config setting enables\disables 11g protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ + +tSirRetStatus +limEnable11gProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.fromllb) + { + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if(!pMac->lim.cfgProtection.fromllb) + { + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled"));) + return eSIR_SUCCESS; + } + } + } + + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + psessionEntry->gLimOlbcParams.protectionEnabled = true; + PELOGE(limLog(pMac, LOGE, FL("protection from olbc is enabled"));) + if(true == psessionEntry->htCapability) + { + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) && + (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + } + //CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS + // This fixes issue of OBSS bit not set after 11b, 11g station leaves + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + //Not processing OBSS bit from other APs, as we are already taking care + //of Protection from overlapping BSS based on erp IE or useProtection bit + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry); + } + } + else + { + psessionEntry->gLim11bParams.protectionEnabled = true; + PELOGE(limLog(pMac, LOGE, FL("protection from 11b is enabled"));) + if(true == psessionEntry->htCapability) + { + if(eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + } + }else if ((eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) && + (true == psessionEntry->htCapability)) + { + if(overlap) + { + psessionEntry->gLimOlbcParams.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + } + //CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS + // This fixes issue of OBSS bit not set after 11b, 11g station leaves + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + //Not processing OBSS bit from other APs, as we are already taking care + //of Protection from overlapping BSS based on erp IE or useProtection bit + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry); + } + else + { + psessionEntry->gLim11bParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.llbCoexist) + { + PELOG1(limLog(pMac, LOG1, FL("=> 11G Protection Enabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llbCoexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + psessionEntry->gLimOlbcParams.protectionEnabled = false; + + //We need to take care of HT OP mode if we are HT AP. + if(psessionEntry->htCapability) + { + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + if(psessionEntry->gLimHt20Params.protectionEnabled){ + //Commenting out beacuse of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + else + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11B stations. + psessionEntry->gLim11bParams.protectionEnabled = false; + PELOGE(limLog(pMac, LOGE, FL("===> 11B Protection Disabled"));) + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11gParams.protectionEnabled) + { + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + PELOGE(limLog(pMac, LOGE, FL("===> 11G Protection Disabled"));) + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + PELOGE(limLog(pMac, LOGE, FL("===> 11G Protection Disabled"));) + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!psessionEntry->gLimOlbcParams.protectionEnabled && + !psessionEntry->gLim11bParams.protectionEnabled) + { + PELOGE(limLog(pMac, LOGE, FL("===> 11G Protection Disabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + psessionEntry->gLimOlbcParams.protectionEnabled = false; + + //We need to take care of HT OP mode iff we are HT AP. + if(psessionEntry->htCapability) + { + // no HT op mode change if any of the overlap protection enabled. + if(!(pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled)) + + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + if(psessionEntry->gLimHt20Params.protectionEnabled) + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + else + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11B stations. + psessionEntry->gLim11bParams.protectionEnabled = false; + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11gParams.protectionEnabled) + { + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled) + + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!psessionEntry->gLimOlbcParams.protectionEnabled && + !psessionEntry->gLim11bParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> 11G Protection Disabled"));) + pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; + } + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnableHtProtectionFrom11g +\brief based on cofig enables\disables protection from 11g. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHtProtectionFrom11g(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // protection from 11g is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && (!psessionEntry->cfgProtection.overlapFromllg)) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11g is disabled"));); + return eSIR_SUCCESS; + }else if ((psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) && (!pMac->lim.cfgProtection.overlapFromllg)) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("overlap protection from 11g is disabled"));); + return eSIR_SUCCESS; + } + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.fromllg){ + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from 11g is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + if(!pMac->lim.cfgProtection.fromllg) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from 11g is disabled"));) + return eSIR_SUCCESS; + } + } + } + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + psessionEntry->gLimOverlap11gParams.protectionEnabled = true; + //11g exists in overlap BSS. + //need not to change the operating mode to overlap_legacy + //if higher or same protection operating mode is enabled right now. + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) && + (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + } + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams, psessionEntry); + } + else + { + //11g is associated to an AP operating in 11n mode. + //Change the HT operating mode to 'mixed mode'. + psessionEntry->gLim11gParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + pMac->lim.gLimOverlap11gParams.protectionEnabled = true; + //11g exists in overlap BSS. + //need not to change the operating mode to overlap_legacy + //if higher or same protection operating mode is enabled right now. + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + //11g is associated to an AP operating in 11n mode. + //Change the HT operating mode to 'mixed mode'. + psessionEntry->gLim11gParams.protectionEnabled = true; + if(eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_MIXED; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.llgCoexist) + { + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + else if (true == psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + // As operating mode changed after G station assoc some way to update beacon + // This addresses the issue of mode not changing to - 11 in beacon when OBSS overlap is enabled + //pMac->sch.schObject.fBeaconChanged = 1; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.llgCoexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + + if(eLIM_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + if (psessionEntry->gLim11gParams.numSta == 0) + psessionEntry->gLimOverlap11gParams.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + if(psessionEntry->gLimHt20Params.protectionEnabled){ + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + else + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLim11gParams.protectionEnabled = false; + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11bParams.protectionEnabled) + { + + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled) + + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!psessionEntry->gLimOverlap11gParams.protectionEnabled && + !psessionEntry->gLim11gParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled"));) + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + pMac->lim.gLimOverlap11gParams.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + if(psessionEntry->gLimHt20Params.protectionEnabled) + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + else + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLim11gParams.protectionEnabled = false; + //Check if any other non-HT protection enabled. + if(!psessionEntry->gLim11bParams.protectionEnabled) + { + + //Right now we are in HT OP Mixed mode. + //Change HT op mode appropriately. + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + + //Change HT OP mode to 01 if any overlap protection enabled + if(psessionEntry->gLimOlbcParams.protectionEnabled || + pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled) + + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + else if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + if(!pMac->lim.gLimOverlap11gParams.protectionEnabled && + !psessionEntry->gLim11gParams.protectionEnabled) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled"));) + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from 11G Disabled"));) + pBeaconParams->llgCoexist = psessionEntry->beaconParams.llgCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_llGCOEXIST_CHANGED; + } + } + return eSIR_SUCCESS; +} +//FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. +//This check will be done at the caller. + +/** ------------------------------------------------------------- +\fn limEnableHtObssProtection +\brief based on cofig enables\disables obss protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHtOBSSProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + + + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + //overlapping protection configuration check. + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && !psessionEntry->cfgProtection.obss) + { //ToDo Update this field + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from Obss is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + if(!pMac->lim.cfgProtection.obss) + { //ToDo Update this field + // protection disabled. + PELOG1(limLog(pMac, LOG1, FL("protection from Obss is disabled"));) + return eSIR_SUCCESS; + } + } + } + + + if (eLIM_AP_ROLE == psessionEntry->limSystemRole){ + if ((enable) && (false == psessionEntry->beaconParams.gHTObssMode) ) + { + PELOG1(limLog(pMac, LOG1, FL("=>obss protection enabled"));) + psessionEntry->beaconParams.gHTObssMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; // UPDATE AN ENUM FOR OBSS MODE + + } + else if (!enable && (true == psessionEntry->beaconParams.gHTObssMode)) + { + PELOG1(limLog(pMac, LOG1, FL("===> obss Protection disabled"));) + psessionEntry->beaconParams.gHTObssMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; + + } +//CR-263021: OBSS bit is not switching back to 0 after disabling the overlapping legacy BSS + if (!enable && !overlap) + { + psessionEntry->gLimOverlap11gParams.protectionEnabled = false; + } + } else + { + if ((enable) && (false == psessionEntry->beaconParams.gHTObssMode) ) + { + PELOG1(limLog(pMac, LOG1, FL("=>obss protection enabled"));) + psessionEntry->beaconParams.gHTObssMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; // UPDATE AN ENUM FOR OBSS MODE + + } + else if (!enable && (true == psessionEntry->beaconParams.gHTObssMode)) + { + + PELOG1(limLog(pMac, LOG1, FL("===> obss Protection disabled"));) + psessionEntry->beaconParams.gHTObssMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_OBSS_MODE_CHANGED; + + } + } + return eSIR_SUCCESS; +} +/** ------------------------------------------------------------- +\fn limEnableHT20Protection +\brief based on cofig enables\disables protection from Ht20. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHT20Protection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.ht20) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from HT20 is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + if(!pMac->lim.cfgProtection.ht20) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from HT20 is disabled"));) + return eSIR_SUCCESS; + } + } + } + + if (enable) + { + //If we are AP and HT capable, we need to set the HT OP mode + //appropriately. + + if(eLIM_AP_ROLE == psessionEntry->limSystemRole){ + if(overlap) + { + psessionEntry->gLimOverlapHt20Params.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != psessionEntry->htOperMode) && + (eSIR_HT_OP_MODE_MIXED != psessionEntry->htOperMode)) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + psessionEntry->gLimHt20Params.protectionEnabled = true; + if(eSIR_HT_OP_MODE_PURE == psessionEntry->htOperMode) + { + //Commenting because of CR 258588 WFA cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + pMac->lim.gLimOverlapHt20Params.protectionEnabled = true; + if((eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode)) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_OVERLAP_LEGACY; + limEnableHtRifsProtection(pMac, true, overlap, pBeaconParams,psessionEntry); + } + } + else + { + psessionEntry->gLimHt20Params.protectionEnabled = true; + if(eSIR_HT_OP_MODE_PURE == pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + } + + //This part is common for staiton as well. + if(false == psessionEntry->beaconParams.ht20Coexist) + { + PELOG1(limLog(pMac, LOG1, FL("=> Prtection from HT20 Enabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + } + } + else if (true == psessionEntry->beaconParams.ht20Coexist) + { + //for AP role. + //we need to take care of HT OP mode change if needed. + //We need to take care of Overlap cases. + if(eLIM_AP_ROLE == psessionEntry->limSystemRole){ + if(overlap) + { + //Overlap Legacy protection disabled. + psessionEntry->gLimOverlapHt20Params.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + psessionEntry->gLimOverlap11gParams.protectionEnabled || + psessionEntry->gLimOverlapHt20Params.protectionEnabled || + psessionEntry->gLimOverlapNonGfParams.protectionEnabled)) + { + + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == psessionEntry->htOperMode) + { + if(psessionEntry->gLimHt20Params.protectionEnabled) + { + //Commented beacuse of CR 258588 for WFA Cert + //psessionEntry->htOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLimHt20Params.protectionEnabled = false; + + //Change HT op mode appropriately. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == psessionEntry->htOperMode) + { + psessionEntry->htOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT 20 Disabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + }else if(eLIM_BT_AMP_AP_ROLE == psessionEntry->limSystemRole) + { + if(overlap) + { + //Overlap Legacy protection disabled. + pMac->lim.gLimOverlapHt20Params.protectionEnabled = false; + + // no HT op mode change if any of the overlap protection enabled. + if(!(psessionEntry->gLimOlbcParams.protectionEnabled || + pMac->lim.gLimOverlap11gParams.protectionEnabled || + pMac->lim.gLimOverlapHt20Params.protectionEnabled || + pMac->lim.gLimOverlapNonGfParams.protectionEnabled)) + { + + //Check if there is a need to change HT OP mode. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pMac->lim.gHTOperMode) + { + if(psessionEntry->gLimHt20Params.protectionEnabled) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + else + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + } + } + } + } + else + { + //Disable protection from 11G stations. + psessionEntry->gLimHt20Params.protectionEnabled = false; + + //Change HT op mode appropriately. + if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pMac->lim.gHTOperMode) + { + pMac->lim.gHTOperMode = eSIR_HT_OP_MODE_PURE; + limEnableHtRifsProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + limEnableHtOBSSProtection(pMac, false, overlap, pBeaconParams,psessionEntry); + } + } + PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT 20 Disabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + } + //for station role + else + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from HT20 Disabled"));) + pBeaconParams->ht20MhzCoexist = psessionEntry->beaconParams.ht20Coexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_HT20MHZCOEXIST_CHANGED; + } + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnableHTNonGfProtection +\brief based on cofig enables\disables protection from NonGf. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHTNonGfProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.nonGf) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from NonGf is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + //normal protection config check + if(!pMac->lim.cfgProtection.nonGf) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL("protection from NonGf is disabled"));) + return eSIR_SUCCESS; + } + } + } + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + if ((enable) && (false == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from non GF Enabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from Non GF Disabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + }else + { + if ((enable) && (false == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from non GF Enabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = true; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.llnNonGFCoexist)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from Non GF Disabled"));) + pBeaconParams->llnNonGFCoexist = psessionEntry->beaconParams.llnNonGFCoexist = false; + pBeaconParams->paramChangeBitmap |= PARAM_NON_GF_DEVICES_PRESENT_CHANGED; + } + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limEnableHTLsigTxopProtection +\brief based on cofig enables\disables LsigTxop protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHTLsigTxopProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE ) && + !psessionEntry->cfgProtection.lsigTxop) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from LsigTxop not supported is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE) + { + //normal protection config check + if(!pMac->lim.cfgProtection.lsigTxop) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from LsigTxop not supported is disabled"));) + return eSIR_SUCCESS; + } + } + } + + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + if ((enable) && (false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from LsigTxop Enabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = true; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from LsigTxop Disabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport= psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = false; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + }else + { + if ((enable) && (false == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Prtection from LsigTxop Enabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = true; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + else if (!enable && (true == psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Protection from LsigTxop Disabled"));) + pBeaconParams->fLsigTXOPProtectionFullSupport= psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = false; + pBeaconParams->paramChangeBitmap |= PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED; + } + } + return eSIR_SUCCESS; +} +//FIXME_PROTECTION : need to check for no APSD whenever we want to enable this protection. +//This check will be done at the caller. +/** ------------------------------------------------------------- +\fn limEnableHtRifsProtection +\brief based on cofig enables\disables Rifs protection. +\param tANI_U8 enable : 1=> enable protection, 0=> disable protection. +\param tANI_U8 overlap: 1=> called from overlap context, 0 => called from assoc context. +\param tpUpdateBeaconParams pBeaconParams +\return None + -------------------------------------------------------------*/ +tSirRetStatus +limEnableHtRifsProtection(tpAniSirGlobal pMac, tANI_U8 enable, + tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry) +{ + if(!psessionEntry->htCapability) + return eSIR_SUCCESS; // this protection is only for HT stations. + + + //overlapping protection configuration check. + if(overlap) + { + } + else + { + //normal protection config check + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) && + !psessionEntry->cfgProtection.rifs) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from Rifs is disabled"));) + return eSIR_SUCCESS; + }else if(psessionEntry->limSystemRole != eLIM_AP_ROLE ) + { + //normal protection config check + if(!pMac->lim.cfgProtection.rifs) + { + // protection disabled. + PELOG3(limLog(pMac, LOG3, FL(" protection from Rifs is disabled"));) + return eSIR_SUCCESS; + } + } + } + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE){ + // Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS + if ((!enable) && (false == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Rifs protection Disabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + // Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS + else if (enable && (true == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Rifs Protection Enabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + }else + { + // Disabling the RIFS Protection means Enable the RIFS mode of operation in the BSS + if ((!enable) && (false == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL(" => Rifs protection Disabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = true; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + // Enabling the RIFS Protection means Disable the RIFS mode of operation in the BSS + else if (enable && (true == psessionEntry->beaconParams.fRIFSMode)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Rifs Protection Enabled"));) + pBeaconParams->fRIFSMode = psessionEntry->beaconParams.fRIFSMode = false; + pBeaconParams->paramChangeBitmap |= PARAM_RIFS_MODE_CHANGED; + } + } + return eSIR_SUCCESS; +} + +// --------------------------------------------------------------------- +/** + * limEnableShortPreamble + * + * FUNCTION: + * Enable/Disable short preamble + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param enable Flag to enable/disable short preamble + * @return None + */ + +tSirRetStatus +limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry) +{ + tANI_U32 val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_SHORT_PREAMBLE, &val) != eSIR_SUCCESS) + { + /* Could not get short preamble enabled flag from CFG. Log error. */ + limLog(pMac, LOGP, FL("could not retrieve short preamble flag")); + return eSIR_FAILURE; + } + + if (!val) + return eSIR_SUCCESS; + + if (wlan_cfgGetInt(pMac, WNI_CFG_11G_SHORT_PREAMBLE_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve 11G short preamble switching enabled flag")); + return eSIR_FAILURE; + } + + if (!val) // 11G short preamble switching is disabled. + return eSIR_SUCCESS; + + if ( psessionEntry->limSystemRole == eLIM_AP_ROLE ) + { + if (enable && (psessionEntry->beaconParams.fShortPreamble == 0)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Short Preamble Enabled"));) + psessionEntry->beaconParams.fShortPreamble = true; + pBeaconParams->fShortPreamble = (tANI_U8) psessionEntry->beaconParams.fShortPreamble; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_PREAMBLE_CHANGED; + } + else if (!enable && (psessionEntry->beaconParams.fShortPreamble == 1)) + { + PELOG1(limLog(pMac, LOG1, FL("===> Short Preamble Disabled"));) + psessionEntry->beaconParams.fShortPreamble = false; + pBeaconParams->fShortPreamble = (tANI_U8) psessionEntry->beaconParams.fShortPreamble; + pBeaconParams->paramChangeBitmap |= PARAM_SHORT_PREAMBLE_CHANGED; + } + } + + return eSIR_SUCCESS; + } + +/** + * limTxComplete + * + * Function: + * This is LIM's very own "TX MGMT frame complete" completion routine. + * + * Logic: + * LIM wants to send a MGMT frame (broadcast or unicast) + * LIM allocates memory using palPktAlloc( ..., **pData, **pPacket ) + * LIM transmits the MGMT frame using the API: + * halTxFrame( ... pPacket, ..., (void *) limTxComplete, pData ) + * HDD, via halTxFrame/DXE, "transfers" the packet over to BMU + * HDD, if it determines that a TX completion routine (in this case + * limTxComplete) has been provided, will invoke this callback + * LIM will try to free the TX MGMT packet that was earlier allocated, in order + * to send this MGMT frame, using the PAL API palPktFree( ... pData, pPacket ) + * + * Assumptions: + * Presently, this is ONLY being used for MGMT frames/packets + * TODO: + * Would it do good for LIM to have some sort of "signature" validation to + * ensure that the pData argument passed in was a buffer that was actually + * allocated by LIM and/or is not corrupted? + * + * Note: FIXME and TODO + * Looks like palPktFree() is interested in pPacket. But, when this completion + * routine is called, only pData is made available to LIM!! + * + * @param void A pointer to pData. Shouldn't it be pPacket?! + * + * @return none + */ +void limTxComplete( tHalHandle hHal, void *pData ) +{ + tpAniSirGlobal pMac; + pMac = (tpAniSirGlobal)hHal; + +#ifdef FIXME_PRIMA + /* the trace logic needs to be fixed for Prima. Refer to CR 306075 */ +#ifdef TRACE_RECORD + { + tpSirMacMgmtHdr mHdr; + v_U8_t *pRxBd; + vos_pkt_t *pVosPkt; + VOS_STATUS vosStatus; + + + + pVosPkt = (vos_pkt_t *)pData; + vosStatus = vos_pkt_peek_data( pVosPkt, 0, (v_PVOID_t *)&pRxBd, WLANHAL_RX_BD_HEADER_SIZE); + + if(VOS_IS_STATUS_SUCCESS(vosStatus)) + { + mHdr = WDA_GET_RX_MAC_HEADER(pRxBd); + + } + } +#endif +#endif + + palPktFree( pMac->hHdd, + HAL_TXRX_FRM_802_11_MGMT, + (void *) NULL, // this is ignored and will likely be removed from this API + (void *) pData ); // lim passed in pPacket in the pData pointer that is given in this completion routine +} + +/** + * \brief This function updates lim global structure, if CB parameters in the BSS + * have changed, and sends an indication to HAL also with the + * updated HT Parameters. + * This function does not detect the change in the primary channel, that is done as part + * of channel Swtich IE processing. + * If STA is configured with '20Mhz only' mode, then this function does not do anything + * This function changes the CB mode, only if the self capability is set to '20 as well as 40Mhz' + * + * + * \param pMac Pointer to global MAC structure + * + * \param pRcvdHTInfo Pointer to HT Info IE obtained from a Beacon or + * Probe Response + * + * \param bssIdx BSS Index of the Bss to which Station is associated. + * + * + */ + +void limUpdateStaRunTimeHTSwitchChnlParams( tpAniSirGlobal pMac, + tDot11fIEHTInfo *pHTInfo, + tANI_U8 bssIdx, + tpPESession psessionEntry) +{ + ePhyChanBondState secondaryChnlOffset = PHY_SINGLE_CHANNEL_CENTERED; +#if !defined WLAN_FEATURE_VOWIFI + tANI_U32 localPwrConstraint; +#endif + + //If self capability is set to '20Mhz only', then do not change the CB mode. + if( !limGetHTCapability( pMac, eHT_SUPPORTED_CHANNEL_WIDTH_SET, psessionEntry )) + return; + + if ((RF_CHAN_14 >= psessionEntry->currentOperChannel) && + psessionEntry->force_24ghz_in_ht20) { + limLog(pMac, LOG1, + FL("force_24_gh_in_ht20 is set and channel is 2.4 Ghz")); + return; + } + +#if !defined WLAN_FEATURE_VOWIFI + if(wlan_cfgGetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, &localPwrConstraint) != eSIR_SUCCESS) { + limLog( pMac, LOGP, FL( "Unable to get Local Power Constraint from cfg" )); + return; + } +#endif + + if (pMac->ft.ftPEContext.pFTPreAuthReq) + { + limLog( pMac, LOGE, FL( "FT PREAUTH channel change is in progress")); + return; + } + + /* + * Do not try to switch channel if RoC is in progress. RoC code path uses + * pMac->lim.gpLimRemainOnChanReq to notify the upper layers that the device + * has started listening on the channel requested as part of RoC, if we set + * pMac->lim.gpLimRemainOnChanReq to NULL as we do below then the + * upper layers will think that the channel change is not successful and the + * RoC from the upper layer perspective will never end... + */ + if (pMac->lim.gpLimRemainOnChanReq) + { + limLog( pMac, LOGE, FL( "RoC is in progress")); + return; + } + + if ( psessionEntry->htSecondaryChannelOffset != ( tANI_U8 ) pHTInfo->secondaryChannelOffset || + psessionEntry->htRecommendedTxWidthSet != ( tANI_U8 ) pHTInfo->recommendedTxWidthSet ) + { + psessionEntry->htSecondaryChannelOffset = ( ePhyChanBondState ) pHTInfo->secondaryChannelOffset; + psessionEntry->htRecommendedTxWidthSet = ( tANI_U8 ) pHTInfo->recommendedTxWidthSet; + if ( eHT_CHANNEL_WIDTH_40MHZ == psessionEntry->htRecommendedTxWidthSet ) + secondaryChnlOffset = (ePhyChanBondState)pHTInfo->secondaryChannelOffset; + + // Notify HAL + limLog( pMac, LOGW, FL( "Channel Information in HT IE change" + "d; sending notification to HAL." ) ); + limLog( pMac, LOGW, FL( "Primary Channel: %d, Secondary Chan" + "nel Offset: %d, Channel Width: %d" ), + pHTInfo->primaryChannel, secondaryChnlOffset, + psessionEntry->htRecommendedTxWidthSet ); + psessionEntry->channelChangeReasonCode=LIM_SWITCH_CHANNEL_OPERATION; + pMac->lim.gpchangeChannelCallback = NULL; + pMac->lim.gpchangeChannelData = NULL; + +#if defined WLAN_FEATURE_VOWIFI + limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel, + secondaryChnlOffset, psessionEntry->maxTxPower, psessionEntry->peSessionId); +#else + limSendSwitchChnlParams( pMac, ( tANI_U8 ) pHTInfo->primaryChannel, + secondaryChnlOffset, (tPowerdBm)localPwrConstraint, psessionEntry->peSessionId); +#endif + + //In case of IBSS, if STA should update HT Info IE in its beacons. + if (eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole) + { + schSetFixedBeaconFields(pMac,psessionEntry); + } + + } +} // End limUpdateStaRunTimeHTParams. + +/** + * \brief This function updates the lim global structure, if any of the + * HT Capabilities have changed. + * + * + * \param pMac Pointer to Global MAC structure + * + * \param pHTCapability Pointer to HT Capability Information Element + * obtained from a Beacon or Probe Response + * + * + * + */ + +void limUpdateStaRunTimeHTCapability( tpAniSirGlobal pMac, + tDot11fIEHTCaps *pHTCaps ) +{ + + if ( pMac->lim.gHTLsigTXOPProtection != ( tANI_U8 ) pHTCaps->lsigTXOPProtection ) + { + pMac->lim.gHTLsigTXOPProtection = ( tANI_U8 ) pHTCaps->lsigTXOPProtection; + // Send change notification to HAL + } + + if ( pMac->lim.gHTAMpduDensity != ( tANI_U8 ) pHTCaps->mpduDensity ) + { + pMac->lim.gHTAMpduDensity = ( tANI_U8 ) pHTCaps->mpduDensity; + // Send change notification to HAL + } + + if ( pMac->lim.gHTMaxRxAMpduFactor != ( tANI_U8 ) pHTCaps->maxRxAMPDUFactor ) + { + pMac->lim.gHTMaxRxAMpduFactor = ( tANI_U8 ) pHTCaps->maxRxAMPDUFactor; + // Send change notification to HAL + } + + +} // End limUpdateStaRunTimeHTCapability. + +/** + * \brief This function updates lim global structure, if any of the HT + * Info Parameters have changed. + * + * + * \param pMac Pointer to the global MAC structure + * + * \param pHTInfo Pointer to the HT Info IE obtained from a Beacon or + * Probe Response + * + * + */ + +void limUpdateStaRunTimeHTInfo( tpAniSirGlobal pMac, + tDot11fIEHTInfo *pHTInfo, tpPESession psessionEntry) +{ + if ( psessionEntry->htRecommendedTxWidthSet != ( tANI_U8 )pHTInfo->recommendedTxWidthSet ) + { + psessionEntry->htRecommendedTxWidthSet = ( tANI_U8 )pHTInfo->recommendedTxWidthSet; + // Send change notification to HAL + } + + if ( psessionEntry->beaconParams.fRIFSMode != ( tANI_U8 )pHTInfo->rifsMode ) + { + psessionEntry->beaconParams.fRIFSMode = ( tANI_U8 )pHTInfo->rifsMode; + // Send change notification to HAL + } + + if ( pMac->lim.gHTServiceIntervalGranularity != ( tANI_U8 )pHTInfo->serviceIntervalGranularity ) + { + pMac->lim.gHTServiceIntervalGranularity = ( tANI_U8 )pHTInfo->serviceIntervalGranularity; + // Send change notification to HAL + } + + if ( pMac->lim.gHTOperMode != ( tSirMacHTOperatingMode )pHTInfo->opMode ) + { + pMac->lim.gHTOperMode = ( tSirMacHTOperatingMode )pHTInfo->opMode; + // Send change notification to HAL + } + + if ( psessionEntry->beaconParams.llnNonGFCoexist != pHTInfo->nonGFDevicesPresent ) + { + psessionEntry->beaconParams.llnNonGFCoexist = ( tANI_U8 )pHTInfo->nonGFDevicesPresent; + } + + if ( pMac->lim.gHTSTBCBasicMCS != ( tANI_U8 )pHTInfo->basicSTBCMCS ) + { + pMac->lim.gHTSTBCBasicMCS = ( tANI_U8 )pHTInfo->basicSTBCMCS; + // Send change notification to HAL + } + + if ( pMac->lim.gHTDualCTSProtection != ( tANI_U8 )pHTInfo->dualCTSProtection ) + { + pMac->lim.gHTDualCTSProtection = ( tANI_U8 )pHTInfo->dualCTSProtection; + // Send change notification to HAL + } + + if ( pMac->lim.gHTSecondaryBeacon != ( tANI_U8 )pHTInfo->secondaryBeacon ) + { + pMac->lim.gHTSecondaryBeacon = ( tANI_U8 )pHTInfo->secondaryBeacon; + // Send change notification to HAL + } + + if ( psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport != ( tANI_U8 )pHTInfo->lsigTXOPProtectionFullSupport ) + { + psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport = ( tANI_U8 )pHTInfo->lsigTXOPProtectionFullSupport; + // Send change notification to HAL + } + + if ( pMac->lim.gHTPCOActive != ( tANI_U8 )pHTInfo->pcoActive ) + { + pMac->lim.gHTPCOActive = ( tANI_U8 )pHTInfo->pcoActive; + // Send change notification to HAL + } + + if ( pMac->lim.gHTPCOPhase != ( tANI_U8 )pHTInfo->pcoPhase ) + { + pMac->lim.gHTPCOPhase = ( tANI_U8 )pHTInfo->pcoPhase; + // Send change notification to HAL + } + +} // End limUpdateStaRunTimeHTInfo. + + +/** ------------------------------------------------------------- +\fn limProcessHalIndMessages +\brief callback function for HAL indication +\param tpAniSirGlobal pMac +\param tANI_U32 mesgId +\param void *mesgParam +\return tSirRetStatu - status + -------------------------------------------------------------*/ + +tSirRetStatus limProcessHalIndMessages(tpAniSirGlobal pMac, tANI_U32 msgId, void *msgParam ) +{ + //its PE's responsibility to free msgparam when its done extracting the message parameters. + tSirMsgQ msg; + + switch(msgId) + { + case SIR_LIM_DEL_TS_IND: + case SIR_LIM_ADD_BA_IND: + case SIR_LIM_DEL_BA_ALL_IND: + case SIR_LIM_DELETE_STA_CONTEXT_IND: + case SIR_LIM_BEACON_GEN_IND: + case SIR_LIM_DEL_BA_IND: + msg.type = (tANI_U16) msgId; + msg.bodyptr = msgParam; + msg.bodyval = 0; + break; + + default: + vos_mem_free(msgParam); + limLog(pMac, LOGP, FL("invalid message id = %d received"), msgId); + return eSIR_FAILURE; + } + + if (limPostMsgApi(pMac, &msg) != eSIR_SUCCESS) + { + vos_mem_free(msgParam); + limLog(pMac, LOGP, FL("limPostMsgApi failed for msgid = %d"), msg.type); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limValidateDeltsReq +\brief Validates DelTs req originated by SME or by HAL and also sends halMsg_DelTs to HAL +\param tpAniSirGlobal pMac +\param tpSirDeltsReq pDeltsReq +\param tSirMacAddr peerMacAddr +\return eSirRetStatus - status + -------------------------------------------------------------*/ + +tSirRetStatus +limValidateDeltsReq(tpAniSirGlobal pMac, tpSirDeltsReq pDeltsReq, tSirMacAddr peerMacAddr,tpPESession psessionEntry) +{ + tpDphHashNode pSta; + tANI_U8 tsStatus; + tSirMacTSInfo *tsinfo; + tANI_U32 i; + tANI_U8 tspecIdx; + /* if sta + * - verify assoc state + * - del tspec locally + * if ap, + * - verify sta is in assoc state + * - del sta tspec locally + */ + if(pDeltsReq == NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Delete TS request pointer is NULL"));) + return eSIR_FAILURE; + } + + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE)||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + tANI_U32 val; + + // station always talks to the AP + pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + + val = sizeof(tSirMacAddr); + #if 0 + if (wlan_cfgGetStr(pMac, WNI_CFG_BSSID, peerMacAddr, &val) != eSIR_SUCCESS) + { + /// Could not get BSSID from CFG. Log error. + limLog(pMac, LOGP, FL("could not retrieve BSSID")); + return eSIR_FAILURE; + } + #endif// TO SUPPORT BT-AMP + sirCopyMacAddr(peerMacAddr,psessionEntry->bssId); + + } + else + { + tANI_U16 assocId; + tANI_U8 *macaddr = (tANI_U8 *) peerMacAddr; + + assocId = pDeltsReq->aid; + if (assocId != 0) + pSta = dphGetHashEntry(pMac, assocId, &psessionEntry->dph.dphHashTable); + else + pSta = dphLookupHashEntry(pMac, pDeltsReq->macAddr, &assocId, &psessionEntry->dph.dphHashTable); + + if (pSta != NULL) + // TBD: check sta assoc state as well + for (i =0; i < sizeof(tSirMacAddr); i++) + macaddr[i] = pSta->staAddr[i]; + } + + if (pSta == NULL) + { + PELOGE(limLog(pMac, LOGE, "Cannot find station context for delts req");) + return eSIR_FAILURE; + } + + if ((! pSta->valid) || + (pSta->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)) + { + PELOGE(limLog(pMac, LOGE, "Invalid Sta (or state) for DelTsReq");) + return eSIR_FAILURE; + } + + pDeltsReq->req.wsmTspecPresent = 0; + pDeltsReq->req.wmeTspecPresent = 0; + pDeltsReq->req.lleTspecPresent = 0; + + if ((pSta->wsmEnabled) && + (pDeltsReq->req.tspec.tsinfo.traffic.accessPolicy != SIR_MAC_ACCESSPOLICY_EDCA)) + pDeltsReq->req.wsmTspecPresent = 1; + else if (pSta->wmeEnabled) + pDeltsReq->req.wmeTspecPresent = 1; + else if (pSta->lleEnabled) + pDeltsReq->req.lleTspecPresent = 1; + else + { + PELOGW(limLog(pMac, LOGW, FL("DELTS_REQ ignore - qos is disabled"));) + return eSIR_FAILURE; + } + + tsinfo = pDeltsReq->req.wmeTspecPresent ? &pDeltsReq->req.tspec.tsinfo + : &pDeltsReq->req.tsinfo; + limLog(pMac, LOG1, + FL("received DELTS_REQ message (wmeTspecPresent = %d, lleTspecPresent = %d, wsmTspecPresent = %d, tsid %d, up %d, direction = %d)"), + pDeltsReq->req.wmeTspecPresent, pDeltsReq->req.lleTspecPresent, pDeltsReq->req.wsmTspecPresent, + tsinfo->traffic.tsid, tsinfo->traffic.userPrio, tsinfo->traffic.direction); + + // if no Access Control, ignore the request + + if (limAdmitControlDeleteTS(pMac, pSta->assocId, tsinfo, &tsStatus, &tspecIdx) + != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, "ERROR DELTS request for sta assocId %d (tsid %d, up %d)", + pSta->assocId, tsinfo->traffic.tsid, tsinfo->traffic.userPrio);) + return eSIR_FAILURE; + } + else if ((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_HCCA) || + (tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_BOTH)) + { + //edca only now. + } + else + { + if((tsinfo->traffic.accessPolicy == SIR_MAC_ACCESSPOLICY_EDCA) && + psessionEntry->gLimEdcaParams[upToAc(tsinfo->traffic.userPrio)].aci.acm) + { + //send message to HAL to delete TS + if(eSIR_SUCCESS != limSendHalMsgDelTs(pMac, + pSta->staIndex, + tspecIdx, + pDeltsReq->req, + psessionEntry->peSessionId, + psessionEntry->bssId)) + { + limLog(pMac, LOGW, FL("DelTs with UP %d failed in limSendHalMsgDelTs - ignoring request"), + tsinfo->traffic.userPrio); + return eSIR_FAILURE; + } + } + } + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn limRegisterHalIndCallBack +\brief registers callback function to HAL for any indication. +\param tpAniSirGlobal pMac +\return none. + -------------------------------------------------------------*/ +void +limRegisterHalIndCallBack(tpAniSirGlobal pMac) +{ + tSirMsgQ msg; + tpHalIndCB pHalCB; + + pHalCB = vos_mem_malloc(sizeof(tHalIndCB)); + if ( NULL == pHalCB ) + { + limLog(pMac, LOGP, FL("AllocateMemory() failed")); + return; + } + + pHalCB->pHalIndCB = limProcessHalIndMessages; + + msg.type = WDA_REGISTER_PE_CALLBACK; + msg.bodyptr = pHalCB; + msg.bodyval = 0; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); + if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg)) + { + vos_mem_free(pHalCB); + limLog(pMac, LOGP, FL("wdaPostCtrlMsg() failed")); + } + + return; +} + + +/** ------------------------------------------------------------- +\fn limProcessAddBaInd + +\brief handles the BA activity check timeout indication coming from HAL. + Validates the request, posts request for sending addBaReq message for every candidate in the list. +\param tpAniSirGlobal pMac +\param tSirMsgQ limMsg +\return None +-------------------------------------------------------------*/ +void +limProcessAddBaInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tANI_U8 i; + tANI_U8 tid; + tANI_U16 assocId; + tpDphHashNode pSta; + tpAddBaCandidate pBaCandidate; + tANI_U32 baCandidateCnt; + tpBaActivityInd pBaActivityInd; + tpPESession psessionEntry; + tANI_U8 sessionId; +#ifdef FEATURE_WLAN_TDLS + boolean htCapable = FALSE; +#endif + + + if (limMsg->bodyptr == NULL) + return; + + pBaActivityInd = (tpBaActivityInd)limMsg->bodyptr; + baCandidateCnt = pBaActivityInd->baCandidateCnt; + + if ((psessionEntry = peFindSessionByBssid(pMac,pBaActivityInd->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given BSSId")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + + //if we are not HT capable we don't need to handle BA timeout indication from HAL. +#ifdef FEATURE_WLAN_TDLS + if ((baCandidateCnt > pMac->lim.maxStation)) +#else + if ((baCandidateCnt > pMac->lim.maxStation) || !psessionEntry->htCapability ) +#endif + { + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + +#ifdef FEATURE_WLAN_TDLS + //if we have TDLS peers, we should look at peers HT capability, which can be different than + //AP capability + pBaCandidate = (tpAddBaCandidate) (((tANI_U8*)pBaActivityInd) + sizeof(tBaActivityInd)); + + for (i=0; istaAddr, &assocId, &psessionEntry->dph.dphHashTable); + if ((NULL == pSta) || (!pSta->valid)) + continue; + + if (STA_ENTRY_TDLS_PEER == pSta->staType) + htCapable = pSta->mlmStaContext.htCapability; + else + htCapable = psessionEntry->htCapability; + + if (htCapable) + break; + } + if (!htCapable) + { + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } +#endif + + //delete the complete dialoguetoken linked list + limDeleteDialogueTokenList(pMac); + pBaCandidate = (tpAddBaCandidate) (((tANI_U8*)pBaActivityInd) + sizeof(tBaActivityInd)); + + for (i=0; istaAddr, &assocId, &psessionEntry->dph.dphHashTable); + if ((NULL == pSta) || (!pSta->valid)) + continue; + + for (tid=0; tidtcCfg[tid].fUseBATx) && + (pBaCandidate->baInfo[tid].fBaEnable)) + { + limLog(pMac, LOG1, + FL("BA setup for staId = %d, TID: %d, SSN: %d"), + pSta->staIndex, tid, + pBaCandidate->baInfo[tid].startingSeqNum); + limPostMlmAddBAReq(pMac, pSta, tid, + pBaCandidate->baInfo[tid].startingSeqNum,psessionEntry); + } + } + } + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; +} + + +/** ------------------------------------------------------------- +\fn limDeleteBASessions +\brief Deletes all the exisitng BA sessions for given session + and BA direction. +\param tpAniSirGlobal pMac +\param tpPESession pSessionEntry +\param tANI_U32 baDirection +\return None +-------------------------------------------------------------*/ + +void +limDeleteBASessions(tpAniSirGlobal pMac, tpPESession pSessionEntry, + tANI_U32 baDirection, tSirMacReasonCodes baReasonCode) +{ + tANI_U32 i; + tANI_U8 tid; + tpDphHashNode pSta; + + if (NULL == pSessionEntry) + { + limLog(pMac, LOGE, FL("Session does not exist")); + } + else + { + for(tid = 0; tid < STACFG_MAX_TC; tid++) + { + if ((eLIM_AP_ROLE == pSessionEntry->limSystemRole) || + (pSessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) || + (eLIM_STA_IN_IBSS_ROLE == pSessionEntry->limSystemRole) || + (pSessionEntry->limSystemRole == eLIM_P2P_DEVICE_GO)) + { + for (i = 0; i < pMac->lim.maxStation; i++) + { + pSta = pSessionEntry->dph.dphHashTable.pDphNodeArray + i; + if (pSta && pSta->added) + { + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBATx) && + (baDirection & BA_INITIATOR)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_INITIATOR, tid, + baReasonCode, + pSessionEntry); + } + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBARx) && + (baDirection & BA_RECIPIENT)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_RECIPIENT, tid, + baReasonCode, + pSessionEntry); + } + } + } + } + else if ((eLIM_STA_ROLE == pSessionEntry->limSystemRole) || + (eLIM_BT_AMP_STA_ROLE == pSessionEntry->limSystemRole) || + (eLIM_P2P_DEVICE_ROLE == pSessionEntry->limSystemRole)) + { + pSta = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, + &pSessionEntry->dph.dphHashTable); + if (pSta && pSta->added) + { + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBATx) && + (baDirection & BA_INITIATOR)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_INITIATOR, tid, + baReasonCode, + pSessionEntry); + } + if ((eBA_ENABLE == pSta->tcCfg[tid].fUseBARx) && + (baDirection & BA_RECIPIENT)) + { + limPostMlmDelBAReq(pMac, pSta, eBA_RECIPIENT, tid, + baReasonCode, + pSessionEntry); + } + } + } + } + } +} + +/** ------------------------------------------------------------- +\fn limDelAllBASessions +\brief Deletes all the exisitng BA sessions. +\param tpAniSirGlobal pMac +\return None +-------------------------------------------------------------*/ + +void limDelAllBASessions(tpAniSirGlobal pMac) +{ + tANI_U32 i; + tpPESession pSessionEntry; + + for (i = 0; i < pMac->lim.maxBssId; i++) + { + pSessionEntry = peFindSessionBySessionId(pMac, i); + if (pSessionEntry) + { + limDeleteBASessions(pMac, pSessionEntry, BA_BOTH_DIRECTIONS, + eSIR_MAC_UNSPEC_FAILURE_REASON); + } + } +} + +/** ------------------------------------------------------------- +\fn limDelAllBASessionsBtc +\brief Deletes all the exisitng BA receipent sessions in 2.4GHz + band. +\param tpAniSirGlobal pMac +\return None +-------------------------------------------------------------*/ + +void limDelPerBssBASessionsBtc(tpAniSirGlobal pMac) +{ + tANI_U8 sessionId; + tpPESession pSessionEntry; + pSessionEntry = peFindSessionByBssid(pMac,pMac->btc.btcBssfordisableaggr, + &sessionId); + if (pSessionEntry) + { + PELOGW(limLog(pMac, LOGW, + "Deleting the BA for session %d as host got BTC event", sessionId);) + limDeleteBASessions(pMac, pSessionEntry, BA_BOTH_DIRECTIONS, + eSIR_MAC_PEER_TIMEDOUT_REASON); + } +} + +/** ------------------------------------------------------------- +\fn limProcessDelTsInd +\brief handles the DeleteTS indication coming from HAL or generated by PE itself in some error cases. + Validates the request, sends the DelTs action frame to the Peer and sends DelTs indicatoin to HDD. +\param tpAniSirGlobal pMac +\param tSirMsgQ limMsg +\return None +-------------------------------------------------------------*/ +void +limProcessDelTsInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpDphHashNode pSta; + tpDelTsParams pDelTsParam = (tpDelTsParams) (limMsg->bodyptr); + tpSirDeltsReq pDelTsReq = NULL; + tSirMacAddr peerMacAddr; + tpSirDeltsReqInfo pDelTsReqInfo; + tpLimTspecInfo pTspecInfo; + tpPESession psessionEntry; + tANI_U8 sessionId; + +if((psessionEntry = peFindSessionByBssid(pMac,pDelTsParam->bssId,&sessionId))== NULL) + { + limLog(pMac, LOGE,FL("session does not exist for given BssId")); + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; + } + + pTspecInfo = &(pMac->lim.tspecInfo[pDelTsParam->tspecIdx]); + if(pTspecInfo->inuse == false) + { + PELOGE(limLog(pMac, LOGE, FL("tspec entry with index %d is not in use"), pDelTsParam->tspecIdx);) + goto error1; + } + + pSta = dphGetHashEntry(pMac, pTspecInfo->assocId, &psessionEntry->dph.dphHashTable); + if(pSta == NULL) + { + limLog(pMac, LOGE, FL("Could not find entry in DPH table for assocId = %d"), + pTspecInfo->assocId); + goto error1; + } + + pDelTsReq = vos_mem_malloc(sizeof(tSirDeltsReq)); + if ( NULL == pDelTsReq ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory() failed"));) + goto error1; + } + + vos_mem_set( (tANI_U8 *)pDelTsReq, sizeof(tSirDeltsReq), 0); + + if(pSta->wmeEnabled) + vos_mem_copy( &(pDelTsReq->req.tspec), &(pTspecInfo->tspec), sizeof(tSirMacTspecIE)); + else + vos_mem_copy( &(pDelTsReq->req.tsinfo), &(pTspecInfo->tspec.tsinfo), sizeof(tSirMacTSInfo)); + + + //validate the req + if (eSIR_SUCCESS != limValidateDeltsReq(pMac, pDelTsReq, peerMacAddr,psessionEntry)) + { + PELOGE(limLog(pMac, LOGE, FL("limValidateDeltsReq failed"));) + goto error2; + } + limLog(pMac, LOG1, "Sent DELTS request to station with " + "assocId = %d MacAddr = "MAC_ADDRESS_STR, + pDelTsReq->aid, MAC_ADDR_ARRAY(peerMacAddr)); + + limSendDeltsReqActionFrame(pMac, peerMacAddr, pDelTsReq->req.wmeTspecPresent, &pDelTsReq->req.tsinfo, &pDelTsReq->req.tspec, + psessionEntry); + + // prepare and send an sme indication to HDD + pDelTsReqInfo = vos_mem_malloc(sizeof(tSirDeltsReqInfo)); + if ( NULL == pDelTsReqInfo ) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory() failed"));) + goto error3; + } + vos_mem_set( (tANI_U8 *)pDelTsReqInfo, sizeof(tSirDeltsReqInfo), 0); + + if(pSta->wmeEnabled) + vos_mem_copy( &(pDelTsReqInfo->tspec), &(pTspecInfo->tspec), sizeof(tSirMacTspecIE)); + else + vos_mem_copy( &(pDelTsReqInfo->tsinfo), &(pTspecInfo->tspec.tsinfo), sizeof(tSirMacTSInfo)); + + limSendSmeDeltsInd(pMac, pDelTsReqInfo, pDelTsReq->aid,psessionEntry); + +error3: + vos_mem_free(pDelTsReqInfo); +error2: + vos_mem_free(pDelTsReq); +error1: + vos_mem_free(limMsg->bodyptr); + limMsg->bodyptr = NULL; + return; +} + +/** + * \brief Setup an A-MPDU/BA session + * + * \sa limPostMlmAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pStaDs DPH Hash Node object of peer STA + * + * \param tid TID for which a BA is being setup. + * If this is set to 0xFFFF, then we retrieve + * the default TID from the CFG + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limPostMlmAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_U8 tid, tANI_U16 startingSeqNum,tpPESession psessionEntry) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpLimMlmAddBAReq pMlmAddBAReq = NULL; + tpDialogueToken dialogueTokenNode; + tANI_U32 val = 0; + + // Check if the peer is a 11n capable STA + // FIXME - Need a 11n peer indication in DPH. + // For now, using the taurusPeer attribute + //if( 0 == pStaDs->taurusPeer == ) + //return eSIR_SUCCESS; + + // Allocate for LIM_MLM_ADDBA_REQ + pMlmAddBAReq = vos_mem_malloc(sizeof( tLimMlmAddBAReq )); + if ( NULL == pMlmAddBAReq ) + { + limLog( pMac, LOGP, FL("AllocateMemory failed")); + status = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pMlmAddBAReq, sizeof( tLimMlmAddBAReq ), 0); + + // Copy the peer MAC + vos_mem_copy( + pMlmAddBAReq->peerMacAddr, + pStaDs->staAddr, + sizeof( tSirMacAddr )); + + // Update the TID + pMlmAddBAReq->baTID = tid; + + // Determine the supported BA policy of local STA + // for the TID of interest + pMlmAddBAReq->baPolicy = (pStaDs->baPolicyFlag >> tid) & 0x1; + + // BA Buffer Size + // Requesting the ADDBA recipient to populate the size. + // If ADDBA is accepted, a non-zero buffer size should + // be returned in the ADDBA Rsp + if ((TRUE == psessionEntry->isCiscoVendorAP) && + (eHT_CHANNEL_WIDTH_80MHZ != pStaDs->htSupportedChannelWidthSet)) + { + /* Cisco AP has issues in receiving more than 25 "mpdu in ampdu" + causing very low throughput in HT40 case */ + limLog( pMac, LOGW, + FL( "Requesting ADDBA with Cisco 1225 AP, window size 25")); + pMlmAddBAReq->baBufferSize = MAX_BA_WINDOW_SIZE_FOR_CISCO; + } + else if (pMac->miracastVendorConfig) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_NUM_BUFF_ADVERT , &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Unable to get WNI_CFG_NUM_BUFF_ADVERT")); + status = eSIR_FAILURE; + goto returnFailure; + } + + pMlmAddBAReq->baBufferSize = val; + } + else + pMlmAddBAReq->baBufferSize = 0; + + limLog( pMac, LOGW, + FL( "Requesting an ADDBA to setup a %s BA session with STA %d for TID %d buff = %d" ), + (pMlmAddBAReq->baPolicy ? "Immediate": "Delayed"), + pStaDs->staIndex, + tid, pMlmAddBAReq->baBufferSize ); + + // BA Timeout + if (wlan_cfgGetInt(pMac, WNI_CFG_BA_TIMEOUT, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("could not retrieve BA TIME OUT Param CFG")); + status = eSIR_FAILURE; + goto returnFailure; + } + pMlmAddBAReq->baTimeout = val; // In TU's + + // ADDBA Failure Timeout + // FIXME_AMPDU - Need to retrieve this from CFG. + //right now we are not checking for response timeout. so this field is dummy just to be compliant with the spec. + pMlmAddBAReq->addBAFailureTimeout = 2000; // In TU's + + // BA Starting Sequence Number + pMlmAddBAReq->baSSN = startingSeqNum; + + /* Update PE session Id*/ + pMlmAddBAReq->sessionId = psessionEntry->peSessionId; + + LIM_SET_STA_BA_STATE(pStaDs, tid, eLIM_BA_STATE_WT_ADD_RSP); + + dialogueTokenNode = limAssignDialogueToken(pMac); + if (NULL == dialogueTokenNode) + { + limLog(pMac, LOGE, FL("could not assign dialogue token")); + status = eSIR_FAILURE; + goto returnFailure; + } + + pMlmAddBAReq->baDialogToken = dialogueTokenNode->token; + //set assocId and tid information in the lim linked list + dialogueTokenNode->assocId = pStaDs->assocId; + dialogueTokenNode->tid = tid; + // Send ADDBA Req to MLME + limPostMlmMessage( pMac, + LIM_MLM_ADDBA_REQ, + (tANI_U32 *) pMlmAddBAReq ); + return eSIR_SUCCESS; + +returnFailure: + vos_mem_free(pMlmAddBAReq); + return status; +} + +/** + * \brief Post LIM_MLM_ADDBA_RSP to MLME. MLME + * will then send an ADDBA Rsp to peer MAC entity + * with the appropriate ADDBA status code + * + * \sa limPostMlmAddBARsp + * + * \param pMac The global tpAniSirGlobal object + * + * \param peerMacAddr MAC address of peer entity that will + * be the recipient of this ADDBA Rsp + * + * \param baStatusCode ADDBA Rsp status code + * + * \param baDialogToken ADDBA Rsp dialog token + * + * \param baTID TID of interest + * + * \param baPolicy The BA policy + * + * \param baBufferSize The BA buffer size + * + * \param baTimeout BA timeout in TU's + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limPostMlmAddBARsp( tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirMacStatusCodes baStatusCode, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tpPESession psessionEntry) +{ +tSirRetStatus status = eSIR_SUCCESS; +tpLimMlmAddBARsp pMlmAddBARsp; + + // Allocate for LIM_MLM_ADDBA_RSP + pMlmAddBARsp = vos_mem_malloc(sizeof( tLimMlmAddBARsp )); + if ( NULL == pMlmAddBARsp ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed with error code %d"), + status ); + + status = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pMlmAddBARsp, sizeof( tLimMlmAddBARsp ), 0); + + // Copy the peer MAC + vos_mem_copy( + pMlmAddBARsp->peerMacAddr, + peerMacAddr, + sizeof( tSirMacAddr )); + + pMlmAddBARsp->baDialogToken = baDialogToken; + pMlmAddBARsp->addBAResultCode = baStatusCode; + pMlmAddBARsp->baTID = baTID; + pMlmAddBARsp->baPolicy = baPolicy; + pMlmAddBARsp->baBufferSize = baBufferSize; + pMlmAddBARsp->baTimeout = baTimeout; + + /* UPdate PE session ID*/ + pMlmAddBARsp->sessionId = psessionEntry->peSessionId; + + // Send ADDBA Rsp to MLME + limPostMlmMessage( pMac, + LIM_MLM_ADDBA_RSP, + (tANI_U32 *) pMlmAddBARsp ); + +returnFailure: + + return status; +} + +/** + * \brief Post LIM_MLM_DELBA_REQ to MLME. MLME + * will then send an DELBA Ind to peer MAC entity + * with the appropriate DELBA status code + * + * \sa limPostMlmDelBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pSta DPH Hash Node object of peer MAC entity + * for which the BA session is being deleted + * + * \param baDirection DELBA direction + * + * \param baTID TID for which the BA session is being deleted + * + * \param baReasonCode DELBA Req reason code + * + * \return eSIR_SUCCESS if setup completes successfully + * eSIR_FAILURE is some problem is encountered + */ +tSirRetStatus limPostMlmDelBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDirection, + tANI_U8 baTID, + tSirMacReasonCodes baReasonCode, + tpPESession psessionEntry) +{ +tSirRetStatus status = eSIR_SUCCESS; +tpLimMlmDelBAReq pMlmDelBAReq; +tLimBAState curBaState; + +if(NULL == pSta) + return eSIR_FAILURE; + +LIM_GET_STA_BA_STATE(pSta, baTID, &curBaState); + + // Need to validate the current BA State. + if( eLIM_BA_STATE_IDLE != curBaState) + { + limLog( pMac, LOGE, + FL( "Received unexpected DELBA REQ when STA BA state for tid = %d is %d" ), + baTID, + curBaState); + + status = eSIR_FAILURE; + goto returnFailure; + } + + // Allocate for LIM_MLM_DELBA_REQ + pMlmDelBAReq = vos_mem_malloc(sizeof( tLimMlmDelBAReq )); + if ( NULL == pMlmDelBAReq ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed with error code %d"), + status ); + + status = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pMlmDelBAReq, sizeof( tLimMlmDelBAReq ), 0); + + // Copy the peer MAC + vos_mem_copy( + pMlmDelBAReq->peerMacAddr, + pSta->staAddr, + sizeof( tSirMacAddr )); + + pMlmDelBAReq->baDirection = baDirection; + pMlmDelBAReq->baTID = baTID; + pMlmDelBAReq->delBAReasonCode = baReasonCode; + + /* Update PE session ID*/ + pMlmDelBAReq->sessionId = psessionEntry->peSessionId; + + //we don't have valid BA session for the given direction. + // HDD wants to get the BA session deleted on PEER in this case. + // in this case we just need to send DelBA to the peer. + if(((eBA_RECIPIENT == baDirection) && (eBA_DISABLE == pSta->tcCfg[baTID].fUseBARx)) || + ((eBA_INITIATOR == baDirection) && (eBA_DISABLE == pSta->tcCfg[baTID].fUseBATx))) + { + // Send DELBA Ind over the air + if( eSIR_SUCCESS != + (status = limSendDelBAInd( pMac, pMlmDelBAReq,psessionEntry))) + status = eSIR_FAILURE; + + vos_mem_free(pMlmDelBAReq); + return status; + } + + + // Update the BA state in STA + LIM_SET_STA_BA_STATE(pSta, pMlmDelBAReq->baTID, eLIM_BA_STATE_WT_DEL_RSP); + + // Send DELBA Req to MLME + limPostMlmMessage( pMac, + LIM_MLM_DELBA_REQ, + (tANI_U32 *) pMlmDelBAReq ); + +returnFailure: + + return status; +} + +/** + * \brief Send WDA_ADDBA_REQ to HAL, in order + * to setup a new BA session with a peer + * + * \sa limPostMsgAddBAReq + * + * \param pMac The global tpAniSirGlobal object + * + * \param pSta Runtime, STA-related configuration cached + * in the HashNode object + * + * \param baDialogToken The Action Frame dialog token + * + * \param baTID TID for which the BA session is being setup + * + * \param baPolicy BA Policy + * + * \param baBufferSize The requested BA buffer size + * + * \param baTimeout BA Timeout. 0 indicates no BA timeout enforced + * + * \param baSSN Starting Sequence Number for this BA session + * + * \param baDirection BA Direction: 1 - Initiator, 0 - Recipient + * + * \return none + * + */ +tSirRetStatus limPostMsgAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tANI_U16 baSSN, + tANI_U8 baDirection, + tpPESession psessionEntry) +{ +tpAddBAParams pAddBAParams = NULL; +tSirRetStatus retCode = eSIR_SUCCESS; +tSirMsgQ msgQ; + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // we can only do BA on "hard" STAs + if (!(IS_HWSTA_IDX(pSta->staIndex))) + { + retCode = eHAL_STATUS_FAILURE; + limLog( pMac, LOGE, + FL( "Sta Id is not HW Sta Id, return code is %d " ), retCode); + goto returnFailure; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + + // Allocate for WDA_ADDBA_REQ + pAddBAParams = vos_mem_malloc(sizeof( tAddBAParams )); + if ( NULL == pAddBAParams ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed") + ); + + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pAddBAParams, sizeof( tAddBAParams ), 0); + + // Copy the peer MAC address + vos_mem_copy( + (void *) pAddBAParams->peerMacAddr, + (void *) pSta->staAddr, + sizeof( tSirMacAddr )); + + // Populate the REQ parameters + pAddBAParams->staIdx = pSta->staIndex; + pAddBAParams->baDialogToken = baDialogToken; + pAddBAParams->baTID = baTID; + pAddBAParams->baPolicy = baPolicy; + pAddBAParams->baBufferSize = baBufferSize; + pAddBAParams->baTimeout = baTimeout; + pAddBAParams->baSSN = baSSN; + pAddBAParams->baDirection = baDirection; + pAddBAParams->respReqd = 1; + + /* UPdate PE session ID */ + pAddBAParams->sessionId = psessionEntry->peSessionId; + + // Post WDA_ADDBA_REQ to HAL. + msgQ.type = WDA_ADDBA_REQ; + // + // FIXME_AMPDU + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pAddBAParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending WDA_ADDBA_REQ... Buff size = %d , staId = %d , timeout = %d " + "Tid = %d, Direction = %d , Policy = %d, sessionId = %d , baSSN = %d " ), + pAddBAParams->baBufferSize, pAddBAParams->staIdx, + pAddBAParams->baTimeout, pAddBAParams->baTID, + pAddBAParams->baDirection, pAddBAParams->baPolicy, + pAddBAParams->sessionId, pAddBAParams->baSSN); + + //defer any other message until we get response back. + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + limLog( pMac, LOGE, + FL("Posting WDA_ADDBA_REQ to HAL failed! Reason = %d"), + retCode ); + else + return retCode; + +returnFailure: + + // Clean-up... + if( NULL != pAddBAParams ) + vos_mem_free( pAddBAParams ); + + return retCode; + +} + +/** + * \brief Send WDA_DELBA_IND to HAL, in order + * to delete an existing BA session with peer + * + * \sa limPostMsgDelBAInd + * + * \param pMac The global tpAniSirGlobal object + * + * \param pSta Runtime, STA-related configuration cached + * in the HashNode object + * + * \param baTID TID for which the BA session is being setup + * + * \param baDirection Identifies whether the DELBA Ind was + * sent by the BA initiator or recipient + * + * \return none + * + */ +tSirRetStatus limPostMsgDelBAInd( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baTID, + tANI_U8 baDirection, + tpPESession psessionEntry) +{ +tpDelBAParams pDelBAParams = NULL; +tSirRetStatus retCode = eSIR_SUCCESS; +tSirMsgQ msgQ; + + // Allocate for SIR_HAL_DELBA_IND + pDelBAParams = vos_mem_malloc(sizeof( tDelBAParams )); + if ( NULL == pDelBAParams ) + { + limLog( pMac, LOGE, + FL("AllocateMemory failed") + ); + + retCode = eSIR_MEM_ALLOC_FAILED; + goto returnFailure; + } + + vos_mem_set( (void *) pDelBAParams, sizeof( tDelBAParams ), 0); + + // Populate the REQ parameters + pDelBAParams->staIdx = pSta->staIndex; + pDelBAParams->baTID = baTID; + pDelBAParams->baDirection = baDirection; + + /* Update PE session ID */ + + + //TBD-RAJESH Updating of the session ID is requird for SIR_HAL_DELBA_IND????? + //pDelBAParams->sessionId = psessionEntry->peSessionId; + + // Post WDA_DELBA_IND to HAL. + msgQ.type = WDA_DELBA_IND; + // + // FIXME: + // A global counter (dialog token) is required to keep track of + // all PE <-> HAL communication(s) + // + msgQ.reserved = 0; + msgQ.bodyptr = pDelBAParams; + msgQ.bodyval = 0; + + limLog( pMac, LOGW, + FL( "Sending SIR_HAL_DELBA_IND..." )); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HAL_DELBA_IND_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + limLog( pMac, LOGE, + FL("Posting WDA_DELBA_IND to HAL failed! Reason = %d"), + retCode ); + else + { + // Update LIM's internal cache... + if( eBA_INITIATOR == baDirection) + { + pSta->tcCfg[baTID].fUseBATx = 0; + pSta->tcCfg[baTID].txBufSize = 0; + } + else + { + pSta->tcCfg[baTID].fUseBARx = 0; + pSta->tcCfg[baTID].rxBufSize = 0; + } + + return retCode; + } + +returnFailure: + + // Clean-up... + if( NULL != pDelBAParams ) + vos_mem_free( pDelBAParams ); + + return retCode; + +} + +/** + * @function : limPostSMStateUpdate() + * + * @brief : This function Updates the HAL and Softmac about the change in the STA's SMPS state. + * + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param limMsg - Lim Message structure object with the MimoPSparam in body + * @return None + */ +tSirRetStatus +limPostSMStateUpdate(tpAniSirGlobal pMac, + tANI_U16 staIdx, tSirMacHTMIMOPowerSaveState state) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpSetMIMOPS pMIMO_PSParams; + + msgQ.reserved = 0; + msgQ.type = WDA_SET_MIMOPS_REQ; + + // Allocate for WDA_SET_MIMOPS_REQ + pMIMO_PSParams = vos_mem_malloc(sizeof(tSetMIMOPS)); + if ( NULL == pMIMO_PSParams ) + { + limLog( pMac, LOGP,FL(" AllocateMemory failed")); + return eSIR_MEM_ALLOC_FAILED; + } + + pMIMO_PSParams->htMIMOPSState = state; + pMIMO_PSParams->staIdx = staIdx; + pMIMO_PSParams->fsendRsp = true; + msgQ.bodyptr = pMIMO_PSParams; + msgQ.bodyval = 0; + + limLog( pMac, LOG2, FL( "Sending WDA_SET_MIMOPS_REQ..." )); + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if (eSIR_SUCCESS != retCode) + { + limLog( pMac, LOGP, FL("Posting WDA_SET_MIMOPS_REQ to HAL failed! Reason = %d"), retCode ); + vos_mem_free(pMIMO_PSParams); + return retCode; + } + + return retCode; +} + +void limPktFree ( + tpAniSirGlobal pMac, + eFrameType frmType, + tANI_U8 *pRxPacketInfo, + void *pBody) +{ + (void) pMac; (void) frmType; (void) pRxPacketInfo; (void) pBody; +} + +/** + * limGetBDfromRxPacket() + * + *FUNCTION: + * This function is called to get pointer to Polaris + * Buffer Descriptor containing MAC header & other control + * info from the body of the message posted to LIM. + * + *LOGIC: + * NA + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param body - Received message body + * @param pRxPacketInfo - Pointer to received BD + * @return None + */ + +void +limGetBDfromRxPacket(tpAniSirGlobal pMac, void *body, tANI_U32 **pRxPacketInfo) +{ + *pRxPacketInfo = (tANI_U32 *) body; +} /*** end limGetBDfromRxPacket() ***/ + + + + + +void limRessetScanChannelInfo(tpAniSirGlobal pMac) +{ + vos_mem_set(&pMac->lim.scanChnInfo, sizeof(tLimScanChnInfo), 0); +} + + +void limAddScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 channelId) +{ + tANI_U8 i; + tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE; + + for(i = 0; i < pMac->lim.scanChnInfo.numChnInfo; i++) + { + if(pMac->lim.scanChnInfo.scanChn[i].channelId == channelId) + { + pMac->lim.scanChnInfo.scanChn[i].numTimeScan++; + fFound = eANI_BOOLEAN_TRUE; + break; + } + } + if(eANI_BOOLEAN_FALSE == fFound) + { + if(pMac->lim.scanChnInfo.numChnInfo < SIR_MAX_SUPPORTED_CHANNEL_LIST) + { + pMac->lim.scanChnInfo.scanChn[pMac->lim.scanChnInfo.numChnInfo].channelId = channelId; + pMac->lim.scanChnInfo.scanChn[pMac->lim.scanChnInfo.numChnInfo++].numTimeScan = 1; + } + else + { + PELOGW(limLog(pMac, LOGW, FL(" -- number of channels exceed mac"));) + } + } +} + + +/** + * @function : limIsChannelValidForChannelSwitch() + * + * @brief : This function checks if the channel to which AP + * is expecting us to switch, is a valid channel for us. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param channel - New channel to which we are expected to move + * @return None + */ +tAniBool +limIsChannelValidForChannelSwitch(tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_U8 index; + tANI_U32 validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN; + tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + + if (wlan_cfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + (tANI_U8 *)validChannelList, + (tANI_U32 *)&validChannelListLen) != eSIR_SUCCESS) + { + PELOGE(limLog(pMac, LOGE, FL("could not retrieve valid channel list"));) + return (eSIR_FALSE); + } + + for(index = 0; index < validChannelListLen; index++) + { + if(validChannelList[index] == channel) + return (eSIR_TRUE); + } + + /* channel does not belong to list of valid channels */ + return (eSIR_FALSE); +} + +/**------------------------------------------------------ +\fn __limFillTxControlParams +\brief Fill the message for stopping/resuming tx. + +\param pMac +\param pTxCtrlMsg - Pointer to tx control message. +\param type - Which way we want to stop/ resume tx. +\param mode - To stop/resume. + -------------------------------------------------------*/ +static eHalStatus +__limFillTxControlParams(tpAniSirGlobal pMac, tpTxControlParams pTxCtrlMsg, + tLimQuietTxMode type, tLimControlTx mode) +{ + + //TBD-RAJESH HOW TO GET sessionEntry????? + tpPESession psessionEntry = &pMac->lim.gpSession[0]; + + if (mode == eLIM_STOP_TX) + pTxCtrlMsg->stopTx = eANI_BOOLEAN_TRUE; + else + pTxCtrlMsg->stopTx = eANI_BOOLEAN_FALSE; + + switch (type) + { + case eLIM_TX_ALL: + /** Stops/resumes transmission completely */ + pTxCtrlMsg->fCtrlGlobal = 1; + break; + + case eLIM_TX_BSS_BUT_BEACON: + /** Stops/resumes transmission on a particular BSS. Stopping BSS, doesnt + * stop beacon transmission. + */ + pTxCtrlMsg->ctrlBss = 1; + pTxCtrlMsg->bssBitmap |= (1 << psessionEntry->bssIdx); + break; + + case eLIM_TX_STA: + /** Memory for station bitmap is allocated dynamically in caller of this + * so decode properly here and fill the bitmap. Now not implemented, + * fall through. + */ + case eLIM_TX_BSS: + //Fall thru... + default: + PELOGW(limLog(pMac, LOGW, FL("Invalid case: Not Handled"));) + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/** + * @function : limFrameTransmissionControl() + * + * @brief : This API is called by the user to halt/resume any frame + * transmission from the device. If stopped, all frames will be + * queued starting from hardware. Then back-pressure + * is built till the driver. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ +void limFrameTransmissionControl(tpAniSirGlobal pMac, tLimQuietTxMode type, tLimControlTx mode) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpTxControlParams pTxCtrlMsg; + tSirMsgQ msgQ; + tANI_U8 nBytes = 0; // No of bytes required for station bitmap. + + /** Allocate only required number of bytes for station bitmap + * Make it to align to 4 byte boundary */ + nBytes = (tANI_U8)HALMSG_NUMBYTES_STATION_BITMAP(pMac->lim.maxStation); + + pTxCtrlMsg = vos_mem_malloc(sizeof(*pTxCtrlMsg) + nBytes); + if ( NULL == pTxCtrlMsg ) + { + limLog(pMac, LOGP, FL("AllocateMemory() failed")); + return; + } + + vos_mem_set((void *) pTxCtrlMsg, + (sizeof(*pTxCtrlMsg) + nBytes), 0); + status = __limFillTxControlParams(pMac, pTxCtrlMsg, type, mode); + if (status != eHAL_STATUS_SUCCESS) + { + vos_mem_free(pTxCtrlMsg); + limLog(pMac, LOGP, FL("__limFillTxControlParams failed, status = %d"), status); + return; + } + + msgQ.bodyptr = (void *) pTxCtrlMsg; + msgQ.bodyval = 0; + msgQ.reserved = 0; + msgQ.type = WDA_TRANSMISSION_CONTROL_IND; + + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if(wdaPostCtrlMsg( pMac, &msgQ) != eSIR_SUCCESS) + { + vos_mem_free(pTxCtrlMsg); + limLog( pMac, LOGP, FL("Posting Message to HAL failed")); + return; + } + + if (mode == eLIM_STOP_TX) + { + limLog(pMac, LOG1, FL("Stopping the transmission of all packets, indicated softmac")); + } + else + { + limLog(pMac, LOG1, FL("Resuming the transmission of all packets, indicated softmac")); + } + return; +} + + +/** + * @function : limRestorePreChannelSwitchState() + * + * @brief : This API is called by the user to undo any + * specific changes done on the device during + * channel switch. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +tSirRetStatus +limRestorePreChannelSwitchState(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + tSirRetStatus retCode = eSIR_SUCCESS; + tANI_U32 val = 0; + + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return retCode; + + /* Channel switch should be ready for the next time */ + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT; + + /* Restore the frame transmission, all the time. */ + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + + /* Free to enter BMPS */ + limSendSmePostChannelSwitchInd(pMac); + + //Background scan is now enabled by SME + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + /* Enable background scan if already enabled, else don't bother */ + if ((retCode = wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &val)) != eSIR_SUCCESS) + + { + limLog(pMac, LOGP, FL("could not retrieve Background scan period value")); + return (retCode); + } + + if (val > 0 && TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_BACKGROUND_SCAN_TIMER)); + if(tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restart background scan timer, doing LOGP")); + return (eSIR_FAILURE); + } + + } + } + + /* Enable heartbeat timer */ + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimHeartBeatTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, + psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if((limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) && + (!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + limLog(pMac, LOGP, FL("Could not restart heartbeat timer, doing LOGP")); + return (eSIR_FAILURE); + } + } + return (retCode); +} + + +/**-------------------------------------------- +\fn limRestorePreQuietState +\brief Restore the pre quiet state + +\param pMac +\return NONE +---------------------------------------------*/ +tSirRetStatus limRestorePreQuietState(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + tSirRetStatus retCode = eSIR_SUCCESS; + tANI_U32 val = 0; + + if (pMac->lim.gLimSystemRole != eLIM_STA_ROLE) + return retCode; + + /* Quiet should be ready for the next time */ + psessionEntry->gLimSpecMgmt.quietState = eLIM_QUIET_INIT; + + /* Restore the frame transmission, all the time. */ + if (psessionEntry->gLimSpecMgmt.quietState == eLIM_QUIET_RUNNING) + limFrameTransmissionControl(pMac, eLIM_TX_ALL, eLIM_RESUME_TX); + + + //Background scan is now enabled by SME + if(pMac->lim.gLimBackgroundScanTerminate == FALSE) + { + /* Enable background scan if already enabled, else don't bother */ + if ((retCode = wlan_cfgGetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, + &val)) != eSIR_SUCCESS) + + { + limLog(pMac, LOGP, FL("could not retrieve Background scan period value")); + return (retCode); + } + + if (val > 0 && TX_TIMER_VALID(pMac->lim.limTimers.gLimBackgroundScanTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_BACKGROUND_SCAN_TIMER)); + if(tx_timer_activate(&pMac->lim.limTimers.gLimBackgroundScanTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restart background scan timer, doing LOGP")); + return (eSIR_FAILURE); + } + + } + } + + /* Enable heartbeat timer */ + if (TX_TIMER_VALID(pMac->lim.limTimers.gLimHeartBeatTimer)) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER)); + if(limActivateHearBeatTimer(pMac, psessionEntry) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Could not restart heartbeat timer, doing LOGP")); + return (eSIR_FAILURE); + } + } + return (retCode); +} + + +/** + * @function: limPrepareFor11hChannelSwitch() + * + * @brief : This API is called by the user to prepare for + * 11h channel switch. As of now, the API does + * very minimal work. User can add more into the + * same API if needed. + * LOGIC: + * + * ASSUMPTIONS: + * NA + * + * NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @param psessionEntry + * @return None + */ +void +limPrepareFor11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole != eLIM_STA_ROLE) + return; + + /* Flag to indicate 11h channel switch in progress */ + psessionEntry->gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_RUNNING; + + /* Disable, Stop background scan if enabled and running */ + limDeactivateAndChangeTimer(pMac, eLIM_BACKGROUND_SCAN_TIMER); + + /* Stop heart-beat timer to stop heartbeat disassociation */ + limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry); + + if(pMac->lim.gLimSmeState == eLIM_SME_LINK_EST_WT_SCAN_STATE || + pMac->lim.gLimSmeState == eLIM_SME_CHANNEL_SCAN_STATE) + { + PELOGE(limLog(pMac, LOGE, FL("Posting finish scan as we are in scan state"));) + /* Stop ongoing scanning if any */ + if (GET_LIM_PROCESS_DEFD_MESGS(pMac)) + { + //Set the resume channel to Any valid channel (invalid). + //This will instruct HAL to set it to any previous valid channel. + peSetResumeChannel(pMac, 0, 0); + limSendHalFinishScanReq(pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE); + } + else + { + limRestorePreChannelSwitchState(pMac, psessionEntry); + } + return; + } + else + { + PELOGE(limLog(pMac, LOGE, FL("Not in scan state, start channel switch timer"));) + /** We are safe to switch channel at this point */ + limStopTxAndSwitchChannel(pMac, psessionEntry->peSessionId); + } +} + + + +/**---------------------------------------------------- +\fn limGetNwType + +\brief Get type of the network from data packet or beacon +\param pMac +\param channelNum - Channel number +\param type - Type of packet. +\param pBeacon - Pointer to beacon or probe response + +\return Network type a/b/g. +-----------------------------------------------------*/ +tSirNwType limGetNwType(tpAniSirGlobal pMac, tANI_U8 channelNum, tANI_U32 type, tpSchBeaconStruct pBeacon) +{ + tSirNwType nwType = eSIR_11B_NW_TYPE; + + if (type == SIR_MAC_DATA_FRAME) + { + if ((channelNum > 0) && (channelNum < 15)) + { + nwType = eSIR_11G_NW_TYPE; + } + else + { + nwType = eSIR_11A_NW_TYPE; + } + } + else + { + if ((channelNum > 0) && (channelNum < 15)) + { + int i; + // 11b or 11g packet + // 11g iff extended Rate IE is present or + // if there is an A rate in suppRate IE + for (i = 0; i < pBeacon->supportedRates.numRates; i++) + { + if (sirIsArate(pBeacon->supportedRates.rate[i] & 0x7f)) + { + nwType = eSIR_11G_NW_TYPE; + break; + } + } + if (pBeacon->extendedRatesPresent) + { + PELOG3(limLog(pMac, LOG3, FL("Beacon, nwtype=G"));) + nwType = eSIR_11G_NW_TYPE; + } + } + else + { + // 11a packet + PELOG3(limLog(pMac, LOG3,FL("Beacon, nwtype=A"));) + nwType = eSIR_11A_NW_TYPE; + } + } + return nwType; +} + + +/**--------------------------------------------------------- +\fn limGetChannelFromBeacon +\brief To extract channel number from beacon + +\param pMac +\param pBeacon - Pointer to beacon or probe rsp +\return channel number +-----------------------------------------------------------*/ +tANI_U8 limGetChannelFromBeacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon) +{ + tANI_U8 channelNum = 0; + + if (pBeacon->dsParamsPresent) + channelNum = pBeacon->channelNumber; + else if(pBeacon->HTInfo.present) + channelNum = pBeacon->HTInfo.primaryChannel; + else + channelNum = pBeacon->channelNumber; + + return channelNum; +} + + +/** --------------------------------------------------------- +\fn limSetTspecUapsdMask +\brief This function sets the PE global variable: +\ 1) gUapsdPerAcTriggerEnableMask and +\ 2) gUapsdPerAcDeliveryEnableMask +\ based on the user priority field and direction field +\ in the TS Info Fields. +\ +\ An AC is a trigger-enabled AC if the PSB subfield +\ is set to 1 in the uplink direction. +\ An AC is a delivery-enabled AC if the PSB subfield +\ is set to 1 in the down-link direction. +\ +\param tpAniSirGlobal pMac +\param tSirMacTSInfo pTsInfo +\param tANI_U32 action +\return None + ------------------------------------------------------------*/ +void limSetTspecUapsdMask(tpAniSirGlobal pMac, tSirMacTSInfo *pTsInfo, tANI_U32 action) +{ + tANI_U8 userPrio = (tANI_U8)pTsInfo->traffic.userPrio; + tANI_U16 direction = pTsInfo->traffic.direction; + tANI_U8 ac = upToAc(userPrio); + + limLog(pMac, LOG1, FL(" Set UAPSD mask for AC %d, direction %d, action=%d (1=set,0=clear) "),ac, direction, action ); + + /* Converting AC to appropriate Uapsd Bit Mask + * AC_BE(0) --> UAPSD_BITOFFSET_ACVO(3) + * AC_BK(1) --> UAPSD_BITOFFSET_ACVO(2) + * AC_VI(2) --> UAPSD_BITOFFSET_ACVO(1) + * AC_VO(3) --> UAPSD_BITOFFSET_ACVO(0) + */ + ac = ((~ac) & 0x3); + + if (action == CLEAR_UAPSD_MASK) + { + if (direction == SIR_MAC_DIRECTION_UPLINK) + pMac->lim.gUapsdPerAcTriggerEnableMask &= ~(1 << ac); + else if (direction == SIR_MAC_DIRECTION_DNLINK) + pMac->lim.gUapsdPerAcDeliveryEnableMask &= ~(1 << ac); + else if (direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gUapsdPerAcTriggerEnableMask &= ~(1 << ac); + pMac->lim.gUapsdPerAcDeliveryEnableMask &= ~(1 << ac); + } + } + else if (action == SET_UAPSD_MASK) + { + if (direction == SIR_MAC_DIRECTION_UPLINK) + pMac->lim.gUapsdPerAcTriggerEnableMask |= (1 << ac); + else if (direction == SIR_MAC_DIRECTION_DNLINK) + pMac->lim.gUapsdPerAcDeliveryEnableMask |= (1 << ac); + else if (direction == SIR_MAC_DIRECTION_BIDIR) + { + pMac->lim.gUapsdPerAcTriggerEnableMask |= (1 << ac); + pMac->lim.gUapsdPerAcDeliveryEnableMask |= (1 << ac); + } + } + + limLog(pMac, LOGE, FL("New pMac->lim.gUapsdPerAcTriggerEnableMask = 0x%x "), pMac->lim.gUapsdPerAcTriggerEnableMask ); + limLog(pMac, LOGE, FL("New pMac->lim.gUapsdPerAcDeliveryEnableMask = 0x%x "), pMac->lim.gUapsdPerAcDeliveryEnableMask ); + + return; +} + + + +void limHandleHeartBeatTimeout(tpAniSirGlobal pMac ) +{ + + tANI_U8 i; + for(i =0;i < pMac->lim.maxBssId;i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if(pMac->lim.gpSession[i].bssType == eSIR_IBSS_MODE) + { + limIbssHeartBeatHandle(pMac,&pMac->lim.gpSession[i]); + break; + } + + if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + limHandleHeartBeatFailure(pMac,&pMac->lim.gpSession[i]); + } + } + } + for(i=0; i< pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + if(pMac->lim.gpSession[i].LimHBFailureStatus == eANI_BOOLEAN_TRUE) + { + /* Activate Probe After HeartBeat Timer incase HB Failure detected */ + PELOGW(limLog(pMac, LOGW,FL("Sending Probe for Session: %d"), + i);) + limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_PROBE_AFTER_HB_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to re-activate Probe-after-heartbeat timer")); + limReactivateHeartBeatTimer(pMac, &pMac->lim.gpSession[i]); + } + break; + } + } + } + } +} + +void limHandleHeartBeatTimeoutForSession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if(psessionEntry->valid == TRUE ) + { + if(psessionEntry->bssType == eSIR_IBSS_MODE) + { + limIbssHeartBeatHandle(pMac,psessionEntry); + } + if((psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) && + (psessionEntry->limSystemRole == eLIM_STA_ROLE)) + { + limHandleHeartBeatFailure(pMac,psessionEntry); + } + } + /* In the function limHandleHeartBeatFailure things can change so check for the session entry valid + and the other things again */ + if(psessionEntry->valid == TRUE ) + { + if((psessionEntry->bssType == eSIR_INFRASTRUCTURE_MODE) && + (psessionEntry->limSystemRole == eLIM_STA_ROLE)) + { + if(psessionEntry->LimHBFailureStatus == eANI_BOOLEAN_TRUE) + { + /* Activate Probe After HeartBeat Timer incase HB Failure detected */ + PELOGW(limLog(pMac, LOGW,FL("Sending Probe for Session: %d"), + psessionEntry->bssIdx);) + limDeactivateAndChangeTimer(pMac, eLIM_PROBE_AFTER_HB_TIMER); + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, 0, eLIM_PROBE_AFTER_HB_TIMER)); + if (tx_timer_activate(&pMac->lim.limTimers.gLimProbeAfterHBTimer) != TX_SUCCESS) + { + limLog(pMac, LOGP, FL("Fail to re-activate Probe-after-heartbeat timer")); + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + } + } +} + + +tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0;i < pMac->lim.maxBssId;i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if((pMac->lim.gpSession[i].bssType == eSIR_INFRASTRUCTURE_MODE) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE)) + { + return pMac->lim.gpSession[i].currentOperChannel; + } + } + } + return 0; +} + +void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +{ + + tpPESession psessionEntry; +// tANI_U8 sessionId; + tpAddStaParams pAddStaParams; + + pAddStaParams = (tpAddStaParams)limMsgQ->bodyptr; + + if((psessionEntry = peFindSessionBySessionId(pMac,pAddStaParams->sessionId))==NULL) + { + limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + vos_mem_free(pAddStaParams); + return; + } + if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + (void) limIbssAddStaRsp(pMac, limMsgQ->bodyptr,psessionEntry); +#ifdef FEATURE_WLAN_TDLS + else if(pMac->lim.gLimAddStaTdls) + { + limProcessTdlsAddStaRsp(pMac, limMsgQ->bodyptr, psessionEntry) ; + pMac->lim.gLimAddStaTdls = FALSE ; + } +#endif + else + limProcessMlmAddStaRsp(pMac, limMsgQ,psessionEntry); + +} + + +void limUpdateBeacon(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0;i < pMac->lim.maxBssId;i++) + { + if(pMac->lim.gpSession[i].valid == TRUE ) + { + if( ( (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_IN_IBSS_ROLE) ) + && (eLIM_SME_NORMAL_STATE == pMac->lim.gpSession[i].limSmeState) + ) + { + schSetFixedBeaconFields(pMac,&pMac->lim.gpSession[i]); + limSendBeaconInd(pMac, &pMac->lim.gpSession[i]); + } + else + { + if( (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE)|| + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_STA_ROLE)) + { + + if(pMac->lim.gpSession[i].statypeForBss == STA_ENTRY_SELF) + { + schSetFixedBeaconFields(pMac,&pMac->lim.gpSession[i]); + } + } + } + } + } +} + +void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac) +{ + tANI_U8 i; + tpPESession psessionEntry; + /* Probe response is not received after HB failure. This is handled by LMM sub module. */ + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + psessionEntry = &pMac->lim.gpSession[i]; + if(psessionEntry->LimHBFailureStatus == eANI_BOOLEAN_TRUE) + { + limLog(pMac, LOGE, + FL("Probe_hb_failure: SME %d, MLME %d, HB-Count %d BCN count %d"), + psessionEntry->limSmeState, psessionEntry->limMlmState, + psessionEntry->LimRxedBeaconCntDuringHB, + psessionEntry->currentBssBeaconCnt); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_HB_FAILURE_TIMEOUT, psessionEntry, 0, 0); +#endif + if (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) + { + /* Disconnect even if we have not received a single beacon + * after connection. + */ + if (((!LIM_IS_CONNECTION_ACTIVE(psessionEntry)) || + (0 == psessionEntry->currentBssBeaconCnt)) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)&& + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) + { + limLog(pMac, LOGE, FL("Probe_hb_failure: for session:%d " ),psessionEntry->peSessionId); + /* AP did not respond to Probe Request. Tear down link with it.*/ + limTearDownLinkWithAp(pMac, + psessionEntry->peSessionId, + eSIR_BEACON_MISSED); + pMac->lim.gLimProbeFailureAfterHBfailedCnt++ ; + } + else // restart heartbeat timer + { + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + else + { + limLog(pMac, LOGE, FL("Unexpected wt-probe-timeout in state ")); + limPrintMlmState(pMac, LOGE, psessionEntry->limMlmState); + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + + } + } + } + /* Deactivate Timer ProbeAfterHB Timer -> As its a oneshot timer, need not deactivate the timer */ + // tx_timer_deactivate(&pMac->lim.limTimers.gLimProbeAfterHBTimer); +} + + +/* +* This function assumes there will not be more than one IBSS session active at any time. +*/ +tpPESession limIsIBSSSessionActive(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0;i < pMac->lim.maxBssId;i++) + { + if( (pMac->lim.gpSession[i].valid) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_IN_IBSS_ROLE)) + return (&pMac->lim.gpSession[i]); + } + + return NULL; +} + +tpPESession limIsApSessionActive(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for(i =0;i < pMac->lim.maxBssId;i++) + { + if( (pMac->lim.gpSession[i].valid) && + ( (pMac->lim.gpSession[i].limSystemRole == eLIM_AP_ROLE) || + (pMac->lim.gpSession[i].limSystemRole == eLIM_BT_AMP_AP_ROLE))) + return (&pMac->lim.gpSession[i]); + } + + return NULL; +} + +/**--------------------------------------------------------- +\fn limHandleDeferMsgError +\brief handles error scenario, when the msg can not be deferred. +\param pMac +\param pLimMsg LIM msg, which could not be deferred. +\return void +-----------------------------------------------------------*/ + +void limHandleDeferMsgError(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg) +{ + if(SIR_BB_XPORT_MGMT_MSG == pLimMsg->type) + { + /*Decrement the Pending count before droping */ + limDecrementPendingMgmtCount (pMac); + vos_pkt_return_packet((vos_pkt_t*)pLimMsg->bodyptr); + } + else if(pLimMsg->bodyptr != NULL) + { + vos_mem_free( pLimMsg->bodyptr); + pLimMsg->bodyptr = NULL; + } +} + + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/**--------------------------------------------------------- +\fn limDiagEventReport +\brief This function reports Diag event +\param pMac +\param eventType +\param bssid +\param status +\param reasonCode +\return void +-----------------------------------------------------------*/ +void limDiagEventReport(tpAniSirGlobal pMac, tANI_U16 eventType, tpPESession pSessionEntry, tANI_U16 status, tANI_U16 reasonCode) +{ + tSirMacAddr nullBssid = { 0, 0, 0, 0, 0, 0 }; + WLAN_VOS_DIAG_EVENT_DEF(peEvent, vos_event_wlan_pe_payload_type); + + vos_mem_set(&peEvent, sizeof(vos_event_wlan_pe_payload_type), 0); + + if (NULL == pSessionEntry) + { + vos_mem_copy( peEvent.bssid, nullBssid, sizeof(tSirMacAddr)); + peEvent.sme_state = (tANI_U16)pMac->lim.gLimSmeState; + peEvent.mlm_state = (tANI_U16)pMac->lim.gLimMlmState; + + } + else + { + vos_mem_copy(peEvent.bssid, pSessionEntry->bssId, sizeof(tSirMacAddr)); + peEvent.sme_state = (tANI_U16)pSessionEntry->limSmeState; + peEvent.mlm_state = (tANI_U16)pSessionEntry->limMlmState; + } + peEvent.event_type = eventType; + peEvent.status = status; + peEvent.reason_code = reasonCode; + + WLAN_VOS_DIAG_EVENT_REPORT(&peEvent, EVENT_WLAN_PE); + return; +} + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +void limProcessAddStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +{ + + tpAddStaSelfParams pAddStaSelfParams; + tSirMsgQ mmhMsg; + tpSirSmeAddStaSelfRsp pRsp; + + + pAddStaSelfParams = (tpAddStaSelfParams)limMsgQ->bodyptr; + + pRsp = vos_mem_malloc(sizeof(tSirSmeAddStaSelfRsp)); + if ( NULL == pRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for Add Sta self RSP")); + vos_mem_free(pAddStaSelfParams); + limMsgQ->bodyptr = NULL; + return; + } + + vos_mem_set((tANI_U8*)pRsp, sizeof(tSirSmeAddStaSelfRsp), 0); + + pRsp->mesgType = eWNI_SME_ADD_STA_SELF_RSP; + pRsp->mesgLen = (tANI_U16) sizeof(tSirSmeAddStaSelfRsp); + pRsp->status = pAddStaSelfParams->status; + + vos_mem_copy( pRsp->selfMacAddr, pAddStaSelfParams->selfMacAddr, sizeof(tSirMacAddr) ); + + vos_mem_free(pAddStaSelfParams); + limMsgQ->bodyptr = NULL; + + mmhMsg.type = eWNI_SME_ADD_STA_SELF_RSP; + mmhMsg.bodyptr = pRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} + +void limProcessDelStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +{ + + tpDelStaSelfParams pDelStaSelfParams; + tSirMsgQ mmhMsg; + tpSirSmeDelStaSelfRsp pRsp; + + + pDelStaSelfParams = (tpDelStaSelfParams)limMsgQ->bodyptr; + + pRsp = vos_mem_malloc(sizeof(tSirSmeDelStaSelfRsp)); + if ( NULL == pRsp ) + { + /// Buffer not available. Log error + limLog(pMac, LOGP, FL("call to AllocateMemory failed for Add Sta self RSP")); + vos_mem_free(pDelStaSelfParams); + limMsgQ->bodyptr = NULL; + return; + } + + vos_mem_set((tANI_U8*)pRsp, sizeof(tSirSmeDelStaSelfRsp), 0); + + pRsp->mesgType = eWNI_SME_DEL_STA_SELF_RSP; + pRsp->mesgLen = (tANI_U16) sizeof(tSirSmeDelStaSelfRsp); + pRsp->status = pDelStaSelfParams->status; + + vos_mem_copy( pRsp->selfMacAddr, pDelStaSelfParams->selfMacAddr, sizeof(tSirMacAddr) ); + + vos_mem_free(pDelStaSelfParams); + limMsgQ->bodyptr = NULL; + + mmhMsg.type = eWNI_SME_DEL_STA_SELF_RSP; + mmhMsg.bodyptr = pRsp; + mmhMsg.bodyval = 0; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, NO_SESSION, mmhMsg.type)); + limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + +} + +/*************************************************************** +* tANI_U8 limUnmapChannel(tANI_U8 mapChannel) +* To unmap the channel to reverse the effect of mapping +* a band channel in hal .Mapping was done hal to overcome the +* limitation of the rxbd which use only 4 bit for channel number. +*****************************************************************/ +tANI_U8 limUnmapChannel(tANI_U8 mapChannel) +{ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if( mapChannel > 0 && mapChannel <= aUnsortedChannelListSize ) + if (IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE) + return aUnsortedChannelList[mapChannel -1]; + else +#else + if( mapChannel > 0 && mapChannel <= abChannelSize ) +#endif + return abChannel[mapChannel -1]; + else + return 0; +} + + +v_U8_t* limGetIEPtr(tpAniSirGlobal pMac, v_U8_t *pIes, int length, v_U8_t eid,eSizeOfLenField size_of_len_field) +{ + int left = length; + v_U8_t *ptr = pIes; + v_U8_t elem_id; + v_U16_t elem_len; + + while(left >= (size_of_len_field+1)) + { + elem_id = ptr[0]; + if (size_of_len_field == TWO_BYTE) + { + elem_len = ((v_U16_t) ptr[1]) | (ptr[2]<<8); + } + else + { + elem_len = ptr[1]; + } + + + left -= (size_of_len_field+1); + if(elem_len > left) + { + limLog(pMac, LOGE, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len,left); + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + (size_of_len_field+1)); + } + return NULL; +} + +/* return NULL if oui is not found in ie + return !NULL pointer to vendor IE (starting from 0xDD) if oui is found + */ +v_U8_t* limGetVendorIEOuiPtr(tpAniSirGlobal pMac, tANI_U8 *oui, tANI_U8 oui_size, tANI_U8 *ie, tANI_U16 ie_len) +{ + int left = ie_len; + v_U8_t *ptr = ie; + v_U8_t elem_id, elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + limLog( pMac, LOGE, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + elem_id,elem_len,left); + return NULL; + } + if (SIR_MAC_EID_VENDOR == elem_id) + { + if(memcmp(&ptr[2], oui, oui_size)==0) + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + +//Returns length of P2P stream and Pointer ie passed to this function is filled with noa stream + +v_U8_t limBuildP2pIe(tpAniSirGlobal pMac, tANI_U8 *ie, tANI_U8 *data, tANI_U8 ie_len) +{ + int length = 0; + tANI_U8 *ptr = ie; + + ptr[length++] = SIR_MAC_EID_VENDOR; + ptr[length++] = ie_len + SIR_MAC_P2P_OUI_SIZE; + vos_mem_copy(&ptr[length], SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE); + vos_mem_copy(&ptr[length + SIR_MAC_P2P_OUI_SIZE], data, ie_len); + return (ie_len + SIR_P2P_IE_HEADER_LEN); +} + +//Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream + +v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen) +{ + v_U8_t overFlowP2pStream[SIR_MAX_NOA_ATTR_LEN]; + + if ((noaLen <= (SIR_MAX_NOA_ATTR_LEN+SIR_P2P_IE_HEADER_LEN)) && + (noaLen >= overFlowLen) && (overFlowLen <= SIR_MAX_NOA_ATTR_LEN)) + { + vos_mem_copy(overFlowP2pStream, + noaStream + noaLen - overFlowLen, overFlowLen); + noaStream[noaLen - overFlowLen] = SIR_MAC_EID_VENDOR; + noaStream[noaLen - overFlowLen + 1] = overFlowLen + SIR_MAC_P2P_OUI_SIZE; + vos_mem_copy(noaStream+noaLen-overFlowLen + 2, + SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE); + vos_mem_copy(noaStream+noaLen + 2 + SIR_MAC_P2P_OUI_SIZE - overFlowLen, + overFlowP2pStream, overFlowLen); + } + + return (noaLen + SIR_P2P_IE_HEADER_LEN); + +} + +//Returns length of NoA stream and Pointer pNoaStream passed to this function is filled with noa stream +v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry) +{ + v_U8_t len=0; + + v_U8_t *pBody = pNoaStream; + + + if ( (psessionEntry != NULL) && (psessionEntry->valid) && + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + if ((!(psessionEntry->p2pGoPsUpdate.uNoa1Duration)) && (!(psessionEntry->p2pGoPsUpdate.uNoa2Duration)) + && (!psessionEntry->p2pGoPsUpdate.oppPsFlag) + ) + return 0; //No NoA Descriptor then return 0 + + + pBody[0] = SIR_P2P_NOA_ATTR; + + pBody[3] = psessionEntry->p2pGoPsUpdate.index; + pBody[4] = psessionEntry->p2pGoPsUpdate.ctWin | (psessionEntry->p2pGoPsUpdate.oppPsFlag<<7); + len = 5; + pBody += len; + + + if (psessionEntry->p2pGoPsUpdate.uNoa1Duration) + { + *pBody = psessionEntry->p2pGoPsUpdate.uNoa1IntervalCnt; + pBody += 1; + len +=1; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1Duration); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1Interval); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa1StartTime); + pBody += sizeof(tANI_U32); + len +=4; + + } + + if (psessionEntry->p2pGoPsUpdate.uNoa2Duration) + { + *pBody = psessionEntry->p2pGoPsUpdate.uNoa2IntervalCnt; + pBody += 1; + len +=1; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2Duration); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2Interval); + pBody += sizeof(tANI_U32); + len +=4; + + *((tANI_U32 *)(pBody)) = sirSwapU32ifNeeded(psessionEntry->p2pGoPsUpdate.uNoa2StartTime); + pBody += sizeof(tANI_U32); + len +=4; + + } + + + pBody = pNoaStream + 1; + *((tANI_U16 *)(pBody)) = sirSwapU16ifNeeded(len-3);/*one byte for Attr and 2 bytes for length*/ + + return (len); + + } + return 0; + +} + +void peSetResumeChannel(tpAniSirGlobal pMac, tANI_U16 channel, ePhyChanBondState phyCbState) +{ + + pMac->lim.gResumeChannel = channel; + pMac->lim.gResumePhyCbState = phyCbState; +} + +/*-------------------------------------------------------------------------- + + \brief peGetResumeChannel() - Returns the channel number for scanning, from a valid session. + + This function returns the channel to resume to during link resume. channel id of 0 means HAL will + resume to previous channel before link suspend + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +void peGetResumeChannel(tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState) +{ + + //Rationale - this could be the suspend/resume for assoc and it is essential that + //the new BSS is active for some time. Other BSS was anyway suspended. + //TODO: Comeup with a better alternative. Sending NULL with PM=0 on other BSS means + //there will be trouble. But since it is sent on current channel, it will be missed by peer + //and hence should be ok. Need to discuss this further + if( !limIsInMCC(pMac) ) + { + //Get current active session channel + peGetActiveSessionChannel(pMac, resumeChannel, resumePhyCbState); + } + else + { + *resumeChannel = pMac->lim.gResumeChannel; + *resumePhyCbState = pMac->lim.gResumePhyCbState; + } + return; +} + +tANI_BOOLEAN limIsNOAInsertReqd(tpAniSirGlobal pMac) +{ + tANI_U8 i; + for(i =0; i < pMac->lim.maxBssId; i++) + { + if(pMac->lim.gpSession[i].valid == TRUE) + { + if( (eLIM_AP_ROLE == pMac->lim.gpSession[i].limSystemRole ) + && ( VOS_P2P_GO_MODE == pMac->lim.gpSession[i].pePersona ) + ) + { + return TRUE; + } + } + } + return FALSE; +} + + +tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel) +{ + if(NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(currentChannel)) + { + return eANI_BOOLEAN_TRUE; + } + else + { + return eANI_BOOLEAN_FALSE; + } +} + +/** + * \brief verify the changes in channel bonding + * + * \param pMac Pointer to the global MAC structure + * + * \param psessionEntry session entry + * beaconSecChanWidth Secondary channel width + * advertized in beacon + * currentSecChanWidth Current configured width + * staId Station Id + * \return eSIR_SUCCESS on success, eSIR_FAILURE else + */ +tANI_BOOLEAN limCheckHTChanBondModeChange(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tANI_U8 beaconSecChanWidth, + tANI_U8 currentSecChanWidth, + tANI_U8 staId) +{ + tUpdateVHTOpMode tempParam; + tANI_BOOLEAN fCbMode24G = FALSE; + tANI_BOOLEAN status = eANI_BOOLEAN_FALSE; + + /* Moving from HT40 to HT20 operation*/ + if (((PHY_DOUBLE_CHANNEL_LOW_PRIMARY == currentSecChanWidth) || + (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == currentSecChanWidth)) + && (PHY_SINGLE_CHANNEL_CENTERED == beaconSecChanWidth)) + { + tempParam.opMode = eHT_CHANNEL_WIDTH_20MHZ; + tempParam.staId = staId; + fCbMode24G = TRUE; + } + + /* Moving from HT20 to HT40 operation*/ + if ((( PHY_DOUBLE_CHANNEL_LOW_PRIMARY == beaconSecChanWidth) || + ( PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == beaconSecChanWidth )) + && (PHY_SINGLE_CHANNEL_CENTERED == currentSecChanWidth)) + { + tempParam.opMode = eHT_CHANNEL_WIDTH_40MHZ; + tempParam.staId = staId; + fCbMode24G = TRUE; + } + + if (TRUE == fCbMode24G) + { + VOS_TRACE( VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "Changing CBMODE to = %d staId = %d", + tempParam.opMode, tempParam.staId ); + if( eSIR_SUCCESS == limSendModeUpdate(pMac, &tempParam, psessionEntry)) + status = eANI_BOOLEAN_TRUE; + } + return status; +} + +#ifdef WLAN_FEATURE_11AC +tANI_BOOLEAN limCheckVHTOpModeChange( tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U8 chanWidth, tANI_U8 staId) +{ + tUpdateVHTOpMode tempParam; + + tempParam.opMode = chanWidth; + tempParam.staId = staId; + + limSendModeUpdate( pMac, &tempParam, psessionEntry ); + + return eANI_BOOLEAN_TRUE; +} +#endif + +void limGetShortSlotFromPhyMode(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U32 phyMode, tANI_U8 *pShortSlotEnabled) +{ + tANI_U8 val=0; + + //only 2.4G band should have short slot enable, rest it should be default + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + /* short slot is default in all other modes */ + if ((psessionEntry->pePersona == VOS_STA_SAP_MODE) || + (psessionEntry->pePersona == VOS_IBSS_MODE) || + (psessionEntry->pePersona == VOS_P2P_GO_MODE)) + { + val = true; + } + // Program Polaris based on AP capability + if (psessionEntry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) + { + // Joining BSS. + val = SIR_MAC_GET_SHORT_SLOT_TIME( psessionEntry->limCurrentBssCaps); + } + else if (psessionEntry->limMlmState == eLIM_MLM_WT_REASSOC_RSP_STATE) + { + // Reassociating with AP. + val = SIR_MAC_GET_SHORT_SLOT_TIME( psessionEntry->limReassocBssCaps); + } + } + else + { + /* + * 11B does not short slot and short slot is default + * for 11A mode. Hence, not need to set this bit + */ + val = false; + } + + limLog(pMac, LOG1, FL("phyMode = %u shortslotsupported = %u"), phyMode, val); + *pShortSlotEnabled = val; +} + +void limUtilsframeshtons(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U16 pIn, + tANI_U8 fMsb) +{ + (void)pCtx; +#if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } + else + { + *pOut = ( pIn & 0xff00 ) >> 8; + *( pOut + 1 ) = pIn & 0xff; + } +#else + if ( !fMsb ) + { + *pOut = pIn & 0xff; + *( pOut + 1 ) = ( pIn & 0xff00 ) >> 8; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } +#endif +} + +void limUtilsframeshtonl(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U32 pIn, + tANI_U8 fMsb) +{ + (void)pCtx; +#if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } + else + { + *pOut = ( pIn & 0xff000000 ) >> 24; + *( pOut + 1 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 2 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 3 ) = ( pIn & 0x000000ff ); + } +#else + if ( !fMsb ) + { + *( pOut ) = ( pIn & 0x000000ff ); + *( pOut + 1 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 2 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 3 ) = ( pIn & 0xff000000 ) >> 24; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } +#endif +} + + +/**-------------------------------------------- +\fn limUpdateOBSSScanParams +\brief Updates OBSS SCAN IE parameters to session + +\param psessionEntry - Session Entry +\return NONE +---------------------------------------------*/ +void limUpdateOBSSScanParams(tpPESession psessionEntry , + tDot11fIEOBSSScanParameters *pOBSSScanParameters) +{ + /*If the recieved value is not in the range specified by the Specification + then it will be the default value configured through cfg */ + if (( pOBSSScanParameters->obssScanActiveDwell > + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMIN ) && + ( pOBSSScanParameters->obssScanActiveDwell < + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME_STAMAX)) + { + psessionEntry->obssHT40ScanParam.OBSSScanActiveDwellTime= + pOBSSScanParameters->obssScanActiveDwell; + } + if((pOBSSScanParameters->obssScanPassiveDwell > + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMIN ) && + (pOBSSScanParameters->obssScanPassiveDwell < + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME_STAMAX)) + { + psessionEntry->obssHT40ScanParam.OBSSScanPassiveDwellTime = + pOBSSScanParameters->obssScanPassiveDwell; + } + if((pOBSSScanParameters->bssWidthChannelTransitionDelayFactor > + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STAMIN) && + (pOBSSScanParameters->bssWidthChannelTransitionDelayFactor < + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR_STAMAX)) + { + psessionEntry->obssHT40ScanParam.BSSWidthChannelTransitionDelayFactor = + pOBSSScanParameters->bssWidthChannelTransitionDelayFactor; + } + if((pOBSSScanParameters->obssScanActiveTotalPerChannel > + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMIN) && + (pOBSSScanParameters->obssScanActiveTotalPerChannel < + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL_STAMAX)) + { + psessionEntry->obssHT40ScanParam.OBSSScanActiveTotalPerChannel = + pOBSSScanParameters->obssScanActiveTotalPerChannel; + } + if((pOBSSScanParameters->obssScanPassiveTotalPerChannel > + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMIN) && + (pOBSSScanParameters->obssScanPassiveTotalPerChannel < + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL_STAMAX)) + { + psessionEntry->obssHT40ScanParam.OBSSScanPassiveTotalPerChannel = + pOBSSScanParameters->obssScanPassiveTotalPerChannel; + } + if((pOBSSScanParameters->bssChannelWidthTriggerScanInterval > + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMIN) && + (pOBSSScanParameters->bssChannelWidthTriggerScanInterval < + WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL_STAMAX)) + { + psessionEntry->obssHT40ScanParam.BSSChannelWidthTriggerScanInterval = + pOBSSScanParameters->bssChannelWidthTriggerScanInterval; + } + if((pOBSSScanParameters->obssScanActivityThreshold > + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMIN )&& + (pOBSSScanParameters->obssScanActivityThreshold < + WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD_STAMAX)) + { + psessionEntry->obssHT40ScanParam.OBSSScanActivityThreshold = + pOBSSScanParameters->obssScanActivityThreshold; + } +} + +#ifdef WLAN_FEATURE_11W +void limPmfSaQueryTimerHandler(void *pMacGlobal, tANI_U32 param) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)pMacGlobal; + tPmfSaQueryTimerId timerId; + tpPESession psessionEntry; + tpDphHashNode pSta; + tANI_U32 maxRetries; + + limLog(pMac, LOG1, FL("SA Query timer fires")); + timerId.value = param; + + // Check that SA Query is in progress + if ((psessionEntry = peFindSessionBySessionId( + pMac, timerId.fields.sessionId)) == NULL) + { + limLog(pMac, LOGE, FL("Session does not exist for given session ID %d"), + timerId.fields.sessionId); + return; + } + if ((pSta = dphGetHashEntry(pMac, timerId.fields.peerIdx, + &psessionEntry->dph.dphHashTable)) == NULL) + { + limLog(pMac, LOGE, FL("Entry does not exist for given peer index %d"), + timerId.fields.peerIdx); + return; + } + if (DPH_SA_QUERY_IN_PROGRESS != pSta->pmfSaQueryState) + return; + + // Increment the retry count, check if reached maximum + if (wlan_cfgGetInt(pMac, WNI_CFG_PMF_SA_QUERY_MAX_RETRIES, + &maxRetries) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Could not retrieve PMF SA Query maximum retries value")); + pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + return; + } + pSta->pmfSaQueryRetryCount++; + if (pSta->pmfSaQueryRetryCount >= maxRetries) + { + limLog(pMac, LOGE, + FL("SA Query timed out,Deleting STA: " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pSta->staAddr)); + limSendDisassocMgmtFrame(pMac, + eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON, + pSta->staAddr, psessionEntry, FALSE); + limTriggerSTAdeletion(pMac, pSta, psessionEntry); + pSta->pmfSaQueryState = DPH_SA_QUERY_TIMED_OUT; + return; + } + + // Retry SA Query + limSendSaQueryRequestFrame(pMac, (tANI_U8 *)&(pSta->pmfSaQueryCurrentTransId), + pSta->staAddr, psessionEntry); + pSta->pmfSaQueryCurrentTransId++; + if (tx_timer_activate(&pSta->pmfSaQueryTimer) != TX_SUCCESS) + { + limLog(pMac, LOGE, FL("PMF SA Query timer activation failed!")); + pSta->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS; + } +} +#endif + +/** --------------------------------------------------------- +\fn limProcessChannelSwitchSuspendLink +\brief This function call channel switch functions based on + the gLimChannelSwitch.state. After function return it + reset the state to eLIM_CHANNEL_SWITCH_IDLE. + If gLimChannelSwitch.state is non-identified then + print error log as well as restore back the + pre-channelSwitch. +\param tpAniSirGlobal pMac +\param eHalStatus status +\param tANI_U32 *ctx +\return None + ------------------------------------------------------------*/ +static void +limProcessChannelSwitchSuspendLink(tpAniSirGlobal pMac, + eHalStatus status, + tANI_U32 *ctx) +{ + tpPESession pSessionEntry = (tpPESession)ctx; + + if ( eHAL_STATUS_SUCCESS != status ) + { + limLog(pMac, LOGE, + FL("Suspend link failed. still proceeding ")); + } + if (NULL == pSessionEntry ) + { + limLog(pMac, LOGE, FL("pSessionEntry is null pointer ")); + return; + } + + switch(pSessionEntry->gLimChannelSwitch.state) + { + case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY: + PELOGW(limLog(pMac, LOGW, + FL("CHANNEL_SWITCH_PRIMARY_ONLY "));) + limSwitchPrimaryChannel(pMac, + pSessionEntry->gLimChannelSwitch.primaryChannel, + pSessionEntry); + pSessionEntry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_IDLE; + break; + + case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY: + PELOGW(limLog(pMac, LOGW, + FL("CHANNEL_SWITCH_PRIMARY_AND_SECONDARY"));) + limSwitchPrimarySecondaryChannel(pMac, pSessionEntry, + pSessionEntry->gLimChannelSwitch.primaryChannel, + pSessionEntry->gLimChannelSwitch.secondarySubBand); + pSessionEntry->gLimChannelSwitch.state = + eLIM_CHANNEL_SWITCH_IDLE; + break; + + default: + PELOGE(limLog(pMac, LOGW, FL("incorrect state %d"), + pSessionEntry->gLimChannelSwitch.state);) + if (limRestorePreChannelSwitchState(pMac, + pSessionEntry) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, + FL("Could not restore pre-channelSwitch " + "(11h) state, resetting the system")); + } + } +} + +/** --------------------------------------------------------- +\fn limInitOBSSScanParams +\brief This function Initializes the OBSS Scan Parameters +\param tpAniSirGlobal pMac +\param tpPESession pSessionEntry +\return None + ------------------------------------------------------------*/ + +void limInitOBSSScanParams(tpAniSirGlobal pMac, + tpPESession psessionEntry) +{ + tANI_U32 cfgValue; + + if (wlan_cfgGetInt(pMac, WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME, + &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve " + "WNI_CFG_OBSS_HT40_SCAN_ACTIVE_DWELL_TIME value")); + return ; + } + psessionEntry->obssHT40ScanParam.OBSSScanActiveDwellTime = cfgValue; + + if (wlan_cfgGetInt(pMac, WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME, + &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve " + "WNI_CFG_OBSS_HT40_SCAN_PASSIVE_DWELL_TIME value")); + return ; + } + psessionEntry->obssHT40ScanParam.OBSSScanPassiveDwellTime = cfgValue; + + if (wlan_cfgGetInt(pMac, WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve " + "WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL value")); + return ; + } + psessionEntry->obssHT40ScanParam.BSSChannelWidthTriggerScanInterval + = cfgValue; + if (wlan_cfgGetInt(pMac, + WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL, + &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve" + "WNI_CFG_OBSS_HT40_SCAN_ACTIVE_TOTAL_PER_CHANNEL value")); + return ; + } + psessionEntry->obssHT40ScanParam.OBSSScanActiveTotalPerChannel = + cfgValue; + if (wlan_cfgGetInt(pMac, + WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL, &cfgValue) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve" + "WNI_CFG_OBSS_HT40_SCAN_PASSIVE_TOTAL_PER_CHANNEL value")); + return ; + } + psessionEntry->obssHT40ScanParam.OBSSScanPassiveTotalPerChannel = + cfgValue; + + if (wlan_cfgGetInt(pMac, + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR, &cfgValue) + != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve" + "WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR value")); + return ; + } + psessionEntry->obssHT40ScanParam.BSSWidthChannelTransitionDelayFactor = + cfgValue; + + + if (wlan_cfgGetInt(pMac, WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD , + &cfgValue) != eSIR_SUCCESS) + { + limLog(pMac, LOGE, FL("Fail to retrieve " + "WNI_CFG_OBSS_HT40_SCAN_ACTIVITY_THRESHOLD value")); + return ; + } + psessionEntry->obssHT40ScanParam.OBSSScanActivityThreshold = cfgValue; +} + +const char * lim_ScanTypetoString(const v_U8_t scanType) +{ + switch (scanType) + { + CASE_RETURN_STRING( eSIR_PASSIVE_SCAN ); + CASE_RETURN_STRING( eSIR_ACTIVE_SCAN ); + CASE_RETURN_STRING( eSIR_BEACON_TABLE ); + default: + return "Unknown ScanType"; + } +} + +const char * lim_BssTypetoString(const v_U8_t bssType) +{ + switch (bssType) + { + CASE_RETURN_STRING( eSIR_INFRASTRUCTURE_MODE ); + CASE_RETURN_STRING( eSIR_INFRA_AP_MODE ); + CASE_RETURN_STRING( eSIR_IBSS_MODE ); + CASE_RETURN_STRING( eSIR_BTAMP_STA_MODE ); + CASE_RETURN_STRING( eSIR_BTAMP_AP_MODE ); + CASE_RETURN_STRING( eSIR_AUTO_MODE ); + default: + return "Unknown BssType"; + } +} + +const char *lim_BackgroundScanModetoString(const v_U8_t mode) +{ + switch (mode) + { + CASE_RETURN_STRING( eSIR_AGGRESSIVE_BACKGROUND_SCAN ); + CASE_RETURN_STRING( eSIR_NORMAL_BACKGROUND_SCAN ); + CASE_RETURN_STRING( eSIR_ROAMING_SCAN ); + default: + return "Unknown BgScanMode"; + } +} + +#ifdef WLAN_FEATURE_11W +/** + * + * \brief This function is called by various LIM modules to correctly set + * the Protected bit in the Frame Control Field of the 802.11 frame MAC header + * + * + * \param pMac Pointer to Global MAC structure + * + * \param psessionEntry Pointer to session corresponding to the connection + * + * \param peer Peer address of the STA to which the frame is to be sent + * + * \param pMacHdr Pointer to the frame MAC header + * + * \return nothing + * + * + */ +void +limSetProtectedBit(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacAddr peer, + tpSirMacMgmtHdr pMacHdr) +{ + tANI_U16 aid; + tpDphHashNode pStaDs; + + if( (psessionEntry->limSystemRole == eLIM_AP_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) ) + { + + pStaDs = dphLookupHashEntry( pMac, peer, &aid, + &psessionEntry->dph.dphHashTable ); + if( pStaDs != NULL ) + /* rmfenabled will be set at the time of addbss. + * but sometimes EAP auth fails and keys are not + * installed then if we send any management frame + * like deauth/disassoc with this bit set then + * firmware crashes. so check for keys are + * installed or not also before setting the bit + */ + if (pStaDs->rmfEnabled && pStaDs->isKeyInstalled) + pMacHdr->fc.wep = 1; + } + else if ( psessionEntry->limRmfEnabled && psessionEntry->isKeyInstalled) + pMacHdr->fc.wep = 1; +} /*** end limSetProtectedBit() ***/ +#endif + +tANI_U8* limGetIePtr(v_U8_t *pIes, int length, v_U8_t eid) +{ + int left = length; + tANI_U8 *ptr = pIes; + tANI_U8 elem_id,elem_len; + + while (left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + + if (elem_len > left) + { + VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("****Invalid IEs eid = %d elem_len=%d left=%d\n*****"), + eid,elem_len,left); + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} + + +void limParseBeaconForTim(tpAniSirGlobal pMac,tANI_U8* pRxPacketInfo, tpPESession psessionEntry) +{ + + tANI_U32 nPayload; + tANI_U8 *pPayload; + tANI_U8 *ieptr; + tSirMacTim *tim; + + pPayload = WDA_GET_RX_MPDU_DATA( pRxPacketInfo ); + nPayload = WDA_GET_RX_PAYLOAD_LEN( pRxPacketInfo ); + + if (nPayload < (SIR_MAC_B_PR_SSID_OFFSET + SIR_MAC_MIN_IE_LEN)) + { + limLog(pMac, LOGE, FL("Beacon length too short to parse")); + return; + } + + if (NULL != + (ieptr = limGetIePtr((pPayload + SIR_MAC_B_PR_SSID_OFFSET), + nPayload, SIR_MAC_TIM_EID))) + { + /* Ignore EID and Length field*/ + tim = (tSirMacTim *)(ieptr + 2); + + vos_mem_copy(( tANI_U8* )&psessionEntry->lastBeaconTimeStamp, + ( tANI_U8* )pPayload, sizeof(tANI_U64)); + if (tim->dtimCount >= MAX_DTIM_COUNT) + tim->dtimCount = DTIM_COUNT_DEFAULT; + if (tim->dtimPeriod >= MAX_DTIM_PERIOD) + tim->dtimPeriod = DTIM_PERIOD_DEFAULT; + psessionEntry->lastBeaconDtimCount = tim->dtimCount; + psessionEntry->lastBeaconDtimPeriod = tim->dtimPeriod; + psessionEntry->currentBssBeaconCnt++; + + limLog(pMac, LOG1, + FL("currentBssBeaconCnt %d lastBeaconDtimCount %d lastBeaconDtimPeriod %d"), + psessionEntry->currentBssBeaconCnt, psessionEntry->lastBeaconDtimCount, + psessionEntry->lastBeaconDtimPeriod); + + } + return; +} + +void limUpdateMaxRateFlag(tpAniSirGlobal pMac, + tANI_U8 smeSessionId, + tANI_U32 maxRateFlag) +{ + tpSirSmeUpdateMaxRateParams pRsp; + tSirMsgQ msg; + + pRsp = vos_mem_malloc(sizeof(tSirSmeUpdateMaxRateParams)); + if (NULL == pRsp) + { + limLog(pMac, LOGP, FL("Memory allocation failed")); + return; + } + vos_mem_set((tANI_U8*)pRsp, sizeof(tSirSmeUpdateMaxRateParams), 0); + pRsp->maxRateFlag = maxRateFlag; + pRsp->smeSessionId = smeSessionId; + msg.type = eWNI_SME_UPDATE_MAX_RATE_IND; + msg.bodyptr = pRsp; + msg.bodyval = 0; + limSysProcessMmhMsgApi(pMac, &msg, ePROT); + return; +} + +void limDecrementPendingMgmtCount (tpAniSirGlobal pMac) +{ + if( pMac->sys.gSysBbtPendingMgmtCount ) + { + vos_spin_lock_acquire( &pMac->sys.lock ); + pMac->sys.gSysBbtPendingMgmtCount--; + vos_spin_lock_release( &pMac->sys.lock ); + } + else + limLog(pMac, LOGW, FL("Pending Management count going negative")); +} + +eHalStatus limTxBdComplete(tpAniSirGlobal pMac, void *pData) +{ + tpSirTxBdStatus pTxBdStatus; + + if (!pData) + { + limLog(pMac, LOGE, FL("pData is NULL")); + return eHAL_STATUS_FAILURE; + } + + pTxBdStatus = (tpSirTxBdStatus) pData; + + limLog(pMac, LOG1, FL("txBdToken %u, txBdStatus %u"), + pTxBdStatus->txBdToken, pTxBdStatus->txCompleteStatus); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus limAssocRspTxCompleteCnf(tpAniSirGlobal pMac, void *pData) +{ + tpSirTxBdStatus pTxBdStatus; + tpDphHashNode pStaDs; + tpPESession psessionEntry; + VOS_STATUS vosStatus; + vos_list_node_t *pNode= NULL, *pNext = NULL; + assoc_rsp_tx_context *tmp_tx_context = NULL; + + if (!pData) + { + limLog(pMac, LOGE, FL("pData is NULL")); + return eHAL_STATUS_FAILURE; + } + + pTxBdStatus = (tpSirTxBdStatus) pData; + + limLog(pMac, LOG1, FL("txBdToken %u, txBdStatus %u"), + pTxBdStatus->txBdToken, pTxBdStatus->txCompleteStatus); + + vos_list_peek_front(&pMac->assoc_rsp_completion_list, + &pNode); + + while(pNode) + { + tmp_tx_context = container_of(pNode, assoc_rsp_tx_context, node); + if (tmp_tx_context->txBdToken != pTxBdStatus->txBdToken) + { + limLog(pMac, LOG1, FL("expecting txBdToken %u, got txBdToken %u"), + tmp_tx_context->txBdToken, pTxBdStatus->txBdToken); + + vosStatus = vos_list_peek_next ( + &pMac->assoc_rsp_completion_list, + pNode, &pNext ); + pNode = pNext; + pNext = NULL; + } + else + { + limLog(pMac, LOG1, FL("expecting txBdToken %u, got txBdToken %u"), + tmp_tx_context->txBdToken, pTxBdStatus->txBdToken); + break; + } + } + + if (!tmp_tx_context) { + limLog(pMac, LOGE, FL("context is NULL")); + return eHAL_STATUS_SUCCESS; + } + psessionEntry = peFindSessionBySessionId(pMac, tmp_tx_context->psessionID); + if (!psessionEntry) { + limLog(pMac, LOGE, FL("failed to get psession pointer")); + vos_list_remove_node(&pMac->assoc_rsp_completion_list, + pNode); + vos_mem_free(tmp_tx_context); + return eHAL_STATUS_SUCCESS; + } + pStaDs = dphGetHashEntry(pMac, tmp_tx_context->staId, + &psessionEntry->dph.dphHashTable); + if (pStaDs == NULL) + { + limLog(pMac, LOGW, + FL("STA context not found")); + vos_list_remove_node(&pMac->assoc_rsp_completion_list, + pNode); + vos_mem_free(tmp_tx_context); + + return eHAL_STATUS_SUCCESS; + } + + /* Receive path cleanup */ + limCleanupRxPath(pMac, pStaDs, psessionEntry); + vos_list_remove_node(&pMac->assoc_rsp_completion_list, + pNode); + vos_mem_free(tmp_tx_context); + + return eHAL_STATUS_SUCCESS; +} +/** + * lim_is_robust_mgmt_action_frame() - Check if action catagory is + * robust action frame + * @action_catagory: Action frame catagory. + * + * This function is used to check if given action catagory is robust + * action frame. + * + * Return: bool + */ +bool lim_is_robust_mgmt_action_frame(uint8 action_catagory) +{ + switch (action_catagory) { + /* + * NOTE: This function doesn't take care of the DMG + * (Directional Multi-Gigatbit) BSS case as 8011ad + * support is not yet added. In future, if the support + * is required then this function need few more arguments + * and little change in logic. + */ + case SIR_MAC_ACTION_SPECTRUM_MGMT: + case SIR_MAC_ACTION_QOS_MGMT: + case SIR_MAC_ACTION_DLP: + case SIR_MAC_ACTION_BLKACK: + case SIR_MAC_ACTION_RRM: + case SIR_MAC_ACTION_FAST_BSS_TRNST: + case SIR_MAC_ACTION_SA_QUERY: + case SIR_MAC_ACTION_PROT_DUAL_PUB: + case SIR_MAC_ACTION_WNM: + case SIR_MAC_ACITON_MESH: + case SIR_MAC_ACTION_MHF: + case SIR_MAC_ACTION_FST: + return true; + default: + VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL("non-PMF action category[%d] "), + action_catagory); + break; + } + return false; +} + +/** + * lim_compute_ext_cap_ie_length - compute the length of ext cap ie + * based on the bits set + * @ext_cap: extended IEs structure + * + * Return: length of the ext cap ie, 0 means should not present + */ +tANI_U8 lim_compute_ext_cap_ie_length (tDot11fIEExtCap *ext_cap) { + tANI_U8 i = DOT11F_IE_EXTCAP_MAX_LEN; + + while (i) { + if (ext_cap->bytes[i-1]) { + break; + } + i --; + } + + return i; +} + +/** + * lim_update_caps_info_for_bss - Update capability info for this BSS + * + * @mac_ctx: mac context + * @caps: Pointer to capability info to be updated + * @bss_caps: Capability info of the BSS + * + * Update the capability info in Assoc/Reassoc request frames and reset + * the spectrum management, short preamble, immediate block ack bits + * if the BSS doesnot support it + * + * Return: None + */ +void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx, + uint16_t *caps, uint16_t bss_caps) +{ + if (!(bss_caps & LIM_SPECTRUM_MANAGEMENT_BIT_MASK)) { + *caps &= (~LIM_SPECTRUM_MANAGEMENT_BIT_MASK); + limLog(mac_ctx, LOG1, FL("Clearing spectrum management:no AP support")); + } + + if (!(bss_caps & LIM_SHORT_PREAMBLE_BIT_MASK)) { + *caps &= (~LIM_SHORT_PREAMBLE_BIT_MASK); + limLog(mac_ctx, LOG1, FL("Clearing short preamble:no AP support")); + } + + if (!(bss_caps & LIM_IMMEDIATE_BLOCK_ACK_MASK)) { + *caps &= (~LIM_IMMEDIATE_BLOCK_ACK_MASK); + limLog(mac_ctx, LOG1, FL("Clearing Immed Blk Ack:no AP support")); + } +} +#ifdef SAP_AUTH_OFFLOAD +/** + * _sap_offload_parse_assoc_req - Parse assoc request and store it. + * + * @pmac: mac context + * @assoc_req: Assoc request + * @add_sta_req: Add Sta request + * + * This function process recieved add sta message and store it as + * sta ds entry. This function will add this sta entry to DPH as well. + * + * Return: DPH hash node + */ +static tpDphHashNode +_sap_offload_parse_assoc_req(tpAniSirGlobal pmac, + tpSirAssocReq assoc_req, + tSapOfldAddStaIndMsg *add_sta_req) +{ + tpSirMacAssocReqFrame mac_assoc_req = NULL; + tpSirAssocReq temp_assoc_req; + tSirRetStatus status; + tpDphHashNode sta_ds = NULL; + uint8_t *frame_body = NULL; + + tpPESession session_entry = limIsApSessionActive(pmac); + + if (session_entry == NULL) + { + PELOGE(limLog(pmac, LOGE, FL(" Session not found"));) + return NULL; + } + + /* Update Attribute and Remove IE for + * Software AP Authentication Offload + */ + frame_body = (tANI_U8 *)add_sta_req->bufp; + mac_assoc_req = (tpSirMacAssocReqFrame)frame_body; + mac_assoc_req->capabilityInfo.privacy = 0; + + status = sirConvertAssocReqFrame2Struct(pmac, + frame_body, + add_sta_req->data_len, + assoc_req); + if (status != eSIR_SUCCESS) + { + limLog(pmac, LOGW, FL("sap_offload_add_sta_req parse error")); + goto error; + } + /* For software AP Auth Offload feature + * Host will take it as none security station + * Force change to none security + */ + assoc_req->rsnPresent = 0; + assoc_req->wpaPresent = 0; + + sta_ds = dphAddHashEntry(pmac, + add_sta_req->peer_macaddr, + add_sta_req->assoc_id, + &session_entry->dph.dphHashTable); + if (sta_ds == NULL) + { + /* Could not add hash table entry at DPH */ + limLog(pmac, LOGE, + FL("could not add hash entry at DPH for aid=%d, MacAddr:" + MAC_ADDRESS_STR), + add_sta_req->assoc_id,MAC_ADDR_ARRAY(add_sta_req->peer_macaddr)); + goto error; + } + + if (session_entry->parsedAssocReq != NULL) + { + temp_assoc_req = session_entry->parsedAssocReq[sta_ds->assocId]; + if (temp_assoc_req != NULL) + { + if (temp_assoc_req->assocReqFrame) + { + vos_mem_free(temp_assoc_req->assocReqFrame); + temp_assoc_req->assocReqFrame = NULL; + temp_assoc_req->assocReqFrameLength = 0; + } + vos_mem_free(temp_assoc_req); + temp_assoc_req = NULL; + } + session_entry->parsedAssocReq[sta_ds->assocId] = assoc_req; + } +error: + return sta_ds; +} + +/** + * _sap_offload_parse_sta_capability - Parse sta caps from assoc request + * + * @sta_ds: STA state node + * @assoc_req: Assoc request + * @add_sta_req: Add Sta request + * + * This function process recieved add sta message and store station's caps + * in station ds entry. + * + * Return: none + */ +static void +_sap_offload_parse_sta_capability(tpDphHashNode sta_ds, + tpSirAssocReq assoc_req, + tSapOfldAddStaIndMsg *add_sta_req) + +{ + + sta_ds->mlmStaContext.htCapability = assoc_req->HTCaps.present; +#ifdef WLAN_FEATURE_11AC + sta_ds->mlmStaContext.vhtCapability = assoc_req->VHTCaps.present; +#endif + sta_ds->qos.addtsPresent = (assoc_req->addtsPresent==0) ? false : true; + sta_ds->qos.addts = assoc_req->addtsReq; + sta_ds->qos.capability = assoc_req->qosCapability; + sta_ds->versionPresent = 0; + /* short slot and short preamble should be + * updated before doing limaddsta + */ + sta_ds->shortPreambleEnabled = + (tANI_U8)assoc_req->capabilityInfo.shortPreamble; + sta_ds->shortSlotTimeEnabled = + (tANI_U8)assoc_req->capabilityInfo.shortSlotTime; + + sta_ds->valid = 0; + /* The Auth Type of Software AP Authentication Offload + * is always Open System is host side + */ + sta_ds->mlmStaContext.authType = eSIR_OPEN_SYSTEM; + sta_ds->staType = STA_ENTRY_PEER; + + /* Assoc Response frame to requesting STA */ + sta_ds->mlmStaContext.subType = 0; + + sta_ds->mlmStaContext.listenInterval = assoc_req->listenInterval; + sta_ds->mlmStaContext.capabilityInfo = assoc_req->capabilityInfo; + + /* The following count will be used to knock-off the station + * if it doesn't come back to receive the buffered data. + * The AP will wait for numTimSent number of beacons after + * sending TIM information for the station, before assuming that + * the station is no more associated and disassociates it + */ + + /* timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/ + sta_ds->timWaitCount = + (tANI_U8)GET_TIM_WAIT_COUNT(assoc_req->listenInterval); + + /* Initialise the Current successful + * MPDU's tranfered to this STA count as 0 + */ + sta_ds->curTxMpduCnt = 0; +} + +/** + * _sap_offload_parse_sta_vht - Parse sta's HT/VHT caps from assoc request + * + * @pmac: mac context + * @sta_ds: STA state node + * @assoc_req: Assoc request + * + * This function process recieved add sta message and store station's HT and + * and VHT caps and store them in station ds entry. + * + * Return: tSirRetStatus + */ +static tSirRetStatus +_sap_offload_parse_sta_vht(tpAniSirGlobal pmac, + tpDphHashNode sta_ds, + tpSirAssocReq assoc_req) +{ + tpPESession session_entry = limIsApSessionActive(pmac); + + if (IS_DOT11_MODE_HT(session_entry->dot11mode) && + assoc_req->HTCaps.present && assoc_req->wmeInfoPresent) + { + sta_ds->htGreenfield = (tANI_U8)assoc_req->HTCaps.greenField; + sta_ds->htAMpduDensity = assoc_req->HTCaps.mpduDensity; + sta_ds->htDsssCckRate40MHzSupport = + (tANI_U8)assoc_req->HTCaps.dsssCckMode40MHz; + sta_ds->htLsigTXOPProtection = + (tANI_U8)assoc_req->HTCaps.lsigTXOPProtection; + sta_ds->htMaxAmsduLength = + (tANI_U8)assoc_req->HTCaps.maximalAMSDUsize; + sta_ds->htMaxRxAMpduFactor = assoc_req->HTCaps.maxRxAMPDUFactor; + sta_ds->htMIMOPSState = assoc_req->HTCaps.mimoPowerSave; + sta_ds->htShortGI20Mhz = (tANI_U8)assoc_req->HTCaps.shortGI20MHz; + sta_ds->htShortGI40Mhz = (tANI_U8)assoc_req->HTCaps.shortGI40MHz; + sta_ds->htSupportedChannelWidthSet = + (tANI_U8)assoc_req->HTCaps.supportedChannelWidthSet; + /* peer just follows AP; so when we are softAP/GO, + * we just store our session entry's secondary channel offset here + * in peer INFRA STA. However, if peer's 40MHz channel width support + * is disabled then secondary channel will be zero + */ + sta_ds->htSecondaryChannelOffset = + (sta_ds->htSupportedChannelWidthSet) ? + session_entry->htSecondaryChannelOffset : 0; +#ifdef WLAN_FEATURE_11AC + if (assoc_req->operMode.present) + { + sta_ds->vhtSupportedChannelWidthSet = + (tANI_U8)((assoc_req->operMode.chanWidth == + eHT_CHANNEL_WIDTH_80MHZ) ? + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ : + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ); + sta_ds->htSupportedChannelWidthSet = + (tANI_U8)(assoc_req->operMode.chanWidth ? + eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ); + } + else if (assoc_req->VHTCaps.present) + { + /* Check if STA has enabled it's channel bonding mode. + * If channel bonding mode is enabled, we decide based on + * SAP's current configuration else, we set it to VHT20. + */ + sta_ds->vhtSupportedChannelWidthSet = + (tANI_U8)((sta_ds->htSupportedChannelWidthSet == + eHT_CHANNEL_WIDTH_20MHZ) ? + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ : + session_entry->vhtTxChannelWidthSet ); + sta_ds->htMaxRxAMpduFactor = assoc_req->VHTCaps.maxAMPDULenExp; + } + + /* Lesser among the AP and STA bandwidth of operation. */ + sta_ds->htSupportedChannelWidthSet = + (sta_ds->htSupportedChannelWidthSet < + session_entry->htSupportedChannelWidthSet) ? + sta_ds->htSupportedChannelWidthSet : + session_entry->htSupportedChannelWidthSet ; +#endif + sta_ds->baPolicyFlag = 0xFF; + sta_ds->htLdpcCapable = (tANI_U8)assoc_req->HTCaps.advCodingCap; + } + + if (assoc_req->VHTCaps.present && assoc_req->wmeInfoPresent) + sta_ds->vhtLdpcCapable = (tANI_U8)assoc_req->VHTCaps.ldpcCodingCap; + + if (!assoc_req->wmeInfoPresent) + { + sta_ds->mlmStaContext.htCapability = 0; +#ifdef WLAN_FEATURE_11AC + sta_ds->mlmStaContext.vhtCapability = 0; +#endif + } +#ifdef WLAN_FEATURE_11AC + if (limPopulateMatchingRateSet(pmac, + sta_ds, + &(assoc_req->supportedRates), + &(assoc_req->extendedRates), + assoc_req->HTCaps.supportedMCSSet, + &(assoc_req->propIEinfo.propRates), + session_entry , &assoc_req->VHTCaps) + != eSIR_SUCCESS) + { +#else + if (limPopulateMatchingRateSet(pmac, + sta_ds, + &(assoc_req->supportedRates), + &(assoc_req->extendedRates), + assoc_req->HTCaps.supportedMCSSet, + &(assoc_req->propIEinfo.propRates), + session_entry) != eSIR_SUCCESS) + { +#endif + limLog(pmac, LOGE, + FL("Rate set mismatched for aid=%d, MacAddr: " + MAC_ADDRESS_STR), + sta_ds->assocId, MAC_ADDR_ARRAY(sta_ds->staAddr)); + goto error; + } + return eSIR_SUCCESS; +error: + return eSIR_FAILURE; +} + +/** + * _sap_offload_parse_sta_qos - Parse sta's QOS caps from assoc request + * + * @pmac: mac context + * @sta_ds: STA state node + * @assoc_req: Assoc request + * + * This function process recieved add sta message and store station's QOS + * store them in station ds entry. + * + * Return: none + */ +static void + _sap_offload_parse_sta_qos(tpAniSirGlobal pmac, + tpDphHashNode sta_ds, + tpSirAssocReq assoc_req) +{ + tHalBitVal qos_mode; + tHalBitVal wsm_mode, wme_mode; + tpPESession session_entry = limIsApSessionActive(pmac); + + limGetQosMode(session_entry, &qos_mode); + sta_ds->qosMode = eANI_BOOLEAN_FALSE; + sta_ds->lleEnabled = eANI_BOOLEAN_FALSE; + + if (assoc_req->capabilityInfo.qos && (qos_mode == eHAL_SET)) + { + sta_ds->lleEnabled = eANI_BOOLEAN_TRUE; + sta_ds->qosMode = eANI_BOOLEAN_TRUE; + } + + sta_ds->wmeEnabled = eANI_BOOLEAN_FALSE; + sta_ds->wsmEnabled = eANI_BOOLEAN_FALSE; + limGetWmeMode(session_entry, &wme_mode); + if ((!sta_ds->lleEnabled) && assoc_req->wmeInfoPresent && + (wme_mode == eHAL_SET)) + { + sta_ds->wmeEnabled = eANI_BOOLEAN_TRUE; + sta_ds->qosMode = eANI_BOOLEAN_TRUE; + limGetWsmMode(session_entry, &wsm_mode); + /* WMM_APSD - WMM_SA related processing should be + * separate; WMM_SA and WMM_APSD can coexist + */ + if (assoc_req->WMMInfoStation.present) + { + /* check whether AP supports or not */ + if ((session_entry->limSystemRole == eLIM_AP_ROLE) + && (session_entry->apUapsdEnable == 0) && + (assoc_req->WMMInfoStation.acbe_uapsd + || assoc_req->WMMInfoStation.acbk_uapsd + || assoc_req->WMMInfoStation.acvo_uapsd + || assoc_req->WMMInfoStation.acvi_uapsd)) + { + /* + * Received Re/Association Request from + * STA when UPASD is not supported + */ + limLog( pmac, LOGE, FL( "AP do not support UAPSD so reply " + "to STA accordingly" )); + /* update UAPSD and send it to LIM to add STA */ + sta_ds->qos.capability.qosInfo.acbe_uapsd = 0; + sta_ds->qos.capability.qosInfo.acbk_uapsd = 0; + sta_ds->qos.capability.qosInfo.acvo_uapsd = 0; + sta_ds->qos.capability.qosInfo.acvi_uapsd = 0; + sta_ds->qos.capability.qosInfo.maxSpLen = 0; + } + else + { + /* update UAPSD and send it to LIM to add STA */ + sta_ds->qos.capability.qosInfo.acbe_uapsd = + assoc_req->WMMInfoStation.acbe_uapsd; + sta_ds->qos.capability.qosInfo.acbk_uapsd = + assoc_req->WMMInfoStation.acbk_uapsd; + sta_ds->qos.capability.qosInfo.acvo_uapsd = + assoc_req->WMMInfoStation.acvo_uapsd; + sta_ds->qos.capability.qosInfo.acvi_uapsd = + assoc_req->WMMInfoStation.acvi_uapsd; + sta_ds->qos.capability.qosInfo.maxSpLen = + assoc_req->WMMInfoStation.max_sp_length; + } + } + if (assoc_req->wsmCapablePresent && (wsm_mode == eHAL_SET)) + sta_ds->wsmEnabled = eANI_BOOLEAN_TRUE; + } +} + +/** + * lim_sap_offload_add_sta - Parse Add sta request from firmware + * + * @pmac: mac context + * @lim_msgq: Add Sta indication buffer + * + * This function will recieve buffer from firmware. This buffer will store + * information about connected client. driver will process this buffer and + * will register this client with driver. Driver will call limAddSta + * + * Return: none + */ +void lim_sap_offload_add_sta(tpAniSirGlobal pmac, + tSapOfldAddStaIndMsg *lim_msgq) +{ + tpSirAssocReq assoc_req = NULL; + tpDphHashNode sta_ds = NULL; + + tSapOfldAddStaIndMsg *add_sta_req = NULL; + tpPESession session_entry = limIsApSessionActive(pmac); + + if (session_entry == NULL) + { + PELOGE(limLog(pmac, LOGE, FL(" Session not found"));) + return; + } + add_sta_req = lim_msgq; + assoc_req = vos_mem_malloc(sizeof(*assoc_req)); + if (NULL == assoc_req) { + limLog(pmac, LOGP, FL("Allocate Memory failed in AssocReq")); + return; + } + vos_mem_set(assoc_req , sizeof(*assoc_req), 0); + + /* parse Assoc req frame for station information */ + sta_ds = _sap_offload_parse_assoc_req(pmac, assoc_req, add_sta_req); + if (sta_ds == NULL) + { + PELOGE(limLog(pmac, LOGE, FL("could not add hash entry for"));) + limPrintMacAddr(pmac, add_sta_req->peer_macaddr, LOGE); + vos_mem_free(assoc_req); + goto error; + } + + /* Parse Station Capability */ + _sap_offload_parse_sta_capability(sta_ds, assoc_req, add_sta_req); + + /* Parse Station HT/VHT information */ + if (_sap_offload_parse_sta_vht(pmac, sta_ds, assoc_req) + == eSIR_FAILURE) + { + PELOGE(limLog(pmac, LOGE, FL("mismatch ht/vht information for "));) + limPrintMacAddr(pmac, add_sta_req->peer_macaddr, LOGE); + vos_mem_free(assoc_req); + goto error; + + } + + /* Parse Station QOS information */ + _sap_offload_parse_sta_qos(pmac, sta_ds, assoc_req); + + session_entry->parsedAssocReq[sta_ds->assocId] = assoc_req; + sta_ds->staIndex = add_sta_req->staIdx; + sta_ds->dpuIndex = add_sta_req->dpuIndex; + sta_ds->bcastDpuIndex = add_sta_req->bcastDpuIndex; + sta_ds->bcastMgmtDpuIdx = add_sta_req->bcastMgmtDpuIdx; + sta_ds->ucUcastSig = add_sta_req->ucUcastSig; + sta_ds->ucBcastSig = add_sta_req->ucBcastSig; + sta_ds->ucMgmtSig = add_sta_req->ucMgmtSig; + sta_ds->bssId = add_sta_req->bssIdx; + + limLog(pmac, LOG1, FL("StaIndex %d BssIDx %d dpuIndex %d bcastDpuIndex %d bcastMgmtDpuIdx %d ucUcastSig %d ucBcastSig %d ucMgmtSig %d AssocId %d"), + sta_ds->staIndex, + sta_ds->bssId, + sta_ds->dpuIndex, + sta_ds->bcastDpuIndex, + sta_ds->bcastMgmtDpuIdx, + sta_ds->ucUcastSig, + sta_ds->ucBcastSig, + sta_ds->ucMgmtSig, + sta_ds->assocId); + + if (limAddSta(pmac, sta_ds, false, session_entry) != eSIR_SUCCESS) { + limLog(pmac, LOGE, FL("could not Add STA with assocId=%d"), + sta_ds->assocId); + } + +error: + return; +} + +/** + * lim_sap_offload_del_sta - Parse Del sta request from firmware + * + * @pmac: mac context + * @lim_msgq: Del Sta indication buffer + * + * This function will recieve buffer from firmware. This buffer will + * have information about clinet to remove with reason code. + * This function will call limSendSmeDisassocInd to do cleanup + * for station entry + * + * Return: none + */ +void +lim_sap_offload_del_sta(tpAniSirGlobal pmac, tSapOfldDelStaIndMsg *lim_msgq) +{ + tSapOfldDelStaIndMsg *del_sta_req = NULL; + tpDphHashNode sta_ds = NULL; + tANI_U16 assoc_id = 0; + tpPESession psession_entry = limIsApSessionActive(pmac); + + if (psession_entry == NULL) + { + PELOGE(limLog(pmac, LOGE, FL(" Session not found"));) + goto error; + } + + del_sta_req = lim_msgq; + sta_ds = dphLookupHashEntry(pmac, + del_sta_req->peer_macaddr, + &assoc_id, + &psession_entry->dph.dphHashTable); + if (sta_ds == NULL) + { + /* + * Disassociating STA is not associated. + * Log error + */ + PELOGE(limLog(pmac, LOGE, + FL("received del sta event that sta not exist in table " + "reasonCode=%d, addr "MAC_ADDRESS_STR), + del_sta_req->reason, + MAC_ADDR_ARRAY(del_sta_req->peer_macaddr));) + goto error; + } + + if (assoc_id != (tANI_U16)del_sta_req->assoc_id) + { + /* + * Associate Id mismatch + * Log error + */ + PELOGE(limLog(pmac, LOGE, + FL("received del sta event that sta assoc Id mismatch"));) + goto error; + } + + sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC; + sta_ds->mlmStaContext.disassocReason = + (tSirMacReasonCodes) del_sta_req->reason; + + limSendSmeDisassocInd(pmac, sta_ds, psession_entry); + +error: + return; +} +#endif /* SAP_AUTH_OFFLOAD */ + +int peFindBssIdxFromSmeSessionId(tpAniSirGlobal pMac, tANI_U8 sme_sessionId) +{ + tANI_U8 i; + tpPESession psessionEntry = NULL; + + for(i =0; i < pMac->lim.maxBssId; i++) + { + /* If BSSID matches return corresponding tables address*/ + if( (pMac->lim.gpSession[i].valid) && (pMac->lim.gpSession[i].smeSessionId == sme_sessionId)) + { + psessionEntry = (&pMac->lim.gpSession[i]); + return psessionEntry->bssIdx; + } + } + + limLog(pMac, LOG4, FL("Session lookup fails for sme_sessionId: ")); + return(0xFF); +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h new file mode 100644 index 000000000000..8083629c6001 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/limUtils.h @@ -0,0 +1,587 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file limUtils.h contains the utility definitions + * LIM uses. + * Author: Chandra Modumudi + * Date: 02/13/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __LIM_UTILS_H +#define __LIM_UTILS_H + +#include "sirApi.h" +#include "sirDebug.h" +#include "cfgApi.h" + +#include "limTypes.h" +#include "limScanResultUtils.h" +#include "limTimerUtils.h" +#include "limTrace.h" +typedef enum +{ + ONE_BYTE = 1, + TWO_BYTE = 2 +} eSizeOfLenField; + +#define LIM_STA_ID_MASK 0x00FF +#define LIM_AID_MASK 0xC000 +#define LIM_SPECTRUM_MANAGEMENT_BIT_MASK 0x0100 +#define LIM_RRM_BIT_MASK 0x1000 +#define LIM_SHORT_PREAMBLE_BIT_MASK 0x0020 +#define LIM_IMMEDIATE_BLOCK_ACK_MASK 0x8000 +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define LIM_MAX_REASSOC_RETRY_LIMIT 2 +#endif + +#define LIM_MAX_BANDS ( 48 ) + +// classifier ID is coded as 0-3: tsid, 4-5:direction +#define LIM_MAKE_CLSID(tsid, dir) (((tsid) & 0x0F) | (((dir) & 0x03) << 4)) + +#define LIM_SET_STA_BA_STATE(pSta, tid, newVal) \ +{\ + pSta->baState = ((pSta->baState | (0x3 << tid*2)) & ((newVal << tid*2) | ~(0x3 << tid*2)));\ +} + +#define LIM_GET_STA_BA_STATE(pSta, tid, pCurVal)\ +{\ + *pCurVal = (tLimBAState)(((pSta->baState >> tid*2) & 0x3));\ +} + +typedef struct sAddBaInfo +{ + tANI_U16 fBaEnable : 1; + tANI_U16 startingSeqNum: 12; + tANI_U16 reserved : 3; +}tAddBaInfo, *tpAddBaInfo; + +typedef struct sAddBaCandidate +{ + tSirMacAddr staAddr; + tAddBaInfo baInfo[STACFG_MAX_TC]; +}tAddBaCandidate, *tpAddBaCandidate; + +#ifdef WLAN_FEATURE_11W +typedef union uPmfSaQueryTimerId +{ + struct + { + tANI_U8 sessionId; + tANI_U16 peerIdx; + } fields; + tANI_U32 value; +} tPmfSaQueryTimerId, *tpPmfSaQueryTimerId; +#endif + +typedef enum offset { + BW20, + BW40PLUS, + BW40MINUS, + BW80, + BWALL +} offset_t; + +typedef struct op_class_map { + tANI_U8 op_class; + tANI_U8 ch_spacing; + offset_t offset; + tANI_U8 channels[25]; +}op_class_map_t; +// LIM utility functions +tANI_BOOLEAN limCheck11BRateBitmap(tANI_U16 RateBitmap); +void limGetBssidFromPkt(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U32 *); +char * limMlmStateStr(tLimMlmStates state); +char * limSmeStateStr(tLimSmeStates state); +char * limMsgStr(tANI_U32 msgType); +char * limResultCodeStr(tSirResultCodes resultCode); +char* limDot11ModeStr(tpAniSirGlobal pMac, tANI_U8 dot11Mode); +char* limStaOpRateModeStr(tStaRateMode opRateMode); +void limPrintMlmState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimMlmStates state); +void limPrintSmeState(tpAniSirGlobal pMac, tANI_U16 logLevel, tLimSmeStates state); +void limPrintMsgName(tpAniSirGlobal pMac, tANI_U16 logLevel, tANI_U32 msgType); +void limPrintMsgInfo(tpAniSirGlobal pMac, tANI_U16 logLevel, tSirMsgQ *msg); +char* limBssTypeStr(tSirBssType bssType); + +#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI +extern tSirRetStatus limSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, + tPowerdBm txPower, + tpPESession pSessionEntry ); +extern tANI_U8 limGetMaxTxPower(tPowerdBm regMax, tPowerdBm apTxPower, tANI_U8 iniTxPower); +#endif + +tANI_U32 limPostMsgApiNoWait(tpAniSirGlobal, tSirMsgQ *); +tANI_U8 limIsAddrBC(tSirMacAddr); +tANI_U8 limIsGroupAddr(tSirMacAddr); + +// check for type of scan allowed +tANI_U8 limActiveScanAllowed(tpAniSirGlobal, tANI_U8); + +// AID pool management functions +void limInitPeerIdxpool(tpAniSirGlobal,tpPESession); +tANI_U16 limAssignPeerIdx(tpAniSirGlobal,tpPESession); + +void limEnableOverlap11gProtection(tpAniSirGlobal pMac, tpUpdateBeaconParams pBeaconParams, tpSirMacMgmtHdr pMh,tpPESession psessionEntry); +void limUpdateOverlapStaParam(tpAniSirGlobal pMac, tSirMacAddr bssId, tpLimProtStaParams pStaParams); +void limUpdateShortPreamble(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); +void limUpdateShortSlotTime(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); + +/* + * The below 'product' check tobe removed if 'Association' is + * allowed in IBSS. + */ +void limReleasePeerIdx(tpAniSirGlobal, tANI_U16, tpPESession); + + +void limDecideApProtection(tpAniSirGlobal pMac, tSirMacAddr peerMacAddr, tpUpdateBeaconParams pBeaconParams,tpPESession); +void +limDecideApProtectionOnDelete(tpAniSirGlobal pMac, + tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); + +extern tSirRetStatus limEnable11aProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession); +extern tSirRetStatus limEnable11gProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry); +extern tSirRetStatus limEnableHtProtectionFrom11g(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry); +extern tSirRetStatus limEnableHT20Protection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession sessionEntry); +extern tSirRetStatus limEnableHTNonGfProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession); +extern tSirRetStatus limEnableHtRifsProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession psessionEntry); +extern tSirRetStatus limEnableHTLsigTxopProtection(tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams,tpPESession); +extern tSirRetStatus limEnableShortPreamble(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); +extern tSirRetStatus limEnableHtOBSSProtection (tpAniSirGlobal pMac, tANI_U8 enable, tANI_U8 overlap, tpUpdateBeaconParams pBeaconParams, tpPESession); +void limDecideStaProtection(tpAniSirGlobal pMac, tpSchBeaconStruct pBeaconStruct, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry); +void limDecideStaProtectionOnAssoc(tpAniSirGlobal pMac, tpSchBeaconStruct pBeaconStruct, tpPESession psessionEntry); +void limUpdateStaRunTimeHTSwitchChnlParams(tpAniSirGlobal pMac, tDot11fIEHTInfo * pHTInfo, tANI_U8 bssIdx, tpPESession psessionEntry); +// Print MAC address utility function +void limPrintMacAddr(tpAniSirGlobal, tSirMacAddr, tANI_U8); + + + +// Deferred Message Queue read/write +tANI_U8 limWriteDeferredMsgQ(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirMsgQ* limReadDeferredMsgQ(tpAniSirGlobal pMac); +void limHandleDeferMsgError(tpAniSirGlobal pMac, tpSirMsgQ pLimMsg); + +// Deferred Message Queue Reset +void limResetDeferredMsgQ(tpAniSirGlobal pMac); + +tSirRetStatus limSysProcessMmhMsgApi(tpAniSirGlobal, tSirMsgQ*, tANI_U8); + +void limHandleUpdateOlbcCache(tpAniSirGlobal pMac); + +tANI_U8 limIsNullSsid( tSirMacSSid *pSsid ); + +void limProcessAddtsRspTimeout(tpAniSirGlobal pMac, tANI_U32 param); + +// 11h Support +void limStopTxAndSwitchChannel(tpAniSirGlobal pMac, tANI_U8 sessionId); +void limProcessChannelSwitchTimeout(tpAniSirGlobal); +tSirRetStatus limStartChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limUpdateChannelSwitch(tpAniSirGlobal, tpSirProbeRespBeacon, tpPESession psessionEntry); +void limProcessQuietTimeout(tpAniSirGlobal); +void limProcessQuietBssTimeout(tpAniSirGlobal); +void limInitOBSSScanParams(tpAniSirGlobal pMac, + tpPESession psessionEntry); +#if 0 +void limProcessWPSOverlapTimeout(tpAniSirGlobal pMac); +#endif + +void limStartQuietTimer(tpAniSirGlobal pMac, tANI_U8 sessionId); +void limSwitchPrimaryChannel(tpAniSirGlobal, tANI_U8,tpPESession); +void limSwitchPrimarySecondaryChannel(tpAniSirGlobal, tpPESession, tANI_U8, ePhyChanBondState); +tAniBool limTriggerBackgroundScanDuringQuietBss(tpAniSirGlobal); +void limUpdateStaRunTimeHTSwtichChnlParams(tpAniSirGlobal pMac, tDot11fIEHTInfo *pRcvdHTInfo, tANI_U8 bssIdx); +void limUpdateStaRunTimeHTCapability(tpAniSirGlobal pMac, tDot11fIEHTCaps *pHTCaps); +void limUpdateStaRunTimeHTInfo(struct sAniSirGlobal *pMac, tDot11fIEHTInfo *pRcvdHTInfo, tpPESession psessionEntry); +void limCancelDot11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limCancelDot11hQuiet(tpAniSirGlobal pMac, tpPESession psessionEntry); +tAniBool limIsChannelValidForChannelSwitch(tpAniSirGlobal pMac, tANI_U8 channel); +void limFrameTransmissionControl(tpAniSirGlobal pMac, tLimQuietTxMode type, tLimControlTx mode); +tSirRetStatus limRestorePreChannelSwitchState(tpAniSirGlobal pMac, tpPESession psessionEntry); +tSirRetStatus limRestorePreQuietState(tpAniSirGlobal pMac, tpPESession psessionEntry); + +void limPrepareFor11hChannelSwitch(tpAniSirGlobal pMac, tpPESession psessionEntry); +void limSwitchChannelCback(tpAniSirGlobal pMac, eHalStatus status, + tANI_U32 *data, tpPESession psessionEntry); + +static inline tSirRFBand limGetRFBand(tANI_U8 channel) +{ + if ((channel >= SIR_11A_CHANNEL_BEGIN) && + (channel <= SIR_11A_CHANNEL_END)) + return SIR_BAND_5_GHZ; + + if ((channel >= SIR_11B_CHANNEL_BEGIN) && + (channel <= SIR_11B_CHANNEL_END)) + return SIR_BAND_2_4_GHZ; + + return SIR_BAND_UNKNOWN; +} + + +static inline tSirRetStatus +limGetMgmtStaid(tpAniSirGlobal pMac, tANI_U16 *staid, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + *staid = 1; + else if (psessionEntry->limSystemRole == eLIM_STA_ROLE) + *staid = 0; + else + return eSIR_FAILURE; + + return eSIR_SUCCESS; +} + +static inline tANI_U8 +limIsSystemInSetMimopsState(tpAniSirGlobal pMac) +{ + if (pMac->lim.gLimMlmState == eLIM_MLM_WT_SET_MIMOPS_STATE) + return true; + return false; +} + +static inline tANI_U8 + isEnteringMimoPS(tSirMacHTMIMOPowerSaveState curState, tSirMacHTMIMOPowerSaveState newState) + { + if (curState == eSIR_HT_MIMO_PS_NO_LIMIT && + (newState == eSIR_HT_MIMO_PS_DYNAMIC ||newState == eSIR_HT_MIMO_PS_STATIC)) + return TRUE; + return FALSE; +} + +/// ANI peer station count management and associated actions +void limUtilCountStaAdd(tpAniSirGlobal pMac, tpDphHashNode pSta, tpPESession psessionEntry); +void limUtilCountStaDel(tpAniSirGlobal pMac, tpDphHashNode pSta, tpPESession psessionEntry); + +tANI_U8 limGetHTCapability( tpAniSirGlobal, tANI_U32, tpPESession); +void limTxComplete( tHalHandle hHal, void *pData ); + +/**********Admit Control***************************************/ + +//callback function for HAL to issue DelTS request to PE. +//This function will be registered with HAL for callback when TSPEC inactivity timer fires. + +void limProcessDelTsInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +tSirRetStatus limProcessHalIndMessages(tpAniSirGlobal pMac, tANI_U32 mesgId, void *mesgParam ); +tSirRetStatus limValidateDeltsReq(tpAniSirGlobal pMac, tpSirDeltsReq pDeltsReq, tSirMacAddr peerMacAddr,tpPESession psessionEntry); +/**********************************************************/ + +//callback function registration to HAL for any indication. +void limRegisterHalIndCallBack(tpAniSirGlobal pMac); +void limPktFree ( + tpAniSirGlobal pMac, + eFrameType frmType, + tANI_U8 *pBD, + void *body); + + + +void limGetBDfromRxPacket(tpAniSirGlobal pMac, void *body, tANI_U32 **pBD); + +/** + * \brief Given a base(X) and power(Y), this API will return + * the result of base raised to power - (X ^ Y) + * + * \sa utilsPowerXY + * + * \param base Base value + * + * \param power Base raised to this Power value + * + * \return Result of X^Y + * + */ +static inline tANI_U32 utilsPowerXY( tANI_U16 base, tANI_U16 power ) +{ +tANI_U32 result = 1, i; + + for( i = 0; i < power; i++ ) + result *= base; + + return result; +} + + + +tSirRetStatus limPostMlmAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pStaDs, + tANI_U8 tid, tANI_U16 startingSeqNum,tpPESession psessionEntry); +tSirRetStatus limPostMlmAddBARsp( tpAniSirGlobal pMac, + tSirMacAddr peerMacAddr, + tSirMacStatusCodes baStatusCode, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tpPESession psessionEntry); +tSirRetStatus limPostMlmDelBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDirection, + tANI_U8 baTID, + tSirMacReasonCodes baReasonCode , + tpPESession psessionEntry); +tSirRetStatus limPostMsgAddBAReq( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baDialogToken, + tANI_U8 baTID, + tANI_U8 baPolicy, + tANI_U16 baBufferSize, + tANI_U16 baTimeout, + tANI_U16 baSSN, + tANI_U8 baDirection, + tpPESession psessionEntry); +tSirRetStatus limPostMsgDelBAInd( tpAniSirGlobal pMac, + tpDphHashNode pSta, + tANI_U8 baTID, + tANI_U8 baDirection, + tpPESession psessionEntry); + +tSirRetStatus limPostSMStateUpdate(tpAniSirGlobal pMac, + tANI_U16 StaIdx, + tSirMacHTMIMOPowerSaveState MIMOPSState); + +void limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void limProcessAddBaInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg); +void limDeleteBASessions(tpAniSirGlobal pMac, tpPESession pSessionEntry, + tANI_U32 baDirection, tSirMacReasonCodes baReasonCode); +void limDelPerBssBASessionsBtc(tpAniSirGlobal pMac); +void limDelAllBASessions(tpAniSirGlobal pMac); +void limDeleteDialogueTokenList(tpAniSirGlobal pMac); +tSirRetStatus limSearchAndDeleteDialogueToken(tpAniSirGlobal pMac, tANI_U8 token, tANI_U16 assocId, tANI_U16 tid); +void limRessetScanChannelInfo(tpAniSirGlobal pMac); +void limAddScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 channelId); + +tANI_U8 limGetChannelFromBeacon(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon); +tSirNwType limGetNwType(tpAniSirGlobal pMac, tANI_U8 channelNum, tANI_U32 type, tpSchBeaconStruct pBeacon); +void limSetTspecUapsdMask(tpAniSirGlobal pMac, tSirMacTSInfo *pTsInfo, tANI_U32 action); +void limHandleHeartBeatTimeout(tpAniSirGlobal pMac); +void limHandleHeartBeatTimeoutForSession(tpAniSirGlobal pMac, tpPESession psessionEntry); + +//void limProcessBtampAddBssRsp(tpAniSirGlobal pMac,tpSirMsgQ pMsgQ,tpPESession peSession); +void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ pMsgQ); + +void limUpdateBeacon(tpAniSirGlobal pMac); + +void limProcessBtAmpApMlmAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ, tpPESession psessionEntry); +void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPESession psessionEntry); + +void limProcessBtAmpApMlmDelStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ,tpPESession psessionEntry); +tpPESession limIsIBSSSessionActive(tpAniSirGlobal pMac); +tpPESession limIsApSessionActive(tpAniSirGlobal pMac); +void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac); + +void limProcessDelStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ); +void limProcessAddStaSelfRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ); +v_U8_t* limGetIEPtr(tpAniSirGlobal pMac, v_U8_t *pIes, int length, v_U8_t eid,eSizeOfLenField size_of_len_field); + +tANI_U8 limUnmapChannel(tANI_U8 mapChannel); + +#define limGetWscIEPtr(pMac, ie, ie_len) \ + limGetVendorIEOuiPtr(pMac, SIR_MAC_WSC_OUI, SIR_MAC_WSC_OUI_SIZE, ie, ie_len) + +#define limGetP2pIEPtr(pMac, ie, ie_len) \ + limGetVendorIEOuiPtr(pMac, SIR_MAC_P2P_OUI, SIR_MAC_P2P_OUI_SIZE, ie, ie_len) + +v_U8_t limGetNoaAttrStreamInMultP2pIes(tpAniSirGlobal pMac,v_U8_t* noaStream,v_U8_t noaLen,v_U8_t overFlowLen); +v_U8_t limGetNoaAttrStream(tpAniSirGlobal pMac, v_U8_t*pNoaStream,tpPESession psessionEntry); + +v_U8_t limBuildP2pIe(tpAniSirGlobal pMac, tANI_U8 *ie, tANI_U8 *data, tANI_U8 ie_len); +tANI_BOOLEAN limIsNOAInsertReqd(tpAniSirGlobal pMac); +v_U8_t* limGetVendorIEOuiPtr(tpAniSirGlobal pMac, tANI_U8 *oui, tANI_U8 oui_size, tANI_U8 *ie, tANI_U16 ie_len); +tANI_BOOLEAN limIsconnectedOnDFSChannel(tANI_U8 currentChannel); +tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_11AC +tANI_BOOLEAN limCheckVHTOpModeChange( tpAniSirGlobal pMac, + tpPESession psessionEntry, tANI_U8 chanWidth, tANI_U8 staId); +#endif +tANI_BOOLEAN limCheckHTChanBondModeChange(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tANI_U8 beaconSecChanWidth, + tANI_U8 currentSecChanWidth, + tANI_U8 staId); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +typedef enum +{ + WLAN_PE_DIAG_SCAN_REQ_EVENT = 0, + WLAN_PE_DIAG_SCAN_ABORT_IND_EVENT, + WLAN_PE_DIAG_SCAN_RSP_EVENT, + WLAN_PE_DIAG_JOIN_REQ_EVENT, + WLAN_PE_DIAG_JOIN_RSP_EVENT, + WLAN_PE_DIAG_SETCONTEXT_REQ_EVENT, + WLAN_PE_DIAG_SETCONTEXT_RSP_EVENT, + WLAN_PE_DIAG_REASSOC_REQ_EVENT, + WLAN_PE_DIAG_REASSOC_RSP_EVENT, + WLAN_PE_DIAG_AUTH_REQ_EVENT, + WLAN_PE_DIAG_AUTH_RSP_EVENT = 10, + WLAN_PE_DIAG_DISASSOC_REQ_EVENT, + WLAN_PE_DIAG_DISASSOC_RSP_EVENT, + WLAN_PE_DIAG_DISASSOC_IND_EVENT, + WLAN_PE_DIAG_DISASSOC_CNF_EVENT, + WLAN_PE_DIAG_DEAUTH_REQ_EVENT, + WLAN_PE_DIAG_DEAUTH_RSP_EVENT, + WLAN_PE_DIAG_DEAUTH_IND_EVENT, + WLAN_PE_DIAG_START_BSS_REQ_EVENT, + WLAN_PE_DIAG_START_BSS_RSP_EVENT, + WLAN_PE_DIAG_AUTH_IND_EVENT = 20, + WLAN_PE_DIAG_ASSOC_IND_EVENT, + WLAN_PE_DIAG_ASSOC_CNF_EVENT, + WLAN_PE_DIAG_REASSOC_IND_EVENT, + WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, + WLAN_PE_DIAG_SWITCH_CHL_RSP_EVENT, + WLAN_PE_DIAG_STOP_BSS_REQ_EVENT, + WLAN_PE_DIAG_STOP_BSS_RSP_EVENT, + WLAN_PE_DIAG_DEAUTH_CNF_EVENT, + WLAN_PE_DIAG_ADDTS_REQ_EVENT, + WLAN_PE_DIAG_ADDTS_RSP_EVENT = 30, + WLAN_PE_DIAG_DELTS_REQ_EVENT, + WLAN_PE_DIAG_DELTS_RSP_EVENT, + WLAN_PE_DIAG_DELTS_IND_EVENT, + WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT, + WLAN_PE_DIAG_ENTER_BMPS_RSP_EVENT, + WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT, + WLAN_PE_DIAG_EXIT_BMPS_RSP_EVENT, + WLAN_PE_DIAG_EXIT_BMPS_IND_EVENT, + WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT, + WLAN_PE_DIAG_ENTER_IMPS_RSP_EVENT = 40, + WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT, + WLAN_PE_DIAG_EXIT_IMPS_RSP_EVENT, + WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT, + WLAN_PE_DIAG_ENTER_UAPSD_RSP_EVENT, + WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT, + WLAN_PE_DIAG_EXIT_UAPSD_RSP_EVENT, + WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT, + WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT, + WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT, + WLAN_PE_DIAG_ENTER_WOWL_RSP_EVENT = 50, + WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT, + WLAN_PE_DIAG_EXIT_WOWL_RSP_EVENT, + WLAN_PE_DIAG_HAL_ADDBA_REQ_EVENT, + WLAN_PE_DIAG_HAL_ADDBA_RSP_EVENT, + WLAN_PE_DIAG_HAL_DELBA_IND_EVENT, + WLAN_PE_DIAG_HB_FAILURE_TIMEOUT, + WLAN_PE_DIAG_PRE_AUTH_REQ_EVENT, + WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, + WLAN_PE_DIAG_PREAUTH_DONE, + WLAN_PE_DIAG_REASSOCIATING = 60, + WLAN_PE_DIAG_CONNECTED, + WLAN_PE_DIAG_ASSOC_REQ_EVENT, + WLAN_PE_DIAG_AUTH_COMP_EVENT, + WLAN_PE_DIAG_ASSOC_COMP_EVENT, + WLAN_PE_DIAG_AUTH_START_EVENT, + WLAN_PE_DIAG_ASSOC_START_EVENT, + WLAN_PE_DIAG_REASSOC_START_EVENT, + WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, + WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT, + WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT = 70, + WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, + WLAN_PE_DIAG_SCAN_COMP_EVENT, + WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, + WLAN_PE_DIAG_ROAM_REQUESTED, + WLAN_PE_DIAG_CHANNEL_SWITCH_ANOUNCEMENT, + WLAN_PE_DIAG_ROAM_CANDIDATE_FOUND, +}WLAN_PE_DIAG_EVENT_TYPE; + +void limDiagEventReport(tpAniSirGlobal pMac, tANI_U16 eventType, tpPESession pSessionEntry, tANI_U16 status, tANI_U16 reasonCode); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +void peSetResumeChannel(tpAniSirGlobal pMac, tANI_U16 channel, ePhyChanBondState cbState); +/*-------------------------------------------------------------------------- + + \brief peGetResumeChannel() - Returns the channel number for scanning, from a valid session. + + This function returns the channel to resume to during link resume. channel id of 0 means HAL will + resume to previous channel before link suspend + + \param pMac - pointer to global adapter context + \return - channel to scan from valid session else zero. + + \sa + + --------------------------------------------------------------------------*/ +void peGetResumeChannel(tpAniSirGlobal pMac, tANI_U8* resumeChannel, ePhyChanBondState* resumePhyCbState); + +void limGetShortSlotFromPhyMode(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U32 phyMode, + tANI_U8 *pShortSlotEnable); + +void limCleanUpDisassocDeauthReq(tpAniSirGlobal pMac, tANI_U8 *staMac, tANI_BOOLEAN cleanRxPath); + +tANI_BOOLEAN limCheckDisassocDeauthAckPending(tpAniSirGlobal pMac, tANI_U8 *staMac); + + +void limUtilsframeshtons(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U16 pIn, + tANI_U8 fMsb); + +void limUtilsframeshtonl(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U32 pIn, + tANI_U8 fMsb); + +void limUpdateOBSSScanParams(tpPESession psessionEntry , + tDot11fIEOBSSScanParameters *pOBSSScanParameters); + +#ifdef WLAN_FEATURE_11W +void limPmfSaQueryTimerHandler(void *pMacGlobal, tANI_U32 param); + +void limSetProtectedBit(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tSirMacAddr peer, + tpSirMacMgmtHdr pMacHdr); +#endif +void limInitOperatingClasses(tHalHandle hHal); +tANI_U8 limGetOPClassFromChannel(tANI_U8 *country, + tANI_U8 channel, + tANI_U8 offset); +void limParseBeaconForTim(tpAniSirGlobal pMac, tANI_U8* pRxPacketInfo, + tpPESession psessionEntry); + +void limUpdateMaxRateFlag(tpAniSirGlobal pMac, + tANI_U8 smeSessionId, + tANI_U32 maxRateFlag); + +extern tANI_U32 limGetMaxRateFlags(tpDphHashNode pStaDs, + tpPESession psessionEntry); + +void limDecrementPendingMgmtCount (tpAniSirGlobal pMac); + +eHalStatus limTxBdComplete(tpAniSirGlobal pMac, void *pData); +eHalStatus limAssocRspTxCompleteCnf(tpAniSirGlobal pMac, void *pData); +bool lim_is_robust_mgmt_action_frame(uint8 action_catagory); +tANI_U8 lim_compute_ext_cap_ie_length (tDot11fIEExtCap *ext_cap); +void lim_update_caps_info_for_bss(tpAniSirGlobal mac_ctx, + uint16_t *caps, uint16_t bss_caps); +#ifdef SAP_AUTH_OFFLOAD +void lim_sap_offload_add_sta(tpAniSirGlobal pmac, + tSapOfldAddStaIndMsg *lim_msgq); +void lim_sap_offload_del_sta(tpAniSirGlobal pmac, + tSapOfldDelStaIndMsg *lim_msgq); +#endif +#endif /* __LIM_UTILS_H */ diff --git a/drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c b/drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c new file mode 100644 index 000000000000..e9977b54c84e --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/lim/lim_mbb.c @@ -0,0 +1,1754 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "aniGlobal.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limFT.h" +#include "limSendMessages.h" +#include "limAssocUtils.h" +#include "limSerDesUtils.h" +#include "limSmeReqUtils.h" +#include "limAdmitControl.h" +#include "sirApi.h" +#include "rrmApi.h" +#include "wlan_qct_tl.h" + +#define PREAUTH_REASSOC_TIMEOUT 500 + +void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds, + tpPESession session_entry); + +/** + * lim_post_pre_auth_reassoc_rsp() -Posts preauth_reassoc response to SME + * @mac: MAC context + * @status: status + * @session_entry: session entry + * @reason: indicates which type of clean up needs to be performed + * + * This function process preauth_reassoc response to SME + */ +void lim_post_pre_auth_reassoc_rsp(tpAniSirGlobal mac, + tSirRetStatus status, tpPESession session_entry, + enum sir_roam_cleanup_type reason) +{ + tpSirFTPreAuthRsp pre_auth_rsp; + tSirMsgQ mmh_msg; + tANI_U16 rsp_len = sizeof(tSirFTPreAuthRsp); + tpPESession session_entry_con_ap; + tpDphHashNode sta_ds = NULL; + + pre_auth_rsp = (tpSirFTPreAuthRsp)vos_mem_malloc(rsp_len); + if (NULL == pre_auth_rsp) { + limLog(mac, LOGE, FL("Failed to allocate memory")); + return; + } + + limLog(mac, LOG1, FL("reason %d"), reason); + + vos_mem_zero(pre_auth_rsp, rsp_len); + pre_auth_rsp->messageType = eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP; + pre_auth_rsp->length = (tANI_U16)rsp_len; + pre_auth_rsp->status = status; + pre_auth_rsp->reason = reason; + + if (session_entry) + pre_auth_rsp->smeSessionId = session_entry->smeSessionId; + + /* The bssid of the AP we are sending Auth1 to. */ + if (mac->ft.ftPEContext.pFTPreAuthReq) + sirCopyMacAddr(pre_auth_rsp->preAuthbssId, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId); + + if (status != eSIR_SUCCESS) { + limLog(mac, LOG1, FL("Pre-Auth Failed, Cleanup!")); + limLog(mac, LOG1, FL("flushing cached packets")); + WLANTL_PreAssocForward(false); + + /* + * If reason is full clean up, add sme session id that + * will be useful in CSR during cleanup. + */ + if (reason == SIR_MBB_DISCONNECTED) { + session_entry_con_ap = + (tpPESession)mac->ft.ftPEContext.psavedsessionEntry; + pre_auth_rsp->smeSessionId = + session_entry_con_ap->smeSessionId; + } + limFTCleanup(mac); + } + + if (status == eSIR_SUCCESS) { + limLog(mac, LOG1, FL("Success")); + + rsp_len = session_entry->assocReqLen + session_entry->assocRspLen + + session_entry->bcnLen; + + pre_auth_rsp->roam_info = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (pre_auth_rsp->roam_info == NULL) { + limLog(mac, LOGE, + FL("Failed to allocate memory for roam info")); + return; + } + vos_mem_set(pre_auth_rsp->roam_info, sizeof(tCsrRoamInfo), 0); + + pre_auth_rsp->roam_info->pbFrames = vos_mem_malloc(rsp_len); + if (pre_auth_rsp->roam_info->pbFrames == NULL) { + limLog(mac, LOGE, + FL("Failed to allocate memory for roam info frames")); + return; + } + vos_mem_set(pre_auth_rsp->roam_info->pbFrames, rsp_len, 0); + + + pre_auth_rsp->length += rsp_len + sizeof(tCsrRoamInfo); + + session_entry_con_ap = + (tpPESession)mac->ft.ftPEContext.psavedsessionEntry; + pre_auth_rsp->smeSessionId = session_entry_con_ap->smeSessionId; + + if(session_entry->beacon != NULL) { + pre_auth_rsp->roam_info->nBeaconLength = session_entry->bcnLen; + vos_mem_copy(pre_auth_rsp->roam_info->pbFrames, + session_entry->beacon, + session_entry->bcnLen); + limLog(mac, LOG1, FL("Beacon len %d"), session_entry->bcnLen); + + vos_mem_free(session_entry->beacon); + session_entry->beacon = NULL; + } + + if(session_entry->assocReq != NULL) { + pre_auth_rsp->roam_info->nAssocReqLength = + session_entry->assocReqLen; + vos_mem_copy(pre_auth_rsp->roam_info->pbFrames + + session_entry->bcnLen, + session_entry->assocReq, + session_entry->assocReqLen); + + vos_mem_free(session_entry->assocReq); + session_entry->assocReq = NULL; + + limLog(mac, LOG1, FL("AssocReq len %d"), session_entry->assocReqLen); + } + + if(session_entry->assocRsp != NULL) { + pre_auth_rsp->roam_info->nAssocRspLength = + session_entry->assocRspLen; + vos_mem_copy(pre_auth_rsp->roam_info->pbFrames + + session_entry->bcnLen + session_entry->assocReqLen, + session_entry->assocRsp, + session_entry->assocRspLen); + + vos_mem_free(session_entry->assocRsp); + session_entry->assocRsp = NULL; + + limLog(mac, LOG1, FL("AssocRsp len %d"), session_entry->assocRspLen); + } + + sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER, + &session_entry->dph.dphHashTable); + if(NULL == sta_ds) { + limLog(mac, LOGE, + FL("Unable to get the DPH Hash Entry for AID - %d"), + DPH_STA_HASH_INDEX_PEER); + return; + } + + pre_auth_rsp->roam_info->staId = sta_ds->staIndex; + pre_auth_rsp->roam_info->ucastSig = sta_ds->ucUcastSig; + pre_auth_rsp->roam_info->bcastSig = sta_ds->ucBcastSig; + pre_auth_rsp->roam_info->maxRateFlags = + limGetMaxRateFlags(sta_ds, session_entry); + } + + mmh_msg.type = pre_auth_rsp->messageType; + mmh_msg.bodyptr = pre_auth_rsp; + mmh_msg.bodyval = 0; + + limLog(mac, LOG1, + FL("Posted Auth Rsp to SME with status of 0x%x"), status); + + limSysProcessMmhMsgApi(mac, &mmh_msg, ePROT); +} + +/* + * lim_reassoc_fail_cleanup() -handles cleanup during reassoc failure + * @mac: MAC context + * @status: status + * @data: pointer to data + * + * This function handles cleanup during reassoc failure + */ +void lim_reassoc_fail_cleanup(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data) +{ + tpPESession session_entry; + + session_entry = (tpPESession)data; + + if (!mac->ft.ftPEContext.pFTPreAuthReq) { + limLog(mac, LOGE, FL("pFTPreAuthReq is NULL")); + return; + } + + if (dphDeleteHashEntry(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + DPH_STA_HASH_INDEX_PEER, + &session_entry->dph.dphHashTable) != eSIR_SUCCESS) { + limLog(mac, LOGE, FL("error deleting hash entry")); + } + + /* Delete session as session was created during preauth success */ + peDeleteSession(mac, session_entry); + + /* Add bss parameter cleanup happens as part of this processing*/ + if ((status == eHAL_STATUS_MBB_DEL_BSS_FAIL) || + (status == eHAL_STATUS_INVALID_PARAMETER) || + (status == eHAL_STATUS_MBB_ADD_BSS_FAIL)) + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_DISCONNECTED); + else + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); +} + +/* + * lim_perform_post_reassoc_mbb_channel_change() -invokes resume callback + * @mac: MAC context + * @status: status + * @data: pointer to data + * @session_entry: session entry + * + * This function invokes resume callback + */ +void lim_perform_post_reassoc_mbb_channel_change(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data, tpPESession session_entry) +{ + tpPESession session_entry_con_ap; + tANI_U8 session_id; + + session_entry_con_ap = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, + &session_id); + if (session_entry_con_ap == NULL) { + limLog(mac, LOGE, + FL("session does not exist for given BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId)); + + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0); + limResumeLink(mac, lim_reassoc_fail_cleanup, + (tANI_U32 *)session_entry); +} + +/* + * lim_handle_reassoc_mbb_fail() -handles reassoc failure + * @mac: MAC context + * @session_entry: session entry + * + * This function handles reassoc failure + */ +void lim_handle_reassoc_mbb_fail(tpAniSirGlobal mac, + tpPESession session_entry) +{ + tpPESession session_entry_con_ap; + tANI_U8 session_id; + + session_entry_con_ap = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, + &session_id); + if (session_entry_con_ap == NULL) { + limLog(mac, LOGE, + FL("session does not exist for given BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId)); + + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"), + session_entry_con_ap->currentOperChannel, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum); + + /* Restore set link to post assoc for currently connected AP */ + if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE, + session_entry_con_ap->bssId, + session_entry_con_ap->selfMacAddr, + NULL, NULL) != eSIR_SUCCESS) { + limLog(mac, LOGE, FL("Set link state to POSTASSOC failed")); + + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + /* Change channel if required as channel might be changed during preauth */ + if (session_entry_con_ap->currentOperChannel != + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) { + limChangeChannelWithCallback(mac, + session_entry_con_ap->currentOperChannel, + lim_perform_post_reassoc_mbb_channel_change, NULL, session_entry); + } else { + /* + * Link needs to be resumed as link was suspended + * for same channel during preauth. + */ + peSetResumeChannel(mac, session_entry_con_ap->currentOperChannel, 0); + limResumeLink(mac, lim_reassoc_fail_cleanup, + (tANI_U32 *)session_entry); + } +} + +/* + * lim_preauth_fail_cleanup() -handles cleanup during preauth failure + * @mac: MAC context + * @status: status + * @data: pointer to data + * + * This function handles cleanup during reassoc failure + */ +void lim_preauth_fail_cleanup(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data) +{ + tpPESession session_entry; + + session_entry = (tpPESession)data; + + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); +} + +/* + * lim_perform_preauth_mbb_fail_channel_change() -invokes resume callback + * @mac: MAC context + * @status: status + * @data: pointer to data + * @session_entry: session entry + * + * This function invokes resume callback + */ +void lim_perform_preauth_mbb_fail_channel_change(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data, tpPESession session_entry) +{ + peSetResumeChannel(mac, session_entry->currentOperChannel, 0); + limResumeLink(mac, lim_preauth_fail_cleanup, + (tANI_U32 *)session_entry); +} + +/* + * lim_handle_preauth_mbb_fail() -handles preauth failure + * @mac: MAC context + * @session_entry: session entry + * + * This function handles reassoc failure + */ +void lim_handle_preauth_mbb_fail(tpAniSirGlobal mac, + tpPESession session_entry) +{ + limLog(mac, LOG1, FL("currentOperChannel %d preAuthchannelNum %d"), + session_entry->currentOperChannel, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum); + + /* Restore set link to post assoc for currently connected AP */ + if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE, + session_entry->bssId, + session_entry->selfMacAddr, + NULL, NULL) != eSIR_SUCCESS) { + limLog(mac, LOGE, FL("Set link state to POSTASSOC failed")); + + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + /* Change channel if required as channel might be changed during preauth */ + if (session_entry->currentOperChannel != + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) { + limChangeChannelWithCallback(mac, + session_entry->currentOperChannel, + lim_perform_preauth_mbb_fail_channel_change, NULL, session_entry); + } else { + /* + * Link needs to be resumed as link was suspended + * for same channel during preauth. + */ + peSetResumeChannel(mac, session_entry->currentOperChannel, 0); + limResumeLink(mac, lim_preauth_fail_cleanup, + (tANI_U32 *)session_entry); + } +} + + +/* + * lim_del_sta_mbb() -performs del sta + * @mac: MAC context + * @sta_ds_connected_ap: station entry of connected AP + * @resp_reqd: indicates whether response is required or not + * @session_entry_connected_ap: session entry of connected AP + * + * This function performs del sta + */ +tSirRetStatus lim_del_sta_mbb(tpAniSirGlobal mac, + tpDphHashNode sta_ds_connected_ap, + tANI_BOOLEAN resp_reqd, + tpPESession session_entry_connected_ap) +{ + tpDeleteStaParams del_sta_params; + tSirMsgQ msg; + tSirRetStatus ret_code; + + del_sta_params = vos_mem_malloc(sizeof(*del_sta_params)); + if (NULL == del_sta_params) { + limLog(mac, LOGE, FL("Unable to allocate memory during DEL_STA" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_zero(del_sta_params, sizeof(*del_sta_params)); + + del_sta_params->sessionId = session_entry_connected_ap->peSessionId; + del_sta_params->status = eHAL_STATUS_SUCCESS; + +#ifdef FEATURE_WLAN_TDLS + if(((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) && + (sta_ds_connected_ap->staType != STA_ENTRY_TDLS_PEER)) || + (eLIM_BT_AMP_STA_ROLE == + GET_LIM_SYSTEM_ROLE(session_entry_connected_ap))) +#else + if((eLIM_STA_ROLE == GET_LIM_SYSTEM_ROLE(session_entry_connected_ap)) || + (eLIM_BT_AMP_STA_ROLE == + GET_LIM_SYSTEM_ROLE(session_entry_connected_ap))) +#endif + del_sta_params->staIdx = session_entry_connected_ap->staId; + else + del_sta_params->staIdx = sta_ds_connected_ap->staIndex; + + del_sta_params->assocId = sta_ds_connected_ap->assocId; + del_sta_params->respReqd = resp_reqd; + + /* Change Mlm state of connected AP to Del sta rsp state */ + session_entry_connected_ap->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, + session_entry_connected_ap->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + + msg.type = WDA_DELETE_STA_REQ; + msg.reserved = 0; + msg.bodyptr = del_sta_params; + msg.bodyval = 0; + + limLog(mac, LOG1, + FL("sessionId %d staIdx: %d assocId: %d for "MAC_ADDRESS_STR), + del_sta_params->sessionId, del_sta_params->staIdx, + del_sta_params->assocId, + MAC_ADDR_ARRAY(sta_ds_connected_ap->staAddr)); + + MTRACE(macTraceMsgTx(mac, session_entry_connected_ap->peSessionId, + msg.type)); + + ret_code = wdaPostCtrlMsg(mac, &msg); + if( eSIR_SUCCESS != ret_code) { + if(resp_reqd) + SET_LIM_PROCESS_DEFD_MESGS(mac, true); + limLog(mac, LOGE, + FL("Posting DELETE_STA_REQ failed, reason=%X"), ret_code); + vos_mem_free(del_sta_params); + } + + return ret_code; +} + +/* + * lim_del_bss_mbb() -performs del bss of connected AP + * @mac: MAC context + * @sta_ds: station entry + * @bss_idx:BSS index + * @session_entry: session entry + * + * This function performs del bss of connected AP + */ +tSirRetStatus lim_del_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds, + tANI_U16 bss_idx,tpPESession session_entry) +{ + tpDeleteBssParams delbss_params = NULL; + tSirMsgQ msg; + tSirRetStatus ret_code = eSIR_SUCCESS; + + delbss_params = vos_mem_malloc(sizeof(tDeleteBssParams)); + if (NULL == delbss_params) { + limLog(mac, LOGE, + FL("Unable to allocate memory during del bss" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set((tANI_U8 *) delbss_params, sizeof(tDeleteBssParams), 0); + + delbss_params->sessionId = session_entry->peSessionId; + + if (sta_ds != NULL) { + delbss_params->bssIdx = sta_ds->bssId; + sta_ds->valid = 0; + sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; + } + else + delbss_params->bssIdx = bss_idx; + + session_entry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE; + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, + session_entry->peSessionId, eLIM_MLM_WT_DEL_BSS_RSP_STATE)); + + delbss_params->status= eHAL_STATUS_SUCCESS; + delbss_params->respReqd = 1; + + limLog(mac, LOG1, FL("Sessionid %d bss idx: %x BSSID:" MAC_ADDRESS_STR), + delbss_params->sessionId, delbss_params->bssIdx, + MAC_ADDR_ARRAY(session_entry->bssId)); + + /* we need to defer the message until we get the response back from HAL. */ + SET_LIM_PROCESS_DEFD_MESGS(mac, false); + + msg.type = WDA_DELETE_BSS_REQ; + msg.reserved = 0; + msg.bodyptr = delbss_params; + msg.bodyval = 0; + + MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type)); + + if(eSIR_SUCCESS != (ret_code = wdaPostCtrlMsg(mac, &msg))) + { + SET_LIM_PROCESS_DEFD_MESGS(mac, true); + limLog(mac, LOGE, + FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"), ret_code); + vos_mem_free(delbss_params); + } + + return ret_code; +} + +/* + * lim_add_bss_mbb() -performs add bss of new roamable AP + * @mac: MAC context + * @sta_ds: station entry + * @bss_idx:BSS index + * @session_entry: session entry + * + * This function performs add bss of new roamable AP + */ +void lim_add_bss_mbb(tpAniSirGlobal mac, tpDphHashNode sta_ds, + tpPESession session_entry) +{ + tSirMsgQ msg; + tSirRetStatus ret_code; + + /* we need to defer the message until we get the response back from HAL. */ + SET_LIM_PROCESS_DEFD_MESGS(mac, false); + + msg.type = SIR_HAL_ADD_BSS_REQ; + msg.reserved = 0; + msg.bodyptr = mac->ft.ftPEContext.pAddBssReq; + msg.bodyval = 0; + + limLog(mac, LOG1, FL("Sending SIR_HAL_ADD_BSS_REQ")); + + session_entry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE; + + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, + session_entry->peSessionId, eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE)); + + MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type)); + + ret_code = wdaPostCtrlMsg(mac, &msg); + if( eSIR_SUCCESS != ret_code) { + vos_mem_free(mac->ft.ftPEContext.pAddBssReq); + limLog(mac, LOGE, + FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"), ret_code); + } + /* Dont need this anymore */ + mac->ft.ftPEContext.pAddBssReq = NULL; +} + +tSirRetStatus lim_add_sta_mbb(tpAniSirGlobal mac, tANI_U16 assoc_id, + tpPESession session_entry) +{ + tpAddStaParams add_sta_params = NULL; + tSirMsgQ msg; + tSirRetStatus retCode = eSIR_SUCCESS; + + add_sta_params = mac->ft.ftPEContext.pAddStaReq; + add_sta_params->assocId = assoc_id; + + msg.type = SIR_HAL_ADD_STA_REQ; + msg.reserved = 0; + msg.bodyptr = add_sta_params; + msg.bodyval = 0; + + limLog(mac, LOG1, + FL("Sending SIR_HAL_ADD_STA_REQ. aid %d)"), + add_sta_params->assocId); + + session_entry->limPrevMlmState = session_entry->limMlmState; + session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE; + + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, + session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE)); + + MTRACE(macTraceMsgTx(mac, session_entry->peSessionId, msg.type)); + + if(eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( mac, &msg))) { + limLog(mac, LOGE, + FL("Posting ADD_STA_REQ to HAL failed, reason=%X"), retCode); + vos_mem_free(add_sta_params); + } + + mac->ft.ftPEContext.pAddStaReq = NULL; + return retCode; +} + +/* + * lim_handle_reassoc_mbb_success() -handles reassoc success + * @mac: MAC context + * @session_entry: session entry + * @assoc_rsp: pointer to assoc response + * @sta_ds : station entry + * + * This function handles reassoc success + */ +void lim_handle_reassoc_mbb_success(tpAniSirGlobal mac, + tpPESession session_entry, tpSirAssocRsp assoc_rsp, tpDphHashNode sta_ds) +{ + tpPESession session_entry_con_ap; + tANI_U8 session_id_connected_ap; + tpDphHashNode sta_ds_connected_ap; + tANI_U16 aid; + tSirRetStatus ret_code; + + limUpdateAssocStaDatas(mac, sta_ds, assoc_rsp, session_entry); + + /* Store assigned AID for TIM processing */ + session_entry->limAID = assoc_rsp->aid & 0x3FFF; + + /* De register STA for currently connected AP */ + mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId, + NULL, NULL, SIR_ROAMING_DEREGISTER_STA); + + mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId, + NULL, NULL, SIR_STOP_ROAM_OFFLOAD_SCAN); + + if((session_entry_con_ap = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, + &session_id_connected_ap))== NULL) { + limLog(mac, LOGE, + FL("session does not exist for given BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId)); + goto end; + } + + session_entry->smeSessionId = session_entry_con_ap->smeSessionId; + + sta_ds_connected_ap = dphLookupHashEntry(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, + &aid, + &session_entry_con_ap->dph.dphHashTable); + if (sta_ds_connected_ap == NULL) { + limLog(mac, LOGE, + FL("sta_ds NULL for given BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId)); + goto end; + } + + /* + * Change Mlm state of new AP to Del sta rsp state so that + * duplicate reassoc response will be dropped. + */ + session_entry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE; + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, + session_entry->peSessionId, eLIM_MLM_WT_DEL_STA_RSP_STATE)); + + /* Delete sta for currently connected AP */ + ret_code = lim_del_sta_mbb(mac, sta_ds_connected_ap, + false, session_entry_con_ap); + if (ret_code == eSIR_SUCCESS) + return; + +end: + /* Connected AP lim cleanup.*/ + lim_cleanup_connected_ap(mac, sta_ds_connected_ap, session_entry_con_ap); + /* + * eHAL_STATUS_INVALID_PARAMETER is used + * so that full cleanup is triggered. + */ + lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER, + (tANI_U32 *)session_entry); +} + + +/* + * lim_process_preauth_mbb_result() -process pre auth result + * @mac: MAC context + * @status: status + * @data: pointer to data + * + * This function invokes resume callback + */ +static inline void lim_process_preauth_mbb_result(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data) +{ + tpPESession session_entry, ft_session_entry; + tpDphHashNode sta_ds; + tAddBssParams *add_bss_params; + tSirSmeJoinReq *reassoc_req; + tLimMlmReassocReq *mlm_reassoc_req; + tANI_U16 caps; + tANI_U16 nSize; + tpSirSmeJoinReq pReassocReq = NULL; + + if (!mac->ft.ftPEContext.pFTPreAuthReq) { + limLog(mac, LOG1, "Pre-Auth request is NULL!"); + goto end; + } + + session_entry = (tpPESession)data; + + /* Post the FT Pre Auth Response to SME in case of failure*/ + if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_FAILURE) + goto end; + + /* Flow for preauth success */ + limFTSetupAuthSession(mac, session_entry); + + /* + * Prepare reassoc request. Memory allocated for tSirSmeJoinReq + *reassoc_req in csr_fill_reassoc_req. Free that memory here. + */ + mac->sme.roaming_mbb_callback(mac, mac->ft.ftSmeContext.smeSessionId, + mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription, + &reassoc_req, SIR_PREPARE_REASSOC_REQ); + if (reassoc_req == NULL) { + limLog(mac, LOGE, + FL("reassoc req is NULL")); + goto end; + } + + nSize = __limGetSmeJoinReqSizeForAlloc((tANI_U8 *) reassoc_req); + pReassocReq = vos_mem_malloc(nSize); + if ( NULL == pReassocReq ) + { + limLog(mac, LOGE, + FL("call to AllocateMemory failed for pReassocReq")); + goto end; + } + vos_mem_set((void *) pReassocReq, nSize, 0); + if ((limJoinReqSerDes(mac, (tpSirSmeJoinReq) pReassocReq, + (tANI_U8 *) reassoc_req) == eSIR_FAILURE) || + (!limIsSmeJoinReqValid(mac, + (tpSirSmeJoinReq) pReassocReq))) + { + limLog(mac, LOGE, + FL("received SME_REASSOC_REQ with invalid data")); + goto end; + } + + ft_session_entry = mac->ft.ftPEContext.pftSessionEntry; + + ft_session_entry->pLimReAssocReq = pReassocReq; + vos_mem_free(reassoc_req); + + add_bss_params = mac->ft.ftPEContext.pAddBssReq; + + mlm_reassoc_req = vos_mem_malloc(sizeof(tLimMlmReassocReq)); + if (NULL == mlm_reassoc_req) { + limLog(mac, LOGE, + FL("call to AllocateMemory failed for mlmReassocReq")); + goto end; + } + + vos_mem_copy(mlm_reassoc_req->peerMacAddr, + ft_session_entry->limReAssocbssId, + sizeof(tSirMacAddr)); + mlm_reassoc_req->reassocFailureTimeout = PREAUTH_REASSOC_TIMEOUT; + + if (cfgGetCapabilityInfo(mac, &caps, ft_session_entry) != eSIR_SUCCESS) { + limLog(mac, LOGE, FL("could not retrieve Capabilities value")); + vos_mem_free(mlm_reassoc_req); + goto end; + } + + lim_update_caps_info_for_bss(mac, &caps, + reassoc_req->bssDescription.capabilityInfo); + + limLog(mac, LOG1, FL("Capabilities info Reassoc: 0x%X"), caps); + + mlm_reassoc_req->capabilityInfo = caps; + mlm_reassoc_req->sessionId = ft_session_entry->peSessionId; + mlm_reassoc_req->listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF; + + if ((sta_ds = dphAddHashEntry(mac, add_bss_params->bssId, + DPH_STA_HASH_INDEX_PEER, + &ft_session_entry->dph.dphHashTable)) == NULL) { + limLog(mac, LOGE, FL("could not add hash entry at DPH")); + limPrintMacAddr(mac, add_bss_params->bssId, LOGE); + vos_mem_free(mlm_reassoc_req); + goto end; + } + + /* Start timer here to handle reassoc timeout */ + mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId = + ft_session_entry->peSessionId; + + MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE, + session_entry->peSessionId, eLIM_REASSOC_MBB_RSP_TIMER)); + + if(TX_SUCCESS != + tx_timer_activate(&mac->lim.limTimers.glim_reassoc_mbb_rsp_timer)) { + limLog(mac, LOGE, FL("Reassoc MBB Rsp Timer Start Failed")); + + if (ft_session_entry->pLimReAssocReq) { + vos_mem_free(ft_session_entry->pLimReAssocReq); + ft_session_entry->pLimReAssocReq = NULL; + } + + vos_mem_free(mlm_reassoc_req); + goto end; + } + + limLog(mac, LOG1, FL("enabling caching")); + WLANTL_EnablePreAssocCaching(); + + /* To do: Add changes for reassoc fail timer */ + limSendReassocReqWithFTIEsMgmtFrame(mac, + mlm_reassoc_req, ft_session_entry); + + ft_session_entry->limMlmState = eLIM_MLM_WT_REASSOC_RSP_STATE; + + limLog(mac, LOG1, FL("Set the mlm state to %d session=%d"), + ft_session_entry->limMlmState, ft_session_entry->peSessionId); + return; + +end: + lim_handle_reassoc_mbb_fail(mac, ft_session_entry); +} + +/* + * lim_perform_post_preauth_mbb_channel_change() -invokes resume callback + * @mac: MAC context + * @status: status + * @data: pointer to data + * @session_entry: session entry + * + * This function invokes resume callback after successful reception of + * pre auth + */ +static inline +void lim_perform_post_preauth_mbb_channel_change(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data, tpPESession session_entry) +{ + peSetResumeChannel(mac, 0, 0); + limResumeLink(mac, lim_process_preauth_mbb_result, + (tANI_U32 *)session_entry); +} + +/* + * lim_handle_pre_auth_mbb_rsp() -handles preauth response + * @mac: MAC context + * @status: status of message + * @session_entry: session entry + * + * This function process preauth response + */ +void lim_handle_pre_auth_mbb_rsp(tpAniSirGlobal mac, + tSirRetStatus status, tpPESession session_entry) +{ + tpPESession ft_session_entry; + tANI_U8 session_id; + tpSirBssDescription bss_description; + + mac->ft.ftPEContext.ftPreAuthStatus = status; + + mac->ft.ftPEContext.saved_auth_rsp_length = 0; + + limLog(mac, LOG1, FL("preauth status %d"), + mac->ft.ftPEContext.ftPreAuthStatus); + + /* Create FT session for the re-association at this point */ + if (mac->ft.ftPEContext.ftPreAuthStatus == eSIR_SUCCESS) { + bss_description = mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription; + if((ft_session_entry = peCreateSession(mac, bss_description->bssId, + &session_id, mac->lim.maxStation)) == NULL) { + limLog(mac, LOGE, + FL("session can not be created for pre-auth AP")); + mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE; + goto out; + } + ft_session_entry->peSessionId = session_id; + sirCopyMacAddr(ft_session_entry->selfMacAddr, + session_entry->selfMacAddr); + sirCopyMacAddr(ft_session_entry->limReAssocbssId, + bss_description->bssId); + ft_session_entry->bssType = session_entry->bssType; + + if (ft_session_entry->bssType == eSIR_INFRASTRUCTURE_MODE) + ft_session_entry->limSystemRole = eLIM_STA_ROLE; + + ft_session_entry->limSmeState = eLIM_SME_WT_REASSOC_STATE; + mac->ft.ftPEContext.pftSessionEntry = ft_session_entry; + limLog(mac, LOG1,"%s:created session (%p) with id = %d", + __func__, ft_session_entry, ft_session_entry->peSessionId); + + /* Update the ReAssoc BSSID of the current session */ + sirCopyMacAddr(session_entry->limReAssocbssId, bss_description->bssId); + limPrintMacAddr(mac, session_entry->limReAssocbssId, LOG1); + + /* Prepare session for roamable AP */ + lim_process_preauth_mbb_result(mac, + mac->ft.ftPEContext.ftPreAuthStatus, (tANI_U32 *)session_entry); + return; + }else { + lim_handle_preauth_mbb_fail(mac, session_entry); + return; + } + +out: + /* This sequence needs to be executed in case of failure*/ + if (session_entry->currentOperChannel != + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) { + limChangeChannelWithCallback(mac, session_entry->currentOperChannel, + lim_perform_post_preauth_mbb_channel_change, NULL, session_entry); + } else { + /* Link needs to be resumed as link was suspended for same channel */ + peSetResumeChannel(mac, 0, 0); + limResumeLink(mac, lim_process_preauth_mbb_result, + (tANI_U32 *)session_entry); + } +} + +/** + * lim_process_preauth_mbb_rsp_timeout() -Process preauth response timeout + * @mac: MAC context + * + * This function is called if preauth response is not received from the AP + * within timeout + */ +void lim_process_preauth_mbb_rsp_timeout(tpAniSirGlobal mac) +{ + tpPESession session_entry; + + /* + * Pre auth is failed. Need to resume link and get back on + * to home channel. + */ + limLog(mac, LOG1, FL("Pre-Auth MBB Time Out!!!!")); + + if((session_entry = peFindSessionBySessionId(mac, + mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId))== NULL) { + limLog(mac, LOGE, FL("session does not exist for given session id")); + return; + } + + /* + * To handle the race condition where we recieve preauth rsp after + * timer has expired. + */ + if (mac->ft.ftPEContext.pFTPreAuthReq == NULL) { + limLog(mac, LOGE, FL("Auth Rsp might already be posted to SME" + "and cleanup done! sessionId:%d"), + mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId); + return; + } + + if (eANI_BOOLEAN_TRUE == + mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed) { + limLog(mac, LOGE, + FL("Auth rsp already posted to SME session %p"), session_entry); + return; + } else { + /* + * Here we are sending preauth rsp with failure state + * and which is forwarded to SME. Now, if we receive an preauth + * resp from AP with success it would create a FT pesession, but + * will be dropped in SME leaving behind the pesession. + * Mark Preauth rsp processed so that any rsp from AP is dropped in + * limProcessAuthFrameNoSession. + */ + limLog(mac,LOG1, + FL("Auth rsp not yet posted to SME session %p)"), session_entry); + mac->ft.ftPEContext.pFTPreAuthReq->bPreAuthRspProcessed = + eANI_BOOLEAN_TRUE; + } + /* + * Ok, so attempted a Pre-Auth and failed. If we are off channel. We need + * to get back. + */ + lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry); + } + +/** + * lim_process_reassoc_mbb_rsp_timeout() -Process reassoc response timeout + * @mac: MAC context + * + * This function is called if preauth response is not received from the + * AP within timeout + */ +void lim_process_reassoc_mbb_rsp_timeout(tpAniSirGlobal mac) +{ + tpPESession session_entry, ft_session_entry; + tANI_U8 session_id; + + if((ft_session_entry = peFindSessionBySessionId(mac, + mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId))== NULL) { + limLog(mac, LOGE, + FL("ft session does not exist for given session id %d"), + mac->lim.limTimers.glim_reassoc_mbb_rsp_timer.sessionId); + return; + } + + limLog(mac, LOG1, FL("Reassoc timeout happened in state %d"), + ft_session_entry->limMlmState); + + if((session_entry = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id))== NULL) { + limLog(mac, LOGE, + FL("session does not exist for given BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(mac->ft.ftPEContext.pFTPreAuthReq->currbssId)); + return; + } + + lim_handle_reassoc_mbb_fail(mac, ft_session_entry); + +} + + +/** + * lim_perform_pre_auth_reassoc() -Sends preauth request + * @mac: MAC context + * @status: status of message + * @data: gives information of session + * @session_entry: session entry + * + * This function process preauth request received from CSR + */ +static inline +void lim_perform_pre_auth_reassoc(tpAniSirGlobal mac, eHalStatus status, + tANI_U32 *data, tpPESession session_entry) +{ + tSirMacAuthFrameBody authFrame; + + if (status != eHAL_STATUS_SUCCESS) { + limLog(mac, LOGE, + FL("Change channel not successful for pre-auth")); + goto preauth_fail; + } + + limLog(mac, LOGE, + FL("session id %d"), session_entry->peSessionId); + + mac->ft.ftPEContext.psavedsessionEntry = session_entry; + + authFrame.authAlgoNumber = eSIR_OPEN_SYSTEM; + authFrame.authTransactionSeqNumber = SIR_MAC_AUTH_FRAME_1; + authFrame.authStatusCode = 0; + + /* Start timer here to come back to operating channel. */ + mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer.sessionId = + session_entry->peSessionId; + + limSendAuthMgmtFrame(mac, &authFrame, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + LIM_NO_WEP_IN_FC, session_entry, eSIR_FALSE); + + MTRACE(macTrace(mac, TRACE_CODE_TIMER_ACTIVATE, + session_entry->peSessionId, eLIM_PREAUTH_MBB_RSP_TIMER)); + + if(TX_SUCCESS != + tx_timer_activate(&mac->lim.limTimers.glim_pre_auth_mbb_rsp_timer)) { + limLog(mac, LOGE, FL("Pre Auth MBB Rsp Timer Start Failed")); + + mac->ft.ftPEContext.psavedsessionEntry = NULL; + goto preauth_fail; + } + + return; + +preauth_fail: + lim_handle_pre_auth_mbb_rsp(mac, eSIR_FAILURE, session_entry); + return; +} + +/** + * pre_auth_mbb_suspend_link_handler() -Handler for suspend link + * @mac: MAC context + * @status: status of message + * @data: gives information of session + * + * This function process preauth request received from CSR + */ +static inline +void pre_auth_mbb_suspend_link_handler(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data) +{ + tpPESession session_entry; + + if (status != eHAL_STATUS_SUCCESS) { + limLog(mac, LOGE, FL("Link suspend failed")); + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, + (tpPESession)data, SIR_MBB_CONNECTED); + return; + } + + session_entry = (tpPESession)data; + + if (session_entry->currentOperChannel != + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum) { + limChangeChannelWithCallback(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum, + lim_perform_pre_auth_reassoc, NULL, session_entry); + return; + } else { + lim_perform_pre_auth_reassoc(mac, eHAL_STATUS_SUCCESS, + NULL, session_entry); + return; + } +} + +/** + * lim_process_pre_auth_reassoc_req() -Process preauth request + * @hal: HAL context + * @msg: message + * + * This function process preauth request received from CSR + */ +void lim_process_pre_auth_reassoc_req(tpAniSirGlobal mac, tpSirMsgQ msg) +{ + tpPESession session_entry; + tANI_U8 session_id; + + limFTInit(mac); + + /* Can set it only after sending auth */ + mac->ft.ftPEContext.ftPreAuthStatus = eSIR_FAILURE; + + /* We need information from the Pre-Auth Req. Lets save that */ + mac->ft.ftPEContext.pFTPreAuthReq = (tpSirFTPreAuthReq)msg->bodyptr; + if (!mac->ft.ftPEContext.pFTPreAuthReq) { + limLog(mac, LOGE, + FL("pFTPreAuthReq is NULL")); + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + /* Get the current session entry */ + session_entry = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, &session_id); + if (session_entry == NULL) { + limLog(mac, LOGE, + FL("Unable to find session for the following bssid")); + limPrintMacAddr(mac, + mac->ft.ftPEContext.pFTPreAuthReq->currbssId, LOGE); + + /* Post the pre auth response to SME */ + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + limLog(mac, LOG1, + FL("set link with eSIR_LINK_PRE_AUTH_REASSOC_STATE")); + + if (limSetLinkState(mac, eSIR_LINK_PRE_AUTH_REASSOC_STATE, + session_entry->bssId, session_entry->selfMacAddr, + NULL, NULL) != eSIR_SUCCESS) { + limLog(mac, LOGE, + FL("set link failed for eSIR_LINK_PRE_AUTH_REASSOC_STATE")); + lim_post_pre_auth_reassoc_rsp(mac, eSIR_FAILURE, NULL, + SIR_MBB_CONNECTED); + return; + } + + /* + * Suspend link for same channel or different channel so that STA + * can be in power save for connected AP. + */ + limLog(mac, LOG1, + FL("pre-auth on channel %d (session %p) currentOperChannel %d"), + mac->ft.ftPEContext.pFTPreAuthReq->preAuthchannelNum, + session_entry, session_entry->currentOperChannel); + limSuspendLink(mac, eSIR_CHECK_ROAMING_SCAN, + pre_auth_mbb_suspend_link_handler, + (tANI_U32 *)session_entry); +} + + +/** + * lim_process_sta_mlm_del_sta_rsp_mbb() -Process del sta response + * @mac: MAC context + * @lim_msg: lim message + * @session_entry: session entry + * + * This function process del sta response + */ +void lim_process_sta_mlm_del_sta_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ lim_msg, tpPESession session_entry) +{ + tpDeleteStaParams del_sta_params = (tpDeleteStaParams)lim_msg->bodyptr; + tpDphHashNode sta_ds = NULL; + tANI_U8 session_id; + tpPESession ft_session_entry; + + if(NULL == del_sta_params) { + limLog(mac, LOGE, FL("Encountered NULL Pointer")); + goto end; + } + + limLog(mac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"), + del_sta_params->status, del_sta_params->assocId); + + if (eHAL_STATUS_SUCCESS != del_sta_params->status) { + limLog(mac, LOGE, FL("Del STA failed! Status:%d, still proceeding" + "with Del BSS"), del_sta_params->status); + } + + sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER, + &session_entry->dph.dphHashTable); + + if (sta_ds == NULL) { + limLog( mac, LOGE, FL("DPH Entry for STA %X missing"), + del_sta_params->assocId); + goto end; + } + + if (eLIM_MLM_WT_DEL_STA_RSP_STATE != session_entry->limMlmState) { + limLog(mac, LOGE, + FL( "Received unexpected WDA_DELETE_STA_RSP in state %s" ), + limMlmStateStr(session_entry->limMlmState)); + goto end; + } + + limLog( mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId); + limPrintMacAddr(mac, sta_ds->staAddr, LOG1); + + /* + * we must complete all cleanup related to del sta + * before calling del bss. + */ + if (NULL != lim_msg->bodyptr) { + vos_mem_free(del_sta_params); + lim_msg->bodyptr = NULL; + } + + /* Proceed to do del bss even if del sta resulted in failure */ + lim_del_bss_mbb(mac, sta_ds, 0, session_entry); + return; + +end: + if(NULL != lim_msg->bodyptr) { + vos_mem_free(del_sta_params); + lim_msg->bodyptr = NULL; + } + + /* Connected AP lim cleanup.*/ + lim_cleanup_connected_ap(mac, sta_ds, session_entry); + + ft_session_entry = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + &session_id); + if (ft_session_entry == NULL) { + limLog(mac, LOGE, + FL("Unable to find session for the following bssid")); + limPrintMacAddr(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE); + return; + } + + /* + * eHAL_STATUS_INVALID_PARAMETER is used + * so that full cleanup is triggered. + */ + lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER, + (tANI_U32 *)ft_session_entry); +} + +/** + * lim_cleanup_rx_path_mbb() -cleans up tspec related info + * @mac: MAC context + * @sta_ds: station entry + * @session_entry: session entry of connected AP + * + * This function cleans up tspec related info + */ +void lim_cleanup_rx_path_mbb(tpAniSirGlobal mac, + tpDphHashNode sta_ds,tpPESession session_entry) +{ + limLog(mac, LOG1, FL("AID %d limSmeState %d, mlmState %d"), + sta_ds->assocId, session_entry->limSmeState, + sta_ds->mlmStaContext.mlmState); + + session_entry->isCiscoVendorAP = FALSE; + + if (mac->lim.gLimAddtsSent) + tx_timer_deactivate(&mac->lim.limTimers.gLimAddtsRspTimer); + + /* delete all tspecs associated with this sta. */ + limAdmitControlDeleteSta(mac, sta_ds->assocId); +} + + +/** + * lim_cleanup_connected_ap() -cleans up connected AP lim info + * @mac: MAC context + * @sta_ds: station entry + * @session_entry: session entry of connected AP + * + * This function cleans up connected AP lim info + */ +void lim_cleanup_connected_ap(tpAniSirGlobal mac, tpDphHashNode sta_ds, + tpPESession session_entry) +{ + lim_cleanup_rx_path_mbb(mac, sta_ds, session_entry); + limDeleteDphHashEntry(mac, sta_ds->staAddr, + sta_ds->assocId, session_entry); + + /** + * Make STA hash entry invalid at eCPU so that DPH + * does not process any more data packets and + * releases those BDs + */ + sta_ds->valid = 0; + + peDeleteSession(mac, session_entry); +} + +/** + * lim_process_sta_mlm_del_bss_rsp_mbb() -Process del bss response of + * connected AP + * @mac: MAC context + * @lim_msg: lim message + * @session_entry: session entry of connected AP + * + * This function process del sta response + */ +void lim_process_sta_mlm_del_bss_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ lim_msg, tpPESession session_entry) +{ + tpDeleteBssParams delbss_params = (tpDeleteBssParams)lim_msg->bodyptr; + tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER, + &session_entry->dph.dphHashTable); + tpPESession ft_session_entry; + tANI_U8 session_id; + + if (NULL == delbss_params) { + limLog(mac, LOGE, FL( "Invalid body pointer in message")); + goto end; + } + + ft_session_entry = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + &session_id); + if (ft_session_entry == NULL) { + limLog(mac, LOGE, + FL("Unable to find session for the following bssid")); + limPrintMacAddr(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE); + goto end; + } + + if(eHAL_STATUS_SUCCESS == delbss_params->status) { + limLog(mac, LOG1, + FL( "STA received the DEL_BSS_RSP for BSSID: %X."), + delbss_params->bssIdx); + + if(sta_ds == NULL) { + limLog(mac, LOGE, FL("DPH Entry for STA missing")); + goto end; + } + if(eLIM_MLM_WT_DEL_BSS_RSP_STATE != session_entry->limMlmState) { + limLog(mac, LOGE, + FL("Received unexpected WDA_DEL_BSS_RSP in state %d"), + session_entry->limMlmState); + goto end; + } + limLog(mac, LOG1, FL("STA AssocID %d MAC "), sta_ds->assocId ); + limPrintMacAddr(mac, sta_ds->staAddr, LOG1); + + lim_cleanup_connected_ap(mac, sta_ds, session_entry); + + lim_add_bss_mbb(mac, sta_ds, ft_session_entry); + + if(NULL != lim_msg->bodyptr) { + vos_mem_free(delbss_params); + lim_msg->bodyptr = NULL; + } + return; + } else { + /* + * If del bss response is failure, cleanup sessions of both currently + * connected AP and roamable AP as add bss can not be send + * without successful delbss. + */ + limLog(mac, LOGE, + FL("DEL BSS failed! Status:%d"), delbss_params->status); + + if(NULL != lim_msg->bodyptr) { + vos_mem_free(delbss_params); + lim_msg->bodyptr = NULL; + } + + /* Connected AP lim cleanup.*/ + lim_cleanup_connected_ap(mac, sta_ds, session_entry); + + /* Newly created session cleanup */ + lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_DEL_BSS_FAIL, + (tANI_U32 *)ft_session_entry); + return; + } + +end: + if(NULL != lim_msg->bodyptr) { + vos_mem_free(delbss_params); + lim_msg->bodyptr = NULL; + } + + lim_cleanup_connected_ap(mac, sta_ds, session_entry); + + ft_session_entry = peFindSessionByBssid(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, + &session_id); + if (ft_session_entry == NULL) { + limLog(mac, LOGE, + FL("Unable to find session for the following bssid")); + limPrintMacAddr(mac, + mac->ft.ftPEContext.pFTPreAuthReq->preAuthbssId, LOGE); + return; + } + + /* + * eHAL_STATUS_INVALID_PARAMETER is used + * so that full cleanup is triggered. + */ + lim_reassoc_fail_cleanup(mac, eHAL_STATUS_INVALID_PARAMETER, + (tANI_U32 *)ft_session_entry); +} + + +void lim_fill_add_sta_params_mbb(tpAniSirGlobal mac, + tpPESession session_entry, tpAddStaParams add_sta_params) +{ + tANI_U32 listen_interval = WNI_CFG_LISTEN_INTERVAL_STADEF; + tANI_U32 self_sta_dot11_mode = 0; + + vos_mem_copy(add_sta_params->staMac, session_entry->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(add_sta_params->bssId, session_entry->bssId, + sizeof(tSirMacAddr)); + + add_sta_params->staType = STA_ENTRY_SELF; + add_sta_params->status = eHAL_STATUS_SUCCESS; + add_sta_params->respReqd = 1; + + add_sta_params->sessionId = session_entry->peSessionId; + add_sta_params->staIdx = HAL_STA_INVALID_IDX; + add_sta_params->updateSta = FALSE; + + add_sta_params->shortPreambleSupported = + session_entry->beaconParams.fShortPreamble; + +#ifdef WLAN_FEATURE_11AC + limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL, + false,session_entry, NULL); +#else + limPopulatePeerRateSet(mac, &add_sta_params->supportedRates, NULL, + false,session_entry); +#endif + + if(session_entry->htCapability) { + add_sta_params->htCapable = session_entry->htCapability; +#ifdef WLAN_FEATURE_11AC + add_sta_params->vhtCapable = session_entry->vhtCapability; + add_sta_params->vhtTxChannelWidthSet = session_entry->vhtTxChannelWidthSet; +#endif + +#ifdef DISABLE_GF_FOR_INTEROP + if((session_entry->pLimJoinReq != NULL) && + (!session_entry->pLimJoinReq->bssDescription.aniIndicator)) { + limLog(mac, LOGE, + FL("Turning off Greenfield, when adding self entry")); + add_sta_params->greenFieldCapable = + WNI_CFG_GREENFIELD_CAPABILITY_DISABLE; + } + else +#endif + add_sta_params->greenFieldCapable = + limGetHTCapability( mac, eHT_GREENFIELD, session_entry); + + if (session_entry->limRFBand == SIR_BAND_2_4_GHZ) + add_sta_params->txChannelWidthSet = + mac->roam.configParam.channelBondingMode24GHz; + else + add_sta_params->txChannelWidthSet = + mac->roam.configParam.channelBondingMode5GHz; + + add_sta_params->mimoPS = + limGetHTCapability(mac, eHT_MIMO_POWER_SAVE, session_entry); + add_sta_params->rifsMode = + limGetHTCapability(mac, eHT_RIFS_MODE, session_entry); + add_sta_params->lsigTxopProtection = + limGetHTCapability(mac, eHT_LSIG_TXOP_PROTECTION, session_entry); + add_sta_params->delBASupport = + limGetHTCapability(mac, eHT_DELAYED_BA, session_entry); + add_sta_params->maxAmpduDensity = + limGetHTCapability(mac, eHT_MPDU_DENSITY, session_entry); + add_sta_params->maxAmpduSize = + limGetHTCapability(mac, eHT_MAX_RX_AMPDU_FACTOR, session_entry); + add_sta_params->maxAmsduSize = + limGetHTCapability(mac, eHT_MAX_AMSDU_LENGTH, session_entry); + add_sta_params->fDsssCckMode40Mhz = + limGetHTCapability(mac, eHT_DSSS_CCK_MODE_40MHZ, session_entry); + add_sta_params->fShortGI20Mhz = + limGetHTCapability(mac, eHT_SHORT_GI_20MHZ, session_entry); + add_sta_params->fShortGI40Mhz = + limGetHTCapability(mac, eHT_SHORT_GI_40MHZ, session_entry); + } + + if (wlan_cfgGetInt(mac, WNI_CFG_LISTEN_INTERVAL, + &listen_interval) != eSIR_SUCCESS) + limLog(mac, LOGE, FL("Couldn't get LISTEN_INTERVAL")); + + add_sta_params->listenInterval = (tANI_U16)listen_interval; + + wlan_cfgGetInt(mac, WNI_CFG_DOT11_MODE, &self_sta_dot11_mode); + add_sta_params->supportedRates.opRateMode = + limGetStaRateMode((tANI_U8)self_sta_dot11_mode); + + mac->ft.ftPEContext.pAddStaReq = add_sta_params; + + +} + +void lim_process_sta_mlm_add_bss_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ limMsgQ,tpPESession session_entry) +{ + tpAddBssParams add_bss_params = (tpAddBssParams)limMsgQ->bodyptr; + tpAddStaParams add_sta_params = NULL; + tpDphHashNode sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER, + &session_entry->dph.dphHashTable); + + if(add_bss_params == 0) + goto end; + + limLog(mac, LOG1, FL("Add BSS RSP received. Status:%d"), + add_bss_params->status); + + if(eHAL_STATUS_SUCCESS == add_bss_params->status) { + + if(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE != session_entry->limMlmState) { + limLog(mac, LOGE, + FL("Received unexpected ADD BSS in state %d"), + session_entry->limMlmState); + goto end; + } + + session_entry->bssIdx = add_bss_params->bssIdx; + + sta_ds->bssId = add_bss_params->bssIdx; + sta_ds->staIndex = add_bss_params->staContext.staIdx; + sta_ds->ucUcastSig = add_bss_params->staContext.ucUcastSig; + sta_ds->ucBcastSig = add_bss_params->staContext.ucBcastSig; + + rrmCacheMgmtTxPower(mac, add_bss_params->txMgmtPower, session_entry); + + /* Allocate memory for add sta params */ + add_sta_params = vos_mem_malloc(sizeof( tAddStaParams )); + if (NULL == add_sta_params) { + limLog(mac, LOGE, + FL("Unable to allocate memory during ADD_STA")); + goto end; + } + vos_mem_set(add_sta_params, sizeof(tAddStaParams), 0); + + /* Prepare add sta params */ + lim_fill_add_sta_params_mbb(mac, session_entry, add_sta_params); + + if(0 != limMsgQ->bodyptr) { + vos_mem_free(add_bss_params); + add_bss_params = NULL; + limMsgQ->bodyptr = NULL; + } + + lim_add_sta_mbb(mac, session_entry->limAID, session_entry); + + } else { + /* + * If add bss response is failure, cleanup session of roamable AP + * as cleanup of connected bss happened during del bss + */ + limLog(mac, LOGE, + FL("ADD BSS failed! Status:%d"), add_bss_params->status); + + /* Newly created session cleanup */ + lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL, + (tANI_U32 *)session_entry); + } + +end: + if(0 != limMsgQ->bodyptr) { + vos_mem_free(add_bss_params); + add_bss_params = NULL; + limMsgQ->bodyptr = NULL; + } +} + +/* + * lim_perform_post_add_sta_rsp() -invokes resume callback to handle add sta response + * @mac: MAC context + * @status: status + * @data: pointer to data + * + * This function invokes resume callback + */ +void lim_perform_post_add_sta_rsp(tpAniSirGlobal mac, + eHalStatus status, tANI_U32 *data) +{ + tpDphHashNode sta_ds; + /* session entry for newly roamed ap */ + tpPESession session_entry; + + session_entry = (tpPESession)data; + + limLog(mac, LOG1, FL("forwarding cached packets")); + WLANTL_PreAssocForward(true); + + sta_ds = dphGetHashEntry(mac, DPH_STA_HASH_INDEX_PEER, + &session_entry->dph.dphHashTable); + if(NULL != sta_ds) + sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + else { + limLog(mac, LOGE, + FL("Unable to get the DPH Hash Entry for AID - %d"), + DPH_STA_HASH_INDEX_PEER); + return; + } + + session_entry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + MTRACE(macTrace(mac, TRACE_CODE_MLM_STATE, + session_entry->peSessionId, eLIM_MLM_LINK_ESTABLISHED_STATE)); + +#ifdef FEATURE_WLAN_TDLS + /* initialize TDLS peer related data */ + limInitTdlsData(mac, session_entry); +#endif + + if (limSetLinkState(mac, eSIR_LINK_POSTASSOC_STATE, session_entry->bssId, + session_entry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS) { + limLog(mac, LOGE, FL("Set link state to POSTASSOC failed")); + return; + } + + session_entry->limSmeState = eLIM_SME_LINK_EST_STATE; + + lim_post_pre_auth_reassoc_rsp(mac, eSIR_SUCCESS, session_entry, + SIR_MBB_CONNECTED); + + /* Freeup the cached preauth request */ + if (mac->ft.ftPEContext.pFTPreAuthReq) { + limLog(mac, LOG1, FL("Freeing pFTPreAuthReq= %p"), + mac->ft.ftPEContext.pFTPreAuthReq); + if (mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription) { + vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription); + mac->ft.ftPEContext.pFTPreAuthReq->pbssDescription = NULL; + } + vos_mem_free(mac->ft.ftPEContext.pFTPreAuthReq); + mac->ft.ftPEContext.pFTPreAuthReq = NULL; + } +} + +void lim_process_sta_mlm_add_sta_rsp_mbb(tpAniSirGlobal mac, + tpSirMsgQ limMsgQ,tpPESession session_entry) +{ + tpAddStaParams add_sta_params = (tpAddStaParams)limMsgQ->bodyptr; + + if(NULL == add_sta_params) { + limLog(mac, LOGE, FL("Encountered NULL Pointer")); + return; + } + + limLog(mac, LOG1, FL("Add STA RSP received. Status:%d"), + add_sta_params->status); + + if (eHAL_STATUS_SUCCESS == add_sta_params->status) { + if ( eLIM_MLM_WT_ADD_STA_RSP_STATE != session_entry->limMlmState) { + limLog(mac, LOGE, + FL("Received unexpected ADD_STA_RSP in state %d"), + session_entry->limMlmState); + goto end; + } + + /* + * Storing the self StaIndex(Generated by HAL) in session context, + * instead of storing it in DPH Hash entry for Self STA. + * DPH entry for the self STA stores the sta index for the BSS entry + * to which the STA is associated. + */ + session_entry->staId = add_sta_params->staIdx; + + limLog(mac, LOG1, FL("resuming to oper ch %d"), + session_entry->currentOperChannel); + + peSetResumeChannel(mac, session_entry->currentOperChannel, 0); + limResumeLink(mac, lim_perform_post_add_sta_rsp, (tANI_U32 *)session_entry); + } else { + limLog(mac, LOGE, FL( "ADD_STA failed!")); + + /* Newly created session cleanup */ + lim_reassoc_fail_cleanup(mac, eHAL_STATUS_MBB_ADD_BSS_FAIL, + (tANI_U32 *)session_entry); + + } +end: + if( 0 != limMsgQ->bodyptr ) + { + vos_mem_free(add_sta_params); + limMsgQ->bodyptr = NULL; + } +} + +eAniBoolean lim_is_mbb_reassoc_in_progress(tpAniSirGlobal mac, + tpPESession session_entry) +{ + if (session_entry == NULL) + return eANI_BOOLEAN_FALSE; + + if ((eLIM_STA_ROLE == session_entry->limSystemRole) && + mac->ft.ftSmeContext.is_preauth_lfr_mbb) { + limLog(mac, LOG1, FL("MBB Reassoc in progress")); + return eANI_BOOLEAN_TRUE; + } + + return eANI_BOOLEAN_FALSE; +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmAP.c b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmAP.c new file mode 100644 index 000000000000..528626e40710 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmAP.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file pmmAP.cc contains AP PM functions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "sirCommon.h" + +#include "aniGlobal.h" + +#include "schApi.h" +#include "limApi.h" +#include "cfgApi.h" +#include "wniCfg.h" + +#include "pmmApi.h" +#include "pmmDebug.h" + +/** + * pmmGenerateTIM + * + * FUNCTION: + * Generate TIM + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to global mac structure + * @param **pPtr pointer to the buffer, where the TIM bit is to be written. + * @param *timLength pointer to limLength, which needs to be returned. + * @return None + */ +void pmmGenerateTIM(tpAniSirGlobal pMac, tANI_U8 **pPtr, tANI_U16 *timLength, tANI_U8 dtimPeriod) +{ + tANI_U8 *ptr = *pPtr; + tANI_U32 val = 0; + tANI_U32 minAid = 1; // Always start with AID 1 as minimum + tANI_U32 maxAid = HAL_NUM_STA; + + + // Generate partial virtual bitmap + tANI_U8 N1 = minAid / 8; + tANI_U8 N2 = maxAid / 8; + if (N1 & 1) N1--; + + *timLength = N2 - N1 + 4; + val = dtimPeriod; + + /* + * 09/23/2011 - ASW team decision; + * Write 0xFF to firmware's field to detect firmware's mal-function early. + * DTIM count and bitmap control usually cannot be 0xFF, so it is easy to know that + * firmware never updated DTIM count/bitmap control field after host driver downloaded + * beacon template if end-user complaints that DTIM count and bitmapControl is 0xFF. + */ + *ptr++ = SIR_MAC_TIM_EID; + *ptr++ = (tANI_U8)(*timLength); + *ptr++ = 0xFF; // location for dtimCount. will be filled in by FW. + *ptr++ = (tANI_U8)val; + + *ptr++ = 0xFF; // location for bitmap control. will be filled in by FW. + ptr += (N2 - N1 + 1); + + PELOG2(sirDumpBuf(pMac, SIR_PMM_MODULE_ID, LOG2, *pPtr, (*timLength)+2);) + *pPtr = ptr; +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c new file mode 100644 index 000000000000..1c31dc8ec3cc --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmApi.c @@ -0,0 +1,3092 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file pmmApi.cc contains functions related to the API exposed + * by power management module + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniCfg.h" + +#include "sirCommon.h" +#include "aniGlobal.h" + +#include "schApi.h" +#include "limApi.h" +#include "limSendMessages.h" +#include "cfgApi.h" +#include "limSessionUtils.h" +#include "limFT.h" + + +#include "pmmApi.h" +#include "pmmDebug.h" +#include "sirApi.h" +#include "wmmApsd.h" + +#include "limSendSmeRspMessages.h" +#include "limTimerUtils.h" +#include "limTrace.h" +#include "limUtils.h" +#include "VossWrapper.h" +#ifdef INTEGRATION_READY +#include "vos_status.h" //VOS_STATUS +#include "vos_mq.h" //vos_mq_post_message() +#endif + +#include "wlan_qct_wda.h" + +#define LIM_ADMIT_MASK_FLAG_ACBE 1 +#define LIM_ADMIT_MASK_FLAG_ACBK 2 +#define LIM_ADMIT_MASK_FLAG_ACVI 4 +#define LIM_ADMIT_MASK_FLAG_ACVO 8 + +// -------------------------------------------------------------------- +/** + * pmmInitialize + * + * FUNCTION: + * Initialize PMM module + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param mode + * @param rate + * @return None + */ + +tSirRetStatus +pmmInitialize(tpAniSirGlobal pMac) +{ + + + pmmResetStats(pMac); + + pMac->pmm.gPmmBeaconInterval = WNI_CFG_BEACON_INTERVAL_STADEF; + pMac->pmm.gPmmState = ePMM_STATE_READY; + + + + pMac->pmm.inMissedBeaconScenario = FALSE; + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * pmmResetStats + * + * FUNCTION: + * Resets the statistics + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac + * + * @return None + */ + +void +pmmResetStats(void *pvMac) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)pvMac; + + pMac->pmm.BmpsmaxSleepTime = 0; + pMac->pmm.BmpsavgSleepTime = 0; + pMac->pmm.BmpsminSleepTime = 0; + pMac->pmm.BmpscntSleep = 0; + + pMac->pmm.BmpsmaxTimeAwake = 0; + pMac->pmm.BmpsavgTimeAwake = 0; + pMac->pmm.BmpsminTimeAwake = 0; + pMac->pmm.BmpscntAwake = 0; + + pMac->pmm.BmpsWakeupTimeStamp = 0; + pMac->pmm.BmpsSleepTimeStamp = 0; + + pMac->pmm.BmpsHalReqFailCnt = 0; + pMac->pmm.BmpsInitFailCnt = 0; + pMac->pmm.BmpsInitFailCnt= 0; + pMac->pmm.BmpsInvStateCnt= 0; + pMac->pmm.BmpsPktDrpInSleepMode= 0; + pMac->pmm.BmpsReqInInvalidRoleCnt= 0; + pMac->pmm.BmpsSleeReqFailCnt= 0; + pMac->pmm.BmpsWakeupIndCnt= 0; + + pMac->pmm.ImpsWakeupTimeStamp = 0; + pMac->pmm.ImpsSleepTimeStamp = 0; + pMac->pmm.ImpsMaxTimeAwake = 0; + pMac->pmm.ImpsMinTimeAwake = 0; + pMac->pmm.ImpsAvgTimeAwake = 0; + pMac->pmm.ImpsCntAwake = 0; + + pMac->pmm.ImpsCntSleep = 0; + pMac->pmm.ImpsMaxSleepTime = 0; + pMac->pmm.ImpsMinSleepTime = 0; + pMac->pmm.ImpsAvgSleepTime = 0; + + pMac->pmm.ImpsSleepErrCnt = 0; + pMac->pmm.ImpsWakeupErrCnt = 0; + pMac->pmm.ImpsLastErr = 0; + pMac->pmm.ImpsInvalidStateCnt = 0; + + return; +} + + + +// -------------------------------------------------------------------- +/** + * pmmInitBmpsResponseHandler + * + * FUNCTION: + * This function processes the SIR_HAL_ENTER_BMPS_RSP from HAL. + * If the response is successful, it puts PMM in ePMM_STATE_BMP_SLEEP state + * and sends back success response to PMC. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * @return None + */ + +void pmmInitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg ) +{ + + + tPmmState nextState = pMac->pmm.gPmmState; + tSirResultCodes retStatus = eSIR_SME_SUCCESS; + tpPESession psessionEntry; + tpEnterBmpsParams pEnterBmpsParams; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_ENTER_BMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(pMac->pmm.gPmmState != ePMM_STATE_BMPS_WT_INIT_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: Received 'InitPwrSaveRsp' while in incorrect state: %d"), + pMac->pmm.gPmmState);) + + retStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + goto failure; + } + + if (NULL == limMsg->bodyptr) + { + PELOGE(pmmLog(pMac, LOGE, FL("pmmBmps: Received SIR_HAL_ENTER_BMPS_RSP with NULL "));) + nextState = ePMM_STATE_READY; + retStatus = eSIR_SME_BMPS_REQ_FAILED; + goto failure; + } + pEnterBmpsParams = (tpEnterBmpsParams)(limMsg->bodyptr); + + //if response is success, then set PMM to BMPS_SLEEP state and send response back to PMC. + //If response is failure, then send the response back to PMC and reset its state. + if(pEnterBmpsParams->status == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOG1, + FL("pmmBmps: Received successful response from HAL to enter BMPS_POWER_SAVE ")); + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + + // Update sleep statistics + pmmUpdatePwrSaveStats(pMac); + + // Disable background scan mode + pMac->sys.gSysEnableScanMode = false; + + if (pMac->lim.gLimTimersCreated) + { + /* Disable heartbeat timer as well */ + if(pMac->lim.limTimers.gLimHeartBeatTimer.pMac) + { + MTRACE(macTrace(pMac, TRACE_CODE_TIMER_DEACTIVATE, NO_SESSION, eLIM_HEART_BEAT_TIMER)); + tx_timer_deactivate(&pMac->lim.limTimers.gLimHeartBeatTimer); + } + } + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, retStatus, 0, 0); + } + else + { + //if init req failed, then go back to WAKEUP state. + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: BMPS_INIT_PWR_SAVE_REQ failed, informing SME"));) + + pmmBmpsUpdateInitFailureCnt(pMac); + nextState = ePMM_STATE_READY; + retStatus = eSIR_SME_BMPS_REQ_FAILED; + goto failure; + } + return; + +failure: + psessionEntry = peGetValidPowerSaveSession(pMac); + if(psessionEntry != NULL) + { + if (pMac->lim.gLimTimersCreated && pMac->lim.limTimers.gLimHeartBeatTimer.pMac) + { + if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer)) + { + PELOGE(pmmLog(pMac, LOGW, FL("Unexpected heartbeat timer not running"));) + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + } + + //Generate an error response back to PMC + pMac->pmm.gPmmState = nextState; + pmmBmpsUpdateSleepReqFailureCnt(pMac); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, retStatus, 0, 0); + return; + +} + +// -------------------------------------------------------------------- +/** + * pmmExitBmpsRequestHandler + * + * FUNCTION: + * This function will send the wakeup message to HAL + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to Global Mac structure. + + * @return None + */ + +void pmmExitBmpsRequestHandler(tpAniSirGlobal pMac, tpExitBmpsInfo pExitBmpsInfo) +{ + tSirResultCodes respStatus = eSIR_SME_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + + if (NULL == pExitBmpsInfo) + { + respStatus = eSIR_SME_BMPS_REQ_REJECT; + PELOGW(pmmLog(pMac, LOGW, FL("pmmBmps: Rcvd EXIT_BMPS with NULL body"));) + goto failure; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_BMPS_REQ_EVENT, + peGetValidPowerSaveSession(pMac), 0, + (tANI_U16)pExitBmpsInfo->exitBmpsReason); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /* PMC is not aware of Background scan, which is done in + * BMPS mode while Nth Beacon is delivered. Essentially, PMC + * can request the device to get out of power-save while + * background scanning is happening. since, the device is already + * out of powersave, just inform that device is out of powersave + */ + if(limIsSystemInScanState(pMac)) + { + PELOGW(pmmLog(pMac, LOGW, + FL("pmmBmps: Device is already awake and scanning, returning success to PMC "));) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, respStatus, 0, 0); + return; + } + + /* send wakeup request, only when in sleep state */ + PELOGW(pmmLog(pMac, LOGW, FL("pmmBmps: Sending eWNI_PMC_EXIT_BMPS_REQ to HAL"));) + + if ((pMac->pmm.gPmmState == ePMM_STATE_BMPS_SLEEP) || + (pMac->pmm.gPmmState == ePMM_STATE_UAPSD_SLEEP)) + { + /* Store the reason code for exiting BMPS. This value will be + * checked when PMM receives SIR_HAL_EXIT_BMPS_RSP from HAL + */ + pMac->pmm.gPmmExitBmpsReasonCode = pExitBmpsInfo->exitBmpsReason; + vos_mem_free(pExitBmpsInfo); + + PELOGW(pmmLog(pMac, LOGW, + FL("pmmBmps: Rcvd EXIT_BMPS with reason code%d "), pMac->pmm.gPmmExitBmpsReasonCode);) + + + // Set PMM to BMPS_WT_WAKEUP_RSP state + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WT_WAKEUP_RSP; + if(pmmSendChangePowerSaveMsg(pMac) != eSIR_SUCCESS) + { + /* Wakeup request failed */ + respStatus = eSIR_SME_BMPS_REQ_REJECT; + pmmBmpsUpdateHalReqFailureCnt(pMac); + goto failure; + } + else + { + pmmLog(pMac, LOG1, + FL("pmmBmps: eWNI_PMC_EXIT_BMPS_REQ was successfully sent to HAL")); + } + } + else + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: eWNI_PMC_EXIT_BMPS_REQ received in invalid state: %d"), + pMac->pmm.gPmmState );) + + respStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + vos_mem_free(pExitBmpsInfo); + goto failure; + } + return; + +failure: + pMac->pmm.gPmmState = origState; + pmmBmpsUpdateWakeupReqFailureCnt(pMac); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, respStatus, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmInitBmpsPwrSave + * + * FUNCTION: + * This function process the eWNI_PMC_ENTER_PMC_REQ from PMC. + * It checks for certain conditions before it puts PMM into + * BMPS power save state: ePMM_STATE_BMPS_WT_INIT_RSP + * It also invokes pmmSendInitPowerSaveMsg() to send ENTER_BMPS_REQ + * to HAL. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param mode can be either 0(sleep mode) or 1 (active mode) + * @param pMac pointer to Global Mac structure. + + * @return None + */ + + +void pmmInitBmpsPwrSave(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes respStatus = eSIR_SME_SUCCESS; + tpPESession psessionEntry; + + tPmmState origState = pMac->pmm.gPmmState; + + if((psessionEntry = peGetValidPowerSaveSession(pMac))== NULL) + { + respStatus = eSIR_SME_BMPS_REQ_REJECT; + goto failure; + } +#ifndef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + // sending beacon filtering information down to HAL + if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGE, FL("Fail to send Beacon Filter Info ")); + } +#else + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + if (limSendBeaconFilterInfo(pMac, psessionEntry) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGE, FL("Fail to send Beacon Filter Info ")); + } + } +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_BMPS_REQ_EVENT, psessionEntry, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if ( ((pMac->pmm.gPmmState != ePMM_STATE_READY) && + (pMac->pmm.gPmmState != ePMM_STATE_BMPS_WAKEUP)) || + limIsSystemInScanState(pMac) || + limIsChanSwitchRunning(pMac) || + limIsInQuietDuration(pMac) ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: BMPS Request received in invalid state PMM=%d, SME=%d, rejecting the initpwrsave request"), + pMac->pmm.gPmmState, pMac->lim.gLimSmeState);) + + respStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + goto failure; + } + + //If we are in a missed beacon scenario, we should not be attempting to enter BMPS as heartbeat probe is going on + if(pMac->pmm.inMissedBeaconScenario) + { + if (pMac->lim.gLimTimersCreated && pMac->lim.limTimers.gLimHeartBeatTimer.pMac) + { + if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer)) + { + PELOGE(pmmLog(pMac, LOGE, FL("Unexpected heartbeat timer not running"));) + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + } + respStatus = eSIR_SME_BMPS_REQ_REJECT; + goto failure; + } + + /* At this point, device is associated and PMM is not in BMPS_SLEEP state. + * Heartbeat timer not running is an indication that PE have detected a + * loss of link. In this case, reject BMPS request. + */ + /* TODO : We need to have a better check. This check is not valid */ +#if 0 + if ( (pMac->sys.gSysEnableLinkMonitorMode) && (pMac->lim.limTimers.gLimHeartBeatTimer.pMac) ) + { + if(VOS_TRUE != tx_timer_running(&pMac->lim.limTimers.gLimHeartBeatTimer)) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Reject BMPS_REQ because HeartBeatTimer is not running. "));) + respStatus = eSIR_SME_BMPS_REQ_FAILED; + goto failure; + } + } +#endif + + //If the following function returns SUCCESS, then PMM will wait for an explicit + //response message from softmac. + + //changing PMM state before posting message to HAL, as this is a synchronous call to HAL + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WT_INIT_RSP; + if((retStatus = pmmSendInitPowerSaveMsg(pMac,psessionEntry)) != eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: Init Power Save Request Failed: Sending Response: %d"), + retStatus);) + + respStatus = eSIR_SME_BMPS_REQ_REJECT; + pmmBmpsUpdateHalReqFailureCnt(pMac); + goto failure; + } + //Update the powerSave sessionId + pMac->pmm.sessionId = psessionEntry->peSessionId; + return; + +failure: + + // Change the state back to original state + pMac->pmm.gPmmState =origState; + limSendSmeRsp(pMac, eWNI_PMC_ENTER_BMPS_RSP, respStatus, 0, 0); + + // update the BMPS pwr save Error Stats + pmmBmpsUpdateSleepReqFailureCnt(pMac); + return; +} + + +/** + * pmmSendChangePowerSaveMsg() + * + *FUNCTION: + * This function is called to send SIR_HAL_EXIT_BMPS_REQ to HAL. + * This message will trigger HAL to program HW to wake up. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @return success if message send is ok, else false. + */ +tSirRetStatus pmmSendChangePowerSaveMsg(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tpExitBmpsParams pExitBmpsParams; + tSirMsgQ msgQ; + tpPESession psessionEntry; + tANI_U8 currentOperatingChannel = limGetCurrentOperatingChannel(pMac); + + pExitBmpsParams = vos_mem_malloc(sizeof(*pExitBmpsParams)); + if ( NULL == pExitBmpsParams ) + { + pmmLog(pMac, LOGW, FL("Failed to allocate memory")); + retStatus = eSIR_MEM_ALLOC_FAILED; + return retStatus; + } + + if((psessionEntry = peGetValidPowerSaveSession(pMac)) == NULL ) + { + retStatus = eSIR_FAILURE; + vos_mem_free(pExitBmpsParams); + return retStatus; + } + + vos_mem_set( (tANI_U8 *)pExitBmpsParams, sizeof(*pExitBmpsParams), 0); + msgQ.type = WDA_EXIT_BMPS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pExitBmpsParams; + msgQ.bodyval = 0; + + /* If reason for full power is disconnecting (ie. link is + * disconnected) or becasue of channel switch or full power requested + * because of beacon miss and connected on DFS channel + * then we should not send data null. + * For all other reason code, send data null. + */ + if ( !(SIR_IS_FULL_POWER_REASON_DISCONNECTED(pMac->pmm.gPmmExitBmpsReasonCode) || + ( (eSME_MISSED_BEACON_IND_RCVD == pMac->pmm.gPmmExitBmpsReasonCode) && + limIsconnectedOnDFSChannel(currentOperatingChannel)))) + pExitBmpsParams->sendDataNull = 1; + + pExitBmpsParams->bssIdx = psessionEntry->bssIdx; + + /* we need to defer any incoming messages until we + * get a WDA_EXIT_BMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retStatus = wdaPostCtrlMsg( pMac, &msgQ); + if( eSIR_SUCCESS != retStatus ) + { + PELOGE(pmmLog( pMac, LOGE, FL("Sending WDA_EXIT_BMPS_REQ failed, reason=%X "), retStatus );) + vos_mem_free(pExitBmpsParams); + return retStatus; + } + + pmmLog(pMac, LOG1, FL("WDA_EXIT_BMPS_REQ has been successfully sent to HAL")); + return retStatus; +} + + +/** + * pmmSendInitPowerSaveMsg() + * + *FUNCTION: + * This function is called to send ENTER_BMPS_REQ message to HAL. + * This message is sent to intialize the process of bringing the + * station into power save state. + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param mode The Power Save or Active State + * + * @return success if message send is ok, else false. + */ + +tSirRetStatus pmmSendInitPowerSaveMsg(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tpEnterBmpsParams pBmpsParams = NULL; + tANI_U32 rssiFilterPeriod = 5; + tANI_U32 numBeaconPerRssiAverage = 20; + tANI_U32 bRssiFilterEnable = FALSE; + + if(psessionEntry->currentBssBeaconCnt == 0 ) + { + PELOGE(pmmLog( pMac, LOGE, FL("Beacon count is zero, can not retrieve the TSF, failing the Enter Bmps Request"));) + return eSIR_FAILURE; + } + + pBmpsParams = vos_mem_malloc(sizeof(tEnterBmpsParams)); + if ( NULL == pBmpsParams ) + { + pmmLog(pMac, LOGP, "PMM: Not able to allocate memory for Enter Bmps"); + return eSIR_FAILURE; + } + + pMac->pmm.inMissedBeaconScenario = FALSE; + pBmpsParams->respReqd = TRUE; + + pBmpsParams->tbtt = psessionEntry->lastBeaconTimeStamp; + pBmpsParams->dtimCount = psessionEntry->lastBeaconDtimCount; + pBmpsParams->dtimPeriod = psessionEntry->lastBeaconDtimPeriod; + pBmpsParams->bssIdx = psessionEntry->bssIdx; + + /* TODO: Config parameters (Rssi filter period, FW RSSI Monitoring + and Number of beacons per RSSI average) values sent down to FW during + initial exchange (driver load) is same as ENTER_BMPS_REQ. + Sending these values again in ENTER_BMPS_REQ is not required + (can be removed). This is kept as-is for now to support + backward compatibility with the older host running on new FW. */ + + if(wlan_cfgGetInt(pMac, WNI_CFG_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period")); + pBmpsParams->rssiFilterPeriod = (tANI_U8)rssiFilterPeriod; + + if(wlan_cfgGetInt(pMac, WNI_CFG_PS_ENABLE_RSSI_MONITOR, &bRssiFilterEnable) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi monitor enable flag")); + pBmpsParams->bRssiFilterEnable = bRssiFilterEnable; + + /* The numBeaconPerRssiAverage should be less than + the max allowed (default set to 20 in CFG) */ + if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, &numBeaconPerRssiAverage) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for num beacon per rssi")); + + pBmpsParams->numBeaconPerRssiAverage = + (tANI_U8)GET_MIN_VALUE((tANI_U8) numBeaconPerRssiAverage, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX); + + pmmLog (pMac, LOG1, + "%s: RssiFilterInfo..%d %x %x", __func__, (int)pBmpsParams->bRssiFilterEnable, + (unsigned int)pBmpsParams->rssiFilterPeriod, (unsigned int)pBmpsParams->numBeaconPerRssiAverage); + + msgQ.type = WDA_ENTER_BMPS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pBmpsParams; + msgQ.bodyval = 0; + + pmmLog( pMac, LOG1, + FL( "pmmBmps: Sending WDA_ENTER_BMPS_REQ" )); + + /* we need to defer any incoming messages until we get a + * WDA_ENTER_BMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + vos_mem_free(pBmpsParams); + PELOGE(pmmLog( pMac, LOGE, + FL("Posting WDA_ENTER_BMPS_REQ to HAL failed, reason=%X"), + retCode );) + } + + return retCode; +} + +/** + * pmmSendPowerSaveCfg() + * + *FUNCTION: + * This function is called to send power save configurtion. + * + *NOTE: + * + * @param pMac pointer to Global Mac structure. + * @param mode The Power Save or Active State + * + * @return success if message send is ok, else false. + */ +tSirRetStatus pmmSendPowerSaveCfg(tpAniSirGlobal pMac, tpSirPowerSaveCfg pUpdatedPwrSaveCfg) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + tANI_U32 listenInterval; + tANI_U32 HeartBeatCount = 1; + tANI_U32 maxPsPoll; + tANI_U32 numBeaconPerRssiAverage; + tANI_U32 minRssiThreshold; + tANI_U32 nthBeaconFilter; + tANI_U32 broadcastFrameFilter; + tANI_U32 rssiFilterPeriod; + tANI_U32 ignoreDtim; + + if (NULL == pUpdatedPwrSaveCfg) + goto returnFailure; + + if(pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE ) + { + pmmLog(pMac, LOGE, + FL("pmmCfg: Power Save Configuration received in invalid global sme state %d"), + pMac->lim.gLimSmeState); + retCode = eSIR_SME_INVALID_STATE; + goto returnFailure; + } + + // Get power save configuration CFG values + if(wlan_cfgGetInt(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for listen interval")); + pUpdatedPwrSaveCfg->listenInterval = (tANI_U16)listenInterval; + + if(wlan_cfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &HeartBeatCount) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for heart beat thresh")); + + pMac->lim.gLimHeartBeatCount = HeartBeatCount; + pUpdatedPwrSaveCfg->HeartBeatCount = HeartBeatCount; + + if(wlan_cfgGetInt(pMac, WNI_CFG_NTH_BEACON_FILTER, &nthBeaconFilter) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Nth beacon filter")); + pUpdatedPwrSaveCfg->nthBeaconFilter = nthBeaconFilter; + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_PS_POLL, &maxPsPoll) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for max poll")); + pUpdatedPwrSaveCfg->maxPsPoll = maxPsPoll; + + if(wlan_cfgGetInt(pMac, WNI_CFG_MIN_RSSI_THRESHOLD, &minRssiThreshold) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for min RSSI Threshold")); + pUpdatedPwrSaveCfg->minRssiThreshold = minRssiThreshold; + + if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, &numBeaconPerRssiAverage) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for num beacon per rssi")); + pUpdatedPwrSaveCfg->numBeaconPerRssiAverage = (tANI_U8) numBeaconPerRssiAverage; + + if(wlan_cfgGetInt(pMac, WNI_CFG_RSSI_FILTER_PERIOD, &rssiFilterPeriod) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Rssi filter period")); + pUpdatedPwrSaveCfg->rssiFilterPeriod = (tANI_U8) rssiFilterPeriod; + + if(wlan_cfgGetInt(pMac, WNI_CFG_BROADCAST_FRAME_FILTER_ENABLE, &broadcastFrameFilter) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for Nth beacon filter")); + pUpdatedPwrSaveCfg->broadcastFrameFilter = (tANI_U8) broadcastFrameFilter; + + if(wlan_cfgGetInt(pMac, WNI_CFG_IGNORE_DTIM, &ignoreDtim) != eSIR_SUCCESS) + pmmLog(pMac, LOGP, FL("pmmCfg: cfgGet failed for ignoreDtim")); + pUpdatedPwrSaveCfg->ignoreDtim = (tANI_U8) ignoreDtim; + + //Save a copy of the CFG in global pmm context. + vos_mem_copy( (tANI_U8 *) &pMac->pmm.gPmmCfg, pUpdatedPwrSaveCfg, sizeof(tSirPowerSaveCfg)); + + + msgQ.type = WDA_PWR_SAVE_CFG; + msgQ.reserved = 0; + msgQ.bodyptr = pUpdatedPwrSaveCfg; + msgQ.bodyval = 0; + + pmmLog( pMac, LOG1, FL( "pmmBmps: Sending WDA_PWR_SAVE_CFG to HAL")); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + pmmLog( pMac, LOGP, + FL("Posting WDA_PWR_SAVE_CFG to HAL failed, reason=%X"), + retCode ); + goto returnFailure; + } + return retCode; + +returnFailure: + + /* In case of failure, we need to free the memory */ + if (NULL != pUpdatedPwrSaveCfg) + { + vos_mem_free(pUpdatedPwrSaveCfg); + } + return retCode; +} + +/** + * pmmExitBmpsResponseHandler + * + *FUNCTION: + * This function processes the Wakeup Rsp from HAL and if successfull, + * sends a respnose back to PMC layer. + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param rspStatus Status of the response, Success or an error code. + * + * @return none. + */ +void pmmExitBmpsResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpExitBmpsParams pExitBmpsRsp; + eHalStatus rspStatus; + tANI_U8 PowersavesessionId; + tpPESession psessionEntry; + tSirResultCodes retStatus = eSIR_SME_SUCCESS; + + /* Copy the power save sessionId to the local variable */ + PowersavesessionId = pMac->pmm.sessionId; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_EXIT_BMPS_REQ. + */ + + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL) + { + pmmLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + + if (NULL == limMsg->bodyptr) + { + pmmLog(pMac, LOGE, FL("Received SIR_HAL_EXIT_BMPS_RSP with NULL ")); + return; + } + pExitBmpsRsp = (tpExitBmpsParams)(limMsg->bodyptr); + rspStatus = pExitBmpsRsp->status; + + if(pMac->pmm.gPmmState != ePMM_STATE_BMPS_WT_WAKEUP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Received SIR_HAL_EXIT_BMPS_RSP while in incorrect state: %d"), + pMac->pmm.gPmmState);) + + retStatus = eSIR_SME_INVALID_PMM_STATE; + pmmBmpsUpdateInvalidStateCnt(pMac); + } + else + { + PELOGW(pmmLog(pMac, LOGW, FL("Received SIR_HAL_EXIT_BMPS_RSP in correct state. "));) + } + + /* PE is going to wakeup irrespective of whether + * SIR_HAL_EXIT_BMPS_REQ was successful or not + */ + switch (rspStatus) + { + case eHAL_STATUS_SUCCESS: + retStatus = eSIR_SME_SUCCESS; + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WAKEUP; + /* Update wakeup statistics */ + pmmUpdateWakeupStats(pMac); + break; + + default: + { + /* PE is going to be awake irrespective of whether EXIT_BMPS_REQ + * failed or not. This is mainly to eliminate the dead-lock condition + * But, PMC will be informed about the error. + */ + retStatus = eSIR_SME_BMPS_REQ_FAILED; + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + pmmBmpsUpdateWakeupReqFailureCnt(pMac); + } + break; + + } + + // turn on background scan + pMac->sys.gSysEnableScanMode = true; + + // send response to PMC + if(IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) ) + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, retStatus, + psessionEntry->smeSessionId, psessionEntry->transactionId); + } + else + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_BMPS_RSP, retStatus, 0, 0); + } + + if ( pMac->pmm.gPmmExitBmpsReasonCode == eSME_MISSED_BEACON_IND_RCVD) + { + PELOGW(pmmLog(pMac, LOGW, FL("Rcvd SIR_HAL_EXIT_BMPS_RSP with MISSED_BEACON"));) + pmmMissedBeaconHandler(pMac); + } + else if(pMac->pmm.inMissedBeaconScenario) + { + PELOGW(pmmLog(pMac, LOGW, FL("Rcvd SIR_HAL_EXIT_BMPS_RSP in missed beacon scenario but reason code not correct"));) + pmmMissedBeaconHandler(pMac); + } + else + { + // Enable heartbeat timer + limReactivateHeartBeatTimer(pMac, psessionEntry); + } + return; +} + + +/** + * pmmMissedBeaconHandler() + * + *FUNCTION: + * This function is called when PMM receives an eWNI_PMC_EXIT_BMPS_REQ + * with reason code being eSME_MISSED_BEACON_IND_RCVD. + * + *NOTE: + * @param pMac pointer to Global Mac structure. + * @return none + */ +void pmmMissedBeaconHandler(tpAniSirGlobal pMac) +{ + tANI_U8 pwrSaveSessionId; + tANI_U32 beaconInterval = 0; + tANI_U32 heartBeatInterval = pMac->lim.gLimHeartBeatCount; + tpPESession psessionEntry; + + /* Copy the power save sessionId to the local variable */ + pwrSaveSessionId = pMac->pmm.sessionId; + + if((psessionEntry = peFindSessionBySessionId(pMac,pwrSaveSessionId))==NULL) + { + pmmLog(pMac, LOGE,FL("Session Does not exist for given sessionID")); + return; + } + + + PELOGE(pmmLog(pMac, LOG1, FL("The device woke up due to MISSED BEACON "));) + + /* Proceed only if HeartBeat timer is created */ + if((pMac->lim.limTimers.gLimHeartBeatTimer.pMac) && + (pMac->lim.gLimTimersCreated)) + { + if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &beaconInterval) != eSIR_SUCCESS) + pmmLog(pMac, LOG1, FL("Fail to get BEACON_INTERVAL value")); + + /* Change timer to reactivate it in future */ + heartBeatInterval= SYS_MS_TO_TICKS(beaconInterval * heartBeatInterval); + + if( tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, + (tANI_U32)heartBeatInterval, 0) != TX_SUCCESS) + { + pmmLog(pMac, LOG1, FL("Fail to change HeartBeat timer")); + } + + /* update some statistics */ + if(LIM_IS_CONNECTION_ACTIVE(psessionEntry)) + { + if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL) + pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++; + else + pMac->lim.gLimHeartBeatBeaconStats[0]++; + } + + /* To handle the missed beacon failure, message is being posted to self as if the + * actual timer has expired. This is done to make sure that there exists one + * common entry and exit points + */ + //limResetHBPktCount(pMac); // 090805: Where did this come from? + limResetHBPktCount(psessionEntry); // 090805: This is what it SHOULD be. If we even need it. + pmmSendMessageToLim(pMac, SIR_LIM_HEART_BEAT_TIMEOUT); + } + else + { + PELOGE(pmmLog(pMac, LOGE, FL("HeartBeat Timer is not created, cannot re-activate"));) + } + + return; +} + + +/** + * pmmExitBmpsIndicationHandler + * + *FUNCTION: + * This function sends a Power Save Indication. back to PMC layer. + * This indication is originated from softmac and will occur in the following two + * scenarios: + * 1) When softmac is in sleep state and wakes up to parse TIM and finds that + * AP has the data pending for this STA, then it sends this indication to let PMC know + * that it is going to be awake and pass the control over to PMC + * 2) When softmac is in sleep state and wakes up to parse TIM and determines that + * current TIM is DTIM and AP has buffered broadcast/multicast frames. + * In this scenario, softmac needs to remain awake for broadcast/multicast frames and it + * sends an indication to PMC that it is awake and passes the control over to PMC. + * 3) If station is awake and 'fEnablePwrSaveImmediately' flag is set, then softmac will transmit all + * frames in its queues and go to sleep. Before going to sleep it sends the notification to PMC that + * it is going to sleep. + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac pointer to Global Mac structure. + * @param rspStatus Status of the response, Success or an error code. + * + * @return none. + */ + +void pmmExitBmpsIndicationHandler(tpAniSirGlobal pMac, tANI_U8 mode, eHalStatus rspStatus) +{ + + tANI_U32 beaconInterval = 0; + tANI_U32 heartBeatInterval = pMac->lim.gLimHeartBeatCount; + tANI_U8 powersavesessionId; + tpPESession psessionEntry; + + /* Copy the power save sessionId to the local variable */ + powersavesessionId = pMac->pmm.sessionId; + + psessionEntry = peFindSessionBySessionId(pMac,powersavesessionId); + + if(psessionEntry == NULL) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Session does Not exist with given sessionId :%d "),powersavesessionId);) + return; + } + + /* Since, the hardware is already wokenup, PE also wakesup and informs + * the upper layers that the system is waking up. Hence always Success is + * sent in the reason code for the message sent to PMC + */ + + PELOGW(pmmLog(pMac, LOGW, + FL("pmmBmps: Received SIR_HAL_EXIT_BMPS_IND from HAL, Exiting BMPS sleep mode")); ) + + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_WAKEUP; + pmmUpdateWakeupStats(pMac); + + /* turn on background scan */ + pMac->sys.gSysEnableScanMode = true; + + pmmBmpsUpdateWakeupIndCnt(pMac); + + /* Inform SME about the system awake state */ + limSendSmeRsp(pMac, + eWNI_PMC_EXIT_BMPS_IND, + eSIR_SME_SUCCESS, 0, 0); + + switch(rspStatus) + { + + /* The SoftMAC sends wakeup indication even when Heart-Beat timer expired + * The PE should start taking action against this as soon as it identifies + * that the SoftMAC has identified heart-beat miss + */ + case eHAL_STATUS_HEARTBEAT_TMOUT: + { + pmmLog(pMac, LOG1, + FL("pmmBmps: The device woke up due to HeartBeat Timeout")); + + /* Proceed only if HeartBeat timer is created */ + if((pMac->lim.limTimers.gLimHeartBeatTimer.pMac) && + (pMac->lim.gLimTimersCreated)) + { + + /* Read the beacon interval from sessionTable */ + beaconInterval = psessionEntry->beaconParams.beaconInterval; + + /* Change timer to reactivate it in future */ + heartBeatInterval= SYS_MS_TO_TICKS(beaconInterval * heartBeatInterval); + + if(tx_timer_change(&pMac->lim.limTimers.gLimHeartBeatTimer, + (tANI_U32)heartBeatInterval, 0) != TX_SUCCESS) + { + pmmLog(pMac, LOG1, + FL("pmmBmps: Unable to change HeartBeat timer")); + } + + /* update some statistics */ + if(LIM_IS_CONNECTION_ACTIVE(psessionEntry)) + { + if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL) + pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++; + else + pMac->lim.gLimHeartBeatBeaconStats[0]++; + } + + /* To handle the heartbeat failure, message is being posted to self as if the + * actual timer has expired. This is done to make sure that there exists one + * common entry and exit points + */ + pmmSendMessageToLim(pMac, SIR_LIM_HEART_BEAT_TIMEOUT); + + } + else + { + + PELOGE(pmmLog(pMac, LOGE, + FL("pmmBmps: HeartBeat Timer is not created, cannot re-activate"));) + } + } + break; + + case eHAL_STATUS_NTH_BEACON_DELIVERY: + break; + + default: + break; + + } + + return; + +} + + +// -------------------------------------------------------------------- +/** + * pmmProcessMessage + * + * FUNCTION: Processes the next received Power Management message + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void pmmProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + switch (pMsg->type) + { + case eWNI_PMC_PWR_SAVE_CFG: + { + tpSirPowerSaveCfg pPSCfg; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + + pPSCfg = vos_mem_malloc(sizeof(tSirPowerSaveCfg)); + if ( NULL == pPSCfg ) + { + pmmLog(pMac, LOGP, "PMM: Not able to allocate memory for PMC Config"); + } + (void) vos_mem_copy(pPSCfg, pMbMsg->data, sizeof(tSirPowerSaveCfg)); + (void) pmmSendPowerSaveCfg(pMac, pPSCfg); + } + break; + + case eWNI_PMC_ENTER_BMPS_REQ: + pmmInitBmpsPwrSave(pMac); + break; + + case WDA_ENTER_BMPS_RSP: + pmmInitBmpsResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_EXIT_BMPS_REQ: + { + tpExitBmpsInfo pExitBmpsInfo; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + + pExitBmpsInfo = vos_mem_malloc(sizeof(tExitBmpsInfo)); + if ( NULL == pExitBmpsInfo ) + { + pmmLog(pMac, LOGP, "PMM: Failed to allocate memory for Exit BMPS Info "); + } + (void) vos_mem_copy(pExitBmpsInfo, pMbMsg->data, sizeof(tExitBmpsInfo)); + (void) pmmExitBmpsRequestHandler(pMac, pExitBmpsInfo); + } + break; + + case WDA_EXIT_BMPS_RSP: + pmmExitBmpsResponseHandler(pMac, pMsg); + break; + + case WDA_EXIT_BMPS_IND: + pmmExitBmpsIndicationHandler(pMac, SIR_PM_ACTIVE_MODE, (eHalStatus)pMsg->bodyval); + break; + + case eWNI_PMC_ENTER_IMPS_REQ: + pmmEnterImpsRequestHandler(pMac); + break; + + case WDA_ENTER_IMPS_RSP: + pmmEnterImpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval); + break; + + case eWNI_PMC_EXIT_IMPS_REQ: + pmmExitImpsRequestHandler(pMac); + break; + + case WDA_EXIT_IMPS_RSP: + pmmExitImpsResponseHandler(pMac, (eHalStatus)pMsg->bodyval); + break; + + case eWNI_PMC_ENTER_UAPSD_REQ: + pmmEnterUapsdRequestHandler(pMac); + break; + + case WDA_ENTER_UAPSD_RSP: + pmmEnterUapsdResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_EXIT_UAPSD_REQ: + pmmExitUapsdRequestHandler(pMac); + break; + + case WDA_EXIT_UAPSD_RSP: + pmmExitUapsdResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + pmmSendWowlAddBcastPtrn(pMac, pMsg); + break; + + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + pmmSendWowlDelBcastPtrn(pMac, pMsg); + break; + + case eWNI_PMC_ENTER_WOWL_REQ: + pmmEnterWowlRequestHandler(pMac, pMsg); + break; + + case WDA_WOWL_ENTER_RSP: + pmmEnterWowlanResponseHandler(pMac, pMsg); + break; + + case eWNI_PMC_EXIT_WOWL_REQ: + pmmExitWowlanRequestHandler(pMac); + break; + + case WDA_WOWL_EXIT_RSP: + pmmExitWowlanResponseHandler(pMac, pMsg); + break; +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: + pmmFilterMatchCountResponseHandler(pMac, pMsg); + break; +#endif // WLAN_FEATURE_PACKET_FILTERING + + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDA_GTK_OFFLOAD_GETINFO_RSP: + pmmGTKOffloadGetInfoResponseHandler(pMac, pMsg); + break; +#endif // WLAN_FEATURE_GTK_OFFLOAD + + default: + PELOGW(pmmLog(pMac, LOGW, + FL("PMM: Unknown message in pmmMsgQ type %d, potential memory leak!!"), + pMsg->type);) + } + + if (NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + pMsg->bodyptr = NULL; + } +} + + + + + + +// -------------------------------------------------------------------- +/** + * pmmPostMessage + * + * FUNCTION: + * Post a message to the pmm message queue + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMsg pointer to message + * @return None + */ + +tSirRetStatus +pmmPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + VOS_STATUS vosStatus; + vosStatus = vos_mq_post_message(VOS_MQ_ID_PE, (vos_msg_t *) pMsg); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + pmmLog(pMac, LOGP, FL("vos_mq_post_message failed with status code %d"), vosStatus); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + + + + + +/** + * pmmUpdatePwrSaveStats + * + * FUNCTION: updated BMPS stats, when Station is going into power save state. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to Global MAC Structure. + * @return None + */ + +void pmmUpdatePwrSaveStats(tpAniSirGlobal pMac) +{ +/* + tANI_U64 TimeAwake = 0; + + pMac->pmm.BmpsSleepTimeStamp = vos_timer_get_system_ticks(); + + if (pMac->pmm.BmpsWakeupTimeStamp) + TimeAwake = (pMac->pmm.BmpsSleepTimeStamp - pMac->pmm.BmpsWakeupTimeStamp) /10; + else + TimeAwake = 0; // very first time + + if (TimeAwake > pMac->pmm.BmpsmaxTimeAwake) + { + pMac->pmm.BmpsmaxTimeAwake = TimeAwake; + } + + if ((!pMac->pmm.BmpsminTimeAwake) || (TimeAwake < pMac->pmm.BmpsminTimeAwake)) + { + pMac->pmm.BmpsminTimeAwake = TimeAwake; + } + + pMac->pmm.BmpsavgTimeAwake = ( ( (pMac->pmm.BmpsavgTimeAwake * pMac->pmm.BmpscntSleep) + TimeAwake ) / (pMac->pmm.BmpscntSleep + 1) ); + +*/ + pMac->pmm.BmpscntSleep++; + return; +} + + + + +/** + * pmmUpdatePwrSaveStats + * + * FUNCTION: updated BMPS stats, when Station is waking up. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMac pointer to Global MAC Structure. + * @return None + */ + +void pmmUpdateWakeupStats(tpAniSirGlobal pMac) +{ +/* + + tANI_U64 SleepTime = 0; + + pMac->pmm.BmpsWakeupTimeStamp = vos_timer_get_system_ticks(); + SleepTime = (pMac->pmm.BmpsWakeupTimeStamp - pMac->pmm.BmpsSleepTimeStamp) / 10; + + if (SleepTime > pMac->pmm.BmpsmaxSleepTime) + { + pMac->pmm.BmpsmaxSleepTime = SleepTime; + } + + if ((!pMac->pmm.BmpsminSleepTime) || (SleepTime < pMac->pmm.BmpsminSleepTime)) + { + pMac->pmm.BmpsminSleepTime = SleepTime; + } + + pMac->pmm.BmpsavgSleepTime = ( ( (pMac->pmm.BmpsavgSleepTime * pMac->pmm.BmpscntAwake) + SleepTime ) / (pMac->pmm.BmpscntAwake + 1) ); + +*/ + pMac->pmm.BmpscntAwake++; + return; +} + +// -------------------------------------------------------------------- +/** + * pmmEnterImpsRequestHandler + * + * FUNCTION: + * This function sends the idle mode power save request from host device + * drive to HAL. This function is called from pmmProcessMsg() + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmEnterImpsRequestHandler (tpAniSirGlobal pMac) +{ + + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + tSirRetStatus retStatus = eSIR_SUCCESS; + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_IMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + /*Returns True even single active session present */ + if(peIsAnySessionActive(pMac)) + { + /* Print active pesession and tracedump once in every 16 + * continous error. + */ + if (!(pMac->pmc.ImpsReqFailCnt & 0xF)) + { + pePrintActiveSession(pMac); + vosTraceDumpAll(pMac,0,0,100,0); + } + resultCode = eSIR_SME_INVALID_STATE; + pmmLog(pMac, LOGE, FL("Session is active go to failure resultCode = " + "eSIR_SME_INVALID_STATE (%d)"),resultCode); + goto failure; + } + + if ( ((pMac->pmm.gPmmState != ePMM_STATE_READY) && + (pMac->pmm.gPmmState != ePMM_STATE_IMPS_WAKEUP)) || + ((pMac->lim.gLimSmeState != eLIM_SME_IDLE_STATE) && + (pMac->lim.gLimSmeState != eLIM_SME_JOIN_FAILURE_STATE)) || + (pMac->lim.gLimMlmState != eLIM_MLM_IDLE_STATE) || + limIsChanSwitchRunning (pMac) || + limIsInQuietDuration (pMac) ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: PMM State = %d, Global MLM State = %d, Global SME State = %d, rejecting the sleep mode request"), + pMac->pmm.gPmmState, pMac->lim.gLimMlmState, pMac->lim.gLimSmeState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + goto failure; + } + + // change PE state and send the request to HAL + pMac->pmm.gPmmState = ePMM_STATE_IMPS_WT_SLEEP_RSP; + if( (retStatus = pmmImpsSendChangePwrSaveMsg(pMac, SIR_PM_SLEEP_MODE)) != eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: IMPS Sleep Request failed: sending response: %x"), retStatus);) + + resultCode = eSIR_SME_IMPS_REQ_FAILED; + goto failure; + } + else + { + pmmLog(pMac, LOG1, + FL("pmmImps: Waiting for SoftMac response for IMPS request")); + } + return; + +failure: + pMac->pmm.gPmmState = origState; + pmmImpsUpdateSleepErrStats(pMac, retStatus); + + limSendSmeRsp(pMac, + eWNI_PMC_ENTER_IMPS_RSP, + resultCode, 0, 0); + +} + +// -------------------------------------------------------------------- +/** + * pmmEnterImpsResponseHandler + * + * FUNCTION: + * This function receives the response from HAL layer for the idle mode + * power save request sent. The function is also responsible for checking + * the correctness of the system state before configuring the new state + * on success. This function is called by pmmProcessMsg() + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC, Status code + * @return None + */ +void pmmEnterImpsResponseHandler (tpAniSirGlobal pMac, eHalStatus rspStatus) +{ + tPmmState nextState = pMac->pmm.gPmmState; + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + static int failCnt = 0; + + /* we need to process all the deferred messages enqueued since + * the initiating the WDA_ENTER_IMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if(pMac->pmm.gPmmState != ePMM_STATE_IMPS_WT_SLEEP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Receives IMPS sleep rsp in invalid state: %d"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + + goto failure; + } + + if(eHAL_STATUS_SUCCESS == rspStatus) + { + //if success, change the state to IMPS sleep mode + pMac->pmm.gPmmState = ePMM_STATE_IMPS_SLEEP; + + pmmLog(pMac, LOG1, + FL("pmmImps: Received successful WDA_ENTER_IMPS_RSP from HAL")); + + //update power save statistics + pmmImpsUpdatePwrSaveStats(pMac); + + limSendSmeRsp(pMac, + eWNI_PMC_ENTER_IMPS_RSP, + resultCode, 0, 0); + } + else + { + // go back to previous state if request failed + nextState = ePMM_STATE_READY; + resultCode = eSIR_SME_CANNOT_ENTER_IMPS; + goto failure; + } + return; + +failure: + if (!(failCnt & 0xF)) + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImpsSleepRsp failed, Ret Code: %d, next state will be: %d"), + rspStatus, + pMac->pmm.gPmmState);) + + failCnt++; + pmmImpsUpdateSleepErrStats(pMac, rspStatus); + + pMac->pmm.gPmmState = nextState; + + limSendSmeRsp(pMac, + eWNI_PMC_ENTER_IMPS_RSP, + resultCode, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmExitImpsRequestHandler + * + * FUNCTION: + * This function is called by pmmProcessMsg(). The function sends a request + * to HAL to wakeup the device from idle mode power save mode. + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitImpsRequestHandler (tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_IMPS_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if (ePMM_STATE_IMPS_SLEEP == pMac->pmm.gPmmState) + { + pMac->pmm.gPmmState = ePMM_STATE_IMPS_WT_WAKEUP_RSP; + if( (retStatus = pmmImpsSendChangePwrSaveMsg(pMac, SIR_PM_ACTIVE_MODE)) != + eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Wakeup request message sent to SoftMac failed"));) + resultCode = eSIR_SME_IMPS_REQ_FAILED; + goto failure; + } + } + else + { + // PE in invalid state + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Wakeup Req received in invalid state: %d"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + + goto failure; + } + return; + +failure: + PELOGE(pmmLog (pMac, LOGE, + FL("pmmImps: Changing to IMPS wakeup mode failed, Ret Code: %d, Next State: %d"), + retStatus, pMac->pmm.gPmmState);) + + pMac->pmm.gPmmState = origState; + pmmImpsUpdateWakeupErrStats(pMac, retStatus); + + limSendSmeRsp(pMac, + eWNI_PMC_EXIT_IMPS_RSP, + resultCode, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmExitImpsResponseHandler + * + * FUNCTION: + * This function receives the response from HAL layer for the idle mode + * power save request sent. The function is also responsible for checking + * the correctness of the system state before configuring the new state + * on success. This function is called by pmmProcessMsg() + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitImpsResponseHandler(tpAniSirGlobal pMac, eHalStatus rspStatus) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued since + * the initiating the WDA_EXIT_IMPS_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (pMac->pmm.gPmmState != ePMM_STATE_IMPS_WT_WAKEUP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmImps: Received 'Wakeup' response in invalid state: %d"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + pmmImpsUpdateErrStateStats(pMac); + } + + switch(rspStatus) + { + case eHAL_STATUS_SUCCESS: + { + resultCode = eSIR_SME_SUCCESS; + pMac->pmm.gPmmState = ePMM_STATE_IMPS_WAKEUP; + pmmLog(pMac, LOG1, + FL("pmmImps: Received WDA_EXIT_IMPS_RSP with Successful response from HAL")); + //update power save statistics + pmmImpsUpdateWakeupStats(pMac); + } + break; + + default: + { + resultCode = eSIR_SME_IMPS_REQ_FAILED; + /* Set the status back to IMPS SLEEP as we failed + * to come out of sleep + */ + pMac->pmm.gPmmState = ePMM_STATE_IMPS_SLEEP; + PELOGW(pmmLog(pMac, LOGW, + FL("pmmImps: Received WDA_EXIT_IMPS_RSP with Failure Status from HAL"));) + // update th power save error stats + pmmImpsUpdateWakeupErrStats(pMac, rspStatus); + } + break; + + } + + + + limSendSmeRsp(pMac, + eWNI_PMC_EXIT_IMPS_RSP, + resultCode, 0, 0); + return; + +} + +// -------------------------------------------------------------------- +/** + * pmmEnterUapsdRequestHandler + * + * FUNCTION: + * This function process the eWNI_PMC_ENTER_UAPSD_REQ from PMC, + * checks the correctness of the system state before configuring + * PMM to the new ePMM_STATE_UAPSD_WT_SLEEP_RSP state, and invokes + * invokes pmmUapsdSendChangePwrSaveMsg() to send + * WDA_ENTER_UAPSD_REQ to HAL. + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmEnterUapsdRequestHandler (tpAniSirGlobal pMac) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + tSirRetStatus retStatus = eSIR_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_UAPSD_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if ( (pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) || + limIsSystemInScanState(pMac) ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: PMM State = %d, Global MLM State = %d, Global SME State = %d, rejecting the sleep mode request"), + pMac->pmm.gPmmState, pMac->lim.gLimMlmState, pMac->lim.gLimSmeState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + goto failure; + } + + pMac->pmm.gPmmState = ePMM_STATE_UAPSD_WT_SLEEP_RSP; + + if( (retStatus = pmmUapsdSendChangePwrSaveMsg(pMac, SIR_PM_SLEEP_MODE)) != eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: HAL_ENTER_UAPSD_REQ failed with response: %x"), retStatus);) + if (retStatus == eSIR_PMM_INVALID_REQ) + resultCode = eSIR_SME_UAPSD_REQ_INVALID; + else + resultCode = eSIR_SME_UAPSD_REQ_FAILED; + goto failure; + } + + pmmLog(pMac, LOG1, FL("pmmUapsd: Waiting for WDA_ENTER_UAPSD_RSP ")); + return; + +failure: + pMac->pmm.gPmmState = origState; + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, resultCode, 0, 0); + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmEnterUapsdResponseHandler + * + * FUNCTION: + * This function processes the SIR_HAL_ENTER_UAPSD_RSP from HAL. + * If the response is successful, it puts PMM into ePMM_STATE_UAPSD_SLEEP + * state and sends back success response to PMC. + * + * NOTE: + * + * @param limMsg + * @return None + */ +void pmmEnterUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpUapsdParams pUapsdRspMsg; + tSirResultCodes retStatus = eSIR_SME_SUCCESS; + + tANI_U8 PowersavesessionId; + tpPESession psessionEntry; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_ENTER_UAPSD_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + /* Copy the power save sessionId to the local variable */ + PowersavesessionId = pMac->pmm.sessionId; + + if (NULL == limMsg->bodyptr) + { + PELOGE(pmmLog(pMac, LOGE, FL("pmmUapsd: Received SIR_HAL_ENTER_UAPSD_RSP with NULL "));) + return; + } + + pUapsdRspMsg = (tpUapsdParams)(limMsg->bodyptr); + + if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL) + { + pmmLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if(pMac->pmm.gPmmState != ePMM_STATE_UAPSD_WT_SLEEP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: Received SIR_HAL_ENTER_UAPSD_RSP while in incorrect state: %d"), + pMac->pmm.gPmmState);) + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0); + return; + } + + if(pUapsdRspMsg->status == eHAL_STATUS_SUCCESS) + { + PELOGW(pmmLog(pMac, LOGW, + FL("pmmUapsd: Received successful response from HAL to enter UAPSD mode "));) + pMac->pmm.gPmmState = ePMM_STATE_UAPSD_SLEEP; + } + else + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: SIR_HAL_ENTER_UAPSD_RSP failed, informing SME"));) + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + retStatus = eSIR_SME_UAPSD_REQ_FAILED; + } + + if(IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION)) + { + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, retStatus, + psessionEntry->smeSessionId, psessionEntry->transactionId); + } + else + { + limSendSmeRsp(pMac, eWNI_PMC_ENTER_UAPSD_RSP, retStatus, 0, 0); + } + + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmExitUapsdRequestHandler + * + * FUNCTION: + * This function process the eWNI_PMC_EXIT_UAPSD_REQ from PMC, + * checks the correctness of the system state before configuring + * PMM to the new ePMM_STATE_UAPSD_WT_WAKEUP_RSP state, and + * invokes pmmUapsdSendChangePwrSaveMsg() to send + * SIR_HAL_EXIT_UAPSD_REQ to HAL. + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitUapsdRequestHandler(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + + tPmmState origState = pMac->pmm.gPmmState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_UAPSD_REQ_EVENT, peGetValidPowerSaveSession(pMac), 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if (ePMM_STATE_UAPSD_SLEEP == pMac->pmm.gPmmState) + { + pMac->pmm.gPmmState = ePMM_STATE_UAPSD_WT_WAKEUP_RSP; + if( (retStatus = pmmUapsdSendChangePwrSaveMsg(pMac, SIR_PM_ACTIVE_MODE)) != + eSIR_SUCCESS) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: sending EXIT_UAPSD to HAL failed "));) + resultCode = eSIR_SME_UAPSD_REQ_FAILED; + goto failure; + } + } + else + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: Rcv EXIT_UAPSD from PMC in invalid state: %d"), + pMac->pmm.gPmmState);) + + resultCode = eSIR_SME_INVALID_PMM_STATE; + goto failure; + } + return; + +failure: + pMac->pmm.gPmmState = origState; + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: Waking up from UAPSD mode failed, Ret Code: %d, Next State: %d"), + retStatus, pMac->pmm.gPmmState);) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, 0, 0); +} + + +// -------------------------------------------------------------------- +/** + * pmmExitUapsdResponseHandler + * + * FUNCTION: + * This function receives the SIR_HAL_EXIT_UAPSD_RSP from HAL and is + * responsible for checking the correctness of the system state + * before configuring PMM to the new ePMM_STATE_BMPS_SLEEP state + * and send eWNI_PMC_EXIT_UAPSD_RSP to PMC. + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ +void pmmExitUapsdResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tSirResultCodes resultCode = eSIR_SME_SUCCESS; + tANI_U8 PowersavesessionId; + tpPESession psessionEntry; + tUapsdParams *pUapsdExitRspParams; + + /* we need to process all the deferred messages enqueued since + * the initiating the SIR_HAL_EXIT_UAPSD_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + if (pMac->pmm.gPmmState != ePMM_STATE_UAPSD_WT_WAKEUP_RSP) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Received HAL_EXIT_UAPSD_RSP in invalid state: %d"), + pMac->pmm.gPmmState);) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SME_INVALID_PMM_STATE, 0, 0); + return; + } + pUapsdExitRspParams = (tUapsdParams *)(limMsg->bodyptr); + + PowersavesessionId = pMac->pmm.sessionId; + if((psessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId))==NULL) + { + pmmLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); + return; + } + + if(NULL == pUapsdExitRspParams ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("Received HAL_EXIT_UAPSD_RSP message with zero parameters:"));) + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, eSIR_SME_UAPSD_REQ_FAILED, 0, 0); + return; + } + switch(pUapsdExitRspParams->status) + { + case eHAL_STATUS_SUCCESS: + resultCode = eSIR_SME_SUCCESS; + PELOGW(pmmLog(pMac, LOGW, + FL("Received SIR_HAL_EXIT_UAPSD_RSP with Successful response "));) + break; + default: + resultCode = eSIR_SME_UAPSD_REQ_FAILED; + PELOGE(pmmLog(pMac, LOGW, + FL("Received SIR_HAL_EXIT_UAPSD_RSP with Failure Status"));) + break; + } + + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + + if(IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION)) + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, psessionEntry->smeSessionId, + psessionEntry->transactionId); + } + else + { + limSendSmeRsp(pMac, eWNI_PMC_EXIT_UAPSD_RSP, resultCode, 0, 0); + } + return; +} + +/** ------------------------------------------------------------ +\fn pmmSendWowlAddBcastPtrn +\brief This function sends a SIR_HAL_WOWL_ADD_BCAST_PTRN +\ message to HAL. +\param tpAniSirGlobal pMac +\param tpSirMsgQ pMsg +\return None + --------------------------------------------------------------*/ +void pmmSendWowlAddBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirWowlAddBcastPtrn pBcastPtrn; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pBcastPtrn = vos_mem_malloc(sizeof(*pBcastPtrn)); + if ( NULL == pBcastPtrn ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Add Bcast Pattern ")); + return; + } + (void) vos_mem_copy(pBcastPtrn, pMbMsg->data, sizeof(*pBcastPtrn)); + + if (NULL == pBcastPtrn) + { + pmmLog(pMac, LOGE, FL("Add broadcast pattern message is NULL ")); + return; + } + + msgQ.type = WDA_WOWL_ADD_BCAST_PTRN; + msgQ.reserved = 0; + msgQ.bodyptr = pBcastPtrn; + msgQ.bodyval = 0; + + pmmLog(pMac, LOG1, FL( "Sending WDA_WOWL_ADD_BCAST_PTRN to HAL")); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_WOWL_ADD_BCAST_PTRN_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + if (pBcastPtrn != NULL) + vos_mem_free(pBcastPtrn); + pmmLog( pMac, LOGP, FL("Posting WDA_WOWL_ADD_BCAST_PTRN failed, reason=%X"), retCode ); + } + return; +} + +/** ------------------------------------------------------------ +\fn pmmSendWowlDelBcastPtrn +\brief This function sends a SIR_HAL_WOWL_DEL_BCAST_PTRN +\ message to HAL. +\param tpAniSirGlobal pMac +\param tpSirMsgQ pMsg +\return None + --------------------------------------------------------------*/ +void pmmSendWowlDelBcastPtrn(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirWowlDelBcastPtrn pDeletePtrn; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + pDeletePtrn = vos_mem_malloc(sizeof(*pDeletePtrn)); + if ( NULL == pDeletePtrn ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Delete Bcast Pattern ")); + return; + } + (void) vos_mem_copy(pDeletePtrn, pMbMsg->data, sizeof(*pDeletePtrn)); + + if (NULL == pDeletePtrn) + { + pmmLog(pMac, LOGE, FL("Delete broadcast pattern message is NULL ")); + return; + } + + msgQ.type = WDA_WOWL_DEL_BCAST_PTRN; + msgQ.reserved = 0; + msgQ.bodyptr = pDeletePtrn; + msgQ.bodyval = 0; + + pmmLog(pMac, LOG1, FL( "Sending WDA_WOWL_DEL_BCAST_PTRN")); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_WOWL_DEL_BCAST_PTRN_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + if (NULL != pDeletePtrn) + vos_mem_free(pDeletePtrn); + pmmLog( pMac, LOGP, FL("Posting WDA_WOWL_DEL_BCAST_PTRN failed, reason=%X"), retCode ); + } + return; +} + +/** --------------------------------------------------------- +\fn pmmEnterWowlRequestHandler +\brief LIM process the eWNI_PMC_ENTER_WOWL_REQ message, and +\ invokes pmmSendWowlEnterRequest() to send +\ WDA_WOWL_ENTER_REQ message to HAL. +\param tpAniSirGlobal pMac +\param tpSirMsgQ pMsg +\return None + ------------------------------------------------------------*/ +void pmmEnterWowlRequestHandler(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + tpSirSmeWowlEnterParams pSmeWowlParams = NULL; + tpSirHalWowlEnterParams pHalWowlParams = NULL; + tSirRetStatus retCode = eSIR_SUCCESS; + tANI_U32 cfgValue = 0; + tSirMbMsg *pMbMsg = (tSirMbMsg *)pMsg->bodyptr; + tpPESession pSessionEntry = NULL; + tANI_U8 peSessionId = 0; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ENTER_WOWL_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + pSmeWowlParams = (tpSirSmeWowlEnterParams)(pMbMsg->data); + if (NULL == pSmeWowlParams) + { + pmmLog(pMac, LOGE, + FL("NULL message received")); + return; + } + + pSessionEntry = peFindSessionByBssid(pMac, pSmeWowlParams->bssId, + &peSessionId); + if (NULL == pSessionEntry) + { + pmmLog(pMac, LOGE, + FL("session does not exist for given BSSId")); + goto end; + } + pMac->pmm.sessionId = peSessionId; + +// Need to fix it ASAP - TBH +#if 0 + if (pMac->lim.gLimSmeState != eLIM_SME_LINK_EST_STATE) + { + pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ when station is not associated ")); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_STA_NOT_ASSOCIATED, 0, 0); + goto end; + } +#endif + /** + * In SAP mode BMPS is not supported skip bmps validation and + * send command directly. + */ + if (pSessionEntry->operMode != BSS_OPERATIONAL_MODE_AP) + { + if ((pMac->pmm.gPmmState != ePMM_STATE_BMPS_SLEEP) && + (pMac->pmm.gPmmState != ePMM_STATE_WOWLAN)) + { + pmmLog(pMac, LOGE, FL("Rcvd PMC_ENTER_WOWL_REQ in invalid Power Save state ")); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, + eSIR_SME_INVALID_PMM_STATE, 0, 0); + goto end; + } + } else + pmmLog(pMac,LOG1, FL("SAP dosn't support BMPS mode directly post wowl request")); + + pHalWowlParams = vos_mem_malloc(sizeof(*pHalWowlParams)); + if ( NULL == pHalWowlParams ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for Enter Wowl Request ")); + goto end; + } + (void) vos_mem_set((tANI_U8 *)pHalWowlParams, sizeof(*pHalWowlParams), 0); + + // fill in the message field + pHalWowlParams->ucMagicPktEnable = pSmeWowlParams->ucMagicPktEnable; + pHalWowlParams->ucPatternFilteringEnable = pSmeWowlParams->ucPatternFilteringEnable; + (void)vos_mem_copy( (tANI_U8 *)pHalWowlParams->magicPtrn, (tANI_U8 *)pSmeWowlParams->magicPtrn, + sizeof(tSirMacAddr) ); + +#ifdef WLAN_WAKEUP_EVENTS + pHalWowlParams->ucWoWEAPIDRequestEnable = pSmeWowlParams->ucWoWEAPIDRequestEnable; + pHalWowlParams->ucWoWEAPOL4WayEnable = pSmeWowlParams->ucWoWEAPOL4WayEnable; + pHalWowlParams->ucWowNetScanOffloadMatch = pSmeWowlParams->ucWowNetScanOffloadMatch; + pHalWowlParams->ucWowGTKRekeyError = pSmeWowlParams->ucWowGTKRekeyError; + pHalWowlParams->ucWoWBSSConnLoss = pSmeWowlParams->ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + pHalWowlParams->bssIdx = pSessionEntry->bssIdx; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_UCAST_PATTERN_FILTER_ENABLE")); + goto end; + } + pHalWowlParams->ucUcastPatternFilteringEnable = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_CHANNEL_SWITCH_ENABLE")); + goto end; + } + pHalWowlParams->ucWowChnlSwitchRcv = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_DEAUTH_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE ")); + goto end; + } + pHalWowlParams->ucWowDeauthRcv = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_DISASSOC_ENABLE, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_DEAUTH_ENABLE ")); + goto end; + } + pHalWowlParams->ucWowDisassocRcv = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_MAX_MISSED_BEACON, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_MISSED_BEACON ")); + goto end; + } + pHalWowlParams->ucWowMaxMissedBeacons = (tANI_U8)cfgValue; + + if(wlan_cfgGetInt(pMac, WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD, &cfgValue) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGP, FL("cfgGet failed for WNI_CFG_WOWLAN_MAX_SLEEP_PERIOD ")); + goto end; + } + pHalWowlParams->ucWowMaxSleepUsec = (tANI_U8)cfgValue; + + //Send message to HAL + if( eSIR_SUCCESS != (retCode = pmmSendWowlEnterRequest( pMac, pHalWowlParams))) + { + pmmLog(pMac, LOGE, FL("Send ENTER_WOWL_REQ to HAL failed, reasonCode %d "), retCode); + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, eSIR_SME_WOWL_ENTER_REQ_FAILED, 0, 0); + goto end; + } + return; + +end: + if (pHalWowlParams != NULL) + vos_mem_free(pHalWowlParams); + return; +} + + +/** ------------------------------------------------------------ +\fn pmmSendWowlEnterRequest +\brief LIM sends a WDA_WOWL_ENTER_REQ message to HAL with +\ the message structure pHalWowlParams. HAL shall later +\ send a WDA_WOWL_ENTER_RSP with the same pointer +\ to the message structure back to PMM. +\param tpAniSirGlobal pMac +\param tpSirHalWowlEnterParams pHalWowlParams +\return tSirRetStatus + --------------------------------------------------------------*/ +tSirRetStatus pmmSendWowlEnterRequest(tpAniSirGlobal pMac, tpSirHalWowlEnterParams pHalWowlParams) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if (NULL == pHalWowlParams) + return eSIR_FAILURE; + + msgQ.type = WDA_WOWL_ENTER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pHalWowlParams; + msgQ.bodyval = 0; + + /* Defer any incoming message until we get + * a WDA_WOWL_ENTER_RSP from HAL + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + retCode = wdaPostCtrlMsg(pMac, &msgQ); + if( eSIR_SUCCESS != retCode ) + { + pmmLog( pMac, LOGE, FL("Posting WDA_WOWL_ENTER_REQ failed, reason=%X"), retCode ); + return retCode; + } + return retCode; +} + +/** --------------------------------------------------------- +\fn pmmEnterWowlanResponseHandler +\brief LIM process the WDA_WOWL_ENTER_RSP message. +\ and sends eWNI_PMC_ENTER_WOWL_RSP to SME. +\param tpAniSirGlobal pMac +\param tpSirMsgQ limMsg +\return None + ------------------------------------------------------------*/ +void pmmEnterWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpSirHalWowlEnterParams pWowlEnterParams; + eHalStatus rspStatus; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_WOWL_ENTER_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pWowlEnterParams = (tpSirHalWowlEnterParams)(limMsg->bodyptr); + if (NULL == pWowlEnterParams) + { + pmmLog(pMac, LOGE, FL("Recvd WDA_WOWL_ENTER_RSP with NULL msg ")); + smeRspCode = eSIR_SME_WOWL_ENTER_REQ_FAILED; + } + else + { + rspStatus = pWowlEnterParams->status; + + if(rspStatus == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOGW, FL("Rcv successful response from HAL to enter WOWLAN ")); + pMac->pmm.gPmmState = ePMM_STATE_WOWLAN; + } + else + { + pmmLog(pMac, LOGE, FL("HAL enter WOWLAN failed, informing SME")); + smeRspCode = eSIR_SME_WOWL_ENTER_REQ_FAILED; + } + } + + limSendSmeRsp(pMac, eWNI_PMC_ENTER_WOWL_RSP, smeRspCode, 0, 0); + return; +} + +/** --------------------------------------------------------- +\fn pmmExitWowlanRequestHandler +\brief PE process the eWNI_PMC_EXIT_WOWL_REQ message. +\ and sends WDA_WOWL_EXIT_REQ to HAL. +\param tpAniSirGlobal pMac +\return None + ------------------------------------------------------------*/ +void pmmExitWowlanRequestHandler(tpAniSirGlobal pMac) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + tpPESession pSessionEntry; + tpSirHalWowlExitParams pHalWowlMsg = NULL; + tANI_U8 PowersavesessionId = 0; + tANI_U8 smeSessionId = 0; + + PowersavesessionId = pMac->pmm.sessionId; + + if((pSessionEntry = peFindSessionBySessionId(pMac,PowersavesessionId)) == NULL ) + { + PELOGW(pmmLog(pMac, LOGE, FL("pmmWowl : failed to allocate memory"));) + smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED; + goto failure; + } + + smeSessionId = pSessionEntry->smeSessionId; + + pHalWowlMsg = vos_mem_malloc(sizeof(*pHalWowlMsg)); + if ( NULL == pHalWowlMsg ) + { + pmmLog(pMac, LOGP, FL("Fail to allocate memory for WoWLAN Add Bcast Pattern ")); + smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED; + goto failure; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_EXIT_WOWL_REQ_EVENT, NULL, 0, 0); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + if ( pMac->pmm.gPmmState != ePMM_STATE_WOWLAN ) + { + pmmLog(pMac, LOGE, + FL("Exit WOWLAN Request received in invalid state PMM=%d "), + pMac->pmm.gPmmState); + smeRspCode = eSIR_SME_INVALID_PMM_STATE; + goto failure; + } + + (void) vos_mem_set((tANI_U8 *)pHalWowlMsg, sizeof(*pHalWowlMsg), 0); + pHalWowlMsg->bssIdx = pSessionEntry->bssIdx; + + if((retStatus = pmmSendExitWowlReq(pMac, pHalWowlMsg)) != eSIR_SUCCESS) + { + pmmLog(pMac, LOGE, + FL("Fail to send WDA_WOWL_EXIT_REQ, reason code %d"), + retStatus); + smeRspCode = eSIR_SME_WOWL_EXIT_REQ_FAILED; + goto failure; + } + return; + +failure: + if (pHalWowlMsg != NULL) + vos_mem_free(pHalWowlMsg); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, smeRspCode, smeSessionId, 0); + return; +} + +/** --------------------------------------------------------- +\fn pmmSendExitWowlReq +\brief This function sends the WDA_WOWL_EXIT_REQ +\ message to HAL. +\param tpAniSirGlobal pMac +\return None + ------------------------------------------------------------*/ +tSirRetStatus pmmSendExitWowlReq(tpAniSirGlobal pMac, tpSirHalWowlExitParams pHalWowlParams) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if (NULL == pHalWowlParams) + return eSIR_FAILURE; + + msgQ.type = WDA_WOWL_EXIT_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pHalWowlParams; + msgQ.bodyval = 0; + + pmmLog(pMac, LOGW, FL("Sending WDA_WOWL_EXIT_REQ")); + + /* we need to defer any incoming messages until + * we get a WDA_WOWL_EXIT_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + pmmLog( pMac, LOGE, + FL("Posting WDA_WOWL_EXIT_REQ failed, reason=%X"), + retCode ); + + return retCode; +} + +/** --------------------------------------------------------- +\fn pmmExitWowlanResponseHandler +\brief This function process the WDA_WOWL_EXIT_RSP message. +\ and sends back eWNI_PMC_EXIT_WOWL_RSP to SME. +\param tpAniSirGlobal pMac +\return None + ------------------------------------------------------------*/ +void pmmExitWowlanResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + + tpSirHalWowlExitParams pHalWowlRspMsg; + eHalStatus rspStatus = eHAL_STATUS_FAILURE; + tpPESession psessionEntry = NULL; + tANI_U8 smeSessionId = 0; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_WOWL_EXIT_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pHalWowlRspMsg = (tpSirHalWowlExitParams)(limMsg->bodyptr); + if (NULL == pHalWowlRspMsg) + { + pmmLog(pMac, LOGE, FL("Recvd WDA_WOWL_ENTER_RSP with NULL msg ")); + } + else + { + // restore PMM state to BMPS mode + pMac->pmm.gPmmState = ePMM_STATE_BMPS_SLEEP; + rspStatus = pHalWowlRspMsg->status; + psessionEntry = peFindSessionByBssIdx(pMac, pHalWowlRspMsg->bssIdx); + if (psessionEntry) { + smeSessionId = psessionEntry->smeSessionId; + if (LIM_IS_AP_ROLE(psessionEntry)) + pMac->pmm.gPmmState = ePMM_STATE_READY; + } + } + + if( rspStatus == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOGW, FL("Rcvd successful rsp from HAL to exit WOWLAN ")); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_SUCCESS, smeSessionId, 0); + } + else + { + pmmLog(pMac, LOGE, FL("Rcvd failure rsp from HAL to exit WOWLAN ")); + limSendSmeRsp(pMac, eWNI_PMC_EXIT_WOWL_RSP, eSIR_SME_WOWL_EXIT_REQ_FAILED, smeSessionId, 0); + } + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmImpsSendChangePwrSaveMsg + * + * FUNCTION: + * This function is called to toggle the Idle mode power save mode + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @param mode to be configured + * @return None + */ + +tSirRetStatus pmmImpsSendChangePwrSaveMsg(tpAniSirGlobal pMac, tANI_U8 mode) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if (SIR_PM_SLEEP_MODE == mode) + { + msgQ.type = WDA_ENTER_IMPS_REQ; + pmmLog (pMac, LOG1, FL("Sending WDA_ENTER_IMPS_REQ to HAL")); + } + else + { + msgQ.type = WDA_EXIT_IMPS_REQ; + pmmLog (pMac, LOG1, FL("Sending WDA_EXIT_IMPS_REQ to HAL")); + } + + msgQ.reserved = 0; + msgQ.bodyptr = NULL; + msgQ.bodyval = 0; + + /* we need to defer any incoming messages until we get a + * WDA_ENTER_IMPS_REQ or WDA_EXIT_IMPS_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retStatus = wdaPostCtrlMsg(pMac, &msgQ); + if ( eSIR_SUCCESS != retStatus ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("WDA_ENTER/EXIT_IMPS_REQ to HAL failed, reason=%X"), retStatus);) + } + + return retStatus; +} + +// -------------------------------------------------------------------- +/** + * pmmUapsdSendChangePwrSaveMsg + * + * FUNCTION: + * This function is called to send either WDA_ENTER_UAPSD_REQ + * or WDA_EXIT_UAPSD_REQ to HAL. + * + * NOTE: + * + * @param pMac Global handle to MAC + * @param mode mode to be configured + * @return tSirRetStatus + */ +tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode) +{ + tSirRetStatus retStatus = eSIR_SUCCESS; + tpUapsdParams pUapsdParams = NULL; + tSirMsgQ msgQ; + tpPESession pSessionEntry; + tpExitUapsdParams pExitUapsdParams = NULL; + + if((pSessionEntry = peGetValidPowerSaveSession(pMac)) == NULL ) + { + PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd : failed to allocate memory"));) + retStatus = eSIR_FAILURE; + return retStatus; + } + + if (SIR_PM_SLEEP_MODE == mode) + { + pUapsdParams = vos_mem_malloc(sizeof(tUapsdParams)); + if ( NULL == pUapsdParams ) + { + PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd : failed to allocate memory"));) + retStatus = eSIR_MEM_ALLOC_FAILED; + return retStatus; + } + + vos_mem_set( (tANI_U8 *)pUapsdParams, sizeof(tUapsdParams), 0); + msgQ.type = WDA_ENTER_UAPSD_REQ; + msgQ.bodyptr = pUapsdParams; + + /* + * An AC is delivery enabled AC if the bit for that AC is set into the + * gAcAdmitMask[SIR_MAC_DIRECTION_DLINK],it is not set then we will take Static values. + */ + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + } + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + + /* + * An AC is trigger enabled AC if the bit for that AC is set into the + * gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK],it is not set then we will take Static values. + */ + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + } + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + + pUapsdParams->bssIdx = pSessionEntry->bssIdx; + + PELOGW(pmmLog(pMac, LOGW, + FL("UAPSD Mask: static = 0x%x, DeliveryEnabled = 0x%x, TriggerEnabled = 0x%x "), + pMac->lim.gUapsdPerAcBitmask, + pMac->lim.gUapsdPerAcDeliveryEnableMask, + pMac->lim.gUapsdPerAcTriggerEnableMask);) + + PELOGW(pmmLog(pMac, LOGW, FL("Delivery Enabled: BK=%d, BE=%d, Vi=%d, Vo=%d "), + pUapsdParams->bkDeliveryEnabled, + pUapsdParams->beDeliveryEnabled, + pUapsdParams->viDeliveryEnabled, + pUapsdParams->voDeliveryEnabled);) + + PELOGW(pmmLog(pMac, LOGW, FL("Trigger Enabled: BK=%d, BE=%d, Vi=%d, Vo=%d "), + pUapsdParams->bkTriggerEnabled, + pUapsdParams->beTriggerEnabled, + pUapsdParams->viTriggerEnabled, + pUapsdParams->voTriggerEnabled);) + + if (pUapsdParams->bkDeliveryEnabled == 0 && + pUapsdParams->beDeliveryEnabled == 0 && + pUapsdParams->viDeliveryEnabled == 0 && + pUapsdParams->voDeliveryEnabled == 0 && + pUapsdParams->bkTriggerEnabled == 0 && + pUapsdParams->beTriggerEnabled == 0 && + pUapsdParams->viTriggerEnabled == 0 && + pUapsdParams->voTriggerEnabled == 0) + { + limLog(pMac, LOGW, FL("No Need to enter UAPSD since Trigger " + "Enabled and Delivery Enabled Mask is zero for all ACs")); + vos_mem_free(pUapsdParams); + retStatus = eSIR_PMM_INVALID_REQ; + return retStatus; + } + + PELOGW(pmmLog (pMac, LOGW, FL("pmmUapsd: Sending WDA_ENTER_UAPSD_REQ to HAL"));) + } + else + { + pExitUapsdParams = vos_mem_malloc(sizeof(tExitUapsdParams)); + if ( NULL == pExitUapsdParams ) + { + PELOGW(pmmLog(pMac, LOGW, FL("pmmUapsd : failed to allocate memory"));) + retStatus = eSIR_MEM_ALLOC_FAILED; + return retStatus; + } + + vos_mem_set( (tANI_U8 *)pExitUapsdParams, sizeof(tExitUapsdParams), 0); + msgQ.type = WDA_EXIT_UAPSD_REQ; + msgQ.bodyptr = pExitUapsdParams; + pExitUapsdParams->bssIdx = pSessionEntry->bssIdx; + PELOGW(pmmLog (pMac, LOGW, FL("pmmUapsd: Sending WDA_EXIT_UAPSD_REQ to HAL"));) + } + + /* we need to defer any incoming messages until we get a + * WDA_ENTER/EXIT_UAPSD_RSP from HAL. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, false); + + msgQ.reserved = 0; + msgQ.bodyval = 0; + MTRACE(macTraceMsgTx(pMac, NO_SESSION, msgQ.type)); + retStatus = wdaPostCtrlMsg(pMac, &msgQ); + if ( eSIR_SUCCESS != retStatus ) + { + PELOGE(pmmLog(pMac, LOGE, + FL("pmmUapsd: WDA_ENTER/EXIT_UAPSD_REQ to HAL failed, reason=%X"), + retStatus);) + if (SIR_PM_SLEEP_MODE == mode) + vos_mem_free(pUapsdParams); + else + vos_mem_free(pExitUapsdParams); + } + + return retStatus; +} + + +// -------------------------------------------------------------------- +/** + * pmmUpdateImpsPwrSaveStats + * + * FUNCTION: + * This function is called to update the power save statistics in MAC + * for Idle mode power save + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ + +void pmmImpsUpdatePwrSaveStats(tpAniSirGlobal pMac) +{ +/* + tANI_U64 TimeAwake = 0; + + pMac->pmm.ImpsSleepTimeStamp = vos_timer_get_system_ticks(); + + if (pMac->pmm.ImpsWakeupTimeStamp) + { + TimeAwake = (pMac->pmm.ImpsSleepTimeStamp - pMac->pmm.ImpsWakeupTimeStamp) / 10 ; + } + else + { + TimeAwake = 0; + } + + if (TimeAwake > pMac->pmm.ImpsMaxTimeAwake) + { + pMac->pmm.ImpsMaxTimeAwake = TimeAwake; + } + + if ((!pMac->pmm.ImpsMinTimeAwake) || (TimeAwake < pMac->pmm.ImpsMinTimeAwake)) + { + pMac->pmm.ImpsMinTimeAwake = TimeAwake; + } + + pMac->pmm.ImpsAvgTimeAwake = ((pMac->pmm.ImpsAvgTimeAwake * pMac->pmm.ImpsCntSleep) + TimeAwake) / (pMac->pmm.ImpsCntSleep + 1); + +*/ + (pMac->pmm.ImpsCntSleep)++; + + return; +} + + +// -------------------------------------------------------------------- +/** + * pmmImpsUpdateWakeupStats + * + * FUNCTION: + * This function is called to update the Wake up statistics in MAC + * for Idle mode power save + * + * LOGIC: + * + * ASSUMPTIONS: + * None + * + * NOTE: + * + * @param Global handle to MAC + * @return None + */ + +void pmmImpsUpdateWakeupStats (tpAniSirGlobal pMac) +{ +/* + tANI_U64 SleepTime = 0; + + pMac->pmm.ImpsWakeupTimeStamp = vos_timer_get_system_ticks(); + + SleepTime = (pMac->pmm.ImpsWakeupTimeStamp - pMac->pmm.ImpsSleepTimeStamp) / 10; + + if (SleepTime > pMac->pmm.ImpsMaxSleepTime) + { + pMac->pmm.ImpsMaxSleepTime = SleepTime; + } + + if ((!pMac->pmm.ImpsMinSleepTime) || (SleepTime < pMac->pmm.ImpsMinSleepTime)) + { + pMac->pmm.ImpsMinSleepTime = SleepTime; + } + + pMac->pmm.ImpsAvgSleepTime = ( ( (pMac->pmm.ImpsAvgSleepTime * pMac->pmm.ImpsCntAwake) + SleepTime) / (pMac->pmm.ImpsCntAwake + 1)); + +*/ + (pMac->pmm.ImpsCntAwake)++; + + return; +} + +// Collects number of times error occurred while going to sleep mode +void pmmImpsUpdateSleepErrStats(tpAniSirGlobal pMac, + tSirRetStatus retStatus) +{ + pMac->pmm.ImpsSleepErrCnt++; + pMac->pmm.ImpsLastErr = retStatus; + return; +} + +// Collects number of times error occurred while waking up from sleep mode +void pmmImpsUpdateWakeupErrStats(tpAniSirGlobal pMac, + tSirRetStatus retStatus) +{ + pMac->pmm.ImpsWakeupErrCnt++; + pMac->pmm.ImpsLastErr = retStatus; + return; +} + + +// Collects number of times the system has received request or +// response in an invalid state +void pmmImpsUpdateErrStateStats(tpAniSirGlobal pMac) +{ + pMac->pmm.ImpsInvalidStateCnt++; + return; +} + +// Collects number of packets dropped while in IMPS mode +void pmmImpsUpdatePktDropStats(tpAniSirGlobal pMac) +{ + + pMac->pmm.ImpsPktDrpInSleepMode++; + return; +} + +// Collects number of packets dropped while in BMPS mode +void pmmBmpsUpdatePktDropStats(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsPktDrpInSleepMode++; + return; +} + +// Collects statistics for number of times BMPS init failed +void pmmBmpsUpdateInitFailureCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsInitFailCnt++; + return; +} + +// Collects statistics for number of times sleep request failed +void pmmBmpsUpdateSleepReqFailureCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsSleeReqFailCnt++; + return; +} + +// Collects statistics for number of times Wakeup request failed +void pmmBmpsUpdateWakeupReqFailureCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsWakeupReqFailCnt++; + return; +} + +// Collects statistics for number of times request / response received in invalid state +void pmmBmpsUpdateInvalidStateCnt(tpAniSirGlobal pMac) +{ + + pMac->pmm.BmpsInvStateCnt++; + return; +} + +// Collects statistics for number of times wakeup indications received +void pmmBmpsUpdateWakeupIndCnt(tpAniSirGlobal pMac) +{ + pMac->pmm.BmpsWakeupIndCnt++; + return; +} + +// Collects statistics for number of times wakeup indications received +void pmmBmpsUpdateHalReqFailureCnt(tpAniSirGlobal pMac) +{ + pMac->pmm.BmpsHalReqFailCnt++; + return; +} + +// Collects statistics for number of times requests received from HDD in +// invalid device role +void pmmBmpsUpdateReqInInvalidRoleCnt(tpAniSirGlobal pMac) +{ + pMac->pmm.BmpsReqInInvalidRoleCnt++; + return; +} + +#if 0 +// Update the sleep statistics +void pmmUpdateDroppedPktStats(tpAniSirGlobal pMac) +{ + switch (pMac->pmm.gPmmState) + { + case ePMM_STATE_BMPS_SLEEP: + pmmBmpsUpdatePktDropStats(pMac); + break; + + case ePMM_STATE_IMPS_SLEEP: + pmmImpsUpdatePktDropStats(pMac); + break; + + default: + break; + } + return; + +} +#endif + +// Resets PMM state ePMM_STATE_READY +void pmmResetPmmState(tpAniSirGlobal pMac) +{ + pMac->pmm.gPmmState = ePMM_STATE_READY; + + pMac->pmm.inMissedBeaconScenario = FALSE; + return; +} + +/* Sends Background scan message back to Lim */ +void pmmSendMessageToLim(tpAniSirGlobal pMac, + tANI_U32 msgId) +{ + tSirMsgQ limMsg; + tANI_U32 statusCode; + + limMsg.type = (tANI_U16) msgId; + limMsg.bodyptr = NULL; + limMsg.bodyval = 0; + + if ((statusCode = limPostMsgApi(pMac, &limMsg)) != eSIR_SUCCESS) + { + PELOGW(pmmLog(pMac, LOGW, + FL("posting message %X to LIM failed, reason=%d"), + limMsg.type, statusCode);) + } +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +void pmmFilterMatchCountResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpSirRcvFltPktMatchRsp pRcvFltPktMatchCntRsp; + eHalStatus rspStatus; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pRcvFltPktMatchCntRsp = (tpSirRcvFltPktMatchRsp)(limMsg->bodyptr); + if (NULL == pRcvFltPktMatchCntRsp) + { + pmmLog(pMac, LOGE, FL("Received " + "WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP with NULL msg ")); + smeRspCode = eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED; + } + else + { + rspStatus = pRcvFltPktMatchCntRsp->status; + if (eHAL_STATUS_SUCCESS == rspStatus) + { + pmmLog(pMac, LOGE, FL("Rcv successful response from HAL to get " + "Packet Coalescing Filter Match Count")); + } + else + { + pmmLog(pMac, LOGE, FL("HAL failed to get Packet Coalescing " + "Filter Match Count, informing SME")); + smeRspCode = eSIR_SME_PC_FILTER_MATCH_COUNT_REQ_FAILED; + } + } + + limSendSmeRsp(pMac, eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP, + smeRspCode, 0, 0); + return; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void pmmGTKOffloadGetInfoResponseHandler(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRspParams; + eHalStatus rspStatus; + tSirResultCodes smeRspCode = eSIR_SME_SUCCESS; + + /* we need to process all the deferred messages enqueued + * since the initiating the WDA_GTK_OFFLOAD_GETINFO_REQ. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); + + pGtkOffloadGetInfoRspParams = (tpSirGtkOffloadGetInfoRspParams)(limMsg->bodyptr); + if (NULL == pGtkOffloadGetInfoRspParams) + { + pmmLog(pMac, LOGE, FL("Received WDA_GTK_OFFLOAD_GETINFO_RSP with NULL msg ")); + smeRspCode = eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED; + } + else + { + rspStatus = pGtkOffloadGetInfoRspParams->ulStatus; + if(rspStatus == eHAL_STATUS_SUCCESS) + { + pmmLog(pMac, LOGW, FL("Rcv successful response from HAL to get GTK Offload Information")); + } + else + { + pmmLog(pMac, LOGE, FL("HAL failed to get GTK Offload Information, informing SME")); + smeRspCode = eSIR_SME_GTK_OFFLOAD_GETINFO_REQ_FAILED; + } + } + + limSendSmeRsp(pMac, eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP, smeRspCode, 0, 0); + return; +} +#endif // WLAN_FEATURE_GTK_OFFLOAD diff --git a/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.c b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.c new file mode 100644 index 000000000000..202b9b1660cf --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file pmmDebug.c + + \brief implementation for log Debug related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + +#include "vos_trace.h" +#include "pmmDebug.h" +#define LOG_SIZE 256 + +void pmmLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...) + { + VOS_TRACE_LEVEL vosDebugLevel; + char logBuffer[LOG_SIZE]; + va_list marker; + + /* getting proper Debug level */ + vosDebugLevel = getVosDebugLevel(loglevel); + + /* extracting arguments from pstring */ + va_start( marker, pString ); + vsnprintf(logBuffer, LOG_SIZE, pString, marker); + + VOS_TRACE(VOS_MODULE_ID_PMC, vosDebugLevel, "%s", logBuffer); + va_end( marker ); + } diff --git a/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.h b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.h new file mode 100644 index 000000000000..ea8d8f8aafdb --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/pmm/pmmDebug.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __PMM_DEBUG_H__ +#define __PMM_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#define UL_HI( field ) ( *( ( (ULONG *)(&(field)) ) + 1 ) ) +#define UL_LO( field ) ( *( ( (ULONG *)(&(field)) ) + 0 ) ) + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) pmmLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...) ; + +#endif + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/rrm/rrmApi.c b/drivers/staging/prima/CORE/MAC/src/pe/rrm/rrmApi.c new file mode 100644 index 000000000000..5bba7e7df264 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/rrm/rrmApi.c @@ -0,0 +1,1360 @@ +/* + * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file rrmApi.c + + \brief implementation for PE RRM APIs + + + ========================================================================*/ + +/* $Header$ */ + +#if defined WLAN_FEATURE_VOWIFI + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "palTypes.h" +#include "wniApi.h" +#include "sirApi.h" +#include "aniGlobal.h" +#include "wniCfg.h" +#include "limTypes.h" +#include "limUtils.h" +#include "limSendSmeRspMessages.h" +#include "parserApi.h" +#include "limSendMessages.h" +#include "rrmGlobal.h" +#include "rrmApi.h" + +tANI_U8 +rrmGetMinOfMaxTxPower(tpAniSirGlobal pMac, + tPowerdBm regMax, tPowerdBm apTxPower) +{ + tANI_U8 maxTxPower = 0; + tANI_U8 txPower = VOS_MIN( regMax, (apTxPower) ); + if((txPower >= RRM_MIN_TX_PWR_CAP) && (txPower <= RRM_MAX_TX_PWR_CAP)) + maxTxPower = txPower; + else if (txPower < RRM_MIN_TX_PWR_CAP) + maxTxPower = RRM_MIN_TX_PWR_CAP; + else + maxTxPower = RRM_MAX_TX_PWR_CAP; + + limLog( pMac, LOG3, + "%s: regulatoryMax = %d, apTxPwr = %d, maxTxpwr = %d", + __func__, regMax, apTxPower, maxTxPower ); + return maxTxPower; +} + +// -------------------------------------------------------------------- +/** + * rrmCacheMgmtTxPower + ** + * FUNCTION: Store Tx power for management frames. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry session entry. + * @return None + */ +void +rrmCacheMgmtTxPower ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry ) +{ + limLog( pMac, LOG3, "Cache Mgmt Tx Power = %d", txPower ); + + if( pSessionEntry == NULL ) + { + limLog( pMac, LOG3, "%s: pSessionEntry is NULL", __func__); + pMac->rrm.rrmPEContext.txMgmtPower = txPower; + } + else + pSessionEntry->txMgmtPower = txPower; +} + +// -------------------------------------------------------------------- +/** + * rrmGetMgmtTxPower + * + * FUNCTION: Get the Tx power for management frames. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry session entry. + * @return txPower + */ +tPowerdBm +rrmGetMgmtTxPower ( tpAniSirGlobal pMac, tpPESession pSessionEntry ) +{ + limLog( pMac, LOG3, "RrmGetMgmtTxPower called" ); + + if( pSessionEntry == NULL ) + { + limLog( pMac, LOG3, "%s: txpower from rrmPEContext: %d", + __func__, pMac->rrm.rrmPEContext.txMgmtPower); + return pMac->rrm.rrmPEContext.txMgmtPower; + } + + return pSessionEntry->txMgmtPower; +} + +// -------------------------------------------------------------------- +/** + * rrmSendSetMaxTxPowerReq + * + * FUNCTION: Send WDA_SET_MAX_TX_POWER_REQ message to change the max tx power. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param txPower txPower to be set. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmSendSetMaxTxPowerReq ( tpAniSirGlobal pMac, tPowerdBm txPower, tpPESession pSessionEntry ) +{ + tpMaxTxPowerParams pMaxTxParams; + tSirRetStatus retCode = eSIR_SUCCESS; + tSirMsgQ msgQ; + + if( pSessionEntry == NULL ) + { + PELOGE(limLog(pMac, LOGE, FL(" Inavalid parameters"));) + return eSIR_FAILURE; + } + pMaxTxParams = vos_mem_malloc(sizeof(tMaxTxPowerParams)); + if ( NULL == pMaxTxParams ) + { + limLog( pMac, LOGP, FL("Unable to allocate memory for pMaxTxParams ") ); + return eSIR_MEM_ALLOC_FAILED; + + } + /* Allocated memory for pMaxTxParams...will be freed in other module */ + pMaxTxParams->power = txPower; + vos_mem_copy(pMaxTxParams->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr)); + vos_mem_copy(pMaxTxParams->selfStaMacAddr, pSessionEntry->selfMacAddr, sizeof(tSirMacAddr)); + + + msgQ.type = WDA_SET_MAX_TX_POWER_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pMaxTxParams; + msgQ.bodyval = 0; + + limLog(pMac, LOG3, + FL( "Sending WDA_SET_MAX_TX_POWER_REQ with power(%d) to HAL"), + txPower); + + MTRACE(macTraceMsgTx(pMac, pSessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + limLog( pMac, LOGP, FL("Posting WDA_SET_MAX_TX_POWER_REQ to HAL failed, reason=%X"), retCode ); + vos_mem_free(pMaxTxParams); + return retCode; + } + return retCode; +} + + +// -------------------------------------------------------------------- +/** + * rrmSetMaxTxPowerRsp + * + * FUNCTION: Process WDA_SET_MAX_TX_POWER_RSP message. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param txPower txPower to be set. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmSetMaxTxPowerRsp ( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) +{ + tSirRetStatus retCode = eSIR_SUCCESS; + tpMaxTxPowerParams pMaxTxParams = (tpMaxTxPowerParams) limMsgQ->bodyptr; + tpPESession pSessionEntry; + tANI_U8 sessionId, i; + tSirMacAddr bssid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if( vos_mem_compare(bssid, pMaxTxParams->bssId, sizeof(tSirMacAddr))) + { + for (i =0;i < pMac->lim.maxBssId;i++) + { + if ( (pMac->lim.gpSession[i].valid == TRUE )) + { + pSessionEntry = &pMac->lim.gpSession[i]; + rrmCacheMgmtTxPower ( pMac, pMaxTxParams->power, pSessionEntry ); + } + } + } + else + { + if((pSessionEntry = peFindSessionByBssid(pMac, pMaxTxParams->bssId, &sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE, FL("Unable to find session:") );) + retCode = eSIR_FAILURE; + } + else + { + rrmCacheMgmtTxPower ( pMac, pMaxTxParams->power, pSessionEntry ); + } + } + + vos_mem_free(limMsgQ->bodyptr); + limMsgQ->bodyptr = NULL; + return retCode; +} +// -------------------------------------------------------------------- +/** + * rrmProcessLinkMeasurementRequest + * + * FUNCTION: Processes the Link measurement request and send the report. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pBd pointer to BD to extract RSSI and SNR + * @param pLinkReq pointer to the Link request frame structure. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmProcessLinkMeasurementRequest( tpAniSirGlobal pMac, + tANI_U8 *pRxPacketInfo, + tDot11fLinkMeasurementRequest *pLinkReq, + tpPESession pSessionEntry ) +{ + tSirMacLinkReport LinkReport; + tpSirMacMgmtHdr pHdr; + v_S7_t currentRSSI = 0; + + limLog( pMac, LOG3, "Received Link measurement request"); + + if( pRxPacketInfo == NULL || pLinkReq == NULL || pSessionEntry == NULL ) + { + PELOGE(limLog( pMac, LOGE, + "%s Invalid parameters - Ignoring the request", __func__);) + return eSIR_FAILURE; + } + pHdr = WDA_GET_RX_MAC_HEADER( pRxPacketInfo ); + LinkReport.txPower = limGetMaxTxPower (pSessionEntry->maxTxPower, + pLinkReq->MaxTxPower.maxTxPower, + pMac->roam.configParam.nTxPowerCap); + + if ((LinkReport.txPower != (uint8)(pSessionEntry->maxTxPower)) && + (eSIR_SUCCESS == rrmSendSetMaxTxPowerReq (pMac, + (tPowerdBm)(LinkReport.txPower), + pSessionEntry))) + { + PELOGW (limLog (pMac, + LOGW, + FL(" maxTx power in link report is not same as local..." + " Local = %d Link Request TxPower = %d" + " Link Report TxPower = %d"), + pSessionEntry->maxTxPower, + LinkReport.txPower, + pLinkReq->MaxTxPower.maxTxPower);) + pSessionEntry->maxTxPower = (tPowerdBm)(LinkReport.txPower); + } + LinkReport.dialogToken = pLinkReq->DialogToken.token; + LinkReport.rxAntenna = 0; + LinkReport.txAntenna = 0; + currentRSSI = WDA_GET_RX_RSSI_DB(pRxPacketInfo); + + limLog( pMac, LOG1, + "Received Link report frame with %d", currentRSSI); + + // 2008 11k spec reference: 18.4.8.5 RCPI Measurement + if ((currentRSSI) <= RCPI_LOW_RSSI_VALUE) + LinkReport.rcpi = 0; + else if ((currentRSSI > RCPI_LOW_RSSI_VALUE) && (currentRSSI <= 0)) + LinkReport.rcpi = CALCULATE_RCPI(currentRSSI); + else + LinkReport.rcpi = RCPI_MAX_VALUE; + + LinkReport.rsni = WDA_GET_RX_SNR(pRxPacketInfo); + + limLog( pMac, LOG3, "Sending Link report frame"); + + return limSendLinkReportActionFrame( pMac, &LinkReport, pHdr->sa, pSessionEntry ); +} + +// -------------------------------------------------------------------- +/** + * rrmProcessNeighborReportResponse + * + * FUNCTION: Processes the Neighbor Report response from the peer AP. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pNeighborRep pointer to the Neighbor report frame structure. + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmProcessNeighborReportResponse( tpAniSirGlobal pMac, + tDot11fNeighborReportResponse *pNeighborRep, + tpPESession pSessionEntry ) +{ + tSirRetStatus status = eSIR_FAILURE; + tpSirNeighborReportInd pSmeNeighborRpt = NULL; + tANI_U16 length; + tANI_U8 i; + tSirMsgQ mmhMsg; + + if( pNeighborRep == NULL || pSessionEntry == NULL ) + { + PELOGE(limLog( pMac, LOGE, FL(" Invalid parameters") );) + return status; + } + + limLog( pMac, LOG3, FL("Neighbor report response received ") ); + + // Dialog token + if( pMac->rrm.rrmPEContext.DialogToken != pNeighborRep->DialogToken.token ) + { + PELOGE(limLog( pMac, LOGE, + "Dialog token mismatch in the received Neighbor report");) + return eSIR_FAILURE; + } + if( pNeighborRep->num_NeighborReport == 0 ) + { + PELOGE(limLog( pMac, LOGE, "No neighbor report in the frame...Dropping it");) + return eSIR_FAILURE; + } + length = (sizeof( tSirNeighborReportInd )) + + (sizeof( tSirNeighborBssDescription ) * (pNeighborRep->num_NeighborReport - 1) ) ; + + //Prepare the request to send to SME. + pSmeNeighborRpt = vos_mem_malloc(length); + if( NULL == pSmeNeighborRpt ) + { + PELOGE(limLog( pMac, LOGP, FL("Unable to allocate memory") );) + return eSIR_MEM_ALLOC_FAILED; + + } + vos_mem_set(pSmeNeighborRpt, length, 0); + + /* Allocated memory for pSmeNeighborRpt...will be freed by other module */ + + for( i = 0 ; i < pNeighborRep->num_NeighborReport ; i++ ) + { + pSmeNeighborRpt->sNeighborBssDescription[i].length = sizeof( tSirNeighborBssDescription ); /*+ any optional ies */ + vos_mem_copy(pSmeNeighborRpt->sNeighborBssDescription[i].bssId, + pNeighborRep->NeighborReport[i].bssid, + sizeof(tSirMacAddr)); + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fApPreauthReachable = pNeighborRep->NeighborReport[i].APReachability; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fSameSecurityMode = pNeighborRep->NeighborReport[i].Security; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fSameAuthenticator = pNeighborRep->NeighborReport[i].KeyScope; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapSpectrumMeasurement = pNeighborRep->NeighborReport[i].SpecMgmtCap; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapQos = pNeighborRep->NeighborReport[i].QosCap; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapApsd = pNeighborRep->NeighborReport[i].apsd; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapRadioMeasurement = pNeighborRep->NeighborReport[i].rrm; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapDelayedBlockAck = pNeighborRep->NeighborReport[i].DelayedBA; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fCapImmediateBlockAck = pNeighborRep->NeighborReport[i].ImmBA; + pSmeNeighborRpt->sNeighborBssDescription[i].bssidInfo.rrmInfo.fMobilityDomain = pNeighborRep->NeighborReport[i].MobilityDomain; + + pSmeNeighborRpt->sNeighborBssDescription[i].regClass = pNeighborRep->NeighborReport[i].regulatoryClass; + pSmeNeighborRpt->sNeighborBssDescription[i].channel = pNeighborRep->NeighborReport[i].channel; + pSmeNeighborRpt->sNeighborBssDescription[i].phyType = pNeighborRep->NeighborReport[i].PhyType; + } + + pSmeNeighborRpt->messageType = eWNI_SME_NEIGHBOR_REPORT_IND; + pSmeNeighborRpt->length = length; + pSmeNeighborRpt->numNeighborReports = pNeighborRep->num_NeighborReport; + vos_mem_copy(pSmeNeighborRpt->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr)); + + //Send request to SME. + mmhMsg.type = pSmeNeighborRpt->messageType; + mmhMsg.bodyptr = pSmeNeighborRpt; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, pSessionEntry->peSessionId, + mmhMsg.type)); + status = limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); + + return status; + +} + +// -------------------------------------------------------------------- +/** + * rrmProcessNeighborReportReq + * + * FUNCTION: + * + * LOGIC: Create a Neighbor report request and send it to peer. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pNeighborReq Neighbor report request params . + * @return None + */ +tSirRetStatus +rrmProcessNeighborReportReq( tpAniSirGlobal pMac, + tpSirNeighborReportReqInd pNeighborReq ) +{ + tSirRetStatus status = eSIR_SUCCESS; + tSirMacNeighborReportReq NeighborReportReq; + tpPESession pSessionEntry ; + tANI_U8 sessionId; + + if( pNeighborReq == NULL ) + { + PELOGE(limLog( pMac, LOGE, "NeighborReq is NULL" );) + return eSIR_FAILURE; + } + if ((pSessionEntry = peFindSessionByBssid(pMac,pNeighborReq->bssId,&sessionId))==NULL) + { + PELOGE(limLog(pMac, LOGE,FL("session does not exist for given bssId"));) + return eSIR_FAILURE; + } + + limLog( pMac, LOG1, FL("SSID present = %d "), pNeighborReq->noSSID ); + + vos_mem_set(&NeighborReportReq,sizeof( tSirMacNeighborReportReq ), 0); + + NeighborReportReq.dialogToken = ++pMac->rrm.rrmPEContext.DialogToken; + NeighborReportReq.ssid_present = !pNeighborReq->noSSID; + if( NeighborReportReq.ssid_present ) + { + vos_mem_copy(&NeighborReportReq.ssid, &pNeighborReq->ucSSID, sizeof(tSirMacSSid)); + PELOGE(sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGE, (tANI_U8*) NeighborReportReq.ssid.ssId, NeighborReportReq.ssid.length );) + } + + status = limSendNeighborReportRequestFrame( pMac, &NeighborReportReq, pNeighborReq->bssId, pSessionEntry ); + + return status; +} + +#define ABS(x) ((x < 0) ? -x : x) +// -------------------------------------------------------------------- +/** + * rrmProcessBeaconReportReq + * + * FUNCTION: Processes the Beacon report request from the peer AP. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pCurrentReq pointer to the current Req comtext. + * @param pBeaconReq pointer to the beacon report request IE from the peer. + * @param pSessionEntry session entry. + * @return None + */ +static tRrmRetStatus +rrmProcessBeaconReportReq( tpAniSirGlobal pMac, + tpRRMReq pCurrentReq, + tDot11fIEMeasurementRequest *pBeaconReq, + tpPESession pSessionEntry ) +{ + tSirMsgQ mmhMsg; + tpSirBeaconReportReqInd pSmeBcnReportReq; + tANI_U8 num_channels = 0, num_APChanReport; + tANI_U16 measDuration, maxMeasduration; + tANI_S8 maxDuration; + tANI_U8 sign; + + if( pBeaconReq->measurement_request.Beacon.BeaconReporting.present && + (pBeaconReq->measurement_request.Beacon.BeaconReporting.reportingCondition != 0) ) + { + //Repeated measurement is not supported. This means number of repetitions should be zero.(Already checked) + //All test case in VoWifi(as of version 0.36) use zero for number of repetitions. + //Beacon reporting should not be included in request if number of repetitons is zero. + // IEEE Std 802.11k-2008 Table 7-29g and section 11.10.8.1 + + PELOGE(limLog( pMac, LOGE, "Dropping the request: Reporting condition included in beacon report request and it is not zero");) + return eRRM_INCAPABLE; + } + + /* The logic here is to check the measurement duration passed in the beacon request. Following are the cases handled. + Case 1: If measurement duration received in the beacon request is greater than the max measurement duration advertised + in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 1, REFUSE the beacon request + Case 2: If measurement duration received in the beacon request is greater than the max measurement duration advertised + in the RRM capabilities(Assoc Req), and Duration Mandatory bit is set to 0, perform measurement for + the duration advertised in the RRM capabilities + + maxMeasurementDuration = 2^(nonOperatingChanMax - 4) * BeaconInterval + */ + maxDuration = pMac->rrm.rrmPEContext.rrmEnabledCaps.nonOperatingChanMax - 4; + sign = (maxDuration < 0) ? 1 : 0; + maxDuration = (1L << ABS(maxDuration)); + if (!sign) + maxMeasduration = maxDuration * pSessionEntry->beaconParams.beaconInterval; + else + maxMeasduration = pSessionEntry->beaconParams.beaconInterval / maxDuration; + + measDuration = pBeaconReq->measurement_request.Beacon.meas_duration; + + limLog( pMac, LOG3, + "maxDuration = %d sign = %d maxMeasduration = %d measDuration = %d", + maxDuration, sign, maxMeasduration, measDuration ); + + if( maxMeasduration < measDuration ) + { + if( pBeaconReq->durationMandatory ) + { + PELOGE(limLog( pMac, LOGE, "Dropping the request: duration mandatory and maxduration > measduration");) + return eRRM_REFUSED; + } + else + measDuration = maxMeasduration; + } + + //Cache the data required for sending report. + pCurrentReq->request.Beacon.reportingDetail = pBeaconReq->measurement_request.Beacon.BcnReportingDetail.present ? + pBeaconReq->measurement_request.Beacon.BcnReportingDetail.reportingDetail : + BEACON_REPORTING_DETAIL_ALL_FF_IE ; + + if( pBeaconReq->measurement_request.Beacon.RequestedInfo.present ) + { + pCurrentReq->request.Beacon.reqIes.pElementIds = vos_mem_malloc(sizeof(tANI_U8) * + pBeaconReq->measurement_request.Beacon.RequestedInfo.num_requested_eids); + if ( NULL == pCurrentReq->request.Beacon.reqIes.pElementIds ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory for request IEs buffer" )); + return eRRM_FAILURE; + } + limLog( pMac, LOG3, FL(" Allocated memory for pElementIds") ); + + pCurrentReq->request.Beacon.reqIes.num = pBeaconReq->measurement_request.Beacon.RequestedInfo.num_requested_eids; + vos_mem_copy(pCurrentReq->request.Beacon.reqIes.pElementIds, + pBeaconReq->measurement_request.Beacon.RequestedInfo.requested_eids, + pCurrentReq->request.Beacon.reqIes.num); + } + + if( pBeaconReq->measurement_request.Beacon.num_APChannelReport ) + { + for( num_APChanReport = 0 ; num_APChanReport < pBeaconReq->measurement_request.Beacon.num_APChannelReport ; num_APChanReport++ ) + num_channels += pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList; + } + + //Prepare the request to send to SME. + pSmeBcnReportReq = vos_mem_malloc(sizeof( tSirBeaconReportReqInd )); + if ( NULL == pSmeBcnReportReq ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during Beacon Report Req Ind to SME" )); + + return eRRM_FAILURE; + + } + + vos_mem_set(pSmeBcnReportReq,sizeof( tSirBeaconReportReqInd ),0); + + /* Allocated memory for pSmeBcnReportReq....will be freed by other modulea*/ + vos_mem_copy(pSmeBcnReportReq->bssId, pSessionEntry->bssId, sizeof(tSirMacAddr)); + pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; + pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd ); + pSmeBcnReportReq->uDialogToken = pBeaconReq->measurement_token; + pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_11K; + pSmeBcnReportReq->randomizationInterval = SYS_TU_TO_MS (pBeaconReq->measurement_request.Beacon.randomization); + pSmeBcnReportReq->channelInfo.regulatoryClass = pBeaconReq->measurement_request.Beacon.regClass; + pSmeBcnReportReq->channelInfo.channelNum = pBeaconReq->measurement_request.Beacon.channel; + pSmeBcnReportReq->measurementDuration[0] = SYS_TU_TO_MS(measDuration); + pSmeBcnReportReq->fMeasurementtype[0] = pBeaconReq->measurement_request.Beacon.meas_mode; + vos_mem_copy(pSmeBcnReportReq->macaddrBssid, pBeaconReq->measurement_request.Beacon.BSSID, + sizeof(tSirMacAddr)); + + if( pBeaconReq->measurement_request.Beacon.SSID.present ) + { + pSmeBcnReportReq->ssId.length = pBeaconReq->measurement_request.Beacon.SSID.num_ssid; + vos_mem_copy(pSmeBcnReportReq->ssId.ssId, + pBeaconReq->measurement_request.Beacon.SSID.ssid, + pSmeBcnReportReq->ssId.length); + } + + pCurrentReq->token = pBeaconReq->measurement_token; + + pSmeBcnReportReq->channelList.numChannels = num_channels; + if( pBeaconReq->measurement_request.Beacon.num_APChannelReport ) + { + tANI_U8 *ch_lst = pSmeBcnReportReq->channelList.channelNumber; + tANI_U8 len; + tANI_U16 ch_ctr = 0; + for(num_APChanReport = 0; + num_APChanReport < + pBeaconReq->measurement_request.Beacon.num_APChannelReport; + num_APChanReport++) { + len = pBeaconReq->measurement_request.Beacon. + APChannelReport[num_APChanReport].num_channelList; + if (ch_ctr + len > + sizeof(pSmeBcnReportReq->channelList.channelNumber)) + break; + + vos_mem_copy(&ch_lst[ch_ctr], + pBeaconReq->measurement_request.Beacon. + APChannelReport[num_APChanReport].channelList, + len); + + ch_ctr += len; + } + } + + //Send request to SME. + mmhMsg.type = eWNI_SME_BEACON_REPORT_REQ_IND; + mmhMsg.bodyptr = pSmeBcnReportReq; + MTRACE(macTrace(pMac, TRACE_CODE_TX_SME_MSG, pSessionEntry->peSessionId, + mmhMsg.type)); + return limSysProcessMmhMsgApi(pMac, &mmhMsg, ePROT); +} + +// -------------------------------------------------------------------- +/** + * rrmFillBeaconIes + * + * FUNCTION: + * + * LOGIC: Fills Fixed fields and Ies in bss description to an array of tANI_U8. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pIes - pointer to the buffer that should be populated with ies. + * @param pNumIes - returns the num of ies filled in this param. + * @param pIesMaxSize - Max size of the buffer pIes. + * @param eids - pointer to array of eids. If NULL, all ies will be populated. + * @param numEids - number of elements in array eids. + * @param pBssDesc - pointer to Bss Description. + * @return None + */ +static void +rrmFillBeaconIes( tpAniSirGlobal pMac, + tANI_U8 *pIes, tANI_U8 *pNumIes, tANI_U8 pIesMaxSize, + tANI_U8 *eids, tANI_U8 numEids, + tpSirBssDescription pBssDesc ) +{ + tANI_U8 len, *pBcnIes, BcnNumIes, count = 0, i; + + if( (pIes == NULL) || (pNumIes == NULL) || (pBssDesc == NULL) ) + { + PELOGE(limLog( pMac, LOGE, FL(" Invalid parameters") );) + return; + } + + //Make sure that if eid is null, numEids is set to zero. + numEids = (eids == NULL) ? 0 : numEids; + + pBcnIes = (tANI_U8*) &pBssDesc->ieFields[0]; + BcnNumIes = (tANI_U8)GET_IE_LEN_IN_BSS( pBssDesc->length ); + + *pNumIes = 0; + + *((tANI_U32*)pIes) = pBssDesc->timeStamp[0]; + *pNumIes+=sizeof(tANI_U32); pIes+=sizeof(tANI_U32); + *((tANI_U32*)pIes) = pBssDesc->timeStamp[1]; + *pNumIes+=sizeof(tANI_U32); pIes+=sizeof(tANI_U32); + *((tANI_U16*)pIes) = pBssDesc->beaconInterval; + *pNumIes+=sizeof(tANI_U16); pIes+=sizeof(tANI_U16); + *((tANI_U16*)pIes) = pBssDesc->capabilityInfo; + *pNumIes+=sizeof(tANI_U16); pIes+=sizeof(tANI_U16); + + while ( BcnNumIes > 0 ) + { + len = *(pBcnIes + 1) + 2; //element id + length. + limLog( pMac, LOG3, "EID = %d, len = %d total = %d", + *pBcnIes, *(pBcnIes+1), len ); + + i = 0; + do + { + if( ( (eids == NULL) || ( *pBcnIes == eids[i] ) ) && + ( (*pNumIes) + len) < pIesMaxSize ) + { + limLog( pMac, LOG3, "Adding Eid %d, len=%d", *pBcnIes, len ); + + vos_mem_copy(pIes, pBcnIes, len); + pIes += len; + *pNumIes += len; + count++; + break; + } + i++; + }while( i < numEids ); + + pBcnIes += len; + BcnNumIes -= len; + } + limLog( pMac, LOG1, "Total length of Ies added = %d", *pNumIes ); +} + +// -------------------------------------------------------------------- +/** + * rrmProcessBeaconReportXmit + * + * FUNCTION: + * + * LOGIC: Create a Radio measurement report action frame and send it to peer. + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pBcnReport Data for beacon report IE from SME. + * @return None + */ +tSirRetStatus +rrmProcessBeaconReportXmit( tpAniSirGlobal pMac, + tpSirBeaconReportXmitInd pBcnReport) +{ + tSirRetStatus status = eSIR_SUCCESS; + tSirMacRadioMeasureReport *pReport = NULL; + tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; + tpPESession pSessionEntry ; + tANI_U8 sessionId; + v_U8_t flagBSSPresent = FALSE, bssDescCnt = 0; + + limLog( pMac, LOG1, "Received beacon report xmit indication"); + + if (NULL == pBcnReport) + { + PELOGE(limLog( pMac, LOGE, + "Received pBcnReport is NULL in PE");) + return eSIR_FAILURE; + } + + if (NULL == pCurrentReq) + { + PELOGE(limLog( pMac, LOGE, + "Received report xmit while there is no request pending in PE");) + return eSIR_FAILURE; + } + + if( (pBcnReport->numBssDesc) || + (!pBcnReport->numBssDesc && pCurrentReq->sendEmptyBcnRpt) ) + { + pBcnReport->numBssDesc = (pBcnReport->numBssDesc == RRM_BCN_RPT_NO_BSS_INFO)? + RRM_BCN_RPT_MIN_RPT : pBcnReport->numBssDesc; + + if (NULL == (pSessionEntry = peFindSessionByBssid(pMac, + pBcnReport->bssId, + &sessionId))) + { + PELOGE(limLog(pMac, LOGE, FL("session does not exist for given bssId"));) + return eSIR_FAILURE; + } + + pReport = vos_mem_malloc(pBcnReport->numBssDesc * + sizeof(tSirMacRadioMeasureReport)); + + if (NULL == pReport) + { + PELOGE(limLog(pMac, LOGE, FL("RRM Report is NULL, allocation failed"));) + return eSIR_FAILURE; + } + + vos_mem_zero( pReport, + pBcnReport->numBssDesc * sizeof(tSirMacRadioMeasureReport) ); + + for (bssDescCnt = 0; bssDescCnt < pBcnReport->numBssDesc; bssDescCnt++) + { + //Prepare the beacon report and send it to the peer. + pReport[bssDescCnt].token = pBcnReport->uDialogToken; + pReport[bssDescCnt].refused = 0; + pReport[bssDescCnt].incapable = 0; + pReport[bssDescCnt].type = SIR_MAC_RRM_BEACON_TYPE; + + //If the scan result is NULL then send report request with + //option subelement as NULL.. + if ( NULL != pBcnReport->pBssDescription[bssDescCnt] ) + { + flagBSSPresent = TRUE; + } + + //Valid response is included if the size of beacon xmit + //is == size of beacon xmit ind + ies + if ( pBcnReport->length >= sizeof( tSirBeaconReportXmitInd ) ) + { + pReport[bssDescCnt].report.beaconReport.regClass = pBcnReport->regClass; + if ( flagBSSPresent ) + { + pReport[bssDescCnt].report.beaconReport.channel = + pBcnReport->pBssDescription[bssDescCnt]->channelId; + vos_mem_copy( pReport[bssDescCnt].report.beaconReport.measStartTime, + pBcnReport->pBssDescription[bssDescCnt]->startTSF, + sizeof( pBcnReport->pBssDescription[bssDescCnt]->startTSF) ); + pReport[bssDescCnt].report.beaconReport.measDuration = + SYS_MS_TO_TU(pBcnReport->duration); + pReport[bssDescCnt].report.beaconReport.phyType = + pBcnReport->pBssDescription[bssDescCnt]->nwType; + pReport[bssDescCnt].report.beaconReport.bcnProbeRsp = 1; + pReport[bssDescCnt].report.beaconReport.rsni = + pBcnReport->pBssDescription[bssDescCnt]->sinr; + pReport[bssDescCnt].report.beaconReport.rcpi = + pBcnReport->pBssDescription[bssDescCnt]->rssi; + + pReport[bssDescCnt].report.beaconReport.antennaId = 0; + pReport[bssDescCnt].report.beaconReport.parentTSF = + pBcnReport->pBssDescription[bssDescCnt]->parentTSF; + vos_mem_copy( pReport[bssDescCnt].report.beaconReport.bssid, + pBcnReport->pBssDescription[bssDescCnt]->bssId, + sizeof(tSirMacAddr)); + } + + switch ( pCurrentReq->request.Beacon.reportingDetail ) + { + case BEACON_REPORTING_DETAIL_NO_FF_IE: + //0 No need to include any elements. + limLog(pMac, LOG3, "No reporting detail requested"); + break; + case BEACON_REPORTING_DETAIL_ALL_FF_REQ_IE: + //1: Include all FFs and Requested Ies. + limLog(pMac, LOG3, + "Only requested IEs in reporting detail requested"); + + if ( flagBSSPresent ) + { + rrmFillBeaconIes( pMac, + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.Ies[0], + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.numIes, + BEACON_REPORT_MAX_IES, + pCurrentReq->request.Beacon.reqIes.pElementIds, + pCurrentReq->request.Beacon.reqIes.num, + pBcnReport->pBssDescription[bssDescCnt] ); + } + + break; + case BEACON_REPORTING_DETAIL_ALL_FF_IE: + //2 / default - Include all FFs and all Ies. + default: + limLog(pMac, LOG3, "Default all IEs and FFs"); + if ( flagBSSPresent ) + { + rrmFillBeaconIes( pMac, + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.Ies[0], + (tANI_U8*) &pReport[bssDescCnt].report.beaconReport.numIes, + BEACON_REPORT_MAX_IES, + NULL, 0, + pBcnReport->pBssDescription[bssDescCnt] ); + } + break; + } + } + } + + limLog( pMac, LOG1, "Sending Action frame with %d bss info", bssDescCnt); + limSendRadioMeasureReportActionFrame( pMac, + pCurrentReq->dialog_token, + bssDescCnt, + pReport, + pBcnReport->bssId, + pSessionEntry ); + + pCurrentReq->sendEmptyBcnRpt = false; + } + + if( pBcnReport->fMeasureDone ) + { + limLog( pMac, LOG3, "Measurement done....cleanup the context"); + + rrmCleanup(pMac); + } + + if( NULL != pReport ) + vos_mem_free(pReport); + + return status; +} + +void rrmProcessBeaconRequestFailure(tpAniSirGlobal pMac, tpPESession pSessionEntry, + tSirMacAddr peer, tRrmRetStatus status) +{ + tpSirMacRadioMeasureReport pReport = NULL; + tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; + + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport )); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return; + } + vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0); + pReport->token = pCurrentReq->token; + pReport->type = SIR_MAC_RRM_BEACON_TYPE; + + switch (status) + { + case eRRM_REFUSED: + pReport->refused = 1; + break; + case eRRM_INCAPABLE: + pReport->incapable = 1; + break; + default: + PELOGE(limLog( pMac, LOGE, + FL(" Beacon request processing failed no report sent with status %d "), + status);); + vos_mem_free(pReport); + return; + } + + limSendRadioMeasureReportActionFrame( pMac, pCurrentReq->dialog_token, 1, + pReport, peer, pSessionEntry ); + + vos_mem_free(pReport); + limLog( pMac, LOG3, FL(" Free memory for pReport") ); + return; +} + +// -------------------------------------------------------------------- +/** + * rrmProcessRadioMeasurementRequest + * + * FUNCTION: Processes the Radio Resource Measurement request. + * + * LOGIC: + + +* + * ASSUMPTIONS: + * + * NOTE: + * + * @param peer Macaddress of the peer requesting the radio measurement. + * @param pRRMReq Array of Measurement request IEs + * @param pSessionEntry session entry. + * @return None + */ +tSirRetStatus +rrmProcessRadioMeasurementRequest( tpAniSirGlobal pMac, + tSirMacAddr peer, + tDot11fRadioMeasurementRequest *pRRMReq, + tpPESession pSessionEntry ) +{ + tANI_U8 i; + tSirRetStatus status = eSIR_SUCCESS; + tpSirMacRadioMeasureReport pReport = NULL; + tANI_U8 num_report = 0; + tpRRMReq pCurrentReq = pMac->rrm.rrmPEContext.pCurrentReq; + tRrmRetStatus rrmStatus = eRRM_SUCCESS; + + if( !pRRMReq->num_MeasurementRequest ) + { + //No measurement requests.... + // + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport )); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport),0); + PELOGE(limLog( pMac, LOGE, + FL("No requestIes in the measurement request, sending incapable report"));) + pReport->incapable = 1; + num_report = 1; + limSendRadioMeasureReportActionFrame( pMac, pRRMReq->DialogToken.token, num_report, + pReport, peer, pSessionEntry ); + vos_mem_free(pReport); + return eSIR_FAILURE; + } + + // PF Fix + if( pRRMReq->NumOfRepetitions.repetitions > 0 ) + { + limLog( pMac, LOG1, + FL(" number of repetitions %d"), + pRRMReq->NumOfRepetitions.repetitions ); + + //Send a report with incapable bit set. Not supporting repetitions. + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport )); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, sizeof(tSirMacRadioMeasureReport), 0); + PELOGE(limLog( pMac, LOGE, FL(" Allocated memory for pReport") );) + pReport->incapable = 1; + pReport->type = pRRMReq->MeasurementRequest[0].measurement_type; + num_report = 1; + goto end; + + } + + for( i= 0; i < pRRMReq->num_MeasurementRequest; i++ ) + { + switch( pRRMReq->MeasurementRequest[i].measurement_type ) + { + case SIR_MAC_RRM_BEACON_TYPE: + //Process beacon request. + if( pCurrentReq ) + { + if ( pReport == NULL ) //Allocate memory to send reports for any subsequent requests. + { + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i)); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, + sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i), + 0); + limLog( pMac, LOG3, + FL(" rrm beacon type refused of %d report in beacon table"), + num_report ); + + } + pReport[num_report].refused = 1; + pReport[num_report].type = SIR_MAC_RRM_BEACON_TYPE; + pReport[num_report].token = pRRMReq->MeasurementRequest[i].measurement_token; + num_report++; + continue; + } + else + { + pCurrentReq = vos_mem_malloc(sizeof( *pCurrentReq )); + if ( NULL == pCurrentReq ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + vos_mem_free(pReport); + return eSIR_MEM_ALLOC_FAILED; + } + limLog( pMac, LOG3, FL(" Processing Beacon Report request") ); + vos_mem_set(pCurrentReq, sizeof( *pCurrentReq ), 0); + pCurrentReq->dialog_token = pRRMReq->DialogToken.token; + pCurrentReq->token = pRRMReq->MeasurementRequest[i].measurement_token; + pCurrentReq->sendEmptyBcnRpt = true; + pMac->rrm.rrmPEContext.pCurrentReq = pCurrentReq; + rrmStatus = rrmProcessBeaconReportReq( pMac, pCurrentReq, &pRRMReq->MeasurementRequest[i], pSessionEntry ); + if (eRRM_SUCCESS != rrmStatus) + { + rrmProcessBeaconRequestFailure(pMac, pSessionEntry, peer, rrmStatus); + rrmCleanup(pMac); + } + } + break; + default: + //Send a report with incapabale bit set. + if ( pReport == NULL ) //Allocate memory to send reports for any subsequent requests. + { + pReport = vos_mem_malloc(sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i)); + if ( NULL == pReport ) + { + limLog( pMac, LOGP, + FL( "Unable to allocate memory during RRM Req processing" )); + return eSIR_MEM_ALLOC_FAILED; + } + vos_mem_set(pReport, + sizeof( tSirMacRadioMeasureReport ) + * (pRRMReq->num_MeasurementRequest - i), + 0); + limLog( pMac, LOG3, + FL(" rrm beacon type incapble of %d report "), + num_report ); + } + pReport[num_report].incapable = 1; + pReport[num_report].type = pRRMReq->MeasurementRequest[i].measurement_type; + pReport[num_report].token = pRRMReq->MeasurementRequest[i].measurement_token; + num_report++; + break; + } + } + +end: + if( pReport ) + { + limSendRadioMeasureReportActionFrame( pMac, pRRMReq->DialogToken.token, num_report, + pReport, peer, pSessionEntry ); + + vos_mem_free(pReport); + limLog( pMac, LOG3, FL(" Free memory for pReport") ); + } + return status; + +} + +// -------------------------------------------------------------------- +/** + * rrmUpdateStartTSF + ** + * FUNCTION: Store start TSF of measurement. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param startTSF - TSF value at the start of measurement. + * @return None + */ +void +rrmUpdateStartTSF ( tpAniSirGlobal pMac, tANI_U32 startTSF[2] ) +{ +#if 0 //defined WLAN_VOWIFI_DEBUG + limLog( pMac, LOGE, "Update Start TSF = %d %d", startTSF[0], startTSF[1] ); +#endif + pMac->rrm.rrmPEContext.startTSF[0] = startTSF[0]; + pMac->rrm.rrmPEContext.startTSF[1] = startTSF[1]; +} + +// -------------------------------------------------------------------- +/** + * rrmGetStartTSF + * + * FUNCTION: Get the Start TSF. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param startTSF - store star TSF in this buffer. + * @return txPower + */ +void +rrmGetStartTSF ( tpAniSirGlobal pMac, tANI_U32 *pStartTSF ) +{ +#if 0 //defined WLAN_VOWIFI_DEBUG + limLog( pMac, LOGE, "Get the start TSF, TSF = %d %d ", pMac->rrm.rrmPEContext.startTSF[0], pMac->rrm.rrmPEContext.startTSF[1] ); +#endif + pStartTSF[0] = pMac->rrm.rrmPEContext.startTSF[0]; + pStartTSF[1] = pMac->rrm.rrmPEContext.startTSF[1]; + +} +// -------------------------------------------------------------------- +/** + * rrmGetCapabilities + * + * FUNCTION: + * Returns a pointer to tpRRMCaps with all the caps enabled in RRM + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry + * @return pointer to tRRMCaps + */ +tpRRMCaps rrmGetCapabilities ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ) +{ + return &pMac->rrm.rrmPEContext.rrmEnabledCaps; +} + +// -------------------------------------------------------------------- +/** + * rrmUpdateConfig + * + * FUNCTION: + * Update the configuration. This is called from limUpdateConfig. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pSessionEntry + * @return pointer to tRRMCaps + */ +void rrmUpdateConfig ( tpAniSirGlobal pMac, + tpPESession pSessionEntry ) +{ + tANI_U32 val; + tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_ENABLED, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get rrm enabled failed")); + return; + } + pMac->rrm.rrmPEContext.rrmEnable = (val) ? 1 : 0; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_OPERATING_CHAN_MAX, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get rrm operating channel max measurement duration failed")); + return; + } + pRRMCaps->operatingChanMax = (tANI_U8)val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_RRM_NON_OPERATING_CHAN_MAX, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get rrm non-operating channel max measurement duration failed")); + return; + } + pRRMCaps->nonOperatingChanMax =(tANI_U8) val; + + limLog( pMac, LOG1, + "RRM enabled = %d OperatingChanMax = %d NonOperatingMax = %d", + pMac->rrm.rrmPEContext.rrmEnable, + pRRMCaps->operatingChanMax, pRRMCaps->nonOperatingChanMax ); +} +// -------------------------------------------------------------------- +/** + * rrmInitialize + * + * FUNCTION: + * Initialize RRM module + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @return None + */ + +tSirRetStatus +rrmInitialize(tpAniSirGlobal pMac) +{ + tpRRMCaps pRRMCaps = &pMac->rrm.rrmPEContext.rrmEnabledCaps; + + pMac->rrm.rrmPEContext.pCurrentReq = NULL; + pMac->rrm.rrmPEContext.txMgmtPower = 0; + pMac->rrm.rrmPEContext.DialogToken = 0; + + pMac->rrm.rrmPEContext.rrmEnable = 0; + + vos_mem_set(pRRMCaps, sizeof(tRRMCaps), 0); + pRRMCaps->LinkMeasurement = 1; + pRRMCaps->NeighborRpt = 1; + pRRMCaps->BeaconPassive = 1; + pRRMCaps->BeaconActive = 1; + pRRMCaps->BeaconTable = 1; + pRRMCaps->APChanReport = 1; + + //pRRMCaps->TCMCapability = 1; + //pRRMCaps->triggeredTCM = 1; + pRRMCaps->operatingChanMax = 3; + pRRMCaps->nonOperatingChanMax = 3; + + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * rrmCleanup + * + * FUNCTION: + * cleanup RRM module + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param mode + * @param rate + * @return None + */ + +tSirRetStatus +rrmCleanup(tpAniSirGlobal pMac) +{ + if( pMac->rrm.rrmPEContext.pCurrentReq ) + { + if( pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.pElementIds ) + { + vos_mem_free(pMac->rrm.rrmPEContext.pCurrentReq->request.Beacon.reqIes.pElementIds); + limLog( pMac, LOG4, FL(" Free memory for pElementIds") ); + } + + vos_mem_free(pMac->rrm.rrmPEContext.pCurrentReq); + limLog( pMac, LOG4, FL(" Free memory for pCurrentReq") ); + } + + pMac->rrm.rrmPEContext.pCurrentReq = NULL; + return eSIR_SUCCESS; +} + +// -------------------------------------------------------------------- +/** + * rrmProcessMessage + * + * FUNCTION: Processes the next received Radio Resource Management message + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void rrmProcessMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + switch (pMsg->type) + { + case eWNI_SME_NEIGHBOR_REPORT_REQ_IND: + rrmProcessNeighborReportReq( pMac, pMsg->bodyptr ); + break; + case eWNI_SME_BEACON_REPORT_RESP_XMIT_IND: + rrmProcessBeaconReportXmit( pMac, pMsg->bodyptr ); + break; + } + +} + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schApi.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schApi.c new file mode 100644 index 000000000000..6357be7f89fd --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schApi.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schApi.cc contains functions related to the API exposed + * by scheduler module + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "aniGlobal.h" +#include "wniCfg.h" + +#include "sirMacProtDef.h" +#include "sirMacPropExts.h" +#include "sirCommon.h" + + +#include "cfgApi.h" +#include "pmmApi.h" + +#include "limApi.h" + +#include "schApi.h" +#include "schDebug.h" + +#include "schSysParams.h" +#include "limTrace.h" +#include "limTypes.h" + +#include "wlan_qct_wda.h" + +//-------------------------------------------------------------------- +// +// Static Variables +// +//------------------------------------------------------------------- +static tANI_U8 gSchProbeRspTemplate[SCH_MAX_PROBE_RESP_SIZE]; +static tANI_U8 gSchBeaconFrameBegin[SCH_MAX_BEACON_SIZE]; +static tANI_U8 gSchBeaconFrameEnd[SCH_MAX_BEACON_SIZE]; + +// -------------------------------------------------------------------- +/** + * schGetCFPCount + * + * FUNCTION: + * Function used by other Sirius modules to read CFPcount + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tANI_U8 +schGetCFPCount(tpAniSirGlobal pMac) +{ + return pMac->sch.schObject.gSchCFPCount; +} + +// -------------------------------------------------------------------- +/** + * schGetCFPDurRemaining + * + * FUNCTION: + * Function used by other Sirius modules to read CFPDuration remaining + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tANI_U16 +schGetCFPDurRemaining(tpAniSirGlobal pMac) +{ + return pMac->sch.schObject.gSchCFPDurRemaining; +} + + +// -------------------------------------------------------------------- +/** + * schInitialize + * + * FUNCTION: + * Initialize + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void +schInitialize(tpAniSirGlobal pMac) +{ + pmmInitialize(pMac); +} + +// -------------------------------------------------------------------- +/** + * schInitGlobals + * + * FUNCTION: + * Initialize globals + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void +schInitGlobals(tpAniSirGlobal pMac) +{ + pMac->sch.gSchHcfEnabled = false; + + pMac->sch.gSchScanRequested = false; + pMac->sch.gSchScanReqRcvd = false; + + pMac->sch.gSchGenBeacon = 1; + pMac->sch.gSchBeaconsSent = 0; + pMac->sch.gSchBeaconsWritten = 0; + pMac->sch.gSchBcnParseErrorCnt = 0; + pMac->sch.gSchBcnIgnored = 0; + pMac->sch.gSchBBXportRcvCnt = 0; + pMac->sch.gSchUnknownRcvCnt = 0; + pMac->sch.gSchBcnRcvCnt = 0; + pMac->sch.gSchRRRcvCnt = 0; + pMac->sch.qosNullCnt = 0; + pMac->sch.numData = 0; + pMac->sch.numPoll = 0; + pMac->sch.numCorrupt = 0; + pMac->sch.numBogusInt = 0; + pMac->sch.numTxAct0 = 0; + pMac->sch.rrTimeout = SCH_RR_TIMEOUT; + pMac->sch.pollPeriod = SCH_POLL_PERIOD; + pMac->sch.keepAlive = 0; + pMac->sch.multipleSched = 1; + pMac->sch.maxPollTimeouts = 20; + pMac->sch.checkCfbFlagStuck = 0; + + pMac->sch.schObject.gSchProbeRspTemplate = gSchProbeRspTemplate; + pMac->sch.schObject.gSchBeaconFrameBegin = gSchBeaconFrameBegin; + pMac->sch.schObject.gSchBeaconFrameEnd = gSchBeaconFrameEnd; + +} + +// -------------------------------------------------------------------- +/** + * schPostMessage + * + * FUNCTION: + * Post the beacon message to the scheduler message queue + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pMsg pointer to message + * @return None + */ + +tSirRetStatus +schPostMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) +{ + schProcessMessage(pMac, pMsg); + + return eSIR_SUCCESS; +} + + + + + +// --------------------------------------------------------------------------- +/** + * schSendStartScanRsp + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void +schSendStartScanRsp(tpAniSirGlobal pMac) +{ + tSirMsgQ msgQ; + tANI_U32 retCode; + + schLog(pMac, LOG1, FL("Sending SIR_SCH_START_SCAN_RSP to LIM")); + msgQ.type = SIR_SCH_START_SCAN_RSP; + if ((retCode = limPostMsgApi(pMac, &msgQ)) != eSIR_SUCCESS) + schLog(pMac, LOGE, + FL("Posting START_SCAN_RSP to LIM failed, reason=%X"), retCode); +} + +/** + * schSendBeaconReq + * + * FUNCTION: + * + * LOGIC: + * 1) SCH received SIR_SCH_BEACON_GEN_IND + * 2) SCH updates TIM IE and other beacon related IE's + * 3) SCH sends WDA_SEND_BEACON_REQ to HAL. HAL then copies the beacon + * template to memory + * + * ASSUMPTIONS: + * Memory allocation is reqd to send this message and SCH allocates memory. + * The assumption is that HAL will "free" this memory. + * + * NOTE: + * + * @param pMac global + * + * @param beaconPayload + * + * @param size - Length of the beacon + * + * @return eHalStatus + */ +tSirRetStatus schSendBeaconReq( tpAniSirGlobal pMac, tANI_U8 *beaconPayload, tANI_U16 size, tpPESession psessionEntry) +{ + tSirMsgQ msgQ; + tpSendbeaconParams beaconParams = NULL; + tSirRetStatus retCode; + + schLog( pMac, LOG2, + FL( "Indicating HAL to copy the beacon template [%d bytes] to memory" ), + size ); + + beaconParams = vos_mem_malloc(sizeof(tSendbeaconParams)); + if ( NULL == beaconParams ) + return eSIR_FAILURE; + + msgQ.type = WDA_SEND_BEACON_REQ; + + // No Dialog Token reqd, as a response is not solicited + msgQ.reserved = 0; + + // Fill in tSendbeaconParams members + /* Knock off all pMac global addresses */ + // limGetBssid( pMac, beaconParams->bssId); + vos_mem_copy(beaconParams->bssId, psessionEntry->bssId, sizeof(psessionEntry->bssId)); + + beaconParams->timIeOffset = pMac->sch.schObject.gSchBeaconOffsetBegin; + /* p2pIeOffset should be atleast greater than timIeOffset */ + if ((pMac->sch.schObject.p2pIeOffset != 0) && + (pMac->sch.schObject.p2pIeOffset < + pMac->sch.schObject.gSchBeaconOffsetBegin)) + { + schLog(pMac, LOGE,FL("Invalid p2pIeOffset:[%d]"), + pMac->sch.schObject.p2pIeOffset); + VOS_ASSERT( 0 ); + return eSIR_FAILURE; + } + beaconParams->p2pIeOffset = pMac->sch.schObject.p2pIeOffset; +#ifdef WLAN_SOFTAP_FW_BEACON_TX_PRNT_LOG + schLog(pMac, LOGE,FL("TimIeOffset:[%d]"),beaconParams->TimIeOffset ); +#endif + + beaconParams->beacon = beaconPayload; + beaconParams->beaconLength = (tANI_U32) size; + msgQ.bodyptr = beaconParams; + msgQ.bodyval = 0; + + // Keep a copy of recent beacon frame sent + + // free previous copy of the beacon + if (psessionEntry->beacon ) + { + vos_mem_free(psessionEntry->beacon); + } + + psessionEntry->bcnLen = 0; + psessionEntry->beacon = NULL; + + psessionEntry->beacon = vos_mem_malloc(size); + if ( psessionEntry->beacon != NULL ) + { + vos_mem_copy(psessionEntry->beacon, beaconPayload, size); + psessionEntry->bcnLen = size; + } + + MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, msgQ.type)); + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + schLog( pMac, LOGE, + FL("Posting SEND_BEACON_REQ to HAL failed, reason=%X"), + retCode ); + } else + { + schLog( pMac, LOG2, + FL("Successfully posted WDA_SEND_BEACON_REQ to HAL")); + + if( (psessionEntry->limSystemRole == eLIM_AP_ROLE ) + && (pMac->sch.schObject.fBeaconChanged) + && ((psessionEntry->proxyProbeRspEn) + || (IS_FEATURE_SUPPORTED_BY_FW(WPS_PRBRSP_TMPL))) + && vos_is_probe_rsp_offload_enabled() + ) + + { + schLog(pMac, LOG1, FL("Sending probeRsp Template to HAL")); + if(eSIR_SUCCESS != (retCode = limSendProbeRspTemplateToHal(pMac,psessionEntry, + &psessionEntry->DefProbeRspIeBitmap[0]))) + { + /* check whether we have to free any memory */ + schLog(pMac, LOGE, FL("FAILED to send probe response template with retCode %d"), retCode); + } + } + } + + return retCode; +} + +tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal pMac,tpPESession psessionEntry + ,tANI_U32* IeBitmap) +{ + tSirMsgQ msgQ; + tANI_U8 *pFrame2Hal = pMac->sch.schObject.gSchProbeRspTemplate; + tpSendProbeRespParams pprobeRespParams=NULL; + tANI_U32 retCode = eSIR_FAILURE; + tANI_U32 nPayload,nBytes,nStatus; + tpSirMacMgmtHdr pMacHdr; + tANI_U32 addnIEPresent; + tANI_U32 addnIE1Len=0; + tANI_U32 addnIE2Len = 0; + tANI_U32 addnIE3Len = 0; + tANI_U32 totalAddnIeLen = 0; + tSirRetStatus nSirStatus; + tANI_U8 *addIE = NULL; + + nStatus = dot11fGetPackedProbeResponseSize( pMac, &psessionEntry->probeRespFrame, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to calculate the packed size f" + "or a Probe Response (0x%08x)."), + nStatus ); + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeResponse ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while calculating" + "the packed size for a Probe Response " + "(0x%08x)."), nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + //Check if probe response IE is present or not + if (wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_ADDNIE_FLAG, &addnIEPresent) != eSIR_SUCCESS) + { + schLog(pMac, LOGE, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_FLAG")); + return retCode; + } + + if (addnIEPresent) + { + if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA1, + &addnIE1Len) != eSIR_SUCCESS) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length")); + return retCode; + } + + if (addnIE1Len == WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN) + { + if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + &addnIE2Len) != eSIR_SUCCESS) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 length")); + return retCode; + } + } + + if (addnIE2Len == WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN) + { + if (wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + &addnIE3Len) != eSIR_SUCCESS) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 length")); + return retCode; + } + } + schLog(pMac,LOG1, FL("addnIE1Len %d, addnIE2Len %d, addnIE3Len %d"), + addnIE1Len, addnIE2Len, addnIE3Len); + totalAddnIeLen = addnIE1Len + addnIE2Len + addnIE3Len; + + addIE = vos_mem_malloc(totalAddnIeLen); + if (NULL == addIE) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length")); + return retCode; + } + + if (addnIE1Len && addnIE1Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && + (nBytes + addnIE1Len) <= SIR_MAX_PACKET_SIZE) + { + if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA1, &addIE[0], + &addnIE1Len)) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 String")); + vos_mem_free(addIE); + return retCode; + } + } + + if (addnIE2Len && addnIE2Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA2_LEN && + (nBytes + addnIE1Len + addnIE2Len) <= SIR_MAX_PACKET_SIZE) + { + if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA2, + &addIE[addnIE1Len], + &addnIE2Len) ) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA2 String")); + vos_mem_free(addIE); + return retCode; + } + } + + if (addnIE3Len && addnIE3Len <= WNI_CFG_PROBE_RSP_ADDNIE_DATA3_LEN && + (nBytes + totalAddnIeLen) <= SIR_MAX_PACKET_SIZE) + { + if ( eSIR_SUCCESS != wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_ADDNIE_DATA3, + &addIE[addnIE1Len + addnIE2Len], + &addnIE3Len) ) + { + schLog(pMac, LOGE, + FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA3 String")); + vos_mem_free(addIE); + return retCode; + } + } + + } + + if (addnIEPresent) + { + if ((nBytes + totalAddnIeLen) <= SIR_MAX_PACKET_SIZE ) + nBytes += totalAddnIeLen; + else + addnIEPresent = false; //Dont include the IE. + } + + // Paranoia: + vos_mem_set(pFrame2Hal, nBytes, 0); + + // Next, we fill out the buffer descriptor: + nSirStatus = limPopulateMacHeader( pMac, pFrame2Hal, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_RSP, psessionEntry->selfMacAddr,psessionEntry->selfMacAddr); + + if ( eSIR_SUCCESS != nSirStatus ) + { + schLog( pMac, LOGE, FL("Failed to populate the buffer descrip" + "tor for a Probe Response (%d)."), + nSirStatus ); + + vos_mem_free(addIE); + return retCode; + } + + pMacHdr = ( tpSirMacMgmtHdr ) pFrame2Hal; + + sirCopyMacAddr(pMacHdr->bssId,psessionEntry->bssId); + + // That done, pack the Probe Response: + nStatus = dot11fPackProbeResponse( pMac, &psessionEntry->probeRespFrame, pFrame2Hal + sizeof(tSirMacMgmtHdr), + nPayload, &nPayload ); + + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to pack a Probe Response (0x%08x)."), + nStatus ); + + vos_mem_free(addIE); + return retCode; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while packing a P" + "robe Response (0x%08x)."), nStatus ); + } + + if (addnIEPresent) + { + vos_mem_copy ( &pFrame2Hal[nBytes - totalAddnIeLen], + &addIE[0], totalAddnIeLen); + } + + /* free the allocated Memory */ + vos_mem_free(addIE); + + pprobeRespParams = vos_mem_malloc(sizeof( tSendProbeRespParams )); + if ( NULL == pprobeRespParams ) + { + schLog( pMac, LOGE, FL("limSendProbeRspTemplateToHal: HAL probe response params malloc failed for bytes %d"), nBytes ); + } + else + { + /* + PELOGE(sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGE, + pFrame2Hal, + nBytes);) + */ + + sirCopyMacAddr( pprobeRespParams->bssId, psessionEntry->bssId); + pprobeRespParams->pProbeRespTemplate = pFrame2Hal; + pprobeRespParams->probeRespTemplateLen = nBytes; + vos_mem_copy(pprobeRespParams->ucProxyProbeReqValidIEBmap,IeBitmap,(sizeof(tANI_U32) * 8)); + msgQ.type = WDA_UPDATE_PROBE_RSP_TEMPLATE_IND; + msgQ.reserved = 0; + msgQ.bodyptr = pprobeRespParams; + msgQ.bodyval = 0; + + if( eSIR_SUCCESS != (retCode = wdaPostCtrlMsg( pMac, &msgQ ))) + { + /* free the allocated Memory */ + schLog( pMac,LOGE, FL("limSendProbeRspTemplateToHal: FAIL bytes %d retcode[%X]"), nBytes, retCode ); + vos_mem_free(pprobeRespParams); + } + else + { + schLog( pMac,LOG1, FL("limSendProbeRspTemplateToHal: Probe response template msg posted to HAL of bytes %d"),nBytes ); + } + } + + return retCode; +} + diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c new file mode 100644 index 000000000000..15438a7796ca --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconGen.c @@ -0,0 +1,891 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file schBeaconGen.cc contains beacon generation related + * functions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniCfg.h" +#include "aniGlobal.h" +#include "sirMacProtDef.h" + +#include "limUtils.h" +#include "limApi.h" + + +#include "halMsgApi.h" +#include "cfgApi.h" +#include "pmmApi.h" +#include "schApi.h" + +#include "parserApi.h" + +#include "schDebug.h" + +// +// March 15, 2006 +// Temporarily (maybe for all of Alpha-1), assuming TIM = 0 +// + +const tANI_U8 P2pOui[] = {0x50, 0x6F, 0x9A, 0x9}; + + +tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 *pP2pIeOffset) +{ + tSirRetStatus status = eSIR_FAILURE; + *pP2pIeOffset = 0; + + // Extra IE is not present + if(0 == extraIeLen) + { + return status; + } + + // Calculate the P2P IE Offset + do + { + if(*pExtraIe == 0xDD) + { + if ( vos_mem_compare ( (void *)(pExtraIe+2), &P2pOui, sizeof(P2pOui) ) ) + { + status = eSIR_SUCCESS; + break; + } + } + + (*pP2pIeOffset)++; + pExtraIe++; + }while(--extraIeLen > 0); + + return status; +} + +tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, + tANI_U8 *pFrame, tANI_U32 maxBeaconSize, + tANI_U32 *nBytes) +{ + tSirRetStatus status = eSIR_FAILURE; + tANI_U32 present, len; + tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN]; + + if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, + &present)) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG")); + return status; + } + + if(present) + { + if((status = wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, + &len)) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, + FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA length")); + return status; + } + + if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && + ((len + *nBytes) <= maxBeaconSize)) + { + if((status = wlan_cfgGetStr(pMac, + WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len)) + == eSIR_SUCCESS) + { + tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], len); + if(pP2pIe != NULL) + { + tANI_U8 noaLen = 0; + tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN]; + //get NoA attribute stream P2P IE + noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry); + if(noaLen) + { + if ( (noaLen + len) <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN ) + { + vos_mem_copy(&addIE[len], noaStream, noaLen); + len += noaLen; + /* Update IE Len */ + pP2pIe[1] += noaLen; + schLog(pMac, LOG1, + FL("NoA length is %d"),noaLen); + } + else + { + schLog(pMac, LOGE, + FL("Not able to insert NoA because of length constraint")); + } + } + } + vos_mem_copy(pFrame, &addIE[0], len); + *nBytes = *nBytes + len; + schLog(pMac, LOG1, + FL("Total beacon size is %d"), *nBytes); + } + } + } + + return status; +} + +// -------------------------------------------------------------------- +/** + * schSetFixedBeaconFields + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tpAniBeaconStruct pBeacon = (tpAniBeaconStruct) + pMac->sch.schObject.gSchBeaconFrameBegin; + tpSirMacMgmtHdr mac; + tANI_U16 offset; + tANI_U8 *ptr; + tDot11fBeacon1 *pBcn1; + tDot11fBeacon2 *pBcn2; + tANI_U32 i, nStatus, nBytes; + tANI_U32 wpsApEnable=0, tmp; + tDot11fIEWscProbeRes *pWscProbeRes; + tANI_U8 *pExtraIe = NULL; + tANI_U32 extraIeLen =0; + tANI_U16 extraIeOffset = 0; + tANI_U16 p2pIeOffset = 0; + tSirRetStatus status = eSIR_SUCCESS; + + pBcn1 = vos_mem_malloc(sizeof(tDot11fBeacon1)); + if ( NULL == pBcn1 ) + { + schLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + + pBcn2 = vos_mem_malloc(sizeof(tDot11fBeacon2)); + if ( NULL == pBcn2 ) + { + schLog(pMac, LOGE, FL("Failed to allocate memory") ); + vos_mem_free(pBcn1); + return eSIR_FAILURE; + } + + pWscProbeRes = vos_mem_malloc(sizeof(tDot11fIEWscProbeRes)); + if ( NULL == pWscProbeRes ) + { + schLog(pMac, LOGE, FL("Failed to allocate memory") ); + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + return eSIR_FAILURE; + } + + PELOG1(schLog(pMac, LOG1, FL("Setting fixed beacon fields"));) + + /* + * First set the fixed fields + */ + + // set the TFP headers + + // set the mac header + vos_mem_set(( tANI_U8*) &pBeacon->macHdr, sizeof( tSirMacMgmtHdr ),0); + mac = (tpSirMacMgmtHdr) &pBeacon->macHdr; + mac->fc.type = SIR_MAC_MGMT_FRAME; + mac->fc.subType = SIR_MAC_MGMT_BEACON; + + for (i=0; i<6; i++) + mac->da[i] = 0xff; + + /* Knocking out Global pMac update */ + /* limGetMyMacAddr(pMac, mac->sa); */ + /* limGetBssid(pMac, mac->bssId); */ + + vos_mem_copy(mac->sa, psessionEntry->selfMacAddr, sizeof(psessionEntry->selfMacAddr)); + vos_mem_copy(mac->bssId, psessionEntry->bssId, sizeof (psessionEntry->bssId)); + + mac->fc.fromDS = 0; + mac->fc.toDS = 0; + + /* + * Now set the beacon body + */ + + vos_mem_set(( tANI_U8*) pBcn1, sizeof( tDot11fBeacon1 ), 0); + + // Skip over the timestamp (it'll be updated later). + + pBcn1->BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval; + PopulateDot11fCapabilities( pMac, &pBcn1->Capabilities, psessionEntry ); + if (psessionEntry->ssidHidden) + { + pBcn1->SSID.present = 1; //rest of the fileds are 0 for hidden ssid + } + else + { + PopulateDot11fSSID( pMac, &psessionEntry->ssId, &pBcn1->SSID ); + } + + + PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &pBcn1->SuppRates,psessionEntry); + PopulateDot11fDSParams( pMac, &pBcn1->DSParams, psessionEntry->currentOperChannel, psessionEntry); + PopulateDot11fIBSSParams( pMac, &pBcn1->IBSSParams,psessionEntry); + + offset = sizeof( tAniBeaconStruct ); + ptr = pMac->sch.schObject.gSchBeaconFrameBegin + offset; + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) + && ((psessionEntry->proxyProbeRspEn) + || (IS_FEATURE_SUPPORTED_BY_FW(WPS_PRBRSP_TMPL))) + && vos_is_probe_rsp_offload_enabled() + ) + { + /* Initialize the default IE bitmap to zero */ + vos_mem_set(( tANI_U8* )&(psessionEntry->DefProbeRspIeBitmap), (sizeof( tANI_U32 ) * 8), 0); + + /* Initialize the default IE bitmap to zero */ + vos_mem_set(( tANI_U8* )&(psessionEntry->probeRespFrame), + sizeof(psessionEntry->probeRespFrame), 0); + + /* Can be efficiently updated whenever new IE added + * in Probe response in future + */ + if (limUpdateProbeRspTemplateIeBitmapBeacon1(pMac, pBcn1, + psessionEntry) != eSIR_SUCCESS) + { + schLog(pMac, LOGE, + FL("Failed to build ProbeRsp template")); + } + } + + nStatus = dot11fPackBeacon1( pMac, pBcn1, ptr, + SCH_MAX_BEACON_SIZE - offset, + &nBytes ); + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon1 (0x%0" + "8x.)."), nStatus ); + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + vos_mem_free(pWscProbeRes); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while packing a tDo" + "t11fBeacon1 (0x%08x.)."), nStatus ); + } + /*changed to correct beacon corruption */ + vos_mem_set(( tANI_U8*) pBcn2, sizeof( tDot11fBeacon2 ), 0); + pMac->sch.schObject.gSchBeaconOffsetBegin = offset + ( tANI_U16 )nBytes; + schLog( pMac, LOG1, FL("Initialized beacon begin, offset %d"), offset ); + + /* + * Initialize the 'new' fields at the end of the beacon + */ + + + PopulateDot11fCountry( pMac, &pBcn2->Country, psessionEntry); + if(pBcn1->Capabilities.qos) + { + PopulateDot11fEDCAParamSet( pMac, &pBcn2->EDCAParamSet, psessionEntry); + } + + if(psessionEntry->lim11hEnable) + { + PopulateDot11fPowerConstraints( pMac, &pBcn2->PowerConstraints ); + PopulateDot11fTPCReport( pMac, &pBcn2->TPCReport, psessionEntry); + } + + + if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B) + PopulateDot11fERPInfo( pMac, &pBcn2->ERPInfo, psessionEntry ); + + if(psessionEntry->htCapability) + { + PopulateDot11fHTCaps( pMac,psessionEntry, &pBcn2->HTCaps ); + PopulateDot11fHTInfo( pMac, &pBcn2->HTInfo, psessionEntry ); + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if ((pMac->roam.configParam.apHT40_24GEnabled) + && (IS_DOT11_MODE_HT(psessionEntry->dot11mode))) + { + PopulateDot11fOBSSScanParameters( pMac, &pBcn2->OBSSScanParameters, + psessionEntry); + /* 10.15.8 Support of DSSS/CCK in 40 MHz, An associated HT STA in + * a 20/40 MHz BSS may generate DSSS/CCK transmissions. Set DSSS/CCK + * Mode in 40 MHz bit in HT capablity. + */ + pBcn2->HTCaps.dsssCckMode40MHz = 1; + } +#endif + + PopulateDot11fExtCap( pMac, &pBcn2->ExtCap, psessionEntry); + +#ifdef WLAN_FEATURE_11AC + if(psessionEntry->vhtCapability) + { + schLog( pMac, LOGW, FL("Populate VHT IEs in Beacon")); + PopulateDot11fVHTCaps( pMac, &pBcn2->VHTCaps, + psessionEntry->currentOperChannel, eSIR_TRUE ); + PopulateDot11fVHTOperation( pMac, &pBcn2->VHTOperation, + psessionEntry->currentOperChannel); + // we do not support multi users yet + //PopulateDot11fVHTExtBssLoad( pMac, &bcn2.VHTExtBssLoad); + if(psessionEntry->gLimOperatingMode.present) + PopulateDot11fOperatingMode( pMac, &pBcn2->OperatingMode, psessionEntry ); + } +#endif + + PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, + &pBcn2->ExtSuppRates, psessionEntry ); + + if( psessionEntry->pLimStartBssReq != NULL ) + { + PopulateDot11fWPA( pMac, &psessionEntry->pLimStartBssReq->rsnIE, + &pBcn2->WPA ); + PopulateDot11fRSNOpaque( pMac, &psessionEntry->pLimStartBssReq->rsnIE, + &pBcn2->RSNOpaque ); +#ifdef SAP_AUTH_OFFLOAD + /* Software AP Authentication Offload feature + * only support WPA2-PSK AES and we + * need to update RSNIE for beacon + */ + sap_auth_offload_update_rsn_ie(pMac, &pBcn2->RSNOpaque); +#endif + } + + if(psessionEntry->limWmeEnabled) + { + PopulateDot11fWMM( pMac, &pBcn2->WMMInfoAp, &pBcn2->WMMParams, &pBcn2->WMMCaps, psessionEntry); + } + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if(psessionEntry->wps_state != SAP_WPS_DISABLED) + { + PopulateDot11fBeaconWPSIEs( pMac, &pBcn2->WscBeacon, psessionEntry); + } + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS) + schLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_ENABLE ); + + wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP; + + if (wpsApEnable) + { + PopulateDot11fWsc(pMac, &pBcn2->WscBeacon); + } + + if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_BEGIN) + { + PopulateDot11fWscRegistrarInfo(pMac, &pBcn2->WscBeacon); + pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS; + } + + if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END) + { + DePopulateDot11fWscRegistrarInfo(pMac, &pBcn2->WscBeacon); + pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_NOOP; + } + } + + if((psessionEntry->limSystemRole == eLIM_AP_ROLE) + && ((psessionEntry->proxyProbeRspEn) + || (IS_FEATURE_SUPPORTED_BY_FW(WPS_PRBRSP_TMPL))) + && vos_is_probe_rsp_offload_enabled() + ) + { + /* Can be efficiently updated whenever new IE added in Probe response in future */ + limUpdateProbeRspTemplateIeBitmapBeacon2(pMac,pBcn2,&psessionEntry->DefProbeRspIeBitmap[0], + &psessionEntry->probeRespFrame); + + /* update probe response WPS IE instead of beacon WPS IE + * */ + if(psessionEntry->wps_state != SAP_WPS_DISABLED) + { + if(psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent) + { + PopulateDot11fProbeResWPSIEs(pMac, pWscProbeRes, psessionEntry); + } + else + { + pWscProbeRes->present = 0; + } + if(pWscProbeRes->present) + { + SetProbeRspIeBitmap(&psessionEntry->DefProbeRspIeBitmap[0],SIR_MAC_WPA_EID); + vos_mem_copy((void *)&psessionEntry->probeRespFrame.WscProbeRes, + (void *)pWscProbeRes, + sizeof(tDot11fIEWscProbeRes)); + } + } + + } + + nStatus = dot11fPackBeacon2( pMac, pBcn2, + pMac->sch.schObject.gSchBeaconFrameEnd, + SCH_MAX_BEACON_SIZE, &nBytes ); + if ( DOT11F_FAILED( nStatus ) ) + { + schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon2 (0x%0" + "8x.)."), nStatus ); + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + vos_mem_free(pWscProbeRes); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + schLog( pMac, LOGE, FL("There were warnings while packing a tDo" + "t11fBeacon2 (0x%08x.)."), nStatus ); + } + + pExtraIe = pMac->sch.schObject.gSchBeaconFrameEnd + nBytes; + extraIeOffset = nBytes; + + //TODO: Append additional IE here. + schAppendAddnIE(pMac, psessionEntry, + pMac->sch.schObject.gSchBeaconFrameEnd + nBytes, + SCH_MAX_BEACON_SIZE, &nBytes); + + pMac->sch.schObject.gSchBeaconOffsetEnd = ( tANI_U16 )nBytes; + + extraIeLen = nBytes - extraIeOffset; + + //Get the p2p Ie Offset + status = schGetP2pIeOffset(pExtraIe, extraIeLen, &p2pIeOffset); + + if(eSIR_SUCCESS == status) + { + //Update the P2P Ie Offset + pMac->sch.schObject.p2pIeOffset = + pMac->sch.schObject.gSchBeaconOffsetBegin + TIM_IE_SIZE + + extraIeOffset + p2pIeOffset; + } + else + { + pMac->sch.schObject.p2pIeOffset = 0; + } + + schLog( pMac, LOG1, FL("Initialized beacon end, offset %d"), + pMac->sch.schObject.gSchBeaconOffsetEnd ); + + pMac->sch.schObject.fBeaconChanged = 1; + vos_mem_free(pBcn1); + vos_mem_free(pBcn2); + vos_mem_free(pWscProbeRes); + return eSIR_SUCCESS; +} + +tSirRetStatus limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal pMac, + tDot11fBeacon1* beacon1, + tpPESession psessionEntry) +{ + tANI_U32* DefProbeRspIeBitmap; + tDot11fProbeResponse* prb_rsp; + + if (!psessionEntry) { + schLog(pMac, LOGE, FL("PESession is null!")); + return eSIR_FAILURE; + } + + DefProbeRspIeBitmap = &psessionEntry->DefProbeRspIeBitmap[0]; + prb_rsp = &psessionEntry->probeRespFrame; + + prb_rsp->BeaconInterval = beacon1->BeaconInterval; + vos_mem_copy((void *)&prb_rsp->Capabilities, (void *)&beacon1->Capabilities, + sizeof(beacon1->Capabilities)); + + /* SSID */ + if(beacon1->SSID.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_SSID_EID); + /* populating it, because probe response has to go with + * SSID even in hidden case + */ + PopulateDot11fSSID(pMac, &psessionEntry->ssId, &prb_rsp->SSID); + } + /* supported rates */ + if(beacon1->SuppRates.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RATESET_EID); + vos_mem_copy((void *)&prb_rsp->SuppRates, (void *)&beacon1->SuppRates, + sizeof(beacon1->SuppRates)); + + } + /* DS Parameter set */ + if(beacon1->DSParams.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_DS_PARAM_SET_EID); + vos_mem_copy((void *)&prb_rsp->DSParams, (void *)&beacon1->DSParams, + sizeof(beacon1->DSParams)); + + } + + /* IBSS params will not be present in the Beacons transmitted by AP */ + + return eSIR_SUCCESS; +} + +void limUpdateProbeRspTemplateIeBitmapBeacon2(tpAniSirGlobal pMac, + tDot11fBeacon2* beacon2, + tANI_U32* DefProbeRspIeBitmap, + tDot11fProbeResponse* prb_rsp) +{ + /* IBSS parameter set - will not be present in probe response tx by AP */ + /* country */ + if(beacon2->Country.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_COUNTRY_EID); + vos_mem_copy((void *)&prb_rsp->Country, (void *)&beacon2->Country, + sizeof(beacon2->Country)); + + } + /* Power constraint */ + if(beacon2->PowerConstraints.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_PWR_CONSTRAINT_EID); + vos_mem_copy((void *)&prb_rsp->PowerConstraints, (void *)&beacon2->PowerConstraints, + sizeof(beacon2->PowerConstraints)); + + } + /* Channel Switch Annoouncement SIR_MAC_CHNL_SWITCH_ANN_EID */ + if(beacon2->ChanSwitchAnn.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_CHNL_SWITCH_ANN_EID); + vos_mem_copy((void *)&prb_rsp->ChanSwitchAnn, (void *)&beacon2->ChanSwitchAnn, + sizeof(beacon2->ChanSwitchAnn)); + + } + /* ERP information */ + if(beacon2->ERPInfo.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_ERP_INFO_EID); + vos_mem_copy((void *)&prb_rsp->ERPInfo, (void *)&beacon2->ERPInfo, + sizeof(beacon2->ERPInfo)); + + } + /* Extended supported rates */ + if(beacon2->ExtSuppRates.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EXTENDED_RATE_EID); + vos_mem_copy((void *)&prb_rsp->ExtSuppRates, (void *)&beacon2->ExtSuppRates, + sizeof(beacon2->ExtSuppRates)); + + } + + /* WPA */ + if(beacon2->WPA.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID); + vos_mem_copy((void *)&prb_rsp->WPA, (void *)&beacon2->WPA, + sizeof(beacon2->WPA)); + + } + + /* RSN */ + if(beacon2->RSNOpaque.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RSN_EID); + vos_mem_copy((void *)&prb_rsp->RSNOpaque, (void *)&beacon2->RSNOpaque, + sizeof(beacon2->RSNOpaque)); + } +/* + // BSS load + if(beacon2->QBSSLoad.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_QBSS_LOAD_EID); + } +*/ + /* EDCA Parameter set */ + if(beacon2->EDCAParamSet.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EDCA_PARAM_SET_EID); + vos_mem_copy((void *)&prb_rsp->EDCAParamSet, (void *)&beacon2->EDCAParamSet, + sizeof(beacon2->EDCAParamSet)); + + } + /* Vendor specific - currently no vendor specific IEs added */ + /* Requested IEs - currently we are not processing this will be added later */ + //HT capability IE + if(beacon2->HTCaps.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_CAPABILITIES_EID); + vos_mem_copy((void *)&prb_rsp->HTCaps, (void *)&beacon2->HTCaps, + sizeof(beacon2->HTCaps)); + } + // HT Info IE + if(beacon2->HTInfo.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_INFO_EID); + vos_mem_copy((void *)&prb_rsp->HTInfo, (void *)&beacon2->HTInfo, + sizeof(beacon2->HTInfo)); + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + // Overlapping BSS Scan Parameters IE + if (pMac->roam.configParam.apHT40_24GEnabled) + { + if (beacon2->OBSSScanParameters.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap, + SIR_MAC_OBSS_SCAN_PARAMETERS_EID); + vos_mem_copy((void *)&prb_rsp->OBSSScanParameters, + (void *)&beacon2->OBSSScanParameters, + sizeof(beacon2->OBSSScanParameters)); + } + + if (beacon2->ExtCap.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap, + SIR_MAC_EXTENDED_CAPABILITIES_EID); + vos_mem_copy((void *)&prb_rsp->ExtCap, + (void *)&beacon2->ExtCap, + sizeof(beacon2->ExtCap)); + + } + } +#endif + +#ifdef WLAN_FEATURE_11AC + if(beacon2->VHTCaps.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_CAPABILITIES_EID); + vos_mem_copy((void *)&prb_rsp->VHTCaps, (void *)&beacon2->VHTCaps, + sizeof(beacon2->VHTCaps)); + } + if(beacon2->VHTOperation.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_OPERATION_EID); + vos_mem_copy((void *)&prb_rsp->VHTOperation, (void *)&beacon2->VHTOperation, + sizeof(beacon2->VHTOperation)); + } + if(beacon2->VHTExtBssLoad.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_EXT_BSS_LOAD_EID); + vos_mem_copy((void *)&prb_rsp->VHTExtBssLoad, (void *)&beacon2->VHTExtBssLoad, + sizeof(beacon2->VHTExtBssLoad)); + } +#endif + + //WMM IE + if(beacon2->WMMParams.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID); + vos_mem_copy((void *)&prb_rsp->WMMParams, (void *)&beacon2->WMMParams, + sizeof(beacon2->WMMParams)); + } + //WMM capability - most of the case won't be present + if(beacon2->WMMCaps.present) + { + SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID); + vos_mem_copy((void *)&prb_rsp->WMMCaps, (void *)&beacon2->WMMCaps, + sizeof(beacon2->WMMCaps)); + } + +} + +void SetProbeRspIeBitmap(tANI_U32* IeBitmap,tANI_U32 pos) +{ + tANI_U32 index,temp; + + index = pos >> 5; + if(index >= 8 ) + { + return; + } + temp = IeBitmap[index]; + + temp |= 1 << (pos & 0x1F); + + IeBitmap[index] = temp; +} + + + +// -------------------------------------------------------------------- +/** + * writeBeaconToMemory + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @param size Size of the beacon to write to memory + * @param length Length field of the beacon to write to memory + * @return None + */ + +void writeBeaconToMemory(tpAniSirGlobal pMac, tANI_U16 size, tANI_U16 length, tpPESession psessionEntry) +{ + tANI_U16 i; + tpAniBeaconStruct pBeacon; + + // copy end of beacon only if length > 0 + if (length > 0) + { + for (i=0; i < pMac->sch.schObject.gSchBeaconOffsetEnd; i++) + pMac->sch.schObject.gSchBeaconFrameBegin[size++] = pMac->sch.schObject.gSchBeaconFrameEnd[i]; + } + + // Update the beacon length + pBeacon = (tpAniBeaconStruct) pMac->sch.schObject.gSchBeaconFrameBegin; + // Do not include the beaconLength indicator itself + if (length == 0) + { + pBeacon->beaconLength = 0; + // Dont copy entire beacon, Copy length field alone + size = 4; + } + else + pBeacon->beaconLength = (tANI_U32) size - sizeof( tANI_U32 ); + + // write size bytes from gSchBeaconFrameBegin + PELOG2(schLog(pMac, LOG2, FL("Beacon size - %d bytes"), size);) + PELOG2(sirDumpBuf(pMac, SIR_SCH_MODULE_ID, LOG2, pMac->sch.schObject.gSchBeaconFrameBegin, size);) + + if (! pMac->sch.schObject.fBeaconChanged) + return; + + pMac->sch.gSchGenBeacon = 1; + if (pMac->sch.gSchGenBeacon) + { + pMac->sch.gSchBeaconsSent++; + + // + // Copy beacon data to SoftMAC shared memory... + // Do this by sending a message to HAL + // + + size = (size + 3) & (~3); + if( eSIR_SUCCESS != schSendBeaconReq( pMac, pMac->sch.schObject.gSchBeaconFrameBegin, + size, psessionEntry)) + PELOGE(schLog(pMac, LOGE, FL("schSendBeaconReq() returned an error (zsize %d)"), size);) + else + { + pMac->sch.gSchBeaconsWritten++; + } + } + pMac->sch.schObject.fBeaconChanged = 0; +} + +// -------------------------------------------------------------------- +/** + * @function: SchProcessPreBeaconInd + * + * @brief : Process the PreBeacon Indication from the Lim + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param : pMac - tpAniSirGlobal + * + * @return None + */ + +void +schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg) +{ + tpBeaconGenParams pMsg = (tpBeaconGenParams)limMsg->bodyptr; + tANI_U32 beaconSize = pMac->sch.schObject.gSchBeaconOffsetBegin; + tpPESession psessionEntry; + tANI_U8 sessionId; + + if((psessionEntry = peFindSessionByBssid(pMac,pMsg->bssId, &sessionId))== NULL) + { + PELOGE(schLog(pMac, LOGE, FL("session lookup fails"));) + goto end; + } + + + + // If SME is not in normal mode, no need to generate beacon + if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE) + { + PELOGE(schLog(pMac, LOG1, FL("PreBeaconInd received in invalid state: %d"), psessionEntry->limSmeState);) + goto end; + } + + switch(psessionEntry->limSystemRole){ + + case eLIM_STA_IN_IBSS_ROLE: + case eLIM_BT_AMP_AP_ROLE: + case eLIM_BT_AMP_STA_ROLE: + // generate IBSS parameter set + if(psessionEntry->statypeForBss == STA_ENTRY_SELF) + writeBeaconToMemory(pMac, (tANI_U16) beaconSize, (tANI_U16)beaconSize, psessionEntry); + else + PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry"));) + break; + + case eLIM_AP_ROLE:{ + tANI_U8 *ptr = &pMac->sch.schObject.gSchBeaconFrameBegin[pMac->sch.schObject.gSchBeaconOffsetBegin]; + tANI_U16 timLength = 0; + if(psessionEntry->statypeForBss == STA_ENTRY_SELF){ + pmmGenerateTIM(pMac, &ptr, &timLength, psessionEntry->dtimPeriod); + beaconSize += 2 + timLength; + writeBeaconToMemory(pMac, (tANI_U16) beaconSize, (tANI_U16)beaconSize, psessionEntry); + } + else + PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry"));) + } + break; + + + default: + PELOGE(schLog(pMac, LOGE, FL("Error-PE has Receive PreBeconGenIndication when System is in %d role"), + psessionEntry->limSystemRole);) + } + +end: + vos_mem_free(pMsg); + +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c new file mode 100644 index 000000000000..7152d3be9625 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file schBeaconProcess.cc contains beacon processing related + * functions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "palTypes.h" +#include "wniCfg.h" + +#include "cfgApi.h" +#include "pmmApi.h" +#include "limApi.h" +#include "utilsApi.h" +#include "schDebug.h" +#include "schApi.h" + + +#include "limUtils.h" +#include "limSendMessages.h" +#include "limStaHashApi.h" + +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif //FEATURE_WLAN_DIAG_SUPPORT + +/** + * Number of bytes of variation in beacon length from the last beacon + * to trigger reprogramming of rx delay register + */ +#define SCH_BEACON_LEN_DELTA 3 + +// calculate 2^cw - 1 +#define CW_GET(cw) (((cw) == 0) ? 1 : ((1 << (cw)) - 1)) + +static void +ap_beacon_process( + tpAniSirGlobal pMac, + tANI_U8* pRxPacketInfo, + tpSchBeaconStruct pBcnStruct, + tpUpdateBeaconParams pBeaconParams, + tpPESession psessionEntry) +{ + tpSirMacMgmtHdr pMh = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + tANI_U32 phyMode; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + //Get RF band from psessionEntry + rfBand = psessionEntry->limRFBand; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + if(SIR_BAND_5_GHZ == rfBand) + { + if (psessionEntry->htCapability) + { + if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel) + { + //11a (non HT) AP overlaps or + //HT AP with HT op mode as mixed overlaps. + //HT AP with HT op mode as overlap legacy overlaps. + if ((!pBcnStruct->HTInfo.present) || + (eSIR_HT_OP_MODE_MIXED == pBcnStruct->HTInfo.opMode) || + (eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBcnStruct->HTInfo.opMode)) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(pMac->lim.gLimOverlap11aParams)); + + if (pMac->lim.gLimOverlap11aParams.numSta && + !pMac->lim.gLimOverlap11aParams.protectionEnabled) + { + limEnable11aProtection(pMac, true, true, pBeaconParams,psessionEntry); + } + } + //HT AP with HT20 op mode overlaps. + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBcnStruct->HTInfo.opMode) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(pMac->lim.gLimOverlapHt20Params)); + + if (pMac->lim.gLimOverlapHt20Params.numSta && + !pMac->lim.gLimOverlapHt20Params.protectionEnabled) + { + limEnableHT20Protection(pMac, true, true, pBeaconParams,psessionEntry); + } + } + } + } + } + else if(SIR_BAND_2_4_GHZ == rfBand) + { + //We are 11G AP. + if ((phyMode == WNI_CFG_PHY_MODE_11G) && + (false == psessionEntry->htCapability)) + { + if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel) + { + if (((!(pBcnStruct->erpPresent)) && + !(pBcnStruct->HTInfo.present))|| + //if erp not present then 11B AP overlapping + (!pMac->roam.configParam.ignorePeerErpInfo && + pBcnStruct->erpPresent && + (pBcnStruct->erpIEInfo.useProtection || + pBcnStruct->erpIEInfo.nonErpPresent))) + { +#ifdef FEATURE_WLAN_ESE + if( psessionEntry->isESEconnection ) + { + VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d", __func__, + pBcnStruct->erpPresent, + pBcnStruct->erpIEInfo.useProtection, + pBcnStruct->erpIEInfo.nonErpPresent); + } +#endif + limEnableOverlap11gProtection(pMac, pBeaconParams, pMh,psessionEntry); + } + + } + } + // handling the case when HT AP has overlapping legacy BSS. + else if(psessionEntry->htCapability) + { + if (pBcnStruct->channelNumber == psessionEntry->currentOperChannel) + { + if (((!(pBcnStruct->erpPresent)) && + !(pBcnStruct->HTInfo.present))|| + //if erp not present then 11B AP overlapping + (!pMac->roam.configParam.ignorePeerErpInfo && + pBcnStruct->erpPresent && + (pBcnStruct->erpIEInfo.useProtection || + pBcnStruct->erpIEInfo.nonErpPresent))) + { +#ifdef FEATURE_WLAN_ESE + if( psessionEntry->isESEconnection ) + { + VOS_TRACE (VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]ESE 11g erpPresent=%d useProtection=%d nonErpPresent=%d", __func__, + pBcnStruct->erpPresent, + pBcnStruct->erpIEInfo.useProtection, + pBcnStruct->erpIEInfo.nonErpPresent); + } +#endif + limEnableOverlap11gProtection(pMac, pBeaconParams, pMh,psessionEntry); + } + + //11g device overlaps + if (pBcnStruct->erpPresent && + !(pBcnStruct->erpIEInfo.useProtection || + pBcnStruct->erpIEInfo.nonErpPresent) && !(pBcnStruct->HTInfo.present)) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlap11gParams)); + + if (psessionEntry->gLimOverlap11gParams.numSta && + !psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + limEnableHtProtectionFrom11g(pMac, true, true, pBeaconParams,psessionEntry); + } + } + + //ht device overlaps. + //here we will check for HT related devices only which might need protection. + //check for 11b and 11g is already done in the previous blocks. + //so we will not check for HT operating mode as MIXED. + if (pBcnStruct->HTInfo.present) + { + //if we are not already in mixed mode or legacy mode as HT operating mode + //and received beacon has HT operating mode as legacy + //then we need to enable protection from 11g station. + //we don't need protection from 11b because if that's needed then our operating + //mode would have already been set to legacy in the previous blocks. + if(eSIR_HT_OP_MODE_OVERLAP_LEGACY == pBcnStruct->HTInfo.opMode + && !pMac->roam.configParam.ignorePeerHTopMode) + { + if((eSIR_HT_OP_MODE_MIXED != pMac->lim.gHTOperMode) && + (eSIR_HT_OP_MODE_OVERLAP_LEGACY != pMac->lim.gHTOperMode)) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlap11gParams)); + if (psessionEntry->gLimOverlap11gParams.numSta && + !psessionEntry->gLimOverlap11gParams.protectionEnabled) + { + limEnableHtProtectionFrom11g(pMac, true, true, pBeaconParams,psessionEntry); + } + } + } + else if(eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT == pBcnStruct->HTInfo.opMode) + { + limUpdateOverlapStaParam(pMac, pMh->bssId, &(psessionEntry->gLimOverlapHt20Params)); + if (psessionEntry->gLimOverlapHt20Params.numSta && + !psessionEntry->gLimOverlapHt20Params.protectionEnabled) + { + limEnableHT20Protection(pMac, true, true, pBeaconParams,psessionEntry); + } + } + } + + } + } + } + pMac->sch.gSchBcnIgnored++; +} +// -------------------------------------------------------------------- + + + + +/** + * __schBeaconProcessNoSession + * + * FUNCTION: + * Process the received beacon frame when + * -- Station is not scanning + * -- No corresponding session is found + * + * LOGIC: + * Following scenarios exist when Session Does not exist: + * * IBSS Beacons, when IBSS session already exists with same SSID, + * but from STA which has not yet joined and has a different BSSID. + * - invoke limHandleIBSScoalescing with the session context of existing IBSS session. + * + * * IBSS Beacons when IBSS session does not exist, only Infra or BT-AMP session exists, + * then save the beacon in the scan results and throw it away. + * + * * Infra Beacons + * - beacons received when no session active + * should not come here, it should be handled as part of scanning, + * else they should not be getting received, should update scan results and drop it if that happens. + * - beacons received when IBSS session active: + * update scan results and drop it. + * - beacons received when Infra session(STA) is active: + * update scan results and drop it + * - beacons received when BT-STA session is active: + * update scan results and drop it. + * - beacons received when Infra/BT-STA or Infra/IBSS is active. + * update scan results and drop it. + * + + */ +static void __schBeaconProcessNoSession(tpAniSirGlobal pMac, tpSchBeaconStruct pBeacon,tANI_U8* pRxPacketInfo) +{ + tpPESession psessionEntry = NULL; + + if( (psessionEntry = limIsIBSSSessionActive(pMac)) != NULL) + { + limHandleIBSScoalescing(pMac, pBeacon, pRxPacketInfo, psessionEntry); + } + + //If station(STA/BT-STA/BT-AP/IBSS) mode, Always save the beacon in the scan results, if atleast one session is active + //schBeaconProcessNoSession will be called only when there is atleast one session active, so not checking + //it again here. + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + return; +} + + + +/* + * __schBeaconProcessForSession + * + * FUNCTION: + * Process the received beacon frame when + * -- Station is not scanning + * -- Corresponding session is found + * + * LOGIC: + * Following scenarios exist when Session exists + * * IBSS STA receving beacons from IBSS Peers, who are part of IBSS. + * - call limHandleIBSScoalescing with that session context. + * * Infra STA receving beacons from AP to which it is connected + * - call schBeaconProcessFromAP with that session's context. + * * BTAMP STA receving beacons from BTAMP AP + * - call schBeaconProcessFromAP with that session's context. + * * BTAMP AP receiving beacons from BTAMP STA + * (here need to make sure BTAP creates session entry for BT STA) + * - just update the beacon count for heart beat purposes for now, + * for now, don't process the beacon. + * * Infra/IBSS both active and receives IBSS beacon: + * - call limHandleIBSScoalescing with that session context. + * * Infra/IBSS both active and receives Infra beacon: + * - call schBeaconProcessFromAP with that session's context. + * any updates to EDCA parameters will be effective for IBSS as well, + * even though no WMM for IBSS ?? Need to figure out how to handle this scenario. + * * Infra/BTSTA both active and receive Infra beacon. + * - change in EDCA parameters on Infra affect the BTSTA link. + * Update the same parameters on BT link + * * Infra/BTSTA both active and receive BT-AP beacon. + * -update beacon cnt for heartbeat + * * Infra/BTAP both active and receive Infra beacon. + * - BT-AP starts advertising BE parameters from Infra AP, if they get changed. + * + * * Infra/BTAP both active and receive BTSTA beacon. + * - update beacon cnt for heartbeat + */ + +static void __schBeaconProcessForSession( tpAniSirGlobal pMac, + tpSchBeaconStruct pBeacon, + tANI_U8* pRxPacketInfo, + tpPESession psessionEntry) +{ + tANI_U32 bi; + tANI_U8 bssIdx = 0; + //tpSirMacMgmtHdr pMh = SIR_MAC_BD_TO_MPDUHEADER(pRxPacketInfo); + //tANI_U8 bssid[sizeof(tSirMacAddr)]; + tUpdateBeaconParams beaconParams; + tANI_U8 sendProbeReq = FALSE; + tpDphHashNode pStaDs = NULL; + tANI_U32 channelBondingMode = 0; +#ifdef WLAN_FEATURE_11AC + tpSirMacMgmtHdr pMh = WDA_GET_RX_MAC_HEADER(pRxPacketInfo); + tANI_U16 aid; + tANI_U8 operMode; + tANI_U8 chWidth = 0; +#endif +#if defined FEATURE_WLAN_ESE || defined WLAN_FEATURE_VOWIFI + tPowerdBm regMax = 0,maxTxPower = 0; +#endif + + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + beaconParams.paramChangeBitmap = 0; + + if(eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + if( limHandleIBSScoalescing(pMac, pBeacon, pRxPacketInfo, psessionEntry) + != eSIR_SUCCESS ) + return; + } + else if( (eLIM_STA_ROLE == psessionEntry->limSystemRole) || + (eLIM_BT_AMP_STA_ROLE == psessionEntry->limSystemRole)) + { + /* + * This handles two cases: + * -- Infra STA receving beacons from AP + * -- BTAMP_STA receving beacons from BTAMP_AP + */ + //Always save the beacon into LIM's cached scan results + limCheckAndAddBssDescription(pMac, pBeacon, pRxPacketInfo, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + + /** + * This is the Beacon received from the AP we're currently associated with. Check + * if there are any changes in AP's capabilities + */ + if((tANI_U8) pBeacon->channelNumber != psessionEntry->currentOperChannel) + { + PELOGE(schLog(pMac, LOGE, FL("Channel Change from %d --> %d - " + "Ignoring beacon!"), + psessionEntry->currentOperChannel, pBeacon->channelNumber);) + goto fail; + } + + if(RF_CHAN_14 >= psessionEntry->currentOperChannel) + { + if (psessionEntry->force_24ghz_in_ht20) + channelBondingMode = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + else + channelBondingMode = + pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + channelBondingMode = pMac->roam.configParam.channelBondingMode5GHz; + } + + limDetectChangeInApCapabilities(pMac, pBeacon, psessionEntry); + if(limGetStaHashBssidx(pMac, DPH_STA_HASH_INDEX_PEER, &bssIdx, psessionEntry) != eSIR_SUCCESS) + goto fail; + beaconParams.bssIdx = bssIdx; + vos_mem_copy(( tANI_U8* )&psessionEntry->lastBeaconTimeStamp, + ( tANI_U8* )pBeacon->timeStamp, sizeof(tANI_U64)); + psessionEntry->lastBeaconDtimCount = pBeacon->tim.dtimCount; + psessionEntry->lastBeaconDtimPeriod= pBeacon->tim.dtimPeriod; + psessionEntry->currentBssBeaconCnt++; + + + + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, psessionEntry->peSessionId, pBeacon->timeStamp[0]);) + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_TSF, psessionEntry->peSessionId, pBeacon->timeStamp[1]);) + + /* Read beacon interval session Entry */ + bi = psessionEntry->beaconParams.beaconInterval; + if (bi != pBeacon->beaconInterval) + { + schLog(pMac, LOG1, FL("Beacon interval changed from %d to %d"), + pBeacon->beaconInterval, bi); + + bi = pBeacon->beaconInterval; + psessionEntry->beaconParams.beaconInterval = (tANI_U16) bi; + beaconParams.paramChangeBitmap |= PARAM_BCN_INTERVAL_CHANGED; + beaconParams.beaconInterval = (tANI_U16)bi; + } + + if (pBeacon->cfPresent) + { + cfgSetInt(pMac, WNI_CFG_CFP_PERIOD, pBeacon->cfParamSet.cfpPeriod); + limSendCFParams(pMac, bssIdx, pBeacon->cfParamSet.cfpCount, pBeacon->cfParamSet.cfpPeriod); + } + + if (pBeacon->timPresent) + { + cfgSetInt(pMac, WNI_CFG_DTIM_PERIOD, pBeacon->tim.dtimPeriod); + //No need to send DTIM Period and Count to HAL/SMAC + //SMAC already parses TIM bit. + } + + if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + + limDecideStaProtection(pMac, pBeacon, &beaconParams, psessionEntry); + if (pBeacon->erpPresent) + { + if (pBeacon->erpIEInfo.barkerPreambleMode) + limEnableShortPreamble(pMac, false, &beaconParams, psessionEntry); + else + limEnableShortPreamble(pMac, true, &beaconParams, psessionEntry); + } + limUpdateShortSlot(pMac, pBeacon, &beaconParams,psessionEntry); + + pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); + if ((pBeacon->wmeEdcaPresent && (psessionEntry->limWmeEnabled)) || + (pBeacon->edcaPresent && (psessionEntry->limQosEnabled))) + { + if(pBeacon->edcaParams.qosInfo.count != psessionEntry->gLimEdcaParamSetCount) + { + if (schBeaconEdcaProcess(pMac, &pBeacon->edcaParams, psessionEntry) != eSIR_SUCCESS) + PELOGE(schLog(pMac, LOGE, FL("EDCA parameter processing error"));) + else if(pStaDs != NULL) + { + // If needed, downgrade the EDCA parameters + limSetActiveEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry); + + if (pStaDs->aniPeer == eANI_BOOLEAN_TRUE) + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_TRUE); + else + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParamsActive, pStaDs->bssId, eANI_BOOLEAN_FALSE); + } + else + PELOGE(schLog(pMac, LOGE, FL("Self Entry missing in Hash Table"));) + } + } + else if( (pBeacon->qosCapabilityPresent && psessionEntry->limQosEnabled) && + (pBeacon->qosCapability.qosInfo.count != psessionEntry->gLimEdcaParamSetCount)) + sendProbeReq = TRUE; + } + + if ( psessionEntry->htCapability && pBeacon->HTInfo.present && + (!LIM_IS_IBSS_ROLE(psessionEntry))) + { + limUpdateStaRunTimeHTSwitchChnlParams( pMac, &pBeacon->HTInfo, bssIdx,psessionEntry); + } + + if ( (psessionEntry->limSystemRole == eLIM_STA_ROLE) ||(psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) ) + { + /* Channel Switch information element updated */ + if(pBeacon->channelSwitchPresent || + pBeacon->propIEinfo.propChannelSwitchPresent) + { + limUpdateChannelSwitch(pMac, pBeacon, psessionEntry); + } + else if (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING) + { + limCancelDot11hChannelSwitch(pMac, psessionEntry); + } + // check for HT capability + pStaDs = dphLookupHashEntry(pMac, pMh->sa, &aid, + &psessionEntry->dph.dphHashTable); + /* Update the channel bonding mode only if channel bonding + * mode is enabled in INI. + */ + if ( (pStaDs != NULL) && (HAL_STA_INVALID_IDX != pStaDs->staIndex ) && + (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != channelBondingMode) ) + { + /* Following check is related to HT40 on 2.4GHz mode*/ + if ((pStaDs->htSecondaryChannelOffset != + pBeacon->HTInfo.secondaryChannelOffset) && + (IS_HT40_OBSS_SCAN_FEATURE_ENABLE) && + (psessionEntry->currentOperChannel <= RF_CHAN_14)) + { + VOS_TRACE( VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO, + FL(" Current Secondarychanoffset %d received " + " secondaryChannelOffset %d, staIdx = %d"), + pStaDs->htSecondaryChannelOffset, + pBeacon->HTInfo.secondaryChannelOffset, + pStaDs->staIndex); + if (eANI_BOOLEAN_TRUE ==(limCheckHTChanBondModeChange(pMac, + psessionEntry, + pBeacon->HTInfo.secondaryChannelOffset, + pStaDs->htSecondaryChannelOffset, + pStaDs->staIndex))) + { + pStaDs->htSupportedChannelWidthSet = + pBeacon->HTInfo.recommendedTxWidthSet; + pStaDs->htSecondaryChannelOffset = + pBeacon->HTInfo.secondaryChannelOffset; + limUpdateMaxRateFlag(pMac, psessionEntry->smeSessionId, + limGetMaxRateFlags(pStaDs, psessionEntry)); + } + } + } + else + schLog(pMac, LOG1, + FL("Self Entry missing in Hash Table or channel bonding mode is disabled")); + } + /* TODO : Below condition checks can be merged with the if */ +#ifdef WLAN_FEATURE_11AC + if ((psessionEntry->limSystemRole == eLIM_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE) || + (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE)) + { + // check for VHT capability + pStaDs = dphLookupHashEntry(pMac, pMh->sa, &aid, + &psessionEntry->dph.dphHashTable); + + /* Update the channel bonding mode only if channel bonding + * mode is enabled in INI. + */ + if ( (NULL != pStaDs) && (HAL_STA_INVALID_IDX != pStaDs->staIndex ) && + (WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != channelBondingMode) ) + { + if (psessionEntry->vhtCapability && pBeacon->OperatingMode.present ) + { + operMode = pStaDs->vhtSupportedChannelWidthSet ? + eHT_CHANNEL_WIDTH_80MHZ : + pStaDs->htSupportedChannelWidthSet ? + eHT_CHANNEL_WIDTH_40MHZ: eHT_CHANNEL_WIDTH_20MHZ; + if (operMode != pBeacon->OperatingMode.chanWidth) + { + schLog(pMac, LOG1, + FL(" received OpMode Chanwidth %d, staIdx = %d"), + pBeacon->OperatingMode.chanWidth, + pStaDs->staIndex); + schLog(pMac, LOG1, FL(" MAC -" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMh->sa)); + + if (pBeacon->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + { + schLog(pMac, LOG1, + FL("Updating the CH Width to 80MHz")); + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if (pBeacon->OperatingMode.chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + { + schLog(pMac, LOG1, + FL("Updating the CH Width to 40MHz")); + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + } + else if (pBeacon->OperatingMode.chanWidth == + eHT_CHANNEL_WIDTH_20MHZ) + { + schLog(pMac, LOG1, + FL("Updating the CH Width to 20MHz")); + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ; + } + limCheckVHTOpModeChange(pMac, psessionEntry, + pBeacon->OperatingMode.chanWidth, + pStaDs->staIndex); + } + } + else if (psessionEntry->vhtCapability && pBeacon->VHTOperation.present) + { + operMode = pStaDs->vhtSupportedChannelWidthSet; + if (operMode != pBeacon->VHTOperation.chanWidth) + { + schLog(pMac, LOG1, + FL(" received VHTOP CHWidth %d staIdx = %d"), + pBeacon->VHTOperation.chanWidth, + pStaDs->staIndex); + schLog(pMac, LOG1, FL(" MAC -" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMh->sa)); + + if (pBeacon->VHTOperation.chanWidth == + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ) + { + schLog(pMac, LOG1, + FL("Updating the CH Width to 80MHz")); + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ; + pStaDs->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ; + chWidth = eHT_CHANNEL_WIDTH_80MHZ; + } + else if (pBeacon->VHTOperation.chanWidth == + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + { + pStaDs->vhtSupportedChannelWidthSet = + WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ; + if (pBeacon->HTCaps.supportedChannelWidthSet) + { + schLog(pMac, LOG1, + FL("Updating the CH Width to 40MHz")); + pStaDs->htSupportedChannelWidthSet = + eHT_CHANNEL_WIDTH_40MHZ; + chWidth = eHT_CHANNEL_WIDTH_40MHZ; + } + else + { + schLog(pMac, LOG1, + FL("Updating the CH Width to 20MHz")); + pStaDs->htSupportedChannelWidthSet = + eHT_CHANNEL_WIDTH_20MHZ; + chWidth = eHT_CHANNEL_WIDTH_20MHZ; + } + } + limCheckVHTOpModeChange(pMac, psessionEntry, + chWidth, pStaDs->staIndex); + } + } + } + } +#endif + +#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI) + /* Obtain the Max Tx power for the current regulatory */ + regMax = cfgGetRegulatoryMaxTransmitPower( pMac, psessionEntry->currentOperChannel ); +#endif +#if defined WLAN_FEATURE_VOWIFI + { + tPowerdBm localRRMConstraint = 0; + if ( pMac->rrm.rrmPEContext.rrmEnable && pBeacon->powerConstraintPresent ) + { + localRRMConstraint = pBeacon->localPowerConstraint.localPowerConstraints; + } + else + { + localRRMConstraint = 0; + } + maxTxPower = limGetMaxTxPower(regMax, regMax - localRRMConstraint, + pMac->roam.configParam.nTxPowerCap); + } +#elif defined FEATURE_WLAN_ESE + maxTxPower = regMax; +#endif + +#if defined FEATURE_WLAN_ESE + if( psessionEntry->isESEconnection ) + { + tPowerdBm localESEConstraint = 0; + if (pBeacon->eseTxPwr.present) + { + localESEConstraint = pBeacon->eseTxPwr.power_limit; + maxTxPower = limGetMaxTxPower(maxTxPower, localESEConstraint, pMac->roam.configParam.nTxPowerCap); + } + schLog( pMac, LOG1, "RegMax = %d, localESECons = %d, MaxTx = %d", regMax, localESEConstraint, maxTxPower ); + } +#endif + +#if defined (FEATURE_WLAN_ESE) || defined (WLAN_FEATURE_VOWIFI) + { + //If maxTxPower is increased or decreased + if( maxTxPower != psessionEntry->maxTxPower ) + { + schLog( pMac, LOG1, "Local power constraint change..updating new maxTx power %d to HAL",maxTxPower); + if( limSendSetMaxTxPowerReq ( pMac, maxTxPower, psessionEntry ) == eSIR_SUCCESS ) + psessionEntry->maxTxPower = maxTxPower; + } + } +#endif + + // Indicate to LIM that Beacon is received + + if (pBeacon->HTInfo.present) + limReceivedHBHandler(pMac, (tANI_U8)pBeacon->HTInfo.primaryChannel, psessionEntry); + else + limReceivedHBHandler(pMac, (tANI_U8)pBeacon->channelNumber, psessionEntry); + + // I don't know if any additional IE is required here. Currently, not include addIE. + if(sendProbeReq) + limSendProbeReqMgmtFrame(pMac, &psessionEntry->ssId, + psessionEntry->bssId, psessionEntry->currentOperChannel,psessionEntry->selfMacAddr, + psessionEntry->dot11mode, 0, NULL); + + if(beaconParams.paramChangeBitmap) + { + schLog(pMac, LOGW, FL("Beacon for session[%d] got changed. "), psessionEntry->peSessionId); + schLog(pMac, LOGW, FL("sending beacon param change bitmap: 0x%x "), beaconParams.paramChangeBitmap); + limSendBeaconParams(pMac, &beaconParams, psessionEntry); + } + +fail: + return; + +} + +/** + * schBeaconProcess + * + * FUNCTION: + * Process the received beacon frame + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param pRxPacketInfo pointer to buffer descriptor + * @return None + */ + +void schBeaconProcess(tpAniSirGlobal pMac, tANI_U8* pRxPacketInfo, tpPESession psessionEntry) +{ + static tSchBeaconStruct beaconStruct; + tUpdateBeaconParams beaconParams; + tpPESession pAPSession = NULL; + vos_mem_zero(&beaconParams, sizeof(tUpdateBeaconParams)); + beaconParams.paramChangeBitmap = 0; + + pMac->sch.gSchBcnRcvCnt++; + + // Convert the beacon frame into a structure + if (sirConvertBeaconFrame2Struct(pMac, (tANI_U8 *) pRxPacketInfo, &beaconStruct)!= eSIR_SUCCESS) + { + schLog(pMac, LOGE, FL("beacon parsing failed")); + pMac->sch.gSchBcnParseErrorCnt++; + + if ((NULL != psessionEntry) && (!psessionEntry->currentBssBeaconCnt)) + limParseBeaconForTim(pMac, (tANI_U8 *) pRxPacketInfo, psessionEntry); + + return; + } + if (beaconStruct.ssidPresent) + { + beaconStruct.ssId.ssId[beaconStruct.ssId.length] = 0; + } + + /* + * First process the beacon in the context of any existing AP or BTAP session. + * This takes cares of following two scenarios: + * - psessionEntry = NULL: + * e.g. beacon received from a neighboring BSS, you want to apply the protection settings to BTAP/InfraAP beacons + * - psessionEntry is non NULL: + * e.g. beacon received is from the INFRA AP to which you are connected on another concurrent link. + * In this case also, we want to apply the protection settings(as advertised by Infra AP) to BTAP beacons + * + * + */ + + if (((pAPSession = limIsApSessionActive(pMac)) != NULL) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (!(WDA_GET_OFFLOADSCANLEARN(pRxPacketInfo))) +#endif + ) + { + beaconParams.bssIdx = pAPSession->bssIdx; + if (pAPSession->gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE) + ap_beacon_process(pMac, pRxPacketInfo, &beaconStruct, &beaconParams, pAPSession); + + if (beaconParams.paramChangeBitmap) + { + //Update the beacons and apply the new settings to HAL + schSetFixedBeaconFields(pMac, pAPSession); + schLog(pMac, LOG1, FL("Beacon for PE session[%d] got changed."), + pAPSession->peSessionId); + schLog(pMac, LOG1, FL("sending beacon param change bitmap: 0x%x "), + beaconParams.paramChangeBitmap); + limSendBeaconParams(pMac, &beaconParams, pAPSession); + } + } + + /* + * Now process the beacon in the context of the BSS which is transmitting the beacons, if one is found + */ + if(psessionEntry == NULL) + { + __schBeaconProcessNoSession(pMac, &beaconStruct, pRxPacketInfo ); + } + else + { + __schBeaconProcessForSession(pMac, &beaconStruct, pRxPacketInfo, psessionEntry ); + } + +} + + + + + +// -------------------------------------------------------------------- +/** + * schBeaconEdcaProcess + * + * FUNCTION: + * Process the EDCA parameter set in the received beacon frame + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param edca reference to edca parameters in beacon struct + * @return success + */ + +tSirRetStatus schBeaconEdcaProcess(tpAniSirGlobal pMac, tSirMacEdcaParamSetIE *edca, tpPESession psessionEntry) +{ + tANI_U8 i; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_log_qos_edca_pkt_type *log_ptr = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT + + schLog(pMac, LOG2, FL("Updating parameter set count: Old %d ---> new %d"), + psessionEntry->gLimEdcaParamSetCount, edca->qosInfo.count); + + psessionEntry->gLimEdcaParamSetCount = edca->qosInfo.count; + psessionEntry->gLimEdcaParams[EDCA_AC_BE] = edca->acbe; + psessionEntry->gLimEdcaParams[EDCA_AC_BK] = edca->acbk; + psessionEntry->gLimEdcaParams[EDCA_AC_VI] = edca->acvi; + psessionEntry->gLimEdcaParams[EDCA_AC_VO] = edca->acvo; + + if (pMac->roam.configParam.enable_edca_params) { + psessionEntry->gLimEdcaParams[EDCA_AC_VO].aci.aifsn = + pMac->roam.configParam.edca_vo_aifs; + psessionEntry->gLimEdcaParams[EDCA_AC_VI].aci.aifsn = + pMac->roam.configParam.edca_vi_aifs; + psessionEntry->gLimEdcaParams[EDCA_AC_BK].aci.aifsn = + pMac->roam.configParam.edca_bk_aifs; + psessionEntry->gLimEdcaParams[EDCA_AC_BE].aci.aifsn = + pMac->roam.configParam.edca_be_aifs; + + psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.min = + pMac->roam.configParam.edca_vo_cwmin; + psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.min = + pMac->roam.configParam.edca_vi_cwmin; + psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.min = + pMac->roam.configParam.edca_bk_cwmin; + psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.min = + pMac->roam.configParam.edca_be_cwmin; + + psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.max = + pMac->roam.configParam.edca_vo_cwmax; + psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.max = + pMac->roam.configParam.edca_vi_cwmax; + psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.max = + pMac->roam.configParam.edca_bk_cwmax; + psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.max = + pMac->roam.configParam.edca_be_cwmax; + } +//log: LOG_WLAN_QOS_EDCA_C +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_edca_pkt_type, LOG_WLAN_QOS_EDCA_C); + if(log_ptr) + { + log_ptr->aci_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].aci.aci; + log_ptr->cw_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_BE].cw.min; + log_ptr->txoplimit_be = psessionEntry->gLimEdcaParams[EDCA_AC_BE].txoplimit; + log_ptr->aci_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].aci.aci; + log_ptr->cw_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_BK].cw.min; + log_ptr->txoplimit_bk = psessionEntry->gLimEdcaParams[EDCA_AC_BK].txoplimit; + log_ptr->aci_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].aci.aci; + log_ptr->cw_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_VI].cw.min; + log_ptr->txoplimit_vi = psessionEntry->gLimEdcaParams[EDCA_AC_VI].txoplimit; + log_ptr->aci_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].aci.aci; + log_ptr->cw_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.max << 4 | + psessionEntry->gLimEdcaParams[EDCA_AC_VO].cw.min; + log_ptr->txoplimit_vo = psessionEntry->gLimEdcaParams[EDCA_AC_VO].txoplimit; + } + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT + schLog(pMac, LOG1, + FL("edsa param enabled in ini %d. Updating Local EDCA Params(gLimEdcaParams) to: "), + pMac->roam.configParam.enable_edca_params); + for(i=0; igLimEdcaParams[i].aci.aifsn, + psessionEntry->gLimEdcaParams[i].aci.acm, + psessionEntry->gLimEdcaParams[i].cw.min, + psessionEntry->gLimEdcaParams[i].cw.max, + psessionEntry->gLimEdcaParams[i].txoplimit); + } + + return eSIR_SUCCESS; +} diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.c new file mode 100644 index 000000000000..92f7c9a1b3d8 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schDebug.cc contains some debug functions. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + + +#include "vos_trace.h" +#include "schDebug.h" +#define LOG_SIZE 256 + +void schLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...) +{ + + VOS_TRACE_LEVEL vosDebugLevel; + char logBuffer[LOG_SIZE]; + va_list marker; + + /* getting proper Debug level*/ + vosDebugLevel = getVosDebugLevel(loglevel); + + /* extracting arguments from pstring */ + va_start( marker, pString ); + vsnprintf(logBuffer, LOG_SIZE, pString, marker); + VOS_TRACE(VOS_MODULE_ID_PE, vosDebugLevel, "%s", logBuffer); + va_end( marker ); + } + + + +// -------------------------------------------------------------------- diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.h b/drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.h new file mode 100644 index 000000000000..41cb7b46eaa5 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schDebug.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schDebug.h contains some debug macros. + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_DEBUG_H__ +#define __SCH_DEBUG_H__ + +#include "utilsApi.h" +#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC +#include "halCommonApi.h" +#endif +#include "sirDebug.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) schLog(tpAniSirGlobal pMac, tANI_U32 loglevel, + const char *pString, ...); + +#endif diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schMessage.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schMessage.c new file mode 100644 index 000000000000..083a7c8009c5 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schMessage.c @@ -0,0 +1,616 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file schMessage.cc contains the message handler + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#include "palTypes.h" +#include "sirCommon.h" + +#include "wniCfg.h" +#include "aniGlobal.h" +#include "cfgApi.h" +#include "limApi.h" +#include "pmmApi.h" +#include "limSendMessages.h" + + +#include "schApi.h" +#include "schDebug.h" + +/// Minimum beacon interval allowed (in Kus) +#define SCH_BEACON_INTERVAL_MIN 10 + +/// Maximum beacon interval allowed (in Kus) +#define SCH_BEACON_INTERVAL_MAX 10000 + +/// convert the CW values into a tANI_U16 +#define GET_CW(pCw) ((tANI_U16) ((*(pCw) << 8) + *((pCw) + 1))) + +// local functions +static tSirRetStatus getWmmLocalParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]); +static void setSchEdcaParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], tpPESession psessionEntry); + +// -------------------------------------------------------------------- +/** + * schSetBeaconInterval + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void schSetBeaconInterval(tpAniSirGlobal pMac,tpPESession psessionEntry) +{ + tANI_U32 bi; + + bi = psessionEntry->beaconParams.beaconInterval; + + if (bi < SCH_BEACON_INTERVAL_MIN || bi > SCH_BEACON_INTERVAL_MAX) + { + schLog(pMac, LOGE, FL("Invalid beacon interval %d (should be [%d,%d]"), + bi, SCH_BEACON_INTERVAL_MIN, SCH_BEACON_INTERVAL_MAX); + return; + } + + pMac->sch.schObject.gSchBeaconInterval = (tANI_U16)bi; +} + + +// -------------------------------------------------------------------- +/** + * schProcessMessage + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param None + * @return None + */ + +void schProcessMessage(tpAniSirGlobal pMac,tpSirMsgQ pSchMsg) +{ +#ifdef FIXME_GEN6 + tANI_U32 *pBD; + tpSirMacMgmtHdr mh; + void *pPacket; +#endif + tANI_U32 val; + + tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry????? + PELOG3(schLog(pMac, LOG3, FL("Received message (%x) "), pSchMsg->type);) + + switch (pSchMsg->type) + { +#ifdef FIXME_GEN6 + case SIR_BB_XPORT_MGMT_MSG: + pMac->sch.gSchBBXportRcvCnt++; + + + pBD = (tANI_U32 *) pSchMsg->bodyptr; + + + mh = SIR_MAC_BD_TO_MPDUHEADER( pBD ); + + if (mh->fc.type == SIR_MAC_MGMT_FRAME && + mh->fc.subType == SIR_MAC_MGMT_BEACON) + schBeaconProcess(pMac, pBD); + else + { + schLog(pMac, LOGE, FL("Unexpected message (%d,%d) rcvd"), + mh->fc.type, mh->fc.subType); + pMac->sch.gSchUnknownRcvCnt++; + } + break; +#endif + + case SIR_SCH_CHANNEL_SWITCH_REQUEST: + schLog(pMac, LOGE, + FL("Channel switch request not handled")); + break; + + case SIR_SCH_START_SCAN_REQ: + pMac->sch.gSchScanReqRcvd = true; + if (pMac->sch.gSchHcfEnabled) + { + // In HCF mode, wait for TFP to stop before sending a response + if (pMac->sch.schObject.gSchCFBInitiated || + pMac->sch.schObject.gSchCFPInitiated) + { + PELOG1(schLog(pMac, LOG1, + FL("Waiting for TFP to halt before sending " + "start scan response"));) + } + else + schSendStartScanRsp(pMac); + } + else + { + // In eDCF mode, send the response right away + schSendStartScanRsp(pMac); + } + break; + + case SIR_SCH_END_SCAN_NTF: + PELOG3(schLog(pMac, LOG3, + FL("Received STOP_SCAN_NTF from LIM"));) + pMac->sch.gSchScanReqRcvd = false; + break; + + case SIR_CFG_PARAM_UPDATE_IND: + + if (wlan_cfgGetInt(pMac, (tANI_U16) pSchMsg->bodyval, &val) != eSIR_SUCCESS) + schLog(pMac, LOGP, FL("failed to cfg get id %d"), pSchMsg->bodyval); + + switch (pSchMsg->bodyval) + { + case WNI_CFG_BEACON_INTERVAL: + // What to do for IBSS ?? - TBD + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + schSetBeaconInterval(pMac,psessionEntry); + break; + + + case WNI_CFG_DTIM_PERIOD: + pMac->sch.schObject.gSchDTIMCount = 0; + break; + + case WNI_CFG_CFP_PERIOD: + pMac->sch.schObject.gSchCFPCount = 0; + break; + + case WNI_CFG_EDCA_PROFILE: + schEdcaProfileUpdate(pMac, psessionEntry); + break; + + case WNI_CFG_EDCA_ANI_ACBK_LOCAL: + case WNI_CFG_EDCA_ANI_ACBE_LOCAL: + case WNI_CFG_EDCA_ANI_ACVI_LOCAL: + case WNI_CFG_EDCA_ANI_ACVO_LOCAL: + case WNI_CFG_EDCA_WME_ACBK_LOCAL: + case WNI_CFG_EDCA_WME_ACBE_LOCAL: + case WNI_CFG_EDCA_WME_ACVI_LOCAL: + case WNI_CFG_EDCA_WME_ACVO_LOCAL: + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + schQosUpdateLocal(pMac, psessionEntry); + break; + + case WNI_CFG_EDCA_ANI_ACBK: + case WNI_CFG_EDCA_ANI_ACBE: + case WNI_CFG_EDCA_ANI_ACVI: + case WNI_CFG_EDCA_ANI_ACVO: + case WNI_CFG_EDCA_WME_ACBK: + case WNI_CFG_EDCA_WME_ACBE: + case WNI_CFG_EDCA_WME_ACVI: + case WNI_CFG_EDCA_WME_ACVO: + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + psessionEntry->gLimEdcaParamSetCount++; + schQosUpdateBroadcast(pMac, psessionEntry); + } + break; + + default: + schLog(pMac, LOGE, FL("Cfg param %d indication not handled"), + pSchMsg->bodyval); + } + break; + + default: + schLog(pMac, LOGE, FL("Unknown message in schMsgQ type %d"), + pSchMsg->type); + } + +} + + +// get the local or broadcast parameters based on the profile sepcified in the config +// params are delivered in this order: BK, BE, VI, VO +tSirRetStatus +schGetParams( + tpAniSirGlobal pMac, + tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], + tANI_U8 local) +{ + tANI_U32 val; + tANI_U32 i,idx; + tANI_U32 *prf; + + tANI_U32 ani_l[] = { WNI_CFG_EDCA_ANI_ACBE_LOCAL,WNI_CFG_EDCA_ANI_ACBK_LOCAL, + WNI_CFG_EDCA_ANI_ACVI_LOCAL, WNI_CFG_EDCA_ANI_ACVO_LOCAL }; + tANI_U32 wme_l[] = {WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL, + WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL}; + tANI_U32 demo_l[] = {WNI_CFG_EDCA_TIT_DEMO_ACBE_LOCAL, WNI_CFG_EDCA_TIT_DEMO_ACBK_LOCAL, + WNI_CFG_EDCA_TIT_DEMO_ACVI_LOCAL, WNI_CFG_EDCA_TIT_DEMO_ACVO_LOCAL}; + tANI_U32 ani_b[] = {WNI_CFG_EDCA_ANI_ACBE, WNI_CFG_EDCA_ANI_ACBK, + WNI_CFG_EDCA_ANI_ACVI, WNI_CFG_EDCA_ANI_ACVO}; + tANI_U32 wme_b[] = {WNI_CFG_EDCA_WME_ACBE, WNI_CFG_EDCA_WME_ACBK, + WNI_CFG_EDCA_WME_ACVI, WNI_CFG_EDCA_WME_ACVO}; + tANI_U32 demo_b[] = {WNI_CFG_EDCA_TIT_DEMO_ACBE, WNI_CFG_EDCA_TIT_DEMO_ACBK, + WNI_CFG_EDCA_TIT_DEMO_ACVI, WNI_CFG_EDCA_TIT_DEMO_ACVO}; + + if (wlan_cfgGetInt(pMac, WNI_CFG_EDCA_PROFILE, &val) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("failed to cfg get EDCA_PROFILE id %d"), + WNI_CFG_EDCA_PROFILE); + return eSIR_FAILURE; + } + + if (val >= WNI_CFG_EDCA_PROFILE_MAX) + { + schLog(pMac, LOGE, FL("Invalid EDCA_PROFILE %d, using %d instead"), + val, WNI_CFG_EDCA_PROFILE_ANI); + val = WNI_CFG_EDCA_PROFILE_ANI; + } + + schLog(pMac, LOGW, FL("EdcaProfile: Using %d (%s)"), val, + ((val == WNI_CFG_EDCA_PROFILE_WMM) ? "WMM" + : ( (val == WNI_CFG_EDCA_PROFILE_TIT_DEMO) ? "Titan" : "HiPerf"))); + + if (local) + { + switch (val) + { + case WNI_CFG_EDCA_PROFILE_WMM: + prf = &wme_l[0]; + break; + case WNI_CFG_EDCA_PROFILE_TIT_DEMO: + prf = &demo_l[0]; + break; + case WNI_CFG_EDCA_PROFILE_ANI: + default: + prf = &ani_l[0]; + break; + } + } + else + { + switch (val) + { + case WNI_CFG_EDCA_PROFILE_WMM: + prf = &wme_b[0]; + break; + case WNI_CFG_EDCA_PROFILE_TIT_DEMO: + prf = &demo_b[0]; + break; + case WNI_CFG_EDCA_PROFILE_ANI: + default: + prf = &ani_b[0]; + break; + } + } + + for (i=0; i < 4; i++) + { + tANI_U8 data[WNI_CFG_EDCA_ANI_ACBK_LEN]; + tANI_U32 len = WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN; + if (wlan_cfgGetStr(pMac, (tANI_U16) prf[i], (tANI_U8 *) &data[0], &len) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("cfgGet failed for %d"), prf[i]); + return eSIR_FAILURE; + } + if (len > WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN) + { + schLog(pMac, LOGE, FL("cfgGet for %d: length is %d instead of %d"), + prf[i], len, WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN); + return eSIR_FAILURE; + } + for (idx=0; idx < len; idx++) + params[i][idx] = (tANI_U32) data[idx]; + } + PELOG1(schLog(pMac, LOG1, FL("GetParams: local=%d, profile = %d Done"), local, val);) + return eSIR_SUCCESS; +} + +static void broadcastWMMOfConcurrentSTASession(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U8 i,j; + tpPESession pConcurrentStaSessionEntry; + + for (i =0;i < pMac->lim.maxBssId;i++) + { + /* Find another INFRA STA AP session on same operating channel. The session entry passed to this API is for GO/SoftAP session that is getting added currently */ + if ( (pMac->lim.gpSession[i].valid == TRUE ) && + (pMac->lim.gpSession[i].peSessionId != psessionEntry->peSessionId) && + (pMac->lim.gpSession[i].currentOperChannel == psessionEntry->currentOperChannel) && + (pMac->lim.gpSession[i].limSystemRole == eLIM_STA_ROLE) + ) + { + pConcurrentStaSessionEntry = &(pMac->lim.gpSession[i]); + for (j=0; jgLimEdcaParamsBC[j].aci.acm = pConcurrentStaSessionEntry->gLimEdcaParams[j].aci.acm; + psessionEntry->gLimEdcaParamsBC[j].aci.aifsn = pConcurrentStaSessionEntry->gLimEdcaParams[j].aci.aifsn; + psessionEntry->gLimEdcaParamsBC[j].cw.min = pConcurrentStaSessionEntry->gLimEdcaParams[j].cw.min; + psessionEntry->gLimEdcaParamsBC[j].cw.max = pConcurrentStaSessionEntry->gLimEdcaParams[j].cw.max; + psessionEntry->gLimEdcaParamsBC[j].txoplimit= pConcurrentStaSessionEntry->gLimEdcaParams[j].txoplimit; + + PELOG1(schLog(pMac, LOG1, "QoSUpdateBCast changed again due to concurrent INFRA STA session: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d", + j, + psessionEntry->gLimEdcaParamsBC[j].aci.aifsn, + psessionEntry->gLimEdcaParamsBC[j].aci.acm, + psessionEntry->gLimEdcaParamsBC[j].cw.min, + psessionEntry->gLimEdcaParamsBC[j].cw.max, + psessionEntry->gLimEdcaParamsBC[j].txoplimit);) + + } + /* Once atleast one concurrent session on same channel is found and WMM broadcast params for current SoftAP/GO session updated, return*/ + break; + } + } +} + +void +schQosUpdateBroadcast(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]; + tANI_U32 cwminidx, cwmaxidx, txopidx; + tANI_U32 phyMode; + tANI_U8 i; + + if (schGetParams(pMac, params, false) != eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("QosUpdateBroadcast: failed"));) + return; + } + limGetPhyMode(pMac, &phyMode, psessionEntry); + + PELOG1(schLog(pMac, LOG1, "QosUpdBcast: mode %d", phyMode);) + + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMING_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXG_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPG_IDX; + } + else if (phyMode == WNI_CFG_PHY_MODE_11B) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINB_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXB_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPB_IDX; + } + else // This can happen if mode is not set yet, assume 11a mode + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINA_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXA_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPA_IDX; + } + + + for(i=0; igLimEdcaParamsBC[i].aci.acm = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_ACM_IDX]; + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_AIFSN_IDX]; + psessionEntry->gLimEdcaParamsBC[i].cw.min = convertCW(GET_CW(¶ms[i][cwminidx])); + psessionEntry->gLimEdcaParamsBC[i].cw.max = convertCW(GET_CW(¶ms[i][cwmaxidx])); + psessionEntry->gLimEdcaParamsBC[i].txoplimit= (tANI_U16) params[i][txopidx]; + + PELOG1(schLog(pMac, LOG1, "QoSUpdateBCast: AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d", i, + psessionEntry->gLimEdcaParamsBC[i].aci.aifsn, + psessionEntry->gLimEdcaParamsBC[i].aci.acm, + psessionEntry->gLimEdcaParamsBC[i].cw.min, + psessionEntry->gLimEdcaParamsBC[i].cw.max, + psessionEntry->gLimEdcaParamsBC[i].txoplimit);) + + } + + /* If there exists a concurrent STA-AP session, use its WMM params to broadcast in beacons. WFA Wifi Direct test plan 6.1.14 requirement */ + broadcastWMMOfConcurrentSTASession(pMac, psessionEntry); + + if (schSetFixedBeaconFields(pMac,psessionEntry) != eSIR_SUCCESS) + PELOGE(schLog(pMac, LOGE, "Unable to set beacon fields!");) +} + +void +schQosUpdateLocal(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + + tANI_U32 params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]; + tANI_BOOLEAN highPerformance=eANI_BOOLEAN_TRUE; + + if (schGetParams(pMac, params, true /*local*/) != eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("schGetParams(local) failed"));) + return; + } + + setSchEdcaParams(pMac, params, psessionEntry); + + if (psessionEntry->limSystemRole == eLIM_AP_ROLE) + { + if (pMac->lim.gLimNumOfAniSTAs) + highPerformance = eANI_BOOLEAN_TRUE; + else + highPerformance = eANI_BOOLEAN_FALSE; + } + else if (psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + highPerformance = eANI_BOOLEAN_TRUE; + } + + //For AP, the bssID is stored in LIM Global context. + limSendEdcaParams(pMac, psessionEntry->gLimEdcaParams, psessionEntry->bssIdx, highPerformance); +} + +/** ---------------------------------------------------------- +\fn schSetDefaultEdcaParams +\brief This function sets the gLimEdcaParams to the default +\ local wmm profile. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------ */ +void +schSetDefaultEdcaParams(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + tANI_U32 params[4][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]; + + if (getWmmLocalParams(pMac, params) != eSIR_SUCCESS) + { + PELOGE(schLog(pMac, LOGE, FL("getWmmLocalParams() failed"));) + return; + } + + setSchEdcaParams(pMac, params, psessionEntry); + return; +} + + +/** ---------------------------------------------------------- +\fn setSchEdcaParams +\brief This function fills in the gLimEdcaParams structure +\ with the given edca params. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------ */ +static void +setSchEdcaParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN], tpPESession psessionEntry) +{ + tANI_U32 i; + tANI_U32 cwminidx, cwmaxidx, txopidx; + tANI_U32 phyMode; + + limGetPhyMode(pMac, &phyMode, psessionEntry); + + PELOG1(schLog(pMac, LOG1, FL("limGetPhyMode() = %d"), phyMode);) + + //if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11G) + if (phyMode == WNI_CFG_PHY_MODE_11G) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMING_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXG_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPG_IDX; + } + //else if (pMac->lim.gLimPhyMode == WNI_CFG_PHY_MODE_11B) + else if (phyMode == WNI_CFG_PHY_MODE_11B) + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINB_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXB_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPB_IDX; + } + else // This can happen if mode is not set yet, assume 11a mode + { + cwminidx = WNI_CFG_EDCA_PROFILE_CWMINA_IDX; + cwmaxidx = WNI_CFG_EDCA_PROFILE_CWMAXA_IDX; + txopidx = WNI_CFG_EDCA_PROFILE_TXOPA_IDX; + } + + for(i=0; igLimEdcaParams[i].aci.acm = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_ACM_IDX]; + psessionEntry->gLimEdcaParams[i].aci.aifsn = (tANI_U8) params[i][WNI_CFG_EDCA_PROFILE_AIFSN_IDX]; + psessionEntry->gLimEdcaParams[i].cw.min = convertCW(GET_CW(¶ms[i][cwminidx])); + psessionEntry->gLimEdcaParams[i].cw.max = convertCW(GET_CW(¶ms[i][cwmaxidx])); + psessionEntry->gLimEdcaParams[i].txoplimit= (tANI_U16) params[i][txopidx]; + + PELOG1(schLog(pMac, LOG1, FL("AC :%d: AIFSN: %d, ACM %d, CWmin %d, CWmax %d, TxOp %d"), i, + psessionEntry->gLimEdcaParams[i].aci.aifsn, + psessionEntry->gLimEdcaParams[i].aci.acm, + psessionEntry->gLimEdcaParams[i].cw.min, + psessionEntry->gLimEdcaParams[i].cw.max, + psessionEntry->gLimEdcaParams[i].txoplimit);) + + } + return; +} + +/** ---------------------------------------------------------- +\fn getWmmLocalParams +\brief This function gets the WMM local edca parameters. +\param tpAniSirGlobal pMac +\param tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN] +\return none +\ ------------------------------------------------------------ */ +static tSirRetStatus +getWmmLocalParams(tpAniSirGlobal pMac, tANI_U32 params[][WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN]) +{ + tANI_U32 i,idx; + tANI_U32 *prf; + tANI_U32 wme_l[] = {WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL, + WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL}; + + prf = &wme_l[0]; + for (i=0; i < 4; i++) + { + tANI_U8 data[WNI_CFG_EDCA_ANI_ACBK_LEN]; + tANI_U32 len = WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN; + if (wlan_cfgGetStr(pMac, (tANI_U16) prf[i], (tANI_U8 *) &data[0], &len) != eSIR_SUCCESS) + { + schLog(pMac, LOGP, FL("cfgGet failed for %d"), prf[i]); + return eSIR_FAILURE; + } + if (len > WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN) + { + schLog(pMac, LOGE, FL("cfgGet for %d: length is %d instead of %d"), + prf[i], len, WNI_CFG_EDCA_ANI_ACBK_LOCAL_LEN); + return eSIR_FAILURE; + } + for (idx=0; idx < len; idx++) + params[i][idx] = (tANI_U32) data[idx]; + } + return eSIR_SUCCESS; +} + + +/** ---------------------------------------------------------- +\fn schEdcaProfileUpdate +\brief This function updates the local and broadcast +\ EDCA params in the gLimEdcaParams structure. It also +\ updates the edcaParamSetCount. +\param tpAniSirGlobal pMac +\return none +\ ------------------------------------------------------------ */ +void +schEdcaProfileUpdate(tpAniSirGlobal pMac, tpPESession psessionEntry) +{ + if (psessionEntry->limSystemRole == eLIM_AP_ROLE || psessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + schQosUpdateLocal(pMac, psessionEntry); + psessionEntry->gLimEdcaParamSetCount++; + schQosUpdateBroadcast(pMac, psessionEntry); + } +} + +// -------------------------------------------------------------------- diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schSysParams.h b/drivers/staging/prima/CORE/MAC/src/pe/sch/schSysParams.h new file mode 100644 index 000000000000..c6018cd52953 --- /dev/null +++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schSysParams.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file schSysParams.h contains scheduler parameter definitions + * + * Author: Sandesh Goel + * Date: 02/25/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#ifndef __SCH_SYS_PARAMS_H__ +#define __SCH_SYS_PARAMS_H__ + +/// Unsolicited poll period (ms) (0 to disable) +#define SCH_POLL_PERIOD 1000 + +/// RR timeout value (ms) (0 to disable) +#define SCH_RR_TIMEOUT_MS 40 + +/// Default CP:CFP ratio +#define SCH_DEFAULT_CP_TO_CFP_RATIO 0 + +/// Default maximum CFP duration (us) +#define SCH_DEFAULT_MAX_CFP_TIME 60000 + +/// Default minimum CP duration (us) +#define SCH_DEFAULT_MIN_CP_TIME 100 + +/// Amount of delay prior to starting CFP (us) +#define SCH_CFP_START_DELAY 100 + +/// Unit of Txop in micro seconds +#define TXOP_UNIT_IN_USEC 32 + +/// Minimum amount of time granted per instruction on average (units of txop) +#define MIN_TXOP_PER_INSTRUCTION 50 + +/// Maximum amount of time granted per instruction (units of txop) +#define MAX_TXOP_PER_INSTRUCTION 300 // HACK - 100 + +/// Maximum amount of time granted to one entire schedule (units of txop) +#define MAX_TXOP_PER_SCHEDULE 400 + +/// Scheduling quantum (units of TXOP) +#define SCH_QUANTUM_QUEUE 4 + +/// Maximum unused quantum allowed to be accumulated by a queue +#define MAX_ACCUMULATED_QUANTUM 500 + +/// Minimum allocated quantum for an uplink flow before a poll instruction is written +#define SCH_MIN_UL_ALLOC 12 + +// ---- Scheduling Policy ---- + +/// Number of QOS classes +#define SCH_NUM_QOS_CLASSES 2 + +#define SCH_POLICY_STRICT_PRI 0 +#define SCH_POLICY_DRR 1 + +/// Scheduling quantum for each class if using DRR +#define SCH_QUANTUM_CLASS 100 + +/// The default scheduling policy between classes +#define SCH_POLICY_DEFAULT SCH_POLICY_STRICT_PRI + +// Scheduling weights for each priority + +#define SCH_QUANTUM_0 40 +#define SCH_QUANTUM_1 36 +#define SCH_QUANTUM_2 32 +#define SCH_QUANTUM_3 28 +#define SCH_QUANTUM_4 24 +#define SCH_QUANTUM_5 20 +#define SCH_QUANTUM_6 16 +#define SCH_QUANTUM_7 12 + +#endif diff --git a/drivers/staging/prima/CORE/SAP/inc/sapApi.h b/drivers/staging/prima/CORE/SAP/inc/sapApi.h new file mode 100644 index 000000000000..390e10b5d39c --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/inc/sapApi.h @@ -0,0 +1,1627 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANSAP_H +#define WLAN_QCT_WLANSAP_H + +/*=========================================================================== + + W L A N S O F T A P P A L L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan SAP PAL layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/SAP/inc/sapApi.h,v 1.21 2009/03/09 08:58:26 jzmuda Exp jzmuda $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +07/01/08 SAP team Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" +#include "vos_types.h" + +#include "p2p_Api.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + defines and enum + ------------------------------------------------------------------------*/ + +#define MAX_SSID_LEN 32 +#define MAX_ACL_MAC_ADDRESS 16 +#define AUTO_CHANNEL_SELECT 0 +#define MAX_ASSOC_IND_IE_LEN 255 + +/* defines for WPS config states */ +#define SAP_WPS_DISABLED 0 +#define SAP_WPS_ENABLED_UNCONFIGURED 1 +#define SAP_WPS_ENABLED_CONFIGURED 2 + +#define MAX_NAME_SIZE 64 +#define MAX_TEXT_SIZE 32 + + +/*-------------------------------------------------------------------------- + reasonCode take form 802.11 standard Table 7-22 to be passed to WLANSAP_DisassocSta api. + ------------------------------------------------------------------------*/ + +typedef enum{ + eSAP_RC_RESERVED0, /*0*/ + eSAP_RC_UNSPECIFIED, /*1*/ + eSAP_RC_PREV_AUTH_INVALID, /*2*/ + eSAP_RC_STA_LEFT_DEAUTH, /*3*/ + eSAP_RC_INACTIVITY_DISASSOC, /*4*/ + eSAP_RC_AP_CAPACITY_FULL, /*5*/ + eSAP_RC_CLS2_FROM_NON_AUTH_STA, /*6*/ + eSAP_RC_CLS3_FROM_NON_AUTH_STA, /*7*/ + eSAP_RC_STA_LEFT_DISASSOC, /*8*/ + eSAP_RC_STA_NOT_AUTH, /*9*/ + eSAP_RC_PC_UNACCEPTABLE, /*10*/ + eSAP_RC_SC_UNACCEPTABLE, /*11*/ + eSAP_RC_RESERVED1, /*12*/ + eSAP_RC_INVALID_IE, /*13*/ + eSAP_RC_MIC_FAIL, /*14*/ + eSAP_RC_4_WAY_HANDSHAKE_TO, /*15*/ + eSAP_RC_GO_KEY_HANDSHAKE_TO, /*16*/ + eSAP_RC_IE_MISMATCH, /*17*/ + eSAP_RC_INVALID_GRP_CHIPHER, /*18*/ + eSAP_RC_INVALID_PAIR_CHIPHER, /*19*/ + eSAP_RC_INVALID_AKMP, /*20*/ + eSAP_RC_UNSUPPORTED_RSN, /*21*/ + eSAP_RC_INVALID_RSN, /*22*/ + eSAP_RC_1X_AUTH_FAILED, /*23*/ + eSAP_RC_CHIPER_SUITE_REJECTED, /*24*/ +}eSapReasonCode; + +typedef enum { + eSAP_DOT11_MODE_abg = 0x0001, + eSAP_DOT11_MODE_11a = 0x0002, + eSAP_DOT11_MODE_11b = 0x0004, + eSAP_DOT11_MODE_11g = 0x0008, + eSAP_DOT11_MODE_11n = 0x0010, + eSAP_DOT11_MODE_11g_ONLY = 0x0080, + eSAP_DOT11_MODE_11n_ONLY = 0x0100, + eSAP_DOT11_MODE_11b_ONLY = 0x0400, +#ifdef WLAN_FEATURE_11AC + eSAP_DOT11_MODE_11ac = 0x1000, + eSAP_DOT11_MODE_11ac_ONLY = 0x2000 +#endif +} eSapPhyMode; + +typedef enum { + eSAP_ACCEPT_UNLESS_DENIED = 0, + eSAP_DENY_UNLESS_ACCEPTED = 1, + eSAP_SUPPORT_ACCEPT_AND_DENY = 2, /* this type is added to support both accept and deny lists at the same time */ + eSAP_ALLOW_ALL = 3, /*In this mode all MAC addresses are allowed to connect*/ +} eSapMacAddrACL; + +typedef enum { + eSAP_BLACK_LIST = 0, /* List of mac addresses NOT allowed to assoc */ + eSAP_WHITE_LIST = 1, /* List of mac addresses allowed to assoc */ +} eSapACLType; + +typedef enum { + ADD_STA_TO_ACL = 0, /* cmd to add STA to access control list */ + DELETE_STA_FROM_ACL = 1, /* cmd to delete STA from access control list */ +} eSapACLCmdType; + +typedef enum { + eSAP_START_BSS_EVENT = 0, /*Event sent when BSS is started*/ + eSAP_STOP_BSS_EVENT, /*Event sent when BSS is stopped*/ + eSAP_STA_ASSOC_IND, /* Indicate the association request to upper layers */ + eSAP_STA_ASSOC_EVENT, /*Event sent when we have successfully associated a station and + upper layer neeeds to allocate a context*/ + eSAP_STA_REASSOC_EVENT, /*Event sent when we have successfully reassociated a station and + upper layer neeeds to allocate a context*/ + eSAP_STA_DISASSOC_EVENT, /*Event sent when associated a station has disassociated as a result of various conditions */ + eSAP_STA_SET_KEY_EVENT, /*Event sent when user called WLANSAP_SetKeySta */ + eSAP_STA_DEL_KEY_EVENT, /*Event sent when user called WLANSAP_DelKeySta */ + eSAP_STA_MIC_FAILURE_EVENT, /*Event sent whenever there is MIC failure detected */ + eSAP_ASSOC_STA_CALLBACK_EVENT, /*Event sent when user called WLANSAP_GetAssocStations */ + eSAP_GET_WPSPBC_SESSION_EVENT, /* Event send when user call WLANSAP_getWpsSessionOverlap */ + eSAP_WPS_PBC_PROBE_REQ_EVENT, /* Event send on WPS PBC probe request is received */ + eSAP_REMAIN_CHAN_READY, + eSAP_SEND_ACTION_CNF, + eSAP_DISCONNECT_ALL_P2P_CLIENT, + eSAP_MAC_TRIG_STOP_BSS_EVENT, + eSAP_UNKNOWN_STA_JOIN, /* Event send when a STA in neither white list or black list tries to associate in softap mode */ + eSAP_MAX_ASSOC_EXCEEDED, /* Event send when a new STA is rejected association since softAP max assoc limit has reached */ +} eSapHddEvent; + +typedef enum { + eSAP_OPEN_SYSTEM, + eSAP_SHARED_KEY, + eSAP_AUTO_SWITCH + } eSapAuthType; + +typedef enum { + eSAP_MAC_INITATED_DISASSOC = 0x10000, /*Disassociation was internally initated from CORE stack*/ + eSAP_USR_INITATED_DISASSOC /*Disassociation was internally initated from host by invoking WLANSAP_DisassocSta call*/ + } eSapDisassocReason; + +/*Handle boolean over here*/ +typedef enum { + eSAP_FALSE, + eSAP_TRUE, +}eSapBool; + +/*--------------------------------------------------------------------------- +SAP PAL "status" and "reason" error code defines + ---------------------------------------------------------------------------*/ +typedef enum { + eSAP_STATUS_SUCCESS, /* Success. */ + eSAP_STATUS_FAILURE, /* General Failure. */ + eSAP_START_BSS_CHANNEL_NOT_SELECTED, /* Channel not selected during intial scan. */ + eSAP_ERROR_MAC_START_FAIL, /* Failed to start Infra BSS */ +}eSapStatus; + +/*--------------------------------------------------------------------------- +SAP PAL "status" and "reason" error code defines + ---------------------------------------------------------------------------*/ +typedef enum { + eSAP_WPSPBC_OVERLAP_IN120S, /* Overlap */ + eSAP_WPSPBC_NO_WPSPBC_PROBE_REQ_IN120S, /* no WPS probe request in 120 second */ + eSAP_WPSPBC_ONE_WPSPBC_PROBE_REQ_IN120S, /* One WPS probe request in 120 second */ +}eWPSPBCOverlap; + +typedef enum { + eSAP_RF_SUBBAND_2_4_GHZ = 0, + eSAP_RF_SUBBAND_5_LOW_GHZ = 1, //Low & Mid U-NII + eSAP_RF_SUBBAND_5_MID_GHZ = 2, //ETSI + eSAP_RF_SUBBAND_5_HIGH_GHZ = 3, //High U-NII + eSAP_RF_SUBBAND_4_9_GHZ = 4, + eSAP_RF_SUBBAND_5_ALL_GHZ = 5, //All 5 GHZ, +}eSapOperatingBand; + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ +typedef struct sap_StartBssCompleteEvent_s { + v_U8_t status; + v_U8_t operatingChannel; + v_U16_t staId; //self StaID +} tSap_StartBssCompleteEvent; + +typedef struct sap_StopBssCompleteEvent_s { + v_U8_t status; +} tSap_StopBssCompleteEvent; + +typedef struct sap_StationAssocIndication_s { + v_MACADDR_t staMac; + v_U8_t assoId; + v_U8_t staId; + v_U8_t status; + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + tANI_BOOLEAN fWmmEnabled; + eCsrAuthType negotiatedAuthType; + eCsrEncryptionType negotiatedUCEncryptionType; + eCsrEncryptionType negotiatedMCEncryptionType; + tANI_BOOLEAN fAuthRequired; +} tSap_StationAssocIndication; + +typedef struct sap_StationAssocReassocCompleteEvent_s { + v_MACADDR_t staMac; + v_U8_t staId; + v_U8_t status; + v_U8_t ies[MAX_ASSOC_IND_IE_LEN]; + v_U16_t iesLen; + v_U32_t statusCode; + eSapAuthType SapAuthType; + v_BOOL_t wmmEnabled; + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + tANI_U32 assocRespLength; + tANI_U8* assocRespPtr; + uint32_t rate_flags; +} tSap_StationAssocReassocCompleteEvent; + +typedef struct sap_StationDisassocCompleteEvent_s { + v_MACADDR_t staMac; + v_U8_t staId; //STAID should not be used + v_U8_t status; + v_U32_t statusCode; + eSapDisassocReason reason; +} tSap_StationDisassocCompleteEvent; + +typedef struct sap_StationSetKeyCompleteEvent_s { + v_U8_t status; + v_MACADDR_t peerMacAddr; +} tSap_StationSetKeyCompleteEvent; + +/*struct corresponding to SAP_STA_DEL_KEY_EVENT */ +typedef struct sap_StationDeleteKeyCompleteEvent_s { + v_U8_t status; + v_U8_t keyId; /* Key index */ +} tSap_StationDeleteKeyCompleteEvent; + +/*struct corresponding to SAP_STA_MIC_FAILURE_EVENT */ +typedef struct sap_StationMICFailureEvent_s { + v_MACADDR_t srcMacAddr; //address used to compute MIC + v_MACADDR_t staMac; //taMacAddr transmitter address + v_MACADDR_t dstMacAddr; + eSapBool multicast; + v_U8_t IV1; // first byte of IV + v_U8_t keyId; // second byte of IV + v_U8_t TSC[SIR_CIPHER_SEQ_CTR_SIZE]; // sequence number + +} tSap_StationMICFailureEvent; +/*Structure to return MAC address of associated stations */ +typedef struct sap_AssocMacAddr_s { + v_MACADDR_t staMac; /*MAC address of Station that is associated*/ + v_U8_t assocId; /*Association ID for the station that is associated*/ + v_U8_t staId; /*Station Id that is allocated to the station*/ + v_U8_t ShortGI40Mhz; + v_U8_t ShortGI20Mhz; + v_U8_t Support40Mhz; + v_U32_t requestedMCRate; + tSirSupportedRates supportedRates; +} tSap_AssocMacAddr, *tpSap_AssocMacAddr; + +/*struct corresponding to SAP_ASSOC_STA_CALLBACK_EVENT */ +typedef struct sap_AssocStaListEvent_s { + VOS_MODULE_ID module; /* module id that was passed in WLANSAP_GetAssocStations API*/ + v_U8_t noOfAssocSta; /* Number of associated stations*/ + tpSap_AssocMacAddr pAssocStas; /*Pointer to pre allocated memory to obtain list of associated + stations passed in WLANSAP_GetAssocStations API*/ +} tSap_AssocStaListEvent; + +typedef struct sap_GetWPSPBCSessionEvent_s { + v_U8_t status; + VOS_MODULE_ID module; /* module id that was passed in WLANSAP_GetAssocStations API*/ + v_U8_t UUID_E[16]; // Unique identifier of the AP. + v_MACADDR_t addr; + eWPSPBCOverlap wpsPBCOverlap; +} tSap_GetWPSPBCSessionEvent; + +typedef struct sap_WPSPBCProbeReqEvent_s { + v_U8_t status; + VOS_MODULE_ID module; /* module id that was passed in WLANSAP_GetAssocStations API*/ + tSirWPSPBCProbeReq WPSPBCProbeReq; +} tSap_WPSPBCProbeReqEvent; + +typedef struct sap_ManagementFrameInfo_s { + tANI_U32 nFrameLength; + tANI_U8 frameType; + tANI_U32 rxChan; //Channel of where packet is received + tANI_U8 *pbFrames; //Point to a buffer contain the beacon, assoc req, assoc rsp frame, in that order + //user needs to use nBeaconLength, nAssocReqLength, nAssocRspLength to desice where + //each frame starts and ends. +} tSap_ManagementFrameInfo; + +typedef struct sap_SendActionCnf_s { + eSapStatus actionSendSuccess; +} tSap_SendActionCnf; + +typedef struct sap_UnknownSTAJoinEvent_s { + v_MACADDR_t macaddr; +} tSap_UnknownSTAJoinEvent; + +typedef struct sap_MaxAssocExceededEvent_s { + v_MACADDR_t macaddr; +} tSap_MaxAssocExceededEvent; + + +/* + This struct will be filled in and passed to tpWLAN_SAPEventCB that is provided during WLANSAP_StartBss call + The event id corresponding to structure in the union is defined in comment next to the structure +*/ + +typedef struct sap_Event_s { + eSapHddEvent sapHddEventCode; + union { + tSap_StartBssCompleteEvent sapStartBssCompleteEvent; /*SAP_START_BSS_EVENT*/ + tSap_StopBssCompleteEvent sapStopBssCompleteEvent; /*SAP_STOP_BSS_EVENT*/ + tSap_StationAssocIndication sapAssocIndication; /*SAP_ASSOC_INDICATION */ + tSap_StationAssocReassocCompleteEvent sapStationAssocReassocCompleteEvent; /*SAP_STA_ASSOC_EVENT, SAP_STA_REASSOC_EVENT*/ + tSap_StationDisassocCompleteEvent sapStationDisassocCompleteEvent;/*SAP_STA_DISASSOC_EVENT*/ + tSap_StationSetKeyCompleteEvent sapStationSetKeyCompleteEvent;/*SAP_STA_SET_KEY_EVENT*/ + tSap_StationDeleteKeyCompleteEvent sapStationDeleteKeyCompleteEvent;/*SAP_STA_DEL_KEY_EVENT*/ + tSap_StationMICFailureEvent sapStationMICFailureEvent; /*SAP_STA_MIC_FAILURE_EVENT */ + tSap_AssocStaListEvent sapAssocStaListEvent; /*SAP_ASSOC_STA_CALLBACK_EVENT */ + tSap_GetWPSPBCSessionEvent sapGetWPSPBCSessionEvent; /*SAP_GET_WPSPBC_SESSION_EVENT */ + tSap_WPSPBCProbeReqEvent sapPBCProbeReqEvent; /*eSAP_WPS_PBC_PROBE_REQ_EVENT */ + tSap_SendActionCnf sapActionCnf; /* eSAP_SEND_ACTION_CNF */ + tSap_UnknownSTAJoinEvent sapUnknownSTAJoin; /* eSAP_UNKNOWN_STA_JOIN */ + tSap_MaxAssocExceededEvent sapMaxAssocExceeded; /* eSAP_MAX_ASSOC_EXCEEDED */ + } sapevt; +} tSap_Event, *tpSap_Event; + + +typedef __ani_attr_pre_packed struct sap_SSID { + v_U8_t length; + v_U8_t ssId[MAX_SSID_LEN]; +} __ani_attr_packed tSap_SSID_t; + +typedef __ani_attr_pre_packed struct sap_SSIDInfo { + tSap_SSID_t ssid; /*SSID of the AP*/ + v_U8_t ssidHidden; /*SSID shouldn't/should be broadcast in probe RSP and beacon*/ +} __ani_attr_packed tSap_SSIDInfo_t; + +typedef struct sap_Config { + tSap_SSIDInfo_t SSIDinfo; + eSapPhyMode SapHw_mode; /* Wireless Mode */ + eSapMacAddrACL SapMacaddr_acl; + v_MACADDR_t accept_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */ + v_BOOL_t ieee80211d; /*Specify if 11D is enabled or disabled*/ + v_BOOL_t protEnabled; /*Specify if protection is enabled or disabled*/ + v_BOOL_t obssProtEnabled; /*Specify if OBSS protection is enabled or disabled*/ + v_MACADDR_t deny_mac[MAX_ACL_MAC_ADDRESS]; /* MAC filtering */ + v_MACADDR_t self_macaddr; //self macaddress or BSSID + + v_U8_t channel; /* Operation channel */ + v_U8_t max_num_sta; /* maximum number of STAs in station table */ + v_U8_t dtim_period; /* dtim interval */ + v_U8_t num_accept_mac; + v_U8_t num_deny_mac; + /* Max ie length 255 * 2(WPA+RSN) + 2 bytes(vendor specific ID) * 2 */ + v_U8_t RSNWPAReqIE[(SIR_MAC_MAX_IE_LENGTH * 2) + 4]; + v_U8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //it is ignored if [0] is 0. + v_U8_t RSNAuthType; + v_U8_t RSNEncryptType; + v_U8_t mcRSNEncryptType; + eSapAuthType authType; + v_BOOL_t privacy; + v_BOOL_t UapsdEnable; + v_BOOL_t fwdWPSPBCProbeReq; + v_U8_t wps_state; // 0 - disabled, 1 - not configured , 2 - configured + + v_U16_t ht_capab; + v_U16_t RSNWPAReqIELength; //The byte count in the pWPAReqIE + + v_U32_t beacon_int; /* Beacon Interval */ + v_U32_t ap_table_max_size; + v_U32_t ap_table_expiration_time; + v_U32_t ht_op_mode_fixed; + tVOS_CON_MODE persona; /*Tells us which persona it is GO or AP for now*/ + +#ifdef WLAN_FEATURE_11W + v_BOOL_t mfpRequired; + v_BOOL_t mfpCapable; +#endif + eCsrBand scanBandPreference; + v_U16_t acsBandSwitchThreshold; + +} tsap_Config_t; + +typedef enum { + eSAP_WPS_PROBE_RSP_IE, + eSAP_WPS_BEACON_IE, + eSAP_WPS_ASSOC_RSP_IE +} eSapWPSIE_CODE; + +typedef struct sSapName { + v_U8_t num_name; + v_U8_t name[MAX_NAME_SIZE]; +} tSapName; + +typedef struct sSapText { + v_U8_t num_text; + v_U8_t text[MAX_TEXT_SIZE]; +} tSapText; + +#define WPS_PROBRSP_VER_PRESENT 0x00000001 +#define WPS_PROBRSP_STATE_PRESENT 0x00000002 +#define WPS_PROBRSP_APSETUPLOCK_PRESENT 0x00000004 +#define WPS_PROBRSP_SELECTEDREGISTRA_PRESENT 0x00000008 +#define WPS_PROBRSP_DEVICEPASSWORDID_PRESENT 0x00000010 +#define WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define WPS_PROBRSP_RESPONSETYPE_PRESENT 0x00000040 +#define WPS_PROBRSP_UUIDE_PRESENT 0x00000080 +#define WPS_PROBRSP_MANUFACTURE_PRESENT 0x00000100 +#define WPS_PROBRSP_MODELNAME_PRESENT 0x00000200 +#define WPS_PROBRSP_MODELNUMBER_PRESENT 0x00000400 +#define WPS_PROBRSP_SERIALNUMBER_PRESENT 0x00000800 +#define WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT 0x00001000 +#define WPS_PROBRSP_DEVICENAME_PRESENT 0x00002000 +#define WPS_PROBRSP_CONFIGMETHODS_PRESENT 0x00004000 +#define WPS_PROBRSP_RF_BANDS_PRESENT 0x00008000 + +typedef struct sap_WPSProbeRspIE_s { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t ResponseType; // Response type + v_U8_t UUID_E[16]; // Unique identifier of the AP. + tSapName Manufacture; + tSapText ModelName; + tSapText ModelNumber; + tSapText SerialNumber; + v_U32_t PrimaryDeviceCategory ; // Device Category ID: 1Computer, 2Input Device, ... + v_U8_t PrimaryDeviceOUI[4] ; // Vendor specific OUI for Device Sub Category + v_U32_t DeviceSubCategory ; // Device Sub Category ID: 1-PC, 2-Server if Device Category ID is computer + tSapText DeviceName; + v_U16_t ConfigMethod; // Configuaration method + v_U8_t RFBand; // RF bands available on the AP +} tSap_WPSProbeRspIE; + +#define WPS_BEACON_VER_PRESENT 0x00000001 +#define WPS_BEACON_STATE_PRESENT 0x00000002 +#define WPS_BEACON_APSETUPLOCK_PRESENT 0x00000004 +#define WPS_BEACON_SELECTEDREGISTRA_PRESENT 0x00000008 +#define WPS_BEACON_DEVICEPASSWORDID_PRESENT 0x00000010 +#define WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT 0x00000020 +#define WPS_BEACON_UUIDE_PRESENT 0x00000080 +#define WPS_BEACON_RF_BANDS_PRESENT 0x00000100 + +typedef struct sap_WPSBeaconIE_s { + v_U32_t FieldPresent; + v_U32_t Version; // Version. 0x10 = version 1.0, 0x11 = etc. + v_U32_t wpsState; // 1 = unconfigured, 2 = configured. + v_BOOL_t APSetupLocked; // Must be included if value is TRUE + v_BOOL_t SelectedRegistra; //BOOL: indicates if the user has recently activated a Registrar to add an Enrollee. + v_U16_t DevicePasswordID; // Device Password ID + v_U16_t SelectedRegistraCfgMethod; // Selected Registrar config method + v_U8_t UUID_E[16]; // Unique identifier of the AP. + v_U8_t RFBand; // RF bands available on the AP +} tSap_WPSBeaconIE; + +#define WPS_ASSOCRSP_VER_PRESENT 0x00000001 +#define WPS_ASSOCRSP_RESPONSETYPE_PRESENT 0x00000002 + +typedef struct sap_WPSAssocRspIE_s { + v_U32_t FieldPresent; + v_U32_t Version; + v_U8_t ResposeType; +} tSap_WPSAssocRspIE; + +typedef struct sap_WPSIE_s { + eSapWPSIE_CODE sapWPSIECode; + union { + tSap_WPSProbeRspIE sapWPSProbeRspIE; /*WPS Set Probe Respose IE*/ + tSap_WPSBeaconIE sapWPSBeaconIE; /*WPS Set Beacon IE*/ + tSap_WPSAssocRspIE sapWPSAssocRspIE; /*WPS Set Assoc Response IE*/ + } sapwpsie; +} tSap_WPSIE, *tpSap_WPSIE; + +#ifdef WLANTL_DEBUG +#define MAX_RATE_INDEX 136 +#define MAX_NUM_RSSI 100 +#define MAX_RSSI_INTERVAL 5 +#endif + +typedef struct sap_SoftapStats_s { + v_U32_t txUCFcnt; + v_U32_t txMCFcnt; + v_U32_t txBCFcnt; + v_U32_t txUCBcnt; + v_U32_t txMCBcnt; + v_U32_t txBCBcnt; + v_U32_t rxUCFcnt; + v_U32_t rxMCFcnt; + v_U32_t rxBCFcnt; + v_U32_t rxUCBcnt; + v_U32_t rxMCBcnt; + v_U32_t rxBCBcnt; + v_U32_t rxBcnt; + v_U32_t rxBcntCRCok; + v_U32_t rxRate; +#ifdef WLANTL_DEBUG + v_U32_t pktCounterRateIdx[MAX_RATE_INDEX]; + v_U32_t pktCounterRssi[MAX_NUM_RSSI]; +#endif +} tSap_SoftapStats, *tpSap_SoftapStats; + +#ifdef FEATURE_WLAN_CH_AVOID +/* Store channel safty information */ +typedef struct +{ + v_U16_t channelNumber; + v_BOOL_t isSafe; +} safeChannelType; +#endif /* FEATURE_WLAN_CH_AVOID */ + +int sapSetPreferredChannel(tANI_U8* ptr); +void sapCleanupChannelList(void); + +/*========================================================================== + FUNCTION WLANSAP_Set_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to set WPS IE. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pWPSIE: tSap_WPSIE structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Set_WpsIe +( + v_PVOID_t pvosGCtx, tSap_WPSIE *pWPSIe +); + +/*========================================================================== + FUNCTION WLANSAP_Update_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to start WPS session. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Update_WpsIe +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Stop_Wps + + DESCRIPTION + This api function provides for Ap App/HDD to stop WPS session. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Stop_Wps +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Get_WPS_State + + DESCRIPTION + This api function provides for Ap App/HDD to get WPS state. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + OUT +pbWPSState: Pointer to variable to indicate if it is in WPS Registration state + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Get_WPS_State +( + v_PVOID_t pvosGCtx, v_BOOL_t * pbWPSState +); + +/*---------------------------------------------------------------------------- + * Opaque SAP handle Type Declaration + * -------------------------------------------------------------------------*/ + +typedef v_PVOID_t tSapHandle, *ptSapHandle; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION WLANSAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). SAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Open +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Start +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in SAP, before close. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Stop +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. SAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Close +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION (*tpWLAN_SAPEventCB) + + DESCRIPTION + Implements the callback for ALL asynchronous events. + Including Events resulting from: + * Start BSS + * Stop BSS,... + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSapEvent: pointer to the union of "Sap Event" structures. This now encodes ALL event types. + Including Command Complete and Command Status + pUsrContext : pUsrContext parameter that was passed to sapStartBss + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to pSapEvent is NULL + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +typedef VOS_STATUS (*tpWLAN_SAPEventCB)( tpSap_Event pSapEvent, v_PVOID_t pUsrContext); + + + +/*========================================================================== + FUNCTION WLANSAP_getState + + DESCRIPTION + This api returns the current SAP state to the caller. + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + + RETURN VALUE + Returns the SAP FSM state. +============================================================================*/ + +v_U8_t WLANSAP_getState ( v_PVOID_t pvosGCtx); + +/*========================================================================== + FUNCTION WLANSAP_get_sessionId + + DESCRIPTION + This api returns the current SAP sessionId to the caller. + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + v_U8_t : Pointer to sessionID + + RETURN VALUE + VOS_STATUS_SUCCESS on success. + + VOS_STATUS_E_INVAL: Pointer to SAP cb is NULL ; access would cause a page + fault +============================================================================*/ +VOS_STATUS WLANSAP_get_sessionId +( + v_PVOID_t pvosGCtx, v_U8_t *sessionId +); +/*========================================================================== + FUNCTION WLANSAP_StartBss + + DESCRIPTION + This api function provides SAP FSM event eWLAN_SAP_HDD_PHYSICAL_LINK_CREATE for +starting AP BSS + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pConfig: Pointer to configuration structure passed down from HDD(HostApd for Android) +hdd_SapEventCallback: Callback function in HDD called by SAP to inform HDD about SAP results +usrDataForCallback: Parameter that will be passed back in all the SAP callback events. + + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StartBss +( + v_PVOID_t pvosGCtx, + tpWLAN_SAPEventCB pSapEventCallback, + tsap_Config_t *pConfig, v_PVOID_t pUsrContext +); + +/*========================================================================== + FUNCTION WLANSAP_SetMacACL + + DESCRIPTION + This api function provides SAP to set mac list entry in accept list as well + as deny list + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pConfig: Pointer to configuration structure passed down from + HDD(HostApd for Android) + + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetMacACL +( + v_PVOID_t pvosGCtx, + tsap_Config_t *pConfig +); + +/*========================================================================== + FUNCTION WLANSAP_Stop + + DESCRIPTION + This api function provides SAP FSM event eWLAN_SAP_HDD_PHYSICAL_LINK_DISCONNECT for +stopping BSS + + DEPENDENCIES + NA. + + PARAMETERS W + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StopBss +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_DisassocSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated disassociation of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pPeerStaMac : Mac address of the station to disassociate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DisassocSta +( + v_PVOID_t pvosGCtx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_U8_t *pPeerStaMac +#else + v_U8_t *pPeerStaMac +#endif +); + +/*========================================================================== + FUNCTION WLANSAP_DeauthSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated deauthentication of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pDelStaParams : Pointer to parameters of the station to + deauthenticate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DeauthSta +( + v_PVOID_t pvosGCtx, + struct tagCsrDelStaParams *pDelStaParams +); + +/*========================================================================== + FUNCTION WLANSAP_SetChannelRange + + DESCRIPTION + This api function sets the range of channels for SoftAP. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + startChannel : start channel + endChannel : End channel + operatingBand : Operating band (2.4GHz/5GHz) + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetChannelRange(tHalHandle hHal,v_U8_t startChannel, v_U8_t endChannel, + eSapOperatingBand operatingBand); + +/*========================================================================== + FUNCTION WLANSAP_SetKeySta + + DESCRIPTION + This api function provides for Ap App/HDD to delete key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSetKeyInfo: tCsrRoamSetKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetKeySta +( + v_PVOID_t pvosGCtx, tCsrRoamSetKey *pSetKeyInfo +); + +/*========================================================================== + FUNCTION WLANSAP_DelKeySta + + DESCRIPTION + This api function provides for Ap App/HDD to delete key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSetKeyInfo: tCsrRoamSetKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DelKeySta +( + v_PVOID_t pvosGCtx, tCsrRoamRemoveKey *pDelKeyInfo +); + + + +/*========================================================================== + FUNCTION WLANSAP_GetAssocStations + + DESCRIPTION + This api function is used to probe the list of associated stations from various modules of CORE stack + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +mod: Module from whom list of associtated stations is supposed to be probed. If an invalid module is passed +then by default VOS_MODULE_ID_PE will be probed + IN/OUT +pNoOfAssocStas:- Number of associated stations that are known to the module specified in mod parameter +pAssocStas: Pointer to list of associated stations that are known to the module specified in mod parameter +NOTE:- The memory for this list will be allocated by the caller of this API + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetAssocStations +( + v_PVOID_t pvosGCtx, VOS_MODULE_ID module, + tpSap_AssocMacAddr pAssocStas +); +/*========================================================================== + FUNCTION WLANSAP_RemoveWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to remove an entry from session session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pRemoveMac: pointer to v_MACADDR_t for session MAC address that needs to be removed from wps session + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + VOS_STATUS_E_FAULT: Session is not dectected. The parameter is function not valid. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_RemoveWpsSessionOverlap + +( + v_PVOID_t pvosGCtx, + v_MACADDR_t pRemoveMac +); + +/*========================================================================== + FUNCTION WLANSAP_getWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to get WPS session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSessionMac: pointer to v_MACADDR_t for session MAC address +uuide: Pointer to 16 bytes array for session UUID_E + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + VOS_STATUS_E_FAULT: Overlap is dectected. The parameter is function not valid. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_getWpsSessionOverlap +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_SetCounterMeasure + + DESCRIPTION + This api function is used to disassociate all the stations and prevent + association for any other station.Whenever Authenticator receives 2 mic failures + within 60 seconds, Authenticator will enable counter measure at SAP Layer. + Authenticator will start the 60 seconds timer. Core stack will not allow any + STA to associate till HDD disables counter meassure. Core stack shall kick out all the + STA which are currently associated and DIASSOC Event will be propogated to HDD for + each STA to clean up the HDD STA table.Once the 60 seconds timer expires, Authenticator + will disable the counter meassure at core stack. Now core stack can allow STAs to associate. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +bEnable: If TRUE than all stations will be disassociated and no more will be allowed to associate. If FALSE than CORE +will come out of this state. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetCounterMeasure +( + v_PVOID_t pvosGCtx, v_BOOL_t bEnable +); + +/*========================================================================== + FUNCTION WLANSap_getstationIE_information + + DESCRIPTION + This api function provides for Ap App/HDD to retrive the WPA and RSNIE of a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pLen : length of WPARSN elment IE where it would be copied + pBuf : buf to copy the WPARSNIe + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSap_getstationIE_information(v_PVOID_t pvosGCtx, + v_U32_t *pLen, + v_U8_t *pBuf); + + +VOS_STATUS +WLANSAP_getWpsSessionOverlap +( + v_PVOID_t pvosGCtx +); +/*========================================================================== + FUNCTION WLANSAP_ClearACL + + DESCRIPTION + This api function removes all the entries in both accept and deny lists. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_ClearACL +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANSAP_SetMode + + DESCRIPTION + This api is used to set mode for ACL + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetMode +( + v_PVOID_t pvosGCtx, + v_U32_t mode +); + +/*========================================================================== + FUNCTION WLANSAP_ModifyACL + + DESCRIPTION + This api function provides for Ap App/HDD to add/remove mac addresses from black/white lists (ACLs). + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pPeerStaMac : MAC address to be added or removed + listType : add/remove to be done on black or white list + cmd : Are we doing to add or delete a mac addr from an ACL. + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_ModifyACL +( + v_PVOID_t pvosGCtx, + v_U8_t *pPeerStaMac, + eSapACLType listType, + eSapACLCmdType cmd +); + +/*========================================================================== + FUNCTION WLANSAP_Set_WPARSNIes + + DESCRIPTION + This api function provides for Ap App/HDD to set AP WPA and RSN IE in its beacon and probe response. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pWPARSNIEs: buffer to the WPA/RSN IEs + WPARSNIEsLen: length of WPA/RSN IEs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Set_WPARSNIes(v_PVOID_t pvosGCtx, v_U8_t *pWPARSNIEs, v_U32_t WPARSNIEsLen); + +/*========================================================================== + FUNCTION WLANSAP_GetStatistics + + DESCRIPTION + This api function provides for Ap App/HDD to get TL statistics for all stations of Soft AP. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + bReset: If set TL statistics will be cleared after reading + OUT + statBuf: Buffer to get the statistics + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_GetStatistics(v_PVOID_t pvosGCtx, tSap_SoftapStats *statBuf, v_BOOL_t bReset); + +/*========================================================================== + + FUNCTION WLANSAP_SendAction + + DESCRIPTION + This api function provides to send action frame sent by upper layer. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pBuf: Pointer of the action frame to be transmitted + len: Length of the action frame + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_SendAction( v_PVOID_t pvosGCtx, const tANI_U8 *pBuf, + tANI_U32 len, tANI_U16 wait ); + +/*========================================================================== + + FUNCTION WLANSAP_RemainOnChannel + + DESCRIPTION + This api function provides to set Remain On channel on specified channel + for specified duration. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + channel: Channel on which driver has to listen + duration: Duration for which driver has to listen on specified channel + callback: Callback function to be called once Listen is done. + pContext: Context needs to be called in callback function. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RemainOnChannel( v_PVOID_t pvosGCtx, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext ); + +/*========================================================================== + + FUNCTION WLANSAP_CancelRemainOnChannel + + DESCRIPTION + This api cancel previous remain on channel request. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_CancelRemainOnChannel( v_PVOID_t pvosGCtx ); + + +/*========================================================================== + + FUNCTION WLANSAP_RegisterMgmtFrame + + DESCRIPTION + HDD use this API to register specified type of frame with CORE stack. + On receiving such kind of frame CORE stack should pass this frame to HDD + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + frameType: frameType that needs to be registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, + tANI_U8* matchData, tANI_U16 matchLen ); + +/*========================================================================== + + FUNCTION WLANSAP_DeRegisterMgmtFrame + + DESCRIPTION + This API is used to deregister previously registered frame. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + frameType: frameType that needs to be De-registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_DeRegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, + tANI_U8* matchData, tANI_U16 matchLen ); + + +/*========================================================================== + FUNCTION WLANSAP_PopulateDelStaParams + + DESCRIPTION + This API is used to populate del station parameters + DEPENDENCIES + NA. + + PARAMETERS + IN + mac: pointer to peer mac address. + reason_code: Reason code for the disassoc/deauth. + subtype: subtype points to either disassoc/deauth frame. + pDelStaParams: address where parameters to be populated. + + RETURN VALUE NONE + + SIDE EFFECTS +============================================================================*/ + +void WLANSAP_PopulateDelStaParams(const v_U8_t *mac, + v_U16_t reason_code, + v_U8_t subtype, + struct tagCsrDelStaParams *pDelStaParams); + +#ifdef __cplusplus + } +#endif + + +#endif /* #ifndef WLAN_QCT_WLANSAP_H */ + diff --git a/drivers/staging/prima/CORE/SAP/src/sapApiLinkCntl.c b/drivers/staging/prima/CORE/SAP/src/sapApiLinkCntl.c new file mode 100644 index 000000000000..a0234c68eac7 --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapApiLinkCntl.c @@ -0,0 +1,1600 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p A p i L i n k C n t l . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + Link Control functions. + + The functions externalized by this module are to be called ONLY by other + WLAN modules (HDD) + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/c/Dropbox/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_SAP_PAL/CORE/SAP/src/sapApiLinkCntl.c,v 1.7 2008/12/18 19:44:11 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-03-15 Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_trace.h" +// Pick up the CSR callback definition +#include "csrApi.h" +#include "sme_Api.h" +// SAP Internal API header file +#include "sapInternal.h" +#ifdef WLAN_FEATURE_AP_HT40_24G +#include "vos_utils.h" +#endif + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define SAP_DEBUG + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION sapSetOperatingChannel() + + DESCRIPTION + Set SAP Operating Channel + + DEPENDENCIES + NA. + + PARAMETERS + + IN + *pContext : The second context pass in for the caller (sapContext) + operChannel : SAP Operating Channel + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +void sapSetOperatingChannel(ptSapContext psapContext, v_U8_t operChannel) +{ + v_U8_t i = 0; + v_U32_t event; + tHalHandle hHal = NULL; + uint32_t operating_band = 0; + + hHal = VOS_GET_HAL_CB(psapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "hHal is NULL in %s", __func__); + return; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("SAP Channel : %d"), psapContext->channel); + + if (operChannel == SAP_CHANNEL_NOT_SELECTED) +#ifdef SOFTAP_CHANNEL_RANGE + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("No suitable channel selected")); + + if ( eCSR_BAND_ALL == psapContext->scanBandPreference || + psapContext->allBandScanned == eSAP_TRUE) + { + if(psapContext->channelList != NULL) + { + psapContext->channel = SAP_CHANNEL_NOT_SELECTED; + for ( i = 0 ; i < psapContext->numofChannel ; i++) + { + if (NV_CHANNEL_ENABLE == + vos_nv_getChannelEnabledState(psapContext->channelList[i])) + { + psapContext->channel = psapContext->channelList[i]; + break; + } + } + } + + /* + * In case if channel is not selected then channel + * to be selected based on band configured in .ini + */ + if (!psapContext->channel) + { + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + &operating_band); + if (operating_band == eSAP_RF_SUBBAND_5_LOW_GHZ || + operating_band == eSAP_RF_SUBBAND_5_MID_GHZ || + operating_band == eSAP_RF_SUBBAND_5_HIGH_GHZ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Default channel selection from band %d"), + operating_band); + + (operating_band == eSAP_RF_SUBBAND_5_LOW_GHZ) ? + (psapContext->channel = + SAP_DEFAULT_LOW_5GHZ_CHANNEL) : + (operating_band == eSAP_RF_SUBBAND_5_MID_GHZ) ? + (psapContext->channel = + SAP_DEFAULT_MID_5GHZ_CHANNEL) : + (operating_band == eSAP_RF_SUBBAND_5_HIGH_GHZ) ? + (psapContext->channel = + SAP_DEFAULT_HIGH_5GHZ_CHANNEL) : 0; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("channel selected to start bss %d"), + psapContext->channel); + } + else + { + psapContext->channel = SAP_DEFAULT_24GHZ_CHANNEL; + } + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Has scan band preference")); + if (eCSR_BAND_24 == psapContext->currentPreferredBand) + psapContext->currentPreferredBand = eCSR_BAND_5G; + else + psapContext->currentPreferredBand = eCSR_BAND_24; + + psapContext->allBandScanned = eSAP_TRUE; + //go back to DISCONNECT state, scan next band + psapContext->sapsMachine = eSAP_DISCONNECTED; + event = eSAP_CHANNEL_SELECTION_FAILED; + } + } +#else + psapContext->channel = SAP_DEFAULT_24GHZ_CHANNEL; +#endif + else + { + psapContext->channel = operChannel; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("SAP Channel : %d"), psapContext->channel); +} + +#ifdef WLAN_FEATURE_AP_HT40_24G +/*========================================================================== + FUNCTION sap_ht2040_timer_cb() + + DESCRIPTION + SAP HT40 timer CallBack, Once this function execute it will move SAP + from HT20 to HT40 + + DEPENDENCIES + NA. + + PARAMETERS + + IN + usrDataForCallback : The second context pass in for the caller (sapContext) + + RETURN VALUE + SIDE EFFECTS +============================================================================*/ +void sap_ht2040_timer_cb(v_PVOID_t usrDataForCallback) +{ + v_U8_t cbMode; + tHalHandle hHal; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + ptSapContext sapContext = (ptSapContext)usrDataForCallback; + eSapPhyMode sapPhyMode; + + hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, + sapContext->pvosGCtx); + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + FL("Invalid hHal")); + return; + } + + cbMode = sme_GetChannelBondingMode24G(hHal); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Current Channel bonding : %d"), cbMode); + + if(cbMode) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + FL("Already in HT40 Channel bonding : %d"), cbMode); + return; + } + + sapPhyMode = + sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode); + + sme_SelectCBMode(hHal, sapPhyMode, sapContext->channel); + + cbMode = sme_GetChannelBondingMode24G(hHal); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Selected Channel bonding : %d"), cbMode); + + if(cbMode) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Move SAP from HT20 to HT40")); + + if (cbMode == eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY) + cbMode = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + else if (cbMode == eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY) + cbMode = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + + halStatus = sme_SetHT2040Mode(hHal, sapContext->sessionId, cbMode); + + if (halStatus == eHAL_STATUS_FAILURE ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to change HT20/40 mode")); + } + } +} + +/*========================================================================== + FUNCTION sapCheckHT2040CoexAction() + + DESCRIPTION + Check 20/40 Coex Info + + DEPENDENCIES + NA. + + PARAMETERS + + IN + ptSapContext : The second context pass in for the caller (sapContext) + tpSirHT2040CoexInfoInd : 20/40 Coex info + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +void sapCheckHT2040CoexAction(ptSapContext psapCtx, + tpSirHT2040CoexInfoInd pSmeHT2040CoexInfoInd) +{ + v_U8_t i; + v_U8_t isHT40Allowed = 1; + tHalHandle hHal; + v_U8_t cbMode; + eHalStatus halStatus; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + unsigned int delay; + + /* tHalHandle */ + hHal = VOS_GET_HAL_CB(psapCtx->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("In invalid hHal")); + return; + } + + // Get Channel Bonding Mode + cbMode = sme_GetChannelBondingMode24G(hHal); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Current Channel Bonding Mode: %d"), + cbMode); + + if (pSmeHT2040CoexInfoInd->HT20MHzBssWidthReq) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("20 MHz BSS width request bit is " + "set in 20/40 coexistence info")); + isHT40Allowed = 0; + } + + if (pSmeHT2040CoexInfoInd->HT40MHzIntolerant) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("40 MHz intolerant bit is set in " + "20/40 coexistence info")); + isHT40Allowed = 0; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Total Reported 20/40 BSS Intolerant Channels :%d"), + pSmeHT2040CoexInfoInd->channel_num); + + if ((0 == psapCtx->affected_start) && (0 == psapCtx->affected_end)) + { + if (!sapGet24GOBSSAffectedChannel(hHal, psapCtx)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to get OBSS Affected Channel " + "Range for Channel: %d"), psapCtx->channel); + return; + } + /* Update to Original Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(hHal, cbMode); + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("OBSS Affected Channel Range : [%d %d]"), + psapCtx->affected_start, psapCtx->affected_end); + + if (pSmeHT2040CoexInfoInd->channel_num) + { + for(i = 0; i < pSmeHT2040CoexInfoInd->channel_num; i++) + { + if ((pSmeHT2040CoexInfoInd->HT2040BssIntoChanReport[i] > + psapCtx->affected_start) + && (pSmeHT2040CoexInfoInd->HT2040BssIntoChanReport[i] < + psapCtx->affected_end)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("BSS Intolerant Channel: %d within OBSS" + " Affected Channel Range : [%d %d]"), + pSmeHT2040CoexInfoInd->HT2040BssIntoChanReport[i], + psapCtx->affected_start, psapCtx->affected_end); + isHT40Allowed = 0; + break; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Reported 20/40 BSS Intolerant Channel:%d " + " is Out of OBSS Affected Channel Range : [%d %d]"), + pSmeHT2040CoexInfoInd->HT2040BssIntoChanReport[i], + psapCtx->affected_start, psapCtx->affected_end); + } + } + + if (!isHT40Allowed) + { + if(cbMode) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Move SAP from HT40 to HT20")); + + halStatus = sme_SetHT2040Mode(hHal, psapCtx->sessionId, + PHY_SINGLE_CHANNEL_CENTERED); + if (halStatus == eHAL_STATUS_FAILURE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to change HT20/40 mode")); + return; + } + + /* Disable Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(hHal, + PHY_SINGLE_CHANNEL_CENTERED); + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("SAP is Already in HT20")); + + if ((!sapCheckHT40SecondaryIsNotAllowed(psapCtx)) + && (!psapCtx->numHT40IntoSta)) + { + /* Stop Previous Running HT20/40 Timer & Start timer + with (OBSS TransitionDelayFactor * obss interval) + delay after time out move AP from HT20 -> HT40 + mode + */ + if (VOS_TIMER_STATE_RUNNING == psapCtx->sap_HT2040_timer.state) + { + vosStatus = vos_timer_stop(&psapCtx->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + + delay = psapCtx->ObssScanInterval * psapCtx->ObssTransitionDelayFactor; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Start HT20/40 itransition" + " timer (%d sec)"), delay); + + vosStatus = vos_timer_start( &psapCtx->sap_HT2040_timer, + (delay * 1000)); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Start HT20/40 timer")); + } + } + return; +} + +/*========================================================================== + FUNCTION sapCheckFor20MhzObss() + + DESCRIPTION + Check 20 MHz Overlapping BSS + + DEPENDENCIES + NA. + + PARAMETERS + + IN + channelNumber : Peer BSS Operating Channel + tpSirProbeRespBeacon: Pointer to Beacon Struct + ptSapContext: Pointer to SAP Context + + RETURN VALUE + v_U8_t : Success - Found OBSS BSS, Fail - zero + + SIDE EFFECTS +============================================================================*/ + +eHalStatus sapCheckFor20MhzObss(v_U8_t channelNumber, + tpSirProbeRespBeacon pBeaconStruct, + ptSapContext psapCtx) +{ + + v_U16_t secondaryChannelOffset; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("channelNumber: %d BSS: %s"), channelNumber, + pBeaconStruct->ssId.ssId); + + if (channelNumber < psapCtx->affected_start + || channelNumber > psapCtx->affected_end) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("channelNumber: %d out of Affetced Channel Range: [%d,%d]"), + channelNumber, psapCtx->affected_start, + psapCtx->affected_end); + return halStatus; + } + + if (!pBeaconStruct->HTCaps.present) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Found overlapping legacy BSS: %s on Channel : %d"), + pBeaconStruct->ssId.ssId, channelNumber); + halStatus = eHAL_STATUS_FAILURE; + return halStatus; + } + + if (pBeaconStruct->HTInfo.present) + { + secondaryChannelOffset = pBeaconStruct->HTInfo.secondaryChannelOffset; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("BSS: %s secondaryChannelOffset: %d on Channel : %d"), + pBeaconStruct->ssId.ssId, secondaryChannelOffset, + channelNumber); + if (PHY_SINGLE_CHANNEL_CENTERED == secondaryChannelOffset) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Found overlapping 20 MHz HT BSS: %s on Channel : %d"), + pBeaconStruct->ssId.ssId, channelNumber); + halStatus = eHAL_STATUS_FAILURE; + return halStatus; + } + } + return halStatus; +} + +/*========================================================================== + FUNCTION sapGetPrimarySecondaryChannelOfBss() + + DESCRIPTION + Get Primary & Seconary Channel of Overlapping BSS + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tpSirProbeRespBeacon: Pointer to Beacon Struct + pri_chan : Primary Operating Channel + sec_chan : Seconary Operating Channel + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +void sapGetPrimarySecondaryChannelOfBss(tpSirProbeRespBeacon pBeaconStruct, + v_U32_t *pri_chan, v_U32_t *sec_chan) +{ + v_U16_t secondaryChannelOffset; + *pri_chan = 0; + *sec_chan = 0; + + if (pBeaconStruct->HTInfo.present) + { + *pri_chan = pBeaconStruct->HTInfo.primaryChannel; + secondaryChannelOffset = pBeaconStruct->HTInfo.secondaryChannelOffset; + if (PHY_DOUBLE_CHANNEL_LOW_PRIMARY == secondaryChannelOffset) + *sec_chan = *pri_chan + 4; + else if (PHY_DOUBLE_CHANNEL_HIGH_PRIMARY == secondaryChannelOffset) + *sec_chan = *pri_chan - 4; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("BSS Primary & Secondary Channel : %d %d "), + *pri_chan, *sec_chan); +} + +/*========================================================================== + FUNCTION sapCheckHT40SecondaryIsNotAllowed() + + DESCRIPTION + Check HT40 Channel Secondary is Allowed + + DEPENDENCIES + NA. + + PARAMETERS + + IN + ptSapContext: Pointer to SAP Context + + RETURN VALUE + v_U8_t : Success - HT40 Allowed in Selected Channale Pair + Fail - HT40 Not Allowed + + SIDE EFFECTS +============================================================================*/ + +eHalStatus sapCheckHT40SecondaryIsNotAllowed(ptSapContext psapCtx) +{ + v_U8_t count; + v_U8_t fValidChannel = 0; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; +#ifdef FEATURE_WLAN_CH_AVOID + int i; + v_U16_t unsafeChannelList[NUM_20MHZ_RF_CHANNELS]; + v_U16_t unsafeChannelCount; +#endif /* FEATURE_WLAN_CH_AVOID */ + + /* Verify that HT40 secondary channel is an allowed 20 MHz + * channel */ + for (count = RF_CHAN_1; count <= RF_CHAN_14; count++) + { + if ((regChannels[count].enabled) + && (rfChannels[count].channelNum == psapCtx->sap_sec_chan)) + { + fValidChannel = TRUE; + break; + } + } + +#ifdef FEATURE_WLAN_CH_AVOID + /* Get unsafe cahnnel list from cached location */ + vos_get_wlan_unsafe_channel(unsafeChannelList, + sizeof(unsafeChannelList), + &unsafeChannelCount); + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Unsafe Channel count %d" + " SAP Secondary Channel: %d"), + unsafeChannelCount, psapCtx->sap_sec_chan); + + for (i = 0; i < unsafeChannelCount; i++) + { + if ((psapCtx->sap_sec_chan == unsafeChannelList[i])) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Unsafe Channel %d SAP Secondary Channel: %d"), + unsafeChannelList[i], psapCtx->sap_sec_chan); + fValidChannel = FALSE; + break; + } + } +#endif /* FEATURE_WLAN_CH_AVOID */ + + if (!fValidChannel) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("HT40 In Secondary Channel : %d not allowed"), + psapCtx->sap_sec_chan); + + halStatus = eHAL_STATUS_FAILURE; + return halStatus; + } + + return halStatus; +} + +/*========================================================================== + FUNCTION sapGet24GOBSSAffectedChannel() + + DESCRIPTION + Get OBSS Affected Channel Range + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tHalHandle : tHalHandle passed in with Affected Channel + ptSapContext: Pointer to SAP Context + + RETURN VALUE + v_U8_t : Success - Able to get AffectedChannel + Fail - Fail to get AffectedChannel + + SIDE EFFECTS +============================================================================*/ + +eHalStatus sapGet24GOBSSAffectedChannel(tHalHandle halHandle, + ptSapContext psapCtx) +{ + + v_U8_t cbMode; + v_U32_t pri_freq, sec_freq; + v_U32_t affected_start_freq, affected_end_freq; + eSapPhyMode sapPhyMode; + eHalStatus halStatus; + + pri_freq = vos_chan_to_freq(psapCtx->channel); + + sapPhyMode = + sapConvertSapPhyModeToCsrPhyMode(psapCtx->csrRoamProfile.phyMode); + + sme_SelectCBMode(halHandle, sapPhyMode, psapCtx->channel); + + cbMode = sme_GetChannelBondingMode24G(halHandle); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Selected Channel bonding : %d"), cbMode); + + if (cbMode == eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY) + sec_freq = pri_freq - 20; + else if (cbMode == eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY) + sec_freq = pri_freq + 20; + else + sec_freq = eCSR_INI_SINGLE_CHANNEL_CENTERED; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Primary Freq : %d MHz Secondary Freq : %d MHz"), + pri_freq, sec_freq); + + if (sec_freq) + { + /* As per 802.11 Std, Section 10.15.3.2 */ + affected_start_freq = (pri_freq + sec_freq) / 2 - 25; + affected_end_freq = (pri_freq + sec_freq) / 2 + 25; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Affected Start Freq: %d MHz Affected End Freq : %d MHz"), + affected_start_freq, affected_end_freq); + + psapCtx->affected_start = vos_freq_to_chan(affected_start_freq); + + /* As there is no channel availabe for 2397 & 2402 Frequency + * Hence taking valid channel 1 (Freq 2412) here + */ + if (affected_start_freq < 2412) + psapCtx->affected_start = 1; + + psapCtx->affected_end = vos_freq_to_chan(affected_end_freq); + + /* As there is no channel availabe for 2477 & 2482 Frequency + * Hence taking lower channel 13 (Freq 2472) here. + */ + if ((2477 == (affected_end_freq)) || (2482 == affected_end_freq)) + { + psapCtx->affected_end = 13; + } + else if (2487 == affected_end_freq) + { + /* As there is no channel availabe for 2487 Frequency + * Hence taking lower channel 14 (Freq 2484) here. + */ + psapCtx->affected_end = 14; + } + + psapCtx->sap_sec_chan = vos_freq_to_chan(sec_freq); + + halStatus = eHAL_STATUS_SUCCESS; + return halStatus; + } + else + { + psapCtx->affected_start = 0; + psapCtx->affected_end = 0; + psapCtx->sap_sec_chan = 0; + halStatus = eHAL_STATUS_FAILURE; + return halStatus; + } +} + +/*========================================================================== + FUNCTION sapCheck40Mhz24G + + DESCRIPTION + Check HT40 is possible in 2.4GHz mode + + DEPENDENCIES + NA. + + PARAMETERS + + IN + halHandle : Pointer to HAL handle + ptSapContext : Pointer to SAP Context + pResult : Pointer to tScanResultHandle + + RETURN VALUE + v_U8_t : Success - HT40 Possible, Fail - zero + + SIDE EFFECTS +============================================================================*/ + +eHalStatus sapCheck40Mhz24G(tHalHandle halHandle, ptSapContext psapCtx, + tScanResultHandle pResult) +{ + v_U32_t pri_chan, sec_chan; + v_U32_t ieLen = 0; + v_U8_t channelNumber = 0; + tSirProbeRespBeacon *pBeaconStruct; + tCsrScanResultInfo *pScanResult; + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if ( (0 == psapCtx->affected_start) && (0 == psapCtx->affected_end) + && (0 == psapCtx->sap_sec_chan)) + { + if (eHAL_STATUS_SUCCESS != + sapGet24GOBSSAffectedChannel(halHandle, psapCtx)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to get OBSS Affected Channel Range for Channel: %d"), + psapCtx->channel); + return halStatus; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("40 MHz affected channel range: [%d,%d] MHz"), + psapCtx->affected_start, psapCtx->affected_end); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("SAP Primary & Secondary Channel : [%d,%d] MHz"), + psapCtx->channel, psapCtx->sap_sec_chan); + + pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pBeaconStruct ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Unable to allocate memory ")); + return halStatus; + } + + /* Check neighboring BSSes from scan result to see whether 40 MHz is + * allowed per IEEE Std 802.11-2012, 10.15.3.2 */ + pScanResult = sme_ScanResultGetFirst(halHandle, pResult); + + while (pScanResult) + { + + /* if the Beacon has channel ID, use it other wise we will + * rely on the channelIdSelf + */ + if(pScanResult->BssDescriptor.channelId == 0) + channelNumber = pScanResult->BssDescriptor.channelIdSelf; + else + channelNumber = pScanResult->BssDescriptor.channelId; + + if (channelNumber > SIR_11B_CHANNEL_END) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("channelNumber: %d BSS: %s"), + channelNumber, pBeaconStruct->ssId.ssId); + goto NextResult; + } + + if ((pScanResult->BssDescriptor.ieFields != NULL)) + { + ieLen = GET_IE_LEN_IN_BSS(pScanResult->BssDescriptor.length); + vos_mem_set((tANI_U8 *) pBeaconStruct, + sizeof(tSirProbeRespBeacon), 0); + + if ((eSIR_SUCCESS == sirParseBeaconIE(pMac, pBeaconStruct, + (tANI_U8 *)( pScanResult->BssDescriptor.ieFields), ieLen))) + { + /* Check Peer BSS is HT20 or Legacy AP */ + if (eHAL_STATUS_SUCCESS != + sapCheckFor20MhzObss(channelNumber, pBeaconStruct, + psapCtx)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Overlapping 20 MHz BSS is found")); + vos_mem_free(pBeaconStruct); + return halStatus; + } + + sapGetPrimarySecondaryChannelOfBss(pBeaconStruct, + &pri_chan, &sec_chan); + + /* Check peer BSS Operating channel is not within OBSS affected + * channel range + */ + if ((pri_chan < psapCtx->affected_start + || pri_chan > psapCtx->affected_end) + && (sec_chan < psapCtx->affected_start + || sec_chan > psapCtx->affected_end)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Peer BSS: %s Primary & Secondary Channel [%d %d]" + "is out of affected Range: [%d %d]"), + pBeaconStruct->ssId.ssId, pri_chan, sec_chan, + psapCtx->affected_start, psapCtx->affected_end); + goto NextResult; /* not within affected channel range */ + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Neighboring BSS: %s Primary & Secondary Channel [%d %d]"), + pBeaconStruct->ssId.ssId, pri_chan, sec_chan); + + if (sec_chan) + { + /* Peer BSS is HT40 capable then check peer BSS + * primary & secondary channel with SAP + * Primary & Secondary channel. + */ + if ((psapCtx->channel != pri_chan) + || (psapCtx->sap_sec_chan != sec_chan)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("40 MHz Pri/Sec channel : [%d %d]" + " missmatch with BSS: %s" + " Pri/Sec channel : [%d %d]"), + psapCtx->channel, psapCtx->sap_sec_chan, + pBeaconStruct->ssId.ssId, pri_chan, sec_chan); + vos_mem_free(pBeaconStruct); + return halStatus; + } + } + + if (pBeaconStruct->HTCaps.present) + { + /* Check Peer BSS HT capablity has 40MHz Intolerant bit */ + if (pBeaconStruct->HTCaps.stbcControlFrame) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Found BSS: %s with 40 MHz" + "Intolerant is set on Channel : %d"), + pBeaconStruct->ssId.ssId, + channelNumber); + vos_mem_free(pBeaconStruct); + return halStatus; + } + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Parse the Beacon IEs")); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("BSS IEs Failed is NULL in Scan")); + } + +NextResult: + pScanResult = sme_ScanResultGetNext(halHandle, pResult); + } + vos_mem_free(pBeaconStruct); + + if (psapCtx->sap_sec_chan) + { + if (eHAL_STATUS_SUCCESS == sapCheckHT40SecondaryIsNotAllowed(psapCtx)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Start SAP/P2P GO in HT 40MHz " + "Primary & Secondary Channel: [%d %d]"), + psapCtx->channel, psapCtx->sap_sec_chan); + halStatus = eHAL_STATUS_SUCCESS; + return halStatus; + } + } + + return halStatus; +} +#endif + +/*========================================================================== + FUNCTION WLANSAP_ScanCallback() + + DESCRIPTION + Callback for Scan (scan results) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tHalHandle : tHalHandle passed in with the scan request + *pContext : The second context pass in for the caller (sapContext) + scanID : scanID got after the scan + status : Status of scan -success, failure or abort + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +eHalStatus +WLANSAP_ScanCallback +( + tHalHandle halHandle, + void *pContext, /* Opaque SAP handle */ + v_U32_t scanID, + eCsrScanStatus scanStatus +) +{ + tScanResultHandle pResult = NULL; + eHalStatus scanGetResultStatus = eHAL_STATUS_FAILURE; + ptSapContext psapContext = (ptSapContext)pContext; + void *pTempHddCtx; + tWLAN_SAPEvent sapEvent; /* State machine event */ + v_U8_t operChannel = 0; + VOS_STATUS sapstatus; + v_U32_t event; + eSapPhyMode sapPhyMode; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + pTempHddCtx = vos_get_context( VOS_MODULE_ID_HDD, + psapContext->pvosGCtx); + if (NULL == pTempHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "HDD context is NULL"); + return eHAL_STATUS_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, before switch on scanStatus = %d", __func__, scanStatus); + + switch (scanStatus) + { + case eCSR_SCAN_SUCCESS: + // sapScanCompleteCallback with eCSR_SCAN_SUCCESS + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, CSR scanStatus = %s (%d)", __func__, + "eCSR_SCAN_SUCCESS", scanStatus); + + /* Get scan results, Run channel selection algorithm, + * select channel and keep in pSapContext->Channel + */ + scanGetResultStatus = sme_ScanGetResult(halHandle, 0, NULL, + &pResult); + + event = eSAP_MAC_SCAN_COMPLETE; + + if ((scanGetResultStatus != eHAL_STATUS_SUCCESS) + && (scanGetResultStatus != eHAL_STATUS_E_NULL_VALUE)) + { + // No scan results + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, Get scan result failed! ret = %d", + __func__, scanGetResultStatus); + sapSetOperatingChannel(psapContext, operChannel); + break; + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (psapContext->channel == AUTO_CHANNEL_SELECT) +#endif + { + operChannel = sapSelectChannel(halHandle, psapContext, pResult); + sapSetOperatingChannel(psapContext, operChannel); + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if ((psapContext->channel <= SIR_11B_CHANNEL_END) + && (psapContext->channel > 0)) + { + if (eHAL_STATUS_SUCCESS != + sapCheck40Mhz24G(halHandle, psapContext, pResult)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Starting SAP into HT20")); + /* Disable Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(halHandle, + PHY_SINGLE_CHANNEL_CENTERED); + } + } +#endif + sme_ScanResultPurge(halHandle, pResult); + break; + + default: + event = eSAP_CHANNEL_SELECTION_FAILED; + if (psapContext->channel == AUTO_CHANNEL_SELECT) + sapSetOperatingChannel(psapContext, operChannel); +#ifdef WLAN_FEATURE_AP_HT40_24G + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Starting SAP into HT20")); + /* Disable Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(halHandle, + PHY_SINGLE_CHANNEL_CENTERED); +#endif + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("CSR scanStatus = %s (%d)"), + "eCSR_SCAN_ABORT/FAILURE", scanStatus); + } + + + sapPhyMode = + sapConvertSapPhyModeToCsrPhyMode(psapContext->csrRoamProfile.phyMode); + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (psapContext->channel > SIR_11B_CHANNEL_END) +#endif + sme_SelectCBMode(halHandle, sapPhyMode, psapContext->channel); + +#ifdef SOFTAP_CHANNEL_RANGE + if(psapContext->channelList != NULL) + { + /* Always free up the memory for channel selection whatever + * the result */ + vos_mem_free(psapContext->channelList); + psapContext->channelList = NULL; + } +#endif + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel selected = %d", __func__, psapContext->channel); + + /* Fill in the event structure */ + sapEvent.event = event; + sapEvent.params = 0; // pCsrRoamInfo; + sapEvent.u1 = scanStatus; // roamstatus + sapEvent.u2 = 0; // roamResult + + /* Handle event */ + sapstatus = sapFsm(psapContext, &sapEvent); + + return sapstatus; +}// WLANSAP_ScanCallback + +/*========================================================================== + FUNCTION WLANSAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext : pContext passed in with the roam request + pCsrRoamInfo : Pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: For detail valid members. It may be NULL + roamId : To identify the callback related roam request. 0 means unsolicited + roamStatus : Flag indicating the status of the callback + roamResult : Result + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +eHalStatus +WLANSAP_RoamCallback +( + void *pContext, /* Opaque SAP handle */ + tCsrRoamInfo *pCsrRoamInfo, + v_U32_t roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +) +{ + /* sapContext value */ + ptSapContext sapContext = (ptSapContext) pContext; + tWLAN_SAPEvent sapEvent; /* State machine event */ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Before switch on roamStatus = %d"), + roamStatus); + switch(roamStatus) + { + case eCSR_ROAM_SESSION_OPENED: + { + /* tHalHandle */ + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_SESSION_OPENED", roamStatus); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s invalid hHal", __func__); + halStatus = eHAL_STATUS_FAILED_ALLOC; + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s calling sme_RoamConnect with eCSR_BSS_TYPE_INFRA_AP", __func__); + sapContext->isSapSessionOpen = eSAP_TRUE; + halStatus = sme_RoamConnect(hHal, sapContext->sessionId, + &sapContext->csrRoamProfile, + &sapContext->csrRoamId); + } + break; + } + + case eCSR_ROAM_INFRA_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_INFRA_IND", roamStatus); + if(roamResult == eCSR_ROAM_RESULT_INFRA_START_FAILED) + { + /* Fill in the event structure */ + sapEvent.event = eSAP_MAC_START_FAILS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + } + break; + + case eCSR_ROAM_LOSTLINK: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_LOSTLINK", roamStatus); + break; + + case eCSR_ROAM_MIC_ERROR_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_MIC_ERROR_IND", roamStatus); + break; + + case eCSR_ROAM_SET_KEY_COMPLETE: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_SET_KEY_COMPLETE", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_FAILURE ) + { + /* Format the SET KEY complete information pass to HDD... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_SET_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_REMOVE_KEY_COMPLETE: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_REMOVE_KEY_COMPLETE", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_FAILURE ) + { + /* Format the SET KEY complete information pass to HDD... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_DEL_KEY_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_ASSOCIATION_COMPLETION: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_ASSOCIATION_COMPLETION", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_FAILURE ) + { + /* Format the SET KEY complete information pass to HDD... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_REASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_DISASSOCIATED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_DISASSOCIATED", roamStatus); + if (roamResult == eCSR_ROAM_RESULT_MIC_FAILURE) + { + /* Format the MIC failure event to return... */ + sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) eSAP_STATUS_FAILURE); + } + break; + + case eCSR_ROAM_WPS_PBC_PROBE_REQ_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_WPS_PBC_PROBE_REQ_IND", roamStatus); + break; + case eCSR_ROAM_REMAIN_CHAN_READY: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_REMAIN_CHAN_READY", roamStatus); + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_REMAIN_CHAN_READY, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + break; + case eCSR_ROAM_SEND_ACTION_CNF: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_SEND_ACTION_CNF", roamStatus); + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_SEND_ACTION_CNF, + (v_PVOID_t)((eSapStatus)((roamResult == eCSR_ROAM_RESULT_NONE) + ? eSAP_STATUS_SUCCESS : eSAP_STATUS_FAILURE))); + break; + + case eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS", roamStatus); + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_DISCONNECT_ALL_P2P_CLIENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS ); + break; + + case eCSR_ROAM_SEND_P2P_STOP_BSS: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Received stopbss")); + sapSignalHDDevent(sapContext, pCsrRoamInfo, + eSAP_MAC_TRIG_STOP_BSS_EVENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS ); + break; + +#ifdef WLAN_FEATURE_AP_HT40_24G + case eCSR_ROAM_2040_COEX_INFO_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamStatus = %s (%d)"), + "eCSR_ROAM_2040_COEX_INFO_IND", + roamStatus); + + sapCheckHT2040CoexAction(sapContext, pCsrRoamInfo->pSmeHT2040CoexInfoInd); + break; +#endif + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("CSR roamStatus not handled roamStatus = %s (%d)"), + get_eRoamCmdStatus_str(roamStatus), roamStatus); + break; + } + + + switch (roamResult) + { + case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL( "CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND", + roamResult); + sapContext->nStaWPARSnReqIeLength = pCsrRoamInfo->rsnIELen; + + if(sapContext->nStaWPARSnReqIeLength) + vos_mem_copy( sapContext->pStaWpaRsnReqIE, + pCsrRoamInfo->prsnIE, sapContext->nStaWPARSnReqIeLength); + + sapContext->nStaAddIeLength = pCsrRoamInfo->addIELen; + + if(sapContext->nStaAddIeLength) + vos_mem_copy( sapContext->pStaAddIE, + pCsrRoamInfo->paddIE, sapContext->nStaAddIeLength); + + sapContext->SapQosCfg.WmmIsEnabled = pCsrRoamInfo->wmmEnabledSta; + // MAC filtering + vosStatus = sapIsPeerMacAllowed(sapContext, (v_U8_t *)pCsrRoamInfo->peerMac); + + if ( VOS_STATUS_SUCCESS == vosStatus ) + { + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_ASSOC_IND, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("CSR roamResult = (%d) MAC (" + MAC_ADDRESS_STR") fail"), + roamResult, + MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac)); + halStatus = eHAL_STATUS_FAILURE; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + FL("CSR roamResult = (%d) MAC (" + MAC_ADDRESS_STR") not allowed"), + roamResult, + MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac)); + halStatus = eHAL_STATUS_FAILURE; + } + + break; + + case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF", + roamResult); + + sapContext->nStaWPARSnReqIeLength = pCsrRoamInfo->rsnIELen; + if (sapContext->nStaWPARSnReqIeLength) + vos_mem_copy( sapContext->pStaWpaRsnReqIE, + pCsrRoamInfo->prsnIE, sapContext->nStaWPARSnReqIeLength); + + sapContext->nStaAddIeLength = pCsrRoamInfo->addIELen; + if(sapContext->nStaAddIeLength) + vos_mem_copy( sapContext->pStaAddIE, + pCsrRoamInfo->paddIE, sapContext->nStaAddIeLength); + + sapContext->SapQosCfg.WmmIsEnabled = pCsrRoamInfo->wmmEnabledSta; + /* Fill in the event structure */ + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_ASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_AP_HT40_24G + else + { + if (pCsrRoamInfo->HT40MHzIntoEnabledSta) + { + sapAddHT40IntolerantSta(sapContext, pCsrRoamInfo); + } + } +#endif + break; + + case eCSR_ROAM_RESULT_DEAUTH_IND: + case eCSR_ROAM_RESULT_DISASSOC_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_DISASSOC_IND", + roamResult); +#ifdef WLAN_FEATURE_AP_HT40_24G + sapRemoveHT40IntolerantSta(sapContext, pCsrRoamInfo); +#endif + /* Fill in the event structure */ + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_GROUP: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_MIC_ERROR_GROUP", + roamResult); + /* Fill in the event structure */ + //TODO: support for group key MIC failure event to be handled + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_MIC_ERROR_UNICAST: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_MIC_ERROR_UNICAST", + roamResult); + /* Fill in the event structure */ + //TODO: support for unicast key MIC failure event to be handled + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_MIC_FAILURE_EVENT,(v_PVOID_t) NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_AUTHENTICATED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_AUTHENTICATED", + roamResult); + /* Fill in the event structure */ + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_SET_KEY_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_ASSOCIATED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_ASSOCIATED", + roamResult); + /* Fill in the event structure */ + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_REASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + break; + + case eCSR_ROAM_RESULT_INFRA_STARTED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_INFRA_STARTED", + roamResult); + /* Fill in the event structure */ + sapEvent.event = eSAP_MAC_START_BSS_SUCCESS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_INFRA_STOPPED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_INFRA_STOPPED", + roamResult); + /* Fill in the event structure */ + sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS; + sapEvent.params = pCsrRoamInfo; + sapEvent.u1 = roamStatus; + sapEvent.u2 = roamResult; + + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND", + roamResult); + /* Fill in the event structure */ + //TODO: support for group key MIC failure event to be handled + vosStatus = sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_WPS_PBC_PROBE_REQ_EVENT,(v_PVOID_t) NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + break; + + case eCSR_ROAM_RESULT_FORCED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_FORCED", + roamResult); +#ifdef WLAN_FEATURE_AP_HT40_24G + sapRemoveHT40IntolerantSta(sapContext, pCsrRoamInfo); +#endif + //This event can be used to inform hdd about user triggered disassoc event + /* Fill in the event structure */ + sapSignalHDDevent( sapContext, pCsrRoamInfo, eSAP_STA_DISASSOC_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + break; + + case eCSR_ROAM_RESULT_NONE: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_NONE", + roamResult); + //This event can be used to inform hdd about user triggered disassoc event + /* Fill in the event structure */ + if ( roamStatus == eCSR_ROAM_SET_KEY_COMPLETE) + { + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_SET_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_SUCCESS); + } + else if (roamStatus == eCSR_ROAM_REMOVE_KEY_COMPLETE ) + { + sapSignalHDDevent( sapContext, pCsrRoamInfo,eSAP_STA_DEL_KEY_EVENT,(v_PVOID_t) eSAP_STATUS_SUCCESS); + } + break; + + case eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("CSR roamResult = %s (%d)"), + "eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED", + roamResult); + /* Fill in the event structure */ + vosStatus = sapSignalHDDevent(sapContext, pCsrRoamInfo, eSAP_MAX_ASSOC_EXCEEDED, (v_PVOID_t)NULL); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + halStatus = eHAL_STATUS_FAILURE; + } + + break; + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("CSR roamResult = %s (%d) not handled"), + get_eCsrRoamResult_str(roamResult), + roamResult); + break; + } + + return halStatus; +} diff --git a/drivers/staging/prima/CORE/SAP/src/sapChSelect.c b/drivers/staging/prima/CORE/SAP/src/sapChSelect.c new file mode 100644 index 000000000000..dda7fa195618 --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapChSelect.c @@ -0,0 +1,2338 @@ +/* + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p C h S e l e c t . C + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + functions for channel selection. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-03-15 SOFTAP Created module + +===========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files +------------------------------------------------------------------------*/ +#include "vos_trace.h" +#include "csrApi.h" +#include "sme_Api.h" +#include "sapChSelect.h" +#include "sapInternal.h" +#ifdef ANI_OS_TYPE_QNX +#include "stdio.h" +#endif +#include "wlan_hdd_main.h" + +/*-------------------------------------------------------------------------- + Function definitions +--------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Defines +--------------------------------------------------------------------------*/ +#define SAP_DEBUG + +#define IS_RSSI_VALID( extRssi, rssi ) \ +( \ + ((extRssi < rssi)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) + +#ifdef FEATURE_WLAN_CH_AVOID +extern safeChannelType safeChannels[]; +#endif /* FEATURE_WLAN_CH_AVOID */ + +/*========================================================================== + FUNCTION sapCleanupChannelList + + DESCRIPTION + Function sapCleanupChannelList frees up the memory allocated to the channel list. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + NULL + + RETURN VALUE + NULL +============================================================================*/ + +void sapCleanupChannelList(void) +{ + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); + ptSapContext pSapCtx; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "Cleaning up the channel list structure"); + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Global Context is NULL"); + return ; + } + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Context is NULL"); + return ; + } + + pSapCtx->SapChnlList.numChannel = 0; + vos_mem_free(pSapCtx->SapChnlList.channelList); + pSapCtx->SapChnlList.channelList = NULL; +} + +typedef struct +{ + v_U16_t chStartNum; + v_U32_t weight; +} sapAcsChannelInfo; + +#define ACS_WEIGHT_MAX 4444 + +sapAcsChannelInfo acsHT40Channels5G[ ] = { + {36, ACS_WEIGHT_MAX}, + {44, ACS_WEIGHT_MAX}, + {52, ACS_WEIGHT_MAX}, + {60, ACS_WEIGHT_MAX}, + {100, ACS_WEIGHT_MAX}, + {108, ACS_WEIGHT_MAX}, + {116, ACS_WEIGHT_MAX}, + {124, ACS_WEIGHT_MAX}, + {132, ACS_WEIGHT_MAX}, + {140, ACS_WEIGHT_MAX}, + {149, ACS_WEIGHT_MAX}, + {157, ACS_WEIGHT_MAX}, +}; + +sapAcsChannelInfo acsHT80Channels[ ] = { + {36, ACS_WEIGHT_MAX}, + {52, ACS_WEIGHT_MAX}, + {100, ACS_WEIGHT_MAX}, + {116, ACS_WEIGHT_MAX}, + {132, ACS_WEIGHT_MAX}, + {149, ACS_WEIGHT_MAX}, +}; + +sapAcsChannelInfo acsHT40Channels24G[ ] = { + {1, ACS_WEIGHT_MAX}, + {2, ACS_WEIGHT_MAX}, + {3, ACS_WEIGHT_MAX}, + {4, ACS_WEIGHT_MAX}, + {9, ACS_WEIGHT_MAX}, +}; + +typedef enum { + CHWIDTH_HT20, + CHWIDTH_HT40, + CHWIDTH_HT80, +} eChannelWidthInfo; + +#define CHANNEL_165 165 + +/*========================================================================== + FUNCTION sapSetPreferredChannel + + DESCRIPTION + Function sapSetPreferredChannel sets the channel list which has been configured + into sap context (pSapCtx) which will be used at the time of best channel selection. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + *ptr: pointer having the command followed by the arguments in string format + + RETURN VALUE + int: return 0 when success else returns error code. +============================================================================*/ + +int sapSetPreferredChannel(tANI_U8* ptr) +{ + + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); + ptSapContext pSapCtx; + tANI_U8* param; + int tempInt; + int j; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Enter: %s", __func__); + + if (NULL == pvosGCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Global Context is NULL"); + return -EINVAL; + } + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "SAP Context is NULL"); + return -EINVAL; + } + + if (NULL != pSapCtx->SapChnlList.channelList) + { + sapCleanupChannelList(); + } + + param = strchr(ptr, ' '); + /*no argument after the command*/ + if (NULL == param) + { + return -EINVAL; + } + + /*no space after the command*/ + else if (SPACE_ASCII_VALUE != *param) + { + return -EINVAL; + } + + param++; + + /*removing empty spaces*/ + while((SPACE_ASCII_VALUE == *param)&& ('\0' != *param) ) param++; + + /*no argument followed by spaces*/ + if('\0' == *param) + { + return -EINVAL; + } + + /*getting the first argument ie the number of channels*/ + if (sscanf(param, "%d ", &tempInt) != 1) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot get number of channels from input", __func__); + return -EINVAL; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Number of channel added are: %d", __func__, tempInt); + + if (tempInt <= 0 || tempInt > 255) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Number of channel received", __func__); + return -EINVAL; + } + + /*allocating space for the desired number of channels*/ + pSapCtx->SapChnlList.channelList = (v_U8_t *)vos_mem_malloc(tempInt); + + if (NULL == pSapCtx->SapChnlList.channelList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, VOS_MALLOC_ERR", __func__); + return -EINVAL; + } + + pSapCtx->SapChnlList.numChannel = tempInt; + for(j=0;jSapChnlList.numChannel;j++) + { + + /*param pointing to the beginning of first space after number of channels*/ + param = strpbrk( param, " " ); + /*no channel list after the number of channels argument*/ + if (NULL == param) + { + sapCleanupChannelList(); + return -EINVAL; + } + + param++; + + /*removing empty space*/ + while((SPACE_ASCII_VALUE == *param) && ('\0' != *param) ) param++; + + /*no channel list after the number of channels argument and spaces*/ + if( '\0' == *param ) + { + sapCleanupChannelList(); + return -EINVAL; + } + + if (sscanf(param, "%d ", &tempInt) != 1) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot read channel number", __func__); + sapCleanupChannelList(); + return -EINVAL; + } + if (tempInt < 0 || tempInt > 255) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid channel number received", __func__); + sapCleanupChannelList(); + return -EINVAL; + } + + pSapCtx->SapChnlList.channelList[j] = tempInt; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Channel %d added to preferred channel list", + __func__, pSapCtx->SapChnlList.channelList[j] ); + + } + + /*extra arguments check*/ + param = strpbrk( param, " " ); + if (NULL != param) + { + while((SPACE_ASCII_VALUE == *param) && ('\0' != *param) ) param++; + + if('\0' != *param) + { + sapCleanupChannelList(); + return -EINVAL; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Exit: %s", __func__); + + return 0; +} + +/*========================================================================== + FUNCTION sapSelectPreferredChannelFromChannelList + + DESCRIPTION + Function sapSelectPreferredChannelFromChannelList calculates the best channel + among the configured channel list. If channel list not configured then returns + the best channel calculated among all the channel list. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure + bestChNum: best channel already calculated among all the chanels + pSapCtx: having info of channel list from which best channel is selected + + RETURN VALUE + v_U8_t: best channel +============================================================================*/ +v_U8_t sapSelectPreferredChannelFromChannelList(v_U8_t bestChNum, + ptSapContext pSapCtx, + tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t j = 0; + v_U8_t count = 0; + + //If Channel List is not Configured don't do anything + //Else return the Best Channel from the Channel List + if((NULL == pSapCtx->SapChnlList.channelList) || + (NULL == pSpectInfoParams) || + (0 == pSapCtx->SapChnlList.numChannel)) + { + return bestChNum; + } + + if (bestChNum > 0 && bestChNum <= 252) + { + for(count=0; count < pSpectInfoParams->numSpectChans ; count++) + { + bestChNum = (v_U8_t)pSpectInfoParams->pSpectCh[count].chNum; + // Select the best channel from allowed list + for(j=0;j< pSapCtx->SapChnlList.numChannel;j++) + { + if( (pSapCtx->SapChnlList.channelList[j]) == bestChNum) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Best channel computed from Channel List is: %d", + bestChNum); + return bestChNum; + } + } + } + + return SAP_CHANNEL_NOT_SELECTED; + } + else + return SAP_CHANNEL_NOT_SELECTED; +} + + +/*========================================================================== + FUNCTION sapChanSelInit + + DESCRIPTION + Function sapChanSelInit allocates the memory, intializes the + structures used by the channel selection algorithm + + DEPENDENCIES + NA. + + PARAMETERS + + IN + *pSpectInfoParams : Pointer to tSapChSelSpectInfo structure + + RETURN VALUE + v_BOOL_t: Success or FAIL + + SIDE EFFECTS +============================================================================*/ +v_BOOL_t sapChanSelInit(tHalHandle halHandle, tSapChSelSpectInfo *pSpectInfoParams) +{ + tSapSpectChInfo *pSpectCh = NULL; + v_U8_t *pChans = NULL; + v_U16_t channelnum = 0; + tpAniSirGlobal pMac = PMAC_STRUCT(halHandle); +#ifdef FEATURE_WLAN_CH_AVOID + v_U16_t i; + v_BOOL_t chSafe = VOS_TRUE; +#endif /* FEATURE_WLAN_CH_AVOID */ + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s", __func__); + + // Channels for that 2.4GHz band + //Considered only for 2.4GHz need to change in future to support 5GHz support + pSpectInfoParams->numSpectChans = pMac->scan.base20MHzChannels.numChannels; + + // Allocate memory for weight computation of 2.4GHz + pSpectCh = (tSapSpectChInfo *)vos_mem_malloc((pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh)); + + if(pSpectCh == NULL) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, VOS_MALLOC_ERR", __func__); + return eSAP_FALSE; + } + + vos_mem_zero(pSpectCh, (pSpectInfoParams->numSpectChans) * sizeof(*pSpectCh)); + + // Initialize the pointers in the DfsParams to the allocated memory + pSpectInfoParams->pSpectCh = pSpectCh; + + pChans = pMac->scan.base20MHzChannels.channelList; + + // Fill the channel number in the spectrum in the operating freq band + for (channelnum = 0; channelnum < pSpectInfoParams->numSpectChans; channelnum++) { +#ifdef FEATURE_WLAN_CH_AVOID + chSafe = VOS_TRUE; + for(i = 0; i < NUM_20MHZ_RF_CHANNELS; i++) + { + if((safeChannels[i].channelNumber == *pChans) && + (VOS_FALSE == safeChannels[i].isSafe)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s : CH %d is not safe", __func__, *pChans); + chSafe = VOS_FALSE; + break; + } + } +#endif /* FEATURE_WLAN_CH_AVOID */ + + if(*pChans == 14 ) //OFDM rates are not supported on channel 14 + { + pChans++; + pSpectCh++; + continue; + } +#ifdef FEATURE_WLAN_CH_AVOID + if (VOS_TRUE == chSafe) + { +#endif /* FEATURE_WLAN_CH_AVOID */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_DEBUG, + "%s : Available Ch %d", + __func__, *pChans); + pSpectCh->chNum = *pChans; + pSpectCh->valid = eSAP_TRUE; + // Initialise for all channels + pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + // Initialise 20MHz for all the Channels + pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; +#ifdef FEATURE_WLAN_CH_AVOID + } +#endif /* FEATURE_WLAN_CH_AVOID */ + pSpectCh++; + pChans++; + } + return eSAP_TRUE; +} + +/*========================================================================== + FUNCTION sapweightRssiCount + + DESCRIPTION + Function weightRssiCount calculates the channel weight due to rssi + and data count(here number of BSS observed) + + DEPENDENCIES + NA. + + PARAMETERS + + IN + rssi : Max signal strength receieved from a BSS for the channel + count : Number of BSS observed in the channel + + RETURN VALUE + v_U32_t : Calculated channel weight based on above two + + SIDE EFFECTS +============================================================================*/ +v_U32_t sapweightRssiCount(v_S7_t rssi, v_U16_t count) +{ + v_S31_t rssiWeight=0; + v_S31_t countWeight=0; + v_U32_t rssicountWeight=0; + + // Weight from RSSI + rssiWeight = SOFTAP_RSSI_WEIGHT * (rssi - SOFTAP_MIN_RSSI) + /(SOFTAP_MAX_RSSI - SOFTAP_MIN_RSSI); + + if(rssiWeight > SOFTAP_RSSI_WEIGHT) + rssiWeight = SOFTAP_RSSI_WEIGHT; + else if (rssiWeight < 0) + rssiWeight = 0; + + // Weight from data count + countWeight = SOFTAP_COUNT_WEIGHT * (count - SOFTAP_MIN_COUNT) + /(SOFTAP_MAX_COUNT - SOFTAP_MIN_COUNT); + + if(countWeight > SOFTAP_COUNT_WEIGHT) + countWeight = SOFTAP_COUNT_WEIGHT; + + rssicountWeight = rssiWeight + countWeight; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, rssiWeight=%d, countWeight=%d, rssicountWeight=%d", + __func__, rssiWeight, countWeight, rssicountWeight); + + return(rssicountWeight); +} + + +/*========================================================================== + FUNCTION sapInterferenceRssiCount + + DESCRIPTION + Function sapInterferenceRssiCount Considers the Adjacent channel rssi + and data count(here number of BSS observed) + + DEPENDENCIES + NA. + + PARAMETERS + + pSpectCh : Channel Information + + RETURN VALUE + NA. + + SIDE EFFECTS +============================================================================*/ +void sapInterferenceRssiCount(tSapSpectChInfo *pSpectCh) +{ + tSapSpectChInfo *pExtSpectCh = NULL; + v_S31_t rssi; + + if (NULL == pSpectCh) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: pSpectCh is NULL", __func__); + return; + } + + switch(pSpectCh->chNum) + { + case CHANNEL_1: + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_2: + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + case CHANNEL_3: + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + case CHANNEL_4: + pExtSpectCh = (pSpectCh - 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_5: + case CHANNEL_6: + case CHANNEL_7: + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_8: + pExtSpectCh = (pSpectCh - 4); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_9: + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_10: + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case CHANNEL_11: + pExtSpectCh = (pSpectCh - 1); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 3); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 4); + if (pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + + SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if (pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + default: + break; + } +} + +/*========================================================================== + FUNCTION sapComputeSpectWeight + + DESCRIPTION + Main function for computing the weight of each channel in the + spectrum based on the RSSI value of the BSSes on the channel + and number of BSS + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSpectInfoParams structure + halHandle : Pointer to HAL handle + pResult : Pointer to tScanResultHandle + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapComputeSpectWeight( tSapChSelSpectInfo* pSpectInfoParams, + tHalHandle halHandle, tScanResultHandle pResult) +{ + v_S7_t rssi = 0; + v_U8_t chn_num = 0; + v_U8_t channel_id = 0; + + tCsrScanResultInfo *pScanResult; + tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh; + v_U32_t operatingBand; + v_U16_t channelWidth; + v_U16_t secondaryChannelOffset; + v_U16_t centerFreq; + v_U16_t vhtSupport; + v_U32_t ieLen = 0; + tSirProbeRespBeacon *pBeaconStruct; + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + + pBeaconStruct = vos_mem_malloc(sizeof(tSirProbeRespBeacon)); + if ( NULL == pBeaconStruct ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "Unable to allocate memory in sapComputeSpectWeight"); + return; + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Computing spectral weight", __func__); + + /** + * Soft AP specific channel weight calculation using DFS formula + */ + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + + pScanResult = sme_ScanResultGetFirst(halHandle, pResult); + + while (pScanResult) { + pSpectCh = pSpectInfoParams->pSpectCh; + // Defining the default values, so that any value will hold the default values + channelWidth = eHT_CHANNEL_WIDTH_20MHZ; + secondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED; + vhtSupport = 0; + centerFreq = 0; + + if (pScanResult->BssDescriptor.ieFields != NULL) + { + ieLen = GET_IE_LEN_IN_BSS(pScanResult->BssDescriptor.length); + vos_mem_set((tANI_U8 *) pBeaconStruct, sizeof(tSirProbeRespBeacon), 0); + + if ((sirParseBeaconIE(pMac, pBeaconStruct,(tANI_U8 *)( pScanResult->BssDescriptor.ieFields), ieLen)) == eSIR_SUCCESS) + { + if (pBeaconStruct->HTCaps.present && pBeaconStruct->HTInfo.present) + { + channelWidth = pBeaconStruct->HTCaps.supportedChannelWidthSet; + secondaryChannelOffset = pBeaconStruct->HTInfo.secondaryChannelOffset; + if(pBeaconStruct->VHTOperation.present) + { + vhtSupport = pBeaconStruct->VHTOperation.present; + if(pBeaconStruct->VHTOperation.chanWidth > WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ) + { + channelWidth = eHT_CHANNEL_WIDTH_80MHZ; + centerFreq = pBeaconStruct->VHTOperation.chanCenterFreqSeg1; + } + } + } + } + } + // Processing for each tCsrScanResultInfo in the tCsrScanResult DLink list + for (chn_num = 0; chn_num < pSpectInfoParams->numSpectChans; chn_num++) { + + /* + * if the Beacon has channel ID, use it other wise we will + * rely on the channelIdSelf + */ + if(pScanResult->BssDescriptor.channelId == 0) + channel_id = pScanResult->BssDescriptor.channelIdSelf; + else + channel_id = pScanResult->BssDescriptor.channelId; + + if (pSpectCh && (channel_id == pSpectCh->chNum)) { + if (pSpectCh->rssiAgr < pScanResult->BssDescriptor.rssi) + pSpectCh->rssiAgr = pScanResult->BssDescriptor.rssi; + + ++pSpectCh->bssCount; // Increment the count of BSS + + if(operatingBand) // Connsidering the Extension Channel only in a channels + { + /* Updating the received ChannelWidth */ + if (pSpectCh->channelWidth != channelWidth) + pSpectCh->channelWidth = channelWidth; + /* If received ChannelWidth is other than HT20, we need to update the extension channel Params as well */ + /* channelWidth == 0, HT20 */ + /* channelWidth == 1, HT40 */ + /* channelWidth == 2, VHT80*/ + switch(pSpectCh->channelWidth) + { + case eHT_CHANNEL_WIDTH_40MHZ: //HT40 + switch( secondaryChannelOffset) + { + tSapSpectChInfo *pExtSpectCh = NULL; + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: // Above the Primary Channel + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + // REducing the rssi by -20 and assigning it to Extension channel + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + break; + + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: // Below the Primary channel + pExtSpectCh = (pSpectCh - 1); + if(pExtSpectCh != NULL) + { + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + ++pExtSpectCh->bssCount; + } + break; + } + break; + case eHT_CHANNEL_WIDTH_80MHZ: // VHT80 + if((centerFreq - channel_id) == 6) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; // Reducing the rssi by -20 and assigning it to Subband 1 + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; // Reducing the rssi by -30 and assigning it to Subband 2 + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND3_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; // Reducing the rssi by -40 and assigning it to Subband 3 + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + else if((centerFreq - channel_id) == 2) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh - 1 ); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + else if((centerFreq - channel_id) == -2) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh - 1 ); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh + 1); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + else if((centerFreq - channel_id) == -6) + { + tSapSpectChInfo *pExtSpectCh = NULL; + pExtSpectCh = (pSpectCh - 1 ); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND1_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 2); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND2_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + pExtSpectCh = (pSpectCh - 3); + if(pExtSpectCh != NULL) + { + ++pExtSpectCh->bssCount; + rssi = pSpectCh->rssiAgr + SAP_SUBBAND3_RSSI_EFFECT_PRIMARY; + if (IS_RSSI_VALID(pExtSpectCh->rssiAgr, rssi)) + { + pExtSpectCh->rssiAgr = rssi; + } + if(pExtSpectCh->rssiAgr < SOFTAP_MIN_RSSI) + pExtSpectCh->rssiAgr = SOFTAP_MIN_RSSI; + } + } + break; + } + } + else if(operatingBand == eSAP_RF_SUBBAND_2_4_GHZ) + { + sapInterferenceRssiCount(pSpectCh); + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, bssdes.ch_self=%d, bssdes.ch_ID=%d, bssdes.rssi=%d, SpectCh.bssCount=%d, pScanResult=%p, ChannelWidth %d, secondaryChanOffset %d, center frequency %d ", + __func__, pScanResult->BssDescriptor.channelIdSelf, pScanResult->BssDescriptor.channelId, pScanResult->BssDescriptor.rssi, pSpectCh->bssCount, pScanResult,pSpectCh->channelWidth,secondaryChannelOffset,centerFreq); + pSpectCh++; + break; + } else { + pSpectCh++; + } + } + + pScanResult = sme_ScanResultGetNext(halHandle, pResult); + } + + // Calculate the weights for all channels in the spectrum pSpectCh + pSpectCh = pSpectInfoParams->pSpectCh; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Spectrum Channels Weight", __func__); + + for (chn_num = 0; chn_num < (pSpectInfoParams->numSpectChans); chn_num++) { + + /* + rssi : Maximum received signal strength among all BSS on that channel + bssCount : Number of BSS on that channel + */ + + rssi = (v_S7_t)pSpectCh->rssiAgr; + + pSpectCh->weight = + SAPDFS_NORMALISE_1000 * sapweightRssiCount(rssi, pSpectCh->bssCount); + pSpectCh->weight_copy = pSpectCh->weight; + //------ Debug Info ------ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Chan=%d Weight= %d rssiAgr=%d bssCount=%d", __func__, + pSpectCh->chNum, pSpectCh->weight, + pSpectCh->rssiAgr, pSpectCh->bssCount); + //------ Debug Info ------ + pSpectCh++; + } + vos_mem_free(pBeaconStruct); +} + +/*========================================================================== + FUNCTION sapChanSelExit + + DESCRIPTION + Exit function for free out the allocated memory, to be called + at the end of the dfsSelectChannel function + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapChanSelExit( tSapChSelSpectInfo *pSpectInfoParams ) +{ + // Free all the allocated memory + vos_mem_free(pSpectInfoParams->pSpectCh); +} + +/*========================================================================== + FUNCTION sapSortChlWeight + + DESCRIPTION + Funtion to sort the channels with the least weight first + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeight(tSapChSelSpectInfo *pSpectInfoParams) +{ + tSapSpectChInfo temp; + + tSapSpectChInfo *pSpectCh = NULL; + v_U32_t i = 0, j = 0, minWeightIndex = 0; + + pSpectCh = pSpectInfoParams->pSpectCh; + for (i = 0; i < pSpectInfoParams->numSpectChans; i++) { + minWeightIndex = i; + for( j = i + 1; j < pSpectInfoParams->numSpectChans; j++) { + if(pSpectCh[j].weight < pSpectCh[minWeightIndex].weight) { + minWeightIndex = j; + } + } + if(minWeightIndex != i) { + vos_mem_copy(&temp, &pSpectCh[minWeightIndex], sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i], sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh)); + } + } +} + +/*========================================================================== + FUNCTION sapSortChlWeightHT80 + + DESCRIPTION + Funtion to sort the channels with the least weight first for HT80 channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightHT80(tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t i, j, n; + tSapSpectChInfo *pSpectInfo; + v_U8_t minIdx; + + pSpectInfo = pSpectInfoParams->pSpectCh; + /* for each HT80 channel, calculate the combined weight of the + four 20MHz weight */ + for (i = 0; i < ARRAY_SIZE(acsHT80Channels); i++) + { + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if ( pSpectInfo[j].chNum == acsHT80Channels[i].chStartNum ) + break; + } + if (j == pSpectInfoParams->numSpectChans) + continue; + + /*found the channel, add the 4 adjacent channels' weight*/ + if (((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) && + ((pSpectInfo[j].chNum +8) == pSpectInfo[j+2].chNum) && + ((pSpectInfo[j].chNum +12) == pSpectInfo[j+3].chNum)) + { + acsHT80Channels[i].weight = pSpectInfo[j].weight + + pSpectInfo[j+1].weight + + pSpectInfo[j+2].weight + + pSpectInfo[j+3].weight; + /* find best channel among 4 channels as the primary channel */ + if ((pSpectInfo[j].weight + pSpectInfo[j+1].weight) < + (pSpectInfo[j+2].weight + pSpectInfo[j+3].weight)) + { + /* lower 2 channels are better choice */ + if (pSpectInfo[j].weight < pSpectInfo[j+1].weight) + minIdx = 0; + else + minIdx = 1; + } + else + { + /* upper 2 channels are better choice */ + if (pSpectInfo[j+2].weight <= pSpectInfo[j+3].weight) + minIdx = 2; + else + minIdx = 3; + } + + /* set all 4 channels to max value first, then reset the + best channel as the selected primary channel, update its + weightage with the combined weight value */ + for (n=0; n<4; n++) + pSpectInfo[j+n].weight = ACS_WEIGHT_MAX * 4; + + pSpectInfo[j+minIdx].weight = acsHT80Channels[i].weight; + } + else + { + /* some channels does not exist in pSectInfo array, + skip this channel and those in the same HT80 width*/ + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 4; + if ((pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) + pSpectInfo[j+1].weight = ACS_WEIGHT_MAX * 4; + if ((pSpectInfo[j].chNum +8) == pSpectInfo[j+2].chNum) + pSpectInfo[j+2].weight = ACS_WEIGHT_MAX * 4; + if ((pSpectInfo[j].chNum +12) == pSpectInfo[j+3].chNum) + pSpectInfo[j+3].weight = ACS_WEIGHT_MAX * 4; + } + } + + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if ( CHANNEL_165 == pSpectInfo[j].chNum ) + { + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 4; + break; + } + } + + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", + __func__, pSpectInfo->chNum, pSpectInfo->weight, + pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; + } + + sapSortChlWeight(pSpectInfoParams); +} + +/*========================================================================== + FUNCTION sapSortChlWeightHT40_24G + + DESCRIPTION + Funtion to sort the channels with the least weight first for 20MHz channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightHT40_24G(tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t i, j; + tSapSpectChInfo *pSpectInfo; + v_U32_t tmpWeight1, tmpWeight2; + + pSpectInfo = pSpectInfoParams->pSpectCh; + /*for each HT40 channel, calculate the combined weight of the + two 20MHz weight */ + for (i = 0; i < ARRAY_SIZE(acsHT40Channels24G); i++) + { + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if (pSpectInfo[j].chNum == acsHT40Channels24G[i].chStartNum) + break; + } + if (j == pSpectInfoParams->numSpectChans) + continue; + + if ((pSpectInfo[j].chNum +4) == pSpectInfo[j+4].chNum) + { + /* check if there is another channel combination possiblity + e.g., {1, 5} & {5, 9} */ + if ((pSpectInfo[j+4].chNum + 4)== pSpectInfo[j+8].chNum) + { + /* need to compare two channel pairs */ + tmpWeight1 = pSpectInfo[j].weight + pSpectInfo[j+4].weight; + tmpWeight2 = pSpectInfo[j+4].weight + pSpectInfo[j+8].weight; + if (tmpWeight1 <= tmpWeight2) + { + if (pSpectInfo[j].weight <= pSpectInfo[j+4].weight) + { + pSpectInfo[j].weight = tmpWeight1; + pSpectInfo[j+4].weight = ACS_WEIGHT_MAX * 2; + pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+4].weight = tmpWeight1; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2; + } + } + else + { + if (pSpectInfo[j+4].weight <= pSpectInfo[j+8].weight) + { + pSpectInfo[j+4].weight = tmpWeight2; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + pSpectInfo[j+8].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+8].weight = tmpWeight2; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + pSpectInfo[j+4].weight = ACS_WEIGHT_MAX * 2; + } + } + } + else + { + tmpWeight1 = pSpectInfo[j].weight + pSpectInfo[j+4].weight; + if (pSpectInfo[j].weight <= pSpectInfo[j+4].weight) + { + pSpectInfo[j].weight = tmpWeight1; + pSpectInfo[j+4].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+4].weight = tmpWeight1; + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + } + } + else + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + + sapSortChlWeight(pSpectInfoParams); +} + + +/*========================================================================== + FUNCTION sapSortChlWeightHT40_5G + + DESCRIPTION + Funtion to sort the channels with the least weight first for HT40 channels + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightHT40_5G(tSapChSelSpectInfo *pSpectInfoParams) +{ + v_U8_t i, j; + tSapSpectChInfo *pSpectInfo; + + pSpectInfo = pSpectInfoParams->pSpectCh; + /*for each HT40 channel, calculate the combined weight of the + two 20MHz weight */ + for (i = 0; i < ARRAY_SIZE(acsHT40Channels5G); i++) + { + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if (pSpectInfo[j].chNum == acsHT40Channels5G[i].chStartNum) + break; + } + if (j == pSpectInfoParams->numSpectChans) + continue; + + /* found the channel, add the two adjacent channels' weight */ + if ( (pSpectInfo[j].chNum +4) == pSpectInfo[j+1].chNum) + { + acsHT40Channels5G[i].weight = pSpectInfo[j].weight + + pSpectInfo[j+1].weight; + /* select better of the adjact channel as the primary channel */ + if (pSpectInfo[j].weight <= pSpectInfo[j+1].weight) + { + pSpectInfo[j].weight = acsHT40Channels5G[i].weight; + /* mark the adjacent channel's weight as max value so + that it will be sorted to the bottom */ + pSpectInfo[j+1].weight = ACS_WEIGHT_MAX * 2; + } + else + { + pSpectInfo[j+1].weight = acsHT40Channels5G[i].weight; + /* mark the adjacent channel's weight as max value so + that it will be sorted to the bottom */ + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + + } + else + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + } + + /* avoid channel 165 by setting its weight to max */ + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < pSpectInfoParams->numSpectChans; j++) + { + if ( CHANNEL_165 == pSpectInfo[j].chNum ) + { + pSpectInfo[j].weight = ACS_WEIGHT_MAX * 2; + break; + } + } + + pSpectInfo = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", + __func__, pSpectInfo->chNum, pSpectInfo->weight, + pSpectInfo->rssiAgr, pSpectInfo->bssCount); + pSpectInfo++; + } + + sapSortChlWeight(pSpectInfoParams); +} + +/*========================================================================== + FUNCTION sapSortChlWeightAll + + DESCRIPTION + Funtion to sort the channels with the least weight first + + DEPENDENCIES + NA. + + PARAMETERS + + IN + ptSapContext : Pointer to the ptSapContext structure + pSpectInfoParams : Pointer to the tSapChSelSpectInfo structure + + RETURN VALUE + void : NULL + + SIDE EFFECTS +============================================================================*/ +void sapSortChlWeightAll(ptSapContext pSapCtx, + tSapChSelSpectInfo *pSpectInfoParams, + eChannelWidthInfo chWidth, + v_U32_t operatingBand) +{ + tSapSpectChInfo *pSpectCh = NULL; + v_U32_t j = 0; +#ifndef SOFTAP_CHANNEL_RANGE + v_U32_t i = 0; +#endif + + pSpectCh = pSpectInfoParams->pSpectCh; +#ifdef SOFTAP_CHANNEL_RANGE + + switch (chWidth) + { + case CHWIDTH_HT40: + if (eSAP_RF_SUBBAND_2_4_GHZ == operatingBand) + sapSortChlWeightHT40_24G(pSpectInfoParams); + else + sapSortChlWeightHT40_5G(pSpectInfoParams); + break; + + case CHWIDTH_HT80: + sapSortChlWeightHT80(pSpectInfoParams); + break; + + case CHWIDTH_HT20: + default: + /* Sorting the channels as per weights as 20MHz channels */ + sapSortChlWeight(pSpectInfoParams); + } + +#else + /* Sorting the channels as per weights */ + for (i = 0; i < SPECT_24GHZ_CH_COUNT; i++) { + minWeightIndex = i; + for( j = i + 1; j < SPECT_24GHZ_CH_COUNT; j++) { + if(pSpectCh[j].weight < pSpectCh[minWeightIndex].weight) { + minWeightIndex = j; + } + } + if(minWeightIndex != i) { + vos_mem_copy(&temp, &pSpectCh[minWeightIndex], sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[minWeightIndex], &pSpectCh[i], + sizeof(*pSpectCh)); + vos_mem_copy(&pSpectCh[i], &temp, sizeof(*pSpectCh)); + } + } +#endif + + /* For testing */ + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Sorted Spectrum Channels Weight", __func__); + pSpectCh = pSpectInfoParams->pSpectCh; + for (j = 0; j < (pSpectInfoParams->numSpectChans); j++) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Channel=%d Weight= %d rssi=%d bssCount=%d", + __func__, pSpectCh->chNum, pSpectCh->weight, + pSpectCh->rssiAgr, pSpectCh->bssCount); + pSpectCh++; + } + +} + +eChannelWidthInfo sapGetChannelWidthInfo(tHalHandle halHandle, ptSapContext pSapCtx, + v_U32_t operatingBand, eSapPhyMode phyMode) +{ + v_U32_t cbMode; + eChannelWidthInfo chWidth = CHWIDTH_HT20; + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (eSAP_RF_SUBBAND_2_4_GHZ == operatingBand) + cbMode = sme_GetChannelBondingMode24G(halHandle); + else +#endif + cbMode = sme_GetChannelBondingMode5G(halHandle); + + if (phyMode == eSAP_DOT11_MODE_11n || + phyMode == eSAP_DOT11_MODE_11n_ONLY) + { + if (cbMode) + chWidth = CHWIDTH_HT40; + else + chWidth = CHWIDTH_HT20; + } + else if (pSapCtx->csrRoamProfile.phyMode == eSAP_DOT11_MODE_11ac || + pSapCtx->csrRoamProfile.phyMode == eSAP_DOT11_MODE_11ac_ONLY) { + chWidth = CHWIDTH_HT80; + } + else { + /* Sorting the channels as per weights as 20MHz channels */ + chWidth = CHWIDTH_HT20; + } + + return chWidth; +} +/*========================================================================== + FUNCTION sapSelectChannel + + DESCRIPTION + Runs a algorithm to select the best channel to operate in based on BSS + rssi and bss count on each channel + + DEPENDENCIES + NA. + + PARAMETERS + + IN + halHandle : Pointer to HAL handle + pResult : Pointer to tScanResultHandle + + RETURN VALUE + v_U8_t : Success - channel number, Fail - zero + + SIDE EFFECTS +============================================================================*/ +v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResultHandle pScanResult) +{ + // DFS param object holding all the data req by the algo + tSapChSelSpectInfo oSpectInfoParams = {NULL,0}; + tSapChSelSpectInfo *pSpectInfoParams = &oSpectInfoParams; // Memory? NB + v_U8_t bestChNum = SAP_CHANNEL_NOT_SELECTED; +#ifdef SOFTAP_CHANNEL_RANGE + v_U32_t startChannelNum; + v_U32_t endChannelNum; + v_U32_t operatingBand = 0; + v_U32_t tmpChNum; + v_U8_t count; + eChannelWidthInfo chWidth; +#endif + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Running SAP Ch Select", __func__); + + // Initialize the structure pointed by pSpectInfoParams + if(sapChanSelInit( halHandle, pSpectInfoParams) != eSAP_TRUE ) { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, Ch Select initialization failed", __func__); + return SAP_CHANNEL_NOT_SELECTED; + } + + // Compute the weight of the entire spectrum in the operating band + sapComputeSpectWeight( pSpectInfoParams, halHandle, pScanResult); + +#ifdef SOFTAP_CHANNEL_RANGE + if (eCSR_BAND_ALL == pSapCtx->scanBandPreference) + { + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, + &startChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, + &endChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + &operatingBand); + } + else + { + if (eCSR_BAND_24 == pSapCtx->currentPreferredBand) + { + startChannelNum = rfChannels[RF_CHAN_1].channelNum; + endChannelNum = rfChannels[RF_CHAN_14].channelNum; + operatingBand = eSAP_RF_SUBBAND_2_4_GHZ; + } + else + { + startChannelNum = rfChannels[RF_CHAN_36].channelNum; + endChannelNum = rfChannels[RF_CHAN_165].channelNum; + operatingBand = eSAP_RF_SUBBAND_5_ALL_GHZ; + } + } + + pSapCtx->acsBestChannelInfo.channelNum = 0; + pSapCtx->acsBestChannelInfo.weight = CFG_ACS_BAND_SWITCH_THRESHOLD_MAX; + /* find the channel width info */ + chWidth = sapGetChannelWidthInfo(halHandle, pSapCtx, operatingBand, pSapCtx->csrRoamProfile.phyMode); + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, chWidth=%u", __func__, chWidth); + + /* Sort the channel list as per the computed weights, lesser weight first.*/ + sapSortChlWeightAll(pSapCtx, pSpectInfoParams, chWidth, operatingBand); + + /*Loop till get the best channel in the given range */ + for(count=0; count < pSpectInfoParams->numSpectChans ; count++) + { + if((startChannelNum <= pSpectInfoParams->pSpectCh[count].chNum)&& + ( endChannelNum >= pSpectInfoParams->pSpectCh[count].chNum)) + { + if (NV_CHANNEL_ENABLE != + vos_nv_getChannelEnabledState(pSpectInfoParams->pSpectCh[count].chNum)) + { + continue; //skip this channel, continue to next channel + } + if(bestChNum == SAP_CHANNEL_NOT_SELECTED) + { + bestChNum = pSpectInfoParams->pSpectCh[count].chNum; + /* check if bestChNum is in preferred channel list */ + bestChNum = sapSelectPreferredChannelFromChannelList( + bestChNum, pSapCtx, pSpectInfoParams); + if (bestChNum == SAP_CHANNEL_NOT_SELECTED) + { + /* not in preferred channel list, go to next best channel*/ + continue; + } + + if (pSpectInfoParams->pSpectCh[count].weight_copy > + pSapCtx->acsBandSwitchThreshold) + { + /* the best channel exceeds the threshold + check if need to scan next band */ + if ((eCSR_BAND_ALL != pSapCtx->scanBandPreference) && + !pSapCtx->allBandScanned) + { + /* store best channel for later comparison */ + pSapCtx->acsBestChannelInfo.channelNum = bestChNum; + pSapCtx->acsBestChannelInfo.weight = + pSpectInfoParams->pSpectCh[count].weight; + bestChNum = SAP_CHANNEL_NOT_SELECTED; + break; + } + else + { + /* all bands are scanned, compare current best channel + with channel scanned previously */ + if ( pSpectInfoParams->pSpectCh[count].weight_copy > + pSapCtx->acsBestChannelInfo.weight) + { + /* previous stored channel is better */ + bestChNum = pSapCtx->acsBestChannelInfo.channelNum; + } + else + { + pSapCtx->acsBestChannelInfo.channelNum = bestChNum; + pSapCtx->acsBestChannelInfo.weight = + pSpectInfoParams->pSpectCh[count].weight_copy; + } + } + } + } + else + { + if(operatingBand == RF_SUBBAND_2_4_GHZ) + { + /* Give preference to Non-overlap channels */ + if(((pSpectInfoParams->pSpectCh[count].chNum == CHANNEL_1) || + (pSpectInfoParams->pSpectCh[count].chNum == CHANNEL_6) || + (pSpectInfoParams->pSpectCh[count].chNum == CHANNEL_11))&& + (pSpectInfoParams->pSpectCh[count].weight_copy == + pSapCtx->acsBestChannelInfo.weight)) + { + tmpChNum = pSpectInfoParams->pSpectCh[count].chNum; + tmpChNum = + sapSelectPreferredChannelFromChannelList(tmpChNum, + pSapCtx, pSpectInfoParams); + if ( tmpChNum != SAP_CHANNEL_NOT_SELECTED) + { + bestChNum = tmpChNum; + break; + } + + } + } + } + } + } +#else + // Sort the channel list as per the computed weights, lesser weight first. + sapSortChlWeightAll(pSapCtx, halHandle, pSpectInfoParams); + // Get the first channel in sorted array as best 20M Channel + bestChNum = (v_U8_t)pSpectInfoParams->pSpectCh[0].chNum; + //Select Best Channel from Channel List if Configured + bestChNum = sapSelectPreferredChannelFromChannelList(bestChNum, + pSapCtx, pSpectInfoParams); +#endif + + // Free all the allocated memory + sapChanSelExit(pSpectInfoParams); + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, Running SAP Ch select Completed, Ch=%d", + __func__, bestChNum); + if (bestChNum > 0 && bestChNum <= 252) + return bestChNum; + else + return SAP_CHANNEL_NOT_SELECTED; +} + diff --git a/drivers/staging/prima/CORE/SAP/src/sapChSelect.h b/drivers/staging/prima/CORE/SAP/src/sapChSelect.h new file mode 100644 index 000000000000..eb7421812ed1 --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapChSelect.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SAP_CH_SELECT_H ) +#define __SAP_CH_SELECT_H + + +/*=========================================================================== + + s a p C h S e l e c t . h + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + functions for channel selection. + + DEPENDENCIES: + + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- ----- -------------------------------------------------------- +2010-03-15 SoftAP Created module + +===========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files +------------------------------------------------------------------------*/ +#include "aniGlobal.h" +/*-------------------------------------------------------------------------- + defines and enum +--------------------------------------------------------------------------*/ + +#define SPECT_24GHZ_CH_COUNT (11) // USA regulatory domain +#define SAPDFS_NORMALISE_1000 (1000/9) // Case of spec20 with channel diff = 0 +/* Gen 5 values +#define SOFTAP_MIN_RSSI (-85) +#define SOFTAP_MAX_RSSI (-45) +*/ +#define SOFTAP_MIN_RSSI (-100) +#define SOFTAP_MAX_RSSI (0) +#define SOFTAP_MIN_COUNT (0) +#define SOFTAP_MAX_COUNT (60) +#define SOFTAP_RSSI_WEIGHT (20) +#define SOFTAP_COUNT_WEIGHT (20) + +#define SAP_DEFAULT_24GHZ_CHANNEL (6) +#define SAP_DEFAULT_LOW_5GHZ_CHANNEL (40) +#define SAP_DEFAULT_MID_5GHZ_CHANNEL (100) +#define SAP_DEFAULT_HIGH_5GHZ_CHANNEL (149) +#define SAP_CHANNEL_NOT_SELECTED (0) + +#define SOFTAP_HT20_CHANNELWIDTH 0 +#define SAP_SUBBAND1_RSSI_EFFECT_PRIMARY (-20) // In HT40/VHT80, Effect of primary Channel RSSi on Subband1 +#define SAP_SUBBAND2_RSSI_EFFECT_PRIMARY (-30) // In VHT80, Effect of primary Channel RSSI on Subband2 +#define SAP_SUBBAND3_RSSI_EFFECT_PRIMARY (-40) // In VHT80, Effect of Primary Channel RSSI on Subband3 + +#define SAP_24GHZ_FIRST_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-10) // In 2.4GHZ, Effect of Primary Channel RSSI on First Overlapping Channel +#define SAP_24GHZ_SEC_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-20) // In 2.4GHZ, Effect of Primary Channel RSSI on Second Overlapping Channel +#define SAP_24GHZ_THIRD_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-30) // In 2.4GHZ, Effect of Primary Channel RSSI on Third Overlapping Channel +#define SAP_24GHZ_FOURTH_OVERLAP_CHAN_RSSI_EFFECT_PRIMARY (-40) // In 2.4GHZ, Effect of Primary Channel RSSI on Fourth Overlapping Channel + +typedef enum +{ + CHANNEL_1 = 1, + CHANNEL_2, + CHANNEL_3, + CHANNEL_4, + CHANNEL_5, + CHANNEL_6, + CHANNEL_7, + CHANNEL_8, + CHANNEL_9, + CHANNEL_10, + CHANNEL_11 +} tSapChannel; + +/** +* Structure holding information of each channel in the spectrum, +* it contains the channel number, the computed weight +*/ + +typedef struct sSapChannelListInfo{ + v_U8_t numChannel; + v_U8_t *channelList; +} tSapChannelListInfo; + +typedef struct { + v_U16_t chNum; // Channel Number + v_U16_t channelWidth; // Channel Width + v_U16_t bssCount; // bss found in scanresult for this channel + v_S31_t rssiAgr; // Max value of rssi among all BSS(es) from scanresult for this channel + v_U32_t weight; // Weightage of this channel + v_U32_t weight_copy; //copy of the orignal weight + v_BOOL_t valid; // Is this a valid center frequency for regulatory domain +} tSapSpectChInfo;//tDfsSpectChInfo; + +/** +* Structure holding all the information required to make a +* decision for the best operating channel based on dfs formula +*/ + +typedef struct { + tSapSpectChInfo *pSpectCh;//tDfsSpectChInfo *pSpectCh; // Ptr to the channels in the entire spectrum band + v_U8_t numSpectChans; // Total num of channels in the spectrum +} tSapChSelSpectInfo;//tDfsChSelParams; + +/** + * Structure for channel weight calculation parameters + */ +typedef struct sSapChSelParams { + void *pSpectInfoParams;//*pDfsParams; // Filled with tSapChSelSpectInfo + v_U16_t numChannels; +} tSapChSelParams; + +#endif // if !defined __SAP_CH_SELECT_H + diff --git a/drivers/staging/prima/CORE/SAP/src/sapFsm.c b/drivers/staging/prima/CORE/SAP/src/sapFsm.c new file mode 100644 index 000000000000..9e48d8cc619c --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapFsm.c @@ -0,0 +1,2147 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p F s m . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP Finite + State Machine modules + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-03-15 Created module + +===========================================================================*/ + + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "sapInternal.h" +#ifdef WLAN_FEATURE_AP_HT40_24G +#include "csrInsideApi.h" +#include "cfgApi.h" +#endif +// Pick up the SME API definitions +#include "sme_Api.h" +// Pick up the PMC API definitions +#include "pmcApi.h" +#include "wlan_nv.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_CH_AVOID +extern safeChannelType safeChannels[]; +#endif /* FEATURE_WLAN_CH_AVOID */ +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ +#ifdef SOFTAP_CHANNEL_RANGE +static VOS_STATUS sapGetChannelList(ptSapContext sapContext, v_U8_t **channelList, + v_U8_t *numberOfChannels); +#endif + +#ifdef WLAN_FEATURE_AP_HT40_24G +static VOS_STATUS sapGetChannelListForObss(tHalHandle halHandle, + ptSapContext psapCtx, v_U8_t **channelList, + v_U8_t *numberOfChannels); +#endif + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION sapEventInit + + DESCRIPTION + Function for initializing sWLAN_SAPEvent structure + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapEvent : State machine event + + RETURN VALUE + + None + + SIDE EFFECTS +============================================================================*/ +static inline void sapEventInit(ptWLAN_SAPEvent sapEvent) +{ + sapEvent->event = eSAP_MAC_SCAN_COMPLETE; + sapEvent->params = 0; + sapEvent->u1 = 0; + sapEvent->u2 = 0; +} + +#ifdef WLAN_FEATURE_AP_HT40_24G +/*========================================================================== + FUNCTION sapSetObssParm + + DESCRIPTION + Function for Setting OBSS Scan interval & OBSS TRANS_DELAY_FACTOR + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +void sapSetObssParm(ptSapContext sapContext) +{ + tHalHandle hHal; + tpAniSirGlobal pMac; + tANI_U32 cfgValue; + + /* tHalHandle */ + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Invalid hHal")); + return; + } + + pMac = PMAC_STRUCT( hHal ); + + if (wlan_cfgGetInt(pMac, WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + &cfgValue) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Fail to retrieve" + "WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL value")); + return; + } + + sapContext->ObssScanInterval = cfgValue; + + if (wlan_cfgGetInt(pMac, + WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR, + &cfgValue) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Fail to retrieve" + "WNI_CFG_OBSS_HT40_WIDTH_CHANNEL_TRANSITION_DELAY_FACTOR value")); + return; + } + + sapContext->ObssTransitionDelayFactor = cfgValue; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("ObssScanInterval: %d" + " ObssTransitionDelayFactor: %d"), + sapContext->ObssScanInterval, + sapContext->ObssTransitionDelayFactor); + + return; +} +#endif + + +/*========================================================================== + FUNCTION sapGotoChannelSel + + DESCRIPTION + Function for initiating scan request for SME + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoChannelSel +( + ptSapContext sapContext, + ptWLAN_SAPEvent sapEvent +) +{ + /* Initiate a SCAN request */ + eHalStatus halStatus; + tCsrScanRequest scanRequest;/* To be initialised if scan is required */ + v_U32_t scanRequestID = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eSapPhyMode sapPhyMode; + +#ifdef SOFTAP_CHANNEL_RANGE + v_U8_t *channelList = NULL; + v_U8_t numOfChannels = 0 ; +#endif + tHalHandle hHal; + tANI_U8 channel; + uint32_t operating_band = 0; + + hHal = (tHalHandle)vos_get_context( VOS_MODULE_ID_SME, sapContext->pvosGCtx); + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "In %s, invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + + sapPhyMode = + sapConvertSapPhyModeToCsrPhyMode(sapContext->csrRoamProfile.phyMode); + + /*If STA-AP concurrency is enabled take the concurrent connected channel first. In other cases wpa_supplicant should take care */ + if (vos_get_concurrency_mode() == VOS_STA_SAP) + { + channel = sme_GetConcurrentOperationChannel(hHal); + + if (channel) + { /*if a valid channel is returned then use concurrent channel. + Else take whatever comes from configuartion*/ + sapContext->channel = channel; +#ifdef WLAN_FEATURE_AP_HT40_24G + if (sapContext->channel > SIR_11B_CHANNEL_END) +#endif + sme_SelectCBMode(hHal, sapPhyMode, sapContext->channel); + } + } + + if (sapContext->channel == AUTO_CHANNEL_SELECT) + { + vos_mem_zero(&scanRequest, sizeof(scanRequest)); + + /* Set scanType to Passive scan */ + scanRequest.scanType = eSIR_PASSIVE_SCAN; + + /* Set min and max channel time to zero */ + scanRequest.minChnTime = 0; + scanRequest.maxChnTime = 0; + + /* Set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + +#ifndef SOFTAP_CHANNEL_RANGE + /*Scan all the channels */ + scanRequest.ChannelInfo.numOfChannels = 0; + + scanRequest.ChannelInfo.ChannelList = NULL; + + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;//eCSR_SCAN_REQUEST_11D_SCAN; + +#else + + sapGetChannelList(sapContext, &channelList, &numOfChannels); + + /*Scan the channels in the list*/ + scanRequest.ChannelInfo.numOfChannels = numOfChannels; + + scanRequest.ChannelInfo.ChannelList = channelList; + + scanRequest.requestType = eCSR_SCAN_SOFTAP_CHANNEL_RANGE; + + sapContext->numofChannel = numOfChannels; + + sapContext->channelList = channelList; + +#endif + /* Set requestType to Full scan */ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Auto Channel Selection Scan")); + + halStatus = sme_ScanRequest(hHal, + 0,//Not used in csrScanRequest + &scanRequest, + &scanRequestID,//, when ID == 0 11D scan/active scan with callback, min-maxChntime set in csrScanRequest()? + &WLANSAP_ScanCallback,//csrScanCompleteCallback callback, + sapContext);//void * pContext scanRequestID filled up + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Auto Channel Selection Scan fail %d!!!"), halStatus); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SoftAP Configuring for default channel, Ch= %d"), + sapContext->channel); + /* + * In case of error, select channel based on band + * configured in .ini + */ + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + &operating_band); + if (operating_band == eSAP_RF_SUBBAND_5_LOW_GHZ || + operating_band == eSAP_RF_SUBBAND_5_MID_GHZ || + operating_band == eSAP_RF_SUBBAND_5_HIGH_GHZ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Default channel selection from band %d"), + operating_band); + + (operating_band == eSAP_RF_SUBBAND_5_LOW_GHZ) ? + (sapContext->channel = SAP_DEFAULT_LOW_5GHZ_CHANNEL) : + (operating_band == eSAP_RF_SUBBAND_5_MID_GHZ) ? + (sapContext->channel = SAP_DEFAULT_MID_5GHZ_CHANNEL) : + (operating_band == eSAP_RF_SUBBAND_5_HIGH_GHZ) ? + (sapContext->channel = + SAP_DEFAULT_HIGH_5GHZ_CHANNEL) : 0; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("channel selected to start bss %d"), + sapContext->channel); + } + else + { + sapContext->channel = SAP_DEFAULT_24GHZ_CHANNEL; + } + +#ifdef SOFTAP_CHANNEL_RANGE + if(sapContext->channelList != NULL) + { + sapContext->channel = sapContext->channelList[0]; + vos_mem_free(sapContext->channelList); + sapContext->channelList = NULL; + } +#endif + /* Fill in the event structure */ + sapEventInit(sapEvent); + /* Handle event */ + vosStatus = sapFsm(sapContext, sapEvent); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Auto Channel Selection Scan Success" + " scanRequestID=%d, Ch= %d"), + scanRequestID, sapContext->channel); + } + + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("For configured channel, Ch= %d"), sapContext->channel); + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (vos_get_concurrency_mode() != VOS_STA_SAP) + { + if ((sapContext->channel <= SIR_11B_CHANNEL_END) + && (sapContext->channel > RF_CHAN_1)) + { + // OBSS Scan for P2P GO/SAP where Auto Channel Selection is Disable + vosStatus = sapGetChannelListForObss(hHal, sapContext, + &channelList, &numOfChannels); + if (VOS_STATUS_SUCCESS == vosStatus && channelList != NULL) + { + + if (sapCheckHT40SecondaryIsNotAllowed(sapContext)) + { + if(channelList != NULL) + { + vos_mem_free(channelList); + channelList = NULL; + } + goto disable24GChannelBonding; + } + vos_mem_zero(&scanRequest, sizeof(scanRequest)); + + /* Set scanType to Passive scan */ + scanRequest.scanType = eSIR_PASSIVE_SCAN; + + /* Set min and max channel time to zero */ + scanRequest.minChnTime = CSR_ACTIVE_MIN_CHANNEL_TIME; + scanRequest.maxChnTime = CSR_ACTIVE_MAX_CHANNEL_TIME; + + /* Set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + /*Scan the channels in the list*/ + scanRequest.ChannelInfo.numOfChannels = numOfChannels; + scanRequest.ChannelInfo.ChannelList = channelList; + scanRequest.requestType = eCSR_SCAN_SOFTAP_CHANNEL_RANGE; + sapContext->channelList = channelList; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("OBSS Scan for SAP/P2P GO: Ch= %d"), + sapContext->channel); + + halStatus = sme_ScanRequest(hHal, + 0,//Not used in csrScanRequest + &scanRequest, + &scanRequestID,//, when ID == 0 11D scan/active scan with callback, min-maxChntime set in csrScanRequest()? + &WLANSAP_ScanCallback,//csrScanCompleteCallback callback, + sapContext);//void * pContext scanRequestID filled up + + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("OBSS ScanRequest Fail %d!!!"), + halStatus); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("SoftAP Configuring for default channel, Ch= %d"), + sapContext->channel); + + if(sapContext->channelList != NULL) + { + vos_mem_free(sapContext->channelList); + sapContext->channelList = NULL; + } + goto disable24GChannelBonding; + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("OBSS ScanRequest Success, scanRequestID=%d" + " Ch= %d"), scanRequestID, sapContext->channel); + goto startgo; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Failed to Prepare the OBSS Scan channel list")); + goto disable24GChannelBonding; + } +disable24GChannelBonding: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Disable Channel Bonding")); + /* Disable Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(hHal, + PHY_SINGLE_CHANNEL_CENTERED); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("No concurrency & Channel: %d"), + sapContext->channel); + goto selectChannelBonding; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("With concurrency & Channel: %d"), + sapContext->channel); + goto selectChannelBonding; + } +#endif + +#ifdef WLAN_FEATURE_AP_HT40_24G +selectChannelBonding: + if (sapContext->channel > SIR_11B_CHANNEL_END) +#endif + sme_SelectCBMode(hHal, sapPhyMode, sapContext->channel); + + /* Fill in the event structure */ + // Eventhough scan was not done, means a user set channel was chosen + sapEventInit(sapEvent); + /* Handle event */ + vosStatus = sapFsm(sapContext, sapEvent); + } +#ifdef WLAN_FEATURE_AP_HT40_24G +startgo: +#endif + /* If scan failed, get default channel and advance state + * machine as success with default channel. Have to wait + * for the call back to be called to get the channel cannot + * advance state machine here as said above */ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Before exiting sapGotoChannelSel channel=%d"), + sapContext->channel); + + return VOS_STATUS_SUCCESS; +}// sapGotoChannelSel + +/*========================================================================== + FUNCTION sapGotoStarting + + DESCRIPTION + Function for initiating start bss request for SME + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + bssType : Type of bss to start, INRA AP + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoStarting +( + ptSapContext sapContext, + ptWLAN_SAPEvent sapEvent, + eCsrRoamBssType bssType +) +{ + /* tHalHandle */ + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + eHalStatus halStatus; + + /*- - - - - - - - TODO:once configs from hdd available - - - - - - - - -*/ + char key_material[32]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,}; + sapContext->key_type = 0x05; + sapContext->key_length = 32; + vos_mem_copy(sapContext->key_material, key_material, sizeof(key_material)); /* Need a key size define */ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s", __func__); + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "In %s, invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + + //TODO: What shall we do if failure???? + halStatus = pmcRequestFullPower( hHal, + WLANSAP_pmcFullPwrReqCB, + sapContext, + eSME_REASON_OTHER); + + /* Open SME Session for Softap */ + halStatus = sme_OpenSession(hHal, + &WLANSAP_RoamCallback, + sapContext, + sapContext->self_mac_addr, + &sapContext->sessionId); + + if(eHAL_STATUS_SUCCESS != halStatus ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Error: In %s calling sme_RoamConnect status = %d", __func__, halStatus); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +}// sapGotoStarting + +/*========================================================================== + FUNCTION sapGotoDisconnecting + + DESCRIPTION + Processing of SAP FSM Disconnecting state + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoDisconnecting +( + ptSapContext sapContext +) +{ + eHalStatus halStatus; + tHalHandle hHal; + + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + /* we have a serious problem */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, invalid hHal", __func__); + return VOS_STATUS_E_FAULT; + } + + sapFreeRoamProfile(&sapContext->csrRoamProfile); + halStatus = sme_RoamStopBss(hHal, sapContext->sessionId); + if(eHAL_STATUS_SUCCESS != halStatus ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Error: In %s calling sme_RoamStopBss status = %d", __func__, halStatus); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +static eHalStatus sapRoamSessionCloseCallback(void *pContext) +{ + ptSapContext sapContext = (ptSapContext)pContext; + return sapSignalHDDevent(sapContext, NULL, + eSAP_STOP_BSS_EVENT, (v_PVOID_t) eSAP_STATUS_SUCCESS); +} + +/*========================================================================== + FUNCTION sapGotoDisconnected + + DESCRIPTION + Function for setting the SAP FSM to Disconnection state + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapGotoDisconnected +( + ptSapContext sapContext +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + tWLAN_SAPEvent sapEvent; + // Processing has to be coded + // Clean up stations from TL etc as AP BSS is shut down then set event + sapEvent.event = eSAP_MAC_READY_FOR_CONNECTIONS;// hardcoded + sapEvent.params = 0; + sapEvent.u1 = 0; + sapEvent.u2 = 0; + /* Handle event */ + vosStatus = sapFsm(sapContext, &sapEvent); + + return vosStatus; +} + +/*========================================================================== + FUNCTION sapSignalHDDevent + + DESCRIPTION + Function for HDD to send the event notification using callback + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + pCsrRoamInfo : Pointer to CSR roam information + sapHddevent : SAP HDD event + context : to pass the element for future support + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapSignalHDDevent +( + ptSapContext sapContext, /* sapContext value */ + tCsrRoamInfo *pCsrRoamInfo, + eSapHddEvent sapHddevent, + void *context +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tSap_Event sapApAppEvent; /* This now encodes ALL event types */ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /* Format the Start BSS Complete event to return... */ + if (NULL == sapContext->pfnSapEventCallback) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("HDD Event callaback invalid")); + return VOS_STATUS_E_INVAL; + } + + switch (sapHddevent) + { + case eSAP_STA_ASSOC_IND: + // TODO - Indicate the assoc request indication to OS + sapApAppEvent.sapHddEventCode = eSAP_STA_ASSOC_IND; + + vos_mem_copy( &sapApAppEvent.sapevt.sapAssocIndication.staMac, pCsrRoamInfo->peerMac,sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapAssocIndication.staId = pCsrRoamInfo->staId; + sapApAppEvent.sapevt.sapAssocIndication.status = 0; + // Required for indicating the frames to upper layer + sapApAppEvent.sapevt.sapAssocIndication.beaconLength = pCsrRoamInfo->beaconLength; + sapApAppEvent.sapevt.sapAssocIndication.beaconPtr = pCsrRoamInfo->beaconPtr; + sapApAppEvent.sapevt.sapAssocIndication.assocReqLength = pCsrRoamInfo->assocReqLength; + sapApAppEvent.sapevt.sapAssocIndication.assocReqPtr = pCsrRoamInfo->assocReqPtr; + sapApAppEvent.sapevt.sapAssocIndication.fWmmEnabled = pCsrRoamInfo->wmmEnabledSta; + if ( pCsrRoamInfo->u.pConnectedProfile != NULL ) + { + sapApAppEvent.sapevt.sapAssocIndication.negotiatedAuthType = pCsrRoamInfo->u.pConnectedProfile->AuthType; + sapApAppEvent.sapevt.sapAssocIndication.negotiatedUCEncryptionType = pCsrRoamInfo->u.pConnectedProfile->EncryptionType; + sapApAppEvent.sapevt.sapAssocIndication.negotiatedMCEncryptionType = pCsrRoamInfo->u.pConnectedProfile->mcEncryptionType; + sapApAppEvent.sapevt.sapAssocIndication.fAuthRequired = pCsrRoamInfo->fAuthRequired; + } + break; + case eSAP_START_BSS_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_START_BSS_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_START_BSS_EVENT; + sapApAppEvent.sapevt.sapStartBssCompleteEvent.status = (eSapStatus )context; + if(pCsrRoamInfo != NULL ){ + sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId = pCsrRoamInfo->staId; + } + else + sapApAppEvent.sapevt.sapStartBssCompleteEvent.staId = 0; + sapApAppEvent.sapevt.sapStartBssCompleteEvent.operatingChannel = (v_U8_t)sapContext->channel; + break; + + case eSAP_STOP_BSS_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_STOP_BSS_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STOP_BSS_EVENT; + sapApAppEvent.sapevt.sapStopBssCompleteEvent.status = (eSapStatus )context; + break; + + case eSAP_STA_ASSOC_EVENT: + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_STA_ASSOC_EVENT"); + if (pCsrRoamInfo->fReassocReq) + sapApAppEvent.sapHddEventCode = eSAP_STA_REASSOC_EVENT; + else + sapApAppEvent.sapHddEventCode = eSAP_STA_ASSOC_EVENT; + + //TODO: Need to fill the SET KEY information and pass to HDD + vos_mem_copy( &sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.staMac, + pCsrRoamInfo->peerMac,sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.staId = pCsrRoamInfo->staId ; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.statusCode = pCsrRoamInfo->statusCode; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.iesLen = pCsrRoamInfo->rsnIELen; + vos_mem_copy(sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.ies, pCsrRoamInfo->prsnIE, + pCsrRoamInfo->rsnIELen); + + if(pCsrRoamInfo->addIELen) + { + v_U8_t len = sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.iesLen; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.iesLen + += pCsrRoamInfo->addIELen; + vos_mem_copy(&sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.ies[len], pCsrRoamInfo->paddIE, + pCsrRoamInfo->addIELen); + } + + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.rate_flags = pCsrRoamInfo->maxRateFlags; + + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.wmmEnabled = pCsrRoamInfo->wmmEnabledSta; + sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.status = (eSapStatus )context; + //TODO: Need to fill sapAuthType + //sapApAppEvent.sapevt.sapStationAssocReassocCompleteEvent.SapAuthType = pCsrRoamInfo->pProfile->negotiatedAuthType; + break; + } + + case eSAP_STA_DISASSOC_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_STA_DISASSOC_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_DISASSOC_EVENT; + + vos_mem_copy( &sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.staMac, + pCsrRoamInfo->peerMac, sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.staId = pCsrRoamInfo->staId; + if (pCsrRoamInfo->reasonCode == eCSR_ROAM_RESULT_FORCED) + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_USR_INITATED_DISASSOC; + else + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.reason = eSAP_MAC_INITATED_DISASSOC; + + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.statusCode = pCsrRoamInfo->statusCode; + sapApAppEvent.sapevt.sapStationDisassocCompleteEvent.status = (eSapStatus )context; + break; + + case eSAP_STA_SET_KEY_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_STA_SET_KEY_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_SET_KEY_EVENT; + sapApAppEvent.sapevt.sapStationSetKeyCompleteEvent.status = (eSapStatus )context; + vos_mem_copy(&sapApAppEvent.sapevt.sapStationSetKeyCompleteEvent.peerMacAddr, + pCsrRoamInfo->peerMac,sizeof(tSirMacAddr)); + break; + + case eSAP_STA_DEL_KEY_EVENT : + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_STA_DEL_KEY_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_DEL_KEY_EVENT; + sapApAppEvent.sapevt.sapStationDeleteKeyCompleteEvent.status = (eSapStatus )context; + //TODO: Should we need to send the key information + //sapApAppEvent.sapevt.sapStationDeleteKeyCompleteEvent.keyId = ; + break; + + case eSAP_STA_MIC_FAILURE_EVENT : + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_STA_MIC_FAILURE_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_STA_MIC_FAILURE_EVENT; + vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.srcMacAddr, + pCsrRoamInfo->u.pMICFailureInfo->srcMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.staMac, + pCsrRoamInfo->u.pMICFailureInfo->taMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy( &sapApAppEvent.sapevt.sapStationMICFailureEvent.dstMacAddr, + pCsrRoamInfo->u.pMICFailureInfo->dstMacAddr, + sizeof(tSirMacAddr)); + sapApAppEvent.sapevt.sapStationMICFailureEvent.multicast = pCsrRoamInfo->u.pMICFailureInfo->multicast; + sapApAppEvent.sapevt.sapStationMICFailureEvent.IV1 = pCsrRoamInfo->u.pMICFailureInfo->IV1; + sapApAppEvent.sapevt.sapStationMICFailureEvent.keyId = pCsrRoamInfo->u.pMICFailureInfo->keyId; + vos_mem_copy( sapApAppEvent.sapevt.sapStationMICFailureEvent.TSC, + pCsrRoamInfo->u.pMICFailureInfo->TSC, + SIR_CIPHER_SEQ_CTR_SIZE); + break; + + case eSAP_ASSOC_STA_CALLBACK_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_ASSOC_STA_CALLBACK_EVENT"); + break; + + case eSAP_WPS_PBC_PROBE_REQ_EVENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_WPS_PBC_PROBE_REQ_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_WPS_PBC_PROBE_REQ_EVENT; + + vos_mem_copy( &sapApAppEvent.sapevt.sapPBCProbeReqEvent.WPSPBCProbeReq, + pCsrRoamInfo->u.pWPSPBCProbeReq, + sizeof(tSirWPSPBCProbeReq)); + break; + case eSAP_REMAIN_CHAN_READY: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_REMAIN_CHAN_READY"); + sapApAppEvent.sapHddEventCode = eSAP_REMAIN_CHAN_READY; + break; + case eSAP_SEND_ACTION_CNF: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_SEND_ACTION_CNF"); + sapApAppEvent.sapHddEventCode = eSAP_SEND_ACTION_CNF; + sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context; + break; + + case eSAP_DISCONNECT_ALL_P2P_CLIENT: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_DISCONNECT_ALL_P2P_CLIENT"); + sapApAppEvent.sapHddEventCode = eSAP_DISCONNECT_ALL_P2P_CLIENT; + sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context; + break; + + case eSAP_MAC_TRIG_STOP_BSS_EVENT : + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_MAC_TRIG_STOP_BSS_EVENT"); + sapApAppEvent.sapHddEventCode = eSAP_MAC_TRIG_STOP_BSS_EVENT; + sapApAppEvent.sapevt.sapActionCnf.actionSendSuccess = (eSapStatus)context; + break; + + + case eSAP_UNKNOWN_STA_JOIN: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_UNKNOWN_STA_JOIN"); + sapApAppEvent.sapHddEventCode = eSAP_UNKNOWN_STA_JOIN; + vos_mem_copy((v_PVOID_t)sapApAppEvent.sapevt.sapUnknownSTAJoin.macaddr.bytes, + (v_PVOID_t)context, sizeof(v_MACADDR_t)); + break; + + case eSAP_MAX_ASSOC_EXCEEDED: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + FL("SAP event callback event = %s"), + "eSAP_MAX_ASSOC_EXCEEDED"); + sapApAppEvent.sapHddEventCode = eSAP_MAX_ASSOC_EXCEEDED; + vos_mem_copy((v_PVOID_t)sapApAppEvent.sapevt.sapMaxAssocExceeded.macaddr.bytes, + (v_PVOID_t)pCsrRoamInfo->peerMac, sizeof(v_MACADDR_t)); + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("SAP Unknown callback event = %d"), + sapHddevent); + break; + } + vosStatus = (*sapContext->pfnSapEventCallback) + ( + &sapApAppEvent, + sapContext->pUsrContext//userdataforcallback - hdd opaque handle + ); + + return vosStatus; + +} /* sapSignalApAppStartBssEvent */ + +/*========================================================================== + FUNCTION sapFsm + + DESCRIPTION + SAP State machine entry function + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + sapEvent : State machine event + status : Return the SAP status here + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +sapFsm +( + ptSapContext sapContext, /* sapContext value */ + ptWLAN_SAPEvent sapEvent /* State machine event */ +) +{ + /* Retrieve the phy link state machine structure + * from the sapContext value + */ + eSapFsmStates_t stateVar = sapContext->sapsMachine; /*state var that keeps track of state machine*/ + tCsrRoamInfo *roamInfo = (tCsrRoamInfo *)(sapEvent->params); + v_U32_t msg = sapEvent->event; /* State machine input event message */ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + + switch (stateVar) + { + case eSAP_DISCONNECTED: + if ((msg == eSAP_HDD_START_INFRA_BSS)) + { + /* Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, new from state %s => %s", + __func__, "eSAP_DISCONNECTED", "eSAP_CH_SELECT"); + + /* There can be one SAP Session for softap */ + if (sapContext->isSapSessionOpen == eSAP_TRUE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "%s:SME Session is already opened\n",__func__); + return VOS_STATUS_E_EXISTS; + } + + sapContext->sessionId = 0xff; + + /* Set SAP device role */ + sapContext->sapsMachine = eSAP_CH_SELECT; + +#ifdef WLAN_FEATURE_AP_HT40_24G + sapSetObssParm(sapContext); +#endif + /* Perform sme_ScanRequest */ + vosStatus = sapGotoChannelSel(sapContext, sapEvent); + + /* Transition from eSAP_DISCONNECTED to eSAP_CH_SELECT (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_DISCONNECTED", "eSAP_CH_SELECT"); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, event msg %d", + __func__, "eSAP_DISCONNECTED", msg); + } + break; + + case eSAP_CH_SELECT: + if (msg == eSAP_MAC_SCAN_COMPLETE) + { + /* Transition from eSAP_CH_SELECT to eSAP_STARTING (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_CH_SELECT", "eSAP_STARTING"); + // Channel selected. Now can sapGotoStarting + sapContext->sapsMachine = eSAP_STARTING; + // Specify the channel + sapContext->csrRoamProfile.ChannelInfo.numOfChannels = 1; + sapContext->csrRoamProfile.ChannelInfo.ChannelList = &sapContext->csrRoamProfile.operationChannel; + sapContext->csrRoamProfile.operationChannel = (tANI_U8)sapContext->channel; + vosStatus = sapGotoStarting( sapContext, sapEvent, eCSR_BSS_TYPE_INFRA_AP); + /* Transition from eSAP_CH_SELECT to eSAP_STARTING (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_CH_SELECT", "eSAP_STARTING"); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_CH_SELECT", msg); + } + break; + + case eSAP_STARTING: + if (msg == eSAP_MAC_START_BSS_SUCCESS ) + { + /* Transition from eSAP_STARTING to eSAP_STARTED (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state channel = %d %s => %s", + __func__,sapContext->channel, "eSAP_STARTING", "eSAP_STARTED"); + + sapContext->sapsMachine = eSAP_STARTED; + /*Action code for transition */ + vosStatus = sapSignalHDDevent( sapContext, roamInfo, eSAP_START_BSS_EVENT, (v_PVOID_t)eSAP_STATUS_SUCCESS); + + /* Transition from eSAP_STARTING to eSAP_STARTED (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_STARTING", "eSAP_STARTED"); + +#ifdef WLAN_FEATURE_AP_HT40_24G + /* Initialize the HT2040 timer */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "In %s, Init HT20/40 timer", __func__); + + vosStatus = vos_timer_init( &sapContext->sap_HT2040_timer, + VOS_TIMER_TYPE_SW, sap_ht2040_timer_cb, + (v_PVOID_t)sapContext ); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, Failed to Init HT20/40 timer", __func__); +#endif + } + else if ((msg == eSAP_HDD_STOP_INFRA_BSS) || + (msg == eSAP_MAC_START_FAILS)) + { + /*Transition from eSAP_STARTING to eSAP_DISCONNECTING (both without substates)*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_STARTING", "eSAP_DISCONNECTING"); + + /*Advance outer statevar */ + sapContext->sapsMachine = eSAP_DISCONNECTED; + vosStatus = sapSignalHDDevent( sapContext, NULL, eSAP_START_BSS_EVENT, (v_PVOID_t)eSAP_STATUS_FAILURE); + vosStatus = sapGotoDisconnected(sapContext); + +#ifdef WLAN_FEATURE_AP_HT40_24G + /* Reset the OBSS Affected Channel Range */ + if ( (0 != sapContext->affected_start) + && (0 != sapContext->affected_end) + && (0 != sapContext->sap_sec_chan) ) + { + sapContext->affected_start = 0; + sapContext->affected_end = 0; + sapContext->sap_sec_chan = 0; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Reset the OBSS Affected Channel Range [%d %d]"), + sapContext->affected_start, sapContext->affected_end); + + } +#endif + /* Close the SME session*/ + + if (eSAP_TRUE == sapContext->isSapSessionOpen) + { + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_STARTING", msg); + } + else if (eHAL_STATUS_SUCCESS == + sme_CloseSession(hHal, + sapContext->sessionId, FALSE, + VOS_TRUE, NULL, NULL)) + { + sapContext->isSapSessionOpen = eSAP_FALSE; + } + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_STARTING", msg); + /* Intentionally left blank */ + } + break; + + case eSAP_STARTED: + if (msg == eSAP_HDD_STOP_INFRA_BSS) + { + /* Transition from eSAP_STARTED to eSAP_DISCONNECTING (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_STARTED", "eSAP_DISCONNECTING"); + sapContext->sapsMachine = eSAP_DISCONNECTING; + vosStatus = sapGotoDisconnecting(sapContext); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_STARTED", msg); + } +#ifdef WLAN_FEATURE_AP_HT40_24G + /* Reset the OBSS Affected Channel Range */ + if ( (0 != sapContext->affected_start) + && (0 != sapContext->affected_end) + && (0 != sapContext->sap_sec_chan) ) + { + sapContext->affected_start = 0; + sapContext->affected_end = 0; + sapContext->sap_sec_chan = 0; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Reset the OBSS Affected Channel Range [%d %d]"), + sapContext->affected_start, sapContext->affected_end); + } + + if (VOS_TIMER_STATE_RUNNING == sapContext->sap_HT2040_timer.state) + { + vosStatus = vos_timer_stop(&sapContext->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + + vosStatus = vos_timer_destroy(&sapContext->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Destroy HT20/40 timer")); +#endif + break; + + case eSAP_DISCONNECTING: + if (msg == eSAP_MAC_READY_FOR_CONNECTIONS) + { + /* Transition from eSAP_DISCONNECTING to eSAP_DISCONNECTED (both without substates) */ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "In %s, from state %s => %s", + __func__, "eSAP_DISCONNECTING", "eSAP_DISCONNECTED"); + + sapContext->sapsMachine = eSAP_DISCONNECTED; + /* Close the SME session*/ + if (eSAP_TRUE == sapContext->isSapSessionOpen) + { + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, NULL hHal in state %s, msg %d", + __func__, "eSAP_DISCONNECTING", msg); + } + else + { + sapContext->isSapSessionOpen = eSAP_FALSE; + sme_CloseSession(hHal, + sapContext->sessionId, TRUE, VOS_TRUE, + NULL, sapContext); + + vosStatus = sapSignalHDDevent(sapContext, NULL, + eSAP_STOP_BSS_EVENT, + (v_PVOID_t) eSAP_STATUS_SUCCESS); + } + } + } + if (msg == eSAP_CHANNEL_SELECTION_FAILED) + { + /* Set SAP device role */ + sapContext->sapsMachine = eSAP_CH_SELECT; + + /* Perform sme_ScanRequest */ + vosStatus = sapGotoChannelSel(sapContext, sapEvent); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "In %s, in state %s, invalid event msg %d", + __func__, "eSAP_DISCONNECTING", msg); + } + break; + } + return vosStatus; +}// sapFsm + + +eSapStatus +sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, tCsrRoamProfile *profile) +{ + //Create Roam profile for SoftAP to connect + profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; + profile->SSIDs.numOfSSIDs = 1; + profile->csrPersona = pconfig_params->persona; + + vos_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, + sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); + + //Flag to not broadcast the SSID information + profile->SSIDs.SSIDList[0].ssidHidden = pconfig_params->SSIDinfo.ssidHidden; + + profile->SSIDs.SSIDList[0].SSID.length = pconfig_params->SSIDinfo.ssid.length; + vos_mem_copy(&profile->SSIDs.SSIDList[0].SSID.ssId, pconfig_params->SSIDinfo.ssid.ssId, + sizeof(pconfig_params->SSIDinfo.ssid.ssId)); + + profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + if (pconfig_params->authType == eSAP_OPEN_SYSTEM) + { + profile->negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + } + else if (pconfig_params->authType == eSAP_SHARED_KEY) + { + profile->negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; + } + else + { + profile->negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; + } + + profile->AuthType.numEntries = 1; + profile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + + //Always set the Encryption Type + profile->EncryptionType.numEntries = 1; + profile->EncryptionType.encryptionType[0] = pconfig_params->RSNEncryptType; + + profile->mcEncryptionType.numEntries = 1; + profile->mcEncryptionType.encryptionType[0] = pconfig_params->mcRSNEncryptType; + + if (pconfig_params->privacy & eSAP_SHARED_KEY) + { + profile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY; + } + + profile->privacy = pconfig_params->privacy; + profile->fwdWPSPBCProbeReq = pconfig_params->fwdWPSPBCProbeReq; + + if (pconfig_params->authType == eSAP_SHARED_KEY) + { + profile->csr80211AuthType = eSIR_SHARED_KEY; + } + else if (pconfig_params->authType == eSAP_OPEN_SYSTEM) + { + profile->csr80211AuthType = eSIR_OPEN_SYSTEM; + } + else + { + profile->csr80211AuthType = eSIR_AUTO_SWITCH; + } + + //Initialize we are not going to use it + profile->pWPAReqIE = NULL; + profile->nWPAReqIELength = 0; + + //set the RSN/WPA IE + profile->pRSNReqIE = NULL; + profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; + if (pconfig_params->RSNWPAReqIELength) + { + profile->pRSNReqIE = vos_mem_malloc(pconfig_params->RSNWPAReqIELength); + if( NULL == profile->pRSNReqIE ) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, " %s Fail to alloc memory", __func__); + return eSAP_STATUS_FAILURE; + } + vos_mem_copy(profile->pRSNReqIE, pconfig_params->RSNWPAReqIE, + pconfig_params->RSNWPAReqIELength); + profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength; + } + + // Turn off CB mode + profile->CBMode = eCSR_CB_OFF; + + //set the phyMode to accept anything + //Best means everything because it covers all the things we support + profile->phyMode = pconfig_params->SapHw_mode; /*eCSR_DOT11_MODE_BEST*/ + + //Configure beaconInterval + profile->beaconInterval = (tANI_U16)pconfig_params->beacon_int; + + // set DTIM period + profile->dtimPeriod = pconfig_params->dtim_period; + + //set Uapsd enable bit + profile->ApUapsdEnable = pconfig_params->UapsdEnable; + + //Enable protection parameters + profile->protEnabled = pconfig_params->protEnabled; + profile->obssProtEnabled = pconfig_params->obssProtEnabled; + profile->cfg_protection = pconfig_params->ht_capab; + + //country code + if (pconfig_params->countryCode[0]) + vos_mem_copy(profile->countryCode, pconfig_params->countryCode, WNI_CFG_COUNTRY_CODE_LEN); + profile->ieee80211d = pconfig_params->ieee80211d; + //wps config info + profile->wps_state = pconfig_params->wps_state; + +#ifdef WLAN_FEATURE_11W + // MFP capable/required + profile->MFPCapable = pconfig_params->mfpCapable ? 1 : 0; + profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; +#endif + + return eSAP_STATUS_SUCCESS; /* Success. */ +} + +/** + * FUNCTION: sapConvertSapPhyModeToCsrPhyMode + * Called internally by SAP + */ +eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode ) +{ + switch (sapPhyMode) + { + case (eSAP_DOT11_MODE_abg): + return eCSR_DOT11_MODE_abg; + case (eSAP_DOT11_MODE_11b): + return eCSR_DOT11_MODE_11b; + case (eSAP_DOT11_MODE_11g): + return eCSR_DOT11_MODE_11g; + case (eSAP_DOT11_MODE_11n): + return eCSR_DOT11_MODE_11n; + case (eSAP_DOT11_MODE_11g_ONLY): + return eCSR_DOT11_MODE_11g_ONLY; + case (eSAP_DOT11_MODE_11n_ONLY): + return eCSR_DOT11_MODE_11n_ONLY; + case (eSAP_DOT11_MODE_11b_ONLY): + return eCSR_DOT11_MODE_11b_ONLY; +#ifdef WLAN_FEATURE_11AC + case (eSAP_DOT11_MODE_11ac_ONLY): + return eCSR_DOT11_MODE_11ac_ONLY; + case (eSAP_DOT11_MODE_11ac): + return eCSR_DOT11_MODE_11ac; +#endif + case (eSAP_DOT11_MODE_11a): + return eCSR_DOT11_MODE_11a; + default: + return eCSR_DOT11_MODE_AUTO; + } +} + +void sapFreeRoamProfile(tCsrRoamProfile *profile) +{ + if(profile->pRSNReqIE) + { + vos_mem_free(profile->pRSNReqIE); + profile->pRSNReqIE = NULL; + } +} + + +void +sapSortMacList(v_MACADDR_t *macList, v_U8_t size) +{ + v_U8_t outer, inner; + v_MACADDR_t temp; + v_SINT_t nRes = -1; + + if ((NULL == macList) || (size >= MAX_ACL_MAC_ADDRESS)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, either buffer is NULL or size = %d is more." + ,__func__, size); + return; + } + + for(outer = 0; outer < size; outer++) + { + for(inner = 0; inner < size - 1; inner++) + { + nRes = vos_mem_compare2((macList + inner)->bytes, (macList + inner + 1)->bytes, sizeof(v_MACADDR_t)); + if (nRes > 0) + { + vos_mem_copy(temp.bytes, (macList + inner + 1)->bytes, sizeof(v_MACADDR_t)); + vos_mem_copy((macList + inner + 1)->bytes, (macList + inner)->bytes, sizeof(v_MACADDR_t)); + vos_mem_copy((macList + inner)->bytes, temp.bytes, sizeof(v_MACADDR_t)); + } + } + } +} + +eSapBool +sapSearchMacList(v_MACADDR_t *macList, v_U8_t num_mac, v_U8_t *peerMac, v_U8_t *index) +{ + v_SINT_t nRes = -1; + v_S7_t nStart = 0, nEnd, nMiddle; + nEnd = num_mac - 1; + + while (nStart <= nEnd) + { + nMiddle = (nStart + nEnd) / 2; + nRes = vos_mem_compare2(&macList[nMiddle], peerMac, sizeof(v_MACADDR_t)); + + if (0 == nRes) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "search SUCC"); + // "index equals NULL" means the caller does not need the + // index value of the peerMac being searched + if (index != NULL) + { + *index = (v_U8_t) nMiddle; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "index %d", *index); + } + return eSAP_TRUE; + } + if (nRes < 0) + nStart = nMiddle + 1; + else + nEnd = nMiddle - 1; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "search not succ"); + return eSAP_FALSE; +} + +void +sapAddMacToACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t *peerMac) +{ + v_SINT_t nRes = -1; + int i; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"add acl entered"); + + if ((NULL == macList) || (*size >= MAX_ACL_MAC_ADDRESS)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, either buffer is NULL or size %d is incorrect." + , __func__, *size); + return; + } + + for (i=((*size)-1); i>=0; i--) + { + nRes = vos_mem_compare2(&macList[i], peerMac, sizeof(v_MACADDR_t)); + if (nRes > 0) + { + /* Move alphabetically greater mac addresses one index down to allow for insertion + of new mac in sorted order */ + vos_mem_copy((macList+i+1)->bytes,(macList+i)->bytes, sizeof(v_MACADDR_t)); + } + else + { + break; + } + } + //This should also take care of if the element is the first to be added in the list + vos_mem_copy((macList+i+1)->bytes, peerMac, sizeof(v_MACADDR_t)); + // increment the list size + (*size)++; +} + +void +sapRemoveMacFromACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t index) +{ + int i; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"remove acl entered"); + /* return if the list passed is empty. Ideally this should never happen since this funcn is always + called after sapSearchMacList to get the index of the mac addr to be removed and this will + only get called if the search is successful. Still no harm in having the check */ + if ((macList==NULL) || (*size == 0) || (*size > MAX_ACL_MAC_ADDRESS)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, either buffer is NULL or size %d is incorrect." + , __func__, *size); + return; + } + for (i=index; i<((*size)-1); i++) + { + /* Move mac addresses starting from "index" passed one index up to delete the void + created by deletion of a mac address in ACL */ + vos_mem_copy((macList+i)->bytes,(macList+i+1)->bytes, sizeof(v_MACADDR_t)); + } + // The last space should be made empty since all mac addesses moved one step up + vos_mem_zero((macList+(*size)-1)->bytes, sizeof(v_MACADDR_t)); + //reduce the list size by 1 + (*size)--; +} + +void sapPrintACL(v_MACADDR_t *macList, v_U8_t size) +{ + int i; + v_BYTE_t *macArray; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"print acl entered"); + + if ((NULL == macList) || (size == 0) || (size >= MAX_ACL_MAC_ADDRESS)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, either buffer is NULL or size %d is incorrect." + , __func__, size); + return; + } + + for (i=0; ibytes; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "** ACL entry %i - "MAC_ADDRESS_STR, i, + MAC_ADDR_ARRAY(macArray)); + } + return; +} + +/*========================================================================== + FUNCTION sapGetStaId + + DESCRIPTION + Get the STA ID from Mac address. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + staId : STA ID + pCsrRoamInfo : Pointer to CSR info + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS sapGetStaId(ptSapContext sapContext, v_U8_t *staId, + tCsrRoamInfo *pCsrRoamInfo) +{ + v_U8_t i; + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (vos_mem_compare(&sapContext->aStaInfo[i].macAddrSTA, + pCsrRoamInfo->peerMac, sizeof(v_MACADDR_t)) + && sapContext->aStaInfo[i].isUsed) + { + *staId = i; + return VOS_STATUS_SUCCESS; + } + } + return VOS_STATUS_E_FAILURE; +} + +/*========================================================================== + FUNCTION sapAddHT40IntolerantSta + + DESCRIPTION + Add HT40 Intolerant STA & Move SAP from HT40 to HT20 + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + pCsrRoamInfo : Pointer to CSR info + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +#ifdef WLAN_FEATURE_AP_HT40_24G +void sapAddHT40IntolerantSta(ptSapContext sapContext, + tCsrRoamInfo *pCsrRoamInfo) +{ + + tHalHandle hHal; + v_U8_t cbMode; + tANI_U8 staId; + eHalStatus halStatus; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /* tHalHandle */ + hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("In invalid hHal")); + return; + } + + staId = pCsrRoamInfo->staId; + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Add HT40 MHz Intolerant STA :" + MAC_ADDRESS_STR " STA ID: %d"), + MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac), + staId); + + // Get Channel Bonding Mode + cbMode = sme_GetChannelBondingMode24G(hHal); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Current Channel Bonding Mode: %d " + "HT40IntolerantSet: %d"), + cbMode, sapContext->aStaInfo[staId].isHT40IntolerantSet); + + if(sapContext->aStaInfo[staId].isHT40IntolerantSet) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("HT40Intolerant is Already Set: %d"), + sapContext->aStaInfo[staId].isHT40IntolerantSet); + return; + } + + spin_lock_bh(&sapContext->staInfo_lock); + + sapContext->aStaInfo[staId].isHT40IntolerantSet = 1; + sapContext->numHT40IntoSta++; + + spin_unlock_bh(&sapContext->staInfo_lock); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Total No of HT40 Intolerant STA: %d" + " STA ID: %d HT40IntolerantSet: %d"), + sapContext->numHT40IntoSta, + staId, sapContext->aStaInfo[staId].isHT40IntolerantSet); + + /* Stop HT20/40 Timer */ + if (VOS_TIMER_STATE_RUNNING == sapContext->sap_HT2040_timer.state) + { + vosStatus = vos_timer_stop(&sapContext->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + + if(cbMode) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Move SAP from HT40 to HT20")); + + halStatus = sme_SetHT2040Mode(hHal, sapContext->sessionId, + PHY_SINGLE_CHANNEL_CENTERED); + + if (halStatus == eHAL_STATUS_FAILURE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to change HT20/40 mode")); + return; + } + + /* Disable Channel Bonding for 2.4GHz */ + sme_UpdateChannelBondingMode24G(hHal, + PHY_SINGLE_CHANNEL_CENTERED); + + } + else + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("SAP is Already in HT20")); +} + +/*========================================================================== + FUNCTION sapRemoveHT40IntolerantSta + + DESCRIPTION + Remove HT40 Intolerant STA & Move SAP from HT40 to HT20 + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + pCsrRoamInfo : Pointer to CSR info + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +void sapRemoveHT40IntolerantSta(ptSapContext sapContext, + tCsrRoamInfo *pCsrRoamInfo) +{ + tANI_U8 staId; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + unsigned int delay; + + vosStatus = sapGetStaId(sapContext, &staId, pCsrRoamInfo); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("ERROR: SAP Failed to find sta id!!")); + return; + } + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Remove HT40 MHz Intolerant STA :" + MAC_ADDRESS_STR " STA ID: %d" + " HT40IntolerantSet:%d"), + MAC_ADDR_ARRAY(pCsrRoamInfo->peerMac), + staId, sapContext->aStaInfo[staId].isHT40IntolerantSet); + + if(!sapContext->aStaInfo[staId].isHT40IntolerantSet) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("HT40Intolerant is not Set: %d"), + sapContext->aStaInfo[staId].isHT40IntolerantSet); + return; + } + + spin_lock_bh(&sapContext->staInfo_lock); + sapContext->aStaInfo[staId].isHT40IntolerantSet = 0; + + if (sapContext->numHT40IntoSta > 0) + sapContext->numHT40IntoSta--; + + spin_unlock_bh(&sapContext->staInfo_lock); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Total No of HT40 Intolerant STA: %d" + " STA ID: %d HT40IntolerantSet: %d"), + sapContext->numHT40IntoSta, + staId, sapContext->aStaInfo[staId].isHT40IntolerantSet); + + if ((!sapCheckHT40SecondaryIsNotAllowed(sapContext)) + && (!sapContext->numHT40IntoSta)) + { + /* Stop Previous Running HT20/40 Timer & Start timer + with (OBSS TransitionDelayFactor * obss interval) + delay after time out move AP from HT20 -> HT40 + mode + */ + if (VOS_TIMER_STATE_RUNNING == sapContext->sap_HT2040_timer.state) + { + vosStatus = vos_timer_stop(&sapContext->sap_HT2040_timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Stop HT20/40 timer")); + } + + delay = + (sapContext->ObssScanInterval * sapContext->ObssTransitionDelayFactor); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Start HT20/40 itransition" + " timer (%d sec)"), delay); + + vosStatus = vos_timer_start( &sapContext->sap_HT2040_timer, + (delay * 1000)); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Failed to Start HT20/40 timer")); + } + return; +} +#endif + +VOS_STATUS +sapIsPeerMacAllowed(ptSapContext sapContext, v_U8_t *peerMac) +{ + if (eSAP_ALLOW_ALL == sapContext->eSapMacAddrAclMode) + return VOS_STATUS_SUCCESS; + + if (sapSearchMacList(sapContext->acceptMacList, sapContext->nAcceptMac, peerMac, NULL)) + return VOS_STATUS_SUCCESS; + + if (sapSearchMacList(sapContext->denyMacList, sapContext->nDenyMac, peerMac, NULL)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Peer "MAC_ADDRESS_STR" in deny list", + __func__, MAC_ADDR_ARRAY(peerMac)); + return VOS_STATUS_E_FAILURE; + } + + // A new station CAN associate, unless in deny list. Less stringent mode + if (eSAP_ACCEPT_UNLESS_DENIED == sapContext->eSapMacAddrAclMode) + return VOS_STATUS_SUCCESS; + + // A new station CANNOT associate, unless in accept list. More stringent mode + if (eSAP_DENY_UNLESS_ACCEPTED == sapContext->eSapMacAddrAclMode) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Peer "MAC_ADDRESS_STR" denied, Mac filter mode is eSAP_DENY_UNLESS_ACCEPTED", + __func__, MAC_ADDR_ARRAY(peerMac)); + return VOS_STATUS_E_FAILURE; + } + + /* The new STA is neither in accept list nor in deny list. In this case, deny the association + * but send a wifi event notification indicating the mac address being denied + */ + if (eSAP_SUPPORT_ACCEPT_AND_DENY == sapContext->eSapMacAddrAclMode) + { + sapSignalHDDevent(sapContext, NULL, eSAP_UNKNOWN_STA_JOIN, (v_PVOID_t)peerMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "In %s, Peer "MAC_ADDRESS_STR" denied, Mac filter mode is eSAP_SUPPORT_ACCEPT_AND_DENY", + __func__, MAC_ADDR_ARRAY(peerMac)); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +#ifdef SOFTAP_CHANNEL_RANGE +static VOS_STATUS sapGetChannelList(ptSapContext sapContext, + v_U8_t **channelList, v_U8_t *numberOfChannels) +{ + v_U32_t startChannelNum; + v_U32_t endChannelNum; + v_U32_t operatingBand; + v_U8_t loopCount; + v_U8_t *list; + v_U8_t channelCount; + v_U8_t bandStartChannel; + v_U8_t bandEndChannel ; + v_U32_t enableLTECoex; + tHalHandle hHal = VOS_GET_HAL_CB(sapContext->pvosGCtx); +#ifdef FEATURE_WLAN_CH_AVOID + v_U8_t i; +#endif + + + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid HAL pointer from pvosGCtx on sapGetChannelList"); + *numberOfChannels = 0; + *channelList = NULL; + return VOS_STATUS_E_FAULT; + } + + if ( eCSR_BAND_ALL == sapContext->scanBandPreference) + { + + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); + ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s:sapGetChannelList: startChannel %d,EndChannel %d,Operatingband:%d", + __func__,startChannelNum,endChannelNum,operatingBand); + + switch(operatingBand) + { + case eSAP_RF_SUBBAND_2_4_GHZ: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + break; + + case eSAP_RF_SUBBAND_5_LOW_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_64; + break; + + case eSAP_RF_SUBBAND_5_MID_GHZ: + bandStartChannel = RF_CHAN_100; + bandEndChannel = RF_CHAN_140; + break; + + case eSAP_RF_SUBBAND_5_HIGH_GHZ: + bandStartChannel = RF_CHAN_149; + bandEndChannel = RF_CHAN_165; + break; + + case eSAP_RF_SUBBAND_5_ALL_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:OperatingBand not valid "); + /* assume 2.4 GHz */ + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + break; + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: expanded startChannel %d,EndChannel %d,Operatingband:%d", + __func__,startChannelNum,endChannelNum,operatingBand); + } + else + { + if ( sapContext->allBandScanned == eSAP_FALSE ) + { + //first band scan + sapContext->currentPreferredBand = sapContext->scanBandPreference; + } + else + { + //scan next band + if ( eCSR_BAND_24 == sapContext->scanBandPreference ) + sapContext->currentPreferredBand = eCSR_BAND_5G; + else + sapContext->currentPreferredBand = eCSR_BAND_24; + } + switch(sapContext->currentPreferredBand) + { + case eCSR_BAND_24: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + startChannelNum = 1; + endChannelNum = 14; + break; + + case eCSR_BAND_5G: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + startChannelNum = 36; + endChannelNum = 165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:bandPreference not valid "); + /* assume 2.4 GHz */ + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + startChannelNum = 1; + endChannelNum = 14; + break; + } + } + + ccmCfgGetInt(hHal, WNI_CFG_ENABLE_LTE_COEX, &enableLTECoex); + /*Check if LTE coex is enabled and 2.4GHz is selected*/ + if (enableLTECoex && (bandStartChannel == RF_CHAN_1) + && (bandEndChannel == RF_CHAN_14)) + { + /*Set 2.4GHz upper limit to channel 9 for LTE COEX*/ + bandEndChannel = RF_CHAN_9; + } + /* Allocate the max number of channel supported */ + list = (v_U8_t *)vos_mem_malloc(NUM_5GHZ_CHANNELS); + if (NULL == list) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate channel list", __func__); + *numberOfChannels = 0; + *channelList = NULL; + return VOS_STATUS_E_RESOURCES; + } + + /*Search for the Active channels in the given range */ + channelCount = 0; + for( loopCount = bandStartChannel; loopCount <= bandEndChannel; loopCount++ ) + { + if((startChannelNum <= rfChannels[loopCount].channelNum)&& + (endChannelNum >= rfChannels[loopCount].channelNum )) + { + if( regChannels[loopCount].enabled ) + { +#ifdef FEATURE_WLAN_CH_AVOID + for( i = 0; i < NUM_20MHZ_RF_CHANNELS; i++ ) + { + if( (safeChannels[i].channelNumber == + rfChannels[loopCount].channelNum) ) + { + /* Check if channel is safe */ + if(VOS_TRUE == safeChannels[i].isSafe) + { +#endif + list[channelCount] = + rfChannels[loopCount].channelNum; + channelCount++; +#ifdef FEATURE_WLAN_CH_AVOID + } + break; + } + } +#endif + } + } + } + if (0 == channelCount) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "sapGetChannelList:No active channels present in the given range for the current region"); + /*LTE COEX: channel range outside the restricted 2.4GHz band limits*/ + if (enableLTECoex && (startChannelNum > bandEndChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "sapGetChannelList:SAP cannot be started as LTE COEX restricted 2.4GHz limits"); + } + } + + /* return the channel list and number of channels to scan*/ + *numberOfChannels = channelCount; + if(channelCount != 0) + { + *channelList = list; + } + else + { + *channelList = NULL; + vos_mem_free(list); + } + + for (loopCount = 0; loopCount channel); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: 40 MHz affected channel range: [%d,%d] MHz", + __func__, psapCtx->affected_start, psapCtx->affected_end); + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: SAP Primary & Secondary Channel : [%d,%d] MHz", + __func__, psapCtx->channel, psapCtx->sap_sec_chan); + + /* Allocate the max number of channel supported */ + list = (v_U8_t *)vos_mem_malloc(RF_CHAN_14 + 1); + if (NULL == list) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate channel list", __func__); + *numberOfChannels = 0; + *channelList = NULL; + return VOS_STATUS_E_RESOURCES; + } + + /*Search for the Active channels in the given range */ + channelCount = 0; + startChannelNum = RF_CHAN_1; + endChannelNum = RF_CHAN_14; + for( loopCount = startChannelNum; loopCount <= endChannelNum; loopCount++ ) + { + if ((rfChannels[loopCount].channelNum >= psapCtx->affected_start) + && (rfChannels[loopCount].channelNum <= psapCtx->affected_end)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: Channel Number: %d State : %d", __func__, + rfChannels[loopCount].channelNum, + vos_nv_getChannelEnabledState(rfChannels[loopCount].channelNum)); + list[channelCount] = rfChannels[loopCount].channelNum; + channelCount++; + } + } + /* return the channel list and number of channels to scan*/ + *numberOfChannels = channelCount; + if(channelCount != 0) + { + *channelList = list; + } + else + { + *channelList = NULL; + vos_mem_free(list); + } + return VOS_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/prima/CORE/SAP/src/sapFsm_ext.h b/drivers/staging/prima/CORE/SAP/src/sapFsm_ext.h new file mode 100644 index 000000000000..bc5ee88936b6 --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapFsm_ext.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* This file is generated from btampFsm.cdd - do not edit manually*/ +/* Generated on: Thu Oct 16 15:40:39 PDT 2008 */ + + +#ifndef __SAPFSM_EXT_H__ +#define __SAPFSM_EXT_H__ + +/* Events that can be sent to the SAP state-machine */ +typedef enum +{ + eSAP_TIMER_CONNECT_ACCEPT_TIMEOUT=0U, + eSAP_MAC_CONNECT_COMPLETED, + eSAP_CHANNEL_SELECTION_FAILED, + eSAP_MAC_CONNECT_INDICATION, + eSAP_MAC_KEY_SET_SUCCESS, + eSAP_RSN_FAILURE, + eSAP_MAC_SCAN_COMPLETE, + eSAP_HDD_START_INFRA_BSS, + eSAP_MAC_READY_FOR_CONNECTIONS, + eSAP_MAC_START_BSS_SUCCESS, + eSAP_MAC_START_BSS_FAILURE, + eSAP_RSN_SUCCESS, + eSAP_MAC_START_FAILS, + eSAP_HDD_STOP_INFRA_BSS, + eSAP_WRITE_REMOTE_AMP_ASSOC, + + eSAP_NO_MSG +}eSapMsg_t; + + +#endif diff --git a/drivers/staging/prima/CORE/SAP/src/sapInternal.h b/drivers/staging/prima/CORE/SAP/src/sapInternal.h new file mode 100644 index 000000000000..dd94138d519d --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapInternal.h @@ -0,0 +1,919 @@ +/* + * Copyright (c) 2012-2013, 2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WLANSAP_INTERNAL_H +#define WLAN_QCT_WLANSAP_INTERNAL_H + +/*=========================================================================== + + W L A N S A P P A L L A Y E R + I N T E R N A L A P I + + +DESCRIPTION + This file contains the internal API exposed by the wlan SAP PAL layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header: /cygdrive/d/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT_BTAMP_RSN/CORE/BAP/src/bapInternal.h,v 1.7 2009/03/09 08:50:43 rgidvani Exp rgidvani $ $DateTime: $ $Author: jzmuda $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +09/15/08 SOFTAP Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" + +// Pick up the CSR API definitions +#include "csrApi.h" +#include "sapApi.h" +#include "sapFsm_ext.h" +#include "sapChSelect.h" +#include "wlan_hdd_dp_utils.h" +#include "wlan_hdd_main.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + + +/*---------------------------------------------------------------------------- + * Defines + * -------------------------------------------------------------------------*/ +#define SAP_DEBUG +// Used to enable or disable security on the BT-AMP link +#define WLANSAP_SECURITY_ENABLED_STATE VOS_TRUE +// How do I get SAP context from voss context? +#define VOS_GET_SAP_CB(ctx) vos_get_context( VOS_MODULE_ID_SAP, ctx) + +#define VOS_GET_HAL_CB(ctx) vos_get_context( VOS_MODULE_ID_PE, ctx) +//MAC Address length +#define ANI_EAPOL_KEY_RSN_NONCE_SIZE 32 + +extern sRegulatoryChannel *regChannels; +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; + +/*---------------------------------------------------------------------------- + * Typedefs + * -------------------------------------------------------------------------*/ +typedef struct sSapContext tSapContext; +// tSapContext, *ptSapContext; +/*---------------------------------------------------------------------------- + * Type Declarations - For internal SAP context information + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Opaque SAP context Type Declaration + * -------------------------------------------------------------------------*/ +// We were only using this syntax, when this was truly opaque. +// (I.E., it was defined in a different file.) + + +/* SAP FSM states for Access Point role */ +typedef enum { + eSAP_DISCONNECTED, + eSAP_CH_SELECT, + eSAP_STARTING, + eSAP_STARTED, + eSAP_DISCONNECTING +} eSapFsmStates_t; + +/*---------------------------------------------------------------------------- + * SAP context Data Type Declaration + * -------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------- + * Type Declarations - QOS related + * -------------------------------------------------------------------------*/ +/* SAP QOS config */ +typedef struct sSapQosCfg { + v_U8_t WmmIsEnabled; +} tSapQosCfg; + +typedef struct sSapAcsChannelInfo { + v_U32_t channelNum; + v_U32_t weight; +}tSapAcsChannelInfo; + +typedef struct { + /** The station entry is used or not */ + v_BOOL_t isUsed; + + /** Station ID reported back from HAL (through SAP). Broadcast + * uses station ID zero by default in both libra and volans. */ + v_U8_t ucSTAId; + + /** MAC address of the station */ + v_MACADDR_t macAddrSTA; + + /** Current Station state so HDD knows how to deal with packet + * queue. Most recent states used to change TL STA state. */ + WLANTL_STAStateType tlSTAState; + + /** Transmit queues for each AC (VO,VI,BE etc). */ + hdd_list_t wmm_tx_queue[NUM_TX_QUEUES]; + + /** Might need to differentiate queue depth in contention case */ + v_U16_t aTxQueueDepth[NUM_TX_QUEUES]; + + /**Track whether OS TX queue has been disabled.*/ + v_BOOL_t txSuspended[NUM_TX_QUEUES]; + + /**Track whether 3/4th of resources are used */ + v_BOOL_t vosLowResource; + + /** Track QoS status of station */ + v_BOOL_t isQosEnabled; + + /** The station entry for which Deauth is in progress */ + v_BOOL_t isDeauthInProgress; + +#ifdef WLAN_FEATURE_AP_HT40_24G + /** Track HT40 Intolerant station */ + v_BOOL_t isHT40IntolerantSet; +#endif + + /** Rate Flags for this connection */ + uint32_t rate_flags; + +} hdd_station_info_t; + +typedef struct sSapContext { + + vos_lock_t SapGlobalLock; + + // Include the current channel of AP + v_U32_t channel; + + // Include the SME(CSR) sessionId here + v_U8_t sessionId; + + // Include the key material for this physical link + v_U8_t key_type; + v_U8_t key_length; + v_U8_t key_material[32]; + + // Include the associations MAC addresses + v_U8_t self_mac_addr[VOS_MAC_ADDRESS_LEN]; + + // Own SSID + v_U8_t ownSsid[MAX_SSID_LEN]; + v_U32_t ownSsidLen; + + // Flag for signaling if security is enabled + v_U8_t ucSecEnabled; + + // Include the SME(CSR) context here + tCsrRoamProfile csrRoamProfile; + v_U32_t csrRoamId; + + //Sap session + tANI_BOOLEAN isSapSessionOpen; + + // SAP event Callback to hdd + tpWLAN_SAPEventCB pfnSapEventCallback; + + // Include the enclosing VOSS context here + v_PVOID_t pvosGCtx; + + // Include the state machine structure here, state var that keeps track of state machine + eSapFsmStates_t sapsMachine; + + // Actual storage for AP and self (STA) SSID + tCsrSSIDInfo SSIDList[2]; + + // Actual storage for AP bssid + tCsrBssid bssid; + + // Mac filtering settings + eSapMacAddrACL eSapMacAddrAclMode; + v_MACADDR_t acceptMacList[MAX_ACL_MAC_ADDRESS]; + v_U8_t nAcceptMac; + v_MACADDR_t denyMacList[MAX_ACL_MAC_ADDRESS]; + v_U8_t nDenyMac; + + // QOS config + tSapQosCfg SapQosCfg; + + v_PVOID_t pUsrContext; + + v_U32_t nStaWPARSnReqIeLength; + v_U8_t pStaWpaRsnReqIE[MAX_ASSOC_IND_IE_LEN]; + tSirAPWPSIEs APWPSIEs; + tSirRSNie APWPARSNIEs; + + v_U32_t nStaAddIeLength; + v_U8_t pStaAddIE[MAX_ASSOC_IND_IE_LEN]; + v_U8_t *channelList; + v_U8_t numofChannel; + tSapChannelListInfo SapChnlList; + + tANI_BOOLEAN allBandScanned; + eCsrBand currentPreferredBand; + eCsrBand scanBandPreference; + v_U16_t acsBandSwitchThreshold; + tSapAcsChannelInfo acsBestChannelInfo; + spinlock_t staInfo_lock; //To protect access to station Info + hdd_station_info_t aStaInfo[WLAN_MAX_STA_COUNT]; +#ifdef WLAN_FEATURE_AP_HT40_24G + v_U8_t affected_start; + v_U8_t affected_end; + v_U8_t sap_sec_chan; + v_U8_t numHT40IntoSta; + vos_timer_t sap_HT2040_timer; + v_U8_t ObssScanInterval; + v_U8_t ObssTransitionDelayFactor; +#endif +} *ptSapContext; + + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// The main per-Physical Link (per WLAN association) context. +extern ptSapContext gpSapCtx; + +/*---------------------------------------------------------------------------- + * SAP state machine event definition + * -------------------------------------------------------------------------*/ +/* The event structure */ +typedef struct sWLAN_SAPEvent { + v_PVOID_t params; /* A VOID pointer type for all possible inputs */ + v_U32_t event; /* State machine input event message */ + v_U32_t u1; /* introduced to handle csrRoamCompleteCallback roamStatus */ + v_U32_t u2; /* introduced to handle csrRoamCompleteCallback roamResult */ +} tWLAN_SAPEvent, *ptWLAN_SAPEvent; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ +#ifdef WLAN_FEATURE_AP_HT40_24G +/*========================================================================== + + FUNCTION sapGet24GOBSSAffectedChannel() + + DESCRIPTION + Get OBSS Affected Channel no for SAP + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tHalHandle: the tHalHandle passed in with the scan request + ptSapContext: Pointer to SAP context + + RETURN VALUE + + SIDE EFFECTS + +============================================================================*/ + +eHalStatus sapGet24GOBSSAffectedChannel(tHalHandle halHandle, + ptSapContext psapCtx); +#endif + +/*========================================================================== + + FUNCTION WLANSAP_ScanCallback() + + DESCRIPTION + Callback for Scan (scan results) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + tHalHandle: the tHalHandle passed in with the scan request + *p2: the second context pass in for the caller, opaque sap Handle here + scanID: + status: Status of scan -success, failure or abort + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +============================================================================*/ +eHalStatus +WLANSAP_ScanCallback +( + tHalHandle halHandle, + void *pContext, + v_U32_t scanID, + eCsrScanStatus scanStatus +); + +/*========================================================================== + + FUNCTION WLANSAP_RoamCallback() + + DESCRIPTION + Callback for Roam (connection status) Events + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pContext: is the pContext passed in with the roam request + pCsrRoamInfo: is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and + eRoamCmdResult: for detail valid members. It may be NULL + roamId: is to identify the callback related roam request. 0 means unsolicited + roamStatus: is a flag indicating the status of the callback + roamResult: is the result + + RETURN VALUE + The eHalStatus code associated with performing the operation + + eHAL_STATUS_SUCCESS: Success + + SIDE EFFECTS + +============================================================================*/ +eHalStatus +WLANSAP_RoamCallback +( + void *pContext, + tCsrRoamInfo *pCsrRoamInfo, + v_U32_t roamId, + eRoamCmdStatus roamStatus, + eCsrRoamResult roamResult +); + +/*========================================================================== + + FUNCTION WLANSAP_CleanCB + + DESCRIPTION + Clear out all fields in the SAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pSapCtx: pointer to the SAP control block + freeFlag: flag indicating whether to free any allocations. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANSAP_CleanCB +( + ptSapContext pSapCtx, + v_U32_t freeFlag /* If 0 do not empty */ +); +/*========================================================================== + + FUNCTION WLANSapFsm + + DESCRIPTION + SAP forward state machine to handle the states of the SAP + + DEPENDENCIES + + PARAMETERS + + IN + sapContext: pointer to the SAP control block + sapEvent : SAP event + status : status of SAP state machine + + RETURN VALUE + Status of the SAP forward machine + + VOS_STATUS_E_FAULT: pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +SapFsm +( + ptSapContext sapContext, /* sapContext value */ + ptWLAN_SAPEvent sapEvent, /* State machine event */ + v_U8_t *status /* return the SAP status here */ +); + +/*========================================================================== + + FUNCTION WLANSAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +WLANSAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +); + +/*========================================================================== + + FUNCTION sapSelectChannel + + DESCRIPTION + Runs a algorithm to select the best channel to operate in for Soft AP in 2.4GHz band + + DEPENDENCIES + + PARAMETERS + + IN + halHandle : Pointer to HAL handle + pSapCtx : Pointer to SAP context + pResult : Pointer to tScanResultHandle + + RETURN VALUE + If SUCCESS channel number or zero for FAILURE. + + SIDE EFFECTS + +============================================================================*/ + +v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResultHandle pScanResult); + +/*========================================================================== + + FUNCTION sapSignalHDDevent + + DESCRIPTION + SAP HDD event callback function + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + pCsrRoamInfo : csrRoamprofile + sapHddevent : SAP HDD callback event + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +sapSignalHDDevent( ptSapContext sapContext, tCsrRoamInfo * pCsrRoamInfo, eSapHddEvent sapHddevent, void *); + +/*========================================================================== + + FUNCTION sapFsm + + DESCRIPTION + SAP Forward state machine + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + sapEvent : state machine event + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sapFsm +( + ptSapContext sapContext, /* sapContext value */ + ptWLAN_SAPEvent sapEvent /* State machine event */ +); + +/*========================================================================== + + FUNCTION sapConvertToCsrProfile + + DESCRIPTION + sapConvertToCsrProfile + + DEPENDENCIES + + PARAMETERS + + IN + pconfig_params : Pointer to configuration structure + bssType : SoftAP type + profile : pointer to a csrProfile that needs to be passed + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +eSapStatus +sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, tCsrRoamProfile *profile); + +/*========================================================================== + + FUNCTION sapFreeRoamProfile + + DESCRIPTION + sapConvertToCsrProfile + + DEPENDENCIES + + PARAMETERS + + IN + profile : pointer to a csrProfile that needs to be freed + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +void sapFreeRoamProfile(tCsrRoamProfile *profile); + + +#ifdef WLAN_FEATURE_AP_HT40_24G +/*========================================================================== + FUNCTION sapAddHT40IntolerantSta + + DESCRIPTION + Add HT40 Intolerant STA & Move SAP from HT40 to HT20 + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + pCsrRoamInfo : Pointer to CSR info + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +void sapAddHT40IntolerantSta(ptSapContext sapContext, tCsrRoamInfo *pCsrRoamInfo); + +/*========================================================================== + FUNCTION sapRemoveHT40IntolerantSta + + DESCRIPTION + Remove HT40 Intolerant STA & Move SAP from HT40 to HT20 + + DEPENDENCIES + NA. + + PARAMETERS + + IN + sapContext : Sap Context value + pCsrRoamInfo : Pointer to CSR info + + RETURN VALUE + + SIDE EFFECTS +============================================================================*/ + +void sapRemoveHT40IntolerantSta(ptSapContext sapContext, tCsrRoamInfo *pCsrRoamInfo); +#endif + +/*========================================================================== + + FUNCTION sapIsPeerMacAllowed + + DESCRIPTION + Function to implement MAC filtering for station association in SoftAP + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + peerMac : Mac address of the peer + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sapIsPeerMacAllowed(ptSapContext sapContext, v_U8_t *peerMac); + +/*========================================================================== + + FUNCTION sapSortMacList + + DESCRIPTION + Function to implement sorting of MAC addresses + + DEPENDENCIES + + PARAMETERS + + IN + macList : Pointer to mac address array + size : Number of entries in mac address array + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +void +sapSortMacList(v_MACADDR_t *macList, v_U8_t size); + +/*========================================================================== + + FUNCTION sapAddMacToACL + + DESCRIPTION + Function to ADD a mac address in an ACL. + The function ensures that the ACL list remains sorted after the addition. + This API does not take care of buffer overflow i.e. if the list is already + maxed out while adding a mac address, it will still try to add. + The caller must take care that the ACL size is less than MAX_ACL_MAC_ADDRESS + before calling this function. + + DEPENDENCIES + + PARAMETERS + + IN + macList : ACL list of mac addresses (black/white list) + size (I/O) : size of the ACL. It is an I/O arg. The API takes care + of incrementing the size by 1. + peerMac : Mac address of the peer to be added + + RETURN VALUE + None. + + SIDE EFFECTS + +============================================================================*/ +void +sapAddMacToACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t *peerMac); + +/*========================================================================== + + FUNCTION sapRemoveMacFromACL + + DESCRIPTION + Function to REMOVE a mac address from an ACL. + The function ensures that the ACL list remains sorted after the DELETION. + + DEPENDENCIES + + PARAMETERS + + IN + macList : ACL list of mac addresses (black/white list) + size (I/O) : size of the ACL. It is an I/O arg. The API takes care of decrementing the size by 1. + index : index in the ACL list where the peerMac is present + This index can be found by using the "sapSearchMacList" API which returns the index of the MAC + addr, if found in an ACL, in one of the arguments passed by the caller. + + RETURN VALUE + None. + + SIDE EFFECTS + +============================================================================*/ +void +sapRemoveMacFromACL(v_MACADDR_t *macList, v_U8_t *size, v_U8_t index); + +/*========================================================================== + + FUNCTION sapPrintACL + + DESCRIPTION + Function to print all the mac address of an ACL. + Useful for debug. + + DEPENDENCIES + + PARAMETERS + + IN + macList : ACL list of mac addresses (black/white list) + size : size of the ACL + + RETURN VALUE + None. + + SIDE EFFECTS + +============================================================================*/ +void +sapPrintACL(v_MACADDR_t *macList, v_U8_t size); + +/*========================================================================== + + FUNCTION sapSearchMacList + + DESCRIPTION + Function to search for a mac address in an ACL + + DEPENDENCIES + + PARAMETERS + + IN + macList : list of mac addresses (black/white list) + num_mac : size of the ACL + peerMac : Mac address of the peer + OP + index : the index at which the peer mac is found + this value gets filled in this function. If the caller is not interested + in the index of the peerMac to be searched, it can pass NULL here. + + RETURN VALUE + SUCCESS : if the mac addr being searched for is found + FAILURE : if the mac addr being searched for is NOT found + + SIDE EFFECTS + +============================================================================*/ +eSapBool +sapSearchMacList(v_MACADDR_t *macList, v_U8_t num_mac, v_U8_t *peerMac, v_U8_t *index); + + +/*========================================================================== + + FUNCTION sap_AcquireGlobalLock + + DESCRIPTION + Function to implement acquire SAP global lock + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + peerMac : Mac address of the peer + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sap_AcquireGlobalLock( ptSapContext pSapCtx ); + +/*========================================================================== + + FUNCTION sapIsPeerMacAllowed + + DESCRIPTION + Function to implement release SAP global lock + + DEPENDENCIES + + PARAMETERS + + IN + sapContext : Pointer to SAP handle + peerMac : Mac address of the peer + + RETURN VALUE + If SUCCESS or FAILURE. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +sap_ReleaseGlobalLock( ptSapContext pSapCtx ); + +/*========================================================================== +FUNCTION sapConvertSapPhyModeToCsrPhyMode + +DESCRIPTION Function to implement selection of CSR PhyMode using SAP PhyMode + +DEPENDENCIES PARAMETERS + +IN sapPhyMode : SAP Phy Module + +RETURN VALUE If SUCCESS or FAILURE + +SIDE EFFECTS +============================================================================*/ +eCsrPhyMode sapConvertSapPhyModeToCsrPhyMode( eSapPhyMode sapPhyMode ); + +#ifdef WLAN_FEATURE_AP_HT40_24G +/*========================================================================== +FUNCTION sap_ht2040_timer_cb + +DESCRIPTION Function to implement ht2040 timer callback implementation + +SIDE EFFECTS +============================================================================*/ +void sap_ht2040_timer_cb(v_PVOID_t usrDataForCallback); + +/*========================================================================== +FUNCTION sapCheckHT40SecondaryIsNotAllowed + +DESCRIPTION Function to check HT40 secondary channel is allowed or not + +SIDE EFFECTS +============================================================================*/ + +eHalStatus sapCheckHT40SecondaryIsNotAllowed(ptSapContext psapCtx); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* #ifndef WLAN_QCT_WLANSAP_INTERNAL_H */ + diff --git a/drivers/staging/prima/CORE/SAP/src/sapModule.c b/drivers/staging/prima/CORE/SAP/src/sapModule.c new file mode 100644 index 000000000000..e8171b1782c7 --- /dev/null +++ b/drivers/staging/prima/CORE/SAP/src/sapModule.c @@ -0,0 +1,2461 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + s a p M o d u l e . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN SAP modules + functions providing EXTERNAL APIs. It is also where the global SAP module + context gets initialised + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +03/15/10 SOFTAP team Created module +06/03/10 js Added support to hostapd driven + * deauth/disassoc/mic failure + +===========================================================================*/ + +/* $Header$ */ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_tl.h" +#include "vos_trace.h" + +// Pick up the sme callback registration API +#include "sme_Api.h" + +// SAP API header file + +#include "sapInternal.h" +#include "smeInside.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define SAP_DEBUG + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * External declarations for global context + * -------------------------------------------------------------------------*/ +// No! Get this from VOS. +// The main per-Physical Link (per WLAN association) context. +ptSapContext gpSapCtx; + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + FUNCTION WLANSAP_Open + + DESCRIPTION + Called at driver initialization (vos_open). SAP will initialize + all its internal resources and will wait for the call to start to + register with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Open +( + v_PVOID_t pvosGCtx +) +{ + + ptSapContext pSapCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + VOS_ASSERT(pvosGCtx); + /*------------------------------------------------------------------------ + Allocate (and sanity check?!) SAP control block + ------------------------------------------------------------------------*/ + vos_alloc_context(pvosGCtx, VOS_MODULE_ID_SAP, (v_VOID_t **)&pSapCtx, sizeof(tSapContext)); + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up SAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANSAP_Open"); + + WLANSAP_CleanCB(pSapCtx, 0 /*do not empty*/); + + if (!VOS_IS_STATUS_SUCCESS(vos_spin_lock_init(&pSapCtx->staInfo_lock))) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "WLANSAP_Start failed init staInfo_lock"); + vos_free_context(pvosGCtx, VOS_MODULE_ID_SAP, pSapCtx); + return VOS_STATUS_E_FAULT; + } + + // Setup the "link back" to the VOSS context + pSapCtx->pvosGCtx = pvosGCtx; + + // Store a pointer to the SAP context provided by VOSS + gpSapCtx = pSapCtx; + + /*------------------------------------------------------------------------ + Allocate internal resources + ------------------------------------------------------------------------*/ + + return VOS_STATUS_SUCCESS; +}// WLANSAP_Open + +/*========================================================================== + FUNCTION WLANSAP_Start + + DESCRIPTION + Called as part of the overall start procedure (vos_start). SAP will + use this call to register with TL as the SAP entity for + SAP RSN frames. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANSAP_Start +( + v_PVOID_t pvosGCtx +) +{ + ptSapContext pSapCtx = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_Start invoked successfully\n"); + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + For now, presume security is not enabled. + -----------------------------------------------------------------------*/ + pSapCtx->ucSecEnabled = WLANSAP_SECURITY_ENABLED_STATE; + + + /*------------------------------------------------------------------------ + Now configure the roaming profile links. To SSID and bssid. + ------------------------------------------------------------------------*/ + // We have room for two SSIDs. + pSapCtx->csrRoamProfile.SSIDs.numOfSSIDs = 1; // This is true for now. + pSapCtx->csrRoamProfile.SSIDs.SSIDList = pSapCtx->SSIDList; //Array of two + pSapCtx->csrRoamProfile.SSIDs.SSIDList[0].SSID.length = 0; + pSapCtx->csrRoamProfile.SSIDs.SSIDList[0].handoffPermitted = VOS_FALSE; + pSapCtx->csrRoamProfile.SSIDs.SSIDList[0].ssidHidden = pSapCtx->SSIDList[0].ssidHidden; + + pSapCtx->csrRoamProfile.BSSIDs.numOfBSSIDs = 1; // This is true for now. + pSapCtx->csrRoamProfile.BSSIDs.bssid = &pSapCtx->bssid; + + // Now configure the auth type in the roaming profile. To open. + pSapCtx->csrRoamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; // open is the default + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pSapCtx->SapGlobalLock))) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "WLANSAP_Start failed init lock\n"); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +}/* WLANSAP_Start */ + +/*========================================================================== + + FUNCTION WLANSAP_Stop + + DESCRIPTION + Called by vos_stop to stop operation in SAP, before close. SAP will suspend all + BT-AMP Protocol Adaption Layer operation and will wait for the close + request to clean up its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Stop +( + v_PVOID_t pvosGCtx +) +{ + + ptSapContext pSapCtx = NULL; + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_Stop invoked successfully "); + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sapFreeRoamProfile(&pSapCtx->csrRoamProfile); + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pSapCtx->SapGlobalLock ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "WLANSAP_Stop failed destroy lock\n"); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Stop SAP (de-register RSN handler!?) + ------------------------------------------------------------------------*/ + + return VOS_STATUS_SUCCESS; +}/* WLANSAP_Stop */ + +/*========================================================================== + FUNCTION WLANSAP_Close + + DESCRIPTION + Called by vos_close during general driver close procedure. SAP will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Close +( + v_PVOID_t pvosGCtx +) +{ + ptSapContext pSapCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_Close invoked"); + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Cleanup SAP control block. + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANSAP_Close"); + WLANSAP_CleanCB(pSapCtx, VOS_TRUE /* empty queues/lists/pkts if any*/); + + /*------------------------------------------------------------------------ + Free SAP context from VOSS global + ------------------------------------------------------------------------*/ + vos_free_context(pvosGCtx, VOS_MODULE_ID_SAP, pSapCtx); + + return VOS_STATUS_SUCCESS; +}/* WLANSAP_Close */ + +/*---------------------------------------------------------------------------- + * Utility Function implementations + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANSAP_CleanCB + + DESCRIPTION + Clear out all fields in the SAP context. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_CleanCB +( + ptSapContext pSapCtx, + v_U32_t freeFlag // 0 /*do not empty*/); +) +{ + /*------------------------------------------------------------------------ + Sanity check SAP control block + ------------------------------------------------------------------------*/ + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer", __func__); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Clean up SAP control block, initialize all values + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "WLANSAP_CleanCB"); + + vos_mem_zero( pSapCtx, sizeof(tSapContext)); + + pSapCtx->pvosGCtx = NULL; + + pSapCtx->sapsMachine= eSAP_DISCONNECTED; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, "%s: Initializing State: %d, sapContext value = %p", + __func__, pSapCtx->sapsMachine, pSapCtx); + pSapCtx->sessionId = 0; + pSapCtx->channel = 0; + + return VOS_STATUS_SUCCESS; +}// WLANSAP_CleanCB + +/*========================================================================== + FUNCTION WLANSAP_pmcFullPwrReqCB + + DESCRIPTION + Callback provide to PMC in the pmcRequestFullPower API. + + DEPENDENCIES + + PARAMETERS + + IN + callbackContext: The user passed in a context to identify + status: The halStatus + + RETURN VALUE + None + + SIDE EFFECTS +============================================================================*/ +void +WLANSAP_pmcFullPwrReqCB +( + void *callbackContext, + eHalStatus status +) +{ + if(HAL_STATUS_SUCCESS(status)) + { + //If success what else to be handled??? + } + else + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_FATAL, + "WLANSAP_pmcFullPwrReqCB: PMC failed to put the chip in Full power\n"); + + } + +}// WLANSAP_pmcFullPwrReqCB +/*========================================================================== + FUNCTION WLANSAP_getState + + DESCRIPTION + This api returns the current SAP state to the caller. + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + + RETURN VALUE + Returns the SAP FSM state. +============================================================================*/ + +v_U8_t WLANSAP_getState +( + v_PVOID_t pvosGCtx +) +{ + ptSapContext pSapCtx = NULL; + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + return pSapCtx->sapsMachine; +} +/*========================================================================== + FUNCTION WLANSAP_get_sessionId + + DESCRIPTION + This api returns the current SAP sessionId to the caller. + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + v_U8_t : Pointer to sessionID + + RETURN VALUE + VOS_STATUS_SUCCESS on success. + + VOS_STATUS_E_INVAL: Pointer to SAP cb is NULL ; access would cause a page + fault +============================================================================*/ +VOS_STATUS WLANSAP_get_sessionId +( + v_PVOID_t pvosGCtx, v_U8_t *sessionId +) +{ + ptSapContext pSapCtx = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + status = VOS_STATUS_E_INVAL; + } + + if (pSapCtx->sapsMachine == eSAP_STARTED) { + *sessionId = pSapCtx->sessionId; + status = VOS_STATUS_SUCCESS; + } + else + status = VOS_STATUS_E_FAILURE; + + return status; +} +/*========================================================================== + FUNCTION WLANSAP_StartBss + + DESCRIPTION + This api function provides SAP FSM event eWLAN_SAP_PHYSICAL_LINK_CREATE for + starting AP BSS + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + pQctCommitConfig : Pointer to configuration structure passed down from HDD(HostApd for Android) + hdd_SapEventCallback: Callback function in HDD called by SAP to inform HDD about SAP results + pUsrContext : Parameter that will be passed back in all the SAP callback events. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StartBss +( + v_PVOID_t pvosGCtx,//pwextCtx + tpWLAN_SAPEventCB pSapEventCallback, + tsap_Config_t *pConfig, + v_PVOID_t pUsrContext +) +{ + tWLAN_SAPEvent sapEvent; /* State machine event*/ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + tANI_BOOLEAN restartNeeded; + tHalHandle hHal; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_StartBss"); + + if (VOS_STA_SAP_MODE == vos_get_conparam ()) + { + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + pSapCtx->sapsMachine = eSAP_DISCONNECTED; + + /* Channel selection is auto or configured */ + pSapCtx->channel = pConfig->channel; + pSapCtx->scanBandPreference = pConfig->scanBandPreference; + pSapCtx->acsBandSwitchThreshold = pConfig->acsBandSwitchThreshold; + pSapCtx->pUsrContext = pUsrContext; + + //Set the BSSID to your "self MAC Addr" read the mac address from Configuation ITEM received from HDD + pSapCtx->csrRoamProfile.BSSIDs.numOfBSSIDs = 1; + + //Save a copy to SAP context + vos_mem_copy(pSapCtx->csrRoamProfile.BSSIDs.bssid, + pConfig->self_macaddr.bytes, sizeof(v_MACADDR_t)); + vos_mem_copy(pSapCtx->self_mac_addr, + pConfig->self_macaddr.bytes, sizeof(v_MACADDR_t)); + + //copy the configuration items to csrProfile + sapconvertToCsrProfile( pConfig, eCSR_BSS_TYPE_INFRA_AP, &pSapCtx->csrRoamProfile); + hHal = (tHalHandle)VOS_GET_HAL_CB(pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid MAC context from pvosGCtx", __func__); + } + else + { + //If concurrent session is running that is already associated + //then we just follow that sessions country info (whether + //present or not doesn't maater as we have to follow whatever + //STA session does) + if ((0 == sme_GetConcurrentOperationChannel(hHal)) && + pConfig->ieee80211d) + { + /* Setting the region/country information */ + sme_setRegInfo(hHal, pConfig->countryCode); + sme_ResetCountryCodeInformation(hHal, &restartNeeded); + } + } + + // Copy MAC filtering settings to sap context + pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl; + vos_mem_copy(pSapCtx->acceptMacList, pConfig->accept_mac, sizeof(pConfig->accept_mac)); + pSapCtx->nAcceptMac = pConfig->num_accept_mac; + sapSortMacList(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + vos_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac, sizeof(pConfig->deny_mac)); + pSapCtx->nDenyMac = pConfig->num_deny_mac; + sapSortMacList(pSapCtx->denyMacList, pSapCtx->nDenyMac); + + /* Fill in the event structure for FSM */ + sapEvent.event = eSAP_HDD_START_INFRA_BSS; + sapEvent.params = 0;//pSapPhysLinkCreate + + /* Store the HDD callback in SAP context */ + pSapCtx->pfnSapEventCallback = pSapEventCallback; + + /* Handle event*/ + vosStatus = sapFsm(pSapCtx, &sapEvent); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "SoftAp role has not been enabled"); + } + + return vosStatus; +}// WLANSAP_StartBss + +/*========================================================================== + FUNCTION WLANSAP_SetMacACL + + DESCRIPTION + This api function provides SAP to set mac list entry in accept list as well + as deny list + + DEPENDENCIES + + PARAMETERS + + IN + pContext : Pointer to Sap Context structure + pQctCommitConfig : Pointer to configuration structure passed down from + HDD(HostApd for Android) + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to SAP cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetMacACL +( + v_PVOID_t pvosGCtx, //pwextCtx + tsap_Config_t *pConfig +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_SetMacACL"); + + if (VOS_STA_SAP_MODE == vos_get_conparam ()) + { + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + // Copy MAC filtering settings to sap context + pSapCtx->eSapMacAddrAclMode = pConfig->SapMacaddr_acl; + + if (eSAP_DENY_UNLESS_ACCEPTED == pSapCtx->eSapMacAddrAclMode) + { + vos_mem_copy(pSapCtx->acceptMacList, pConfig->accept_mac, + sizeof(pConfig->accept_mac)); + pSapCtx->nAcceptMac = pConfig->num_accept_mac; + sapSortMacList(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + } + else if (eSAP_ACCEPT_UNLESS_DENIED == pSapCtx->eSapMacAddrAclMode) + { + vos_mem_copy(pSapCtx->denyMacList, pConfig->deny_mac, + sizeof(pConfig->deny_mac)); + pSapCtx->nDenyMac = pConfig->num_deny_mac; + sapSortMacList(pSapCtx->denyMacList, pSapCtx->nDenyMac); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s : SoftAp role has not been enabled", __func__); + return VOS_STATUS_E_FAULT; + } + + return vosStatus; +}//WLANSAP_SetMacACL + +/*========================================================================== + FUNCTION WLANSAP_StopBss + + DESCRIPTION + This api function provides SAP FSM event eSAP_HDD_STOP_INFRA_BSS for + stopping AP BSS + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx : Pointer to the global vos context; a handle to SAP's + control block can be extracted from its contexe + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Pointer to VOSS GC is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_StopBss +( + v_PVOID_t pvosGCtx +) +{ + tWLAN_SAPEvent sapEvent; /* State machine event*/ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANSAP_StopBss"); + + if ( NULL == pvosGCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Global VOSS handle", __func__); + return VOS_STATUS_E_FAULT; + } + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + if (NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + /* Fill in the event structure for FSM */ + sapEvent.event = eSAP_HDD_STOP_INFRA_BSS; + sapEvent.params = 0; + + /* Handle event*/ + vosStatus = sapFsm(pSapCtx, &sapEvent); + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_GetAssocStations + + DESCRIPTION + This api function is used to probe the list of associated stations from various modules of CORE stack + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + modId : Module from whom list of associtated stations is supposed to be probed. If an invalid module is passed + then by default VOS_MODULE_ID_PE will be probed + IN/OUT + pAssocStas : Pointer to list of associated stations that are known to the module specified in mod parameter + + NOTE: The memory for this list will be allocated by the caller of this API + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_GetAssocStations +( + v_PVOID_t pvosGCtx, + VOS_MODULE_ID modId, + tpSap_AssocMacAddr pAssocStas +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamGetAssociatedStas( VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + modId, + pSapCtx->pUsrContext, + (v_PVOID_t *)pSapCtx->pfnSapEventCallback, + (v_U8_t *)pAssocStas ); + + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION WLANSAP_RemoveWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to remove an entry from session session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pRemoveMac: pointer to v_MACADDR_t for session MAC address + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + VOS_STATUS_E_FAULT: Session is not dectected. The parameter is function not valid. + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_RemoveWpsSessionOverlap + +( + v_PVOID_t pvosGCtx, + v_MACADDR_t pRemoveMac +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamGetWpsSessionOverlap( VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pSapCtx->pUsrContext, + (v_PVOID_t *)pSapCtx->pfnSapEventCallback, + pRemoveMac); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_getWpsSessionOverlap + + DESCRIPTION + This api function provides for Ap App/HDD to get WPS session overlap info. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_getWpsSessionOverlap +( + v_PVOID_t pvosGCtx +) +{ + v_MACADDR_t pRemoveMac = VOS_MAC_ADDR_ZERO_INITIALIZER; + + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamGetWpsSessionOverlap( VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pSapCtx->pUsrContext, + (v_PVOID_t *)pSapCtx->pfnSapEventCallback, + pRemoveMac); + + return VOS_STATUS_SUCCESS; +} + + +/* This routine will set the mode of operation for ACL dynamically*/ +VOS_STATUS +WLANSAP_SetMode ( v_PVOID_t pvosGCtx, v_U32_t mode) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + pSapCtx->eSapMacAddrAclMode = (eSapMacAddrACL)mode; + return VOS_STATUS_SUCCESS; +} + +/* This routine will clear all the entries in accept list as well as deny list */ + +VOS_STATUS +WLANSAP_ClearACL( v_PVOID_t pvosGCtx) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + v_U8_t i; + + if (NULL == pSapCtx) + { + return VOS_STATUS_E_RESOURCES; + } + + if (pSapCtx->denyMacList != NULL) + { + for (i = 0; i < (pSapCtx->nDenyMac-1); i++) + { + vos_mem_zero((pSapCtx->denyMacList+i)->bytes, sizeof(v_MACADDR_t)); + + } + } + sapPrintACL(pSapCtx->denyMacList, pSapCtx->nDenyMac); + pSapCtx->nDenyMac = 0; + + if (pSapCtx->acceptMacList!=NULL) + { + for (i = 0; i < (pSapCtx->nAcceptMac-1); i++) + { + vos_mem_zero((pSapCtx->acceptMacList+i)->bytes, sizeof(v_MACADDR_t)); + + } + } + sapPrintACL(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + pSapCtx->nAcceptMac = 0; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS +WLANSAP_ModifyACL +( + v_PVOID_t pvosGCtx, + v_U8_t *pPeerStaMac, + eSapACLType listType, + eSapACLCmdType cmd +) +{ + eSapBool staInWhiteList=eSAP_FALSE, staInBlackList=eSAP_FALSE; + v_U8_t staWLIndex, staBLIndex; + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP Context", __func__); + return VOS_STATUS_E_FAULT; + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"Modify ACL entered\n" + "Before modification of ACL\n" + "size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** WHITE LIST ***"); + sapPrintACL(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** BLACK LIST ***"); + sapPrintACL(pSapCtx->denyMacList, pSapCtx->nDenyMac); + + /* the expectation is a mac addr will not be in both the lists at the same time. + It is the responsiblity of userspace to ensure this */ + staInWhiteList = sapSearchMacList(pSapCtx->acceptMacList, pSapCtx->nAcceptMac, pPeerStaMac, &staWLIndex); + staInBlackList = sapSearchMacList(pSapCtx->denyMacList, pSapCtx->nDenyMac, pPeerStaMac, &staBLIndex); + + if (staInWhiteList && staInBlackList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Peer mac "MAC_ADDRESS_STR" found in white and black lists." + "Initial lists passed incorrect. Cannot execute this command.", + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + + } + + switch(listType) + { + case eSAP_WHITE_LIST: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, "cmd %d", cmd); + if (cmd == ADD_STA_TO_ACL) + { + //error check + // if list is already at max, return failure + if (pSapCtx->nAcceptMac == MAX_ACL_MAC_ADDRESS) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "White list is already maxed out. Cannot accept "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + if (staInWhiteList) + { + //Do nothing if already present in white list. Just print a warning + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address already present in white list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + } else + { + if (staInBlackList) + { + //remove it from black list before adding to the white list + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "STA present in black list so first remove from it"); + sapRemoveMacFromACL(pSapCtx->denyMacList, &pSapCtx->nDenyMac, staBLIndex); + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "... Now add to the white list"); + sapAddMacToACL(pSapCtx->acceptMacList, &pSapCtx->nAcceptMac, pPeerStaMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, "size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + } + else if (cmd == DELETE_STA_FROM_ACL) + { + if (staInWhiteList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "Delete from white list"); + sapRemoveMacFromACL(pSapCtx->acceptMacList, &pSapCtx->nAcceptMac, staWLIndex); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, "size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address to be deleted is not present in the white list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Invalid cmd type passed"); + return VOS_STATUS_E_FAILURE; + } + break; + + case eSAP_BLACK_LIST: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW, + "cmd %d", cmd); + if (cmd == ADD_STA_TO_ACL) + { + //error check + // if list is already at max, return failure + if (pSapCtx->nDenyMac == MAX_ACL_MAC_ADDRESS) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Black list is already maxed out. Cannot accept "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + if (staInBlackList) + { + //Do nothing if already present in white list + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address already present in black list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + } else + { + if (staInWhiteList) + { + //remove it from white list before adding to the white list + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "Present in white list so first remove from it"); + sapRemoveMacFromACL(pSapCtx->acceptMacList, &pSapCtx->nAcceptMac, staWLIndex); + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "... Now add to black list"); + sapAddMacToACL(pSapCtx->denyMacList, &pSapCtx->nDenyMac, pPeerStaMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"size of accept and deny lists %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + } + else if (cmd == DELETE_STA_FROM_ACL) + { + if (staInBlackList) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, "Delete from black list"); + sapRemoveMacFromACL(pSapCtx->denyMacList, &pSapCtx->nDenyMac, staBLIndex); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"no accept and deny mac %d %d", + pSapCtx->nAcceptMac, pSapCtx->nDenyMac); + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_WARN, + "MAC address to be deleted is not present in the black list "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pPeerStaMac)); + return VOS_STATUS_E_FAILURE; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, "Invalid cmd type passed"); + return VOS_STATUS_E_FAILURE; + } + break; + + default: + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid list type passed %d",listType); + return VOS_STATUS_E_FAILURE; + } + } + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_LOW,"After modification of ACL"); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** WHITE LIST ***"); + sapPrintACL(pSapCtx->acceptMacList, pSapCtx->nAcceptMac); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO_HIGH,"*** BLACK LIST ***"); + sapPrintACL(pSapCtx->denyMacList, pSapCtx->nDenyMac); + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_DisassocSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated disassociation of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pPeerStaMac : Mac address of the station to disassociate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DisassocSta +( + v_PVOID_t pvosGCtx, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_U8_t *pPeerStaMac +#else + v_U8_t *pPeerStaMac +#endif +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamDisconnectSta(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, + pPeerStaMac); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_DeauthSta + + DESCRIPTION + This api function provides for Ap App/HDD initiated deauthentication of station + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx : Pointer to vos global context structure + pDelStaParams : Pointer to parameters of the station to + deauthenticate + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DeauthSta +( + v_PVOID_t pvosGCtx, + struct tagCsrDelStaParams *pDelStaParams +) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return vosStatus; + } + + halStatus = sme_RoamDeauthSta(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), + pSapCtx->sessionId, pDelStaParams); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + vosStatus = VOS_STATUS_SUCCESS; + } + return vosStatus; +} +/*========================================================================== + FUNCTION WLANSAP_SetChannelRange + + DESCRIPTION + This api function sets the range of channels for AP. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + startChannel : start channel + endChannel : End channel + operatingBand : Operating band (2.4GHz/5GHz) + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetChannelRange(tHalHandle hHal,v_U8_t startChannel, v_U8_t endChannel, + eSapOperatingBand operatingBand) +{ + + v_U8_t validChannelFlag =0; + v_U8_t loopStartCount =0; + v_U8_t loopEndCount =0; + v_U8_t bandStartChannel =0; + v_U8_t bandEndChannel =0; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "WLANSAP_SetChannelRange:startChannel %d,EndChannel %d,Operatingband:%d", + startChannel,endChannel,operatingBand); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMIN > operatingBand) || + (WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND_STAMAX < operatingBand)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid operatingBand on WLANSAP_SetChannelRange"); + return VOS_STATUS_E_FAULT; + } + if (( WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMIN > startChannel) || + (WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL_STAMAX < startChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid startChannel value on WLANSAP_SetChannelRange"); + return VOS_STATUS_E_FAULT; + } + if (( WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMIN > endChannel) || + (WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL_STAMAX < endChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid endChannel value on WLANSAP_SetChannelRange"); + return VOS_STATUS_E_FAULT; + } + switch(operatingBand) + { + case eSAP_RF_SUBBAND_2_4_GHZ: + bandStartChannel = RF_CHAN_1; + bandEndChannel = RF_CHAN_14; + break; + + case eSAP_RF_SUBBAND_5_LOW_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_64; + break; + + case eSAP_RF_SUBBAND_5_MID_GHZ: + bandStartChannel = RF_CHAN_100; +#ifndef FEATURE_WLAN_CH144 + bandEndChannel = RF_CHAN_140; +#else + bandEndChannel = RF_CHAN_144; +#endif /* FEATURE_WLAN_CH144 */ + break; + + case eSAP_RF_SUBBAND_5_HIGH_GHZ: + bandStartChannel = RF_CHAN_149; + bandEndChannel = RF_CHAN_165; + break; + + case eSAP_RF_SUBBAND_5_ALL_GHZ: + bandStartChannel = RF_CHAN_36; + bandEndChannel = RF_CHAN_165; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Invalid operatingBand value on WLANSAP_SetChannelRange"); + break; + } + + /* Validating the start channel is in range or not*/ + for(loopStartCount = bandStartChannel ; loopStartCount <= bandEndChannel ; + loopStartCount++) + { + if(rfChannels[loopStartCount].channelNum == startChannel ) + { + /* start channel is in the range */ + break; + } + } + /* Validating the End channel is in range or not*/ + for(loopEndCount = bandStartChannel ; loopEndCount <= bandEndChannel ; + loopEndCount++) + { + if(rfChannels[loopEndCount].channelNum == endChannel ) + { + /* End channel is in the range */ + break; + } + } + if((loopStartCount > bandEndChannel)||(loopEndCount > bandEndChannel)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid startChannel-%d or EndChannel-%d for band -%d", + __func__,startChannel,endChannel,operatingBand); + /* Supplied channels are nt in the operating band so set the default + channels for the given operating band */ + startChannel = rfChannels[bandStartChannel].channelNum; + endChannel = rfChannels[bandEndChannel].channelNum; + } + + /*Search for the Active channels in the given range */ + for( loopStartCount = bandStartChannel; loopStartCount <= bandEndChannel; loopStartCount++ ) + { + if((startChannel <= rfChannels[loopStartCount].channelNum)&& + (endChannel >= rfChannels[loopStartCount].channelNum )) + { + if( regChannels[loopStartCount].enabled ) + { + validChannelFlag = 1; + break; + } + } + } + if(0 == validChannelFlag) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s-No active channels present in the given range for the current region", + __func__); + /* There is no active channel in the supplied range.Updating the config + with the default channels in the given band so that we can select the best channel in the sub-band*/ + startChannel = rfChannels[bandStartChannel].channelNum; + endChannel = rfChannels[bandEndChannel].channelNum; + } + + if (ccmCfgSetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, + operatingBand, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND to CCn"); + return VOS_STATUS_E_FAULT; + } + if (ccmCfgSetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, + startChannel, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL to CCM"); + return VOS_STATUS_E_FAULT; + + } + if (ccmCfgSetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, + endChannel, NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL to CCM"); + return VOS_STATUS_E_FAULT; + } + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANSAP_SetCounterMeasure + + DESCRIPTION + This api function is used to disassociate all the stations and prevent + association for any other station.Whenever Authenticator receives 2 mic failures + within 60 seconds, Authenticator will enable counter measure at SAP Layer. + Authenticator will start the 60 seconds timer. Core stack will not allow any + STA to associate till HDD disables counter meassure. Core stack shall kick out all the + STA which are currently associated and DIASSOC Event will be propogated to HDD for + each STA to clean up the HDD STA table.Once the 60 seconds timer expires, Authenticator + will disable the counter meassure at core stack. Now core stack can allow STAs to associate. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +bEnable: If TRUE than all stations will be disassociated and no more will be allowed to associate. If FALSE than CORE +will come out of this state. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetCounterMeasure +( + v_PVOID_t pvosGCtx, + v_BOOL_t bEnable +) +{ + ptSapContext pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + + /*------------------------------------------------------------------------ + Sanity check + Extract SAP control block + ------------------------------------------------------------------------*/ + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + sme_RoamTKIPCounterMeasures(VOS_GET_HAL_CB(pSapCtx->pvosGCtx), pSapCtx->sessionId, bEnable); + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION WLANSAP_SetKeysSta + + DESCRIPTION + This api function provides for Ap App/HDD to set key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSetKeyInfo: tCsrRoamSetKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_SetKeySta +( + v_PVOID_t pvosGCtx, tCsrRoamSetKey *pSetKeyInfo +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_U32_t roamId=0xFF; + + if (VOS_STA_SAP_MODE == vos_get_conparam ( )) + { + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + halStatus = sme_RoamSetKey(hHal, pSapCtx->sessionId, pSetKeyInfo, &roamId); + + if (halStatus == eHAL_STATUS_SUCCESS) + { + vosStatus = VOS_STATUS_SUCCESS; + } else + { + vosStatus = VOS_STATUS_E_FAULT; + } + } + else + vosStatus = VOS_STATUS_E_FAULT; + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_DelKeySta + + DESCRIPTION + This api function provides for Ap App/HDD to delete key for a station. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pSetKeyInfo: tCsrRoamRemoveKey structure for the station + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_DelKeySta +( + v_PVOID_t pvosGCtx, + tCsrRoamRemoveKey *pRemoveKeyInfo +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_U32_t roamId=0xFF; + tCsrRoamRemoveKey RemoveKeyInfo; + + if (VOS_STA_SAP_MODE == vos_get_conparam ( )) + { + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + vos_mem_zero(&RemoveKeyInfo, sizeof(RemoveKeyInfo)); + RemoveKeyInfo.encType = pRemoveKeyInfo->encType; + vos_mem_copy(RemoveKeyInfo.peerMac, pRemoveKeyInfo->peerMac, WNI_CFG_BSSID_LEN); + RemoveKeyInfo.keyId = pRemoveKeyInfo->keyId; + + halStatus = sme_RoamRemoveKey(hHal, pSapCtx->sessionId, &RemoveKeyInfo, &roamId); + + if (HAL_STATUS_SUCCESS(halStatus)) + { + vosStatus = VOS_STATUS_SUCCESS; + } + else + { + vosStatus = VOS_STATUS_E_FAULT; + } + } + else + vosStatus = VOS_STATUS_E_FAULT; + + return vosStatus; +} + +VOS_STATUS +WLANSap_getstationIE_information(v_PVOID_t pvosGCtx, + v_U32_t *pLen, + v_U8_t *pBuf) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + ptSapContext pSapCtx = NULL; + v_U32_t len = 0; + + if (VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + if (pLen) + { + len = *pLen; + *pLen = pSapCtx->nStaWPARSnReqIeLength; + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: WPAIE len : %x", __func__, *pLen); + if(pBuf) + { + if(len >= pSapCtx->nStaWPARSnReqIeLength) + { + vos_mem_copy( pBuf, pSapCtx->pStaWpaRsnReqIE, pSapCtx->nStaWPARSnReqIeLength); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s: WPAIE: %02x:%02x:%02x:%02x:%02x:%02x", + __func__, + pBuf[0], pBuf[1], pBuf[2], + pBuf[3], pBuf[4], pBuf[5]); + vosStatus = VOS_STATUS_SUCCESS; + } + } + } + } + + if( VOS_STATUS_E_FAILURE == vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Error unable to populate the RSNWPAIE", + __func__); + } + + return vosStatus; + +} + +/*========================================================================== + FUNCTION WLANSAP_Set_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to set WPS IE. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure +pWPSIE: tSap_WPSIE structure that include WPS IEs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Set_WpsIe +( + v_PVOID_t pvosGCtx, tSap_WPSIE *pSap_WPSIe +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s, %d", __func__, __LINE__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )) { + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( sap_AcquireGlobalLock( pSapCtx ) == VOS_STATUS_SUCCESS ) + { + if (pSap_WPSIe->sapWPSIECode == eSAP_WPS_BEACON_IE) + { + vos_mem_copy(&pSapCtx->APWPSIEs.SirWPSBeaconIE, &pSap_WPSIe->sapwpsie.sapWPSBeaconIE, sizeof(tSap_WPSBeaconIE)); + } + else if (pSap_WPSIe->sapWPSIECode == eSAP_WPS_PROBE_RSP_IE) + { + vos_mem_copy(&pSapCtx->APWPSIEs.SirWPSProbeRspIE, &pSap_WPSIe->sapwpsie.sapWPSProbeRspIE, sizeof(tSap_WPSProbeRspIE)); + } + else + { + sap_ReleaseGlobalLock( pSapCtx ); + return VOS_STATUS_E_FAULT; + } + sap_ReleaseGlobalLock( pSapCtx ); + return VOS_STATUS_SUCCESS; + } + else + return VOS_STATUS_E_FAULT; + } + else + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + FUNCTION WLANSAP_Update_WpsIe + + DESCRIPTION + This api function provides for Ap App/HDD to update WPS IEs. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Update_WpsIe +( + v_PVOID_t pvosGCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + ptSapContext pSapCtx = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s, %d", __func__, __LINE__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RoamUpdateAPWPSIE( hHal, pSapCtx->sessionId, &pSapCtx->APWPSIEs); + + if(halStatus == eHAL_STATUS_SUCCESS) { + vosStatus = VOS_STATUS_SUCCESS; + } else + { + vosStatus = VOS_STATUS_E_FAULT; + } + + } + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANSAP_Get_WPS_State + + DESCRIPTION + This api function provides for Ap App/HDD to check if WPS session in process. + + DEPENDENCIES + NA. + + PARAMETERS + + IN +pvosGCtx: Pointer to vos global context structure + + OUT +pbWPSState: Pointer to variable to indicate if it is in WPS Registration state + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANSAP_Get_WPS_State +( + v_PVOID_t pvosGCtx, v_BOOL_t *bWPSState +) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + "%s, %d", __func__, __LINE__); + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( sap_AcquireGlobalLock(pSapCtx ) == VOS_STATUS_SUCCESS ) + { + if(pSapCtx->APWPSIEs.SirWPSProbeRspIE.FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) + *bWPSState = eANI_BOOLEAN_TRUE; + else + *bWPSState = eANI_BOOLEAN_FALSE; + + sap_ReleaseGlobalLock( pSapCtx ); + + return VOS_STATUS_SUCCESS; + } + else + return VOS_STATUS_E_FAULT; + } + else + return VOS_STATUS_E_FAULT; + +} + +VOS_STATUS +sap_AcquireGlobalLock +( + ptSapContext pSapCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + + if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &pSapCtx->SapGlobalLock) ) ) + { + vosStatus = VOS_STATUS_SUCCESS; + } + + return (vosStatus); +} + +VOS_STATUS +sap_ReleaseGlobalLock +( + ptSapContext pSapCtx +) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAULT; + + if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &pSapCtx->SapGlobalLock) ) ) + { + vosStatus = VOS_STATUS_SUCCESS; + } + + return (vosStatus); +} + +/*========================================================================== + FUNCTION WLANSAP_Set_WPARSNIes + + DESCRIPTION + This api function provides for Ap App/HDD to set AP WPA and RSN IE in its beacon and probe response. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pWPARSNIEs: buffer to the WPA/RSN IEs + WPARSNIEsLen: length of WPA/RSN IEs + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_Set_WPARSNIes(v_PVOID_t pvosGCtx, v_U8_t *pWPARSNIEs, v_U32_t WPARSNIEsLen) +{ + + ptSapContext pSapCtx = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + v_PVOID_t hHal = NULL; + + if(VOS_STA_SAP_MODE == vos_get_conparam ( )){ + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if ( NULL == pSapCtx ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ( NULL == hHal ){ + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid HAL pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + + pSapCtx->APWPARSNIEs.length = (tANI_U16)WPARSNIEsLen; + vos_mem_copy(pSapCtx->APWPARSNIEs.rsnIEdata, pWPARSNIEs, WPARSNIEsLen); + + halStatus = sme_RoamUpdateAPWPARSNIEs( hHal, pSapCtx->sessionId, &pSapCtx->APWPARSNIEs); + + if(halStatus == eHAL_STATUS_SUCCESS) { + return VOS_STATUS_SUCCESS; + } else + { + return VOS_STATUS_E_FAULT; + } + } + + return VOS_STATUS_E_FAULT; +} + +VOS_STATUS WLANSAP_GetStatistics(v_PVOID_t pvosGCtx, tSap_SoftapStats *statBuf, v_BOOL_t bReset) +{ + if (NULL == pvosGCtx) + { + return VOS_STATUS_E_FAULT; + } + + return (WLANTL_GetSoftAPStatistics(pvosGCtx, statBuf, bReset)); +} + +/*========================================================================== + + FUNCTION WLANSAP_SendAction + + DESCRIPTION + This api function provides to send action frame sent by upper layer. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + pBuf: Pointer of the action frame to be transmitted + len: Length of the action frame + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_SendAction( v_PVOID_t pvosGCtx, const tANI_U8 *pBuf, + tANI_U32 len, tANI_U16 wait ) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB( pvosGCtx ); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_sendAction( hHal, pSapCtx->sessionId, pBuf, len, 0 , 0); + + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Send Action Frame"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_RemainOnChannel + + DESCRIPTION + This api function provides to set Remain On channel on specified channel + for specified duration. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + channel: Channel on which driver has to listen + duration: Duration for which driver has to listen on specified channel + callback: Callback function to be called once Listen is done. + pContext: Context needs to be called in callback function. + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RemainOnChannel( v_PVOID_t pvosGCtx, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext ) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB( pvosGCtx ); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RemainOnChannel( hHal, pSapCtx->sessionId, + channel, duration, callback, pContext, TRUE ); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Set Remain on Channel"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_CancelRemainOnChannel + + DESCRIPTION + This api cancel previous remain on channel request. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_CancelRemainOnChannel( v_PVOID_t pvosGCtx ) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + pSapCtx = VOS_GET_SAP_CB(pvosGCtx); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if ((NULL == hHal) || (eSAP_TRUE != pSapCtx->isSapSessionOpen)) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_CancelRemainOnChannel(hHal, pSapCtx->sessionId); + + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Cancel Remain on Channel"); + return VOS_STATUS_E_FAULT; + } + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION WLANSAP_RegisterMgmtFrame + + DESCRIPTION + HDD use this API to register specified type of frame with CORE stack. + On receiving such kind of frame CORE stack should pass this frame to HDD + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + frameType: frameType that needs to be registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_RegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, + tANI_U8* matchData, tANI_U16 matchLen ) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB( pvosGCtx ); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_RegisterMgmtFrame(hHal, pSapCtx->sessionId, + frameType, matchData, matchLen); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Register MGMT frame"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + + FUNCTION WLANSAP_DeRegisterMgmtFrame + + DESCRIPTION + This API is used to deregister previously registered frame. + + DEPENDENCIES + NA. + + PARAMETERS + + IN + pvosGCtx: Pointer to vos global context structure + frameType: frameType that needs to be De-registered with PE. + matchData: Data pointer which should be matched after frame type is matched. + matchLen: Length of the matchData + + RETURN VALUE + The VOS_STATUS code associated with performing the operation + + VOS_STATUS_SUCCESS: Success + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS WLANSAP_DeRegisterMgmtFrame( v_PVOID_t pvosGCtx, tANI_U16 frameType, + tANI_U8* matchData, tANI_U16 matchLen ) +{ + ptSapContext pSapCtx = NULL; + v_PVOID_t hHal = NULL; + eHalStatus halStatus = eHAL_STATUS_FAILURE; + + if( VOS_STA_SAP_MODE == vos_get_conparam ( ) ) + { + pSapCtx = VOS_GET_SAP_CB( pvosGCtx ); + if (NULL == pSapCtx) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid SAP pointer from pvosGCtx", __func__); + return VOS_STATUS_E_FAULT; + } + hHal = VOS_GET_HAL_CB(pSapCtx->pvosGCtx); + if( ( NULL == hHal ) || ( eSAP_TRUE != pSapCtx->isSapSessionOpen ) ) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: HAL pointer (%p) NULL OR SME session is not open (%d)", + __func__, hHal, pSapCtx->isSapSessionOpen ); + return VOS_STATUS_E_FAULT; + } + + halStatus = sme_DeregisterMgmtFrame( hHal, pSapCtx->sessionId, + frameType, matchData, matchLen ); + + if( eHAL_STATUS_SUCCESS == halStatus ) + { + return VOS_STATUS_SUCCESS; + } + } + + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "Failed to Deregister MGMT frame"); + + return VOS_STATUS_E_FAULT; +} + +/*========================================================================== + FUNCTION WLANSAP_PopulateDelStaParams + + DESCRIPTION + This API is used to populate del station parameters + DEPENDENCIES + NA. + + PARAMETERS + IN + mac: pointer to peer mac address. + reason_code: Reason code for the disassoc/deauth. + subtype: subtype points to either disassoc/deauth frame. + pDelStaParams: address where parameters to be populated. + + RETURN VALUE NONE + + SIDE EFFECTS +============================================================================*/ +void WLANSAP_PopulateDelStaParams(const v_U8_t *mac, + v_U16_t reason_code, + v_U8_t subtype, + struct tagCsrDelStaParams *pDelStaParams) +{ + if (NULL == mac) + memset(pDelStaParams->peerMacAddr, 0xff, VOS_MAC_ADDR_SIZE); + else + vos_mem_copy(pDelStaParams->peerMacAddr, mac, VOS_MAC_ADDR_SIZE); + + if (reason_code == 0) + pDelStaParams->reason_code = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON; + else + pDelStaParams->reason_code = reason_code; + + if (subtype == (SIR_MAC_MGMT_DEAUTH >> 4) || + subtype == (SIR_MAC_MGMT_DISASSOC >> 4)) + pDelStaParams->subtype = subtype; + else + pDelStaParams->subtype = (SIR_MAC_MGMT_DEAUTH >> 4); + + VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Delete STA with RC:%hu subtype:%hhu MAC::" MAC_ADDRESS_STR), + pDelStaParams->reason_code, pDelStaParams->subtype, + MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr)); +} diff --git a/drivers/staging/prima/CORE/SME/inc/btcApi.h b/drivers/staging/prima/CORE/SME/inc/btcApi.h new file mode 100644 index 000000000000..c6da770b5fff --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/btcApi.h @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: btcApi.h +* +* Description: BTC Events Layer API definitions. +* +* +******************************************************************************/ + +#ifndef __BTC_API_H__ +#define __BTC_API_H__ + +#include "vos_types.h" +#include "vos_timer.h" +#include "vos_nvitem.h" + +#define BT_INVALID_CONN_HANDLE (0xFFFF) /**< Invalid connection handle */ + +/* ACL and Sync connection attempt results */ +#define BT_CONN_STATUS_FAIL (0) /**< Connection failed */ +#define BT_CONN_STATUS_SUCCESS (1) /**< Connection successful */ +#define BT_CONN_STATUS_MAX (2) /**< This and beyond are invalid values */ + +/** ACL and Sync link types + These must match the Bluetooth Spec! +*/ +#define BT_SCO (0) /**< SCO Link */ +#define BT_ACL (1) /**< ACL Link */ +#define BT_eSCO (2) /**< eSCO Link */ +#define BT_LINK_TYPE_MAX (3) /**< This value and higher are invalid */ + +/** ACL link modes + These must match the Bluetooth Spec! +*/ +#define BT_ACL_ACTIVE (0) /**< Active mode */ +#define BT_ACL_HOLD (1) /**< Hold mode */ +#define BT_ACL_SNIFF (2) /**< Sniff mode */ +#define BT_ACL_PARK (3) /**< Park mode */ +#define BT_ACL_MODE_MAX (4) /**< This value and higher are invalid */ + +/** + * A2DP BTC max no of BT sub intervals + * + * **/ +#define BTC_MAX_NUM_ACL_BT_SUB_INTS (7) + +/** BTC Executions Modes allowed to be set by user +*/ +#define BTC_SMART_COEXISTENCE (0) /** BTC Mapping Layer decides whats best */ +#define BTC_WLAN_ONLY (1) /** WLAN takes all mode */ +#define BTC_PTA_ONLY (2) /** Allow only 3 wire protocol in H/W */ +#define BTC_SMART_MAX_WLAN (3) /** BTC Mapping Layer decides whats best, WLAN weighted */ +#define BTC_SMART_MAX_BT (4) /** BTC Mapping Layer decides whats best, BT weighted */ +#define BTC_SMART_BT_A2DP (5) /** BTC Mapping Layer decides whats best, balanced + BT A2DP weight */ +#define BT_EXEC_MODE_MAX (6) /** This and beyond are invalid values */ + +/** Enumeration of different kinds actions that BTC Mapping Layer + can do if PM indication (to AP) fails. +*/ +#define BTC_RESTART_CURRENT (0) /** Restart the interval we just failed to leave */ +#define BTC_START_NEXT (1) /** Start the next interval even though the PM transition at the AP was unsuccessful */ +#define BTC_ACTION_TYPE_MAX (2) /** This and beyond are invalid values */ + +#define BTC_BT_INTERVAL_MODE1_DEFAULT (120) /** BT Interval in Mode 1 */ +#define BTC_WLAN_INTERVAL_MODE1_DEFAULT (30) /** WLAN Interval in Mode 1 */ + +/** Bitmaps used for maintaining various BT events that requires + enough time to complete such that it might require disbling of + heartbeat monitoring to avoid WLAN link loss with the AP +*/ +#define BT_INQUIRY_STARTED (1<<0) +#define BT_PAGE_STARTED (1<<1) +#define BT_CREATE_ACL_CONNECTION_STARTED (1<<2) +#define BT_CREATE_SYNC_CONNECTION_STARTED (1<<3) + +/** Maximum time duration in milliseconds between a specific BT start event and its + respective stop event, before it can be declared timed out on receiving the stop event. +*/ +#define BT_MAX_EVENT_DONE_TIMEOUT 45000 + +/* + To suppurt multiple SCO connections for BT+UAPSD work +*/ +#define BT_MAX_SCO_SUPPORT 3 +#define BT_MAX_ACL_SUPPORT 3 +#define BT_MAX_DISCONN_SUPPORT (BT_MAX_SCO_SUPPORT+BT_MAX_ACL_SUPPORT) +#define BT_MAX_NUM_EVENT_ACL_DEFERRED 4 //We may need to defer these many BT events for ACL +#define BT_MAX_NUM_EVENT_SCO_DEFERRED 4 //We may need to defer these many BT events for SYNC + +/** Default values for the BTC tunables parameters +*/ +#define BTC_STATIC_BT_LEN_INQ_DEF (120000) // 120 msec +#define BTC_STATIC_BT_LEN_PAGE_DEF (10000) // 10 msec (don't care) +#define BTC_STATIC_BT_LEN_CONN_DEF (10000) // 10 msec (don't care) +#define BTC_STATIC_BT_LEN_LE_DEF (10000) // 10 msec (don't care) +#define BTC_STATIC_WLAN_LEN_INQ_DEF (30000) // 30 msec +#define BTC_STATIC_WLAN_LEN_PAGE_DEF (0) // 0 msec (BT takes all) +#define BTC_STATIC_WLAN_LEN_CONN_DEF (0) // 0 msec (BT takes all) +#define BTC_STATIC_WLAN_LEN_LE_DEF (0) // 0 msec (BT takes all) +#define BTC_DYNAMIC_BT_LEN_MAX_DEF (250000) // 250 msec +#define BTC_DYNAMIC_WLAN_LEN_MAX_DEF (45000) // 45 msec +#define BTC_SCO_BLOCK_PERC_DEF (1) // 1 percent +#define BTC_DHCP_ON_A2DP_DEF (1) // ON +#define BTC_DHCP_ON_SCO_DEF (0) // OFF + +/* + * Number of victim tables and mws coex configurations + */ +#define MWS_COEX_MAX_VICTIM_TABLE 10 +#define MWS_COEX_MAX_CONFIG 6 + +/** Enumeration of all the different kinds of BT events +*/ +typedef enum eSmeBtEventType +{ + BT_EVENT_DEVICE_SWITCHED_ON, + BT_EVENT_DEVICE_SWITCHED_OFF, + BT_EVENT_INQUIRY_STARTED, + BT_EVENT_INQUIRY_STOPPED, + BT_EVENT_INQUIRY_SCAN_STARTED, + BT_EVENT_INQUIRY_SCAN_STOPPED, + BT_EVENT_PAGE_STARTED, + BT_EVENT_PAGE_STOPPED, + BT_EVENT_PAGE_SCAN_STARTED, + BT_EVENT_PAGE_SCAN_STOPPED, + BT_EVENT_CREATE_ACL_CONNECTION, + BT_EVENT_ACL_CONNECTION_COMPLETE, + BT_EVENT_CREATE_SYNC_CONNECTION, + BT_EVENT_SYNC_CONNECTION_COMPLETE, + BT_EVENT_SYNC_CONNECTION_UPDATED, + BT_EVENT_DISCONNECTION_COMPLETE, + BT_EVENT_MODE_CHANGED, + BT_EVENT_A2DP_STREAM_START, + BT_EVENT_A2DP_STREAM_STOP, + BT_EVENT_TYPE_MAX, //This and beyond are invalid values +} tSmeBtEventType; + +/** BT-AMP events type +*/ +typedef enum eSmeBtAmpEventType +{ + BTAMP_EVENT_CONNECTION_START, + BTAMP_EVENT_CONNECTION_STOP, + BTAMP_EVENT_CONNECTION_TERMINATED, + BTAMP_EVENT_TYPE_MAX, //This and beyond are invalid values +} tSmeBtAmpEventType; + + +/**Data structure that specifies the needed event parameters for + BT_EVENT_CREATE_ACL_CONNECTION and BT_EVENT_ACL_CONNECTION_COMPLETE +*/ +typedef struct sSmeBtAclConnectionParam +{ + v_U8_t bdAddr[6]; + v_U16_t connectionHandle; + v_U8_t status; +} tSmeBtAclConnectionParam, *tpSmeBtAclConnectionParam; + +/** Data structure that specifies the needed event parameters for + BT_EVENT_CREATE_SYNC_CONNECTION, BT_EVENT_SYNC_CONNECTION_COMPLETE + and BT_EVENT_SYNC_CONNECTION_UPDATED +*/ +typedef struct sSmeBtSyncConnectionParam +{ + v_U8_t bdAddr[6]; + v_U16_t connectionHandle; + v_U8_t status; + v_U8_t linkType; + v_U8_t scoInterval; //units in number of 625us slots + v_U8_t scoWindow; //units in number of 625us slots + v_U8_t retransmisisonWindow; //units in number of 625us slots +} tSmeBtSyncConnectionParam, *tpSmeBtSyncConnectionParam; + +typedef struct sSmeBtSyncUpdateHist +{ + tSmeBtSyncConnectionParam btSyncConnection; + v_BOOL_t fValid; +} tSmeBtSyncUpdateHist, *tpSmeBtSyncUpdateHist; + +/**Data structure that specifies the needed event parameters for + BT_EVENT_MODE_CHANGED +*/ +typedef struct sSmeBtAclModeChangeParam +{ + v_U16_t connectionHandle; + v_U8_t mode; +} tSmeBtAclModeChangeParam, *tpSmeBtAclModeChangeParam; + +/*Data structure that specifies the needed event parameters for + BT_EVENT_DISCONNECTION_COMPLETE +*/ +typedef struct sSmeBtDisconnectParam +{ + v_U16_t connectionHandle; +} tSmeBtDisconnectParam, *tpSmeBtDisconnectParam; + +/*Data structure that specifies the needed event parameters for + BT_EVENT_A2DP_STREAM_START + BT_EVENT_A2DP_STREAM_STOP +*/ +typedef struct sSmeBtA2DPParam +{ + v_U8_t bdAddr[6]; +} tSmeBtA2DPParam, *tpSmeBtA2DPParam; + + +/** Generic Bluetooth Event structure for BTC +*/ +typedef struct sSmeBtcBtEvent +{ + tSmeBtEventType btEventType; + union + { + v_U8_t bdAddr[6]; /**< For events with only a BT Addr in event_data */ + tSmeBtAclConnectionParam btAclConnection; + tSmeBtSyncConnectionParam btSyncConnection; + tSmeBtDisconnectParam btDisconnect; + tSmeBtAclModeChangeParam btAclModeChange; + }uEventParam; +} tSmeBtEvent, *tpSmeBtEvent; + + +/** + BT-AMP Event Structure +*/ +typedef struct sSmeBtAmpEvent +{ + tSmeBtAmpEventType btAmpEventType; + +} tSmeBtAmpEvent, *tpSmeBtAmpEvent; + + +/** Data structure that specifies the BTC Configuration parameters +*/ +typedef struct sSmeBtcConfig +{ + v_U8_t btcExecutionMode; + v_U8_t btcConsBtSlotsToBlockDuringDhcp; + v_U8_t btcA2DPBtSubIntervalsDuringDhcp; + v_U8_t btcActionOnPmFail; + v_U8_t btcBtIntervalMode1; + v_U8_t btcWlanIntervalMode1; + + v_U32_t btcStaticLenInqBt; + v_U32_t btcStaticLenPageBt; + v_U32_t btcStaticLenConnBt; + v_U32_t btcStaticLenLeBt; + v_U32_t btcStaticLenInqWlan; + v_U32_t btcStaticLenPageWlan; + v_U32_t btcStaticLenConnWlan; + v_U32_t btcStaticLenLeWlan; + v_U32_t btcDynMaxLenBt; + v_U32_t btcDynMaxLenWlan; + v_U32_t btcMaxScoBlockPerc; + v_U32_t btcDhcpProtOnA2dp; + v_U32_t btcDhcpProtOnSco; + + v_U32_t mwsCoexVictimWANFreq[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexVictimWLANFreq[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexVictimConfig[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexVictimConfig2[MWS_COEX_MAX_VICTIM_TABLE]; + v_U32_t mwsCoexModemBackoff; + v_U32_t mwsCoexConfig[MWS_COEX_MAX_CONFIG]; + v_U32_t SARPowerBackoff; +} tSmeBtcConfig, *tpSmeBtcConfig; + + +typedef struct sSmeBtAclModeChangeEventHist +{ + tSmeBtAclModeChangeParam btAclModeChange; + v_BOOL_t fValid; +} tSmeBtAclModeChangeEventHist, *tpSmeBtAclModeChangeEventHist; + +typedef struct sSmeBtAclEventHist +{ + //At most, cached events are COMPLETION, DISCONNECT, CREATION, COMPLETION + tSmeBtEventType btEventType[BT_MAX_NUM_EVENT_ACL_DEFERRED]; + tSmeBtAclConnectionParam btAclConnection[BT_MAX_NUM_EVENT_ACL_DEFERRED]; + //bNextEventIdx == 0 meaning no event cached here + tANI_U8 bNextEventIdx; +} tSmeBtAclEventHist, *tpSmeBtAclEventHist; + +typedef struct sSmeBtSyncEventHist +{ + //At most, cached events are COMPLETION, DISCONNECT, CREATION, COMPLETION + tSmeBtEventType btEventType[BT_MAX_NUM_EVENT_SCO_DEFERRED]; + tSmeBtSyncConnectionParam btSyncConnection[BT_MAX_NUM_EVENT_SCO_DEFERRED]; + //bNextEventIdx == 0 meaning no event cached here + tANI_U8 bNextEventIdx; +} tSmeBtSyncEventHist, *tpSmeBtSyncEventHist; + +typedef struct sSmeBtDisconnectEventHist +{ + tSmeBtDisconnectParam btDisconnect; + v_BOOL_t fValid; +} tSmeBtDisconnectEventHist, *tpSmeBtDisconnectEventHist; + + +/* + Data structure for the history of BT events +*/ +typedef struct sSmeBtcEventHist +{ + tSmeBtSyncEventHist btSyncConnectionEvent[BT_MAX_SCO_SUPPORT]; + tSmeBtAclEventHist btAclConnectionEvent[BT_MAX_ACL_SUPPORT]; + tSmeBtAclModeChangeEventHist btAclModeChangeEvent[BT_MAX_ACL_SUPPORT]; + tSmeBtDisconnectEventHist btDisconnectEvent[BT_MAX_DISCONN_SUPPORT]; + tSmeBtSyncUpdateHist btSyncUpdateEvent[BT_MAX_SCO_SUPPORT]; + int nInquiryEvent; //>0 for # of outstanding inquiriy starts + //<0 for # of outstanding inquiry stops + //0 == no inquiry event + int nPageEvent; //>0 for # of outstanding page starts + //<0 for # of outstanding page stops + //0 == no page event + v_BOOL_t fA2DPStarted; + v_BOOL_t fA2DPStopped; +} tSmeBtcEventHist, *tpSmeBtcEventHist; + +typedef struct sSmeBtcEventReplay +{ + tSmeBtcEventHist btcEventHist; + v_BOOL_t fBTSwitchOn; + v_BOOL_t fBTSwitchOff; + //This is not directly tied to BT event so leave it alone when processing BT events + v_BOOL_t fRestoreHBMonitor; +} tSmeBtcEventReplay, *tpSmeBtcEventReplay; + +typedef struct sSmeBtcInfo +{ + tSmeBtcConfig btcConfig; + v_BOOL_t btcReady; + v_U8_t btcEventState; + v_U8_t btcHBActive; /* Is HB currently active */ + v_U8_t btcHBCount; /* default HB count */ + vos_timer_t restoreHBTimer; /* Timer to restore heart beat */ + tSmeBtcEventReplay btcEventReplay; + v_BOOL_t fReplayBTEvents; + v_BOOL_t btcUapsdOk; /* Indicate whether BTC is ok with UAPSD */ + v_BOOL_t fA2DPTrafStop;/*flag to check A2DP_STOP event has come before MODE_CHANGED*/ + v_U16_t btcScoHandles[BT_MAX_SCO_SUPPORT]; /* Handles for SCO, if any*/ + v_BOOL_t fA2DPUp; /*remember whether A2DP is in session*/ + /* Scan compromise due to eSCO */ + bool btc_scan_compromise_esco; + /* Scan compromise due to SCO */ + bool btc_scan_compromise_sco; + v_U8_t btcBssfordisableaggr[VOS_MAC_ADDRESS_LEN]; + vos_timer_t enableUapsdTimer; +} tSmeBtcInfo, *tpSmeBtcInfo; + + +/** Routine definitions +*/ + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +VOS_STATUS btcOpen (tHalHandle hHal); +VOS_STATUS btcClose (tHalHandle hHal); +VOS_STATUS btcReady (tHalHandle hHal); +VOS_STATUS btcSendCfgMsg(tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); +VOS_STATUS btcSignalBTEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent); +VOS_STATUS btcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); +VOS_STATUS btcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); +/* + Caller can check whether BTC's current event allows UAPSD. This doesn't affect + BMPS. + return: VOS_TRUE -- BTC is ready for UAPSD + VOS_FALSE -- certain BT event is active, cannot enter UAPSD +*/ +v_BOOL_t btcIsReadyForUapsd( tHalHandle hHal ); +eHalStatus btcHandleCoexInd(tHalHandle hHal, void* pMsg); +#endif /* End of WLAN_MDM_CODE_REDUCTION_OPT */ + +#endif diff --git a/drivers/staging/prima/CORE/SME/inc/ccmApi.h b/drivers/staging/prima/CORE/SME/inc/ccmApi.h new file mode 100644 index 000000000000..0abfdc5b5b25 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/ccmApi.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file ccmApi.h + + \brief Exports and types for the Common Config Module (CCM) + + $Id$ + + This file contains all the interfaces for thge Platform Abstration Layer + functions. It is intended to be included in all modules that are using + the PAL interfaces. + + ========================================================================== */ +#ifndef CCMAPI_H__ +#define CCMAPI_H__ + +//#include "wniCfgAp.h" /* CFG_PARAM_MAX_NUM */ +#include "wniCfg.h" +#include "halTypes.h" + +#define CCM_11B_CHANNEL_END 14 + +#define CCM_IS_RESULT_SUCCESS(result) (WNI_CFG_SUCCESS == (result) ||\ + WNI_CFG_NEED_RESTART == (result) || \ + WNI_CFG_NEED_RELOAD == (result)) + +#define CCM_INTEGER_TYPE 0 +#define CCM_STRING_TYPE 1 + +typedef void (*tCcmCfgSetCallback)(tHalHandle hHal, tANI_S32 result) ; + +typedef enum { + eCCM_STOPPED, + eCCM_STARTED, + eCCM_REQ_SENT, + eCCM_REQ_QUEUED, + eCCM_REQ_DONE, +} eCcmState ; + +/* We do not use Linux's list facility */ +typedef struct cfgreq { + struct cfgreq *next ; + tANI_U16 cfgId ; + tANI_U8 type ; + tANI_U8 state : 7 ; + tANI_U8 toBeSaved : 1 ; + tANI_S32 length ; + void *ccmPtr; + tANI_U32 ccmValue; + tCcmCfgSetCallback callback; + void *done ; +} tCfgReq ; + +typedef struct { + tANI_U16 started : 1 ; + tANI_U16 in_progress : 1 ; + tANI_U16 reserved : 14 ; + tANI_S16 nr_param ; + tANI_U32 result ; + tCcmCfgSetCallback callback ; + void *done ; +} tCfgReplay ; + +struct ccmlink { + tCfgReq *head; + tCfgReq *tail; +} ; + +typedef struct { + struct ccmlink reqQ ; + eCcmState state ; + tCfgReq * comp[CFG_PARAM_MAX_NUM] ; + tCfgReplay replay ; + void *lock; +} tCcm ; + +void ccmCfgCnfMsgHandler(tHalHandle hHal, void *msg) ; +eHalStatus ccmOpen(tHalHandle hHal) ; +eHalStatus ccmClose(tHalHandle hHal) ; +void ccmStart(tHalHandle hHal) ; +void ccmStop(tHalHandle hHal) ; +//If callback is NULL, the API is not serialized for the CFGs +eHalStatus ccmCfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) ; +//If callback is NULL, the API is not serialized for the CFGs +eHalStatus ccmCfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, tANI_U32 length, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) ; +eHalStatus ccmCfgUpdate(tHalHandle hHal, tCcmCfgSetCallback callback) ; +eHalStatus ccmCfgGetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 *pValue) ; +eHalStatus ccmCfgGetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength) ; + +void ccmDumpInit(tHalHandle hHal); + +#endif /*CCMAPI_H__*/ diff --git a/drivers/staging/prima/CORE/SME/inc/csrApi.h b/drivers/staging/prima/CORE/SME/inc/csrApi.h new file mode 100644 index 000000000000..715c7e6a24d3 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/csrApi.h @@ -0,0 +1,1782 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrApi.h + + Exports and types for the Common Scan and Roaming Module interfaces. + ========================================================================== */ +#ifndef CSRAPI_H__ +#define CSRAPI_H__ + +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "csrLinkList.h" +typedef enum +{ + eCSR_AUTH_TYPE_NONE, //never used + // MAC layer authentication types + eCSR_AUTH_TYPE_OPEN_SYSTEM, + eCSR_AUTH_TYPE_SHARED_KEY, + eCSR_AUTH_TYPE_AUTOSWITCH, + + // Upper layer authentication types + eCSR_AUTH_TYPE_WPA, + eCSR_AUTH_TYPE_WPA_PSK, + eCSR_AUTH_TYPE_WPA_NONE, + + eCSR_AUTH_TYPE_RSN, + eCSR_AUTH_TYPE_RSN_PSK, +#if defined WLAN_FEATURE_VOWIFI_11R + eCSR_AUTH_TYPE_FT_RSN, + eCSR_AUTH_TYPE_FT_RSN_PSK, +#endif +#ifdef FEATURE_WLAN_WAPI + eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + eCSR_AUTH_TYPE_WAPI_WAI_PSK, +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + eCSR_AUTH_TYPE_CCKM_WPA, + eCSR_AUTH_TYPE_CCKM_RSN, +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + eCSR_AUTH_TYPE_RSN_PSK_SHA256, + eCSR_AUTH_TYPE_RSN_8021X_SHA256, +#endif + eCSR_NUM_OF_SUPPORT_AUTH_TYPE, + eCSR_AUTH_TYPE_FAILED = 0xff, + eCSR_AUTH_TYPE_UNKNOWN = eCSR_AUTH_TYPE_FAILED, + +}eCsrAuthType; + + +typedef enum +{ + eCSR_ENCRYPT_TYPE_NONE, + eCSR_ENCRYPT_TYPE_WEP40_STATICKEY, + eCSR_ENCRYPT_TYPE_WEP104_STATICKEY, + + eCSR_ENCRYPT_TYPE_WEP40, + eCSR_ENCRYPT_TYPE_WEP104, + eCSR_ENCRYPT_TYPE_TKIP, + eCSR_ENCRYPT_TYPE_AES, +#ifdef FEATURE_WLAN_WAPI + eCSR_ENCRYPT_TYPE_WPI, //WAPI +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + eCSR_ENCRYPT_TYPE_KRK, +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + //11w BIP + eCSR_ENCRYPT_TYPE_AES_CMAC, +#endif + eCSR_ENCRYPT_TYPE_ANY, + eCSR_NUM_OF_ENCRYPT_TYPE = eCSR_ENCRYPT_TYPE_ANY, + + eCSR_ENCRYPT_TYPE_FAILED = 0xff, + eCSR_ENCRYPT_TYPE_UNKNOWN = eCSR_ENCRYPT_TYPE_FAILED, + +}eCsrEncryptionType; + +/*--------------------------------------------------------------------------- + Enumeration of the various Security types +---------------------------------------------------------------------------*/ +typedef enum +{ + eCSR_SECURITY_TYPE_WPA, + eCSR_SECURITY_TYPE_RSN, +#ifdef FEATURE_WLAN_WAPI + eCSR_SECURITY_TYPE_WAPI, +#endif /* FEATURE_WLAN_WAPI */ + eCSR_SECURITY_TYPE_UNKNOWN, + +}eCsrSecurityType; + +typedef enum +{ + eCSR_DOT11_MODE_TAURUS = 0, //This mean everything because it covers all thing we support + eCSR_DOT11_MODE_abg = 0x0001, //11a/b/g only, no HT, no proprietary + eCSR_DOT11_MODE_11a = 0x0002, + eCSR_DOT11_MODE_11b = 0x0004, + eCSR_DOT11_MODE_11g = 0x0008, + eCSR_DOT11_MODE_11n = 0x0010, + eCSR_DOT11_MODE_POLARIS = 0x0020, + eCSR_DOT11_MODE_TITAN = 0x0040, + eCSR_DOT11_MODE_11g_ONLY = 0x0080, + eCSR_DOT11_MODE_11n_ONLY = 0x0100, + eCSR_DOT11_MODE_TAURUS_ONLY = 0x0200, + eCSR_DOT11_MODE_11b_ONLY = 0x0400, + eCSR_DOT11_MODE_11a_ONLY = 0x0800, +#ifdef WLAN_FEATURE_11AC + eCSR_DOT11_MODE_11ac = 0x1000, + eCSR_DOT11_MODE_11ac_ONLY = 0x2000, +#endif + //This is for WIFI test. It is same as eWNIAPI_MAC_PROTOCOL_ALL except when it starts IBSS in 11B of 2.4GHz + //It is for CSR internal use + eCSR_DOT11_MODE_AUTO = 0x4000, + + eCSR_NUM_PHY_MODE = 16, //specify the number of maximum bits for phyMode +}eCsrPhyMode; + + +typedef tANI_U8 tCsrBssid[WNI_CFG_BSSID_LEN]; + +typedef enum +{ + eCSR_BSS_TYPE_NONE, + eCSR_BSS_TYPE_INFRASTRUCTURE, + eCSR_BSS_TYPE_INFRA_AP, // SoftAP AP + eCSR_BSS_TYPE_IBSS, // an IBSS network we will NOT start + eCSR_BSS_TYPE_START_IBSS, // an IBSS network we will start if no partners detected. + eCSR_BSS_TYPE_WDS_AP, // BT-AMP AP + eCSR_BSS_TYPE_WDS_STA, // BT-AMP station + eCSR_BSS_TYPE_ANY, // any BSS type (IBSS or Infrastructure). +}eCsrRoamBssType; + + + +typedef enum { + eCSR_SCAN_REQUEST_11D_SCAN = 1, + eCSR_SCAN_REQUEST_FULL_SCAN, + eCSR_SCAN_IDLE_MODE_SCAN, + eCSR_SCAN_HO_BG_SCAN, // bg scan request in NRT & RT Handoff sub-states + eCSR_SCAN_HO_PROBE_SCAN, // directed probe on an entry from the candidate list + eCSR_SCAN_HO_NT_BG_SCAN, // bg scan request in NT sub-state + eCSR_SCAN_P2P_DISCOVERY, + + eCSR_SCAN_SOFTAP_CHANNEL_RANGE, + eCSR_SCAN_P2P_FIND_PEER, +}eCsrRequestType; +typedef enum { + eCSR_SCAN_RESULT_GET = 0, + eCSR_SCAN_RESULT_FLUSH = 1, //to delete all cached scan results +}eCsrScanResultCmd; + +typedef enum +{ + eCSR_SCAN_SUCCESS, + eCSR_SCAN_FAILURE, + eCSR_SCAN_ABORT, + eCSR_SCAN_FOUND_PEER, +}eCsrScanStatus; + +/* Reason to abort the scan + * The reason can used later to decide whether to update the scan results + * to upper layer or not + */ +typedef enum +{ + eCSR_SCAN_ABORT_DEFAULT = 1, + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE, //Scan aborted due to band change +}eCsrAbortReason; + +typedef enum +{ + eCSR_INI_SINGLE_CHANNEL_CENTERED = 0, + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY, + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY, +#ifdef WLAN_FEATURE_11AC + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH, + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH, +#endif + eCSR_INI_CHANNEL_BONDING_STATE_MAX +}eIniChanBondState; + +#define CSR_SCAN_TIME_DEFAULT 0 +#define CSR_VALUE_IGNORED 0xFFFFFFFF +#define CSR_RSN_PMKID_SIZE 16 +#define CSR_MAX_PMKID_ALLOWED 32 +#define CSR_WEP40_KEY_LEN 5 +#define CSR_WEP104_KEY_LEN 13 +#define CSR_TKIP_KEY_LEN 32 +#define CSR_AES_KEY_LEN 16 +#define CSR_MAX_TX_POWER ( WNI_CFG_CURRENT_TX_POWER_LEVEL_STAMAX ) +#define CSR_MAX_RSC_LEN 16 +#ifdef FEATURE_WLAN_WAPI +#define CSR_WAPI_BKID_SIZE 16 +#define CSR_MAX_BKID_ALLOWED 16 +#define CSR_WAPI_KEY_LEN 32 +#define CSR_MAX_KEY_LEN ( CSR_WAPI_KEY_LEN ) //longest one is for WAPI +#else +#define CSR_MAX_KEY_LEN ( CSR_TKIP_KEY_LEN ) //longest one is for TKIP +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE +#define CSR_KRK_KEY_LEN 16 +#endif + + + +typedef struct tagCsrChannelInfo +{ + tANI_U8 numOfChannels; + tANI_U8 *ChannelList; //it will be an array of channels +}tCsrChannelInfo, *tpCsrChannelInfo; + +typedef struct tagCsrSSIDInfo +{ + tSirMacSSid SSID; + tANI_BOOLEAN handoffPermitted; + tANI_BOOLEAN ssidHidden; +}tCsrSSIDInfo; + +typedef struct tagCsrSSIDs +{ + tANI_U32 numOfSSIDs; + tCsrSSIDInfo *SSIDList; //To be allocated for array of SSIDs +}tCsrSSIDs; + +typedef struct tagCsrBSSIDs +{ + tANI_U32 numOfBSSIDs; + tCsrBssid *bssid; +}tCsrBSSIDs; + +typedef struct tagCsrStaParams +{ + tANI_U16 capability; + tANI_U8 extn_capability[SIR_MAC_MAX_EXTN_CAP]; + tANI_U8 supported_rates_len; + tANI_U8 supported_rates[SIR_MAC_MAX_SUPP_RATES]; + tANI_U8 htcap_present; + tSirHTCap HTCap; + tANI_U8 vhtcap_present; + tSirVHTCap VHTCap; + tANI_U8 uapsd_queues; + tANI_U8 max_sp; + tANI_U8 supported_channels_len; + tANI_U8 supported_channels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supported_oper_classes_len; + tANI_U8 supported_oper_classes[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +}tCsrStaParams; + +typedef struct tagCsrScanRequest +{ + tSirScanType scanType; + tCsrBssid bssid; + eCsrRoamBssType BSSType; + tCsrSSIDs SSIDs; + tCsrChannelInfo ChannelInfo; + tANI_U32 minChnTime; //in units of milliseconds + tANI_U32 maxChnTime; //in units of milliseconds + tANI_U32 min_chntime_btc_esco; //in units of milliseconds + tANI_U32 max_chntime_btc_esco; //in units of milliseconds + tANI_U32 restTime; //in units of milliseconds //ignored when not connected + tANI_U32 uIEFieldLen; + tANI_U8 *pIEField; + eCsrRequestType requestType; //11d scan or full scan + tANI_BOOLEAN p2pSearch; + tANI_BOOLEAN skipDfsChnlInP2pSearch; +}tCsrScanRequest; + +typedef struct tagCsrBGScanRequest +{ + tSirScanType scanType; + tSirMacSSid SSID; + tCsrChannelInfo ChannelInfo; + tANI_U32 scanInterval; //in units of milliseconds + tANI_U32 minChnTime; //in units of milliseconds + tANI_U32 maxChnTime; //in units of milliseconds + tANI_U32 min_chntime_btc_esco; //in units of milliseconds + tANI_U32 max_chntime_btc_esco; //in units of milliseconds + tANI_U32 restTime; //in units of milliseconds //ignored when not connected + tANI_U32 throughputImpact; //specify whether BG scan cares about impacting throughput //ignored when not connected + tCsrBssid bssid; //how to use it?? Apple +}tCsrBGScanRequest, *tpCsrBGScanRequest; + + +typedef struct tagCsrScanResultInfo +{ + //Carry the IEs for the current BSSDescription. A pointer to tDot11fBeaconIEs. Maybe NULL for start BSS. + void *pvIes; + tAniSSID ssId; + v_TIME_t timer; // timer is variable which is used for hidden SSID's timer value + //This member must be the last in the structure because the end of tSirBssDescription is an + // array with nonknown size at this time + tSirBssDescription BssDescriptor; +}tCsrScanResultInfo; + +typedef struct tagCsrEncryptionList +{ + + tANI_U32 numEntries; + eCsrEncryptionType encryptionType[eCSR_NUM_OF_ENCRYPT_TYPE]; + +}tCsrEncryptionList, *tpCsrEncryptionList; + +typedef struct tagCsrAuthList +{ + tANI_U32 numEntries; + eCsrAuthType authType[eCSR_NUM_OF_SUPPORT_AUTH_TYPE]; +}tCsrAuthList, *tpCsrAuthList; + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct tagCsrMobilityDomainInfo +{ + tANI_U8 mdiePresent; + tANI_U16 mobilityDomain; +} tCsrMobilityDomainInfo; +#endif + +#ifdef FEATURE_WLAN_ESE +typedef struct tagCsrEseCckmInfo +{ + tANI_U32 reassoc_req_num; + tANI_BOOLEAN krk_plumbed; + tANI_U8 krk[CSR_KRK_KEY_LEN]; +} tCsrEseCckmInfo; +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +#define CSR_DOT11F_IE_RSN_MAX_LEN (114) /*TODO: duplicate one in dot11f.h */ + +typedef struct tagCsrEseCckmIe +{ + tANI_U8 cckmIe[CSR_DOT11F_IE_RSN_MAX_LEN]; + tANI_U8 cckmIeLen; +} tCsrEseCckmIe; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +typedef struct tagCsrScanResultFilter +{ + tCsrBSSIDs BSSIDs; //each bssid has a length of WNI_CFG_BSSID_LEN (6) + tCsrSSIDs SSIDs; + tCsrChannelInfo ChannelInfo; + tCsrAuthList authType; + tCsrEncryptionList EncryptionType; + //eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type. If caller doesn't case, + //put all supported encryption types in here + tCsrEncryptionList mcEncryptionType; + eCsrRoamBssType BSSType; + //this is a bit mask of all the needed phy mode defined in eCsrPhyMode + tANI_U32 phyMode; + //If countryCode[0] is not 0, countryCode is checked independent of fCheckUnknownCountryCode + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; + tANI_U8 uapsd_mask; + /*For WPS filtering if true => auth and ecryption should be ignored*/ + tANI_BOOLEAN bWPSAssociation; + tANI_BOOLEAN bOSENAssociation; +#if defined WLAN_FEATURE_VOWIFI + /*For measurement reports --> if set, only SSID, BSSID and channel is considered for filtering.*/ + tANI_BOOLEAN fMeasurement; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsrMobilityDomainInfo MDID; +#endif + tANI_BOOLEAN p2pResult; +#ifdef WLAN_FEATURE_11W + // Management Frame Protection + tANI_BOOLEAN MFPEnabled; + tANI_U8 MFPRequired; + tANI_U8 MFPCapable; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tANI_BOOLEAN isPERRoamScan; +#endif + tCsrBssid bssid_hint; +}tCsrScanResultFilter; + + +typedef struct sCsrChnPower_ +{ + tANI_U8 firstChannel; + tANI_U8 numChannels; + tANI_U8 maxtxPower; +}sCsrChnPower; + + +typedef struct sCsrChannel_ +{ + tANI_U8 numChannels; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}sCsrChannel; + + +typedef struct tagCsr11dinfo +{ + sCsrChannel Channels; + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN+1]; + //max power channel list + sCsrChnPower ChnPower[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tCsr11dinfo; + + +typedef enum +{ + eCSR_ROAM_CANCELLED = 1, + //this mean error happens before association_start or roaming_start is called. + eCSR_ROAM_FAILED, + //a CSR trigger roaming operation starts, callback may get a pointer to tCsrConnectedProfile + eCSR_ROAM_ROAMING_START, + //a CSR trigger roaming operation is completed + eCSR_ROAM_ROAMING_COMPLETION, + //Connection completed status. + eCSR_ROAM_CONNECT_COMPLETION, + //an association or start_IBSS operation starts, + //callback may get a pointer to tCsrRoamProfile and a pointer to tSirBssDescription + eCSR_ROAM_ASSOCIATION_START, + //a roaming operation is finish, see eCsrRoamResult for + //possible data passed back + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_DISASSOCIATED, + eCSR_ROAM_ASSOCIATION_FAILURE, + //when callback with this flag. callback gets a pointer to the BSS desc. + eCSR_ROAM_SHOULD_ROAM, + //A new candidate for PMKID is found + eCSR_ROAM_SCAN_FOUND_NEW_BSS, + //CSR is done lostlink roaming and still cannot reconnect + eCSR_ROAM_LOSTLINK, + //a link lost is detected. CSR starts roaming. + eCSR_ROAM_LOSTLINK_DETECTED, + //TKIP MIC error detected, callback gets a pointer to tpSirSmeMicFailureInd + eCSR_ROAM_MIC_ERROR_IND, + eCSR_ROAM_IBSS_IND, //IBSS indications. + //Update the connection status, useful for IBSS: new peer added, network is active etc. + eCSR_ROAM_CONNECT_STATUS_UPDATE, + eCSR_ROAM_GEN_INFO, + eCSR_ROAM_SET_KEY_COMPLETE, + eCSR_ROAM_REMOVE_KEY_COMPLETE, + eCSR_ROAM_IBSS_LEAVE, //IBSS indications. + //BSS in WDS mode status indication + eCSR_ROAM_WDS_IND, + //BSS in SoftAP mode status indication + eCSR_ROAM_INFRA_IND, + eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, +#ifdef WLAN_FEATURE_VOWIFI_11R + eCSR_ROAM_FT_RESPONSE, +#endif + eCSR_ROAM_FT_START, + eCSR_ROAM_REMAIN_CHAN_READY, + eCSR_ROAM_SEND_ACTION_CNF, + //this mean error happens before association_start or roaming_start is called. + eCSR_ROAM_SESSION_OPENED, + eCSR_ROAM_FT_REASSOC_FAILED, +#ifdef FEATURE_WLAN_LFR + eCSR_ROAM_PMK_NOTIFY, +#endif +#ifdef FEATURE_WLAN_LFR_METRICS + eCSR_ROAM_PREAUTH_INIT_NOTIFY, + eCSR_ROAM_PREAUTH_STATUS_SUCCESS, + eCSR_ROAM_PREAUTH_STATUS_FAILURE, + eCSR_ROAM_HANDOVER_SUCCESS, +#endif +#ifdef FEATURE_WLAN_TDLS + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, +#endif + eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, //Disaconnect all the clients + eCSR_ROAM_SEND_P2P_STOP_BSS, //Stopbss triggered from SME due to different + // beacon interval +#ifdef WLAN_FEATURE_11W + eCSR_ROAM_UNPROT_MGMT_FRAME_IND, +#endif + +#ifdef WLAN_FEATURE_RMC + eCSR_ROAM_IBSS_PEER_INFO_COMPLETE, +#endif + +#ifdef WLAN_FEATURE_AP_HT40_24G + eCSR_ROAM_2040_COEX_INFO_IND, +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + eCSR_ROAM_TSM_IE_IND, + eCSR_ROAM_CCKM_PREAUTH_NOTIFY, + eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, + eCSR_ROAM_ESE_BCN_REPORT_IND, +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + eCSR_ROAM_UPDATE_MAX_RATE_IND, + eCSR_ROAM_LOST_LINK_PARAMS_IND, + eCSR_ROAM_UPDATE_SCAN_RESULT, +}eRoamCmdStatus; + + +//comment inside indicates what roaming callback gets +typedef enum +{ + eCSR_ROAM_RESULT_NONE, + //this means no more action in CSR + //If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION, tCsrRoamInfo's pBssDesc may pass back + eCSR_ROAM_RESULT_FAILURE, + //Pass back pointer to tCsrRoamInfo + eCSR_ROAM_RESULT_ASSOCIATED, + eCSR_ROAM_RESULT_NOT_ASSOCIATED, + eCSR_ROAM_RESULT_MIC_FAILURE, + eCSR_ROAM_RESULT_FORCED, + eCSR_ROAM_RESULT_DISASSOC_IND, + eCSR_ROAM_RESULT_DEAUTH_IND, + eCSR_ROAM_RESULT_CAP_CHANGED, + //This means we starts an IBSS + //tCsrRoamInfo's pBssDesc may pass back + eCSR_ROAM_RESULT_IBSS_STARTED, + //START_BSS failed + //tCsrRoamInfo's pBssDesc may pass back + eCSR_ROAM_RESULT_IBSS_START_FAILED, + eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS, + eCSR_ROAM_RESULT_IBSS_JOIN_FAILED, + eCSR_ROAM_RESULT_IBSS_CONNECT, + eCSR_ROAM_RESULT_IBSS_INACTIVE, + //If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION + //tCsrRoamInfo's pBssDesc may pass back. and the peer's MAC address in peerMacOrBssid + //If roamStatus is eCSR_ROAM_IBSS_IND, + //the peer's MAC address in peerMacOrBssid and a beacon frame of the IBSS in pbFrames + eCSR_ROAM_RESULT_IBSS_NEW_PEER, + //Peer departed from IBSS, Callback may get a pointer tSmeIbssPeerInd in pIbssPeerInd + eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED, + //Coalescing in the IBSS network (joined an IBSS network) + //Callback pass a BSSID in peerMacOrBssid + eCSR_ROAM_RESULT_IBSS_COALESCED, + //If roamStatus is eCSR_ROAM_ROAMING_START, callback may get a pointer to tCsrConnectedProfile used to connect. + eCSR_ROAM_RESULT_IBSS_STOP, + eCSR_ROAM_RESULT_LOSTLINK, + eCSR_ROAM_RESULT_MIC_ERROR_UNICAST, + eCSR_ROAM_RESULT_MIC_ERROR_GROUP, + eCSR_ROAM_RESULT_AUTHENTICATED, + eCSR_ROAM_RESULT_NEW_RSN_BSS, +#ifdef FEATURE_WLAN_WAPI + eCSR_ROAM_RESULT_NEW_WAPI_BSS, +#endif /* FEATURE_WLAN_WAPI */ + // WDS started successfully + eCSR_ROAM_RESULT_WDS_STARTED, + // WDS start failed + eCSR_ROAM_RESULT_WDS_START_FAILED, + // WDS stopped + eCSR_ROAM_RESULT_WDS_STOPPED, + // WDS joined successfully in STA mode + eCSR_ROAM_RESULT_WDS_ASSOCIATED, + // A station joined WDS AP + eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND, + // WDS join failed in STA mode + eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED, + // WDS disassociated + eCSR_ROAM_RESULT_WDS_DISASSOCIATED, + // INFRA started successfully + eCSR_ROAM_RESULT_INFRA_STARTED, + // INFRA start failed + eCSR_ROAM_RESULT_INFRA_START_FAILED, + // INFRA stopped + eCSR_ROAM_RESULT_INFRA_STOPPED, + // A station joining INFRA AP + eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND, + // A station joined INFRA AP + eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF, + // INFRA disassociated + eCSR_ROAM_RESULT_INFRA_DISASSOCIATED, + eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND, + eCSR_ROAM_RESULT_SEND_ACTION_FAIL, + // peer rejected assoc because max assoc limit reached. callback gets pointer to peer + eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED, + //Assoc rejected due to concurrent session running on a different channel + eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL, +#ifdef FEATURE_WLAN_TDLS + eCSR_ROAM_RESULT_ADD_TDLS_PEER, + eCSR_ROAM_RESULT_UPDATE_TDLS_PEER, + eCSR_ROAM_RESULT_DELETE_TDLS_PEER, + eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND, + eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND, + eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP, + eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP, +#endif + +#ifdef WLAN_FEATURE_RMC + eCSR_ROAM_RESULT_IBSS_PEER_INFO_SUCCESS, + eCSR_ROAM_RESULT_IBSS_PEER_INFO_FAILED, +#endif + /* If Scan for SSID failed to found proper BSS */ + eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE, +}eCsrRoamResult; + + + +/*---------------------------------------------------------------------------- + List of link quality indications HDD can receive from SME +-----------------------------------------------------------------------------*/ +typedef enum +{ + eCSR_ROAM_LINK_QUAL_MIN_IND = -1, + + eCSR_ROAM_LINK_QUAL_POOR_IND = 0, /* bad link */ + eCSR_ROAM_LINK_QUAL_GOOD_IND = 1, /* acceptable for voice */ + eCSR_ROAM_LINK_QUAL_VERY_GOOD_IND = 2, /* suitable for voice */ + eCSR_ROAM_LINK_QUAL_EXCELLENT_IND = 3, /* suitable for voice */ + + eCSR_ROAM_LINK_QUAL_MAX_IND /* invalid value */ + +} eCsrRoamLinkQualityInd; + +typedef enum +{ + eCSR_DISCONNECT_REASON_UNSPECIFIED = 0, + eCSR_DISCONNECT_REASON_MIC_ERROR, + eCSR_DISCONNECT_REASON_DISASSOC, + eCSR_DISCONNECT_REASON_DEAUTH, + eCSR_DISCONNECT_REASON_HANDOFF, + eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE, + eCSR_DISCONNECT_REASON_IBSS_LEAVE, +}eCsrRoamDisconnectReason; + +typedef enum +{ + // Not associated in Infra or participating in an IBSS / Ad-hoc network. + eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED, + // Associated in an Infrastructure network. + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED, + // Participating in an IBSS network though disconnected (no partner stations + // in the IBSS). + eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED, + // Participating in an IBSS network with partner stations also present + eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED, + // Participating in a WDS network in AP or STA mode but not connected yet + eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED, + // Participating in a WDS network and connected peer to peer + eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED, + // Participating in a Infra network in AP not yet in connected state + eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED, + // Participating in a Infra network and connected to a peer + eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED, + +}eCsrConnectState; + + +// This parameter is no longer supported in the Profile. Need to set this in the global properties +// for the adapter. +typedef enum eCSR_MEDIUM_ACCESS +{ + eCSR_MEDIUM_ACCESS_AUTO = 0, + eCSR_MEDIUM_ACCESS_DCF, + eCSR_MEDIUM_ACCESS_eDCF, + eCSR_MEDIUM_ACCESS_HCF, + + eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p, + eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP, + eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify, + eCSR_MEDIUM_ACCESS_11e_eDCF = eCSR_MEDIUM_ACCESS_eDCF, + eCSR_MEDIUM_ACCESS_11e_HCF = eCSR_MEDIUM_ACCESS_HCF, +}eCsrMediaAccessType; + +typedef enum +{ + eCSR_TX_RATE_AUTO = 0, // use rate adaption to determine Tx rate. + + eCSR_TX_RATE_1Mbps = 0x00000001, + eCSR_TX_RATE_2Mbps = 0x00000002, + eCSR_TX_RATE_5_5Mbps = 0x00000004, + eCSR_TX_RATE_6Mbps = 0x00000008, + eCSR_TX_RATE_9Mbps = 0x00000010, + eCSR_TX_RATE_11Mbps = 0x00000020, + eCSR_TX_RATE_12Mbps = 0x00000040, + eCSR_TX_RATE_18Mbps = 0x00000080, + eCSR_TX_RATE_24Mbps = 0x00000100, + eCSR_TX_RATE_36Mbps = 0x00000200, + eCSR_TX_RATE_42Mbps = 0x00000400, + eCSR_TX_RATE_48Mbps = 0x00000800, + eCSR_TX_RATE_54Mbps = 0x00001000, + eCSR_TX_RATE_72Mbps = 0x00002000, + eCSR_TX_RATE_84Mbps = 0x00004000, + eCSR_TX_RATE_96Mbps = 0x00008000, + eCSR_TX_RATE_108Mbps = 0x00010000, + eCSR_TX_RATE_126Mbps = 0x00020000, + eCSR_TX_RATE_144Mbps = 0x00040000, + eCSR_TX_RATE_168Mbps = 0x00080000, + eCSR_TX_RATE_192Mbps = 0x00100000, + eCSR_TX_RATE_216Mbps = 0x00200000, + eCSR_TX_RATE_240Mbps = 0x00400000, + +}eCsrExposedTxRate; + +typedef enum +{ + eCSR_OPERATING_CHANNEL_ALL = 0, + eCSR_OPERATING_CHANNEL_AUTO = eCSR_OPERATING_CHANNEL_ALL, + eCSR_OPERATING_CHANNEL_ANY = eCSR_OPERATING_CHANNEL_ALL, +}eOperationChannel; + +typedef enum +{ + eCSR_DOT11_FRAG_THRESH_AUTO = -1, + eCSR_DOT11_FRAG_THRESH_MIN = 256, + eCSR_DOT11_FRAG_THRESH_MAX = 2346, + eCSR_DOT11_FRAG_THRESH_DEFAULT = 2000 +}eCsrDot11FragThresh; + + +//for channel bonding for ibss +typedef enum +{ + eCSR_CB_OFF = 0, + eCSR_CB_AUTO = 1, + eCSR_CB_DOWN = 2, + eCSR_CB_UP = 3, +}eCsrCBChoice; + +//For channel bonding, the channel number gap is 4, either up or down. For both 11a and 11g mode. +#define CSR_CB_CHANNEL_GAP 4 +#define CSR_CB_CENTER_CHANNEL_OFFSET 2 +#define CSR_MAX_24GHz_CHANNEL_NUMBER ( SIR_11B_CHANNEL_END ) +#define CSR_MIN_5GHz_CHANNEL_NUMBER ( SIR_11A_CHANNEL_BEGIN ) +#define CSR_MAX_5GHz_CHANNEL_NUMBER ( SIR_11A_CHANNEL_END ) + +// WEP keysize (in bits)... +typedef enum +{ + eCSR_SECURITY_WEP_KEYSIZE_40 = 40, // 40 bit key + 24bit IV = 64bit WEP + eCSR_SECURITY_WEP_KEYSIZE_104 = 104, // 104bit key + 24bit IV = 128bit WEP + + eCSR_SECURITY_WEP_KEYSIZE_MIN = eCSR_SECURITY_WEP_KEYSIZE_40, + eCSR_SECURITY_WEP_KEYSIZE_MAX = eCSR_SECURITY_WEP_KEYSIZE_104, + eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES = ( eCSR_SECURITY_WEP_KEYSIZE_MAX / 8 ), +}eCsrWEPKeySize; + + +// Possible values for the WEP static key ID... +typedef enum +{ + + eCSR_SECURITY_WEP_STATIC_KEY_ID_MIN = 0, + eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX = 3, + eCSR_SECURITY_WEP_STATIC_KEY_ID_DEFAULT = 0, + + eCSR_SECURITY_WEP_STATIC_KEY_ID_INVALID = -1, + +}eCsrWEPStaticKeyID; + +// Two extra key indicies are used for the IGTK (which is used by BIP) +#define CSR_MAX_NUM_KEY (eCSR_SECURITY_WEP_STATIC_KEY_ID_MAX + 2 + 1) + +typedef enum +{ + eCSR_SECURITY_SET_KEY_ACTION_NO_CHANGE, + eCSR_SECURITY_SET_KEY_ACTION_SET_KEY, + eCSR_SECURITY_SET_KEY_ACTION_DELETE_KEY, +}eCsrSetKeyAction; + +typedef enum +{ + eCSR_BAND_ALL, + eCSR_BAND_24, + eCSR_BAND_5G, + eCSR_BAND_MAX, +}eCsrBand; + + +typedef enum +{ + // Roaming because HDD requested for reassoc by changing one of the fields in + // tCsrRoamModifyProfileFields. OR + // Roaming because SME requested for reassoc by changing one of the fields in + // tCsrRoamModifyProfileFields. + eCsrRoamReasonStaCapabilityChanged, + // Roaming because SME requested for reassoc to a different AP, as part of + // inter AP handoff. + eCsrRoamReasonBetterAP, + // Roaming because SME requested it as the link is lost - placeholder, will + // clean it up once handoff code gets in + eCsrRoamReasonSmeIssuedForLostLink, + +}eCsrRoamReasonCodes; + +typedef enum +{ + eCsrRoamWmmAuto = 0, + eCsrRoamWmmQbssOnly = 1, + eCsrRoamWmmNoQos = 2, + +} eCsrRoamWmmUserModeType; + +typedef enum +{ + eCSR_REQUESTER_MIN = 0, + eCSR_DIAG, + eCSR_UMA_GAN, + eCSR_HDD +} eCsrStatsRequesterType; + +typedef enum +{ + INIT = 0, + REINIT, +} driver_load_type; + +typedef struct tagPmkidCandidateInfo +{ + tCsrBssid BSSID; + tANI_BOOLEAN preAuthSupported; +}tPmkidCandidateInfo; + +typedef struct tagPmkidCacheInfo +{ + tCsrBssid BSSID; + tANI_U8 PMKID[CSR_RSN_PMKID_SIZE]; +}tPmkidCacheInfo; + +#ifdef FEATURE_WLAN_WAPI +typedef struct tagBkidCandidateInfo +{ + tCsrBssid BSSID; + tANI_BOOLEAN preAuthSupported; +}tBkidCandidateInfo; + +typedef struct tagBkidCacheInfo +{ + tCsrBssid BSSID; + tANI_U8 BKID[CSR_WAPI_BKID_SIZE]; +}tBkidCacheInfo; +#endif /* FEATURE_WLAN_WAPI */ + +typedef struct tagCsrKeys +{ + tANI_U8 KeyLength[ CSR_MAX_NUM_KEY ]; //Also use to indicate whether the key index is set + tANI_U8 KeyMaterial[ CSR_MAX_NUM_KEY ][ CSR_MAX_KEY_LEN ]; + tANI_U8 defaultIndex; +}tCsrKeys; + +/* Following are fields which are part of tCsrRoamConnectedProfile might need + modification dynamically once STA is up & running and this could trigger + reassoc */ +typedef struct tagCsrRoamModifyProfileFields +{ + // during connect this specifies ACs U-APSD is to be setup + // for (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored). + // During assoc response this COULD carry confirmation of what ACs U-APSD + // got setup for. Later if an APP looking for APSD, SME-QoS might need to + // modify this field + tANI_U8 uapsd_mask; + // HDD might ask to modify this field + tANI_U16 listen_interval; +}tCsrRoamModifyProfileFields; + +typedef struct tagCsrRoamProfile +{ + //For eCSR_BSS_TYPE_WDS_AP. There must be one SSID in SSIDs. + //For eCSR_BSS_TYPE_WDS_STA. There must be two SSIDs. Index 0 is the SSID of the WDS-AP + //that we need to join. Index 1 is the SSID for self BSS. + tCsrSSIDs SSIDs; + tCsrBSSIDs BSSIDs; + tANI_U32 phyMode; //this is a bit mask of all the needed phy mode defined in eCsrPhyMode + eCsrRoamBssType BSSType; + + tCsrAuthList AuthType; + eCsrAuthType negotiatedAuthType; + + tCsrEncryptionList EncryptionType; + //This field is for output only, not for input + eCsrEncryptionType negotiatedUCEncryptionType; + + //eCSR_ENCRYPT_TYPE_ANY cannot be set in multicast encryption type. If caller doesn't case, + //put all supported encryption types in here + tCsrEncryptionList mcEncryptionType; + //This field is for output only, not for input + eCsrEncryptionType negotiatedMCEncryptionType; + +#ifdef WLAN_FEATURE_11W + // Management Frame Protection + tANI_BOOLEAN MFPEnabled; + tANI_U8 MFPRequired; + tANI_U8 MFPCapable; +#endif + + tCsrKeys Keys; + eCsrCBChoice CBMode; //up, down or auto + tCsrChannelInfo ChannelInfo; + tANI_U8 operationChannel; + tANI_U16 beaconInterval; //If this is 0, SME will fill in for caller. + // during connect this specifies ACs U-APSD is to be setup + // for (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored). + // During assoc response this COULD carry confirmation of what ACs U-APSD got setup for + tANI_U8 uapsd_mask; + tANI_U32 nWPAReqIELength; //The byte count in the pWPAReqIE + tANI_U8 *pWPAReqIE; //If not null, it has the IE byte stream for WPA + tANI_U32 nRSNReqIELength; //The byte count in the pRSNReqIE + tANI_U8 *pRSNReqIE; //If not null, it has the IE byte stream for RSN +#ifdef FEATURE_WLAN_WAPI + tANI_U32 nWAPIReqIELength; //The byte count in the pWAPIReqIE + tANI_U8 *pWAPIReqIE; //If not null, it has the IE byte stream for WAPI +#endif /* FEATURE_WLAN_WAPI */ + + //The byte count in the pAddIE for scan (at the time of join) + tANI_U32 nAddIEScanLength; + /* Additional IE information. + * It has the IE byte stream for additional IE, + * which can be WSC IE and/or P2P IE + */ + tANI_U8 addIEScan[SIR_MAC_MAX_ADD_IE_LENGTH+2]; //Additional IE information. + tANI_U32 nAddIEAssocLength; //The byte count in the pAddIE for assoc + tANI_U8 *pAddIEAssoc; //If not null, it has the IE byte stream for additional IE, which can be WSC IE and/or P2P IE + + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; //it is ignored if [0] is 0. + /*WPS Association if true => auth and ecryption should be ignored*/ + tANI_BOOLEAN bWPSAssociation; + tANI_BOOLEAN bOSENAssociation; + tANI_U32 nWSCReqIELength; //The byte count in the pWSCReqIE + tANI_U8 *pWSCReqIE; //If not null, it has the IE byte stream for WSC + + tANI_U8 ieee80211d; + tANI_U8 privacy; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tAniAuthType csr80211AuthType; + tANI_U32 dtimPeriod; + tANI_BOOLEAN ApUapsdEnable; + tANI_BOOLEAN protEnabled; + tANI_BOOLEAN obssProtEnabled; + tANI_U16 cfg_protection; + tANI_U8 wps_state; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsrMobilityDomainInfo MDID; +#endif + tVOS_CON_MODE csrPersona; + bool force_24ghz_in_ht20; + tCsrBssid bssid_hint; +}tCsrRoamProfile; + + +typedef struct tagCsrRoamConnectedProfile +{ + tSirMacSSid SSID; + tANI_BOOLEAN handoffPermitted; + tANI_BOOLEAN ssidHidden; + tCsrBssid bssid; + eCsrRoamBssType BSSType; + eCsrAuthType AuthType; + tCsrAuthList AuthInfo; + eCsrEncryptionType EncryptionType; + tCsrEncryptionList EncryptionInfo; + eCsrEncryptionType mcEncryptionType; + tCsrEncryptionList mcEncryptionInfo; + eCsrCBChoice CBMode; //up, down or auto + tANI_U8 operationChannel; + tANI_U16 beaconInterval; + tCsrKeys Keys; + // meaningless on connect. It's an OUT param from CSR's point of view + // During assoc response carries the ACM bit-mask i.e. what + // ACs have ACM=1 (if any), + // (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) + tANI_U8 acm_mask; + tCsrRoamModifyProfileFields modifyProfileFields; + tANI_U32 nAddIEAssocLength; //The byte count in the pAddIE for assoc + tANI_U8 *pAddIEAssoc; //If not null, it has the IE byte stream for additional IE, which can be WSC IE and/or P2P IE + + tSirBssDescription *pBssDesc; + tANI_BOOLEAN qap; //AP supports QoS + tANI_BOOLEAN qosConnection; //A connection is QoS enabled +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsrMobilityDomainInfo MDID; +#endif + +#ifdef FEATURE_WLAN_ESE + tCsrEseCckmInfo eseCckmInfo; + tANI_BOOLEAN isESEAssoc; +#endif + tANI_U32 dot11Mode; + +#ifdef WLAN_FEATURE_11W + /* Management Frame Protection */ + tANI_BOOLEAN MFPEnabled; + tANI_U8 MFPRequired; + tANI_U8 MFPCapable; +#endif + +}tCsrRoamConnectedProfile; + + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct tagCsr11rConfigParams +{ + tANI_BOOLEAN IsFTResourceReqSupported; +} tCsr11rConfigParams; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +typedef struct tagCsrNeighborRoamConfigParams +{ + + tANI_U32 nNeighborScanTimerPeriod; + tANI_U8 nNeighborLookupRssiThreshold; + tANI_U8 nNeighborReassocRssiThreshold; + tANI_U16 nNeighborScanMinChanTime; + tANI_U16 nNeighborScanMaxChanTime; + sCsrChannel neighborScanChanList; + tANI_U8 nMaxNeighborRetries; + tANI_U16 nNeighborResultsRefreshPeriod; + tANI_U16 nEmptyScanRefreshPeriod; + tANI_U8 nNeighborInitialForcedRoamTo5GhEnable; + tANI_U8 nWeakZoneRssiThresholdForRoam; +}tCsrNeighborRoamConfigParams; +#endif + +typedef struct tagCsrConfigParam +{ + tANI_U32 FragmentationThreshold; + tANI_U32 channelBondingMode24GHz; // keep this tANI_U32. This gets converted to ePhyChannelBondState + tANI_U32 channelBondingMode5GHz; // in csrChangeDefaultConfigParam using convertCBIniValueToPhyCBState + eCsrPhyMode phyMode; + eCsrBand eBand; + tANI_U32 RTSThreshold; + tANI_U32 HeartbeatThresh50; + tANI_U32 HeartbeatThresh24; + eCsrCBChoice cbChoice; + eCsrBand bandCapability; //indicate hw capability + tANI_U32 bgScanInterval; + tANI_U16 TxRate; + eCsrRoamWmmUserModeType WMMSupportMode; + tANI_BOOLEAN Is11eSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabledOriginal; + tANI_BOOLEAN Is11hSupportEnabled; + tANI_BOOLEAN shortSlotTime; + tANI_BOOLEAN ProprietaryRatesEnabled; + tANI_U8 AdHocChannel24; + tANI_U8 AdHocChannel5G; + tANI_U32 impsSleepTime; //in units of seconds + tANI_U32 nScanResultAgeCount; //this number minus one is the number of times a scan doesn't find it before it is removed + tANI_U32 scanAgeTimeNCNPS; //scan result aging time threshold when Not-Connect-No-Power-Save, in seconds + tANI_U32 scanAgeTimeNCPS; //scan result aging time threshold when Not-Connect-Power-Save, in seconds + tANI_U32 scanAgeTimeCNPS; //scan result aging time threshold when Connect-No-Power-Save, in seconds, + tANI_U32 scanAgeTimeCPS; //scan result aging time threshold when Connect-Power-Savein seconds + tANI_U32 nRoamingTime; //In seconds, CSR will try this long before gives up. 0 means no roaming + tANI_U8 bCatRssiOffset; //to set the RSSI difference for each category + tANI_U8 fEnableMCCMode; //to set MCC Enable/Disable mode + tANI_U8 fAllowMCCGODiffBI; //to allow MCC GO different B.I than STA's. NOTE: make sure if RIVA firmware can handle this combination before enabling this + //at the moment, this flag is provided only to pass Wi-Fi Cert. 5.1.12 + tCsr11dinfo Csr11dinfo; + //Whether to limit the channels to the ones set in Csr11dInfo. If true, the opertaional + //channels are limited to the default channel list. It is an "AND" operation between the + //default channels and the channels in the 802.11d IE. + tANI_BOOLEAN fEnforce11dChannels; + //Country Code Priority + //0 = 802.11D > Country IOCTL > NV + //1 = Country IOCTL > 802.11D > NV + tANI_BOOLEAN fSupplicantCountryCodeHasPriority; + //When true, AP with unknown country code won't be see. + //"Unknown country code" means either Ap doesn't have 11d IE or we cannot + //find a domain for the country code in its 11d IE. + tANI_BOOLEAN fEnforceCountryCodeMatch; + //When true, only APs in the default domain can be seen. If the Ap has "unknown country + //code", or the domain of the country code doesn't match the default domain, the Ap is + //not acceptable. + tANI_BOOLEAN fEnforceDefaultDomain; + + tANI_U16 vccRssiThreshold; + tANI_U32 vccUlMacLossThreshold; + + tANI_U32 nPassiveMinChnTime; //in units of milliseconds + tANI_U32 nPassiveMaxChnTime; //in units of milliseconds + tANI_U32 nActiveMinChnTime; //in units of milliseconds + tANI_U32 nActiveMaxChnTime; //in units of milliseconds + + tANI_U32 nInitialDwellTime; //in units of milliseconds + + uint32_t min_chntime_btc_esco; //in units of milliseconds + uint32_t max_chntime_btc_esco; //in units of milliseconds + uint32_t min_chntime_btc_sco; + uint32_t max_chntime_btc_sco; + tANI_U32 disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + tANI_U32 nPassiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nPassiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nRestTimeConc; //in units of milliseconds + tANI_U8 nNumStaChanCombinedConc; //number of channels combined for + //STA in each split scan operation + tANI_U8 nNumP2PChanCombinedConc; //number of channels combined for + //P2P in each split scan operation +#endif + + tANI_BOOLEAN IsIdleScanEnabled; + //in dBm, the maximum TX power + //The actual TX power is the lesser of this value and 11d. + //If 11d is disable, the lesser of this and default setting. + tANI_U8 nTxPowerCap; + tANI_U32 statsReqPeriodicity; //stats request frequency from PE while in full power + tANI_U32 statsReqPeriodicityInPS;//stats request frequency from PE while in power save +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsr11rConfigParams csr11rConfig; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif +#ifdef FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; + tANI_U8 MAWCEnabled; +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 isFastTransitionEnabled; + tANI_U8 RoamRssiDiff; + tANI_U8 nImmediateRoamRssiDiff; + tANI_BOOLEAN isWESModeEnabled; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tCsrNeighborRoamConfigParams neighborRoamConfig; +#endif + + /* Instead of Reassoc, send ADDTS/DELTS even when ACM is off for that AC + * This is mandated by WMM-AC certification */ + tANI_BOOLEAN addTSWhenACMIsOff; + + + /*channelPowerInfoList24 has been seen corrupted. Set this flag to true trying to + * detect when it happens. Adding this into code because we can't reproduce it easily. + * We don't know when it happens. */ + tANI_BOOLEAN fValidateList; + + /*Customer wants to start with an active scan based on the default country code. + * This optimization will minimize the driver load to association time. + * Based on this flag we will bypass the initial passive scan needed for 11d + * to determine the country code & domain */ + tANI_BOOLEAN fEnableBypass11d; + + /*Customer wants to optimize the scan time. Avoiding scans(passive) on DFS + * channels while swipping through both bands can save some time + * (apprx 1.3 sec) */ + tANI_U8 fEnableDFSChnlScan; + + //To enable/disable scanning 2.4Ghz channels twice on a single scan request from HDD + tANI_BOOLEAN fScanTwice; +#ifdef WLAN_FEATURE_11AC + tANI_U32 nVhtChannelWidth; + tANI_U8 enableTxBF; + tANI_U8 txBFCsnValue; + tANI_BOOLEAN enableVhtFor24GHz; + tANI_U8 enableMuBformee; +#endif + + /* + * To enable/disable scanning only 2.4Ghz channels on first scan + */ + tANI_BOOLEAN fFirstScanOnly2GChnl; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_BOOLEAN nRoamPrefer5GHz; + tANI_BOOLEAN nRoamIntraBand; + tANI_U8 nProbes; + tANI_U16 nRoamScanHomeAwayTime; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tANI_BOOLEAN isRoamOffloadScanEnabled; + tANI_BOOLEAN bFastRoamInConIniFeatureEnabled; + v_BOOL_t isPERRoamEnabled; + v_BOOL_t isPERRoamCCAEnabled; + v_S15_t PERRoamFullScanThreshold; + v_S15_t PERMinRssiThresholdForRoam; + v_U32_t rateUpThreshold; + v_U32_t rateDownThreshold; + v_U32_t waitPeriodForNextPERScan; + v_U32_t PERtimerThreshold; + v_U32_t PERroamTriggerPercent; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + tANI_BOOLEAN enable_lfr_mbb; +#endif + +#endif + + tANI_BOOLEAN ignorePeerErpInfo; + tANI_U8 scanCfgAgingTime; + + tANI_U8 enableTxLdpc; + + tANI_U8 isAmsduSupportInAMPDU; + tANI_U8 nSelect5GHzMargin; + + tANI_U8 isCoalesingInIBSSAllowed; + tANI_U8 allowDFSChannelRoam; + tANI_BOOLEAN initialScanSkipDFSCh; + tANI_BOOLEAN sendDeauthBeforeCon; + + eCsrBand scanBandPreference; +#ifdef WLAN_FEATURE_AP_HT40_24G + tANI_BOOLEAN apHT40_24GEnabled; + tANI_U32 channelBondingAPMode24GHz; // Use for SAP/P2P GO 2.4GHz channel Bonding +#endif + tANI_U32 nOBSSScanWidthTriggerInterval; + tANI_U8 roamDelayStatsEnabled; + tANI_BOOLEAN ignorePeerHTopMode; + tANI_BOOLEAN disableP2PMacSpoofing; + tANI_BOOLEAN enableFatalEvent; + tANI_U8 max_chan_for_dwell_time_cfg; + uint32_t enable_edca_params; + uint32_t edca_vo_cwmin; + uint32_t edca_vi_cwmin; + uint32_t edca_bk_cwmin; + uint32_t edca_be_cwmin; + uint32_t edca_vo_cwmax; + uint32_t edca_vi_cwmax; + uint32_t edca_bk_cwmax; + uint32_t edca_be_cwmax; + uint32_t edca_vo_aifs; + uint32_t edca_vi_aifs; + uint32_t edca_bk_aifs; + uint32_t edca_be_aifs; + tANI_BOOLEAN disable_scan_during_sco; + uint32_t sta_auth_retries_for_code17; +}tCsrConfigParam; + +//Tush +typedef struct tagCsrUpdateConfigParam +{ + tCsr11dinfo Csr11dinfo; +}tCsrUpdateConfigParam; + +typedef struct tagCsrRoamInfo +{ + tCsrRoamProfile *pProfile; //may be NULL + tSirBssDescription *pBssDesc; //May be NULL + tANI_U32 nBeaconLength; //the length, in bytes, of the beacon frame, can be 0 + tANI_U32 nAssocReqLength; //the length, in bytes, of the assoc req frame, can be 0 + tANI_U32 nAssocRspLength; //The length, in bytes, of the assoc rsp frame, can be 0 + tANI_U32 nFrameLength; + tANI_U8 frameType; + tANI_U8 *pbFrames; //Point to a buffer contain the beacon, assoc req, assoc rsp frame, in that order + //user needs to use nBeaconLength, nAssocReqLength, nAssocRspLength to desice where + //each frame starts and ends. + tANI_BOOLEAN fReassocReq; //set to true if for re-association + tANI_BOOLEAN fReassocRsp; //set to true if for re-association + tCsrBssid bssid; + //Only valid in IBSS + //this is the peers MAC address for eCSR_ROAM_RESULT_IBSS_NEW_PEER or PEER_DEPARTED + tCsrBssid peerMac; + tSirResultCodes statusCode; + tANI_U32 reasonCode; //this could be our own defined or sent from the other BSS(per 802.11 spec) + tANI_U8 staId; // Peer stationId when connected + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU signature*/ + tANI_U8 ucastSig; + + /*Broadcast DPU signature*/ + tANI_U8 bcastSig; + + tANI_BOOLEAN fAuthRequired; //FALSE means auth needed from supplicant. TRUE means authenticated(static WEP, open) + tANI_U8 sessionId; + tANI_U8 rsnIELen; + tANI_U8 *prsnIE; + + tANI_U8 addIELen; + tANI_U8 *paddIE; + + union + { + tSirMicFailureInfo *pMICFailureInfo; + tCsrRoamConnectedProfile *pConnectedProfile; + tSirWPSPBCProbeReq *pWPSPBCProbeReq; + tSirLostLinkParamsInfo *pLostLinkParams; + } u; + + tANI_BOOLEAN wmmEnabledSta; //set to true if WMM enabled STA +#ifdef WLAN_FEATURE_AP_HT40_24G + tANI_BOOLEAN HT40MHzIntoEnabledSta; //set to true if 40 MHz Intolerant enabled STA +#endif + tANI_U32 dtimPeriod; + +#ifdef FEATURE_WLAN_ESE + tANI_BOOLEAN isESEAssoc; +#ifdef FEATURE_WLAN_ESE_UPLOAD + tSirTsmIE tsmIe; + tANI_U32 timestamp[2]; + tANI_U16 tsmRoamDelay; + tSirEseBcnReportRsp *pEseBcnReportRsp; +#endif /* FEATURE_WLAN_ESE_UPLOAD */ +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_BOOLEAN is11rAssoc; +#endif + + void* pRemainCtx; + tANI_U32 rxChan; + +#ifdef FEATURE_WLAN_TDLS + tANI_U8 staType; +#endif + + // Required for indicating the frames to upper layer + tANI_U32 beaconLength; + tANI_U8* beaconPtr; + tANI_U32 assocReqLength; + tANI_U8* assocReqPtr; + + tANI_S8 rxRssi; + tANI_U32 maxRateFlags; +#ifdef WLAN_FEATURE_AP_HT40_24G + tpSirHT2040CoexInfoInd pSmeHT2040CoexInfoInd; +#endif + tDot11fIEHTCaps ht_caps; + tDot11fIEVHTCaps vht_caps; + tDot11fIEhs20vendor_ie hs20vendor_ie; + tDot11fIEVHTOperation vht_operation; + tDot11fIEHTInfo ht_operation; + bool reassoc; +}tCsrRoamInfo; + +typedef struct tagCsrFreqScanInfo +{ + tANI_U32 nStartFreq; //in unit of MHz + tANI_U32 nEndFreq; //in unit of MHz + tSirScanType scanType; +}tCsrFreqScanInfo; + + +typedef struct sSirSmeAssocIndToUpperLayerCnf +{ + tANI_U16 messageType; // eWNI_SME_ASSOC_CNF + tANI_U16 length; + tANI_U8 sessionId; + tSirResultCodes statusCode; + tSirMacAddr bssId; // Self BSSID + tSirMacAddr peerMacAddr; + tANI_U16 aid; + tSirMacAddr alternateBssId; + tANI_U8 alternateChannelId; + tANI_U8 wmmEnabledSta; //set to true if WMM enabled STA + tSirRSNie rsnIE; // RSN IE received from peer + tSirAddie addIE; // Additional IE received from peer, which can be WSC and/or P2P IE + tANI_U8 reassocReq; //set to true if reassoc +#ifdef WLAN_FEATURE_AP_HT40_24G + tANI_U8 HT40MHzIntoEnabledSta; //set to true if 40 MHz Intolerant enabled STA +#endif + uint32_t rate_flags; +} tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf; + +typedef struct tagCsrSummaryStatsInfo +{ + tANI_U32 retry_cnt[4]; + tANI_U32 multiple_retry_cnt[4]; + tANI_U32 tx_frm_cnt[4]; + //tANI_U32 num_rx_frm_crc_err; same as rx_error_cnt + //tANI_U32 num_rx_frm_crc_ok; same as rx_frm_cnt + tANI_U32 rx_frm_cnt; + tANI_U32 frm_dup_cnt; + tANI_U32 fail_cnt[4]; + tANI_U32 rts_fail_cnt; + tANI_U32 ack_fail_cnt; + tANI_U32 rts_succ_cnt; + tANI_U32 rx_discard_cnt; + tANI_U32 rx_error_cnt; + tANI_U32 tx_byte_cnt; + +}tCsrSummaryStatsInfo; + +typedef struct tagCsrGlobalClassAStatsInfo +{ + tANI_U32 rx_frag_cnt; + tANI_U32 promiscuous_rx_frag_cnt; + //tANI_U32 rx_fcs_err; + tANI_U32 rx_input_sensitivity; + tANI_U32 max_pwr; + //tANI_U32 default_pwr; + tANI_U32 sync_fail_cnt; + tANI_U32 tx_rate; + //mcs index for HT20 and HT40 rates + tANI_U32 mcs_index; + //to defferentiate between HT20 and HT40 rates;short and long guard interval + tANI_U32 tx_rate_flags; + +}tCsrGlobalClassAStatsInfo; + +typedef struct tagCsrGlobalClassBStatsInfo +{ + tANI_U32 uc_rx_wep_unencrypted_frm_cnt; + tANI_U32 uc_rx_mic_fail_cnt; + tANI_U32 uc_tkip_icv_err; + tANI_U32 uc_aes_ccmp_format_err; + tANI_U32 uc_aes_ccmp_replay_cnt; + tANI_U32 uc_aes_ccmp_decrpt_err; + tANI_U32 uc_wep_undecryptable_cnt; + tANI_U32 uc_wep_icv_err; + tANI_U32 uc_rx_decrypt_succ_cnt; + tANI_U32 uc_rx_decrypt_fail_cnt; + tANI_U32 mcbc_rx_wep_unencrypted_frm_cnt; + tANI_U32 mcbc_rx_mic_fail_cnt; + tANI_U32 mcbc_tkip_icv_err; + tANI_U32 mcbc_aes_ccmp_format_err; + tANI_U32 mcbc_aes_ccmp_replay_cnt; + tANI_U32 mcbc_aes_ccmp_decrpt_err; + tANI_U32 mcbc_wep_undecryptable_cnt; + tANI_U32 mcbc_wep_icv_err; + tANI_U32 mcbc_rx_decrypt_succ_cnt; + tANI_U32 mcbc_rx_decrypt_fail_cnt; + +}tCsrGlobalClassBStatsInfo; + +typedef struct tagCsrGlobalClassCStatsInfo +{ + tANI_U32 rx_amsdu_cnt; + tANI_U32 rx_ampdu_cnt; + tANI_U32 tx_20_frm_cnt; + tANI_U32 rx_20_frm_cnt; + tANI_U32 rx_mpdu_in_ampdu_cnt; + tANI_U32 ampdu_delimiter_crc_err; + +}tCsrGlobalClassCStatsInfo; + +typedef struct tagCsrGlobalClassDStatsInfo +{ + tANI_U32 tx_uc_frm_cnt; + tANI_U32 tx_mc_frm_cnt; + tANI_U32 tx_bc_frm_cnt; + tANI_U32 rx_uc_frm_cnt; + tANI_U32 rx_mc_frm_cnt; + tANI_U32 rx_bc_frm_cnt; + tANI_U32 tx_uc_byte_cnt[4]; + tANI_U32 tx_mc_byte_cnt; + tANI_U32 tx_bc_byte_cnt; + tANI_U32 rx_uc_byte_cnt[4]; + tANI_U32 rx_mc_byte_cnt; + tANI_U32 rx_bc_byte_cnt; + tANI_U32 rx_byte_cnt; + tANI_U32 num_rx_bytes_crc_ok; + tANI_U32 rx_rate; + +}tCsrGlobalClassDStatsInfo; + +typedef struct tagCsrPerStaStatsInfo +{ + tANI_U32 tx_frag_cnt[4]; + tANI_U32 tx_ampdu_cnt; + tANI_U32 tx_mpdu_in_ampdu_cnt; +} tCsrPerStaStatsInfo; + +typedef struct tagCsrRoamSetKey +{ + eCsrEncryptionType encType; + tAniKeyDirection keyDirection; //Tx, Rx or Tx-and-Rx + tCsrBssid peerMac; //Peers MAC address. ALL 1's for group key + tANI_U8 paeRole; //0 for supplicant + tANI_U8 keyId; // Kye index + tANI_U16 keyLength; //Number of bytes containing the key in pKey + tANI_U8 Key[CSR_MAX_KEY_LEN]; + tANI_U8 keyRsc[CSR_MAX_RSC_LEN]; +} tCsrRoamSetKey; + +typedef struct tagCsrRoamRemoveKey +{ + eCsrEncryptionType encType; + tCsrBssid peerMac; //Peers MAC address. ALL 1's for group key + tANI_U8 keyId; //key index +} tCsrRoamRemoveKey; + +#ifdef FEATURE_WLAN_TDLS + +typedef struct tagCsrLinkEstablishParams +{ + tSirMacAddr peerMac; + tANI_U8 uapsdQueues; + tANI_U8 qos; + tANI_U8 maxSp; + tANI_U8 isBufSta; + tANI_U8 isOffChannelSupported; + tANI_U8 isResponder; + tANI_U8 supportedChannelsLen; + tANI_U8 supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supportedOperClassesLen; + tANI_U8 supportedOperClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +}tCsrTdlsLinkEstablishParams; + +typedef struct tagCsrTdlsSendMgmt +{ + tSirMacAddr peerMac; + tANI_U8 frameType; + tANI_U8 dialog; + tANI_U16 statusCode; + tANI_U8 responder; + tANI_U32 peerCapability; + tANI_U8 *buf; + tANI_U8 len; + +}tCsrTdlsSendMgmt; + +#endif + +typedef void * tScanResultHandle; + +#define CSR_INVALID_SCANRESULT_HANDLE (NULL) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +typedef struct tagCsrHandoffRequest +{ + tCsrBssid bssid; + tANI_U8 channel; + /* To check if its a REASSOC or a FASTREASSOC IOCTL */ + tANI_U8 src; +}tCsrHandoffRequest; +#endif + +typedef enum { + REASSOC = 0, + FASTREASSOC = 1, + CONNECT_CMD_USERSPACE = 2, +} handoff_src; + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +typedef struct tagCsrEseBeaconReqParams +{ + tANI_U16 measurementToken; + tANI_U8 channel; + tANI_U8 scanMode; + tANI_U16 measurementDuration; +} tCsrEseBeaconReqParams, *tpCsrEseBeaconReqParams; + +typedef struct tagCsrEseBeaconReq +{ + tANI_U8 numBcnReqIe; + tCsrEseBeaconReqParams bcnReq[SIR_ESE_MAX_MEAS_IE_REQS]; +} tCsrEseBeaconReq, *tpCsrEseBeaconReq; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +struct tagCsrDelStaParams +{ + tCsrBssid peerMacAddr; + u16 reason_code; + u8 subtype; +}; + + +/** + * struct csr_set_tx_max_pwr_per_band - Req params to + * set max tx power per band + * @band: band for which power to be set + * @power: power to set in dB + */ +struct csr_set_tx_max_pwr_per_band { + eCsrBand band; + tPowerdBm power; +}; + +////////////////////////////////////////////Common SCAN starts + +//void *p2 -- the second context pass in for the caller +//***what if callback is called before requester gets the scanId?? +typedef eHalStatus (*csrScanCompleteCallback)(tHalHandle, void *p2, tANI_U32 scanID, eCsrScanStatus status); + + + +///////////////////////////////////////////Common Roam starts + +//pContext is the pContext passed in with the roam request +//pParam is a pointer to a tCsrRoamInfo, see definition of eRoamCmdStatus and +// eRoamCmdResult for detail valid members. It may be NULL +//roamId is to identify the callback related roam request. 0 means unsolicit +//roamStatus is a flag indicating the status of the callback +//roamResult is the result +typedef eHalStatus (*csrRoamCompleteCallback)(void *pContext, tCsrRoamInfo *pParam, tANI_U32 roamId, + eRoamCmdStatus roamStatus, eCsrRoamResult roamResult); + +typedef eHalStatus (*csrRoamSessionCloseCallback)(void *pContext); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetNumPMKIDCache + \brief return number of PMKID cache entries + \return tANI_U32 - the number of PMKID cache entries + -------------------------------------------------------------------------------*/ +//tANI_U32 csrRoamGetNumPMKIDCache(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetPMKIDCache + \brief return PMKID cache from CSR + \param pNum - caller allocated memory that has the space of the number of pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +//eHalStatus csrRoamGetPMKIDCache(tHalHandle hHal, tANI_U32 *pNum, tPmkidCacheInfo *pPmkidCache); + +//pProfile - pointer to tCsrRoamProfile +#define CSR_IS_START_IBSS(pProfile) (eCSR_BSS_TYPE_START_IBSS == (pProfile)->BSSType) +#define CSR_IS_JOIN_TO_IBSS(pProfile) (eCSR_BSS_TYPE_IBSS == (pProfile)->BSSType) +#define CSR_IS_IBSS(pProfile) ( CSR_IS_START_IBSS(pProfile) || CSR_IS_JOIN_TO_IBSS(pProfile) ) +#define CSR_IS_INFRASTRUCTURE(pProfile) (eCSR_BSS_TYPE_INFRASTRUCTURE == (pProfile)->BSSType) +#define CSR_IS_ANY_BSS_TYPE(pProfile) (eCSR_BSS_TYPE_ANY == (pProfile)->BSSType) +#define CSR_IS_WDS_AP( pProfile ) ( eCSR_BSS_TYPE_WDS_AP == (pProfile)->BSSType ) +#define CSR_IS_WDS_STA( pProfile ) ( eCSR_BSS_TYPE_WDS_STA == (pProfile)->BSSType ) +#define CSR_IS_WDS( pProfile ) ( CSR_IS_WDS_AP( pProfile ) || CSR_IS_WDS_STA( pProfile ) ) +#define CSR_IS_INFRA_AP( pProfile ) ( eCSR_BSS_TYPE_INFRA_AP == (pProfile)->BSSType ) + +//pProfile - pointer to tCsrRoamConnectedProfile +#define CSR_IS_CONN_INFRA_AP( pProfile ) ( eCSR_BSS_TYPE_INFRA_AP == (pProfile)->BSSType ) +#define CSR_IS_CONN_WDS_AP( pProfile ) ( eCSR_BSS_TYPE_WDS_AP == (pProfile)->BSSType ) +#define CSR_IS_CONN_WDS_STA( pProfile ) ( eCSR_BSS_TYPE_WDS_STA == (pProfile)->BSSType ) +#define CSR_IS_CONN_WDS( pProfile ) ( CSR_IS_WDS_AP( pProfile ) || CSR_IS_WDS_STA( pProfile ) ) + + + +///////////////////////////////////////////Common Roam ends + + +/* --------------------------------------------------------------------------- + \fn csrSetChannels + \brief HDD calls this function to change some global settings. + caller must set the all fields or call csrGetConfigParam to prefill the fields. + \param pParam - caller allocated memory + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus csrSetChannels(tHalHandle hHal, tCsrConfigParam *pParam ); + +eHalStatus csrSetRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode); + + +//enum to string conversion for debug output +const char * get_eRoamCmdStatus_str(eRoamCmdStatus val); +const char * get_eCsrRoamResult_str(eCsrRoamResult val); +/* --------------------------------------------------------------------------- + \fn csrSetPhyMode + \brief HDD calls this function to set the phyMode. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \param phyMode - indicate the phyMode needs to set to. The value has to be either 0, or some bits set. + See eCsrPhyMode for definition + \param eBand - specify the operational band (2.4, 5 or both) + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrSetPhyMode(tHalHandle hHal, tANI_U32 phyMode, eCsrBand eBand, tANI_BOOLEAN *pfRestartNeeded); + +void csrDumpInit(tHalHandle hHal); + + +/*--------------------------------------------------------------------------- + This is the type for a link quality callback to be registered with SME + for indications + Once the link quality has been indicated, subsequently, link indications are + posted each time there is a CHANGE in link quality. + *** If there is no change in link, there will be no indication *** + + The indications may be based on one or more criteria internal to SME + such as RSSI and PER. + + \param ind - Indication being posted + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void (* csrRoamLinkQualityIndCallback) + (eCsrRoamLinkQualityInd ind, void *pContext); + + +/*--------------------------------------------------------------------------- + This is the type for a statistics callback to be registered with SME + for stats reporting + + Since the client requesting for the stats already know which class/type of + stats it asked for, the callback will carry them in the rsp buffer + (void * stats) whose size will be same as the size of requested stats & + will be exactly in the same order requested in the stats mask from LSB to MSB + + \param stats - stats rsp buffer sent back with the report + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void ( *tCsrStatsCallback) (void * stats, void *pContext); + +/*--------------------------------------------------------------------------- + This is the type for a rssi callback to be registered with SME + for getting rssi + + \param rssi - rssi + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ + +typedef void ( *tCsrRssiCallback) (v_S7_t rssi, tANI_U32 staId, void *pContext); + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/*--------------------------------------------------------------------------- + This is the type for a tsm stats callback to be registered with SME + for getting tsm stats + + \param tsmMetrics - tsmMetrics + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ + +typedef void ( *tCsrTsmStatsCallback) (tAniTrafStrmMetrics tsmMetrics, tANI_U32 staId, void *pContext); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/*--------------------------------------------------------------------------- + This is the type for a snr callback to be registered with SME + for getting snr + + \param snr + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void (*tCsrSnrCallback) (v_S7_t snr, tANI_U32 staId, void *pContext); + +/*--------------------------------------------------------------------------- + This is the type for a get current antenna callback to be registered with SME + for getting cuurently used antenna index + + \param antennaId to be filled by firmware. + \param pContext - any user data given at callback registration. + \return None + +---------------------------------------------------------------------------*/ +typedef void ( *tCsrAntennaIndexCallback) (int antennaId, void *pContext); + + +#ifdef WLAN_FEATURE_VOWIFI_11R +eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tpSirBssDescription pBssDescription); +#endif + +/*--------------------------------------------------------------------------- + This is the function to change the Band configuraiton (ALL/2.4 GHZ/5 GHZ) + + \param hHal - handle to Hal context + \param eBand - band value + \return eHalStatus + +---------------------------------------------------------------------------*/ +eHalStatus csrSetBand(tHalHandle hHal, eCsrBand eBand); + +/*--------------------------------------------------------------------------- + This is the function to get the current operating band value + \param hHal - handl to Hal context + \return eCsrband - band value + +---------------------------------------------------------------------------*/ +eCsrBand csrGetCurrentBand (tHalHandle hHal); + +#endif + diff --git a/drivers/staging/prima/CORE/SME/inc/csrInternal.h b/drivers/staging/prima/CORE/SME/inc/csrInternal.h new file mode 100644 index 000000000000..3d1fff6ac837 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/csrInternal.h @@ -0,0 +1,1517 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrInternal.h + + Define internal data structure for MAC. + ========================================================================== */ +#ifndef CSRINTERNAL_H__ +#define CSRINTERNAL_H__ + +#include "vos_status.h" +#include "vos_utils.h" + +#include "vos_lock.h" + +#include "palTimer.h" +#include "csrSupport.h" +#include "vos_nvitem.h" +#include "wlan_qct_tl.h" + +#include "csrApi.h" + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "csrNeighborRoam.h" +#endif + +#define CSR_MAX_STA (HAL_NUM_STA) + +#define CSR_SME_SCAN_FLAGS_DELETE_CACHE 0x80 + +#define CSR_TITAN_MAX_RATE_MIMO_CB 240 +#define CSR_TITAN_MAX_RATE_MIMO 126 + +//define scan return criteria. LIM should use these define as well +#define CSR_SCAN_RETURN_AFTER_ALL_CHANNELS ( 0 ) +#define CSR_SCAN_RETURN_AFTER_FIRST_MATCH ( 0x01 ) +#define CSR_SCAN_RETURN_AFTER_5_BAND_11d_FOUND ( 0x80 ) +#define CSR_SCAN_RETURN_AFTER_24_BAND_11d_FOUND ( 0x40 ) +#define CSR_SCAN_RETURN_AFTER_EITHER_BAND_11d_FOUND ( CSR_SCAN_RETURN_AFTER_5_BAND_11d_FOUND | CSR_SCAN_RETURN_AFTER_24_BAND_11d_FOUND ) +#define CSR_NUM_RSSI_CAT 15 +#define CSR_MAX_STATISTICS_REQ 10 +#define CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME 3 + +//Support for multiple session +#define CSR_SESSION_ID_INVALID 0xFF // session ID invalid +#define CSR_ROAM_SESSION_MAX 5 // No of sessions to be supported, and a + // session is for Infra, IBSS or BT-AMP + +#define CSR_IS_SESSION_VALID( pMac, sessionId ) ( ( (sessionId) < CSR_ROAM_SESSION_MAX ) \ + && ( (pMac)->roam.roamSession[(sessionId)].sessionActive ) ) +#define CSR_GET_SESSION( pMac, sessionId ) \ +( \ + (sessionId < CSR_ROAM_SESSION_MAX) ? \ + (&(pMac)->roam.roamSession[(sessionId)]) :\ + NULL \ +) + +#define CSR_MAX_NUM_COUNTRY_CODE 100 +#define CSR_IS_SELECT_5GHZ_MARGIN( pMac ) \ +( \ + (((pMac)->roam.configParam.nSelect5GHzMargin)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define CSR_IS_ROAM_PREFER_5GHZ( pMac ) \ +( \ + (((pMac)->roam.configParam.nRoamPrefer5GHz)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) +#define CSR_IS_ROAM_INTRA_BAND_ENABLED( pMac ) \ +( \ + (((pMac)->roam.configParam.nRoamIntraBand)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define CSR_IS_ROAM_SCAN_OFFLOAD_ENABLED( pMac ) \ +( \ + (((pMac)->roam.configParam.isRoamOffloadScanEnabled)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) + +#define CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED( pMac ) \ +( \ + (((pMac)->roam.configParam.bFastRoamInConIniFeatureEnabled)?eANI_BOOLEAN_TRUE:eANI_BOOLEAN_FALSE) \ +) +#endif + +//Support for "Fast roaming" (i.e., ESE, LFR, or 802.11r.) +#define CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN 15 + +typedef enum +{ + //eCSR_CFG_DOT11_MODE_BEST = 0, + eCSR_CFG_DOT11_MODE_TAURUS = 0, + eCSR_CFG_DOT11_MODE_ABG, + eCSR_CFG_DOT11_MODE_11A, + eCSR_CFG_DOT11_MODE_11B, + eCSR_CFG_DOT11_MODE_11G, + eCSR_CFG_DOT11_MODE_11N, + eCSR_CFG_DOT11_MODE_POLARIS, + eCSR_CFG_DOT11_MODE_TITAN, +#ifdef WLAN_FEATURE_11AC + eCSR_CFG_DOT11_MODE_11AC, +#endif + eCSR_CFG_DOT11_MODE_11G_ONLY, + eCSR_CFG_DOT11_MODE_11N_ONLY, +#ifdef WLAN_FEATURE_11AC + eCSR_CFG_DOT11_MODE_11AC_ONLY, +#endif + //This value can never set to CFG. It is for CSR's internal use + eCSR_CFG_DOT11_MODE_AUTO, +}eCsrCfgDot11Mode; //Used to determine what to set to the WNI_CFG_DOT11_MODE + +typedef enum etCsrRoamCommands +{ + eCsrRoamNoCommand, + eCsrRoamCommandScan, + eCsrRoamCommandRoam, + eCsrRoamCommandWmStatusChange, + eCsrRoamCommandSetKey, + eCsrRoamCommandRemoveKey, + +} eCsrRoamCommands; + +typedef enum +{ + eCsrScanOther = 1, + eCsrScanLostLink1, + eCsrScanLostLink2, + eCsrScanLostLink3, + eCsrScanLostLink4, + eCsrScan11d1, //First 11d scan + eCsrScan11d2, //First 11d scan has failed + eCsrScan11dDone, //11d scan succeeded, try the rest of the channel + eCsrScanUserRequest, + eCsrScanGetResult, + eCsrScanSetBGScanParam, //used for HO too - bg scan request in NT Handoff sub-state + eCsrScanForSsid, + eCsrScanForCapsChange, + eCsrScanBGScanAbort, + eCsrScanBGScanEnable, + eCsrScanIdleScan, + eCsrScanGetScanChnInfo, //To get the list of channels scanned + + eCsrScanBgScan, // bg scan request in NRT & RT Handoff sub-states + eCsrScanProbeBss, // directed probe on an entry from the candidate list - HO + eCsrScanAbortBgScan, //aborting a BG scan (meaning the scan is triggered by LIM timer) + eCsrScanAbortNormalScan, //aborting a normal scan (the scan is trigger by eWNI_SME_SCAN_REQ) + eCsrScanP2PFindPeer, + eCsrScanGetLfrResult, // get the LFR candidates from PE scan cache +}eCsrScanReason; + +typedef enum +{ + eCsrNoConnection, // Roaming because we have not established the initial connection. + eCsrCapsChange, // roaming because LIM reported a Capability change in the associated AP. + eCsrForcedDisassoc, // roaming becuase someone asked us to Disassoc and stay disassociated. + eCsrHddIssued, // roaming because an 802.11 request was issued to the driver. + eCsrLostLink1, // roaming because we lost link to an associated AP + eCsrLostLink2, + eCsrLostLink3, + eCsrForcedDisassocMICFailure, // roaming because we need to force a Disassoc due to MIC failure + eCsrHddIssuedReassocToSameAP, + eCsrSmeIssuedReassocToSameAP, + eCsrSmeIssuedReassocToDiffAP, + eCsrForcedDeauth, // roaming becuase someone asked us to deauth and stay disassociated. + eCsrSmeIssuedDisassocForHandoff, // will be issued by Handoff logic to disconect from current AP + eCsrSmeIssuedAssocToSimilarAP, // will be issued by Handoff logic to join a new AP with same profile + eCsrSmeIssuedIbssJoinFailure, // ibss join timer fired before any perr showed up, so shut down the network + eCsrForcedIbssLeave, + eCsrStopBss, + eCsrSmeIssuedFTReassoc, + eCsrForcedDisassocSta, + eCsrForcedDeauthSta, + eCsrPerformPreauth, + eCsrLostLink1Abort, + eCsrLostLink2Abort, + eCsrLostLink3Abort, + ecsr_mbb_perform_preauth_reassoc, +}eCsrRoamReason; + +typedef enum +{ + eCSR_ROAM_SUBSTATE_NONE = 0, + eCSR_ROAM_SUBSTATE_START_BSS_REQ, + eCSR_ROAM_SUBSTATE_JOIN_REQ, + eCSR_ROAM_SUBSTATE_REASSOC_REQ, + eCSR_ROAM_SUBSTATE_DISASSOC_REQ, + eCSR_ROAM_SUBSTATE_STOP_BSS_REQ, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, //Continue the current roam command after disconnect + eCSR_ROAM_SUBSTATE_AUTH_REQ, + eCSR_ROAM_SUBSTATE_CONFIG, + eCSR_ROAM_SUBSTATE_DEAUTH_REQ, + eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, + eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, + eCSR_ROAM_SUBSTATE_DISASSOC_FORCED, + eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, + eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF, + eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC, + eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC, + eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC, +// max is 15 unless the bitfield is expanded... +} eCsrRoamSubState; + + +typedef enum +{ + eCSR_ROAMING_STATE_STOP = 0, + eCSR_ROAMING_STATE_IDLE, + eCSR_ROAMING_STATE_SCANNING, + eCSR_ROAMING_STATE_JOINING, + eCSR_ROAMING_STATE_JOINED, +}eCsrRoamState; + + +typedef enum +{ + eCsrContinueRoaming, + eCsrStopRoaming, + eCsrStartIbss, + eCsrStartIbssSameIbss, + eCsrReassocToSelfNoCapChange, + eCsrStopRoamingDueToConcurrency, + +}eCsrJoinState; + +typedef enum +{ + eCsrNotRoaming, + eCsrLostlinkRoamingDisassoc, + eCsrLostlinkRoamingDeauth, + eCsrDynamicRoaming, + eCsrReassocRoaming, +}eCsrRoamingReason; + +typedef enum +{ + eCsrDisassociated, + eCsrDeauthenticated + +}eCsrRoamWmStatusChangeTypes; + +typedef enum +{ + eCsrSummaryStats = 0, + eCsrGlobalClassAStats, + eCsrGlobalClassBStats, + eCsrGlobalClassCStats, + eCsrGlobalClassDStats, + eCsrPerStaStats, + eCsrPerPktStats, + eCsrMaxStats +}eCsrRoamStatsClassTypes; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +typedef enum +{ + eCSR_WLAN_STATUS_CONNECT =0, + eCSR_WLAN_STATUS_DISCONNECT + +}eCsrDiagWlanStatusEventSubtype; + +typedef enum +{ + eCSR_REASON_UNSPECIFIED = 0, + eCSR_REASON_USER_REQUESTED, + eCSR_REASON_MIC_ERROR, + eCSR_REASON_DISASSOC, + eCSR_REASON_DEAUTH, + eCSR_REASON_HANDOFF, + +}eCsrDiagWlanStatusEventReason; + +typedef enum +{ + eCSR_WLAN_HANDOFF_EVENT =0, + +}eCsrDiagWlanHandoffEventSubtype; + +typedef enum +{ + eCSR_WLAN_VCC_EVENT =0, + +}eCsrDiagWlanVccEventSubtype; + +#endif //FEATURE_WLAN_DIAG_SUPPORT + +typedef struct tagCsrChannel +{ + tANI_U8 numChannels; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tCsrChannel; + +typedef struct tagScanProfile +{ + tANI_U32 minChnTime; + tANI_U32 maxChnTime; + tANI_U32 restTime; //This is ignored if not associated + tANI_U32 numOfChannels; + tANI_U8 *pChannelList; + tSirScanType scanType; //active or passive + eCsrRoamBssType bssType; //BSS or IBSS + tANI_U8 ssid[WNI_CFG_SSID_LEN]; + tANI_U8 bReturnAfter1stMatch; + tANI_U8 fUniqueResult; + tANI_U8 freshScan; + tCsrBssid bssid; +}tScanProfile; + +typedef struct tagBssConfigParam +{ + eCsrMediaAccessType qosType; + tSirMacSSid SSID; + tANI_U32 uRTSThresh; + tANI_U32 uDeferThresh; // + eCsrCfgDot11Mode uCfgDot11Mode; + eCsrBand eBand; + tANI_U8 standardRate[CSR_DOT11_SUPPORTED_RATES_MAX]; + tANI_U8 extendedRate[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX]; + eCsrExposedTxRate txRate; + tAniAuthType authType; + eCsrEncryptionType encType; + tANI_U32 uShortSlotTime; + tANI_U32 uHTSupport; //High throughput + tANI_U32 uPowerLimit; + tANI_U32 uHeartBeatThresh; + tANI_U32 uJoinTimeOut; + tSirMacCapabilityInfo BssCap; + tANI_BOOLEAN f11hSupport; + ePhyChanBondState cbMode; +}tBssConfigParam; + + +typedef struct tagCsrRoamStartBssParams +{ + tSirMacSSid ssId; + tCsrBssid bssid; //this is the BSSID for the party we want to join (only use for IBSS or WDS) + tSirNwType sirNwType; + ePhyChanBondState cbMode; + tSirMacRateSet operationalRateSet; + tSirMacRateSet extendedRateSet; + tANI_U8 operationChn; + eCsrCfgDot11Mode uCfgDot11Mode; + tANI_U8 privacy; + tANI_BOOLEAN fwdWPSPBCProbeReq; + tANI_BOOLEAN protEnabled; + tANI_BOOLEAN obssProtEnabled; + tAniAuthType authType; + tANI_U16 beaconInterval; //If this is 0, SME will fill in for caller. + tANI_U16 ht_protection; + tANI_U32 dtimPeriod; + tANI_U8 ApUapsdEnable; + tANI_U8 ssidHidden; + tANI_U8 wps_state; + tVOS_CON_MODE bssPersona; + tANI_U16 nRSNIELength; //The byte count in the pRSNIE, if 0, pRSNIE is ignored. + tANI_U8 *pRSNIE; //If not null, it has the IE byte stream for RSN + tANI_BOOLEAN updatebeaconInterval; //Flag used to indicate update + // beaconInterval +#ifdef WLAN_FEATURE_11W + tANI_BOOLEAN mfpCapable; + tANI_BOOLEAN mfpRequired; +#endif +}tCsrRoamStartBssParams; + + +typedef struct tagScanCmd +{ + tANI_U32 scanID; + csrScanCompleteCallback callback; + void *pContext; + eCsrScanReason reason; + tCsrRoamProfile *pToRoamProfile; + tANI_U32 roamId; //this is the ID related to the pToRoamProfile + union + { + tCsrScanRequest scanRequest; + tCsrBGScanRequest bgScanRequest; + }u; + //This flag will be set while aborting the scan due to band change + eCsrAbortReason abortScanIndication; +}tScanCmd; + +typedef struct tagRoamCmd +{ + tANI_U32 roamId; + eCsrRoamReason roamReason; + tCsrRoamProfile roamProfile; + tScanResultHandle hBSSList; //BSS list fits the profile + tListElem *pRoamBssEntry; //point to the current BSS in the list that is roaming. It starts from head to tail + tSirBssDescription *pLastRoamBss; //the last BSS we try and failed + tANI_BOOLEAN fReleaseBssList; //whether to free hBSSList + tANI_BOOLEAN fReleaseProfile; //whether to free roamProfile + tANI_BOOLEAN fReassoc; //whether this command is for reassociation + tANI_BOOLEAN fUpdateCurRoamProfile; //whether pMac->roam.pCurRoamProfile needs to be updated + //this is for CSR internal used only. And it should not be assigned when creating the command + //This causes the roam command not to do anything. + tANI_BOOLEAN fReassocToSelfNoCapChange; + + tANI_BOOLEAN fStopWds; + tSirMacAddr peerMac; + tSirMacReasonCodes reason; +}tRoamCmd; + +typedef struct tagSetKeyCmd +{ + tANI_U32 roamId; + eCsrEncryptionType encType; + eCsrAuthType authType; + tAniKeyDirection keyDirection; //Tx, Rx or Tx-and-Rx + tSirMacAddr peerMac; //Peer's MAC address. ALL 1's for group key + tANI_U8 paeRole; //0 for supplicant + tANI_U8 keyId; // Kye index + tANI_U8 keyLength; //Number of bytes containing the key in pKey + tANI_U8 Key[CSR_MAX_KEY_LEN]; + tANI_U8 keyRsc[CSR_MAX_RSC_LEN]; +} tSetKeyCmd; + +typedef struct tahRemoveKeyCmd +{ + tANI_U32 roamId; + eCsrEncryptionType encType; + eCsrAuthType authType; + tSirMacAddr peerMac; //Peer's MAC address. ALL 1's for group key + tANI_U8 keyId; //key index +} tRemoveKeyCmd; + +typedef struct tagWmStatusChangeCmd +{ + eCsrRoamWmStatusChangeTypes Type; + union + { + tSirSmeDeauthInd DeauthIndMsg; + tSirSmeDisassocInd DisassocIndMsg; + }u; + +}tWmStatusChangeCmd; + + +typedef struct tagAddStaForSessionCmd +{ + //Session self mac addr + tSirMacAddr selfMacAddr; + tVOS_CON_MODE currDeviceMode; +}tAddStaForSessionCmd; + +typedef struct tagDelStaForSessionCmd +{ + //Session self mac addr + tSirMacAddr selfMacAddr; + csrRoamSessionCloseCallback callback; + void *pContext; +}tDelStaForSessionCmd; + +//This structure represents one scan request +typedef struct tagCsrCmd +{ + tListElem Link; + eCsrRoamCommands command; + tANI_U8 sessionId; // Session ID for this command + union + { + tScanCmd scanCmd; + tRoamCmd roamCmd; + tWmStatusChangeCmd wmStatusChangeCmd; + tSetKeyCmd setKeyCmd; + tRemoveKeyCmd removeKeyCmd; + tAddStaForSessionCmd addStaSessionCmd; + tDelStaForSessionCmd delStaSessionCmd; + }u; +}tCsrCmd; + +#ifdef WLAN_FEATURE_VOWIFI_11R +typedef struct tagCsr11rConfig +{ + tANI_BOOLEAN IsFTResourceReqSupported; +} tCsr11rConfig; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +typedef struct tagCsrNeighborRoamConfig +{ + tANI_U32 nNeighborScanTimerPeriod; + tANI_U8 nNeighborLookupRssiThreshold; + tANI_U8 nNeighborReassocRssiThreshold; + tANI_U16 nNeighborScanMinChanTime; + tANI_U16 nNeighborScanMaxChanTime; + sCsrChannel neighborScanChanList; + tANI_U8 nMaxNeighborRetries; + tANI_U16 nNeighborResultsRefreshPeriod; + tANI_U16 nEmptyScanRefreshPeriod; + tANI_U8 nNeighborInitialForcedRoamTo5GhEnable; + tANI_U8 nWeakZoneRssiThresholdForRoam; +}tCsrNeighborRoamConfig; +#endif + +typedef struct tagCsrConfig +{ + tANI_U32 agingCount; + tANI_U32 FragmentationThreshold; + tANI_U32 channelBondingMode24GHz; + tANI_U32 channelBondingMode5GHz; + tANI_U32 RTSThreshold; + eCsrPhyMode phyMode; + eCsrCfgDot11Mode uCfgDot11Mode; + eCsrBand eBand; + tANI_U32 HeartbeatThresh50; + tANI_U32 HeartbeatThresh24; + tANI_U32 bgScanInterval; + eCsrCBChoice cbChoice; + eCsrBand bandCapability; //indicate hw capability + eCsrRoamWmmUserModeType WMMSupportMode; + tANI_BOOLEAN Is11eSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabled; + tANI_BOOLEAN Is11dSupportEnabledOriginal; + tANI_BOOLEAN Is11hSupportEnabled; + tANI_BOOLEAN shortSlotTime; + tANI_BOOLEAN ProprietaryRatesEnabled; + tANI_BOOLEAN fenableMCCMode; + tANI_U16 TxRate; + tANI_U8 fAllowMCCGODiffBI; + tANI_U8 AdHocChannel24; + tANI_U8 AdHocChannel5G; + tANI_U32 impsSleepTime; //in units of microseconds + tANI_U32 scanAgeTimeNCNPS; //scan result aging time threshold when Not-Connect-No-Power-Save, in seconds + tANI_U32 scanAgeTimeNCPS; //scan result aging time threshold when Not-Connect-Power-Save, in seconds + tANI_U32 scanAgeTimeCNPS; //scan result aging time threshold when Connect-No-Power-Save, in seconds, + tANI_U32 scanAgeTimeCPS; //scan result aging time threshold when Connect-Power-Savein seconds + tANI_U32 BssPreferValue[CSR_NUM_RSSI_CAT]; //each RSSI category has one value + int RSSICat[CSR_NUM_RSSI_CAT]; + tANI_U8 bCatRssiOffset; //to set the RSSI difference for each category + tANI_U32 nRoamingTime; //In seconds, CSR will try this long before gives up, 0 means no roaming + //Whether to limit the channels to the ones set in Csr11dInfo. If true, the opertaional + //channels are limited to the default channel list. It is an "AND" operation between the + //default channels and the channels in the 802.11d IE. + tANI_BOOLEAN fEnforce11dChannels; + //Country Code Priority + //0 = 802.11D > Configured Country > NV + //1 = Configured Country > 802.11D > NV + tANI_BOOLEAN fSupplicantCountryCodeHasPriority; + //When true, AP with unknown country code won't be see. + //"Unknown country code" means either Ap doesn't have 11d IE or we cannot + //find a domain for the country code in its 11d IE. + tANI_BOOLEAN fEnforceCountryCodeMatch; + //When true, only APs in the default domain can be seen. If the Ap has "unknown country + //code", or the doamin of the country code doesn't match the default domain, the Ap is + //not acceptable. + tANI_BOOLEAN fEnforceDefaultDomain; + //When set, It enforece country code even if 11doriginal is true + tANI_BOOLEAN fEnforceCountryCode; + tANI_U16 vccRssiThreshold; + tANI_U32 vccUlMacLossThreshold; + + tANI_U32 nPassiveMinChnTime; //in units of milliseconds + tANI_U32 nPassiveMaxChnTime; //in units of milliseconds + tANI_U32 nActiveMinChnTime; //in units of milliseconds + tANI_U32 nActiveMaxChnTime; //in units of milliseconds + + tANI_U32 nInitialDwellTime; //in units of milliseconds + + uint32_t min_chntime_btc_esco; //in units of milliseconds + uint32_t max_chntime_btc_esco; //in units of milliseconds + uint32_t min_chntime_btc_sco; + uint32_t max_chntime_btc_sco; + tANI_U8 disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + tANI_U32 nPassiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nPassiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMinChnTimeConc; //in units of milliseconds + tANI_U32 nActiveMaxChnTimeConc; //in units of milliseconds + tANI_U32 nRestTimeConc; //in units of milliseconds + tANI_U8 nNumStaChanCombinedConc; //number of channels combined for + //Sta in each split scan operation + tANI_U8 nNumP2PChanCombinedConc; //number of channels combined for + //P2P in each split scan operation +#endif + + tANI_BOOLEAN IsIdleScanEnabled; + //in dBm, the maximum TX power + //The actual TX power is the lesser of this value and 11d. + //If 11d is disable, the lesser of this and default setting. + tANI_U8 nTxPowerCap; + tANI_U32 statsReqPeriodicity; //stats request frequency from PE while in full power + tANI_U32 statsReqPeriodicityInPS;//stats request frequency from PE while in power save + tANI_U32 dtimPeriod; + tANI_BOOLEAN ssidHidden; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tCsr11rConfig csr11rConfig; +#endif + +#ifdef FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; + tANI_U8 MAWCEnabled; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tANI_U8 isRoamOffloadScanEnabled; + tANI_BOOLEAN bFastRoamInConIniFeatureEnabled; + v_BOOL_t isPERRoamEnabled; + v_BOOL_t isPERRoamCCAEnabled; + v_S15_t PERRoamFullScanThreshold; + v_S15_t PERMinRssiThresholdForRoam; + tANI_U32 rateUpThreshold; + tANI_U32 rateDownThreshold; + tANI_U32 waitPeriodForNextPERScan; + tANI_U32 PERtimerThreshold; + tANI_U32 PERroamTriggerPercent; +#endif +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + tANI_BOOLEAN enable_lfr_mbb; +#endif + +#ifdef FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 isFastTransitionEnabled; + tANI_U8 RoamRssiDiff; + tANI_U8 nImmediateRoamRssiDiff; + tANI_BOOLEAN nRoamPrefer5GHz; + tANI_BOOLEAN nRoamIntraBand; + tANI_BOOLEAN isWESModeEnabled; + tANI_BOOLEAN nRoamScanControl; + tANI_U8 nProbes; + tANI_U16 nRoamScanHomeAwayTime; +#endif + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tCsrNeighborRoamConfig neighborRoamConfig; +#endif + + /* Instead of Reassoc, send ADDTS/DELTS even when ACM is off for that AC + * This is mandated by WMM-AC certification */ + tANI_BOOLEAN addTSWhenACMIsOff; + + tANI_BOOLEAN fValidateList; + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + tANI_BOOLEAN doBMPSWorkaround; + + //To enable/disable scanning 2.4Ghz channels twice on a single scan request from HDD + tANI_BOOLEAN fScanTwice; +#ifdef WLAN_FEATURE_11AC + tANI_U32 nVhtChannelWidth; + tANI_U8 txBFEnable; + tANI_U8 txBFCsnValue; + tANI_BOOLEAN enableVhtFor24GHz; + tANI_U8 txMuBformee; +#endif + tANI_U8 txLdpcEnable; + + /* + * Enable/Disable heartbeat offload + */ + tANI_BOOLEAN enableHeartBeatOffload; + tANI_U8 isAmsduSupportInAMPDU; + tANI_U8 nSelect5GHzMargin; + tANI_U8 isCoalesingInIBSSAllowed; + tANI_U8 allowDFSChannelRoam; + tANI_BOOLEAN initialScanSkipDFSCh; + tANI_BOOLEAN ignorePeerErpInfo; + tANI_BOOLEAN sendDeauthBeforeCon; +#ifdef WLAN_FEATURE_AP_HT40_24G + tANI_BOOLEAN apHT40_24GEnabled; + tANI_U32 channelBondingAPMode24GHz; // Use for SAP/P2P GO 2.4GHz channel Bonding +#endif + tANI_U32 nOBSSScanWidthTriggerInterval; + tANI_U8 roamDelayStatsEnabled; + tANI_BOOLEAN ignorePeerHTopMode; + tANI_BOOLEAN disableP2PMacSpoofing; + tANI_BOOLEAN enableFatalEvent; + tANI_U8 max_chan_for_dwell_time_cfg; + uint32_t enable_edca_params; + uint32_t edca_vo_cwmin; + uint32_t edca_vi_cwmin; + uint32_t edca_bk_cwmin; + uint32_t edca_be_cwmin; + uint32_t edca_vo_cwmax; + uint32_t edca_vi_cwmax; + uint32_t edca_bk_cwmax; + uint32_t edca_be_cwmax; + uint32_t edca_vo_aifs; + uint32_t edca_vi_aifs; + uint32_t edca_bk_aifs; + uint32_t edca_be_aifs; +}tCsrConfig; + +typedef struct tagCsrChannelPowerInfo +{ + tListElem link; + tANI_U8 firstChannel; + tANI_U8 numChannels; + tANI_U8 txPower; + tANI_U8 interChannelOffset; +}tCsrChannelPowerInfo; + +typedef struct tagRoamJoinStatus +{ + tSirResultCodes statusCode; + //this is set to unspecified if statusCode indicates timeout. Or it is the failed reason from the other BSS(per 802.11 spec) + tANI_U32 reasonCode; + tSirMacAddr bssId; +}tCsrRoamJoinStatus; + +typedef struct tagCsrOsChannelMask +{ + tANI_U8 numChannels; + tANI_BOOLEAN scanEnabled[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; +}tCsrOsChannelMask; + +typedef struct tagCsrVotes11d +{ + tANI_U8 votes; + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; +}tCsrVotes11d; + +struct csr_disable_scan_during_sco_timer_info +{ + struct net_device *dev; + tANI_U32 scan_id; + csrScanCompleteCallback callback; +}; + +typedef struct tagCsrScanStruct +{ + tScanProfile scanProfile; + tANI_U32 nextScanID; + tDblLinkList scanResultList; + tDblLinkList tempScanResults; + tANI_BOOLEAN fScanEnable; + tANI_BOOLEAN fFullScanIssued; + vos_timer_t hTimerGetResult; + vos_timer_t disable_scan_during_sco_timer; + struct csr_disable_scan_during_sco_timer_info + disable_scan_during_sco_timer_info; + tANI_BOOLEAN disable_scan_during_sco; +#ifdef WLAN_AP_STA_CONCURRENCY + vos_timer_t hTimerStaApConcTimer; +#endif + vos_timer_t hTimerIdleScan; + tPalTimerHandle hTimerBgScan; + //changes on every scan, it is used as a flag for whether 11d info is found on every scan + tANI_U8 channelOf11dInfo; + tANI_U8 scanResultCfgAgingTime; + //changes on every scan, a flag to tell whether conflict 11d info found on each BSS + tANI_BOOLEAN fAmbiguous11dInfoFound; + //Tush: changes on every scan, a flag to tell whether the applied 11d info present in one of the scan results + tANI_BOOLEAN fCurrent11dInfoMatch; + tANI_BOOLEAN f11dInfoReset; //to indicate whether the 11d info in CFG is reset to default + tSirScanType curScanType; + tCsrChannel baseChannels; //This are all the supported channels AND(&) to the current eBand + tCsrChannel channels11d; + tChannelListWithPower defaultPowerTable[WNI_CFG_VALID_CHANNEL_LIST_LEN]; //From NV + tChannelListWithPower defaultPowerTable40MHz[WNI_CFG_VALID_CHANNEL_LIST_LEN]; //From NV + tANI_U32 numChannelsDefault; //total channels of NV + tCsrChannel base20MHzChannels; //The channel base to work on + tCsrChannel base40MHzChannels; //center channels for 40MHz channels + tDblLinkList channelPowerInfoList24; + tDblLinkList channelPowerInfoList5G; + tANI_U32 nLastAgeTimeOut; + tANI_U32 nAgingCountDown; + tANI_U8 countryCodeDefault[WNI_CFG_COUNTRY_CODE_LEN]; //The country code from NV + tANI_U8 countryCodeCurrent[WNI_CFG_COUNTRY_CODE_LEN]; + tANI_U8 countryCode11d[WNI_CFG_COUNTRY_CODE_LEN]; + v_REGDOMAIN_t domainIdDefault; //default regulatory domain + v_REGDOMAIN_t domainIdCurrent; //current regulatory domain + tCsrBssid currentCountryBssid; // Bssid for current country code + tANI_S8 currentCountryRSSI; // RSSI for current country code + tANI_BOOLEAN f11dInfoApplied; + tANI_BOOLEAN fCancelIdleScan; + tANI_U8 countryCodeCount; + tCsrVotes11d votes11d[CSR_MAX_NUM_COUNTRY_CODE]; //counts for various advertized country codes + //in 11d IE from probe rsp or beacons of neighboring APs; + //will use the most popular one (max count) + tANI_U8 countryCodeElected[WNI_CFG_COUNTRY_CODE_LEN]; + + +#ifdef FEATURE_WLAN_WAPI +// tANI_U16 NumBkidCandidate; +// tBkidCandidateInfo BkidCandidateInfo[CSR_MAX_BKID_ALLOWED]; /* Move this as part of SessionEntry */ +#endif /* FEATURE_WLAN_WAPI */ + tANI_U8 numBGScanChannel; //number of valid channels in the bgScanChannelList + tANI_U8 bgScanChannelList[WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN]; + //the ChannelInfo member is not used in this structure. + //numBGScanChannel and bgScanChannelList are used for the BG scan channel info + tCsrBGScanRequest bgScanParams; + tANI_BOOLEAN fRestartIdleScan; + tANI_U32 nIdleScanTimeGap; //the time since last trying to trigger idle scan + tCsrOsChannelMask osScanChannelMask;//keep a track of channels to be scnned while in traffic condition + tANI_U16 nBssLimit; //the maximum number of BSS in scan cache + /*channelPowerInfoList24 has been seen corrupted. Set this flag to true trying to + * detect when it happens. Adding this into code because we can't reproduce it easily. + * We don't know when it happens. */ + tANI_BOOLEAN fValidateList; + /*Customer wants to start with an active scan based on the default country code. + * This optimization will minimize the driver load to association time. + * Based on this flag we will bypass the initial passive scan needed for 11d + * to determine the country code & domain */ + tANI_BOOLEAN fEnableBypass11d; + + /*Customer wants to optimize the scan time. Avoiding scans(passive) on DFS + * channels while swipping through both bands can save some time + * (apprx 1.3 sec) */ + tANI_U8 fEnableDFSChnlScan; + + /* + * To enable/disable scanning only 2.4Ghz channels on first scan + */ + tANI_BOOLEAN fFirstScanOnly2GChnl; + + tANI_BOOLEAN fDropScanCmd; //true means we don't accept scan commands + +#ifdef WLAN_AP_STA_CONCURRENCY + tDblLinkList scanCmdPendingList; +#endif + tCsrChannel occupiedChannels; //This includes all channels on which candidate APs are found + tANI_S8 inScanResultBestAPRssi; + + csrScanCompleteCallback callback11dScanDone; + eCsrBand scanBandPreference; //This defines the band perference for scan + bool fcc_constraint; + /* flag to defer updated chanel list */ + bool defer_update_channel_list; +}tCsrScanStruct; + + +//Save the connected information. This structure + connectedProfile +//should contain all information about the connection +typedef struct tagRoamCsrConnectedInfo +{ + tANI_U32 nBeaconLength; //the length, in bytes, of the beacon frame, can be 0 + tANI_U32 nAssocReqLength; //the length, in bytes, of the assoc req frame, can be 0 + tANI_U32 nAssocRspLength; //The length, in bytes, of the assoc rsp frame, can be 0 +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U32 nRICRspLength; //Length of the parsed RIC response IEs received in reassoc response +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U32 nTspecIeLength; +#endif + tANI_U8 *pbFrames; //Point to a buffer contain the beacon, assoc req, assoc rsp frame, in that order + //user needs to use nBeaconLength, nAssocReqLength, nAssocRspLength to desice where + //each frame starts and ends. + tANI_U8 staId; +}tCsrRoamConnectedInfo; + + +typedef struct tagCsrLinkQualityIndInfo +{ + csrRoamLinkQualityIndCallback callback; + void *context; +}tCsrLinkQualityIndInfo; + +typedef struct tagCsrPeStatsReqInfo +{ + tListElem link; /* list links */ + tANI_U32 statsMask; + tANI_U32 periodicity; + tANI_BOOLEAN rspPending; + vos_timer_t hPeStatsTimer; + tANI_BOOLEAN timerRunning; + tANI_U8 staId; + tANI_U8 numClient; + tpAniSirGlobal pMac; + /* To remember if the peStats timer is stopped successfully or not */ + tANI_BOOLEAN timerStopFailed; + +}tCsrPeStatsReqInfo; + +typedef struct tagCsrStatsClientReqInfo +{ + tListElem link; /* list links */ + eCsrStatsRequesterType requesterId; + tCsrStatsCallback callback; + tANI_U32 periodicity; + void *pContext; + tANI_U32 statsMask; + tCsrPeStatsReqInfo *pPeStaEntry; + tANI_U8 staId; + vos_timer_t timer; + tANI_BOOLEAN timerExpired; + tpAniSirGlobal pMac; // TODO: Confirm this change BTAMP +}tCsrStatsClientReqInfo; + +typedef struct tagCsrTlStatsReqInfo +{ + tANI_U32 periodicity; + tANI_BOOLEAN timerRunning; + vos_timer_t hTlStatsTimer; + tANI_U8 numClient; +}tCsrTlStatsReqInfo; + +typedef struct tagCsrRoamSession +{ + tANI_U8 sessionId; // Session ID + tANI_BOOLEAN sessionActive; // TRUE if it is used + tCsrBssid selfMacAddr; // For BT-AMP station, this serve as BSSID for self-BSS. + csrRoamCompleteCallback callback; + void *pContext; + eCsrConnectState connectState; + tCsrRoamConnectedProfile connectedProfile; + tCsrRoamConnectedInfo connectedInfo; + tCsrRoamProfile *pCurRoamProfile; + tSirBssDescription *pConnectBssDesc; + tANI_U16 NumPmkidCache; /* valid no. of pmkid in the cache */ + tANI_U16 CurCacheIndex; /* the index in pmkidcache to write next to */ + tPmkidCacheInfo PmkidCacheInfo[CSR_MAX_PMKID_ALLOWED]; + tANI_U8 cJoinAttemps; + //This may or may not have the up-to-date valid channel list + //It is used to get WNI_CFG_VALID_CHANNEL_LIST and not allocate memory all the time + tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_S32 sPendingCommands; //0 means CSR is ok to low power +#ifdef FEATURE_WLAN_WAPI + tANI_U16 NumBkidCache; + tBkidCacheInfo BkidCacheInfo[CSR_MAX_BKID_ALLOWED]; +#endif /* FEATURE_WLAN_WAPI */ + tANI_BOOLEAN fRoaming; //indicate whether CSR is roaming (either via lostlink or dynamic roaming) + //to remember some parameters needed for START_BSS. + //All member must be set every time we try to join or start an IBSS or BT-AMP + tCsrRoamStartBssParams bssParams; + tANI_U32 nWpaRsnReqIeLength; //the byte count of pWpaRsnIE; + tANI_U8 *pWpaRsnReqIE; //this contain the WPA/RSN IE in assoc request or the one sent in beacon (IBSS) + tANI_U32 nWpaRsnRspIeLength; //the byte count for pWpaRsnRspIE + tANI_U8 *pWpaRsnRspIE; //this contain the WPA/RSN IE in beacon/probe rsp +#ifdef FEATURE_WLAN_WAPI + tANI_U32 nWapiReqIeLength; //the byte count of pWapiReqIE; + tANI_U8 *pWapiReqIE; //this contain the WAPI IE in assoc request or the one sent in beacon (IBSS) + tANI_U32 nWapiRspIeLength; //the byte count for pWapiRspIE + tANI_U8 *pWapiRspIE; //this contain the WAPI IE in beacon/probe rsp +#endif /* FEATURE_WLAN_WAPI */ + tANI_U32 nAddIEScanLength; //length of addIeScan + /* This contains the additional IE in (unicast) + * probe request at the time of join + */ + tANI_U8 addIEScan[SIR_MAC_MAX_ADD_IE_LENGTH+2]; + tANI_U32 nAddIEAssocLength; //the byte count for pAddIeAssocIE + tANI_U8 *pAddIEAssoc; //this contains the additional IE in (re) assoc request + + tANI_TIMESTAMP roamingStartTime; //in units of 10ms + tCsrTimerInfo roamingTimerInfo; + eCsrRoamingReason roamingReason; + tANI_BOOLEAN fCancelRoaming; + vos_timer_t hTimerRoaming; + eCsrRoamResult roamResult; //the roamResult that is used when the roaming timer fires + tCsrRoamJoinStatus joinFailStatusCode; //This is the reason code for join(assoc) failure + //The status code returned from PE for deauth or disassoc (in case of lostlink), or our own dynamic roaming + tANI_U32 roamingStatusCode; + tANI_U16 NumPmkidCandidate; + tPmkidCandidateInfo PmkidCandidateInfo[CSR_MAX_PMKID_ALLOWED]; + #ifdef FEATURE_WLAN_WAPI + tANI_U16 NumBkidCandidate; + tBkidCandidateInfo BkidCandidateInfo[CSR_MAX_BKID_ALLOWED]; +#endif + tANI_BOOLEAN fWMMConnection; + tANI_BOOLEAN fQOSConnection; + +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //To retry a join later when it fails if so desired + vos_timer_t hTimerJoinRetry; + tCsrTimerInfo joinRetryTimerInfo; + tANI_U32 maxRetryCount; +#endif +#ifdef FEATURE_WLAN_ESE + tCsrEseCckmInfo eseCckmInfo; + tANI_BOOLEAN isPrevApInfoValid; + tSirMacSSid prevApSSID; + tCsrBssid prevApBssid; + tANI_U8 prevOpChannel; + tANI_U16 clientDissSecs; + tANI_U32 roamTS1; +#if defined(FEATURE_WLAN_ESE_UPLOAD) + tCsrEseCckmIe suppCckmIeInfo; +#endif +#endif + tANI_U8 bRefAssocStartCnt; //Tracking assoc start indication + /* to force the AP initiate fresh 802.1x authentication after re-association need to clear + * the PMKID cache. To clear the cache in this particular case this is added + * it is needed by the HS 2.0 passpoint certification 5.2.a and b testcases */ + tANI_BOOLEAN fIgnorePMKIDCache; + tANI_BOOLEAN abortConnection; + bool dhcp_done; +} tCsrRoamSession; + +typedef struct tagCsrRoamStruct +{ + tANI_U32 nextRoamId; + tDblLinkList roamCmdPendingList; + tDblLinkList channelList5G; + tDblLinkList channelList24; + tCsrConfig configParam; + tANI_U32 numChannelsEeprom; //total channels of eeprom + tCsrChannel base20MHzChannels; //The channel base to work on + tCsrChannel base40MHzChannels; //center channels for 40MHz channels + eCsrRoamState curState[CSR_ROAM_SESSION_MAX]; + eCsrRoamSubState curSubState[CSR_ROAM_SESSION_MAX]; + eCsrRoamState prev_state[CSR_ROAM_SESSION_MAX]; + //This may or may not have the up-to-date valid channel list + //It is used to get WNI_CFG_VALID_CHANNEL_LIST and not allocate memory all the time + tSirMacChanNum validChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U32 numValidChannels; //total number of channels in CFG + + tANI_S32 sPendingCommands; + vos_timer_t hTimerWaitForKey; //To support timeout for WaitForKey state + tCsrSummaryStatsInfo summaryStatsInfo; + tCsrGlobalClassAStatsInfo classAStatsInfo; + tCsrGlobalClassBStatsInfo classBStatsInfo; + tCsrGlobalClassCStatsInfo classCStatsInfo; + tCsrGlobalClassDStatsInfo classDStatsInfo; + tCsrPerStaStatsInfo perStaStatsInfo[CSR_MAX_STA]; + tPerTxPacketFrmFw perPktStatsInfo; + tDblLinkList statsClientReqList; + tDblLinkList peStatsReqList; + tCsrTlStatsReqInfo tlStatsReqInfo; + eCsrRoamLinkQualityInd vccLinkQuality; + tCsrLinkQualityIndInfo linkQualityIndInfo; + v_CONTEXT_t gVosContext; //used for interaction with TL + //To specify whether an association or a IBSS is WMM enabled + //This parameter is only valid during a join or start BSS command is being executed + //tANI_BOOLEAN fWMMConnection; /* Moving it to be part of roamsession */ + v_U8_t ucACWeights[WLANTL_MAX_AC]; + /* TODO : Upto here */ + tCsrTimerInfo WaitForKeyTimerInfo; + tCsrRoamSession *roamSession; + tANI_U32 transactionId; // Current transaction ID for internal use. +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tCsrNeighborRoamControlInfo neighborRoamInfo; +#endif +#ifdef FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; +#endif +#ifdef FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 RoamRssiDiff; + tANI_BOOLEAN isWESModeEnabled; +#endif + tANI_U32 deauthRspStatus; + tANI_BOOLEAN pending_roam_disable; +}tCsrRoamStruct; + + +#define GET_NEXT_ROAM_ID(pRoamStruct) (((pRoamStruct)->nextRoamId + 1 == 0) ? 1 : (pRoamStruct)->nextRoamId) +#define CSR_IS_ROAM_STATE(pMac, state, sessionId) ( (state) == (pMac)->roam.curState[sessionId] ) + +#define CSR_IS_ROAM_STOP(pMac, sessionId) CSR_IS_ROAM_STATE( (pMac), eCSR_ROAMING_STATE_STOP, sessionId ) +#define CSR_IS_ROAM_INIT(pMac, sessionId) CSR_IS_ROAM_STATE( (pMac), eCSR_ROAMING_STATE_INIT, sessionId ) +#define CSR_IS_ROAM_SCANNING(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_SCANNING, sessionId ) +#define CSR_IS_ROAM_JOINING(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ) +#define CSR_IS_ROAM_IDLE(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ) +#define CSR_IS_ROAM_JOINED(pMac, sessionId) CSR_IS_ROAM_STATE( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ) + +#define CSR_IS_ROAM_SUBSTATE(pMac, subState, sessionId) ((subState) == (pMac)->roam.curSubState[sessionId]) +#define CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_AUTH_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_AUTH_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_REASSOC_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, sessionId) +#define CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_FORCED, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DEAUTH_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_START_BSS_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_START_BSS_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_STOP_BSS_REQ, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, sessionId) +#define CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_CONFIG, sessionId) +#define CSR_IS_ROAM_SUBSTATE_WAITFORKEY(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, sessionId) +#define CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF, sessionId) +#define CSR_IS_ROAM_SUBSTATE_HO_NT(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC, sessionId) +#define CSR_IS_ROAM_SUBSTATE_HO_NRT(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC, sessionId) +#define CSR_IS_ROAM_SUBSTATE_HO_RT(pMac, sessionId) CSR_IS_ROAM_SUBSTATE((pMac), eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC, sessionId) + +#define CSR_IS_PHY_MODE_B_ONLY(pMac) \ + ((eCSR_DOT11_MODE_11b == (pMac)->roam.configParam.phyMode) ||\ + (eCSR_DOT11_MODE_11b_ONLY == (pMac)->roam.configParam.phyMode)) + +#define CSR_IS_PHY_MODE_G_ONLY(pMac) \ + (eCSR_DOT11_MODE_11g == (pMac)->roam.configParam.phyMode || eCSR_DOT11_MODE_11g_ONLY == (pMac)->roam.configParam.phyMode) + +#define CSR_IS_PHY_MODE_A_ONLY(pMac) \ + ((eCSR_DOT11_MODE_11a == (pMac)->roam.configParam.phyMode) ||\ + (eCSR_DOT11_MODE_11a_ONLY == (pMac)->roam.configParam.phyMode)) + +#ifdef WLAN_FEATURE_11AC +#define CSR_IS_PHY_MODE_DUAL_BAND(phyMode) \ + ((eCSR_DOT11_MODE_abg & (phyMode)) || (eCSR_DOT11_MODE_11n & (phyMode)) || \ + (eCSR_DOT11_MODE_11ac & (phyMode)) || \ + (eCSR_DOT11_MODE_TAURUS & (phyMode)) || \ + (eCSR_DOT11_MODE_AUTO & (phyMode))) +#else +#define CSR_IS_PHY_MODE_DUAL_BAND(phyMode) \ + ((eCSR_DOT11_MODE_abg & (phyMode)) || (eCSR_DOT11_MODE_11n & (phyMode)) || \ + (eCSR_DOT11_MODE_TAURUS & (phyMode)) || \ + (eCSR_DOT11_MODE_AUTO & (phyMode))) +#endif + + +// this function returns TRUE if the NIC is operating exclusively in the 2.4 GHz band, meaning +// it is NOT operating in the 5.0 GHz band. +#define CSR_IS_24_BAND_ONLY(pMac) \ + (eCSR_BAND_24 == (pMac)->roam.configParam.eBand) + +#define CSR_IS_5G_BAND_ONLY(pMac) \ + (eCSR_BAND_5G == (pMac)->roam.configParam.eBand) + +#define CSR_IS_RADIO_DUAL_BAND(pMac) \ + (eCSR_BAND_ALL == (pMac)->roam.configParam.bandCapability) + +#define CSR_IS_RADIO_BG_ONLY(pMac) \ + (eCSR_BAND_24 == (pMac)->roam.configParam.bandCapability) + +// this function returns TRUE if the NIC is operating exclusively in the 5.0 GHz band, meaning +// it is NOT operating in the 2.4 GHz band +#define CSR_IS_RADIO_A_ONLY(pMac) \ + (eCSR_BAND_5G == (pMac)->roam.configParam.bandCapability) + +// this function returns TRUE if the NIC is operating in both bands. +#define CSR_IS_OPEARTING_DUAL_BAND(pMac) \ + ((eCSR_BAND_ALL == (pMac)->roam.configParam.bandCapability) && (eCSR_BAND_ALL == (pMac)->roam.configParam.eBand)) + +// this function returns TRUE if the NIC can operate in the 5.0 GHz band (could operate in the +// 2.4 GHz band also). +#define CSR_IS_OPERATING_A_BAND(pMac) \ + (CSR_IS_OPEARTING_DUAL_BAND((pMac)) || CSR_IS_RADIO_A_ONLY((pMac)) || CSR_IS_5G_BAND_ONLY((pMac))) + +// this function returns TRUE if the NIC can operate in the 2.4 GHz band (could operate in the +// 5.0 GHz band also). +#define CSR_IS_OPERATING_BG_BAND(pMac) \ + (CSR_IS_OPEARTING_DUAL_BAND((pMac)) || CSR_IS_RADIO_BG_ONLY((pMac)) || CSR_IS_24_BAND_ONLY((pMac))) + +#define CSR_IS_CHANNEL_5GHZ(chnNum) \ + (((chnNum) >= CSR_MIN_5GHz_CHANNEL_NUMBER) && ((chnNum) <= CSR_MAX_5GHz_CHANNEL_NUMBER)) + +#define CSR_IS_CHANNEL_DFS(chnNum) \ + (NV_CHANNEL_ENABLE != vos_nv_getChannelEnabledState(chnNum)) + +#define CSR_IS_CHANNEL_24GHZ(chnNum) \ + (((chnNum) > 0) && ((chnNum) <= CSR_MAX_24GHz_CHANNEL_NUMBER)) + +#define CSR_IS_SAME_BAND_CHANNELS(ch1, ch2) (CSR_IS_CHANNEL_5GHZ(ch1) == CSR_IS_CHANNEL_5GHZ(ch2)) + + +#define CSR_IS_11D_INFO_FOUND(pMac) \ + (0 != (pMac)->scan.channelOf11dInfo) +// DEAUTHIND +#define CSR_IS_ROAMING(pSession) ((CSR_IS_LOSTLINK_ROAMING((pSession)->roamingReason)) || \ + (eCsrDynamicRoaming == (pSession)->roamingReason) || \ + (eCsrReassocRoaming == (pSession)->roamingReason)) + + +#define CSR_IS_SET_KEY_COMMAND( pCommand ) ( eSmeCommandSetKey == (pCommand)->command ) + +#define CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) (pMac->roam.configParam.addTSWhenACMIsOff) +// DEAUTHIND +#define CSR_IS_LOSTLINK_ROAMING(reason) ((eCsrLostlinkRoamingDisassoc == (reason)) || (eCsrLostlinkRoamingDeauth == (reason))) + +#define CSR_IS_ROAMING_COMMAND(pCommand) ((eCsrLostLink1 == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrLostLink2 == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrLostLink3 == (pCommand)->u.roamCmd.roamReason) ) + + +//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR +void csrScanSuspendIMPS( tpAniSirGlobal pMac ); +//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS +//because IMPS maybe disabled. +void csrScanResumeIMPS( tpAniSirGlobal pMac ); + +eHalStatus csrInitGetChannels(tpAniSirGlobal pMac); +eHalStatus csrScanFilterResults(tpAniSirGlobal pMac); +eHalStatus csrScanFilterDFSResults(tpAniSirGlobal pMac); + +eHalStatus csrSetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModifyProfileFields); +/* --------------------------------------------------------------------------- + \fn csrGetModifyProfileFields + \brief HDD or SME - QOS calls this function to get the current values of + connected profile fields changing which can cause reassoc. + This function must be called after CFG is downloaded and STA is in connected + state. + \param pModifyProfileFields - pointer to the connected profile fields + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields * pModifyProfileFields); +void csrSetGlobalCfgs( tpAniSirGlobal pMac ); +void csrSetDefaultDot11Mode( tpAniSirGlobal pMac ); +void csrScanSetChannelMask(tpAniSirGlobal pMac, tCsrChannelInfo *pChannelInfo); +tANI_BOOLEAN csrIsConnStateDisconnected(tpAniSirGlobal pMac, tANI_U32 sessionId); +tANI_BOOLEAN csrIsConnStateConnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateDisconnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateConnectedInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateConnected( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateWds( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateConnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsConnStateDisconnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ); +tANI_BOOLEAN csrIsAnySessionInConnectState( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsAllSessionDisconnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsStaSessionConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsP2pSessionConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsAnySessionConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsInfraConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsConcurrentInfraConnected( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsConcurrentSessionRunning( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsInfraApStarted( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsIBSSStarted( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsBTAMPStarted( tpAniSirGlobal pMac ); +tANI_BOOLEAN csrIsBTAMP( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrIsBTAMPAllowed( tpAniSirGlobal pMac, tANI_U32 chnId ); +tANI_BOOLEAN csrIsValidMcConcurrentSession(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc); +tANI_BOOLEAN csrIsConnStateConnectedInfraAp( tpAniSirGlobal pMac, tANI_U32 sessionId ); +/*---------------------------------------------------------------------------- + \fn csrRoamRegisterLinkQualityIndCallback + + \brief + a CSR function to allow HDD to register a callback handler with CSR for + link quality indications. + + Only one callback may be registered at any time. + In order to deregister the callback, a NULL cback may be provided. + + Registration happens in the task context of the caller. + + \param callback - Call back being registered + \param pContext - user data + + DEPENDENCIES: After CSR open + + \return eHalStatus +-----------------------------------------------------------------------------*/ +eHalStatus csrRoamRegisterLinkQualityIndCallback(tpAniSirGlobal pMac, + csrRoamLinkQualityIndCallback callback, + void *pContext); +/* --------------------------------------------------------------------------- + \fn csrGetStatistics + \brief csr function that client calls to register a callback to get + different PHY level statistics from CSR. + + \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc + \param statsMask - The different category/categories of stats requester is looking for + \param callback - SME sends back the requested stats using the callback + \param periodicity - If requester needs periodic update, 0 means it's an one + time request + \param cache - If requester is happy with cached stats + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext); + +/* --------------------------------------------------------------------------- + \fn csrGetTLSTAState + \helper function to get the TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 csrGetTLSTAState(tpAniSirGlobal pMac, tANI_U8 staId); + +eHalStatus csrGetRssi(tpAniSirGlobal pMac,tCsrRssiCallback callback,tANI_U8 staId,tCsrBssid bssId,void * pContext,void * pVosContext); + +/* --------------------------------------------------------------------------- + \fn csrGetSnr + \brief csr function that client calls to register a callback to get + SNR stored in TL + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param bssid - The bssid for the connected session + \param pContext - user context to be passed back along with the callback + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrGetSnr(tpAniSirGlobal pMac, tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, void *pContext); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +eHalStatus csrGetRoamRssi(tpAniSirGlobal pMac, + tCsrRssiCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void * pContext, + void * pVosContext); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus csrGetTsmStats(tpAniSirGlobal pMac, tCsrTsmStatsCallback callback, tANI_U8 staId, + tCsrBssid bssId, void *pContext, void* pVosContext, + tANI_U8 tid); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +eHalStatus csrRoamRegisterCallback(tpAniSirGlobal pMac, csrRoamCompleteCallback callback, void *pContext); +/* --------------------------------------------------------------------------- + \fn csrGetConfigParam + \brief HDD calls this function to get the global settings currently maintained by CSR. + \param pParam - caller allocated memory + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam); + +/* --------------------------------------------------------------------------- + \fn csrMsgProcessor + \brief HDD calls this function to change some global settings. + caller must set the all fields or call csrGetConfigParam to prefill the fields. + \param pParam - caller allocated memory + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam); + + +/* --------------------------------------------------------------------------- + \fn csrMsgProcessor + \brief HDD calls this function for the messages that are handled by CSR. + \param pMsgBuf - a pointer to a buffer that maps to various structures base on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); + +/* --------------------------------------------------------------------------- + \fn csrOpen + \brief This function must be called before any API call to CSR. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrOpen(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------- + \fn csrInitChannels + \brief This function must be called to initialize CSR channel lists + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrInitChannels(tpAniSirGlobal pMac); + +#ifdef CONFIG_ENABLE_LINUX_REG +/* --------------------------------------------------------------------------- + \fn csrInitChannelsForCC + \brief This function must be called to issue reg hint + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrInitChannelsForCC(tpAniSirGlobal pMac, driver_load_type init ); +#endif + +/* --------------------------------------------------------------------------- + \fn csrClose + \brief To close down CSR module. There should not be any API call into CSR after calling this function. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrClose(tpAniSirGlobal pMac); +/* --------------------------------------------------------------------------- + \fn csrStart + \brief To start CSR. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrStart(tpAniSirGlobal pMac); +/* --------------------------------------------------------------------------- + \fn csrStop + \brief To stop CSR. CSR still keeps its current setting. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrStop(tpAniSirGlobal pMac, tHalStopType stopType); +/* --------------------------------------------------------------------------- + \fn csrReady + \brief To let CSR is ready to operate + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrReady(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrRoamGetBKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pNum, + tBkidCacheInfo *pBkidCache); + + +eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems ); +tANI_U32 csrRoamGetNumBKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrRoamSetBKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId, tBkidCacheInfo *pBKIDCache, + tANI_U32 numItems ); +/* --------------------------------------------------------------------------- + \fn csrRoamGetWapiReqIE + \brief return the WAPI IE CSR passes to PE to JOIN request or START_BSS request + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWapiReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWapiRspIE + \brief return the WAPI IE from the beacon or probe rsp if connected + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWapiRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); +tANI_U8 csrConstructWapiIe( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ); +#endif /* FEATURE_WLAN_WAPI */ + +eHalStatus csrRoamUpdateAPWPSIE( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirAPWPSIEs *pAPWPSIES ); +eHalStatus csrRoamUpdateWPARSNIEs( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirRSNie * pAPSirRSNie); +void csrSetCfgPrivacy( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy ); +tANI_S8 csrGetInfraSessionId( tpAniSirGlobal pMac ); +tANI_U8 csrGetInfraOperationChannel( tpAniSirGlobal pMac, tANI_U8 sessionId); +tANI_BOOLEAN csrIsSessionClientAndConnected(tpAniSirGlobal pMac, tANI_U8 sessionId); +tANI_U8 csrGetConcurrentOperationChannel( tpAniSirGlobal pMac ); + +eHalStatus csrRoamCopyConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamConnectedProfile *pProfile); +tANI_BOOLEAN csrIsSetKeyAllowed(tpAniSirGlobal pMac, tANI_U32 sessionId); + +void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac ); +void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList, + tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels ); + +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus csrScanSavePreferredNetworkFound(tpAniSirGlobal pMac, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd); +#endif //FEATURE_WLAN_SCAN_PNO +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R +//Returns whether the current association is a 11r assoc or not +tANI_BOOLEAN csrRoamIs11rAssoc(tpAniSirGlobal pMac); +#endif + +#ifdef FEATURE_WLAN_ESE +//Returns whether the current association is a ESE assoc or not +tANI_BOOLEAN csrRoamIsESEAssoc(tpAniSirGlobal pMac); +tANI_BOOLEAN csrRoamIsEseIniFeatureEnabled(tpAniSirGlobal pMac); +tANI_BOOLEAN csrNeighborRoamIsESEAssoc(tpAniSirGlobal pMac); +#endif + +//Remove this code once SLM_Sessionization is supported +//BMPS_WORKAROUND_NOT_NEEDED +void csrDisconnectAllActiveSessions(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_LFR +//Returns whether "Legacy Fast Roaming" is enabled...or not +tANI_BOOLEAN csrRoamIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U32 sessionId); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +tANI_BOOLEAN csrRoamIsRoamOffloadScanEnabled(tpAniSirGlobal pMac); +#endif +tANI_BOOLEAN csrIsChannelPresentInList( tANI_U8 *pChannelList, int numChannels, tANI_U8 channel ); +VOS_STATUS csrAddToChannelListFront( tANI_U8 *pChannelList, int numChannels, tANI_U8 channel ); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +eHalStatus csrScanRequestLfrResult(tpAniSirGlobal pMac, tANI_U32 sessionId, + csrScanCompleteCallback callback, void *pContext); +eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, tANI_U8 reason); +eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, tCsrHandoffRequest *pHandoffInfo); +#endif +tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId); +#endif + +void csrDisableDfsChannel(tpAniSirGlobal pMac); + +#ifdef WLAN_FEATURE_RMC +eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId); +#endif /* WLAN_FEATURE_RMC */ + +eHalStatus csrRoamStopNetwork(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes); + +eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac, + tANI_U32 sessionId, eCsrAuthType authType, + tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes); + +void csrRoamSubstateChange(tpAniSirGlobal pMac, + eCsrRoamSubState NewSubstate, tANI_U32 sessionId); + +eHalStatus csrRoamFreeConnectedInfo(tpAniSirGlobal pMac, + tCsrRoamConnectedInfo *pConnectedInfo); diff --git a/drivers/staging/prima/CORE/SME/inc/csrLinkList.h b/drivers/staging/prima/CORE/SME/inc/csrLinkList.h new file mode 100644 index 000000000000..58912cf4b778 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/csrLinkList.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrLinkList.h + + Exports and types for the Common link list interfaces. + + ========================================================================== */ +#ifndef CSR_LINK_LIST_H__ +#define CSR_LINK_LIST_H__ + +#include "vos_lock.h" + + +#define LL_ACCESS_LOCK eANI_BOOLEAN_TRUE +#define LL_ACCESS_NOLOCK eANI_BOOLEAN_FALSE + +typedef struct tagListElem +{ + struct tagListElem *last; + struct tagListElem *next; +}tListElem; + +typedef enum +{ + LIST_FLAG_CLOSE = 0, + LIST_FLAG_OPEN = 0xa1b2c4d7, +}tListFlag; + +//This is a circular double link list +typedef struct tagDblLinkList +{ + tListElem ListHead; + vos_lock_t Lock; + tANI_U32 Count; + tHddHandle hHdd; + tListFlag Flag; + + /*command debugging */ + tANI_U32 cmdTimeoutDuration; /* command timeout duration */ + vos_timer_t *cmdTimeoutTimer; /*command timeout Timer */ +}tDblLinkList; + +//To get the address of an object of (type) base on the (address) of one of its (field) +#define GET_BASE_ADDR(address, type, field) ((type *)( \ + (tANI_U8 *)(address) - \ + (tANI_U8 *)(&((type *)0)->field))) + +//To get the offset of (field) inside structure (type) +#define GET_FIELD_OFFSET(type, field) ((uintptr_t)(&(((type *)0)->field))) + +#define GET_ROUND_UP( _Field, _Boundary ) (((_Field) + ((_Boundary) - 1)) & ~((_Boundary) - 1)) +#define BITS_ON( _Field, _Bitmask ) ( (_Field) |= (_Bitmask) ) +#define BITS_OFF( _Field, _Bitmask ) ( (_Field) &= ~(_Bitmask) ) + +#define CSR_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define CSR_MIN(a, b) ((a) < (b) ? (a) : (b)) + + +#define csrIsListEmpty(pHead) ((pHead)->next == (pHead)) + +tANI_U32 csrLLCount( tDblLinkList *pList ); + +eHalStatus csrLLOpen( tHddHandle hHdd, tDblLinkList *pList ); +void csrLLClose( tDblLinkList *pList ); + +void csrLLLock( tDblLinkList *pList ); +void csrLLUnlock( tDblLinkList *pList ); + +tANI_BOOLEAN csrLLIsListEmpty( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); + +void csrLLInsertHead( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); +void csrLLInsertTail( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); +//This function put pNewEntry before pEntry. Caller should have found pEntry +void csrLLInsertEntry( tDblLinkList *pList, tListElem *pEntry, tListElem *pNewEntry, tANI_BOOLEAN fInterlocked ); + +tListElem *csrLLPeekHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); +tListElem *csrLLPeekTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); + +tListElem *csrLLRemoveHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); +tListElem *csrLLRemoveTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); +tANI_BOOLEAN csrLLRemoveEntry( tDblLinkList *pList, tListElem *pEntryToRemove, tANI_BOOLEAN fInterlocked ); +void csrLLPurge( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ); + +//csrLLNext return NULL if reaching the end or list is empty +tListElem *csrLLNext( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); + +tListElem *csrLLPrevious( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ); + +tANI_BOOLEAN csrLLFindEntry( tDblLinkList *pList, tListElem *pEntryToFind ); + + +#endif + diff --git a/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h b/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h new file mode 100644 index 000000000000..93bfc0769ce2 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/csrNeighborRoam.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrNeighborRoam.h + + Exports and types for the neighbor roaming algorithm which is sepcifically + designed for Android. + +========================================================================== */ +#ifndef CSR_NEIGHBOR_ROAM_H +#define CSR_NEIGHBOR_ROAM_H + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "sme_Api.h" + +/* 15 seconds, for WPA, WPA2, CCKM */ +#define CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD (15 * PAL_TIMER_TO_SEC_UNIT) +/* 120 seconds, for WPS */ +#define CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD (120 * PAL_TIMER_TO_SEC_UNIT) + + +/* Enumeration of various states in neighbor roam algorithm */ +typedef enum +{ + eCSR_NEIGHBOR_ROAM_STATE_CLOSED, + eCSR_NEIGHBOR_ROAM_STATE_INIT, + eCSR_NEIGHBOR_ROAM_STATE_CONNECTED, + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN, + eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING, +#ifdef WLAN_FEATURE_VOWIFI_11R + eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY, + eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN, + eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING, + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE, +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef WLAN_FEATURE_LFR_MBB + eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC, +#endif + + eNEIGHBOR_STATE_MAX +} eCsrNeighborRoamState; + +/* Parameters that are obtained from CFG */ +typedef struct sCsrNeighborRoamCfgParams +{ + tANI_U8 maxNeighborRetries; + tANI_U32 neighborScanPeriod; + tCsrChannelInfo channelInfo; + tANI_U8 neighborLookupThreshold; + tANI_U8 neighborReassocThreshold; + tANI_U32 minChannelScanTime; + tANI_U32 maxChannelScanTime; + tANI_U16 neighborResultsRefreshPeriod; + tANI_U16 emptyScanRefreshPeriod; + tANI_U8 neighborInitialForcedRoamTo5GhEnable; + tANI_U8 WeakZoneRssiThresholdForRoam; +} tCsrNeighborRoamCfgParams, *tpCsrNeighborRoamCfgParams; + +#define CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX 255 +typedef struct sCsrNeighborRoamChannelInfo +{ + tANI_BOOLEAN IAPPNeighborListReceived; // Flag to mark reception of IAPP Neighbor list + tANI_BOOLEAN chanListScanInProgress; + tANI_U8 currentChanIndex; //Current channel index that is being scanned + tCsrChannelInfo currentChannelListInfo; //Max number of channels in channel list and the list of channels +} tCsrNeighborRoamChannelInfo, *tpCsrNeighborRoamChannelInfo; + +typedef struct sCsrNeighborRoamBSSInfo +{ + tListElem List; + tANI_U8 apPreferenceVal; +// tCsrScanResultInfo *scanResultInfo; + tpSirBssDescription pBssDescription; +} tCsrNeighborRoamBSSInfo, *tpCsrNeighborRoamBSSInfo; + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT 1000 //in milliseconds +#define CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER 10 //in milliseconds +#define MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS 10 //Max number of MAC addresses with which the pre-auth was failed +#define MAX_BSS_IN_NEIGHBOR_RPT 15 +#define CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES 3 +#define INITIAL_FORCED_ROAM_TO_5G_TIMER_PERIOD 5000 //in msecs + +/* Black listed APs. List of MAC Addresses with which the Preauthentication was failed. */ +typedef struct sCsrPreauthFailListInfo +{ + tANI_U8 numMACAddress; + tSirMacAddr macAddress[MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS]; +} tCsrPreauthFailListInfo, *tpCsrPreauthFailListInfo; + +typedef struct sCsrNeighborReportBssInfo +{ + tANI_U8 channelNum; + tANI_U8 neighborScore; + tSirMacAddr neighborBssId; +} tCsrNeighborReportBssInfo, *tpCsrNeighborReportBssInfo; + +typedef struct sCsr11rAssocNeighborInfo +{ + tANI_BOOLEAN preauthRspPending; + tANI_BOOLEAN neighborRptPending; + tANI_U8 currentNeighborRptRetryNum; + tCsrPreauthFailListInfo preAuthFailList; + tANI_U32 neighborReportTimeout; + tANI_U32 PEPreauthRespTimeout; + tANI_U8 numPreAuthRetries; + tDblLinkList preAuthDoneList; /* Linked list which consists or preauthenticated nodes */ + tANI_U8 numBssFromNeighborReport; + tCsrNeighborReportBssInfo neighboReportBssInfo[MAX_BSS_IN_NEIGHBOR_RPT]; //Contains info needed during REPORT_SCAN State +} tCsr11rAssocNeighborInfo, *tpCsr11rAssocNeighborInfo; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* Below macros are used to increase the registered neighbor Lookup threshold with TL when + * we dont see any AP during back ground scanning. The values are incremented from neighborLookupThreshold + * from CFG, incremented by 5,10,15...50(LOOKUP_THRESHOLD_INCREMENT_MULTIPLIER_MAX * + * NEIGHBOR_LOOKUP_THRESHOLD_INCREMENT_CONSTANT) */ +#define NEIGHBOR_LOOKUP_THRESHOLD_INCREMENT_CONSTANT 5 +#define LOOKUP_THRESHOLD_INCREMENT_MULTIPLIER_MAX 4 +/* + * Set lookup UP threshold 5 dB higher than the configured + * lookup DOWN threshold to minimize thrashing between + * DOWN and UP events. + */ +#define NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD \ + (pNeighborRoamInfo->cfgParams.neighborLookupThreshold-5) +#ifdef FEATURE_WLAN_LFR +typedef enum +{ + eFirstEmptyScan=1, + eSecondEmptyScan, + eThirdEmptyScan, + eFourthEmptyScan, + eFifthEmptyScan, + eMaxEmptyScan=eFifthEmptyScan, +} eNeighborRoamEmptyScanCount; + +typedef enum +{ + DEFAULT_SCAN=0, + SPLIT_SCAN_OCCUPIED_LIST=1, +} eNeighborRoamScanMode; +#endif + +/* Complete control information for neighbor roam algorithm */ +typedef struct sCsrNeighborRoamControlInfo +{ + eCsrNeighborRoamState neighborRoamState; + eCsrNeighborRoamState prevNeighborRoamState; + tCsrNeighborRoamCfgParams cfgParams; + tCsrBssid currAPbssid; // current assoc AP + tANI_U8 currAPoperationChannel; // current assoc AP + vos_timer_t neighborScanTimer; + vos_timer_t neighborResultsRefreshTimer; + vos_timer_t emptyScanRefreshTimer; + tCsrNeighborRoamChannelInfo roamChannelInfo; + tANI_U8 currentNeighborLookupThreshold; + tANI_BOOLEAN scanRspPending; + v_TIME_t scanRequestTimeStamp; + tDblLinkList roamableAPList; // List of current FT candidates + tANI_U32 csrSessionId; + tCsrRoamProfile csrNeighborRoamProfile; +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_BOOLEAN is11rAssoc; + tCsr11rAssocNeighborInfo FTRoamInfo; +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef FEATURE_WLAN_ESE + tANI_BOOLEAN isESEAssoc; + tANI_BOOLEAN isVOAdmitted; + tANI_U32 MinQBssLoadRequired; +#endif +#ifdef FEATURE_WLAN_LFR + tANI_U8 uEmptyScanCount; /* Consecutive number of times scan + yielded no results. */ + tCsrRoamConnectedProfile prevConnProfile; /* Previous connected profile. If the + new profile does not match previous + we re-initialize occupied channel list */ + tANI_S8 lookupDOWNRssi; + tANI_U8 uScanMode; + tANI_U8 uOsRequestedHandoff; /* upper layer requested + a reassoc */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + tCsrHandoffRequest handoffReqInfo; /* handoff related info came + with upper layer's req for + reassoc */ +#endif +#endif + tSmeFastRoamTrigger cfgRoamEn; + tSirMacAddr cfgRoambssId; + vos_timer_t forcedInitialRoamTo5GHTimer; + tANI_U8 isForcedInitialRoamTo5GH; + tANI_U8 lastSentCmd; + +#ifdef WLAN_FEATURE_LFR_MBB + bool is_pre_auth_reassoc_mbb_timer_started; +#endif + +} tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo; + + +/* All the necessary Function declarations are here */ +eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac,tANI_U8 sessionId, VOS_STATUS status); +eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac,tANI_U8 sessionId); +tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac); +void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac); +eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac); +void csrNeighborRoamClose(tpAniSirGlobal pMac); +void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac); +VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac); +VOS_STATUS csrNeighborRoamTransitionToPreauthDone(tpAniSirGlobal pMac); +eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter); +tANI_BOOLEAN csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode); +eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, tSirRetStatus limStatus); +#ifdef WLAN_FEATURE_VOWIFI_11R +tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac); +#endif +VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac); +void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac); +tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac); +tANI_BOOLEAN csrNeighborRoamScanRspPending(tHalHandle hHal); +tANI_BOOLEAN csrNeighborMiddleOfRoaming(tHalHandle hHal); +VOS_STATUS csrNeighborRoamSetLookupRssiThreshold(tpAniSirGlobal pMac, v_U8_t neighborLookupRssiThreshold); +VOS_STATUS csrNeighborRoamUpdateFastRoamingEnabled(tpAniSirGlobal pMac, const v_BOOL_t fastRoamEnabled); +VOS_STATUS csrNeighborRoamUpdateEseModeEnabled(tpAniSirGlobal pMac, const v_BOOL_t eseMode); +VOS_STATUS csrNeighborRoamChannelsFilterByBand( + tpAniSirGlobal pMac, + tANI_U8* pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8* pOutputChannelList, + tANI_U8* pMergedOutputNumOfChannels, + tSirRFBand band + ); +VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter, + v_U8_t trafficStatus, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi); +VOS_STATUS csrNeighborRoamMergeChannelLists(tpAniSirGlobal pMac, + tANI_U8 *pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8 *pOutputChannelList, + tANI_U8 outputNumOfChannels, + tANI_U8 *pMergedOutputNumOfChannels); +tANI_BOOLEAN +csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac, + tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry); +eHalStatus +csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, + tSirMacAddr bssId); +void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, + tpCsrNeighborRoamBSSInfo neighborRoamBSSNode); + + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define ROAM_SCAN_OFFLOAD_START 1 +#define ROAM_SCAN_OFFLOAD_STOP 2 +#define ROAM_SCAN_OFFLOAD_RESTART 3 +#define ROAM_SCAN_OFFLOAD_UPDATE_CFG 4 + +#define REASON_CONNECT 1 +#define REASON_CHANNEL_LIST_CHANGED 2 +#define REASON_LOOKUP_THRESH_CHANGED 3 +#define REASON_DISCONNECTED 4 +#define REASON_RSSI_DIFF_CHANGED 5 +#define REASON_ESE_INI_CFG_CHANGED 6 +#define REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED 7 +#define REASON_VALID_CHANNEL_LIST_CHANGED 8 +#define REASON_FLUSH_CHANNEL_LIST 9 +#define REASON_EMPTY_SCAN_REF_PERIOD_CHANGED 10 +#define REASON_PREAUTH_FAILED_FOR_ALL 11 +#define REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW 12 +#define REASON_NPROBES_CHANGED 13 +#define REASON_HOME_AWAY_TIME_CHANGED 14 +#define REASON_OS_REQUESTED_ROAMING_NOW 15 +#define REASON_SCAN_CH_TIME_CHANGED 16 +#define REASON_SCAN_HOME_TIME_CHANGED 17 +#define REASON_INITIAL_FORCED_ROAM_TO_5G 18 +eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reason); +eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, void* pMsg); +eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg); +eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac); +eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status); +eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 OffloadCmdStopReason); +eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, + tANI_U32 interval); +void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid); + +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, + const tANI_U8 *pCckmIe, + const tANI_U8 ccKmIeLen); +VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp); + + +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + +#endif /* CSR_NEIGHBOR_ROAM_H */ diff --git a/drivers/staging/prima/CORE/SME/inc/csrSupport.h b/drivers/staging/prima/CORE/SME/inc/csrSupport.h new file mode 100644 index 000000000000..28c775adda74 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/csrSupport.h @@ -0,0 +1,839 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + + \file csrSupport.h + + Exports and types for the Common Scan and Roaming supporting interfaces. + + ========================================================================== */ +#ifndef CSR_SUPPORT_H__ +#define CSR_SUPPORT_H__ + +#include "csrLinkList.h" +#include "csrApi.h" +#include "vos_nvitem.h" + +#ifdef FEATURE_WLAN_WAPI +#define CSR_WAPI_OUI_ROW_SIZE ( 3 ) +#define CSR_WAPI_OUI_SIZE ( 4 ) +#define CSR_WAPI_VERSION_SUPPORTED ( 1 ) +#define CSR_WAPI_MAX_AUTH_SUITES ( 2 ) +#define CSR_WAPI_MAX_CYPHERS ( 5 ) +#define CSR_WAPI_MAX_UNICAST_CYPHERS ( 5 ) +#define CSR_WAPI_MAX_MULTICAST_CYPHERS ( 1 ) +#endif /* FEATURE_WLAN_WAPI */ + +#define CSR_RSN_OUI_SIZE ( 4 ) +#define CSR_RSN_VERSION_SUPPORTED ( 1 ) +#define CSR_RSN_MAX_AUTH_SUITES ( 4 ) +#define CSR_RSN_MAX_CYPHERS ( 5 ) +#define CSR_RSN_MAX_UNICAST_CYPHERS ( 5 ) +#define CSR_RSN_MAX_MULTICAST_CYPHERS ( 1 ) + +#define CSR_WPA_OUI_SIZE ( 4 ) +#define CSR_WPA_VERSION_SUPPORTED ( 1 ) +#define CSR_WME_OUI_SIZE ( 4 ) +#define CSR_WPA_MAX_AUTH_SUITES ( 2 ) +#define CSR_WPA_MAX_CYPHERS ( 5 ) +#define CSR_WPA_MAX_UNICAST_CYPHERS ( 5 ) +#define CSR_WPA_MAX_MULTICAST_CYPHERS ( 1 ) +#define CSR_WPA_IE_MIN_SIZE ( 6 ) // minimum size of the IE->length is the size of the Oui + Version. +#define CSR_WPA_IE_MIN_SIZE_W_MULTICAST ( HDD_WPA_IE_MIN_SIZE + HDD_WPA_OUI_SIZE ) +#define CSR_WPA_IE_MIN_SIZE_W_UNICAST ( HDD_WPA_IE_MIN_SIZE + HDD_WPA_OUI_SIZE + sizeof( pWpaIe->cUnicastCyphers ) ) + +#define CSR_DOT11_SUPPORTED_RATES_MAX ( 12 ) +#define CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ( 8 ) + +#define CSR_DOT11_MAX_NUM_SUPPORTED_11B_RATES ( 4 ) +#define CSR_DOT11_MAX_NUM_SUPPORTED_11A_RATES ( 8 ) +#define CSR_DOT11_BASIC_RATE_MASK ( 0x80 ) + +#define CSR_WME_INFO_IE_VERSION_SUPPORTED ( 1 ) +#define CSR_WME_PARM_IE_VERSION_SUPPORTED ( 1 ) + +#define CSR_PASSIVE_SCAN_STARTING_CHANNEL ( 52) +#define CSR_PASSIVE_SCAN_ENDING_CHANNEL ( 140) + +#define CSR_DOT11_MAX_11A_RATE ( 54 * 2 ) +#define CSR_DOT11_MIN_11A_RATE ( 6 * 2 ) +#define CSR_DOT11_MAX_11B_RATE ( 11 * 2 ) +#define CSR_DOT11_MIN_11B_RATE ( 1 * 2 ) +#define CSR_DOT11_MAX_11G_RATE ( 54 * 2 ) +#define CSR_DOT11_MIN_11G_RATE ( 6 * 2 ) + +//Define the frequency ranges that need to be passive scan, MHz +#define CSR_PASSIVE_SCAN_CAT1_LOW 5250 +#define CSR_PASSIVE_SCAN_CAT1_HIGH 5350 +#define CSR_PASSIVE_SCAN_CAT2_LOW 5470 +#define CSR_PASSIVE_SCAN_CAT2_HIGH 5725 +#define CSR_PASSIVE_SCAN_CAT3_LOW 5500 +#define CSR_PASSIVE_SCAN_CAT3_HIGH 5560 + +#define CSR_OUI_USE_GROUP_CIPHER_INDEX 0x00 +#define CSR_OUI_WEP40_OR_1X_INDEX 0x01 +#define CSR_OUI_TKIP_OR_PSK_INDEX 0x02 +#define CSR_OUI_RESERVED_INDEX 0x03 +#define CSR_OUI_AES_INDEX 0x04 +#define CSR_OUI_WEP104_INDEX 0x05 + +#ifdef FEATURE_WLAN_WAPI +#define CSR_OUI_WAPI_RESERVED_INDEX 0x00 +#define CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX 0x01 +#define CSR_OUI_WAPI_WAI_PSK_INDEX 0x02 +#endif /* FEATURE_WLAN_WAPI */ + + +typedef enum +{ + // 11b rates + eCsrSuppRate_1Mbps = 1 * 2, + eCsrSuppRate_2Mbps = 2 * 2, + eCsrSuppRate_5_5Mbps = 11, // 5.5 * 2 + eCsrSuppRate_11Mbps = 11 * 2, + + // 11a / 11g rates + eCsrSuppRate_6Mbps = 6 * 2, + eCsrSuppRate_9Mbps = 9 * 2, + eCsrSuppRate_12Mbps = 12 * 2, + eCsrSuppRate_18Mbps = 18 * 2, + eCsrSuppRate_24Mbps = 24 * 2, + eCsrSuppRate_36Mbps = 36 * 2, + eCsrSuppRate_48Mbps = 48 * 2, + eCsrSuppRate_54Mbps = 54 * 2, + + // airgo proprietary rates + eCsrSuppRate_10Mbps = 10 * 2, + eCsrSuppRate_10_5Mbps= 21, // 10.5 * 2 + eCsrSuppRate_20Mbps = 20 * 2, + eCsrSuppRate_21Mbps = 21 * 2, + eCsrSuppRate_40Mbps = 40 * 2, + eCsrSuppRate_42Mbps = 42 * 2, + eCsrSuppRate_60Mbps = 60 * 2, + eCsrSuppRate_63Mbps = 63 * 2, + eCsrSuppRate_72Mbps = 72 * 2, + eCsrSuppRate_80Mbps = 80 * 2, + eCsrSuppRate_84Mbps = 84 * 2, + eCsrSuppRate_96Mbps = 96 * 2, + eCsrSuppRate_108Mbps = 108 * 2, + eCsrSuppRate_120Mbps = 120 * 2, + eCsrSuppRate_126Mbps = 126 * 2, + eCsrSuppRate_144Mbps = 144 * 2, + eCsrSuppRate_160Mbps = 160 * 2, + eCsrSuppRate_168Mbps = 168 * 2, + eCsrSuppRate_192Mbps = 192 * 2, + eCsrSuppRate_216Mbps = 216 * 2, + eCsrSuppRate_240Mbps = 240 * 2 +}eCsrSupportedRates; + +typedef enum +{ + eCsrPassiveScanNot, //can be scanned actively on the whole 5GHz band + eCsrPassiveScanCat1, //always passive scan from 5250 to 5350MHz + eCsrPassiveScanCat2, //always passive scan from 5250 to 5350MHz, and from 5470 to 5725MHz + eCsrPassiveScanCat3, //always passive scan from 5250 to 5350MHz, from 5470 to 5725MHz, and from 5500 to 5560MHz +}eCsrPassiveScanCat; + + +//Please donot insert in the middle of the enum here because they tie to the indiex +typedef enum +{ + eCSR_COUNTRY_INDEX_US = 0, //Always set US as index 0 + eCSR_COUNTRY_INDEX_ANDORRA, + eCSR_COUNTRY_INDEX_UAE, //United Arab Emirates + eCSR_COUNTRY_INDEX_AFGHANISTAN, + eCSR_COUNTRY_INDEX_ANTIGUA_AND_BARBUDA, + eCSR_COUNTRY_INDEX_ANGUILLA, + eCSR_COUNTRY_INDEX_ALBANIA, + eCSR_COUNTRY_INDEX_ARMENIA, + eCSR_COUNTRY_INDEX_NETHERLANDS_ANTILLES, + eCSR_COUNTRY_INDEX_ANGOLA, + eCSR_COUNTRY_INDEX_ANTARCTICA, + eCSR_COUNTRY_INDEX_ARGENTINA, + eCSR_COUNTRY_INDEX_AMERICAN_SAMOA, + eCSR_COUNTRY_INDEX_AUSTRIA, + eCSR_COUNTRY_INDEX_AUSTRALIA, + eCSR_COUNTRY_INDEX_ARUBA, + eCSR_COUNTRY_INDEX_ALAND_ISLANDS, + eCSR_COUNTRY_INDEX_AZERBAIJAN, + eCSR_COUNTRY_INDEX_BOSNIA_AND_HERZEGOVINA, + eCSR_COUNTRY_INDEX_BARBADOS, + eCSR_COUNTRY_INDEX_BANGLADESH, + eCSR_COUNTRY_INDEX_BELGIUM, + eCSR_COUNTRY_INDEX_BURKINA_FASO, + eCSR_COUNTRY_INDEX_BULGARIA, + eCSR_COUNTRY_INDEX_BAHRAIN, + eCSR_COUNTRY_INDEX_BURUNDI, + eCSR_COUNTRY_INDEX_BENIN, + eCSR_COUNTRY_INDEX_SAINT_BARTHELEMY, + eCSR_COUNTRY_INDEX_BERMUDA, + eCSR_COUNTRY_INDEX_BRUNEI_DARUSSALAM, + eCSR_COUNTRY_INDEX_BOLVIA, + eCSR_COUNTRY_INDEX_BRAZIL, + eCSR_COUNTRY_INDEX_BAHAMAS, + eCSR_COUNTRY_INDEX_BHUTAN, + eCSR_COUNTRY_INDEX_BOUVET_ISLAND, + eCSR_COUNTRY_INDEX_BOTSWANA, + eCSR_COUNTRY_INDEX_BELARUS, + eCSR_COUNTRY_INDEX_BELIZE, + eCSR_COUNTRY_INDEX_CANADA, + eCSR_COUNTRY_INDEX_COCOS_KEELING_ISLANDS, + eCSR_COUNTRY_INDEX_CONGO_REP, + eCSR_COUNTRY_INDEX_CENTRAL_AFRICAN, + eCSR_COUNTRY_INDEX_CONGO, + eCSR_COUNTRY_INDEX_SWITZERLAND, + eCSR_COUNTRY_INDEX_COTE_DIVOIRE, + eCSR_COUNTRY_INDEX_COOK_ISLANDS, + eCSR_COUNTRY_INDEX_CHILE, + eCSR_COUNTRY_INDEX_CAMEROON, + eCSR_COUNTRY_INDEX_CHINA, + eCSR_COUNTRY_INDEX_COLUMBIA, + eCSR_COUNTRY_INDEX_COSTA_RICA, + eCSR_COUNTRY_INDEX_CUBA, + eCSR_COUNTRY_INDEX_CAPE_VERDE, + eCSR_COUNTRY_INDEX_CHRISTMAS_ISLAND, + eCSR_COUNTRY_INDEX_CYPRUS, + eCSR_COUNTRY_INDEX_CZECH, + eCSR_COUNTRY_INDEX_GERMANY, + eCSR_COUNTRY_INDEX_DJIBOUTI, + eCSR_COUNTRY_INDEX_DENMARK, + eCSR_COUNTRY_INDEX_DOMINICA, + eCSR_COUNTRY_INDEX_DOMINICAN_REP, + eCSR_COUNTRY_INDEX_ALGERIA, + eCSR_COUNTRY_INDEX_ECUADOR, + eCSR_COUNTRY_INDEX_ESTONIA, + eCSR_COUNTRY_INDEX_EGYPT, + eCSR_COUNTRY_INDEX_WESTERN_SAHARA, + eCSR_COUNTRY_INDEX_ERITREA, + eCSR_COUNTRY_INDEX_SPAIN, + eCSR_COUNTRY_INDEX_ETHIOPIA, + eCSR_COUNTRY_INDEX_FINLAND, + eCSR_COUNTRY_INDEX_FIJI, + eCSR_COUNTRY_INDEX_FALKLAND_ISLANDS, + eCSR_COUNTRY_INDEX_MICRONESIA, + eCSR_COUNTRY_INDEX_FAROE_ISLANDS, + eCSR_COUNTRY_INDEX_FRANCE, + eCSR_COUNTRY_INDEX_GABON, + eCSR_COUNTRY_INDEX_UNITED_KINGDOM, + eCSR_COUNTRY_INDEX_GRENADA, + eCSR_COUNTRY_INDEX_GEORGIA, + eCSR_COUNTRY_INDEX_FRENCH_GUIANA, + eCSR_COUNTRY_INDEX_GUERNSEY, + eCSR_COUNTRY_INDEX_GHANA, + eCSR_COUNTRY_INDEX_GIBRALTAR, + eCSR_COUNTRY_INDEX_GREENLAND, + eCSR_COUNTRY_INDEX_GAMBIA, + eCSR_COUNTRY_INDEX_GUINEA, + eCSR_COUNTRY_INDEX_GUADELOUPE, + eCSR_COUNTRY_INDEX_EQUATORIAL_GUINEA, + eCSR_COUNTRY_INDEX_GREECE, + eCSR_COUNTRY_INDEX_SOUTH_GEORGIA, + eCSR_COUNTRY_INDEX_GUATEMALA, + eCSR_COUNTRY_INDEX_GUAM, + eCSR_COUNTRY_INDEX_GUINEA_BISSAU, + eCSR_COUNTRY_INDEX_GUYANA, + eCSR_COUNTRY_INDEX_HONGKONG, + eCSR_COUNTRY_INDEX_HEARD_ISLAND, + eCSR_COUNTRY_INDEX_HONDURAS, + eCSR_COUNTRY_INDEX_CROATIA, + eCSR_COUNTRY_INDEX_HAITI, + eCSR_COUNTRY_INDEX_HUNGARY, + eCSR_COUNTRY_INDEX_INDONESIA, + eCSR_COUNTRY_INDEX_IRELAND, + eCSR_COUNTRY_INDEX_ISRAEL, + eCSR_COUNTRY_INDEX_ISLE_OF_MAN, + eCSR_COUNTRY_INDEX_INDIA, + eCSR_COUNTRY_INDEX_BRITISH_INDIAN, + eCSR_COUNTRY_INDEX_IRAQ, + eCSR_COUNTRY_INDEX_IRAN, + eCSR_COUNTRY_INDEX_ICELAND, + eCSR_COUNTRY_INDEX_ITALY, + eCSR_COUNTRY_INDEX_JERSEY, + eCSR_COUNTRY_INDEX_JAMAICA, + eCSR_COUNTRY_INDEX_JORDAN, + eCSR_COUNTRY_INDEX_JAPAN, + eCSR_COUNTRY_INDEX_KENYA, + eCSR_COUNTRY_INDEX_KYRGYZSTAN, + eCSR_COUNTRY_INDEX_CAMBODIA, + eCSR_COUNTRY_INDEX_KIRIBATI, + eCSR_COUNTRY_INDEX_COMOROS, + eCSR_COUNTRY_INDEX_SAINT_KITTS_AND_NEVIS, + eCSR_COUNTRY_INDEX_KOREA_NORTH, + eCSR_COUNTRY_INDEX_KOREA_SOUTH, + eCSR_COUNTRY_INDEX_KUWAIT, + eCSR_COUNTRY_INDEX_CAYMAN_ISLANDS, + eCSR_COUNTRY_INDEX_KAZAKHSTAN, + eCSR_COUNTRY_INDEX_LAO, + eCSR_COUNTRY_INDEX_LEBANON, + eCSR_COUNTRY_INDEX_SAINT_LUCIA, + eCSR_COUNTRY_INDEX_LIECHTENSTEIN, + eCSR_COUNTRY_INDEX_SRI_LANKA, + eCSR_COUNTRY_INDEX_LIBERIA, + eCSR_COUNTRY_INDEX_LESOTHO, + eCSR_COUNTRY_INDEX_LITHUANIA, + eCSR_COUNTRY_INDEX_LUXEMBOURG, + eCSR_COUNTRY_INDEX_LATVIA, + eCSR_COUNTRY_INDEX_LIBYAN_ARAB_JAMAHIRIYA, + eCSR_COUNTRY_INDEX_MOROCCO, + eCSR_COUNTRY_INDEX_MONACO, + eCSR_COUNTRY_INDEX_MOLDOVA, + eCSR_COUNTRY_INDEX_MONTENEGRO, + eCSR_COUNTRY_INDEX_MADAGASCAR, + eCSR_COUNTRY_INDEX_MARSHALL_ISLANDS, + eCSR_COUNTRY_INDEX_MACEDONIA, + eCSR_COUNTRY_INDEX_MALI, + eCSR_COUNTRY_INDEX_MYANMAR, + eCSR_COUNTRY_INDEX_MONGOLIA, + eCSR_COUNTRY_INDEX_MACAO, + eCSR_COUNTRY_INDEX_NORTHERN_MARIANA_ISLANDS, + eCSR_COUNTRY_INDEX_MARTINIQUE, + eCSR_COUNTRY_INDEX_MAURITANIA, + eCSR_COUNTRY_INDEX_MONTSERRAT, + eCSR_COUNTRY_INDEX_MALTA, + eCSR_COUNTRY_INDEX_MAURITIUS, + eCSR_COUNTRY_INDEX_MALDIVES, + eCSR_COUNTRY_INDEX_MALAWI, + eCSR_COUNTRY_INDEX_MEXICO, + eCSR_COUNTRY_INDEX_MALAYSIA, + eCSR_COUNTRY_INDEX_MOZAMBIQUE, + eCSR_COUNTRY_INDEX_NAMIBIA, + eCSR_COUNTRY_INDEX_NEW_CALENDONIA, + eCSR_COUNTRY_INDEX_NIGER, + eCSR_COUNTRY_INDEX_NORFOLK_ISLAND, + eCSR_COUNTRY_INDEX_NIGERIA, + eCSR_COUNTRY_INDEX_NICARAGUA, + eCSR_COUNTRY_INDEX_NETHERLANDS, + eCSR_COUNTRY_INDEX_NORWAY, + eCSR_COUNTRY_INDEX_NEPAL, + eCSR_COUNTRY_INDEX_NAURU, + eCSR_COUNTRY_INDEX_NIUE, + eCSR_COUNTRY_INDEX_NEW_ZEALAND, + eCSR_COUNTRY_INDEX_OMAN, + eCSR_COUNTRY_INDEX_PANAMA, + eCSR_COUNTRY_INDEX_PERU, + eCSR_COUNTRY_INDEX_FRENCH_POLYNESIA, + eCSR_COUNTRY_INDEX_PAPUA_NEW_HUINEA, + eCSR_COUNTRY_INDEX_PHILIPPINES, + eCSR_COUNTRY_INDEX_PAKISTAN, + eCSR_COUNTRY_INDEX_POLAND, + eCSR_COUNTRY_INDEX_SAINT_PIERRE_AND_MIQUELON, + eCSR_COUNTRY_INDEX_PITCAIRN, + eCSR_COUNTRY_INDEX_PUERTO_RICO, + eCSR_COUNTRY_INDEX_PALESTINIAN_TERRITOTY_OCCUPIED, + eCSR_COUNTRY_INDEX_PORTUGAL, + eCSR_COUNTRY_INDEX_PALAU, + eCSR_COUNTRY_INDEX_PARAGUAY, + eCSR_COUNTRY_INDEX_QATAR, + eCSR_COUNTRY_INDEX_REUNION, + eCSR_COUNTRY_INDEX_ROMANIA, + eCSR_COUNTRY_INDEX_SERBIA, + eCSR_COUNTRY_INDEX_RUSSIAN, + eCSR_COUNTRY_INDEX_RWANDA, + eCSR_COUNTRY_INDEX_SAUDI_ARABIA, + eCSR_COUNTRY_INDEX_SOLOMON_ISLANDS, + eCSR_COUNTRY_INDEX_SEYCHELLES, + eCSR_COUNTRY_INDEX_SUDAN, + eCSR_COUNTRY_INDEX_SWEDEN, + eCSR_COUNTRY_INDEX_SINGAPORE, + eCSR_COUNTRY_INDEX_SAINT_HELENA, + eCSR_COUNTRY_INDEX_SLOVENIA, + eCSR_COUNTRY_INDEX_SVALBARD_AND_JAN_MAYEN, + eCSR_COUNTRY_INDEX_SLOVAKIA, + eCSR_COUNTRY_INDEX_SIERRA_LEONE, + eCSR_COUNTRY_INDEX_SAN_MARINO, + eCSR_COUNTRY_INDEX_SENEGAL, + eCSR_COUNTRY_INDEX_SOMOLIA, + eCSR_COUNTRY_INDEX_SURINAME, + eCSR_COUNTRY_INDEX_SAO_TOME_AND_PRINCIPE, + eCSR_COUNTRY_INDEX_EL_SALVADOR, + eCSR_COUNTRY_INDEX_SYRIAN_REP, + eCSR_COUNTRY_INDEX_SWAZILAND, + eCSR_COUNTRY_INDEX_TURKS_AND_CAICOS_ISLANDS, + eCSR_COUNTRY_INDEX_CHAD, + eCSR_COUNTRY_INDEX_FRENCH_SOUTHERN_TERRRTORY, + eCSR_COUNTRY_INDEX_TOGO, + eCSR_COUNTRY_INDEX_THAILAND, + eCSR_COUNTRY_INDEX_TAJIKSTAN, + eCSR_COUNTRY_INDEX_TOKELAU, + eCSR_COUNTRY_INDEX_TIMOR_LESTE, + eCSR_COUNTRY_INDEX_TURKMENISTAN, + eCSR_COUNTRY_INDEX_TUNISIA, + eCSR_COUNTRY_INDEX_TONGA, + eCSR_COUNTRY_INDEX_TURKEY, + eCSR_COUNTRY_INDEX_TRINIDAD_AND_TOBAGO, + eCSR_COUNTRY_INDEX_TUVALU, + eCSR_COUNTRY_INDEX_TAIWAN, + eCSR_COUNTRY_INDEX_TANZANIA, + eCSR_COUNTRY_INDEX_UKRAINE, + eCSR_COUNTRY_INDEX_UGANDA, + eCSR_COUNTRY_INDEX_US_MINOR_OUTLYING_ISLANDS, + eCSR_COUNTRY_INDEX_URUGUAY, + eCSR_COUNTRY_INDEX_UZBEKISTAN, + eCSR_COUNTRY_INDEX_HOLY_SEE, + eCSR_COUNTRY_INDEX_SAINT_VINCENT_AND_THE_GRENADINES, + eCSR_COUNTRY_INDEX_VENESUELA, + eCSR_COUNTRY_INDEX_VIRGIN_ISLANDS_BRITISH, + eCSR_COUNTRY_INDEX_VIRGIN_ISLANDS_US, + eCSR_COUNTRY_INDEX_VIET_NAM, + eCSR_COUNTRY_INDEX_VANUATU, + eCSR_COUNTRY_INDEX_WALLIS_AND_FUTUNA, + eCSR_COUNTRY_INDEX_SAMOA, + eCSR_COUNTRY_INDEX_YEMEN, + eCSR_COUNTRY_INDEX_MAYOTTE, + eCSR_COUNTRY_INDEX_SOTHER_AFRICA, + eCSR_COUNTRY_INDEX_ZAMBIA, + eCSR_COUNTRY_INDEX_ZIMBABWE, + + eCSR_COUNTRY_INDEX_KOREA_1, + eCSR_COUNTRY_INDEX_KOREA_2, + eCSR_COUNTRY_INDEX_KOREA_3, + eCSR_COUNTRY_INDEX_KOREA_4, + + eCSR_NUM_COUNTRY_INDEX, +}eCsrCountryIndex; +//Please donot insert in the middle of the enum above because they tie to the indiex + + +typedef struct tagCsrSirMBMsgHdr +{ + tANI_U16 type; + tANI_U16 msgLen; + +}tCsrSirMBMsgHdr; + +typedef struct tagCsrCfgMsgTlvHdr +{ + tANI_U32 type; + tANI_U32 length; + +}tCsrCfgMsgTlvHdr; + + + +typedef struct tagCsrCfgMsgTlv +{ + tCsrCfgMsgTlvHdr Hdr; + tANI_U32 variable[ 1 ]; // placeholder for the data + +}tCsrCfgMsgTlv; + +typedef struct tagCsrCfgGetRsp +{ + tCsrSirMBMsgHdr hdr; + tANI_U32 respStatus; + tANI_U32 paramId; + tANI_U32 attribLen; + tANI_U32 attribVal[1]; +}tCsrCfgGetRsp; + +typedef struct tagCsrCfgSetRsp +{ + + tCsrSirMBMsgHdr hdr; + tANI_U32 respStatus; + tANI_U32 paramId; +}tCsrCfgSetRsp; + + +typedef struct tagCsrDomainChnScanInfo +{ + tANI_U8 chnId; + tSirScanType scanType; //whether this channel must be scan passively +}tCsrDomainChnScanInfo; + + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( push ) +#pragma pack( 1 ) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#pragma pack( 1 ) +#endif + +// Generic Information Element Structure +typedef __ani_attr_pre_packed struct sDot11IEHeader +{ + tANI_U8 ElementID; + tANI_U8 Length; +}__ani_attr_packed tDot11IEHeader; + +typedef __ani_attr_pre_packed struct tagCsrWmeInfoIe +{ + tDot11IEHeader IeHeader; + tANI_U8 Oui[ CSR_WME_OUI_SIZE ]; // includes the 3 byte OUI + 1 byte Type + tANI_U8 Subtype; + tANI_U8 Version; + tANI_U8 QoSInfo; + +} __ani_attr_packed tCsrWmeInfoIe; + +typedef __ani_attr_pre_packed struct tagCsrWmeAcParms +{ + tANI_U8 AciAifsn; + tANI_U8 EcwMinEcwMax; + tANI_U16 TxOpLimit; + +} __ani_attr_packed tCsrWmeAcParms; + +typedef __ani_attr_pre_packed struct tagCsrWmeParmIe +{ + tDot11IEHeader IeHeader; + tANI_U8 Oui[ CSR_WME_OUI_SIZE ]; // includes the 3 byte OUI + 1 byte Type + tANI_U8 Subtype; + tANI_U8 Version; + tANI_U8 QoSInfo; + tANI_U8 Reserved; + tCsrWmeAcParms BestEffort; + tCsrWmeAcParms Background; + tCsrWmeAcParms Video; + tCsrWmeAcParms Voice; + +} __ani_attr_packed tCsrWmeParmIe; + +typedef __ani_attr_pre_packed struct tagCsrWpaIe +{ + tDot11IEHeader IeHeader; + tANI_U8 Oui[ CSR_WPA_OUI_SIZE ]; + tANI_U16 Version; + tANI_U8 MulticastOui[ CSR_WPA_OUI_SIZE ]; + tANI_U16 cUnicastCyphers; + + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WPA_OUI_SIZE ]; + + } __ani_attr_packed UnicastOui[ 1 ]; + +} __ani_attr_packed tCsrWpaIe; + +typedef __ani_attr_pre_packed struct tagCsrWpaAuthIe +{ + + tANI_U16 cAuthenticationSuites; + + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WPA_OUI_SIZE ]; + + } __ani_attr_packed AuthOui[ 1 ]; + +} __ani_attr_packed tCsrWpaAuthIe; + + +typedef __ani_attr_pre_packed struct tagCsrRSNIe +{ + tDot11IEHeader IeHeader; + tANI_U16 Version; + tANI_U8 MulticastOui[ CSR_RSN_OUI_SIZE ]; + tANI_U16 cUnicastCyphers; + + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_RSN_OUI_SIZE ]; + + } __ani_attr_packed UnicastOui[ 1 ]; + +} __ani_attr_packed tCsrRSNIe; + +typedef __ani_attr_pre_packed struct tagCsrRSNAuthIe +{ + tANI_U16 cAuthenticationSuites; + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_RSN_OUI_SIZE ]; + + } __ani_attr_packed AuthOui[ 1 ]; + +} __ani_attr_packed tCsrRSNAuthIe; + +typedef __ani_attr_pre_packed struct tagCsrRSNCapabilities +{ + tANI_U16 PreAuthSupported:1; + tANI_U16 NoPairwise:1; + tANI_U16 PTKSAReplayCounter:2; + tANI_U16 GTKSAReplayCounter:2; + tANI_U16 MFPRequired:1; + tANI_U16 MFPCapable:1; + tANI_U16 Reserved:8; +} __ani_attr_packed tCsrRSNCapabilities; + +typedef __ani_attr_pre_packed struct tagCsrRSNPMKIe +{ + tANI_U16 cPMKIDs; + + __ani_attr_pre_packed struct { + + tANI_U8 PMKID[ CSR_RSN_PMKID_SIZE ]; + + } __ani_attr_packed PMKIDList[ 1 ]; + + +} __ani_attr_packed tCsrRSNPMKIe; + +typedef __ani_attr_pre_packed struct tCsrIELenInfo +{ + tANI_U8 min; + tANI_U8 max; +} __ani_attr_packed tCsrIELenInfo; + +#ifdef FEATURE_WLAN_WAPI +typedef __ani_attr_pre_packed struct tagCsrWapiIe +{ + tDot11IEHeader IeHeader; + tANI_U16 Version; + + tANI_U16 cAuthenticationSuites; + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WAPI_OUI_SIZE ]; + + } __ani_attr_packed AuthOui[ 1 ]; + + tANI_U16 cUnicastCyphers; + __ani_attr_pre_packed struct { + + tANI_U8 Oui[ CSR_WAPI_OUI_SIZE ]; + + } __ani_attr_packed UnicastOui[ 1 ]; + + tANI_U8 MulticastOui[ CSR_WAPI_OUI_SIZE ]; + + __ani_attr_pre_packed struct { + tANI_U16 PreAuthSupported:1; + tANI_U16 Reserved:15; + } __ani_attr_packed tCsrWapiCapabilities; + + +} __ani_attr_packed tCsrWapiIe; + +typedef __ani_attr_pre_packed struct tagCsrWAPIBKIe +{ + tANI_U16 cBKIDs; + __ani_attr_pre_packed struct { + + tANI_U8 BKID[ CSR_WAPI_BKID_SIZE ]; + + } __ani_attr_packed BKIDList[ 1 ]; + + +} __ani_attr_packed tCsrWAPIBKIe; +#endif /* FEATURE_WLAN_WAPI */ + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( pop ) +#endif + +// Structure used to describe a group of continuous channels and hook it into the +// corresponding channel list +typedef struct tagCsrChannelSet +{ + tListElem channelListLink; + tANI_U8 firstChannel; + tANI_U8 interChannelOffset; + tANI_U8 numChannels; + tANI_U8 txPower; +}tCsrChannelSet; + + +typedef struct sDot11InfoIBSSParmSet +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 ATIMWindow; +}tDot11InfoIBSSParmSet; + + +typedef struct sDot11IECountry +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 countryString[3]; + tSirMacChanInfo chanInfo[1]; +}tDot11IECountry; + + +typedef struct sDot11IEExtenedSupportedRates +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 ExtendedSupportedRates[ CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ]; +}tDot11IEExtenedSupportedRates; + +#define CSR_DOT11_AP_NAME_MAX_LENGTH ( 32 ) + +typedef struct tagDot11IEAPName +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 ApName[ CSR_DOT11_AP_NAME_MAX_LENGTH ]; +}tDot11IEAPName; + +typedef struct tagDot11IE11HLocalPowerConstraint +{ + tDot11IEHeader dot11IEHeader; + tANI_U8 localPowerConstraint; + +}tDot11IE11HLocalPowerConstraint; + +typedef struct tagRoamingTimerInfo +{ + tpAniSirGlobal pMac; + tANI_U8 sessionId; +} tCsrTimerInfo; + + +#define CSR_IS_11A_BSS(pBssDesc) ( eSIR_11A_NW_TYPE == (pBssDesc)->nwType ) +#define CSR_IS_BASIC_RATE(rate) ((rate) & CSR_DOT11_BASIC_RATE_MASK) +#define CSR_IS_QOS_BSS(pIes) ( (pIes)->WMMParams.present || (pIes)->WMMInfoAp.present ) + +#define CSR_IS_UAPSD_BSS(pIes) \ + ( ((pIes)->WMMParams.present && ((pIes)->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD)) || \ + ((pIes)->WMMInfoAp.present && (pIes)->WMMInfoAp.uapsd) ) + +//This macro returns the total length needed of Tlv with with len bytes of data +#define GET_TLV_MSG_LEN(len) GET_ROUND_UP((sizeof(tCsrCfgMsgTlvHdr) + (len)), sizeof(tANI_U32)) + +tANI_BOOLEAN csrGetBssIdBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tCsrBssid *pBssId ); +tANI_BOOLEAN csrIsBssIdEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ); + +eCsrMediaAccessType csrGetQoSFromBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes); +tANI_BOOLEAN csrIsNULLSSID( tANI_U8 *pBssSsid, tANI_U8 len ); +tANI_BOOLEAN csrIsInfraBssDesc( tSirBssDescription *pSirBssDesc ); +tANI_BOOLEAN csrIsIbssBssDesc( tSirBssDescription *pSirBssDesc ); +tANI_BOOLEAN csrIsPrivacy( tSirBssDescription *pSirBssDesc ); +tSirResultCodes csrGetDisassocRspStatusCode( tSirSmeDisassocRsp *pSmeDisassocRsp ); +tSirResultCodes csrGetDeAuthRspStatusCode( tSirSmeDeauthRsp *pSmeRsp ); +tANI_U32 csrGetFragThresh( tHalHandle hHal ); +tANI_U32 csrGetRTSThresh( tHalHandle hHal ); +eCsrPhyMode csrGetPhyModeFromBssDesc( tSirBssDescription *pSirBssDesc ); +tANI_U32 csrGet11hPowerConstraint( tHalHandle hHal, tDot11fIEPowerConstraints *pPowerConstraint ); +tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe ); +tANI_U8 csrConstructWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ); +#ifdef FEATURE_WLAN_WAPI + +tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile ); +#endif /* FEATURE_WLAN_WAPI */ +//If a WPAIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ); +tANI_BOOLEAN csrIsSsidEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 ); +//Null ssid means match +tANI_BOOLEAN csrIsSsidInList( tHalHandle hHal, tSirMacSSid *pSsid, tCsrSSIDs *pSsidList ); +tANI_BOOLEAN csrIsProfileWpa( tCsrRoamProfile *pProfile ); +tANI_BOOLEAN csrIsProfileRSN( tCsrRoamProfile *pProfile ); +//This function returns the raw byte array of WPA and/or RSN IE +tANI_BOOLEAN csrGetWpaRsnIe( tHalHandle hHal, tANI_U8 *pIes, tANI_U32 len, + tANI_U8 *pWpaIe, tANI_U8 *pcbWpaIe, tANI_U8 *pRSNIe, tANI_U8 *pcbRSNIe); +//If a RSNIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveRsnIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe ); +#ifdef FEATURE_WLAN_WAPI +//If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE +tANI_U8 csrRetrieveWapiIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ); +#endif /* FEATURE_WLAN_WAPI */ +tANI_BOOLEAN csrSearchChannelListForTxPower(tHalHandle hHal, tSirBssDescription *pBssDescription, tCsrChannelSet *returnChannelGroup); +tANI_BOOLEAN csrRatesIsDot11Rate11bSupportedRate( tANI_U8 dot11Rate ); +tANI_BOOLEAN csrRatesIsDot11Rate11aSupportedRate( tANI_U8 dot11Rate ); +tAniEdType csrTranslateEncryptTypeToEdType( eCsrEncryptionType EncryptType ); +//pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs +tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType, + tCsrEncryptionList *pUCEncryptionType, + tCsrEncryptionList *pMCEncryptionType, + tANI_BOOLEAN *pMFPEnabled, + tANI_U8 *pMFPRequired, + tANI_U8 *pMFPCapable, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, + eCsrAuthType *negotiatedAuthtype, eCsrEncryptionType *negotiatedUCCipher, eCsrEncryptionType *negotiatedMCCipher ); +tANI_BOOLEAN csrIsBSSTypeMatch(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2); +tANI_BOOLEAN csrIsBssTypeIBSS(eCsrRoamBssType bssType); +tANI_BOOLEAN csrIsBssTypeWDS(eCsrRoamBssType bssType); +//ppIes can be NULL. If caller want to get the *ppIes allocated by this function, pass in *ppIes = NULL +//Caller needs to free the memory in this case +tANI_BOOLEAN csrMatchBSS( tHalHandle hHal, tSirBssDescription *pBssDesc, tCsrScanResultFilter *pFilter, + eCsrAuthType *pNegAuth, eCsrEncryptionType *pNegUc, eCsrEncryptionType *pNegMc, + tDot11fBeaconIEs **ppIes); + +tANI_BOOLEAN csrIsBssidMatch( tHalHandle hHal, tCsrBssid *pProfBssid, tCsrBssid *BssBssid ); +tANI_BOOLEAN csrMatchBSSToConnectProfile( tHalHandle hHal, tCsrRoamConnectedProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ); + +void csrAddRateBitmap(tANI_U8 rate, tANI_U16 *pRateBitmap); +tANI_BOOLEAN csrIsRateAlreadyPresent(tANI_U8 rate, tANI_U16 RateBitmap); + +tANI_BOOLEAN csrRatesIsDot11RateSupported( tHalHandle hHal, tANI_U8 rate ); +tANI_U16 csrRatesFindBestRate( tSirMacRateSet *pSuppRates, tSirMacRateSet *pExtRates, tSirMacPropRateSet *pPropRates ); +tSirBssType csrTranslateBsstypeToMacType(eCsrRoamBssType csrtype); + +//Caller allocates memory for pIEStruct +eHalStatus csrParseBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIEStruct); +//This function will allocate memory for the parsed IEs to the caller. Caller must free the memory +//after it is done with the data only if this function succeeds +eHalStatus csrGetParsedBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs **ppIEStruct); + +tANI_BOOLEAN csrValidateCountryString( tHalHandle hHal, tANI_U8 *pCountryString ); +tSirScanType csrGetScanType(tpAniSirGlobal pMac, tANI_U8 chnId); + +tANI_U8 csrToUpper( tANI_U8 ch ); +eHalStatus csrGetPhyModeFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription, + eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes); + +//fForce -- force reassoc regardless of whether there is any change +//The reason is that for UAPSD-bypass, the code underneath this call determine whether +//to allow UAPSD. The information in pModProfileFields reflects what the user wants. +//There may be discrepency in it. UAPSD-bypass logic should decide if it needs to reassoc +eHalStatus csrReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce); + +eHalStatus +csrIsconcurrentsessionValid(tpAniSirGlobal pMac,tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona); + +//Update beaconInterval for P2P-GO case if it is different +eHalStatus csrUpdatep2pBeaconInterval(tpAniSirGlobal pMac); + +//BeaconInterval validation for MCC support +eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, + tANI_U16 *beaconInterval, tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona); + +#ifdef WLAN_FEATURE_VOWIFI_11R +tANI_BOOLEAN csrIsProfile11r( tCsrRoamProfile *pProfile ); +tANI_BOOLEAN csrIsAuthType11r( eCsrAuthType AuthType, tANI_U8 mdiePresent); +#endif + +#ifdef FEATURE_WLAN_ESE +tANI_BOOLEAN csrIsAuthTypeESE( eCsrAuthType AuthType ); +tANI_BOOLEAN csrIsProfileESE( tCsrRoamProfile *pProfile ); +#endif + +#endif + diff --git a/drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h b/drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h new file mode 100644 index 000000000000..aa0bcbcaa973 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/csr_roam_mbb.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac); + +eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal, + tANI_U32 session_id, tpSirBssDescription bss_description); + +void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal, + tpSirFTPreAuthRsp pre_auth_rsp); + +void csr_preauth_reassoc_mbb_timer_callback(void *context); + +void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac); + diff --git a/drivers/staging/prima/CORE/SME/inc/nan_Api.h b/drivers/staging/prima/CORE/SME/inc/nan_Api.h new file mode 100644 index 000000000000..8e49cf0df7cb --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/nan_Api.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: nan_Api.h +* +* Description: NAN FSM defines. +* +******************************************************************************/ + +#ifndef __NAN_API_H__ +#define __NAN_API_H__ + +#include "vos_types.h" +#include "halTypes.h" + +typedef struct sNanRequestReq +{ + tANI_U16 request_data_len; + const tANI_U8* request_data; +} tNanRequestReq, *tpNanRequestReq; + +/****************************************************************************** + * Function: Pointer NanCallback + * + * Description: + * this function pointer is used hold nan response callback. When ever driver + * receives nan response, this callback will be used. + * + * Args: + * first argument to pass hHal pointer and second argument + * to pass the nan response data. + * + * Returns: + * void +******************************************************************************/ +typedef void (*NanCallback)(void*, tSirNanEvent*); + +/****************************************************************************** + * Function: sme_NanRegisterCallback + * + * Description: + * This function gets called when HDD wants register nan rsp callback with + * sme layer. + * + * Args: + * hHal and callback which needs to be registered. + * + * Returns: + * void +******************************************************************************/ +void sme_NanRegisterCallback(tHalHandle hHal, NanCallback callback); + +/****************************************************************************** + * Function: sme_NanRequest + * + * Description: + * This function gets called when HDD receives NAN vendor command + * from userspace + * + * Args: + * hHal, Nan Request structure ptr and sessionId + * + * Returns: + * VOS_STATUS +******************************************************************************/ +VOS_STATUS sme_NanRequest(tHalHandle hHalHandle, tpNanRequestReq input, + tANI_U32 sessionId); + +/****************************************************************************** + \fn sme_NanEvent + + \brief + a callback function called when SME received eWNI_SME_NAN_EVENT + event from WDA + + \param hHal - HAL handle for device + \param pMsg - Message body passed from WDA; includes NAN header + + \return VOS_STATUS +******************************************************************************/ +VOS_STATUS sme_NanEvent(tHalHandle hHal, void* pMsg); + +#endif /* __NAN_API_H__ */ diff --git a/drivers/staging/prima/CORE/SME/inc/oemDataApi.h b/drivers/staging/prima/CORE/SME/inc/oemDataApi.h new file mode 100644 index 000000000000..fa8dccc29d39 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/oemDataApi.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file oemDataApi.h + + Exports and types for the Common OEM DATA REQ/RSP Module interfaces. + + Copyright (C) 2010 Qualcomm Inc. + + + ========================================================================== */ + +#ifndef __OEM_DATA_API_H__ +#define __OEM_DATA_API_H__ +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "csrLinkList.h" + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif + +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +#ifndef NEW_OEM_DATA_REQ_SIZE +#define NEW_OEM_DATA_REQ_SIZE 292 +#endif + +#ifndef NEW_OEM_DATA_RSP_SIZE +#define NEW_OEM_DATA_RSP_SIZE 2100 +#endif + +/************************************************************************************************************* + OEM DATA REQ/RSP - DATA STRUCTURES +*************************************************************************************************************/ + +/* Structure for defining req sent to the PE */ +typedef struct tagOemDataReq +{ + tANI_U8 sessionId; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tOemDataReq, tOemDataReqConfig; + +/************************************************************************************************************* + OEM DATA RESPONSE - DATA STRUCTURES +*************************************************************************************************************/ +typedef struct tagOemDataRsp +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tOemDataRsp; + +/*************************************************************************************************************/ + +typedef enum +{ + eOEM_DATA_REQ_SUCCESS=1, + eOEM_DATA_REQ_FAILURE, + eOEM_DATA_REQ_INVALID_MODE, +} eOemDataReqStatus; + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqOpen + \brief This function must be called before any API call to MEAS (OEM DATA REQ/RSP module) + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqOpen(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqClose + \brief This function must be called before closing the csr module + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqClose(tHalHandle hHal); + +/* HDD Callback function for the sme to callback when the oem data rsp is available */ +typedef eHalStatus (*oemData_OemDataReqCompleteCallback)( + tHalHandle, + void* p2, + tANI_U32 oemDataReqID, + eOemDataReqStatus status); + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReq + \brief Request an OEM DATA RSP + \param sessionId - Id of session to be used + \param pOemDataReqID - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_OemDataReq(tHalHandle, tANI_U8, tOemDataReqConfig *, tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, void *pContext); + +/* --------------------------------------------------------------------------- + \fn sme_HandleOemDataRsp + \brief This function processes the oem data response obtained from the PE + \param pMsg - Pointer to the pSirSmeOemDataRsp + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8*); + +/* --------------------------------------------------------------------------- + \fn oemData_IsOemDataReqAllowed + \brief This function checks if oem data req/rsp can be performed in the + current driver state + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal); + + +/* --------------------------------------------------------------------------- + OEM DATA REQ NEW - DATA STRUCTURES + -------------------------------------------------------------------------------*/ +/* Structure for defining req sent to the PE */ +typedef struct tagOemDataReqNew +{ + tSirMacAddr selfMacAddr; + tANI_U8 reserved[2]; + tANI_U8 oemDataReqNew[NEW_OEM_DATA_REQ_SIZE]; +} tOemDataReqNew, tOemDataReqNewConfig; + +/* --------------------------------------------------------------------------- + OEM DATA RESPONSE - DATA STRUCTURES + -------------------------------------------------------------------------------*/ +typedef struct tagOemDataRspNew +{ + tANI_U8 oemDataRspNew[NEW_OEM_DATA_RSP_SIZE]; +} tOemDataRspNew; + +/*************************************************************************************************************/ + +void send_oem_data_rsp_msg(tANI_U32 length, tANI_U8 *oemDataRsp); + +#endif //_OEM_DATA_API_H__ + +#endif //FEATURE_OEM_DATA_SUPPORT diff --git a/drivers/staging/prima/CORE/SME/inc/oemDataInternal.h b/drivers/staging/prima/CORE/SME/inc/oemDataInternal.h new file mode 100644 index 000000000000..8099f9dd5d77 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/oemDataInternal.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file oemDataInternal.h + + Exports and types for the Common OEM DATA REQ/RSP Module interfaces. + + Copyright (C) 2010 Qualcomm Inc. + + ========================================================================== */ + + +#ifndef __OEM_DATA_INTERNAL_H__ +#define __OEM_DATA_INTERNAL_H__ + +#include "palTimer.h" +#include "csrSupport.h" +#include "vos_nvitem.h" +#include "wlan_qct_tl.h" + +#include "oemDataApi.h" + +typedef struct tagOemDataStruct +{ + tANI_U32 nextOemReqId; //a global req id + tANI_BOOLEAN oemDataReqActive; //indicates that currently a request has been posted and + //waiting for the response + oemData_OemDataReqCompleteCallback callback; //callback function pointer for returning the response + void* pContext; //context of the original caller + tANI_U32 oemDataReqID; //original request ID + tOemDataRsp* pOemDataRsp; //response + tOemDataReqConfig oemDataReqConfig; //current oem data request + tANI_U8 sessionId; //Session on which oem data req is active +} tOemDataStruct; + +typedef struct tagOemDataCmd +{ + tANI_U32 oemDataReqID; + oemData_OemDataReqCompleteCallback callback; + void* pContext; + tOemDataReq oemDataReq; +} tOemDataCmd; + +#endif //__OEM_DATA_INTERNAL_H__ + +#endif //FEATURE_OEM_DATA_SUPPORT diff --git a/drivers/staging/prima/CORE/SME/inc/p2p_Api.h b/drivers/staging/prima/CORE/SME/inc/p2p_Api.h new file mode 100644 index 000000000000..5e38b73836a5 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/p2p_Api.h @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: p2p_Api.h +* +* Description: P2P FSM defines. +* +* +******************************************************************************/ + +#ifndef __P2P_API_H__ +#define __P2P_API_H__ + +#include "vos_types.h" +#include "halTypes.h" +#include "palTimer.h" +#include "vos_lock.h" + +typedef struct sP2pPsConfig{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; + tANI_U8 sessionid; +}tP2pPsConfig,*tpP2pPsConfig; + +typedef eHalStatus (*remainOnChanCallback)( tHalHandle, void* context, + eHalStatus status ); + +typedef struct sRemainOnChn{ + tANI_U8 chn; + tANI_U32 duration; + remainOnChanCallback callback; + void *pCBContext; +}tRemainOnChn, tpRemainOnChn; + +#define SIZE_OF_NOA_DESCRIPTOR 13 +#define MAX_NOA_PERIOD_IN_MICROSECS 3000000 + +#define P2P_CLEAR_POWERSAVE 0 +#define P2P_OPPORTUNISTIC_PS 1 +#define P2P_PERIODIC_NOA 2 +#define P2P_SINGLE_NOA 4 + +#ifdef WLAN_FEATURE_P2P_INTERNAL + +#define MAX_SOCIAL_CHANNELS 3 +#define P2P_OPERATING_CHANNEL 6 +#define P2P_MAX_GROUP_LIMIT 5 +#define P2P_MAC_ADDRESS_LEN 6 +#define MAX_LISTEN_SEARCH_CYCLE 3 +#define P2P_LISTEN_TIMEOUT_AUTO 500 //0.5 sec +#define P2P_LISTEN_TIMEOUT_HIGH 200 //0.4 sec +#define P2P_LISTEN_TIMEOUT 1000 //1 sec +#define P2P_REMAIN_ON_CHAN_TIMEOUT 300 +#define P2P_REMAIN_ON_CHAN_TIMEOUT_HIGH 1000 +#define P2P_REMAIN_ON_CHAN_TIMEOUT_LOW 100 +#define ACTION_FRAME_RETRY_TIMEOUT 50 +#define P2P_COUNTRY_CODE_LEN 3 + +/* Wi-Fi Direct Device Discovery Type */ +typedef enum ep2pDiscoverType { + /** Driver must perform device discovery only using the scan phase*/ + WFD_DISCOVER_TYPE_SCAN_ONLY = 1, + /** Driver must perform device discovery only using the find phase*/ + WFD_DISCOVER_TYPE_FIND_ONLY = 2, + /** Driver can use either use scan phase or find phase to discovery + P2P devices. In our case Driver uses scan phase */ + WFD_DISCOVER_TYPE_AUTO = 3, + /*Scan only social channel*/ + WFD_DISCOVER_SCAN_ONLY_SOCIAL_CHN, + /** If it is set, driver must perform a complete discovery, + If it is false, it can do partial discovery.*/ + WFD_DISCOVER_TYPE_FORCED = 0x80000000 +} ep2pDiscoverType, *ePp2pDiscoverType; + +//bit mask for what to discover +#define QCWLAN_P2P_DISCOVER_DEVICE 0x1 +#define QCWLAN_P2P_DISCOVER_GO 0x2 +#define QCWLAN_P2P_DISCOVER_ANY 0x8 + +#define P2P_DISCOVER_SCAN_ONLY(t) ( (WFD_DISCOVER_TYPE_SCAN_ONLY == (t)) \ + || (WFD_DISCOVER_SCAN_ONLY_SOCIAL_CHN == (t)) ) + +/* Scan Type */ +typedef enum ep2pScanType { + P2P_SCAN_TYPE_ACTIVE = 1, /** device should perform active scans for the scan phase of device discovery */ + P2P_SCAN_TYPE_PASSIVE = 2, /** device should perform passive scanning for the scan phase of device discovery */ + P2P_SCAN_TYPE_AUTO = 3 /** The selection of the scan type is upto the driver */ +} ep2pScanType, * ePp2pScanType; + +/** Listen State Discoverability */ +typedef enum ep2pListenStateDiscoverability { + P2P_DEVICE_NOT_DISCOVERABLE, /** Wi-Fi Direct Device Port must not make itself discoverable */ + P2P_DEVICE_AUTO_AVAILABILITY, /** Wi-Fi Direct Device Port must periodically put itself in the listen state to become discoverable*/ + P2P_DEVICE_HIGH_AVAILABILITY /** Wi-Fi Direct Device Port must be frequently put itself in the listen state + to increase the speed and reliability of remote devices discovering it */ +} ep2pListenStateDiscoverability, * ePp2pListenStateDiscoverability; + +typedef enum ep2pOperatingMode { + OPERATION_MODE_INVALID, + OPERATION_MODE_P2P_DEVICE, + OPERATION_MODE_P2P_GROUP_OWNER, + OPERATION_MODE_P2P_CLIENT +}ep2pOperatingMode; + +typedef struct _tp2pDiscoverDeviceFilter{ + tSirMacAddr DeviceID; + v_UCHAR_t ucBitmask; + tSirMacSSid GroupSSID; +} tp2pDiscoverDeviceFilter; + +typedef struct _tp2pDiscoverRequest { + ep2pDiscoverType discoverType; + ep2pScanType scanType; + tANI_U32 uDiscoverTimeout; + tANI_U32 uNumDeviceFilters; + tp2pDiscoverDeviceFilter *pDeviceFilters; + tANI_BOOLEAN bForceScanLegacyNetworks; + tANI_U32 uNumOfLegacySSIDs; + tANI_U8 *pLegacySSIDs; + tANI_U32 uIELen; + tANI_U8 *pIEField; +} tP2PDiscoverRequest; + +typedef enum _eP2PDiscoverStatus { + eP2P_DISCOVER_SUCCESS, + eP2P_DISCOVER_FAILURE, + eP2P_DISCOVER_ABORT, + eP2P_DIRECTED_DISCOVER +} eP2PDiscoverStatus; + +typedef eHalStatus (*p2pDiscoverCompleteCallback)(tHalHandle hHal, void *pContext, eP2PDiscoverStatus discoverStatus); + +typedef struct sP2PGroupId { + tANI_U8 present; + tANI_U8 deviceAddress[6]; + tANI_U8 num_ssid; + tANI_U8 ssid[32]; +} tP2PGroupId; + +typedef struct sP2PGroupBssid { + tANI_U8 present; + tANI_U8 P2PGroupBssid[6]; +} tP2PGroupBssid; + +typedef struct sP2PChannel { + tANI_U8 present; + tANI_U8 countryString[P2P_COUNTRY_CODE_LEN]; + tANI_U8 regulatoryClass; + tANI_U8 channel; +} tP2P_OperatingChannel, tP2P_ListenChannel; + +/** Structure contains parameters required for Wi-Fi Direct Device functionality such as device discovery, Group Owner Negotiation */ +typedef enum P2PFrameType { + eP2P_INVALID_FRM, + eP2P_PROBE_REQ, + eP2P_PROBE_RSP, + eP2P_GONEGO_REQ, + eP2P_GONEGO_RES, + eP2P_GONEGO_CNF, + eP2P_PROVISION_DISCOVERY_REQUEST, + eP2P_PROVISION_DISCOVERY_RESPONSE, + eP2P_BEACON, + eP2P_GROUP_ID, + eP2P_ASSOC_REQ, + eP2P_INVITATION_REQ, + eP2P_INVITATION_RSP, + eP2P_DEVICE_DISCOVERY_REQ, + eP2P_DEVICE_DISCOVERY_RSP, +} eP2PFrameType; + +typedef enum P2PRequest { + eWFD_DISCOVER_REQUEST, + eWFD_DEVICE_ID, + eWFD_DEVICE_CAPABILITY, + eWFD_GROUP_OWNER_CAPABILITY, + eWFD_DEVICE_INFO, + eWFD_SECONDARY_DEVICE_TYPE_LIST, + eWFD_ADDITIONAL_IE, + eWFD_GROUP_ID, + eWFD_SEND_GO_NEGOTIATION_REQUEST, + eWFD_SEND_GO_NEGOTIATION_RESPONSE, + eWFD_SEND_GO_NEGOTIATION_CONFIRMATION, + eWFD_SEND_PROVISION_DISCOVERY_REQUEST, + eWFD_SEND_PROVISION_DISCOVERY_RESPONSE, + eWFD_SEND_INVITATION_REQUEST, + eWFD_SEND_INVITATION_RESPONSE, + eWFD_OPERATING_CHANNEL, + eWFD_LISTEN_CHANNEL +} eP2PRequest; + +typedef struct _p2p_device_capability_config { + tANI_BOOLEAN bServiceDiscoveryEnabled; + tANI_BOOLEAN bClientDiscoverabilityEnabled; + tANI_BOOLEAN bConcurrentOperationSupported; + tANI_BOOLEAN bInfrastructureManagementEnabled; + tANI_BOOLEAN bDeviceLimitReached; + tANI_BOOLEAN bInvitationProcedureEnabled; + tANI_U32 WPSVersionsEnabled; +} tp2p_device_capability_config; + +typedef struct _p2p_group_owner_capability_config { + tANI_BOOLEAN bPersistentGroupEnabled; + tANI_BOOLEAN bIntraBSSDistributionSupported; + tANI_BOOLEAN bCrossConnectionSupported; + tANI_BOOLEAN bPersistentReconnectSupported; + tANI_BOOLEAN bGroupFormationEnabled; + tANI_U32 uMaximumGroupLimit; +} tp2p_group_owner_capability_config; + +typedef struct _tP2P_ProvDiscoveryReq { + tANI_U8 dialogToken; + tANI_U8 PeerDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U32 uSendTimeout; + tANI_U8 GroupCapability; + tP2PGroupId GroupId; + tANI_BOOLEAN bUseGroupID; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_ProvDiscoveryReq; + +typedef struct _tP2P_ProvDiscoveryRes { + tANI_U8 dialogToken; + tANI_U8 ReceiverDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U32 uSendTimeout; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_ProvDiscoveryRes; + +typedef struct p2p_go_request { + tANI_U8 dialogToken; + tANI_U8 peerDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U32 uSendTimeout; + tANI_U8 GoIntent; + tANI_U32 GoTimeout; + tANI_U32 ClientTimeout; + tANI_U8 IntendedInterfaceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 GroupCapability; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_go_request; + +typedef struct p2p_go_confirm { + tANI_U8 peerDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 dialog_token; + tANI_U32 uSendTimeout; + tANI_U8 status; + tANI_U8 GroupCapability; + tP2PGroupId GroupId; + tANI_BOOLEAN bUsedGroupId; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_go_confirm; + +typedef struct p2p_go_response { + tANI_U8 peerDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 dialog_token; + tANI_U32 uSendTimeout; + tANI_U8 status; + tANI_U8 GoIntent; + tANI_U32 GoTimeout; + tANI_U32 ClientTimeout; + tANI_U8 IntendedInterfaceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 GroupCapability; + tP2PGroupId GroupId; + tANI_BOOLEAN bUsedGroupId; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_go_response; + +//Invitation Req parameters +typedef struct p2p_invitation_request { + tANI_U8 DialogToken; + tANI_U8 PeerDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U32 uSendTimeout; + tANI_U32 GoTimeout; + tANI_U32 ClientTimeout; + tANI_U8 InvitationFlags; + tP2PGroupBssid GroupBSSID; + tP2P_OperatingChannel OperatingChannel; + tP2PGroupId GroupID; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_invitation_request; + + +//Invitation Response parameters +typedef struct p2p_invitation_response { + tANI_U8 ReceiverDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 DialogToken; + void* RequestContext; + tANI_U32 uSendTimeout; + tANI_U8 status; + tANI_U32 GoTimeout; + tANI_U32 ClientTimeout; + tP2PGroupBssid GroupBSSID; + tP2P_OperatingChannel OperatingChannel; + tANI_U32 uIELength; + tANI_U8 *IEdata; +} tP2P_invitation_response; + +typedef enum eOUISubType { + eOUI_P2P_GONEGO_REQ, + eOUI_P2P_GONEGO_RES, + eOUI_P2P_GONEGO_CNF, + eOUI_P2P_INVITATION_REQ, + eOUI_P2P_INVITATION_RES, + eOUI_P2P_DEVICE_DISCOVERABILITY_REQ, + eOUI_P2P_DEVICE_DISCOVERABILITY_RES, + eOUI_P2P_PROVISION_DISCOVERY_REQ, + eOUI_P2P_PROVISION_DISCOVERY_RES, + eOUI_P2P_INVALID +}eOUISubType; + +typedef enum _eP2PPort { + eP2PPortDevice, + eP2PPortGroupOwner, + eP2PPortClient +} eP2PPort; + +typedef enum eListenDiscoverableState { + eStateDisabled, + eStateEnabled, + +}eListenDiscoverableState; + +typedef enum P2PRemainOnChnReason +{ + eP2PRemainOnChnReasonUnknown, + eP2PRemainOnChnReasonDiscovery, //Part of the discovery (search and listen) + eP2PRemainOnChnReasonSendFrame, //Found peer and before sending request frame + eP2PRemainOnChnReasonListen, //In listen-only mode +}eP2PRemainOnChnReason; + +typedef struct sGroupFormationReq { + tCsrBssid deviceAddress; + tANI_U8 targetListenChannel; + tANI_U8 persistent_group; + tANI_U8 group_limit; /* may be internal */ + tANI_U8 GO_config_timeout; + tANI_U8 CL_config_timeout; + tANI_U8 GO_intent; + tANI_U16 devicePasswdId; + tSirMacAddr groupBssid; + tSirMacSSid groupSsid; +}tGroupFormationReq; + +typedef struct tP2PConfigParam +{ + v_U32_t P2POperatingChannel; + v_U32_t P2PListenChannel; + v_U32_t P2PPSSelection; + v_U32_t P2POpPSCTWindow; + v_U32_t P2PNoADuration; + v_U32_t P2PNoACount; + v_U32_t P2PNoAInterval; +}tP2PConfigParam; + +#endif + +typedef struct sp2pContext +{ + v_CONTEXT_t vosContext; + tHalHandle hHal; + tANI_U8 sessionId; //Session id corresponding to P2P. On windows it is same as HDD sessionid not sme sessionid. + tANI_U8 SMEsessionId; + tANI_U8 probeReqForwarding; + tANI_U8 *probeRspIe; + tANI_U32 probeRspIeLength; +#ifdef WLAN_FEATURE_P2P_INTERNAL + tANI_U8 numClients; + tANI_U32 maxGroupLimit; + ep2pOperatingMode operatingmode; + tANI_U8 state; + tANI_U8 socialChannel[MAX_SOCIAL_CHANNELS]; + tANI_U8 currentSearchIndex; + tANI_U8 listenIndex; + tANI_U8 dialogToken; + tANI_U8 receivedDialogToken; + eOUISubType actionFrameOUI; + eP2PFrameType actionFrameType; + tANI_BOOLEAN actionFrameTimeout; + tANI_U8 *pSentActionFrame; + tANI_U32 ActionFrameLen; + tANI_U32 ActionFrameSendTimeout; + eListenDiscoverableState listenDiscoverableState; + vos_timer_t listenTimerHandler; + vos_timer_t WPSRegistrarCheckTimerHandler; + tANI_U32 WPSRegistrarSet; + tANI_U8 bWaitForWPSReady; + tANI_U8 bInGroupFormation; + vos_timer_t discoverTimer; + vos_timer_t retryActionFrameTimer; + vos_timer_t actionFrameTimer; + tPalTimerHandle nextActionFrameTimer; + tANI_U8 peerMacAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 selfMacAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 ReceiverDeviceAddress[P2P_MAC_ADDRESS_LEN]; + tANI_U8 listen_search_cycle; + ep2pDiscoverType discoverType; + ep2pScanType scanType; + tANI_U32 uDiscoverTimeout; + tp2pDiscoverDeviceFilter *directedDiscoveryFilter; + tANI_U32 uNumDeviceFilters; + //Number of deviceFilter directedDiscoveryFilter holds + tANI_U32 uNumDeviceFilterAllocated; + tGroupFormationReq formationReq; + tANI_U8 GroupFormationPending; + tANI_BOOLEAN PeerFound; + tANI_BOOLEAN directedDiscovery; + tANI_U32 listenDuration; + tANI_U32 expire_time; + p2pDiscoverCompleteCallback p2pDiscoverCBFunc; + void *pContext; + tANI_BOOLEAN bForceScanLegacyNetworks; + tANI_U8 *DiscoverReqIeField; + tANI_U32 DiscoverReqIeLength; + tANI_U8 *GoNegoReqIeField; + tANI_U32 GoNegoReqIeLength; + tANI_U8 *GoNegoResIeField; + tANI_U32 GoNegoResIeLength; + tANI_U8 *GoNegoCnfIeField; + tANI_U32 GoNegoCnfIeLength; + tANI_U8 *ProvDiscReqIeField; + tANI_U32 ProvDiscReqIeLength; + tANI_U8 *ProvDiscResIeField; + tANI_U32 ProvDiscResIeLength; + tANI_U8 *InvitationReqIeField; + tANI_U32 InvitationReqIeLength; + tANI_U8 *InvitationResIeField; + tANI_U32 InvitationResIeLength; + tANI_U32 DiscoverableCfg; + vos_spin_lock_t lState; + tANI_U8 *pNextActionFrm; + tANI_U32 nNextFrmLen; + tANI_U32 nNextFrameTimeOut; + eP2PFrameType NextActionFrameType; + tANI_U8 ssid[32]; + v_U32_t P2PListenChannel; + v_U32_t P2POperatingChannel; + tP2pPsConfig pNoA; + tANI_U8 OriginalGroupCapability; +#endif +} tp2pContext, *tPp2pContext; + +eHalStatus sme_RemainOnChannel( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, + tANI_U8 isP2PProbeReqAllowed); +eHalStatus sme_ReportProbeReq( tHalHandle hHal, tANI_U8 flag ); +eHalStatus sme_updateP2pIe( tHalHandle hHal, void *p2pIe, + tANI_U32 p2pIeLength ); +eHalStatus sme_sendAction( tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, + tANI_U16 wait, tANI_BOOLEAN noack); +eHalStatus sme_CancelRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId ); +eHalStatus sme_p2pOpen( tHalHandle hHal ); +eHalStatus p2pStop( tHalHandle hHal ); +eHalStatus sme_p2pClose( tHalHandle hHal ); +eHalStatus sme_p2pSetPs( tHalHandle hHal, tP2pPsConfig * data ); +#ifdef WLAN_FEATURE_P2P_INTERNAL +eHalStatus p2pRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, void *pContext, + tANI_U8 isP2PProbeReqAllowed, + eP2PRemainOnChnReason reason); +#else +eHalStatus p2pRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, + tANI_U8 isP2PProbeReqAllowed); +#endif +eHalStatus p2pSendAction( tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, + tANI_U16 wait, tANI_BOOLEAN noack); +eHalStatus p2pCancelRemainOnChannel( tHalHandle hHal, tANI_U8 sessionId ); +eHalStatus p2pSetPs( tHalHandle hHal, tP2pPsConfig *pNoA ); +tSirRFBand GetRFBand(tANI_U8 channel); +#ifdef WLAN_FEATURE_P2P_INTERNAL +eHalStatus p2pRemainOnChannelCallback(tHalHandle halHandle, void *pContext, eHalStatus scan_status); +eHalStatus P2P_DiscoverRequest(tHalHandle hHal, tANI_U8 SessionID, tP2PDiscoverRequest *pDiscoverRequest, + p2pDiscoverCompleteCallback callback, void *pContext); +tANI_U8 p2pGetDialogToken(tHalHandle hHal, tANI_U8 SessionID, eP2PFrameType actionFrameType); +eHalStatus P2P_ListenStateDiscoverable(tHalHandle hHal, tANI_U8 sessionId, ep2pListenStateDiscoverability listenState); +eHalStatus p2pCreateSendActionFrame(tHalHandle hHal, tANI_U8 SessionID, + void *p2pactionframe, eP2PFrameType actionFrameType, tANI_U32 timeout); +eHalStatus p2pScanRequest(tp2pContext *p2pContext, p2pDiscoverCompleteCallback callback, void *pContext); +void p2pActionFrameTimerHandler(void *pContext); +void p2pListenDiscoverTimerHandler(void *pContext); +void p2pDiscoverTimerHandler(void *pContext); +void p2pRetryActionFrameTimerHandler(void *pContext); +eHalStatus p2pGrpFormationRemainOnChanRspCallback(tHalHandle halHandle, void *pContext, tANI_U32 scanId, eCsrScanStatus scan_status); +eHalStatus p2pChangeDefaultConfigParam(tHalHandle hHal, tP2PConfigParam *pParam); +eHalStatus p2pGetConfigParam(tHalHandle hHal, tP2PConfigParam *pParam); +eHalStatus p2pPS(tHalHandle hHal, tANI_U8 sessionId); +eHalStatus p2pCloseSession(tHalHandle hHal, tANI_U8 SessionID); +eHalStatus p2pSetSessionId(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 SmeSessionId); +tANI_BOOLEAN p2pIsOperatingChannEqualListenChann(tHalHandle hHal, tANI_U8 SessionID); +eHalStatus p2pGetListenChannel(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 *channel); +eHalStatus p2pSetListenChannel(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 channel); +eHalStatus p2pStopDiscovery(tHalHandle hHal, tANI_U8 SessionID); +tANI_U8 getP2PSessionIdFromSMESessionId(tHalHandle hHal, tANI_U8 SessionID); +void p2pCallDiscoverCallback(tp2pContext *p2pContext, eP2PDiscoverStatus statusCode); +eHalStatus p2pGetResultFilter(tp2pContext *pP2pContext, + tCsrScanResultFilter *pFilter); +#endif//INTERNAL +#endif //__P2P_API_H__ diff --git a/drivers/staging/prima/CORE/SME/inc/pmc.h b/drivers/staging/prima/CORE/SME/inc/pmc.h new file mode 100644 index 000000000000..cc15dc0b2ae3 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/pmc.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmc.h +* +* Description: Power Management Control (PMC) internal definitions. +* +* +******************************************************************************/ + +#ifndef __PMC_H__ +#define __PMC_H__ + + +#include "palTimer.h" +#include "csrLinkList.h" +#include "pmcApi.h" +#include "smeInternal.h" + + +//Change PMC_ABORT to no-op for now. We need to define it as VOS_ASSERT(0) once we +//cleanup the usage. +#define PMC_ABORT + +/* Host power sources. */ +typedef enum ePowerSource +{ + AC_POWER, /* host is operating from AC power */ + BATTERY_POWER /* host is operating from battery power */ +} tPowerSource; + + +/* Power save check routine list entry. */ +typedef struct sPowerSaveCheckEntry +{ + tListElem link; /* list links */ + tANI_BOOLEAN (*checkRoutine) (void *checkContext); /* power save check routine */ + void *checkContext; /* value to be passed as parameter to routine specified above */ +} tPowerSaveCheckEntry, *tpPowerSaveCheckEntry; + + +/* Device Power State update indication list entry. */ +typedef struct sDeviceStateUpdateIndEntry +{ + tListElem link; /* list links */ + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState); /* Callback routine to be invoked when pmc changes device state */ + void *callbackContext; /* value to be passed as parameter to routine specified above */ +} tDeviceStateUpdateIndEntry, *tpDeviceStateUpdateIndEntry; + +/* Request full power callback routine list entry. */ +typedef struct sRequestFullPowerEntry +{ + tListElem link; /* list links */ + void (*callbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call when full power is restored */ + void *callbackContext; /* value to be passed as parameter to routine specified above */ +} tRequestFullPowerEntry, *tpRequestFullPowerEntry; + + +/* Request BMPS callback routine list entry. */ +typedef struct sRequestBmpsEntry +{ + tListElem link; /* list links */ + + /* routine to call when BMPS request succeeded/failed */ + void (*callbackRoutine) (void *callbackContext, eHalStatus status); + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + +} tRequestBmpsEntry, *tpRequestBmpsEntry; + + +/* Start U-APSD callback routine list entry. */ +typedef struct sStartUapsdEntry +{ + tListElem link; /* list links */ + + /* routine to call when Uapsd Start succeeded/failed*/ + void (*callbackRoutine) (void *callbackContext, eHalStatus status); + + /* value to be passed as parameter to routine specified above */ + void *callbackContext; + +} tStartUapsdEntry, *tpStartUapsdEntry; + +typedef struct sPmcDeferredMsg +{ + tListElem link; + tpAniSirGlobal pMac; + tANI_U16 messageType; + tANI_U16 size; //number of bytes in u.data + union + { + tSirPowerSaveCfg powerSaveConfig; + tSirWowlAddBcastPtrn wowlAddPattern; + tSirWowlDelBcastPtrn wowlDelPattern; + tANI_U8 data[1]; //a place holder + }u; +} tPmcDeferredMsg; + + + +/* Current PMC information for a particular device. */ +typedef struct sPmcInfo +{ + tPowerSource powerSource; /* host power source */ + tPmcSwitchState hwWlanSwitchState; /* Hardware WLAN Switch state */ + tPmcSwitchState swWlanSwitchState; /* Software WLAN Switch state */ + tPmcState pmcState; /* PMC state */ + tANI_BOOLEAN requestFullPowerPending; /* TRUE if a request for full power is pending */ + tRequestFullPowerReason requestFullPowerReason; /* reason for requesting full power */ + tPmcImpsConfigParams impsConfig; /* IMPS configuration */ + tPmcBmpsConfigParams bmpsConfig; /* BMPS configuration */ + tPmcSmpsConfigParams smpsConfig; /* SMPS configuration */ + tANI_BOOLEAN impsEnabled; /* TRUE if IMPS is enabled */ + tANI_BOOLEAN bmpsEnabled; /* TRUE if BMPS is enabled */ + tANI_BOOLEAN autoBmpsEntryEnabled; /* TRUE if auto BMPS entry is enabled. If set to TRUE, PMC will + attempt to put the device into BMPS on entry into full Power */ + tANI_BOOLEAN bmpsRequestedByHdd; /*TRUE if BMPS mode has been requested by HDD */ + tANI_BOOLEAN bmpsRequestQueued; /*If a enter BMPS request is queued*/ + tANI_BOOLEAN smpsEnabled; /* TRUE if SMPS is enabled */ + tANI_BOOLEAN remainInPowerActiveTillDHCP; /* Remain in Power active till DHCP completes */ + /* Remain in Power active till set key is done */ + bool full_power_till_set_key; + tANI_U32 remainInPowerActiveThreshold; /*Remain in Power active till DHCP threshold*/ + tANI_U32 impsPeriod; /* amount of time to remain in IMPS */ + void (*impsCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call when IMPS period + has finished */ + void *impsCallbackContext; /* value to be passed as parameter to routine specified above */ + vos_timer_t hImpsTimer; /* timer to use with IMPS */ + vos_timer_t hTrafficTimer; /* timer to measure traffic for BMPS */ + vos_timer_t hExitPowerSaveTimer; /* timer for deferred exiting of power save mode */ + tDblLinkList powerSaveCheckList; /* power save check routine list */ + tDblLinkList requestFullPowerList; /* request full power callback routine list */ + tANI_U32 cLastTxUnicastFrames; /* transmit unicast frame count at last BMPS traffic timer expiration */ + tANI_U32 cLastRxUnicastFrames; /* receive unicast frame count at last BMPS traffic timer expiration */ + + + tANI_BOOLEAN uapsdEnabled; /* TRUE if UAPSD is enabled */ + tANI_BOOLEAN uapsdSessionRequired; /* TRUE if device should go to UAPSD on entering BMPS*/ + tDblLinkList requestBmpsList; /* request Bmps callback routine list */ + tDblLinkList requestStartUapsdList; /* request start Uapsd callback routine list */ + tANI_BOOLEAN standbyEnabled; /* TRUE if Standby is enabled */ + void (*standbyCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call for standby request */ + void *standbyCallbackContext;/* value to be passed as parameter to routine specified above */ + tDblLinkList deviceStateUpdateIndList; /*update device state indication list */ + tANI_BOOLEAN pmcReady; /*whether eWNI_SME_SYS_READY_IND has been sent to PE or not */ + tANI_BOOLEAN wowlEnabled; /* TRUE if WoWL is enabled */ + tANI_BOOLEAN wowlModeRequired; /* TRUE if device should go to WOWL on entering BMPS */ + tWowlExitSource wowlExitSrc; /*WoWl exiting because of wakeup pkt or user explicitly disabling WoWL*/ + tANI_BOOLEAN isAPWOWExit; /* TRUE if last WOW exit is from soft ap */ + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status); /* routine to call for wowl request */ + void *enterWowlCallbackContext;/* value to be passed as parameter to routine specified above */ + tSirSmeWowlEnterParams wowlEnterParams; /* WOWL mode configuration */ + tDblLinkList deferredMsgList; //The message in here are deferred and DONOT expect response from PE + tANI_BOOLEAN rfSuppliesVotedOff; //Whether RF supplies are voted off or not. +#ifdef FEATURE_WLAN_SCAN_PNO + preferredNetworkFoundIndCallback prefNetwFoundCB; /* routine to call for Preferred Network Found Indication */ + void *preferredNetworkFoundIndCallbackContext;/* value to be passed as parameter to routine specified above */ +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_PACKET_FILTERING + FilterMatchCountCallback FilterMatchCountCB; /* routine to call for Packet Coalescing Filter Match Count */ + void *FilterMatchCountCBContext;/* value to be passed as parameter to routine specified above */ +#endif // WLAN_FEATURE_PACKET_FILTERING +#ifdef WLAN_FEATURE_GTK_OFFLOAD + GTKOffloadGetInfoCallback GtkOffloadGetInfoCB; /* routine to call for GTK Offload Information */ + void *GtkOffloadGetInfoCBContext; /* value to be passed as parameter to routine specified above */ +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd); /* routine to call for Wake Reason Indication */ + void *wakeReasonIndCBContext; /* value to be passed as parameter to routine specified above */ +#endif // WLAN_WAKEUP_EVENTS + +/* If TRUE driver will go to BMPS only if host operatiing system asks to enter BMPS. +* For android wlan_hdd_cfg80211_set_power_mgmt API will be used to set host powersave*/ + v_BOOL_t isHostPsEn; + v_BOOL_t ImpsReqFailed; + v_BOOL_t ImpsReqTimerFailed; + tANI_U8 ImpsReqFailCnt; + tANI_U8 ImpsReqTimerfailCnt; + tANI_U8 ImpsRspFailCnt; + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*HDD callback to be called after receiving SET BATCH SCAN RSP from FW*/ + hddSetBatchScanReqCallback setBatchScanReqCallback; + void * setBatchScanReqCallbackContext; + /*HDD callback to be called after receiving BATCH SCAN iRESULT IND from FW*/ + hddTriggerBatchScanResultIndCallback batchScanResultCallback; + void * batchScanResultCallbackContext; +#endif + + +} tPmcInfo, *tpPmcInfo; + + +//MACRO +#define PMC_IS_READY(pMac) ( ((pMac)->pmc.pmcReady) && (STOPPED != (pMac)->pmc.pmcState) ) + + +/* Routine definitions. */ +extern eHalStatus pmcEnterLowPowerState (tHalHandle hHal); +extern eHalStatus pmcExitLowPowerState (tHalHandle hHal); +extern eHalStatus pmcEnterFullPowerState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestFullPowerState (tHalHandle hHal, tRequestFullPowerReason fullPowerReason); +extern eHalStatus pmcEnterRequestImpsState (tHalHandle hHal); +extern eHalStatus pmcEnterImpsState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestBmpsState (tHalHandle hHal); +extern eHalStatus pmcEnterBmpsState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestStartUapsdState (tHalHandle hHal); +extern eHalStatus pmcEnterUapsdState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestStopUapsdState (tHalHandle hHal); +extern eHalStatus pmcEnterRequestStandbyState (tHalHandle hHal); +extern eHalStatus pmcEnterStandbyState (tHalHandle hHal); +extern tANI_BOOLEAN pmcPowerSaveCheck (tHalHandle hHal); +extern eHalStatus pmcSendPowerSaveConfigMessage (tHalHandle hHal); +extern eHalStatus pmcSendMessage (tpAniSirGlobal pMac, tANI_U16 messageType, void *pMessageData, tANI_U32 messageSize); +extern void pmcDoCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern void pmcDoBmpsCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern void pmcDoStartUapsdCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern void pmcDoStandbyCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +extern eHalStatus pmcStartTrafficTimer (tHalHandle hHal, tANI_U32 expirationTime); +extern void pmcStopTrafficTimer (tHalHandle hHal); +extern void pmcImpsTimerExpired (tHalHandle hHal); +extern void pmcTrafficTimerExpired (tHalHandle hHal); +extern void pmcExitPowerSaveTimerExpired (tHalHandle hHal); +extern tPmcState pmcGetPmcState (tHalHandle hHal); +extern const char* pmcGetPmcStateStr(tPmcState state); +extern void pmcDoDeviceStateUpdateCallbacks (tHalHandle hHal, tPmcState state); +extern eHalStatus pmcRequestEnterWowlState(tHalHandle hHal, tpSirSmeWowlEnterParams wowlEnterParams); +extern eHalStatus pmcEnterWowlState (tHalHandle hHal); +extern eHalStatus pmcRequestExitWowlState(tHalHandle hHal); +extern void pmcDoEnterWowlCallbacks (tHalHandle hHal, eHalStatus callbackStatus); +//The function will request for full power as well in addition to defer the message +extern eHalStatus pmcDeferMsg( tpAniSirGlobal pMac, tANI_U16 messageType, + void *pData, tANI_U32 size); +extern eHalStatus pmcIssueCommand( tpAniSirGlobal pMac, eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tANI_BOOLEAN fPutToListHead ); +extern eHalStatus pmcEnterImpsCheck( tpAniSirGlobal pMac ); +extern eHalStatus pmcEnterBmpsCheck( tpAniSirGlobal pMac ); +extern tANI_BOOLEAN pmcShouldBmpsTimerRun( tpAniSirGlobal pMac ); +#endif diff --git a/drivers/staging/prima/CORE/SME/inc/pmcApi.h b/drivers/staging/prima/CORE/SME/inc/pmcApi.h new file mode 100644 index 000000000000..4a1915f1a198 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/pmcApi.h @@ -0,0 +1,556 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + +* + +* Name: pmcApi.h + +* + +* Description: Power Management Control (PMC) API definitions. + +* All Rights Reserved. + + +* + +******************************************************************************/ + + +#ifndef __PMC_API_H__ + +#define __PMC_API_H__ + +//This timer value determines the default periodicity at which BMPS retries will happen +//This default value is overwritten typicaly by OS specific registry/INI values. +#define BMPS_TRAFFIC_TIMER_DEFAULT 5000 //unit = ms +#define DHCP_REMAIN_POWER_ACTIVE_THRESHOLD 12 // (12 * 5) sec = 60 seconds = 1 min + +//This timer value is used when starting the timer right after association. This value +//should be large enough to allow the auth, DHCP handshake to complete +#define BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP 8000 //unit = ms + +//This timer value is used to start the timer right after key completion +//during roaming. This should be small enough to allow STA to enter PS +//immediately after key completion as no DHCP phase during roaming. +#define TRAFFIC_TIMER_ROAMING 100 //unit = ms + +#define PMC_IS_CHIP_ACCESSIBLE(pmcState) ( (IMPS != (pmcState)) && (REQUEST_IMPS != (pmcState)) && \ + (STANDBY != (pmcState)) && (REQUEST_STANDBY != (pmcState)) ) + +/* Power events that are signaled to PMC. */ + +typedef enum ePmcPowerEvent + +{ + + ePMC_SYSTEM_HIBERNATE, /* host is entering hibernation */ + + ePMC_SYSTEM_RESUME, /* host is resuming after hibernation */ + + ePMC_HW_WLAN_SWITCH_OFF, /* Hardware WLAN Switch has been turned off */ + + ePMC_HW_WLAN_SWITCH_ON, /* Hardware WLAN Switch has been turned on */ + + ePMC_SW_WLAN_SWITCH_OFF, /* Software WLAN Switch has been turned off */ + + ePMC_SW_WLAN_SWITCH_ON, /* Software WLAN Switch has been turned on */ + + ePMC_BATTERY_OPERATION, /* host is now operating on battery power */ + + ePMC_AC_OPERATION /* host is now operating on AC power */ + +} tPmcPowerEvent; + + + + +/* Power saving modes. */ + +typedef enum ePmcPowerSavingMode + +{ + + ePMC_IDLE_MODE_POWER_SAVE, /* Idle Mode Power Save (IMPS) */ + + ePMC_BEACON_MODE_POWER_SAVE, /* Beacon Mode Power Save (BMPS) */ + + ePMC_SPATIAL_MULTIPLEX_POWER_SAVE, /* Spatial Multiplexing Power Save (SMPS) */ + + ePMC_UAPSD_MODE_POWER_SAVE, /* Unscheduled Automatic Power Save Delivery Mode */ + + ePMC_STANDBY_MODE_POWER_SAVE, /* Standby Power Save Mode */ + + ePMC_WOWL_MODE_POWER_SAVE /* Wake-on-Wireless LAN Power Save Mode */ + +} tPmcPowerSavingMode; + + + + +/* Switch states. */ + +typedef enum ePmcSwitchState + +{ + + ePMC_SWITCH_OFF, /* switch off */ + + ePMC_SWITCH_ON /* switch on */ + +} tPmcSwitchState; + + + + +/* Device power states. */ + +typedef enum ePmcPowerState + +{ + + ePMC_FULL_POWER, /* full power */ + + ePMC_LOW_POWER, /* low power */ + +} tPmcPowerState; + + + +/* PMC states. */ + +typedef enum ePmcState + +{ + + STOPPED, /* PMC is stopped */ + + FULL_POWER, /* full power */ + + LOW_POWER, /* low power */ + + REQUEST_IMPS, /* requesting IMPS */ + + IMPS, /* in IMPS */ + + REQUEST_BMPS, /* requesting BMPS */ + + BMPS, /* in BMPS */ + + REQUEST_FULL_POWER, /* requesting full power */ + + REQUEST_START_UAPSD, /* requesting Start UAPSD */ + + REQUEST_STOP_UAPSD, /* requesting Stop UAPSD */ + + UAPSD, /* in UAPSD */ + + REQUEST_STANDBY, /* requesting standby mode */ + + STANDBY, /* in standby mode */ + + REQUEST_ENTER_WOWL, /* requesting enter WOWL */ + + REQUEST_EXIT_WOWL, /* requesting exit WOWL */ + + WOWL /* Chip in WOWL mode */ + +} tPmcState; + +/* Which beacons should be forwarded to the host. */ + +typedef enum ePmcBeaconsToForward + +{ + + ePMC_NO_BEACONS, /* none */ + + ePMC_BEACONS_WITH_TIM_SET, /* with TIM set */ + + ePMC_BEACONS_WITH_DTIM_SET, /* with DTIM set */ + + ePMC_NTH_BEACON, /* every Nth beacon */ + + ePMC_ALL_BEACONS /* all beacons */ + +} tPmcBeaconsToForward; + + + + +/* The Spatial Mulitplexing Power Save modes. */ + +typedef enum ePmcSmpsMode + +{ + + ePMC_DYNAMIC_SMPS, /* dynamic SMPS */ + + ePMC_STATIC_SMPS /* static SMPS */ + +} tPmcSmpsMode; + +typedef enum +{ + eWOWL_EXIT_USER, + eWOWL_EXIT_WAKEIND +}tWowlExitSource; + +/* Configuration parameters for Idle Mode Power Save (IMPS). */ + +typedef struct sPmcImpsConfigParams + +{ + + tANI_BOOLEAN enterOnAc; /* FALSE if device should enter IMPS only when host operating + + on battery power, TRUE if device should enter always */ + +} tPmcImpsConfigParams, *tpPmcImpsConfigParams; + + + + +/* Configuration parameters for Beacon Mode Power Save (BMPS). */ + +typedef struct sPmcBmpsConfigParams + +{ + + tANI_BOOLEAN enterOnAc; /* FALSE if device should enter BMPS only when host operating on + + battery power, TRUE if device should enter always */ + + tANI_U32 txThreshold; /* transmit rate under which BMPS should be entered (frames / traffic measurement period) */ + + tANI_U32 rxThreshold; /* receive rate under which BMPS should be entered (frames / traffic measurement period) */ + + tANI_U32 trafficMeasurePeriod; /* period for BMPS traffic measurement (milliseconds) */ + + tANI_U32 bmpsPeriod; /* amount of time in low power (beacon intervals) */ + + tPmcBeaconsToForward forwardBeacons; /* which beacons should be forwarded to the host */ + + tANI_U32 valueOfN; /* the value of N when forwardBeacons is set to ePMC_NTH_BEACON */ + + tANI_BOOLEAN usePsPoll; /* TRUE if PS-POLL should be used to retrieve frames from AP, FALSE if a + + null data frame with the PM bit reset should be used */ + + tANI_BOOLEAN setPmOnLastFrame; /* TRUE to keep device in BMPS as much as possible, FALSE otherwise, TRUE means: + + 1) PM bit should be set on last pending transmit data frame + + 2) null frame with PM bit set should be transmitted after last pending receive + + frame has been processed */ + + tANI_BOOLEAN enableBeaconEarlyTermination; /* if TRUE, BET feature in RIVA + will be enabled, FALSE otherwise, TRUE means: + RXP will read the beacon header for the + TIM bit & discard the rest if set to 0, + while in BMPS */ + tANI_U8 bcnEarlyTermWakeInterval; /* This specifies how often in terms + of LI we will disable BET in order to sync + up TSF*/ + +} tPmcBmpsConfigParams, *tpPmcBmpsConfigParams; + + + + +/* Configuration parameters for Spatial Mulitplexing Power Save (SMPS). */ + +typedef struct sPmcSmpsConfigParams + +{ + + tPmcSmpsMode mode; /* mode to use */ + + tANI_BOOLEAN enterOnAc; /* FALSE if device should enter SMPS only when host operating on + + battery power, TRUE if device should enter always */ + +} tPmcSmpsConfigParams, *tpPmcSmpsConfigParams; + + +/* Routine definitions. */ +extern eHalStatus pmcOpen (tHalHandle hHal); + +extern eHalStatus pmcStart (tHalHandle hHal); + +extern eHalStatus pmcStop (tHalHandle hHal); + +extern eHalStatus pmcClose (tHalHandle hHal ); + +extern eHalStatus pmcSignalPowerEvent (tHalHandle hHal, tPmcPowerEvent event); + +extern eHalStatus pmcSetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams); + +extern eHalStatus pmcGetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams); + +extern eHalStatus pmcEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode); + +extern eHalStatus pmcStartAutoBmpsTimer (tHalHandle hHal); + +extern eHalStatus pmcStopAutoBmpsTimer (tHalHandle hHal); + +extern eHalStatus pmcDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode); + +extern eHalStatus pmcQueryPowerState (tHalHandle hHal, tPmcPowerState *pPowerState, tPmcSwitchState *pHwWlanSwitchState, + + tPmcSwitchState *pSwWlanSwitchState); + +extern tANI_BOOLEAN pmcIsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode); + +extern eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext, tRequestFullPowerReason fullPowerReason); + +extern eHalStatus pmcRequestImps (tHalHandle hHal, tANI_U32 impsPeriod, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + +extern eHalStatus pmcRegisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext), + + void *checkContext); + +extern eHalStatus pmcDeregisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext)); + +extern void pmcMessageProcessor (tHalHandle hHal, tSirSmeRsp *pMsg); +extern void pmcResetImpsFailStatus (tHalHandle hHal); +extern v_BOOL_t IsPmcImpsReqFailed (tHalHandle hHal); + +extern eHalStatus pmcRequestBmps ( + + tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + + +extern eHalStatus pmcStartUapsd ( + + tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + + +extern eHalStatus pmcStopUapsd (tHalHandle hHal); + + +extern eHalStatus pmcRequestStandby ( + + tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + + void *callbackContext); + + +extern eHalStatus pmcRegisterDeviceStateUpdateInd (tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + + void *callbackContext); + + +extern eHalStatus pmcDeregisterDeviceStateUpdateInd (tHalHandle hHal, + + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)); + + +extern eHalStatus pmcReady(tHalHandle hHal); + + +void pmcDumpInit(tHalHandle hHal); + + +extern eHalStatus pmcWowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId); + + +extern eHalStatus pmcWowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId); + + +extern eHalStatus pmcEnterWowl ( + + tHalHandle hHal, + + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + + void *wakeReasonIndCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId); + +extern eHalStatus pmcExitWowl (tHalHandle hHal, tWowlExitSource wowlExitSrc); + + +extern eHalStatus pmcSetHostOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn pmcSetKeepAlive + \brief Set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the keepalive. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcSetKeepAlive (tHalHandle hHal, tpSirKeepAliveReq pRequest, tANI_U8 sessionId); + +extern tANI_BOOLEAN pmcValidateConnectState( tHalHandle hHal ); + +extern tANI_BOOLEAN pmcAllowImps( tHalHandle hHal ); + + +#ifdef FEATURE_WLAN_SCAN_PNO +/*Pref netw found Cb declaration*/ +typedef void(*preferredNetworkFoundIndCallback)(void *callbackContext, tpSirPrefNetworkFoundInd pPrefNetworkFoundInd); + +extern eHalStatus pmcSetPreferredNetworkList(tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, preferredNetworkFoundIndCallback callbackRoutine, void *callbackContext); +extern eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_PACKET_FILTERING +// Packet Coalescing Filter Match Count Callback declaration +typedef void(*FilterMatchCountCallback)(void *callbackContext, + tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp); +extern eHalStatus pmcGetFilterMatchCount(tHalHandle hHal, FilterMatchCountCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId); +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +// GTK Offload Information Callback declaration +typedef void(*GTKOffloadGetInfoCallback)(void *callbackContext, tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp); + +/* --------------------------------------------------------------------------- + \fn pmcSetGTKOffload + \brief Set GTK offload feature. + \param hHal - The handle returned by macOpen. + \param pGtkOffload - Pointer to the GTK offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcSetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pGtkOffload, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn pmcGetGTKOffload + \brief Get GTK offload information. + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Pointer to the GTK Offload Get Info response callback routine. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcGetGTKOffload(tHalHandle hHal, + GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef FEATURE_WLAN_BATCH_SCAN +/*Set batch scan request Cb declaration*/ +typedef void(*hddSetBatchScanReqCallback)(void *callbackContext, + tSirSetBatchScanRsp *pRsp); + +/*Trigger batch scan result indication Cb declaration*/ +typedef void(*hddTriggerBatchScanResultIndCallback)(void *callbackContext, + void *pRsp); + +/* ----------------------------------------------------------------------------- + \fn pmcSetBatchScanReq + \brief Setting batch scan request in FW + \param hHal - The handle returned by macOpen. + \param sessionId - session id + \param callbackRoutine - Pointer to set batch scan request callback routine + \param calbackContext - callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ +extern eHalStatus pmcSetBatchScanReq(tHalHandle hHal, tSirSetBatchScanReq + *pRequest, tANI_U8 sessionId, hddSetBatchScanReqCallback callbackRoutine, + void *callbackContext); + +/* ----------------------------------------------------------------------------- + \fn pmcTriggerBatchScanResultInd + \brief API to pull batch scan result from FW + \param hHal - The handle returned by macOpen. + \param sessionId - session id + \param callbackRoutine - Pointer to get batch scan request callback routine + \param calbackContext - callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ +extern eHalStatus pmcTriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + hddTriggerBatchScanResultIndCallback callbackRoutine, void *callbackContext +); + + +/* ----------------------------------------------------------------------------- + \fn pmcStopBatchScanInd + \brief Stoping batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pInd - Pointer to stop batch scan indication + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +extern eHalStatus pmcStopBatchScanInd +( + tHalHandle hHal, + tSirStopBatchScanInd *pInd, + tANI_U8 sessionId +); + +#endif // FEATURE_WLAN_BATCH_SCAN + + +#endif + diff --git a/drivers/staging/prima/CORE/SME/inc/smeInside.h b/drivers/staging/prima/CORE/SME/inc/smeInside.h new file mode 100644 index 000000000000..902e0a0c6a3b --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/smeInside.h @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SMEINSIDE_H ) +#define __SMEINSIDE_H + + +/**========================================================================= + + \file smeInside.h + + \brief prototype for SME structures and APIs used insside SME + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "sirApi.h" +#include "csrInternal.h" +#include "sme_QosApi.h" +#include "smeQosInternal.h" + + +#ifdef FEATURE_OEM_DATA_SUPPORT +#include "oemDataInternal.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "sme_RrmApi.h" +#endif + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +#define SME_TOTAL_COMMAND 30 +#define SME_START_CHAN_STEP 4 + +typedef struct sGenericPmcCmd +{ + tANI_U32 size; //sizeof the data in the union, if any + tRequestFullPowerReason fullPowerReason; + tANI_BOOLEAN fReleaseWhenDone; //if TRUE, the command shall not put back to the queue, free te memory instead. + union + { + tExitBmpsInfo exitBmpsInfo; + tSirSmeWowlEnterParams enterWowlInfo; + }u; +} tGenericPmcCmd; + + +typedef struct sGenericQosCmd +{ + sme_QosWmmTspecInfo tspecInfo; + sme_QosEdcaAcType ac; + v_U8_t tspec_mask; +} tGenericQosCmd; + +typedef struct sRemainChlCmd +{ + tANI_U8 chn; + tANI_U8 phyMode; + tANI_U32 duration; + tANI_U8 isP2PProbeReqAllowed; + void* callback; + void* callbackCtx; +}tRemainChlCmd; + +typedef struct sNoACmd +{ + tP2pPsConfig NoA; +} tNoACmd; +#ifdef FEATURE_WLAN_TDLS +typedef struct TdlsSendMgmtInfo +{ + tSirMacAddr peerMac; + tANI_U8 frameType; + tANI_U8 dialog; + tANI_U16 statusCode; + tANI_U8 responder; + tANI_U32 peerCapability; + tANI_U8 *buf; + tANI_U8 len; +} tTdlsSendMgmtCmdInfo; + +typedef struct TdlsLinkEstablishInfo +{ + tSirMacAddr peerMac; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; + tANI_U8 isBufSta; + tANI_U8 isOffChannelSupported; + tANI_U8 isResponder; + tANI_U8 supportedChannelsLen; + tANI_U8 supportedChannels[SIR_MAC_MAX_SUPP_CHANNELS]; + tANI_U8 supportedOperClassesLen; + tANI_U8 supportedOperClasses[SIR_MAC_MAX_SUPP_OPER_CLASSES]; +} tTdlsLinkEstablishCmdInfo; + +typedef struct TdlsAddStaInfo +{ + eTdlsAddOper tdlsAddOper; + tSirMacAddr peerMac; + tANI_U16 capability; + tANI_U8 extnCapability[SIR_MAC_MAX_EXTN_CAP]; + tANI_U8 supportedRatesLen; + tANI_U8 supportedRates[SIR_MAC_MAX_SUPP_RATES]; + tANI_U8 htcap_present; + tSirHTCap HTCap; + tANI_U8 vhtcap_present; + tSirVHTCap VHTCap; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; +} tTdlsAddStaCmdInfo; + +typedef struct TdlsDelStaInfo +{ + tSirMacAddr peerMac; +} tTdlsDelStaCmdInfo; + +// tdlsoffchan +typedef struct TdlsChanSwitchInfo +{ + tSirMacAddr peerMac; + tANI_U8 tdlsOffCh; + tANI_U8 tdlsOffChBwOffset; + tANI_U8 tdlsSwMode; +} tTdlsChanSwitchCmdInfo; + +/* + * TDLS cmd info, CMD from SME to PE. + */ +typedef struct s_tdls_cmd +{ + tANI_U32 size; + union + { + tTdlsLinkEstablishCmdInfo tdlsLinkEstablishCmdInfo; + tTdlsSendMgmtCmdInfo tdlsSendMgmtCmdInfo; + tTdlsAddStaCmdInfo tdlsAddStaCmdInfo; + tTdlsDelStaCmdInfo tdlsDelStaCmdInfo; + tTdlsChanSwitchCmdInfo tdlsChanSwitchCmdInfo; //tdlsoffchan + }u; +} tTdlsCmd; +#endif /* FEATURE_WLAN_TDLS */ + +typedef struct tagSmeCmd +{ + tListElem Link; + eSmeCommandType command; + tANI_U32 sessionId; + union + { + tScanCmd scanCmd; + tRoamCmd roamCmd; + tWmStatusChangeCmd wmStatusChangeCmd; + tSetKeyCmd setKeyCmd; + tRemoveKeyCmd removeKeyCmd; + tGenericPmcCmd pmcCmd; + tGenericQosCmd qosCmd; +#ifdef FEATURE_OEM_DATA_SUPPORT + tOemDataCmd oemDataCmd; +#endif + tRemainChlCmd remainChlCmd; + tNoACmd NoACmd; + tAddStaForSessionCmd addStaSessionCmd; + tDelStaForSessionCmd delStaSessionCmd; +#ifdef FEATURE_WLAN_TDLS + tTdlsCmd tdlsCmd; +#endif + tSirPNOScanReq pnoInfo; + tSirSpoofMacAddrReq macAddrSpoofCmd; + tAniGetFrameLogReq getFramelogCmd; + struct s_ani_set_tx_max_pwr set_tx_max_pwr; + tpNanRequest pNanReq; + struct csr_set_tx_max_pwr_per_band set_tx_max_pwr_per_band; + tpSirUpdateChanList chan_list; + }u; +}tSmeCmd; + + + +/*-------------------------------------------------------------------------- + Internal to SME + ------------------------------------------------------------------------*/ + +//To get a command buffer +//Return: NULL if there no more command buffer left +tSmeCmd *smeGetCommandBuffer( tpAniSirGlobal pMac ); +void smePushCommand( tpAniSirGlobal pMac, tSmeCmd *pCmd, tANI_BOOLEAN fHighPriority ); +void smeProcessPendingQueue( tpAniSirGlobal pMac ); +void smeReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd); +void purgeSmeSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tDblLinkList *pList, bool flush_all); +tANI_U32 sme_get_sessionid_from_activeList(tpAniSirGlobal pMac); +tANI_BOOLEAN smeCommandPending(tpAniSirGlobal pMac); +tANI_BOOLEAN pmcProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +//this function is used to abort a command where the normal processing of the command +//is terminated without going through the normal path. it is here to take care of callbacks for +//the command, if applicable. +void pmcAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); +tANI_BOOLEAN qosProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrIsValidChannel(tpAniSirGlobal pMac, tANI_U8 chnNum); +tANI_BOOLEAN csrRoamIsValid40MhzChannel(tpAniSirGlobal pMac, tANI_U8 channel); +eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrRoamProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrRoamProcessWmStatusChangeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrReinitRoamCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReinitWmStatusChangeCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReinitSetKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReinitRemoveKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +eHalStatus csrRoamProcessSetKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrRoamProcessRemoveKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrReleaseCommandSetKey(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseCommandRemoveKey(tpAniSirGlobal pMac, tSmeCmd *pCommand); +//eHalStatus csrRoamIssueSetKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 roamId ); +eHalStatus csrRoamIssueRemoveKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamRemoveKey *pRemoveKey, tANI_U32 roamId ); +eHalStatus csrIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand, tRequestFullPowerReason *pReason, + tANI_BOOLEAN *pfNeedPower); +bool csr_is_disconnect_full_power_cmd(tSmeCmd *command); +void csrAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); + +eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme); +eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme); + +/* --------------------------------------------------------------------------- + \fn sme_SetCfgScanControlList + \brief API to set Scan Control List + \param hHal - The handle returned by macOpen. + \param countryCode - Pointer to the countryCode + \param pChannelList - Pointer to the valid channel list + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetCfgScanControlList(tHalHandle hHal, tANI_U8 *countryCode, + tCsrChannel *pChannelList); + +#ifdef FEATURE_OEM_DATA_SUPPORT +eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand); +#endif + +eHalStatus csrProcessAddStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrProcessAddStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); +eHalStatus csrProcessDelStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrProcessMacAddrSpoofCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +eHalStatus csrProcessDelStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); +eHalStatus csrProcessGetFrameLogCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); + +#ifdef WLAN_NS_OFFLOAD +/* --------------------------------------------------------------------------- + \fn pmcSetNSOffload + \brief Set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \param sessionId . Session index of the session + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetNSOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, tANI_U8 sessionId); +#endif //WLAN_NS_OFFLOAD + +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus pmcSetPreferredNetworkList(tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, preferredNetworkFoundIndCallback callbackRoutine, void *callbackContext); +eHalStatus pmcUpdateScanParams(tHalHandle hHal, tCsrConfig *pRequest, tCsrChannel *pChannelList, tANI_U8 b11dResolved); +eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold); +#endif // FEATURE_WLAN_SCAN_PNO +eHalStatus pmcSetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced); + +tANI_BOOLEAN csrRoamGetConcurrencyConnectStatusForBmps(tpAniSirGlobal pMac); +#ifdef FEATURE_WLAN_TDLS +eHalStatus csrTdlsSendMgmtReq(tHalHandle hHal, tANI_U8 sessionId, tCsrTdlsSendMgmt *tdlsSendMgmt); +VOS_STATUS csrTdlsSendLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams); +eHalStatus csrTdlsAddPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif + ); +eHalStatus csrTdlsChangePeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrStaParams *pstaParams); +eHalStatus csrTdlsDelPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif + ); +eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac,tSmeCmd *pCommand ); +eHalStatus csrTdlsProcessLinkEstablish( tpAniSirGlobal pMac, tSmeCmd *cmd ); +eHalStatus csrTdlsProcessChanSwitchReq(tpAniSirGlobal pMac, tSmeCmd *cmd ); //tdlsoffchan +eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac,v_U16_t msg_type, void *pMsgBuf); +VOS_STATUS csrTdlsSendChanSwitchReq(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tANI_S32 tdlsOffCh, + tANI_S32 tdlsOffChBwOffset, + tANI_U8 tdlsSwMode); +#endif /* FEATURE_WLAN_TDLS */ + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +eHalStatus csrFlushCfgBgScanRoamChannelList(tpAniSirGlobal pMac); +eHalStatus csrCreateBgScanRoamChannelList(tpAniSirGlobal pMac, + const tANI_U8 *pChannelList, + const tANI_U8 numChannels); +eHalStatus csrUpdateBgScanConfigIniChannelList(tpAniSirGlobal pMac, eCsrBand eBand); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus csrCreateRoamScanChannelList(tpAniSirGlobal pMac, + tANI_U8 *pChannelList, + tANI_U8 numChannels, + const eCsrBand eBand); +#endif +void activeListCmdTimeoutHandle(void *userData); + +void csrGetStaticUapsdMask(tpAniSirGlobal pMac, tANI_U8 *staticUapsdMask); + +#endif //#if !defined( __SMEINSIDE_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/smeInternal.h b/drivers/staging/prima/CORE/SME/inc/smeInternal.h new file mode 100644 index 000000000000..79f27af6ec24 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/smeInternal.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#if !defined( __SMEINTERNAL_H ) +#define __SMEINTERNAL_H + + +/**========================================================================= + + \file smeInternal.h + + \brief prototype for SME internal structures and APIs used for SME and MAC + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "csrLinkList.h" +#include "vos_diag_core_event.h" + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +// Mask can be only have one bit set +typedef enum eSmeCommandType +{ + eSmeNoCommand = 0, + eSmeDropCommand, + //CSR + eSmeCsrCommandMask = 0x10000, //this is not a command, it is to identify this is a CSR command + eSmeCommandScan, + eSmeCommandRoam, + eSmeCommandWmStatusChange, + eSmeCommandSetKey, + eSmeCommandRemoveKey, + eSmeCommandAddStaSession, + eSmeCommandDelStaSession, + eSmeCommandPnoReq, + eSmeCommandMacSpoofRequest, + eSmeCommandGetFrameLogRequest, + eSmeCommandSetMaxTxPower, + eSmeCommandSetMaxTxPowerPerBand, + eSmeCommandUpdateChannelList, +#ifdef FEATURE_WLAN_TDLS + //eSmeTdlsCommandMask = 0x80000, //To identify TDLS commands + //These can be considered as csr commands. + eSmeCommandTdlsSendMgmt, + eSmeCommandTdlsAddPeer, + eSmeCommandTdlsDelPeer, + eSmeCommandTdlsLinkEstablish, + eSmeCommandTdlsChannelSwitch, // tdlsoffchan +#endif + eSmeCommandNanReq, + //PMC + eSmePmcCommandMask = 0x20000, //To identify PMC commands + eSmeCommandEnterImps, + eSmeCommandExitImps, + eSmeCommandEnterBmps, + eSmeCommandExitBmps, + eSmeCommandEnterUapsd, + eSmeCommandExitUapsd, + eSmeCommandEnterWowl, + eSmeCommandExitWowl, + eSmeCommandEnterStandby, + //QOS + eSmeQosCommandMask = 0x40000, //To identify Qos commands + eSmeCommandAddTs, + eSmeCommandDelTs, +#ifdef FEATURE_OEM_DATA_SUPPORT + eSmeCommandOemDataReq = 0x80000, //To identify the oem data commands +#endif + eSmeCommandRemainOnChannel, + eSmeCommandNoAUpdate, +} eSmeCommandType; + + +typedef enum eSmeState +{ + SME_STATE_STOP, + SME_STATE_START, + SME_STATE_READY, +} eSmeState; + +#define SME_IS_START(pMac) (SME_STATE_STOP != (pMac)->sme.state) +#define SME_IS_READY(pMac) (SME_STATE_READY == (pMac)->sme.state) + +#ifdef WLAN_FEATURE_RMC + +/* HDD Callback function */ +typedef void(*pIbssPeerInfoCb)(void *pUserData, void *infoParam); + +/* Peer info */ +typedef struct tagSmePeerInfoHddCbkInfo +{ + void *pUserData; + pIbssPeerInfoCb peerInfoCbk; +}tSmePeerInfoHddCbkInfo; +#endif /* WLAN_FEATURE_RMC */ + +/* HDD Callback function */ +typedef void(*pEncryptMsgRSPCb)(void *pUserData, void *infoParam); + +typedef struct tagSmeEncMsgHddCbkInfo +{ + void *pUserData; + pEncryptMsgRSPCb pEncMsgCbk; +}tSmeEncMsgHddCbkInfo; + +typedef struct tagSmeStruct +{ + eSmeState state; + vos_lock_t lkSmeGlobalLock; + tANI_U32 totalSmeCmd; + void *pSmeCmdBufAddr; + tDblLinkList smeCmdActiveList; + tDblLinkList smeCmdPendingList; + tDblLinkList smeCmdFreeList; //preallocated roam cmd list + void (*pTxPerHitCallback) (void *pCallbackContext); /* callback for Tx PER hit to HDD */ + void *pTxPerHitCbContext; + tVOS_CON_MODE currDeviceMode; +#ifdef FEATURE_WLAN_LPHB + void (*pLphbIndCb) (void *pAdapter, void *indParam); +#endif /* FEATURE_WLAN_LPHB */ + //pending scan command list + tDblLinkList smeScanCmdPendingList; + //active scan command list + tDblLinkList smeScanCmdActiveList; +#ifdef WLAN_FEATURE_RMC + tSmePeerInfoHddCbkInfo peerInfoParams; +#endif /* WLAN_FEATURE_RMC */ +#ifdef FEATURE_WLAN_CH_AVOID + void (*pChAvoidNotificationCb) (void *pAdapter, void *indParam); +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + /* HDD callback to be called after receiving Link Layer Stats Results IND from FW */ + void(*pLinkLayerStatsIndCallback)(void *callbackContext, + int indType, void *pRsp, tANI_U8 *macAddr ); + void *pLinkLayerStatsCallbackContext; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + void (*pEXTScanIndCb) (void *, const tANI_U16, void *); + /* Use this request ID while sending Full Scan Results */ + int extScanStartReqId; + void *pEXTScanCallbackContext; +#endif /* WLAN_FEATURE_EXTSCAN */ + tSmeEncMsgHddCbkInfo pEncMsgInfoParams; + void (*pBtCoexTDLSNotification) (void *pAdapter, int); + void (*nanCallback) (void*, tSirNanEvent*); + void (*rssiThresholdBreachedCb)(void *, struct rssi_breach_event *); +#ifdef FEATURE_OEM_DATA_SUPPORT + void (*pOemDataIndCb) (void *, const tANI_U16, void *, tANI_U32); + void *pOemDataCallbackContext; +#endif /* FEATURE_OEM_DATA_SUPPORT */ +#ifdef WLAN_FEATURE_LFR_MBB + void (*roaming_mbb_callback)(void* mac, tANI_U32 session_id, + void* bss_description, void *reassoc_req, tANI_U32 csr_roam_op_code); +#endif +} tSmeStruct, *tpSmeStruct; + + +#endif //#if !defined( __SMEINTERNAL_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/smeQosInternal.h b/drivers/staging/prima/CORE/SME/inc/smeQosInternal.h new file mode 100644 index 000000000000..739889389f7a --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/smeQosInternal.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SMEQOSINTERNAL_H ) +#define __SMEQOSINTERNAL_H + + +/**========================================================================= + + \file smeQosInternal.h + + \brief prototype for SME QoS APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "aniGlobal.h" +#include "sirApi.h" +#include "sme_QosApi.h" +#include "smeInternal.h" + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +#define SME_QOS_AP_SUPPORTS_APSD 0x80 + +/*--------------------------------------------------------------------------- + Enumeration of the various EDCA Access Categories: + Based on AC to ACI mapping in 802.11e spec (identical to WMM) +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_EDCA_AC_BE = 0, /* Best effort access category */ + SME_QOS_EDCA_AC_BK = 1, /* Background access category */ + SME_QOS_EDCA_AC_VI = 2, /* Video access category */ + SME_QOS_EDCA_AC_VO = 3, /* Voice access category */ + + SME_QOS_EDCA_AC_MAX +} sme_QosEdcaAcType; + + +/*--------------------------------------------------------------------------- + Enumeration of the various CSR event indication types that would be reported + by CSR +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_CSR_JOIN_REQ = 0, + SME_QOS_CSR_ASSOC_COMPLETE, + SME_QOS_CSR_REASSOC_REQ, + SME_QOS_CSR_REASSOC_COMPLETE, + SME_QOS_CSR_REASSOC_FAILURE, + SME_QOS_CSR_DISCONNECT_REQ, + SME_QOS_CSR_DISCONNECT_IND, + SME_QOS_CSR_HANDOFF_ASSOC_REQ, + SME_QOS_CSR_HANDOFF_COMPLETE, + SME_QOS_CSR_HANDOFF_FAILURE, +#ifdef WLAN_FEATURE_VOWIFI_11R + SME_QOS_CSR_PREAUTH_SUCCESS_IND, + SME_QOS_CSR_SET_KEY_SUCCESS_IND, +#endif +}sme_QosCsrEventIndType; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +typedef enum +{ + SME_QOS_DIAG_ADDTS_REQ = 0, + SME_QOS_DIAG_ADDTS_RSP, + SME_QOS_DIAG_DELTS + +}sme_QosDiagQosEventSubtype; + +typedef enum +{ + SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED = 0, + SME_QOS_DIAG_ADDTS_INVALID_PARAMS, + SME_QOS_DIAG_ADDTS_RESERVED, + SME_QOS_DIAG_ADDTS_REFUSED, + SME_QOS_DIAG_USER_REQUESTED, + SME_QOS_DIAG_DELTS_IND_FROM_AP, + +}sme_QosDiagQosEventReasonCode; + +#endif //FEATURE_WLAN_DIAG_SUPPORT +/*--------------------------------------------------------------------------- + The association information structure to be passed by CSR after assoc or + reassoc is done +---------------------------------------------------------------------------*/ +typedef struct +{ + tSirBssDescription *pBssDesc; + tCsrRoamProfile *pProfile; +} sme_QosAssocInfo; + +/*-------------------------------------------------------------------------- + External APIs for CSR - Internal to SME + ------------------------------------------------------------------------*/ + +/* -------------------------------------------------------------------------- + \brief sme_QosOpen() - This function must be called before any API call to + SME QoS module. + + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosOpen(tpAniSirGlobal pMac); + +/* -------------------------------------------------------------------------- + \brief sme_QosClose() - To close down SME QoS module. There should not be + any API call into this module after calling this function until another + call of sme_QosOpen. + + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosClose(tpAniSirGlobal pMac); + +/*-------------------------------------------------------------------------- + \brief sme_QosSetParams() - This function is used by HDD to provide the + default TSPEC params to SME. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info per AC as defined above, provided by HDD + + \return eHAL_STATUS_SUCCESS - Setparam is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSetParams(tpAniSirGlobal pMac, sme_QosWmmTspecInfo * pQoSInfo); + +/*-------------------------------------------------------------------------- + \brief sme_QosMsgProcessor() - sme_ProcessMsg() calls this function for the + messages that are handled by SME QoS module. + + \param pMac - Pointer to the global MAC parameter structure. + \param msg_type - the type of msg passed by PE as defined in wniApi.h + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHalStatus. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf); + +/*-------------------------------------------------------------------------- + Internal APIs for CSR + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief sme_QosValidateParams() - The SME QoS API exposed to CSR to validate AP + capabilities regarding QoS support & any other QoS parameter validation. + + \param pMac - Pointer to the global MAC parameter structure. + \param pBssDesc - Pointer to the BSS Descriptor information passed down by + CSR to PE while issuing the Join request + + \return eHAL_STATUS_SUCCESS - Validation is successful + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosValidateParams(tpAniSirGlobal pMac, + tSirBssDescription *pBssDesc); + +/*-------------------------------------------------------------------------- + \brief sme_QosCsrEventInd() - The QoS sub-module in SME expects notifications + from CSR when certain events occur as mentioned in sme_QosCsrEventIndType. + + \param pMac - Pointer to the global MAC parameter structure. + \param ind - The event occurred of type sme_QosCsrEventIndType. + \param pEvent_info - Information related to the event + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosCsrEventInd(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosCsrEventIndType ind, + void *pEvent_info); + +/*-------------------------------------------------------------------------- + \brief sme_QosGetACMMask() - The QoS sub-module API to find out on which ACs + AP mandates Admission Control (ACM = 1) + + \param pMac - Pointer to the global MAC parameter structure. + \param pSirBssDesc - The event occurred of type sme_QosCsrEventIndType. + \param pIes - the parsed IE for pSirBssDesc. This can be NULL. + + + \return a bit mask indicating for which ACs AP has ACM set to 1 + + \sa + + --------------------------------------------------------------------------*/ +v_U8_t sme_QosGetACMMask(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes); + +/* + sme_QosTriggerUapsdChange + It trigger a change on UAPSD (either disable/enable UAPSD) on current QoS flows +*/ +sme_QosStatusType sme_QosTriggerUapsdChange( tpAniSirGlobal pMac ); + +void sme_QoSUpdateUapsdBTEvent(tpAniSirGlobal pMac); + +#ifdef FEATURE_WLAN_ESE +v_U8_t sme_QosESERetrieveTspecInfo(tpAniSirGlobal pMac, v_U8_t sessionId, tTspecInfo *pTspecInfo); + +#endif + +#endif //#if !defined( __SMEQOSINTERNAL_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/smeRrmInternal.h b/drivers/staging/prima/CORE/SME/inc/smeRrmInternal.h new file mode 100644 index 000000000000..9ba377d6b050 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/smeRrmInternal.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __SMERRMINTERNAL_H ) +#define __SMERRMINTERNAL_H + + +/**========================================================================= + + \file smeRrmInternal.h + + \brief prototype for SME RRM APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "palTimer.h" +#include "rrmGlobal.h" + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct sRrmConfigParam +{ + tANI_U8 rrmEnabled; + tANI_U8 maxRandnInterval; +}tRrmConfigParam, *tpRrmConfigParam; + +typedef struct sRrmNeighborReportDesc +{ + tListElem List; + tSirNeighborBssDescription *pNeighborBssDescription; + tANI_U32 roamScore; +} tRrmNeighborReportDesc, *tpRrmNeighborReportDesc; + + +typedef void (*NeighborReportRspCallback) (void *context, VOS_STATUS vosStatus); + +typedef struct sRrmNeighborRspCallbackInfo +{ + tANI_U32 timeout; //in ms.. min value is 10 (10ms) + NeighborReportRspCallback neighborRspCallback; + void *neighborRspCallbackContext; +} tRrmNeighborRspCallbackInfo, *tpRrmNeighborRspCallbackInfo; + +typedef struct sRrmNeighborRequestControlInfo +{ + tANI_BOOLEAN isNeighborRspPending; //To check whether a neighbor req is already sent and response pending + vos_timer_t neighborRspWaitTimer; + tRrmNeighborRspCallbackInfo neighborRspCallbackInfo; +} tRrmNeighborRequestControlInfo, *tpRrmNeighborRequestControlInfo; + +typedef struct sRrmSMEContext +{ + tANI_U16 token; + tCsrBssid sessionBssId; + tANI_U8 regClass; + tCsrChannelInfo channelList; //list of all channels to be measured. + tANI_U8 currentIndex; + tAniSSID ssId; //SSID used in the measuring beacon report. + tSirMacAddr bssId; //bssid used for beacon report measurement. + tANI_U16 randnIntvl; //Randomization interval to be used in subsequent measurements. + tANI_U16 duration[SIR_ESE_MAX_MEAS_IE_REQS]; + tANI_U8 measMode[SIR_ESE_MAX_MEAS_IE_REQS]; + tRrmConfigParam rrmConfig; + vos_timer_t IterMeasTimer; + tDblLinkList neighborReportCache; + tRrmNeighborRequestControlInfo neighborReqControlInfo; + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + tCsrEseBeaconReq eseBcnReqInfo; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + tRrmMsgReqSource msgSource; +}tRrmSMEContext, *tpRrmSMEContext; + +typedef struct sRrmNeighborReq +{ + tANI_U8 no_ssid; + tSirMacSSid ssid; +}tRrmNeighborReq, *tpRrmNeighborReq; + +#endif //#if !defined( __SMERRMINTERNAL_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/sme_Api.h b/drivers/staging/prima/CORE/SME/inc/sme_Api.h new file mode 100644 index 000000000000..5d4a8070b243 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/sme_Api.h @@ -0,0 +1,4012 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#if !defined( __SME_API_H ) +#define __SME_API_H + + +/**========================================================================= + + \file smeApi.h + + \brief prototype for SME APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "ccmApi.h" +#include "csrApi.h" +#include "pmcApi.h" +#include "vos_mq.h" +#include "vos_lock.h" +#include "halTypes.h" +#include "sirApi.h" +#include "btcApi.h" +#include "vos_nvitem.h" +#include "p2p_Api.h" +#ifdef WLAN_FEATURE_RMC +#include "smeInternal.h" +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT +#include "oemDataApi.h" +#endif + +#if defined WLAN_FEATURE_VOWIFI +#include "smeRrmInternal.h" +#endif +#include "nan_Api.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define SME_SUMMARY_STATS 1 +#define SME_GLOBAL_CLASSA_STATS 2 +#define SME_GLOBAL_CLASSB_STATS 4 +#define SME_GLOBAL_CLASSC_STATS 8 +#define SME_GLOBAL_CLASSD_STATS 16 +#define SME_PER_STA_STATS 32 +#define SME_PER_PKT_STATS 64 + +#define SME_INVALID_COUNTRY_CODE "XX" + +//Macro to disable split scan +#define SME_DISABLE_SPLIT_SCAN 255 + +//Macro to indicate invalid no of tspecs +#define INVALID_TSPEC 100 + +#define SME_SET_CHANNEL_REG_POWER(reg_info_1, val) do { \ + reg_info_1 &= 0xff00ffff; \ + reg_info_1 |= ((val & 0xff) << 16); \ +} while(0) + +#define SME_SET_CHANNEL_MAX_TX_POWER(reg_info_2, val) do { \ + reg_info_2 &= 0xffff00ff; \ + reg_info_2 |= ((val & 0xff) << 8); \ +} while(0) + +/** + * ALLOWED_ACTION_FRAMES_BITMAP + * + * Bitmask is based on the below.The frames with 0's + * set to their corresponding bit can be dropped in FW. + * + * -----------------------------+-----+-------+ + * Type | Bit | Allow | + * -----------------------------+-----+-------+ + * SIR_MAC_ACTION_SPECTRUM_MGMT 0 1 + * SIR_MAC_ACTION_QOS_MGMT 1 1 + * SIR_MAC_ACTION_DLP 2 0 + * SIR_MAC_ACTION_BLKACK 3 1 + * SIR_MAC_ACTION_PUBLIC_USAGE 4 1 + * SIR_MAC_ACTION_RRM 5 1 + * SIR_MAC_ACTION_FAST_BSS_TRNST 6 0 + * SIR_MAC_ACTION_HT 7 0 + * SIR_MAC_ACTION_SA_QUERY 8 1 + * SIR_MAC_ACTION_PROT_DUAL_PUB 9 0 + * SIR_MAC_ACTION_WNM 10 1 + * SIR_MAC_ACTION_UNPROT_WNM 11 0 + * SIR_MAC_ACTION_TDLS 12 0 + * SIR_MAC_ACITON_MESH 13 0 + * SIR_MAC_ACTION_MHF 14 0 + * SIR_MAC_SELF_PROTECTED 15 0 + * SIR_MAC_ACTION_WME 17 1 + * SIR_MAC_ACTION_FST 18 0 + * SIR_MAC_ACTION_VHT 21 1 + * ----------------------------+------+-------+ + */ +#define ALLOWED_ACTION_FRAMES_BITMAP \ + ((1 << SIR_MAC_ACTION_SPECTRUM_MGMT) | \ + (1 << SIR_MAC_ACTION_QOS_MGMT) | \ + (1 << SIR_MAC_ACTION_BLKACK) | \ + (1 << SIR_MAC_ACTION_PUBLIC_USAGE) | \ + (1 << SIR_MAC_ACTION_RRM) | \ + (1 << SIR_MAC_ACTION_SA_QUERY) | \ + (1 << SIR_MAC_ACTION_WNM) | \ + (1 << SIR_MAC_ACTION_WME) | \ + (1 << SIR_MAC_ACTION_VHT)) +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct _smeConfigParams +{ + tCsrConfigParam csrConfig; +#if defined WLAN_FEATURE_VOWIFI + tRrmConfigParam rrmConfig; +#endif +#if defined FEATURE_WLAN_LFR + tANI_U8 isFastRoamIniFeatureEnabled; + tANI_U8 MAWCEnabled; +#endif +#if defined FEATURE_WLAN_ESE + tANI_U8 isEseIniFeatureEnabled; +#endif +#if defined WLAN_FEATURE_P2P_INTERNAL + tP2PConfigParam p2pConfig; +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 isFastTransitionEnabled; + tANI_U8 RoamRssiDiff; + tANI_BOOLEAN isWESModeEnabled; +#endif + tANI_BOOLEAN fScanOffload; + tANI_U8 isAmsduSupportInAMPDU; + tANI_U32 fEnableDebugLog; + tANI_U32 fDeferIMPSTime; + tANI_U8 fBtcEnableIndTimerVal; +} tSmeConfigParams, *tpSmeConfigParams; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief API to set link layer stats request to FW + \param hHal - The handle returned by macOpen. + + \Param pStatsReq - a pointer to a caller allocated object of + typedef struct tSirLLStatsSetReq, signifying the parameters to link layer + stats set. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq(tHalHandle hHal, tSirLLStatsSetReq *pStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief API to get link layer stats request to FW + \param hHal - The handle returned by macOpen. + + \Param pStatsReq - a pointer to a caller allocated object of + typedef struct tSirLLStatsGetReq, signifying the parameters to link layer + stats get. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq(tHalHandle hHal, tSirLLStatsGetReq *pStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief API to clear link layer stats request to FW + \param hHal - The handle returned by macOpen. + + \Param pStatsReq - a pointer to a caller allocated object of + typedef struct tSirLLStatsClearReq, signifying the parameters to link layer + stats clear. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq(tHalHandle hHal, tSirLLStatsClearReq *pStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief API to trigger Link Layer stats result indications from from FW + \param hHal - The handle returned by macOpen. + \param callbackRoutine - HDD callback which needs to be invoked after + getting get Link Layer Statistics results from FW + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp, + tANI_U8 *macAddr) +); + + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_EXTSCAN +/* --------------------------------------------------------------------------- + \fn sme_GetValidChannelsByBand + \brief SME API to fetch all valid channel filtered by band + \param hHal + \param wifiBand: RF band information + \param aValidChannels: Array to store channel info + \param len: number of channels + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetValidChannelsByBand (tHalHandle hHal, tANI_U8 wifiBand, + tANI_U32 *aValidChannels, tANI_U8 *pNumChannels); + +/* --------------------------------------------------------------------------- + \fn sme_EXTScanGetCapabilities + \brief SME API to fetch Extented Scan capabilities + \param hHal + \param pReq: Extented Scan capabilities structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanGetCapabilities (tHalHandle hHal, + tSirGetEXTScanCapabilitiesReqParams *pReq); + +/* --------------------------------------------------------------------------- + \fn sme_EXTScanStart + \brief SME API to issue Extented Scan start + \param hHal + \param pStartCmd: Extented Scan start structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanStart (tHalHandle hHal, + tSirEXTScanStartReqParams *pStartCmd); + +/* --------------------------------------------------------------------------- + \fn sme_EXTScanStop + \brief SME API to issue Extented Scan stop + \param hHal + \param pStopReq: Extented Scan stop structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanStop(tHalHandle hHal, tSirEXTScanStopReqParams *pStopReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetBssHotlist + \brief SME API to set BSSID hotlist + \param hHal + \param pSetHotListReq: Extented Scan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetBssHotlist (tHalHandle hHal, + tSirEXTScanSetBssidHotListReqParams *pSetHotListReq); + +/* --------------------------------------------------------------------------- + \fn sme_ResetBssHotlist + \brief SME API to reset BSSID hotlist + \param hHal + \param pSetHotListReq: Extented Scan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ResetBssHotlist (tHalHandle hHal, + tSirEXTScanResetBssidHotlistReqParams *pResetReq); + +/* --------------------------------------------------------------------------- + \fn sme_getCachedResults + \brief SME API to get cached results + \param hHal + \param pCachedResultsReq: Extented Scan get cached results structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_getCachedResults (tHalHandle hHal, + tSirEXTScanGetCachedResultsReqParams *pCachedResultsReq); + +/* --------------------------------------------------------------------------- + \fn sme_EXTScanRegisterCallback + \brief SME API to register Extented Scan notification callback + \param pEXTScanIndCb + \- return void + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanRegisterCallback (tHalHandle hHal, + void (*pEXTScanIndCb)(void *, const tANI_U16, void *), + void *); + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef FEATURE_OEM_DATA_SUPPORT +eHalStatus sme_OemDataRegisterCallback (tHalHandle hHal, + void (*pOemDataIndCb)(void *, const tANI_U16, void *, tANI_U32), + void *callbackContext); +#endif + +/* --------------------------------------------------------------------------- + \fn sme_SpoofMacAddrReq + \brief SME API to send Spoof Mac Addr req to HAL + \param macaddr: mac address to be sent + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SpoofMacAddrReq(tHalHandle hHal, v_MACADDR_t *macaddr); + +typedef enum +{ + eSME_ROAM_TRIGGER_NONE = 0, + eSME_ROAM_TRIGGER_SCAN = 1, + eSME_ROAM_TRIGGER_FAST_ROAM = 2, + eSME_ROAM_TRIGGER_MAX +} tSmeFastRoamTrigger; + +#ifdef WLAN_FEATURE_APFIND +struct sme_ap_find_request_req +{ + u_int16_t request_data_len; + const u_int8_t* request_data; +}; +#endif /* WLAN_FEATURE_APFIND */ + + +/*------------------------------------------------------------------------- + Function declarations and documentation. + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + + \brief sme_Open() - Initialze all SME modules and put them at idle state + + The function initializes each module inside SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are at idle state ready to start. + + smeOpen must be called before any other SME APIs can be involved. + smeOpen must be called after macOpen. + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is successfully initialized. + + Other status means SME is failed to be initialized + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Open(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_Close() - Release all SME modules and their resources. + + The function release each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at closed state. + + No SME APIs can be involved after sme_Close except sme_Open. + sme_Close must be called before macClose. + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is successfully close. + + Other status means SME is failed to be closed but caller still cannot + call any other SME functions except smeOpen. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Close(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_PreClose() - Stop SME resources prior to final sme_Stop. + + The function stops resources in SME, PMC, CCM, CSR, etc. as needed + to handle fast closure during SSR/unload-load cases. + + \param hHal - The handle returned by macOpen. + \return v_VOID_t + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t sme_PreClose(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_Start() - Put all SME modules at ready state. + + The function starts each module in SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are ready to run. + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is ready. + + Other status means SME is failed to start. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Start(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_Stop() - Stop all SME modules and put them at idle state + + The function stops each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at idle state ready to start. + + + \param hHal - The handle returned by macOpen. + + \param tHalStopType - reason for stopping + + \return eHAL_STATUS_SUCCESS - SME is stopped. + + Other status means SME is failed to stop but caller should still consider + SME is stopped. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Stop(tHalHandle hHal, tHalStopType stopType); + + +/*-------------------------------------------------------------------------- + + \brief sme_OpenSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + \param callback - A pointer to the function caller specifies for roam/connect status indication + \param pContext - The context passed with callback + \param pSelfMacAddr - Caller allocated memory filled with self MAC address (6 bytes) + \param pbSessionId - pointer to a caller allocated buffer for returned session ID + + \return eHAL_STATUS_SUCCESS - session is opened. sessionId returned. + + Other status means SME is failed to open the session. + eHAL_STATUS_RESOURCES - no more session available. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_OpenSession(tHalHandle hHal, csrRoamCompleteCallback callback, + void *pContext, tANI_U8 *pSelfMacAddr, + tANI_U8 *pbSessionId); + +/*-------------------------------------------------------------------------- + + \brief sme_SetCurrDeviceMode() - Sets the current operating device mode. + \param hHal - The handle returned by macOpen. + \param currDeviceMode - Current operating device mode. + --------------------------------------------------------------------------*/ + +void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode); + +/*-------------------------------------------------------------------------- + + \brief sme_CloseSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param sessionId - A previous opened session's ID. + + \param bPurgeSmeCmdList - Whether sme cmd list purging is required or not. + TRUE -Purging require FALSE - Purging not require + + \return eHAL_STATUS_SUCCESS - session is closed. + + Other status means SME is failed to open the session. + eHAL_STATUS_INVALID_PARAMETER - session is not opened. + \sa + + + --------------------------------------------------------------------------*/ +eHalStatus sme_CloseSession(tHalHandle hHal, tANI_U8 sessionId, + tANI_BOOLEAN fSync, + tANI_U8 bPurgeSmeCmdList, + csrRoamSessionCloseCallback callback, + void *pContext); + +/*-------------------------------------------------------------------------- + + \brief sme_UpdateConfig() - Change configurations for all SME moduels + + The function updates some configuration for modules in SME, CCM, CSR, etc + during SMEs close -> open sequence. + + Modules inside SME apply the new configuration at the next transaction. + + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams); + +#ifdef FEATURE_WLAN_SCAN_PNO +/*-------------------------------------------------------------------------- + + \brief sme_UpdateChannelConfig() - Update channel configuration in RIVA. + + It is used at driver start up to inform RIVA of the default channel + configuration. + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME update the channel config successfully. + + Other status means SME is failed to update the channel config. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateChannelConfig(tHalHandle hHal); + +#endif // FEATURE_WLAN_SCAN_PNLO +/*-------------------------------------------------------------------------- + + \brief sme_UpdateChannelList() - Update channel List in FW. + + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME update the channel config successfully. + + Other status means SME is failed to update the channel config. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateChannelList(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + + \brief sme_set11dinfo() - Set the 11d information about valid channels + and there power using information from nvRAM + This function is called only for AP. + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams); + +/*-------------------------------------------------------------------------- + + \brief sme_getSoftApDomain() - Get the current regulatory domain of softAp. + + This is a synchronuous call + + \param hHal - The handle returned by HostapdAdapter. + \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp. + + \return eHAL_STATUS_SUCCESS - SME successfully completed the request. + + Other status means, failed to get the current regulatory domain. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_getSoftApDomain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp); + +eHalStatus sme_setRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode); + + +/* --------------------------------------------------------------------------- + \fn sme_ChangeConfigParams + \brief The SME API exposed for HDD to provide config params to SME during + SMEs stop -> start sequence. + + If HDD changed the domain that will cause a reset. This function will + provide the new set of 11d information for the new domain. Currrently this + API provides info regarding 11d only at reset but we can extend this for + other params (PMC, QoS) which needs to be initialized again at reset. + + This is a synchronuous call + + \param hHal - The handle returned by macOpen. + + \Param + pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that + currently provides 11d related information like Country code, + Regulatory domain, valid channel list, Tx power per channel, a + list with active/passive scan allowed per valid channel. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ChangeConfigParams(tHalHandle hHal, + tCsrUpdateConfigParam *pUpdateConfigParam); + +/*-------------------------------------------------------------------------- + + \brief sme_HDDReadyInd() - SME sends eWNI_SME_SYS_READY_IND to PE to inform that the NIC + is ready tio run. + + The function is called by HDD at the end of initialization stage so PE/HAL can enable the NIC + to running state. + + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE successfully. + + Other status means SME failed to send the message to PE. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_HDDReadyInd(tHalHandle hHal); + + +/*-------------------------------------------------------------------------- + + \brief sme_ProcessMsg() - The main message processor for SME. + + The function is called by a message dispatcher when to process a message + targeted for SME. + + + \param hHal - The handle returned by macOpen. + \param pMsg - A pointer to a caller allocated object of tSirMsgQ. + + \return eHAL_STATUS_SUCCESS - SME successfully process the message. + + Other status means SME failed to process the message. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg); + +v_VOID_t sme_FreeMsg( tHalHandle hHal, vos_msg_t* pMsg ); + +/* --------------------------------------------------------------------------- + \fn sme_ScanRequest + \brief a wrapper function to Request a 11d or full scan from CSR. + \param pScanRequestID - pointer to an object to get back the request ID + \param callback - a callback function that scan calls upon finish, will not + be called if csrScanRequest returns error + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanRequest(tHalHandle hHal, tANI_U8 sessionId, tCsrScanRequest *, + tANI_U32 *pScanRequestID, + csrScanCompleteCallback callback, void *pContext); + + +/* --------------------------------------------------------------------------- + \fn sme_ScanSetBGScanparams + \brief a wrapper function to request CSR to set BG scan params in PE + \param pScanReq - BG scan request structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanSetBGScanparams(tHalHandle hHal, tANI_U8 sessionId, tCsrBGScanRequest *pScanReq); + + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetResult + \brief a wrapper function to request scan results from CSR. + \param pFilter - If pFilter is NULL, all cached results are returned + \param phResult - an object for the result. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetResult(tHalHandle hHal, tANI_U8 sessionId, tCsrScanResultFilter *pFilter, + tScanResultHandle *phResult); + + +/* --------------------------------------------------------------------------- + \fn sme_ScanFlushResult + \brief a wrapper function to request CSR to clear scan results. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanFlushResult(tHalHandle hHal, tANI_U8 sessionId); + +/* + * --------------------------------------------------------------------------- + * \fn sme_FilterScanResults + * \brief a wrapper function to request CSR to filter the scan results based + * on valid chennel list. + * \return eHalStatus + *--------------------------------------------------------------------------- + */ +eHalStatus sme_FilterScanResults(tHalHandle hHal, tANI_U8 sessionId); + +/* + * --------------------------------------------------------------------------- + * \fn sme_FilterScanDFSResults + * \brief a wrapper function to request CSR to filter BSSIDs on DFS channels + * from the scan results. + * \return eHalStatus + *--------------------------------------------------------------------------- + */ +eHalStatus sme_FilterScanDFSResults(tHalHandle hHal); + +eHalStatus sme_ScanFlushP2PResult(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetFirst + \brief a wrapper function to request CSR to returns the first element of + scan result. + \param hScanResult - returned from csrScanGetResult + \return tCsrScanResultInfo * - NULL if no result + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetFirst(tHalHandle, + tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetNext + \brief a wrapper function to request CSR to returns the next element of + scan result. It can be called without calling csrScanResultGetFirst + first + \param hScanResult - returned from csrScanGetResult + \return Null if no result or reach the end + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetNext(tHalHandle, + tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultPurge + \brief a wrapper function to request CSR to remove all items(tCsrScanResult) + in the list and free memory for each item + \param hScanResult - returned from csrScanGetResult. hScanResult is + considered gone by + calling this function and even before this function reutrns. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanResultPurge(tHalHandle hHal, tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetPMKIDCandidateList + \brief a wrapper function to return the PMKID candidate list + \param pPmkidList - caller allocated buffer point to an array of + tPmkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tPmkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tPmkidCandidateInfo. + \Note: pNumItems is a number of tPmkidCandidateInfo, + not sizeof(tPmkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetPMKIDCandidateList(tHalHandle hHal, tANI_U8 sessionId, + tPmkidCandidateInfo *pPmkidList, + tANI_U32 *pNumItems ); + + +/*---------------------------------------------------------------------------- + \fn sme_RoamRegisterLinkQualityIndCallback + + \brief + a wrapper function to allow HDD to register a callback handler with CSR for + link quality indications. + + Only one callback may be registered at any time. + In order to deregister the callback, a NULL cback may be provided. + + Registration happens in the task context of the caller. + + \param callback - Call back being registered + \param pContext - user data + + DEPENDENCIES: After CSR open + + \return eHalStatus +-----------------------------------------------------------------------------*/ +eHalStatus sme_RoamRegisterLinkQualityIndCallback(tHalHandle hHal, tANI_U8 sessionId, + csrRoamLinkQualityIndCallback callback, + void *pContext); + + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnect + \brief a wrapper function to request CSR to inititiate an association + \param sessionId - the sessionId returned by sme_OpenSession. + \param pProfile - can be NULL to join to any open ones + \param pRoamId - to get back the request ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnect(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tANI_U32 *pRoamId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamReassoc + \brief a wrapper function to request CSR to inititiate a re-association + \param pProfile - can be NULL to join the currently connected AP. In that + case modProfileFields should carry the modified field(s) which could trigger + reassoc + \param modProfileFields - fields which are part of tCsrRoamConnectedProfile + that might need modification dynamically once STA is up & running and this + could trigger a reassoc + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamReassoc(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce); + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnectToLastProfile + \brief a wrapper function to request CSR to disconnect and reconnect with + the same profile + \return eHalStatus. It returns fail if currently connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnectToLastProfile(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnect + \brief a wrapper function to request CSR to disconnect from a network + \param reason -- To indicate the reason for disconnecting. Currently, only + eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDisconnectReason reason); + +/* --------------------------------------------------------------------------- + \fn.sme_abortConnection + \brief a wrapper function to request CSR to stop from connecting a network + \retun void. +---------------------------------------------------------------------------*/ + +void sme_abortConnection(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn.sme_dhcp_done_ind + \brief a wrapper function to set dhcp done ind in sme session + \retun void. +---------------------------------------------------------------------------*/ +void sme_dhcp_done_ind(tHalHandle hal, uint8_t session_id); + +/* --------------------------------------------------------------------------- + \fn sme_RoamStopBss + \brief a wrapper function to request CSR to stop bss + \param sessionId - sessionId of SoftAP + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamStopBss(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetAssociatedStas + \brief To probe the list of associated stations from various modules of CORE stack. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param modId - Module from whom list of associtated stations is to be probed. + If an invalid module is passed then by default VOS_MODULE_ID_PE will be probed + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pAssocBuf - Caller allocated memory to be filled with associatd stations info + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetAssociatedStas(tHalHandle hHal, tANI_U8 sessionId, + VOS_MODULE_ID modId, void *pUsrContext, + void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf); + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnectSta + \brief To disassociate a station. This is an asynchronous API. + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnectSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pPeerMacAddr +#else + tANI_U8 *pPeerMacAddr +#endif + ); + +/* --------------------------------------------------------------------------- + \fn sme_RoamDeauthSta + \brief To disassociate a station. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \param pDelStaParams- Pointer to parameters of the station to deauthenticate + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDeauthSta(tHalHandle hHal, tANI_U8 sessionId, + struct tagCsrDelStaParams *pDelStaParams); + +/* --------------------------------------------------------------------------- + \fn sme_RoamTKIPCounterMeasures + \brief To start or stop TKIP counter measures. This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param bEnable - Flag to start/stop TKIP countermeasures + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamTKIPCounterMeasures(tHalHandle hHal, tANI_U8 sessionId, tANI_BOOLEAN bEnable); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetWpsSessionOverlap + \brief To get the WPS PBC session overlap information. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetWpsSessionOverlap(tHalHandle hHal, tANI_U8 sessionId, + void *pUsrContext, void *pfnSapEventCallback, + v_MACADDR_t pRemoveMac); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectState + \brief a wrapper function to request CSR to return the current connect state + of Roaming + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectState(tHalHandle hHal, tANI_U8 sessionId, eCsrConnectState *pState); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectProfile + \brief a wrapper function to request CSR to return the current connect + profile. Caller must call csrRoamFreeConnectProfile after it is done + and before reuse for another csrRoamGetConnectProfile call. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. Failure if not connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectProfile(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn sme_RoamFreeConnectProfile + \brief a wrapper function to request CSR to free and reinitialize the + profile returned previously by csrRoamGetConnectProfile. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamFreeConnectProfile(tHalHandle hHal, + tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn sme_RoamSetPMKIDCache + \brief a wrapper function to request CSR to return the PMKID candidate list + \param pPMKIDCache - caller allocated buffer point to an array of + tPmkidCacheInfo + \param numItems - a variable that has the number of tPmkidCacheInfo + allocated when retruning, this is either the number needed + or number of items put into pPMKIDCache + \param update_entire_cache - if TRUE, then it overwrites the entire cache + with pPMKIDCache, else it updates entry by + entry without deleting the old entries. + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems has the number of + tPmkidCacheInfo. + \Note: pNumItems is a number of tPmkidCacheInfo, + not sizeof(tPmkidCacheInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetPMKIDCache( tHalHandle hHal, tANI_U8 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityReqIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR + passes to PE to JOIN request or START_BSS request + This is a synchronuous call. + \param sessionId - returned by sme_OpenSession. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityReqIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityRspIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE from + the beacon or probe rsp if connected + \param sessionId - returned by sme_OpenSession. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityRspIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType); + + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetNumPMKIDCache + \brief a wrapper function to request CSR to return number of PMKID cache + entries + \return tANI_U32 - the number of PMKID cache entries + ---------------------------------------------------------------------------*/ +tANI_U32 sme_RoamGetNumPMKIDCache(tHalHandle hHal, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetPMKIDCache + \brief a wrapper function to request CSR to return PMKID cache from CSR + \param pNum - caller allocated memory that has the space of the number of + pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if + any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetPMKIDCache(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pNum, + tPmkidCacheInfo *pPmkidCache); + +/* --------------------------------------------------------------------------- + \fn sme_GetConfigParam + \brief a wrapper function that HDD calls to get the global settings + currently maintained by CSR. + \param pParam - caller allocated memory + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam); + +/* --------------------------------------------------------------------------- + \fn sme_GetStatistics + \brief a wrapper function that client calls to register a callback to get + different PHY level statistics from CSR. + + \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc + \param statsMask - The different category/categories of stats requester is looking for + The order in which you set the bits in the statsMask for requesting + different type of stats is: + + eCsrSummaryStats = bit 0 + eCsrGlobalClassAStats = bit 1 + eCsrGlobalClassBStats = bit 2 + eCsrGlobalClassCStats = bit 3 + eCsrGlobalClassDStats = bit 4 + eCsrPerStaStats = bit 5 + + \param callback - SME sends back the requested stats using the callback + \param periodicity - If requester needs periodic update, 0 means it's an one + time request + \param cache - If requester is happy with cached stats + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext); + +/* --------------------------------------------------------------------------- + \fn smeGetTLSTAState + \helper function to get teh TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 smeGetTLSTAState(tHalHandle hHal, tANI_U8 staId); + +eHalStatus sme_GetRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, void *pContext, void* pVosContext); + +/* --------------------------------------------------------------------------- + \fn sme_GetSnr + \brief a wrapper function that client calls to register a callback to get + SNR from FW + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param bssid - The bssid of the connected session + \param pContext - user context to be passed back along with the callback + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetSnr(tHalHandle hHal, + tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext); +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +eHalStatus sme_GetRoamRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void *pContext, + void* pVosContext); +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* --------------------------------------------------------------------------- + \fn sme_GetTsmStats + \brief a wrapper function that client calls to register a callback to get TSM Stats + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetTsmStats(tHalHandle hHal, + tCsrTsmStatsCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext, tANI_U8 tid); + +/* --------------------------------------------------------------------------- + \fn sme_SetCCKMIe + \brief function to store the CCKM IE passed from supplicant and use it while packing + reassociation request + \param hHal - HAL handle for device + \param pCckmIe - pointer to CCKM IE data + \param pCckmIeLen - length of the CCKM IE + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetCCKMIe(tHalHandle hHal, tANI_U8 sessionId, tANI_U8 *pCckmIe, tANI_U8 cckmIeLen); + + +/* --------------------------------------------------------------------------- + \fn sme_SetEseBeaconRequest + \brief function to set ESE beacon request parameters + \param hHal - HAL handle for device + \param pESEBcnReq - pointer to ESE beacon request + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetEseBeaconRequest(tHalHandle hHal, const tANI_U8 sessionId, + const tCsrEseBeaconReq* pEseBcnReq); + + +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +/* --------------------------------------------------------------------------- + \fn sme_CfgSetInt + \brief a wrapper function that HDD calls to set parameters in CFG. + \param cfgId - Configuration Parameter ID (type) for STA. + \param ccmValue - The information related to Configuration Parameter ID + which needs to be saved in CFG + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, + tCcmCfgSetCallback callback, eAniBoolean toBeSaved) ; + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetStr + \brief a wrapper function that HDD calls to set parameters in CFG. + \param cfgId - Configuration Parameter ID (type) for STA. + \param pStr - Pointer to the byte array which carries the information needs + to be saved in CFG + \param length - Length of the data to be saved + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, + tANI_U32 length, tCcmCfgSetCallback callback, + eAniBoolean toBeSaved) ; +/* --------------------------------------------------------------------------- + \fn sme_GetModifyProfileFields + \brief HDD or SME - QOS calls this function to get the current values of + connected profile fields, changing which can cause reassoc. + This function must be called after CFG is downloaded and STA is in connected + state. Also, make sure to call this function to get the current profile + fields before calling the reassoc. So that pModifyProfileFields will have + all the latest values plus the one(s) has been updated as part of reassoc + request. + \param pModifyProfileFields - pointer to the connected profile fields + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetModifyProfileFields(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamModifyProfileFields * pModifyProfileFields); +/* --------------------------------------------------------------------------- + \fn sme_HT40StopOBSSScan + \brief HDD or SME - Command to stop the OBSS scan + THis is implemented only for debugging purpose. + As per spec while operating in 2.4GHz OBSS scan shouldnt be stopped. + \param sessionId - sessionId + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_HT40StopOBSSScan(tHalHandle hHal, tANI_U8 sessionId ); + +/*-------------------------------------------------------------------------- + \fn sme_SetConfigPowerSave + \brief Wrapper fn to change power save configuration in SME (PMC) module. + For BMPS related configuration, this function also updates the CFG + and sends a message to FW to pick up the new values. Note: Calling + this function only updates the configuration and does not enable + the specified power save mode. + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode being modified + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_SetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams); + +/*-------------------------------------------------------------------------- + \fn sme_GetConfigPowerSave + \brief Wrapper fn to retireve power save configuration in SME (PMC) module + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams); + +/* --------------------------------------------------------------------------- + \fn sme_SignalPowerEvent + \brief Signals to PMC that a power event has occurred. Used for putting + the chip into deep sleep mode. + \param hHal - The handle returned by macOpen. + \param event - the event that has occurred + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_SignalPowerEvent ( + tHalHandle hHal, + tPmcPowerEvent event); + +/* --------------------------------------------------------------------------- + \fn sme_EnablePowerSave + \brief Enables one of the power saving modes. This API does not cause a + device state change. This is purely a configuration API. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to enable. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_EnablePowerSave ( + tHalHandle hHal, + tPmcPowerSavingMode psMode); + +/* --------------------------------------------------------------------------- + \fn sme_DisablePowerSave + \brief Disables one of the power saving modes.Disabling does not imply + that device will be brought out of the current PS mode. This is + purely a configuration API. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to disable. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_DisablePowerSave ( + tHalHandle hHal, + tPmcPowerSavingMode psMode); + + /* --------------------------------------------------------------------------- + \fn sme_SetHostPowerSave + \brief The BMPS logic is controlled by the User level Apps + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to enable. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_SetHostPowerSave ( + tHalHandle hHal, + v_BOOL_t psMode); + +/* --------------------------------------------------------------------------- + \fn sme_StartAutoBmpsTimer + \brief Starts a timer that periodically polls all the registered + module for entry into Bmps mode. This timer is started only if BMPS is + enabled and whenever the device is in full power. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StartAutoBmpsTimer ( tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_StopAutoBmpsTimer + \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer + Stopping the timer does not cause a device state change. Only the timer + is stopped. If "Full Power" is desired, use the sme_RequestFullPower API + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StopAutoBmpsTimer ( tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_QueryPowerState + \brief Returns the current power state of the device. + \param hHal - The handle returned by macOpen. + \param pPowerState - pointer to location to return power state + \param pSwWlanSwitchState - ptr to location to return SW WLAN Switch state + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_QueryPowerState ( + tHalHandle hHal, + tPmcPowerState *pPowerState, + tPmcSwitchState *pSwWlanSwitchState); + +/* --------------------------------------------------------------------------- + \fn sme_IsPowerSaveEnabled + \brief Checks if the device is able to enter a particular power save mode + This does not imply that the device is in a particular PS mode + \param hHal - The handle returned by macOpen. + \param psMode - the power saving mode + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern tANI_BOOLEAN sme_IsPowerSaveEnabled( + tHalHandle hHal, + tPmcPowerSavingMode psMode); + +/* --------------------------------------------------------------------------- + \fn sme_RequestFullPower + \brief Request that the device be brought to full power state. + Note 1: If "fullPowerReason" specificied in this API is set to + eSME_FULL_PWR_NEEDED_BY_HDD, PMC will clear any "buffered wowl" requests + and also clear any "buffered BMPS requests by HDD". Assumption is that since + HDD is requesting full power, we need to undo any previous HDD requests for + BMPS (using sme_RequestBmps) or WoWL (using sme_EnterWoWL). If the reason is + specified anything other than above, the buffered requests for BMPS and WoWL + will not be cleared. + Note 2: Requesting full power (no matter what the fullPowerReason is) doesn't + disable the "auto bmps timer" (if it is enabled) or clear any "buffered uapsd + request". + Note 3: When the device finally enters Full Power PMC will start a timer + if any of the following holds true: + - Auto BMPS mode is enabled + - Uapsd request is pending + - HDD's request for BMPS is pending + - HDD's request for WoWL is pending + On timer expiry PMC will attempt to put the device in BMPS mode if following + (in addition to those listed above) holds true: + - Polling of all modules through the Power Save Check routine passes + - STA is associated to an access point + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + \param - fullPowerReason - Reason why this API is being invoked. SME needs to + distinguish between BAP and HDD requests + \return eHalStatus - status + eHAL_STATUS_SUCCESS - device brought to full power state + eHAL_STATUS_FAILURE - device cannot be brought to full power state + eHAL_STATUS_PMC_PENDING - device is being brought to full power state, + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RequestFullPower ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext, + tRequestFullPowerReason fullPowerReason); + +/* --------------------------------------------------------------------------- + \fn sme_RequestBmps + \brief Request that the device be put in BMPS state. Request will be + accepted only if BMPS mode is enabled and power save check routine + passes. Only HDD should invoke this API. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought to BMPS state + eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RequestBmps ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_SetDHCPTillPowerActiveFlag + \brief Sets/Clears DHCP related flag in PMC to disable/enable auto BMPS + entry by PMC + \param hHal - The handle returned by macOpen. + ---------------------------------------------------------------------------*/ +void sme_SetDHCPTillPowerActiveFlag(tHalHandle hHal, tANI_U8 flag); + + +/* --------------------------------------------------------------------------- + \fn sme_StartUapsd + \brief Request that the device be put in UAPSD state. If the device is in + Full Power it will be put in BMPS mode first and then into UAPSD + mode. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + eHAL_STATUS_SUCCESS - device is in UAPSD state + eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state + eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state + eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StartUapsd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_StopUapsd + \brief Request that the device be put out of UAPSD state. Device will be + put in in BMPS state after stop UAPSD completes. Buffered requests for + UAPSD will be cleared after this. + \param hHal - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_StopUapsd (tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_RequestStandby + \brief Request that the device be put in standby. It is HDD's responsibility + to bring the chip to full power and do a discconnect before calling + this API. Request for standby will be rejected if STA is associated + to an AP. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \param - callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in Standby mode + eHAL_STATUS_FAILURE - device cannot be put in standby mode + eHAL_STATUS_PMC_PENDING - device is being put in standby mode + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RequestStandby ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_RegisterPowerSaveCheck + \brief Register a power save check routine that is called whenever + the device is about to enter one of the power save modes. + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RegisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext), void *checkContext); + +/* --------------------------------------------------------------------------- + \fn sme_Register11dScanDoneCallback + \brief Register a routine of type csrScanCompleteCallback which is + called whenever an 11d scan is done + \param hHal - The handle returned by macOpen. + \param callback - 11d scan complete routine to be registered + \return eHalStatus + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_Register11dScanDoneCallback ( + tHalHandle hHal, + csrScanCompleteCallback); + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterPowerSaveCheck + \brief Deregister a power save check routine + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_DeregisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext)); + +/* --------------------------------------------------------------------------- + \fn sme_RegisterDeviceStateUpdateInd + \brief Register a callback routine that is called whenever + the device enters a new device state (Full Power, BMPS, UAPSD) + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_RegisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + void *callbackContext); + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterDeviceStateUpdateInd + \brief Deregister a routine that was registered for device state changes + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_DeregisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)); + +/* --------------------------------------------------------------------------- + \fn sme_WowlAddBcastPattern + \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will + do a pattern match on these patterns when Wowl is enabled during BMPS + mode. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be added + \return eHalStatus + eHAL_STATUS_FAILURE Cannot add pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_WowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_WowlDelBcastPattern + \brief Delete a pattern that was added for Pattern Byte Matching. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be deleted + \return eHalStatus + eHAL_STATUS_FAILURE Cannot delete pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_WowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_EnterWowl + \brief This is the API to request entry into WOWL mode. + WoWLAN works on top of BMPS mode. If the device is not in BMPS mode, + SME will will cache the information that WOWL has been requested and + attempt to put the device in BMPS first. On entry into BMPS, SME will + enter the WOWL mode. + Note 1: After WoWL request is accepted, If module other than HDD requests + full power BEFORE WoWL request is completed, PMC will buffer the WoWL request + and attempt to put the chip into BMPS+WOWL based on a timer. + Note 2: Buffered request for WoWL will be cleared immedisately AFTER "enter Wowl" + completes or if HDD requests full power or if sme_ExitWoWL API is invoked. + Note 3: Both UAPSD and WOWL work on top of BMPS. On entry into BMPS, SME + will give priority to UAPSD and enable only UAPSD if both UAPSD and WOWL + are required. Currently there is no requirement or use case to support UAPSD + and WOWL at the same time. + Note 4. Request for WoWL is rejected if there is a pending UAPSD request. + Note 5. Request for WoWL is rejected if BMPS is disabled. + + \param hHal - The handle returned by macOpen. + \param enterWowlCallbackRoutine - Callback routine provided by HDD. + Used for success/failure notification by SME + \param enterWowlCallbackContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \param wakeReasonIndCB - Callback routine provided by HDD. + Used for Wake Reason Indication by SME + \param wakeReasonIndCBContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \return eHalStatus + eHAL_STATUS_SUCCESS Device is already in WoWLAN mode + eHAL_STATUS_FAILURE Device cannot enter WoWLAN mode. + eHAL_STATUS_PMC_PENDING Request accepted. SME will enable WOWL when BMPS + mode is entered. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_EnterWowl ( + tHalHandle hHal, + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + void *wakeReasonIndCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ExitWowl + \brief This is the SME API exposed to HDD to request exit from WoWLAN mode. + SME will initiate exit from WoWLAN mode and device will be put in BMPS + mode. Any Buffered request for WoWL will be cleared after this API. + \param hHal - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode. This can happen + only if the previous "Enter WOWL" transaction has + not even completed. + eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode. + ---------------------------------------------------------------------------*/ +extern eHalStatus sme_ExitWowl (tHalHandle hHal, tWowlExitSource wowlExitSrc); + +/* --------------------------------------------------------------------------- + + \fn sme_RoamSetKey + + \brief To set encryption key. This function should be called only when connected + This is an asynchronous API. + + \param pSetKeyInfo - pointer to a caller allocated object of tCsrSetContextInfo + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetKey(tHalHandle, tANI_U8 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 *pRoamId); + +/* --------------------------------------------------------------------------- + + \fn sme_RoamRemoveKey + + \brief To set encryption key. This is an asynchronous API. + + \param pRemoveKey - pointer to a caller allocated object of tCsrRoamRemoveKey + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamRemoveKey(tHalHandle, tANI_U8 sessionId, tCsrRoamRemoveKey *pRemoveKey, tANI_U32 *pRoamId); + + +/* --------------------------------------------------------------------------- + + \fn sme_GetCountryCode + + \brief To return the current country code. If no country code is applied, default country code is + used to fill the buffer. + If 11d supported is turned off, an error is return and the last applied/default country code is used. + This is a synchronous API. + + \param pBuf - pointer to a caller allocated buffer for returned country code. + + \param pbLen For input, this parameter indicates how big is the buffer. + Upon return, this parameter has the number of bytes for country. If pBuf + doesn't have enough space, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U8 *pbLen); + +/* --------------------------------------------------------------------------- + + \fn sme_SetCountryCode + + \brief To change the current/default country code. + If 11d supported is turned off, an error is return. + This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for the country code. + + \param pfRestartNeeded A pointer to caller allocated memory, upon successful return, it indicates + whether a reset is required. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetCountryCode(tHalHandle hHal, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + + \fn sme_InitChannels + + \brief Used to initialize CSR channel lists while driver loading + + \param hHal - global pMac structure + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_InitChannels(tHalHandle hHal); + + +#ifdef CONFIG_ENABLE_LINUX_REG +/* --------------------------------------------------------------------------- + \fn sme_InitChannelsForCC + + \brief Used to issue regulatory hint to user + + \param hHal - global pMac structure + init - param to initiate channel list on basis of init/Reinit + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_InitChannelsForCC(tHalHandle hHal, driver_load_type init); +#endif + +/* --------------------------------------------------------------------------- + \fn sme_ResetCountryCodeInformation + \brief this function is to reset the country code current being used back to EEPROM default + this includes channel list and power setting. This is a synchronous API. + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_ResetCountryCodeInformation(tHalHandle hHal, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn sme_GetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed byte count. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf. If pbuf is NULL, as input, *pbLen should be 0. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U32 *pbLen); + +/* --------------------------------------------------------------------------- + \fn sme_GetCurrentRegulatoryDomain + \brief this function is to get the current regulatory domain. This is a synchronous API. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. The function fails if 11d support is turned off. + \param pDomain - Caller allocated buffer to return the current domain. + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t *pDomain); + +/* --------------------------------------------------------------------------- + \fn sme_SetRegulatoryDomain + \brief this function is to set the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. This is a synchronous API. + \param domainId - indicate the domain (defined in the driver) needs to set to. + See v_REGDOMAIN_t for definition + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + + \fn sme_GetRegulatoryDomainForCountry + + \brief To return a regulatory domain base on a country code. This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for input country code. + + \param pDomainId Upon successful return, it is the domain that country belongs to. + If it is NULL, returning success means that the country code is known. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetRegulatoryDomainForCountry(tHalHandle hHal, tANI_U8 *pCountry, v_REGDOMAIN_t *pDomainId); + + + +/* --------------------------------------------------------------------------- + + \fn sme_GetSupportedRegulatoryDomains + + \brief To return a list of supported regulatory domains. This is a synchronous API. + + \param pDomains - pointer to a caller allocated buffer for returned regulatory domains. + + \param pNumDomains For input, this parameter indicates howm many domains pDomains can hold. + Upon return, this parameter has the number for supported domains. If pDomains + doesn't have enough space for all the supported domains, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedRegulatoryDomains(tHalHandle hHal, v_REGDOMAIN_t *pDomains, tANI_U32 *pNumDomains); + +//some support functions +tANI_BOOLEAN sme_Is11dSupported(tHalHandle hHal); +tANI_BOOLEAN sme_Is11hSupported(tHalHandle hHal); +tANI_BOOLEAN sme_IsWmmSupported(tHalHandle hHal); +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus sme_ScanGetBaseChannels( tHalHandle hHal, tCsrChannelInfo * pChannelInfo ); + +typedef void ( *tSmeChangeCountryCallback)(void *pContext); +/* --------------------------------------------------------------------------- + + \fn sme_ChangeCountryCode + + \brief Change Country code from upperlayer during WLAN driver operation. + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param sendRegHint If we want to send reg hint to nl80211 + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeCountryCode( tHalHandle hHal, + tSmeChangeCountryCallback callback, + tANI_U8 *pCountry, + void *pContext, + void* pVosContext, + tAniBool countryFromUserSpace, + tAniBool sendRegHint); + +/* --------------------------------------------------------------------------- + + \fn sme_GenericChangeCountryCode + + \brief Generic API to change country code + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param reg_domain Regulatory domain for the new country code + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GenericChangeCountryCode( tHalHandle hHal, + tANI_U8 *pCountry, + v_REGDOMAIN_t reg_domain); + +#ifdef WLAN_FEATURE_RMC +/* --------------------------------------------------------------------------- + + \fn sme_TXFailMonitorStartStopInd + + \brief Indicate FW about TX Fail Monitor Indication` + + \param hHal - The handle returned by macOpen. + + \param tx_fail_count number of failures after which the firmware sends + an indication to host + + \param txFailIndCallback function to be called after receiving TX Fail + indication + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_TXFailMonitorStartStopInd(tHalHandle hHal, + tANI_U8 tx_fail_count, + void * txFailIndCallback); +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +VOS_STATUS sme_set_per_roam_rxconfig (tHalHandle hHal, v_U8_t sessionId, + v_U16_t minRate, v_U16_t maxRate, v_U8_t minPercentage, + v_U16_t minPktRequired, v_U64_t waitPeriodForNextPERScan); + +VOS_STATUS sme_unset_per_roam_rxconfig (tHalHandle hHal); + +void sme_PERRoamScanStartStop(void *hHal, tANI_U8 start); +#endif + +/* --------------------------------------------------------------------------- + + \fn sme_DHCPStartInd + + \brief Indicate FW about DHCP start event. + + \param hHal - The handle returned by macOpen. + + \param device_mode the mode of the device + + \param sessionId session ID + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ + +eHalStatus sme_DHCPStartInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 sessionId ); + +/* --------------------------------------------------------------------------- + + \fn sme_DHCPStopInd + + \brief Indicate FW about DHCP stop event. + + \param hHal - The handle returned by macOpen. + + \param device_mode the mode of the device + + \param sessionId session ID + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_DHCPStopInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 sessionId ); + + +/* --------------------------------------------------------------------------- + \fn sme_BtcSignalBtEvent + \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the + BT event type and the current operating mode of Libra (full power, + BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy + would be employed. + \param hHal - The handle returned by macOpen. + \param pBtcBtEvent - Pointer to a caller allocated object of type tSmeBtEvent + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE BT Event not passed to HAL. This can happen + if driver has not yet been initialized or if BTC + Events Layer has been disabled. + VOS_STATUS_SUCCESS BT Event passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSignalBtEvent (tHalHandle hHal, tpSmeBtEvent pBtcBtEvent); + +/* --------------------------------------------------------------------------- + \fn sme_BtcSetConfig + \brief API to change the current Bluetooth Coexistence (BTC) configuration + This function should be invoked only after CFG download has completed. + Calling it after sme_HDDReadyInd is recommended. + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); + +/* --------------------------------------------------------------------------- + \fn sme_BtcGetConfig + \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type tSmeBtcConfig. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig); + +/* --------------------------------------------------------------------------- + \fn sme_SetCfgPrivacy + \brief API to set configure privacy parameters + \param hHal - The handle returned by macOpen. + \param pProfile - Pointer CSR Roam profile. + \param fPrivacy - This parameter indicates status of privacy + + \return void + ---------------------------------------------------------------------------*/ +void sme_SetCfgPrivacy(tHalHandle hHal, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy); + +#if defined WLAN_FEATURE_VOWIFI +/* --------------------------------------------------------------------------- + \fn sme_NeighborReportRequest + \brief API to request neighbor report. + \param hHal - The handle returned by macOpen. + \param pRrmNeighborReq - Pointer to a caller allocated object of type + tRrmNeighborReq. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_NeighborReportRequest (tHalHandle hHal, tANI_U8 sessionId, + tpRrmNeighborReq pRrmNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo); +#endif + +//The following are debug APIs to support direct read/write register/memory +//They are placed in SME because HW cannot be access when in LOW_POWER state +//AND not connected. The knowledge and synchronization is done in SME + +//sme_DbgReadRegister +//Caller needs to validate the input values +VOS_STATUS sme_DbgReadRegister(tHalHandle hHal, v_U32_t regAddr, v_U32_t *pRegValue); + +//sme_DbgWriteRegister +//Caller needs to validate the input values +VOS_STATUS sme_DbgWriteRegister(tHalHandle hHal, v_U32_t regAddr, v_U32_t regValue); + +//sme_DbgReadMemory +//Caller needs to validate the input values +//pBuf caller allocated buffer has the length of nLen +VOS_STATUS sme_DbgReadMemory(tHalHandle hHal, v_U32_t memAddr, v_U8_t *pBuf, v_U32_t nLen); + +//sme_DbgWriteMemory +//Caller needs to validate the input values +VOS_STATUS sme_DbgWriteMemory(tHalHandle hHal, v_U32_t memAddr, v_U8_t *pBuf, v_U32_t nLen); + +VOS_STATUS sme_GetWcnssWlanCompiledVersion(tHalHandle hHal, + tSirVersionType *pVersion); +VOS_STATUS sme_GetWcnssWlanReportedVersion(tHalHandle hHal, + tSirVersionType *pVersion); +VOS_STATUS sme_GetWcnssSoftwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize); +VOS_STATUS sme_GetWcnssHardwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize); +eHalStatus sme_RoamRegisterCallback(tHalHandle hHal, + csrRoamCompleteCallback callback, + void *pContext); + +#ifdef FEATURE_WLAN_WAPI +/* --------------------------------------------------------------------------- + \fn sme_RoamSetBKIDCache + \brief The SME API exposed to HDD to allow HDD to provde SME the BKID + candidate list. + \param hHal - Handle to the HAL. The HAL handle is returned by the HAL after + it is opened (by calling halOpen). + \param pBKIDCache - caller allocated buffer point to an array of tBkidCacheInfo + \param numItems - a variable that has the number of tBkidCacheInfo allocated + when retruning, this is the number of items put into pBKIDCache + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems has the number of tBkidCacheInfo. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetBKIDCache( tHalHandle hHal, tANI_U32 sessionId, tBkidCacheInfo *pBKIDCache, + tANI_U32 numItems ); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetBKIDCache + \brief The SME API exposed to HDD to allow HDD to request SME to return its + BKID cache. + \param hHal - Handle to the HAL. The HAL handle is returned by the HAL after + it is opened (by calling halOpen). + \param pNum - caller allocated memory that has the space of the number of + tBkidCacheInfo as input. Upon returned, *pNum has the needed number of entries + in SME cache. + \param pBkidCache - Caller allocated memory that contains BKID cache, if any, + upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetBKIDCache(tHalHandle hHal, tANI_U32 *pNum, + tBkidCacheInfo *pBkidCache); + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetNumBKIDCache + \brief The SME API exposed to HDD to allow HDD to request SME to return the + number of BKID cache entries. + \param hHal - Handle to the HAL. The HAL handle is returned by the HAL after + it is opened (by calling halOpen). + \return tANI_U32 - the number of BKID cache entries. + ---------------------------------------------------------------------------*/ +tANI_U32 sme_RoamGetNumBKIDCache(tHalHandle hHal, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetBKIDCandidateList + \brief a wrapper function to return the BKID candidate list + \param pBkidList - caller allocated buffer point to an array of + tBkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tBkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tBkidCandidateInfo. + \Note: pNumItems is a number of tBkidCandidateInfo, + not sizeof(tBkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetBKIDCandidateList(tHalHandle hHal, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, + tANI_U32 *pNumItems ); +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef FEATURE_OEM_DATA_SUPPORT +/******************************************************************************************** + Oem data related modifications +*********************************************************************************************/ +/* --------------------------------------------------------------------------- + \fn sme_OemDataReq + \param sessionId - session id of session to be used for oem data req. + \param pOemDataReqID - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_OemDataReq(tHalHandle hHal, + tANI_U8 sessionId, + tOemDataReqConfig *, + tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, + void *pContext); + +/* --------------------------------------------------------------------------- + \fn sme_getOemDataRsp + \param pOemDataRsp - A pointer to the response object + \param pOemDataReqID - pointer to an object to get back the request ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_getOemDataRsp(tHalHandle hHal, + tOemDataRsp **pOemDataRsp); + +/* --------------------------------------------------------------------------- + \fn sme_OemDataReqNew + \brief a wrapper function for OEM DATA REQ NEW + \param pOemDataReqNewConfig - Data to be passed to FW + ---------------------------------------------------------------------------*/ +void sme_OemDataReqNew(tHalHandle hHal, + tOemDataReqNewConfig *pOemDataReqNewConfig); + +#endif /*FEATURE_OEM_DATA_SUPPORT*/ + + + +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPSIE + + \brief To update AP's WPS IE. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPWPSIES - pointer to a caller allocated object of tCsrRoamAPWPSIES + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ + +eHalStatus sme_RoamUpdateAPWPSIE(tHalHandle, tANI_U8 sessionId, tSirAPWPSIEs *pAPWPSIES); +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPARSNIEs + + \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs + + \return eHalStatus SUCCESS + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamUpdateAPWPARSNIEs(tHalHandle hHal, tANI_U8 sessionId, tSirRSNie * pAPSirRSNie); + +/* --------------------------------------------------------------------------- + + sme_ChangeMCCBeaconInterval + + \brief To update P2P-GO's beacon Interval. + + \return eHalStatus SUCCESS + FAILURE or RESOURCES + The API finished and failed. + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId); + + + +/* --------------------------------------------------------------------------- + \fn sme_sendBTAmpEvent + \brief API to send the btAMPstate to FW + \param hHal - The handle returned by macOpen. + \param btAmpEvent -- btAMP event + \return eHalStatus SUCCESS + FAILURE or RESOURCES The API finished and failed. + +--------------------------------------------------------------------------- */ + +eHalStatus sme_sendBTAmpEvent(tHalHandle hHal, tSmeBtAmpEvent btAmpEvent); + + + +/* --------------------------------------------------------------------------- + \fn sme_SetHostOffload + \brief API to set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetHostOffload (tHalHandle hHal, tANI_U8 sessionId, + tpSirHostOffloadReq pRequest); + +/* --------------------------------------------------------------------------- + \fn sme_SetKeepAlive + \brief API to set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetKeepAlive (tHalHandle hHal, tANI_U8 sessionId, + tpSirKeepAliveReq pRequest); + +/* ---------------------------------------------------------------------------- + \fn sme_GetOperationChannel + \brief API to get current channel on which STA is parked + this function gives channel information only of infra station or IBSS station. + \param hHal, pointer to memory location and sessionId + \returns eHAL_STATUS_SUCCESS + eHAL_STATUS_FAILURE +-------------------------------------------------------------------------------*/ +eHalStatus sme_GetOperationChannel(tHalHandle hHal, tANI_U32 *pChannel, tANI_U8 sessionId); + +eHalStatus sme_register_mgmt_frame_ind_callback(tHalHandle hHal, + sir_mgmt_frame_ind_callback callback); + +/* --------------------------------------------------------------------------- + + \fn sme_RegisterMgtFrame + + \brief To register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RegisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen); + +/* --------------------------------------------------------------------------- + + \fn sme_DeregisterMgtFrame + + \brief To De-register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen); +/* --------------------------------------------------------------------------- + \fn sme_GetFramesLog + \brief a wrapper function that client calls to register a callback to get + mgmt frames logged + \param flag - flag tells to clear OR send the frame log buffer + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetFramesLog(tHalHandle hHal, tANI_U8 flag); +/* --------------------------------------------------------------------------- + + \fn sme_InitMgmtFrameLogging + + \brief + SME will pass this request to lower mac to initialize Frame Logging. + + \param + + hHal - The handle returned by macOpen. + + wlanFWLoggingInitParam - Params to initialize frame logging + + \return eHalStatus +--------------------------------------------------------------------------- */ +eHalStatus sme_InitMgmtFrameLogging( tHalHandle hHal, + tpSirFWLoggingInitParam wlanFWLoggingInitParam); + + +/* --------------------------------------------------------------------------- + + \fn sme_StopRssiMonitoring + + \brief + SME will pass this request to lower mac to stop monitoring rssi range on + a bssid. + + \param + + hHal - The handle returned by macOpen. + + tSirRssiMonitorReq req- depict the monitor req params. + + \return eHalStatus + +--------------------------------------------------------------------------- */ +eHalStatus sme_StopRssiMonitoring(tHalHandle hHal, + tSirRssiMonitorReq *req); + +/* --------------------------------------------------------------------------- + + \fn sme_StartRssiMonitoring + + \brief + SME will pass this request to lower mac to start monitoring rssi range on + a bssid. + + \param + + hHal - The handle returned by macOpen. + + tSirRssiMonitorReq req- depict the monitor req params. + + \return eHalStatus + +--------------------------------------------------------------------------- */ +eHalStatus sme_StartRssiMonitoring(tHalHandle hHal, + tSirRssiMonitorReq *req); + + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureRxpFilter + + \brief + SME will pass this request to lower mac to set/reset the filter on RXP for + multicast & broadcast traffic. + + \param + + hHal - The handle returned by macOpen. + + filterMask- Currently the API takes a 1 or 0 (set or reset) as filter. + Basically to enable/disable the filter (to filter "all" mcbc traffic) based + on this param. In future we can use this as a mask to set various types of + filters as suggested below: + FILTER_ALL_MULTICAST: + FILTER_ALL_BROADCAST: + FILTER_ALL_MULTICAST_BROADCAST: + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureRxpFilter( tHalHandle hHal, + tpSirWlanSetRxpFilters wlanRxpFilterParam); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureAppsCpuWakeupState + + \brief + SME will pass this request to lower mac to dynamically adjusts the listen + interval based on the WLAN/MSM activity. This feature is named as + Telescopic Beacon wakeup feature. + + \param + + hHal - The handle returned by macOpen. + + isAppsAwake- Depicts the state of the Apps CPU + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureAppsCpuWakeupState( tHalHandle hHal, tANI_BOOLEAN isAppsAwake); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureSuspendInd + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be suspended + + \param + + hHal - The handle returned by macOpen. + + wlanSuspendParam- Depicts the wlan suspend params + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureSuspendInd( tHalHandle hHal, + tpSirWlanSuspendParam wlanSuspendParam); + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureResumeReq + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be Resumed + + \param + + hHal - The handle returned by macOpen. + + wlanResumeParam- Depicts the wlan resume params + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureResumeReq( tHalHandle hHal, + tpSirWlanResumeParam wlanResumeParam); + + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraSessionId + + \brief To get the session ID for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \return sessionid, -1 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_S8 sme_GetInfraSessionId(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraOperationChannel + + \brief To get the operating channel for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param sessionId - the sessionId returned by sme_OpenSession. + + \return operating channel, 0 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_U8 sme_GetInfraOperationChannel( tHalHandle hHal, tANI_U8 sessionId); +/* --------------------------------------------------------------------------- + + \fn sme_GetConcurrentOperationChannel + + \brief To get the operating channel for other concurrent sessions, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param currentPersona - persona that is trying to come up. + + \return operating channel, 0 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_U8 sme_GetConcurrentOperationChannel( tHalHandle hHal ); + +/* --------------------------------------------------------------------------- + \fn sme_AbortMacScan + \brief API to cancel MAC scan. + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId for interface + \return tSirAbortScanStatus return status abort scan + + ---------------------------------------------------------------------------*/ +tSirAbortScanStatus sme_AbortMacScan(tHalHandle hHal, tANI_U8 sessionId, + eCsrAbortReason reason); + +/* --------------------------------------------------------------------------- + \fn sme_GetCfgValidChannels + \brief API to get valid channel list + \param hHal - The handle returned by macOpen. + \param aValidChannels - Pointer to the valid channel list + \param len - valid channel list length + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetCfgValidChannels(tHalHandle hHal, tANI_U8 *aValidChannels, tANI_U32 *len); + +#ifdef FEATURE_WLAN_SCAN_PNO + +/* --------------------------------------------------------------------------- + \fn sme_SetPreferredNetworkList + \brief API to set the Preferred Network List Offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetPreferredNetworkList (tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, preferredNetworkFoundIndCallback callbackRoutine, void *callbackContext ); + +/* --------------------------------------------------------------------------- + \fn sme_SetRSSIFilter + \brief API to set RSSI Filter feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetRSSIFilter(tHalHandle hHal, v_U8_t rssiThreshold); + +/****************************************************************************** +* +* Name: sme_PreferredNetworkFoundInd +* +* Description: +* Invoke Preferred Network Found Indication +* +* Parameters: +* hHal - HAL handle for device +* pMsg - found network description +* +* Returns: eHalStatus +* +******************************************************************************/ +eHalStatus sme_PreferredNetworkFoundInd (tHalHandle hHal, void* pMsg); +#endif // FEATURE_WLAN_SCAN_PNO + +/* --------------------------------------------------------------------------- + \fn sme_SetPowerParams + \brief API to set Power Parameters + \param hHal - The handle returned by macOpen. + \param pwParams - Pointer to the power parameters requested. + \param forced - if true, not to be dropped silently in host, it must reach + FW; It is added to avoid a race condition scenario where LIM hasn't deleted + the session yet before power params gets sent to PMC + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced); + +/* --------------------------------------------------------------------------- + \fn sme_SetTxPerTracking + \brief Set Tx PER tracking configuration parameters + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingParam - Tx PER configuration parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking ( + tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/* --------------------------------------------------------------------------- + \fn sme_ReceiveFilterSetFilter + \brief API to set 8023 Multicast Address List + \param hHal - The handle returned by macOpen. + \param pMulticastAddrs - Pointer to the Multicast Address List + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_8023MulticastList(tHalHandle hHal, tANI_U8 sessionId, tpSirRcvFltMcAddrList pMulticastAddrs); + +/* --------------------------------------------------------------------------- + \fn sme_ReceiveFilterSetFilter + \brief API to set Receive Packet Filter + \param hHal - The handle returned by macOpen. + \param pRcvPktFilterCfg - Receive Packet Filter parameter + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ReceiveFilterSetFilter(tHalHandle hHal, tpSirRcvPktFilterCfgType pRcvPktFilterCfg, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_GetFilterMatchCount + \brief API to get D0 PC Filter Match Count + \param hHal - The handle returned by macOpen + \param callbackRoutine - Callback routine invoked to receive Packet Coalescing Filter Match Count + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetFilterMatchCount(tHalHandle hHal, + FilterMatchCountCallback callbackRoutine, + void *callbackContext, + tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_ReceiveFilterClearFilter + \brief API to clear Receive Packet Filter + \param hHal - The handle returned by macOpen. + \param pRcvFltPktClearParam - Receive Packet Filter Clear parameter + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ReceiveFilterClearFilter(tHalHandle hHal, + tpSirRcvFltPktClearParam pRcvFltPktClearParam, + tANI_U8 sessionId); +#endif // WLAN_FEATURE_PACKET_FILTERING +/* --------------------------------------------------------------------------- + + \fn sme_IsChannelValid + \brief To check if the channel is valid for currently established domain + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param channel - channel to verify + + \return TRUE/FALSE, TRUE if channel is valid + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel); + +/* --------------------------------------------------------------------------- + \fn sme_SetFreqBand + \brief Used to set frequency band. + \param hHal + \eBand band value to be configured + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetFreqBand(tHalHandle hHal, eCsrBand eBand); + +/* --------------------------------------------------------------------------- + \fn sme_GetFreqBand + \brief Used to get the current band settings. + \param hHal + \pBand pointer to hold the current band value + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetFreqBand(tHalHandle hHal, eCsrBand *pBand); + +/* --------------------------------------------------------------------------- + + \fn sme_SetTxPerTracking + \brief Set Tx PER tracking configuration parameters + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingParam - Tx PER configuration parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking ( + tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam); + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_SetGTKOffload + \brief API to set GTK offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pRequest, tANI_U8 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_GetGTKOffload + \brief API to get GTK offload information. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload response. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetGTKOffload (tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +eHalStatus sme_WakeReasonIndCallback (tHalHandle hHal, void* pMsg); +#endif // WLAN_WAKEUP_EVENTS + +/* --------------------------------------------------------------------------- + \fn sme_SetTxPerTracking + \brief Set Tx PER tracking configuration parameters + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingParam - Tx PER configuration parameters + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking ( + tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam); + + +//return frequency for a particular channel +tANI_U16 sme_ChnToFreq(tANI_U8 chanNum); + +tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel); + +#if defined WLAN_FEATURE_P2P_INTERNAL + +eHalStatus sme_p2pResetSession(tHalHandle hHal, tANI_U8 HDDSessionId); + +/* --------------------------------------------------------------------------- + \fn sme_p2pFlushDeviceList + \brief Remove cached P2P result from scan results + \param hHal - The handle returned by macOpen. + \param HDDSessionId - HDD's sessionId. Currently unused. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_p2pFlushDeviceList(tHalHandle hHal, tANI_U8 HDDSessionId); + +eHalStatus sme_p2pGetResultFilter(tHalHandle hHal, tANI_U8 HDDSessionId, + tCsrScanResultFilter *pFilter); + +#endif //#if defined WLAN_FEATURE_P2P_INTERNAL + +/* --------------------------------------------------------------------------- + \fn sme_SetMaxTxPower + \brief Used to set the Maximum Transmit Power dynamically. Note: this + setting will not persist over reboots + \param hHal + \param pBssid BSSID to set the power cap for + \param pBssid pSelfMacAddress self MAC Address + \param pBssid power to set in dB + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr pBssid, + tSirMacAddr pSelfMacAddress, v_S7_t dB); + +/** + * sme_SetMaxTxPowerPerBand() - Set the Maximum Transmit Power + * specific to band dynamically + * @band: Band for which power needs to be applied + * @dB: power to set in dB + * @hal: HAL handle + * + * Set the maximum transmit power dynamically per band + * + * Return: eHalStatus + */ +eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB, + tHalHandle hal); + +/* --------------------------------------------------------------------------- + + \fn sme_SetTxPower + + \brief Set Transmit Power dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param sessionId Target Session ID + \param mW power to set in mW + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPower(tHalHandle hHal, v_U8_t sessionId, v_U8_t mW); + +/* --------------------------------------------------------------------------- + + \fn sme_HideSSID + + \brief Enable/Disables hidden SSID dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param sessionId + \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HideSSID(tHalHandle hHal, v_U8_t sessionId, v_U8_t ssidHidden); + +/* --------------------------------------------------------------------------- + + \fn sme_SetTmLevel + \brief Set Thermal Mitigation Level to RIVA + \param hHal - The handle returned by macOpen. + \param newTMLevel - new Thermal Mitigation Level + \param tmMode - Thermal Mitigation handle mode, default 0 + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTmLevel(tHalHandle hHal, v_U16_t newTMLevel, v_U16_t tmMode); + +/*--------------------------------------------------------------------------- + + \brief sme_featureCapsExchange() - SME interface to exchange capabilities between + Host and FW. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_featureCapsExchange(tHalHandle hHal); + +/*--------------------------------------------------------------------------- + + \brief sme_disableActiveModeOffload() - SME interface to disable Active mode Offload capabilitu + between in Host. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_disableFeatureCapablity(tANI_U8 feature_index); + +/*--------------------------------------------------------------------------- + + \brief sme_GetDefaultCountryCodeFrmNv() - SME interface to get the default + country code + Host and FW. + + \param hHal - HAL handle for device + \param pCountry - pointer to country code + + \return Success or failure + + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetDefaultCountryCodeFrmNv(tHalHandle hHal, tANI_U8 *pCountry); + +/*--------------------------------------------------------------------------- + + \brief sme_GetCurrentCountryCode() - SME interface to get the current operating + country code. + + \param hHal - HAL handle for device + \param pCountry - pointer to country code + + \return Success or failure + + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentCountryCode(tHalHandle hHal, tANI_U8 *pCountry); + +/* --------------------------------------------------------------------------- + \fn sme_transportDebug + \brief Dynamically monitoring Transport channels + Private IOCTL will querry transport channel status if driver loaded + \param hHal Upper MAC context + \param displaySnapshot Display transport channel snapshot option + \param toggleStallDetect Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + \- return NONE + -------------------------------------------------------------------------*/ +void sme_transportDebug(tHalHandle hHal, v_BOOL_t displaySnapshot, v_BOOL_t toggleStallDetect); + +/* --------------------------------------------------------------------------- + \fn sme_ResetPowerValuesFor5G + \brief Reset the power values for 5G band with NV power values. + \param hHal - HAL handle for device + \- return NONE + -------------------------------------------------------------------------*/ +void sme_ResetPowerValuesFor5G (tHalHandle hHal); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamPrefer5GHz + \brief enable/disable Roam prefer 5G runtime option + This function is called through dynamic setConfig callback function + to configure the Roam prefer 5G runtime option + \param hHal - HAL handle for device + \param nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamPrefer5GHz(tHalHandle hHal, v_BOOL_t nRoamPrefer5GHz); + +/* --------------------------------------------------------------------------- + \fn sme_setRoamIntraBand + \brief enable/disable Intra band roaming + This function is called through dynamic setConfig callback function + to configure the intra band roaming + \param hHal - HAL handle for device + \param nRoamIntraBand Enable/Disable Intra band roaming + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setRoamIntraBand(tHalHandle hHal, const v_BOOL_t nRoamIntraBand); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanNProbes + \brief function to update roam scan N probes + This function is called through dynamic setConfig callback function + to update roam scan N probes + \param hHal - HAL handle for device + \param nProbes number of probe requests to be sent out + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanNProbes(tHalHandle hHal, const v_U8_t nProbes); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanHomeAwayTime + \brief function to update roam scan Home away time + This function is called through dynamic setConfig callback function + to update roam scan home away time + \param hHal - HAL handle for device + \param nRoamScanAwayTime Scan home away time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanHomeAwayTime(tHalHandle hHal, + const v_U16_t nRoamScanHomeAwayTime, + const eAniBoolean bSendOffloadCmd); + +/* --------------------------------------------------------------------------- + \fn sme_getRoamIntraBand + \brief get Intra band roaming + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_BOOL_t sme_getRoamIntraBand(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanNProbes + \brief get N Probes + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U8_t sme_getRoamScanNProbes(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanHomeAwayTime + \brief get Roam scan home away time + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U16_t sme_getRoamScanHomeAwayTime(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateImmediateRoamRssiDiff + \brief Update nImmediateRoamRssiDiff + This function is called through dynamic setConfig callback function + to configure nImmediateRoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig gImmediateRoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param nImmediateRoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateImmediateRoamRssiDiff(tHalHandle hHal, v_U8_t nImmediateRoamRssiDiff); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamRssiDiff + \brief Update RoamRssiDiff + This function is called through dynamic setConfig callback function + to configure RoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param RoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamRssiDiff(tHalHandle hHal, v_U8_t RoamRssiDiff); + +/*-------------------------------------------------------------------------- + \brief sme_UpdateFastTransitionEnabled() - enable/disable Fast Transition support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastTransitionEnabled. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isFastTransitionEnabled config successfully. + Other status means SME is failed to update isFastTransitionEnabled. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateFastTransitionEnabled(tHalHandle hHal, + v_BOOL_t isFastTransitionEnabled); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateWESMode + \brief Update WESMode + This function is called through dynamic setConfig callback function + to configure isWESModeEnabled + \param hHal - HAL handle for device + \param isWESModeEnabled - Enable/Disable WES Mode + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateWESMode(tHalHandle hHal, v_BOOL_t isWESModeEnabled); + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamScanControl + \brief Set roam scan control + This function is called to set roam scan control + if roam scan control is set to 0, roaming scan cache is cleared + any value other than 0 is treated as invalid value + \param hHal - HAL handle for device + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME failure to update + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamScanControl(tHalHandle hHal, v_BOOL_t roamScanControl); +#endif /* (WLAN_FEATURE_VOWIFI_11R) || (FEATURE_WLAN_ESE) || (FEATURE_WLAN_LFR) */ + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsFastRoamIniFeatureEnabled() - enable/disable LFR support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastRoamIniFeatureEnabled. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config successfully. + Other status means SME is failed to update isFastRoamIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateIsFastRoamIniFeatureEnabled(tHalHandle hHal, + const v_BOOL_t isFastRoamIniFeatureEnabled); + +/*-------------------------------------------------------------------------- + \brief sme_ConfigFwrRoaming() - enable/disable LFR support at runtime + When Supplicant issue enabled / disable fwr based roaming on the basis + of the Bssid modification in network block ( e.g. AutoJoin mody N/W block) + + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME (enabled/disabled) offload scan successfully. + Other status means SME is failed to (enabled/disabled) offload scan. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_ConfigFwrRoaming(tHalHandle hHal, + const v_BOOL_t isFastRoamEnabled); + +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsMAWCIniFeatureEnabled() - + Enable/disable LFR MAWC support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isMAWCIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update MAWCEnabled config successfully. + Other status means SME is failed to update MAWCEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsMAWCIniFeatureEnabled(tHalHandle hHal, + const v_BOOL_t MAWCEnabled); + + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateEnableFastRoamInConcurrency() - enable/disable LFR if Concurrent session exists + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS + Other status means SME is failed + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateEnableFastRoamInConcurrency(tHalHandle hHal, + v_BOOL_t bFastRoamInConIniFeatureEnabled); +#endif +#endif /* FEATURE_WLAN_LFR */ + +#ifdef FEATURE_WLAN_ESE +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsEseFeatureEnabled() - enable/disable ESE support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isEseIniFeatureEnabled. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config successfully. + Other status means SME is failed to update isEseIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateIsEseFeatureEnabled(tHalHandle hHal, + const v_BOOL_t isEseIniFeatureEnabled); + +#endif /* FEATURE_WLAN_ESE */ + +/*-------------------------------------------------------------------------- + \brief sme_UpdateConfigFwRssiMonitoring() - enable/disable firmware RSSI Monitornig at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + fEnableFwRssiMonitoring. + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring config successfully. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateConfigFwRssiMonitoring(tHalHandle hHal, + v_BOOL_t fEnableFwRssiMonitoring); + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +/*-------------------------------------------------------------------------- + \brief sme_setNeighborLookupRssiThreshold() - update neighbor lookup rssi threshold + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborLookupRssiThreshold(tHalHandle hHal, + v_U8_t neighborLookupRssiThreshold); + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborReassocRssiThreshold() - update neighbor reassoc rssi threshold + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborReassocRssiThreshold(tHalHandle hHal, + v_U8_t neighborReassocRssiThreshold); + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborLookupRssiThreshold() - get neighbor lookup rssi threshold + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getNeighborLookupRssiThreshold(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborScanRefreshPeriod() - set neighbor scan results refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanRefreshPeriod(tHalHandle hHal, + v_U16_t neighborScanResultsRefreshPeriod); + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborScanRefreshPeriod() - get neighbor scan results refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanRefreshPeriod(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_getEmptyScanRefreshPeriod() - get empty scan refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getEmptyScanRefreshPeriod(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateEmptyScanRefreshPeriod + \brief Update nEmptyScanRefreshPeriod + This function is called through dynamic setConfig callback function + to configure nEmptyScanRefreshPeriod + Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param nEmptyScanRefreshPeriod - scan period following empty scan results. + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateEmptyScanRefreshPeriod(tHalHandle hHal, v_U16_t nEmptyScanRefreshPeriod); + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMinChanTime + \brief Update nNeighborScanMinChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMinTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMinTime=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanMinChanTime - Channel minimum dwell time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMinChanTime(tHalHandle hHal, const v_U16_t nNeighborScanMinChanTime); + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMaxChanTime + \brief Update nNeighborScanMaxChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMaxTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMaxTime=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanMinChanTime - Channel maximum dwell time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMaxChanTime(tHalHandle hHal, const v_U16_t nNeighborScanMaxChanTime); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMinChanTime + \brief get neighbor scan min channel time + \param hHal - The handle returned by macOpen. + \return v_U16_t - channel min time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMinChanTime(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMaxChanTime + \brief get neighbor scan max channel time + \param hHal - The handle returned by macOpen. + \return v_U16_t - channel max time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMaxChanTime(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanPeriod + \brief Update nNeighborScanPeriod + This function is called through dynamic setConfig callback function + to configure nNeighborScanPeriod + Usage: adb shell iwpriv wlan0 setConfig nNeighborScanPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanPeriod - neighbor scan period + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanPeriod(tHalHandle hHal, const v_U16_t nNeighborScanPeriod); + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanPeriod + \brief get neighbor scan period + \param hHal - The handle returned by macOpen. + \return v_U16_t - neighbor scan period + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanPeriod(tHalHandle hHal); + +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/*-------------------------------------------------------------------------- + \brief sme_getRoamRssiDiff() - get Roam rssi diff + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getRoamRssiDiff(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_ChangeRoamScanChannelList() - Change roam scan channel list + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList, + tANI_U8 numChannels); + +#ifdef FEATURE_WLAN_ESE_UPLOAD +/*-------------------------------------------------------------------------- + \brief sme_SetEseRoamScanChannelList() - set ese roam scan channel list + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_SetEseRoamScanChannelList(tHalHandle hHal, + tANI_U8 *pChannelList, + tANI_U8 numChannels); +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getRoamScanChannelList() - get roam scan channel list + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_getRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList, + tANI_U8 *pNumChannels); + +/*-------------------------------------------------------------------------- + \brief sme_getIsEseFeatureEnabled() - get ESE feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the ESE feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsEseFeatureEnabled(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_getWESMode() - getWES Mode + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_U8_t - WES Mode Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetWESMode(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_GetRoamScanControl() - get scan control + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_BOOL_t - Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetRoamScanControl(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateEmptyScanRefreshPeriod + \brief Update nnEmptyScanRefreshPeriod + This function is called through dynamic setConfig callback function + to configure nnEmptyScanRefreshPeriod + Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param nEmptyScanRefreshPeriod - scan period following empty scan results. + \- return Success or failure + -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief sme_getIsLfrFeatureEnabled() - get LFR feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsLfrFeatureEnabled(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief sme_getIsFtFeatureEnabled() - get FT feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsFtFeatureEnabled(tHalHandle hHal); + +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamScanOffloadEnabled() - enable/disable roam scan offload feaure + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + gRoamScanOffloadEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamScanOffloadEnabled(tHalHandle hHal, v_BOOL_t nRoamScanOffloadEnabled); +#endif + +eHalStatus sme_FwMemDumpReq(tHalHandle hHal, tAniFwrDumpReq *recv_req); + + +/* --------------------------------------------------------------------------- + \fn sme_IsFeatureSupportedByFW + \brief Check if a feature is enabled by FW + + \param featEnumValue - Enumeration value of the feature to be checked. + A value from enum placeHolderInCapBitmap + + \- return 1/0 (TRUE/FALSE) + -------------------------------------------------------------------------*/ +tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue); + +/* --------------------------------------------------------------------------- + \fn sme_IsFeatureSupportedByDriver + \brief Check if a feature is enabled by driver + + \param featEnumValue - Enumeration value of the feature to be checked. + A value from enum placeHolderInCapBitmap + + \- return 1/0 (TRUE/FALSE) + -------------------------------------------------------------------------*/ +tANI_U8 sme_IsFeatureSupportedByDriver(tANI_U8 featEnumValue); + +#ifdef FEATURE_WLAN_TDLS + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsLinkEstablishParams + \brief API to send TDLS Link Establishment Parameters. + + \param peerMac - peer's Mac Adress. + \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ + +VOS_STATUS sme_SendTdlsLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams); + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsMgmtFrame + \brief API to send TDLS management frames. + + \param peerMac - peer's Mac Adress. + \param frame_type - Type of TDLS mgmt frame to be sent. + \param dialog - dialog token used in the frame. + \param status - status to be incuded in the frame. + \param peerCapability - peerCapability to be incuded in the frame. + \param buf - additional IEs to be included + \param len - lenght of additional Ies + \param responder - Tdls request type + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tANI_U8 frame_type, tANI_U8 dialog, + tANI_U16 status, tANI_U32 peerCapability, + tANI_U8 *buf, tANI_U8 len, tANI_U8 responder); +/* --------------------------------------------------------------------------- + \fn sme_ChangeTdlsPeerSta + \brief API to Update TDLS peer sta parameters. + + \param peerMac - peer's Mac Adress. + \param staParams - Peer Station Parameters. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_ChangeTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrStaParams *pstaParams); +/* --------------------------------------------------------------------------- + \fn sme_AddTdlsPeerSta + \brief API to Add TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_AddTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif + ); +/* --------------------------------------------------------------------------- + \fn sme_DeleteTdlsPeerSta + \brief API to Delete TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif + ); +/* --------------------------------------------------------------------------- + \fn sme_SetTdlsPowerSaveProhibited + \API to set/reset the isTdlsPowerSaveProhibited. + + \- return void + -------------------------------------------------------------------------*/ +void sme_SetTdlsPowerSaveProhibited(tHalHandle hHal, v_BOOL_t val); +#endif +/* --------------------------------------------------------------------------- + \fn sme_IsPmcBmps + \brief API to Check if PMC state is BMPS. + + \- return v_BOOL_t + -------------------------------------------------------------------------*/ +v_BOOL_t sme_IsPmcBmps(tHalHandle hHal); + +eHalStatus sme_UpdateDfsSetting(tHalHandle hHal, tANI_U8 fUpdateEnableDFSChnlScan); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSRoamMode + \brief Update DFS roam scan mode + This function is called to configure allowDFSChannelRoam + dynamically + \param hHal - HAL handle for device + \param allowDFSChannelRoam - DFS roaming scan mode + mode 0 disable roam scan on DFS channels + mode 1 enables roam scan (passive/active) on DFS channels + \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config + successfully. + Other status means SME failed to update DFS roaming scan config. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSRoamMode(tHalHandle hHal, tANI_U8 allowDFSChannelRoam); + +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSScanMode + \brief Update DFS scan mode + This function is called to configure fEnableDFSChnlScan. + \param hHal - HAL handle for device + \param dfsScanMode - DFS scan mode + mode 0 disable scan on DFS channels + mode 1 enables passive scan on DFS channels + mode 2 enables active scan on DFS channels for static list + \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config + successfully. + Other status means SME failed to update DFS scan config. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, tANI_U8 dfsScanMode); + +/*-------------------------------------------------------------------------- + \brief sme_GetDFSScanMode() - get DFS scan mode + \param hHal - The handle returned by macOpen. + \return DFS scan mode + mode 0 disable scan on DFS channels + mode 1 enables passive scan on DFS channels + mode 2 enables active scan on DFS channels for static list + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetDFSScanMode(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_HandleDFSChanScan + \brief Gets Valid channel list and updates scan control list according to + dfsScanMode + \param hHal - HAL handle for device + \return eHAL_STATUS_FAILURE when failed to get valid channel list + Otherwise eHAL_STATUS_SUCCESS - + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_HandleDFSChanScan(tHalHandle hHal); + +/* + * SME API to enable/disable WLAN driver initiated SSR + */ +void sme_UpdateEnableSSR(tHalHandle hHal, tANI_BOOLEAN enableSSR); + +/* --------------------------------------------------------------------------- + + \fn sme_SetPhyMode + + \brief Changes the PhyMode. + + \param hHal - The handle returned by macOpen. + + \param phyMode new phyMode which is to set + + \return eHalStatus SUCCESS. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetPhyMode(tHalHandle hHal, eCsrPhyMode phyMode); + +/* --------------------------------------------------------------------------- + + \fn sme_GetPhyMode + + \brief gets current PhyMode. + + \param hHal - The handle returned by macOpen. + + \return eHalStatus PhyMode + + -------------------------------------------------------------------------------*/ +eCsrPhyMode sme_GetPhyMode(tHalHandle hHal); + +/* + * SME API to determine the channel bonding mode + */ +VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, tANI_U8 channel); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_HandoffRequest() - a wrapper function to Request a handoff + from CSR. + This is a synchronous call + \param hHal - The handle returned by macOpen + \param pHandoffInfo - info provided by HDD with the handoff request (namely: + BSSID, channel etc.) + \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_HandoffRequest(tHalHandle hHal, tCsrHandoffRequest *pHandoffInfo); +#endif +/*-------------------------------------------------------------------------- + \brief sme_isSta_p2p_clientConnected() - a wrapper function to check if there + is any connected session . + This is a synchronous call + \param hHal - The handle returned by macOpen + \return VOS_STATUS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ +VOS_STATUS sme_isSta_p2p_clientConnected(tHalHandle hHal); + +/*-------------------------------------------------------------------------- + \brief hdd_is_any_session_connected() - a wrapper function to check if there + is any connected session . + This is a synchronous call + \param hHal - The handle returned by macOpen + \return VOS_STATUS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ +VOS_STATUS sme_is_any_session_connected(tHalHandle hHal); + +#ifdef FEATURE_WLAN_LPHB +/* --------------------------------------------------------------------------- + \fn sme_LPHBConfigReq + \API to make configuration LPHB within FW. + \param hHal - The handle returned by macOpen + \param lphdReq - LPHB request argument by client + \param pCallbackfn - LPHB timeout notification callback function pointer + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_LPHBConfigReq( + tHalHandle hHal, + tSirLPHBReq *lphdReq, + void (*pCallbackfn)(void *pAdapter, void *indParam)); +#endif /* FEATURE_WLAN_LPHB */ + +/* --------------------------------------------------------------------------- + \fn sme_AddPeriodicTxPtrn + \brief API to Periodic TX Pattern Offload feature + \param hHal - The handle returned by macOpen + \param addPeriodicTxPtrnParams - Pointer to the add pattern structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_AddPeriodicTxPtrn(tHalHandle hHal, tSirAddPeriodicTxPtrn + *addPeriodicTxPtrnParams); + +/* --------------------------------------------------------------------------- + \fn sme_DelPeriodicTxPtrn + \brief API to Periodic TX Pattern Offload feature + \param hHal - The handle returned by macOpen + \param delPeriodicTxPtrnParams - Pointer to the deleting pattern structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_DelPeriodicTxPtrn(tHalHandle hHal, tSirDelPeriodicTxPtrn + *delPeriodicTxPtrnParams); +/*-------------------------------------------------------------------------- + \brief sme_enable_disable_split_scan() - a wrapper function to set the split + scan parameter. + This is a synchronous call + \param hHal - The handle returned by macOpen + \return None. + \sa + --------------------------------------------------------------------------*/ +void sme_enable_disable_split_scan (tHalHandle hHal, tANI_U8 nNumStaChan, + tANI_U8 nNumP2PChan); + +#ifdef WLAN_FEATURE_RMC +/* --------------------------------------------------------------------------- + \fn sme_EnableRMC + \brief Used to enable RMC + setting will not persist over reboots + \param hHal + \param sessionId + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EnableRMC(tHalHandle hHal, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn sme_DisableRMC + \brief Used to disable RMC + setting will not persist over reboots + \param hHal + \param sessionId + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_DisableRMC(tHalHandle hHal, tANI_U32 sessionId); +#endif /* WLAN_FEATURE_RMC */ + +/* --------------------------------------------------------------------------- + \fn sme_SendRateUpdateInd + \brief API to Update rate + \param hHal - The handle returned by macOpen + \param rateUpdateParams - Pointer to rate update params + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, tSirRateUpdateInd *rateUpdateParams); + +#ifdef WLAN_FEATURE_RMC +/* --------------------------------------------------------------------------- + \fn sme_GetIBSSPeerInfo + \brief Used to disable RMC + setting will not persist over reboots + \param hHal + \param ibssPeerInfoReq multicast Group IP address + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_RequestIBSSPeerInfo(tHalHandle hHal, void *pUserData, + pIbssPeerInfoCb peerInfoCbk, + tANI_BOOLEAN allPeerInfoReqd, + tANI_U8 staIdx); +#endif /* WLAN_FEATURE_RMC */ + +/* + * sme API to trigger fast BSS roam to a given BSSID independent of RSSI + * triggers + * return status +*/ +eHalStatus smeIssueFastRoamNeighborAPEvent (tHalHandle hHal, + tANI_U8 *bssid, + tSmeFastRoamTrigger fastRoamTrig, + tANI_U8 channel); + +eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pBSSId, +#else + tANI_U8 *pBSSId, +#endif + tANI_BOOLEAN flush_cache ); + +void smeGetCommandQStatus( tHalHandle hHal ); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* --------------------------------------------------------------------------- + \fn sme_SetBatchScanReq + \brief API to set batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting set batch scan response from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_SetBatchScanReq +( + tHalHandle hHal, tSirSetBatchScanReq *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, tSirSetBatchScanRsp *pRsp), + void *callbackContext +); + +/* --------------------------------------------------------------------------- + \fn sme_TriggerBatchScanResultInd + \brief API to trigger batch scan result indications from from FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to get batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting get batch scan response from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_TriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, void *pRsp), + void *callbackContext +); + +/* --------------------------------------------------------------------------- + \fn sme_StopBatchScanInd + \brief API to stop batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to stop batch indication + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +sme_StopBatchScanInd +( + tHalHandle hHal, tSirStopBatchScanInd *pInd, tANI_U8 sessionId +); + +#endif + +#ifdef FEATURE_WLAN_CH_AVOID +/* --------------------------------------------------------------------------- + \fn sme_AddChAvoidCallback + \brief Used to plug in callback function + Which notify channel may not be used with SAP or P2PGO mode. + Notification come from FW. + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_AddChAvoidCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, void *indParam) +); +#endif /* FEATURE_WLAN_CH_AVOID */ +eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value); + +/* --------------------------------------------------------------------------- + \fn sme_requestTypetoString + \brief API to convert requestType enum values + to string. + ---------------------------------------------------------------------------*/ +const char * sme_requestTypetoString(const v_U8_t requestType); +/* --------------------------------------------------------------------------- + \fn sme_PmcStatetoString + \brief API to convert PmcState enum values + to string. + ---------------------------------------------------------------------------*/ +const char * sme_PmcStatetoString(const v_U8_t pmcState); + +eHalStatus sme_getBcnMissRate(tHalHandle, tANI_U8, void *, void *); + +tANI_BOOLEAN sme_Is11dCountrycode(tHalHandle hHal); + +// tdlsoffchan +VOS_STATUS sme_SendTdlsChanSwitchReq(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tANI_S32 tdlsOffCh, + tANI_S32 tdlsOffChBwOffset, + tANI_U8 tdlsSwMode); +eHalStatus sme_GetFwStats(tHalHandle hHal, tANI_U32 stats, + void *pContext, tSirFWStatsCallback callback); +void sme_SetMiracastMode (tHalHandle hHal,tANI_U8 mode); + +void sme_resetCoexEevent(tHalHandle hHal); + +tANI_U32 sme_GetChannelBondingMode5G(tHalHandle hHal); +tANI_U32 sme_GetChannelBondingMode24G(tHalHandle hHal); +#ifdef WLAN_FEATURE_AP_HT40_24G +void sme_UpdateChannelBondingMode24G(tHalHandle hHal, + tANI_U8 cbMode); +eHalStatus sme_SetHT2040Mode(tHalHandle hHal, + tANI_U8 sessionId, tANI_U8 cbMode); +#endif + +eHalStatus sme_set_rssi_threshold_breached_cb(tHalHandle hal, + void (*cb)(void *, struct rssi_breach_event *)); + +void sme_disable_dfs_channel(tHalHandle hHal, bool disable_dfs); + +/* HDD Callback function */ +typedef void(*pEncryptMsgRSPCb)(void *pUserData, void *infoParam); + +eHalStatus sme_Encryptmsgsend (tHalHandle hHal, + u8 *pCmd, + int length, + pEncryptMsgRSPCb encCB); + +/* --------------------------------------------------------------------------- + \fn sme_RegisterBtCoexTDLSCallback + \brief Used to plug in callback function + Which notify btcoex on or off. + Notification come from FW. + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_RegisterBtCoexTDLSCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, int) +); + +/* --------------------------------------------------------------------------- + \fn smeNeighborMiddleOfRoaming + + \brief This function is a wrapper to call csrNeighborMiddleOfRoaming + + \param hHal - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if reassoc in progress, + eANI_BOOLEAN_FALSE otherwise +---------------------------------------------------------------------------*/ +tANI_BOOLEAN smeNeighborMiddleOfRoaming(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + + \fn sme_IsTdlsOffChannelValid + \brief To check if the channel is valid for currently established domain + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param channel - channel to verify + + \return TRUE/FALSE, TRUE if channel is valid + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsTdlsOffChannelValid(tHalHandle hHal, tANI_U8 channel); + +/* -------------------------------------------------------------------------- + + \fn sme_IsCoexScoIndicationSet + \brief To check if the BTC module in fwr has sent the SCO + indication to host or not + + \param hHal - The handle returned by macOpen. + \return TRUE - Sco call in progress FALSE- No SCO call in progress + + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsCoexScoIndicationSet(tHalHandle hHal); + +eHalStatus sme_SetMiracastVendorConfig(tHalHandle hHal, + tANI_U32 iniNumBuffAdvert, + tANI_U32 set_value); + +void sme_SetDefDot11Mode(tHalHandle hHal); + +/* --------------------------------------------------------------------------- + \fn sme_SetTdls2040BSSCoexistence + \brief API to enable or disable 20_40 BSS Coexistence IE in TDLS frames. + + \param isEnabled - Enable or Disable. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +eHalStatus sme_SetTdls2040BSSCoexistence(tHalHandle hHal, tANI_S32 isEnabled); + +/* --------------------------------------------------------------------------- + \fn sme_SetRtsCtsHtVht + \brief API to to enable/disable RTS/CTS for different modes. + + \param set_value - Bit mask value to enable RTS/CTS for different modes. + \- return VOS_STATUS_SUCCES if INdication is posted to + WDA else return eHAL_STATUS_FAILURE + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRtsCtsHtVht(tHalHandle hHal, tANI_U32 set_value); + +tANI_BOOLEAN sme_handleSetFccChannel(tHalHandle hHal, + tANI_U8 fcc_constraint, + v_U32_t scan_pending); + +eHalStatus sme_DeleteAllTDLSPeers(tHalHandle hHal, uint8_t sessionId); +eHalStatus sme_fatal_event_logs_req(tHalHandle hHal, tANI_U32 is_fatal, + tANI_U32 indicator, tANI_U32 reason_code, + tANI_BOOLEAN dump_vos_trace); + +eHalStatus sme_enableDisableChanAvoidIndEvent(tHalHandle hHal, + tANI_U8 set_value); + +/* --------------------------------------------------------------------------- + \fn sme_set_wificonfig_params + \brief API to set WifiConfiguration Parameters. + + \param wifi_config_param - Wificonfig parameter 1.Averaging factor 2. Guard time + \- return VOS_STATUS_SUCCES if INdication is posted to + WDA else return eHAL_STATUS_FAILURE + -------------------------------------------------------------------------*/ + +eHalStatus sme_set_wificonfig_params(tHalHandle hHal, tSetWifiConfigParams *req); +eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId, + tANI_U32 *regInfo1, tANI_U32 *regInfo2); +eHalStatus sme_GetCurrentAntennaIndex(tHalHandle hHal, + tCsrAntennaIndexCallback callback, + void *pContext, tANI_U8 sessionId); + +eHalStatus sme_setBcnMissPenaltyCount(tHalHandle hHal, + tModifyRoamParamsReqParams *params); +eHalStatus sme_remove_bssid_from_scan_list(tHalHandle hal, + tSirMacAddr bssid); +void sme_set_mgmt_frm_via_wq5(tHalHandle hHal, + tANI_BOOLEAN sendMgmtPktViaWQ5); +eHalStatus sme_update_cfg_int_param(tHalHandle hHal, tANI_U32 cfg_id); + +#ifdef WLAN_FEATURE_APFIND +VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input); +#endif /* WLAN_FEATURE_APFIND */ + +#ifdef SAP_AUTH_OFFLOAD +/** + * sme_set_sap_auth_offload() enable/disable SAP Auth Offload + * @hHal: hal layer handler + * @sap_auth_offload_info: the information of SAP Auth Offload + * + * This function provide enable/disable SAP authenticaiton offload + * feature on target firmware + * + * Return: eHalStatus. + */ +eHalStatus sme_set_sap_auth_offload(tHalHandle hHal, + struct tSirSapOffloadInfo *sap_auth_offload_info); + +#endif /* SAP_AUTH_OFFLOAD */ +#ifdef DHCP_SERVER_OFFLOAD +eHalStatus sme_set_dhcp_srv_offload(tHalHandle hal, + sir_dhcp_srv_offload_info_t *dhcp_srv_info); +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +eHalStatus sme_set_mdns_offload(tHalHandle hal, + sir_mdns_offload_info_t *mdns_info); + +eHalStatus sme_set_mdns_fqdn(tHalHandle hal, + sir_mdns_fqdn_info_t *mdns_fqdn); + +eHalStatus sme_set_mdns_resp(tHalHandle hal, + sir_mdns_resp_info_t *mdns_resp); +#endif /* MDNS_OFFLOAD */ + +eHalStatus sme_update_hb_threshold(tHalHandle hHal, tANI_U32 cfgId, + tANI_U8 hbThresh, eCsrBand eBand); + +eHalStatus sme_capture_tsf_req(tHalHandle hHal, + tSirCapTsfParams capTsfParams); + +eHalStatus sme_get_tsf_req(tHalHandle hHal, + tSirCapTsfParams capTsfParams); + +eHalStatus sme_set_tsfcb(tHalHandle hHal, + tsf_rsp_cb rsp_cb, struct stsf *pTsf, + void *pcallbackcontext); + +/* ARP DEBUG STATS */ +eHalStatus sme_set_nud_debug_stats(tHalHandle hHal, + psetArpStatsParams pSetStatsParam); +eHalStatus sme_get_nud_debug_stats(tHalHandle hHal, + pgetArpStatsParams pGetStatsParam); +eHalStatus sme_del_sta_ba_session_req(tHalHandle hHal, + tDelBaParams sta_del_params); +#endif //#if !defined( __SME_API_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h b/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h new file mode 100644 index 000000000000..0a57aa5e8e0a --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/sme_FTApi.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SME_FTAPI_H ) +#define __SME_FTAPI_H + +#include +#include + +/**========================================================================= + + \brief macros and prototype for SME APIs + + ========================================================================*/ +typedef enum eFTIEState +{ + eFT_START_READY, // Start before and after 11r assoc + eFT_AUTH_REQ_READY, // When we have recvd the 1st or nth auth req + eFT_WAIT_AUTH2, // Sent auth1 and waiting auth2 + eFT_AUTH_COMPLETE, // We are now ready for FT phase, send auth1, recd auth2 + eFT_REASSOC_REQ_WAIT, // Now we have sent Auth Rsp to the supplicant and waiting + // Reassoc Req from the supplicant. + eFT_SET_KEY_WAIT, // We have received the Reassoc request from + // supplicant. Waiting for the keys. +} tFTIEStates; + + +typedef struct sFTSMEContext +{ + tANI_U8 *auth_ft_ies; + tANI_U32 auth_ft_ies_length; + + tANI_U8 *reassoc_ft_ies; + tANI_U16 reassoc_ft_ies_length; + + // Pre-Auth info + tFTIEStates FTState; // The state of FT in the current 11rAssoc + tSirMacAddr preAuthbssId; // BSSID to preauth to + tANI_U32 smeSessionId; + + // Saved pFTPreAuthRsp + tpSirFTPreAuthRsp psavedFTPreAuthRsp; + v_BOOL_t setFTPreAuthState; + v_BOOL_t setFTPTKState; + + // Time to trigger reassoc once pre-auth is successful + vos_timer_t preAuthReassocIntvlTimer; + tCsrRoamSetKey *pCsrFTKeyInfo; + + v_BOOL_t addMDIE; + + tANI_BOOLEAN is_preauth_lfr_mbb; + +#ifdef WLAN_FEATURE_LFR_MBB + vos_timer_t pre_auth_reassoc_mbb_timer; +#endif +} tftSMEContext, *tpftSMEContext; + +/*-------------------------------------------------------------------------- + Prototype functions + ------------------------------------------------------------------------*/ +void sme_FTOpen(tHalHandle hHal); +void sme_FTClose(tHalHandle hHal); +void sme_SetFTIEs( tHalHandle hHal, tANI_U8 sessionId, const tANI_U8 *ft_ies, tANI_U16 ft_ies_length ); +eHalStatus sme_FTUpdateKey( tHalHandle hHal, tCsrRoamSetKey * pFTKeyInfo ); +void csrFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuthRsp ); +void sme_GetFTPreAuthResponse( tHalHandle hHal, tANI_U8 *ft_ies, tANI_U32 ft_ies_ip_len, tANI_U16 *ft_ies_length ); +void sme_GetRICIEs( tHalHandle hHal, tANI_U8 *ric_ies, tANI_U32 ric_ies_ip_len, tANI_U32 *ric_ies_length ); +void sme_PreauthReassocIntvlTimerCallback(void *context); +void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state); +v_BOOL_t sme_GetFTPreAuthState(tHalHandle hHal); +v_BOOL_t sme_GetFTPTKState(tHalHandle hHal); +void sme_SetFTPTKState(tHalHandle hHal, v_BOOL_t state); +#if defined(WLAN_FEATURE_VOWIFI_11R) +void sme_FTReset(tHalHandle hHal); +#endif + + + +#endif //#if !defined( __SME_FTAPI_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/sme_QosApi.h b/drivers/staging/prima/CORE/SME/inc/sme_QosApi.h new file mode 100644 index 000000000000..237a64e7caaf --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/sme_QosApi.h @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SME_QOSAPI_H ) +#define __SME_QOSAPI_H + + +/**========================================================================= + + \file sme_QosApi.h + + \brief prototype for SME QoS APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "aniGlobal.h" +#include "sirApi.h" + +/*-------------------------------------------------------------------------- + Pre-processor Definitions + ------------------------------------------------------------------------*/ +#define SME_QOS_UAPSD_VO 0x01 +#define SME_QOS_UAPSD_VI 0x02 +#define SME_QOS_UAPSD_BE 0x08 +#define SME_QOS_UAPSD_BK 0x04 + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Enumeration of the various QoS status types that would be reported to HDD +---------------------------------------------------------------------------*/ +typedef enum +{ + //async: once PE notifies successful TSPEC negotiation, or CSR notifies for + //successful reassoc, notifies HDD with current QoS Params + SME_QOS_STATUS_SETUP_SUCCESS_IND = 0, + //sync: only when App asked for APSD & it's already set with ACM = 0 + SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY, + //both: sync or async: in case of async notifies HDD with current QoS Params + SME_QOS_STATUS_SETUP_FAILURE_RSP, + //sync + SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP, + //sync: AP doesn't support QoS (WMM) + SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP, + //sync: either req has been sent down to PE or just buffered in SME + SME_QOS_STATUS_SETUP_REQ_PENDING_RSP, + //async: in case of flow aggregation, if the new TSPEC negotiation is + //successful, OR, + //notify existing flows that TSPEC is modified with current QoS Params + SME_QOS_STATUS_SETUP_MODIFIED_IND, + //sync: no APSD asked for & ACM = 0 + SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode right away (eHAL_STATUS_PMC_PENDING) + SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode at all (eHAL_STATUS_FAILURE) + SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED, + + //sync: req has been sent down to PE in case of delts or addts for remain + // flows, OR if the AC doesn't have APSD or ACM + //async: once the downgrade req for QoS params is successful + SME_QOS_STATUS_RELEASE_SUCCESS_RSP = 100, + //both: sync or async: in case of async notifies HDD with current QoS Params + SME_QOS_STATUS_RELEASE_FAILURE_RSP, + //async: AP sent DELTS indication + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + //sync: an addts req has been sent down to PE to downgrade the QoS params or + // just buffered in SME + SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP, + //sync + SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP, + + //async: for QoS modify request if modification is successful, notifies HDD + // with current QoS Params + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND = 200, + //sync: only when App asked for APSD & it's already set with ACM = 0 + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY, + //both: sync or async: in case of async notifies HDD with current QoS Params + SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP, + //sync: either req has been sent down to PE or just buffered in SME + SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP, + //sync: no APSD asked for & ACM = 0 + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP, + //sync + SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode right away (eHAL_STATUS_PMC_PENDING) + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_PENDING, + //async: In case of UAPSD, once PE notifies successful TSPEC negotiation, or + //CSR notifies for successful reassoc to SME-QoS, notify HDD if PMC can't + //put the module in UAPSD mode at all (eHAL_STATUS_FAILURE) + SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED, + //sync: STA is handing off to a new AP + SME_QOS_STATUS_HANDING_OFF = 300, + //async:powersave mode changed by PMC from UAPSD to Full power + SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND = 400, + //async:powersave mode changed by PMC from Full power to UAPSD + SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND, + +}sme_QosStatusType; + +/*--------------------------------------------------------------------------- + Enumeration of the various User priority (UP) types + + From 802.1D/802.11e/WMM specifications (all refer to same table) +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_WMM_UP_BE = 0, + SME_QOS_WMM_UP_BK = 1, + SME_QOS_WMM_UP_RESV = 2, /* Reserved */ + SME_QOS_WMM_UP_EE = 3, + SME_QOS_WMM_UP_CL = 4, + SME_QOS_WMM_UP_VI = 5, + SME_QOS_WMM_UP_VO = 6, + SME_QOS_WMM_UP_NC = 7, + + SME_QOS_WMM_UP_MAX + +}sme_QosWmmUpType; + +/*--------------------------------------------------------------------------- + Enumeration of the various TSPEC directions + + From 802.11e/WMM specifications +---------------------------------------------------------------------------*/ + +typedef enum +{ + SME_QOS_WMM_TS_DIR_UPLINK = 0, + SME_QOS_WMM_TS_DIR_DOWNLINK = 1, + SME_QOS_WMM_TS_DIR_RESV = 2, /* Reserved */ + SME_QOS_WMM_TS_DIR_BOTH = 3, + +}sme_QosWmmDirType; + +/*--------------------------------------------------------------------------- + Enumeration of the various TSPEC ack policies. + + From 802.11 WMM specification +---------------------------------------------------------------------------*/ + +typedef enum +{ + SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK = 0, + SME_QOS_WMM_TS_ACK_POLICY_RESV1 = 1, + SME_QOS_WMM_TS_ACK_POLICY_RESV2 = 2, /* Reserved */ + SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK = 3, + +}sme_QosWmmAckPolicyType; + +/*--------------------------------------------------------------------------- + TS Info field in the WMM TSPEC + + See suggestive values above +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t burst_size_defn; + sme_QosWmmAckPolicyType ack_policy; + sme_QosWmmUpType up; /* User priority */ + v_U8_t psb; /* power-save bit */ + sme_QosWmmDirType direction; /* Direction */ + v_U8_t tid; /* TID : To be filled up by SME-QoS */ +} sme_QosWmmTsInfoType; + +/*--------------------------------------------------------------------------- + The WMM TSPEC Element (from the WMM spec) +---------------------------------------------------------------------------*/ +typedef struct +{ + sme_QosWmmTsInfoType ts_info; + v_U16_t nominal_msdu_size; + v_U16_t maximum_msdu_size; + v_U32_t min_service_interval; + v_U32_t max_service_interval; + v_U32_t inactivity_interval; + v_U32_t suspension_interval; + v_U32_t svc_start_time; + v_U32_t min_data_rate; + v_U32_t mean_data_rate; + v_U32_t peak_data_rate; + v_U32_t max_burst_size; + v_U32_t delay_bound; + v_U32_t min_phy_rate; + v_U16_t surplus_bw_allowance; + v_U16_t medium_time; + v_U8_t expec_psb_byapp; +} sme_QosWmmTspecInfo; + + +/*-------------------------------------------------------------------------- + External APIs + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + \brief sme_QosCallback() - This is a callback function which is registered + per flow while HDD is requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to be sent to HDD. HDD + will notify the application in turn, if needed. + + \param hHal - The handle returned by macOpen. + \param HDDcontext - A cookie passed by HDD during QoS setup, to be used by SME + during any QoS notification (through the callabck) to HDD + \param pCurrentQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM + TSPEC related info as defined above, fed back to HDD + \param status - The status of the flow running on an AC. It could be of + sme_QosStatusType + + \return eHAL_STATUS_SUCCESS - Callback invoke successful. + + + \sa + + --------------------------------------------------------------------------*/ +typedef eHalStatus (*sme_QosCallback)(tHalHandle hHal, void * HDDcontext, + sme_QosWmmTspecInfo * pCurrentQoSInfo, + sme_QosStatusType status, + v_U32_t QosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosSetupReq() - The SME QoS API exposed to HDD to request for QoS + on a particular AC. This function should be called after a link has been + established, i.e. STA is associated with an AP etc. If the request involves + admission control on the requested AC, HDD needs to provide the necessary + Traffic Specification (TSPEC) parameters otherwise SME is going to use the + default params. + + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId returned by sme_OpenSession. Current QOS code doesn't + support multiple session. This function returns failure when different + sessionId is passed in before calling sme_QosReleaseReq. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QoSCallback - The callback which is registered per flow while + requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to + be sent to HDD + \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS + notification (through the callabck) to HDD + \param UPType - Useful only if HDD or any other upper layer module (BAP etc.) + looking for implicit QoS setup, in that + case, the pQoSInfo will be NULL & SME will know about the AC + (from the UP provided in this param) QoS is requested on + \param pQosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow is + successful + + \return SME_QOS_STATUS_SETUP_SUCCESS - Setup request processed successfully. + + Other status means Setup request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosSetupReq(tHalHandle hHal, tANI_U32 sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, void * HDDcontext, + sme_QosWmmUpType UPType, v_U32_t * pQosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosModifyReq() - The SME QoS API exposed to HDD to request for + modification of certain QoS params on a flow running on a particular AC. + This function should be called after a link has been established, i.e. STA is + associated with an AP etc. & a QoS setup has been succesful for that flow. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters & SME might + start the renegotiation process through ADDTS. + + \param hHal - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow has + been successful already + + \return SME_QOS_STATUS_SETUP_SUCCESS - Modification request processed + successfully. + + Other status means request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosModifyReq(tHalHandle hHal, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosReleaseReq() - The SME QoS API exposed to HDD to request for + releasing a QoS flow running on a particular AC. This function should be + called only if a QoS is set up with a valid FlowID. HDD sould invoke this + API only if an explicit request for QoS release has come from Application + + \param hHal - The handle returned by macOpen. + \param QosFlowID - Identification per flow running on each AC generated by SME + It is only meaningful if the QoS setup for the flow is + successful + + \return SME_QOS_STATUS_RELEASE_SUCCESS - Release request processed + successfully. + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosReleaseReq(tHalHandle hHal, v_U32_t QosFlowID); + +/*-------------------------------------------------------------------------- + \brief sme_QosIsTSInfoAckPolicyValid() - The SME QoS API exposed to HDD to + check if TS info ack policy field can be set to "HT-immediate block acknowledgement" + + \param pMac - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info, provided by HDD + \param sessionId - sessionId returned by sme_OpenSession. + + \return VOS_TRUE - Current Association is HT association and so TS info ack policy + can be set to "HT-immediate block acknowledgement" + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosIsTSInfoAckPolicyValid(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId); + +/*-------------------------------------------------------------------------- + \brief sme_QosTspecActive() - The SME QoS API exposed to HDD to + check no of active Tspecs + + \param pMac - The handle returned by macOpen. + \param ac - Determines type of Access Category + \param sessionId - sessionId returned by sme_OpenSession. + + \return VOS_TRUE -When there is no error with pSession + + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosTspecActive(tpAniSirGlobal pMac, + WLANTL_ACEnumType ac, v_U8_t sessionId, v_U8_t *pActiveTspec); + + +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateHandOff() - Function which can be called to update + Hand-off state of SME QoS Session + \param sessionId - session id + \param updateHandOff - value True/False to update the handoff flag + + \sa + +-------------------------------------------------------------------------*/ +void sme_QosUpdateHandOff(v_U8_t sessionId, + v_BOOL_t updateHandOff); + + +/*-------------------------------------------------------------------------- + \brief sme_UpdateDSCPtoUPMapping() - Function which can be called to update + qos mapping table maintained in HDD + \param hHal - The handle returned by macOpen. + \param dscpmapping - pointer to the qos mapping structure in HDD + \param sessionId - session id + + \sa +-------------------------------------------------------------------------*/ +VOS_STATUS sme_UpdateDSCPtoUPMapping(tHalHandle hHal, + sme_QosWmmUpType* dscpmapping, v_U8_t sessionId); + +#endif //#if !defined( __SME_QOSAPI_H ) diff --git a/drivers/staging/prima/CORE/SME/inc/sme_RrmApi.h b/drivers/staging/prima/CORE/SME/inc/sme_RrmApi.h new file mode 100644 index 000000000000..621ac2909f58 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/sme_RrmApi.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __SMERRMAPI_H ) +#define __SMERRMAPI_H + + +/**========================================================================= + + \file sme_RrmApi.h + + \brief prototype for SME RRM APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_lock.h" +#include "vos_trace.h" +#include "vos_memory.h" +#include "vos_types.h" +#include "aniGlobal.h" +#include "sirApi.h" +#include "smeInternal.h" +#include "smeRrmInternal.h" + + +//APIs +eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf); + +VOS_STATUS rrmClose (tpAniSirGlobal pMac); +VOS_STATUS rrmReady (tpAniSirGlobal pMac); +VOS_STATUS rrmOpen (tpAniSirGlobal pMac); +VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig); +VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo); + +tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac); +tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac, tpRrmNeighborReportDesc pBssEntry); +void sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf); + + +#endif diff --git a/drivers/staging/prima/CORE/SME/inc/sme_Trace.h b/drivers/staging/prima/CORE/SME/inc/sme_Trace.h new file mode 100644 index 000000000000..77ff1d689031 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/sme_Trace.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*********************************************************************** + sme_Trace.h + + \brief definition for trace related APIs + + \author Kiran Kumar Reddy CH L V + + ========================================================================*/ + +#ifndef __SME_TRACE_H__ +#define __SME_TRACE_H__ + + +#include "macTrace.h" + +#define NO_SESSION 0xFF + +enum { + TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, + TRACE_CODE_SME_RX_HDD_MSG_CONNECT, + TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, + TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, + TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, + TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE, + TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, + TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, + TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, + TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE, + TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, + TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, + TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, + TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE, + TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE, + TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE, + TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE, + TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER, + TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER, + TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED, + TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER, + TRACE_CODE_SME_RX_HDD_REQUEST_BMPS, + TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, + TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY, + TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, + TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, + TRACE_CODE_SME_RX_HDD_ENTER_WOWL, + TRACE_CODE_SME_RX_HDD_EXIT_WOWL, + TRACE_CODE_SME_RX_HDD_SET_KEY, + TRACE_CODE_SME_RX_HDD_REMOVE_KEY, + TRACE_CODE_SME_RX_HDD_GET_STATS, + TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, + TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE, + TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, + TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT, + TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG, + TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG, + TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, + TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, + TRACE_CODE_SME_RX_HDD_DBG_READREG, + TRACE_CODE_SME_RX_HDD_DBG_WRITEREG, + TRACE_CODE_SME_RX_HDD_DBG_READMEM, + TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM, + TRACE_CODE_SME_RX_HDD_OPEN_SESSION, + TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, + TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, + TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD, + TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD, + TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS, + TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, + TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, + TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, + TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, + TRACE_CODE_SME_RX_HDD_SEND_ACTION, + TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, + TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, + TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, + TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, + TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, + TRACE_CODE_SME_RX_HDD_SET_TXPOW, + TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, + TRACE_CODE_SME_RX_HDD_CAPS_EXCH, + TRACE_CODE_SME_RX_HDD_DISABLE_CAP, + TRACE_CODE_SME_RX_HDD_GET_DEFCCNV, + TRACE_CODE_SME_RX_HDD_GET_CURCC, + TRACE_CODE_SME_RX_HDD_RESET_PW5G, + TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, + TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, + TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, + TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF, + TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF, + TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, + TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE, + TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, + TRACE_CODE_SME_RX_HDD_EXTSCAN_START, + TRACE_CODE_SME_RX_HDD_EXTSCAN_STOP, + TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_BSS_HOTLIST, + TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_BSS_HOTLIST, + TRACE_CODE_SME_RX_HDD_EXTSCAN_GET_CACHED_RESULTS, + TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_SSID_HOTLIST, + TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_SSID_HOTLIST, + TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA, +#ifdef FEATURE_WLAN_TDLS + TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM, + TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ, + TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME, + TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA, + TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA, + TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA, +#endif + TRACE_CODE_SME_RX_HDD_PREF_NET_LIST, +#ifdef FEATURE_WLAN_LPHB + TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ, +#endif /* FEATURE_WLAN_LPHB */ + TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE, + TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ, + TRACE_CODE_SME_TX_HDD_GET_TSF_REQ, + TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ, + /* New trace commands to be added before this comment not at the end */ + /* Trace codes for SME commands */ + TRACE_CODE_SME_COMMAND = 250, + TRACE_CODE_SME_TX_WDA_MSG, + TRACE_CODE_SME_RX_WDA_MSG, +}; + +void smeTraceInit(tpAniSirGlobal pMac); +void sme_register_debug_callback(void); +#endif //__SME_TRACE_H__ diff --git a/drivers/staging/prima/CORE/SME/inc/smsDebug.h b/drivers/staging/prima/CORE/SME/inc/smsDebug.h new file mode 100644 index 000000000000..ec5ae58af8df --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/smsDebug.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file smsDebug.h + + Define debug log interface for SMS. + + ========================================================================== */ + +#ifndef SMS_DEBUG_H__ +#define SMS_DEBUG_H__ + +#include "utilsApi.h" +#include "sirDebug.h" + +#if !defined(__printf) +#define __printf(a,b) +#endif + +void __printf(3,4) +smsLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...); + +void __printf(3,4) +pmcLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...); + +#endif // __SMS_DEBUG_H__ diff --git a/drivers/staging/prima/CORE/SME/inc/wlan_ps_wow_diag.h b/drivers/staging/prima/CORE/SME/inc/wlan_ps_wow_diag.h new file mode 100644 index 000000000000..cce93fdedc5c --- /dev/null +++ b/drivers/staging/prima/CORE/SME/inc/wlan_ps_wow_diag.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef _WLAN_PS_WOW_DIAG_H_ +#define _WLAN_PS_WOW_DIAG_H_ + + +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +typedef enum +{ + WLAN_BMPS_ENTER_REQ =0, + WLAN_UAPSD_START_REQ =1, + WLAN_UAPSD_STOP_REQ =2, + WLAN_ENTER_STANDBY_REQ =3, + WLAN_ENTER_DEEP_SLEEP_REQ =4, + WLAN_START_BMPS_AUTO_TIMER_REQ =5, + WLAN_STOP_BMPS_AUTO_TIMER_REQ =6, + WLAN_IMPS_ENTER_REQ =7, + WLAN_ENTER_FULL_POWER_REQ =8, + WLAN_PMC_CURRENT_STATE =9, + WLAN_PS_MODE_ENABLE_REQ =10, + WLAN_PS_MODE_DISABLE_REQ =11, + WLAN_WINMOB_D_POWER_STATE =12, + WLAN_BMPS_DTIM_PERIOD =13, + WLAN_BMPS_FINAL_LI =14, + WLAN_BMPS_SET_CONFIG =15, + +} wlan_ps_evt_subtype_t; + +// maps directly to eRequestFullPowerReason +typedef enum +{ + WLAN_MISSED_BEACON_IND_RCVD, /* PE received a MAX_MISSED_BEACON_IND */ + WLAN_BMPS_STATUS_IND_RCVD, /* PE received a SIR_HAL_BMPS_STATUS_IND */ + WLAN_BMPS_MODE_DISABLED, /* BMPS mode was disabled by HDD in SME */ + WLAN_LINK_DISCONNECTED_BY_HDD, /* Link has been disconnected requested by HDD */ + WLAN_LINK_DISCONNECTED_BY_OTHER,/* Disconnect due to linklost or requested by peer */ + WLAN_FULL_PWR_NEEDED_BY_HDD, /* HDD request full power for some reason */ + WLAN_FULL_PWR_NEEDED_BY_BAP, /* BAP request full power for BT_AMP */ + WLAN_FULL_PWR_NEEDED_BY_CSR, /* CSR requests full power */ + WLAN_FULL_PWR_NEEDED_BY_QOS, /* QOS requests full power */ + WLAN_REASON_OTHER /* No specific reason. General reason code */ + +} wlan_ps_full_power_request_reason_t; + +// maps directly to ePmcState +typedef enum +{ + WLAN_PMC_STOPPED, /* PMC is stopped */ + WLAN_PMC_FULL_POWER, /* full power */ + WLAN_PMC_LOW_POWER, /* low power */ + WLAN_PMC_REQUEST_IMPS, /* requesting IMPS */ + WLAN_PMC_IMPS, /* in IMPS */ + WLAN_PMC_REQUEST_BMPS, /* requesting BMPS */ + WLAN_PMC_BMPS, /* in BMPS */ + WLAN_PMC_REQUEST_FULL_POWER, /* requesting full power */ + WLAN_PMC_REQUEST_START_UAPSD, /* requesting Start UAPSD */ + WLAN_PMC_REQUEST_STOP_UAPSD, /* requesting Stop UAPSD */ + WLAN_PMC_UAPSD, /* in UAPSD */ + WLAN_PMC_REQUEST_STANDBY, /* requesting standby mode */ + WLAN_PMC_STANDBY, /* in standby mode */ + WLAN_PMC_REQUEST_ENTER_WOWL, /* requesting enter WOWL */ + WLAN_PMC_REQUEST_EXIT_WOWL, /* requesting exit WOWL */ + WLAN_PMC_WOWL /* Chip in WOWL mode */ + +} wlan_ps_pmc_current_state_t; + +// maps directly to ePmcPowerSavingMode +typedef enum +{ + WLAN_IDLE_MODE_POWER_SAVE, /* Idle Mode Power Save (IMPS) */ + WLAN_BEACON_MODE_POWER_SAVE, /* Beacon Mode Power Save (BMPS) */ + WLAN_SPATIAL_MULTIPLEX_POWER_SAVE, /* Spatial Multiplexing Power Save (SMPS) */ + WLAN_UAPSD_MODE_POWER_SAVE, /* Unscheduled Automatic Power Save Delivery Mode */ + WLAN_STANDBY_MODE_POWER_SAVE, /* Standby Power Save Mode */ + WLAN_WOWL_MODE_POWER_SAVE /* Wake-on-Wireless LAN Power Save Mode */ + +} wlan_ps_enable_disable_ps_mode_t; + +typedef enum +{ + WLAN_D0, + WLAN_D1, + WLAN_D2, + WLAN_D3, + WLAN_D4 + +} wlan_ps_winmob_d_power_state_t; + +typedef enum +{ + WLAN_WOW_ENTER_REQ =0, + WLAN_WOW_EXIT_REQ =1, + WLAN_WOW_DEL_PTRN_REQ =2, + WLAN_WOW_WAKEUP = 3 + +} wlan_ps_wow_evt_subtype_t; + +typedef enum +{ + WLAN_WOW_TYPE_NONE, + WLAN_WOW_TYPE_MAGIC_PKT_ONLY, + WLAN_WOW_TYPE_PTRN_BYTE_MATCH_ONLY, + WLAN_WOW_TYPE_MAGIC_PKT_PTRN_BYTE_MATCH, + +} wlan_ps_wow_type_t; + +typedef enum +{ + WLAN_WOW_MAGIC_PKT_MATCH, + WLAN_WOW_PTRN_BYTE_MATCH + +} wlan_ps_wos_wakeup_cause_t; + +#endif // FEATURE_WLAN_DIAG_SUPPORT + +#endif // _WLAN_PS_WOW_DIAG_H_ + diff --git a/drivers/staging/prima/CORE/SME/src/QoS/sme_Qos.c b/drivers/staging/prima/CORE/SME/src/QoS/sme_Qos.c new file mode 100644 index 000000000000..a4fb0437f959 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/QoS/sme_Qos.c @@ -0,0 +1,8390 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file sme_Qos.c + + \brief implementation for SME QoS APIs + + + ========================================================================*/ +/* $Header$ */ +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + +#include "aniGlobal.h" + +#include "smeInside.h" +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" + +#ifdef WLAN_FEATURE_VOWIFI_11R +#include "smsDebug.h" +#include "utilsParser.h" +#endif +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include +#endif + +#include "vos_utils.h" + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/* TODO : 6Mbps as Cisco APs seem to like only this value; analysis req. */ +#define SME_QOS_MIN_PHY_RATE 0x5B8D80 +#define SME_QOS_SURPLUS_BW_ALLOWANCE 0x2000 /* Ratio of 1.0 */ +/*--------------------------------------------------------------------------- + Max values to bound tspec params against and avoid rollover +---------------------------------------------------------------------------*/ +#define SME_QOS_32BIT_MAX 0xFFFFFFFF +#define SME_QOS_16BIT_MAX 0xFFFF +#define SME_QOS_16BIT_MSB 0x8000 +/*--------------------------------------------------------------------------- + Adds y to x, but saturates at 32-bit max to avoid rollover +---------------------------------------------------------------------------*/ +#define SME_QOS_BOUNDED_U32_ADD_Y_TO_X( _x, _y ) \ + do \ + { \ + (_x) = ( (SME_QOS_32BIT_MAX-(_x))<(_y) ) ? \ + (SME_QOS_32BIT_MAX) : (_x)+(_y); \ + } while(0) +/*--------------------------------------------------------------------------- + As per WMM spec there could be max 2 TSPEC running on the same AC with + different direction. We will refer each TSPEC with an index +---------------------------------------------------------------------------*/ +#define SME_QOS_TSPEC_INDEX_0 0 +#define SME_QOS_TSPEC_INDEX_1 1 +#define SME_QOS_TSPEC_INDEX_MAX 2 +#define SME_QOS_TSPEC_MASK_BIT_1_SET 1 +#define SME_QOS_TSPEC_MASK_BIT_2_SET 2 +#define SME_QOS_TSPEC_MASK_BIT_1_2_SET 3 +#define SME_QOS_TSPEC_MASK_CLEAR 0 + +//which key to search on, in the flowlist (1 = flowID, 2 = AC, 4 = reason) +#define SME_QOS_SEARCH_KEY_INDEX_1 1 +#define SME_QOS_SEARCH_KEY_INDEX_2 2 +#define SME_QOS_SEARCH_KEY_INDEX_3 4 +#define SME_QOS_SEARCH_KEY_INDEX_4 8 // ac + direction +#define SME_QOS_SEARCH_KEY_INDEX_5 0x10 // ac + tspec_mask +//special value for searching any Session Id +#define SME_QOS_SEARCH_SESSION_ID_ANY CSR_ROAM_SESSION_MAX +#define SME_QOS_ACCESS_POLICY_EDCA 1 +#define SME_QOS_MAX_TID 255 +#define SME_QOS_TSPEC_IE_LENGTH 61 +#define SME_QOS_TSPEC_IE_TYPE 2 +#define SME_QOS_MIN_FLOW_ID 1 +#define SME_QOS_MAX_FLOW_ID 0xFFFFFFFE +#define SME_QOS_INVALID_FLOW_ID 0xFFFFFFFF +// per the WMM Specification v1.2 Section 2.2.10 +// The Dialog Token field shall be set [...] to a non-zero value +#define SME_QOS_MIN_DIALOG_TOKEN 1 +#define SME_QOS_MAX_DIALOG_TOKEN 0xFF +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + Enumeration of the various states in the QoS state m/c +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_CLOSED = 0, + SME_QOS_INIT, + SME_QOS_LINK_UP, + SME_QOS_REQUESTED, + SME_QOS_QOS_ON, + SME_QOS_HANDOFF, + +}sme_QosStates; +/*--------------------------------------------------------------------------- + Enumeration of the various Release QoS trigger +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_RELEASE_DEFAULT = 0, + SME_QOS_RELEASE_BY_AP, +}sme_QosRelTriggers; +/*--------------------------------------------------------------------------- + Enumeration of the various QoS cmds +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_SETUP_REQ = 0, + SME_QOS_RELEASE_REQ, + SME_QOS_MODIFY_REQ, + SME_QOS_RESEND_REQ, + SME_QOS_CMD_MAX +}sme_QosCmdType; +/*--------------------------------------------------------------------------- + Enumeration of the various QoS reason codes to be used in the Flow list +---------------------------------------------------------------------------*/ +typedef enum +{ + SME_QOS_REASON_SETUP = 0, + SME_QOS_REASON_RELEASE, + SME_QOS_REASON_MODIFY, + SME_QOS_REASON_MODIFY_PENDING, + SME_QOS_REASON_REQ_SUCCESS, + SME_QOS_REASON_MAX +}sme_QosReasonType; + +/*--------------------------------------------------------------------------- + Table to map user priority passed in as an argument to appropriate Access + Category as specified in 802.11e/WMM +---------------------------------------------------------------------------*/ +sme_QosEdcaAcType sme_QosUPtoACMap[SME_QOS_WMM_UP_MAX] = +{ + SME_QOS_EDCA_AC_BE, /* User Priority 0 */ + SME_QOS_EDCA_AC_BK, /* User Priority 1 */ + SME_QOS_EDCA_AC_BK, /* User Priority 2 */ + SME_QOS_EDCA_AC_BE, /* User Priority 3 */ + SME_QOS_EDCA_AC_VI, /* User Priority 4 */ + SME_QOS_EDCA_AC_VI, /* User Priority 5 */ + SME_QOS_EDCA_AC_VO, /* User Priority 6 */ + SME_QOS_EDCA_AC_VO /* User Priority 7 */ +}; + +/*--------------------------------------------------------------------------- + Table to map access category (AC) to appropriate user priority as specified + in 802.11e/WMM + Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs + Mapping is done for consistency +---------------------------------------------------------------------------*/ +sme_QosWmmUpType sme_QosACtoUPMap[SME_QOS_EDCA_AC_MAX] = +{ + SME_QOS_WMM_UP_BE, /* AC BE */ + SME_QOS_WMM_UP_BK, /* AC BK */ + SME_QOS_WMM_UP_VI, /* AC VI */ + SME_QOS_WMM_UP_VO /* AC VO */ +}; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's FLOW Link List structure. This list can hold information per + flow/request, like TSPEC params requested, which AC it is running on +---------------------------------------------------------------------------*/ +typedef struct sme_QosFlowInfoEntry_s +{ + tListElem link; /* list links */ + v_U8_t sessionId; + v_U8_t tspec_mask; + sme_QosReasonType reason; + v_U32_t QosFlowID; + sme_QosEdcaAcType ac_type; + sme_QosWmmTspecInfo QoSInfo; + void * HDDcontext; + sme_QosCallback QoSCallback; + v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after + //handoff, will set to FALSE once done with + //the process. Helps SME to decide if at all + //to notify HDD/LIS for flow renewal after HO +} sme_QosFlowInfoEntry; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's setup request cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosSetupCmdInfo_s +{ + v_U32_t QosFlowID; + sme_QosWmmTspecInfo QoSInfo; + void *HDDcontext; + sme_QosCallback QoSCallback; + sme_QosWmmUpType UPType; + v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after + //handoff, will set to FALSE once done with + //the process. Helps SME to decide if at all + //to notify HDD/LIS for flow renewal after HO +} sme_QosSetupCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's modify cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosModifyCmdInfo_s +{ + v_U32_t QosFlowID; + sme_QosEdcaAcType ac; + sme_QosWmmTspecInfo QoSInfo; +} sme_QosModifyCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's resend cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosResendCmdInfo_s +{ + v_U8_t tspecMask; + sme_QosEdcaAcType ac; + sme_QosWmmTspecInfo QoSInfo; +} sme_QosResendCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's release cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosReleaseCmdInfo_s +{ + v_U32_t QosFlowID; +} sme_QosReleaseCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's buffered cmd related information structure. +---------------------------------------------------------------------------*/ +typedef struct sme_QosCmdInfo_s +{ + sme_QosCmdType command; + tpAniSirGlobal pMac; + v_U8_t sessionId; + union + { + sme_QosSetupCmdInfo setupCmdInfo; + sme_QosModifyCmdInfo modifyCmdInfo; + sme_QosResendCmdInfo resendCmdInfo; + sme_QosReleaseCmdInfo releaseCmdInfo; + }u; +} sme_QosCmdInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's buffered cmd List structure. This list can hold information + related to any pending cmd from HDD +---------------------------------------------------------------------------*/ +typedef struct sme_QosCmdInfoEntry_s +{ + tListElem link; /* list links */ + sme_QosCmdInfo cmdInfo; +} sme_QosCmdInfoEntry; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's Per AC information structure. This can hold information on + how many flows running on the AC, the current, previous states the AC is in +---------------------------------------------------------------------------*/ +typedef struct sme_QosACInfo_s +{ + v_U8_t num_flows[SME_QOS_TSPEC_INDEX_MAX]; + sme_QosStates curr_state; + sme_QosStates prev_state; + sme_QosWmmTspecInfo curr_QoSInfo[SME_QOS_TSPEC_INDEX_MAX]; + sme_QosWmmTspecInfo requested_QoSInfo[SME_QOS_TSPEC_INDEX_MAX]; + v_BOOL_t reassoc_pending;//reassoc requested for APSD + //As per WMM spec there could be max 2 TSPEC running on the same AC with + //different direction. We will refer each TSPEC with an index + v_U8_t tspec_mask_status; //status showing if both the indices are in use + v_U8_t tspec_pending;//tspec negotiation going on for which index + v_BOOL_t hoRenewal;//set to TRUE while re-negotiating flows after + //handoff, will set to FALSE once done with + //the process. Helps SME to decide if at all + //to notify HDD/LIS for flow renewal after HO +#ifdef WLAN_FEATURE_VOWIFI_11R + v_U8_t ricIdentifier[SME_QOS_TSPEC_INDEX_MAX]; + /* stores the ADD TS response for each AC. The ADD TS response is formed by + parsing the RIC received in the the reassoc response */ + tSirAddtsRsp addTsRsp[SME_QOS_TSPEC_INDEX_MAX]; +#endif + sme_QosRelTriggers relTrig; + +} sme_QosACInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's Per session information structure. This can hold information + on the state of the session +---------------------------------------------------------------------------*/ +typedef struct sme_QosSessionInfo_s +{ + // what is this entry's session id + v_U8_t sessionId; + // is the session currently active + v_BOOL_t sessionActive; + // All AC info for this session + sme_QosACInfo ac_info[SME_QOS_EDCA_AC_MAX]; + // Bitmask of the ACs with APSD on + // Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored + v_U8_t apsdMask; + // association information for this session + sme_QosAssocInfo assocInfo; + // ID assigned to our reassoc request + v_U32_t roamID; + // maintaining a powersave status in QoS module, to be fed back to PMC at + // times through the sme_QosPmcCheckRoutine + v_BOOL_t readyForPowerSave; + // are we in the process of handing off to a different AP + v_BOOL_t handoffRequested; + // following reassoc or AddTS has UAPSD already been requested from PMC + v_BOOL_t uapsdAlreadyRequested; + // commands that are being buffered for this session + tDblLinkList bufferedCommandList; + +#ifdef WLAN_FEATURE_VOWIFI_11R + v_BOOL_t ftHandoffInProgress; +#endif + +} sme_QosSessionInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + Search key union. We can use the flowID, ac type, or reason to find an entry + in the flow list +---------------------------------------------------------------------------*/ +typedef union sme_QosSearchKey_s +{ + v_U32_t QosFlowID; + sme_QosEdcaAcType ac_type; + sme_QosReasonType reason; +}sme_QosSearchKey; +/*--------------------------------------------------------------------------- +DESCRIPTION + We can either use the flowID or the ac type to find an entry in the flow list. + The index is a bitmap telling us which key to use. Starting from LSB, + bit 0 - Flow ID + bit 1 - AC type +---------------------------------------------------------------------------*/ +typedef struct sme_QosSearchInfo_s +{ + v_U8_t sessionId; + v_U8_t index; + sme_QosSearchKey key; + sme_QosWmmDirType direction; + v_U8_t tspec_mask; +}sme_QosSearchInfo; +/*--------------------------------------------------------------------------- +DESCRIPTION + SME QoS module's internal control block. +---------------------------------------------------------------------------*/ +struct sme_QosCb_s +{ + //global Mac pointer + tpAniSirGlobal pMac; + //All Session Info + sme_QosSessionInfo sessionInfo[CSR_ROAM_SESSION_MAX]; + //All FLOW info + tDblLinkList flow_list; + //default TSPEC params + sme_QosWmmTspecInfo def_QoSInfo[SME_QOS_EDCA_AC_MAX]; + //counter for assigning Flow IDs + v_U32_t nextFlowId; + //counter for assigning Dialog Tokens + v_U8_t nextDialogToken; +}sme_QosCb; +typedef eHalStatus (*sme_QosProcessSearchEntry)(tpAniSirGlobal pMac, tListElem *pEntry); +/*-------------------------------------------------------------------------- + Internal function declarations + ------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalSetupReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, + void * HDDcontext, + sme_QosWmmUpType UPType, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd, + v_BOOL_t hoRenewal); +sme_QosStatusType sme_QosInternalModifyReq(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd); +sme_QosStatusType sme_QosInternalReleaseReq(tpAniSirGlobal pMac, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd); +sme_QosStatusType sme_QosSetup(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo *pTspec_Info, + sme_QosEdcaAcType ac); +eHalStatus sme_QosAddTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pTspec_Info, + sme_QosEdcaAcType ac); +eHalStatus sme_QosDelTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask); +eHalStatus sme_QosProcessAddTsRsp(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosProcessDelTsInd(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosProcessDelTsRsp(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosProcessAssocCompleteEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessReassocSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessReassocFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessDisconnectEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessJoinReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessHandoffAssocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessHandoffSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessHandoffFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +#ifdef WLAN_FEATURE_VOWIFI_11R +eHalStatus sme_QosProcessPreauthSuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessSetKeySuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info); +eHalStatus sme_QosProcessAggrQosRsp(tpAniSirGlobal pMac, void *pMsgBuf); +eHalStatus sme_QosFTAggrQosReq( tpAniSirGlobal pMac, v_U8_t sessionId ); +#endif +eHalStatus sme_QosProcessAddTsSuccessRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp); +eHalStatus sme_QosProcessAddTsFailureRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp); +eHalStatus sme_QosAggregateParams( + sme_QosWmmTspecInfo * pInput_Tspec_Info, + sme_QosWmmTspecInfo * pCurrent_Tspec_Info, + sme_QosWmmTspecInfo * pUpdated_Tspec_Info); +static eHalStatus sme_QosUpdateParams(v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask, + sme_QosWmmTspecInfo * pTspec_Info); +sme_QosWmmUpType sme_QosAcToUp(sme_QosEdcaAcType ac); +sme_QosEdcaAcType sme_QosUpToAc(sme_QosWmmUpType up); +v_BOOL_t sme_QosIsACM(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes); +tListElem *sme_QosFindInFlowList(sme_QosSearchInfo search_key); +eHalStatus sme_QosFindAllInFlowList(tpAniSirGlobal pMac, + sme_QosSearchInfo search_key, + sme_QosProcessSearchEntry fnp); +static void sme_QosStateTransition(v_U8_t sessionId, + sme_QosEdcaAcType ac, + sme_QosStates new_state); +eHalStatus sme_QosBufferCmd(sme_QosCmdInfo *pcmd, v_BOOL_t insert_head); +static eHalStatus sme_QosProcessBufferedCmd(v_U8_t sessionId); +eHalStatus sme_QosSaveAssocInfo(sme_QosSessionInfo *pSession, sme_QosAssocInfo *pAssoc_info); +eHalStatus sme_QosSetupFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosModificationNotifyFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosModifyFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosDelTsIndFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosReassocSuccessEvFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosAddTsFailureFnp(tpAniSirGlobal pMac, tListElem *pEntry); +eHalStatus sme_QosAddTsSuccessFnp(tpAniSirGlobal pMac, tListElem *pEntry); +static v_BOOL_t sme_QosIsRspPending(v_U8_t sessionId, sme_QosEdcaAcType ac); +static v_BOOL_t sme_QosIsUapsdActive(void); +void sme_QosPmcFullPowerCallback(void *callbackContext, eHalStatus status); +void sme_QosPmcStartUapsdCallback(void *callbackContext, eHalStatus status); +v_BOOL_t sme_QosPmcCheckRoutine(void *callbackContext); +void sme_QosPmcDeviceStateUpdateInd(void *callbackContext, tPmcState pmcState); +eHalStatus sme_QosProcessOutOfUapsdMode(tpAniSirGlobal pMac); +eHalStatus sme_QosProcessIntoUapsdMode(tpAniSirGlobal pMac); +static eHalStatus sme_QosBufferExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId); +static eHalStatus sme_QosDeleteExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId); +static void sme_QosCleanupCtrlBlkForHandoff(tpAniSirGlobal pMac, + v_U8_t sessionId); +static eHalStatus sme_QosDeleteBufferedRequests(tpAniSirGlobal pMac, + v_U8_t sessionId); +v_BOOL_t sme_QosValidateRequestedParams(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId); + +extern eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme); +extern eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme); +static eHalStatus qosIssueCommand( tpAniSirGlobal pMac, v_U8_t sessionId, + eSmeCommandType cmdType, sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, v_U8_t tspec_mask ); +/* + sme_QosReRequestAddTS to re-send AddTS for the combined QoS request +*/ +static sme_QosStatusType sme_QosReRequestAddTS(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, + v_U8_t tspecMask); +static void sme_QosInitACs(tpAniSirGlobal pMac, v_U8_t sessionId); +static eHalStatus sme_QosRequestReassoc(tpAniSirGlobal pMac, tANI_U8 sessionId, + tCsrRoamModifyProfileFields *pModFields, + v_BOOL_t fForce ); +static v_U32_t sme_QosAssignFlowId(void); +static v_U8_t sme_QosAssignDialogToken(void); +static eHalStatus sme_QosUpdateTspecMask(v_U8_t sessionId, + sme_QosSearchInfo search_key, + v_U8_t new_tspec_mask); +/*-------------------------------------------------------------------------- + External APIs definitions + ------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------------- + \brief sme_QosOpen() - This function must be called before any API call to + SME QoS module. + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosOpen(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + v_U8_t sessionId; + eHalStatus status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: initializing SME-QoS module", + __func__, __LINE__); + //init the control block + //(note that this will make all sessions invalid) + vos_mem_zero(&sme_QosCb, sizeof(sme_QosCb)); + sme_QosCb.pMac = pMac; + sme_QosCb.nextFlowId = SME_QOS_MIN_FLOW_ID; + sme_QosCb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN; + //init flow list + status = csrLLOpen(pMac->hHdd, &sme_QosCb.flow_list); + if (!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot initialize Flow List", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + pSession->sessionId = sessionId; + // initialize the session's per-AC information + sme_QosInitACs(pMac, sessionId); + // initialize the session's buffered command list + status = csrLLOpen(pMac->hHdd, &pSession->bufferedCommandList); + if (!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot initialize cmd list for session %d", + __func__, __LINE__, + sessionId); + return eHAL_STATUS_FAILURE; + } + pSession->readyForPowerSave = VOS_TRUE; + } + //the routine registered here gets called by PMC whenever the device is about + //to enter one of the power save modes. PMC runs a poll with all the + //registered modules if device can enter powersave mode or remain full power + if(!HAL_STATUS_SUCCESS( + pmcRegisterPowerSaveCheck(pMac, sme_QosPmcCheckRoutine, pMac))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot register with pmcRegisterPowerSaveCheck()", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + //the routine registered here gets called by PMC whenever there is a device + // state change. PMC might go to full power because of many reasons and this + // is the way for PMC to inform all the other registered modules so that + // everyone is in sync. + if(!HAL_STATUS_SUCCESS( + pmcRegisterDeviceStateUpdateInd(pMac, sme_QosPmcDeviceStateUpdateInd, pMac))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot register with pmcRegisterDeviceStateUpdateInd()", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: done initializing SME-QoS module", + __func__, __LINE__); + return eHAL_STATUS_SUCCESS; +} +/* -------------------------------------------------------------------------- + \brief sme_QosClose() - To close down SME QoS module. There should not be + any API call into this module after calling this function until another + call of sme_QosOpen. + \param pMac - Pointer to the global MAC parameter structure. + + \return eHalStatus +----------------------------------------------------------------------------*/ +eHalStatus sme_QosClose(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + sme_QosEdcaAcType ac; + v_U8_t sessionId; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: closing down SME-QoS", + __func__, __LINE__); + // deregister with PMC + if(!HAL_STATUS_SUCCESS( + pmcDeregisterDeviceStateUpdateInd(pMac, sme_QosPmcDeviceStateUpdateInd))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister with pmcDeregisterDeviceStateUpdateInd()", + __func__, __LINE__); + } + if(!HAL_STATUS_SUCCESS( + pmcDeregisterPowerSaveCheck(pMac, sme_QosPmcCheckRoutine))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister with pmcDeregisterPowerSaveCheck()", + __func__, __LINE__); + } + //cleanup control block + //close the flow list + csrLLClose(&sme_QosCb.flow_list); + // shut down all of the sessions + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if (pSession == NULL) + continue; + + sme_QosInitACs(pMac, sessionId); + // this session doesn't require UAPSD + pSession->apsdMask = 0; + + pSession->uapsdAlreadyRequested = VOS_FALSE; + pSession->handoffRequested = VOS_FALSE; + pSession->readyForPowerSave = VOS_TRUE; + pSession->roamID = 0; + //need to clean up buffered req + sme_QosDeleteBufferedRequests(pMac, sessionId); + //need to clean up flows + sme_QosDeleteExistingFlows(pMac, sessionId); + + // Clean up the assoc info if already allocated + if (pSession->assocInfo.pBssDesc) { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + + // close the session's buffered command list + csrLLClose(&pSession->bufferedCommandList); + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + sme_QosStateTransition(sessionId, ac, SME_QOS_CLOSED); + } + pSession->sessionActive = VOS_FALSE; + pSession->readyForPowerSave = VOS_TRUE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: closed down QoS", + __func__, __LINE__); + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosSetupReq() - The SME QoS API exposed to HDD to request for QoS + on a particular AC. This function should be called after a link has been + established, i.e. STA is associated with an AP etc. If the request involves + admission control on the requested AC, HDD needs to provide the necessary + Traffic Specification (TSPEC) parameters otherwise SME is going to use the + default params. + + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId returned by sme_OpenSession. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QoSCallback - The callback which is registered per flow while + requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to + be sent to HDD + \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS + notification (through the callabck) to HDD + \param UPType - Useful only if HDD or any other upper layer module (BAP etc.) + looking for implicit QoS setup, in that + case, the pQoSInfo will be NULL & SME will know about the AC + (from the UP provided in this param) QoS is requested on + \param pQosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow is + successful + + \return eHAL_STATUS_SUCCESS - Setup is successful. + + Other status means Setup request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosSetupReq(tHalHandle hHal, tANI_U32 sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, + void * HDDcontext, + sme_QosWmmUpType UPType, v_U32_t * pQosFlowID) +{ + sme_QosSessionInfo *pSession; + eHalStatus lock_status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + sme_QosStatusType status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Setup requested by client on session %d", + __func__, __LINE__, + sessionId); + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + //Make sure the session is valid + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Supplied Session ID %d is invalid", + __func__, __LINE__, + sessionId); + status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + else + { + //Make sure the session is active + pSession = &sme_QosCb.sessionInfo[sessionId]; + if (!pSession->sessionActive) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Supplied Session ID %d is inactive", + __func__, __LINE__, + sessionId); + status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + else + { + //Assign a Flow ID + *pQosFlowID = sme_QosAssignFlowId(); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS request on session %d assigned Flow ID %d", + __func__, __LINE__, + sessionId, *pQosFlowID); + //Call the internal function for QoS setup, + // adding a layer of abstraction + status = sme_QosInternalSetupReq(pMac, (v_U8_t)sessionId, pQoSInfo, + QoSCallback, HDDcontext, UPType, + *pQosFlowID, VOS_FALSE, VOS_FALSE); + } + } + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS setup return status on session %d is %d", + __func__, __LINE__, + sessionId, status); + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosModifyReq() - The SME QoS API exposed to HDD to request for + modification of certain QoS params on a flow running on a particular AC. + This function should be called after a link has been established, i.e. STA is + associated with an AP etc. & a QoS setup has been succesful for that flow. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters & SME might + start the renegotiation process through ADDTS. + + \param hHal - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow has + been successful already + + \return SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful. + + Other status means request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosModifyReq(tHalHandle hHal, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID) +{ + eHalStatus lock_status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + sme_QosStatusType status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Modify requested by client for Flow %d", + __func__, __LINE__, + QosFlowID); + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + //Call the internal function for QoS modify, adding a layer of abstraction + status = sme_QosInternalModifyReq(pMac, pQoSInfo, QosFlowID, VOS_FALSE); + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Modify return status on Flow %d is %d", + __func__, __LINE__, + QosFlowID, status); + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosReleaseReq() - The SME QoS API exposed to HDD to request for + releasing a QoS flow running on a particular AC. This function should be + called only if a QoS is set up with a valid FlowID. HDD sould invoke this + API only if an explicit request for QoS release has come from Application + + \param hHal - The handle returned by macOpen. + \param QosFlowID - Identification per flow running on each AC generated by SME + It is only meaningful if the QoS setup for the flow is + successful + + \return eHAL_STATUS_SUCCESS - Release is successful. + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosReleaseReq(tHalHandle hHal, v_U32_t QosFlowID) +{ + eHalStatus lock_status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + sme_QosStatusType status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Release requested by client for Flow %d", + __func__, __LINE__, + QosFlowID); + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + //Call the internal function for QoS release, adding a layer of abstraction + status = sme_QosInternalReleaseReq(pMac, QosFlowID, VOS_FALSE); + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Release return status on Flow %d is %d", + __func__, __LINE__, + QosFlowID, status); + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosSetParams() - This function is used by HDD to provide the + default TSPEC params to SME. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info per AC as defined above, provided by HDD + + \return eHAL_STATUS_SUCCESS - Setparam is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSetParams(tpAniSirGlobal pMac, sme_QosWmmTspecInfo * pQoSInfo) +{ + sme_QosEdcaAcType ac; + // find the AC + ac = sme_QosUpToAc(pQoSInfo->ts_info.up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Invalid AC %d (via UP %d)", + __func__, __LINE__, + ac, pQoSInfo->ts_info.up ); + return eHAL_STATUS_FAILURE; + } + //copy over the default params for this AC + sme_QosCb.def_QoSInfo[ac] = *pQoSInfo; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS default params set for AC %d (via UP %d)", + __func__, __LINE__, + ac, pQoSInfo->ts_info.up ); + return eHAL_STATUS_SUCCESS; +} + +void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + vos_mem_zero( &pCommand->u.qosCmd, sizeof( tGenericQosCmd ) ); + smeReleaseCommand( pMac, pCommand ); +} + +/*-------------------------------------------------------------------------- + \brief sme_QosMsgProcessor() - sme_ProcessMsg() calls this function for the + messages that are handled by SME QoS module. + + \param pMac - Pointer to the global MAC parameter structure. + \param msg_type - the type of msg passed by PE as defined in wniApi.h + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry; + tSmeCmd *pCommand; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: msg = %d for QoS", + __func__, __LINE__, msg_type); + //switch on the msg type & make the state transition accordingly + switch(msg_type) + { + case eWNI_SME_ADDTS_RSP: + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandAddTs == pCommand->command ) + { + status = sme_QosProcessAddTsRsp(pMac, pMsgBuf); + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + qosReleaseCommand( pMac, pCommand ); + } + smeProcessPendingQueue( pMac ); + } + } + break; + case eWNI_SME_DELTS_RSP: + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandDelTs == pCommand->command ) + { + status = sme_QosProcessDelTsRsp(pMac, pMsgBuf); + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + qosReleaseCommand( pMac, pCommand ); + } + smeProcessPendingQueue( pMac ); + } + } + break; + case eWNI_SME_DELTS_IND: + status = sme_QosProcessDelTsInd(pMac, pMsgBuf); + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_AGGR_QOS_RSP: + status = sme_QosProcessAggrQosRsp(pMac, pMsgBuf); + break; +#endif + + default: + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: unknown msg type = %d", + __func__, __LINE__, msg_type); + break; + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosValidateParams() - The SME QoS API exposed to CSR to validate AP + capabilities regarding QoS support & any other QoS parameter validation. + + \param pMac - Pointer to the global MAC parameter structure. + \param pBssDesc - Pointer to the BSS Descriptor information passed down by + CSR to PE while issuing the Join request + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosValidateParams(tpAniSirGlobal pMac, + tSirBssDescription *pBssDesc) +{ + tDot11fBeaconIEs *pIes = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: validation for QAP & APSD", + __func__, __LINE__); + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: csrGetParsedBssDescriptionIEs() failed", + __func__, __LINE__); + break; + } + //check if the AP is QAP & it supports APSD + if( !CSR_IS_QOS_BSS(pIes) ) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: AP doesn't support QoS", + __func__, __LINE__); + + break; + } + if(!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) && + !(pIes->WMMInfoAp.uapsd)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: AP doesn't support APSD", + __func__, __LINE__); + break; + } + status = eHAL_STATUS_SUCCESS; + }while(0); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: validated with status = %d", + __func__, __LINE__, status); + if(pIes) + { + vos_mem_free(pIes); + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosCsrEventInd() - The QoS sub-module in SME expects notifications + from CSR when certain events occur as mentioned in sme_QosCsrEventIndType. + \param pMac - Pointer to the global MAC parameter structure. + \param ind - The event occurred of type sme_QosCsrEventIndType. + \param pEvent_info - Information related to the event + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosCsrEventInd(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosCsrEventIndType ind, + void *pEvent_info) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On Session %d Event %d received from CSR", + __func__, __LINE__, + sessionId, ind ); + switch(ind) + { + case SME_QOS_CSR_ASSOC_COMPLETE: + //expecting assoc info in pEvent_info + status = sme_QosProcessAssocCompleteEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_REASSOC_REQ: + //nothing expected in pEvent_info + status = sme_QosProcessReassocReqEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_REASSOC_COMPLETE: + //expecting assoc info in pEvent_info + status = sme_QosProcessReassocSuccessEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_REASSOC_FAILURE: + //nothing expected in pEvent_info + status = sme_QosProcessReassocFailureEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_DISCONNECT_REQ: + case SME_QOS_CSR_DISCONNECT_IND: + //nothing expected in pEvent_info + status = sme_QosProcessDisconnectEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_JOIN_REQ: + //nothing expected in pEvent_info + status = sme_QosProcessJoinReqEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_HANDOFF_ASSOC_REQ: + //nothing expected in pEvent_info + status = sme_QosProcessHandoffAssocReqEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_HANDOFF_COMPLETE: + //nothing expected in pEvent_info + status = sme_QosProcessHandoffSuccessEv(pMac, sessionId, pEvent_info); + break; + case SME_QOS_CSR_HANDOFF_FAILURE: + //nothing expected in pEvent_info + status = sme_QosProcessHandoffFailureEv(pMac, sessionId, pEvent_info); + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case SME_QOS_CSR_PREAUTH_SUCCESS_IND: + status = sme_QosProcessPreauthSuccessInd(pMac, sessionId, pEvent_info); + break; +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + case SME_QOS_CSR_SET_KEY_SUCCESS_IND: + status = sme_QosProcessSetKeySuccessInd(pMac, sessionId, pEvent_info); + break; +#endif +#endif + default: + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d Unknown Event %d received from CSR", + __func__, __LINE__, + sessionId, ind ); + break; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On Session %d processed Event %d with status %d", + __func__, __LINE__, + sessionId, ind, status ); + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosGetACMMask() - The QoS sub-module API to find out on which ACs + AP mandates Admission Control (ACM = 1) + (Bit0:VO; Bit1:VI; Bit2:BK; Bit3:BE all other bits are ignored) + \param pMac - Pointer to the global MAC parameter structure. + \param pSirBssDesc - The event occurred of type sme_QosCsrEventIndType. + + \return a bit mask indicating for which ACs AP has ACM set to 1 + + \sa + + --------------------------------------------------------------------------*/ +v_U8_t sme_QosGetACMMask(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes) +{ + sme_QosEdcaAcType ac; + v_U8_t acm_mask = 0; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked", + __func__, __LINE__); + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + if(sme_QosIsACM(pMac, pSirBssDesc, ac, pIes)) + { + acm_mask = acm_mask | (1 << (SME_QOS_EDCA_AC_VO - ac)); + } + + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: mask is %d", + __func__, __LINE__, acm_mask); + return acm_mask; +} +/*-------------------------------------------------------------------------- + Internal function definitions + ------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------- + \brief sme_QosInternalSetupReq() - The SME QoS internal setup request handling + function. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters otherwise SME + is going to use the default params. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QoSCallback - The callback which is registered per flow while + requesting for QoS. Used for any notification for the + flow (i.e. setup success/failure/release) which needs to + be sent to HDD + \param HDDcontext - A cookie passed by HDD to be used by SME during any QoS + notification (through the callabck) to HDD + \param UPType - Useful only if HDD or any other upper layer module (BAP etc.) + looking for implicit QoS setup, in that + case, the pQoSInfo will be NULL & SME will know about the AC + (from the UP provided in this param) QoS is requested on + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow is + successful + \param buffered_cmd - tells us if the cmd was a buffered one or fresh from + client + + \return eHAL_STATUS_SUCCESS - Setup is successful. + + Other status means Setup request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalSetupReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosCallback QoSCallback, + void * HDDcontext, + sme_QosWmmUpType UPType, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd, + v_BOOL_t hoRenewal) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + sme_QosWmmTspecInfo Tspec_Info; + sme_QosStates new_state = SME_QOS_CLOSED; + sme_QosFlowInfoEntry *pentry = NULL; + sme_QosCmdInfo cmd; + sme_QosStatusType status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + v_U8_t tmask = 0; + v_U8_t new_tmask = 0; + sme_QosSearchInfo search_key; + v_BOOL_t bufferCommand; + eHalStatus hstatus; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for flow %d", + __func__, __LINE__, + sessionId, QosFlowID); + pSession = &sme_QosCb.sessionInfo[sessionId]; + // if caller sent an empty TSPEC, fill up with the default one + if(!pQoSInfo) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: caller sent an empty QoS param list, using defaults", + __func__, __LINE__); + // find the AC with UPType passed in + ac = sme_QosUpToAc(UPType); + if(SME_QOS_EDCA_AC_MAX == ac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, + ac, UPType); + + return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP; + } + Tspec_Info = sme_QosCb.def_QoSInfo[ac]; + } + else + { + // find the AC + ac = sme_QosUpToAc(pQoSInfo->ts_info.up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, + ac, pQoSInfo->ts_info.up); + + return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP; + } + //validate QoS params + if(!sme_QosValidateRequestedParams(pMac, pQoSInfo, sessionId)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid params", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_INVALID_PARAMS_RSP; + } + Tspec_Info = *pQoSInfo; + } + pACInfo = &pSession->ac_info[ac]; + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + // assume we won't have to (re)buffer the command + bufferCommand = VOS_FALSE; + //check to consider the following flowing scenario + //Addts request is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the setup request for flow %d in state %d " + "since another request is pending", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + else + { + // make sure we are in full power so that we can issue + // an AddTS or reassoc if necessary + hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, + pSession, eSME_REASON_OTHER); + if( eHAL_STATUS_PMC_PENDING == hstatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the setup request for flow %d in state %d, " + "waiting for full power", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + } + if (bufferCommand) + { + // we need to buffer the command + cmd.command = SME_QOS_SETUP_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.setupCmdInfo.HDDcontext = HDDcontext; + cmd.u.setupCmdInfo.QoSInfo = Tspec_Info; + cmd.u.setupCmdInfo.QoSCallback = QoSCallback; + cmd.u.setupCmdInfo.UPType = UPType; + cmd.u.setupCmdInfo.hoRenewal = hoRenewal; + cmd.u.setupCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the setup request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Buffered setup request for flow = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + } + + //get into the state m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + //call the internal qos setup logic to decide on if the + // request is NOP, or need reassoc for APSD and/or need to send out ADDTS + status = sme_QosSetup(pMac, sessionId, &Tspec_Info, ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_LINK_UP " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)|| + (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + // we received an expected "good" status + //create an entry in the flow list + pentry = vos_mem_malloc(sizeof(*pentry)); + if (!pentry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the new " + "entry in the Flow List", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + pentry->ac_type = ac; + pentry->HDDcontext = HDDcontext; + pentry->QoSCallback = QoSCallback; + pentry->hoRenewal = hoRenewal; + pentry->QosFlowID = QosFlowID; + pentry->sessionId = sessionId; + // since we are in state SME_QOS_LINK_UP this must be the + // first TSPEC on this AC, so use index 0 (mask bit 1) + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0] = Tspec_Info; + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + if(pACInfo->tspec_mask_status && + !pACInfo->reassoc_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d with AC %d in state " + "SME_QOS_LINK_UP tspec_mask_status is %d " + "but should not be set yet", + __func__, __LINE__, + sessionId, ac, pACInfo->tspec_mask_status); + //ASSERT + VOS_ASSERT(0); + vos_mem_free(pentry); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET; + if(!pACInfo->reassoc_pending) + { + // we didn't request for reassoc, it must be a tspec negotiation + pACInfo->tspec_pending = 1; + } + + pentry->reason = SME_QOS_REASON_SETUP; + new_state = SME_QOS_REQUESTED; + } + else + { + // SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP or + // SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY + pentry->reason = SME_QOS_REASON_REQ_SUCCESS; + new_state = SME_QOS_QOS_ON; + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET; + pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = Tspec_Info; + if(buffered_cmd && !pentry->hoRenewal) + { + QoSCallback(pMac, HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + status, + pentry->QosFlowID); + } + pentry->hoRenewal = VOS_FALSE; + } + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]++; + + //indicate on which index the flow entry belongs to & add it to the + //Flow List at the end + pentry->tspec_mask = pACInfo->tspec_mask_status; + pentry->QoSInfo = Tspec_Info; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Creating entry on session %d at %p with flowID %d", + __func__, __LINE__, + sessionId, pentry, QosFlowID); + csrLLInsertTail(&sme_QosCb.flow_list, &pentry->link, VOS_TRUE); + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = pACInfo->curr_state; + if(buffered_cmd && hoRenewal) + { + QoSCallback(pMac, HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + QosFlowID); + } + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: Buffering setup request for flow %d in state = %d", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + //buffer cmd + cmd.command = SME_QOS_SETUP_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.setupCmdInfo.HDDcontext = HDDcontext; + cmd.u.setupCmdInfo.QoSInfo = Tspec_Info; + cmd.u.setupCmdInfo.QoSCallback = QoSCallback; + cmd.u.setupCmdInfo.UPType = UPType; + cmd.u.setupCmdInfo.hoRenewal = hoRenewal; + cmd.u.setupCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d couldn't buffer the setup " + "request for flow %d in state = %d", + __func__, __LINE__, + sessionId, QosFlowID, pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + new_state = pACInfo->curr_state; + break; + case SME_QOS_QOS_ON: + + //check if multiple flows running on the ac + if((pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] > 0)|| + (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0)) + { + //do we need to care about the case where APSD needed on ACM = 0 below? + if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) || + sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tspec_mask_status = %d for AC = %d", + __func__, __LINE__, + pACInfo->tspec_mask_status, ac); + if(!pACInfo->tspec_mask_status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: tspec_mask_status can't be 0 for ac = %d in " + "state = %d", + __func__, __LINE__, + ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return status; + } + /* Flow aggregation */ + if(((pACInfo->tspec_mask_status > 0) && + (pACInfo->tspec_mask_status <= SME_QOS_TSPEC_INDEX_MAX))) + { + /* Either of upstream, downstream or bidirectional flows are present */ + /* If either of new stream or current stream is for bidirecional, aggregate + * the new stream with the current streams present and send out aggregated Tspec.*/ + if((Tspec_Info.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) || + (pACInfo->curr_QoSInfo[pACInfo->tspec_mask_status - 1]. + ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH)) + { + // Aggregate the new stream with the current stream(s). + tmask = pACInfo->tspec_mask_status; + } + /* None of new stream or current (aggregated) streams are for bidirectional. + * Check if the new stream direction matches the current stream direction. */ + else if(pACInfo->curr_QoSInfo[pACInfo->tspec_mask_status - 1]. + ts_info.direction == Tspec_Info.ts_info.direction) + { + // Aggregate the new stream with the current stream(s). + tmask = pACInfo->tspec_mask_status; + } + /* New stream is in different direction. */ + else + { + // No Aggregation. Mark the 2nd tpsec index also as active. + tmask = SME_QOS_TSPEC_MASK_CLEAR; + new_tmask = SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~pACInfo->tspec_mask_status; + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_2_SET; + } + } + else if(SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status) + { + /* Both uplink and downlink streams are present. */ + /* If new stream is bidirectional, aggregate new stream with all existing + * upstreams and downstreams. Send out new aggregated tpsec. */ + if(Tspec_Info.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) + { + // Only one tspec index (0) will be in use after this aggregation. + tmask = SME_QOS_TSPEC_MASK_BIT_1_2_SET; + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_SET; + } + /* New stream is also uni-directional + * Find out the tsepc index with which it needs to be aggregated */ + else if(pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.direction != + Tspec_Info.ts_info.direction) + { + // Aggregate with 2nd tspec index + tmask = SME_QOS_TSPEC_MASK_BIT_2_SET; + } + else + { + // Aggregate with 1st tspec index + tmask = SME_QOS_TSPEC_MASK_BIT_1_SET; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: wrong tmask = %d", __func__, __LINE__, + pACInfo->tspec_mask_status ); + } + } + else + { + //ACM = 0 + // We won't be sending a TSPEC to the AP but we still need + // to aggregate to calculate trigger frame parameters + tmask = SME_QOS_TSPEC_MASK_BIT_1_SET; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tmask = %d, new_tmask = %d in state = %d", + __func__, __LINE__, + tmask, new_tmask, pACInfo->curr_state ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tspec_mask_status = %d for AC = %d", + __func__, __LINE__, + pACInfo->tspec_mask_status, ac); + if(tmask) + { + // create the aggregate TSPEC + if(tmask != SME_QOS_TSPEC_MASK_BIT_1_2_SET) + { + hstatus = sme_QosAggregateParams(&Tspec_Info, + &pACInfo->curr_QoSInfo[tmask - 1], + &pACInfo->requested_QoSInfo[tmask - 1]); + } + else + { + /* Aggregate the new bidirectional stream with the existing upstreams and + * downstreams in tspec indices 0 and 1. */ + tmask = SME_QOS_TSPEC_MASK_BIT_1_SET; + + if((hstatus = sme_QosAggregateParams(&Tspec_Info, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + &pACInfo->requested_QoSInfo[tmask - 1])) + == eHAL_STATUS_SUCCESS) + { + hstatus = sme_QosAggregateParams(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1], + &pACInfo->requested_QoSInfo[tmask - 1], + NULL); + } + } + + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: failed to aggregate params", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + } + else + { + if (!(new_tmask > 0 && new_tmask <= SME_QOS_TSPEC_INDEX_MAX)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: ArrayIndexOutOfBoundsException", + __func__, __LINE__); + + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + tmask = new_tmask; + pACInfo->requested_QoSInfo[tmask-1] = Tspec_Info; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no flows running for ac = %d while in state = %d", + __func__, __LINE__, + ac, pACInfo->curr_state ); + //ASSERT + VOS_ASSERT(0); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return status; + } + //although aggregating, make sure to request on the correct UP,TID,PSB + //and direction + pACInfo->requested_QoSInfo[tmask - 1].ts_info.up = Tspec_Info.ts_info.up; + pACInfo->requested_QoSInfo[tmask - 1].ts_info.tid = + Tspec_Info.ts_info.tid; + pACInfo->requested_QoSInfo[tmask - 1].ts_info.direction = + Tspec_Info.ts_info.direction; + pACInfo->requested_QoSInfo[tmask - 1].ts_info.psb = + Tspec_Info.ts_info.psb; + status = sme_QosSetup(pMac, sessionId, + &pACInfo->requested_QoSInfo[tmask - 1], ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if((SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status)|| + (SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + // we received an expected "good" status + //create an entry in the flow list + pentry = (sme_QosFlowInfoEntry *) vos_mem_malloc(sizeof(*pentry)); + if (!pentry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the new " + "entry in the Flow List", + __func__, __LINE__); + return SME_QOS_STATUS_SETUP_FAILURE_RSP; + } + pentry->ac_type = ac; + pentry->HDDcontext = HDDcontext; + pentry->QoSCallback = QoSCallback; + pentry->hoRenewal = hoRenewal; + pentry->QosFlowID = QosFlowID; + pentry->sessionId = sessionId; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Creating flow %d", + __func__, __LINE__, + QosFlowID); + if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status)|| + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + new_state = pACInfo->curr_state; + pentry->reason = SME_QOS_REASON_REQ_SUCCESS; + pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0]; + if(buffered_cmd && !pentry->hoRenewal) + { + QoSCallback(pMac, HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + status, + pentry->QosFlowID); + } + if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) + { + // if we are not in handoff, then notify all flows on + // this AC that the aggregate TSPEC may have changed + if(!pentry->hoRenewal) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosSetupFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't notify other " + "entries on this AC =%d", + __func__, __LINE__, ac); + } + } + } + pentry->hoRenewal = VOS_FALSE; + } + else + { + // SME_QOS_STATUS_SETUP_REQ_PENDING_RSP + new_state = SME_QOS_REQUESTED; + pentry->reason = SME_QOS_REASON_SETUP; + //Need this info when addts comes back from PE to know on + //which index of the AC the request was from + pACInfo->tspec_pending = tmask; + } + if(tmask) + pACInfo->num_flows[tmask - 1]++; + else + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: ArrayIndexOutOfBoundsException", + __func__, __LINE__); + //indicate on which index the flow entry belongs to & add it to the + //Flow List at the end + pentry->tspec_mask = tmask; + pentry->QoSInfo = Tspec_Info; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d creating entry at %p with flowID %d", + __func__, __LINE__, + sessionId, pentry, QosFlowID); + csrLLInsertTail(&sme_QosCb.flow_list, &pentry->link, VOS_TRUE); + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = pACInfo->curr_state; + } + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: setup requested in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + VOS_ASSERT(0); + new_state = pACInfo->curr_state; + } + /* if current state is same as previous no need for transistion, + if we are doing reassoc & we are already in handoff state, no need to move + to requested state. But make sure to set the previous state as requested + state + */ + if((new_state != pACInfo->curr_state)&& + (!(pACInfo->reassoc_pending && + (SME_QOS_HANDOFF == pACInfo->curr_state)))) + { + sme_QosStateTransition(sessionId, ac, new_state); + } + + if(pACInfo->reassoc_pending && + (SME_QOS_HANDOFF == pACInfo->curr_state)) + { + pACInfo->prev_state = SME_QOS_REQUESTED; + } + if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosInternalModifyReq() - The SME QoS internal function to request + for modification of certain QoS params on a flow running on a particular AC. + If the request involves admission control on the requested AC, HDD needs to + provide the necessary Traffic Specification (TSPEC) parameters & SME might + start the renegotiation process through ADDTS. + + \param pMac - Pointer to the global MAC parameter structure. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info as defined above, provided by HDD + \param QosFlowID - Identification per flow running on each AC generated by + SME. + It is only meaningful if the QoS setup for the flow has + been successful already + + \return SME_QOS_STATUS_SETUP_SUCCESS_RSP - Modification is successful. + + Other status means request failed + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalModifyReq(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd) +{ + tListElem *pEntry= NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *pNewEntry= NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosEdcaAcType ac; + sme_QosStates new_state = SME_QOS_CLOSED; + sme_QosStatusType status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + sme_QosWmmTspecInfo Aggr_Tspec_Info; + sme_QosSearchInfo search_key; + sme_QosCmdInfo cmd; + v_U8_t sessionId; + v_BOOL_t bufferCommand; + eHalStatus hstatus; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked for flow %d", + __func__, __LINE__, + QosFlowID); + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.QosFlowID = QosFlowID; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_1; + search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY; + //go through the link list to find out the details on the flow + pEntry = sme_QosFindInFlowList(search_key); + if(!pEntry) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for flowID = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP; + } + // find the AC + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + + sessionId = flow_info->sessionId; + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + + //validate QoS params + if(!sme_QosValidateRequestedParams(pMac, pQoSInfo, sessionId)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid params", + __func__, __LINE__); + return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP; + } + // For modify, make sure that direction, TID and UP are not being altered + if((pQoSInfo->ts_info.direction != flow_info->QoSInfo.ts_info.direction) || + (pQoSInfo->ts_info.up != flow_info->QoSInfo.ts_info.up) || + (pQoSInfo->ts_info.tid != flow_info->QoSInfo.ts_info.tid)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Modification of direction/tid/up is not allowed", + __func__, __LINE__); + + return SME_QOS_STATUS_MODIFY_SETUP_INVALID_PARAMS_RSP; + } + + //should not be same as previous ioctl parameters + if ((pQoSInfo->nominal_msdu_size == flow_info->QoSInfo.nominal_msdu_size) && + (pQoSInfo->maximum_msdu_size == flow_info->QoSInfo.maximum_msdu_size) && + (pQoSInfo->min_data_rate == flow_info->QoSInfo.min_data_rate) && + (pQoSInfo->mean_data_rate == flow_info->QoSInfo.mean_data_rate) && + (pQoSInfo->peak_data_rate == flow_info->QoSInfo.peak_data_rate) && + (pQoSInfo->min_service_interval == + flow_info->QoSInfo.min_service_interval) && + (pQoSInfo->max_service_interval == + flow_info->QoSInfo.max_service_interval) && + (pQoSInfo->inactivity_interval == + flow_info->QoSInfo.inactivity_interval) && + (pQoSInfo->suspension_interval == + flow_info->QoSInfo.suspension_interval) && + (pQoSInfo->surplus_bw_allowance == + flow_info->QoSInfo.surplus_bw_allowance)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: the addts parameters are same as last request," + "dropping the current request", + __func__, __LINE__); + + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + // assume we won't have to (re)buffer the command + bufferCommand = VOS_FALSE; + //check to consider the following flowing scenario + //Addts request is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the modify request for flow %d in state %d " + "since another request is pending", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + else + { + // make sure we are in full power so that we can issue + // an AddTS or reassoc if necessary + hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, + pSession, eSME_REASON_OTHER); + if( eHAL_STATUS_PMC_PENDING == hstatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the modify request for flow %d in state %d, " + "waiting for full power", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + } + if (bufferCommand) + { + // we need to buffer the command + cmd.command = SME_QOS_MODIFY_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.modifyCmdInfo.QosFlowID = QosFlowID; + cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the modify request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Buffered modify request for flow = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + } + //get into the stat m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_QOS_ON: + //save the new params adding a new (duplicate) entry in the Flow List + //Once we have decided on OTA exchange needed or not we can delete the + //original one from the List + pNewEntry = (sme_QosFlowInfoEntry *) vos_mem_malloc(sizeof(*pNewEntry)); + if (!pNewEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the new " + "entry in the Flow List", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + pNewEntry->ac_type = ac; + pNewEntry->sessionId = sessionId; + pNewEntry->HDDcontext = flow_info->HDDcontext; + pNewEntry->QoSCallback = flow_info->QoSCallback; + pNewEntry->QosFlowID = flow_info->QosFlowID; + pNewEntry->reason = SME_QOS_REASON_MODIFY_PENDING; + //since it is a modify request, use the same index on which the flow + //entry originally was running & add it to the Flow List at the end + pNewEntry->tspec_mask = flow_info->tspec_mask; + pNewEntry->QoSInfo = *pQoSInfo; + //update the entry from Flow List which needed to be modified + flow_info->reason = SME_QOS_REASON_MODIFY; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d creating modified " + "entry at %p with flowID %d", + __func__, __LINE__, + sessionId, pNewEntry, pNewEntry->QosFlowID); + //add the new entry under construction to the Flow List + csrLLInsertTail(&sme_QosCb.flow_list, &pNewEntry->link, VOS_TRUE); + //update TSPEC with the new param set + hstatus = sme_QosUpdateParams(sessionId, + ac, pNewEntry->tspec_mask, + &Aggr_Tspec_Info); + if(HAL_STATUS_SUCCESS(hstatus)) + { + pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1] = Aggr_Tspec_Info; + //if ACM, send out a new ADDTS + status = sme_QosSetup(pMac, sessionId, + &pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1], + ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + new_state = SME_QOS_REQUESTED; + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + pACInfo->tspec_pending = pNewEntry->tspec_mask; + } + else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + new_state = SME_QOS_QOS_ON; + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //delete the original entry in FLOW list which got modified + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosModifyFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP != status) + { + pACInfo->curr_QoSInfo[pNewEntry->tspec_mask -1] = + pACInfo->requested_QoSInfo[pNewEntry->tspec_mask -1]; + if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) + { + status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY; + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosModificationNotifyFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't notify other " + "entries on this AC =%d", + __func__, __LINE__, ac); + } + } + else if(SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) + { + status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP; + } + } + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pNewEntry->tspec_mask -1], + status, + flow_info->QosFlowID); + } + + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = SME_QOS_QOS_ON; + } + } + else + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosUpdateParams() failed", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + new_state = SME_QOS_LINK_UP; + } + /* if we are doing reassoc & we are already in handoff state, no need + to move to requested state. But make sure to set the previous state + as requested state + */ + if(!(pACInfo->reassoc_pending && + (SME_QOS_HANDOFF == pACInfo->curr_state))) + { + sme_QosStateTransition(sessionId, ac, new_state); + } + else + { + pACInfo->prev_state = SME_QOS_REQUESTED; + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: Buffering modify request for flow %d in state = %d", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + //buffer cmd + cmd.command = SME_QOS_MODIFY_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.modifyCmdInfo.QosFlowID = QosFlowID; + cmd.u.modifyCmdInfo.QoSInfo = *pQoSInfo; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the modify request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + case SME_QOS_LINK_UP: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: modify requested in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + break; + } + if((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosInternalReleaseReq() - The SME QoS internal function to request + for releasing a QoS flow running on a particular AC. + + \param pMac - Pointer to the global MAC parameter structure. + \param QosFlowID - Identification per flow running on each AC generated by SME + It is only meaningful if the QoS setup for the flow is + successful + + \return eHAL_STATUS_SUCCESS - Release is successful. + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosInternalReleaseReq(tpAniSirGlobal pMac, + v_U32_t QosFlowID, + v_BOOL_t buffered_cmd) +{ + tListElem *pEntry= NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosFlowInfoEntry *pDeletedFlow = NULL; + sme_QosEdcaAcType ac; + sme_QosStates new_state = SME_QOS_CLOSED; + sme_QosStatusType status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + sme_QosWmmTspecInfo Aggr_Tspec_Info; + sme_QosSearchInfo search_key; + sme_QosCmdInfo cmd; + tCsrRoamModifyProfileFields modifyProfileFields; + v_BOOL_t deltsIssued = VOS_FALSE; + v_U8_t sessionId; + v_BOOL_t bufferCommand; + eHalStatus hstatus; + v_BOOL_t biDirectionalFlowsPresent = VOS_FALSE; + v_BOOL_t uplinkFlowsPresent = VOS_FALSE; + v_BOOL_t downlinkFlowsPresent = VOS_FALSE; + tListElem *pResult= NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked for flow %d", + __func__, __LINE__, + QosFlowID); + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.QosFlowID = QosFlowID; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_1; + search_key.sessionId = SME_QOS_SEARCH_SESSION_ID_ANY; + //go through the link list to find out the details on the flow + pEntry = sme_QosFindInFlowList(search_key); + + if(!pEntry) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for flowID = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP; + } + // find the AC + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + sessionId = flow_info->sessionId; + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + // assume we won't have to (re)buffer the command + bufferCommand = VOS_FALSE; + //check to consider the following flowing scenario + //Addts request is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the release request for flow %d in state %d " + "since another request is pending", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + else + { + // make sure we are in full power so that we can issue + // a DelTS or reassoc if necessary + hstatus = pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, + pSession, eSME_REASON_OTHER); + if( eHAL_STATUS_PMC_PENDING == hstatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: buffering the release request for flow %d in state %d, " + "waiting for full power", + __func__, __LINE__, + QosFlowID, pACInfo->curr_state ); + bufferCommand = VOS_TRUE; + } + } + if (bufferCommand) + { + // we need to buffer the command + cmd.command = SME_QOS_RELEASE_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.releaseCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the release request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Buffered release request for flow = %d", + __func__, __LINE__, + QosFlowID); + return SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP; + } + //get into the stat m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_QOS_ON: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: tspec_mask_status = %d for AC = %d with " + "entry tspec_mask = %d", + __func__, __LINE__, + pACInfo->tspec_mask_status, ac, flow_info->tspec_mask); + + //check if multiple flows running on the ac + if(pACInfo->num_flows[flow_info->tspec_mask - 1] > 1) + { + //don't want to include the flow in the new TSPEC on which release + //is requested + flow_info->reason = SME_QOS_REASON_RELEASE; + + /* Check if the flow being released is for bi-diretional. + * Following flows may present in the system. + * a) bi-directional flows + * b) uplink flows + * c) downlink flows. + * If the flow being released is for bidirectional, splitting of existing + * streams into two tspec indices is required in case ff (b), (c) are present + * and not (a). + * In case if split occurs, all upstreams are aggregated into tspec index 0, + * downstreams are aggregaed into tspec index 1 and two tspec requests for + * (aggregated) upstream(s) followed by (aggregated) downstream(s) is sent + * to AP. */ + if(flow_info->QoSInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_4; + search_key.sessionId = sessionId; + search_key.direction = SME_QOS_WMM_TS_DIR_BOTH; + pResult = sme_QosFindInFlowList(search_key); + if(pResult) + biDirectionalFlowsPresent = VOS_TRUE; + + if(!biDirectionalFlowsPresent) + { + // The only existing bidirectional flow is being released + + // Check if uplink flows exist + search_key.direction = SME_QOS_WMM_TS_DIR_UPLINK; + pResult = sme_QosFindInFlowList(search_key); + if(pResult) + uplinkFlowsPresent = VOS_TRUE; + + // Check if downlink flows exist + search_key.direction = SME_QOS_WMM_TS_DIR_DOWNLINK; + pResult = sme_QosFindInFlowList(search_key); + if(pResult) + downlinkFlowsPresent = VOS_TRUE; + + if(uplinkFlowsPresent && downlinkFlowsPresent) + { + // Need to split the uni-directional flows into SME_QOS_TSPEC_INDEX_0 and SME_QOS_TSPEC_INDEX_1 + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + // Mark all downstream flows as using tspec index 1 + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_4; + search_key.sessionId = sessionId; + search_key.direction = SME_QOS_WMM_TS_DIR_DOWNLINK; + sme_QosUpdateTspecMask(sessionId, search_key, SME_QOS_TSPEC_MASK_BIT_2_SET); + + // Aggregate all downstream flows + hstatus = sme_QosUpdateParams(sessionId, + ac, SME_QOS_TSPEC_MASK_BIT_2_SET, + &Aggr_Tspec_Info); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d buffering the AddTS request " + "for AC %d in state %d as Addts is pending " + "on other Tspec index of this AC", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + + // Buffer the (aggregated) tspec request for downstream flows. + // Please note that the (aggregated) tspec for upstream flows is sent + // out by the susequent logic. + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = SME_QOS_TSPEC_MASK_BIT_2_SET; + cmd.u.resendCmdInfo.QoSInfo = Aggr_Tspec_Info; + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_MASK_BIT_2_SET - 1] = Aggr_Tspec_Info; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to buffer the AddTS " + "request for AC %d TSPEC %d in state %d", + __func__, __LINE__, + sessionId, ac, SME_QOS_TSPEC_MASK_BIT_2_SET, pACInfo->curr_state); + + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_BIT_1_2_SET; + + } + } + } + + /* In case of splitting of existing streams, + * tspec_mask will be pointing to tspec index 0 and + * aggregated tspec for upstream(s) is sent out here. */ + hstatus = sme_QosUpdateParams(sessionId, + ac, flow_info->tspec_mask, + &Aggr_Tspec_Info); + if(HAL_STATUS_SUCCESS(hstatus)) + { + pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1] = Aggr_Tspec_Info; + //if ACM, send out a new ADDTS + status = sme_QosSetup(pMac, sessionId, + &pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1], ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d with AC %d in state SME_QOS_QOS_ON " + "sme_QosSetup returned with status %d", + __func__, __LINE__, + sessionId, ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + new_state = SME_QOS_REQUESTED; + status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP; + pACInfo->tspec_pending = flow_info->tspec_mask; + } + else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + new_state = SME_QOS_QOS_ON; + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1] = + pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1]; + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + pDeletedFlow = flow_info; + if(SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + hstatus = sme_QosFindAllInFlowList(pMac, search_key, + sme_QosSetupFnp); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't notify other " + "entries on this AC =%d", + __func__, __LINE__, ac); + } + } + status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP; + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + status, + flow_info->QosFlowID); + } + } + else + { + // unexpected status returned by sme_QosSetup() + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unexpected status %d " + "returned by sme_QosSetup", + __func__, __LINE__, + sessionId, status); + new_state = SME_QOS_LINK_UP; + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1] = + pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1]; + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d deleting entry at " + "%p with flowID %d", + __func__, __LINE__, + sessionId, flow_info, QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + pDeletedFlow = flow_info; + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + status, + flow_info->QosFlowID); + } + } + } + else + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosUpdateParams() failed", + __func__, __LINE__); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + new_state = SME_QOS_LINK_UP; + if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + status, + flow_info->QosFlowID); + } + } + } + else + { + // this is the only flow aggregated in this TSPEC + status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP; +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + if (ac == SME_QOS_EDCA_AC_VO) + { + // Indicate to neighbor roam logic of the new required VO + // ac bandwidth requirement. + csrNeighborRoamIndicateVoiceBW( pMac, pACInfo->curr_QoSInfo[0].peak_data_rate, FALSE ); + } +#endif + //check if delts needs to be sent + if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) || + sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL)) + { + //check if other TSPEC for this AC is also in use + if(SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status) + { + // this is the only TSPEC active on this AC + // so indicate that we no longer require APSD + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + //Also update modifyProfileFields.uapsd_mask in CSR for consistency + csrGetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask = pSession->apsdMask; + csrSetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + if(!pSession->apsdMask) + { + // this session no longer needs UAPSD + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + } + } + if (SME_QOS_RELEASE_DEFAULT == pACInfo->relTrig) + { + //send delts + hstatus = qosIssueCommand(pMac, sessionId, eSmeCommandDelTs, + NULL, ac, flow_info->tspec_mask); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosDelTsReq() failed", + __func__, __LINE__); + status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + // we won't be waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + else + { + pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET & + (~flow_info->tspec_mask); + deltsIssued = VOS_TRUE; + } + } + else + { + pSession->readyForPowerSave = VOS_TRUE; + pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET & + (~flow_info->tspec_mask); + deltsIssued = VOS_TRUE; + } + } + else if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) + { + //reassoc logic + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask |= pSession->apsdMask; + modifyProfileFields.uapsd_mask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + if(!pSession->apsdMask) + { + // this session no longer needs UAPSD + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + } + hstatus = sme_QosRequestReassoc(pMac, sessionId, + &modifyProfileFields, VOS_FALSE); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Reassoc failed", + __func__, __LINE__); + status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + // we won't be waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + else + { + pACInfo->reassoc_pending = VOS_FALSE;//no need to wait + pACInfo->prev_state = SME_QOS_LINK_UP; + pACInfo->tspec_pending = 0; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: nothing to do for AC = %d", + __func__, __LINE__, ac); + // we won't be waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + + if (SME_QOS_RELEASE_BY_AP == pACInfo->relTrig) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + flow_info->QosFlowID); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + } + else if(buffered_cmd) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + NULL, + status, + flow_info->QosFlowID); + } + + if(SME_QOS_STATUS_RELEASE_FAILURE_RSP == status) + { + break; + } + + if(((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->tspec_mask) > 0) && + ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~flow_info->tspec_mask) <= + SME_QOS_TSPEC_INDEX_MAX)) + { + if(pACInfo->num_flows[(SME_QOS_TSPEC_MASK_BIT_1_2_SET & + ~flow_info->tspec_mask) - 1] > 0) + { + new_state = SME_QOS_QOS_ON; + } + else + { + new_state = SME_QOS_LINK_UP; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Exceeded the array bounds of pACInfo->num_flows", + __func__, __LINE__); + VOS_ASSERT (0); + return SME_QOS_STATUS_RELEASE_INVALID_PARAMS_RSP; + } + + if(VOS_FALSE == deltsIssued) + { + vos_mem_zero(&pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + sizeof(sme_QosWmmTspecInfo)); + } + vos_mem_zero(&pACInfo->requested_QoSInfo[flow_info->tspec_mask - 1], + sizeof(sme_QosWmmTspecInfo)); + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d deleting entry at %p with flowID %d", + __func__, __LINE__, + sessionId, flow_info, QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + pDeletedFlow = flow_info; + pACInfo->relTrig = SME_QOS_RELEASE_DEFAULT; + } + /* if we are doing reassoc & we are already in handoff state, no need + to move to requested state. But make sure to set the previous state + as requested state + */ + if(SME_QOS_HANDOFF != pACInfo->curr_state) + { + sme_QosStateTransition(sessionId, ac, new_state); + } + if(pACInfo->reassoc_pending) + { + pACInfo->prev_state = SME_QOS_REQUESTED; + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + //buffer cmd + cmd.command = SME_QOS_RELEASE_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.releaseCmdInfo.QosFlowID = QosFlowID; + hstatus = sme_QosBufferCmd(&cmd, buffered_cmd); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the release request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + status = SME_QOS_STATUS_RELEASE_REQ_PENDING_RSP; + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + case SME_QOS_LINK_UP: + default: + //print error msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: release request in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + //ASSERT + VOS_ASSERT(0); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + break; + } + // if we deleted a flow, reclaim the memory + if (pDeletedFlow) + { + vos_mem_free(pDeletedFlow); + } + if((SME_QOS_STATUS_RELEASE_SUCCESS_RSP == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosSetup() - The internal qos setup function which has the + intelligence if the request is NOP, or for APSD and/or need to send out ADDTS. + It also does the sanity check for QAP, AP supports APSD etc. + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - Session upon which setup is being performed + \param pTspec_Info - Pointer to sme_QosWmmTspecInfo which contains the WMM + TSPEC related info as defined above + \param ac - Enumeration of the various EDCA Access Categories. + + \return SME_QOS_STATUS_SETUP_SUCCESS_RSP if the setup is successful + The logic used in the code might be confusing. Trying to cover all the cases + here. + AP supports App wants ACM = 1 Already set APSD Result + | 0 | 0 | 0 | 0 | NO ACM NO APSD + | 0 | 0 | 0 | 1 | NO ACM NO APSD/INVALID + | 0 | 0 | 1 | 0 | ADDTS + | 0 | 0 | 1 | 1 | ADDTS + | 0 | 1 | 0 | 0 | FAILURE + | 0 | 1 | 0 | 1 | INVALID + | 0 | 1 | 1 | 0 | ADDTS + | 0 | 1 | 1 | 1 | ADDTS + | 1 | 0 | 0 | 0 | NO ACM NO APSD + | 1 | 0 | 0 | 1 | NO ACM NO APSD + | 1 | 0 | 1 | 0 | ADDTS + | 1 | 0 | 1 | 1 | ADDTS + | 1 | 1 | 0 | 0 | REASSOC + | 1 | 1 | 0 | 1 | NOP: APSD SET ALREADY + | 1 | 1 | 1 | 0 | ADDTS + | 1 | 1 | 1 | 1 | ADDTS + + \sa + + --------------------------------------------------------------------------*/ +sme_QosStatusType sme_QosSetup(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo *pTspec_Info, + sme_QosEdcaAcType ac) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosStatusType status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + tDot11fBeaconIEs *pIes = NULL; + tCsrRoamModifyProfileFields modifyProfileFields; + eHalStatus hstatus; + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session Id %d is invalid", + __func__, __LINE__, + sessionId); + return status; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d is inactive", + __func__, __LINE__, + sessionId); + return status; + } + if(!pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d has an Invalid BSS Descriptor", + __func__, __LINE__, + sessionId); + return status; + } + hstatus = csrGetParsedBssDescriptionIEs(pMac, + pSession->assocInfo.pBssDesc, + &pIes); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to parse BSS IEs", + __func__, __LINE__, + sessionId); + return status; + } + + /* success so pIes was allocated */ + + if( !CSR_IS_QOS_BSS(pIes) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AP doesn't support QoS", + __func__, __LINE__, + sessionId); + vos_mem_free(pIes); + //notify HDD through the synchronous status msg + return SME_QOS_STATUS_SETUP_NOT_QOS_AP_RSP; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "%s: %d: UAPSD/PSB set %d: ", __func__, __LINE__, + pTspec_Info->ts_info.psb); + + pACInfo = &pSession->ac_info[ac]; + do + { + // is ACM enabled for this AC? + if(CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac) || + sme_QosIsACM(pMac, pSession->assocInfo.pBssDesc, ac, NULL)) + { + // ACM is enabled for this AC so we must send an AddTS + if(pTspec_Info->ts_info.psb && + (!pMac->pmc.uapsdEnabled )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Request is looking for APSD but PMC doesn't " + "have support for APSD", + __func__, __LINE__); + break; + } + + if (pTspec_Info->ts_info.psb && + !(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) && + !(pIes->WMMInfoAp.uapsd)) + { + // application is looking for APSD but AP doesn't support it + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AP doesn't support APSD", + __func__, __LINE__, + sessionId); + break; + } + + if(SME_QOS_MAX_TID == pTspec_Info->ts_info.tid) + { + //App didn't set TID, generate one + pTspec_Info->ts_info.tid = + (v_U8_t)(SME_QOS_WMM_UP_NC - pTspec_Info->ts_info.up); + } + //addts logic + hstatus = qosIssueCommand(pMac, sessionId, eSmeCommandAddTs, + pTspec_Info, ac, 0); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosAddTsReq() failed", + __func__, __LINE__); + break; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AddTS on AC %d is pending", + __func__, __LINE__, + sessionId, ac); + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + break; + } + // ACM is not enabled for this AC + // Is the application looking for APSD? + if(0 == pTspec_Info->ts_info.psb) + { + //no, we don't need APSD + //but check the case, if the setup is called as a result of a release + // or modify which boils down to the fact that APSD was set on this AC + // but no longer needed - so we need a reassoc for the above case to + // let the AP know + if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) + { + // APSD was formerly enabled on this AC but is no longer required + // so we must reassociate + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassoc needed " + "to disable APSD on AC %d", + __func__, __LINE__, + sessionId, ac); + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask |= pSession->apsdMask; + modifyProfileFields.uapsd_mask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + hstatus = sme_QosRequestReassoc(pMac, sessionId, + &modifyProfileFields, VOS_FALSE); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to request reassociation", + __func__, __LINE__); + break; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassociation to enable " + "APSD on AC %d is pending", + __func__, __LINE__, + sessionId, ac); + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + pACInfo->reassoc_pending = VOS_TRUE; + } + } + else + { + // we don't need APSD on this AC + // and we don't currently have APSD on this AC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Request is not looking for APSD & Admission " + "Control isn't mandatory for the AC", + __func__, __LINE__); + //return success right away + status = SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP; + } + break; + } + else if(!(pIes->WMMParams.qosInfo & SME_QOS_AP_SUPPORTS_APSD) && + !(pIes->WMMInfoAp.uapsd)) + { + // application is looking for APSD but AP doesn't support it + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AP doesn't support APSD", + __func__, __LINE__, + sessionId); + break; + } + else if(pSession->apsdMask & (1 << (SME_QOS_EDCA_AC_VO - ac))) + { + // application is looking for APSD + // and it is already enabled on this AC + status = SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Request is looking for APSD and it is already " + "set for the AC", + __func__, __LINE__); + break; + } + else + { + // application is looking for APSD + // but it is not enabled on this AC + // so we need to reassociate + if(pMac->pmc.uapsdEnabled) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassoc needed " + "to enable APSD on AC %d", + __func__, __LINE__, + sessionId, ac); + //reassoc logic + // update the UAPSD mask to include the new + // AC on which APSD is requested + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask |= pSession->apsdMask; + modifyProfileFields.uapsd_mask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + hstatus = sme_QosRequestReassoc(pMac, sessionId, + &modifyProfileFields, VOS_FALSE); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to request reassociation", + __func__, __LINE__); + break; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d reassociation to enable " + "APSD on AC %d is pending", + __func__, __LINE__, + sessionId, ac); + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + pACInfo->reassoc_pending = VOS_TRUE; + } + } + else + { + //err msg: no support for APSD from PMC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no support for APSD or BMPS from PMC", + __func__, __LINE__); + } + } + }while(0); + + vos_mem_free(pIes); + return status; +} + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* This is a dummy function now. But the purpose of me adding this was to + * delay the TSPEC processing till SET_KEY completes. This function can be + * used to do any SME_QOS processing after the SET_KEY. As of now, it is + * not required as we are ok with tspec getting programmed before set_key + * as the roam timings are measured without tspec in reassoc! + */ +eHalStatus sme_QosProcessSetKeySuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "########### Set Key Complete #############"); + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; +} +#endif + +#ifdef FEATURE_WLAN_ESE +/*-------------------------------------------------------------------------- + \brief sme_QosESESaveTspecResponse() - This function saves the TSPEC + parameters that came along in the TSPEC IE in the reassoc response + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - SME session ID + \param pTspec - Pointer to the TSPEC IE from the reassoc rsp + \param ac - Access Category for which this TSPEC rsp is received + \param tspecIndex - flow/direction + + \return eHAL_STATUS_SUCCESS - Release is successful. + --------------------------------------------------------------------------*/ +eHalStatus sme_QosESESaveTspecResponse(tpAniSirGlobal pMac, v_U8_t sessionId, tDot11fIEWMMTSPEC *pTspec, v_U8_t ac, v_U8_t tspecIndex) +{ + tpSirAddtsRsp pAddtsRsp = &sme_QosCb.sessionInfo[sessionId].ac_info[ac].addTsRsp[tspecIndex]; + + ac = sme_QosUPtoACMap[pTspec->user_priority]; + + vos_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp)); + + pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP; + pAddtsRsp->length = sizeof(tSirAddtsRsp); + pAddtsRsp->rc = eSIR_SUCCESS; + pAddtsRsp->sessionId = sessionId; + pAddtsRsp->rsp.dialogToken = 0; + pAddtsRsp->rsp.status = eSIR_SUCCESS; + pAddtsRsp->rsp.wmeTspecPresent = pTspec->present; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Copy Tspec to local data structure ac=%d, tspecIdx=%d", + __func__, ac, tspecIndex); + + if (pAddtsRsp->rsp.wmeTspecPresent) + { + //Copy TSPEC params received in assoc response to addts response + ConvertWMMTSPEC(pMac, &pAddtsRsp->rsp.tspec, pTspec); + } + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosESEProcessReassocTspecRsp() - This function processes the + WMM TSPEC IE in the reassoc response. Reassoc triggered as part of + ESE roaming to another ESE capable AP. If the TSPEC was added before + reassoc, as part of Call Admission Control, the reasso req from the + STA would carry the TSPEC parameters which were already negotiated + with the older AP. + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - SME session ID + \param pEven_info - Pointer to the smeJoinRsp structure + + \return eHAL_STATUS_SUCCESS - Release is successful. + --------------------------------------------------------------------------*/ +eHalStatus sme_QosESEProcessReassocTspecRsp(tpAniSirGlobal pMac, v_U8_t sessionId, void* pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + tDot11fIEWMMTSPEC *pTspecIE = NULL; + tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamConnectedInfo *pCsrConnectedInfo = &pCsrSession->connectedInfo; + eHalStatus status = eHAL_STATUS_FAILURE; + v_U8_t ac, numTspec, cnt; + v_U8_t tspec_flow_index, tspec_mask_status; + v_U32_t tspecIeLen; + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + // Get the TSPEC IEs which came along with the reassoc response + // from the pbFrames pointer + pTspecIE = (tDot11fIEWMMTSPEC *)(pCsrConnectedInfo->pbFrames + pCsrConnectedInfo->nBeaconLength + + pCsrConnectedInfo->nAssocReqLength + pCsrConnectedInfo->nAssocRspLength + pCsrConnectedInfo->nRICRspLength); + + // Get the number of tspecs Ies in the frame, the min length + // should be atleast equal to the one TSPEC IE + tspecIeLen = pCsrConnectedInfo->nTspecIeLength; + if (tspecIeLen < sizeof(tDot11fIEWMMTSPEC)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("ESE Tspec IE len %d less than min %d"), + tspecIeLen, sizeof(tDot11fIEWMMTSPEC)); + return eHAL_STATUS_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "TspecLen = %d, pbFrames = %p, pTspecIE = %p", + tspecIeLen, pCsrConnectedInfo->pbFrames, pTspecIE); + + numTspec = (tspecIeLen)/sizeof(tDot11fIEWMMTSPEC); + for(cnt=0; cntuser_priority); + pACInfo = &pSession->ac_info[ac]; + tspec_mask_status = pACInfo->tspec_mask_status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("UP=%d, ac=%d, tspec_mask_status=%x"), + pTspecIE->user_priority, ac, tspec_mask_status ); + + for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) { + if (tspec_mask_status & (1 << tspec_flow_index)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Found Tspec entry flow = %d AC = %d"),tspec_flow_index, ac); + sme_QosESESaveTspecResponse(pMac, sessionId, pTspecIE, ac, tspec_flow_index); + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Not found Tspec entry flow = %d AC = %d"),tspec_flow_index, ac); + } + } + // Increment the pointer to point it to the next TSPEC IE + pTspecIE++; + } + + /* Send the Aggregated QoS request to HAL */ + status = sme_QosFTAggrQosReq(pMac,sessionId); + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosCopyTspecInfo() - This function copies the existing TSPEC + parameters from the source structure to the destination structure. + + \param pMac - Pointer to the global MAC parameter structure. + \param pTspec_Info - source structure + \param pTspec - destination structure + + \return void + --------------------------------------------------------------------------*/ +static void sme_QosCopyTspecInfo(tpAniSirGlobal pMac, sme_QosWmmTspecInfo *pTspec_Info, tSirMacTspecIE* pTspec) +{ + /* As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service + * Interval, Service Start Time, Suspension Interval and Delay Bound are + * all intended for HCCA operation and therefore must be set to zero*/ + pTspec->delayBound = pTspec_Info->delay_bound; + pTspec->inactInterval = pTspec_Info->inactivity_interval; + pTspec->length = SME_QOS_TSPEC_IE_LENGTH; + pTspec->maxBurstSz = pTspec_Info->max_burst_size; + pTspec->maxMsduSz = pTspec_Info->maximum_msdu_size; + pTspec->maxSvcInterval = pTspec_Info->max_service_interval; + pTspec->meanDataRate = pTspec_Info->mean_data_rate; + pTspec->mediumTime = pTspec_Info->medium_time; + pTspec->minDataRate = pTspec_Info->min_data_rate; + pTspec->minPhyRate = pTspec_Info->min_phy_rate; + pTspec->minSvcInterval = pTspec_Info->min_service_interval; + pTspec->nomMsduSz = pTspec_Info->nominal_msdu_size; + pTspec->peakDataRate = pTspec_Info->peak_data_rate; + pTspec->surplusBw = pTspec_Info->surplus_bw_allowance; + pTspec->suspendInterval = pTspec_Info->suspension_interval; + pTspec->svcStartTime = pTspec_Info->svc_start_time; + pTspec->tsinfo.traffic.direction = pTspec_Info->ts_info.direction; + + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if (pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac)) { + pTspec->tsinfo.traffic.psb = pTspec_Info->ts_info.psb; + } else { + pTspec->tsinfo.traffic.psb = 0; + pTspec_Info->ts_info.psb = 0; + } + pTspec->tsinfo.traffic.tsid = pTspec_Info->ts_info.tid; + pTspec->tsinfo.traffic.userPrio = pTspec_Info->ts_info.up; + pTspec->tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA; + pTspec->tsinfo.traffic.burstSizeDefn = pTspec_Info->ts_info.burst_size_defn; + pTspec->tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy; + pTspec->type = SME_QOS_TSPEC_IE_TYPE; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: up = %d, tid = %d", + __func__, __LINE__, + pTspec_Info->ts_info.up, + pTspec_Info->ts_info.tid); +} + +/*-------------------------------------------------------------------------- + \brief sme_QosEseRetrieveTspecInfo() - This function is called by CSR + when try to create reassoc request message to PE - csrSendSmeReassocReqMsg + This functions get the existing tspec parameters to be included + in the reassoc request. + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - SME session ID + \param pTspecInfo - Pointer to the structure to carry back the TSPEC parameters + + \return v_U8_t - number of existing negotiated TSPECs + --------------------------------------------------------------------------*/ +v_U8_t sme_QosESERetrieveTspecInfo(tpAniSirGlobal pMac, v_U8_t sessionId, tTspecInfo *pTspecInfo) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t tspec_mask_status = 0; + v_U8_t tspec_pending_status = 0; + v_U8_t ac, numTspecs = 0; + tTspecInfo *pDstTspec = pTspecInfo; + + //TODO: Check if TSPEC has already been established, if not return + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) { + volatile v_U8_t tspec_index = 0; + + pACInfo = &pSession->ac_info[ac]; + tspec_pending_status = pACInfo->tspec_pending; + tspec_mask_status = pACInfo->tspec_mask_status; + + do { + if (tspec_mask_status & SME_QOS_TSPEC_MASK_BIT_1_SET) { + /* If a tspec status is pending, take requested_QoSInfo for RIC request, else use curr_QoSInfo + for the RIC request */ + if (tspec_pending_status & SME_QOS_TSPEC_MASK_BIT_1_SET) { + sme_QosCopyTspecInfo(pMac, &pACInfo->requested_QoSInfo[tspec_index], &pDstTspec->tspec); + } else { + sme_QosCopyTspecInfo(pMac, &pACInfo->curr_QoSInfo[tspec_index], &pDstTspec->tspec); + } + pDstTspec->valid = TRUE; + numTspecs++; + pDstTspec++; + } + tspec_mask_status >>= 1; + tspec_pending_status >>= 1; + tspec_index++; + } while (tspec_mask_status); + } + + return numTspecs; +} + +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + +eHalStatus sme_QosCreateTspecRICIE(tpAniSirGlobal pMac, sme_QosWmmTspecInfo *pTspec_Info, + v_U8_t *pRICBuffer, v_U32_t *pRICLength, v_U8_t *pRICIdentifier) +{ + tDot11fIERICDataDesc ricIE; + tANI_U32 nStatus; + + VOS_ASSERT(NULL != pRICBuffer); + VOS_ASSERT(NULL != pRICLength); + VOS_ASSERT(NULL != pRICIdentifier); + + if (pRICBuffer == NULL || pRICIdentifier == NULL || pRICLength == NULL) + return eHAL_STATUS_FAILURE; + + vos_mem_zero(&ricIE, sizeof(tDot11fIERICDataDesc)); + + ricIE.present = 1; + ricIE.RICData.present = 1; + ricIE.RICData.resourceDescCount = 1; + ricIE.RICData.statusCode = 0; + ricIE.RICData.Identifier = sme_QosAssignDialogToken(); +#ifndef USE_80211_WMMTSPEC_FOR_RIC + ricIE.TSPEC.present = 1; + ricIE.TSPEC.delay_bound = pTspec_Info->delay_bound; + ricIE.TSPEC.inactivity_int = pTspec_Info->inactivity_interval; + ricIE.TSPEC.burst_size = pTspec_Info->max_burst_size; + ricIE.TSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size; + ricIE.TSPEC.max_service_int = pTspec_Info->max_service_interval; + ricIE.TSPEC.mean_data_rate = pTspec_Info->mean_data_rate; + ricIE.TSPEC.medium_time = 0; + ricIE.TSPEC.min_data_rate = pTspec_Info->min_data_rate; + ricIE.TSPEC.min_phy_rate = pTspec_Info->min_phy_rate; + ricIE.TSPEC.min_service_int = pTspec_Info->min_service_interval; + ricIE.TSPEC.size = pTspec_Info->nominal_msdu_size; + ricIE.TSPEC.peak_data_rate = pTspec_Info->peak_data_rate; + ricIE.TSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance; + ricIE.TSPEC.suspension_int = pTspec_Info->suspension_interval; + ricIE.TSPEC.service_start_time = pTspec_Info->svc_start_time; + ricIE.TSPEC.direction = pTspec_Info->ts_info.direction; + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if( pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac) ) + { + ricIE.TSPEC.psb = pTspec_Info->ts_info.psb; + } + else + { + ricIE.TSPEC.psb = 0; + } + ricIE.TSPEC.tsid = pTspec_Info->ts_info.tid; + ricIE.TSPEC.user_priority = pTspec_Info->ts_info.up; + ricIE.TSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA; + + *pRICIdentifier = ricIE.RICData.Identifier; + + nStatus = dot11fPackIeRICDataDesc(pMac, &ricIE, pRICBuffer, sizeof(ricIE), pRICLength); + if (DOT11F_FAILED(nStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Packing of RIC Data of length %d failed with status %d"), + *pRICLength, nStatus); + } +#else // WMM TSPEC + /*As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service + Interval, Service Start Time, Suspension Interval and Delay Bound are + all intended for HCCA operation and therefore must be set to zero*/ + ricIE.WMMTSPEC.present = 1; + ricIE.WMMTSPEC.version = 1; + ricIE.WMMTSPEC.delay_bound = pTspec_Info->delay_bound; + ricIE.WMMTSPEC.inactivity_int = pTspec_Info->inactivity_interval; + ricIE.WMMTSPEC.burst_size = pTspec_Info->max_burst_size; + ricIE.WMMTSPEC.max_msdu_size = pTspec_Info->maximum_msdu_size; + ricIE.WMMTSPEC.max_service_int = pTspec_Info->max_service_interval; + ricIE.WMMTSPEC.mean_data_rate = pTspec_Info->mean_data_rate; + ricIE.WMMTSPEC.medium_time = 0; + ricIE.WMMTSPEC.min_data_rate = pTspec_Info->min_data_rate; + ricIE.WMMTSPEC.min_phy_rate = pTspec_Info->min_phy_rate; + ricIE.WMMTSPEC.min_service_int = pTspec_Info->min_service_interval; + ricIE.WMMTSPEC.size = pTspec_Info->nominal_msdu_size; + ricIE.WMMTSPEC.peak_data_rate = pTspec_Info->peak_data_rate; + ricIE.WMMTSPEC.surplus_bw_allowance = pTspec_Info->surplus_bw_allowance; + ricIE.WMMTSPEC.suspension_int = pTspec_Info->suspension_interval; + ricIE.WMMTSPEC.service_start_time = pTspec_Info->svc_start_time; + ricIE.WMMTSPEC.direction = pTspec_Info->ts_info.direction; + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if( pTspec_Info->ts_info.psb && btcIsReadyForUapsd(pMac) ) + { + ricIE.WMMTSPEC.psb = pTspec_Info->ts_info.psb; + } + else + { + ricIE.WMMTSPEC.psb = 0; + } + ricIE.WMMTSPEC.tsid = pTspec_Info->ts_info.tid; + ricIE.WMMTSPEC.user_priority = pTspec_Info->ts_info.up; + ricIE.WMMTSPEC.access_policy = SME_QOS_ACCESS_POLICY_EDCA; + + + nStatus = dot11fPackIeRICDataDesc(pMac, &ricIE, pRICBuffer, sizeof(ricIE), pRICLength); + if (DOT11F_FAILED(nStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Packing of RIC Data of length %d failed with status %d"), + *pRICLength, nStatus); + } +#endif /* 80211_TSPEC */ + *pRICIdentifier = ricIE.RICData.Identifier; + return nStatus; +} + +eHalStatus sme_QosProcessFTReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac, qos_requested = FALSE; + v_U8_t tspec_flow_index; + sme_QosFlowInfoEntry *flow_info = NULL; + tListElem *pEntry= NULL; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + FL("Invoked on session %d"), sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + qos_requested = FALSE; + + for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) + { + /* Only in the below case, copy the AC's curr QoS Info to requested QoS info */ + if ((pACInfo->ricIdentifier[tspec_flow_index] && !pACInfo->tspec_pending) || + (pACInfo->tspec_mask_status & (1<requested_QoSInfo[tspec_flow_index] = pACInfo->curr_QoSInfo[tspec_flow_index]; + vos_mem_zero(&pACInfo->curr_QoSInfo[tspec_flow_index], sizeof(sme_QosWmmTspecInfo)); + qos_requested = TRUE; + } + } + + // Only if the tspec is required, transition the state to + // SME_QOS_REQUESTED for this AC + if (qos_requested) + { + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, SME_QOS_REQUESTED); + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("FT Reassoc req event in unexpected state %d"), pACInfo->curr_state); + VOS_ASSERT(0); + } + } + + } + + /* At this point of time, we are disconnected from the old AP, so it is safe + * to reset all these session variables */ + pSession->apsdMask = 0; + pSession->uapsdAlreadyRequested = 0; + pSession->readyForPowerSave = 0; + + /* Now change reason and HO renewal of all the flow in this session only */ + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: Flow List empty, nothing to update", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + do + { + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if(sessionId == flow_info->sessionId) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Changing FlowID %d reason to SETUP and HO renewal to FALSE", + __func__, __LINE__, + flow_info->QosFlowID); + flow_info->reason = SME_QOS_REASON_SETUP; + flow_info->hoRenewal = eANI_BOOLEAN_TRUE; + } + pEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + } while( pEntry ); + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus sme_QosFTAggrQosReq( tpAniSirGlobal pMac, v_U8_t sessionId ) +{ + tSirAggrQosReq *pMsg = NULL; + sme_QosSessionInfo *pSession; + eHalStatus status = eHAL_STATUS_FAILURE; + int i, j = 0; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", __func__, __LINE__, + sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + pMsg = (tSirAggrQosReq *)vos_mem_malloc(sizeof(tSirAggrQosReq)); + + if (!pMsg) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the msg buffer", + __func__, __LINE__); + + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(pMsg, sizeof(tSirAggrQosReq)); + + pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_FT_AGGR_QOS_REQ); + pMsg->length = sizeof(tSirAggrQosReq); + pMsg->sessionId = sessionId; + pMsg->timeout = 0; + pMsg->rspReqd = VOS_TRUE; + vos_mem_copy( &pMsg->bssId[ 0 ], + &pSession->assocInfo.pBssDesc->bssId[ 0 ], + sizeof(tCsrBssid) ); + + for( i = 0; i < SME_QOS_EDCA_AC_MAX; i++ ) + { + for( j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++ ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("ac=%d, tspec_mask_staus=%x, tspec_index=%d"), + i, pSession->ac_info[i].tspec_mask_status, j); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("direction = %d"), pSession->ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.direction); + // Check if any flow is active on this AC + if ((pSession->ac_info[i].tspec_mask_status) & (1 << j)) + { + tANI_U8 direction = pSession->ac_info[i].addTsRsp[j].rsp.tspec.tsinfo.traffic.direction; + if ((direction == SME_QOS_WMM_TS_DIR_UPLINK) || + (direction == SME_QOS_WMM_TS_DIR_BOTH)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("Found tspec entry AC=%d, flow=%d, direction = %d"), i, j, direction); + pMsg->aggrInfo.aggrAddTsInfo[i].dialogToken = + sme_QosAssignDialogToken(); + pMsg->aggrInfo.aggrAddTsInfo[i].lleTspecPresent = + pSession->ac_info[i].addTsRsp[j].rsp.lleTspecPresent; + pMsg->aggrInfo.aggrAddTsInfo[i].numTclas = + pSession->ac_info[i].addTsRsp[j].rsp.numTclas; + vos_mem_copy( pMsg->aggrInfo.aggrAddTsInfo[i].tclasInfo, + pSession->ac_info[i].addTsRsp[j].rsp.tclasInfo, + SIR_MAC_TCLASIE_MAXNUM ); + pMsg->aggrInfo.aggrAddTsInfo[i].tclasProc = + pSession->ac_info[i].addTsRsp[j].rsp.tclasProc; + pMsg->aggrInfo.aggrAddTsInfo[i].tclasProcPresent = + pSession->ac_info[i].addTsRsp[j].rsp.tclasProcPresent; + pMsg->aggrInfo.aggrAddTsInfo[i].tspec = + pSession->ac_info[i].addTsRsp[j].rsp.tspec; + pMsg->aggrInfo.aggrAddTsInfo[i].wmeTspecPresent = + pSession->ac_info[i].addTsRsp[j].rsp.wmeTspecPresent; + pMsg->aggrInfo.aggrAddTsInfo[i].wsmTspecPresent = + pSession->ac_info[i].addTsRsp[j].rsp.wsmTspecPresent; + pMsg->aggrInfo.tspecIdx |= ( 1 << i ); + + // Mark the index for this AC as pending for response, which would be + // used to validate the AddTS response from HAL->PE->SME + pSession->ac_info[i].tspec_pending = (1<aggrInfo.tspecIdx); + + if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg))) + { + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sent down a AGGR QoS req to PE", + __func__, __LINE__); + } + + return status; +} + +eHalStatus sme_QosProcessFTRICResponse(tpAniSirGlobal pMac, v_U8_t sessionId, tDot11fIERICDataDesc *pRicDataDesc, v_U8_t ac, v_U8_t tspecIndex) +{ + tANI_U8 i = 0; + tpSirAddtsRsp pAddtsRsp + = &sme_QosCb.sessionInfo[sessionId].ac_info[ac].addTsRsp[tspecIndex]; + + vos_mem_zero(pAddtsRsp, sizeof(tSirAddtsRsp)); + + pAddtsRsp->messageType = eWNI_SME_ADDTS_RSP; + pAddtsRsp->length = sizeof(tSirAddtsRsp); + pAddtsRsp->rc = pRicDataDesc->RICData.statusCode; + pAddtsRsp->sessionId = sessionId; + pAddtsRsp->rsp.dialogToken = pRicDataDesc->RICData.Identifier; + pAddtsRsp->rsp.status = pRicDataDesc->RICData.statusCode; + pAddtsRsp->rsp.wmeTspecPresent = pRicDataDesc->TSPEC.present; + if (pAddtsRsp->rsp.wmeTspecPresent) + { + //Copy TSPEC params received in RIC response to addts response + ConvertTSPEC(pMac, &pAddtsRsp->rsp.tspec, &pRicDataDesc->TSPEC); + } + + pAddtsRsp->rsp.numTclas = pRicDataDesc->num_TCLAS; + if (pAddtsRsp->rsp.numTclas) + { + for (i = 0; i < pAddtsRsp->rsp.numTclas; i++) + { + //Copy TCLAS info per index to the addts response + ConvertTCLAS(pMac, &pAddtsRsp->rsp.tclasInfo[i], &pRicDataDesc->TCLAS[i]); + } + } + + pAddtsRsp->rsp.tclasProcPresent = pRicDataDesc->TCLASSPROC.present; + if (pAddtsRsp->rsp.tclasProcPresent) + pAddtsRsp->rsp.tclasProc = pRicDataDesc->TCLASSPROC.processing; + + + pAddtsRsp->rsp.schedulePresent = pRicDataDesc->Schedule.present; + if (pAddtsRsp->rsp.schedulePresent) + { + //Copy Schedule IE params to addts response + ConvertSchedule(pMac, &pAddtsRsp->rsp.schedule, &pRicDataDesc->Schedule); + } + + //Need to check the below portion is a part of WMM TSPEC + //Process Delay element + if (pRicDataDesc->TSDelay.present) + ConvertTSDelay(pMac, &pAddtsRsp->rsp.delay, &pRicDataDesc->TSDelay); + + //Need to call for WMMTSPEC + if (pRicDataDesc->WMMTSPEC.present) + { + ConvertWMMTSPEC(pMac, &pAddtsRsp->rsp.tspec, &pRicDataDesc->WMMTSPEC); + } + //return sme_QosProcessAddTsRsp(pMac, &addtsRsp); + return eHAL_STATUS_SUCCESS; +} +eHalStatus sme_QosProcessAggrQosRsp(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirAggrQosRsp pAggrRsp = (tpSirAggrQosRsp)pMsgBuf; + tSirAddtsRsp addtsRsp; + eHalStatus status = eHAL_STATUS_SUCCESS; + int i, j = 0; + tANI_U8 sessionId = pAggrRsp->sessionId; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Received AGGR_QOS resp from LIM")); + + /* Copy over the updated response information for TSPEC of all the ACs */ + for( i = 0; i < SIR_QOS_NUM_AC_MAX; i++ ) + { + tANI_U8 tspec_mask_status = sme_QosCb.sessionInfo[sessionId].ac_info[i].tspec_mask_status; + for( j = 0; j < SME_QOS_TSPEC_INDEX_MAX; j++ ) + { + tANI_U8 direction = sme_QosCb.sessionInfo[sessionId].ac_info[i]. + addTsRsp[j].rsp.tspec.tsinfo.traffic.direction; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Addts rsp from LIM AC=%d, flow=%d dir=%d, tspecIdx=%x"), + i, j, direction, pAggrRsp->aggrInfo.tspecIdx); + // Check if the direction is Uplink or bi-directional + if( ((1<aggrInfo.tspecIdx) && + ((tspec_mask_status) & (1<aggrInfo.aggrRsp[i].status; + addtsRsp.rsp.status = pAggrRsp->aggrInfo.aggrRsp[i].status; + addtsRsp.rsp.tspec = pAggrRsp->aggrInfo.aggrRsp[i].tspec; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Processing Addts rsp from LIM AC=%d, flow=%d"), i, j); + /* post ADD TS response for each */ + if (sme_QosProcessAddTsRsp(pMac, &addtsRsp) != eHAL_STATUS_SUCCESS) + { + status = eHAL_STATUS_FAILURE; + } + } + } + } + return status; +} + + +eHalStatus sme_QosProcessFTReassocRspEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + v_U8_t tspec_flow_index; + tDot11fIERICDataDesc *pRicDataDesc = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamConnectedInfo *pCsrConnectedInfo = NULL; + tANI_U32 ricRspLen; + + if(NULL == pCsrSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("The Session pointer is NULL")); + return eHAL_STATUS_FAILURE; + } + + pCsrConnectedInfo = &pCsrSession->connectedInfo; + + ricRspLen = pCsrConnectedInfo->nRICRspLength; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + pRicDataDesc = (tDot11fIERICDataDesc *)((pCsrConnectedInfo->pbFrames) + + (pCsrConnectedInfo->nBeaconLength + pCsrConnectedInfo->nAssocReqLength + + pCsrConnectedInfo->nAssocRspLength)); + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + + for (tspec_flow_index = 0; tspec_flow_index < SME_QOS_TSPEC_INDEX_MAX; tspec_flow_index++) + { + /* Only in the below case, copy the AC's curr QoS Info to requested QoS info */ + if (pACInfo->ricIdentifier[tspec_flow_index]) + { + + if (!ricRspLen) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RIC Response not received for AC %d on TSPEC Index %d, RIC Req Identifier = %d"), + ac, tspec_flow_index, pACInfo->ricIdentifier[tspec_flow_index]); + VOS_ASSERT(0); + } + else + { + /* Now we got response for this identifier. Process it. */ + if (pRicDataDesc->present) + { + if (pRicDataDesc->RICData.present) + { + if (pRicDataDesc->RICData.Identifier != pACInfo->ricIdentifier[tspec_flow_index]) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RIC response order not same as request sent. Request ID = %d, Response ID = %d"), + pACInfo->ricIdentifier[tspec_flow_index], pRicDataDesc->RICData.Identifier); + VOS_ASSERT(0); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Processing RIC Response for AC %d, TSPEC Flow index %d with RIC ID %d "), + ac, tspec_flow_index, pRicDataDesc->RICData.Identifier); + status = sme_QosProcessFTRICResponse(pMac, sessionId, pRicDataDesc, ac, tspec_flow_index); + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed with status %d for AC %d in TSPEC Flow index = %d"), + status, ac, tspec_flow_index); + } + } + pRicDataDesc++; + ricRspLen -= sizeof(tDot11fIERICDataDesc); + } + } + } + } + + } + } + + if (ricRspLen) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RIC Response still follows despite traversing through all ACs. Remaining len = %d"), ricRspLen); + VOS_ASSERT(0); + } + + /* Send the Aggregated QoS request to HAL */ + status = sme_QosFTAggrQosReq(pMac,sessionId); + + return status; +} + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + + +/*-------------------------------------------------------------------------- + \brief sme_QosAddTsReq() - To send down the ADDTS request with TSPEC params + to PE + + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - Session upon which the TSPEC should be added + \param pTspec_Info - Pointer to sme_QosWmmTspecInfo which contains the WMM + TSPEC related info as defined above + \param ac - Enumeration of the various EDCA Access Categories. + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAddTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pTspec_Info, + sme_QosEdcaAcType ac) +{ + tSirAddtsReq *pMsg = NULL; + sme_QosSessionInfo *pSession; + eHalStatus status = eHAL_STATUS_FAILURE; +#ifdef FEATURE_WLAN_ESE + tCsrRoamSession *pCsrSession = CSR_GET_SESSION( pMac, sessionId ); +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d", + __func__, __LINE__, + sessionId, ac); + if (sessionId >= CSR_ROAM_SESSION_MAX) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sessionId(%d) is invalid", + __func__, __LINE__, sessionId); + return eHAL_STATUS_FAILURE; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + pMsg = (tSirAddtsReq *)vos_mem_malloc(sizeof(tSirAddtsReq)); + if (!pMsg) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the msg buffer", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(pMsg, sizeof(tSirAddtsReq)); + pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_ADDTS_REQ); + pMsg->length = sizeof(tSirAddtsReq); + pMsg->sessionId = sessionId; + pMsg->timeout = 0; + pMsg->rspReqd = VOS_TRUE; + pMsg->req.dialogToken = sme_QosAssignDialogToken(); + /*As per WMM_AC_testplan_v0.39 Minimum Service Interval, Maximum Service + Interval, Service Start Time, Suspension Interval and Delay Bound are + all intended for HCCA operation and therefore must be set to zero*/ + pMsg->req.tspec.delayBound = 0; + pMsg->req.tspec.inactInterval = pTspec_Info->inactivity_interval; + pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH; + pMsg->req.tspec.maxBurstSz = pTspec_Info->max_burst_size; + pMsg->req.tspec.maxMsduSz = pTspec_Info->maximum_msdu_size; + pMsg->req.tspec.maxSvcInterval = pTspec_Info->max_service_interval; + pMsg->req.tspec.meanDataRate = pTspec_Info->mean_data_rate; + pMsg->req.tspec.mediumTime = pTspec_Info->medium_time; + pMsg->req.tspec.minDataRate = pTspec_Info->min_data_rate; + pMsg->req.tspec.minPhyRate = pTspec_Info->min_phy_rate; + pMsg->req.tspec.minSvcInterval = pTspec_Info->min_service_interval; + pMsg->req.tspec.nomMsduSz = pTspec_Info->nominal_msdu_size; + pMsg->req.tspec.peakDataRate = pTspec_Info->peak_data_rate; + pMsg->req.tspec.surplusBw = pTspec_Info->surplus_bw_allowance; + pMsg->req.tspec.suspendInterval = pTspec_Info->suspension_interval; + pMsg->req.tspec.svcStartTime = 0; + pMsg->req.tspec.tsinfo.traffic.direction = pTspec_Info->ts_info.direction; + //Make sure UAPSD is allowed. BTC may want to disable UAPSD while keep QoS setup + if( pTspec_Info->ts_info.psb + && btcIsReadyForUapsd(pMac) + ) + { + pMsg->req.tspec.tsinfo.traffic.psb = pTspec_Info->ts_info.psb; + } + else + { + pMsg->req.tspec.tsinfo.traffic.psb = 0; + pTspec_Info->ts_info.psb = 0; + } + pMsg->req.tspec.tsinfo.traffic.tsid = pTspec_Info->ts_info.tid; + pMsg->req.tspec.tsinfo.traffic.userPrio = pTspec_Info->ts_info.up; + pMsg->req.tspec.tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA; + pMsg->req.tspec.tsinfo.traffic.burstSizeDefn = pTspec_Info->ts_info.burst_size_defn; + pMsg->req.tspec.tsinfo.traffic.ackPolicy = pTspec_Info->ts_info.ack_policy; + pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE; + /*Fill the BSSID pMsg->req.bssId*/ + if (NULL == pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: BSS descriptor is NULL so we don't send request to PE", + __func__, __LINE__); + vos_mem_free(pMsg); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy( &pMsg->bssId[ 0 ], + &pSession->assocInfo.pBssDesc->bssId[ 0 ], + sizeof(tCsrBssid) ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: up = %d, tid = %d", + __func__, __LINE__, + pTspec_Info->ts_info.up, + pTspec_Info->ts_info.tid); +#ifdef FEATURE_WLAN_ESE + if(pCsrSession->connectedProfile.isESEAssoc) + { + pMsg->req.tsrsIE.tsid = pTspec_Info->ts_info.up; + pMsg->req.tsrsPresent = 1; + } +#endif + if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg))) + { + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sent down a ADDTS req to PE", + __func__, __LINE__); + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_ADDTS_REQ; + qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDelTsReq() - To send down the DELTS request with TSPEC params + to PE + + + \param pMac - Pointer to the global MAC parameter structure. + \param sessionId - Session from which the TSPEC should be deleted + \param ac - Enumeration of the various EDCA Access Categories. + \param tspec_mask - on which tspec per AC, the delts is requested + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosDelTsReq(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + tSirDeltsReq *pMsg; + sme_QosWmmTspecInfo *pTspecInfo; + eHalStatus status = eHAL_STATUS_FAILURE; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d", + __func__, __LINE__, + sessionId, ac); + pMsg = (tSirDeltsReq *)vos_mem_malloc(sizeof(tSirDeltsReq)); + if (!pMsg) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the msg buffer", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(pMsg, sizeof(tSirDeltsReq)); + // get pointer to the TSPEC being deleted + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + pTspecInfo = &pACInfo->curr_QoSInfo[tspec_mask - 1]; + pMsg->messageType = pal_cpu_to_be16((v_U16_t)eWNI_SME_DELTS_REQ); + pMsg->length = sizeof(tSirDeltsReq); + pMsg->sessionId = sessionId; + pMsg->rspReqd = VOS_TRUE; + pMsg->req.tspec.delayBound = pTspecInfo->delay_bound; + pMsg->req.tspec.inactInterval = pTspecInfo->inactivity_interval; + pMsg->req.tspec.length = SME_QOS_TSPEC_IE_LENGTH; + pMsg->req.tspec.maxBurstSz = pTspecInfo->max_burst_size; + pMsg->req.tspec.maxMsduSz = pTspecInfo->maximum_msdu_size; + pMsg->req.tspec.maxSvcInterval = pTspecInfo->max_service_interval; + pMsg->req.tspec.meanDataRate = pTspecInfo->mean_data_rate; + pMsg->req.tspec.mediumTime = pTspecInfo->medium_time; + pMsg->req.tspec.minDataRate = pTspecInfo->min_data_rate; + pMsg->req.tspec.minPhyRate = pTspecInfo->min_phy_rate; + pMsg->req.tspec.minSvcInterval = pTspecInfo->min_service_interval; + pMsg->req.tspec.nomMsduSz = pTspecInfo->nominal_msdu_size; + pMsg->req.tspec.peakDataRate = pTspecInfo->peak_data_rate; + pMsg->req.tspec.surplusBw = pTspecInfo->surplus_bw_allowance; + pMsg->req.tspec.suspendInterval = pTspecInfo->suspension_interval; + pMsg->req.tspec.svcStartTime = pTspecInfo->svc_start_time; + pMsg->req.tspec.tsinfo.traffic.direction = pTspecInfo->ts_info.direction; + pMsg->req.tspec.tsinfo.traffic.psb = pTspecInfo->ts_info.psb; + pMsg->req.tspec.tsinfo.traffic.tsid = pTspecInfo->ts_info.tid; + pMsg->req.tspec.tsinfo.traffic.userPrio = pTspecInfo->ts_info.up; + pMsg->req.tspec.tsinfo.traffic.accessPolicy = SME_QOS_ACCESS_POLICY_EDCA; + pMsg->req.tspec.tsinfo.traffic.burstSizeDefn = pTspecInfo->ts_info.burst_size_defn; + pMsg->req.tspec.tsinfo.traffic.ackPolicy = pTspecInfo->ts_info.ack_policy; + pMsg->req.tspec.type = SME_QOS_TSPEC_IE_TYPE; + /*Fill the BSSID pMsg->req.bssId*/ + if (NULL == pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: BSS descriptor is NULL so we don't send request to PE", + __func__, __LINE__); + vos_mem_free(pMsg); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy( &pMsg->bssId[ 0 ], + &pSession->assocInfo.pBssDesc->bssId[ 0 ], + sizeof(tCsrBssid) ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: up = %d, tid = %d", + __func__, __LINE__, + pTspecInfo->ts_info.up, + pTspecInfo->ts_info.tid); + vos_mem_zero(&pACInfo->curr_QoSInfo[tspec_mask - 1], + sizeof(sme_QosWmmTspecInfo)); + if(HAL_STATUS_SUCCESS(palSendMBMessage(pMac->hHdd, pMsg))) + { + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sme_QosDelTsReq:Test: sent down a DELTS req to PE", + __func__, __LINE__); + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_DELTS; + qos.reasonCode = SME_QOS_DIAG_USER_REQUESTED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + } + + return status; +} + + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAddTsRsp() - Function to process the + eWNI_SME_ADDTS_RSP came from PE + + \param pMac - Pointer to the global MAC parameter structure. + \param pMsgBuf - Pointer to the msg buffer came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAddTsRsp(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirAddtsRsp paddts_rsp = (tpSirAddtsRsp)pMsgBuf; + sme_QosSessionInfo *pSession; + v_U8_t sessionId = paddts_rsp->sessionId; + eHalStatus status = eHAL_STATUS_FAILURE; +#ifdef WLAN_FEATURE_VOWIFI_11R + sme_QosWmmUpType up = (sme_QosWmmUpType)paddts_rsp->rsp.tspec.tsinfo.traffic.userPrio; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; +#endif +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + + pSession = &sme_QosCb.sessionInfo[sessionId]; + +#ifdef WLAN_FEATURE_VOWIFI_11R + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, ac, up); + + return eHAL_STATUS_FAILURE; + } + pACInfo = &pSession->ac_info[ac]; + if (SME_QOS_HANDOFF == pACInfo->curr_state) + { + smsLog(pMac, LOG1, FL("ADDTS Response received for AC %d in HANDOFF State.. Dropping"), ac); + pSession->readyForPowerSave = VOS_TRUE; + return eHAL_STATUS_SUCCESS; + } +#endif + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d with return code %d", + __func__, __LINE__, + sessionId, paddts_rsp->rc); + // our outstanding request has been serviced + // we can go into powersave + pSession->readyForPowerSave = VOS_TRUE; + if(paddts_rsp->rc) + { + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_ADDTS_RSP; + qos.reasonCode = SME_QOS_DIAG_ADDTS_REFUSED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + status = sme_QosProcessAddTsFailureRsp(pMac, sessionId, &paddts_rsp->rsp); + } + else + { + status = sme_QosProcessAddTsSuccessRsp(pMac, sessionId, &paddts_rsp->rsp); + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessDelTsRsp() - Function to process the + eWNI_SME_DELTS_RSP came from PE + + \param pMac - Pointer to the global MAC parameter structure. + \param pMsgBuf - Pointer to the msg buffer came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessDelTsRsp(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirDeltsRsp pDeltsRsp = (tpSirDeltsRsp)pMsgBuf; + sme_QosSessionInfo *pSession; + v_U8_t sessionId = pDeltsRsp->sessionId; + // msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d with return code %d", + __func__, __LINE__, + sessionId, pDeltsRsp->rc); + pSession = &sme_QosCb.sessionInfo[sessionId]; + // our outstanding request has been serviced + // we can go into powersave + pSession->readyForPowerSave = VOS_TRUE; + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessDelTsInd() - Function to process the + eWNI_SME_DELTS_IND came from PE + + Since it's a DELTS indication from AP, will notify all the flows running on + this AC about QoS release + \param pMac - Pointer to the global MAC parameter structure. + \param pMsgBuf - Pointer to the msg buffer came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessDelTsInd(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirDeltsRsp pdeltsind = (tpSirDeltsRsp)pMsgBuf; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t sessionId = pdeltsind->sessionId; + sme_QosEdcaAcType ac; + sme_QosSearchInfo search_key; + sme_QosWmmUpType up = (sme_QosWmmUpType)pdeltsind->rsp.tspec.tsinfo.traffic.userPrio; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, + ac, up); + return eHAL_STATUS_FAILURE; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + //find all Flows on the perticular AC & delete them, also send HDD indication + // through the callback it registered per request + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosDelTsIndFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for ac = %d", + __func__, __LINE__, + search_key.key.ac_type); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + +//event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_DELTS; + qos.reasonCode = SME_QOS_DIAG_DELTS_IND_FROM_AP; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); +#endif //FEATURE_WLAN_DIAG_SUPPORT + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAssocCompleteEv() - Function to process the + SME_QOS_CSR_ASSOC_COMPLETE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAssocCompleteEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + eHalStatus status = eHAL_STATUS_FAILURE; + sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_BE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if(((SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state)&& + (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state)&& + (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state)&& + (SME_QOS_INIT == pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state)) || + (pSession->handoffRequested)) + { + //get the association info + if(!pEvent_info) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pEvent_info is NULL", + __func__, __LINE__); + return status; + } + if(!((sme_QosAssocInfo *)pEvent_info)->pBssDesc) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pBssDesc is NULL", + __func__, __LINE__); + return status; + } + if((pSession->assocInfo.pBssDesc) && + (csrIsBssidMatch(pMac, (tCsrBssid *)&pSession->assocInfo.pBssDesc->bssId, + (tCsrBssid *) &(((sme_QosAssocInfo *)pEvent_info)->pBssDesc->bssId)))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: assoc with the same BSS, no update needed", + __func__, __LINE__); + } + else + { + status = sme_QosSaveAssocInfo(pSession, pEvent_info); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: wrong state: BE %d, BK %d, VI %d, VO %d", + __func__, __LINE__, + pSession->ac_info[SME_QOS_EDCA_AC_BE].curr_state, + pSession->ac_info[SME_QOS_EDCA_AC_BK].curr_state, + pSession->ac_info[SME_QOS_EDCA_AC_VI].curr_state, + pSession->ac_info[SME_QOS_EDCA_AC_VO].curr_state); + //ASSERT + VOS_ASSERT(0); + return status; + } + // the session is active + pSession->sessionActive = VOS_TRUE; + if(pSession->handoffRequested) + { + pSession->handoffRequested = VOS_FALSE; + //renew all flows + (void)sme_QosProcessBufferedCmd(sessionId); + status = eHAL_STATUS_SUCCESS; + } + else + { + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_INIT: + sme_QosStateTransition(sessionId, ac, SME_QOS_LINK_UP); + break; + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + case SME_QOS_HANDOFF: + case SME_QOS_CLOSED: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessReassocReqEv() - Function to process the + SME_QOS_CSR_REASSOC_REQ event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessReassocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pSession->ftHandoffInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF); + sme_QosProcessFTReassocReqEv(pMac, sessionId, pEvent_info); + return eHAL_STATUS_SUCCESS; + } +#endif + + if(pSession->handoffRequested) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF); + + //buffer the existing flows to be renewed after handoff is done + sme_QosBufferExistingFlows(pMac, sessionId); + //clean up the control block partially for handoff + sme_QosCleanupCtrlBlkForHandoff(pMac, sessionId); + return eHAL_STATUS_SUCCESS; + } +//TBH: Assuming both handoff algo & 11r willn't be enabled at the same time +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pSession->ftHandoffInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF); + + sme_QosProcessFTReassocReqEv(pMac, sessionId, pEvent_info); + return eHAL_STATUS_SUCCESS; + } +#endif + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + break; + case SME_QOS_HANDOFF: + //This is normal because sme_QosRequestReassoc may already change the state + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessReassocSuccessEv() - Function to process the + SME_QOS_CSR_REASSOC_COMPLETE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessReassocSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + + tCsrRoamSession *pCsrRoamSession = NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac, ac_index; + sme_QosSearchInfo search_key; + sme_QosSearchInfo search_key1; + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry= NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + + if (CSR_ROAM_SESSION_MAX <= sessionId) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + return status; + } + + pCsrRoamSession = CSR_GET_SESSION( pMac, sessionId ); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + // our pending reassociation has completed + // we can allow powersave + pSession->readyForPowerSave = VOS_TRUE; + //get the association info + if(!pEvent_info) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pEvent_info is NULL", + __func__, __LINE__); + return status; + } + if(!((sme_QosAssocInfo *)pEvent_info)->pBssDesc) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pBssDesc is NULL", + __func__, __LINE__); + return status; + } + status = sme_QosSaveAssocInfo(pSession, pEvent_info); + if(status) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosSaveAssocInfo() failed", + __func__, __LINE__); + } +//TBH: Assuming both handoff algo & 11r willn't be enabled at the same time + if(pSession->handoffRequested) + { + pSession->handoffRequested = VOS_FALSE; + //renew all flows + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSession->ftHandoffInProgress) + { + if (csrRoamIs11rAssoc(pMac)) + { + if (pCsrRoamSession && pCsrRoamSession->connectedInfo.nRICRspLength) + { + status = sme_QosProcessFTReassocRspEv(pMac, sessionId, pEvent_info); + } + } +#ifdef FEATURE_WLAN_ESE + // If ESE association check for TSPEC IEs in the reassoc rsp frame + if (csrRoamIsESEAssoc(pMac)) + { + if (pCsrRoamSession && pCsrRoamSession->connectedInfo.nTspecIeLength) + { + status = sme_QosESEProcessReassocTspecRsp(pMac, sessionId, pEvent_info); + } + } +#endif + pSession->ftHandoffInProgress = VOS_FALSE; + pSession->handoffRequested = VOS_FALSE; + return status; + } +#endif + + pSession->sessionActive = VOS_TRUE; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + // return to our previous state + sme_QosStateTransition(sessionId, ac, pACInfo->prev_state); + //for which ac APSD (hence the reassoc) is requested + if(pACInfo->reassoc_pending) + { + //update the apsd mask in CB - make sure to take care of the case + //where we are resetting the bit in apsd_mask + if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb) + { + pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + } + else + { + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + } + pACInfo->reassoc_pending = VOS_FALSE; + //during setup it gets set as addts & reassoc both gets a pending flag + //pACInfo->tspec_pending = 0; + sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON); + // notify HDD with new Service Interval + pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0] = + pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0]; + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + //notify PMC that reassoc is done for APSD on certain AC?? + + vos_mem_zero(&search_key1, sizeof(sme_QosSearchInfo)); + //set the hoRenewal field in control block if needed + search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3; + search_key1.key.reason = SME_QOS_REASON_SETUP; + search_key1.sessionId = sessionId; + for(ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX; ac_index++) + { + pEntry = sme_QosFindInFlowList(search_key1); + if(pEntry) + { + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if(flow_info->ac_type == ac) + { + pACInfo->hoRenewal = flow_info->hoRenewal; + break; + } + } + } + //notify HDD the success for the requested flow + //notify all the other flows running on the AC that QoS got modified + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosReassocSuccessEvFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no match found for ac = %d", + __func__, __LINE__, + search_key.key.ac_type); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + pACInfo->hoRenewal = VOS_FALSE; + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + } + status = eHAL_STATUS_SUCCESS; + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + //NOP + status = eHAL_STATUS_SUCCESS; + break; + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + (void)sme_QosProcessBufferedCmd(sessionId); + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessReassocFailureEv() - Function to process the + SME_QOS_CSR_REASSOC_FAILURE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessReassocFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + // our pending reassociation has completed + // we can allow powersave + pSession->readyForPowerSave = VOS_TRUE; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + if(pACInfo->reassoc_pending) + { + pACInfo->reassoc_pending = VOS_FALSE; + } + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR; + pACInfo->tspec_pending = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0; + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + //NOP + break; + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + //need to clean up flows + sme_QosDeleteExistingFlows(pMac, sessionId); + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessHandoffAssocReqEv() - Function to process the + SME_QOS_CSR_HANDOFF_ASSOC_REQ event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessHandoffAssocReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + break; + case SME_QOS_HANDOFF: + //print error msg +#ifdef WLAN_FEATURE_VOWIFI_11R + if(pSession->ftHandoffInProgress) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: SME_QOS_CSR_HANDOFF_ASSOC_REQ received in " + "SME_QOS_HANDOFF state with FT in progress" + , __func__, __LINE__); + break; + } +#endif + + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + // If FT handoff is in progress, legacy handoff need not be enabled + if (!pSession->ftHandoffInProgress) { + pSession->handoffRequested = VOS_TRUE; + } + // this session no longer needs UAPSD + pSession->apsdMask = 0; + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + pSession->uapsdAlreadyRequested = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessHandoffSuccessEv() - Function to process the + SME_QOS_CSR_HANDOFF_COMPLETE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessHandoffSuccessEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + //go back to original state before handoff + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, pACInfo->prev_state); + //we will retry for the requested flow(s) with the new AP + if(SME_QOS_REQUESTED == pACInfo->curr_state) + { + pACInfo->curr_state = SME_QOS_LINK_UP; + } + status = eHAL_STATUS_SUCCESS; + break; + // FT logic, has already moved it to QOS_REQUESTED state during the + // reassoc request event, which would include the Qos (TSPEC) params + // in the reassoc req frame + case SME_QOS_REQUESTED: + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + case SME_QOS_LINK_UP: + case SME_QOS_QOS_ON: + default: +#ifdef WLAN_FEATURE_VOWIFI_11R +/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the + state may be SME_QOS_REQUESTED */ + if( pSession->ftHandoffInProgress ) + break; +#endif + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessHandoffFailureEv() - Function to process the + SME_QOS_CSR_HANDOFF_FAILURE event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessHandoffFailureEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + switch(pACInfo->curr_state) + { + case SME_QOS_HANDOFF: + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + //need to clean up flows: TODO + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + vos_mem_zero(&pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_1], + sizeof(sme_QosWmmTspecInfo)); + pACInfo->tspec_mask_status = SME_QOS_TSPEC_MASK_CLEAR; + pACInfo->tspec_pending = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0] = 0; + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] = 0; + break; + case SME_QOS_INIT: + case SME_QOS_CLOSED: + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + //no longer in handoff + pSession->handoffRequested = VOS_FALSE; + //clean up the assoc info + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessDisconnectEv() - Function to process the + SME_QOS_CSR_DISCONNECT_REQ or SME_QOS_CSR_DISCONNECT_IND event indication + from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessDisconnectEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if((pSession->handoffRequested) +#ifdef WLAN_FEATURE_VOWIFI_11R +/* In case of 11r - RIC, we request QoS and Hand-off at the same time hence the + state may be SME_QOS_REQUESTED */ + && !pSession->ftHandoffInProgress +#endif + ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF); + return eHAL_STATUS_SUCCESS; + } + sme_QosInitACs(pMac, sessionId); + // this session doesn't require UAPSD + pSession->apsdMask = 0; + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + pSession->uapsdAlreadyRequested = VOS_FALSE; + pSession->handoffRequested = VOS_FALSE; + pSession->readyForPowerSave = VOS_TRUE; + pSession->roamID = 0; + //need to clean up buffered req + sme_QosDeleteBufferedRequests(pMac, sessionId); + //need to clean up flows + sme_QosDeleteExistingFlows(pMac, sessionId); + //clean up the assoc info + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + sme_QosCb.sessionInfo[sessionId].sessionActive = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessJoinReqEv() - Function to process the + SME_QOS_CSR_JOIN_REQ event indication from CSR + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessJoinReqEv(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosEdcaAcType ac; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if(pSession->handoffRequested) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: no need for state transition, should " + "already be in handoff state", + __func__, __LINE__); + VOS_ASSERT(pSession->ac_info[0].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[1].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[2].curr_state == SME_QOS_HANDOFF); + VOS_ASSERT(pSession->ac_info[3].curr_state == SME_QOS_HANDOFF); + //buffer the existing flows to be renewed after handoff is done + sme_QosBufferExistingFlows(pMac, sessionId); + //clean up the control block partially for handoff + sme_QosCleanupCtrlBlkForHandoff(pMac, sessionId); + return eHAL_STATUS_SUCCESS; + } + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + } + //clean up the assoc info if already set + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*-------------------------------------------------------------------------- + \brief sme_QosProcessPreauthSuccessInd() - Function to process the + SME_QOS_CSR_PREAUTH_SUCCESS_IND event indication from CSR + + \param pEvent_info - Pointer to relevant info from CSR. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessPreauthSuccessInd(tpAniSirGlobal pMac, v_U8_t sessionId, void * pEvent_info) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac; + eHalStatus status = eHAL_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d", + __func__, __LINE__, + sessionId); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + + switch(pACInfo->curr_state) + { + case SME_QOS_LINK_UP: + case SME_QOS_REQUESTED: + case SME_QOS_QOS_ON: + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + break; + case SME_QOS_HANDOFF: + //print error msg + case SME_QOS_CLOSED: + case SME_QOS_INIT: + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d is in wrong state %d", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //ASSERT + VOS_ASSERT(0); + break; + } + } + + pSession->ftHandoffInProgress = VOS_TRUE; + + // Check if its a 11R roaming before preparing the RIC IEs + if (csrRoamIs11rAssoc(pMac)) + { + v_U16_t ricOffset = 0; + v_U32_t ricIELength = 0; + v_U8_t *ricIE; + v_U8_t tspec_mask_status = 0; + v_U8_t tspec_pending_status = 0; + + /* Any Block Ack info there, should have been already filled by PE and present in this buffer + and the ric_ies_length should contain the length of the whole RIC IEs. Filling of TSPEC info + should start from this length */ + ricIE = pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies; + ricOffset = pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length; + + /* Now we have to process the currentTspeInfo inside this session and create the RIC IEs */ + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + volatile v_U8_t tspec_index = 0; + ricIELength = 0; + pACInfo = &pSession->ac_info[ac]; + tspec_pending_status = pACInfo->tspec_pending; + tspec_mask_status = pACInfo->tspec_mask_status; + vos_mem_zero(pACInfo->ricIdentifier, SME_QOS_TSPEC_INDEX_MAX); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("AC %d ==> TSPEC status = %d, tspec pending = %d"), + ac, tspec_mask_status, tspec_pending_status); + + do + { + if (tspec_mask_status & 0x1) + { + /* If a tspec status is pending, take requested_QoSInfo for RIC request, else use curr_QoSInfo + for the RIC request */ + if (tspec_pending_status & 0x1) + { + status = sme_QosCreateTspecRICIE(pMac, &pACInfo->requested_QoSInfo[tspec_index], + ricIE + ricOffset, &ricIELength, &pACInfo->ricIdentifier[tspec_index]); + } + else + { + status = sme_QosCreateTspecRICIE(pMac, &pACInfo->curr_QoSInfo[tspec_index], + ricIE + ricOffset, &ricIELength, &pACInfo->ricIdentifier[tspec_index]); + } + } + ricOffset += ricIELength; + pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length += ricIELength; + + tspec_mask_status >>= 1; + tspec_pending_status >>= 1; + tspec_index++; + } while (tspec_mask_status); + } + } + return status; +} + +#endif + + +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAddTsFailureRsp() - Function to process the + Addts request failure response came from PE + + We will notify HDD only for the requested Flow, other Flows running on the AC + stay intact + + \param pMac - Pointer to the global MAC parameter structure. + \param pRsp - Pointer to the addts response structure came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAddTsFailureRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + sme_QosSearchInfo search_key; + v_U8_t tspec_pending; + sme_QosWmmUpType up = (sme_QosWmmUpType)pRsp->tspec.tsinfo.traffic.userPrio; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, ac, up); + return eHAL_STATUS_FAILURE; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + // is there a TSPEC request pending on this AC? + tspec_pending = pACInfo->tspec_pending; + if(!tspec_pending) + { + //ASSERT + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d an AddTS is not pending on AC %d", + __func__, __LINE__, + sessionId, ac); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosAddTsFailureFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d no match found for ac = %d", + __func__, __LINE__, + sessionId, search_key.key.ac_type); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1], + sizeof(sme_QosWmmTspecInfo)); + + if((!pACInfo->num_flows[0])&& + (!pACInfo->num_flows[1])) + { + pACInfo->tspec_mask_status &= SME_QOS_TSPEC_MASK_BIT_1_2_SET & + (~pACInfo->tspec_pending); + sme_QosStateTransition(sessionId, ac, SME_QOS_LINK_UP); + } + else + { + sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON); + } + pACInfo->tspec_pending = 0; + + (void)sme_QosProcessBufferedCmd(sessionId); + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateTspecMask() - Utiltity function to update the tspec. + Typical usage while aggregating unidirectional flows into a bi-directional + flow on AC which is running multiple flows + + \param sessionId - Session upon which the TSPEC is being updated + \param ac - Enumeration of the various EDCA Access Categories. + \param old_tspec_mask - on which tspec per AC, the update is requested + \param new_tspec_mask - tspec to be set for this AC + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosUpdateTspecMask(v_U8_t sessionId, + sme_QosSearchInfo search_key, + v_U8_t new_tspec_mask) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d TSPEC %d", + __func__, __LINE__, + sessionId, search_key.key.ac_type, new_tspec_mask); + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + if (search_key.key.ac_type < SME_QOS_EDCA_AC_MAX) + { + pACInfo = &pSession->ac_info[search_key.key.ac_type]; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Exceeded the array bounds of pSession->ac_info", + __func__, __LINE__); + VOS_ASSERT (0); + return eHAL_STATUS_FAILURE; + } + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, nothing to update", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + + if(search_key.sessionId == flow_info->sessionId) + { + if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_4) + { + if((search_key.key.ac_type == flow_info->ac_type) && + (search_key.direction == flow_info->QoSInfo.ts_info.direction)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow %d matches", + __func__, __LINE__, + flow_info->QosFlowID); + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->num_flows[new_tspec_mask - 1]++; + flow_info->tspec_mask = new_tspec_mask; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_5) + { + if((search_key.key.ac_type == flow_info->ac_type) && + (search_key.tspec_mask == flow_info->tspec_mask)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow %d matches", + __func__, __LINE__, + flow_info->QosFlowID); + pACInfo->num_flows[flow_info->tspec_mask - 1]--; + pACInfo->num_flows[new_tspec_mask - 1]++; + flow_info->tspec_mask = new_tspec_mask; + } + } + } + + pEntry = pNextEntry; + } + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessAddTsSuccessRsp() - Function to process the + Addts request success response came from PE + + We will notify HDD with addts success for the requested Flow, & for other + Flows running on the AC we will send an addts modify status + + + \param pMac - Pointer to the global MAC parameter structure. + \param pRsp - Pointer to the addts response structure came from PE. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessAddTsSuccessRsp(tpAniSirGlobal pMac, + v_U8_t sessionId, + tSirAddtsRspInfo * pRsp) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac, ac_index; + sme_QosSearchInfo search_key; + sme_QosSearchInfo search_key1; + v_U8_t tspec_pending; + tListElem *pEntry= NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosWmmUpType up = (sme_QosWmmUpType)pRsp->tspec.tsinfo.traffic.userPrio; +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(qos, vos_event_wlan_qos_payload_type); + vos_log_qos_tspec_pkt_type *log_ptr = NULL; +#endif //FEATURE_WLAN_DIAG_SUPPORT + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for UP %d", + __func__, __LINE__, + sessionId, up); + pSession = &sme_QosCb.sessionInfo[sessionId]; + ac = sme_QosUpToAc(up); + if(SME_QOS_EDCA_AC_MAX == ac) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid AC %d from UP %d", + __func__, __LINE__, ac, up); + return eHAL_STATUS_FAILURE; + } + pACInfo = &pSession->ac_info[ac]; + // is there a TSPEC request pending on this AC? + tspec_pending = pACInfo->tspec_pending; + if(!tspec_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d an AddTS is not pending on AC %d", + __func__, __LINE__, + sessionId, ac); + return eHAL_STATUS_FAILURE; + } + //App is looking for APSD or the App which was looking for APSD has been + //released, so STA re-negotiated with AP + if(pACInfo->requested_QoSInfo[tspec_pending - 1].ts_info.psb) + { + //update the session's apsd mask + pSession->apsdMask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + } + else + { + if(((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) > 0) && + ((SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) <= + SME_QOS_TSPEC_INDEX_MAX)) + { + if(!pACInfo->requested_QoSInfo + [(SME_QOS_TSPEC_MASK_BIT_1_2_SET & ~tspec_pending) - 1].ts_info.psb) + { + //update the session's apsd mask + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Exceeded the array bounds of pACInfo->requested_QosInfo", + __func__, __LINE__); + VOS_ASSERT (0); + return eHAL_STATUS_FAILURE; + } + } + + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.burst_size_defn = + pRsp->tspec.tsinfo.traffic.burstSizeDefn; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.ack_policy = + pRsp->tspec.tsinfo.traffic.ackPolicy; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up = + pRsp->tspec.tsinfo.traffic.userPrio; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb = + pRsp->tspec.tsinfo.traffic.psb; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction = + pRsp->tspec.tsinfo.traffic.direction; + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid = + pRsp->tspec.tsinfo.traffic.tsid; + pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size = + pRsp->tspec.nomMsduSz; + pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size = + pRsp->tspec.maxMsduSz; + pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval = + pRsp->tspec.minSvcInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval = + pRsp->tspec.maxSvcInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval = + pRsp->tspec.inactInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval = + pRsp->tspec.suspendInterval; + pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time = + pRsp->tspec.svcStartTime; + pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate = + pRsp->tspec.minDataRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate = + pRsp->tspec.meanDataRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate = + pRsp->tspec.peakDataRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size = + pRsp->tspec.maxBurstSz; + pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound = + pRsp->tspec.delayBound; + + pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate = + pRsp->tspec.minPhyRate; + pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance = + pRsp->tspec.surplusBw; + pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time = + pRsp->tspec.mediumTime; + // Save the expected UAPSD settings by application + pACInfo->curr_QoSInfo[tspec_pending - 1].expec_psb_byapp = + pACInfo->requested_QoSInfo[tspec_pending - 1].expec_psb_byapp; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AddTspec Medium Time %d", + __func__, __LINE__, + sessionId, pRsp->tspec.mediumTime); + + /* Check if the current flow is for bi-directional. If so, update the number of flows + * to reflect that all flows are aggregated into tspec index 0. */ + if((pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.direction == SME_QOS_WMM_TS_DIR_BOTH) && + (pACInfo->num_flows[SME_QOS_TSPEC_INDEX_1] > 0)) + { + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + /* update tspec_mask for all the flows having SME_QOS_TSPEC_MASK_BIT_2_SET to SME_QOS_TSPEC_MASK_BIT_1_SET */ + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_5; + search_key.sessionId = sessionId; + search_key.tspec_mask = SME_QOS_TSPEC_MASK_BIT_2_SET; + sme_QosUpdateTspecMask(sessionId, search_key, SME_QOS_TSPEC_MASK_BIT_1_SET); + } + + vos_mem_zero(&search_key1, sizeof(sme_QosSearchInfo)); + //set the horenewal field in control block if needed + search_key1.index = SME_QOS_SEARCH_KEY_INDEX_3; + search_key1.key.reason = SME_QOS_REASON_SETUP; + search_key1.sessionId = sessionId; + for(ac_index = SME_QOS_EDCA_AC_BE; ac_index < SME_QOS_EDCA_AC_MAX; ac_index++) + { + pEntry = sme_QosFindInFlowList(search_key1); + if(pEntry) + { + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if(flow_info->ac_type == ac) + { + pACInfo->hoRenewal = flow_info->hoRenewal; + break; + } + } + } + vos_mem_zero(&search_key, sizeof(sme_QosSearchInfo)); + //set the key type & the key to be searched in the Flow List + search_key.key.ac_type = ac; + search_key.index = SME_QOS_SEARCH_KEY_INDEX_2; + search_key.sessionId = sessionId; + //notify HDD the success for the requested flow + //notify all the other flows running on the AC that QoS got modified + if(!HAL_STATUS_SUCCESS(sme_QosFindAllInFlowList(pMac, search_key, sme_QosAddTsSuccessFnp))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d no match found for ac %d", + __func__, __LINE__, + sessionId, search_key.key.ac_type); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + pACInfo->hoRenewal = VOS_FALSE; + vos_mem_zero(&pACInfo->requested_QoSInfo[tspec_pending - 1], + sizeof(sme_QosWmmTspecInfo)); + //event: EVENT_WLAN_QOS +#ifdef FEATURE_WLAN_DIAG_SUPPORT + qos.eventId = SME_QOS_DIAG_ADDTS_RSP; + qos.reasonCode = SME_QOS_DIAG_ADDTS_ADMISSION_ACCEPTED; + WLAN_VOS_DIAG_EVENT_REPORT(&qos, EVENT_WLAN_QOS); + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_qos_tspec_pkt_type, LOG_WLAN_QOS_TSPEC_C); + if(log_ptr) + { + log_ptr->delay_bound = pACInfo->curr_QoSInfo[tspec_pending - 1].delay_bound; + log_ptr->inactivity_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].inactivity_interval; + log_ptr->max_burst_size = pACInfo->curr_QoSInfo[tspec_pending - 1].max_burst_size; + log_ptr->max_service_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].max_service_interval; + log_ptr->maximum_msdu_size = pACInfo->curr_QoSInfo[tspec_pending - 1].maximum_msdu_size; + log_ptr->mean_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].mean_data_rate; + log_ptr->medium_time = pACInfo->curr_QoSInfo[tspec_pending - 1].medium_time; + log_ptr->min_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].min_data_rate; + log_ptr->min_phy_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].min_phy_rate; + log_ptr->min_service_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].min_service_interval; + log_ptr->nominal_msdu_size = pACInfo->curr_QoSInfo[tspec_pending - 1].nominal_msdu_size; + log_ptr->peak_data_rate = pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate; + log_ptr->surplus_bw_allowance = pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance; + log_ptr->suspension_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].surplus_bw_allowance; + log_ptr->suspension_interval = pACInfo->curr_QoSInfo[tspec_pending - 1].suspension_interval; + log_ptr->svc_start_time = pACInfo->curr_QoSInfo[tspec_pending - 1].svc_start_time; + log_ptr->tsinfo[0] = pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.direction << 5 | + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.tid << 1; + log_ptr->tsinfo[1] = pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.up << 11 | + pACInfo->curr_QoSInfo[tspec_pending - 1].ts_info.psb << 10; + log_ptr->tsinfo[2] = 0; + } + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); +#endif //FEATURE_WLAN_DIAG_SUPPORT +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + if (ac == SME_QOS_EDCA_AC_VO) + { + // Indicate to neighbor roam logic of the new required VO + // ac bandwidth requirement. + csrNeighborRoamIndicateVoiceBW( pMac, pACInfo->curr_QoSInfo[tspec_pending - 1].peak_data_rate, TRUE ); + } +#endif + pACInfo->tspec_pending = 0; + + sme_QosStateTransition(sessionId, ac, SME_QOS_QOS_ON); + + + (void)sme_QosProcessBufferedCmd(sessionId); + return eHAL_STATUS_SUCCESS; + +} +/*-------------------------------------------------------------------------- + \brief sme_QosAggregateParams() - Utiltity function to increament the TSPEC + params per AC. Typical usage while using flow aggregation or deletion of flows + + \param pInput_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains the + WMM TSPEC related info with which pCurrent_Tspec_Info will be updated + \param pCurrent_Tspec_Info - Pointer to sme_QosWmmTspecInfo which contains + current the WMM TSPEC related info + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAggregateParams( + sme_QosWmmTspecInfo * pInput_Tspec_Info, + sme_QosWmmTspecInfo * pCurrent_Tspec_Info, + sme_QosWmmTspecInfo * pUpdated_Tspec_Info) +{ + sme_QosWmmTspecInfo TspecInfo; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked", + __func__, __LINE__); + if(!pInput_Tspec_Info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: input is NULL, nothing to aggregate", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + if(!pCurrent_Tspec_Info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Current is NULL, can't aggregate", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(&TspecInfo, pCurrent_Tspec_Info, + sizeof(sme_QosWmmTspecInfo)); + TspecInfo.ts_info.psb = pInput_Tspec_Info->ts_info.psb; + /*------------------------------------------------------------------------- + APSD preference is only meaningful if service interval was set by app + -------------------------------------------------------------------------*/ + if(pCurrent_Tspec_Info->min_service_interval && + pInput_Tspec_Info->min_service_interval && + (pCurrent_Tspec_Info->ts_info.direction != + pInput_Tspec_Info->ts_info.direction)) + { + TspecInfo.min_service_interval = VOS_MIN( + pCurrent_Tspec_Info->min_service_interval, + pInput_Tspec_Info->min_service_interval); + } + else if(pInput_Tspec_Info->min_service_interval) + { + TspecInfo.min_service_interval = pInput_Tspec_Info->min_service_interval; + } + if(pCurrent_Tspec_Info->max_service_interval && + pInput_Tspec_Info->max_service_interval && + (pCurrent_Tspec_Info->ts_info.direction != + pInput_Tspec_Info->ts_info.direction)) + { + TspecInfo.max_service_interval = VOS_MIN( + pCurrent_Tspec_Info->max_service_interval, + pInput_Tspec_Info->max_service_interval); + } + else + { + TspecInfo.max_service_interval = pInput_Tspec_Info->max_service_interval; + } + /*------------------------------------------------------------------------- + If directions don't match, it must necessarily be both uplink and + downlink + -------------------------------------------------------------------------*/ + if(pCurrent_Tspec_Info->ts_info.direction != + pInput_Tspec_Info->ts_info.direction) + { + TspecInfo.ts_info.direction = pInput_Tspec_Info->ts_info.direction; + } + /*------------------------------------------------------------------------- + Max MSDU size : these sizes are `maxed' + -------------------------------------------------------------------------*/ + TspecInfo.maximum_msdu_size = VOS_MAX(pCurrent_Tspec_Info->maximum_msdu_size, + pInput_Tspec_Info->maximum_msdu_size); + + /*------------------------------------------------------------------------- + Inactivity interval : these sizes are `maxed' + -------------------------------------------------------------------------*/ + TspecInfo.inactivity_interval = VOS_MAX(pCurrent_Tspec_Info->inactivity_interval, + pInput_Tspec_Info->inactivity_interval); + + /*------------------------------------------------------------------------- + Delay bounds: min of all values + Check on 0: if 0, it means initial value since delay can never be 0!! + -------------------------------------------------------------------------*/ + if(pCurrent_Tspec_Info->delay_bound) + { + TspecInfo.delay_bound = VOS_MIN(pCurrent_Tspec_Info->delay_bound, + pInput_Tspec_Info->delay_bound); + } + else + { + TspecInfo.delay_bound = pInput_Tspec_Info->delay_bound; + } + TspecInfo.max_burst_size = VOS_MAX(pCurrent_Tspec_Info->max_burst_size, + pInput_Tspec_Info->max_burst_size); + + /*------------------------------------------------------------------------- + Nominal MSDU size also has a fixed bit that needs to be `handled' before + aggregation + This can be handled only if previous size is the same as new or both have + the fixed bit set + These sizes are not added: but `maxed' + -------------------------------------------------------------------------*/ + TspecInfo.nominal_msdu_size = VOS_MAX( + pCurrent_Tspec_Info->nominal_msdu_size & ~SME_QOS_16BIT_MSB, + pInput_Tspec_Info->nominal_msdu_size & ~SME_QOS_16BIT_MSB); + + if( ((pCurrent_Tspec_Info->nominal_msdu_size == 0) || + (pCurrent_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB)) && + ((pInput_Tspec_Info->nominal_msdu_size == 0) || + (pInput_Tspec_Info->nominal_msdu_size & SME_QOS_16BIT_MSB))) + { + TspecInfo.nominal_msdu_size |= SME_QOS_16BIT_MSB; + } + + /*------------------------------------------------------------------------- + Data rates: + Add up the rates for aggregation + -------------------------------------------------------------------------*/ + SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.peak_data_rate, + pInput_Tspec_Info->peak_data_rate ); + SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.min_data_rate, + pInput_Tspec_Info->min_data_rate ); + /* mean data rate = peak data rate: aggregate to be flexible on apps */ + SME_QOS_BOUNDED_U32_ADD_Y_TO_X( TspecInfo.mean_data_rate, + pInput_Tspec_Info->mean_data_rate ); + + /*------------------------------------------------------------------------- + Suspension interval : this is set to the inactivity interval since per + spec it is less than or equal to inactivity interval + This is not provided by app since we currently don't support the HCCA + mode of operation + Currently set it to 0 to avoid confusion: Cisco ESE needs ~0; spec + requires inactivity interval to be > suspension interval: this could + be tricky! + -------------------------------------------------------------------------*/ + TspecInfo.suspension_interval = 0; + /*------------------------------------------------------------------------- + Remaining parameters do not come from app as they are very WLAN + air interface specific + Set meaningful values here + -------------------------------------------------------------------------*/ + TspecInfo.medium_time = 0; /* per WMM spec */ + TspecInfo.min_phy_rate = SME_QOS_MIN_PHY_RATE; + TspecInfo.svc_start_time = 0; /* arbitrary */ + TspecInfo.surplus_bw_allowance += pInput_Tspec_Info->surplus_bw_allowance; + if(TspecInfo.surplus_bw_allowance > SME_QOS_SURPLUS_BW_ALLOWANCE) + { + TspecInfo.surplus_bw_allowance = SME_QOS_SURPLUS_BW_ALLOWANCE; + } + /* Set ack_policy to block ack even if one stream requests block ack policy */ + if((pInput_Tspec_Info->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) || + (pCurrent_Tspec_Info->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK)) + { + TspecInfo.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK; + } + + if(pInput_Tspec_Info->ts_info.burst_size_defn || pCurrent_Tspec_Info->ts_info.burst_size_defn ) + { + TspecInfo.ts_info.burst_size_defn = 1; + } + if(pUpdated_Tspec_Info) + { + vos_mem_copy(pUpdated_Tspec_Info, &TspecInfo, + sizeof(sme_QosWmmTspecInfo)); + } + else + { + vos_mem_copy(pCurrent_Tspec_Info, &TspecInfo, + sizeof(sme_QosWmmTspecInfo)); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateParams() - Utiltity function to update the TSPEC + params per AC. Typical usage while deleting flows on AC which is running + multiple flows + + \param sessionId - Session upon which the TSPEC is being updated + \param ac - Enumeration of the various EDCA Access Categories. + \param tspec_mask - on which tspec per AC, the update is requested + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosUpdateParams(v_U8_t sessionId, + sme_QosEdcaAcType ac, + v_U8_t tspec_mask, + sme_QosWmmTspecInfo * pTspec_Info) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosWmmTspecInfo Tspec_Info; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: invoked on session %d for AC %d TSPEC %d", + __func__, __LINE__, + sessionId, ac, tspec_mask); + if(!pTspec_Info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: output is NULL, can't aggregate", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(&Tspec_Info, sizeof(sme_QosWmmTspecInfo)); + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, nothing to update", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + //init the TS info field + Tspec_Info.ts_info.up = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.up; + Tspec_Info.ts_info.psb = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.psb; + Tspec_Info.ts_info.tid = pACInfo->curr_QoSInfo[tspec_mask - 1].ts_info.tid; + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if((sessionId == flow_info->sessionId) && + (ac == flow_info->ac_type) && + (tspec_mask == flow_info->tspec_mask)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow %d matches", + __func__, __LINE__, + flow_info->QosFlowID); + + if((SME_QOS_REASON_RELEASE == flow_info->reason ) || + (SME_QOS_REASON_MODIFY == flow_info->reason)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Skipping Flow %d as it is marked " + "for release/modify", + __func__, __LINE__, + flow_info->QosFlowID); + } + else if(!HAL_STATUS_SUCCESS(sme_QosAggregateParams(&flow_info->QoSInfo, + &Tspec_Info, + NULL))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosAggregateParams() failed", + __func__, __LINE__); + } + } + pEntry = pNextEntry; + } + // return the aggregate + *pTspec_Info = Tspec_Info; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosAcToUp() - Utiltity function to map an AC to UP + Note: there is a quantization loss here because 4 ACs are mapped to 8 UPs + Mapping is done for consistency + \param ac - Enumeration of the various EDCA Access Categories. + \return an User Priority + + \sa + + --------------------------------------------------------------------------*/ +sme_QosWmmUpType sme_QosAcToUp(sme_QosEdcaAcType ac) +{ + sme_QosWmmUpType up = SME_QOS_WMM_UP_MAX; + if(ac >= 0 && ac < SME_QOS_EDCA_AC_MAX) + { + up = sme_QosACtoUPMap[ac]; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: ac = %d up = %d returned", + __func__, __LINE__, ac, up); + return up; +} +/*-------------------------------------------------------------------------- + \brief sme_QosUpToAc() - Utiltity function to map an UP to AC + \param up - Enumeration of the various User priorities (UP). + \return an Access Category + + \sa + + --------------------------------------------------------------------------*/ +sme_QosEdcaAcType sme_QosUpToAc(sme_QosWmmUpType up) +{ + sme_QosEdcaAcType ac = SME_QOS_EDCA_AC_MAX; + if(up >= 0 && up < SME_QOS_WMM_UP_MAX) + { + ac = sme_QosUPtoACMap[up]; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: up = %d ac = %d returned", + __func__, __LINE__, up, ac); + return ac; +} +/*-------------------------------------------------------------------------- + \brief sme_QosStateTransition() - The state transition function per AC. We + save the previous state also. + \param sessionId - Session upon which the state machine is running + \param ac - Enumeration of the various EDCA Access Categories. + \param new_state - The state FSM is moving to. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +static void sme_QosStateTransition(v_U8_t sessionId, + sme_QosEdcaAcType ac, + sme_QosStates new_state) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + pACInfo->prev_state = pACInfo->curr_state; + pACInfo->curr_state = new_state; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d new state=%d, old state=%d, for AC=%d", + __func__, __LINE__, + sessionId, pACInfo->curr_state, pACInfo->prev_state, ac ); +} +/*-------------------------------------------------------------------------- + \brief sme_QosFindInFlowList() - Utility function to find an flow entry from + the flow_list. + \param search_key - We can either use the flowID or the ac type to find the + entry in the flow list. + A bitmap in sme_QosSearchInfo tells which key to use. Starting from LSB, + bit 0 - Flow ID + bit 1 - AC type + \return the pointer to the entry in the link list + + \sa + + --------------------------------------------------------------------------*/ +tListElem *sme_QosFindInFlowList(sme_QosSearchInfo search_key) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return NULL; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if((search_key.sessionId == flow_info->sessionId) || + (search_key.sessionId == SME_QOS_SEARCH_SESSION_ID_ANY)) + { + if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_1) + { + if(search_key.key.QosFlowID == flow_info->QosFlowID) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on flowID, ending search", + __func__, __LINE__); + break; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_2) + { + if(search_key.key.ac_type == flow_info->ac_type) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on ac, ending search", + __func__, __LINE__); + break; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_3) + { + if(search_key.key.reason == flow_info->reason) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on reason, ending search", + __func__, __LINE__); + break; + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_4) + { + if((search_key.key.ac_type == flow_info->ac_type) && + (search_key.direction == flow_info->QoSInfo.ts_info.direction)) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on reason, ending search", + __func__, __LINE__); + + break; + } + } + } + pEntry = pNextEntry; + } + return pEntry; +} +/*-------------------------------------------------------------------------- + \brief sme_QosFindAllInFlowList() - Utility function to find an flow entry + from the flow_list & act on it. + \param search_key - We can either use the flowID or the ac type to find the + entry in the flow list. + A bitmap in sme_QosSearchInfo tells which key to use. Starting from LSB, + bit 0 - Flow ID + bit 1 - AC type + \param fnp - function pointer specifying the action type for the entry found + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosFindAllInFlowList(tpAniSirGlobal pMac, + sme_QosSearchInfo search_key, + sme_QosProcessSearchEntry fnp) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosSessionInfo *pSession; + sme_QosFlowInfoEntry *flow_info = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + if((search_key.sessionId == flow_info->sessionId) || + (search_key.sessionId == SME_QOS_SEARCH_SESSION_ID_ANY)) + { + if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_1) + { + if(search_key.key.QosFlowID == flow_info->QosFlowID) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on flowID, ending search", + __func__, __LINE__); + status = fnp(pMac, pEntry); + if(eHAL_STATUS_FAILURE == status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Failed to process entry", + __func__, __LINE__); + break; + } + } + } + else if(search_key.index & SME_QOS_SEARCH_KEY_INDEX_2) + { + if(search_key.key.ac_type == flow_info->ac_type) + { + //msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: match found on ac, ending search", + __func__, __LINE__); + flow_info->hoRenewal = pSession->ac_info[flow_info->ac_type].hoRenewal; + status = fnp(pMac, pEntry); + if(eHAL_STATUS_FAILURE == status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Failed to process entry", + __func__, __LINE__); + break; + } + } + } + } + pEntry = pNextEntry; + } + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_QosIsACM() - Utility function to check if a particular AC + mandates Admission Control. + \param ac - Enumeration of the various EDCA Access Categories. + + \return VOS_TRUE if the AC mandates Admission Control + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosIsACM(tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + sme_QosEdcaAcType ac, tDot11fBeaconIEs *pIes) +{ + v_BOOL_t ret_val = VOS_FALSE; + tDot11fBeaconIEs *pIesLocal; + if(!pSirBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pSirBssDesc is NULL", + __func__, __LINE__); + return VOS_FALSE; + } + + if (NULL != pIes) + { + /* IEs were provided so use them locally */ + pIesLocal = pIes; + } + else + { + /* IEs were not provided so parse them ourselves */ + if (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: csrGetParsedBssDescriptionIEs() failed", + __func__, __LINE__); + return VOS_FALSE; + } + + /* if success then pIesLocal was allocated */ + } + + if(CSR_IS_QOS_BSS(pIesLocal)) + { + switch(ac) + { + case SME_QOS_EDCA_AC_BE: + if(pIesLocal->WMMParams.acbe_acm) ret_val = VOS_TRUE; + break; + case SME_QOS_EDCA_AC_BK: + if(pIesLocal->WMMParams.acbk_acm) ret_val = VOS_TRUE; + break; + case SME_QOS_EDCA_AC_VI: + if(pIesLocal->WMMParams.acvi_acm) ret_val = VOS_TRUE; + break; + case SME_QOS_EDCA_AC_VO: + if(pIesLocal->WMMParams.acvo_acm) ret_val = VOS_TRUE; + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: unknown AC = %d", + __func__, __LINE__, ac); + //Assert + VOS_ASSERT(0); + break; + } + }//IS_QOS_BSS + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: ACM = %d for AC = %d", + __func__, __LINE__, ret_val, ac ); + if (NULL == pIes) + { + /* IEs were allocated locally so free them */ + vos_mem_free(pIesLocal); + } + return ret_val; +} +/*-------------------------------------------------------------------------- + \brief sme_QosBufferExistingFlows() - Utility function to buffer the existing + flows in flow_list, so that we can renew them after handoff is done. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosBufferExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosSessionInfo *pSession; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosCmdInfo cmd; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow List empty, nothing to buffer", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if (flow_info->sessionId == sessionId) + { + if((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason )|| + (SME_QOS_REASON_SETUP == flow_info->reason )) + { + cmd.command = SME_QOS_SETUP_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.setupCmdInfo.HDDcontext = flow_info->HDDcontext; + cmd.u.setupCmdInfo.QoSInfo = flow_info->QoSInfo; + cmd.u.setupCmdInfo.QoSCallback = flow_info->QoSCallback; + cmd.u.setupCmdInfo.UPType = SME_QOS_WMM_UP_MAX;//shouldn't be needed + cmd.u.setupCmdInfo.QosFlowID = flow_info->QosFlowID; + if(SME_QOS_REASON_SETUP == flow_info->reason ) + { + cmd.u.setupCmdInfo.hoRenewal = VOS_FALSE; + } + else + { + cmd.u.setupCmdInfo.hoRenewal = VOS_TRUE;//TODO: might need this for modify + } + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the setup request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: buffered a setup request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + } + else if(SME_QOS_REASON_RELEASE == flow_info->reason ) + { + cmd.command = SME_QOS_RELEASE_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.releaseCmdInfo.QosFlowID = flow_info->QosFlowID; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the release request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: buffered a release request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + } + else if(SME_QOS_REASON_MODIFY_PENDING == flow_info->reason) + { + cmd.command = SME_QOS_MODIFY_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.modifyCmdInfo.QosFlowID = flow_info->QosFlowID; + cmd.u.modifyCmdInfo.QoSInfo = flow_info->QoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the modify request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: buffered a modify request for " + "flow %d in handoff state", + __func__, __LINE__, + flow_info->QosFlowID); + } + } + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting original entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + vos_mem_free(flow_info); + } + pEntry = pNextEntry; + } + pSession = &sme_QosCb.sessionInfo[sessionId]; + pSession->uapsdAlreadyRequested = VOS_FALSE; + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDeleteExistingFlows() - Utility function to Delete the existing + flows in flow_list, if we lost connectivity. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosDeleteExistingFlows(tpAniSirGlobal pMac, + v_U8_t sessionId) +{ + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_TRUE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: Flow List empty, nothing to delete", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_TRUE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + if (flow_info->sessionId == sessionId) + { + if((SME_QOS_REASON_REQ_SUCCESS == flow_info->reason )|| + (SME_QOS_REASON_SETUP == flow_info->reason )|| + (SME_QOS_REASON_RELEASE == flow_info->reason )|| + (SME_QOS_REASON_MODIFY == flow_info->reason )) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + NULL, + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + flow_info->QosFlowID); + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + //delete the entry from Flow List + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + vos_mem_free(flow_info); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosBufferCmd() - Utility function to buffer a request (setup/modify/ + release) from client while processing another one on the same AC. + \param pcmd - a pointer to the cmd structure to be saved inside the buffered + cmd link list + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosBufferCmd(sme_QosCmdInfo *pcmd, v_BOOL_t insert_head) +{ + sme_QosSessionInfo *pSession; + sme_QosCmdInfoEntry * pentry = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked", + __func__, __LINE__); + pentry = (sme_QosCmdInfoEntry *) vos_mem_malloc(sizeof(sme_QosCmdInfoEntry)); + if (!pentry) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Memory allocation failure", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + // copy the entire CmdInfo + pentry->cmdInfo = *pcmd; + + pSession = &sme_QosCb.sessionInfo[pcmd->sessionId]; + if(insert_head) + { + csrLLInsertHead(&pSession->bufferedCommandList, &pentry->link, VOS_TRUE); + } + else + { + csrLLInsertTail(&pSession->bufferedCommandList, &pentry->link, VOS_TRUE); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessBufferedCmd() - Utility function to process a buffered + request (setup/modify/release) initially came from the client. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosProcessBufferedCmd(v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosCmdInfoEntry *pcmd = NULL; + tListElem *pEntry= NULL; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d", + __func__, __LINE__, + sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + if(!csrLLIsListEmpty( &pSession->bufferedCommandList, VOS_FALSE )) + { + pEntry = csrLLRemoveHead( &pSession->bufferedCommandList, VOS_TRUE ); + if(!pEntry) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: no more buffered commands on session %d", + __func__, __LINE__, + sessionId); + pSession->readyForPowerSave = VOS_TRUE; + return eHAL_STATUS_FAILURE; + } + pcmd = GET_BASE_ADDR( pEntry, sme_QosCmdInfoEntry, link ); + switch(pcmd->cmdInfo.command) + { + case SME_QOS_SETUP_REQ: + hdd_status = sme_QosInternalSetupReq(pcmd->cmdInfo.pMac, + pcmd->cmdInfo.sessionId, + &pcmd->cmdInfo.u.setupCmdInfo.QoSInfo, + pcmd->cmdInfo.u.setupCmdInfo.QoSCallback, + pcmd->cmdInfo.u.setupCmdInfo.HDDcontext, + pcmd->cmdInfo.u.setupCmdInfo.UPType, + pcmd->cmdInfo.u.setupCmdInfo.QosFlowID, + VOS_TRUE, + pcmd->cmdInfo.u.setupCmdInfo.hoRenewal); + if(SME_QOS_STATUS_SETUP_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosInternalSetupReq failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + case SME_QOS_RELEASE_REQ: + hdd_status = sme_QosInternalReleaseReq(pcmd->cmdInfo.pMac, + pcmd->cmdInfo.u.releaseCmdInfo.QosFlowID, + VOS_TRUE); + if(SME_QOS_STATUS_RELEASE_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosInternalReleaseReq failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + case SME_QOS_MODIFY_REQ: + hdd_status = sme_QosInternalModifyReq(pcmd->cmdInfo.pMac, + &pcmd->cmdInfo.u.modifyCmdInfo.QoSInfo, + pcmd->cmdInfo.u.modifyCmdInfo.QosFlowID, + VOS_TRUE); + if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosInternalModifyReq failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + case SME_QOS_RESEND_REQ: + hdd_status = sme_QosReRequestAddTS(pcmd->cmdInfo.pMac, + pcmd->cmdInfo.sessionId, + &pcmd->cmdInfo.u.resendCmdInfo.QoSInfo, + pcmd->cmdInfo.u.resendCmdInfo.ac, + pcmd->cmdInfo.u.resendCmdInfo.tspecMask); + if(SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP == hdd_status) + { + //Err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: sme_QosReRequestAddTS failed on session %d", + __func__, __LINE__, + sessionId); + halStatus = eHAL_STATUS_FAILURE; + } + break; + default: + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unknown cmd = %d", + __func__, __LINE__, + sessionId, pcmd->cmdInfo.command); + //ASSERT + VOS_ASSERT(0); + break; + } + // buffered command has been processed, reclaim the memory + vos_mem_free(pcmd); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: cmd buffer empty", + __func__, __LINE__); + pSession->readyForPowerSave = VOS_TRUE; + } + return halStatus; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDeleteBufferedRequests() - Utility function to Delete the buffered + requests in the buffered_cmd_list, if we lost connectivity. + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +static eHalStatus sme_QosDeleteBufferedRequests(tpAniSirGlobal pMac, + v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosCmdInfoEntry *pcmd = NULL; + tListElem *pEntry= NULL, *pNextEntry = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d", + __func__, __LINE__, sessionId); + pSession = &sme_QosCb.sessionInfo[sessionId]; + pEntry = csrLLPeekHead( &pSession->bufferedCommandList, VOS_TRUE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: %d: Buffered List empty, nothing to delete on session %d", + __func__, __LINE__, + sessionId); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &pSession->bufferedCommandList, pEntry, VOS_TRUE ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: deleting entry from buffered List", + __func__, __LINE__); + //delete the entry from Flow List + csrLLRemoveEntry(&pSession->bufferedCommandList, pEntry, VOS_TRUE ); + // reclaim the memory + pcmd = GET_BASE_ADDR( pEntry, sme_QosCmdInfoEntry, link ); + vos_mem_free(pcmd); + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosSaveAssocInfo() - Utility function to save the assoc info in the + CB like BSS descritor of the AP, the profile that HDD sent down with the + connect request, while CSR notifies for assoc/reassoc success. + \param pAssoc_info - pointer to the assoc structure to store the BSS descritor + of the AP, the profile that HDD sent down with the + connect request + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSaveAssocInfo(sme_QosSessionInfo *pSession, sme_QosAssocInfo *pAssoc_info) +{ + tSirBssDescription *pBssDesc = NULL; + v_U32_t bssLen = 0; + if(NULL == pAssoc_info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: pAssoc_info is NULL", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + //clean up the assoc info if already set + if(pSession->assocInfo.pBssDesc) + { + vos_mem_free(pSession->assocInfo.pBssDesc); + pSession->assocInfo.pBssDesc = NULL; + } + bssLen = pAssoc_info->pBssDesc->length + + sizeof(pAssoc_info->pBssDesc->length); + //save the bss Descriptor + pBssDesc = (tSirBssDescription *)vos_mem_malloc(bssLen); + if (!pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't allocate memory for the bss Descriptor", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pBssDesc, pAssoc_info->pBssDesc, bssLen); + pSession->assocInfo.pBssDesc = pBssDesc; + //save the apsd info from assoc + if(pAssoc_info->pProfile) + { + pSession->apsdMask |= pAssoc_info->pProfile->uapsd_mask; + } + // [TODO] Do we need to update the global APSD bitmap? + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosSetupFnp() - Utility function (pointer) to notify other entries + in FLOW list on the same AC that qos params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosSetupFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + sme_QosEdcaAcType ac; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + if(SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) + { + //notify HDD, only the other Flows running on the AC + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + hdd_status, + flow_info->QosFlowID); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Entry with flowID = %d getting notified", + __func__, __LINE__, + flow_info->QosFlowID); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosModificationNotifyFnp() - Utility function (pointer) to notify + other entries in FLOW list on the same AC that qos params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosModificationNotifyFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + sme_QosEdcaAcType ac; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + if(SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) + { + //notify HDD, only the other Flows running on the AC + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[flow_info->tspec_mask - 1], + hdd_status, + flow_info->QosFlowID); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Entry with flowID = %d getting notified", + __func__, __LINE__, + flow_info->QosFlowID); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosModifyFnp() - Utility function (pointer) to delete the origianl + entry in FLOW list & add the modified one + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosModifyFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosFlowInfoEntry *flow_info = NULL; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + switch(flow_info->reason) + { + case SME_QOS_REASON_MODIFY_PENDING: + //set the proper reason code for the new (with modified params) entry + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + break; + case SME_QOS_REASON_MODIFY: + //delete the original entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting original entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + break; + default: + break; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosDelTsIndFnp() - Utility function (pointer) to find all Flows on + the perticular AC & delete them, also send HDD indication through the callback + it registered per request + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosDelTsIndFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + sme_QosEdcaAcType ac; + eHalStatus lock_status = eHAL_STATUS_FAILURE; + sme_QosStatusType status; + + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + //delete the entry from Flow List + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + pACInfo->relTrig = SME_QOS_RELEASE_BY_AP; + + lock_status = sme_AcquireGlobalLock( &pMac->sme ); + if ( !HAL_STATUS_SUCCESS( lock_status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Unable to obtain lock", + __func__, __LINE__); + return SME_QOS_STATUS_RELEASE_FAILURE_RSP; + } + //Call the internal function for QoS release, adding a layer of abstraction + status = sme_QosInternalReleaseReq(pMac, flow_info->QosFlowID, VOS_FALSE); + sme_ReleaseGlobalLock( &pMac->sme ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: QoS Release return status on Flow %d is %d", + __func__, __LINE__, + flow_info->QosFlowID, status); + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosReassocSuccessEvFnp() - Utility function (pointer) to notify HDD + the success for the requested flow & notify all the other flows running on the + same AC that QoS params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosReassocSuccessEvFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + v_BOOL_t delete_entry = VOS_FALSE; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + sme_QosEdcaAcType ac; + eHalStatus pmc_status = eHAL_STATUS_FAILURE; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR(pEntry, sme_QosFlowInfoEntry, link); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + switch(flow_info->reason) + { + case SME_QOS_REASON_SETUP: + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND; + delete_entry = VOS_FALSE; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + //check for the case where we had to do reassoc to reset the apsd bit + //for the ac - release or modify scenario + if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb) + { + // notify PMC as App is looking for APSD. If we already requested + // then we don't need to do anything. + if(!pSession->uapsdAlreadyRequested) + { + // this is the first flow to detect we need PMC in UAPSD mode + + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED; + //we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + // let other flows know PMC has been notified + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + break; + case SME_QOS_REASON_RELEASE: + pACInfo->num_flows[SME_QOS_TSPEC_INDEX_0]--; + // fall through + case SME_QOS_REASON_MODIFY: + delete_entry = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY_PENDING: + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND; + delete_entry = VOS_FALSE; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + if(pACInfo->requested_QoSInfo[SME_QOS_TSPEC_INDEX_0].ts_info.psb) + { + + if(!pSession->uapsdAlreadyRequested) + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED; + // we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + break; + case SME_QOS_REASON_REQ_SUCCESS: + hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + // fall through + default: + delete_entry = VOS_FALSE; + break; + } + if(!delete_entry) + { + if(!flow_info->hoRenewal) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[SME_QOS_TSPEC_INDEX_0], + hdd_status, + flow_info->QosFlowID); + } + else + { + flow_info->hoRenewal = VOS_FALSE; + } + } + else + { + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + } + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosAddTsFailureFnp() - Utility function (pointer), + if the Addts request was for for an flow setup request, delete the entry from + Flow list & notify HDD + if the Addts request was for downgrading of QoS params because of an flow + release requested on the AC, delete the entry from Flow list & notify HDD + if the Addts request was for change of QoS params because of an flow + modification requested on the AC, delete the new entry from Flow list & notify + HDD + + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAddTsFailureFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + v_BOOL_t inform_hdd = VOS_FALSE; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + sme_QosEdcaAcType ac; + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + switch(flow_info->reason) + { + case SME_QOS_REASON_SETUP: + hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + inform_hdd = VOS_TRUE; + break; + case SME_QOS_REASON_RELEASE: + hdd_status = SME_QOS_STATUS_RELEASE_FAILURE_RSP; + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + inform_hdd = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY_PENDING: + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + inform_hdd = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY: + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + case SME_QOS_REASON_REQ_SUCCESS: + if(flow_info->hoRenewal == VOS_TRUE) + { + // This case will occur when re-requesting AddTs during BT Coex + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: ac:%d num_flows:%d",__func__, __LINE__, + ac,pACInfo->num_flows[pACInfo->tspec_pending - 1]); + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + inform_hdd = VOS_TRUE; + break; + } + default: + inform_hdd = VOS_FALSE; + break; + } + if(inform_hdd) + { + //notify HDD, only the requested Flow, other Flows running on the AC stay + // intact + if(!flow_info->hoRenewal) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + hdd_status, + flow_info->QosFlowID); + } + else + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + SME_QOS_STATUS_RELEASE_QOS_LOST_IND, + flow_info->QosFlowID); + } + //delete the entry from Flow List + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosAddTsSuccessFnp() - Utility function (pointer), + if the Addts request was for for an flow setup request, notify HDD for success + for the flow & notify all the other flows running on the same AC that QoS + params got modified + if the Addts request was for downgrading of QoS params because of an flow + release requested on the AC, delete the entry from Flow list & notify HDD + if the Addts request was for change of QoS params because of an flow + modification requested on the AC, delete the old entry from Flow list & notify + HDD for success for the flow & notify all the other flows running on the same + AC that QoS params got modified + \param pMac - Pointer to the global MAC parameter structure. + \param pEntry - Pointer to an entry in the flow_list(i.e. tListElem structure) + + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosAddTsSuccessFnp(tpAniSirGlobal pMac, tListElem *pEntry) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosFlowInfoEntry *flow_info = NULL; + v_BOOL_t inform_hdd = VOS_FALSE; + v_BOOL_t delete_entry = VOS_FALSE; + sme_QosStatusType hdd_status = SME_QOS_STATUS_SETUP_FAILURE_RSP; + sme_QosEdcaAcType ac; + eHalStatus pmc_status = eHAL_STATUS_FAILURE; + tCsrRoamModifyProfileFields modifyProfileFields; + + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Entry is NULL", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + ac = flow_info->ac_type; + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + pACInfo = &pSession->ac_info[ac]; + if(flow_info->tspec_mask != pACInfo->tspec_pending) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: No need to notify the HDD, the ADDTS " + "success is not for index = %d of the AC = %d", + __func__, __LINE__, + flow_info->tspec_mask, ac); + return eHAL_STATUS_SUCCESS; + } + switch(flow_info->reason) + { + case SME_QOS_REASON_SETUP: + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + delete_entry = VOS_FALSE; + inform_hdd = VOS_TRUE; + // check if App is looking for APSD + if(pACInfo->requested_QoSInfo[pACInfo->tspec_pending - 1].ts_info.psb) + { + // notify PMC as App is looking for APSD. If we already requested + // then we don't need to do anything + if(!pSession->uapsdAlreadyRequested) + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_SET_FAILED; + // we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + // let other flows know PMC has been notified + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + break; + case SME_QOS_REASON_RELEASE: + pACInfo->num_flows[pACInfo->tspec_pending - 1]--; + hdd_status = SME_QOS_STATUS_RELEASE_SUCCESS_RSP; + inform_hdd = VOS_TRUE; + delete_entry = VOS_TRUE; + break; + case SME_QOS_REASON_MODIFY: + delete_entry = VOS_TRUE; + inform_hdd = VOS_FALSE; + break; + case SME_QOS_REASON_MODIFY_PENDING: + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND; + delete_entry = VOS_FALSE; + flow_info->reason = SME_QOS_REASON_REQ_SUCCESS; + inform_hdd = VOS_TRUE; + //notify PMC if App is looking for APSD + if(pACInfo->requested_QoSInfo[pACInfo->tspec_pending - 1].ts_info.psb) + { + // notify PMC as App is looking for APSD. If we already requested + // then we don't need to do anything. + if(!pSession->uapsdAlreadyRequested) + { + // this is the first flow to detect we need PMC in UAPSD mode + pmc_status = pmcStartUapsd(pMac, + sme_QosPmcStartUapsdCallback, + pSession); + // if PMC doesn't return success right away means it is yet to put + // the module in BMPS state & later to UAPSD state + if(eHAL_STATUS_FAILURE == pmc_status) + { + hdd_status = SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_IND_APSD_SET_FAILED; + // we need to always notify this case + flow_info->hoRenewal = VOS_FALSE; + } + else if(eHAL_STATUS_PMC_PENDING == pmc_status) + { + // let other flows know PMC has been notified + pSession->uapsdAlreadyRequested = VOS_TRUE; + } + // for any other pmc status we declare success + } + } + else + { + if((pACInfo->num_flows[flow_info->tspec_mask - 1] == 1) && + (SME_QOS_TSPEC_MASK_BIT_1_2_SET != pACInfo->tspec_mask_status)) + { + // this is the only TSPEC active on this AC + // so indicate that we no longer require APSD + pSession->apsdMask &= ~(1 << (SME_QOS_EDCA_AC_VO - ac)); + //Also update modifyProfileFields.uapsd_mask in CSR for consistency + csrGetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + modifyProfileFields.uapsd_mask = pSession->apsdMask; + csrSetModifyProfileFields(pMac, flow_info->sessionId, &modifyProfileFields); + if(!pSession->apsdMask) + { + // this session no longer needs UAPSD + // do any sessions still require UAPSD? + if (!sme_QosIsUapsdActive()) + { + // No sessions require UAPSD so turn it off + // (really don't care when PMC stops it) + (void)pmcStopUapsd(pMac); + } + } + } + } + break; + case SME_QOS_REASON_REQ_SUCCESS: + hdd_status = SME_QOS_STATUS_SETUP_MODIFIED_IND; + inform_hdd = VOS_TRUE; + default: + delete_entry = VOS_FALSE; + break; + } + if(inform_hdd) + { + if(!flow_info->hoRenewal) + { + + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + hdd_status, + flow_info->QosFlowID); + } + else + { + //For downgrading purpose Hdd set WmmTspecValid to false during roaming + //So need to set that flag we need to call the hdd in successful case. + if(hdd_status == SME_QOS_STATUS_SETUP_SUCCESS_IND) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s calling hdd_wmm_smecallback during roaming for ac = %d", __func__, ac); + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1], + hdd_status, + flow_info->QosFlowID + ); + } + flow_info->hoRenewal = VOS_FALSE; + } + } + + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + if (pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.up == SME_QOS_WMM_UP_VO || + pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.up == SME_QOS_WMM_UP_NC) + { + vos_record_roam_event(e_SME_VO_ADDTS_RSP, NULL, 0); + } + + if (pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.up == SME_QOS_WMM_UP_VI || + pACInfo->curr_QoSInfo[pACInfo->tspec_pending - 1].ts_info.up == SME_QOS_WMM_UP_CL) + { + vos_record_roam_event(e_SME_VI_ADDTS_RSP, NULL, 0); + } + } + + if(delete_entry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Deleting entry at %p with flowID %d", + __func__, __LINE__, + flow_info, flow_info->QosFlowID); + //delete the entry from Flow List + csrLLRemoveEntry(&sme_QosCb.flow_list, pEntry, VOS_TRUE ); + // reclaim the memory + vos_mem_free(flow_info); + } + + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosIsRspPending() - Utility function to check if we are waiting + for an AddTS or reassoc response on some AC other than the given AC + + \param sessionId - Session we are interted in + \param ac - Enumeration of the various EDCA Access Categories. + + \return boolean + TRUE - Response is pending on an AC + + \sa + + --------------------------------------------------------------------------*/ +static v_BOOL_t sme_QosIsRspPending(v_U8_t sessionId, sme_QosEdcaAcType ac) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType acIndex; + v_BOOL_t status = VOS_FALSE; + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(acIndex = SME_QOS_EDCA_AC_BE; acIndex < SME_QOS_EDCA_AC_MAX; acIndex++) + { + if(acIndex == ac) + { + continue; + } + pACInfo = &pSession->ac_info[acIndex]; + if((pACInfo->tspec_pending) || (pACInfo->reassoc_pending)) + { + status = VOS_TRUE; + break; + } + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosUpdateHandOff() - Function which can be called to update + Hand-off state of SME QoS Session + \param sessionId - session id + \param updateHandOff - value True/False to update the handoff flag + + \sa + +-------------------------------------------------------------------------*/ +void sme_QosUpdateHandOff(v_U8_t sessionId, + v_BOOL_t updateHandOff) +{ + sme_QosSessionInfo *pSession; + pSession = &sme_QosCb.sessionInfo[sessionId]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s: %d: handoffRequested %d updateHandOff %d", + __func__, __LINE__,pSession->handoffRequested, + updateHandOff); + + pSession->handoffRequested = updateHandOff; + +} + +/*-------------------------------------------------------------------------- + \brief sme_QosIsUapsdActive() - Function which can be called to determine + if any sessions require PMC to be in U-APSD mode. + \return boolean + + Returns true if at least one session required PMC to be in U-APSD mode + Returns false if no sessions require PMC to be in U-APSD mode + + \sa + + --------------------------------------------------------------------------*/ +static v_BOOL_t sme_QosIsUapsdActive(void) +{ + sme_QosSessionInfo *pSession; + v_U8_t sessionId; + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if ((pSession->sessionActive) && (pSession->apsdMask)) + { + return VOS_TRUE; + } + } + // no active sessions have U-APSD active + return VOS_FALSE; +} +/*-------------------------------------------------------------------------- + \brief sme_QosPmcFullPowerCallback() - Callback function registered with PMC + to notify SME-QoS when it puts the chip into full power + + \param callbackContext - The context passed to PMC during pmcRequestFullPower + call. + \param status - eHalStatus returned by PMC. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_QosPmcFullPowerCallback(void *callbackContext, eHalStatus status) +{ + sme_QosSessionInfo *pSession = callbackContext; + if(HAL_STATUS_SUCCESS(status)) + { + (void)sme_QosProcessBufferedCmd(pSession->sessionId); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: PMC failed to put the chip in Full power", + __func__, __LINE__); + //ASSERT + VOS_ASSERT(0); + } +} + +/*-------------------------------------------------------------------------- + \brief sme_QosPmcStartUAPSDCallback() - Callback function registered with PMC + to notify SME-QoS when it puts the chip into UAPSD mode + + \param callbackContext - The context passed to PMC during pmcStartUapsd call. + \param status - eHalStatus returned by PMC. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_QosPmcStartUapsdCallback(void *callbackContext, eHalStatus status) +{ + sme_QosSessionInfo *pSession = callbackContext; + // NOTE WELL + // + // In the orignal QoS design the TL module was responsible for + // the generation of trigger frames. When that design was in + // use, we had to queue up any flows which were waiting for PMC + // since we didn't want to notify HDD until PMC had changed to + // UAPSD state. Otherwise HDD would provide TL with the trigger + // frame parameters, and TL would start trigger frame generation + // before PMC was ready. The flows were queued in various places + // throughout this module, and they were dequeued here following + // a successful transition to the UAPSD state by PMC. + // + // In the current QoS design the Firmware is responsible for the + // generation of trigger frames, but the parameters are still + // provided by TL via HDD. The Firmware will be notified of the + // change to UAPSD state directly by PMC, at which time it will be + // responsible for the generation of trigger frames. Therefore + // where we used to queue up flows waiting for PMC to transition + // to the UAPSD state, we now always transition directly to the + // "success" state so that HDD will immediately provide the trigger + // frame parameters to TL, who will in turn plumb them down to the + // Firmware. That way the Firmware will have the trigger frame + // parameters when it needs them + // just note that there is no longer an outstanding request + pSession->uapsdAlreadyRequested = VOS_FALSE; +} +/*-------------------------------------------------------------------------- + \brief sme_QosPmcCheckRoutine() - Function registered with PMC to check with + SME-QoS whenever the device is about to enter one of the power + save modes. PMC runs a poll with all the registered modules if device can + enter powersave mode or remain in full power + + \param callbackContext - The context passed to PMC during registration through + pmcRegisterPowerSaveCheck. + \return boolean + + SME-QOS returns PMC true or false respectively if it wants to vote for + entering power save or not + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosPmcCheckRoutine(void *callbackContext) +{ + sme_QosSessionInfo *pSession; + v_U8_t sessionId; + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if ((pSession->sessionActive) && + (!pSession->readyForPowerSave)) + { + return VOS_FALSE; + } + } + // all active sessions have voted for powersave + return VOS_TRUE; +} +/*-------------------------------------------------------------------------- + \brief sme_QosPmcDeviceStateUpdateInd() - Callback function registered with + PMC to notify SME-QoS when it changes the power state + + \param callbackContext - The context passed to PMC during registration + through pmcRegisterDeviceStateUpdateInd. + \param pmcState - Current power state that PMC moved into. + + \return None + + \sa + + --------------------------------------------------------------------------*/ +void sme_QosPmcDeviceStateUpdateInd(void *callbackContext, tPmcState pmcState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext ); + //check all the entries in Flow list for non-zero service interval, which will + //tell us if we need to notify HDD when PMC is out of UAPSD mode or going + // back to UAPSD mode + switch(pmcState) + { + case FULL_POWER: + status = sme_QosProcessOutOfUapsdMode(pMac); + break; + case UAPSD: + status = sme_QosProcessIntoUapsdMode(pMac); + break; + default: + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: nothing to process in PMC state %s (%d)", + __func__, __LINE__, + sme_PmcStatetoString(pmcState), pmcState); + } + if(!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: ignoring Device(PMC) state change to %s (%d)", + __func__, __LINE__, + sme_PmcStatetoString(pmcState), pmcState); + } + +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessOutOfUapsdMode() - Function to notify HDD when PMC + notifies SME-QoS that it moved out of UAPSD mode to FULL power + + \param pMac - Pointer to the global MAC parameter structure. + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessOutOfUapsdMode(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + //only notify the flows which already successfully setup UAPSD + if((flow_info->QoSInfo.max_service_interval || + flow_info->QoSInfo.min_service_interval) && + (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason)) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pSession->ac_info[flow_info->ac_type].curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_OUT_OF_APSD_POWER_MODE_IND, + flow_info->QosFlowID); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + \brief sme_QosProcessIntoUapsdMode() - Function to notify HDD when PMC + notifies SME-QoS that it is moving into UAPSD mode + + \param pMac - Pointer to the global MAC parameter structure. + \return eHalStatus + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_QosProcessIntoUapsdMode(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession; + tListElem *pEntry= NULL, *pNextEntry = NULL; + sme_QosFlowInfoEntry *flow_info = NULL; + + pEntry = csrLLPeekHead( &sme_QosCb.flow_list, VOS_FALSE ); + if(!pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Flow List empty, can't search", + __func__, __LINE__); + return eHAL_STATUS_FAILURE; + } + while( pEntry ) + { + pNextEntry = csrLLNext( &sme_QosCb.flow_list, pEntry, VOS_FALSE ); + flow_info = GET_BASE_ADDR( pEntry, sme_QosFlowInfoEntry, link ); + pSession = &sme_QosCb.sessionInfo[flow_info->sessionId]; + //only notify the flows which already successfully setup UAPSD + if( (flow_info->QoSInfo.ts_info.psb) && + (SME_QOS_REASON_REQ_SUCCESS == flow_info->reason) ) + { + flow_info->QoSCallback(pMac, flow_info->HDDcontext, + &pSession->ac_info[flow_info->ac_type].curr_QoSInfo[flow_info->tspec_mask - 1], + SME_QOS_STATUS_INTO_APSD_POWER_MODE_IND, + flow_info->QosFlowID); + } + pEntry = pNextEntry; + } + return eHAL_STATUS_SUCCESS; +} + +void sme_QosCleanupCtrlBlkForHandoff(tpAniSirGlobal pMac, v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosEdcaAcType ac; + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + vos_mem_zero(pACInfo->curr_QoSInfo, + sizeof(sme_QosWmmTspecInfo) * SME_QOS_TSPEC_INDEX_MAX); + vos_mem_zero(pACInfo->requested_QoSInfo, + sizeof(sme_QosWmmTspecInfo) * SME_QOS_TSPEC_INDEX_MAX); + pACInfo->num_flows[0] = 0; + pACInfo->num_flows[1] = 0; + pACInfo->reassoc_pending = VOS_FALSE; + pACInfo->tspec_mask_status = 0; + pACInfo->tspec_pending = VOS_FALSE; + pACInfo->hoRenewal = VOS_FALSE; + pACInfo->prev_state = SME_QOS_LINK_UP; + } +} + +/*-------------------------------------------------------------------------- + \brief sme_QosIsTSInfoAckPolicyValid() - The SME QoS API exposed to HDD to + check if TS info ack policy field can be set to "HT-immediate block acknowledgement" + + \param pMac - The handle returned by macOpen. + \param pQoSInfo - Pointer to sme_QosWmmTspecInfo which contains the WMM TSPEC + related info, provided by HDD + \param sessionId - sessionId returned by sme_OpenSession. + + \return VOS_TRUE - Current Association is HT association and so TS info ack policy + can be set to "HT-immediate block acknowledgement" + + \sa + + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosIsTSInfoAckPolicyValid(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId) +{ + tDot11fBeaconIEs *pIes = NULL; + sme_QosSessionInfo *pSession; + eHalStatus hstatus; + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session Id %d is invalid", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d is inactive", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + if(!pSession->assocInfo.pBssDesc) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d has an Invalid BSS Descriptor", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + hstatus = csrGetParsedBssDescriptionIEs(pMac, + pSession->assocInfo.pBssDesc, + &pIes); + if(!HAL_STATUS_SUCCESS(hstatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to parse BSS IEs", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + /* success means pIes was allocated */ + + if(!pIes->HTCaps.present && + pQoSInfo->ts_info.ack_policy == SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d HT Caps aren't present but application set ack policy to HT ", + __func__, __LINE__, + sessionId); + + vos_mem_free(pIes); + return VOS_FALSE; + } + + vos_mem_free(pIes); + return VOS_TRUE; +} + +/*-------------------------------------------------------------------------- + \brief sme_QosTspecActive() - The SME QoS API exposed to HDD to + check no of active Tspecs + + \param pMac - The handle returned by macOpen. + \param ac - Determines type of Access Category + \param sessionId - sessionId returned by sme_OpenSession. + + \return VOS_TRUE -When there is no error with pSession + + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_QosTspecActive(tpAniSirGlobal pMac, + WLANTL_ACEnumType ac, v_U8_t sessionId, v_U8_t *pActiveTspec) +{ + sme_QosSessionInfo *pSession = NULL; + sme_QosACInfo *pACInfo = NULL; + + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session Id %d is invalid", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d pSession not found sessionId:%d",__func__,__LINE__,sessionId); + return VOS_FALSE; + } + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Session %d is inactive", + __func__, __LINE__, + sessionId); + return VOS_FALSE; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Session %d is active", __func__, __LINE__, sessionId); + + pACInfo = &pSession->ac_info[ac]; + + // Does this AC have QoS active? + if( SME_QOS_QOS_ON == pACInfo->curr_state ) + { + // Yes, QoS is active on this AC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has QoS active", + __func__, __LINE__, sessionId, ac); + + // Are any TSPECs active? + if( pACInfo->tspec_mask_status ) + { + // Yes, at least 1 TSPEC is active. Are they both active? + if( SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status ) + { + //both TSPECS are active + *pActiveTspec = 2; + } + else + { + // only one TSPEC is active + *pActiveTspec = 1; + } + } + else + { + *pActiveTspec = 0; + } + } + else + { + // Hardcoding value to INVALID_TSPEC (invalid non-zero in this context, + // valid values are 0,1,2) to indicate the caller not to update UAPSD + // parameters as QOS is not active + + *pActiveTspec = INVALID_TSPEC; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has no QoS active", + __func__, __LINE__, sessionId, ac); + } + + return VOS_TRUE; +} + +v_BOOL_t sme_QosValidateRequestedParams(tpAniSirGlobal pMac, + sme_QosWmmTspecInfo * pQoSInfo, + v_U8_t sessionId) +{ + v_BOOL_t rc = VOS_FALSE; + + do + { + if(SME_QOS_WMM_TS_DIR_RESV == pQoSInfo->ts_info.direction) break; + if(!sme_QosIsTSInfoAckPolicyValid(pMac, pQoSInfo, sessionId)) break; + + rc = VOS_TRUE; + }while(0); + return rc; +} + +static eHalStatus qosIssueCommand( tpAniSirGlobal pMac, v_U8_t sessionId, + eSmeCommandType cmdType, sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, v_U8_t tspec_mask ) +{ + eHalStatus status = eHAL_STATUS_RESOURCES; + tSmeCmd *pCommand = NULL; + do + { + pCommand = smeGetCommandBuffer( pMac ); + if ( !pCommand ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: fail to get command buffer for command %d", + __func__, __LINE__, cmdType); + break; + } + pCommand->command = cmdType; + pCommand->sessionId = sessionId; + switch ( cmdType ) + { + case eSmeCommandAddTs: + if( pQoSInfo ) + { + status = eHAL_STATUS_SUCCESS; + pCommand->u.qosCmd.tspecInfo = *pQoSInfo; + pCommand->u.qosCmd.ac = ac; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: NULL pointer passed", + __func__, __LINE__); + status = eHAL_STATUS_INVALID_PARAMETER; + } + break; + case eSmeCommandDelTs: + status = eHAL_STATUS_SUCCESS; + pCommand->u.qosCmd.ac = ac; + pCommand->u.qosCmd.tspec_mask = tspec_mask; + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid command type %d", + __func__, __LINE__, cmdType ); + status = eHAL_STATUS_INVALID_PARAMETER; + break; + } + } while( 0 ); + if( HAL_STATUS_SUCCESS( status ) && pCommand ) + { + smePushCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); + } + else if( pCommand ) + { + qosReleaseCommand( pMac, pCommand ); + } + return( status ); +} +tANI_BOOLEAN qosProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE; + do + { + switch ( pCommand->command ) + { + case eSmeCommandAddTs: + status = sme_QosAddTsReq( pMac, (v_U8_t)pCommand->sessionId, &pCommand->u.qosCmd.tspecInfo, pCommand->u.qosCmd.ac); + if( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP; + } + break; + case eSmeCommandDelTs: + status = sme_QosDelTsReq( pMac, (v_U8_t)pCommand->sessionId, pCommand->u.qosCmd.ac, pCommand->u.qosCmd.tspec_mask ); + if( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: invalid command type %d", + __func__, __LINE__, pCommand->command ); + break; + }//switch + } while(0); + return( fRemoveCmd ); +} + +/* + sme_QosTriggerUapsdChange + Invoked by BTC when UAPSD bypass is enabled or disabled + We, in turn, must disable or enable UAPSD on all flows as appropriate + That may require us to re-add TSPECs or to reassociate +*/ +sme_QosStatusType sme_QosTriggerUapsdChange( tpAniSirGlobal pMac ) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + v_U8_t ac, tspec1 = 0, tspec2 = 0; + v_U8_t uapsd_mask; + tDot11fBeaconIEs *pIesLocal; + v_U8_t acm_mask; + v_BOOL_t fIsUapsdNeeded; + v_U8_t sessionId; + v_BOOL_t addtsWhenACMNotSet = CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked", + __func__, __LINE__); + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; ++sessionId) + { + pSession = &sme_QosCb.sessionInfo[sessionId]; + if( !pSession->sessionActive ) + { + continue; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Session %d is active", + __func__, __LINE__, + sessionId); + if( HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSession->assocInfo.pBssDesc, &pIesLocal)) ) + { + // get the ACM mask + acm_mask = sme_QosGetACMMask(pMac, pSession->assocInfo.pBssDesc, pIesLocal); + vos_mem_free(pIesLocal); + // get the uapsd mask for this session + uapsd_mask = pSession->apsdMask; + // unmask the bits with ACM on to avoid reassoc on them + uapsd_mask &= ~acm_mask; + // iterate through the ACs to determine if we need to re-add any TSPECs + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + // Does this AC have QoS active? + if( SME_QOS_QOS_ON == pACInfo->curr_state ) + { + // Yes, QoS is active on this AC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has QoS active", + __func__, __LINE__, + sessionId, ac); + // Does this AC require ACM? + if(( acm_mask & (1 << (SME_QOS_EDCA_AC_VO - ac)) ) || addtsWhenACMNotSet ) + { + // Yes, so we need to re-add any TSPECS + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has ACM enabled", + __func__, __LINE__, + sessionId, ac); + // Are any TSPECs active? + if( pACInfo->tspec_mask_status ) + { + // Yes, at least 1 TSPEC is active. Are they both active? + if( SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status ) + { + //both TSPECS are active + tspec1 = SME_QOS_TSPEC_MASK_BIT_1_SET; + tspec2 = SME_QOS_TSPEC_MASK_BIT_2_SET; + } + else + { + // only one TSPEC is active, get its mask + tspec1 = SME_QOS_TSPEC_MASK_BIT_1_2_SET & pACInfo->tspec_mask_status; + } + // Does TSPEC 1 really require UAPSD? + fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[tspec1 - 1].ts_info.psb); + //double check whether we need to do anything + if( fIsUapsdNeeded ) + { + pACInfo->requested_QoSInfo[tspec1 - 1] = + pACInfo->curr_QoSInfo[tspec1 - 1]; + sme_QosReRequestAddTS( pMac, sessionId, + &pACInfo->requested_QoSInfo[tspec1 - 1], + ac, + tspec1 ); + } + // Is TSPEC 2 active? + if( tspec2 ) + { + // Does TSPEC 2 really require UAPSD? + fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[tspec2 - 1].ts_info.psb); + if( fIsUapsdNeeded ) + { + //No need to inform HDD + //pACInfo->hoRenewal = VOS_TRUE; + pACInfo->requested_QoSInfo[tspec2 - 1] = + pACInfo->curr_QoSInfo[tspec2 - 1]; + sme_QosReRequestAddTS( pMac, sessionId, + &pACInfo->requested_QoSInfo[tspec2 - 1], + ac, + tspec2); + } + } + } + else + { + // QoS is set, ACM is on, but no TSPECs -- inconsistent state + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d has QoS enabled and ACM is set, but no TSPEC", + __func__, __LINE__, + sessionId, ac); + VOS_ASSERT(0); + } + } + else + { + //Since ACM bit is not set, there should be only one QoS information for both directions. + fIsUapsdNeeded = (v_BOOL_t)(pACInfo->curr_QoSInfo[0].ts_info.psb); + if(fIsUapsdNeeded) + { + // we need UAPSD on this AC (and we may not currently have it) + uapsd_mask |= 1 << (SME_QOS_EDCA_AC_VO - ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has ACM disabled, uapsd mask now 0x%X", + __func__, __LINE__, + sessionId, ac, uapsd_mask); + } + } + } + } + // do we need to reassociate? + if(uapsd_mask) + { + tCsrRoamModifyProfileFields modifyProfileFields; + //we need to do a reassoc on these AC + csrGetModifyProfileFields(pMac, sessionId, &modifyProfileFields); + if( btcIsReadyForUapsd(pMac) ) + { + modifyProfileFields.uapsd_mask = uapsd_mask; + } + else + { + modifyProfileFields.uapsd_mask = 0; + } + //Do we need to inform HDD? + if(!HAL_STATUS_SUCCESS(sme_QosRequestReassoc(pMac, sessionId, &modifyProfileFields, VOS_TRUE))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d Reassoc failed", + __func__, __LINE__, + sessionId); + } + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d failed to parse IEs", + __func__, __LINE__, + sessionId); + } + } + // return status is ignored by BTC + return SME_QOS_STATUS_SETUP_SUCCESS_IND; +} + +/* + sme_QoSUpdateUapsdBTEvent + Invoked by BTC when there is a need to disable/enable UAPSD + The driver in turn must come out of UAPSD and re-negotiate Tspec + changed UAPSD settings on all active Tspecs. +*/ +void sme_QoSUpdateUapsdBTEvent(tpAniSirGlobal pMac) +{ + sme_QosSessionInfo *pSession = NULL; + sme_QosACInfo *pACInfo = NULL; + v_U8_t ac, tspec1 = 0, tspec2 = 0; + tDot11fBeaconIEs *pIesLocal; + v_U8_t acm_mask; + v_S7_t sessionId; + v_BOOL_t addtsWhenACMNotSet = CSR_IS_ADDTS_WHEN_ACMOFF_SUPPORTED(pMac); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked", __func__, __LINE__); + + if (csrIsConcurrentSessionRunning(pMac)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d Concurrent Sessions running, do nothing", + __func__,__LINE__); + return; + } + + sessionId = csrGetInfraSessionId(pMac); + if (-1 == sessionId) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d Invalid sessionId",__func__,__LINE__); + return; + } + + pSession = &sme_QosCb.sessionInfo[sessionId]; + if (NULL == pSession) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d pSession not found sessionId:%d",__func__,__LINE__,sessionId); + return; + } + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d Session %d not active",__func__,__LINE__,sessionId); + return; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Session %d is active", __func__, __LINE__, sessionId); + + if( HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSession->assocInfo.pBssDesc, &pIesLocal)) ) + { + // get the ACM mask + acm_mask = sme_QosGetACMMask(pMac, pSession->assocInfo.pBssDesc, pIesLocal); + vos_mem_free(pIesLocal); + + // iterate through the ACs to determine if we need to re-add any TSPECs + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + + // Does this AC have QoS active? + if( SME_QOS_QOS_ON == pACInfo->curr_state ) + { + // Yes, QoS is active on this AC + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has QoS active", + __func__, __LINE__, sessionId, ac); + // Does this AC require ACM? + if(( acm_mask & (1 << (SME_QOS_EDCA_AC_VO - ac)) ) || addtsWhenACMNotSet ) + { + // Yes, so we need to re-add any TSPECS + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: On session %d AC %d has ACM enabled", + __func__, __LINE__, sessionId, ac); + // Are any TSPECs active? + if( pACInfo->tspec_mask_status ) + { + // Yes, at least 1 TSPEC is active. Are they both active? + if( SME_QOS_TSPEC_MASK_BIT_1_2_SET == pACInfo->tspec_mask_status ) + { + //both TSPECS are active + tspec1 = SME_QOS_TSPEC_MASK_BIT_1_SET; + tspec2 = SME_QOS_TSPEC_MASK_BIT_2_SET; + } + else + { + // only one TSPEC is active, get its mask + tspec1 = SME_QOS_TSPEC_MASK_BIT_1_2_SET & pACInfo->tspec_mask_status; + } + + if (pACInfo->curr_QoSInfo[tspec1 - 1].expec_psb_byapp ) + { + pACInfo->requested_QoSInfo[tspec1 - 1] = + pACInfo->curr_QoSInfo[tspec1 - 1]; + + pACInfo->requested_QoSInfo[tspec1 - 1].ts_info.psb = 1; + + if(!btcIsReadyForUapsd(pMac)) + pACInfo->requested_QoSInfo[tspec1 - 1].ts_info.psb = 0; + + sme_QosReRequestAddTS (pMac, sessionId, + &pACInfo->requested_QoSInfo[tspec1 - 1], + ac, + tspec1); + } + + if (tspec2) + { + if (pACInfo->curr_QoSInfo[tspec2 - 1].expec_psb_byapp) + { + pACInfo->requested_QoSInfo[tspec2 - 1] = + pACInfo->curr_QoSInfo[tspec2 - 1]; + + pACInfo->requested_QoSInfo[tspec2 - 1].ts_info.psb = 1; + + if(!btcIsReadyForUapsd(pMac)) + pACInfo->requested_QoSInfo[tspec2 - 1].ts_info.psb = 0; + + sme_QosReRequestAddTS (pMac, sessionId, + &pACInfo->requested_QoSInfo[tspec2 - 1], + ac, + tspec2); + } + } + } + else + { + // QoS is ON, ACM is on, but no TSPECs -- Inconsistent state + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d AC %d has QoS enabled and ACM is set, but no TSPEC", + __func__, __LINE__, + sessionId, ac); + } + } + } + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On Session %d failed to parse IEs", + __func__, __LINE__, + sessionId); + } +} + +/* + sme_QosReRequestAddTS to re-send AddTS for the combined QoS request +*/ +static sme_QosStatusType sme_QosReRequestAddTS(tpAniSirGlobal pMac, + v_U8_t sessionId, + sme_QosWmmTspecInfo * pQoSInfo, + sme_QosEdcaAcType ac, + v_U8_t tspecMask) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + sme_QosStatusType status = SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + sme_QosCmdInfo cmd; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d for AC %d TSPEC %d", + __func__, __LINE__, + sessionId, ac, tspecMask); + pSession = &sme_QosCb.sessionInfo[sessionId]; + pACInfo = &pSession->ac_info[ac]; + // need to vote off powersave for the duration of this request + pSession->readyForPowerSave = VOS_FALSE; + //call PMC's request for power function + // AND + //another check is added considering the flowing scenario + //Addts reqest is pending on one AC, while APSD requested on another which + //needs a reassoc. Will buffer a request if Addts is pending on any AC, + //which will safegaurd the above scenario, & also won't confuse PE with back + //to back Addts or Addts followed by Reassoc + if(sme_QosIsRspPending(sessionId, ac) || + ( eHAL_STATUS_PMC_PENDING == pmcRequestFullPower(pMac, sme_QosPmcFullPowerCallback, pSession, eSME_REASON_OTHER))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d buffering the AddTS request " + "for AC %d in state %d as Addts is pending " + "on other AC or waiting for full power", + __func__, __LINE__, + sessionId, ac, pACInfo->curr_state); + //buffer cmd + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = tspecMask; + cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: On session %d unable to buffer the AddTS " + "request for AC %d TSPEC %d in state %d", + __func__, __LINE__, + sessionId, ac, tspecMask, pACInfo->curr_state); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + return SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + } + //get into the stat m/c to see if the request can be granted + switch(pACInfo->curr_state) + { + case SME_QOS_QOS_ON: + { + //if ACM, send out a new ADDTS + pACInfo->hoRenewal = VOS_TRUE; + status = sme_QosSetup(pMac, sessionId, pQoSInfo, ac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: sme_QosSetup returned in SME_QOS_QOS_ON state on " + "AC %d with status =%d", + __func__, __LINE__, + ac, status); + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP != status) + { + // we aren't waiting for a response from the AP + // so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + } + if(SME_QOS_STATUS_SETUP_REQ_PENDING_RSP == status) + { + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + pACInfo->tspec_pending = tspecMask; + } + else if((SME_QOS_STATUS_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_APSD_SET_ALREADY == status) || + (SME_QOS_STATUS_SETUP_SUCCESS_IND_APSD_PENDING == status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: UAPSD is setup already status = %d " + "returned by sme_QosSetup", + __func__, __LINE__, + status); + } + else + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: unexpected status = %d returned by sme_QosSetup", + __func__, __LINE__, + status); + } + } + break; + case SME_QOS_HANDOFF: + case SME_QOS_REQUESTED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: Re-Add request in state = %d buffer the request", + __func__, __LINE__, + pACInfo->curr_state); + cmd.command = SME_QOS_RESEND_REQ; + cmd.pMac = pMac; + cmd.sessionId = sessionId; + cmd.u.resendCmdInfo.ac = ac; + cmd.u.resendCmdInfo.tspecMask = tspecMask; + cmd.u.resendCmdInfo.QoSInfo = *pQoSInfo; + if(!HAL_STATUS_SUCCESS(sme_QosBufferCmd(&cmd, VOS_FALSE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: couldn't buffer the readd request in state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to buffer the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + return SME_QOS_STATUS_MODIFY_SETUP_FAILURE_RSP; + } + status = SME_QOS_STATUS_MODIFY_SETUP_PENDING_RSP; + break; + case SME_QOS_CLOSED: + case SME_QOS_INIT: + case SME_QOS_LINK_UP: + default: + //print error msg, + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: %d: ReAdd request in unexpected state = %d", + __func__, __LINE__, + pACInfo->curr_state ); + // unable to service the request + // nothing is pending so vote powersave back on + pSession->readyForPowerSave = VOS_TRUE; + // ASSERT? + break; + } + if((SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_NO_ACM_NO_APSD_RSP == status) || + (SME_QOS_STATUS_MODIFY_SETUP_SUCCESS_APSD_SET_ALREADY == status)) + { + (void)sme_QosProcessBufferedCmd(sessionId); + } + return (status); +} + +static void sme_QosInitACs(tpAniSirGlobal pMac, v_U8_t sessionId) +{ + sme_QosSessionInfo *pSession; + sme_QosEdcaAcType ac; + pSession = &sme_QosCb.sessionInfo[sessionId]; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + vos_mem_zero(&pSession->ac_info[ac], sizeof(sme_QosACInfo)); + sme_QosStateTransition(sessionId, ac, SME_QOS_INIT); + } +} +static eHalStatus sme_QosRequestReassoc(tpAniSirGlobal pMac, tANI_U8 sessionId, + tCsrRoamModifyProfileFields *pModFields, + v_BOOL_t fForce ) +{ + sme_QosSessionInfo *pSession; + sme_QosACInfo *pACInfo; + eHalStatus status; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: %d: Invoked on session %d with UAPSD mask 0x%X", + __func__, __LINE__, + sessionId, pModFields->uapsd_mask); + pSession = &sme_QosCb.sessionInfo[sessionId]; + status = csrReassoc(pMac, sessionId, pModFields, &pSession->roamID, fForce); + if(HAL_STATUS_SUCCESS(status)) + { + //Update the state to Handoff so subsequent requests are queued until + // this one is finished + sme_QosEdcaAcType ac; + for(ac = SME_QOS_EDCA_AC_BE; ac < SME_QOS_EDCA_AC_MAX; ac++) + { + pACInfo = &pSession->ac_info[ac]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: %d: AC[%d] is in state [%d]", + __func__, __LINE__, + ac, pACInfo->curr_state ); + // If it is already in HANDOFF state, don't do anything since we + // MUST preserve the previous state and sme_QosStateTransition + // will change the previous state + if(SME_QOS_HANDOFF != pACInfo->curr_state) + { + sme_QosStateTransition(sessionId, ac, SME_QOS_HANDOFF); + } + } + } + return status; +} +static v_U32_t sme_QosAssignFlowId(void) +{ + v_U32_t flowId; + flowId = sme_QosCb.nextFlowId; + if (SME_QOS_MAX_FLOW_ID == flowId) + { + // The Flow ID wrapped. This is obviously not a real life scenario + // but handle it to keep the software test folks happy + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: Software Test made the flow counter wrap, " + "QoS may no longer be functional", + __func__, __LINE__); + sme_QosCb.nextFlowId = SME_QOS_MIN_FLOW_ID; + } + else + { + sme_QosCb.nextFlowId++; + } + return flowId; +} + +static v_U8_t sme_QosAssignDialogToken(void) +{ + v_U8_t token; + token = sme_QosCb.nextDialogToken; + if (SME_QOS_MAX_DIALOG_TOKEN == token) + { + // wrap is ok + sme_QosCb.nextDialogToken = SME_QOS_MIN_DIALOG_TOKEN; + } + else + { + sme_QosCb.nextDialogToken++; + } + return token; +} +#endif /* WLAN_MDM_CODE_REDUCTION_OPT */ diff --git a/drivers/staging/prima/CORE/SME/src/btc/btcApi.c b/drivers/staging/prima/CORE/SME/src/btc/btcApi.c new file mode 100644 index 000000000000..ea82288d2309 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/btc/btcApi.c @@ -0,0 +1,2142 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: btcApi.c +* +* Description: Routines that make up the BTC API. +* +* +******************************************************************************/ +#include "wlan_qct_wda.h" +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +#include "aniGlobal.h" +#include "smsDebug.h" +#include "btcApi.h" +#include "cfgApi.h" +#include "pmc.h" +#include "smeQosInternal.h" +#include "sme_Trace.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent); +static void btcRestoreHeartBeatMonitoringHandle(void* hHal); +static void btcEnableUapsdTimerExpiryHandler(void* hHal); +static void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent ); +VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent); +static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState ); +static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ); +static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ); +#ifdef FEATURE_WLAN_DIAG_SUPPORT +static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +/* --------------------------------------------------------------------------- + \fn btcOpen + \brief API to init the BTC Events Layer + \param hHal - The handle returned by macOpen. + \return VOS_STATUS + VOS_STATUS_E_FAILURE success + VOS_STATUS_SUCCESS failure + ---------------------------------------------------------------------------*/ +VOS_STATUS btcOpen (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + int i; + + /* Initialize BTC configuartion. */ + pMac->btc.btcConfig.btcExecutionMode = BTC_SMART_COEXISTENCE; + pMac->btc.btcConfig.btcConsBtSlotsToBlockDuringDhcp = 0; + pMac->btc.btcConfig.btcA2DPBtSubIntervalsDuringDhcp = BTC_MAX_NUM_ACL_BT_SUB_INTS; + pMac->btc.btcConfig.btcBtIntervalMode1 = BTC_BT_INTERVAL_MODE1_DEFAULT; + pMac->btc.btcConfig.btcWlanIntervalMode1 = BTC_WLAN_INTERVAL_MODE1_DEFAULT; + pMac->btc.btcConfig.btcActionOnPmFail = BTC_START_NEXT; + + pMac->btc.btcConfig.btcStaticLenInqBt = BTC_STATIC_BT_LEN_INQ_DEF; + pMac->btc.btcConfig.btcStaticLenPageBt = BTC_STATIC_BT_LEN_PAGE_DEF; + pMac->btc.btcConfig.btcStaticLenConnBt = BTC_STATIC_BT_LEN_CONN_DEF; + pMac->btc.btcConfig.btcStaticLenLeBt = BTC_STATIC_BT_LEN_LE_DEF; + pMac->btc.btcConfig.btcStaticLenInqWlan = BTC_STATIC_WLAN_LEN_INQ_DEF; + pMac->btc.btcConfig.btcStaticLenPageWlan = BTC_STATIC_WLAN_LEN_PAGE_DEF; + pMac->btc.btcConfig.btcStaticLenConnWlan = BTC_STATIC_WLAN_LEN_CONN_DEF; + pMac->btc.btcConfig.btcStaticLenLeWlan = BTC_STATIC_WLAN_LEN_LE_DEF; + pMac->btc.btcConfig.btcDynMaxLenBt = BTC_DYNAMIC_BT_LEN_MAX_DEF; + pMac->btc.btcConfig.btcDynMaxLenWlan = BTC_DYNAMIC_WLAN_LEN_MAX_DEF; + pMac->btc.btcConfig.btcMaxScoBlockPerc = BTC_SCO_BLOCK_PERC_DEF; + pMac->btc.btcConfig.btcDhcpProtOnA2dp = BTC_DHCP_ON_A2DP_DEF; + pMac->btc.btcConfig.btcDhcpProtOnSco = BTC_DHCP_ON_SCO_DEF; + + pMac->btc.btcReady = VOS_FALSE; + pMac->btc.btcEventState = 0; + pMac->btc.btcHBActive = VOS_TRUE; + pMac->btc.btc_scan_compromise_esco = false; + pMac->btc.btc_scan_compromise_sco = false; + + for (i = 0; i < MWS_COEX_MAX_VICTIM_TABLE; i++) + { + pMac->btc.btcConfig.mwsCoexVictimWANFreq[i] = 0; + pMac->btc.btcConfig.mwsCoexVictimWLANFreq[i] = 0; + pMac->btc.btcConfig.mwsCoexVictimConfig[i] = 0; + pMac->btc.btcConfig.mwsCoexVictimConfig2[i] = 0; + } + + for (i = 0; i < MWS_COEX_MAX_CONFIG; i++) + { + pMac->btc.btcConfig.mwsCoexConfig[i] = 0; + } + + pMac->btc.btcConfig.mwsCoexModemBackoff = 0; + pMac->btc.btcConfig.SARPowerBackoff = 0; + + vosStatus = vos_timer_init( &pMac->btc.restoreHBTimer, + VOS_TIMER_TYPE_SW, + btcRestoreHeartBeatMonitoringHandle, + (void*) hHal); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to init timer"); + return VOS_STATUS_E_FAILURE; + } + + vosStatus = vos_timer_init( &pMac->btc.enableUapsdTimer, + VOS_TIMER_TYPE_SW, + btcEnableUapsdTimerExpiryHandler, + (void*) hHal); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to init Uapsd timer"); + return VOS_STATUS_E_FAILURE; + } + + if( !HAL_STATUS_SUCCESS(pmcRegisterDeviceStateUpdateInd( pMac, btcPowerStateCB, pMac )) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to register PMC callback"); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcClose + \brief API to exit the BTC Events Layer + \param hHal - The handle returned by macOpen. + \return VOS_STATUS + VOS_STATUS_E_FAILURE success + VOS_STATUS_SUCCESS failure + ---------------------------------------------------------------------------*/ +VOS_STATUS btcClose (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + pMac->btc.btcReady = VOS_FALSE; + pMac->btc.btcUapsdOk = VOS_FALSE; + vos_timer_stop(&pMac->btc.restoreHBTimer); + vosStatus = vos_timer_destroy(&pMac->btc.restoreHBTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcClose: Fail to destroy timer"); + return VOS_STATUS_E_FAILURE; + } + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pMac->btc.enableUapsdTimer)) + vos_timer_stop(&pMac->btc.enableUapsdTimer); + vosStatus = vos_timer_destroy(&pMac->btc.enableUapsdTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcClose: Fail to destroy uapsd timer"); + return VOS_STATUS_E_FAILURE; + } + + if(!HAL_STATUS_SUCCESS( + pmcDeregisterDeviceStateUpdateInd(pMac, btcPowerStateCB))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: %d: cannot deregister with pmcDeregisterDeviceStateUpdateInd()", + __func__, __LINE__); + } + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn btcReady + \brief fn to inform BTC that eWNI_SME_SYS_READY_IND has been sent to PE. + This acts as a trigger to send a message to HAL to update the BTC + related conig to FW. Note that if HDD configures any power BTC + related stuff before this API is invoked, BTC will buffer all the + configutaion. + \param hHal - The handle returned by macOpen. + \return VOS_STATUS + ---------------------------------------------------------------------------*/ +VOS_STATUS btcReady (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_U32_t cfgVal = 0; + v_U8_t i; + pMac->btc.btcReady = VOS_TRUE; + pMac->btc.btcUapsdOk = VOS_TRUE; + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE; + } + + // Read heartbeat threshold CFG and save it. + ccmCfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &cfgVal); + pMac->btc.btcHBCount = (v_U8_t)cfgVal; + if (btcSendCfgMsg(hHal, &(pMac->btc.btcConfig)) != VOS_STATUS_SUCCESS) + { + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS btcSendBTEvent(tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent) +{ + vos_msg_t msg; + tpSmeBtEvent ptrSmeBtEvent = NULL; + switch(pBtEvent->btEventType) + { + case BT_EVENT_CREATE_SYNC_CONNECTION: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + if(pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO && + pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid link type %d for Sync Connection. BT event will be dropped ", + __func__, pBtEvent->uEventParam.btSyncConnection.linkType); + return VOS_STATUS_E_FAILURE; + } + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + if((pBtEvent->uEventParam.btSyncConnection.status == BT_CONN_STATUS_SUCCESS) && + ((pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO && pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO) || + (pBtEvent->uEventParam.btSyncConnection.connectionHandle == BT_INVALID_CONN_HANDLE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid connection handle %d or link type %d for Sync Connection. BT event will be dropped ", + __func__, + pBtEvent->uEventParam.btSyncConnection.connectionHandle, + pBtEvent->uEventParam.btSyncConnection.linkType); + return VOS_STATUS_E_FAILURE; + } + break; + case BT_EVENT_MODE_CHANGED: + if(pBtEvent->uEventParam.btAclModeChange.mode >= BT_ACL_MODE_MAX) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid mode %d for ACL Connection. BT event will be dropped ", + __func__, + pBtEvent->uEventParam.btAclModeChange.mode); + return VOS_STATUS_E_FAILURE; + } + break; + case BT_EVENT_DEVICE_SWITCHED_OFF: + pMac->btc.btcEventState = 0; + break; + default: + break; + } + ptrSmeBtEvent = vos_mem_malloc(sizeof(tSmeBtEvent)); + if (NULL == ptrSmeBtEvent) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to allocate memory for BT event", __func__); + return VOS_STATUS_E_FAILURE; + } + btcLogEvent(pMac, pBtEvent); +#ifdef FEATURE_WLAN_DIAG_SUPPORT + btcDiagEventLog(pMac, pBtEvent); +#endif + vos_mem_copy(ptrSmeBtEvent, pBtEvent, sizeof(tSmeBtEvent)); + msg.type = WDA_SIGNAL_BT_EVENT; + msg.reserved = 0; + msg.bodyptr = ptrSmeBtEvent; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post WDA_SIGNAL_BT_EVENT message to WDA", __func__); + vos_mem_free( ptrSmeBtEvent ); + return VOS_STATUS_E_FAILURE; + } + // After successfully posting the message, check if heart beat + // monitoring needs to be turned off + (void)btcCheckHeartBeatMonitoring(pMac, pBtEvent); + //Check whether BTC and UAPSD can co-exist + btcUapsdCheck( pMac, pBtEvent ); + return VOS_STATUS_SUCCESS; + } + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT +/* --------------------------------------------------------------------------- + \fn btcSignalBTEvent + \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the + BT event type and the current operating mode of Libra (full power, + BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy + would be employed. + \param hHal - The handle returned by macOpen. + \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE – BT Event not passed to HAL. This can happen + if driver has not yet been initialized or if BTC + Events Layer has been disabled. + VOS_STATUS_SUCCESS – BT Event passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcSignalBTEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + VOS_STATUS vosStatus; + if( NULL == pBtEvent ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Null pointer for SME BT Event", __func__); + return VOS_STATUS_E_FAILURE; + } + if(( BTC_WLAN_ONLY == pMac->btc.btcConfig.btcExecutionMode ) || + ( BTC_PTA_ONLY == pMac->btc.btcConfig.btcExecutionMode )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "BTC execution mode not set to BTC_SMART_COEXISTENCE. BT event will be dropped", __func__); + return VOS_STATUS_E_FAILURE; + } + if( pBtEvent->btEventType < 0 || pBtEvent->btEventType >= BT_EVENT_TYPE_MAX ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Invalid BT event %d being passed. BT event will be dropped", + __func__, pBtEvent->btEventType); + return VOS_STATUS_E_FAILURE; + } + //Check PMC state to make sure whether we need to defer + //If we already have deferred events, defer the new one as well, in case PMC is in transition state + if( pMac->btc.fReplayBTEvents || !PMC_IS_CHIP_ACCESSIBLE(pmcGetPmcState( pMac )) ) + { + //We need to defer the event + vosStatus = btcDeferEvent(pMac, pBtEvent); + if( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + pMac->btc.fReplayBTEvents = VOS_TRUE; + return VOS_STATUS_SUCCESS; + } + else + { + return vosStatus; + } + } + btcSendBTEvent(pMac, pBtEvent); + return VOS_STATUS_SUCCESS; +} +#endif +/* --------------------------------------------------------------------------- + \fn btcCheckHeartBeatMonitoring + \brief API to check whether heartbeat monitoring is required to be disabled + for specific BT start events which takes significant time to complete + during which WLAN misses beacons. To avoid WLAN-MAC from disconnecting + for the not enough beacons received we stop the heartbeat timer during + this start BT event till the stop of that BT event. + \param hHal - The handle returned by macOpen. + \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + VOS_STATUS vosStatus; + switch(pBtEvent->btEventType) + { + // Start events which requires heartbeat monitoring be disabled. + case BT_EVENT_INQUIRY_STARTED: + pMac->btc.btcEventState |= BT_INQUIRY_STARTED; + break; + case BT_EVENT_PAGE_STARTED: + pMac->btc.btcEventState |= BT_PAGE_STARTED; + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + pMac->btc.btcEventState |= BT_CREATE_ACL_CONNECTION_STARTED; + break; + case BT_EVENT_CREATE_SYNC_CONNECTION: + pMac->btc.btcEventState |= BT_CREATE_SYNC_CONNECTION_STARTED; + break; + // Stop/done events which indicates heartbeat monitoring can be enabled + case BT_EVENT_INQUIRY_STOPPED: + pMac->btc.btcEventState &= ~(BT_INQUIRY_STARTED); + break; + case BT_EVENT_PAGE_STOPPED: + pMac->btc.btcEventState &= ~(BT_PAGE_STARTED); + break; + case BT_EVENT_ACL_CONNECTION_COMPLETE: + pMac->btc.btcEventState &= ~(BT_CREATE_ACL_CONNECTION_STARTED); + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + pMac->btc.btcEventState &= ~(BT_CREATE_SYNC_CONNECTION_STARTED); + break; + default: + // Ignore other events + return VOS_STATUS_SUCCESS; + } + // Check if any of the BT start events are active + if (pMac->btc.btcEventState) { + if (pMac->btc.btcHBActive) { + // set heartbeat threshold CFG to zero + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_FALSE; + } + // Deactivate and active the restore HB timer + vos_timer_stop( &pMac->btc.restoreHBTimer); + vosStatus= vos_timer_start( &pMac->btc.restoreHBTimer, BT_MAX_EVENT_DONE_TIMEOUT ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to start timer"); + return VOS_STATUS_E_FAILURE; + } + } else { + // Restore CFG back to the original value only if it was disabled + if (!pMac->btc.btcHBActive) { + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_TRUE; + } + // Deactivate the timer + vosStatus = vos_timer_stop( &pMac->btc.restoreHBTimer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to stop timer"); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcRestoreHeartBeatMonitoringHandle + \brief Timer handler to handlet the timeout condition when a specific BT + stop event does not come back, in which case to restore back the + heartbeat timer. + \param hHal - The handle returned by macOpen. + \return VOID + ---------------------------------------------------------------------------*/ +void btcRestoreHeartBeatMonitoringHandle(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if( !pMac->btc.btcHBActive ) + { + tPmcState pmcState; + //Check PMC state to make sure whether we need to defer + pmcState = pmcGetPmcState( pMac ); + if( PMC_IS_CHIP_ACCESSIBLE(pmcState) ) + { + // Restore CFG back to the original value + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BT event timeout, restoring back HeartBeat timer"); + } + else + { + //defer it + pMac->btc.btcEventReplay.fRestoreHBMonitor = VOS_TRUE; + } + } +} + +/* --------------------------------------------------------------------------- + \fn btcEnableUapsdTimerExpiryHandler + \brief Timer handler to handle the timeout condition when Uapsd timer + expires, in this case negotiate for uapsd settings with the AP. + \param hHal - The handle returned by macOpen. + \return VOID + ---------------------------------------------------------------------------*/ +void btcEnableUapsdTimerExpiryHandler(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (IS_DYNAMIC_WMM_PS_ENABLED) + { + if (pMac->btc.btcUapsdOk == VOS_FALSE) + { + pMac->btc.btcUapsdOk = VOS_TRUE; + smsLog(pMac, LOG1, FL("Uapsd Timer Expired, Enable Uapsd")); + sme_QoSUpdateUapsdBTEvent(pMac); + } + } + + if (pMac->sme.pBtCoexTDLSNotification) + { + smsLog(pMac, LOG1, FL("btCoex notification, Enable TDLS")); + pMac->sme.pBtCoexTDLSNotification(pMac->pAdapter, + SIR_COEX_IND_TYPE_TDLS_ENABLE); + } +} + +/* --------------------------------------------------------------------------- + \fn btcSetConfig + \brief API to change the current Bluetooth Coexistence (BTC) configuration + This function should be invoked only after CFG download has completed. + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + //Save a copy in the global BTC config + vos_mem_copy(&(pMac->btc.btcConfig), pSmeBtcConfig, sizeof(tSmeBtcConfig)); + //Send the config down only if SME_HddReady has been invoked. If not ready, + //BTC config will plumbed down when btcReady is eventually invoked. + if(pMac->btc.btcReady) + { + if(VOS_STATUS_SUCCESS != btcSendCfgMsg(hHal, pSmeBtcConfig)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "Failure to send BTC config down"); + return VOS_STATUS_E_FAILURE; + } + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcPostBtcCfgMsg + \brief Private API to post BTC config message to HAL + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS btcSendCfgMsg(tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + tpSmeBtcConfig ptrSmeBtcConfig = NULL; + vos_msg_t msg; + if( NULL == pSmeBtcConfig ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Null pointer for BTC Config"); + return VOS_STATUS_E_FAILURE; + } + if( pSmeBtcConfig->btcExecutionMode >= BT_EXEC_MODE_MAX ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Invalid BT execution mode %d being set", + pSmeBtcConfig->btcExecutionMode); + return VOS_STATUS_E_FAILURE; + } + ptrSmeBtcConfig = vos_mem_malloc(sizeof(tSmeBtcConfig)); + if (NULL == ptrSmeBtcConfig) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Not able to allocate memory for SME BTC Config"); + return VOS_STATUS_E_FAILURE; + } + vos_mem_copy(ptrSmeBtcConfig, pSmeBtcConfig, sizeof(tSmeBtcConfig)); + msg.type = WDA_BTC_SET_CFG; + msg.reserved = 0; + msg.bodyptr = ptrSmeBtcConfig; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: " + "Not able to post WDA_BTC_SET_CFG message to WDA"); + vos_mem_free( ptrSmeBtcConfig ); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn btcGetConfig + \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS btcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if( NULL == pSmeBtcConfig ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcGetConfig: " + "Null pointer for BTC Config"); + return VOS_STATUS_E_FAILURE; + } + vos_mem_copy(pSmeBtcConfig, &(pMac->btc.btcConfig), sizeof(tSmeBtcConfig)); + return VOS_STATUS_SUCCESS; +} +/* + btcFindAclEventHist find a suited ACL event buffer + Param: bdAddr - NULL meaning not care. + pointer to caller alocated buffer containing the BD address to find a match + handle - BT_INVALID_CONN_HANDLE == not care + otherwise, a handle to match + NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither + bdAddr nor handle is valid, return the next free slot. +*/ +static tpSmeBtAclEventHist btcFindAclEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle ) +{ + int i, j; + tpSmeBtAclEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + for( i = 0; (i < BT_MAX_ACL_SUPPORT) && (NULL == pRet); i++ ) + { + if( NULL != bdAddr ) + { + //try to match addr + if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( vos_mem_compare(pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].bdAddr, + bdAddr, 6) ) + { + //found it + pRet = &pReplay->btcEventHist.btAclConnectionEvent[i]; + break; + } + } + } + } + else if( BT_INVALID_CONN_HANDLE != handle ) + { + //try to match handle + if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].connectionHandle == + handle ) + { + //found it + pRet = &pReplay->btcEventHist.btAclConnectionEvent[i]; + break; + } + } + } + } + else if( 0 == pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + pRet = &pReplay->btcEventHist.btAclConnectionEvent[i]; + break; + } + } + return (pRet); +} + +/* + btcFindSyncEventHist find a suited SYNC event buffer + Param: bdAddr - NULL meaning not care. + pointer to caller alocated buffer containing the BD address to find a match + handle - BT_INVALID_CONN_HANDLE == not care + otherwise, a handle to match + NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither + bdAddr nor handle is valid, return the next free slot. +*/ +static tpSmeBtSyncEventHist btcFindSyncEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle ) +{ + int i, j; + tpSmeBtSyncEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + for( i = 0; (i < BT_MAX_SCO_SUPPORT) && (NULL == pRet); i++ ) + { + if( NULL != bdAddr ) + { + //try to match addr + if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( vos_mem_compare(pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].bdAddr, + bdAddr, 6) ) + { + //found it + pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + break; + } + } + } + } + else if( BT_INVALID_CONN_HANDLE != handle ) + { + //try to match handle + if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++) + { + if( pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].connectionHandle == + handle ) + { + //found it + pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + break; + } + } + } + } + else if( !pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + break; + } + } + return (pRet); +} + +/* + btcFindDisconnEventHist find a slot for the deferred disconnect event + If handle is invlid, it returns a free slot, if any. + If handle is valid, it tries to find a match first in case same disconnect event comes down again. +*/ +static tpSmeBtDisconnectEventHist btcFindDisconnEventHist( tpAniSirGlobal pMac, v_U16_t handle ) +{ + tpSmeBtDisconnectEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + int i; + if( BT_INVALID_CONN_HANDLE != handle ) + { + for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++) + { + if( pReplay->btcEventHist.btDisconnectEvent[i].fValid && + (handle == pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect.connectionHandle) ) + { + pRet = &pReplay->btcEventHist.btDisconnectEvent[i]; + break; + } + } + } + if( NULL == pRet ) + { + //Find a free slot + for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++) + { + if( !pReplay->btcEventHist.btDisconnectEvent[i].fValid ) + { + pRet = &pReplay->btcEventHist.btDisconnectEvent[i]; + break; + } + } + } + return (pRet); +} + +/* + btcFindModeChangeEventHist find a slot for the deferred mopde change event + If handle is invalid, it returns a free slot, if any. + If handle is valid, it tries to find a match first in case same disconnect event comes down again. +*/ +tpSmeBtAclModeChangeEventHist btcFindModeChangeEventHist( tpAniSirGlobal pMac, v_U16_t handle ) +{ + tpSmeBtAclModeChangeEventHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + int i; + if( BT_INVALID_CONN_HANDLE != handle ) + { + for(i = 0; i < BT_MAX_ACL_SUPPORT; i++) + { + if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid && + (handle == pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange.connectionHandle) ) + { + pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i]; + break; + } + } + } + if( NULL == pRet ) + { + //Find a free slot + for(i = 0; i < BT_MAX_ACL_SUPPORT; i++) + { + if( !pReplay->btcEventHist.btAclModeChangeEvent[i].fValid ) + { + pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i]; + break; + } + } + } + return (pRet); +} + +/* + btcFindSyncUpdateEventHist find a slot for the deferred SYNC_UPDATE event + If handle is invalid, it returns a free slot, if any. + If handle is valid, it tries to find a match first in case same disconnect event comes down again. +*/ +tpSmeBtSyncUpdateHist btcFindSyncUpdateEventHist( tpAniSirGlobal pMac, v_U16_t handle ) +{ + tpSmeBtSyncUpdateHist pRet = NULL; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + int i; + if( BT_INVALID_CONN_HANDLE != handle ) + { + for(i = 0; i < BT_MAX_SCO_SUPPORT; i++) + { + if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid && + (handle == pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection.connectionHandle) ) + { + pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i]; + break; + } + } + } + if( NULL == pRet ) + { + //Find a free slot + for(i = 0; i < BT_MAX_SCO_SUPPORT; i++) + { + if( !pReplay->btcEventHist.btSyncUpdateEvent[i].fValid ) + { + pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i]; + break; + } + } + } + return (pRet); +} + +/* + Call must validate pAclEventHist +*/ +static void btcReleaseAclEventHist( tpAniSirGlobal pMac, tpSmeBtAclEventHist pAclEventHist ) +{ + vos_mem_zero( pAclEventHist, sizeof(tSmeBtAclEventHist) ); +} + +/* + Call must validate pSyncEventHist +*/ +static void btcReleaseSyncEventHist( tpAniSirGlobal pMac, tpSmeBtSyncEventHist pSyncEventHist ) +{ + vos_mem_zero( pSyncEventHist, sizeof(tSmeBtSyncEventHist) ); +} + +/*To defer a ACL creation event + We only support one ACL per BD address. + If the last cached event another ACL create event, replace that event with the new event + If a completion event with success status code, and the new ACL creation + on same address, defer a new disconnect event(fake one), then cache this ACL creation event. + Otherwise, save this create event. +*/ +static VOS_STATUS btcDeferAclCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtAclEventHist pAclEventHist; + tSmeBtAclConnectionParam *pAclEvent = NULL; + do + { + //Find a match + pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if( NULL == pAclEventHist ) + { + //No cached ACL event on this address + //Find a free slot and save it + pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + if( NULL != pAclEventHist ) + { + vos_mem_copy(&pAclEventHist->btAclConnection[0], &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->btEventType[0] = BT_EVENT_CREATE_ACL_CONNECTION; + pAclEventHist->bNextEventIdx = 1; + } + else + { + smsLog(pMac, LOGE, FL(" failed to find ACL event slot")); + status = VOS_STATUS_E_RESOURCES; + } + //done + break; + } + else + { + //There is history on this BD address + if ((pAclEventHist->bNextEventIdx <= 0) || + (pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED)) + { + VOS_ASSERT(0); + status = VOS_STATUS_E_FAILURE; + break; + } + pAclEvent = &pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx - 1]; + if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1]) + { + //The last cached event is creation, replace it with the new one + if (pAclEvent) + { + vos_mem_copy(pAclEvent, + &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + } + //done + break; + } + else if(BT_EVENT_ACL_CONNECTION_COMPLETE == + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1]) + { + //The last cached event is completion, check the status. + if(BT_CONN_STATUS_SUCCESS == pAclEvent->status) + { + tSmeBtEvent btEvent; + //The last event we have is success completion event. + //Should not get a creation event before creation. + smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d"), pAclEvent->connectionHandle); + //Fake a disconnect event + btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE; + btEvent.uEventParam.btDisconnect.connectionHandle = pAclEvent->connectionHandle; + btcDeferDisconnEvent(pMac, &btEvent); + } + } + //Need to save the new event + if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_CREATE_ACL_CONNECTION; + vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx], + &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" ACL event overflow")); + VOS_ASSERT(0); + } + } + }while(0); + return status; +} + +/*Defer a ACL completion event + If there is cached event on this BD address, check completion status. + If status is fail and last cached event is creation, remove the creation event and drop + this completion event. Otherwise, cache this completion event as the latest one. +*/ +static VOS_STATUS btcDeferAclComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtAclEventHist pAclEventHist; + do + { + //Find a match + pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if(pAclEventHist) + { + VOS_ASSERT(pAclEventHist->bNextEventIdx >0); + //Found one + if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btAclConnection.status) + { + //If completion fails, and the last one is creation, remove the creation event + if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1]) + { + vos_mem_zero(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx-1], + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->bNextEventIdx--; + //Done with this event + break; + } + else + { + smsLog(pMac, LOGE, FL(" ACL completion fail but last event(%d) not creation"), + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1]); + } + } + } + if( NULL == pAclEventHist ) + { + pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + } + if(pAclEventHist) + { + if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + //Save this event + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_ACL_CONNECTION_COMPLETE; + vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx], + &pEvent->uEventParam.btAclConnection, + sizeof(tSmeBtAclConnectionParam)); + pAclEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" ACL event overflow")); + VOS_ASSERT(0); + } + } + else + { + smsLog(pMac, LOGE, FL(" cannot find match for failed " + "BT_EVENT_ACL_CONNECTION_COMPLETE of bdAddr " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pEvent->uEventParam.btAclConnection.bdAddr)); + status = VOS_STATUS_E_EMPTY; + } + }while(0); + return (status); +} + +/*To defer a SYNC creation event + If the last cached event is another SYNC create event, replace + that event with the new event. + If there is a completion event with success status code, cache a new + disconnect event(fake) first, then cache this SYNC creation event. + Otherwise, cache this create event. +*/ +static VOS_STATUS btcDeferSyncCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncEventHist pSyncEventHist; + tSmeBtSyncConnectionParam *pSyncEvent = NULL; + do + { + //Find a match + pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if( NULL == pSyncEventHist ) + { + //No cached ACL event on this address + //Find a free slot and save it + pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + if( NULL != pSyncEventHist ) + { + vos_mem_copy(&pSyncEventHist->btSyncConnection[0], &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->btEventType[0] = BT_EVENT_CREATE_SYNC_CONNECTION; + pSyncEventHist->bNextEventIdx = 1; + } + else + { + smsLog(pMac, LOGE, FL(" failed to find SYNC event slot")); + status = VOS_STATUS_E_RESOURCES; + } + //done + break; + } + else + { + //There is history on this BD address + if ((pSyncEventHist->bNextEventIdx <= 0) || + (pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED)) + { + VOS_ASSERT(0); + status = VOS_STATUS_E_FAILURE; + return status; + } + pSyncEvent = &pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx - 1]; + if(BT_EVENT_CREATE_SYNC_CONNECTION == + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1]) + { + //The last cached event is creation, replace it with the new one + if(pSyncEvent) + { + vos_mem_copy(pSyncEvent, + &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + } + //done + break; + } + else if(BT_EVENT_SYNC_CONNECTION_COMPLETE == + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1]) + { + //The last cached event is completion, check the status. + if(BT_CONN_STATUS_SUCCESS == pSyncEvent->status) + { + tSmeBtEvent btEvent; + //The last event we have is success completion event. + //Should not get a creation event before creation. + smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d"), pSyncEvent->connectionHandle); + //Fake a disconnect event + btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE; + btEvent.uEventParam.btDisconnect.connectionHandle = pSyncEvent->connectionHandle; + btcDeferDisconnEvent(pMac, &btEvent); + } + } + //Need to save the new event + if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED) + { + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_CREATE_SYNC_CONNECTION; + vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx], + &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC event overflow")); + } + } + }while(0); + return status; +} + +/*Defer a SYNC completion event + If there is cached event on this BD address, check completion status. + If status is fail and last cached event is creation, remove te creation event and drop + this completion event. + Otherwise, cache this completion event as the latest one. +*/ +static VOS_STATUS btcDeferSyncComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncEventHist pSyncEventHist; + do + { + //Find a match + pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr, + BT_INVALID_CONN_HANDLE ); + if(pSyncEventHist) + { + VOS_ASSERT(pSyncEventHist->bNextEventIdx >0); + //Found one + if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btSyncConnection.status) + { + //If completion fails, and the last one is creation, remove the creation event + if(BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1]) + { + vos_mem_zero(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx-1], + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->bNextEventIdx--; + //Done with this event + break; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC completion fail but last event(%d) not creation"), + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1]); + } + } + } + if(NULL == pSyncEventHist) + { + //In case we don't defer the creation event + pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE ); + } + if(pSyncEventHist) + { + if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + //Save this event + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_SYNC_CONNECTION_COMPLETE; + vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx], + &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + pSyncEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC event overflow")); + } + } + else + { + smsLog(pMac, LOGE, FL(" cannot find match for " + "BT_EVENT_SYNC_CONNECTION_COMPLETE of bdAddr " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pEvent->uEventParam.btSyncConnection.bdAddr)); + status = VOS_STATUS_E_EMPTY; + } + }while(0); + return (status); +} + +//return VOS_STATUS_E_EXISTS if the event handle cannot be found +//VOS_STATUS_SUCCESS if the event is processed +//Other error status meaning it cannot continue due to other errors +/* + Defer a disconnect event for ACL + Check if any history on this event handle. + If both ACL_CREATION and ACL_COMPLETION is cached, remove both those events and drop + this disconnect event. + Otherwise save disconnect event in this ACL's bin. + If not ACL match on this handle, not to do anything. + Either way, remove any cached MODE_CHANGE event matches this disconnect event's handle. +*/ +static VOS_STATUS btcDeferDisconnectEventForACL( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtAclEventHist pAclEventHist; + tpSmeBtAclModeChangeEventHist pModeChangeEventHist; + v_BOOL_t fDone = VOS_FALSE; + int i; + pAclEventHist = btcFindAclEventHist( pMac, NULL, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if(pAclEventHist) + { + if( pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + smsLog(pMac, LOGE, FL(" ACL event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_ACL_DEFERRED"), pAclEventHist->bNextEventIdx); + pAclEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_ACL_DEFERRED; + } + //Looking backwords + for(i = pAclEventHist->bNextEventIdx - 1; i >= 0; i--) + { + if( BT_EVENT_ACL_CONNECTION_COMPLETE == pAclEventHist->btEventType[i] ) + { + //make sure we can cancel the link + if( (i > 0) && (BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[i - 1]) ) + { + fDone = VOS_TRUE; + if(i == 1) + { + //All events can be wiped off + btcReleaseAclEventHist(pMac, pAclEventHist); + break; + } + //we have both ACL creation and completion, wipe out all of them + pAclEventHist->bNextEventIdx = (tANI_U8)(i - 1); + vos_mem_zero(&pAclEventHist->btAclConnection[i-1], sizeof(tSmeBtAclConnectionParam)); + vos_mem_zero(&pAclEventHist->btAclConnection[i], sizeof(tSmeBtAclConnectionParam)); + break; + } + } + }//for loop + if(!fDone) + { + //Save this disconnect event + if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED) + { + pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = + BT_EVENT_DISCONNECTION_COMPLETE; + pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx].connectionHandle = + pEvent->uEventParam.btDisconnect.connectionHandle; + pAclEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" ACL event overflow")); + status = VOS_STATUS_E_FAILURE; + } + } + } + else + { + status = VOS_STATUS_E_EXISTS; + } + //Wipe out the related mode change event if it is there + pModeChangeEventHist = btcFindModeChangeEventHist( pMac, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if( pModeChangeEventHist && pModeChangeEventHist->fValid ) + { + pModeChangeEventHist->fValid = VOS_FALSE; + } + return status; +} + +//This function works the same as btcDeferDisconnectEventForACL except it hanldes SYNC events +//return VOS_STATUS_E_EXISTS if the event handle cannot be found +//VOS_STATUS_SUCCESS if the event is processed +//Other error status meaning it cannot continue due to other errors +/* + Defer a disconnect event for SYNC + Check if any SYNC history on this event handle. + If yes and if both SYNC_CREATION and SYNC_COMPLETION is cached, remove both those events and drop + this disconnect event. + Otherwise save disconnect event in this SYNC's bin. + If no match found, not to save this event here. + Either way, remove any cached SYNC_UPDATE event matches this disconnect event's handle. +*/ +static VOS_STATUS btcDeferDisconnectEventForSync( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncEventHist pSyncEventHist; + tpSmeBtSyncUpdateHist pSyncUpdateHist; + v_BOOL_t fDone = VOS_FALSE; + int i; + pSyncEventHist = btcFindSyncEventHist( pMac, NULL, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if(pSyncEventHist) + { + if( pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED) + { + smsLog(pMac, LOGE, FL(" SYNC event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_SCO_DEFERRED"), pSyncEventHist->bNextEventIdx); + pSyncEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_SCO_DEFERRED; + } + //Looking backwords + for(i = pSyncEventHist->bNextEventIdx - 1; i >= 0; i--) + { + //if a mode change event exists, drop it + if( BT_EVENT_SYNC_CONNECTION_COMPLETE == pSyncEventHist->btEventType[i] ) + { + //make sure we can cancel the link + if( (i > 0) && (BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[i - 1]) ) + { + fDone = VOS_TRUE; + if(i == 1) + { + //All events can be wiped off + btcReleaseSyncEventHist(pMac, pSyncEventHist); + break; + } + //we have both ACL creation and completion, wipe out all of them + pSyncEventHist->bNextEventIdx = (tANI_U8)(i - 1); + vos_mem_zero(&pSyncEventHist->btSyncConnection[i-1], sizeof(tSmeBtSyncConnectionParam)); + vos_mem_zero(&pSyncEventHist->btSyncConnection[i], sizeof(tSmeBtSyncConnectionParam)); + break; + } + } + }//for loop + if(!fDone) + { + //Save this disconnect event + if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED) + { + pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = + BT_EVENT_DISCONNECTION_COMPLETE; + pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx].connectionHandle = + pEvent->uEventParam.btDisconnect.connectionHandle; + pSyncEventHist->bNextEventIdx++; + } + else + { + smsLog(pMac, LOGE, FL(" SYNC event overflow")); + status = VOS_STATUS_E_FAILURE; + } + } + } + else + { + status = VOS_STATUS_E_EXISTS; + } + //Wipe out the related mode change event if it is there + pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if( pSyncUpdateHist && pSyncUpdateHist->fValid ) + { + pSyncUpdateHist->fValid = VOS_FALSE; + } + return status; +} + +/* + Defer a disconnect event. + Try to defer it as part of the ACL event first. + If no match is found, try SYNC. + If still no match found, defer it at DISCONNECT event bin. +*/ +static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtDisconnectEventHist pDisconnEventHist; + if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle ) + { + smsLog( pMac, LOGE, FL(" invalid handle") ); + return (VOS_STATUS_E_INVAL); + } + //Check ACL first + status = btcDeferDisconnectEventForACL(pMac, pEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + status = btcDeferDisconnectEventForSync(pMac, pEvent); + } + if( !VOS_IS_STATUS_SUCCESS(status) ) + { + //Save the disconnect event + pDisconnEventHist = btcFindDisconnEventHist( pMac, + pEvent->uEventParam.btDisconnect.connectionHandle ); + if( pDisconnEventHist ) + { + pDisconnEventHist->fValid = VOS_TRUE; + vos_mem_copy( &pDisconnEventHist->btDisconnect, &pEvent->uEventParam.btDisconnect, + sizeof(tSmeBtDisconnectParam) ); + status = VOS_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_DISCONNECTION_COMPLETE of handle (%d)"), + pEvent->uEventParam.btDisconnect.connectionHandle); + status = VOS_STATUS_E_EMPTY; + } + } + return (status); +} + +/* + btcDeferEvent save the event for possible replay when chip can be accessed + This function is called only when in IMPS/Standby state +*/ +static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpSmeBtSyncUpdateHist pSyncUpdateHist; + tpSmeBtAclModeChangeEventHist pModeChangeEventHist; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + switch(pEvent->btEventType) + { + case BT_EVENT_DEVICE_SWITCHED_ON: + //Clear all events first + vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) ); + pReplay->fBTSwitchOn = VOS_TRUE; + pReplay->fBTSwitchOff = VOS_FALSE; + break; + case BT_EVENT_DEVICE_SWITCHED_OFF: + //Clear all events first + vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) ); + pReplay->fBTSwitchOff = VOS_TRUE; + pReplay->fBTSwitchOn = VOS_FALSE; + break; + case BT_EVENT_INQUIRY_STARTED: + pReplay->btcEventHist.nInquiryEvent++; + break; + case BT_EVENT_INQUIRY_STOPPED: + pReplay->btcEventHist.nInquiryEvent--; + break; + case BT_EVENT_PAGE_STARTED: + pReplay->btcEventHist.nPageEvent++; + break; + case BT_EVENT_PAGE_STOPPED: + pReplay->btcEventHist.nPageEvent--; + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + status = btcDeferAclCreate(pMac, pEvent); + break; + case BT_EVENT_ACL_CONNECTION_COMPLETE: + status = btcDeferAclComplete( pMac, pEvent ); + break; + case BT_EVENT_CREATE_SYNC_CONNECTION: + status = btcDeferSyncCreate(pMac, pEvent); + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + status = btcDeferSyncComplete( pMac, pEvent ); + break; + case BT_EVENT_SYNC_CONNECTION_UPDATED: + if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle ) + { + smsLog( pMac, LOGE, FL(" invalid handle") ); + status = VOS_STATUS_E_INVAL; + break; + } + //Find a match on handle. If not found, get a free slot. + pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac, + pEvent->uEventParam.btSyncConnection.connectionHandle ); + if(pSyncUpdateHist) + { + pSyncUpdateHist->fValid = VOS_TRUE; + vos_mem_copy(&pSyncUpdateHist->btSyncConnection, &pEvent->uEventParam.btSyncConnection, + sizeof(tSmeBtSyncConnectionParam)); + } + else + { + smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_SYNC_CONNECTION_UPDATED of handle (%d)"), + pEvent->uEventParam.btSyncConnection.connectionHandle ); + status = VOS_STATUS_E_EMPTY; + } + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + status = btcDeferDisconnEvent( pMac, pEvent ); + break; + case BT_EVENT_MODE_CHANGED: + if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle ) + { + smsLog( pMac, LOGE, FL(" invalid handle") ); + status = VOS_STATUS_E_INVAL; + break; + } + //Find a match on handle, If not found, return a free slot + pModeChangeEventHist = btcFindModeChangeEventHist( pMac, + pEvent->uEventParam.btAclModeChange.connectionHandle ); + if(pModeChangeEventHist) + { + pModeChangeEventHist->fValid = VOS_TRUE; + vos_mem_copy( &pModeChangeEventHist->btAclModeChange, + &pEvent->uEventParam.btAclModeChange, sizeof(tSmeBtAclModeChangeParam) ); + } + else + { + smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_MODE_CHANGED of handle (%d)"), + pEvent->uEventParam.btAclModeChange.connectionHandle); + status = VOS_STATUS_E_EMPTY; + } + break; + case BT_EVENT_A2DP_STREAM_START: + pReplay->btcEventHist.fA2DPStarted = VOS_TRUE; + pReplay->btcEventHist.fA2DPStopped = VOS_FALSE; + break; + case BT_EVENT_A2DP_STREAM_STOP: + pReplay->btcEventHist.fA2DPStopped = VOS_TRUE; + pReplay->btcEventHist.fA2DPStarted = VOS_FALSE; + break; + default: + smsLog( pMac, LOGE, FL(" event (%d) is not deferred"), pEvent->btEventType ); + status = VOS_STATUS_E_NOSUPPORT; + break; + } + return (status); +} + +/* + Replay all cached events in the following order + 1. If BT_SWITCH_OFF event, send it. + 2. Send INQUIRY event (START or STOP),if available + 3. Send PAGE event (START or STOP), if available + 4. Send DISCONNECT events, these DISCONNECT events are not tied to + any ACL/SYNC event that we have cached + 5. Send ACL events (possible events, CREATION, COMPLETION, DISCONNECT) + 6. Send MODE_CHANGE events, if available + 7. Send A2DP event(START or STOP), if available + 8. Send SYNC events (possible events, CREATION, COMPLETION, DISCONNECT) + 9. Send SYNC_UPDATE events, if available +*/ +static void btcReplayEvents( tpAniSirGlobal pMac ) +{ + int i, j; + tSmeBtEvent btEvent; + tpSmeBtAclEventHist pAclHist; + tpSmeBtSyncEventHist pSyncHist; + tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay; + //Always turn on HB monitor first. + //It is independent of BT events even though BT event causes this + if( pReplay->fRestoreHBMonitor ) + { + pReplay->fRestoreHBMonitor = VOS_FALSE; + //Only do it when needed + if( !pMac->btc.btcHBActive ) + { + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_TRUE; + } + } + if( pMac->btc.fReplayBTEvents ) + { + /*Set the flag to false here so btcSignalBTEvent won't defer any further. + This works because SME has it global lock*/ + pMac->btc.fReplayBTEvents = VOS_FALSE; + if( pReplay->fBTSwitchOff ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_OFF; + btcSendBTEvent( pMac, &btEvent ); + pReplay->fBTSwitchOff = VOS_FALSE; + } + else if( pReplay->fBTSwitchOn ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_ON; + btcSendBTEvent( pMac, &btEvent ); + pReplay->fBTSwitchOn = VOS_FALSE; + } + //Do inquire first + if( pReplay->btcEventHist.nInquiryEvent > 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_INQUIRY_STARTED; + i = pReplay->btcEventHist.nInquiryEvent; + while(i--) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + else if( pReplay->btcEventHist.nInquiryEvent < 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_INQUIRY_STOPPED; + i = pReplay->btcEventHist.nInquiryEvent; + while(i++) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + //Page + if( pReplay->btcEventHist.nPageEvent > 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_PAGE_STARTED; + i = pReplay->btcEventHist.nPageEvent; + while(i--) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + else if( pReplay->btcEventHist.nPageEvent < 0 ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_PAGE_STOPPED; + i = pReplay->btcEventHist.nPageEvent; + while(i++) + { + btcSendBTEvent( pMac, &btEvent ); + } + } + //Replay non-completion disconnect events first + //Disconnect + for( i = 0; i < BT_MAX_DISCONN_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btDisconnectEvent[i].fValid ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE; + vos_mem_copy( &btEvent.uEventParam.btDisconnect, + &pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect, sizeof(tSmeBtDisconnectParam) ); + btcSendBTEvent( pMac, &btEvent ); + } + } + //ACL + for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx ) + { + pAclHist = &pReplay->btcEventHist.btAclConnectionEvent[i]; + //Replay all ACL events for this BD address/handle + for(j = 0; j < pAclHist->bNextEventIdx; j++) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = pAclHist->btEventType[j]; + if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType) + { + //It must be CREATE or CONNECTION_COMPLETE + vos_mem_copy( &btEvent.uEventParam.btAclConnection, + &pAclHist->btAclConnection[j], sizeof(tSmeBtAclConnectionParam) ); + } + else + { + btEvent.uEventParam.btDisconnect.connectionHandle = pAclHist->btAclConnection[j].connectionHandle; + } + btcSendBTEvent( pMac, &btEvent ); + } + } + } + //Mode change + for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_MODE_CHANGED; + vos_mem_copy( &btEvent.uEventParam.btAclModeChange, + &pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange, sizeof(tSmeBtAclModeChangeParam) ); + btcSendBTEvent( pMac, &btEvent ); + } + } + //A2DP + if( pReplay->btcEventHist.fA2DPStarted ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_A2DP_STREAM_START; + btcSendBTEvent( pMac, &btEvent ); + } + else if( pReplay->btcEventHist.fA2DPStopped ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_A2DP_STREAM_STOP; + btcSendBTEvent( pMac, &btEvent ); + } + //SCO + for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx ) + { + pSyncHist = &pReplay->btcEventHist.btSyncConnectionEvent[i]; + //Replay all SYNC events for this BD address/handle + for(j = 0; j < pSyncHist->bNextEventIdx; j++) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = pSyncHist->btEventType[j]; + if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType) + { + //Must be CREATION or CONNECTION_COMPLETE + vos_mem_copy( &btEvent.uEventParam.btSyncConnection, + &pSyncHist->btSyncConnection[j], sizeof(tSmeBtSyncConnectionParam) ); + } + else + { + btEvent.uEventParam.btDisconnect.connectionHandle = pSyncHist->btSyncConnection[j].connectionHandle; + } + btcSendBTEvent( pMac, &btEvent ); + } + } + } + //SYNC update + for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ ) + { + if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid ) + { + vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) ); + btEvent.btEventType = BT_EVENT_SYNC_CONNECTION_UPDATED; + vos_mem_copy( &btEvent.uEventParam.btSyncConnection, + &pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection, + sizeof(tSmeBtSyncConnectionParam) ); + btcSendBTEvent( pMac, &btEvent ); + } + } + //Clear all events + vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) ); + } +} + +static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(pContext); + if( FULL_POWER == pmcState ) + { + btcReplayEvents( pMac ); + } +} + +/* --------------------------------------------------------------------------- + \fn btcLogEvent + \brief API to log the the current Bluetooth event + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtEvent. Caller owns the memory and is responsible + for freeing it. + \return None + ---------------------------------------------------------------------------*/ +static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + v_U8_t bdAddrRev[6]; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Bluetooth Event %d received", __func__, pBtEvent->btEventType); + switch(pBtEvent->btEventType) + { + case BT_EVENT_CREATE_SYNC_CONNECTION: + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "SCO Connection: " + "connectionHandle = %d status = %d linkType %d " + "scoInterval %d scoWindow %d retransmisisonWindow = %d ", + pBtEvent->uEventParam.btSyncConnection.connectionHandle, + pBtEvent->uEventParam.btSyncConnection.status, + pBtEvent->uEventParam.btSyncConnection.linkType, + pBtEvent->uEventParam.btSyncConnection.scoInterval, + pBtEvent->uEventParam.btSyncConnection.scoWindow, + pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow); + + bdAddrRev[0] = pBtEvent->uEventParam.btSyncConnection.bdAddr[5]; + bdAddrRev[1] = pBtEvent->uEventParam.btSyncConnection.bdAddr[4]; + bdAddrRev[2] = pBtEvent->uEventParam.btSyncConnection.bdAddr[3]; + bdAddrRev[3] = pBtEvent->uEventParam.btSyncConnection.bdAddr[2]; + bdAddrRev[4] = pBtEvent->uEventParam.btSyncConnection.bdAddr[1]; + bdAddrRev[5] = pBtEvent->uEventParam.btSyncConnection.bdAddr[0]; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(bdAddrRev)); + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + case BT_EVENT_ACL_CONNECTION_COMPLETE: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Connection: " + "connectionHandle = %d status = %d ", + pBtEvent->uEventParam.btAclConnection.connectionHandle, + pBtEvent->uEventParam.btAclConnection.status); + + bdAddrRev[0] = pBtEvent->uEventParam.btAclConnection.bdAddr[5]; + bdAddrRev[1] = pBtEvent->uEventParam.btAclConnection.bdAddr[4]; + bdAddrRev[2] = pBtEvent->uEventParam.btAclConnection.bdAddr[3]; + bdAddrRev[3] = pBtEvent->uEventParam.btAclConnection.bdAddr[2]; + bdAddrRev[4] = pBtEvent->uEventParam.btAclConnection.bdAddr[1]; + bdAddrRev[5] = pBtEvent->uEventParam.btAclConnection.bdAddr[0]; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(bdAddrRev)); + break; + case BT_EVENT_MODE_CHANGED: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Mode change : " + "connectionHandle %d mode %d ", + pBtEvent->uEventParam.btAclModeChange.connectionHandle, + pBtEvent->uEventParam.btAclModeChange.mode); + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Disconnect Event : " + "connectionHandle %d ", pBtEvent->uEventParam.btAclModeChange.connectionHandle); + break; + default: + break; + } + } + +/* + Caller can check whether BTC's current event allows UAPSD. This doesn't affect + BMPS. + return: VOS_TRUE -- BTC is ready for UAPSD + VOS_FALSE -- certain BT event is active, cannot enter UAPSD +*/ +v_BOOL_t btcIsReadyForUapsd( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return( pMac->btc.btcUapsdOk ); +} + +/* + Base on the BT event, this function sets the flag on whether to allow UAPSD + At this time, we are only interested in SCO and A2DP. + A2DP tracking is through BT_EVENT_A2DP_STREAM_START and BT_EVENT_A2DP_STREAM_STOP + SCO is through BT_EVENT_SYNC_CONNECTION_COMPLETE and BT_EVENT_DISCONNECTION_COMPLETE + BT_EVENT_DEVICE_SWITCHED_OFF overwrites them all +*/ +void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent ) +{ + v_U8_t i; + v_BOOL_t fLastUapsdState = pMac->btc.btcUapsdOk, fMoreSCO = VOS_FALSE; + switch( pBtEvent->btEventType ) + { + case BT_EVENT_DISCONNECTION_COMPLETE: + if( (VOS_FALSE == pMac->btc.btcUapsdOk) && + BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btDisconnect.connectionHandle ) + { + //Check whether all SCO connections are gone + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if( (BT_INVALID_CONN_HANDLE != pMac->btc.btcScoHandles[i]) && + (pMac->btc.btcScoHandles[i] != pBtEvent->uEventParam.btDisconnect.connectionHandle) ) + { + //We still have outstanding SCO connection + fMoreSCO = VOS_TRUE; + } + else if( pMac->btc.btcScoHandles[i] == pBtEvent->uEventParam.btDisconnect.connectionHandle ) + { + pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE; + } + } + if( !fMoreSCO && !pMac->btc.fA2DPUp ) + { + //All SCO is disconnected + smsLog( pMac, LOGE, "BT event (DISCONNECTION) happens, UAPSD-allowed flag (%d) change to TRUE", + pMac->btc.btcUapsdOk ); + pMac->btc.btcUapsdOk = VOS_TRUE; + } + } + break; + case BT_EVENT_DEVICE_SWITCHED_OFF: + smsLog( pMac, LOGE, "BT event (DEVICE_OFF) happens, UAPSD-allowed flag (%d) change to TRUE", + pMac->btc.btcUapsdOk ); + //Clean up SCO + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE; + } + pMac->btc.fA2DPUp = VOS_FALSE; + pMac->btc.btcUapsdOk = VOS_TRUE; + break; + case BT_EVENT_A2DP_STREAM_STOP: + smsLog( pMac, LOGE, "BT event (A2DP_STREAM_STOP) happens, UAPSD-allowed flag (%d)", + pMac->btc.btcUapsdOk ); + pMac->btc.fA2DPUp = VOS_FALSE; + //Check whether SCO is on + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE) + { + break; + } + } + if( BT_MAX_SCO_SUPPORT == i ) + { + pMac->btc.fA2DPTrafStop = VOS_TRUE; + smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_STOP: UAPSD-allowed flag is now %d", + pMac->btc.btcUapsdOk ); + } + break; + + case BT_EVENT_MODE_CHANGED: + smsLog( pMac, LOGE, "BT event (BT_EVENT_MODE_CHANGED) happens, Mode (%d) UAPSD-allowed flag (%d)", + pBtEvent->uEventParam.btAclModeChange.mode, pMac->btc.btcUapsdOk ); + if(pBtEvent->uEventParam.btAclModeChange.mode == BT_ACL_SNIFF) + { + //Check whether SCO is on + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE) + { + break; + } + } + if( BT_MAX_SCO_SUPPORT == i ) + { + if(VOS_TRUE == pMac->btc.fA2DPTrafStop) + { + pMac->btc.btcUapsdOk = VOS_TRUE; + pMac->btc.fA2DPTrafStop = VOS_FALSE; + } + smsLog( pMac, LOGE, "BT_EVENT_MODE_CHANGED with Mode:%d UAPSD-allowed flag is now %d", + pBtEvent->uEventParam.btAclModeChange.mode,pMac->btc.btcUapsdOk ); + } + } + break; + case BT_EVENT_CREATE_SYNC_CONNECTION: + { + pMac->btc.btcUapsdOk = VOS_FALSE; + smsLog( pMac, LOGE, "BT_EVENT_CREATE_SYNC_CONNECTION (%d) happens, UAPSD-allowed flag (%d) change to FALSE", + pBtEvent->btEventType, pMac->btc.btcUapsdOk ); + } + break; + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + //Make sure it is a success + if( BT_CONN_STATUS_FAIL != pBtEvent->uEventParam.btSyncConnection.status ) + { + //Save te handle for later use + for( i = 0; i < BT_MAX_SCO_SUPPORT; i++) + { + VOS_ASSERT(BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle); + if( (BT_INVALID_CONN_HANDLE == pMac->btc.btcScoHandles[i]) && + (BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle)) + { + pMac->btc.btcScoHandles[i] = pBtEvent->uEventParam.btSyncConnection.connectionHandle; + break; + } + } + + if( i >= BT_MAX_SCO_SUPPORT ) + { + smsLog(pMac, LOGE, FL("Too many SCO, ignore this one")); + } + } + else + { + //Check whether SCO is on + for(i=0; i < BT_MAX_SCO_SUPPORT; i++) + { + if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE) + { + break; + } + } + /*If No Other Sco/A2DP is ON reenable UAPSD*/ + if( (BT_MAX_SCO_SUPPORT == i) && !pMac->btc.fA2DPUp) + { + pMac->btc.btcUapsdOk = VOS_TRUE; + } + smsLog(pMac, LOGE, FL("TSYNC complete failed")); + } + break; + case BT_EVENT_A2DP_STREAM_START: + smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_START (%d) happens, UAPSD-allowed flag (%d) change to FALSE", + pBtEvent->btEventType, pMac->btc.btcUapsdOk ); + pMac->btc.fA2DPTrafStop = VOS_FALSE; + pMac->btc.btcUapsdOk = VOS_FALSE; + pMac->btc.fA2DPUp = VOS_TRUE; + break; + default: + //No change for these events + smsLog( pMac, LOGE, "BT event (%d) happens, UAPSD-allowed flag (%d) no change", + pBtEvent->btEventType, pMac->btc.btcUapsdOk ); + break; + } + if(fLastUapsdState != pMac->btc.btcUapsdOk) + { + sme_QosTriggerUapsdChange( pMac ); + } +} + +/* --------------------------------------------------------------------------- + \fn btcHandleCoexInd + \brief API to handle Coex indication from WDI + \param pMac - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_FAILURE success + eHAL_STATUS_SUCCESS failure + ---------------------------------------------------------------------------*/ +eHalStatus btcHandleCoexInd(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeCoexInd *pSmeCoexInd = (tSirSmeCoexInd *)pMsg; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + // DEBUG + smsLog(pMac, LOG1, "Coex indication in %s(), type %d", + __func__, pSmeCoexInd->coexIndType); + + // suspend heartbeat monitoring + if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_HB_MONITOR) + { + // set heartbeat threshold CFG to zero + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_FALSE; + } + + // resume heartbeat monitoring + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_HB_MONITOR) + { + if (!pMac->btc.btcHBActive) + { + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcHBActive = VOS_TRUE; + } + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_SCAN_COMPROMISED) + { + smsLog(pMac, LOGW, + FL("Coex indication SIR_COEX_IND_TYPE_SCAN_COMPROMISED data[0] %d"), + pSmeCoexInd->coexIndData[0]); + + /* coexIndData[0] will be 1 for SCO call and 0 for eSCO call */ + if (pSmeCoexInd->coexIndData[0]) + pMac->btc.btc_scan_compromise_sco = true; + else + pMac->btc.btc_scan_compromise_esco = true; + + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED) + { + pMac->btc.btc_scan_compromise_esco = false; + pMac->btc.btc_scan_compromise_sco = false; + smsLog(pMac, LOGW, "Coex indication in %s(), type - SIR_COEX_IND_TYPE_SCAN_NOT_COMPROMISED", + __func__); + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4) + { + if (pMac->roam.configParam.disableAggWithBtc) + { + ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, 1, + NULL, eANI_BOOLEAN_FALSE); + pMac->btc.btcBssfordisableaggr[0] = pSmeCoexInd->coexIndData[0] & 0xFF; + pMac->btc.btcBssfordisableaggr[1] = pSmeCoexInd->coexIndData[0] >> 8; + pMac->btc.btcBssfordisableaggr[2] = pSmeCoexInd->coexIndData[1] & 0xFF; + pMac->btc.btcBssfordisableaggr[3] = pSmeCoexInd->coexIndData[1] >> 8; + pMac->btc.btcBssfordisableaggr[4] = pSmeCoexInd->coexIndData[2] & 0xFF; + pMac->btc.btcBssfordisableaggr[5] = pSmeCoexInd->coexIndData[2] >> 8; + smsLog(pMac, LOGW, "Coex indication in %s(), " + "type - SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4 " + "for BSSID "MAC_ADDRESS_STR,__func__, + MAC_ADDR_ARRAY(pMac->btc.btcBssfordisableaggr)); + } + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4) + { + if (pMac->roam.configParam.disableAggWithBtc) + { + ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, 0, + NULL, eANI_BOOLEAN_FALSE); + smsLog(pMac, LOGW, + "Coex indication in %s(), type - SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4", + __func__); + } + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_UAPSD) + { + smsLog(pMac, LOG1, FL("DISABLE UAPSD BT Event received")); + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pMac->btc.enableUapsdTimer)) { + smsLog(pMac, LOG1, FL("Stop Uapsd Timer")); + vos_timer_stop(&pMac->btc.enableUapsdTimer); + } + + if (IS_DYNAMIC_WMM_PS_ENABLED) { + if (pMac->btc.btcUapsdOk == VOS_TRUE) { + pMac->btc.btcUapsdOk = VOS_FALSE; + sme_QoSUpdateUapsdBTEvent(pMac); + } + } + + if (pMac->sme.pBtCoexTDLSNotification) + { + smsLog(pMac, LOG1, FL("btCoex notification, Disable TDLS")); + pMac->sme.pBtCoexTDLSNotification(pMac->pAdapter, + SIR_COEX_IND_TYPE_TDLS_DISABLE); + } + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_UAPSD) + { + smsLog(pMac, LOG1, FL("ENABLE UAPSD BT Event received")); + vos_timer_start(&pMac->btc.enableUapsdTimer, + (pMac->fBtcEnableIndTimerVal * 1000)); + } + else if (pSmeCoexInd->coexIndType == + SIR_COEX_IND_TYPE_HID_CONNECTED_WLAN_CONNECTED_IN_2p4) + { + smsLog(pMac, LOG1, + FL("SIR_COEX_IND_TYPE_HID_CONNECTED_WLAN_CONNECTED_IN_2p4")); + vos_set_snoc_high_freq_voting(true); + } + else if (pSmeCoexInd->coexIndType == + SIR_COEX_IND_TYPE_HID_DISCONNECTED_WLAN_CONNECTED_IN_2p4) + { + smsLog(pMac, LOG1, + FL("SIR_COEX_IND_TYPE_HID_DISCONNECTED_WLAN_CONNECTED_IN_2p4")); + vos_set_snoc_high_freq_voting(false); + } + else // unknown indication type + { + smsLog(pMac, LOGE, "unknown Coex indication type in %s()", __func__); + } + } + + return(status); +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/* --------------------------------------------------------------------------- + \fn btcDiagEventLog + \brief API to log the the current Bluetooth event + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtEvent. Caller owns the memory and is responsible + for freeing it. + \return None + ---------------------------------------------------------------------------*/ +static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + //vos_event_wlan_btc_type *log_ptr = NULL; + WLAN_VOS_DIAG_EVENT_DEF(btDiagEvent, vos_event_wlan_btc_type); + { + btDiagEvent.eventId = pBtEvent->btEventType; + switch(pBtEvent->btEventType) + { + case BT_EVENT_CREATE_SYNC_CONNECTION: + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + btDiagEvent.connHandle = pBtEvent->uEventParam.btSyncConnection.connectionHandle; + btDiagEvent.connStatus = pBtEvent->uEventParam.btSyncConnection.status; + btDiagEvent.linkType = pBtEvent->uEventParam.btSyncConnection.linkType; + btDiagEvent.scoInterval = pBtEvent->uEventParam.btSyncConnection.scoInterval; + btDiagEvent.scoWindow = pBtEvent->uEventParam.btSyncConnection.scoWindow; + btDiagEvent.retransWindow = pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow; + vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btSyncConnection.bdAddr, + sizeof(btDiagEvent.btAddr)); + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + case BT_EVENT_ACL_CONNECTION_COMPLETE: + btDiagEvent.connHandle = pBtEvent->uEventParam.btAclConnection.connectionHandle; + btDiagEvent.connStatus = pBtEvent->uEventParam.btAclConnection.status; + vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btAclConnection.bdAddr, + sizeof(btDiagEvent.btAddr)); + break; + case BT_EVENT_MODE_CHANGED: + btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle; + btDiagEvent.mode = pBtEvent->uEventParam.btAclModeChange.mode; + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle; + break; + default: + break; + } + } + WLAN_VOS_DIAG_EVENT_REPORT(&btDiagEvent, EVENT_WLAN_BTC); +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ diff --git a/drivers/staging/prima/CORE/SME/src/ccm/ccmApi.c b/drivers/staging/prima/CORE/SME/src/ccm/ccmApi.c new file mode 100644 index 000000000000..3be9efb086d0 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/ccm/ccmApi.c @@ -0,0 +1,830 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "palTypes.h" +#include "wniApi.h" /* WNI_CFG_SET_REQ */ +#include "sirParams.h" /* tSirMbMsg */ +#include "smsDebug.h" /* smsLog */ +#include "cfgApi.h" +#include "ccmApi.h" +#include "logDump.h" + +//#define CCM_DEBUG +#undef CCM_DEBUG + +#define CCM_DEBUG2 +//#undef CCM_DEBUG2 + +#define CFGOBJ_ALIGNTO 4 +#define CFGOBJ_ALIGN(len) ( ((len)+CFGOBJ_ALIGNTO-1) & ~(CFGOBJ_ALIGNTO-1) ) + +#define CFGOBJ_ID_SIZE 4 /* 4 bytes for cfgId */ +#define CFGOBJ_LEN_SIZE 4 /* 4 bytes for length */ +#define CFGOBJ_INTEGER_VALUE_SIZE 4 /* 4 bytes for integer value */ + +#define CFG_UPDATE_MAGIC_DWORD 0xabab + +#define halHandle2HddHandle(hHal) ( (NULL == (hHal)) ? 0 : ((tpAniSirGlobal)(hHal))->hHdd ) + +static void ccmComplete(tHddHandle hHdd, void *done) +{ + if (done) + { + (void)palSemaphoreGive(hHdd, done); + } +} + +static void ccmWaitForCompletion(tHddHandle hHdd, void *done) +{ + if (done) + { + (void)palSemaphoreTake(hHdd, done); + } +} + +static tANI_U32 * encodeCfgReq(tHddHandle hHdd, tANI_U32 *pl, tANI_U32 cfgId, tANI_S32 length, void *pBuf, tANI_U32 value, tANI_U32 type) +{ + *pl++ = pal_cpu_to_be32(cfgId) ; + *pl++ = pal_cpu_to_be32(length) ; + if (type == CCM_INTEGER_TYPE) + { + *pl++ = pal_cpu_to_be32(value) ; + } + else + { + vos_mem_copy((void *)pl, (void *)pBuf, length); + pl += (CFGOBJ_ALIGN(length) / CFGOBJ_ALIGNTO); + } + return pl ; +} + +/* + * CCM_STRING_TYPE CCM_INTEGER_TYPE + * |<-------- 4 ----->| |<-------- 4 ----->| + * +----------+ <-- msg --> +----------+ + * |type | |type | + * +----------+ +----------+ + * |msgLen=24 | |msgLen=16 | + * +----------+----------+ +----------+----------+ + * | cfgId | | cfgId | + * +---------------------+ +---------------------+ + * | length=11 | | length=4 | + * +---------------------+ +---------------------+ + * | | | value | + * | | +---------------------+ + * | | + * | +----+ + * | |////| <- padding to 4-byte boundary + * +----------------+----+ + */ +static eHalStatus sendCfg(tpAniSirGlobal pMac, tHddHandle hHdd, tCfgReq *req, tANI_BOOLEAN fRsp) +{ + tSirMbMsg *msg; + eHalStatus status; + tANI_S16 msgLen = (tANI_U16)(4 + /* 4 bytes for msg header */ + CFGOBJ_ID_SIZE + + CFGOBJ_LEN_SIZE + + CFGOBJ_ALIGN(req->length)) ; + + msg = vos_mem_malloc(msgLen); + if ( NULL != msg ) + { + if( fRsp ) + { + msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ); + } + else + { + msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ_NO_RSP); + } + msg->msgLen = pal_cpu_to_be16(msgLen); + (void)encodeCfgReq(hHdd, msg->data, req->cfgId, req->length, req->ccmPtr, req->ccmValue, req->type) ; + + status = palSendMBMessage(hHdd, msg) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("palSendMBMessage() failed")); + //No need to free msg. palSendMBMessage frees it. + status = eHAL_STATUS_FAILURE ; + } + } + else + { + smsLog( pMac, LOGW, FL("failed to allocate memory(len=%d)"), msgLen ); + status = eHAL_STATUS_FAILURE; + } + + return status ; +} + +static tCfgReq * allocateCfgReq(tHddHandle hHdd, tANI_U32 type, tANI_S32 length) +{ + tCfgReq *req ; + tANI_S32 alloc_len = sizeof(tCfgReq) ; + + if (type == CCM_STRING_TYPE) + { + alloc_len += length ; + } + + req = vos_mem_malloc(alloc_len); + if ( NULL == req ) + { + return NULL ; + } + + req->ccmPtr = (req+1); + + return req ; +} + +static void freeCfgReq(tHddHandle hHdd, tCfgReq *req) +{ + vos_mem_free(req); +} + +static void add_req_tail(tCfgReq *req, struct ccmlink *q) +{ + if (q->tail) + { + q->tail->next = req; + q->tail = req ; + } + else + { + q->head = q->tail = req ; + } +} + +static void del_req(tCfgReq *req, struct ccmlink *q) +{ + q->head = req->next ; + req->next = NULL ; + if (q->head == NULL) + { + q->tail = NULL ; + } +} + +static void purgeReqQ(tHalHandle hHal) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCfgReq *req, *tmp ; + + for (req = pMac->ccm.reqQ.head; req; req = tmp) + { + /* loop thru reqQ and invoke callback to return failure */ + smsLog(pMac, LOGW, FL("deleting cfgReq, cfgid=%d"), (int)req->cfgId); + + tmp = req->next ; + + if (req->callback) + { + req->callback(hHal, eHAL_STATUS_FAILURE); + } + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ); + palSpinLockGive(hHdd, pMac->ccm.lock); + freeCfgReq(hHdd, req); + } + return ; +} + +static void sendQueuedReqToMacSw(tpAniSirGlobal pMac, tHddHandle hHdd) +{ + tCfgReq *req ; + + /* Send the head req */ + req = pMac->ccm.reqQ.head ; + if (req) + { + if (req->state == eCCM_REQ_QUEUED) + { + /* Send WNI_CFG_SET_REQ */ + req->state = eCCM_REQ_SENT; + if (sendCfg(pMac, hHdd, req, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("sendCfg() failed")); + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ) ; + palSpinLockGive(hHdd, pMac->ccm.lock); + if (req->callback) + { + req->callback((tHalHandle)pMac, WNI_CFG_OTHER_ERROR) ; + } + +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); +#endif + ccmComplete(hHdd, req->done); + + freeCfgReq(hHdd, req); + } + } + else + { + smsLog( pMac, LOGW, FL("reqState is not eCCM_REQ_QUEUED, is %d"), req->state ); + } + } + + return ; +} + +static eHalStatus cfgSetSub(tpAniSirGlobal pMac, tHddHandle hHdd, tANI_U32 cfgId, tANI_U32 type, + tANI_S32 length, void *ccmPtr, tANI_U32 ccmValue, + tCcmCfgSetCallback callback, eAniBoolean toBeSaved, void *sem, tCfgReq **r) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCfgReq *req ; + + do + { + *r = NULL ; + + if (pMac->ccm.state == eCCM_STOPPED) + { + status = eHAL_STATUS_FAILURE ; + break ; + } + + req = allocateCfgReq(hHdd, type, length); + if (req == NULL) + { + status = eHAL_STATUS_FAILED_ALLOC ; + break ; + } + + req->next = NULL ; + req->cfgId = (tANI_U16)cfgId ; + req->type = (tANI_U8)type ; + req->state = eCCM_REQ_QUEUED ; + req->toBeSaved = !!toBeSaved ; + req->length = length ; + req->done = sem ; + req->callback = callback ; + if (type == CCM_INTEGER_TYPE) + { + req->ccmValue = ccmValue ; + } + else + { + vos_mem_copy((void *)req->ccmPtr, (void *)ccmPtr, length); + } + + palSpinLockTake(hHdd, pMac->ccm.lock); + + add_req_tail(req, &pMac->ccm.reqQ); + /* If this is the first req on the queue, send it to MAC SW */ + if ((pMac->ccm.replay.started == 0) && (pMac->ccm.reqQ.head == req)) + { + /* Send WNI_CFG_SET_REQ */ + req->state = eCCM_REQ_SENT; + palSpinLockGive(hHdd, pMac->ccm.lock); + status = sendCfg(pMac, hHdd, req, eANI_BOOLEAN_TRUE) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("sendCfg() failed")); + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ); + palSpinLockGive(hHdd, pMac->ccm.lock); + freeCfgReq(hHdd, req); + break ; + } + else + { + palSpinLockTake(hHdd, pMac->ccm.lock); + if(req != pMac->ccm.reqQ.head) + { + //We send the request and it must be done already + req = NULL; + } + palSpinLockGive(hHdd, pMac->ccm.lock); + } + } + else + { + palSpinLockGive(hHdd, pMac->ccm.lock); + } + *r = req ; + + } while(0) ; + + return status; +} + +static eHalStatus cfgSet(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 type, tANI_S32 length, void * ccmPtr, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + tCfgReq *req ; + + if (pal_in_interrupt()) + { +#ifdef CCM_DEBUG2 + smsLog(pMac, LOG1, FL("WNI_CFG_%s (%d 0x%x), in_interrupt()=TRUE"), gCfgParamName[cfgId], (int)cfgId, (int)cfgId); +#endif + status = cfgSetSub(pMac, hHdd, cfgId, type, length, ccmPtr, ccmValue, callback, toBeSaved, NULL, &req); + } + else + { + void *sem ; + +#ifdef CCM_DEBUG2 + smsLog(pMac, LOG1, FL("WNI_CFG_%s (%d 0x%x), in_interrupt()=FALSE"), gCfgParamName[cfgId], (int)cfgId, (int)cfgId); +#endif + pal_local_bh_disable() ; + + status = palMutexAllocLocked( hHdd, &sem ) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("mutex alloc failed")); + sem = NULL; + } + else + { + status = cfgSetSub(pMac, hHdd, cfgId, type, length, ccmPtr, ccmValue, callback, toBeSaved, sem, &req); + if ((status != eHAL_STATUS_SUCCESS) || (req == NULL)) + { + //Either it fails to send or the req is finished already + palSemaphoreFree( hHdd, sem ); + sem = NULL; + } + } + + pal_local_bh_enable() ; + + if ((status == eHAL_STATUS_SUCCESS) && (sem != NULL)) + { +#ifdef CCM_DEBUG + smsLog(pMac, LOG1, FL("ccmWaitForCompletion(%p)"), req->done); +#endif + ccmWaitForCompletion(hHdd, sem); + +#ifdef CCM_DEBUG + smsLog(pMac, LOG1, FL("free(%p)"), req->done); +#endif + palSemaphoreFree( hHdd, sem ) ; + } + } + + return status ; +} + +eHalStatus ccmOpen(tHalHandle hHal) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + vos_mem_set(&pMac->ccm, sizeof(tCcm), 0); + return palSpinLockAlloc(hHdd, &pMac->ccm.lock); +} + +eHalStatus ccmClose(tHalHandle hHal) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 i ; + tCfgReq *req ; + + ccmStop(hHal); + + /* Go thru comp[] to free all saved requests */ + for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) + { + if ((req = pMac->ccm.comp[i]) != NULL) + { + freeCfgReq(hHdd, req); + } + } + + return palSpinLockFree(hHdd, pMac->ccm.lock); +} + +/* This function executes in (Linux) softirq context */ +void ccmCfgCnfMsgHandler(tHalHandle hHal, void *m) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSirMbMsg *msg = (tSirMbMsg *)m ; + tANI_U32 result, cfgId ; + tCfgReq *req, *old ; + +#if 0 + if (pMac->ccm.state != eCCM_STARTED) + { + return ; + } +#endif + + result = pal_be32_to_cpu(msg->data[0]); + cfgId = pal_be32_to_cpu(msg->data[1]); + + if (pMac->ccm.replay.started && cfgId == CFG_UPDATE_MAGIC_DWORD) + { + pMac->ccm.replay.in_progress = 1 ; + return ; + } + + if (pMac->ccm.replay.in_progress) + { + /* save error code */ + if (!CCM_IS_RESULT_SUCCESS(result)) + { + pMac->ccm.replay.result = result ; + } + + if (--pMac->ccm.replay.nr_param == 0) + { + pMac->ccm.replay.in_progress = 0 ; + + if (pMac->ccm.replay.callback) + { + pMac->ccm.replay.callback(hHal, pMac->ccm.replay.result); + } + + pMac->ccm.replay.started = 0 ; + + /* Wake up the sleeping process */ +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmComplete(%p)"), pMac->ccm.replay.done); +#endif + ccmComplete(hHdd, pMac->ccm.replay.done); + //Let go with the rest of the set CFGs waiting. + sendQueuedReqToMacSw(pMac, hHdd); + } + } + else + { + /* + * Try to match this response with the request. + * What if i could not find the req entry ??? + */ + req = pMac->ccm.reqQ.head ; + if (req) + { + + if (req->cfgId == cfgId && req->state == eCCM_REQ_SENT) + { + palSpinLockTake(hHdd, pMac->ccm.lock); + del_req(req, &pMac->ccm.reqQ); + palSpinLockGive(hHdd, pMac->ccm.lock); + req->state = eCCM_REQ_DONE ; + + if (result == WNI_CFG_NEED_RESTART || + result == WNI_CFG_NEED_RELOAD) + { +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("need restart/reload, cfgId=%d"), req->cfgId) ; +#endif + //purgeReqQ(hHal); + } + + /* invoke callback */ + if (req->callback) + { +#ifdef CCM_DEBUG + req->callback(hHal, cfgId) ; +#else + req->callback(hHal, result) ; +#endif + } + + /* Wake up the sleeping process */ +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("cfgId=%ld, calling ccmComplete(%p)"), cfgId, req->done); +#endif + ccmComplete(hHdd, req->done); + + /* move the completed req from reqQ to comp[] */ + if (req->toBeSaved && (CCM_IS_RESULT_SUCCESS(result))) + { + if (cfgId < CFG_PARAM_MAX_NUM) + { + if ((old = pMac->ccm.comp[cfgId]) != NULL) + { + freeCfgReq(hHdd, old) ; + } + pMac->ccm.comp[cfgId] = req ; + } + } + else + { + freeCfgReq(hHdd, req) ; + } + sendQueuedReqToMacSw(pMac, hHdd); + } + else + { + smsLog( pMac, LOGW, FL("can not match RSP with REQ, rspcfgid=%d result=%d reqcfgid=%d reqstate=%d"), + (int)cfgId, (int)result, req->cfgId, req->state); + +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmComplete(%p)"), req->done); +#endif + } + + } + } + + return ; +} + +void ccmStart(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->ccm.state = eCCM_STARTED ; + +#if defined(ANI_LOGDUMP) + ccmDumpInit(hHal); +#endif //#if defined(ANI_LOGDUMP) + + return ; +} + +void ccmStop(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->ccm.state = eCCM_STOPPED ; + + pal_local_bh_disable() ; + purgeReqQ(hHal); + pal_local_bh_enable() ; + + return ; +} + +eHalStatus ccmCfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + if( callback || toBeSaved) + { + //we need to sychronous this one + return cfgSet(hHal, cfgId, CCM_INTEGER_TYPE, sizeof(tANI_U32), NULL, ccmValue, callback, toBeSaved); + } + else + { + //Simply push to CFG and not waiting for the response + tCfgReq req; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + req.callback = NULL; + req.next = NULL; + req.cfgId = ( tANI_U16 )cfgId; + req.length = sizeof( tANI_U32 ); + req.type = CCM_INTEGER_TYPE; + req.ccmPtr = NULL; + req.ccmValue = ccmValue; + req.toBeSaved = toBeSaved; + req.state = eCCM_REQ_SENT; + + return ( sendCfg( pMac, pMac->hHdd, &req, eANI_BOOLEAN_FALSE ) ); + } +} + +eHalStatus ccmCfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, tANI_U32 length, tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + if( callback || toBeSaved ) + { + //we need to sychronous this one + return cfgSet(hHal, cfgId, CCM_STRING_TYPE, length, pStr, 0, callback, toBeSaved); + } + else + { + //Simply push to CFG and not waiting for the response + tCfgReq req; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + req.callback = NULL; + req.next = NULL; + req.cfgId = ( tANI_U16 )cfgId; + req.length = length; + req.type = CCM_STRING_TYPE; + req.ccmPtr = pStr; + req.ccmValue = 0; + req.toBeSaved = toBeSaved; + req.state = eCCM_REQ_SENT; + + return ( sendCfg( pMac, pMac->hHdd, &req, eANI_BOOLEAN_FALSE ) ); + } +} + +eHalStatus ccmCfgGetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 *pValue) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS ; + tCfgReq *req = pMac->ccm.comp[cfgId] ; + + if (req && req->state == eCCM_REQ_DONE) + { + *pValue = req->ccmValue ; + } + else + { + if (wlan_cfgGetInt(pMac, (tANI_U16)cfgId, pValue) != eSIR_SUCCESS) + status = eHAL_STATUS_FAILURE; + } + + return status ; +} + +eHalStatus ccmCfgGetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pBuf, tANI_U32 *pLength) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tHddHandle hHdd; + eHalStatus status = eHAL_STATUS_SUCCESS ; + tCfgReq *req; + + if (!pMac) + return eHAL_STATUS_FAILURE; + + hHdd = halHandle2HddHandle(hHal); + req = pMac->ccm.comp[cfgId] ; + + if (req && req->state == eCCM_REQ_DONE && (tANI_U32)req->length <= *pLength) + { + *pLength = req->length ; + vos_mem_copy((void *)pBuf, (void *)req->ccmPtr, req->length); + } + else + { + if (wlan_cfgGetStr(pMac, (tANI_U16)cfgId, pBuf, pLength) != eSIR_SUCCESS) + status = eHAL_STATUS_FAILURE; + } + + return status ; +} + +/* + * Loop thru comp[] and form an ANI message which contains all completed cfgIds. + * The message begins with an INTEGER parameter (cfgId=CFG_UPDATE_MAGIC_DWORD) + * to mark the start of the message. + */ +static eHalStatus cfgUpdate(tpAniSirGlobal pMac, tHddHandle hHdd, tCcmCfgSetCallback callback) +{ + tANI_U32 i, *pl ; + tCfgReq *req ; + tSirMbMsg *msg ; + eHalStatus status ; + tANI_S16 msgLen = 4 + /* 4 bytes for msg header */ + /* for CFG_UPDATE_MAGIC_DWORD */ + CFGOBJ_ID_SIZE + + CFGOBJ_LEN_SIZE + + CFGOBJ_INTEGER_VALUE_SIZE ; + + if (pMac->ccm.state == eCCM_STOPPED || pMac->ccm.replay.started) + { + status = eHAL_STATUS_FAILURE ; + goto end ; + } + + palSpinLockTake(hHdd, pMac->ccm.lock); + + pMac->ccm.replay.started = 1 ; + pMac->ccm.replay.nr_param = 0 ; + + palSpinLockGive(hHdd, pMac->ccm.lock); + + /* Calculate message length */ + for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) + { + if ((req = pMac->ccm.comp[i]) != NULL) + { + msgLen += (tANI_S16)(CFGOBJ_ID_SIZE + CFGOBJ_LEN_SIZE + CFGOBJ_ALIGN(req->length)) ; + pMac->ccm.replay.nr_param += 1 ; +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("cfgId=%d"), req->cfgId); +#endif + } + } + + if (pMac->ccm.replay.nr_param == 0) + { + if (callback) + { + callback((tHalHandle)pMac, WNI_CFG_SUCCESS) ; + } + status = eHAL_STATUS_SUCCESS ; + goto end ; + } + + pMac->ccm.replay.in_progress = 0 ; + pMac->ccm.replay.result = WNI_CFG_SUCCESS ; + pMac->ccm.replay.callback = callback ; + pMac->ccm.replay.done = NULL ; + + msg = vos_mem_malloc(msgLen); + if ( NULL == msg ) + { + pMac->ccm.replay.started = 0 ; + status = eHAL_STATUS_FAILURE; + goto end; + } + + msg->type = pal_cpu_to_be16(WNI_CFG_SET_REQ); + msg->msgLen = pal_cpu_to_be16(msgLen); + + /* Encode the starting cfgId */ + pl = encodeCfgReq(hHdd, msg->data, CFG_UPDATE_MAGIC_DWORD, 4, NULL, 0, CCM_INTEGER_TYPE) ; + + /* Encode the saved cfg requests */ + for (i = 0 ; i < CFG_PARAM_MAX_NUM ; ++i) + { + if ((req = pMac->ccm.comp[i]) != NULL) + { + pl = encodeCfgReq(hHdd, pl, req->cfgId, req->length, req->ccmPtr, req->ccmValue, req->type) ; + } + } + + status = palSendMBMessage(hHdd, msg) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGW, FL("palSendMBMessage() failed. status=%d"), status); + pMac->ccm.replay.started = 0 ; + //No need to free msg. palSendMBMessage frees it. + goto end ; + } + + end: + return status ; +} + +eHalStatus ccmCfgUpdate(tHalHandle hHal, tCcmCfgSetCallback callback) +{ + tHddHandle hHdd = halHandle2HddHandle(hHal); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status ; + + pal_local_bh_disable() ; + + status = cfgUpdate(pMac, hHdd, callback) ; + if (status == eHAL_STATUS_SUCCESS) + { + if (pMac->ccm.replay.nr_param == 0) + { + /* there is nothing saved at comp[], so we are done! */ + pMac->ccm.replay.started = 0 ; + } + else + { + /* we have sent update message to MAC SW */ + void *sem ; + + status = palMutexAllocLocked( hHdd, &sem ) ; + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("mutex alloc failed")); + pMac->ccm.replay.started = 0 ; + } + else + { + pMac->ccm.replay.done = sem ; + } + } + } + + pal_local_bh_enable() ; + + /* Waiting here ... */ + if (status == eHAL_STATUS_SUCCESS && pMac->ccm.replay.done) + { +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("ccmWaitForCompletion(%p)"), pMac->ccm.replay.done); +#endif + ccmWaitForCompletion(hHdd, pMac->ccm.replay.done); + +#ifdef CCM_DEBUG + smsLog(pMac, LOGW, FL("free(%p)"), pMac->ccm.replay.done); +#endif + palSemaphoreFree( hHdd, pMac->ccm.replay.done) ; + } + + return status ; +} + diff --git a/drivers/staging/prima/CORE/SME/src/ccm/ccmLogDump.c b/drivers/staging/prima/CORE/SME/src/ccm/ccmLogDump.c new file mode 100644 index 000000000000..ac24fa8a55d9 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/ccm/ccmLogDump.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ +ccmLogDump.c + +Implements the dump commands specific to the ccm module. + + ============================================================================*/ + + +#include "aniGlobal.h" +#include "logDump.h" + +#if defined(ANI_LOGDUMP) + +static tDumpFuncEntry ccmMenuDumpTable[] = { + + {0, "CCM (861-870)", NULL}, + //{861, "CCM: CCM testing ", dump_ccm} + +}; + +void ccmDumpInit(tHalHandle hHal) +{ + logDumpRegisterTable( (tpAniSirGlobal) hHal, &ccmMenuDumpTable[0], + sizeof(ccmMenuDumpTable)/sizeof(ccmMenuDumpTable[0]) ); +} + +#endif //#if defined(ANI_LOGDUMP) + diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c b/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c new file mode 100644 index 000000000000..074fc3da6124 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrApiRoam.c @@ -0,0 +1,19650 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrApiRoam.c + + Implementation for the Common Roaming interfaces. + + Copyright (C) 2008 Qualcomm, Incorporated + + + ========================================================================== */ +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + when who what, where, why +---------- --- -------------------------------------------------------- +06/03/10 js Added support to hostapd driven + * deauth/disassoc/mic failure +===========================================================================*/ +#include "aniGlobal.h" //for tpAniSirGlobal +#include "wlan_qct_wda.h" +#include "halMsgApi.h" //for HAL_STA_INVALID_IDX. +#include "limUtils.h" +#include "palApi.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "sme_Trace.h" +#include "logDump.h" +#include "smeQosInternal.h" +#include "wlan_qct_tl.h" +#include "smeInside.h" +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#include "csrApi.h" +#include "pmc.h" +#include "vos_nvitem.h" +#include "macTrace.h" +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "csrNeighborRoam.h" +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD */ +#include "vos_utils.h" +#ifdef WLAN_FEATURE_LFR_MBB +#include "csr_roam_mbb.h" +#endif + + +#define CSR_NUM_IBSS_START_CHANNELS_50 4 +#define CSR_NUM_IBSS_START_CHANNELS_24 3 +#define CSR_DEF_IBSS_START_CHANNEL_50 36 +#define CSR_DEF_IBSS_START_CHANNEL_24 1 + +/*--------------------------------------------------------------------------- + OBIWAN recommends [8 10]% : pick 9% +---------------------------------------------------------------------------*/ +#define CSR_VCC_UL_MAC_LOSS_THRESHOLD 9 +/*--------------------------------------------------------------------------- + OBIWAN recommends -85dBm +---------------------------------------------------------------------------*/ +#define CSR_VCC_RSSI_THRESHOLD 80 +#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD 500 //ms +#define CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS 2000 //ms +#define CSR_MIN_TL_STAT_QUERY_PERIOD 500 //ms +#define CSR_DIAG_LOG_STAT_PERIOD 3000 //ms +//We use constatnt 4 here +//This macro returns true when higher AC parameter is bigger than lower AC for a difference +//The bigger the number, the less chance of TX +//It must put lower AC as the first parameter. +#define SME_DETECT_AC_WEIGHT_DIFF(loAC, hiAC) (v_BOOL_t)(((hiAC) > (loAC)) ? (((hiAC)-(loAC)) > 4) : 0) +//Flag to send/do not send disassoc frame over the air +#define CSR_DONT_SEND_DISASSOC_OVER_THE_AIR 1 +#define RSSI_HACK_BMPS (-40) +#define MAX_CB_VALUE_IN_INI (2) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +static tANI_BOOLEAN bRoamScanOffloadStarted = VOS_FALSE; +#endif + +#define MAX_PWR_FCC_CHAN_12 8 +#define MAX_PWR_FCC_CHAN_13 2 + +/*-------------------------------------------------------------------------- + Static Type declarations + ------------------------------------------------------------------------*/ +static tCsrRoamSession csrRoamRoamSession[CSR_ROAM_SESSION_MAX]; + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +int diagAuthTypeFromCSRType(eCsrAuthType authType) +{ + int n = AUTH_OPEN; + switch(authType) + { + case eCSR_AUTH_TYPE_SHARED_KEY: + n = AUTH_SHARED; + break; + case eCSR_AUTH_TYPE_WPA: + n = AUTH_WPA_EAP; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + n = AUTH_WPA_PSK; + break; + case eCSR_AUTH_TYPE_RSN: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + n = AUTH_WPA2_EAP; + break; + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: +#endif + n = AUTH_WPA2_PSK; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + n = AUTH_WAPI_CERT; + break; + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + n = AUTH_WAPI_PSK; + break; +#endif /* FEATURE_WLAN_WAPI */ + default: + break; + } + return (n); +} +int diagEncTypeFromCSRType(eCsrEncryptionType encType) +{ + int n = ENC_MODE_OPEN; + switch(encType) + { + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + n = ENC_MODE_WEP40; + break; + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + n = ENC_MODE_WEP104; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + n = ENC_MODE_TKIP; + break; + case eCSR_ENCRYPT_TYPE_AES: + n = ENC_MODE_AES; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + n = ENC_MODE_SMS4; + break; +#endif /* FEATURE_WLAN_WAPI */ + default: + break; + } + return (n); +} +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +static const tANI_U8 csrStartIbssChannels50[ CSR_NUM_IBSS_START_CHANNELS_50 ] = { 36, 40, 44, 48}; +static const tANI_U8 csrStartIbssChannels24[ CSR_NUM_IBSS_START_CHANNELS_24 ] = { 1, 6, 11 }; +static void initConfigParam(tpAniSirGlobal pMac); +static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, + eCsrRoamCompleteResult Result, void *Context ); +static eHalStatus csrRoamStartIbss( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamProfile *pProfile, + tANI_BOOLEAN *pfSameIbss ); +static void csrRoamUpdateConnectedProfileFromNewBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirSmeNewBssInfo *pNewBss ); +static void csrRoamPrepareBssParams(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, tDot11fBeaconIEs *pIes); +static ePhyChanBondState csrGetCBModeFromIes(tpAniSirGlobal pMac, tANI_U8 primaryChn, tDot11fBeaconIEs *pIes); +eHalStatus csrInitGetChannels(tpAniSirGlobal pMac); +static void csrRoamingStateConfigCnfProcessor( tpAniSirGlobal pMac, tANI_U32 result ); +eHalStatus csrRoamOpen(tpAniSirGlobal pMac); +eHalStatus csrRoamClose(tpAniSirGlobal pMac); +void csrRoamMICErrorTimerHandler(void *pv); +void csrRoamTKIPCounterMeasureTimerHandler(void *pv); +tANI_BOOLEAN csrRoamIsSameProfileKeys(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pConnProfile, tCsrRoamProfile *pProfile2); + +static eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval); +static eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId); +static void csrRoamRoamingTimerHandler(void *pv); +eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac); +static void csrRoamWaitForKeyTimeOutHandler(void *pv); +static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo); +static eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo); +eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U8 keyLength, tANI_U8 *pKey, tANI_U8 paeRole, + tANI_U8 *pKeyRsc ); +static eHalStatus csrRoamIssueReassociate( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, + tCsrRoamProfile *pProfile ); +void csrRoamStatisticsTimerHandler(void *pv); +void csrRoamStatsGlobalClassDTimerHandler(void *pv); +VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal, + v_U8_t rssiNotification, + void * context); +static void csrRoamLinkDown(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrRoamVccTrigger(tpAniSirGlobal pMac); +eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, tANI_U8 staId); +/* + pStaEntry is no longer invalid upon the return of this function. +*/ +static void csrRoamRemoveStatListEntry(tpAniSirGlobal pMac, tListElem *pEntry); +static eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile,tANI_U8 operationChn, eCsrBand *pBand ); +static eHalStatus csrRoamGetQosInfoFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc); +tCsrStatsClientReqInfo * csrRoamInsertEntryIntoList( tpAniSirGlobal pMac, + tDblLinkList *pStaList, + tCsrStatsClientReqInfo *pStaEntry); +void csrRoamStatsClientTimerHandler(void *pv); +tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask, + tANI_U32 periodicity, tANI_BOOLEAN *pFound, tANI_U8 staId); +void csrRoamReportStatistics(tpAniSirGlobal pMac, tANI_U32 statsMask, + tCsrStatsCallback callback, tANI_U8 staId, void *pContext); +void csrRoamSaveStatsFromTl(tpAniSirGlobal pMac, WLANTL_TRANSFER_STA_TYPE *pTlStats); +void csrRoamTlStatsTimerHandler(void *pv); +void csrRoamPeStatsTimerHandler(void *pv); +tListElem * csrRoamCheckClientReqList(tpAniSirGlobal pMac, tANI_U32 statsMask); +void csrRoamRemoveEntryFromPeStatsReqList(tpAniSirGlobal pMac, tCsrPeStatsReqInfo *pPeStaEntry); +tListElem * csrRoamFindInPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask); +eHalStatus csrRoamDeregStatisticsReq(tpAniSirGlobal pMac); +static tANI_U32 csrFindIbssSession( tpAniSirGlobal pMac ); +static eHalStatus csrRoamStartWds( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc ); +static void csrInitSession( tpAniSirGlobal pMac, tANI_U32 sessionId ); +static eHalStatus csrRoamIssueSetKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamSetKey *pSetKey, tANI_U32 roamId ); +//static eHalStatus csrRoamProcessStopBss( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +static eHalStatus csrRoamGetQosInfoFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc); +void csrRoamReissueRoamCommand(tpAniSirGlobal pMac); +#ifdef FEATURE_WLAN_BTAMP_UT_RF +void csrRoamJoinRetryTimerHandler(void *pv); +#endif +void limInitOperatingClasses( tHalHandle hHal ); +extern void SysProcessMmhMsg(tpAniSirGlobal pMac, tSirMsgQ* pMsg); +extern void btampEstablishLogLinkHdlr(void* pMsg); +static void csrSerDesUnpackDiassocRsp(tANI_U8 *pBuf, tSirSmeDisassocRsp *pRsp); +void csrReinitPreauthCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); + +//Initialize global variables +static void csrRoamInitGlobals(tpAniSirGlobal pMac) +{ + if(pMac) + { + vos_mem_zero(&csrRoamRoamSession, sizeof(csrRoamRoamSession)); + pMac->roam.roamSession = csrRoamRoamSession; + } + return; +} + +static void csrRoamDeInitGlobals(tpAniSirGlobal pMac) +{ + if(pMac) + { + pMac->roam.roamSession = NULL; + } + return; +} +eHalStatus csrOpen(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; +#ifndef CONFIG_ENABLE_LINUX_REG + static uNvTables nvTables; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_REGDOMAIN_t regId; +#endif + tANI_U32 i; + + do + { + /* Initialize CSR Roam Globals */ + csrRoamInitGlobals(pMac); + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_STOP, i); + + initConfigParam(pMac); + if(!HAL_STATUS_SUCCESS((status = csrScanOpen(pMac)))) + break; + if(!HAL_STATUS_SUCCESS((status = csrRoamOpen(pMac)))) + break; + pMac->roam.nextRoamId = 1; //Must not be 0 + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &pMac->roam.statsClientReqList))) + break; + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &pMac->roam.peStatsReqList))) + break; + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &pMac->roam.roamCmdPendingList))) + break; + +#ifndef CONFIG_ENABLE_LINUX_REG + vosStatus = vos_nv_readDefaultCountryTable( &nvTables ); + if ( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_copy(pMac->scan.countryCodeDefault, nvTables.defaultCountryTable.countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGE, FL(" fail to get NV_FIELD_IMAGE") ); + //hardcoded for now + pMac->scan.countryCodeDefault[0] = 'U'; + pMac->scan.countryCodeDefault[1] = 'S'; + pMac->scan.countryCodeDefault[2] = 'I'; + //status = eHAL_STATUS_SUCCESS; + } + smsLog( pMac, LOG1, FL(" country Code from nvRam %.2s"), pMac->scan.countryCodeDefault ); + + if (!('0' == pMac->scan.countryCodeDefault[0] && + '0' == pMac->scan.countryCodeDefault[1])) + { + csrGetRegulatoryDomainForCountry(pMac, pMac->scan.countryCodeDefault, + ®Id, COUNTRY_NV); + } + else + { + regId = REGDOMAIN_WORLD; + } + WDA_SetRegDomain(pMac, regId, eSIR_TRUE); + pMac->scan.domainIdDefault = regId; + pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault; + vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + status = csrInitGetChannels( pMac ); +#endif + }while(0); + + return (status); +} + +/* -------------------------------------------------------------------------- + \fn csrInitChannels + \brief This function must be called to initialize CSR channel lists + \return eHalStatus + ----------------------------------------------------------------------------*/ +eHalStatus csrInitChannels(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + static uNvTables nvTables; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_REGDOMAIN_t regId = REGDOMAIN_WORLD; + + vosStatus = vos_nv_readDefaultCountryTable( &nvTables ); + if ( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_copy(pMac->scan.countryCodeDefault, + nvTables.defaultCountryTable.countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + else + { + smsLog( pMac, LOGE, FL(" fail to get NV_FIELD_IMAGE") ); + //hardcoded for now + pMac->scan.countryCodeDefault[0] = 'U'; + pMac->scan.countryCodeDefault[1] = 'S'; + pMac->scan.countryCodeDefault[2] = 'I'; + } + smsLog( pMac, LOG1, FL(" country Code from nvRam %.2s"), pMac->scan.countryCodeDefault ); + + WDA_SetRegDomain(pMac, regId, eSIR_TRUE); + pMac->scan.domainIdDefault = regId; + pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault; + vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCodeElected, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCode11d, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + status = csrInitGetChannels( pMac ); + csrClearVotesForCountryInfo(pMac); + + return status; +} + +#ifdef CONFIG_ENABLE_LINUX_REG +eHalStatus csrInitChannelsForCC(tpAniSirGlobal pMac, driver_load_type init) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + v_REGDOMAIN_t regId = REGDOMAIN_WORLD; + tANI_U8 cc[WNI_CFG_COUNTRY_CODE_LEN]; + + /* In case of driver load ; driver need to get channel + * list with default Countrycode. + * In case of SSR; driver need to get channel list + * with old country code. 0 is for init and + * 1 is for reinit + */ + switch (init) + { + case INIT: + vos_mem_copy(cc, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + if (!('0' == cc[0] && + '0' == cc[1])) + { + csrGetRegulatoryDomainForCountry(pMac, cc, + ®Id, COUNTRY_NV); + } + else + { + return status; + } + pMac->scan.domainIdDefault = regId; + break; + case REINIT: + vos_getCurrentCountryCode(&cc[0]); + status = csrGetRegulatoryDomainForCountry(pMac, + cc, ®Id, COUNTRY_QUERY); + break; + } + WDA_SetRegDomain(pMac, regId, eSIR_TRUE); + pMac->scan.domainIdCurrent = regId; + vos_mem_copy(pMac->scan.countryCodeCurrent, cc, + WNI_CFG_COUNTRY_CODE_LEN); + status = csrInitGetChannels( pMac ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Current Country is %c%c "), pMac->scan.countryCodeCurrent[0], + pMac->scan.countryCodeCurrent[1]); + + /* reset info based on new cc, and we are done */ + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + csrScanFilterResults(pMac); + + return status; +} +#endif + +eHalStatus csrSetRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_REGDOMAIN_t regId; + v_U8_t cntryCodeLength; + if(NULL == apCntryCode) + { + smsLog( pMac, LOGE, FL(" Invalid country Code Pointer") ); + return eHAL_STATUS_FAILURE; + } + smsLog( pMac, LOG1, FL(" country Code %.2s"), apCntryCode ); + /* To get correct Regulatory domain from NV table + * 2 character Country code should be used + * 3rd charater is optional for indoor/outdoor setting */ + cntryCodeLength = WNI_CFG_COUNTRY_CODE_LEN; +/* + cntryCodeLength = strlen(apCntryCode); + + if (cntryCodeLength > WNI_CFG_COUNTRY_CODE_LEN) + { + smsLog( pMac, LOGW, FL(" Invalid Country Code Length") ); + return eHAL_STATUS_FAILURE; + } +*/ + status = csrGetRegulatoryDomainForCountry(pMac, apCntryCode, ®Id, + COUNTRY_USER); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL(" fail to get regId for country Code %.2s"), apCntryCode ); + return status; + } + status = WDA_SetRegDomain(hHal, regId, eSIR_TRUE); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL(" fail to get regId for country Code %.2s"), apCntryCode ); + return status; + } + pMac->scan.domainIdDefault = regId; + pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault; + /* Clear CC field */ + vos_mem_set(pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN, 0); + + /* Copy 2 or 3 bytes country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, apCntryCode, cntryCodeLength); + + /* If 2 bytes country code, 3rd byte must be filled with space */ + if((WNI_CFG_COUNTRY_CODE_LEN - 1) == cntryCodeLength) + { + vos_mem_set(pMac->scan.countryCodeDefault + 2, 1, 0x20); + } + vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + status = csrInitGetChannels( pMac ); + return status; +} +eHalStatus csrSetChannels(tHalHandle hHal, tCsrConfigParam *pParam ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 index = 0; + vos_mem_copy(pParam->Csr11dinfo.countryCode, pMac->scan.countryCodeCurrent, + WNI_CFG_COUNTRY_CODE_LEN); + for ( index = 0; index < pMac->scan.base20MHzChannels.numChannels ; index++) + { + pParam->Csr11dinfo.Channels.channelList[index] = pMac->scan.base20MHzChannels.channelList[ index ]; + pParam->Csr11dinfo.ChnPower[index].firstChannel = pMac->scan.base20MHzChannels.channelList[ index ]; + pParam->Csr11dinfo.ChnPower[index].numChannels = 1; + pParam->Csr11dinfo.ChnPower[index].maxtxPower = pMac->scan.defaultPowerTable[index].pwr; + } + pParam->Csr11dinfo.Channels.numChannels = pMac->scan.base20MHzChannels.numChannels; + + return status; +} +eHalStatus csrClose(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + csrRoamClose(pMac); + csrScanClose(pMac); + csrLLClose(&pMac->roam.statsClientReqList); + csrLLClose(&pMac->roam.peStatsReqList); + csrLLClose(&pMac->roam.roamCmdPendingList); + /* DeInit Globals */ + csrRoamDeInitGlobals(pMac); + return (status); +} + +eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac) +{ + tSirUpdateChanList *pChanList; + tCsrScanStruct *pScan = &pMac->scan; + tANI_U32 numChan = 0; + tANI_U32 bufLen ; + tANI_U8 i, j; + tANI_U8 num_channel = 0; + tANI_U8 channel_state; + tANI_U8 cfgnumChannels = 0; + tANI_U8 *cfgChannelList = NULL; + eHalStatus status; + tSmeCmd *command; + + limInitOperatingClasses((tHalHandle)pMac); + numChan = sizeof(pMac->roam.validChannelList); + + if ( !HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + (tANI_U8 *)pMac->roam.validChannelList, &numChan))) + { + smsLog( pMac, LOGE, "Failed to get Channel list from CFG"); + return eHAL_STATUS_FAILED_ALLOC; + } + + bufLen = sizeof(tSirUpdateChanList) + + (sizeof(tSirUpdateChanParam) * (numChan - 1)); + + pChanList = (tSirUpdateChanList *) vos_mem_malloc(bufLen); + if (!pChanList) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate memory for tSirUpdateChanList"); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_zero(pChanList, bufLen); + + smsLog(pMac, LOG1, FL("fEnableDFSChnlScan %d"), + pMac->scan.fEnableDFSChnlScan); + + for (i = 0; i < numChan; i++) + { + channel_state = + vos_nv_getChannelEnabledState(pMac->roam.validChannelList[i]); + + if((pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_DISABLED) + && (channel_state == NV_CHANNEL_DFS)) + { + continue; + } + pChanList->chanParam[num_channel].chanId = + pMac->roam.validChannelList[i]; + pChanList->chanParam[num_channel].pwr = + cfgGetRegulatoryMaxTransmitPower(pMac, + pScan->defaultPowerTable[i].chanId); + if (pMac->scan.fcc_constraint) + { + if (pChanList->chanParam[num_channel].chanId == 12) + { + pChanList->chanParam[num_channel].pwr = MAX_PWR_FCC_CHAN_12; + smsLog(pMac, LOG1, + "fcc_constraint is set, txpower for channel 12 is 8db "); + } + if (pChanList->chanParam[num_channel].chanId == 13) + { + pChanList->chanParam[num_channel].pwr = MAX_PWR_FCC_CHAN_13; + smsLog(pMac, LOG1, + "fcc_constraint is set, txpower for channel 13 is 2db "); + } + } + + if (!pChanList->chanParam[num_channel].pwr) + { + smsLog(pMac, LOGE, FL("Power level is zero for channel %d " + "setting to default %d"), + pChanList->chanParam[num_channel].chanId, + TX_POWER_DEFAULT); + pChanList->chanParam[num_channel].pwr = TX_POWER_DEFAULT; + } + if (channel_state == NV_CHANNEL_DFS) + pChanList->chanParam[num_channel].dfsSet = VOS_TRUE; + else + pChanList->chanParam[num_channel].dfsSet = VOS_FALSE; + + /* When DFS mode is 2, mark static channels as active */ + if (pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_ENABLED_ACTIVE) + { + cfgnumChannels = + pMac->roam.neighborRoamInfo.cfgParams.channelInfo.numOfChannels; + cfgChannelList = + pMac->roam.neighborRoamInfo.cfgParams.channelInfo.ChannelList; + + if (cfgChannelList) + { + for(j=0; j< cfgnumChannels; j++) + { + if (CSR_IS_CHANNEL_DFS(cfgChannelList[j]) && + (pMac->roam.validChannelList[i] == cfgChannelList[j])) + { + pChanList->chanParam[num_channel].dfsSet = VOS_FALSE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s Marked DFS ch %d as active\n", __func__, + cfgChannelList[j]); + } + } + } + else + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s cfgChannelList is NULL \n", __func__); + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s Supported Channel: %d dfsSet %d pwr: %d \n", __func__, + pChanList->chanParam[num_channel].chanId, + pChanList->chanParam[num_channel].dfsSet, + pChanList->chanParam[num_channel].pwr); + num_channel++; + } + pChanList->regId = csrGetCurrentRegulatoryDomain(pMac); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s : regID : %d \n", __func__, + pChanList->regId); + + pChanList->numChan = num_channel; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) { + command = csrGetCommandBuffer(pMac); + if (command) { + command->command = eSmeCommandUpdateChannelList; + command->u.chan_list = pChanList; + + status = csrQueueSmeCommand(pMac, command, eANI_BOOLEAN_TRUE); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, LOGE, FL("fail to send msg status = %d"), status); + csrReleaseCommand(pMac, command); + } + } else { + smsLog(pMac, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status; +} + +eHalStatus csrStart(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i; + + do + { + //save the global vos context + pMac->roam.gVosContext = vos_get_global_context(VOS_MODULE_ID_SME, pMac); + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, i ); + + status = csrRoamStart(pMac); + if(!HAL_STATUS_SUCCESS(status)) break; + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE; + status = pmcRegisterPowerSaveCheck(pMac, csrCheckPSReady, pMac); + if(!HAL_STATUS_SUCCESS(status)) break; + pMac->roam.sPendingCommands = 0; + csrScanEnable(pMac); +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + status = csrNeighborRoamInit(pMac); +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + pMac->roam.tlStatsReqInfo.numClient = 0; + pMac->roam.tlStatsReqInfo.periodicity = 0; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + //init the link quality indication also + pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrStart: Couldn't Init HO control blk "); + break; + } + + }while(0); +#if defined(ANI_LOGDUMP) + csrDumpInit(pMac); +#endif //#if defined(ANI_LOGDUMP) + return (status); +} + +eHalStatus csrStop(tpAniSirGlobal pMac, tHalStopType stopType) +{ + tANI_U32 sessionId; + tANI_U32 i; + + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + csrRoamCloseSession(pMac, sessionId, TRUE, TRUE, NULL, NULL); + } + csrScanDisable(pMac); + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE; + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + csrLLPurge( &pMac->roam.roamCmdPendingList, eANI_BOOLEAN_TRUE ); + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + csrNeighborRoamClose(pMac); +#endif + csrScanFlushResult(pMac); //Do we want to do this? + // deregister from PMC since we register during csrStart() + // (ignore status since there is nothing we can do if it fails) + (void) pmcDeregisterPowerSaveCheck(pMac, csrCheckPSReady); + //Reset the domain back to the deault + pMac->scan.domainIdCurrent = pMac->scan.domainIdDefault; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_STOP, i ); + pMac->roam.curSubState[i] = eCSR_ROAM_SUBSTATE_NONE; + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* When HAL resets all the context information + * in HAL is lost, so we might need to send the + * scan offload request again when it comes + * out of reset for scan offload to be functional + */ + if (HAL_STOP_TYPE_SYS_RESET == stopType) + { + bRoamScanOffloadStarted = VOS_FALSE; + } +#endif + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus csrReady(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + csrScanGetSupportedChannels( pMac ); + //WNI_CFG_VALID_CHANNEL_LIST should be set by this time + //use it to init the background scan list + csrInitBGScanChannelList(pMac); + //Store the AC weights in TL for later use + WLANTL_GetACWeights(pMac->roam.gVosContext, pMac->roam.ucACWeights); + status = csrInitChannelList( pMac ); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "csrInitChannelList failed during csrReady with status=%d", + status ); + } + return (status); +} +void csrSetDefaultDot11Mode( tpAniSirGlobal pMac ) +{ + v_U32_t wniDot11mode = 0; + wniDot11mode = csrTranslateToWNICfgDot11Mode(pMac,pMac->roam.configParam.uCfgDot11Mode); + ccmCfgSetInt(pMac, WNI_CFG_DOT11_MODE, wniDot11mode, NULL, eANI_BOOLEAN_FALSE); +} +void csrSetGlobalCfgs( tpAniSirGlobal pMac ) +{ + + ccmCfgSetInt(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, csrGetFragThresh(pMac), NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_RTS_THRESHOLD, csrGetRTSThresh(pMac), NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_11D_ENABLED, + ((pMac->roam.configParam.Is11hSupportEnabled) ? pMac->roam.configParam.Is11dSupportEnabled : pMac->roam.configParam.Is11dSupportEnabled), + NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_11H_ENABLED, pMac->roam.configParam.Is11hSupportEnabled, NULL, eANI_BOOLEAN_FALSE); + /* For now we will just use the 5GHz CB mode ini parameter to decide whether CB supported or not in Probes when there is no session + * Once session is established we will use the session related params stored in PE session for CB mode + */ + ccmCfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, !!(pMac->roam.configParam.channelBondingMode5GHz), NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->roam.configParam.HeartbeatThresh24, NULL, eANI_BOOLEAN_FALSE); + + //Update the operating mode to configured value during initialization, + //So that client can advertise full capabilities in Probe request frame. + csrSetDefaultDot11Mode( pMac ); +} + +eHalStatus csrRoamOpen(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i; + tCsrRoamSession *pSession = NULL; + do + { + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + pSession = CSR_GET_SESSION( pMac, i ); + pSession->roamingTimerInfo.pMac = pMac; + pSession->roamingTimerInfo.sessionId = CSR_SESSION_ID_INVALID; + } + pMac->roam.WaitForKeyTimerInfo.pMac = pMac; + pMac->roam.WaitForKeyTimerInfo.sessionId = CSR_SESSION_ID_INVALID; + status = vos_timer_init(&pMac->roam.hTimerWaitForKey, VOS_TIMER_TYPE_SW, + csrRoamWaitForKeyTimeOutHandler, + &pMac->roam.WaitForKeyTimerInfo); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for WaitForKey time out timer")); + break; + } + status = vos_timer_init(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, + VOS_TIMER_TYPE_SW, csrRoamTlStatsTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for summary Statistics timer")); + return eHAL_STATUS_FAILURE; + } + }while (0); + return (status); +} + +eHalStatus csrRoamClose(tpAniSirGlobal pMac) +{ + tANI_U32 sessionId; + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + csrRoamCloseSession(pMac, sessionId, TRUE, TRUE, NULL, NULL); + } + vos_timer_stop(&pMac->roam.hTimerWaitForKey); + vos_timer_destroy(&pMac->roam.hTimerWaitForKey); + vos_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + vos_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus csrRoamStart(tpAniSirGlobal pMac) +{ + (void)pMac; + return (eHAL_STATUS_SUCCESS); +} + +void csrRoamStop(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + csrRoamStopRoamingTimer(pMac, sessionId); + /* deregister the clients requesting stats from PE/TL & also stop the corresponding timers*/ + csrRoamDeregStatisticsReq(pMac); +} +eHalStatus csrRoamGetConnectState(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrConnectState *pState) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + if ( CSR_IS_SESSION_VALID(pMac, sessionId) && (NULL != pState) ) + { + status = eHAL_STATUS_SUCCESS; + *pState = pMac->roam.roamSession[sessionId].connectState; + } + return (status); +} + +eHalStatus csrRoamCopyConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 size = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pProfile) + { + if(pSession->pConnectBssDesc) + { + do + { + size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length); + if(size) + { + pProfile->pBssDesc = vos_mem_malloc(size); + if ( NULL != pProfile->pBssDesc ) + { + vos_mem_copy(pProfile->pBssDesc, + pSession->pConnectBssDesc, size); + status = eHAL_STATUS_SUCCESS; + } + else + break; + } + else + { + pProfile->pBssDesc = NULL; + } + pProfile->AuthType = pSession->connectedProfile.AuthType; + pProfile->EncryptionType = pSession->connectedProfile.EncryptionType; + pProfile->mcEncryptionType = pSession->connectedProfile.mcEncryptionType; + pProfile->BSSType = pSession->connectedProfile.BSSType; + pProfile->operationChannel = pSession->connectedProfile.operationChannel; + pProfile->CBMode = pSession->connectedProfile.CBMode; + vos_mem_copy(&pProfile->bssid, &pSession->connectedProfile.bssid, + sizeof(tCsrBssid)); + vos_mem_copy(&pProfile->SSID, &pSession->connectedProfile.SSID, + sizeof(tSirMacSSid)); +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSession->connectedProfile.MDID.mdiePresent) + { + pProfile->MDID.mdiePresent = 1; + pProfile->MDID.mobilityDomain = pSession->connectedProfile.MDID.mobilityDomain; + } + else + { + pProfile->MDID.mdiePresent = 0; + pProfile->MDID.mobilityDomain = 0; + } +#endif +#ifdef FEATURE_WLAN_ESE + pProfile->isESEAssoc = pSession->connectedProfile.isESEAssoc; + if (csrIsAuthTypeESE(pSession->connectedProfile.AuthType)) + { + vos_mem_copy (pProfile->eseCckmInfo.krk, + pSession->connectedProfile.eseCckmInfo.krk, + CSR_KRK_KEY_LEN); + pProfile->eseCckmInfo.reassoc_req_num= + pSession->connectedProfile.eseCckmInfo.reassoc_req_num; + pProfile->eseCckmInfo.krk_plumbed = + pSession->connectedProfile.eseCckmInfo.krk_plumbed; + } +#endif + }while(0); + } + } + + return (status); +} + +eHalStatus csrRoamGetConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + + if((csrIsConnStateConnected(pMac, sessionId)) || + (csrIsConnStateIbss(pMac, sessionId))) + { + if(pProfile) + { + status = csrRoamCopyConnectProfile(pMac, sessionId, pProfile); + } + } + return (status); +} + +eHalStatus csrRoamFreeConnectProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + if (pProfile->pBssDesc) + { + vos_mem_free(pProfile->pBssDesc); + } + if (pProfile->pAddIEAssoc) + { + vos_mem_free(pProfile->pAddIEAssoc); + } + vos_mem_set(pProfile, sizeof(tCsrRoamConnectedProfile), 0); + + pProfile->AuthType = eCSR_AUTH_TYPE_UNKNOWN; + return (status); +} + +eHalStatus csrRoamFreeConnectedInfo( tpAniSirGlobal pMac, tCsrRoamConnectedInfo *pConnectedInfo ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + if( pConnectedInfo->pbFrames ) + { + vos_mem_free(pConnectedInfo->pbFrames); + pConnectedInfo->pbFrames = NULL; + } + pConnectedInfo->nBeaconLength = 0; + pConnectedInfo->nAssocReqLength = 0; + pConnectedInfo->nAssocRspLength = 0; + pConnectedInfo->staId = 0; +#ifdef WLAN_FEATURE_VOWIFI_11R + pConnectedInfo->nRICRspLength = 0; +#endif +#ifdef FEATURE_WLAN_ESE + pConnectedInfo->nTspecIeLength = 0; +#endif + return ( status ); +} + + + + +void csrReleaseCommandPreauth(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitPreauthCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitRoamCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitScanCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitWmStatusChangeCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +void csrReinitSetKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + vos_mem_set(&pCommand->u.setKeyCmd, sizeof(tSetKeyCmd), 0); +} + +void csrReinitRemoveKeyCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + vos_mem_set(&pCommand->u.removeKeyCmd, sizeof(tRemoveKeyCmd), 0); +} + +void csrReleaseCommandSetKey(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitSetKeyCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} +void csrReleaseCommandRemoveKey(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + csrReinitRemoveKeyCmd(pMac, pCommand); + csrReleaseCommand( pMac, pCommand ); +} + +/** + * csr_is_disconnect_full_power_cmd() - Check if command is for + * disconnect or for fullpower + * @command: command to check + * + * Return: true if disconnect or full power command else false + */ +bool csr_is_disconnect_full_power_cmd(tSmeCmd *command) +{ + switch (command->command) { + case eSmeCommandRoam: + if (CSR_IS_DISCONNECT_COMMAND(command)) + return true; + break; + case eSmeCommandWmStatusChange: + case eSmeCommandExitImps: + case eSmeCommandExitBmps: + case eSmeCommandExitUapsd: + case eSmeCommandExitWowl: + return true; + default: + return false; + } + return false; +} + +void csrAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) +{ + + if( eSmeCsrCommandMask & pCommand->command ) + { + switch (pCommand->command) + { + case eSmeCommandScan: + // We need to inform the requester before dropping the scan command + smsLog( pMac, LOGW, "%s: Drop scan reason %d callback %p", + __func__, pCommand->u.scanCmd.reason, + pCommand->u.scanCmd.callback); + if (NULL != pCommand->u.scanCmd.callback) + { + smsLog( pMac, LOGW, "%s callback scan requester", __func__); + csrScanCallCallback(pMac, pCommand, eCSR_SCAN_ABORT); + } + csrReleaseCommandScan( pMac, pCommand ); + break; + case eSmeCommandRoam: + csrReleaseCommandRoam( pMac, pCommand ); + break; + + case eSmeCommandWmStatusChange: + csrReleaseCommandWmStatusChange( pMac, pCommand ); + break; + + case eSmeCommandSetKey: + csrReleaseCommandSetKey( pMac, pCommand ); + break; + + case eSmeCommandRemoveKey: + csrReleaseCommandRemoveKey( pMac, pCommand ); + break; + + default: + smsLog( pMac, LOGW, " CSR abort standard command %d", pCommand->command ); + csrReleaseCommand( pMac, pCommand ); + break; + } + } +} + +void csrRoamSubstateChange( tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate, tANI_U32 sessionId) +{ + smsLog(pMac, LOG1, FL("CSR RoamSubstate: [ %s <== %s ]"), + macTraceGetcsrRoamSubState(NewSubstate), + macTraceGetcsrRoamSubState(pMac->roam.curSubState[sessionId])); + + if(pMac->roam.curSubState[sessionId] == NewSubstate) + { + return; + } + pMac->roam.curSubState[sessionId] = NewSubstate; +} + +eCsrRoamState csrRoamStateChange( tpAniSirGlobal pMac, eCsrRoamState NewRoamState, tANI_U8 sessionId) +{ + eCsrRoamState PreviousState; + + smsLog(pMac, LOG1, FL("CSR RoamState[%hu]: [ %s <== %s ]"), sessionId, + macTraceGetcsrRoamState(NewRoamState), + macTraceGetcsrRoamState(pMac->roam.curState[sessionId])); + + PreviousState = pMac->roam.curState[sessionId]; + + if ( NewRoamState != pMac->roam.curState[sessionId] ) + { + // Whenever we transition OUT of the Roaming state, clear the Roaming substate... + if ( CSR_IS_ROAM_JOINING(pMac, sessionId) ) + { + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + } + + pMac->roam.curState[sessionId] = NewRoamState; + } + return( PreviousState ); +} + +void csrAssignRssiForCategory(tpAniSirGlobal pMac, tANI_S8 bestApRssi, tANI_U8 catOffset) +{ + int i; + if(catOffset) + { + pMac->roam.configParam.bCatRssiOffset = catOffset; + for(i = 0; i < CSR_NUM_RSSI_CAT; i++) + { + pMac->roam.configParam.RSSICat[CSR_NUM_RSSI_CAT - i - 1] = (int)bestApRssi - pMac->roam.configParam.nSelect5GHzMargin - (int)(i * catOffset); + } + } +} + +static void initConfigParam(tpAniSirGlobal pMac) +{ + int i; + pMac->roam.configParam.agingCount = CSR_AGING_COUNT; + pMac->roam.configParam.channelBondingMode24GHz = + WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + pMac->roam.configParam.channelBondingMode5GHz = + WNI_CFG_CHANNEL_BONDING_MODE_ENABLE; + pMac->roam.configParam.phyMode = eCSR_DOT11_MODE_TAURUS; + pMac->roam.configParam.eBand = eCSR_BAND_ALL; + pMac->roam.configParam.uCfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + pMac->roam.configParam.FragmentationThreshold = eCSR_DOT11_FRAG_THRESH_DEFAULT; + pMac->roam.configParam.HeartbeatThresh24 = 40; + pMac->roam.configParam.HeartbeatThresh50 = 40; + pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.Is11dSupportEnabledOriginal = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.Is11eSupportEnabled = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.Is11hSupportEnabled = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.RTSThreshold = 2346; + pMac->roam.configParam.shortSlotTime = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.WMMSupportMode = eCsrRoamWmmAuto; + pMac->roam.configParam.ProprietaryRatesEnabled = eANI_BOOLEAN_TRUE; + pMac->roam.configParam.TxRate = eCSR_TX_RATE_AUTO; + pMac->roam.configParam.impsSleepTime = CSR_IDLE_SCAN_NO_PS_INTERVAL; + pMac->roam.configParam.scanAgeTimeNCNPS = CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS; + pMac->roam.configParam.scanAgeTimeNCPS = CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS; + pMac->roam.configParam.scanAgeTimeCNPS = CSR_SCAN_AGING_TIME_CONNECT_NO_PS; + pMac->roam.configParam.scanAgeTimeCPS = CSR_SCAN_AGING_TIME_CONNECT_W_PS; + for(i = 0; i < CSR_NUM_RSSI_CAT; i++) + { + pMac->roam.configParam.BssPreferValue[i] = i; + } + csrAssignRssiForCategory(pMac, CSR_BEST_RSSI_VALUE, CSR_DEFAULT_RSSI_DB_GAP); + pMac->roam.configParam.nRoamingTime = CSR_DEFAULT_ROAMING_TIME; + pMac->roam.configParam.fEnforce11dChannels = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fSupplicantCountryCodeHasPriority = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fEnforceCountryCodeMatch = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fEnforceDefaultDomain = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.fEnforceCountryCode = eANI_BOOLEAN_FALSE; + pMac->roam.configParam.nActiveMaxChnTime = CSR_ACTIVE_MAX_CHANNEL_TIME; + pMac->roam.configParam.nActiveMinChnTime = CSR_ACTIVE_MIN_CHANNEL_TIME; + pMac->roam.configParam.nPassiveMaxChnTime = CSR_PASSIVE_MAX_CHANNEL_TIME; + pMac->roam.configParam.nPassiveMinChnTime = CSR_PASSIVE_MIN_CHANNEL_TIME; + pMac->roam.configParam.max_chntime_btc_esco = + CSR_ACTIVE_MAX_CHANNEL_TIME_ESCO_BTC; + pMac->roam.configParam.min_chntime_btc_esco = + CSR_ACTIVE_MIN_CHANNEL_TIME_ESCO_BTC; + pMac->roam.configParam.min_chntime_btc_sco = + CSR_ACTIVE_MIN_CHANNEL_TIME_SCO_BTC; + pMac->roam.configParam.max_chntime_btc_sco= + CSR_ACTIVE_MAX_CHANNEL_TIME_SCO_BTC; + pMac->roam.configParam.disableAggWithBtc = eANI_BOOLEAN_TRUE; +#ifdef WLAN_AP_STA_CONCURRENCY + pMac->roam.configParam.nActiveMaxChnTimeConc = CSR_ACTIVE_MAX_CHANNEL_TIME_CONC; + pMac->roam.configParam.nActiveMinChnTimeConc = CSR_ACTIVE_MIN_CHANNEL_TIME_CONC; + pMac->roam.configParam.nPassiveMaxChnTimeConc = CSR_PASSIVE_MAX_CHANNEL_TIME_CONC; + pMac->roam.configParam.nPassiveMinChnTimeConc = CSR_PASSIVE_MIN_CHANNEL_TIME_CONC; + pMac->roam.configParam.nRestTimeConc = CSR_REST_TIME_CONC; + pMac->roam.configParam.nNumStaChanCombinedConc = CSR_NUM_STA_CHAN_COMBINED_CONC; + pMac->roam.configParam.nNumP2PChanCombinedConc = CSR_NUM_P2P_CHAN_COMBINED_CONC; +#endif + pMac->roam.configParam.IsIdleScanEnabled = TRUE; //enable the idle scan by default + pMac->roam.configParam.nTxPowerCap = CSR_MAX_TX_POWER; + pMac->roam.configParam.statsReqPeriodicity = CSR_MIN_GLOBAL_STAT_QUERY_PERIOD; + pMac->roam.configParam.statsReqPeriodicityInPS = CSR_MIN_GLOBAL_STAT_QUERY_PERIOD_IN_BMPS; +#ifdef WLAN_FEATURE_VOWIFI_11R + pMac->roam.configParam.csr11rConfig.IsFTResourceReqSupported = 0; +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries = 3; + pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold = 120; + pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold = 125; + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = 20; + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = 40; + pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod = 200; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels = 3; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[0] = 1; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[1] = 6; + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[2] = 11; + pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod = 20000; //20 seconds + pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = 0; + pMac->roam.configParam.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable = 0; + pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam = 0; +#endif +#ifdef WLAN_FEATURE_11AC + pMac->roam.configParam.nVhtChannelWidth = WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1; +#endif + + pMac->roam.configParam.addTSWhenACMIsOff = 0; + pMac->roam.configParam.fScanTwice = eANI_BOOLEAN_FALSE; + + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + pMac->roam.configParam.doBMPSWorkaround = 0; + +} +eCsrBand csrGetCurrentBand(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.bandCapability; +} + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* + This function flushes the roam scan cache +*/ +eHalStatus csrFlushRoamScanRoamChannelList(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + /* Free up the memory first (if required) */ + if (NULL != pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + } + return status; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* + This function flushes the roam scan cache +*/ +eHalStatus csrFlushCfgBgScanRoamChannelList(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + /* Free up the memory first (if required) */ + if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0; + } + return status; +} + + + +/* + This function flushes the roam scan cache and creates fresh cache + based on the input channel list +*/ +eHalStatus csrCreateBgScanRoamChannelList(tpAniSirGlobal pMac, + const tANI_U8 *pChannelList, + const tANI_U8 numChannels) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = numChannels; + + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = + vos_mem_malloc(pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed")); + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = 0; + return eHAL_STATUS_RESOURCES; + } + + /* Update the roam global structure */ + vos_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pChannelList, + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + return status; +} + +/* This function modifies the bgscan channel list set via config ini or + runtime, whenever the band changes. + if the band is auto, then no operation is performed on the channel list + if the band is 2.4G, then make sure channel list contains only 2.4G valid channels + if the band is 5G, then make sure channel list contains only 5G valid channels +*/ +eHalStatus csrUpdateBgScanConfigIniChannelList(tpAniSirGlobal pMac, + eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 outNumChannels = 0; + tANI_U8 inNumChannels = 0; + tANI_U8 *inPtr = NULL; + tANI_U8 i = 0; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "No update required for channel list " + "either cfg.ini channel list is not set up or " + "auto band (Band %d)", eBand); + return status; + } + + inNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; + inPtr = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList; + if (eCSR_BAND_24 == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (CSR_IS_CHANNEL_24GHZ(inPtr[i]) && csrRoamIsChannelValid(pMac, inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + csrFlushCfgBgScanRoamChannelList(pMac); + csrCreateBgScanRoamChannelList(pMac, ChannelList, outNumChannels); + } + else if (eCSR_BAND_5G == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + /* Add 5G Non-DFS channel */ + if (CSR_IS_CHANNEL_5GHZ(inPtr[i]) && + csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + csrFlushCfgBgScanRoamChannelList(pMac); + csrCreateBgScanRoamChannelList(pMac, ChannelList, outNumChannels); + } + else if (eCSR_BAND_ALL == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + csrFlushCfgBgScanRoamChannelList(pMac); + csrCreateBgScanRoamChannelList(pMac, ChannelList, outNumChannels); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "Invalid band, No operation carried out (Band %d)", eBand); + status = eHAL_STATUS_INVALID_PARAMETER; + } + + return status; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* This function modifies the roam scan channel list as per AP neighbor + report; AP neighbor report may be empty or may include only other AP + channels; in any case, we merge the channel list with the learned occupied + channels list. + if the band is 2.4G, then make sure channel list contains only 2.4G valid channels + if the band is 5G, then make sure channel list contains only 5G valid channels +*/ +eHalStatus csrCreateRoamScanChannelList(tpAniSirGlobal pMac, + tANI_U8 *pChannelList, + tANI_U8 numChannels, + const eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 outNumChannels = 0; + tANI_U8 inNumChannels = numChannels; + tANI_U8 *inPtr = pChannelList; + tANI_U8 i = 0; + tANI_U8 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tANI_U8 mergedOutputNumOfChannels = 0; + tpCsrChannelInfo currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + + /* Create a Union of occupied channel list learnt by the DUT along with the Neighbor + * report Channels. This increases the chances of the DUT to get a candidate AP while + * roaming even if the Neighbor Report is not able to provide sufficient information. */ + if (pMac->scan.occupiedChannels.numChannels) + { + csrNeighborRoamMergeChannelLists(pMac, + &pMac->scan.occupiedChannels.channelList[0], + pMac->scan.occupiedChannels.numChannels, + inPtr, + inNumChannels, + &mergedOutputNumOfChannels); + inNumChannels = mergedOutputNumOfChannels; + } + + if (eCSR_BAND_24 == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (CSR_IS_CHANNEL_24GHZ(inPtr[i]) && csrRoamIsChannelValid(pMac, inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + } + else if (eCSR_BAND_5G == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + /* Add 5G Non-DFS channel */ + if (CSR_IS_CHANNEL_5GHZ(inPtr[i]) && + csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + } + else if (eCSR_BAND_ALL == eBand) + { + for (i = 0; i < inNumChannels; i++) + { + if (csrRoamIsChannelValid(pMac, inPtr[i]) && + !CSR_IS_CHANNEL_DFS(inPtr[i])) + { + ChannelList[outNumChannels++] = inPtr[i]; + } + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "Invalid band, No operation carried out (Band %d)", eBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + + /* if roaming within band is enabled, then select only the + in band channels . + This is required only if the band capability is set to ALL, + E.g., if band capability is only 2.4G then all the channels in the + list are already filtered for 2.4G channels, hence ignore this check*/ + + if ((eCSR_BAND_ALL == eBand) && CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByBand( + pMac, + ChannelList, + outNumChannels, + tmpChannelList, + &outNumChannels, + GetRFBand(pMac->roam.neighborRoamInfo.currAPoperationChannel)); + vos_mem_copy(ChannelList, + tmpChannelList, outNumChannels); + } + + /* Prepare final roam scan channel list */ + if(outNumChannels) + { + /* Clear the channel list first */ + if (NULL != currChannelListInfo->ChannelList) + { + vos_mem_free(currChannelListInfo->ChannelList); + currChannelListInfo->ChannelList = NULL; + currChannelListInfo->numOfChannels = 0; + } + + currChannelListInfo->ChannelList = vos_mem_malloc(outNumChannels * sizeof(tANI_U8)); + if (NULL == currChannelListInfo->ChannelList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "Failed to allocate memory for roam scan channel list"); + currChannelListInfo->numOfChannels = 0; + return VOS_STATUS_E_RESOURCES; + } + vos_mem_copy(currChannelListInfo->ChannelList, + ChannelList, outNumChannels); + } + return status; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +eHalStatus csrSetBand(tHalHandle hHal, eCsrBand eBand) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + if (CSR_IS_PHY_MODE_A_ONLY(pMac) && + (eBand == eCSR_BAND_24)) + { + /* DOT11 mode configured to 11a only and received + request to change the band to 2.4 GHz */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to set band cfg80211 = %u, band = %u", + pMac->roam.configParam.uCfgDot11Mode, eBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + if ((CSR_IS_PHY_MODE_B_ONLY(pMac) || + CSR_IS_PHY_MODE_G_ONLY(pMac)) && + (eBand == eCSR_BAND_5G)) + { + /* DOT11 mode configured to 11b/11g only and received + request to change the band to 5 GHz */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to set band dot11mode = %u, band = %u", + pMac->roam.configParam.uCfgDot11Mode, eBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Band changed to %u (0 - ALL, 1 - 2.4 GHZ, 2 - 5GHZ)", eBand); + pMac->roam.configParam.eBand = eBand; + pMac->roam.configParam.bandCapability = eBand; + csrScanGetSupportedChannels( pMac ); +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + csrUpdateBgScanConfigIniChannelList( pMac, eBand ); +#endif + status = csrInitGetChannels( pMac ); + if (eHAL_STATUS_SUCCESS == status) + csrInitChannelList( hHal ); + return status; +} + + +/* The funcns csrConvertCBIniValueToPhyCBState and csrConvertPhyCBStateToIniValue have been + * introduced to convert the ini value to the ENUM used in csr and MAC for CB state + * Ideally we should have kept the ini value and enum value same and representing the same + * cb values as in 11n standard i.e. + * Set to 1 (SCA) if the secondary channel is above the primary channel + * Set to 3 (SCB) if the secondary channel is below the primary channel + * Set to 0 (SCN) if no secondary channel is present + * However, since our driver is already distributed we will keep the ini definition as it is which is: + * 0 - secondary none + * 1 - secondary LOW + * 2 - secondary HIGH + * and convert to enum value used within the driver in csrChangeDefaultConfigParam using this funcn + * The enum values are as follows: + * PHY_SINGLE_CHANNEL_CENTERED = 0 + * PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1 + * PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + */ +ePhyChanBondState csrConvertCBIniValueToPhyCBState(v_U32_t cbIniValue) +{ + + ePhyChanBondState phyCbState; + switch (cbIniValue) { + // secondary none + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + phyCbState = PHY_SINGLE_CHANNEL_CENTERED; + break; + // secondary LOW + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + phyCbState = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + // secondary HIGH + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + phyCbState = PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + phyCbState = PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + break; +#endif + default: + // If an invalid value is passed, disable CHANNEL BONDING + phyCbState = PHY_SINGLE_CHANNEL_CENTERED; + break; + } + + return phyCbState; +} + +v_U32_t csrConvertPhyCBStateToIniValue(ePhyChanBondState phyCbState) +{ + + v_U32_t cbIniValue; + switch (phyCbState) { + // secondary none + case PHY_SINGLE_CHANNEL_CENTERED: + cbIniValue = eCSR_INI_SINGLE_CHANNEL_CENTERED; + break; + // secondary LOW + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + cbIniValue = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + // secondary HIGH + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + cbIniValue = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + break; +#ifdef WLAN_FEATURE_11AC + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + break; + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + cbIniValue = eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + break; +#endif + default: + // return some invalid value + cbIniValue = eCSR_INI_CHANNEL_BONDING_STATE_MAX; + break; + } + + return cbIniValue; +} + +eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(pParam) + { + pMac->roam.configParam.WMMSupportMode = pParam->WMMSupportMode; + pMac->roam.configParam.Is11eSupportEnabled = pParam->Is11eSupportEnabled; + pMac->roam.configParam.FragmentationThreshold = pParam->FragmentationThreshold; + pMac->roam.configParam.Is11dSupportEnabled = pParam->Is11dSupportEnabled; + pMac->roam.configParam.Is11dSupportEnabledOriginal = pParam->Is11dSupportEnabled; + pMac->roam.configParam.Is11hSupportEnabled = pParam->Is11hSupportEnabled; + + pMac->roam.configParam.fenableMCCMode = pParam->fEnableMCCMode; + pMac->roam.configParam.fAllowMCCGODiffBI = pParam->fAllowMCCGODiffBI; + + /* channelBondingMode5GHz plays a dual role right now + * INFRA STA will use this non zero value as CB enabled and SOFTAP will use this non-zero value to determine the secondary channel offset + * This is how channelBondingMode5GHz works now and this is kept intact to avoid any cfg.ini change + */ + if (pParam->channelBondingMode24GHz > MAX_CB_VALUE_IN_INI) + { + smsLog( pMac, LOGW, "Invalid CB value from ini in 2.4GHz band %d, CB DISABLED", pParam->channelBondingMode24GHz); + } + pMac->roam.configParam.channelBondingMode24GHz = csrConvertCBIniValueToPhyCBState(pParam->channelBondingMode24GHz); + if (pParam->channelBondingMode5GHz > MAX_CB_VALUE_IN_INI) + { + smsLog( pMac, LOGW, "Invalid CB value from ini in 5GHz band %d, CB DISABLED", pParam->channelBondingMode5GHz); + } +#ifdef WLAN_FEATURE_AP_HT40_24G + pMac->roam.configParam.channelBondingAPMode24GHz = csrConvertCBIniValueToPhyCBState(pParam->channelBondingAPMode24GHz); +#endif + pMac->roam.configParam.channelBondingMode5GHz = csrConvertCBIniValueToPhyCBState(pParam->channelBondingMode5GHz); + pMac->roam.configParam.RTSThreshold = pParam->RTSThreshold; + pMac->roam.configParam.phyMode = pParam->phyMode; + pMac->roam.configParam.shortSlotTime = pParam->shortSlotTime; + pMac->roam.configParam.HeartbeatThresh24 = pParam->HeartbeatThresh24; + pMac->roam.configParam.HeartbeatThresh50 = pParam->HeartbeatThresh50; + pMac->roam.configParam.ProprietaryRatesEnabled = pParam->ProprietaryRatesEnabled; + pMac->roam.configParam.TxRate = pParam->TxRate; + pMac->roam.configParam.AdHocChannel24 = pParam->AdHocChannel24; + pMac->roam.configParam.AdHocChannel5G = pParam->AdHocChannel5G; + pMac->roam.configParam.bandCapability = pParam->bandCapability; + pMac->roam.configParam.cbChoice = pParam->cbChoice; + pMac->roam.configParam.bgScanInterval = pParam->bgScanInterval; + pMac->roam.configParam.disableAggWithBtc = pParam->disableAggWithBtc; + //if HDD passed down non zero values then only update, + //otherwise keep using the defaults + if (pParam->nInitialDwellTime) + { + pMac->roam.configParam.nInitialDwellTime = + pParam->nInitialDwellTime; + } + if (pParam->nActiveMaxChnTime) + { + pMac->roam.configParam.nActiveMaxChnTime = pParam->nActiveMaxChnTime; + cfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, + pParam->nActiveMaxChnTime); + } + if (pParam->nActiveMinChnTime) + { + pMac->roam.configParam.nActiveMinChnTime = pParam->nActiveMinChnTime; + cfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, + pParam->nActiveMinChnTime); + } + if (pParam->nPassiveMaxChnTime) + { + pMac->roam.configParam.nPassiveMaxChnTime = pParam->nPassiveMaxChnTime; + cfgSetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + pParam->nPassiveMaxChnTime); + } + if (pParam->nPassiveMinChnTime) + { + pMac->roam.configParam.nPassiveMinChnTime = pParam->nPassiveMinChnTime; + cfgSetInt(pMac, WNI_CFG_PASSIVE_MINIMUM_CHANNEL_TIME, + pParam->nPassiveMinChnTime); + } + if (pParam->nOBSSScanWidthTriggerInterval) + { + pMac->roam.configParam.nOBSSScanWidthTriggerInterval = + pParam->nOBSSScanWidthTriggerInterval; + cfgSetInt(pMac, WNI_CFG_OBSS_HT40_SCAN_WIDTH_TRIGGER_INTERVAL, + pParam->nOBSSScanWidthTriggerInterval); + } + if (pParam->max_chntime_btc_esco) + { + pMac->roam.configParam.max_chntime_btc_esco = + pParam->max_chntime_btc_esco; + } + if (pParam->min_chntime_btc_esco) + { + pMac->roam.configParam.min_chntime_btc_esco = + pParam->min_chntime_btc_esco; + } + if (pParam->min_chntime_btc_sco) + pMac->roam.configParam.min_chntime_btc_sco = + pParam->min_chntime_btc_sco; + if (pParam->max_chntime_btc_sco) + pMac->roam.configParam.max_chntime_btc_sco = + pParam->max_chntime_btc_sco; +#ifdef WLAN_AP_STA_CONCURRENCY + if (pParam->nActiveMaxChnTimeConc) + { + pMac->roam.configParam.nActiveMaxChnTimeConc = pParam->nActiveMaxChnTimeConc; + } + if (pParam->nActiveMinChnTimeConc) + { + pMac->roam.configParam.nActiveMinChnTimeConc = pParam->nActiveMinChnTimeConc; + } + if (pParam->nPassiveMaxChnTimeConc) + { + pMac->roam.configParam.nPassiveMaxChnTimeConc = pParam->nPassiveMaxChnTimeConc; + } + if (pParam->nPassiveMinChnTimeConc) + { + pMac->roam.configParam.nPassiveMinChnTimeConc = pParam->nPassiveMinChnTimeConc; + } + if (pParam->nRestTimeConc) + { + pMac->roam.configParam.nRestTimeConc = pParam->nRestTimeConc; + } + if (pParam->nNumStaChanCombinedConc) + { + pMac->roam.configParam.nNumStaChanCombinedConc = pParam->nNumStaChanCombinedConc; + } + if (pParam->nNumP2PChanCombinedConc) + { + pMac->roam.configParam.nNumP2PChanCombinedConc = pParam->nNumP2PChanCombinedConc; + } +#endif + //if upper layer wants to disable idle scan altogether set it to 0 + if (pParam->impsSleepTime) + { + //Change the unit from second to microsecond + tANI_U32 impsSleepTime = pParam->impsSleepTime * PAL_TIMER_TO_SEC_UNIT; + if(CSR_IDLE_SCAN_NO_PS_INTERVAL_MIN <= impsSleepTime) + { + pMac->roam.configParam.impsSleepTime = impsSleepTime; + } + else + { + pMac->roam.configParam.impsSleepTime = CSR_IDLE_SCAN_NO_PS_INTERVAL; + } + } + else + { + pMac->roam.configParam.impsSleepTime = 0; + } + pMac->roam.configParam.eBand = pParam->eBand; + pMac->roam.configParam.uCfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(NULL, pMac->roam.configParam.phyMode, + pMac->roam.configParam.ProprietaryRatesEnabled); + //if HDD passed down non zero values for age params, then only update, + //otherwise keep using the defaults + if (pParam->nScanResultAgeCount) + { + pMac->roam.configParam.agingCount = pParam->nScanResultAgeCount; + } + if(pParam->scanAgeTimeNCNPS) + { + pMac->roam.configParam.scanAgeTimeNCNPS = pParam->scanAgeTimeNCNPS; + } + if(pParam->scanAgeTimeNCPS) + { + pMac->roam.configParam.scanAgeTimeNCPS = pParam->scanAgeTimeNCPS; + } + if(pParam->scanAgeTimeCNPS) + { + pMac->roam.configParam.scanAgeTimeCNPS = pParam->scanAgeTimeCNPS; + } + if(pParam->scanAgeTimeCPS) + { + pMac->roam.configParam.scanAgeTimeCPS = pParam->scanAgeTimeCPS; + } + if (pParam->initialScanSkipDFSCh) + { + pMac->roam.configParam.initialScanSkipDFSCh = + pParam->initialScanSkipDFSCh; + } + + csrAssignRssiForCategory(pMac, CSR_BEST_RSSI_VALUE, pParam->bCatRssiOffset); + pMac->roam.configParam.nRoamingTime = pParam->nRoamingTime; + pMac->roam.configParam.fEnforce11dChannels = pParam->fEnforce11dChannels; + pMac->roam.configParam.fSupplicantCountryCodeHasPriority = pParam->fSupplicantCountryCodeHasPriority; + pMac->roam.configParam.fEnforceCountryCodeMatch = pParam->fEnforceCountryCodeMatch; + pMac->roam.configParam.fEnforceDefaultDomain = pParam->fEnforceDefaultDomain; + pMac->roam.configParam.vccRssiThreshold = pParam->vccRssiThreshold; + pMac->roam.configParam.vccUlMacLossThreshold = pParam->vccUlMacLossThreshold; + pMac->roam.configParam.IsIdleScanEnabled = pParam->IsIdleScanEnabled; + pMac->roam.configParam.statsReqPeriodicity = pParam->statsReqPeriodicity; + pMac->roam.configParam.statsReqPeriodicityInPS = pParam->statsReqPeriodicityInPS; + //Assign this before calling CsrInit11dInfo + pMac->roam.configParam.nTxPowerCap = pParam->nTxPowerCap; + if( csrIs11dSupported( pMac ) ) + { + status = CsrInit11dInfo(pMac, &pParam->Csr11dinfo); + } + else + { + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + } + + /* Initialize the power + channel information if 11h is enabled. + If 11d is enabled this information has already been initialized */ + if( csrIs11hSupported( pMac ) && !csrIs11dSupported( pMac ) ) + { + csrInitChannelPowerList(pMac, &pParam->Csr11dinfo); + } + + +#ifdef WLAN_FEATURE_VOWIFI_11R + vos_mem_copy(&pMac->roam.configParam.csr11rConfig, + &pParam->csr11rConfig, sizeof(tCsr11rConfigParams)); + smsLog( pMac, LOG1, "IsFTResourceReqSupp = %d", pMac->roam.configParam.csr11rConfig.IsFTResourceReqSupported); +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pMac->roam.configParam.isFastTransitionEnabled = pParam->isFastTransitionEnabled; + pMac->roam.configParam.RoamRssiDiff = pParam->RoamRssiDiff; + pMac->roam.configParam.nImmediateRoamRssiDiff = pParam->nImmediateRoamRssiDiff; + smsLog( pMac, LOG1, "nImmediateRoamRssiDiff = %d", + pMac->roam.configParam.nImmediateRoamRssiDiff ); + pMac->roam.configParam.nRoamPrefer5GHz = pParam->nRoamPrefer5GHz; + pMac->roam.configParam.nRoamIntraBand = pParam->nRoamIntraBand; + pMac->roam.configParam.isWESModeEnabled = pParam->isWESModeEnabled; + pMac->roam.configParam.nProbes = pParam->nProbes; + pMac->roam.configParam.nRoamScanHomeAwayTime = pParam->nRoamScanHomeAwayTime; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pMac->roam.configParam.isRoamOffloadScanEnabled = + pParam->isRoamOffloadScanEnabled; + pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = + pParam->bFastRoamInConIniFeatureEnabled; + pMac->roam.configParam.isPERRoamEnabled = + pParam->isPERRoamEnabled; + pMac->roam.configParam.rateUpThreshold = pParam->rateUpThreshold; + pMac->roam.configParam.rateDownThreshold = pParam->rateDownThreshold; + pMac->roam.configParam.waitPeriodForNextPERScan = + pParam->waitPeriodForNextPERScan; + pMac->roam.configParam.PERtimerThreshold = pParam->PERtimerThreshold; + pMac->roam.configParam.isPERRoamCCAEnabled = + pParam->isPERRoamCCAEnabled; + pMac->roam.configParam.PERRoamFullScanThreshold = + pParam->PERRoamFullScanThreshold; + pMac->roam.configParam.PERroamTriggerPercent = + pParam->PERroamTriggerPercent; + pMac->roam.configParam.PERMinRssiThresholdForRoam = + pParam->PERMinRssiThresholdForRoam; + pMac->PERroamTimeout = pParam->waitPeriodForNextPERScan; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + pMac->roam.configParam.enable_lfr_mbb = pParam->enable_lfr_mbb; +#endif + +#ifdef FEATURE_WLAN_LFR + pMac->roam.configParam.isFastRoamIniFeatureEnabled = pParam->isFastRoamIniFeatureEnabled; + pMac->roam.configParam.MAWCEnabled = pParam->MAWCEnabled; +#endif + +#ifdef FEATURE_WLAN_ESE + pMac->roam.configParam.isEseIniFeatureEnabled = pParam->isEseIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + vos_mem_copy(&pMac->roam.configParam.neighborRoamConfig, + &pParam->neighborRoamConfig, sizeof(tCsrNeighborRoamConfigParams)); + smsLog( pMac, LOG1, "nNeighborScanTimerPerioid = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod); + smsLog( pMac, LOG1, "nNeighborReassocRssiThreshold = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold); + smsLog( pMac, LOG1, "nNeighborLookupRssiThreshold = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold); + smsLog( pMac, LOG1, "nNeighborScanMinChanTime = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime); + smsLog( pMac, LOG1, "nNeighborScanMaxChanTime = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime); + smsLog( pMac, LOG1, "nMaxNeighborRetries = %d", pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries); + smsLog( pMac, LOG1, "nNeighborResultsRefreshPeriod = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod); + smsLog( pMac, LOG1, "nEmptyScanRefreshPeriod = %d", pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod); + smsLog( pMac, LOG1, "nNeighborInitialForcedRoamTo5GhEnable = %d", pMac->roam.configParam.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable); + smsLog( pMac, LOG1, "nWeakZoneRssiThresholdForRoam = %d", pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam); + { + int i; + smsLog( pMac, LOG1, FL("Num of Channels in CFG Channel List: %d"), pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + for( i=0; i< pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels; i++) + { + smsLog( pMac, LOG1, "%d ", pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[i] ); + } + } +#endif + pMac->roam.configParam.addTSWhenACMIsOff = pParam->addTSWhenACMIsOff; + pMac->scan.fValidateList = pParam->fValidateList; + pMac->scan.fEnableBypass11d = pParam->fEnableBypass11d; + pMac->scan.fEnableDFSChnlScan = pParam->fEnableDFSChnlScan; + pMac->scan.disable_scan_during_sco = pParam->disable_scan_during_sco; + pMac->scan.scanResultCfgAgingTime = pParam->scanCfgAgingTime; + pMac->roam.configParam.fScanTwice = pParam->fScanTwice; + pMac->scan.fFirstScanOnly2GChnl = pParam->fFirstScanOnly2GChnl; + pMac->scan.scanBandPreference = pParam->scanBandPreference; + /* This parameter is not available in cfg and not passed from upper layers. Instead it is initialized here + * This paramtere is used in concurrency to determine if there are concurrent active sessions. + * Is used as a temporary fix to disconnect all active sessions when BMPS enabled so the active session if Infra STA + * will automatically connect back and resume BMPS since resume BMPS is not working when moving from concurrent to + * single session + */ + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + pMac->roam.configParam.doBMPSWorkaround = 0; + +#ifdef WLAN_FEATURE_11AC + pMac->roam.configParam.nVhtChannelWidth = pParam->nVhtChannelWidth; + pMac->roam.configParam.txBFEnable= pParam->enableTxBF; + pMac->roam.configParam.txBFCsnValue = pParam->txBFCsnValue; + pMac->roam.configParam.enableVhtFor24GHz = pParam->enableVhtFor24GHz; + /* Consider Mu-beamformee only if SU-beamformee is enabled */ + if ( pParam->enableTxBF ) + pMac->roam.configParam.txMuBformee= pParam->enableMuBformee; + else + pMac->roam.configParam.txMuBformee= 0; +#endif + pMac->roam.configParam.txLdpcEnable = pParam->enableTxLdpc; + + pMac->roam.configParam.isAmsduSupportInAMPDU = pParam->isAmsduSupportInAMPDU; + pMac->roam.configParam.nSelect5GHzMargin = pParam->nSelect5GHzMargin; + pMac->roam.configParam.ignorePeerErpInfo = pParam->ignorePeerErpInfo; + pMac->roam.configParam.ignorePeerHTopMode = pParam->ignorePeerHTopMode; + pMac->roam.configParam.disableP2PMacSpoofing = + pParam->disableP2PMacSpoofing; + pMac->roam.configParam.enableFatalEvent = + pParam->enableFatalEvent; + pMac->roam.configParam.isCoalesingInIBSSAllowed = + pParam->isCoalesingInIBSSAllowed; + pMac->roam.configParam.allowDFSChannelRoam = pParam->allowDFSChannelRoam; + pMac->roam.configParam.sendDeauthBeforeCon = pParam->sendDeauthBeforeCon; +#ifdef WLAN_FEATURE_AP_HT40_24G + pMac->roam.configParam.apHT40_24GEnabled = pParam->apHT40_24GEnabled; +#endif + pMac->roam.configParam.roamDelayStatsEnabled = pParam->roamDelayStatsEnabled; + pMac->roam.configParam.max_chan_for_dwell_time_cfg = + pParam->max_chan_for_dwell_time_cfg; + + pMac->roam.configParam.enable_edca_params = pParam->enable_edca_params; + pMac->roam.configParam.edca_vo_cwmin = pParam->edca_vo_cwmin; + pMac->roam.configParam.edca_vi_cwmin = pParam->edca_vi_cwmin; + pMac->roam.configParam.edca_bk_cwmin = pParam->edca_bk_cwmin; + pMac->roam.configParam.edca_be_cwmin = pParam->edca_be_cwmin; + + pMac->roam.configParam.edca_vo_cwmax = pParam->edca_vo_cwmax; + pMac->roam.configParam.edca_vi_cwmax = pParam->edca_vi_cwmax; + pMac->roam.configParam.edca_bk_cwmax = pParam->edca_bk_cwmax; + pMac->roam.configParam.edca_be_cwmax = pParam->edca_be_cwmax; + + pMac->roam.configParam.edca_vo_aifs = pParam->edca_vo_aifs; + pMac->roam.configParam.edca_vi_aifs = pParam->edca_vi_aifs; + pMac->roam.configParam.edca_bk_aifs = pParam->edca_bk_aifs; + pMac->roam.configParam.edca_be_aifs = pParam->edca_be_aifs; + } + + return status; +} + +eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + if(pParam) + { + pParam->WMMSupportMode = pMac->roam.configParam.WMMSupportMode; + pParam->Is11eSupportEnabled = pMac->roam.configParam.Is11eSupportEnabled; + pParam->FragmentationThreshold = pMac->roam.configParam.FragmentationThreshold; + pParam->Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabled; + pParam->Is11dSupportEnabledOriginal = pMac->roam.configParam.Is11dSupportEnabledOriginal; + pParam->Is11hSupportEnabled = pMac->roam.configParam.Is11hSupportEnabled; + pParam->channelBondingMode24GHz = csrConvertPhyCBStateToIniValue(pMac->roam.configParam.channelBondingMode24GHz); +#ifdef WLAN_FEATURE_AP_HT40_24G + pParam->channelBondingAPMode24GHz = csrConvertPhyCBStateToIniValue(pMac->roam.configParam.channelBondingAPMode24GHz); +#endif + pParam->channelBondingMode5GHz = csrConvertPhyCBStateToIniValue(pMac->roam.configParam.channelBondingMode5GHz); + pParam->RTSThreshold = pMac->roam.configParam.RTSThreshold; + pParam->phyMode = pMac->roam.configParam.phyMode; + pParam->shortSlotTime = pMac->roam.configParam.shortSlotTime; + pParam->HeartbeatThresh24 = pMac->roam.configParam.HeartbeatThresh24; + pParam->HeartbeatThresh50 = pMac->roam.configParam.HeartbeatThresh50; + pParam->ProprietaryRatesEnabled = pMac->roam.configParam.ProprietaryRatesEnabled; + pParam->TxRate = pMac->roam.configParam.TxRate; + pParam->AdHocChannel24 = pMac->roam.configParam.AdHocChannel24; + pParam->AdHocChannel5G = pMac->roam.configParam.AdHocChannel5G; + pParam->bandCapability = pMac->roam.configParam.bandCapability; + pParam->cbChoice = pMac->roam.configParam.cbChoice; + pParam->bgScanInterval = pMac->roam.configParam.bgScanInterval; + pParam->nActiveMaxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pParam->nActiveMinChnTime = pMac->roam.configParam.nActiveMinChnTime; + pParam->nPassiveMaxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + pParam->nPassiveMinChnTime = pMac->roam.configParam.nPassiveMinChnTime; + pParam->max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pParam->min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + pParam->min_chntime_btc_sco = + pMac->roam.configParam.min_chntime_btc_sco; + pParam->max_chntime_btc_sco = + pMac->roam.configParam.max_chntime_btc_sco; + pParam->disableAggWithBtc = pMac->roam.configParam.disableAggWithBtc; +#ifdef WLAN_AP_STA_CONCURRENCY + pParam->nActiveMaxChnTimeConc = pMac->roam.configParam.nActiveMaxChnTimeConc; + pParam->nActiveMinChnTimeConc = pMac->roam.configParam.nActiveMinChnTimeConc; + pParam->nPassiveMaxChnTimeConc = pMac->roam.configParam.nPassiveMaxChnTimeConc; + pParam->nPassiveMinChnTimeConc = pMac->roam.configParam.nPassiveMinChnTimeConc; + pParam->nRestTimeConc = pMac->roam.configParam.nRestTimeConc; + pParam->nNumStaChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc; + pParam->nNumP2PChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc; +#endif + //Change the unit from microsecond to second + pParam->impsSleepTime = pMac->roam.configParam.impsSleepTime / PAL_TIMER_TO_SEC_UNIT; + pParam->eBand = pMac->roam.configParam.eBand; + pParam->nScanResultAgeCount = pMac->roam.configParam.agingCount; + pParam->scanAgeTimeNCNPS = pMac->roam.configParam.scanAgeTimeNCNPS; + pParam->scanAgeTimeNCPS = pMac->roam.configParam.scanAgeTimeNCPS; + pParam->scanAgeTimeCNPS = pMac->roam.configParam.scanAgeTimeCNPS; + pParam->scanAgeTimeCPS = pMac->roam.configParam.scanAgeTimeCPS; + pParam->bCatRssiOffset = pMac->roam.configParam.bCatRssiOffset; + pParam->nRoamingTime = pMac->roam.configParam.nRoamingTime; + pParam->fEnforce11dChannels = pMac->roam.configParam.fEnforce11dChannels; + pParam->fSupplicantCountryCodeHasPriority = pMac->roam.configParam.fSupplicantCountryCodeHasPriority; + pParam->fEnforceCountryCodeMatch = pMac->roam.configParam.fEnforceCountryCodeMatch; + pParam->fEnforceDefaultDomain = pMac->roam.configParam.fEnforceDefaultDomain; + pParam->vccRssiThreshold = pMac->roam.configParam.vccRssiThreshold; + pParam->vccUlMacLossThreshold = pMac->roam.configParam.vccUlMacLossThreshold; + pParam->IsIdleScanEnabled = pMac->roam.configParam.IsIdleScanEnabled; + pParam->nTxPowerCap = pMac->roam.configParam.nTxPowerCap; + pParam->statsReqPeriodicity = pMac->roam.configParam.statsReqPeriodicity; + pParam->statsReqPeriodicityInPS = pMac->roam.configParam.statsReqPeriodicityInPS; + pParam->addTSWhenACMIsOff = pMac->roam.configParam.addTSWhenACMIsOff; + pParam->fValidateList = pMac->roam.configParam.fValidateList; + pParam->fEnableBypass11d = pMac->scan.fEnableBypass11d; + pParam->fEnableDFSChnlScan = pMac->scan.fEnableDFSChnlScan; + pParam->disable_scan_during_sco = pMac->scan.disable_scan_during_sco; + pParam->fScanTwice = pMac->roam.configParam.fScanTwice; + pParam->fFirstScanOnly2GChnl = pMac->scan.fFirstScanOnly2GChnl; + pParam->fEnableMCCMode = pMac->roam.configParam.fenableMCCMode; + pParam->fAllowMCCGODiffBI = pMac->roam.configParam.fAllowMCCGODiffBI; + pParam->scanCfgAgingTime = pMac->scan.scanResultCfgAgingTime; + pParam->scanBandPreference = pMac->scan.scanBandPreference; +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + vos_mem_copy(&pParam->neighborRoamConfig, + &pMac->roam.configParam.neighborRoamConfig, + sizeof(tCsrNeighborRoamConfigParams)); +#endif +#ifdef WLAN_FEATURE_11AC + pParam->nVhtChannelWidth = pMac->roam.configParam.nVhtChannelWidth; + pParam->enableTxBF = pMac->roam.configParam.txBFEnable; + pParam->txBFCsnValue = pMac->roam.configParam.txBFCsnValue; + pParam->enableVhtFor24GHz = pMac->roam.configParam.enableVhtFor24GHz; + /* Consider Mu-beamformee only if SU-beamformee is enabled */ + if ( pParam->enableTxBF ) + pParam->enableMuBformee = pMac->roam.configParam.txMuBformee; + else + pParam->enableMuBformee = 0; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + vos_mem_copy(&pMac->roam.configParam.csr11rConfig, + &pParam->csr11rConfig, sizeof(tCsr11rConfigParams)); +#endif +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pParam->isFastTransitionEnabled = pMac->roam.configParam.isFastTransitionEnabled; + pParam->RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff; + pParam->nImmediateRoamRssiDiff = pMac->roam.configParam.nImmediateRoamRssiDiff; + pParam->nRoamPrefer5GHz = pMac->roam.configParam.nRoamPrefer5GHz; + pParam->nRoamIntraBand = pMac->roam.configParam.nRoamIntraBand; + pParam->isWESModeEnabled = pMac->roam.configParam.isWESModeEnabled; + pParam->nProbes = pMac->roam.configParam.nProbes; + pParam->nRoamScanHomeAwayTime = pMac->roam.configParam.nRoamScanHomeAwayTime; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pParam->isRoamOffloadScanEnabled = pMac->roam.configParam.isRoamOffloadScanEnabled; + pParam->bFastRoamInConIniFeatureEnabled = pMac->roam.configParam.bFastRoamInConIniFeatureEnabled; + pParam->isPERRoamEnabled = + pMac->roam.configParam.isPERRoamEnabled; + pParam->rateUpThreshold = pMac->roam.configParam.rateUpThreshold; + pParam->rateDownThreshold = pMac->roam.configParam.rateDownThreshold; + pParam->waitPeriodForNextPERScan = + pMac->roam.configParam.waitPeriodForNextPERScan; + pParam->PERtimerThreshold = pMac->roam.configParam.PERtimerThreshold; + pParam->isPERRoamCCAEnabled = + pMac->roam.configParam.isPERRoamCCAEnabled; + pParam->PERRoamFullScanThreshold = + pMac->roam.configParam.PERRoamFullScanThreshold; + pParam->PERroamTriggerPercent = + pMac->roam.configParam.PERroamTriggerPercent; + pParam->PERMinRssiThresholdForRoam = + pMac->roam.configParam.PERMinRssiThresholdForRoam; +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + pParam->enable_lfr_mbb = pMac->roam.configParam.enable_lfr_mbb; +#endif + +#ifdef FEATURE_WLAN_LFR + pParam->isFastRoamIniFeatureEnabled = pMac->roam.configParam.isFastRoamIniFeatureEnabled; +#endif + +#ifdef FEATURE_WLAN_ESE + pParam->isEseIniFeatureEnabled = pMac->roam.configParam.isEseIniFeatureEnabled; +#endif +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + vos_mem_copy(&pParam->neighborRoamConfig, + &pMac->roam.configParam.neighborRoamConfig, + sizeof(tCsrNeighborRoamConfigParams)); + { + int i; + smsLog( pMac, LOG1, FL("Num of Channels in CFG Channel List: %d"), pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + for( i=0; i< pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels; i++) + { + smsLog( pMac, LOG1, "%d ", pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList[i] ); + } + } +#endif + + pParam->enableTxLdpc = pMac->roam.configParam.txLdpcEnable; + + pParam->isAmsduSupportInAMPDU = pMac->roam.configParam.isAmsduSupportInAMPDU; + pParam->nSelect5GHzMargin = pMac->roam.configParam.nSelect5GHzMargin; + pParam->ignorePeerErpInfo = pMac->roam.configParam.ignorePeerErpInfo; + pParam->ignorePeerHTopMode = pMac->roam.configParam.ignorePeerHTopMode; + pParam->disableP2PMacSpoofing = + pMac->roam.configParam.disableP2PMacSpoofing; + pParam->enableFatalEvent = pMac->roam.configParam.enableFatalEvent; + + pParam->isCoalesingInIBSSAllowed = + pMac->roam.configParam.isCoalesingInIBSSAllowed; + pParam->allowDFSChannelRoam = + pMac->roam.configParam.allowDFSChannelRoam; + pParam->sendDeauthBeforeCon = pMac->roam.configParam.sendDeauthBeforeCon; + csrSetChannels(pMac, pParam); +#ifdef WLAN_FEATURE_AP_HT40_24G + pParam->apHT40_24GEnabled = pMac->roam.configParam.apHT40_24GEnabled; +#endif + pParam->max_chan_for_dwell_time_cfg = + pMac->roam.configParam.max_chan_for_dwell_time_cfg; + + pParam->enable_edca_params = pMac->roam.configParam.enable_edca_params; + pParam->edca_vo_cwmin = pMac->roam.configParam.edca_vo_cwmin; + pParam->edca_vi_cwmin = pMac->roam.configParam.edca_vi_cwmin; + pParam->edca_bk_cwmin = pMac->roam.configParam.edca_bk_cwmin; + pParam->edca_be_cwmin = pMac->roam.configParam.edca_be_cwmin; + + pParam->edca_vo_cwmax = pMac->roam.configParam.edca_vo_cwmax; + pParam->edca_vi_cwmax = pMac->roam.configParam.edca_vi_cwmax; + pParam->edca_bk_cwmax = pMac->roam.configParam.edca_bk_cwmax; + pParam->edca_be_cwmax = pMac->roam.configParam.edca_be_cwmax; + + pParam->edca_vo_aifs = pMac->roam.configParam.edca_vo_aifs; + pParam->edca_vi_aifs = pMac->roam.configParam.edca_vi_aifs; + pParam->edca_bk_aifs = pMac->roam.configParam.edca_bk_aifs; + pParam->edca_be_aifs = pMac->roam.configParam.edca_be_aifs; + + status = eHAL_STATUS_SUCCESS; + } + return (status); +} + +eHalStatus csrSetPhyMode(tHalHandle hHal, tANI_U32 phyMode, eCsrBand eBand, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRestartNeeded = eANI_BOOLEAN_FALSE; + eCsrPhyMode newPhyMode = eCSR_DOT11_MODE_AUTO; + do + { + if(eCSR_BAND_24 == eBand) + { + if(CSR_IS_RADIO_A_ONLY(pMac)) break; + if((eCSR_DOT11_MODE_11a & phyMode) || (eCSR_DOT11_MODE_11a_ONLY & phyMode)) break; + } + if(eCSR_BAND_5G == eBand) + { + if(CSR_IS_RADIO_BG_ONLY(pMac)) break; + if((eCSR_DOT11_MODE_11b & phyMode) || (eCSR_DOT11_MODE_11b_ONLY & phyMode) || + (eCSR_DOT11_MODE_11g & phyMode) || (eCSR_DOT11_MODE_11g_ONLY & phyMode) + ) + { + break; + } + } + if((0 == phyMode) || (eCSR_DOT11_MODE_TAURUS & phyMode)) + { + newPhyMode = eCSR_DOT11_MODE_TAURUS; + } + else if(eCSR_DOT11_MODE_AUTO & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_AUTO; + } + else + { + //Check for dual band and higher capability first + if(eCSR_DOT11_MODE_11n_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11n_ONLY != phyMode) break; + newPhyMode = eCSR_DOT11_MODE_11n_ONLY; + } + else if(eCSR_DOT11_MODE_11a_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11a_ONLY != phyMode) break; + if(eCSR_BAND_24 == eBand) break; + newPhyMode = eCSR_DOT11_MODE_11a_ONLY; + eBand = eCSR_BAND_5G; + } + else if(eCSR_DOT11_MODE_11g_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11g_ONLY != phyMode) break; + if(eCSR_BAND_5G == eBand) break; + newPhyMode = eCSR_DOT11_MODE_11g_ONLY; + eBand = eCSR_BAND_24; + } + else if(eCSR_DOT11_MODE_11b_ONLY & phyMode) + { + if(eCSR_DOT11_MODE_11b_ONLY != phyMode) break; + if(eCSR_BAND_5G == eBand) break; + newPhyMode = eCSR_DOT11_MODE_11b_ONLY; + eBand = eCSR_BAND_24; + } + else if(eCSR_DOT11_MODE_11n & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_11n; + } + else if(eCSR_DOT11_MODE_abg & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_abg; + } + else if(eCSR_DOT11_MODE_11a & phyMode) + { + if((eCSR_DOT11_MODE_11g & phyMode) || (eCSR_DOT11_MODE_11b & phyMode)) + { + if(eCSR_BAND_ALL == eBand) + { + newPhyMode = eCSR_DOT11_MODE_abg; + } + else + { + //bad setting + break; + } + } + else + { + newPhyMode = eCSR_DOT11_MODE_11a; + eBand = eCSR_BAND_5G; + } + } + else if(eCSR_DOT11_MODE_11g & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_11g; + eBand = eCSR_BAND_24; + } + else if(eCSR_DOT11_MODE_11b & phyMode) + { + newPhyMode = eCSR_DOT11_MODE_11b; + eBand = eCSR_BAND_24; + } + else + { + //We will never be here + smsLog( pMac, LOGE, FL(" cannot recognize the phy mode 0x%08X"), phyMode ); + newPhyMode = eCSR_DOT11_MODE_AUTO; + } + } + //Done validating + status = eHAL_STATUS_SUCCESS; + //Now we need to check whether a restart is needed. + if(eBand != pMac->roam.configParam.eBand) + { + fRestartNeeded = eANI_BOOLEAN_TRUE; + break; + } + if(newPhyMode != pMac->roam.configParam.phyMode) + { + fRestartNeeded = eANI_BOOLEAN_TRUE; + break; + } + }while(0); + if(HAL_STATUS_SUCCESS(status)) + { + pMac->roam.configParam.eBand = eBand; + pMac->roam.configParam.phyMode = newPhyMode; + if(pfRestartNeeded) + { + *pfRestartNeeded = fRestartNeeded; + } + } + return (status); +} + +void csrPruneChannelListForMode( tpAniSirGlobal pMac, tCsrChannel *pChannelList ) +{ + tANI_U8 Index; + tANI_U8 cChannels; + // for dual band NICs, don't need to trim the channel list.... + if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) + { + // 2.4 GHz band operation requires the channel list to be trimmed to + // the 2.4 GHz channels only... + if ( CSR_IS_24_BAND_ONLY( pMac ) ) + { + for( Index = 0, cChannels = 0; Index < pChannelList->numChannels; + Index++ ) + { + if ( CSR_IS_CHANNEL_24GHZ(pChannelList->channelList[ Index ]) ) + { + pChannelList->channelList[ cChannels ] = pChannelList->channelList[ Index ]; + cChannels++; + } + } + // Cleanup the rest of channels. Note we only need to clean up the channels if we had + // to trim the list. Calling palZeroMemory() with a 0 size is going to throw asserts on + // the debug builds so let's be a bit smarter about that. Zero out the reset of the channels + // only if we need to. + // + // The amount of memory to clear is the number of channesl that we trimmed + // (pChannelList->numChannels - cChannels) times the size of a channel in the structure. + + if ( pChannelList->numChannels > cChannels ) + { + vos_mem_set(&pChannelList->channelList[ cChannels ], + sizeof( pChannelList->channelList[ 0 ] ) * + ( pChannelList->numChannels - cChannels ), 0); + } + + pChannelList->numChannels = cChannels; + } + else if ( CSR_IS_5G_BAND_ONLY( pMac ) ) + { + for ( Index = 0, cChannels = 0; Index < pChannelList->numChannels; Index++ ) + { + if ( CSR_IS_CHANNEL_5GHZ(pChannelList->channelList[ Index ]) ) + { + pChannelList->channelList[ cChannels ] = pChannelList->channelList[ Index ]; + cChannels++; + } + } + // Cleanup the rest of channels. Note we only need to clean up the channels if we had + // to trim the list. Calling palZeroMemory() with a 0 size is going to throw asserts on + // the debug builds so let's be a bit smarter about that. Zero out the reset of the channels + // only if we need to. + // + // The amount of memory to clear is the number of channesl that we trimmed + // (pChannelList->numChannels - cChannels) times the size of a channel in the structure. + if ( pChannelList->numChannels > cChannels ) + { + vos_mem_set(&pChannelList->channelList[ cChannels ], + sizeof( pChannelList->channelList[ 0 ] ) * + ( pChannelList->numChannels - cChannels ), 0); + } + + pChannelList->numChannels = cChannels; + } + } +} +#define INFRA_AP_DEFAULT_CHANNEL 6 +eHalStatus csrIsValidChannel(tpAniSirGlobal pMac, tANI_U8 chnNum) +{ + tANI_U8 index= 0; + eHalStatus status = eHAL_STATUS_FAILURE; + for (index=0; index < pMac->scan.base20MHzChannels.numChannels ;index++) + { + if(pMac->scan.base20MHzChannels.channelList[ index ] == chnNum){ + status = eHAL_STATUS_SUCCESS; + break; + } + } + return status; +} + + +eHalStatus csrInitGetChannels(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 num20MHzChannelsFound = 0; + VOS_STATUS vosStatus; + tANI_U8 Index = 0; + tANI_U8 num40MHzChannelsFound = 0; + + + //TODO: this interface changed to include the 40MHz channel list + // this needs to be tied into the adapter structure somehow and referenced appropriately for CB operation + // Read the scan channel list (including the power limit) from EEPROM + vosStatus = vos_nv_getChannelListWithPower( pMac->scan.defaultPowerTable, &num20MHzChannelsFound, + pMac->scan.defaultPowerTable40MHz, &num40MHzChannelsFound); + if ( (VOS_STATUS_SUCCESS != vosStatus) || (num20MHzChannelsFound == 0) ) + { + smsLog( pMac, LOGE, FL("failed to get channels ")); + status = eHAL_STATUS_FAILURE; + } + else + { + if ( num20MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN ) + { + num20MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + pMac->scan.numChannelsDefault = num20MHzChannelsFound; + // Move the channel list to the global data + // structure -- this will be used as the scan list + for ( Index = 0; Index < num20MHzChannelsFound; Index++) + { + pMac->scan.base20MHzChannels.channelList[ Index ] = pMac->scan.defaultPowerTable[ Index ].chanId; + } + pMac->scan.base20MHzChannels.numChannels = num20MHzChannelsFound; + if(num40MHzChannelsFound > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + num40MHzChannelsFound = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + for ( Index = 0; Index < num40MHzChannelsFound; Index++) + { + pMac->scan.base40MHzChannels.channelList[ Index ] = pMac->scan.defaultPowerTable40MHz[ Index ].chanId; + } + pMac->scan.base40MHzChannels.numChannels = num40MHzChannelsFound; + } + return (status); +} +eHalStatus csrInitChannelList( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels); + csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); + // Apply the base channel list, power info, and set the Country code... + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE ); + limInitOperatingClasses(hHal); + return (status); +} +eHalStatus csrChangeConfigParams(tpAniSirGlobal pMac, + tCsrUpdateConfigParam *pUpdateConfigParam) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsr11dinfo *ps11dinfo = NULL; + ps11dinfo = &pUpdateConfigParam->Csr11dinfo; + status = CsrInit11dInfo(pMac, ps11dinfo); + return status; +} + +static eHalStatus CsrInit11dInfo(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U8 index; + tANI_U32 count=0; + tSirMacChanInfo *pChanInfo; + tSirMacChanInfo *pChanInfoStart; + tANI_BOOLEAN applyConfig = TRUE; + + pMac->scan.currentCountryRSSI = -128; + + if(!ps11dinfo) + { + return (status); + } + if ( ps11dinfo->Channels.numChannels && ( WNI_CFG_VALID_CHANNEL_LIST_LEN >= ps11dinfo->Channels.numChannels ) ) + { + pMac->scan.base20MHzChannels.numChannels = ps11dinfo->Channels.numChannels; + vos_mem_copy(pMac->scan.base20MHzChannels.channelList, + ps11dinfo->Channels.channelList, + ps11dinfo->Channels.numChannels); + } + else + { + //No change + return (eHAL_STATUS_SUCCESS); + } + //legacy maintenance + + vos_mem_copy(pMac->scan.countryCodeDefault, ps11dinfo->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + + + //Tush: at csropen get this initialized with default, during csr reset if this + // already set with some value no need initilaize with default again + if(0 == pMac->scan.countryCodeCurrent[0]) + { + vos_mem_copy(pMac->scan.countryCodeCurrent, ps11dinfo->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + // need to add the max power channel list + pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN); + if (pChanInfo != NULL) + { + vos_mem_set(pChanInfo, + sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN , + 0); + + pChanInfoStart = pChanInfo; + for(index = 0; index < ps11dinfo->Channels.numChannels; index++) + { + pChanInfo->firstChanNum = ps11dinfo->ChnPower[index].firstChannel; + pChanInfo->numChannels = ps11dinfo->ChnPower[index].numChannels; + pChanInfo->maxTxPower = CSR_ROAM_MIN( ps11dinfo->ChnPower[index].maxtxPower, pMac->roam.configParam.nTxPowerCap ); + pChanInfo++; + count++; + } + if(count) + { + csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart ); + } + vos_mem_free(pChanInfoStart); + } + //Only apply them to CFG when not in STOP state. Otherwise they will be applied later + if( HAL_STATUS_SUCCESS(status) ) + { + for( index = 0; index < CSR_ROAM_SESSION_MAX; index++ ) + { + if((CSR_IS_SESSION_VALID(pMac, index)) && CSR_IS_ROAM_STOP(pMac, index)) + { + applyConfig = FALSE; + } + } + + if(TRUE == applyConfig) + { + // Apply the base channel list, power info, and set the Country code... + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE ); + } + + } + return (status); +} +/* Initialize the Channel + Power List in the local cache and in the CFG */ +eHalStatus csrInitChannelPowerList( tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo) +{ + tANI_U8 index; + tANI_U32 count=0; + tSirMacChanInfo *pChanInfo; + tSirMacChanInfo *pChanInfoStart; + + if(!ps11dinfo || !pMac) + { + return eHAL_STATUS_FAILURE; + } + + pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN); + if (pChanInfo != NULL) + { + vos_mem_set(pChanInfo, + sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN, + 0); + pChanInfoStart = pChanInfo; + + for(index = 0; index < ps11dinfo->Channels.numChannels; index++) + { + pChanInfo->firstChanNum = ps11dinfo->ChnPower[index].firstChannel; + pChanInfo->numChannels = ps11dinfo->ChnPower[index].numChannels; + pChanInfo->maxTxPower = CSR_ROAM_MIN( ps11dinfo->ChnPower[index].maxtxPower, pMac->roam.configParam.nTxPowerCap ); + pChanInfo++; + count++; + } + if(count) + { + csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart ); + } + vos_mem_free(pChanInfoStart); + } + + return eHAL_STATUS_SUCCESS; +} + +/** + * csr_roam_remove_duplicate_cmd_from_list()- Remove duplicate roam cmd from + * list + * + * @pMac: pointer to global mac + * @sessionId: session id for the cmd + * @pList: pending list from which cmd needs to be removed + * @pCommand: cmd to be removed, can be NULL + * @eRoamReason: cmd with reason to be removed + * + * Remove duplicate command from the pending list. + * + * Return: void + */ +void csr_roam_remove_duplicate_cmd_from_list(tpAniSirGlobal pMac, + tANI_U32 sessionId, tDblLinkList *pList, + tSmeCmd *pCommand, eCsrRoamReason eRoamReason) +{ + tListElem *pEntry, *pNextEntry; + tSmeCmd *pDupCommand; + tDblLinkList localList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if (!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL("failed to open list")); + return; + } + csrLLLock(pList); + pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); + while (pEntry) + { + pNextEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pDupCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + /* + * Remove the previous command if.. + * - the new roam command is for the same RoamReason... + * - the new roam command is a NewProfileList. + * - the new roam command is a Forced Dissoc + * - the new roam command is from an 802.11 OID + * (OID_SSID or OID_BSSID). + */ + if ((pCommand && (pCommand->sessionId == pDupCommand->sessionId) && + ((pCommand->command == pDupCommand->command) && + /* + * This peermac check is requried for Softap/GO scenarios + * For STA scenario below OR check will suffice as pCommand + * will always be NULL for STA scenarios + */ + (vos_mem_compare(pDupCommand->u.roamCmd.peerMac, + pCommand->u.roamCmd.peerMac, sizeof(v_MACADDR_t))) && + ((pCommand->u.roamCmd.roamReason == + pDupCommand->u.roamCmd.roamReason) || + (eCsrForcedDisassoc == pCommand->u.roamCmd.roamReason) || + (eCsrHddIssued == pCommand->u.roamCmd.roamReason)))) || + /* OR if pCommand is NULL */ + ((sessionId == pDupCommand->sessionId) && + (eSmeCommandRoam == pDupCommand->command) && + ((eCsrForcedDisassoc == eRoamReason) || + (eCsrHddIssued == eRoamReason)))) + { + smsLog(pMac, LOGW, FL("RoamReason = %d"), + pDupCommand->u.roamCmd.roamReason); + /* Remove the 'stale' roam command from the pending list */ + if (csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK)) + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + pEntry = pNextEntry; + } + csrLLUnlock(pList); + + while ((pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK))) + { + pDupCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* Tell caller that the command is cancelled */ + csrRoamCallCallback(pMac, pDupCommand->sessionId, NULL, + pDupCommand->u.roamCmd.roamId, + eCSR_ROAM_CANCELLED, eCSR_ROAM_RESULT_NONE); + csrReleaseCommandRoam(pMac, pDupCommand); + } + csrLLClose(&localList); +} + +/** + * csrRoamRemoveDuplicateCommand()- Remove duplicate roam cmd + * from pending lists. + * + * @pMac: pointer to global mac + * @sessionId: session id for the cmd + * @pCommand: cmd to be removed, can be null + * @eRoamReason: cmd with reason to be removed + * + * Remove duplicate command from the sme and roam pending list. + * + * Return: void + */ +void csrRoamRemoveDuplicateCommand(tpAniSirGlobal pMac, + tANI_U32 sessionId, tSmeCmd *pCommand, + eCsrRoamReason eRoamReason) +{ + /* Always lock active list before locking pending lists */ + csrLLLock(&pMac->sme.smeCmdActiveList); + csr_roam_remove_duplicate_cmd_from_list(pMac, + sessionId, &pMac->sme.smeCmdPendingList, + pCommand, eRoamReason); + csr_roam_remove_duplicate_cmd_from_list(pMac, + sessionId, &pMac->roam.roamCmdPendingList, + pCommand, eRoamReason); + csrLLUnlock(&pMac->sme.smeCmdActiveList); +} + +eHalStatus csrRoamCallCallback(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus u1, eCsrRoamResult u2) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + WLAN_VOS_DIAG_EVENT_DEF(connectionStatus, vos_event_wlan_status_payload_type); +#endif + tCsrRoamSession *pSession = NULL; + if( CSR_IS_SESSION_VALID( pMac, sessionId) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + } + else + { + smsLog(pMac, LOGE, "Session ID:%d is not valid", sessionId); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE; + } + + if (eANI_BOOLEAN_FALSE == pSession->sessionActive) + { + smsLog(pMac, LOG1, "%s Session is not Active", __func__); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG4, "Recieved RoamCmdStatus %d with Roam Result %d", u1, u2); + + if(eCSR_ROAM_ASSOCIATION_COMPLETION == u1 && pRoamInfo) + { + smsLog(pMac, LOGW, " Assoc complete result = %d statusCode = %d reasonCode = %d", u2, pRoamInfo->statusCode, pRoamInfo->reasonCode); + } + if ((u1 == eCSR_ROAM_FT_REASSOC_FAILED) && (pSession->bRefAssocStartCnt)) { + /* + * Decrement bRefAssocStartCnt for FT reassoc failure. + * Reason: For FT reassoc failures, we first call + * csrRoamCallCallback before notifying a failed roam + * completion through csrRoamComplete. The latter in + * turn calls csrRoamProcessResults which tries to + * once again call csrRoamCallCallback if bRefAssocStartCnt + * is non-zero. Since this is redundant for FT reassoc + * failure, decrement bRefAssocStartCnt. + */ + pSession->bRefAssocStartCnt--; + } + + if(NULL != pSession->callback) + { + if( pRoamInfo ) + { + pRoamInfo->sessionId = (tANI_U8)sessionId; + } + + /* avoid holding the global lock when making the roaming callback, original change came + from a raised CR (CR304874). Since this callback is in HDD a potential deadlock + is possible on other OS ports where the callback may need to take locks to protect + HDD state + UPDATE : revert this change but keep the comments here. Need to revisit as there are callbacks + that may actually depend on the lock being held */ + // TODO: revisit: sme_ReleaseGlobalLock( &pMac->sme ); + status = pSession->callback(pSession->pContext, pRoamInfo, roamId, u1, u2); + // TODO: revisit: sme_AcquireGlobalLock( &pMac->sme ); + } + //EVENT_WLAN_STATUS_V2: eCSR_ROAM_ASSOCIATION_COMPLETION, + // eCSR_ROAM_LOSTLINK, eCSR_ROAM_DISASSOCIATED, +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + vos_mem_set(&connectionStatus, + sizeof(vos_event_wlan_status_payload_type), 0); + + if((eCSR_ROAM_ASSOCIATION_COMPLETION == u1) && (eCSR_ROAM_RESULT_ASSOCIATED == u2) && pRoamInfo) + { + connectionStatus.eventId = eCSR_WLAN_STATUS_CONNECT; + connectionStatus.bssType = pRoamInfo->u.pConnectedProfile->BSSType; + if(NULL != pRoamInfo->pBssDesc) + { + connectionStatus.rssi = pRoamInfo->pBssDesc->rssi * (-1); + connectionStatus.channel = pRoamInfo->pBssDesc->channelId; + } + connectionStatus.qosCapability = pRoamInfo->u.pConnectedProfile->qosConnection; + connectionStatus.authType = (v_U8_t)diagAuthTypeFromCSRType(pRoamInfo->u.pConnectedProfile->AuthType); + connectionStatus.encryptionType = (v_U8_t)diagEncTypeFromCSRType(pRoamInfo->u.pConnectedProfile->EncryptionType); + vos_mem_copy(connectionStatus.ssid, + pRoamInfo->u.pConnectedProfile->SSID.ssId, + pRoamInfo->u.pConnectedProfile->SSID.length); + + connectionStatus.reason = eCSR_REASON_UNSPECIFIED; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS_V2); + } + if((eCSR_ROAM_MIC_ERROR_IND == u1) || (eCSR_ROAM_RESULT_MIC_FAILURE == u2)) + { + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_MIC_ERROR; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS_V2); + } + if(eCSR_ROAM_RESULT_FORCED == u2) + { + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_USER_REQUESTED; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS_V2); + } + if(eCSR_ROAM_RESULT_DISASSOC_IND == u2) + { + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_DISASSOC; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS_V2); + } + if(eCSR_ROAM_RESULT_DEAUTH_IND == u2) + { + connectionStatus.eventId = eCSR_WLAN_STATUS_DISCONNECT; + connectionStatus.reason = eCSR_REASON_DEAUTH; + WLAN_VOS_DIAG_EVENT_REPORT(&connectionStatus, EVENT_WLAN_STATUS_V2); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + + return (status); +} +// Returns whether handoff is currently in progress or not +tANI_BOOLEAN csrRoamIsHandoffInProgress(tpAniSirGlobal pMac) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + return csrNeighborRoamIsHandoffInProgress(pMac); +#else + return eANI_BOOLEAN_FALSE; +#endif +} +eHalStatus csrRoamIssueDisassociate( tpAniSirGlobal pMac, tANI_U32 sessionId, + eCsrRoamSubState NewSubstate, tANI_BOOLEAN fMICFailure ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tANI_U16 reasonCode; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + //Restore AC weight in case we change it + if ( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, FL(" restore AC weights (%d-%d-%d-%d)"), pMac->roam.ucACWeights[0], pMac->roam.ucACWeights[1], + pMac->roam.ucACWeights[2], pMac->roam.ucACWeights[3]); + WLANTL_SetACWeights(pMac->roam.gVosContext, pMac->roam.ucACWeights); + } + + if ( fMICFailure ) + { + reasonCode = eSIR_MAC_MIC_FAILURE_REASON; + } + else if (NewSubstate == eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF) + { + reasonCode = eSIR_MAC_DISASSOC_DUE_TO_FTHANDOFF_REASON; + } + else + { + reasonCode = eSIR_MAC_UNSPEC_FAILURE_REASON; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if ( (csrRoamIsHandoffInProgress(pMac)) && + (NewSubstate != eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF)) + { + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + vos_mem_copy(&bssId, + pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, + sizeof(tSirMacAddr)); + } + else +#endif + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + + + smsLog(pMac, LOG2, FL("CSR Attempting to Disassociate Bssid="MAC_ADDRESS_STR + " subState = %s reason=%d"), + MAC_ADDR_ARRAY(bssId), macTraceGetcsrRoamSubState(NewSubstate), + reasonCode); + + csrRoamSubstateChange( pMac, NewSubstate, sessionId); + + status = csrSendMBDisassocReqMsg( pMac, sessionId, bssId, reasonCode ); + + if(HAL_STATUS_SUCCESS(status)) + { + csrRoamLinkDown(pMac, sessionId); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + //no need to tell QoS that we are disassociating, it will be taken care off in assoc req for HO + if(eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF != NewSubstate) + { + //notify QoS module that disassoc happening + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_DISCONNECT_REQ, NULL); + } +#endif + } + else + { + smsLog(pMac, LOGW, FL("csrSendMBDisassocReqMsg failed with status %d"), status); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDisassociateStaCmd + \brief csr function that HDD calls to disassociate a associated station + \param sessionId - session Id for Soft AP + \param pPeerMacAddr - MAC of associated station to delete + \param reason - reason code, be one of the tSirMacReasonCodes + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDisassociateStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pPeerMacAddr, +#else + tANI_U8 *pPeerMacAddr, +#endif + tANI_U32 reason) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + do + { + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta; + vos_mem_copy(pCommand->u.roamCmd.peerMac, pPeerMacAddr, 6); + pCommand->u.roamCmd.reason = (tSirMacReasonCodes)reason; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + }while(0); + + return status; +} + + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDeauthSta + \brief csr function that HDD calls to delete a associated station + \param sessionId - session Id for Soft AP + \param pDelStaParams- Pointer to parameters of the station to deauthenticate + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDeauthStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, + struct tagCsrDelStaParams *pDelStaParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + do + { + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta; + vos_mem_copy(pCommand->u.roamCmd.peerMac, pDelStaParams->peerMacAddr, + sizeof(tSirMacAddr)); + pCommand->u.roamCmd.reason = + (tSirMacReasonCodes)pDelStaParams->reason_code; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + }while(0); + + return status; +} +eHalStatus +csrRoamIssueTkipCounterMeasures( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN bEnable ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!pSession) + { + smsLog( pMac, LOGE, "csrRoamIssueTkipCounterMeasures:CSR Session not found"); + return (status); + } + if (pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + else + { + smsLog( pMac, LOGE, "csrRoamIssueTkipCounterMeasures:Connected BSS Description in CSR Session not found"); + return (status); + } + smsLog( pMac, LOG2, "CSR issuing tkip counter measures for Bssid = "MAC_ADDRESS_STR", Enable = %d", + MAC_ADDR_ARRAY(bssId), bEnable); + status = csrSendMBTkipCounterMeasuresReqMsg( pMac, sessionId, bEnable, bssId ); + return (status); +} +eHalStatus +csrRoamGetAssociatedStas( tpAniSirGlobal pMac, tANI_U32 sessionId, + VOS_MODULE_ID modId, void *pUsrContext, + void *pfnSapEventCallback, v_U8_t *pAssocStasBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!pSession) + { + smsLog( pMac, LOGE, "csrRoamGetAssociatedStas:CSR Session not found"); + return (status); + } + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + else + { + smsLog( pMac, LOGE, "csrRoamGetAssociatedStas:Connected BSS Description in CSR Session not found"); + return (status); + } + smsLog( pMac, LOG2, "CSR getting associated stations for Bssid = "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssId)); + status = csrSendMBGetAssociatedStasReqMsg( pMac, sessionId, modId, bssId, pUsrContext, pfnSapEventCallback, pAssocStasBuf ); + return (status); +} +eHalStatus +csrRoamGetWpsSessionOverlap( tpAniSirGlobal pMac, tANI_U32 sessionId, + void *pUsrContext, void *pfnSapEventCallback, v_MACADDR_t pRemoveMac ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog( pMac, LOGE, "csrRoamGetWpsSessionOverlap:CSR Session not found"); + return (status); + } + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + else + { + smsLog( pMac, LOGE, "csrRoamGetWpsSessionOverlap:Connected BSS Description in CSR Session not found"); + return (status); + } + smsLog( pMac, LOG2, "CSR getting WPS Session Overlap for Bssid = "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssId)); + + status = csrSendMBGetWPSPBCSessions( pMac, sessionId, bssId, pUsrContext, pfnSapEventCallback, pRemoveMac); + + return (status); +} +eHalStatus csrRoamIssueDeauth( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamSubState NewSubstate ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBssid bssId = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&bssId, pSession->pConnectBssDesc->bssId, sizeof(tCsrBssid)); + } + smsLog( pMac, LOG2, "CSR Attempting to Deauth Bssid= "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssId)); + csrRoamSubstateChange( pMac, NewSubstate, sessionId); + + status = csrSendMBDeauthReqMsg( pMac, sessionId, bssId, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON ); + if(HAL_STATUS_SUCCESS(status)) + { + csrRoamLinkDown(pMac, sessionId); + } + else + { + smsLog(pMac, LOGE, FL("csrSendMBDeauthReqMsg failed with status %d Session ID: %d" + MAC_ADDRESS_STR ), status, sessionId, MAC_ADDR_ARRAY(bssId)); + } + + return (status); +} + +eHalStatus csrRoamSaveConnectedBssDesc( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDesc ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U32 size; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + // If no BSS description was found in this connection (happens with start IBSS), then + // nix the BSS description that we keep around for the connected BSS) and get out... + if(NULL == pBssDesc) + { + csrFreeConnectBssDesc(pMac, sessionId); + } + else + { + size = pBssDesc->length + sizeof( pBssDesc->length ); + if(NULL != pSession->pConnectBssDesc) + { + if(((pSession->pConnectBssDesc->length) + sizeof(pSession->pConnectBssDesc->length)) < size) + { + //not enough room for the new BSS, pMac->roam.pConnectBssDesc is freed inside + csrFreeConnectBssDesc(pMac, sessionId); + } + } + if(NULL == pSession->pConnectBssDesc) + { + pSession->pConnectBssDesc = vos_mem_malloc(size); + } + if (NULL == pSession->pConnectBssDesc) + status = eHAL_STATUS_FAILURE; + else + vos_mem_copy(pSession->pConnectBssDesc, pBssDesc, size); + } + return (status); +} + +eHalStatus csrRoamPrepareBssConfig(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, + tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrCfgDot11Mode cfgDot11Mode; + VOS_ASSERT( pIes != NULL ); + if (pIes == NULL) + return eHAL_STATUS_FAILURE; + + do + { + vos_mem_copy(&pBssConfig->BssCap, &pBssDesc->capabilityInfo, + sizeof(tSirMacCapabilityInfo)); + //get qos + pBssConfig->qosType = csrGetQoSFromBssDesc(pMac, pBssDesc, pIes); + //get SSID + if(pIes->SSID.present) + { + vos_mem_copy(&pBssConfig->SSID.ssId, pIes->SSID.ssid, pIes->SSID.num_ssid); + pBssConfig->SSID.length = pIes->SSID.num_ssid; + } + else + pBssConfig->SSID.length = 0; + if(csrIsNULLSSID(pBssConfig->SSID.ssId, pBssConfig->SSID.length)) + { + smsLog(pMac, LOGW, " BSS desc SSID is a wildcard"); + //Return failed if profile doesn't have an SSID either. + if(pProfile->SSIDs.numOfSSIDs == 0) + { + smsLog(pMac, LOGW, " Both BSS desc and profile doesn't have SSID"); + status = eHAL_STATUS_FAILURE; + break; + } + } + if(CSR_IS_CHANNEL_5GHZ(pBssDesc->channelId)) + { + pBssConfig->eBand = eCSR_BAND_5G; + } + else + { + pBssConfig->eBand = eCSR_BAND_24; + } + //phymode + if(csrIsPhyModeMatch( pMac, pProfile->phyMode, pBssDesc, pProfile, &cfgDot11Mode, pIes )) + { + pBssConfig->uCfgDot11Mode = cfgDot11Mode; + } + else + { + smsLog(pMac, LOGW, " Can not find match phy mode"); + //force it + if(eCSR_BAND_24 == pBssConfig->eBand) + { + pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + else + { + pBssConfig->uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + } + smsLog(pMac, LOG1, FL("phyMode %d uCfgDot11Mode %d"), + pProfile->phyMode, pBssConfig->uCfgDot11Mode); + //Qos + if ((pBssConfig->uCfgDot11Mode != eCSR_CFG_DOT11_MODE_11N) && + (pMac->roam.configParam.WMMSupportMode == eCsrRoamWmmNoQos)) + { + //Joining BSS is not 11n capable and WMM is disabled on client. + //Disable QoS and WMM + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF; + } + + if (((pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11N) || + (pBssConfig->uCfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC)) && + ((pBssConfig->qosType != eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP) || + (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_HCF) || + (pBssConfig->qosType != eCSR_MEDIUM_ACCESS_11e_eDCF) )) + { + //Joining BSS is 11n capable and WMM is disabled on AP. + //Assume all HT AP's are QOS AP's and enable WMM + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; + } + + //auth type + switch( pProfile->negotiatedAuthType ) + { + default: + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + pBssConfig->authType = eSIR_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + pBssConfig->authType = eSIR_SHARED_KEY; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + pBssConfig->authType = eSIR_AUTO_SWITCH; + break; + } + //short slot time + if( eCSR_CFG_DOT11_MODE_11B != cfgDot11Mode ) + { + pBssConfig->uShortSlotTime = pMac->roam.configParam.shortSlotTime; + } + else + { + pBssConfig->uShortSlotTime = 0; + } + if(pBssConfig->BssCap.ibss) + { + //We don't support 11h on IBSS + pBssConfig->f11hSupport = eANI_BOOLEAN_FALSE; + } + else + { + pBssConfig->f11hSupport = pMac->roam.configParam.Is11hSupportEnabled; + } + //power constraint + pBssConfig->uPowerLimit = csrGet11hPowerConstraint(pMac, &pIes->PowerConstraints); + //heartbeat + if ( CSR_IS_11A_BSS( pBssDesc ) ) + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh50; + } + else + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh24; + } + //Join timeout + // if we find a BeaconInterval in the BssDescription, then set the Join Timeout to + // be 10 x the BeaconInterval. + if ( pBssDesc->beaconInterval ) + { + //Make sure it is bigger than the minimal + pBssConfig->uJoinTimeOut = CSR_ROAM_MAX(10 * pBssDesc->beaconInterval, CSR_JOIN_FAILURE_TIMEOUT_MIN); + } + else + { + pBssConfig->uJoinTimeOut = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT; + } + //validate CB + pBssConfig->cbMode = csrGetCBModeFromIes(pMac, pBssDesc->channelId, pIes); + if (CSR_IS_CHANNEL_24GHZ(pBssDesc->channelId) && + pProfile->force_24ghz_in_ht20) { + pBssConfig->cbMode = PHY_SINGLE_CHANNEL_CENTERED; + smsLog(pMac, LOG1, + FL("force_24ghz_in_ht20 is set so set cbmode to 0")); + } + smsLog(pMac, LOG1, FL("Bss Cb is %d, join timeout is %d, HB thresh is %d,"), + pBssConfig->cbMode, pBssConfig->uJoinTimeOut, pBssConfig->uHeartBeatThresh); + }while(0); + return (status); +} + +static eHalStatus csrRoamPrepareBssConfigFromProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tBssConfigParam *pBssConfig, tSirBssDescription *pBssDesc) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 operationChannel = 0; + tANI_U8 qAPisEnabled = FALSE; + //SSID + pBssConfig->SSID.length = 0; + if(pProfile->SSIDs.numOfSSIDs) + { + //only use the first one + vos_mem_copy(&pBssConfig->SSID, &pProfile->SSIDs.SSIDList[0].SSID, + sizeof(tSirMacSSid)); + } + else + { + //SSID must present + return eHAL_STATUS_FAILURE; + } + //Settomg up the capabilities + if( csrIsBssTypeIBSS(pProfile->BSSType) ) + { + pBssConfig->BssCap.ibss = 1; + } + else + { + pBssConfig->BssCap.ess = 1; + } + if( eCSR_ENCRYPT_TYPE_NONE != pProfile->EncryptionType.encryptionType[0] ) + { + pBssConfig->BssCap.privacy = 1; + } + pBssConfig->eBand = pMac->roam.configParam.eBand; + //phymode + if(pProfile->ChannelInfo.ChannelList) + { + operationChannel = pProfile->ChannelInfo.ChannelList[0]; + } + pBssConfig->uCfgDot11Mode = csrRoamGetPhyModeBandForBss(pMac, pProfile, operationChannel, + &pBssConfig->eBand); + //QOS + //Is this correct to always set to this //*** + if ( pBssConfig->BssCap.ess == 1 ) + { + /*For Softap case enable WMM*/ + if(CSR_IS_INFRA_AP(pProfile) && (eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode )){ + qAPisEnabled = TRUE; + } + else + if (csrRoamGetQosInfoFromBss(pMac, pBssDesc) == eHAL_STATUS_SUCCESS) { + qAPisEnabled = TRUE; + } else { + qAPisEnabled = FALSE; + } + } else { + qAPisEnabled = TRUE; + } + if (( eCsrRoamWmmNoQos != pMac->roam.configParam.WMMSupportMode && qAPisEnabled) || + (( eCSR_CFG_DOT11_MODE_11N == pBssConfig->uCfgDot11Mode && qAPisEnabled) || + ( eCSR_CFG_DOT11_MODE_TAURUS == pBssConfig->uCfgDot11Mode ) ) //For 11n, need QoS + ) + { + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; + } else { + pBssConfig->qosType = eCSR_MEDIUM_ACCESS_DCF; + } + + //auth type + switch( pProfile->AuthType.authType[0] ) //Take the preferred Auth type. + { + default: + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + pBssConfig->authType = eSIR_OPEN_SYSTEM; + break; + case eCSR_AUTH_TYPE_SHARED_KEY: + pBssConfig->authType = eSIR_SHARED_KEY; + break; + case eCSR_AUTH_TYPE_AUTOSWITCH: + pBssConfig->authType = eSIR_AUTO_SWITCH; + break; + } + //short slot time + if( WNI_CFG_PHY_MODE_11B != pBssConfig->uCfgDot11Mode ) + { + pBssConfig->uShortSlotTime = pMac->roam.configParam.shortSlotTime; + } + else + { + pBssConfig->uShortSlotTime = 0; + } + //power constraint. We don't support 11h on IBSS + pBssConfig->f11hSupport = eANI_BOOLEAN_FALSE; + pBssConfig->uPowerLimit = 0; + //heartbeat + if ( eCSR_BAND_5G == pBssConfig->eBand ) + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh50; + } + else + { + pBssConfig->uHeartBeatThresh = pMac->roam.configParam.HeartbeatThresh24; + } + //Join timeout + pBssConfig->uJoinTimeOut = CSR_JOIN_FAILURE_TIMEOUT_DEFAULT; + + return (status); +} +static eHalStatus csrRoamGetQosInfoFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tDot11fBeaconIEs *pIes = NULL; + + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "csrRoamGetQosInfoFromBss() failed"); + break; + } + //check if the AP is QAP & it supports APSD + if( CSR_IS_QOS_BSS(pIes) ) + { + status = eHAL_STATUS_SUCCESS; + } + } while (0); + + if (NULL != pIes) + { + vos_mem_free(pIes); + } + + return status; +} + +void csrSetCfgPrivacy( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, tANI_BOOLEAN fPrivacy ) +{ + // !! Note: the only difference between this function and the csrSetCfgPrivacyFromProfile() is the + // setting of the privacy CFG based on the advertised privacy setting from the AP for WPA associations. + // See !!Note: below in this function... + tANI_U32 PrivacyEnabled = 0; + tANI_U32 RsnEnabled = 0; + tANI_U32 WepDefaultKeyId = 0; + tANI_U32 WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5; /* default 40 bits */ + tANI_U32 Key0Length = 0; + tANI_U32 Key1Length = 0; + tANI_U32 Key2Length = 0; + tANI_U32 Key3Length = 0; + + // Reserve for the biggest key + tANI_U8 Key0[ WNI_CFG_WEP_DEFAULT_KEY_1_LEN ]; + tANI_U8 Key1[ WNI_CFG_WEP_DEFAULT_KEY_2_LEN ]; + tANI_U8 Key2[ WNI_CFG_WEP_DEFAULT_KEY_3_LEN ]; + tANI_U8 Key3[ WNI_CFG_WEP_DEFAULT_KEY_4_LEN ]; + + switch ( pProfile->negotiatedUCEncryptionType ) + { + case eCSR_ENCRYPT_TYPE_NONE: + + // for NO encryption, turn off Privacy and Rsn. + PrivacyEnabled = 0; + RsnEnabled = 0; + + // WEP key length and Wep Default Key ID don't matter in this case.... + + // clear out the WEP keys that may be hanging around. + Key0Length = 0; + Key1Length = 0; + Key2Length = 0; + Key3Length = 0; + + break; + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + + // Privacy is ON. NO RSN for Wep40 static key. + PrivacyEnabled = 1; + RsnEnabled = 0; + + // Set the Wep default key ID. + WepDefaultKeyId = pProfile->Keys.defaultIndex; + // Wep key size if 5 bytes (40 bits). + WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_5; + + // set encryption keys in the CFG database or clear those that are not present in this profile. + if ( pProfile->Keys.KeyLength[0] ) + { + vos_mem_copy(Key0, pProfile->Keys.KeyMaterial[0], + WNI_CFG_WEP_KEY_LENGTH_5); + Key0Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key0Length = 0; + } + + if ( pProfile->Keys.KeyLength[1] ) + { + vos_mem_copy(Key1, pProfile->Keys.KeyMaterial[1], + WNI_CFG_WEP_KEY_LENGTH_5); + Key1Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key1Length = 0; + } + + if ( pProfile->Keys.KeyLength[2] ) + { + vos_mem_copy(Key2, pProfile->Keys.KeyMaterial[2], + WNI_CFG_WEP_KEY_LENGTH_5); + Key2Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key2Length = 0; + } + + if ( pProfile->Keys.KeyLength[3] ) + { + vos_mem_copy(Key3, pProfile->Keys.KeyMaterial[3], + WNI_CFG_WEP_KEY_LENGTH_5); + Key3Length = WNI_CFG_WEP_KEY_LENGTH_5; + } + else + { + Key3Length = 0; + } + break; + + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + + // Privacy is ON. NO RSN for Wep40 static key. + PrivacyEnabled = 1; + RsnEnabled = 0; + + // Set the Wep default key ID. + WepDefaultKeyId = pProfile->Keys.defaultIndex; + + // Wep key size if 13 bytes (104 bits). + WepKeyLength = WNI_CFG_WEP_KEY_LENGTH_13; + + // set encryption keys in the CFG database or clear those that are not present in this profile. + if ( pProfile->Keys.KeyLength[0] ) + { + vos_mem_copy(Key0, pProfile->Keys.KeyMaterial[ 0 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key0Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key0Length = 0; + } + + if ( pProfile->Keys.KeyLength[1] ) + { + vos_mem_copy(Key1, pProfile->Keys.KeyMaterial[ 1 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key1Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key1Length = 0; + } + + if ( pProfile->Keys.KeyLength[2] ) + { + vos_mem_copy(Key2, pProfile->Keys.KeyMaterial[ 2 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key2Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key2Length = 0; + } + + if ( pProfile->Keys.KeyLength[3] ) + { + vos_mem_copy(Key3, pProfile->Keys.KeyMaterial[ 3 ], + WNI_CFG_WEP_KEY_LENGTH_13); + Key3Length = WNI_CFG_WEP_KEY_LENGTH_13; + } + else + { + Key3Length = 0; + } + + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: +#endif /* FEATURE_WLAN_WAPI */ + // !! Note: this is the only difference between this function and the csrSetCfgPrivacyFromProfile() + // (setting of the privacy CFG based on the advertised privacy setting from the AP for WPA/WAPI associations ). + PrivacyEnabled = (0 != fPrivacy); + + // turn on RSN enabled for WPA associations + RsnEnabled = 1; + + // WEP key length and Wep Default Key ID don't matter in this case.... + + // clear out the static WEP keys that may be hanging around. + Key0Length = 0; + Key1Length = 0; + Key2Length = 0; + Key3Length = 0; + + break; + default: + PrivacyEnabled = 0; + RsnEnabled = 0; + break; + } + + ccmCfgSetInt(pMac, WNI_CFG_PRIVACY_ENABLED, PrivacyEnabled, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_RSN_ENABLED, RsnEnabled, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_1, Key0, Key0Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_2, Key1, Key1Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_3, Key2, Key2Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_WEP_DEFAULT_KEY_4, Key3, Key3Length, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_WEP_KEY_LENGTH, WepKeyLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, WepDefaultKeyId, NULL, eANI_BOOLEAN_FALSE); +} + +static void csrSetCfgSsid( tpAniSirGlobal pMac, tSirMacSSid *pSSID ) +{ + tANI_U32 len = 0; + if(pSSID->length <= WNI_CFG_SSID_LEN) + { + len = pSSID->length; + } + ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pSSID->ssId, len, NULL, eANI_BOOLEAN_FALSE); +} + +eHalStatus csrSetQosToCfg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrMediaAccessType qosType ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 QoSEnabled; + tANI_U32 WmeEnabled; + // set the CFG enable/disable variables based on the qosType being configured... + switch( qosType ) + { + case eCSR_MEDIUM_ACCESS_WMM_eDCF_802dot1p: + QoSEnabled = FALSE; + WmeEnabled = TRUE; + break; + case eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP: + QoSEnabled = FALSE; + WmeEnabled = TRUE; + break; + case eCSR_MEDIUM_ACCESS_WMM_eDCF_NoClassify: + QoSEnabled = FALSE; + WmeEnabled = TRUE; + break; + case eCSR_MEDIUM_ACCESS_11e_eDCF: + QoSEnabled = TRUE; + WmeEnabled = FALSE; + break; + case eCSR_MEDIUM_ACCESS_11e_HCF: + QoSEnabled = TRUE; + WmeEnabled = FALSE; + break; + default: + case eCSR_MEDIUM_ACCESS_DCF: + QoSEnabled = FALSE; + WmeEnabled = FALSE; + break; + } + //save the WMM setting for later use + pMac->roam.roamSession[sessionId].fWMMConnection = (tANI_BOOLEAN)WmeEnabled; + pMac->roam.roamSession[sessionId].fQOSConnection = (tANI_BOOLEAN)QoSEnabled; + return (status); +} +static eHalStatus csrGetRateSet( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes, tSirMacRateSet *pOpRateSet, tSirMacRateSet *pExRateSet, tANI_U16 *pRateBitmap) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + int i; + eCsrCfgDot11Mode cfgDot11Mode; + tANI_U8 *pDstRate; + tANI_U16 rateBitmap = 0; + vos_mem_set(pOpRateSet, sizeof(tSirMacRateSet), 0); + vos_mem_set(pExRateSet, sizeof(tSirMacRateSet), 0); + VOS_ASSERT( pIes != NULL ); + + if( NULL != pIes ) + { + csrIsPhyModeMatch( pMac, phyMode, pBssDesc, pProfile, &cfgDot11Mode, pIes ); + // Originally, we thought that for 11a networks, the 11a rates are always + // in the Operational Rate set & for 11b and 11g networks, the 11b rates + // appear in the Operational Rate set. Consequently, in either case, we + // would blindly put the rates we support into our Operational Rate set + // (including the basic rates, which we have already verified are + // supported earlier in the roaming decision). + // However, it turns out that this is not always the case. Some AP's + // (e.g. D-Link DI-784) ram 11g rates into the Operational Rate set, + // too. Now, we're a little more careful: + pDstRate = pOpRateSet->rate; + if(pIes->SuppRates.present) + { + for ( i = 0; i < pIes->SuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->SuppRates.rates[ i ] ) ) + { + if ( !csrIsRateAlreadyPresent(pIes->SuppRates.rates[ i ], rateBitmap) ) + { + csrAddRateBitmap(pIes->SuppRates.rates[ i ], &rateBitmap); + *pDstRate++ = pIes->SuppRates.rates[ i ]; + pOpRateSet->numRates++; + } + } + } + } + /* If there are Extended Rates in the beacon, we will reflect those + * extended rates that we support in out Extended Operational Rate + * set*/ + pDstRate = pExRateSet->rate; + if(pIes->ExtSuppRates.present) + { + for (i = 0; i < pIes->ExtSuppRates.num_rates; i++) + { + if (csrRatesIsDot11RateSupported(pMac, + pIes->ExtSuppRates.rates[ i ])) + { + if (!csrIsRateAlreadyPresent(pIes->ExtSuppRates.rates[i], + rateBitmap)) + { + csrAddRateBitmap(pIes->ExtSuppRates.rates[i], + &rateBitmap); + *pDstRate++ = pIes->ExtSuppRates.rates[i]; + pExRateSet->numRates++; + } + } + } + } + *pRateBitmap = rateBitmap; + }//Parsing BSSDesc + else + { + smsLog(pMac, LOGE, FL("failed to parse BssDesc")); + } + if (pOpRateSet->numRates > 0 || pExRateSet->numRates > 0) status = eHAL_STATUS_SUCCESS; + return status; +} + +static void csrSetCfgRateSet( tpAniSirGlobal pMac, eCsrPhyMode phyMode, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + int i; + tANI_U8 *pDstRate; + eCsrCfgDot11Mode cfgDot11Mode; + tANI_U8 OperationalRates[ CSR_DOT11_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 OperationalRatesLength = 0; + tANI_U8 ExtendedOperationalRates[ CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 ExtendedOperationalRatesLength = 0; + tANI_U8 ProprietaryOperationalRates[ 4 ]; // leave enough room for the max number of proprietary rates + tANI_U32 ProprietaryOperationalRatesLength = 0; + tANI_U32 PropRatesEnable = 0; + tANI_U8 MCSRateIdxSet[ SIZE_OF_SUPPORTED_MCS_SET ]; + tANI_U32 MCSRateLength = 0; + VOS_ASSERT( pIes != NULL ); + if( NULL != pIes ) + { + csrIsPhyModeMatch( pMac, phyMode, pBssDesc, pProfile, &cfgDot11Mode, pIes ); + // Originally, we thought that for 11a networks, the 11a rates are always + // in the Operational Rate set & for 11b and 11g networks, the 11b rates + // appear in the Operational Rate set. Consequently, in either case, we + // would blindly put the rates we support into our Operational Rate set + // (including the basic rates, which we have already verified are + // supported earlier in the roaming decision). + // However, it turns out that this is not always the case. Some AP's + // (e.g. D-Link DI-784) ram 11g rates into the Operational Rate set, + // too. Now, we're a little more careful: + pDstRate = OperationalRates; + if(pIes->SuppRates.present) + { + for ( i = 0; i < pIes->SuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->SuppRates.rates[ i ] ) && + ( OperationalRatesLength < CSR_DOT11_SUPPORTED_RATES_MAX )) + { + *pDstRate++ = pIes->SuppRates.rates[ i ]; + OperationalRatesLength++; + } + } + } + if ( eCSR_CFG_DOT11_MODE_11G == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11Mode || + eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode ) + { + // If there are Extended Rates in the beacon, we will reflect those + // extended rates that we support in out Extended Operational Rate + // set: + pDstRate = ExtendedOperationalRates; + if(pIes->ExtSuppRates.present) + { + for ( i = 0; i < pIes->ExtSuppRates.num_rates; i++ ) + { + if ( csrRatesIsDot11RateSupported( pMac, pIes->ExtSuppRates.rates[ i ] ) && + ( ExtendedOperationalRatesLength < CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX )) + { + *pDstRate++ = pIes->ExtSuppRates.rates[ i ]; + ExtendedOperationalRatesLength++; + } + } + } + } + // Enable proprietary MAC features if peer node is Airgo node and STA + // user wants to use them + if( pIes->Airgo.present && pMac->roam.configParam.ProprietaryRatesEnabled ) + { + PropRatesEnable = 1; + } + else + { + PropRatesEnable = 0; + } + // For ANI network companions, we need to populate the proprietary rate + // set with any proprietary rates we found in the beacon, only if user + // allows them... + if ( PropRatesEnable && pIes->Airgo.PropSuppRates.present && + ( pIes->Airgo.PropSuppRates.num_rates > 0 )) + { + ProprietaryOperationalRatesLength = pIes->Airgo.PropSuppRates.num_rates; + if ( ProprietaryOperationalRatesLength > sizeof(ProprietaryOperationalRates) ) + { + ProprietaryOperationalRatesLength = sizeof (ProprietaryOperationalRates); + } + vos_mem_copy(ProprietaryOperationalRates, + pIes->Airgo.PropSuppRates.rates, + ProprietaryOperationalRatesLength); + } + else { + // No proprietary modes... + ProprietaryOperationalRatesLength = 0; + } + /* Get MCS Rate */ + pDstRate = MCSRateIdxSet; + if ( pIes->HTCaps.present ) + { + for ( i = 0; i < VALID_MAX_MCS_INDEX; i++ ) + { + if ( (unsigned int)pIes->HTCaps.supportedMCSSet[0] & (1 << i) ) + { + MCSRateLength++; + *pDstRate++ = i; + } + } + } + // Set the operational rate set CFG variables... + ccmCfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, + OperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedOperationalRates, + ExtendedOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + ProprietaryOperationalRates, + ProprietaryOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, PropRatesEnable, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_CURRENT_MCS_SET, MCSRateIdxSet, + MCSRateLength, NULL, eANI_BOOLEAN_FALSE); + }//Parsing BSSDesc + else + { + smsLog(pMac, LOGE, FL("failed to parse BssDesc")); + } +} + +static void csrSetCfgRateSetFromProfile( tpAniSirGlobal pMac, + tCsrRoamProfile *pProfile ) +{ + tSirMacRateSetIE DefaultSupportedRates11a = { SIR_MAC_RATESET_EID, + { 8, + { SIR_MAC_RATE_6, + SIR_MAC_RATE_9, + SIR_MAC_RATE_12, + SIR_MAC_RATE_18, + SIR_MAC_RATE_24, + SIR_MAC_RATE_36, + SIR_MAC_RATE_48, + SIR_MAC_RATE_54 } } }; + tSirMacRateSetIE DefaultSupportedRates11b = { SIR_MAC_RATESET_EID, + { 4, + { SIR_MAC_RATE_1, + SIR_MAC_RATE_2, + SIR_MAC_RATE_5_5, + SIR_MAC_RATE_11 } } }; + + + tSirMacPropRateSet DefaultSupportedPropRates = { 3, + { SIR_MAC_RATE_72, + SIR_MAC_RATE_96, + SIR_MAC_RATE_108 } }; + eCsrCfgDot11Mode cfgDot11Mode; + eCsrBand eBand; + tANI_U8 OperationalRates[ CSR_DOT11_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 OperationalRatesLength = 0; + tANI_U8 ExtendedOperationalRates[ CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX ]; // leave enough room for the max number of rates + tANI_U32 ExtendedOperationalRatesLength = 0; + tANI_U8 ProprietaryOperationalRates[ 4 ]; // leave enough room for the max number of proprietary rates + tANI_U32 ProprietaryOperationalRatesLength = 0; + tANI_U32 PropRatesEnable = 0; + tANI_U8 operationChannel = 0; + if(pProfile->ChannelInfo.ChannelList) + { + operationChannel = pProfile->ChannelInfo.ChannelList[0]; + } + cfgDot11Mode = csrRoamGetPhyModeBandForBss( pMac, pProfile, operationChannel, &eBand ); + // For 11a networks, the 11a rates go into the Operational Rate set. For 11b and 11g + // networks, the 11b rates appear in the Operational Rate set. In either case, + // we can blindly put the rates we support into our Operational Rate set + // (including the basic rates, which we have already verified are supported + // earlier in the roaming decision). + if ( eCSR_BAND_5G == eBand ) + { + // 11a rates into the Operational Rate Set. + OperationalRatesLength = DefaultSupportedRates11a.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11a.supportedRateSet.rate); + vos_mem_copy(OperationalRates, + DefaultSupportedRates11a.supportedRateSet.rate, + OperationalRatesLength); + + // Nothing in the Extended rate set. + ExtendedOperationalRatesLength = 0; + // populate proprietary rates if user allows them + if ( pMac->roam.configParam.ProprietaryRatesEnabled ) + { + ProprietaryOperationalRatesLength = DefaultSupportedPropRates.numPropRates * + sizeof(*DefaultSupportedPropRates.propRate); + vos_mem_copy(ProprietaryOperationalRates, + DefaultSupportedPropRates.propRate, + ProprietaryOperationalRatesLength); + } + else + { + // No proprietary modes + ProprietaryOperationalRatesLength = 0; + } + } + else if ( eCSR_CFG_DOT11_MODE_11B == cfgDot11Mode ) + { + // 11b rates into the Operational Rate Set. + OperationalRatesLength = DefaultSupportedRates11b.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11b.supportedRateSet.rate); + vos_mem_copy(OperationalRates, + DefaultSupportedRates11b.supportedRateSet.rate, + OperationalRatesLength); + // Nothing in the Extended rate set. + ExtendedOperationalRatesLength = 0; + // No proprietary modes + ProprietaryOperationalRatesLength = 0; + } + else + { + // 11G + + // 11b rates into the Operational Rate Set. + OperationalRatesLength = DefaultSupportedRates11b.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11b.supportedRateSet.rate); + vos_mem_copy(OperationalRates, + DefaultSupportedRates11b.supportedRateSet.rate, + OperationalRatesLength); + + // 11a rates go in the Extended rate set. + ExtendedOperationalRatesLength = DefaultSupportedRates11a.supportedRateSet.numRates * + sizeof(*DefaultSupportedRates11a.supportedRateSet.rate); + vos_mem_copy(ExtendedOperationalRates, + DefaultSupportedRates11a.supportedRateSet.rate, + ExtendedOperationalRatesLength); + + // populate proprietary rates if user allows them + if ( pMac->roam.configParam.ProprietaryRatesEnabled ) + { + ProprietaryOperationalRatesLength = DefaultSupportedPropRates.numPropRates * + sizeof(*DefaultSupportedPropRates.propRate); + vos_mem_copy(ProprietaryOperationalRates, + DefaultSupportedPropRates.propRate, + ProprietaryOperationalRatesLength); + } + else + { + // No proprietary modes + ProprietaryOperationalRatesLength = 0; + } + } + // set this to 1 if prop. rates need to be advertised in to the IBSS beacon and user wants to use them + if ( ProprietaryOperationalRatesLength && pMac->roam.configParam.ProprietaryRatesEnabled ) + { + PropRatesEnable = 1; + } + else + { + PropRatesEnable = 0; + } + + // Set the operational rate set CFG variables... + ccmCfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET, OperationalRates, + OperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, ExtendedOperationalRates, + ExtendedOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetStr(pMac, WNI_CFG_PROPRIETARY_OPERATIONAL_RATE_SET, + ProprietaryOperationalRates, + ProprietaryOperationalRatesLength, NULL, eANI_BOOLEAN_FALSE); + ccmCfgSetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, PropRatesEnable, NULL, eANI_BOOLEAN_FALSE); +} +void csrRoamCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + tListElem *pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + tANI_U32 sessionId; + tSmeCmd *pCommand = NULL; + if(NULL == pEntry) + { + smsLog(pMac, LOGW, " CFG_CNF with active list empty"); + return; + } + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + sessionId = pCommand->sessionId; + smsLog(pMac, LOG1, FL("CCM CFG return value is %d, " + " current state : %d sub state : %d "), + result, pMac->roam.curState[sessionId], + pMac->roam.curSubState[sessionId]); + if(CSR_IS_ROAM_JOINING(pMac, sessionId) && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) + { + csrRoamingStateConfigCnfProcessor(pMac, (tANI_U32)result); + } +} + +//This function is very dump. It is here because PE still need WNI_CFG_PHY_MODE +tANI_U32 csrRoamGetPhyModeFromDot11Mode(eCsrCfgDot11Mode dot11Mode, eCsrBand band) +{ + if(eCSR_CFG_DOT11_MODE_11B == dot11Mode) + { + return (WNI_CFG_PHY_MODE_11B); + } + else + { + if(eCSR_BAND_24 == band) + return (WNI_CFG_PHY_MODE_11G); + } + return (WNI_CFG_PHY_MODE_11A); +} + + +#ifdef WLAN_FEATURE_11AC +ePhyChanBondState csrGetHTCBStateFromVHTCBState(ePhyChanBondState aniCBMode) +{ + switch ( aniCBMode ) + { + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + case PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + case PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + default : + return PHY_SINGLE_CHANNEL_CENTERED; + } +} +#endif + +//pIes may be NULL +eHalStatus csrRoamSetBssConfigCfg(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN resetCountry) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + tANI_U8 channel = 0; + //Make sure we have the domain info for the BSS we try to connect to. + //Do we need to worry about sequence for OSs that are not Windows?? + if (pBssDesc) + { + if (csrLearnCountryInformation(pMac, pBssDesc, pIes, eANI_BOOLEAN_TRUE)) + { + //Make sure the 11d info from this BSSDesc can be applied + pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE; + if (VOS_TRUE == resetCountry) + { + csrApplyCountryInformation(pMac, FALSE); + } + else + { + csrApplyCountryInformation(pMac, TRUE); + } + } + if ((csrIs11dSupported (pMac)) && pIes) + { + if (!pIes->Country.present) + { + csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE ); + } + else + { + //Let's also update the below to make sure we don't update CC while + //connected to an AP which is advertising some CC + vos_mem_copy(pMac->scan.currentCountryBssid, + pBssDesc->bssId, sizeof(tSirMacAddr)); + } + } + } + //Qos + csrSetQosToCfg( pMac, sessionId, pBssConfig->qosType ); + //SSID + csrSetCfgSsid(pMac, &pBssConfig->SSID ); + //fragment threshold + //ccmCfgSetInt(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, csrGetFragThresh(pMac), NULL, eANI_BOOLEAN_FALSE); + //RTS threshold + //ccmCfgSetInt(pMac, WNI_CFG_RTS_THRESHOLD, csrGetRTSThresh(pMac), NULL, eANI_BOOLEAN_FALSE); + + //ccmCfgSetInt(pMac, WNI_CFG_DOT11_MODE, csrTranslateToWNICfgDot11Mode(pMac, pBssConfig->uCfgDot11Mode), NULL, eANI_BOOLEAN_FALSE); + //Auth type + ccmCfgSetInt(pMac, WNI_CFG_AUTHENTICATION_TYPE, pBssConfig->authType, NULL, eANI_BOOLEAN_FALSE); + //encryption type + csrSetCfgPrivacy(pMac, pProfile, (tANI_BOOLEAN)pBssConfig->BssCap.privacy ); + //short slot time + ccmCfgSetInt(pMac, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED, pBssConfig->uShortSlotTime, NULL, eANI_BOOLEAN_FALSE); + //11d + ccmCfgSetInt(pMac, WNI_CFG_11D_ENABLED, + ((pBssConfig->f11hSupport) ? pBssConfig->f11hSupport : pProfile->ieee80211d), + NULL, eANI_BOOLEAN_FALSE); + /*//11h + ccmCfgSetInt(pMac, WNI_CFG_11H_ENABLED, pMac->roam.configParam.Is11hSupportEnabled, NULL, eANI_BOOLEAN_FALSE); + */ + ccmCfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, pBssConfig->uPowerLimit, NULL, eANI_BOOLEAN_FALSE); + //CB + + if(CSR_IS_INFRA_AP(pProfile) || CSR_IS_WDS_AP(pProfile) || CSR_IS_IBSS(pProfile)) + { + channel = pProfile->operationChannel; + } + else + { + if(pBssDesc) + { + channel = pBssDesc->channelId; + } + } + if(0 != channel) + { + if(CSR_IS_CHANNEL_24GHZ(channel) && + !pMac->roam.configParam.channelBondingMode24GHz && + !WDA_getFwWlanFeatCaps(HT40_OBSS_SCAN)) + {//On 2.4 Ghz, CB will be disabled if it is not configured through .ini + cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: " + " cbMode disabled cfgCb = %d channelBondingMode24GHz %d", + __func__, cfgCb, pMac->roam.configParam.channelBondingMode24GHz); + } + else + { + cfgCb = pBssConfig->cbMode; + } + } +#ifdef WLAN_FEATURE_11AC + // cbMode = 1 in cfg.ini is mapped to PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + // in function csrConvertCBIniValueToPhyCBState() + // So, max value for cbMode in 40MHz mode is 3 (MAC\src\include\sirParams.h) + if(cfgCb > PHY_DOUBLE_CHANNEL_HIGH_PRIMARY) + { + if(!WDA_getFwWlanFeatCaps(DOT11AC)) { + cfgCb = csrGetHTCBStateFromVHTCBState(cfgCb); + } + else + { + ccmCfgSetInt(pMac, WNI_CFG_VHT_CHANNEL_WIDTH, pMac->roam.configParam.nVhtChannelWidth, NULL, eANI_BOOLEAN_FALSE); + } + } + else +#endif + ccmCfgSetInt(pMac, WNI_CFG_CHANNEL_BONDING_MODE, cfgCb, NULL, eANI_BOOLEAN_FALSE); + //Rate + //Fixed Rate + if(pBssDesc) + { + csrSetCfgRateSet(pMac, (eCsrPhyMode)pProfile->phyMode, pProfile, pBssDesc, pIes); + } + else + { + csrSetCfgRateSetFromProfile(pMac, pProfile); + } + //Make this the last CFG to set. The callback will trigger a join_req + //Join time out + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_CONFIG, sessionId ); + + ccmCfgSetInt(pMac, WNI_CFG_JOIN_FAILURE_TIMEOUT, pBssConfig->uJoinTimeOut, (tCcmCfgSetCallback)csrRoamCcmCfgSetCallback, eANI_BOOLEAN_FALSE); + return (status); +} + +eHalStatus csrRoamStopNetwork( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + eHalStatus status; + tBssConfigParam *pBssConfig; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pBssConfig = vos_mem_malloc(sizeof(tBssConfigParam)); + if ( NULL == pBssConfig ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pBssConfig, sizeof(tBssConfigParam), 0); + status = csrRoamPrepareBssConfig(pMac, pProfile, pBssDesc, pBssConfig, pIes); + if(HAL_STATUS_SUCCESS(status)) + { + pSession->bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode; + /* This will allow to pass cbMode during join req */ + pSession->bssParams.cbMode= pBssConfig->cbMode; + //For IBSS, we need to prepare some more information + if( csrIsBssTypeIBSS(pProfile->BSSType) || CSR_IS_WDS( pProfile ) + || CSR_IS_INFRA_AP(pProfile) + ) + { + csrRoamPrepareBssParams(pMac, sessionId, pProfile, pBssDesc, pBssConfig, pIes); + } + // If we are in an IBSS, then stop the IBSS... + ////Not worry about WDS connection for now + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING ); + } + else + { + // if we are in an Infrastructure association.... + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + // and the new Bss is an Ibss OR we are roaming from Infra to Infra + // across SSIDs (roaming to a new SSID)... // + //Not worry about WDS connection for now + if ( pBssDesc && ( ( csrIsIbssBssDesc( pBssDesc ) ) || + !csrIsSsidEqual( pMac, pSession->pConnectBssDesc, pBssDesc, pIes ) ) ) + { + // then we need to disassociate from the Infrastructure network... + status = csrRoamIssueDisassociate( pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE ); + } + else + { + // In an Infrastucture and going to an Infrastructure network with the same SSID. This + // calls for a Reassociation sequence. So issue the CFG sets for this new AP. + if ( pBssDesc ) + { + // Set parameters for this Bss. + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + pBssDesc, pBssConfig, + pIes, eANI_BOOLEAN_FALSE); + } + } + } + else + { + // Neiher in IBSS nor in Infra. We can go ahead and set the CFG for tne new network... + // Nothing to stop. + if ( pBssDesc || CSR_IS_WDS_AP( pProfile ) + || CSR_IS_INFRA_AP(pProfile) + ) + { + tANI_BOOLEAN is11rRoamingFlag = eANI_BOOLEAN_FALSE; + is11rRoamingFlag = csrRoamIs11rAssoc(pMac); + // Set parameters for this Bss. + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + pBssDesc, pBssConfig, + pIes, is11rRoamingFlag); + } + } + } + }//Success getting BSS config info + vos_mem_free(pBssConfig); + }//Allocate memory + return (status); +} + +eCsrJoinState csrRoamJoin( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrScanResultInfo *pScanResult, tCsrRoamProfile *pProfile ) +{ + eCsrJoinState eRoamState = eCsrContinueRoaming; + eHalStatus status; + tSirBssDescription *pBssDesc = &pScanResult->BssDescriptor; + tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)( pScanResult->pvIes ); //This may be NULL + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return (eCsrStopRoaming); + } + + if( CSR_IS_WDS_STA( pProfile ) ) + { + status = csrRoamStartWds( pMac, sessionId, pProfile, pBssDesc ); + if( !HAL_STATUS_SUCCESS( status ) ) + { + eRoamState = eCsrStopRoaming; + } + } + else + { + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + return (eCsrStopRoaming); + } + if ( csrIsInfraBssDesc( pBssDesc ) ) + { + // If we are connected in infrastructure mode and the Join Bss description is for the same BssID, then we are + // attempting to join the AP we are already connected with. In that case, see if the Bss or Sta capabilities + // have changed and handle the changes (without disturbing the current association). + + if ( csrIsConnStateConnectedInfra(pMac, sessionId) && + csrIsBssIdEqual( pMac, pBssDesc, pSession->pConnectBssDesc ) && + csrIsSsidEqual( pMac, pSession->pConnectBssDesc, pBssDesc, pIesLocal ) + ) + { + // Check to see if the Auth type has changed in the Profile. If so, we don't want to Reassociate + // with Authenticating first. To force this, stop the current association (Disassociate) and + // then re 'Join' the AP, wihch will force an Authentication (with the new Auth type) followed by + // a new Association. + if(csrIsSameProfile(pMac, &pSession->connectedProfile, pProfile)) + { + smsLog(pMac, LOGW, FL(" detect same profile")); + if(csrRoamIsSameProfileKeys(pMac, &pSession->connectedProfile, pProfile)) + { + eRoamState = eCsrReassocToSelfNoCapChange; + } + else + { + tBssConfigParam bssConfig; + //The key changes + vos_mem_set(&bssConfig, sizeof(bssConfig), 0); + status = csrRoamPrepareBssConfig(pMac, pProfile, pBssDesc, &bssConfig, pIesLocal); + if(HAL_STATUS_SUCCESS(status)) + { + pSession->bssParams.uCfgDot11Mode = bssConfig.uCfgDot11Mode; + pSession->bssParams.cbMode = bssConfig.cbMode; + //Reapply the config including Keys so reassoc is happening. + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + pBssDesc, &bssConfig, + pIesLocal, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + eRoamState = eCsrStopRoaming; + } + } + else + { + eRoamState = eCsrStopRoaming; + } + }//same profile + } + else + { + if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociate( pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISASSOC_REQ, FALSE ))) + { + smsLog(pMac, LOGE, FL(" fail to issue disassociate with Session ID %d"), + sessionId); + eRoamState = eCsrStopRoaming; + } + } + } + else + { + // note: we used to pre-auth here with open authentication networks but that was not working so well. + // stop the existing network before attempting to join the new network... + if(!HAL_STATUS_SUCCESS(csrRoamStopNetwork(pMac, sessionId, pProfile, pBssDesc, pIesLocal))) + { + eRoamState = eCsrStopRoaming; + } + } + }//Infra + else + { + if(!HAL_STATUS_SUCCESS(csrRoamStopNetwork(pMac, sessionId, pProfile, pBssDesc, pIesLocal))) + { + eRoamState = eCsrStopRoaming; + } + } + if( pIesLocal && !pScanResult->pvIes ) + { + vos_mem_free(pIesLocal); + } + } + return( eRoamState ); +} + +eHalStatus csrRoamShouldRoam(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc, tANI_U32 roamId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pBssDesc; + status = csrRoamCallCallback(pMac, sessionId, &roamInfo, roamId, eCSR_ROAM_SHOULD_ROAM, eCSR_ROAM_RESULT_NONE); + return (status); +} +//In case no matching BSS is found, use whatever default we can find +static void csrRoamAssignDefaultParam( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + //Need to get all negotiated types in place first + //auth type + switch( pCommand->u.roamCmd.roamProfile.AuthType.authType[0] ) //Take the preferred Auth type. + { + default: + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + break; + + case eCSR_AUTH_TYPE_SHARED_KEY: + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_SHARED_KEY; + break; + + case eCSR_AUTH_TYPE_AUTOSWITCH: + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = eCSR_AUTH_TYPE_AUTOSWITCH; + break; + } + pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = + pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0]; + //In this case, the multicast encryption needs to follow the uncast ones. + pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType = + pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0]; +} + + +static void csrSetAbortRoamingCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + switch(pCommand->u.roamCmd.roamReason) + { + case eCsrLostLink1: + pCommand->u.roamCmd.roamReason = eCsrLostLink1Abort; + break; + case eCsrLostLink2: + pCommand->u.roamCmd.roamReason = eCsrLostLink2Abort; + break; + case eCsrLostLink3: + pCommand->u.roamCmd.roamReason = eCsrLostLink3Abort; + break; + default: + smsLog(pMac, LOGE, FL(" aborting roaming reason %d not recognized"), + pCommand->u.roamCmd.roamReason); + break; + } +} + +static eCsrJoinState csrRoamJoinNextBss( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fUseSameBss ) +{ + eHalStatus status; + tCsrScanResult *pScanResult = NULL; + eCsrJoinState eRoamState = eCsrStopRoaming; + tScanResultList *pBSSList = (tScanResultList *)pCommand->u.roamCmd.hBSSList; + tANI_BOOLEAN fDone = eANI_BOOLEAN_FALSE; + tCsrRoamInfo roamInfo, *pRoamInfo = NULL; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + v_U8_t acm_mask = 0; +#endif + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamProfile *pProfile = &pCommand->u.roamCmd.roamProfile; + tANI_U8 concurrentChannel = 0; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return (eCsrStopRoaming); + } + + do + { + // Check for Cardbus eject condition, before trying to Roam to any BSS + //***if( !balIsCardPresent(pAdapter) ) break; + + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + vos_mem_copy (&roamInfo.bssid, &pSession->joinFailStatusCode.bssId, sizeof(tSirMacAddr)); + if(NULL != pBSSList) + { + // When handling AP's capability change, continue to associate to + // same BSS and make sure pRoamBssEntry is not Null. + if((eANI_BOOLEAN_FALSE == fUseSameBss) || (pCommand->u.roamCmd.pRoamBssEntry == NULL)) + { + if(pCommand->u.roamCmd.pRoamBssEntry == NULL) + { + //Try the first BSS + pCommand->u.roamCmd.pLastRoamBss = NULL; + pCommand->u.roamCmd.pRoamBssEntry = csrLLPeekHead(&pBSSList->List, LL_ACCESS_LOCK); + } + else + { + pCommand->u.roamCmd.pRoamBssEntry = csrLLNext(&pBSSList->List, pCommand->u.roamCmd.pRoamBssEntry, LL_ACCESS_LOCK); + if(NULL == pCommand->u.roamCmd.pRoamBssEntry) + { + //Done with all the BSSs + //In this case, will tell HDD the completion + break; + } + else + { + //We need to indicate to HDD that we are done with this one. + //vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; //this shall not be NULL + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + pRoamInfo = &roamInfo; + } + } + while(pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + /*If concurrency enabled take the concurrent connected channel first. */ + /* Valid multichannel concurrent sessions exempted */ + if (vos_concurrent_open_sessions_running() && + !csrIsValidMcConcurrentSession(pMac, sessionId, + &pScanResult->Result.BssDescriptor)) + { + concurrentChannel = + csrGetConcurrentOperationChannel(pMac); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: " + " csr Concurrent Channel = %d", __func__, concurrentChannel); + if ((concurrentChannel) && + (concurrentChannel == + pScanResult->Result.BssDescriptor.channelId)) + { + //make this 0 because we do not want the + //below check to pass as we don't want to + //connect on other channel + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Concurrent channel match =%d"), + concurrentChannel); + concurrentChannel = 0; + } + } + + if (!concurrentChannel) + { + + if(HAL_STATUS_SUCCESS(csrRoamShouldRoam(pMac, + sessionId, &pScanResult->Result.BssDescriptor, + pCommand->u.roamCmd.roamId))) + { + //Ok to roam this + break; + } + } + else + { + eRoamState = eCsrStopRoamingDueToConcurrency; + } + pCommand->u.roamCmd.pRoamBssEntry = csrLLNext(&pBSSList->List, pCommand->u.roamCmd.pRoamBssEntry, LL_ACCESS_LOCK); + if(NULL == pCommand->u.roamCmd.pRoamBssEntry) + { + //Done with all the BSSs + fDone = eANI_BOOLEAN_TRUE; + break; + } + } + if(fDone) + { + break; + } + } + } + //We have something to roam, tell HDD when it is infra. + //For IBSS, the indication goes back to HDD via eCSR_ROAM_IBSS_IND + //For WDS, the indication is eCSR_ROAM_WDS_IND + if( CSR_IS_INFRASTRUCTURE( pProfile ) ) + { + if(pRoamInfo) + { + if(pSession->bRefAssocStartCnt) + { + pSession->bRefAssocStartCnt--; + //Complete the last association attemp because a new one is about to be tried + csrRoamCallCallback(pMac, sessionId, pRoamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_NOT_ASSOCIATED); + } + } + /* If the roaming has stopped, not to continue the roaming command*/ + if ( !CSR_IS_ROAMING(pSession) && CSR_IS_ROAMING_COMMAND(pCommand) ) + { + //No need to complete roaming here as it already completes + smsLog(pMac, LOGW, FL(" Roam command (reason %d) aborted due to roaming completed"), + pCommand->u.roamCmd.roamReason); + eRoamState = eCsrStopRoaming; + csrSetAbortRoamingCommand(pMac, pCommand); + break; + } + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + if(pScanResult) + { + tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)pScanResult->Result.pvIes; + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->Result.BssDescriptor, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" cannot parse IEs")); + fDone = eANI_BOOLEAN_TRUE; + eRoamState = eCsrStopRoaming; + break; + } + roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor; + pCommand->u.roamCmd.pLastRoamBss = roamInfo.pBssDesc; + //No need to put uapsd_mask in if the BSS doesn't support uAPSD + if( pCommand->u.roamCmd.roamProfile.uapsd_mask && + CSR_IS_QOS_BSS(pIesLocal) && + CSR_IS_UAPSD_BSS(pIesLocal) ) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(pMac, &pScanResult->Result.BssDescriptor, + pIesLocal); +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + else + { + pCommand->u.roamCmd.roamProfile.uapsd_mask = 0; + } + if( pIesLocal && !pScanResult->Result.pvIes) + { + vos_mem_free(pIesLocal); + } + } + else + { + pCommand->u.roamCmd.roamProfile.uapsd_mask = 0; + } + roamInfo.pProfile = pProfile; + pSession->bRefAssocStartCnt++; + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_START, eCSR_ROAM_RESULT_NONE ); + } + if ( NULL == pCommand->u.roamCmd.pRoamBssEntry ) + { + // If this is a start IBSS profile, then we need to start the IBSS. + if ( CSR_IS_START_IBSS(pProfile) ) + { + tANI_BOOLEAN fSameIbss = eANI_BOOLEAN_FALSE; + // Attempt to start this IBSS... + csrRoamAssignDefaultParam( pMac, pCommand ); + status = csrRoamStartIbss( pMac, sessionId, pProfile, &fSameIbss ); + if(HAL_STATUS_SUCCESS(status)) + { + if ( fSameIbss ) + { + eRoamState = eCsrStartIbssSameIbss; + } + else + { + eRoamState = eCsrContinueRoaming; + } + } + else + { + //it somehow fail need to stop + eRoamState = eCsrStopRoaming; + } + break; + } + else if ( (CSR_IS_WDS_AP(pProfile)) + || (CSR_IS_INFRA_AP(pProfile)) + ) + { + // Attempt to start this WDS... + csrRoamAssignDefaultParam( pMac, pCommand ); + /* For AP WDS, we dont have any BSSDescription */ + status = csrRoamStartWds( pMac, sessionId, pProfile, NULL ); + if(HAL_STATUS_SUCCESS(status)) + { + eRoamState = eCsrContinueRoaming; + } + else + { + //it somehow fail need to stop + eRoamState = eCsrStopRoaming; + } + } + else + { + //Nothing we can do + smsLog(pMac, LOGW, FL("cannot continue without BSS list")); + eRoamState = eCsrStopRoaming; + break; + } + } + else //We have BSS + { + //Need to assign these value because they are used in csrIsSameProfile + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + /* The OSEN IE doesn't provide the cipher suite. + * Therefore set to constant value of AES */ + if(pCommand->u.roamCmd.roamProfile.bOSENAssociation) + { + pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = + eCSR_ENCRYPT_TYPE_AES; + pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType = + eCSR_ENCRYPT_TYPE_AES; + } + else + { + pCommand->u.roamCmd.roamProfile.negotiatedUCEncryptionType = + pScanResult->ucEncryptionType; //Negotiated while building scan result. + pCommand->u.roamCmd.roamProfile.negotiatedMCEncryptionType = + pScanResult->mcEncryptionType; + } + pCommand->u.roamCmd.roamProfile.negotiatedAuthType = pScanResult->authType; + if ( CSR_IS_START_IBSS(&pCommand->u.roamCmd.roamProfile) ) + { + if(csrIsSameProfile(pMac, &pSession->connectedProfile, pProfile)) + { + eRoamState = eCsrStartIbssSameIbss; + break; + } + } + if( pCommand->u.roamCmd.fReassocToSelfNoCapChange ) + { + //trying to connect to the one already connected + pCommand->u.roamCmd.fReassocToSelfNoCapChange = eANI_BOOLEAN_FALSE; + eRoamState = eCsrReassocToSelfNoCapChange; + break; + } + // Attempt to Join this Bss... + eRoamState = csrRoamJoin( pMac, sessionId, &pScanResult->Result, pProfile ); + break; + } + + } while( 0 ); + if( (eCsrStopRoaming == eRoamState) && (CSR_IS_INFRASTRUCTURE( pProfile )) ) + { + //Need to indicate association_completion if association_start has been done + if(pSession->bRefAssocStartCnt > 0) + { + pSession->bRefAssocStartCnt--; + //Complete the last association attemp because a new one is about to be tried + pRoamInfo = &roamInfo; + csrRoamCallCallback(pMac, sessionId, pRoamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_NOT_ASSOCIATED); + } + } + + return( eRoamState ); +} + +static eHalStatus csrRoam( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrJoinState RoamState; + tANI_U32 sessionId = pCommand->sessionId; + + //***if( hddIsRadioStateOn( pAdapter ) ) + { + // Attept to join a Bss... + RoamState = csrRoamJoinNextBss( pMac, pCommand, eANI_BOOLEAN_FALSE ); + + // if nothing to join.. + if (( eCsrStopRoaming == RoamState ) || ( eCsrStopRoamingDueToConcurrency == RoamState)) + { + tANI_BOOLEAN fComplete = eANI_BOOLEAN_FALSE; + // and if connected in Infrastructure mode... + if ( csrIsConnStateInfra(pMac, sessionId) ) + { + //... then we need to issue a disassociation + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN, FALSE ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL(" failed to issue disassociate, status = %d"), status); + //roam command is completed by caller in the failed case + fComplete = eANI_BOOLEAN_TRUE; + } + } + else if( csrIsConnStateIbss(pMac, sessionId) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL(" failed to issue stop bss, status = %d"), status); + //roam command is completed by caller in the failed case + fComplete = eANI_BOOLEAN_TRUE; + } + } + else if (csrIsConnStateConnectedInfraAp(pMac, sessionId)) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL(" failed to issue stop bss, status = %d"), status); + //roam command is completed by caller in the failed case + fComplete = eANI_BOOLEAN_TRUE; + } + } + else + { + fComplete = eANI_BOOLEAN_TRUE; + } + if(fComplete) + { + // ... otherwise, we can complete the Roam command here. + if(eCsrStopRoamingDueToConcurrency == RoamState) + { + csrRoamComplete( pMac, eCsrJoinFailureDueToConcurrency, NULL ); + } + else + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + } + else if ( eCsrReassocToSelfNoCapChange == RoamState ) + { + csrRoamComplete( pMac, eCsrSilentlyStopRoamingSaveState, NULL ); + } + else if ( eCsrStartIbssSameIbss == RoamState ) + { + csrRoamComplete( pMac, eCsrSilentlyStopRoaming, NULL ); + } + }//hddIsRadioStateOn + + return status; +} +eHalStatus csrProcessFTReassocRoamCommand ( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + tANI_U32 sessionId; + tCsrRoamSession *pSession = NULL; + tCsrScanResult *pScanResult = NULL; + tSirBssDescription *pBssDesc = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) + { + //the roaming is cancelled. Simply complete the command + smsLog(pMac, LOG1, FL(" Roam command cancelled")); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + return eHAL_STATUS_FAILURE; + } + if (pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + pBssDesc = &pScanResult->Result.BssDescriptor; + } + else + { + //the roaming is cancelled. Simply complete the command + smsLog(pMac, LOG1, FL(" Roam command cancelled")); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + return eHAL_STATUS_FAILURE; + } + status = csrRoamIssueReassociate(pMac, sessionId, pBssDesc, + (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ), &pCommand->u.roamCmd.roamProfile); + return status; +} + +eHalStatus csrRoamProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL("Roam Reason : %d, sessionId: %d"), + pCommand->u.roamCmd.roamReason, sessionId); + switch ( pCommand->u.roamCmd.roamReason ) + { + case eCsrForcedDisassoc: + status = csrRoamProcessDisassocDeauth( pMac, pCommand, TRUE, FALSE ); + csrFreeRoamProfile(pMac, sessionId); + break; + case eCsrSmeIssuedDisassocForHandoff: + //Not to free pMac->roam.pCurRoamProfile (via csrFreeRoamProfile) because it is needed after disconnect +#if 0 // TODO : Confirm this change + status = csrRoamProcessDisassociate( pMac, pCommand, FALSE ); +#else + status = csrRoamProcessDisassocDeauth( pMac, pCommand, TRUE, FALSE ); +#endif + + break; + case eCsrForcedDisassocMICFailure: + status = csrRoamProcessDisassocDeauth( pMac, pCommand, TRUE, TRUE ); + csrFreeRoamProfile(pMac, sessionId); + break; + case eCsrForcedDeauth: + status = csrRoamProcessDisassocDeauth( pMac, pCommand, FALSE, FALSE ); + csrFreeRoamProfile(pMac, sessionId); + break; + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + { + tDot11fBeaconIEs *pIes = NULL; + + if( pSession->pConnectBssDesc ) + { + status = csrGetParsedBssDescriptionIEs(pMac, pSession->pConnectBssDesc, &pIes); + if(!HAL_STATUS_SUCCESS(status) ) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + } + else + { + roamInfo.reasonCode = eCsrRoamReasonStaCapabilityChanged; + csrRoamCallCallback(pMac, pSession->sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE); + pSession->roamingReason = eCsrReassocRoaming; + roamInfo.pBssDesc = pSession->pConnectBssDesc; + roamInfo.pProfile = &pCommand->u.roamCmd.roamProfile; + pSession->bRefAssocStartCnt++; + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_START, eCSR_ROAM_RESULT_NONE ); + + smsLog(pMac, LOG1, FL(" calling csrRoamIssueReassociate")); + status = csrRoamIssueReassociate( pMac, sessionId, pSession->pConnectBssDesc, pIes, + &pCommand->u.roamCmd.roamProfile ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamIssueReassociate failed with status %d"), status); + csrReleaseCommandRoam( pMac, pCommand ); + } + + vos_mem_free(pIes); + pIes = NULL; + } + } + else + status = eHAL_STATUS_FAILURE; + break; + } + case eCsrCapsChange: + smsLog(pMac, LOGE, FL("received eCsrCapsChange ")); + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ); + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE); + break; + case eCsrSmeIssuedFTReassoc: + smsLog(pMac, LOG1, FL("received FT Reassoc Req ")); + status = csrProcessFTReassocRoamCommand(pMac, pCommand); + break; + + case eCsrStopBss: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + break; + + case eCsrForcedDisassocSta: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_DISASSOC_REQ, sessionId); + status = csrSendMBDisassocReqMsg( pMac, sessionId, pCommand->u.roamCmd.peerMac, + pCommand->u.roamCmd.reason); + break; + + case eCsrForcedDeauthSta: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_DEAUTH_REQ, sessionId); + status = csrSendMBDeauthReqMsg( pMac, sessionId, pCommand->u.roamCmd.peerMac, + pCommand->u.roamCmd.reason); + break; + + case eCsrPerformPreauth: + smsLog(pMac, LOG1, FL("Attempting FT PreAuth Req")); + status = csrRoamIssueFTPreauthReq(pMac, sessionId, + pCommand->u.roamCmd.pLastRoamBss); + break; + +#ifdef WLAN_FEATURE_LFR_MBB + case ecsr_mbb_perform_preauth_reassoc: + smsLog(pMac, LOG1, FL("Attempting MBB PreAuth/Reassoc Req")); + status = csr_roam_issue_preauth_reassoc_req(pMac, sessionId, + pCommand->u.roamCmd.pLastRoamBss); + if (eHAL_STATUS_SUCCESS != status) + { + pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false; + smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"), + pMac->ft.ftSmeContext.is_preauth_lfr_mbb); + } + break; +#endif + + default: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ); + + if( pCommand->u.roamCmd.fUpdateCurRoamProfile ) + { + //Remember the roaming profile + csrFreeRoamProfile(pMac, sessionId); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL != pSession->pCurRoamProfile ) + { + vos_mem_set(pSession->pCurRoamProfile, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, &pCommand->u.roamCmd.roamProfile); + } + } + + //At this point, original uapsd_mask is saved in pCurRoamProfile + //uapsd_mask in the pCommand may change from this point on. + + // Attempt to roam with the new scan results (if we need to..) + status = csrRoam( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL("csrRoam() failed with status = 0x%08X"), status); + } + break; + } + return (status); +} + +void csrReinitPreauthCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + pCommand->u.roamCmd.pLastRoamBss = NULL; + pCommand->u.roamCmd.pRoamBssEntry = NULL; + //Because u.roamCmd is union and share with scanCmd and StatusChange + vos_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0); +} + +void csrReinitRoamCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + if(pCommand->u.roamCmd.fReleaseBssList) + { + csrScanResultPurge(pMac, pCommand->u.roamCmd.hBSSList); + pCommand->u.roamCmd.fReleaseBssList = eANI_BOOLEAN_FALSE; + pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE; + } + if(pCommand->u.roamCmd.fReleaseProfile) + { + csrReleaseProfile(pMac, &pCommand->u.roamCmd.roamProfile); + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + } + pCommand->u.roamCmd.pRoamBssEntry = NULL; + //Because u.roamCmd is union and share with scanCmd and StatusChange + vos_mem_set(&pCommand->u.roamCmd, sizeof(tRoamCmd), 0); +} + +void csrReinitWmStatusChangeCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + vos_mem_set(&pCommand->u.wmStatusChangeCmd, sizeof(tWmStatusChangeCmd), 0); +} +void csrRoamComplete( tpAniSirGlobal pMac, eCsrRoamCompleteResult Result, void *Context ) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + tANI_BOOLEAN fReleaseCommand = eANI_BOOLEAN_TRUE; + smsLog( pMac, LOG2, "Roam Completion ..." ); + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + // If the head of the queue is Active and it is a ROAM command, remove + // and put this on the Free queue. + if ( eSmeCommandRoam == pCommand->command ) + { + //we need to process the result first before removing it from active list because state changes + //still happening insides roamQProcessRoamResults so no other roam command should be issued + fReleaseCommand = csrRoamProcessResults( pMac, pCommand, Result, Context ); + if( fReleaseCommand ) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRoam( pMac, pCommand ); + } + else + { + smsLog( pMac, LOGE, " **********csrRoamComplete fail to release command reason %d", + pCommand->u.roamCmd.roamReason ); + } + } + else + { + smsLog( pMac, LOGE, " **********csrRoamComplete fail to release command reason %d", + pCommand->u.roamCmd.roamReason ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: Roam Completion called but ROAM command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: Roam Completion called but NO commands are ACTIVE ..." ); + } + if( fReleaseCommand ) + { + smeProcessPendingQueue( pMac ); + } +} + +void csrResetPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + vos_mem_set(&(pSession->PmkidCandidateInfo[0]), + sizeof(tPmkidCandidateInfo) * CSR_MAX_PMKID_ALLOWED, 0); + pSession->NumPmkidCandidate = 0; +} +#ifdef FEATURE_WLAN_WAPI +void csrResetBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + vos_mem_set(&(pSession->BkidCandidateInfo[0]), + sizeof(tBkidCandidateInfo) * CSR_MAX_BKID_ALLOWED, 0); + pSession->NumBkidCandidate = 0; +} +#endif /* FEATURE_WLAN_WAPI */ +extern tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ]; + +eHalStatus csrRoamSaveSecurityRspIE(tpAniSirGlobal pMac, + tANI_U32 sessionId, eCsrAuthType authType, + tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tDot11fBeaconIEs *pIesLocal = pIes; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if((eCSR_AUTH_TYPE_WPA == authType) || + (eCSR_AUTH_TYPE_WPA_PSK == authType) || + (eCSR_AUTH_TYPE_RSN == authType) || + (eCSR_AUTH_TYPE_RSN_PSK == authType) +#if defined WLAN_FEATURE_VOWIFI_11R + || + (eCSR_AUTH_TYPE_FT_RSN == authType) || + (eCSR_AUTH_TYPE_FT_RSN_PSK == authType) +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_WAPI + || + (eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) || + (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType) +#endif /* FEATURE_WLAN_WAPI */ +#ifdef WLAN_FEATURE_11W + || + (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) || + (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType) +#endif /* FEATURE_WLAN_WAPI */ + ) + { + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" cannot parse IEs")); + } + if( pIesLocal ) + { + tANI_U32 nIeLen; + tANI_U8 *pIeBuf; + if((eCSR_AUTH_TYPE_RSN == authType) || +#if defined WLAN_FEATURE_VOWIFI_11R + (eCSR_AUTH_TYPE_FT_RSN == authType) || + (eCSR_AUTH_TYPE_FT_RSN_PSK == authType) || +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#if defined WLAN_FEATURE_11W + (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == authType) || + (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == authType) || +#endif + (eCSR_AUTH_TYPE_RSN_PSK == authType)) + { + if(pIesLocal->RSN.present) + { + //Calculate the actual length + nIeLen = 8 //version + gp_cipher_suite + pwise_cipher_suite_count + + pIesLocal->RSN.pwise_cipher_suite_count * 4 //pwise_cipher_suites + + 2 //akm_suite_count + + pIesLocal->RSN.akm_suite_count * 4 //akm_suites + + 2; //reserved + if( pIesLocal->RSN.pmkid_count ) + { + nIeLen += 2 + pIesLocal->RSN.pmkid_count * 4; //pmkid + } + //nIeLen doesn't count EID and length fields + pSession->pWpaRsnRspIE = vos_mem_malloc(nIeLen + 2); + if (NULL == pSession->pWpaRsnRspIE) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pSession->pWpaRsnRspIE, nIeLen + 2, 0); + pSession->pWpaRsnRspIE[0] = DOT11F_EID_RSN; + pSession->pWpaRsnRspIE[1] = (tANI_U8)nIeLen; + //copy upto akm_suites + pIeBuf = pSession->pWpaRsnRspIE + 2; + vos_mem_copy(pIeBuf, &pIesLocal->RSN.version, + sizeof(pIesLocal->RSN.version)); + pIeBuf += sizeof(pIesLocal->RSN.version); + vos_mem_copy(pIeBuf, &pIesLocal->RSN.gp_cipher_suite, + sizeof(pIesLocal->RSN.gp_cipher_suite)); + pIeBuf += sizeof(pIesLocal->RSN.gp_cipher_suite); + vos_mem_copy(pIeBuf, &pIesLocal->RSN.pwise_cipher_suite_count, + sizeof(pIesLocal->RSN.pwise_cipher_suite_count)); + pIeBuf += sizeof(pIesLocal->RSN.pwise_cipher_suite_count ); + if( pIesLocal->RSN.pwise_cipher_suite_count ) + { + //copy pwise_cipher_suites + vos_mem_copy(pIeBuf, + pIesLocal->RSN.pwise_cipher_suites, + pIesLocal->RSN.pwise_cipher_suite_count * 4); + pIeBuf += pIesLocal->RSN.pwise_cipher_suite_count * 4; + } + vos_mem_copy(pIeBuf, &pIesLocal->RSN.akm_suite_count, 2); + pIeBuf += 2; + if( pIesLocal->RSN.akm_suite_count ) + { + //copy akm_suites + vos_mem_copy(pIeBuf, + pIesLocal->RSN.akm_suites, + pIesLocal->RSN.akm_suite_count * 4); + pIeBuf += pIesLocal->RSN.akm_suite_count * 4; + } + //copy the rest + vos_mem_copy(pIeBuf, + pIesLocal->RSN.akm_suites + pIesLocal->RSN.akm_suite_count * 4, + 2 + pIesLocal->RSN.pmkid_count * 4); + pSession->nWpaRsnRspIeLength = nIeLen + 2; + } + } + } + else if((eCSR_AUTH_TYPE_WPA == authType) || + (eCSR_AUTH_TYPE_WPA_PSK == authType)) + { + if(pIesLocal->WPA.present) + { + //Calculate the actual length + nIeLen = 12 //OUI + version + multicast_cipher + unicast_cipher_count + + pIesLocal->WPA.unicast_cipher_count * 4 //unicast_ciphers + + 2 //auth_suite_count + + pIesLocal->WPA.auth_suite_count * 4; //auth_suites + // The WPA capabilities follows the Auth Suite (two octects)-- + // this field is optional, and we always "send" zero, so just + // remove it. This is consistent with our assumptions in the + // frames compiler; c.f. bug 15234: + //nIeLen doesn't count EID and length fields + + pSession->pWpaRsnRspIE = vos_mem_malloc(nIeLen + 2); + if ( NULL == pSession->pWpaRsnRspIE ) + status = eHAL_STATUS_FAILURE; + else + { + pSession->pWpaRsnRspIE[0] = DOT11F_EID_WPA; + pSession->pWpaRsnRspIE[1] = (tANI_U8)nIeLen; + pIeBuf = pSession->pWpaRsnRspIE + 2; + //Copy WPA OUI + vos_mem_copy(pIeBuf, &csrWpaOui[1], 4); + pIeBuf += 4; + vos_mem_copy(pIeBuf, &pIesLocal->WPA.version, + 8 + pIesLocal->WPA.unicast_cipher_count * 4); + pIeBuf += 8 + pIesLocal->WPA.unicast_cipher_count * 4; + vos_mem_copy(pIeBuf, &pIesLocal->WPA.auth_suite_count, + 2 + pIesLocal->WPA.auth_suite_count * 4); + pIeBuf += pIesLocal->WPA.auth_suite_count * 4; + pSession->nWpaRsnRspIeLength = nIeLen + 2; + } + } + } +#ifdef FEATURE_WLAN_WAPI + else if((eCSR_AUTH_TYPE_WAPI_WAI_PSK == authType) || + (eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == authType)) + { + if(pIesLocal->WAPI.present) + { + //Calculate the actual length + nIeLen = 4 //version + akm_suite_count + + pIesLocal->WAPI.akm_suite_count * 4 // akm_suites + + 2 //pwise_cipher_suite_count + + pIesLocal->WAPI.unicast_cipher_suite_count * 4 //pwise_cipher_suites + + 6; //gp_cipher_suite + preauth + reserved + if( pIesLocal->WAPI.bkid_count ) + { + nIeLen += 2 + pIesLocal->WAPI.bkid_count * 4; //bkid + } + + //nIeLen doesn't count EID and length fields + pSession->pWapiRspIE = vos_mem_malloc(nIeLen + 2); + if ( NULL == pSession->pWapiRspIE ) + status = eHAL_STATUS_FAILURE; + else + { + pSession->pWapiRspIE[0] = DOT11F_EID_WAPI; + pSession->pWapiRspIE[1] = (tANI_U8)nIeLen; + pIeBuf = pSession->pWapiRspIE + 2; + //copy upto akm_suite_count + vos_mem_copy(pIeBuf, &pIesLocal->WAPI.version, 2); + pIeBuf += 4; + if( pIesLocal->WAPI.akm_suite_count ) + { + //copy akm_suites + vos_mem_copy(pIeBuf, pIesLocal->WAPI.akm_suites, + pIesLocal->WAPI.akm_suite_count * 4); + pIeBuf += pIesLocal->WAPI.akm_suite_count * 4; + } + vos_mem_copy(pIeBuf, + &pIesLocal->WAPI.unicast_cipher_suite_count, + 2); + pIeBuf += 2; + if( pIesLocal->WAPI.unicast_cipher_suite_count ) + { + //copy pwise_cipher_suites + vos_mem_copy( pIeBuf, + pIesLocal->WAPI.unicast_cipher_suites, + pIesLocal->WAPI.unicast_cipher_suite_count * 4); + pIeBuf += pIesLocal->WAPI.unicast_cipher_suite_count * 4; + } + //gp_cipher_suite + vos_mem_copy(pIeBuf, + pIesLocal->WAPI.multicast_cipher_suite, + 4); + pIeBuf += 4; + //preauth + reserved + vos_mem_copy(pIeBuf, + pIesLocal->WAPI.multicast_cipher_suite + 4, + 2); + pIeBuf += 2; + if ( pIesLocal->WAPI.bkid_count ) + { + //bkid_count + vos_mem_copy(pIeBuf, &pIesLocal->WAPI.bkid_count, 2); + pIeBuf += 2; + //copy akm_suites + vos_mem_copy(pIeBuf, pIesLocal->WAPI.bkid, + pIesLocal->WAPI.bkid_count * 4); + pIeBuf += pIesLocal->WAPI.bkid_count * 4; + } + pSession->nWapiRspIeLength = nIeLen + 2; + } + } + } +#endif /* FEATURE_WLAN_WAPI */ + if( !pIes ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + } + } + return (status); +} + +static void csrCheckAndUpdateACWeight( tpAniSirGlobal pMac, tDot11fBeaconIEs *pIEs ) +{ + v_U8_t bACWeights[WLANTL_MAX_AC]; + v_U8_t paramBk, paramBe, paramVi, paramVo; + v_BOOL_t fWeightChange = VOS_FALSE; + //Compare two ACs' EDCA parameters, from low to high (BK, BE, VI, VO) + //The "formula" is, if lower AC's AIFSN+CWMin is bigger than a fixed amount + //of the higher AC one, make the higher AC has the same weight as the lower AC. + //This doesn't address the case where the lower AC needs a real higher weight + if( pIEs->WMMParams.present ) + { + //no change to the lowest ones + bACWeights[WLANTL_AC_BK] = pMac->roam.ucACWeights[WLANTL_AC_BK]; + bACWeights[WLANTL_AC_BE] = pMac->roam.ucACWeights[WLANTL_AC_BE]; + bACWeights[WLANTL_AC_VI] = pMac->roam.ucACWeights[WLANTL_AC_VI]; + bACWeights[WLANTL_AC_VO] = pMac->roam.ucACWeights[WLANTL_AC_VO]; + paramBk = pIEs->WMMParams.acbk_aifsn + pIEs->WMMParams.acbk_acwmin; + paramBe = pIEs->WMMParams.acbe_aifsn + pIEs->WMMParams.acbe_acwmin; + paramVi = pIEs->WMMParams.acvi_aifsn + pIEs->WMMParams.acvi_acwmin; + paramVo = pIEs->WMMParams.acvo_aifsn + pIEs->WMMParams.acvo_acwmin; + if( SME_DETECT_AC_WEIGHT_DIFF(paramBk, paramBe) ) + { + bACWeights[WLANTL_AC_BE] = bACWeights[WLANTL_AC_BK]; + fWeightChange = VOS_TRUE; + } + if( SME_DETECT_AC_WEIGHT_DIFF(paramBk, paramVi) ) + { + bACWeights[WLANTL_AC_VI] = bACWeights[WLANTL_AC_BK]; + fWeightChange = VOS_TRUE; + } + else if( SME_DETECT_AC_WEIGHT_DIFF(paramBe, paramVi) ) + { + bACWeights[WLANTL_AC_VI] = bACWeights[WLANTL_AC_BE]; + fWeightChange = VOS_TRUE; + } + if( SME_DETECT_AC_WEIGHT_DIFF(paramBk, paramVo) ) + { + bACWeights[WLANTL_AC_VO] = bACWeights[WLANTL_AC_BK]; + fWeightChange = VOS_TRUE; + } + else if( SME_DETECT_AC_WEIGHT_DIFF(paramBe, paramVo) ) + { + bACWeights[WLANTL_AC_VO] = bACWeights[WLANTL_AC_BE]; + fWeightChange = VOS_TRUE; + } + else if( SME_DETECT_AC_WEIGHT_DIFF(paramVi, paramVo) ) + { + bACWeights[WLANTL_AC_VO] = bACWeights[WLANTL_AC_VI]; + fWeightChange = VOS_TRUE; + } + if(fWeightChange) + { + smsLog(pMac, LOGE, FL(" change AC weights (%d-%d-%d-%d)"), bACWeights[0], bACWeights[1], + bACWeights[2], bACWeights[3]); + WLANTL_SetACWeights(pMac->roam.gVosContext, bACWeights); + } + } +} +#ifdef WLAN_FEATURE_VOWIFI_11R +//Returns whether the current association is a 11r assoc or not +tANI_BOOLEAN csrRoamIs11rAssoc(tpAniSirGlobal pMac) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + return csrNeighborRoamIs11rAssoc(pMac); +#else + return eANI_BOOLEAN_FALSE; +#endif +} +#endif +#ifdef FEATURE_WLAN_ESE +//Returns whether the current association is a ESE assoc or not +tANI_BOOLEAN csrRoamIsESEAssoc(tpAniSirGlobal pMac) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + return csrNeighborRoamIsESEAssoc(pMac); +#else + return eANI_BOOLEAN_FALSE; +#endif +} +#endif +#ifdef FEATURE_WLAN_LFR +//Returns whether "Legacy Fast Roaming" is currently enabled...or not +tANI_BOOLEAN csrRoamIsFastRoamEnabled(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = NULL; + + if (CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL != pSession->pCurRoamProfile) + { + if (pSession->pCurRoamProfile->csrPersona != VOS_STA_MODE) + { + return eANI_BOOLEAN_FALSE; + } + } + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (eANI_BOOLEAN_TRUE == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) + { + return (pMac->roam.configParam.isFastRoamIniFeatureEnabled); + } + else +#endif + { + return (pMac->roam.configParam.isFastRoamIniFeatureEnabled && + (!csrIsConcurrentSessionRunning(pMac))); + } +} + +#ifdef FEATURE_WLAN_ESE +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIsESEAssoc + + \brief This function returns whether the current association is a ESE assoc or not + + \param pMac - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if current assoc is ESE, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIsESEAssoc(tpAniSirGlobal pMac) +{ + return pMac->roam.neighborRoamInfo.isESEAssoc; +} +#endif /* FEATURE_WLAN_ESE */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +//Returns whether "FW based BG scan" is currently enabled...or not +tANI_BOOLEAN csrRoamIsRoamOffloadScanEnabled(tpAniSirGlobal pMac) +{ + return (pMac->roam.configParam.isRoamOffloadScanEnabled); +} +#endif +#endif + +#if defined(FEATURE_WLAN_ESE) +tANI_BOOLEAN csrRoamIsEseIniFeatureEnabled(tpAniSirGlobal pMac) +{ + return pMac->roam.configParam.isEseIniFeatureEnabled; +} +#endif /*FEATURE_WLAN_ESE*/ + +//Return true means the command can be release, else not +static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, + eCsrRoamCompleteResult Result, void *Context ) +{ + tANI_BOOLEAN fReleaseCommand = eANI_BOOLEAN_TRUE; + tSirBssDescription *pSirBssDesc = NULL; + tSirMacAddr BroadcastMac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + tCsrScanResult *pScanResult = NULL; + tCsrRoamInfo roamInfo; + sme_QosAssocInfo assocInfo; + sme_QosCsrEventIndType ind_qos;//indication for QoS module in SME + tANI_U8 acm_mask = 0; //HDD needs the ACM mask in the assoc rsp callback + tDot11fBeaconIEs *pIes = NULL; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamProfile *pProfile = &pCommand->u.roamCmd.roamProfile; + eRoamCmdStatus roamStatus; + eCsrRoamResult roamResult; + eHalStatus status; + tANI_U32 key_timeout_interval = 0; + tSirSmeStartBssRsp *pSmeStartBssRsp = NULL; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eANI_BOOLEAN_FALSE; + } + + smsLog( pMac, LOG1, FL("Processing ROAM results...")); + switch( Result ) + { + case eCsrJoinSuccess: + // reset the IDLE timer + // !! + // !! fall through to the next CASE statement here is intentional !! + // !! + case eCsrReassocSuccess: + if(eCsrReassocSuccess == Result) + { + roamInfo.reassoc = true; + ind_qos = SME_QOS_CSR_REASSOC_COMPLETE; + } + else + { + roamInfo.reassoc = false; + ind_qos = SME_QOS_CSR_ASSOC_COMPLETE; + } + // Success Join Response from LIM. Tell NDIS we are connected and save the + // Connected state... + smsLog(pMac, LOGW, FL("receives association indication")); + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + //always free the memory here + if(pSession->pWpaRsnRspIE) + { + pSession->nWpaRsnRspIeLength = 0; + vos_mem_free(pSession->pWpaRsnRspIE); + pSession->pWpaRsnRspIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + if(pSession->pWapiRspIE) + { + pSession->nWapiRspIeLength = 0; + vos_mem_free(pSession->pWapiRspIE); + pSession->pWapiRspIE = NULL; + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //Reset counter so no join retry is needed. + pSession->maxRetryCount = 0; + csrRoamStopJoinRetryTimer(pMac, sessionId); +#endif + /* This creates problem since we have not saved the connected profile. + So moving this after saving the profile + */ + //csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED ); + + /* Reset full_power_till_set_key as it might have been set + * by last failed secured connection. + * It should be set only for secured connection. + */ + pMac->pmc.full_power_till_set_key = false; + if( CSR_IS_INFRASTRUCTURE( pProfile ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED; + } + else + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED; + } + //Use the last connected bssdesc for reassoc-ing to the same AP. + //NOTE: What to do when reassoc to a different AP??? + if( (eCsrHddIssuedReassocToSameAP == pCommand->u.roamCmd.roamReason) || + (eCsrSmeIssuedReassocToSameAP == pCommand->u.roamCmd.roamReason) ) + { + pSirBssDesc = pSession->pConnectBssDesc; + if(pSirBssDesc) + { + vos_mem_copy(&roamInfo.bssid, &pSirBssDesc->bssId, + sizeof(tCsrBssid)); + } + } + else + { + + if(pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + if(pScanResult != NULL) + { + pSirBssDesc = &pScanResult->Result.BssDescriptor; + //this can be NULL + pIes = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + vos_mem_copy(&roamInfo.bssid, &pSirBssDesc->bssId, + sizeof(tCsrBssid)); + } + } + } + if( pSirBssDesc ) + { + roamInfo.staId = HAL_STA_INVALID_IDX; + csrRoamSaveConnectedInfomation(pMac, sessionId, pProfile, pSirBssDesc, pIes); + //Save WPA/RSN IE + csrRoamSaveSecurityRspIE(pMac, sessionId, pProfile->negotiatedAuthType, pSirBssDesc, pIes); +#ifdef FEATURE_WLAN_ESE + roamInfo.isESEAssoc = pSession->connectedProfile.isESEAssoc; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSirBssDesc->mdiePresent) + { + if(csrIsAuthType11r(pProfile->negotiatedAuthType, VOS_TRUE) +#ifdef FEATURE_WLAN_ESE + && !((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) && + (pIes->ESEVersion.present) && (pMac->roam.configParam.isEseIniFeatureEnabled)) +#endif + ) + { + // is11Rconnection; + roamInfo.is11rAssoc = VOS_TRUE; + } + else + { + // is11Rconnection; + roamInfo.is11rAssoc = VOS_FALSE; + } + } +#endif + // csrRoamStateChange also affects sub-state. Hence, csrRoamStateChange happens first and then + // substate change. + // Moving even save profile above so that below mentioned conditon is also met. + // JEZ100225: Moved to after saving the profile. Fix needed in main/latest + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ); + // Make sure the Set Context is issued before link indication to NDIS. After link indication is + // made to NDIS, frames could start flowing. If we have not set context with LIM, the frames + // will be dropped for the security context may not be set properly. + // + // this was causing issues in the 2c_wlan_wep WHQL test when the SetContext was issued after the link + // indication. (Link Indication happens in the profFSMSetConnectedInfra call). + // + // this reordering was done on titan_prod_usb branch and is being replicated here. + // + + if( CSR_IS_ENC_TYPE_STATIC( pProfile->negotiatedUCEncryptionType ) && + !pProfile->bWPSAssociation) + { + // Issue the set Context request to LIM to establish the Unicast STA context + if( !HAL_STATUS_SUCCESS( csrRoamIssueSetContextReq( pMac, sessionId, + pProfile->negotiatedUCEncryptionType, + pSirBssDesc, &(pSirBssDesc->bssId), + FALSE, TRUE, eSIR_TX_RX, 0, 0, NULL, 0 ) ) ) // NO keys... these key parameters don't matter. + { + smsLog( pMac, LOGE, FL(" Set context for unicast fail") ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + } + // Issue the set Context request to LIM to establish the Broadcast STA context + csrRoamIssueSetContextReq( pMac, sessionId, pProfile->negotiatedMCEncryptionType, + pSirBssDesc, &BroadcastMac, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + else if (!pSession->abortConnection) + { + //Need to wait for supplicant authtication + roamInfo.fAuthRequired = eANI_BOOLEAN_TRUE; + //Set the subestate to WaitForKey in case authentiation is needed + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, sessionId ); + + if(pProfile->bWPSAssociation) + { + key_timeout_interval = CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD; + } + else + { + key_timeout_interval = CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD; + } + + //Save sessionId in case of timeout + pMac->roam.WaitForKeyTimerInfo.sessionId = (tANI_U8)sessionId; + //This time should be long enough for the rest of the process plus setting key + if(!HAL_STATUS_SUCCESS( csrRoamStartWaitForKeyTimer( pMac, key_timeout_interval ) ) ) + { + //Reset our state so nothting is blocked. + smsLog( pMac, LOGE, FL(" Failed to start pre-auth timer") ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + } + + assocInfo.pBssDesc = pSirBssDesc; //could be NULL + assocInfo.pProfile = pProfile; + if(Context) + { + tSirSmeJoinRsp *pJoinRsp = (tSirSmeJoinRsp *)Context; + tANI_U32 len; + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + len = pJoinRsp->assocReqLength + pJoinRsp->assocRspLength + pJoinRsp->beaconLength; +#ifdef WLAN_FEATURE_VOWIFI_11R + len += pJoinRsp->parsedRicRspLen; +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef FEATURE_WLAN_ESE + len += pJoinRsp->tspecIeLen; +#endif + if(len) + { + pSession->connectedInfo.pbFrames = vos_mem_malloc(len); + if ( pSession->connectedInfo.pbFrames != NULL ) + { + vos_mem_copy(pSession->connectedInfo.pbFrames, + pJoinRsp->frames, len); + pSession->connectedInfo.nAssocReqLength = pJoinRsp->assocReqLength; + pSession->connectedInfo.nAssocRspLength = pJoinRsp->assocRspLength; + pSession->connectedInfo.nBeaconLength = pJoinRsp->beaconLength; +#ifdef WLAN_FEATURE_VOWIFI_11R + pSession->connectedInfo.nRICRspLength = pJoinRsp->parsedRicRspLen; +#endif /* WLAN_FEATURE_VOWIFI_11R */ +#ifdef FEATURE_WLAN_ESE + pSession->connectedInfo.nTspecIeLength = pJoinRsp->tspecIeLen; +#endif + roamInfo.nAssocReqLength = pJoinRsp->assocReqLength; + roamInfo.nAssocRspLength = pJoinRsp->assocRspLength; + roamInfo.nBeaconLength = pJoinRsp->beaconLength; + roamInfo.pbFrames = pSession->connectedInfo.pbFrames; + } + } + if(pCommand->u.roamCmd.fReassoc) + { + roamInfo.fReassocReq = roamInfo.fReassocRsp = eANI_BOOLEAN_TRUE; + } + pSession->connectedInfo.staId = ( tANI_U8 )pJoinRsp->staId; + roamInfo.staId = ( tANI_U8 )pJoinRsp->staId; + roamInfo.ucastSig = ( tANI_U8 )pJoinRsp->ucastSig; + roamInfo.bcastSig = ( tANI_U8 )pJoinRsp->bcastSig; + roamInfo.maxRateFlags = pJoinRsp->maxRateFlags; + roamInfo.vht_caps = pJoinRsp->vht_caps; + roamInfo.ht_caps = pJoinRsp->ht_caps; + roamInfo.hs20vendor_ie = pJoinRsp->hs20vendor_ie; + roamInfo.ht_operation = pJoinRsp->ht_operation; + roamInfo.vht_operation = pJoinRsp->vht_operation; + + } + else + { + if(pCommand->u.roamCmd.fReassoc) + { + roamInfo.fReassocReq = roamInfo.fReassocRsp = eANI_BOOLEAN_TRUE; + roamInfo.nAssocReqLength = pSession->connectedInfo.nAssocReqLength; + roamInfo.nAssocRspLength = pSession->connectedInfo.nAssocRspLength; + roamInfo.nBeaconLength = pSession->connectedInfo.nBeaconLength; + roamInfo.pbFrames = pSession->connectedInfo.pbFrames; + } + } + /* Update the staId from the previous connected profile info + as the reassociation is triggred at SME/HDD */ + if( (eCsrHddIssuedReassocToSameAP == pCommand->u.roamCmd.roamReason) || + (eCsrSmeIssuedReassocToSameAP == pCommand->u.roamCmd.roamReason) ) + { + roamInfo.staId = pSession->connectedInfo.staId; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + // Indicate SME-QOS with reassoc success event, only after + // copying the frames + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, ind_qos, &assocInfo); +#endif + roamInfo.pBssDesc = pSirBssDesc; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(pMac, pSirBssDesc, NULL); +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + pSession->connectedProfile.acm_mask = acm_mask; + //start UAPSD if uapsd_mask is not 0 because HDD will configure for trigger frame + //It may be better to let QoS do this???? + if( pSession->connectedProfile.modifyProfileFields.uapsd_mask ) + { + smsLog(pMac, LOGE, " uapsd_mask (0x%X) set, request UAPSD now", + pSession->connectedProfile.modifyProfileFields.uapsd_mask); + pmcStartUapsd( pMac, NULL, NULL ); + } + pSession->connectedProfile.dot11Mode = pSession->bssParams.uCfgDot11Mode; + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + if( pSession->bRefAssocStartCnt > 0 ) + { + pSession->bRefAssocStartCnt--; + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && ( csrIsConcurrentSessionRunning( pMac ))) + { + pMac->roam.configParam.doBMPSWorkaround = 1; + } + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED); + } + + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_NONE, eANI_BOOLEAN_TRUE); + // reset the PMKID candidate list + csrResetPMKIDCandidateList( pMac, sessionId ); + //Update TL's AC weight base on the current EDCA parameters + //These parameters may change in the course of the connection, that sictuation + //is not taken care here. This change is mainly to address a WIFI WMM test where + //BE has a equal or higher TX priority than VI. + //We only do this for infra link + if( csrIsConnStateConnectedInfra(pMac, sessionId ) && pIes ) + { + csrCheckAndUpdateACWeight(pMac, pIes); + } +#ifdef FEATURE_WLAN_WAPI + // reset the BKID candidate list + csrResetBKIDCandidateList( pMac, sessionId ); +#endif /* FEATURE_WLAN_WAPI */ + } + else + { + smsLog(pMac, LOGW, " Roam command doesn't have a BSS desc"); + } + csrScanCancelIdleScan(pMac); + //Not to signal link up because keys are yet to be set. + //The linkup function will overwrite the sub-state that we need to keep at this point. + if( !CSR_IS_WAIT_FOR_KEY(pMac, sessionId) ) + { + csrRoamLinkUp(pMac, pSession->connectedProfile.bssid); + } + //Check if BMPS is required and start the BMPS retry timer. Timer period is large + //enough to let security and DHCP handshake succeed before entry into BMPS + if (pmcShouldBmpsTimerRun(pMac)) + { + /* Set full_power_till_set_key to make sure we wait for + * until keys are set before going into BMPS. + */ + if(eANI_BOOLEAN_TRUE == roamInfo.fAuthRequired) + { + pMac->pmc.full_power_till_set_key = true; + smsLog(pMac, LOG1, + FL("Set full_power_till_set_key to make sure we wait until keys are set before going to BMPS")); + } + + if (pmcStartTrafficTimer(pMac, BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP) + != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGP, FL("Cannot start BMPS Retry timer")); + } + smsLog(pMac, LOG2, FL("BMPS Retry Timer already running or started")); + } + break; + + case eCsrStartBssSuccess: + // on the StartBss Response, LIM is returning the Bss Description that we + // are beaconing. Add this Bss Description to our scan results and + // chain the Profile to this Bss Description. On a Start BSS, there was no + // detected Bss description (no partner) so we issued the Start Bss to + // start the Ibss without any Bss description. Lim was kind enough to return + // the Bss Description that we start beaconing for the newly started Ibss. + smsLog(pMac, LOG2, FL("receives start BSS ok indication")); + status = eHAL_STATUS_FAILURE; + pSmeStartBssRsp = (tSirSmeStartBssRsp *)Context; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + if( CSR_IS_IBSS( pProfile ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED; + } + else if (CSR_IS_INFRA_AP(pProfile)) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED; + } + else + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED; + } + if( !CSR_IS_WDS_STA( pProfile ) ) + { + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ); + pSirBssDesc = &pSmeStartBssRsp->bssDescription; + if( !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs( pMac, pSirBssDesc, &pIes )) ) + { + smsLog(pMac, LOGW, FL("cannot parse IBSS IEs")); + roamInfo.pBssDesc = pSirBssDesc; + //We need to associate_complete it first, becasue Associate_start already indicated. + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_IBSS_START_FAILED ); + break; + } + if (!CSR_IS_INFRA_AP(pProfile)) + { + pScanResult = csrScanAppendBssDescription( pMac, pSirBssDesc, pIes, FALSE ); + } + csrRoamSaveConnectedBssDesc(pMac, sessionId, pSirBssDesc); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + if(pSirBssDesc) + { + csrRoamSaveConnectedInfomation(pMac, sessionId, pProfile, pSirBssDesc, pIes); + vos_mem_copy(&roamInfo.bssid, &pSirBssDesc->bssId, + sizeof(tCsrBssid)); + } + //We are doen with the IEs so free it + vos_mem_free(pIes); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + tANI_U32 bi; + + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + if(CSR_INVALID_SCANRESULT_HANDLE == pCommand->u.roamCmd.hBSSList) + { + //We start the IBSS (didn't find any matched IBSS out there) + pIbssLog->eventId = WLAN_IBSS_EVENT_START_IBSS_RSP; + } + else + { + pIbssLog->eventId = WLAN_IBSS_EVENT_JOIN_IBSS_RSP; + } + if(pSirBssDesc) + { + vos_mem_copy(pIbssLog->bssid, pSirBssDesc->bssId, 6); + pIbssLog->operatingChannel = pSirBssDesc->channelId; + } + if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &bi))) + { + //***U8 is not enough for beacon interval + pIbssLog->beaconInterval = (v_U8_t)bi; + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + //Only set context for non-WDS_STA. We don't even need it for WDS_AP. But since the encryption + //is WPA2-PSK so it won't matter. + if( CSR_IS_ENC_TYPE_STATIC( pProfile->negotiatedUCEncryptionType ) && !CSR_IS_INFRA_AP( pSession->pCurRoamProfile )) + { + // Issue the set Context request to LIM to establish the Broadcast STA context for the Ibss. + csrRoamIssueSetContextReq( pMac, sessionId, + pProfile->negotiatedMCEncryptionType, + pSirBssDesc, &BroadcastMac, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + } + else + { + //Keep the state to eCSR_ROAMING_STATE_JOINING + //Need to send join_req. + if(pCommand->u.roamCmd.pRoamBssEntry) + { + if((pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link))) + { + pSirBssDesc = &pScanResult->Result.BssDescriptor; + pIes = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + // Set the roaming substate to 'join attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId); + status = csrSendJoinReqMsg( pMac, sessionId, pSirBssDesc, pProfile, pIes, eWNI_SME_JOIN_REQ ); + } + } + else + { + smsLog( pMac, LOGE, " StartBSS for WDS station with no BssDesc" ); + VOS_ASSERT( 0 ); + } + } + //Only tell upper layer is we start the BSS because Vista doesn't like multiple connection + //indications. If we don't start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS will + //trigger the connection start indication in Vista + if( !CSR_IS_JOIN_TO_IBSS( pProfile ) ) + { + roamStatus = eCSR_ROAM_IBSS_IND; + roamResult = eCSR_ROAM_RESULT_IBSS_STARTED; + if( CSR_IS_WDS( pProfile ) ) + { + roamStatus = eCSR_ROAM_WDS_IND; + roamResult = eCSR_ROAM_RESULT_WDS_STARTED; + } + if( CSR_IS_INFRA_AP( pProfile ) ) + { + roamStatus = eCSR_ROAM_INFRA_IND; + roamResult = eCSR_ROAM_RESULT_INFRA_STARTED; + } + + //Only tell upper layer is we start the BSS because Vista doesn't like multiple connection + //indications. If we don't start the BSS ourself, handler of eSIR_SME_JOINED_NEW_BSS will + //trigger the connection start indication in Vista + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + //We start the IBSS (didn't find any matched IBSS out there) + roamInfo.pBssDesc = pSirBssDesc; + roamInfo.staId = (tANI_U8)pSmeStartBssRsp->staId; + vos_mem_copy(roamInfo.bssid, pSirBssDesc->bssId, + sizeof(tCsrBssid)); + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && + ( csrIsConcurrentSessionRunning( pMac ))) + { + pMac->roam.configParam.doBMPSWorkaround = 1; + } + + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, roamStatus, roamResult ); + } + + csrScanCancelIdleScan(pMac); + + if( CSR_IS_WDS_STA( pProfile ) ) + { + //need to send stop BSS because we fail to send join_req + csrRoamIssueDisassociateCmd( pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED ); + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_STOPPED ); + } + break; + case eCsrStartBssFailure: +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->status = WLAN_IBSS_STATUS_FAILURE; + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + roamStatus = eCSR_ROAM_IBSS_IND; + roamResult = eCSR_ROAM_RESULT_IBSS_STARTED; + if( CSR_IS_WDS( pProfile ) ) + { + roamStatus = eCSR_ROAM_WDS_IND; + roamResult = eCSR_ROAM_RESULT_WDS_STARTED; + } + if( CSR_IS_INFRA_AP( pProfile ) ) + { + roamStatus = eCSR_ROAM_INFRA_IND; + roamResult = eCSR_ROAM_RESULT_INFRA_START_FAILED; + } + if(Context) + { + pSirBssDesc = (tSirBssDescription *)Context; + } + else + { + pSirBssDesc = NULL; + } + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pSirBssDesc; + //We need to associate_complete it first, becasue Associate_start already indicated. + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, roamStatus, roamResult ); + csrSetDefaultDot11Mode( pMac ); + break; + case eCsrSilentlyStopRoaming: + // We are here because we try to start the same IBSS + //No message to PE + // return the roaming state to Joined. + smsLog(pMac, LOGW, FL("receives silently roaming indication")); + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pSession->pConnectBssDesc; + if( roamInfo.pBssDesc ) + { + vos_mem_copy(&roamInfo.bssid, &roamInfo.pBssDesc->bssId, + sizeof(tCsrBssid)); + } + //Since there is no change in the current state, simply pass back no result otherwise + //HDD may be mistakenly mark to disconnected state. + csrRoamCallCallback( pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_NONE ); + break; + case eCsrSilentlyStopRoamingSaveState: + //We are here because we try to connect to the same AP + //No message to PE + smsLog(pMac, LOGW, FL("receives silently stop roaming indication")); + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + + //to aviod resetting the substate to NONE + pMac->roam.curState[sessionId] = eCSR_ROAMING_STATE_JOINED; + //No need to change substate to wai_for_key because there is no state change + roamInfo.pBssDesc = pSession->pConnectBssDesc; + if( roamInfo.pBssDesc ) + { + vos_mem_copy(&roamInfo.bssid, &roamInfo.pBssDesc->bssId, + sizeof(tCsrBssid)); + } + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + roamInfo.nBeaconLength = pSession->connectedInfo.nBeaconLength; + roamInfo.nAssocReqLength = pSession->connectedInfo.nAssocReqLength; + roamInfo.nAssocRspLength = pSession->connectedInfo.nAssocRspLength; + roamInfo.pbFrames = pSession->connectedInfo.pbFrames; + roamInfo.staId = pSession->connectedInfo.staId; + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + VOS_ASSERT( roamInfo.staId != 0 ); + pSession->bRefAssocStartCnt--; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED); + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_ASSOCIATED, eANI_BOOLEAN_TRUE); + break; + case eCsrReassocFailure: +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_REASSOC_FAILURE, NULL); +#endif + case eCsrJoinWdsFailure: + smsLog(pMac, LOGW, FL("failed to join WDS")); + csrFreeConnectBssDesc(pMac, sessionId); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_WDS_IND, + eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED); + //Need to issue stop_bss + break; + case eCsrJoinFailure: + case eCsrNothingToJoin: + case eCsrJoinFailureDueToConcurrency: + default: + { + smsLog(pMac, LOGW, FL("receives no association indication")); + smsLog(pMac, LOG1, FL("Assoc ref count %d"), + pSession->bRefAssocStartCnt); + if( CSR_IS_INFRASTRUCTURE( &pSession->connectedProfile ) || + CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ( pMac, sessionId ) ) + { + //do not free for the other profiles as we need to send down stop BSS later + csrFreeConnectBssDesc(pMac, sessionId); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + csrSetDefaultDot11Mode( pMac ); + } + + switch( pCommand->u.roamCmd.roamReason ) + { + // If this transition is because of an 802.11 OID, then we transition + // back to INIT state so we sit waiting for more OIDs to be issued and + // we don't start the IDLE timer. + case eCsrSmeIssuedFTReassoc: + case eCsrSmeIssuedAssocToSimilarAP: + case eCsrHddIssued: + case eCsrSmeIssuedDisassocForHandoff: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + vos_mem_copy(&roamInfo.bssid, + &pSession->joinFailStatusCode.bssId, + sizeof(tCsrBssid)); + + /* Defeaturize this later if needed */ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + /* If Join fails while Handoff is in progress, indicate disassociated event to supplicant to reconnect */ + if (csrRoamIsHandoffInProgress(pMac)) + { + /* Should indicate neighbor roam algorithm about the connect failure here */ + csrNeighborRoamIndicateConnect(pMac, (tANI_U8)sessionId, VOS_STATUS_E_FAILURE); + } +#endif + if(pSession->bRefAssocStartCnt > 0) + { + pSession->bRefAssocStartCnt--; + if(eCsrJoinFailureDueToConcurrency == Result) + { + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL); + } + else + { + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_FAILURE); + } + } + else + { + /* bRefAssocStartCnt is not incremented when + * eRoamState == eCsrStopRoamingDueToConcurrency + * in csrRoamJoinNextBss API. so handle this in + * else case by sending assoc failure + */ + csrRoamCallCallback(pMac, sessionId, &roamInfo, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, + eCSR_ROAM_RESULT_FAILURE); + } + smsLog(pMac, LOG1, FL(" roam(reason %d) failed"), pCommand->u.roamCmd.roamReason); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosUpdateHandOff((tANI_U8)sessionId, VOS_FALSE); + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_FAILURE, eANI_BOOLEAN_FALSE); + csrScanStartIdleScan(pMac); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //For WDS STA. To fix the issue where the WDS AP side may be too busy by + //BT activity and not able to recevie WLAN traffic. Retry the join + if( CSR_IS_WDS_STA(pProfile) ) + { + csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD); + } +#endif + break; + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId); + + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_FAILURE, eANI_BOOLEAN_FALSE); + csrScanStartIdleScan(pMac); + break; + case eCsrForcedDisassoc: + case eCsrForcedDeauth: + case eCsrSmeIssuedIbssJoinFailure: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId); + + if(eCsrSmeIssuedIbssJoinFailure == pCommand->u.roamCmd.roamReason) + { + // Notify HDD that IBSS join failed + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_IBSS_IND, eCSR_ROAM_RESULT_IBSS_JOIN_FAILED); + } + else + { + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamLinkDown(pMac, sessionId); + /* + *DelSta not done FW still in conneced state so dont + *issue IMPS req + */ + if (pMac->roam.deauthRspStatus == eSIR_SME_DEAUTH_STATUS) + { + smsLog(pMac, LOGW, FL("FW still in connected state ")); + break; + } + csrScanStartIdleScan(pMac); + break; + case eCsrForcedIbssLeave: + csrIbssAgeBss(pMac); + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_IBSS_LEAVE, + eCSR_ROAM_RESULT_IBSS_STOP); + break; + case eCsrForcedDisassocMICFailure: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.roamCmd.roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_MIC_FAILURE); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (tANI_U8)sessionId, SME_QOS_CSR_DISCONNECT_REQ, NULL); +#endif + csrScanStartIdleScan(pMac); + break; + case eCsrStopBss: + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.roamCmd.roamId, + eCSR_ROAM_INFRA_IND, + eCSR_ROAM_RESULT_INFRA_STOPPED); + break; + case eCsrForcedDisassocSta: + case eCsrForcedDeauthSta: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINED, sessionId); + pSession = CSR_GET_SESSION(pMac, sessionId); + if (pSession) + { + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + roamInfo.u.pConnectedProfile = + &pSession->connectedProfile; + vos_mem_copy(roamInfo.peerMac, + pCommand->u.roamCmd.peerMac, + sizeof(tSirMacAddr)); + roamInfo.reasonCode = eCSR_ROAM_RESULT_FORCED; + roamInfo.statusCode = eSIR_SME_SUCCESS; + status = csrRoamCallCallback(pMac, sessionId, + &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_FORCED); + } + } + else + { + smsLog(pMac, LOGE, FL("Inactive session %d"), + sessionId); + return eHAL_STATUS_FAILURE; + } + } + else + { + smsLog(pMac, LOGE, FL("Invalid session")); + return eHAL_STATUS_FAILURE; + } + break; + case eCsrLostLink1: + // if lost link roam1 failed, then issue lost link Scan2 ... + csrScanRequestLostLink2(pMac, sessionId); + break; + case eCsrLostLink2: + // if lost link roam2 failed, then issue lost link scan3 ... + csrScanRequestLostLink3(pMac, sessionId); + break; + case eCsrLostLink3: + default: + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_IDLE, sessionId ); + + //We are done with one round of lostlink roaming here + csrScanHandleFailedLostlink3(pMac, sessionId); + break; + } + break; + } + } + return ( fReleaseCommand ); +} + +eHalStatus csrRoamRegisterCallback(tpAniSirGlobal pMac, csrRoamCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + return (status); +} + +eHalStatus csrRoamCopyProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pDstProfile, tCsrRoamProfile *pSrcProfile) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 size = 0; + + do + { + vos_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0); + if(pSrcProfile->BSSIDs.numOfBSSIDs) + { + size = sizeof(tCsrBssid) * pSrcProfile->BSSIDs.numOfBSSIDs; + pDstProfile->BSSIDs.bssid = vos_mem_malloc(size); + if ( NULL == pDstProfile->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->BSSIDs.numOfBSSIDs = pSrcProfile->BSSIDs.numOfBSSIDs; + vos_mem_copy(pDstProfile->BSSIDs.bssid, + pSrcProfile->BSSIDs.bssid, size); + } + if(pSrcProfile->SSIDs.numOfSSIDs) + { + size = sizeof(tCsrSSIDInfo) * pSrcProfile->SSIDs.numOfSSIDs; + pDstProfile->SSIDs.SSIDList = vos_mem_malloc(size); + if ( NULL == pDstProfile->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->SSIDs.numOfSSIDs = pSrcProfile->SSIDs.numOfSSIDs; + vos_mem_copy(pDstProfile->SSIDs.SSIDList, + pSrcProfile->SSIDs.SSIDList, size); + } + if(pSrcProfile->nWPAReqIELength) + { + pDstProfile->pWPAReqIE = vos_mem_malloc(pSrcProfile->nWPAReqIELength); + if ( NULL == pDstProfile->pWPAReqIE ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nWPAReqIELength = pSrcProfile->nWPAReqIELength; + vos_mem_copy(pDstProfile->pWPAReqIE, pSrcProfile->pWPAReqIE, + pSrcProfile->nWPAReqIELength); + } + if(pSrcProfile->nRSNReqIELength) + { + pDstProfile->pRSNReqIE = vos_mem_malloc(pSrcProfile->nRSNReqIELength); + if ( NULL == pDstProfile->pRSNReqIE ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nRSNReqIELength = pSrcProfile->nRSNReqIELength; + vos_mem_copy(pDstProfile->pRSNReqIE, pSrcProfile->pRSNReqIE, + pSrcProfile->nRSNReqIELength); + } +#ifdef FEATURE_WLAN_WAPI + if(pSrcProfile->nWAPIReqIELength) + { + pDstProfile->pWAPIReqIE = vos_mem_malloc(pSrcProfile->nWAPIReqIELength); + if ( NULL == pDstProfile->pWAPIReqIE ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nWAPIReqIELength = pSrcProfile->nWAPIReqIELength; + vos_mem_copy(pDstProfile->pWAPIReqIE, pSrcProfile->pWAPIReqIE, + pSrcProfile->nWAPIReqIELength); + } +#endif /* FEATURE_WLAN_WAPI */ + if(pSrcProfile->nAddIEScanLength) + { + memset(pDstProfile->addIEScan, 0 , SIR_MAC_MAX_ADD_IE_LENGTH); + if ( SIR_MAC_MAX_ADD_IE_LENGTH >= pSrcProfile->nAddIEScanLength) + { + vos_mem_copy(pDstProfile->addIEScan, pSrcProfile->addIEScan, + pSrcProfile->nAddIEScanLength); + pDstProfile->nAddIEScanLength = pSrcProfile->nAddIEScanLength; + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL(" AddIEScanLength is not valid %u"), + pSrcProfile->nAddIEScanLength); + } + } + if(pSrcProfile->nAddIEAssocLength) + { + pDstProfile->pAddIEAssoc = vos_mem_malloc(pSrcProfile->nAddIEAssocLength); + if ( NULL == pDstProfile->pAddIEAssoc ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength; + vos_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc, + pSrcProfile->nAddIEAssocLength); + } + if(pSrcProfile->ChannelInfo.ChannelList) + { + pDstProfile->ChannelInfo.ChannelList = vos_mem_malloc( + pSrcProfile->ChannelInfo.numOfChannels); + if ( NULL == pDstProfile->ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->ChannelInfo.numOfChannels = pSrcProfile->ChannelInfo.numOfChannels; + vos_mem_copy(pDstProfile->ChannelInfo.ChannelList, + pSrcProfile->ChannelInfo.ChannelList, + pSrcProfile->ChannelInfo.numOfChannels); + } + pDstProfile->AuthType = pSrcProfile->AuthType; + pDstProfile->EncryptionType = pSrcProfile->EncryptionType; + pDstProfile->mcEncryptionType = pSrcProfile->mcEncryptionType; + pDstProfile->negotiatedUCEncryptionType = pSrcProfile->negotiatedUCEncryptionType; + pDstProfile->negotiatedMCEncryptionType = pSrcProfile->negotiatedMCEncryptionType; + pDstProfile->negotiatedAuthType = pSrcProfile->negotiatedAuthType; +#ifdef WLAN_FEATURE_11W + pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled; + pDstProfile->MFPRequired = pSrcProfile->MFPRequired; + pDstProfile->MFPCapable = pSrcProfile->MFPCapable; +#endif + pDstProfile->BSSType = pSrcProfile->BSSType; + pDstProfile->phyMode = pSrcProfile->phyMode; + pDstProfile->csrPersona = pSrcProfile->csrPersona; + +#ifdef FEATURE_WLAN_WAPI + if(csrIsProfileWapi(pSrcProfile)) + { + if(pDstProfile->phyMode & eCSR_DOT11_MODE_11n) + { + pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n; + } + } +#endif /* FEATURE_WLAN_WAPI */ + pDstProfile->CBMode = pSrcProfile->CBMode; + /*Save the WPS info*/ + pDstProfile->bWPSAssociation = pSrcProfile->bWPSAssociation; + pDstProfile->bOSENAssociation = pSrcProfile->bOSENAssociation; + pDstProfile->uapsd_mask = pSrcProfile->uapsd_mask; + pDstProfile->beaconInterval = pSrcProfile->beaconInterval; + pDstProfile->privacy = pSrcProfile->privacy; + pDstProfile->fwdWPSPBCProbeReq = pSrcProfile->fwdWPSPBCProbeReq; + pDstProfile->csr80211AuthType = pSrcProfile->csr80211AuthType; + pDstProfile->dtimPeriod = pSrcProfile->dtimPeriod; + pDstProfile->ApUapsdEnable = pSrcProfile->ApUapsdEnable; + pDstProfile->SSIDs.SSIDList[0].ssidHidden = pSrcProfile->SSIDs.SSIDList[0].ssidHidden; + pDstProfile->protEnabled = pSrcProfile->protEnabled; + pDstProfile->obssProtEnabled = pSrcProfile->obssProtEnabled; + pDstProfile->cfg_protection = pSrcProfile->cfg_protection; + pDstProfile->wps_state = pSrcProfile->wps_state; + pDstProfile->ieee80211d = pSrcProfile->ieee80211d; + pDstProfile->force_24ghz_in_ht20 = + pSrcProfile->force_24ghz_in_ht20; + vos_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys, + sizeof(pDstProfile->Keys)); +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSrcProfile->MDID.mdiePresent) + { + pDstProfile->MDID.mdiePresent = 1; + pDstProfile->MDID.mobilityDomain = pSrcProfile->MDID.mobilityDomain; + } +#endif + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrReleaseProfile(pMac, pDstProfile); + pDstProfile = NULL; + } + + return (status); +} +eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamConnectedProfile *pSrcProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + do + { + vos_mem_set(pDstProfile, sizeof(tCsrRoamProfile), 0); + if(pSrcProfile->bssid) + { + pDstProfile->BSSIDs.bssid = vos_mem_malloc(sizeof(tCsrBssid)); + if ( NULL == pDstProfile->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, + FL("failed to allocate memory for BSSID" + "%02x:%02x:%02x:%02x:%02x:%02x"), + pSrcProfile->bssid[0], pSrcProfile->bssid[1], pSrcProfile->bssid[2], + pSrcProfile->bssid[3], pSrcProfile->bssid[4], pSrcProfile->bssid[5]); + break; + } + pDstProfile->BSSIDs.numOfBSSIDs = 1; + vos_mem_copy(pDstProfile->BSSIDs.bssid, pSrcProfile->bssid, + sizeof(tCsrBssid)); + } + if(pSrcProfile->SSID.ssId) + { + pDstProfile->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == pDstProfile->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, + FL("failed to allocate memory for SSIDList" + "%02x:%02x:%02x:%02x:%02x:%02x"), + pSrcProfile->bssid[0], pSrcProfile->bssid[1], pSrcProfile->bssid[2], + pSrcProfile->bssid[3], pSrcProfile->bssid[4], pSrcProfile->bssid[5]); + break; + } + pDstProfile->SSIDs.numOfSSIDs = 1; + pDstProfile->SSIDs.SSIDList[0].handoffPermitted = pSrcProfile->handoffPermitted; + pDstProfile->SSIDs.SSIDList[0].ssidHidden = pSrcProfile->ssidHidden; + vos_mem_copy(&pDstProfile->SSIDs.SSIDList[0].SSID, + &pSrcProfile->SSID, sizeof(tSirMacSSid)); + } + if(pSrcProfile->nAddIEAssocLength) + { + pDstProfile->pAddIEAssoc = vos_mem_malloc(pSrcProfile->nAddIEAssocLength); + if ( NULL == pDstProfile->pAddIEAssoc) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, FL(" failed to allocate memory for additional IEs ") ); + break; + } + pDstProfile->nAddIEAssocLength = pSrcProfile->nAddIEAssocLength; + vos_mem_copy(pDstProfile->pAddIEAssoc, pSrcProfile->pAddIEAssoc, + pSrcProfile->nAddIEAssocLength); + } + pDstProfile->ChannelInfo.ChannelList = vos_mem_malloc(1); + if ( NULL == pDstProfile->ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pDstProfile->ChannelInfo.numOfChannels = 1; + pDstProfile->ChannelInfo.ChannelList[0] = pSrcProfile->operationChannel; + pDstProfile->AuthType.numEntries = 1; + pDstProfile->AuthType.authType[0] = pSrcProfile->AuthType; + pDstProfile->negotiatedAuthType = pSrcProfile->AuthType; + pDstProfile->EncryptionType.numEntries = 1; + pDstProfile->EncryptionType.encryptionType[0] = pSrcProfile->EncryptionType; + pDstProfile->negotiatedUCEncryptionType = pSrcProfile->EncryptionType; + pDstProfile->mcEncryptionType.numEntries = 1; + pDstProfile->mcEncryptionType.encryptionType[0] = pSrcProfile->mcEncryptionType; + pDstProfile->negotiatedMCEncryptionType = pSrcProfile->mcEncryptionType; + pDstProfile->BSSType = pSrcProfile->BSSType; + pDstProfile->CBMode = pSrcProfile->CBMode; + vos_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys, + sizeof(pDstProfile->Keys)); +#ifdef WLAN_FEATURE_11W + pDstProfile->MFPEnabled = pSrcProfile->MFPEnabled; + pDstProfile->MFPRequired = pSrcProfile->MFPRequired; + pDstProfile->MFPCapable = pSrcProfile->MFPCapable; +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSrcProfile->MDID.mdiePresent) + { + pDstProfile->MDID.mdiePresent = 1; + pDstProfile->MDID.mobilityDomain = pSrcProfile->MDID.mobilityDomain; + } +#endif + + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrReleaseProfile(pMac, pDstProfile); + pDstProfile = NULL; + } + + return (status); +} + +eHalStatus csrRoamIssueConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBSSList, + eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate, + tANI_BOOLEAN fClearScan) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + else + { + if( fClearScan ) + { + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + } + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + if(NULL == pProfile) + { + //We can roam now + //Since pProfile is NULL, we need to build our own profile, set everything to default + //We can only support open and no encryption + pCommand->u.roamCmd.roamProfile.AuthType.numEntries = 1; + pCommand->u.roamCmd.roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM; + pCommand->u.roamCmd.roamProfile.EncryptionType.numEntries = 1; + pCommand->u.roamCmd.roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + pCommand->u.roamCmd.roamProfile.csrPersona = VOS_STA_MODE; + } + else + { + //make a copy of the profile + status = csrRoamCopyProfile(pMac, &pCommand->u.roamCmd.roamProfile, pProfile); + if(HAL_STATUS_SUCCESS(status)) + { + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_TRUE; + } + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.hBSSList = hBSSList; + pCommand->u.roamCmd.roamId = roamId; + pCommand->u.roamCmd.roamReason = reason; + //We need to free the BssList when the command is done + pCommand->u.roamCmd.fReleaseBssList = eANI_BOOLEAN_TRUE; + pCommand->u.roamCmd.fUpdateCurRoamProfile = eANI_BOOLEAN_TRUE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("CSR PERSONA=%d"), + pCommand->u.roamCmd.roamProfile.csrPersona); + status = csrQueueSmeCommand(pMac, pCommand, fImediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } + + return (status); +} +eHalStatus csrRoamIssueReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields *pMmodProfileFields, + eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + else + { + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + if(pProfile) + { + //This is likely trying to reassoc to different profile + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + //make a copy of the profile + status = csrRoamCopyProfile(pMac, &pCommand->u.roamCmd.roamProfile, pProfile); + pCommand->u.roamCmd.fUpdateCurRoamProfile = eANI_BOOLEAN_TRUE; + } + else + { + status = csrRoamCopyConnectedProfile(pMac, sessionId, &pCommand->u.roamCmd.roamProfile); + //how to update WPA/WPA2 info in roamProfile?? + pCommand->u.roamCmd.roamProfile.uapsd_mask = pMmodProfileFields->uapsd_mask; + } + if(HAL_STATUS_SUCCESS(status)) + { + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_TRUE; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamId = roamId; + pCommand->u.roamCmd.roamReason = reason; + //We need to free the BssList when the command is done + //For reassoc there is no BSS list, so the boolean set to false + pCommand->u.roamCmd.hBSSList = CSR_INVALID_SCANRESULT_HANDLE; + pCommand->u.roamCmd.fReleaseBssList = eANI_BOOLEAN_FALSE; + pCommand->u.roamCmd.fReassoc = eANI_BOOLEAN_TRUE; + status = csrQueueSmeCommand(pMac, pCommand, fImediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrRoamCompletion(pMac, sessionId, NULL, pCommand, eCSR_ROAM_RESULT_FAILURE, eANI_BOOLEAN_FALSE); + csrReleaseCommandRoam( pMac, pCommand ); + } + } + return (status); +} + +eHalStatus csrRoamEnqueuePreauth(tpAniSirGlobal pMac, tANI_U32 sessionId, tpSirBssDescription pBssDescription, + eCsrRoamReason reason, tANI_BOOLEAN fImmediate) +// , eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + else + { + if(pBssDescription) + { + //copy over the parameters we need later + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = reason; + //this is the important parameter + //in this case we are using this field for the "next" BSS + pCommand->u.roamCmd.pLastRoamBss = pBssDescription; + status = csrQueueSmeCommand(pMac, pCommand, fImmediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to enqueue preauth command, status = %d"), status ); + csrReleaseCommandPreauth( pMac, pCommand ); + } + } + else + { + //Return failure + status = eHAL_STATUS_RESOURCES; + } + } + return (status); +} + +eHalStatus csrRoamDequeuePreauth(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( (eSmeCommandRoam == pCommand->command) && + (eCsrPerformPreauth == pCommand->u.roamCmd.roamReason)) + { + smsLog( pMac, LOG1, FL("DQ-Command = %d, Reason = %d"), + pCommand->command, pCommand->u.roamCmd.roamReason); + if (csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK )) { + csrReleaseCommandPreauth( pMac, pCommand ); + } + } else { + smsLog( pMac, LOGE, FL("Command = %d, Reason = %d "), + pCommand->command, pCommand->u.roamCmd.roamReason); + } + } + else { + smsLog( pMac, LOGE, FL("pEntry NULL for eWNI_SME_FT_PRE_AUTH_RSP")); + } + smeProcessPendingQueue( pMac ); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrRoamConnectWithBSSList(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBssListIn, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList; + tANI_U32 roamId = 0; + status = csrScanCopyResultList(pMac, hBssListIn, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("failed to start a join process")); + csrScanResultPurge(pMac, hBSSList); + } + } + return (status); +} + +eHalStatus csrRoamConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBssListIn, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tScanResultHandle hBSSList; + tCsrScanResultFilter *pScanFilter; + tANI_U32 roamId = 0; + tANI_BOOLEAN fCallCallback = eANI_BOOLEAN_FALSE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pProfile) + { + smsLog(pMac, LOGP, FL("No profile specified")); + return eHAL_STATUS_FAILURE; + } + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL("called BSSType = %s (%d) authtype = %d " + "encryType = %d"), + lim_BssTypetoString(pProfile->BSSType), + pProfile->BSSType, + pProfile->AuthType.authType[0], + pProfile->EncryptionType.encryptionType[0]); + if( CSR_IS_WDS( pProfile ) && + !HAL_STATUS_SUCCESS( status = csrIsBTAMPAllowed( pMac, pProfile->operationChannel ) ) ) + { + smsLog(pMac, LOGE, FL("Request for BT AMP connection failed, channel requested is different than infra = %d"), + pProfile->operationChannel); + return status; + } + /* Reset abortConnection for the fresh connection */ + pSession->abortConnection = FALSE; + csrRoamCancelRoaming(pMac, sessionId); + csrScanRemoveFreshScanCommand(pMac, sessionId); + csrScanCancelIdleScan(pMac); + //Only abort the scan if it is not used for other roam/connect purpose + csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT); + + if (!vos_concurrent_open_sessions_running() && + (VOS_STA_SAP_MODE == pProfile->csrPersona)) + { + /* In case of AP mode we do not want idle mode scan */ + csrScanDisable(pMac); + } + + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrHddIssued); + //Check whether ssid changes + if(csrIsConnStateConnected(pMac, sessionId)) + { + if(pProfile->SSIDs.numOfSSIDs && !csrIsSsidInList(pMac, &pSession->connectedProfile.SSID, &pProfile->SSIDs)) + { + csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + pSession->maxRetryCount = CSR_JOIN_MAX_RETRY_COUNT; +#endif + + if(CSR_INVALID_SCANRESULT_HANDLE != hBssListIn) + { + smsLog(pMac, LOG1, FL("is called with BSSList")); + status = csrRoamConnectWithBSSList(pMac, sessionId, pProfile, hBssListIn, pRoamId); + if(pRoamId) + { + roamId = *pRoamId; + } + if(!HAL_STATUS_SUCCESS(status)) + { + fCallCallback = eANI_BOOLEAN_TRUE; + } + } + else + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + //Try to connect to any BSS + if(NULL == pProfile) + { + //No encryption + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + }//we don't have a profile + else + { + //Here is the profile we need to connect to + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + }//We have a profile + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + if(HAL_STATUS_SUCCESS(status)) + { + /*Save the WPS info*/ + if(NULL != pProfile) + { + pScanFilter->bWPSAssociation = pProfile->bWPSAssociation; + pScanFilter->bOSENAssociation = pProfile->bOSENAssociation; + } + else + { + pScanFilter->bWPSAssociation = 0; + pScanFilter->bOSENAssociation = 0; + } + do + { + if( (pProfile && CSR_IS_WDS_AP( pProfile ) ) + || (pProfile && CSR_IS_INFRA_AP ( pProfile )) + ) + { + //This can be started right away + status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" CSR failed to issue start BSS command with status = 0x%08X"), status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + else + { + smsLog(pMac, LOG1, FL("Connect request to proceed for AMP/SoftAP mode")); + } + break; + } + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + smsLog(pMac, LOG1, "************ csrScanGetResult Status ********* %d", status); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" CSR failed to issue connect command with status = 0x%08X"), status); + csrScanResultPurge(pMac, hBSSList); + fCallCallback = eANI_BOOLEAN_TRUE; + } + }//Have scan result + else if(NULL != pProfile) + { + //Check whether it is for start ibss + if(CSR_IS_START_IBSS(pProfile)) + { + status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " CSR failed to issue startIBSS command with status = 0x%08X", status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + } + else + { + //scan for this SSID + status = csrScanForSSID(pMac, sessionId, pProfile, roamId, TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" CSR failed to issue SSID scan command with status = 0x%08X"), status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + else + { + smsLog(pMac, LOG1, FL("SSID scan requested for Infra connect req")); + } + } + } + else + { + fCallCallback = eANI_BOOLEAN_TRUE; + } + } while (0); + if(NULL != pProfile) + { + //we need to free memory for filter if profile exists + csrFreeScanFilter(pMac, pScanFilter); + } + }//Got the scan filter from profile + + vos_mem_free(pScanFilter); + }//allocated memory for pScanFilter + }//No Bsslist coming in + //tell the caller if we fail to trigger a join request + if( fCallCallback ) + { + csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + + return (status); +} +eHalStatus csrRoamReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fCallCallback = eANI_BOOLEAN_TRUE; + tANI_U32 roamId = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pProfile) + { + smsLog(pMac, LOGP, FL("No profile specified")); + return eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL("called BSSType = %s (%d) authtype = %d " + "encryType = %d"), + lim_BssTypetoString(pProfile->BSSType), + pProfile->BSSType, + pProfile->AuthType.authType[0], + pProfile->EncryptionType.encryptionType[0]); + csrRoamCancelRoaming(pMac, sessionId); + csrScanRemoveFreshScanCommand(pMac, sessionId); + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrHddIssuedReassocToSameAP); + if(csrIsConnStateConnected(pMac, sessionId)) + { + if(pProfile) + { + if(pProfile->SSIDs.numOfSSIDs && + csrIsSsidInList(pMac, &pSession->connectedProfile.SSID, &pProfile->SSIDs)) + { + fCallCallback = eANI_BOOLEAN_FALSE; + } + else + { + smsLog(pMac, LOG1, FL("Not connected to the same SSID asked in the profile")); + } + } + else if (!vos_mem_compare(&modProfileFields, + &pSession->connectedProfile.modifyProfileFields, + sizeof(tCsrRoamModifyProfileFields))) + { + fCallCallback = eANI_BOOLEAN_FALSE; + } + else + { + smsLog(pMac, LOG1, FL("Either the profile is NULL or none of the fields " + "in tCsrRoamModifyProfileFields got modified")); + } + } + else + { + smsLog(pMac, LOG1, FL("Not connected! No need to reassoc")); + } + if(!fCallCallback) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + status = csrRoamIssueReassoc(pMac, sessionId, pProfile, &modProfileFields, + eCsrHddIssuedReassocToSameAP, roamId, eANI_BOOLEAN_FALSE); + } + else + { + status = csrRoamCallCallback(pMac, sessionId, NULL, roamId, + eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + return status; +} +eHalStatus csrRoamJoinLastProfile(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = NULL; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do + { + if(pSession->pCurRoamProfile) + { + csrScanCancelIdleScan(pMac); + csrScanAbortMacScanNotForConnect(pMac, sessionId); + //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if (!HAL_STATUS_SUCCESS(status)) + break; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + //we want to put the last connected BSS to the very beginning, if possible + csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList); + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + roamId, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_FALSE); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, hBSSList); + break; + } + } + else + { + //Do a scan on this profile + //scan for this SSID only in case the AP suppresses SSID + status = csrScanForSSID(pMac, sessionId, pProfile, roamId, TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + } + }//We have a profile + else + { + smsLog(pMac, LOGW, FL("cannot find a roaming profile")); + break; + } + }while(0); + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + return (status); +} +eHalStatus csrRoamReconnect(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + if(csrIsConnStateConnected(pMac, sessionId)) + { + status = csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrRoamJoinLastProfile(pMac, sessionId); + } + } + return (status); +} + +eHalStatus csrRoamConnectToLastProfile(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGW, FL("is called")); + csrRoamCancelRoaming(pMac, sessionId); + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrHddIssued); + if(csrIsConnStateDisconnected(pMac, sessionId)) + { + status = csrRoamJoinLastProfile(pMac, sessionId); + } + return (status); +} + +eHalStatus csrRoamProcessDisassocDeauth( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fDisassoc, tANI_BOOLEAN fMICFailure ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fComplete = eANI_BOOLEAN_FALSE; + eCsrRoamSubState NewSubstate; + tANI_U32 sessionId = pCommand->sessionId; + + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, FL(" Stop Wait for key timer and change substate to" + " eCSR_ROAM_SUBSTATE_NONE")); + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + // change state to 'Roaming'... + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId ); + + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + // If we are in an IBSS, then stop the IBSS... + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + else if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, FL(" restore AC weights (%d-%d-%d-%d)"), pMac->roam.ucACWeights[0], pMac->roam.ucACWeights[1], + pMac->roam.ucACWeights[2], pMac->roam.ucACWeights[3]); + //Restore AC weight in case we change it + WLANTL_SetACWeights(pMac->roam.gVosContext, pMac->roam.ucACWeights); + // in Infrasturcture, we need to disassociate from the Infrastructure network... + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_FORCED; + if(eCsrSmeIssuedDisassocForHandoff == pCommand->u.roamCmd.roamReason) + { + NewSubstate = eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF; + } + else + { + // If we are in neighbor preauth done state then on receiving + // disassoc or deauth we dont roam instead we just disassoc + // from current ap and then go to disconnected state + // This happens for ESE and 11r FT connections ONLY. +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac) && + (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsESEAssoc(pMac) && + (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId) && + (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef WLAN_FEATURE_LFR_MBB + csr_stop_preauth_reassoc_mbb_timer(pMac); +#endif + } + + if( fDisassoc ) + { + status = csrRoamIssueDisassociate( pMac, sessionId, NewSubstate, fMICFailure ); + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_SME_DISASSOC_ISSUE, NULL, 0); + } + } + else + { + status = csrRoamIssueDeauth( pMac, sessionId, eCSR_ROAM_SUBSTATE_DEAUTH_REQ ); + } + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + else if ( csrIsConnStateWds( pMac, sessionId ) ) + { + if( CSR_IS_WDS_AP( &pMac->roam.roamSession[sessionId].connectedProfile ) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + //This has to be WDS station + else if( csrIsConnStateConnectedWds( pMac, sessionId ) ) //This has to be WDS station + { + + pCommand->u.roamCmd.fStopWds = eANI_BOOLEAN_TRUE; + if( fDisassoc ) + { + status = csrRoamIssueDisassociate( pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, fMICFailure ); + fComplete = (!HAL_STATUS_SUCCESS(status)); + } + } + } else { + // we got a dis-assoc request while not connected to any peer + // just complete the command + fComplete = eANI_BOOLEAN_TRUE; + status = eHAL_STATUS_FAILURE; + } + if(fComplete) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + + if(HAL_STATUS_SUCCESS(status)) + { + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + //Set the state to disconnect here + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + //we don't need to run this timer any more + if (VOS_TIMER_STATE_RUNNING == + pMac->roam.neighborRoamInfo.forcedInitialRoamTo5GHTimer.state) + { + status = vos_timer_stop(&pMac->roam.neighborRoamInfo.forcedInitialRoamTo5GHTimer); + if (status != eHAL_STATUS_SUCCESS) + smsLog(pMac, LOGE, FL("Failed to Stop Forced 5G timer")); + } +#endif + } + } + else + { + smsLog(pMac, LOGW, FL(" failed with status %d"), status); + } + return (status); +} + +/* This is been removed from latest code base */ +/* +static eHalStatus csrRoamProcessStopBss( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status; + tANI_U32 sessionId = pCommand->sessionId; + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING ); + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ); + return ( status ); +} +*/ + +eHalStatus csrRoamIssueDisassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + + do + { + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + //Change the substate in case it is wait-for-key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + smsLog( pMac, LOG1, FL("Disassociate reason: %d, sessionId: %d"), + reason,sessionId); + switch ( reason ) + { + case eCSR_DISCONNECT_REASON_MIC_ERROR: + pCommand->u.roamCmd.roamReason = eCsrForcedDisassocMICFailure; + break; + case eCSR_DISCONNECT_REASON_DEAUTH: + pCommand->u.roamCmd.roamReason = eCsrForcedDeauth; + break; + case eCSR_DISCONNECT_REASON_HANDOFF: + pCommand->u.roamCmd.roamReason = eCsrSmeIssuedDisassocForHandoff; + break; + case eCSR_DISCONNECT_REASON_UNSPECIFIED: + case eCSR_DISCONNECT_REASON_DISASSOC: + pCommand->u.roamCmd.roamReason = eCsrForcedDisassoc; + break; + case eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE: + pCommand->u.roamCmd.roamReason = eCsrSmeIssuedIbssJoinFailure; + break; + case eCSR_DISCONNECT_REASON_IBSS_LEAVE: + pCommand->u.roamCmd.roamReason = eCsrForcedIbssLeave; + break; + default: + break; + } + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } while( 0 ); + return( status ); +} + +eHalStatus csrRoamIssueStopBssCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN fHighPriority ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + pCommand = csrGetCommandBuffer( pMac ); + if ( NULL != pCommand ) + { + //Change the substate in case it is wait-for-key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrStopBss; + status = csrQueueSmeCommand(pMac, pCommand, fHighPriority); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } + else + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + } + return ( status ); +} + +eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //Stop te retry + pSession->maxRetryCount = 0; + csrRoamStopJoinRetryTimer(pMac, sessionId); +#endif + //Not to call cancel roaming here + //Only issue disconnect when necessary + if(csrIsConnStateConnected(pMac, sessionId) || csrIsBssTypeIBSS(pSession->connectedProfile.BSSType) + || csrIsBssTypeWDS(pSession->connectedProfile.BSSType) + || csrIsRoamCommandWaitingForSession(pMac, sessionId) ) + + { + smsLog(pMac, LOG2, FL("called")); + status = csrRoamIssueDisassociateCmd(pMac, sessionId, reason); + } + else + { + csrScanAbortScanForSSID(pMac, sessionId); + csrScanStartIdleScan(pMac); + status = eHAL_STATUS_CMD_NOT_QUEUED; + smsLog(pMac, LOGE, + FL("Disconnect not queued, Abort Scan for SSID")); + } + return (status); +} + +eHalStatus csrRoamDisconnect(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + csrRoamCancelRoaming(pMac, sessionId); + csrRoamRemoveDuplicateCommand(pMac, sessionId, NULL, eCsrForcedDisassoc); + + return (csrRoamDisconnectInternal(pMac, sessionId, reason)); +} + +void csr_abortConnection(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->abortConnection = TRUE; + return; +} + +eHalStatus csrRoamSaveConnectedInfomation(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tDot11fBeaconIEs *pIesTemp = pIes; + tANI_U8 index; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tCsrRoamConnectedProfile *pConnectProfile = &pSession->connectedProfile; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + if(pConnectProfile->pAddIEAssoc) + { + vos_mem_free(pConnectProfile->pAddIEAssoc); + pConnectProfile->pAddIEAssoc = NULL; + } + vos_mem_set(&pSession->connectedProfile, sizeof(tCsrRoamConnectedProfile), 0); + pConnectProfile->AuthType = pProfile->negotiatedAuthType; + pConnectProfile->AuthInfo = pProfile->AuthType; + pConnectProfile->CBMode = pProfile->CBMode; //*** this may not be valid + pConnectProfile->EncryptionType = pProfile->negotiatedUCEncryptionType; + pConnectProfile->EncryptionInfo = pProfile->EncryptionType; + pConnectProfile->mcEncryptionType = pProfile->negotiatedMCEncryptionType; + pConnectProfile->mcEncryptionInfo = pProfile->mcEncryptionType; + pConnectProfile->BSSType = pProfile->BSSType; + pConnectProfile->modifyProfileFields.uapsd_mask = pProfile->uapsd_mask; + pConnectProfile->operationChannel = pSirBssDesc->channelId; + pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval; + if (!pConnectProfile->beaconInterval) + { + smsLog(pMac, LOGW, FL("ERROR: Beacon interval is ZERO")); + } + vos_mem_copy(&pConnectProfile->Keys, &pProfile->Keys, sizeof(tCsrKeys)); + /* saving the addional IE`s like Hot spot indication element and extended capabilities */ + if(pProfile->nAddIEAssocLength) + { + pConnectProfile->pAddIEAssoc = vos_mem_malloc(pProfile->nAddIEAssocLength); + if ( NULL == pConnectProfile->pAddIEAssoc ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory for additional IEs")) ; + return eHAL_STATUS_FAILURE; + } + pConnectProfile->nAddIEAssocLength = pProfile->nAddIEAssocLength; + vos_mem_copy(pConnectProfile->pAddIEAssoc, pProfile->pAddIEAssoc, + pProfile->nAddIEAssocLength); + } + +#ifdef WLAN_FEATURE_11W + pConnectProfile->MFPEnabled = pProfile->MFPEnabled; + pConnectProfile->MFPRequired = pProfile->MFPRequired; + pConnectProfile->MFPCapable = pProfile->MFPCapable; +#endif + + //Save bssid + csrGetBssIdBssDesc(pMac, pSirBssDesc, &pConnectProfile->bssid); +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pSirBssDesc->mdiePresent) + { + pConnectProfile->MDID.mdiePresent = 1; + pConnectProfile->MDID.mobilityDomain = (pSirBssDesc->mdie[1] << 8) | (pSirBssDesc->mdie[0]); + } +#endif + if( NULL == pIesTemp ) + { + status = csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesTemp); + } +#ifdef FEATURE_WLAN_ESE + if ((csrIsProfileESE(pProfile) || + ((pIesTemp->ESEVersion.present) + && ((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (pProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (pMac->roam.configParam.isEseIniFeatureEnabled)) + { + pConnectProfile->isESEAssoc = 1; + } +#endif + //save ssid + if(HAL_STATUS_SUCCESS(status)) + { + if(pIesTemp->SSID.present) + { + pConnectProfile->SSID.length = pIesTemp->SSID.num_ssid; + vos_mem_copy(pConnectProfile->SSID.ssId, pIesTemp->SSID.ssid, + pIesTemp->SSID.num_ssid); + } + + //Save the bss desc + status = csrRoamSaveConnectedBssDesc(pMac, sessionId, pSirBssDesc); + + if( CSR_IS_QOS_BSS(pIesTemp) || pIesTemp->HTCaps.present) + { + //Some HT AP's dont send WMM IE so in that case we assume all HT Ap's are Qos Enabled AP's + pConnectProfile->qap = TRUE; + } + else + { + pConnectProfile->qap = FALSE; + } + if ( NULL == pIes ) + { + //Free memory if it allocated locally + vos_mem_free(pIesTemp); + } + } + //Save Qos connection + pConnectProfile->qosConnection = pMac->roam.roamSession[sessionId].fWMMConnection; + + if(!HAL_STATUS_SUCCESS(status)) + { + csrFreeConnectBssDesc(pMac, sessionId); + } + for(index = 0; index < pProfile->SSIDs.numOfSSIDs; index++) + { + if ((pProfile->SSIDs.SSIDList[index].SSID.length == pConnectProfile->SSID.length) && + vos_mem_compare(pProfile->SSIDs.SSIDList[index].SSID.ssId, + pConnectProfile->SSID.ssId, + pConnectProfile->SSID.length)) + { + pConnectProfile->handoffPermitted = pProfile->SSIDs.SSIDList[index].handoffPermitted; + break; + } + pConnectProfile->handoffPermitted = FALSE; + } + + return (status); +} + +static void csrRoamJoinRspProcessor( tpAniSirGlobal pMac, tSirSmeJoinRsp *pSmeJoinRsp ) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamSession *pSession = NULL; + //The head of the active list is the request we sent + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + } + pSession = CSR_GET_SESSION( pMac, pSmeJoinRsp->sessionId ); + if ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) + { + if(pCommand && eCsrSmeIssuedAssocToSimilarAP == pCommand->u.roamCmd.roamReason) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, pSmeJoinRsp->sessionId, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); +#endif + } + csrRoamComplete( pMac, eCsrJoinSuccess, (void *)pSmeJoinRsp ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), + pSmeJoinRsp->sessionId); + return; + } + pSession->abortConnection = FALSE; + } + else + { + tANI_U32 roamId = 0; + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), + pSmeJoinRsp->sessionId); + return; + } + if (pSession->abortConnection) + { + smsLog(pMac, LOG1, FL("Disconnection in progess" + "abort Join request")); + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + pSession->abortConnection = FALSE; + return; + } + //The head of the active list is the request we sent + //Try to get back the same profile and roam again + if(pCommand) + { + roamId = pCommand->u.roamCmd.roamId; + } + pSession->joinFailStatusCode.statusCode = pSmeJoinRsp->statusCode; + pSession->joinFailStatusCode.reasonCode = pSmeJoinRsp->protStatusCode; + smsLog( pMac, LOGW, "SmeJoinReq failed with statusCode= 0x%08X [%d]", pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode ); +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* If Join fails while Handoff is in progress, indicate disassociated event to supplicant to reconnect */ + if (csrRoamIsHandoffInProgress(pMac)) + { + csrRoamCallCallback(pMac, pSmeJoinRsp->sessionId, NULL, roamId, eCSR_ROAM_DISASSOCIATED, eCSR_ROAM_RESULT_FORCED); + /* Should indicate neighbor roam algorithm about the connect failure here */ + csrNeighborRoamIndicateConnect(pMac, pSmeJoinRsp->sessionId, VOS_STATUS_E_FAILURE); + } +#endif + if (pCommand) + { + if(CSR_IS_WDS_STA( &pCommand->u.roamCmd.roamProfile )) + { + pCommand->u.roamCmd.fStopWds = eANI_BOOLEAN_TRUE; + pSession->connectedProfile.BSSType = eCSR_BSS_TYPE_WDS_STA; + csrRoamReissueRoamCommand(pMac); + } + else if( CSR_IS_WDS( &pCommand->u.roamCmd.roamProfile ) ) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else + { + csrRoam(pMac, pCommand); + } + } + else + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode ) */ +} + +eHalStatus csrRoamIssueJoin( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, + tCsrRoamProfile *pProfile, tANI_U32 roamId ) +{ + eHalStatus status; + smsLog( pMac, LOG1, "Attempting to Join Bssid= "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pSirBssDesc->bssId)); + + // Set the roaming substate to 'join attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_JOIN_REQ, sessionId); + // attempt to Join this BSS... + status = csrSendJoinReqMsg( pMac, sessionId, pSirBssDesc, pProfile, pIes, eWNI_SME_JOIN_REQ ); + return (status); +} + +static eHalStatus csrRoamIssueReassociate( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrRoamProfile *pProfile) +{ + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_JOINING, sessionId); + // Set the roaming substate to 'join attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_REASSOC_REQ, sessionId ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL(" calling csrSendJoinReqMsg (eWNI_SME_REASSOC_REQ)")); + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_SME_ISSUE_REASSOC_REQ, NULL, pProfile->negotiatedAuthType); + vos_record_roam_event(e_CACHE_ROAM_PEER_MAC, (void *)pSirBssDesc->bssId, 6); + } + // attempt to Join this BSS... + return csrSendJoinReqMsg( pMac, sessionId, pSirBssDesc, pProfile, pIes, eWNI_SME_REASSOC_REQ); +} + +void csrRoamReissueRoamCommand(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + tCsrRoamInfo roamInfo; + tANI_U32 sessionId; + tCsrRoamSession *pSession = NULL; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if ( eSmeCommandRoam == pCommand->command ) + { + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + /* While switching between two AP, csr will reissue roam command again + to the nextbss if it was interrupted by the dissconnect req for the + previous bss.During this csr is incrementing bRefAssocStartCnt twice. + so reset the bRefAssocStartCnt. + */ + if(pSession->bRefAssocStartCnt > 0) + { + pSession->bRefAssocStartCnt--; + } + if( pCommand->u.roamCmd.fStopWds ) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.pBssDesc = pCommand->u.roamCmd.pLastRoamBss; + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + if (CSR_IS_WDS(&pSession->connectedProfile)){ + pSession->connectState = eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_WDS_IND, + eCSR_ROAM_RESULT_WDS_DISASSOCIATED); + }else if (CSR_IS_INFRA_AP(&pSession->connectedProfile)){ + pSession->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED; + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.roamCmd.roamId, + eCSR_ROAM_INFRA_IND, + eCSR_ROAM_RESULT_INFRA_DISASSOCIATED); + } + + + if( !HAL_STATUS_SUCCESS( csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_STOP_BSS_REQ ) ) ) + { + smsLog(pMac, LOGE, " Failed to reissue stop_bss command for WDS after disassociated"); + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + else if(eCsrStopRoaming == csrRoamJoinNextBss(pMac, pCommand, eANI_BOOLEAN_TRUE)) + { + smsLog(pMac, LOGW, " Failed to reissue join command after disassociated"); + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + else + { + smsLog(pMac, LOGW, " Command is not roaming after disassociated"); + } + } + else + { + smsLog(pMac, LOGE, " Disassoc rsp cannot continue because no command is available"); + } +} + +tANI_BOOLEAN csrIsRoamCommandWaitingForSession(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + tSmeCmd *pCommand = NULL; + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( ( eSmeCommandRoam == pCommand->command ) && ( sessionId == pCommand->sessionId ) ) + { + fRet = eANI_BOOLEAN_TRUE; + } + } + if(eANI_BOOLEAN_FALSE == fRet) + { + csrLLLock(&pMac->sme.smeCmdPendingList); + pEntry = csrLLPeekHead(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK); + while(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( ( eSmeCommandRoam == pCommand->command ) && ( sessionId == pCommand->sessionId ) ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + pEntry = csrLLNext(&pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(&pMac->sme.smeCmdPendingList); + } + if (eANI_BOOLEAN_FALSE == fRet) + { + csrLLLock(&pMac->roam.roamCmdPendingList); + pEntry = csrLLPeekHead(&pMac->roam.roamCmdPendingList, LL_ACCESS_NOLOCK); + while (pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if (( eSmeCommandRoam == pCommand->command ) && ( sessionId == pCommand->sessionId ) ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + pEntry = csrLLNext(&pMac->roam.roamCmdPendingList, pEntry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(&pMac->roam.roamCmdPendingList); + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + return (fRet); +} + +tANI_BOOLEAN csrIsRoamCommandWaiting(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U32 i; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && ( fRet = csrIsRoamCommandWaitingForSession( pMac, i ) ) ) + { + break; + } + } + return ( fRet ); +} + +tANI_BOOLEAN csrIsCommandWaiting(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + fRet = csrLLIsListEmpty(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK); + if(eANI_BOOLEAN_FALSE == fRet) + { + fRet = csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK); + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + return (fRet); +} + +tANI_BOOLEAN csrIsScanForRoamCommandActive( tpAniSirGlobal pMac ) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + tCsrCmd *pCommand; + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tCsrCmd, Link); + if( ( eCsrRoamCommandScan == pCommand->command ) && + ( ( eCsrScanForSsid == pCommand->u.scanCmd.reason ) || + ( eCsrScanForCapsChange == pCommand->u.scanCmd.reason ) || + ( eCsrScanP2PFindPeer == pCommand->u.scanCmd.reason ) ) ) + { + fRet = eANI_BOOLEAN_TRUE; + } + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + return (fRet); +} +eHalStatus csrRoamIssueReassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fHighPriority = eANI_BOOLEAN_TRUE; + tANI_BOOLEAN fRemoveCmd = FALSE; + tListElem *pEntry; + // Delete the old assoc command. All is setup for reassoc to be serialized + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + return eHAL_STATUS_RESOURCES; + } + if ( eSmeCommandRoam == pCommand->command ) + { + if (pCommand->u.roamCmd.roamReason == eCsrSmeIssuedAssocToSimilarAP) + { + fRemoveCmd = csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ); + } + else + { + smsLog( pMac, LOGE, FL(" Unexpected active roam command present ") ); + } + if (fRemoveCmd == FALSE) + { + // Implies we did not get the serialized assoc command we + // were expecting + pCommand = NULL; + } + } + } + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer as expected based on previous connect roam command") ); + return eHAL_STATUS_RESOURCES; + } + do + { + //Change the substate in case it is wait-for-key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId ); + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrSmeIssuedFTReassoc; + status = csrQueueSmeCommand(pMac, pCommand, fHighPriority); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandRoam( pMac, pCommand ); + } + } while( 0 ); + + return( status ); +} +static void csrRoamingStateConfigCnfProcessor( tpAniSirGlobal pMac, tANI_U32 result ) +{ + tListElem *pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + tCsrScanResult *pScanResult = NULL; + tSirBssDescription *pBssDesc = NULL; + tSmeCmd *pCommand = NULL; + tANI_U32 sessionId; + tCsrRoamSession *pSession = NULL; + if(NULL == pEntry) + { + smsLog(pMac, LOGE, " CFG_CNF with active list empty"); + return; + } + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + smsLog(pMac, LOG1, FL("CFG return value is %d " + " current state is : %d substate is : %d "), + result, pMac->roam.curState[sessionId], + pMac->roam.curSubState[sessionId]); + if(CSR_IS_ROAMING(pSession) && pSession->fCancelRoaming) + { + //the roaming is cancelled. Simply complete the command + smsLog(pMac, LOGW, FL(" Roam command cancelled")); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + } + /* If the roaming has stopped, not to continue the roaming command*/ + else if ( !CSR_IS_ROAMING(pSession) && CSR_IS_ROAMING_COMMAND(pCommand) ) + { + //No need to complete roaming here as it already completes + smsLog(pMac, LOGW, FL(" Roam command (reason %d) aborted due to roaming completed\n"), + pCommand->u.roamCmd.roamReason); + csrSetAbortRoamingCommand( pMac, pCommand ); + csrRoamComplete(pMac, eCsrNothingToJoin, NULL); + } + else + { + if ( CCM_IS_RESULT_SUCCESS(result) ) + { + smsLog(pMac, LOG1, "Cfg sequence complete"); + // Successfully set the configuration parameters for the new Bss. Attempt to + // join the roaming Bss. + if(pCommand->u.roamCmd.pRoamBssEntry) + { + pScanResult = GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, tCsrScanResult, Link); + if (!pScanResult) + { + smsLog(pMac, LOGE, + FL("Failed to get base address for pScanResult")); + return; + } + pBssDesc = &pScanResult->Result.BssDescriptor; + } + if ( csrIsBssTypeIBSS( pCommand->u.roamCmd.roamProfile.BSSType ) || + CSR_IS_WDS( &pCommand->u.roamCmd.roamProfile ) + || CSR_IS_INFRA_AP(&pCommand->u.roamCmd.roamProfile) + ) + { + if(!HAL_STATUS_SUCCESS(csrRoamIssueStartBss( pMac, sessionId, + &pSession->bssParams, &pCommand->u.roamCmd.roamProfile, + pBssDesc, pCommand->u.roamCmd.roamId ))) + { + smsLog(pMac, LOGE, " CSR start BSS failed"); + //We need to complete the command + csrRoamComplete(pMac, eCsrStartBssFailure, NULL); + } + } + else + { + if (!pCommand->u.roamCmd.pRoamBssEntry) + { + smsLog(pMac, LOGE, " pRoamBssEntry is NULL"); + //We need to complete the command + csrRoamComplete(pMac, eCsrJoinFailure, NULL); + return; + } + // If we are roaming TO an Infrastructure BSS... + VOS_ASSERT(pScanResult != NULL); + if( !pScanResult->Result.pvIes ) + { + smsLog(pMac, LOGE, FL(" pvIes is NULL")); + return; + } + + if ( csrIsInfraBssDesc( pBssDesc ) ) + { + tDot11fBeaconIEs *pIesLocal = (tDot11fBeaconIEs *)pScanResult->Result.pvIes; + smsLog(pMac, LOG1, " Roaming in a Infra BSS"); + if(pIesLocal || (HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal))) ) + { + // ..and currently in an Infrastructure connection.... + if( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + smsLog(pMac, LOG1, " Connected to infra BSS"); + // ...and the SSIDs are equal, then we Reassoc. + if ( csrIsSsidEqual( pMac, pSession->pConnectBssDesc, pBssDesc, + pIesLocal ) ) + // ..and currently in an infrastructure connection + { + // then issue a Reassoc. + pCommand->u.roamCmd.fReassoc = eANI_BOOLEAN_TRUE; + csrRoamIssueReassociate( pMac, sessionId, pBssDesc, pIesLocal, + &pCommand->u.roamCmd.roamProfile ); + } + else + { + + // otherwise, we have to issue a new Join request to LIM because we disassociated from the + // previously associated AP. + if(!HAL_STATUS_SUCCESS(csrRoamIssueJoin( pMac, sessionId, pBssDesc, + pIesLocal, + &pCommand->u.roamCmd.roamProfile, pCommand->u.roamCmd.roamId ))) + { + //try something else + csrRoam( pMac, pCommand ); + } + } + } + else + { + eHalStatus status = eHAL_STATUS_SUCCESS; + + /* We need to come with other way to figure out that this is because of HO in BMP + The below API will be only available for Android as it uses a different HO algorithm */ + /* Reassoc request will be used only for ESE and 11r handoff whereas other legacy roaming should + * use join request */ +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIsHandoffInProgress(pMac) && + csrRoamIs11rAssoc(pMac)) + { + smsLog(pMac, LOG1, " HandoffInProgress with 11r enabled"); + status = csrRoamIssueReassociate(pMac, sessionId, pBssDesc, + (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ), &pCommand->u.roamCmd.roamProfile); + } + else +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsHandoffInProgress(pMac) && + csrRoamIsESEAssoc(pMac)) + { + smsLog(pMac, LOG1, " HandoffInProgress with ESE enabled"); + // Now serialize the reassoc command. + status = csrRoamIssueReassociateCmd(pMac, sessionId); + } + else +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsHandoffInProgress(pMac) && + csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + smsLog(pMac, LOG1, " HandoffInProgress with LFR enabled"); + // Now serialize the reassoc command. + status = csrRoamIssueReassociateCmd(pMac, sessionId); + } + else +#endif + // else we are not connected and attempting to Join. Issue the + // Join request. + { + smsLog(pMac, LOG1, " Not connected, Attempting to Join"); + status = csrRoamIssueJoin( pMac, sessionId, pBssDesc, + (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ), + &pCommand->u.roamCmd.roamProfile, pCommand->u.roamCmd.roamId ); + } + if(!HAL_STATUS_SUCCESS(status)) + { + //try something else + csrRoam( pMac, pCommand ); + } + } + if( !pScanResult->Result.pvIes ) + { + //Locally allocated + vos_mem_free(pIesLocal); + } + } + }//if ( csrIsInfraBssDesc( pBssDesc ) ) + else + { + smsLog(pMac, LOGW, FL(" found BSSType mismatching the one in BSS description")); + } + }//else + }//if ( WNI_CFG_SUCCESS == result ) + else + { + // In the event the configuration failed, for infra let the roam processor + //attempt to join something else... + if( pCommand->u.roamCmd.pRoamBssEntry && CSR_IS_INFRASTRUCTURE( &pCommand->u.roamCmd.roamProfile ) ) + { + csrRoam(pMac, pCommand); + } + else + { + //We need to complete the command + if ( csrIsBssTypeIBSS( pCommand->u.roamCmd.roamProfile.BSSType ) ) + { + csrRoamComplete(pMac, eCsrStartBssFailure, NULL); + } + else + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + } + } + }//we have active entry +} + +static void csrRoamRoamingStateAuthRspProcessor( tpAniSirGlobal pMac, tSirSmeAuthRsp *pSmeAuthRsp ) +{ + if ( eSIR_SME_SUCCESS == pSmeAuthRsp->statusCode ) + { + smsLog( pMac, LOGW, "CSR SmeAuthReq Successful" ); + // Successfully authenticated with a new Bss. Attempt to stop the current Bss and + // join the new one... + /***pBssDesc = profGetRoamingBssDesc( pAdapter, &pHddProfile ); + roamStopNetwork( pAdapter, &pBssDesc->SirBssDescription );***/ + } + else { + smsLog( pMac, LOGW, "CSR SmeAuthReq failed with statusCode= 0x%08X [%d]", pSmeAuthRsp->statusCode, pSmeAuthRsp->statusCode ); + /***profHandleLostLinkAfterReset(pAdapter); + // In the event the authenticate fails, let the roam processor attempt to join something else... + roamRoam( pAdapter );***/ + } +} + +static void csrRoamRoamingStateReassocRspProcessor( tpAniSirGlobal pMac, tpSirSmeJoinRsp pSmeJoinRsp ) +{ + eCsrRoamCompleteResult result; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tCsrRoamInfo roamInfo; + tANI_U32 roamId = 0; + tANI_U32 current_timestamp, max_time = -1; + tANI_U32 candidateApCnt, oldestIndex = 0; + tANI_U8 nilMac[6] = {0}; + + if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) + { + smsLog( pMac, LOGW, "CSR SmeReassocReq Successful" ); + result = eCsrReassocSuccess; + /* Defeaturize this part later if needed */ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + /* Since the neighbor roam algorithm uses reassoc req for handoff instead of join, + * we need the response contents while processing the result in csrRoamProcessResults() */ + if (csrRoamIsHandoffInProgress(pMac)) + { + /* Need to dig more on indicating events to SME QoS module */ + sme_QosCsrEventInd(pMac, pSmeJoinRsp->sessionId, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); + csrRoamComplete( pMac, result, pSmeJoinRsp); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* Add previous BSSID to blacklist ; this will be in blacklised for + * some period and score of this AP will be reduced if black listed + * to avoid ping pong */ + if (pMac->PERroamCandidatesCnt) + { + current_timestamp = jiffies_to_msecs(jiffies); + for (candidateApCnt = 0; candidateApCnt < + SIR_PER_ROAM_MAX_CANDIDATE_CNT; candidateApCnt++) + { + /* Find one blank entry */ + if (sirCompareMacAddr(nilMac, + pMac->previousRoamApInfo[candidateApCnt].bssAddr)) + { + vos_mem_copy(pMac->previousRoamApInfo[candidateApCnt]. + bssAddr, + pNeighborRoamInfo->prevConnProfile.bssid, + sizeof(tSirMacAddr)); + pMac->previousRoamApInfo[candidateApCnt].timeStamp = + current_timestamp; + smsLog(pMac, LOG1, FL("added bssid=" MAC_ADDRESS_STR " at index %d"), + MAC_ADDR_ARRAY( + pNeighborRoamInfo->prevConnProfile.bssid), + candidateApCnt); + break; + } + /* if already in the list */ + if (sirCompareMacAddr(pMac->previousRoamApInfo + [candidateApCnt].bssAddr, + pNeighborRoamInfo->prevConnProfile.bssid) && + ((current_timestamp - + pMac->previousRoamApInfo[candidateApCnt].timeStamp) > + pMac->PERroamTimeout)) + { + vos_mem_copy(pMac->previousRoamApInfo[candidateApCnt]. + bssAddr, + pNeighborRoamInfo->prevConnProfile.bssid, + sizeof(tSirMacAddr)); + pMac->previousRoamApInfo[candidateApCnt].timeStamp = + current_timestamp; + break; + } else + { + /* find oldest BSSID entry in the blacklist */ + if (max_time < + pMac->previousRoamApInfo[candidateApCnt].timeStamp) + { + max_time = + pMac->previousRoamApInfo[candidateApCnt].timeStamp; + oldestIndex = candidateApCnt; + } + } + } + if (candidateApCnt == SIR_PER_ROAM_MAX_CANDIDATE_CNT) + { + smsLog(pMac, LOGW, + "%s: Clearing out oldest roam results bssid=" + MAC_ADDRESS_STR, + __func__, + MAC_ADDR_ARRAY(pMac->previousRoamApInfo[oldestIndex].bssAddr)); + pMac->previousRoamApInfo[oldestIndex].timeStamp = current_timestamp; + vos_mem_copy(pMac->previousRoamApInfo[oldestIndex].bssAddr, + pNeighborRoamInfo->prevConnProfile.bssid, + sizeof(tSirMacAddr)); + } + } +#endif + } + else +#endif + { + csrRoamComplete( pMac, result, NULL ); + } + } + /* Should we handle this similar to handling the join failure? Is it ok + * to call csrRoamComplete() with state as CsrJoinFailure */ + else + { + smsLog( pMac, LOGW, "CSR SmeReassocReq failed with statusCode= 0x%08X [%d]", pSmeJoinRsp->statusCode, pSmeJoinRsp->statusCode ); + result = eCsrReassocFailure; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ROAM_FAIL, + FALSE, TRUE); +#ifdef WLAN_FEATURE_VOWIFI_11R + if ((eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE == pSmeJoinRsp->statusCode) || + (eSIR_SME_FT_REASSOC_FAILURE == pSmeJoinRsp->statusCode) || + (eSIR_SME_JOIN_DEAUTH_FROM_AP_DURING_ADD_STA == pSmeJoinRsp->statusCode)) + { + // Inform HDD to turn off FT flag in HDD + if (pNeighborRoamInfo) + { + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, + &roamInfo, roamId, eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS); + /* + * Since the above callback sends a disconnect + * to HDD, we should clean-up our state + * machine as well to be in sync with the upper + * layers. There is no need to send a disassoc + * since: 1) we will never reassoc to the current + * AP in LFR, and 2) there is no need to issue a + * disassoc to the AP with which we were trying + * to reassoc. + */ + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + return; + } + } +#endif + // In the event that the Reassociation fails, then we need to Disassociate the current association and keep + // roaming. Note that we will attempt to Join the AP instead of a Reassoc since we may have attempted a + // 'Reassoc to self', which AP's that don't support Reassoc will force a Disassoc. + //The disassoc rsp message will remove the command from active list + if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociate( pMac, pSmeJoinRsp->sessionId, + eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, FALSE ))) + { + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + } + } +} + +static void csrRoamRoamingStateStopBssRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSmeRsp) +{ +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_RSP; + if(eSIR_SME_SUCCESS != pSmeRsp->statusCode) + { + pIbssLog->status = WLAN_IBSS_STATUS_FAILURE; + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + pMac->roam.roamSession[pSmeRsp->sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + if(CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ( pMac, pSmeRsp->sessionId)) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else if(CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE( pMac, pSmeRsp->sessionId)) + { + csrRoamReissueRoamCommand(pMac); + } +} + +void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeRsp ) +{ + tSirResultCodes statusCode; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + tScanResultHandle hBSSList; + tANI_BOOLEAN fCallCallback, fRemoveCmd; + eHalStatus status; + tCsrRoamInfo roamInfo; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId = 0; + tCsrRoamProfile *pCurRoamProfile = NULL; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; +#endif + tANI_U32 sessionId; + tCsrRoamSession *pSession = NULL; + + tSirSmeDisassocRsp SmeDisassocRsp; + + csrSerDesUnpackDiassocRsp((tANI_U8 *)pSmeRsp, &SmeDisassocRsp); + sessionId = SmeDisassocRsp.sessionId; + statusCode = SmeDisassocRsp.statusCode; + + smsLog( pMac, LOG2, "csrRoamRoamingStateDisassocRspProcessor sessionId %d", sessionId); + + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN( pMac, sessionId ) ) + { + smsLog( pMac, LOG2, "***eCsrNothingToJoin***"); + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED( pMac, sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ( pMac, sessionId ) ) + { + if ( eSIR_SME_SUCCESS == statusCode ) + { + smsLog( pMac, LOG2, "CSR SmeDisassocReq force disassociated Successfully" ); + //A callback to HDD will be issued from csrRoamComplete so no need to do anything here + } + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "CSR SmeDisassocReq due to HO on session %d", sessionId ); +#if defined (WLAN_FEATURE_NEIGHBOR_ROAMING) + /* + * First ensure if the roam profile is in the scan cache. + * If not, post a reassoc failure and disconnect. + */ + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, + &pMac->roam.neighborRoamInfo.csrNeighborRoamProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, "%s: failed to prepare scan filter with status %d", + __func__, status); + goto POST_ROAM_FAILURE; + } + else + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE,"%s: csrScanGetResult failed with status %d", + __func__, status); + goto POST_ROAM_FAILURE; + } + } + } + else + { + smsLog( pMac, LOGE,"%s: alloc for pScanFilter failed with status %d", + __func__, status); + goto POST_ROAM_FAILURE; + } + + /* + * After ensuring that the roam profile is in the scan result list, + * dequeue the command from the active list. + */ + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* If the head of the queue is Active and it is a ROAM command, remove + * and put this on the Free queue. + */ + if ( eSmeCommandRoam == pCommand->command ) + { + + /* + * we need to process the result first before removing it from active list + * because state changes still happening insides roamQProcessRoamResults so + * no other roam command should be issued. + */ + fRemoveCmd = csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ); + if(pCommand->u.roamCmd.fReleaseProfile) + { + csrReleaseProfile(pMac, &pCommand->u.roamCmd.roamProfile); + pCommand->u.roamCmd.fReleaseProfile = eANI_BOOLEAN_FALSE; + } + if( fRemoveCmd ) + csrReleaseCommandRoam( pMac, pCommand ); + else + { + smsLog( pMac, LOGE, "%s: fail to remove cmd reason %d", + __func__, pCommand->u.roamCmd.roamReason ); + } + } + else + { + smsLog( pMac, LOGE, "%s: roam command not active", __func__ ); + } + } + else + { + smsLog( pMac, LOGE, "%s: NO commands are active", __func__ ); + } + + /* Notify HDD about handoff and provide the BSSID too */ + roamInfo.reasonCode = eCsrRoamReasonBetterAP; + + vos_mem_copy(roamInfo.bssid, + pMac->roam.neighborRoamInfo.csrNeighborRoamProfile.BSSIDs.bssid, + sizeof(tSirMacAddr)); + + csrRoamCallCallback(pMac,sessionId, &roamInfo, 0, + eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE); + + /* Copy the connected profile to apply the same for this connection as well */ + pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( pCurRoamProfile != NULL ) + { + vos_mem_set(pCurRoamProfile, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pCurRoamProfile, pSession->pCurRoamProfile); + //make sure to put it at the head of the cmd queue + status = csrRoamIssueConnect(pMac, sessionId, pCurRoamProfile, + hBSSList, eCsrSmeIssuedAssocToSimilarAP, + roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_FALSE); + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE,"%s: csrRoamIssueConnect failed with status %d", + __func__, status); + fCallCallback = eANI_BOOLEAN_TRUE; + } + + /* Notify sub-modules like QoS etc. that handoff happening */ + sme_QosCsrEventInd(pMac, sessionId, SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL); + pmcStopTrafficTimer(pMac); + csrReleaseProfile(pMac, pCurRoamProfile); + vos_mem_free(pCurRoamProfile); + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + return; + } + +POST_ROAM_FAILURE: + if (pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if (pCurRoamProfile) + vos_mem_free(pCurRoamProfile); + + /* Inform the upper layers that the reassoc failed */ + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(pMac, sessionId, + &roamInfo, 0, eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS); + + /* + * Issue a disassoc request so that PE/LIM uses this to clean-up the FT session. + * Upon success, we would re-enter this routine after receiving the disassoc + * response and will fall into the reassoc fail sub-state. And, eventually + * call csrRoamComplete which would remove the roam command from SME active + * queue. + */ + if (!HAL_STATUS_SUCCESS(csrRoamIssueDisassociate(pMac, sessionId, + eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE, FALSE))) + { + smsLog( pMac, LOGE,"%s: csrRoamIssueDisassociate failed with status %d", + __func__, status); + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + } +#endif + + } //else if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac ) ) + else if ( CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL( pMac, sessionId ) ) + { + // Disassoc due to Reassoc failure falls into this codepath.... + csrRoamComplete( pMac, eCsrJoinFailure, NULL ); + } + else + { + if ( eSIR_SME_SUCCESS == statusCode ) + { + // Successfully disassociated from the 'old' Bss... + // + // We get Disassociate response in three conditions. + // - First is the case where we are disasociating from an Infra Bss to start an IBSS. + // - Second is the when we are disassociating from an Infra Bss to join an IBSS or a new + // Infrastructure network. + // - Third is where we are doing an Infra to Infra roam between networks with different + // SSIDs. In all cases, we set the new Bss configuration here and attempt to join + + smsLog( pMac, LOG2, "CSR SmeDisassocReq disassociated Successfully" ); + } + else + { + smsLog( pMac, LOGE, "SmeDisassocReq failed with statusCode= 0x%08X", statusCode ); + } + //We are not done yet. Get the data and continue roaming + csrRoamReissueRoamCommand(pMac); + } +} + +static void csrRoamRoamingStateDeauthRspProcessor( tpAniSirGlobal pMac, tSirSmeDeauthRsp *pSmeRsp ) +{ + tSirResultCodes statusCode; + statusCode = csrGetDeAuthRspStatusCode( pSmeRsp ); + pMac->roam.deauthRspStatus = statusCode; + if ( CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ( pMac, pSmeRsp->sessionId) ) + { + csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + } + else + { + if ( eSIR_SME_SUCCESS == statusCode ) + { + // Successfully deauth from the 'old' Bss... + // + smsLog( pMac, LOG2, "CSR SmeDeauthReq disassociated Successfully" ); + } + else + { + smsLog( pMac, LOGW, "SmeDeauthReq failed with statusCode= 0x%08X", statusCode ); + } + //We are not done yet. Get the data and continue roaming + csrRoamReissueRoamCommand(pMac); + } +} + +static void csrRoamRoamingStateStartBssRspProcessor( tpAniSirGlobal pMac, tSirSmeStartBssRsp *pSmeStartBssRsp ) +{ + eCsrRoamCompleteResult result; + + if ( eSIR_SME_SUCCESS == pSmeStartBssRsp->statusCode ) + { + smsLog( pMac, LOGW, "SmeStartBssReq Successful" ); + result = eCsrStartBssSuccess; + } + else + { + smsLog( pMac, LOGW, "SmeStartBssReq failed with statusCode= 0x%08X", pSmeStartBssRsp->statusCode ); + //Let csrRoamComplete decide what to do + result = eCsrStartBssFailure; + } + csrRoamComplete( pMac, result, pSmeStartBssRsp); +} + +/* + We need to be careful on whether to cast pMsgBuf (pSmeRsp) to other type of strucutres. + It depends on how the message is constructed. If the message is sent by limSendSmeRsp, + the pMsgBuf is only a generic response and can only be used as pointer to tSirSmeRsp. + For the messages where sender allocates memory for specific structures, then it can be + cast accordingly. +*/ +void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + tSirSmeRsp *pSmeRsp; + tSmeIbssPeerInd *pIbssPeerInd; + tCsrRoamInfo roamInfo; + // TODO Session Id need to be acquired in this function + tANI_U32 sessionId = 0; + pSmeRsp = (tSirSmeRsp *)pMsgBuf; + smsLog(pMac, LOG2, FL("Message %d[0x%04X] received in substate %s"), + pSmeRsp->messageType, pSmeRsp->messageType, + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + pSmeRsp->messageType = (pSmeRsp->messageType); + pSmeRsp->length = (pSmeRsp->length); + pSmeRsp->statusCode = (pSmeRsp->statusCode); + switch (pSmeRsp->messageType) + { + + case eWNI_SME_JOIN_RSP: // in Roaming state, process the Join response message... + if (CSR_IS_ROAM_SUBSTATE_JOIN_REQ(pMac, pSmeRsp->sessionId)) + { + //We sent a JOIN_REQ + csrRoamJoinRspProcessor( pMac, (tSirSmeJoinRsp *)pSmeRsp ); + } + break; + + case eWNI_SME_AUTH_RSP: // or the Authenticate response message... + if (CSR_IS_ROAM_SUBSTATE_AUTH_REQ( pMac, pSmeRsp->sessionId) ) + { + //We sent a AUTH_REQ + csrRoamRoamingStateAuthRspProcessor( pMac, (tSirSmeAuthRsp *)pSmeRsp ); + } + break; + + case eWNI_SME_REASSOC_RSP: // or the Reassociation response message... + if (CSR_IS_ROAM_SUBSTATE_REASSOC_REQ( pMac, pSmeRsp->sessionId) ) + { + csrRoamRoamingStateReassocRspProcessor( pMac, (tpSirSmeJoinRsp )pSmeRsp ); + } + break; + + case eWNI_SME_STOP_BSS_RSP: // or the Stop Bss response message... + { + csrRoamRoamingStateStopBssRspProcessor(pMac, pSmeRsp); + } + break; + + case eWNI_SME_DISASSOC_RSP: // or the Disassociate response message... + if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_REQ( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISASSOC_NO_JOIN( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_REASSOC_FAIL( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISASSOC_FORCED( pMac, pSmeRsp->sessionId ) || + CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE( pMac, pSmeRsp->sessionId ) || +//HO + CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, pSmeRsp->sessionId ) ) + { + smsLog(pMac, LOG1, FL("eWNI_SME_DISASSOC_RSP subState = %s"), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + csrRoamRoamingStateDisassocRspProcessor( pMac, (tSirSmeDisassocRsp *)pSmeRsp ); + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_SME_DISASSOC_COMPLETE, NULL, 0); + } + } + break; + + case eWNI_SME_DEAUTH_RSP: // or the Deauthentication response message... + if ( CSR_IS_ROAM_SUBSTATE_DEAUTH_REQ( pMac, pSmeRsp->sessionId ) ) + { + csrRoamRoamingStateDeauthRspProcessor( pMac, (tSirSmeDeauthRsp *)pSmeRsp ); + } + break; + + case eWNI_SME_START_BSS_RSP: // or the Start BSS response message... + if (CSR_IS_ROAM_SUBSTATE_START_BSS_REQ( pMac, pSmeRsp->sessionId ) ) + { + csrRoamRoamingStateStartBssRspProcessor( pMac, (tSirSmeStartBssRsp *)pSmeRsp ); + } + break; + + case WNI_CFG_SET_CNF: // process the Config Confirm messages when we are in 'Config' substate... + if ( CSR_IS_ROAM_SUBSTATE_CONFIG( pMac, pSmeRsp->sessionId ) ) + { + csrRoamingStateConfigCnfProcessor( pMac, ((tCsrCfgSetRsp *)pSmeRsp)->respStatus ); + } + break; + //In case CSR issues STOP_BSS, we need to tell HDD about peer departed becasue PE is removing them + case eWNI_SME_IBSS_PEER_DEPARTED_IND: + pIbssPeerInd = (tSmeIbssPeerInd*)pSmeRsp; + smsLog(pMac, LOGE, "CSR: Peer departed notification from LIM in joining state"); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.staId = (tANI_U8)pIbssPeerInd->staId; + roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig; + roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig; + vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, + eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); + break; + case eWNI_SME_LOST_LINK_PARAMS_IND: + { + tpSirSmeLostLinkParamsInd pLostLinkParamsInd = (tpSirSmeLostLinkParamsInd)pSmeRsp; + tCsrRoamInfo roamInfo, *pRoamInfo = NULL; + eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.u.pLostLinkParams = &pLostLinkParamsInd->info; + pRoamInfo = &roamInfo; + csrRoamCallCallback(pMac, pLostLinkParamsInd->sessionId, + pRoamInfo, 0, eCSR_ROAM_LOST_LINK_PARAMS_IND, result); + break; + } + default: + smsLog(pMac, LOG1, + FL("Unexpected message type = %d[0x%X] received in substate %s"), + pSmeRsp->messageType, pSmeRsp->messageType, + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + + //If we are connected, check the link status change + if(!csrIsConnStateDisconnected(pMac, sessionId)) + { + csrRoamCheckForLinkStatusChange( pMac, pSmeRsp ); + } + break; + } +} + +void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + tSirSmeRsp *pSirMsg = (tSirSmeRsp *)pMsgBuf; + switch (pSirMsg->messageType) + { + case eWNI_SME_GET_STATISTICS_RSP: + smsLog( pMac, LOG2, FL("Stats rsp from PE")); + csrRoamStatsRspProcessor( pMac, pSirMsg ); + break; + case eWNI_SME_UPPER_LAYER_ASSOC_CNF: + { + tCsrRoamSession *pSession = NULL; + tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf; + tCsrRoamInfo roamInfo; + tCsrRoamInfo *pRoamInfo = NULL; + tANI_U32 sessionId; + eHalStatus status; + smsLog( pMac, LOG1, FL("ASSOCIATION confirmation can be given to upper layer ")); + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + pRoamInfo = &roamInfo; + pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *)pMsgBuf; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pUpperLayerAssocCnf->bssId, &sessionId ); + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + pRoamInfo->statusCode = eSIR_SME_SUCCESS; //send the status code as Success + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + pRoamInfo->staId = (tANI_U8)pUpperLayerAssocCnf->aid; + pRoamInfo->rsnIELen = (tANI_U8)pUpperLayerAssocCnf->rsnIE.length; + pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata; + pRoamInfo->addIELen = (tANI_U8)pUpperLayerAssocCnf->addIE.length; + pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata; + vos_mem_copy(pRoamInfo->peerMac, pUpperLayerAssocCnf->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pUpperLayerAssocCnf->bssId, + sizeof(tCsrBssid)); + pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta; +#ifdef WLAN_FEATURE_AP_HT40_24G + pRoamInfo->HT40MHzIntoEnabledSta = + pUpperLayerAssocCnf->HT40MHzIntoEnabledSta; + smsLog( pMac, LOGW, FL("HT40MHzIntoEnabledSta: %d \n"), + pRoamInfo->HT40MHzIntoEnabledSta); +#endif + pRoamInfo->maxRateFlags = pUpperLayerAssocCnf->rate_flags; + if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) ) + { + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED; + pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); + } + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + { + vos_sleep( 100 ); + pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;//Sta + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta + } + + } + break; + default: + csrRoamCheckForLinkStatusChange( pMac, pSirMsg ); + break; + } +} + +eHalStatus csrRoamIssueSetContextReq( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrEncryptionType EncryptType, + tSirBssDescription *pBssDescription, + tSirMacAddr *bssId, tANI_BOOLEAN addKey, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U16 keyLength, + tANI_U8 *pKey, tANI_U8 paeRole ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniEdType edType; + + if(eCSR_ENCRYPT_TYPE_UNKNOWN == EncryptType) + { + EncryptType = eCSR_ENCRYPT_TYPE_NONE; //*** + } + + edType = csrTranslateEncryptTypeToEdType( EncryptType ); + + // Allow 0 keys to be set for the non-WPA encrypt types... For WPA encrypt types, the num keys must be non-zero + // or LIM will reject the set context (assumes the SET_CONTEXT does not occur until the keys are distrubuted). + if ( CSR_IS_ENC_TYPE_STATIC( EncryptType ) || + addKey ) + { + tCsrRoamSetKey setKey; + setKey.encType = EncryptType; + setKey.keyDirection = aniKeyDirection; //Tx, Rx or Tx-and-Rx + vos_mem_copy(&setKey.peerMac, bssId, sizeof(tCsrBssid)); + setKey.paeRole = paeRole; //0 for supplicant + setKey.keyId = keyId; // Kye index + setKey.keyLength = keyLength; + if( keyLength ) + { + vos_mem_copy(setKey.Key, pKey, keyLength); + } + status = csrRoamIssueSetKeyCommand( pMac, sessionId, &setKey, 0 ); + } + return (status); +} + +static eHalStatus csrRoamIssueSetKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamSetKey *pSetKey, tANI_U32 roamId ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pCommand = NULL; +#ifdef FEATURE_WLAN_ESE + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); +#endif /* FEATURE_WLAN_ESE */ + + do + { + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_zero(pCommand, sizeof(tSmeCmd)); + pCommand->command = eSmeCommandSetKey; + pCommand->sessionId = (tANI_U8)sessionId; + // validate the key length, Adjust if too long... + // for static WEP the keys are not set thru' SetContextReq + if ( ( eCSR_ENCRYPT_TYPE_WEP40 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pSetKey->encType ) ) + { + //KeyLength maybe 0 for static WEP + if( pSetKey->keyLength ) + { + if ( pSetKey->keyLength < CSR_WEP40_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid WEP40 keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + + pCommand->u.setKeyCmd.keyLength = CSR_WEP40_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_WEP40_KEY_LEN); + } + } + else if ( ( eCSR_ENCRYPT_TYPE_WEP104 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pSetKey->encType ) ) + { + //KeyLength maybe 0 for static WEP + if( pSetKey->keyLength ) + { + if ( pSetKey->keyLength < CSR_WEP104_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid WEP104 keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + + pCommand->u.setKeyCmd.keyLength = CSR_WEP104_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_WEP104_KEY_LEN); + } + } + else if ( eCSR_ENCRYPT_TYPE_TKIP == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_TKIP_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid TKIP keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_TKIP_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_TKIP_KEY_LEN); + } + else if ( eCSR_ENCRYPT_TYPE_AES == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_AES_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_AES_KEY_LEN); + } +#ifdef FEATURE_WLAN_WAPI + else if ( eCSR_ENCRYPT_TYPE_WPI == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_WAPI_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid WAPI keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_WAPI_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, + CSR_WAPI_KEY_LEN); + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + else if ( eCSR_ENCRYPT_TYPE_KRK == pSetKey->encType ) + { + if ( pSetKey->keyLength < CSR_KRK_KEY_LEN ) + { + smsLog( pMac, LOGW, "Invalid KRK keylength [= %d] in SetContext call", pSetKey->keyLength ); + break; + } + vos_mem_copy(pSession->eseCckmInfo.krk, pSetKey->Key, + CSR_KRK_KEY_LEN); + pSession->eseCckmInfo.reassoc_req_num=1; + pSession->eseCckmInfo.krk_plumbed = eANI_BOOLEAN_TRUE; + status = eHAL_STATUS_SUCCESS; + break; + } +#endif /* FEATURE_WLAN_ESE */ + +#ifdef WLAN_FEATURE_11W + //Check for 11w BIP + else if (eCSR_ENCRYPT_TYPE_AES_CMAC == pSetKey->encType) + { + if (pSetKey->keyLength < CSR_AES_KEY_LEN) + { + smsLog(pMac, LOGW, "Invalid AES/CCMP keylength [= %d] in SetContext call", pSetKey->keyLength); + break; + } + pCommand->u.setKeyCmd.keyLength = CSR_AES_KEY_LEN; + vos_mem_copy(pCommand->u.setKeyCmd.Key, pSetKey->Key, CSR_AES_KEY_LEN); + } +#endif + status = eHAL_STATUS_SUCCESS; + pCommand->u.setKeyCmd.roamId = roamId; + pCommand->u.setKeyCmd.encType = pSetKey->encType; + pCommand->u.setKeyCmd.keyDirection = pSetKey->keyDirection; //Tx, Rx or Tx-and-Rx + vos_mem_copy(&pCommand->u.setKeyCmd.peerMac, &pSetKey->peerMac, + sizeof(tCsrBssid)); + pCommand->u.setKeyCmd.paeRole = pSetKey->paeRole; //0 for supplicant + pCommand->u.setKeyCmd.keyId = pSetKey->keyId; + vos_mem_copy(pCommand->u.setKeyCmd.keyRsc, pSetKey->keyRsc, CSR_MAX_RSC_LEN); + //Always put set key to the head of the Q because it is the only thing to get executed in case of WT_KEY state + + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + } + } while (0); + // Free the command if there has been a failure, or it is a + // "local" operation like the set ESE CCKM KRK key. + if ( ( NULL != pCommand ) && + ( (!HAL_STATUS_SUCCESS( status ) ) +#ifdef FEATURE_WLAN_ESE + || ( eCSR_ENCRYPT_TYPE_KRK == pSetKey->encType ) +#endif /* FEATURE_WLAN_ESE */ + ) ) + { + csrReleaseCommandSetKey( pMac, pCommand ); + } + return( status ); +} + +eHalStatus csrRoamIssueRemoveKeyCommand( tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamRemoveKey *pRemoveKey, tANI_U32 roamId ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fImediate = eANI_BOOLEAN_TRUE; + do + { + if( !csrIsSetKeyAllowed(pMac, sessionId) ) + { + smsLog( pMac, LOGW, FL(" wrong state not allowed to set key") ); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + break; + } + pCommand->command = eSmeCommandRemoveKey; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.removeKeyCmd.roamId = roamId; + pCommand->u.removeKeyCmd.encType = pRemoveKey->encType; + vos_mem_copy(&pCommand->u.removeKeyCmd.peerMac, &pRemoveKey->peerMac, + sizeof(tSirMacAddr)); + pCommand->u.removeKeyCmd.keyId = pRemoveKey->keyId; + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + //in this case, put it to the end of the Q incase there is a set key pending. + fImediate = eANI_BOOLEAN_FALSE; + } + smsLog( pMac, LOGE, FL("keyType=%d, keyId=%d, PeerMac="MAC_ADDRESS_STR), + pRemoveKey->encType, pRemoveKey->keyId, + MAC_ADDR_ARRAY(pCommand->u.removeKeyCmd.peerMac)); + status = csrQueueSmeCommand(pMac, pCommand, fImediate); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while (0); + if( !HAL_STATUS_SUCCESS( status ) && ( NULL != pCommand ) ) + { + csrReleaseCommandRemoveKey( pMac, pCommand ); + } + return (status ); +} + +eHalStatus csrRoamProcessSetKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status; + tANI_U8 numKeys = ( pCommand->u.setKeyCmd.keyLength ) ? 1 : 0; + tAniEdType edType = csrTranslateEncryptTypeToEdType( pCommand->u.setKeyCmd.encType ); + tANI_BOOLEAN fUnicast = ( pCommand->u.setKeyCmd.peerMac[0] == 0xFF ) ? eANI_BOOLEAN_FALSE : eANI_BOOLEAN_TRUE; + tANI_U32 sessionId = pCommand->sessionId; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + WLAN_VOS_DIAG_EVENT_DEF(setKeyEvent, vos_event_wlan_security_payload_type); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + if(eSIR_ED_NONE != edType) + { + vos_mem_set(&setKeyEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + if( *(( tANI_U8 *)&pCommand->u.setKeyCmd.peerMac) & 0x01 ) + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_BCAST_REQ; + setKeyEvent.encryptionModeMulticast = (v_U8_t)diagEncTypeFromCSRType(pCommand->u.setKeyCmd.encType); + setKeyEvent.encryptionModeUnicast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + } + else + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_UNICAST_REQ; + setKeyEvent.encryptionModeUnicast = (v_U8_t)diagEncTypeFromCSRType(pCommand->u.setKeyCmd.encType); + setKeyEvent.encryptionModeMulticast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + } + vos_mem_copy(setKeyEvent.bssid, pSession->connectedProfile.bssid, 6); + if(CSR_IS_ENC_TYPE_STATIC(pCommand->u.setKeyCmd.encType)) + { + tANI_U32 defKeyId; + //It has to be static WEP here + if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_WEP_DEFAULT_KEYID, &defKeyId))) + { + setKeyEvent.keyId = (v_U8_t)defKeyId; + } + } + else + { + setKeyEvent.keyId = pCommand->u.setKeyCmd.keyId; + } + setKeyEvent.authMode = (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( csrIsSetKeyAllowed(pMac, sessionId) ) + { + status = csrSendMBSetContextReqMsg( pMac, sessionId, + ( tANI_U8 *)&pCommand->u.setKeyCmd.peerMac, + numKeys, edType, fUnicast, pCommand->u.setKeyCmd.keyDirection, + pCommand->u.setKeyCmd.keyId, pCommand->u.setKeyCmd.keyLength, + pCommand->u.setKeyCmd.Key, pCommand->u.setKeyCmd.paeRole, + pCommand->u.setKeyCmd.keyRsc); + } + else + { + smsLog( pMac, LOGW, FL(" cannot process not connected") ); + //Set this status so the error handling take care of the case. + status = eHAL_STATUS_CSR_WRONG_STATE; + } + if( !HAL_STATUS_SUCCESS(status) ) + { + smsLog( pMac, LOGE, FL(" error status %d"), status ); + csrRoamCallCallback( pMac, sessionId, NULL, pCommand->u.setKeyCmd.roamId, eCSR_ROAM_SET_KEY_COMPLETE, eCSR_ROAM_RESULT_FAILURE); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + if(eSIR_ED_NONE != edType) + { + if( *(( tANI_U8 *)&pCommand->u.setKeyCmd.peerMac) & 0x01 ) + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_BCAST_RSP; + } + else + { + setKeyEvent.eventId = WLAN_SECURITY_EVENT_SET_UNICAST_RSP; + } + setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + WLAN_VOS_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + } + return ( status ); +} + +eHalStatus csrRoamProcessRemoveKeyCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status; + tpSirSmeRemoveKeyReq pMsg = NULL; + tANI_U16 wMsgLen = sizeof(tSirSmeRemoveKeyReq); + tANI_U8 *p; + tANI_U32 sessionId = pCommand->sessionId; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + WLAN_VOS_DIAG_EVENT_DEF(removeKeyEvent, vos_event_wlan_security_payload_type); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + vos_mem_set(&removeKeyEvent, + sizeof(vos_event_wlan_security_payload_type),0); + removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_REQ; + removeKeyEvent.encryptionModeMulticast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + removeKeyEvent.encryptionModeUnicast = (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(removeKeyEvent.bssid, pSession->connectedProfile.bssid, 6); + removeKeyEvent.keyId = pCommand->u.removeKeyCmd.keyId; + removeKeyEvent.authMode = (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&removeKeyEvent, EVENT_WLAN_SECURITY); +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( csrIsSetKeyAllowed(pMac, sessionId) ) + { + pMsg = vos_mem_malloc(wMsgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGW, FL(" wrong state not allowed to set key") ); + //Set the error status so error handling kicks in below + status = eHAL_STATUS_CSR_WRONG_STATE; + } + if( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_set(pMsg, wMsgLen ,0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_REMOVEKEY_REQ); + pMsg->length = pal_cpu_to_be16(wMsgLen); + pMsg->sessionId = (tANI_U8)sessionId; + pMsg->transactionId = 0; + p = (tANI_U8 *)pMsg + sizeof(pMsg->messageType) + sizeof(pMsg->length) + + sizeof(pMsg->sessionId) + sizeof(pMsg->transactionId); + // bssId - copy from session Info + vos_mem_copy(p, + &pMac->roam.roamSession[sessionId].connectedProfile.bssid, + sizeof(tSirMacAddr)); + p += sizeof(tSirMacAddr); + // peerMacAddr + vos_mem_copy(p, pCommand->u.removeKeyCmd.peerMac, sizeof(tSirMacAddr)); + p += sizeof(tSirMacAddr); + // edType + *p = (tANI_U8)csrTranslateEncryptTypeToEdType( pCommand->u.removeKeyCmd.encType ); + p++; + // weptype + if( ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pCommand->u.removeKeyCmd.encType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pCommand->u.removeKeyCmd.encType ) ) + { + *p = (tANI_U8)eSIR_WEP_STATIC; + } + else + { + *p = (tANI_U8)eSIR_WEP_DYNAMIC; + } + p++; + //keyid + *p = pCommand->u.removeKeyCmd.keyId; + p++; + *p = (pCommand->u.removeKeyCmd.peerMac[0] == 0xFF ) ? 0 : 1; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" error status %d"), status ); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_RSP; + removeKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + WLAN_VOS_DIAG_EVENT_REPORT(&removeKeyEvent, EVENT_WLAN_SECURITY); +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + csrRoamCallCallback( pMac, sessionId, NULL, pCommand->u.removeKeyCmd.roamId, eCSR_ROAM_REMOVE_KEY_COMPLETE, eCSR_ROAM_RESULT_FAILURE); + } + return ( status ); +} + +eHalStatus csrRoamSetKey( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 roamId ) +{ + eHalStatus status; + + if( !csrIsSetKeyAllowed(pMac, sessionId) ) + { + status = eHAL_STATUS_CSR_WRONG_STATE; + } + else + { + status = csrRoamIssueSetKeyCommand( pMac, sessionId, pSetKey, roamId ); + } + return ( status ); +} + +/* + Prepare a filter base on a profile for parsing the scan results. + Upon successful return, caller MUST call csrFreeScanFilter on + pScanFilter when it is done with the filter. +*/ +eHalStatus csrRoamPrepareFilterFromProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tCsrScanResultFilter *pScanFilter) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 size = 0; + tANI_U8 index = 0; + + do + { + if(pProfile->BSSIDs.numOfBSSIDs) + { + size = sizeof(tCsrBssid) * pProfile->BSSIDs.numOfBSSIDs; + pScanFilter->BSSIDs.bssid = vos_mem_malloc(size); + if ( NULL == pScanFilter->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pScanFilter->BSSIDs.numOfBSSIDs = pProfile->BSSIDs.numOfBSSIDs; + vos_mem_copy(pScanFilter->BSSIDs.bssid, pProfile->BSSIDs.bssid, size); + } + if(pProfile->SSIDs.numOfSSIDs) + { + if( !CSR_IS_WDS_STA( pProfile ) ) + { + pScanFilter->SSIDs.numOfSSIDs = pProfile->SSIDs.numOfSSIDs; + } + else + { + //For WDS station + //We always use index 1 for self SSID. Index 0 for peer's SSID that we want to join + pScanFilter->SSIDs.numOfSSIDs = 1; + } + size = sizeof(tCsrSSIDInfo) * pProfile->SSIDs.numOfSSIDs; + pScanFilter->SSIDs.SSIDList = vos_mem_malloc(size); + if ( NULL == pScanFilter->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_copy(pScanFilter->SSIDs.SSIDList, pProfile->SSIDs.SSIDList, + size); + } + if(!pProfile->ChannelInfo.ChannelList || (pProfile->ChannelInfo.ChannelList[0] == 0) ) + { + pScanFilter->ChannelInfo.numOfChannels = 0; + pScanFilter->ChannelInfo.ChannelList = NULL; + } + else if(pProfile->ChannelInfo.numOfChannels) + { + pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc( + sizeof(*pScanFilter->ChannelInfo.ChannelList) * + pProfile->ChannelInfo.numOfChannels); + if ( NULL == pScanFilter->ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + pScanFilter->ChannelInfo.numOfChannels = 0; + if(HAL_STATUS_SUCCESS(status)) + { + for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++) + { + if(csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[index])) + { + pScanFilter->ChannelInfo.ChannelList[pScanFilter->ChannelInfo.numOfChannels] + = pProfile->ChannelInfo.ChannelList[index]; + pScanFilter->ChannelInfo.numOfChannels++; + } + else + { + smsLog(pMac, LOG1, FL("process a channel (%d) that is invalid"), pProfile->ChannelInfo.ChannelList[index]); + } + } + } + else + { + break; + } + } + else + { + smsLog(pMac, LOGE, FL("Channel list empty")); + status = eHAL_STATUS_FAILURE; + break; + } + pScanFilter->uapsd_mask = pProfile->uapsd_mask; + pScanFilter->authType = pProfile->AuthType; + pScanFilter->EncryptionType = pProfile->EncryptionType; + pScanFilter->mcEncryptionType = pProfile->mcEncryptionType; + pScanFilter->BSSType = pProfile->BSSType; + pScanFilter->phyMode = pProfile->phyMode; +#ifdef FEATURE_WLAN_WAPI + //check if user asked for WAPI with 11n or auto mode, in that case modify + //the phymode to 11g + if(csrIsProfileWapi(pProfile)) + { + if(pScanFilter->phyMode & eCSR_DOT11_MODE_11n) + { + pScanFilter->phyMode &= ~eCSR_DOT11_MODE_11n; + } + if(pScanFilter->phyMode & eCSR_DOT11_MODE_AUTO) + { + pScanFilter->phyMode &= ~eCSR_DOT11_MODE_AUTO; + } + if(!pScanFilter->phyMode) + { + pScanFilter->phyMode = eCSR_DOT11_MODE_11g; + } + } +#endif /* FEATURE_WLAN_WAPI */ + /*Save the WPS info*/ + pScanFilter->bWPSAssociation = pProfile->bWPSAssociation; + pScanFilter->bOSENAssociation = pProfile->bOSENAssociation; + if( pProfile->countryCode[0] ) + { + //This causes the matching function to use countryCode as one of the criteria. + vos_mem_copy(pScanFilter->countryCode, pProfile->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pProfile->MDID.mdiePresent) + { + pScanFilter->MDID.mdiePresent = 1; + pScanFilter->MDID.mobilityDomain = pProfile->MDID.mobilityDomain; + } +#endif + vos_mem_copy(pScanFilter->bssid_hint, + pProfile->bssid_hint, VOS_MAC_ADDR_SIZE); + +#ifdef WLAN_FEATURE_11W + // Management Frame Protection + pScanFilter->MFPEnabled = pProfile->MFPEnabled; + pScanFilter->MFPRequired = pProfile->MFPRequired; + pScanFilter->MFPCapable = pProfile->MFPCapable; +#endif + + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrFreeScanFilter(pMac, pScanFilter); + } + + return(status); +} + +tANI_BOOLEAN csrRoamIssueWmStatusChange( tpAniSirGlobal pMac, tANI_U32 sessionId, + eCsrRoamWmStatusChangeTypes Type, tSirSmeRsp *pSmeRsp ) +{ + tANI_BOOLEAN fCommandQueued = eANI_BOOLEAN_FALSE; + tSmeCmd *pCommand; + do + { + // Validate the type is ok... + if ( ( eCsrDisassociated != Type ) && ( eCsrDeauthenticated != Type ) ) break; + pCommand = csrGetCommandBuffer( pMac ); + if ( !pCommand ) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + break; + } + //Change the substate in case it is waiting for key + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + } + pCommand->command = eSmeCommandWmStatusChange; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.wmStatusChangeCmd.Type = Type; + if ( eCsrDisassociated == Type ) + { + vos_mem_copy(&pCommand->u.wmStatusChangeCmd.u.DisassocIndMsg, + pSmeRsp, + sizeof( pCommand->u.wmStatusChangeCmd.u.DisassocIndMsg )); + } + else + { + vos_mem_copy(&pCommand->u.wmStatusChangeCmd.u.DeauthIndMsg, + pSmeRsp, + sizeof( pCommand->u.wmStatusChangeCmd.u.DeauthIndMsg )); + } + if( HAL_STATUS_SUCCESS( csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE) ) ) + { + fCommandQueued = eANI_BOOLEAN_TRUE; + } + else + { + smsLog( pMac, LOGE, FL(" fail to send message ") ); + csrReleaseCommandWmStatusChange( pMac, pCommand ); + } + + /* AP has issued Dissac/Deauth, Set the operating mode value to configured value */ + csrSetDefaultDot11Mode( pMac ); + } while( 0 ); + return( fCommandQueued ); +} + +static void csrUpdateRssi(tpAniSirGlobal pMac, void* pMsg) +{ + v_S7_t rssi = 0; + tAniGetRssiReq *pGetRssiReq = (tAniGetRssiReq*)pMsg; + if(pGetRssiReq) + { + if(NULL != pGetRssiReq->pVosContext) + { + WLANTL_GetRssi(pGetRssiReq->pVosContext, pGetRssiReq->staId, &rssi); + } + else + { + smsLog( pMac, LOGE, FL("pGetRssiReq->pVosContext is NULL")); + return; + } + + if(NULL != pGetRssiReq->rssiCallback) + { + ((tCsrRssiCallback)(pGetRssiReq->rssiCallback))(rssi, pGetRssiReq->staId, pGetRssiReq->pDevContext); + } + else + { + smsLog( pMac, LOGE, FL("pGetRssiReq->rssiCallback is NULL")); + return; + } + } + else + { + smsLog( pMac, LOGE, FL("pGetRssiReq is NULL")); + } + return; +} + +static void csrUpdateSnr(tpAniSirGlobal pMac, void* pMsg) +{ + tANI_S8 snr = 0; + tAniGetSnrReq *pGetSnrReq = (tAniGetSnrReq*)pMsg; + + if (pGetSnrReq) + { + if (VOS_STATUS_SUCCESS != + WDA_GetSnr(pGetSnrReq->staId, &snr)) + { + smsLog(pMac, LOGE, FL("Error in WLANTL_GetSnr")); + return; + } + + if (pGetSnrReq->snrCallback) + { + ((tCsrSnrCallback)(pGetSnrReq->snrCallback))(snr, pGetSnrReq->staId, + pGetSnrReq->pDevContext); + } + else + { + smsLog(pMac, LOGE, FL("pGetSnrReq->snrCallback is NULL")); + return; + } + } + else + { + smsLog(pMac, LOGE, FL("pGetSnrReq is NULL")); + } + return; +} +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +void csrRoamRssiRspProcessor(tpAniSirGlobal pMac, void* pMsg) +{ + tAniGetRoamRssiRsp* pRoamRssiRsp = (tAniGetRoamRssiRsp*)pMsg; + + if (NULL != pRoamRssiRsp) + { + /* Get roam Rssi request is backed up and passed back to the response, + Extract the request message to fetch callback */ + tpAniGetRssiReq reqBkp = (tAniGetRssiReq*)pRoamRssiRsp->rssiReq; + v_S7_t rssi = pRoamRssiRsp->rssi; + + if ((NULL != reqBkp) && (NULL != reqBkp->rssiCallback)) + { + ((tCsrRssiCallback)(reqBkp->rssiCallback))(rssi, pRoamRssiRsp->staId, reqBkp->pDevContext); + reqBkp->rssiCallback = NULL; + vos_mem_free(reqBkp); + pRoamRssiRsp->rssiReq = NULL; + } + else + { + smsLog( pMac, LOGE, FL("reqBkp->rssiCallback is NULL")); + if (NULL != reqBkp) + { + vos_mem_free(reqBkp); + pRoamRssiRsp->rssiReq = NULL; + } + } + } + else + { + smsLog( pMac, LOGE, FL("pRoamRssiRsp is NULL")); + } + return; +} +#endif + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +void csrTsmStatsRspProcessor(tpAniSirGlobal pMac, void* pMsg) +{ + tAniGetTsmStatsRsp* pTsmStatsRsp = (tAniGetTsmStatsRsp*)pMsg; + + if (NULL != pTsmStatsRsp) + { + /* Get roam Rssi request is backed up and passed back to the response, + Extract the request message to fetch callback */ + tpAniGetTsmStatsReq reqBkp = (tAniGetTsmStatsReq*)pTsmStatsRsp->tsmStatsReq; + + if (NULL != reqBkp) + { + if (NULL != reqBkp->tsmStatsCallback) + { + ((tCsrTsmStatsCallback)(reqBkp->tsmStatsCallback))(pTsmStatsRsp->tsmMetrics, + pTsmStatsRsp->staId, reqBkp->pDevContext); + reqBkp->tsmStatsCallback = NULL; + } + vos_mem_free(reqBkp); + pTsmStatsRsp->tsmStatsReq = NULL; + } + else + { + smsLog( pMac, LOGE, FL("reqBkp is NULL")); + if (NULL != reqBkp) + { + vos_mem_free(reqBkp); + pTsmStatsRsp->tsmStatsReq = NULL; + } + } + } + else + { + smsLog( pMac, LOGE, FL("pTsmStatsRsp is NULL")); + } + return; +} + +void csrSendEseAdjacentApRepInd(tpAniSirGlobal pMac, tCsrRoamSession *pSession) +{ + tANI_U32 roamTS2 = 0; + tCsrRoamInfo roamInfo; + tpPESession pSessionEntry = NULL; + tANI_U8 sessionId = CSR_SESSION_ID_INVALID; + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL")); + return; + } + + roamTS2 = vos_timer_get_system_time(); + roamInfo.tsmRoamDelay = roamTS2 - pSession->roamTS1; + smsLog(pMac, LOG1, "Bssid("MAC_ADDRESS_STR") Roaming Delay(%u ms)", + MAC_ADDR_ARRAY(pSession->connectedProfile.bssid), + roamInfo.tsmRoamDelay); + + pSessionEntry = peFindSessionByBssid(pMac, pSession->connectedProfile.bssid, &sessionId); + if (NULL == pSessionEntry) + { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + return; + } + pSessionEntry->eseContext.tsm.tsmMetrics.RoamingDly = roamInfo.tsmRoamDelay; + csrRoamCallCallback(pMac, pSession->sessionId, &roamInfo, + 0, eCSR_ROAM_ESE_ADJ_AP_REPORT_IND, 0); +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +static void csrRoamRssiIndHdlr(tpAniSirGlobal pMac, void* pMsg) +{ + WLANTL_TlIndicationReq *pTlRssiInd = (WLANTL_TlIndicationReq*)pMsg; + if(pTlRssiInd) + { + if(NULL != pTlRssiInd->tlCallback) + { + ((WLANTL_RSSICrossThresholdCBType)(pTlRssiInd->tlCallback)) + (pTlRssiInd->pAdapter, pTlRssiInd->rssiNotification, pTlRssiInd->pUserCtxt, pTlRssiInd->avgRssi); + } + else + { + smsLog( pMac, LOGE, FL("pTlRssiInd->tlCallback is NULL")); + } + } + else + { + smsLog( pMac, LOGE, FL("pTlRssiInd is NULL")); + } + return; +} + +eHalStatus csrSendResetApCapsChanged(tpAniSirGlobal pMac, tSirMacAddr *bssId) +{ + tpSirResetAPCapsChange pMsg; + tANI_U16 len; + eHalStatus status = eHAL_STATUS_SUCCESS; + + /* Create the message and send to lim */ + len = sizeof(tSirResetAPCapsChange); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, sizeof(tSirResetAPCapsChange), 0); + pMsg->messageType = eWNI_SME_RESET_AP_CAPS_CHANGED; + pMsg->length = len; + vos_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr)); + smsLog( pMac, LOG1, FL("CSR reset caps change for Bssid= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->bssId)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + else + { + smsLog( pMac, LOGE, FL("Memory allocation failed\n")); + } + return status; +} + +void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg ) +{ + tSirSmeAssocInd *pAssocInd; + tSirSmeDisassocInd *pDisassocInd; + tSirSmeDeauthInd *pDeauthInd; + tSirSmeDisConDoneInd *pDisConDoneInd; + tSirSmeWmStatusChangeNtf *pStatusChangeMsg; + tSirSmeNewBssInfo *pNewBss; + tSmeIbssPeerInd *pIbssPeerInd; + tSirMacAddr Broadcastaddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + tSirSmeApNewCaps *pApNewCaps; + eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; + eRoamCmdStatus roamStatus = eCSR_ROAM_FAILED; + tCsrRoamInfo *pRoamInfo = NULL; + tCsrRoamInfo roamInfo; + eHalStatus status; + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + tCsrRoamSession *pSession = NULL; + tpSirSmeSwitchChannelInd pSwitchChnInd; + tSmeMaxAssocInd *pSmeMaxAssocInd; + vos_mem_set(&roamInfo, sizeof(roamInfo), 0); + + + if (NULL == pSirMsg) + { smsLog(pMac, LOGE, FL("pSirMsg is NULL")); + return; + } + switch( pSirMsg->messageType ) + { + case eWNI_SME_ASSOC_IND: + { + tCsrRoamSession *pSession = NULL; + smsLog( pMac, LOG1, FL("Receive WNI_SME_ASSOC_IND from SME")); + pAssocInd = (tSirSmeAssocInd *)pSirMsg; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pAssocInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + pRoamInfo = &roamInfo; + + // Required for indicating the frames to upper layer + pRoamInfo->assocReqLength = pAssocInd->assocReqLength; + pRoamInfo->assocReqPtr = pAssocInd->assocReqPtr; + + pRoamInfo->beaconPtr = pAssocInd->beaconPtr; + pRoamInfo->beaconLength = pAssocInd->beaconLength; + pRoamInfo->statusCode = eSIR_SME_SUCCESS; //send the status code as Success + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + + pRoamInfo->staId = (tANI_U8)pAssocInd->staId; + pRoamInfo->rsnIELen = (tANI_U8)pAssocInd->rsnIE.length; + pRoamInfo->prsnIE = pAssocInd->rsnIE.rsnIEdata; + + pRoamInfo->addIELen = (tANI_U8)pAssocInd->addIE.length; + pRoamInfo->paddIE = pAssocInd->addIE.addIEdata; + vos_mem_copy(pRoamInfo->peerMac, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, pAssocInd->bssId, + sizeof(tCsrBssid)); + pRoamInfo->wmmEnabledSta = pAssocInd->wmmEnabledSta; + pRoamInfo->maxRateFlags = pAssocInd->rate_flags; +#ifdef WLAN_FEATURE_AP_HT40_24G + pRoamInfo->HT40MHzIntoEnabledSta = + pAssocInd->HT40MHzIntoEnabledSta; + smsLog(pMac, LOGW, FL("HT40MHzIntoEnabledSta: %d \n"), + pRoamInfo->HT40MHzIntoEnabledSta); +#endif + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_WDS_IND, eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta + if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) + { +#ifdef SAP_AUTH_OFFLOAD + if (pMac->sap_auth_offload) + { + smsLog(pMac, LOGW, FL(" Auth is not required to set in Auth offload case \n")); + pRoamInfo->fAuthRequired = FALSE; + } + else + { +#endif + if( CSR_IS_ENC_TYPE_STATIC( pSession->pCurRoamProfile->negotiatedUCEncryptionType )) + { + csrRoamIssueSetContextReq( pMac, sessionId, pSession->pCurRoamProfile->negotiatedUCEncryptionType, + pSession->pConnectBssDesc, + &(pRoamInfo->peerMac), + FALSE, TRUE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + pRoamInfo->fAuthRequired = FALSE; + } + else + { + pRoamInfo->fAuthRequired = TRUE; + } +#ifdef SAP_AUTH_OFFLOAD + } +#endif + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND); + if (!HAL_STATUS_SUCCESS(status)) + pRoamInfo->statusCode = eSIR_SME_ASSOC_REFUSED;// Refused due to Mac filtering + } + /* Send Association completion message to PE */ + status = csrSendAssocCnfMsg( pMac, pAssocInd, status );//Sta + + /* send a message to CSR itself just to avoid the EAPOL frames going + * OTA before association response */ + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + { + status = csrSendAssocIndToUpperLayerCnfMsg(pMac, pAssocInd, status, sessionId); + } + else if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) && (pRoamInfo->statusCode != eSIR_SME_ASSOC_REFUSED)) + { + pRoamInfo->fReassocReq = pAssocInd->reassocReq; + //status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); + status = csrSendAssocIndToUpperLayerCnfMsg(pMac, pAssocInd, status, sessionId); + } + } + } + break; + case eWNI_SME_DISASSOC_IND: + { + // Check if AP dis-associated us because of MIC failure. If so, + // then we need to take action immediately and not wait till the + // the WmStatusChange requests is pushed and processed + tSmeCmd *pCommand; + + pDisassocInd = (tSirSmeDisassocInd *)pSirMsg; + status = csrRoamGetSessionIdFromBSSID( pMac, + (tCsrBssid *)pDisassocInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("DISASSOCIATION Indication from MAC" + " for session %d "), sessionId); + smsLog( pMac, LOGE, FL("DISASSOCIATION from peer =" + MAC_ADDRESS_STR " " + " reason = %d status = %d "), + MAC_ADDR_ARRAY(pDisassocInd->peerMacAddr), + pDisassocInd->reasonCode, + pDisassocInd->statusCode); + // If we are in neighbor preauth done state then on receiving + // disassoc or deauth we dont roam instead we just disassoc + // from current ap and then go to disconnected state + // This happens for ESE and 11r FT connections ONLY. +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac) && (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsESEAssoc(pMac) && (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId) && (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef WLAN_FEATURE_LFR_MBB + csr_stop_preauth_reassoc_mbb_timer(pMac); +#endif + + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamLinkDown(pMac, sessionId); + csrRoamIssueWmStatusChange( pMac, sessionId, eCsrDisassociated, pSirMsg ); + if (CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + /* + * STA/P2P client got disassociated so remove any pending deauth + * commands in sme pending list + */ + pCommand = csrGetCommandBuffer(pMac); + if (NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + status = eHAL_STATUS_RESOURCES; + return; + } + pCommand->command = eSmeCommandRoam; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta; + vos_mem_copy(pCommand->u.roamCmd.peerMac, + pDisassocInd->peerMacAddr, + sizeof(tSirMacAddr)); + csrRoamRemoveDuplicateCommand(pMac, sessionId, pCommand, eCsrForcedDeauthSta); + csrReleaseCommand( pMac, pCommand ); + + } + } + else + { + smsLog(pMac, LOGE, FL(" Session Id not found for BSSID " MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pDisassocInd->bssId)); + } + } + break; + case eWNI_SME_DEAUTH_IND: + smsLog( pMac, LOG1, FL("DEAUTHENTICATION Indication from MAC")); + pDeauthInd = (tpSirSmeDeauthInd)pSirMsg; + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pDeauthInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + // If we are in neighbor preauth done state then on receiving + // disassoc or deauth we dont roam instead we just disassoc + // from current ap and then go to disconnected state + // This happens for ESE and 11r FT connections ONLY. +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac) && (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef FEATURE_WLAN_ESE + if (csrRoamIsESEAssoc(pMac) && (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId) && (csrNeighborRoamStatePreauthDone(pMac))) + { + csrNeighborRoamTranistionPreauthDoneToDisconnected(pMac); + } +#endif +#ifdef WLAN_FEATURE_LFR_MBB + csr_stop_preauth_reassoc_mbb_timer(pMac); +#endif + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if ( csrIsConnStateInfra( pMac, sessionId ) ) + { + pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_DISCONNECT_IND, NULL); +#endif + csrRoamLinkDown(pMac, sessionId); + csrRoamIssueWmStatusChange( pMac, sessionId, eCsrDeauthenticated, pSirMsg ); + } + break; + + case eWNI_SME_DISCONNECT_DONE_IND: + pDisConDoneInd = (tSirSmeDisConDoneInd *)(pSirMsg); + smsLog( pMac, LOG1, + FL("eWNI_SME_DISCONNECT_DONE_IND RC:%d"), + pDisConDoneInd->reasonCode); + if( CSR_IS_SESSION_VALID(pMac, pDisConDoneInd->sessionId)) + { + roamInfo.reasonCode = pDisConDoneInd->reasonCode; + roamInfo.statusCode = eSIR_SME_STA_DISASSOCIATED; + vos_mem_copy(roamInfo.peerMac, pDisConDoneInd->peerMacAddr, + sizeof(tSirMacAddr)); + status = csrRoamCallCallback(pMac, + pDisConDoneInd->sessionId, + &roamInfo, 0, + eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_DISASSOC_IND); + pSession = CSR_GET_SESSION(pMac, + pDisConDoneInd->sessionId); + if (pSession && + !CSR_IS_INFRA_AP(&pSession->connectedProfile)) + csrRoamStateChange(pMac, + eCSR_ROAMING_STATE_IDLE, + pDisConDoneInd->sessionId); + } + else + { + smsLog(pMac, LOGE, FL("Inactive session %d"), + pDisConDoneInd->sessionId); + } + break; + + case eWNI_SME_SWITCH_CHL_REQ: // in case of STA, the SWITCH_CHANNEL originates from its AP + smsLog( pMac, LOGW, FL("eWNI_SME_SWITCH_CHL_REQ from SME")); + pSwitchChnInd = (tpSirSmeSwitchChannelInd)pSirMsg; + //Update with the new channel id. + //The channel id is hidden in the statusCode. + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pSwitchChnInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->connectedProfile.operationChannel = (tANI_U8)pSwitchChnInd->newChannelId; + if(pSession->pConnectBssDesc) + { + pSession->pConnectBssDesc->channelId = (tANI_U8)pSwitchChnInd->newChannelId; + } + } + break; + + case eWNI_SME_DEAUTH_RSP: + smsLog( pMac, LOGW, FL("eWNI_SME_DEAUTH_RSP from SME")); + { + tSirSmeDeauthRsp* pDeauthRsp = (tSirSmeDeauthRsp *)pSirMsg; + sessionId = pDeauthRsp->sessionId; + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + pRoamInfo = &roamInfo; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + vos_mem_copy(pRoamInfo->peerMac, pDeauthRsp->peerMacAddr, + sizeof(tSirMacAddr)); + pRoamInfo->reasonCode = eCSR_ROAM_RESULT_FORCED; + pRoamInfo->statusCode = pDeauthRsp->statusCode; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_LOSTLINK, eCSR_ROAM_RESULT_FORCED); + } + } + } + break; + + case eWNI_SME_DISASSOC_RSP: + /* session id is invalid here so cant use it to access the array curSubstate as index */ + smsLog( pMac, LOGW, FL("eWNI_SME_DISASSOC_RSP from SME ")); + { + tSirSmeDisassocRsp *pDisassocRsp = (tSirSmeDisassocRsp *)pSirMsg; + sessionId = pDisassocRsp->sessionId; + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + pSession = CSR_GET_SESSION(pMac, sessionId); + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + pRoamInfo = &roamInfo; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + vos_mem_copy(pRoamInfo->peerMac, pDisassocRsp->peerMacAddr, + sizeof(tSirMacAddr)); + pRoamInfo->reasonCode = eCSR_ROAM_RESULT_FORCED; + pRoamInfo->statusCode = pDisassocRsp->statusCode; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_LOSTLINK, eCSR_ROAM_RESULT_FORCED); + } + } + } + break; + case eWNI_SME_LOST_LINK_PARAMS_IND: + { + tpSirSmeLostLinkParamsInd pLostLinkParamsInd = (tpSirSmeLostLinkParamsInd)pSirMsg; + tCsrRoamInfo roamInfo, *pRoamInfo = NULL; + eCsrRoamResult result = eCSR_ROAM_RESULT_NONE; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.u.pLostLinkParams = &pLostLinkParamsInd->info; + pRoamInfo = &roamInfo; + csrRoamCallCallback(pMac, pLostLinkParamsInd->sessionId, + pRoamInfo, 0, eCSR_ROAM_LOST_LINK_PARAMS_IND, result); + break; + } + case eWNI_SME_MIC_FAILURE_IND: + { + tpSirSmeMicFailureInd pMicInd = (tpSirSmeMicFailureInd)pSirMsg; + tCsrRoamInfo roamInfo, *pRoamInfo = NULL; + eCsrRoamResult result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; + + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pMicInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.u.pMICFailureInfo = &pMicInd->info; + pRoamInfo = &roamInfo; + if(pMicInd->info.multicast) + { + result = eCSR_ROAM_RESULT_MIC_ERROR_GROUP; + } + else + { + result = eCSR_ROAM_RESULT_MIC_ERROR_UNICAST; + } + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_MIC_ERROR_IND, result); + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + vos_mem_set(&secEvent, sizeof(vos_event_wlan_security_payload_type), 0); + secEvent.eventId = WLAN_SECURITY_EVENT_MIC_ERROR; + secEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + secEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + secEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + vos_mem_copy(secEvent.bssid, + pSession->connectedProfile.bssid, 6); + WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); + } +#endif//FEATURE_WLAN_DIAG_SUPPORT_CSR + } + break; + case eWNI_SME_WPS_PBC_PROBE_REQ_IND: + { + tpSirSmeProbeReqInd pProbeReqInd = (tpSirSmeProbeReqInd)pSirMsg; + tCsrRoamInfo roamInfo; + smsLog( pMac, LOG1, FL("WPS PBC Probe request Indication from SME")); + + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pProbeReqInd->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.u.pWPSPBCProbeReq = &pProbeReqInd->WPSPBCProbeReq; + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_WPS_PBC_PROBE_REQ_IND, + eCSR_ROAM_RESULT_WPS_PBC_PROBE_REQ_IND); + } + } + break; + + case eWNI_SME_WM_STATUS_CHANGE_NTF: + pStatusChangeMsg = (tSirSmeWmStatusChangeNtf *)pSirMsg; + switch( pStatusChangeMsg->statusChangeCode ) + { + case eSIR_SME_IBSS_ACTIVE: + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED; + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&roamInfo.bssid, + pSession->pConnectBssDesc->bssId, + sizeof(tCsrBssid)); + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + pRoamInfo = &roamInfo; + } + else + { + smsLog(pMac, LOGE, " CSR eSIR_SME_IBSS_NEW_PEER connected BSS is empty"); + } + result = eCSR_ROAM_RESULT_IBSS_CONNECT; + roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; + } + break; + case eSIR_SME_IBSS_INACTIVE: + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + pSession->connectState = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED; + result = eCSR_ROAM_RESULT_IBSS_INACTIVE; + roamStatus = eCSR_ROAM_CONNECT_STATUS_UPDATE; + } + break; + case eSIR_SME_JOINED_NEW_BSS: // IBSS coalescing. + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + // update the connection state information + pNewBss = &pStatusChangeMsg->statusChangeInfo.newBssInfo; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + tANI_U32 bi; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_COALESCING; + if(pNewBss) + { + vos_mem_copy(pIbssLog->bssid, pNewBss->bssId, 6); + if(pNewBss->ssId.length) + { + vos_mem_copy(pIbssLog->ssid, pNewBss->ssId.ssId, + pNewBss->ssId.length); + } + pIbssLog->operatingChannel = pNewBss->channelNumber; + } + if(HAL_STATUS_SUCCESS(ccmCfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &bi))) + { + //***U8 is not enough for beacon interval + pIbssLog->beaconInterval = (v_U8_t)bi; + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + csrRoamUpdateConnectedProfileFromNewBss( pMac, sessionId, pNewBss ); + + if ((eCSR_ENCRYPT_TYPE_NONE == + pSession->connectedProfile.EncryptionType )) + { + csrRoamIssueSetContextReq( pMac, sessionId, + pSession->connectedProfile.EncryptionType, + pSession->pConnectBssDesc, + &Broadcastaddr, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0 ); + } + result = eCSR_ROAM_RESULT_IBSS_COALESCED; + roamStatus = eCSR_ROAM_IBSS_IND; + vos_mem_copy(&roamInfo.bssid, &pNewBss->bssId, + sizeof(tCsrBssid)); + pRoamInfo = &roamInfo; + //This BSSID is th ereal BSSID, let's save it + if(pSession->pConnectBssDesc) + { + vos_mem_copy(pSession->pConnectBssDesc->bssId, + &pNewBss->bssId, sizeof(tCsrBssid)); + } + } + smsLog(pMac, LOGW, "CSR: eSIR_SME_JOINED_NEW_BSS received from PE"); + break; + // detection by LIM that the capabilities of the associated AP have changed. + case eSIR_SME_AP_CAPS_CHANGED: + pApNewCaps = &pStatusChangeMsg->statusChangeInfo.apNewCaps; + smsLog(pMac, LOGW, "CSR handling eSIR_SME_AP_CAPS_CHANGED"); + status = csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid *)pApNewCaps->bssId, &sessionId ); + if( HAL_STATUS_SUCCESS( status ) ) + { + if ((eCSR_ROAMING_STATE_JOINED == pMac->roam.curState[sessionId]) && + ((eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC == pMac->roam.curSubState[sessionId]) || + (eCSR_ROAM_SUBSTATE_NONE == pMac->roam.curSubState[sessionId]) || + (eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC == pMac->roam.curSubState[sessionId]) || + (eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC == pMac->roam.curSubState[sessionId])) + ) + { + smsLog(pMac, LOGW, "Calling csrRoamDisconnectInternal"); + csrRoamDisconnectInternal(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + else + { + smsLog(pMac, LOGW, + FL("Skipping csrScanForCapabilityChange as " + "CSR is in state %s and sub-state %s"), + macTraceGetcsrRoamState( + pMac->roam.curState[sessionId]), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[sessionId])); + /* We ignore the caps change event if CSR is not in full connected state. + * Send one event to PE to reset limSentCapsChangeNtf + * Once limSentCapsChangeNtf set 0, lim can send sub sequent CAPS change event + * otherwise lim cannot send any CAPS change events to SME */ + csrSendResetApCapsChanged(pMac, &pApNewCaps->bssId); + } + } + break; + + default: + roamStatus = eCSR_ROAM_FAILED; + result = eCSR_ROAM_RESULT_NONE; + break; + } // end switch on statusChangeCode + if(eCSR_ROAM_RESULT_NONE != result) + { + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, roamStatus, result); + } + break; + case eWNI_SME_IBSS_NEW_PEER_IND: + pIbssPeerInd = (tSmeIbssPeerInd *)pSirMsg; +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_JOIN; + vos_mem_copy(pIbssLog->peerMacAddr, &pIbssPeerInd->peerAddr, 6); + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + // Issue the set Context request to LIM to establish the Unicast STA context for the new peer... + if(pSession->pConnectBssDesc) + { + vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr, + sizeof(tCsrBssid)); + vos_mem_copy(&roamInfo.bssid, pSession->pConnectBssDesc->bssId, + sizeof(tCsrBssid)); + if(pIbssPeerInd->mesgLen > sizeof(tSmeIbssPeerInd)) + { + roamInfo.pbFrames = vos_mem_malloc((pIbssPeerInd->mesgLen + - sizeof(tSmeIbssPeerInd))); + if ( NULL == roamInfo.pbFrames ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + roamInfo.nBeaconLength = (pIbssPeerInd->mesgLen - sizeof(tSmeIbssPeerInd)); + vos_mem_copy(roamInfo.pbFrames, + ((tANI_U8 *)pIbssPeerInd) + sizeof(tSmeIbssPeerInd), + roamInfo.nBeaconLength); + } + roamInfo.staId = (tANI_U8)pIbssPeerInd->staId; + roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig; + roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig; + roamInfo.pBssDesc = vos_mem_malloc(pSession->pConnectBssDesc->length); + if ( NULL == roamInfo.pBssDesc ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(roamInfo.pBssDesc, + pSession->pConnectBssDesc, + pSession->pConnectBssDesc->length); + } + if(HAL_STATUS_SUCCESS(status)) + { + pRoamInfo = &roamInfo; + } + else + { + if(roamInfo.pbFrames) + { + vos_mem_free(roamInfo.pbFrames); + } + if(roamInfo.pBssDesc) + { + vos_mem_free(roamInfo.pBssDesc); + } + } + } + else + { + pRoamInfo = &roamInfo; + } + if ((eCSR_ENCRYPT_TYPE_NONE == + pSession->connectedProfile.EncryptionType )) + { + csrRoamIssueSetContextReq( pMac, sessionId, + pSession->connectedProfile.EncryptionType, + pSession->pConnectBssDesc, + &(pIbssPeerInd->peerAddr), + FALSE, TRUE, eSIR_TX_RX, 0, 0, NULL, 0 ); // NO keys... these key parameters don't matter. + } + } + else + { + smsLog(pMac, LOGW, " CSR eSIR_SME_IBSS_NEW_PEER connected BSS is empty"); + } + //send up the sec type for the new peer + if (pRoamInfo) + { + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + } + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, eCSR_ROAM_RESULT_IBSS_NEW_PEER); + if(pRoamInfo) + { + if(roamInfo.pbFrames) + { + vos_mem_free(roamInfo.pbFrames); + } + if(roamInfo.pBssDesc) + { + vos_mem_free(roamInfo.pBssDesc); + } + } + } + break; + case eWNI_SME_IBSS_PEER_DEPARTED_IND: + pIbssPeerInd = (tSmeIbssPeerInd*)pSirMsg; + sessionId = csrFindIbssSession( pMac ); + if( CSR_SESSION_ID_INVALID != sessionId ) + { +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_PEER_LEAVE; + if(pIbssPeerInd) + { + vos_mem_copy(pIbssLog->peerMacAddr, + &pIbssPeerInd->peerAddr, 6); + } + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + smsLog(pMac, LOGW, "CSR: Peer departed notification from LIM"); + roamInfo.staId = (tANI_U8)pIbssPeerInd->staId; + roamInfo.ucastSig = (tANI_U8)pIbssPeerInd->ucastSig; + roamInfo.bcastSig = (tANI_U8)pIbssPeerInd->bcastSig; + vos_mem_copy(&roamInfo.peerMac, pIbssPeerInd->peerAddr, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_CONNECT_STATUS_UPDATE, eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED); + } + break; + case eWNI_SME_SETCONTEXT_RSP: + { + tSirSmeSetContextRsp *pRsp = (tSirSmeSetContextRsp *)pSirMsg; + tListElem *pEntry; + tSmeCmd *pCommand; + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandSetKey == pCommand->command ) + { + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + if(eCSR_ENCRYPT_TYPE_NONE != pSession->connectedProfile.EncryptionType) + { + WLAN_VOS_DIAG_EVENT_DEF(setKeyEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&setKeyEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + if( pRsp->peerMacAddr[0] & 0x01 ) + { + setKeyEvent.eventId = + WLAN_SECURITY_EVENT_SET_BCAST_RSP; + } + else + { + setKeyEvent.eventId = + WLAN_SECURITY_EVENT_SET_UNICAST_RSP; + } + if( pRsp->peerMacAddr[0] & 0x01 ) + { + pMac->pmc.full_power_till_set_key = false; + smsLog(pMac, LOG1, FL("Reset full_power_till_set_key to allow BMPS")); + } + setKeyEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + setKeyEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(setKeyEvent.bssid, + pSession->connectedProfile.bssid, 6); + setKeyEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + if( eSIR_SME_SUCCESS != pRsp->statusCode ) + { + setKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + } + WLAN_VOS_DIAG_EVENT_REPORT(&setKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( CSR_IS_WAIT_FOR_KEY( pMac, sessionId) ) + { + csrRoamStopWaitForKeyTimer( pMac ); + + //We are done with authentication, whethere succeed or not + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_NONE, sessionId); + //We do it here because this linkup function is not called after association + //when a key needs to be set. + if( csrIsConnStateConnectedInfra(pMac, sessionId) ) + { + csrRoamLinkUp(pMac, pSession->connectedProfile.bssid); + } + } + if( eSIR_SME_SUCCESS == pRsp->statusCode ) + { + vos_mem_copy(&roamInfo.peerMac, + &pRsp->peerMacAddr, sizeof(tCsrBssid)); + //Make sure we install the GTK before indicating to HDD as authenticated + //This is to prevent broadcast packets go out after PTK and before GTK. + if ( vos_mem_compare( &Broadcastaddr, pRsp->peerMacAddr, + sizeof(tSirMacAddr) ) ) + { +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + tpSirSetActiveModeSetBncFilterReq pMsg; + pMsg = vos_mem_malloc(sizeof(tSirSetActiveModeSetBncFilterReq)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, FL("vos_mem_malloc failed")); + return; + } + + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SET_BCN_FILTER_REQ); + pMsg->length = pal_cpu_to_be16(sizeof( + tSirSetActiveModeSetBncFilterReq)); + pMsg->seesionId = sessionId; + vos_mem_copy(pMsg->bssid, + pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg ); + } +#endif + /* OBSS SCAN Indication will be sent to Firmware to start OBSS Scan */ + if( CSR_IS_CHANNEL_24GHZ(pSession->connectedProfile.operationChannel) + && IS_HT40_OBSS_SCAN_FEATURE_ENABLE + && (pSession->connectState == + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED) + && pSession->pCurRoamProfile + && (VOS_P2P_GO_MODE != + pSession->pCurRoamProfile->csrPersona + && VOS_STA_SAP_MODE != + pSession->pCurRoamProfile->csrPersona)) + { + tpSirSmeHT40OBSSScanInd pMsg; + pMsg = vos_mem_malloc(sizeof(tSirSmeHT40OBSSScanInd)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, FL("vos_mem_malloc failed")); + return; + } + + pMsg->messageType = + pal_cpu_to_be16((tANI_U16)eWNI_SME_HT40_OBSS_SCAN_IND); + pMsg->length = + pal_cpu_to_be16(sizeof( tSirSmeHT40OBSSScanInd)); + vos_mem_copy(pMsg->peerMacAddr, + pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, + pMsg ); + } + else + { + smsLog( pMac, LOG1,FL("OBSS SCAN" + "Indication not sent to FW" + "channel %d OBSS_SCAN: %d"), + pSession->connectedProfile. + operationChannel, + IS_HT40_OBSS_SCAN_FEATURE_ENABLE); + smsLog( pMac, LOG1,FL("connectState %d" + "pCurRoamProfile %p"), + pSession->connectState, + pSession->pCurRoamProfile); + } + + result = eCSR_ROAM_RESULT_AUTHENTICATED; + } + else + { + result = eCSR_ROAM_RESULT_NONE; + } + pRoamInfo = &roamInfo; + } + else + { + result = eCSR_ROAM_RESULT_FAILURE; + smsLog(pMac, LOGE, "CSR: Roam Completion setkey " + "command failed(%d) PeerMac "MAC_ADDRESS_STR, + pRsp->statusCode, MAC_ADDR_ARRAY(pRsp->peerMacAddr)); + } + roamInfo.is11rAssoc = csrRoamIs11rAssoc(pMac); + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.setKeyCmd.roamId, + eCSR_ROAM_SET_KEY_COMPLETE, result); + // Indicate SME_QOS that the SET_KEY is completed, so that SME_QOS + // can go ahead and initiate the TSPEC if any are pending + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_SET_KEY_SUCCESS_IND, NULL); +#ifdef FEATURE_WLAN_ESE + //Send Adjacent AP repot to new AP. + if (result == eCSR_ROAM_RESULT_AUTHENTICATED && + pSession->isPrevApInfoValid && + pSession->connectedProfile.isESEAssoc) + { +#ifdef FEATURE_WLAN_ESE_UPLOAD + csrSendEseAdjacentApRepInd(pMac, pSession); +#else + csrEseSendAdjacentApRepMsg(pMac, pSession); +#endif + pSession->isPrevApInfoValid = FALSE; + } +#endif + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandSetKey( pMac, pCommand ); + } + } + else + { + smsLog( pMac, LOGE, "CSR: Roam Completion called but setkey command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGE, "CSR: SetKey Completion called but NO commands are ACTIVE ..." ); + } + smeProcessPendingQueue( pMac ); + } + break; + case eWNI_SME_REMOVEKEY_RSP: + { + tSirSmeRemoveKeyRsp *pRsp = (tSirSmeRemoveKeyRsp *)pSirMsg; + tListElem *pEntry; + tSmeCmd *pCommand; + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandRemoveKey == pCommand->command ) + { + sessionId = pCommand->sessionId; + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(removeKeyEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&removeKeyEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + removeKeyEvent.eventId = WLAN_SECURITY_EVENT_REMOVE_KEY_RSP; + removeKeyEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + removeKeyEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy( removeKeyEvent.bssid, + pSession->connectedProfile.bssid, 6); + removeKeyEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + if( eSIR_SME_SUCCESS != pRsp->statusCode ) + { + removeKeyEvent.status = WLAN_SECURITY_STATUS_FAILURE; + } + WLAN_VOS_DIAG_EVENT_REPORT(&removeKeyEvent, EVENT_WLAN_SECURITY); + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + if( eSIR_SME_SUCCESS == pRsp->statusCode ) + { + vos_mem_copy(&roamInfo.peerMac, &pRsp->peerMacAddr, + sizeof(tCsrBssid)); + result = eCSR_ROAM_RESULT_NONE; + pRoamInfo = &roamInfo; + } + else + { + result = eCSR_ROAM_RESULT_FAILURE; + } + csrRoamCallCallback(pMac, sessionId, &roamInfo, pCommand->u.setKeyCmd.roamId, + eCSR_ROAM_REMOVE_KEY_COMPLETE, result); + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRemoveKey( pMac, pCommand ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: Roam Completion called but setkey command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: SetKey Completion called but NO commands are ACTIVE ..." ); + } + smeProcessPendingQueue( pMac ); + } + break; + case eWNI_SME_GET_STATISTICS_RSP: + smsLog( pMac, LOG2, FL("Stats rsp from PE")); + csrRoamStatsRspProcessor( pMac, pSirMsg ); + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case eWNI_SME_GET_ROAM_RSSI_RSP: + smsLog( pMac, LOG2, FL("Stats rsp from PE")); + csrRoamRssiRspProcessor( pMac, pSirMsg ); + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_GET_TSM_STATS_RSP: + smsLog( pMac, LOG2, FL("TSM Stats rsp from PE")); + csrTsmStatsRspProcessor( pMac, pSirMsg ); + break; +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + case eWNI_SME_GET_RSSI_REQ: + smsLog( pMac, LOG2, FL("GetRssiReq from self")); + csrUpdateRssi( pMac, pSirMsg ); + break; + + case eWNI_SME_GET_SNR_REQ: + smsLog( pMac, LOG2, FL("GetSnrReq from self")); + csrUpdateSnr(pMac, pSirMsg); + break; + +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_PRE_AUTH_RSP: + csrRoamFTPreAuthRspProcessor( pMac, (tpSirFTPreAuthRsp)pSirMsg ); + break; +#endif +#ifdef WLAN_FEATURE_LFR_MBB + case eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP: + csr_roam_preauth_rsp_mbb_processor(pMac, + (tpSirFTPreAuthRsp)pSirMsg); + break; +#endif + + case eWNI_SME_MAX_ASSOC_EXCEEDED: + pSmeMaxAssocInd = (tSmeMaxAssocInd*)pSirMsg; + smsLog( pMac, LOG1, FL("send indication that max assoc have been reached and the new peer cannot be accepted")); + sessionId = pSmeMaxAssocInd->sessionId; + roamInfo.sessionId = sessionId; + vos_mem_copy(&roamInfo.peerMac, pSmeMaxAssocInd->peerMac, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_INFRA_IND, eCSR_ROAM_RESULT_MAX_ASSOC_EXCEEDED); + break; + + case eWNI_SME_BTAMP_LOG_LINK_IND: + smsLog( pMac, LOG1, FL("Establish logical link req from HCI serialized through MC thread")); + btampEstablishLogLinkHdlr( pSirMsg ); + break; + case eWNI_SME_RSSI_IND: + smsLog( pMac, LOG1, FL("RSSI indication from TL serialized through MC thread")); + csrRoamRssiIndHdlr( pMac, pSirMsg ); + break; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eWNI_SME_CANDIDATE_FOUND_IND: + smsLog( pMac, LOG2, FL("Candidate found indication from PE")); + csrNeighborRoamCandidateFoundIndHdlr( pMac, pSirMsg ); + break; + case eWNI_SME_HANDOFF_REQ: + smsLog( pMac, LOG2, FL("Handoff Req from self")); + csrNeighborRoamHandoffReqHdlr( pMac, pSirMsg ); + break; +#endif + + default: + break; + } // end switch on message type +} + +void csrCallRoamingCompletionCallback(tpAniSirGlobal pMac, tCsrRoamSession *pSession, + tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, eCsrRoamResult roamResult) +{ + if(pSession) + { + if(pSession->bRefAssocStartCnt) + { + pSession->bRefAssocStartCnt--; + VOS_ASSERT( pSession->bRefAssocStartCnt == 0); + //Need to call association_completion because there is an assoc_start pending. + csrRoamCallCallback(pMac, pSession->sessionId, NULL, roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_FAILURE); + } + csrRoamCallCallback(pMac, pSession->sessionId, pRoamInfo, roamId, eCSR_ROAM_ROAMING_COMPLETION, roamResult); + } + else + { + smsLog(pMac, LOGW, FL(" pSession is NULL")); + } +} + + +eHalStatus csrRoamStartRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamingReason roamingReason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + if(CSR_IS_LOSTLINK_ROAMING(roamingReason) && + (eANI_BOOLEAN_FALSE == pMac->roam.roamSession[sessionId].fCancelRoaming)) + { + status = csrScanRequestLostLink1( pMac, sessionId ); + } + return(status); +} + +//return a boolean to indicate whether roaming completed or continue. +tANI_BOOLEAN csrRoamCompleteRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fForce, eCsrRoamResult roamResult) +{ + tANI_BOOLEAN fCompleted = eANI_BOOLEAN_TRUE; + tANI_TIMESTAMP roamTime = (tANI_TIMESTAMP)(pMac->roam.configParam.nRoamingTime * PAL_TICKS_PER_SECOND); + tANI_TIMESTAMP curTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eANI_BOOLEAN_FALSE; + } + //Check whether time is up + if(pSession->fCancelRoaming || fForce || + ((curTime - pSession->roamingStartTime) > roamTime) || + eCsrReassocRoaming == pSession->roamingReason || + eCsrDynamicRoaming == pSession->roamingReason) + { + smsLog(pMac, LOGW, FL(" indicates roaming completion")); + if(pSession->fCancelRoaming && CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason)) + { + //roaming is cancelled, tell HDD to indicate disconnect + //Because LIM overload deauth_ind for both deauth frame and missed beacon + //we need to use this logic to detinguish it. For missed beacon, LIM set reason + //to be eSIR_BEACON_MISSED + if(eSIR_BEACON_MISSED == pSession->roamingStatusCode) + { + roamResult = eCSR_ROAM_RESULT_LOSTLINK; + } + else if(eCsrLostlinkRoamingDisassoc == pSession->roamingReason) + { + roamResult = eCSR_ROAM_RESULT_DISASSOC_IND; + } + else if(eCsrLostlinkRoamingDeauth == pSession->roamingReason) + { + roamResult = eCSR_ROAM_RESULT_DEAUTH_IND; + } + else + { + roamResult = eCSR_ROAM_RESULT_LOSTLINK; + } + } + csrCallRoamingCompletionCallback(pMac, pSession, NULL, 0, roamResult); + pSession->roamingReason = eCsrNotRoaming; + } + else + { + pSession->roamResult = roamResult; + if(!HAL_STATUS_SUCCESS(csrRoamStartRoamingTimer(pMac, sessionId, PAL_TIMER_TO_SEC_UNIT))) + { + csrCallRoamingCompletionCallback(pMac, pSession, NULL, 0, roamResult); + pSession->roamingReason = eCsrNotRoaming; + } + else + { + fCompleted = eANI_BOOLEAN_FALSE; + } + } + return(fCompleted); +} + +void csrRoamCancelRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(CSR_IS_ROAMING(pSession)) + { + smsLog(pMac, LOGW, " Cancelling roaming"); + pSession->fCancelRoaming = eANI_BOOLEAN_TRUE; + if(CSR_IS_ROAM_JOINING(pMac, sessionId) && CSR_IS_ROAM_SUBSTATE_CONFIG(pMac, sessionId)) + { + //No need to do anything in here because the handler takes care of it + } + else + { + eCsrRoamResult roamResult = CSR_IS_LOSTLINK_ROAMING(pSession->roamingReason) ? + eCSR_ROAM_RESULT_LOSTLINK : eCSR_ROAM_RESULT_NONE; + //Roaming is stopped after here + csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_TRUE, roamResult); + //Since CSR may be in lostlink roaming situation, abort all roaming related activities + csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT); + csrRoamStopRoamingTimer(pMac, sessionId); + } + } +} + +void csrRoamRoamingTimerHandler(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tANI_U32 sessionId = pInfo->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(eANI_BOOLEAN_FALSE == pSession->fCancelRoaming) + { + if(!HAL_STATUS_SUCCESS(csrRoamStartRoaming(pMac, sessionId, pSession->roamingReason))) + { + csrCallRoamingCompletionCallback(pMac, pSession, NULL, 0, pSession->roamResult); + pSession->roamingReason = eCsrNotRoaming; + } + } +} + +eHalStatus csrRoamStartRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval) +{ + eHalStatus status; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found"), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG1, " csrScanStartRoamingTimer"); + pSession->roamingTimerInfo.sessionId = (tANI_U8)sessionId; + status = vos_timer_start(&pSession->hTimerRoaming, interval/PAL_TIMER_TO_MS_UNIT); + + return (status); +} + +eHalStatus csrRoamStopRoamingTimer(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (vos_timer_stop(&pMac->roam.roamSession[sessionId].hTimerRoaming)); +} + +void csrRoamWaitForKeyTimeOutHandler(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pInfo->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + smsLog(pMac, LOGE, FL("WaitForKey timer expired in state=%s sub-state=%s"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pInfo->sessionId])); + + if (pSession) + { + if( CSR_IS_WAIT_FOR_KEY( pMac, pInfo->sessionId ) ) + { +#ifdef FEATURE_WLAN_LFR + if (csrNeighborRoamIsHandoffInProgress(pMac)) + { + /* + * Enable heartbeat timer when hand-off is in progress + * and Key Wait timer expired. + */ + smsLog(pMac, LOG2, "Enabling HB timer after WaitKey expiry" + " (nHBCount=%d)", + pMac->roam.configParam.HeartbeatThresh24); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, + pMac->roam.configParam.HeartbeatThresh24, + NULL, eANI_BOOLEAN_FALSE); + } +#endif + smsLog(pMac, LOGE, " SME pre-auth state timeout. "); + + //Change the substate so command queue is unblocked. + if (CSR_ROAM_SESSION_MAX > pInfo->sessionId) + { + csrRoamSubstateChange(pMac, eCSR_ROAM_SUBSTATE_NONE, + pInfo->sessionId); + } + + if( csrIsConnStateConnectedInfra(pMac, pInfo->sessionId) ) + { + csrRoamLinkUp(pMac, pSession->connectedProfile.bssid); + smeProcessPendingQueue(pMac); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + csrRoamDisconnect(pMac, pInfo->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); + sme_ReleaseGlobalLock(&pMac->sme); + } + } + else + { + smsLog(pMac, LOGE, FL("Session id %d is disconnected"), + pInfo->sessionId); + } + } + else + { + smsLog(pMac, LOGW, "%s: session not found", __func__); + } + } + +} + +eHalStatus csrRoamStartWaitForKeyTimer(tpAniSirGlobal pMac, tANI_U32 interval) +{ + eHalStatus status; +#ifdef FEATURE_WLAN_LFR + if (csrNeighborRoamIsHandoffInProgress(pMac)) + { + /* Disable heartbeat timer when hand-off is in progress */ + smsLog(pMac, LOG2, FL("disabling HB timer in state=%s sub-state=%s"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pMac->roam.WaitForKeyTimerInfo.sessionId] + )); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE); + } +#endif + smsLog(pMac, LOG1, " csrScanStartWaitForKeyTimer"); + status = vos_timer_start(&pMac->roam.hTimerWaitForKey, interval/PAL_TIMER_TO_MS_UNIT); + + return (status); +} + +eHalStatus csrRoamStopWaitForKeyTimer(tpAniSirGlobal pMac) +{ + smsLog(pMac, LOG2, FL("WaitForKey timer stopped in state=%s sub-state=%s"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pMac->roam.WaitForKeyTimerInfo.sessionId])); +#ifdef FEATURE_WLAN_LFR + if (csrNeighborRoamIsHandoffInProgress(pMac)) + { + /* + * Enable heartbeat timer when hand-off is in progress + * and Key Wait timer got stopped for some reason + */ + smsLog(pMac, LOG2, "Enabling HB timer after WaitKey stop" + " (nHBCount=%d)", + pMac->roam.configParam.HeartbeatThresh24); + ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, + pMac->roam.configParam.HeartbeatThresh24, + NULL, eANI_BOOLEAN_FALSE); + } +#endif + return (vos_timer_stop(&pMac->roam.hTimerWaitForKey)); +} + +void csrRoamCompletion(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand, + eCsrRoamResult roamResult, tANI_BOOLEAN fSuccess) +{ + eRoamCmdStatus roamStatus = csrGetRoamCompleteStatus(pMac, sessionId); + tANI_U32 roamId = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + /* To silence the KW tool Null chaeck is added */ + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if(pCommand) + { + roamId = pCommand->u.roamCmd.roamId; + VOS_ASSERT( sessionId == pCommand->sessionId ); + } + if(eCSR_ROAM_ROAMING_COMPLETION == roamStatus) + { + //if success, force roaming completion + csrRoamCompleteRoaming(pMac, sessionId, fSuccess, roamResult); + } + else + { + VOS_ASSERT(pSession->bRefAssocStartCnt == 0); + smsLog(pMac, LOGW, FL(" indicates association completion. roamResult = %d"), roamResult); + csrRoamCallCallback(pMac, sessionId, pRoamInfo, roamId, roamStatus, roamResult); + } +} + +eHalStatus csrRoamLostLink( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 type, tSirSmeRsp *pSirMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDeauthInd *pDeauthIndMsg = NULL; + tSirSmeDisassocInd *pDisassocIndMsg = NULL; + eCsrRoamResult result = eCSR_ROAM_RESULT_LOSTLINK; + tCsrRoamInfo *pRoamInfo = NULL; + tCsrRoamInfo roamInfo; + tANI_BOOLEAN fToRoam; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + /* To silence the KW tool Null chaeck is added */ + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + //Only need to roam for infra station. In this case P2P client will roam as well + fToRoam = CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile); + pSession->fCancelRoaming = eANI_BOOLEAN_FALSE; + if ( eWNI_SME_DISASSOC_IND == type ) + { + result = eCSR_ROAM_RESULT_DISASSOC_IND; + pDisassocIndMsg = (tSirSmeDisassocInd *)pSirMsg; + pSession->roamingStatusCode = pDisassocIndMsg->statusCode; + pSession->joinFailStatusCode.reasonCode = pDisassocIndMsg->reasonCode; + } + else if ( eWNI_SME_DEAUTH_IND == type ) + { + result = eCSR_ROAM_RESULT_DEAUTH_IND; + pDeauthIndMsg = (tSirSmeDeauthInd *)pSirMsg; + pSession->roamingStatusCode = pDeauthIndMsg->statusCode; + pSession->joinFailStatusCode.reasonCode = pDeauthIndMsg->reasonCode; + } + else + { + smsLog(pMac, LOGW, FL("gets an unknown type (%d)"), type); + result = eCSR_ROAM_RESULT_NONE; + pSession->joinFailStatusCode.reasonCode = 1; + } + + // call profile lost link routine here + if(!CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_LOSTLINK_DETECTED, result); + } + + if ( eWNI_SME_DISASSOC_IND == type ) + { + status = csrSendMBDisassocCnfMsg(pMac, pDisassocIndMsg); + } + else if ( eWNI_SME_DEAUTH_IND == type ) + { + status = csrSendMBDeauthCnfMsg(pMac, pDeauthIndMsg); + } + if(!HAL_STATUS_SUCCESS(status)) + { + //If fail to send confirmation to PE, not to trigger roaming + fToRoam = eANI_BOOLEAN_FALSE; + } + + //prepare to tell HDD to disconnect + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + roamInfo.statusCode = (tSirResultCodes)pSession->roamingStatusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + if( eWNI_SME_DISASSOC_IND == type) + { + //staMacAddr + vos_mem_copy(roamInfo.peerMac, pDisassocIndMsg->peerMacAddr, + sizeof(tSirMacAddr)); + roamInfo.staId = (tANI_U8)pDisassocIndMsg->staId; + } + else if( eWNI_SME_DEAUTH_IND == type ) + { + //staMacAddr + vos_mem_copy(roamInfo.peerMac, pDeauthIndMsg->peerMacAddr, + sizeof(tSirMacAddr)); + roamInfo.staId = (tANI_U8)pDeauthIndMsg->staId; + } + smsLog(pMac, LOGW, FL("roamInfo.staId (%d)"), roamInfo.staId); + + /* See if we can possibly roam. If so, start the roaming process and notify HDD + that we are roaming. But if we cannot possibly roam, or if we are unable to + currently roam, then notify HDD of the lost link */ + if(fToRoam) + { + //Only remove the connected BSS in infrastructure mode + csrRoamRemoveConnectedBssFromScanCache(pMac, &pSession->connectedProfile); + //Not to do anying for lostlink with WDS + if( pMac->roam.configParam.nRoamingTime ) + { + if(HAL_STATUS_SUCCESS(status = csrRoamStartRoaming(pMac, sessionId, + ( eWNI_SME_DEAUTH_IND == type ) ? + eCsrLostlinkRoamingDeauth : eCsrLostlinkRoamingDisassoc))) + { + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + //For IBSS, we need to give some more info to HDD + if(csrIsBssTypeIBSS(pSession->connectedProfile.BSSType)) + { + roamInfo.u.pConnectedProfile = &pSession->connectedProfile; + roamInfo.statusCode = (tSirResultCodes)pSession->roamingStatusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + } + else + { + roamInfo.reasonCode = eCsrRoamReasonSmeIssuedForLostLink; + } + pRoamInfo = &roamInfo; + pSession->roamingReason = ( eWNI_SME_DEAUTH_IND == type ) ? + eCsrLostlinkRoamingDeauth : eCsrLostlinkRoamingDisassoc; + pSession->roamingStartTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd); + csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_LOSTLINK); + } + else + { + smsLog(pMac, LOGW, " %s Fail to start roaming, status = %d", __func__, status); + fToRoam = eANI_BOOLEAN_FALSE; + } + } + else + { + //We are told not to roam, indicate lostlink + fToRoam = eANI_BOOLEAN_FALSE; + } + } + if(!fToRoam) + { + /*No need to start idle scan in case of IBSS/SAP + Still enable idle scan for polling in case concurrent sessions are running */ + if(CSR_IS_INFRASTRUCTURE(&pSession->connectedProfile)) + { + csrScanStartIdleScan(pMac); + } + } + + return (status); +} + +eHalStatus csrRoamLostLinkAfterhandoffFailure( tpAniSirGlobal pMac,tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pSession->fCancelRoaming = eANI_BOOLEAN_FALSE; + //Only remove the connected BSS in infrastructure mode + csrRoamRemoveConnectedBssFromScanCache(pMac, &pSession->connectedProfile); + if(pMac->roam.configParam.nRoamingTime) + { + if(HAL_STATUS_SUCCESS(status = csrRoamStartRoaming(pMac,sessionId, pSession->roamingReason))) + { + //before starting the lost link logic release the roam command for handoff + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + } + if(pCommand) + { + if (( eSmeCommandRoam == pCommand->command ) && + ( eCsrSmeIssuedAssocToSimilarAP == pCommand->u.roamCmd.roamReason)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRoam( pMac, pCommand ); + } + } + } + smsLog( pMac, LOGW, "Lost link roaming started ..."); + } + } + else + { + //We are told not to roam, indicate lostlink + status = eHAL_STATUS_FAILURE; + } + + return (status); +} +void csrRoamWmStatusChangeComplete( tpAniSirGlobal pMac ) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandWmStatusChange == pCommand->command ) + { + // Nothing to process in a Lost Link completion.... It just kicks off a + // roaming sequence. + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandWmStatusChange( pMac, pCommand ); + } + else + { + smsLog( pMac, LOGE, " ******csrRoamWmStatusChangeComplete fail to release command"); + } + + } + else + { + smsLog( pMac, LOGW, "CSR: WmStatusChange Completion called but LOST LINK command is not ACTIVE ..." ); + } + } + else + { + smsLog( pMac, LOGW, "CSR: WmStatusChange Completion called but NO commands are ACTIVE ..." ); + } + smeProcessPendingQueue( pMac ); +} + +void csrRoamProcessWmStatusChangeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirSmeRsp *pSirSmeMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pCommand->sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), pCommand->sessionId); + return; + } + smsLog(pMac, LOG1, FL("session:%d, CmdType : %d"), + pCommand->sessionId, + pCommand->u.wmStatusChangeCmd.Type); + switch ( pCommand->u.wmStatusChangeCmd.Type ) + { + case eCsrDisassociated: + pSirSmeMsg = (tSirSmeRsp *)&pCommand->u.wmStatusChangeCmd.u.DisassocIndMsg; + status = csrRoamLostLink(pMac, pCommand->sessionId, eWNI_SME_DISASSOC_IND, pSirSmeMsg); + break; + case eCsrDeauthenticated: + pSirSmeMsg = (tSirSmeRsp *)&pCommand->u.wmStatusChangeCmd.u.DeauthIndMsg; + status = csrRoamLostLink(pMac, pCommand->sessionId, eWNI_SME_DEAUTH_IND, pSirSmeMsg); + break; + default: + smsLog(pMac, LOGW, FL("gets an unknown command %d"), pCommand->u.wmStatusChangeCmd.Type); + break; + } + //For WDS, we want to stop BSS as well when it is indicated that it is disconnected. + if( CSR_IS_CONN_WDS(&pSession->connectedProfile) ) + { + if( !HAL_STATUS_SUCCESS(csrRoamIssueStopBssCmd( pMac, pCommand->sessionId, eANI_BOOLEAN_TRUE )) ) + { + //This is not good + smsLog(pMac, LOGE, FL(" failed to issue stopBSS command")); + } + } + // Lost Link just triggers a roaming sequence. We can complte the Lost Link + // command here since there is nothing else to do. + csrRoamWmStatusChangeComplete( pMac ); +} + +//This function returns band and mode information. +//The only tricky part is that if phyMode is set to 11abg, this function may return eCSR_CFG_DOT11_MODE_11B +//instead of eCSR_CFG_DOT11_MODE_11G if everything is set to auto-pick. +static eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tANI_U8 operationChn, eCsrBand *pBand ) +{ + eCsrPhyMode phyModeIn = (eCsrPhyMode)pProfile->phyMode; + eCsrCfgDot11Mode cfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(pProfile, phyModeIn, + pMac->roam.configParam.ProprietaryRatesEnabled); + eCsrBand eBand; + + //If the global setting for dot11Mode is set to auto/abg, we overwrite the setting in the profile. + if( ((!CSR_IS_INFRA_AP(pProfile )&& !CSR_IS_WDS(pProfile )) && + ((eCSR_CFG_DOT11_MODE_AUTO == pMac->roam.configParam.uCfgDot11Mode) || + (eCSR_CFG_DOT11_MODE_ABG == pMac->roam.configParam.uCfgDot11Mode))) || + (eCSR_CFG_DOT11_MODE_AUTO == cfgDot11Mode) || (eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode) ) + { + switch( pMac->roam.configParam.uCfgDot11Mode ) + { + case eCSR_CFG_DOT11_MODE_11A: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + eBand = eCSR_BAND_5G; + break; + case eCSR_CFG_DOT11_MODE_11B: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + eBand = eCSR_BAND_24; + break; + case eCSR_CFG_DOT11_MODE_11G: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + eBand = eCSR_BAND_24; + break; + case eCSR_CFG_DOT11_MODE_11N: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_CFG_DOT11_MODE_11AC: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* If the operating channel is in 2.4 GHz band, check for + * INI item to disable VHT operation in 2.4 GHz band + */ + if (CSR_IS_CHANNEL_24GHZ(operationChn) && + !pMac->roam.configParam.enableVhtFor24GHz) + { + /* Disable 11AC operation */ + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + break; + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* If the operating channel is in 2.4 GHz band, check for + * INI item to disable VHT operation in 2.4 GHz band + */ + if (CSR_IS_CHANNEL_24GHZ(operationChn) && + !pMac->roam.configParam.enableVhtFor24GHz) + { + /* Disable 11AC operation */ + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY; + } + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + else + { + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; +#endif + case eCSR_CFG_DOT11_MODE_AUTO: +#ifdef WLAN_FEATURE_11AC + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + /* If the operating channel is in 2.4 GHz band, check for + * INI item to disable VHT operation in 2.4 GHz band + */ + if (CSR_IS_CHANNEL_24GHZ(operationChn) && + !pMac->roam.configParam.enableVhtFor24GHz) + { + /* Disable 11AC operation */ + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; + } +#else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + eBand = CSR_IS_CHANNEL_24GHZ(operationChn) ? eCSR_BAND_24 : eCSR_BAND_5G; +#endif + break; + default: + // Global dot11 Mode setting is 11a/b/g. + // use the channel number to determine the Mode setting. + if ( eCSR_OPERATING_CHANNEL_AUTO == operationChn ) + { + eBand = pMac->roam.configParam.eBand; + if(eCSR_BAND_24 == eBand) + { + //See reason in else if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) to pick 11B + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { + //prefer 5GHz + eBand = eCSR_BAND_5G; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + } + else if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) + { + // WiFi tests require IBSS networks to start in 11b mode + // without any change to the default parameter settings + // on the adapter. We use ACU to start an IBSS through + // creation of a startIBSS profile. This startIBSS profile + // has Auto MACProtocol and the adapter property setting + // for dot11Mode is also AUTO. So in this case, let's + // start the IBSS network in 11b mode instead of 11g mode. + // So this is for Auto=profile->MacProtocol && Auto=Global. + // dot11Mode && profile->channel is < 14, then start the IBSS + // in b mode. + // + // Note: we used to have this start as an 11g IBSS for best + // performance... now to specify that the user will have to + // set the do11Mode in the property page to 11g to force it. + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + eBand = eCSR_BAND_24; + } + else + { + // else, it's a 5.0GHz channel. Set mode to 11a. + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + eBand = eCSR_BAND_5G; + } + break; + }//switch + }//if( eCSR_CFG_DOT11_MODE_ABG == cfgDot11Mode ) + else + { + //dot11 mode is set, lets pick the band + if ( eCSR_OPERATING_CHANNEL_AUTO == operationChn ) + { + // channel is Auto also. + eBand = pMac->roam.configParam.eBand; + if(eCSR_BAND_ALL == eBand) + { + //prefer 5GHz + eBand = eCSR_BAND_5G; + } + } + else if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) + { + eBand = eCSR_BAND_24; + } + else + { + eBand = eCSR_BAND_5G; + } + } + if(pBand) + { + *pBand = eBand; + } + + if (operationChn == 14){ + smsLog(pMac, LOGE, FL(" Switching to Dot11B mode ")); + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + + /* Incase of WEP Security encryption type is coming as part of add key. So while STart BSS dont have information */ + if ( +#ifdef SAP_AUTH_OFFLOAD + (!pMac->sap_auth_offload && !pMac->sap_auth_offload_sec_type) && +#endif + ((!CSR_IS_11n_ALLOWED(pProfile->EncryptionType.encryptionType[0] ) || + ((pProfile->privacy == 1) && + (pProfile->EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_NONE)))) && + ((eCSR_CFG_DOT11_MODE_11N == cfgDot11Mode) || +#ifdef WLAN_FEATURE_11AC + (eCSR_CFG_DOT11_MODE_11AC == cfgDot11Mode) || +#endif + (eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11Mode)) ) + { + //We cannot do 11n here + if ( CSR_IS_CHANNEL_24GHZ(operationChn) ) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + } + return( cfgDot11Mode ); +} + +eHalStatus csrRoamIssueStopBss( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamSubState NewSubstate ) +{ + eHalStatus status; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_STOP_REQ; + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + // Set the roaming substate to 'stop Bss request'... + csrRoamSubstateChange( pMac, NewSubstate, sessionId ); + + // attempt to stop the Bss (reason code is ignored...) + status = csrSendMBStopBssReqMsg( pMac, sessionId ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, FL("csrSendMBStopBssReqMsg failed with status %d"), status); + } + return (status); +} + +//pNumChan is a caller allocated space with the sizeof pChannels +eHalStatus csrGetCfgValidChannels(tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U32 *pNumChan) +{ + + return (ccmCfgGetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, + (tANI_U8 *)pChannels, + pNumChan)); +} + +tPowerdBm csrGetCfgMaxTxPower (tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_U32 cfgLength = 0; + tANI_U16 cfgId = 0; + tPowerdBm maxTxPwr = 0; + tANI_U8 *pCountryInfo = NULL; + eHalStatus status; + tANI_U8 count = 0; + tANI_U8 firstChannel; + tANI_U8 maxChannels; + + if (CSR_IS_CHANNEL_5GHZ(channel)) + { + cfgId = WNI_CFG_MAX_TX_POWER_5; + cfgLength = WNI_CFG_MAX_TX_POWER_5_LEN; + } + else if (CSR_IS_CHANNEL_24GHZ(channel)) + { + cfgId = WNI_CFG_MAX_TX_POWER_2_4; + cfgLength = WNI_CFG_MAX_TX_POWER_2_4_LEN; + } + else + return maxTxPwr; + + pCountryInfo = vos_mem_malloc(cfgLength); + if ( NULL == pCountryInfo ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (status != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("%s: failed to allocate memory, status = %d"), + __FUNCTION__, status); + goto error; + } + status = ccmCfgGetStr(pMac, cfgId, (tANI_U8 *)pCountryInfo, &cfgLength); + if (status != eHAL_STATUS_SUCCESS) + { + goto error; + } + /* Identify the channel and maxtxpower */ + while (count <= (cfgLength - (sizeof(tSirMacChanInfo)))) + { + firstChannel = pCountryInfo[count++]; + maxChannels = pCountryInfo[count++]; + maxTxPwr = pCountryInfo[count++]; + + if ((channel >= firstChannel) && + (channel < (firstChannel + maxChannels))) + { + break; + } + } + +error: + if (NULL != pCountryInfo) + vos_mem_free(pCountryInfo); + + return maxTxPwr; +} + + +tANI_BOOLEAN csrRoamIsChannelValid( tpAniSirGlobal pMac, tANI_U8 channel ) +{ + tANI_BOOLEAN fValid = FALSE; + tANI_U32 idxValidChannels; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len))) + { + for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ ) + { + if ( channel == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fValid = TRUE; + break; + } + } + } + pMac->roam.numValidChannels = len; + return fValid; +} + +tANI_BOOLEAN csrRoamIsValid40MhzChannel(tpAniSirGlobal pMac, tANI_U8 channel) +{ + tANI_BOOLEAN fValid = eANI_BOOLEAN_FALSE; + tANI_U8 i; + for(i = 0; i < pMac->scan.base40MHzChannels.numChannels; i++) + { + if(channel == pMac->scan.base40MHzChannels.channelList[i]) + { + fValid = eANI_BOOLEAN_TRUE; + break; + } + } + return (fValid); +} + +//This function check and validate whether the NIC can do CB (40MHz) + static ePhyChanBondState csrGetCBModeFromIes(tpAniSirGlobal pMac, tANI_U8 primaryChn, tDot11fBeaconIEs *pIes) +{ + ePhyChanBondState eRet = PHY_SINGLE_CHANNEL_CENTERED; + tANI_U8 centerChn; + tANI_U32 ChannelBondingMode; + + if(CSR_IS_CHANNEL_24GHZ(primaryChn)) + { + ChannelBondingMode = pMac->roam.configParam.channelBondingMode24GHz; + } + else + { + ChannelBondingMode = pMac->roam.configParam.channelBondingMode5GHz; + } + //Figure what the other side's CB mode + if(WNI_CFG_CHANNEL_BONDING_MODE_DISABLE != ChannelBondingMode) + { + if(pIes->HTCaps.present && (eHT_CHANNEL_WIDTH_40MHZ == pIes->HTCaps.supportedChannelWidthSet)) + { + // In Case WPA2 and TKIP is the only one cipher suite in Pairwise. + if ((pIes->RSN.present && (pIes->RSN.pwise_cipher_suite_count == 1) && + !memcmp(&(pIes->RSN.pwise_cipher_suites[0][0]), + "\x00\x0f\xac\x02",4)) + //In Case only WPA1 is supported and TKIP is the only one cipher suite in Unicast. + ||( !pIes->RSN.present && (pIes->WPA.present && (pIes->WPA.unicast_cipher_count == 1) && + !memcmp(&(pIes->WPA.unicast_ciphers[0][0]), + "\x00\x50\xf2\x02",4)))) + + { + smsLog(pMac, LOGW, " No channel bonding in TKIP mode "); + eRet = PHY_SINGLE_CHANNEL_CENTERED; + } + + else if(pIes->HTInfo.present) + { + /* This is called during INFRA STA/CLIENT and should use the merged value of + * supported channel width and recommended tx width as per standard + */ + smsLog(pMac, LOG1, "scws %u rtws %u sco %u", + pIes->HTCaps.supportedChannelWidthSet, + pIes->HTInfo.recommendedTxWidthSet, + pIes->HTInfo.secondaryChannelOffset); + + if (pIes->HTInfo.recommendedTxWidthSet == eHT_CHANNEL_WIDTH_40MHZ) + eRet = (ePhyChanBondState)pIes->HTInfo.secondaryChannelOffset; + else + eRet = PHY_SINGLE_CHANNEL_CENTERED; + switch (eRet) { + case PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + centerChn = primaryChn + CSR_CB_CENTER_CHANNEL_OFFSET; + break; + case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + centerChn = primaryChn - CSR_CB_CENTER_CHANNEL_OFFSET; + break; + case PHY_SINGLE_CHANNEL_CENTERED: + default: + centerChn = primaryChn; + break; + } + if((PHY_SINGLE_CHANNEL_CENTERED != eRet) && !csrRoamIsValid40MhzChannel(pMac, centerChn)) + { + smsLog(pMac, LOGE, " Invalid center channel (%d), disable 40MHz mode", centerChn); + eRet = PHY_SINGLE_CHANNEL_CENTERED; + } + if ((CSR_IS_CHANNEL_24GHZ(primaryChn))&& !IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + { + smsLog(pMac, LOG1,FL("FW doesn't support channelBondingMode24GHz")); + eRet = PHY_SINGLE_CHANNEL_CENTERED; + } + } + } + } + return eRet; +} +tANI_BOOLEAN csrIsEncryptionInList( tpAniSirGlobal pMac, tCsrEncryptionList *pCipherList, eCsrEncryptionType encryptionType ) +{ + tANI_BOOLEAN fFound = FALSE; + tANI_U32 idx; + for( idx = 0; idx < pCipherList->numEntries; idx++ ) + { + if( pCipherList->encryptionType[idx] == encryptionType ) + { + fFound = TRUE; + break; + } + } + return fFound; +} +tANI_BOOLEAN csrIsAuthInList( tpAniSirGlobal pMac, tCsrAuthList *pAuthList, eCsrAuthType authType ) +{ + tANI_BOOLEAN fFound = FALSE; + tANI_U32 idx; + for( idx = 0; idx < pAuthList->numEntries; idx++ ) + { + if( pAuthList->authType[idx] == authType ) + { + fFound = TRUE; + break; + } + } + return fFound; +} +tANI_BOOLEAN csrIsSameProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile1, tCsrRoamProfile *pProfile2) +{ + tANI_BOOLEAN fCheck = eANI_BOOLEAN_FALSE; + tCsrScanResultFilter *pScanFilter = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(pProfile1 && pProfile2) + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pProfile2, pScanFilter); + if(HAL_STATUS_SUCCESS(status)) + { + fCheck = eANI_BOOLEAN_FALSE; + do + { + tANI_U32 i; + for(i = 0; i < pScanFilter->SSIDs.numOfSSIDs; i++) + { + fCheck = csrIsSsidMatch( pMac, pScanFilter->SSIDs.SSIDList[i].SSID.ssId, + pScanFilter->SSIDs.SSIDList[i].SSID.length, + pProfile1->SSID.ssId, pProfile1->SSID.length, eANI_BOOLEAN_FALSE ); + if ( fCheck ) break; + } + if(!fCheck) + { + break; + } + if( !csrIsAuthInList( pMac, &pProfile2->AuthType, pProfile1->AuthType) + || pProfile2->BSSType != pProfile1->BSSType + || !csrIsEncryptionInList( pMac, &pProfile2->EncryptionType, pProfile1->EncryptionType ) + ) + { + fCheck = eANI_BOOLEAN_FALSE; + break; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pProfile1->MDID.mdiePresent || pProfile2->MDID.mdiePresent) + { + if (pProfile1->MDID.mobilityDomain != pProfile2->MDID.mobilityDomain) + { + fCheck = eANI_BOOLEAN_FALSE; + break; + } + } +#endif + //Match found + fCheck = eANI_BOOLEAN_TRUE; + }while(0); + csrFreeScanFilter(pMac, pScanFilter); + } + vos_mem_free(pScanFilter); + } + } + + return (fCheck); +} + +tANI_BOOLEAN csrRoamIsSameProfileKeys(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pConnProfile, tCsrRoamProfile *pProfile2) +{ + tANI_BOOLEAN fCheck = eANI_BOOLEAN_FALSE; + int i; + do + { + //Only check for static WEP + if(!csrIsEncryptionInList(pMac, &pProfile2->EncryptionType, eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) && + !csrIsEncryptionInList(pMac, &pProfile2->EncryptionType, eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) + { + fCheck = eANI_BOOLEAN_TRUE; + break; + } + if(!csrIsEncryptionInList(pMac, &pProfile2->EncryptionType, pConnProfile->EncryptionType)) break; + if(pConnProfile->Keys.defaultIndex != pProfile2->Keys.defaultIndex) break; + for(i = 0; i < CSR_MAX_NUM_KEY; i++) + { + if(pConnProfile->Keys.KeyLength[i] != pProfile2->Keys.KeyLength[i]) break; + if (!vos_mem_compare(&pConnProfile->Keys.KeyMaterial[i], + &pProfile2->Keys.KeyMaterial[i], pProfile2->Keys.KeyLength[i])) + { + break; + } + } + if( i == CSR_MAX_NUM_KEY) + { + fCheck = eANI_BOOLEAN_TRUE; + } + }while(0); + return (fCheck); +} + +//IBSS + +tANI_U8 csrRoamGetIbssStartChannelNumber50( tpAniSirGlobal pMac ) +{ + tANI_U8 channel = 0; + tANI_U32 idx; + tANI_U32 idxValidChannels; + tANI_BOOLEAN fFound = FALSE; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if(eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel5G) + { + channel = pMac->roam.configParam.AdHocChannel5G; + if(!csrRoamIsChannelValid(pMac, channel)) + { + channel = 0; + } + } + if (0 == channel && HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + for ( idx = 0; ( idx < CSR_NUM_IBSS_START_CHANNELS_50 ) && !fFound; idx++ ) + { + for ( idxValidChannels = 0; ( idxValidChannels < len ) && !fFound; idxValidChannels++ ) + { + if ( csrStartIbssChannels50[ idx ] == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fFound = TRUE; + channel = csrStartIbssChannels50[ idx ]; + } + } + } + // this is rare, but if it does happen, we find anyone in 11a bandwidth and return the first 11a channel found! + if (!fFound) + { + for ( idxValidChannels = 0; idxValidChannels < len ; idxValidChannels++ ) + { + if ( CSR_IS_CHANNEL_5GHZ(pMac->roam.validChannelList[ idxValidChannels ]) ) // the max channel# in 11g is 14 + { + channel = pMac->roam.validChannelList[ idxValidChannels ]; + break; + } + } + } + }//if + + return( channel ); +} + +tANI_U8 csrRoamGetIbssStartChannelNumber24( tpAniSirGlobal pMac ) +{ + tANI_U8 channel = 1; + tANI_U32 idx; + tANI_U32 idxValidChannels; + tANI_BOOLEAN fFound = FALSE; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if(eCSR_OPERATING_CHANNEL_ANY != pMac->roam.configParam.AdHocChannel24) + { + channel = pMac->roam.configParam.AdHocChannel24; + if(!csrRoamIsChannelValid(pMac, channel)) + { + channel = 0; + } + } + + if (0 == channel && HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + for ( idx = 0; ( idx < CSR_NUM_IBSS_START_CHANNELS_24 ) && !fFound; idx++ ) + { + for ( idxValidChannels = 0; ( idxValidChannels < len ) && !fFound; idxValidChannels++ ) + { + if ( csrStartIbssChannels24[ idx ] == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fFound = TRUE; + channel = csrStartIbssChannels24[ idx ]; + } + } + } + } + + return( channel ); +} + +static void csrRoamGetBssStartParms( tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, + tCsrRoamStartBssParams *pParam ) +{ + eCsrCfgDot11Mode cfgDot11Mode; + eCsrBand eBand; + tANI_U8 channel = 0; + tSirNwType nwType; + tANI_U8 operationChannel = 0; + + if(pProfile->ChannelInfo.numOfChannels && pProfile->ChannelInfo.ChannelList) + { + operationChannel = pProfile->ChannelInfo.ChannelList[0]; + } + + cfgDot11Mode = csrRoamGetPhyModeBandForBss( pMac, pProfile, operationChannel, &eBand ); + + if( ( (pProfile->csrPersona == VOS_P2P_CLIENT_MODE) || + (pProfile->csrPersona == VOS_P2P_GO_MODE) ) + && ( cfgDot11Mode == eCSR_CFG_DOT11_MODE_11B) + ) + { + /* This should never happen */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + FL("For P2PClient/P2P-GO (persona %d) cfgDot11Mode is 11B"), + pProfile->csrPersona); + VOS_ASSERT(0); + } + switch( cfgDot11Mode ) + { + case eCSR_CFG_DOT11_MODE_11G: + nwType = eSIR_11G_NW_TYPE; + break; + case eCSR_CFG_DOT11_MODE_11B: + nwType = eSIR_11B_NW_TYPE; + break; + case eCSR_CFG_DOT11_MODE_11A: + nwType = eSIR_11A_NW_TYPE; + break; + default: + case eCSR_CFG_DOT11_MODE_11N: + case eCSR_CFG_DOT11_MODE_TAURUS: + //Because LIM only verifies it against 11a, 11b or 11g, set only 11g or 11a here + if(eCSR_BAND_24 == eBand) + { + nwType = eSIR_11G_NW_TYPE; + } + else + { + nwType = eSIR_11A_NW_TYPE; + } + break; + } + + pParam->extendedRateSet.numRates = 0; + + switch ( nwType ) + { + default: + smsLog(pMac, LOGE, FL("sees an unknown pSirNwType (%d)"), nwType); + case eSIR_11A_NW_TYPE: + + pParam->operationalRateSet.numRates = 8; + + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_6 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_9; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_12 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_18; + pParam->operationalRateSet.rate[4] = SIR_MAC_RATE_24 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[5] = SIR_MAC_RATE_36; + pParam->operationalRateSet.rate[6] = SIR_MAC_RATE_48; + pParam->operationalRateSet.rate[7] = SIR_MAC_RATE_54; + + if ( eCSR_OPERATING_CHANNEL_ANY == operationChannel ) + { + channel = csrRoamGetIbssStartChannelNumber50( pMac ); + if( 0 == channel && + CSR_IS_PHY_MODE_DUAL_BAND(pProfile->phyMode) && + CSR_IS_PHY_MODE_DUAL_BAND(pMac->roam.configParam.phyMode) + ) + { + //We could not find a 5G channel by auto pick, let's try 2.4G channels + //We only do this here because csrRoamGetPhyModeBandForBss always picks 11a for AUTO + nwType = eSIR_11B_NW_TYPE; + channel = csrRoamGetIbssStartChannelNumber24( pMac ); + pParam->operationalRateSet.numRates = 4; + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_1 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_2 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_5_5 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_11 | CSR_DOT11_BASIC_RATE_MASK; + } + } + else + { + channel = operationChannel; + } + break; + + case eSIR_11B_NW_TYPE: + pParam->operationalRateSet.numRates = 4; + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_1 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_2 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_5_5 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_11 | CSR_DOT11_BASIC_RATE_MASK; + if ( eCSR_OPERATING_CHANNEL_ANY == operationChannel ) + { + channel = csrRoamGetIbssStartChannelNumber24( pMac ); + } + else + { + channel = operationChannel; + } + + break; + case eSIR_11G_NW_TYPE: + /* For P2P Client and P2P GO, disable 11b rates */ + if( (pProfile->csrPersona == VOS_P2P_CLIENT_MODE) || + (pProfile->csrPersona == VOS_P2P_GO_MODE) + ) + { + pParam->operationalRateSet.numRates = 8; + + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_6 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_9; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_12 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_18; + pParam->operationalRateSet.rate[4] = SIR_MAC_RATE_24 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[5] = SIR_MAC_RATE_36; + pParam->operationalRateSet.rate[6] = SIR_MAC_RATE_48; + pParam->operationalRateSet.rate[7] = SIR_MAC_RATE_54; + } + else + { + pParam->operationalRateSet.numRates = 4; + pParam->operationalRateSet.rate[0] = SIR_MAC_RATE_1 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[1] = SIR_MAC_RATE_2 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[2] = SIR_MAC_RATE_5_5 | CSR_DOT11_BASIC_RATE_MASK; + pParam->operationalRateSet.rate[3] = SIR_MAC_RATE_11 | CSR_DOT11_BASIC_RATE_MASK; + + pParam->extendedRateSet.numRates = 8; + pParam->extendedRateSet.rate[0] = SIR_MAC_RATE_6; + pParam->extendedRateSet.rate[1] = SIR_MAC_RATE_9; + pParam->extendedRateSet.rate[2] = SIR_MAC_RATE_12; + pParam->extendedRateSet.rate[3] = SIR_MAC_RATE_18; + pParam->extendedRateSet.rate[4] = SIR_MAC_RATE_24; + pParam->extendedRateSet.rate[5] = SIR_MAC_RATE_36; + pParam->extendedRateSet.rate[6] = SIR_MAC_RATE_48; + pParam->extendedRateSet.rate[7] = SIR_MAC_RATE_54; + } + + if ( eCSR_OPERATING_CHANNEL_ANY == operationChannel ) + { + channel = csrRoamGetIbssStartChannelNumber24( pMac ); + } + else + { + channel = operationChannel; + } + + break; + } + pParam->operationChn = channel; + pParam->sirNwType = nwType; +} + +static void csrRoamGetBssStartParmsFromBssDesc( tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes, tCsrRoamStartBssParams *pParam ) +{ + + if( pParam ) + { + pParam->sirNwType = pBssDesc->nwType; + pParam->cbMode = PHY_SINGLE_CHANNEL_CENTERED; + pParam->operationChn = pBssDesc->channelId; + vos_mem_copy(&pParam->bssid, pBssDesc->bssId, sizeof(tCsrBssid)); + + if( pIes ) + { + if(pIes->SuppRates.present) + { + pParam->operationalRateSet.numRates = pIes->SuppRates.num_rates; + if(pIes->SuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) + { + smsLog(pMac, LOGE, FL("num_rates :%d is more than SIR_MAC_RATESET_EID_MAX, resetting to SIR_MAC_RATESET_EID_MAX"), + pIes->SuppRates.num_rates); + pIes->SuppRates.num_rates = SIR_MAC_RATESET_EID_MAX; + } + vos_mem_copy(pParam->operationalRateSet.rate, pIes->SuppRates.rates, + sizeof(*pIes->SuppRates.rates) * pIes->SuppRates.num_rates); + } + if (pIes->ExtSuppRates.present) + { + pParam->extendedRateSet.numRates = pIes->ExtSuppRates.num_rates; + if(pIes->ExtSuppRates.num_rates > SIR_MAC_RATESET_EID_MAX) + { + smsLog(pMac, LOGE, FL("num_rates :%d is more than \ + SIR_MAC_RATESET_EID_MAX, resetting to \ + SIR_MAC_RATESET_EID_MAX"), + pIes->ExtSuppRates.num_rates); + pIes->ExtSuppRates.num_rates = SIR_MAC_RATESET_EID_MAX; + } + vos_mem_copy(pParam->extendedRateSet.rate, + pIes->ExtSuppRates.rates, + sizeof(*pIes->ExtSuppRates.rates) * pIes->ExtSuppRates.num_rates); + } + if( pIes->SSID.present ) + { + pParam->ssId.length = pIes->SSID.num_ssid; + vos_mem_copy(pParam->ssId.ssId, pIes->SSID.ssid, + pParam->ssId.length); + } + pParam->cbMode = csrGetCBModeFromIes(pMac, pParam->operationChn, pIes); + } + else + { + pParam->ssId.length = 0; + pParam->operationalRateSet.numRates = 0; + } + } +} + +static void csrRoamDetermineMaxRateForAdHoc( tpAniSirGlobal pMac, tSirMacRateSet *pSirRateSet ) +{ + tANI_U8 MaxRate = 0; + tANI_U32 i; + tANI_U8 *pRate; + + pRate = pSirRateSet->rate; + for ( i = 0; i < pSirRateSet->numRates; i++ ) + { + MaxRate = CSR_MAX( MaxRate, ( pRate[ i ] & (~CSR_DOT11_BASIC_RATE_MASK) ) ); + } + + // Save the max rate in the connected state information... + + // modify LastRates variable as well + + return; +} + +eHalStatus csrRoamIssueStartBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamStartBssParams *pParam, + tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc, tANI_U32 roamId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrBand eBand; + // Set the roaming substate to 'Start BSS attempt'... + csrRoamSubstateChange( pMac, eCSR_ROAM_SUBSTATE_START_BSS_REQ, sessionId ); +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + //Need to figure out whether we need to log WDS??? + if( CSR_IS_IBSS( pProfile ) ) + { + vos_log_ibss_pkt_type *pIbssLog; + WLAN_VOS_DIAG_LOG_ALLOC(pIbssLog, vos_log_ibss_pkt_type, LOG_WLAN_IBSS_C); + if(pIbssLog) + { + if(pBssDesc) + { + pIbssLog->eventId = WLAN_IBSS_EVENT_JOIN_IBSS_REQ; + vos_mem_copy(pIbssLog->bssid, pBssDesc->bssId, 6); + } + else + { + pIbssLog->eventId = WLAN_IBSS_EVENT_START_IBSS_REQ; + } + vos_mem_copy(pIbssLog->ssid, pParam->ssId.ssId, pParam->ssId.length); + if(pProfile->ChannelInfo.numOfChannels == 0) + { + pIbssLog->channelSetting = AUTO_PICK; + } + else + { + pIbssLog->channelSetting = SPECIFIED; + } + pIbssLog->operatingChannel = pParam->operationChn; + WLAN_VOS_DIAG_LOG_REPORT(pIbssLog); + } + } +#endif //FEATURE_WLAN_DIAG_SUPPORT_CSR + //Put RSN information in for Starting BSS + pParam->nRSNIELength = (tANI_U16)pProfile->nRSNReqIELength; + pParam->pRSNIE = pProfile->pRSNReqIE; + + pParam->privacy = pProfile->privacy; + pParam->fwdWPSPBCProbeReq = pProfile->fwdWPSPBCProbeReq; + pParam->authType = pProfile->csr80211AuthType; + pParam->beaconInterval = pProfile->beaconInterval; + pParam->dtimPeriod = pProfile->dtimPeriod; + pParam->ApUapsdEnable = pProfile->ApUapsdEnable; + pParam->ssidHidden = pProfile->SSIDs.SSIDList[0].ssidHidden; + if (CSR_IS_INFRA_AP(pProfile)&& (pParam->operationChn != 0)) + { + if (csrIsValidChannel(pMac, pParam->operationChn) != eHAL_STATUS_SUCCESS) + { + pParam->operationChn = INFRA_AP_DEFAULT_CHANNEL; + } + } + pParam->protEnabled = pProfile->protEnabled; + pParam->obssProtEnabled = pProfile->obssProtEnabled; + pParam->ht_protection = pProfile->cfg_protection; + pParam->wps_state = pProfile->wps_state; + + pParam->uCfgDot11Mode = csrRoamGetPhyModeBandForBss(pMac, pProfile, pParam->operationChn /* pProfile->operationChannel*/, + &eBand); + pParam->bssPersona = pProfile->csrPersona; + +#ifdef WLAN_FEATURE_11W + pParam->mfpCapable = (0 != pProfile->MFPCapable); + pParam->mfpRequired = (0 != pProfile->MFPRequired); +#endif + + // When starting an IBSS, start on the channel from the Profile. + status = csrSendMBStartBssReqMsg( pMac, sessionId, pProfile->BSSType, pParam, pBssDesc ); + return (status); +} + +static void csrRoamPrepareBssParams(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pBssDesc, tBssConfigParam *pBssConfig, tDot11fBeaconIEs *pIes) +{ + tANI_U8 Channel; + ePhyChanBondState cbMode = PHY_SINGLE_CHANNEL_CENTERED; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if( pBssDesc ) + { + csrRoamGetBssStartParmsFromBssDesc( pMac, pBssDesc, pIes, &pSession->bssParams ); + //Since csrRoamGetBssStartParmsFromBssDesc fills in the bssid for pSession->bssParams + //The following code has to be do after that. + //For WDS station, use selfMac as the self BSSID + if( CSR_IS_WDS_STA( pProfile ) ) + { + vos_mem_copy(&pSession->bssParams.bssid, &pSession->selfMacAddr, + sizeof(tCsrBssid)); + } + } + else + { + csrRoamGetBssStartParms(pMac, pProfile, &pSession->bssParams); + //Use the first SSID + if(pProfile->SSIDs.numOfSSIDs) + { + vos_mem_copy(&pSession->bssParams.ssId, pProfile->SSIDs.SSIDList, + sizeof(tSirMacSSid)); + } + //For WDS station, use selfMac as the self BSSID + if( CSR_IS_WDS_STA( pProfile ) ) + { + vos_mem_copy(&pSession->bssParams.bssid, &pSession->selfMacAddr, + sizeof(tCsrBssid)); + } + //Use the first BSSID + else if( pProfile->BSSIDs.numOfBSSIDs ) + { + vos_mem_copy(&pSession->bssParams.bssid, pProfile->BSSIDs.bssid, + sizeof(tCsrBssid)); + } + else + { + vos_mem_set(&pSession->bssParams.bssid, sizeof(tCsrBssid), 0); + } + } + Channel = pSession->bssParams.operationChn; + //Set operating channel in pProfile which will be used + //in csrRoamSetBssConfigCfg() to determine channel bonding + //mode and will be configured in CFG later + pProfile->operationChannel = Channel; + + if(Channel == 0) + { + smsLog(pMac, LOGE, " CSR cannot find a channel to start IBSS"); + } + else + { + + csrRoamDetermineMaxRateForAdHoc( pMac, &pSession->bssParams.operationalRateSet ); + if (CSR_IS_INFRA_AP(pProfile) || CSR_IS_START_IBSS( pProfile ) ) + { + if(CSR_IS_CHANNEL_24GHZ(Channel) ) + { +#ifdef WLAN_FEATURE_AP_HT40_24G + if (CSR_IS_INFRA_AP(pProfile)) + cbMode = pMac->roam.configParam.channelBondingAPMode24GHz; + else + cbMode = PHY_SINGLE_CHANNEL_CENTERED; +#else + cbMode = PHY_SINGLE_CHANNEL_CENTERED; +#endif + } + else + { + cbMode = pMac->roam.configParam.channelBondingMode5GHz; + } + smsLog(pMac, LOG1, "## cbMode %d", cbMode); + pBssConfig->cbMode = cbMode; + pSession->bssParams.cbMode = cbMode; + } + } +} + +static eHalStatus csrRoamStartIbss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tANI_BOOLEAN *pfSameIbss ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fSameIbss = FALSE; + + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + // Check if any profile parameter has changed ? If any profile parameter + // has changed then stop old BSS and start a new one with new parameters + if ( csrIsSameProfile( pMac, &pMac->roam.roamSession[sessionId].connectedProfile, pProfile ) ) + { + fSameIbss = TRUE; + } + else + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING ); + } + } + else if ( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + // Disassociate from the connected Infrastructure network... + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE ); + } + else + { + tBssConfigParam *pBssConfig; + + pBssConfig = vos_mem_malloc(sizeof(tBssConfigParam)); + if ( NULL == pBssConfig ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pBssConfig, sizeof(tBssConfigParam), 0); + // there is no Bss description before we start an IBSS so we need to adopt + // all Bss configuration parameters from the Profile. + status = csrRoamPrepareBssConfigFromProfile(pMac, pProfile, pBssConfig, NULL); + if(HAL_STATUS_SUCCESS(status)) + { + //save dotMode + pMac->roam.roamSession[sessionId].bssParams.uCfgDot11Mode = pBssConfig->uCfgDot11Mode; + //Prepare some more parameters for this IBSS + csrRoamPrepareBssParams(pMac, sessionId, pProfile, NULL, pBssConfig, NULL); + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + NULL, pBssConfig, + NULL, eANI_BOOLEAN_FALSE); + } + + vos_mem_free(pBssConfig); + }//Allocate memory + } + + if(pfSameIbss) + { + *pfSameIbss = fSameIbss; + } + return( status ); +} + +static void csrRoamUpdateConnectedProfileFromNewBss( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirSmeNewBssInfo *pNewBss ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + if( pNewBss ) + { + // Set the operating channel. + pSession->connectedProfile.operationChannel = pNewBss->channelNumber; + // move the BSSId from the BSS description into the connected state information. + vos_mem_copy(&pSession->connectedProfile.bssid, &(pNewBss->bssId), + sizeof( tCsrBssid )); + } + return; +} + +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrRoamSetBKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId, tBkidCacheInfo *pBKIDCache, + tANI_U32 numItems ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tCsrRoamSession *pSession = NULL; + if(!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + smsLog(pMac, LOGE, FL(" Invalid session ID")); + return status; + } + smsLog(pMac, LOGW, "csrRoamSetBKIDCache called, numItems = %d", numItems); + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(numItems <= CSR_MAX_BKID_ALLOWED) + { + status = eHAL_STATUS_SUCCESS; + //numItems may be 0 to clear the cache + pSession->NumBkidCache = (tANI_U16)numItems; + if(numItems && pBKIDCache) + { + vos_mem_copy(pSession->BkidCacheInfo, pBKIDCache, + sizeof(tBkidCacheInfo) * numItems); + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} +eHalStatus csrRoamGetBKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pNum, + tBkidCacheInfo *pBkidCache) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tCsrRoamSession *pSession = NULL; + if(!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + smsLog(pMac, LOGE, FL(" Invalid session ID")); + return status; + } + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(pNum && pBkidCache) + { + if(pSession->NumBkidCache == 0) + { + *pNum = 0; + status = eHAL_STATUS_SUCCESS; + } + else if(*pNum >= pSession->NumBkidCache) + { + if(pSession->NumBkidCache > CSR_MAX_BKID_ALLOWED) + { + smsLog(pMac, LOGE, FL("NumBkidCache :%d is more than CSR_MAX_BKID_ALLOWED, resetting to CSR_MAX_BKID_ALLOWED"), + pSession->NumBkidCache); + pSession->NumBkidCache = CSR_MAX_BKID_ALLOWED; + } + vos_mem_copy(pBkidCache, pSession->BkidCacheInfo, + sizeof(tBkidCacheInfo) * pSession->NumBkidCache); + *pNum = pSession->NumBkidCache; + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} +tANI_U32 csrRoamGetNumBKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (pMac->roam.roamSession[sessionId].NumBkidCache); +} +#endif /* FEATURE_WLAN_WAPI */ +eHalStatus csrRoamSetPMKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, "csrRoamSetPMKIDCache called, numItems = %d", numItems); + + if (numItems <= CSR_MAX_PMKID_ALLOWED) + { +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&secEvent, + sizeof(vos_event_wlan_security_payload_type), 0); + secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_UPDATE; + secEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + secEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(secEvent.bssid, pSession->connectedProfile.bssid, 6); + secEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); + } +#endif//FEATURE_WLAN_DIAG_SUPPORT_CSR + status = eHAL_STATUS_SUCCESS; + if (update_entire_cache) { + if (numItems && pPMKIDCache) + { + pSession->NumPmkidCache = (tANI_U16)numItems; + vos_mem_copy(pSession->PmkidCacheInfo, pPMKIDCache, + sizeof(tPmkidCacheInfo) * numItems); + pSession->CurCacheIndex = (tANI_U16)numItems; + } + } else { + tANI_U32 i = 0; + tPmkidCacheInfo *pmksa; + + for (i = 0; i < numItems; i++) { + pmksa = &pPMKIDCache[i]; + + /* Delete the entry if present */ + csrRoamDelPMKIDfromCache(pMac,sessionId,pmksa->BSSID,FALSE); + + /* Add entry to the cache */ + vos_mem_copy( + pSession->PmkidCacheInfo[pSession->CurCacheIndex].BSSID, + pmksa->BSSID, VOS_MAC_ADDR_SIZE); + vos_mem_copy( + pSession->PmkidCacheInfo[pSession->CurCacheIndex].PMKID, + pmksa->PMKID, CSR_RSN_PMKID_SIZE); + + /* Increment the CSR local cache index */ + if (pSession->CurCacheIndex < (CSR_MAX_PMKID_ALLOWED - 1)) + pSession->CurCacheIndex++; + else + pSession->CurCacheIndex = 0; + + pSession->NumPmkidCache++; + if(pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) + pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED; + } + } + } + return (status); +} + +eHalStatus csrRoamDelPMKIDfromCache( tpAniSirGlobal pMac, tANI_U32 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pBSSId, +#else + tANI_U8 *pBSSId, +#endif + tANI_BOOLEAN flush_cache ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_BOOLEAN fMatchFound = FALSE; + tANI_U32 Index; + tANI_U32 CurIndex; + tANI_U32 i; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + /* Check if there are no entries to delete */ + if (0 == pSession->NumPmkidCache) { + smsLog(pMac, LOG1, FL("No entries to delete/Flush")); + return eHAL_STATUS_SUCCESS; + } + + if (!flush_cache) { + for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) { + if (vos_mem_compare(pSession->PmkidCacheInfo[Index].BSSID, + pBSSId, VOS_MAC_ADDR_SIZE)) { + fMatchFound = 1; + + /* Clear this - the matched entry */ + vos_mem_zero(&pSession->PmkidCacheInfo[Index], + sizeof(tPmkidCacheInfo)); + break; + } + } + + if (Index == CSR_MAX_PMKID_ALLOWED && !fMatchFound) { + smsLog(pMac, LOG1, FL("No such PMKSA entry exists "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pBSSId)); + } + else { + /* Match Found */ + CurIndex = pSession->CurCacheIndex; + if(Index < CurIndex) { + for(i = Index; i < (CurIndex-1); i++) { + vos_mem_copy(&pSession->PmkidCacheInfo[i], + &pSession->PmkidCacheInfo[i+1],sizeof(tPmkidCacheInfo)); + } + pSession->CurCacheIndex--; + vos_mem_zero(&pSession->PmkidCacheInfo[pSession->CurCacheIndex], + sizeof(tPmkidCacheInfo)); + } else if(Index > CurIndex) { + for(i = Index; i > (CurIndex); i--) { + vos_mem_copy(&pSession->PmkidCacheInfo[i], + &pSession->PmkidCacheInfo[i-1],sizeof(tPmkidCacheInfo)); + } + vos_mem_zero(&pSession->PmkidCacheInfo[pSession->CurCacheIndex], + sizeof(tPmkidCacheInfo)); + } + pSession->NumPmkidCache--; + } + } else { + /* Flush the entire cache */ + vos_mem_zero(pSession->PmkidCacheInfo, + sizeof(tPmkidCacheInfo) * CSR_MAX_PMKID_ALLOWED); + pSession->NumPmkidCache = 0; + pSession->CurCacheIndex = 0; + } + + return eHAL_STATUS_SUCCESS; +} + +tANI_U32 csrRoamGetNumPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (pMac->roam.roamSession[sessionId].NumPmkidCache); +} + +eHalStatus csrRoamGetPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pNum, tPmkidCacheInfo *pPmkidCache) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tPmkidCacheInfo *pmksa; + tANI_U16 i,j; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pNum && pPmkidCache) + { + if(pSession->NumPmkidCache == 0) + { + *pNum = 0; + status = eHAL_STATUS_SUCCESS; + } + else if(*pNum >= pSession->NumPmkidCache) + { + if(pSession->NumPmkidCache > CSR_MAX_PMKID_ALLOWED) + { + smsLog(pMac, LOGE, FL("NumPmkidCache :%d is more than CSR_MAX_PMKID_ALLOWED, resetting to CSR_MAX_PMKID_ALLOWED"), + pSession->NumPmkidCache); + pSession->NumPmkidCache = CSR_MAX_PMKID_ALLOWED; + } + + for(i = 0,j = 0; (jNumPmkidCache)&&(iPmkidCacheInfo[i]; + if(!csrIsMacAddressZero(pMac, &pmksa->BSSID)) { + vos_mem_copy(pPmkidCache,pmksa,sizeof(tPmkidCacheInfo)); + pPmkidCache++; + j++; + } + } + + *pNum = pSession->NumPmkidCache; + status = eHAL_STATUS_SUCCESS; + } + } + return (status); +} + +eHalStatus csrRoamGetWpaRsnReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWpaRsnReqIeLength; + if(pBuf) + { + if(len >= pSession->nWpaRsnReqIeLength) + { + vos_mem_copy(pBuf, pSession->pWpaRsnReqIE, + pSession->nWpaRsnReqIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} + +eHalStatus csrRoamGetWpaRsnRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWpaRsnRspIeLength; + if(pBuf) + { + if(len >= pSession->nWpaRsnRspIeLength) + { + vos_mem_copy(pBuf, pSession->pWpaRsnRspIE, + pSession->nWpaRsnRspIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrRoamGetWapiReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWapiReqIeLength; + if(pBuf) + { + if(len >= pSession->nWapiReqIeLength) + { + vos_mem_copy(pBuf, pSession->pWapiReqIE, + pSession->nWapiReqIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} +eHalStatus csrRoamGetWapiRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if(pLen) + { + len = *pLen; + *pLen = pSession->nWapiRspIeLength; + if(pBuf) + { + if(len >= pSession->nWapiRspIeLength) + { + vos_mem_copy(pBuf, pSession->pWapiRspIE, + pSession->nWapiRspIeLength); + status = eHAL_STATUS_SUCCESS; + } + } + } + return (status); +} +#endif /* FEATURE_WLAN_WAPI */ +eRoamCmdStatus csrGetRoamCompleteStatus(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eRoamCmdStatus retStatus = eCSR_ROAM_CONNECT_COMPLETION; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return (retStatus); + } + + if(CSR_IS_ROAMING(pSession)) + { + retStatus = eCSR_ROAM_ROAMING_COMPLETION; + pSession->fRoaming = eANI_BOOLEAN_FALSE; + } + return (retStatus); +} + +//This function remove the connected BSS from te cached scan result +eHalStatus csrRoamRemoveConnectedBssFromScanCache(tpAniSirGlobal pMac, + tCsrRoamConnectedProfile *pConnProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrScanResultFilter *pScanFilter = NULL; + tListElem *pEntry; + tCsrScanResult *pResult; + tDot11fBeaconIEs *pIes; + tANI_BOOLEAN fMatch; + if(!(csrIsMacAddressZero(pMac, &pConnProfile->bssid) || + csrIsMacAddressBroadcast(pMac, &pConnProfile->bssid))) + { + do + { + //Prepare the filter. Only fill in the necessary fields. Not all fields are needed + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tCsrBssid)); + if ( NULL == pScanFilter->BSSIDs.bssid ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + vos_mem_copy(pScanFilter->BSSIDs.bssid, &pConnProfile->bssid, + sizeof(tCsrBssid)); + pScanFilter->BSSIDs.numOfBSSIDs = 1; + if(!csrIsNULLSSID(pConnProfile->SSID.ssId, pConnProfile->SSID.length)) + { + pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == pScanFilter->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + vos_mem_copy(&pScanFilter->SSIDs.SSIDList[0].SSID, + &pConnProfile->SSID, sizeof(tSirMacSSid)); + } + pScanFilter->authType.numEntries = 1; + pScanFilter->authType.authType[0] = pConnProfile->AuthType; + pScanFilter->BSSType = pConnProfile->BSSType; + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = pConnProfile->EncryptionType; + pScanFilter->mcEncryptionType.numEntries = 1; + pScanFilter->mcEncryptionType.encryptionType[0] = pConnProfile->mcEncryptionType; + //We ignore the channel for now, BSSID should be enough + pScanFilter->ChannelInfo.numOfChannels = 0; + //Also ignore the following fields + pScanFilter->uapsd_mask = 0; + pScanFilter->bWPSAssociation = eANI_BOOLEAN_FALSE; + pScanFilter->bOSENAssociation = eANI_BOOLEAN_FALSE; + pScanFilter->countryCode[0] = 0; + pScanFilter->phyMode = eCSR_DOT11_MODE_TAURUS; + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = (tDot11fBeaconIEs *)( pResult->Result.pvIes ); + fMatch = csrMatchBSS(pMac, &pResult->Result.BssDescriptor, + pScanFilter, NULL, NULL, NULL, &pIes); + //Release the IEs allocated by csrMatchBSS is needed + if( !pResult->Result.pvIes ) + { + //need to free the IEs since it is allocated by csrMatchBSS + vos_mem_free(pIes); + } + if(fMatch) + { + //We found the one + if( csrLLRemoveEntry(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK) ) + { + //Free the memory + csrFreeScanResultEntry( pMac, pResult ); + } + break; + } + pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + }//while + csrLLUnlock(&pMac->scan.scanResultList); + }while(0); + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + } + return (status); +} + +//BT-AMP +eHalStatus csrIsBTAMPAllowed( tpAniSirGlobal pMac, tANI_U32 chnId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId; + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + if( csrIsConnStateIbss( pMac, sessionId ) || csrIsBTAMP( pMac, sessionId ) ) + { + //co-exist with IBSS or BT-AMP is not supported + smsLog( pMac, LOGW, " BTAMP is not allowed due to IBSS/BT-AMP exist in session %d", sessionId ); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + if( csrIsConnStateInfra( pMac, sessionId ) ) + { + if( chnId && + ( (tANI_U8)chnId != pMac->roam.roamSession[sessionId].connectedProfile.operationChannel ) ) + { + smsLog( pMac, LOGW, " BTAMP is not allowed due to channel (%d) diff than infr channel (%d)", + chnId, pMac->roam.roamSession[sessionId].connectedProfile.operationChannel ); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + } + } + } + return ( status ); +} + +static eHalStatus csrRoamStartWds( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tBssConfigParam bssConfig; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + if ( csrIsConnStateIbss( pMac, sessionId ) ) + { + status = csrRoamIssueStopBss( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING ); + } + else if ( csrIsConnStateConnectedInfra( pMac, sessionId ) ) + { + // Disassociate from the connected Infrastructure network... + status = csrRoamIssueDisassociate( pMac, sessionId, eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING, FALSE ); + } + else + { + //We don't expect Bt-AMP HDD not to disconnect the last connection first at this time. + //Otherwise we need to add code to handle the + //situation just like IBSS. Though for WDS station, we need to send disassoc to PE first then + //send stop_bss to PE, before we can continue. + VOS_ASSERT( !csrIsConnStateWds( pMac, sessionId ) ); + vos_mem_set(&bssConfig, sizeof(tBssConfigParam), 0); + /* Assume HDD provide bssid in profile */ + vos_mem_copy(&pSession->bssParams.bssid, pProfile->BSSIDs.bssid[0], + sizeof(tCsrBssid)); + // there is no Bss description before we start an WDS so we need + // to adopt all Bss configuration parameters from the Profile. + status = csrRoamPrepareBssConfigFromProfile(pMac, pProfile, &bssConfig, pBssDesc); + if(HAL_STATUS_SUCCESS(status)) + { + //Save profile for late use + csrFreeRoamProfile( pMac, sessionId ); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if (pSession->pCurRoamProfile != NULL ) + { + vos_mem_set(pSession->pCurRoamProfile, + sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile); + } + //Prepare some more parameters for this WDS + csrRoamPrepareBssParams(pMac, sessionId, pProfile, NULL, &bssConfig, NULL); + status = csrRoamSetBssConfigCfg(pMac, sessionId, pProfile, + NULL, &bssConfig, + NULL, eANI_BOOLEAN_FALSE); + } + } + + return( status ); +} + +////////////////////Mail box + +//pBuf is caller allocated memory point to &(tSirSmeJoinReq->rsnIE.rsnIEdata[ 0 ]) + pMsg->rsnIE.length; +//or &(tSirSmeReassocReq->rsnIE.rsnIEdata[ 0 ]) + pMsg->rsnIE.length; +static void csrPrepareJoinReassocReqBuffer( tpAniSirGlobal pMac, + tSirBssDescription *pBssDescription, + tANI_U8 *pBuf, tANI_U8 uapsdMask) +{ + tCsrChannelSet channelGroup; + tSirMacCapabilityInfo *pAP_capabilityInfo; + tAniBool fTmp; + tANI_BOOLEAN found = FALSE; + tANI_U32 size = 0; + tANI_S8 pwrLimit = 0; + tANI_U16 i; + // plug in neighborhood occupancy info (i.e. BSSes on primary or secondary channels) + *pBuf++ = (tANI_U8)FALSE; //tAniTitanCBNeighborInfo->cbBssFoundPri + *pBuf++ = (tANI_U8)FALSE; //tAniTitanCBNeighborInfo->cbBssFoundSecDown + *pBuf++ = (tANI_U8)FALSE; //tAniTitanCBNeighborInfo->cbBssFoundSecUp + // 802.11h + //We can do this because it is in HOST CPU order for now. + pAP_capabilityInfo = (tSirMacCapabilityInfo *)&pBssDescription->capabilityInfo; + //tell the target AP my 11H capability only if both AP and STA support 11H and the channel being used is 11a + if ( csrIs11hSupported( pMac ) && pAP_capabilityInfo->spectrumMgt && eSIR_11A_NW_TYPE == pBssDescription->nwType ) + { + fTmp = (tAniBool)pal_cpu_to_be32(1); + } + else + fTmp = (tAniBool)0; + + // corresponds to --- pMsg->spectrumMgtIndicator = ON; + vos_mem_copy(pBuf, (tANI_U8 *)&fTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + *pBuf++ = MIN_TX_PWR_CAP; // it is for pMsg->powerCap.minTxPower = 0; + found = csrSearchChannelListForTxPower(pMac, pBssDescription, &channelGroup); + // This is required for 11k test VoWiFi Ent: Test 2. + // We need the power capabilities for Assoc Req. + // This macro is provided by the halPhyCfg.h. We pick our + // max and min capability by the halPhy provided macros + pwrLimit = csrGetCfgMaxTxPower (pMac, pBssDescription->channelId); + if (0 != pwrLimit) + { + *pBuf++ = pwrLimit; + } + else + { + *pBuf++ = MAX_TX_PWR_CAP; + } + size = sizeof(pMac->roam.validChannelList); + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &size))) + { + tANI_U8 *actualSize = pBuf++; + *actualSize = 0; + + for ( i = 0; i < size; i++) + { + /* Only add 5ghz channels*/ + if (CSR_IS_CHANNEL_5GHZ(pMac->roam.validChannelList[ i ])) + { + *actualSize +=1; + *pBuf++ = pMac->roam.validChannelList[ i ]; + } + } + } + else + { + smsLog(pMac, LOGE, FL("can not find any valid channel")); + *pBuf++ = 0; //tSirSupChnl->numChnl + } + //Check whether it is ok to enter UAPSD +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if( btcIsReadyForUapsd(pMac) ) +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + { + *pBuf++ = uapsdMask; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + else + { + smsLog(pMac, LOGE, FL(" BTC doesn't allow UAPSD for uapsd_mask(0x%X)"), uapsdMask); + *pBuf++ = 0; + } +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + + // move the entire BssDescription into the join request. + vos_mem_copy(pBuf, pBssDescription, + pBssDescription->length + sizeof( pBssDescription->length )); + pBuf += pBssDescription->length + sizeof( pBssDescription->length ); // update to new location +} + +/* + * The communication between HDD and LIM is thru mailbox (MB). + * Both sides will access the data structure "tSirSmeJoinReq". + * The rule is, while the components of "tSirSmeJoinReq" can be accessed in the regular way like tSirSmeJoinReq.assocType, this guideline + * stops at component tSirRSNie; any acces to the components after tSirRSNie is forbidden because the space from tSirRSNie is quueezed + * with the component "tSirBssDescription". And since the size of actual 'tSirBssDescription' varies, the receiving side (which is the routine + * limJoinReqSerDes() of limSerDesUtils.cc) should keep in mind not to access the components DIRECTLY after tSirRSNie. + */ +eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription, + tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeJoinReq *pMsg; + tANI_U8 *pBuf; + v_U8_t acm_mask = 0, uapsd_mask; + tANI_U16 msgLen, wTmp, ieLen; + tSirMacRateSet OpRateSet; + tSirMacRateSet ExRateSet; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U32 dwTmp; + tANI_U8 wpaRsnIE[DOT11F_IE_RSN_MAX_LEN]; //RSN MAX is bigger than WPA MAX + tANI_U32 ucDot11Mode = 0; + tANI_U8 txBFCsnValue = 0; + tANI_U16 rateBitmap = 0; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + /* To satisfy klockworks */ + if (NULL == pBssDescription) + { + smsLog(pMac, LOGE, FL(" pBssDescription is NULL")); + return eHAL_STATUS_FAILURE; + } + + do { + pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS; + pSession->joinFailStatusCode.reasonCode = 0; + vos_mem_copy (&pSession->joinFailStatusCode.bssId, &pBssDescription->bssId, sizeof(tSirMacAddr)); + // There are a number of variable length fields to consider. First, the tSirSmeJoinReq + // includes a single bssDescription. bssDescription includes a single tANI_U32 for the + // IE fields, but the length field in the bssDescription needs to be interpreted to + // determine length of the IE fields. + // + // So, take the size of the JoinReq, subtract the size of the bssDescription and + // add in the length from the bssDescription (then add the size of the 'length' field + // itself because that is NOT included in the length field). + msgLen = sizeof( tSirSmeJoinReq ) - sizeof( *pBssDescription ) + + pBssDescription->length + sizeof( pBssDescription->length ) + + sizeof( tCsrWpaIe ) + sizeof( tCsrWpaAuthIe ) + sizeof( tANI_U16 ); // add in the size of the WPA IE that we may build. + pMsg = vos_mem_malloc(msgLen); + if (NULL == pMsg) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, msgLen , 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)messageType); + pMsg->length = pal_cpu_to_be16(msgLen); + pBuf = &pMsg->sessionId; + // sessionId + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + // ssId + if( pIes->SSID.present && pIes->SSID.num_ssid ) + { + // ssId len + *pBuf = pIes->SSID.num_ssid; + pBuf++; + vos_mem_copy(pBuf, pIes->SSID.ssid, pIes->SSID.num_ssid); + pBuf += pIes->SSID.num_ssid; + } + else + { + *pBuf = 0; + pBuf++; + } + // selfMacAddr + vos_mem_copy((tSirMacAddr *)pBuf, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // bsstype + dwTmp = pal_cpu_to_be32( csrTranslateBsstypeToMacType( pProfile->BSSType ) ); + if (dwTmp == eSIR_BTAMP_STA_MODE) dwTmp = eSIR_BTAMP_AP_MODE; // Override BssType for BTAMP + vos_mem_copy(pBuf, &dwTmp, sizeof(tSirBssType)); + pBuf += sizeof(tSirBssType); + // dot11mode + ucDot11Mode = csrTranslateToWNICfgDot11Mode( pMac, pSession->bssParams.uCfgDot11Mode ); + if (pBssDescription->channelId <= 14 && + FALSE == pMac->roam.configParam.enableVhtFor24GHz && + WNI_CFG_DOT11_MODE_11AC == ucDot11Mode) + { + //Need to disable VHT operation in 2.4 GHz band + ucDot11Mode = WNI_CFG_DOT11_MODE_11N; + } + smsLog(pMac, LOG1, FL("dot11mode %d uCfgDot11Mode %d"), + ucDot11Mode, pSession->bssParams.uCfgDot11Mode); + + *pBuf = (tANI_U8)ucDot11Mode; + pBuf++; + //Persona + *pBuf = (tANI_U8)pProfile->csrPersona; + pBuf++; + *pBuf = (tANI_U8)pProfile->bOSENAssociation; + pBuf++; + *pBuf = (tANI_U8)pProfile->bWPSAssociation; + pBuf++; + //CBMode + *pBuf = (tANI_U8)pSession->bssParams.cbMode; + pBuf++; + *pBuf = (tANI_U8)pProfile->force_24ghz_in_ht20; + pBuf++; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("CSR PERSONA=%d CSR CbMode %d force_24ghz_in_ht20 %d"), + pProfile->csrPersona, pSession->bssParams.cbMode, + pProfile->force_24ghz_in_ht20); + + // uapsdPerAcBitmask + *pBuf = pProfile->uapsd_mask; + pBuf++; + + + + status = csrGetRateSet(pMac, pProfile, (eCsrPhyMode)pProfile->phyMode, pBssDescription, pIes, &OpRateSet, &ExRateSet,&rateBitmap); + if (HAL_STATUS_SUCCESS(status) ) + { + // OperationalRateSet + if (OpRateSet.numRates) { + *pBuf++ = OpRateSet.numRates; + vos_mem_copy(pBuf, OpRateSet.rate, OpRateSet.numRates); + pBuf += OpRateSet.numRates; + } else *pBuf++ = 0; + // ExtendedRateSet + if (ExRateSet.numRates) { + *pBuf++ = ExRateSet.numRates; + vos_mem_copy(pBuf, ExRateSet.rate, ExRateSet.numRates); + pBuf += ExRateSet.numRates; + } else *pBuf++ = 0; + } + else + { + *pBuf++ = 0; + *pBuf++ = 0; + } + + //rateBitmap + vos_mem_copy(pBuf, &rateBitmap, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + + // rsnIE + if ( csrIsProfileWpa( pProfile ) ) + { + // Insert the Wpa IE into the join request + ieLen = csrRetrieveWpaIe( pMac, pProfile, pBssDescription, pIes, + (tCsrWpaIe *)( wpaRsnIE ) ); + } + else if( csrIsProfileRSN( pProfile ) ) + { + // Insert the RSN IE into the join request + ieLen = csrRetrieveRsnIe( pMac, sessionId, pProfile, pBssDescription, pIes, + (tCsrRSNIe *)( wpaRsnIE ) ); + } +#ifdef FEATURE_WLAN_WAPI + else if( csrIsProfileWapi( pProfile ) ) + { + // Insert the WAPI IE into the join request + ieLen = csrRetrieveWapiIe( pMac, sessionId, pProfile, pBssDescription, pIes, + (tCsrWapiIe *)( wpaRsnIE ) ); + } +#endif /* FEATURE_WLAN_WAPI */ + else + { + ieLen = 0; + } + //remember the IE for future use + if( ieLen ) + { + if(ieLen > DOT11F_IE_RSN_MAX_LEN) + { + smsLog(pMac, LOGE, FL(" WPA RSN IE length :%d is more than DOT11F_IE_RSN_MAX_LEN, resetting to %d"), ieLen, DOT11F_IE_RSN_MAX_LEN); + ieLen = DOT11F_IE_RSN_MAX_LEN; + } +#ifdef FEATURE_WLAN_WAPI + if( csrIsProfileWapi( pProfile ) ) + { + //Check whether we need to allocate more memory + if(ieLen > pSession->nWapiReqIeLength) + { + if(pSession->pWapiReqIE && pSession->nWapiReqIeLength) + { + vos_mem_free(pSession->pWapiReqIE); + } + pSession->pWapiReqIE = vos_mem_malloc(ieLen); + if (NULL == pSession->pWapiReqIE) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nWapiReqIeLength = ieLen; + vos_mem_copy(pSession->pWapiReqIE, wpaRsnIE, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, wpaRsnIE, ieLen); + pBuf += ieLen; + } + else//should be WPA/WPA2 otherwise +#endif /* FEATURE_WLAN_WAPI */ + { + //Check whether we need to allocate more memory + if(ieLen > pSession->nWpaRsnReqIeLength) + { + if(pSession->pWpaRsnReqIE && pSession->nWpaRsnReqIeLength) + { + vos_mem_free(pSession->pWpaRsnReqIE); + } + pSession->pWpaRsnReqIE = vos_mem_malloc(ieLen); + if (NULL == pSession->pWpaRsnReqIE) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nWpaRsnReqIeLength = ieLen; + vos_mem_copy(pSession->pWpaRsnReqIE, wpaRsnIE, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, wpaRsnIE, ieLen); + pBuf += ieLen; + } + } + else + { + //free whatever old info + pSession->nWpaRsnReqIeLength = 0; + if(pSession->pWpaRsnReqIE) + { + vos_mem_free(pSession->pWpaRsnReqIE); + pSession->pWpaRsnReqIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + pSession->nWapiReqIeLength = 0; + if(pSession->pWapiReqIE) + { + vos_mem_free(pSession->pWapiReqIE); + pSession->pWapiReqIE = NULL; + } +#endif /* FEATURE_WLAN_WAPI */ + //length is two bytes + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } +#ifdef FEATURE_WLAN_ESE + if( eWNI_SME_JOIN_REQ == messageType ) + { + // Never include the cckmIE in an Join Request + //length is two bytes + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + else if(eWNI_SME_REASSOC_REQ == messageType ) + { + // cckmIE + if( csrIsProfileESE( pProfile ) ) + { + // Insert the CCKM IE into the join request +#ifdef FEATURE_WLAN_ESE_UPLOAD + ieLen = pSession->suppCckmIeInfo.cckmIeLen; + vos_mem_copy((void *) (wpaRsnIE), + pSession->suppCckmIeInfo.cckmIe, ieLen); +#else + ieLen = csrConstructEseCckmIe( pMac, + pSession, + pProfile, + pBssDescription, + pSession->pWpaRsnReqIE, + pSession->nWpaRsnReqIeLength, + (void *)( wpaRsnIE ) ); +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + } + else + { + ieLen = 0; + } + //If present, copy the IE into the eWNI_SME_REASSOC_REQ message buffer + if( ieLen ) + { + //Copy the CCKM IE over from the temp buffer (wpaRsnIE) + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, wpaRsnIE, ieLen); + pBuf += ieLen; + } + else + { + //Indicate you have no CCKM IE + //length is two bytes + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + } +#endif /* FEATURE_WLAN_ESE */ + // addIEScan + if (pProfile->nAddIEScanLength) + { + ieLen = pProfile->nAddIEScanLength; + memset(pSession->addIEScan, 0 , pSession->nAddIEScanLength); + pSession->nAddIEScanLength = ieLen; + vos_mem_copy(pSession->addIEScan, pProfile->addIEScan, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, pProfile->addIEScan, ieLen); + pBuf += ieLen; + } + else + { + memset(pSession->addIEScan, 0, pSession->nAddIEScanLength); + pSession->nAddIEScanLength = 0; + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + // addIEAssoc + if(pProfile->nAddIEAssocLength && pProfile->pAddIEAssoc) + { + ieLen = pProfile->nAddIEAssocLength; + if(ieLen > pSession->nAddIEAssocLength) + { + if(pSession->pAddIEAssoc && pSession->nAddIEAssocLength) + { + vos_mem_free(pSession->pAddIEAssoc); + } + pSession->pAddIEAssoc = vos_mem_malloc(ieLen); + if (NULL == pSession->pAddIEAssoc) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + pSession->nAddIEAssocLength = ieLen; + vos_mem_copy(pSession->pAddIEAssoc, pProfile->pAddIEAssoc, ieLen); + wTmp = pal_cpu_to_be16( ieLen ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + vos_mem_copy(pBuf, pProfile->pAddIEAssoc, ieLen); + pBuf += ieLen; + } + else + { + pSession->nAddIEAssocLength = 0; + if(pSession->pAddIEAssoc) + { + vos_mem_free(pSession->pAddIEAssoc); + pSession->pAddIEAssoc = NULL; + } + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += 2; + } + + if(eWNI_SME_REASSOC_REQ == messageType ) + { + //Unmask any AC in reassoc that is ACM-set + uapsd_mask = (v_U8_t)pProfile->uapsd_mask; + if( uapsd_mask && ( NULL != pBssDescription ) ) + { + if( CSR_IS_QOS_BSS(pIes) && CSR_IS_UAPSD_BSS(pIes) ) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(pMac, pBssDescription, pIes); +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + else + { + uapsd_mask = 0; + } + } + } + + dwTmp = pal_cpu_to_be32( csrTranslateEncryptTypeToEdType( pProfile->negotiatedUCEncryptionType) ); + vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); + + dwTmp = pal_cpu_to_be32( csrTranslateEncryptTypeToEdType( pProfile->negotiatedMCEncryptionType) ); + vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); +#ifdef WLAN_FEATURE_11W + //MgmtEncryption + if (pProfile->MFPEnabled) + { + dwTmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC); + } + else + { + dwTmp = pal_cpu_to_be32(eSIR_ED_NONE); + } + vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + pProfile->MDID.mdiePresent = pBssDescription->mdiePresent; + if (csrIsProfile11r( pProfile ) +#ifdef FEATURE_WLAN_ESE + && !((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) && + (pIes->ESEVersion.present) && (pMac->roam.configParam.isEseIniFeatureEnabled)) +#endif + ) + { + // is11Rconnection; + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)) ; + pBuf += sizeof(tAniBool); + } + else + { + // is11Rconnection; + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } +#endif +#ifdef FEATURE_WLAN_ESE + + // isESEFeatureIniEnabled + if (TRUE == pMac->roam.configParam.isEseIniFeatureEnabled) + { + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + + /* A profile can not be both ESE and 11R. But an 802.11R AP + * may be advertising support for ESE as well. So if we are + * associating Open or explicitly ESE then we will get ESE. + * If we are associating explictly 11R only then we will get + * 11R. + */ + if ((csrIsProfileESE(pProfile) || + ((pIes->ESEVersion.present) + && ((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (pProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (pMac->roam.configParam.isEseIniFeatureEnabled)) + { + // isESEconnection; + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + //isESEconnection; + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + + if (eWNI_SME_JOIN_REQ == messageType) + { + tESETspecInfo eseTspec; + // ESE-Tspec IEs in the ASSOC request is presently not supported + // so nullify the TSPEC parameters + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + vos_mem_copy(pBuf, &eseTspec, sizeof(tESETspecInfo)); + pBuf += sizeof(tESETspecInfo); + } + else if (eWNI_SME_REASSOC_REQ == messageType) + { + if ((csrIsProfileESE(pProfile) || + ((pIes->ESEVersion.present) + && ((pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (pProfile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (pProfile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (pMac->roam.configParam.isEseIniFeatureEnabled)) + { + tESETspecInfo eseTspec; + // ESE Tspec information + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + eseTspec.numTspecs = sme_QosESERetrieveTspecInfo(pMac, sessionId, (tTspecInfo *) &eseTspec.tspec[0]); + *pBuf = eseTspec.numTspecs; + pBuf += sizeof(tANI_U8); + // Copy the TSPEC information only if present + if (eseTspec.numTspecs) { + vos_mem_copy(pBuf, (void*)&eseTspec.tspec[0], + (eseTspec.numTspecs*sizeof(tTspecInfo))); + } + pBuf += sizeof(eseTspec.tspec); + } + else + { + tESETspecInfo eseTspec; + // ESE-Tspec IEs in the ASSOC request is presently not supported + // so nullify the TSPEC parameters + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + vos_mem_copy(pBuf, &eseTspec, sizeof(tESETspecInfo)); + pBuf += sizeof(tESETspecInfo); + } + } +#endif // FEATURE_WLAN_ESE +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + // Fill in isFastTransitionEnabled + if (pMac->roam.configParam.isFastTransitionEnabled +#ifdef FEATURE_WLAN_LFR + || csrRoamIsFastRoamEnabled(pMac, sessionId) +#endif + ) + { + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } +#endif +#ifdef FEATURE_WLAN_LFR + if(csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + //legacy fast roaming enabled + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } +#endif + + // txLdpcIniFeatureEnabled + *pBuf = (tANI_U8)pMac->roam.configParam.txLdpcEnable; + pBuf++; + + if ((csrIs11hSupported (pMac)) && (CSR_IS_CHANNEL_5GHZ(pBssDescription->channelId)) && + (pIes->Country.present) && (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + csrSaveToChannelPower2G_5G( pMac, pIes->Country.num_triplets * sizeof(tSirMacChanInfo), + (tSirMacChanInfo *)(&pIes->Country.triplets[0]) ); + csrApplyPower2Current(pMac); + } + +#ifdef WLAN_FEATURE_11AC + // txBFIniFeatureEnabled + *pBuf = (tANI_U8)pMac->roam.configParam.txBFEnable; + pBuf++; + + // txBFCsnValue + if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps)) + { + txBFCsnValue = (tANI_U8)pMac->roam.configParam.txBFCsnValue; + if (pIes->VHTCaps.numSoundingDim) + txBFCsnValue = CSR_ROAM_MIN + (txBFCsnValue, pIes->VHTCaps.numSoundingDim); + } + *pBuf = txBFCsnValue; + pBuf++; + + /* Only enable MuBf if no other MuBF session exist + * and FW and HOST is MuBF capable. + */ + if ( IS_MUMIMO_BFORMEE_CAPABLE && (FALSE == pMac->isMuBfsessionexist) ) + { + *pBuf = (tANI_U8)pMac->roam.configParam.txMuBformee; + pBuf++; + } + else + { + *pBuf = 0; + pBuf++; + } +#endif + *pBuf = (tANI_U8)pMac->roam.configParam.isAmsduSupportInAMPDU; + pBuf++; + + // WME + if(pMac->roam.roamSession[sessionId].fWMMConnection) + { + //WME enabled + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + + // QOS + if(pMac->roam.roamSession[sessionId].fQOSConnection) + { + //QOS enabled + dwTmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + else + { + dwTmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(pBuf, &dwTmp, sizeof(tAniBool)); + pBuf += sizeof(tAniBool); + } + //BssDesc + csrPrepareJoinReassocReqBuffer( pMac, pBssDescription, pBuf, + (tANI_U8)pProfile->uapsd_mask); + + status = palSendMBMessage(pMac->hHdd, pMsg ); + /* Memory allocated to pMsg will get free'd in palSendMBMessage */ + pMsg = NULL; + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + else + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if (eWNI_SME_JOIN_REQ == messageType) + { + //Tush-QoS: notify QoS module that join happening + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_JOIN_REQ, NULL); + } + else if (eWNI_SME_REASSOC_REQ == messageType) + { + //Tush-QoS: notify QoS module that reassoc happening + sme_QosCsrEventInd(pMac, (v_U8_t)sessionId, SME_QOS_CSR_REASSOC_REQ, NULL); + } +#endif + } + } while( 0 ); + + if (pMsg != NULL) + { + vos_mem_free( pMsg ); + } + + return( status ); +} + +#ifdef WLAN_FEATURE_LFR_MBB +/** + * csr_prepare_reassoc_req () - Prepares reassoc request + * @mac: MAC context + * @session_id: session id + * @pbss_description: bss description + * @ies: pointer to beacon IE's + * @reassoc_req: pointer to reassociation request + * + *Return: None + */ +eHalStatus csr_fill_reassoc_req(tpAniSirGlobal mac, tANI_U32 session_id, + tSirBssDescription *bss_description, tDot11fBeaconIEs *ies, + tSirSmeJoinReq **reassoc_req) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeJoinReq *csr_join_req; + tANI_U8 *buf; + v_U8_t acm_mask = 0, uapsd_mask; + tANI_U16 msg_len, w_tmp, ie_len; + tSirMacRateSet op_rate_set; + tSirMacRateSet ex_rate_set; + tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id); + tANI_U32 dw_tmp; + tANI_U8 wpa_rsn_ie[DOT11F_IE_RSN_MAX_LEN]; + tANI_U32 uc_dot11_mode = 0; + tANI_U8 tx_bf_csn_value = 0; + tANI_U16 rate_bitmap = 0; + tANI_U16 message_type = eWNI_SME_REASSOC_REQ; + tCsrRoamProfile *profile; + + if(!session) { + smsLog(mac, LOGE, FL(" session %d not found "), session_id); + return eHAL_STATUS_FAILURE; + } + + if (NULL == bss_description) { + smsLog(mac, LOGE, FL(" pBssDescription is NULL")); + return eHAL_STATUS_FAILURE; + } + + smsLog(mac, LOG1, + FL("session_id %d"), session_id); + + profile = vos_mem_malloc(sizeof(*profile)); + if (NULL == profile) { + smsLog(mac, LOGE, FL("Memory allocation failure for profile")); + return eHAL_STATUS_RESOURCES; + } + + status = csrRoamCopyProfile(mac, profile, session->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) { + smsLog(mac, LOGE, FL("Profile copy failed")); + return eHAL_STATUS_FAILURE; + } + + do { + /* + * There are a number of variable length fields to consider. + * First, the tSirSmeJoinReq includes a single bssDescription. + * bssDescription includes a single tANI_U32 for the IE fields, + * but the length field in the bssDescription needs to be + * interpreted to determine length of the IE fields. + * So, take the size of the JoinReq, subtract the size of the + * bssDescription and add in the length from the bssDescription + * (then add the size of the 'length' field itself because that is + * NOT included in the length field). msgLen = + * sizeof( tSirSmeJoinReq ) - sizeof( *pBssDescription ) + + * pBssDescription->length + sizeof( pBssDescription->length ) + + * sizeof( tCsrWpaIe ) + sizeof( tCsrWpaAuthIe ) + sizeof( tANI_U16 ); + * add in the size of the WPA IE that we may build. + */ + + msg_len = sizeof(tSirSmeJoinReq) - sizeof(*bss_description) + + bss_description->length + sizeof(bss_description->length) + + sizeof(tCsrWpaIe) + sizeof(tCsrWpaAuthIe) + sizeof(tANI_U16); + + csr_join_req = vos_mem_malloc(msg_len); + if (NULL == csr_join_req) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + + vos_mem_set(csr_join_req, msg_len, 0); + *reassoc_req = csr_join_req; + + csr_join_req->messageType = pal_cpu_to_be16(eWNI_SME_REASSOC_REQ); + csr_join_req->length = pal_cpu_to_be16(msg_len); + buf = &csr_join_req->sessionId; + + /* session_id */ + *buf = (tANI_U8)session_id; + buf++; + + /* transactionId */ + *buf = 0; + *(buf + 1) = 0; + buf += sizeof(tANI_U16); + + /* ssId */ + if(ies->SSID.present && ies->SSID.num_ssid) + { + /* ssId len */ + *buf = ies->SSID.num_ssid; + buf++; + vos_mem_copy(buf, ies->SSID.ssid, ies->SSID.num_ssid); + buf += ies->SSID.num_ssid; + } + else + { + *buf = 0; + buf++; + } + + /* selfMacAddr */ + vos_mem_copy((tSirMacAddr *)buf, &session->selfMacAddr, + sizeof(tSirMacAddr)); + buf += sizeof(tSirMacAddr); + + /* bsstype */ + dw_tmp = + pal_cpu_to_be32(csrTranslateBsstypeToMacType(profile->BSSType)); + /* Override BssType for BTAMP */ + if (dw_tmp == eSIR_BTAMP_STA_MODE) dw_tmp = eSIR_BTAMP_AP_MODE; + vos_mem_copy(buf, &dw_tmp, sizeof(tSirBssType)); + buf += sizeof(tSirBssType); + + /* dot11mode */ + uc_dot11_mode = + csrTranslateToWNICfgDot11Mode(mac, session->bssParams.uCfgDot11Mode); + if (bss_description->channelId <= 14 && + FALSE == mac->roam.configParam.enableVhtFor24GHz && + WNI_CFG_DOT11_MODE_11AC == uc_dot11_mode) + { + /* Need to disable VHT operation in 2.4 GHz band */ + uc_dot11_mode = WNI_CFG_DOT11_MODE_11N; + } + *buf = (tANI_U8)uc_dot11_mode; + buf++; + + /* Persona */ + *buf = (tANI_U8)profile->csrPersona; + buf++; + *buf = (tANI_U8)profile->bOSENAssociation; + buf++; + *buf = (tANI_U8)profile->bWPSAssociation; + buf++; + + /* CBMode */ + *buf = (tANI_U8)session->bssParams.cbMode; + buf++; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("CSR PERSONA=%d CSR CbMode %d"), profile->csrPersona, + session->bssParams.cbMode); + + /* uapsdPerAcBitmask */ + *buf = profile->uapsd_mask; + buf++; + + + status = csrGetRateSet(mac, profile, (eCsrPhyMode)profile->phyMode, + bss_description, ies, &op_rate_set, &ex_rate_set,&rate_bitmap); + if (HAL_STATUS_SUCCESS(status)) + { + /* OperationalRateSet */ + if (op_rate_set.numRates) { + *buf++ = op_rate_set.numRates; + vos_mem_copy(buf, op_rate_set.rate, op_rate_set.numRates); + buf += op_rate_set.numRates; + } else *buf++ = 0; + + /* ExtendedRateSet */ + if (ex_rate_set.numRates) { + *buf++ = ex_rate_set.numRates; + vos_mem_copy(buf, ex_rate_set.rate, ex_rate_set.numRates); + buf += ex_rate_set.numRates; + } else *buf++ = 0; + } + else + { + *buf++ = 0; + *buf++ = 0; + } + + /* rateBitmap */ + vos_mem_copy(buf, &rate_bitmap, sizeof(tANI_U16)); + buf += sizeof(tANI_U16); + + profile->negotiatedAuthType = + mac->roam.roamSession[session_id].connectedProfile.AuthType; + profile->negotiatedUCEncryptionType = + mac->roam.roamSession[session_id].connectedProfile.EncryptionType; + + /* rsnIE */ + if ( csrIsProfileWpa(profile)) + { + /* Insert the Wpa IE into the join request */ + ie_len = csrRetrieveWpaIe(mac, profile, bss_description, ies, + (tCsrWpaIe *)(wpa_rsn_ie)); + } + else if( csrIsProfileRSN(profile)) + { + /* Insert the RSN IE into the join request */ + ie_len = csrRetrieveRsnIe(mac, session_id, profile, bss_description, + ies, (tCsrRSNIe *)(wpa_rsn_ie)); + } +#ifdef FEATURE_WLAN_WAPI + else if( csrIsProfileWapi(profile)) + { + /* Insert the WAPI IE into the join request */ + ie_len = csrRetrieveWapiIe(mac, session_id, profile, + bss_description, ies, (tCsrWapiIe *)(wpa_rsn_ie)); + } +#endif + else + { + ie_len = 0; + } + /* remember the IE for future use */ + if(ie_len) + { + if(ie_len > DOT11F_IE_RSN_MAX_LEN) + { + smsLog(mac, LOGE, + FL("WPA RSN IE length :%d is more than RSN_MAX_LEN %d"), + ie_len, DOT11F_IE_RSN_MAX_LEN); + ie_len = DOT11F_IE_RSN_MAX_LEN; + } +#ifdef FEATURE_WLAN_WAPI + if( csrIsProfileWapi(profile)) + { + /* Check whether we need to allocate more memory */ + if(ie_len > session->nWapiReqIeLength) + { + if(session->pWapiReqIE && session->nWapiReqIeLength) + { + vos_mem_free(session->pWapiReqIE); + } + session->pWapiReqIE = vos_mem_malloc(ie_len); + if (NULL == session->pWapiReqIE) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + session->nWapiReqIeLength = ie_len; + vos_mem_copy(session->pWapiReqIE, wpa_rsn_ie, ie_len); + w_tmp = pal_cpu_to_be16(ie_len); + vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16)); + buf += sizeof(tANI_U16); + vos_mem_copy(buf, wpa_rsn_ie, ie_len); + buf += ie_len; + } + else /* should be WPA/WPA2 otherwise */ +#endif + { + /* Check whether we need to allocate more memory */ + if(ie_len > session->nWpaRsnReqIeLength) + { + if(session->pWpaRsnReqIE && session->nWpaRsnReqIeLength) + { + vos_mem_free(session->pWpaRsnReqIE); + } + session->pWpaRsnReqIE = vos_mem_malloc(ie_len); + if (NULL == session->pWpaRsnReqIE) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + session->nWpaRsnReqIeLength = ie_len; + vos_mem_copy(session->pWpaRsnReqIE, wpa_rsn_ie, ie_len); + w_tmp = pal_cpu_to_be16(ie_len); + vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16)); + buf += sizeof(tANI_U16); + vos_mem_copy(buf, wpa_rsn_ie, ie_len); + buf += ie_len; + } + } + else + { + /* free whatever old info */ + session->nWpaRsnReqIeLength = 0; + if(session->pWpaRsnReqIE) + { + vos_mem_free(session->pWpaRsnReqIE); + session->pWpaRsnReqIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + session->nWapiReqIeLength = 0; + if(session->pWapiReqIE) + { + vos_mem_free(session->pWapiReqIE); + session->pWapiReqIE = NULL; + } +#endif + /* length is two bytes */ + *buf = 0; + *(buf + 1) = 0; + buf += 2; + } +#ifdef FEATURE_WLAN_ESE + if(eWNI_SME_JOIN_REQ == message_type) + { + /* + * Never include the cckmIE in an Join Request + * length is two bytes + */ + *buf = 0; + *(buf + 1) = 0; + buf += 2; + } + else if(eWNI_SME_REASSOC_REQ == message_type) + { + /* cckmIE */ + if( csrIsProfileESE(profile)) + { + /* Insert the CCKM IE into the join request */ +#ifdef FEATURE_WLAN_ESE_UPLOAD + ie_len = session->suppCckmIeInfo.cckmIeLen; + vos_mem_copy((void *) (wpa_rsn_ie), + session->suppCckmIeInfo.cckmIe, ie_len); +#else + ie_len = csrConstructEseCckmIe(mac, + session, + profile, + bss_description, + session->pWpaRsnReqIE, + session->nWpaRsnReqIeLength, + (void *)(wpa_rsn_ie)); +#endif + } + else + { + ie_len = 0; + } + /* + * If present, copy the IE into the eWNI_SME_REASSOC_REQ + * message buffer + */ + if(ie_len) + { + /* Copy the CCKM IE over from the temp buffer (wpaRsnIE) */ + w_tmp = pal_cpu_to_be16(ie_len); + vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16)); + buf += sizeof(tANI_U16); + vos_mem_copy(buf, wpa_rsn_ie, ie_len); + buf += ie_len; + } + else + { + /* Indicate you have no CCKM IE length is two bytes */ + *buf = 0; + *(buf + 1) = 0; + buf += 2; + } + } +#endif + /* addIEScan */ + if (profile->nAddIEScanLength) + { + ie_len = profile->nAddIEScanLength; + memset(session->addIEScan, 0 , session->nAddIEScanLength); + session->nAddIEScanLength = ie_len; + vos_mem_copy(session->addIEScan, profile->addIEScan, ie_len); + w_tmp = pal_cpu_to_be16(ie_len); + vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16)); + buf += sizeof(tANI_U16); + vos_mem_copy(buf, profile->addIEScan, ie_len); + buf += ie_len; + } + else + { + memset(session->addIEScan, 0, session->nAddIEScanLength); + session->nAddIEScanLength = 0; + *buf = 0; + *(buf + 1) = 0; + buf += 2; + } + /* addIEAssoc */ + if(profile->nAddIEAssocLength && profile->pAddIEAssoc) + { + ie_len = profile->nAddIEAssocLength; + if(ie_len > session->nAddIEAssocLength) + { + if(session->pAddIEAssoc && session->nAddIEAssocLength) + { + vos_mem_free(session->pAddIEAssoc); + } + session->pAddIEAssoc = vos_mem_malloc(ie_len); + if (NULL == session->pAddIEAssoc) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) break; + } + session->nAddIEAssocLength = ie_len; + vos_mem_copy(session->pAddIEAssoc, profile->pAddIEAssoc, ie_len); + w_tmp = pal_cpu_to_be16(ie_len); + vos_mem_copy(buf, &w_tmp, sizeof(tANI_U16)); + buf += sizeof(tANI_U16); + vos_mem_copy(buf, profile->pAddIEAssoc, ie_len); + buf += ie_len; + } + else + { + session->nAddIEAssocLength = 0; + if(session->pAddIEAssoc) + { + vos_mem_free(session->pAddIEAssoc); + session->pAddIEAssoc = NULL; + } + *buf = 0; + *(buf + 1) = 0; + buf += 2; + } + + if(eWNI_SME_REASSOC_REQ == message_type ) + { + /*Unmask any AC in reassoc that is ACM-set */ + uapsd_mask = (v_U8_t)profile->uapsd_mask; + if( uapsd_mask && (NULL != bss_description)) + { + if( CSR_IS_QOS_BSS(ies) && CSR_IS_UAPSD_BSS(ies) ) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + acm_mask = sme_QosGetACMMask(mac, bss_description, ies); +#endif + } + else + { + uapsd_mask = 0; + } + } + } + + dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType( + profile->negotiatedUCEncryptionType)); + vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32)); + buf += sizeof(tANI_U32); + + dw_tmp = pal_cpu_to_be32(csrTranslateEncryptTypeToEdType( + profile->negotiatedMCEncryptionType)); + vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32)); + buf += sizeof(tANI_U32); +#ifdef WLAN_FEATURE_11W + /* MgmtEncryption */ + if (profile->MFPEnabled) + { + dw_tmp = pal_cpu_to_be32(eSIR_ED_AES_128_CMAC); + } + else + { + dw_tmp = pal_cpu_to_be32(eSIR_ED_NONE); + } + vos_mem_copy(buf, &dw_tmp, sizeof(tANI_U32)); + buf += sizeof(tANI_U32); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + profile->MDID.mdiePresent = bss_description->mdiePresent; + if (csrIsProfile11r(profile) +#ifdef FEATURE_WLAN_ESE + && !((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) && + (ies->ESEVersion.present) && + (mac->roam.configParam.isEseIniFeatureEnabled)) +#endif + ) + { + /* is11Rconnection */ + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)) ; + buf += sizeof(tAniBool); + } + else + { + /* is11Rconnection */ + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } +#endif +#ifdef FEATURE_WLAN_ESE + + /* isESEFeatureIniEnabled */ + if (TRUE == mac->roam.configParam.isEseIniFeatureEnabled) + { + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + else + { + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + + /* A profile can not be both ESE and 11R. But an 802.11R AP + * may be advertising support for ESE as well. So if we are + * associating Open or explicitly ESE then we will get ESE. + * If we are associating explictly 11R only then we will get + * 11R. + */ + if ((csrIsProfileESE(profile) || + ((ies->ESEVersion.present) + && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (profile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (profile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN_PSK)))) + && (mac->roam.configParam.isEseIniFeatureEnabled)) + { + /* isESEconnection */ + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + else + { + /* isESEconnection */ + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + + if (eWNI_SME_JOIN_REQ == message_type) + { + tESETspecInfo eseTspec; + /* + * ESE-Tspec IEs in the ASSOC request is presently not supported + * so nullify the TSPEC parameters + */ + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo)); + buf += sizeof(tESETspecInfo); + } + else if (eWNI_SME_REASSOC_REQ == message_type) + { + if ((csrIsProfileESE(profile) || + ((ies->ESEVersion.present) + && ((profile->negotiatedAuthType == eCSR_AUTH_TYPE_OPEN_SYSTEM) + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA) + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_WPA_PSK) + || (profile->negotiatedAuthType == eCSR_AUTH_TYPE_RSN) +#ifdef WLAN_FEATURE_11W + || (profile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_PSK_SHA256) + || (profile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_8021X_SHA256) +#endif + || (profile->negotiatedAuthType == + eCSR_AUTH_TYPE_RSN_PSK)))) + && (mac->roam.configParam.isEseIniFeatureEnabled)) + { + tESETspecInfo eseTspec; + /* ESE Tspec information */ + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + eseTspec.numTspecs = sme_QosESERetrieveTspecInfo(mac, session_id, + (tTspecInfo *) &eseTspec.tspec[0]); + *buf = eseTspec.numTspecs; + buf += sizeof(tANI_U8); + // Copy the TSPEC information only if present + if (eseTspec.numTspecs) { + vos_mem_copy(buf, (void*)&eseTspec.tspec[0], + (eseTspec.numTspecs*sizeof(tTspecInfo))); + } + buf += sizeof(eseTspec.tspec); + } + else + { + tESETspecInfo eseTspec; + /* + * ESE-Tspec IEs in the ASSOC request is presently + * not supported so nullify the TSPEC parameters + */ + vos_mem_set(&eseTspec, sizeof(tESETspecInfo), 0); + vos_mem_copy(buf, &eseTspec, sizeof(tESETspecInfo)); + buf += sizeof(tESETspecInfo); + } + } +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + /* Fill in isFastTransitionEnabled */ + if (mac->roam.configParam.isFastTransitionEnabled +#ifdef FEATURE_WLAN_LFR + || csrRoamIsFastRoamEnabled(mac, session_id) +#endif + ) + { + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + else + { + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } +#endif +#ifdef FEATURE_WLAN_LFR + if(csrRoamIsFastRoamEnabled(mac, session_id)) + { + /* legacy fast roaming enabled */ + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + else + { + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } +#endif + + /* txLdpcIniFeatureEnabled */ + *buf = (tANI_U8)mac->roam.configParam.txLdpcEnable; + buf++; + + if ((csrIs11hSupported(mac)) && + (CSR_IS_CHANNEL_5GHZ(bss_description->channelId)) && + (ies->Country.present) &&\ + (!mac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + csrSaveToChannelPower2G_5G(mac, + ies->Country.num_triplets * sizeof(tSirMacChanInfo), + (tSirMacChanInfo *)(&ies->Country.triplets[0])); + csrApplyPower2Current(mac); + } + +#ifdef WLAN_FEATURE_11AC + /* txBFIniFeatureEnabled */ + *buf = (tANI_U8)mac->roam.configParam.txBFEnable; + buf++; + + /* txBFCsnValue */ + if (IS_BSS_VHT_CAPABLE(ies->VHTCaps)) + { + tx_bf_csn_value = (tANI_U8)mac->roam.configParam.txBFCsnValue; + if (ies->VHTCaps.numSoundingDim) + tx_bf_csn_value = CSR_ROAM_MIN + (tx_bf_csn_value, ies->VHTCaps.numSoundingDim); + } + *buf = tx_bf_csn_value; + buf++; + + /* Only enable MuBf if no other MuBF session exist + * and FW and HOST is MuBF capable. + */ + if (IS_MUMIMO_BFORMEE_CAPABLE && (FALSE == mac->isMuBfsessionexist)) + { + *buf = (tANI_U8)mac->roam.configParam.txMuBformee; + buf++; + } + else + { + *buf = 0; + buf++; + } +#endif + *buf = (tANI_U8)mac->roam.configParam.isAmsduSupportInAMPDU; + buf++; + + /* WME */ + if(mac->roam.roamSession[session_id].fWMMConnection) + { + /* WME enabled */ + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + else + { + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + + /* QOS */ + if(mac->roam.roamSession[session_id].fQOSConnection) + { + /* QOS enabled */ + dw_tmp = pal_cpu_to_be32(TRUE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + else + { + dw_tmp = pal_cpu_to_be32(FALSE); + vos_mem_copy(buf, &dw_tmp, sizeof(tAniBool)); + buf += sizeof(tAniBool); + } + /* BssDesc */ + csrPrepareJoinReassocReqBuffer(mac, bss_description, buf, + (tANI_U8)profile->uapsd_mask); + } while( 0 ); + + smsLog(mac, LOG1, FL("status %d"), status); + + vos_mem_free(profile); + return status; +} +#endif + +// +eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDisassocReq *pMsg; + tANI_U8 *pBuf; + tANI_U16 wTmp; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + return eHAL_STATUS_FAILURE; + do { + pMsg = vos_mem_malloc(sizeof(tSirSmeDisassocReq)); + if (NULL == pMsg) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDisassocReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DISASSOC_REQ); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDisassocReq )); + pBuf = &pMsg->sessionId; + // sessionId + *pBuf++ = (tANI_U8)sessionId; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + + if ( (pSession->pCurRoamProfile != NULL) && + ((CSR_IS_INFRA_AP(pSession->pCurRoamProfile)) || + (CSR_IS_WDS_AP(pSession->pCurRoamProfile))) ) + { + // Set the bssid address before sending the message to LIM + vos_mem_copy((tSirMacAddr *)pBuf, pSession->selfMacAddr, + sizeof( tSirMacAddr )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + // Set the peer MAC address before sending the message to LIM + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof( tSirMacAddr )); + //perMacAddr is passed as bssId for softAP + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + } + else + { + // Set the peer MAC address before sending the message to LIM + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof( tSirMacAddr )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof( pMsg->bssId )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + } + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + // reasonCode + wTmp = pal_cpu_to_be16(reasonCode); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + pBuf += sizeof(tANI_U16); + /* The state will be DISASSOC_HANDOFF only when we are doing handoff. + Here we should not send the disassoc over the air to the AP */ + if ( CSR_IS_ROAM_SUBSTATE_DISASSOC_HO(pMac, sessionId) +#ifdef WLAN_FEATURE_VOWIFI_11R + && csrRoamIs11rAssoc(pMac) +#endif + ) + { + *pBuf = CSR_DONT_SEND_DISASSOC_OVER_THE_AIR; /* Set DoNotSendOverTheAir flag to 1 only for handoff case */ + } + pBuf += sizeof(tANI_U8); + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} +eHalStatus csrSendMBTkipCounterMeasuresReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN bEnable, tSirMacAddr bssId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeTkipCntrMeasReq *pMsg; + tANI_U8 *pBuf; + do + { + pMsg = vos_mem_malloc(sizeof( tSirSmeTkipCntrMeasReq )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeTkipCntrMeasReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_TKIP_CNTR_MEAS_REQ); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeTkipCntrMeasReq )); + pBuf = &pMsg->sessionId; + // sessionId + *pBuf++ = (tANI_U8)sessionId; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + // bssid + vos_mem_copy(pMsg->bssId, bssId, sizeof( tSirMacAddr )); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof ( tSirMacAddr ); + // bEnable + *pBuf = (tANI_BOOLEAN)bEnable; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} +eHalStatus +csrSendMBGetAssociatedStasReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, + VOS_MODULE_ID modId, tSirMacAddr bssId, + void *pUsrContext, void *pfnSapEventCallback, + tANI_U8 *pAssocStasBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeGetAssocSTAsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + tANI_U32 dwTmp; + do + { + pMsg = vos_mem_malloc(sizeof( tSirSmeGetAssocSTAsReq )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + vos_mem_set(pMsg, sizeof( tSirSmeGetAssocSTAsReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_ASSOC_STAS_REQ); + pBuf = (tANI_U8 *)&pMsg->bssId; + wTmpBuf = pBuf; + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // modId + dwTmp = pal_cpu_to_be16((tANI_U16)modId); + vos_mem_copy(pBuf, (tANI_U8 *)&dwTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + // pUsrContext + vos_mem_copy(pBuf, (tANI_U8 *)pUsrContext, sizeof(void *)); + pBuf += sizeof(void*); + // pfnSapEventCallback + vos_mem_copy(pBuf, (tANI_U8 *)pfnSapEventCallback, sizeof(void*)); + pBuf += sizeof(void*); + // pAssocStasBuf + vos_mem_copy(pBuf, pAssocStasBuf, sizeof(void*)); + pBuf += sizeof(void*); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)));//msg_header + msg + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); + } +eHalStatus +csrSendMBGetWPSPBCSessions( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr bssId, void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac) + { + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeGetWPSPBCSessionsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + + do + { + pMsg = vos_mem_malloc(sizeof(tSirSmeGetWPSPBCSessionsReq)); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) break; + vos_mem_set(pMsg, sizeof( tSirSmeGetWPSPBCSessionsReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_WPSPBC_SESSION_REQ); + pBuf = (tANI_U8 *)&pMsg->pUsrContext; + VOS_ASSERT(pBuf); + + wTmpBuf = pBuf; + // pUsrContext + vos_mem_copy(pBuf, (tANI_U8 *)pUsrContext, sizeof(void*)); + pBuf += sizeof(void *); + // pSapEventCallback + vos_mem_copy(pBuf, (tANI_U8 *)pfnSapEventCallback, sizeof(void *)); + pBuf += sizeof(void *); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, bssId, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // MAC Address of STA in WPS session + vos_mem_copy((tSirMacAddr *)pBuf, pRemoveMac.bytes, sizeof(v_MACADDR_t)); + pBuf += sizeof(v_MACADDR_t); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)));//msg_header + msg + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus +csrSendChngMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tpSirChangeBIParams pMsg; + tANI_U16 len = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + //NO need to update the Beacon Params if update beacon parameter flag is not set + if(!pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval ) + return eHAL_STATUS_SUCCESS; + + pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_FALSE; + + /* Create the message and send to lim */ + len = sizeof(tSirChangeBIParams); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, sizeof(tSirChangeBIParams), 0); + pMsg->messageType = eWNI_SME_CHNG_MCC_BEACON_INTERVAL; + pMsg->length = len; + + // bssId + vos_mem_copy((tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + smsLog( pMac, LOG1, FL("CSR Attempting to change BI for Bssid= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->bssId)); + pMsg->sessionId = sessionId; + smsLog(pMac, LOG1, FL(" session %d BeaconInterval %d"), sessionId, pMac->roam.roamSession[sessionId].bssParams.beaconInterval); + pMsg->beaconInterval = pMac->roam.roamSession[sessionId].bssParams.beaconInterval; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + return status; +} + +#ifdef WLAN_FEATURE_AP_HT40_24G +eHalStatus csrSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 cbMode) +{ + tpSirSetHT2040Mode pMsg; + tANI_U16 len = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + /* Create the message and send to lim */ + len = sizeof(tSirSetHT2040Mode); + pMsg = vos_mem_malloc(len); + + if ( NULL == pMsg ) + { + smsLog( pMac, LOGE, FL("Memory Allocation Fail !!!")); + status = eHAL_STATUS_FAILURE; + } + else + status = eHAL_STATUS_SUCCESS; + + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, sizeof(tSirSetHT2040Mode), 0); + pMsg->messageType = eWNI_SME_SET_HT_2040_MODE; + pMsg->length = len; + + // bssId + vos_mem_copy((tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + + smsLog( pMac, LOGW, FL("CSR Attempting to set " + "HT20/40 mode for Bssid= "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->bssId)); + + pMsg->sessionId = sessionId; + pMsg->cbMode = cbMode; + + smsLog(pMac, LOGW, FL("session %d Channel Bonding: %d"), + sessionId, cbMode); + + status = palSendMBMessage(pMac->hHdd, pMsg); + } + return status; +} +#endif + +eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDeauthReq *pMsg; + tANI_U8 *pBuf; + tANI_U16 wTmp; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + return eHAL_STATUS_FAILURE; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeDeauthReq )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDeauthReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEAUTH_REQ); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDeauthReq )); + //sessionId + pBuf = &pMsg->sessionId; + *pBuf++ = (tANI_U8)sessionId; + + //tansactionId + *pBuf = 0; + *(pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + if ((pSession->pCurRoamProfile != NULL) && ( + (CSR_IS_INFRA_AP(pSession->pCurRoamProfile)) || + (CSR_IS_WDS_AP(pSession->pCurRoamProfile)))){ + // Set the BSSID before sending the message to LIM + vos_mem_copy( (tSirMacAddr *)pBuf, pSession->selfMacAddr, + sizeof( pMsg->peerMacAddr ) ); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof(tSirMacAddr); + } + else + { + // Set the BSSID before sending the message to LIM + vos_mem_copy( (tSirMacAddr *)pBuf, bssId, sizeof( pMsg->peerMacAddr ) ); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof(tSirMacAddr); + } + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + // Set the peer MAC address before sending the message to LIM + vos_mem_copy( (tSirMacAddr *) pBuf, bssId, sizeof( pMsg->peerMacAddr ) ); + status = eHAL_STATUS_SUCCESS; + pBuf = pBuf + sizeof(tSirMacAddr); + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + wTmp = pal_cpu_to_be16(reasonCode); + vos_mem_copy( pBuf, &wTmp,sizeof( tANI_U16 ) ); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDisassocCnf *pMsg; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeDisassocCnf )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDisassocCnf), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DISASSOC_CNF); + pMsg->statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDisassocCnf )); + pMsg->assocId = pal_cpu_to_be16((tANI_U16)pDisassocInd->assocId); + vos_mem_copy(pMsg->peerMacAddr, pDisassocInd->peerMacAddr, + sizeof(pMsg->peerMacAddr)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } +//To test reconn + vos_mem_copy(pMsg->bssId, pDisassocInd->bssId, sizeof(pMsg->peerMacAddr)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } +//To test reconn ends + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeDeauthCnf *pMsg; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeDeauthCnf )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeDeauthCnf ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEAUTH_CNF); + pMsg->statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeDeauthCnf )); + pMsg->assocId = pal_cpu_to_be16((tANI_U16)pDeauthInd->assocId); + vos_mem_copy(pMsg->bssId, pDeauthInd->bssId, sizeof(pMsg->bssId)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + vos_mem_copy(pMsg->peerMacAddr, pDeauthInd->peerMacAddr, + sizeof(pMsg->peerMacAddr)); + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(pMsg); + break; + } + status = palSendMBMessage( pMac->hHdd, pMsg ); + } while( 0 ); + return( status ); +} +eHalStatus csrSendAssocCnfMsg( tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd, eHalStatus Halstatus ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeAssocCnf *pMsg; + tANI_U8 *pBuf; + tSirResultCodes statusCode; + tANI_U16 wTmp; + + smsLog( pMac, LOG1, FL("Posting eWNI_SME_ASSOC_CNF to LIM. " + "HalStatus : %d"), + Halstatus); + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeAssocCnf )); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( !HAL_STATUS_SUCCESS(status) ) break; + vos_mem_set(pMsg, sizeof( tSirSmeAssocCnf ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_ASSOC_CNF); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeAssocCnf )); + pBuf = (tANI_U8 *)&pMsg->statusCode; + if(HAL_STATUS_SUCCESS(Halstatus)) + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + else + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_ASSOC_REFUSED); + vos_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes)); + pBuf += sizeof(tSirResultCodes); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + status = eHAL_STATUS_SUCCESS; + pBuf += sizeof (tSirMacAddr); + // peerMacAddr + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + status = eHAL_STATUS_SUCCESS; + pBuf += sizeof (tSirMacAddr); + // aid + wTmp = pal_cpu_to_be16(pAssocInd->aid); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof (tANI_U16); + // alternateBssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + status = eHAL_STATUS_SUCCESS; + pBuf += sizeof (tSirMacAddr); + // alternateChannelId + *pBuf = 11; + status = palSendMBMessage( pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + //pMsg is freed by palSendMBMessage + break; + } + } while( 0 ); + return( status ); +} +eHalStatus csrSendAssocIndToUpperLayerCnfMsg( tpAniSirGlobal pMac, + tpSirSmeAssocInd pAssocInd, + eHalStatus Halstatus, + tANI_U8 sessionId) +{ + tSirMsgQ msgQ; + tSirSmeAssocIndToUpperLayerCnf *pMsg; + tANI_U8 *pBuf; + tSirResultCodes statusCode; + tANI_U16 wTmp; + do { + pMsg = vos_mem_malloc(sizeof( tSirSmeAssocIndToUpperLayerCnf )); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof( tSirSmeAssocIndToUpperLayerCnf ), 0); + + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_UPPER_LAYER_ASSOC_CNF); + pMsg->length = pal_cpu_to_be16((tANI_U16)sizeof( tSirSmeAssocIndToUpperLayerCnf )); + + pMsg->sessionId = sessionId; + + pBuf = (tANI_U8 *)&pMsg->statusCode; + if(HAL_STATUS_SUCCESS(Halstatus)) + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_SUCCESS); + else + statusCode = (tSirResultCodes)pal_cpu_to_be32(eSIR_SME_ASSOC_REFUSED); + vos_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes)) ; + pBuf += sizeof(tSirResultCodes); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof (tSirMacAddr); + // peerMacAddr + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr, + sizeof(tSirMacAddr)); + pBuf += sizeof (tSirMacAddr); + // StaId + wTmp = pal_cpu_to_be16(pAssocInd->staId); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof (tANI_U16); + // alternateBssId + vos_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId, sizeof(tSirMacAddr)); + pBuf += sizeof (tSirMacAddr); + // alternateChannelId + *pBuf = 11; + pBuf += sizeof (tANI_U8); + // Instead of copying roam Info, we just copy only WmmEnabled, RsnIE information + //Wmm + *pBuf = pAssocInd->wmmEnabledSta; + pBuf += sizeof (tANI_U8); + //RSN IE + vos_mem_copy((tSirRSNie *)pBuf, &pAssocInd->rsnIE, sizeof(tSirRSNie)); + pBuf += sizeof (tSirRSNie); + //Additional IE + vos_mem_copy((void *)pBuf, &pAssocInd->addIE, sizeof(tSirAddie)); + pBuf += sizeof (tSirAddie); + //reassocReq + *pBuf = pAssocInd->reassocReq; + pBuf += sizeof (tANI_U8); +#ifdef WLAN_FEATURE_AP_HT40_24G + // 40 MHz Intolerant + *pBuf = pAssocInd->HT40MHzIntoEnabledSta; + pBuf += sizeof (tANI_U8); +#endif + *pBuf = pAssocInd->rate_flags; + pBuf += sizeof (uint32_t); + msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF; + msgQ.bodyptr = pMsg; + msgQ.bodyval = 0; + SysProcessMmhMsg(pMac, &msgQ); + } while( 0 ); + return( eHAL_STATUS_SUCCESS ); +} + +eHalStatus csrSendMBSetContextReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr peerMacAddr, tANI_U8 numKeys, tAniEdType edType, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U8 keyLength, tANI_U8 *pKey, tANI_U8 paeRole, + tANI_U8 *pKeyRsc ) +{ + tSirSmeSetContextReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + tAniEdType tmpEdType; + tAniKeyDirection tmpDirection; + tANI_U8 *pBuf = NULL; + tANI_U8 *p = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + smsLog( pMac, LOG1, FL("keylength is %d, Encry type is : %d"), + keyLength, edType); + do { + if( ( 1 != numKeys ) && ( 0 != numKeys ) ) break; + // all of these fields appear in every SET_CONTEXT message. Below we'll add in the size for each + // key set. Since we only support upto one key, we always allocate memory for 1 key + msgLen = sizeof( tANI_U16) + sizeof( tANI_U16 ) + sizeof( tSirMacAddr ) + + sizeof( tSirMacAddr ) + 1 + sizeof(tANI_U16) + + sizeof( pMsg->keyMaterial.length ) + sizeof( pMsg->keyMaterial.edType ) + sizeof( pMsg->keyMaterial.numKeys ) + + ( sizeof( pMsg->keyMaterial.key ) ); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SETCONTEXT_REQ); + pMsg->length = pal_cpu_to_be16(msgLen); + //sessionId + pBuf = &pMsg->sessionId; + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += sizeof(tANI_U16); + // peerMacAddr + vos_mem_copy(pBuf, (tANI_U8 *)peerMacAddr, sizeof(tSirMacAddr)); + + pBuf += sizeof(tSirMacAddr); + + // bssId + vos_mem_copy(pBuf, (tANI_U8 *)&pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + pBuf += sizeof(tSirMacAddr); + + p = pBuf; + // Set the pMsg->keyMaterial.length field (this length is defined as all data that follows the edType field + // in the tSirKeyMaterial keyMaterial; field). + // + // !!NOTE: This keyMaterial.length contains the length of a MAX size key, though the keyLength can be + // shorter than this max size. Is LIM interpreting this ok ? + p = pal_set_U16( p, pal_cpu_to_be16((tANI_U16)( sizeof( pMsg->keyMaterial.numKeys ) + ( numKeys * sizeof( pMsg->keyMaterial.key ) ) )) ); + // set pMsg->keyMaterial.edType + tmpEdType = (tAniEdType)pal_cpu_to_be32(edType); + vos_mem_copy(p, (tANI_U8 *)&tmpEdType, sizeof(tAniEdType)); + p += sizeof( pMsg->keyMaterial.edType ); + // set the pMsg->keyMaterial.numKeys field + *p = numKeys; + p += sizeof( pMsg->keyMaterial.numKeys ); + // set pSirKey->keyId = keyId; + *p = keyId; + p += sizeof( pMsg->keyMaterial.key[ 0 ].keyId ); + // set pSirKey->unicast = (tANI_U8)fUnicast; + *p = (tANI_U8)fUnicast; + p += sizeof( pMsg->keyMaterial.key[ 0 ].unicast ); + // set pSirKey->keyDirection = aniKeyDirection; + tmpDirection = (tAniKeyDirection)pal_cpu_to_be32(aniKeyDirection); + vos_mem_copy(p, (tANI_U8 *)&tmpDirection, sizeof(tAniKeyDirection)); + p += sizeof(tAniKeyDirection); + // pSirKey->keyRsc = ;; + vos_mem_copy(p, pKeyRsc, CSR_MAX_RSC_LEN); + p += sizeof( pMsg->keyMaterial.key[ 0 ].keyRsc ); + // set pSirKey->paeRole + *p = paeRole; // 0 is Supplicant + p++; + // set pSirKey->keyLength = keyLength; + p = pal_set_U16( p, pal_cpu_to_be16(keyLength) ); + if ( keyLength && pKey ) + vos_mem_copy(p, pKey, keyLength); + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBStartBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamBssType bssType, + tCsrRoamStartBssParams *pParam, tSirBssDescription *pBssDesc ) +{ + eHalStatus status; + tSirSmeStartBssReq *pMsg; + tANI_U8 *pBuf = NULL; + tANI_U8 *wTmpBuf = NULL; + tANI_U16 msgLen, wTmp; + tANI_U32 dwTmp; + tSirNwType nwType; + ePhyChanBondState cbMode; + tANI_U32 authType; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do { + pSession->joinFailStatusCode.statusCode = eSIR_SME_SUCCESS; + pSession->joinFailStatusCode.reasonCode = 0; + msgLen = sizeof(tSirSmeStartBssReq); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_START_BSS_REQ); + pBuf = &pMsg->sessionId; + wTmpBuf = pBuf; + //sessionId + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + *(pBuf + 1) = 0; + pBuf += sizeof(tANI_U16); + // bssid + vos_mem_copy(pBuf, pParam->bssid, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // selfMacAddr + vos_mem_copy(pBuf, pSession->selfMacAddr, sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // beaconInterval + if( pBssDesc && pBssDesc->beaconInterval ) + { + wTmp = pal_cpu_to_be16( pBssDesc->beaconInterval ); + } + else if(pParam->beaconInterval) + { + wTmp = pal_cpu_to_be16( pParam->beaconInterval ); + } + else + { + wTmp = pal_cpu_to_be16( WNI_CFG_BEACON_INTERVAL_STADEF ); + } + if(csrIsconcurrentsessionValid (pMac, sessionId, + pParam->bssPersona) + == eHAL_STATUS_SUCCESS ) + { + csrValidateMCCBeaconInterval(pMac, pParam->operationChn, &wTmp, sessionId, + pParam->bssPersona); + //Update the beacon Interval + pParam->beaconInterval = wTmp; + } + else + { + smsLog( pMac,LOGE, FL("****Start BSS failed persona already exists***")); + status = eHAL_STATUS_FAILURE; + vos_mem_free(pMsg); + return status; + } + + vos_mem_copy(pBuf, &wTmp, sizeof( tANI_U16 )); + pBuf += sizeof(tANI_U16); + // dot11mode + *pBuf = (tANI_U8)csrTranslateToWNICfgDot11Mode( pMac, pParam->uCfgDot11Mode ); + pBuf += 1; + // bssType + dwTmp = pal_cpu_to_be32( csrTranslateBsstypeToMacType( bssType ) ); + vos_mem_copy(pBuf, &dwTmp, sizeof(tSirBssType)); + pBuf += sizeof(tSirBssType); + // ssId + if( pParam->ssId.length ) + { + // ssId len + *pBuf = pParam->ssId.length; + pBuf++; + vos_mem_copy(pBuf, pParam->ssId.ssId, pParam->ssId.length); + pBuf += pParam->ssId.length; + } + else + { + *pBuf = 0; + pBuf++; + } + // set the channel Id + *pBuf = pParam->operationChn; + pBuf++; + //What should we really do for the cbmode. + cbMode = (ePhyChanBondState)pal_cpu_to_be32(pParam->cbMode); + vos_mem_copy(pBuf, (tANI_U8 *)&cbMode, sizeof(ePhyChanBondState)); + pBuf += sizeof(ePhyChanBondState); + + // Set privacy + *pBuf = pParam->privacy; + pBuf++; + + //Set Uapsd + *pBuf = pParam->ApUapsdEnable; + pBuf++; + //Set SSID hidden + *pBuf = pParam->ssidHidden; + pBuf++; + *pBuf = (tANI_U8)pParam->fwdWPSPBCProbeReq; + pBuf++; + + //Ht protection Enable/Disable + *pBuf = (tANI_U8)pParam->protEnabled; + pBuf++; + //Enable Beacons to Receive for OBSS protection Enable/Disable + *pBuf = (tANI_U8)pParam->obssProtEnabled; + pBuf++; + //set cfg related to protection + wTmp = pal_cpu_to_be16( pParam->ht_protection ); + vos_mem_copy(pBuf, &wTmp, sizeof( tANI_U16 )); + pBuf += sizeof(tANI_U16); + // Set Auth type + authType = pal_cpu_to_be32(pParam->authType); + vos_mem_copy(pBuf, (tANI_U8 *)&authType, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); + // Set DTIM + dwTmp = pal_cpu_to_be32(pParam->dtimPeriod); + vos_mem_copy(pBuf, (tANI_U8 *)&dwTmp, sizeof(tANI_U32)); + pBuf += sizeof(tANI_U32); + // Set wps_state + *pBuf = pParam->wps_state; + pBuf++; + // set isCoalesingInIBSSAllowed + *pBuf = pMac->isCoalesingInIBSSAllowed; + pBuf++; + //Persona + *pBuf = (tANI_U8)pParam->bssPersona; + pBuf++; + + //txLdpcIniFeatureEnabled + *pBuf = (tANI_U8)(tANI_U8)pMac->roam.configParam.txLdpcEnable; + pBuf++; + +#ifdef WLAN_FEATURE_11W + // Set MFP capable/required + *pBuf = (tANI_U8)pParam->mfpCapable; + pBuf++; + *pBuf = (tANI_U8)pParam->mfpRequired; + pBuf++; +#endif + + // set RSN IE + if( pParam->nRSNIELength > sizeof(pMsg->rsnIE.rsnIEdata) ) + { + status = eHAL_STATUS_INVALID_PARAMETER; + vos_mem_free(pMsg); + break; + } + wTmp = pal_cpu_to_be16( pParam->nRSNIELength ); + vos_mem_copy(pBuf, &wTmp, sizeof(tANI_U16)); + pBuf += sizeof(tANI_U16); + if( wTmp ) + { + wTmp = pParam->nRSNIELength; + vos_mem_copy(pBuf, pParam->pRSNIE, wTmp); + pBuf += wTmp; + } + nwType = (tSirNwType)pal_cpu_to_be32(pParam->sirNwType); + vos_mem_copy(pBuf, (tANI_U8 *)&nwType, sizeof(tSirNwType)); + pBuf += sizeof(tSirNwType); + *pBuf = pParam->operationalRateSet.numRates; //tSirMacRateSet->numRates + pBuf++; + vos_mem_copy(pBuf, pParam->operationalRateSet.rate, + pParam->operationalRateSet.numRates ); + pBuf += pParam->operationalRateSet.numRates ; + *pBuf++ = pParam->extendedRateSet.numRates; + if(0 != pParam->extendedRateSet.numRates) + { + vos_mem_copy(pBuf, pParam->extendedRateSet.rate, + pParam->extendedRateSet.numRates); + pBuf += pParam->extendedRateSet.numRates; + } +#ifdef WLAN_FEATURE_AP_HT40_24G + *pBuf++ = (tANI_U8)pMac->roam.configParam.apHT40_24GEnabled; +#endif + + msgLen = (tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)); //msg_header + msg + pMsg->length = pal_cpu_to_be16(msgLen); + + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} + +eHalStatus csrSendMBStopBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirSmeStopBssReq *pMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U8 *pBuf; + tANI_U16 msgLen; + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tSirSmeStopBssReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof( tSirSmeStopBssReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_STOP_BSS_REQ); + pBuf = &pMsg->sessionId; + //sessionId + *pBuf = (tANI_U8)sessionId; + pBuf++; + // transactionId + *pBuf = 0; + pBuf += sizeof(tANI_U16); + //reason code + *pBuf = 0; + pBuf += sizeof(tSirResultCodes); + // bssid + // if BSSType is WDS sta, use selfmacAddr as bssid, else use bssid in connectedProfile + if( CSR_IS_CONN_WDS_STA(&pSession->connectedProfile) ) + { + vos_mem_copy(pBuf, (tANI_U8 *)&pSession->selfMacAddr, + sizeof(tSirMacAddr)); + } + else + { + vos_mem_copy(pBuf, (tANI_U8 *)&pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + } + pBuf += sizeof(tSirMacAddr); + msgLen = sizeof(tANI_U16) + sizeof(tANI_U16) + 1 + sizeof(tANI_U16) + sizeof(tSirResultCodes) + sizeof(tSirMacAddr); + pMsg->length = pal_cpu_to_be16(msgLen); + status = palSendMBMessage( pMac->hHdd, pMsg ); + + return( status ); +} + +eHalStatus csrReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 roamId = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if((csrIsConnStateConnected(pMac, sessionId)) && + (fForce || (!vos_mem_compare( &pModProfileFields, + &pSession->connectedProfile.modifyProfileFields, + sizeof(tCsrRoamModifyProfileFields)))) ) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + status = csrRoamIssueReassoc(pMac, sessionId, NULL, pModProfileFields, + eCsrSmeIssuedReassocToSameAP, roamId, + eANI_BOOLEAN_FALSE); + } + return status; +} +static eHalStatus csrRoamSessionOpened(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo roamInfo; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + status = csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, + eCSR_ROAM_SESSION_OPENED, eCSR_ROAM_RESULT_NONE); + return (status); +} +eHalStatus csrProcessAddStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirSmeAddStaSelfRsp *pRsp; + do + { + if(pMsg == NULL) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if(pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandAddStaSession == pCommand->command) + { + pRsp = (tSirSmeAddStaSelfRsp*)pMsg; + smsLog( pMac, LOG1, "Add Sta rsp status = %d", pRsp->status ); + if (pRsp->status == eSIR_FAILURE) { + VOS_ASSERT( 0 ); + } + //Nothing to be done. May be indicate the self sta addition success by calling session callback (TODO). + csrRoamSessionOpened(pMac, pCommand->sessionId); + //Remove this command out of the active list + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK)) + { + //Now put this command back on the avilable command list + csrReleaseCommand(pMac, pCommand); + } + smeProcessPendingQueue( pMac ); + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_ADD_STA_SELF_RSP Received but NO Add sta session command are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_ADD_STA_SELF_RSP Received but NO commands are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } while(0); + return status; +} +eHalStatus csrSendMBAddSelfStaReqMsg(tpAniSirGlobal pMac, + tAddStaForSessionCmd *pAddStaReq) +{ + tSirSmeAddStaSelfReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + do { + msgLen = sizeof(tSirSmeAddStaSelfReq); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) break; + vos_mem_set(pMsg, msgLen, 0); + pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_ADD_STA_SELF_REQ); + pMsg->mesgLen = pal_cpu_to_be16(msgLen); + // self station address + vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, + (tANI_U8 *)&pAddStaReq->selfMacAddr, sizeof(tSirMacAddr)); + + pMsg->currDeviceMode = pAddStaReq->currDeviceMode; + + smsLog( pMac, LOG1, FL("selfMac="MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pMsg->selfMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} +eHalStatus csrIssueAddStaForSessionReq(tpAniSirGlobal pMac, + tANI_U32 sessionId, + tSirMacAddr sessionMacAddr) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + status = eHAL_STATUS_RESOURCES; + } + else + { + pCommand->command = eSmeCommandAddStaSession; + pCommand->sessionId = (tANI_U8)sessionId; + vos_mem_copy(pCommand->u.addStaSessionCmd.selfMacAddr, sessionMacAddr, + sizeof( tSirMacAddr ) ); + pCommand->u.addStaSessionCmd.currDeviceMode = pMac->sme.currDeviceMode; + status = csrQueueSmeCommand(pMac, pCommand, TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + //Should be panic?? + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + } + } + return (status); +} +eHalStatus csrProcessAddStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + return csrSendMBAddSelfStaReqMsg(pMac, &pCommand->u.addStaSessionCmd); +} +eHalStatus csrRoamOpenSession(tpAniSirGlobal pMac, + csrRoamCompleteCallback callback, + void *pContext, tANI_U8 *pSelfMacAddr, + tANI_U8 *pbSessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 i; + tCsrRoamSession *pSession = NULL; + *pbSessionId = CSR_SESSION_ID_INVALID; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( !CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + status = eHAL_STATUS_SUCCESS; + pSession->sessionActive = eANI_BOOLEAN_TRUE; + pSession->sessionId = (tANI_U8)i; + pSession->callback = callback; + pSession->pContext = pContext; + vos_mem_copy(&pSession->selfMacAddr, pSelfMacAddr, sizeof(tCsrBssid)); + *pbSessionId = (tANI_U8)i; + status = vos_timer_init(&pSession->hTimerRoaming, VOS_TIMER_TYPE_SW, + csrRoamRoamingTimerHandler, + &pSession->roamingTimerInfo); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for Roaming timer")); + break; + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + status = vos_timer_init(&pSession->hTimerJoinRetry, VOS_TIMER_TYPE_SW, + csrRoamJoinRetryTimerHandler, + &pSession->joinRetryTimerInfo); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for joinretry timer")); + break; + } +#endif + status = csrIssueAddStaForSessionReq (pMac, i, pSelfMacAddr); + break; + } + } + if( CSR_ROAM_SESSION_MAX == i ) + { + //No session is available + status = eHAL_STATUS_RESOURCES; + } + return ( status ); +} +eHalStatus csrProcessDelStaSessionRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirSmeDelStaSelfRsp *pRsp; + do + { + if(pMsg == NULL) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if(pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandDelStaSession == pCommand->command) + { + tANI_U8 sessionId = pCommand->sessionId; + pRsp = (tSirSmeDelStaSelfRsp*)pMsg; + smsLog( pMac, LOG1, "Del Sta rsp status = %d", pRsp->status ); + //This session is done. + csrCleanupSession(pMac, sessionId); + if(pCommand->u.delStaSessionCmd.callback) + { + + status = sme_ReleaseGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pCommand->u.delStaSessionCmd.callback( + pCommand->u.delStaSessionCmd.pContext); + status = sme_AcquireGlobalLock( &pMac->sme ); + if (! HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGP, "%s: Failed to Acquire Lock", __func__); + return status; + } + } + else { + smsLog(pMac, LOGE, "%s: Failed to Release Lock", __func__); + } + } + + //Remove this command out of the active list + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK)) + { + //Now put this command back on the avilable command list + csrReleaseCommand(pMac, pCommand); + } + smeProcessPendingQueue( pMac ); + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_DEL_STA_SELF_RSP Received but NO Del sta session command are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_DEL_STA_SELF_RSP Received but NO commands are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } while(0); + return status; +} +eHalStatus csrSendMBDelSelfStaReqMsg( tpAniSirGlobal pMac, tSirMacAddr macAddr ) +{ + tSirSmeDelStaSelfReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + do { + msgLen = sizeof( tANI_U16 ) + sizeof( tANI_U16 ) + sizeof( tSirMacAddr ) /*+ + sizeof( tSirBssType )*/; + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, msgLen, 0); + pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEL_STA_SELF_REQ); + pMsg->mesgLen = pal_cpu_to_be16(msgLen); + // self station address + vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, (tANI_U8 *)macAddr, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} +eHalStatus csrIssueDelStaForSessionReq(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fHighPriority, + tSirMacAddr sessionMacAddr, + csrRoamSessionCloseCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + status = eHAL_STATUS_RESOURCES; + } + else + { + pCommand->command = eSmeCommandDelStaSession; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.delStaSessionCmd.callback = callback; + pCommand->u.delStaSessionCmd.pContext = pContext; + vos_mem_copy(pCommand->u.delStaSessionCmd.selfMacAddr, sessionMacAddr, + sizeof( tSirMacAddr )); + status = csrQueueSmeCommand(pMac, pCommand, fHighPriority); + if( !HAL_STATUS_SUCCESS( status ) ) + { + //Should be panic?? + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + } + } + return (status); +} +eHalStatus csrProcessDelStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + return csrSendMBDelSelfStaReqMsg( pMac, + pCommand->u.delStaSessionCmd.selfMacAddr ); +} +static void purgeCsrSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + bool flush_all) +{ + tDblLinkList *pList = &pMac->roam.roamCmdPendingList; + tListElem *pEntry, *pNext; + tSmeCmd *pCommand; + tDblLinkList localList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + csrLLLock(pList); + pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); + while(pEntry != NULL) + { + pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + if (!flush_all && + csr_is_disconnect_full_power_cmd(pCommand)) { + smsLog(pMac, LOGW, FL(" Ignore disconnect")); + pEntry = pNext; + continue; + } + if(pCommand->sessionId == sessionId) + { + if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + } + pEntry = pNext; + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + } + csrLLClose(&localList); +} + +void csrCleanupSession(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + csrRoamStop(pMac, sessionId); + csrFreeConnectBssDesc(pMac, sessionId); + csrRoamFreeConnectProfile( pMac, &pSession->connectedProfile ); + csrRoamFreeConnectedInfo ( pMac, &pSession->connectedInfo); + vos_timer_destroy(&pSession->hTimerRoaming); +#ifdef FEATURE_WLAN_BTAMP_UT_RF + vos_timer_destroy(&pSession->hTimerJoinRetry); +#endif + csrPurgeSmeCmdList(pMac, sessionId, true); + csrInitSession(pMac, sessionId); + } +} + +void csrPurgeSmeCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + bool flush_all) +{ + purgeSmeSessionCmdList(pMac, sessionId, + &pMac->sme.smeCmdPendingList, + flush_all); + if (pMac->fScanOffload) + { + purgeSmeSessionCmdList(pMac, sessionId, + &pMac->sme.smeScanCmdPendingList, + flush_all); + } + purgeCsrSessionCmdList(pMac, sessionId, + flush_all); +} + +eHalStatus csrRoamCloseSession( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fSync, tANI_U8 bPurgeList, + csrRoamSessionCloseCallback callback, + void *pContext ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if(fSync) + { + csrCleanupSession(pMac, sessionId); + } + else + { + csrPurgeSmeCmdList(pMac, sessionId, bPurgeList); + /* If bPurgeList is FALSE, it means HDD already free all the + * cmd and later queue few essential cmd. Now sme should process + * the cmd in pending queue order only.Hence we should + * avoid DEL_SELF_STA as high priority cmd. + */ + status = csrIssueDelStaForSessionReq( pMac, sessionId, bPurgeList, + pSession->selfMacAddr, callback, pContext); + } + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + return ( status ); +} + +static void csrInitSession( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + pSession->sessionActive = eANI_BOOLEAN_FALSE; + pSession->sessionId = CSR_SESSION_ID_INVALID; + pSession->callback = NULL; + pSession->pContext = NULL; + pSession->connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + // TODO : Confirm pMac->roam.fReadyForPowerSave = eANI_BOOLEAN_FALSE; + csrFreeRoamProfile( pMac, sessionId ); + csrRoamFreeConnectProfile(pMac, &pSession->connectedProfile); + csrRoamFreeConnectedInfo( pMac, &pSession->connectedInfo ); + csrFreeConnectBssDesc(pMac, sessionId); + csrScanEnable(pMac); + vos_mem_set(&pSession->selfMacAddr, sizeof(tCsrBssid), 0); + if (pSession->pWpaRsnReqIE) + { + vos_mem_free(pSession->pWpaRsnReqIE); + pSession->pWpaRsnReqIE = NULL; + } + pSession->nWpaRsnReqIeLength = 0; + if (pSession->pWpaRsnRspIE) + { + vos_mem_free(pSession->pWpaRsnRspIE); + pSession->pWpaRsnRspIE = NULL; + } + pSession->nWpaRsnRspIeLength = 0; +#ifdef FEATURE_WLAN_WAPI + if (pSession->pWapiReqIE) + { + vos_mem_free(pSession->pWapiReqIE); + pSession->pWapiReqIE = NULL; + } + pSession->nWapiReqIeLength = 0; + if (pSession->pWapiRspIE) + { + vos_mem_free(pSession->pWapiRspIE); + pSession->pWapiRspIE = NULL; + } + pSession->nWapiRspIeLength = 0; +#endif /* FEATURE_WLAN_WAPI */ + if (pSession->nAddIEScanLength) + { + memset(pSession->addIEScan, 0 , SIR_MAC_MAX_ADD_IE_LENGTH); + } + pSession->nAddIEScanLength = 0; + + if (pSession->pAddIEAssoc) + { + vos_mem_free(pSession->pAddIEAssoc); + pSession->pAddIEAssoc = NULL; + } + pSession->nAddIEAssocLength = 0; +} + +eHalStatus csrRoamGetSessionIdFromBSSID( tpAniSirGlobal pMac, tCsrBssid *bssid, tANI_U32 *pSessionId ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U32 i; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + if( csrIsMacAddressEqual( pMac, bssid, &pMac->roam.roamSession[i].connectedProfile.bssid ) ) + { + //Found it + status = eHAL_STATUS_SUCCESS; + *pSessionId = i; + break; + } + } + } + return( status ); +} + +//This function assumes that we only support one IBSS session. We cannot use BSSID to identify +//session because for IBSS, the bssid changes. +static tANI_U32 csrFindIbssSession( tpAniSirGlobal pMac ) +{ + tANI_U32 i, nRet = CSR_SESSION_ID_INVALID; + tCsrRoamSession *pSession; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + if( pSession->pCurRoamProfile && ( csrIsBssTypeIBSS( pSession->connectedProfile.BSSType ) ) ) + { + //Found it + nRet = i; + break; + } + } + } + return (nRet); +} +void csrRoamLinkUp(tpAniSirGlobal pMac, tCsrBssid bssid) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + /* Update the current BSS info in ho control block based on connected + profile info from pmac global structure */ + + smsLog(pMac, LOGW, " csrRoamLinkUp: WLAN link UP with AP= "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(bssid)); + /* Check for user misconfig of RSSI trigger threshold */ + pMac->roam.configParam.vccRssiThreshold = + ( 0 == pMac->roam.configParam.vccRssiThreshold ) ? + CSR_VCC_RSSI_THRESHOLD : pMac->roam.configParam.vccRssiThreshold; + pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; + /* Check for user misconfig of UL MAC Loss trigger threshold */ + pMac->roam.configParam.vccUlMacLossThreshold = + ( 0 == pMac->roam.configParam.vccUlMacLossThreshold ) ? + CSR_VCC_UL_MAC_LOSS_THRESHOLD : pMac->roam.configParam.vccUlMacLossThreshold; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + { + tANI_U32 sessionId = 0; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + /* Indicate the neighbor roal algorithm about the connect indication */ + csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)bssid, &sessionId); + csrNeighborRoamIndicateConnect(pMac, sessionId, VOS_STATUS_SUCCESS); + + /* Making sure we are roaming force fully to 5GHz AP only once and + * only when we connected to 2.4GH AP only during initial association. + */ + if(pNeighborRoamInfo->cfgParams.neighborInitialForcedRoamTo5GhEnable && + (GetRFBand(pNeighborRoamInfo->currAPoperationChannel) == + SIR_BAND_2_4_GHZ) + ) + { + status = vos_timer_start( + &pNeighborRoamInfo->forcedInitialRoamTo5GHTimer, + INITIAL_FORCED_ROAM_TO_5G_TIMER_PERIOD); + if ( status != VOS_STATUS_SUCCESS ) + { + smsLog(pMac, LOGE, + FL("forcedInitialRoamTo5GHTimer start failed status %d"), + status); + //Send RSO start because in case 5G roaming + //host have not enabled at initial connection + csrRoamOffloadScan(pMac,ROAM_SCAN_OFFLOAD_START,REASON_CONNECT); + } + else + { + smsLog(pMac, LOG1, FL("%s: Forced roam to 5G started Timer"), + __func__); + } + } + /* + * Making ini value to false here only so we just roam to + * only once for whole driver load to unload tenure + * This feature is only applicable for first connection only + */ + if(pNeighborRoamInfo->cfgParams.neighborInitialForcedRoamTo5GhEnable) + { + pNeighborRoamInfo->cfgParams.neighborInitialForcedRoamTo5GhEnable + = VOS_FALSE; + } + } +#endif +} + +static void csrRoamLinkDown(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return; + } + + //Only to handle the case for Handover on infra link + if( eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType ) + { + return; + } + /* deregister the clients requesting stats from PE/TL & also stop the corresponding timers*/ + csrRoamDeregStatisticsReq(pMac); + pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* Indicate the neighbor roal algorithm about the disconnect indication */ + csrNeighborRoamIndicateDisconnect(pMac, sessionId); +#endif + + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && + csrIsInfraApStarted( pMac ) && + pMac->roam.configParam.doBMPSWorkaround) + { + pMac->roam.configParam.doBMPSWorkaround = 0; + } +} + +void csrRoamTlStatsTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + eHalStatus status; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + + smsLog(pMac, LOG1, FL(" TL stat timer is no-op. It needs to support multiple stations")); + +#if 0 + // TODO Persession .??? + //req TL for stats + if(WLANTL_GetStatistics(pMac->roam.gVosContext, &tlStats, pMac->roam.connectedInfo.staId)) + { + smsLog(pMac, LOGE, FL("csrRoamTlStatsTimerHandler:couldn't get the stats from TL")); + } + else + { + //save in SME + csrRoamSaveStatsFromTl(pMac, tlStats); + } +#endif + if(!pMac->roam.tlStatsReqInfo.timerRunning) + { + if(pMac->roam.tlStatsReqInfo.periodicity) + { + //start timer + status = vos_timer_start(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, + pMac->roam.tlStatsReqInfo.periodicity); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamTlStatsTimerHandler:cannot start TlStatsTimer timer")); + return; + } + pMac->roam.tlStatsReqInfo.timerRunning = TRUE; + } + } +} +void csrRoamPeStatsTimerHandler(void *pv) +{ + tCsrPeStatsReqInfo *pPeStatsReqListEntry = (tCsrPeStatsReqInfo *)pv; + eHalStatus status; + tpAniSirGlobal pMac = pPeStatsReqListEntry->pMac; + VOS_STATUS vosStatus; + tPmcPowerState powerState; + pPeStatsReqListEntry->timerRunning = FALSE; + if( pPeStatsReqListEntry->timerStopFailed == TRUE ) + { + // If we entered here, meaning the timer could not be successfully + // stopped in csrRoamRemoveEntryFromPeStatsReqList(). So do it here. + + /* Destroy the timer */ + vosStatus = vos_timer_destroy( &pPeStatsReqListEntry->hPeStatsTimer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:failed to destroy hPeStatsTimer timer")); + } + + // Free the entry + vos_mem_free(pPeStatsReqListEntry); + pPeStatsReqListEntry = NULL; + } + else + { + if(!pPeStatsReqListEntry->rspPending) + { + status = csrSendMBStatsReqMsg(pMac, pPeStatsReqListEntry->statsMask & ~(1 << eCsrGlobalClassDStats), + pPeStatsReqListEntry->staId); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:failed to send down stats req to PE")); + } + else + { + pPeStatsReqListEntry->rspPending = TRUE; + } + } + + //send down a req + if(pPeStatsReqListEntry->periodicity && + (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pPeStatsReqListEntry->hPeStatsTimer))) + { + pmcQueryPowerState(pMac, &powerState, NULL, NULL); + if(ePMC_FULL_POWER == powerState) + { + if(pPeStatsReqListEntry->periodicity < pMac->roam.configParam.statsReqPeriodicity) + { + pPeStatsReqListEntry->periodicity = pMac->roam.configParam.statsReqPeriodicity; + } + } + else + { + if(pPeStatsReqListEntry->periodicity < pMac->roam.configParam.statsReqPeriodicityInPS) + { + pPeStatsReqListEntry->periodicity = pMac->roam.configParam.statsReqPeriodicityInPS; + } + } + //start timer + vosStatus = vos_timer_start( &pPeStatsReqListEntry->hPeStatsTimer, pPeStatsReqListEntry->periodicity ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamPeStatsTimerHandler:cannot start hPeStatsTimer timer")); + return; + } + pPeStatsReqListEntry->timerRunning = TRUE; + + } + + } +} +void csrRoamStatsClientTimerHandler(void *pv) +{ + tCsrStatsClientReqInfo *pStaEntry = (tCsrStatsClientReqInfo *)pv; + if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&pStaEntry->timer)) + { +#if 0 + // TODO Stats fix for multisession + //start the timer + vosStatus = vos_timer_start( &pStaEntry->timer, pStaEntry->periodicity ); + + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pStaEntry->pMac, LOGE, FL("csrGetStatistics:cannot start StatsClient timer")); + } +#endif + } +#if 0 + //send up the stats report + csrRoamReportStatistics(pStaEntry->pMac, pStaEntry->statsMask, pStaEntry->callback, + pStaEntry->staId, pStaEntry->pContext); +#endif +} + + + +eHalStatus csrSendMBStatsReqMsg( tpAniSirGlobal pMac, tANI_U32 statsMask, tANI_U8 staId) +{ + tAniGetPEStatsReq *pMsg; + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirMsgQ msgQ; + + pMsg = vos_mem_malloc(sizeof(tAniGetPEStatsReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL( "Failed to allocate mem for stats req ")); + return eHAL_STATUS_FAILURE; + } + // need to initiate a stats request to PE + pMsg->msgType = pal_cpu_to_be16((tANI_U16)WDA_GET_STATISTICS_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetPEStatsReq); + pMsg->staId = staId; + pMsg->statsMask = statsMask; + + msgQ.type = WDA_GET_STATISTICS_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pMsg; + msgQ.bodyval = 0; + status = wdaPostCtrlMsg(pMac, &msgQ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOG1, FL("Failed to send down the stats req ")); + vos_mem_free(pMsg); + } + return status; +} +void csrRoamStatsRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg) +{ + tAniGetPEStatsRsp *pSmeStatsRsp; + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry = NULL; + tCsrStatsClientReqInfo *pTempStaEntry = NULL; + tCsrPeStatsReqInfo *pPeStaEntry = NULL; + tANI_U32 tempMask = 0; + tANI_U8 counter = 0; + tANI_U8 *pStats = NULL; + tANI_U32 length = 0; + v_PVOID_t pvosGCtx; + v_S7_t rssi = 0, snr = 0; + tANI_U32 *pRssi = NULL, *pSnr = NULL; + tAniPerTxPktStatsInfo * txPacketInfo; + tANI_U32 linkCapacity; + pSmeStatsRsp = (tAniGetPEStatsRsp *)pSirMsg; + if(pSmeStatsRsp->rc) + { + smsLog( pMac, LOGW, FL("csrRoamStatsRspProcessor:stats rsp from PE shows failure")); + goto post_update; + } + tempMask = pSmeStatsRsp->statsMask; + pStats = ((tANI_U8 *)&pSmeStatsRsp->statsMask) + sizeof(pSmeStatsRsp->statsMask); + /* subtract all statistics from this length, and after processing the entire + * 'stat' part of the message, if the length is not zero, then rssi is piggy packed + * in this 'stats' message. + */ + length = pSmeStatsRsp->msgLen - sizeof(tAniGetPEStatsRsp); + //new stats info from PE, fill up the stats strucutres in PMAC + while(tempMask) + { + if(tempMask & 1) + { + switch(counter) + { + case eCsrSummaryStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:summary stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.summaryStatsInfo, + pStats, sizeof(tCsrSummaryStatsInfo)); + pStats += sizeof(tCsrSummaryStatsInfo); + length -= sizeof(tCsrSummaryStatsInfo); + break; + case eCsrGlobalClassAStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:ClassA stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.classAStatsInfo, + pStats, sizeof(tCsrGlobalClassAStatsInfo)); + pStats += sizeof(tCsrGlobalClassAStatsInfo); + length -= sizeof(tCsrGlobalClassAStatsInfo); + break; + case eCsrGlobalClassBStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:ClassB stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.classBStatsInfo, + pStats, sizeof(tCsrGlobalClassBStatsInfo)); + pStats += sizeof(tCsrGlobalClassBStatsInfo); + length -= sizeof(tCsrGlobalClassBStatsInfo); + break; + case eCsrGlobalClassCStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:ClassC stats")); + vos_mem_copy((tANI_U8 *)&pMac->roam.classCStatsInfo, + pStats, sizeof(tCsrGlobalClassCStatsInfo)); + pStats += sizeof(tCsrGlobalClassCStatsInfo); + length -= sizeof(tCsrGlobalClassCStatsInfo); + break; + case eCsrPerStaStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:PerSta stats")); + if( CSR_MAX_STA > pSmeStatsRsp->staId ) + { + status = eHAL_STATUS_SUCCESS; + vos_mem_copy((tANI_U8 *)&pMac->roam.perStaStatsInfo[pSmeStatsRsp->staId], + pStats, sizeof(tCsrPerStaStatsInfo)); + } + else + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, FL("csrRoamStatsRspProcessor:out bound staId:%d"), pSmeStatsRsp->staId); + VOS_ASSERT( 0 ); + } + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGW, FL("csrRoamStatsRspProcessor:failed to copy PerSta stats")); + } + pStats += sizeof(tCsrPerStaStatsInfo); + length -= sizeof(tCsrPerStaStatsInfo); + break; + case eCsrPerPktStats: + smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:PerPkt stats")); + vos_mem_zero(&pMac->roam.perPktStatsInfo, sizeof(tPerTxPacketFrmFw)); + if (IS_FEATURE_SUPPORTED_BY_FW(PER_PKT_STATS_SUPPORTED)) + { + txPacketInfo = (tAniPerTxPktStatsInfo *)pStats; + pMac->roam.perPktStatsInfo.lastTxRate = txPacketInfo->lastTxRate; + pMac->roam.perPktStatsInfo.txAvgRetry = txPacketInfo->txAvgRetry; + /* for reserved bytes */ + pStats += (sizeof(tAniPerTxPktStatsInfo) + 2*sizeof(tANI_U32)); + length -= (sizeof(tAniPerTxPktStatsInfo) + 2*sizeof(tANI_U32)); + } + break; + default: + smsLog( pMac, LOGW, FL("csrRoamStatsRspProcessor:unknown stats type")); + break; + } + } + tempMask >>=1; + counter++; + } + pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SME, pMac); + if (length != 0) + { + pRssi = (tANI_U32*)pStats; + rssi = (v_S7_t)*pRssi; + pStats += sizeof(tANI_U32); + length -= sizeof(tANI_U32); + } + else + { + /* If riva is not sending rssi, continue to use the hack */ + rssi = RSSI_HACK_BMPS; + } + /* send positive value of rssi to wifi_hal */ + pMac->roam.perPktStatsInfo.avgRssi = (-1)*rssi; + vos_updatePktStatsInfo(&pMac->roam.perPktStatsInfo); + WDA_UpdateRssiBmps(pvosGCtx, pSmeStatsRsp->staId, rssi); + + if (length != 0) + { + linkCapacity = *(tANI_U32*)pStats; + pStats += sizeof(tANI_U32); + length -= sizeof(tANI_U32); + } + else + { + linkCapacity = 0; + } + + WDA_UpdateLinkCapacity(pvosGCtx, pSmeStatsRsp->staId, linkCapacity); + + if (length != 0) + { + pSnr = (tANI_U32*)pStats; + snr = (v_S7_t)*pSnr; + } + else + { + snr = SNR_HACK_BMPS; + } + + WDA_UpdateSnrBmps(pvosGCtx, pSmeStatsRsp->staId, snr); +post_update: + //make sure to update the pe stats req list + pEntry = csrRoamFindInPeStatsReqList(pMac, pSmeStatsRsp->statsMask); + if(pEntry) + { + pPeStaEntry = GET_BASE_ADDR( pEntry, tCsrPeStatsReqInfo, link ); + pPeStaEntry->rspPending = FALSE; + + } + //check the one timer cases + pEntry = csrRoamCheckClientReqList(pMac, pSmeStatsRsp->statsMask); + if(pEntry) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if(pTempStaEntry->timerExpired) + { + //send up the stats report + csrRoamReportStatistics(pMac, pTempStaEntry->statsMask, pTempStaEntry->callback, + pTempStaEntry->staId, pTempStaEntry->pContext); + //also remove from the client list + csrRoamRemoveStatListEntry(pMac, pEntry); + pTempStaEntry = NULL; + } + } +} +tListElem * csrRoamFindInPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask) +{ + tListElem *pEntry = NULL; + tCsrPeStatsReqInfo *pTempStaEntry = NULL; + pEntry = csrLLPeekHead( &pMac->roam.peStatsReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOG2, "csrRoamFindInPeStatsReqList: List empty, no request to PE"); + return NULL; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrPeStatsReqInfo, link ); + if(pTempStaEntry->statsMask == statsMask) + { + smsLog(pMac, LOG3, "csrRoamFindInPeStatsReqList: match found"); + break; + } + pEntry = csrLLNext( &pMac->roam.peStatsReqList, pEntry, LL_ACCESS_NOLOCK ); + } + return pEntry; +} + +tListElem * csrRoamChecknUpdateClientReqList(tpAniSirGlobal pMac, tCsrStatsClientReqInfo *pStaEntry, + tANI_BOOLEAN update) +{ + tListElem *pEntry; + tCsrStatsClientReqInfo *pTempStaEntry; + pEntry = csrLLPeekHead( &pMac->roam.statsClientReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOG2, "csrRoamChecknUpdateClientReqList: List empty, no request from " + "upper layer client(s)"); + return NULL; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if((pTempStaEntry->requesterId == pStaEntry->requesterId) && + (pTempStaEntry->statsMask == pStaEntry->statsMask)) + { + smsLog(pMac, LOG3, "csrRoamChecknUpdateClientReqList: match found"); + if(update) + { + pTempStaEntry->periodicity = pStaEntry->periodicity; + pTempStaEntry->callback = pStaEntry->callback; + pTempStaEntry->pContext = pStaEntry->pContext; + } + break; + } + pEntry = csrLLNext( &pMac->roam.statsClientReqList, pEntry, LL_ACCESS_NOLOCK ); + } + return pEntry; +} +tListElem * csrRoamCheckClientReqList(tpAniSirGlobal pMac, tANI_U32 statsMask) +{ + tListElem *pEntry; + tCsrStatsClientReqInfo *pTempStaEntry; + pEntry = csrLLPeekHead( &pMac->roam.statsClientReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOG2, "csrRoamCheckClientReqList: List empty, no request from " + "upper layer client(s)"); + return NULL; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if((pTempStaEntry->statsMask & ~(1 << eCsrGlobalClassDStats)) == statsMask) + { + smsLog(pMac, LOG3, "csrRoamCheckClientReqList: match found"); + break; + } + pEntry = csrLLNext( &pMac->roam.statsClientReqList, pEntry, LL_ACCESS_NOLOCK ); + } + return pEntry; +} +eHalStatus csrRoamRegisterLinkQualityIndCallback(tpAniSirGlobal pMac, + csrRoamLinkQualityIndCallback callback, + void *pContext) +{ + pMac->roam.linkQualityIndInfo.callback = callback; + pMac->roam.linkQualityIndInfo.context = pContext; + if( NULL == callback ) + { + smsLog(pMac, LOGW, "csrRoamRegisterLinkQualityIndCallback: indication callback being deregistered"); + } + else + { + smsLog(pMac, LOGW, "csrRoamRegisterLinkQualityIndCallback: indication callback being registered"); + /* do we need to invoke the callback to notify client of initial value ?? */ + } + return eHAL_STATUS_SUCCESS; +} +void csrRoamVccTrigger(tpAniSirGlobal pMac) +{ + eCsrRoamLinkQualityInd newVccLinkQuality; + tANI_U32 ul_mac_loss = 0; + tANI_U32 ul_mac_loss_trigger_threshold; + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /*------------------------------------------------------------------------- + Link quality is currently binary based on OBIWAN recommended triggers + Check for a change in link quality and notify client if necessary + -------------------------------------------------------------------------*/ + ul_mac_loss_trigger_threshold = + pMac->roam.configParam.vccUlMacLossThreshold; + VOS_ASSERT( ul_mac_loss_trigger_threshold != 0 ); + smsLog(pMac, LOGW, "csrRoamVccTrigger: UL_MAC_LOSS_THRESHOLD is %d", + ul_mac_loss_trigger_threshold ); + if(ul_mac_loss_trigger_threshold < ul_mac_loss) + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality is POOR "); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; + } + else + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality is GOOD"); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_GOOD_IND; + } + smsLog(pMac, LOGW, "csrRoamVccTrigger: link qual : *** UL_MAC_LOSS %d *** ", + ul_mac_loss); + if(newVccLinkQuality != pMac->roam.vccLinkQuality) + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality changed: trigger necessary"); + if(NULL != pMac->roam.linkQualityIndInfo.callback) + { + smsLog(pMac, LOGW, "csrRoamVccTrigger: link quality indication %d", + newVccLinkQuality ); + + /* we now invoke the callback once to notify client of initial value */ + pMac->roam.linkQualityIndInfo.callback( newVccLinkQuality, + pMac->roam.linkQualityIndInfo.context ); + //event: EVENT_WLAN_VCC + } + } + pMac->roam.vccLinkQuality = newVccLinkQuality; + +} +VOS_STATUS csrRoamVccTriggerRssiIndCallback(tHalHandle hHal, + v_U8_t rssiNotification, + void * context) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( context ); + eCsrRoamLinkQualityInd newVccLinkQuality; + // TODO : Session info unavailable + tANI_U32 sessionId = 0; + VOS_STATUS status = VOS_STATUS_SUCCESS; + /*------------------------------------------------------------------------- + Link quality is currently binary based on OBIWAN recommended triggers + Check for a change in link quality and notify client if necessary + -------------------------------------------------------------------------*/ + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: RSSI trigger threshold is %d", + pMac->roam.configParam.vccRssiThreshold); + if(!csrIsConnStateConnectedInfra(pMac, sessionId)) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: ignoring the indication as we are not connected"); + return VOS_STATUS_SUCCESS; + } + if(WLANTL_HO_THRESHOLD_DOWN == rssiNotification) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality is POOR"); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_POOR_IND; + } + else if(WLANTL_HO_THRESHOLD_UP == rssiNotification) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality is GOOD "); + newVccLinkQuality = eCSR_ROAM_LINK_QUAL_GOOD_IND; + } + else + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: unknown rssi notification %d", rssiNotification); + //Set to this so the code below won't do anything + newVccLinkQuality = pMac->roam.vccLinkQuality; + VOS_ASSERT(0); + } + + if(newVccLinkQuality != pMac->roam.vccLinkQuality) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality changed: trigger necessary"); + if(NULL != pMac->roam.linkQualityIndInfo.callback) + { + smsLog(pMac, LOGW, "csrRoamVccTriggerRssiIndCallback: link quality indication %d", + newVccLinkQuality); + /* we now invoke the callback once to notify client of initial value */ + pMac->roam.linkQualityIndInfo.callback( newVccLinkQuality, + pMac->roam.linkQualityIndInfo.context ); + //event: EVENT_WLAN_VCC + } + } + pMac->roam.vccLinkQuality = newVccLinkQuality; + return status; +} +tCsrStatsClientReqInfo * csrRoamInsertEntryIntoList( tpAniSirGlobal pMac, + tDblLinkList *pStaList, + tCsrStatsClientReqInfo *pStaEntry) +{ + tCsrStatsClientReqInfo *pNewStaEntry = NULL; + //if same entity requested for same set of stats with different periodicity & + // callback update it + if(NULL == csrRoamChecknUpdateClientReqList(pMac, pStaEntry, TRUE)) + { + + pNewStaEntry = vos_mem_malloc(sizeof(tCsrStatsClientReqInfo)); + if (NULL == pNewStaEntry) + { + smsLog(pMac, LOGW, "csrRoamInsertEntryIntoList: couldn't allocate memory for the " + "entry"); + return NULL; + } + + pNewStaEntry->callback = pStaEntry->callback; + pNewStaEntry->pContext = pStaEntry->pContext; + pNewStaEntry->periodicity = pStaEntry->periodicity; + pNewStaEntry->requesterId = pStaEntry->requesterId; + pNewStaEntry->statsMask = pStaEntry->statsMask; + pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry; + pNewStaEntry->pMac = pStaEntry->pMac; + pNewStaEntry->staId = pStaEntry->staId; + pNewStaEntry->timerExpired = pStaEntry->timerExpired; + + csrLLInsertTail( pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK ); + } + return pNewStaEntry; +} + +tCsrPeStatsReqInfo * csrRoamInsertEntryIntoPeStatsReqList( tpAniSirGlobal pMac, + tDblLinkList *pStaList, + tCsrPeStatsReqInfo *pStaEntry) +{ + tCsrPeStatsReqInfo *pNewStaEntry = NULL; + pNewStaEntry = vos_mem_malloc(sizeof(tCsrPeStatsReqInfo)); + if (NULL == pNewStaEntry) + { + smsLog(pMac, LOGW, "csrRoamInsertEntryIntoPeStatsReqList: couldn't allocate memory for the " + "entry"); + return NULL; + } + + pNewStaEntry->hPeStatsTimer = pStaEntry->hPeStatsTimer; + pNewStaEntry->numClient = pStaEntry->numClient; + pNewStaEntry->periodicity = pStaEntry->periodicity; + pNewStaEntry->statsMask = pStaEntry->statsMask; + pNewStaEntry->pMac = pStaEntry->pMac; + pNewStaEntry->staId = pStaEntry->staId; + pNewStaEntry->timerRunning = pStaEntry->timerRunning; + pNewStaEntry->rspPending = pStaEntry->rspPending; + + csrLLInsertTail( pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK ); + return pNewStaEntry; +} +eHalStatus csrGetRssi(tpAniSirGlobal pMac, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t msg; + tANI_U32 sessionId; + + tAniGetRssiReq *pMsg; + smsLog(pMac, LOG2, FL("called")); + pMsg = vos_mem_malloc(sizeof(tAniGetRssiReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, " csrGetRssi: failed to allocate mem for req "); + return eHAL_STATUS_FAILURE; + } + csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)bssId, &sessionId); + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_RSSI_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetRssiReq); + pMsg->sessionId = sessionId; + pMsg->staId = staId; + pMsg->rssiCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + msg.type = eWNI_SME_GET_RSSI_REQ; + msg.bodyptr = pMsg; + msg.reserved = 0; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, " csrGetRssi failed to post msg to self "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG2, FL("returned")); + return status; +} + +eHalStatus csrGetSnr(tpAniSirGlobal pMac, + tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t msg; + tANI_U32 sessionId; + + tAniGetSnrReq *pMsg; + + smsLog(pMac, LOG2, FL("called")); + + pMsg =(tAniGetSnrReq *)vos_mem_malloc(sizeof(tAniGetSnrReq)); + if (NULL == pMsg ) + { + smsLog(pMac, LOGE, "%s: failed to allocate mem for req",__func__); + return status; + } + + csrRoamGetSessionIdFromBSSID(pMac, (tCsrBssid *)bssId, &sessionId); + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_SNR_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetSnrReq); + pMsg->sessionId = sessionId; + pMsg->staId = staId; + pMsg->snrCallback = callback; + pMsg->pDevContext = pContext; + msg.type = eWNI_SME_GET_SNR_REQ; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, "%s failed to post msg to self", __func__); + vos_mem_free((v_VOID_t *)pMsg); + status = eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOG2, FL("returned")); + return status; +} + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +eHalStatus csrGetRoamRssi(tpAniSirGlobal pMac, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniGetRssiReq *pMsg; + + pMsg = vos_mem_malloc(sizeof(tAniGetRssiReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL("Failed to allocate mem for req")); + return eHAL_STATUS_FAILURE; + } + // need to initiate a stats request to PE + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_ROAM_RSSI_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetRssiReq); + pMsg->staId = staId; + pMsg->rssiCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + status = palSendMBMessage(pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" Failed to send down get rssi req")); + //pMsg is freed by palSendMBMessage + status = eHAL_STATUS_FAILURE; + } + return status; +} +#endif + + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +eHalStatus csrGetTsmStats(tpAniSirGlobal pMac, + tCsrTsmStatsCallback callback, + tANI_U8 staId, + tCsrBssid bssId, + void *pContext, + void* pVosContext, + tANI_U8 tid) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniGetTsmStatsReq *pMsg = NULL; + + pMsg = (tAniGetTsmStatsReq*)vos_mem_malloc(sizeof(tAniGetTsmStatsReq)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "csrGetTsmStats: failed to allocate mem for req"); + return eHAL_STATUS_FAILED_ALLOC; + } + // need to initiate a stats request to PE + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GET_TSM_STATS_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniGetTsmStatsReq); + pMsg->staId = staId; + pMsg->tid = tid; + vos_mem_copy(pMsg->bssId, bssId, sizeof(tSirMacAddr)); + pMsg->tsmStatsCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + status = palSendMBMessage(pMac->hHdd, pMsg ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOG1, " csrGetTsmStats: failed to send down the rssi req"); + //pMsg is freed by palSendMBMessage + status = eHAL_STATUS_FAILURE; + } + return status; +} +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + +/* --------------------------------------------------------------------------- + \fn csrGetTLSTAState + \helper function to get teh TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 csrGetTLSTAState(tpAniSirGlobal pMac, tANI_U8 staId) +{ + WLANTL_STAStateType tlSTAState; + tlSTAState = WLANTL_STA_INIT; + + //request TL for STA State + if ( !VOS_IS_STATUS_SUCCESS(WLANTL_GetSTAState(pMac->roam.gVosContext, staId, &tlSTAState)) ) + { + smsLog(pMac, LOGE, FL("csrGetTLSTAState:couldn't get the STA state from TL")); + } + + return tlSTAState; +} + +eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext) +{ + tCsrStatsClientReqInfo staEntry; + tCsrStatsClientReqInfo *pStaEntry = NULL; + tCsrPeStatsReqInfo *pPeStaEntry = NULL; + tListElem *pEntry = NULL; + tANI_BOOLEAN found = FALSE; + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN insertInClientList = FALSE; + VOS_STATUS vosStatus; + WLANTL_TRANSFER_STA_TYPE *pTlStats; + + if( csrIsAllSessionDisconnected(pMac) ) + { + //smsLog(pMac, LOGW, "csrGetStatistics: wrong state curState(%d) not connected", pMac->roam.curState); + return eHAL_STATUS_FAILURE; + } + + if (csrNeighborMiddleOfRoaming((tHalHandle)pMac)) + { + smsLog(pMac, LOG1, FL("in the middle of roaming states")); + return eHAL_STATUS_FAILURE; + } + + if((!statsMask) && (!callback)) + { + //msg + smsLog(pMac, LOGW, "csrGetStatistics: statsMask & callback empty in the request"); + return eHAL_STATUS_FAILURE; + } + //for the search list method for deregister + staEntry.requesterId = requesterId; + staEntry.statsMask = statsMask; + //requester wants to deregister or just an error + if((statsMask) && (!callback)) + { + pEntry = csrRoamChecknUpdateClientReqList(pMac, &staEntry, FALSE); + if(!pEntry) + { + //msg + smsLog(pMac, LOGW, "csrGetStatistics: callback is empty in the request & couldn't " + "find any existing request in statsClientReqList"); + return eHAL_STATUS_FAILURE; + } + else + { + //clean up & return + pStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if(NULL != pStaEntry->pPeStaEntry) + { + pStaEntry->pPeStaEntry->numClient--; + //check if we need to delete the entry from peStatsReqList too + if(!pStaEntry->pPeStaEntry->numClient) + { + csrRoamRemoveEntryFromPeStatsReqList(pMac, pStaEntry->pPeStaEntry); + } + } + + //check if we need to stop the tl stats timer too + pMac->roam.tlStatsReqInfo.numClient--; + if(!pMac->roam.tlStatsReqInfo.numClient) + { + if(pMac->roam.tlStatsReqInfo.timerRunning) + { + status = vos_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot stop TlStatsTimer timer")); + return eHAL_STATUS_FAILURE; + } + } + pMac->roam.tlStatsReqInfo.periodicity = 0; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + } + if (periodicity) + { + vos_timer_stop(&pStaEntry->timer); + // Destroy the vos timer + vosStatus = vos_timer_destroy(&pStaEntry->timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGE, FL("Failed to destroy Client req timer")); + } + } + csrRoamRemoveStatListEntry(pMac, pEntry); + pStaEntry = NULL; + return eHAL_STATUS_SUCCESS; + } + } + + if(cache && !periodicity) + { + //return the cached stats + csrRoamReportStatistics(pMac, statsMask, callback, staId, pContext); + } + else + { + //add the request in the client req list + staEntry.callback = callback; + staEntry.pContext = pContext; + staEntry.periodicity = periodicity; + staEntry.pPeStaEntry = NULL; + staEntry.staId = staId; + staEntry.pMac = pMac; + staEntry.timerExpired = FALSE; + + + //if periodic report requested with non cached result from PE/TL + if(periodicity) + { + + //if looking for stats from PE + if(statsMask & ~(1 << eCsrGlobalClassDStats)) + { + + //check if same request made already & waiting for rsp + pPeStaEntry = csrRoamCheckPeStatsReqList(pMac, statsMask & ~(1 << eCsrGlobalClassDStats), + periodicity, &found, staId); + if(!pPeStaEntry) + { + //bail out, maxed out on number of req for PE + return eHAL_STATUS_FAILURE; + } + else + { + staEntry.pPeStaEntry = pPeStaEntry; + } + + } + //request stats from TL rightaway if requested by client, update tlStatsReqInfo if needed + if(statsMask & (1 << eCsrGlobalClassDStats)) + { + if(cache && pMac->roam.tlStatsReqInfo.numClient) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:Looking for cached stats from TL")); + } + else + { + + //update periodicity + if(pMac->roam.tlStatsReqInfo.periodicity) + { + pMac->roam.tlStatsReqInfo.periodicity = + CSR_ROAM_MIN(periodicity, pMac->roam.tlStatsReqInfo.periodicity); + } + else + { + pMac->roam.tlStatsReqInfo.periodicity = periodicity; + } + if(pMac->roam.tlStatsReqInfo.periodicity < CSR_MIN_TL_STAT_QUERY_PERIOD) + { + pMac->roam.tlStatsReqInfo.periodicity = CSR_MIN_TL_STAT_QUERY_PERIOD; + } + + if(!pMac->roam.tlStatsReqInfo.timerRunning) + { + pTlStats = (WLANTL_TRANSFER_STA_TYPE *)vos_mem_malloc(sizeof(WLANTL_TRANSFER_STA_TYPE)); + if (NULL != pTlStats) + { + //req TL for class D stats + if(WLANTL_GetStatistics(pMac->roam.gVosContext, pTlStats, staId)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:couldn't get the stats from TL")); + } + else + { + //save in SME + csrRoamSaveStatsFromTl(pMac, pTlStats); + } + vos_mem_free(pTlStats); + pTlStats = NULL; + } + else + { + smsLog(pMac, LOGE, FL("cannot allocate memory for TL stat")); + } + + if(pMac->roam.tlStatsReqInfo.periodicity) + { + //start timer + status = vos_timer_start(&pMac->roam.tlStatsReqInfo.hTlStatsTimer, + pMac->roam.tlStatsReqInfo.periodicity); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot start TlStatsTimer timer")); + return eHAL_STATUS_FAILURE; + } + pMac->roam.tlStatsReqInfo.timerRunning = TRUE; + } + } + } + pMac->roam.tlStatsReqInfo.numClient++; + } + + insertInClientList = TRUE; + } + //if one time report requested with non cached result from PE/TL + else if(!cache && !periodicity) + { + if(statsMask & ~(1 << eCsrGlobalClassDStats)) + { + //send down a req + status = csrSendMBStatsReqMsg(pMac, statsMask & ~(1 << eCsrGlobalClassDStats), staId); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:failed to send down stats req to PE")); + } + //so that when the stats rsp comes back from PE we respond to upper layer + //right away + staEntry.timerExpired = TRUE; + insertInClientList = TRUE; + } + if(statsMask & (1 << eCsrGlobalClassDStats)) + { + pTlStats = (WLANTL_TRANSFER_STA_TYPE *)vos_mem_malloc(sizeof(WLANTL_TRANSFER_STA_TYPE)); + if (NULL != pTlStats) + { + //req TL for class D stats + if(!VOS_IS_STATUS_SUCCESS(WLANTL_GetStatistics(pMac->roam.gVosContext, pTlStats, staId))) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:couldn't get the stats from TL")); + } + else + { + //save in SME + csrRoamSaveStatsFromTl(pMac, pTlStats); + } + vos_mem_free(pTlStats); + pTlStats = NULL; + } + else + { + smsLog(pMac, LOGE, FL("cannot allocate memory for TL stat")); + } + + } + //if looking for stats from TL only + if(!insertInClientList) + { + //return the stats + csrRoamReportStatistics(pMac, statsMask, callback, staId, pContext); + } + } + if(insertInClientList) + { + pStaEntry = csrRoamInsertEntryIntoList(pMac, &pMac->roam.statsClientReqList, &staEntry); + if(!pStaEntry) + { + //msg + smsLog(pMac, LOGW, "csrGetStatistics: Failed to insert req in statsClientReqList"); + return eHAL_STATUS_FAILURE; + } + pStaEntry->periodicity = periodicity; + //Init & start timer if needed + if(periodicity) + { + vosStatus = vos_timer_init( &pStaEntry->timer, VOS_TIMER_TYPE_SW, + csrRoamStatsClientTimerHandler, pStaEntry ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot init StatsClient timer")); + return eHAL_STATUS_FAILURE; + } + vosStatus = vos_timer_start( &pStaEntry->timer, periodicity ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrGetStatistics:cannot start StatsClient timer")); + return eHAL_STATUS_FAILURE; + } + } + } + } + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +static tSirRetStatus +csrRoamScanOffloadPopulateMacHeader(tpAniSirGlobal pMac, + tANI_U8* pBD, + tANI_U8 type, + tANI_U8 subType, + tSirMacAddr peerAddr, + tSirMacAddr selfMacAddr) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tpSirMacMgmtHdr pMacHdr; + + /* Prepare MAC management header */ + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + /* Prepare FC */ + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type; + pMacHdr->fc.subType = subType; + + /* Prepare Address 1 */ + vos_mem_copy((tANI_U8 *) pMacHdr->da, (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + + sirCopyMacAddr(pMacHdr->sa,selfMacAddr); + + /* Prepare Address 3 */ + vos_mem_copy((tANI_U8 *) pMacHdr->bssId, (tANI_U8 *) peerAddr, + sizeof( tSirMacAddr )); + return statusCode; +} /*** csrRoamScanOffloadPopulateMacHeader() ***/ + +static tSirRetStatus +csrRoamScanOffloadPrepareProbeReqTemplate(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tANI_U32 dot11mode, + tSirMacAddr selfMacAddr, + tANI_U8 *pFrame, + tANI_U16 *pusLen) +{ + tDot11fProbeRequest pr; + tANI_U32 nStatus, nBytes, nPayload; + tSirRetStatus nSirStatus; + /*Bcast tx*/ + tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + + vos_mem_set(( tANI_U8* )&pr, sizeof( pr ), 0); + + PopulateDot11fSuppRates( pMac, nChannelNum, &pr.SuppRates,NULL); + + if ( WNI_CFG_DOT11_MODE_11B != dot11mode ) + { + PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates ); + } + + + if (IS_DOT11_MODE_HT(dot11mode)) + { + PopulateDot11fHTCaps( pMac, NULL, &pr.HTCaps ); + } + + + nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to calculate the packed size f" + "or a Probe Request (0x%08x).\n", nStatus ); + + + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while calculating" + "the packed size for a Probe Request (" + "0x%08x).\n", nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + /* Prepare outgoing frame*/ + vos_mem_set(pFrame, nBytes , 0); + + + nSirStatus = csrRoamScanOffloadPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_REQ, bssId,selfMacAddr); + + if ( eSIR_SUCCESS != nSirStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to populate the buffer descriptor for a Probe Request (%d).\n", + nSirStatus ); + return nSirStatus; + } + + + nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to pack a Probe Request (0x%08x).\n", nStatus ); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while packing a Probe Request (0x%08x).\n", + nStatus ); + } + + *pusLen = nPayload + sizeof(tSirMacMgmtHdr); + return eSIR_SUCCESS; +} + +/* + * Below Table describe whether RSO command can be send down to fimrware or not. + * Host check it on the basis of previous RSO command sent down to firmware. +||===========================================================================|| +|| New cmd | LAST SENT COMMAND ---> || +||====|======================================================================|| +|| V | RSO_START | RSO_STOP | RSO_RESTART | RSO_UPDATE_CFG || +|| --------------------------------------------------------------------------|| +|| RSO_START | NO | YES | NO | NO || +|| RSO_STOP | YES | NO | YES | YES || +|| RSO_RESTART | YES | NO | YES | YES || +|| RSO_UPDATE_CFG | YES | NO | YES | YES || +||===========================================================================|| +*/ + +#define RSO_START_BIT (1<roam.neighborRoamInfo; + tANI_U8 desiredMask = 0; + switch(command) + { + case ROAM_SCAN_OFFLOAD_START: + desiredMask = RSO_START_ALLOW_MASK; + break; + case ROAM_SCAN_OFFLOAD_STOP: + desiredMask = RSO_STOP_ALLOW_MASK; + break; + case ROAM_SCAN_OFFLOAD_RESTART: + desiredMask = RSO_RESTART_ALLOW_MASK; + break; + case ROAM_SCAN_OFFLOAD_UPDATE_CFG: + desiredMask = RSO_UPDATE_CFG_ALLOW_MASK; + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Wrong RSO command %d, not allowed"), command); + return 0;/*Cmd Not allowed*/ + } + return ( desiredMask & ( 1 << pNeighborRoamInfo->lastSentCmd) ); +} + +eCsrBand GetCurrentBand(tANI_U8 channel) +{ + tSirRFBand Rfband; + eCsrBand band; + + Rfband = GetRFBand(channel); + + if (Rfband == SIR_BAND_5_GHZ) + band = eCSR_BAND_5G; + else if (Rfband == SIR_BAND_2_4_GHZ) + band = eCSR_BAND_24; + else if (Rfband == SIR_BAND_UNKNOWN) + band = eCSR_BAND_MAX; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "channel %d Rfband %d band %d", channel, Rfband, band); + + return band; +} + +eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 command, tANI_U8 reason) +{ + vos_msg_t msg; + vos_msg_t PERroamScanConfigMsg = {0}; + tSirRoamOffloadScanReq *pRequestBuf; + tSirPERRoamOffloadScanReq *PERRoamReqBuf; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tCsrRoamSession *pSession = NULL; + tANI_U8 i,j,num_channels = 0, ucDot11Mode; + tANI_U8 *ChannelList = NULL; + tANI_U32 sessionId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrChannelInfo currChannelListInfo; + tANI_U32 host_channels = 0; + tANI_U8 ChannelCacheStr[128] = {0}; + eCsrBand eBand, Rfband = eCSR_BAND_ALL; + tSirBssDescription *pBssDesc = NULL; + tDot11fBeaconIEs *pIes = NULL; + tANI_U8 minRate = 0, dataRate; + tANI_U8 operationChannel = 0; + + currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + + if (0 == csrRoamIsRoamOffloadScanEnabled(pMac)) + { + smsLog( pMac, LOGE,"isRoamOffloadScanEnabled not set"); + return eHAL_STATUS_FAILURE; + } + + if ((VOS_TRUE == bRoamScanOffloadStarted) && (ROAM_SCAN_OFFLOAD_START == command)) + { + smsLog( pMac, LOGE,"Roam Scan Offload is already started"); + return eHAL_STATUS_FAILURE; + } + + /*The Dynamic Config Items Update may happen even if the state is in INIT. + * It is important to ensure that the command is passed down to the FW only + * if the Infra Station is in a connected state.A connected station could also be + * in a PREAUTH or REASSOC states.So, consider not sending the command down in INIT state. + * We also have to ensure that if there is a STOP command we always have to inform Riva, + * irrespective of whichever state we are in.*/ + if ((pMac->roam.neighborRoamInfo.neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_INIT) && + (command != ROAM_SCAN_OFFLOAD_STOP)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Scan Command not sent to FW with state = %s and cmd=%d\n"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState), command); + return eHAL_STATUS_FAILURE; + } + + if (!CsrIsRSOCommandAllowed(pMac, command)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("RSO command %d lastSentCmd %d, RSO is out of sync in HOST-FWR"), + command, pNeighborRoamInfo->lastSentCmd); + return eHAL_STATUS_FAILURE; + } + + /* We dont need psession during ROAM_SCAN_OFFLOAD_STOP + * Also there are cases where pNeighborRoamInfo->currAPbssid + * is set to 0 during disconnect and so we might return without stopping + * the roam scan. So no need to find the session if command is + * ROAM_SCAN_OFFLOAD_STOP. + */ + status = csrRoamGetSessionIdFromBSSID(pMac, + (tCsrBssid *)pNeighborRoamInfo->currAPbssid, + &sessionId); + if( ROAM_SCAN_OFFLOAD_STOP != command ) + { + if ( !HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to find the sessionId for Roam Offload scan request", __func__); + return eHAL_STATUS_FAILURE; + } + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:pSession is null", __func__); + return eHAL_STATUS_FAILURE; + } + pBssDesc = pSession->pConnectBssDesc; + if (pBssDesc == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pBssDesc not found for current session", __func__); + return eHAL_STATUS_FAILURE; + } + + operationChannel = pSession->connectedProfile.operationChannel; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "operationChannel %d", operationChannel); + } + pRequestBuf = vos_mem_malloc(sizeof(tSirRoamOffloadScanReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for Roam Offload scan request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + limDiagEventReport(pMac, WLAN_PE_DIAG_ROAM_REQUESTED, NULL, + eSIR_SUCCESS, eSIR_SUCCESS); +#endif + + vos_mem_zero(pRequestBuf, sizeof(tSirRoamOffloadScanReq)); + /* If command is STOP, then pass down ScanOffloadEnabled as Zero.This will handle the case of + * host driver reloads, but Riva still up and running*/ + pRequestBuf->Command = command; + if(command == ROAM_SCAN_OFFLOAD_STOP) + { + pRequestBuf->RoamScanOffloadEnabled = 0; + pRequestBuf->StartScanReason = reason; + /*For a STOP Command, there is no need to + * go through filling up all the below parameters + * since they are not required for the STOP command*/ + goto send_roam_scan_offload_cmd; + } + else + pRequestBuf->RoamScanOffloadEnabled = pMac->roam.configParam.isRoamOffloadScanEnabled; + vos_mem_copy(pRequestBuf->ConnectedNetwork.currAPbssid, + pNeighborRoamInfo->currAPbssid, + sizeof(tCsrBssid)); + pRequestBuf->ConnectedNetwork.ssId.length = + pMac->roam.roamSession[sessionId].connectedProfile.SSID.length; + vos_mem_copy(pRequestBuf->ConnectedNetwork.ssId.ssId, + pMac->roam.roamSession[sessionId].connectedProfile.SSID.ssId, + pRequestBuf->ConnectedNetwork.ssId.length); + pRequestBuf->ConnectedNetwork.authentication = + pMac->roam.roamSession[sessionId].connectedProfile.AuthType; + pRequestBuf->ConnectedNetwork.encryption = + pMac->roam.roamSession[sessionId].connectedProfile.EncryptionType; + pRequestBuf->ConnectedNetwork.mcencryption = + pMac->roam.roamSession[sessionId].connectedProfile.mcEncryptionType; + if (pNeighborRoamInfo->cfgParams.neighborLookupThreshold) + { + pRequestBuf->LookupThreshold = + (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1); + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_DEFAULT; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Calculate Adaptive Threshold"); + + if (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: csrGetParsedBssDescriptionIEs failed", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + if(NULL == pIes) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s : pIes is Null", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + if (pIes->SuppRates.present) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Number \t Rate"); + /*Check for both basic rates and extended rates.*/ + for (i = 0; i < pIes->SuppRates.num_rates; i++) + { + /*Check if the Rate is Mandatory or Not*/ + if (csrRatesIsDot11RateSupported(pMac, pIes->SuppRates.rates[i]) + && (pIes->SuppRates.rates[i] & 0x80)) + { + /*Retrieve the actual data rate*/ + dataRate = (pIes->SuppRates.rates[i] & 0x7F)/2; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%d \t\t %d", i, dataRate); + if (minRate == 0) + minRate = dataRate; + else + minRate = (minRate < dataRate) ? minRate:dataRate; + } + } + + if (pIes->ExtSuppRates.present) + { + for (i = 0; i < pIes->ExtSuppRates.num_rates; i++) + { + /*Check if the Rate is Mandatory or Not*/ + if (csrRatesIsDot11RateSupported(pMac, pIes->ExtSuppRates.rates[i]) + && (pIes->ExtSuppRates.rates[i] & 0x80)) + { + /*Retrieve the actual data rate*/ + dataRate = (pIes->ExtSuppRates.rates[i] & 0x7F)/2; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%d \t\t %d", i, dataRate); + if (minRate == 0) + minRate = dataRate; + else + minRate = (minRate < dataRate) ? minRate:dataRate; + } + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "MinRate = %d", minRate); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Supp Rates not present in pIes", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + if (NULL != pIes) + { + vos_mem_free(pIes); + pIes = NULL; + } + switch (minRate) + { + case 1: + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_1MBPS; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_1MBPS; + break; + case 2: + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_2MBPS; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_2MBPS; + break; + case 5: + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_5_5MBPS; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_5_5MBPS; + break; + case 6: + if (CSR_IS_CHANNEL_24GHZ(operationChannel)) + { + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_6MBPS_2G; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_6MBPS_2G; + } + else + { + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_6MBPS_5G; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_6MBPS_5G; + } + break; + case 11: + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_11MBPS; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_11MBPS; + break; + case 12: + if (CSR_IS_CHANNEL_24GHZ(operationChannel)) + { + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_12MBPS_2G; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_12MBPS_2G; + } + else + { + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_12MBPS_5G; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_12MBPS_5G; + } + break; + case 24: + if (CSR_IS_CHANNEL_24GHZ(operationChannel)) + { + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_24MBPS_2G; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_24MBPS_2G; + } + else + { + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_24MBPS_5G; + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_24MBPS_5G; + } + break; + default: + pRequestBuf->LookupThreshold = LFR_LOOKUP_THR_DEFAULT; + pRequestBuf->RxSensitivityThreshold = LFR_SENSITIVITY_THR_DEFAULT; + break; + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "Chnl=%d,MinRate=%d,RxSenThr=%d,LookupThr=%d", + operationChannel, minRate, + pRequestBuf->RxSensitivityThreshold, + pRequestBuf->LookupThreshold); + pRequestBuf->RoamRssiDiff = + pMac->roam.configParam.RoamRssiDiff; + pRequestBuf->StartScanReason = reason; + pRequestBuf->NeighborScanTimerPeriod = + pNeighborRoamInfo->cfgParams.neighborScanPeriod; + pRequestBuf->NeighborRoamScanRefreshPeriod = + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod; + pRequestBuf->NeighborScanChannelMinTime = + pNeighborRoamInfo->cfgParams.minChannelScanTime; + pRequestBuf->NeighborScanChannelMaxTime = + pNeighborRoamInfo->cfgParams.maxChannelScanTime; + pRequestBuf->EmptyRefreshScanPeriod = + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod; + /* MAWC feature */ + pRequestBuf->MAWCEnabled = + pMac->roam.configParam.MAWCEnabled; + +#ifdef FEATURE_WLAN_ESE + pRequestBuf->IsESEEnabled = pMac->roam.configParam.isEseIniFeatureEnabled; +#endif + if ( +#ifdef FEATURE_WLAN_ESE + ((pNeighborRoamInfo->isESEAssoc) && + (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == + eANI_BOOLEAN_FALSE)) || + (pNeighborRoamInfo->isESEAssoc == eANI_BOOLEAN_FALSE) || +#endif // ESE + currChannelListInfo->numOfChannels == 0) + { + + /*Retrieve the Channel Cache either from ini or from the Occupied Channels list. + * Give Preference to INI Channels.*/ + if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + ChannelList = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList; + /*The INI channels need to be filtered with respect to the current + * band that is supported.*/ + eBand = pMac->roam.configParam.bandCapability; + if ((eCSR_BAND_24 != eBand) && (eCSR_BAND_5G != eBand) && (eCSR_BAND_ALL != eBand)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Invalid band, No operation carried out (Band %d)", eBand); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + if (pMac->roam.configParam.nRoamIntraBand) + { + eBand = GetCurrentBand(operationChannel); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Current Band %d", eBand); + } + + for (i=0; icfgParams.channelInfo.numOfChannels; i++) + { + if(((eCSR_BAND_24 == eBand) && CSR_IS_CHANNEL_24GHZ(*ChannelList)) || + ((eCSR_BAND_5G == eBand) && CSR_IS_CHANNEL_5GHZ(*ChannelList)) || + (eCSR_BAND_ALL == eBand)) + { + if(*ChannelList && csrRoamIsChannelValid(pMac, *ChannelList) && + ((pMac->roam.configParam.allowDFSChannelRoam) || + (!CSR_IS_CHANNEL_DFS(*ChannelList))) && + (num_channels < SIR_ROAM_MAX_CHANNELS)) + { + pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList; + } + } + ChannelList++; + } + pRequestBuf->ConnectedNetwork.ChannelCount = num_channels; + pRequestBuf->ChannelCacheType = CHANNEL_LIST_STATIC; + } + else + { + ChannelList = pMac->scan.occupiedChannels.channelList; + + if (pMac->roam.configParam.nRoamIntraBand) + { + Rfband = GetCurrentBand(operationChannel); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Current Band %d", Rfband); + } + + for(i=0; iscan.occupiedChannels.numChannels; i++) + { + if(((eCSR_BAND_24 == Rfband) && + CSR_IS_CHANNEL_24GHZ(*ChannelList)) || + ((eCSR_BAND_5G == Rfband) && CSR_IS_CHANNEL_5GHZ(*ChannelList)) + || (eCSR_BAND_ALL == Rfband)) + { + /* Allow DFS channels only if the DFS channel roam flag is + * enabled + */ + if(*ChannelList && ((pMac->roam.configParam. + allowDFSChannelRoam) || (!CSR_IS_CHANNEL_DFS(*ChannelList))) + && (num_channels < SIR_ROAM_MAX_CHANNELS)) + { + pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] + = *ChannelList; + } + } + ChannelList++; + } + pRequestBuf->ConnectedNetwork.ChannelCount = num_channels; + /* If the profile changes as to what it was earlier, inform the FW through + * FLUSH as ChannelCacheType in which case, the FW will flush the occupied channels + * for the earlier profile and try to learn them afresh.*/ + if (reason == REASON_FLUSH_CHANNEL_LIST) + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_FLUSH; + else { + if ((csrNeighborRoamIsNewConnectedProfile(pMac)) || + (pMac->roam.configParam.nRoamIntraBand)) + pRequestBuf->ChannelCacheType = + CHANNEL_LIST_DYNAMIC_INIT; + else + pRequestBuf->ChannelCacheType = + CHANNEL_LIST_DYNAMIC_UPDATE; + } + } + } +#ifdef FEATURE_WLAN_ESE + else + { + /* If ESE is enabled, and a neighbor Report is received,then + * Ignore the INI Channels or the Occupied Channel List. Consider + * the channels in the neighbor list sent by the ESE AP.*/ + if (currChannelListInfo->numOfChannels != 0) + { + ChannelList = currChannelListInfo->ChannelList; + + if (pMac->roam.configParam.nRoamIntraBand) + { + Rfband = GetCurrentBand(operationChannel); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Current Band %d", Rfband); + } + + for (i=0;inumOfChannels;i++) + { + if(((eCSR_BAND_24 == Rfband) && + CSR_IS_CHANNEL_24GHZ(*ChannelList)) || + ((eCSR_BAND_5G == Rfband) && CSR_IS_CHANNEL_5GHZ(*ChannelList)) + || (eCSR_BAND_ALL == Rfband)) + { + if(*ChannelList && ((pMac->roam.configParam. + allowDFSChannelRoam) || (!CSR_IS_CHANNEL_DFS(*ChannelList)))) + { + pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = + *ChannelList; + } + } + ChannelList++; + } + pRequestBuf->ConnectedNetwork.ChannelCount = num_channels; + if (pMac->roam.configParam.nRoamIntraBand) + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_INIT; + else + pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE; + } + } +#endif + for (i = 0, j = 0;j < (sizeof(ChannelCacheStr)/sizeof(ChannelCacheStr[0])) + && i < pRequestBuf->ConnectedNetwork.ChannelCount; i++) + { + if (j < sizeof(ChannelCacheStr)) + { + j += snprintf(ChannelCacheStr + j, sizeof(ChannelCacheStr) - j," %d", + pRequestBuf->ConnectedNetwork.ChannelCache[i]); + } + else + { + break; + } + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "ChnlCacheType:%d, No of Chnls:%d,Channels: %s", + pRequestBuf->ChannelCacheType, + pRequestBuf->ConnectedNetwork.ChannelCount, + ChannelCacheStr); + num_channels = 0; + ChannelList = NULL; + + /* Maintain the Valid Channels List*/ + host_channels = sizeof(pMac->roam.validChannelList); + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &host_channels))) + { + ChannelList = pMac->roam.validChannelList; + pMac->roam.numValidChannels = host_channels; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s:Failed to get the valid channel list", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + if (pMac->roam.configParam.nRoamIntraBand) + { + Rfband = GetCurrentBand(operationChannel); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Current Band %d", + Rfband); + } + + for(i=0; iroam.numValidChannels; i++) + { + if(((eCSR_BAND_24 == Rfband) && CSR_IS_CHANNEL_24GHZ(*ChannelList)) || + ((eCSR_BAND_5G == Rfband) && CSR_IS_CHANNEL_5GHZ(*ChannelList)) || + (eCSR_BAND_ALL == Rfband)) + { + if(*ChannelList && ((pMac->roam.configParam.allowDFSChannelRoam) || + (!CSR_IS_CHANNEL_DFS(*ChannelList)))) + { + pRequestBuf->ValidChannelList[num_channels++] = *ChannelList; + } + } + ChannelList++; + } + pRequestBuf->ValidChannelCount = num_channels; + + pRequestBuf->MDID.mdiePresent = + pMac->roam.roamSession[sessionId].connectedProfile.MDID.mdiePresent; + pRequestBuf->MDID.mobilityDomain = + pMac->roam.roamSession[sessionId].connectedProfile.MDID.mobilityDomain; + pRequestBuf->nProbes = pMac->roam.configParam.nProbes; + + pRequestBuf->HomeAwayTime = pMac->roam.configParam.nRoamScanHomeAwayTime; + /* Home Away Time should be at least equal to (MaxDwell time + (2*RFS)), + * where RFS is the RF Switching time. It is twice RFS to consider the + * time to go off channel and return to the home channel. */ + if (pRequestBuf->HomeAwayTime < (pRequestBuf->NeighborScanChannelMaxTime + (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "%s: Invalid config, Home away time(%d) is less than (twice RF switching time + channel max time)(%d)" + " Hence enforcing home away time to disable (0)", + __func__, pRequestBuf->HomeAwayTime, + (pRequestBuf->NeighborScanChannelMaxTime + (2 * CSR_ROAM_SCAN_CHANNEL_SWITCH_TIME))); + pRequestBuf->HomeAwayTime = 0; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,"HomeAwayTime:%d",pRequestBuf->HomeAwayTime); + + pRequestBuf->WeakZoneRssiThresholdForRoam = + pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam; + /*Prepare a probe request for 2.4GHz band and one for 5GHz band*/ + ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, + csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode )); + csrRoamScanOffloadPrepareProbeReqTemplate(pMac,SIR_ROAM_SCAN_24G_DEFAULT_CH, ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p24GProbeTemplate, &pRequestBuf->us24GProbeTemplateLen); + + csrRoamScanOffloadPrepareProbeReqTemplate(pMac,SIR_ROAM_SCAN_5G_DEFAULT_CH, ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p5GProbeTemplate, &pRequestBuf->us5GProbeTemplateLen); +send_roam_scan_offload_cmd: + msg.type = WDA_ROAM_SCAN_OFFLOAD_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_ROAM_SCAN_OFFLOAD_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + else + { + if (ROAM_SCAN_OFFLOAD_START == command) + bRoamScanOffloadStarted = VOS_TRUE; + else if (ROAM_SCAN_OFFLOAD_STOP == command) + bRoamScanOffloadStarted = VOS_FALSE; + + /*update the last sent cmd*/ + pNeighborRoamInfo->lastSentCmd = command; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Roam Scan Offload Command %d, Reason %d", command, reason); + + if (sme_IsFeatureSupportedByFW(PER_BASED_ROAMING) && + (command != ROAM_SCAN_OFFLOAD_STOP) && + pMac->roam.configParam.isPERRoamEnabled) + { + + /* PER ROAM SCAN */ + PERRoamReqBuf = vos_mem_malloc(sizeof(*PERRoamReqBuf)); + if (!PERRoamReqBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate mem for PERRoamReqBuf", __func__); + return eHAL_STATUS_FAILURE; + } + /* PER Roam Config */ + PERRoamReqBuf->rateUpThreshold = + pMac->roam.configParam.rateUpThreshold; + PERRoamReqBuf->rateDownThreshold = + pMac->roam.configParam.rateDownThreshold; + PERRoamReqBuf->waitPeriodForNextPERScan = + pMac->roam.configParam.waitPeriodForNextPERScan; + PERRoamReqBuf->PERtimerThreshold = + pMac->roam.configParam.PERtimerThreshold; + PERRoamReqBuf->isPERRoamCCAEnabled = + pMac->roam.configParam.isPERRoamCCAEnabled; + PERRoamReqBuf->PERRoamFullScanThreshold = + pMac->roam.configParam.PERRoamFullScanThreshold; + PERRoamReqBuf->PERroamTriggerPercent = + pMac->roam.configParam.PERroamTriggerPercent; + PERRoamReqBuf->sessionId = sessionId; + + PERroamScanConfigMsg.type = WDA_PER_ROAM_SCAN_OFFLOAD_REQ; + PERroamScanConfigMsg.reserved = 0; + PERroamScanConfigMsg.bodyptr = PERRoamReqBuf; + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, + &PERroamScanConfigMsg))) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post WDA_PER_ROAM_SCAN_OFFLOAD_REQ msg to WDA")); + vos_mem_free(PERRoamReqBuf); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("rateUpThreshold =%x rateDownThreshold =%x waitPeriodForNextPERScan=%u PERtimerThreshold=%u"), + PERRoamReqBuf->rateUpThreshold, + PERRoamReqBuf->rateDownThreshold, + PERRoamReqBuf->waitPeriodForNextPERScan, + PERRoamReqBuf->PERtimerThreshold); + } + + return status; +} + +eHalStatus csrRoamOffloadScanRspHdlr(tpAniSirGlobal pMac, tANI_U8 reason) +{ + switch(reason) + { + case 0: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "Rsp for Roam Scan Offload with failure status"); + break; + case REASON_OS_REQUESTED_ROAMING_NOW: + csrNeighborRoamProceedWithHandoffReq(pMac); + break; + case REASON_INITIAL_FORCED_ROAM_TO_5G: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, "%s recevied REASON_INITIAL_FORCED_ROAM_TO_5G", __func__); + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Rsp for Roam Scan Offload with reason %d", reason); + } + return eHAL_STATUS_SUCCESS; +} +#endif + +tCsrPeStatsReqInfo * csrRoamCheckPeStatsReqList(tpAniSirGlobal pMac, tANI_U32 statsMask, + tANI_U32 periodicity, tANI_BOOLEAN *pFound, tANI_U8 staId) +{ + tANI_BOOLEAN found = FALSE; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrPeStatsReqInfo staEntry; + tCsrPeStatsReqInfo *pTempStaEntry = NULL; + tListElem *pStaEntry = NULL; + VOS_STATUS vosStatus; + tPmcPowerState powerState; + *pFound = FALSE; + + pStaEntry = csrRoamFindInPeStatsReqList(pMac, statsMask); + if(pStaEntry) + { + pTempStaEntry = GET_BASE_ADDR( pStaEntry, tCsrPeStatsReqInfo, link ); + if(pTempStaEntry->periodicity) + { + pTempStaEntry->periodicity = + CSR_ROAM_MIN(periodicity, pTempStaEntry->periodicity); + } + else + { + pTempStaEntry->periodicity = periodicity; + } + pTempStaEntry->numClient++; + found = TRUE; + } + else + { + vos_mem_set(&staEntry, sizeof(tCsrPeStatsReqInfo), 0); + staEntry.numClient = 1; + staEntry.periodicity = periodicity; + staEntry.pMac = pMac; + staEntry.rspPending = FALSE; + staEntry.staId = staId; + staEntry.statsMask = statsMask; + staEntry.timerRunning = FALSE; + pTempStaEntry = csrRoamInsertEntryIntoPeStatsReqList(pMac, &pMac->roam.peStatsReqList, &staEntry); + if(!pTempStaEntry) + { + //msg + smsLog(pMac, LOGW, "csrRoamCheckPeStatsReqList: Failed to insert req in peStatsReqList"); + return NULL; + } + } + pmcQueryPowerState(pMac, &powerState, NULL, NULL); + if(ePMC_FULL_POWER == powerState) + { + if(pTempStaEntry->periodicity < pMac->roam.configParam.statsReqPeriodicity) + { + pTempStaEntry->periodicity = pMac->roam.configParam.statsReqPeriodicity; + } + } + else + { + if(pTempStaEntry->periodicity < pMac->roam.configParam.statsReqPeriodicityInPS) + { + pTempStaEntry->periodicity = pMac->roam.configParam.statsReqPeriodicityInPS; + } + } + if(!pTempStaEntry->timerRunning) + { + //send down a req in case of one time req, for periodic ones wait for timer to expire + if(!pTempStaEntry->rspPending && + !pTempStaEntry->periodicity) + { + status = csrSendMBStatsReqMsg(pMac, statsMask & ~(1 << eCsrGlobalClassDStats), staId); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:failed to send down stats req to PE")); + } + else + { + pTempStaEntry->rspPending = TRUE; + } + } + if(pTempStaEntry->periodicity) + { + if(!found) + { + + vosStatus = vos_timer_init( &pTempStaEntry->hPeStatsTimer, VOS_TIMER_TYPE_SW, + csrRoamPeStatsTimerHandler, pTempStaEntry ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:cannot init hPeStatsTimer timer")); + return NULL; + } + } + //start timer + smsLog(pMac, LOG1, "csrRoamCheckPeStatsReqList:peStatsTimer period %d", pTempStaEntry->periodicity); + vosStatus = vos_timer_start( &pTempStaEntry->hPeStatsTimer, pTempStaEntry->periodicity ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamCheckPeStatsReqList:cannot start hPeStatsTimer timer")); + return NULL; + } + pTempStaEntry->timerRunning = TRUE; + } + } + *pFound = found; + return pTempStaEntry; +} + +/* + pStaEntry is no longer invalid upon the return of this function. +*/ +static void csrRoamRemoveStatListEntry(tpAniSirGlobal pMac, tListElem *pEntry) +{ + if(pEntry) + { + if(csrLLRemoveEntry(&pMac->roam.statsClientReqList, pEntry, LL_ACCESS_LOCK)) + { + vos_mem_free(GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link )); + } + } + } + +void csrRoamRemoveEntryFromPeStatsReqList(tpAniSirGlobal pMac, tCsrPeStatsReqInfo *pPeStaEntry) +{ + tListElem *pEntry; + tCsrPeStatsReqInfo *pTempStaEntry; + VOS_STATUS vosStatus; + pEntry = csrLLPeekHead( &pMac->roam.peStatsReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOGE, FL(" List empty, no stats req for PE")); + return; + } + while( pEntry ) + { + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrPeStatsReqInfo, link ); + if( pTempStaEntry && pTempStaEntry->statsMask == pPeStaEntry->statsMask) + { + smsLog(pMac, LOGW, FL("Match found")); + if(pTempStaEntry->timerRunning) + { + vosStatus = vos_timer_stop( &pTempStaEntry->hPeStatsTimer ); + /* If we are not able to stop the timer here, just remove + * the entry from the linked list. Destroy the timer object + * and free the memory in the timer CB + */ + if ( vosStatus == VOS_STATUS_SUCCESS ) + { + /* the timer is successfully stopped */ + pTempStaEntry->timerRunning = FALSE; + + /* Destroy the timer */ + vosStatus = vos_timer_destroy( &pTempStaEntry->hPeStatsTimer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamRemoveEntryFromPeStatsReqList:failed to destroy hPeStatsTimer timer")); + } + } + else + { + // the timer could not be stopped. Hence destroy and free the + // memory for the PE stat entry in the timer CB. + pTempStaEntry->timerStopFailed = TRUE; + } + } + + if(csrLLRemoveEntry(&pMac->roam.peStatsReqList, pEntry, LL_ACCESS_LOCK)) + { + // Only free the memory if we could stop the timer successfully + if(!pTempStaEntry->timerStopFailed) + { + vos_mem_free(pTempStaEntry); + pTempStaEntry = NULL; + } + break; + } + + pEntry = csrLLNext( &pMac->roam.peStatsReqList, pEntry, LL_ACCESS_NOLOCK ); + } + } + return; +} + + +void csrRoamSaveStatsFromTl(tpAniSirGlobal pMac, WLANTL_TRANSFER_STA_TYPE *pTlStats) +{ + + pMac->roam.classDStatsInfo.num_rx_bytes_crc_ok = pTlStats->rxBcntCRCok; + pMac->roam.classDStatsInfo.rx_bc_byte_cnt = pTlStats->rxBCBcnt; + pMac->roam.classDStatsInfo.rx_bc_frm_cnt = pTlStats->rxBCFcnt; + pMac->roam.classDStatsInfo.rx_byte_cnt = pTlStats->rxBcnt; + pMac->roam.classDStatsInfo.rx_mc_byte_cnt = pTlStats->rxMCBcnt; + pMac->roam.classDStatsInfo.rx_mc_frm_cnt = pTlStats->rxMCFcnt; + pMac->roam.classDStatsInfo.rx_rate = pTlStats->rxRate; + //?? need per AC + pMac->roam.classDStatsInfo.rx_uc_byte_cnt[0] = pTlStats->rxUCBcnt; + pMac->roam.classDStatsInfo.rx_uc_frm_cnt = pTlStats->rxUCFcnt; + pMac->roam.classDStatsInfo.tx_bc_byte_cnt = pTlStats->txBCBcnt; + pMac->roam.classDStatsInfo.tx_bc_frm_cnt = pTlStats->txBCFcnt; + pMac->roam.classDStatsInfo.tx_mc_byte_cnt = pTlStats->txMCBcnt; + pMac->roam.classDStatsInfo.tx_mc_frm_cnt = pTlStats->txMCFcnt; + //?? need per AC + pMac->roam.classDStatsInfo.tx_uc_byte_cnt[0] = pTlStats->txUCBcnt; + pMac->roam.classDStatsInfo.tx_uc_frm_cnt = pTlStats->txUCFcnt; + +} + +void csrRoamReportStatistics(tpAniSirGlobal pMac, tANI_U32 statsMask, + tCsrStatsCallback callback, tANI_U8 staId, void *pContext) +{ + tANI_U8 stats[500]; + tANI_U8 *pStats = NULL; + tANI_U32 tempMask = 0; + tANI_U8 counter = 0; + if(!callback) + { + smsLog(pMac, LOGE, FL("Cannot report callback NULL")); + return; + } + if(!statsMask) + { + smsLog(pMac, LOGE, FL("Cannot report statsMask is 0")); + return; + } + pStats = stats; + tempMask = statsMask; + while(tempMask) + { + if(tempMask & 1) + { + //new stats info from PE, fill up the stats strucutres in PMAC + switch(counter) + { + case eCsrSummaryStats: + smsLog( pMac, LOG2, FL("Summary stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.summaryStatsInfo, + sizeof(tCsrSummaryStatsInfo)); + pStats += sizeof(tCsrSummaryStatsInfo); + break; + case eCsrGlobalClassAStats: + smsLog( pMac, LOG2, FL("ClassA stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classAStatsInfo, + sizeof(tCsrGlobalClassAStatsInfo)); + pStats += sizeof(tCsrGlobalClassAStatsInfo); + break; + case eCsrGlobalClassBStats: + smsLog( pMac, LOG2, FL("ClassB stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classBStatsInfo, + sizeof(tCsrGlobalClassBStatsInfo)); + pStats += sizeof(tCsrGlobalClassBStatsInfo); + break; + case eCsrGlobalClassCStats: + smsLog( pMac, LOG2, FL("ClassC stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classCStatsInfo, + sizeof(tCsrGlobalClassCStatsInfo)); + pStats += sizeof(tCsrGlobalClassCStatsInfo); + break; + case eCsrGlobalClassDStats: + smsLog( pMac, LOG2, FL("ClassD stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.classDStatsInfo, + sizeof(tCsrGlobalClassDStatsInfo)); + pStats += sizeof(tCsrGlobalClassDStatsInfo); + break; + case eCsrPerStaStats: + smsLog( pMac, LOG2, FL("PerSta stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.perStaStatsInfo[staId], + sizeof(tCsrPerStaStatsInfo)); + pStats += sizeof(tCsrPerStaStatsInfo); + break; + case eCsrPerPktStats: + smsLog( pMac, LOG2, FL("PerPkt stats")); + vos_mem_copy( pStats, (tANI_U8 *)&pMac->roam.perPktStatsInfo, + sizeof(tPerTxPacketFrmFw)); + pStats += sizeof(tPerTxPacketFrmFw); + break; + default: + smsLog( pMac, LOGE, FL("Unknown stats type and counter %d"), counter); + break; + } + } + tempMask >>=1; + counter++; + } + callback(stats, pContext ); +} + +eHalStatus csrRoamDeregStatisticsReq(tpAniSirGlobal pMac) +{ + tListElem *pEntry = NULL; + tListElem *pPrevEntry = NULL; + tCsrStatsClientReqInfo *pTempStaEntry = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + pEntry = csrLLPeekHead( &pMac->roam.statsClientReqList, LL_ACCESS_LOCK ); + if(!pEntry) + { + //list empty + smsLog(pMac, LOGW, "csrRoamDeregStatisticsReq: List empty, no request from " + "upper layer client(s)"); + return status; + } + while( pEntry ) + { + if(pPrevEntry) + { + pTempStaEntry = GET_BASE_ADDR( pPrevEntry, tCsrStatsClientReqInfo, link ); + //send up the stats report + csrRoamReportStatistics(pMac, pTempStaEntry->statsMask, pTempStaEntry->callback, + pTempStaEntry->staId, pTempStaEntry->pContext); + csrRoamRemoveStatListEntry(pMac, pPrevEntry); + } + pTempStaEntry = GET_BASE_ADDR( pEntry, tCsrStatsClientReqInfo, link ); + if (pTempStaEntry->pPeStaEntry) //pPeStaEntry can be NULL + { + pTempStaEntry->pPeStaEntry->numClient--; + //check if we need to delete the entry from peStatsReqList too + if(!pTempStaEntry->pPeStaEntry->numClient) + { + csrRoamRemoveEntryFromPeStatsReqList(pMac, pTempStaEntry->pPeStaEntry); + } + } + //check if we need to stop the tl stats timer too + pMac->roam.tlStatsReqInfo.numClient--; + if(!pMac->roam.tlStatsReqInfo.numClient) + { + if(pMac->roam.tlStatsReqInfo.timerRunning) + { + status = vos_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("csrRoamDeregStatisticsReq:cannot stop TlStatsTimer timer")); + //we will continue + } + } + pMac->roam.tlStatsReqInfo.periodicity = 0; + pMac->roam.tlStatsReqInfo.timerRunning = FALSE; + } + if (pTempStaEntry->periodicity) + { + //While creating StaEntry in csrGetStatistics, + //Initializing and starting timer only when periodicity is set. + //So Stop and Destroy timer only when periodicity is set. + + vos_timer_stop( &pTempStaEntry->timer ); + // Destroy the vos timer... + vosStatus = vos_timer_destroy( &pTempStaEntry->timer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + smsLog(pMac, LOGE, FL("csrRoamDeregStatisticsReq:failed to destroy Client req timer")); + } + } + + + pPrevEntry = pEntry; + pEntry = csrLLNext( &pMac->roam.statsClientReqList, pEntry, LL_ACCESS_NOLOCK ); + } + //the last one + if(pPrevEntry) + { + pTempStaEntry = GET_BASE_ADDR( pPrevEntry, tCsrStatsClientReqInfo, link ); + //send up the stats report + csrRoamReportStatistics(pMac, pTempStaEntry->statsMask, pTempStaEntry->callback, + pTempStaEntry->staId, pTempStaEntry->pContext); + csrRoamRemoveStatListEntry(pMac, pPrevEntry); + } + return status; + +} + +eHalStatus csrIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tRequestFullPowerReason *pReason, + tANI_BOOLEAN *pfNeedPower ) +{ + tANI_BOOLEAN fNeedFullPower = eANI_BOOLEAN_FALSE; + tRequestFullPowerReason reason = eSME_REASON_OTHER; + tPmcState pmcState; + eHalStatus status = eHAL_STATUS_SUCCESS; + // TODO : Session info unavailable + tANI_U32 sessionId = 0; + if( pfNeedPower ) + { + *pfNeedPower = eANI_BOOLEAN_FALSE; + } + //We only handle CSR commands + if( !(eSmeCsrCommandMask & pCommand->command) ) + { + return eHAL_STATUS_SUCCESS; + } + //Check PMC state first + pmcState = pmcGetPmcState( pMac ); + switch( pmcState ) + { + case REQUEST_IMPS: + case IMPS: + if( eSmeCommandScan == pCommand->command ) + { + switch( pCommand->u.scanCmd.reason ) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eCsrScanGetLfrResult: +#endif + case eCsrScanGetResult: + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + case eCsrScanGetScanChnInfo: + //Internal process, no need for full power + fNeedFullPower = eANI_BOOLEAN_FALSE; + break; + default: + //Other scans are real scan, ask for power + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + } //switch + } + else + { + //ask for power for roam and status change + fNeedFullPower = eANI_BOOLEAN_TRUE; + } + break; + case REQUEST_BMPS: + case BMPS: + case REQUEST_START_UAPSD: + case UAPSD: + //We treat WOWL same as BMPS + case REQUEST_ENTER_WOWL: + case WOWL: + if( eSmeCommandRoam == pCommand->command ) + { + tScanResultList *pBSSList = (tScanResultList *)pCommand->u.roamCmd.hBSSList; + tCsrScanResult *pScanResult; + tListElem *pEntry; + switch ( pCommand->u.roamCmd.roamReason ) + { + case eCsrForcedDisassoc: + case eCsrForcedDisassocMICFailure: + reason = eSME_LINK_DISCONNECTED_BY_HDD; + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + case eCsrSmeIssuedDisassocForHandoff: + case eCsrForcedDeauth: + case eCsrHddIssuedReassocToSameAP: + case eCsrSmeIssuedReassocToSameAP: + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + case eCsrCapsChange: + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + case eCsrForcedDisassocSta: + case eCsrForcedDeauthSta: + fNeedFullPower = eANI_BOOLEAN_FALSE; + break; + default: + //Check whether the profile is already connected. If so, no need for full power + //Note: IBSS is ignored for now because we don't support powersave in IBSS + if ( csrIsConnStateConnectedInfra(pMac, sessionId) && pBSSList ) + { + //Only need to check the first one + pEntry = csrLLPeekHead(&pBSSList->List, LL_ACCESS_LOCK); + if( pEntry ) + { + pScanResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); +#if 0 + // TODO : Session Specific info pConnectBssDesc + if( csrIsBssIdEqual( pMac, &pScanResult->Result.BssDescriptor, pMac->roam.pConnectBssDesc ) && + csrIsSsidEqual( pMac, pMac->roam.pConnectBssDesc, + &pScanResult->Result.BssDescriptor, (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ) ) ) + { + // Check to see if the Auth type has changed in the Profile. If so, we don't want to Reassociate + // with Authenticating first. To force this, stop the current association (Disassociate) and + // then re 'Join' the AP, wihch will force an Authentication (with the new Auth type) followed by + // a new Association. + if(csrIsSameProfile(pMac, &pMac->roam.connectedProfile, pProfile)) + { + if(csrRoamIsSameProfileKeys(pMac, &pMac->roam.connectedProfile, pProfile)) + { + //Done, eventually, the command reaches eCsrReassocToSelfNoCapChange; + //No need for full power + //Set the flag so the code later can avoid to do the above + //check again. + pCommand->u.roamCmd.fReassocToSelfNoCapChange = eANI_BOOLEAN_TRUE; + break; + } + } + } +#endif + } + } + //If we are here, full power is needed + fNeedFullPower = eANI_BOOLEAN_TRUE; + break; + } + } + else if( eSmeCommandWmStatusChange == pCommand->command ) + { + //need full power for all + fNeedFullPower = eANI_BOOLEAN_TRUE; + reason = eSME_LINK_DISCONNECTED_BY_OTHER; + } +#ifdef FEATURE_WLAN_TDLS + else if( eSmeCommandTdlsAddPeer == pCommand->command ) + { + //TDLS link is getting established. need full power + fNeedFullPower = eANI_BOOLEAN_TRUE; + reason = eSME_FULL_PWR_NEEDED_BY_TDLS_PEER_SETUP; + } +#endif + else if (eSmeCommandDelStaSession == pCommand->command) + { + //need full power for all + fNeedFullPower = eANI_BOOLEAN_TRUE; + } + + break; + case REQUEST_STOP_UAPSD: + case REQUEST_EXIT_WOWL: + if( eSmeCommandRoam == pCommand->command ) + { + fNeedFullPower = eANI_BOOLEAN_TRUE; + switch ( pCommand->u.roamCmd.roamReason ) + { + case eCsrForcedDisassoc: + case eCsrForcedDisassocMICFailure: + reason = eSME_LINK_DISCONNECTED_BY_HDD; + break; + default: + break; + } + } + break; + case STOPPED: + case REQUEST_STANDBY: + case STANDBY: + case LOW_POWER: + //We are not supposed to do anything + smsLog( pMac, LOGE, FL( "cannot process because PMC is in" + " stopped/standby state %s (%d)" ), + sme_PmcStatetoString(pmcState), pmcState ); + status = eHAL_STATUS_FAILURE; + break; + case FULL_POWER: + case REQUEST_FULL_POWER: + default: + //No need to ask for full power. This has to be FULL_POWER state + break; + } //switch + if( pReason ) + { + *pReason = reason; + } + if( pfNeedPower ) + { + *pfNeedPower = fNeedFullPower; + } + return ( status ); +} + +static eHalStatus csrRequestFullPower( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fNeedFullPower = eANI_BOOLEAN_FALSE; + tRequestFullPowerReason reason = eSME_REASON_OTHER; + status = csrIsFullPowerNeeded( pMac, pCommand, &reason, &fNeedFullPower ); + if( fNeedFullPower && HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestFullPower(pMac, csrFullPowerCallback, pMac, reason); + } + return ( status ); +} + +tSmeCmd *csrGetCommandBuffer( tpAniSirGlobal pMac ) +{ + tSmeCmd *pCmd = smeGetCommandBuffer( pMac ); + if( pCmd ) + { + pMac->roam.sPendingCommands++; + } + return ( pCmd ); +} + +void csrReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + if (pMac->roam.sPendingCommands > 0) + { + //All command allocated through csrGetCommandBuffer need to + //decrement the pending count when releasing. + pMac->roam.sPendingCommands--; + smeReleaseCommand( pMac, pCommand ); + } + else + { + smsLog(pMac, LOGE, FL( "no pending commands")); + VOS_ASSERT(0); + } +} + +//Return SUCCESS is the command is queued, failed +eHalStatus csrQueueSmeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fHighPriority ) +{ + eHalStatus status; + + if (!SME_IS_START(pMac)) + { + smsLog( pMac, LOGE, FL("Sme in stop state")); + return eHAL_STATUS_FAILURE; + } + + if( (eSmeCommandScan == pCommand->command) && pMac->scan.fDropScanCmd ) + { + smsLog(pMac, LOGW, FL(" drop scan (scan reason %d) command"), + pCommand->u.scanCmd.reason); + return eHAL_STATUS_CSR_WRONG_STATE; + } + + if ((pMac->fScanOffload) && (pCommand->command == eSmeCommandScan)) + { + csrLLInsertTail(&pMac->sme.smeScanCmdPendingList, + &pCommand->Link, LL_ACCESS_LOCK); + // process the command queue... + smeProcessPendingQueue(pMac); + status = eHAL_STATUS_SUCCESS; + goto end; + } + + //We can call request full power first before putting the command into pending Q + //because we are holding SME lock at this point. + status = csrRequestFullPower( pMac, pCommand ); + if( HAL_STATUS_SUCCESS( status ) ) + { + tANI_BOOLEAN fNoCmdPending; + //make sure roamCmdPendingList is not empty first + fNoCmdPending = csrLLIsListEmpty( &pMac->roam.roamCmdPendingList, eANI_BOOLEAN_FALSE ); + if( fNoCmdPending ) + { + smePushCommand( pMac, pCommand, fHighPriority ); + } + else + { + //Other commands are waiting for PMC callback, queue the new command to the pending Q + //no list lock is needed since SME lock is held + if( !fHighPriority ) + { + csrLLInsertTail( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + else { + csrLLInsertHead( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + } + } + else if( eHAL_STATUS_PMC_PENDING == status ) + { + //no list lock is needed since SME lock is held + if( !fHighPriority ) + { + csrLLInsertTail( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + else { + csrLLInsertHead( &pMac->roam.roamCmdPendingList, &pCommand->Link, eANI_BOOLEAN_FALSE ); + } + //Let caller know the command is queue + status = eHAL_STATUS_SUCCESS; + } + else + { + //Not to decrease pMac->roam.sPendingCommands here. Caller will decrease it when it + //release the command. + smsLog( pMac, LOGE, FL( " cannot queue command %d" ), pCommand->command ); + } +end: + return ( status ); +} +eHalStatus csrRoamUpdateAPWPSIE( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirAPWPSIEs* pAPWPSIES ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirUpdateAPWPSIEsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL( " Session does not exist for session id %d" ), sessionId); + return eHAL_STATUS_FAILURE; + } + + do + { + pMsg = vos_mem_malloc(sizeof(tSirUpdateAPWPSIEsReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof(tSirUpdateAPWPSIEsReq), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_UPDATE_APWPSIE_REQ); + + pBuf = (tANI_U8 *)&pMsg->transactionId; + VOS_ASSERT(pBuf); + + wTmpBuf = pBuf; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, &pSession->selfMacAddr, + sizeof(tSirMacAddr) ); + pBuf += sizeof(tSirMacAddr); + //sessionId + *pBuf++ = (tANI_U8)sessionId; + // APWPSIEs + vos_mem_copy((tSirAPWPSIEs *)pBuf, pAPWPSIES, sizeof(tSirAPWPSIEs)); + pBuf += sizeof(tSirAPWPSIEs); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32) + (pBuf - wTmpBuf))); //msg_header + msg + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return ( status ); +} +eHalStatus csrRoamUpdateWPARSNIEs( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirRSNie * pAPSirRSNie) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirUpdateAPWPARSNIEsReq *pMsg; + tANI_U8 *pBuf = NULL, *wTmpBuf = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL( " Session does not exist for session id %d" ), sessionId); + return eHAL_STATUS_FAILURE; + } + do + { + pMsg = vos_mem_malloc(sizeof(tSirUpdateAPWPARSNIEsReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set(pMsg, sizeof( tSirUpdateAPWPARSNIEsReq ), 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SET_APWPARSNIEs_REQ); + pBuf = (tANI_U8 *)&pMsg->transactionId; + wTmpBuf = pBuf; + // transactionId + *pBuf = 0; + *( pBuf + 1 ) = 0; + pBuf += sizeof(tANI_U16); + VOS_ASSERT(pBuf); + + // bssId + vos_mem_copy((tSirMacAddr *)pBuf, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + pBuf += sizeof(tSirMacAddr); + // sessionId + *pBuf++ = (tANI_U8)sessionId; + + // APWPARSNIEs + vos_mem_copy((tSirRSNie *)pBuf, pAPSirRSNie, sizeof(tSirRSNie)); + pBuf += sizeof(tSirRSNie); + pMsg->length = pal_cpu_to_be16((tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf))); //msg_header + msg + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return ( status ); +} + +tANI_U32 csrGetdot11Mode(tHalHandle hHal, tANI_U32 sessionId, + tpSirBssDescription pBssDescription) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + eCsrCfgDot11Mode uCfgDot11Mode, cfgDot11Mode; + eHalStatus status; + tDot11fBeaconIEs *ies_local = NULL; + tANI_U32 dot11mode = 0; + + smsLog(pMac, LOG1, FL("phyMode %d"), pSession->pCurRoamProfile->phyMode); + + /* Get IE's */ + status = csrGetParsedBssDescriptionIEs(pMac, pBssDescription, &ies_local); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, LOGE, + FL("csrGetParsedBssDescriptionIEs failed")); + return 0; + } + if(ies_local == NULL) { + smsLog(pMac, LOGE, + FL("ies_local is NULL")); + return 0; + } + + if(csrIsPhyModeMatch(pMac, pSession->pCurRoamProfile->phyMode, + pBssDescription, pSession->pCurRoamProfile, &cfgDot11Mode, ies_local)) + uCfgDot11Mode = cfgDot11Mode; + else + { + smsLog(pMac, LOGE, "Can not find match phy mode"); + if(CSR_IS_CHANNEL_5GHZ(pBssDescription->channelId)) + uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + else + uCfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + + /* dot11mode */ + dot11mode = csrTranslateToWNICfgDot11Mode(pMac, uCfgDot11Mode); + smsLog(pMac, LOG1, + FL("dot11mode %d uCfgDot11Mode %d"), dot11mode, uCfgDot11Mode); + + if (pBssDescription->channelId <= 14 && + FALSE == pMac->roam.configParam.enableVhtFor24GHz && + WNI_CFG_DOT11_MODE_11AC == dot11mode) + { + /* Need to disable VHT operation in 2.4 GHz band */ + dot11mode = WNI_CFG_DOT11_MODE_11N; + } + vos_mem_free(ies_local); + return dot11mode; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +//eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tCsrBssid preAuthBssid, tANI_U8 channelId) +eHalStatus csrRoamIssueFTPreauthReq(tHalHandle hHal, tANI_U32 sessionId, tpSirBssDescription pBssDescription) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpSirFTPreAuthReq pftPreAuthReq; + tANI_U16 auth_req_len = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + auth_req_len = sizeof(tSirFTPreAuthReq); + pftPreAuthReq = (tpSirFTPreAuthReq)vos_mem_malloc(auth_req_len); + if (NULL == pftPreAuthReq) + { + smsLog(pMac, LOGE, FL("Memory allocation for FT Preauth request failed")); + return eHAL_STATUS_RESOURCES; + } + // Save the SME Session ID here. We need it while processing the preauth response + pMac->ft.ftSmeContext.smeSessionId = sessionId; + vos_mem_zero(pftPreAuthReq, auth_req_len); + + pftPreAuthReq->pbssDescription = (tpSirBssDescription)vos_mem_malloc( + sizeof(pBssDescription->length) + pBssDescription->length); + + pftPreAuthReq->messageType = pal_cpu_to_be16(eWNI_SME_FT_PRE_AUTH_REQ); + + pftPreAuthReq->preAuthchannelNum = pBssDescription->channelId; + pftPreAuthReq->dot11mode = + csrGetdot11Mode(hHal, sessionId, pBssDescription); + if (!pftPreAuthReq->dot11mode) + { + smsLog(pMac, LOGE, FL("pftPreAuthReq->dot11mode is zero")); + vos_mem_free(pftPreAuthReq); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy((void *)&pftPreAuthReq->currbssId, + (void *)pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + vos_mem_copy((void *)&pftPreAuthReq->preAuthbssId, + (void *)pBssDescription->bssId, sizeof(tSirMacAddr)); + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (csrRoamIs11rAssoc(pMac) && + (pMac->roam.roamSession[sessionId].connectedProfile.AuthType != eCSR_AUTH_TYPE_OPEN_SYSTEM)) + { + pftPreAuthReq->ft_ies_length = (tANI_U16)pMac->ft.ftSmeContext.auth_ft_ies_length; + vos_mem_copy(pftPreAuthReq->ft_ies, pMac->ft.ftSmeContext.auth_ft_ies, + pMac->ft.ftSmeContext.auth_ft_ies_length); + } + else +#endif + { + pftPreAuthReq->ft_ies_length = 0; + } + vos_mem_copy(pftPreAuthReq->pbssDescription, pBssDescription, + sizeof(pBssDescription->length) + pBssDescription->length); + pftPreAuthReq->length = pal_cpu_to_be16(auth_req_len); + return palSendMBMessage(pMac->hHdd, pftPreAuthReq); +} +/*-------------------------------------------------------------------------- + * This will receive and process the FT Pre Auth Rsp from the current + * associated ap. + * + * This will invoke the hdd call back. This is so that hdd can now + * send the FTIEs from the Auth Rsp (Auth Seq 2) to the supplicant. + ------------------------------------------------------------------------*/ +void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuthRsp ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; +#if defined(FEATURE_WLAN_LFR) || defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) + tCsrRoamInfo roamInfo; +#endif + eCsrAuthType conn_Auth_type; + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + status = csrNeighborRoamPreauthRspHandler(pMac, pFTPreAuthRsp->status); + if (status != eHAL_STATUS_SUCCESS) { + /* + * Bail out if pre-auth was not even processed. + */ + smsLog(pMac, LOGE,FL("Preauth was not processed: %d SessionID: %d"), + status, pFTPreAuthRsp->smeSessionId); + return; + } +#endif + /* The below function calls/timers should be invoked only if the pre-auth is successful */ + if (VOS_STATUS_SUCCESS != (VOS_STATUS)pFTPreAuthRsp->status) + return; + // Implies a success + pMac->ft.ftSmeContext.FTState = eFT_AUTH_COMPLETE; + // Indicate SME QoS module the completion of Preauth success. This will trigger the creation of RIC IEs + pMac->ft.ftSmeContext.psavedFTPreAuthRsp = pFTPreAuthRsp; + /* No need to notify qos module if this is a non 11r & ESE roam*/ + if (csrRoamIs11rAssoc(pMac) +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) + || csrRoamIsESEAssoc(pMac) +#endif + ) + { + sme_QosCsrEventInd(pMac, pMac->ft.ftSmeContext.smeSessionId, SME_QOS_CSR_PREAUTH_SUCCESS_IND, NULL); + } + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_CACHE_ROAM_DELAY_DATA, NULL, 0); + } + /* Start the pre-auth reassoc interval timer with a period of 400ms. When this expires, + * actual transition from the current to handoff AP is triggered */ + status = vos_timer_start(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer, + 60); + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_SME_PREAUTH_REASSOC_START, NULL, 0); + } + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Preauth reassoc interval timer start failed to start with status %d"), status); + return; + } + // Save the received response + vos_mem_copy((void *)&pMac->ft.ftSmeContext.preAuthbssId, + (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); + if (csrRoamIs11rAssoc(pMac)) + csrRoamCallCallback(pMac, pFTPreAuthRsp->smeSessionId, NULL, 0, + eCSR_ROAM_FT_RESPONSE, eCSR_ROAM_RESULT_NONE); + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + if (csrRoamIsESEAssoc(pMac)) + { + /* read TSF */ + csrRoamReadTSF(pMac, (tANI_U8 *)roamInfo.timestamp); + + // Save the bssid from the received response + vos_mem_copy((void *)&roamInfo.bssid, (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pFTPreAuthRsp->smeSessionId, &roamInfo, 0, eCSR_ROAM_CCKM_PREAUTH_NOTIFY, 0); + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +#ifdef FEATURE_WLAN_LFR + // If Legacy Fast Roaming is enabled, signal the supplicant + // So he can send us a PMK-ID for this candidate AP. + if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID)) + { + // Save the bssid from the received response + vos_mem_copy((void *)&roamInfo.bssid, + (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pFTPreAuthRsp->smeSessionId, &roamInfo, 0, eCSR_ROAM_PMK_NOTIFY, 0); + } + +#endif + + // If its an Open Auth, FT IEs are not provided by supplicant + // Hence populate them here + conn_Auth_type = pMac->roam.roamSession[pMac->ft.ftSmeContext.smeSessionId].connectedProfile.AuthType; + pMac->ft.ftSmeContext.addMDIE = FALSE; + if( csrRoamIs11rAssoc(pMac) && + (conn_Auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) + { + tANI_U16 ft_ies_length; + ft_ies_length = pFTPreAuthRsp->ric_ies_length; + + if (pMac->roam.roamSession[pMac->ft.ftSmeContext.smeSessionId]. + connectedProfile.MDID.mdiePresent) + pMac->ft.ftSmeContext.addMDIE = TRUE; + + if ( (pMac->ft.ftSmeContext.reassoc_ft_ies) && + (pMac->ft.ftSmeContext.reassoc_ft_ies_length)) + { + vos_mem_free(pMac->ft.ftSmeContext.reassoc_ft_ies); + pMac->ft.ftSmeContext.reassoc_ft_ies_length = 0; + } + + if (!ft_ies_length) + { + pMac->ft.ftSmeContext.psavedFTPreAuthRsp = NULL; + return; + } + + pMac->ft.ftSmeContext.reassoc_ft_ies = vos_mem_malloc(ft_ies_length); + if ( NULL == pMac->ft.ftSmeContext.reassoc_ft_ies ) + { + smsLog( pMac, LOGE, FL("Memory allocation failed for ft_ies")); + } + else + { + // Copy the RIC IEs to reassoc IEs + vos_mem_copy(((tANI_U8 *)pMac->ft.ftSmeContext.reassoc_ft_ies), + (tANI_U8 *)pFTPreAuthRsp->ric_ies, + pFTPreAuthRsp->ric_ies_length); + pMac->ft.ftSmeContext.reassoc_ft_ies_length = ft_ies_length; + pMac->ft.ftSmeContext.addMDIE = TRUE; + } + } + + // Done with it, init it. + pMac->ft.ftSmeContext.psavedFTPreAuthRsp = NULL; +} +#endif + +#ifdef FEATURE_WLAN_BTAMP_UT_RF +void csrRoamJoinRetryTimerHandler(void *pv) +{ + tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv; + tpAniSirGlobal pMac = pInfo->pMac; + tANI_U32 sessionId = pInfo->sessionId; + tCsrRoamSession *pSession; + + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + smsLog( pMac, LOGE, FL( " retrying the last roam profile on session %d" ), sessionId ); + pSession = CSR_GET_SESSION( pMac, sessionId ); + if(pSession->pCurRoamProfile && csrIsConnStateDisconnected(pMac, sessionId)) + { + if( !HAL_STATUS_SUCCESS(csrRoamJoinLastProfile(pMac, sessionId)) ) + { + smsLog( pMac, LOGE, FL( " fail to retry the last roam profile" ) ); + } + } + } +} +eHalStatus csrRoamStartJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(pSession->pCurRoamProfile && pSession->maxRetryCount) + { + smsLog(pMac, LOGE, FL(" call sessionId %d retry count %d left"), sessionId, pSession->maxRetryCount); + pSession->maxRetryCount--; + pSession->joinRetryTimerInfo.pMac = pMac; + pSession->joinRetryTimerInfo.sessionId = (tANI_U8)sessionId; + status = vos_timer_start(&pSession->hTimerJoinRetry, interval/PAL_TIMER_TO_MS_UNIT); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to start timer status %s"), status); + } + } + else + { + smsLog(pMac, LOGE, FL(" not to start timer due to no profile or reach mac ret (%d)"), + pSession->maxRetryCount); + } + + return (status); +} +eHalStatus csrRoamStopJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + smsLog(pMac, LOGE, " csrRoamStopJoinRetryTimer"); + if( CSR_IS_SESSION_VALID(pMac, sessionId) ) + { + return (vos_timer_stop(&pMac->roam.roamSession[sessionId].hTimerJoinRetry)); + } + + return eHAL_STATUS_SUCCESS; +} +#endif + + +/* + pBuf points to the beginning of the message + LIM packs disassoc rsp as below, + messageType - 2 bytes + messageLength - 2 bytes + sessionId - 1 byte + transactionId - 2 bytes (tANI_U16) + reasonCode - 4 bytes (sizeof(tSirResultCodes)) + peerMacAddr - 6 bytes + The rest is conditionally defined of (WNI_POLARIS_FW_PRODUCT == AP) and not used +*/ +static void csrSerDesUnpackDiassocRsp(tANI_U8 *pBuf, tSirSmeDisassocRsp *pRsp) +{ + if(pBuf && pRsp) + { + pBuf += 4; //skip type and length + pRsp->sessionId = *pBuf++; + pal_get_U16( pBuf, (tANI_U16 *)&pRsp->transactionId ); + pBuf += 2; + pal_get_U32( pBuf, (tANI_U32 *)&pRsp->statusCode ); + pBuf += 4; + vos_mem_copy(pRsp->peerMacAddr, pBuf, 6); + } +} + +eHalStatus csrGetDefaultCountryCodeFrmNv(tpAniSirGlobal pMac, tANI_U8 *pCountry) +{ + static uNvTables nvTables; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = vos_nv_readDefaultCountryTable( &nvTables ); + + /* read the country code from NV and use it */ + if ( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_copy(pCountry, nvTables.defaultCountryTable.countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + return status; + } + else + { + vos_mem_copy(pCountry, "XXX", WNI_CFG_COUNTRY_CODE_LEN); + status = eHAL_STATUS_FAILURE; + return status; + } +} + +eHalStatus csrGetCurrentCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry) +{ + vos_mem_copy(pCountry, pMac->scan.countryCode11d, WNI_CFG_COUNTRY_CODE_LEN); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrSetTxPower(tpAniSirGlobal pMac, v_U8_t sessionId, v_U8_t mW) +{ + tSirSetTxPowerReq *pMsg = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tSirSetTxPowerReq)); + if ( NULL == pMsg ) return eHAL_STATUS_FAILURE; + vos_mem_set((void *)pMsg, sizeof(tSirSetTxPowerReq), 0); + pMsg->messageType = eWNI_SME_SET_TX_POWER_REQ; + pMsg->length = sizeof(tSirSetTxPowerReq); + pMsg->mwPower = mW; + vos_mem_copy((tSirMacAddr *)pMsg->bssId, &pSession->selfMacAddr, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" csr set TX Power Post MSG Fail %d "), status); + //pMsg is freed by palSendMBMessage + } + return status; +} + +eHalStatus csrHT40StopOBSSScan(tpAniSirGlobal pMac, v_U8_t sessionId) +{ + tSirSmeHT40OBSSStopScanInd *pMsg = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + if(IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + { + pMsg = vos_mem_malloc(sizeof(tSirSmeHT40OBSSStopScanInd)); + + if( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL("PMsg is NULL ")); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero((void *)pMsg, sizeof(tSirSmeHT40OBSSStopScanInd)); + pMsg->messageType = eWNI_SME_HT40_STOP_OBSS_SCAN_IND; + pMsg->length = + pal_cpu_to_be16(sizeof(tSirSmeHT40OBSSStopScanInd)); + pMsg->seesionId = sessionId; + vos_mem_copy(pMsg->bssid, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" csr STOP OBSS SCAN Fail %d "), status); + //pMsg is freed by palSendMBMessage + } + } + else + { + smsLog(pMac, LOGE, FL(" OBSS STOP OBSS SCAN is not supported")); + status = eHAL_STATUS_FAILURE; + } + return status; +} +/* Returns whether a session is in VOS_STA_MODE...or not */ +tANI_BOOLEAN csrRoamIsStaMode(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = NULL; + pSession = CSR_GET_SESSION ( pMac, sessionId ); + if(!pSession) + { + smsLog(pMac, LOGE, FL(" %s: session %d not found "), __func__, sessionId); + return eANI_BOOLEAN_FALSE; + } + if ( !CSR_IS_SESSION_VALID ( pMac, sessionId ) ) + { + smsLog(pMac, LOGE, FL(" %s: Inactive session"), __func__); + return eANI_BOOLEAN_FALSE; + } + if ( eCSR_BSS_TYPE_INFRASTRUCTURE != pSession->connectedProfile.BSSType ) + { + return eANI_BOOLEAN_FALSE; + } + /* There is a possibility that the above check may fail,because + * P2P CLI also uses the same BSSType (eCSR_BSS_TYPE_INFRASTRUCTURE) + * when it is connected.So,we may sneak through the above check even + * if we are not a STA mode INFRA station. So, if we sneak through + * the above condition, we can use the following check if we are + * really in STA Mode.*/ + + if ( NULL != pSession->pCurRoamProfile ) + { + if ( pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE ) + { + return eANI_BOOLEAN_TRUE; + } else { + smsLog(pMac, LOGE, FL(" %s: pCurRoamProfile is NULL\n"), __func__); + return eANI_BOOLEAN_FALSE; + } + } + + return eANI_BOOLEAN_FALSE; +} + +/** + * csr_set_src_handoff_request() - Set handoff source to + * SME handoff request + * @pHandoffInfo: Pointer to Handoff info + * @pMsg: Pointer to SME handoff request message + * + * Return: None + */ +#ifndef QCA_WIFI_ISOC +static inline void csr_set_src_handoff_request(tAniHandoffReq *pMsg, + tCsrHandoffRequest *pHandoffInfo) +{ + pMsg->handoff_src = pHandoffInfo->src; +} +#else +static inline void csr_set_src_handoff_request(tAniHandoffReq *pMsg, + tCsrHandoffRequest *pHandoffInfo) +{ +} +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +eHalStatus csrHandoffRequest(tpAniSirGlobal pMac, + tCsrHandoffRequest *pHandoffInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t msg; + + tAniHandoffReq *pMsg; + pMsg = vos_mem_malloc(sizeof(tAniHandoffReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, " csrHandoffRequest: failed to allocate mem for req "); + return eHAL_STATUS_FAILURE; + } + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_HANDOFF_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniHandoffReq); + pMsg->sessionId = pMac->roam.neighborRoamInfo.csrSessionId; + pMsg->channel = pHandoffInfo->channel; + csr_set_src_handoff_request(pMsg, pHandoffInfo); + vos_mem_copy(pMsg->bssid, + pHandoffInfo->bssid, + 6); + msg.type = eWNI_SME_HANDOFF_REQ; + msg.bodyptr = pMsg; + msg.reserved = 0; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, " csrHandoffRequest failed to post msg to self "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + return status; +} +#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */ + +#ifdef WLAN_FEATURE_RMC +eHalStatus csrEnableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tSirSetRMCReq *pMsg = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tSirSetRMCReq)); + if (NULL != pMsg) + { + vos_mem_set((void *)pMsg, sizeof(tSirSetRMCReq), 0); + pMsg->msgType = eWNI_SME_ENABLE_RMC_REQ; + pMsg->msgLen = sizeof(tSirSetRMCReq); + vos_mem_copy((v_U8_t *)pMsg->mcastTransmitter, + &pSession->selfMacAddr, sizeof(tSirMacAddr)); + + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" csr enable RMC Post MSG Fail %d "), status); + //pMsg is freed by palSendMBMessage + } + } + else + { + return eHAL_STATUS_FAILURE; + } + return status; +} + +eHalStatus csrDisableRMC(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tSirSetRMCReq *pMsg = NULL; + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(sizeof(tSirSetRMCReq)); + if (NULL != pMsg) + { + vos_mem_set((void *)pMsg, sizeof(tSirSetRMCReq), 0); + pMsg->msgType = eWNI_SME_DISABLE_RMC_REQ; + pMsg->msgLen = sizeof(tSirSetRMCReq); + vos_mem_copy((v_U8_t *)pMsg->mcastTransmitter, + &pSession->selfMacAddr, sizeof(tSirMacAddr)); + + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" csr disable RMC Post MSG Fail %d "), status); + //pMsg is freed by palSendMBMessage + } + } + else + { + return eHAL_STATUS_FAILURE; + } + return status; +} + +#endif /* WLAN_FEATURE_RMC */ + + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* --------------------------------------------------------------------------- + \fn csrSetCCKMIe + \brief This function stores the CCKM IE passed by the supplicant in a place holder + data structure and this IE will be packed inside reassociation request + \param pMac - pMac global structure + \param sessionId - Current session id + \param pCckmIe - pointer to CCKM IE data + \param ccKmIeLen - length of the CCKM IE + \- return Success or failure + -------------------------------------------------------------------------*/ +VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, + const tANI_U8 *pCckmIe, + const tANI_U8 ccKmIeLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + if (!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pSession->suppCckmIeInfo.cckmIe, pCckmIe, ccKmIeLen); + pSession->suppCckmIeInfo.cckmIeLen = ccKmIeLen; + return status; +} + +/* --------------------------------------------------------------------------- + \fn csrRoamReadTSF + \brief This function reads the TSF; and also add the time elapsed since last beacon or + probe response reception from the hand off AP to arrive at the latest TSF value. + \param pMac - pMac global structure + \param pTimestamp - output TSF timestamp + \- return Success or failure + -------------------------------------------------------------------------*/ +VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrNeighborRoamBSSInfo handoffNode; + tANI_U32 timer_diff = 0; + tANI_U32 timeStamp[2]; + tpSirBssDescription pBssDescription = NULL; + + csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode); + pBssDescription = handoffNode.pBssDescription; + + // Get the time diff in milli seconds + timer_diff = vos_timer_get_system_time() - pBssDescription->scanSysTimeMsec; + // Convert msec to micro sec timer + timer_diff = (tANI_U32)(timer_diff * SYSTEM_TIME_MSEC_TO_USEC); + + timeStamp[0] = pBssDescription->timeStamp[0]; + timeStamp[1] = pBssDescription->timeStamp[1]; + + UpdateCCKMTSF(&(timeStamp[0]), &(timeStamp[1]), &timer_diff); + + vos_mem_copy(pTimestamp, (void *) &timeStamp[0], + sizeof (tANI_U32) * 2); + return status; +} + +#endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + +/* --------------------------------------------------------------------------- + \fn csrDisableDfsChannel + \brief This function will call csrApplyChannelPowerCountryInfo to + \ to trim the list on basis of NO_DFS flag. + \param pMac - pMac global structure + \- return void + -------------------------------------------------------------------------*/ +void csrDisableDfsChannel(tpAniSirGlobal pMac) +{ + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, + pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE); +} + +/* --------------------------------------------------------------------------- + \fn csrGetStaticUapsdMask + \brief This function will get the static uapsd settings for an existing + \ Infra session. + \param pMac - pMac global structure + \- return void + -------------------------------------------------------------------------*/ +void csrGetStaticUapsdMask(tpAniSirGlobal pMac, tANI_U8 *staticUapsdMask) +{ + tANI_S8 sessionId; + tCsrRoamSession *pSession = NULL; + + *staticUapsdMask = 0; + sessionId = csrGetInfraSessionId(pMac); + if(sessionId == -1) + smsLog(pMac, LOGE, FL("Valid session not present.")); + else + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession || !pSession->pCurRoamProfile) + smsLog(pMac, LOGE, FL("Either pSession or Roam profile is NULL," + " pSession:%p"), pSession); + else + *staticUapsdMask = pSession->pCurRoamProfile->uapsd_mask; +} + diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c b/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c new file mode 100644 index 000000000000..4a737a10f9cd --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrApiScan.c @@ -0,0 +1,9507 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrApiScan.c + + Implementation for the Common Scan interfaces. + ========================================================================== */ + +#include "aniGlobal.h" + +#include "palApi.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "smsDebug.h" + +#include "csrSupport.h" +#include "wlan_qct_tl.h" + +#include "vos_diag_core_log.h" +#include "vos_diag_core_event.h" + +#include "vos_nvitem.h" +#include "vos_memory.h" +#include "wlan_qct_wda.h" +#include "vos_utils.h" + +#define MIN_CHN_TIME_TO_FIND_GO 100 +#define MAX_CHN_TIME_TO_FIND_GO 100 +#define DIRECT_SSID_LEN 7 + + +/* Purpose of HIDDEN_TIMER +** When we remove hidden ssid from the profile i.e., forget the SSID via GUI that SSID shouldn't see in the profile +** For above requirement we used timer limit, logic is explained below +** Timer value is initialsed to current time when it receives corresponding probe response of hidden SSID (The probe request is +** received regularly till SSID in the profile. Once it is removed from profile probe request is not sent.) when we receive probe response +** for broadcast probe request, during update SSID with saved SSID we will diff current time with saved SSID time if it is greater than 1 min +** then we are not updating with old one +*/ + +#define HIDDEN_TIMER (1*60*1000) +#define CSR_SCAN_RESULT_RSSI_WEIGHT 80 // must be less than 100, represent the persentage of new RSSI + +/*--------------------------------------------------------------------------- + PER filter constant fraction: it is a % +---------------------------------------------------------------------------*/ +#define CSR_SCAN_PER_FILTER_FRAC 100 + +/*--------------------------------------------------------------------------- + RSSI filter constant fraction: it is a % +---------------------------------------------------------------------------*/ +#define CSR_SCAN_RSSI_FILTER_FRAC 100 + +/*--------------------------------------------------------------------------- +Convert RSSI into overall score: Since RSSI is in -dBm values, and the +overall needs to be weighted inversely (where greater value means better +system), we convert. +RSSI *cannot* be more than 0xFF or less than 0 for meaningful WLAN operation +---------------------------------------------------------------------------*/ +#define CSR_SCAN_MAX_SCORE_VAL 0xFF +#define CSR_SCAN_MIN_SCORE_VAL 0x0 +#define CSR_SCAN_HANDOFF_DELTA 10 + +#define CSR_PURGE_RSSI_THRESHOLD -70 + +#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL 140 +#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL 120 + +#ifndef QCA_WIFI_ISOC +#define MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 30 +#define MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC 20 +#endif + +#define CSR_SCAN_OVERALL_SCORE( rssi ) \ + (( rssi < CSR_SCAN_MAX_SCORE_VAL ) \ + ? (CSR_SCAN_MAX_SCORE_VAL-rssi) : CSR_SCAN_MIN_SCORE_VAL) + + +#define CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) \ + ( (pMac)->scan.nBssLimit <= (csrLLCount(&(pMac)->scan.scanResultList)) ) + +#define THIRTY_PERCENT(x) (x*30/100); + +#define MANDATORY_BG_CHANNEL 11 + +#ifndef CONFIG_ENABLE_LINUX_REG +tCsrIgnoreChannels countryIgnoreList[MAX_COUNTRY_IGNORE] = { + { {'U','A'}, { 136, 140}, 2}, + { {'T','W'}, { 36, 40, 44, 48, 52}, 5}, + { {'I','D'}, { 165}, 1 }, + { {'A','U'}, { 120, 124, 128}, 3 }, + { {'A','R'}, { 120, 124, 128}, 3 } + }; +#else +tCsrIgnoreChannels countryIgnoreList[MAX_COUNTRY_IGNORE] = { }; +#endif //CONFIG_ENABLE_LINUX_REG + +//*** This is temporary work around. It need to call CCM api to get to CFG later +/// Get string parameter value +extern tSirRetStatus wlan_cfgGetStr(tpAniSirGlobal, tANI_U16, tANI_U8*, tANI_U32*); + +void csrScanGetResultTimerHandler(void *); +void csr_handle_disable_scan(void *pv); +static void csrPurgeScanResultByAge(void *pv); +void csrScanIdleScanTimerHandler(void *); +static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest); +#ifdef WLAN_AP_STA_CONCURRENCY +static void csrStaApConcTimerHandler(void *); +#endif +tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId); +eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels ); +void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId ); +void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode ); +void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList ); +//if bgPeriod is 0, background scan is disabled. It is in millisecond units +eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod); +eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus); +static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels, + tANI_U8 numChn, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs **ppIes ); +eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels); +void csrReleaseCmdSingle(tpAniSirGlobal pMac, tSmeCmd *pCommand); +tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel ); +void csrPruneChannelListForMode( tpAniSirGlobal pMac, tCsrChannel *pChannelList ); +void csrPurgeScanResults(tpAniSirGlobal pMac); + + + + +static void csrReleaseScanCmdPendingList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + + while((pEntry = csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK)) != NULL) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCsrCommandMask & pCommand->command ) + { + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_TRUE ); + } + else + { + smsLog(pMac, LOGE, FL("Error: Received command : %d"),pCommand->command); + } + } +} +//pResult is invalid calling this function. +void csrFreeScanResultEntry( tpAniSirGlobal pMac, tCsrScanResult *pResult ) +{ + if( NULL != pResult->Result.pvIes ) + { + vos_mem_free(pResult->Result.pvIes); + } + vos_mem_free(pResult); +} + + +static eHalStatus csrLLScanPurgeResult(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry; + tCsrScanResult *pBssDesc; + + csrLLLock(pList); + + while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + csrFreeScanResultEntry( pMac, pBssDesc ); + } + + csrLLUnlock(pList); + + return (status); +} + +eHalStatus csrScanOpen( tpAniSirGlobal pMac ) +{ + eHalStatus status; + + do + { + csrLLOpen(pMac->hHdd, &pMac->scan.scanResultList); + csrLLOpen(pMac->hHdd, &pMac->scan.tempScanResults); + csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList24); + csrLLOpen(pMac->hHdd, &pMac->scan.channelPowerInfoList5G); +#ifdef WLAN_AP_STA_CONCURRENCY + csrLLOpen(pMac->hHdd, &pMac->scan.scanCmdPendingList); +#endif + pMac->scan.fFullScanIssued = eANI_BOOLEAN_FALSE; + pMac->scan.nBssLimit = CSR_MAX_BSS_SUPPORT; + status = vos_timer_init(&pMac->scan.hTimerGetResult, VOS_TIMER_TYPE_SW, csrScanGetResultTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for getResult timer")); + break; + } +#ifdef WLAN_AP_STA_CONCURRENCY + status = vos_timer_init(&pMac->scan.hTimerStaApConcTimer, VOS_TIMER_TYPE_SW, csrStaApConcTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for hTimerStaApConcTimer timer")); + break; + } +#endif + status = vos_timer_init(&pMac->scan.hTimerIdleScan, VOS_TIMER_TYPE_SW, csrScanIdleScanTimerHandler, pMac); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("cannot allocate memory for idleScan timer")); + break; + } + status = vos_timer_init(&pMac->scan.disable_scan_during_sco_timer, + VOS_TIMER_TYPE_SW, + csr_handle_disable_scan, + pMac); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, LOGE, + FL("cannot allocate memory for disable_scan_during_sco_timer")); + break; + } + }while(0); + + return (status); +} + + +eHalStatus csrScanClose( tpAniSirGlobal pMac ) +{ + csrLLScanPurgeResult(pMac, &pMac->scan.tempScanResults); + csrLLScanPurgeResult(pMac, &pMac->scan.scanResultList); +#ifdef WLAN_AP_STA_CONCURRENCY + csrReleaseScanCmdPendingList(pMac); +#endif + csrLLClose(&pMac->scan.scanResultList); + csrLLClose(&pMac->scan.tempScanResults); +#ifdef WLAN_AP_STA_CONCURRENCY + csrLLClose(&pMac->scan.scanCmdPendingList); +#endif + csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList24); + csrPurgeChannelPower(pMac, &pMac->scan.channelPowerInfoList5G); + csrLLClose(&pMac->scan.channelPowerInfoList24); + csrLLClose(&pMac->scan.channelPowerInfoList5G); + csrScanDisable(pMac); + vos_timer_destroy(&pMac->scan.hTimerGetResult); +#ifdef WLAN_AP_STA_CONCURRENCY + vos_timer_destroy(&pMac->scan.hTimerStaApConcTimer); +#endif + vos_timer_destroy(&pMac->scan.hTimerIdleScan); + vos_timer_destroy(&pMac->scan.disable_scan_during_sco_timer); + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus csrScanEnable( tpAniSirGlobal pMac ) +{ + + pMac->scan.fScanEnable = eANI_BOOLEAN_TRUE; + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus csrScanDisable( tpAniSirGlobal pMac ) +{ + + csrScanStopTimers(pMac); + pMac->scan.fScanEnable = eANI_BOOLEAN_FALSE; + + return eHAL_STATUS_SUCCESS; +} + + +//Set scan timing parameters according to state of other driver sessions +//No validation of the parameters is performed. +static void csrSetDefaultScanTiming( tpAniSirGlobal pMac, tSirScanType scanType, tCsrScanRequest *pScanRequest) +{ +#ifdef WLAN_AP_STA_CONCURRENCY + if(csrIsAnySessionConnected(pMac)) + { + //Reset passive scan time as per ini parameter. + ccmCfgSetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + pMac->roam.configParam.nPassiveMaxChnTimeConc, + NULL,eANI_BOOLEAN_FALSE); + //If multi-session, use the appropriate default scan times + if(scanType == eSIR_ACTIVE_SCAN) + { + pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTimeConc; + pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTimeConc; + } + else + { + pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTimeConc; + pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTimeConc; + } + pScanRequest->max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pScanRequest->min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + + pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc; + + //Return so that fields set above will not be overwritten. + return; + } +#endif + + //This portion of the code executed if multi-session not supported + //(WLAN_AP_STA_CONCURRENCY not defined) or no multi-session. + //Use the "regular" (non-concurrency) default scan timing. + ccmCfgSetInt(pMac, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, + pMac->roam.configParam.nPassiveMaxChnTime, + NULL,eANI_BOOLEAN_FALSE); + if(pScanRequest->scanType == eSIR_ACTIVE_SCAN) + { + pScanRequest->maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pScanRequest->minChnTime = pMac->roam.configParam.nActiveMinChnTime; + } + else + { + pScanRequest->maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + pScanRequest->minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + } + pScanRequest->max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pScanRequest->min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + +#ifdef WLAN_AP_STA_CONCURRENCY + //No rest time if no sessions are connected. + pScanRequest->restTime = 0; +#endif +} + +#ifdef WLAN_AP_STA_CONCURRENCY +//Return SUCCESS is the command is queued, else returns eHAL_STATUS_FAILURE +eHalStatus csrQueueScanRequest( tpAniSirGlobal pMac, tSmeCmd *pScanCmd ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + tANI_BOOLEAN fNoCmdPending; + tSmeCmd *pQueueScanCmd=NULL; + tSmeCmd *pSendScanCmd=NULL; + tANI_U8 nNumChanCombinedConc = 0; + if (NULL == pScanCmd) + { + smsLog (pMac, LOGE, FL("Scan Req cmd is NULL")); + return eHAL_STATUS_FAILURE; + } + /* split scan if any one of the following: + * - STA session is connected and the scan is not a P2P search + * - any P2P session is connected + * Do not split scans if no concurrent infra connections are + * active and if the scan is a BG scan triggered by LFR (OR) + * any scan if LFR is in the middle of a BG scan. Splitting + * the scan is delaying the time it takes for LFR to find + * candidates and resulting in disconnects. + */ + + if(csrIsStaSessionConnected(pMac) && + !csrIsP2pSessionConnected(pMac)) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc; + } + else if(csrIsP2pSessionConnected(pMac)) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc; + } + if ( (csrIsStaSessionConnected(pMac) && +#ifdef FEATURE_WLAN_LFR + (csrIsConcurrentInfraConnected(pMac) || + ((pScanCmd->u.scanCmd.reason != eCsrScanBgScan) && + (pMac->roam.neighborRoamInfo.neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) && +#endif + (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) || + (csrIsP2pSessionConnected(pMac)) ) + { + tCsrScanRequest scanReq; + tANI_U8 numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo; + tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_BOOLEAN bMemAlloc = eANI_BOOLEAN_FALSE; + + if (numChn == 0) + { + + numChn = pMac->scan.baseChannels.numChannels; + + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(numChn); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + { + smsLog( pMac, LOGE, FL(" Failed to get memory for channel list ") ); + return eHAL_STATUS_FAILURE; + } + bMemAlloc = eANI_BOOLEAN_TRUE; + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, + pMac->scan.baseChannels.channelList, numChn); + status = eHAL_STATUS_SUCCESS; + if( !HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + smsLog( pMac, LOGE, FL(" Failed to copy memory to channel list ") ); + return eHAL_STATUS_FAILURE; + } + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Total Number of channels to scan : %d " + "Splitted in group of %d ", __func__, numChn, + nNumChanCombinedConc); + //Whenever we get a scan request with multiple channels we break it up into 2 requests + //First request for first channel to scan and second request to scan remaining channels + if ( numChn > nNumChanCombinedConc) + { + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + + pQueueScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only + if (!pQueueScanCmd) + { + if (bMemAlloc) + { + vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + + } + smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer") ); + return eHAL_STATUS_FAILURE; + } + pQueueScanCmd->command = pScanCmd->command; + pQueueScanCmd->sessionId = pScanCmd->sessionId; + pQueueScanCmd->u.scanCmd.callback = pScanCmd->u.scanCmd.callback; + pQueueScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext; + pQueueScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason; + pQueueScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + + /* First copy all the parameters to local variable of scan request */ + csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest); + + /* Now modify the elements of local var scan request required to be modified for split scan */ + if(scanReq.ChannelInfo.ChannelList != NULL) + { + vos_mem_free(scanReq.ChannelInfo.ChannelList); + scanReq.ChannelInfo.ChannelList = NULL; + } + + pChnInfo->numOfChannels = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels - nNumChanCombinedConc; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL(" &channelToScan %p pScanCmd(%p) pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList(%p)numChn(%d)"), + &channelToScan[0], pScanCmd, + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, numChn); + + vos_mem_copy(&channelToScan[0], + &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[ + nNumChanCombinedConc], + pChnInfo->numOfChannels * sizeof(tANI_U8)); + + pChnInfo->ChannelList = &channelToScan[0]; + + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq); + + status = csrScanCopyRequest(pMac, &pQueueScanCmd->u.scanCmd.u.scanRequest, &scanReq); + + if(!HAL_STATUS_SUCCESS(status)) + { + if (bMemAlloc) + { + vos_mem_free(pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + + } + if( scanReq.pIEField != NULL) + { + vos_mem_free(scanReq.pIEField); + scanReq.pIEField = NULL; + } + smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d"), status ); + return eHAL_STATUS_FAILURE; + } + /* Clean the local scan variable */ + scanReq.ChannelInfo.ChannelList = NULL; + scanReq.ChannelInfo.numOfChannels = 0; + csrScanFreeRequest(pMac, &scanReq); + + /* setup the command to scan 2 channels */ + pSendScanCmd = pScanCmd; + pSendScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nNumChanCombinedConc; + pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest); + pSendScanCmd->u.scanCmd.callback = NULL; + } else { + pSendScanCmd = pScanCmd; + pSendScanCmd->u.scanCmd.u.scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, pSendScanCmd->u.scanCmd.u.scanRequest.scanType, &pSendScanCmd->u.scanCmd.u.scanRequest); + } + + fNoCmdPending = csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK ); + + //Logic Below is as follows + // If the scanCmdPendingList is empty then we directly send that command + // to smeCommandQueue else we buffer it in our scanCmdPendingList Queue + if( fNoCmdPending ) + { + if (pQueueScanCmd != NULL) + { + csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK ); + } + + if (pSendScanCmd != NULL) + { + return csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE); + } + } + else + { + if (pSendScanCmd != NULL) + { + csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pSendScanCmd->Link, LL_ACCESS_LOCK ); + } + + if (pQueueScanCmd != NULL) + { + csrLLInsertTail( &pMac->scan.scanCmdPendingList, &pQueueScanCmd->Link, LL_ACCESS_LOCK ); + } + } + } + else + { //No concurrency case + smsLog( pMac, LOG2, FL("Queuing scan command (reason=%d, roamState=%d" + " numOfChannels=%d)"), + pScanCmd->u.scanCmd.reason, + pMac->roam.neighborRoamInfo.neighborRoamState, + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels); + return csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + } + + return ( status ); +} +#endif + +/* --------------------------------------------------------------------------- + \fn csrScan2GOnyRequest + \brief This function will update the scan request with only + 2.4GHz valid channel list. + \param pMac + \param pScanCmd + \param pScanRequest + \return None + -------------------------------------------------------------------------------*/ +static void csrScan2GOnyRequest(tpAniSirGlobal pMac,tSmeCmd *pScanCmd, + tCsrScanRequest *pScanRequest) +{ + tANI_U8 index, channelId, channelListSize = 0; + tANI_U8 channelList2G[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + static tANI_U8 validchannelList[CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS] = {0}; + + VOS_ASSERT(pScanCmd && pScanRequest); + /* To silence the KW tool null check is added */ + if((pScanCmd == NULL) || (pScanRequest == NULL)) + { + smsLog( pMac, LOGE, FL(" pScanCmd or pScanRequest is NULL ")); + return; + } + + if (pScanCmd->u.scanCmd.scanID || + (eCSR_SCAN_REQUEST_FULL_SCAN != pScanRequest->requestType)) + return; + + //Contsruct valid Supported 2.4 GHz Channel List + for( index = 0; index < ARRAY_SIZE(channelList2G); index++ ) + { + channelId = channelList2G[index]; + if ( csrIsSupportedChannel( pMac, channelId ) ) + { + validchannelList[channelListSize++] = channelId; + } + } + + pScanRequest->ChannelInfo.numOfChannels = channelListSize; + pScanRequest->ChannelInfo.ChannelList = validchannelList; +} + +eHalStatus csrScanRequest(tpAniSirGlobal pMac, tANI_U16 sessionId, + tCsrScanRequest *pScanRequest, tANI_U32 *pScanRequestID, + csrScanCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSmeCmd *pScanCmd = NULL; + eCsrConnectState ConnectState; + + if(pScanRequest == NULL) + { + smsLog( pMac, LOGE, FL(" pScanRequest is NULL")); + VOS_ASSERT(0); + return eHAL_STATUS_FAILURE ; + } + + /* During group formation, the P2P client scans for GO with the specific SSID. + * There will be chances of GO switching to other channels because of scan or + * to STA channel in case of STA+GO MCC scenario. So to increase the possibility + * of client to find the GO, the dwell time of scan is increased to 100ms. + */ + if(pScanRequest->p2pSearch) + { + if(pScanRequest->SSIDs.numOfSSIDs) + { + //If the scan request is for specific SSId the length of SSID will be + //greater than 7 as SSID for p2p search contains "DIRECT-") + if(pScanRequest->SSIDs.SSIDList->SSID.length > DIRECT_SSID_LEN) + { + smsLog( pMac, LOG1, FL("P2P: Increasing the min and max Dwell" + " time to %d for specific SSID scan %.*s"), + MAX_CHN_TIME_TO_FIND_GO, + pScanRequest->SSIDs.SSIDList->SSID.length, + pScanRequest->SSIDs.SSIDList->SSID.ssId); + pScanRequest->maxChnTime = MAX_CHN_TIME_TO_FIND_GO; + pScanRequest->minChnTime = MIN_CHN_TIME_TO_FIND_GO; + } + } + } + + do + { + if(pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if(pScanCmd) + { + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->command = eSmeCommandScan; + pScanCmd->sessionId = sessionId; + pScanCmd->u.scanCmd.callback = callback; + pScanCmd->u.scanCmd.pContext = pContext; + if(eCSR_SCAN_REQUEST_11D_SCAN == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScan11d1; + } + else if((eCSR_SCAN_REQUEST_FULL_SCAN == pScanRequest->requestType) || + (eCSR_SCAN_P2P_DISCOVERY == pScanRequest->requestType) +#ifdef SOFTAP_CHANNEL_RANGE + ||(eCSR_SCAN_SOFTAP_CHANNEL_RANGE == pScanRequest->requestType) +#endif + ) + { + pScanCmd->u.scanCmd.reason = eCsrScanUserRequest; + } + else if(eCSR_SCAN_HO_BG_SCAN == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScanBgScan; + } + else if(eCSR_SCAN_HO_PROBE_SCAN == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScanProbeBss; + } + else if(eCSR_SCAN_P2P_FIND_PEER == pScanRequest->requestType) + { + pScanCmd->u.scanCmd.reason = eCsrScanP2PFindPeer; + } + else + { + pScanCmd->u.scanCmd.reason = eCsrScanIdleScan; + } + if(pScanRequest->minChnTime == 0 && pScanRequest->maxChnTime == 0) + { + //The caller doesn't set the time correctly. Set it here + csrSetDefaultScanTiming(pMac, pScanRequest->scanType, + pScanRequest); + smsLog(pMac, LOG1, FL("Setting default min %d and max %d" + " ChnTime"), pScanRequest->minChnTime, + pScanRequest->maxChnTime); + } +#ifdef WLAN_AP_STA_CONCURRENCY + if(pScanRequest->restTime == 0) + { + //Need to set restTime only if at least one session is connected + if(csrIsAnySessionConnected(pMac)) + { + pScanRequest->restTime = pMac->roam.configParam.nRestTimeConc; + } + } +#endif + /*For Standalone wlan : channel time will remain the same. + For BTC with A2DP up: Channel time = Channel time * 2, if station is not already associated. + This has been done to provide a larger scan window for faster connection during btc.Else Scan is seen + to take a long time. + For BTC with A2DP up: Channel time will not be doubled, if station is already associated. + */ + status = csrRoamGetConnectState(pMac,sessionId,&ConnectState); + if (HAL_STATUS_SUCCESS(status) && + pMac->btc.fA2DPUp && + (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED != ConnectState) && + (eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED != ConnectState)) + { + pScanRequest->maxChnTime = pScanRequest->maxChnTime << 1; + pScanRequest->minChnTime = pScanRequest->minChnTime << 1; + smsLog( pMac, LOG1, FL("BTC A2DP up, doubling max and min" + " ChnTime (Max=%d Min=%d)"), + pScanRequest->maxChnTime, + pScanRequest->minChnTime); + } + + pScanRequest->max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pScanRequest->min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + + if(pScanRequestID) + { + *pScanRequestID = pScanCmd->u.scanCmd.scanID; + } + + // If it is the first scan request from HDD, CSR checks if it is for 11d. + // If it is not, CSR will save the scan request in the pending cmd queue + // & issue an 11d scan request to PE. + if (((0 == pScanCmd->u.scanCmd.scanID) + && (eCSR_SCAN_REQUEST_11D_SCAN != pScanRequest->requestType)) +#ifdef SOFTAP_CHANNEL_RANGE + && (eCSR_SCAN_SOFTAP_CHANNEL_RANGE != pScanRequest->requestType) +#endif + && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d) + ) + { + tSmeCmd *p11dScanCmd; + tCsrScanRequest scanReq; + tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo; + + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + + p11dScanCmd = csrGetCommandBuffer(pMac); + if (p11dScanCmd) + { + tANI_U32 numChn = pMac->scan.baseChannels.numChannels; + + vos_mem_set(&p11dScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pChnInfo->ChannelList = vos_mem_malloc(numChn); + if ( NULL == pChnInfo->ChannelList ) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory")); + status = eHAL_STATUS_FAILURE; + break; + } + vos_mem_copy(pChnInfo->ChannelList, + pMac->scan.baseChannels.channelList, + numChn); + pChnInfo->numOfChannels = (tANI_U8)numChn; + + p11dScanCmd->command = eSmeCommandScan; + p11dScanCmd->u.scanCmd.callback = pMac->scan.callback11dScanDone; + p11dScanCmd->u.scanCmd.pContext = NULL; + p11dScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + + if ( csrIs11dSupported(pMac) ) + { + scanReq.scanType = eSIR_PASSIVE_SCAN; + scanReq.requestType = eCSR_SCAN_REQUEST_11D_SCAN; + p11dScanCmd->u.scanCmd.reason = eCsrScan11d1; + scanReq.maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + scanReq.minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + } + else + { + scanReq.scanType = pScanRequest->scanType; + scanReq.requestType = eCSR_SCAN_IDLE_MODE_SCAN; + p11dScanCmd->u.scanCmd.reason = eCsrScanIdleScan; + scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + + scanReq.max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + scanReq.min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + } + if (pMac->roam.configParam.nInitialDwellTime) + { + scanReq.maxChnTime = + pMac->roam.configParam.nInitialDwellTime; + smsLog(pMac, LOG1, FL("11d scan, updating" + "dwell time for first scan %u"), + scanReq.maxChnTime); + } + if ((pScanCmd->u.scanCmd.reason == eCsrScanUserRequest) + && !(pScanRequest->p2pSearch) + &&(pScanRequest->ChannelInfo.numOfChannels + < pMac->roam.configParam. + max_chan_for_dwell_time_cfg)) + { + pScanRequest->maxChnTime = + pScanRequest->maxChnTime << 1; + pScanRequest->minChnTime = + pScanRequest->minChnTime << 1; + smsLog(pMac, LOG1, + FL("Double ChnTime (Max=%d Min=%d) numOfChannels=%d max_chan_for_dwell_time_cfg=%d"), + pScanRequest->maxChnTime, + pScanRequest->minChnTime, + pScanRequest->ChannelInfo.numOfChannels, + pMac->roam.configParam. + max_chan_for_dwell_time_cfg); + } + + status = csrScanCopyRequest(pMac, &p11dScanCmd->u.scanCmd.u.scanRequest, &scanReq); + //Free the channel list + vos_mem_free(pChnInfo->ChannelList); + pChnInfo->ChannelList = NULL; + + if (HAL_STATUS_SUCCESS(status)) + { + pMac->scan.scanProfile.numOfChannels = + p11dScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + //Start process the command +#ifdef WLAN_AP_STA_CONCURRENCY + if (!pMac->fScanOffload) + status = csrQueueScanRequest(pMac, p11dScanCmd); + else + status = csrQueueSmeCommand(pMac, p11dScanCmd, + eANI_BOOLEAN_FALSE); +#else + status = csrQueueSmeCommand(pMac, p11dScanCmd, eANI_BOOLEAN_FALSE); +#endif + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGE, FL("Failed to send message" + " status = %d"), status); + break; + } + } + else + { + smsLog(pMac, LOGE, FL("csrScanCopyRequest failed")); + break; + } + } + else + { + //error + smsLog( pMac, LOGE, FL("p11dScanCmd failed") ); + break; + } + } + + //Scan only 2G Channels if set in ini file + //This is mainly to reduce the First Scan duration + //Once we turn on Wifi + if(pMac->scan.fFirstScanOnly2GChnl) + { + smsLog( pMac, LOG1, FL("Scanning only 2G Channels during first scan")); + csrScan2GOnyRequest(pMac, pScanCmd, pScanRequest); + } + + if (pMac->roam.configParam.nInitialDwellTime) + { + pScanRequest->maxChnTime = + pMac->roam.configParam.nInitialDwellTime; + pMac->roam.configParam.nInitialDwellTime = 0; + smsLog(pMac, LOG1, + FL("updating dwell time for first scan %u"), + pScanRequest->maxChnTime); + } + + if ((pScanCmd->u.scanCmd.reason == eCsrScanUserRequest) + && !(pScanRequest->p2pSearch) + && (pScanRequest->ChannelInfo.numOfChannels + < pMac->roam.configParam.max_chan_for_dwell_time_cfg)) + { + pScanRequest->maxChnTime = pScanRequest->maxChnTime << 1; + pScanRequest->minChnTime = pScanRequest->minChnTime << 1; + smsLog(pMac, LOG1, + FL("Double ChnTime (Max=%d Min=%d) numOfChannels=%d max_chan_for_dwell_time_cfg=%d"), + pScanRequest->maxChnTime, + pScanRequest->minChnTime, + pScanRequest->ChannelInfo.numOfChannels, + pMac->roam.configParam.max_chan_for_dwell_time_cfg); + } + status = csrScanCopyRequest(pMac, &pScanCmd->u.scanCmd.u.scanRequest, pScanRequest); + if(HAL_STATUS_SUCCESS(status)) + { + tCsrScanRequest *pTempScanReq = + &pScanCmd->u.scanCmd.u.scanRequest; + pMac->scan.scanProfile.numOfChannels = + pTempScanReq->ChannelInfo.numOfChannels; + + smsLog( pMac, LOG1, FL(" SId=%d scanId=%d" + " Scan reason=%u numSSIDs=%d" + " numChan=%d P2P search=%d minCT=%d maxCT=%d" + " minCBtc=%d maxCBtx=%d"), + sessionId, pScanCmd->u.scanCmd.scanID, + pScanCmd->u.scanCmd.reason, + pTempScanReq->SSIDs.numOfSSIDs, + pTempScanReq->ChannelInfo.numOfChannels, + pTempScanReq->p2pSearch, + pTempScanReq->minChnTime, + pTempScanReq->maxChnTime, + pTempScanReq->min_chntime_btc_esco, + pTempScanReq->max_chntime_btc_esco); + //Start process the command +#ifdef WLAN_AP_STA_CONCURRENCY + if (!pMac->fScanOffload) + status = csrQueueScanRequest(pMac,pScanCmd); + else + status = csrQueueSmeCommand(pMac, pScanCmd, + eANI_BOOLEAN_FALSE); +#else + status = csrQueueSmeCommand(pMac, pScanCmd, + eANI_BOOLEAN_FALSE); +#endif + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } + else + { + smsLog( pMac, LOGE, FL(" fail to copy request status = %d"), status ); + break; + } + } + else + { + smsLog( pMac, LOGE, FL(" pScanCmd is NULL")); + break; + } + } + else + { + smsLog( pMac, LOGE, FL("SId: %d Scanning not enabled" + " Scan type=%u, numOfSSIDs=%d P2P search=%d"), + sessionId, pScanRequest->requestType, + pScanRequest->SSIDs.numOfSSIDs, + pScanRequest->p2pSearch ); + } + } while(0); + + + if(!HAL_STATUS_SUCCESS(status) && pScanCmd) + { + if( eCsrScanIdleScan == pScanCmd->u.scanCmd.reason ) + { + //Set the flag back for restarting idle scan + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + smsLog( pMac, LOGE, FL(" SId: %d Failed with status=%d" + " Scan reason=%u numOfSSIDs=%d" + " P2P search=%d scanId=%d"), + sessionId, status, pScanCmd->u.scanCmd.reason, + pScanRequest->SSIDs.numOfSSIDs, pScanRequest->p2pSearch, + pScanCmd->u.scanCmd.scanID ); + csrReleaseCommandScan(pMac, pScanCmd); + } + + return (status); +} + + +eHalStatus csrScanRequestResult(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pScanCmd; + + if(pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if(pScanCmd) + { + pScanCmd->command = eSmeCommandScan; + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + pScanCmd->u.scanCmd.reason = eCsrScanGetResult; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan(pMac, pScanCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + } + + return (status); +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +eHalStatus csrScanRequestLfrResult(tpAniSirGlobal pMac, tANI_U32 sessionId, + csrScanCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pScanCmd; + + if (pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if (pScanCmd) + { + pScanCmd->command = eSmeCommandScan; + pScanCmd->sessionId = sessionId; + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.callback = callback; + pScanCmd->u.scanCmd.pContext = pContext; + pScanCmd->u.scanCmd.reason = eCsrScanGetLfrResult; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID; //let it wrap around + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_TRUE); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d\n"), status ); + csrReleaseCommandScan(pMac, pScanCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer\n")); + status = eHAL_STATUS_RESOURCES; + } + } + + return (status); +} +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +eHalStatus csrScanAllChannels(tpAniSirGlobal pMac, eCsrRequestType reqType) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 scanId; + tCsrScanRequest scanReq; + + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = reqType; + scanReq.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + scanReq.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + scanReq.max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + scanReq.min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + //Scan with invalid sessionId. + //This results in SME using the first available session to scan. + status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq, + &scanId, NULL, NULL); + + return (status); +} + + + + +eHalStatus csrIssueRoamAfterLostlinkScan(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamReason reason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = NULL; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId = 0; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + do + { + smsLog(pMac, LOG1, " csrIssueRoamAfterLostlinkScan called"); + if(pSession->fCancelRoaming) + { + smsLog(pMac, LOGW, " lostlink roaming is cancelled"); + csrScanStartIdleScan(pMac); + status = eHAL_STATUS_SUCCESS; + break; + } + //Here is the profile we need to connect to + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + if(NULL == pSession->pCurRoamProfile) + { + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + } + else + { + //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + }//We have a profile + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + if(eCsrLostLink1 == reason) + { + //we want to put the last connected BSS to the very beginning, if possible + csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList); + } + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, reason, + roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, hBSSList); + } + }//Have scan result + } + }while(0); + if(pScanFilter) + { + //we need to free memory for filter if profile exists + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + + return (status); +} + + +eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pScanCmd; + + if(pMac->scan.fScanEnable) + { + pScanCmd = csrGetCommandBuffer(pMac); + if(pScanCmd) + { + pScanCmd->command = eSmeCommandScan; + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.reason = eCsrScanGetScanChnInfo; + //Need to make the following atomic + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + pScanCmd->sessionId = pCommand->sessionId; + if( pCommand->u.scanCmd.reason == eCsrScanUserRequest) + { + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + } else { + pScanCmd->u.scanCmd.callback = pCommand->u.scanCmd.callback; + pScanCmd->u.scanCmd.pContext = pCommand->u.scanCmd.pContext; + pScanCmd->u.scanCmd.abortScanIndication = + pCommand->u.scanCmd.abortScanIndication; + } + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan(pMac, pScanCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + } + + return (status); +} + + +eHalStatus csrScanHandleFailedLostlink1(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " Lostlink scan 1 failed"); + if(pSession->fCancelRoaming) + { + csrScanStartIdleScan(pMac); + } + else if(pSession->pCurRoamProfile) + { + //We fail lostlink1 but there may be other BSS in the cached result fit the profile. Give it a try first + if(pSession->pCurRoamProfile->SSIDs.numOfSSIDs == 0 || + pSession->pCurRoamProfile->SSIDs.numOfSSIDs > 1) + { + //try lostlink scan2 + status = csrScanRequestLostLink2(pMac, sessionId); + } + else if(!pSession->pCurRoamProfile->ChannelInfo.ChannelList || + pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0) + { + //go straight to lostlink scan3 + status = csrScanRequestLostLink3(pMac, sessionId); + } + else + { + //we are done with lostlink + if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + csrScanStartIdleScan(pMac); + } + status = eHAL_STATUS_SUCCESS; + } + } + else + { + status = csrScanRequestLostLink3(pMac, sessionId); + } + + return (status); +} + + + +eHalStatus csrScanHandleFailedLostlink2(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " Lostlink scan 2 failed"); + if(pSession->fCancelRoaming) + { + csrScanStartIdleScan(pMac); + } + else if(!pSession->pCurRoamProfile || !pSession->pCurRoamProfile->ChannelInfo.ChannelList || + pSession->pCurRoamProfile->ChannelInfo.ChannelList[0] == 0) + { + //try lostlink scan3 + status = csrScanRequestLostLink3(pMac, sessionId); + } + else + { + //we are done with lostlink + if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + csrScanStartIdleScan(pMac); + } + } + + return (status); +} + + + +eHalStatus csrScanHandleFailedLostlink3(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOGW, " Lostlink scan 3 failed"); + if(eANI_BOOLEAN_TRUE == csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + //we are done with lostlink + csrScanStartIdleScan(pMac); + } + + return (status); +} + + + + +//Lostlink1 scan is to actively scan the last connected profile's SSID on all matched BSS channels. +//If no roam profile (it should not), it is like lostlinkscan3 +eHalStatus csrScanRequestLostLink1( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrScanResultFilter *pScanFilter = NULL; + tScanResultHandle hBSSList = NULL; + tCsrScanResultInfo *pScanResult = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, FL(" called")); + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.scanCmd.reason = eCsrScanLostLink1; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + pCommand->u.scanCmd.u.scanRequest.max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pCommand->u.scanCmd.u.scanRequest.min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + if(pSession->connectedProfile.SSID.length) + { + pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1; + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID, + &pSession->connectedProfile.SSID, sizeof(tSirMacSSid)); + } + else + { + pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 0; + } + if(pSession->pCurRoamProfile) + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + //Don't change variable status here because whether we can get result or not, the command goes to PE. + //The status is also used to indicate whether the command is queued. Not success meaning not queue + if(HAL_STATUS_SUCCESS((csrScanGetResult(pMac, pScanFilter, &hBSSList))) && hBSSList) + { + tANI_U8 i, nChn = 0; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = + vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && + nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + for(i = 0; i < nChn; i++) + { + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == + pScanResult->BssDescriptor.channelId) + { + break; + } + } + if(i == nChn) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId; + } + } + //Include the last connected BSS' channel + if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel)) + { + for(i = 0; i < nChn; i++) + { + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == + pSession->connectedProfile.operationChannel) + { + break; + } + } + if(i == nChn) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pSession->connectedProfile.operationChannel; + } + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn; + } + else + { + if(csrRoamIsChannelValid(pMac, pSession->connectedProfile.operationChannel)) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(1); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + //just try the last connected channel + if(HAL_STATUS_SUCCESS(status)) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0] = pSession->connectedProfile.operationChannel; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 1; + } + else + { + break; + } + } + } + } + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid)); + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while( 0 ); + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrScanRequestLostLink1 failed with status %d", status); + if(pCommand) + { + csrReleaseCommandScan(pMac, pCommand); + } + status = csrScanHandleFailedLostlink1( pMac, sessionId ); + } + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(hBSSList) + { + csrScanResultPurge(pMac, hBSSList); + } + + return( status ); +} + + +//Lostlink2 scan is to actively scan the all SSIDs of the last roaming profile's on all matched BSS channels. +//Since MAC doesn't support multiple SSID, we scan all SSIDs and filter them afterwards +eHalStatus csrScanRequestLostLink2( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tCsrScanResultFilter *pScanFilter = NULL; + tScanResultHandle hBSSList = NULL; + tCsrScanResultInfo *pScanResult = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, FL(" called")); + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.scanCmd.reason = eCsrScanLostLink2; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + pCommand->u.scanCmd.u.scanRequest.max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pCommand->u.scanCmd.u.scanRequest.min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + if(pSession->pCurRoamProfile) + { + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + if(hBSSList) + { + tANI_U8 i, nChn = 0; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = + vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL == pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + break; + } + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && + nChn < WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + for(i = 0; i < nChn; i++) + { + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] == + pScanResult->BssDescriptor.channelId) + { + break; + } + } + if(i == nChn) + { + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[nChn++] = pScanResult->BssDescriptor.channelId; + } + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = nChn; + } + } + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid)); + //Put to the head in pending queue + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while( 0 ); + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrScanRequestLostLink2 failed with status %d", status); + if(pCommand) + { + csrReleaseCommandScan(pMac, pCommand); + } + status = csrScanHandleFailedLostlink2( pMac, sessionId ); + } + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(hBSSList) + { + csrScanResultPurge(pMac, hBSSList); + } + + return( status ); +} + + +//To actively scan all valid channels +eHalStatus csrScanRequestLostLink3( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + smsLog(pMac, LOGW, FL(" called")); + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->sessionId = (tANI_U8)sessionId; + pCommand->u.scanCmd.reason = eCsrScanLostLink3; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + pCommand->u.scanCmd.u.scanRequest.maxChnTime = pMac->roam.configParam.nActiveMaxChnTime; + pCommand->u.scanCmd.u.scanRequest.minChnTime = pMac->roam.configParam.nActiveMinChnTime; + pCommand->u.scanCmd.u.scanRequest.max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pCommand->u.scanCmd.u.scanRequest.min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + vos_mem_copy(&pCommand->u.scanCmd.u.scanRequest.bssid, bAddr, sizeof(tCsrBssid)); + //Put to the head of pending queue + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + } while( 0 ); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGW, " csrScanRequestLostLink3 failed with status %d", status); + if(csrRoamCompleteRoaming(pMac, sessionId, eANI_BOOLEAN_FALSE, eCSR_ROAM_RESULT_FAILURE)) + { + csrScanStartIdleScan(pMac); + } + if(pCommand) + { + csrReleaseCommandScan(pMac, pCommand); + } + } + + return( status ); +} + + +eHalStatus csrScanHandleSearchForSSID(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = CSR_INVALID_SCANRESULT_HANDLE; + tCsrScanResultFilter *pScanFilter = NULL; + tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + do + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + //if this scan is for LFR + if(pMac->roam.neighborRoamInfo.uOsRequestedHandoff) + { + //notify LFR state m/c + if(eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, eHAL_STATUS_SUCCESS)) + { + csrNeighborRoamStartLfrScan(pMac, REASON_OS_REQUESTED_ROAMING_NOW); + } + status = eHAL_STATUS_SUCCESS; + break; + } +#endif + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + break; + } + /* If Disconnect is already issued from HDD no need to issue connect */ + if (pSession->abortConnection) + { + smsLog(pMac, LOGE, + FL("Disconnect in progress, no need to issue connect")); + break; + } + //If there is roam command waiting, ignore this roam because the newer roam command is the one to execute + if(csrIsRoamCommandWaitingForSession(pMac, sessionId)) + { + smsLog(pMac, LOGW, FL(" aborts because roam command waiting")); + break; + } + if(pProfile == NULL) + break; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, eCsrHddIssued, + pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + }while(0); + if(!HAL_STATUS_SUCCESS(status)) + { + if(CSR_INVALID_SCANRESULT_HANDLE != hBSSList) + { + csrScanResultPurge(pMac, hBSSList); + } + //We haven't done anything to this profile + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, + eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE); + //In case we have nothing else to do, restart idle scan + if(csrIsConnStateDisconnected(pMac, sessionId) && !csrIsRoamCommandWaiting(pMac)) + { + status = csrScanStartIdleScan(pMac); + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //In case of WDS station, let it retry. + if( CSR_IS_WDS_STA(pProfile) ) + { + //Save the roma profile so we can retry + csrFreeRoamProfile( pMac, sessionId ); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL != pSession->pCurRoamProfile ) + { + vos_mem_set(pSession->pCurRoamProfilee, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile); + } + csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD); + } +#endif + } + if (pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + + return (status); +} + + +eHalStatus csrScanHandleSearchForSSIDFailure(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId = pCommand->sessionId; + tCsrRoamProfile *pProfile = pCommand->u.scanCmd.pToRoamProfile; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + //if this scan is for LFR + if(pMac->roam.neighborRoamInfo.uOsRequestedHandoff) + { + //notify LFR state m/c + if(eHAL_STATUS_SUCCESS != csrNeighborRoamSssidScanDone(pMac, eHAL_STATUS_FAILURE)) + { + csrNeighborRoamStartLfrScan(pMac, REASON_OS_REQUESTED_ROAMING_NOW); + } + return eHAL_STATUS_SUCCESS; + } +#endif + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + +#if defined(WLAN_DEBUG) + if(pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs == 1) + { + char str[36]; + vos_mem_copy(str, + pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.ssId, + pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length); + str[pCommand->u.scanCmd.u.scanRequest.SSIDs.SSIDList[0].SSID.length] = 0; + smsLog(pMac, LOGW, FL(" SSID = %s"), str); + } +#endif + //Check whether it is for start ibss. No need to do anything if it is a JOIN request + if(pProfile && CSR_IS_START_IBSS(pProfile)) + { + status = csrRoamIssueConnect(pMac, sessionId, pProfile, NULL, eCsrHddIssued, + pCommand->u.scanCmd.roamId, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("failed to issue startIBSS command with status = 0x%08X"), status); + csrRoamCallCallback(pMac, sessionId, NULL, pCommand->u.scanCmd.roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + } + else + { + eCsrRoamResult roamResult = eCSR_ROAM_RESULT_FAILURE; + + if(csrIsConnStateDisconnected(pMac, sessionId) && + !csrIsRoamCommandWaitingForSession(pMac, sessionId)) + { + status = csrScanStartIdleScan(pMac); + } + if((NULL == pProfile) || !csrIsBssTypeIBSS(pProfile->BSSType)) + { + //Only indicate assoc_completion if we indicate assoc_start. + if(pSession->bRefAssocStartCnt > 0) + { + tCsrRoamInfo *pRoamInfo = NULL, roamInfo; + vos_mem_set(&roamInfo, sizeof(tCsrRoamInfo), 0); + pRoamInfo = &roamInfo; + if(pCommand->u.roamCmd.pRoamBssEntry) + { + tCsrScanResult *pScanResult = + GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, + tCsrScanResult, Link); + roamInfo.pBssDesc = &pScanResult->Result.BssDescriptor; + } + roamInfo.statusCode = pSession->joinFailStatusCode.statusCode; + roamInfo.reasonCode = pSession->joinFailStatusCode.reasonCode; + pSession->bRefAssocStartCnt--; + csrRoamCallCallback(pMac, sessionId, pRoamInfo, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE); + } + else + { + csrRoamCallCallback(pMac, sessionId, NULL, + pCommand->u.scanCmd.roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, + eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE); + } +#ifdef FEATURE_WLAN_BTAMP_UT_RF + //In case of WDS station, let it retry. + if( CSR_IS_WDS_STA(pProfile) ) + { + //Save the roma profile so we can retry + csrFreeRoamProfile( pMac, sessionId ); + pSession->pCurRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL != pSession->pCurRoamProfile ) + { + vos_mem_set(pSession->pCurRoamProfile, sizeof(tCsrRoamProfile), 0); + csrRoamCopyProfile(pMac, pSession->pCurRoamProfile, pProfile); + } + csrRoamStartJoinRetryTimer(pMac, sessionId, CSR_JOIN_RETRY_TIMEOUT_PERIOD); + } +#endif + } + else + { + roamResult = eCSR_ROAM_RESULT_IBSS_START_FAILED; + } + csrRoamCompletion(pMac, sessionId, NULL, pCommand, roamResult, eANI_BOOLEAN_FALSE); + } + + return (status); +} + + +//After scan for cap changes, issue a roaming command to either reconnect to the AP or pick another one to connect +eHalStatus csrScanHandleCapChangeScanComplete(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultHandle hBSSList = NULL; + tCsrScanResultFilter *pScanFilter = NULL; + tANI_U32 roamId = 0; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + do + { + //Here is the profile we need to connect to + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + break; + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + if (NULL == pSession) break; + if (NULL == pSession->pCurRoamProfile) + { + pScanFilter->EncryptionType.numEntries = 1; + pScanFilter->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE; + } + else + { + //We have to make a copy of pCurRoamProfile because it will be free inside csrRoamIssueConnect + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) + break; + status = csrRoamPrepareFilterFromProfile(pMac, pProfile, pScanFilter); + }//We have a profile + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + //we want to put the last connected BSS to the very beginning, if possible + csrMoveBssToHeadFromBSSID(pMac, &pSession->connectedProfile.bssid, hBSSList); + status = csrRoamIssueConnect(pMac, sessionId, pProfile, hBSSList, + eCsrCapsChange, 0, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, hBSSList); + } + }//Have scan result + else + { + smsLog(pMac, LOGW, FL("cannot find matching BSS of " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pSession->connectedProfile.bssid)); + //Disconnect + csrRoamDisconnectInternal(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } + }while(0); + if(pScanFilter) + { + csrFreeScanFilter(pMac, pScanFilter); + vos_mem_free(pScanFilter); + } + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + + return (status); +} + + + +eHalStatus csrScanResultPurge(tpAniSirGlobal pMac, tScanResultHandle hScanList) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tScanResultList *pScanList = (tScanResultList *)hScanList; + + if(pScanList) + { + status = csrLLScanPurgeResult(pMac, &pScanList->List); + csrLLClose(&pScanList->List); + vos_mem_free(pScanList); + } + return (status); +} + + +static tANI_U32 csrGetBssPreferValue(tpAniSirGlobal pMac, int rssi) +{ + tANI_U32 ret = 0; + int i = CSR_NUM_RSSI_CAT - 1; + + while(i >= 0) + { + if(rssi >= pMac->roam.configParam.RSSICat[i]) + { + ret = pMac->roam.configParam.BssPreferValue[i]; + break; + } + i--; + }; + + return (ret); +} + + +//Return a CapValue base on the capabilities of a BSS +static tANI_U32 csrGetBssCapValue(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + tANI_U32 ret = CSR_BSS_CAP_VALUE_NONE; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if(CSR_IS_ROAM_PREFER_5GHZ(pMac)) + { + if((pBssDesc) && CSR_IS_CHANNEL_5GHZ(pBssDesc->channelId)) + { + ret += CSR_BSS_CAP_VALUE_5GHZ; + } + } +#endif + /* if strict select 5GHz is non-zero then ignore the capability checking */ + if (pIes && !CSR_IS_SELECT_5GHZ_MARGIN(pMac)) + { + //We only care about 11N capability + if(pIes->HTCaps.present) + { + ret += CSR_BSS_CAP_VALUE_HT; + } + if(CSR_IS_QOS_BSS(pIes)) + { + ret += CSR_BSS_CAP_VALUE_WMM; + //Give advantage to UAPSD + if(CSR_IS_UAPSD_BSS(pIes)) + { + ret += CSR_BSS_CAP_VALUE_UAPSD; + } + } + } + + return (ret); +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/* Calculate channel weight based on other APs RSSI and count for + * PER based roaming */ +static tANI_U32 GetPERRoamRssiCountWeight(tANI_S32 rssi, tANI_S32 count) +{ + tANI_S32 rssiWeight=0; + tANI_S32 countWeight=0; + tANI_S32 rssicountWeight=0; + + rssiWeight = ROAMING_RSSI_WEIGHT * (rssi - MIN_RSSI) + /(MAX_RSSI - MIN_RSSI); + + if(rssiWeight > ROAMING_RSSI_WEIGHT) + rssiWeight = ROAMING_RSSI_WEIGHT; + else if (rssiWeight < 0) + rssiWeight = 0; + + countWeight = ROAM_AP_COUNT_WEIGHT * (count + ROAM_MIN_COUNT) + /(ROAM_MAX_COUNT + ROAM_MIN_COUNT); + + if(countWeight > ROAM_AP_COUNT_WEIGHT) + countWeight = ROAM_AP_COUNT_WEIGHT; + + rssicountWeight = ROAM_MAX_WEIGHT - (rssiWeight + countWeight); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + FL("rssiWeight=%d, countWeight=%d, rssicountWeight=%d rssi=%d count=%d"), + rssiWeight, countWeight, rssicountWeight, rssi, count); + + return rssicountWeight; +} + +/* Calculate BSS score based on AP capabilty and channel condition + * for PER based roaming */ +static tANI_U32 calculateBssScore(tSirBssDescription *bssInfo, + tANI_S32 best_rssi, tANI_S32 ap_cnt, tANI_S32 cca) +{ + tANI_S32 score = 0; + tANI_S32 ap_load = 0; + tANI_S32 normalised_width = PER_ROAM_20MHZ; + tANI_S32 normalised_rssi = 0; + tANI_S32 channel_weight; + if (bssInfo->rssi) { + /* Calculate % of rssi we are getting + * max = 100 + * min = 0 + * less than -40 = 100% + * -40 - -55 = 80% + * -55 - -65 = 60% + * below that = 100 - value + * TODO: a linear decrement function after PER_ROAM_GOOD_RSSI_WEIGHT + * since throughput decrements linearly after PER_ROAM_GOOD_RSSI_WEIGHT + **/ + if (bssInfo->rssi >= PER_EXCELENT_RSSI) + normalised_rssi = PER_ROAM_EXCELLENT_RSSI_WEIGHT; + else if (bssInfo->rssi >= PER_GOOD_RSSI) + normalised_rssi = PER_ROAM_GOOD_RSSI_WEIGHT; + else if (bssInfo->rssi >= PER_POOR_RSSI) + normalised_rssi = PER_ROAM_BAD_RSSI_WEIGHT; + else + normalised_rssi = bssInfo->rssi - MIN_RSSI; + + /* Calculate score part for rssi */ + score += (normalised_rssi * RSSI_WEIGHTAGE); + } + + if (bssInfo->HTCapsPresent) { + score += PER_ROAM_MAX_WEIGHT * HT_CAPABILITY_WEIGHTAGE; + } + /* VHT caps are available */ + if (bssInfo->vhtCapsPresent) { + score += PER_ROAM_MAX_WEIGHT * VHT_CAP_WEIGHTAGE; + } + + if (bssInfo->beacomformingCapable) + score += PER_ROAM_MAX_WEIGHT * BEAMFORMING_CAP_WEIGHTAGE; + + /* Channel width 20Mhz=30, 40Mhz=70, 80Mhz=100 */ + if (bssInfo->chanWidth == eHT_CHANNEL_WIDTH_80MHZ) + normalised_width = PER_ROAM_80MHZ; + else if (bssInfo->chanWidth == eHT_CHANNEL_WIDTH_40MHZ) + normalised_width = PER_ROAM_40MHZ; + else + normalised_width = PER_ROAM_20MHZ; + score += normalised_width * CHAN_WIDTH_WEIGHTAGE; + + /* Channel Band, Channel Number */ + if (GetRFBand(bssInfo->channelId) == SIR_BAND_5_GHZ) + score += PER_ROAM_MAX_WEIGHT * CHAN_BAND_WEIGHTAGE; + + /* WMM emabled */ + if (bssInfo->wmeInfoPresent) + score += PER_ROAM_MAX_WEIGHT * WMM_WEIGHTAGE; + +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + /* AP load Ie */ + if (bssInfo->QBSSLoad_present) { + /* calculate value in % */ + ap_load = (bssInfo->QBSS_ChanLoad * PER_ROAM_MAX_WEIGHT) / MAX_AP_LOAD; + } +#endif + /* if CCA consideration is off in configuration, FW will send 50% for + every channel which should be considered as it is */ + if (ap_load) + score += (100 - ap_load) * CCA_WEIGHTAGE; + else + score += (100 - cca) * CCA_WEIGHTAGE; + + channel_weight = GetPERRoamRssiCountWeight(best_rssi, ap_cnt); + + score += channel_weight * OTHER_AP_WEIGHT; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, + FL("rssi=%d normalized_rssi=%d htcaps=%d vht=%d bw=%d channel=%d wmm=%d beamforming=%d ap_load=%d channel_weight=%d"), + bssInfo->rssi, normalised_rssi, bssInfo->HTCapsPresent, + bssInfo->vhtCapsPresent, bssInfo->chanWidth, + bssInfo->channelId, bssInfo->wmeInfoPresent, + bssInfo->beacomformingCapable, ap_load, channel_weight); + return score; +} + +/* Calculate candidate AP score for PER based roaming */ +static tANI_S32 csrFindCongestionScore (tpAniSirGlobal pMac, tCsrScanResult *pBss) +{ + tANI_S32 score = 0; + tANI_S32 i; + tANI_S32 candidateApCnt, best_rssi, other_ap_cnt; + tANI_U32 current_timestamp; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo; + + tSirBssDescription *bssInfo = &(pBss->Result.BssDescriptor); + pBss->congestionScore = 0; + for (i = 0; i < pMac->PERroamCandidatesCnt; i++) + if (pMac->candidateChannelInfo[i].channelNumber == + pBss->Result.BssDescriptor.channelId) + break; + + if (i == SIR_PER_ROAM_MAX_CANDIDATE_CNT) { + smsLog(pMac, LOGE, + FL("candidate chan info not found for channel %d bssid " + MAC_ADDRESS_STR), pBss->Result.BssDescriptor.channelId, + MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId)); + return -1; + } + + if (bssInfo->rssi < pMac->roam.configParam.PERMinRssiThresholdForRoam) { + smsLog(pMac, LOG1, + FL("discarding candidate due to low rssi=%d than %d, bssid " + MAC_ADDRESS_STR), bssInfo->rssi, + pMac->roam.configParam.PERMinRssiThresholdForRoam, + MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId)); + return 0; + } + /* find best RSSI of other AP in this channel */ + best_rssi = MIN_RSSI; + for (other_ap_cnt = 0; other_ap_cnt < + pMac->candidateChannelInfo[i].otherApCount; other_ap_cnt++) { + if (pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt] > best_rssi) + best_rssi = pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt]; + } + + score = calculateBssScore(bssInfo, best_rssi, + pMac->candidateChannelInfo[i].otherApCount, + pMac->candidateChannelInfo[i].channelCCA); + current_timestamp = jiffies_to_msecs(jiffies); + + /* penalty logic */ + + /* In the previous list */ + for (candidateApCnt = 0; candidateApCnt < + SIR_PER_ROAM_MAX_CANDIDATE_CNT; candidateApCnt++) { + if (sirCompareMacAddr(pMac->previousRoamApInfo[candidateApCnt].bssAddr, + pBss->Result.BssDescriptor.bssId) && + ((current_timestamp - pMac->previousRoamApInfo[candidateApCnt].timeStamp) < + PENALTY_TIMEOUT)) { + score = (score * PENALTY_REMAINING_SCORE)/PENALTY_TOTAL_SCORE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("AP BSSID " MAC_ADDRESS_STR "adding penalty(in previous list)new score %d"), + MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId), + score); + break; + } + } + /* preauth failed last time */ + for (candidateApCnt = 0; candidateApCnt < + MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS; candidateApCnt++) { + if (sirCompareMacAddr(pNeighborRoamInfo->FTRoamInfo. + preAuthFailList.macAddress[candidateApCnt], + pBss->Result.BssDescriptor.bssId)) { + score = (score * PENALTY_REMAINING_SCORE)/PENALTY_TOTAL_SCORE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("AP BSSID " MAC_ADDRESS_STR "adding penalty(previously auth failed)new score %d"), + MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId), + score); + break; + } + } + pBss->congestionScore = score; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("AP BSSID " MAC_ADDRESS_STR " score %d channel %d"), + MAC_ADDR_ARRAY(pBss->Result.BssDescriptor.bssId), + score, pBss->Result.BssDescriptor.channelId); + return 0; +} + +/* Calculate current AP score for PER based roaming */ +static tANI_S32 csrFindSelfCongestionScore(tpAniSirGlobal pMac, + tSirBssDescription *bssInfo) +{ + tANI_S32 i, best_rssi, other_ap_cnt; + tANI_S32 score = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, + pMac->roam.roamSession->sessionId); + + if (pSession == NULL) + return -1; + + if (bssInfo->rssi < pMac->roam.configParam.PERMinRssiThresholdForRoam) { + smsLog(pMac, LOG1, + FL("Current AP has low rssi=%d than %d"), bssInfo->rssi, + pMac->roam.configParam.PERMinRssiThresholdForRoam); + /* + * Make Current candidate score as zero which will cause roaming + * in low RSSI scenarios + */ + pMac->currentBssScore = 0; + return 0; + } + + for (i = 0; i <= pMac->PERroamCandidatesCnt; i++) + if (pMac->candidateChannelInfo[i].channelNumber == bssInfo->channelId) + break; + if (i > pMac->PERroamCandidatesCnt) { + /* home channel info is not present, no need to roam */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("home channel %d congestion info not present"), + bssInfo->channelId); + pMac->currentBssScore = PER_ROAM_MAX_BSS_SCORE; + return -1; + } + + /* find best RSSI of other AP in this channel */ + best_rssi = MIN_RSSI; + for (other_ap_cnt = 0; other_ap_cnt < + pMac->candidateChannelInfo[i].otherApCount; other_ap_cnt++) { + if (pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt] > best_rssi) + best_rssi = pMac->candidateChannelInfo[i].otherApRssi[other_ap_cnt]; + } + + /* update latest RSSI for current AP */ + WLANTL_GetRssi(vos_get_global_context(VOS_MODULE_ID_SME, NULL), + pSession->connectedInfo.staId, + &bssInfo->rssi); + + score = calculateBssScore(bssInfo, best_rssi, + pMac->candidateChannelInfo[i].otherApCount, + pMac->candidateChannelInfo[i].channelCCA); + pMac->currentBssScore = score; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("PER Roam Current AP score %d channel %d"), + score, bssInfo->channelId); + return 0; +} + + +static tANI_BOOLEAN csrIsBetterBssInCongestion(tCsrScanResult *pBss1, + tCsrScanResult *pBss2) +{ + tANI_BOOLEAN ret; + + if(CSR_IS_BETTER_PREFER_VALUE(pBss1->congestionScore, + pBss2->congestionScore)) + ret = eANI_BOOLEAN_TRUE; + else + ret = eANI_BOOLEAN_FALSE; + + return (ret); +} +#endif + +//To check whther pBss1 is better than pBss2 +static tANI_BOOLEAN csrIsBetterBss(tCsrScanResult *pBss1, tCsrScanResult *pBss2) +{ + tANI_BOOLEAN ret; + + if(CSR_IS_BETTER_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue)) + { + ret = eANI_BOOLEAN_TRUE; + } + else if(CSR_IS_EQUAL_PREFER_VALUE(pBss1->preferValue, pBss2->preferValue)) + { + if(CSR_IS_BETTER_CAP_VALUE(pBss1->capValue, pBss2->capValue)) + { + ret = eANI_BOOLEAN_TRUE; + } + else + { + ret = eANI_BOOLEAN_FALSE; + } + } + else + { + ret = eANI_BOOLEAN_FALSE; + } + + return (ret); +} + + +#ifdef FEATURE_WLAN_LFR +//Add the channel to the occupiedChannels array +static void csrScanAddToOccupiedChannels( + tpAniSirGlobal pMac, + tCsrScanResult *pResult, + tCsrChannel *pOccupiedChannels, + tDot11fBeaconIEs *pIes) +{ + eHalStatus status; + tANI_U8 channel; + tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels; + tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList; + + channel = pResult->Result.BssDescriptor.channelId; + + if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, channel) + && csrNeighborRoamConnectedProfileMatch(pMac, pResult, pIes)) + { + status = csrAddToChannelListFront(pOccupiedChannelList, numOccupiedChannels, channel); + if(HAL_STATUS_SUCCESS(status)) + { + pOccupiedChannels->numChannels++; + smsLog(pMac, LOG2, FL("%s: added channel %d to the list (count=%d)"), + __func__, channel, pOccupiedChannels->numChannels); + if (pOccupiedChannels->numChannels > CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN) + pOccupiedChannels->numChannels = CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN; + } + } +} + +void csrAddChannelToOccupiedChannelList(tpAniSirGlobal pMac, + tANI_U8 channel) +{ + eHalStatus status; + tCsrChannel *pOccupiedChannels = &pMac->scan.occupiedChannels; + tANI_U8 numOccupiedChannels = pOccupiedChannels->numChannels; + tANI_U8 *pOccupiedChannelList = pOccupiedChannels->channelList; + if (!csrIsChannelPresentInList(pOccupiedChannelList, + numOccupiedChannels, channel)) + { + status = csrAddToChannelListFront(pOccupiedChannelList, + numOccupiedChannels, channel); + if(HAL_STATUS_SUCCESS(status)) + { + pOccupiedChannels->numChannels++; + smsLog(pMac, LOG2, FL("added channel %d to the list (count=%d)"), + channel, pOccupiedChannels->numChannels); + if (pOccupiedChannels->numChannels > + CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN) + { + pOccupiedChannels->numChannels = + CSR_BG_SCAN_OCCUPIED_CHANNEL_LIST_LEN; + smsLog(pMac, LOG2, + FL("trim no of Channels for Occ channel list")); + } + } + } +} +#endif + +//Put the BSS into the scan result list +//pIes can not be NULL +static void csrScanAddResult(tpAniSirGlobal pMac, tCsrScanResult *pResult, tDot11fBeaconIEs *pIes) +{ +#ifdef FEATURE_WLAN_LFR + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; +#endif + + pResult->preferValue = csrGetBssPreferValue(pMac, (int)pResult->Result.BssDescriptor.rssi); + pResult->capValue = csrGetBssCapValue(pMac, &pResult->Result.BssDescriptor, pIes); + csrLLInsertTail( &pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_LOCK ); +#ifdef FEATURE_WLAN_LFR + if(0 == pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + /* Build the occupied channel list, only if "gNeighborScanChannelList" is + NOT set in the cfg.ini file */ + csrScanAddToOccupiedChannels(pMac, pResult, &pMac->scan.occupiedChannels, pIes); + } +#endif +} + + +eHalStatus csrScanGetResult(tpAniSirGlobal pMac, tCsrScanResultFilter *pFilter, tScanResultHandle *phResult) +{ + eHalStatus status; + tScanResultList *pRetList; + tCsrScanResult *pResult, *pBssDesc; + tANI_U32 count = 0; + tListElem *pEntry; + tANI_U32 bssLen, allocLen; + eCsrEncryptionType uc = eCSR_ENCRYPT_TYPE_NONE, mc = eCSR_ENCRYPT_TYPE_NONE; + eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM; + tDot11fBeaconIEs *pIes, *pNewIes; + tANI_BOOLEAN fMatch; + tANI_U16 i = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, + pMac->roam.roamSession->sessionId); + + if(phResult) + { + *phResult = CSR_INVALID_SCANRESULT_HANDLE; + } + + if (pMac->roam.configParam.nSelect5GHzMargin) + { + pMac->scan.inScanResultBestAPRssi = -128; + csrLLLock(&pMac->scan.scanResultList); + + /* Find out the best AP Rssi going thru the scan results */ + pEntry = csrLLPeekHead(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK); + while ( NULL != pEntry) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + fMatch = FALSE; + + if (pFilter) + for(i = 0; i < pFilter->SSIDs.numOfSSIDs; i++) + { + fMatch = csrIsSsidMatch( pMac, pFilter->SSIDs.SSIDList[i].SSID.ssId, pFilter->SSIDs.SSIDList[i].SSID.length, + pBssDesc->Result.ssId.ssId, + pBssDesc->Result.ssId.length, eANI_BOOLEAN_TRUE ); + if (fMatch) + { + pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes ); + + //At this time, pBssDescription->Result.pvIes may be NULL + if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pBssDesc->Result.BssDescriptor, &pIes))) ) + { + continue; + } + + smsLog(pMac, LOG1, FL("SSID Matched")); + + if ( pFilter->bOSENAssociation ) + { + fMatch = TRUE; + } + else + { +#ifdef WLAN_FEATURE_11W + fMatch = csrIsSecurityMatch(pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + &pFilter->MFPEnabled, + &pFilter->MFPRequired, + &pFilter->MFPCapable, + &pBssDesc->Result.BssDescriptor, + pIes, NULL, NULL, NULL ); +#else + fMatch = csrIsSecurityMatch(pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + NULL, NULL, NULL, + &pBssDesc->Result.BssDescriptor, + pIes, NULL, NULL, NULL ); +#endif + } + if ((pBssDesc->Result.pvIes == NULL) && pIes) + vos_mem_free(pIes); + + if (fMatch) + smsLog(pMac, LOG1, FL(" Security Matched")); + } + } + + if (fMatch && (pBssDesc->Result.BssDescriptor.rssi > pMac->scan.inScanResultBestAPRssi)) + { + smsLog(pMac, LOG1, FL("Best AP Rssi changed from %d to %d"), + pMac->scan.inScanResultBestAPRssi, + pBssDesc->Result.BssDescriptor.rssi); + pMac->scan.inScanResultBestAPRssi = pBssDesc->Result.BssDescriptor.rssi; + } + pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + } + + if ( -128 != pMac->scan.inScanResultBestAPRssi) + { + smsLog(pMac, LOG1, FL("Best AP Rssi is %d"), pMac->scan.inScanResultBestAPRssi); + /* Modify Rssi category based on best AP Rssi */ + csrAssignRssiForCategory(pMac, pMac->scan.inScanResultBestAPRssi, pMac->roam.configParam.bCatRssiOffset); + pEntry = csrLLPeekHead(&pMac->scan.scanResultList, LL_ACCESS_NOLOCK); + while ( NULL != pEntry) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + /* re-assign preference value based on modified rssi bucket */ + pBssDesc->preferValue = csrGetBssPreferValue(pMac, (int)pBssDesc->Result.BssDescriptor.rssi); + + smsLog(pMac, LOG2, FL("BSSID("MAC_ADDRESS_STR + ") Rssi(%d) Chnl(%d) PrefVal(%u) SSID=%.*s"), + MAC_ADDR_ARRAY(pBssDesc->Result.BssDescriptor.bssId), + pBssDesc->Result.BssDescriptor.rssi, + pBssDesc->Result.BssDescriptor.channelId, + pBssDesc->preferValue, + pBssDesc->Result.ssId.length, pBssDesc->Result.ssId.ssId); + + pEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + } + } + + csrLLUnlock(&pMac->scan.scanResultList); + } + + pRetList = vos_mem_malloc(sizeof(tScanResultList)); + if ( NULL == pRetList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pRetList, sizeof(tScanResultList), 0); + csrLLOpen(pMac->hHdd, &pRetList->List); + pRetList->pCurEntry = NULL; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pFilter && pFilter->isPERRoamScan) + if (pSession && pSession->pConnectBssDesc) + csrFindSelfCongestionScore(pMac, + pSession->pConnectBssDesc); +#endif + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes ); + //if pBssDesc->Result.pvIes is NULL, we need to free any memory allocated by csrMatchBSS + //for any error condition, otherwiase, it will be freed later. + //reset + fMatch = eANI_BOOLEAN_FALSE; + pNewIes = NULL; + + if(pFilter) + { + fMatch = csrMatchBSS(pMac, &pBssDesc->Result.BssDescriptor, pFilter, &auth, &uc, &mc, &pIes); + if( NULL != pIes ) + { + //Only save it when matching + if(fMatch) + { + if( !pBssDesc->Result.pvIes ) + { + //csrMatchBSS allocates the memory. Simply pass it and it is freed later + pNewIes = pIes; + } + else + { + //The pIes is allocated by someone else. make a copy + //Only to save parsed IEs if caller provides a filter. Most likely the caller + //is using to for association, hence save the parsed IEs + pNewIes = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( NULL == pNewIes ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if ( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_copy(pNewIes, pIes, sizeof( tDot11fBeaconIEs )); + } + else + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for IEs")); + //Need to free memory allocated by csrMatchBSS + if( !pBssDesc->Result.pvIes ) + { + vos_mem_free(pIes); + } + break; + } + } + }//fMatch + else if( !pBssDesc->Result.pvIes ) + { + vos_mem_free(pIes); + } + } + } + if(NULL == pFilter || fMatch) + { + bssLen = pBssDesc->Result.BssDescriptor.length + sizeof(pBssDesc->Result.BssDescriptor.length); + allocLen = sizeof( tCsrScanResult ) + bssLen; + pResult = vos_mem_malloc(allocLen); + if ( NULL == pResult ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for scan result, len=%d"), allocLen); + if(pNewIes) + { + vos_mem_free(pNewIes); + } + break; + } + vos_mem_set(pResult, allocLen, 0); + pResult->capValue = pBssDesc->capValue; + pResult->preferValue = pBssDesc->preferValue; + pResult->ucEncryptionType = uc; + pResult->mcEncryptionType = mc; + pResult->authType = auth; + pResult->Result.ssId = pBssDesc->Result.ssId; + pResult->Result.timer = pBssDesc->Result.timer; + //save the pIes for later use + pResult->Result.pvIes = pNewIes; + //save bss description + vos_mem_copy(&pResult->Result.BssDescriptor, + &pBssDesc->Result.BssDescriptor, bssLen); + //No need to lock pRetList because it is locally allocated and no outside can access it at this time + if(csrLLIsListEmpty(&pRetList->List, LL_ACCESS_NOLOCK)) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pFilter && pFilter->isPERRoamScan) { + csrFindCongestionScore(pMac, pResult); + if (pResult->congestionScore > pMac->currentBssScore) { + csrLLInsertTail(&pRetList->List, &pResult->Link, + LL_ACCESS_NOLOCK); + smsLog(pMac, LOGW, + FL("added one entry in LL in PER Roam list")); + } + } + else +#endif + { + csrLLInsertTail(&pRetList->List, &pResult->Link, + LL_ACCESS_NOLOCK); + } + } + /* bssid hint AP should be on head */ + else if (pFilter && + vos_mem_compare(pResult->Result.BssDescriptor.bssId, + pFilter->bssid_hint, VOS_MAC_ADDR_SIZE)) + { + csrLLInsertHead(&pRetList->List, + &pResult->Link, LL_ACCESS_NOLOCK); + } + else + { + //To sort the list + tListElem *pTmpEntry; + tCsrScanResult *pTmpResult; + + pTmpEntry = csrLLPeekHead(&pRetList->List, LL_ACCESS_NOLOCK); + while(pTmpEntry) + { + pTmpResult = GET_BASE_ADDR( pTmpEntry, tCsrScanResult, Link ); + /* Skip the bssid hint AP, as it should be on head */ + if (pFilter && vos_mem_compare( + pTmpResult->Result.BssDescriptor.bssId, + pFilter->bssid_hint, VOS_MAC_ADDR_SIZE)) { + pTmpEntry = csrLLNext(&pRetList->List, + pTmpEntry, LL_ACCESS_NOLOCK); + continue; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pFilter && pFilter->isPERRoamScan) { + csrFindCongestionScore(pMac, pResult); + if(csrIsBetterBssInCongestion(pResult, pTmpResult)&& + (pResult->congestionScore > pMac->currentBssScore)) + { + csrLLInsertEntry(&pRetList->List, pTmpEntry, + &pResult->Link, LL_ACCESS_NOLOCK); + smsLog(pMac, LOGW, + FL("added another entry in LL in PER Roam list")); + pResult = NULL; + break; + } + pTmpEntry = csrLLNext(&pRetList->List, + pTmpEntry, LL_ACCESS_NOLOCK); + } + else +#endif + { + if(csrIsBetterBss(pResult, pTmpResult)) + { + csrLLInsertEntry(&pRetList->List, pTmpEntry, + &pResult->Link, LL_ACCESS_NOLOCK); + //To indicate we are done + pResult = NULL; + break; + } + pTmpEntry = csrLLNext(&pRetList->List, + pTmpEntry, LL_ACCESS_NOLOCK); + } + } + if(pResult != NULL) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if ((pFilter && !pFilter->isPERRoamScan) || + (pFilter == NULL) || + (pResult->congestionScore > pMac->currentBssScore)) +#endif + { + //This one is not better than any one + csrLLInsertTail(&pRetList->List, + &pResult->Link, LL_ACCESS_NOLOCK); + } + } + count++; + } + pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK ); + }//while + csrLLUnlock(&pMac->scan.scanResultList); + + smsLog(pMac, LOG2, FL("return %d BSS"), csrLLCount(&pRetList->List)); + + if( !HAL_STATUS_SUCCESS(status) || (phResult == NULL) ) + { + //Fail or No one wants the result. + csrScanResultPurge(pMac, (tScanResultHandle)pRetList); + } + else + { + if(0 == count) + { + //We are here meaning the there is no match + csrLLClose(&pRetList->List); + vos_mem_free(pRetList); + status = eHAL_STATUS_E_NULL_VALUE; + smsLog(pMac, LOGW, + FL("Nil scan results or no matching AP found")); + } + else if(phResult) + { + *phResult = pRetList; + } + } + }//Allocated pRetList + + return (status); +} + +/* + * NOTE: This routine is being added to make + * sure that scan results are not being flushed + * while roaming. If the scan results are flushed, + * we are unable to recover from + * csrRoamRoamingStateDisassocRspProcessor. + * If it is needed to remove this routine, + * first ensure that we recover gracefully from + * csrRoamRoamingStateDisassocRspProcessor if + * csrScanGetResult returns with a failure because + * of not being able to find the roaming BSS. + */ +tANI_U8 csrScanFlushDenied(tpAniSirGlobal pMac) +{ + switch(pMac->roam.neighborRoamInfo.neighborRoamState) { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE: + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + return (pMac->roam.neighborRoamInfo.neighborRoamState); + default: + return 0; + } +} + +eHalStatus csrScanFlushResult(tpAniSirGlobal pMac) +{ + tANI_U8 isFlushDenied = csrScanFlushDenied(pMac); + eHalStatus status = eHAL_STATUS_SUCCESS; + if (isFlushDenied) { + smsLog(pMac, LOGW, "%s: scan flush denied in roam state %d", + __func__, isFlushDenied); + return eHAL_STATUS_FAILURE; + } + csrLLScanPurgeResult( pMac, &pMac->scan.tempScanResults ); + csrLLScanPurgeResult( pMac, &pMac->scan.scanResultList ); + return( status ); +} + +eHalStatus csrScanFlushSelectiveResultForBand(tpAniSirGlobal pMac, v_BOOL_t flushP2P, tSirRFBand band) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry,*pFreeElem; + tCsrScanResult *pBssDesc; + tDblLinkList *pList = &pMac->scan.scanResultList; + + csrLLLock(pList); + + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK ); + while( pEntry != NULL) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if( (flushP2P == vos_mem_compare( pBssDesc->Result.ssId.ssId, + "DIRECT-", 7)) && + (GetRFBand(pBssDesc->Result.BssDescriptor.channelId) == band) + ) + { + pFreeElem = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK); + csrFreeScanResultEntry( pMac, pBssDesc ); + continue; + } + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + } + + csrLLUnlock(pList); + + return (status); +} + +eHalStatus csrScanFlushSelectiveResult(tpAniSirGlobal pMac, v_BOOL_t flushP2P) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry,*pFreeElem; + tCsrScanResult *pBssDesc; + tDblLinkList *pList = &pMac->scan.scanResultList; + + csrLLLock(pList); + + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK ); + while( pEntry != NULL) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if( flushP2P == vos_mem_compare( pBssDesc->Result.ssId.ssId, + "DIRECT-", 7) ) + { + pFreeElem = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + csrLLRemoveEntry(pList, pFreeElem, LL_ACCESS_NOLOCK); + csrFreeScanResultEntry( pMac, pBssDesc ); + continue; + } + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + } + + csrLLUnlock(pList); + + return (status); +} + +/** + * csrCheck11dChannel + * + *FUNCTION: + * This function is called from csrScanFilterResults function and + * compare channel number with given channel list. + * + *LOGIC: + * Check Scan result channel number with CFG channel list + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param channelId channel number + * @param pChannelList Pointer to channel list + * @param numChannels Number of channel in channel list + * + * @return Status + */ + +eHalStatus csrCheck11dChannel(tANI_U8 channelId, tANI_U8 *pChannelList, tANI_U32 numChannels) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_U8 i = 0; + + for (i = 0; i < numChannels; i++) + { + if(pChannelList[ i ] == channelId) + { + status = eHAL_STATUS_SUCCESS; + break; + } + } + return status; +} + +/** + * csrScanFilterResults + * + *FUNCTION: + * This function is called from csrApplyCountryInformation function and + * filter scan result based on valid channel list number. + * + *LOGIC: + * Get scan result from scan list and Check Scan result channel number + * with 11d channel list if channel number is found in 11d channel list + * then do not remove scan result entry from scan list + * + *ASSUMPTIONS: + * + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * + * @return Status + */ + +eHalStatus csrScanFilterResults(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry,*pTempEntry; + tCsrScanResult *pBssDesc; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + /* Get valid channels list from CFG */ + if (!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + pMac->roam.validChannelList, &len))) + { + smsLog( pMac, LOGE, "Failed to get Channel list from CFG"); + } + + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, + LL_ACCESS_LOCK ); + if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId, + pMac->roam.validChannelList, len)) + { + /* Remove Scan result which does not have 11d channel */ + if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, + LL_ACCESS_LOCK )) + { + csrFreeScanResultEntry( pMac, pBssDesc ); + } + } + pEntry = pTempEntry; + } + + pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pTempEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, + LL_ACCESS_LOCK ); + if(csrCheck11dChannel(pBssDesc->Result.BssDescriptor.channelId, + pMac->roam.validChannelList, len)) + { + /* Remove Scan result which does not have 11d channel */ + if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, + LL_ACCESS_LOCK )) + { + csrFreeScanResultEntry( pMac, pBssDesc ); + } + } + else + { + smsLog( pMac, LOG1, FL("%d is a Valid channel"), + pBssDesc->Result.BssDescriptor.channelId); + } + pEntry = pTempEntry; + } + return status; +} + +/** + * csrScanFilterDFSResults + * + *FUNCTION: + * This function filter BSSIDs on DFS channels from the scan results. + * + *LOGIC: + * Get scan result from scan list and Check Scan result channel number + * with 11d channel list if channel number is found in 11d channel list + * and if fEnableDFSChnlScan is zero and if channel is DFS, then + * remove scan result entry from scan list + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * + * @return Status + */ + +eHalStatus csrScanFilterDFSResults(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry,*pTempEntry; + tCsrScanResult *pBssDesc; + + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pTempEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, + LL_ACCESS_LOCK ); + if((pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_DISABLED) && + CSR_IS_CHANNEL_DFS(pBssDesc->Result.BssDescriptor.channelId)) + { + smsLog( pMac, LOG1, FL("%d is a DFS ch filtered from scan list"), + pBssDesc->Result.BssDescriptor.channelId); + /* Remove Scan result which does not have 11d channel */ + if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, + LL_ACCESS_LOCK )) + { + csrFreeScanResultEntry( pMac, pBssDesc ); + } + } + else + { + smsLog( pMac, LOG1, FL("%d is a Valid channel"), + pBssDesc->Result.BssDescriptor.channelId); + } + pEntry = pTempEntry; + } + + pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pTempEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, + LL_ACCESS_LOCK ); + + if((pMac->scan.fEnableDFSChnlScan == DFS_CHNL_SCAN_DISABLED) && + CSR_IS_CHANNEL_DFS(pBssDesc->Result.BssDescriptor.channelId)) + { + smsLog( pMac, LOG1, FL("%d is a DFS ch filtered from scan list"), + pBssDesc->Result.BssDescriptor.channelId); + /* Remove Scan result which does not have 11d channel */ + if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, + LL_ACCESS_LOCK )) + { + csrFreeScanResultEntry( pMac, pBssDesc ); + } + } + else + { + smsLog( pMac, LOG1, FL("%d is a Valid channel"), + pBssDesc->Result.BssDescriptor.channelId); + } + pEntry = pTempEntry; + } + return status; +} + + +eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tScanResultList *pRetList, *pInList = (tScanResultList *)hIn; + tCsrScanResult *pResult, *pScanResult; + tANI_U32 count = 0; + tListElem *pEntry; + tANI_U32 bssLen, allocLen; + + if(phResult) + { + *phResult = CSR_INVALID_SCANRESULT_HANDLE; + } + pRetList = vos_mem_malloc(sizeof(tScanResultList)); + if ( NULL == pRetList ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pRetList, sizeof(tScanResultList), 0); + csrLLOpen(pMac->hHdd, &pRetList->List); + pRetList->pCurEntry = NULL; + csrLLLock(&pMac->scan.scanResultList); + csrLLLock(&pInList->List); + + pEntry = csrLLPeekHead( &pInList->List, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pScanResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + bssLen = pScanResult->Result.BssDescriptor.length + sizeof(pScanResult->Result.BssDescriptor.length); + allocLen = sizeof( tCsrScanResult ) + bssLen; + pResult = vos_mem_malloc(allocLen); + if ( NULL == pResult ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + csrScanResultPurge(pMac, (tScanResultHandle *)pRetList); + count = 0; + break; + } + vos_mem_set(pResult, allocLen , 0); + vos_mem_copy(&pResult->Result.BssDescriptor, &pScanResult->Result.BssDescriptor, bssLen); + if( pScanResult->Result.pvIes ) + { + pResult->Result.pvIes = vos_mem_malloc(sizeof( tDot11fBeaconIEs )); + if ( NULL == pResult->Result.pvIes ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + //Free the memory we allocate above first + vos_mem_free(pResult); + csrScanResultPurge(pMac, (tScanResultHandle *)pRetList); + count = 0; + break; + } + vos_mem_copy(pResult->Result.pvIes, pScanResult->Result.pvIes, + sizeof( tDot11fBeaconIEs )); + } + csrLLInsertTail(&pRetList->List, &pResult->Link, LL_ACCESS_LOCK); + count++; + pEntry = csrLLNext( &pInList->List, pEntry, LL_ACCESS_NOLOCK ); + }//while + csrLLUnlock(&pInList->List); + csrLLUnlock(&pMac->scan.scanResultList); + + if(HAL_STATUS_SUCCESS(status)) + { + if(0 == count) + { + csrLLClose(&pRetList->List); + vos_mem_free(pRetList); + status = eHAL_STATUS_E_NULL_VALUE; + } + else if(phResult) + { + *phResult = pRetList; + } + } + }//Allocated pRetList + + return (status); +} + + + +eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirMbMsg *pMsg = (tSirMbMsg *)pMsgBuf; + tSirSmeDisConDoneInd *pDisConDoneInd; + tCsrRoamSession *pSession; + tCsrRoamInfo roamInfo = {0}; + + if((eWNI_SME_SCAN_RSP == pMsg->type) || + (eWNI_SME_GET_SCANNED_CHANNEL_RSP == pMsg->type)) + { + status = csrScanSmeScanResponse( pMac, pMsgBuf ); + } + else + { + switch (pMsg->type) + { + case eWNI_SME_UPPER_LAYER_ASSOC_CNF: + { + tSirSmeAssocIndToUpperLayerCnf *pUpperLayerAssocCnf; + tCsrRoamInfo *pRoamInfo = NULL; + tANI_U32 sessionId; + eHalStatus status; + + smsLog( pMac, LOG1, + FL("Scanning : ASSOCIATION confirmation can be given to upper layer ")); + pRoamInfo = &roamInfo; + pUpperLayerAssocCnf = (tSirSmeAssocIndToUpperLayerCnf *)pMsgBuf; + status = csrRoamGetSessionIdFromBSSID( pMac, + (tCsrBssid *)pUpperLayerAssocCnf->bssId, + &sessionId ); + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + //send the status code as Success + pRoamInfo->statusCode = eSIR_SME_SUCCESS; + pRoamInfo->u.pConnectedProfile = &pSession->connectedProfile; + pRoamInfo->staId = (tANI_U8)pUpperLayerAssocCnf->aid; + pRoamInfo->rsnIELen = + (tANI_U8)pUpperLayerAssocCnf->rsnIE.length; + pRoamInfo->prsnIE = pUpperLayerAssocCnf->rsnIE.rsnIEdata; + pRoamInfo->addIELen = + (tANI_U8)pUpperLayerAssocCnf->addIE.length; + pRoamInfo->paddIE = pUpperLayerAssocCnf->addIE.addIEdata; + vos_mem_copy(pRoamInfo->peerMac, + pUpperLayerAssocCnf->peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(&pRoamInfo->bssid, + pUpperLayerAssocCnf->bssId, + sizeof(tCsrBssid)); + pRoamInfo->wmmEnabledSta = pUpperLayerAssocCnf->wmmEnabledSta; +#ifdef WLAN_FEATURE_AP_HT40_24G + pRoamInfo->HT40MHzIntoEnabledSta = + pUpperLayerAssocCnf->HT40MHzIntoEnabledSta; +#endif + if(CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile) ) + { + pMac->roam.roamSession[sessionId].connectState = + eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED; + pRoamInfo->fReassocReq = pUpperLayerAssocCnf->reassocReq; + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, + 0, eCSR_ROAM_INFRA_IND, + eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF); + } + if(CSR_IS_WDS_AP( pRoamInfo->u.pConnectedProfile)) + { + vos_sleep( 100 ); + pMac->roam.roamSession[sessionId].connectState = + eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED;//Sta + status = csrRoamCallCallback(pMac, sessionId, pRoamInfo, 0, + eCSR_ROAM_WDS_IND, + eCSR_ROAM_RESULT_WDS_ASSOCIATION_IND);//Sta + } + break; + } + case eWNI_SME_DISCONNECT_DONE_IND: + pDisConDoneInd = (tSirSmeDisConDoneInd *)(pMsg); + + smsLog( pMac, LOG1, + FL("eWNI_SME_DISCONNECT_DONE_IND RC:%d"), + pDisConDoneInd->reasonCode); + pSession = CSR_GET_SESSION(pMac,pDisConDoneInd->sessionId); + if (pSession) + { + if( CSR_IS_SESSION_VALID(pMac, pDisConDoneInd->sessionId)) + { + roamInfo.reasonCode = pDisConDoneInd->reasonCode; + roamInfo.statusCode = eSIR_SME_STA_DISASSOCIATED; + vos_mem_copy(roamInfo.peerMac, pDisConDoneInd->peerMacAddr, + sizeof(tSirMacAddr)); + status = csrRoamCallCallback(pMac, + pDisConDoneInd->sessionId, + &roamInfo, 0, + eCSR_ROAM_LOSTLINK, + eCSR_ROAM_RESULT_DISASSOC_IND); + /* + * Update the previous state if + * previous state was eCSR_ROAMING_STATE_JOINED + * as we are disconnected and + * currunt state is scanning + */ + if (!CSR_IS_INFRA_AP(&pSession->connectedProfile) + && (eCSR_ROAMING_STATE_IDLE != + pMac->roam.prev_state[pDisConDoneInd->sessionId])) + pMac->roam.prev_state[pDisConDoneInd->sessionId] = + eCSR_ROAMING_STATE_IDLE; + } + else + { + smsLog(pMac, LOGE, FL("Inactive session %d"), + pDisConDoneInd->sessionId); + status = eHAL_STATUS_FAILURE; + } + } + else + { + smsLog(pMac, LOGE, FL("Invalid session")); + status = eHAL_STATUS_FAILURE; + } + break; + + default : + if( csrIsAnySessionInConnectState( pMac ) ) + { + /*In case of we are connected, we need to check whether connect + * status changes because scan may also run while connected. + */ + csrRoamCheckForLinkStatusChange( pMac, (tSirSmeRsp *)pMsgBuf ); + } + else + { + smsLog( pMac, LOGW, + "Message [0x%04x] received in state, when expecting Scan Response", + pMsg->type ); + } + } + } + + return (status); +} + + + +void csrCheckNSaveWscIe(tpAniSirGlobal pMac, tSirBssDescription *pNewBssDescr, tSirBssDescription *pOldBssDescr) +{ + int idx, len; + tANI_U8 *pbIe; + + //If failed to remove, assuming someone else got it. + if((pNewBssDescr->fProbeRsp != pOldBssDescr->fProbeRsp) && + (0 == pNewBssDescr->WscIeLen)) + { + idx = 0; + len = GET_IE_LEN_IN_BSS(pOldBssDescr->length) + - DOT11F_IE_WSCPROBERES_MIN_LEN - 2; + pbIe = (tANI_U8 *)pOldBssDescr->ieFields; + //Save WPS IE if it exists + pNewBssDescr->WscIeLen = 0; + while(idx < len) + { + if((DOT11F_EID_WSCPROBERES == pbIe[0]) && + (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5])) + { + //Founrd it + if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1]) + { + vos_mem_copy(pNewBssDescr->WscIeProbeRsp, pbIe, pbIe[1] + 2); + pNewBssDescr->WscIeLen = pbIe[1] + 2; + } + break; + } + idx += pbIe[1] + 2; + pbIe += pbIe[1] + 2; + } + } +} + + + +//pIes may be NULL +tANI_BOOLEAN csrRemoveDupBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDescr, + tDot11fBeaconIEs *pIes, tAniSSID *pSsid, v_TIME_t *timer, tANI_BOOLEAN fForced ) +{ + tListElem *pEntry; + + tCsrScanResult *pBssDesc; + tANI_BOOLEAN fRC = FALSE; + + // Walk through all the chained BssDescriptions. If we find a chained BssDescription that + // matches the BssID of the BssDescription passed in, then these must be duplicate scan + // results for this Bss. In that case, remove the 'old' Bss description from the linked list. + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType + // matches + if ( csrIsDuplicateBssDescription( pMac, &pBssDesc->Result.BssDescriptor, + pSirBssDescr, pIes, fForced ) ) + { + pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) + + ((tANI_S32)pBssDesc->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 ); + // Remove the 'old' entry from the list.... + if( csrLLRemoveEntry( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ) ) + { + // !we need to free the memory associated with this node + //If failed to remove, assuming someone else got it. + *pSsid = pBssDesc->Result.ssId; + *timer = pBssDesc->Result.timer; + csrCheckNSaveWscIe(pMac, pSirBssDescr, &pBssDesc->Result.BssDescriptor); + + csrFreeScanResultEntry( pMac, pBssDesc ); + } + else + { + smsLog( pMac, LOGW, FL( " fail to remove entry" ) ); + } + fRC = TRUE; + + // If we found a match, we can stop looking through the list. + break; + } + + pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_LOCK ); + } + + return fRC; +} + + +eHalStatus csrAddPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, "csrAddPMKIDCandidateList called pMac->scan.NumPmkidCandidate = %d", pSession->NumPmkidCandidate); + if( pIes ) + { + // check if this is a RSN BSS + if( pIes->RSN.present ) + { + // Check if the BSS is capable of doing pre-authentication + if( pSession->NumPmkidCandidate < CSR_MAX_PMKID_ALLOWED ) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + WLAN_VOS_DIAG_EVENT_DEF(secEvent, vos_event_wlan_security_payload_type); + vos_mem_set(&secEvent, sizeof(vos_event_wlan_security_payload_type), 0); + secEvent.eventId = WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND; + secEvent.encryptionModeMulticast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.mcEncryptionType); + secEvent.encryptionModeUnicast = + (v_U8_t)diagEncTypeFromCSRType(pSession->connectedProfile.EncryptionType); + vos_mem_copy(secEvent.bssid, pSession->connectedProfile.bssid, 6); + secEvent.authMode = + (v_U8_t)diagAuthTypeFromCSRType(pSession->connectedProfile.AuthType); + WLAN_VOS_DIAG_EVENT_REPORT(&secEvent, EVENT_WLAN_SECURITY); + } +#endif//#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + // if yes, then add to PMKIDCandidateList + vos_mem_copy(pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].BSSID, + pBssDesc->bssId, WNI_CFG_BSSID_LEN); + // Bit 0 offirst byte - PreAuthentication Capability + if ( (pIes->RSN.RSN_Cap[0] >> 0) & 0x1 ) + { + pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported + = eANI_BOOLEAN_TRUE; + } + else + { + pSession->PmkidCandidateInfo[pSession->NumPmkidCandidate].preAuthSupported + = eANI_BOOLEAN_FALSE; + } + pSession->NumPmkidCandidate++; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + } + + return (status); +} + +//This function checks whether new AP is found for the current connected profile +//If it is found, it return the sessionId, else it return invalid sessionID +tANI_U32 csrProcessBSSDescForPMKIDList(tpAniSirGlobal pMac, + tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tANI_U32 i, bRet = CSR_SESSION_ID_INVALID; + tCsrRoamSession *pSession; + tDot11fBeaconIEs *pIesLocal = pIes; + + if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) ) + { + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + if( csrIsConnStateConnectedInfra( pMac, i ) && + ( eCSR_AUTH_TYPE_RSN == pSession->connectedProfile.AuthType ) ) + { + if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile, pBssDesc, pIesLocal)) + { + //this new BSS fits the current profile connected + if(HAL_STATUS_SUCCESS(csrAddPMKIDCandidateList(pMac, i, pBssDesc, pIesLocal))) + { + bRet = i; + } + break; + } + } + } + } + if( !pIes ) + { + vos_mem_free(pIesLocal); + } + } + + return (tANI_U8)bRet; +} + +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrAddBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, "csrAddBKIDCandidateList called pMac->scan.NumBkidCandidate = %d", + pSession->NumBkidCandidate); + if( pIes ) + { + // check if this is a WAPI BSS + if( pIes->WAPI.present ) + { + // Check if the BSS is capable of doing pre-authentication + if( pSession->NumBkidCandidate < CSR_MAX_BKID_ALLOWED ) + { + + // if yes, then add to BKIDCandidateList + vos_mem_copy(pSession->BkidCandidateInfo[pSession->NumBkidCandidate].BSSID, + pBssDesc->bssId, WNI_CFG_BSSID_LEN); + if ( pIes->WAPI.preauth ) + { + pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported + = eANI_BOOLEAN_TRUE; + } + else + { + pSession->BkidCandidateInfo[pSession->NumBkidCandidate].preAuthSupported + = eANI_BOOLEAN_FALSE; + } + pSession->NumBkidCandidate++; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + } + + return (status); +} + +//This function checks whether new AP is found for the current connected profile +//if so add to BKIDCandidateList +tANI_BOOLEAN csrProcessBSSDescForBKIDList(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tANI_BOOLEAN fRC = FALSE; + tDot11fBeaconIEs *pIesLocal = pIes; + tANI_U32 sessionId; + tCsrRoamSession *pSession; + + if( pIesLocal || HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal)) ) + { + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if( csrIsConnStateConnectedInfra( pMac, sessionId ) && + eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE == pSession->connectedProfile.AuthType) + { + if(csrMatchBSSToConnectProfile(pMac, &pSession->connectedProfile,pBssDesc, pIesLocal)) + { + //this new BSS fits the current profile connected + if(HAL_STATUS_SUCCESS(csrAddBKIDCandidateList(pMac, sessionId, pBssDesc, pIesLocal))) + { + fRC = TRUE; + } + } + } + } + } + if(!pIes) + { + vos_mem_free(pIesLocal); + } + + } + return fRC; +} + +#endif + + +static void csrMoveTempScanResultsToMainList( tpAniSirGlobal pMac, tANI_U8 reason ) +{ + tListElem *pEntry; + tCsrScanResult *pBssDescription; + tANI_BOOLEAN fDupBss; +#ifdef FEATURE_WLAN_WAPI + tANI_BOOLEAN fNewWapiBSSForCurConnection = eANI_BOOLEAN_FALSE; +#endif /* FEATURE_WLAN_WAPI */ + tDot11fBeaconIEs *pIesLocal = NULL; + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + tAniSSID tmpSsid; + v_TIME_t timer=0; + tANI_U8 occupied_chan_count = pMac->scan.occupiedChannels.numChannels; + + tmpSsid.length = 0; + + // remove the BSS descriptions from temporary list + while( ( pEntry = csrLLRemoveTail( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ) ) != NULL) + { + pBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + smsLog( pMac, LOG2, "...Bssid= "MAC_ADDRESS_STR" chan= %d, rssi = -%d", + MAC_ADDR_ARRAY(pBssDescription->Result.BssDescriptor.bssId), + pBssDescription->Result.BssDescriptor.channelId, + pBssDescription->Result.BssDescriptor.rssi * (-1) ); + + //At this time, pBssDescription->Result.pvIes may be NULL + pIesLocal = (tDot11fBeaconIEs *)( pBssDescription->Result.pvIes ); + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssDescription->Result.BssDescriptor, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" Cannot pared IEs")); + csrFreeScanResultEntry(pMac, pBssDescription); + continue; + } + fDupBss = csrRemoveDupBssDescription( pMac, &pBssDescription->Result.BssDescriptor, pIesLocal, &tmpSsid, &timer, FALSE ); + //Check whether we have reach out limit, but don't lose the LFR candidates came from FW + if( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !( eCsrScanGetLfrResult == reason ) +#endif + ) + { + smsLog(pMac, LOG1, FL("########## BSS Limit reached ###########")); + csrPurgeScanResults(pMac); + } + // check for duplicate scan results + if ( !fDupBss ) + { + //Found a new BSS + sessionId = csrProcessBSSDescForPMKIDList(pMac, + &pBssDescription->Result.BssDescriptor, pIesLocal); + if( CSR_SESSION_ID_INVALID != sessionId) + { + csrRoamCallCallback(pMac, sessionId, NULL, 0, + eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NONE); + } + } + else + { + //Check if the new one has SSID it it, if not, use the older SSID if it exists. + if( (0 == pBssDescription->Result.ssId.length) && tmpSsid.length ) + { + //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only + //if diff of saved SSID time and current time is less than 1 min to avoid + //side effect of saving SSID with old one is that if AP changes its SSID while remain + //hidden, we may never see it and also to address the requirement of + //When we remove hidden ssid from the profile i.e., forget the SSID via + // GUI that SSID shouldn't see in the profile + if( (vos_timer_get_system_time() - timer) <= HIDDEN_TIMER) + { + pBssDescription->Result.timer = timer; + pBssDescription->Result.ssId = tmpSsid; + } + } + } + + //Find a good AP for 11d info + if ( csrIs11dSupported( pMac ) ) + { + // check if country information element is present + if (pIesLocal->Country.present) + { + csrAddVoteForCountryInfo(pMac, pIesLocal->Country.country); + smsLog(pMac, LOGW, FL("11d AP Bssid " MAC_ADDRESS_STR + " chan= %d, rssi = -%d, countryCode %c%c"), + MAC_ADDR_ARRAY( pBssDescription->Result.BssDescriptor.bssId), + pBssDescription->Result.BssDescriptor.channelId, + pBssDescription->Result.BssDescriptor.rssi * (-1), + pIesLocal->Country.country[0],pIesLocal->Country.country[1] ); + } + + } + + // append to main list + csrScanAddResult(pMac, pBssDescription, pIesLocal); + if ( (pBssDescription->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (sme_IsFeatureSupportedByFW(PER_BASED_ROAMING) && + (csrGetInfraSessionId(pMac) != -1) && + (pMac->scan.occupiedChannels.numChannels != occupied_chan_count)) + { + /* Update FW with new list */ + smsLog(pMac, LOGW, + FL("Updating occupied channel list, new chanNum %d"), + pMac->scan.occupiedChannels.numChannels); + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_CHANNEL_LIST_CHANGED); + } +#endif + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + //we don't need to update CC while connected to an AP which is advertising CC already + if (csrIs11dSupported(pMac)) + { + tANI_U32 i; + tCsrRoamSession *pSession; + + for (i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if (CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + if (csrIsConnStateConnected(pMac, i)) + { + smsLog(pMac, LOGW, FL("No need for updating CC in" + "connected state")); + goto end; + } + } + } + if (csrElectedCountryInfo(pMac)) + csrLearnCountryInformation(pMac, NULL, NULL, + eANI_BOOLEAN_TRUE); + } + +end: + //If we can find the current 11d info in any of the scan results, or + // a good enough AP with the 11d info from the scan results then no need to + // get into ambiguous state + if(pMac->scan.fAmbiguous11dInfoFound) + { + if((pMac->scan.fCurrent11dInfoMatch)) + { + pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE; + } + } + +#ifdef FEATURE_WLAN_WAPI + if(fNewWapiBSSForCurConnection) + { + //remember it first + csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SCAN_FOUND_NEW_BSS, eCSR_ROAM_RESULT_NEW_WAPI_BSS); + } +#endif /* FEATURE_WLAN_WAPI */ + + return; +} + +/** + * csrPurgeScanResults() - This function removes scan entry based + * on RSSI or AGE + * @pMac: pointer to Global MAC structure + * + * This function removes scan entry based on RSSI or AGE. + * If an scan entry with RSSI less than CSR_PURGE_RSSI_THRESHOLD, + * the scan entry is removed else oldest entry is removed. + * + * Return: None + */ +void csrPurgeScanResults(tpAniSirGlobal pMac) +{ + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult, *oldest_bss = NULL, *weakest_bss = NULL; + v_TIME_t oldest_entry = 0; + v_TIME_t curTime = vos_timer_get_system_time(); + tANI_S8 weakest_rssi = 0; + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while(pEntry) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, + LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if((curTime - + pResult->Result.BssDescriptor.nReceivedTime) > oldest_entry) + { + oldest_entry = curTime - + pResult->Result.BssDescriptor.nReceivedTime; + oldest_bss = pResult; + } + if (pResult->Result.BssDescriptor.rssi < weakest_rssi) + { + weakest_rssi = pResult->Result.BssDescriptor.rssi; + weakest_bss = pResult; + } + pEntry = tmpEntry; + } + if (oldest_bss) + { + tCsrScanResult *bss_to_remove; + + if (weakest_rssi < CSR_PURGE_RSSI_THRESHOLD) + bss_to_remove = weakest_bss; + else + bss_to_remove = oldest_bss; + + //Free the old BSS Entries + if(csrLLRemoveEntry(&pMac->scan.scanResultList, + &bss_to_remove->Link, LL_ACCESS_NOLOCK)) + { + smsLog(pMac, LOG1, + FL("BSSID: "MAC_ADDRESS_STR" Removed, time delta (%lu) RSSI %d"), + MAC_ADDR_ARRAY( + bss_to_remove->Result.BssDescriptor.bssId), + (curTime - + bss_to_remove->Result.BssDescriptor.nReceivedTime), + bss_to_remove->Result.BssDescriptor.rssi); + csrFreeScanResultEntry(pMac, bss_to_remove); + } + } + csrLLUnlock(&pMac->scan.scanResultList); +} + +static tCsrScanResult *csrScanSaveBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription, + tDot11fBeaconIEs *pIes) +{ + tCsrScanResult *pCsrBssDescription = NULL; + tANI_U32 cbBSSDesc; + tANI_U32 cbAllocated; + tListElem *pEntry; + + // figure out how big the BSS description is (the BSSDesc->length does NOT + // include the size of the length field itself). + cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length ); + + cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc; + + pCsrBssDescription = vos_mem_malloc(cbAllocated); + if ( NULL != pCsrBssDescription ) + { + vos_mem_set(pCsrBssDescription, cbAllocated, 0); + pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount; + vos_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc); +#if defined(VOSS_ENSBALED) + VOS_ASSERT( pCsrBssDescription->Result.pvIes == NULL ); +#endif + csrScanAddResult(pMac, pCsrBssDescription, pIes); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + } + + return( pCsrBssDescription ); +} + +// Append a Bss Description... +tCsrScanResult *csrScanAppendBssDescription( tpAniSirGlobal pMac, + tSirBssDescription *pSirBssDescription, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForced ) +{ + tCsrScanResult *pCsrBssDescription = NULL; + tAniSSID tmpSsid; + v_TIME_t timer = 0; + int result; + + tmpSsid.length = 0; + result = csrRemoveDupBssDescription( pMac, pSirBssDescription, pIes, &tmpSsid, &timer, fForced ); + pCsrBssDescription = csrScanSaveBssDescription( pMac, pSirBssDescription, pIes ); + if (result && (pCsrBssDescription != NULL)) + { + //Check if the new one has SSID it it, if not, use the older SSID if it exists. + if( (0 == pCsrBssDescription->Result.ssId.length) && tmpSsid.length ) + { + //New BSS has a hidden SSID and old one has the SSID. Keep the SSID only + //if diff of saved SSID time and current time is less than 1 min to avoid + //side effect of saving SSID with old one is that if AP changes its SSID while remain + //hidden, we may never see it and also to address the requirement of + //When we remove hidden ssid from the profile i.e., forget the SSID via + // GUI that SSID shouldn't see in the profile + if((vos_timer_get_system_time()-timer) <= HIDDEN_TIMER) + { + pCsrBssDescription->Result.ssId = tmpSsid; + pCsrBssDescription->Result.timer = timer; + } + } + } + + + return( pCsrBssDescription ); +} + + + +void csrPurgeChannelPower( tpAniSirGlobal pMac, tDblLinkList *pChannelList ) +{ + tCsrChannelPowerInfo *pChannelSet; + tListElem *pEntry; + + csrLLLock(pChannelList); + // Remove the channel sets from the learned list and put them in the free list + while( ( pEntry = csrLLRemoveHead( pChannelList, LL_ACCESS_NOLOCK ) ) != NULL) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + if( pChannelSet ) + { + vos_mem_free(pChannelSet); + } + } + csrLLUnlock(pChannelList); + return; +} + + +/* + * Save the channelList into the ultimate storage as the final stage of channel + * Input: pCountryInfo -- the country code (e.g. "USI"), channel list, and power limit are all stored inside this data structure + */ +eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable ) +{ + tANI_U32 i = tableSize / sizeof( tSirMacChanInfo ); + tSirMacChanInfo *pChannelInfo; + tCsrChannelPowerInfo *pChannelSet; + tANI_BOOLEAN f2GHzInfoFound = FALSE; + tANI_BOOLEAN f2GListPurged = FALSE, f5GListPurged = FALSE; + + pChannelInfo = channelTable; + // atleast 3 bytes have to be remaining -- from "countryString" + while ( i-- ) + { + pChannelSet = vos_mem_malloc(sizeof(tCsrChannelPowerInfo)); + if ( NULL != pChannelSet ) + { + vos_mem_set(pChannelSet, sizeof(tCsrChannelPowerInfo), 0); + pChannelSet->firstChannel = pChannelInfo->firstChanNum; + pChannelSet->numChannels = pChannelInfo->numChannels; + + // Now set the inter-channel offset based on the frequency band the channel set lies in + if( (CSR_IS_CHANNEL_24GHZ(pChannelSet->firstChannel)) && + ((pChannelSet->firstChannel + (pChannelSet->numChannels - 1)) <= CSR_MAX_24GHz_CHANNEL_NUMBER) ) + + { + pChannelSet->interChannelOffset = 1; + f2GHzInfoFound = TRUE; + } + else if ( (CSR_IS_CHANNEL_5GHZ(pChannelSet->firstChannel)) && + ((pChannelSet->firstChannel + ((pChannelSet->numChannels - 1) * 4)) <= CSR_MAX_5GHz_CHANNEL_NUMBER) ) + { + pChannelSet->interChannelOffset = 4; + f2GHzInfoFound = FALSE; + } + else + { + smsLog( pMac, LOGW, FL("Invalid Channel %d Present in Country IE"), + pChannelSet->firstChannel); + vos_mem_free(pChannelSet); + return eHAL_STATUS_FAILURE; + } + + pChannelSet->txPower = CSR_ROAM_MIN( pChannelInfo->maxTxPower, pMac->roam.configParam.nTxPowerCap ); + + if( f2GHzInfoFound ) + { + if( !f2GListPurged ) + { + // purge previous results if found new + csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList24 ); + f2GListPurged = TRUE; + } + + if(CSR_IS_OPERATING_BG_BAND(pMac)) + { + // add to the list of 2.4 GHz channel sets + csrLLInsertTail( &pMac->scan.channelPowerInfoList24, &pChannelSet->link, LL_ACCESS_LOCK ); + } + else { + smsLog( pMac, LOGW, FL("Adding 11B/G channels in 11A mode -- First Channel is %d"), + pChannelSet->firstChannel); + vos_mem_free(pChannelSet); + } + } + else + { + // 5GHz info found + if( !f5GListPurged ) + { + // purge previous results if found new + csrPurgeChannelPower( pMac, &pMac->scan.channelPowerInfoList5G ); + f5GListPurged = TRUE; + } + + if(CSR_IS_OPERATING_A_BAND(pMac)) + { + // add to the list of 5GHz channel sets + csrLLInsertTail( &pMac->scan.channelPowerInfoList5G, &pChannelSet->link, LL_ACCESS_LOCK ); + } + else { + smsLog( pMac, LOGW, FL("Adding 11A channels in B/G mode -- First Channel is %d"), + pChannelSet->firstChannel); + vos_mem_free(pChannelSet); + } + } + } + + pChannelInfo++; // move to next entry + } + + return eHAL_STATUS_SUCCESS; +} + +static void csrClearDfsChannelList( tpAniSirGlobal pMac ) +{ + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL != pMsg ) + { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_CLEAR_DFS_CHANNEL_LIST); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + palSendMBMessage(pMac->hHdd, pMsg); + } +} + +void csrApplyPower2Current( tpAniSirGlobal pMac ) +{ + smsLog( pMac, LOG3, FL(" Updating Cfg with power settings")); + csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList24, WNI_CFG_MAX_TX_POWER_2_4 ); + csrSaveTxPowerToCfg( pMac, &pMac->scan.channelPowerInfoList5G, WNI_CFG_MAX_TX_POWER_5 ); +} + + +void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode, tANI_BOOLEAN updateRiva) +{ + int i, j, count, countryIndex = -1; + tANI_U8 numChannels = 0; + tANI_U8 tempNumChannels = 0; + tANI_U8 channelIgnore = FALSE; + tCsrChannel ChannelList; + + if( pChannelList->numChannels ) + { + for(count=0; count < MAX_COUNTRY_IGNORE; count++) + { + if(vos_mem_compare(countryCode, countryIgnoreList[count].countryCode, + VOS_COUNTRY_CODE_LEN)) + { + countryIndex = count; + break; + } + } + tempNumChannels = CSR_MIN(pChannelList->numChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN); + + for(i=0; i < tempNumChannels; i++) + { + channelIgnore = FALSE; + if( countryIndex != -1 ) + { + for(j=0; j < countryIgnoreList[countryIndex].channelCount; j++) + { + if( pChannelList->channelList[i] == + countryIgnoreList[countryIndex].channelList[j] ) + { + channelIgnore = TRUE; + break; + } + } + } + if( FALSE == channelIgnore ) + { + ChannelList.channelList[numChannels] = pChannelList->channelList[i]; + numChannels++; + } + } + ChannelList.numChannels = numChannels; + csrApplyPower2Current( pMac ); // Store the channel+power info in the global place: Cfg + csrSetCfgValidChannelList(pMac, ChannelList.channelList, ChannelList.numChannels); + // extend scan capability + // build a scan list based on the channel list : channel# + active/passive scan + csrSetCfgScanControlList(pMac, countryCode, &ChannelList); +#ifdef FEATURE_WLAN_SCAN_PNO + if (updateRiva) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, FL(" Sending 11d PNO info to Riva")); + // Send HAL UpdateScanParams message + pmcUpdateScanParams(pMac, &(pMac->roam.configParam), &ChannelList, TRUE); + } +#endif // FEATURE_WLAN_SCAN_PNO + } + else + { + smsLog( pMac, LOGE, FL(" 11D channel list is empty")); + } + csrSetCfgCountryCode(pMac, countryCode); +} + +void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce, tANI_BOOLEAN updateRiva ) +{ + if( fForce || (csrIs11dSupported( pMac ) && (!pMac->scan.f11dInfoReset))) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_802_11d_pkt_type *p11dLog; + int Index; + + WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C); + if(p11dLog) + { + p11dLog->eventId = WLAN_80211D_EVENT_RESET; + vos_mem_copy(p11dLog->countryCode, pMac->scan.countryCodeCurrent, 3); + p11dLog->numChannel = pMac->scan.base20MHzChannels.numChannels; + if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL) + { + vos_mem_copy(p11dLog->Channels, + pMac->scan.base20MHzChannels.channelList, + p11dLog->numChannel); + for (Index=0; Index < pMac->scan.base20MHzChannels.numChannels; Index++) + { + p11dLog->TxPwr[Index] = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap ); + } + } + if(!pMac->roam.configParam.Is11dSupportEnabled) + { + p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED; + } + else if(pMac->roam.configParam.fEnforceDefaultDomain) + { + p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN; + } + else + { + p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN; + } + WLAN_VOS_DIAG_LOG_REPORT(p11dLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + csrPruneChannelListForMode(pMac, &pMac->scan.baseChannels); + csrPruneChannelListForMode(pMac, &pMac->scan.base20MHzChannels); + + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_FALSE); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); + // ... and apply the channel list, power settings, and the country code. + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, pMac->scan.countryCodeCurrent, updateRiva ); + // clear the 11d channel list + vos_mem_set(&pMac->scan.channels11d, sizeof(pMac->scan.channels11d), 0); + pMac->scan.f11dInfoReset = eANI_BOOLEAN_TRUE; + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_FALSE; + } + + return; +} + + +eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRestart = eANI_BOOLEAN_FALSE; + + //Use the Country code and domain from EEPROM + vos_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, + WNI_CFG_COUNTRY_CODE_LEN); + csrSetRegulatoryDomain(pMac, pMac->scan.domainIdCurrent, &fRestart); + if( ((eANI_BOOLEAN_FALSE == fRestart) || (pfRestartNeeded == NULL) ) + && !csrIsInfraConnected(pMac)) + { + //Only reset the country info if we don't need to restart + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + } + if(pfRestartNeeded) + { + *pfRestartNeeded = fRestart; + } + + return (status); +} + +void csrClearVotesForCountryInfo(tpAniSirGlobal pMac) +{ + pMac->scan.countryCodeCount = 0; + vos_mem_set(pMac->scan.votes11d, + sizeof(tCsrVotes11d) * CSR_MAX_NUM_COUNTRY_CODE, 0); +} + +void csrAddVoteForCountryInfo(tpAniSirGlobal pMac, tANI_U8 *pCountryCode) +{ + tANI_BOOLEAN match = FALSE; + tANI_U8 i; + + /* convert to UPPER here so we are assured + * the strings are always in upper case. + */ + for( i = 0; i < 3; i++ ) + { + pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] ); + } + + /* Some of the 'old' Cisco 350 series AP's advertise NA as the + * country code (for North America ??). NA is not a valid country code + * or domain so let's allow this by changing it to the proper + * country code (which is US). We've also seen some NETGEAR AP's + * that have "XX " as the country code with valid 2.4 GHz US channel + * information. If we cannot find the country code advertised in the + * 11d information element, let's default to US. + */ + + if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( pMac, + pCountryCode, NULL,COUNTRY_QUERY ) ) ) + { + pCountryCode[ 0 ] = '0'; + pCountryCode[ 1 ] = '0'; + } + + /* We've seen some of the AP's improperly put a 0 for the + * third character of the country code. spec says valid charcters are + * 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either). + * if we see a 0 in this third character, let's change it to a ' '. + */ + if ( 0 == pCountryCode[ 2 ] ) + { + pCountryCode[ 2 ] = ' '; + } + + for (i = 0; i < pMac->scan.countryCodeCount; i++) + { + match = (vos_mem_compare(pMac->scan.votes11d[i].countryCode, + pCountryCode, 2)); + if(match) + { + break; + } + } + + if (match) + { + pMac->scan.votes11d[i].votes++; + } + else + { + vos_mem_copy( pMac->scan.votes11d[pMac->scan.countryCodeCount].countryCode, + pCountryCode, 3 ); + pMac->scan.votes11d[pMac->scan.countryCodeCount].votes = 1; + pMac->scan.countryCodeCount++; + } + + return; +} + +tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = FALSE; + tANI_U8 maxVotes = 0; + tANI_U8 i, j=0; + + if (!pMac->scan.countryCodeCount) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "No AP with 11d Country code is present in scan list"); + return fRet; + } + maxVotes = pMac->scan.votes11d[0].votes; + fRet = TRUE; + + for(i = 1; i < pMac->scan.countryCodeCount; i++) + { + /* If we have a tie for max votes for 2 different country codes, + * pick random.we can put some more intelligence - TBD + */ + if (maxVotes < pMac->scan.votes11d[i].votes) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + " Votes for Country %c%c : %d\n", + pMac->scan.votes11d[i].countryCode[0], + pMac->scan.votes11d[i].countryCode[1], + pMac->scan.votes11d[i].votes); + + maxVotes = pMac->scan.votes11d[i].votes; + j = i; + fRet = TRUE; + } + + } + if (fRet) + { + vos_mem_copy(pMac->scan.countryCodeElected, + pMac->scan.votes11d[j].countryCode, WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCode11d, + pMac->scan.votes11d[j].countryCode, WNI_CFG_COUNTRY_CODE_LEN); + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Selected Country is %c%c With count %d\n", + pMac->scan.votes11d[j].countryCode[0], + pMac->scan.votes11d[j].countryCode[1], + pMac->scan.votes11d[j].votes); + } + return fRet; +} + +eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + v_REGDOMAIN_t domainId; + + if(pCountry) + { + status = csrGetRegulatoryDomainForCountry(pMac, pCountry, &domainId, COUNTRY_USER); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrSetRegulatoryDomain(pMac, domainId, pfRestartNeeded); + if(HAL_STATUS_SUCCESS(status)) + { + //We don't need to check the pMac->roam.configParam.fEnforceDefaultDomain flag here, + //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria. + vos_mem_copy(pMac->scan.countryCodeCurrent, pCountry, WNI_CFG_COUNTRY_CODE_LEN); + if((pfRestartNeeded == NULL) || !(*pfRestartNeeded)) + { + //Simply set it to cfg. If we need to restart, restart will apply it to the CFG + csrSetCfgCountryCode(pMac, pCountry); + } + } + } + } + + return (status); +} + + + +//caller allocated memory for pNumChn and pChnPowerInfo +//As input, *pNumChn has the size of the array of pChnPowerInfo +//Upon return, *pNumChn has the number of channels assigned. +void csrGetChannelPowerInfo( tpAniSirGlobal pMac, tDblLinkList *pList, + tANI_U32 *pNumChn, tChannelListWithPower *pChnPowerInfo) +{ + tListElem *pEntry; + tANI_U32 chnIdx = 0, idx; + tCsrChannelPowerInfo *pChannelSet; + + //Get 2.4Ghz first + pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK ); + while( pEntry && (chnIdx < *pNumChn) ) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + if ( 1 != pChannelSet->interChannelOffset ) + { + for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ ) + { + pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset )); + pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower; + } + } + else + { + for( idx = 0; (idx < pChannelSet->numChannels) && (chnIdx < *pNumChn); idx++ ) + { + pChnPowerInfo[chnIdx].chanId = (tANI_U8)(pChannelSet->firstChannel + idx); + pChnPowerInfo[chnIdx++].pwr = pChannelSet->txPower; + } + } + + pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK ); + } + *pNumChn = chnIdx; + + return ; +} + + + +void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce ) +{ + v_REGDOMAIN_t domainId; + eHalStatus status = eHAL_STATUS_SUCCESS; + + do + { + if( !csrIs11dSupported( pMac ) || 0 == pMac->scan.channelOf11dInfo) break; + if( pMac->scan.fAmbiguous11dInfoFound ) + { + // ambiguous info found + //Restore te default domain as well + if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( + pMac, pMac->scan.countryCodeCurrent, + &domainId, COUNTRY_QUERY))) + { + pMac->scan.domainIdCurrent = domainId; + } + else + { + smsLog(pMac, LOGE, FL(" failed to get domain from currentCountryCode %02X%02X"), + pMac->scan.countryCodeCurrent[0], pMac->scan.countryCodeCurrent[1]); + } + csrResetCountryInformation( pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE ); + break; + } + if ( pMac->scan.f11dInfoApplied && !fForce ) break; + if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry( + pMac, pMac->scan.countryCode11d, + &domainId, COUNTRY_QUERY))) + { + //Check whether we need to enforce default domain + if( ( !pMac->roam.configParam.fEnforceDefaultDomain ) || + (pMac->scan.domainIdCurrent == domainId) ) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_802_11d_pkt_type *p11dLog; + tChannelListWithPower chnPwrInfo[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U32 nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN, nTmp; + + WLAN_VOS_DIAG_LOG_ALLOC(p11dLog, vos_log_802_11d_pkt_type, LOG_WLAN_80211D_C); + if(p11dLog) + { + p11dLog->eventId = WLAN_80211D_EVENT_COUNTRY_SET; + vos_mem_copy(p11dLog->countryCode, pMac->scan.countryCode11d, 3); + p11dLog->numChannel = pMac->scan.channels11d.numChannels; + if(p11dLog->numChannel <= VOS_LOG_MAX_NUM_CHANNEL) + { + vos_mem_copy(p11dLog->Channels, + pMac->scan.channels11d.channelList, + p11dLog->numChannel); + csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList24, + &nChnInfo, chnPwrInfo); + nTmp = nChnInfo; + nChnInfo = WNI_CFG_VALID_CHANNEL_LIST_LEN - nTmp; + csrGetChannelPowerInfo(pMac, &pMac->scan.channelPowerInfoList5G, + &nChnInfo, &chnPwrInfo[nTmp]); + for(nTmp = 0; nTmp < p11dLog->numChannel; nTmp++) + { + for(nChnInfo = 0; nChnInfo < WNI_CFG_VALID_CHANNEL_LIST_LEN; nChnInfo++) + { + if(p11dLog->Channels[nTmp] == chnPwrInfo[nChnInfo].chanId) + { + p11dLog->TxPwr[nTmp] = chnPwrInfo[nChnInfo].pwr; + break; + } + } + } + } + if(!pMac->roam.configParam.Is11dSupportEnabled) + { + p11dLog->supportMultipleDomain = WLAN_80211D_DISABLED; + } + else if(pMac->roam.configParam.fEnforceDefaultDomain) + { + p11dLog->supportMultipleDomain = WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN; + } + else + { + p11dLog->supportMultipleDomain = WLAN_80211D_SUPPORT_MULTI_DOMAIN; + } + WLAN_VOS_DIAG_LOG_REPORT(p11dLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + if(pMac->scan.domainIdCurrent != domainId) + { + smsLog(pMac, LOGW, FL("Domain Changed Old %s (%d), new %s"), + voss_DomainIdtoString(pMac->scan.domainIdCurrent), + pMac->scan.domainIdCurrent, + voss_DomainIdtoString(domainId)); + status = WDA_SetRegDomain(pMac, domainId, eSIR_TRUE); + } + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL(" fail to set regId %d"), domainId ); + } + pMac->scan.domainIdCurrent = domainId; +#ifndef CONFIG_ENABLE_LINUX_REG + csrApplyChannelPowerCountryInfo( pMac, &pMac->scan.base20MHzChannels, + pMac->scan.countryCodeCurrent, eANI_BOOLEAN_TRUE ); +#endif + // switch to active scans using this new channel list + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE; + pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE; + } + } + + } while( 0 ); + + return; +} + + + +tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode, + tANI_BOOLEAN fForce) +{ + tANI_BOOLEAN fCountryStringChanged = FALSE, fUnknownCountryCode = FALSE; + tANI_U32 i; + v_REGDOMAIN_t regd; + tANI_BOOLEAN fCountryNotPresentInDriver = FALSE; + + // convert to UPPER here so we are assured the strings are always in upper case. + for( i = 0; i < 3; i++ ) + { + pCountryCode[ i ] = (tANI_U8)csrToUpper( pCountryCode[ i ] ); + } + + // Some of the 'old' Cisco 350 series AP's advertise NA as the country code (for North America ??). + // NA is not a valid country code or domain so let's allow this by changing it to the proper + // country code (which is US). We've also seen some NETGEAR AP's that have "XX " as the country code + // with valid 2.4 GHz US channel information. If we cannot find the country code advertised in the + // 11d information element, let's default to US. + if ( !HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, + pCountryCode, + ®d, + COUNTRY_QUERY) ) ) + { + // Check the enforcement first + if( pMac->roam.configParam.fEnforceDefaultDomain || pMac->roam.configParam.fEnforceCountryCodeMatch ) + { + fUnknownCountryCode = TRUE; + } + else + { + fCountryNotPresentInDriver = TRUE; + } + } + //right now, even if we don't find the CC in driver we set to world. Making + //sure countryCode11d doesn't get updated with the invalid CC, instead + //reflect the world CC + else if (REGDOMAIN_WORLD == regd) + { + fCountryNotPresentInDriver = TRUE; + } + + // We've seen some of the AP's improperly put a 0 for the third character of the country code. + // spec says valid charcters are 'O' (for outdoor), 'I' for Indoor, or ' ' (space; for either). + // if we see a 0 in this third character, let's change it to a ' '. + if ( 0 == pCountryCode[ 2 ] ) + { + pCountryCode[ 2 ] = ' '; + } + + if( !fUnknownCountryCode ) + { + fCountryStringChanged = (!vos_mem_compare(pMac->scan.countryCode11d, pCountryCode, 2)); + + + if(( 0 == pMac->scan.countryCode11d[ 0 ] && 0 == pMac->scan.countryCode11d[ 1 ] ) + || (fForce)) + { + if (!fCountryNotPresentInDriver) + { + // this is the first .11d information + vos_mem_copy(pMac->scan.countryCode11d, pCountryCode, + sizeof( pMac->scan.countryCode11d )); + + } + else + { + pMac->scan.countryCode11d[0] = '0'; + pMac->scan.countryCode11d[1] = '0'; + } + } + } + + return( fCountryStringChanged ); +} + + +void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand ) +{ + tANI_U32 Index, count=0; + tSirMacChanInfo *pChanInfo; + tSirMacChanInfo *pChanInfoStart; + tANI_S32 maxChannelIndex; + + maxChannelIndex = ( pMac->scan.base20MHzChannels.numChannels < WNI_CFG_VALID_CHANNEL_LIST_LEN ) ? + pMac->scan.base20MHzChannels.numChannels : WNI_CFG_VALID_CHANNEL_LIST_LEN ; + + pChanInfo = vos_mem_malloc(sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL != pChanInfo ) + { + vos_mem_set(pChanInfo, sizeof(tSirMacChanInfo) * WNI_CFG_VALID_CHANNEL_LIST_LEN, 0); + pChanInfoStart = pChanInfo; + for (Index=0; Index < maxChannelIndex; Index++) + { + if ((fPopulate5GBand && (CSR_IS_CHANNEL_5GHZ(pMac->scan.defaultPowerTable[Index].chanId))) || + (!fPopulate5GBand && (CSR_IS_CHANNEL_24GHZ(pMac->scan.defaultPowerTable[Index].chanId))) ) + { + if(count >= WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + smsLog( pMac, LOGW, FL(" csrSaveChannelPowerForBand, count exceeded, count = %d"), count); + break; + } + pChanInfo->firstChanNum = pMac->scan.defaultPowerTable[Index].chanId; + pChanInfo->numChannels = 1; + pChanInfo->maxTxPower = CSR_ROAM_MIN( pMac->scan.defaultPowerTable[Index].pwr, pMac->roam.configParam.nTxPowerCap ); + pChanInfo++; + count++; + } + } + if(count) + { + csrSaveToChannelPower2G_5G( pMac, count * sizeof(tSirMacChanInfo), pChanInfoStart ); + } + vos_mem_free(pChanInfoStart); + } +} + + +void csrSetOppositeBandChannelInfo( tpAniSirGlobal pMac ) +{ + tANI_BOOLEAN fPopulate5GBand = FALSE; + + do + { + // if this is not a dual band product, then we don't need to set the opposite + // band info. We only work in one band so no need to look in the other band. + if ( !CSR_IS_OPEARTING_DUAL_BAND( pMac ) ) break; + // if we found channel info on the 5.0 band and... + if ( CSR_IS_CHANNEL_5GHZ( pMac->scan.channelOf11dInfo ) ) + { + // and the 2.4 band is empty, then populate the 2.4 channel info + if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList24, LL_ACCESS_LOCK ) ) break; + fPopulate5GBand = FALSE; + } + else + { + // else, we found channel info in the 2.4 GHz band. If the 5.0 band is empty + // set the 5.0 band info from the 2.4 country code. + if ( !csrLLIsListEmpty( &pMac->scan.channelPowerInfoList5G, LL_ACCESS_LOCK ) ) break; + fPopulate5GBand = TRUE; + } + csrSaveChannelPowerForBand( pMac, fPopulate5GBand ); + + } while( 0 ); +} + + +tANI_BOOLEAN csrIsSupportedChannel(tpAniSirGlobal pMac, tANI_U8 channelId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U32 i; + + //Make sure it is a channel that is in our supported list. + for ( i = 0; i < pMac->scan.baseChannels.numChannels; i++ ) + { + if ( channelId == pMac->scan.baseChannels.channelList[i] ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + } + + //If it is configured to limit a set of the channels + if( fRet && pMac->roam.configParam.fEnforce11dChannels ) + { + fRet = eANI_BOOLEAN_FALSE; + for ( i = 0; i < pMac->scan.base20MHzChannels.numChannels; i++ ) + { + if ( channelId == pMac->scan.base20MHzChannels.channelList[i] ) + { + fRet = eANI_BOOLEAN_TRUE; + break; + } + } + } + + return (fRet); +} + + + +//bSize specify the buffer size of pChannelList +tANI_U8 csrGetChannelListFromChannelSet( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 bSize, tCsrChannelPowerInfo *pChannelSet ) +{ + tANI_U8 i, j = 0, chnId; + + bSize = CSR_MIN(bSize, pChannelSet->numChannels); + for( i = 0; i < bSize; i++ ) + { + chnId = (tANI_U8)(pChannelSet->firstChannel + ( i * pChannelSet->interChannelOffset )); + if ( csrIsSupportedChannel( pMac, chnId ) ) + { + pChannelList[j++] = chnId; + } + } + + return (j); +} + + + +//bSize -- specify the buffer size of pChannelList +void csrConstructCurrentValidChannelList( tpAniSirGlobal pMac, tDblLinkList *pChannelSetList, + tANI_U8 *pChannelList, tANI_U8 bSize, tANI_U8 *pNumChannels ) +{ + tListElem *pEntry; + tCsrChannelPowerInfo *pChannelSet; + tANI_U8 numChannels; + tANI_U8 *pChannels; + + if( pChannelSetList && pChannelList && pNumChannels ) + { + pChannels = pChannelList; + *pNumChannels = 0; + pEntry = csrLLPeekHead( pChannelSetList, LL_ACCESS_LOCK ); + while( pEntry ) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + numChannels = csrGetChannelListFromChannelSet( pMac, pChannels, bSize, pChannelSet ); + pChannels += numChannels; + *pNumChannels += numChannels; + pEntry = csrLLNext( pChannelSetList, pEntry, LL_ACCESS_LOCK ); + } + } +} + + +/* + * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d +*/ +tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce) +{ + eHalStatus status; + tANI_U8 *pCountryCodeSelected; + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + v_REGDOMAIN_t domainId; + tDot11fBeaconIEs *pIesLocal = pIes; + tANI_BOOLEAN useVoting = eANI_BOOLEAN_FALSE; + + if (VOS_STA_SAP_MODE == vos_get_conparam ()) + return eHAL_STATUS_SUCCESS; + + if ((NULL == pSirBssDesc) && (NULL == pIes)) + useVoting = eANI_BOOLEAN_TRUE; + + do + { + // check if .11d support is enabled + if( !csrIs11dSupported( pMac ) ) break; + + if (eANI_BOOLEAN_FALSE == useVoting) + { + if( !pIesLocal && + (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pSirBssDesc, &pIesLocal)))) + { + break; + } + // check if country information element is present + if(!pIesLocal->Country.present) + { + //No country info + break; + } + + if( HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry + (pMac, pIesLocal->Country.country, &domainId, + COUNTRY_QUERY)) && + ( domainId == REGDOMAIN_WORLD)) + { + break; + } + } //useVoting == eANI_BOOLEAN_FALSE + + if (eANI_BOOLEAN_FALSE == useVoting) + pCountryCodeSelected = pIesLocal->Country.country; + else + pCountryCodeSelected = pMac->scan.countryCodeElected; + + status = csrGetRegulatoryDomainForCountry(pMac, + pCountryCodeSelected, &domainId, COUNTRY_IE); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get regId %d"), domainId ); + fRet = eANI_BOOLEAN_FALSE; + break; + } + + /* updating 11d Country Code with Country code selected. */ + + vos_mem_copy(pMac->scan.countryCode11d, + pCountryCodeSelected, + WNI_CFG_COUNTRY_CODE_LEN); + +#ifndef CONFIG_ENABLE_LINUX_REG + // Checking for Domain Id change + if ( domainId != pMac->scan.domainIdCurrent ) + { + vos_mem_copy(pMac->scan.countryCode11d, + pCountryCodeSelected, + sizeof( pMac->scan.countryCode11d ) ); + /* Set Current Country code and Current Regulatory domain */ + status = csrSetRegulatoryDomain(pMac, domainId, NULL); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, "Set Reg Domain Fail %d", status); + fRet = eANI_BOOLEAN_FALSE; + return fRet; + } + //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria. + vos_mem_copy(pMac->scan.countryCodeCurrent, + pCountryCodeSelected, WNI_CFG_COUNTRY_CODE_LEN); + //Simply set it to cfg. + csrSetCfgCountryCode(pMac, pCountryCodeSelected); + + /* overwrite the defualt country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, + pMac->scan.countryCodeCurrent, + WNI_CFG_COUNTRY_CODE_LEN); + /* Set Current RegDomain */ + status = WDA_SetRegDomain(pMac, domainId, eSIR_TRUE); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to Set regId %d"), domainId ); + fRet = eANI_BOOLEAN_FALSE; + return fRet; + } + /* set to default domain ID */ + pMac->scan.domainIdCurrent = domainId; + /* get the channels based on new cc */ + status = csrInitGetChannels( pMac ); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + fRet = eANI_BOOLEAN_FALSE; + return fRet; + } + + /* reset info based on new cc, and we are done */ + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + /* Regulatory Domain Changed, Purge Only scan result + * which does not have channel number belong to 11d + * channel list + */ + csrScanFilterResults(pMac); + } +#endif + fRet = eANI_BOOLEAN_TRUE; + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( fRet ); +} + + +static void csrSaveScanResults( tpAniSirGlobal pMac, tANI_U8 reason ) +{ + // initialize this to FALSE. profMoveInterimScanResultsToMainList() routine + // will set this to the channel where an .11d beacon is seen + pMac->scan.channelOf11dInfo = 0; + // if we get any ambiguous .11d information then this will be set to TRUE + pMac->scan.fAmbiguous11dInfoFound = eANI_BOOLEAN_FALSE; + //Tush + // if we get any ambiguous .11d information, then this will be set to TRUE + // only if the applied 11d info could be found in one of the scan results + pMac->scan.fCurrent11dInfoMatch = eANI_BOOLEAN_FALSE; + // move the scan results from interim list to the main scan list + csrMoveTempScanResultsToMainList( pMac, reason ); +} + + +void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + switch (pCommand->u.scanCmd.reason) + { + case eCsrScanSetBGScanParam: + case eCsrScanAbortBgScan: + if(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList) + { + vos_mem_free(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList); + pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL; + } + break; + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + case eCsrScanGetScanChnInfo: + break; + case eCsrScanAbortNormalScan: + default: + csrScanFreeRequest(pMac, &pCommand->u.scanCmd.u.scanRequest); + break; + } + if(pCommand->u.scanCmd.pToRoamProfile) + { + csrReleaseProfile(pMac, pCommand->u.scanCmd.pToRoamProfile); + vos_mem_free(pCommand->u.scanCmd.pToRoamProfile); + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); +} + + +tANI_BOOLEAN csrGetRemainingChannelsFor11dScan( tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U8 *pcChannels ) +{ + tANI_U32 index11dChannels, index; + tANI_U32 indexCurrentChannels; + tANI_BOOLEAN fChannelAlreadyScanned; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + *pcChannels = 0; + if ( CSR_IS_11D_INFO_FOUND(pMac) && csrRoamIsChannelValid(pMac, pMac->scan.channelOf11dInfo) ) + { + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + //Find the channel index where we found the 11d info + for(index = 0; index < len; index++) + { + if(pMac->scan.channelOf11dInfo == pMac->roam.validChannelList[index]) + break; + } + //check whether we found the channel index + if(index < len) + { + // Now, look through the 11d channel list and create a list of all channels in the 11d list that are + // NOT in the current channel list. This gives us a list of the new channels that have not been + // scanned. We'll scan this new list so we have a complete set of scan results on all of the domain channels + // initially. + for ( index11dChannels = 0; index11dChannels < pMac->scan.channels11d.numChannels; index11dChannels++ ) + { + fChannelAlreadyScanned = eANI_BOOLEAN_FALSE; + + for( indexCurrentChannels = 0; indexCurrentChannels < index; indexCurrentChannels++ ) + { + if ( pMac->roam.validChannelList[ indexCurrentChannels ] == pMac->scan.channels11d.channelList[ index11dChannels ] ) + { + fChannelAlreadyScanned = eANI_BOOLEAN_TRUE; + break; + } + } + + if ( !fChannelAlreadyScanned ) + { + pChannels[ *pcChannels ] = pMac->scan.channels11d.channelList[ index11dChannels ]; + ( *pcChannels )++; + } + } + } + }//GetCFG + } + return( *pcChannels ); +} + + +eCsrScanCompleteNextCommand csrScanGetNextCommandState( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fSuccess ) +{ + eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing; + + switch( pCommand->u.scanCmd.reason ) + { + case eCsrScan11d1: + NextCommand = (fSuccess) ? eCsrNext11dScan1Success : eCsrNext11dScan1Failure; + break; + case eCsrScan11d2: + NextCommand = (fSuccess) ? eCsrNext11dScan2Success : eCsrNext11dScan2Failure; + break; + case eCsrScan11dDone: + NextCommand = eCsrNext11dScanComplete; + break; + case eCsrScanLostLink1: + NextCommand = (fSuccess) ? eCsrNextLostLinkScan1Success : eCsrNextLostLinkScan1Failed; + break; + case eCsrScanLostLink2: + NextCommand = (fSuccess) ? eCsrNextLostLinkScan2Success : eCsrNextLostLinkScan2Failed; + break; + case eCsrScanLostLink3: + NextCommand = (fSuccess) ? eCsrNextLostLinkScan3Success : eCsrNextLostLinkScan3Failed; + break; + case eCsrScanForSsid: + NextCommand = (fSuccess) ? eCsrNexteScanForSsidSuccess : eCsrNexteScanForSsidFailure; + break; + case eCsrScanForCapsChange: + NextCommand = eCsrNextCapChangeScanComplete; //don't care success or not + break; + case eCsrScanIdleScan: + NextCommand = eCsrNextIdleScanComplete; + break; + default: + NextCommand = eCsrNextScanNothing; + break; + } + return( NextCommand ); +} + + +//Return whether the pCommand is finished. +tANI_BOOLEAN csrHandleScan11d1Failure(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + + //Apply back the default setting and passively scan one more time. + csrResetCountryInformation(pMac, eANI_BOOLEAN_FALSE, eANI_BOOLEAN_TRUE); + pCommand->u.scanCmd.reason = eCsrScan11d2; + if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand))) + { + fRet = eANI_BOOLEAN_FALSE; + } + + return (fRet); +} + + +tANI_BOOLEAN csrHandleScan11dSuccess(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + tANI_U8 *pChannels; + tANI_U8 cChannels; + + pChannels = vos_mem_malloc(WNI_CFG_VALID_CHANNEL_LIST_LEN); + if ( NULL != pChannels ) + { + vos_mem_set(pChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN, 0); + if ( csrGetRemainingChannelsFor11dScan( pMac, pChannels, &cChannels ) ) + { + pCommand->u.scanCmd.reason = eCsrScan11dDone; + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) + { + vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc(cChannels); + if ( NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + { + vos_mem_copy(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, + pChannels, cChannels); + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = cChannels; + pCommand->u.scanCmd.u.scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + pCommand->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + if(HAL_STATUS_SUCCESS(csrScanChannels(pMac, pCommand))) + { + //Reuse the same command buffer + fRet = eANI_BOOLEAN_FALSE; + } + } + } + vos_mem_free(pChannels); + } + + return (fRet); +} + +//Return whether the command should be removed +tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp ) +{ + eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing; + tListElem *pEntry; + tSmeCmd *pCommand; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + tANI_BOOLEAN fSuccess; + + if (pMac->fScanOffload) + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + else + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + // If the head of the queue is Active and it is a SCAN command, remove + // and put this on the Free queue. + if ( eSmeCommandScan == pCommand->command ) + { + tANI_U32 sessionId = pCommand->sessionId; + + if(eSIR_SME_SUCCESS != pScanRsp->statusCode) + { + fSuccess = eANI_BOOLEAN_FALSE; + } + else + { + //pMac->scan.tempScanResults is not empty meaning the scan found something + //This check only valid here because csrSaveScanresults is not yet called + fSuccess = (!csrLLIsListEmpty(&pMac->scan.tempScanResults, LL_ACCESS_LOCK)); + } + if (pCommand->u.scanCmd.abortScanIndication & + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) + { + /* + * Scan aborted due to band change + * The scan results need to be flushed + */ + if (pCommand->u.scanCmd.callback + != pMac->scan.callback11dScanDone) + { + smsLog(pMac, LOG1, FL("Filtering the scan results as the " + "results may belong to wrong band")); + csrScanFilterResults(pMac); + } + else + { + smsLog(pMac, LOG1, FL("11d_scan_done will flush the scan" + " results")); + } + } + csrSaveScanResults(pMac, pCommand->u.scanCmd.reason); + + /* filter scan result based on valid channel list number */ + if (pMac->scan.fcc_constraint) + { + smsLog(pMac, LOG1, FL("Clear BSS from invalid channels")); + csrScanFilterResults(pMac); + } +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_scan_pkt_type *pScanLog = NULL; + tScanResultHandle hScanResult; + tCsrScanResultInfo *pScanResult; + tDot11fBeaconIEs *pIes; + int n = 0, c = 0; + + WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C); + if(pScanLog) + { + if(eCsrScanBgScan == pCommand->u.scanCmd.reason || + eCsrScanProbeBss == pCommand->u.scanCmd.reason || + eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason) + { + pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_RSP; + } + else + { + if( eSIR_PASSIVE_SCAN != pMac->scan.curScanType ) + { + pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP; + } + else + { + pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP; + } + } + if(eSIR_SME_SUCCESS == pScanRsp->statusCode) + { + if(HAL_STATUS_SUCCESS(csrScanGetResult(pMac, NULL, &hScanResult))) + { + while(((pScanResult = csrScanResultGetNext(pMac, hScanResult)) != NULL)) + { + if( n < VOS_LOG_MAX_NUM_BSSID ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pScanResult->BssDescriptor, &pIes))) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + break; + } + vos_mem_copy(pScanLog->bssid[n], + pScanResult->BssDescriptor.bssId, 6); + if(pIes && pIes->SSID.present && VOS_LOG_MAX_SSID_SIZE >= pIes->SSID.num_ssid) + { + vos_mem_copy(pScanLog->ssid[n], + pIes->SSID.ssid, pIes->SSID.num_ssid); + } + vos_mem_free(pIes); + n++; + } + c++; + } + pScanLog->numSsid = (v_U8_t)n; + pScanLog->totalSsid = (v_U8_t)c; + csrScanResultPurge(pMac, hScanResult); + } + } + else + { + pScanLog->status = WLAN_SCAN_STATUS_FAILURE; + } + WLAN_VOS_DIAG_LOG_REPORT(pScanLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + NextCommand = csrScanGetNextCommandState(pMac, pCommand, fSuccess); + //We reuse the command here instead reissue a new command + switch(NextCommand) + { + case eCsrNext11dScan1Success: + case eCsrNext11dScan2Success: + smsLog( pMac, LOG2, FL("11dScan1/3 produced results. Reissue Active scan...")); + // if we found country information, no need to continue scanning further, bail out + fRemoveCommand = eANI_BOOLEAN_TRUE; + NextCommand = eCsrNext11dScanComplete; + break; + case eCsrNext11dScan1Failure: + //We are not done yet. 11d scan fail once. We will try to reset anything and do it over again + //The only meaningful thing for this retry is that we cannot find 11d information after a reset so + //we clear the "old" 11d info and give it once more chance + fRemoveCommand = csrHandleScan11d1Failure(pMac, pCommand); + if(fRemoveCommand) + { + NextCommand = eCsrNext11dScanComplete; + } + break; + case eCsrNextLostLinkScan1Success: + if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink1))) + { + csrScanHandleFailedLostlink1(pMac, sessionId); + } + break; + case eCsrNextLostLinkScan2Success: + if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink2))) + { + csrScanHandleFailedLostlink2(pMac, sessionId); + } + break; + case eCsrNextLostLinkScan3Success: + if(!HAL_STATUS_SUCCESS(csrIssueRoamAfterLostlinkScan(pMac, sessionId, eCsrLostLink3))) + { + csrScanHandleFailedLostlink3(pMac, sessionId); + } + break; + case eCsrNextLostLinkScan1Failed: + csrScanHandleFailedLostlink1(pMac, sessionId); + break; + case eCsrNextLostLinkScan2Failed: + csrScanHandleFailedLostlink2(pMac, sessionId); + break; + case eCsrNextLostLinkScan3Failed: + csrScanHandleFailedLostlink3(pMac, sessionId); + break; + case eCsrNexteScanForSsidSuccess: + csrScanHandleSearchForSSID(pMac, pCommand); + break; + case eCsrNexteScanForSsidFailure: + csrScanHandleSearchForSSIDFailure(pMac, pCommand); + break; + case eCsrNextIdleScanComplete: + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + break; + case eCsrNextCapChangeScanComplete: + csrScanHandleCapChangeScanComplete(pMac, sessionId); + break; + default: + + break; + } + } + else + { + smsLog( pMac, LOGW, FL("Scan Completion called but SCAN command is not ACTIVE ...")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + } + } + else + { + smsLog( pMac, LOGW, FL("Scan Completion called but NO commands are ACTIVE ...")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + } + + return( fRemoveCommand ); +} + + + +static void csrScanRemoveDupBssDescriptionFromInterimList( tpAniSirGlobal pMac, + tSirBssDescription *pSirBssDescr, + tDot11fBeaconIEs *pIes) +{ + tListElem *pEntry; + tCsrScanResult *pCsrBssDescription; + + // Walk through all the chained BssDescriptions. If we find a chained BssDescription that + // matches the BssID of the BssDescription passed in, then these must be duplicate scan + // results for this Bss. In that case, remove the 'old' Bss description from the linked list. + pEntry = csrLLPeekHead( &pMac->scan.tempScanResults, LL_ACCESS_LOCK ); + while( pEntry ) + { + pCsrBssDescription = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + // we have a duplicate scan results only when BSSID, SSID, Channel and NetworkType + // matches + + if ( csrIsDuplicateBssDescription( pMac, &pCsrBssDescription->Result.BssDescriptor, + pSirBssDescr, pIes, FALSE ) ) + { + pSirBssDescr->rssi = (tANI_S8)( (((tANI_S32)pSirBssDescr->rssi * CSR_SCAN_RESULT_RSSI_WEIGHT ) + + ((tANI_S32)pCsrBssDescription->Result.BssDescriptor.rssi * (100 - CSR_SCAN_RESULT_RSSI_WEIGHT) )) / 100 ); + + // Remove the 'old' entry from the list.... + if( csrLLRemoveEntry( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ) ) + { + csrCheckNSaveWscIe(pMac, pSirBssDescr, &pCsrBssDescription->Result.BssDescriptor); + // we need to free the memory associated with this node + csrFreeScanResultEntry( pMac, pCsrBssDescription ); + } + + // If we found a match, we can stop looking through the list. + break; + } + + pEntry = csrLLNext( &pMac->scan.tempScanResults, pEntry, LL_ACCESS_LOCK ); + } +} + + + +//Caller allocated memory pfNewBssForConn to return whether new candidate for +//current connection is found. Cannot be NULL +tCsrScanResult *csrScanSaveBssDescriptionToInterimList( tpAniSirGlobal pMac, + tSirBssDescription *pBSSDescription, + tDot11fBeaconIEs *pIes) +{ + tCsrScanResult *pCsrBssDescription = NULL; + tANI_U32 cbBSSDesc; + tANI_U32 cbAllocated; + + // figure out how big the BSS description is (the BSSDesc->length does NOT + // include the size of the length field itself). + cbBSSDesc = pBSSDescription->length + sizeof( pBSSDescription->length ); + + cbAllocated = sizeof( tCsrScanResult ) + cbBSSDesc; + + pCsrBssDescription = vos_mem_malloc(cbAllocated); + if ( NULL != pCsrBssDescription ) + { + vos_mem_set(pCsrBssDescription, cbAllocated, 0); + pCsrBssDescription->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount; + vos_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc ); + //Save SSID separately for later use + if( pIes->SSID.present && !csrIsNULLSSID(pIes->SSID.ssid, pIes->SSID.num_ssid) ) + { + //SSID not hidden + tANI_U32 len = pIes->SSID.num_ssid; + if (len > SIR_MAC_MAX_SSID_LENGTH) + { + // truncate to fit in our struct + len = SIR_MAC_MAX_SSID_LENGTH; + } + pCsrBssDescription->Result.ssId.length = len; + pCsrBssDescription->Result.timer = vos_timer_get_system_time(); + vos_mem_copy(pCsrBssDescription->Result.ssId.ssId, pIes->SSID.ssid, len); + } + csrLLInsertTail( &pMac->scan.tempScanResults, &pCsrBssDescription->Link, LL_ACCESS_LOCK ); + } + + return( pCsrBssDescription ); +} + + + + +tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2, tANI_BOOLEAN fForced ) +{ + tANI_BOOLEAN fMatch = FALSE; + tSirMacCapabilityInfo *pCap1, *pCap2; + tDot11fBeaconIEs *pIes1 = NULL; + tDot11fBeaconIEs *pIesTemp = pIes2; + + pCap1 = (tSirMacCapabilityInfo *)&pSirBssDesc1->capabilityInfo; + pCap2 = (tSirMacCapabilityInfo *)&pSirBssDesc2->capabilityInfo; + if(pCap1->ess == pCap2->ess) + { + if (pCap1->ess && + csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)&& + (fForced || (vos_chan_to_band(pSirBssDesc1->channelId) == vos_chan_to_band((pSirBssDesc2->channelId))))) + { + fMatch = TRUE; + // Check for SSID match, if exists + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1))) + { + break; + } + if( NULL == pIesTemp ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp))) + { + break; + } + } + if(pIes1->SSID.present && pIesTemp->SSID.present) + { + fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid, + pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE); + } + }while(0); + + } + else if (pCap1->ibss && (pSirBssDesc1->channelId == pSirBssDesc2->channelId)) + { + + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1))) + { + break; + } + if( NULL == pIesTemp ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesTemp))) + { + break; + } + } + //Same channel cannot have same SSID for different IBSS + if(pIes1->SSID.present && pIesTemp->SSID.present) + { + fMatch = csrIsSsidMatch(pMac, pIes1->SSID.ssid, pIes1->SSID.num_ssid, + pIesTemp->SSID.ssid, pIesTemp->SSID.num_ssid, eANI_BOOLEAN_TRUE); + } + }while(0); + } + /* In case of P2P devices, ess and ibss will be set to zero */ + else if (!pCap1->ess && + csrIsMacAddressEqual( pMac, (tCsrBssid *)pSirBssDesc1->bssId, (tCsrBssid *)pSirBssDesc2->bssId)) + { + fMatch = TRUE; + } + } + + if(pIes1) + { + vos_mem_free(pIes1); + } + + if( (NULL == pIes2) && pIesTemp ) + { + //locally allocated + vos_mem_free(pIesTemp); + } + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ) +{ + return( pSirBssDesc1->nwType == pSirBssDesc2->nwType ); +} + + +//to check whether the BSS matches the dot11Mode +static tANI_BOOLEAN csrScanIsBssAllowed(tpAniSirGlobal pMac, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tANI_BOOLEAN fAllowed = eANI_BOOLEAN_FALSE; + eCsrPhyMode phyMode; + + if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pBssDesc, &phyMode, pIes))) + { + switch(pMac->roam.configParam.phyMode) + { + case eCSR_DOT11_MODE_11b: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode); + break; + case eCSR_DOT11_MODE_11g: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a != phyMode); + break; + case eCSR_DOT11_MODE_11g_ONLY: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11g == phyMode); + break; + case eCSR_DOT11_MODE_11a: + fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11b != phyMode) && (eCSR_DOT11_MODE_11g != phyMode)); + break; + case eCSR_DOT11_MODE_11n_ONLY: + fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11n == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode)); + break; + +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac_ONLY: + fAllowed = (tANI_BOOLEAN)((eCSR_DOT11_MODE_11ac == phyMode) || (eCSR_DOT11_MODE_TAURUS == phyMode)); + break; +#endif + case eCSR_DOT11_MODE_11b_ONLY: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11b == phyMode); + break; + case eCSR_DOT11_MODE_11a_ONLY: + fAllowed = (tANI_BOOLEAN)(eCSR_DOT11_MODE_11a == phyMode); + break; + case eCSR_DOT11_MODE_11n: +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: +#endif + case eCSR_DOT11_MODE_TAURUS: + default: + fAllowed = eANI_BOOLEAN_TRUE; + break; + } + } + + return (fAllowed); +} + + + +//Return pIes to caller for future use when returning TRUE. +static tANI_BOOLEAN csrScanValidateScanResult( tpAniSirGlobal pMac, tANI_U8 *pChannels, + tANI_U8 numChn, tSirBssDescription *pBssDesc, + tDot11fBeaconIEs **ppIes ) +{ + tANI_BOOLEAN fValidChannel = FALSE; + tDot11fBeaconIEs *pIes = NULL; + tANI_U8 index; + + for( index = 0; index < numChn; index++ ) + { + // This check relies on the fact that a single BSS description is returned in each + // ScanRsp call, which is the way LIM implemented the scan req/rsp funtions. We changed + // to this model when we ran with a large number of APs. If this were to change, then + // this check would have to mess with removing the bssDescription from somewhere in an + // arbitrary index in the bssDescription array. + if ( pChannels[ index ] == pBssDesc->channelId ) + { + fValidChannel = TRUE; + break; + } + } + *ppIes = NULL; + if(fValidChannel) + { + if( HAL_STATUS_SUCCESS( csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes) ) ) + { + fValidChannel = csrScanIsBssAllowed(pMac, pBssDesc, pIes); + if( fValidChannel ) + { + *ppIes = pIes; + } + else + { + vos_mem_free(pIes); + } + } + else + { + fValidChannel = FALSE; + } + } + + return( fValidChannel ); +} + + +//Return whether last scan result is received +static tANI_BOOLEAN csrScanProcessScanResults( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tSirSmeScanRsp *pScanRsp, tANI_BOOLEAN *pfRemoveCommand ) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE, fRemoveCommand = eANI_BOOLEAN_FALSE; + tDot11fBeaconIEs *pIes = NULL; + tANI_U32 cbParsed; + tSirBssDescription *pSirBssDescription; + tANI_U32 cbBssDesc; + eHalStatus status; + tANI_U32 cbScanResult = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ) + + sizeof(tSirBssDescription); //We need at least one CB + + // don't consider the scan rsp to be valid if the status code is Scan Failure. Scan Failure + // is returned when the scan could not find anything. so if we get scan failure return that + // the scan response is invalid. Also check the lenght in the scan result for valid scan + // BssDescriptions.... + do + { + if ( ( cbScanResult <= pScanRsp->length ) && + (( eSIR_SME_SUCCESS == pScanRsp->statusCode ) || + ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW == pScanRsp->statusCode ) ) ) + { + tANI_U8 *pChannelList = NULL; + tANI_U8 cChannels = 0; + + //Different scan type can reach this point, we need to distinguish it +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if( eCsrScanGetLfrResult == pCommand->u.scanCmd.reason ) + { + pChannelList = NULL; + cChannels = 0; + } + else +#endif + if( eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason ) + { + //eCsrScanSetBGScanParam uses different structure + tCsrBGScanRequest *pBgScanReq = &pCommand->u.scanCmd.u.bgScanRequest; + + cChannels = pBgScanReq->ChannelInfo.numOfChannels; + pChannelList = pBgScanReq->ChannelInfo.ChannelList; + } + else + { + //the rest use generic scan request + cChannels = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + pChannelList = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList; + } + + // if the scan result is not on one of the channels in the Valid channel list, then it + // must have come from an AP on an overlapping channel (in the 2.4GHz band). In this case, + // let's drop the scan result. + // + // The other situation is where the scan request is for a scan on a particular channel set + // and the scan result is from a + + // if the NumChannels is 0, then we are supposed to be scanning all channels. Use the full channel + // list as the 'valid' channel list. Otherwise, use the specific channel list in the scan parms + // as the valid channels. + if ( 0 == cChannels ) + { + tANI_U32 len = sizeof(pMac->roam.validChannelList); + + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + pChannelList = pMac->roam.validChannelList; + cChannels = (tANI_U8)len; + } + else + { + //Cannot continue + smsLog( pMac, LOGE, "CSR: Processing internal SCAN results...csrGetCfgValidChannels failed" ); + break; + } + } + + smsLog( pMac, LOG2, "CSR: Processing internal SCAN results..." ); + cbParsed = GET_FIELD_OFFSET( tSirSmeScanRsp, bssDescription ); + pSirBssDescription = pScanRsp->bssDescription; + while( cbParsed < pScanRsp->length ) + { + if ( csrScanValidateScanResult( pMac, pChannelList, cChannels, pSirBssDescription, &pIes ) ) + { + csrScanRemoveDupBssDescriptionFromInterimList(pMac, pSirBssDescription, pIes); + csrScanSaveBssDescriptionToInterimList( pMac, pSirBssDescription, pIes ); + if( eSIR_PASSIVE_SCAN == pMac->scan.curScanType ) + { + if( csrIs11dSupported( pMac) ) + { + //Check whether the BSS is acceptable base on 11d info and our configs. + if( csrMatchCountryCode( pMac, NULL, pIes ) ) + { + //Double check whether the channel is acceptable by us. + if( csrIsSupportedChannel( pMac, pSirBssDescription->channelId ) ) + { + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + } + } + } + else + { + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + } + } + //Free the resource + vos_mem_free(pIes); + } + // skip over the BSS description to the next one... + cbBssDesc = pSirBssDescription->length + sizeof( pSirBssDescription->length ); + + cbParsed += cbBssDesc; + pSirBssDescription = (tSirBssDescription *)((tANI_U8 *)pSirBssDescription + cbBssDesc ); + + } //while + } + else + { + smsLog( pMac, LOGW, " Scanrsp fail (0x%08X), length = %d (expected %d)", + pScanRsp->statusCode, pScanRsp->length, cbScanResult); + //HO bg scan/probe failed no need to try autonomously + if(eCsrScanBgScan == pCommand->u.scanCmd.reason || + eCsrScanProbeBss == pCommand->u.scanCmd.reason || +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + eCsrScanGetLfrResult == pCommand->u.scanCmd.reason || +#endif + eCsrScanSetBGScanParam == pCommand->u.scanCmd.reason) + { + fRemoveCommand = eANI_BOOLEAN_TRUE; + } + } + }while(0); + if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode ) + { + smsLog(pMac, LOG1, " Scan received %d unique BSS scan reason is %d", csrLLCount(&pMac->scan.tempScanResults), pCommand->u.scanCmd.reason); + fRemoveCommand = csrScanComplete( pMac, pScanRsp ); + fRet = eANI_BOOLEAN_TRUE; + }//if ( eSIR_SME_MORE_SCAN_RESULTS_FOLLOW != pScanRsp->statusCode ) + if(pfRemoveCommand) + { + *pfRemoveCommand = fRemoveCommand; + } + + /* + * Currently SET_FCC_CHANNEL issues updated channel list to fw. + * At the time of driver load, if scan is issued followed with + * SET_FCC_CHANNEL, driver will send update channel list to fw. + * Fw will stop ongoing scan because of that GUI will have very less + * scan list. + * Update channel list should be sent to fw once scan is done + */ + if (pMac->scan.defer_update_channel_list) { + status = csrUpdateChannelList(pMac); + if (eHAL_STATUS_SUCCESS != status) + smsLog(pMac, LOGE, + FL( "failed to update the supported channel list")); + pMac->scan.defer_update_channel_list = false; + } + +#ifdef WLAN_AP_STA_CONCURRENCY + if (pMac->fScanOffload) + return fRet; + + if (!csrLLIsListEmpty( &pMac->scan.scanCmdPendingList, LL_ACCESS_LOCK )) + { + /* Pending scan commands in the list because the previous scan command + * was split into a scan command on one channel + a scan command for all + * remaining channels. + * + * Start timer to trigger processing of the next scan command. + * NOTE for LFR: + * Do not split scans if no concurrent infra connections are + * active and if the scan is a BG scan triggered by LFR (OR) + * any scan if LFR is in the middle of a BG scan. Splitting + * the scan is delaying the time it takes for LFR to find + * candidates and resulting in disconnects. + */ + if ( (csrIsStaSessionConnected(pMac) && +#ifdef FEATURE_WLAN_LFR + (csrIsConcurrentInfraConnected(pMac) || + ((pCommand->u.scanCmd.reason != eCsrScanBgScan) && + (pMac->roam.neighborRoamInfo.neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) && +#endif + (pCommand->u.scanCmd.u.scanRequest.p2pSearch != 1)) || + (csrIsP2pSessionConnected(pMac)) ) + { + /* if active connected sessions present then continue to split scan + * with specified interval between consecutive scans */ + csrSetDefaultScanTiming(pMac, pCommand->u.scanCmd.u.scanRequest.scanType, &(pCommand->u.scanCmd.u.scanRequest)); + vos_timer_start(&pMac->scan.hTimerStaApConcTimer, + pCommand->u.scanCmd.u.scanRequest.restTime); + } else { + /* if no connected sessions present then initiate next scan command immediately */ + /* minimum timer granularity is 10ms */ + vos_timer_start(&pMac->scan.hTimerStaApConcTimer, 10); + } + } +#endif + return (fRet); +} + + +tANI_BOOLEAN csrScanIsWildCardScan( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0}; + tANI_BOOLEAN f = vos_mem_compare(pCommand->u.scanCmd.u.scanRequest.bssid, + bssid, sizeof(tCsrBssid)); + + //It is not a wild card scan if the bssid is not broadcast and the number of SSID is 1. + return ((tANI_BOOLEAN)( (f || (0xff == pCommand->u.scanCmd.u.scanRequest.bssid[0])) && + (pCommand->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs != 1) )); +} + + +eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry; + tSmeCmd *pCommand; + eCsrScanStatus scanStatus; + tSirSmeScanRsp *pScanRsp; + tSmeGetScanChnRsp *pScanChnInfo; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + eCsrScanReason reason = eCsrScanOther; + + if (pMac->fScanOffload) + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, + LL_ACCESS_LOCK); + else + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandScan == pCommand->command ) + { + /* Purge the scan results based on Aging */ + if (pEntry && pMac->scan.scanResultCfgAgingTime) + csrPurgeScanResultByAge(pMac); + reason = pCommand->u.scanCmd.reason; + switch(pCommand->u.scanCmd.reason) + { + case eCsrScanAbortBgScan: + case eCsrScanAbortNormalScan: + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + pScanRsp = (tSirSmeScanRsp *)pMsgBuf; + scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ? + eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE; + break; + case eCsrScanGetScanChnInfo: + pScanChnInfo = (tSmeGetScanChnRsp *)pMsgBuf; + /* + * status code not available in tSmeGetScanChnRsp, so + * by default considereing it to be success + */ + scanStatus = eSIR_SME_SUCCESS; + csrScanAgeResults(pMac, pScanChnInfo); + break; + case eCsrScanForCapsChange: + pScanRsp = (tSirSmeScanRsp *)pMsgBuf; + scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ? + eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE; + csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand ); + break; + case eCsrScanP2PFindPeer: + pScanRsp = (tSirSmeScanRsp *)pMsgBuf; + scanStatus = ((eSIR_SME_SUCCESS == pScanRsp->statusCode) && + (pScanRsp->length > 50)) ? eCSR_SCAN_FOUND_PEER : eCSR_SCAN_FAILURE; + csrScanProcessScanResults( pMac, pCommand, pScanRsp, NULL ); + break; + case eCsrScanSetBGScanParam: + default: + pScanRsp = (tSirSmeScanRsp *)pMsgBuf; + scanStatus = (eSIR_SME_SUCCESS == pScanRsp->statusCode) ? + eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE; + if(csrScanProcessScanResults( pMac, pCommand, pScanRsp, &fRemoveCommand )) + { + //Not to get channel info if the scan is not a wildcard scan because + //it may cause scan results got aged out incorrectly. + if(csrScanIsWildCardScan( pMac, pCommand ) && + (!pCommand->u.scanCmd.u.scanRequest.p2pSearch) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (pCommand->u.scanCmd.reason != eCsrScanGetLfrResult) +#endif + ) + { + csrScanGetScanChnInfo(pMac, pCommand); + } + } + break; + }//switch + if(fRemoveCommand) + { + + csrReleaseScanCommand(pMac, pCommand, scanStatus); + + } + smeProcessPendingQueue( pMac ); + } + else + { + smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." ); + status = eHAL_STATUS_FAILURE; + } + } + else + { + smsLog( pMac, LOGW, "CSR: Scan Completion called but NO commands are ACTIVE ..." ); + status = eHAL_STATUS_FAILURE; + } + + return (status); +} + + + + +tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal pMac, tScanResultHandle hScanResult) +{ + tListElem *pEntry; + tCsrScanResult *pResult; + tCsrScanResultInfo *pRet = NULL; + tScanResultList *pResultList = (tScanResultList *)hScanResult; + + if(pResultList) + { + csrLLLock(&pResultList->List); + pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK); + if(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + pRet = &pResult->Result; + } + pResultList->pCurEntry = pEntry; + csrLLUnlock(&pResultList->List); + } + + return pRet; +} + + +tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal pMac, tScanResultHandle hScanResult) +{ + tListElem *pEntry = NULL; + tCsrScanResult *pResult = NULL; + tCsrScanResultInfo *pRet = NULL; + tScanResultList *pResultList = (tScanResultList *)hScanResult; + + if(pResultList) + { + csrLLLock(&pResultList->List); + if(NULL == pResultList->pCurEntry) + { + pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK); + } + else + { + pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK); + } + if(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + pRet = &pResult->Result; + } + pResultList->pCurEntry = pEntry; + csrLLUnlock(&pResultList->List); + } + + return pRet; +} + + +//This function moves the first BSS that matches the bssid to the head of the result +eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanResultList *pResultList = (tScanResultList *)hScanResult; + tCsrScanResult *pResult = NULL; + tListElem *pEntry = NULL; + + if(pResultList && bssid) + { + csrLLLock(&pResultList->List); + pEntry = csrLLPeekHead(&pResultList->List, LL_ACCESS_NOLOCK); + while(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrScanResult, Link); + if (vos_mem_compare(bssid, pResult->Result.BssDescriptor.bssId, sizeof(tCsrBssid))) + { + status = eHAL_STATUS_SUCCESS; + csrLLRemoveEntry(&pResultList->List, pEntry, LL_ACCESS_NOLOCK); + csrLLInsertHead(&pResultList->List, pEntry, LL_ACCESS_NOLOCK); + break; + } + pEntry = csrLLNext(&pResultList->List, pResultList->pCurEntry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(&pResultList->List); + } + + return (status); +} + + +//Remove the BSS if possible. +//Return -- TRUE == the BSS is remove. False == Fail to remove it +//This function is called when list lock is held. Be caution what functions it can call. +tANI_BOOLEAN csrScanAgeOutBss(tpAniSirGlobal pMac, tCsrScanResult *pResult) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U32 i; + tCsrRoamSession *pSession; + tANI_BOOLEAN isConnBssfound = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + //Not to remove the BSS we are connected to. + if(csrIsConnStateConnectedInfra(pMac, i) && (NULL != pSession->pConnectBssDesc) && + (csrIsDuplicateBssDescription(pMac, &pResult->Result.BssDescriptor, + pSession->pConnectBssDesc, NULL, FALSE)) + ) + { + isConnBssfound = eANI_BOOLEAN_TRUE; + break; + } + } + } + + if( isConnBssfound ) + { + //Reset the counter so that aging out of connected BSS won't hapeen too soon + pResult->AgingCount = (tANI_S32)pMac->roam.configParam.agingCount; + pResult->Result.BssDescriptor.nReceivedTime = + vos_timer_get_system_time(); + + return (fRet); + } + else + { + smsLog(pMac, LOGW, "Aging out BSS "MAC_ADDRESS_STR" Channel %d", + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId), + pResult->Result.BssDescriptor.channelId); + //No need to hold the spin lock because caller should hold the lock for pMac->scan.scanResultList + if( csrLLRemoveEntry(&pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_NOLOCK) ) + { + if (csrIsMacAddressEqual(pMac, + (tCsrBssid *) pResult->Result.BssDescriptor.bssId, + (tCsrBssid *) pMac->scan.currentCountryBssid)) + { + smsLog(pMac, LOGW, "Aging out 11d BSS "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId)); + pMac->scan.currentCountryRSSI = -128; + } + csrFreeScanResultEntry(pMac, pResult); + fRet = eANI_BOOLEAN_TRUE; + } + } + + return (fRet); +} + + +eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult; + tLimScanChn *pChnInfo; + tANI_U8 i; + + csrLLLock(&pMac->scan.scanResultList); + for(i = 0; i < pScanChnInfo->numChn; i++) + { + pChnInfo = &pScanChnInfo->scanChn[i]; + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if(pResult->Result.BssDescriptor.channelId == pChnInfo->channelId) + { + if(pResult->AgingCount <= 0) + { + smsLog(pMac, LOGW, " age out due to ref count"); + csrScanAgeOutBss(pMac, pResult); + } + else + { + pResult->AgingCount--; + } + } + pEntry = tmpEntry; + } + } + csrLLUnlock(&pMac->scan.scanResultList); + + return (status); +} + +eHalStatus csrIbssAgeBss(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult; + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, + pEntry, LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + + smsLog(pMac, LOGW, FL(" age out due Forced IBSS leave")); + csrScanAgeOutBss(pMac, pResult); + pEntry = tmpEntry; + } + csrLLUnlock(&pMac->scan.scanResultList); + + return (status); +} + +/** + * csr_remove_bssid_from_scan_list() - remove the bssid from + * scan list + * @pMac: mac context. + * @bssid: bssid to be removed + * + * This function remove the given bssid from scan list. + * + * Return: void. + */ +void csr_remove_bssid_from_scan_list(tpAniSirGlobal pMac, + tSirMacAddr bssid) +{ + tListElem *entry,*free_elem; + tCsrScanResult *bss_desc; + tDblLinkList *list = &pMac->scan.scanResultList; + + csrLLLock(list); + entry = csrLLPeekHead(list, LL_ACCESS_NOLOCK); + while (entry != NULL) { + bss_desc = GET_BASE_ADDR( entry, tCsrScanResult, Link); + if (vos_mem_compare(bss_desc->Result.BssDescriptor.bssId, + bssid, sizeof(tSirMacAddr))) { + free_elem = entry; + entry = csrLLNext(list, entry, LL_ACCESS_NOLOCK); + csrLLRemoveEntry(list, free_elem, LL_ACCESS_NOLOCK); + csrFreeScanResultEntry(pMac, bss_desc); + smsLog(pMac, LOGW, FL("Removed BSS entry:%pM"), + bssid); + continue; + } + entry = csrLLNext(list, entry, LL_ACCESS_NOLOCK); + } + csrLLUnlock(list); +} + +eHalStatus csrSendMBScanReq( tpAniSirGlobal pMac, tANI_U16 sessionId, + tCsrScanRequest *pScanReq, tScanReqParam *pScanReqParam ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeScanReq *pMsg; + tANI_U16 msgLen; + tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0}; + tSirScanType scanType = pScanReq->scanType; + tANI_U32 minChnTime; //in units of milliseconds + tANI_U32 maxChnTime; //in units of milliseconds + tANI_U32 i; + tANI_U8 selfMacAddr[WNI_CFG_BSSID_LEN]; + tANI_U8 *pSelfMac = NULL; + + msgLen = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) + + ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) + + ( pScanReq->uIEFieldLen ) ; + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + do + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ); + pMsg->length = pal_cpu_to_be16(msgLen); + //ToDO: Fill in session info when we need to do scan base on session. + if ((pMac->fScanOffload) && (sessionId != CSR_SESSION_ID_INVALID)) + { + pMsg->sessionId = sessionId; + } + else + { + /* if sessionId == CSR_SESSION_ID_INVALID, then send the scan + request on first available session */ + pMsg->sessionId = 0; + } + + pMsg->transactionId = 0; + pMsg->dot11mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode )); + pMsg->bssType = pal_cpu_to_be32(csrTranslateBsstypeToMacType(pScanReq->BSSType)); + + if ( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[sessionId].selfMacAddr; + } + else + { + // Since we don't have session for the scanning, we find a valid session. In case we fail to + // do so, get the WNI_CFG_STA_ID + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSelfMac = (tANI_U8 *)&pMac->roam.roamSession[i].selfMacAddr; + break; + } + } + if( CSR_ROAM_SESSION_MAX == i ) + { + tANI_U32 len = WNI_CFG_BSSID_LEN; + pSelfMac = selfMacAddr; + status = ccmCfgGetStr( pMac, WNI_CFG_STA_ID, pSelfMac, &len ); + if( !HAL_STATUS_SUCCESS( status ) || + ( len < WNI_CFG_BSSID_LEN ) ) + { + smsLog( pMac, LOGE, FL(" Can not get self MAC address from CFG status = %d"), status ); + //Force failed status + status = eHAL_STATUS_FAILURE; + break; + } + } + } + vos_mem_copy((tANI_U8 *)pMsg->selfMacAddr, pSelfMac, sizeof(tSirMacAddr)); + + //sirCopyMacAddr + vos_mem_copy((tANI_U8 *)pMsg->bssId, (tANI_U8 *)&pScanReq->bssid, sizeof(tSirMacAddr)); + if ( vos_mem_compare(pScanReq->bssid, bssid, sizeof(tCsrBssid))) + { + vos_mem_set(pMsg->bssId, sizeof(tSirMacAddr), 0xff); + } + else + { + vos_mem_copy(pMsg->bssId, pScanReq->bssid, WNI_CFG_BSSID_LEN); + } + minChnTime = pScanReq->minChnTime; + maxChnTime = pScanReq->maxChnTime; + + //Verify the scan type first, if the scan is active scan, we need to make sure we + //are allowed to do so. + /* if 11d is enabled & we don't see any beacon around, scan type falls + back to passive. But in BT AMP STA mode we need to send out a + directed probe*/ + if( (eSIR_PASSIVE_SCAN != scanType) && (eCSR_SCAN_P2P_DISCOVERY != pScanReq->requestType) + && (eCSR_BSS_TYPE_WDS_STA != pScanReq->BSSType) + && (eANI_BOOLEAN_FALSE == pMac->scan.fEnableBypass11d)) + { + scanType = pMac->scan.curScanType; + if(eSIR_PASSIVE_SCAN == pMac->scan.curScanType) + { + if(minChnTime < pMac->roam.configParam.nPassiveMinChnTime) + { + minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + } + if(maxChnTime < pMac->roam.configParam.nPassiveMaxChnTime) + { + maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + } + } + } + pMsg->scanType = pal_cpu_to_be32(scanType); + + pMsg->numSsid = + (pScanReq->SSIDs.numOfSSIDs < SIR_SCAN_MAX_NUM_SSID) ? + pScanReq->SSIDs.numOfSSIDs : SIR_SCAN_MAX_NUM_SSID; + if((pScanReq->SSIDs.numOfSSIDs != 0) && ( eSIR_PASSIVE_SCAN != scanType )) + { + for (i = 0; i < pMsg->numSsid; i++) + { + vos_mem_copy(&pMsg->ssId[i], + &pScanReq->SSIDs.SSIDList[i].SSID, sizeof(tSirMacSSid)); + } + } + else + { + //Otherwise we scan all SSID and let the result filter later + for (i = 0; i < SIR_SCAN_MAX_NUM_SSID; i++) + { + pMsg->ssId[i].length = 0; + } + } + + pMsg->minChannelTime = pal_cpu_to_be32(minChnTime); + pMsg->maxChannelTime = pal_cpu_to_be32(maxChnTime); + pMsg->min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + pMsg->max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + //hidden SSID option + pMsg->hiddenSsid = pScanReqParam->hiddenSsid; + //rest time + //pMsg->restTime = pScanReq->restTime; + pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch; + // All the scan results caching will be done by Roaming + // We do not want LIM to do any caching of scan results, + // so delete the LIM cache on all scan requests + pMsg->returnFreshResults = pScanReqParam->freshScan; + //Always ask for unique result + pMsg->returnUniqueResults = pScanReqParam->fUniqueResult; + pMsg->channelList.numChannels = (tANI_U8)pScanReq->ChannelInfo.numOfChannels; + if(pScanReq->ChannelInfo.numOfChannels) + { + //Assuming the channelNumber is tANI_U8 (1 byte) + vos_mem_copy(pMsg->channelList.channelNumber, + pScanReq->ChannelInfo.ChannelList, + pScanReq->ChannelInfo.numOfChannels); + } + + pMsg->uIEFieldLen = (tANI_U16) pScanReq->uIEFieldLen; + pMsg->uIEFieldOffset = (tANI_U16)(sizeof( tSirSmeScanReq ) - sizeof( pMsg->channelList.channelNumber ) + + ( sizeof( pMsg->channelList.channelNumber ) * pScanReq->ChannelInfo.numOfChannels )) ; + if(pScanReq->uIEFieldLen != 0) + { + vos_mem_copy((tANI_U8 *)pMsg+pMsg->uIEFieldOffset, pScanReq->pIEField, + pScanReq->uIEFieldLen); + } + pMsg->p2pSearch = pScanReq->p2pSearch; + + if (pScanReq->requestType == eCSR_SCAN_HO_BG_SCAN) + { + pMsg->backgroundScanMode = eSIR_ROAMING_SCAN; + } + + }while(0); + smsLog(pMac, LOG1, FL("domainIdCurrent %s (%d) scanType %s (%d)" + "bssType %s (%d), requestType %s(%d)" + "numChannels %d"), + voss_DomainIdtoString(pMac->scan.domainIdCurrent), + pMac->scan.domainIdCurrent, + lim_ScanTypetoString(pMsg->scanType), pMsg->scanType, + lim_BssTypetoString(pMsg->bssType), pMsg->bssType, + sme_requestTypetoString(pScanReq->requestType), + pScanReq->requestType, + pMsg->channelList.numChannels); + + for(i = 0; i < pMsg->channelList.numChannels; i++) + { + smsLog(pMac, LOG3, FL("channelNumber[%d]= %d"), i, pMsg->channelList.channelNumber[i]); + } + + if(HAL_STATUS_SUCCESS(status)) + { + status = palSendMBMessage(pMac->hHdd, pMsg); + } + else + { + smsLog( pMac, LOGE, FL(" failed to send down scan req with status = %d"), status ); + vos_mem_free(pMsg); + } + }//Success allocated memory + else + { + smsLog( pMac, LOGE, FL(" memory allocation failure")); + } + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOG1, FL("Failed: SId: %d FirstMatch = %d" + " UniqueResult = %d freshScan = %d hiddenSsid = %d"), + sessionId, pScanReqParam->bReturnAfter1stMatch, + pScanReqParam->fUniqueResult, pScanReqParam->freshScan, + pScanReqParam->hiddenSsid ); + smsLog( pMac, LOG1, FL("scanType = %s (%d) BSSType = %s (%d) " + "numOfSSIDs = %d numOfChannels = %d requestType = %s (%d)" + " p2pSearch = %d\n"), + lim_ScanTypetoString(pScanReq->scanType), + pScanReq->scanType, + lim_BssTypetoString(pScanReq->BSSType), + pScanReq->BSSType, + pScanReq->SSIDs.numOfSSIDs, + pScanReq->ChannelInfo.numOfChannels, + sme_requestTypetoString(pScanReq->requestType), + pScanReq->requestType, + pScanReq->p2pSearch ); + + } + + return( status ); +} + +eHalStatus csrSendMBScanResultReq( tpAniSirGlobal pMac, tANI_U32 sessionId, tScanReqParam *pScanReqParam ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeScanReq *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirSmeScanReq )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_REQ); + pMsg->length = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + pMsg->transactionId = 0; + pMsg->returnFreshResults = pScanReqParam->freshScan; + //Always ask for unique result + pMsg->returnUniqueResults = pScanReqParam->fUniqueResult; + pMsg->returnAfterFirstMatch = pScanReqParam->bReturnAfter1stMatch; + status = palSendMBMessage(pMac->hHdd, pMsg); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, FL(" failed to send down scan req with status = %d\n"), status ); + } + + } + + return( status ); +} + + + +eHalStatus csrScanChannels( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanReqParam scanReq; + + do + { + scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE | TRUE; + scanReq.fUniqueResult = TRUE; + scanReq.hiddenSsid = SIR_SCAN_NO_HIDDEN_SSID; + if(eCsrScanForSsid == pCommand->u.scanCmd.reason) + { + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_FIRST_MATCH; + } + else + { + // Basically do scan on all channels even for 11D 1st scan case. + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS; + } + if((eCsrScanBgScan == pCommand->u.scanCmd.reason)|| + (eCsrScanProbeBss == pCommand->u.scanCmd.reason)) + { + scanReq.hiddenSsid = SIR_SCAN_HIDDEN_SSID_PE_DECISION; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_scan_pkt_type *pScanLog = NULL; + + WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C); + if(pScanLog) + { + if(eCsrScanBgScan == pCommand->u.scanCmd.reason || + eCsrScanProbeBss == pCommand->u.scanCmd.reason) + { + pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ; + } + else + { + if( (eSIR_PASSIVE_SCAN != pCommand->u.scanCmd.u.scanRequest.scanType) && + (eSIR_PASSIVE_SCAN != pMac->scan.curScanType) ) + { + pScanLog->eventId = WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ; + } + else + { + pScanLog->eventId = WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ; + } + } + pScanLog->minChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.minChnTime; + pScanLog->maxChnTime = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.maxChnTime; + pScanLog->numChannel = (v_U8_t)pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL)) + { + vos_mem_copy(pScanLog->channels, + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList, + pScanLog->numChannel); + } + WLAN_VOS_DIAG_LOG_REPORT(pScanLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + csrClearVotesForCountryInfo(pMac); + status = csrSendMBScanReq(pMac, pCommand->sessionId, + &pCommand->u.scanCmd.u.scanRequest, &scanReq); + }while(0); + + return( status ); +} + + +eHalStatus csrScanRetrieveResult(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tScanReqParam scanReq; + + do + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (eCsrScanGetLfrResult == pCommand->u.scanCmd.reason) + { + //to get the LFR candidates from PE cache + scanReq.freshScan = SIR_BG_SCAN_RETURN_LFR_CACHED_RESULTS|SIR_BG_SCAN_PURGE_LFR_RESULTS; + scanReq.fUniqueResult = TRUE; + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS; + } + else +#endif + { + //not a fresh scan + scanReq.freshScan = CSR_SME_SCAN_FLAGS_DELETE_CACHE; + scanReq.fUniqueResult = TRUE; + scanReq.bReturnAfter1stMatch = CSR_SCAN_RETURN_AFTER_ALL_CHANNELS; + } + status = csrSendMBScanResultReq(pMac, pCommand->sessionId, &scanReq); + }while(0); + + return (status); +} + +eHalStatus csrProcessMacAddrSpoofCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + tSirSpoofMacAddrReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + do { + msgLen = sizeof(tSirSpoofMacAddrReq); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + return eHAL_STATUS_FAILURE; + pMsg->messageType= pal_cpu_to_be16((tANI_U16)eWNI_SME_MAC_SPOOF_ADDR_IND); + pMsg->length= pal_cpu_to_be16(msgLen); + // spoof mac address + vos_mem_copy((tANI_U8 *)pMsg->macAddr, + (tANI_U8 *)pCommand->u.macAddrSpoofCmd.macAddr, sizeof(tSirMacAddr)); + status = palSendMBMessage(pMac->hHdd, pMsg); + } while( 0 ); + return( status ); +} + +eHalStatus csrProcessScanCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrChannelInfo newChannelInfo = {0, NULL}; + int i, j; + tANI_U8 *pChannel = NULL; + tANI_U32 len = 0; + + // Transition to Scanning state... + if (!pMac->fScanOffload) + { + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + pMac->roam.prev_state[i]= + csrRoamStateChange( pMac, eCSR_ROAMING_STATE_SCANNING, i); + smsLog( pMac, LOG3, "starting SCAN command from %d state...." + " reason is %d", pMac->roam.prev_state[i], + pCommand->u.scanCmd.reason ); + } + } + else + { + pMac->roam.prev_state[pCommand->sessionId] = + csrRoamStateChange(pMac, eCSR_ROAMING_STATE_SCANNING, + pCommand->sessionId); + smsLog( pMac, LOG3, + "starting SCAN command from %d state.... reason is %d", + pMac->roam.prev_state[pCommand->sessionId], + pCommand->u.scanCmd.reason ); + } + + switch(pCommand->u.scanCmd.reason) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eCsrScanGetLfrResult: +#endif + case eCsrScanGetResult: + case eCsrScanForCapsChange: //For cap change, LIM already save BSS description + status = csrScanRetrieveResult(pMac, pCommand); + break; + case eCsrScanSetBGScanParam: + status = csrProcessSetBGScanParam(pMac, pCommand); + break; + case eCsrScanBGScanAbort: + status = csrSetCfgBackgroundScanPeriod(pMac, 0); + break; + case eCsrScanBGScanEnable: + status = csrSetCfgBackgroundScanPeriod(pMac, pMac->roam.configParam.bgScanInterval); + break; + case eCsrScanGetScanChnInfo: + status = csrScanGetScanChannelInfo(pMac, pCommand->sessionId); + break; + case eCsrScanUserRequest: + if(pMac->roam.configParam.fScanTwice) + { + //We scan 2.4 channel twice + if(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels && + (NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList)) + { + len = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + //allocate twice the channel + newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2); + pChannel = pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList; + } + else + { + //get the valid channel list to scan all. + len = sizeof(pMac->roam.validChannelList); + + if (HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, (tANI_U8 *)pMac->roam.validChannelList, &len))) + { + //allocate twice the channel + newChannelInfo.ChannelList = (tANI_U8 *)vos_mem_malloc(len * 2); + pChannel = pMac->roam.validChannelList; + } + } + if(NULL == newChannelInfo.ChannelList) + { + newChannelInfo.numOfChannels = 0; + } + else + { + j = 0; + for(i = 0; i < len; i++) + { + newChannelInfo.ChannelList[j++] = pChannel[i]; + if(CSR_MAX_24GHz_CHANNEL_NUMBER >= pChannel[i]) + { + newChannelInfo.ChannelList[j++] = pChannel[i]; + } + } + if(NULL != pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) + { + //pChannel points to the channellist from the command, free it. + vos_mem_free(pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList); + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = NULL; + } + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = j; + pCommand->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = newChannelInfo.ChannelList; + } + } //if(pMac->roam.configParam.fScanTwice) + + status = csrScanChannels(pMac, pCommand); + + break; + default: + status = csrScanChannels(pMac, pCommand); + break; + } + + if(!HAL_STATUS_SUCCESS(status)) + { + csrReleaseScanCommand(pMac, pCommand, eCSR_SCAN_FAILURE); + } + + return (status); +} + + +eHalStatus csrScanSetBGScanparams(tpAniSirGlobal pMac, tCsrBGScanRequest *pScanReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + + if(pScanReq) + { + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->u.scanCmd.reason = eCsrScanSetBGScanParam; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + vos_mem_copy(&pCommand->u.scanCmd.u.bgScanRequest, pScanReq, sizeof(tCsrBGScanRequest)); + //we have to do the follow + if(pScanReq->ChannelInfo.numOfChannels == 0) + { + pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList = NULL; + } + else + { + pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList + = vos_mem_malloc(pScanReq->ChannelInfo.numOfChannels); + if ( NULL != pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList ) + { + vos_mem_copy(pCommand->u.scanCmd.u.bgScanRequest.ChannelInfo.ChannelList, + pScanReq->ChannelInfo.ChannelList, + pScanReq->ChannelInfo.numOfChannels); + } + else + { + smsLog(pMac, LOGE, FL("ran out of memory")); + csrReleaseCommandScan(pMac, pCommand); + return eHAL_STATUS_FAILURE; + } + } + + //scan req for SSID + if(pScanReq->SSID.length) + { + vos_mem_copy(pCommand->u.scanCmd.u.bgScanRequest.SSID.ssId, + pScanReq->SSID.ssId, pScanReq->SSID.length); + pCommand->u.scanCmd.u.bgScanRequest.SSID.length = pScanReq->SSID.length; + + } + pCommand->u.scanCmd.u.bgScanRequest.maxChnTime= pScanReq->maxChnTime; + pCommand->u.scanCmd.u.bgScanRequest.minChnTime = pScanReq->minChnTime; + pCommand->u.scanCmd.u.bgScanRequest.scanInterval = pScanReq->scanInterval; + + + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan( pMac, pCommand ); + break; + } + }while(0); + } + + return (status); +} + +eHalStatus csrScanBGScanAbort( tpAniSirGlobal pMac ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->u.scanCmd.reason = eCsrScanBGScanAbort; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan( pMac, pCommand ); + break; + } + }while(0); + + return (status); +} + + +//This will enable the background scan with the non-zero interval +eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pCommand = NULL; + + if(pMac->roam.configParam.bgScanInterval) + { + do + { + pCommand = csrGetCommandBuffer(pMac); + if(!pCommand) + { + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pCommand->u.scanCmd, sizeof(tScanCmd), 0); + pCommand->command = eSmeCommandScan; + pCommand->u.scanCmd.reason = eCsrScanBGScanEnable; + pCommand->u.scanCmd.callback = NULL; + pCommand->u.scanCmd.pContext = NULL; + status = csrQueueSmeCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + csrReleaseCommandScan( pMac, pCommand ); + break; + } + }while(0); + } + else + { + smsLog(pMac, LOGE, FL("cannot continue because the bgscan interval is 0")); + status = eHAL_STATUS_INVALID_PARAMETER; + } + return (status); +} + + +eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 len = sizeof(pMac->roam.validChannelList); + tANI_U32 index = 0; + tANI_U32 new_index = 0; + eNVChannelEnabledType NVchannel_state; + tANI_U8 ch144_support = 0; + + ch144_support = WDA_getFwWlanFeatCaps(WLAN_CH144); + + do + { + status = csrScanFreeRequest(pMac, pDstReq); + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(pDstReq, pSrcReq, sizeof(tCsrScanRequest)); + /* Re-initialize the pointers to NULL since we did a copy */ + pDstReq->pIEField = NULL; + pDstReq->ChannelInfo.ChannelList = NULL; + pDstReq->SSIDs.SSIDList = NULL; + + if(pSrcReq->uIEFieldLen == 0) + { + pDstReq->pIEField = NULL; + } + else + { + pDstReq->pIEField = vos_mem_malloc(pSrcReq->uIEFieldLen); + if ( NULL == pDstReq->pIEField ) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, FL("No memory for scanning IE fields")); + break; + } + else + { + status = eHAL_STATUS_SUCCESS; + vos_mem_copy(pDstReq->pIEField, pSrcReq->pIEField, + pSrcReq->uIEFieldLen); + pDstReq->uIEFieldLen = pSrcReq->uIEFieldLen; + } + }//Allocate memory for IE field + { + if(pSrcReq->ChannelInfo.numOfChannels == 0) + { + pDstReq->ChannelInfo.ChannelList = NULL; + pDstReq->ChannelInfo.numOfChannels = 0; + } + else + { + pDstReq->ChannelInfo.ChannelList = vos_mem_malloc( + pSrcReq->ChannelInfo.numOfChannels + * sizeof(*pDstReq->ChannelInfo.ChannelList)); + if ( NULL == pDstReq->ChannelInfo.ChannelList ) + { + status = eHAL_STATUS_FAILURE; + pDstReq->ChannelInfo.numOfChannels = 0; + smsLog(pMac, LOGE, FL("No memory for scanning Channel" + " List")); + break; + } + + if((pSrcReq->scanType == eSIR_PASSIVE_SCAN) && (pSrcReq->requestType == eCSR_SCAN_REQUEST_11D_SCAN)) + { + for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ ) + { + /* Skip CH 144 if firmware support not present */ + if (pSrcReq->ChannelInfo.ChannelList[index] == 144 && !ch144_support) + continue; + /* Skip channel 12 and 13 when FCC constraint is true */ + if ((pMac->scan.fcc_constraint) && + ((pSrcReq->ChannelInfo.ChannelList[index] ==12) || + (pSrcReq->ChannelInfo.ChannelList[index] ==13))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Ignoring channel : %d "), + pSrcReq->ChannelInfo.ChannelList[index]); + continue; + } + + NVchannel_state = vos_nv_getChannelEnabledState( + pSrcReq->ChannelInfo.ChannelList[index]); + if ((NV_CHANNEL_ENABLE == NVchannel_state) || + (NV_CHANNEL_DFS == NVchannel_state)) + { + pDstReq->ChannelInfo.ChannelList[new_index] = + pSrcReq->ChannelInfo.ChannelList[index]; + new_index++; + } + } + pDstReq->ChannelInfo.numOfChannels = new_index; + } + else if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len))) + { + new_index = 0; + pMac->roam.numValidChannels = len; + + /* Since in CsrScanRequest,value of pMac->scan. + * nextScanID is incremented before calling + * CsrScanCopyRequest, as a result pMac->scan. + * nextScanID is equal to ONE for the first scan. + * If number of channels is less than max chan + * for dwell time no need to skip dfs in first + * scan as anyway few channels will be scanned + * and it will not take much time to display + * results on GUI. + */ + if (((pSrcReq->ChannelInfo.numOfChannels >= + pMac->roam.configParam. + max_chan_for_dwell_time_cfg) && + (pMac->roam.configParam. + initialScanSkipDFSCh && + 1 == pMac->scan.nextScanID)) || + (pMac->miracast_mode)) + { + smsLog(pMac, LOG1, + FL("Initial scan, scan only non-DFS channels")); + + for (index = 0; index < pSrcReq->ChannelInfo. + numOfChannels ; index++ ) + { + if((csrRoamIsValidChannel(pMac, + pSrcReq->ChannelInfo. + ChannelList[index]))) + { + /*Skiipping DFS Channels for 1st scan */ + if(NV_CHANNEL_DFS == + vos_nv_getChannelEnabledState( + pSrcReq->ChannelInfo. + ChannelList[index])) + continue ; + + pDstReq->ChannelInfo. + ChannelList[new_index] = + pSrcReq->ChannelInfo.ChannelList[index]; + new_index++; + + } + } + pMac->roam.configParam.initialScanSkipDFSCh = 0; + } + else + csrValidateScanChannels(pMac, pDstReq, pSrcReq, + &new_index, ch144_support); + pDstReq->ChannelInfo.numOfChannels = new_index; +#ifdef FEATURE_WLAN_LFR + if ( ( ( eCSR_SCAN_HO_BG_SCAN == + pSrcReq->requestType ) || + ( eCSR_SCAN_P2P_DISCOVERY == + pSrcReq->requestType ) ) && + ( 0 == pDstReq->ChannelInfo.numOfChannels ) ) + { + /* + * No valid channels found in the request. + * Only perform scan on the channels passed + * pSrcReq if it is a eCSR_SCAN_HO_BG_SCAN or + * eCSR_SCAN_P2P_DISCOVERY. + * Passing 0 to LIM will trigger a scan on + * all valid channels which is not desirable. + */ + smsLog(pMac, LOGE, FL(" no valid channels found" + " (request=%d)"), pSrcReq->requestType); + for ( index = 0; index < pSrcReq->ChannelInfo. + numOfChannels ; index++ ) + { + smsLog(pMac, LOGE, FL("pSrcReq index=%d" + " channel=%d"), index, + pSrcReq->ChannelInfo.ChannelList[index]); + } + status = eHAL_STATUS_FAILURE; + break; + } +#endif + } + else + { + smsLog(pMac, LOGE, FL("Couldn't get the valid Channel" + " List, keeping requester's list")); + vos_mem_copy(pDstReq->ChannelInfo.ChannelList, + pSrcReq->ChannelInfo.ChannelList, + pSrcReq->ChannelInfo.numOfChannels + * sizeof(*pDstReq->ChannelInfo.ChannelList)); + pDstReq->ChannelInfo.numOfChannels = + pSrcReq->ChannelInfo.numOfChannels; + } + }//Allocate memory for Channel List + } + if(pSrcReq->SSIDs.numOfSSIDs == 0) + { + pDstReq->SSIDs.numOfSSIDs = 0; + pDstReq->SSIDs.SSIDList = NULL; + } + else + { + pDstReq->SSIDs.SSIDList = vos_mem_malloc( + pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList)); + if ( NULL == pDstReq->SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + pDstReq->SSIDs.numOfSSIDs = pSrcReq->SSIDs.numOfSSIDs; + vos_mem_copy(pDstReq->SSIDs.SSIDList, + pSrcReq->SSIDs.SSIDList, + pSrcReq->SSIDs.numOfSSIDs * sizeof(*pDstReq->SSIDs.SSIDList)); + } + else + { + pDstReq->SSIDs.numOfSSIDs = 0; + smsLog(pMac, LOGE, FL("No memory for scanning SSID List")); + break; + } + }//Allocate memory for SSID List + pDstReq->p2pSearch = pSrcReq->p2pSearch; + pDstReq->skipDfsChnlInP2pSearch = pSrcReq->skipDfsChnlInP2pSearch; + + } + }while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanFreeRequest(pMac, pDstReq); + } + + return (status); +} + + +eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq) +{ + + if(pReq->ChannelInfo.ChannelList) + { + vos_mem_free(pReq->ChannelInfo.ChannelList); + pReq->ChannelInfo.ChannelList = NULL; + } + pReq->ChannelInfo.numOfChannels = 0; + if(pReq->pIEField) + { + vos_mem_free(pReq->pIEField); + pReq->pIEField = NULL; + } + pReq->uIEFieldLen = 0; + if(pReq->SSIDs.SSIDList) + { + vos_mem_free(pReq->SSIDs.SSIDList); + pReq->SSIDs.SSIDList = NULL; + } + pReq->SSIDs.numOfSSIDs = 0; + + return eHAL_STATUS_SUCCESS; +} + + +void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus) +{ + if(pCommand->u.scanCmd.callback) + { + if (pCommand->u.scanCmd.abortScanIndication){ + if ((pCommand->u.scanCmd.reason != eCsrScanForSsid) || + (scanStatus != eCSR_SCAN_SUCCESS)) { + smsLog( pMac, LOG1, FL("scanDone due to abort")); + scanStatus = eCSR_SCAN_ABORT; + } + } + pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext, pCommand->u.scanCmd.scanID, scanStatus); + } else { + smsLog(pMac, LOG2, + FL("Callback NULL cmd reason %d"), + pCommand->u.scanCmd.reason); + } +} + + +void csrScanStopTimers(tpAniSirGlobal pMac) +{ + csrScanStopIdleScanTimer(pMac); + csrScanStopGetResultTimer(pMac); +} + + +eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac) +{ + eHalStatus status; + + if(pMac->scan.fScanEnable) + { + status = vos_timer_start(&pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL/PAL_TIMER_TO_MS_UNIT); + } + else + { + status = eHAL_STATUS_FAILURE; + } + + return (status); +} + + +eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac) +{ + return (vos_timer_stop(&pMac->scan.hTimerGetResult)); +} + + +void csrScanGetResultTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + + csrScanRequestResult(pMac); + + vos_timer_start(&pMac->scan.hTimerGetResult, CSR_SCAN_GET_RESULT_INTERVAL/PAL_TIMER_TO_MS_UNIT); +} + + +void csr_handle_disable_scan(void *pv) +{ + tpAniSirGlobal mac = PMAC_STRUCT(pv); + + if (mac->scan.disable_scan_during_sco_timer_info.callback) + mac->scan.disable_scan_during_sco_timer_info.callback( + mac, + mac->scan.disable_scan_during_sco_timer_info.dev, + mac->scan.disable_scan_during_sco_timer_info.scan_id, + eHAL_STATUS_SUCCESS); + else + smsLog(mac, LOGE, FL("Callback is NULL")); +} + +#ifdef WLAN_AP_STA_CONCURRENCY +static void csrStaApConcTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry; + tSmeCmd *pScanCmd; + + csrLLLock(&pMac->scan.scanCmdPendingList); + + if ( NULL != ( pEntry = csrLLPeekHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) ) ) + { + tCsrScanRequest scanReq; + tSmeCmd *pSendScanCmd = NULL; + tANI_U8 numChn = 0; + tANI_U8 nNumChanCombinedConc = 0; + tANI_U8 i, j; + tCsrChannelInfo *pChnInfo = &scanReq.ChannelInfo; + tANI_U8 channelToScan[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + eHalStatus status; + + pScanCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + numChn = pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels; + + /* if any session is connected and the number of channels to scan is + * greater than 1 then split the scan into multiple scan operations + * on each individual channel else continue to perform scan on all + * specified channels */ + + /* split scan if number of channels to scan is greater than 1 and + * any one of the following: + * - STA session is connected and the scan is not a P2P search + * - any P2P session is connected + * Do not split scans if no concurrent infra connections are + * active and if the scan is a BG scan triggered by LFR (OR) + * any scan if LFR is in the middle of a BG scan. Splitting + * the scan is delaying the time it takes for LFR to find + * candidates and resulting in disconnects. + */ + + if((csrIsStaSessionConnected(pMac) && + !csrIsP2pSessionConnected(pMac))) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumStaChanCombinedConc; + } + else if(csrIsP2pSessionConnected(pMac)) + { + nNumChanCombinedConc = pMac->roam.configParam.nNumP2PChanCombinedConc; + } + + if ( (numChn > nNumChanCombinedConc) && + ((csrIsStaSessionConnected(pMac) && +#ifdef FEATURE_WLAN_LFR + (csrIsConcurrentInfraConnected(pMac) || + ((pScanCmd->u.scanCmd.reason != eCsrScanBgScan) && + (pMac->roam.neighborRoamInfo.neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN))) && +#endif + (pScanCmd->u.scanCmd.u.scanRequest.p2pSearch != 1)) || + (csrIsP2pSessionConnected(pMac)))) + { + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + + pSendScanCmd = csrGetCommandBuffer(pMac); //optimize this to use 2 command buffer only + if (!pSendScanCmd) + { + smsLog( pMac, LOGE, FL(" Failed to get Queue command buffer") ); + csrLLUnlock(&pMac->scan.scanCmdPendingList); + return; + } + pSendScanCmd->command = pScanCmd->command; + pSendScanCmd->sessionId = pScanCmd->sessionId; + pSendScanCmd->u.scanCmd.callback = NULL; + pSendScanCmd->u.scanCmd.pContext = pScanCmd->u.scanCmd.pContext; + pSendScanCmd->u.scanCmd.reason = pScanCmd->u.scanCmd.reason; + pSendScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + + /* First copy all the parameters to local variable of scan request */ + csrScanCopyRequest(pMac, &scanReq, &pScanCmd->u.scanCmd.u.scanRequest); + + /* Now modify the elements of local var scan request required to be modified for split scan */ + if(scanReq.ChannelInfo.ChannelList != NULL) + { + vos_mem_free(scanReq.ChannelInfo.ChannelList); + scanReq.ChannelInfo.ChannelList = NULL; + } + + pChnInfo->numOfChannels = nNumChanCombinedConc; + vos_mem_copy(&channelToScan[0], + &pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[0], + pChnInfo->numOfChannels * sizeof(tANI_U8));//just send one channel + pChnInfo->ChannelList = &channelToScan[0]; + + for (i = 0, j = nNumChanCombinedConc; i < (numChn-nNumChanCombinedConc); i++, j++) + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[i] = + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[j]; //Move all the channels one step + } + + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = numChn - nNumChanCombinedConc; //reduce outstanding # of channels to be scanned + + scanReq.BSSType = eCSR_BSS_TYPE_ANY; + + //Use concurrency values for min/maxChnTime. + //We know csrIsAnySessionConnected(pMac) returns TRUE here + csrSetDefaultScanTiming(pMac, scanReq.scanType, &scanReq); + + status = csrScanCopyRequest(pMac, &pSendScanCmd->u.scanCmd.u.scanRequest, &scanReq); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog( pMac, LOGE, FL(" Failed to get copy csrScanRequest = %d"), status ); + csrLLUnlock(&pMac->scan.scanCmdPendingList); + return; + } + /* Clean the local scan variable */ + scanReq.ChannelInfo.ChannelList = NULL; + scanReq.ChannelInfo.numOfChannels = 0; + csrScanFreeRequest(pMac, &scanReq); + } + else + { + /* no active connected session present or numChn == 1 + * scan all remaining channels */ + pSendScanCmd = pScanCmd; + //remove this command from pending list + if (csrLLRemoveHead( &pMac->scan.scanCmdPendingList, LL_ACCESS_NOLOCK) == NULL) + { //In case between PeekHead and here, the entry got removed by another thread. + smsLog( pMac, LOGE, FL(" Failed to remove entry from scanCmdPendingList")); + } + + } + csrQueueSmeCommand(pMac, pSendScanCmd, eANI_BOOLEAN_FALSE); + + } + + csrLLUnlock(&pMac->scan.scanCmdPendingList); + +} +#endif + +//This function returns the maximum time a BSS is allowed in the scan result. +//The time varies base on connection and power saving factors. +//Not connected, No PS +//Not connected, with PS +//Connected w/o traffic, No PS +//Connected w/o traffic, with PS +//Connected w/ traffic, no PS -- Not supported +//Connected w/ traffic, with PS -- Not supported +//the return unit is in seconds. +tANI_U32 csrScanGetAgeOutTime(tpAniSirGlobal pMac) +{ + tANI_U32 nRet; + + if(pMac->scan.nAgingCountDown) + { + //Calculate what should be the timeout value for this + nRet = pMac->scan.nLastAgeTimeOut * pMac->scan.nAgingCountDown; + pMac->scan.nAgingCountDown--; + } + else + { + if( csrIsAllSessionDisconnected( pMac ) ) + { + if(pmcIsPowerSaveEnabled(pMac, ePMC_IDLE_MODE_POWER_SAVE)) + { + nRet = pMac->roam.configParam.scanAgeTimeNCPS; + } + else + { + nRet = pMac->roam.configParam.scanAgeTimeNCNPS; + } + } + else + { + if(pmcIsPowerSaveEnabled(pMac, ePMC_BEACON_MODE_POWER_SAVE)) + { + nRet = pMac->roam.configParam.scanAgeTimeCPS; + } + else + { + nRet = pMac->roam.configParam.scanAgeTimeCNPS; + } + } + //If state-change causing aging time out change, we want to delay it somewhat to avoid + //unnecessary removal of BSS. This is mostly due to transition from connect to disconnect. + if(pMac->scan.nLastAgeTimeOut > nRet) + { + if(nRet) + { + pMac->scan.nAgingCountDown = (pMac->scan.nLastAgeTimeOut / nRet); + } + pMac->scan.nLastAgeTimeOut = nRet; + nRet *= pMac->scan.nAgingCountDown; + } + else + { + pMac->scan.nLastAgeTimeOut = nRet; + } + } + + return (nRet); +} + +static void csrPurgeScanResultByAge(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry, *tmpEntry; + tCsrScanResult *pResult; + v_TIME_t ageOutTime = + (v_TIME_t)(pMac->scan.scanResultCfgAgingTime * SYSTEM_TIME_SEC_TO_MSEC); + v_TIME_t curTime = vos_timer_get_system_time(); + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + smsLog(pMac, LOG1, FL("Ageout time=%lu"),ageOutTime); + while( pEntry ) + { + tmpEntry = csrLLNext(&pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK); + pResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + if((curTime - pResult->Result.BssDescriptor.nReceivedTime) > ageOutTime) + { + smsLog(pMac, LOG1, FL("age out due to time out for BSSID" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pResult->Result.BssDescriptor.bssId)); + csrScanAgeOutBss(pMac, pResult); + } + pEntry = tmpEntry; + } + csrLLUnlock(&pMac->scan.scanResultList); +} + +eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval) +{ + eHalStatus status; + + smsLog(pMac, LOG1, " csrScanStartIdleScanTimer"); + if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) && interval) + { + pMac->scan.nIdleScanTimeGap += interval; + vos_timer_stop(&pMac->scan.hTimerIdleScan); + status = vos_timer_start(&pMac->scan.hTimerIdleScan, interval/PAL_TIMER_TO_MS_UNIT); + if( !HAL_STATUS_SUCCESS(status) ) + { + smsLog(pMac, LOGE, " Fail to start Idle scan timer. status = %d interval = %d", status, interval); + //This should not happen but set the flag to restart when ready + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + } + else + { + if( pMac->scan.fScanEnable && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) ) + { + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + status = eHAL_STATUS_FAILURE; + } + + return (status); +} + + +eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac) +{ + return (vos_timer_stop(&pMac->scan.hTimerIdleScan)); +} + + +//Stop CSR from asking for IMPS, This function doesn't disable IMPS from CSR +void csrScanSuspendIMPS( tpAniSirGlobal pMac ) +{ + csrScanCancelIdleScan(pMac); +} + + +//Start CSR from asking for IMPS. This function doesn't trigger CSR to request entering IMPS +//because IMPS maybe disabled. +void csrScanResumeIMPS( tpAniSirGlobal pMac ) +{ + csrScanStartIdleScan( pMac ); +} + + +void csrScanIMPSCallback(void *callbackContext, eHalStatus status) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( callbackContext ); + + if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + { + if(pMac->roam.configParam.IsIdleScanEnabled) + { + if(HAL_STATUS_SUCCESS(status)) + { + if(csrIsAllSessionDisconnected(pMac) && !csrIsRoamCommandWaiting(pMac)) + { + smsLog(pMac, LOGW, FL("starts idle mode full scan")); + csrScanAllChannels(pMac, eCSR_SCAN_IDLE_MODE_SCAN); + } + else + { + smsLog(pMac, LOGW, FL("cannot start idle mode full scan")); + //even though we are in timer handle, calling stop timer will make sure the timer + //doesn't get to restart. + csrScanStopIdleScanTimer(pMac); + } + } + else + { + smsLog(pMac, LOGE, FL("sees not success status (%d)"), status); + } + } + else + {//we might need another flag to check if CSR needs to request imps at all + + tANI_U32 nTime = 0; + + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime))) + { + csrScanStartIdleScanTimer(pMac, nTime); + } + } + } +} + + +//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for +//idle scan timer interval +//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan +eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval) +{ + eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE; + + //Do not trigger IMPS in case of concurrency + if (vos_concurrent_open_sessions_running() && + csrIsAnySessionInConnectState(pMac)) + { + smsLog( pMac, LOG1, FL("Cannot request IMPS because Concurrent Sessions Running") ); + return (status); + } + + if(pTimeInterval) + { + *pTimeInterval = 0; + } + + smsLog(pMac, LOG3, FL("called")); + if( smeCommandPending( pMac ) ) + { + smsLog( pMac, LOG1, FL(" Cannot request IMPS because command pending") ); + //Not to enter IMPS because more work to do + if(pTimeInterval) + { + *pTimeInterval = 0; + } + //restart when ready + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + + return (status); + } + if (IsPmcImpsReqFailed (pMac)) + { + if(pTimeInterval) + { + *pTimeInterval = 1000000; //usec + } + //restart when ready + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + + return status; + } + + if ( !pMac->deferImps && pMac->fDeferIMPSTime ) + { + smsLog( pMac, LOG1, FL("Defer IMPS for %dms as command processed"), + pMac->fDeferIMPSTime); + if(pTimeInterval) + { + *pTimeInterval = pMac->fDeferIMPSTime * 1000; //usec + } + pMac->deferImps = eANI_BOOLEAN_TRUE; + return status; + } + + if((pMac->scan.fScanEnable) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + /*&& pMac->roam.configParam.impsSleepTime*/) + { + //Stop get result timer because idle scan gets scan result out of PE + csrScanStopGetResultTimer(pMac); + if(pTimeInterval) + { + *pTimeInterval = pMac->roam.configParam.impsSleepTime; + } + //pmcRequestImps take a period in millisecond unit. + status = pmcRequestImps(pMac, pMac->roam.configParam.impsSleepTime / PAL_TIMER_TO_MS_UNIT, csrScanIMPSCallback, pMac); + if(!HAL_STATUS_SUCCESS(status)) + { + if(eHAL_STATUS_PMC_ALREADY_IN_IMPS != status) + { + //Do restart the timer if CSR thinks it cannot do IMPS + if( !csrCheckPSReady( pMac ) ) + { + if(pTimeInterval) + { + *pTimeInterval = 0; + } + //Set the restart flag to true because that idle scan + //can be restarted even though the timer will not be running + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + } + else + { + //For not now, we do a quicker retry + if(pTimeInterval) + { + *pTimeInterval = CSR_IDLE_SCAN_WAIT_TIME; + } + } + smsLog(pMac, LOGW, FL("call pmcRequestImps and it returns status code (%d)"), status); + } + else + { + smsLog(pMac, LOGW, FL("already in IMPS")); + //Since CSR is the only module to request for IMPS. If it is already in IMPS, CSR assumes + //the callback will be called in the future. Should not happen though. + status = eHAL_STATUS_SUCCESS; + pMac->scan.nIdleScanTimeGap = 0; + } + } + else + { + //requested so let's reset the value + pMac->scan.nIdleScanTimeGap = 0; + } + } + + return (status); +} + + +eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_CSR_WRONG_STATE; + tANI_U32 nTime = 0; + + smsLog(pMac, LOGW, FL("called")); + if(pMac->roam.configParam.IsIdleScanEnabled) + { + //stop bg scan first + csrScanBGScanAbort(pMac); + //Stop get result timer because idle scan gets scan result out of PE + csrScanStopGetResultTimer(pMac); + } + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE; + status = csrScanTriggerIdleScan(pMac, &nTime); + if(!HAL_STATUS_SUCCESS(status)) + { + csrScanStartIdleScanTimer(pMac, nTime); + } + + return (status); +} + + +void csrScanCancelIdleScan(tpAniSirGlobal pMac) +{ + if(eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + { + if (vos_concurrent_open_sessions_running()) { + return; + } + smsLog(pMac, LOG1, " csrScanCancelIdleScan"); + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE; + //Set the restart flag in case later on it is uncancelled + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + csrScanStopIdleScanTimer(pMac); + csrScanRemoveNotRoamingScanCommand(pMac); + } +} + + +void csrScanIdleScanTimerHandler(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + eHalStatus status; + tANI_U32 nTime = 0; + + smsLog(pMac, LOGW, " csrScanIdleScanTimerHandler called "); + pmcResetImpsFailStatus (pMac); + status = csrScanTriggerIdleScan(pMac, &nTime); + if(!HAL_STATUS_SUCCESS(status) && (eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan)) + { + //Check whether it is time to actually do an idle scan + if(pMac->scan.nIdleScanTimeGap >= pMac->roam.configParam.impsSleepTime) + { + pMac->scan.nIdleScanTimeGap = 0; + csrScanIMPSCallback(pMac, eHAL_STATUS_SUCCESS); + } + else + { + csrScanStartIdleScanTimer(pMac, nTime); + } + } + if(pMac->deferImps) + { + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + pMac->deferImps = eANI_BOOLEAN_FALSE; + } +} + + + + +tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry, *pEntryTmp; + tSmeCmd *pCommand; + tDblLinkList localList; + tDblLinkList *pCmdList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return fRet; + } + if (!pMac->fScanOffload) + pCmdList = &pMac->sme.smeCmdPendingList; + else + pCmdList = &pMac->sme.smeScanCmdPendingList; + + csrLLLock(pCmdList); + pEntry = csrLLPeekHead(pCmdList, LL_ACCESS_NOLOCK); + while(pEntry) + { + pEntryTmp = csrLLNext(pCmdList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandScan == pCommand->command ) + { + switch( pCommand->u.scanCmd.reason ) + { + case eCsrScanIdleScan: + if( csrLLRemoveEntry(pCmdList, pEntry, LL_ACCESS_NOLOCK) ) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + fRet = eANI_BOOLEAN_TRUE; + break; + + default: + break; + } //switch + } + pEntry = pEntryTmp; + } + + csrLLUnlock(pCmdList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + csrReleaseCommandScan( pMac, pCommand ); + } + + csrLLClose(&localList); + + return (fRet); +} + + +tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tListElem *pEntry, *pEntryTmp; + tSmeCmd *pCommand; + tDblLinkList localList; + tDblLinkList *pCmdList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return fRet; + } + + if (!pMac->fScanOffload) + pCmdList = &pMac->sme.smeCmdPendingList; + else + pCmdList = &pMac->sme.smeScanCmdPendingList; + + csrLLLock(pCmdList); + pEntry = csrLLPeekHead(pCmdList, LL_ACCESS_NOLOCK); + while(pEntry) + { + pEntryTmp = csrLLNext(pCmdList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( (eSmeCommandScan == pCommand->command) && (sessionId == pCommand->sessionId) ) + { + switch(pCommand->u.scanCmd.reason) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eCsrScanGetLfrResult: +#endif + case eCsrScanGetResult: + case eCsrScanSetBGScanParam: + case eCsrScanBGScanAbort: + case eCsrScanBGScanEnable: + case eCsrScanGetScanChnInfo: + break; + default: + smsLog (pMac, LOGW, "%s: -------- abort scan command reason = %d", + __func__, pCommand->u.scanCmd.reason); + //The rest are fresh scan requests + if( csrLLRemoveEntry(pCmdList, pEntry, LL_ACCESS_NOLOCK) ) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + fRet = eANI_BOOLEAN_TRUE; + break; + } + } + pEntry = pEntryTmp; + } + + csrLLUnlock(pCmdList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if (pCommand->u.scanCmd.callback) + { + /* User scan request is pending, + * send response with status eCSR_SCAN_ABORT*/ + pCommand->u.scanCmd.callback(pMac, + pCommand->u.scanCmd.pContext, + pCommand->u.scanCmd.scanID, + eCSR_SCAN_ABORT); + } + csrReleaseCommandScan( pMac, pCommand ); + } + csrLLClose(&localList); + + return (fRet); +} + + +void csrReleaseScanCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus) +{ + eCsrScanReason reason = pCommand->u.scanCmd.reason; + tANI_BOOLEAN status; + + if (!pMac->fScanOffload) + { + tANI_U32 i; + for(i = 0; i < CSR_ROAM_SESSION_MAX; i++) + csrRoamStateChange(pMac, + pMac->roam.prev_state[i], i); + } + else + { + csrRoamStateChange(pMac, + pMac->roam.prev_state[pCommand->sessionId], + pCommand->sessionId); + } + + csrScanCallCallback(pMac, pCommand, scanStatus); + + smsLog(pMac, LOG3, " Remove Scan command reason = %d", reason); + if (pMac->fScanOffload) + { + status = csrLLRemoveEntry(&pMac->sme.smeScanCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK); + } + else + { + status = csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK); + } + + if(status) + { + csrReleaseCommandScan( pMac, pCommand ); + } + else + { + smsLog(pMac, LOGE, + " ********csrReleaseScanCommand cannot release command reason %d", + pCommand->u.scanCmd.reason ); + } +} + + +eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " pMac->scan.NumPmkidCandidate = %d", pSession->NumPmkidCandidate); + csrResetPMKIDCandidateList(pMac, sessionId); + if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile) + { + tCsrScanResultFilter *pScanFilter; + tCsrScanResultInfo *pScanResult; + tScanResultHandle hBSSList; + tANI_U32 nItems = *pNumItems; + + *pNumItems = 0; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + //Here is the profile we need to connect to + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumPmkidCandidate < nItems)) + { + //NumPmkidCandidate adds up here + csrProcessBSSDescForPMKIDList(pMac, &pScanResult->BssDescriptor, + (tDot11fBeaconIEs *)( pScanResult->pvIes )); + } + if(pSession->NumPmkidCandidate) + { + *pNumItems = pSession->NumPmkidCandidate; + vos_mem_copy(pPmkidList, pSession->PmkidCandidateInfo, + pSession->NumPmkidCandidate * sizeof(tPmkidCandidateInfo)); + } + csrScanResultPurge(pMac, hBSSList); + }//Have scan result + csrFreeScanFilter(pMac, pScanFilter); + } + vos_mem_free(pScanFilter); + } + } + + return (status); +} + + + +#ifdef FEATURE_WLAN_WAPI +eHalStatus csrScanGetBKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return eHAL_STATUS_FAILURE; + } + + smsLog(pMac, LOGW, " pMac->scan.NumBkidCandidate = %d", pSession->NumBkidCandidate); + csrResetBKIDCandidateList(pMac, sessionId); + if(csrIsConnStateConnected(pMac, sessionId) && pSession->pCurRoamProfile) + { + tCsrScanResultFilter *pScanFilter; + tCsrScanResultInfo *pScanResult; + tScanResultHandle hBSSList; + tANI_U32 nItems = *pNumItems; + *pNumItems = 0; + pScanFilter = vos_mem_malloc(sizeof(tCsrScanResultFilter)); + if ( NULL == pScanFilter ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); + //Here is the profile we need to connect to + status = csrRoamPrepareFilterFromProfile(pMac, pSession->pCurRoamProfile, pScanFilter); + if(HAL_STATUS_SUCCESS(status)) + { + status = csrScanGetResult(pMac, pScanFilter, &hBSSList); + if(HAL_STATUS_SUCCESS(status)) + { + while(((pScanResult = csrScanResultGetNext(pMac, hBSSList)) != NULL) && ( pSession->NumBkidCandidate < nItems)) + { + //pMac->scan.NumBkidCandidate adds up here + csrProcessBSSDescForBKIDList(pMac, &pScanResult->BssDescriptor, + (tDot11fBeaconIEs *)( pScanResult->pvIes )); + + } + if(pSession->NumBkidCandidate) + { + *pNumItems = pSession->NumBkidCandidate; + vos_mem_copy(pBkidList, pSession->BkidCandidateInfo, pSession->NumBkidCandidate * sizeof(tBkidCandidateInfo)); + } + csrScanResultPurge(pMac, hBSSList); + }//Have scan result + } + vos_mem_free(pScanFilter); + } + } + + return (status); +} +#endif /* FEATURE_WLAN_WAPI */ + +/** + * csr_scan_request_set_chan_time() - Populate max and min + * channel time in Scan request + * @pMac - pointer to mac context + * @pScanCmd - pointer to the Scan command + * + * Return - None + */ +#ifndef QCA_WIFI_ISOC +static void csr_scan_request_set_chan_time(tpAniSirGlobal pMac, + tSmeCmd *pScanCmd) +{ + if (pMac->roam.neighborRoamInfo.handoffReqInfo.src + == FASTREASSOC) { + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime + = MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime + = MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL_FASTREASSOC; + pMac->roam.neighborRoamInfo.handoffReqInfo.src = 0; + } else { + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime + = MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime + = MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL; + } +} +#else +static void csr_scan_request_set_chan_time(tpAniSirGlobal pMac, + tSmeCmd *pScanCmd) +{ + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime + = MAX_ACTIVE_SCAN_FOR_ONE_CHANNEL; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime + = MIN_ACTIVE_SCAN_FOR_ONE_CHANNEL; +} +#endif + +/** + * csr_ssid_scan_done_callback() - Callback to indicate + * scan is done for ssid scan + * @halHandle: handle to hal + * @context: SSID scan context + * @scanId: Scan id for the scheduled scan + * @status: scan done status + * + * Return - eHalStatus + */ +static eHalStatus csr_ssid_scan_done_callback(tHalHandle halHandle, + void *context, + tANI_U32 scanId, + eCsrScanStatus status) +{ + struct csr_scan_for_ssid_context *scan_context = + (struct csr_scan_for_ssid_context *)context; + + if (NULL == scan_context) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("scan for ssid context not found")); + return eHAL_STATUS_FAILURE; + } + + if (eCSR_SCAN_ABORT == status) + csrRoamCallCallback(scan_context->pMac, scan_context->sessionId, + NULL, scan_context->roamId, + eCSR_ROAM_ASSOCIATION_FAILURE, + eCSR_ROAM_RESULT_SCAN_FOR_SSID_FAILURE); + vos_mem_free(scan_context); + return eHAL_STATUS_SUCCESS; +} + +//This function is usually used for BSSs that suppresses SSID so the profile +//shall have one and only one SSID +eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pScanCmd = NULL; + tANI_U8 bAddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tANI_U8 index = 0; + tANI_U32 numSsid = pProfile->SSIDs.numOfSSIDs; + struct csr_scan_for_ssid_context *context; + + smsLog(pMac, LOG2, FL("called")); + //For WDS, we use the index 0. There must be at least one in there + if( CSR_IS_WDS_STA( pProfile ) && numSsid ) + { + numSsid = 1; + } + if(pMac->scan.fScanEnable && ( numSsid == 1 ) ) + { + do + { + pScanCmd = csrGetCommandBuffer(pMac); + if(!pScanCmd) + { + smsLog(pMac, LOGE, FL("failed to allocate command buffer")); + break; + } + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + pScanCmd->u.scanCmd.pToRoamProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pScanCmd->u.scanCmd.pToRoamProfile ) + { + status = eHAL_STATUS_FAILURE; + } + else + { + status = csrRoamCopyProfile(pMac, pScanCmd->u.scanCmd.pToRoamProfile, pProfile); + } + context = vos_mem_malloc(sizeof(*context)); + if (NULL == context) + { + smsLog(pMac, LOGE, + "Failed to allocate memory for ssid scan context"); + status = eHAL_STATUS_FAILED_ALLOC; + } + if(!HAL_STATUS_SUCCESS(status)) + break; + context->pMac = pMac; + context->sessionId = sessionId; + context->roamId = roamId; + pScanCmd->u.scanCmd.roamId = roamId; + pScanCmd->command = eSmeCommandScan; + pScanCmd->sessionId = (tANI_U8)sessionId; + pScanCmd->u.scanCmd.callback = csr_ssid_scan_done_callback; + pScanCmd->u.scanCmd.pContext = context; + pScanCmd->u.scanCmd.reason = eCsrScanForSsid;//Need to check: might need a new reason for SSID scan for LFR during multisession with p2p + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + vos_mem_set(&pScanCmd->u.scanCmd.u.scanRequest, sizeof(tCsrScanRequest), 0); + pScanCmd->u.scanCmd.u.scanRequest.scanType = eSIR_ACTIVE_SCAN; + pScanCmd->u.scanCmd.u.scanRequest.BSSType = pProfile->BSSType; + // To avoid 11b rate in probe request Set p2pSearch flag as 1 for P2P Client Mode + if(VOS_P2P_CLIENT_MODE == pProfile->csrPersona) + { + pScanCmd->u.scanCmd.u.scanRequest.p2pSearch = 1; + } + if(pProfile->nAddIEScanLength) + { + pScanCmd->u.scanCmd.u.scanRequest.pIEField = vos_mem_malloc( + pProfile->nAddIEScanLength); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.pIEField ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + vos_mem_set(pScanCmd->u.scanCmd.u.scanRequest.pIEField, + pProfile->nAddIEScanLength, 0); + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.pIEField, + pProfile->addIEScan, pProfile->nAddIEScanLength); + pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = pProfile->nAddIEScanLength; + } + else + { + smsLog(pMac, LOGE, "No memory for scanning IE fields"); + } + } //Allocate memory for IE field + else + { + pScanCmd->u.scanCmd.u.scanRequest.uIEFieldLen = 0; + } + /* For one channel be good enpugh time to receive beacon atleast */ + if( 1 == pProfile->ChannelInfo.numOfChannels ) + { + csr_scan_request_set_chan_time(pMac, pScanCmd); + } else { + pScanCmd->u.scanCmd.u.scanRequest.maxChnTime = + pMac->roam.configParam.nActiveMaxChnTime; + pScanCmd->u.scanCmd.u.scanRequest.minChnTime = + pMac->roam.configParam.nActiveMinChnTime; + } + pScanCmd->u.scanCmd.u.scanRequest.max_chntime_btc_esco = + pMac->roam.configParam.max_chntime_btc_esco; + pScanCmd->u.scanCmd.u.scanRequest.min_chntime_btc_esco = + pMac->roam.configParam.min_chntime_btc_esco; + if(pProfile->BSSIDs.numOfBSSIDs == 1) + { + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.bssid, + pProfile->BSSIDs.bssid, sizeof(tCsrBssid)); + } + else + { + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.bssid, bAddr, 6); + } + if(pProfile->ChannelInfo.numOfChannels) + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList = vos_mem_malloc( + sizeof(*pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList) + * pProfile->ChannelInfo.numOfChannels); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0; + if(HAL_STATUS_SUCCESS(status)) + { + csrRoamIsChannelValid(pMac, pProfile->ChannelInfo.ChannelList[0]); + for(index = 0; index < pProfile->ChannelInfo.numOfChannels; index++) + { + if(csrRoamIsValidChannel(pMac, pProfile->ChannelInfo.ChannelList[index])) + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.ChannelList[pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels] + = pProfile->ChannelInfo.ChannelList[index]; + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels++; + } + else + { + smsLog(pMac, LOGW, FL("process a channel (%d) that is invalid"), pProfile->ChannelInfo.ChannelList[index]); + } + + } + } + else + { + break; + } + + } + else + { + pScanCmd->u.scanCmd.u.scanRequest.ChannelInfo.numOfChannels = 0; + } + if(pProfile->SSIDs.numOfSSIDs) + { + pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList = vos_mem_malloc( + pProfile->SSIDs.numOfSSIDs * sizeof(tCsrSSIDInfo)); + if ( NULL == pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + pScanCmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs = 1; + vos_mem_copy(pScanCmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList, + pProfile->SSIDs.SSIDList, sizeof(tCsrSSIDInfo)); + } + //Start process the command + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + }while(0); + if(!HAL_STATUS_SUCCESS(status)) + { + if(pScanCmd) + { + csrReleaseCommandScan(pMac, pScanCmd); + //TODO:free the memory that is allocated in this function + } + if(notify) + { + csrRoamCallCallback(pMac, sessionId, NULL, roamId, eCSR_ROAM_FAILED, eCSR_ROAM_RESULT_FAILURE); + } + } + }//valid + else + { + smsLog(pMac, LOGE, FL("cannot scan because scanEnable (%d) or numSSID (%d) is invalid"), + pMac->scan.fScanEnable, pProfile->SSIDs.numOfSSIDs); + } + + return (status); +} + + +//Issue a scan base on the new capability infomation +//This should only happen when the associated AP changes its capability. +//After this scan is done, CSR reroams base on the new scan results +eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tSmeCmd *pScanCmd = NULL; + + if(pNewCaps) + { + do + { + pScanCmd = csrGetCommandBuffer(pMac); + if(!pScanCmd) + { + smsLog(pMac, LOGE, FL("failed to allocate command buffer")); + status = eHAL_STATUS_RESOURCES; + break; + } + vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); + status = eHAL_STATUS_SUCCESS; + pScanCmd->u.scanCmd.roamId = 0; + pScanCmd->command = eSmeCommandScan; + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + pScanCmd->u.scanCmd.reason = eCsrScanForCapsChange; + pScanCmd->u.scanCmd.scanID = pMac->scan.nextScanID++; //let it wrap around + status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); + if( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL(" fail to send message status = %d"), status ); + break; + } + }while(0); + if(!HAL_STATUS_SUCCESS(status)) + { + if(pScanCmd) + { + csrReleaseCommandScan(pMac, pScanCmd); + } + } + } + + return (status); +} + + + +void csrInitBGScanChannelList(tpAniSirGlobal pMac) +{ + tANI_U32 len = CSR_MIN(sizeof(pMac->roam.validChannelList), sizeof(pMac->scan.bgScanChannelList)); + + vos_mem_set(pMac->scan.bgScanChannelList, len, 0); + pMac->scan.numBGScanChannel = 0; + + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len))) + { + pMac->roam.numValidChannels = len; + pMac->scan.numBGScanChannel = (tANI_U8)CSR_MIN(len, WNI_CFG_BG_SCAN_CHANNEL_LIST_LEN); + vos_mem_copy(pMac->scan.bgScanChannelList, pMac->roam.validChannelList, + pMac->scan.numBGScanChannel); + csrSetBGScanChannelList(pMac, pMac->scan.bgScanChannelList, pMac->scan.numBGScanChannel); + } +} + + +//This function return TRUE if background scan channel list is adjusted. +//this function will only shrink the background scan channel list +tANI_BOOLEAN csrAdjustBGScanChannelList(tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels, + tANI_U8 *pAdjustChannels, tANI_U8 *pNumAdjustChannels) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + tANI_U8 i, j, count = *pNumAdjustChannels; + + i = 0; + while(i < count) + { + for(j = 0; j < NumChannels; j++) + { + if(pChannelList[j] == pAdjustChannels[i]) + break; + } + if(j == NumChannels) + { + //This channel is not in the list, remove it + fRet = eANI_BOOLEAN_TRUE; + count--; + if(count - i) + { + vos_mem_copy(&pAdjustChannels[i], &pAdjustChannels[i+1], count - i); + } + else + { + //already remove the last one. Done. + break; + } + } + else + { + i++; + } + }//while(iscan.baseChannels.channelList, &n, NULL, NULL ); + if( HAL_STATUS_SUCCESS(status) ) + { + pMac->scan.baseChannels.numChannels = (tANI_U8)n; + } + else + { + smsLog( pMac, LOGE, FL(" failed") ); + pMac->scan.baseChannels.numChannels = 0; + } + + return ( status ); +} + +//This function use the input pChannelList to validate the current saved channel list +eHalStatus csrSetBGScanChannelList( tpAniSirGlobal pMac, tANI_U8 *pAdjustChannels, tANI_U8 NumAdjustChannels) +{ + tANI_U32 dataLen = sizeof( tANI_U8 ) * NumAdjustChannels; + + return (ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pAdjustChannels, dataLen, NULL, eANI_BOOLEAN_FALSE)); +} + + +void csrSetCfgValidChannelList( tpAniSirGlobal pMac, tANI_U8 *pChannelList, tANI_U8 NumChannels ) +{ + tANI_U32 dataLen = sizeof( tANI_U8 ) * NumChannels; + eHalStatus status; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: dump valid channel list(NumChannels(%d))", + __func__,NumChannels); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + pChannelList, NumChannels); + + ccmCfgSetStr(pMac, WNI_CFG_VALID_CHANNEL_LIST, pChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE); +#ifdef QCA_WIFI_2_0 + if (pMac->fScanOffload) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Scan offload is enabled, update default chan list"); + status = csrUpdateChannelList(pMac); + } +#else + status = csrUpdateChannelList(pMac); +#endif + + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to update the supported channel list"); + } + return; +} + + + +/* + * The Tx power limits are saved in the cfg for future usage. + */ +void csrSaveTxPowerToCfg( tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 cfgId ) +{ + tListElem *pEntry; + tANI_U32 cbLen = 0, dataLen; + tCsrChannelPowerInfo *pChannelSet; + tANI_U32 idx; + tSirMacChanInfo *pChannelPowerSet; + tANI_U8 *pBuf = NULL; + + //allocate maximum space for all channels + dataLen = WNI_CFG_VALID_CHANNEL_LIST_LEN * sizeof(tSirMacChanInfo); + if ( (pBuf = vos_mem_malloc(dataLen)) != NULL ) + { + vos_mem_set(pBuf, dataLen, 0); + pChannelPowerSet = (tSirMacChanInfo *)(pBuf); + + pEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK ); + // write the tuples (startChan, numChan, txPower) for each channel found in the channel power list. + while( pEntry ) + { + pChannelSet = GET_BASE_ADDR( pEntry, tCsrChannelPowerInfo, link ); + if ( 1 != pChannelSet->interChannelOffset ) + { + // we keep the 5G channel sets internally with an interchannel offset of 4. Expand these + // to the right format... (inter channel offset of 1 is the only option for the triplets + // that 11d advertises. + if ((cbLen + (pChannelSet->numChannels * sizeof(tSirMacChanInfo))) >= dataLen) + { + // expanding this entry will overflow our allocation + smsLog(pMac, LOGE, + "%s: Buffer overflow, start %d, num %d, offset %d", + __func__, + pChannelSet->firstChannel, + pChannelSet->numChannels, + pChannelSet->interChannelOffset); + break; + } + + for( idx = 0; idx < pChannelSet->numChannels; idx++ ) + { + pChannelPowerSet->firstChanNum = (tSirMacChanNum)(pChannelSet->firstChannel + ( idx * pChannelSet->interChannelOffset )); + smsLog(pMac, LOG3, " Setting Channel Number %d", pChannelPowerSet->firstChanNum); + pChannelPowerSet->numChannels = 1; + pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap ); + smsLog(pMac, LOG3, " Setting Max Transmit Power %d", pChannelPowerSet->maxTxPower); + cbLen += sizeof( tSirMacChanInfo ); + pChannelPowerSet++; + } + } + else + { + if (cbLen >= dataLen) + { + // this entry will overflow our allocation + smsLog(pMac, LOGE, + "%s: Buffer overflow, start %d, num %d, offset %d", + __func__, + pChannelSet->firstChannel, + pChannelSet->numChannels, + pChannelSet->interChannelOffset); + break; + } + pChannelPowerSet->firstChanNum = pChannelSet->firstChannel; + smsLog(pMac, LOG3, " Setting Channel Number %d", pChannelPowerSet->firstChanNum); + pChannelPowerSet->numChannels = pChannelSet->numChannels; + pChannelPowerSet->maxTxPower = CSR_ROAM_MIN( pChannelSet->txPower, pMac->roam.configParam.nTxPowerCap ); + smsLog(pMac, LOG3, " Setting Max Transmit Power %d, nTxPower %d", pChannelPowerSet->maxTxPower,pMac->roam.configParam.nTxPowerCap ); + + + cbLen += sizeof( tSirMacChanInfo ); + pChannelPowerSet++; + } + + pEntry = csrLLNext( pList, pEntry, LL_ACCESS_LOCK ); + } + + if(cbLen) + { + ccmCfgSetStr(pMac, cfgId, (tANI_U8 *)pBuf, cbLen, NULL, eANI_BOOLEAN_FALSE); + } + vos_mem_free(pBuf); + }//Allocate memory +} + + +void csrSetCfgCountryCode( tpAniSirGlobal pMac, tANI_U8 *countryCode ) +{ + tANI_U8 cc[WNI_CFG_COUNTRY_CODE_LEN]; + ///v_REGDOMAIN_t DomainId; + + smsLog( pMac, LOG3, "Setting Country Code in Cfg from csrSetCfgCountryCode %s",countryCode ); + vos_mem_copy(cc, countryCode, WNI_CFG_COUNTRY_CODE_LEN); + + // don't program the bogus country codes that we created for Korea in the MAC. if we see + // the bogus country codes, program the MAC with the right country code. + if ( ( 'K' == countryCode[ 0 ] && '1' == countryCode[ 1 ] ) || + ( 'K' == countryCode[ 0 ] && '2' == countryCode[ 1 ] ) || + ( 'K' == countryCode[ 0 ] && '3' == countryCode[ 1 ] ) || + ( 'K' == countryCode[ 0 ] && '4' == countryCode[ 1 ] ) ) + { + // replace the alternate Korea country codes, 'K1', 'K2', .. with 'KR' for Korea + cc[ 1 ] = 'R'; + } + ccmCfgSetStr(pMac, WNI_CFG_COUNTRY_CODE, cc, WNI_CFG_COUNTRY_CODE_LEN, NULL, eANI_BOOLEAN_FALSE); + + //Need to let HALPHY know about the current domain so it can apply some + //domain-specific settings (TX filter...) + /*if(HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry(pMac, cc, &DomainId))) + { + halPhySetRegDomain(pMac, DomainId); + }*/ +} + + + +eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 len; + + if(pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN)) + { + len = *pbLen; + status = ccmCfgGetStr(pMac, WNI_CFG_COUNTRY_CODE, pBuf, &len); + if(HAL_STATUS_SUCCESS(status)) + { + *pbLen = (tANI_U8)len; + } + } + + return (status); +} + + +void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList ) +{ + tANI_U8 i, j, k; + tANI_BOOLEAN found=FALSE; + tANI_U8 *pControlList = NULL; + tANI_U32 len = WNI_CFG_SCAN_CONTROL_LIST_LEN; + tANI_U8 cfgActiveDFSChannels = 0; + tANI_U8 *cfgActiveDFSChannelLIst = NULL; + + if ( (pControlList = vos_mem_malloc(WNI_CFG_SCAN_CONTROL_LIST_LEN)) != NULL ) + { + vos_mem_set((void *)pControlList, WNI_CFG_SCAN_CONTROL_LIST_LEN, 0); + if(HAL_STATUS_SUCCESS(ccmCfgGetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, &len))) + { + for (i = 0; i < pChannelList->numChannels; i++) + { + for (j = 0; j < len; j += 2) + { + if (pControlList[j] == pChannelList->channelList[i]) + { + found = TRUE; + break; + } + } + + if (found) // insert a pair(channel#, flag) + { + pControlList[j+1] = csrGetScanType(pMac, pControlList[j]); + found = FALSE; // reset the flag + + // When DFS mode is 2, mark static channels as active + if (pMac->scan.fEnableDFSChnlScan == + DFS_CHNL_SCAN_ENABLED_ACTIVE) + { + cfgActiveDFSChannels = + pMac->roam.neighborRoamInfo.cfgParams. + channelInfo.numOfChannels; + cfgActiveDFSChannelLIst = + pMac->roam.neighborRoamInfo.cfgParams. + channelInfo.ChannelList; + if (cfgActiveDFSChannelLIst) + { + for (k=0; k < cfgActiveDFSChannels; k++) + { + if(CSR_IS_CHANNEL_DFS(cfgActiveDFSChannelLIst[k]) + && (pControlList[j] == + cfgActiveDFSChannelLIst[k])) + { + pControlList[j+1] = eSIR_ACTIVE_SCAN; + smsLog(pMac, LOG1, FL("Marked DFS ch %d" + " as active"), + cfgActiveDFSChannelLIst[k]); + } + } + } + } + } + } + smsLog(pMac, LOG1, FL("fEnableDFSChnlScan %d"), + pMac->scan.fEnableDFSChnlScan); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: dump scan control list",__func__); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + pControlList, len); + + ccmCfgSetStr(pMac, WNI_CFG_SCAN_CONTROL_LIST, pControlList, len, NULL, eANI_BOOLEAN_FALSE); + }//Successfully getting scan control list + vos_mem_free(pControlList); + }//AllocateMemory + + /* Send msg to Lim to clear DFS channel list */ + smsLog(pMac, LOG1, FL("csrClearDfsChannelList")); + csrClearDfsChannelList(pMac); +} + +//if bgPeriod is 0, background scan is disabled. It is in millisecond units +eHalStatus csrSetCfgBackgroundScanPeriod(tpAniSirGlobal pMac, tANI_U32 bgPeriod) +{ + return (ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, bgPeriod, (tCcmCfgSetCallback) csrScanCcmCfgSetCallback, eANI_BOOLEAN_FALSE)); +} + + +void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tDblLinkList *pCmdList ; + + if (!pMac->fScanOffload) + pCmdList = &pMac->sme.smeCmdActiveList; + else + pCmdList = &pMac->sme.smeScanCmdActiveList; + + pEntry = csrLLPeekHead( pCmdList, LL_ACCESS_LOCK ); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if ( eSmeCommandScan == pCommand->command ) + { + eCsrScanStatus scanStatus = (CCM_IS_RESULT_SUCCESS(result)) ? eCSR_SCAN_SUCCESS : eCSR_SCAN_FAILURE; + csrReleaseScanCommand(pMac, pCommand, scanStatus); + } + else + { + smsLog( pMac, LOGW, "CSR: Scan Completion called but SCAN command is not ACTIVE ..." ); + } + } + smeProcessPendingQueue( pMac ); +} + +eHalStatus csrProcessSetBGScanParam(tpAniSirGlobal pMac, tSmeCmd *pCommand) +{ + eHalStatus status; + tCsrBGScanRequest *pScanReq = &pCommand->u.scanCmd.u.bgScanRequest; + tANI_U32 dataLen = sizeof( tANI_U8 ) * pScanReq->ChannelInfo.numOfChannels; + + //***setcfg for background scan channel list + status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MINIMUM_CHANNEL_TIME, pScanReq->minChnTime, NULL, eANI_BOOLEAN_FALSE); + status = ccmCfgSetInt(pMac, WNI_CFG_ACTIVE_MAXIMUM_CHANNEL_TIME, pScanReq->maxChnTime, NULL, eANI_BOOLEAN_FALSE); + //Not set the background scan interval if not connected because bd scan should not be run if not connected + if(!csrIsAllSessionDisconnected(pMac)) + { + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + { + vos_log_scan_pkt_type *pScanLog = NULL; + + WLAN_VOS_DIAG_LOG_ALLOC(pScanLog, vos_log_scan_pkt_type, LOG_WLAN_SCAN_C); + if(pScanLog) + { + pScanLog->eventId = WLAN_SCAN_EVENT_HO_SCAN_REQ; + pScanLog->minChnTime = (v_U8_t)pScanReq->minChnTime; + pScanLog->maxChnTime = (v_U8_t)pScanReq->maxChnTime; + pScanLog->timeBetweenBgScan = (v_U8_t)pScanReq->scanInterval; + pScanLog->numChannel = pScanReq->ChannelInfo.numOfChannels; + if(pScanLog->numChannel && (pScanLog->numChannel < VOS_LOG_MAX_NUM_CHANNEL)) + { + vos_mem_copy(pScanLog->channels, + pScanReq->ChannelInfo.ChannelList, + pScanLog->numChannel); + } + WLAN_VOS_DIAG_LOG_REPORT(pScanLog); + } + } +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + + status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, pScanReq->scanInterval, NULL, eANI_BOOLEAN_FALSE); + } + else + { + //No need to stop aging because IDLE scan is still running + status = ccmCfgSetInt(pMac, WNI_CFG_BACKGROUND_SCAN_PERIOD, 0, NULL, eANI_BOOLEAN_FALSE); + } + + if(pScanReq->SSID.length > WNI_CFG_SSID_LEN) + { + pScanReq->SSID.length = WNI_CFG_SSID_LEN; + } + + status = ccmCfgSetStr(pMac, WNI_CFG_BG_SCAN_CHANNEL_LIST, pScanReq->ChannelInfo.ChannelList, dataLen, NULL, eANI_BOOLEAN_FALSE); + status = ccmCfgSetStr(pMac, WNI_CFG_SSID, (tANI_U8 *)pScanReq->SSID.ssId, pScanReq->SSID.length, NULL, eANI_BOOLEAN_FALSE); + + + + return (status); +} + + +tSirAbortScanStatus csrScanAbortMacScan(tpAniSirGlobal pMac, + tANI_U8 sessionId, + eCsrAbortReason reason) +{ + tSirAbortScanStatus abortScanStatus = eSIR_ABORT_ACTIVE_SCAN_LIST_EMPTY; + tSirSmeScanAbortReq *pMsg; + tANI_U16 msgLen; + tListElem *pEntry; + tSmeCmd *pCommand; + + if (!pMac->fScanOffload) + { +#ifdef WLAN_AP_STA_CONCURRENCY + csrLLLock(&pMac->scan.scanCmdPendingList); + while(NULL != + (pEntry = csrLLRemoveHead(&pMac->scan.scanCmdPendingList, + LL_ACCESS_NOLOCK))) + { + + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE); + } + csrLLUnlock(&pMac->scan.scanCmdPendingList); +#endif + + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; + csrRemoveCmdFromPendingList( pMac, &pMac->roam.roamCmdPendingList, eSmeCommandScan); + csrRemoveCmdFromPendingList( pMac, &pMac->sme.smeCmdPendingList, eSmeCommandScan); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + } + else + { + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; + csrRemoveCmdWithSessionIdFromPendingList(pMac, + sessionId, + &pMac->sme.smeScanCmdPendingList, + eSmeCommandScan); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + } + + //We need to abort scan only if we are scanning + if(NULL != pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandScan == pCommand->command && + pCommand->sessionId == sessionId) + { + msgLen = (tANI_U16)(sizeof(tSirSmeScanAbortReq)); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq")); + abortScanStatus = eSIR_ABORT_SCAN_FAILURE; + } + else + { + pCommand->u.scanCmd.abortScanIndication = eCSR_SCAN_ABORT_DEFAULT; + if(reason == eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) + { + pCommand->u.scanCmd.abortScanIndication + = eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE; + } + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + if (eHAL_STATUS_SUCCESS != palSendMBMessage(pMac->hHdd, pMsg)) + { + smsLog(pMac, LOGE, + FL("Failed to post eWNI_SME_SCAN_ABORT_IND")); + abortScanStatus = eSIR_ABORT_SCAN_FAILURE; + pCommand->u.scanCmd.abortScanIndication = 0; + } + else + { + abortScanStatus = eSIR_ABORT_ACTIVE_SCAN_LIST_NOT_EMPTY; + } + } + } + } + + return(abortScanStatus); +} + +void csrRemoveCmdWithSessionIdFromPendingList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tDblLinkList *pList, + eSmeCommandType commandType) +{ + tDblLinkList localList; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pEntryToRemove; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + if ((pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK))) + { + + /* Have to make sure we don't loop back to the head of the list, + * which will happen if the entry is NOT on the list */ + while (pEntry) + { + pEntryToRemove = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link ); + if ((pCommand->command == commandType) && + (pCommand->sessionId == sessionId)) + { + /* Remove that entry only */ + if (csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntryToRemove, + LL_ACCESS_NOLOCK); + } + } + } + } + csrLLUnlock(pList); + + while ((pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK))) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + csrAbortCommand(pMac, pCommand, eANI_BOOLEAN_FALSE); + } + + csrLLClose(&localList); +} + +void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, + eSmeCommandType commandType ) +{ + tDblLinkList localList; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pEntryToRemove; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) ) + { + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + while( pEntry ) + { + pEntryToRemove = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link ); + if ( pCommand->command == commandType ) + { + // Remove that entry only + if(csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK); + } + } + } + + + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE); + } + csrLLClose(&localList); + +} + +eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeScanAbortReq *pMsg; + tANI_U16 msgLen; + tListElem *pEntry; + tSmeCmd *pCommand; + + if (!pMac->fScanOffload) + { + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; +#ifdef WLAN_AP_STA_CONCURRENCY + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->scan.scanCmdPendingList, sessionId); +#endif + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->roam.roamCmdPendingList, sessionId); + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeCmdPendingList, sessionId); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + } + else + { + pMac->scan.fDropScanCmd = eANI_BOOLEAN_TRUE; + csrRemoveScanForSSIDFromPendingList( pMac, &pMac->sme.smeScanCmdPendingList, sessionId); + pMac->scan.fDropScanCmd = eANI_BOOLEAN_FALSE; + pEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, LL_ACCESS_LOCK); + } + + if(NULL != pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + if ( (eSmeCommandScan == pCommand->command ) && + (sessionId == pCommand->sessionId)) + { + if ( eCsrScanForSsid == pCommand->u.scanCmd.reason) + { + msgLen = (tANI_U16)(sizeof( tSirSmeScanAbortReq )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + status = eHAL_STATUS_FAILURE; + smsLog(pMac, LOGE, FL("Failed to allocate memory for SmeScanAbortReq")); + } + else + { + vos_mem_zero((void *)pMsg, msgLen); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + } + } + } + return( status ); +} + +void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId) +{ + tDblLinkList localList; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pEntryToRemove; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + if( !csrLLIsListEmpty( pList, LL_ACCESS_NOLOCK ) ) + { + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + while( pEntry ) + { + pEntryToRemove = pEntry; + pEntry = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntryToRemove, tSmeCmd, Link ); + if ( (eSmeCommandScan == pCommand->command ) && + (sessionId == pCommand->sessionId) ) + { + if ( eCsrScanForSsid == pCommand->u.scanCmd.reason) + { + // Remove that entry only + if ( csrLLRemoveEntry( pList, pEntryToRemove, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntryToRemove, LL_ACCESS_NOLOCK); + } + } + } + } + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + csrAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE); + } + csrLLClose(&localList); +} + +eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + if( !csrIsScanForRoamCommandActive( pMac ) ) + { + //Only abort the scan if it is not used for other roam/connect purpose + if (eSIR_ABORT_SCAN_FAILURE == + csrScanAbortMacScan(pMac, sessionId, eCSR_SCAN_ABORT_DEFAULT)) + { + smsLog(pMac, LOGE, FL("fail to abort scan")); + status = eHAL_STATUS_FAILURE; + } + } + + return (status); +} + + +eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + if (pMac->fScanOffload) + msgLen = (tANI_U16)(sizeof(tSirSmeGetScanChanReq)); + else + msgLen = (tANI_U16)(sizeof(tSirMbMsg)); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->type = eWNI_SME_GET_SCANNED_CHANNEL_REQ; + pMsg->msgLen = msgLen; + if (pMac->fScanOffload) + ((tSirSmeGetScanChanReq *)pMsg)->sessionId = sessionId; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return( status ); +} + +tANI_BOOLEAN csrRoamIsValidChannel( tpAniSirGlobal pMac, tANI_U8 channel ) +{ + tANI_BOOLEAN fValid = FALSE; + tANI_U32 idxValidChannels; + tANI_U32 len = pMac->roam.numValidChannels; + + for ( idxValidChannels = 0; ( idxValidChannels < len ); idxValidChannels++ ) + { + if ( channel == pMac->roam.validChannelList[ idxValidChannels ] ) + { + fValid = TRUE; + break; + } + } + + return fValid; +} + +#ifdef FEATURE_WLAN_SCAN_PNO +eHalStatus csrScanSavePreferredNetworkFound(tpAniSirGlobal pMac, + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd) +{ + v_U32_t uLen = 0; + tpSirProbeRespBeacon pParsedFrame; + tCsrScanResult *pScanResult = NULL; + tSirBssDescription *pBssDescr = NULL; + tANI_BOOLEAN fDupBss; + tDot11fBeaconIEs *pIesLocal = NULL; + tAniSSID tmpSsid; + v_TIME_t timer=0; + tpSirMacMgmtHdr macHeader = (tpSirMacMgmtHdr)pPrefNetworkFoundInd->data; + boolean bFoundonAppliedChannel = FALSE; + v_U32_t indx; + u8 channelsAllowed[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + v_U32_t numChannelsAllowed = WNI_CFG_VALID_CHANNEL_LIST_LEN; + tListElem *pEntry; + + + pParsedFrame = + (tpSirProbeRespBeacon)vos_mem_vmalloc(sizeof(tSirProbeRespBeacon)); + + if (NULL == pParsedFrame) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for frame")); + return eHAL_STATUS_RESOURCES; + } + + if ( pPrefNetworkFoundInd->frameLength <= SIR_MAC_HDR_LEN_3A ) + { + smsLog(pMac, LOGE, + FL("Not enough bytes in PNO indication probe resp frame! length=%d"), + pPrefNetworkFoundInd->frameLength); + vos_mem_vfree(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + + if (sirConvertProbeFrame2Struct(pMac, + &pPrefNetworkFoundInd->data[SIR_MAC_HDR_LEN_3A], + pPrefNetworkFoundInd->frameLength - SIR_MAC_HDR_LEN_3A, + pParsedFrame) != eSIR_SUCCESS || + !pParsedFrame->ssidPresent) + { + smsLog(pMac, LOGE, + FL("Parse error ProbeResponse, length=%d"), + pPrefNetworkFoundInd->frameLength); + vos_mem_vfree(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + //24 byte MAC header and 12 byte to ssid IE + if (pPrefNetworkFoundInd->frameLength > + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET)) + { + uLen = pPrefNetworkFoundInd->frameLength - + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET); + } + + pScanResult = vos_mem_malloc(sizeof(tCsrScanResult) + uLen); + if ( NULL == pScanResult ) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory for frame")); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_RESOURCES; + } + + vos_mem_set(pScanResult, sizeof(tCsrScanResult) + uLen, 0); + pBssDescr = &pScanResult->Result.BssDescriptor; + /** + * Length of BSS desription is without length of + * length itself and length of pointer + * that holds the next BSS description + */ + pBssDescr->length = (tANI_U16)( + ((uintptr_t)OFFSET_OF(tSirBssDescription, ieFields)) + - sizeof(pBssDescr->length) + uLen); + if (pParsedFrame->dsParamsPresent) + { + pBssDescr->channelId = pParsedFrame->channelNumber; + } + else if (pParsedFrame->HTInfo.present) + { + pBssDescr->channelId = pParsedFrame->HTInfo.primaryChannel; + } + else + { + /** + * If Probe Responce received in PNO indication does not + * contain DSParam IE or HT Info IE then add dummy channel + * to the received BSS info so that Scan result received as + * a part of PNO is updated to the supplicant. Specially + * applicable in case of AP configured in 11A only mode. + */ + if ((pMac->roam.configParam.bandCapability == eCSR_BAND_ALL) || + (pMac->roam.configParam.bandCapability == eCSR_BAND_24)) + { + pBssDescr->channelId = 1; + } + else if(pMac->roam.configParam.bandCapability == eCSR_BAND_5G) + { + pBssDescr->channelId = 36; + } + /* Restrict the logic to ignore the pno indication for invalid channel + * only if valid channel info is present in beacon/probe resp. + * If no channel info is present in beacon/probe resp, always process + * the pno indication. + */ + bFoundonAppliedChannel = TRUE; + } + + if (0 != sme_GetCfgValidChannels(pMac, channelsAllowed, &numChannelsAllowed)) + { + smsLog(pMac, LOGE, FL(" sme_GetCfgValidChannels failed ")); + csrFreeScanResultEntry(pMac, pScanResult); + vos_mem_vfree(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + /* Checking chhanelId with allowed channel list */ + for (indx = 0; indx < numChannelsAllowed; indx++) + { + if (pBssDescr->channelId == channelsAllowed[indx]) + { + bFoundonAppliedChannel = TRUE; + smsLog(pMac, LOG1, FL(" pno ind found on applied channel =%d\n "), + pBssDescr->channelId); + break; + } + } + /* Ignore PNO indication if AP is on Invalid channel. + */ + if(FALSE == bFoundonAppliedChannel) + { + smsLog(pMac, LOGW, FL(" prefered network found on invalid channel = %d"), + pBssDescr->channelId); + csrFreeScanResultEntry(pMac, pScanResult); + vos_mem_vfree(pParsedFrame); + return eHAL_STATUS_FAILURE; + } + + if ((pBssDescr->channelId > 0) && (pBssDescr->channelId < 15)) + { + int i; + // 11b or 11g packet + // 11g iff extended Rate IE is present or + // if there is an A rate in suppRate IE + for (i = 0; i < pParsedFrame->supportedRates.numRates; i++) + { + if (sirIsArate(pParsedFrame->supportedRates.rate[i] & 0x7f)) + { + pBssDescr->nwType = eSIR_11G_NW_TYPE; + break; + } + } + if (pParsedFrame->extendedRatesPresent) + { + pBssDescr->nwType = eSIR_11G_NW_TYPE; + } + } + else + { + // 11a packet + pBssDescr->nwType = eSIR_11A_NW_TYPE; + } + + pBssDescr->sinr = 0; + pBssDescr->rssi = -1 * pPrefNetworkFoundInd->rssi; + pBssDescr->beaconInterval = pParsedFrame->beaconInterval; + if (!pBssDescr->beaconInterval) + { + smsLog(pMac, LOGW, + FL("Bcn Interval is Zero , default to 100" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pBssDescr->bssId) ); + pBssDescr->beaconInterval = 100; + } + pBssDescr->timeStamp[0] = pParsedFrame->timeStamp[0]; + pBssDescr->timeStamp[1] = pParsedFrame->timeStamp[1]; + pBssDescr->capabilityInfo = *((tANI_U16 *)&pParsedFrame->capabilityInfo); + vos_mem_copy((tANI_U8 *) &pBssDescr->bssId, (tANI_U8 *) macHeader->bssId, sizeof(tSirMacAddr)); + pBssDescr->nReceivedTime = vos_timer_get_system_time(); + +#ifdef WLAN_FEATURE_VOWIFI_11R + // MobilityDomain + pBssDescr->mdie[0] = 0; + pBssDescr->mdie[1] = 0; + pBssDescr->mdie[2] = 0; + pBssDescr->mdiePresent = FALSE; + // If mdie is present in the probe resp we fill it in the bss description + if(pParsedFrame->mdiePresent) + { + pBssDescr->mdiePresent = TRUE; + pBssDescr->mdie[0] = pParsedFrame->mdie[0]; + pBssDescr->mdie[1] = pParsedFrame->mdie[1]; + pBssDescr->mdie[2] = pParsedFrame->mdie[2]; + } + smsLog(pMac, LOG1, FL("mdie=%02x%02x%02x"), + (unsigned int)pBssDescr->mdie[0], (unsigned int)pBssDescr->mdie[1], + (unsigned int)pBssDescr->mdie[2]); +#endif + + smsLog( pMac, LOG1, FL("Bssid= "MAC_ADDRESS_STR + " chan= %d, rssi = %d "), + MAC_ADDR_ARRAY(pBssDescr->bssId), + pBssDescr->channelId, + pBssDescr->rssi); + + //IEs + if (uLen) + { + vos_mem_copy(&pBssDescr->ieFields, + pPrefNetworkFoundInd->data + (SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_SSID_OFFSET), + uLen); + } + + pIesLocal = (tDot11fBeaconIEs *)( pScanResult->Result.pvIes ); + if ( !pIesLocal && + (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pScanResult->Result.BssDescriptor, &pIesLocal))) ) + { + smsLog(pMac, LOGE, FL(" Cannot parse IEs")); + csrFreeScanResultEntry(pMac, pScanResult); + vos_mem_vfree(pParsedFrame); + return eHAL_STATUS_RESOURCES; + } + + fDupBss = csrRemoveDupBssDescription( pMac, + &pScanResult->Result.BssDescriptor, pIesLocal, &tmpSsid, &timer, FALSE); + //Check whether we have reach out limit + if ( CSR_SCAN_IS_OVER_BSS_LIMIT(pMac) ) + { + //Limit reach + smsLog(pMac, LOGE, FL(" BSS limit reached")); + //Free the resources + if( (pScanResult->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + csrFreeScanResultEntry(pMac, pScanResult); + vos_mem_free(pParsedFrame); + return eHAL_STATUS_RESOURCES; + } + + if ((macHeader->fc.type == SIR_MAC_MGMT_FRAME) && + (macHeader->fc.subType == SIR_MAC_MGMT_PROBE_RSP)) + { + pScanResult->Result.BssDescriptor.fProbeRsp = 1; + } + //Add to scan cache + csrScanAddResult(pMac, pScanResult, pIesLocal); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_LOCK ); + if( (pScanResult->Result.pvIes == NULL) && pIesLocal ) + { + vos_mem_free(pIesLocal); + } + + vos_mem_vfree(pParsedFrame); + + return eHAL_STATUS_SUCCESS; +} +#endif //FEATURE_WLAN_SCAN_PNO + +#ifdef FEATURE_WLAN_LFR +void csrInitOccupiedChannelsList(tpAniSirGlobal pMac) +{ + tListElem *pEntry = NULL; + tCsrScanResult *pBssDesc = NULL; + tDot11fBeaconIEs *pIes = NULL; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + smsLog(pMac, LOG1, FL("%s: Ini file contains neighbor scan channel list," + " hence NO need to build occupied channel list (numChannels = %d)"), + __func__, pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + return; + } + + if (!csrNeighborRoamIsNewConnectedProfile(pMac)) + { + smsLog(pMac, LOG2, FL("%s: donot flush occupied list since current roam profile" + " matches previous (numChannels = %d)"), + __func__, pMac->scan.occupiedChannels.numChannels); + return; + } + + /* Empty occupied channels here */ + pMac->scan.occupiedChannels.numChannels = 0; + + csrLLLock(&pMac->scan.scanResultList); + pEntry = csrLLPeekHead( &pMac->scan.scanResultList, LL_ACCESS_NOLOCK ); + while( pEntry ) + { + pBssDesc = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = (tDot11fBeaconIEs *)( pBssDesc->Result.pvIes ); + + //At this time, pBssDescription->Result.pvIes may be NULL + if( !pIes && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + &pBssDesc->Result.BssDescriptor, &pIes))) ) + { + continue; + } + + csrScanAddToOccupiedChannels(pMac, pBssDesc, &pMac->scan.occupiedChannels, pIes); + + /* + * Free the memory allocated for pIes in csrGetParsedBssDescriptionIEs + */ + if( (pBssDesc->Result.pvIes == NULL) && pIes ) + { + vos_mem_free(pIes); + } + + pEntry = csrLLNext( &pMac->scan.scanResultList, pEntry, LL_ACCESS_NOLOCK ); + }//while + csrLLUnlock(&pMac->scan.scanResultList); + +} +#endif + +eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrBssid bssid, tANI_U8 channel) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tDot11fBeaconIEs *pNewIes = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tSirBssDescription *pNewBssDescriptor = NULL; + tANI_U32 size = 0; + + if(NULL == pSession) + { + status = eHAL_STATUS_FAILURE; + return status; + } + smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: Current bssid::" + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(pSession->pConnectBssDesc->bssId)); + smsLog(pMac, LOG2, FL("csrScanCreateEntryInScanCache: My bssid::" + MAC_ADDRESS_STR" channel %d"), + MAC_ADDR_ARRAY(bssid), channel); + + do + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pSession->pConnectBssDesc, &pNewIes))) + { + smsLog(pMac, LOGE, FL("%s: Failed to parse IEs"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + size = pSession->pConnectBssDesc->length + sizeof(pSession->pConnectBssDesc->length); + if (size) + { + pNewBssDescriptor = vos_mem_malloc(size); + if ( NULL == pNewBssDescriptor ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (HAL_STATUS_SUCCESS(status)) + { + vos_mem_copy(pNewBssDescriptor, pSession->pConnectBssDesc, size); + } + else + { + smsLog(pMac, LOGE, FL("%s: memory allocation failed"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + //change the BSSID & channel as passed + vos_mem_copy(pNewBssDescriptor->bssId, bssid, sizeof(tSirMacAddr)); + pNewBssDescriptor->channelId = channel; + if(NULL == csrScanAppendBssDescription( pMac, pNewBssDescriptor, pNewIes, TRUE )) + { + smsLog(pMac, LOGE, FL("%s: csrScanAppendBssDescription failed"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, FL("%s: length of bss descriptor is 0"), + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + smsLog(pMac, LOGE, FL("%s: entry successfully added in scan cache"), + __func__); + }while(0); + + if(pNewIes) + { + vos_mem_free(pNewIes); + } + if(pNewBssDescriptor) + { + vos_mem_free(pNewBssDescriptor); + } + return status; +} + +#ifdef FEATURE_WLAN_ESE +// Update the TSF with the difference in system time +void UpdateCCKMTSF(tANI_U32 *timeStamp0, tANI_U32 *timeStamp1, tANI_U32 *incr) +{ + tANI_U64 timeStamp64 = ((tANI_U64)*timeStamp1 << 32) | (*timeStamp0); + + timeStamp64 = (tANI_U64)(timeStamp64 + (tANI_U64)*incr); + *timeStamp0 = (tANI_U32)(timeStamp64 & 0xffffffff); + *timeStamp1 = (tANI_U32)((timeStamp64 >> 32) & 0xffffffff); +} +#endif + +void csrValidateScanChannels(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, + tCsrScanRequest *pSrcReq, tANI_U32 *new_index, tANI_U8 ch144_support) +{ + + int index; + for ( index = 0; index < pSrcReq->ChannelInfo. + numOfChannels ; index++ ) + { + /* Skip CH 144 if firmware support not present */ + if (pSrcReq->ChannelInfo.ChannelList[index] == 144 && !ch144_support) + continue; + + /* Allow scan on valid channels only. + */ + if ( ( csrRoamIsValidChannel(pMac, + pSrcReq->ChannelInfo.ChannelList[index]) ) ) + { + if( ((pSrcReq->skipDfsChnlInP2pSearch || + (pMac->scan.fEnableDFSChnlScan == + DFS_CHNL_SCAN_DISABLED)) && + (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState( + pSrcReq->ChannelInfo.ChannelList[index])) && + (pSrcReq->ChannelInfo.numOfChannels > 1)) +#ifdef FEATURE_WLAN_LFR + /* + * If LFR is requesting a contiguous scan + * (i.e. numOfChannels > 1), then ignore + * DFS channels. + * TODO: vos_nv_getChannelEnabledState is returning + * 120, 124 and 128 as non-DFS channels. Hence, the + * use of direct check for channels below. + */ + || ((eCSR_SCAN_HO_BG_SCAN == pSrcReq->requestType) && + (pSrcReq->ChannelInfo.numOfChannels > 1) && + (CSR_IS_CHANNEL_DFS( + pSrcReq->ChannelInfo.ChannelList[index])) && + !pMac->roam.configParam.allowDFSChannelRoam) +#endif + ) + { +#ifdef FEATURE_WLAN_LFR + smsLog(pMac, LOG1, + FL(" reqType=%s (%d), numOfChannels=%d," + " ignoring DFS channel:%d"), + sme_requestTypetoString(pSrcReq->requestType), + pSrcReq->requestType, + pSrcReq->ChannelInfo.numOfChannels, + pSrcReq->ChannelInfo.ChannelList[index]); +#endif + continue; + } + + pDstReq->ChannelInfo.ChannelList[*new_index] = + pSrcReq->ChannelInfo.ChannelList[index]; + (*new_index)++; + } + } +} diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c b/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c new file mode 100644 index 000000000000..c773cc9a1280 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrCmdProcess.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- + + ---------------------------------------------------------------------------* +*/ + +#include "aniGlobal.h" + +#include "palApi.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "smsDebug.h" +#include "macTrace.h" + + + +eHalStatus csrMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirSmeRsp *pSmeRsp = (tSirSmeRsp *)pMsgBuf; + + smsLog(pMac, LOG2, FL("Message %d[0x%04X] received in curState %s" + "and substate %s"), + pSmeRsp->messageType, pSmeRsp->messageType, + macTraceGetcsrRoamState(pMac->roam.curState[pSmeRsp->sessionId]), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[pSmeRsp->sessionId])); + + // Process the message based on the state of the roaming states... + +#if defined( ANI_RTT_DEBUG ) + if(!pAdapter->fRttModeEnabled) + { +#endif//RTT + switch (pMac->roam.curState[pSmeRsp->sessionId]) + { + case eCSR_ROAMING_STATE_SCANNING: + { + //Are we in scan state +#if defined( ANI_EMUL_ASSOC ) + emulScanningStateMsgProcessor( pAdapter, pMBBufHdr ); +#else + status = csrScanningStateMsgProcessor(pMac, pMsgBuf); +#endif + break; + } + + case eCSR_ROAMING_STATE_JOINED: + { + //are we in joined state + csrRoamJoinedStateMsgProcessor( pMac, pMsgBuf ); + break; + } + + case eCSR_ROAMING_STATE_JOINING: + { + //are we in roaming states +#if defined( ANI_EMUL_ASSOC ) + emulRoamingStateMsgProcessor( pAdapter, pMBBufHdr ); +#endif + csrRoamingStateMsgProcessor( pMac, pMsgBuf ); + break; + } + + //For all other messages, we ignore it + default: + { + /*To work-around an issue where checking for set/remove key base on connection state is no longer + * workable due to failure or finding the condition meets both SAP and infra/IBSS requirement. + */ + if( (eWNI_SME_SETCONTEXT_RSP == pSmeRsp->messageType) || + (eWNI_SME_REMOVEKEY_RSP == pSmeRsp->messageType) || + (pSmeRsp->messageType == eWNI_SME_FT_PRE_AUTH_RSP) || + (eWNI_SME_GET_STATISTICS_RSP == pSmeRsp->messageType)) + { + smsLog(pMac, LOGW, FL(" handling msg 0x%X CSR state is %d"), pSmeRsp->messageType, pMac->roam.curState[pSmeRsp->sessionId]); + csrRoamCheckForLinkStatusChange(pMac, pSmeRsp); + } + else + { + smsLog(pMac, LOGW, " Message 0x%04X is not handled by CSR. CSR state is %d ", pSmeRsp->messageType, pMac->roam.curState[pSmeRsp->sessionId]); + } + break; + } + + }//switch + +#if defined( ANI_RTT_DEBUG ) + } +#endif//RTT + + return (status); +} + + + +tANI_BOOLEAN csrCheckPSReady(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + + VOS_ASSERT( pMac->roam.sPendingCommands >= 0 ); + return (pMac->roam.sPendingCommands == 0); +} + + +void csrFullPowerCallback(void *pv, eHalStatus status) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tListElem *pEntry; + tSmeCmd *pCommand; + + (void)status; + + while( NULL != ( pEntry = csrLLRemoveHead( &pMac->roam.roamCmdPendingList, eANI_BOOLEAN_TRUE ) ) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smePushCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); + } + +} + + diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h b/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h new file mode 100644 index 000000000000..2f57205e423a --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrInsideApi.h @@ -0,0 +1,1122 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrInsideApi.h + + Define interface only used by CSR. + ========================================================================== */ +#ifndef CSR_INSIDE_API_H__ +#define CSR_INSIDE_API_H__ + + +#include +#include "csrSupport.h" +#include "smeInside.h" +#include "vos_nvitem.h" + +#define CSR_PASSIVE_MAX_CHANNEL_TIME 110 +#define CSR_PASSIVE_MIN_CHANNEL_TIME 60 + +#define CSR_ACTIVE_MAX_CHANNEL_TIME 40 +#define CSR_ACTIVE_MIN_CHANNEL_TIME 20 + +#define CSR_ACTIVE_MAX_CHANNEL_TIME_ESCO_BTC 120 +#define CSR_ACTIVE_MIN_CHANNEL_TIME_ESCO_BTC 60 + +#define CSR_ACTIVE_MIN_CHANNEL_TIME_SCO_BTC 20 +#define CSR_ACTIVE_MAX_CHANNEL_TIME_SCO_BTC 40 + +#ifdef WLAN_AP_STA_CONCURRENCY +#define CSR_PASSIVE_MAX_CHANNEL_TIME_CONC 110 +#define CSR_PASSIVE_MIN_CHANNEL_TIME_CONC 60 + +#define CSR_ACTIVE_MAX_CHANNEL_TIME_CONC 27 +#define CSR_ACTIVE_MIN_CHANNEL_TIME_CONC 20 + +#define CSR_REST_TIME_CONC 100 + +#define CSR_NUM_STA_CHAN_COMBINED_CONC 3 +#define CSR_NUM_P2P_CHAN_COMBINED_CONC 1 +#endif + +#define CSR_MAX_NUM_SUPPORTED_CHANNELS 55 + +#define CSR_MAX_2_4_GHZ_SUPPORTED_CHANNELS 14 + +#define CSR_MAX_BSS_SUPPORT 512 +#define SYSTEM_TIME_MSEC_TO_USEC 1000 +#define SYSTEM_TIME_SEC_TO_MSEC 1000 + +//This number minus 1 means the number of times a channel is scanned before a BSS is remvoed from +//cache scan result +#define CSR_AGING_COUNT 3 +//The following defines are used by palTimer +//This is used for palTimer when request to imps fails +#define CSR_IDLE_SCAN_WAIT_TIME (1 * PAL_TIMER_TO_SEC_UNIT) //1 second +//This is used for palTimer when imps ps is disabled +//This number shall not be smaller than 5-6 seconds in general because a full scan may take 3-4 seconds +#define CSR_IDLE_SCAN_NO_PS_INTERVAL (10 * PAL_TIMER_TO_SEC_UNIT) //10 second +#define CSR_IDLE_SCAN_NO_PS_INTERVAL_MIN (5 * PAL_TIMER_TO_SEC_UNIT) +#define CSR_SCAN_GET_RESULT_INTERVAL (5 * PAL_TIMER_TO_SEC_UNIT) //5 seconds +#define CSR_MIC_ERROR_TIMEOUT (60 * PAL_TIMER_TO_SEC_UNIT) //60 seconds +#define CSR_TKIP_COUNTER_MEASURE_TIMEOUT (60 * PAL_TIMER_TO_SEC_UNIT) //60 seconds +#define CSR_SCAN_RESULT_AGING_INTERVAL (5 * PAL_TIMER_TO_SEC_UNIT) //5 seconds +//the following defines are NOT used by palTimer +#define CSR_SCAN_AGING_TIME_NOT_CONNECT_NO_PS 50 //50 seconds +#define CSR_SCAN_AGING_TIME_NOT_CONNECT_W_PS 300 //300 seconds +#define CSR_SCAN_AGING_TIME_CONNECT_NO_PS 150 //150 seconds +#define CSR_SCAN_AGING_TIME_CONNECT_W_PS 600 //600 seconds +#define CSR_JOIN_FAILURE_TIMEOUT_DEFAULT ( 3000 ) +#define CSR_JOIN_FAILURE_TIMEOUT_MIN (1000) //minimal value +//These are going against the signed RSSI (tANI_S8) so it is between -+127 +#define CSR_BEST_RSSI_VALUE (-30) //RSSI >= this is in CAT4 +#define CSR_DEFAULT_RSSI_DB_GAP 30 //every 30 dbm for one category +#define CSR_BSS_CAP_VALUE_NONE 0 //not much value +#define CSR_BSS_CAP_VALUE_HT 2 +#define CSR_BSS_CAP_VALUE_WMM 1 +#define CSR_BSS_CAP_VALUE_UAPSD 1 +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +#define CSR_BSS_CAP_VALUE_5GHZ 1 +#endif +#define CSR_DEFAULT_ROAMING_TIME 10 //10 seconds +#define CSR_ROAM_MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +#define CSR_ROAM_MAX(X, Y) ((X) > (Y) ? (X) : (Y)) + +#ifdef FEATURE_WLAN_BTAMP_UT_RF +#define CSR_JOIN_MAX_RETRY_COUNT 10 +#define CSR_JOIN_RETRY_TIMEOUT_PERIOD ( 1 * PAL_TIMER_TO_SEC_UNIT ) // 1 second +#endif + +#define CSR_DISABLE_SCAN_DURING_SCO 100 //100 milliseconds + + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define ROAMING_RSSI_WEIGHT 50 +#define MIN_RSSI (-100) +#define MAX_RSSI 0 +#define ROAM_AP_COUNT_WEIGHT 50 +#define ROAM_MAX_COUNT 30 +#define ROAM_MIN_COUNT 0 +#define ROAM_MAX_WEIGHT 100 + +#define RSSI_WEIGHTAGE 25 +#define HT_CAPABILITY_WEIGHTAGE 10 +#define VHT_CAP_WEIGHTAGE 6 +#define BEAMFORMING_CAP_WEIGHTAGE 2 +#define CHAN_WIDTH_WEIGHTAGE 10 +#define CHAN_BAND_WEIGHTAGE 5 +#define WMM_WEIGHTAGE 2 +#define CCA_WEIGHTAGE 10 +#define OTHER_AP_WEIGHT 30 + +#define MAX_AP_LOAD 255 +#define PENALTY_TIMEOUT (30 * 60 * 1000) +#define PENALTY_REMAINING_SCORE (7) +#define PENALTY_TOTAL_SCORE (10) +#define PER_EXCELENT_RSSI -40 +#define PER_GOOD_RSSI -55 +#define PER_POOR_RSSI -65 +#define PER_BAD_RSSI -80 +#define PER_ROAM_EXCELLENT_RSSI_WEIGHT 100 +#define PER_ROAM_GOOD_RSSI_WEIGHT 80 +#define PER_ROAM_BAD_RSSI_WEIGHT 60 +#define PER_ROAM_MAX_WEIGHT 100 +#define PER_ROAM_80MHZ 100 +#define PER_ROAM_40MHZ 70 +#define PER_ROAM_20MHZ 30 +#define PER_ROAM_PENALTY (3/10) +#define PER_ROAM_MAX_BSS_SCORE 10000 +#endif + +typedef enum +{ + eCsrNextScanNothing, + eCsrNextLostLinkScan1Success, + eCsrNextLostLinkScan1Failed, + eCsrNextLostLinkScan2Success, + eCsrNextLostLinkScan2Failed, + eCsrNextLostLinkScan3Success, + eCsrNexteScanForSsidSuccess, + eCsrNextLostLinkScan3Failed, + eCsrNext11dScan1Failure, + eCsrNext11dScan1Success, + eCsrNext11dScan2Failure, + eCsrNext11dScan2Success, + eCsrNext11dScanComplete, + eCsrNexteScanForSsidFailure, + eCsrNextIdleScanComplete, + eCsrNextCapChangeScanComplete, + +}eCsrScanCompleteNextCommand; + +typedef enum +{ + eCsrJoinSuccess, + eCsrJoinFailure, + eCsrReassocSuccess, + eCsrReassocFailure, + eCsrNothingToJoin, + eCsrStartBssSuccess, + eCsrStartBssFailure, + eCsrSilentlyStopRoaming, + eCsrSilentlyStopRoamingSaveState, + eCsrJoinWdsFailure, + eCsrJoinFailureDueToConcurrency, + +}eCsrRoamCompleteResult; + +typedef struct tagScanReqParam +{ + tANI_U8 bReturnAfter1stMatch; + tANI_U8 fUniqueResult; + tANI_U8 freshScan; + tANI_U8 hiddenSsid; + tANI_U8 reserved; +}tScanReqParam; + +typedef struct tagCsrScanResult +{ + tListElem Link; + tANI_S32 AgingCount; //This BSS is removed when it reaches 0 or less + tANI_U32 preferValue; //The bigger the number, the better the BSS. This value override capValue + tANI_U32 capValue; //The biggger the better. This value is in use only if we have equal preferValue + //This member must be the last in the structure because the end of tSirBssDescription (inside) is an + // array with nonknown size at this time + + eCsrEncryptionType ucEncryptionType; //Preferred Encryption type that matched with profile. + eCsrEncryptionType mcEncryptionType; + eCsrAuthType authType; //Preferred auth type that matched with the profile. +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + int congestionScore; +#endif + tCsrScanResultInfo Result; +}tCsrScanResult; + +typedef struct +{ + tDblLinkList List; + tListElem *pCurEntry; +}tScanResultList; + +/** + * csr_scan_for_ssid_context() - Callback context for SSID scan + * + * @pMac: pMac handle + * @sessionId: scan session id + * @roamId: roam Id + */ +struct csr_scan_for_ssid_context +{ + tpAniSirGlobal pMac; + tANI_U32 sessionId; + tANI_U32 roamId; +}; + +#define CSR_IS_ROAM_REASON( pCmd, reason ) ( (reason) == (pCmd)->roamCmd.roamReason ) +#define CSR_IS_BETTER_PREFER_VALUE(v1, v2) ((v1) > (v2)) +#define CSR_IS_EQUAL_PREFER_VALUE(v1, v2) ((v1) == (v2)) +#define CSR_IS_BETTER_CAP_VALUE(v1, v2) ((v1) > (v2)) +#define CSR_IS_ENC_TYPE_STATIC( encType ) ( ( eCSR_ENCRYPT_TYPE_NONE == (encType) ) || \ + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == (encType) ) || \ + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == (encType) ) ) +#define CSR_IS_WAIT_FOR_KEY( pMac, sessionId ) ( CSR_IS_ROAM_JOINED( pMac, sessionId ) && CSR_IS_ROAM_SUBSTATE_WAITFORKEY( pMac, sessionId ) ) +//WIFI has a test case for not using HT rates with TKIP as encryption +//We may need to add WEP but for now, TKIP only. + +#define CSR_IS_11n_ALLOWED( encType ) (( eCSR_ENCRYPT_TYPE_TKIP != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP40 != (encType) ) && \ + ( eCSR_ENCRYPT_TYPE_WEP104 != (encType) ) ) + +#define CSR_IS_DISCONNECT_COMMAND(pCommand) ((eSmeCommandRoam == \ + (pCommand)->command) &&\ + ((eCsrForcedDisassoc == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrForcedIbssLeave == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrForcedDeauth == (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrSmeIssuedDisassocForHandoff ==\ + (pCommand)->u.roamCmd.roamReason) ||\ + (eCsrForcedDisassocMICFailure ==\ + (pCommand)->u.roamCmd.roamReason))) + +eCsrRoamState csrRoamStateChange( tpAniSirGlobal pMac, eCsrRoamState NewRoamState, tANI_U8 sessionId); +eHalStatus csrScanningStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); +void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); +void csrRoamJoinedStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ); +tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp ); +void csrReleaseCommandRoam(tpAniSirGlobal pMac, tSmeCmd *pCommand); +tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac, + tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry); +v_U8_t *csrNeighborRoamStateToString(v_U8_t state); +void csrReleaseCommandPreauth(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseCommandScan(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrReleaseCommandWmStatusChange(tpAniSirGlobal pMac, tSmeCmd *pCommand); +//pIes2 can be NULL +tANI_BOOLEAN csrIsDuplicateBssDescription( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2, tANI_BOOLEAN fForced ); +eHalStatus csrRoamSaveConnectedBssDesc( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDesc ); +tANI_BOOLEAN csrIsNetworkTypeEqual( tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ); +eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf ); +/* + Prepare a filter base on a profile for parsing the scan results. + Upon successful return, caller MUST call csrFreeScanFilter on + pScanFilter when it is done with the filter. +*/ +eHalStatus csrRoamPrepareFilterFromProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile, tCsrScanResultFilter *pScanFilter); +eHalStatus csrRoamCopyProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pDstProfile, tCsrRoamProfile *pSrcProfile); +eHalStatus csrRoamStart(tpAniSirGlobal pMac); +void csrRoamStop(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrRoamStartMICFailureTimer(tpAniSirGlobal pMac); +void csrRoamStopMICFailureTimer(tpAniSirGlobal pMac); +void csrRoamStartTKIPCounterMeasureTimer(tpAniSirGlobal pMac); +void csrRoamStopTKIPCounterMeasureTimer(tpAniSirGlobal pMac); + +eHalStatus csrScanOpen(tpAniSirGlobal pMac); +eHalStatus csrScanClose(tpAniSirGlobal pMac); +eHalStatus csrScanRequestLostLink1( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrScanRequestLostLink2( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrScanRequestLostLink3( tpAniSirGlobal pMac, tANI_U32 sessionId ); +eHalStatus csrScanHandleFailedLostlink1(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrScanHandleFailedLostlink2(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrScanHandleFailedLostlink3(tpAniSirGlobal pMac, tANI_U32 sessionId); +tCsrScanResult *csrScanAppendBssDescription( tpAniSirGlobal pMac, + tSirBssDescription *pSirBssDescription, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForced); +void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus scanStatus); +eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCsrScanRequest *pSrcReq); +eHalStatus csrScanFreeRequest(tpAniSirGlobal pMac, tCsrScanRequest *pReq); +eHalStatus csrScanCopyResultList(tpAniSirGlobal pMac, tScanResultHandle hIn, tScanResultHandle *phResult); +void csrInitBGScanChannelList(tpAniSirGlobal pMac); +eHalStatus csrScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, tANI_U32 roamId, tANI_BOOLEAN notify); +eHalStatus csrScanForCapabilityChange(tpAniSirGlobal pMac, tSirSmeApNewCaps *pNewCaps); +eHalStatus csrScanStartGetResultTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStopGetResultTimer(tpAniSirGlobal pMac); +eHalStatus csrScanBGScanEnable(tpAniSirGlobal pMac); +eHalStatus csrScanStartIdleScanTimer(tpAniSirGlobal pMac, tANI_U32 interval); +eHalStatus csrScanStopIdleScanTimer(tpAniSirGlobal pMac); +eHalStatus csrScanStartIdleScan(tpAniSirGlobal pMac); +//Param: pTimeInterval -- Caller allocated memory in return, if failed, to specify the nxt time interval for +//idle scan timer interval +//Return: Not success -- meaning it cannot start IMPS, caller needs to start a timer for idle scan +eHalStatus csrScanTriggerIdleScan(tpAniSirGlobal pMac, tANI_U32 *pTimeInterval); +void csrScanCancelIdleScan(tpAniSirGlobal pMac); +void csrScanStopTimers(tpAniSirGlobal pMac); +//This function will remove scan commands that are not related to association or IBSS +tANI_BOOLEAN csrScanRemoveNotRoamingScanCommand(tpAniSirGlobal pMac); +//To remove fresh scan commands from the pending queue +tANI_BOOLEAN csrScanRemoveFreshScanCommand(tpAniSirGlobal pMac, tANI_U8 sessionId); +tSirAbortScanStatus csrScanAbortMacScan(tpAniSirGlobal pMac, + tANI_U8 sessionId, + eCsrAbortReason reason); +void csrRemoveCmdFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, + eSmeCommandType commandType ); +void csrRemoveCmdWithSessionIdFromPendingList(tpAniSirGlobal pMac, + tANI_U8 sessionId, + tDblLinkList *pList, + eSmeCommandType commandType); +eHalStatus csrScanAbortMacScanNotForConnect(tpAniSirGlobal pMac, + tANI_U8 sessionId); +eHalStatus csrScanGetScanChannelInfo(tpAniSirGlobal pMac, tANI_U8 sessionId); +eHalStatus csrScanAbortScanForSSID(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrRemoveScanForSSIDFromPendingList(tpAniSirGlobal pMac, tDblLinkList *pList, tANI_U32 sessionId); + +//To age out scan results base. tSmeGetScanChnRsp is a pointer returned by LIM that +//has the information regarding scanned channels. +//The logic is that whenever CSR add a BSS to scan result, it set the age count to +//a value. This function deduct the age count if channelId matches the BSS' channelId +//The BSS is remove if the count reaches 0. +eHalStatus csrScanAgeResults(tpAniSirGlobal pMac, tSmeGetScanChnRsp *pScanChnInfo); + +eHalStatus csrIbssAgeBss(tpAniSirGlobal pMac); + +//If fForce is TRUE we will save the new String that is learn't. +//Typically it will be true in case of Join or user initiated ioctl +tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce ); +void csrApplyCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce ); +void csrSetCfgScanControlList( tpAniSirGlobal pMac, tANI_U8 *countryCode, tCsrChannel *pChannelList ); +void csrReinitScanCmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); +void csrFreeScanResultEntry( tpAniSirGlobal pMac, tCsrScanResult *pResult ); + +eHalStatus csrRoamCallCallback(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, + tANI_U32 roamId, eRoamCmdStatus u1, eCsrRoamResult u2); +eHalStatus csrRoamIssueConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBSSList, + eCsrRoamReason reason, tANI_U32 roamId, + tANI_BOOLEAN fImediate, tANI_BOOLEAN fClearScan); +eHalStatus csrRoamIssueReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields *pModProfileFields, + eCsrRoamReason reason, tANI_U32 roamId, tANI_BOOLEAN fImediate); +void csrRoamComplete( tpAniSirGlobal pMac, eCsrRoamCompleteResult Result, void *Context ); +eHalStatus csrRoamIssueSetContextReq( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrEncryptionType EncryptType, + tSirBssDescription *pBssDescription, + tSirMacAddr *bssId, tANI_BOOLEAN addKey, + tANI_BOOLEAN fUnicast, tAniKeyDirection aniKeyDirection, + tANI_U8 keyId, tANI_U16 keyLength, + tANI_U8 *pKey, tANI_U8 paeRole ); +eHalStatus csrRoamProcessDisassocDeauth( tpAniSirGlobal pMac, tSmeCmd *pCommand, + tANI_BOOLEAN fDisassoc, tANI_BOOLEAN fMICFailure ); +eHalStatus csrRoamSaveConnectedInfomation(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes); +void csrRoamCheckForLinkStatusChange( tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg ); +void csrRoamStatsRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg); +eHalStatus csrRoamIssueStartBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamStartBssParams *pParam, + tCsrRoamProfile *pProfile, tSirBssDescription *pBssDesc, tANI_U32 roamId ); +eHalStatus csrRoamIssueStopBss( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamSubState NewSubstate ); +tANI_BOOLEAN csrIsSameProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile1, tCsrRoamProfile *pProfile2); +tANI_BOOLEAN csrIsRoamCommandWaiting(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIsRoamCommandWaitingForSession(tpAniSirGlobal pMac, tANI_U32 sessionId); +tANI_BOOLEAN csrIsScanForRoamCommandActive( tpAniSirGlobal pMac ); +eRoamCmdStatus csrGetRoamCompleteStatus(tpAniSirGlobal pMac, tANI_U32 sessionId); +//pBand can be NULL if caller doesn't need to get it +//eCsrCfgDot11Mode csrRoamGetPhyModeBandForBss( tpAniSirGlobal pMac, eCsrPhyMode phyModeIn, tANI_U8 operationChn, eCsrBand *pBand ); +eHalStatus csrRoamIssueDisassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason ); +eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason); +//pCommand may be NULL +void csrRoamRemoveDuplicateCommand(tpAniSirGlobal pMac, tANI_U32 sessionId, tSmeCmd *pCommand, eCsrRoamReason eRoamReason); + +eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription, + tCsrRoamProfile *pProfile, tDot11fBeaconIEs *pIes, tANI_U16 messageType ); +eHalStatus csrSendMBDisassocReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ); +#ifdef WLAN_FEATURE_LFR_MBB +eHalStatus csr_fill_reassoc_req(tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDescription *pBssDescription, + tDot11fBeaconIEs *pIes, tSirSmeJoinReq **reassoc_req); +#endif +eHalStatus csrSendMBDeauthReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirMacAddr bssId, tANI_U16 reasonCode ); +eHalStatus csrSendMBDisassocCnfMsg( tpAniSirGlobal pMac, tpSirSmeDisassocInd pDisassocInd ); +eHalStatus csrSendMBDeauthCnfMsg( tpAniSirGlobal pMac, tpSirSmeDeauthInd pDeauthInd ); +eHalStatus csrSendAssocCnfMsg( tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd, eHalStatus status ); +eHalStatus csrSendAssocIndToUpperLayerCnfMsg( tpAniSirGlobal pMac, tpSirSmeAssocInd pAssocInd, eHalStatus Halstatus, tANI_U8 sessionId ); +eHalStatus csrSendMBStartBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamBssType bssType, + tCsrRoamStartBssParams *pParam, tSirBssDescription *pBssDesc ); +eHalStatus csrSendMBStopBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId ); + +tANI_BOOLEAN csrIsMacAddressEqual( tpAniSirGlobal pMac, tCsrBssid *pMacAddr1, tCsrBssid *pMacAddr2 ); +//Caller should put the BSS' ssid to fiedl bssSsid when comparing SSID for a BSS. +tANI_BOOLEAN csrIsSsidMatch( tpAniSirGlobal pMac, tANI_U8 *ssid1, tANI_U8 ssid1Len, tANI_U8 *bssSsid, + tANI_U8 bssSsidLen, tANI_BOOLEAN fSsidRequired ); +tANI_BOOLEAN csrIsPhyModeMatch( tpAniSirGlobal pMac, tANI_U32 phyMode, + tSirBssDescription *pSirBssDesc, tCsrRoamProfile *pProfile, + eCsrCfgDot11Mode *pReturnCfgDot11Mode, + tDot11fBeaconIEs *pIes); +tANI_BOOLEAN csrRoamIsChannelValid( tpAniSirGlobal pMac, tANI_U8 channel ); + +//pNumChan is a caller allocated space with the sizeof pChannels +eHalStatus csrGetCfgValidChannels(tpAniSirGlobal pMac, tANI_U8 *pChannels, tANI_U32 *pNumChan); +void csrRoamCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result); +void csrScanCcmCfgSetCallback(tHalHandle hHal, tANI_S32 result); + +tPowerdBm csrGetCfgMaxTxPower (tpAniSirGlobal pMac, tANI_U8 channel); + +//To free the last roaming profile +void csrFreeRoamProfile(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrFreeConnectBssDesc(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrMoveBssToHeadFromBSSID(tpAniSirGlobal pMac, tCsrBssid *bssid, tScanResultHandle hScanResult); +tANI_BOOLEAN csrCheckPSReady(void *pv); +void csrFullPowerCallback(void *pv, eHalStatus status); +//to free memory allocated inside the profile structure +void csrReleaseProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile); +//To free memory allocated inside scanFilter +void csrFreeScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter); +eCsrCfgDot11Mode csrGetCfgDot11ModeFromCsrPhyMode(tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tANI_BOOLEAN fProprietary); +tANI_U32 csrTranslateToWNICfgDot11Mode(tpAniSirGlobal pMac, eCsrCfgDot11Mode csrDot11Mode); +void csrSaveChannelPowerForBand( tpAniSirGlobal pMac, tANI_BOOLEAN fPopulate5GBand ); +void csrApplyChannelPowerCountryInfo( tpAniSirGlobal pMac, tCsrChannel *pChannelList, tANI_U8 *countryCode, tANI_BOOLEAN updateRiva); +void csrApplyPower2Current( tpAniSirGlobal pMac ); +void csrAssignRssiForCategory(tpAniSirGlobal pMac, tANI_S8 bestApRssi, tANI_U8 catOffset); +tANI_BOOLEAN csrIsMacAddressZero( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ); +tANI_BOOLEAN csrIsMacAddressBroadcast( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ); +eHalStatus csrRoamRemoveConnectedBssFromScanCache(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pConnProfile); +eHalStatus csrRoamStartRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamingReason roamingReason); +//return a boolean to indicate whether roaming completed or continue. +tANI_BOOLEAN csrRoamCompleteRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fForce, eCsrRoamResult roamResult); +void csrRoamCompletion(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamInfo *pRoamInfo, tSmeCmd *pCommand, eCsrRoamResult roamResult, tANI_BOOLEAN fSuccess); +void csrRoamCancelRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId); +void csrResetCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce, tANI_BOOLEAN updateRiva ); +void csrResetPMKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ); +#ifdef FEATURE_WLAN_WAPI +void csrResetBKIDCandidateList( tpAniSirGlobal pMac, tANI_U32 sessionId ); +#endif /* FEATURE_WLAN_WAPI */ +eHalStatus csrSaveToChannelPower2G_5G( tpAniSirGlobal pMac, tANI_U32 tableSize, tSirMacChanInfo *channelTable ); +//Get the list of the base channels to scan for passively 11d info +eHalStatus csrScanGetSupportedChannels( tpAniSirGlobal pMac ); +//To check whether a country code matches the one in the IE +//Only check the first two characters, ignoring in/outdoor +//pCountry -- caller allocated buffer contain the country code that is checking against +//the one in pIes. It can be NULL. +//caller must provide pIes, it cannot be NULL +//This function always return TRUE if 11d support is not turned on. +//pIes cannot be NULL +tANI_BOOLEAN csrMatchCountryCode( tpAniSirGlobal pMac, tANI_U8 *pCountry, tDot11fBeaconIEs *pIes ); +eHalStatus csrRoamSetKey( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 roamId ); +eHalStatus csrRoamOpenSession(tpAniSirGlobal pMac, + csrRoamCompleteCallback callback, + void *pContext, tANI_U8 *pSelfMacAddr, + tANI_U8 *pbSessionId); +//fSync: TRUE means cleanupneeds to handle synchronously. +eHalStatus csrRoamCloseSession( tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_BOOLEAN fSync, tANI_U8 bPurgeList, + csrRoamSessionCloseCallback callback, + void *pContext ); +void csrPurgeSmeCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + bool flush_all); +void csrCleanupSession(tpAniSirGlobal pMac, tANI_U32 sessionId); +eHalStatus csrRoamGetSessionIdFromBSSID( tpAniSirGlobal pMac, tCsrBssid *bssid, tANI_U32 *pSessionId ); +eCsrCfgDot11Mode csrFindBestPhyMode( tpAniSirGlobal pMac, tANI_U32 phyMode ); + +/* --------------------------------------------------------------------------- + \fn csrScanEnable + \brief Enable the scanning feature of CSR. It must be called before any scan request can be performed. + \param tHalHandle - HAL context handle + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanEnable(tpAniSirGlobal); + +/* --------------------------------------------------------------------------- + \fn csrScanDisable + \brief Disableing the scanning feature of CSR. After this function return success, no scan is performed until +a successfull to csrScanEnable + \param tHalHandle - HAL context handle + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanDisable(tpAniSirGlobal); +/* --------------------------------------------------------------------------- + \fn csrScanRequest + \brief Request a 11d or full scan. + \param pScanRequestID - pointer to an object to get back the request ID + \param callback - a callback function that scan calls upon finish, will not be called if csrScanRequest returns error + \param pContext - a pointer passed in for the callback + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanRequest(tpAniSirGlobal, tANI_U16, tCsrScanRequest *, + tANI_U32 *pScanRequestID, csrScanCompleteCallback callback, + void *pContext); + +/* --------------------------------------------------------------------------- + \fn csrScanAbort + \brief If a scan request is abort, the scan complete callback will be called first before csrScanAbort returns. + \param pScanRequestID - The request ID returned from csrScanRequest + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanAbort(tpAniSirGlobal, tANI_U32 scanRequestID); + +eHalStatus csrScanSetBGScanparams(tpAniSirGlobal, tCsrBGScanRequest *); +eHalStatus csrScanBGScanAbort(tpAniSirGlobal); + +/* --------------------------------------------------------------------------- + \fn csrScanGetResult + \brief Return scan results. + \param pFilter - If pFilter is NULL, all cached results are returned + \param phResult - an object for the result. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanGetResult(tpAniSirGlobal, tCsrScanResultFilter *pFilter, tScanResultHandle *phResult); + +#ifdef FEATURE_WLAN_LFR +/* --------------------------------------------------------------------------- + \fn csrAddChannelToOccupiedChannelList + \brief Add channel no given by fast reassoc cmd into occ chn list + \param channel - channel no passed by fast reassoc cmd + \return void + -------------------------------------------------------------------------------*/ +void csrAddChannelToOccupiedChannelList(tpAniSirGlobal pMac, tANI_U8 channel); +#endif +/* --------------------------------------------------------------------------- + \fn csrScanFlushResult + \brief Clear scan results. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanFlushResult(tpAniSirGlobal); +/* --------------------------------------------------------------------------- + * \fn csrScanFilterResults + * \brief Filter scan results based on valid channel list. + * \return eHalStatus + *------------------------------------------------------------------------------- + */ +eHalStatus csrScanFilterResults(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------- + * \fn csrScanFilterDFSResults + * \brief Filter BSSIDs on DFS channels from the scan results. + * \return eHalStatus + *------------------------------------------------------------------------------- + */ +eHalStatus csrScanFilterDFSResults(tpAniSirGlobal pMac); + +eHalStatus csrScanFlushSelectiveResult(tpAniSirGlobal, v_BOOL_t flushP2P); + +eHalStatus csrScanFlushSelectiveResultForBand(tpAniSirGlobal, v_BOOL_t flushP2P, tSirRFBand band); + +/* --------------------------------------------------------------------------- + \fn csrScanBGScanGetParam + \brief Returns the current background scan settings. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanBGScanGetParam(tpAniSirGlobal, tCsrBGScanRequest *); + +/* --------------------------------------------------------------------------- + \fn csrScanResultGetFirst + \brief Returns the first element of scan result. + \param hScanResult - returned from csrScanGetResult + \return tCsrScanResultInfo * - NULL if no result + -------------------------------------------------------------------------------*/ +tCsrScanResultInfo *csrScanResultGetFirst(tpAniSirGlobal, tScanResultHandle hScanResult); +/* --------------------------------------------------------------------------- + \fn csrScanResultGetNext + \brief Returns the next element of scan result. It can be called without calling csrScanResultGetFirst first + \param hScanResult - returned from csrScanGetResult + \return Null if no result or reach the end + -------------------------------------------------------------------------------*/ +tCsrScanResultInfo *csrScanResultGetNext(tpAniSirGlobal, tScanResultHandle hScanResult); + +/* --------------------------------------------------------------------------- + \fn csrGetCountryCode + \brief this function is to get the country code current being used + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, this has the country code + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U8 *pbLen); + +/* --------------------------------------------------------------------------- + \fn csrSetCountryCode + \brief this function is to set the country code so channel/power setting matches the countrycode and + the domain it belongs to. + \param pCountry - Caller allocated buffer with at least 3 bytes specifying the country code + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrSetCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn csrResetCountryCodeInformation + \brief this function is to reset the country code current being used back to EEPROM default + this includes channel list and power setting. + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrResetCountryCodeInformation(tpAniSirGlobal pMac, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn csrGetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed bytes. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetSupportedCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U32 *pbLen); + +/* --------------------------------------------------------------------------- + \fn csrSetRegulatoryDomain + \brief this function is to set the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \param domainId - indicate the domain (defined in the driver) needs to set to. + See eRegDomainId for definition + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrSetRegulatoryDomain(tpAniSirGlobal pMac, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded); + +/* --------------------------------------------------------------------------- + \fn csrGetCurrentRegulatoryDomain + \brief this function is to get the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \return eRegDomainId + -------------------------------------------------------------------------------*/ +v_REGDOMAIN_t csrGetCurrentRegulatoryDomain(tpAniSirGlobal pMac); + +/* --------------------------------------------------------------------------- + \fn csrGetRegulatoryDomainForCountry + \brief this function is to get the regulatory domain for a country. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \param pCountry - Caller allocated buffer with at least 3 bytes specifying the country code + \param pDomainId - Caller allocated buffer to get the return domain ID upon success return. Can be NULL. + \param source - the source of country information. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetRegulatoryDomainForCountry(tpAniSirGlobal pMac, + tANI_U8 *pCountry, + v_REGDOMAIN_t *pDomainId, + v_CountryInfoSource_t source); + + +tANI_BOOLEAN csrSave11dCountryString( tpAniSirGlobal pMac, tANI_U8 *pCountryCode, tANI_BOOLEAN fForce ); + +//some support functions +tANI_BOOLEAN csrIs11dSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIs11hSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIs11eSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIsWmmSupported(tpAniSirGlobal pMac); +tANI_BOOLEAN csrIsMCCSupported(tpAniSirGlobal pMac); + +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus csrScanGetBaseChannels( tpAniSirGlobal pMac, tCsrChannelInfo * pChannelInfo ); +//Return SUCCESS is the command is queued, failed +eHalStatus csrQueueSmeCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fHighPriority ); +tSmeCmd *csrGetCommandBuffer( tpAniSirGlobal pMac ); +void csrReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCommand); +#ifdef FEATURE_WLAN_WAPI +tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile ); +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR + +//Security +#define WLAN_SECURITY_EVENT_SET_PTK_REQ 1 +#define WLAN_SECURITY_EVENT_SET_PTK_RSP 2 +#define WLAN_SECURITY_EVENT_SET_GTK_REQ 3 +#define WLAN_SECURITY_EVENT_SET_GTK_RSP 4 +#define WLAN_SECURITY_EVENT_REMOVE_KEY_REQ 5 +#define WLAN_SECURITY_EVENT_REMOVE_KEY_RSP 6 +#define WLAN_SECURITY_EVENT_PMKID_CANDIDATE_FOUND 7 +#define WLAN_SECURITY_EVENT_PMKID_UPDATE 8 +#define WLAN_SECURITY_EVENT_MIC_ERROR 9 +#define WLAN_SECURITY_EVENT_SET_UNICAST_REQ 10 +#define WLAN_SECURITY_EVENT_SET_UNICAST_RSP 11 +#define WLAN_SECURITY_EVENT_SET_BCAST_REQ 12 +#define WLAN_SECURITY_EVENT_SET_BCAST_RSP 13 + + +#define AUTH_OPEN 0 +#define AUTH_SHARED 1 +#define AUTH_WPA_EAP 2 +#define AUTH_WPA_PSK 3 +#define AUTH_WPA2_EAP 4 +#define AUTH_WPA2_PSK 5 +#ifdef FEATURE_WLAN_WAPI +#define AUTH_WAPI_CERT 6 +#define AUTH_WAPI_PSK 7 +#endif /* FEATURE_WLAN_WAPI */ + +#define ENC_MODE_OPEN 0 +#define ENC_MODE_WEP40 1 +#define ENC_MODE_WEP104 2 +#define ENC_MODE_TKIP 3 +#define ENC_MODE_AES 4 +#ifdef FEATURE_WLAN_WAPI +#define ENC_MODE_SMS4 5 //WAPI +#endif /* FEATURE_WLAN_WAPI */ + +#define NO_MATCH 0 +#define MATCH 1 + +#define WLAN_SECURITY_STATUS_SUCCESS 0 +#define WLAN_SECURITY_STATUS_FAILURE 1 + +//Scan +#define WLAN_SCAN_EVENT_ACTIVE_SCAN_REQ 1 +#define WLAN_SCAN_EVENT_ACTIVE_SCAN_RSP 2 +#define WLAN_SCAN_EVENT_PASSIVE_SCAN_REQ 3 +#define WLAN_SCAN_EVENT_PASSIVE_SCAN_RSP 4 +#define WLAN_SCAN_EVENT_HO_SCAN_REQ 5 +#define WLAN_SCAN_EVENT_HO_SCAN_RSP 6 + +#define WLAN_SCAN_STATUS_SUCCESS 0 +#define WLAN_SCAN_STATUS_FAILURE 1 +#define WLAN_SCAN_STATUS_ABORT 2 + +//Ibss +#define WLAN_IBSS_EVENT_START_IBSS_REQ 0 +#define WLAN_IBSS_EVENT_START_IBSS_RSP 1 +#define WLAN_IBSS_EVENT_JOIN_IBSS_REQ 2 +#define WLAN_IBSS_EVENT_JOIN_IBSS_RSP 3 +#define WLAN_IBSS_EVENT_COALESCING 4 +#define WLAN_IBSS_EVENT_PEER_JOIN 5 +#define WLAN_IBSS_EVENT_PEER_LEAVE 6 +#define WLAN_IBSS_EVENT_STOP_REQ 7 +#define WLAN_IBSS_EVENT_STOP_RSP 8 + +#define AUTO_PICK 0 +#define SPECIFIED 1 + +#define WLAN_IBSS_STATUS_SUCCESS 0 +#define WLAN_IBSS_STATUS_FAILURE 1 + +//11d +#define WLAN_80211D_EVENT_COUNTRY_SET 0 +#define WLAN_80211D_EVENT_RESET 1 + +#define WLAN_80211D_DISABLED 0 +#define WLAN_80211D_SUPPORT_MULTI_DOMAIN 1 +#define WLAN_80211D_NOT_SUPPORT_MULTI_DOMAIN 2 + +int diagAuthTypeFromCSRType(eCsrAuthType authType); +int diagEncTypeFromCSRType(eCsrEncryptionType encType); +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR +/* --------------------------------------------------------------------------- + \fn csrScanResultPurge + \brief remove all items(tCsrScanResult) in the list and free memory for each item + \param hScanResult - returned from csrScanGetResult. hScanResult is considered gone by + calling this function and even before this function reutrns. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrScanResultPurge(tpAniSirGlobal pMac, tScanResultHandle hScanResult); + + +///////////////////////////////////////////Common Scan ends + +/* --------------------------------------------------------------------------- + \fn csrRoamConnect + \brief To inititiate an association + \param pProfile - can be NULL to join to any open ones + \param hBssListIn - a list of BSS descriptor to roam to. It is returned from csrScanGetResult + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamConnect(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tScanResultHandle hBssListIn, tANI_U32 *pRoamId); + +/* --------------------------------------------------------------------------- + \fn csrRoamReassoc + \brief To inititiate a re-association + \param pProfile - can be NULL to join the currently connected AP. In that + case modProfileFields should carry the modified field(s) which could trigger + reassoc + \param modProfileFields - fields which are part of tCsrRoamConnectedProfile + that might need modification dynamically once STA is up & running and this + could trigger a reassoc + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamReassoc(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId); + + +/* --------------------------------------------------------------------------- + \fn csrRoamReconnect + \brief To disconnect and reconnect with the same profile + \return eHalStatus. It returns fail if currently not connected + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamReconnect(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrRoamSetPMKIDCache + \brief return the PMKID candidate list + \param pPMKIDCache - caller allocated buffer point to an array of tPmkidCacheInfo + \param numItems - a variable that has the number of tPmkidCacheInfo allocated + when retruning, this is either the number needed or number of items put into pPMKIDCache + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough and pNumItems + has the number of tPmkidCacheInfo. + \Note: pNumItems is a number of tPmkidCacheInfo, not sizeof(tPmkidCacheInfo) * something + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamSetPMKIDCache( tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWpaRsnReqIE + \brief return the WPA or RSN IE CSR passes to PE to JOIN request or START_BSS request + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWpaRsnReqIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWpaRsnRspIE + \brief return the WPA or RSN IE from the beacon or probe rsp if connected + \param pLen - caller allocated memory that has the length of pBuf as input. Upon returned, *pLen has the + needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWpaRsnRspIE(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 *pLen, tANI_U8 *pBuf); + + +/* --------------------------------------------------------------------------- + \fn csrRoamGetNumPMKIDCache + \brief return number of PMKID cache entries + \return tANI_U32 - the number of PMKID cache entries + -------------------------------------------------------------------------------*/ +tANI_U32 csrRoamGetNumPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetPMKIDCache + \brief return PMKID cache from CSR + \param pNum - caller allocated memory that has the space of the number of pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetPMKIDCache(tpAniSirGlobal pMac, tANI_U32 sessionId, + tANI_U32 *pNum, tPmkidCacheInfo *pPmkidCache); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetConnectProfile + \brief To return the current connect profile. Caller must call csrRoamFreeConnectProfile + after it is done and before reuse for another csrRoamGetConnectProfile call. + \param pProfile - pointer to a caller allocated structure tCsrRoamConnectedProfile + \return eHalStatus. Failure if not connected + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetConnectProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetConnectState + \brief To return the current connect state of Roaming + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamGetConnectState(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrConnectState *pState); + +/* --------------------------------------------------------------------------- + \fn csrRoamFreeConnectProfile + \brief To free and reinitialize the profile return previous by csrRoamGetConnectProfile. + \param pProfile - pointer to a caller allocated structure tCsrRoamConnectedProfile + \return eHalStatus. + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamFreeConnectProfile(tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile); + +/* --------------------------------------------------------------------------- + \fn csrInitChannelList + \brief HDD calls this function to set the WNI_CFG_VALID_CHANNEL_LIST base on the band/mode settings. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + CSR. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrInitChannelList( tHalHandle hHal ); + +/* --------------------------------------------------------------------------- + \fn csrChangeConfigParams + \brief The CSR API exposed for HDD to provide config params to CSR during + SMEs stop -> start sequence. + If HDD changed the domain that will cause a reset. This function will + provide the new set of 11d information for the new domain. Currrently this + API provides info regarding 11d only at reset but we can extend this for + other params (PMC, QoS) which needs to be initialized again at reset. + \param + hHal - Handle to the HAL. The HAL handle is returned by the HAL after it is + opened (by calling halOpen). + pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that + currently provides 11d related information like Country code, + Regulatory domain, valid channel list, Tx power per channel, a + list with active/passive scan allowed per valid channel. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrChangeConfigParams(tpAniSirGlobal pMac, + tCsrUpdateConfigParam *pUpdateConfigParam); + +/* --------------------------------------------------------------------------- + \fn csrRoamConnectToLastProfile + \brief To disconnect and reconnect with the same profile + \return eHalStatus. It returns fail if currently connected + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamConnectToLastProfile(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrRoamDisconnect + \brief To disconnect from a network + \param reason -- To indicate the reason for disconnecting. Currently, only eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrRoamDisconnect(tpAniSirGlobal pMac, tANI_U32 sessionId, eCsrRoamDisconnectReason reason); + +/* --------------------------------------------------------------------------- + \fn csr_abortConnection + \brief To disconnect from a connecting network + \retutn void. +----------------------------------------------------------------------------*/ + +void csr_abortConnection(tpAniSirGlobal pMac, tANI_U32 sessionId); + +/* --------------------------------------------------------------------------- + \fn csrScanGetPMKIDCandidateList + \brief return the PMKID candidate list + \param pPmkidList - caller allocated buffer point to an array of tPmkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of tPmkidCandidateInfo allocated + when retruning, this is either the number needed or number of items put into pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not big enough and pNumItems + has the number of tPmkidCandidateInfo. + \Note: pNumItems is a number of tPmkidCandidateInfo, not sizeof(tPmkidCandidateInfo) * something + -------------------------------------------------------------------------------*/ +eHalStatus csrScanGetPMKIDCandidateList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tPmkidCandidateInfo *pPmkidList, tANI_U32 *pNumItems ); + +//This function is used to stop a BSS. It is similar of csrRoamIssueDisconnect but this function +//doesn't have any logic other than blindly trying to stop BSS +eHalStatus csrRoamIssueStopBssCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN fHighPriority ); + +void csrCallRoamingCompletionCallback(tpAniSirGlobal pMac, tCsrRoamSession *pSession, + tCsrRoamInfo *pRoamInfo, tANI_U32 roamId, eCsrRoamResult roamResult); + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDisassociateStaCmd + \brief csr function that HDD calls to disassociate a associated station + \param sessionId - session Id for Soft AP + \param pPeerMacAddr - MAC of associated station to delete + \param reason - reason code, be one of the tSirMacReasonCodes + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDisassociateStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pPeerMacAddr, +#else + tANI_U8 *pPeerMacAddr, +#endif + tANI_U32 reason); + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueDeauthSta + \brief csr function that HDD calls to delete a associated station + \param sessionId - session Id for Soft AP + \param pDelStaParams- Pointer to parameters of the station to deauthenticate + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueDeauthStaCmd( tpAniSirGlobal pMac, + tANI_U32 sessionId, + struct tagCsrDelStaParams *pDelStaParams); + +/* --------------------------------------------------------------------------- + \fn csrRoamIssueTkipCounterMeasures + \brief csr function that HDD calls to start and stop tkip countermeasures + \param sessionId - session Id for Soft AP + \param bEnable - Flag to start/stop countermeasures + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamIssueTkipCounterMeasures( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_BOOLEAN bEnable); + +eHalStatus csrSendMBTkipCounterMeasuresReqMsg( tpAniSirGlobal pMac, tANI_U32 sessinId, tANI_BOOLEAN bEnable, tSirMacAddr bssId ); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetAssociatedStas + \brief csr function that HDD calls to get list of associated stations based on module ID + \param sessionId - session Id for Soft AP + \param modId - module ID - PE/HAL/TL + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pAssocStasBuf - Caller allocated memory to be filled with associatd stations info + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamGetAssociatedStas( tpAniSirGlobal pMac, tANI_U32 sessionId, VOS_MODULE_ID modId, + void *pUsrContext, void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf ); + +eHalStatus csrSendMBGetAssociatedStasReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, VOS_MODULE_ID modId, tSirMacAddr bssId, + void *pUsrContext, void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf ); + +/* --------------------------------------------------------------------------- + \fn csrRoamGetWpsSessionOverlap + \brief csr function that HDD calls to get WPS PBC session overlap information + \param sessionId - session Id for Soft AP + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pRemoveMac - pointer to MAC address of session to be removed + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus csrRoamGetWpsSessionOverlap( tpAniSirGlobal pMac, tANI_U32 sessionId, + void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac ); + +eHalStatus csrSendMBGetWPSPBCSessions( tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirMacAddr bssId, void *pUsrContext, void *pfnSapEventCallback,v_MACADDR_t pRemoveMac); + +/* --------------------------------------------------------------------------- + \fn csrSendChngMCCBeaconInterval + \brief csr function that HDD calls to send Update beacon interval + \param sessionId - session Id for Soft AP + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus +csrSendChngMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U32 sessionId); + +#ifdef FEATURE_WLAN_BTAMP_UT_RF +eHalStatus csrRoamStartJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U32 interval); +eHalStatus csrRoamStopJoinRetryTimer(tpAniSirGlobal pMac, tANI_U32 sessionId); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R +/* --------------------------------------------------------------------------- + \fn csrRoamFTPreAuthRspProcessor + \brief csr function that handles pre auth response from LIM + ---------------------------------------------------------------------------*/ +void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuthRsp ); +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +void csrEseSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession); +#endif + +#if defined(FEATURE_WLAN_ESE) +void UpdateCCKMTSF(tANI_U32 *timeStamp0, tANI_U32 *timeStamp1, tANI_U32 *incr); +#endif + +eHalStatus csrGetDefaultCountryCodeFrmNv(tpAniSirGlobal pMac, tANI_U8 *pCountry); +eHalStatus csrGetCurrentCountryCode(tpAniSirGlobal pMac, tANI_U8 *pCountry); + + +eHalStatus csrRoamEnqueuePreauth(tpAniSirGlobal pMac, tANI_U32 sessionId, tpSirBssDescription pBssDescription, + eCsrRoamReason reason, tANI_BOOLEAN fImmediate); +eHalStatus csrRoamDequeuePreauth(tpAniSirGlobal pMac); +#ifdef FEATURE_WLAN_LFR +void csrInitOccupiedChannelsList(tpAniSirGlobal pMac); +tANI_BOOLEAN csrNeighborRoamIsNewConnectedProfile(tpAniSirGlobal pMac); +tANI_BOOLEAN csrNeighborRoamConnectedProfileMatch(tpAniSirGlobal pMac, tCsrScanResult *pResult, + tDot11fBeaconIEs *pIes); +#endif +eHalStatus csrSetTxPower(tpAniSirGlobal pMac, v_U8_t sessionId, v_U8_t mW); +eHalStatus csrHT40StopOBSSScan(tpAniSirGlobal pMac, v_U8_t sessionId); + +eHalStatus csrScanCreateEntryInScanCache(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrBssid bssid, tANI_U8 channel); + +eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac); +eHalStatus csrRoamDelPMKIDfromCache( tpAniSirGlobal pMac, tANI_U32 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pBSSId, +#else + tANI_U8 *pBSSId, +#endif + tANI_BOOLEAN flush_cache ); +tANI_BOOLEAN csrElectedCountryInfo(tpAniSirGlobal pMac); +void csrAddVoteForCountryInfo(tpAniSirGlobal pMac, tANI_U8 *pCountryCode); +void csrClearVotesForCountryInfo(tpAniSirGlobal pMac); +void csr_remove_bssid_from_scan_list(tpAniSirGlobal pMac, + tSirMacAddr bssid); + +#ifdef WLAN_FEATURE_AP_HT40_24G +eHalStatus csrSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 cbMode); +#endif +void csrValidateScanChannels(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, + tCsrScanRequest *pSrcReq, tANI_U32 *new_index, tANI_U8 ch144_support); +#endif + diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrLinkList.c b/drivers/staging/prima/CORE/SME/src/csr/csrLinkList.c new file mode 100644 index 000000000000..eff1432aaf4a --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrLinkList.c @@ -0,0 +1,663 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + \file csrLinkList.c + + Implementation for the Common link list interfaces. + ========================================================================== */ + +#include "palApi.h" +#include "csrLinkList.h" +#include "vos_lock.h" +#include "vos_memory.h" +#include "vos_trace.h" + +#include "vos_timer.h" + +ANI_INLINE_FUNCTION void csrListInit(tListElem *pList) +{ + pList->last = pList->next = pList; +} + + +ANI_INLINE_FUNCTION void csrListRemoveEntry(tListElem *pEntry) +{ + tListElem *pLast; + tListElem *pNext; + + pLast = pEntry->last; + pNext = pEntry->next; + pLast->next = pNext; + pNext->last = pLast; +} + + +ANI_INLINE_FUNCTION tListElem * csrListRemoveHead(tListElem *pHead) +{ + tListElem *pEntry; + tListElem *pNext; + + pEntry = pHead->next; + pNext = pEntry->next; + pHead->next = pNext; + pNext->last = pHead; + + return (pEntry); +} + + + +ANI_INLINE_FUNCTION tListElem * csrListRemoveTail(tListElem *pHead) +{ + tListElem *pEntry; + tListElem *pLast; + + pEntry = pHead->last; + pLast = pEntry->last; + pHead->last = pLast; + pLast->next = pHead; + + return (pEntry); +} + + +ANI_INLINE_FUNCTION void csrListInsertTail(tListElem *pHead, tListElem *pEntry) +{ + tListElem *pLast; + + pLast = pHead->last; + pEntry->last = pLast; + pEntry->next = pHead; + pLast->next = pEntry; + pHead->last = pEntry; +} + + +ANI_INLINE_FUNCTION void csrListInsertHead(tListElem *pHead, tListElem *pEntry) +{ + tListElem *pNext; + + pNext = pHead->next; + pEntry->next = pNext; + pEntry->last = pHead; + pNext->last = pEntry; + pHead->next = pEntry; +} + + +//Insert pNewEntry before pEntry +void csrListInsertEntry(tListElem *pEntry, tListElem *pNewEntry) +{ + tListElem *pLast; + if( !pEntry) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pEntry is Null", __func__); + return; + } + + pLast = pEntry->last; + pLast->next = pNewEntry; + pEntry->last = pNewEntry; + pNewEntry->next = pEntry; + pNewEntry->last = pLast; +} + +tANI_U32 csrLLCount( tDblLinkList *pList ) +{ + tANI_U32 c = 0; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return c; + } + + if ( pList && ( LIST_FLAG_OPEN == pList->Flag ) ) + { + c = pList->Count; + } + + return( c ); +} + + +void csrLLLock( tDblLinkList *pList ) +{ + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + vos_lock_acquire(&pList->Lock); + } +} + + +void csrLLUnlock( tDblLinkList *pList ) +{ + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + vos_lock_release(&pList->Lock); + } +} + + +tANI_BOOLEAN csrLLIsListEmpty( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tANI_BOOLEAN fEmpty = eANI_BOOLEAN_TRUE; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return fEmpty ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + + fEmpty = csrIsListEmpty( &pList->ListHead ); + + if(fInterlocked) + { + csrLLUnlock(pList); + } + } + return( fEmpty ); +} + + + +tANI_BOOLEAN csrLLFindEntry( tDblLinkList *pList, tListElem *pEntryToFind ) +{ + tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return fFound ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + + while( pEntry && ( pEntry != &pList->ListHead ) ) + { + if ( pEntry == pEntryToFind ) + { + fFound = eANI_BOOLEAN_TRUE; + break; + } + pEntry = pEntry->next; + } + + } + return( fFound ); +} + + +eHalStatus csrLLOpen( tHddHandle hHdd, tDblLinkList *pList ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return eHAL_STATUS_FAILURE ; + } + + if ( LIST_FLAG_OPEN != pList->Flag ) + { + pList->Count = 0; + pList->cmdTimeoutTimer = NULL; + vosStatus = vos_lock_init(&pList->Lock); + + if(VOS_IS_STATUS_SUCCESS(vosStatus)) + { + csrListInit( &pList->ListHead ); + pList->Flag = LIST_FLAG_OPEN; + pList->hHdd = hHdd; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + return (status); +} + +void csrLLClose( tDblLinkList *pList ) +{ + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + // Make sure the list is empty... + csrLLPurge( pList, LL_ACCESS_LOCK ); + vos_lock_destroy( &pList->Lock ); + pList->Flag = LIST_FLAG_CLOSE; + } +} + +void csrLLInsertTail( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + csrListInsertTail( &pList->ListHead, pEntry ); + pList->Count++; + if(fInterlocked) + { + csrLLUnlock(pList); + } + } +} + + + +void csrLLInsertHead( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + csrListInsertHead( &pList->ListHead, pEntry ); + pList->Count++; + if(fInterlocked) + { + csrLLUnlock(pList); + } + if ( pList->cmdTimeoutTimer && pList->cmdTimeoutDuration ) + { + /* timer to detect pending command in activelist*/ + vos_timer_start( pList->cmdTimeoutTimer, + pList->cmdTimeoutDuration); + } + } +} + + +void csrLLInsertEntry( tDblLinkList *pList, tListElem *pEntry, tListElem *pNewEntry, tANI_BOOLEAN fInterlocked ) +{ + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if(fInterlocked) + { + csrLLLock(pList); + } + csrListInsertEntry( pEntry, pNewEntry ); + pList->Count++; + if(fInterlocked) + { + csrLLUnlock(pList); + } + } +} + + + +tListElem *csrLLRemoveTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + + pEntry = csrListRemoveTail( &pList->ListHead ); + pList->Count--; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + +tListElem *csrLLPeekTail( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + pEntry = pList->ListHead.last; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + + +tListElem *csrLLRemoveHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + pEntry = csrListRemoveHead( &pList->ListHead ); + pList->Count--; + } + + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + +tListElem *csrLLPeekHead( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) ) + { + pEntry = pList->ListHead.next; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pEntry ); +} + + + +void csrLLPurge( tDblLinkList *pList, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pEntry; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + while( (pEntry = csrLLRemoveHead( pList, LL_ACCESS_NOLOCK )) ) + { + // just remove everything from the list until + // nothing left on the list. + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } +} + + +tANI_BOOLEAN csrLLRemoveEntry( tDblLinkList *pList, tListElem *pEntryToRemove, tANI_BOOLEAN fInterlocked ) +{ + tANI_BOOLEAN fFound = eANI_BOOLEAN_FALSE; + tListElem *pEntry; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return fFound; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + pEntry = csrLLPeekHead( pList, LL_ACCESS_NOLOCK ); + + // Have to make sure we don't loop back to the head of the list, which will + // happen if the entry is NOT on the list... + while( pEntry && ( pEntry != &pList->ListHead ) ) + { + if ( pEntry == pEntryToRemove ) + { + csrListRemoveEntry( pEntry ); + pList->Count--; + + fFound = eANI_BOOLEAN_TRUE; + break; + } + + pEntry = pEntry->next; + } + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + if ( pList->cmdTimeoutTimer ) + { + vos_timer_stop(pList->cmdTimeoutTimer); + } + } + + return( fFound ); +} + + + +tListElem *csrLLNext( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pNextEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pNextEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) && csrLLFindEntry( pList, pEntry ) ) + { + pNextEntry = pEntry->next; + //Make sure we don't walk past the head + if ( pNextEntry == &pList->ListHead ) + { + pNextEntry = NULL; + } + } + + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pNextEntry ); +} + + +tListElem *csrLLPrevious( tDblLinkList *pList, tListElem *pEntry, tANI_BOOLEAN fInterlocked ) +{ + tListElem *pNextEntry = NULL; + + if( !pList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,"%s: Error!! pList is Null", __func__); + return pNextEntry ; + } + + if ( LIST_FLAG_OPEN == pList->Flag ) + { + if ( fInterlocked ) + { + csrLLLock( pList ); + } + + if ( !csrIsListEmpty(&pList->ListHead) && csrLLFindEntry( pList, pEntry ) ) + { + pNextEntry = pEntry->last; + //Make sure we don't walk past the head + if ( pNextEntry == &pList->ListHead ) + { + pNextEntry = NULL; + } + } + + if ( fInterlocked ) + { + csrLLUnlock( pList ); + } + } + + return( pNextEntry ); +} + + + + diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrLogDump.c b/drivers/staging/prima/CORE/SME/src/csr/csrLogDump.c new file mode 100644 index 000000000000..a216bb44e825 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrLogDump.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ +csrLogDump.c +Implements the dump commands specific to the csr module. +============================================================================*/ +#include "aniGlobal.h" +#include "csrApi.h" +#include "btcApi.h" +#include "logDump.h" +#include "smsDebug.h" +#include "smeInside.h" +#include "csrInsideApi.h" +#if defined(ANI_LOGDUMP) +static char * +dump_csr( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p ) +{ + static tCsrRoamProfile x; + static tSirMacSSid ssid; //To be allocated for array of SSIDs + static tANI_U8 sessionId; // Defined for fixed session ID + vos_mem_set((void*)&x, sizeof(x), 0); + x.SSIDs.numOfSSIDs=1 ; + x.SSIDs.SSIDList[0].SSID = ssid ; + ssid.length=6 ; + vos_mem_copy(ssid.ssId, "AniNet", 6); + if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme ))) + { + (void)csrRoamConnect(pMac, sessionId, &x, NULL, NULL); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return p; +} +static char *dump_btcSetEvent( tpAniSirGlobal pMac, tANI_U32 arg1, + tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p ) +{ + tSmeBtEvent btEvent; + if( arg1 < BT_EVENT_TYPE_MAX ) + { + smsLog(pMac, LOGE, FL(" signal BT event (%d) handle (%d) 3rd param(%d)"), arg1, arg2, arg3); + vos_mem_zero(&btEvent, sizeof(tSmeBtEvent)); + btEvent.btEventType = arg1; + switch( arg1 ) + { + case BT_EVENT_SYNC_CONNECTION_COMPLETE: + case BT_EVENT_SYNC_CONNECTION_UPDATED: + btEvent.uEventParam.btSyncConnection.connectionHandle = (v_U16_t)arg2; + btEvent.uEventParam.btSyncConnection.status = (v_U8_t)arg3; + break; + case BT_EVENT_DISCONNECTION_COMPLETE: + btEvent.uEventParam.btDisconnect.connectionHandle = (v_U16_t)arg2; + break; + case BT_EVENT_CREATE_ACL_CONNECTION: + case BT_EVENT_ACL_CONNECTION_COMPLETE: + btEvent.uEventParam.btAclConnection.connectionHandle = (v_U16_t)arg2; + btEvent.uEventParam.btAclConnection.status = (v_U8_t)arg3; + break; + case BT_EVENT_MODE_CHANGED: + btEvent.uEventParam.btAclModeChange.connectionHandle = (v_U16_t)arg2; + break; + default: + break; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if(HAL_STATUS_SUCCESS(sme_AcquireGlobalLock( &pMac->sme ))) + { + btcSignalBTEvent(pMac, &btEvent); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + } + else + { + smsLog(pMac, LOGE, FL(" invalid event (%d)"), arg1); + } + return p; +} +static char* dump_csrApConcScanParams( tpAniSirGlobal pMac, tANI_U32 arg1, + tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p ) +{ + if( arg1 ) + { + pMac->roam.configParam.nRestTimeConc = arg1; + } + if( arg2 ) + { + pMac->roam.configParam.nActiveMinChnTimeConc = arg2; + } + if( arg3 ) + { + pMac->roam.configParam.nActiveMaxChnTimeConc = arg3; + } + + smsLog(pMac, LOGE, FL(" Working %d %d %d"), (int) pMac->roam.configParam.nRestTimeConc, + (int)pMac->roam.configParam.nActiveMinChnTimeConc, (int) pMac->roam.configParam.nActiveMaxChnTimeConc); + return p; +} + +static tDumpFuncEntry csrMenuDumpTable[] = { + {0, "CSR (850-860)", NULL}, + {851, "CSR: CSR testing connection to AniNet", dump_csr}, + {852, "BTC: Fake BT events (event, handle)", dump_btcSetEvent}, + {853, "CSR: Split Scan related params", dump_csrApConcScanParams}, +}; + +void csrDumpInit(tHalHandle hHal) +{ + logDumpRegisterTable( (tpAniSirGlobal)hHal, &csrMenuDumpTable[0], + sizeof(csrMenuDumpTable)/sizeof(csrMenuDumpTable[0]) ); +} + +#endif //#if defined(ANI_LOGDUMP) diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c b/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c new file mode 100644 index 000000000000..1467f5919a60 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrNeighborRoam.c @@ -0,0 +1,5749 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrNeighborRoam.c + + Implementation for the simple roaming algorithm for 802.11r Fast transitions and Legacy roaming for Android platform. + + Copyright (C) 2010 Qualcomm, Incorporated + + + ========================================================================== */ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +08/01/10 Murali Created + +===========================================================================*/ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +#include "wlan_qct_wda.h" +#include "palApi.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "logDump.h" +#include "smeQosInternal.h" +#include "wlan_qct_tl.h" +#include "smeInside.h" +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#include "csrApi.h" +#include "wlan_qct_tl.h" +#include "sme_Api.h" +#include "csrNeighborRoam.h" +#include "macTrace.h" +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif +#ifdef WLAN_FEATURE_LFR_MBB +#include "csr_roam_mbb.h" +#endif + +#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1 +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG +#define NEIGHBOR_ROAM_DEBUG smsLog +#else +#define NEIGHBOR_ROAM_DEBUG(x...) +#endif + +static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo); +static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac); +static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac); +static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac); + +VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi); +VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi); +void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus); +eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile ); + +#ifdef WLAN_FEATURE_VOWIFI_11R +static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac); +VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac); +#endif + +v_U8_t *csrNeighborRoamStateToString(v_U8_t state) +{ + switch(state) + { + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_CLOSED ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_INIT ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_CONNECTED ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING ); + CASE_RETURN_STRING( eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE ); +#ifdef WLAN_FEATURE_LFR_MBB + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC); +#endif + default: + return "eCSR_NEIGHBOR_ROAM_STATE_UNKNOWN"; + } + +} + +/* State Transition macro */ +#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\ +{\ + pMac->roam.neighborRoamInfo.prevNeighborRoamState = pMac->roam.neighborRoamInfo.neighborRoamState;\ + pMac->roam.neighborRoamInfo.neighborRoamState = newState;\ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, \ + FL("Neighbor Roam Transition from state %s ==> %s"), \ + csrNeighborRoamStateToString (pMac->roam.neighborRoamInfo.prevNeighborRoamState), \ + csrNeighborRoamStateToString (newState));\ +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamFreeNeighborRoamBSSNode + + \brief This function frees all the internal pointers CSR NeighborRoam BSS Info + and also frees the node itself + + \param pMac - The handle returned by macOpen. + neighborRoamBSSNode - Neighbor Roam BSS Node to be freed + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode) +{ + if (neighborRoamBSSNode) + { + if (neighborRoamBSSNode->pBssDescription) + { + vos_mem_free(neighborRoamBSSNode->pBssDescription); + neighborRoamBSSNode->pBssDescription = NULL; + } + vos_mem_free(neighborRoamBSSNode); + neighborRoamBSSNode = NULL; + } + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamRemoveRoamableAPListEntry + + \brief This function removes a given entry from the given list + + \param pMac - The handle returned by macOpen. + pList - The list from which the entry should be removed + pNeighborEntry - Neighbor Roam BSS Node to be removed + + \return TRUE if successfully removed, else FALSE + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac, + tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry) +{ + if(pList) + { + return csrLLRemoveEntry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK); + } + + smsLog(pMac, LOGE, FL("Removing neighbor BSS node from list failed. Current count = %d"), csrLLCount(pList)); + + return eANI_BOOLEAN_FALSE; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamGetRoamableAPListNextEntry + + \brief Gets the entry next to passed entry. If NULL is passed, return the entry in the head of the list + + \param pMac - The handle returned by macOpen. + pList - The list from which the entry should be returned + pNeighborEntry - Neighbor Roam BSS Node whose next entry should be returned + + \return Neighbor Roam BSS Node to be returned + +---------------------------------------------------------------------------*/ +tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac, + tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry) +{ + tListElem *pEntry = NULL; + tpCsrNeighborRoamBSSInfo pResult = NULL; + + if(pList) + { + if(NULL == pNeighborEntry) + { + pEntry = csrLLPeekHead(pList, LL_ACCESS_LOCK); + } + else + { + pEntry = csrLLNext(pList, &pNeighborEntry->List, LL_ACCESS_LOCK); + } + if(pEntry) + { + pResult = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List); + } + } + + return pResult; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamFreeRoamableBSSList + + \brief Empties and frees all the nodes in the roamable AP list + + \param pMac - The handle returned by macOpen. + pList - Neighbor Roam BSS List to be emptied + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamFreeRoamableBSSList(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + tpCsrNeighborRoamBSSInfo pResult = NULL; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Emptying the BSS list. Current count = %d"), csrLLCount(pList)); + + /* Pick up the head, remove and free the node till the list becomes empty */ + while ((pResult = csrNeighborRoamGetRoamableAPListNextEntry(pMac, pList, NULL)) != NULL) + { + csrNeighborRoamRemoveRoamableAPListEntry(pMac, pList, pResult); + csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pResult); + } + return; +} + +static eHalStatus csrNeighborRoamTriggerHandoff(tpAniSirGlobal pMac, + tpCsrNeighborRoamControlInfo pNeighborRoamInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + +#ifdef WLAN_FEATURE_LFR_MBB + smsLog(pMac, LOG1, FL("enable_lfr_mbb %d is mbb supported %d"), + pMac->roam.configParam.enable_lfr_mbb, + sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK)); + + if (pMac->roam.configParam.enable_lfr_mbb + && sme_IsFeatureSupportedByFW(MAKE_BEFORE_BREAK) +#ifdef WLAN_FEATURE_VOWIFI_11R + && (!pNeighborRoamInfo->is11rAssoc) +#endif +#ifdef FEATURE_WLAN_ESE + && (!pNeighborRoamInfo->isESEAssoc) +#endif + ) { + smsLog(pMac, LOG1, + FL("Issuing preauth reassoc")); + status = csr_neighbor_roam_issue_preauth_reassoc(pMac); + if (eHAL_STATUS_SUCCESS != status) + { + pMac->ft.ftSmeContext.is_preauth_lfr_mbb = false; + smsLog(pMac, LOG1, FL("is_preauth_lfr_mbb %d"), + pMac->ft.ftSmeContext.is_preauth_lfr_mbb); + } + return status; + } + + +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + if ((pNeighborRoamInfo->is11rAssoc) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) + { + if ((eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn)) + { + status = csrNeighborRoamIssuePreauthReq(pMac); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_NONE; + vos_mem_set(&pNeighborRoamInfo->cfgRoambssId[0], + sizeof(pNeighborRoamInfo->cfgRoambssId), + 0xFF); + } + else + { + smsLog(pMac, LOGE, FL("11R Reassoc indication received in" + "unexpected state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + VOS_ASSERT(0); + } + } + else +#endif + +#ifdef FEATURE_WLAN_ESE + if ((pNeighborRoamInfo->isESEAssoc) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) + { + if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) + { + status = csrNeighborRoamIssuePreauthReq(pMac); + } + else + { + smsLog(pMac, LOGE, FL("ESE Reassoc indication received in unexpected state %s"), + macTraceGetNeighbourRoamState(pNeighborRoamInfo->neighborRoamState)); + VOS_ASSERT(0); + } + } + else +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID)) + { + if ((eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + || csrRoamIsRoamOffloadScanEnabled(pMac) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn) +#endif + ) + { + status = csrNeighborRoamIssuePreauthReq(pMac); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_NONE; + vos_mem_set(&pNeighborRoamInfo->cfgRoambssId[0], + sizeof(pNeighborRoamInfo->cfgRoambssId), + 0xFF); + } + else + { + smsLog(pMac, LOGE, FL("LFR Reassoc indication received in" + "unexpected state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + VOS_ASSERT(0); + } + } + else +#endif + { + if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState) + { + csrNeighborRoamRequestHandoff(pMac); + } + else + { + smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in" + "unexpected state %s or Roaming is disabled"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + } + } + return status; +} + +VOS_STATUS csrNeighborRoamUpdateFastRoamingEnabled(tpAniSirGlobal pMac, const v_BOOL_t fastRoamEnabled) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + if (VOS_TRUE == fastRoamEnabled) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_CONNECT); + } else { +#endif + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pMac); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d"), vosStatus); + vosStatus = VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + else if (VOS_FALSE == fastRoamEnabled) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in CONNECTED state, so deregister all events")); + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED); + } else { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in INIT state, Nothing to do")); + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Unexpected state %s, returning failure"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +#ifdef FEATURE_WLAN_ESE +VOS_STATUS csrNeighborRoamUpdateEseModeEnabled(tpAniSirGlobal pMac, const v_BOOL_t eseMode) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + if (VOS_TRUE == eseMode) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_CONNECT); + } else { +#endif + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pMac); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d"), vosStatus); + vosStatus = VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + else if (VOS_FALSE == eseMode) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in CONNECTED state, so deregister all events")); + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED); + } else { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in INIT state, Nothing to do")); + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Unexpected state %d, returning failure"), pNeighborRoamInfo->neighborRoamState); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +#endif + + +VOS_STATUS csrNeighborRoamSetLookupRssiThreshold(tpAniSirGlobal pMac, v_U8_t neighborLookupRssiThreshold) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in CONNECTED state, so deregister all and re-register for DOWN event again")); + + pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold = neighborLookupRssiThreshold; + pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold; + + /* De-register existing lookup UP/DOWN, Rssi indications */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_LOOKUP_THRESH_CHANGED); + } + else + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold); + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pMac); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d"), vosStatus); + vosStatus = VOS_STATUS_E_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + } + else if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Currently in INIT state, safe to set lookupRssi threshold")); + pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold = neighborLookupRssiThreshold; + pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold; + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Unexpected state %s, returning failure"), + macTraceGetNeighbourRoamState(pNeighborRoamInfo->neighborRoamState)); + vosStatus = VOS_STATUS_E_FAILURE; + } + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamReassocIndCallback + + \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold. + Directly triggere HO in case of non-11r association + In case of 11R association, triggers a pre-auth eventually followed by actual HO + + \param pAdapter - VOS Context + trafficStatus - UP/DOWN indication from TL + pUserCtxt - Parameter for callback registered during callback registration. Should be pMac + + \return VOID + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter, + v_U8_t trafficStatus, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (eSME_ROAM_TRIGGER_FAST_ROAM != pNeighborRoamInfo->cfgRoamEn) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. Threshold RSSI = %d Reported RSSI = %d"), + pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + avgRssi); + + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d"), vosStatus); + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Rcvd reassoc notification-deregister UP indication. Threshold RSSI = %d Reported RSSI = %d"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), avgRssi); + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupUPCallback with TL: Status = %d"), vosStatus); + } + } + /* We dont need to run this timer any more. */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + + csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo); + + return VOS_STATUS_SUCCESS; +} + +/*CleanUP Routines*/ +static void csrNeighborRoamResetChannelInfo(tpCsrNeighborRoamChannelInfo rChInfo) +{ + if ((rChInfo->IAPPNeighborListReceived == FALSE) && + (rChInfo->currentChannelListInfo.numOfChannels)) + { + rChInfo->currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; + rChInfo->currentChannelListInfo.numOfChannels = 0; + + if (rChInfo->currentChannelListInfo.ChannelList) + vos_mem_free(rChInfo->currentChannelListInfo.ChannelList); + + rChInfo->currentChannelListInfo.ChannelList = NULL; + rChInfo->chanListScanInProgress = eANI_BOOLEAN_FALSE; + } + else + { + rChInfo->currentChanIndex = 0; + rChInfo->chanListScanInProgress = eANI_BOOLEAN_TRUE; + } +} + +static void csrNeighborRoamResetCfgListChanScanControlInfo(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + /* Stop neighbor scan timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + + /* Stop neighbor scan results refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + + /* Stop empty scan results refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + + /* Abort any ongoing scan */ + if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending) + { + csrScanAbortMacScan(pMac, pNeighborRoamInfo->csrSessionId, + eCSR_SCAN_ABORT_DEFAULT); + } + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + /* Reset roam channel list information */ + csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo); +} + +static void csrNeighborRoamResetPreauthControlInfo(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE; + /* Purge pre-auth fail list */ + csrNeighborRoamPurgePreauthFailedList(pMac); +#endif + + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Do not free up the preauth done list here */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 0; + vos_mem_zero(&pNeighborRoamInfo->handoffReqInfo, sizeof(tCsrHandoffRequest)); +#endif + +} + +static void csrNeighborRoamDeregAllRssiIndication(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregister neighbor lookup UP callback with TL. RSSI = %d"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + + /* Deregister reassoc callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL("Couldn't deregister csrNeighborRoamNeighborLookupUPCallback " + "with TL: Status = %d"), vosStatus); + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregistering reassoc DOWN callback with TL. RSSI = %d"), + pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1)); + + /* Deregister reassoc callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with " + "TL: Status = %d"), vosStatus); + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Deregistering neighborLookup DOWN callback with TL. RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + + /* Deregister neighbor lookup callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback " + "with TL: Status = %d"), vosStatus); + } + + /* Reset thresholds only after deregistering DOWN event from TL */ + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->lookupDOWNRssi = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; +#endif +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamResetConnectedStateControlInfo + + \brief This function will reset the neighbor roam control info data structures. + This function should be invoked whenever we move to CONNECTED state from + any state other than INIT state + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + csrNeighborRoamResetChannelInfo(&pNeighborRoamInfo->roamChannelInfo); + csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList); + + /* We dont need to run this timer any more. */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Do not free up the preauth done list here */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0; + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 0; + vos_mem_zero(&pNeighborRoamInfo->handoffReqInfo, sizeof(tCsrHandoffRequest)); +#endif +} + +void csrNeighborRoamResetReportScanStateControlInfo(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID; + vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0); +#ifdef FEATURE_WLAN_ESE + pNeighborRoamInfo->isESEAssoc = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->MinQBssLoadRequired = 0; +#endif + + /* Stop scan refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + /* Stop empty scan results refresh timer */ + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + /* Purge roamable AP list */ + csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList); + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamResetInitStateControlInfo + + \brief This function will reset the neighbor roam control info data structures. + This function should be invoked whenever we move to CONNECTED state from + INIT state + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac) +{ + csrNeighborRoamResetConnectedStateControlInfo(pMac); + + /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */ + csrNeighborRoamResetReportScanStateControlInfo(pMac); +} + + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamBssIdScanFilter + + \brief This API is used to prepare a filter to obtain scan results when + we complete the scan in the REPORT_SCAN state after receiving a + valid neighbor report from AP. This filter includes BSSIDs received from + the neighbor report from the AP in addition to the other filter parameters + created from connected profile + + \param pMac - The handle returned by macOpen. + pScanFilter - Scan filter to be filled and returned + + \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error + code otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 i = 0; + + VOS_ASSERT(pScanFilter != NULL); + if (pScanFilter == NULL) + return eHAL_STATUS_FAILURE; + vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter)); + + pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport; + pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + if (NULL == pScanFilter->BSSIDs.bssid) + { + smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + + /* Populate the BSSID from Neighbor BSS info received from neighbor report */ + for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) + { + vos_mem_copy(&pScanFilter->BSSIDs.bssid[i], + pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr)); + } + + /* Fill other general scan filter params */ + return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter); +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPurgePreauthFailList + + \brief This function empties the preauth fail list + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list")); + while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress) + { + vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1], + sizeof(tSirMacAddr)); + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--; + } + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamAddBssIdToPreauthFailList + + \brief This function adds the given BSSID to the Preauth fail list + + \param pMac - The handle returned by macOpen. + bssId - BSSID to be added to the preauth fail list + + \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID "MAC_ADDRESS_STR" to Preauth failed list"), + MAC_ADDR_ARRAY(bssId)); + + + if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) > + MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS) + { + smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one")); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[ + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress], + bssId, + sizeof(tSirMacAddr)); + pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++; + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIsPreauthCandidate + + \brief This function checks whether the given MAC address is already + present in the preauth fail list and returns TRUE/FALSE accordingly + + \param pMac - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId) +{ + tANI_U8 i = 0; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + return eANI_BOOLEAN_TRUE; + } +#endif + if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress) + return eANI_BOOLEAN_TRUE; + + for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++) + { + if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i], + bssId, sizeof(tSirMacAddr))) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID "MAC_ADDRESS_STR" already present in preauth fail list"), + MAC_ADDR_ARRAY(bssId)); + return eANI_BOOLEAN_FALSE; + } + } + + return eANI_BOOLEAN_TRUE; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIssuePreauthReq + + \brief This function issues preauth request to PE with the 1st AP entry in the + roamable AP list + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamBSSInfo pNeighborBssNode; + +#ifdef FEATURE_WLAN_LFR_METRICS + tCsrRoamInfo *roamInfo; +#endif + + /* This must not be true here */ + VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE); + + /* Issue Preauth request to PE here */ + /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */ + /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */ + /* If roamableAPList gets empty, should transition to REPORT_SCAN state */ + pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL); + + if (NULL == pNeighborBssNode) + { + smsLog(pMac, LOGW, FL("Roamable AP list is empty.. ")); + return eHAL_STATUS_FAILURE; + } + else + { +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth initiation metric. + Send the event to supplicant that pre-auth was initiated */ + roamInfo = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfo) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfo->bssid, + (void *)pNeighborBssNode->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, + roamInfo, 0, eCSR_ROAM_PREAUTH_INIT_NOTIFY, 0); + vos_mem_free(roamInfo); + } +#endif + + status = csrRoamEnqueuePreauth(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription, + eCsrPerformPreauth, eANI_BOOLEAN_TRUE); + + smsLog(pMac, LOG1, FL("Before Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"), + MAC_ADDR_ARRAY(pNeighborBssNode->pBssDescription->bssId), + (int)pNeighborBssNode->pBssDescription->channelId); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d"), status); + return status; + } + } + + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE; + + /* Increment the preauth retry count */ + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++; + + /* Transition the state to preauthenticating */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPreauthRspHandler + + \brief This function handle the Preauth response from PE + Every preauth is allowed max 3 tries if it fails. If a bssid failed + for more than MAX_TRIES, we will remove it from the list and try + with the next node in the roamable AP list and add the BSSID to pre-auth failed + list. If no more entries present in + roamable AP list, transition to REPORT_SCAN state + + \param pMac - The handle returned by macOpen. + limStatus - eSIR_SUCCESS/eSIR_FAILURE/eSIR_LIM_MAX_STA_REACHED_ERROR/ + eSIT_LIM_AUTH_RSP_TIMEOUT status from PE + + \return eHAL_STATUS_SUCCESS on success (i.e. pre-auth processed), + eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, tSirRetStatus limStatus) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus preauthProcessed = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL; + tCsrRoamSession *pSession; +#ifdef FEATURE_WLAN_LFR_METRICS + tCsrRoamInfo *roamInfo; +#endif + + if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->FTRoamInfo.preauthRspPending) + { + + /* This can happen when we disconnect immediately + * after sending a pre-auth request. During processing + * of the disconnect command, we would have reset + * preauthRspPending and transitioned to INIT state. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + FL("Unexpected pre-auth response in state %d"), + pNeighborRoamInfo->neighborRoamState); + preauthProcessed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + + // We can receive it in these 2 states. + if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) && + (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + FL("Preauth response received in state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + preauthProcessed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + + pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE; + + if (eSIR_SUCCESS == limStatus) + { + pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL); + } + if ((eSIR_SUCCESS == limStatus) && (NULL != pPreauthRspNode)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Preauth completed successfully after %d tries"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries); + + smsLog(pMac, LOG1, FL("After Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"), + MAC_ADDR_ARRAY(pPreauthRspNode->pBssDescription->bssId), + (int)pPreauthRspNode->pBssDescription->channelId); + +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth completion metric. + Send the event to supplicant that pre-auth successfully completed */ + roamInfo = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfo) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfo->bssid, + (void *)pPreauthRspNode->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, + roamInfo, 0, eCSR_ROAM_PREAUTH_STATUS_SUCCESS, 0); + vos_mem_free(roamInfo); + } +#endif + + /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */ + csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode); + csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK); + + /* Pre-auth completed successfully. Transition to PREAUTH Done state */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + + /* The caller of this function would start a timer and by the time it expires, supplicant should + have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */ + } + else + { + tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL; + tListElem *pEntry; + uint32_t retries; + + retries = pMac->sta_auth_retries_for_code17 > + CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES ? + pMac->sta_auth_retries_for_code17 : + CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES; + + smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = 0x%x"), + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, limStatus); + + /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */ + if ((pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= retries) || + ((eSIR_LIM_MAX_STA_REACHED_ERROR == limStatus) && + (pMac->sta_auth_retries_for_code17 == 0))) + { + /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */ + pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0; + + /* The one in the head of the list should be one with which we issued pre-auth and failed */ + pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK); + if(pEntry) + { + pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List); + /* Add the BSSID to pre-auth fail list if it is not requested by HDD */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!pNeighborRoamInfo->uOsRequestedHandoff) +#endif + { + status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId); + } + +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth completion metric. Send the event + to supplicant that pre-auth successfully completed */ + roamInfo = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfo) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfo->bssid, + (void *)pNeighborBssNode->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, + roamInfo, 0, eCSR_ROAM_PREAUTH_STATUS_FAILURE, 0); + vos_mem_free(roamInfo); + } +#endif + + /* Now we can free this node */ + csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode); + } + } + pSession = CSR_GET_SESSION(pMac, pNeighborRoamInfo->csrSessionId); + if ((NULL != pSession) && pSession->abortConnection) + { + smsLog(pMac, LOGE, FL(" Deauth in progress Abort preauth")); + goto abort_preauth; + } + + if (pMac->roam.pending_roam_disable) + { + smsLog(pMac, LOG1, FL("process pending roam disable")); + pMac->roam.configParam.isFastRoamIniFeatureEnabled = FALSE; + pMac->roam.pending_roam_disable = FALSE; + csrNeighborRoamUpdateFastRoamingEnabled(pMac, FALSE); + CSR_NEIGHBOR_ROAM_STATE_TRANSITION( + eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + goto DEQ_PREAUTH; + } + + /* Issue preauth request for the same/next entry */ + if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac)) + goto DEQ_PREAUTH; + +abort_preauth: +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + if(pNeighborRoamInfo->uOsRequestedHandoff) + { + pNeighborRoamInfo->uOsRequestedHandoff = 0; + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_PREAUTH_FAILED_FOR_ALL); + } + else if(pNeighborRoamInfo->isForcedInitialRoamTo5GH) + { + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 0; + smsLog(pMac, LOGE, FL("Forced 5G roaming preauth got failed" + "send RSO START cmd to fwr.")); + csrRoamOffloadScan(pMac,ROAM_SCAN_OFFLOAD_START,REASON_CONNECT); + } + else + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_RESTART, REASON_PREAUTH_FAILED_FOR_ALL); + } + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + } else + { +#endif + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN); + + /* Register Neighbor Lookup threshold callback with TL for UP event now */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No more pre-auth candidates-" + "register UP indication with TL. RSSI = %d,"), NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME, pMac); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d"), status); + } + + /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */ + status = vos_timer_start(&pNeighborRoamInfo->neighborResultsRefreshTimer, + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d"), status); + } + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + +DEQ_PREAUTH: + csrRoamDequeuePreauth(pMac); + return preauthProcessed; +} +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPrepareScanProfileFilter + + \brief This function creates a scan filter based on the currently connected profile. + Based on this filter, scan results are obtained + + \param pMac - The handle returned by macOpen. + pScanFilter - Populated scan filter based on the connected profile + + \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId; + tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + tANI_U8 i = 0; + + VOS_ASSERT(pScanFilter != NULL); + if (pScanFilter == NULL) + return eHAL_STATUS_FAILURE; + + vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter)); + + /* We dont want to set BSSID based Filter */ + pScanFilter->BSSIDs.numOfBSSIDs = 0; + + //only for HDD requested handoff fill in the BSSID in the filter +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pNeighborRoamInfo->uOsRequestedHandoff) + { + + smsLog(pMac, LOG1, FL("OS Requested Handoff")); + pScanFilter->BSSIDs.numOfBSSIDs = 1; + pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + if (NULL == pScanFilter->BSSIDs.bssid) + { + smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs); + + /* Populate the BSSID from handoff info received from HDD */ + for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++) + { + vos_mem_copy(&pScanFilter->BSSIDs.bssid[i], + pNeighborRoamInfo->handoffReqInfo.bssid, sizeof(tSirMacAddr)); + } + } +#endif + /* Populate all the information from the connected profile */ + pScanFilter->SSIDs.numOfSSIDs = 1; + pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if (NULL == pScanFilter->SSIDs.SSIDList) + { + smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + pScanFilter->SSIDs.SSIDList->handoffPermitted = 1; + pScanFilter->SSIDs.SSIDList->ssidHidden = 0; + pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length; + vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length); + + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Filtering for SSID %.*s from scan results," + "length of SSID = %u"), + pScanFilter->SSIDs.SSIDList->SSID.length, + pScanFilter->SSIDs.SSIDList->SSID.ssId, + pScanFilter->SSIDs.SSIDList->SSID.length); + pScanFilter->authType.numEntries = 1; + pScanFilter->authType.authType[0] = pCurProfile->AuthType; + + pScanFilter->EncryptionType.numEntries = 1; //This must be 1 + pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType; + + pScanFilter->mcEncryptionType.numEntries = 1; + pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType; + + pScanFilter->BSSType = pCurProfile->BSSType; + + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels) + { + /* We are intrested only in the scan results on channels that we scanned */ + pScanFilter->ChannelInfo.numOfChannels = + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; + pScanFilter->ChannelInfo.ChannelList = + vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8)); + if (NULL == pScanFilter->ChannelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed")); + vos_mem_free(pScanFilter->SSIDs.SSIDList); + pScanFilter->SSIDs.SSIDList = NULL; + return eHAL_STATUS_FAILED_ALLOC; + } + for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++) + { + pScanFilter->ChannelInfo.ChannelList[i] = + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]; + } + } + else + { + pScanFilter->ChannelInfo.numOfChannels = 0; + pScanFilter->ChannelInfo.ChannelList = NULL; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->PERroamCandidatesCnt) + pScanFilter->isPERRoamScan = true; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pNeighborRoamInfo->is11rAssoc) + { + /* MDIE should be added as a part of profile. This should be added as a part of filter as well */ + pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent; + pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain; + } +#endif + +#ifdef WLAN_FEATURE_11W + pScanFilter->MFPEnabled = pCurProfile->MFPEnabled; + pScanFilter->MFPRequired = pCurProfile->MFPRequired; + pScanFilter->MFPCapable = pCurProfile->MFPCapable; +#endif + + return eHAL_STATUS_SUCCESS; +} + +tANI_U32 csrGetCurrentAPRssi(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList) +{ + tCsrScanResultInfo *pScanResult; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; +#ifdef FEATURE_WLAN_LFR + tANI_U32 CurrAPRssi = pNeighborRoamInfo->lookupDOWNRssi; +#else + /* We are setting this as default value to make sure we return this value, + when we do not see this AP in the scan result for some reason.However,it is + less likely that we are associated to an AP and do not see it in the scan list */ + tANI_U32 CurrAPRssi = -125; +#endif + + while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList))) + { + + if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr))) + { + /* We got a match with the currently associated AP. + * Capture the RSSI value and complete the while loop. + * The while loop is completed in order to make the current entry go back to NULL, + * and in the next while loop, it properly starts searching from the head of the list. + * TODO: Can also try setting the current entry directly to NULL as soon as we find the new AP*/ + + CurrAPRssi = (int)pScanResult->BssDescriptor.rssi * (-1) ; + + } else { + continue; + } + } + + return CurrAPRssi; + +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamProcessScanResults + + \brief This function extracts scan results, sorts on the basis of neighbor score(todo). + Assumed that the results are already sorted by RSSI by csrScanGetResult + + \param pMac - The handle returned by macOpen. + pScanResultList - Scan result result obtained from csrScanGetResult() + + \return tANI_BOOLEAN - return TRUE if we have a candidate we can immediately + roam to. Otherwise, return FALSE. + +---------------------------------------------------------------------------*/ + +static tANI_BOOLEAN csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac, + tScanResultHandle *pScanResultList) +{ + tCsrScanResultInfo *pScanResult; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tpCsrNeighborRoamBSSInfo pBssInfo; + tANI_U32 CurrAPRssi; + tANI_U8 RoamRssiDiff = pMac->roam.configParam.RoamRssiDiff; +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + tANI_U8 immediateRoamRssiDiff = pMac->roam.configParam.nImmediateRoamRssiDiff; +#endif + tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE; + + /*************************************************************** + * Find out the Current AP RSSI and keep it handy to check if + * it is better than the RSSI of the AP which we are + * going to roam.If so, we are going to continue with the + * current AP. + ***************************************************************/ + CurrAPRssi = csrGetCurrentAPRssi(pMac, pScanResultList); + + /* Expecting the scan result already to be in the sorted order based on the RSSI */ + /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */ + /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS. + If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */ + /* For now, let us take the top of the list provided as it is by the CSR Scan result API. This means it is assumed that neighbor score + and rssi score are in the same order. This will be taken care later */ + + while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList))) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("Scan result: BSSID "MAC_ADDRESS_STR" (Rssi %ld, Ch:%d)"), + MAC_ADDR_ARRAY(pScanResult->BssDescriptor.bssId), + abs(pScanResult->BssDescriptor.rssi), + pScanResult->BssDescriptor.channelId); + + if ((VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr))) || + ((eSME_ROAM_TRIGGER_SCAN == pNeighborRoamInfo->cfgRoamEn) && + (VOS_TRUE != vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->cfgRoambssId, sizeof(tSirMacAddr))))) + { + /* currently associated AP. Do not have this in the roamable AP list */ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "SKIP-currently associated AP"); + continue; + } + + if (vos_concurrent_open_sessions_running() && + !pMac->roam.configParam.fenableMCCMode && + (pScanResult->BssDescriptor.channelId != + csrGetConcurrentOperationChannel(pMac))) { + smsLog(pMac, LOG1, FL("MCC not supported so Ignore AP on channel %d"), + pScanResult->BssDescriptor.channelId); + continue; + } + +#ifdef FEATURE_WLAN_LFR +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* In case of reassoc requested by upper layer, look for exact match of bssid & channel; + csr cache might have duplicates*/ + if ((pNeighborRoamInfo->uOsRequestedHandoff) && + ((VOS_FALSE == vos_mem_compare(pScanResult->BssDescriptor.bssId, + pNeighborRoamInfo->handoffReqInfo.bssid, + sizeof(tSirMacAddr)))|| + (pScanResult->BssDescriptor.channelId != pNeighborRoamInfo->handoffReqInfo.channel))) + + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "SKIP-not a candidate AP for OS requested roam"); + continue; + } +#endif +#endif + +#ifdef FEATURE_WLAN_LFR +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pNeighborRoamInfo->isForcedInitialRoamTo5GH) + { + //Below check is required because scanning for forced initial roaming we have not + //flush all the 2.4 GHz Channel, so it may possbile we may roam again to + //2.4 Ghz ap only. + if(GetRFBand(pScanResult->BssDescriptor.channelId) != SIR_BAND_5_GHZ) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Forced Roam to 5G Skip Non 5G Scan results ", __func__); + continue; + } + + //rssi's are -ve value, so if abs of rssi is greater + //means new ap is poor then currently connected ap. + //Check it is only poor within nSelect5GHzMargin value. + if (abs(pScanResult->BssDescriptor.rssi) > abs(CurrAPRssi) && + ((abs(pScanResult->BssDescriptor.rssi) - abs(CurrAPRssi)) + > pMac->roam.configParam.nSelect5GHzMargin) + ) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Forced Roam to 5G Current AP rssi=%d new ap rssi=%d not good enough, nSelect5GHzMargin=%d", __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1), + pMac->roam.configParam.nSelect5GHzMargin); + continue; + } + + } +#endif +#endif + + /* This condition is to ensure to roam to an AP with better RSSI. if the value of RoamRssiDiff is Zero, this feature + * is disabled and we continue to roam without any check*/ + if ((RoamRssiDiff > 0) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + && ((eSME_ROAM_TRIGGER_SCAN != pNeighborRoamInfo->cfgRoamEn) && + (eSME_ROAM_TRIGGER_FAST_ROAM != pNeighborRoamInfo->cfgRoamEn))) + { + /* + * If RSSI is lower than the lookup threshold, then continue. + */ + if (abs(pScanResult->BssDescriptor.rssi) > + pNeighborRoamInfo->currentNeighborLookupThreshold) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] new ap rssi (%d) lower than lookup threshold (%d)", + __func__, (int)pScanResult->BssDescriptor.rssi * (-1), + (int)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + continue; + } + + if (abs(CurrAPRssi) < abs(pScanResult->BssDescriptor.rssi)) + { + /*Do not roam to an AP with worse RSSI than the current*/ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]Current AP rssi=%d new ap rssi worse=%d", __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1) ); + continue; + } else { + /*Do not roam to an AP which is having better RSSI than the current AP, but still less than the + * margin that is provided by user from the ini file (RoamRssiDiff)*/ + if (abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) < RoamRssiDiff) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]Current AP rssi=%d new ap rssi=%d not good enough, roamRssiDiff=%d", __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1), + RoamRssiDiff); + continue; + } + else { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG]Current AP rssi=%d new ap rssi better=%d", __func__, + CurrAPRssi, + (int)pScanResult->BssDescriptor.rssi * (-1) ); + } + } + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pNeighborRoamInfo->is11rAssoc) + { + if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId)) + { + smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring")); + continue; + } + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +#ifdef FEATURE_WLAN_ESE +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + if (pNeighborRoamInfo->isESEAssoc) + { + if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId)) + { + smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring")); + continue; + } + } + if ((pScanResult->BssDescriptor.QBSSLoad_present) && + (pScanResult->BssDescriptor.QBSSLoad_avail)) + { + if (pNeighborRoamInfo->isVOAdmitted) + { + smsLog(pMac, LOG1, FL("New AP has %x BW available"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail); + smsLog(pMac, LOG1, FL("We need %x BW available"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired); + if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "[INFOLOG]BSSID : "MAC_ADDRESS_STR" has no bandwidth ignoring..not adding to roam list", + MAC_ADDR_ARRAY(pScanResult->BssDescriptor.bssId)); + continue; + } + } + } + else + { + smsLog(pMac, LOGE, FL("No QBss %x %x"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present); + if (pNeighborRoamInfo->isVOAdmitted) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "[INFOLOG]BSSID : "MAC_ADDRESS_STR" has no QBSSLoad IE, ignoring..not adding to roam list", + MAC_ADDR_ARRAY(pScanResult->BssDescriptor.bssId)); + continue; + } + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif +#endif /* FEATURE_WLAN_ESE */ + +#ifdef FEATURE_WLAN_LFR + // If we are supporting legacy roaming, and + // if the candidate is on the "pre-auth failed" list, ignore it. + if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID)) + { + if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId)) + { + smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring")); + continue; + } + } +#endif /* FEATURE_WLAN_LFR */ + + /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip + * this result */ + if ((pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) + { + smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp")); + continue; + } + + pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo)); + if (NULL == pBssInfo) + { + smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring")); + continue; + } + + pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length)); + if (pBssInfo->pBssDescription != NULL) + { + vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor, + pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length)); + } + else + { + smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring")); + vos_mem_free(pBssInfo); + continue; + + } + pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score + + /* Just add to the end of the list as it is already sorted by RSSI */ + csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK); + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if ((eSME_ROAM_TRIGGER_SCAN == pNeighborRoamInfo->cfgRoamEn) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn)) + { + roamNow = eANI_BOOLEAN_FALSE; + } + else if ((abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)) >= immediateRoamRssiDiff) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && !csrRoamIsRoamOffloadScanEnabled(pMac) +#endif + ) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] potential candidate to roam immediately (diff=%ld, expected=%d)", + __func__, abs(abs(CurrAPRssi) - abs(pScanResult->BssDescriptor.rssi)), + immediateRoamRssiDiff); + roamNow = eANI_BOOLEAN_TRUE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /* If we are here means, FW already found candidates to roam, so we are + good to go with pre-auth */ + if(csrRoamIsRoamOffloadScanEnabled(pMac)) + { + roamNow = eANI_BOOLEAN_TRUE; + } +#endif +#endif + } + + /* Now we have all the scan results in our local list. Good time to free up the the list we got as a part of csrGetScanResult */ + csrScanResultPurge(pMac, *pScanResultList); + + return roamNow; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamHandleEmptyScanResult + + \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when + there are no valid APs in the scan result for roaming. This means + our AP is the best and no other AP is around. No point in scanning + again and again. Performing the following here. + 1. Stop the neighbor scan timer. + 2a. If this is the first time we encountered empty scan, then + re-register with TL with modified lookup threshold. + 2b. Else if this is the second time we encountered empty scan, + then start neighbor scan results refresh timer (20s). + 2c. Else, nothing more to do. + NOTE: In LFR, channels selected for scanning is dervied from + the occuped channel list. Scan cycle following one which + yielded empty results is split into two halves: (i) scan on + channels in the occupied list, and (ii) scan on channels not + in the occupied list. This helps converging faster (while + looking for candidates in the occupied list first), and also, + adds channels to the occupied channel list upon finding candidates + matching SSID profile of interest. + + uEmptyScanCount Comments + eFirstEmptyScan Previous scan was done on channels in the + occupied list and yielded potential candidates. + This scan cycle was likely triggered through + receipt of lookup DOWN notification event. + eSecondEmptyScan Previous scan was done on channels in the + occupied list and yielded no candidates. This scan + cycle was triggered through RSSI notification + with modified lookup threshold. + eThirdEmptyScan Previous scan was done on channels NOT in + the occupied list and yielded no candidates. This + scan cycle was triggered immediately after scanning + channels in the occupied list and no candidates + were found. + eFourthEmptyScan Previous scan was done on channels in the + occupied list and yielded no candidates. This scan + cycle was triggered upon expiry of + neighborScanResultsRefreshPeriod (=20s). + eFifthEmptyScan Previous scan was done on channels NOT in + the occupied list and yielded no candidates. This + scan cycle was triggered immediately after scanning + channels in the occupied list and no candidates + were found. + + [1], [2,3] and [4,5] together form one discrete set of scan cycle. + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; +#ifdef FEATURE_WLAN_LFR + tANI_BOOLEAN performPeriodicScan = + (pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod) ? TRUE : FALSE; +#endif + + /* Stop neighbor scan timer */ + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + /* + * Increase the neighbor lookup threshold by 3 dB + * after every scan cycle. NOTE: uEmptyScanCount + * would be either 1, 3 or 5 at the end of every + * scan cycle. + */ +#ifdef FEATURE_WLAN_LFR + if ((++pNeighborRoamInfo->uEmptyScanCount) > eFifthEmptyScan) + { + pNeighborRoamInfo->uEmptyScanCount = eFifthEmptyScan; + } + if (((0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) || + (abs(pNeighborRoamInfo->lookupDOWNRssi) > + abs(pNeighborRoamInfo->cfgParams.neighborReassocThreshold))) && + ((pNeighborRoamInfo->uEmptyScanCount == eSecondEmptyScan) || + (pNeighborRoamInfo->uEmptyScanCount == eFourthEmptyScan))) + { + /* + * If the scan was triggered due to lookupDOWNRssi > reassoc threshold, + * then it would be a contiguous scan on all valid non-DFS channels. + * If channels are configured in INI, then only those channels need + * to be scanned. + * In either of these modes, there is no need to trigger an immediate + * scan upon empty scan results for the second and fourth time (which + * would be equivalent to scanning on channels in non-occupied list). + * Incrementing uEmptyScanCount will correspond to skipping this step. + * NOTE: double increment of uEmptyScanCount corresponds to completion + * of scans on all valid channels. + */ + ++pNeighborRoamInfo->uEmptyScanCount; + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Extra increment of empty scan count (=%d)" + " in contiguous scan mode", pNeighborRoamInfo->uEmptyScanCount); + } +#endif + if (((pNeighborRoamInfo->currentNeighborLookupThreshold+3) < + pNeighborRoamInfo->cfgParams.neighborReassocThreshold) +#ifdef FEATURE_WLAN_LFR + && ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1) +#endif + ) + { + pNeighborRoamInfo->currentNeighborLookupThreshold += 3; + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + /* Clear off the old neighbor report details */ + vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); +#endif + + /* Transition to CONNECTED state */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + + /* Reset all the necessary variables before transitioning to the CONNECTED state */ + csrNeighborRoamResetConnectedStateControlInfo(pMac); + +#ifdef FEATURE_WLAN_LFR + if (pNeighborRoamInfo->uEmptyScanCount == eFirstEmptyScan) + { +#endif + /* Empty scan results for the first time */ + /* Re-register neighbor lookup DOWN threshold callback with TL */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"), + pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pMac); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL("Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback" + " with TL: Status = %d"), status); + } +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; + } + else if ((pNeighborRoamInfo->uEmptyScanCount == eSecondEmptyScan) || + (pNeighborRoamInfo->uEmptyScanCount == eFourthEmptyScan)) + { + /* Empty scan results for the second or fourth time */ + + /* Immediately scan on channels in non-occupied list */ + csrNeighborRoamTransitToCFGChanScan(pMac); + } + else if (pNeighborRoamInfo->uEmptyScanCount >= eThirdEmptyScan) + { + /* Empty scan results for the third time */ + if (performPeriodicScan) + { + smsLog(pMac, LOGE, FL("Performing periodic scan, uEmptyScanCount=%d"), + pNeighborRoamInfo->uEmptyScanCount); + + /* + * Set uEmptyScanCount to MAX so that we always enter this + * condition on subsequent empty scan results + */ + pNeighborRoamInfo->uEmptyScanCount = eMaxEmptyScan; + + /* From here on, ONLY scan on channels in the occupied list */ + pNeighborRoamInfo->uScanMode = SPLIT_SCAN_OCCUPIED_LIST; + + /* Start empty scan refresh timer */ + if (VOS_STATUS_SUCCESS != + vos_timer_start(&pNeighborRoamInfo->emptyScanRefreshTimer, + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod)) + { + smsLog(pMac, LOGE, FL("Empty scan refresh timer failed to start (%d)"), + status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + vosStatus = VOS_STATUS_E_FAILURE; + } + else + { + smsLog(pMac, LOGE, FL("Empty scan refresh timer started (%d ms)"), + (pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod)); + } + } + else if (eThirdEmptyScan == pNeighborRoamInfo->uEmptyScanCount) + { + /* Start neighbor scan results refresh timer */ + if (VOS_STATUS_SUCCESS != + vos_timer_start(&pNeighborRoamInfo->neighborResultsRefreshTimer, + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod)) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start (%d)"), + status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + vosStatus = VOS_STATUS_E_FAILURE; + } + else + { + smsLog(pMac, LOG2, FL("Neighbor results refresh timer started (%d ms)"), + (pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT)); + } + } + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Neighbor roam empty scan count=%d scan mode=%d", + pNeighborRoamInfo->uEmptyScanCount, pNeighborRoamInfo->uScanMode); +#endif + return vosStatus; +} + + +static eHalStatus csrNeighborRoamProcessScanComplete (tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tCsrScanResultFilter scanFilter; + tScanResultHandle scanResult; + tANI_U32 tempVal = 0; + tANI_BOOLEAN roamNow = eANI_BOOLEAN_FALSE; + eHalStatus hstatus; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we + should use the BSSID filter made out of neighbor reports */ + if ((eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + && (!csrRoamIsRoamOffloadScanEnabled(pMac)) +#endif + ) + { + hstatus = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter); + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R or ESE Association: Prepare scan filter status with neighbor AP = %d"), hstatus); + tempVal = 1; + } + else +#endif + { + hstatus = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter); + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R/ESE/Other Association: Prepare scan to find neighbor AP filter status = %d"), hstatus); + } + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal); + return eHAL_STATUS_FAILURE; + } + hstatus = csrScanGetResult(pMac, &scanFilter, &scanResult); + if (hstatus != eHAL_STATUS_SUCCESS) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), hstatus); + } + /* Process the scan results and update roamable AP list */ + roamNow = csrNeighborRoamProcessScanResults(pMac, &scanResult); + + /* Free the scan filter */ + csrFreeScanFilter(pMac, &scanFilter); + + tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + switch(pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN: + if (tempVal) + { +#ifdef FEATURE_WLAN_LFR + /* + * Since there are non-zero candidates found + * after the scan, reset empty scan count. + */ + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + /* If this is a non-11r association, then we can register the reassoc callback here as we have some + APs in the roamable AP list */ + if (pNeighborRoamInfo->is11rAssoc) + { + /* Valid APs are found after scan. Now we can initiate pre-authentication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN) + } + else +#endif +#ifdef FEATURE_WLAN_ESE + /* If this is a non-11r association, then we can register the reassoc callback here as we have some + APs in the roamable AP list */ + if (pNeighborRoamInfo->isESEAssoc) + { + /* Valid APs are found after scan. Now we can initiate pre-authentication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN) + } + else +#endif +#ifdef FEATURE_WLAN_LFR + /* If LFR is enabled, then we can register the reassoc callback here as we have some + APs in the roamable AP list */ + if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID)) + { + /* Valid APs are found after scan. Now we can initiate pre-authentication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN) + } + else +#endif + { + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback")); + /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */ + /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we + need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL + within certain duration */ + +// vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + } + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, + FL("No candidate found after scanning in state %s .. "), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + /* Handle it appropriately */ + csrNeighborRoamHandleEmptyScanResult(pMac); + } + break; +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + if (!tempVal) + { + smsLog(pMac, LOGE, FL("No candidate found after scanning" + "in state %s .. "), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */ + csrNeighborRoamTransitToCFGChanScan(pMac); + } + break; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + default: + // Can come only in INIT state. Where in we are associated, we sent scan and user + // in the meantime decides to disassoc, we will be in init state and still received call + // back issued. Should not come here in any other state, printing just in case + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("State %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + + // Lets just exit out silently. + return eHAL_STATUS_SUCCESS; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + if (tempVal) + { + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (roamNow) + { +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if(!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, + FL("Immediate roam-deregister UP indication. RSSI = %d"), + NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, LOGW, + FL("Couldn't deregister lookup UP callback with TL: Status = %d"), vosStatus); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + hstatus = csrNeighborRoamTriggerHandoff(pMac,pNeighborRoamInfo); + if(eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, + FL("csrNeighborRoamTriggerHandoff fail status = %d"), + hstatus); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + + hstatus = vos_timer_start(&pNeighborRoamInfo->neighborResultsRefreshTimer, + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod); + + /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely + * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */ + if( hstatus != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), hstatus); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + return eHAL_STATUS_FAILURE; + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1)); + /* Register a reassoc Indication callback */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME, pMac); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d"), vosStatus); + } + + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + if (!tempVal || !roamNow) + { + if((eSME_ROAM_TRIGGER_SCAN == pNeighborRoamInfo->cfgRoamEn) || + (eSME_ROAM_TRIGGER_FAST_ROAM == pNeighborRoamInfo->cfgRoamEn)) + { + //This is ioctl based roaming if we did not find any roamable + //candidate then just log it. + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "tempVal = %u, roamNow = %d uOsRequestedHandoff = %d", + tempVal, roamNow, pNeighborRoamInfo->uOsRequestedHandoff); + } + else if (pNeighborRoamInfo->isForcedInitialRoamTo5GH) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "No 5G candidate found tempVal=%u, roamNow=%d", + tempVal, roamNow); + return eHAL_STATUS_FAILURE; + } + else + { + if (pNeighborRoamInfo->uOsRequestedHandoff) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, + REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + pNeighborRoamInfo->uOsRequestedHandoff = 0; + } + + else + { + /* There is no candidate or We are not roaming Now. + * Inform the FW to restart Roam Offload Scan */ + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_RESTART, + REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + } + } + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + } + } +#endif + return eHAL_STATUS_SUCCESS; +} + + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamScanRequestCallback + + \brief This function is the callback function registered in csrScanRequest() to + indicate the completion of scan. If scan is completed for all the channels in + the channel list, this function gets the scan result and starts the refresh results + timer to avoid having stale results. If scan is not completed on all the channels, + it restarts the neighbor scan timer which on expiry issues scan on the next + channel + + \param halHandle - The handle returned by macOpen. + pContext - not used + scanId - not used + status - not used + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 currentChanIndex; + eHalStatus hstatus; +#ifdef FEATURE_WLAN_LFR + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + + if (NULL != pContext) + { + sessionId = *((tANI_U32*)pContext); + + if (!csrRoamIsStaMode(pMac, sessionId)) + { + smsLog(pMac, LOGE, FL("Ignoring scan request callback on non-infra" + "session %d in state %s"), + sessionId, macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + if (!csrRoamIsFastRoamEnabled(pMac,sessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + } +#endif + pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE; + + /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */ + currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0; + + /* Validate inputs */ + if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"), + pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex); + } + else + { + smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event.")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress) + { + /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state + just to get the results and perform PREAUTH */ + /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter + sort the results based on neighborScore and RSSI and select the best candidate out of the list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex); + VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0); + + hstatus = csrNeighborRoamProcessScanComplete(pMac); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_FAILURE; + } + } + else + { + + /* Restart the timer for the next scan sequence as scanning is not over */ + hstatus = vos_timer_start(&pNeighborRoamInfo->neighborScanTimer, + pNeighborRoamInfo->cfgParams.neighborScanPeriod); + if (eHAL_STATUS_SUCCESS != hstatus) + { + /* Timer start failed.. Should we ASSERT here??? */ + smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_FAILURE; + } + } + + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamScanResultRequestCallback + + \brief This function is the callback function registered in csrScanRequestLfrResult() to + indicate the completion of scan. If scan is completed for all the channels in + the channel list, this function gets the scan result and treats them as candidates + + \param halHandle - The handle returned by macOpen. + pContext - not used + scanId - not used + status - not used + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +static eHalStatus csrNeighborRoamScanResultRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus hstatus; + + smsLog(pMac, LOG2, FL("called ")); + pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE; + + /* we must be in connected state, if not ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGW, FL("Received in not CONNECTED state. Ignore it")); + return eHAL_STATUS_SUCCESS; + } + + /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter + sort the results based on neighborScore and RSSI and select the best candidate out of the list */ + + hstatus = csrNeighborRoamProcessScanComplete(pMac); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef FEATURE_WLAN_LFR +static eHalStatus csrNeighborRoamForceRoamTo5GhScanCb(tHalHandle halHandle, + void *pContext, tANI_U32 scanId, eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus hstatus = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + + if (NULL != pContext) + { + sessionId = *((tANI_U32*)pContext); + if (!csrRoamIsFastRoamEnabled(pMac,sessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + hstatus = eHAL_STATUS_FAILURE; + goto end; + } + } + + pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE; + + if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in neighborRoamState %d . Ignore it"), + pNeighborRoamInfo->neighborRoamState); + hstatus = eHAL_STATUS_FAILURE; + goto end; + } + + //keep track of forced 5G scan & roam is due to Forced initial roam to 5GHz + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 1; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "%s: process scan results", __func__); + hstatus = csrNeighborRoamProcessScanComplete(pMac); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Force Roam To 5GhScanCb failed with status %d"), + hstatus); + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 0; + /* + * Send RSO start because in case 5G roaming host have + * not enabled at initial connection + */ + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_CONNECT); + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + } + + if (NULL != pContext) + vos_mem_free(pContext); + return hstatus; + +end: + if (NULL != pContext) + vos_mem_free(pContext); + return hstatus; +} +#endif + +#ifdef FEATURE_WLAN_LFR +static eHalStatus csrNeighborRoamContiguousScanRequestCallback(tHalHandle halHandle, + void *pContext, tANI_U32 scanId, eCsrScanStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus hstatus = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId = CSR_SESSION_ID_INVALID; + + if (NULL != pContext) + { + sessionId = *((tANI_U32*)pContext); + if (!csrRoamIsFastRoamEnabled(pMac,sessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + } + + pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE; + + /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in INIT state. Must have disconnected. Ignore it")); + if (NULL != pContext) + vos_mem_free(pContext); + return eHAL_STATUS_SUCCESS; + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "%s: process scan results", __func__); + hstatus = csrNeighborRoamProcessScanComplete(pMac); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + } + + if (NULL != pContext) + vos_mem_free(pContext); + + return hstatus; +} +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIssueBgScanRequest + + \brief This function issues CSR scan request after populating all the BG scan params + passed + + \param pMac - The handle returned by macOpen. + pBgScanParams - Params that need to be populated into csr Scan request + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, + tCsrBGScanRequest *pBgScanParams, + tANI_U32 sessionId, + csrScanCompleteCallback callbackfn) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 scanId; + tCsrScanRequest scanReq; + tANI_U8 channel; + void * userData = NULL; + + if (1 == pBgScanParams->ChannelInfo.numOfChannels) + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel = %d, ChanIndex = %d"), + pBgScanParams->ChannelInfo.ChannelList[0], + pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex); + + //send down the scan req for 1 channel on the associated SSID + vos_mem_set(&scanReq, sizeof(tCsrScanRequest), 0); + /* Fill in the SSID Info */ + scanReq.SSIDs.numOfSSIDs = 1; + scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs); + if (NULL == scanReq.SSIDs.SSIDList) + { + //err msg + smsLog(pMac, LOGE, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List")); + return eHAL_STATUS_FAILURE; + } + vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs); + + scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE; + scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE; + vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID)); + + scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels; + if (1 == pBgScanParams->ChannelInfo.numOfChannels) + { + channel = pBgScanParams->ChannelInfo.ChannelList[0]; + scanReq.ChannelInfo.ChannelList = &channel; + } + else + { + scanReq.ChannelInfo.ChannelList = pBgScanParams->ChannelInfo.ChannelList; + } + + scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE; + scanReq.scanType = eSIR_ACTIVE_SCAN; + scanReq.requestType = eCSR_SCAN_HO_BG_SCAN; + scanReq.maxChnTime = pBgScanParams->maxChnTime; + scanReq.minChnTime = pBgScanParams->minChnTime; + + userData = vos_mem_malloc(sizeof(tANI_U32)); + if (NULL == userData) + { + smsLog(pMac, LOGE, FL("Failed to allocate memory for scan request")); + vos_mem_free(scanReq.SSIDs.SSIDList); + return eHAL_STATUS_FAILURE; + } + *((tANI_U32*)userData) = sessionId; + status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq, + &scanId, callbackfn, (void *) userData); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status); + vos_mem_free(scanReq.SSIDs.SSIDList); + vos_mem_free(userData); + return status; + } + pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE; + + vos_mem_free(scanReq.SSIDs.SSIDList); + if (1 == pBgScanParams->ChannelInfo.numOfChannels) + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %p, Actual index = %d"), + &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0], + pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex); + + return status; +} + +static void csrNeighborRoamFillNonChannelBgScanParams (tpAniSirGlobal pMac, + tpCsrBGScanRequest bgScanParams) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + vos_mem_copy(bgScanParams->bssid, broadcastBssid, sizeof(tCsrBssid)); + bgScanParams->SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length; + vos_mem_copy(bgScanParams->SSID.ssId, + pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId, + pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length); + + bgScanParams->minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime; + bgScanParams->maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPerformBgScan + + \brief This function is invoked on every expiry of neighborScanTimer till all + the channels in the channel list are scanned. It populates necessary + parameters for BG scan and calls appropriate AP to invoke the CSR scan + request + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tCsrBGScanRequest bgScanParams; + tANI_U8 channel = 0; + + if ( pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList && + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels ) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Channel List Address = %p"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]); + } + else + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty")); + // Go back and restart. Mostly timer start failure has occurred. + // When timer start is declared a failure, then we delete the list. + // Should not happen now as we stop and then only start the scan timer. + // still handle the unlikely case. + csrNeighborRoamHandleEmptyScanResult(pMac); + return status; + } + + /* Validate the currentChanIndex value before using it to index the ChannelList array */ + if ( pNeighborRoamInfo->roamChannelInfo.currentChanIndex + > pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Invalid channel index: %d"), pNeighborRoamInfo->roamChannelInfo.currentChanIndex); + // Go back and restart. + csrNeighborRoamHandleEmptyScanResult(pMac); + return status; + } + + /* Need to perform scan here before getting the list */ + + vos_mem_set(&bgScanParams, sizeof(tCsrBGScanRequest), 0); + + channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex]; + bgScanParams.ChannelInfo.numOfChannels = 1; + bgScanParams.ChannelInfo.ChannelList = &channel; + + csrNeighborRoamFillNonChannelBgScanParams(pMac, &bgScanParams); + + /* Update the passive scan time for DFS channel */ + if ((TRUE == CSR_IS_CHANNEL_DFS(channel)) && + (TRUE == pMac->roam.configParam.allowDFSChannelRoam)) + { + bgScanParams.minChnTime = pMac->roam.configParam.nPassiveMinChnTime; + bgScanParams.maxChnTime = pMac->roam.configParam.nPassiveMaxChnTime; + } + + status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams, + sessionId, csrNeighborRoamScanRequestCallback); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status); + } + + pNeighborRoamInfo->roamChannelInfo.currentChanIndex++; + if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >= + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"), + pNeighborRoamInfo->roamChannelInfo.currentChanIndex, + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels); + /* We have completed scanning all the channels */ + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0; + /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results + and select the best AP in the list */ + if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress) + { + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE; + } + } + + if (eHAL_STATUS_SUCCESS != status) + { + /* + * If the status is not success, we need to call the callback + * routine so that the state machine does not get stuck. + */ + csrNeighborRoamScanRequestCallback(pMac, NULL, 0, eCSR_SCAN_FAILURE); + } + + return status; +} + +#ifdef FEATURE_WLAN_LFR +eHalStatus csrNeighborRoamScanForInitialForced5GRoaming(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBGScanRequest bgScanParams; + tANI_U8 numOfChannels = 0, i = 0; + tANI_U8 tempChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tANI_U8 tempNumOfChannels = 0; + + vos_mem_set(&bgScanParams, sizeof(tCsrBGScanRequest), 0); + /* Contiguously scan all channels from valid list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "%s: get valid channel list", __func__); + tempNumOfChannels = sizeof(pMac->roam.validChannelList); + + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + (tANI_U8 *)pMac->roam.validChannelList, + (tANI_U32 *) &tempNumOfChannels))) + { + //Make sure we are scanning only for 5Ghz AP only + //Filetring out the 5GHZ based AP.from valid channel list + csrNeighborRoamChannelsFilterByBand( + pMac, + pMac->roam.validChannelList, + tempNumOfChannels, + tempChannelList, + &tempNumOfChannels, + SIR_BAND_5_GHZ + ); + for (i = 0; (i < tempNumOfChannels &&(i < WNI_CFG_VALID_CHANNEL_LIST_LEN)); i++) + { + /* DFS channel will be added in the list only when the + DFS Roaming scan flag is enabled*/ + if (CSR_IS_CHANNEL_DFS(tempChannelList[i])) + { + if (pMac->roam.configParam.allowDFSChannelRoam == TRUE) + { + channelList[numOfChannels++] = tempChannelList[i]; + } + } + else + { + channelList[numOfChannels++] = tempChannelList[i]; + } + } + } + else + { + smsLog(pMac, LOGW, FL("csrGetCfgValidChannels got failed ")); + return eHAL_STATUS_FAILURE; + } + + if(numOfChannels == 0) + { + smsLog(pMac, LOGE, + FL(" No valid 5Ghz channel present so skipping Initial Forced 5Gh roaming")); + return VOS_STATUS_E_EMPTY; + } + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + + bgScanParams.ChannelInfo.numOfChannels = numOfChannels; + bgScanParams.ChannelInfo.ChannelList = channelList; + for (i = 0; i < numOfChannels; i++) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "%s: valid channel list = %d", + __func__, bgScanParams.ChannelInfo.ChannelList[i]); + } + csrNeighborRoamFillNonChannelBgScanParams(pMac, &bgScanParams); + + status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams, + sessionId, csrNeighborRoamForceRoamTo5GhScanCb); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Forced intial roam to 5Gh request failed: Status = %d"), status); + } + return status; +} +#endif + +#ifdef FEATURE_WLAN_LFR +eHalStatus csrNeighborRoamPerformContiguousBgScan(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrBGScanRequest bgScanParams; + tANI_U8 numOfChannels = 0, i = 0; + tANI_U8 *channelList = NULL; + tANI_U8 *pInChannelList = NULL; + tANI_U8 tmpChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + + vos_mem_set(&bgScanParams, sizeof(tCsrBGScanRequest), 0); + + /* Contiguously scan all channels from valid list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "%s: get valid channel list", __func__); + + numOfChannels = sizeof(pMac->roam.validChannelList); + + if(!HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + (tANI_U8 *)pMac->roam.validChannelList, + (tANI_U32 *) &numOfChannels))) + { + smsLog(pMac, LOGE, FL("Could not get valid channel list")); + return eHAL_STATUS_FAILURE; + } + pInChannelList = pMac->roam.validChannelList; + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByBand( + pMac, + pInChannelList, + numOfChannels, + tmpChannelList, + &numOfChannels, + GetRFBand(pMac->roam.neighborRoamInfo.currAPoperationChannel)); + pInChannelList = tmpChannelList; + } + + channelList = vos_mem_malloc(numOfChannels); + if ( NULL == channelList ) + { + smsLog(pMac, LOGE, FL("could not allocate memory for channelList")); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(channelList, (tANI_U8 *)pInChannelList, + numOfChannels * sizeof(tANI_U8)); + + bgScanParams.ChannelInfo.numOfChannels = numOfChannels; + bgScanParams.ChannelInfo.ChannelList = channelList; + for (i = 0; i < numOfChannels; i++) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "%s: valid channel list = %d", + __func__, bgScanParams.ChannelInfo.ChannelList[i]); + } + csrNeighborRoamFillNonChannelBgScanParams(pMac, &bgScanParams); + + status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams, + sessionId, csrNeighborRoamContiguousScanRequestCallback); + + vos_mem_free(channelList); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status); + } + + return status; +} +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborScanTimerCallback + + \brief This function is the neighbor scan timer callback function. It invokes + the BG scan request based on the current and previous states + + \param pv - CSR timer context info which includes pMac and session ID + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamNeighborScanTimerCallback(void *pv) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pv ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo; + if(!pMac) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("pMac is Null")); + return; + } + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + // check if bg scan is on going, no need to send down the new params if true + if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending) + { + //msg + smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending")); + return; + } + + switch (pNeighborRoamInfo->neighborRoamState) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + switch(pNeighborRoamInfo->prevNeighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY: + csrNeighborRoamPerformBgScan(pMac, pNeighborRoamInfo->csrSessionId); + break; + default: + smsLog(pMac, LOGE, FL("Neighbor scan callback received in" + "state %s, prev state = %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->prevNeighborRoamState)); + break; + } + break; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN: + csrNeighborRoamPerformBgScan(pMac, pNeighborRoamInfo->csrSessionId ); + break; + default: + break; + } + return; +} + +void csrNeighborRoamEmptyScanRefreshTimerCallback(void *context) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( context ); + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo; + if(!pMac) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("pMac is Null")); + return; + } + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + /* Reset all the variables just as no scan had happened before */ + csrNeighborRoamResetConnectedStateControlInfo(pMac); + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI + if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state")); + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return; + } + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY) + } + else +#endif + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or ESE Association:empty scan refresh timer expired")); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + return; + } + } + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamResultsRefreshTimerCallback + + \brief This function is the timer callback function for results refresh timer. + When this is invoked, it is as good as down event received from TL. So, + clear off the roamable AP list and start the scan procedure based on 11R + or non-11R association + + \param context - CSR timer context info which includes pMac and session ID + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamResultsRefreshTimerCallback(void *context) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( context ); + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo; + + if(!pMac) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("pMac is Null")); + return; + } + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1)); + + /* Deregister reassoc callback. Ignore return status */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamReassocIndCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d"), vosStatus); + } + + /* Reset all the variables just as no scan had happened before */ + csrNeighborRoamResetConnectedStateControlInfo(pMac); + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI + if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled)) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state")); + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return; + } + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY) + } + else +#endif + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or ESE Association:results refresh timer expired")); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + return; + } + } + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrForcedInitialRoamTo5GHTimerCallback + + \brief This function is the timer callback function for triggering + roaming to 5GHz after the initial association. + + \param context - CSR timer context info which includes pMac and session ID + + \return VOID + +---------------------------------------------------------------------------*/ + +void csrForcedInitialRoamTo5GHTimerCallback(void *context) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( context ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo; + if(!pMac) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("pMac is Null")); + return; + } + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("forcedInitialRoamTo5GHTimer timer expired")); + + //we don't need to run this timer any more + vos_timer_stop(&pNeighborRoamInfo->forcedInitialRoamTo5GHTimer); + + //we must be in connected state, if not ignore it + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it")); + return; + } + + //it may possible user reconnected / DUT roamed to other band ap btw + //timer started and timer callback hit. + if(GetRFBand(pMac->roam.neighborRoamInfo.currAPoperationChannel) == SIR_BAND_5_GHZ) + { + smsLog(pMac, LOGE, + FL("DUT is already connected to 5GH ap, so no need to trigger forced roam.")); + return; + } + + pNeighborRoamInfo->scanRequestTimeStamp = vos_timer_get_system_time(); + /* + * We are about to start a fresh scan cycle for all valid channles for 5Ghz + * purge non-P2P results from the past for 5Ghz band + */ + csrScanFlushSelectiveResultForBand(pMac, VOS_FALSE, SIR_BAND_5_GHZ); + status = csrNeighborRoamScanForInitialForced5GRoaming( + pMac, pNeighborRoamInfo->csrSessionId); + if(status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("csrNeighborRoamScanForInitialForced5GRoaming failed status=%d"), status); + //Send RSO start because in case 5G roaming host have not enabled at initial connection + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_CONNECT); + return; + } + + /* Transition to CFG_CHAN_LIST_SCAN */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN); +} + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIssueNeighborRptRequest + + \brief This function is invoked when TL issues a down event and the current assoc + is a 11R association. It invokes SME RRM API to issue the neighbor request to + the currently associated AP with the current SSID + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac) +{ + tRrmNeighborRspCallbackInfo callbackInfo; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tRrmNeighborReq neighborReq; + + + neighborReq.no_ssid = 0; + + /* Fill in the SSID */ + neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length; + vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId, + pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length); + + callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult; + callbackInfo.neighborRspCallbackContext = pMac; + callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout; + + return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo); +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamChannelsFilterByBand + + \brief This function is used to filter out the channels + based on the Band given as input + + \param pMac - The handle returned by macOpen. + \param pInputChannelList - The input channel list + \param inputNumOfChannels - The number of channels in input channel list + \param pOutputChannelList - The output channel list + \param outputNumOfChannels - The number of channels in output channel list + \param pMergedOutputNumOfChannels - The final number of channels in the output channel list. + \param band - The band which will be get compared with the input channel list band + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ + +VOS_STATUS csrNeighborRoamChannelsFilterByBand( + tpAniSirGlobal pMac, + tANI_U8* pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8* pOutputChannelList, + tANI_U8* pMergedOutputNumOfChannels, + tSirRFBand band + ) +{ + tANI_U8 i = 0; + tANI_U8 numChannels = 0; + + // Check for NULL pointer + if (!pInputChannelList) return VOS_STATUS_E_INVAL; + + // Check for NULL pointer + if (!pOutputChannelList) return VOS_STATUS_E_INVAL; + + if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Wrong Number of Input Channels %d", + __func__, inputNumOfChannels); + return VOS_STATUS_E_INVAL; + } + for (i = 0; i < inputNumOfChannels; i++) + { + if (band == GetRFBand(pInputChannelList[i])) + { + pOutputChannelList[numChannels] = pInputChannelList[i]; + numChannels++; + } + } + + // Return final number of channels + *pMergedOutputNumOfChannels = numChannels; + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamMergeChannelLists + + \brief This function is used to merge two channel list. + NB: If called with outputNumOfChannels == 0, this routines + simply copies the input channel list to the output channel list. + + \param pMac - The handle returned by macOpen. + \param pInputChannelList - The addtional channels to merge in to the "merged" channels list. + \param inputNumOfChannels - The number of additional channels. + \param pOutputChannelList - The place to put the "merged" channel list. + \param outputNumOfChannels - The original number of channels in the "merged" channels list. + \param pMergedOutputNumOfChannels - The final number of channels in the "merged" channel list. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamMergeChannelLists( + tpAniSirGlobal pMac, + tANI_U8 *pInputChannelList, + tANI_U8 inputNumOfChannels, + tANI_U8 *pOutputChannelList, + tANI_U8 outputNumOfChannels, + tANI_U8 *pMergedOutputNumOfChannels + ) +{ + tANI_U8 i = 0; + tANI_U8 j = 0; + tANI_U8 numChannels = outputNumOfChannels; + + // Check for NULL pointer + if (!pInputChannelList) return VOS_STATUS_E_INVAL; + + // Check for NULL pointer + if (!pOutputChannelList) return VOS_STATUS_E_INVAL; + + if (inputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Wrong Number of Input Channels %d", + __func__, inputNumOfChannels); + return VOS_STATUS_E_INVAL; + } + if (outputNumOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Wrong Number of Output Channels %d", + __func__, inputNumOfChannels); + return VOS_STATUS_E_INVAL; + } + + /* Add the "new" channels in the input list to the end of the output list. + Check added in for loop to make sure outputlist doesn't exceeds valid + channel list length. */ + for (i = 0; (i < inputNumOfChannels) && (numChannels < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++) + { + for (j = 0; j < outputNumOfChannels; j++) + { + if (pInputChannelList[i] == pOutputChannelList[j]) + break; + } + if (j == outputNumOfChannels) + { + if (pInputChannelList[i]) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] Adding extra %d to Neighbor channel list", __func__, + pInputChannelList[i]); + pOutputChannelList[numChannels] = pInputChannelList[i]; + numChannels++; + } + } + } + + // Return final number of channels + *pMergedOutputNumOfChannels = numChannels; + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamCreateChanListFromNeighborReport + + \brief This function is invoked when neighbor report is received for the + neighbor request. Based on the channels present in the neighbor report, + it generates channel list which will be used in REPORT_SCAN state to + scan for these neighbor APs + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac) +{ + tpRrmNeighborReportDesc pNeighborBssDesc; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 numChannels = 0; + tANI_U8 i = 0; + tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT]; + tANI_U8 mergedOutputNumOfChannels = 0; + + /* This should always start from 0 whenever we create a channel list out of neighbor AP list */ + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0; + + pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac); + + while (pNeighborBssDesc) + { + if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break; + + /* Update the neighbor BSS Info in the 11r FT Roam Info */ + pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum = + pNeighborBssDesc->pNeighborBssDescription->channel; + pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore = + (tANI_U8)pNeighborBssDesc->roamScore; + vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId, + pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr)); + pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++; + + /* Saving the channel list non-redundantly */ + for (i = 0; (i < numChannels && i < MAX_BSS_IN_NEIGHBOR_RPT); i++) + { + if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i]) + break; + } + + if (i == numChannels) + { + if (pNeighborBssDesc->pNeighborBssDescription->channel) + { + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + // Make sure to add only if its the same band + if (GetRFBand(pNeighborRoamInfo->currAPoperationChannel) == + GetRFBand(pNeighborBssDesc->pNeighborBssDescription->channel)) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] Adding %d to Neighbor channel list (Same band)\n", __func__, + pNeighborBssDesc->pNeighborBssDescription->channel); + channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel; + numChannels++; + } + } + else + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__, + pNeighborBssDesc->pNeighborBssDescription->channel); + channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel; + numChannels++; + } + } + } + + pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc); + } + + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + } + + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + /* Store the obtained channel list to the Neighbor Control data structure */ + if (numChannels) + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8)); + if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored")); + return VOS_STATUS_E_RESOURCES; + } + + vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList, + channelList, (numChannels) * sizeof(tANI_U8)); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels; + /* + * Create a Union of occupied channel list learnt by the DUT along with the Neighbor + * report Channels. This increases the chances of the DUT to get a candidate AP while + * roaming even if the Neighbor Report is not able to provide sufficient information. + * */ + if (pMac->scan.occupiedChannels.numChannels) + { + csrNeighborRoamMergeChannelLists(pMac, + &pMac->scan.occupiedChannels.channelList[0], + pMac->scan.occupiedChannels.numChannels, + &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0], + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels, + &mergedOutputNumOfChannels); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = + mergedOutputNumOfChannels; + + } + /*Indicate the firmware about the update only if any new channels are added. + * Otherwise, the firmware would already be knowing the non-IAPPneighborlist + * channels. There is no need to update.*/ + if (numChannels) + { + smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected" + "in state %s."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_CHANNEL_LIST_CHANGED); + } +#endif + } + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE; + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamRRMNeighborReportResult + + \brief This function is the neighbor report callback that will be invoked by + SME RRM on receiving a neighbor report or of neighbor report is not + received after timeout. On receiving a valid report, it generates a + channel list from the neighbor report and starts the + neighbor scan timer + + \param context - The handle returned by macOpen. + vosStatus - Status of the callback(SUCCESS/FAILURE) + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(context); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d"), vosStatus); + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY: + /* Reset the report pending variable */ + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE; + if (VOS_STATUS_SUCCESS == vosStatus) + { + /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */ + vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac); + if (VOS_STATUS_SUCCESS == vosStatus) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state")); + } + + /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */ + pNeighborRoamInfo->scanRequestTimeStamp = + vos_timer_get_system_time(); + + /* Now ready for neighbor scan based on the channel list created */ + /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is + what palTimerStart expects */ + status = vos_timer_start(&pNeighborRoamInfo->neighborScanTimer, + pNeighborRoamInfo->cfgParams.neighborScanPeriod); + if (eHAL_STATUS_SUCCESS != status) + { + /* Timer start failed.. Should we ASSERT here??? */ + smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status); + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + return; + } + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + /* Neighbor scan timer started. Transition to REPORT_SCAN state */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN) + } + else + { + /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we + reach the maxNeighborRetries or receiving a successful neighbor response */ + smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d"), + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries); + if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >= + pNeighborRoamInfo->cfgParams.maxNeighborRetries) + { + smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. ")); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d "), vosStatus); + return; + } + /* We transitioned to different state now. Reset the Neighbor report retry count */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + } + else + { + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return; + } + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + } + } + break; + default: + smsLog(pMac, LOGE, FL("Neighbor result callback not expected in" + "state %s, Ignoring.."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + break; + } + return; +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +#ifdef FEATURE_WLAN_LFR +tANI_BOOLEAN csrNeighborRoamIsSsidAndSecurityMatch( + tpAniSirGlobal pMac, + tCsrRoamConnectedProfile *pCurProfile, + tSirBssDescription *pBssDesc, + tDot11fBeaconIEs *pIes) +{ + tCsrAuthList authType; + tCsrEncryptionList uCEncryptionType; + tCsrEncryptionList mCEncryptionType; + tANI_BOOLEAN fMatch = FALSE; + + authType.numEntries = 1; + authType.authType[0] = pCurProfile->AuthType; + uCEncryptionType.numEntries = 1; + uCEncryptionType.encryptionType[0] = pCurProfile->EncryptionType; + mCEncryptionType.numEntries = 1; + mCEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType; + + if( pIes ) + { + if(pIes->SSID.present) + { + fMatch = csrIsSsidMatch( pMac, + (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length, + pIes->SSID.ssid, pIes->SSID.num_ssid, + eANI_BOOLEAN_TRUE ); + if(TRUE == fMatch) + { + /* + * for now we are sending NULL for all PMF related filter + * parameters during roam to the neighbor AP because + * so far 80211W spec doesn't specify anything about + * roaming scenario. + * + * Once roaming scenario is defined, we should re-visit + * this section and remove this comment. + */ + fMatch = csrIsSecurityMatch(pMac, &authType, &uCEncryptionType, + &mCEncryptionType, + NULL, NULL, NULL, + pBssDesc, pIes, NULL, NULL, NULL); + return (fMatch); + } + else + { + return (fMatch); + } + + } + else + { + return FALSE; // Treat a missing SSID as a non-match. + } + } + else + { + return FALSE; // Again, treat missing pIes as a non-match. + } +} + +tANI_BOOLEAN csrNeighborRoamIsNewConnectedProfile( + tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId; + tCsrRoamConnectedProfile *pCurrProfile = NULL; + tCsrRoamConnectedProfile *pPrevProfile = NULL; + tDot11fBeaconIEs *pIes = NULL; + tSirBssDescription *pBssDesc = NULL; + tANI_BOOLEAN fNew = TRUE; + + if(!(pMac->roam.roamSession && CSR_IS_SESSION_VALID(pMac, sessionId))) + { + return (fNew); + } + + pCurrProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + if( !pCurrProfile ) + { + return (fNew); +} + + pPrevProfile = &pNeighborRoamInfo->prevConnProfile; + if( !pPrevProfile ) + { + return (fNew); + } + + pBssDesc = pPrevProfile->pBssDesc; + if (pBssDesc) + { + if (HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, + pBssDesc, &pIes)) && + csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurrProfile, pBssDesc, pIes)) + { + fNew = FALSE; + } + if (pIes) + { + vos_mem_free(pIes); + } + } + + if (fNew) + { + smsLog(pMac, LOG1, FL("Prev roam profile did not match current")); + } + else + { + smsLog(pMac, LOG1, FL("Prev roam profile matches current")); + } + + return (fNew); +} + +tANI_BOOLEAN csrNeighborRoamConnectedProfileMatch( + tpAniSirGlobal pMac, + tCsrScanResult *pResult, + tDot11fBeaconIEs *pIes) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId; + tCsrRoamConnectedProfile *pCurProfile = NULL; + tSirBssDescription *pBssDesc = &pResult->Result.BssDescriptor; + + if( !(pMac->roam.roamSession + && CSR_IS_SESSION_VALID(pMac, sessionId))) + { + return FALSE; + } + + pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile; + + if( !pCurProfile) + { + return FALSE; + } + + return csrNeighborRoamIsSsidAndSecurityMatch(pMac, pCurProfile, pBssDesc, pIes); +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPrepareNonOccupiedChannelList + + \brief This function is used to prepare a channel list that is derived from + the list of valid channels and does not include those in the occupied + list. + + \param pMac - The handle returned by macOpen. + \param pInputChannelList - The default channels list. + \param numOfChannels - The number of channels in the default channels list. + \param pOutputChannelList - The place to put the non-occupied channel list. + \param pOutputNumOfChannels - The number of channels in the non-occupied channel list. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamPrepareNonOccupiedChannelList( + tpAniSirGlobal pMac, + tANI_U8 *pInputChannelList, + tANI_U8 numOfChannels, + tANI_U8 *pOutputChannelList, + tANI_U8 *pOutputNumOfChannels + ) +{ + tANI_U8 i = 0; + tANI_U8 outputNumOfChannels = 0; // Clear the output number of channels + tANI_U8 numOccupiedChannels = pMac->scan.occupiedChannels.numChannels; + tANI_U8 *pOccupiedChannelList = pMac->scan.occupiedChannels.channelList; + + for (i = 0; (i < numOfChannels &&(i < WNI_CFG_VALID_CHANNEL_LIST_LEN)); i++) + { + if (!csrIsChannelPresentInList(pOccupiedChannelList, numOccupiedChannels, + pInputChannelList[i])) + { + /* DFS channel will be added in the list only when the + DFS Roaming scan flag is enabled*/ + if (CSR_IS_CHANNEL_DFS(pInputChannelList[i])) + { + if (pMac->roam.configParam.allowDFSChannelRoam == TRUE) + { + pOutputChannelList[outputNumOfChannels++] = pInputChannelList[i]; + } + } + else + { + pOutputChannelList[outputNumOfChannels++] = pInputChannelList[i]; + } + } + } + + smsLog(pMac, LOG2, FL("Number of channels in the valid channel list=%d; " + "Number of channels in the non-occupied list list=%d"), + numOfChannels, outputNumOfChannels); + + // Return the number of channels + *pOutputNumOfChannels = outputNumOfChannels; + + return eHAL_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_LFR */ + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamTransitToCFGChanScan + + \brief This function is called whenever there is a transition to CFG chan scan + state from any state. It frees up the current channel list and allocates + a new memory for the channels received from CFG item. It then starts the + neighbor scan timer to perform the scan on each channel one by one + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + int i = 0; + tANI_U8 numOfChannels = 0; + tANI_U8 channelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + tpCsrChannelInfo currChannelListInfo; + tANI_U8 scanChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN]; + int outputNumOfChannels = 0; +#ifdef FEATURE_WLAN_LFR + tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId; +#endif + currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + + if ( +#ifdef FEATURE_WLAN_ESE + ((pNeighborRoamInfo->isESEAssoc) && + (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) || + (pNeighborRoamInfo->isESEAssoc == eANI_BOOLEAN_FALSE) || +#endif // ESE + currChannelListInfo->numOfChannels == 0) + { + smsLog(pMac, LOGW, FL("Building channel list to scan")); + + + /* Free up the channel list and allocate a new memory. This is because we dont know how much + was allocated last time. If we directly copy more number of bytes than allocated earlier, this might + result in memory corruption */ + if (NULL != currChannelListInfo->ChannelList) + { + vos_mem_free(currChannelListInfo->ChannelList); + currChannelListInfo->ChannelList = NULL; + currChannelListInfo->numOfChannels = 0; + } + + // Now obtain the contents for "channelList" (the "default valid channel list") from EITHER + // the gNeighborScanChannelList in "cfg.ini", OR the actual "valid channel list" information formed by CSR. + if (0 != pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) + { + // Copy the "default valid channel list" (channelList) from the gNeighborScanChannelList in "cfg.ini". + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Using the channel list from cfg.ini"); + status = csrNeighborRoamMergeChannelLists( + pMac, + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels, + channelList, + 0, //NB: If 0, simply copy the input channel list to the output list. + &numOfChannels ); + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByBand( + pMac, + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels, + channelList, + &numOfChannels, + GetRFBand(pMac->roam.neighborRoamInfo.currAPoperationChannel)); + } + if(numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + smsLog(pMac, LOGE, FL("Received wrong number of Channel list")); + return VOS_STATUS_E_INVAL; + } + /* Remove the DFS channels from CFG channel list when ' + gAllowRoamToDFS is disabled */ + if ( pMac->roam.configParam.allowDFSChannelRoam == FALSE) + { + for (i=0; iChannelList = + vos_mem_malloc(outputNumOfChannels*sizeof(tANI_U8)); + if (NULL == currChannelListInfo->ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed")); + return VOS_STATUS_E_RESOURCES; + } + currChannelListInfo->numOfChannels = outputNumOfChannels; + vos_mem_copy(currChannelListInfo->ChannelList, + scanChannelList, outputNumOfChannels * sizeof(tANI_U8)); + } + + +#ifdef FEATURE_WLAN_LFR + else if ((pNeighborRoamInfo->uScanMode == DEFAULT_SCAN) && + (abs(pNeighborRoamInfo->lookupDOWNRssi) > + abs(pNeighborRoamInfo->cfgParams.neighborReassocThreshold))) + { + /* + * Trigger a contiguous scan on all channels when the + * RSSI in the lookup DOWN notification is below reassoc + * threshold. This will help us find the best available + * candidate and also update the channel cache. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "Triggering contiguous scan " + "(lookupDOWNRssi=%d,reassocThreshold=%d)", + pNeighborRoamInfo->lookupDOWNRssi, + pNeighborRoamInfo->cfgParams.neighborReassocThreshold*(-1)); + + pNeighborRoamInfo->scanRequestTimeStamp = + vos_timer_get_system_time(); + + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + + /* We are about to start a fresh scan cycle, + * purge non-P2P results from the past */ + csrScanFlushSelectiveResult(pMac, VOS_FALSE); + + csrNeighborRoamPerformContiguousBgScan(pMac, sessionId); + + /* Transition to CFG_CHAN_LIST_SCAN */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN); + + return VOS_STATUS_SUCCESS; + } +#endif + else + { + numOfChannels = pMac->scan.occupiedChannels.numChannels; + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + if (numOfChannels +#ifdef FEATURE_WLAN_LFR + && ((pNeighborRoamInfo->uScanMode == SPLIT_SCAN_OCCUPIED_LIST) || + (pNeighborRoamInfo->uEmptyScanCount == 0) || + ((pNeighborRoamInfo->uEmptyScanCount % 2) == 1)) +#endif + ) + { + /* + * Always scan channels in the occupied channel list + * before scanning on the non-occupied list. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Switching to occupied channel list" +#ifdef FEATURE_WLAN_LFR + "-uScanMode=%d, uEmptyScanCount=%d", + pNeighborRoamInfo->uScanMode, + pNeighborRoamInfo->uEmptyScanCount +#endif + ); + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByBand( + pMac, + pMac->scan.occupiedChannels.channelList, + numOfChannels, + channelList, + &numOfChannels, + GetRFBand(pMac->roam.neighborRoamInfo.currAPoperationChannel)); + } + else + { + vos_mem_copy(channelList, + pMac->scan.occupiedChannels.channelList, + numOfChannels * sizeof(tANI_U8)); + } + /* Remove the DFS channels from CFG channel list when ' + gAllowRoamToDFS is disabled */ + if ( pMac->roam.configParam.allowDFSChannelRoam == FALSE) + { + for (i=0; iChannelList = vos_mem_malloc(outputNumOfChannels * sizeof(tANI_U8)); + if (NULL == currChannelListInfo->ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed")); + return VOS_STATUS_E_RESOURCES; + } + currChannelListInfo->numOfChannels = outputNumOfChannels; + vos_mem_copy(currChannelListInfo->ChannelList, + scanChannelList, + outputNumOfChannels * sizeof(tANI_U8)); + } + else + { + /* Scan all channels from non-occupied list */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Get valid channel list"); + numOfChannels = sizeof(pMac->roam.validChannelList); + + if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, + (tANI_U8 *)pMac->roam.validChannelList, + (tANI_U32 *) &numOfChannels))) + { +#ifdef FEATURE_WLAN_LFR + /* + * Prepare non-occupied channel list (channelList) + * from the actual "valid channel list" information + * formed by CSR. + */ + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, "Switching to non-occupied channel list"); + status = csrNeighborRoamPrepareNonOccupiedChannelList(pMac, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels, + channelList, + &numOfChannels); +#else + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, "Merging channel list"); + status = csrNeighborRoamMergeChannelLists( + pMac, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels, // The number of channels in the validChannelList + channelList, + 0, //NB: If 0, simply copy the input channel list to the output list. + &numOfChannels ); // The final number of channels in the output list. Will be numOfChannels +#endif + } + else + { + smsLog(pMac, LOGE, FL("Could not get valid channel list")); + return VOS_STATUS_E_FAILURE; + } + + if (CSR_IS_ROAM_INTRA_BAND_ENABLED(pMac)) + { + csrNeighborRoamChannelsFilterByBand( + pMac, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels, + channelList, + &numOfChannels, + GetRFBand(pMac->roam.neighborRoamInfo.currAPoperationChannel)); + } + + if (numOfChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) + { + numOfChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + } + + if (numOfChannels == 0) + { + smsLog(pMac, LOGE, FL("No channels to scan")); + return VOS_STATUS_E_FAILURE; + } + currChannelListInfo->ChannelList = + vos_mem_malloc(numOfChannels*sizeof(tANI_U8)); + + if (NULL == currChannelListInfo->ChannelList) + { + smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed")); + return VOS_STATUS_E_RESOURCES; + } + currChannelListInfo->numOfChannels = numOfChannels; +#ifdef FEATURE_WLAN_LFR + vos_mem_copy(currChannelListInfo->ChannelList, + channelList, numOfChannels * sizeof(tANI_U8)); +#else + vos_mem_copy(currChannelListInfo->ChannelList, + (tANI_U8 *)pMac->roam.validChannelList, + numOfChannels * sizeof(tANI_U8)); +#endif + } + } + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, + "Number of channels from CFG (or) (non-)occupied list=%d", + currChannelListInfo->numOfChannels); + for (i = 0; i < currChannelListInfo->numOfChannels; i++) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, "Channel List from CFG (or) (non-)occupied list" + "= %d", currChannelListInfo->ChannelList[i]); + } + } + + /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */ + pNeighborRoamInfo->scanRequestTimeStamp = vos_timer_get_system_time(); + + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is + what palTimerStart expects */ + status = vos_timer_start(&pNeighborRoamInfo->neighborScanTimer, + pNeighborRoamInfo->cfgParams.neighborScanPeriod); + + if (eHAL_STATUS_SUCCESS != status) + { + /* Timer start failed.. */ + smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status); + vos_mem_free(currChannelListInfo->ChannelList); + currChannelListInfo->ChannelList = NULL; + currChannelListInfo->numOfChannels = 0; + return VOS_STATUS_E_FAILURE; + } + + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE; + /* We are about to start a fresh scan cycle, + * purge non-P2P results from the past */ + csrScanFlushSelectiveResult(pMac, VOS_FALSE); + + /* We are about to start a fresh scan cycle, + * purge failed pre-auth results from the past */ + csrNeighborRoamPurgePreauthFailedList(pMac); + + /* Transition to CFG_CHAN_LIST_SCAN_STATE */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN) + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupUpEvent + + \brief This function is called as soon as TL indicates that the current AP's + RSSI is better than the neighbor lookup threshold. Here, we transition to + CONNECTED state and reset all the scan parameters + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus; + csrNeighborRoamDeregAllRssiIndication(pMac); + + /* Recheck whether the below check is needed. */ + if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) + && (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)) + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) +#ifdef FEATURE_WLAN_LFR + if (!csrRoamIsFastRoamEnabled(pMac,pMac->roam.neighborRoamInfo.csrSessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + return eHAL_STATUS_SUCCESS; + } +#endif + /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */ + csrNeighborRoamResetConnectedStateControlInfo(pMac); + + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + /* Register Neighbor Lookup threshold callback with TL for DOWN event now */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pMac); +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; +#endif + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d"), vosStatus); + } + + + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupDownEvent + + \brief This function is called as soon as TL indicates that the current AP's + RSSI falls below the current eighbor lookup threshold. Here, we transition to + REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is + a non-11R association. + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED: + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"), + pNeighborRoamInfo->currentNeighborLookupThreshold * (-1)); + /* De-register Neighbor Lookup threshold callback with TL */ + vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d"), vosStatus); + } +#ifdef FEATURE_WLAN_LFR + if (!csrRoamIsFastRoamEnabled(pMac,pMac->roam.neighborRoamInfo.csrSessionId)) + { + smsLog(pMac, LOGE, FL("Received when fast roam is disabled. Ignore it")); + return eHAL_STATUS_SUCCESS; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI + if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled)) + { + + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state")); + vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d"), vosStatus); + return vosStatus; + } + /* Increment the neighbor report retry count after sending the neighbor request successfully */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++; + pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE; + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY) + } + else +#endif + { + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or ESE Association:Neighbor Lookup Down event received in CONNECTED state")); + + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamTransitToCFGChanScan failed" + " with status=%d"), vosStatus); + return vosStatus; + } + } + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1)); + /* Register Neighbor Lookup threshold callback with TL for UP event now */ + vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, + (v_S7_t)NEIGHBOR_ROAM_LOOKUP_UP_THRESHOLD * (-1), + WLANTL_HO_THRESHOLD_UP, + csrNeighborRoamNeighborLookupUPCallback, + VOS_MODULE_ID_SME, pMac); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + //err msg + smsLog(pMac, LOGE, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d"), status); + } + break; + default: + smsLog(pMac, LOGE, FL("DOWN event received in invalid" + "state %s ..Ignoring..."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + break; + + } + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupUPCallback + + \brief This function is registered with TL to indicate whenever the RSSI + gets better than the neighborLookup RSSI Threshold + + \param pAdapter - VOS Context + trafficStatus - UP/DOWN indication from TL + pUserCtxt - Parameter for callback registered during callback registration. Should be pMac + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup UP indication callback called with notification %d Reported RSSI = %d"), + rssiNotification, + avgRssi); + + if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId)) + { + smsLog(pMac, LOGW, "Ignoring the indication as we are not connected"); + return VOS_STATUS_SUCCESS; + } + + VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification); + vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac); + return vosStatus; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamNeighborLookupDOWNCallback + + \brief This function is registered with TL to indicate whenever the RSSI + falls below the current neighborLookup RSSI Threshold + + \param pAdapter - VOS Context + trafficStatus - UP/DOWN indication from TL + pUserCtxt - Parameter for callback registered during callback registration. Should be pMac + + \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Neighbor Lookup DOWN indication callback called with notification %d Reported RSSI = %d"), + rssiNotification, + avgRssi); + +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = avgRssi; +#endif + if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId)) + { + smsLog(pMac, LOGW, "Ignoring the indication as we are not connected"); + return VOS_STATUS_SUCCESS; + } + + VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification); + vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac); + + return vosStatus; +} + +#ifdef RSSI_HACK +extern int dumpCmdRSSI; +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIndicateDisconnect + + \brief This function is called by CSR as soon as the station disconnects from + the AP. This function does the necessary cleanup of neighbor roam data + structures. Neighbor roam state transitions to INIT state whenever this + function is called except if the current state is REASSOCIATING + + \param pMac - The handle returned by macOpen. + sessionId - CSR session id that got disconnected + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; +#ifdef FEATURE_WLAN_LFR + tCsrRoamConnectedProfile *pPrevProfile = &pNeighborRoamInfo->prevConnProfile; +#endif + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId); + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL ")); + return eHAL_STATUS_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Disconnect indication on session %d in state %s" + "from BSSID : " + MAC_ADDRESS_STR), sessionId, + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState), + MAC_ADDR_ARRAY(pSession->connectedProfile.bssid)); + +#ifdef FEATURE_WLAN_LFR + /*Free the current previous profile and move the current profile to prev profile.*/ + csrRoamFreeConnectProfile(pMac, pPrevProfile); + csrRoamCopyConnectProfile(pMac, sessionId, pPrevProfile); +#endif + if (NULL != pSession) + { + if (NULL != pSession->pCurRoamProfile) + { + if (VOS_STA_MODE != pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona) + { + smsLog(pMac, LOGE, FL("Ignoring Disconnect indication received from a non STA persona." + "sessionId: %d, csrPersonna %d"), sessionId, + (int)pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona); + return eHAL_STATUS_SUCCESS; + } + } + +#ifdef FEATURE_WLAN_ESE + if (pSession->connectedProfile.isESEAssoc) + { + vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, + sizeof(tSirMacSSid)); + vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + pSession->prevOpChannel = pSession->connectedProfile.operationChannel; + pSession->isPrevApInfoValid = TRUE; + pSession->roamTS1 = vos_timer_get_system_time(); + } +#endif + } //if (NULL != pSession) + +#ifdef RSSI_HACK + dumpCmdRSSI = -40; +#endif + switch (pNeighborRoamInfo->neighborRoamState) + { + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + // Stop scan and neighbor refresh timers. + // These are indeed not required when we are in reassociating + // state. + vos_timer_stop(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_stop(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_stop(&pNeighborRoamInfo->emptyScanRefreshTimer); + if (!CSR_IS_ROAM_SUBSTATE_DISASSOC_HO( pMac, sessionId )) { + /* + * Disconnect indication during Disassoc Handoff sub-state + * is received when we are trying to disconnect with the old + * AP during roam. BUT, if receive a disconnect indication + * outside of Disassoc Handoff sub-state, then it means that + * this is a genuine disconnect and we need to clean up. + * Otherwise, we will be stuck in reassoc state which will + * in-turn block scans (see csrIsScanAllowed). + */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT); + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; +#endif + + } + break; + + case eCSR_NEIGHBOR_ROAM_STATE_INIT: + csrNeighborRoamResetInitStateControlInfo(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + + case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED: + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + csrNeighborRoamResetConnectedStateControlInfo(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + +#ifdef WLAN_FEATURE_LFR_MBB + csr_stop_preauth_reassoc_mbb_timer(pMac); +#endif + break; + + case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN: + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT); + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + csrNeighborRoamResetCfgListChanScanControlInfo(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE: + /* Stop pre-auth to reassoc interval timer */ + vos_timer_stop(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer); + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING: + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + csrNeighborRoamResetPreauthControlInfo(pMac); + csrNeighborRoamResetReportScanStateControlInfo(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (!csrRoamIsRoamOffloadScanEnabled(pMac)) + { +#endif + csrNeighborRoamDeregAllRssiIndication(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + break; + + default: + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Received disconnect event" + "in state %s"), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Transitioning to INIT state")); + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; +#endif + break; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + /*Inform the Firmware to STOP Scanning as the host has a disconnect.*/ + if (csrRoamIsStaMode(pMac, sessionId)) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED); + } +#endif + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIndicateConnect + + \brief This function is called by CSR as soon as the station connects to an AP. + This initializes all the necessary data structures related to the + associated AP and transitions the state to CONNECTED state + + \param pMac - The handle returned by macOpen. + sessionId - CSR session id that got connected + vosStatus - connect status SUCCESS/FAILURE + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vstatus; + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + int init_ft_flag = FALSE; +#endif + + // if session id invalid then we need return failure + if (NULL == pNeighborRoamInfo || !CSR_IS_SESSION_VALID(pMac, sessionId) || + (NULL == pMac->roam.roamSession[sessionId].pCurRoamProfile)) + { + return eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG2, FL("Connect indication received with session id %d" + "in state %s"), + sessionId, macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + + // Bail out if this is NOT a STA persona + if (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona != VOS_STA_MODE) + { + smsLog(pMac, LOGE, FL("Ignoring Connect indication received from a non STA persona." + "sessionId: %d, csrPersonna %d"), + sessionId, + (int)pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona); + return eHAL_STATUS_SUCCESS; + } + + // if a concurrent session is running +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (eANI_BOOLEAN_FALSE == CSR_IS_FASTROAM_IN_CONCURRENCY_INI_FEATURE_ENABLED(pMac)) + { +#endif + if (csrIsConcurrentSessionRunning(pMac)) + { + smsLog(pMac, LOGE, FL("Ignoring Connect indication received in multisession %d"), + csrIsConcurrentSessionRunning(pMac)); + return eHAL_STATUS_SUCCESS; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif + + switch (pNeighborRoamInfo->neighborRoamState) + { +#ifdef WLAN_FEATURE_LFR_MBB + case eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC: +#endif + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + if (VOS_STATUS_SUCCESS != vosStatus) + { + /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; +#endif + break; + } + /* Fall through if the status is SUCCESS */ + case eCSR_NEIGHBOR_ROAM_STATE_INIT: + /* Reset all the data structures here */ + csrNeighborRoamResetInitStateControlInfo(pMac); + + pNeighborRoamInfo->csrSessionId = sessionId; + +#ifdef FEATURE_WLAN_LFR + /* + * Initialize the occupied list ONLY if we are + * transitioning from INIT state to CONNECTED state. + */ + if (eCSR_NEIGHBOR_ROAM_STATE_INIT == pNeighborRoamInfo->neighborRoamState) + csrInitOccupiedChannelsList(pMac); +#endif + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + + vos_mem_copy(pNeighborRoamInfo->currAPbssid, + pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid)); + pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel; + pNeighborRoamInfo->currentNeighborLookupThreshold = + pNeighborRoamInfo->cfgParams.neighborLookupThreshold; +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->lookupDOWNRssi = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; +#endif + + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + /* Now we can clear the preauthDone that was saved as we are connected afresh */ + csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList); +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + // Based on the auth scheme tell if we are 11r + if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType, + pMac->roam.roamSession[sessionId].connectedProfile.MDID.mdiePresent)) + { + if (pMac->roam.configParam.isFastTransitionEnabled) + init_ft_flag = TRUE; + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE; + } + else + pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE; + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc); +#endif + +#ifdef FEATURE_WLAN_ESE + // Based on the auth scheme tell if we are 11r + if (pMac->roam.roamSession[sessionId].connectedProfile.isESEAssoc) + { + if (pMac->roam.configParam.isFastTransitionEnabled) + init_ft_flag = TRUE; + pNeighborRoamInfo->isESEAssoc = eANI_BOOLEAN_TRUE; + } + else + pNeighborRoamInfo->isESEAssoc = eANI_BOOLEAN_FALSE; + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("isESEAssoc is = %d ft = %d"), + pNeighborRoamInfo->isESEAssoc, init_ft_flag); + +#endif + + if (pMac->roam.pending_roam_disable) + { + smsLog(pMac, LOG1, FL("process pending roam disable")); + pMac->roam.configParam.isFastRoamIniFeatureEnabled = FALSE; + pMac->roam.pending_roam_disable = FALSE; + } + +#ifdef FEATURE_WLAN_LFR + // If "Legacy Fast Roaming" is enabled + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + init_ft_flag = TRUE; + } +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + if ( init_ft_flag == TRUE ) + { + /* Initialize all the data structures needed for the 11r FT Preauth */ + pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0; + csrNeighborRoamPurgePreauthFailedList(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + /*If this is not a INFRA type BSS, then do not send the command + * down to firmware.Do not send the START command for other session + * connections.*/ + if(csrRoamIsStaMode(pMac, sessionId)) + { + pNeighborRoamInfo->uOsRequestedHandoff = 0; + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 0; + if(pNeighborRoamInfo->cfgParams.neighborInitialForcedRoamTo5GhEnable && + (GetRFBand(pNeighborRoamInfo->currAPoperationChannel) == + SIR_BAND_2_4_GHZ)) + { + /* + * Keep 5G and Fwr roaming mutually exclusive so do not + * send RSO start Note we have to send RSO start in all + * errro case. + */ + smsLog(pMac, LOG1, + FL("Do not send RSO start" + "because 5G force roaming is enabled")); + break; + } + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_CONNECT); + } + } else { +#endif + + NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold); + /* Register Neighbor Lookup threshold callback with TL for DOWN event only */ + vstatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1), + WLANTL_HO_THRESHOLD_DOWN, + csrNeighborRoamNeighborLookupDOWNCallback, + VOS_MODULE_ID_SME, pMac); +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; +#endif + if(!VOS_IS_STATUS_SUCCESS(vstatus)) + { + //err msg + smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d"), vstatus); + status = eHAL_STATUS_FAILURE; + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + } +#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */ + } +#endif + break; + default: + smsLog(pMac, LOGE, FL("Connect event received in invalid state %s" + "..Ignoring..."), + macTraceGetNeighbourRoamState( + pNeighborRoamInfo->neighborRoamState)); + break; + } + return status; +} + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamPurgePreauthFailedList + + \brief This function purges all the MAC addresses in the pre-auth fail list + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++) + { + vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr)); + } + pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0; + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamInit11rAssocInfo + + \brief This function initializes 11r related neighbor roam data structures + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac) +{ + eHalStatus status; + tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo; + + pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE; + pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries; + pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT; + pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod; + pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE; + pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE; + + pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0; + pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0; + vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo, + sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); + + + status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed")); + return eHAL_STATUS_RESOURCES; + } + return status; +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamInit + + \brief This function initializes neighbor roam data structures + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac) +{ + eHalStatus status; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED; + pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED; + pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID; + pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime; + pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime; + pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0; + pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold; + pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold; + pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod; + pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod; + pNeighborRoamInfo->cfgParams.emptyScanRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod; + pNeighborRoamInfo->cfgParams.neighborInitialForcedRoamTo5GhEnable = pMac->roam.configParam.neighborRoamConfig.nNeighborInitialForcedRoamTo5GhEnable; + pNeighborRoamInfo->cfgParams.WeakZoneRssiThresholdForRoam = + pMac->roam.configParam.neighborRoamConfig.nWeakZoneRssiThresholdForRoam; + + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels = + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels; + + if (pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels != 0) + { + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = + vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed")); + return eHAL_STATUS_RESOURCES; + } + + /* Update the roam global structure from CFG */ + vos_mem_copy(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList, + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList, + pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels); + } + else + { + smsLog(pMac, LOGW, + FL("invalid neighbor roam channel list: %u"), + pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels); + } + + vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0); + pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold; +#ifdef FEATURE_WLAN_LFR + pNeighborRoamInfo->lookupDOWNRssi = 0; + pNeighborRoamInfo->uEmptyScanCount = 0; + pNeighborRoamInfo->uScanMode = DEFAULT_SCAN; + vos_mem_set(&pNeighborRoamInfo->prevConnProfile, sizeof(tCsrRoamConnectedProfile), 0); +#endif + pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE; + + status = vos_timer_init(&pNeighborRoamInfo->neighborScanTimer, VOS_TIMER_TYPE_SW, + csrNeighborRoamNeighborScanTimerCallback, (void *)pMac); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Neighbor scan timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + return eHAL_STATUS_RESOURCES; + } + + status = vos_timer_init(&pNeighborRoamInfo->neighborResultsRefreshTimer, VOS_TIMER_TYPE_SW, + csrNeighborRoamResultsRefreshTimerCallback, (void *)pMac); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Neighbor results refresh timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + return eHAL_STATUS_RESOURCES; + } + + status = vos_timer_init(&pNeighborRoamInfo->emptyScanRefreshTimer, VOS_TIMER_TYPE_SW, + csrNeighborRoamEmptyScanRefreshTimerCallback, + (void *)pMac); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Empty scan refresh timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + return eHAL_STATUS_RESOURCES; + } + + status = vos_timer_init(&pNeighborRoamInfo->forcedInitialRoamTo5GHTimer, VOS_TIMER_TYPE_SW, + csrForcedInitialRoamTo5GHTimerCallback, (void *)pMac); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("forcedInitialRoamTo5GHTimer timer allocation failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + return eHAL_STATUS_RESOURCES; + } + + status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->forcedInitialRoamTo5GHTimer); + return eHAL_STATUS_RESOURCES; + } + + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + +#ifdef WLAN_FEATURE_VOWIFI_11R + status = csrNeighborRoamInit11rAssocInfo(pMac); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed")); + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->forcedInitialRoamTo5GHTimer); + csrLLClose(&pNeighborRoamInfo->roamableAPList); + return eHAL_STATUS_RESOURCES; + } +#endif + /* Initialize this with the current tick count */ + pNeighborRoamInfo->scanRequestTimeStamp = vos_timer_get_system_time(); + + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; +#endif + + //Set the Last Sent Cmd as RSO_STOP + pNeighborRoamInfo->lastSentCmd = ROAM_SCAN_OFFLOAD_STOP; + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamClose + + \brief This function closes/frees all the neighbor roam data structures + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamClose(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGW, FL("Neighbor Roam Algorithm Already Closed")); + return; + } + + if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList); + + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL; + + vos_timer_destroy(&pNeighborRoamInfo->neighborScanTimer); + vos_timer_destroy(&pNeighborRoamInfo->neighborResultsRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->emptyScanRefreshTimer); + vos_timer_destroy(&pNeighborRoamInfo->forcedInitialRoamTo5GHTimer); + + /* Should free up the nodes in the list before closing the double Linked list */ + csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList); + csrLLClose(&pNeighborRoamInfo->roamableAPList); + + if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList) + { + vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList); + } + + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0; + pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL; + pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE; + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; + + /* Free the profile.. */ + csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile); +#ifdef FEATURE_WLAN_LFR + csrRoamFreeConnectProfile(pMac, &pNeighborRoamInfo->prevConnProfile); +#endif +#ifdef WLAN_FEATURE_VOWIFI_11R + pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0; + pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0; + vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo, + sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT); + csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList); + csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED) + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamRequestHandoff + + \brief This function triggers actual switching from one AP to the new AP. + It issues disassociate with reason code as Handoff and CSR as a part of + handling disassoc rsp, issues reassociate to the new AP + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac) +{ + + tCsrRoamInfo roamInfo; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId; + tCsrNeighborRoamBSSInfo handoffNode; + extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp ); + tANI_U32 roamId = 0; + eHalStatus status; + +#ifdef FEATURE_WLAN_LFR_METRICS + tCsrRoamInfo *roamInfoMetrics; +#endif + + if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) + { + smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %s state"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + return; + } + + if (eANI_BOOLEAN_FALSE == + csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode)) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to obtain handoff AP")); + return; + } + + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + FL("HANDOFF CANDIDATE BSSID "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(handoffNode.pBssDescription->bssId)); + + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START, + eSIR_SME_SUCCESS); + + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING) + +#ifdef FEATURE_WLAN_LFR_METRICS + /* LFR metrics - pre-auth completion metric. + Send the event to supplicant that pre-auth successfully completed */ + roamInfoMetrics = vos_mem_malloc(sizeof(tCsrRoamInfo)); + if (NULL == roamInfoMetrics) + { + smsLog(pMac, LOG1, FL("Memory allocation failed!")); + } + else + { + vos_mem_copy((void *)roamInfoMetrics->bssid, + (void *)&handoffNode.pBssDescription->bssId, sizeof(tCsrBssid)); + csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, + roamInfoMetrics, 0, eCSR_ROAM_HANDOVER_SUCCESS, 0); + vos_mem_free(roamInfoMetrics); + } +#endif + + /* Free the profile.. Just to make sure we dont leak memory here */ + csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile); + /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number + This should happen before issuing disconnect */ + status = csrRoamCopyConnectedProfile(pMac, + pNeighborRoamInfo->csrSessionId, + &pNeighborRoamInfo->csrNeighborRoamProfile); + if(eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("csrRoamCopyConnectedProfile returned failed %d"), status); + return; + } + + vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr)); + pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId; + + NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP"); + + if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF))) + { + smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate"); + return; + } + + //notify HDD for handoff, providing the BSSID too + roamInfo.reasonCode = eCsrRoamReasonBetterAP; + + vos_mem_copy(roamInfo.bssid, + handoffNode.pBssDescription->bssId, + sizeof( tCsrBssid )); + + csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE); + + + return; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIsHandoffInProgress + + \brief This function returns whether handoff is in progress or not based on + the current neighbor roam state + + \param pMac - The handle returned by macOpen. + is11rReassoc - Return whether reassoc is of type 802.11r reassoc + + \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac) +{ + if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState) + return eANI_BOOLEAN_TRUE; + + return eANI_BOOLEAN_FALSE; +} + +#if defined(WLAN_FEATURE_VOWIFI_11R) || defined(WLAN_FEATURE_NEIGHBOR_ROAMING) +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamIs11rAssoc + + \brief This function returns whether the current association is a 11r assoc or not + + \param pMac - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac) +{ + return pMac->roam.neighborRoamInfo.is11rAssoc; +} +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamGetHandoffAPInfo + + \brief This function returns the best possible AP for handoff. For 11R case, it + returns the 1st entry from pre-auth done list. For non-11r case, it returns + the 1st entry from roamable AP list + + \param pMac - The handle returned by macOpen. + pHandoffNode - AP node that is the handoff candidate returned + + \return eANI_BOOLEAN_TRUE if able find handoff AP, eANI_BOOLEAN_FALSE otherwise + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tpCsrNeighborRoamBSSInfo pBssNode = NULL; + + VOS_ASSERT(NULL != pHandoffNode); + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pNeighborRoamInfo->is11rAssoc) + { + /* Always the BSS info in the head is the handoff candidate */ + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList)); + } + else +#endif +#ifdef FEATURE_WLAN_ESE + if (pNeighborRoamInfo->isESEAssoc) + { + /* Always the BSS info in the head is the handoff candidate */ + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList)); + } + else +#endif +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, CSR_SESSION_ID_INVALID)) + { + /* Always the BSS info in the head is the handoff candidate */ + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList)); + } + else +#endif + { + pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL); + NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList)); + } + + if (NULL == pBssNode) + { + return eANI_BOOLEAN_FALSE; + } + + vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo)); + + return eANI_BOOLEAN_TRUE; +} + +/* --------------------------------------------------------------------------- + \brief This function returns TRUE if preauth is completed + + \param pMac - The handle returned by macOpen. + + \return boolean + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac) +{ + return (pMac->roam.neighborRoamInfo.neighborRoamState == + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE); +} + +/* --------------------------------------------------------------------------- + \brief In the event that we are associated with AP1 and we have + completed pre auth with AP2. Then we receive a deauth/disassoc from + AP1. + At this point neighbor roam is in pre auth done state, pre auth timer + is running. We now handle this case by stopping timer and clearing + the pre-auth state. We basically clear up and just go to disconnected + state. + + \param pMac - The handle returned by macOpen. + + \return boolean +---------------------------------------------------------------------------*/ +void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + if (pMac->roam.neighborRoamInfo.neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return; + + // Stop timer + vos_timer_stop(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer); + + // Transition to init state + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT) + pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pNeighborRoamInfo->uOsRequestedHandoff = 0; +#endif +} + +/* --------------------------------------------------------------------------- + \brief This function returns TRUE if background scan triggered by + LFR is in progress. + + \param halHandle - The handle from HDD context. + + \return boolean + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborRoamScanRspPending (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return (pMac->roam.neighborRoamInfo.scanRspPending); +} + +/* --------------------------------------------------------------------------- + \brief This function returns TRUE if STA is in the middle of roaming states + + \param halHandle - The handle from HDD context. + + \return boolean + +---------------------------------------------------------------------------*/ +tANI_BOOLEAN csrNeighborMiddleOfRoaming (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_BOOLEAN val = (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING == pMac->roam.neighborRoamInfo.neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE == pMac->roam.neighborRoamInfo.neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState) || + (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pMac->roam.neighborRoamInfo.neighborRoamState) + +#ifdef WLAN_FEATURE_LFR_MBB + || (eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC == + pMac->roam.neighborRoamInfo.neighborRoamState); +#else + ; +#endif + return (val); +} +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamCandidateFoundIndHdlr + + \brief This function is called by CSR as soon as TL posts the candidate + found indication to SME via MC thread + + \param pMac - The handle returned by macOpen. + pMsg - Msg sent by PE + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamCandidateFoundIndHdlr(tpAniSirGlobal pMac, void* pMsg) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + /* we must be in connected state, if not ignore it */ + if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + || (pNeighborRoamInfo->uOsRequestedHandoff)) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state OR uOsRequestedHandoff is set. Ignore it")); + status = eHAL_STATUS_FAILURE; + } + else + { + /* We are about to start a fresh scan cycle, + * purge non-P2P results from the past */ + csrScanFlushSelectiveResult(pMac, VOS_FALSE); + /* Once it gets the candidates found indication from PE, will issue a scan + - req to PE with “freshScan” in scanreq structure set as follows: + 0x42 - Return & purge LFR scan results + */ + status = csrScanRequestLfrResult(pMac, pNeighborRoamInfo->csrSessionId, + csrNeighborRoamScanResultRequestCallback, pMac); + } + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamProcessHandoffReq + + \brief This function is called start with the handoff process. First do a + SSID scan for the BSSID provided + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamProcessHandoffReq(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 roamId; + tCsrRoamProfile *pProfile = NULL; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pNeighborRoamInfo->csrSessionId ); + tANI_U8 i = 0; + uint8_t roam_now = 0; + uint8_t roamable_ap_count = 0; + tCsrScanResultFilter scan_filter; + tScanResultHandle scan_result; + + if (NULL == pSession) + { + smsLog(pMac, LOGE, FL("pSession is NULL ")); + return eHAL_STATUS_FAILURE; + } + + do + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + pProfile = vos_mem_malloc(sizeof(tCsrRoamProfile)); + if ( NULL == pProfile ) + { + smsLog(pMac, LOGE, FL("Memory alloc failed")); + return eHAL_STATUS_FAILURE; + } + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + status = csrRoamCopyProfile(pMac, pProfile, pSession->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("Profile copy failed")); + break; + } + + //Add the BSSID & Channel + pProfile->BSSIDs.numOfBSSIDs = 1; + pProfile->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pProfile->BSSIDs.numOfBSSIDs); + if (NULL == pProfile->BSSIDs.bssid) + { + smsLog(pMac, LOGE, FL("mem alloc failed for BSSID")); + status = eHAL_STATUS_FAILURE; + break; + } + + vos_mem_zero(pProfile->BSSIDs.bssid, sizeof(tSirMacAddr) * pProfile->BSSIDs.numOfBSSIDs); + + /* Populate the BSSID from handoff info received from HDD */ + for (i = 0; i < pProfile->BSSIDs.numOfBSSIDs; i++) + { + vos_mem_copy(&pProfile->BSSIDs.bssid[i], + pNeighborRoamInfo->handoffReqInfo.bssid, sizeof(tSirMacAddr)); + } + + pProfile->ChannelInfo.numOfChannels = 1; + pProfile->ChannelInfo.ChannelList = + vos_mem_malloc(sizeof(*pProfile->ChannelInfo.ChannelList) * + pProfile->ChannelInfo.numOfChannels); + if (NULL == pProfile->ChannelInfo.ChannelList) + { + smsLog(pMac, LOGE, FL("mem alloc failed for ChannelList")); + status = eHAL_STATUS_FAILURE; + break; + } + pProfile->ChannelInfo.ChannelList[0] = pNeighborRoamInfo->handoffReqInfo.channel; + + /* + * For User space connect requests, the scan has already been done. + * So, check if the BSS descriptor exists in the scan cache and + * proceed with the handoff instead of a redundant scan again. + */ + if (pNeighborRoamInfo->handoffReqInfo.src == CONNECT_CMD_USERSPACE) { + smsLog(pMac, LOG1, FL("Connect cmd with bssid within same ESS")); + status = csrNeighborRoamPrepareScanProfileFilter( + pMac, &scan_filter); + smsLog(pMac, LOG1, FL("Filter creation status = %d"), status); + status = csrScanGetResult(pMac, &scan_filter, &scan_result); + roam_now = csrNeighborRoamProcessScanResults(pMac, &scan_result); + roamable_ap_count = csrLLCount(&pNeighborRoamInfo->roamableAPList); + csrFreeScanFilter(pMac, &scan_filter); + smsLog(pMac, LOG1, FL("roam_now=%d, roamable_ap_count=%d"), + roam_now, roamable_ap_count); + } + if (roam_now && roamable_ap_count) { + csrNeighborRoamTriggerHandoff(pMac, pNeighborRoamInfo); + } else { + status = csrScanForSSID(pMac, pSession->sessionId, + pProfile, roamId, FALSE); + if(!HAL_STATUS_SUCCESS(status)) + smsLog(pMac, LOGE, FL("SSID scan failed")); + } + }while(0); + + if(NULL != pProfile) + { + csrReleaseProfile(pMac, pProfile); + vos_mem_free(pProfile); + } + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamSssidScanDone + + \brief This function is called once SSID scan is done. If SSID scan failed + to find our candidate add an entry to csr scan cache ourself before starting + the handoff process + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamSssidScanDone(tpAniSirGlobal pMac, eHalStatus status) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus hstatus; + + smsLog(pMac, LOGE, FL("called ")); + + /* we must be in connected state, if not ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it")); + return eHAL_STATUS_FAILURE; + } + + //if SSID scan failed to find our candidate add an entry to csr scan cache ourself + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL("Add an entry to csr scan cache")); + hstatus = csrScanCreateEntryInScanCache(pMac, pNeighborRoamInfo->csrSessionId, + pNeighborRoamInfo->handoffReqInfo.bssid, + pNeighborRoamInfo->handoffReqInfo.channel); + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("csrScanCreateEntryInScanCache failed with status %d"), hstatus); + return eHAL_STATUS_FAILURE; + } + } + + /* Now we have completed scanning for the candidate provided by HDD. Let move on to HO*/ + hstatus = csrNeighborRoamProcessScanComplete(pMac); + + if (eHAL_STATUS_SUCCESS != hstatus) + { + smsLog(pMac, LOGE, FL("Neighbor scan process complete failed with status %d"), hstatus); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} + +/** + * csr_neighbor_roam_handler_assign_handoff_src() - Assign source of + * roam handoff + * @pNeighborRoamInfo: Pointer to csr neighbor roam control info + * @pHandoffReqInfo: Pointer to the Handoff request + * + * Return: None + */ +#ifndef QCA_WIFI_ISOC +static inline void csr_neighbor_roam_handler_assign_handoff_src( + tpCsrNeighborRoamControlInfo pNeighborRoamInfo, + tAniHandoffReq *pHandoffReqInfo) +{ + pNeighborRoamInfo->handoffReqInfo.src + = pHandoffReqInfo->handoff_src; +} +#else +static inline void csr_neighbor_roam_handler_assign_handoff_src( + tpCsrNeighborRoamControlInfo pNeighborRoamInfo, + tAniHandoffReq *pHandoffReqInfo) +{ +} +#endif + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamHandoffReqHdlr + + \brief This function is called by CSR as soon as it gets a handoff request + to SME via MC thread + + \param pMac - The handle returned by macOpen. + pMsg - Msg sent by HDD + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamHandoffReqHdlr(tpAniSirGlobal pMac, void* pMsg) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tAniHandoffReq *pHandoffReqInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + /* we must be in connected state, if not ignore it */ + if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state. Ignore it")); + status = eHAL_STATUS_FAILURE; + } + else + { + //save the handoff info came from HDD as part of the reassoc req + pHandoffReqInfo = (tAniHandoffReq *)pMsg; + if (NULL != pHandoffReqInfo) + { + //sanity check + if (VOS_FALSE == vos_mem_compare(pHandoffReqInfo->bssid, + pNeighborRoamInfo->currAPbssid, + sizeof(tSirMacAddr))) + { + + pNeighborRoamInfo->handoffReqInfo.channel = pHandoffReqInfo->channel; + csr_neighbor_roam_handler_assign_handoff_src(pNeighborRoamInfo, + pHandoffReqInfo); + vos_mem_copy(pNeighborRoamInfo->handoffReqInfo.bssid, + pHandoffReqInfo->bssid, + 6); + pNeighborRoamInfo->uOsRequestedHandoff = 1; + status = csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_STOP, + REASON_OS_REQUESTED_ROAMING_NOW); + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("csrRoamOffloadScan failed")); + pNeighborRoamInfo->uOsRequestedHandoff = 0; + } + } + else + { + smsLog(pMac, LOGE, FL("Received req has same BSSID as current AP!!")); + status = eHAL_STATUS_FAILURE; + } + } + else + { + smsLog(pMac, LOGE, FL("Received msg is NULL")); + status = eHAL_STATUS_FAILURE; + } + } + + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamProceedWithHandoffReq + + \brief This function is called by CSR as soon as it gets rsp back for + ROAM_SCAN_OFFLOAD_STOP with reason REASON_OS_REQUESTED_ROAMING_NOW + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamProceedWithHandoffReq(tpAniSirGlobal pMac) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + /* we must be in connected state, if not ignore it */ + if ((eCSR_NEIGHBOR_ROAM_STATE_CONNECTED != pNeighborRoamInfo->neighborRoamState) + || (!pNeighborRoamInfo->uOsRequestedHandoff)) + { + smsLog(pMac, LOGE, FL("Received in not CONNECTED state or uOsRequestedHandoff is not set. Ignore it")); + status = eHAL_STATUS_FAILURE; + } + else + { + //Let's go ahead with handoff + status = csrNeighborRoamProcessHandoffReq(pMac); + } + if(!HAL_STATUS_SUCCESS(status)) + { + pNeighborRoamInfo->uOsRequestedHandoff = 0; + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn csrNeighborRoamStartLfrScan + + \brief This function is called if HDD requested handoff failed for some + reason. start the LFR logic at that point.By the time, this function is + called, a STOP command has already been issued. + + \param pMac - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise + +---------------------------------------------------------------------------*/ +eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 OffloadCmdStopReason) +{ + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + + smsLog(pMac, LOGE, + FL(" uOsRequestedHandoff=%d isForcedInitialRoamTo5GH=%d OffloadCmdStopReason = %d"), + pNeighborRoamInfo->uOsRequestedHandoff, + pNeighborRoamInfo->isForcedInitialRoamTo5GH, + OffloadCmdStopReason); + + if(OffloadCmdStopReason == REASON_OS_REQUESTED_ROAMING_NOW) + pNeighborRoamInfo->uOsRequestedHandoff = 0; + if(OffloadCmdStopReason == REASON_INITIAL_FORCED_ROAM_TO_5G) + pNeighborRoamInfo->isForcedInitialRoamTo5GH = 0; + /* There is no candidate or We are not roaming Now. + * Inform the FW to restart Roam Offload Scan */ + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_START, REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + + return eHAL_STATUS_SUCCESS; +} +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrTdlsProcess.c b/drivers/staging/prima/CORE/SME/src/csr/csrTdlsProcess.c new file mode 100644 index 000000000000..77a084d3de8c --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrTdlsProcess.c @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrTdlsProcess.c + + Implementation for the TDLS interface to PE. + + Copyright (C) 2010 Qualcomm, Incorporated + + + ========================================================================== */ + +#ifdef FEATURE_WLAN_TDLS + +#include "aniGlobal.h" //for tpAniSirGlobal +#include "palApi.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "smsDebug.h" + +#include "csrSupport.h" +#include "wlan_qct_tl.h" + +#include "vos_diag_core_log.h" +#include "vos_diag_core_event.h" +#include "csrInternal.h" + + +/* + * common routine to remove TDLS cmd from SME command list.. + * commands are removed after getting reponse from PE. + */ +eHalStatus csrTdlsRemoveSmeCmd(tpAniSirGlobal pMac, eSmeCommandType cmdType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tListElem *pEntry; + tSmeCmd *pCommand; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( cmdType == pCommand->command ) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + pEntry, LL_ACCESS_LOCK ) ) + { + vos_mem_zero( &pCommand->u.tdlsCmd, sizeof( tTdlsCmd ) ); + csrReleaseCommand( pMac, pCommand ); + smeProcessPendingQueue( pMac ); + status = eHAL_STATUS_SUCCESS ; + } + } + } + return status ; +} + +/* + * TDLS request API, called from HDD to send a TDLS frame + * in SME/CSR and send message to PE to trigger TDLS discovery procedure. + */ +eHalStatus csrTdlsSendMgmtReq(tHalHandle hHal, tANI_U8 sessionId, tCsrTdlsSendMgmt *tdlsSendMgmt) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsSendMgmtCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != tdlsSendMgmt) ) + { + tdlsSendMgmtCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsSendMgmtCmd) + { + tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = + &tdlsSendMgmtCmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; + + vos_mem_zero(&tdlsSendMgmtCmd->u.tdlsCmd, sizeof(tTdlsCmd)); + + tdlsSendMgmtCmd->sessionId = sessionId; + + tdlsSendMgmtCmdInfo->frameType = tdlsSendMgmt->frameType ; + tdlsSendMgmtCmdInfo->dialog = tdlsSendMgmt->dialog ; + tdlsSendMgmtCmdInfo->statusCode = tdlsSendMgmt->statusCode ; + tdlsSendMgmtCmdInfo->responder = tdlsSendMgmt->responder; + tdlsSendMgmtCmdInfo->peerCapability = tdlsSendMgmt->peerCapability; + vos_mem_copy(tdlsSendMgmtCmdInfo->peerMac, + tdlsSendMgmt->peerMac, sizeof(tSirMacAddr)) ; + + if( (0 != tdlsSendMgmt->len) && (NULL != tdlsSendMgmt->buf) ) + { + tdlsSendMgmtCmdInfo->buf = vos_mem_malloc(tdlsSendMgmt->len); + if ( NULL == tdlsSendMgmtCmdInfo->buf ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Alloc Failed") ); + VOS_ASSERT(0) ; + return status ; + } + vos_mem_copy(tdlsSendMgmtCmdInfo->buf, + tdlsSendMgmt->buf, tdlsSendMgmt->len ); + tdlsSendMgmtCmdInfo->len = tdlsSendMgmt->len; + } + else + { + tdlsSendMgmtCmdInfo->buf = NULL; + tdlsSendMgmtCmdInfo->len = 0; + } + + tdlsSendMgmtCmd->command = eSmeCommandTdlsSendMgmt ; + tdlsSendMgmtCmd->u.tdlsCmd.size = sizeof(tTdlsSendMgmtCmdInfo) ; + smePushCommand(pMac, tdlsSendMgmtCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + smsLog( pMac, LOG1, + FL("Successfully posted tdlsSendMgmtCmd to SME")); + } + } + + return status ; +} + +/* + * TDLS request API, called from HDD to modify an existing TDLS peer + */ +eHalStatus csrTdlsChangePeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrStaParams *pstaParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsAddStaCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + if (NULL == pstaParams) + return status; + + //If connected and in Infra. Only then allow this + if (CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac)){ + + tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; + + if (tdlsAddStaCmd) + { + tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = + &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; + + vos_mem_zero(&tdlsAddStaCmd->u.tdlsCmd, sizeof(tTdlsCmd)); + + tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_UPDATE; + + tdlsAddStaCmd->sessionId = sessionId; + + vos_mem_copy(tdlsAddStaCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)) ; + tdlsAddStaCmdInfo->capability = pstaParams->capability; + tdlsAddStaCmdInfo->uapsdQueues = pstaParams->uapsd_queues; + tdlsAddStaCmdInfo->maxSp = pstaParams->max_sp; + vos_mem_copy(tdlsAddStaCmdInfo->extnCapability, + pstaParams->extn_capability, + sizeof(pstaParams->extn_capability)); + + tdlsAddStaCmdInfo->htcap_present = pstaParams->htcap_present; + if(pstaParams->htcap_present) + vos_mem_copy( &tdlsAddStaCmdInfo->HTCap, + &pstaParams->HTCap, sizeof(pstaParams->HTCap)); + else + vos_mem_set(&tdlsAddStaCmdInfo->HTCap, sizeof(pstaParams->HTCap), 0); + + tdlsAddStaCmdInfo->vhtcap_present = pstaParams->vhtcap_present; + if(pstaParams->vhtcap_present) + vos_mem_copy( &tdlsAddStaCmdInfo->VHTCap, + &pstaParams->VHTCap, sizeof(pstaParams->VHTCap)); + else + vos_mem_set(&tdlsAddStaCmdInfo->VHTCap, sizeof(pstaParams->VHTCap), 0); + + tdlsAddStaCmdInfo->supportedRatesLen = pstaParams->supported_rates_len; + + if (0 != pstaParams->supported_rates_len) + vos_mem_copy( &tdlsAddStaCmdInfo->supportedRates, + pstaParams->supported_rates, + pstaParams->supported_rates_len); + + tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer; + tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; + smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; + smsLog( pMac, LOG1, + FL("Successfully posted tdlsAddStaCmd to SME to modify peer ")); + status = eHAL_STATUS_SUCCESS ; + } + } + + return status ; +} +/* + * TDLS request API, called from HDD to Send Link Establishment Parameters + */ +VOS_STATUS csrTdlsSendLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsLinkEstablishCmd; + eHalStatus status = eHAL_STATUS_FAILURE ; + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsLinkEstablishCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsLinkEstablishCmd) + { + tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo = + &tdlsLinkEstablishCmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo ; + + vos_mem_zero(&tdlsLinkEstablishCmd->u.tdlsCmd, sizeof(tTdlsCmd)); + + tdlsLinkEstablishCmd->sessionId = sessionId; + + vos_mem_copy( tdlsLinkEstablishCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)); + tdlsLinkEstablishCmdInfo->isBufSta = tdlsLinkEstablishParams->isBufSta; + tdlsLinkEstablishCmdInfo->isResponder = tdlsLinkEstablishParams->isResponder; + tdlsLinkEstablishCmdInfo->maxSp = tdlsLinkEstablishParams->maxSp; + tdlsLinkEstablishCmdInfo->uapsdQueues = tdlsLinkEstablishParams->uapsdQueues; + tdlsLinkEstablishCmdInfo->isOffChannelSupported = + tdlsLinkEstablishParams->isOffChannelSupported; + + vos_mem_copy(tdlsLinkEstablishCmdInfo->supportedChannels, + tdlsLinkEstablishParams->supportedChannels, + tdlsLinkEstablishParams->supportedChannelsLen); + tdlsLinkEstablishCmdInfo->supportedChannelsLen = + tdlsLinkEstablishParams->supportedChannelsLen; + + vos_mem_copy(tdlsLinkEstablishCmdInfo->supportedOperClasses, + tdlsLinkEstablishParams->supportedOperClasses, + tdlsLinkEstablishParams->supportedOperClassesLen); + tdlsLinkEstablishCmdInfo->supportedOperClassesLen = + tdlsLinkEstablishParams->supportedOperClassesLen; + tdlsLinkEstablishCmdInfo->isResponder= tdlsLinkEstablishParams->isResponder; + tdlsLinkEstablishCmdInfo->maxSp= tdlsLinkEstablishParams->maxSp; + tdlsLinkEstablishCmdInfo->uapsdQueues= tdlsLinkEstablishParams->uapsdQueues; + tdlsLinkEstablishCmd->command = eSmeCommandTdlsLinkEstablish ; + tdlsLinkEstablishCmd->u.tdlsCmd.size = sizeof(tTdlsLinkEstablishCmdInfo) ; + smePushCommand(pMac, tdlsLinkEstablishCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + smsLog( pMac, LOG1, + FL("Successfully posted tdlsLinkEstablishCmd to SME")); + } + } + + return status ; +} + +/* + * TDLS request API, called from HDD to add a TDLS peer + */ +eHalStatus csrTdlsAddPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif + ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsAddStaCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsAddStaCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsAddStaCmd) + { + tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = + &tdlsAddStaCmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; + + vos_mem_zero(&tdlsAddStaCmd->u.tdlsCmd, sizeof(tTdlsCmd)); + + tdlsAddStaCmd->sessionId = sessionId; + tdlsAddStaCmdInfo->tdlsAddOper = TDLS_OPER_ADD; + + vos_mem_copy( tdlsAddStaCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)) ; + + tdlsAddStaCmd->command = eSmeCommandTdlsAddPeer ; + tdlsAddStaCmd->u.tdlsCmd.size = sizeof(tTdlsAddStaCmdInfo) ; + smePushCommand(pMac, tdlsAddStaCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + smsLog( pMac, LOG1, + FL("Successfully posted tdlsAddStaCmd to SME")); + } + } + + return status ; +} + +/* + * TDLS request API, called from HDD to delete a TDLS peer + */ +eHalStatus csrTdlsDelPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsDelStaCmd ; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsDelStaCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsDelStaCmd) + { + tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo = + &tdlsDelStaCmd->u.tdlsCmd.u.tdlsDelStaCmdInfo ; + + vos_mem_zero(&tdlsDelStaCmd->u.tdlsCmd, sizeof(tTdlsCmd)); + + tdlsDelStaCmd->sessionId = sessionId; + + vos_mem_copy(tdlsDelStaCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)) ; + + tdlsDelStaCmd->command = eSmeCommandTdlsDelPeer ; + tdlsDelStaCmd->u.tdlsCmd.size = sizeof(tTdlsDelStaCmdInfo) ; + smePushCommand(pMac, tdlsDelStaCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + smsLog( pMac, LOG1, + FL("Successfully posted tdlsDelStaCmd to SME")); + } + } + + return status ; +} + +//tdlsoffchan +/* + * TDLS request API, called from HDD to Send Channel Switch Parameters + */ +VOS_STATUS csrTdlsSendChanSwitchReq(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tANI_S32 tdlsOffCh, + tANI_S32 tdlsOffChBwOffset, + tANI_U8 tdlsSwMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *tdlsChanSwitchCmd; + eHalStatus status = eHAL_STATUS_FAILURE ; + + //If connected and in Infra. Only then allow this + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && + csrIsConnStateConnectedInfra( pMac, sessionId ) && + (NULL != peerMac) ) + { + tdlsChanSwitchCmd = csrGetCommandBuffer(pMac) ; + + if(tdlsChanSwitchCmd) + { + tTdlsChanSwitchCmdInfo *tdlsChanSwitchCmdInfo = + &tdlsChanSwitchCmd->u.tdlsCmd.u.tdlsChanSwitchCmdInfo; + + vos_mem_zero(&tdlsChanSwitchCmd->u.tdlsCmd, sizeof(tTdlsCmd)); + + tdlsChanSwitchCmd->sessionId = sessionId; + + vos_mem_copy(tdlsChanSwitchCmdInfo->peerMac, + peerMac, sizeof(tSirMacAddr)); + tdlsChanSwitchCmdInfo->tdlsOffCh = tdlsOffCh; + tdlsChanSwitchCmdInfo->tdlsOffChBwOffset = tdlsOffChBwOffset; + tdlsChanSwitchCmdInfo->tdlsSwMode = tdlsSwMode; + + tdlsChanSwitchCmd->command = eSmeCommandTdlsChannelSwitch; + tdlsChanSwitchCmd->u.tdlsCmd.size = sizeof(tTdlsChanSwitchCmdInfo) ; + smePushCommand(pMac, tdlsChanSwitchCmd, FALSE) ; + status = eHAL_STATUS_SUCCESS ; + smsLog( pMac, LOG1, + FL("Successfully posted tdlsChanSwitchCmd to SME")); + } + } + + return status ; +} + + +/* + * TDLS messages sent to PE . + */ +eHalStatus tdlsSendMessage(tpAniSirGlobal pMac, tANI_U16 msg_type, + void *msg_data, tANI_U32 msg_size) +{ + + tSirMbMsg *pMsg = (tSirMbMsg *)msg_data ; + pMsg->type = msg_type ; + pMsg->msgLen = (tANI_U16) (msg_size) ; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("sending msg = %d"), pMsg->type) ; + /* Send message. */ + if (palSendMBMessage(pMac->hHdd, pMsg) != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, FL("Cannot send message")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrTdlsProcessSendMgmt( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsSendMgmtCmdInfo *tdlsSendMgmtCmdInfo = &cmd->u.tdlsCmd.u.tdlsSendMgmtCmdInfo ; + tSirTdlsSendMgmtReq *tdlsSendMgmtReq = NULL ; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + if (NULL == pSession->pConnectBssDesc) + { + smsLog( pMac, LOGE, FL("BSS Description is not present") ); + return eHAL_STATUS_FAILURE; + } + + tdlsSendMgmtReq = vos_mem_malloc( + sizeof(tSirTdlsSendMgmtReq) + tdlsSendMgmtCmdInfo->len); + if ( NULL == tdlsSendMgmtReq ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("alloc failed") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsSendMgmtReq->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsSendMgmtReq->transactionId = tdlsSendMgmtCmdInfo->dialog; + tdlsSendMgmtReq->reqType = tdlsSendMgmtCmdInfo->frameType ; + tdlsSendMgmtReq->dialog = tdlsSendMgmtCmdInfo->dialog ; + tdlsSendMgmtReq->statusCode = tdlsSendMgmtCmdInfo->statusCode ; + tdlsSendMgmtReq->responder = tdlsSendMgmtCmdInfo->responder; + tdlsSendMgmtReq->peerCapability = tdlsSendMgmtCmdInfo->peerCapability; + + vos_mem_copy(tdlsSendMgmtReq->bssid, + pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); + + vos_mem_copy(tdlsSendMgmtReq->peerMac, + tdlsSendMgmtCmdInfo->peerMac, sizeof(tSirMacAddr)) ; + + if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) + { + vos_mem_copy(tdlsSendMgmtReq->addIe, tdlsSendMgmtCmdInfo->buf, + tdlsSendMgmtCmdInfo->len); + + } + // Send the request to PE. + smsLog( pMac, LOG1, FL("sending TDLS Mgmt Frame req to PE " )); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_SEND_MGMT_REQ, + (void *)tdlsSendMgmtReq , sizeof(tSirTdlsSendMgmtReq)+tdlsSendMgmtCmdInfo->len) ; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC")); + } + if(tdlsSendMgmtCmdInfo->len && tdlsSendMgmtCmdInfo->buf) + { + //Done with the buf. Free it. + vos_mem_free( tdlsSendMgmtCmdInfo->buf ); + tdlsSendMgmtCmdInfo->buf = NULL; + tdlsSendMgmtCmdInfo->len = 0; + } + + return status; +} + +eHalStatus csrTdlsProcessAddSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsAddStaCmdInfo *tdlsAddStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsAddStaCmdInfo ; + tSirTdlsAddStaReq *tdlsAddStaReq = NULL ; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pSession->pConnectBssDesc) + { + smsLog( pMac, LOGE, FL("BSS description is not present") ); + return eHAL_STATUS_FAILURE; + } + + tdlsAddStaReq = vos_mem_malloc(sizeof(tSirTdlsAddStaReq)); + if ( NULL == tdlsAddStaReq ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("alloc failed") ); + VOS_ASSERT(0) ; + return status ; + } + vos_mem_set(tdlsAddStaReq, sizeof(tSirTdlsAddStaReq), 0); + + tdlsAddStaReq->sessionId = cmd->sessionId; + tdlsAddStaReq->tdlsAddOper = tdlsAddStaCmdInfo->tdlsAddOper; + //Using dialog as transactionId. This can be used to match response with request + tdlsAddStaReq->transactionId = 0; + + vos_mem_copy( tdlsAddStaReq->bssid, + pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); + + vos_mem_copy( tdlsAddStaReq->peerMac, + tdlsAddStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; + + tdlsAddStaReq->capability = tdlsAddStaCmdInfo->capability; + tdlsAddStaReq->uapsd_queues = tdlsAddStaCmdInfo->uapsdQueues; + tdlsAddStaReq->max_sp = tdlsAddStaCmdInfo->maxSp; + + vos_mem_copy( tdlsAddStaReq->extn_capability, + tdlsAddStaCmdInfo->extnCapability, + SIR_MAC_MAX_EXTN_CAP); + tdlsAddStaReq->htcap_present = tdlsAddStaCmdInfo->htcap_present; + vos_mem_copy( &tdlsAddStaReq->htCap, + &tdlsAddStaCmdInfo->HTCap, sizeof(tdlsAddStaCmdInfo->HTCap)); + tdlsAddStaReq->vhtcap_present = tdlsAddStaCmdInfo->vhtcap_present; + vos_mem_copy( &tdlsAddStaReq->vhtCap, + &tdlsAddStaCmdInfo->VHTCap, sizeof(tdlsAddStaCmdInfo->VHTCap)); + tdlsAddStaReq->supported_rates_length = tdlsAddStaCmdInfo->supportedRatesLen; + vos_mem_copy( &tdlsAddStaReq->supported_rates, + tdlsAddStaCmdInfo->supportedRates, tdlsAddStaCmdInfo->supportedRatesLen); + + // Send the request to PE. + smsLog( pMac, LOGE, "sending TDLS Add Sta req to PE " ); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_ADD_STA_REQ, + (void *)tdlsAddStaReq , sizeof(tSirTdlsAddStaReq)) ; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC")); + } + return status; +} + +eHalStatus csrTdlsProcessDelSta( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsDelStaCmdInfo *tdlsDelStaCmdInfo = &cmd->u.tdlsCmd.u.tdlsDelStaCmdInfo ; + tSirTdlsDelStaReq *tdlsDelStaReq = NULL ; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + eHalStatus status = eHAL_STATUS_FAILURE; + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pSession->pConnectBssDesc) + { + smsLog( pMac, LOGE, FL("BSS description is not present") ); + return eHAL_STATUS_FAILURE; + } + + tdlsDelStaReq = vos_mem_malloc(sizeof(tSirTdlsDelStaReq)); + if ( NULL == tdlsDelStaReq ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + + + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("alloc failed") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsDelStaReq->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsDelStaReq->transactionId = 0; + + vos_mem_copy( tdlsDelStaReq->bssid, + pSession->pConnectBssDesc->bssId, sizeof (tSirMacAddr)); + + vos_mem_copy( tdlsDelStaReq->peerMac, + tdlsDelStaCmdInfo->peerMac, sizeof(tSirMacAddr)) ; + + // Send the request to PE. + smsLog( pMac, LOG1, + "sending TDLS Del Sta "MAC_ADDRESS_STR" req to PE", + MAC_ADDR_ARRAY(tdlsDelStaCmdInfo->peerMac)); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_DEL_STA_REQ, + (void *)tdlsDelStaReq , sizeof(tSirTdlsDelStaReq)) ; + if(!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC")); + } + return status; +} +/* + * commands received from CSR + */ +eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac, tSmeCmd *cmd) +{ + eSmeCommandType cmdType = cmd->command ; + eHalStatus status = eHAL_STATUS_SUCCESS; + switch(cmdType) + { + case eSmeCommandTdlsSendMgmt: + status = csrTdlsProcessSendMgmt(pMac, cmd); + break ; + case eSmeCommandTdlsAddPeer: + status = csrTdlsProcessAddSta(pMac, cmd); + break; + case eSmeCommandTdlsDelPeer: + status = csrTdlsProcessDelSta(pMac, cmd); + break; + case eSmeCommandTdlsLinkEstablish: + status = csrTdlsProcessLinkEstablish(pMac, cmd); + break; +// tdlsoffchan + case eSmeCommandTdlsChannelSwitch: + status = csrTdlsProcessChanSwitchReq(pMac, cmd); + break; + default: + status = eHAL_STATUS_FAILURE; + /* TODO: Add defualt handling */ + break ; + } + return status ; +} + +eHalStatus csrTdlsProcessLinkEstablish( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsLinkEstablishCmdInfo *tdlsLinkEstablishCmdInfo = &cmd->u.tdlsCmd.u.tdlsLinkEstablishCmdInfo ; + tSirTdlsLinkEstablishReq *tdlsLinkEstablishReq = NULL ; + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + tdlsLinkEstablishReq = vos_mem_malloc(sizeof(tSirTdlsLinkEstablishReq)); + + if (tdlsLinkEstablishReq == NULL) + { + smsLog( pMac, LOGE, FL("alloc failed \n") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsLinkEstablishReq->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsLinkEstablishReq->transactionId = 0; + vos_mem_copy(tdlsLinkEstablishReq->peerMac, + tdlsLinkEstablishCmdInfo->peerMac, sizeof(tSirMacAddr)); + vos_mem_copy(tdlsLinkEstablishReq->bssid, pSession->pConnectBssDesc->bssId, + sizeof (tSirMacAddr)); + vos_mem_copy(tdlsLinkEstablishReq->supportedChannels, + tdlsLinkEstablishCmdInfo->supportedChannels, + tdlsLinkEstablishCmdInfo->supportedChannelsLen); + tdlsLinkEstablishReq->supportedChannelsLen = + tdlsLinkEstablishCmdInfo->supportedChannelsLen; + vos_mem_copy(tdlsLinkEstablishReq->supportedOperClasses, + tdlsLinkEstablishCmdInfo->supportedOperClasses, + tdlsLinkEstablishCmdInfo->supportedOperClassesLen); + tdlsLinkEstablishReq->supportedOperClassesLen = + tdlsLinkEstablishCmdInfo->supportedOperClassesLen; + tdlsLinkEstablishReq->isBufSta = tdlsLinkEstablishCmdInfo->isBufSta; + tdlsLinkEstablishReq->isResponder= tdlsLinkEstablishCmdInfo->isResponder; + tdlsLinkEstablishReq->uapsdQueues= tdlsLinkEstablishCmdInfo->uapsdQueues; + tdlsLinkEstablishReq->maxSp= tdlsLinkEstablishCmdInfo->maxSp; + tdlsLinkEstablishReq->isOffChannelSupported = + tdlsLinkEstablishCmdInfo->isOffChannelSupported; + + // Send the request to PE. + smsLog( pMac, LOGE, "sending TDLS Link Establish Request to PE \n" ); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_LINK_ESTABLISH_REQ, + (void *)tdlsLinkEstablishReq, + sizeof(tSirTdlsLinkEstablishReq)); + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC\n")); + } + return status; +} + +// tdlsoffchan +eHalStatus csrTdlsProcessChanSwitchReq( tpAniSirGlobal pMac, tSmeCmd *cmd ) +{ + tTdlsChanSwitchCmdInfo *tdlsChanSwitchCmdInfo = &cmd->u.tdlsCmd.u.tdlsChanSwitchCmdInfo ; + tSirTdlsChanSwitch *tdlsChanSwitch = NULL ; + eHalStatus status = eHAL_STATUS_FAILURE; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId ); + + if (NULL == pSession) + { + smsLog( pMac, LOGE, FL("pSession is NULL")); + return eHAL_STATUS_FAILURE; + } + + tdlsChanSwitch = vos_mem_malloc(sizeof(tSirTdlsChanSwitch)); + if (tdlsChanSwitch == NULL) + { + smsLog( pMac, LOGE, FL("alloc failed \n") ); + VOS_ASSERT(0) ; + return status ; + } + tdlsChanSwitch->sessionId = cmd->sessionId; + //Using dialog as transactionId. This can be used to match response with request + tdlsChanSwitch->transactionId = 0; + vos_mem_copy( tdlsChanSwitch->peerMac, + tdlsChanSwitchCmdInfo->peerMac, sizeof(tSirMacAddr)); + vos_mem_copy(tdlsChanSwitch->bssid, pSession->pConnectBssDesc->bssId, + sizeof (tSirMacAddr)); + + tdlsChanSwitch->tdlsOffCh = tdlsChanSwitchCmdInfo->tdlsOffCh; + tdlsChanSwitch->tdlsOffChBwOffset = tdlsChanSwitchCmdInfo->tdlsOffChBwOffset; + tdlsChanSwitch->tdlsSwMode = tdlsChanSwitchCmdInfo->tdlsSwMode; + + // Send the request to PE. + smsLog( pMac, LOGE, "sending TDLS Channel Switch to PE \n" ); + status = tdlsSendMessage(pMac, eWNI_SME_TDLS_CHANNEL_SWITCH_REQ, + (void *)tdlsChanSwitch, + sizeof(tSirTdlsChanSwitch)); + if (!HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("Failed to send request to MAC\n")); + } + return status; +} + +/* + * TDLS Message processor, will be called after TDLS message recieved from + * PE + */ +eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac, v_U16_t msgType, + void *pMsgBuf) +{ + switch(msgType) + { + case eWNI_SME_TDLS_SEND_MGMT_RSP: + { + tSirSmeRsp *pMsg = (tSirSmeRsp*) pMsgBuf; + tCsrRoamInfo roamInfo = {0} ; + + /* remove pending eSmeCommandTdlsDiscovery command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsSendMgmt) ; + + if (eSIR_SME_SUCCESS != pMsg->statusCode) + { + /* Tx failed, so there wont be any ack confirmation*/ + /* Indicate ack failure to upper layer */ + roamInfo.reasonCode = 0; + csrRoamCallCallback(pMac, pMsg->sessionId, &roamInfo, + 0, eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, 0); + } + } + break; + case eWNI_SME_TDLS_ADD_STA_RSP: + { + tSirTdlsAddStaRsp *addStaRsp = (tSirTdlsAddStaRsp *) pMsgBuf ; + eCsrRoamResult roamResult ; + tCsrRoamInfo roamInfo = {0} ; + vos_mem_copy( &roamInfo.peerMac, addStaRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = addStaRsp->staId ; + roamInfo.ucastSig = addStaRsp->ucastSig ; + roamInfo.bcastSig = addStaRsp->bcastSig ; + roamInfo.statusCode = addStaRsp->statusCode ; + /* + * register peer with TL, we have to go through HDD as this is + * the only way to register any STA with TL. + */ + if (addStaRsp->tdlsAddOper == TDLS_OPER_ADD) + roamResult = eCSR_ROAM_RESULT_ADD_TDLS_PEER; + else /* addStaRsp->tdlsAddOper must be TDLS_OPER_UPDATE */ + roamResult = eCSR_ROAM_RESULT_UPDATE_TDLS_PEER; + csrRoamCallCallback(pMac, addStaRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + roamResult); + + /* remove pending eSmeCommandTdlsDiscovery command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsAddPeer) ; + } + break; + case eWNI_SME_TDLS_DEL_STA_RSP: + { + tSirTdlsDelStaRsp *delStaRsp = (tSirTdlsDelStaRsp *) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; + + vos_mem_copy( &roamInfo.peerMac, delStaRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = delStaRsp->staId ; + roamInfo.statusCode = delStaRsp->statusCode ; + /* + * register peer with TL, we have to go through HDD as this is + * the only way to register any STA with TL. + */ + csrRoamCallCallback(pMac, delStaRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_DELETE_TDLS_PEER); + + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsDelPeer) ; + } + break; + case eWNI_SME_TDLS_DEL_STA_IND: + { + tpSirTdlsDelStaInd pSirTdlsDelStaInd = (tpSirTdlsDelStaInd) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; + vos_mem_copy( &roamInfo.peerMac, pSirTdlsDelStaInd->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = pSirTdlsDelStaInd->staId ; + roamInfo.reasonCode = pSirTdlsDelStaInd->reasonCode ; + + /* Sending the TEARDOWN indication to HDD. */ + csrRoamCallCallback(pMac, pSirTdlsDelStaInd->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND); + break ; + } + case eWNI_SME_TDLS_DEL_ALL_PEER_IND: + { + tpSirTdlsDelAllPeerInd pSirTdlsDelAllPeerInd = (tpSirTdlsDelAllPeerInd) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; + + /* Sending the TEARDOWN indication to HDD. */ + csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND); + break ; + } + case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: + { + tpSirMgmtTxCompletionInd pSirTdlsDelAllPeerInd = (tpSirMgmtTxCompletionInd) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; + roamInfo.reasonCode = pSirTdlsDelAllPeerInd->txCompleteStatus; + + csrRoamCallCallback(pMac, pSirTdlsDelAllPeerInd->sessionId, &roamInfo, + 0, eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND, 0); + break; + } + case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: + { + tSirTdlsLinkEstablishReqRsp *linkEstablishReqRsp = (tSirTdlsLinkEstablishReqRsp *) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; +#if 0 + vos_mem_copy(&roamInfo.peerMac, delStaRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = delStaRsp->staId ; + roamInfo.statusCode = delStaRsp->statusCode ; +#endif + vos_mem_copy(&roamInfo.peerMac, linkEstablishReqRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = (tANI_U8)linkEstablishReqRsp->sta_idx; + roamInfo.statusCode = linkEstablishReqRsp->statusCode; + + csrRoamCallCallback(pMac, linkEstablishReqRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP); + /* remove pending eSmeCommandTdlsLinkEstablish command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsLinkEstablish); + break; + } + + case eWNI_SME_TDLS_CHANNEL_SWITCH_RSP: + { +#if 0 + tSirTdlsChanSwitchReqRsp *ChanSwitchReqRsp = (tSirTdlsChanSwitchReqRsp *) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; + vos_mem_copy(&roamInfo.peerMac, delStaRsp->peerMac, + sizeof(tSirMacAddr)) ; + roamInfo.staId = delStaRsp->staId ; + roamInfo.statusCode = delStaRsp->statusCode ; + csrRoamCallCallback(pMac, ChanSwitchReqRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP); +#endif + tSirTdlsChanSwitchReqRsp *ChanSwitchReqRsp = + (tSirTdlsChanSwitchReqRsp *) pMsgBuf ; + tCsrRoamInfo roamInfo = {0} ; + + vos_mem_copy(&roamInfo.peerMac, ChanSwitchReqRsp->peerMac, + sizeof(tSirMacAddr)); + roamInfo.staId = (tANI_U8)ChanSwitchReqRsp->sta_idx; + roamInfo.statusCode = ChanSwitchReqRsp->statusCode; + + csrRoamCallCallback(pMac, ChanSwitchReqRsp->sessionId, &roamInfo, 0, + eCSR_ROAM_TDLS_STATUS_UPDATE, + eCSR_ROAM_RESULT_CHANNEL_SWITCH_REQ_RSP); + + /* remove pending eSmeCommandTdlsChanSwitch command */ + csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsChannelSwitch); + break; + } + default: + { + break ; + } + } + + return eHAL_STATUS_SUCCESS ; +} +#endif diff --git a/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c b/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c new file mode 100644 index 000000000000..52687fe9c68e --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csrUtil.c @@ -0,0 +1,6992 @@ +/* + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file csrUtil.c + + Implementation supporting routines for CSR. + ========================================================================== */ + + +#include "aniGlobal.h" + +#include "palApi.h" +#include "csrSupport.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "smeQosInternal.h" +#include "wlan_qct_wda.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "vos_utils.h" +#include "csrEse.h" +#endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD*/ +tANI_U8 csrWpaOui[][ CSR_WPA_OUI_SIZE ] = { + { 0x00, 0x50, 0xf2, 0x00 }, + { 0x00, 0x50, 0xf2, 0x01 }, + { 0x00, 0x50, 0xf2, 0x02 }, + { 0x00, 0x50, 0xf2, 0x03 }, + { 0x00, 0x50, 0xf2, 0x04 }, + { 0x00, 0x50, 0xf2, 0x05 }, +#ifdef FEATURE_WLAN_ESE + { 0x00, 0x40, 0x96, 0x00 }, // CCKM +#endif /* FEATURE_WLAN_ESE */ +}; + +tANI_U8 csrRSNOui[][ CSR_RSN_OUI_SIZE ] = { + { 0x00, 0x0F, 0xAC, 0x00 }, // group cipher + { 0x00, 0x0F, 0xAC, 0x01 }, // WEP-40 or RSN + { 0x00, 0x0F, 0xAC, 0x02 }, // TKIP or RSN-PSK + { 0x00, 0x0F, 0xAC, 0x03 }, // Reserved + { 0x00, 0x0F, 0xAC, 0x04 }, // AES-CCMP + { 0x00, 0x0F, 0xAC, 0x05 }, // WEP-104 + { 0x00, 0x40, 0x96, 0x00 }, // CCKM + { 0x00, 0x0F, 0xAC, 0x06 }, // BIP (encryption type) or RSN-PSK-SHA256 (authentication type) + /* RSN-8021X-SHA256 (authentication type) */ + { 0x00, 0x0F, 0xAC, 0x05 } +}; + +#ifdef FEATURE_WLAN_WAPI +tANI_U8 csrWapiOui[CSR_WAPI_OUI_ROW_SIZE][ CSR_WAPI_OUI_SIZE ] = { + { 0x00, 0x14, 0x72, 0x00 }, // Reserved + { 0x00, 0x14, 0x72, 0x01 }, // WAI certificate or SMS4 + { 0x00, 0x14, 0x72, 0x02 } // WAI PSK +}; +#endif /* FEATURE_WLAN_WAPI */ +tANI_U8 csrWmeInfoOui[ CSR_WME_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 }; +tANI_U8 csrWmeParmOui[ CSR_WME_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 }; + +static tCsrIELenInfo gCsrIELengthTable[] = { +/* 000 */ { SIR_MAC_SSID_EID_MIN, SIR_MAC_SSID_EID_MAX }, +/* 001 */ { SIR_MAC_RATESET_EID_MIN, SIR_MAC_RATESET_EID_MAX }, +/* 002 */ { SIR_MAC_FH_PARAM_SET_EID_MIN, SIR_MAC_FH_PARAM_SET_EID_MAX }, +/* 003 */ { SIR_MAC_DS_PARAM_SET_EID_MIN, SIR_MAC_DS_PARAM_SET_EID_MAX }, +/* 004 */ { SIR_MAC_CF_PARAM_SET_EID_MIN, SIR_MAC_CF_PARAM_SET_EID_MAX }, +/* 005 */ { SIR_MAC_TIM_EID_MIN, SIR_MAC_TIM_EID_MAX }, +/* 006 */ { SIR_MAC_IBSS_PARAM_SET_EID_MIN, SIR_MAC_IBSS_PARAM_SET_EID_MAX }, +/* 007 */ { SIR_MAC_COUNTRY_EID_MIN, SIR_MAC_COUNTRY_EID_MAX }, +/* 008 */ { SIR_MAC_FH_PARAMS_EID_MIN, SIR_MAC_FH_PARAMS_EID_MAX }, +/* 009 */ { SIR_MAC_FH_PATTERN_EID_MIN, SIR_MAC_FH_PATTERN_EID_MAX }, +/* 010 */ { SIR_MAC_REQUEST_EID_MIN, SIR_MAC_REQUEST_EID_MAX }, +/* 011 */ { SIR_MAC_QBSS_LOAD_EID_MIN, SIR_MAC_QBSS_LOAD_EID_MAX }, +/* 012 */ { SIR_MAC_EDCA_PARAM_SET_EID_MIN, SIR_MAC_EDCA_PARAM_SET_EID_MAX }, +/* 013 */ { SIR_MAC_TSPEC_EID_MIN, SIR_MAC_TSPEC_EID_MAX }, +/* 014 */ { SIR_MAC_TCLAS_EID_MIN, SIR_MAC_TCLAS_EID_MAX }, +/* 015 */ { SIR_MAC_QOS_SCHEDULE_EID_MIN, SIR_MAC_QOS_SCHEDULE_EID_MAX }, +/* 016 */ { SIR_MAC_CHALLENGE_TEXT_EID_MIN, SIR_MAC_CHALLENGE_TEXT_EID_MAX }, +/* 017 */ { 0, 255 }, +/* 018 */ { 0, 255 }, +/* 019 */ { 0, 255 }, +/* 020 */ { 0, 255 }, +/* 021 */ { 0, 255 }, +/* 022 */ { 0, 255 }, +/* 023 */ { 0, 255 }, +/* 024 */ { 0, 255 }, +/* 025 */ { 0, 255 }, +/* 026 */ { 0, 255 }, +/* 027 */ { 0, 255 }, +/* 028 */ { 0, 255 }, +/* 029 */ { 0, 255 }, +/* 030 */ { 0, 255 }, +/* 031 */ { 0, 255 }, +/* 032 */ { SIR_MAC_PWR_CONSTRAINT_EID_MIN, SIR_MAC_PWR_CONSTRAINT_EID_MAX }, +/* 033 */ { SIR_MAC_PWR_CAPABILITY_EID_MIN, SIR_MAC_PWR_CAPABILITY_EID_MAX }, +/* 034 */ { SIR_MAC_TPC_REQ_EID_MIN, SIR_MAC_TPC_REQ_EID_MAX }, +/* 035 */ { SIR_MAC_TPC_RPT_EID_MIN, SIR_MAC_TPC_RPT_EID_MAX }, +/* 036 */ { SIR_MAC_SPRTD_CHNLS_EID_MIN, SIR_MAC_SPRTD_CHNLS_EID_MAX }, +/* 037 */ { SIR_MAC_CHNL_SWITCH_ANN_EID_MIN, SIR_MAC_CHNL_SWITCH_ANN_EID_MAX }, +/* 038 */ { SIR_MAC_MEAS_REQ_EID_MIN, SIR_MAC_MEAS_REQ_EID_MAX }, +/* 039 */ { SIR_MAC_MEAS_RPT_EID_MIN, SIR_MAC_MEAS_RPT_EID_MAX }, +/* 040 */ { SIR_MAC_QUIET_EID_MIN, SIR_MAC_QUIET_EID_MAX }, +/* 041 */ { SIR_MAC_IBSS_DFS_EID_MIN, SIR_MAC_IBSS_DFS_EID_MAX }, +/* 042 */ { SIR_MAC_ERP_INFO_EID_MIN, SIR_MAC_ERP_INFO_EID_MAX }, +/* 043 */ { SIR_MAC_TS_DELAY_EID_MIN, SIR_MAC_TS_DELAY_EID_MAX }, +/* 044 */ { SIR_MAC_TCLAS_PROC_EID_MIN, SIR_MAC_TCLAS_PROC_EID_MAX }, +/* 045 */ { SIR_MAC_QOS_ACTION_EID_MIN, SIR_MAC_QOS_ACTION_EID_MAX }, +/* 046 */ { SIR_MAC_QOS_CAPABILITY_EID_MIN, SIR_MAC_QOS_CAPABILITY_EID_MAX }, +/* 047 */ { 0, 255 }, +/* 048 */ { SIR_MAC_RSN_EID_MIN, SIR_MAC_RSN_EID_MAX }, +/* 049 */ { 0, 255 }, +/* 050 */ { SIR_MAC_EXTENDED_RATE_EID_MIN, SIR_MAC_EXTENDED_RATE_EID_MAX }, +/* 051 */ { 0, 255 }, +/* 052 */ { 0, 255 }, +/* 053 */ { 0, 255 }, +/* 054 */ { 0, 255 }, +/* 055 */ { 0, 255 }, +/* 056 */ { 0, 255 }, +/* 057 */ { 0, 255 }, +/* 058 */ { 0, 255 }, +/* 059 */ { 0, 255 }, +/* 060 */ { 0, 255 }, +/* 061 */ { 0, 255 }, +/* 062 */ { 0, 255 }, +/* 063 */ { 0, 255 }, +/* 064 */ { 0, 255 }, +/* 065 */ { 0, 255 }, +/* 066 */ { 0, 255 }, +/* 067 */ { 0, 255 }, +#ifdef FEATURE_WLAN_WAPI +/* 068 */ { DOT11F_EID_WAPI, DOT11F_IE_WAPI_MAX_LEN }, +#else +/* 068 */ { 0, 255 }, +#endif /* FEATURE_WLAN_WAPI */ +/* 069 */ { 0, 255 }, +/* 070 */ { 0, 255 }, +/* 071 */ { 0, 255 }, +/* 072 */ { 0, 255 }, +/* 073 */ { 0, 255 }, +/* 074 */ { 0, 255 }, +/* 075 */ { 0, 255 }, +/* 076 */ { 0, 255 }, +/* 077 */ { 0, 255 }, +/* 078 */ { 0, 255 }, +/* 079 */ { 0, 255 }, +/* 080 */ { 0, 255 }, +/* 081 */ { 0, 255 }, +/* 082 */ { 0, 255 }, +/* 083 */ { 0, 255 }, +/* 084 */ { 0, 255 }, +/* 085 */ { 0, 255 }, +/* 086 */ { 0, 255 }, +/* 087 */ { 0, 255 }, +/* 088 */ { 0, 255 }, +/* 089 */ { 0, 255 }, +/* 090 */ { 0, 255 }, +/* 091 */ { 0, 255 }, +/* 092 */ { 0, 255 }, +/* 093 */ { 0, 255 }, +/* 094 */ { 0, 255 }, +/* 095 */ { 0, 255 }, +/* 096 */ { 0, 255 }, +/* 097 */ { 0, 255 }, +/* 098 */ { 0, 255 }, +/* 099 */ { 0, 255 }, +/* 100 */ { 0, 255 }, +/* 101 */ { 0, 255 }, +/* 102 */ { 0, 255 }, +/* 103 */ { 0, 255 }, +/* 104 */ { 0, 255 }, +/* 105 */ { 0, 255 }, +/* 106 */ { 0, 255 }, +/* 107 */ { 0, 255 }, +/* 108 */ { 0, 255 }, +/* 109 */ { 0, 255 }, +/* 110 */ { 0, 255 }, +/* 111 */ { 0, 255 }, +/* 112 */ { 0, 255 }, +/* 113 */ { 0, 255 }, +/* 114 */ { 0, 255 }, +/* 115 */ { 0, 255 }, +/* 116 */ { 0, 255 }, +/* 117 */ { 0, 255 }, +/* 118 */ { 0, 255 }, +/* 119 */ { 0, 255 }, +/* 120 */ { 0, 255 }, +/* 121 */ { 0, 255 }, +/* 122 */ { 0, 255 }, +/* 123 */ { 0, 255 }, +/* 124 */ { 0, 255 }, +/* 125 */ { 0, 255 }, +/* 126 */ { 0, 255 }, +/* 127 */ { 0, 255 }, +/* 128 */ { 0, 255 }, +/* 129 */ { 0, 255 }, +/* 130 */ { 0, 255 }, +/* 131 */ { 0, 255 }, +/* 132 */ { 0, 255 }, +/* 133 */ { 0, 255 }, +/* 134 */ { 0, 255 }, +/* 135 */ { 0, 255 }, +/* 136 */ { 0, 255 }, +/* 137 */ { 0, 255 }, +/* 138 */ { 0, 255 }, +/* 139 */ { 0, 255 }, +/* 140 */ { 0, 255 }, +/* 141 */ { 0, 255 }, +/* 142 */ { 0, 255 }, +/* 143 */ { 0, 255 }, +/* 144 */ { 0, 255 }, +/* 145 */ { 0, 255 }, +/* 146 */ { 0, 255 }, +/* 147 */ { 0, 255 }, +/* 148 */ { 0, 255 }, +/* 149 */ { 0, 255 }, +/* 150 */ { 0, 255 }, +/* 151 */ { 0, 255 }, +/* 152 */ { 0, 255 }, +/* 153 */ { 0, 255 }, +/* 154 */ { 0, 255 }, +/* 155 */ { 0, 255 }, +/* 156 */ { 0, 255 }, +/* 157 */ { 0, 255 }, +/* 158 */ { 0, 255 }, +/* 159 */ { 0, 255 }, +/* 160 */ { 0, 255 }, +/* 161 */ { 0, 255 }, +/* 162 */ { 0, 255 }, +/* 163 */ { 0, 255 }, +/* 164 */ { 0, 255 }, +/* 165 */ { 0, 255 }, +/* 166 */ { 0, 255 }, +/* 167 */ { 0, 255 }, +/* 168 */ { 0, 255 }, +/* 169 */ { 0, 255 }, +/* 170 */ { 0, 255 }, +/* 171 */ { 0, 255 }, +/* 172 */ { 0, 255 }, +/* 173 */ { 0, 255 }, +/* 174 */ { 0, 255 }, +/* 175 */ { 0, 255 }, +/* 176 */ { 0, 255 }, +/* 177 */ { 0, 255 }, +/* 178 */ { 0, 255 }, +/* 179 */ { 0, 255 }, +/* 180 */ { 0, 255 }, +/* 181 */ { 0, 255 }, +/* 182 */ { 0, 255 }, +/* 183 */ { 0, 255 }, +/* 184 */ { 0, 255 }, +/* 185 */ { 0, 255 }, +/* 186 */ { 0, 255 }, +/* 187 */ { 0, 255 }, +/* 188 */ { 0, 255 }, +/* 189 */ { 0, 255 }, +/* 190 */ { 0, 255 }, +/* 191 */ { 0, 255 }, +/* 192 */ { 0, 255 }, +/* 193 */ { 0, 255 }, +/* 194 */ { 0, 255 }, +/* 195 */ { 0, 255 }, +/* 196 */ { 0, 255 }, +/* 197 */ { 0, 255 }, +/* 198 */ { 0, 255 }, +/* 199 */ { 0, 255 }, +/* 200 */ { 0, 255 }, +/* 201 */ { 0, 255 }, +/* 202 */ { 0, 255 }, +/* 203 */ { 0, 255 }, +/* 204 */ { 0, 255 }, +/* 205 */ { 0, 255 }, +/* 206 */ { 0, 255 }, +/* 207 */ { 0, 255 }, +/* 208 */ { 0, 255 }, +/* 209 */ { 0, 255 }, +/* 210 */ { 0, 255 }, +/* 211 */ { 0, 255 }, +/* 212 */ { 0, 255 }, +/* 213 */ { 0, 255 }, +/* 214 */ { 0, 255 }, +/* 215 */ { 0, 255 }, +/* 216 */ { 0, 255 }, +/* 217 */ { 0, 255 }, +/* 218 */ { 0, 255 }, +/* 219 */ { 0, 255 }, +/* 220 */ { 0, 255 }, +/* 221 */ { SIR_MAC_WPA_EID_MIN, SIR_MAC_WPA_EID_MAX }, +/* 222 */ { 0, 255 }, +/* 223 */ { 0, 255 }, +/* 224 */ { 0, 255 }, +/* 225 */ { 0, 255 }, +/* 226 */ { 0, 255 }, +/* 227 */ { 0, 255 }, +/* 228 */ { 0, 255 }, +/* 229 */ { 0, 255 }, +/* 230 */ { 0, 255 }, +/* 231 */ { 0, 255 }, +/* 232 */ { 0, 255 }, +/* 233 */ { 0, 255 }, +/* 234 */ { 0, 255 }, +/* 235 */ { 0, 255 }, +/* 236 */ { 0, 255 }, +/* 237 */ { 0, 255 }, +/* 238 */ { 0, 255 }, +/* 239 */ { 0, 255 }, +/* 240 */ { 0, 255 }, +/* 241 */ { 0, 255 }, +/* 242 */ { 0, 255 }, +/* 243 */ { 0, 255 }, +/* 244 */ { 0, 255 }, +/* 245 */ { 0, 255 }, +/* 246 */ { 0, 255 }, +/* 247 */ { 0, 255 }, +/* 248 */ { 0, 255 }, +/* 249 */ { 0, 255 }, +/* 250 */ { 0, 255 }, +/* 251 */ { 0, 255 }, +/* 252 */ { 0, 255 }, +/* 253 */ { 0, 255 }, +/* 254 */ { 0, 255 }, +/* 255 */ { SIR_MAC_ANI_WORKAROUND_EID_MIN, SIR_MAC_ANI_WORKAROUND_EID_MAX } +}; + +#if 0 +//Don't not insert entry into the table, put it to the end. If you have to insert, make sure it is also +//reflected in eCsrCountryIndex +static tCsrCountryInfo gCsrCountryInfo[eCSR_NUM_COUNTRY_INDEX] = +{ + {REG_DOMAIN_FCC, {'U', 'S', ' '}}, //USA/******The "US" MUST be at index 0*******/ + {REG_DOMAIN_WORLD, {'A', 'D', ' '}}, //ANDORRA + {REG_DOMAIN_WORLD, {'A', 'E', ' '}}, //UAE + {REG_DOMAIN_WORLD, {'A', 'F', ' '}}, //AFGHANISTAN + {REG_DOMAIN_WORLD, {'A', 'G', ' '}}, //ANTIGUA AND BARBUDA + {REG_DOMAIN_WORLD, {'A', 'I', ' '}}, //ANGUILLA + {REG_DOMAIN_HI_5GHZ, {'A', 'L', ' '}}, //ALBANIA + {REG_DOMAIN_WORLD, {'A', 'M', ' '}}, //ARMENIA + {REG_DOMAIN_WORLD, {'A', 'N', ' '}}, //NETHERLANDS ANTILLES + {REG_DOMAIN_WORLD, {'A', 'O', ' '}}, //ANGOLA + {REG_DOMAIN_WORLD, {'A', 'Q', ' '}}, //ANTARCTICA + {REG_DOMAIN_HI_5GHZ, {'A', 'R', ' '}}, //ARGENTINA + {REG_DOMAIN_FCC, {'A', 'S', ' '}}, //AMERICAN SOMOA + {REG_DOMAIN_ETSI, {'A', 'T', ' '}}, //AUSTRIA + {REG_DOMAIN_ETSI, {'A', 'U', ' '}}, //AUSTRALIA + {REG_DOMAIN_WORLD, {'A', 'W', ' '}}, //ARUBA + {REG_DOMAIN_WORLD, {'A', 'X', ' '}}, //ALAND ISLANDS + {REG_DOMAIN_WORLD, {'A', 'Z', ' '}}, //AZERBAIJAN + {REG_DOMAIN_WORLD, {'B', 'A', ' '}}, //BOSNIA AND HERZEGOVINA + {REG_DOMAIN_WORLD, {'B', 'B', ' '}}, //BARBADOS + {REG_DOMAIN_WORLD, {'B', 'D', ' '}}, //BANGLADESH + {REG_DOMAIN_ETSI, {'B', 'E', ' '}}, //BELGIUM + {REG_DOMAIN_WORLD, {'B', 'F', ' '}}, //BURKINA FASO + {REG_DOMAIN_HI_5GHZ, {'B', 'G', ' '}}, //BULGARIA + {REG_DOMAIN_WORLD, {'B', 'H', ' '}}, //BAHRAIN + {REG_DOMAIN_WORLD, {'B', 'I', ' '}}, //BURUNDI + {REG_DOMAIN_WORLD, {'B', 'J', ' '}}, //BENIN + {REG_DOMAIN_WORLD, {'B', 'L', ' '}}, //SAINT BARTHELEMY + {REG_DOMAIN_ETSI, {'B', 'M', ' '}}, //BERMUDA + {REG_DOMAIN_WORLD, {'B', 'N', ' '}}, //BRUNEI DARUSSALAM + {REG_DOMAIN_WORLD, {'B', 'O', ' '}}, //BOLIVIA + {REG_DOMAIN_WORLD, {'B', 'R', ' '}}, //BRAZIL + {REG_DOMAIN_WORLD, {'B', 'S', ' '}}, //BAHAMAS + {REG_DOMAIN_WORLD, {'B', 'T', ' '}}, //BHUTAN + {REG_DOMAIN_WORLD, {'B', 'V', ' '}}, //BOUVET ISLAND + {REG_DOMAIN_WORLD, {'B', 'W', ' '}}, //BOTSWANA + {REG_DOMAIN_WORLD, {'B', 'Y', ' '}}, //BELARUS + {REG_DOMAIN_WORLD, {'B', 'Z', ' '}}, //BELIZE + {REG_DOMAIN_FCC, {'C', 'A', ' '}}, //CANADA + {REG_DOMAIN_WORLD, {'C', 'C', ' '}}, //COCOS (KEELING) ISLANDS + {REG_DOMAIN_WORLD, {'C', 'D', ' '}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE + {REG_DOMAIN_WORLD, {'C', 'F', ' '}}, //CENTRAL AFRICAN REPUBLIC + {REG_DOMAIN_WORLD, {'C', 'G', ' '}}, //CONGO + {REG_DOMAIN_ETSI, {'C', 'H', ' '}}, //SWITZERLAND + {REG_DOMAIN_WORLD, {'C', 'I', ' '}}, //COTE D'IVOIRE + {REG_DOMAIN_WORLD, {'C', 'K', ' '}}, //COOK ISLANDS + {REG_DOMAIN_WORLD, {'C', 'L', ' '}}, //CHILE + {REG_DOMAIN_WORLD, {'C', 'M', ' '}}, //CAMEROON + {REG_DOMAIN_HI_5GHZ, {'C', 'N', ' '}}, //CHINA + {REG_DOMAIN_WORLD, {'C', 'O', ' '}}, //COLOMBIA + {REG_DOMAIN_WORLD, {'C', 'R', ' '}}, //COSTA RICA + {REG_DOMAIN_WORLD, {'C', 'U', ' '}}, //CUBA + {REG_DOMAIN_WORLD, {'C', 'V', ' '}}, //CAPE VERDE + {REG_DOMAIN_WORLD, {'C', 'X', ' '}}, //CHRISTMAS ISLAND + {REG_DOMAIN_WORLD, {'C', 'Y', ' '}}, //CYPRUS + {REG_DOMAIN_HI_5GHZ, {'C', 'Z', ' '}}, //CZECH REPUBLIC + {REG_DOMAIN_ETSI, {'D', 'E', ' '}}, //GERMANY + {REG_DOMAIN_WORLD, {'D', 'J', ' '}}, //DJIBOUTI + {REG_DOMAIN_ETSI, {'D', 'K', ' '}}, //DENMARK + {REG_DOMAIN_WORLD, {'D', 'M', ' '}}, //DOMINICA + {REG_DOMAIN_WORLD, {'D', 'O', ' '}}, //DOMINICAN REPUBLIC + {REG_DOMAIN_WORLD, {'D', 'Z', ' '}}, //ALGERIA + {REG_DOMAIN_WORLD, {'E', 'C', ' '}}, //ECUADOR + {REG_DOMAIN_HI_5GHZ, {'E', 'E', ' '}}, //ESTONIA + {REG_DOMAIN_WORLD, {'E', 'G', ' '}}, //EGYPT + {REG_DOMAIN_WORLD, {'E', 'H', ' '}}, //WESTERN SAHARA + {REG_DOMAIN_WORLD, {'E', 'R', ' '}}, //ERITREA + {REG_DOMAIN_ETSI, {'E', 'S', ' '}}, //SPAIN + {REG_DOMAIN_WORLD, {'E', 'T', ' '}}, //ETHIOPIA + {REG_DOMAIN_WORLD, {'F', 'I', ' '}}, //FINLAND + {REG_DOMAIN_WORLD, {'F', 'J', ' '}}, //FIJI + {REG_DOMAIN_WORLD, {'F', 'K', ' '}}, //FALKLAND ISLANDS (MALVINAS) + {REG_DOMAIN_WORLD, {'F', 'M', ' '}}, //MICRONESIA, FEDERATED STATES OF + {REG_DOMAIN_WORLD, {'F', 'O', ' '}}, //FAROE ISLANDS + {REG_DOMAIN_ETSI, {'F', 'R', ' '}}, //FRANCE + {REG_DOMAIN_WORLD, {'G', 'A', ' '}}, //GABON + {REG_DOMAIN_ETSI, {'G', 'B', ' '}}, //UNITED KINGDOM + {REG_DOMAIN_WORLD, {'G', 'D', ' '}}, //GRENADA + {REG_DOMAIN_HI_5GHZ, {'G', 'E', ' '}}, //GEORGIA + {REG_DOMAIN_WORLD, {'G', 'F', ' '}}, //FRENCH GUIANA + {REG_DOMAIN_ETSI, {'G', 'G', ' '}}, //GUERNSEY + {REG_DOMAIN_WORLD, {'G', 'H', ' '}}, //GHANA + {REG_DOMAIN_WORLD, {'G', 'I', ' '}}, //GIBRALTAR + {REG_DOMAIN_WORLD, {'G', 'L', ' '}}, //GREENLAND + {REG_DOMAIN_WORLD, {'G', 'M', ' '}}, //GAMBIA + {REG_DOMAIN_WORLD, {'G', 'N', ' '}}, //GUINEA + {REG_DOMAIN_WORLD, {'G', 'P', ' '}}, //GUADELOUPE + {REG_DOMAIN_WORLD, {'G', 'Q', ' '}}, //EQUATORIAL GUINEA + {REG_DOMAIN_ETSI, {'G', 'R', ' '}}, //GREECE + {REG_DOMAIN_WORLD, {'G', 'S', ' '}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS + {REG_DOMAIN_WORLD, {'G', 'T', ' '}}, //GUATEMALA + {REG_DOMAIN_WORLD, {'G', 'U', ' '}}, //GUAM + {REG_DOMAIN_WORLD, {'G', 'W', ' '}}, //GUINEA-BISSAU + {REG_DOMAIN_WORLD, {'G', 'Y', ' '}}, //GUYANA + {REG_DOMAIN_WORLD, {'H', 'K', ' '}}, //HONGKONG + {REG_DOMAIN_WORLD, {'H', 'M', ' '}}, //HEARD ISLAND AND MCDONALD ISLANDS + {REG_DOMAIN_WORLD, {'H', 'N', ' '}}, //HONDURAS + {REG_DOMAIN_HI_5GHZ, {'H', 'R', ' '}}, //CROATIA + {REG_DOMAIN_WORLD, {'H', 'T', ' '}}, //HAITI + {REG_DOMAIN_HI_5GHZ, {'H', 'U', ' '}}, //HUNGARY + {REG_DOMAIN_APAC, {'I', 'D', ' '}}, //INDONESIA + {REG_DOMAIN_ETSI, {'I', 'E', ' '}}, //IRELAND + {REG_DOMAIN_WORLD, {'I', 'L', ' '}}, //ISREAL + {REG_DOMAIN_ETSI, {'I', 'M', ' '}}, //ISLE OF MAN + {REG_DOMAIN_WORLD, {'I', 'N', ' '}}, //INDIA + {REG_DOMAIN_ETSI, {'I', 'O', ' '}}, //BRITISH INDIAN OCEAN TERRITORY + {REG_DOMAIN_WORLD, {'I', 'Q', ' '}}, //IRAQ + {REG_DOMAIN_WORLD, {'I', 'R', ' '}}, //IRAN, ISLAMIC REPUBLIC OF + {REG_DOMAIN_WORLD, {'I', 'S', ' '}}, //ICELAND + {REG_DOMAIN_ETSI, {'I', 'T', ' '}}, //ITALY + {REG_DOMAIN_ETSI, {'J', 'E', ' '}}, //JERSEY + {REG_DOMAIN_WORLD, {'J', 'M', ' '}}, //JAMAICA + {REG_DOMAIN_WORLD, {'J', 'O', ' '}}, //JORDAN + {REG_DOMAIN_JAPAN, {'J', 'P', ' '}}, //JAPAN + {REG_DOMAIN_WORLD, {'K', 'E', ' '}}, //KENYA + {REG_DOMAIN_WORLD, {'K', 'G', ' '}}, //KYRGYZSTAN + {REG_DOMAIN_WORLD, {'K', 'H', ' '}}, //CAMBODIA + {REG_DOMAIN_WORLD, {'K', 'I', ' '}}, //KIRIBATI + {REG_DOMAIN_WORLD, {'K', 'M', ' '}}, //COMOROS + {REG_DOMAIN_WORLD, {'K', 'N', ' '}}, //SAINT KITTS AND NEVIS + {REG_DOMAIN_KOREA, {'K', 'P', ' '}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF + {REG_DOMAIN_KOREA, {'K', 'R', ' '}}, //KOREA, REPUBLIC OF + {REG_DOMAIN_WORLD, {'K', 'W', ' '}}, //KUWAIT + {REG_DOMAIN_WORLD, {'K', 'Y', ' '}}, //CAYMAN ISLANDS + {REG_DOMAIN_WORLD, {'K', 'Z', ' '}}, //KAZAKHSTAN + {REG_DOMAIN_WORLD, {'L', 'A', ' '}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC + {REG_DOMAIN_WORLD, {'L', 'B', ' '}}, //LEBANON + {REG_DOMAIN_WORLD, {'L', 'C', ' '}}, //SAINT LUCIA + {REG_DOMAIN_ETSI, {'L', 'I', ' '}}, //LIECHTENSTEIN + {REG_DOMAIN_WORLD, {'L', 'K', ' '}}, //SRI LANKA + {REG_DOMAIN_WORLD, {'L', 'R', ' '}}, //LIBERIA + {REG_DOMAIN_WORLD, {'L', 'S', ' '}}, //LESOTHO + {REG_DOMAIN_HI_5GHZ, {'L', 'T', ' '}}, //LITHUANIA + {REG_DOMAIN_ETSI, {'L', 'U', ' '}}, //LUXEMBOURG + {REG_DOMAIN_HI_5GHZ, {'L', 'V', ' '}}, //LATVIA + {REG_DOMAIN_WORLD, {'L', 'Y', ' '}}, //LIBYAN ARAB JAMAHIRIYA + {REG_DOMAIN_WORLD, {'M', 'A', ' '}}, //MOROCCO + {REG_DOMAIN_ETSI, {'M', 'C', ' '}}, //MONACO + {REG_DOMAIN_WORLD, {'M', 'D', ' '}}, //MOLDOVA, REPUBLIC OF + {REG_DOMAIN_WORLD, {'M', 'E', ' '}}, //MONTENEGRO + {REG_DOMAIN_WORLD, {'M', 'G', ' '}}, //MADAGASCAR + {REG_DOMAIN_WORLD, {'M', 'H', ' '}}, //MARSHALL ISLANDS + {REG_DOMAIN_WORLD, {'M', 'K', ' '}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF + {REG_DOMAIN_WORLD, {'M', 'L', ' '}}, //MALI + {REG_DOMAIN_WORLD, {'M', 'M', ' '}}, //MYANMAR + {REG_DOMAIN_HI_5GHZ, {'M', 'N', ' '}}, //MONGOLIA + {REG_DOMAIN_WORLD, {'M', 'O', ' '}}, //MACAO + {REG_DOMAIN_WORLD, {'M', 'P', ' '}}, //NORTHERN MARIANA ISLANDS + {REG_DOMAIN_WORLD, {'M', 'Q', ' '}}, //MARTINIQUE + {REG_DOMAIN_WORLD, {'M', 'R', ' '}}, //MAURITANIA + {REG_DOMAIN_WORLD, {'M', 'S', ' '}}, //MONTSERRAT + {REG_DOMAIN_WORLD, {'M', 'T', ' '}}, //MALTA + {REG_DOMAIN_WORLD, {'M', 'U', ' '}}, //MAURITIUS + {REG_DOMAIN_WORLD, {'M', 'V', ' '}}, //MALDIVES + {REG_DOMAIN_WORLD, {'M', 'W', ' '}}, //MALAWI + {REG_DOMAIN_WORLD, {'M', 'X', ' '}}, //MEXICO + {REG_DOMAIN_HI_5GHZ, {'M', 'Y', ' '}}, //MALAYSIA + {REG_DOMAIN_WORLD, {'M', 'Z', ' '}}, //MOZAMBIQUE + {REG_DOMAIN_WORLD, {'N', 'A', ' '}}, //NAMIBIA + {REG_DOMAIN_WORLD, {'N', 'C', ' '}}, //NEW CALEDONIA + {REG_DOMAIN_WORLD, {'N', 'E', ' '}}, //NIGER + {REG_DOMAIN_WORLD, {'N', 'F', ' '}}, //NORFOLD ISLAND + {REG_DOMAIN_WORLD, {'N', 'G', ' '}}, //NIGERIA + {REG_DOMAIN_WORLD, {'N', 'I', ' '}}, //NICARAGUA + {REG_DOMAIN_ETSI, {'N', 'L', ' '}}, //NETHERLANDS + {REG_DOMAIN_WORLD, {'N', 'O', ' '}}, //NORWAY + {REG_DOMAIN_WORLD, {'N', 'P', ' '}}, //NEPAL + {REG_DOMAIN_WORLD, {'N', 'R', ' '}}, //NAURU + {REG_DOMAIN_WORLD, {'N', 'U', ' '}}, //NIUE + {REG_DOMAIN_ETSI, {'N', 'Z', ' '}}, //NEW ZEALAND + {REG_DOMAIN_WORLD, {'O', 'M', ' '}}, //OMAN + {REG_DOMAIN_WORLD, {'P', 'A', ' '}}, //PANAMA + {REG_DOMAIN_WORLD, {'P', 'E', ' '}}, //PERU + {REG_DOMAIN_WORLD, {'P', 'F', ' '}}, //FRENCH POLYNESIA + {REG_DOMAIN_WORLD, {'P', 'G', ' '}}, //PAPUA NEW GUINEA + {REG_DOMAIN_WORLD, {'P', 'H', ' '}}, //PHILIPPINES + {REG_DOMAIN_WORLD, {'P', 'K', ' '}}, //PAKISTAN + {REG_DOMAIN_WORLD, {'P', 'L', ' '}}, //POLAND + {REG_DOMAIN_WORLD, {'P', 'M', ' '}}, //SAINT PIERRE AND MIQUELON + {REG_DOMAIN_WORLD, {'P', 'N', ' '}}, //PITCAIRN + {REG_DOMAIN_FCC, {'P', 'R', ' '}}, //PUERTO RICO + {REG_DOMAIN_WORLD, {'P', 'S', ' '}}, //PALESTINIAN TERRITORY, OCCUPIED + {REG_DOMAIN_ETSI, {'P', 'T', ' '}}, //PORTUGAL + {REG_DOMAIN_WORLD, {'P', 'W', ' '}}, //PALAU + {REG_DOMAIN_WORLD, {'P', 'Y', ' '}}, //PARAGUAY + {REG_DOMAIN_WORLD, {'Q', 'A', ' '}}, //QATAR + {REG_DOMAIN_WORLD, {'R', 'E', ' '}}, //REUNION + {REG_DOMAIN_HI_5GHZ, {'R', 'O', ' '}}, //ROMANIA + {REG_DOMAIN_HI_5GHZ, {'R', 'S', ' '}}, //SERBIA + {REG_DOMAIN_WORLD, {'R', 'U', ' '}}, //RUSSIA + {REG_DOMAIN_WORLD, {'R', 'W', ' '}}, //RWANDA + {REG_DOMAIN_WORLD, {'S', 'A', ' '}}, //SAUDI ARABIA + {REG_DOMAIN_WORLD, {'S', 'B', ' '}}, //SOLOMON ISLANDS + {REG_DOMAIN_ETSI, {'S', 'C', ' '}}, //SEYCHELLES + {REG_DOMAIN_WORLD, {'S', 'D', ' '}}, //SUDAN + {REG_DOMAIN_ETSI, {'S', 'E', ' '}}, //SWEDEN + {REG_DOMAIN_APAC, {'S', 'G', ' '}}, //SINGAPORE + {REG_DOMAIN_WORLD, {'S', 'H', ' '}}, //SAINT HELENA + {REG_DOMAIN_HI_5GHZ, {'S', 'I', ' '}}, //SLOVENNIA + {REG_DOMAIN_WORLD, {'S', 'J', ' '}}, //SVALBARD AND JAN MAYEN + {REG_DOMAIN_HI_5GHZ, {'S', 'K', ' '}}, //SLOVAKIA + {REG_DOMAIN_WORLD, {'S', 'L', ' '}}, //SIERRA LEONE + {REG_DOMAIN_WORLD, {'S', 'M', ' '}}, //SAN MARINO + {REG_DOMAIN_WORLD, {'S', 'N', ' '}}, //SENEGAL + {REG_DOMAIN_WORLD, {'S', 'O', ' '}}, //SOMALIA + {REG_DOMAIN_WORLD, {'S', 'R', ' '}}, //SURINAME + {REG_DOMAIN_WORLD, {'S', 'T', ' '}}, //SAO TOME AND PRINCIPE + {REG_DOMAIN_WORLD, {'S', 'V', ' '}}, //EL SALVADOR + {REG_DOMAIN_WORLD, {'S', 'Y', ' '}}, //SYRIAN ARAB REPUBLIC + {REG_DOMAIN_WORLD, {'S', 'Z', ' '}}, //SWAZILAND + {REG_DOMAIN_WORLD, {'T', 'C', ' '}}, //TURKS AND CAICOS ISLANDS + {REG_DOMAIN_WORLD, {'T', 'D', ' '}}, //CHAD + {REG_DOMAIN_WORLD, {'T', 'F', ' '}}, //FRENCH SOUTHERN TERRITORIES + {REG_DOMAIN_WORLD, {'T', 'G', ' '}}, //TOGO + {REG_DOMAIN_WORLD, {'T', 'H', ' '}}, //THAILAND + {REG_DOMAIN_WORLD, {'T', 'J', ' '}}, //TAJIKISTAN + {REG_DOMAIN_WORLD, {'T', 'K', ' '}}, //TOKELAU + {REG_DOMAIN_WORLD, {'T', 'L', ' '}}, //TIMOR-LESTE + {REG_DOMAIN_WORLD, {'T', 'M', ' '}}, //TURKMENISTAN + {REG_DOMAIN_WORLD, {'T', 'N', ' '}}, //TUNISIA + {REG_DOMAIN_WORLD, {'T', 'O', ' '}}, //TONGA + {REG_DOMAIN_WORLD, {'T', 'R', ' '}}, //TURKEY + {REG_DOMAIN_WORLD, {'T', 'T', ' '}}, //TRINIDAD AND TOBAGO + {REG_DOMAIN_WORLD, {'T', 'V', ' '}}, //TUVALU + {REG_DOMAIN_HI_5GHZ, {'T', 'W', ' '}}, //TAIWAN, PROVINCE OF CHINA + {REG_DOMAIN_WORLD, {'T', 'Z', ' '}}, //TANZANIA, UNITED REPUBLIC OF + {REG_DOMAIN_HI_5GHZ, {'U', 'A', ' '}}, //UKRAINE + {REG_DOMAIN_WORLD, {'U', 'G', ' '}}, //UGANDA + {REG_DOMAIN_FCC, {'U', 'M', ' '}}, //UNITED STATES MINOR OUTLYING ISLANDS + {REG_DOMAIN_WORLD, {'U', 'Y', ' '}}, //URUGUAY + {REG_DOMAIN_HI_5GHZ, {'U', 'Z', ' '}}, //UZBEKISTAN + {REG_DOMAIN_ETSI, {'V', 'A', ' '}}, //HOLY SEE (VATICAN CITY STATE) + {REG_DOMAIN_WORLD, {'V', 'C', ' '}}, //SAINT VINCENT AND THE GRENADINES + {REG_DOMAIN_HI_5GHZ, {'V', 'E', ' '}}, //VENEZUELA + {REG_DOMAIN_ETSI, {'V', 'G', ' '}}, //VIRGIN ISLANDS, BRITISH + {REG_DOMAIN_FCC, {'V', 'I', ' '}}, //VIRGIN ISLANDS, US + {REG_DOMAIN_WORLD, {'V', 'N', ' '}}, //VIET NAM + {REG_DOMAIN_WORLD, {'V', 'U', ' '}}, //VANUATU + {REG_DOMAIN_WORLD, {'W', 'F', ' '}}, //WALLIS AND FUTUNA + {REG_DOMAIN_WORLD, {'W', 'S', ' '}}, //SOMOA + {REG_DOMAIN_WORLD, {'Y', 'E', ' '}}, //YEMEN + {REG_DOMAIN_WORLD, {'Y', 'T', ' '}}, //MAYOTTE + {REG_DOMAIN_WORLD, {'Z', 'A', ' '}}, //SOUTH AFRICA + {REG_DOMAIN_WORLD, {'Z', 'M', ' '}}, //ZAMBIA + {REG_DOMAIN_WORLD, {'Z', 'W', ' '}}, //ZIMBABWE + + {REG_DOMAIN_KOREA, {'K', '1', ' '}}, //Korea alternate 1 + {REG_DOMAIN_KOREA, {'K', '2', ' '}}, //Korea alternate 2 + {REG_DOMAIN_KOREA, {'K', '3', ' '}}, //Korea alternate 3 + {REG_DOMAIN_KOREA, {'K', '4', ' '}}, //Korea alternate 4 +}; + + +//The channels listed here doesn't mean they are valid channels for certain domain. They are here only to present +//whether they should be passive scanned. +tCsrDomainChnInfo gCsrDomainChnInfo[NUM_REG_DOMAINS] = +{ + //REG_DOMAIN_FCC + { + REG_DOMAIN_FCC, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_PASSIVE_SCAN}, + {56, eSIR_PASSIVE_SCAN}, + {60, eSIR_PASSIVE_SCAN}, + {64, eSIR_PASSIVE_SCAN}, + //5470 to 5725 + {100, eSIR_PASSIVE_SCAN}, + {104, eSIR_PASSIVE_SCAN}, + {108, eSIR_PASSIVE_SCAN}, + {112, eSIR_PASSIVE_SCAN}, + {116, eSIR_PASSIVE_SCAN}, + {120, eSIR_PASSIVE_SCAN}, + {124, eSIR_PASSIVE_SCAN}, + {128, eSIR_PASSIVE_SCAN}, + {132, eSIR_PASSIVE_SCAN}, + {136, eSIR_PASSIVE_SCAN}, + {140, eSIR_PASSIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_ETSI + { + REG_DOMAIN_ETSI, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_PASSIVE_SCAN}, + {56, eSIR_PASSIVE_SCAN}, + {60, eSIR_PASSIVE_SCAN}, + {64, eSIR_PASSIVE_SCAN}, + //5470 to 5725 + {100, eSIR_PASSIVE_SCAN}, + {104, eSIR_PASSIVE_SCAN}, + {108, eSIR_PASSIVE_SCAN}, + {112, eSIR_PASSIVE_SCAN}, + {116, eSIR_PASSIVE_SCAN}, + {120, eSIR_PASSIVE_SCAN}, + {124, eSIR_PASSIVE_SCAN}, + {128, eSIR_PASSIVE_SCAN}, + {132, eSIR_PASSIVE_SCAN}, + {136, eSIR_PASSIVE_SCAN}, + {140, eSIR_PASSIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_JAPAN + { + REG_DOMAIN_JAPAN, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_PASSIVE_SCAN}, + {56, eSIR_PASSIVE_SCAN}, + {60, eSIR_PASSIVE_SCAN}, + {64, eSIR_PASSIVE_SCAN}, + //5470 to 5725 + {100, eSIR_PASSIVE_SCAN}, + {104, eSIR_PASSIVE_SCAN}, + {108, eSIR_PASSIVE_SCAN}, + {112, eSIR_PASSIVE_SCAN}, + {116, eSIR_PASSIVE_SCAN}, + {120, eSIR_PASSIVE_SCAN}, + {124, eSIR_PASSIVE_SCAN}, + {128, eSIR_PASSIVE_SCAN}, + {132, eSIR_PASSIVE_SCAN}, + {136, eSIR_PASSIVE_SCAN}, + {140, eSIR_PASSIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_WORLD + { + REG_DOMAIN_WORLD, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_ACTIVE_SCAN}, + {56, eSIR_ACTIVE_SCAN}, + {60, eSIR_ACTIVE_SCAN}, + {64, eSIR_ACTIVE_SCAN}, + //5470 to 5725 + {100, eSIR_ACTIVE_SCAN}, + {104, eSIR_ACTIVE_SCAN}, + {108, eSIR_ACTIVE_SCAN}, + {112, eSIR_ACTIVE_SCAN}, + {116, eSIR_ACTIVE_SCAN}, + {120, eSIR_ACTIVE_SCAN}, + {124, eSIR_ACTIVE_SCAN}, + {128, eSIR_ACTIVE_SCAN}, + {132, eSIR_ACTIVE_SCAN}, + {136, eSIR_ACTIVE_SCAN}, + {140, eSIR_ACTIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_N_AMER_EXC_FCC + { + REG_DOMAIN_N_AMER_EXC_FCC, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_PASSIVE_SCAN}, + {56, eSIR_PASSIVE_SCAN}, + {60, eSIR_PASSIVE_SCAN}, + {64, eSIR_PASSIVE_SCAN}, + //5470 to 5725 + {100, eSIR_ACTIVE_SCAN}, + {104, eSIR_ACTIVE_SCAN}, + {108, eSIR_ACTIVE_SCAN}, + {112, eSIR_ACTIVE_SCAN}, + {116, eSIR_ACTIVE_SCAN}, + {120, eSIR_ACTIVE_SCAN}, + {124, eSIR_ACTIVE_SCAN}, + {128, eSIR_ACTIVE_SCAN}, + {132, eSIR_ACTIVE_SCAN}, + {136, eSIR_ACTIVE_SCAN}, + {140, eSIR_ACTIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_APAC + { + REG_DOMAIN_APAC, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_PASSIVE_SCAN}, + {56, eSIR_PASSIVE_SCAN}, + {60, eSIR_PASSIVE_SCAN}, + {64, eSIR_PASSIVE_SCAN}, + //5470 to 5725 + {100, eSIR_ACTIVE_SCAN}, + {104, eSIR_ACTIVE_SCAN}, + {108, eSIR_ACTIVE_SCAN}, + {112, eSIR_ACTIVE_SCAN}, + {116, eSIR_ACTIVE_SCAN}, + {120, eSIR_ACTIVE_SCAN}, + {124, eSIR_ACTIVE_SCAN}, + {128, eSIR_ACTIVE_SCAN}, + {132, eSIR_ACTIVE_SCAN}, + {136, eSIR_ACTIVE_SCAN}, + {140, eSIR_ACTIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_KOREA + { + REG_DOMAIN_KOREA, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_PASSIVE_SCAN}, + {56, eSIR_PASSIVE_SCAN}, + {60, eSIR_PASSIVE_SCAN}, + {64, eSIR_PASSIVE_SCAN}, + //5470 to 5725 + {100, eSIR_PASSIVE_SCAN}, + {104, eSIR_PASSIVE_SCAN}, + {108, eSIR_PASSIVE_SCAN}, + {112, eSIR_PASSIVE_SCAN}, + {116, eSIR_PASSIVE_SCAN}, + {120, eSIR_PASSIVE_SCAN}, + {124, eSIR_PASSIVE_SCAN}, + {128, eSIR_PASSIVE_SCAN}, + {132, eSIR_PASSIVE_SCAN}, + {136, eSIR_PASSIVE_SCAN}, + {140, eSIR_PASSIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_HI_5GHZ + { + REG_DOMAIN_HI_5GHZ, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_ACTIVE_SCAN}, + {56, eSIR_ACTIVE_SCAN}, + {60, eSIR_ACTIVE_SCAN}, + {64, eSIR_ACTIVE_SCAN}, + //5470 to 5725 + {100, eSIR_ACTIVE_SCAN}, + {104, eSIR_ACTIVE_SCAN}, + {108, eSIR_ACTIVE_SCAN}, + {112, eSIR_ACTIVE_SCAN}, + {116, eSIR_ACTIVE_SCAN}, + {120, eSIR_ACTIVE_SCAN}, + {124, eSIR_ACTIVE_SCAN}, + {128, eSIR_ACTIVE_SCAN}, + {132, eSIR_ACTIVE_SCAN}, + {136, eSIR_ACTIVE_SCAN}, + {140, eSIR_ACTIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, + //REG_DOMAIN_NO_5GHZ + { + REG_DOMAIN_NO_5GHZ, + 45, //Num channels + //Channels + { + //5GHz + //5180 - 5240 + {36, eSIR_ACTIVE_SCAN}, + {40, eSIR_ACTIVE_SCAN}, + {44, eSIR_ACTIVE_SCAN}, + {48, eSIR_ACTIVE_SCAN}, + //5250 to 5350 + {52, eSIR_ACTIVE_SCAN}, + {56, eSIR_ACTIVE_SCAN}, + {60, eSIR_ACTIVE_SCAN}, + {64, eSIR_ACTIVE_SCAN}, + //5470 to 5725 + {100, eSIR_ACTIVE_SCAN}, + {104, eSIR_ACTIVE_SCAN}, + {108, eSIR_ACTIVE_SCAN}, + {112, eSIR_ACTIVE_SCAN}, + {116, eSIR_ACTIVE_SCAN}, + {120, eSIR_ACTIVE_SCAN}, + {124, eSIR_ACTIVE_SCAN}, + {128, eSIR_ACTIVE_SCAN}, + {132, eSIR_ACTIVE_SCAN}, + {136, eSIR_ACTIVE_SCAN}, + {140, eSIR_ACTIVE_SCAN}, + //5745 - 5825 + {149, eSIR_ACTIVE_SCAN}, + {153, eSIR_ACTIVE_SCAN}, + {157, eSIR_ACTIVE_SCAN}, + {161, eSIR_ACTIVE_SCAN}, + {165, eSIR_ACTIVE_SCAN}, + //4.9GHz + //4920 - 5080 + {240, eSIR_ACTIVE_SCAN}, + {244, eSIR_ACTIVE_SCAN}, + {248, eSIR_ACTIVE_SCAN}, + {252, eSIR_ACTIVE_SCAN}, + {208, eSIR_ACTIVE_SCAN}, + {212, eSIR_ACTIVE_SCAN}, + {216, eSIR_ACTIVE_SCAN}, + //2,4GHz + {1, eSIR_ACTIVE_SCAN}, + {2, eSIR_ACTIVE_SCAN}, + {3, eSIR_ACTIVE_SCAN}, + {4, eSIR_ACTIVE_SCAN}, + {5, eSIR_ACTIVE_SCAN}, + {6, eSIR_ACTIVE_SCAN}, + {7, eSIR_ACTIVE_SCAN}, + {8, eSIR_ACTIVE_SCAN}, + {9, eSIR_ACTIVE_SCAN}, + {10, eSIR_ACTIVE_SCAN}, + {11, eSIR_ACTIVE_SCAN}, + {12, eSIR_ACTIVE_SCAN}, + {13, eSIR_ACTIVE_SCAN}, + {14, eSIR_ACTIVE_SCAN}, + } + }, +}; +#endif + +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; + +//////////////////////////////////////////////////////////////////////// + +/** + * \var gPhyRatesSuppt + * + * \brief Rate support lookup table + * + * + * This is a lookup table indexing rates & configuration parameters to + * support. Given a rate (in unites of 0.5Mpbs) & three booleans (MIMO + * Enabled, Channel Bonding Enabled, & Concatenation Enabled), one can + * determine whether the given rate is supported by computing two + * indices. The first maps the rate to table row as indicated below + * (i.e. eHddSuppRate_6Mbps maps to row zero, eHddSuppRate_9Mbps to row + * 1, and so on). Index two can be computed like so: + * + * \code + idx2 = ( fEsf ? 0x4 : 0x0 ) | + ( fCb ? 0x2 : 0x0 ) | + ( fMimo ? 0x1 : 0x0 ); + * \endcode + * + * + * Given that: + * + \code + fSupported = gPhyRatesSuppt[idx1][idx2]; + \endcode + * + * + * This table is based on the document "PHY Supported Rates.doc". This + * table is permissive in that a rate is reflected as being supported + * even when turning off an enabled feature would be required. For + * instance, "PHY Supported Rates" lists 42Mpbs as unsupported when CB, + * ESF, & MIMO are all on. However, if we turn off either of CB or + * MIMO, it then becomes supported. Therefore, we mark it as supported + * even in index 7 of this table. + * + * + */ + +static const tANI_BOOLEAN gPhyRatesSuppt[24][8] = { + + // SSF SSF SSF SSF ESF ESF ESF ESF + // SIMO MIMO SIMO MIMO SIMO MIMO SIMO MIMO + // No CB No CB CB CB No CB No CB CB CB + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 6Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 9Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 12Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 18Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE }, // 20Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 24Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 36Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 40Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 42Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 48Mbps + { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // 54Mbps + { FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 72Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 80Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 84Mbps + { FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 96Mbps + { FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 108Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 120Mbps + { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE }, // 126Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 144Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 160Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 168Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 192Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 216Mbps + { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE }, // 240Mbps + +}; + +#define CASE_RETURN_STR(n) case (n): return (#n) + +const char * +get_eRoamCmdStatus_str(eRoamCmdStatus val) +{ + switch (val) + { + CASE_RETURN_STR(eCSR_ROAM_CANCELLED); + CASE_RETURN_STR(eCSR_ROAM_FAILED); + CASE_RETURN_STR(eCSR_ROAM_ROAMING_START); + CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION); + CASE_RETURN_STR(eCSR_ROAM_CONNECT_COMPLETION); + CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START); + CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION); + CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED); + CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM); + CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS); + CASE_RETURN_STR(eCSR_ROAM_LOSTLINK); + CASE_RETURN_STR(eCSR_ROAM_LOSTLINK_DETECTED); + CASE_RETURN_STR(eCSR_ROAM_MIC_ERROR_IND); + CASE_RETURN_STR(eCSR_ROAM_IBSS_IND); + CASE_RETURN_STR(eCSR_ROAM_CONNECT_STATUS_UPDATE); + CASE_RETURN_STR(eCSR_ROAM_GEN_INFO); + CASE_RETURN_STR(eCSR_ROAM_SET_KEY_COMPLETE); + CASE_RETURN_STR(eCSR_ROAM_REMOVE_KEY_COMPLETE); + CASE_RETURN_STR(eCSR_ROAM_IBSS_LEAVE); + CASE_RETURN_STR(eCSR_ROAM_WDS_IND); + CASE_RETURN_STR(eCSR_ROAM_INFRA_IND); + CASE_RETURN_STR(eCSR_ROAM_WPS_PBC_PROBE_REQ_IND); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STR(eCSR_ROAM_FT_RESPONSE); +#endif + CASE_RETURN_STR(eCSR_ROAM_FT_START); + CASE_RETURN_STR(eCSR_ROAM_REMAIN_CHAN_READY); + CASE_RETURN_STR(eCSR_ROAM_SEND_ACTION_CNF); + CASE_RETURN_STR(eCSR_ROAM_SESSION_OPENED); + CASE_RETURN_STR(eCSR_ROAM_FT_REASSOC_FAILED); +#ifdef FEATURE_WLAN_LFR + CASE_RETURN_STR(eCSR_ROAM_PMK_NOTIFY); +#endif +#ifdef FEATURE_WLAN_LFR_METRICS + CASE_RETURN_STR(eCSR_ROAM_PREAUTH_INIT_NOTIFY); + CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_SUCCESS); + CASE_RETURN_STR(eCSR_ROAM_PREAUTH_STATUS_FAILURE); + CASE_RETURN_STR(eCSR_ROAM_HANDOVER_SUCCESS); +#endif +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STR(eCSR_ROAM_TDLS_STATUS_UPDATE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND); +#endif + CASE_RETURN_STR(eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS); + CASE_RETURN_STR(eCSR_ROAM_SEND_P2P_STOP_BSS); +#ifdef WLAN_FEATURE_11W + CASE_RETURN_STR(eCSR_ROAM_UNPROT_MGMT_FRAME_IND); +#endif +#ifdef WLAN_FEATURE_RMC + CASE_RETURN_STR(eCSR_ROAM_IBSS_PEER_INFO_COMPLETE); +#endif +#ifdef WLAN_FEATURE_AP_HT40_24G + CASE_RETURN_STR(eCSR_ROAM_2040_COEX_INFO_IND); +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + CASE_RETURN_STR(eCSR_ROAM_TSM_IE_IND); + CASE_RETURN_STR(eCSR_ROAM_CCKM_PREAUTH_NOTIFY); + CASE_RETURN_STR(eCSR_ROAM_ESE_ADJ_AP_REPORT_IND); + CASE_RETURN_STR(eCSR_ROAM_ESE_BCN_REPORT_IND); +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + CASE_RETURN_STR(eCSR_ROAM_UPDATE_MAX_RATE_IND); + CASE_RETURN_STR(eCSR_ROAM_LOST_LINK_PARAMS_IND); + default: + return "unknown"; + } +} + +const char * +get_eCsrRoamResult_str(eCsrRoamResult val) +{ + switch (val) + { + CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND); + CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND); + CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER); + CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED); + default: + return "unknown"; + } +} + + + +tANI_BOOLEAN csrGetBssIdBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tCsrBssid *pBssId ) +{ + vos_mem_copy(pBssId, &pSirBssDesc->bssId[ 0 ], sizeof(tCsrBssid)); + return( TRUE ); +} + + +tANI_BOOLEAN csrIsBssIdEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, tSirBssDescription *pSirBssDesc2 ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fEqual = FALSE; + tCsrBssid bssId1; + tCsrBssid bssId2; + + do { + if ( !pSirBssDesc1 ) break; + if ( !pSirBssDesc2 ) break; + + if ( !csrGetBssIdBssDesc( pMac, pSirBssDesc1, &bssId1 ) ) break; + if ( !csrGetBssIdBssDesc( pMac, pSirBssDesc2, &bssId2 ) ) break; + + //sirCompareMacAddr + fEqual = csrIsMacAddressEqual(pMac, &bssId1, &bssId2); + + } while( 0 ); + + return( fEqual ); +} + +tANI_BOOLEAN csrIsConnStateConnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateDisconnectedIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateConnectedInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateConnected( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + if( csrIsConnStateConnectedIbss( pMac, sessionId ) || csrIsConnStateConnectedInfra( pMac, sessionId ) || csrIsConnStateConnectedWds( pMac, sessionId) ) + return TRUE; + else + return FALSE; +} + +tANI_BOOLEAN csrIsConnStateInfra( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( csrIsConnStateConnectedInfra( pMac, sessionId ) ); +} + +tANI_BOOLEAN csrIsConnStateIbss( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( csrIsConnStateConnectedIbss( pMac, sessionId ) || csrIsConnStateDisconnectedIbss( pMac, sessionId ) ); +} + + +tANI_BOOLEAN csrIsConnStateConnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateConnectedInfraAp( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == pMac->roam.roamSession[sessionId].connectState) || + (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ) ); +} + +tANI_BOOLEAN csrIsConnStateDisconnectedWds( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED == pMac->roam.roamSession[sessionId].connectState ); +} + +tANI_BOOLEAN csrIsConnStateWds( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return( csrIsConnStateConnectedWds( pMac, sessionId ) || + csrIsConnStateDisconnectedWds( pMac, sessionId ) ); +} + +tANI_BOOLEAN csrIsConnStateAp( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + tCsrRoamSession *pSession; + pSession = CSR_GET_SESSION(pMac, sessionId); + if (!pSession) + return eANI_BOOLEAN_FALSE; + if ( CSR_IS_INFRA_AP(&pSession->connectedProfile) ) + { + return eANI_BOOLEAN_TRUE; + } + return eANI_BOOLEAN_FALSE; +} + +tANI_BOOLEAN csrIsAnySessionInConnectState( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && + ( csrIsConnStateInfra( pMac, i ) + || csrIsConnStateIbss( pMac, i ) + || csrIsConnStateAp( pMac, i) ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + +tANI_S8 csrGetInfraSessionId( tpAniSirGlobal pMac ) +{ + tANI_U8 i; + tANI_S8 sessionid = -1; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateInfra( pMac, i ) ) + { + sessionid = i; + break; + } + } + + return ( sessionid ); +} + +tANI_U8 csrGetInfraOperationChannel( tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tANI_U8 channel; + + if( CSR_IS_SESSION_VALID( pMac, sessionId )) + { + channel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel; + } + else + { + channel = 0; + } + return channel; +} + +tANI_BOOLEAN csrIsSessionClientAndConnected(tpAniSirGlobal pMac, tANI_U8 sessionId) +{ + tCsrRoamSession *pSession = NULL; + if ( CSR_IS_SESSION_VALID( pMac, sessionId) && csrIsConnStateInfra( pMac, sessionId)) + { + pSession = CSR_GET_SESSION( pMac, sessionId); + if (NULL != pSession->pCurRoamProfile) + { + if ((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) || + (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE)) + { + return TRUE; + } + } + } + return FALSE; +} +//This routine will return operating channel on FIRST BSS that is active/operating to be used for concurrency mode. +//If other BSS is not up or not connected it will return 0 + +tANI_U8 csrGetConcurrentOperationChannel( tpAniSirGlobal pMac ) +{ + tCsrRoamSession *pSession = NULL; + tANI_U8 i = 0; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) + { + if ( + (((pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) || + (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE)) && + (pSession->connectState == eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) + || + (((pSession->pCurRoamProfile->csrPersona == VOS_P2P_GO_MODE) || + (pSession->pCurRoamProfile->csrPersona == VOS_STA_SAP_MODE)) && + (pSession->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) + ) + return (pSession->connectedProfile.operationChannel); + } + + } + } + return 0; +} + +tANI_BOOLEAN csrIsAllSessionDisconnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_TRUE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + fRc = eANI_BOOLEAN_FALSE; + break; + } + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsStaSessionConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + tCsrRoamSession *pSession = NULL; + tANI_U32 countSta = 0; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) + { + if (pSession->pCurRoamProfile->csrPersona == VOS_STA_MODE) { + countSta++; + } + } + } + } + + /* return TRUE if one of the following conditions is TRUE: + * - more than one STA session connected + */ + if ( countSta > 0) { + fRc = eANI_BOOLEAN_TRUE; + } + + return( fRc ); +} + +tANI_BOOLEAN csrIsP2pSessionConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + tCsrRoamSession *pSession = NULL; + tANI_U32 countP2pCli = 0; + tANI_U32 countP2pGo = 0; + tANI_U32 countSAP = 0; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + pSession = CSR_GET_SESSION( pMac, i ); + + if (NULL != pSession->pCurRoamProfile) + { + if (pSession->pCurRoamProfile->csrPersona == VOS_P2P_CLIENT_MODE) { + countP2pCli++; + } + + if (pSession->pCurRoamProfile->csrPersona == VOS_P2P_GO_MODE) { + countP2pGo++; + } + + if (pSession->pCurRoamProfile->csrPersona == VOS_STA_SAP_MODE) { + countSAP++; + } + } + } + } + + /* return TRUE if one of the following conditions is TRUE: + * - at least one P2P CLI session is connected + * - at least one P2P GO session is connected + */ + if ( (countP2pCli > 0) || (countP2pGo > 0 ) || (countSAP > 0 ) ) { + fRc = eANI_BOOLEAN_TRUE; + } + + return( fRc ); +} + +tANI_BOOLEAN csrIsAnySessionConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i, count; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + count = 0; + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && !csrIsConnStateDisconnected( pMac, i ) ) + { + count++; + } + } + + if (count > 0) + { + fRc = eANI_BOOLEAN_TRUE; + } + return( fRc ); +} + +tANI_BOOLEAN csrIsInfraConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedInfra( pMac, i ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsConcurrentInfraConnected( tpAniSirGlobal pMac ) +{ + tANI_U32 i, noOfConnectedInfra = 0; + + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedInfra( pMac, i ) ) + { + ++noOfConnectedInfra; + } + } + + // More than one Infra Sta Connected + if(noOfConnectedInfra > 1) + { + fRc = eANI_BOOLEAN_TRUE; + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsIBSSStarted( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateIbss( pMac, i ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + + +tANI_BOOLEAN csrIsBTAMPStarted( tpAniSirGlobal pMac ) +{ + tANI_U32 i; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) + { + if( CSR_IS_SESSION_VALID( pMac, i ) && csrIsConnStateConnectedWds( pMac, i ) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsConcurrentSessionRunning( tpAniSirGlobal pMac ) +{ + tANI_U32 sessionId, noOfCocurrentSession = 0; + eCsrConnectState connectState; + + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + connectState = pMac->roam.roamSession[sessionId].connectState; + if( (eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED == connectState) || + (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED == connectState) || + (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED == connectState) ) + { + ++noOfCocurrentSession; + } + } + } + + // More than one session is Up and Running + if(noOfCocurrentSession > 1) + { + fRc = eANI_BOOLEAN_TRUE; + } + + return ( fRc ); +} + +tANI_BOOLEAN csrIsInfraApStarted( tpAniSirGlobal pMac ) +{ + tANI_U32 sessionId; + tANI_BOOLEAN fRc = eANI_BOOLEAN_FALSE; + + for( sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) && (csrIsConnStateConnectedInfraAp(pMac, sessionId)) ) + { + fRc = eANI_BOOLEAN_TRUE; + break; + } + } + + return ( fRc ); + +} + +tANI_BOOLEAN csrIsBTAMP( tpAniSirGlobal pMac, tANI_U32 sessionId ) +{ + return ( csrIsConnStateConnectedWds( pMac, sessionId ) ); +} + + +tANI_BOOLEAN csrIsConnStateDisconnected(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + return (eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED == pMac->roam.roamSession[sessionId].connectState); +} + +tANI_BOOLEAN csrIsValidMcConcurrentSession(tpAniSirGlobal pMac, tANI_U32 sessionId, + tSirBssDescription *pBssDesc) +{ + tCsrRoamSession *pSession = NULL; + eAniBoolean status = eANI_BOOLEAN_FALSE; + + //Check for MCC support + if (!pMac->roam.configParam.fenableMCCMode) + { + return status; + } + + //Validate BeaconInterval + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (NULL != pSession->pCurRoamProfile) + { + if (csrIsconcurrentsessionValid (pMac, sessionId, + pSession->pCurRoamProfile->csrPersona) + == eHAL_STATUS_SUCCESS ) + { + if (csrValidateMCCBeaconInterval( pMac, pBssDesc->channelId, + &pBssDesc->beaconInterval, sessionId, + pSession->pCurRoamProfile->csrPersona) + != eHAL_STATUS_SUCCESS) + { + status = eANI_BOOLEAN_FALSE; + } + else + { + status = eANI_BOOLEAN_TRUE; + } + } + else + { + status = eANI_BOOLEAN_FALSE; + } + } + } + return status; +} + +static tSirMacCapabilityInfo csrGetBssCapabilities( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps; + + //tSirMacCapabilityInfo is 16-bit + pal_get_U16( (tANI_U8 *)&pSirBssDesc->capabilityInfo, (tANI_U16 *)&dot11Caps ); + + return( dot11Caps ); +} + +tANI_BOOLEAN csrIsInfraBssDesc( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.ess ); +} + + +tANI_BOOLEAN csrIsIbssBssDesc( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.ibss ); +} + +tANI_BOOLEAN csrIsQoSBssDesc( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.qos ); +} + +tANI_BOOLEAN csrIsPrivacy( tSirBssDescription *pSirBssDesc ) +{ + tSirMacCapabilityInfo dot11Caps = csrGetBssCapabilities( pSirBssDesc ); + + return( (tANI_BOOLEAN)dot11Caps.privacy ); +} + + +tANI_BOOLEAN csrIs11dSupported(tpAniSirGlobal pMac) +{ + return(pMac->roam.configParam.Is11dSupportEnabled); +} + + +tANI_BOOLEAN csrIs11hSupported(tpAniSirGlobal pMac) +{ + return(pMac->roam.configParam.Is11hSupportEnabled); +} + + +tANI_BOOLEAN csrIs11eSupported(tpAniSirGlobal pMac) +{ + return(pMac->roam.configParam.Is11eSupportEnabled); +} + +tANI_BOOLEAN csrIsMCCSupported ( tpAniSirGlobal pMac ) +{ + return(pMac->roam.configParam.fenableMCCMode); + +} + +tANI_BOOLEAN csrIsWmmSupported(tpAniSirGlobal pMac) +{ + if(eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode) + { + return eANI_BOOLEAN_FALSE; + } + else + { + return eANI_BOOLEAN_TRUE; + } +} + + + + +//pIes is the IEs for pSirBssDesc2 +tANI_BOOLEAN csrIsSsidEqual( tHalHandle hHal, tSirBssDescription *pSirBssDesc1, + tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2 ) +{ + tANI_BOOLEAN fEqual = FALSE; + tSirMacSSid Ssid1, Ssid2; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tDot11fBeaconIEs *pIes1 = NULL; + tDot11fBeaconIEs *pIesLocal = pIes2; + + do { + if( ( NULL == pSirBssDesc1 ) || ( NULL == pSirBssDesc2 ) ) break; + if( !pIesLocal && !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc2, &pIesLocal)) ) + { + smsLog(pMac, LOGE, FL(" fail to parse IEs")); + break; + } + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc1, &pIes1))) + { + break; + } + if( ( !pIes1->SSID.present ) || ( !pIesLocal->SSID.present ) ) break; + if ( pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid ) break; + vos_mem_copy(Ssid1.ssId, pIes1->SSID.ssid, pIes1->SSID.num_ssid); + vos_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid, pIesLocal->SSID.num_ssid); + + fEqual = vos_mem_compare(Ssid1.ssId, Ssid2.ssId, pIesLocal->SSID.num_ssid); + + } while( 0 ); + if(pIes1) + { + vos_mem_free(pIes1); + } + if( pIesLocal && !pIes2 ) + { + vos_mem_free(pIesLocal); + } + + return( fEqual ); +} + +tANI_BOOLEAN csrIsAniWmeSupported(tDot11fIEAirgo *pIeAirgo) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE; + + if(pIeAirgo && pIeAirgo->present && pIeAirgo->PropCapability.present) + { + fRet = (tANI_BOOLEAN)(PROP_CAPABILITY_GET( WME, pIeAirgo->PropCapability.capability )); + } + + return fRet; +} + + + + +//pIes can be passed in as NULL if the caller doesn't have one prepared +tANI_BOOLEAN csrIsBssDescriptionWme( tHalHandle hHal, tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + // Assume that WME is found... + tANI_BOOLEAN fWme = TRUE; + tDot11fBeaconIEs *pIesTemp = pIes; + + do + { + if(pIesTemp == NULL) + { + if( !HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesTemp)) ) + { + fWme = FALSE; + break; + } + } + // if the AirgoProprietary indicator is found, then WME is supported... + if ( csrIsAniWmeSupported(&pIesTemp->Airgo) ) break; + // if the Wme Info IE is found, then WME is supported... + if ( CSR_IS_QOS_BSS(pIesTemp) ) break; + // if none of these are found, then WME is NOT supported... + fWme = FALSE; + } while( 0 ); + if( !csrIsWmmSupported( pMac ) && fWme) + { + if( !pIesTemp->HTCaps.present ) + { + fWme = FALSE; + } + } + if( ( pIes == NULL ) && ( NULL != pIesTemp ) ) + { + //we allocate memory here so free it before returning + vos_mem_free(pIesTemp); + } + + return( fWme ); +} + +tANI_BOOLEAN csrIsHcfEnabled( tDot11fIEAirgo *pIeAirgo ) +{ + tANI_BOOLEAN fHcfSupported = FALSE; + + fHcfSupported = ((tANI_BOOLEAN)(PROP_CAPABILITY_GET( WME, pIeAirgo->PropCapability.capability )) || + (pIeAirgo->present && pIeAirgo->HCF.present && pIeAirgo->HCF.enabled)); + + return( fHcfSupported ); +} + + +eCsrMediaAccessType csrGetQoSFromBssDesc( tHalHandle hHal, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes ) +{ + eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF; + + VOS_ASSERT( pIes != NULL ); + + do + { + // if we find WMM in the Bss Description, then we let this + // override and use WMM. + if ( csrIsBssDescriptionWme( hHal, pSirBssDesc, pIes ) ) + { + qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP; + } + else + { + // if the QoS bit is on, then the AP is advertising 11E QoS... + if ( csrIsQoSBssDesc( pSirBssDesc ) ) + { + // which could be HCF or eDCF. + if ( csrIsHcfEnabled( &pIes->Airgo ) ) + { + qosType = eCSR_MEDIUM_ACCESS_11e_HCF; + } + else + { + qosType = eCSR_MEDIUM_ACCESS_11e_eDCF; + } + } + else + { + qosType = eCSR_MEDIUM_ACCESS_DCF; + } + // scale back based on the types turned on for the adapter... + if ( eCSR_MEDIUM_ACCESS_11e_eDCF == qosType && !csrIs11eSupported( hHal ) ) + { + qosType = eCSR_MEDIUM_ACCESS_DCF; + } + } + + } while(0); + + return( qosType ); +} + + + + +//Caller allocates memory for pIEStruct +eHalStatus csrParseBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIEStruct) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + int ieLen = (int)GET_IE_LEN_IN_BSS(pBssDesc->length); + + if(ieLen > 0 && pIEStruct) + { + if(!DOT11F_FAILED(dot11fUnpackBeaconIEs( pMac, (tANI_U8 *)pBssDesc->ieFields, ieLen, pIEStruct ))) + { + status = eHAL_STATUS_SUCCESS; + } + } + + return (status); +} + + +//This function will allocate memory for the parsed IEs to the caller. Caller must free the memory +//after it is done with the data only if this function succeeds +eHalStatus csrGetParsedBssDescriptionIEs(tHalHandle hHal, tSirBssDescription *pBssDesc, tDot11fBeaconIEs **ppIEStruct) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if(pBssDesc && ppIEStruct) + { + *ppIEStruct = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( (*ppIEStruct) != NULL) + { + vos_mem_set((void *)*ppIEStruct, sizeof(tDot11fBeaconIEs), 0); + status = csrParseBssDescriptionIEs(hHal, pBssDesc, *ppIEStruct); + if(!HAL_STATUS_SUCCESS(status)) + { + vos_mem_free(*ppIEStruct); + *ppIEStruct = NULL; + } + } + else + { + smsLog( pMac, LOGE, FL(" failed to allocate memory") ); + VOS_ASSERT( 0 ); + return eHAL_STATUS_FAILURE; + } + } + + return (status); +} + +eHalStatus csrProcessGetFrameLogCommand( tpAniSirGlobal pMac, + tSmeCmd *pCommand ) +{ + tAniGetFrameLogReq *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + + msgLen = sizeof(tAniGetFrameLogReq); + + if ( NULL == pCommand ) + { + smsLog( pMac, LOGE, FL("cannot process. cmd is null") ); + return eHAL_STATUS_FAILURE; + } + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + smsLog( pMac, LOGE, FL("fail to allocate memory") ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType= pal_cpu_to_be16((tANI_U16)WDA_GET_FRAME_LOG_REQ); + pMsg->msgLen= pal_cpu_to_be16(msgLen); + + pMsg->getFrameLogCmdFlag = pCommand->u.getFramelogCmd.getFrameLogCmdFlag; + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return( status ); +} + +tANI_BOOLEAN csrIsNULLSSID( tANI_U8 *pBssSsid, tANI_U8 len ) +{ + tANI_BOOLEAN fNullSsid = FALSE; + + tANI_U32 SsidLength; + tANI_U8 *pSsidStr; + + do + { + if ( 0 == len ) + { + fNullSsid = TRUE; + break; + } + + //Consider 0 or space for hidden SSID + if ( 0 == pBssSsid[0] ) + { + fNullSsid = TRUE; + break; + } + + SsidLength = len; + pSsidStr = pBssSsid; + + while ( SsidLength ) + { + if( *pSsidStr ) + break; + + pSsidStr++; + SsidLength--; + } + + if( 0 == SsidLength ) + { + fNullSsid = TRUE; + break; + } + } + while( 0 ); + + return fNullSsid; +} + + +tANI_U32 csrGetFragThresh( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return pMac->roam.configParam.FragmentationThreshold; +} + +tANI_U32 csrGetRTSThresh( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return pMac->roam.configParam.RTSThreshold; +} + +eCsrPhyMode csrTranslateToPhyModeFromBssDesc( tSirBssDescription *pSirBssDesc ) +{ + eCsrPhyMode phyMode; + + switch ( pSirBssDesc->nwType ) + { + case eSIR_11A_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11a; + break; + + case eSIR_11B_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11b; + break; + + case eSIR_11G_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11g; + break; + + case eSIR_11N_NW_TYPE: + phyMode = eCSR_DOT11_MODE_11n; + break; +#ifdef WLAN_FEATURE_11AC + case eSIR_11AC_NW_TYPE: + default: + phyMode = eCSR_DOT11_MODE_11ac; +#else + default: + phyMode = eCSR_DOT11_MODE_11n; +#endif + break; + } + return( phyMode ); +} + + +tANI_U32 csrTranslateToWNICfgDot11Mode(tpAniSirGlobal pMac, eCsrCfgDot11Mode csrDot11Mode) +{ + tANI_U32 ret; + + switch(csrDot11Mode) + { + case eCSR_CFG_DOT11_MODE_AUTO: + smsLog(pMac, LOGW, FL(" Warning: sees eCSR_CFG_DOT11_MODE_AUTO ")); + //We cannot decide until now. + if(pMac->roam.configParam.ProprietaryRatesEnabled) + { + ret = WNI_CFG_DOT11_MODE_TAURUS; + } + else + { +#ifdef WLAN_FEATURE_11AC + if ( IS_FEATURE_SUPPORTED_BY_DRIVER(DOT11AC) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + ret = WNI_CFG_DOT11_MODE_11AC; + else + ret = WNI_CFG_DOT11_MODE_11N; +#else + ret = WNI_CFG_DOT11_MODE_11N; +#endif + } + break; + case eCSR_CFG_DOT11_MODE_TAURUS: + ret = WNI_CFG_DOT11_MODE_TAURUS; + break; + case eCSR_CFG_DOT11_MODE_11A: + ret = WNI_CFG_DOT11_MODE_11A; + break; + case eCSR_CFG_DOT11_MODE_11B: + ret = WNI_CFG_DOT11_MODE_11B; + break; + case eCSR_CFG_DOT11_MODE_11G: + ret = WNI_CFG_DOT11_MODE_11G; + break; + case eCSR_CFG_DOT11_MODE_11N: + ret = WNI_CFG_DOT11_MODE_11N; + break; + case eCSR_CFG_DOT11_MODE_POLARIS: + ret = WNI_CFG_DOT11_MODE_POLARIS; + break; + case eCSR_CFG_DOT11_MODE_TITAN: + ret = WNI_CFG_DOT11_MODE_TITAN; + break; + case eCSR_CFG_DOT11_MODE_11G_ONLY: + ret = WNI_CFG_DOT11_MODE_11G_ONLY; + break; + case eCSR_CFG_DOT11_MODE_11N_ONLY: + ret = WNI_CFG_DOT11_MODE_11N_ONLY; + break; + +#ifdef WLAN_FEATURE_11AC + case eCSR_CFG_DOT11_MODE_11AC_ONLY: + if ( IS_FEATURE_SUPPORTED_BY_DRIVER(DOT11AC) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + ret = WNI_CFG_DOT11_MODE_11AC_ONLY; + else + ret = WNI_CFG_DOT11_MODE_11N; + break; + case eCSR_CFG_DOT11_MODE_11AC: + if ( IS_FEATURE_SUPPORTED_BY_DRIVER(DOT11AC) && + IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + ret = WNI_CFG_DOT11_MODE_11AC; + else + ret = WNI_CFG_DOT11_MODE_11N; + break; +#endif + default: + smsLog(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"), csrDot11Mode); + if(eCSR_BAND_24 == pMac->roam.configParam.eBand) + { + ret = WNI_CFG_DOT11_MODE_11G; + } + else + { + ret = WNI_CFG_DOT11_MODE_11A; + } + break; + } + + return (ret); +} + + +//This function should only return the super set of supported modes. 11n implies 11b/g/a/n. +eHalStatus csrGetPhyModeFromBss(tpAniSirGlobal pMac, tSirBssDescription *pBSSDescription, + eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + eCsrPhyMode phyMode = csrTranslateToPhyModeFromBssDesc(pBSSDescription); + + if( pIes ) + { + if(pIes->Airgo.present) + { + if(pIes->Airgo.PropCapability.present) + { + if( PROP_CAPABILITY_GET( TAURUS, pIes->Airgo.PropCapability.capability )) + { + phyMode = eCSR_DOT11_MODE_TAURUS; + } + } + } + if(pIes->HTCaps.present && (eCSR_DOT11_MODE_TAURUS != phyMode)) + { + phyMode = eCSR_DOT11_MODE_11n; +#ifdef WLAN_FEATURE_11AC + if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps)) + { + phyMode = eCSR_DOT11_MODE_11ac; + } +#endif + } + *pPhyMode = phyMode; + } + + return (status); + +} + + +//This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes matches +//bssPhyMode is the mode derived from the BSS description +//f5GhzBand is derived from the channel id of BSS description +tANI_BOOLEAN csrGetPhyModeInUse( eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode, tANI_BOOLEAN f5GhzBand, + eCsrCfgDot11Mode *pCfgDot11ModeToUse ) +{ + tANI_BOOLEAN fMatch = FALSE; + eCsrCfgDot11Mode cfgDot11Mode; + + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; // to suppress compiler warning + + switch( phyModeIn ) + { + case eCSR_DOT11_MODE_abg: //11a or 11b or 11g + if( f5GhzBand ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + else if( eCSR_DOT11_MODE_11b == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + break; + + case eCSR_DOT11_MODE_11a: //11a + if( f5GhzBand ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + break; + + case eCSR_DOT11_MODE_11a_ONLY: //11a + if( eCSR_DOT11_MODE_11a == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + } + break; + + case eCSR_DOT11_MODE_11g: + if(!f5GhzBand) + { + if( eCSR_DOT11_MODE_11b == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + else + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + } + break; + + case eCSR_DOT11_MODE_11g_ONLY: + if( eCSR_DOT11_MODE_11g == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + } + break; + + case eCSR_DOT11_MODE_11b: + if( !f5GhzBand ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + break; + + case eCSR_DOT11_MODE_11b_ONLY: + if( eCSR_DOT11_MODE_11b == bssPhyMode ) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + } + break; + + case eCSR_DOT11_MODE_11n: + fMatch = TRUE; + switch(bssPhyMode) + { + case eCSR_DOT11_MODE_11g: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11b: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11a: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11n: +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: +#endif + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; + + case eCSR_DOT11_MODE_TAURUS: + default: +#ifdef WLAN_FEATURE_11AC + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; +#else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; +#endif + break; + } + break; + + case eCSR_DOT11_MODE_11n_ONLY: + if((eCSR_DOT11_MODE_11n == bssPhyMode) || (eCSR_DOT11_MODE_TAURUS == bssPhyMode)) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + + } + + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + fMatch = TRUE; + switch(bssPhyMode) + { + case eCSR_DOT11_MODE_11g: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11b: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11a: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11n: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; + case eCSR_DOT11_MODE_11ac: + case eCSR_DOT11_MODE_TAURUS: + default: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + break; + } + break; + + case eCSR_DOT11_MODE_11ac_ONLY: + if((eCSR_DOT11_MODE_11ac == bssPhyMode) || (eCSR_DOT11_MODE_TAURUS == bssPhyMode)) + { + fMatch = TRUE; + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + break; +#endif + + case eCSR_DOT11_MODE_TAURUS: + default: + fMatch = TRUE; + switch(bssPhyMode) + { + case eCSR_DOT11_MODE_11g: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11b: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11a: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11n: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + break; +#endif + case eCSR_DOT11_MODE_TAURUS: + default: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + break; + } + break; + } + + if ( fMatch && pCfgDot11ModeToUse ) + { +#ifdef WLAN_FEATURE_11AC + if(cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))) + { + *pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; + } + else +#endif + { + *pCfgDot11ModeToUse = cfgDot11Mode; + } + } + return( fMatch ); +} + + +//This function decides whether the one of the bit of phyMode is matching the mode in the BSS and allowed by the user +//setting, pMac->roam.configParam.uCfgDot11Mode. It returns the mode that fits the criteria. +tANI_BOOLEAN csrIsPhyModeMatch( tpAniSirGlobal pMac, tANI_U32 phyMode, + tSirBssDescription *pSirBssDesc, tCsrRoamProfile *pProfile, + eCsrCfgDot11Mode *pReturnCfgDot11Mode, + tDot11fBeaconIEs *pIes) +{ + tANI_BOOLEAN fMatch = FALSE; + eCsrPhyMode phyModeInBssDesc, phyMode2; + eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_TAURUS; + tANI_U32 bitMask, loopCount; + + if(HAL_STATUS_SUCCESS(csrGetPhyModeFromBss(pMac, pSirBssDesc, &phyModeInBssDesc, pIes ))) + { + //In case some change change eCSR_DOT11_MODE_TAURUS to non-0 + if ( (0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode) || (eCSR_DOT11_MODE_TAURUS & phyMode)) + { + //Taurus means anything + if ( eCSR_CFG_DOT11_MODE_ABG == pMac->roam.configParam.uCfgDot11Mode ) + { + phyMode = eCSR_DOT11_MODE_abg; + } + else if(eCSR_CFG_DOT11_MODE_AUTO == pMac->roam.configParam.uCfgDot11Mode) + { + if(pMac->roam.configParam.ProprietaryRatesEnabled) + { + phyMode = eCSR_DOT11_MODE_TAURUS; + } + else + { + +#ifdef WLAN_FEATURE_11AC + phyMode = eCSR_DOT11_MODE_11ac; +#else + phyMode = eCSR_DOT11_MODE_11n; +#endif + + } + } + else + { + //user's pick + phyMode = pMac->roam.configParam.phyMode; + } + } + if ( (0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode) || (eCSR_DOT11_MODE_TAURUS & phyMode) ) + { + if(0 != phyMode) + { + if(eCSR_DOT11_MODE_AUTO & phyMode) + { + phyMode2 = eCSR_DOT11_MODE_AUTO & phyMode; + } + else + { + phyMode2 = eCSR_DOT11_MODE_TAURUS & phyMode; + } + } + else + { + phyMode2 = phyMode; + } + fMatch = csrGetPhyModeInUse( phyMode2, phyModeInBssDesc, CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId), + &cfgDot11ModeToUse ); + } + else + { + bitMask = 1; + loopCount = 0; + while(loopCount < eCSR_NUM_PHY_MODE) + { + if(0 != ( phyMode2 = (phyMode & (bitMask << loopCount++)) )) + { + fMatch = csrGetPhyModeInUse( phyMode2, phyModeInBssDesc, CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId), + &cfgDot11ModeToUse ); + if(fMatch) break; + } + } + } + if ( fMatch && pReturnCfgDot11Mode ) + { + if( pProfile ) + { + /* IEEE 11n spec (8.4.3): HT STA shall eliminate TKIP as a + * choice for the pairwise cipher suite if CCMP is advertised + * by the AP or if the AP included an HT capabilities element + * in its Beacons and Probe Response. + */ + if( (!CSR_IS_11n_ALLOWED( pProfile->negotiatedUCEncryptionType )) && + ((eCSR_CFG_DOT11_MODE_11N == cfgDot11ModeToUse) || +#ifdef WLAN_FEATURE_11AC + (eCSR_CFG_DOT11_MODE_11AC == cfgDot11ModeToUse) || +#endif + (eCSR_CFG_DOT11_MODE_TAURUS == cfgDot11ModeToUse)) ) + { + //We cannot do 11n here + if( !CSR_IS_CHANNEL_5GHZ(pSirBssDesc->channelId) ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; + } + else + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; + } + } + } + *pReturnCfgDot11Mode = cfgDot11ModeToUse; + } + } + + return( fMatch ); +} + + +eCsrCfgDot11Mode csrFindBestPhyMode( tpAniSirGlobal pMac, tANI_U32 phyMode ) +{ + eCsrCfgDot11Mode cfgDot11ModeToUse; + eCsrBand eBand = pMac->roam.configParam.eBand; + + + if ((0 == phyMode) || +#ifdef WLAN_FEATURE_11AC + (eCSR_DOT11_MODE_11ac & phyMode) || +#endif + (eCSR_DOT11_MODE_AUTO & phyMode)) + { +#ifdef WLAN_FEATURE_11AC + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC; + } + else +#endif + { + /* Default to 11N mode if user has configured 11ac mode + * and FW doesn't supports 11ac mode . + */ + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; + } + } + else + { + if( ( eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY ) & phyMode ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N; + } + else if ( eCSR_DOT11_MODE_abg & phyMode ) + { + if( eCSR_BAND_24 != eBand ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; + } + else + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; + } + } + else if( ( eCSR_DOT11_MODE_11a | eCSR_DOT11_MODE_11a_ONLY ) & phyMode ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A; + } + else if( ( eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY ) & phyMode ) + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G; + } + else + { + cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B; + } + } + + return ( cfgDot11ModeToUse ); +} + + + + +tANI_U32 csrGet11hPowerConstraint( tHalHandle hHal, tDot11fIEPowerConstraints *pPowerConstraint ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 localPowerConstraint = 0; + + // check if .11h support is enabled, if not, the power constraint is 0. + if(pMac->roam.configParam.Is11hSupportEnabled && pPowerConstraint->present) + { + localPowerConstraint = pPowerConstraint->localPowerConstraints; + } + + return( localPowerConstraint ); +} + + +tANI_BOOLEAN csrIsProfileWpa( tCsrRoamProfile *pProfile ) +{ + tANI_BOOLEAN fWpaProfile = FALSE; + + switch ( pProfile->negotiatedAuthType ) + { + case eCSR_AUTH_TYPE_WPA: + case eCSR_AUTH_TYPE_WPA_PSK: + case eCSR_AUTH_TYPE_WPA_NONE: +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: +#endif + fWpaProfile = TRUE; + break; + + default: + fWpaProfile = FALSE; + break; + } + + if ( fWpaProfile ) + { + switch ( pProfile->negotiatedUCEncryptionType ) + { + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: + fWpaProfile = TRUE; + break; + + default: + fWpaProfile = FALSE; + break; + } + } + return( fWpaProfile ); +} + +tANI_BOOLEAN csrIsProfileRSN( tCsrRoamProfile *pProfile ) +{ + tANI_BOOLEAN fRSNProfile = FALSE; + + switch ( pProfile->negotiatedAuthType ) + { + case eCSR_AUTH_TYPE_RSN: + case eCSR_AUTH_TYPE_RSN_PSK: +#ifdef WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: + case eCSR_AUTH_TYPE_FT_RSN_PSK: +#endif +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_RSN: +#endif +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: +#endif + fRSNProfile = TRUE; + break; + + default: + fRSNProfile = FALSE; + break; + } + + if ( fRSNProfile ) + { + switch ( pProfile->negotiatedUCEncryptionType ) + { + // !!REVIEW - For WPA2, use of RSN IE mandates + // use of AES as encryption. Here, we qualify + // even if encryption type is WEP or TKIP + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: + fRSNProfile = TRUE; + break; + + default: + fRSNProfile = FALSE; + break; + } + } + return( fRSNProfile ); +} + +eHalStatus +csrIsconcurrentsessionValid(tpAniSirGlobal pMac,tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona) +{ + tANI_U32 sessionId = 0; + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if (cursessionId != sessionId ) + { + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + continue; + } + + switch (currBssPersona) + { + case VOS_STA_MODE: + { + smsLog(pMac, LOG4, FL(" Second session for persona %d"), currBssPersona); + return eHAL_STATUS_SUCCESS; + } + break; + + case VOS_STA_SAP_MODE: + if((pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE)&& + (pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****SoftAP mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + else if( (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) || + (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_IBSS_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****Cannot start Multiple Beaconing Role ****")); + return eHAL_STATUS_FAILURE; + } + break; + + case VOS_P2P_CLIENT_MODE: + if(pMac->roam.roamSession[sessionId].pCurRoamProfile && + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_P2P_CLIENT_MODE)) //check for P2P client mode + { + smsLog(pMac, LOGE, FL(" ****CLIENT mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + break; + + case VOS_P2P_GO_MODE: + if((pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) && + (pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****P2P GO mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + else if( (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) || + (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_IBSS_MODE && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED) ) + { + smsLog(pMac, LOGE, FL(" ****Cannot start Multiple Beaconing Role ****")); + return eHAL_STATUS_FAILURE; + } + break; + case VOS_IBSS_MODE: + if((pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_IBSS_MODE) && + (pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED)) + { + smsLog(pMac, LOGE, FL(" ****IBSS mode already exists ****")); + return eHAL_STATUS_FAILURE; + } + else if( (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE || + pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE) && + pMac->roam.roamSession[sessionId].connectState + != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED) + { + smsLog(pMac, LOGE, FL(" ****Cannot start Multiple Beaconing Role ****")); + return eHAL_STATUS_FAILURE; + } + break; + default : + smsLog(pMac, LOGE, FL("***Persona not handled = %d*****"),currBssPersona); + break; + } + } + } + return eHAL_STATUS_SUCCESS; + +} + +eHalStatus csrUpdateMCCp2pBeaconInterval(tpAniSirGlobal pMac) +{ + tANI_U32 sessionId = 0; + + //If MCC is not supported just break and return SUCCESS + if ( !pMac->roam.configParam.fenableMCCMode){ + return eHAL_STATUS_FAILURE; + } + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + /* If GO in MCC support different beacon interval, + * change the BI of the P2P-GO */ + if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) + { + /* Handle different BI scneario based on the configuration set. + * If Config is set to 0x02 then Disconnect all the P2P clients + * associated. If config is set to 0x04 then update the BI + * without disconnecting all the clients + */ + if ((pMac->roam.configParam.fAllowMCCGODiffBI == 0x04) && + (pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval)) + { + return csrSendChngMCCBeaconInterval( pMac, sessionId); + } + //If the configuration of fAllowMCCGODiffBI is set to other than 0x04 + else if ( pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval) + { + return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS, eCSR_ROAM_RESULT_NONE); + } + } + } + return eHAL_STATUS_FAILURE; +} + +tANI_U16 csrCalculateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U16 sta_bi, tANI_U16 go_gbi) +{ + tANI_U8 num_beacons = 0; + tANI_U8 is_multiple = 0; + tANI_U16 go_cbi = 0; + tANI_U16 go_fbi = 0; + tANI_U16 sta_cbi = 0; + + //If GO's given beacon Interval is less than 100 + if(go_gbi < 100) + go_cbi = 100; + //if GO's given beacon Interval is greater than or equal to 100 + else + go_cbi = 100 + (go_gbi % 100); + + if ( sta_bi == 0 ) + { + /* There is possibility to receive zero as value. + Which will cause divide by zero. Hence initialise with 100 + */ + sta_bi = 100; + smsLog(pMac, LOGW, + FL("sta_bi 2nd parameter is zero, initialise to %d"), sta_bi); + } + + // check, if either one is multiple of another + if (sta_bi > go_cbi) + { + is_multiple = !(sta_bi % go_cbi); + } + else + { + is_multiple = !(go_cbi % sta_bi); + } + // if it is multiple, then accept GO's beacon interval range [100,199] as it is + if (is_multiple) + { + return go_cbi; + } + //else , if it is not multiple, then then check for number of beacons to be + //inserted based on sta BI + num_beacons = sta_bi / 100; + if (num_beacons) + { + // GO's final beacon interval will be aligned to sta beacon interval, but + //in the range of [100, 199]. + sta_cbi = sta_bi / num_beacons; + go_fbi = sta_cbi; + } + else + { + // if STA beacon interval is less than 100, use GO's change bacon interval + //instead of updating to STA's beacon interval. + go_fbi = go_cbi; + } + return go_fbi; +} + +eHalStatus csrValidateMCCBeaconInterval(tpAniSirGlobal pMac, tANI_U8 channelId, + tANI_U16 *beaconInterval, tANI_U32 cursessionId, + tVOS_CON_MODE currBssPersona) +{ + tANI_U32 sessionId = 0; + tANI_U16 new_beaconInterval = 0; + + //If MCC is not supported just break + if (!pMac->roam.configParam.fenableMCCMode){ + return eHAL_STATUS_FAILURE; + } + + for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++ ) + { + if (cursessionId != sessionId ) + { + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + continue; + } + + switch (currBssPersona) + { + case VOS_STA_MODE: + if (pMac->roam.roamSession[sessionId].pCurRoamProfile && + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_P2P_CLIENT_MODE)) //check for P2P client mode + { + smsLog(pMac, LOG1, FL(" Beacon Interval Validation not required for STA/CLIENT")); + } + //IF SAP has started and STA wants to connect on different channel MCC should + //MCC should not be enabled so making it false to enforce on same channel + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE) + { + if (pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) + { + smsLog(pMac, LOGE, FL("*** MCC with SAP+STA sessions ****")); + return eHAL_STATUS_SUCCESS; + } + } + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) //Check for P2P go scenario + { + /* if GO in MCC support different beacon interval, + * change the BI of the P2P-GO */ + if ((pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) && + (pMac->roam.roamSession[sessionId].bssParams.beaconInterval + != *beaconInterval)) + { + /* if GO in MCC support different beacon interval, return success */ + if ( pMac->roam.configParam.fAllowMCCGODiffBI == 0x01) + { + return eHAL_STATUS_SUCCESS; + } + // Send only Broadcast disassoc and update beaconInterval + //If configuration is set to 0x04 then dont + // disconnect all the station + else if ((pMac->roam.configParam.fAllowMCCGODiffBI == 0x02) || + (pMac->roam.configParam.fAllowMCCGODiffBI == 0x04)) + { + //Check to pass the right beacon Interval + new_beaconInterval = csrCalculateMCCBeaconInterval(pMac, *beaconInterval, + pMac->roam.roamSession[sessionId].bssParams.beaconInterval); + smsLog(pMac, LOG1, FL(" Peer AP BI : %d, new Beacon Interval: %d"),*beaconInterval,new_beaconInterval ); + //Update the becon Interval + if (new_beaconInterval != pMac->roam.roamSession[sessionId].bssParams.beaconInterval) + { + //Update the beaconInterval now + smsLog(pMac, LOGE, FL(" Beacon Interval got changed config used: %d\n"), + pMac->roam.configParam.fAllowMCCGODiffBI); + + pMac->roam.roamSession[sessionId].bssParams.beaconInterval = new_beaconInterval; + pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_TRUE; + return csrUpdateMCCp2pBeaconInterval(pMac); + } + return eHAL_STATUS_SUCCESS; + } + //Disconnect the P2P session + else if (pMac->roam.configParam.fAllowMCCGODiffBI == 0x03) + { + pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = eANI_BOOLEAN_FALSE; + return csrRoamCallCallback(pMac, sessionId, NULL, 0, eCSR_ROAM_SEND_P2P_STOP_BSS, eCSR_ROAM_RESULT_NONE); + } + else + { + smsLog(pMac, LOGE, FL("BeaconInterval is different cannot connect to preferred AP...")); + return eHAL_STATUS_FAILURE; + } + } + } + break; + + case VOS_P2P_CLIENT_MODE: + if (pMac->roam.roamSession[sessionId].pCurRoamProfile && + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_STA_MODE)) //check for P2P client mode + { + smsLog(pMac, LOG1, FL(" Ignore Beacon Interval Validation...")); + } + //IF SAP has started and STA wants to connect on different channel MCC should + //MCC should not be enabled so making it false to enforce on same channel + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_STA_SAP_MODE) + { + if (pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) + { + smsLog(pMac, LOGE, FL("***MCC is not enabled for SAP + CLIENT****")); + return eHAL_STATUS_FAILURE; + } + } + else if (pMac->roam.roamSession[sessionId].bssParams.bssPersona + == VOS_P2P_GO_MODE) //Check for P2P go scenario + { + if ((pMac->roam.roamSession[sessionId].bssParams.operationChn + != channelId ) && + (pMac->roam.roamSession[sessionId].bssParams.beaconInterval + != *beaconInterval)) + { + smsLog(pMac, LOGE, FL("BeaconInterval is different cannot connect to P2P_GO network ...")); + return eHAL_STATUS_FAILURE; + } + } + break; + + case VOS_P2P_GO_MODE : + { + if (pMac->roam.roamSession[sessionId].pCurRoamProfile && + ((pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_P2P_CLIENT_MODE) || + (pMac->roam.roamSession[sessionId].pCurRoamProfile->csrPersona + == VOS_STA_MODE))) //check for P2P_client scenario + { + if ((pMac->roam.roamSession[sessionId].connectedProfile.operationChannel + == 0 )&& + (pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval + == 0)) + { + continue; + } + + //Assert if connected profile beacon internal is ZERO + if(!pMac->roam.roamSession[sessionId].\ + connectedProfile.beaconInterval) + { + smsLog( pMac, LOGE, FL(" Connected profile " + "beacon interval is zero") ); + } + + + if (csrIsConnStateConnectedInfra(pMac, sessionId) && + (pMac->roam.roamSession[sessionId].connectedProfile.operationChannel + != channelId ) && + (pMac->roam.roamSession[sessionId].connectedProfile.beaconInterval + != *beaconInterval)) + { + /* + * Updated beaconInterval should be used only when we are starting a new BSS + * not incase of client or STA case + */ + //Calculate beacon Interval for P2P-GO incase of MCC + new_beaconInterval = csrCalculateMCCBeaconInterval(pMac, + pMac->roam.roamSession[sessionId].bssParams.beaconInterval, + *beaconInterval ); + if(*beaconInterval != new_beaconInterval) + *beaconInterval = new_beaconInterval; + return eHAL_STATUS_SUCCESS; + } + } + } + break; + + default : + smsLog(pMac, LOGE, FL(" Persona not supported : %d"),currBssPersona); + return eHAL_STATUS_FAILURE; + } + } + } + + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* Function to return TRUE if the authtype is 11r */ +tANI_BOOLEAN csrIsAuthType11r( eCsrAuthType AuthType, tANI_U8 mdiePresent) +{ + switch ( AuthType ) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + if(mdiePresent) + return TRUE; + break; + case eCSR_AUTH_TYPE_FT_RSN_PSK: + case eCSR_AUTH_TYPE_FT_RSN: + return TRUE; + break; + default: + break; + } + return FALSE; +} + +/* Function to return TRUE if the profile is 11r */ +tANI_BOOLEAN csrIsProfile11r( tCsrRoamProfile *pProfile ) +{ + return csrIsAuthType11r( pProfile->negotiatedAuthType, pProfile->MDID.mdiePresent ); +} + +#endif + +#ifdef FEATURE_WLAN_ESE + +/* Function to return TRUE if the authtype is ESE */ +tANI_BOOLEAN csrIsAuthTypeESE( eCsrAuthType AuthType ) +{ + switch ( AuthType ) + { + case eCSR_AUTH_TYPE_CCKM_WPA: + case eCSR_AUTH_TYPE_CCKM_RSN: + return TRUE; + break; + default: + break; + } + return FALSE; +} + +/* Function to return TRUE if the profile is ESE */ +tANI_BOOLEAN csrIsProfileESE( tCsrRoamProfile *pProfile ) +{ + return (csrIsAuthTypeESE( pProfile->negotiatedAuthType )); +} + +#endif + +#ifdef FEATURE_WLAN_WAPI +tANI_BOOLEAN csrIsProfileWapi( tCsrRoamProfile *pProfile ) +{ + tANI_BOOLEAN fWapiProfile = FALSE; + + switch ( pProfile->negotiatedAuthType ) + { + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + fWapiProfile = TRUE; + break; + + default: + fWapiProfile = FALSE; + break; + } + + if ( fWapiProfile ) + { + switch ( pProfile->negotiatedUCEncryptionType ) + { + case eCSR_ENCRYPT_TYPE_WPI: + fWapiProfile = TRUE; + break; + + default: + fWapiProfile = FALSE; + break; + } + } + return( fWapiProfile ); +} + +static tANI_BOOLEAN csrIsWapiOuiEqual( tpAniSirGlobal pMac, tANI_U8 *Oui1, tANI_U8 *Oui2 ) +{ + return (vos_mem_compare(Oui1, Oui2, CSR_WAPI_OUI_SIZE)); +} + +static tANI_BOOLEAN csrIsWapiOuiMatch( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Cypher[], + tANI_U8 Oui[] ) +{ + tANI_BOOLEAN fYes = FALSE; + tANI_U8 idx; + + for ( idx = 0; idx < cAllCyphers; idx++ ) + { + if ( csrIsWapiOuiEqual( pMac, AllCyphers[ idx ], Cypher ) ) + { + fYes = TRUE; + break; + } + } + + if ( fYes && Oui ) + { + vos_mem_copy(Oui, AllCyphers[ idx ], CSR_WAPI_OUI_SIZE); + } + + return( fYes ); +} +#endif /* FEATURE_WLAN_WAPI */ + +static tANI_BOOLEAN csrIsWpaOuiEqual( tpAniSirGlobal pMac, tANI_U8 *Oui1, tANI_U8 *Oui2 ) +{ + return(vos_mem_compare(Oui1, Oui2, CSR_WPA_OUI_SIZE)); +} + +static tANI_BOOLEAN csrIsOuiMatch( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Cypher[], + tANI_U8 Oui[] ) +{ + tANI_BOOLEAN fYes = FALSE; + tANI_U8 idx; + + for ( idx = 0; idx < cAllCyphers; idx++ ) + { + if ( csrIsWpaOuiEqual( pMac, AllCyphers[ idx ], Cypher ) ) + { + fYes = TRUE; + break; + } + } + + if ( fYes && Oui ) + { + vos_mem_copy(Oui, AllCyphers[ idx ], CSR_WPA_OUI_SIZE); + } + + return( fYes ); +} + +static tANI_BOOLEAN csrMatchRSNOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, tANI_U8 ouiIndex, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui[ouiIndex], Oui ) ); + +} + +#ifdef FEATURE_WLAN_WAPI +static tANI_BOOLEAN csrMatchWapiOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllCyphers, tANI_U8 ouiIndex, + tANI_U8 Oui[] ) +{ + if (ouiIndex < CSR_WAPI_OUI_ROW_SIZE)// since csrWapiOui row size is 3 . + return( csrIsWapiOuiMatch( pMac, AllCyphers, cAllCyphers, + csrWapiOui[ouiIndex], Oui ) ); + else + return FALSE ; + +} +#endif /* FEATURE_WLAN_WAPI */ + +static tANI_BOOLEAN csrMatchWPAOUIIndex( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, tANI_U8 ouiIndex, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui[ouiIndex], Oui ) ); + +} + +#if 0 +static tANI_BOOLEAN csrIsRSNUnicastNone( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui00, Oui ) ); +} + +static tANI_BOOLEAN csrIsRSNMulticastWep( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + tANI_BOOLEAN fYes = FALSE; + + // Check Wep 104 first, if fails, then check Wep40. + fYes = csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui05, Oui ); + + if ( !fYes ) + { + // if not Wep-104, check Wep-40 + fYes = csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui01, Oui ); + } + + return( fYes ); +} + + +static tANI_BOOLEAN csrIsRSNUnicastTkip( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui02, Oui ) ); +} + + +static tANI_BOOLEAN csrIsRSNMulticastTkip( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui02, Oui ) ); +} + +static tANI_BOOLEAN csrIsRSNUnicastAes( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui04, Oui ) ); +} + +static tANI_BOOLEAN csrIsRSNMulticastAes( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrRSNOui04, Oui ) ); +} +#endif +#ifdef FEATURE_WLAN_WAPI +static tANI_BOOLEAN csrIsAuthWapiCert( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsWapiOuiMatch( pMac, AllSuites, cAllSuites, csrWapiOui[1], Oui ) ); +} +static tANI_BOOLEAN csrIsAuthWapiPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WAPI_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsWapiOuiMatch( pMac, AllSuites, cAllSuites, csrWapiOui[2], Oui ) ); +} +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/* + * Function for 11R FT Authentication. We match the FT Authentication Cipher suite + * here. This matches for FT Auth with the 802.1X exchange. + * + */ +static tANI_BOOLEAN csrIsFTAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[03], Oui ) ); +} + +/* + * Function for 11R FT Authentication. We match the FT Authentication Cipher suite + * here. This matches for FT Auth with the PSK. + * + */ +static tANI_BOOLEAN csrIsFTAuthRSNPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[04], Oui ) ); +} + +#endif + +#ifdef FEATURE_WLAN_ESE + +/* + * Function for ESE CCKM AKM Authentication. We match the CCKM AKM Authentication Key Management suite + * here. This matches for CCKM AKM Auth with the 802.1X exchange. + * + */ +static tANI_BOOLEAN csrIsEseCckmAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[06], Oui ) ); +} + +static tANI_BOOLEAN csrIsEseCckmAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[06], Oui ) ); +} + +#endif + +static tANI_BOOLEAN csrIsAuthRSN( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[01], Oui ) ); +} +static tANI_BOOLEAN csrIsAuthRSNPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[02], Oui ) ); +} + +#ifdef WLAN_FEATURE_11W +static tANI_BOOLEAN csrIsAuthRSNPskSha256( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[07], Oui ); +} +static tANI_BOOLEAN csrIsAuthRSN8021xSha256(tpAniSirGlobal pMac, + tANI_U8 AllSuites[][CSR_RSN_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrRSNOui[8], Oui ); +} +#endif + +static tANI_BOOLEAN csrIsAuthWpa( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[01], Oui ) ); +} + +#ifdef NOT_CURRENTLY_USED +static tANI_BOOLEAN csrIsAuth802_1x( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[00], Oui ) ); +} +#endif // NOT_CURRENTLY_USED + +static tANI_BOOLEAN csrIsAuthWpaPsk( tpAniSirGlobal pMac, tANI_U8 AllSuites[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllSuites, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllSuites, cAllSuites, csrWpaOui[02], Oui ) ); +} +#if 0 +static tANI_BOOLEAN csrIsUnicastNone( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui00, Oui ) ); +} + +static tANI_BOOLEAN csrIsUnicastTkip( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui02, Oui ) ); +} + +static tANI_BOOLEAN csrIsUnicastAes( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui04, Oui ) ); +} + + +static tANI_BOOLEAN csrIsMulticastWep( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + tANI_BOOLEAN fYes = FALSE; + + // Check Wep 104 first, if fails, then check Wep40. + fYes = csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui05, Oui ); + + if ( !fYes ) + { + // if not Wep-104, check Wep-40 + fYes = csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui01, Oui ); + } + + return( fYes ); +} + + +static tANI_BOOLEAN csrIsMulticastTkip( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui02, Oui ) ); +} + + +static tANI_BOOLEAN csrIsMulticastAes( tpAniSirGlobal pMac, tANI_U8 AllCyphers[][CSR_WPA_OUI_SIZE], + tANI_U8 cAllCyphers, + tANI_U8 Oui[] ) +{ + return( csrIsOuiMatch( pMac, AllCyphers, cAllCyphers, csrWpaOui04, Oui ) ); +} + +#endif + +tANI_U8 csrGetOUIIndexFromCipher( eCsrEncryptionType enType ) +{ + tANI_U8 OUIIndex; + + switch ( enType ) + { + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + OUIIndex = CSR_OUI_WEP104_INDEX; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX; + break; + case eCSR_ENCRYPT_TYPE_AES: + OUIIndex = CSR_OUI_AES_INDEX; + break; + case eCSR_ENCRYPT_TYPE_NONE: + OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX; + break; +#endif /* FEATURE_WLAN_WAPI */ + default: //HOWTO handle this? + OUIIndex = CSR_OUI_RESERVED_INDEX; + break; + }//switch + + return OUIIndex; +} + +tANI_BOOLEAN csrGetRSNInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption, + tDot11fIERSN *pRSNIe, + tANI_U8 *UnicastCypher, + tANI_U8 *MulticastCypher, + tANI_U8 *AuthSuite, + tCsrRSNCapabilities *Capabilities, + eCsrAuthType *pNegotiatedAuthtype, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fAcceptableCyphers = FALSE; + tANI_U8 cUnicastCyphers = 0; + tANI_U8 cMulticastCyphers = 0; + tANI_U8 cAuthSuites = 0, i; + tANI_U8 Unicast[ CSR_RSN_OUI_SIZE ]; + tANI_U8 Multicast[ CSR_RSN_OUI_SIZE ]; + tANI_U8 AuthSuites[ CSR_RSN_MAX_AUTH_SUITES ][ CSR_RSN_OUI_SIZE ]; + tANI_U8 Authentication[ CSR_RSN_OUI_SIZE ]; + tANI_U8 MulticastCyphers[ CSR_RSN_MAX_MULTICAST_CYPHERS ][ CSR_RSN_OUI_SIZE ]; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + do{ + if ( pRSNIe->present ) + { + cMulticastCyphers++; + vos_mem_copy(MulticastCyphers, pRSNIe->gp_cipher_suite, CSR_RSN_OUI_SIZE); + cUnicastCyphers = (tANI_U8)(pRSNIe->pwise_cipher_suite_count); + cAuthSuites = (tANI_U8)(pRSNIe->akm_suite_count); + for(i = 0; i < cAuthSuites && i < CSR_RSN_MAX_AUTH_SUITES; i++) + { + vos_mem_copy((void *)&AuthSuites[i], + (void *)&pRSNIe->akm_suites[i], + CSR_RSN_OUI_SIZE); + } + + //Check - Is requested Unicast Cipher supported by the BSS. + fAcceptableCyphers = csrMatchRSNOUIIndex( pMac, pRSNIe->pwise_cipher_suites, cUnicastCyphers, + csrGetOUIIndexFromCipher( enType ), Unicast ); + + if( !fAcceptableCyphers ) break; + + + //Unicast is supported. Pick the first matching Group cipher, if any. + for( i = 0 ; i < pMCEncryption->numEntries ; i++ ) + { + fAcceptableCyphers = csrMatchRSNOUIIndex( pMac, MulticastCyphers, cMulticastCyphers, + csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i] ), Multicast ); + if(fAcceptableCyphers) + { + break; + } + } + if( !fAcceptableCyphers ) break; + + if( pNegotiatedMCCipher ) + *pNegotiatedMCCipher = pMCEncryption->encryptionType[i]; + + /* Initializing with FALSE as it has TRUE value already */ + fAcceptableCyphers = FALSE; + for (i = 0 ; i < pAuthType->numEntries; i++) + { + //Ciphers are supported, Match authentication algorithm and pick first matching authtype. + #ifdef WLAN_FEATURE_VOWIFI_11R + /* Changed the AKM suites according to order of preference */ + if ( csrIsFTAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_FT_RSN == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_FT_RSN; + } + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsFTAuthRSNPsk( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_FT_RSN_PSK == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_FT_RSN_PSK; + } +#endif +#ifdef FEATURE_WLAN_ESE + /* ESE only supports 802.1X. No PSK. */ + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsEseCckmAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_CCKM_RSN == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_CCKM_RSN; + } +#endif + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSN( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_RSN == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN; + } + if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPsk( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_RSN_PSK == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN_PSK; + } +#ifdef WLAN_FEATURE_11W + if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthRSNPskSha256( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN_PSK_SHA256; + } + if ((negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && + csrIsAuthRSN8021xSha256(pMac, AuthSuites, + cAuthSuites, Authentication)) { + if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 == + pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_RSN_8021X_SHA256; + } +#endif + + // The 1st auth type in the APs RSN IE, to match stations connecting + // profiles auth type will cause us to exit this loop + // This is added as some APs advertise multiple akms in the RSN IE. + if (eCSR_AUTH_TYPE_UNKNOWN != negAuthType) + { + fAcceptableCyphers = TRUE; + break; + } + } // for + } + + }while (0); + + if ( fAcceptableCyphers ) + { + if ( MulticastCypher ) + { + vos_mem_copy(MulticastCypher, Multicast, CSR_RSN_OUI_SIZE); + } + + if ( UnicastCypher ) + { + vos_mem_copy(UnicastCypher, Unicast, CSR_RSN_OUI_SIZE); + } + + if ( AuthSuite ) + { + vos_mem_copy(AuthSuite, Authentication, CSR_RSN_OUI_SIZE); + } + + if ( pNegotiatedAuthtype ) + { + *pNegotiatedAuthtype = negAuthType; + } + if ( Capabilities ) + { + Capabilities->PreAuthSupported = (pRSNIe->RSN_Cap[0] >> 0) & 0x1 ; // Bit 0 PreAuthentication + Capabilities->NoPairwise = (pRSNIe->RSN_Cap[0] >> 1) & 0x1 ; // Bit 1 No Pairwise + Capabilities->PTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 2) & 0x3 ; // Bit 2, 3 PTKSA Replay Counter + Capabilities->GTKSAReplayCounter = (pRSNIe->RSN_Cap[0] >> 4) & 0x3 ; // Bit 4, 5 GTKSA Replay Counter +#ifdef WLAN_FEATURE_11W + Capabilities->MFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1 ; // Bit 6 MFPR + Capabilities->MFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1 ; // Bit 7 MFPC +#else + Capabilities->MFPRequired = 0 ; // Bit 6 MFPR + Capabilities->MFPCapable = 0 ; // Bit 7 MFPC +#endif + + Capabilities->Reserved = pRSNIe->RSN_Cap[1] & 0xff ; // remaining reserved + } + } + return( fAcceptableCyphers ); +} + +#ifdef WLAN_FEATURE_11W +/* --------------------------------------------------------------------------- + \fn csrIsPMFCapabilitiesInRSNMatch + + \brief this function is to match our current capabilities with the AP + to which we are expecting make the connection. + + \param hHal - HAL Pointer + pFilterMFPEnabled - given by supplicant to us to specify what kind + of connection supplicant is expecting to make + if it is enabled then make PMF connection. + if it is disabled then make normal connection. + pFilterMFPRequired - given by supplicant based on our configuration + if it is 1 then we will require mandatory + PMF connection and if it is 0 then we PMF + connection is optional. + pFilterMFPCapable - given by supplicant based on our configuration + if it 1 then we are PMF capable and if it 0 + then we are not PMF capable. + pRSNIe - RSNIe from Beacon/probe response of + neighbor AP against which we will compare + our capabilities. + + \return tANI_BOOLEAN - if our PMF capabilities matches with AP then we + will return true to indicate that we are good + to make connection with it. Else we will return + false. + -------------------------------------------------------------------------------*/ +static tANI_BOOLEAN +csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal, + tANI_BOOLEAN *pFilterMFPEnabled, + tANI_U8 *pFilterMFPRequired, + tANI_U8 *pFilterMFPCapable, + tDot11fIERSN *pRSNIe) +{ + tANI_U8 apProfileMFPCapable = 0; + tANI_U8 apProfileMFPRequired = 0; + if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable && pFilterMFPRequired) + { + /* Extracting MFPCapable bit from RSN Ie */ + apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1; + apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1; + if (*pFilterMFPEnabled && *pFilterMFPCapable && *pFilterMFPRequired + && (apProfileMFPCapable == 0)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "AP is not capable to make PMF connection"); + return VOS_FALSE; + } + else if (*pFilterMFPEnabled && *pFilterMFPCapable && + !(*pFilterMFPRequired) && (apProfileMFPCapable == 0)) + { + /* + * This is tricky, because supplicant asked us to make mandatory + * PMF connection eventhough PMF connection is optional here. + * so if AP is not capable of PMF then drop it. Don't try to + * connect with it. + */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "we need PMF connection & AP isn't capable to make PMF connection"); + return VOS_FALSE; + } + else if (!(*pFilterMFPCapable) && + apProfileMFPCapable && apProfileMFPRequired) + { + /* + * In this case, AP with whom we trying to connect requires + * mandatory PMF connections and we are not capable so this AP + * is not good choice to connect + */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "AP needs PMF connection and we are not capable of pmf connection"); + return VOS_FALSE; + } + else if (!(*pFilterMFPEnabled) && *pFilterMFPCapable && + (apProfileMFPCapable == 1)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "we don't need PMF connection eventhough both parties are capable"); + return VOS_FALSE; + } + } + return VOS_TRUE; +} +#endif + +tANI_BOOLEAN csrIsRSNMatch( tHalHandle hHal, tCsrAuthList *pAuthType, + eCsrEncryptionType enType, + tCsrEncryptionList *pEnMcType, + tANI_BOOLEAN *pMFPEnabled, tANI_U8 *pMFPRequired, + tANI_U8 *pMFPCapable, + tDot11fBeaconIEs *pIes, + eCsrAuthType *pNegotiatedAuthType, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fRSNMatch = FALSE; + + // See if the cyphers in the Bss description match with the settings in the profile. + fRSNMatch = csrGetRSNInformation( hHal, pAuthType, enType, pEnMcType, &pIes->RSN, NULL, NULL, NULL, NULL, + pNegotiatedAuthType, pNegotiatedMCCipher ); +#ifdef WLAN_FEATURE_11W + /* If all the filter matches then finally checks for PMF capabilities */ + if (fRSNMatch) + { + fRSNMatch = csrIsPMFCapabilitiesInRSNMatch( hHal, pMFPEnabled, + pMFPRequired, pMFPCapable, + &pIes->RSN); + } +#endif + + return( fRSNMatch ); +} + + +tANI_BOOLEAN csrLookupPMKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 *pBSSId, tANI_U8 *pPMKId ) +{ + tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE; + tANI_U32 Index; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return FALSE; + } + /* to force the AP initiate fresh 802.1x authentication after re-association should not + * fill the PMKID from cache this is needed + * by the HS 2.0 passpoint certification 5.2.a and b testcases */ + + if(pSession->fIgnorePMKIDCache) + { + pSession->fIgnorePMKIDCache = FALSE; + return fRC; + } + + do + { + for( Index=0; Index < CSR_MAX_PMKID_ALLOWED; Index++ ) + { + if( vos_mem_compare(pBSSId, pSession->PmkidCacheInfo[Index].BSSID, sizeof(tCsrBssid)) ) + { + // match found + fMatchFound = TRUE; + break; + } + } + + if( !fMatchFound ) break; + + vos_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID, CSR_RSN_PMKID_SIZE); + + fRC = TRUE; + } + while( 0 ); + smsLog(pMac, LOG1, "csrLookupPMKID called return match = %d pMac->roam.NumPmkidCache = %d", + fRC, pSession->NumPmkidCache); + + return fRC; +} + + +tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRSNMatch; + tANI_U8 cbRSNIe = 0; + tANI_U8 UnicastCypher[ CSR_RSN_OUI_SIZE ]; + tANI_U8 MulticastCypher[ CSR_RSN_OUI_SIZE ]; + tANI_U8 AuthSuite[ CSR_RSN_OUI_SIZE ]; + tCsrRSNAuthIe *pAuthSuite; + tCsrRSNCapabilities RSNCapabilities; + tCsrRSNPMKIe *pPMK; + tANI_U8 PMKId[CSR_RSN_PMKID_SIZE]; +#ifdef WLAN_FEATURE_11W + tANI_U8 *pGroupMgmtCipherSuite; +#endif + tDot11fBeaconIEs *pIesLocal = pIes; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + smsLog(pMac, LOGW, "%s called...", __func__); + + do + { + if ( !csrIsProfileRSN( pProfile ) ) break; + + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + break; + } + + // See if the cyphers in the Bss description match with the settings in the profile. + fRSNMatch = csrGetRSNInformation( hHal, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, + &pProfile->mcEncryptionType, &pIesLocal->RSN, + UnicastCypher, MulticastCypher, AuthSuite, &RSNCapabilities, &negAuthType, NULL ); + if ( !fRSNMatch ) break; + + pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID; + + pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED; + + vos_mem_copy(pRSNIe->MulticastOui, MulticastCypher, sizeof( MulticastCypher )); + + pRSNIe->cUnicastCyphers = 1; + + vos_mem_copy(&pRSNIe->UnicastOui[ 0 ], UnicastCypher, sizeof( UnicastCypher )); + + pAuthSuite = (tCsrRSNAuthIe *)( &pRSNIe->UnicastOui[ pRSNIe->cUnicastCyphers ] ); + + pAuthSuite->cAuthenticationSuites = 1; + vos_mem_copy(&pAuthSuite->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite )); + + // RSN capabilities follows the Auth Suite (two octects) + // !!REVIEW - What should STA put in RSN capabilities, currently + // just putting back APs capabilities + // For one, we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability + // For another, we should use the Management Frame Protection values given by the supplicant + RSNCapabilities.PreAuthSupported = 0; +#ifdef WLAN_FEATURE_11W + RSNCapabilities.MFPRequired = pProfile->MFPRequired; + RSNCapabilities.MFPCapable = pProfile->MFPCapable; +#endif + *(tANI_U16 *)( &pAuthSuite->AuthOui[ 1 ] ) = *((tANI_U16 *)(&RSNCapabilities)); + + pPMK = (tCsrRSNPMKIe *)( ((tANI_U8 *)(&pAuthSuite->AuthOui[ 1 ])) + sizeof(tANI_U16) ); + + if ( +#ifdef FEATURE_WLAN_ESE + (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) && +#endif + csrLookupPMKID( pMac, sessionId, pSirBssDesc->bssId, &(PMKId[0]) ) ) + { + pPMK->cPMKIDs = 1; + + vos_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId, CSR_RSN_PMKID_SIZE); + } + else + { + pPMK->cPMKIDs = 0; + } + +#ifdef WLAN_FEATURE_11W + if ( pProfile->MFPEnabled ) + { + pGroupMgmtCipherSuite = (tANI_U8 *) pPMK + sizeof ( tANI_U16 ) + + ( pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE ); + vos_mem_copy(pGroupMgmtCipherSuite, csrRSNOui[07], CSR_WPA_OUI_SIZE); + } +#endif + + // Add in the fixed fields plus 1 Unicast cypher, less the IE Header length + // Add in the size of the Auth suite (count plus a single OUI) + // Add in the RSN caps field. + // Add PMKID count and PMKID (if any) + // Add group management cipher suite + pRSNIe->IeHeader.Length = (tANI_U8) (sizeof( *pRSNIe ) - sizeof ( pRSNIe->IeHeader ) + + sizeof( *pAuthSuite ) + + sizeof( tCsrRSNCapabilities )); + if(pPMK->cPMKIDs) + { + pRSNIe->IeHeader.Length += (tANI_U8)(sizeof( tANI_U16 ) + + (pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE)); + } +#ifdef WLAN_FEATURE_11W + if ( pProfile->MFPEnabled ) + { + if ( 0 == pPMK->cPMKIDs ) + pRSNIe->IeHeader.Length += sizeof( tANI_U16 ); + pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE; + } +#endif + + // return the size of the IE header (total) constructed... + cbRSNIe = pRSNIe->IeHeader.Length + sizeof( pRSNIe->IeHeader ); + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( cbRSNIe ); +} + + +#ifdef FEATURE_WLAN_WAPI +tANI_BOOLEAN csrGetWapiInformation( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption, + tDot11fIEWAPI *pWapiIe, + tANI_U8 *UnicastCypher, + tANI_U8 *MulticastCypher, + tANI_U8 *AuthSuite, + eCsrAuthType *pNegotiatedAuthtype, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fAcceptableCyphers = FALSE; + tANI_U8 cUnicastCyphers = 0; + tANI_U8 cMulticastCyphers = 0; + tANI_U8 cAuthSuites = 0, i; + tANI_U8 Unicast[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 Multicast[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 AuthSuites[ CSR_WAPI_MAX_AUTH_SUITES ][ CSR_WAPI_OUI_SIZE ]; + tANI_U8 Authentication[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 MulticastCyphers[ CSR_WAPI_MAX_MULTICAST_CYPHERS ][ CSR_WAPI_OUI_SIZE ]; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + do{ + if ( pWapiIe->present ) + { + cMulticastCyphers++; + vos_mem_copy(MulticastCyphers, pWapiIe->multicast_cipher_suite, + CSR_WAPI_OUI_SIZE); + cUnicastCyphers = (tANI_U8)(pWapiIe->unicast_cipher_suite_count); + cAuthSuites = (tANI_U8)(pWapiIe->akm_suite_count); + for(i = 0; i < cAuthSuites && i < CSR_WAPI_MAX_AUTH_SUITES; i++) + { + vos_mem_copy((void *)&AuthSuites[i], (void *)&pWapiIe->akm_suites[i], + CSR_WAPI_OUI_SIZE); + } + + //Check - Is requested Unicast Cipher supported by the BSS. + fAcceptableCyphers = csrMatchWapiOUIIndex( pMac, pWapiIe->unicast_cipher_suites, cUnicastCyphers, + csrGetOUIIndexFromCipher( enType ), Unicast ); + + if( !fAcceptableCyphers ) break; + + + //Unicast is supported. Pick the first matching Group cipher, if any. + for( i = 0 ; i < pMCEncryption->numEntries ; i++ ) + { + fAcceptableCyphers = csrMatchWapiOUIIndex( pMac, MulticastCyphers, cMulticastCyphers, + csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i] ), Multicast ); + if(fAcceptableCyphers) + { + break; + } + } + if( !fAcceptableCyphers ) break; + + if( pNegotiatedMCCipher ) + *pNegotiatedMCCipher = pMCEncryption->encryptionType[i]; + + //Ciphers are supported, Match authentication algorithm and pick first matching authtype. + if ( csrIsAuthWapiCert( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + negAuthType = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + } + else if ( csrIsAuthWapiPsk( pMac, AuthSuites, cAuthSuites, Authentication ) ) + { + negAuthType = eCSR_AUTH_TYPE_WAPI_WAI_PSK; + } + else + { + fAcceptableCyphers = FALSE; + negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + } + if( ( 0 == pAuthType->numEntries ) || ( FALSE == fAcceptableCyphers ) ) + { + //Caller doesn't care about auth type, or BSS doesn't match + break; + } + fAcceptableCyphers = FALSE; + for( i = 0 ; i < pAuthType->numEntries; i++ ) + { + if( pAuthType->authType[i] == negAuthType ) + { + fAcceptableCyphers = TRUE; + break; + } + } + } + }while (0); + + if ( fAcceptableCyphers ) + { + if ( MulticastCypher ) + { + vos_mem_copy(MulticastCypher, Multicast, CSR_WAPI_OUI_SIZE); + } + + if ( UnicastCypher ) + { + vos_mem_copy(UnicastCypher, Unicast, CSR_WAPI_OUI_SIZE); + } + + if ( AuthSuite ) + { + vos_mem_copy(AuthSuite, Authentication, CSR_WAPI_OUI_SIZE); + } + + if ( pNegotiatedAuthtype ) + { + *pNegotiatedAuthtype = negAuthType; + } + } + return( fAcceptableCyphers ); +} + +tANI_BOOLEAN csrIsWapiMatch( tHalHandle hHal, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType, + tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fWapiMatch = FALSE; + + // See if the cyphers in the Bss description match with the settings in the profile. + fWapiMatch = csrGetWapiInformation( hHal, pAuthType, enType, pEnMcType, &pIes->WAPI, NULL, NULL, NULL, + pNegotiatedAuthType, pNegotiatedMCCipher ); + + return( fWapiMatch ); +} + +tANI_BOOLEAN csrLookupBKID( tpAniSirGlobal pMac, tANI_U32 sessionId, tANI_U8 *pBSSId, tANI_U8 *pBKId ) +{ + tANI_BOOLEAN fRC = FALSE, fMatchFound = FALSE; + tANI_U32 Index; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + return FALSE; + } + + do + { + for( Index=0; Index < pSession->NumBkidCache; Index++ ) + { + smsLog(pMac, LOGW, "match BKID "MAC_ADDRESS_STR" to ", + MAC_ADDR_ARRAY(pBSSId)); + if (vos_mem_compare(pBSSId, pSession->BkidCacheInfo[Index].BSSID, sizeof(tCsrBssid) ) ) + { + // match found + fMatchFound = TRUE; + break; + } + } + + if( !fMatchFound ) break; + + vos_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID, CSR_WAPI_BKID_SIZE); + + fRC = TRUE; + } + while( 0 ); + smsLog(pMac, LOGW, "csrLookupBKID called return match = %d pMac->roam.NumBkidCache = %d", fRC, pSession->NumBkidCache); + + return fRC; +} + +tANI_U8 csrConstructWapiIe( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ) +{ + tANI_BOOLEAN fWapiMatch = FALSE; + tANI_U8 cbWapiIe = 0; + tANI_U8 UnicastCypher[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 MulticastCypher[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 AuthSuite[ CSR_WAPI_OUI_SIZE ]; + tANI_U8 BKId[CSR_WAPI_BKID_SIZE]; + tANI_U8 *pWapi = NULL; + tANI_BOOLEAN fBKIDFound = FALSE; + tDot11fBeaconIEs *pIesLocal = pIes; + + do + { + if ( !csrIsProfileWapi( pProfile ) ) break; + + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + break; + } + + // See if the cyphers in the Bss description match with the settings in the profile. + fWapiMatch = csrGetWapiInformation( pMac, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, + &pProfile->mcEncryptionType, &pIesLocal->WAPI, + UnicastCypher, MulticastCypher, AuthSuite, NULL, NULL ); + if ( !fWapiMatch ) break; + + vos_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0); + + pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI; + + pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED; + + pWapiIe->cAuthenticationSuites = 1; + vos_mem_copy(&pWapiIe->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite )); + + pWapi = (tANI_U8 *) (&pWapiIe->AuthOui[ 1 ]); + + *pWapi = (tANI_U16)1; //cUnicastCyphers + pWapi+=2; + vos_mem_copy(pWapi, UnicastCypher, sizeof( UnicastCypher )); + pWapi += sizeof( UnicastCypher ); + + vos_mem_copy(pWapi, MulticastCypher, sizeof( MulticastCypher )); + pWapi += sizeof( MulticastCypher ); + + + // WAPI capabilities follows the Auth Suite (two octects) + // we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability + // & since we already did a memset pWapiIe to 0, skip these fields + pWapi +=2; + + fBKIDFound = csrLookupBKID( pMac, sessionId, pSirBssDesc->bssId, &(BKId[0]) ); + + + if( fBKIDFound ) + { + /* Do we need to change the endianness here */ + *pWapi = (tANI_U16)1; //cBKIDs + pWapi+=2; + vos_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE); + } + else + { + *pWapi = 0; + pWapi+=1; + *pWapi = 0; + pWapi+=1; + } + + // Add in the IE fields except the IE header + // Add BKID count and BKID (if any) + pWapiIe->IeHeader.Length = (tANI_U8) (sizeof( *pWapiIe ) - sizeof ( pWapiIe->IeHeader )); + + /*2 bytes for BKID Count field*/ + pWapiIe->IeHeader.Length += sizeof( tANI_U16 ); + + if(fBKIDFound) + { + pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE; + } + // return the size of the IE header (total) constructed... + cbWapiIe = pWapiIe->IeHeader.Length + sizeof( pWapiIe->IeHeader ); + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( cbWapiIe ); +} +#endif /* FEATURE_WLAN_WAPI */ + +tANI_BOOLEAN csrGetWpaCyphers( tpAniSirGlobal pMac, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pMCEncryption, + tDot11fIEWPA *pWpaIe, + tANI_U8 *UnicastCypher, + tANI_U8 *MulticastCypher, + tANI_U8 *AuthSuite, + eCsrAuthType *pNegotiatedAuthtype, + eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fAcceptableCyphers = FALSE; + tANI_U8 cUnicastCyphers = 0; + tANI_U8 cMulticastCyphers = 0; + tANI_U8 cAuthSuites = 0; + tANI_U8 Unicast[ CSR_WPA_OUI_SIZE ]; + tANI_U8 Multicast[ CSR_WPA_OUI_SIZE ]; + tANI_U8 Authentication[ CSR_WPA_OUI_SIZE ]; + tANI_U8 MulticastCyphers[ 1 ][ CSR_WPA_OUI_SIZE ]; + tANI_U8 i; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + do + { + if ( pWpaIe->present ) + { + cMulticastCyphers = 1; + vos_mem_copy(MulticastCyphers, pWpaIe->multicast_cipher, CSR_WPA_OUI_SIZE); + cUnicastCyphers = (tANI_U8)(pWpaIe->unicast_cipher_count); + cAuthSuites = (tANI_U8)(pWpaIe->auth_suite_count); + + //Check - Is requested Unicast Cipher supported by the BSS. + fAcceptableCyphers = csrMatchWPAOUIIndex( pMac, pWpaIe->unicast_ciphers, cUnicastCyphers, + csrGetOUIIndexFromCipher( enType ), Unicast ); + + if( !fAcceptableCyphers ) break; + + + //Unicast is supported. Pick the first matching Group cipher, if any. + for( i = 0 ; i < pMCEncryption->numEntries ; i++ ) + { + fAcceptableCyphers = csrMatchWPAOUIIndex( pMac, MulticastCyphers, cMulticastCyphers, + csrGetOUIIndexFromCipher( pMCEncryption->encryptionType[i]), Multicast ); + if(fAcceptableCyphers) + { + break; + } + } + if( !fAcceptableCyphers ) break; + + if( pNegotiatedMCCipher ) + *pNegotiatedMCCipher = pMCEncryption->encryptionType[i]; + + /* Initializing with FALSE as it has TRUE value already */ + fAcceptableCyphers = FALSE; + for (i = 0 ; i < pAuthType->numEntries; i++) + { + //Ciphers are supported, Match authentication algorithm and pick first matching authtype. + if ( csrIsAuthWpa( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_WPA == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_WPA; + } + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsAuthWpaPsk( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_WPA_PSK == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_WPA_PSK; + } +#ifdef FEATURE_WLAN_ESE + if ( (negAuthType == eCSR_AUTH_TYPE_UNKNOWN) && csrIsEseCckmAuthWpa( pMac, pWpaIe->auth_suites, cAuthSuites, Authentication ) ) + { + if (eCSR_AUTH_TYPE_CCKM_WPA == pAuthType->authType[i]) + negAuthType = eCSR_AUTH_TYPE_CCKM_WPA; + } +#endif /* FEATURE_WLAN_ESE */ + + // The 1st auth type in the APs WPA IE, to match stations connecting + // profiles auth type will cause us to exit this loop + // This is added as some APs advertise multiple akms in the WPA IE. + if (eCSR_AUTH_TYPE_UNKNOWN != negAuthType) + { + fAcceptableCyphers = TRUE; + break; + } + } // for + } + }while(0); + + if ( fAcceptableCyphers ) + { + if ( MulticastCypher ) + { + vos_mem_copy((tANI_U8 **)MulticastCypher, Multicast, CSR_WPA_OUI_SIZE); + } + + if ( UnicastCypher ) + { + vos_mem_copy((tANI_U8 **)UnicastCypher, Unicast, CSR_WPA_OUI_SIZE); + } + + if ( AuthSuite ) + { + vos_mem_copy((tANI_U8 **)AuthSuite, Authentication, CSR_WPA_OUI_SIZE); + } + + if( pNegotiatedAuthtype ) + { + *pNegotiatedAuthtype = negAuthType; + } + } + + return( fAcceptableCyphers ); +} + + + +tANI_BOOLEAN csrIsWpaEncryptionMatch( tpAniSirGlobal pMac, tCsrAuthList *pAuthType, eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType, + tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthtype, eCsrEncryptionType *pNegotiatedMCCipher ) +{ + tANI_BOOLEAN fWpaMatch = eANI_BOOLEAN_FALSE; + + // See if the cyphers in the Bss description match with the settings in the profile. + fWpaMatch = csrGetWpaCyphers( pMac, pAuthType, enType, pEnMcType, &pIes->WPA, NULL, NULL, NULL, pNegotiatedAuthtype, pNegotiatedMCCipher ); + + return( fWpaMatch ); +} + + +tANI_U8 csrConstructWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fWpaMatch; + tANI_U8 cbWpaIe = 0; + tANI_U8 UnicastCypher[ CSR_WPA_OUI_SIZE ]; + tANI_U8 MulticastCypher[ CSR_WPA_OUI_SIZE ]; + tANI_U8 AuthSuite[ CSR_WPA_OUI_SIZE ]; + tCsrWpaAuthIe *pAuthSuite; + tDot11fBeaconIEs *pIesLocal = pIes; + + do + { + if ( !csrIsProfileWpa( pProfile ) ) break; + + if( !pIesLocal && (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pSirBssDesc, &pIesLocal))) ) + { + break; + } + // See if the cyphers in the Bss description match with the settings in the profile. + fWpaMatch = csrGetWpaCyphers( hHal, &pProfile->AuthType, pProfile->negotiatedUCEncryptionType, &pProfile->mcEncryptionType, + &pIesLocal->WPA, UnicastCypher, MulticastCypher, AuthSuite, NULL, NULL ); + if ( !fWpaMatch ) break; + + pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID; + + vos_mem_copy(pWpaIe->Oui, csrWpaOui[01], sizeof( pWpaIe->Oui )); + + pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED; + + vos_mem_copy(pWpaIe->MulticastOui, MulticastCypher, sizeof( MulticastCypher )); + + pWpaIe->cUnicastCyphers = 1; + + vos_mem_copy(&pWpaIe->UnicastOui[ 0 ], UnicastCypher, sizeof( UnicastCypher )); + + pAuthSuite = (tCsrWpaAuthIe *)( &pWpaIe->UnicastOui[ pWpaIe->cUnicastCyphers ] ); + + pAuthSuite->cAuthenticationSuites = 1; + vos_mem_copy(&pAuthSuite->AuthOui[ 0 ], AuthSuite, sizeof( AuthSuite )); + + // The WPA capabilities follows the Auth Suite (two octects)-- + // this field is optional, and we always "send" zero, so just + // remove it. This is consistent with our assumptions in the + // frames compiler; c.f. bug 15234: + // http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 + + // Add in the fixed fields plus 1 Unicast cypher, less the IE Header length + // Add in the size of the Auth suite (count plus a single OUI) + pWpaIe->IeHeader.Length = sizeof( *pWpaIe ) - sizeof ( pWpaIe->IeHeader ) + + sizeof( *pAuthSuite ); + + // return the size of the IE header (total) constructed... + cbWpaIe = pWpaIe->IeHeader.Length + sizeof( pWpaIe->IeHeader ); + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( cbWpaIe ); +} + + +tANI_BOOLEAN csrGetWpaRsnIe( tHalHandle hHal, tANI_U8 *pIes, tANI_U32 len, + tANI_U8 *pWpaIe, tANI_U8 *pcbWpaIe, tANI_U8 *pRSNIe, tANI_U8 *pcbRSNIe) +{ + tDot11IEHeader *pIEHeader; + tSirMacPropIE *pSirMacPropIE; + tANI_U32 cbParsed; + tANI_U32 cbIE; + int cExpectedIEs = 0; + int cFoundIEs = 0; + int cbPropIETotal; + + pIEHeader = (tDot11IEHeader *)pIes; + if(pWpaIe) cExpectedIEs++; + if(pRSNIe) cExpectedIEs++; + + // bss description length includes all fields other than the length itself + cbParsed = 0; + + // Loop as long as there is data left in the IE of the Bss Description + // and the number of Expected IEs is NOT found yet. + while( ( (cbParsed + sizeof( *pIEHeader )) <= len ) && ( cFoundIEs < cExpectedIEs ) ) + { + cbIE = sizeof( *pIEHeader ) + pIEHeader->Length; + + if ( ( cbIE + cbParsed ) > len ) break; + + if ( ( pIEHeader->Length >= gCsrIELengthTable[ pIEHeader->ElementID ].min ) && + ( pIEHeader->Length <= gCsrIELengthTable[ pIEHeader->ElementID ].max ) ) + { + switch( pIEHeader->ElementID ) + { + // Parse the 221 (0xdd) Proprietary IEs here... + // Note that the 221 IE is overloaded, containing the WPA IE, WMM/WME IE, and the + // Airgo proprietary IE information. + case SIR_MAC_WPA_EID: + { + tANI_U32 aniOUI; + tANI_U8 *pOui = (tANI_U8 *)&aniOUI; + + pOui++; + aniOUI = ANI_OUI; + aniOUI = i_ntohl( aniOUI ); + + pSirMacPropIE = ( tSirMacPropIE *)pIEHeader; + cbPropIETotal = pSirMacPropIE->length; + + // Validate the ANI OUI is in the OUI field in the proprietary IE... + if ( ( pSirMacPropIE->length >= WNI_CFG_MANUFACTURER_OUI_LEN ) && + pOui[ 0 ] == pSirMacPropIE->oui[ 0 ] && + pOui[ 1 ] == pSirMacPropIE->oui[ 1 ] && + pOui[ 2 ] == pSirMacPropIE->oui[ 2 ] ) + { + } + else + { + tCsrWpaIe *pIe = ( tCsrWpaIe * )pIEHeader; + + if(!pWpaIe || !pcbWpaIe) break; + // Check if this is a valid WPA IE. Then check that the + // WPA OUI is in place and the version is one that we support. + if ( ( pIe->IeHeader.Length >= SIR_MAC_WPA_IE_MIN_LENGTH ) && + ( vos_mem_compare( pIe->Oui, (void *)csrWpaOui[1], + sizeof( pIe->Oui ) ) ) && + ( pIe->Version <= CSR_WPA_VERSION_SUPPORTED ) ) + { + vos_mem_copy(pWpaIe, pIe, + pIe->IeHeader.Length + sizeof( pIe->IeHeader )); + *pcbWpaIe = pIe->IeHeader.Length + sizeof( pIe->IeHeader ); + cFoundIEs++; + + break; + } + } + + break; + } + + case SIR_MAC_RSN_EID: + { + tCsrRSNIe *pIe; + + if(!pcbRSNIe || !pRSNIe) break; + pIe = (tCsrRSNIe *)pIEHeader; + + // Check the length of the RSN Ie to assure it is valid. Then check that the + // version is one that we support. + + if ( pIe->IeHeader.Length < SIR_MAC_RSN_IE_MIN_LENGTH ) break; + if ( pIe->Version > CSR_RSN_VERSION_SUPPORTED ) break; + + cFoundIEs++; + + // if there is enough room in the WpaIE passed in, then copy the Wpa IE into + // the buffer passed in. + if ( *pcbRSNIe < pIe->IeHeader.Length + sizeof( pIe->IeHeader ) ) break; + vos_mem_copy(pRSNIe, pIe, + pIe->IeHeader.Length + sizeof( pIe->IeHeader )); + *pcbRSNIe = pIe->IeHeader.Length + sizeof( pIe->IeHeader ); + + break; + } + + // Add support for other IE here... + default: + break; + } + } + + cbParsed += cbIE; + + pIEHeader = (tDot11IEHeader *)( ((tANI_U8 *)pIEHeader) + cbIE ); + + } + + // return a BOOL that tells if all of the IEs asked for were found... + return( cFoundIEs == cExpectedIEs ); +} + + +//If a WPAIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveWpaIe( tHalHandle hHal, tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 cbWpaIe = 0; + + do + { + if ( !csrIsProfileWpa( pProfile ) ) break; + if(pProfile->nWPAReqIELength && pProfile->pWPAReqIE) + { + if(SIR_MAC_WPA_IE_MAX_LENGTH >= pProfile->nWPAReqIELength) + { + cbWpaIe = (tANI_U8)pProfile->nWPAReqIELength; + vos_mem_copy(pWpaIe, pProfile->pWPAReqIE, cbWpaIe); + } + else + { + smsLog(pMac, LOGW, " csrRetrieveWpaIe detect invalid WPA IE length (%d) ", pProfile->nWPAReqIELength); + } + } + else + { + cbWpaIe = csrConstructWpaIe(pMac, pProfile, pSirBssDesc, pIes, pWpaIe); + } + }while(0); + + return (cbWpaIe); +} + + +//If a RSNIE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE +tANI_U8 csrRetrieveRsnIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile *pProfile, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 cbRsnIe = 0; + + do + { + if ( !csrIsProfileRSN( pProfile ) ) break; +#ifdef FEATURE_WLAN_LFR + if (csrRoamIsFastRoamEnabled(pMac, sessionId)) + { + // If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from + // scratch. So it contains the current PMK-IDs + cbRsnIe = csrConstructRSNIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pRsnIe); + } + else +#endif + if(pProfile->nRSNReqIELength && pProfile->pRSNReqIE) + { + // If you have one started away, re-use it. + if(SIR_MAC_WPA_IE_MAX_LENGTH >= pProfile->nRSNReqIELength) + { + cbRsnIe = (tANI_U8)pProfile->nRSNReqIELength; + vos_mem_copy(pRsnIe, pProfile->pRSNReqIE, cbRsnIe); + } + else + { + smsLog(pMac, LOGW, " csrRetrieveRsnIe detect invalid RSN IE length (%d) ", pProfile->nRSNReqIELength); + } + } + else + { + cbRsnIe = csrConstructRSNIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pRsnIe); + } + }while(0); + + return (cbRsnIe); +} + + +#ifdef FEATURE_WLAN_WAPI +//If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS +//Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE +tANI_U8 csrRetrieveWapiIe( tHalHandle hHal, tANI_U32 sessionId, + tCsrRoamProfile *pProfile, tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 cbWapiIe = 0; + + do + { + if ( !csrIsProfileWapi( pProfile ) ) break; + if(pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) + { + if(DOT11F_IE_WAPI_MAX_LEN >= pProfile->nWAPIReqIELength) + { + cbWapiIe = (tANI_U8)pProfile->nWAPIReqIELength; + vos_mem_copy(pWapiIe, pProfile->pWAPIReqIE, cbWapiIe); + } + else + { + smsLog(pMac, LOGW, " csrRetrieveWapiIe detect invalid WAPI IE length (%d) ", pProfile->nWAPIReqIELength); + } + } + else + { + cbWapiIe = csrConstructWapiIe(pMac, sessionId, pProfile, pSirBssDesc, pIes, pWapiIe); + } + }while(0); + + return (cbWapiIe); +} +#endif /* FEATURE_WLAN_WAPI */ + +tANI_BOOLEAN csrSearchChannelListForTxPower(tHalHandle hHal, tSirBssDescription *pBssDescription, tCsrChannelSet *returnChannelGroup) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tListElem *pEntry; + tANI_U16 i; + tANI_U16 startingChannel; + tANI_BOOLEAN found = FALSE; + tCsrChannelSet *pChannelGroup; + + pEntry = csrLLPeekHead( &pMac->roam.channelList5G, LL_ACCESS_LOCK ); + + while ( pEntry ) + { + pChannelGroup = GET_BASE_ADDR( pEntry, tCsrChannelSet, channelListLink ); + startingChannel = pChannelGroup->firstChannel; + for ( i = 0; i < pChannelGroup->numChannels; i++ ) + { + if ( startingChannel + i * pChannelGroup->interChannelOffset == pBssDescription->channelId ) + { + found = TRUE; + break; + } + } + + if ( found ) + { + vos_mem_copy(returnChannelGroup, pChannelGroup, sizeof(tCsrChannelSet)); + break; + } + else + { + pEntry = csrLLNext( &pMac->roam.channelList5G, pEntry, LL_ACCESS_LOCK ); + } + } + + return( found ); +} + +tANI_BOOLEAN csrRatesIsDot11Rate11bSupportedRate( tANI_U8 dot11Rate ) +{ + tANI_BOOLEAN fSupported = FALSE; + tANI_U16 nonBasicRate = (tANI_U16)( BITS_OFF( dot11Rate, CSR_DOT11_BASIC_RATE_MASK ) ); + + switch ( nonBasicRate ) + { + case eCsrSuppRate_1Mbps: + case eCsrSuppRate_2Mbps: + case eCsrSuppRate_5_5Mbps: + case eCsrSuppRate_11Mbps: + fSupported = TRUE; + break; + + default: + break; + } + + return( fSupported ); +} + +tANI_BOOLEAN csrRatesIsDot11Rate11aSupportedRate( tANI_U8 dot11Rate ) +{ + tANI_BOOLEAN fSupported = FALSE; + tANI_U16 nonBasicRate = (tANI_U16)( BITS_OFF( dot11Rate, CSR_DOT11_BASIC_RATE_MASK ) ); + + switch ( nonBasicRate ) + { + case eCsrSuppRate_6Mbps: + case eCsrSuppRate_9Mbps: + case eCsrSuppRate_12Mbps: + case eCsrSuppRate_18Mbps: + case eCsrSuppRate_24Mbps: + case eCsrSuppRate_36Mbps: + case eCsrSuppRate_48Mbps: + case eCsrSuppRate_54Mbps: + fSupported = TRUE; + break; + + default: + break; + } + + return( fSupported ); +} + + + +tAniEdType csrTranslateEncryptTypeToEdType( eCsrEncryptionType EncryptType ) +{ + tAniEdType edType; + + switch ( EncryptType ) + { + default: + case eCSR_ENCRYPT_TYPE_NONE: + edType = eSIR_ED_NONE; + break; + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + edType = eSIR_ED_WEP40; + break; + + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104: + edType = eSIR_ED_WEP104; + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + edType = eSIR_ED_TKIP; + break; + + case eCSR_ENCRYPT_TYPE_AES: + edType = eSIR_ED_CCMP; + break; +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + edType = eSIR_ED_WPI; + break ; +#endif +#ifdef WLAN_FEATURE_11W + //11w BIP + case eCSR_ENCRYPT_TYPE_AES_CMAC: + edType = eSIR_ED_AES_128_CMAC; + break; +#endif + } + + return( edType ); +} + + +//pIes can be NULL +tANI_BOOLEAN csrValidateWep( tpAniSirGlobal pMac, eCsrEncryptionType ucEncryptionType, + tCsrAuthList *pAuthList, tCsrEncryptionList *pMCEncryptionList, + eCsrAuthType *pNegotiatedAuthType, eCsrEncryptionType *pNegotiatedMCEncryption, + tSirBssDescription *pSirBssDesc, tDot11fBeaconIEs *pIes ) +{ + tANI_U32 idx; + tANI_BOOLEAN fMatch = FALSE; + eCsrAuthType negotiatedAuth = eCSR_AUTH_TYPE_OPEN_SYSTEM; + eCsrEncryptionType negotiatedMCCipher = eCSR_ENCRYPT_TYPE_UNKNOWN; + + //This function just checks whether HDD is giving correct values for Multicast cipher and Auth. + + do + { + //If privacy bit is not set, consider no match + if ( !csrIsPrivacy( pSirBssDesc ) ) break; + + for( idx = 0; idx < pMCEncryptionList->numEntries; idx++ ) + { + switch( pMCEncryptionList->encryptionType[idx] ) + { + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + /* Multicast list may contain WEP40/WEP104. Check whether it matches UC. + */ + if( ucEncryptionType == pMCEncryptionList->encryptionType[idx] ) + { + fMatch = TRUE; + negotiatedMCCipher = pMCEncryptionList->encryptionType[idx]; + } + break; + default: + fMatch = FALSE; + break; + } + if(fMatch) break; + } + + if(!fMatch) break; + + for( idx = 0; idx < pAuthList->numEntries; idx++ ) + { + switch( pAuthList->authType[idx] ) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + case eCSR_AUTH_TYPE_SHARED_KEY: + case eCSR_AUTH_TYPE_AUTOSWITCH: + fMatch = TRUE; + negotiatedAuth = pAuthList->authType[idx]; + break; + default: + fMatch = FALSE; + } + if (fMatch) break; + } + + if(!fMatch) break; + //In case of WPA / WPA2, check whether it supports WEP as well + if(pIes) + { + //Prepare the encryption type for WPA/WPA2 functions + if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == ucEncryptionType ) + { + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40; + } + else if( eCSR_ENCRYPT_TYPE_WEP104 == ucEncryptionType ) + { + ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104; + } + //else we can use the encryption type directly + if ( pIes->WPA.present ) + { + fMatch = vos_mem_compare(pIes->WPA.multicast_cipher, + csrWpaOui[csrGetOUIIndexFromCipher( ucEncryptionType )], + CSR_WPA_OUI_SIZE); + if( fMatch ) break; + } + if ( pIes->RSN.present ) + { + fMatch = vos_mem_compare(pIes->RSN.gp_cipher_suite, + csrRSNOui[csrGetOUIIndexFromCipher( ucEncryptionType )], + CSR_RSN_OUI_SIZE); + } + } + + }while(0); + + if( fMatch ) + { + if( pNegotiatedAuthType ) + *pNegotiatedAuthType = negotiatedAuth; + + if( pNegotiatedMCEncryption ) + *pNegotiatedMCEncryption = negotiatedMCCipher; + } + + + return fMatch; +} + + +//pIes shall contain IEs from pSirBssDesc. It shall be returned from function csrGetParsedBssDescriptionIEs +tANI_BOOLEAN csrIsSecurityMatch( tHalHandle hHal, tCsrAuthList *authType, + tCsrEncryptionList *pUCEncryptionType, + tCsrEncryptionList *pMCEncryptionType, + tANI_BOOLEAN *pMFPEnabled, + tANI_U8 *pMFPRequired, tANI_U8 *pMFPCapable, + tSirBssDescription *pSirBssDesc, + tDot11fBeaconIEs *pIes, + eCsrAuthType *negotiatedAuthtype, + eCsrEncryptionType *negotiatedUCCipher, + eCsrEncryptionType *negotiatedMCCipher ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fMatch = FALSE; + tANI_U8 i,idx; + eCsrEncryptionType mcCipher = eCSR_ENCRYPT_TYPE_UNKNOWN, ucCipher = eCSR_ENCRYPT_TYPE_UNKNOWN; + eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN; + + for( i = 0 ; ((i < pUCEncryptionType->numEntries) && (!fMatch)) ; i++ ) + { + ucCipher = pUCEncryptionType->encryptionType[i]; + // If the Bss description shows the Privacy bit is on, then we must have some sort of encryption configured + // for the profile to work. Don't attempt to join networks with Privacy bit set when profiles say NONE for + // encryption type. + switch ( ucCipher ) + { + case eCSR_ENCRYPT_TYPE_NONE: + { + // for NO encryption, if the Bss description has the Privacy bit turned on, then encryption is + // required so we have to reject this Bss. + if ( csrIsPrivacy( pSirBssDesc ) ) + { + fMatch = FALSE; + } + else + { + fMatch = TRUE; + } + + if ( fMatch ) + { + fMatch = FALSE; + //Check Multicast cipher requested and Auth type requested. + for( idx = 0 ; idx < pMCEncryptionType->numEntries ; idx++ ) + { + if( eCSR_ENCRYPT_TYPE_NONE == pMCEncryptionType->encryptionType[idx] ) + { + fMatch = TRUE; //Multicast can only be none. + mcCipher = pMCEncryptionType->encryptionType[idx]; + break; + } + } + if (!fMatch) break; + + fMatch = FALSE; + //Check Auth list. It should contain AuthOpen. + for( idx = 0 ; idx < authType->numEntries ; idx++ ) + { + if( eCSR_AUTH_TYPE_OPEN_SYSTEM == authType->authType[idx] ) + { + fMatch = TRUE; + negAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + break; + } + } + if (!fMatch) break; + + } + break; + } + + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + // !! might want to check for WEP keys set in the Profile.... ? + // !! don't need to have the privacy bit in the Bss description. Many AP policies make legacy + // encryption 'optional' so we don't know if we can associate or not. The AP will reject if + // encryption is not allowed without the Privacy bit turned on. + fMatch = csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes); + + break; + + // these are all of the WPA encryption types... + case eCSR_ENCRYPT_TYPE_WEP40: + case eCSR_ENCRYPT_TYPE_WEP104: + fMatch = csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes); + break; + + case eCSR_ENCRYPT_TYPE_TKIP: + case eCSR_ENCRYPT_TYPE_AES: + { + if(pIes) + { + // First check if there is a RSN match + fMatch = csrIsRSNMatch( pMac, authType, ucCipher, + pMCEncryptionType, pMFPEnabled, + pMFPRequired, pMFPCapable, + pIes, &negAuthType, &mcCipher ); + if( !fMatch ) + { + // If not RSN, then check if there is a WPA match + fMatch = csrIsWpaEncryptionMatch( pMac, authType, ucCipher, pMCEncryptionType, pIes, + &negAuthType, &mcCipher ); + } + } + else + { + fMatch = FALSE; + } + break; + } +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI://WAPI + { + if(pIes) + { + fMatch = csrIsWapiMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher ); + } + else + { + fMatch = FALSE; + } + break; + } +#endif /* FEATURE_WLAN_WAPI */ + case eCSR_ENCRYPT_TYPE_ANY: + default: + { + tANI_BOOLEAN fMatchAny = eANI_BOOLEAN_FALSE; + + fMatch = eANI_BOOLEAN_TRUE; + //It is allowed to match anything. Try the more secured ones first. + if(pIes) + { + //Check AES first + ucCipher = eCSR_ENCRYPT_TYPE_AES; + fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher, + pMCEncryptionType, pMFPEnabled, + pMFPRequired, pMFPCapable, pIes, + &negAuthType, &mcCipher ); + if(!fMatchAny) + { + //Check TKIP + ucCipher = eCSR_ENCRYPT_TYPE_TKIP; + fMatchAny = csrIsRSNMatch( hHal, authType, ucCipher, + pMCEncryptionType, + pMFPEnabled, pMFPRequired, + pMFPCapable, pIes, + &negAuthType, &mcCipher ); + } +#ifdef FEATURE_WLAN_WAPI + if(!fMatchAny) + { + //Check WAPI + ucCipher = eCSR_ENCRYPT_TYPE_WPI; + fMatchAny = csrIsWapiMatch( hHal, authType, ucCipher, pMCEncryptionType, pIes, &negAuthType, &mcCipher ); + } +#endif /* FEATURE_WLAN_WAPI */ + } + if(!fMatchAny) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP104; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP40; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + ucCipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + if(!csrValidateWep( pMac, ucCipher, authType, pMCEncryptionType, &negAuthType, &mcCipher, pSirBssDesc, pIes)) + { + //It must be open and no encryption + if ( csrIsPrivacy( pSirBssDesc ) ) + { + //This is not right + fMatch = eANI_BOOLEAN_FALSE; + } + else + { + negAuthType = eCSR_AUTH_TYPE_OPEN_SYSTEM; + mcCipher = eCSR_ENCRYPT_TYPE_NONE; + ucCipher = eCSR_ENCRYPT_TYPE_NONE; + } + } + } + } + } + } + break; + } + } + + } + + if( fMatch ) + { + if( negotiatedUCCipher ) + *negotiatedUCCipher = ucCipher; + + if( negotiatedMCCipher ) + *negotiatedMCCipher = mcCipher; + + if( negotiatedAuthtype ) + *negotiatedAuthtype = negAuthType; + } + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsSsidMatch( tpAniSirGlobal pMac, tANI_U8 *ssid1, tANI_U8 ssid1Len, tANI_U8 *bssSsid, + tANI_U8 bssSsidLen, tANI_BOOLEAN fSsidRequired ) +{ + tANI_BOOLEAN fMatch = FALSE; + + do { + // Check for the specification of the Broadcast SSID at the beginning + // of the list. If specified, then all SSIDs are matches + // (broadcast SSID means accept all SSIDs). + if ( ssid1Len == 0 ) + { + fMatch = TRUE; + break; + } + + // There are a few special cases. If the Bss description has a Broadcast SSID, + // then our Profile must have a single SSID without Wildcards so we can program + // the SSID. + // SSID could be suppressed in beacons. In that case SSID IE has valid length + // but the SSID value is all NULL characters. That condition is trated same + // as NULL SSID + if ( csrIsNULLSSID( bssSsid, bssSsidLen ) ) + { + if ( eANI_BOOLEAN_FALSE == fSsidRequired ) + { + fMatch = TRUE; + } + break; + } + + if(ssid1Len != bssSsidLen) break; + if (vos_mem_compare(bssSsid, ssid1, bssSsidLen)) + { + fMatch = TRUE; + break; + } + + } while( 0 ); + + return( fMatch ); +} + + +//Null ssid means match +tANI_BOOLEAN csrIsSsidInList( tHalHandle hHal, tSirMacSSid *pSsid, tCsrSSIDs *pSsidList ) +{ + tANI_BOOLEAN fMatch = FALSE; + tANI_U32 i; + + if ( pSsidList && pSsid ) + { + for(i = 0; i < pSsidList->numOfSSIDs; i++) + { + if(csrIsNULLSSID(pSsidList->SSIDList[i].SSID.ssId, pSsidList->SSIDList[i].SSID.length) || + ((pSsidList->SSIDList[i].SSID.length == pSsid->length) && + vos_mem_compare(pSsid->ssId, pSsidList->SSIDList[i].SSID.ssId, pSsid->length))) + { + fMatch = TRUE; + break; + } + } + } + + return (fMatch); +} + +//like to use sirCompareMacAddr +tANI_BOOLEAN csrIsMacAddressZero( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ) +{ + tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0, 0, 0, 0, 0, 0}; + + return (vos_mem_compare(bssid, pMacAddr, WNI_CFG_BSSID_LEN)); +} + +//like to use sirCompareMacAddr +tANI_BOOLEAN csrIsMacAddressBroadcast( tpAniSirGlobal pMac, tCsrBssid *pMacAddr ) +{ + tANI_U8 bssid[WNI_CFG_BSSID_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + return(vos_mem_compare(bssid, pMacAddr, WNI_CFG_BSSID_LEN)); +} + + +//like to use sirCompareMacAddr +tANI_BOOLEAN csrIsMacAddressEqual( tpAniSirGlobal pMac, tCsrBssid *pMacAddr1, tCsrBssid *pMacAddr2 ) +{ + return(vos_mem_compare(pMacAddr1, pMacAddr2, sizeof(tCsrBssid))); +} + + +tANI_BOOLEAN csrIsBssidMatch( tHalHandle hHal, tCsrBssid *pProfBssid, tCsrBssid *BssBssid ) +{ + tANI_BOOLEAN fMatch = FALSE; + tCsrBssid ProfileBssid; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + // for efficiency of the MAC_ADDRESS functions, move the + // Bssid's into MAC_ADDRESS structs. + vos_mem_copy(&ProfileBssid, pProfBssid, sizeof(tCsrBssid)); + + do { + + // Give the profile the benefit of the doubt... accept either all 0 or + // the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to + // match any Bssids). + if ( csrIsMacAddressZero( pMac, &ProfileBssid ) || + csrIsMacAddressBroadcast( pMac, &ProfileBssid ) ) + { + fMatch = TRUE; + break; + } + + if ( csrIsMacAddressEqual( pMac, BssBssid, &ProfileBssid ) ) + { + fMatch = TRUE; + break; + } + + } while( 0 ); + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsBSSTypeMatch(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2) +{ + if((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2) && (bssType1 != bssType2)) + return eANI_BOOLEAN_FALSE; + else + return eANI_BOOLEAN_TRUE; +} + + +tANI_BOOLEAN csrIsBssTypeIBSS(eCsrRoamBssType bssType) +{ + return((tANI_BOOLEAN)(eCSR_BSS_TYPE_START_IBSS == bssType || eCSR_BSS_TYPE_IBSS == bssType)); +} + +tANI_BOOLEAN csrIsBssTypeWDS(eCsrRoamBssType bssType) +{ + return((tANI_BOOLEAN)(eCSR_BSS_TYPE_WDS_STA == bssType || eCSR_BSS_TYPE_WDS_AP == bssType)); +} + +tANI_BOOLEAN csrIsBSSTypeCapsMatch( eCsrRoamBssType bssType, tSirBssDescription *pSirBssDesc ) +{ + tANI_BOOLEAN fMatch = TRUE; + + do + { + switch( bssType ) + { + case eCSR_BSS_TYPE_ANY: + break; + + case eCSR_BSS_TYPE_INFRASTRUCTURE: + case eCSR_BSS_TYPE_WDS_STA: + if( !csrIsInfraBssDesc( pSirBssDesc ) ) + fMatch = FALSE; + + break; + + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + if( !csrIsIbssBssDesc( pSirBssDesc ) ) + fMatch = FALSE; + + break; + + case eCSR_BSS_TYPE_WDS_AP: //For WDS AP, no need to match anything + default: + fMatch = FALSE; + break; + } + } + while( 0 ); + + + return( fMatch ); +} + +static tANI_BOOLEAN csrIsCapabilitiesMatch( tpAniSirGlobal pMac, eCsrRoamBssType bssType, tSirBssDescription *pSirBssDesc ) +{ + return( csrIsBSSTypeCapsMatch( bssType, pSirBssDesc ) ); +} + + + +static tANI_BOOLEAN csrIsSpecificChannelMatch( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc, tANI_U8 Channel ) +{ + tANI_BOOLEAN fMatch = TRUE; + + do + { + // if the channel is ANY, then always match... + if ( eCSR_OPERATING_CHANNEL_ANY == Channel ) break; + if ( Channel == pSirBssDesc->channelId ) break; + + // didn't match anything.. so return NO match + fMatch = FALSE; + + } while( 0 ); + + return( fMatch ); +} + + +tANI_BOOLEAN csrIsChannelBandMatch( tpAniSirGlobal pMac, tANI_U8 channelId, tSirBssDescription *pSirBssDesc ) +{ + tANI_BOOLEAN fMatch = TRUE; + + do + { + // if the profile says Any channel AND the global settings says ANY channel, then we + // always match... + if ( eCSR_OPERATING_CHANNEL_ANY == channelId ) break; + + if ( eCSR_OPERATING_CHANNEL_ANY != channelId ) + { + fMatch = csrIsSpecificChannelMatch( pMac, pSirBssDesc, channelId ); + } + + } while( 0 ); + + return( fMatch ); +} + + +/** + * \brief Enquire as to whether a given rate is supported by the + * adapter as currently configured + * + * + * \param nRate A rate in units of 500kbps + * + * \return TRUE if the adapter is currently capable of supporting this + * rate, FALSE else + * + * + * The rate encoding is just as in 802.11 Information Elements, except + * that the high bit is \em not interpreted as indicating a Basic Rate, + * and proprietary rates are allowed, too. + * + * Note that if the adapter's dot11Mode is g, we don't restrict the + * rates. According to hwReadEepromParameters, this will happen when: + * + * ... the card is configured for ALL bands through the property + * page. If this occurs, and the card is not an ABG card ,then this + * code is setting the dot11Mode to assume the mode that the + * hardware can support. For example, if the card is an 11BG card + * and we are configured to support ALL bands, then we change the + * dot11Mode to 11g because ALL in this case is only what the + * hardware can support. + * + * + */ + +static tANI_BOOLEAN csrIsAggregateRateSupported( tpAniSirGlobal pMac, tANI_U16 rate ) +{ + tANI_BOOLEAN fSupported = eANI_BOOLEAN_FALSE; + tANI_U16 idx, newRate; + + //In case basic rate flag is set + newRate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK); + if ( eCSR_CFG_DOT11_MODE_11A == pMac->roam.configParam.uCfgDot11Mode ) + { + switch ( newRate ) + { + case eCsrSuppRate_6Mbps: + case eCsrSuppRate_9Mbps: + case eCsrSuppRate_12Mbps: + case eCsrSuppRate_18Mbps: + case eCsrSuppRate_24Mbps: + case eCsrSuppRate_36Mbps: + case eCsrSuppRate_48Mbps: + case eCsrSuppRate_54Mbps: + fSupported = TRUE; + break; + default: + fSupported = FALSE; + break; + } + + } + else if( eCSR_CFG_DOT11_MODE_11B == pMac->roam.configParam.uCfgDot11Mode ) + { + switch ( newRate ) + { + case eCsrSuppRate_1Mbps: + case eCsrSuppRate_2Mbps: + case eCsrSuppRate_5_5Mbps: + case eCsrSuppRate_11Mbps: + fSupported = TRUE; + break; + default: + fSupported = FALSE; + break; + } + } + else if ( !pMac->roam.configParam.ProprietaryRatesEnabled ) + { + + switch ( newRate ) + { + case eCsrSuppRate_1Mbps: + case eCsrSuppRate_2Mbps: + case eCsrSuppRate_5_5Mbps: + case eCsrSuppRate_6Mbps: + case eCsrSuppRate_9Mbps: + case eCsrSuppRate_11Mbps: + case eCsrSuppRate_12Mbps: + case eCsrSuppRate_18Mbps: + case eCsrSuppRate_24Mbps: + case eCsrSuppRate_36Mbps: + case eCsrSuppRate_48Mbps: + case eCsrSuppRate_54Mbps: + fSupported = TRUE; + break; + default: + fSupported = FALSE; + break; + } + + } + else { + + if ( eCsrSuppRate_1Mbps == newRate || + eCsrSuppRate_2Mbps == newRate || + eCsrSuppRate_5_5Mbps == newRate || + eCsrSuppRate_11Mbps == newRate ) + { + fSupported = TRUE; + } + else { + idx = 0x1; + + switch ( newRate ) + { + case eCsrSuppRate_6Mbps: + fSupported = gPhyRatesSuppt[0][idx]; + break; + case eCsrSuppRate_9Mbps: + fSupported = gPhyRatesSuppt[1][idx]; + break; + case eCsrSuppRate_12Mbps: + fSupported = gPhyRatesSuppt[2][idx]; + break; + case eCsrSuppRate_18Mbps: + fSupported = gPhyRatesSuppt[3][idx]; + break; + case eCsrSuppRate_20Mbps: + fSupported = gPhyRatesSuppt[4][idx]; + break; + case eCsrSuppRate_24Mbps: + fSupported = gPhyRatesSuppt[5][idx]; + break; + case eCsrSuppRate_36Mbps: + fSupported = gPhyRatesSuppt[6][idx]; + break; + case eCsrSuppRate_40Mbps: + fSupported = gPhyRatesSuppt[7][idx]; + break; + case eCsrSuppRate_42Mbps: + fSupported = gPhyRatesSuppt[8][idx]; + break; + case eCsrSuppRate_48Mbps: + fSupported = gPhyRatesSuppt[9][idx]; + break; + case eCsrSuppRate_54Mbps: + fSupported = gPhyRatesSuppt[10][idx]; + break; + case eCsrSuppRate_72Mbps: + fSupported = gPhyRatesSuppt[11][idx]; + break; + case eCsrSuppRate_80Mbps: + fSupported = gPhyRatesSuppt[12][idx]; + break; + case eCsrSuppRate_84Mbps: + fSupported = gPhyRatesSuppt[13][idx]; + break; + case eCsrSuppRate_96Mbps: + fSupported = gPhyRatesSuppt[14][idx]; + break; + case eCsrSuppRate_108Mbps: + fSupported = gPhyRatesSuppt[15][idx]; + break; + case eCsrSuppRate_120Mbps: + fSupported = gPhyRatesSuppt[16][idx]; + break; + case eCsrSuppRate_126Mbps: + fSupported = gPhyRatesSuppt[17][idx]; + break; + case eCsrSuppRate_144Mbps: + fSupported = gPhyRatesSuppt[18][idx]; + break; + case eCsrSuppRate_160Mbps: + fSupported = gPhyRatesSuppt[19][idx]; + break; + case eCsrSuppRate_168Mbps: + fSupported = gPhyRatesSuppt[20][idx]; + break; + case eCsrSuppRate_192Mbps: + fSupported = gPhyRatesSuppt[21][idx]; + break; + case eCsrSuppRate_216Mbps: + fSupported = gPhyRatesSuppt[22][idx]; + break; + case eCsrSuppRate_240Mbps: + fSupported = gPhyRatesSuppt[23][idx]; + break; + default: + fSupported = FALSE; + break; + } + } + } + + return fSupported; +} + + + +static tANI_BOOLEAN csrIsRateSetMatch( tpAniSirGlobal pMac, + tDot11fIESuppRates *pBssSuppRates, + tDot11fIEExtSuppRates *pBssExtSuppRates ) +{ + tANI_BOOLEAN fMatch = TRUE; + tANI_U32 i; + + + // Validate that all of the Basic rates advertised in the Bss description are supported. + if ( pBssSuppRates ) + { + for( i = 0; i < pBssSuppRates->num_rates; i++ ) + { + if ( CSR_IS_BASIC_RATE( pBssSuppRates->rates[ i ] ) ) + { + if ( !csrIsAggregateRateSupported( pMac, pBssSuppRates->rates[ i ] ) ) + { + fMatch = FALSE; + break; + } + } + } + } + + if ( fMatch && pBssExtSuppRates ) + { + for( i = 0; i < pBssExtSuppRates->num_rates; i++ ) + { + if ( CSR_IS_BASIC_RATE( pBssExtSuppRates->rates[ i ] ) ) + { + if ( !csrIsAggregateRateSupported( pMac, pBssExtSuppRates->rates[ i ] ) ) + { + fMatch = FALSE; + break; + } + } + } + } + + return( fMatch ); + +} + + +//ppIes can be NULL. If caller want to get the *ppIes allocated by this function, pass in *ppIes = NULL +tANI_BOOLEAN csrMatchBSS( tHalHandle hHal, tSirBssDescription *pBssDesc, tCsrScanResultFilter *pFilter, + eCsrAuthType *pNegAuth, eCsrEncryptionType *pNegUc, eCsrEncryptionType *pNegMc, + tDot11fBeaconIEs **ppIes) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRC = eANI_BOOLEAN_FALSE, fCheck; + tANI_U32 i; + tDot11fBeaconIEs *pIes = NULL; + tANI_U8 *pb; + + do { + if( ( NULL == ppIes ) || ( *ppIes ) == NULL ) + { + //If no IEs passed in, get our own. + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIes))) + { + break; + } + } + else + { + //Save the one pass in for local use + pIes = *ppIes; + } + + //Check if caller wants P2P + fCheck = (!pFilter->p2pResult || pIes->P2PBeaconProbeRes.present); + if(!fCheck) break; + + if(pIes->SSID.present) + { + for(i = 0; i < pFilter->SSIDs.numOfSSIDs; i++) + { + fCheck = csrIsSsidMatch( pMac, pFilter->SSIDs.SSIDList[i].SSID.ssId, pFilter->SSIDs.SSIDList[i].SSID.length, + pIes->SSID.ssid, + pIes->SSID.num_ssid, eANI_BOOLEAN_TRUE ); + if ( fCheck ) break; + } + if(!fCheck) break; + } + fCheck = eANI_BOOLEAN_TRUE; + for(i = 0; i < pFilter->BSSIDs.numOfBSSIDs; i++) + { + fCheck = csrIsBssidMatch( pMac, (tCsrBssid *)&pFilter->BSSIDs.bssid[i], (tCsrBssid *)pBssDesc->bssId ); + if ( fCheck ) break; + + if (pFilter->p2pResult && pIes->P2PBeaconProbeRes.present) + { + fCheck = csrIsBssidMatch( pMac, (tCsrBssid *)&pFilter->BSSIDs.bssid[i], + (tCsrBssid *)pIes->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress ); + + if ( fCheck ) break; + } + } + if(!fCheck) break; + + fCheck = eANI_BOOLEAN_TRUE; + for(i = 0; i < pFilter->ChannelInfo.numOfChannels; i++) + { + fCheck = csrIsChannelBandMatch( pMac, pFilter->ChannelInfo.ChannelList[i], pBssDesc ); + if ( fCheck ) break; + } + if(!fCheck) + break; +#if defined WLAN_FEATURE_VOWIFI + /* If this is for measurement filtering */ + if( pFilter->fMeasurement ) + { + fRC = eANI_BOOLEAN_TRUE; + break; + } +#endif + if ( !csrIsPhyModeMatch( pMac, pFilter->phyMode, pBssDesc, NULL, NULL, pIes ) ) break; + if ( (!pFilter->bWPSAssociation) && (!pFilter->bOSENAssociation) && +#ifdef WLAN_FEATURE_11W + !csrIsSecurityMatch( pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + &pFilter->MFPEnabled, + &pFilter->MFPRequired, + &pFilter->MFPCapable, + pBssDesc, pIes, pNegAuth, + pNegUc, pNegMc ) +#else + !csrIsSecurityMatch( pMac, &pFilter->authType, + &pFilter->EncryptionType, + &pFilter->mcEncryptionType, + NULL, NULL, NULL, + pBssDesc, pIes, pNegAuth, + pNegUc, pNegMc ) +#endif + ) break; + if ( !csrIsCapabilitiesMatch( pMac, pFilter->BSSType, pBssDesc ) ) break; + if ( !csrIsRateSetMatch( pMac, &pIes->SuppRates, &pIes->ExtSuppRates ) ) break; + //Tush-QoS: validate first if asked for APSD or WMM association + if ( (eCsrRoamWmmQbssOnly == pMac->roam.configParam.WMMSupportMode) && + !CSR_IS_QOS_BSS(pIes) ) + break; + //Check country. check even when pb is NULL because we may want to make sure + //AP has a country code in it if fEnforceCountryCodeMatch is set. + pb = ( pFilter->countryCode[0] ) ? ( pFilter->countryCode) : NULL; + + fCheck = csrMatchCountryCode( pMac, pb, pIes ); + if(!fCheck) + break; + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pFilter->MDID.mdiePresent && csrRoamIs11rAssoc(pMac)) + { + if (pBssDesc->mdiePresent) + { + if (pFilter->MDID.mobilityDomain != (pBssDesc->mdie[1] << 8 | pBssDesc->mdie[0])) + break; + } + else + break; + } +#endif + fRC = eANI_BOOLEAN_TRUE; + + } while( 0 ); + if( ppIes ) + { + *ppIes = pIes; + } + else if( pIes ) + { + vos_mem_free(pIes); + } + + return( fRC ); +} + +tANI_BOOLEAN csrMatchConnectedBSSSecurity( tpAniSirGlobal pMac, tCsrRoamConnectedProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes) +{ + tCsrEncryptionList ucEncryptionList, mcEncryptionList; + tCsrAuthList authList; + + ucEncryptionList.numEntries = 1; + ucEncryptionList.encryptionType[0] = pProfile->EncryptionType; + + mcEncryptionList.numEntries = 1; + mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType; + + authList.numEntries = 1; + authList.authType[0] = pProfile->AuthType; + + return( csrIsSecurityMatch( pMac, &authList, &ucEncryptionList, + &mcEncryptionList, NULL, NULL, NULL, + pBssDesc, pIes, NULL, NULL, NULL )); + +} + + +tANI_BOOLEAN csrMatchBSSToConnectProfile( tHalHandle hHal, tCsrRoamConnectedProfile *pProfile, + tSirBssDescription *pBssDesc, tDot11fBeaconIEs *pIes ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN fRC = eANI_BOOLEAN_FALSE, fCheck; + tDot11fBeaconIEs *pIesLocal = pIes; + + do { + if( !pIes ) + { + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, pBssDesc, &pIesLocal))) + { + break; + } + } + fCheck = eANI_BOOLEAN_TRUE; + if(pIesLocal->SSID.present) + { + tANI_BOOLEAN fCheckSsid = eANI_BOOLEAN_FALSE; + if(pProfile->SSID.length) + { + fCheckSsid = eANI_BOOLEAN_TRUE; + } + fCheck = csrIsSsidMatch( pMac, pProfile->SSID.ssId, pProfile->SSID.length, + pIesLocal->SSID.ssid, pIesLocal->SSID.num_ssid, fCheckSsid ); + if(!fCheck) break; + } + if ( !csrMatchConnectedBSSSecurity( pMac, pProfile, pBssDesc, pIesLocal) ) break; + if ( !csrIsCapabilitiesMatch( pMac, pProfile->BSSType, pBssDesc ) ) break; + if ( !csrIsRateSetMatch( pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates ) ) break; + fCheck = csrIsChannelBandMatch( pMac, pProfile->operationChannel, pBssDesc ); + if(!fCheck) + break; + + fRC = eANI_BOOLEAN_TRUE; + + } while( 0 ); + + if( !pIes && pIesLocal ) + { + //locally allocated + vos_mem_free(pIesLocal); + } + + return( fRC ); +} + + + +void csrAddRateBitmap(tANI_U8 rate, tANI_U16 *pRateBitmap) +{ + tANI_U16 rateBitmap; + tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK ); + rateBitmap = *pRateBitmap; + switch(n) + { + case SIR_MAC_RATE_1: + rateBitmap |= SIR_MAC_RATE_1_BITMAP; + break; + case SIR_MAC_RATE_2: + rateBitmap |= SIR_MAC_RATE_2_BITMAP; + break; + case SIR_MAC_RATE_5_5: + rateBitmap |= SIR_MAC_RATE_5_5_BITMAP; + break; + case SIR_MAC_RATE_11: + rateBitmap |= SIR_MAC_RATE_11_BITMAP; + break; + case SIR_MAC_RATE_6: + rateBitmap |= SIR_MAC_RATE_6_BITMAP; + break; + case SIR_MAC_RATE_9: + rateBitmap |= SIR_MAC_RATE_9_BITMAP; + break; + case SIR_MAC_RATE_12: + rateBitmap |= SIR_MAC_RATE_12_BITMAP; + break; + case SIR_MAC_RATE_18: + rateBitmap |= SIR_MAC_RATE_18_BITMAP; + break; + case SIR_MAC_RATE_24: + rateBitmap |= SIR_MAC_RATE_24_BITMAP; + break; + case SIR_MAC_RATE_36: + rateBitmap |= SIR_MAC_RATE_36_BITMAP; + break; + case SIR_MAC_RATE_48: + rateBitmap |= SIR_MAC_RATE_48_BITMAP; + break; + case SIR_MAC_RATE_54: + rateBitmap |= SIR_MAC_RATE_54_BITMAP; + break; + } + *pRateBitmap = rateBitmap; +} + + + +tANI_BOOLEAN csrIsRateAlreadyPresent(tANI_U8 rate, tANI_U16 rateBitmap) +{ + tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK ); + + switch(n) + { + case SIR_MAC_RATE_1: + rateBitmap &= SIR_MAC_RATE_1_BITMAP; + break; + case SIR_MAC_RATE_2: + rateBitmap &= SIR_MAC_RATE_2_BITMAP; + break; + case SIR_MAC_RATE_5_5: + rateBitmap &= SIR_MAC_RATE_5_5_BITMAP; + break; + case SIR_MAC_RATE_11: + rateBitmap &= SIR_MAC_RATE_11_BITMAP; + break; + case SIR_MAC_RATE_6: + rateBitmap &= SIR_MAC_RATE_6_BITMAP; + break; + case SIR_MAC_RATE_9: + rateBitmap &= SIR_MAC_RATE_9_BITMAP; + break; + case SIR_MAC_RATE_12: + rateBitmap &= SIR_MAC_RATE_12_BITMAP; + break; + case SIR_MAC_RATE_18: + rateBitmap &= SIR_MAC_RATE_18_BITMAP; + break; + case SIR_MAC_RATE_24: + rateBitmap &= SIR_MAC_RATE_24_BITMAP; + break; + case SIR_MAC_RATE_36: + rateBitmap &= SIR_MAC_RATE_36_BITMAP; + break; + case SIR_MAC_RATE_48: + rateBitmap &= SIR_MAC_RATE_48_BITMAP; + break; + case SIR_MAC_RATE_54: + rateBitmap &= SIR_MAC_RATE_54_BITMAP; + break; + } + return !!rateBitmap; +} + + + +tANI_BOOLEAN csrRatesIsDot11RateSupported( tHalHandle hHal, tANI_U8 rate ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U16 n = BITS_OFF( rate, CSR_DOT11_BASIC_RATE_MASK ); + + return csrIsAggregateRateSupported( pMac, n ); +} + + +tANI_U16 csrRatesMacPropToDot11( tANI_U16 Rate ) +{ + tANI_U16 ConvertedRate = Rate; + + switch( Rate ) + { + case SIR_MAC_RATE_1: + ConvertedRate = 2; + break; + case SIR_MAC_RATE_2: + ConvertedRate = 4; + break; + case SIR_MAC_RATE_5_5: + ConvertedRate = 11; + break; + case SIR_MAC_RATE_11: + ConvertedRate = 22; + break; + + case SIR_MAC_RATE_6: + ConvertedRate = 12; + break; + case SIR_MAC_RATE_9: + ConvertedRate = 18; + break; + case SIR_MAC_RATE_12: + ConvertedRate = 24; + break; + case SIR_MAC_RATE_18: + ConvertedRate = 36; + break; + case SIR_MAC_RATE_24: + ConvertedRate = 48; + break; + case SIR_MAC_RATE_36: + ConvertedRate = 72; + break; + case SIR_MAC_RATE_42: + ConvertedRate = 84; + break; + case SIR_MAC_RATE_48: + ConvertedRate = 96; + break; + case SIR_MAC_RATE_54: + ConvertedRate = 108; + break; + + case SIR_MAC_RATE_72: + ConvertedRate = 144; + break; + case SIR_MAC_RATE_84: + ConvertedRate = 168; + break; + case SIR_MAC_RATE_96: + ConvertedRate = 192; + break; + case SIR_MAC_RATE_108: + ConvertedRate = 216; + break; + case SIR_MAC_RATE_126: + ConvertedRate = 252; + break; + case SIR_MAC_RATE_144: + ConvertedRate = 288; + break; + case SIR_MAC_RATE_168: + ConvertedRate = 336; + break; + case SIR_MAC_RATE_192: + ConvertedRate = 384; + break; + case SIR_MAC_RATE_216: + ConvertedRate = 432; + break; + case SIR_MAC_RATE_240: + ConvertedRate = 480; + break; + + case 0xff: + ConvertedRate = 0; + break; + } + + return ConvertedRate; +} + + +tANI_U16 csrRatesFindBestRate( tSirMacRateSet *pSuppRates, tSirMacRateSet *pExtRates, tSirMacPropRateSet *pPropRates ) +{ + tANI_U8 i; + tANI_U16 nBest; + + nBest = pSuppRates->rate[ 0 ] & ( ~CSR_DOT11_BASIC_RATE_MASK ); + + if(pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX) + { + pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX; + } + + for ( i = 1U; i < pSuppRates->numRates; ++i ) + { + nBest = (tANI_U16)CSR_MAX( nBest, pSuppRates->rate[ i ] & ( ~CSR_DOT11_BASIC_RATE_MASK ) ); + } + + if ( NULL != pExtRates ) + { + for ( i = 0U; i < pExtRates->numRates; ++i ) + { + nBest = (tANI_U16)CSR_MAX( nBest, pExtRates->rate[ i ] & ( ~CSR_DOT11_BASIC_RATE_MASK ) ); + } + } + + if ( NULL != pPropRates ) + { + for ( i = 0U; i < pPropRates->numPropRates; ++i ) + { + nBest = (tANI_U16)CSR_MAX( nBest, csrRatesMacPropToDot11( pPropRates->propRate[ i ] ) ); + } + } + + return nBest; +} + + +void csrReleaseProfile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile) +{ + if(pProfile) + { + if(pProfile->BSSIDs.bssid) + { + vos_mem_free(pProfile->BSSIDs.bssid); + pProfile->BSSIDs.bssid = NULL; + } + if(pProfile->SSIDs.SSIDList) + { + vos_mem_free(pProfile->SSIDs.SSIDList); + pProfile->SSIDs.SSIDList = NULL; + } + if(pProfile->pWPAReqIE) + { + vos_mem_free(pProfile->pWPAReqIE); + pProfile->pWPAReqIE = NULL; + } + if(pProfile->pRSNReqIE) + { + vos_mem_free(pProfile->pRSNReqIE); + pProfile->pRSNReqIE = NULL; + } +#ifdef FEATURE_WLAN_WAPI + if(pProfile->pWAPIReqIE) + { + vos_mem_free(pProfile->pWAPIReqIE); + pProfile->pWAPIReqIE = NULL; + } +#endif /* FEATURE_WLAN_WAPI */ + + if (pProfile->nAddIEScanLength) + { + memset(pProfile->addIEScan, 0 , SIR_MAC_MAX_ADD_IE_LENGTH+2); + pProfile->nAddIEScanLength = 0; + } + + if(pProfile->pAddIEAssoc) + { + vos_mem_free(pProfile->pAddIEAssoc); + pProfile->pAddIEAssoc = NULL; + } + if(pProfile->ChannelInfo.ChannelList) + { + vos_mem_free(pProfile->ChannelInfo.ChannelList); + pProfile->ChannelInfo.ChannelList = NULL; + } + vos_mem_set(pProfile, sizeof(tCsrRoamProfile), 0); + } +} + +void csrFreeScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter) +{ + if(pScanFilter->BSSIDs.bssid) + { + vos_mem_free(pScanFilter->BSSIDs.bssid); + pScanFilter->BSSIDs.bssid = NULL; + } + if(pScanFilter->ChannelInfo.ChannelList) + { + vos_mem_free(pScanFilter->ChannelInfo.ChannelList); + pScanFilter->ChannelInfo.ChannelList = NULL; + } + if(pScanFilter->SSIDs.SSIDList) + { + vos_mem_free(pScanFilter->SSIDs.SSIDList); + pScanFilter->SSIDs.SSIDList = NULL; + } +} + + +void csrFreeRoamProfile(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; + + if(pSession->pCurRoamProfile) + { + csrReleaseProfile(pMac, pSession->pCurRoamProfile); + vos_mem_free(pSession->pCurRoamProfile); + pSession->pCurRoamProfile = NULL; + } +} + + +void csrFreeConnectBssDesc(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId]; + + if(pSession->pConnectBssDesc) + { + vos_mem_free(pSession->pConnectBssDesc); + pSession->pConnectBssDesc = NULL; + } +} + + + +tSirResultCodes csrGetDisassocRspStatusCode( tSirSmeDisassocRsp *pSmeDisassocRsp ) +{ + tANI_U8 *pBuffer = (tANI_U8 *)pSmeDisassocRsp; + tANI_U32 ret; + + pBuffer += (sizeof(tANI_U16) + sizeof(tANI_U16) + sizeof(tSirMacAddr)); + //tSirResultCodes is an enum, assuming is 32bit + //If we cannot make this assumption, use copymemory + pal_get_U32( pBuffer, &ret ); + + return( ( tSirResultCodes )ret ); +} + + +tSirResultCodes csrGetDeAuthRspStatusCode( tSirSmeDeauthRsp *pSmeRsp ) +{ + tANI_U8 *pBuffer = (tANI_U8 *)pSmeRsp; + tANI_U32 ret; + + pBuffer += (sizeof(tANI_U16) + sizeof(tANI_U16) + sizeof(tANI_U8) + sizeof(tANI_U16)); + //tSirResultCodes is an enum, assuming is 32bit + //If we cannot make this assumption, use copymemory + pal_get_U32( pBuffer, &ret ); + + return( ( tSirResultCodes )ret ); +} + +#if 0 +tSirScanType csrGetScanType(tANI_U8 chnId, eRegDomainId domainId, tANI_U8 *countryCode) +{ + tSirScanType scanType = eSIR_PASSIVE_SCAN; + tANI_U8 cc = 0; + + while (cc++ < gCsrDomainChnInfo[domainId].numChannels) + { + if(chnId == gCsrDomainChnInfo[domainId].chnInfo[cc].chnId) + { + scanType = gCsrDomainChnInfo[domainId].chnInfo[cc].scanType; + break; + } + } + + return (scanType); +} +#endif + +tSirScanType csrGetScanType(tpAniSirGlobal pMac, tANI_U8 chnId) +{ + tSirScanType scanType = eSIR_PASSIVE_SCAN; + eNVChannelEnabledType channelEnabledType; + + channelEnabledType = vos_nv_getChannelEnabledState(chnId); + if( NV_CHANNEL_ENABLE == channelEnabledType) + { + scanType = eSIR_ACTIVE_SCAN; + } + return (scanType); +} + + +tANI_U8 csrToUpper( tANI_U8 ch ) +{ + tANI_U8 chOut; + + if ( ch >= 'a' && ch <= 'z' ) + { + chOut = ch - 'a' + 'A'; + } + else + { + chOut = ch; + } + return( chOut ); +} + + +tSirBssType csrTranslateBsstypeToMacType(eCsrRoamBssType csrtype) +{ + tSirBssType ret; + + switch(csrtype) + { + case eCSR_BSS_TYPE_INFRASTRUCTURE: + ret = eSIR_INFRASTRUCTURE_MODE; + break; + case eCSR_BSS_TYPE_IBSS: + case eCSR_BSS_TYPE_START_IBSS: + ret = eSIR_IBSS_MODE; + break; + case eCSR_BSS_TYPE_WDS_AP: + ret = eSIR_BTAMP_AP_MODE; + break; + case eCSR_BSS_TYPE_WDS_STA: + ret = eSIR_BTAMP_STA_MODE; + break; + case eCSR_BSS_TYPE_INFRA_AP: + ret = eSIR_INFRA_AP_MODE; + break; + case eCSR_BSS_TYPE_ANY: + default: + ret = eSIR_AUTO_MODE; + break; + } + + return (ret); +} + + +//This function use the parameters to decide the CFG value. +//CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG +//So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value +eCsrCfgDot11Mode csrGetCfgDot11ModeFromCsrPhyMode(tCsrRoamProfile *pProfile, eCsrPhyMode phyMode, tANI_BOOLEAN fProprietary) +{ + tANI_U32 cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG; + + switch(phyMode) + { + case eCSR_DOT11_MODE_11a: + case eCSR_DOT11_MODE_11a_ONLY: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A; + break; + case eCSR_DOT11_MODE_11b: + case eCSR_DOT11_MODE_11b_ONLY: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B; + break; + case eCSR_DOT11_MODE_11g: + case eCSR_DOT11_MODE_11g_ONLY: + if(pProfile && (CSR_IS_INFRA_AP(pProfile)) && (phyMode == eCSR_DOT11_MODE_11g_ONLY)) + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY; + else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G; + break; + case eCSR_DOT11_MODE_11n: + if(fProprietary) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; + case eCSR_DOT11_MODE_11n_ONLY: + if(pProfile && CSR_IS_INFRA_AP(pProfile)) + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY; + else + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + break; + case eCSR_DOT11_MODE_TAURUS: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_TAURUS; + break; + case eCSR_DOT11_MODE_abg: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG; + break; + case eCSR_DOT11_MODE_AUTO: + cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO; + break; + +#ifdef WLAN_FEATURE_11AC + case eCSR_DOT11_MODE_11ac: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; + case eCSR_DOT11_MODE_11ac_ONLY: + if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY; + } + else + { + cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N; + } + break; +#endif + default: + //No need to assign anything here + break; + } + + return (cfgDot11Mode); +} + + +eHalStatus csrSetRegulatoryDomain(tpAniSirGlobal pMac, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_BOOLEAN fRestart; + + if(pMac->scan.domainIdCurrent == domainId) + { + //no change + fRestart = eANI_BOOLEAN_FALSE; + } + else if( !pMac->roam.configParam.fEnforceDefaultDomain ) + { + pMac->scan.domainIdCurrent = domainId; + fRestart = eANI_BOOLEAN_TRUE; + } + else + { + //We cannot change the domain + status = eHAL_STATUS_CSR_WRONG_STATE; + fRestart = eANI_BOOLEAN_FALSE; + } + if(pfRestartNeeded) + { + *pfRestartNeeded = fRestart; + } + + return (status); +} + + +v_REGDOMAIN_t csrGetCurrentRegulatoryDomain(tpAniSirGlobal pMac) +{ + return (pMac->scan.domainIdCurrent); +} + + +eHalStatus csrGetRegulatoryDomainForCountry +( +tpAniSirGlobal pMac, +tANI_U8 *pCountry, +v_REGDOMAIN_t *pDomainId, +v_CountryInfoSource_t source +) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + VOS_STATUS vosStatus; + v_COUNTRYCODE_t countryCode; + v_REGDOMAIN_t domainId; + + if(pCountry) + { + countryCode[0] = pCountry[0]; + countryCode[1] = pCountry[1]; + vosStatus = vos_nv_getRegDomainFromCountryCode(&domainId, + countryCode, + source); + + if( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + if( pDomainId ) + { + *pDomainId = domainId; + } + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog(pMac, LOGW, FL(" Couldn't find domain for country code %c%c"), pCountry[0], pCountry[1]); + status = eHAL_STATUS_INVALID_PARAMETER; + } + } + + return (status); +} + +//To check whether a country code matches the one in the IE +//Only check the first two characters, ignoring in/outdoor +//pCountry -- caller allocated buffer contain the country code that is checking against +//the one in pIes. It can be NULL. +//caller must provide pIes, it cannot be NULL +//This function always return TRUE if 11d support is not turned on. +tANI_BOOLEAN csrMatchCountryCode( tpAniSirGlobal pMac, tANI_U8 *pCountry, tDot11fBeaconIEs *pIes ) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + v_REGDOMAIN_t domainId = REGDOMAIN_COUNT; //This is init to invalid value + eHalStatus status; + + do + { + if( !csrIs11dSupported( pMac) ) + { + break; + } + if( !pIes ) + { + smsLog(pMac, LOGE, FL(" No IEs")); + break; + } + if( pMac->roam.configParam.fEnforceDefaultDomain || + pMac->roam.configParam.fEnforceCountryCodeMatch ) + { + //Make sure this country is recognizable + if( pIes->Country.present ) + { + status = csrGetRegulatoryDomainForCountry(pMac, + pIes->Country.country, + &domainId, COUNTRY_QUERY); + if( !HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetRegulatoryDomainForCountry(pMac, + pMac->scan.countryCode11d, + (v_REGDOMAIN_t *) &domainId, + COUNTRY_QUERY); + if( !HAL_STATUS_SUCCESS( status ) ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + } + //check whether it is needed to enforce to the default regulatory domain first + if( pMac->roam.configParam.fEnforceDefaultDomain ) + { + if( domainId != pMac->scan.domainIdCurrent ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + if( pMac->roam.configParam.fEnforceCountryCodeMatch ) + { + if( domainId >= REGDOMAIN_COUNT ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + } + if( pCountry ) + { + tANI_U32 i; + + if( !pIes->Country.present ) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + // Convert the CountryCode characters to upper + for ( i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++ ) + { + pCountry[i] = csrToUpper( pCountry[i] ); + } + if (!vos_mem_compare(pIes->Country.country, pCountry, + WNI_CFG_COUNTRY_CODE_LEN - 1)) + { + fRet = eANI_BOOLEAN_FALSE; + break; + } + } + } while(0); + + return (fRet); +} + +#if 0 +eHalStatus csrSetCountryDomainMapping(tpAniSirGlobal pMac, tCsrCountryDomainMapping *pCountryDomainMapping) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 i, j; + tANI_BOOLEAN fDomainChanged = eANI_BOOLEAN_FALSE; + tANI_U8 countryCode[WNI_CFG_COUNTRY_CODE_LEN]; + + i = WNI_CFG_COUNTRY_CODE_LEN; + //Get the currently used country code + status = ccmCfgGetStr(pMac, WNI_CFG_COUNTRY_CODE, countryCode, &i); + if(HAL_STATUS_SUCCESS(status)) + { + if(pCountryDomainMapping && pCountryDomainMapping->numEntry) + { + for(i = 0; i < pCountryDomainMapping->numEntry; i++) + { + for(j = 0; j < eCSR_NUM_COUNTRY_INDEX; j++) + { + if (vos_mem_compare(gCsrCountryInfo[j].countryCode, + pCountryDomainMapping->pCountryInfo[i].countryCode, + 2)) + { + if(gCsrCountryInfo[j].domainId != pCountryDomainMapping->pCountryInfo[i].domainId) + { + gCsrCountryInfo[j].domainId = pCountryDomainMapping->pCountryInfo[i].domainId; + //Check whether it matches the currently used country code + //If matching, need to update base on the new domain setting. + if (vos_mem_compare(countryCode, + pCountryDomainMapping->pCountryInfo[i].countryCode, + 2)) + { + fDomainChanged = eANI_BOOLEAN_TRUE; + } + } + break; + } + } + } + status = eHAL_STATUS_SUCCESS; + if(fDomainChanged) + { + tCsrChannel *pChannelList; + + if(pMac->scan.f11dInfoApplied) + { + //11d info already applied. Let's reapply with the new domain setting + if(pMac->scan.channels11d.numChannels) + { + pChannelList = &pMac->scan.channels11d; + } + else + { + pChannelList = &pMac->scan.base20MHzChannels; + } + } + else + { + //no 11d so we use the base channelist from EEPROM + pChannelList = &pMac->scan.base20MHzChannels; + } + //set the new domain's scan requirement to CFG + csrSetCfgScanControlList(pMac, countryCode, pChannelList); + } + } + } + + return (status); +} + +eHalStatus csrSetDomainScanSetting(tpAniSirGlobal pMac, tCsrDomainFreqInfo *pDomainFreqInfo) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tANI_U32 i, j; + tANI_U16 freq; + + if(pDomainFreqInfo && pDomainFreqInfo->numEntry && (pDomainFreqInfo->domainId < NUM_REG_DOMAINS)) + { + tCsrDomainChnInfo *pDomainChnInfo = &gCsrDomainChnInfo[pDomainFreqInfo->domainId]; + + for(j = 0; j < pDomainChnInfo->numChannels; j++) + { + if(HAL_STATUS_SUCCESS(halPhyChIdToFreqConversion(pDomainChnInfo->chnInfo[j].chnId, &freq))) + { + for(i = 0; i < pDomainFreqInfo->numEntry; i++) + { + if((pDomainFreqInfo->pCsrScanFreqInfo[i].nStartFreq <= freq) && + (freq <= pDomainFreqInfo->pCsrScanFreqInfo[i].nEndFreq)) + { + pDomainChnInfo->chnInfo[j].scanType = pDomainFreqInfo->pCsrScanFreqInfo[i].scanType; + break; + } + } + } + else + { + smsLog(pMac, LOGW, " Failed to get frequency of channel %d", pDomainChnInfo->chnInfo[j].chnId); + } + } + status = eHAL_STATUS_SUCCESS; + } + + return (status); +} +#endif + +eHalStatus csrGetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModifyProfileFields) +{ + + if(!pModifyProfileFields) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pModifyProfileFields, + &pMac->roam.roamSession[sessionId].connectedProfile.modifyProfileFields, + sizeof(tCsrRoamModifyProfileFields)); + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus csrSetModifyProfileFields(tpAniSirGlobal pMac, tANI_U32 sessionId, + tCsrRoamModifyProfileFields *pModifyProfileFields) +{ + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + vos_mem_copy(&pSession->connectedProfile.modifyProfileFields, + pModifyProfileFields, + sizeof(tCsrRoamModifyProfileFields)); + + return eHAL_STATUS_SUCCESS; +} + + +#if 0 +/* --------------------------------------------------------------------------- + \fn csrGetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed bytes. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetSupportedCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U32 *pbLen) +{ + tANI_U32 numOfCountry = sizeof( gCsrCountryInfo ) / sizeof( gCsrCountryInfo[0] ); + tANI_U32 numBytes = 0; + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if( pbLen ) + { + numBytes = *pbLen; + //Consider it ok, at least we can return the number of bytes needed; + *pbLen = numOfCountry * WNI_CFG_COUNTRY_CODE_LEN; + status = eHAL_STATUS_SUCCESS; + if( pBuf && ( numBytes >= *pbLen ) ) + { + //The ugly part starts. + //We may need to alter the data structure and find a way to make this faster. + tANI_U32 i; + + for ( i = 0; i < numOfCountry; i++ ) + { + vos_mem_copy(pBuf + ( i * WNI_CFG_COUNTRY_CODE_LEN ), + gCsrCountryInfo[i].countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + } + } + + return ( status ); +} +#endif + +/* --------------------------------------------------------------------------- + \fn csrGetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed bytes. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus csrGetSupportedCountryCode(tpAniSirGlobal pMac, tANI_U8 *pBuf, tANI_U32 *pbLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + v_SIZE_t size = (v_SIZE_t)*pbLen; + + vosStatus = vos_nv_getSupportedCountryCode( pBuf, &size, 1 ); + //eiter way, return the value back + *pbLen = (tANI_U32)size; + + //If pBuf is NULL, caller just want to get the size, consider it success + if(pBuf) + { + if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + tANI_U32 i, n = *pbLen / 3; + + for( i = 0; i < n; i++ ) + { + pBuf[i*3 + 2] = ' '; + } + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + + return (status); +} + + + +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus csrScanGetBaseChannels( tpAniSirGlobal pMac, tCsrChannelInfo * pChannelInfo ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + + do + { + + if(!pMac->scan.baseChannels.numChannels || !pChannelInfo) + { + break; + } + pChannelInfo->ChannelList = vos_mem_malloc(pMac->scan.baseChannels.numChannels); + if ( NULL == pChannelInfo->ChannelList ) + { + smsLog( pMac, LOGE, FL("csrScanGetBaseChannels: fail to allocate memory") ); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(pChannelInfo->ChannelList, + pMac->scan.baseChannels.channelList, + pMac->scan.baseChannels.numChannels); + pChannelInfo->numOfChannels = pMac->scan.baseChannels.numChannels; + + }while(0); + + return ( status ); +} + + +tANI_BOOLEAN csrIsSetKeyAllowed(tpAniSirGlobal pMac, tANI_U32 sessionId) +{ + tANI_BOOLEAN fRet = eANI_BOOLEAN_TRUE; + tCsrRoamSession *pSession; + + pSession =CSR_GET_SESSION(pMac, sessionId); + + /*This condition is not working for infra state. When infra is in not-connected state + * the pSession->pCurRoamProfile is NULL. And this function returns TRUE, that is incorrect. + * Since SAP requires to set key without any BSS started, it needs this condition to be met. + * In other words, this function is useless. + * The current work-around is to process setcontext_rsp and removekey_rsp no matter what the + * state is. + */ + smsLog( pMac, LOG2, FL(" is not what it intends to. Must be revisit or removed") ); + if( (NULL == pSession) || + ( csrIsConnStateDisconnected( pMac, sessionId ) && + (pSession->pCurRoamProfile != NULL) && + (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) ) + ) + { + fRet = eANI_BOOLEAN_FALSE; + } + + return ( fRet ); +} + +//no need to acquire lock for this basic function +tANI_U16 sme_ChnToFreq(tANI_U8 chanNum) +{ + int i; + + for (i = 0; i < NUM_RF_CHANNELS; i++) + { + if (rfChannels[i].channelNum == chanNum) + { + return rfChannels[i].targetFreq; + } + } + + return (0); +} + +/* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we + * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and + * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there + * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to + * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS + */ + +//Remove this code once SLM_Sessionization is supported +//BMPS_WORKAROUND_NOT_NEEDED +void csrDisconnectAllActiveSessions(tpAniSirGlobal pMac) +{ + tANI_U8 i; + + /* Disconnect all the active sessions */ + for (i=0; i 0; i--) + { + pChannelList[i] = pChannelList[i-1]; + } + + // Now add the NEW channel...at the front + pChannelList[0] = channel; + + return eHAL_STATUS_SUCCESS; +} +#endif +const char * sme_requestTypetoString(const v_U8_t requestType) +{ + switch (requestType) + { + CASE_RETURN_STRING( eCSR_SCAN_REQUEST_11D_SCAN ); + CASE_RETURN_STRING( eCSR_SCAN_REQUEST_FULL_SCAN ); + CASE_RETURN_STRING( eCSR_SCAN_IDLE_MODE_SCAN ); + CASE_RETURN_STRING( eCSR_SCAN_HO_BG_SCAN ); + CASE_RETURN_STRING( eCSR_SCAN_HO_PROBE_SCAN ); + CASE_RETURN_STRING( eCSR_SCAN_HO_NT_BG_SCAN ); + CASE_RETURN_STRING( eCSR_SCAN_P2P_DISCOVERY ); + CASE_RETURN_STRING( eCSR_SCAN_SOFTAP_CHANNEL_RANGE ); + CASE_RETURN_STRING( eCSR_SCAN_P2P_FIND_PEER ); + default: + return "Unknown Scan Request Type"; + } +} diff --git a/drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c b/drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c new file mode 100644 index 000000000000..f70172217ae2 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/csr/csr_roam_mbb.c @@ -0,0 +1,890 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "aniGlobal.h" +#include "smeInside.h" +#include "csrInsideApi.h" +#include "smsDebug.h" +#include "macTrace.h" +#include "csrNeighborRoam.h" +#include "csr_roam_mbb.h" +#include "csrInternal.h" +#include "wlan_qct_wda.h" + +eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac); + +#define PREAUTH_REASSOC_MBB_TIMER_VALUE 60 + +#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\ +{\ + mac->roam.neighborRoamInfo.prevNeighborRoamState = mac->roam.neighborRoamInfo.neighborRoamState;\ + mac->roam.neighborRoamInfo.neighborRoamState = newState;\ + VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, \ + FL("Neighbor Roam Transition from state %s ==> %s"), \ + csrNeighborRoamStateToString (mac->roam.neighborRoamInfo.prevNeighborRoamState), \ + csrNeighborRoamStateToString (newState));\ +} + +/** + * csr_roam_issue_preauth_reassoc_req() -Prepares preauth request + * @hal: HAL context + * @session_id: session id + * @bss_description: BSS description + * + * This function prepares preauth request and sends request to PE + * + * Return: eHAL_STATUS_SUCCESS on success, + * : eHAL_STATUS_RESOURCES when resource allocation is failure + * : eHAL_STATUS_FAILURE otherwise + */ +eHalStatus csr_roam_issue_preauth_reassoc_req(tHalHandle hal, + tANI_U32 session_id, tpSirBssDescription bss_description) +{ + tpAniSirGlobal mac = PMAC_STRUCT(hal); + tpSirFTPreAuthReq pre_auth_req; + tANI_U16 auth_req_len = 0; + tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id); + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac->roam.neighborRoamInfo; + eHalStatus status; + + auth_req_len = sizeof(tSirFTPreAuthReq); + pre_auth_req = (tpSirFTPreAuthReq)vos_mem_malloc(auth_req_len); + if (NULL == pre_auth_req) { + smsLog(mac, LOGE, + FL("Memory allocation for Preauth request failed")); + return eHAL_STATUS_RESOURCES; + } + + /* + * If neighborRoamState is eCSR_NEIGHBOR_ROAM_STATE_INIT + * by the time this API is invoked, disconnect would have happened. + * So, need to proceed further. + */ + if (mac->roam.neighborRoamInfo.neighborRoamState == + eCSR_NEIGHBOR_ROAM_STATE_INIT) { + smsLog(mac, LOGE, FL("neighborRoamState %d"), + mac->roam.neighborRoamInfo.neighborRoamState); + return eHAL_STATUS_FAILURE; + } + + /* + * Save the SME Session ID here. We need it while processing + * the preauth response. + */ + mac->ft.ftSmeContext.smeSessionId = session_id; + vos_mem_zero(pre_auth_req, auth_req_len); + + pre_auth_req->pbssDescription = (tpSirBssDescription)vos_mem_malloc( + sizeof(bss_description->length) + bss_description->length); + if (NULL == pre_auth_req->pbssDescription) { + smsLog(mac, LOGE, + FL("Unable to allocate memory for preauth bss description")); + return eHAL_STATUS_RESOURCES; + } + + pre_auth_req->messageType = + pal_cpu_to_be16(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ); + + pre_auth_req->preAuthchannelNum = bss_description->channelId; + + vos_mem_copy((void *)&pre_auth_req->currbssId, + (void *)session->connectedProfile.bssid, sizeof(tSirMacAddr)); + vos_mem_copy((void *)&pre_auth_req->preAuthbssId, + (void *)bss_description->bssId, sizeof(tSirMacAddr)); + + vos_mem_copy(pre_auth_req->pbssDescription, bss_description, + sizeof(bss_description->length) + bss_description->length); + pre_auth_req->length = pal_cpu_to_be16(auth_req_len); + + /* Register mbb callback */ + smsLog(mac, LOG1, FL("Registering mbb callback")); + csr_register_roaming_mbb_callback(mac); + + csrReleaseProfile(mac, &neighbor_roam_info->csrNeighborRoamProfile); + + /* Copy current profile to be used in csr_update_roamed_info_mbb */ + status = csrRoamCopyProfile(mac, + &neighbor_roam_info->csrNeighborRoamProfile, + session->pCurRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) { + smsLog(mac, LOGE, FL("Profile copy failed")); + return status; + } + + return palSendMBMessage(mac->hHdd, pre_auth_req); +} + +/** + * csr_neighbor_roam_issue_preauth_reassoc() -issues preauth_reassoc request + * @mac: MAC context + * + * This function issues preauth_reassoc request to PE with the 1st AP + * entry in the roamable AP list + * + * Return: eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise + */ +eHalStatus csr_neighbor_roam_issue_preauth_reassoc(tpAniSirGlobal mac) +{ + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamBSSInfo neighbor_bss_node; + tCsrRoamInfo roam_info; + + VOS_ASSERT(neighbor_roam_info->FTRoamInfo.preauthRspPending == + eANI_BOOLEAN_FALSE); + + neighbor_bss_node = csrNeighborRoamGetRoamableAPListNextEntry(mac, + &neighbor_roam_info->roamableAPList, NULL); + + if (neighbor_bss_node == NULL) + { + smsLog(mac, LOGE, FL("Roamable AP list is empty")); + csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_RESTART, + REASON_NO_CAND_FOUND_OR_NOT_ROAMING_NOW); + return eHAL_STATUS_FAILURE; + } + else + { + /* + * Set is_preauth_lfr_mbb which will be checked in + * different API's. + */ + mac->ft.ftSmeContext.is_preauth_lfr_mbb = true; + smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"), + mac->ft.ftSmeContext.is_preauth_lfr_mbb); + + status = csrRoamEnqueuePreauth(mac, + neighbor_roam_info->csrSessionId, + neighbor_bss_node->pBssDescription, + ecsr_mbb_perform_preauth_reassoc, + eANI_BOOLEAN_TRUE); + + smsLog(mac, LOG1, FL("Before Pre-Auth: BSSID "MAC_ADDRESS_STR", Ch:%d"), + MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId), + neighbor_bss_node->pBssDescription->channelId); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(mac, LOGE, + FL("Send Preauth request to PE failed with status %d"), + status); + return status; + } + } + + neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE; + + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC) + + if (csrRoamIsFastRoamEnabled(mac, CSR_SESSION_ID_INVALID)) + { + smsLog(mac, LOG1, FL("Invoking eCSR_ROAM_PMK_NOTIFY")); + vos_mem_copy((void *)&roam_info.bssid, + (void *)neighbor_bss_node->pBssDescription->bssId, + sizeof(tCsrBssid)); + csrRoamCallCallback(mac, neighbor_roam_info->csrSessionId, &roam_info, + 0, eCSR_ROAM_PMK_NOTIFY, 0); + } + return status; +} + +/** + * csr_stop_preauth_reassoc_mbb_timer() -stops preauth_reassoc timer + * @mac: MAC context + * + * This function stops preauth_reassoc timer + * + */ +void csr_stop_preauth_reassoc_mbb_timer(tpAniSirGlobal mac) +{ + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + + if (mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started) { + vos_status = + vos_timer_stop(&mac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer); + mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = + false; + } +} + + +/** + * csr_preauth_reassoc_mbb_timer_callback() -preauth_reassoc timer callback + * @mac: MAC context + * + * This function issues preauth_reassoc with another roamable entry + * + */ +void csr_preauth_reassoc_mbb_timer_callback(void *context) +{ + tpAniSirGlobal mac = (tpAniSirGlobal)context; + + mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = 0; + + smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"), + mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started); + + csr_neighbor_roam_issue_preauth_reassoc(mac); +} + + +/** + * csr_roam_dequeue_preauth_reassoc() -Dequeues + * ecsr_mbb_perform_preauth_reassoc + * @mac: MAC context + * + * This function dequeues ecsr_mbb_perform_preauth_reassoc + * + */ +eHalStatus csr_roam_dequeue_preauth_reassoc(tpAniSirGlobal mac) +{ + tListElem *entry; + tSmeCmd *command; + entry = csrLLPeekHead(&mac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (entry) { + command = GET_BASE_ADDR(entry, tSmeCmd, Link); + if ((eSmeCommandRoam == command->command) && + (ecsr_mbb_perform_preauth_reassoc == + command->u.roamCmd.roamReason)) { + smsLog(mac, LOG1, FL("DQ-Command = %d, Reason = %d"), + command->command, command->u.roamCmd.roamReason); + if (csrLLRemoveEntry( &mac->sme.smeCmdActiveList, + entry, LL_ACCESS_LOCK)) { + csrReleaseCommandPreauth( mac, command ); + } + } else { + smsLog(mac, LOGE, FL("Command = %d, Reason = %d "), + command->command, command->u.roamCmd.roamReason); + } + } + else { + smsLog(mac, LOGE, + FL("pEntry NULL for eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP")); + } + smeProcessPendingQueue( mac ); + return eHAL_STATUS_SUCCESS; +} + +/** + * csr_neighbor_roam_preauth_reassoc_rsp_handler() -handles preauth + * reassoc response + * @mac: MAC context + * @lim_status: status of preauth reassoc response from lim + * @bss_description: bss description pointer + * + * This function handles preauth_reassoc response from PE. When + * preauth_reassoc response failure is received, preauth reassoc + * with new candidate will be attempted. In success case, candidate will be + * removed from roamable entry. + * + */ +eHalStatus +csr_neighbor_roam_preauth_reassoc_rsp_handler(tpAniSirGlobal mac, + tSirRetStatus lim_status, tSirBssDescription **bss_description) +{ + tpCsrNeighborRoamControlInfo neighbor_roam_info = + &mac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + eHalStatus preauth_processed = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamBSSInfo preauth_rsp_node = NULL; + + if (eANI_BOOLEAN_FALSE == + neighbor_roam_info->FTRoamInfo.preauthRspPending) { + /* + * This can happen when we disconnect immediately after sending + * a pre-auth request. During processing of the disconnect command, + * we would have reset preauthRspPending and transitioned to INIT state. + */ + smsLog(mac, LOGE, + FL("Unexpected pre-auth response in state %d"), + neighbor_roam_info->neighborRoamState); + preauth_processed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + + if ((neighbor_roam_info->neighborRoamState != + eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC)) { + smsLog(mac, LOGE, + FL("Preauth response received in state %s"), + macTraceGetNeighbourRoamState( + neighbor_roam_info->neighborRoamState)); + preauth_processed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + + neighbor_roam_info->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE; + + if (eSIR_SUCCESS == lim_status) + preauth_rsp_node = csrNeighborRoamGetRoamableAPListNextEntry(mac, + &neighbor_roam_info->roamableAPList, NULL); + + if ((eSIR_SUCCESS == lim_status) && (NULL != preauth_rsp_node)) { + smsLog(mac, LOG1, FL("MBB Reassoc completed successfully")); + + smsLog(mac, LOG1, FL("After MBB reassoc BSSID "MAC_ADDRESS_STR" Ch %d"), + MAC_ADDR_ARRAY(preauth_rsp_node->pBssDescription->bssId), + preauth_rsp_node->pBssDescription->channelId); + + /* Memory will be freed in caller of this */ + *bss_description = (tpSirBssDescription)vos_mem_malloc( + sizeof(preauth_rsp_node->pBssDescription->length) + + preauth_rsp_node->pBssDescription->length); + if (NULL == *bss_description) { + smsLog(mac, LOGE, + FL("Unable to allocate memory for preauth bss description")); + preauth_processed = eHAL_STATUS_RESOURCES; + goto DEQ_PREAUTH; + } + + vos_mem_copy(*bss_description, preauth_rsp_node->pBssDescription, + sizeof(preauth_rsp_node->pBssDescription->length) + + preauth_rsp_node->pBssDescription->length); + + /* + * MBB Reassoc competer successfully. Insert the preauthenticated + * node to tail of preAuthDoneList + */ + csrNeighborRoamRemoveRoamableAPListEntry(mac, + &neighbor_roam_info->roamableAPList, preauth_rsp_node); + csrLLInsertTail(&neighbor_roam_info->FTRoamInfo.preAuthDoneList, + &preauth_rsp_node->List, LL_ACCESS_LOCK); + return eHAL_STATUS_SUCCESS; + } else { + tpCsrNeighborRoamBSSInfo neighbor_bss_node = NULL; + tListElem *entry; + + /* + * Pre-auth failed. Add the bssId to the preAuth failed list MAC Address. + * Also remove the AP from roamable AP list. The one in the head of the + * list should be one with which we issued pre-auth and failed. + */ + entry = csrLLRemoveHead(&neighbor_roam_info->roamableAPList, + LL_ACCESS_LOCK); + if(entry) { + neighbor_bss_node = GET_BASE_ADDR(entry, + tCsrNeighborRoamBSSInfo, List); + /* + * Add the BSSID to pre-auth fail list if it is + * not requested by HDD + */ + status = csrNeighborRoamAddBssIdToPreauthFailList(mac, + neighbor_bss_node->pBssDescription->bssId); + + smsLog(mac, LOG1, + FL("MBB reassoc failed BSSID "MAC_ADDRESS_STR" Ch:%d status %d"), + MAC_ADDR_ARRAY(neighbor_bss_node->pBssDescription->bssId), + neighbor_bss_node->pBssDescription->channelId, lim_status); + + /* Now we can free this node */ + csrNeighborRoamFreeNeighborRoamBSSNode(mac, neighbor_bss_node); + } + + /* + * Move state to Connected. Connected state here signifies connection + * with current AP as preauth failed with roamable AP. Still driver has + * connection with current AP. + */ + CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED) + + /* Start a timer to issue preauth_reassoc request for the next entry*/ + status = vos_timer_start(&mac->ft.ftSmeContext. + pre_auth_reassoc_mbb_timer, PREAUTH_REASSOC_MBB_TIMER_VALUE); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(mac, LOGE, + FL("pre_auth_reassoc_mbb_timer start failed status %d"), + status); + preauth_processed = eHAL_STATUS_FAILURE; + goto DEQ_PREAUTH; + } + mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started = true; + smsLog(mac, LOG1, FL("is_pre_auth_reassoc_mbb_timer_started %d"), + mac->roam.neighborRoamInfo.is_pre_auth_reassoc_mbb_timer_started); + preauth_processed = eHAL_STATUS_SUCCESS; + } + +DEQ_PREAUTH: + csr_roam_dequeue_preauth_reassoc(mac); + return preauth_processed; +} + +eHalStatus csr_update_roamed_info_mbb(tHalHandle hal, + tpSirBssDescription bss_description, tpSirFTPreAuthRsp pre_auth_rsp) +{ + eHalStatus status; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + tDot11fBeaconIEs *ies_local = NULL; + tCsrRoamSession *session = NULL; + tCsrRoamProfile *profile; + tSirMacAddr broadcast_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + tANI_U32 key_timeout_interval; + tCsrRoamInfo roam_info; + sme_QosAssocInfo assoc_info; + tANI_U32 len; + tANI_U8 sme_session_id = pre_auth_rsp->smeSessionId; + tANI_U8 acm_mask = 0; + + /* Get profile */ + session = CSR_GET_SESSION(mac, sme_session_id); + + profile = vos_mem_malloc(sizeof(*profile)); + if (NULL == profile) { + smsLog(mac, LOGE, FL("Memory allocation failure for profile")); + return eHAL_STATUS_FAILURE; + } + + /* + * session->pCurRoamProfile is copied into csrNeighborRoamProfile + * in csr_roam_issue_preauth_reassoc_req as there is a chance of + * session->pCurRoamProfile getting freed when disconnect is issued + * from upper layer. + */ + status = csrRoamCopyProfile(mac, profile, + &mac->roam.neighborRoamInfo.csrNeighborRoamProfile); + if(!HAL_STATUS_SUCCESS(status)) { + smsLog(mac, LOGE, FL("Profile copy failed")); + vos_mem_free(profile); + return status; + } + + profile->negotiatedAuthType = + mac->roam.roamSession[sme_session_id].connectedProfile.AuthType; + profile->negotiatedUCEncryptionType = + mac->roam.roamSession[sme_session_id].connectedProfile.EncryptionType; + profile->mcEncryptionType = + mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionInfo; + profile->negotiatedMCEncryptionType = + mac->roam.roamSession[sme_session_id].connectedProfile.mcEncryptionType; + + smsLog(mac, LOG1, + FL("AuthType %d UCEType %d Entries %d encryptionType %d MCEType %d"), + profile->negotiatedAuthType, + profile->negotiatedUCEncryptionType, + profile->mcEncryptionType.numEntries, + profile->mcEncryptionType.encryptionType[0], + profile->negotiatedMCEncryptionType); + + /* Get IE's */ + status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(mac, LOGE, + FL("csrGetParsedBssDescriptionIEs failed")); + vos_mem_free(profile); + return status; + } + if(ies_local == NULL) { + smsLog(mac, LOGE, + FL("ies_local is NULL ")); + vos_mem_free(profile); + return eHAL_STATUS_FAILURE; + } + + vos_mem_set(&roam_info, sizeof(roam_info), 0); + + csrRoamStopNetwork(mac, sme_session_id, profile, + bss_description, ies_local); + + session->connectState = eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED; + + csrRoamSaveConnectedInfomation(mac, sme_session_id, profile, + bss_description, ies_local); + csrRoamSaveSecurityRspIE(mac, sme_session_id, + profile->negotiatedAuthType, bss_description, + ies_local); + + csrRoamStateChange(mac, eCSR_ROAMING_STATE_JOINED, sme_session_id); + + /* + * If abortConnection is set, it implies that disconnect in progress + * from upper layer. So there is no point in proceeding further. + * By this point, pConnectBssDesc is updated in + * csrRoamSaveConnectedInfomation. This pConnectBssDesc is used + * during processing of disconnect in CSR and this has new BSSID info. + * By this time, original AP related info was cleaned up in LIM. So, + * disconnect queued while roaming in progress will take care of + * cleaning up roamed AP related info in LIM. + */ + if (session->abortConnection) { + smsLog(mac, LOGE, FL("Disconnect in progress")); + + smsLog(mac, LOGE, FL("MBB reassoc BSSID "MAC_ADDRESS_STR" Ch %d"), + MAC_ADDR_ARRAY(bss_description->bssId), + bss_description->channelId); + + vos_mem_free(profile); + return eHAL_STATUS_FAILURE; + } + + if(CSR_IS_ENC_TYPE_STATIC(profile->negotiatedUCEncryptionType) && + !profile->bWPSAssociation) { + /* + * Issue the set Context request to LIM to establish the + * Unicast STA context + */ + if(!HAL_STATUS_SUCCESS(csrRoamIssueSetContextReq(mac, + sme_session_id, + profile->negotiatedUCEncryptionType, + bss_description, &(bss_description->bssId), FALSE, TRUE, + eSIR_TX_RX, 0, 0, NULL, 0))) { + smsLog(mac, LOGE, FL("Set context for unicast fail")); + csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE, + sme_session_id); + } + /* + * Issue the set Context request to LIM to establish the + * Broadcast STA context + */ + csrRoamIssueSetContextReq(mac, sme_session_id, + profile->negotiatedMCEncryptionType, + bss_description, &broadcast_mac, + FALSE, FALSE, eSIR_TX_RX, 0, 0, NULL, 0); + } else if (!session->abortConnection) { + /* Need to wait for supplicant authtication */ + roam_info.fAuthRequired = eANI_BOOLEAN_TRUE; + /* Set the subestate to WaitForKey in case authentiation is needed */ + csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY, + sme_session_id); + + if(profile->bWPSAssociation) + key_timeout_interval = CSR_WAIT_FOR_WPS_KEY_TIMEOUT_PERIOD; + else + key_timeout_interval = CSR_WAIT_FOR_KEY_TIMEOUT_PERIOD; + + /* Save sessionId in case of timeout */ + mac->roam.WaitForKeyTimerInfo.sessionId = sme_session_id; + /* + * This time should be long enough for the rest of the + * process plus setting key + */ + if(!HAL_STATUS_SUCCESS(csrRoamStartWaitForKeyTimer(mac, + key_timeout_interval))) { + /* Reset our state so nothting is blocked */ + smsLog(mac, LOGE, FL("Failed to start pre-auth timer")); + csrRoamSubstateChange(mac, eCSR_ROAM_SUBSTATE_NONE, + sme_session_id); + } + } + + csrRoamFreeConnectedInfo(mac, &session->connectedInfo); + + assoc_info.pBssDesc = bss_description; + assoc_info.pProfile = profile; + + len = pre_auth_rsp->roam_info->nBeaconLength + + pre_auth_rsp->roam_info->nAssocReqLength + + pre_auth_rsp->roam_info->nAssocRspLength; + + if(len) { + session->connectedInfo.pbFrames = vos_mem_malloc(len); + if (session->connectedInfo.pbFrames != NULL ) { + vos_mem_copy(session->connectedInfo.pbFrames, + pre_auth_rsp->roam_info->pbFrames, len); + session->connectedInfo.nAssocReqLength = + pre_auth_rsp->roam_info->nAssocReqLength; + session->connectedInfo.nAssocRspLength = + pre_auth_rsp->roam_info->nAssocRspLength; + session->connectedInfo.nBeaconLength = + pre_auth_rsp->roam_info->nBeaconLength; + + roam_info.nAssocReqLength = pre_auth_rsp->roam_info->nAssocReqLength; + roam_info.nAssocRspLength = pre_auth_rsp->roam_info->nAssocRspLength; + roam_info.nBeaconLength = pre_auth_rsp->roam_info->nBeaconLength; + roam_info.pbFrames = session->connectedInfo.pbFrames; + } + session->connectedInfo.staId = pre_auth_rsp->roam_info->staId; + roam_info.staId = pre_auth_rsp->roam_info->staId; + roam_info.ucastSig = pre_auth_rsp->roam_info->ucastSig; + roam_info.bcastSig = pre_auth_rsp->roam_info->bcastSig; + roam_info.maxRateFlags = pre_auth_rsp->roam_info->maxRateFlags; + } + + roam_info.statusCode = eSIR_SME_SUCCESS; + roam_info.reasonCode = eSIR_SME_SUCCESS; + roam_info.pBssDesc = bss_description; + + vos_mem_copy(&roam_info.bssid, &bss_description->bssId, + sizeof(tCsrBssid)); + + mac->roam.roamSession[sme_session_id].connectState = + eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; + + sme_QosCsrEventInd(mac, sme_session_id, + SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL); + sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_REASSOC_REQ, NULL); + sme_QosCsrEventInd(mac, sme_session_id, SME_QOS_CSR_HANDOFF_COMPLETE, NULL); + + mac->roam.roamSession[sme_session_id].connectState = + eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED; + sme_QosCsrEventInd(mac, sme_session_id, + SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info); + + + acm_mask = sme_QosGetACMMask(mac, bss_description, NULL); + + session->connectedProfile.acm_mask = acm_mask; + if(session->connectedProfile.modifyProfileFields.uapsd_mask) { + smsLog(mac, LOGE, "uapsd_mask (0x%X) set, request UAPSD now", + session->connectedProfile.modifyProfileFields.uapsd_mask); + pmcStartUapsd(mac, NULL, NULL); + } + session->connectedProfile.dot11Mode = session->bssParams.uCfgDot11Mode; + roam_info.u.pConnectedProfile = &session->connectedProfile; + + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION) && + (csrIsConcurrentSessionRunning(mac))) + mac->roam.configParam.doBMPSWorkaround = 1; + + csr_roam_dequeue_preauth_reassoc(mac); + + csrRoamCallCallback(mac, sme_session_id, &roam_info, 0, + eCSR_ROAM_ASSOCIATION_COMPLETION, eCSR_ROAM_RESULT_ASSOCIATED); + + csrResetPMKIDCandidateList(mac, sme_session_id); +#ifdef FEATURE_WLAN_WAPI + csrResetBKIDCandidateList(mac, sme_session_id); +#endif + + if(!CSR_IS_WAIT_FOR_KEY(mac, sme_session_id)) { + smsLog(mac, LOG1, "NO CSR_IS_WAIT_FOR_KEY -> csr_roam_link_up"); + csrRoamLinkUp(mac, session->connectedProfile.bssid); + } + + if (pmcShouldBmpsTimerRun(mac)) { + if(eANI_BOOLEAN_TRUE == roam_info.fAuthRequired) { + mac->pmc.full_power_till_set_key = true; + smsLog(mac, LOG1, + FL("full_power_till_set_key is made true")); + } + + if (pmcStartTrafficTimer(mac, BMPS_TRAFFIC_TIMER_ALLOW_SECURITY_DHCP) + != eHAL_STATUS_SUCCESS) + smsLog(mac, LOGE, FL("Cannot start BMPS Retry timer")); + + smsLog(mac, LOG1, FL("BMPS Retry Timer already running or started")); + } + + vos_mem_free(pre_auth_rsp->roam_info->pbFrames); + vos_mem_free(pre_auth_rsp->roam_info); + vos_mem_free(profile); + vos_mem_free(ies_local); + + return eHAL_STATUS_SUCCESS; +} + + +/** + * csr_roam_preauth_rsp_mbb_processor() -handles + * eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP + * @hal: HAL context + * + * This function invokes preauth reassoc response handler and + * updates CSR with new connection information. + * + */ +void csr_roam_preauth_rsp_mbb_processor(tHalHandle hal, + tpSirFTPreAuthRsp pre_auth_rsp) +{ + tpAniSirGlobal mac = PMAC_STRUCT(hal); + eHalStatus status; + tCsrRoamInfo roam_info; + tpSirBssDescription bss_description = NULL; + tCsrRoamSession *session = NULL; + + mac->ft.ftSmeContext.is_preauth_lfr_mbb = false; + smsLog(mac, LOG1, FL("is_preauth_lfr_mbb %d"), + mac->ft.ftSmeContext.is_preauth_lfr_mbb); + + /* + * When reason is SIR_MBB_DISCONNECTED, cleanup CSR info + * of connected AP. + */ + if (pre_auth_rsp->reason == SIR_MBB_DISCONNECTED) { + /* Dequeue ecsr_perform_preauth_reassoc */ + csr_roam_dequeue_preauth_reassoc(mac); + + vos_mem_zero(&roam_info, sizeof(tCsrRoamInfo)); + csrRoamCallCallback(mac, pre_auth_rsp->smeSessionId, &roam_info, 0, + eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS); + + csrRoamComplete(mac, eCsrJoinFailure, NULL); + } + + status = csr_neighbor_roam_preauth_reassoc_rsp_handler(mac, + pre_auth_rsp->status, &bss_description); + if (status != eHAL_STATUS_SUCCESS) { + smsLog(mac, LOGE,FL("Preauth was not processed: %d SessionID: %d"), + status, pre_auth_rsp->smeSessionId); + /* + * Preauth_reassoc is dequeued already in + * csr_neighbor_roam_preauth_reassoc_rsp_handler for error cases. + */ + return; + } + + session = CSR_GET_SESSION(mac, pre_auth_rsp->smeSessionId); + if (session->abortConnection) { + smsLog(mac, LOGE, + FL("Disconnect in progress, stop preauth/reassoc timer")); + vos_timer_stop(&mac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer); + } + + /* + * The below function calls/timers should be invoked only + * if the pre-auth is successful. Also, Preauth_reassoc is dequeued + * already in csr_neighbor_roam_preauth_reassoc_rsp_handler. + */ + if (VOS_STATUS_SUCCESS != (VOS_STATUS)pre_auth_rsp->status) + return; + + mac->ft.ftSmeContext.FTState = eFT_AUTH_COMPLETE; + + /* Save the received response */ + vos_mem_copy((void *)&mac->ft.ftSmeContext.preAuthbssId, + (void *)pre_auth_rsp->preAuthbssId, sizeof(tCsrBssid)); + + + /* + * bss_description is updated in + * csr_neighbor_roam_preauth_reassoc_rsp_handler + */ + if (NULL == bss_description) { + smsLog(mac, LOGE, + FL("bss description is NULL")); + goto DEQ_PREAUTH; + } + + /* Update CSR for new connection */ + status = csr_update_roamed_info_mbb(hal, bss_description, pre_auth_rsp); + /* In success case preauth reassoc is dequeued in + * csr_update_roamed_info_mbb before updating HDD. + */ + if(HAL_STATUS_SUCCESS(status)) + return; + +DEQ_PREAUTH: + csr_roam_dequeue_preauth_reassoc(mac); +} + +/** + * csr_prepare_reassoc_req () - Prepares reassoc request + * @pmac: MAC context + * @session_id: session id + * @pbss_description: bss description + * @preassoc_req: pointer to reassociation request + * + *Return: None + */ +static void csr_prepare_reassoc_req(void* pmac, tANI_U32 session_id, + void* pbss_description, void *preassoc_req) +{ + tDot11fBeaconIEs *ies_local = NULL; + eHalStatus status; + tpAniSirGlobal mac = (tpAniSirGlobal)pmac; + tpSirBssDescription bss_description = (tpSirBssDescription)pbss_description; + tSirSmeJoinReq **reassoc_req = (tSirSmeJoinReq **)preassoc_req; + + /* Get IE's */ + status = csrGetParsedBssDescriptionIEs(mac, bss_description, &ies_local); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(mac, LOGE, + FL("csrGetParsedBssDescriptionIEs failed")); + return; + } + if(ies_local == NULL) { + smsLog(mac, LOGE, + FL("ies_local is NULL")); + return; + } + + smsLog(mac, LOG1, FL("session_id %d"), session_id); + + status = csr_fill_reassoc_req(mac, session_id, bss_description, + ies_local, reassoc_req); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(mac, LOGE, + FL("Reassociation request filling failed")); + return; + } + vos_mem_free(ies_local); + smsLog(mac, LOG1, FL("status %d"), status); +} + +/** + * csr_roaming_mbb_callback () - handles mbb callback + * @pmac: MAC context + * @session_id: session id + * @pbss_description: bss description + * @preassoc_req: pointer to reassociation request + * @csr_roam_op_code: callback opcode + * + *Return: None + */ +static void csr_roaming_mbb_callback(void* pmac, tANI_U32 session_id, + void* pbss_description, void *preassoc_req, tANI_U32 csr_roam_op_code) +{ + tpAniSirGlobal mac = (tpAniSirGlobal)pmac; + + smsLog(mac, LOG1, + FL("csr_roam_op_code %d"), csr_roam_op_code); + + switch(csr_roam_op_code) { + case SIR_ROAMING_DEREGISTER_STA: + csrRoamCallCallback(mac, session_id, NULL, 0, + eCSR_ROAM_FT_START, eSIR_SME_SUCCESS); + break; + case SIR_STOP_ROAM_OFFLOAD_SCAN: + csrRoamOffloadScan(mac, ROAM_SCAN_OFFLOAD_STOP, REASON_DISCONNECTED); + break; + case SIR_PREPARE_REASSOC_REQ: + csr_prepare_reassoc_req(pmac, session_id, pbss_description, + preassoc_req); + break; + } +} + +/** + * csr_register_roaming_mbb_callback () - registers roaming callback + * @mac: MAC context + * + *Return: eHAL_STATUS_SUCCESS on success, otherwise failure + */ +eHalStatus csr_register_roaming_mbb_callback(tpAniSirGlobal mac) +{ + eHalStatus status; + + status = sme_AcquireGlobalLock(&mac->sme); + if (eHAL_STATUS_SUCCESS == status) { + mac->sme.roaming_mbb_callback = csr_roaming_mbb_callback; + sme_ReleaseGlobalLock(&mac->sme); + } else + smsLog(mac, LOGE, + FL("sme_AcquireGlobalLock error")); + return status; +} diff --git a/drivers/staging/prima/CORE/SME/src/nan/nan_Api.c b/drivers/staging/prima/CORE/SME/src/nan/nan_Api.c new file mode 100644 index 000000000000..3ccf954c2999 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/nan/nan_Api.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "sme_Api.h" +#include "smsDebug.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "limApi.h" +#include "cfgApi.h" + +/****************************************************************************** + * Function: sme_NanRegisterCallback + * + * Description: + * This function gets called when HDD wants register nan rsp callback with + * sme layer. + * + * Args: + * hHal and callback which needs to be registered. + * + * Returns: + * void + *****************************************************************************/ +void sme_NanRegisterCallback(tHalHandle hHal, NanCallback callback) +{ + tpAniSirGlobal pMac = NULL; + + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("hHal is not valid")); + return; + } + pMac = PMAC_STRUCT(hHal); + pMac->sme.nanCallback = callback; +} + +/****************************************************************************** + * Function: sme_NanRequest + * + * Description: + * This function gets called when HDD receives NAN vendor command + * from userspace + * + * Args: + * hHal, Nan Request structure ptr and sessionId + * + * Returns: + * VOS_STATUS + *****************************************************************************/ +VOS_STATUS sme_NanRequest(tHalHandle hHalHandle, tpNanRequestReq input, + tANI_U32 sessionId) +{ + tNanRequest *pNanReq = NULL; + size_t data_len; + tSmeCmd *pCommand; + tpAniSirGlobal pMac = PMAC_STRUCT(hHalHandle); + + pCommand = csrGetCommandBuffer(pMac); + if (NULL == pCommand) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed to get command buffer for nan req")); + return eHAL_STATUS_RESOURCES; + } + + data_len = sizeof(tNanRequest) - sizeof(pNanReq->request_data) + + input->request_data_len; + pNanReq = vos_mem_malloc(data_len); + + if (pNanReq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Memory allocation failure, size : %zu"), data_len); + csrReleaseCommand(pMac, pCommand); + return eHAL_STATUS_RESOURCES; + } + + smsLog(pMac, LOG1, "Posting NAN command to csr queue"); + vos_mem_zero(pNanReq, data_len); + pNanReq->request_data_len = input->request_data_len; + vos_mem_copy(pNanReq->request_data, + input->request_data, + input->request_data_len); + + pCommand->command = eSmeCommandNanReq; + pCommand->sessionId = sessionId; + pCommand->u.pNanReq = pNanReq; + + if (!HAL_STATUS_SUCCESS(csrQueueSmeCommand(pMac, pCommand, TRUE))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to post eSmeCommandNanReq command")); + csrReleaseCommand(pMac, pCommand); + vos_mem_free(pNanReq); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +/****************************************************************************** + * Function: sme_NanEvent + * + * Description: + * This callback function will be called when SME received eWNI_SME_NAN_EVENT + * event from WMA + * + * Args: + * hHal - HAL handle for device + * pMsg - Message body passed from WDA; includes NAN header + * + * Returns: + * VOS_STATUS +******************************************************************************/ +VOS_STATUS sme_NanEvent(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("msg ptr is NULL")); + status = VOS_STATUS_E_FAILURE; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + FL("SME: Received sme_NanEvent")); + if (pMac->sme.nanCallback) + { + pMac->sme.nanCallback(pMac->hHdd, (tSirNanEvent *)pMsg); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("nanCallback is NULL")); + } + } + + return status; +} diff --git a/drivers/staging/prima/CORE/SME/src/oemData/oemDataApi.c b/drivers/staging/prima/CORE/SME/src/oemData/oemDataApi.c new file mode 100644 index 000000000000..2227b60ace29 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/oemData/oemDataApi.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file oemDataApi.c + + Implementation for the OEM DATA REQ/RSP interfaces. + ========================================================================== */ +#include "aniGlobal.h" +#include "oemDataApi.h" +#include "palApi.h" +#include "smeInside.h" +#include "smsDebug.h" + +#include "csrSupport.h" +#include "wlan_qct_tl.h" + +#include "vos_diag_core_log.h" +#include "vos_diag_core_event.h" + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqOpen + \brief This function must be called before any API call to (OEM DATA REQ/RSP module) + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqOpen(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //initialize all the variables to null + vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, "oemData_OemDataReqOpen: Cannot allocate memory for the timer function"); + break; + } + } while(0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReqClose + \brief This function must be called before closing the csr module + \return eHalStatus + -------------------------------------------------------------------------------*/ + +eHalStatus oemData_OemDataReqClose(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, "oemData_OemDataReqClose: Failed in oemData_OemDataReqClose at StopTimers"); + break; + } + + if(pMac->oemData.pOemDataRsp != NULL) + { + vos_mem_free(pMac->oemData.pOemDataRsp); + } + + //initialize all the variables to null + vos_mem_set(&(pMac->oemData), sizeof(tOemDataStruct), 0); + } while(0); + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn oemData_ReleaseOemDataReqCommand + \brief This function removes the oemDataCommand from the active list and + and frees up any memory occupied by this + \return eHalStatus + -------------------------------------------------------------------------------*/ +void oemData_ReleaseOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataCmd, eOemDataReqStatus oemDataReqStatus) +{ + //Do the callback + pOemDataCmd->u.oemDataCmd.callback(pMac, pOemDataCmd->u.oemDataCmd.pContext, pOemDataCmd->u.oemDataCmd.oemDataReqID, oemDataReqStatus); + + //First take this command out of the active list + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, &pOemDataCmd->Link, LL_ACCESS_LOCK)) + { + vos_mem_set(&(pOemDataCmd->u.oemDataCmd), sizeof(tOemDataCmd), 0); + + //Now put this command back on the avilable command list + smeReleaseCommand(pMac, pOemDataCmd); + } + else + { + smsLog(pMac, LOGE, "OEM_DATA: **************** oemData_ReleaseOemDataReqCommand cannot release the command"); + } +} + +/* --------------------------------------------------------------------------- + \fn oemData_OemDataReq + \brief Request an OEM DATA RSP + \param sessionId - Id of session to be used + \param pOemDataReqID - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_OemDataReq(tHalHandle hHal, + tANI_U8 sessionId, + tOemDataReqConfig *oemDataReqConfig, + tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tSmeCmd *pOemDataCmd = NULL; + + do + { + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = eHAL_STATUS_FAILURE; + break; + } + + pMac->oemData.oemDataReqConfig.sessionId = sessionId; + pMac->oemData.callback = callback; + pMac->oemData.pContext = pContext; + pMac->oemData.oemDataReqID = *(pOemDataReqID); + + vos_mem_copy((v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), + (v_VOID_t*)(oemDataReqConfig->oemDataReq), + OEM_DATA_REQ_SIZE); + + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + + pOemDataCmd = smeGetCommandBuffer(pMac); + + //fill up the command before posting it. + if(pOemDataCmd) + { + pOemDataCmd->command = eSmeCommandOemDataReq; + pOemDataCmd->u.oemDataCmd.callback = callback; + pOemDataCmd->u.oemDataCmd.pContext = pContext; + pOemDataCmd->u.oemDataCmd.oemDataReqID = pMac->oemData.oemDataReqID; + + //set the oem data request + pOemDataCmd->u.oemDataCmd.oemDataReq.sessionId = pMac->oemData.oemDataReqConfig.sessionId; + vos_mem_copy((v_VOID_t*)(pOemDataCmd->u.oemDataCmd.oemDataReq.oemDataReq), + (v_VOID_t*)(pMac->oemData.oemDataReqConfig.oemDataReq), + OEM_DATA_REQ_SIZE); + } + else + { + status = eHAL_STATUS_FAILURE; + break; + } + + //now queue this command in the sme command queue + //Here since this is not interacting with the csr just push the command + //into the sme queue. Also push this command with the normal priority + smePushCommand(pMac, pOemDataCmd, eANI_BOOLEAN_FALSE); + + } while(0); + + if(!HAL_STATUS_SUCCESS(status) && pOemDataCmd) + { + oemData_ReleaseOemDataReqCommand(pMac, pOemDataCmd, eOEM_DATA_REQ_FAILURE); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_SendMBOemDataReq + \brief Request an OEM DATA REQ to be passed down to PE + \param pMac: + \param pOemDataReq: Pointer to the oem data request + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_SendMBOemDataReq(tpAniSirGlobal pMac, tOemDataReq *pOemDataReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirOemDataReq* pMsg; + tANI_U16 msgLen; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, pOemDataReq->sessionId ); + + smsLog(pMac, LOGW, "OEM_DATA: entering Function %s", __func__); + + msgLen = (tANI_U16)(sizeof(tSirOemDataReq)); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if(HAL_STATUS_SUCCESS(status)) + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_OEM_DATA_REQ); + pMsg->messageLen = pal_cpu_to_be16(msgLen); + vos_mem_copy(pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr) ); + vos_mem_copy(pMsg->oemDataReq, pOemDataReq->oemDataReq, OEM_DATA_REQ_SIZE); + smsLog(pMac, LOGW, "OEM_DATA: sending message to pe%s", __func__); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + smsLog(pMac, LOGW, "OEM_DATA: exiting Function %s", __func__); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_ProcessOemDataReqCommand + \brief This function is called by the smeProcessCommand when the case hits + eSmeCommandOemDataReq + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_ProcessOemDataReqCommand(tpAniSirGlobal pMac, tSmeCmd *pOemDataReqCmd) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + //check if the system is in proper mode of operation for + //oem data req/rsp to be functional. Currently, concurrency is not + //supported and the driver must be operational only as + //STA for oem data req/rsp to be functional. We return an invalid + //mode flag if it is operational as any one of the following + //in any of the active sessions + //1. AP Mode + //2. IBSS Mode + //3. BTAMP Mode ... + + if(eHAL_STATUS_SUCCESS == oemData_IsOemDataReqAllowed(pMac)) + { + smsLog(pMac, LOG1, "%s: OEM_DATA REQ allowed in the current mode", __func__); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_TRUE; + status = oemData_SendMBOemDataReq(pMac, &(pOemDataReqCmd->u.oemDataCmd.oemDataReq)); + } + else + { + smsLog(pMac, LOG1, "%s: OEM_DATA REQ not allowed in the current mode", __func__); + status = eHAL_STATUS_FAILURE; + } + + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOG1, "%s: OEM_DATA Failure, Release command", __func__); + oemData_ReleaseOemDataReqCommand(pMac, pOemDataReqCmd, eOEM_DATA_REQ_INVALID_MODE); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_HandleOemDataRsp + \brief This function processes the oem data response obtained from the PE + \param pMsg - Pointer to the pSirOemDataRsp + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleOemDataRsp(tHalHandle hHal, tANI_U8* pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirOemDataRsp* pOemDataRsp = NULL; + pMac = PMAC_STRUCT(hHal); + + smsLog(pMac, LOG1, "%s: OEM_DATA Entering", __func__); + + do + { + if(pMsg == NULL) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if(pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if(eSmeCommandOemDataReq == pCommand->command) + { + pOemDataRsp = (tSirOemDataRsp*)pMsg; + + //make sure to acquire the lock before modifying the data + status = sme_AcquireGlobalLock(&pMac->sme); + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + + if(pMac->oemData.pOemDataRsp != NULL) + { + vos_mem_free(pMac->oemData.pOemDataRsp); + } + pMac->oemData.pOemDataRsp = (tOemDataRsp*)vos_mem_malloc(sizeof(tOemDataRsp)); + + if(pMac->oemData.pOemDataRsp == NULL) + { + sme_ReleaseGlobalLock(&pMac->sme); + smsLog(pMac, LOGE, "in %s vos_mem_malloc failed for pMac->oemData.pOemDataRsp", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + smsLog(pMac, LOGE, "Before memory copy"); + vos_mem_copy((v_VOID_t*)(pMac->oemData.pOemDataRsp), + (v_VOID_t*)(&pOemDataRsp->oemDataRsp), + sizeof(tOemDataRsp)); + smsLog(pMac, LOGE, "after memory copy"); + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO REQs are ACTIVE ...", + __func__); + status = eHAL_STATUS_FAILURE; + break; + } + } + else + { + smsLog(pMac, LOGE, "in %s eWNI_SME_OEM_DATA_RSP Received but NO commands are ACTIVE ...", __func__); + status = eHAL_STATUS_FAILURE; + break; + } + + oemData_ReleaseOemDataReqCommand(pMac, pCommand, eHAL_STATUS_SUCCESS); + pMac->oemData.oemDataReqActive = eANI_BOOLEAN_FALSE; + + } while(0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn oemData_IsOemDataReqAllowed + \brief This function checks if OEM DATA REQs can be performed in the + current driver state + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus oemData_IsOemDataReqAllowed(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 sessionId; + + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + for(sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + if(CSR_IS_SESSION_VALID(pMac, sessionId)) + { + //co-exist with IBSS or BT-AMP mode is not supported + if(csrIsConnStateIbss(pMac, sessionId) || csrIsBTAMP(pMac, sessionId) ) + { + //co-exist with IBSS or BT-AMP mode is not supported + smsLog(pMac, LOGW, "OEM DATA REQ is not allowed due to IBSS|BTAMP exist in session %d", sessionId); + status = eHAL_STATUS_CSR_WRONG_STATE; + break; + } + } + } + + smsLog(pMac, LOG1, "Exiting oemData_IsOemDataReqAllowed with status %d", status); + + return (status); +} + +#endif /*FEATURE_OEM_DATA_SUPPORT*/ diff --git a/drivers/staging/prima/CORE/SME/src/p2p/p2p_Api.c b/drivers/staging/prima/CORE/SME/src/p2p/p2p_Api.c new file mode 100644 index 000000000000..58bb906272f7 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/p2p/p2p_Api.c @@ -0,0 +1,2282 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include "sme_Api.h" +#include "smsDebug.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "p2p_Api.h" +#include "limApi.h" +#include "cfgApi.h" + +#ifdef WLAN_FEATURE_P2P_INTERNAL +#include "p2p_ie.h" +#include "p2pFsm.h" + +extern tp2pie gP2PIe; + +static eHalStatus p2pSendActionFrame(tpAniSirGlobal pMac, tANI_U8 SessionID, eP2PFrameType actionFrameType); +static eHalStatus p2pListenStateDiscoverableCallback(tHalHandle halHandle, void *pContext, eHalStatus retStatus); +static eHalStatus p2pRemainOnChannelReadyCallback(tHalHandle halHandle, void *pContext, eHalStatus scan_status); +static tANI_BOOLEAN p2pIsGOportEnabled(tpAniSirGlobal pMac); +#endif + +eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd); +/*------------------------------------------------------------------ + * + * Release RoC Request command. + * + *------------------------------------------------------------------*/ + +void csrReleaseRocReqCommand(tpAniSirGlobal pMac) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if ( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if ( eSmeCommandRemainOnChannel == pCommand->command ) + { + remainOnChanCallback callback = pCommand->u.remainChlCmd.callback; + /* process the msg */ + if ( callback ) + callback(pMac, pCommand->u.remainChlCmd.callbackCtx, 0); + smsLog(pMac, LOGE, FL("Remove RoC Request from Sme Active Cmd List ")); + if ( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + //Now put this command back on the avilable command list + smeReleaseCommand(pMac, pCommand); + } + } + } +} + + +/*------------------------------------------------------------------ + * + * handle SME remain on channel request. + * + *------------------------------------------------------------------*/ + +eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirRemainOnChnReq* pMsg; + tANI_U32 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, p2pRemainonChn->sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), p2pRemainonChn->sessionId); + status = eHAL_STATUS_FAILURE; + goto error; + } + +#ifdef WLAN_FEATURE_P2P_INTERNAL + tANI_U8 P2PsessionId = getP2PSessionIdFromSMESessionId(pMac, p2pRemainonChn->sessionId); + tp2pContext *p2pContext = &pMac->p2pContext[P2PsessionId]; + tANI_U32 ieLen = 0; +#endif + +#ifdef WLAN_FEATURE_P2P_INTERNAL + if( !pSession->sessionActive || (CSR_SESSION_ID_INVALID == P2PsessionId)) + { + smsLog(pMac, LOGE, FL(" session %d (P2P session %d) is invalid or listen is disabled "), + p2pRemainonChn->sessionId, P2PsessionId); + status = eHAL_STATUS_FAILURE; + goto error; + } +#else + if(!pSession->sessionActive) + { + smsLog(pMac, LOGE, FL(" session %d is invalid or listen is disabled "), + p2pRemainonChn->sessionId); + status = eHAL_STATUS_FAILURE; + goto error; + } +#endif +#ifdef WLAN_FEATURE_P2P_INTERNAL + P2P_GetIE(p2pContext, + p2pContext->sessionId, eP2P_PROBE_RSP, + &p2pContext->probeRspIe, &ieLen); + p2pContext->probeRspIeLength = ieLen; + len = sizeof(tSirRemainOnChnReq) + ieLen; +#else + len = sizeof(tSirRemainOnChnReq) + pMac->p2pContext.probeRspIeLength; +#endif + if( len > 0xFFFF ) + { + /*In coming len for Msg is more then 16bit value*/ + smsLog(pMac, LOGE, FL(" Message length is very large, %d"), + len); + status = eHAL_STATUS_FAILURE; + goto error; + } + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, FL("Msg memory alloc failed")); + status = eHAL_STATUS_FAILURE; + goto error; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s call", __func__); + vos_mem_set(pMsg, sizeof(tSirRemainOnChnReq), 0); + pMsg->messageType = eWNI_SME_REMAIN_ON_CHANNEL_REQ; + pMsg->length = (tANI_U16)len; + vos_mem_copy(pMsg->selfMacAddr, pSession->selfMacAddr, sizeof(tSirMacAddr)); + pMsg->chnNum = p2pRemainonChn->u.remainChlCmd.chn; + pMsg->phyMode = p2pRemainonChn->u.remainChlCmd.phyMode; + pMsg->duration = p2pRemainonChn->u.remainChlCmd.duration; + pMsg->sessionId = p2pRemainonChn->sessionId; + pMsg->isProbeRequestAllowed = p2pRemainonChn->u.remainChlCmd.isP2PProbeReqAllowed; +#ifdef WLAN_FEATURE_P2P_INTERNAL + pMsg->sessionId = pSession->sessionId; + if( p2pContext->probeRspIeLength ) + { + vos_mem_copy((void *)pMsg->probeRspIe, (void *)p2pContext->probeRspIe, + p2pContext->probeRspIeLength); + } +#else + if( pMac->p2pContext.probeRspIeLength ) + vos_mem_copy((void *)pMsg->probeRspIe, (void *)pMac->p2pContext.probeRspIe, + pMac->p2pContext.probeRspIeLength); +#endif + status = palSendMBMessage(pMac->hHdd, pMsg); + } + error: + if (eHAL_STATUS_FAILURE == status) + { + csrReleaseRocReqCommand(pMac); + } + return status; +} + + +/*------------------------------------------------------------------ + * + * handle LIM remain on channel rsp: Success/failure. + * + *------------------------------------------------------------------*/ + +eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tSirSmeRsp *pRsp = (tSirSmeRsp *)pMsg; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandRemainOnChannel == pCommand->command ) + { + remainOnChanCallback callback = pCommand->u.remainChlCmd.callback; + /* process the msg */ + if( callback ) + callback(pMac, pCommand->u.remainChlCmd.callbackCtx, + pRsp->statusCode); + + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + //Now put this command back on the avilable command list + smeReleaseCommand(pMac, pCommand); + } + smeProcessPendingQueue( pMac ); + } + } + return status; +} + +/*------------------------------------------------------------------ + * + * Handle the remain on channel ready indication from PE + * + *------------------------------------------------------------------*/ + +eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tCsrRoamInfo RoamInfo; +#ifdef WLAN_FEATURE_P2P_INTERNAL + tSirSmeRsp *pRsp = (tSirSmeRsp *)pMsg; + //pRsp->sessionId is SME's session index + tANI_U8 P2PSessionID = getP2PSessionIdFromSMESessionId(pMac, pRsp->sessionId); + + if(CSR_SESSION_ID_INVALID == P2PSessionID) + { + return eHAL_STATUS_FAILURE; + } +#endif + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if( pEntry ) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + if( eSmeCommandRemainOnChannel == pCommand->command ) + { + +#ifdef WLAN_FEATURE_P2P_INTERNAL + if (pMac->p2pContext[P2PSessionID].PeerFound) + { + p2pRemainOnChannelReadyCallback(pMac, &pMac->p2pContext[P2PSessionID], eHAL_STATUS_SUCCESS); + } +#else + /* forward the indication to HDD */ + RoamInfo.pRemainCtx = pCommand->u.remainChlCmd.callbackCtx; + csrRoamCallCallback(pMac, ((tSirSmeRsp*)pMsg)->sessionId, &RoamInfo, + 0, eCSR_ROAM_REMAIN_CHAN_READY, 0); +#endif + } + } + + return status; +} + + +eHalStatus sme_sendActionCnf( tHalHandle hHal, tANI_U8* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo RoamInfo; + tSirSmeRsp* pSmeRsp = (tSirSmeRsp*)pMsg; + +#ifdef WLAN_FEATURE_P2P_INTERNAL + tSirResultCodes rspStatus = pSmeRsp->statusCode; + tANI_U8 HDDsessionId = getP2PSessionIdFromSMESessionId(pMac, pSmeRsp->sessionId); + tANI_U8 *pBuf = NULL; + tp2pContext *pP2pContext; + + if(CSR_SESSION_ID_INVALID == HDDsessionId) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " %s fail to get HDD sessionID (SMESessionID %d)", __func__, pSmeRsp->sessionId); + return eHAL_STATUS_INVALID_PARAMETER; + } + + pP2pContext = &pMac->p2pContext[HDDsessionId]; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s status %d Action Frame %d actionFrameTimeout %d", + __func__, pSmeRsp->statusCode, pP2pContext->actionFrameType + , pP2pContext->actionFrameTimeout); + vos_mem_zero(&RoamInfo, sizeof(tCsrRoamInfo)); + + if (pSmeRsp->statusCode != eSIR_SME_SUCCESS && !pP2pContext->actionFrameTimeout + && pP2pContext->pSentActionFrame) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Action frame:Ack not received. Retransmitting", __func__); + + if(NULL == pP2pContext->pNextActionFrm) + { + status = vos_timer_start(&pP2pContext->retryActionFrameTimer, ACTION_FRAME_RETRY_TIMEOUT); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " %s fail to start retryActionFrameTimerHandler", + __func__, pP2pContext->NextActionFrameType); + } + return status; + } + //In case if there is new frame to send, finish the current frame + else + { + smsLog(pMac, LOGE, " %s send next action frame type %d Last frame status (%d)", + __func__, rspStatus); + //Force it to be success + rspStatus = eSIR_SME_SUCCESS; + } + } + + if (pP2pContext->actionFrameTimer) + { + vos_timer_stop(&pP2pContext->actionFrameTimer); + status = eHAL_STATUS_SUCCESS; + } + + if (pP2pContext->retryActionFrameTimer) + { + vos_timer_stop(&pP2pContext->retryActionFrameTimer); + status = eHAL_STATUS_SUCCESS; + } + + if(pP2pContext->pSentActionFrame) + { + csrRoamCallCallback((tpAniSirGlobal)pP2pContext->hHal, + pP2pContext->SMEsessionId, &RoamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + ((rspStatus == eSIR_SME_SUCCESS) ? + eCSR_ROAM_RESULT_NONE: eCSR_ROAM_RESULT_SEND_ACTION_FAIL)); + } + + if(VOS_IS_STATUS_SUCCESS(vos_spin_lock_acquire(&pP2pContext->lState))) + { + if(pP2pContext->pSentActionFrame) + { + pBuf = pP2pContext->pSentActionFrame; + pP2pContext->pSentActionFrame = NULL; + } + vos_spin_lock_release(&pP2pContext->lState); + + if(NULL != pBuf) + { + vos_mem_free(pBuf); + pBuf = NULL; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, "%s pSentActionFrame is null ", __func__); + } + if(pP2pContext->pNextActionFrm) + { + //need to send the next action frame + pP2pContext->pSentActionFrame = pP2pContext->pNextActionFrm; + pP2pContext->ActionFrameLen = pP2pContext->nNextFrmLen; + pP2pContext->actionFrameType = pP2pContext->NextActionFrameType; + pP2pContext->pNextActionFrm = NULL; + pP2pContext->ActionFrameSendTimeout = pP2pContext->nNextFrameTimeOut; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s cannot get lock1", __func__); + } + + if(NULL != pP2pContext->pSentActionFrame) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, " sending next frame %d type", + pP2pContext->NextActionFrameType); + status = vos_timer_start(&pP2pContext->actionFrameTimer, pP2pContext->ActionFrameSendTimeout); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" %s fail to start timer status %d"), __func__, status); + //Without the timer we cannot continue + csrRoamCallCallback((tpAniSirGlobal)pP2pContext->hHal, + pP2pContext->SMEsessionId, &RoamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + eCSR_ROAM_RESULT_SEND_ACTION_FAIL); + vos_spin_lock_acquire(&pP2pContext->lState); + pBuf = pP2pContext->pSentActionFrame; + pP2pContext->pSentActionFrame = NULL; + vos_spin_lock_release(&pP2pContext->lState); + vos_mem_free(pBuf); + pBuf = NULL; + p2pFsm(pP2pContext, eP2P_TRIGGER_DISCONNECTED); + return status; + } + status = p2pSendActionFrame(pMac, pP2pContext->sessionId, pP2pContext->actionFrameType); + if(!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, " sending next frame %d type", + pP2pContext->NextActionFrameType); + status = vos_timer_start(&pP2pContext->retryActionFrameTimer, ACTION_FRAME_RETRY_TIMEOUT); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " %s fail to start retryActionFrameTimerHandler", __func__); + } + } + } + else + { + p2pFsm(pP2pContext, eP2P_TRIGGER_DISCONNECTED); + } + +#else + /* forward the indication to HDD */ + //RoamInfo can be passed as NULL....todo + csrRoamCallCallback(pMac, pSmeRsp->sessionId, &RoamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + (pSmeRsp->statusCode == eSIR_SME_SUCCESS) ? 0: + eCSR_ROAM_RESULT_SEND_ACTION_FAIL); +#endif + return status; +} + + +#ifdef WLAN_FEATURE_P2P_INTERNAL +void p2pResetContext(tp2pContext *pP2pContext) +{ + if(NULL != pP2pContext) + { + tpAniSirGlobal pMac = PMAC_STRUCT(pP2pContext->hHal); + int i; + + //When it is resetting a GO or client session, we + //need to reset the group capability back to the original one + if( (OPERATION_MODE_P2P_GROUP_OWNER == pP2pContext->operatingmode) || + (OPERATION_MODE_P2P_CLIENT == pP2pContext->operatingmode) ) + { + for( i = 0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) + { + if(OPERATION_MODE_P2P_DEVICE == pMac->p2pContext[i].operatingmode) + { + gP2PIe[i].p2pCapabilityAttrib.groupCapability = pMac->p2pContext[i].OriginalGroupCapability; + } + } + } + + pP2pContext->state = eP2P_STATE_DISCONNECTED; + pP2pContext->currentSearchIndex = 0; + pP2pContext->listenIndex = 1; + + pP2pContext->actionFrameType = eP2P_INVALID_FRM; + + pP2pContext->dialogToken = 0; + pP2pContext->PeerFound = FALSE; + pP2pContext->GroupFormationPending = FALSE; + pP2pContext->directedDiscovery = FALSE; + pP2pContext->listenDiscoverableState = eStateDisabled; + + + if(pP2pContext->pSentActionFrame) + { + vos_mem_free(pP2pContext->pSentActionFrame); + pP2pContext->pSentActionFrame = NULL; + } + if(pP2pContext->pNextActionFrm) + { + vos_mem_free(pP2pContext->pSentActionFrame); + pP2pContext->pSentActionFrame = NULL; + } + if( pP2pContext->probeRspIe ) + { + vos_mem_free(pP2pContext->probeRspIe); + pP2pContext->probeRspIe = NULL; + pP2pContext->probeRspIeLength = 0; + } + + if( pP2pContext->DiscoverReqIeField ) + { + vos_mem_free(pP2pContext->DiscoverReqIeField); + pP2pContext->DiscoverReqIeField = NULL; + pP2pContext->DiscoverReqIeLength = 0; + } + + if( pP2pContext->GoNegoCnfIeField ) + { + vos_mem_free(pP2pContext->GoNegoCnfIeField); + pP2pContext->GoNegoCnfIeField = NULL; + pP2pContext->GoNegoCnfIeLength = 0; + } + + if( pP2pContext->GoNegoReqIeField ) + { + vos_mem_free(pP2pContext->GoNegoReqIeField); + pP2pContext->GoNegoReqIeField = NULL; + pP2pContext->GoNegoReqIeLength = 0; + } + + if( pP2pContext->GoNegoResIeField ) + { + vos_mem_free(pP2pContext->GoNegoResIeField); + pP2pContext->GoNegoResIeField = NULL; + pP2pContext->GoNegoResIeLength = 0; + } + + if( pP2pContext->ProvDiscReqIeField ) + { + vos_mem_free(pP2pContext->ProvDiscReqIeField); + pP2pContext->ProvDiscReqIeField = NULL; + pP2pContext->ProvDiscReqIeLength = 0; + } + + if( pP2pContext->ProvDiscResIeField ) + { + vos_mem_free(pP2pContext->ProvDiscResIeField); + pP2pContext->ProvDiscResIeLength = 0; + pP2pContext->ProvDiscResIeField = NULL; + } + + if (pP2pContext->actionFrameTimer) + { + vos_timer_stop(&pP2pContext->actionFrameTimer); + } + + if (pP2pContext->discoverTimer) + { + vos_timer_stop(&pP2pContext->discoverTimer); + } + + if (pP2pContext->listenTimerHandler) + { + vos_timer_stop(&pP2pContext->listenTimerHandler); + } + + if (pP2pContext->WPSRegistrarCheckTimerHandler) + { + vos_timer_stop(&pP2pContext->WPSRegistrarCheckTimerHandler); + } + + if (pP2pContext->directedDiscoveryFilter) + { + pP2pContext->uNumDeviceFilterAllocated = 0; + vos_mem_free(pP2pContext->directedDiscoveryFilter); + pP2pContext->directedDiscoveryFilter = NULL; + } + + vos_mem_zero(pP2pContext->peerMacAddress, P2P_MAC_ADDRESS_LEN); + } +} +#endif + + +eHalStatus sme_p2pOpen( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + +#ifdef WLAN_FEATURE_P2P_INTERNAL + int i; + tp2pContext *pP2pContext; + + for ( i=0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) + { + pP2pContext = &pMac->p2pContext[i]; + pP2pContext->hHal = hHal; + + pP2pContext->socialChannel[0] = 1; + pP2pContext->socialChannel[1] = 6; + pP2pContext->socialChannel[2] = 11; + + vos_spin_lock_init(&pP2pContext->lState); + + p2pResetContext(pP2pContext); + + status = vos_timer_init(&pP2pContext->actionFrameTimer, VOS_TIMER_TYPE_SW, p2pActionFrameTimerHandler, pP2pContext); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " %s fail to alloc actionFrame timer for session %d", __func__, i); + break; + } + status = vos_timer_init(&pP2pContext->listenTimerHandler, VOS_TIMER_TYPE_SW, + p2pListenDiscoverTimerHandler, pP2pContext); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " %s fail to alloc listen timer for session %d", __func__, i); + break; + } + status = vos_timer_init(&pP2pContext->discoverTimer, VOS_TIMER_TYPE_SW, p2pDiscoverTimerHandler, pP2pContext); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " %s fail to alloc discover timer for session %d", __func__, i); + break; + } + + status = vos_timer_init(&pP2pContext->retryActionFrameTimer, VOS_TIMER_TYPE_SW, + p2pRetryActionFrameTimerHandler, pP2pContext); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, " %s fail to alloc retryActionFrameTimerHandler timer for session %d", __func__, i); + break; + } + + p2pCreateDefaultIEs(hHal, i); + } +#else + //If static structure is too big, Need to change this function to allocate memory dynamically + vos_mem_zero(&pMac->p2pContext, sizeof( tp2pContext )); +#endif + + if(!HAL_STATUS_SUCCESS(status)) + { + sme_p2pClose(hHal); + } + + return status; +} + + +eHalStatus p2pStop( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef WLAN_FEATURE_P2P_INTERNAL + int i; + + for ( i = 0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) + { + p2pCloseSession(pMac, i); + } +#else + if( pMac->p2pContext.probeRspIe ) + { + vos_mem_free(pMac->p2pContext.probeRspIe); + pMac->p2pContext.probeRspIe = NULL; + } + + pMac->p2pContext.probeRspIeLength = 0; +#endif + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus sme_p2pClose( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef WLAN_FEATURE_P2P_INTERNAL + tp2pContext *pContext; + int i; + + p2pStop(hHal); + + for ( i = 0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) + { + p2pCloseSession(pMac, i); + pContext = &pMac->p2pContext[i]; + if (pContext->actionFrameTimer) + { + vos_timer_destroy(&pContext->actionFrameTimer); + pContext->actionFrameTimer = NULL; + } + + if (pContext->discoverTimer) + { + vos_timer_destroy(&pContext->discoverTimer); + pContext->discoverTimer = NULL; + } + + if (pContext->listenTimerHandler) + { + vos_timer_destroy(&pContext->listenTimerHandler); + pContext->listenTimerHandler = NULL; + } + + if (pContext->WPSRegistrarCheckTimerHandler) + { + vos_timer_destroy(&pContext->WPSRegistrarCheckTimerHandler); + pContext->WPSRegistrarCheckTimerHandler = NULL; + } + + vos_spin_lock_destroy(&pContext->lState); + } +#else + if( pMac->p2pContext.probeRspIe ) + { + vos_mem_free(pMac->p2pContext.probeRspIe); + pMac->p2pContext.probeRspIe = NULL; + } + + pMac->p2pContext.probeRspIeLength = 0; +#endif + + return eHAL_STATUS_SUCCESS; +} + + +tSirRFBand GetRFBand(tANI_U8 channel) +{ + if ((channel >= SIR_11A_CHANNEL_BEGIN) && + (channel <= SIR_11A_CHANNEL_END)) + return SIR_BAND_5_GHZ; + + if ((channel >= SIR_11B_CHANNEL_BEGIN) && + (channel <= SIR_11B_CHANNEL_END)) + return SIR_BAND_2_4_GHZ; + + return SIR_BAND_UNKNOWN; +} + +/* --------------------------------------------------------------------------- + + \fn p2pRemainOnChannel + \brief API to post the remain on channel command. + \param hHal - The handle returned by macOpen. + \param sessinId - HDD session ID. + \param channel - Channel to remain on channel. + \param duration - Duration for which we should remain on channel + \param callback - callback function. + \param pContext - argument to the callback function + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus p2pRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, tANI_U8 isP2PProbeReqAllowed +#ifdef WLAN_FEATURE_P2P_INTERNAL + , eP2PRemainOnChnReason reason +#endif + ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeCmd *pRemainChlCmd = NULL; + tANI_U32 phyMode; + + pRemainChlCmd = smeGetCommandBuffer(pMac); + if(pRemainChlCmd == NULL) + return eHAL_STATUS_FAILURE; + + if (SIR_BAND_5_GHZ == GetRFBand(channel)) + { + phyMode = WNI_CFG_PHY_MODE_11A; + } + else + { + phyMode = WNI_CFG_PHY_MODE_11G; + } + + cfgSetInt(pMac, WNI_CFG_PHY_MODE, phyMode); + + do + { + /* call set in context */ + pRemainChlCmd->command = eSmeCommandRemainOnChannel; + pRemainChlCmd->sessionId = sessionId; + pRemainChlCmd->u.remainChlCmd.chn = channel; + pRemainChlCmd->u.remainChlCmd.duration = duration; + pRemainChlCmd->u.remainChlCmd.isP2PProbeReqAllowed = isP2PProbeReqAllowed; + pRemainChlCmd->u.remainChlCmd.callback = callback; + pRemainChlCmd->u.remainChlCmd.callbackCtx = pContext; + + //Put it at the head of the Q if we just finish finding the peer and ready to send a frame +#ifdef WLAN_FEATURE_P2P_INTERNAL + smePushCommand(pMac, pRemainChlCmd, (eP2PRemainOnChnReasonSendFrame == reason)); +#else + status = csrQueueSmeCommand(pMac, pRemainChlCmd, eANI_BOOLEAN_FALSE); +#endif + } while(0); + + smsLog(pMac, LOGW, "%s: status %d", +#ifdef WLAN_FEATURE_P2P_INTERNAL + " for reason = %d" __func__, status, reason +#else + __func__, status +#endif + ); + + return(status); +} + +eHalStatus p2pSendAction(tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, tANI_U16 wait, tANI_BOOLEAN noack) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMbMsgP2p *pMsg; + tANI_U16 msgLen; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + " %s sends action frame", __func__); + msgLen = (tANI_U16)((sizeof( tSirMbMsg )) + len); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SEND_ACTION_FRAME_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + pMsg->sessionId = sessionId; + pMsg->noack = noack; + pMsg->wait = (tANI_U16)wait; + vos_mem_copy(pMsg->data, pBuf, len); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return( status ); +} + +eHalStatus p2pCancelRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + //Need to check session ID to support concurrency + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set((void *)pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_ABORT_REMAIN_ON_CHAN_IND); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return( status ); +} + +eHalStatus p2pSetPs(tHalHandle hHal, tP2pPsConfig *pNoA) +{ + tpP2pPsConfig pNoAParam; + tSirMsgQ msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pNoAParam = vos_mem_malloc(sizeof(tP2pPsConfig)); + if ( NULL == pNoAParam ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pNoAParam, sizeof(tP2pPsConfig), 0); + vos_mem_copy(pNoAParam, pNoA, sizeof(tP2pPsConfig)); + msg.type = eWNI_SME_UPDATE_NOA; + msg.bodyval = 0; + msg.bodyptr = pNoAParam; + limPostMsgApi(pMac, &msg); + } + return status; +} + +#ifdef WLAN_FEATURE_P2P_INTERNAL +eHalStatus p2pGetConfigParam(tHalHandle hHal, tP2PConfigParam *pParam) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if(pParam) + { + pParam->P2PListenChannel = pMac->p2pContext[0].P2PListenChannel; + pParam->P2POperatingChannel = pMac->p2pContext[0].P2POperatingChannel; + pParam->P2POpPSCTWindow = pMac->p2pContext[0].pNoA.ctWindow; + pParam->P2PPSSelection = pMac->p2pContext[0].pNoA.psSelection; + pParam->P2POpPSCTWindow = pMac->p2pContext[0].pNoA.ctWindow; + pParam->P2PNoADuration = pMac->p2pContext[0].pNoA.duration; + pParam->P2PNoACount = pMac->p2pContext[0].pNoA.count; + pParam->P2PNoAInterval = pMac->p2pContext[0].pNoA.interval; + + status = eHAL_STATUS_SUCCESS; + } + + return (status); +} + +eHalStatus p2pChangeDefaultConfigParam(tHalHandle hHal, tP2PConfigParam *pParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + int i; + tANI_U8 pBuf[P2P_COUNTRY_CODE_LEN]; + tANI_U8 uBufLen = P2P_COUNTRY_CODE_LEN; + tP2P_OperatingChannel p2pChannel; + + status = sme_GetCountryCode( pMac, pBuf, &uBufLen ); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + status = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Cannot get the country code", __func__); + } + + vos_mem_copy(p2pChannel.countryString, pBuf, sizeof(pBuf)); + p2pChannel.regulatoryClass = 0x51; + + if(pParam) + { + for ( i=0; i < MAX_NO_OF_P2P_SESSIONS; i++ ) + { + if (pParam->P2PListenChannel == 1 || pParam->P2PListenChannel == 6 + || pParam->P2PListenChannel == 11) + { + pMac->p2pContext[i].P2PListenChannel = pParam->P2PListenChannel; + } + else + { + pMac->p2pContext[i].P2PListenChannel = P2P_OPERATING_CHANNEL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid P2P Listen Channel in config. Switch to default Listen Channel %d", + __func__, P2P_OPERATING_CHANNEL); + } + + if(csrRoamIsChannelValid(pMac, pParam->P2POperatingChannel)) + { + pMac->p2pContext[i].P2POperatingChannel = pParam->P2POperatingChannel; + } + else + { + pMac->p2pContext[i].P2POperatingChannel = P2P_OPERATING_CHANNEL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + "Invalid P2P Operating Channel in config. Switch to default Channel %d", + __func__, P2P_OPERATING_CHANNEL); + } + pMac->p2pContext[i].pNoA.ctWindow = pParam->P2POpPSCTWindow; + pMac->p2pContext[i].pNoA.psSelection = pParam->P2PPSSelection; + pMac->p2pContext[i].pNoA.ctWindow = pParam->P2POpPSCTWindow; + pMac->p2pContext[i].pNoA.duration = pParam->P2PNoADuration; + pMac->p2pContext[i].pNoA.count = pParam->P2PNoACount; + pMac->p2pContext[i].pNoA.interval = pParam->P2PNoAInterval; + + p2pChannel.channel = pMac->p2pContext[i].P2POperatingChannel; + P2P_UpdateIE(pMac, i, eWFD_OPERATING_CHANNEL, &p2pChannel, 1); + p2pChannel.channel = pMac->p2pContext[i].P2PListenChannel; + P2P_UpdateIE(pMac, i, eWFD_LISTEN_CHANNEL, &p2pChannel, 1); + } + } + + return status; +} + +eHalStatus p2pPS(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tP2pPsConfig pNoA; + + /* call set in context */ + pNoA.psSelection = pMac->p2pContext[sessionId].pNoA.psSelection; + pNoA.sessionid = sessionId; + + if (pMac->p2pContext[sessionId].pNoA.psSelection == P2P_CLEAR_POWERSAVE) + { + return status; + } + + if (pMac->p2pContext[sessionId].pNoA.psSelection == P2P_OPPORTUNISTIC_PS) + { + pNoA.opp_ps = TRUE; + pNoA.ctWindow = pMac->p2pContext[sessionId].pNoA.ctWindow; + pNoA.count = 0; + pNoA.duration = 0; + pNoA.interval = 0; + pNoA.single_noa_duration = 0; + } + else if (pMac->p2pContext[sessionId].pNoA.psSelection == P2P_PERIODIC_NOA) + { + pNoA.opp_ps = 0; + pNoA.ctWindow = 0; + pNoA.count = pMac->p2pContext[sessionId].pNoA.count; + pNoA.duration = pMac->p2pContext[sessionId].pNoA.duration; + pNoA.interval = pMac->p2pContext[sessionId].pNoA.interval; + pNoA.single_noa_duration = 0; + } + else if(pMac->p2pContext[sessionId].pNoA.psSelection == P2P_SINGLE_NOA) + { + pNoA.opp_ps = 0; + pNoA.ctWindow = 0; + pNoA.count = 0; + pNoA.duration = 0; + pNoA.interval = 0; + pNoA.single_noa_duration = pMac->p2pContext[sessionId].pNoA.duration; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + " %s HDDSession %d set NoA parameters. Selection %d, opp_ps %d, ctWindow %d, count %d, " + "duration %d, interval %d single NoA duration %d", + __func__, sessionId, pMac->p2pContext[sessionId].pNoA.psSelection, + pNoA.opp_ps, pNoA.ctWindow, pNoA.count, pNoA.duration, + pNoA.interval, pNoA.single_noa_duration ); + + status = sme_p2pSetPs(pMac, &pNoA); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" sme_p2pSetPs fail with status %d"), status); + return status; + } + + return status; +} + +void P2P_UpdateMacHdr(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 *pBuf) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacMgmtHdr *macHdr = (tSirMacMgmtHdr *)pBuf; + + macHdr->fc.protVer = 0; + macHdr->fc.type = 0; + macHdr->fc.subType = 13; + macHdr->durationLo = 0; + macHdr->durationHi = 0; + vos_mem_copy(macHdr->da, pMac->p2pContext[SessionID].peerMacAddress, + P2P_MAC_ADDRESS_LEN); + vos_mem_copy(macHdr->sa, pMac->p2pContext[SessionID].selfMacAddress, + P2P_MAC_ADDRESS_LEN); + vos_mem_copy(macHdr->bssId, pMac->p2pContext[SessionID].peerMacAddress, + P2P_MAC_ADDRESS_LEN); + + return; +} + +static eHalStatus p2pRemainOnChannelReadyCallback(tHalHandle halHandle, + void *pContext, + eHalStatus scan_status) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tp2pContext *p2pContext = (tp2pContext*) pContext; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s GroupFormationPending %d PeerFound %d", + __func__, p2pContext->GroupFormationPending, p2pContext->PeerFound); + + if (p2pContext->PeerFound) + { + p2pContext->PeerFound = FALSE; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Sending actionframe", __func__); + if (p2pContext->pSentActionFrame) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s calling p2pSendAction", __func__); + p2pSendAction(halHandle, p2pContext->SMEsessionId, (tANI_U8 *)p2pContext->pSentActionFrame, p2pContext->ActionFrameLen); + } + } + + return status; +} + +eHalStatus p2pGrpFormationRemainOnChanRspCallback(tHalHandle halHandle, void *pContext, tANI_U32 scanId, eCsrScanStatus scan_status) +{ + return eHAL_STATUS_SUCCESS; +} + +tANI_U8 p2pGetDialogToken(tHalHandle hHal, tANI_U8 SessionID, eP2PFrameType actionFrameType) +{ + tANI_U8 dialogToken = 0; + + dialogToken = (tANI_U8) vos_timer_get_system_ticks(); + + return(dialogToken); +} + +void p2pRetryActionFrameTimerHandler(void *pContext) +{ + tp2pContext *p2pContext = (tp2pContext*) pContext; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( p2pContext->hHal ); + + p2pContext->PeerFound = TRUE; + smsLog( pMac, LOGE, "%s Calling remain on channel to Resend Action Frame ", + __func__); + status = p2pRemainOnChannel( pMac, p2pContext->SMEsessionId, p2pContext->P2PListenChannel/*pScanResult->BssDescriptor.channelId*/, P2P_REMAIN_ON_CHAN_TIMEOUT_LOW, + NULL, NULL, TRUE, eP2PRemainOnChnReasonSendFrame); + if(status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, "%s remain on channel failed", __func__); + } + + return; +} + +void p2pActionFrameTimerHandler(void *pContext) +{ + tp2pContext *p2pContext = (tp2pContext*) pContext; + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 *pBuf = NULL, *pNextBuf = NULL; + tCsrRoamInfo roamInfo; + + + if(p2pContext->pSentActionFrame) + { + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback((tpAniSirGlobal)p2pContext->hHal, p2pContext->SMEsessionId, &roamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + eCSR_ROAM_RESULT_SEND_ACTION_FAIL); + } + + if(VOS_IS_STATUS_SUCCESS(vos_spin_lock_acquire(&p2pContext->lState))) + { + if(p2pContext->pSentActionFrame) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + " %s actionframe timeout type %d", __func__, p2pContext->actionFrameType); + pBuf = p2pContext->pSentActionFrame; + p2pContext->pSentActionFrame = NULL; + } + if(p2pContext->pNextActionFrm) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + " %s next actionframe timeout type %d", __func__, p2pContext->NextActionFrameType); + pNextBuf = p2pContext->pNextActionFrm; + p2pContext->pNextActionFrm = NULL; + } + vos_spin_lock_release(&p2pContext->lState); + + if(pBuf) + { + vos_mem_free(pBuf); + } + if(pNextBuf) + { + //Inform the failure of the next frame. + p2pContext->pSentActionFrame = pNextBuf; + p2pContext->ActionFrameLen = p2pContext->nNextFrmLen; + p2pContext->actionFrameType = p2pContext->NextActionFrameType; + vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo)); + csrRoamCallCallback((tpAniSirGlobal)p2pContext->hHal, p2pContext->SMEsessionId, &roamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + eCSR_ROAM_RESULT_SEND_ACTION_FAIL); + p2pContext->pSentActionFrame = NULL; + vos_mem_free(pNextBuf); + } + } + status = p2pFsm(p2pContext, eP2P_TRIGGER_DISCONNECTED); + p2pContext->actionFrameTimeout = TRUE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s timedout", __func__); + + return; +} + + +eHalStatus p2pCreateActionFrame(tpAniSirGlobal pMac, tANI_U8 SessionID, void *p2pactionframe, + eP2PFrameType actionFrameType, tANI_U8 **ppFrm) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 len = 0; + tANI_U32 nActionFrmlen = 0, pendingFrameLen; + tANI_U8 *pActionFrm = NULL; + tANI_U8 *pBuf = NULL, *pLocal = NULL; + eP2PFrameType pendingActionFrameType; + tp2pContext *pP2pContext = &pMac->p2pContext[SessionID]; + + if(NULL == ppFrm) + { + smsLog(pMac, LOGE, FL(" invalid parameters")); + return eHAL_STATUS_FAILURE; + } + + csrScanAbortMacScan(pMac, SessionID, eCSR_SCAN_ABORT_DEFAULT); + + switch (actionFrameType) + { + case eP2P_GONEGO_REQ: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_GO_NEGOTIATION_REQUEST, p2pactionframe, len); + break; + + case eP2P_GONEGO_RES: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_GO_NEGOTIATION_RESPONSE, p2pactionframe, len); + break; + + case eP2P_GONEGO_CNF: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_GO_NEGOTIATION_CONFIRMATION, p2pactionframe, len); + break; + + case eP2P_PROVISION_DISCOVERY_REQUEST: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_PROVISION_DISCOVERY_REQUEST, p2pactionframe, len); + break; + + case eP2P_PROVISION_DISCOVERY_RESPONSE: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_PROVISION_DISCOVERY_RESPONSE, p2pactionframe, len); + break; + + case eP2P_INVITATION_REQ: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_INVITATION_REQUEST, p2pactionframe, len); + break; + + case eP2P_INVITATION_RSP: + status = P2P_UpdateIE(pMac, SessionID, eWFD_SEND_INVITATION_RESPONSE, p2pactionframe, len); + break; + default: + return status; + } + + status = P2P_GetActionFrame(pMac, SessionID, actionFrameType, &pActionFrm, &nActionFrmlen); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" P2P_GetActionFrame fail with status %d"), status); + return status; + } + + P2P_UpdateMacHdr(pMac, SessionID, pActionFrm); + + pBuf = (tANI_U8 *)vos_mem_malloc( nActionFrmlen); + if (NULL == pBuf) + { + smsLog(pMac, LOGE, FL(" fail to allocate memory")); + if (pActionFrm) + vos_mem_free(pActionFrm); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pBuf, pActionFrm, nActionFrmlen); + vos_mem_free(pActionFrm); + + if( !VOS_IS_STATUS_SUCCESS(vos_spin_lock_acquire(&pP2pContext->lState))) + { + smsLog(pMac, LOGE, FL(" fail to acquire spinlock")); + vos_mem_free(pBuf); + return eHAL_STATUS_FAILURE; + } + + if(NULL != pP2pContext->pSentActionFrame) + { + //If there is one pending frame already. Drop that one and save the new one + pLocal = pP2pContext->pNextActionFrm; + pendingActionFrameType = pP2pContext->NextActionFrameType; + pendingFrameLen = pP2pContext->nNextFrmLen; + pP2pContext->pNextActionFrm = pBuf; + pP2pContext->nNextFrmLen = nActionFrmlen; + pP2pContext->NextActionFrameType = actionFrameType; + *ppFrm = NULL; + } + else + { + pP2pContext->pSentActionFrame = pBuf; + pP2pContext->ActionFrameLen = nActionFrmlen; + pP2pContext->actionFrameType = actionFrameType; + *ppFrm = pBuf; + } + vos_spin_lock_release(&pP2pContext->lState); + + if(NULL != pLocal) + { + smsLog(pMac, LOGE, FL(" Drop a waiting action frame 0x%x, type %d lenth %d"), + pLocal, pendingActionFrameType, pendingFrameLen); + vos_mem_free(pLocal); + } + + return status; +} + + +extern eHalStatus p2pGetSSID(tANI_U8 *ssId, tANI_U32 *ssIdLen, tANI_U8 SessionID); + +static eHalStatus p2pSendActionFrame(tpAniSirGlobal pMac, tANI_U8 HDDSessionID, eP2PFrameType actionFrameType) +{ + tCsrScanResultFilter filter; + eHalStatus status = eHAL_STATUS_SUCCESS; + tScanResultHandle hScanResult = NULL; + tCsrScanResultInfo *pScanResult = NULL; + tANI_U8 ssId[SIR_MAC_MAX_SSID_LENGTH]; + tANI_U32 ssIdLen = 0; + tp2pContext *pP2pContext = &pMac->p2pContext[HDDSessionID]; + + pP2pContext->GroupFormationPending = TRUE; + if (actionFrameType == eP2P_GONEGO_REQ || actionFrameType == eP2P_PROVISION_DISCOVERY_REQUEST + || actionFrameType == eP2P_INVITATION_REQ) + { + vos_mem_zero(&filter, sizeof(filter)); + filter.BSSIDs.numOfBSSIDs = 1; + filter.BSSIDs.bssid = &pP2pContext->peerMacAddress; + filter.bWPSAssociation = TRUE; + filter.BSSType = eCSR_BSS_TYPE_ANY; + + status = csrScanGetResult(pMac, &filter, &hScanResult); + + if (hScanResult) + { + pScanResult = csrScanResultGetFirst(pMac, hScanResult ); + if(pScanResult) + { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s found match on channel %d", + __func__, pScanResult->BssDescriptor.channelId); + pP2pContext->formationReq.targetListenChannel = pScanResult->BssDescriptor.channelId; + if(pP2pContext->P2PListenChannel != pScanResult->BssDescriptor.channelId) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s adapt listen channel to %d", + __func__, pScanResult->BssDescriptor.channelId); + p2pSetListenChannel(pMac, pP2pContext->sessionId, pScanResult->BssDescriptor.channelId); + } + vos_mem_copy(pP2pContext->formationReq.deviceAddress, + pScanResult->BssDescriptor.bssId, + P2P_MAC_ADDRESS_LEN); + } + csrScanResultPurge(pMac, hScanResult); + } + else + { + vos_mem_zero(&filter, sizeof(filter)); + filter.bWPSAssociation = TRUE; + filter.BSSType = eCSR_BSS_TYPE_ANY; + filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if ( NULL == filter.SSIDs.SSIDList ) + { + smsLog( pMac, LOGP, FL("memory allocation failed for SSIDList") ); + pP2pContext->GroupFormationPending = FALSE; + return eHAL_STATUS_FAILURE; + } + vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) ); + p2pGetSSID(ssId, &ssIdLen, HDDSessionID); + + if (ssIdLen) + { + filter.SSIDs.SSIDList->SSID.length = ssIdLen; + vos_mem_copy(&filter.SSIDs.SSIDList[0].SSID.ssId, &ssId, ssIdLen); + filter.SSIDs.numOfSSIDs = 1; + status = csrScanGetResult(pMac, &filter, &hScanResult); + if (hScanResult) + { + pScanResult = csrScanResultGetFirst(pMac, hScanResult ); + pP2pContext->formationReq.targetListenChannel = pScanResult->BssDescriptor.channelId; + vos_mem_copy(pP2pContext->formationReq.deviceAddress, + pScanResult->BssDescriptor.bssId, + P2P_MAC_ADDRESS_LEN); + csrScanResultPurge(pMac, hScanResult); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s not found match", __func__); + pP2pContext->formationReq.targetListenChannel = 0; + vos_mem_copy(pP2pContext->formationReq.deviceAddress, pP2pContext->peerMacAddress, + P2P_MAC_ADDRESS_LEN); + status = eHAL_STATUS_SUCCESS; + } + vos_mem_free(filter.SSIDs.SSIDList); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s not found match", __func__); + pP2pContext->formationReq.targetListenChannel = 0; + vos_mem_copy(pP2pContext->formationReq.deviceAddress, + pP2pContext->peerMacAddress, P2P_MAC_ADDRESS_LEN); + status = eHAL_STATUS_SUCCESS; + } + } + sme_CancelRemainOnChannel(pMac, pP2pContext->SMEsessionId ); + p2pFsm(pP2pContext, eP2P_TRIGGER_GROUP_FORMATION); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, " %s send action frame %d timeout %d", + __func__, actionFrameType, pP2pContext->ActionFrameSendTimeout); + } + else + { + pP2pContext->PeerFound = TRUE; + + status = p2pSendAction(pMac, pP2pContext->SMEsessionId, (tANI_U8 *)pP2pContext->pSentActionFrame, + pP2pContext->ActionFrameLen); + if(status != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s p2pSendAction failed to send frame type %d", __func__, actionFrameType); + pP2pContext->GroupFormationPending = FALSE; + return status; + } + + if ( actionFrameType == eP2P_GONEGO_RES ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling p2pRemainOnChannel with duration" + "%d on channel %d", __func__, P2P_REMAIN_ON_CHAN_TIMEOUT, pP2pContext->P2PListenChannel); + + if(p2pRemainOnChannel( pMac, pP2pContext->SMEsessionId, + pP2pContext->P2PListenChannel, P2P_REMAIN_ON_CHAN_TIMEOUT_LOW, + NULL, NULL, TRUE, eP2PRemainOnChnReasonSendFrame)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s remain on channel failed", __func__); + } + } + } + + return(status); +} + + +#define WLAN_P2P_DEF_ACTION_FRM_TIMEOUT_VALUE 1000 //1s + +eHalStatus p2pCreateSendActionFrame(tHalHandle hHal, tANI_U8 HDDSessionID, + void *p2pactionframe, eP2PFrameType actionFrameType, tANI_U32 timeout) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 *pBuf = NULL; + tp2pContext *pP2pContext = &pMac->p2pContext[HDDSessionID]; + + status = p2pCreateActionFrame(pMac, HDDSessionID, p2pactionframe, actionFrameType, &pBuf); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to create action frame")); + return status; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, " %s send action frame %d timeout %d", + __func__, actionFrameType, timeout); + + if(NULL != pBuf) + { + if (timeout) + { + pP2pContext->ActionFrameSendTimeout = timeout; + } + else + { + pP2pContext->ActionFrameSendTimeout = WLAN_P2P_DEF_ACTION_FRM_TIMEOUT_VALUE; + } + + status = vos_timer_start(&pP2pContext->actionFrameTimer, + pP2pContext->ActionFrameSendTimeout); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + tCsrRoamInfo RoamInfo; + + vos_mem_zero(&RoamInfo, sizeof(tCsrRoamInfo)); + smsLog(pMac, LOGE, FL(" %s fail to start timer status %d"), __func__, status); + //Without the timer we cannot continue + csrRoamCallCallback((tpAniSirGlobal)pP2pContext->hHal, + pP2pContext->SMEsessionId, &RoamInfo, 0, + eCSR_ROAM_SEND_ACTION_CNF, + eCSR_ROAM_RESULT_SEND_ACTION_FAIL); + vos_spin_lock_acquire(&pP2pContext->lState); + pBuf = pP2pContext->pSentActionFrame; + pP2pContext->pSentActionFrame = NULL; + vos_spin_lock_release(&pP2pContext->lState); + vos_mem_free(pBuf); + pBuf = NULL; + p2pFsm(pP2pContext, eP2P_TRIGGER_DISCONNECTED); + return status; + } + //We can send this frame now + status = p2pSendActionFrame(pMac, HDDSessionID, actionFrameType); + if(!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to send action frame status %d"), status); + } + //Let them retry + pP2pContext->actionFrameTimeout = FALSE; + } + else + { + //An action frame is pedning at lower layer + smsLog(pMac, LOGW, FL(" An action frame is pending while trying to send frametype %d"), actionFrameType); + if (timeout) + { + pP2pContext->nNextFrameTimeOut = timeout; + } + else + { + pP2pContext->nNextFrameTimeOut = WLAN_P2P_DEF_ACTION_FRM_TIMEOUT_VALUE; + } + } + + return status; +} + + +void p2pListenDiscoverTimerHandlerCB(void *pContext) +{ +} + +void p2pListenDiscoverTimerHandler(void *pContext) +{ + tp2pContext *p2pContext = (tp2pContext*) pContext; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if( (eP2P_STATE_DISCONNECTED == p2pContext->state) && + (eStateDisabled != p2pContext->listenDiscoverableState) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with duration %d on channel %d", + __func__, p2pContext->listenDuration, p2pContext->P2PListenChannel); + status = p2pRemainOnChannel( p2pContext->hHal, p2pContext->SMEsessionId, p2pContext->P2PListenChannel, p2pContext->listenDuration, + p2pListenStateDiscoverableCallback, p2pContext, TRUE, eP2PRemainOnChnReasonListen); + } + else + { + smsLog(((tpAniSirGlobal)p2pContext->hHal), LOGW, FL(" cannot call p2pRemainOnChannel state %d"), p2pContext->state); + } + + return; +} + + +static eHalStatus p2pListenStateDiscoverableCallback(tHalHandle halHandle, void *pContext, eHalStatus retStatus) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(halHandle); + tp2pContext *p2pContext = (tp2pContext*) pContext; + + if( (eP2P_STATE_DISCONNECTED == p2pContext->state) && + (eStateDisabled != p2pContext->listenDiscoverableState) && + (NULL == p2pContext->p2pDiscoverCBFunc) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s restart listen timer expire time %d", + __func__, p2pContext->expire_time); + //We can restart the listening + status = vos_timer_start(&p2pContext->listenTimerHandler, (p2pContext->expire_time)/PAL_TIMER_TO_MS_UNIT); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_ASSERT(status); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s not restart listen timer state (%d)", + __func__, p2pContext->state); + } + + return status; +} + + +eHalStatus P2P_ListenStateDiscoverable(tHalHandle hHal, tANI_U8 sessionId, + ep2pListenStateDiscoverability listenState) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + switch (listenState) + { + case P2P_DEVICE_NOT_DISCOVERABLE: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_NOT_DISCOVERABLE", __func__); + pMac->p2pContext[sessionId].listenDiscoverableState = eStateDisabled; + pMac->p2pContext[sessionId].DiscoverableCfg = listenState; + if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED) + { + sme_CancelRemainOnChannel(hHal, sessionId ); + + if (pMac->p2pContext[sessionId].listenTimerHandler) + { + vos_timer_stop(&pMac->p2pContext[sessionId].listenTimerHandler); + status = eHAL_STATUS_SUCCESS; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Timer Stop status %d", + __func__, status); + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s P2P_NOT_DISCOVERABLE not in right state (%d)", + __func__, pMac->p2pContext[sessionId].state); + } + break; + + case P2P_DEVICE_AUTO_AVAILABILITY: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_AUTO_AVAILABILITY",__func__); + pMac->p2pContext[sessionId].listenDiscoverableState = eStateEnabled; + pMac->p2pContext[sessionId].DiscoverableCfg = listenState; + pMac->p2pContext[sessionId].expire_time = P2P_LISTEN_TIMEOUT_AUTO * PAL_TIMER_TO_MS_UNIT; + pMac->p2pContext[sessionId].listenDuration = P2P_LISTEN_TIMEOUT; + if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with diration %d on channel %d", + __func__, pMac->p2pContext[sessionId].listenDuration, pMac->p2pContext[sessionId].P2PListenChannel); + p2pRemainOnChannel( pMac, pMac->p2pContext[sessionId].SMEsessionId, pMac->p2pContext[sessionId].P2PListenChannel, + pMac->p2pContext[sessionId].listenDuration, p2pListenStateDiscoverableCallback, + &pMac->p2pContext[sessionId], TRUE, eP2PRemainOnChnReasonListen); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s P2P_AUTO_DISCOVERABLE not in right state (%d)", + __func__, pMac->p2pContext[sessionId].state); + } + break; + + case P2P_DEVICE_HIGH_AVAILABILITY: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_HIGH_AVAILABILITY",__func__); + pMac->p2pContext[sessionId].listenDiscoverableState = eStateEnabled; + pMac->p2pContext[sessionId].DiscoverableCfg = listenState; + pMac->p2pContext[sessionId].expire_time = P2P_REMAIN_ON_CHAN_TIMEOUT_LOW * PAL_TIMER_TO_MS_UNIT; + pMac->p2pContext[sessionId].listenDuration = P2P_LISTEN_TIMEOUT_HIGH; + if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with duration %d on channel %d", + __func__, pMac->p2pContext[sessionId].listenDuration, pMac->p2pContext[sessionId].P2PListenChannel); + p2pRemainOnChannel( pMac, pMac->p2pContext[sessionId].SMEsessionId, pMac->p2pContext[sessionId].P2PListenChannel, + pMac->p2pContext[sessionId].listenDuration, p2pListenStateDiscoverableCallback, + &pMac->p2pContext[sessionId], TRUE, eP2PRemainOnChnReasonListen); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s P2P_HIGH_DISCOVERABLE not in right state (%d)", + __func__, pMac->p2pContext[sessionId].state); + } + break; + + case 234: //Not to use this as it enabling GO to be concurrent with P2P device P2P_DEVICE_HIGH_AVAILABILITY: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s P2P_HIGH_AVAILABILITY",__func__); + pMac->p2pContext[sessionId].listenDiscoverableState = eStateEnabled; + pMac->p2pContext[sessionId].DiscoverableCfg = listenState; + + if ((pMac->p2pContext[sessionId].P2POperatingChannel != pMac->p2pContext[sessionId].P2PListenChannel) + && p2pIsGOportEnabled(pMac)) + { + pMac->p2pContext[sessionId].expire_time = P2P_LISTEN_TIMEOUT_HIGH * PAL_TIMER_TO_MS_UNIT * 5; + pMac->p2pContext[sessionId].listenDuration = P2P_REMAIN_ON_CHAN_TIMEOUT_LOW; + } + else + { + pMac->p2pContext[sessionId].expire_time = P2P_LISTEN_TIMEOUT_HIGH * PAL_TIMER_TO_MS_UNIT; + pMac->p2pContext[sessionId].listenDuration = P2P_LISTEN_TIMEOUT; + } + + if (pMac->p2pContext[sessionId].state == eP2P_STATE_DISCONNECTED) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Calling RemainOnChannel with duration %d on channel %d", + __func__, pMac->p2pContext[sessionId].listenDuration, pMac->p2pContext[sessionId].P2PListenChannel); + p2pRemainOnChannel( pMac, pMac->p2pContext[sessionId].SMEsessionId, pMac->p2pContext[sessionId].P2PListenChannel, + pMac->p2pContext[sessionId].listenDuration, p2pListenStateDiscoverableCallback, + &pMac->p2pContext[sessionId], TRUE, eP2PRemainOnChnReasonListen); + } + + break; + + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Unknown listen setting",__func__, listenState); + break; + } + + return( status ); +} + + +void p2pCallDiscoverCallback(tp2pContext *p2pContext, eP2PDiscoverStatus statusCode) +{ + if (p2pContext->p2pDiscoverCBFunc) + { + p2pDiscoverCompleteCallback pcallback = p2pContext->p2pDiscoverCBFunc; + p2pContext->p2pDiscoverCBFunc = NULL; + pcallback(p2pContext->hHal, p2pContext->pContext, statusCode); + } + p2pContext->directedDiscovery = FALSE; +} + + +void p2pDiscoverTimerHandler(void *pContext) +{ + tp2pContext *p2pContext = (tp2pContext*) pContext; + eHalStatus status = eHAL_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s enter", __func__); + p2pCallDiscoverCallback(p2pContext, + (p2pContext->directedDiscovery) ? eP2P_DIRECTED_DISCOVER : eP2P_DISCOVER_SUCCESS); + + status = p2pFsm(p2pContext, eP2P_TRIGGER_DISCONNECTED); + + return; +} + + + +eHalStatus p2pGetResultFilter(tp2pContext *pP2pContext, + tCsrScanResultFilter *pFilter) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + v_U32_t uNumDeviceFilters; + tp2pDiscoverDeviceFilter *directedDiscoveryFilter; + int i; + tCsrBssid *bssid = NULL; + + do + { + if( (NULL != pP2pContext) && (NULL != pFilter) ) + { + vos_mem_zero(pFilter, sizeof(tCsrScanResultFilter)); + uNumDeviceFilters = pP2pContext->uNumDeviceFilters; + directedDiscoveryFilter = pP2pContext->directedDiscoveryFilter; + for(i = 0; i < uNumDeviceFilters; i++) + { + if (directedDiscoveryFilter->ucBitmask & DISCOVERY_FILTER_BITMASK_DEVICE) + { + pFilter->BSSIDs.numOfBSSIDs++; + } + + if ((directedDiscoveryFilter->ucBitmask != QCWLAN_P2P_DISCOVER_ANY) + && (directedDiscoveryFilter->ucBitmask & DISCOVERY_FILTER_BITMASK_GO)) + { + //Matching Device ID and GroupSSID + pFilter->BSSIDs.numOfBSSIDs++; + if(directedDiscoveryFilter->GroupSSID.length) + { + pFilter->SSIDs.numOfSSIDs++; + } + } + directedDiscoveryFilter += sizeof(tp2pDiscoverDeviceFilter); + } + + directedDiscoveryFilter = pP2pContext->directedDiscoveryFilter; + if (pFilter->BSSIDs.numOfBSSIDs) + { + bssid = ( tCsrBssid *) vos_mem_malloc( + sizeof( tCsrBssid ) * pFilter->BSSIDs.numOfBSSIDs ); + if (NULL == bssid) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " %s fail to allocate bssid", __func__); + status = eHAL_STATUS_RESOURCES; + break; + } + + pFilter->BSSIDs.bssid = bssid; + + for (i = 0; i < uNumDeviceFilters; i++) + { + vos_mem_copy(bssid, directedDiscoveryFilter->DeviceID, + P2P_MAC_ADDRESS_LEN); + bssid += sizeof(tCsrBssid); + directedDiscoveryFilter += sizeof(tp2pDiscoverDeviceFilter); + } + } + + directedDiscoveryFilter = pP2pContext->directedDiscoveryFilter; + if (pFilter->SSIDs.numOfSSIDs) + { + pFilter->SSIDs.SSIDList = (tCsrSSIDInfo *)vos_mem_malloc( + sizeof( *pFilter->SSIDs.SSIDList ) * pFilter->SSIDs.numOfSSIDs ); + if (NULL == pFilter->SSIDs.SSIDList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " %s fail to allocate bssid", __func__); + status = eHAL_STATUS_RESOURCES; + break; + } + + if ( pFilter->SSIDs.SSIDList ) + { + for ( i = 0; i < uNumDeviceFilters; i++ ) + { + if (directedDiscoveryFilter->ucBitmask == DISCOVERY_FILTER_BITMASK_GO) + { + if(directedDiscoveryFilter->GroupSSID.length) + { + pFilter->SSIDs.SSIDList[i].SSID.length = directedDiscoveryFilter->GroupSSID.length; + vos_mem_copy( pFilter->SSIDs.SSIDList[i].SSID.ssId, + directedDiscoveryFilter->GroupSSID.ssId, + directedDiscoveryFilter->GroupSSID.length ); + } + } + directedDiscoveryFilter += sizeof(tp2pDiscoverDeviceFilter); + } + } + } + } + + pFilter->p2pResult = TRUE; + pFilter->bWPSAssociation = TRUE; + pFilter->BSSType = eCSR_BSS_TYPE_ANY; + } while(0); + + if(!HAL_STATUS_SUCCESS(status)) + { + if(pFilter->SSIDs.SSIDList) + { + vos_mem_free(pFilter->SSIDs.SSIDList); + pFilter->SSIDs.SSIDList = NULL; + } + if( pFilter->BSSIDs.bssid ) + { + vos_mem_free(pFilter->BSSIDs.bssid); + pFilter->BSSIDs.bssid = NULL; + } + } + + return status; +} + + +/* + @breif Function calls P2P_Fsm function to initiate the P2P Discover process + + @param[in] hHal - Handle to MAC structure. + [in] sessionID - Session ID returned by sme_OpenSession + [in] pDiscoverRequest - pointer to the tp2pDiscoverRequest structure + whose parameters are filled in the HDD. + [in] callback - HDD callback function to be called when Discover + is complete + [in] pContext - a pointer passed in for the callback + + @return eHAL_STATUS_FAILURE - If success. + eHAL_STATUS_SUCCESS - If failure. +*/ +eHalStatus P2P_DiscoverRequest(tHalHandle hHal, + tANI_U8 SessionID, + tP2PDiscoverRequest *pDiscoverRequest, + p2pDiscoverCompleteCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tScanResultHandle hScanResult = NULL; + tCsrScanResultFilter filter; + tANI_U32 uNumDeviceFilters; + tp2pDiscoverDeviceFilter *pDeviceFilters; + tANI_U32 i = 0; + tp2pContext *pP2pContext = &pMac->p2pContext[SessionID]; + tCsrBssid *bssid = NULL; + tp2pDiscoverDeviceFilter discoverFilter; + tANI_BOOLEAN fDirect = FALSE; + + if (pDiscoverRequest == NULL) + { + return status; + } + + pP2pContext->discoverType = pDiscoverRequest->discoverType; + pP2pContext->scanType = pDiscoverRequest->scanType; + pP2pContext->uDiscoverTimeout = pDiscoverRequest->uDiscoverTimeout; + + if (pP2pContext->DiscoverReqIeField) + { + vos_mem_free(pP2pContext->DiscoverReqIeField); + pP2pContext->DiscoverReqIeLength = 0; + pP2pContext->DiscoverReqIeField = NULL; + } + + if (pDiscoverRequest->uIELen) + { + pP2pContext->DiscoverReqIeField = (tANI_U8 *)vos_mem_malloc(pDiscoverRequest->uIELen); + vos_mem_copy((tANI_U8 *)pP2pContext->DiscoverReqIeField, + pDiscoverRequest->pIEField, pDiscoverRequest->uIELen); + pP2pContext->DiscoverReqIeLength = pDiscoverRequest->uIELen; + } + else + { + pP2pContext->DiscoverReqIeLength = 0; + } + + vos_mem_zero(&filter, sizeof(filter)); + + do + { + if (pDiscoverRequest->uNumDeviceFilters) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s directed", __func__); + fDirect = TRUE; + uNumDeviceFilters = pDiscoverRequest->uNumDeviceFilters; + + pP2pContext->uDiscoverTimeout = pP2pContext->uDiscoverTimeout; + pP2pContext->uNumDeviceFilters = pDiscoverRequest->uNumDeviceFilters; + if(pP2pContext->uNumDeviceFilterAllocated < pDiscoverRequest->uNumDeviceFilters) + { + if(pP2pContext->directedDiscoveryFilter) + { + pP2pContext->uNumDeviceFilterAllocated = 0; + vos_mem_free(pP2pContext->directedDiscoveryFilter); + pP2pContext->directedDiscoveryFilter = NULL; + } + pP2pContext->directedDiscoveryFilter = (tp2pDiscoverDeviceFilter *) + vos_mem_malloc(sizeof(tp2pDiscoverDeviceFilter) * uNumDeviceFilters); + if (NULL == pP2pContext->directedDiscoveryFilter) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s fail to allocate memory for discoverFilter", __func__); + status = eHAL_STATUS_RESOURCES; + break; + } + pP2pContext->uNumDeviceFilterAllocated = uNumDeviceFilters; + } + + pDeviceFilters = pDiscoverRequest->pDeviceFilters; + if(NULL != pDeviceFilters) + { + vos_mem_copy (pP2pContext->directedDiscoveryFilter, pDeviceFilters, + sizeof(tp2pDiscoverDeviceFilter) * uNumDeviceFilters); + + if(!HAL_STATUS_SUCCESS(status = p2pGetResultFilter(pP2pContext, &filter))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s fail to create filter", __func__); + break; + } + }//if(NULL != pDeviceFilters) + + status = csrScanGetResult(pMac, &filter, &hScanResult); + if (hScanResult) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s calling p2pDiscoverCompleteCallback", __func__); + if (callback) + { + callback(hHal, pContext, eP2P_DIRECTED_DISCOVER); + + } + status = eHAL_STATUS_SUCCESS; + break; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Directed find did not find BSSID in cache", __func__); + pP2pContext->formationReq.targetListenChannel = 0; + if (pDiscoverRequest->uNumDeviceFilters == 1 && filter.BSSIDs.numOfBSSIDs == 1) + { + vos_mem_copy(&pP2pContext->formationReq.deviceAddress, + pDiscoverRequest->pDeviceFilters->DeviceID, + P2P_MAC_ADDRESS_LEN); + } + } + } + + pP2pContext->p2pDiscoverCBFunc = callback; + pP2pContext->pContext = pContext; + pP2pContext->directedDiscovery = fDirect; + if(!pP2pContext->GroupFormationPending) + { + p2pFsm(&pMac->p2pContext[SessionID], eP2P_TRIGGER_DEVICE_MODE_DEVICE); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, + "%s while group formation", __func__); + } + + pP2pContext->uDiscoverTimeout = pDiscoverRequest->uDiscoverTimeout; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_MED, "%s Start discover", __func__); + status = vos_timer_start(&pP2pContext->discoverTimer, + pP2pContext->uDiscoverTimeout); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s failt to start discover timer", __func__); + pP2pContext->p2pDiscoverCBFunc = NULL; + pP2pContext->pContext = NULL; + if(callback) + { + callback(pMac, pContext, eP2P_DISCOVER_FAILURE); + } + } + }while(0); + + if(filter.SSIDs.SSIDList) + { + vos_mem_free(filter.SSIDs.SSIDList); + } + if( hScanResult ) + { + sme_ScanResultPurge( pMac, hScanResult ); + } + if( filter.BSSIDs.bssid ) + { + vos_mem_free(filter.BSSIDs.bssid); + } + + return status; +} + +eHalStatus p2pScanRequest(tp2pContext *p2pContext, p2pDiscoverCompleteCallback callback, void *pContext) +{ + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + tANI_U32 len = 0; + tCsrSSIDInfo wcSSID = { {P2P_WILDCARD_SSID_LEN, P2P_WILDCARD_SSID}, 0, 0 }; + tANI_U8 Channel; + eHalStatus status = eHAL_STATUS_SUCCESS; + tP2P_OperatingChannel p2pOperatingChannel; + tpAniSirGlobal pMac = PMAC_STRUCT(p2pContext->hHal); + tANI_U8 *p2pIe = NULL; + tANI_U32 p2pIeLen; + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + P2P_GetOperatingChannel(p2pContext->hHal, p2pContext->sessionId, &p2pOperatingChannel); + Channel = p2pOperatingChannel.channel; + + if (Channel) + { + scanRequest.ChannelInfo.numOfChannels = 1; + scanRequest.ChannelInfo.ChannelList = &Channel; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Scan on channel %d p2pContext->sessionId %d", + __func__, Channel, p2pContext->sessionId); + } + else + { + getChannelInfo(p2pContext, &scanRequest.ChannelInfo, WFD_DISCOVER_TYPE_AUTO); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Scan on all channels", + __func__); + } + + /* set the scan type to active */ + scanRequest.scanType = eSIR_ACTIVE_SCAN; + + vos_mem_set(scanRequest.bssid, sizeof( tCsrBssid ), 0xff); + + scanRequest.requestType = eCSR_SCAN_P2P_FIND_PEER; + /* set min and max channel time to zero */ + scanRequest.minChnTime = 30; + scanRequest.maxChnTime = 100; + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + scanRequest.SSIDs.numOfSSIDs = 1; + scanRequest.SSIDs.SSIDList = &wcSSID; + scanRequest.p2pSearch = VOS_FALSE; + + P2P_GetIE(p2pContext, p2pContext->sessionId, eP2P_GROUP_ID, &p2pIe, &p2pIeLen); + vos_mem_copy(scanRequest.bssid, ((tP2PGroupId *)p2pIe)->deviceAddress, + P2P_MAC_ADDRESS_LEN); + + P2P_GetIE(p2pContext, p2pContext->sessionId, eP2P_PROBE_REQ, &scanRequest.pIEField, &len); + + scanRequest.uIEFieldLen = len; + + status = csrScanRequest( p2pContext->hHal, p2pContext->SMEsessionId, &scanRequest, &scanId, callback, pContext ); + + if(scanRequest.pIEField) + { + vos_mem_free(scanRequest.pIEField); + } + + if(p2pIe) + { + vos_mem_free(p2pIe); + } + return status; +} + +tANI_U8 getP2PSessionIdFromSMESessionId(tHalHandle hHal, tANI_U8 SessionID) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 num_session; + + for (num_session = 0; num_session < MAX_NO_OF_P2P_SESSIONS; num_session++) + { + if(SessionID == pMac->p2pContext[num_session].SMEsessionId) + { + return pMac->p2pContext[num_session].sessionId; + } + } + + return CSR_SESSION_ID_INVALID; +} + + +/* SessionID is HDD session id, not SME sessionId*/ +eHalStatus p2pCloseSession(tHalHandle hHal, tANI_U8 SessionID) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tp2pContext *pContext = &pMac->p2pContext[SessionID]; + + pContext->SMEsessionId = CSR_SESSION_ID_INVALID; + p2pResetContext(pContext); + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus p2pSetSessionId(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 SmeSessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pMac->p2pContext[SessionID].sessionId = SessionID; + pMac->p2pContext[SessionID].SMEsessionId = SmeSessionId; + + return eHAL_STATUS_SUCCESS; +} + +static tANI_BOOLEAN p2pIsGOportEnabled(tpAniSirGlobal pMac) +{ + + tANI_U8 num_session = 0; + + for (num_session = 0; num_session < MAX_NO_OF_P2P_SESSIONS ; num_session++) + { + if (pMac->p2pContext[num_session].operatingmode == OPERATION_MODE_P2P_GROUP_OWNER) + { + return eANI_BOOLEAN_TRUE; + } + } + + return eANI_BOOLEAN_FALSE; +} + +tANI_BOOLEAN p2pIsOperatingChannEqualListenChann(tHalHandle hHal, tANI_U8 SessionID) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if(pMac->p2pContext[SessionID].P2POperatingChannel == pMac->p2pContext[SessionID].P2PListenChannel) + { + return eANI_BOOLEAN_TRUE; + } + + return eANI_BOOLEAN_FALSE; +} + +eHalStatus p2pGetListenChannel(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 *channel) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + *channel = pMac->p2pContext[SessionID].P2PListenChannel; + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus p2pSetListenChannel(tHalHandle hHal, tANI_U8 SessionID, tANI_U8 channel) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tP2P_OperatingChannel p2pListenChannel; + eHalStatus status = eHAL_STATUS_SUCCESS; + + if(csrRoamIsChannelValid(pMac, channel)) + { + pMac->p2pContext[SessionID].P2PListenChannel = channel; + p2pGetListenChannelAttrib(pMac, pMac->p2pContext[SessionID].sessionId, &p2pListenChannel); + p2pListenChannel.channel = channel; + p2pUpdateListenChannelAttrib(pMac, pMac->p2pContext[SessionID].sessionId, &p2pListenChannel); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " %s fail with invalid channel %d", __func__, channel); + status = eHAL_STATUS_INVALID_PARAMETER; + } + + return status; +} + + + +eHalStatus p2pStopDiscovery(tHalHandle hHal, tANI_U8 SessionID) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = vos_timer_stop(&pMac->p2pContext[SessionID].discoverTimer); + if (status != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s Timer Stop status %d", __func__, status); + return status; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s Timer Stop status %d", __func__, status); + p2pCallDiscoverCallback(&pMac->p2pContext[SessionID], eP2P_DIRECTED_DISCOVER); + + status = p2pFsm( &pMac->p2pContext[SessionID], eP2P_TRIGGER_DISCONNECTED ); + + return status; +} + +//Purge P2P device/GO from the list +eHalStatus p2pPurgeDeviceList(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry, *pNext; + tCsrScanResult *pBssResult; + tDot11fBeaconIEs *pIes; + + csrLLLock(pList); + + pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); + while( NULL != pEntry ) + { + pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pBssResult = GET_BASE_ADDR( pEntry, tCsrScanResult, Link ); + pIes = NULL; + if(!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac, &pBssResult->Result.BssDescriptor, &pIes))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + " %s fail to parse IEs. pEntry (0x%X)", + __func__, pEntry); + pEntry = pNext; + continue; + } + if( pIes->P2PBeaconProbeRes.present ) + { + //Found a P2P BSS + if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK) ) + { + csrFreeScanResultEntry( pMac, pBssResult ); + } + } + vos_mem_free(pIes); + pEntry = pNext; + } + + csrLLUnlock(pList); + + return (status); +} + + +eHalStatus sme_p2pFlushDeviceList(tHalHandle hHal, tANI_U8 HDDSessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = p2pPurgeDeviceList(pMac, &pMac->scan.scanResultList); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +eHalStatus sme_p2pResetSession(tHalHandle hHal, tANI_U8 HDDSessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if(MAX_NO_OF_P2P_SESSIONS > HDDSessionId) + { + p2pResetContext(&pMac->p2pContext[HDDSessionId]); + status = eHAL_STATUS_SUCCESS; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + + +eHalStatus sme_p2pGetResultFilter(tHalHandle hHal, tANI_U8 HDDSessionId, + tCsrScanResultFilter *pFilter) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if(MAX_NO_OF_P2P_SESSIONS > HDDSessionId) + { + status = p2pGetResultFilter(&pMac->p2pContext[HDDSessionId], pFilter); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + + + +#endif //WLAN_FEATURE_P2P_INTERNAL + +eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd) +{ + tpP2pPsConfig pNoA; + tSirMsgQ msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + + pNoA = vos_mem_malloc(sizeof(tP2pPsConfig)); + if ( NULL == pNoA ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pNoA, sizeof(tP2pPsConfig), 0); + pNoA->opp_ps = pNoACmd->u.NoACmd.NoA.opp_ps; + pNoA->ctWindow = pNoACmd->u.NoACmd.NoA.ctWindow; + pNoA->duration = pNoACmd->u.NoACmd.NoA.duration; + pNoA->interval = pNoACmd->u.NoACmd.NoA.interval; + pNoA->count = pNoACmd->u.NoACmd.NoA.count; + pNoA->single_noa_duration = pNoACmd->u.NoACmd.NoA.single_noa_duration; + pNoA->psSelection = pNoACmd->u.NoACmd.NoA.psSelection; + pNoA->sessionid = pNoACmd->u.NoACmd.NoA.sessionid; + msg.type = eWNI_SME_UPDATE_NOA; + msg.bodyval = 0; + msg.bodyptr = pNoA; + limPostMsgApi(pMac, &msg); + } + return status; +} + + + + diff --git a/drivers/staging/prima/CORE/SME/src/pmc/pmc.c b/drivers/staging/prima/CORE/SME/src/pmc/pmc.c new file mode 100644 index 000000000000..f5539ff66927 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/pmc/pmc.c @@ -0,0 +1,2586 @@ +/* + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmc.c +* +* Description: + Power Management Control (PMC) processing routines. +* +* +* +******************************************************************************/ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "csrLinkList.h" +#include "csrApi.h" +#include "smeInside.h" +#include "sme_Api.h" +#include "smsDebug.h" +#include "pmc.h" +#include "wlan_qct_wda.h" +#include "wlan_ps_wow_diag.h" +#include "csrInsideApi.h" + +static void pmcProcessDeferredMsg( tpAniSirGlobal pMac ); + +/****************************************************************************** +* +* Name: pmcEnterLowPowerState +* +* Description: +* Have the device enter Low Power State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterLowPowerState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterLowPowerState")); + + /* If already in Low Power State, just return. */ + if (pMac->pmc.pmcState == LOW_POWER) + return eHAL_STATUS_SUCCESS; + + /* Cancel any running timers. */ + if (vos_timer_stop(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); + return eHAL_STATUS_FAILURE; + } + + pmcStopTrafficTimer(hHal); + + if (vos_timer_stop(&pMac->pmc.hExitPowerSaveTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel exit power save mode timer")); + return eHAL_STATUS_FAILURE; + } + + /* Do all the callbacks. */ + pmcDoCallbacks(hHal, eHAL_STATUS_FAILURE); + + /* Change state. */ + pMac->pmc.pmcState = LOW_POWER; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcExitLowPowerState +* +* Description: +* Have the device exit the Low Power State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcExitLowPowerState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcExitLowPowerState")); + + /* Must be in Low Power State if we are going to exit that state. */ + if (pMac->pmc.pmcState != LOW_POWER) + { + pmcLog(pMac, LOGE, FL("Cannot exit Low Power State if not in that state")); + return eHAL_STATUS_FAILURE; + } + + /* Both WLAN switches much be on to exit Low Power State. */ + if ((pMac->pmc.hwWlanSwitchState == ePMC_SWITCH_OFF) || (pMac->pmc.swWlanSwitchState == ePMC_SWITCH_OFF)) + return eHAL_STATUS_SUCCESS; + + /* Change state. */ + pMac->pmc.pmcState = FULL_POWER; + if(pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterFullPowerState +* +* Description: +* Have the device enter the Full Power State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterFullPowerState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG1, FL("PMC state is %d"), pMac->pmc.pmcState); + + /* Take action based on the current state. */ + switch (pMac->pmc.pmcState) + { + + /* Already in Full Power State. */ + case FULL_POWER: + break; + + /* Notify everyone that we are going to full power. + Change to Full Power State. */ + case REQUEST_FULL_POWER: + case REQUEST_IMPS: + case REQUEST_BMPS: + case REQUEST_STANDBY: + + /* Change state. */ + pMac->pmc.pmcState = FULL_POWER; + pMac->pmc.requestFullPowerPending = FALSE; + + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + + pmcProcessDeferredMsg( pMac ); + /* Do all the callbacks. */ + pmcDoCallbacks(hHal, eHAL_STATUS_SUCCESS); + + /* Update registerd modules that we are entering Full Power. This is + only way to inform modules if PMC exited a power save mode because + of error conditions or if som other module requested full power */ + pmcDoDeviceStateUpdateCallbacks(hHal, FULL_POWER); + break; + + /* Cannot go directly to Full Power State from these states. */ + default: + pmcLog(pMac, LOGE, FL("Trying to enter Full Power State from state %d"), pMac->pmc.pmcState); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + pmcLog(pMac, LOG1, "PMC: Enter full power done"); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestFullPowerState +* +* Description: +* Have the device enter the Request Full Power State. +* +* Parameters: +* hHal - HAL handle for device +* fullPowerReason - Reason code for requesting full power +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestFullPowerState (tHalHandle hHal, tRequestFullPowerReason fullPowerReason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG1, FL("Enter. PMC state is %d"), pMac->pmc.pmcState); + + /* Take action based on the current state of the device. */ + switch (pMac->pmc.pmcState) + { + + /* Should not request full power if already there. */ + case FULL_POWER: + pmcLog(pMac, LOGE, FL("Requesting Full Power State when already there")); + return eHAL_STATUS_FAILURE; + + /* Only power events can take device out of Low Power State. */ + case LOW_POWER: + pmcLog(pMac, LOGE, FL("Cannot request exit from Low Power State")); + return eHAL_STATUS_FAILURE; + + /* Cannot go directly to Request Full Power state from these states. + Record that this is pending and take care of it later. */ + case REQUEST_IMPS: + case REQUEST_START_UAPSD: + case REQUEST_STOP_UAPSD: + case REQUEST_STANDBY: + case REQUEST_BMPS: + case REQUEST_ENTER_WOWL: + case REQUEST_EXIT_WOWL: + pmcLog(pMac, LOGW, FL("Request for full power is being buffered. " + "Current state is %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), + pMac->pmc.pmcState); + //Ignore the new reason if request for full power is already pending + if( !pMac->pmc.requestFullPowerPending ) + { + pMac->pmc.requestFullPowerPending = TRUE; + pMac->pmc.requestFullPowerReason = fullPowerReason; + } + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device enter full power mode. */ + case IMPS: + if ( pMac->pmc.rfSuppliesVotedOff ) + { + pMac->pmc.rfSuppliesVotedOff = FALSE; + } + + if (pmcIssueCommand( pMac, eSmeCommandExitImps, NULL, 0, FALSE ) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message " + "eSmeCommandExitImps")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device enter full power mode. */ + case BMPS: + { + tExitBmpsInfo exitBmpsInfo; + exitBmpsInfo.exitBmpsReason = fullPowerReason; + + if (pmcIssueCommand(hHal, eSmeCommandExitBmps, &exitBmpsInfo, sizeof(tExitBmpsInfo), FALSE) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message " + "eSmeCommandExitBmps")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + /* Already in Request Full Power State. */ + case REQUEST_FULL_POWER: + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device enter full power mode. */ + case STANDBY: + if ( pMac->pmc.rfSuppliesVotedOff ) + { + pMac->pmc.rfSuppliesVotedOff = FALSE; + } + + if (pmcIssueCommand(hHal, eSmeCommandExitImps, NULL, 0, FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message " + "eWNI_PMC_EXIT_IMPS_REQ")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device exit UAPSD mode first */ + case UAPSD: + //Need to save the reason code here in case later on we need to exit BMPS as well + if (pmcIssueCommand(hHal, eSmeCommandExitUapsd, &fullPowerReason, sizeof(tRequestFullPowerReason), FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + /* Tell MAC to have device exit WOWL mode first */ + case WOWL: + if (pmcIssueCommand(hHal, eSmeCommandExitWowl, &fullPowerReason, sizeof(tRequestFullPowerReason), FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message " + "eWNI_PMC_EXIT_WOWL_REQ")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + /* Cannot go directly to Request Full Power State from these states. */ + default: + pmcLog(pMac, LOGE, + FL("Trying to enter Request Full Power State from state %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), + pMac->pmc.pmcState); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestImpsState +* +* Description: +* Have the device enter the Request IMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestImpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterRequestImpsState")); + + /* Can enter Request IMPS State only from Full Power State. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, FL("Trying to enter Request IMPS State from state %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Make sure traffic timer that triggers bmps entry is not running */ + pmcStopTrafficTimer(hHal); + + /* Tell MAC to have device enter IMPS mode. */ + if (pmcIssueCommand(hHal, eSmeCommandEnterImps, NULL, 0, FALSE) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message eWNI_PMC_ENTER_IMPS_REQ"); + pMac->pmc.pmcState = FULL_POWER; + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + return eHAL_STATUS_FAILURE; + } + + pmcLog(pMac, LOG2, FL("eWNI_PMC_ENTER_IMPS_REQ sent to PE")); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterImpsState +* +* Description: +* Have the device enter the IMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterImpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pmcLog(pMac, LOG2, FL("Entering pmcEnterImpsState")); + + /* Can enter IMPS State only from Request IMPS State. */ + if (pMac->pmc.pmcState != REQUEST_IMPS) + { + pmcLog(pMac, LOGE, FL("Trying to enter IMPS State from state %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = IMPS; + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + + /* Start exit IMPS sequence now. */ + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + /* Set timer to come out of IMPS.only if impsPeriod is non-Zero*/ + if(0 != pMac->pmc.impsPeriod) + { + if (vos_timer_start(&pMac->pmc.hImpsTimer, pMac->pmc.impsPeriod) != VOS_STATUS_SUCCESS) + { + PMC_ABORT; + pMac->pmc.ImpsReqTimerFailed = VOS_TRUE; + if (!(pMac->pmc.ImpsReqTimerfailCnt & 0xF)) + { + pMac->pmc.ImpsReqTimerfailCnt++; + pmcLog(pMac, LOGE, + FL("Cannot start IMPS timer, FailCnt - %d"), pMac->pmc.ImpsReqTimerfailCnt); + } + pmcEnterRequestFullPowerState(hHal, eSME_REASON_OTHER); + return eHAL_STATUS_FAILURE; + } + if (pMac->pmc.ImpsReqTimerfailCnt) + { + pmcLog(pMac, LOGE, + FL("Start IMPS timer was failed %d times before success"), pMac->pmc.ImpsReqTimerfailCnt); + } + pMac->pmc.ImpsReqTimerfailCnt = 0; + } + + pMac->pmc.rfSuppliesVotedOff= TRUE; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestBmpsState +* +* Description: +* Have the device enter the Request BMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestBmpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcEnterRequestBmpsState")); + + if (pMac->isCoexScoIndSet) + { + pmcLog(pMac, LOGE, FL("block entering into BMPS mode in SCO case %d\n"), + pMac->isCoexScoIndSet); + return eHAL_STATUS_FAILURE; + } + /* Can enter Request BMPS State only from Full Power State. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, + FL("Trying to enter Request BMPS State from state %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Stop Traffic timer if running. Note: timer could have expired because of possible + race conditions. So no need to check for errors. Just make sure timer is not running */ + pmcStopTrafficTimer(hHal); + + /* Tell MAC to have device enter BMPS mode. */ + if ( !pMac->pmc.bmpsRequestQueued ) + { + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_TRUE; + if(pmcIssueCommand(hHal, eSmeCommandEnterBmps, NULL, 0, FALSE) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message eWNI_PMC_ENTER_BMPS_REQ")); + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + pMac->pmc.pmcState = FULL_POWER; + if(pmcShouldBmpsTimerRun(pMac)) + { + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + return eHAL_STATUS_FAILURE; + } + } + else + { + pmcLog(pMac, LOG1, FL("PMC: enter BMPS command already queued")); + //restart the timer if needed + if(pmcShouldBmpsTimerRun(pMac)) + { + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + return eHAL_STATUS_SUCCESS; + } + + pmcLog(pMac, LOG1, FL("eWNI_PMC_ENTER_BMPS_REQ sent to PE")); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterBmpsState +* +* Description: +* Have the device enter the BMPS State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterBmpsState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG1, FL("Enter. PMC state is %d"), pMac->pmc.pmcState); + + /* Can enter BMPS State only from 5 states. */ + if (pMac->pmc.pmcState != REQUEST_BMPS && + pMac->pmc.pmcState != REQUEST_START_UAPSD && + pMac->pmc.pmcState != REQUEST_STOP_UAPSD && + pMac->pmc.pmcState != REQUEST_ENTER_WOWL && + pMac->pmc.pmcState != REQUEST_EXIT_WOWL) + { + pmcLog(pMac, LOGE, FL("Trying to enter BMPS State from state %d"), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = BMPS; + + /* Update registerd modules that we are entering BMPS. This is + only way to inform modules if PMC entered BMPS power save mode + on its own because of traffic timer */ + pmcDoDeviceStateUpdateCallbacks(hHal, BMPS); + + /* If we have a reqeust for full power pending then we have to go directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + + /* Start exit BMPS sequence now. */ + pmcLog(pMac, LOGW, FL("Pending Full Power request found on entering BMPS mode. " + "Start exit BMPS exit sequence")); + //Note: Reason must have been set when requestFullPowerPending flag was set. + pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + return eHAL_STATUS_SUCCESS; + } + + /*This should never happen ideally. WOWL and UAPSD not supported at the same time */ + if (pMac->pmc.wowlModeRequired && pMac->pmc.uapsdSessionRequired) + { + pmcLog(pMac, LOGW, FL("Both UAPSD and WOWL is required on entering BMPS mode. " + "UAPSD will be prioritized over WOWL")); + } + + /* Do we need Uapsd?*/ + if (pMac->pmc.uapsdSessionRequired) + { + pmcLog(pMac, LOGW, FL("UAPSD session is required on entering BMPS mode. " + "Start UAPSD entry sequence")); + pmcEnterRequestStartUapsdState(hHal); + return eHAL_STATUS_SUCCESS; + } + + /* Do we need WOWL?*/ + if (pMac->pmc.wowlModeRequired) + { + pmcLog(pMac, LOGW, FL("WOWL is required on entering BMPS mode. " + "Start WOWL entry sequence")); + pmcRequestEnterWowlState(hHal, &(pMac->pmc.wowlEnterParams)); + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcPowerSaveCheck +* +* Description: +* Check if device is allowed to enter a power save mode. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* TRUE - entry is allowed +* FALSE - entry is not allowed at this time +* +******************************************************************************/ +tANI_BOOLEAN pmcPowerSaveCheck (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPowerSaveCheckEntry pPowerSaveCheckEntry; + tANI_BOOLEAN (*checkRoutine) (void *checkContext); + tANI_BOOLEAN bResult=FALSE; + + pmcLog(pMac, LOG2, FL("Entering pmcPowerSaveCheck")); + + /* Call the routines in the power save check routine list. If any + return FALSE, then we cannot go into power save mode. */ + pEntry = csrLLPeekHead(&pMac->pmc.powerSaveCheckList, FALSE); + while (pEntry != NULL) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link); + checkRoutine = pPowerSaveCheckEntry->checkRoutine; + + /* If the checkRoutine is NULL for a paricular entry, proceed with other entries + * in the list */ + if (NULL != checkRoutine) + { + if (!checkRoutine(pPowerSaveCheckEntry->checkContext)) + { + pmcLog(pMac, LOG1, FL("pmcPowerSaveCheck fail!")); + bResult = FALSE; + break; + } + else + { + bResult = TRUE; + } + } + pEntry = csrLLNext(&pMac->pmc.powerSaveCheckList, pEntry, FALSE); + } + + return bResult; +} + + +/****************************************************************************** +* +* Name: pmcSendPowerSaveConfigMessage +* +* Description: +* Send a message to PE/MAC to configure the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - message successfuly sent +* eHAL_STATUS_FAILURE - error while sending message +* +******************************************************************************/ +eHalStatus pmcSendPowerSaveConfigMessage (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirPowerSaveCfg powerSaveConfig; + + pmcLog(pMac, LOG2, FL("Entering pmcSendPowerSaveConfigMessage")); + + vos_mem_set(&(powerSaveConfig), sizeof(tSirPowerSaveCfg), 0); + + switch (pMac->pmc.bmpsConfig.forwardBeacons) + { + case ePMC_NO_BEACONS: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_NONE; + break; + case ePMC_BEACONS_WITH_TIM_SET: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_TIM; + break; + case ePMC_BEACONS_WITH_DTIM_SET: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_DTIM; + break; + case ePMC_NTH_BEACON: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_NTH; + powerSaveConfig.nthBeaconFwd = (tANI_U16)pMac->pmc.bmpsConfig.valueOfN; + break; + case ePMC_ALL_BEACONS: + powerSaveConfig.beaconFwd = ePM_BEACON_FWD_NTH; + powerSaveConfig.nthBeaconFwd = 1; + break; + } + powerSaveConfig.fEnablePwrSaveImmediately = pMac->pmc.bmpsConfig.setPmOnLastFrame; + powerSaveConfig.fPSPoll = pMac->pmc.bmpsConfig.usePsPoll; + powerSaveConfig.fEnableBeaconEarlyTermination = + pMac->pmc.bmpsConfig.enableBeaconEarlyTermination; + powerSaveConfig.bcnEarlyTermWakeInterval = + pMac->pmc.bmpsConfig.bcnEarlyTermWakeInterval; + + /* setcfg for listenInterval. Make sure CFG is updated because PE reads this + from CFG at the time of assoc or reassoc */ + ccmCfgSetInt(pMac, WNI_CFG_LISTEN_INTERVAL, pMac->pmc.bmpsConfig.bmpsPeriod, + NULL, eANI_BOOLEAN_FALSE); + + if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS ) + { + //Wake up the chip first + eHalStatus status = pmcDeferMsg( pMac, eWNI_PMC_PWR_SAVE_CFG, + &powerSaveConfig, sizeof(tSirPowerSaveCfg) ); + + if( eHAL_STATUS_PMC_PENDING == status ) + { + return eHAL_STATUS_SUCCESS; + } + else + { + //either fail or already in full power + if( !HAL_STATUS_SUCCESS( status ) ) + { + return ( status ); + } + //else let it through because it is in full power state + } + } + /* Send a message so that FW System config is also updated and is in sync with + the CFG.*/ + if (pmcSendMessage(hHal, eWNI_PMC_PWR_SAVE_CFG, &powerSaveConfig, sizeof(tSirPowerSaveCfg)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_PWR_SAVE_CFG to PE failed")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcSendMessage +* +* Description: +* Send a message to PE/MAC. +* +* Parameters: +* hHal - HAL handle for device +* messageType - message type to send +* pMessageData - pointer to message data +* messageSize - Size of the message data +* +* Returns: +* eHAL_STATUS_SUCCESS - message successfuly sent +* eHAL_STATUS_FAILURE - error while sending message +* +******************************************************************************/ +eHalStatus pmcSendMessage (tpAniSirGlobal pMac, tANI_U16 messageType, void *pMessageData, tANI_U32 messageSize) +{ + tSirMbMsg *pMsg; + + pmcLog(pMac, LOG2, FL("Entering pmcSendMessage, message type %d"), messageType); + + /* Allocate and fill in message. */ + pMsg = vos_mem_malloc(WNI_CFG_MB_HDR_LEN + messageSize); + if ( NULL == pMsg ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for message")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + pMsg->type = messageType; + pMsg->msgLen = (tANI_U16) (WNI_CFG_MB_HDR_LEN + messageSize); + if (messageSize > 0) + { + vos_mem_copy(pMsg->data, pMessageData, messageSize); + } + + /* Send message. */ + if (palSendMBMessage(pMac->hHdd, pMsg) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot send message")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcDoCallbacks +* +* Description: +* Call the IMPS callback routine and the routines in the request full +* power callback routine list. +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - status to pass to the callback routines +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpRequestFullPowerEntry pRequestFullPowerEntry; + + pmcLog(pMac, LOG2, FL("Enter")); + + /* Call IMPS callback routine. */ + if (pMac->pmc.impsCallbackRoutine != NULL) + { + pMac->pmc.impsCallbackRoutine(pMac->pmc.impsCallbackContext, callbackStatus); + pMac->pmc.impsCallbackRoutine = NULL; + } + + /* Call the routines in the request full power callback routine list. */ + while (NULL != (pEntry = csrLLRemoveHead(&pMac->pmc.requestFullPowerList, TRUE))) + { + pRequestFullPowerEntry = GET_BASE_ADDR(pEntry, tRequestFullPowerEntry, link); + if (pRequestFullPowerEntry->callbackRoutine) + pRequestFullPowerEntry->callbackRoutine(pRequestFullPowerEntry->callbackContext, callbackStatus); + vos_mem_free(pRequestFullPowerEntry); + } + +} + + +/****************************************************************************** +* +* Name: pmcStartTrafficTimer +* +* Description: +* Start the timer used in Full Power State to measure traffic +* levels and determine when to enter BMPS. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - timer successfuly started +* eHAL_STATUS_FAILURE - error while starting timer +* +******************************************************************************/ +eHalStatus pmcStartTrafficTimer (tHalHandle hHal, tANI_U32 expirationTime) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + + pmcLog(pMac, LOG1, FL("Enter. Timer duration is %d"), expirationTime); + + vosStatus = vos_timer_start(&pMac->pmc.hTrafficTimer, expirationTime); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + if( VOS_STATUS_E_ALREADY == vosStatus ) + { + //Consider this ok since the timer is already started. + pmcLog(pMac, LOGW, FL(" traffic timer is already started")); + } + else + { + pmcLog(pMac, LOGP, FL("Cannot start traffic timer")); + return eHAL_STATUS_FAILURE; + } + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcStopTrafficTimer +* +* Description: +* Cancels the timer (if running) used in Full Power State to measure traffic +* levels and determine when to enter BMPS. +* +* Parameters: +* hHal - HAL handle for device +* +* +******************************************************************************/ +void pmcStopTrafficTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pmcLog(pMac, LOG2, FL("Entering pmcStopTrafficTimer")); + vos_timer_stop(&pMac->pmc.hTrafficTimer); +} + + +/****************************************************************************** +* +* Name: pmcImpsTimerExpired +* +* Description: +* Called when IMPS timer expires. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcImpsTimerExpired (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcImpsTimerExpired")); + + /* If timer expires and we are in a state other than IMPS State then something is wrong. */ + if (pMac->pmc.pmcState != IMPS) + { + pmcLog(pMac, LOGE, FL("Got IMPS timer expiration in state %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), pMac->pmc.pmcState); + PMC_ABORT; + return; + } + + /* Start on the path of going back to full power. */ + pmcEnterRequestFullPowerState(hHal, eSME_REASON_OTHER); +} + + +/****************************************************************************** +* +* Name: pmcTrafficTimerExpired +* +* Description: +* Called when traffic measurement timer expires. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcTrafficTimerExpired (tHalHandle hHal) +{ + + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + VOS_STATUS vosStatus; + + pmcLog(pMac, LOG2, FL("BMPS Traffic timer expired")); + + /* If timer expires and we are in a state other than Full Power State then something is wrong. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, FL("Got traffic timer expiration in state %s (%d)"), + sme_PmcStatetoString(pMac->pmc.pmcState), pMac->pmc.pmcState); + return; + } + + /* Untill DHCP and set key is not completed remain in power active */ + if (pMac->pmc.remainInPowerActiveTillDHCP || pMac->pmc.full_power_till_set_key) + { + pmcLog(pMac, LOG1, + FL("BMPS Traffic Timer expired before DHCP (%d) or set key (%d) completion ignore enter BMPS"), + pMac->pmc.remainInPowerActiveTillDHCP, pMac->pmc.full_power_till_set_key); + pMac->pmc.remainInPowerActiveThreshold++; + if( pMac->pmc.remainInPowerActiveThreshold >= DHCP_REMAIN_POWER_ACTIVE_THRESHOLD) + { + pmcLog(pMac, LOGE, + FL("Remain in power active DHCP threshold reached FALLBACK to enable enter BMPS")); + /*FALLBACK: reset the flag to make BMPS entry possible*/ + pMac->pmc.remainInPowerActiveTillDHCP = FALSE; + pMac->pmc.full_power_till_set_key = false; + pMac->pmc.remainInPowerActiveThreshold = 0; + } + //Activate the Traffic Timer again for entering into BMPS + vosStatus = vos_timer_start(&pMac->pmc.hTrafficTimer, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) && (VOS_STATUS_E_ALREADY != vosStatus) ) + { + pmcLog(pMac, LOGP, FL("Cannot re-start traffic timer")); + } + return; + } + + /* Clear remain in power active threshold */ + pMac->pmc.remainInPowerActiveThreshold = 0; + + /* Check if the timer should be running */ + if (!pmcShouldBmpsTimerRun(pMac)) + { + pmcLog(pMac, LOGE, FL("BMPS timer should not be running")); + return; + } + +#ifdef FEATURE_WLAN_TDLS + if (pMac->isTdlsPowerSaveProhibited) + { + pmcLog(pMac, LOGE, FL("TDLS peer(s) connected/discovery sent. Dont enter BMPS")); + return; + } +#endif + + if (pmcPowerSaveCheck(hHal)) + { + pmcLog(pMac, LOG1, FL("BMPS entry criteria satisfied. Requesting BMPS state")); + (void)pmcEnterRequestBmpsState(hHal); + } + else + { + /*Some module voted against Power Save. + * So timer should be restarted again to retry BMPS + */ + pmcLog(pMac, LOGW, + FL("Power Save check failed. Retry BMPS again later")); + //Since hTrafficTimer is a vos_timer now, we need to restart the timer here + vosStatus = vos_timer_start(&pMac->pmc.hTrafficTimer, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) && (VOS_STATUS_E_ALREADY != vosStatus) ) + { + pmcLog(pMac, LOGP, FL("Cannot start traffic timer")); + return; + } + } +} + + +/****************************************************************************** +* +* Name: pmcExitPowerSaveTimerExpired +* +* Description: +* Called when timer used to schedule a deferred power save mode exit expires. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcExitPowerSaveTimerExpired (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcExitPowerSaveTimerExpired")); + + /* Make sure process of exiting power save mode might hasn't already been started due to another trigger. */ + if (pMac->pmc.requestFullPowerPending) + + /* Start on the path of going back to full power. */ + pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); +} + +/****************************************************************************** +* +* Name: pmcDoBmpsCallbacks +* +* Description: +* Call the registered BMPS callback routines because device is unable to +* enter BMPS state +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - Success or Failure. +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoBmpsCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpRequestBmpsEntry pRequestBmpsEntry; + + pmcLog(pMac, LOG1, FL("Enter")); + + /* Call the routines in the request BMPS callback routine list. */ + csrLLLock(&pMac->pmc.requestBmpsList); + pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE); + while (pEntry != NULL) + { + pRequestBmpsEntry = GET_BASE_ADDR(pEntry, tRequestBmpsEntry, link); + if (pRequestBmpsEntry->callbackRoutine) + pRequestBmpsEntry->callbackRoutine(pRequestBmpsEntry->callbackContext, + callbackStatus); + vos_mem_free(pRequestBmpsEntry); + pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE); + } + csrLLUnlock(&pMac->pmc.requestBmpsList); +} + + + + +/****************************************************************************** +* +* Name: pmcDoStartUapsdCallbacks +* +* Description: +* Call the registered UAPSD callback routines because device is unable to +* start UAPSD state +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - Success or Failure. +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoStartUapsdCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpStartUapsdEntry pStartUapsdEntry; + + pmcLog(pMac, LOG1, FL("Enter")); + csrLLLock(&pMac->pmc.requestStartUapsdList); + /* Call the routines in the request start UAPSD callback routine list. */ + pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE); + while (pEntry != NULL) + { + pStartUapsdEntry = GET_BASE_ADDR(pEntry, tStartUapsdEntry, link); + pStartUapsdEntry->callbackRoutine(pStartUapsdEntry->callbackContext, + callbackStatus); + vos_mem_free(pStartUapsdEntry); + pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE); + } + csrLLUnlock(&pMac->pmc.requestStartUapsdList); +} + +/****************************************************************************** +* +* Name: pmcEnterRequestStartUapsdState +* +* Description: +* Have the device enter the UAPSD State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestStartUapsdState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG1, FL("Enter. PMC State is %d"), pMac->pmc.pmcState); + + /* Can enter UAPSD State only from FULL_POWER or BMPS State. */ + switch (pMac->pmc.pmcState) + { + case FULL_POWER: + /* UAPSD mode will be attempted when we enter BMPS later */ + pMac->pmc.uapsdSessionRequired = TRUE; + + /* Check that entry into a power save mode is allowed at this time. */ + if (!pmcPowerSaveCheck(hHal)) + { + pmcLog(pMac, LOGW, "PMC: Power save check failed. UAPSD request " + "will be accepted and buffered"); + /* Make sure the BMPS retry timer is running */ + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + else + { + /* PowerSaveCheck passed, put the device into BMPS first */ + if(pmcEnterRequestBmpsState(hHal) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: Device in Full Power. Enter Request Bmps failed. " + "UAPSD request will be dropped "); + return eHAL_STATUS_FAILURE; + } + } + break; + + case BMPS: + { + tANI_U8 staticUapsdMask = 0; + csrGetStaticUapsdMask(pMac, &staticUapsdMask); + + //It is already in BMPS mode, check BTC state +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if (btcIsReadyForUapsd(pMac) || staticUapsdMask) +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + { + /* BTC is OK with Uapsd or static Uapsd is configured, then tell + MAC to have device enter UAPSD mode. */ + if (pmcIssueCommand(hHal, eSmeCommandEnterUapsd, NULL, 0, FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_BMPS_REQ"); + return eHAL_STATUS_FAILURE; + } + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + else + { + //Not ready for UAPSD at this time, save it first and wake up the chip + pmcLog(pMac, LOGE, "Uapsd not needed now, PMC state = %d" + "btcIsUapsdOk:%d staticUapsdMask:0x%x",pMac->pmc.pmcState, + btcIsReadyForUapsd(pMac), staticUapsdMask); + pMac->pmc.uapsdSessionRequired = TRUE; + } +#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + break; + + case REQUEST_START_UAPSD: + pmcLog(pMac, LOGE, "Request Uapsd in progress"); + break; + + case REQUEST_BMPS: + /* Buffer request for UAPSD mode. */ + pMac->pmc.uapsdSessionRequired = TRUE; + pmcLog(pMac, LOGE, "Request BMPS in progress"); + break; + + default: + pmcLog(pMac, LOGE, "PMC: trying to enter UAPSD State from state %d", + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterUapsdState +* +* Description: +* Have the device enter the UAPSD State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterUapsdState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Enter")); + + /* Can enter UAPSD State only from Request UAPSD State. */ + if (pMac->pmc.pmcState != REQUEST_START_UAPSD ) + { + pmcLog(pMac, LOGE, FL("PMC: trying to enter UAPSD State from state %d"), + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = UAPSD; + + /* Update registerd modules that we are entering UAPSD. This is + only way to inform modules if PMC resumed UAPSD power save mode + on its own after full power mode */ + pmcDoDeviceStateUpdateCallbacks(hHal, UAPSD); + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + /* Start exit UAPSD sequence now. */ + pmcLog(pMac, LOG1, FL("Full power request pending. Exit UAPSD")); + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcEnterRequestStopUapsdState +* +* Description: +* Have the device Stop the UAPSD State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestStopUapsdState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterRequestStopUapsdState"); + + /* If already in REQUEST_STOP_UAPSD, simply return */ + if (pMac->pmc.pmcState == REQUEST_STOP_UAPSD) + { + return eHAL_STATUS_SUCCESS; + } + + /* Can enter Request Stop UAPSD State only from UAPSD */ + if (pMac->pmc.pmcState != UAPSD) + { + pmcLog(pMac, LOGE, "PMC: trying to enter Request Stop UAPSD State from " + "state %d", pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Tell MAC to have device exit UAPSD mode. */ + if (pmcIssueCommand(hHal, eSmeCommandExitUapsd, NULL, 0, FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ"); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterRequestStandbyState +* +* Description: +* Have the device enter the Request STANDBY State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterRequestStandbyState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterRequestStandbyState"); + + /* Can enter Standby State only from Full Power State. */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, FL("PMC: trying to enter Standby State from " + "state %d"), pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + // Stop traffic timer. Just making sure timer is not running + pmcStopTrafficTimer(hHal); + + /* Tell MAC to have device enter STANDBY mode. We are using the same message + as IMPS mode to avoid code changes in layer below (PE/HAL)*/ + if (pmcIssueCommand(hHal, eSmeCommandEnterStandby, NULL, 0, FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message " + "eWNI_PMC_ENTER_IMPS_REQ")); + pMac->pmc.pmcState = FULL_POWER; + + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterStandbyState +* +* Description: +* Have the device enter the STANDBY State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterStandbyState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Enter")); + + /* Can enter STANDBY State only from REQUEST_STANDBY State. */ + if (pMac->pmc.pmcState != REQUEST_STANDBY) + { + pmcLog(pMac, LOGE, FL("PMC: trying to enter STANDBY State from state %d"), + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = STANDBY; + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + /* Start exit STANDBY sequence now. */ + pmcLog(pMac, LOG1, FL("Full power req pending. Exit Standby")); + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + pMac->pmc.rfSuppliesVotedOff= TRUE; + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcDoStandbyCallbacks +* +* Description: +* Call the registered Standby callback routines +* +* Parameters: +* hHal - HAL handle for device +* callbackStatus - Success or Failure. +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcDoStandbyCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcDoStandbyCallbacks"); + + /* Call Standby callback routine. */ + if (pMac->pmc.standbyCallbackRoutine != NULL) + pMac->pmc.standbyCallbackRoutine(pMac->pmc.standbyCallbackContext, callbackStatus); + pMac->pmc.standbyCallbackRoutine = NULL; + pMac->pmc.standbyCallbackContext = NULL; +} + +/****************************************************************************** +* +* Name: pmcGetPmcState +* +* Description: +* Return the PMC state +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* tPmcState (one of IMPS, REQUEST_IMPS, BMPS, REQUEST_BMPS etc) +* +******************************************************************************/ +tPmcState pmcGetPmcState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->pmc.pmcState; +} + +const char* pmcGetPmcStateStr(tPmcState state) +{ + switch(state) + { + case STOPPED: + return "STOPPED"; + case FULL_POWER: + return "FULL_POWER"; + case LOW_POWER: + return "LOW_POWER"; + case IMPS: + return "IMPS"; + case BMPS: + return "BMPS"; + case UAPSD: + return "UAPSD"; + case STANDBY: + return "STANDBY"; + case REQUEST_IMPS: + return "REQUEST_IMPS"; + case REQUEST_BMPS: + return "REQUEST_BMPS"; + case REQUEST_START_UAPSD: + return "REQUEST_START_UAPSD"; + case REQUEST_STOP_UAPSD: + return "REQUEST_STOP_UAPSD"; + case REQUEST_FULL_POWER: + return "REQUEST_FULL_POWER"; + case REQUEST_STANDBY: + return "REQUEST_STANDBY"; + case REQUEST_ENTER_WOWL: + return "REQUEST_ENTER_WOWL"; + case REQUEST_EXIT_WOWL: + return "REQUEST_EXIT_WOWL"; + case WOWL: + return "WOWL"; + default: + break; + } + + return "UNKNOWN"; +} + +void pmcDoDeviceStateUpdateCallbacks (tHalHandle hHal, tPmcState state) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry; + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState); + + pmcLog(pMac, LOG1, FL("PMC - Update registered modules of new device " + "state: %s"), pmcGetPmcStateStr(state)); + + /* Call the routines in the update device state routine list. */ + pEntry = csrLLPeekHead(&pMac->pmc.deviceStateUpdateIndList, FALSE); + while (pEntry != NULL) + { + pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link); + callbackRoutine = pDeviceStateUpdateIndEntry->callbackRoutine; + callbackRoutine(pDeviceStateUpdateIndEntry->callbackContext, state); + pEntry = csrLLNext(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE); + } +} + +/****************************************************************************** +* +* Name: pmcRequestEnterWowlState +* +* Description: +* Have the device enter the WOWL State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - WOWL mode will be entered +* eHAL_STATUS_FAILURE - WOWL mode cannot be entered +* +******************************************************************************/ +eHalStatus pmcRequestEnterWowlState(tHalHandle hHal, tpSirSmeWowlEnterParams wowlEnterParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPESession pSessionEntry; + tANI_U8 peSessionId = 0; + + pSessionEntry = peFindSessionByBssid(pMac, wowlEnterParams->bssId, + &peSessionId); + if (NULL == pSessionEntry) + { + pmcLog(pMac, LOGE, + FL("session does not exist for given BSSId")); + + if (wowlEnterParams != NULL) + vos_mem_free(wowlEnterParams); + + return eHAL_STATUS_FAILURE; + } + + pmcLog(pMac, LOG1, FL("Enter. PMC State is %d"),pMac->pmc.pmcState); + + /* Incase of SAP send command directly */ + if ((pSessionEntry->operMode == BSS_OPERATIONAL_MODE_AP)) + { + if (pmcIssueCommand(hHal, eSmeCommandEnterWowl, wowlEnterParams, + sizeof(tSirSmeWowlEnterParams), FALSE) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, + FL("PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ")); + if (wowlEnterParams != NULL) + vos_mem_free(wowlEnterParams); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + + switch (pMac->pmc.pmcState) + { + case FULL_POWER: + /* Put device in BMPS mode first. This step should NEVER fail. */ + if(pmcEnterRequestBmpsState(hHal) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: Device in Full Power. pmcEnterRequestBmpsState failed. " + "Cannot enter WOWL")); + return eHAL_STATUS_FAILURE; + } + break; + + case REQUEST_BMPS: + pmcLog(pMac, LOGW, FL("PMC: BMPS transaction going on. WOWL request " + "will be buffered")); + break; + + case BMPS: + case WOWL: + /* Tell MAC to have device enter WOWL mode. Note: We accept WOWL request + when we are in WOWL mode. This allows HDD to change WOWL configuration + without having to exit WOWL mode */ + if (pmcIssueCommand(hHal, eSmeCommandEnterWowl, wowlEnterParams, sizeof(tSirSmeWowlEnterParams), FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ")); + return eHAL_STATUS_FAILURE; + } + break; + + case REQUEST_ENTER_WOWL: + //Multiple enter WOWL requests at the same time are not accepted + pmcLog(pMac, LOGE, FL("PMC: Enter WOWL transaction already going on. New WOWL request " + "will be rejected")); + return eHAL_STATUS_FAILURE; + + case REQUEST_EXIT_WOWL: + pmcLog(pMac, LOGW, FL("PMC: Exit WOWL transaction going on. New WOWL request " + "will be buffered")); + break; + + default: + pmcLog(pMac, LOGE, FL("PMC: Trying to enter WOWL State from state %s"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcEnterWowlState +* +* Description: +* Have the device enter the WOWL State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - changing state successful +* eHAL_STATUS_FAILURE - changing state not successful +* +******************************************************************************/ +eHalStatus pmcEnterWowlState (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcEnterWowlState"); + + /* Can enter WOWL State only from Request WOWL State. */ + if (pMac->pmc.pmcState != REQUEST_ENTER_WOWL ) + { + pmcLog(pMac, LOGE, FL("PMC: trying to enter WOWL State from state %d"), + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + + /* Change state. */ + pMac->pmc.pmcState = WOWL; + + /* Clear the buffered command for WOWL */ + pMac->pmc.wowlModeRequired = FALSE; + + /* If we have a reqeust for full power pending then we have to go + directly into full power. */ + if (pMac->pmc.requestFullPowerPending) + { + /* Start exit Wowl sequence now. */ + pmcLog(pMac, LOG1, FL("Full power req pending. Exit Wowl")); + return pmcEnterRequestFullPowerState(hHal, pMac->pmc.requestFullPowerReason); + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcRequestExitWowlState +* +* Description: +* Have the device exit WOWL State. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - Exit WOWL successful +* eHAL_STATUS_FAILURE - Exit WOWL unsuccessful +* +******************************************************************************/ +eHalStatus pmcRequestExitWowlState(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcRequestExitWowlState"); + + switch (pMac->pmc.pmcState) + { + case WOWL: + /* Tell MAC to have device exit WOWL mode. */ + if (pmcIssueCommand(hHal, eSmeCommandExitWowl, NULL, 0, FALSE) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGP, FL("PMC: failure to send message eWNI_PMC_EXIT_WOWL_REQ")); + return eHAL_STATUS_FAILURE; + } + break; + + case REQUEST_ENTER_WOWL: + pmcLog(pMac, LOGP, FL("PMC: Rcvd exit WOWL even before enter WOWL was completed")); + return eHAL_STATUS_FAILURE; + + default: + pmcLog(pMac, LOGW, FL("PMC: Got exit WOWL in state %s(%d). Nothing to do as already out of WOWL"), + pmcGetPmcStateStr(pMac->pmc.pmcState), pMac->pmc.pmcState); + break; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcDoEnterWowlCallbacks +* +* Description: +* Invoke Enter WOWL callbacks +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: None +* +******************************************************************************/ +void pmcDoEnterWowlCallbacks (tHalHandle hHal, eHalStatus callbackStatus) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, "PMC: entering pmcDoWowlCallbacks"); + + /* Call Wowl callback routine. */ + if (pMac->pmc.enterWowlCallbackRoutine != NULL) + pMac->pmc.enterWowlCallbackRoutine(pMac->pmc.enterWowlCallbackContext, callbackStatus); +} + + +static void pmcProcessDeferredMsg( tpAniSirGlobal pMac ) +{ + tPmcDeferredMsg *pDeferredMsg; + tListElem *pEntry; + + while( NULL != ( pEntry = csrLLRemoveHead( &pMac->pmc.deferredMsgList, eANI_BOOLEAN_TRUE ) ) ) + { + pDeferredMsg = GET_BASE_ADDR( pEntry, tPmcDeferredMsg, link ); + switch (pDeferredMsg->messageType) + { + case eWNI_PMC_WOWL_ADD_BCAST_PTRN: + VOS_ASSERT( pDeferredMsg->size == sizeof(tSirWowlAddBcastPtrn) ); + if (pmcSendMessage(pMac, eWNI_PMC_WOWL_ADD_BCAST_PTRN, + &pDeferredMsg->u.wowlAddPattern, sizeof(tSirWowlAddBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed")); + } + break; + + case eWNI_PMC_WOWL_DEL_BCAST_PTRN: + VOS_ASSERT( pDeferredMsg->size == sizeof(tSirWowlDelBcastPtrn) ); + if (pmcSendMessage(pMac, eWNI_PMC_WOWL_DEL_BCAST_PTRN, + &pDeferredMsg->u.wowlDelPattern, sizeof(tSirWowlDelBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed")); + } + break; + + case eWNI_PMC_PWR_SAVE_CFG: + VOS_ASSERT( pDeferredMsg->size == sizeof(tSirPowerSaveCfg) ); + if (pmcSendMessage(pMac, eWNI_PMC_PWR_SAVE_CFG, + &pDeferredMsg->u.powerSaveConfig, sizeof(tSirPowerSaveCfg)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_PWR_SAVE_CFG to PE failed")); + } + break; + + default: + pmcLog(pMac, LOGE, FL("unknown message (%d)"), pDeferredMsg->messageType); + break; + } + //Need to free the memory here + vos_mem_free(pDeferredMsg); + } //while +} + + +eHalStatus pmcDeferMsg( tpAniSirGlobal pMac, tANI_U16 messageType, void *pData, tANI_U32 size) +{ + tPmcDeferredMsg *pDeferredMsg; + eHalStatus status; + + pDeferredMsg = vos_mem_malloc(sizeof(tPmcDeferredMsg)); + if ( NULL == pDeferredMsg ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for callback context")); + return eHAL_STATUS_RESOURCES; + } + vos_mem_set(pDeferredMsg, sizeof(tPmcDeferredMsg), 0); + pDeferredMsg->messageType = messageType; + pDeferredMsg->size = (tANI_U16)size; + if( pData ) + { + vos_mem_copy(&pDeferredMsg->u.data, pData, size); + } + csrLLInsertTail( &pMac->pmc.deferredMsgList, &pDeferredMsg->link, eANI_BOOLEAN_TRUE ); + //No callback is needed. The messages are put into deferred queue and be processed first + //when enter full power is complete. + status = pmcRequestFullPower( pMac, NULL, NULL, eSME_REASON_OTHER ); + if( eHAL_STATUS_PMC_PENDING != status ) + { + //either fail or already in full power + if( csrLLRemoveEntry( &pMac->pmc.deferredMsgList, &pDeferredMsg->link, eANI_BOOLEAN_TRUE ) ) + { + vos_mem_free(pDeferredMsg); + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOGE, FL("failed to request full power status = %d"), status); + } + } + + return (status); +} + +void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + if(!pCommand->u.pmcCmd.fReleaseWhenDone) + { + //This is a normal command, put it back to the free lsit + pCommand->u.pmcCmd.size = 0; + smeReleaseCommand( pMac, pCommand ); + } + else + { + //this is a specially allocated comamnd due to out of command buffer. free it. + vos_mem_free(pCommand); + } +} + + +//this function is used to abort a command where the normal processing of the command +//is terminated without going through the normal path. it is here to take care of callbacks for +//the command, if applicable. +void pmcAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) +{ + if( eSmePmcCommandMask & pCommand->command ) + { + if( !fStopping ) + { + switch( pCommand->command ) + { + case eSmeCommandEnterImps: + pmcLog(pMac, LOGE, FL("aborting request to enter IMPS")); + pmcEnterFullPowerState(pMac); + break; + + case eSmeCommandExitImps: + pmcLog(pMac, LOGE, FL("aborting request to exit IMPS ")); + pmcEnterFullPowerState(pMac); + break; + + case eSmeCommandEnterBmps: + pmcLog(pMac, LOGE, FL("aborting request to enter BMPS ")); + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + pmcEnterFullPowerState(pMac); + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitBmps: + pmcLog(pMac, LOGE, FL("aborting request to exit BMPS ")); + pmcEnterFullPowerState(pMac); + break; + + case eSmeCommandEnterUapsd: + pmcLog(pMac, LOGE, FL("aborting request to enter UAPSD ")); + //Since there is no retry for UAPSD, tell the requester here we are done with failure + pMac->pmc.uapsdSessionRequired = FALSE; + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitUapsd: + pmcLog(pMac, LOGE, FL("aborting request to exit UAPSD ")); + break; + + case eSmeCommandEnterWowl: + pmcLog(pMac, LOGE, FL("aborting request to enter WOWL ")); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + case eSmeCommandExitWowl: + pmcLog(pMac, LOGE, FL("aborting request to exit WOWL ")); + break; + + case eSmeCommandEnterStandby: + pmcLog(pMac, LOGE, FL("aborting request to enter Standby ")); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE); + break; + + default: + pmcLog(pMac, LOGE, FL("Request for PMC command (%d) is dropped"), pCommand->command); + break; + } + }// !stopping + pmcReleaseCommand( pMac, pCommand ); + } +} + + + +//These commands are not supposed to fail due to out of command buffer, +//otherwise other commands are not executed and no command is released. It will be deadlock. +#define PMC_IS_COMMAND_CANNOT_FAIL(cmdType)\ + ( (eSmeCommandEnterStandby == (cmdType )) ||\ + (eSmeCommandExitImps == (cmdType )) ||\ + (eSmeCommandExitBmps == (cmdType )) ||\ + (eSmeCommandExitUapsd == (cmdType )) ||\ + (eSmeCommandExitWowl == (cmdType )) ) + +eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tSmeCmd **ppCmd ) +{ + eHalStatus status = eHAL_STATUS_RESOURCES; + tSmeCmd *pCommand = NULL; + + VOS_ASSERT( ppCmd ); + do + { + pCommand = smeGetCommandBuffer( pMac ); + if ( pCommand ) + { + //Make sure it will be put back to the list + pCommand->u.pmcCmd.fReleaseWhenDone = FALSE; + } + else + { + pmcLog( pMac, LOGE, + FL(" fail to get command buffer for command 0x%X curState = %d"), + cmdType, pMac->pmc.pmcState ); + //For certain PMC command, we cannot fail + if( PMC_IS_COMMAND_CANNOT_FAIL(cmdType) ) + { + pmcLog( pMac, LOGE, + FL(" command 0x%X cannot fail try allocating memory for it"), cmdType ); + pCommand = vos_mem_malloc(sizeof(tSmeCmd)); + if ( NULL == pCommand ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s fail to allocate memory for command (0x%X)", + __func__, cmdType); + pCommand = NULL; + return eHAL_STATUS_FAILURE; + } + vos_mem_set(pCommand, sizeof(tSmeCmd), 0); + //Make sure it will be free when it is done + pCommand->u.pmcCmd.fReleaseWhenDone = TRUE; + } + else + { + break; + } + } + pCommand->command = cmdType; + pCommand->u.pmcCmd.size = size; + //Initialize the reason code here. It may be overwritten later when + //a particular reason is needed. + pCommand->u.pmcCmd.fullPowerReason = eSME_REASON_OTHER; + switch ( cmdType ) + { + case eSmeCommandEnterImps: + case eSmeCommandExitImps: + case eSmeCommandEnterBmps: + case eSmeCommandEnterUapsd: + case eSmeCommandEnterStandby: + status = eHAL_STATUS_SUCCESS; + break; + + case eSmeCommandExitUapsd: + case eSmeCommandExitWowl: + status = eHAL_STATUS_SUCCESS; + if( pvParam ) + { + pCommand->u.pmcCmd.fullPowerReason = *( (tRequestFullPowerReason *)pvParam ); + } + break; + + case eSmeCommandExitBmps: + status = eHAL_STATUS_SUCCESS; + if( pvParam ) + { + pCommand->u.pmcCmd.u.exitBmpsInfo = *( (tExitBmpsInfo *)pvParam ); + pCommand->u.pmcCmd.fullPowerReason = pCommand->u.pmcCmd.u.exitBmpsInfo.exitBmpsReason; + } + else + { + pmcLog( pMac, LOGE, (" exit BMPS must have a reason code") ); + } + break; + + case eSmeCommandEnterWowl: + status = eHAL_STATUS_SUCCESS; + if( pvParam ) + { + pCommand->u.pmcCmd.u.enterWowlInfo = *( ( tSirSmeWowlEnterParams * )pvParam ); + } + break; + + default: + pmcLog( pMac, LOGE, FL(" invalid command type %d"), cmdType ); + status = eHAL_STATUS_INVALID_PARAMETER; + break; + } + + } while( 0 ); + + if( HAL_STATUS_SUCCESS( status ) && pCommand ) + { + *ppCmd = pCommand; + } + else if( pCommand ) + { + pmcReleaseCommand( pMac, pCommand ); + } + + return (status); +} + + +eHalStatus pmcIssueCommand( tpAniSirGlobal pMac, eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tANI_BOOLEAN fPutToListHead ) +{ + eHalStatus status = eHAL_STATUS_RESOURCES; + tSmeCmd *pCommand = NULL; + + status = pmcPrepareCommand( pMac, cmdType, pvParam, size, &pCommand ); + if( HAL_STATUS_SUCCESS( status ) && pCommand ) + { + smePushCommand( pMac, pCommand, fPutToListHead ); + } + else if( pCommand ) + { + pmcReleaseCommand( pMac, pCommand ); + } + + return( status ); +} + + + +tANI_BOOLEAN pmcProcessCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpPESession pSessionEntry; + tANI_U8 peSessionId = 0; + + tANI_BOOLEAN fRemoveCmd = eANI_BOOLEAN_TRUE; + pmcLog(pMac, LOG1, FL("PMC command is 0x%x"), pCommand->command); + do + { + switch ( pCommand->command ) + { + case eSmeCommandEnterImps: + if( FULL_POWER == pMac->pmc.pmcState ) + { + status = pmcEnterImpsCheck( pMac ); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* Change state. */ + pMac->pmc.pmcState = REQUEST_IMPS; + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_IMPS_REQ, NULL, 0); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* If we already went back Full Power State (meaning that request did not + get as far as the device) then we are not successfull. */ + if ( FULL_POWER != pMac->pmc.pmcState ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + } + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOGE, + "PMC: failure to send message eWNI_PMC_ENTER_IMPS_REQ or pmcEnterImpsCheck failed"); + pmcEnterFullPowerState( pMac ); + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + }//full_power + break; + + case eSmeCommandExitImps: + { + tPmcState origState = pMac->pmc.pmcState; + pMac->pmc.requestFullPowerPending = FALSE; + if( ( IMPS == pMac->pmc.pmcState ) || ( STANDBY == pMac->pmc.pmcState ) ) + { + //Check state before sending message. The state may change after that + if( STANDBY == pMac->pmc.pmcState ) + { + //Enable Idle scan in CSR + csrScanResumeIMPS(pMac); + } + + pMac->pmc.pmcState = REQUEST_FULL_POWER; + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_IMPS_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOG1, FL("eWNI_PMC_EXIT_IMPS_REQ sent to PE")); + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pMac->pmc.pmcState = origState; + pmcLog(pMac, LOGE, + FL("eWNI_PMC_EXIT_IMPS_REQ fail to be sent to PE status %d"), status); + //Callbacks are called with success srarus, do we need to pass in real status?? + pmcEnterFullPowerState(pMac); + } + } + } + break; + + case eSmeCommandEnterBmps: + if( FULL_POWER == pMac->pmc.pmcState ) + { + //This function will not return success because the pmc state is not BMPS + status = pmcEnterBmpsCheck( pMac ); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* Change PMC state */ + pMac->pmc.pmcState = REQUEST_BMPS; + pmcLog(pMac, LOG1, "PMC: Enter BMPS req done"); + + /* Tell MAC to have device enter BMPS mode. */ + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_BMPS_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "Fail to send enter BMPS msg to PE"); + } + } + if( !HAL_STATUS_SUCCESS( status ) ) + { + pmcLog(pMac, LOGE, + "PMC: failure to send message eWNI_PMC_ENTER_BMPS_REQ status %d", status); + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + pmcEnterFullPowerState(pMac); + //Do not call UAPSD callback here since it may be retried + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE); + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + } + break; + + case eSmeCommandExitBmps: + if ((BMPS == pMac->pmc.pmcState) || (UAPSD == pMac->pmc.pmcState)) + { + tPmcState origState = pMac->pmc.pmcState; + pMac->pmc.requestFullPowerPending = FALSE; + /* Change PMC state */ + pMac->pmc.pmcState = REQUEST_FULL_POWER; + status = pmcSendMessage( pMac, eWNI_PMC_EXIT_BMPS_REQ, + &pCommand->u.pmcCmd.u.exitBmpsInfo, sizeof(tExitBmpsInfo) ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + pmcLog(pMac, LOG1, FL("eWNI_PMC_EXIT_BMPS_REQ sent to PE")); + + } + else + { + pMac->pmc.pmcState = origState; + pmcLog(pMac, LOGE, FL("eWNI_PMC_EXIT_BMPS_REQ fail to be sent to PE status %d"), status); + pmcEnterFullPowerState(pMac); + } + } + break; + + case eSmeCommandEnterUapsd: + if( BMPS == pMac->pmc.pmcState ) + { + pMac->pmc.uapsdSessionRequired = TRUE; + /* Change PMC state */ + pMac->pmc.pmcState = REQUEST_START_UAPSD; + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_UAPSD_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pMac->pmc.pmcState = BMPS; + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_BMPS_REQ"); + //there is no retry for re-entering UAPSD so tell the requester we are done witgh failure. + pMac->pmc.uapsdSessionRequired = FALSE; + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE); + } + } + break; + + case eSmeCommandExitUapsd: + if( UAPSD == pMac->pmc.pmcState ) + { + pMac->pmc.requestFullPowerPending = FALSE; + /* If already in REQUEST_STOP_UAPSD, simply return */ + if (pMac->pmc.pmcState == REQUEST_STOP_UAPSD) + { + break; + } + + /* Change state. Note that device will be put in BMPS state at the + end of REQUEST_STOP_UAPSD state even if response is a failure*/ + pMac->pmc.pmcState = REQUEST_STOP_UAPSD; + /* Tell MAC to have device exit UAPSD mode. */ + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_UAPSD_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->pmc.requestFullPowerPending = TRUE; + pMac->pmc.requestFullPowerReason = pCommand->u.pmcCmd.fullPowerReason; + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pMac->pmc.pmcState = UAPSD; + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_EXIT_UAPSD_REQ"); + pmcEnterBmpsState(pMac); + } + } + + break; + + case eSmeCommandEnterWowl: + { + tPmcState origState = pMac->pmc.pmcState; + pSessionEntry = peFindSessionByBssid(pMac, + pCommand->u.pmcCmd.u.enterWowlInfo.bssId, + &peSessionId); + if (( BMPS == pMac->pmc.pmcState ) || + ( WOWL == pMac->pmc.pmcState ) || + ((pSessionEntry != NULL) && + (pSessionEntry->operMode == BSS_OPERATIONAL_MODE_AP))) + { + pMac->pmc.pmcState = REQUEST_ENTER_WOWL; + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_WOWL_REQ, + &pCommand->u.pmcCmd.u.enterWowlInfo, sizeof(tSirSmeWowlEnterParams)); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pMac->pmc.pmcState = origState; + pmcLog(pMac, LOGE, + "PMC: failure to send message eWNI_PMC_ENTER_WOWL_REQ in state %d", origState); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE); + } + } + else + { + fRemoveCmd = eANI_BOOLEAN_TRUE; + } + break; + } + case eSmeCommandExitWowl: + if( WOWL == pMac->pmc.pmcState ) + { + pMac->pmc.requestFullPowerPending = FALSE; + pMac->pmc.pmcState = REQUEST_EXIT_WOWL; + status = pmcSendMessage(pMac, eWNI_PMC_EXIT_WOWL_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + fRemoveCmd = eANI_BOOLEAN_FALSE; + pMac->pmc.requestFullPowerPending = TRUE; + pMac->pmc.requestFullPowerReason = pCommand->u.pmcCmd.fullPowerReason; + } + else + { + pMac->pmc.pmcState = WOWL; + pmcLog(pMac, LOGP, "PMC: failure to send message eWNI_PMC_EXIT_WOWL_REQ"); + pmcEnterBmpsState(pMac); + } + } + break; + + case eSmeCommandEnterStandby: + if( FULL_POWER == pMac->pmc.pmcState ) + { + //Disallow standby if concurrent sessions are present. Note that CSR would have + //caused the STA to disconnect the Infra session (if not already disconnected) because of + //standby request. But we are now failing the standby request because of concurrent session. + //So was the tearing of infra session wasteful if we were going to fail the standby request ? + //Not really. This is beacuse if and when BT-AMP etc sessions are torn down we will transition + //to IMPS/standby and still save power. + if (csrIsIBSSStarted(pMac) || csrIsBTAMPStarted(pMac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "WLAN: IBSS or BT-AMP session present. Cannot honor standby request"); + + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_PMC_NOT_NOW); + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + break; + } + + // Stop traffic timer. Just making sure timer is not running + pmcStopTrafficTimer(pMac); + + /* Change state. */ + pMac->pmc.pmcState = REQUEST_STANDBY; + + /* Tell MAC to have device enter STANDBY mode. We are using the same message + as IMPS mode to avoid code changes in layer below (PE/HAL)*/ + status = pmcSendMessage(pMac, eWNI_PMC_ENTER_IMPS_REQ, NULL, 0); + if ( HAL_STATUS_SUCCESS( status ) ) + { + //Disable Idle scan in CSR + csrScanSuspendIMPS(pMac); + fRemoveCmd = eANI_BOOLEAN_FALSE; + } + else + { + pmcLog(pMac, LOGE, "PMC: failure to send message " + "eWNI_PMC_ENTER_IMPS_REQ"); + pMac->pmc.pmcState = FULL_POWER; + pmcEnterFullPowerState(pMac); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE); + /* Start the timer only if Auto BMPS feature is enabled or an UAPSD session is + required */ + if(pmcShouldBmpsTimerRun(pMac)) + (void)pmcStartTrafficTimer(pMac, pMac->pmc.bmpsConfig.trafficMeasurePeriod); + } + } + break; + + default: + pmcLog( pMac, LOGE, FL(" invalid command type %d"), pCommand->command ); + break; + } + + } while( 0 ); + + return( fRemoveCmd ); +} + +eHalStatus pmcEnterImpsCheck( tpAniSirGlobal pMac ) +{ + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting IMPS when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check if IMPS is enabled. */ + if (!pMac->pmc.impsEnabled) + { + pmcLog(pMac, LOG1, FL("IMPS is disabled")); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check if IMPS enabled for current power source. */ + if ((pMac->pmc.powerSource == AC_POWER) && !pMac->pmc.impsConfig.enterOnAc) + { + pmcLog(pMac, LOG1, FL("IMPS is disabled when operating on AC power")); + return eHAL_STATUS_PMC_AC_POWER; + } + + /* Check that entry into a power save mode is allowed at this time. */ + if (!pmcPowerSaveCheck(pMac)) + { + pmcLog(pMac, LOG1, FL("IMPS cannot be entered now")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + /* Check that entry into a power save mode is allowed at this time if all + running sessions agree. */ + if (!pmcAllowImps(pMac)) + { + pmcLog(pMac, LOG1, FL("IMPS cannot be entered now")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + /* Check if already in IMPS. */ + if ((pMac->pmc.pmcState == REQUEST_IMPS) || (pMac->pmc.pmcState == IMPS) || + (pMac->pmc.pmcState == REQUEST_FULL_POWER)) + { + pmcLog(pMac, LOG1, FL("Already in IMPS")); + return eHAL_STATUS_PMC_ALREADY_IN_IMPS; + } + + /* Check whether driver load unload is in progress */ + if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)) + { + pmcLog(pMac, LOGW, FL("Driver load/unload is in progress")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + return ( eHAL_STATUS_SUCCESS ); +} + +/* This API detrmines if it is ok to proceed with a Enter BMPS Request or not . Note when + device is in BMPS/UAPSD states, this API returns failure because it is not ok to issue + a BMPS request */ +eHalStatus pmcEnterBmpsCheck( tpAniSirGlobal pMac ) +{ + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, FL("PMC: Cannot initiate BMPS. BMPS is disabled")); + return eHAL_STATUS_PMC_DISABLED; + } + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting BMPS when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check that we are associated with a single active session. */ + if (!pmcValidateConnectState( pMac )) + { + pmcLog(pMac, VOS_TRACE_LEVEL_INFO, FL("PMC: STA not associated with an AP with single" + " active session. BMPS cannot be entered")); + return eHAL_STATUS_FAILURE; + } + + /* BMPS can only be requested when device is in Full Power */ + if (pMac->pmc.pmcState != FULL_POWER) + { + pmcLog(pMac, LOGE, + FL("PMC: Device not in full power. Cannot request BMPS. pmcState %d"), + pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + /* Check that entry into a power save mode is allowed at this time. */ + if (!pmcPowerSaveCheck(pMac)) + { + pmcLog(pMac, LOGE, FL("PMC: Power save check failed. BMPS cannot be entered now")); + return eHAL_STATUS_PMC_NOT_NOW; + } + + //Remove this code once SLM_Sessionization is supported + //BMPS_WORKAROUND_NOT_NEEDED + if(!IS_FEATURE_SUPPORTED_BY_FW(SLM_SESSIONIZATION)) + { + pmcLog(pMac, LOG1, FL("doBMPSWorkaround %u"), pMac->roam.configParam.doBMPSWorkaround); + if (pMac->roam.configParam.doBMPSWorkaround) + { + pMac->roam.configParam.doBMPSWorkaround = 0; + pmcLog(pMac, LOG1, + FL("reset doBMPSWorkaround to disabled %u"), pMac->roam.configParam.doBMPSWorkaround); + csrDisconnectAllActiveSessions(pMac); + pmcLog(pMac, LOGE, + "PMC: doBMPSWorkaround was enabled. First Disconnect all sessions. pmcState %d", pMac->pmc.pmcState); + return eHAL_STATUS_FAILURE; + } + } + + return ( eHAL_STATUS_SUCCESS ); +} + +tANI_BOOLEAN pmcShouldBmpsTimerRun( tpAniSirGlobal pMac ) +{ + /* Check if BMPS is enabled and if Auto BMPS Feature is still enabled + * or there is a pending Uapsd request or HDD requested BMPS or there + * is a pending request for WoWL. In all these cases BMPS is required. + * Otherwise just stop the timer and return. + */ + if (!(pMac->pmc.bmpsEnabled && (pMac->pmc.autoBmpsEntryEnabled || + pMac->pmc.uapsdSessionRequired || pMac->pmc.bmpsRequestedByHdd || + pMac->pmc.wowlModeRequired ))) + { + pmcLog(pMac, LOG1, FL("BMPS is not enabled or not required")); + return eANI_BOOLEAN_FALSE; + } + + if (pMac->pmc.isHostPsEn && pMac->pmc.remainInPowerActiveTillDHCP) + { + pmcLog(pMac, LOG1, + FL("Host controlled ps enabled, so don't run the timer")); + return eANI_BOOLEAN_FALSE; + } + + if ((vos_concurrent_open_sessions_running()) && + ((csrIsConcurrentInfraConnected( pMac ) || + (vos_get_concurrency_mode()& VOS_SAP) || + (vos_get_concurrency_mode()& VOS_P2P_GO)))) + { + pmcLog(pMac, LOG1, FL("Multiple Sessions/GO/SAP sessions . BMPS should not be started")); + return eANI_BOOLEAN_FALSE; + } + /* Check if there is an Infra session. BMPS is possible only if there is + * an Infra session */ + if (!csrIsInfraConnected(pMac)) + { + pmcLog(pMac, LOG1, FL("No Infra Session. BMPS can't be started")); + return eANI_BOOLEAN_FALSE; + } + return eANI_BOOLEAN_TRUE; +} + +const char * sme_PmcStatetoString(const v_U8_t pmcState) +{ switch (pmcState) + { + CASE_RETURN_STRING( STOPPED ); + CASE_RETURN_STRING( FULL_POWER ); + CASE_RETURN_STRING( LOW_POWER); + CASE_RETURN_STRING( REQUEST_IMPS ); + CASE_RETURN_STRING( IMPS ); + CASE_RETURN_STRING( REQUEST_BMPS ); + CASE_RETURN_STRING( BMPS ); + CASE_RETURN_STRING( REQUEST_FULL_POWER ); + CASE_RETURN_STRING( REQUEST_START_UAPSD ); + CASE_RETURN_STRING( REQUEST_STOP_UAPSD ); + CASE_RETURN_STRING( UAPSD ); + CASE_RETURN_STRING( REQUEST_STANDBY ); + CASE_RETURN_STRING( STANDBY ); + CASE_RETURN_STRING( REQUEST_ENTER_WOWL ); + CASE_RETURN_STRING( REQUEST_EXIT_WOWL ); + CASE_RETURN_STRING( WOWL ); + default: + return "Invalid pmcState"; + } +} diff --git a/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c b/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c new file mode 100644 index 000000000000..e46cd3505148 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/pmc/pmcApi.c @@ -0,0 +1,3622 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmcApi.c +* +* Description: Routines that make up the Power Management Control (PMC) API. +* +* +******************************************************************************/ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "palTimer.h" +#include "csrLinkList.h" +#include "smsDebug.h" +#include "sme_Trace.h" +#include "pmcApi.h" +#include "pmc.h" +#include "cfgApi.h" +#include "smeInside.h" +#include "csrInsideApi.h" +#include "wlan_ps_wow_diag.h" +#include "wlan_qct_wda.h" +#include "limSessionUtils.h" +#include "csrInsideApi.h" + +extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); + +void pmcCloseDeferredMsgList(tpAniSirGlobal pMac); +void pmcCloseDeviceStateUpdateList(tpAniSirGlobal pMac); +void pmcCloseRequestStartUapsdList(tpAniSirGlobal pMac); +void pmcCloseRequestBmpsList(tpAniSirGlobal pMac); +void pmcCloseRequestFullPowerList(tpAniSirGlobal pMac); +void pmcClosePowerSaveCheckList(tpAniSirGlobal pMac); + +/****************************************************************************** +* +* Name: pmcOpen +* +* Description: +* Does a PMC open operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - open successful +* eHAL_STATUS_FAILURE - open not successful +* +******************************************************************************/ +eHalStatus pmcOpen (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcOpen")); + + /* Initialize basic PMC information about device. */ + pMac->pmc.powerSource = BATTERY_POWER; + pMac->pmc.pmcState = STOPPED; + pMac->pmc.pmcReady = FALSE; + + /* Initialize Power Save Modes */ + pMac->pmc.impsEnabled = FALSE; + pMac->pmc.autoBmpsEntryEnabled = FALSE; + pMac->pmc.smpsEnabled = FALSE; + pMac->pmc.uapsdEnabled = TRUE; + pMac->pmc.bmpsEnabled = TRUE; + pMac->pmc.standbyEnabled = TRUE; + pMac->pmc.wowlEnabled = TRUE; + pMac->pmc.rfSuppliesVotedOff= FALSE; + + vos_mem_set(&(pMac->pmc.bmpsConfig), sizeof(tPmcBmpsConfigParams), 0); + vos_mem_set(&(pMac->pmc.impsConfig), sizeof(tPmcImpsConfigParams), 0); + vos_mem_set(&(pMac->pmc.smpsConfig), sizeof(tPmcSmpsConfigParams), 0); + + /* Allocate a timer to use with IMPS. */ + if (vos_timer_init(&pMac->pmc.hImpsTimer, VOS_TIMER_TYPE_SW, pmcImpsTimerExpired, hHal) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot allocate timer for IMPS")); + return eHAL_STATUS_FAILURE; + } + + /* Allocate a timer used in Full Power State to measure traffic + levels and determine when to enter BMPS. */ + if (!VOS_IS_STATUS_SUCCESS(vos_timer_init(&pMac->pmc.hTrafficTimer, + VOS_TIMER_TYPE_SW, pmcTrafficTimerExpired, hHal))) + { + pmcLog(pMac, LOGE, FL("Cannot allocate timer for traffic measurement")); + return eHAL_STATUS_FAILURE; + } + + //Initialize the default value for Bmps related config. + pMac->pmc.bmpsConfig.trafficMeasurePeriod = BMPS_TRAFFIC_TIMER_DEFAULT; + pMac->pmc.bmpsConfig.bmpsPeriod = WNI_CFG_LISTEN_INTERVAL_STADEF; + + /* Allocate a timer used to schedule a deferred power save mode exit. */ + if (vos_timer_init(&pMac->pmc.hExitPowerSaveTimer, VOS_TIMER_TYPE_SW, + pmcExitPowerSaveTimerExpired, hHal) !=VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot allocate exit power save mode timer")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for power save check routines and request full power callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.powerSaveCheckList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot initialize power save check routine list")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestFullPowerList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot initialize request full power callback routine list")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for request BMPS callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestBmpsList) != + eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: cannot initialize request BMPS callback routine list"); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for request start UAPSD callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.requestStartUapsdList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: cannot initialize request start UAPSD callback routine list"); + return eHAL_STATUS_FAILURE; + } + + /* Initialize lists for device state update indication callback routines. */ + if (csrLLOpen(pMac->hHdd, &pMac->pmc.deviceStateUpdateIndList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, "PMC: cannot initialize device state update indication callback list"); + return eHAL_STATUS_FAILURE; + } + + if (csrLLOpen(pMac->hHdd, &pMac->pmc.deferredMsgList) != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot initialize deferred msg list")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcStart +* +* Description: +* Does a PMC start operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - start successful +* eHAL_STATUS_FAILURE - start not successful +* +******************************************************************************/ +eHalStatus pmcStart (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; + + pmcLog(pMac, LOG2, FL("Entering pmcStart")); + + /* Initialize basic PMC information about device. */ + pMac->pmc.pmcState = FULL_POWER; + pMac->pmc.requestFullPowerPending = FALSE; + pMac->pmc.uapsdSessionRequired = FALSE; + pMac->pmc.wowlModeRequired = FALSE; + pMac->pmc.wowlExitSrc = eWOWL_EXIT_USER; + pMac->pmc.isAPWOWExit = FALSE; + pMac->pmc.bmpsRequestedByHdd = FALSE; + pMac->pmc.remainInPowerActiveTillDHCP = FALSE; + pMac->pmc.full_power_till_set_key = false; + pMac->pmc.remainInPowerActiveThreshold = 0; + + /* WLAN Switch initial states. */ + pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_ON; + pMac->pmc.swWlanSwitchState = ePMC_SWITCH_ON; + + /* No IMPS callback routine yet. */ + pMac->pmc.impsCallbackRoutine = NULL; + + /* No STANDBY callback routine yet. */ + pMac->pmc.standbyCallbackRoutine = NULL; + + /* No WOWL callback routine yet. */ + pMac->pmc.enterWowlCallbackRoutine = NULL; + + /* Initialize BMPS traffic counts. */ + pMac->pmc.cLastTxUnicastFrames = 0; + pMac->pmc.cLastRxUnicastFrames = 0; + pMac->pmc.ImpsReqFailed = VOS_FALSE; + pMac->pmc.ImpsReqFailCnt = 0; + pMac->pmc.ImpsReqTimerFailed = 0; + pMac->pmc.ImpsReqTimerfailCnt = 0; + + /* Configure SMPS. */ + if (pMac->pmc.smpsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.smpsConfig.enterOnAc)) + { + if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC; + if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC; + } + else + htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT; + + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + +#if defined(ANI_LOGDUMP) + pmcDumpInit(hHal); +#endif + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcStop +* +* Description: +* Does a PMC stop operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - stop successful +* eHAL_STATUS_FAILURE - stop not successful +* +******************************************************************************/ +eHalStatus pmcStop (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tPmcDeferredMsg *pDeferredMsg; + + pmcLog(pMac, LOG2, FL("Entering pmcStop")); + + /* Cancel any running timers. */ + if (vos_timer_stop(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); + } + + pmcStopTrafficTimer(hHal); + + if (vos_timer_stop(&pMac->pmc.hExitPowerSaveTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel exit power save mode timer")); + } + + /* Do all the callbacks. */ + pmcDoCallbacks(hHal, eHAL_STATUS_FAILURE); + pmcDoBmpsCallbacks(hHal, eHAL_STATUS_FAILURE); + pMac->pmc.uapsdSessionRequired = FALSE; + pmcDoStartUapsdCallbacks(hHal, eHAL_STATUS_FAILURE); + pmcDoStandbyCallbacks(hHal, eHAL_STATUS_FAILURE); + + //purge the deferred msg list + csrLLLock( &pMac->pmc.deferredMsgList ); + while( NULL != ( pEntry = csrLLRemoveHead( &pMac->pmc.deferredMsgList, eANI_BOOLEAN_FALSE ) ) ) + { + pDeferredMsg = GET_BASE_ADDR( pEntry, tPmcDeferredMsg, link ); + vos_mem_free(pDeferredMsg); + } + csrLLUnlock( &pMac->pmc.deferredMsgList ); + + /* PMC is stopped. */ + pMac->pmc.pmcState = STOPPED; + pMac->pmc.pmcReady = FALSE; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcClose +* +* Description: +* Does a PMC close operation on the device. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - close successful +* eHAL_STATUS_FAILURE - close not successful +* +******************************************************************************/ +eHalStatus pmcClose (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcClose")); + + /* Free up allocated resources. */ + if (vos_timer_destroy(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate IMPS timer")); + } + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(&pMac->pmc.hTrafficTimer))) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate traffic timer")); + } + if (vos_timer_destroy(&pMac->pmc.hExitPowerSaveTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot deallocate exit power save mode timer")); + } + + /* + The following list's entries are dynamically allocated so they need their own + cleanup function + */ + pmcClosePowerSaveCheckList(pMac); + pmcCloseRequestFullPowerList(pMac); + pmcCloseRequestBmpsList(pMac); + pmcCloseRequestStartUapsdList(pMac); + pmcCloseDeviceStateUpdateList(pMac); + pmcCloseDeferredMsgList(pMac); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcSignalPowerEvent +* +* Description: +* Signals to PMC that a power event has occurred. +* +* Parameters: +* hHal - HAL handle for device +* event - the event that has occurred +* +* Returns: +* eHAL_STATUS_SUCCESS - signaling successful +* eHAL_STATUS_FAILURE - signaling not successful +* +******************************************************************************/ +eHalStatus pmcSignalPowerEvent (tHalHandle hHal, tPmcPowerEvent event) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); +#ifndef GEN6_ONWARDS + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcSignalPowerEvent, event %d"), event); + + /* Take action based on the event being signaled. */ + switch (event) + { +#ifndef GEN6_ONWARDS + case ePMC_SYSTEM_HIBERNATE: + return pmcEnterLowPowerState(hHal); + + case ePMC_SYSTEM_RESUME: + return pmcExitLowPowerState(hHal); + + case ePMC_HW_WLAN_SWITCH_OFF: + pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_OFF; + return pmcEnterLowPowerState(hHal); + + case ePMC_HW_WLAN_SWITCH_ON: + pMac->pmc.hwWlanSwitchState = ePMC_SWITCH_ON; + return pmcExitLowPowerState(hHal); + + case ePMC_SW_WLAN_SWITCH_OFF: + pMac->pmc.swWlanSwitchState = ePMC_SWITCH_OFF; + return pmcEnterLowPowerState(hHal); + + case ePMC_SW_WLAN_SWITCH_ON: + pMac->pmc.swWlanSwitchState = ePMC_SWITCH_ON; + return pmcExitLowPowerState(hHal); + + case ePMC_BATTERY_OPERATION: + pMac->pmc.powerSource = BATTERY_POWER; + + /* Turn on SMPS. */ + if (pMac->pmc.smpsEnabled) + { + if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC; + if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC; + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + + case ePMC_AC_OPERATION: + pMac->pmc.powerSource = AC_POWER; + + /* Turn off SMPS. */ + if (!pMac->pmc.smpsConfig.enterOnAc) + { + htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT; + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +#endif //GEN6_ONWARDS + default: + pmcLog(pMac, LOGE, FL("Invalid event %d"), event); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } +} + + +/****************************************************************************** +* +* Name: pmcSetConfigPowerSave +* +* Description: +* Configures one of the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to configure +* pConfigParams - pointer to configuration parameters specific to the +* power saving mode +* +* Returns: +* eHAL_STATUS_SUCCESS - configuration successful +* eHAL_STATUS_FAILURE - configuration not successful +* +******************************************************************************/ +eHalStatus pmcSetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcSetConfigPowerSave, power save mode %d"), psMode); + + /* Configure the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + pMac->pmc.impsConfig = *(tpPmcImpsConfigParams)pConfigParams; + pmcLog(pMac, LOG3, FL("IMPS configuration")); + pmcLog(pMac, LOG3, " enter on AC: %d", + pMac->pmc.impsConfig.enterOnAc); + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmc.bmpsConfig = *(tpPmcBmpsConfigParams)pConfigParams; + pmcLog(pMac, LOG3, FL("BMPS configuration")); + pmcLog(pMac, LOG3, " enter on AC: %d", + pMac->pmc.bmpsConfig.enterOnAc); + pmcLog(pMac, LOG3, " TX threshold: %d", + pMac->pmc.bmpsConfig.txThreshold); + pmcLog(pMac, LOG3, " RX threshold: %d", + pMac->pmc.bmpsConfig.rxThreshold); + pmcLog(pMac, LOG3, " traffic measurement period (ms): %d", + pMac->pmc.bmpsConfig.trafficMeasurePeriod); + pmcLog(pMac, LOG3, " BMPS period: %d", + pMac->pmc.bmpsConfig.bmpsPeriod); + pmcLog(pMac, LOG3, " beacons to forward code: %d", + pMac->pmc.bmpsConfig.forwardBeacons); + pmcLog(pMac, LOG3, " value of N: %d", + pMac->pmc.bmpsConfig.valueOfN); + pmcLog(pMac, LOG3, " use PS poll: %d", + pMac->pmc.bmpsConfig.usePsPoll); + pmcLog(pMac, LOG3, " set PM on last frame: %d", + pMac->pmc.bmpsConfig.setPmOnLastFrame); + pmcLog(pMac, LOG3, " value of enableBeaconEarlyTermination: %d", + pMac->pmc.bmpsConfig.enableBeaconEarlyTermination); + pmcLog(pMac, LOG3, " value of bcnEarlyTermWakeInterval: %d", + pMac->pmc.bmpsConfig.bcnEarlyTermWakeInterval); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_BMPS_SET_CONFIG; + /* possible loss of data due to mismatch but expectation is that + values can reasonably be expected to fit in target widths */ + psRequest.bmps_auto_timer_duration = (v_U16_t)pMac->pmc.bmpsConfig.trafficMeasurePeriod; + psRequest.bmps_period = (v_U16_t)pMac->pmc.bmpsConfig.bmpsPeriod; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + pMac->pmc.smpsConfig = *(tpPmcSmpsConfigParams)pConfigParams; + pmcLog(pMac, LOG3, FL("SMPS configuration")); + pmcLog(pMac, LOG3, " mode: %d", pMac->pmc.smpsConfig.mode); + pmcLog(pMac, LOG3, " enter on AC: %d", + pMac->pmc.smpsConfig.enterOnAc); + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + //Send the power save config down to PE/HAL/FW if BMPS mode is being configured + //and pmcReady has been invoked + if(PMC_IS_READY(pMac) && psMode == ePMC_BEACON_MODE_POWER_SAVE) + { + if (pmcSendPowerSaveConfigMessage(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcGetConfigPowerSave +* +* Description: +* Get the config for the specified power save mode +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to configure +* pConfigParams - pointer to configuration parameters specific to the +* power saving mode +* +* Returns: +* eHAL_STATUS_SUCCESS - configuration successful +* eHAL_STATUS_FAILURE - configuration not successful +* +******************************************************************************/ +eHalStatus pmcGetConfigPowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode, void *pConfigParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcGetConfigPowerSave, power save mode %d"), psMode); + + /* Configure the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + *(tpPmcImpsConfigParams)pConfigParams = pMac->pmc.impsConfig; + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + *(tpPmcBmpsConfigParams)pConfigParams = pMac->pmc.bmpsConfig; + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + *(tpPmcSmpsConfigParams)pConfigParams = pMac->pmc.smpsConfig; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +/****************************************************************************** +* +* Name: pmcEnablePowerSave +* +* Description: +* Enables one of the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to enable +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully enabled +* eHAL_STATUS_FAILURE - not successfully enabled +* +******************************************************************************/ +eHalStatus pmcEnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_PS_MODE_ENABLE_REQ; + psRequest.enable_disable_powersave_mode = psMode; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcEnablePowerSave, power save mode %d"), psMode); + + /* Enable the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + pMac->pmc.impsEnabled = TRUE; + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmc.bmpsEnabled = TRUE; + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + pMac->pmc.smpsEnabled = TRUE; + + /* If PMC already started, then turn on SMPS. */ + if (pMac->pmc.pmcState != STOPPED) + if (pMac->pmc.powerSource != AC_POWER || + pMac->pmc.smpsConfig.enterOnAc) + { + if (pMac->pmc.smpsConfig.mode == ePMC_DYNAMIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_DYNAMIC; + if (pMac->pmc.smpsConfig.mode == ePMC_STATIC_SMPS) + htMimoPowerSaveState = eSIR_HT_MIMO_PS_STATIC; + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + break; + + case ePMC_UAPSD_MODE_POWER_SAVE: + pMac->pmc.uapsdEnabled = TRUE; + break; + + case ePMC_STANDBY_MODE_POWER_SAVE: + pMac->pmc.standbyEnabled = TRUE; + break; + + case ePMC_WOWL_MODE_POWER_SAVE: + pMac->pmc.wowlEnabled = TRUE; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +/* --------------------------------------------------------------------------- + \fn pmcStartAutoBmpsTimer + \brief Starts a timer that periodically polls all the registered + module for entry into Bmps mode. This timer is started only if BMPS is + enabled and whenever the device is in full power. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus pmcStartAutoBmpsTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_START_BMPS_AUTO_TIMER_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcStartAutoBmpsTimer")); + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enable BMPS timer. BMPS is disabled"); + return eHAL_STATUS_FAILURE; + } + + pMac->pmc.autoBmpsEntryEnabled = TRUE; + + /* Check if there is an Infra session. If there is no Infra session, timer will be started + when STA associates to AP */ + + if (pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(hHal, pMac->pmc.bmpsConfig.trafficMeasurePeriod) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + } + + + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcStopAutoBmpsTimer + \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer + Stopping the timer does not cause a device state change. Only the timer + is stopped. If "Full Power" is desired, use the pmcRequestFullPower API + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus pmcStopAutoBmpsTimer (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_STOP_BMPS_AUTO_TIMER_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcStopAutoBmpsTimer")); + + pMac->pmc.autoBmpsEntryEnabled = FALSE; + /* If uapsd session is not required or HDD has not requested BMPS, stop the auto bmps timer.*/ + if (!pMac->pmc.uapsdSessionRequired && !pMac->pmc.bmpsRequestedByHdd) + pmcStopTrafficTimer(hHal); + + return eHAL_STATUS_SUCCESS; +} + +/****************************************************************************** +* +* Name: pmcDisablePowerSave +* +* Description: +* Disables one of the power saving modes. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode to disable +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully disabled +* eHAL_STATUS_FAILURE - not successfully disabled +* +******************************************************************************/ +eHalStatus pmcDisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSirMacHTMIMOPowerSaveState htMimoPowerSaveState; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_PS_MODE_DISABLE_REQ; + psRequest.enable_disable_powersave_mode = psMode; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcDisablePowerSave, power save mode %d"), psMode); + + /* Disable the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + pMac->pmc.impsEnabled = FALSE; + break; + + case ePMC_BEACON_MODE_POWER_SAVE: + pMac->pmc.bmpsEnabled = FALSE; + break; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + pMac->pmc.smpsEnabled = FALSE; + + /* Turn off SMPS. */ + htMimoPowerSaveState = eSIR_HT_MIMO_PS_NO_LIMIT; + if (pmcSendMessage(hHal, eWNI_PMC_SMPS_STATE_IND, &htMimoPowerSaveState, + sizeof(tSirMacHTMIMOPowerSaveState)) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + break; + + case ePMC_UAPSD_MODE_POWER_SAVE: + pMac->pmc.uapsdEnabled = FALSE; + break; + + case ePMC_STANDBY_MODE_POWER_SAVE: + pMac->pmc.standbyEnabled = FALSE; + break; + + case ePMC_WOWL_MODE_POWER_SAVE: + pMac->pmc.wowlEnabled = FALSE; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcQueryPowerState +* +* Description: +* Returns the current power state of the device. +* +* Parameters: +* hHal - HAL handle for device +* pPowerState - pointer to location to return power state +* pHwWlanSwitchState - pointer to location to return Hardware WLAN +* Switch state +* pSwWlanSwitchState - pointer to location to return Software WLAN +* Switch state +* +* Returns: +* eHAL_STATUS_SUCCESS - power state successfully returned +* eHAL_STATUS_FAILURE - power state not successfully returned +* +******************************************************************************/ +eHalStatus pmcQueryPowerState (tHalHandle hHal, tPmcPowerState *pPowerState, + tPmcSwitchState *pHwWlanSwitchState, tPmcSwitchState *pSwWlanSwitchState) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcQueryPowerState")); + + /* Return current power state based on PMC state. */ + if(pPowerState != NULL) + { + /* Return current power state based on PMC state. */ + switch (pMac->pmc.pmcState) + { + + case FULL_POWER: + *pPowerState = ePMC_FULL_POWER; + break; + + default: + *pPowerState = ePMC_LOW_POWER; + break; + } + } + + /* Return current switch settings. */ + if(pHwWlanSwitchState != NULL) + *pHwWlanSwitchState = pMac->pmc.hwWlanSwitchState; + if(pSwWlanSwitchState != NULL) + *pSwWlanSwitchState = pMac->pmc.swWlanSwitchState; + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcIsPowerSaveEnabled +* +* Description: +* Checks if the device is able to enter one of the power save modes. +* "Able to enter" means the power save mode is enabled for the device +* and the host is using the correct power source for entry into the +* power save mode. This routine does not indicate whether the device +* is actually in the power save mode at a particular point in time. +* +* Parameters: +* hHal - HAL handle for device +* psMode - the power saving mode +* +* Returns: +* TRUE if device is able to enter the power save mode, FALSE otherwise +* +******************************************************************************/ +tANI_BOOLEAN pmcIsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcIsPowerSaveEnabled, power save mode %d"), psMode); + + /* Check ability to enter based on the specified power saving mode. */ + switch (psMode) + { + + case ePMC_IDLE_MODE_POWER_SAVE: + return pMac->pmc.impsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.impsConfig.enterOnAc); + + case ePMC_BEACON_MODE_POWER_SAVE: + return pMac->pmc.bmpsEnabled; + + case ePMC_SPATIAL_MULTIPLEX_POWER_SAVE: + return pMac->pmc.smpsEnabled && (pMac->pmc.powerSource != AC_POWER || pMac->pmc.smpsConfig.enterOnAc); + + case ePMC_UAPSD_MODE_POWER_SAVE: + return pMac->pmc.uapsdEnabled; + + case ePMC_STANDBY_MODE_POWER_SAVE: + return pMac->pmc.standbyEnabled; + + case ePMC_WOWL_MODE_POWER_SAVE: + return pMac->pmc.wowlEnabled; + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid power save mode %d"), psMode); + PMC_ABORT; + return FALSE; + } +} + + +/****************************************************************************** +* +* Name: pmcRequestFullPower +* +* Description: +* Request that the device be brought to full power state. +* +* Parameters: +* hHal - HAL handle for device +* callbackRoutine - routine to call when device actually achieves full +* power state if "eHAL_STATUS_PMC_PENDING" is returned +* callbackContext - value to be passed as parameter to routine specified +* above +* fullPowerReason - Reason for requesting full power mode. This is used +* by PE to decide whether data null should be sent to +* AP when exiting BMPS mode. Caller should use the +* eSME_LINK_DISCONNECTED reason if link is disconnected +* and there is no need to tell the AP that we are going +* out of power save. +* +* Returns: +* eHAL_STATUS_SUCCESS - device brought to full power state +* eHAL_STATUS_FAILURE - device cannot be brought to full power state +* eHAL_STATUS_PMC_PENDING - device is being brought to full power state, +* callbackRoutine will be called when completed +* +******************************************************************************/ +eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext, tRequestFullPowerReason fullPowerReason) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpRequestFullPowerEntry pRequestFullPowerEntry; + tListElem *pEntry; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_ENTER_FULL_POWER_REQ; + psRequest.full_power_request_reason = fullPowerReason; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, FL("Entering pmcRequestFullPower")); + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting Full Power when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* If HDD is requesting full power, clear any buffered requests for WOWL and BMPS that were + requested by HDD previously */ + if(SIR_IS_FULL_POWER_NEEDED_BY_HDD(fullPowerReason)) + { + pMac->pmc.bmpsRequestedByHdd = FALSE; + pMac->pmc.wowlModeRequired = FALSE; + } + + /* If already in full power, just return. */ + if (pMac->pmc.pmcState == FULL_POWER) + return eHAL_STATUS_SUCCESS; + + /* If in IMPS State, then cancel the timer. */ + if (pMac->pmc.pmcState == IMPS) + if (vos_timer_stop(&pMac->pmc.hImpsTimer) != VOS_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); + } + + /* If able to enter Request Full Power State, then request is pending. + Allocate entry for request full power callback routine list. */ + //If caller doesn't need a callback, simply waits up the chip. + if (callbackRoutine) + { + pRequestFullPowerEntry = vos_mem_malloc(sizeof(tRequestFullPowerEntry)); + if (NULL == pRequestFullPowerEntry) + { + pmcLog(pMac, LOGE, + FL("Cannot allocate memory for request full power routine list entry")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pRequestFullPowerEntry->callbackRoutine = callbackRoutine; + pRequestFullPowerEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.requestFullPowerList, &pRequestFullPowerEntry->link, TRUE); + } + /* Enter Request Full Power State. */ + if (pmcEnterRequestFullPowerState(hHal, fullPowerReason) != eHAL_STATUS_SUCCESS) + { + /* If pmcEnterRequestFullPowerState fails ; driver need to remove callback + * from requestFullPowerList */ + if (callbackRoutine) + { + pEntry = csrLLRemoveTail(&pMac->pmc.requestFullPowerList, TRUE); + pRequestFullPowerEntry = GET_BASE_ADDR(pEntry, tRequestFullPowerEntry, link); + vos_mem_free(pRequestFullPowerEntry); + } + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_PMC_PENDING; +} + + +/****************************************************************************** +* +* Name: pmcRequestImps +* +* Description: +* Request that the device be placed in Idle Mode Power Save (IMPS). +* The Common Scan/Roam Module makes this request. The device will be +* placed into IMPS for the specified amount of time, and then returned +* to full power. +* +* Parameters: +* hHal - HAL handle for device +* impsPeriod - amount of time to remain in IMPS (milliseconds) +* callbackRoutine - routine to call when IMPS period has finished and +* the device has been brought to full power +* callbackContext - value to be passed as parameter to routine specified +* above +* +* Returns: +* eHAL_STATUS_SUCCESS - device will enter IMPS +* eHAL_STATUS_PMC_DISABLED - IMPS is disabled +* eHAL_STATUS_PMC_NOT_NOW - another module is prohibiting entering IMPS +* at this time +* eHAL_STATUS_PMC_AC_POWER - IMPS is disabled when host operating from +* AC power +* eHAL_STATUS_PMC_ALREADY_IN_IMPS - device is already in IMPS +* eHAL_STATUS_PMC_SYS_ERROR - system error that prohibits entering IMPS +* +******************************************************************************/ +eHalStatus pmcRequestImps (tHalHandle hHal, tANI_U32 impsPeriod, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_IMPS_ENTER_REQ; + psRequest.imps_period = impsPeriod; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + + pmcLog(pMac, LOG2, FL("Entering pmcRequestImps")); + + status = pmcEnterImpsCheck( pMac ); + if( HAL_STATUS_SUCCESS( status ) ) + { + /* Enter Request IMPS State. */ + status = pmcEnterRequestImpsState( hHal ); + if (HAL_STATUS_SUCCESS( status )) + { + /* Save the period and callback routine for when we need it. */ + pMac->pmc.impsPeriod = impsPeriod; + pMac->pmc.impsCallbackRoutine = callbackRoutine; + pMac->pmc.impsCallbackContext = callbackContext; + + } + else + { + status = eHAL_STATUS_PMC_SYS_ERROR; + } + } + + return status; +} + + +/****************************************************************************** +* +* Name: pmcRegisterPowerSaveCheck +* +* Description: +* Allows a routine to be registered so that the routine is called whenever +* the device is about to enter one of the power save modes. This routine +* will say whether the device is allowed to enter the power save mode at +* the time of the call. +* +* Parameters: +* hHal - HAL handle for device +* checkRoutine - routine to call before entering a power save mode, should +* return TRUE if the device is allowed to enter the power +* save mode, FALSE otherwise +* checkContext - value to be passed as parameter to routine specified above +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully registered +* eHAL_STATUS_FAILURE - not successfully registered +* +******************************************************************************/ +eHalStatus pmcRegisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext), + void *checkContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPowerSaveCheckEntry pEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcRegisterPowerSaveCheck")); + + /* Allocate entry for power save check routine list. */ + pEntry = vos_mem_malloc(sizeof(tPowerSaveCheckEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for power save check routine list entry")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->checkRoutine = checkRoutine; + pEntry->checkContext = checkContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.powerSaveCheckList, &pEntry->link, FALSE); + + return eHAL_STATUS_SUCCESS; +} + + +/****************************************************************************** +* +* Name: pmcDeregisterPowerSaveCheck +* +* Description: +* Reregisters a routine that was previously registered with +* pmcRegisterPowerSaveCheck. +* +* Parameters: +* hHal - HAL handle for device +* checkRoutine - routine to deregister +* +* Returns: +* eHAL_STATUS_SUCCESS - successfully deregistered +* eHAL_STATUS_FAILURE - not successfully deregistered +* +******************************************************************************/ +eHalStatus pmcDeregisterPowerSaveCheck (tHalHandle hHal, tANI_BOOLEAN (*checkRoutine) (void *checkContext)) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpPowerSaveCheckEntry pPowerSaveCheckEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcDeregisterPowerSaveCheck")); + + /* Find entry in the power save check routine list that matches + the specified routine and remove it. */ + pEntry = csrLLPeekHead(&pMac->pmc.powerSaveCheckList, FALSE); + while (pEntry != NULL) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link); + if (pPowerSaveCheckEntry->checkRoutine == checkRoutine) + { + if (csrLLRemoveEntry(&pMac->pmc.powerSaveCheckList, pEntry, FALSE)) + { + vos_mem_free(pPowerSaveCheckEntry); + } + else + { + pmcLog(pMac, LOGE, FL("Cannot remove power save check routine list entry")); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; + } + pEntry = csrLLNext(&pMac->pmc.powerSaveCheckList, pEntry, FALSE); + } + + /* Could not find matching entry. */ + return eHAL_STATUS_FAILURE; +} + + +static void pmcProcessResponse( tpAniSirGlobal pMac, tSirSmeRsp *pMsg ) +{ + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + tANI_BOOLEAN fRemoveCommand = eANI_BOOLEAN_TRUE; + tCsrRoamSession *pSession = NULL; + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if(pEntry) + { + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + + pmcLog(pMac, LOG2, FL("process message = 0x%x"), pMsg->messageType); + + /* Process each different type of message. */ + switch (pMsg->messageType) + { + + /* We got a response to our IMPS request. */ + case eWNI_PMC_ENTER_IMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_IMPS_RSP with status = %d"), pMsg->statusCode); + if( (eSmeCommandEnterImps != pCommand->command) && (eSmeCommandEnterStandby != pCommand->command) ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_IMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + if(pMac->pmc.pmcState == REQUEST_IMPS) + { + /* Enter IMPS State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pMac->pmc.ImpsReqFailed = VOS_FALSE; + pmcEnterImpsState(pMac); + if (!(pMac->pmc.ImpsReqFailed || pMac->pmc.ImpsReqTimerFailed) && pMac->pmc.ImpsReqFailCnt) + { + pmcLog(pMac, LOGE, + FL("Response message to request to enter IMPS was failed %d times before success"), + pMac->pmc.ImpsReqFailCnt); + pMac->pmc.ImpsReqFailCnt = 0; + } + } + + /* If response is failure, then we stay in Full Power State and tell everyone that we aren't going into IMPS. */ + else + { + pMac->pmc.ImpsReqFailed = VOS_TRUE; + if (!(pMac->pmc.ImpsReqFailCnt & 0xF)) + { + pmcLog(pMac, LOGE, + FL("Response message to request to enter IMPS indicates failure, status %x, FailCnt - %d"), + pMsg->statusCode, ++pMac->pmc.ImpsReqFailCnt); + } + else + { + pMac->pmc.ImpsReqFailCnt++; + } + pmcEnterFullPowerState(pMac); + } + } + else if (pMac->pmc.pmcState == REQUEST_STANDBY) + { + /* Enter STANDBY State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pmcEnterStandbyState(pMac); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + + /* If response is failure, then we stay in Full Power State + and tell everyone that we aren't going into STANDBY. */ + else + { + pmcLog(pMac, LOGE, "PMC: response message to request to enter " + "standby indicates failure, status %d", pMsg->statusCode); + pmcEnterFullPowerState(pMac); + pmcDoStandbyCallbacks(pMac, eHAL_STATUS_FAILURE); + } + } + else + { + pmcLog(pMac, LOGE, "PMC: Enter IMPS rsp rcvd when device is " + "in %d state", pMac->pmc.pmcState); + } + break; + + /* We got a response to our wake from IMPS request. */ + case eWNI_PMC_EXIT_IMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_IMPS_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandExitImps != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_IMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_FULL_POWER) + { + pmcLog(pMac, LOGE, FL("Got Exit IMPS Response Message while " + "in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter Full Power State. */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Response message to request to exit " + "IMPS indicates failure, status %d"), pMsg->statusCode); + if (vos_is_logp_in_progress(VOS_MODULE_ID_SME, NULL)) + { + pmcLog(pMac, LOGE, FL("SSR Is in progress do not send " + "exit imps req again")); + } + else if( (pMac->pmc.ImpsRspFailCnt <= + BMPS_IMPS_FAILURE_REPORT_THRESHOLD)) + { + pMac->pmc.ImpsRspFailCnt++; + if (eHAL_STATUS_SUCCESS == + pmcSendMessage(pMac, eWNI_PMC_EXIT_IMPS_REQ, NULL, 0) ) + { + fRemoveCommand = eANI_BOOLEAN_FALSE; + pMac->pmc.pmcState = REQUEST_FULL_POWER; + pmcLog(pMac, LOGE, FL("eWNI_PMC_EXIT_IMPS_REQ sent again" + " to PE")); + break; + } + } + else + { + pMac->pmc.ImpsRspFailCnt = 0; + VOS_ASSERT(0); + break; + } + } + else + { + pMac->pmc.ImpsRspFailCnt = 0; + } + + pmcEnterFullPowerState(pMac); + break; + + /* We got a response to our BMPS request. */ + case eWNI_PMC_ENTER_BMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandEnterBmps != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_BMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + pMac->pmc.bmpsRequestQueued = eANI_BOOLEAN_FALSE; + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_BMPS) + { + pmcLog(pMac, LOGE, + FL("Got Enter BMPS Response Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter BMPS State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pmcEnterBmpsState(pMac); + /* Note: If BMPS was requested because of start UAPSD, + there will no entries for BMPS callback routines and + pmcDoBmpsCallbacks will be a No-Op*/ + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + /* If response is failure, then we stay in Full Power State and tell everyone that we aren't going into BMPS. */ + else + { + pmcLog(pMac, LOGE, + FL("Response message to request to enter BMPS indicates failure, status %d"), + pMsg->statusCode); + pmcEnterFullPowerState(pMac); + //Do not call UAPSD callback here since it may be re-entered + pmcDoBmpsCallbacks(pMac, eHAL_STATUS_FAILURE); + } + break; + + /* We got a response to our wake from BMPS request. */ + case eWNI_PMC_EXIT_BMPS_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandExitBmps != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_BMPS_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_FULL_POWER) + { + pmcLog(pMac, LOGE, + FL("Got Exit BMPS Response Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter Full Power State. */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) + { + pmcLog(pMac, LOGP, + FL("Response message to request to exit BMPS indicates failure, status %d"), + pMsg->statusCode); + /*Status is not succes, so set back the pmc state as BMPS*/ + pMac->pmc.pmcState = BMPS; + } + else + pmcEnterFullPowerState(pMac); + break; + + /* We got a response to our Start UAPSD request. */ + case eWNI_PMC_ENTER_UAPSD_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandEnterUapsd != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_UAPSD_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_START_UAPSD) + { + pmcLog(pMac, LOGE, + FL("Got Enter Uapsd rsp Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter UAPSD State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) + { + pmcEnterUapsdState(pMac); + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + else + { + /* If response is failure, then we try to put the chip back in + BMPS mode*/ + tANI_BOOLEAN OrigUapsdReqState = pMac->pmc.uapsdSessionRequired; + pmcLog(pMac, LOGE, "PMC: response message to request to enter " + "UAPSD indicates failure, status %d", pMsg->statusCode); + + //Need to reset the UAPSD flag so pmcEnterBmpsState won't try to enter UAPSD. + pMac->pmc.uapsdSessionRequired = FALSE; + pmcEnterBmpsState(pMac); + + if (pMsg->statusCode != eSIR_SME_UAPSD_REQ_INVALID) + { + //UAPSD will not be retied in this case so tell requester we are done with failure + pmcDoStartUapsdCallbacks(pMac, eHAL_STATUS_FAILURE); + } + else + pMac->pmc.uapsdSessionRequired = OrigUapsdReqState; + } + break; + + /* We got a response to our Stop UAPSD request. */ + case eWNI_PMC_EXIT_UAPSD_RSP: + pmcLog(pMac, LOG2, FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP with status = %d"), pMsg->statusCode); + if( eSmeCommandExitUapsd != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_UAPSD_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_STOP_UAPSD) + { + pmcLog(pMac, LOGE, + FL("Got Exit Uapsd rsp Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter BMPS State */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) { + pmcLog(pMac, LOGP, "PMC: response message to request to exit " + "UAPSD indicates failure, status %d", pMsg->statusCode); + } + pmcEnterBmpsState(pMac); + break; + + /* We got a response to our enter WOWL request. */ + case eWNI_PMC_ENTER_WOWL_RSP: + + if( eSmeCommandEnterWowl != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_ENTER_WOWL_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_ENTER_WOWL) + { + pmcLog(pMac, LOGE, FL("Got eWNI_PMC_ENTER_WOWL_RSP while in state %s"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + break; + } + + /* Enter WOWL State if response indicates success. */ + if (pMsg->statusCode == eSIR_SME_SUCCESS) { + pmcEnterWowlState(pMac); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_SUCCESS); + } + + /* If response is failure, then we try to put the chip back in + BMPS mode*/ + else { + pmcLog(pMac, LOGE, "PMC: response message to request to enter " + "WOWL indicates failure, status %d", pMsg->statusCode); + pmcEnterBmpsState(pMac); + pmcDoEnterWowlCallbacks(pMac, eHAL_STATUS_FAILURE); + } + break; + + /* We got a response to our exit WOWL request. */ + case eWNI_PMC_EXIT_WOWL_RSP: + + if( eSmeCommandExitWowl != pCommand->command ) + { + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_WOWL_RSP without request")); + fRemoveCommand = eANI_BOOLEAN_FALSE; + break; + } + /* Check that we are in the correct state for this message. */ + if (pMac->pmc.pmcState != REQUEST_EXIT_WOWL) + { + pmcLog(pMac, LOGE, FL("Got Exit WOWL rsp Message while in state %d"), pMac->pmc.pmcState); + break; + } + + /* Enter BMPS State */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) { + pmcLog(pMac, LOGP, "PMC: response message to request to exit " + "WOWL indicates failure, status %d", pMsg->statusCode); + } + + pSession = CSR_GET_SESSION(pMac, pMsg->sessionId); + if (pSession && pSession->pCurRoamProfile && + CSR_IS_INFRA_AP(pSession->pCurRoamProfile)) + { + pMac->pmc.pmcState = FULL_POWER; + pMac->pmc.isAPWOWExit = TRUE; + break; + } + else + { + pMac->pmc.isAPWOWExit = FALSE; + } + + pmcEnterBmpsState(pMac); + break; + + default: + pmcLog(pMac, LOGE, FL("Invalid message type %d received"), pMsg->messageType); + PMC_ABORT; + break; + }//switch + + if( fRemoveCommand ) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, pEntry, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + smeProcessPendingQueue( pMac ); + } + } + } + else + { + pmcLog(pMac, LOGE, FL("message type %d received but no request is found"), pMsg->messageType); + } +} + + +/****************************************************************************** +* +* Name: pmcMessageProcessor +* +* Description: +* Process a message received by PMC. +* +* Parameters: +* hHal - HAL handle for device +* pMsg - pointer to received message +* +* Returns: +* nothing +* +******************************************************************************/ +void pmcMessageProcessor (tHalHandle hHal, tSirSmeRsp *pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Message type %d"), pMsg->messageType); + + switch( pMsg->messageType ) + { + case eWNI_PMC_EXIT_BMPS_IND: + //When PMC needs to handle more indication from PE, they need to be added here. + { + /* Device left BMPS on its own. */ + pmcLog(pMac, LOGW, FL("Rcvd eWNI_PMC_EXIT_BMPS_IND with status = %d"), pMsg->statusCode); + /* Check that we are in the correct state for this message. */ + switch(pMac->pmc.pmcState) + { + case BMPS: + case REQUEST_START_UAPSD: + case UAPSD: + case REQUEST_STOP_UAPSD: + case REQUEST_ENTER_WOWL: + case WOWL: + case REQUEST_EXIT_WOWL: + case REQUEST_FULL_POWER: + pmcLog(pMac, LOGW, FL("Got eWNI_PMC_EXIT_BMPS_IND while in state %d"), pMac->pmc.pmcState); + break; + default: + pmcLog(pMac, LOGE, FL("Got eWNI_PMC_EXIT_BMPS_IND while in state %d"), pMac->pmc.pmcState); + PMC_ABORT; + break; + } + + /* Enter Full Power State. */ + if (pMsg->statusCode != eSIR_SME_SUCCESS) + { + pmcLog(pMac, LOGP, FL("Exit BMPS indication indicates failure, status %d"), pMsg->statusCode); + } + else + { + tpSirSmeExitBmpsInd pExitBmpsInd = (tpSirSmeExitBmpsInd)pMsg; + pmcEnterRequestFullPowerState(hHal, pExitBmpsInd->exitBmpsReason); + } + break; + } + + default: + pmcProcessResponse( pMac, pMsg ); + break; + } + +} + + +tANI_BOOLEAN pmcValidateConnectState( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if ( !csrIsInfraConnected( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: STA not associated. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + + //Cannot have other session + if ( csrIsIBSSStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: IBSS started. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + if ( csrIsBTAMPStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: BT-AMP exists. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + if ((vos_concurrent_open_sessions_running()) && + (csrIsConcurrentInfraConnected( pMac ) || + (vos_get_concurrency_mode()& VOS_SAP) || + (vos_get_concurrency_mode()& VOS_P2P_GO))) + { + pmcLog(pMac, LOGW, "PMC: Multiple active sessions exists. BMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } +#ifdef FEATURE_WLAN_TDLS + if (pMac->isTdlsPowerSaveProhibited) + { + pmcLog(pMac, LOGE, FL("TDLS peer(s) connected/discovery sent. Dont enter BMPS")); + return eANI_BOOLEAN_FALSE; + } +#endif + return eANI_BOOLEAN_TRUE; +} + +tANI_BOOLEAN pmcAllowImps( tHalHandle hHal ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + //Cannot have other session like IBSS or BT AMP running + if ( csrIsIBSSStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: IBSS started. IMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + if ( csrIsBTAMPStarted( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: BT-AMP exists. IMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + + //All sessions must be disconnected to allow IMPS + if ( !csrIsAllSessionDisconnected( pMac ) ) + { + pmcLog(pMac, LOGW, "PMC: Atleast one connected session. IMPS cannot be entered"); + return eANI_BOOLEAN_FALSE; + } + + return eANI_BOOLEAN_TRUE; +} + +/****************************************************************************** +* +* Name: pmcRequestBmps +* +* Description: +* Request that the device be put in BMPS state. +* +* Parameters: +* hHal - HAL handle for device +* callbackRoutine - Callback routine invoked in case of success/failure +* callbackContext - value to be passed as parameter to routine specified +* above +* +* Returns: +* eHAL_STATUS_SUCCESS - device is in BMPS state +* eHAL_STATUS_FAILURE - device cannot be brought to BMPS state +* eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state, +* +******************************************************************************/ +eHalStatus pmcRequestBmps ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpRequestBmpsEntry pEntry; + eHalStatus status; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_BMPS_ENTER_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcRequestBmps"); + + /* If already in BMPS, just return. */ + if (pMac->pmc.pmcState == BMPS || REQUEST_START_UAPSD == pMac->pmc.pmcState || UAPSD == pMac->pmc.pmcState) + { + pmcLog(pMac, LOG2, "PMC: Device already in BMPS pmcState %d", pMac->pmc.pmcState); + pMac->pmc.bmpsRequestedByHdd = TRUE; + return eHAL_STATUS_SUCCESS; + } + + status = pmcEnterBmpsCheck( pMac ); + if(HAL_STATUS_SUCCESS( status )) + { + /* If DUT exits from WoWL because of wake-up indication then it enters + * into WoWL again. Disable WoWL only when user explicitly disables. + */ + if(pMac->pmc.wowlModeRequired == FALSE && + pMac->pmc.wowlExitSrc == eWOWL_EXIT_WAKEIND && + !pMac->pmc.isAPWOWExit) + { + pMac->pmc.wowlModeRequired = TRUE; + } + + status = pmcEnterRequestBmpsState(hHal); + + /* Enter Request BMPS State. */ + if ( HAL_STATUS_SUCCESS( status ) ) + { + /* Remember that HDD requested BMPS. This flag will be used to put the + device back into BMPS if any module other than HDD (e.g. CSR, QoS, or BAP) + requests full power for any reason */ + pMac->pmc.bmpsRequestedByHdd = TRUE; + + /* If able to enter Request BMPS State, then request is pending. + Allocate entry for request BMPS callback routine list. */ + pEntry = vos_mem_malloc(sizeof(tRequestBmpsEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, "PMC: cannot allocate memory for request " + "BMPS routine list entry"); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.requestBmpsList, &pEntry->link, FALSE); + + status = eHAL_STATUS_PMC_PENDING; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + /* Retry to enter the BMPS if the + status = eHAL_STATUS_PMC_NOT_NOW */ + else if (status == eHAL_STATUS_PMC_NOT_NOW) + { + pmcStopTrafficTimer(hHal); + pmcLog(pMac, LOG1, FL("Can't enter BMPS+++")); + if (pmcShouldBmpsTimerRun(pMac)) + { + if (pmcStartTrafficTimer(pMac, + pMac->pmc.bmpsConfig.trafficMeasurePeriod) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOG1, FL("Cannot start BMPS Retry timer")); + } + pmcLog(pMac, LOG1, + FL("BMPS Retry Timer already running or started")); + } + } + + return status; +} + +/****************************************************************************** +* +* Name: pmcStartUapsd +* +* Description: +* Request that the device be put in UAPSD state. +* +* Parameters: +* hHal - HAL handle for device +* callbackRoutine - Callback routine invoked in case of success/failure +* callbackContext - value to be passed as parameter to routine specified +* above +* +* Returns: +* eHAL_STATUS_SUCCESS - device is in UAPSD state +* eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state +* eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state +* eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled +* +******************************************************************************/ +eHalStatus pmcStartUapsd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpStartUapsdEntry pEntry; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_UAPSD_START_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcStartUapsd"); + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting UAPSD when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter UAPSD. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Check if UAPSD is enabled. */ + if (!pMac->pmc.uapsdEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter UAPSD. UAPSD is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* If already in UAPSD, just return. */ + if (pMac->pmc.pmcState == UAPSD) + return eHAL_STATUS_SUCCESS; + + /* Check that we are associated. */ + if (!pmcValidateConnectState( pMac )) + { + pmcLog(pMac, LOGE, "PMC: STA not associated with an AP. UAPSD cannot be entered"); + return eHAL_STATUS_FAILURE; + } + + /* Enter REQUEST_START_UAPSD State. */ + if (pmcEnterRequestStartUapsdState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + if( NULL != callbackRoutine ) + { + /* If success then request is pending. Allocate entry for callback routine list. */ + pEntry = vos_mem_malloc(sizeof(tStartUapsdEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, "PMC: cannot allocate memory for request " + "start UAPSD routine list entry"); + return eHAL_STATUS_FAILURE; + } + + /* Store routine and context in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.requestStartUapsdList, &pEntry->link, FALSE); + } + + return eHAL_STATUS_PMC_PENDING; +} + +/****************************************************************************** +* +* Name: pmcStopUapsd +* +* Description: +* Request that the device be put out of UAPSD state. +* +* Parameters: +* hHal - HAL handle for device +* +* Returns: +* eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state +* eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state +* +******************************************************************************/ +eHalStatus pmcStopUapsd (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_S8 sessionId; + tCsrRoamSession *pSession = NULL; + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_UAPSD_STOP_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + pmcLog(pMac, LOG2, "PMC: entering pmcStopUapsd"); + sessionId = csrGetInfraSessionId(pMac); + if (-1 != sessionId) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + } + + + if (pSession && pSession->pCurRoamProfile && pSession->pCurRoamProfile->uapsd_mask) + pMac->pmc.uapsdSessionRequired = TRUE; + else + pMac->pmc.uapsdSessionRequired = FALSE; + + /* Nothing to be done if we are already out of UAPSD. This can happen if + some other module (HDD, BT-AMP) requested Full Power.*/ + if (pMac->pmc.pmcState != UAPSD && pMac->pmc.pmcState != REQUEST_STOP_UAPSD) + { + pmcLog(pMac, LOGW, "PMC: Device is already out of UAPSD " + "state. Current state is %d", pMac->pmc.pmcState); + return eHAL_STATUS_SUCCESS; + } + + /* Enter REQUEST_STOP_UAPSD State*/ + if (pmcEnterRequestStopUapsdState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcRequestStandby + \brief Request that the device be put in standby. + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine invoked in case of success/failure + \param callbackContext - value to be passed as parameter to callback + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in Standby mode + eHAL_STATUS_FAILURE - device cannot be put in standby mode + eHAL_STATUS_PMC_PENDING - device is being put in standby mode + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcRequestStandby ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); + + vos_mem_zero(&psRequest, sizeof(vos_event_wlan_powersave_payload_type)); + psRequest.event_subtype = WLAN_ENTER_STANDBY_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&psRequest, EVENT_WLAN_POWERSAVE_GENERIC); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcRequestStandby"); + + /* Check if standby is enabled. */ + if (!pMac->pmc.standbyEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter standby. Standby is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting standby when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + /* If already in STANDBY, just return. */ + if (pMac->pmc.pmcState == STANDBY) + return eHAL_STATUS_SUCCESS; + + + if (csrIsIBSSStarted(pMac) || csrIsBTAMPStarted(pMac)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "WLAN: IBSS or BT-AMP session present. Cannot honor standby request"); + return eHAL_STATUS_PMC_NOT_NOW; + } + + /* Enter Request Standby State. */ + if (pmcEnterRequestStandbyState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + /* Save the callback routine for when we need it. */ + pMac->pmc.standbyCallbackRoutine = callbackRoutine; + pMac->pmc.standbyCallbackContext = callbackContext; + + return eHAL_STATUS_PMC_PENDING; +} + +/* --------------------------------------------------------------------------- + \fn pmcRegisterDeviceStateUpdateInd + \brief Register a callback routine that is called whenever + the device enters a new device state (Full Power, BMPS, UAPSD) + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +extern eHalStatus pmcRegisterDeviceStateUpdateInd (tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + void *callbackContext) +{ + + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpDeviceStateUpdateIndEntry pEntry; + + pmcLog(pMac, LOG2, FL("Entering pmcRegisterDeviceStateUpdateInd")); + + /* Allocate entry for device power state update indication. */ + pEntry = vos_mem_malloc(sizeof(tDeviceStateUpdateIndEntry)); + if ( NULL == pEntry ) + { + pmcLog(pMac, LOGE, FL("Cannot allocate memory for device power state update indication")); + PMC_ABORT; + return eHAL_STATUS_FAILURE; + } + + /* Store routine in entry. */ + pEntry->callbackRoutine = callbackRoutine; + pEntry->callbackContext = callbackContext; + + /* Add entry to list. */ + csrLLInsertTail(&pMac->pmc.deviceStateUpdateIndList, &pEntry->link, FALSE); + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcDeregisterDeviceStateUpdateInd + \brief Deregister a routine that was registered for device state changes + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +eHalStatus pmcDeregisterDeviceStateUpdateInd (tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tListElem *pEntry; + tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry; + + pmcLog(pMac, LOG2, FL(": Enter")); + + /* Find entry in the power save update routine list that matches + the specified routine and remove it. */ + pEntry = csrLLPeekHead(&pMac->pmc.deviceStateUpdateIndList, FALSE); + while (pEntry != NULL) + { + pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link); + if (pDeviceStateUpdateIndEntry->callbackRoutine == callbackRoutine) + { + if (!csrLLRemoveEntry(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE)) + { + pmcLog(pMac, LOGE, FL("Cannot remove device state update ind entry from list")); + return eHAL_STATUS_FAILURE; + } + vos_mem_free(pDeviceStateUpdateIndEntry); + return eHAL_STATUS_SUCCESS; + } + pEntry = csrLLNext(&pMac->pmc.deviceStateUpdateIndList, pEntry, FALSE); + } + + /* Could not find matching entry. */ + return eHAL_STATUS_FAILURE; +} + +/* --------------------------------------------------------------------------- + \fn pmcReady + \brief fn to inform PMC that eWNI_SME_SYS_READY_IND has been sent to PE. + This acts as a trigger to send a message to PE to update the power + save related conig to FW. Note that if HDD configures any power save + related stuff before this API is invoked, PMC will buffer all the + configutaion. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus pmcReady(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pmcLog(pMac, LOG2, FL("Entering pmcReady")); + + if(pMac->pmc.pmcState == STOPPED) + { + pmcLog(pMac, LOGP, FL("pmcReady is invoked even before pmcStart")); + return eHAL_STATUS_FAILURE; + } + + pMac->pmc.pmcReady = TRUE; + if (pmcSendPowerSaveConfigMessage(hHal) != eHAL_STATUS_SUCCESS) + { + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcWowlAddBcastPattern + \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will + do a pattern match on these patterns when Wowl is enabled during BMPS + mode. Note that Firmware performs the pattern matching only on + broadcast frames and while Libra is in BMPS mode. + \param hHal - The handle returned by macOpen. + \param pattern - Pointer to the pattern to be added + \return eHalStatus + eHAL_STATUS_FAILURE Cannot add pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcWowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + vos_log_powersave_wow_add_ptrn_pkt_type *log_ptr = NULL; +#endif //#ifdef FEATURE_WLAN_DIAG_SUPPORT + + pmcLog(pMac, LOG2, "PMC: entering pmcWowlAddBcastPattern"); + + if(pattern == NULL) + { + pmcLog(pMac, LOGE, FL("Null broadcast pattern being passed")); + return eHAL_STATUS_FAILURE; + } + + if( pSession == NULL) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_powersave_wow_add_ptrn_pkt_type, + LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C); + if( log_ptr ) + { + log_ptr->pattern_id = pattern->ucPatternId; + log_ptr->pattern_byte_offset = pattern->ucPatternByteOffset; + log_ptr->pattern_size = + (pattern->ucPatternSize <= VOS_LOG_MAX_WOW_PTRN_SIZE) ? + pattern->ucPatternSize : VOS_LOG_MAX_WOW_PTRN_SIZE; + log_ptr->pattern_mask_size = + (pattern->ucPatternMaskSize <= VOS_LOG_MAX_WOW_PTRN_MASK_SIZE) ? + pattern->ucPatternMaskSize : VOS_LOG_MAX_WOW_PTRN_MASK_SIZE; + + vos_mem_copy(log_ptr->pattern, pattern->ucPattern, + SIR_WOWL_BCAST_PATTERN_MAX_SIZE); + /* 1 bit in the pattern mask denotes 1 byte of pattern hence pattern mask size is 1/8 */ + vos_mem_copy(log_ptr->pattern_mask, pattern->ucPatternMask, + SIR_WOWL_BCAST_PATTERN_MAX_SIZE >> 3); + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); + } + +#endif + + + if(pattern->ucPatternId >= SIR_WOWL_BCAST_MAX_NUM_PATTERNS ) + { + pmcLog(pMac, LOGE, FL("Pattern Id must range from 0 to %d"), SIR_WOWL_BCAST_MAX_NUM_PATTERNS-1); + return eHAL_STATUS_FAILURE; + } + + if( pMac->pmc.pmcState == STANDBY || pMac->pmc.pmcState == REQUEST_STANDBY ) + { + pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern as chip is in %s state"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS ) + { + pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern as chip is in %s state"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + if (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) + { + if( !csrIsConnStateConnected(pMac, sessionId) ) + { + pmcLog(pMac, LOGE, FL("Cannot add WoWL Pattern session in %d state"), + pSession->connectState); + return eHAL_STATUS_FAILURE; + } + } + + vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + if (pmcSendMessage(hHal, eWNI_PMC_WOWL_ADD_BCAST_PTRN, pattern, sizeof(tSirWowlAddBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_ADD_BCAST_PTRN to PE failed")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcWowlDelBcastPattern + \brief Delete a pattern that was added for Pattern Byte Matching. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be deleted + \return eHalStatus + eHAL_STATUS_FAILURE Cannot delete pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcWowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type); + + vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type)); + wowRequest.event_subtype = WLAN_WOW_DEL_PTRN_REQ; + wowRequest.wow_del_ptrn_id = pattern->ucPatternId; + + WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcWowlDelBcastPattern"); + + if( NULL == pSession ) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + + if(pattern->ucPatternId >= SIR_WOWL_BCAST_MAX_NUM_PATTERNS ) + { + pmcLog(pMac, LOGE, FL("Pattern Id must range from 0 to %d"), + SIR_WOWL_BCAST_MAX_NUM_PATTERNS-1); + return eHAL_STATUS_FAILURE; + } + + if(pMac->pmc.pmcState == STANDBY || pMac->pmc.pmcState == REQUEST_STANDBY) + { + pmcLog(pMac, LOGE, FL("Cannot delete WoWL Pattern as chip is in %s state"), + pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + if( pMac->pmc.pmcState == IMPS || pMac->pmc.pmcState == REQUEST_IMPS ) + { + eHalStatus status; + + vos_mem_copy(pattern->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + //Wake up the chip first + status = pmcDeferMsg( pMac, eWNI_PMC_WOWL_DEL_BCAST_PTRN, + pattern, sizeof(tSirWowlDelBcastPtrn) ); + + if( eHAL_STATUS_PMC_PENDING == status ) + { + return eHAL_STATUS_SUCCESS; + } + else + { + //either fail or already in full power + if( !HAL_STATUS_SUCCESS( status ) ) + { + return ( status ); + } + //else let it through because it is in full power state + } + } + + if (pmcSendMessage(hHal, eWNI_PMC_WOWL_DEL_BCAST_PTRN, pattern, sizeof(tSirWowlDelBcastPtrn)) + != eHAL_STATUS_SUCCESS) + { + pmcLog(pMac, LOGE, FL("Send of eWNI_PMC_WOWL_DEL_BCAST_PTRN to PE failed")); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcEnterWowl + \brief Request that the device be brought to full power state. + Note 1: If "fullPowerReason" specificied in this API is set to + eSME_FULL_PWR_NEEDED_BY_HDD, PMC will clear any "buffered wowl" requests + and also clear any "buffered BMPS requests by HDD". Assumption is that since + HDD is requesting full power, we need to undo any previous HDD requests for + BMPS (using sme_RequestBmps) or WoWL (using sme_EnterWoWL). If the reason is + specified anything other than above, the buffered requests for BMPS and WoWL + will not be cleared. + Note 2: Requesting full power (no matter what the fullPowerReason is) doesn't + disable the "auto bmps timer" (if it is enabled) or clear any "buffered uapsd + request". + Note 3: When the device finally enters Full Power PMC will start a timer + if any of the following holds true: + - Auto BMPS mode is enabled + - Uapsd request is pending + - HDD's request for BMPS is pending + - HDD's request for WoWL is pending + On timer expiry PMC will attempt to put the device in BMPS mode if following + (in addition to those listed above) holds true: + - Polling of all modules through the Power Save Check routine passes + - STA is associated to an access point + \param hHal - The handle returned by macOpen. + \param - enterWowlCallbackRoutine Callback routine invoked in case of success/failure + \param - enterWowlCallbackContext - Cookie to be passed back during callback + \param - wakeReasonIndCB Callback routine invoked for Wake Reason Indication + \param - wakeReasonIndCBContext - Cookie to be passed back during callback + \param - fullPowerReason - Reason why this API is being invoked. SME needs to + distinguish between BAP and HDD requests + \return eHalStatus - status + eHAL_STATUS_SUCCESS - device brought to full power state + eHAL_STATUS_FAILURE - device cannot be brought to full power state + eHAL_STATUS_PMC_PENDING - device is being brought to full power state, + ---------------------------------------------------------------------------*/ +eHalStatus pmcEnterWowl ( + tHalHandle hHal, + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeReasonIndCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + void *wakeReasonIndCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type); + + vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type)); + wowRequest.event_subtype = WLAN_WOW_ENTER_REQ; + wowRequest.wow_type = 0; + + if(wowlEnterParams->ucMagicPktEnable) + { + wowRequest.wow_type |= 1; + vos_mem_copy(wowRequest.wow_magic_pattern, + (tANI_U8 *)wowlEnterParams->magicPtrn, 6); + } + + if(wowlEnterParams->ucPatternFilteringEnable) + { + wowRequest.wow_type |= 2; + } + WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW); +#endif + + pmcLog(pMac, LOG2, FL("PMC: entering pmcEnterWowl")); + + if( NULL == pSession ) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + + if( !PMC_IS_READY(pMac) ) + { + pmcLog(pMac, LOGE, FL("Requesting WoWL when PMC not ready")); + pmcLog(pMac, LOGE, FL("pmcReady = %d pmcState = %s"), + pMac->pmc.pmcReady, pmcGetPmcStateStr(pMac->pmc.pmcState)); + return eHAL_STATUS_FAILURE; + } + + if ((!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))) + && !(vos_get_concurrency_mode()& VOS_STA_SAP)) + { + /* Check if BMPS is enabled. */ + if (!pMac->pmc.bmpsEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter WoWL. BMPS is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + /* Check that we are associated with single Session. */ + if (!pmcValidateConnectState( pMac )) + { + pmcLog(pMac, LOGE, "PMC: Cannot enable WOWL. STA not associated " + "with an Access Point in Infra Mode with single active session"); + return eHAL_STATUS_FAILURE; + } + } + + /* Check if WoWL is enabled. */ + if (!pMac->pmc.wowlEnabled) + { + pmcLog(pMac, LOGE, "PMC: Cannot enter WoWL. WoWL is disabled"); + return eHAL_STATUS_PMC_DISABLED; + } + + /* Is there a pending UAPSD request? HDD should have triggered QoS + module to do the necessary cleanup before triggring WOWL*/ + if(pMac->pmc.uapsdSessionRequired) + { + pmcLog(pMac, LOGE, "PMC: Cannot request WOWL. Pending UAPSD request"); + return eHAL_STATUS_FAILURE; + } + + /* Check that entry into a power save mode is allowed at this time. */ + if (pMac->pmc.pmcState == FULL_POWER && !pmcPowerSaveCheck(hHal)) + { + pmcLog(pMac, LOGE, "PMC: Power save check failed. WOWL request " + "will not be accepted"); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(wowlEnterParams->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + // To avoid race condition, set callback routines before sending message. + /* cache the WOWL information */ + pMac->pmc.wowlEnterParams = *wowlEnterParams; + pMac->pmc.enterWowlCallbackRoutine = enterWowlCallbackRoutine; + pMac->pmc.enterWowlCallbackContext = enterWowlCallbackContext; +#ifdef WLAN_WAKEUP_EVENTS + /* Cache the Wake Reason Indication callback information */ + pMac->pmc.wakeReasonIndCB = wakeReasonIndCB; + pMac->pmc.wakeReasonIndCBContext = wakeReasonIndCBContext; +#endif // WLAN_WAKEUP_EVENTS + + /* Enter Request WOWL State. */ + if (pmcRequestEnterWowlState(hHal, wowlEnterParams) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + pMac->pmc.wowlModeRequired = TRUE; + + /* By default set wowlExitSrc to eWOWL_EXIT_WAKEIND, so that device will + * come out of WoWL only when user explicity disables WoWL. + */ + pMac->pmc.wowlExitSrc = eWOWL_EXIT_WAKEIND; + + return eHAL_STATUS_PMC_PENDING; +} + +/* --------------------------------------------------------------------------- + \fn pmcExitWowl + \brief This is the SME API exposed to HDD to request exit from WoWLAN mode. + SME will initiate exit from WoWLAN mode and device will be put in BMPS + mode. + \param hHal - The handle returned by macOpen. + wowlExitSrc - is wowl exiting because of wakeup pkt or user + explicitly disabling WoWL + \return eHalStatus + eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode. + eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode. + ---------------------------------------------------------------------------*/ +eHalStatus pmcExitWowl (tHalHandle hHal, tWowlExitSource wowlExitSrc) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + WLAN_VOS_DIAG_EVENT_DEF(wowRequest, vos_event_wlan_powersave_wow_payload_type); + + vos_mem_zero(&wowRequest, sizeof(vos_event_wlan_powersave_wow_payload_type)); + wowRequest.event_subtype = WLAN_WOW_EXIT_REQ; + + WLAN_VOS_DIAG_EVENT_REPORT(&wowRequest, EVENT_WLAN_POWERSAVE_WOW); +#endif + + pmcLog(pMac, LOG2, "PMC: entering pmcExitWowl"); + + /* Clear any buffered command for entering WOWL */ + pMac->pmc.wowlModeRequired = FALSE; + + /* are we exiting from WoW because of wake indication + or user disabling this feature */ + pMac->pmc.wowlExitSrc = wowlExitSrc; + + /* Enter REQUEST_EXIT_WOWL State*/ + if (pmcRequestExitWowlState(hHal) != eHAL_STATUS_SUCCESS) + return eHAL_STATUS_FAILURE; + + if (eWOWL_EXIT_USER == wowlExitSrc) + { + /* Clear the callback routines */ + pMac->pmc.enterWowlCallbackRoutine = NULL; + pMac->pmc.enterWowlCallbackContext = NULL; +#ifdef WLAN_WAKEUP_EVENTS + pMac->pmc.wakeReasonIndCB = NULL; + pMac->pmc.wakeReasonIndCBContext = NULL; +#endif + } + + return eHAL_STATUS_SUCCESS; +} + + + +/* --------------------------------------------------------------------------- + \fn pmcSetHostOffload + \brief Set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetHostOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, + tANI_U8 sessionId) +{ + tpSirHostOffloadReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: IP address = %d.%d.%d.%d", __func__, + pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1], + pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: SESSION not Found\n", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirHostOffloadReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for host offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirHostOffloadReq)); + + msg.type = WDA_SET_HOST_OFFLOAD; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_HOST_OFFLOAD message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcSetKeepAlive + \brief Set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the keepalive. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetKeepAlive (tHalHandle hHal, tpSirKeepAliveReq pRequest, tANI_U8 sessionId) +{ + tpSirKeepAliveReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, "%s: " + "WDA_SET_KEEP_ALIVE message", __func__); + + if(pSession == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + " Session not Found", __func__); + return eHAL_STATUS_FAILURE; + } + pRequestBuf = vos_mem_malloc(sizeof(tSirKeepAliveReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to allocate memory for keep alive request", + __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirKeepAliveReq)); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_LOW, "buff TP %d " + "input TP %d ", pRequestBuf->timePeriod, pRequest->timePeriod); + + msg.type = WDA_SET_KEEP_ALIVE; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post WDA_SET_KEEP_ALIVE message to WDA", + __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +#ifdef WLAN_NS_OFFLOAD + +/* --------------------------------------------------------------------------- + \fn pmcSetNSOffload + \brief Set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetNSOffload (tHalHandle hHal, tpSirHostOffloadReq pRequest, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpSirHostOffloadReq pRequestBuf; + vos_msg_t msg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if( NULL == pSession ) + { + pmcLog(pMac, LOGE, FL("Session not found ")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRequest->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + pRequestBuf = vos_mem_malloc(sizeof(tSirHostOffloadReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for NS offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirHostOffloadReq)); + + msg.type = WDA_SET_NS_OFFLOAD; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post SIR_HAL_SET_HOST_OFFLOAD message to HAL", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +#endif //WLAN_NS_OFFLOAD + + +void pmcClosePowerSaveCheckList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpPowerSaveCheckEntry pPowerSaveCheckEntry; + + csrLLLock(&pMac->pmc.powerSaveCheckList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.powerSaveCheckList, FALSE)) ) + { + pPowerSaveCheckEntry = GET_BASE_ADDR(pEntry, tPowerSaveCheckEntry, link); + vos_mem_free(pPowerSaveCheckEntry); + } + csrLLUnlock(&pMac->pmc.powerSaveCheckList); + csrLLClose(&pMac->pmc.powerSaveCheckList); +} + + +void pmcCloseRequestFullPowerList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpRequestFullPowerEntry pRequestFullPowerEntry; + + csrLLLock(&pMac->pmc.requestFullPowerList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestFullPowerList, FALSE)) ) + { + pRequestFullPowerEntry = GET_BASE_ADDR(pEntry, tRequestFullPowerEntry, link); + vos_mem_free(pRequestFullPowerEntry); + } + csrLLUnlock(&pMac->pmc.requestFullPowerList); + csrLLClose(&pMac->pmc.requestFullPowerList); +} + + +void pmcCloseRequestBmpsList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpRequestBmpsEntry pRequestBmpsEntry; + + csrLLLock(&pMac->pmc.requestBmpsList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestBmpsList, FALSE)) ) + { + pRequestBmpsEntry = GET_BASE_ADDR(pEntry, tRequestBmpsEntry, link); + vos_mem_free(pRequestBmpsEntry); + } + csrLLUnlock(&pMac->pmc.requestBmpsList); + csrLLClose(&pMac->pmc.requestBmpsList); +} + + +void pmcCloseRequestStartUapsdList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpStartUapsdEntry pStartUapsdEntry; + + csrLLLock(&pMac->pmc.requestStartUapsdList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.requestStartUapsdList, FALSE)) ) + { + pStartUapsdEntry = GET_BASE_ADDR(pEntry, tStartUapsdEntry, link); + vos_mem_free(pStartUapsdEntry); + } + csrLLUnlock(&pMac->pmc.requestStartUapsdList); + csrLLClose(&pMac->pmc.requestStartUapsdList); +} + + +void pmcCloseDeviceStateUpdateList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tpDeviceStateUpdateIndEntry pDeviceStateUpdateIndEntry; + + csrLLLock(&pMac->pmc.deviceStateUpdateIndList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.deviceStateUpdateIndList, FALSE)) ) + { + pDeviceStateUpdateIndEntry = GET_BASE_ADDR(pEntry, tDeviceStateUpdateIndEntry, link); + vos_mem_free(pDeviceStateUpdateIndEntry); + } + csrLLUnlock(&pMac->pmc.deviceStateUpdateIndList); + csrLLClose(&pMac->pmc.deviceStateUpdateIndList); +} + + +void pmcCloseDeferredMsgList(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tPmcDeferredMsg *pDeferredMsg; + + csrLLLock(&pMac->pmc.deferredMsgList); + while ( (pEntry = csrLLRemoveHead(&pMac->pmc.deferredMsgList, FALSE)) ) + { + pDeferredMsg = GET_BASE_ADDR(pEntry, tPmcDeferredMsg, link); + vos_mem_free(pDeferredMsg); + } + csrLLUnlock(&pMac->pmc.deferredMsgList); + csrLLClose(&pMac->pmc.deferredMsgList); +} + + +#ifdef FEATURE_WLAN_SCAN_PNO + +static tSirRetStatus +pmcPopulateMacHeader( tpAniSirGlobal pMac, + tANI_U8* pBD, + tANI_U8 type, + tANI_U8 subType, + tSirMacAddr peerAddr, + tSirMacAddr selfMacAddr) +{ + tSirRetStatus statusCode = eSIR_SUCCESS; + tpSirMacMgmtHdr pMacHdr; + + /// Prepare MAC management header + pMacHdr = (tpSirMacMgmtHdr) (pBD); + + // Prepare FC + pMacHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + pMacHdr->fc.type = type; + pMacHdr->fc.subType = subType; + + // Prepare Address 1 + vos_mem_copy((tANI_U8 *) pMacHdr->da, (tANI_U8 *) peerAddr, sizeof( tSirMacAddr )); + + sirCopyMacAddr(pMacHdr->sa,selfMacAddr); + + // Prepare Address 3 + vos_mem_copy((tANI_U8 *) pMacHdr->bssId, (tANI_U8 *) peerAddr, sizeof( tSirMacAddr )); + return statusCode; +} /*** pmcPopulateMacHeader() ***/ + + +static tSirRetStatus +pmcPrepareProbeReqTemplate(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tANI_U32 dot11mode, + tSirMacAddr selfMacAddr, + tANI_U8 *pFrame, + tANI_U16 *pusLen) +{ + tDot11fProbeRequest pr; + tANI_U32 nStatus, nBytes, nPayload; + tSirRetStatus nSirStatus; + /*Bcast tx*/ + tSirMacAddr bssId = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + // The scheme here is to fill out a 'tDot11fProbeRequest' structure + // and then hand it off to 'dot11fPackProbeRequest' (for + // serialization). We start by zero-initializing the structure: + vos_mem_set(( tANI_U8* )&pr, sizeof( pr ), 0); + + PopulateDot11fSuppRates( pMac, nChannelNum, &pr.SuppRates,NULL); + + if ( WNI_CFG_DOT11_MODE_11B != dot11mode ) + { + PopulateDot11fExtSuppRates1( pMac, nChannelNum, &pr.ExtSuppRates ); + } + + + if (IS_DOT11_MODE_HT(dot11mode)) + { + PopulateDot11fHTCaps( pMac, NULL, &pr.HTCaps ); + } + + // That's it-- now we pack it. First, how much space are we going to + // need? + nStatus = dot11fGetPackedProbeRequestSize( pMac, &pr, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to calculate the packed size f" + "or a Probe Request (0x%08x).", nStatus ); + + // We'll fall back on the worst case scenario: + nPayload = sizeof( tDot11fProbeRequest ); + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while calculating" + "the packed size for a Probe Request (" + "0x%08x).", nStatus ); + } + + nBytes = nPayload + sizeof( tSirMacMgmtHdr ); + + /* Prepare outgoing frame*/ + vos_mem_set(pFrame, nBytes, 0); + + // Next, we fill out the buffer descriptor: + nSirStatus = pmcPopulateMacHeader( pMac, pFrame, SIR_MAC_MGMT_FRAME, + SIR_MAC_MGMT_PROBE_REQ, bssId,selfMacAddr); + + if ( eSIR_SUCCESS != nSirStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to populate the buffer descriptor for a Probe Request (%d).", + nSirStatus ); + return nSirStatus; // allocated! + } + + // That done, pack the Probe Request: + nStatus = dot11fPackProbeRequest( pMac, &pr, pFrame + + sizeof( tSirMacMgmtHdr ), + nPayload, &nPayload ); + if ( DOT11F_FAILED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to pack a Probe Request (0x%08x).", nStatus ); + return eSIR_FAILURE; // allocated! + } + else if ( DOT11F_WARNED( nStatus ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "There were warnings while packing a Probe Request" ); + } + + *pusLen = nPayload + sizeof(tSirMacMgmtHdr); + return eSIR_SUCCESS; +} // End pmcPrepareProbeReqTemplate. + + +eHalStatus pmcSetPreferredNetworkList +( + tHalHandle hHal, + tpSirPNOScanReq pRequest, + tANI_U8 sessionId, + preferredNetworkFoundIndCallback callbackRoutine, + void *callbackContext +) +{ + tpSirPNOScanReq pRequestBuf; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + tANI_U8 ucDot11Mode; + tSmeCmd *pCommand; + tANI_U8 *tmp = NULL; + tANI_U16 len = 0; + + if (NULL == pSession) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: pSession is NULL", __func__); + return eHAL_STATUS_FAILURE; + } + + pCommand = csrGetCommandBuffer(pMac); + if(NULL == pCommand) + { + smsLog( pMac, LOGE, FL(" fail to get command buffer") ); + return eHAL_STATUS_RESOURCES; + } + pRequestBuf = &(pCommand->u.pnoInfo); + vos_mem_copy(pRequestBuf, pRequest, sizeof(tSirPNOScanReq)); + if (pRequestBuf->enable == 1) + { + if (pRequestBuf->ucNetworksCount == 0) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Network count is 0")); + csrReleaseCommand(pMac, pCommand); + return eHAL_STATUS_FAILURE; + } + /*Must translate the mode first*/ + ucDot11Mode = (tANI_U8) csrTranslateToWNICfgDot11Mode(pMac, + csrFindBestPhyMode( pMac, pMac->roam.configParam.phyMode )); + + if (pRequestBuf->us24GProbeTemplateLen || + pRequestBuf->us5GProbeTemplateLen) + { + tmp = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE); + if (tmp == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to allocate memory")); + } + /* Continue even mem alloc fails as driver can still go ahead + * without supplicant IE's in probe req. + */ + } + + if (NULL != tmp) + { + len = pRequestBuf->us24GProbeTemplateLen; + if (0 != len && len <= SIR_PNO_MAX_PB_REQ_SIZE) + { + vos_mem_copy(tmp, pRequestBuf->p24GProbeTemplate, len); + } + } + + /*Prepare a probe request for 2.4GHz band and one for 5GHz band*/ + if (eSIR_SUCCESS == pmcPrepareProbeReqTemplate(pMac, SIR_PNO_24G_DEFAULT_CH, + ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p24GProbeTemplate, + &pRequestBuf->us24GProbeTemplateLen)) + { + /* Append IE passed by supplicant(if any) to probe request */ + if ((0 < len) &&((pRequestBuf->us24GProbeTemplateLen + len) + < SIR_PNO_MAX_PB_REQ_SIZE )) + { + vos_mem_copy((tANI_U8 *)&pRequestBuf->p24GProbeTemplate + + pRequestBuf->us24GProbeTemplateLen, + tmp, + len); + pRequestBuf->us24GProbeTemplateLen += len; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: us24GProbeTemplateLen = %d", __func__, + pRequestBuf->us24GProbeTemplateLen); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Extra ie discarded on 2.4G, IE length = %d Max IE length is %d", + __func__, pRequestBuf->us24GProbeTemplateLen, SIR_PNO_MAX_PB_REQ_SIZE); + } + } + + len = 0; + if (NULL != tmp) + { + len = pRequestBuf->us5GProbeTemplateLen; + if (0 != len && len <= SIR_PNO_MAX_PB_REQ_SIZE) + { + vos_mem_copy(tmp, pRequestBuf->p5GProbeTemplate, len); + } + } + + if (eSIR_SUCCESS == pmcPrepareProbeReqTemplate(pMac, SIR_PNO_5G_DEFAULT_CH, + ucDot11Mode, pSession->selfMacAddr, + pRequestBuf->p5GProbeTemplate, + &pRequestBuf->us5GProbeTemplateLen)) + { + /* Append IE passed by supplicant(if any) to probe request */ + if ((0 < len) &&((pRequestBuf->us5GProbeTemplateLen + len) + < SIR_PNO_MAX_PB_REQ_SIZE)) + { + vos_mem_copy((tANI_U8 *)&pRequestBuf->p5GProbeTemplate + + pRequestBuf->us5GProbeTemplateLen, + tmp, + len); + pRequestBuf->us5GProbeTemplateLen += len; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: us5GProbeTemplateLen = %d", __func__, + pRequestBuf->us5GProbeTemplateLen); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Extra IE discarded on 5G, IE length = %d Max IE length is %d", + __func__, pRequestBuf->us5GProbeTemplateLen, SIR_PNO_MAX_PB_REQ_SIZE); + } + } + if (NULL != tmp) + vos_mem_free(tmp); + } + pCommand->command = eSmeCommandPnoReq; + pCommand->sessionId = (tANI_U8)sessionId; + + if (!HAL_STATUS_SUCCESS(csrQueueSmeCommand(pMac, pCommand, + !pRequestBuf->enable))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to post eSmeCommandPnoReq command")); + csrReleaseCommand(pMac, pCommand); + return eHAL_STATUS_FAILURE; + } + + /* Cache the Preferred Network Found Indication callback information */ + pMac->pmc.prefNetwFoundCB = callbackRoutine; + pMac->pmc.preferredNetworkFoundIndCallbackContext = callbackContext; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "-%s", __func__); + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus pmcSetRssiFilter(tHalHandle hHal, v_U8_t rssiThreshold) +{ + tpSirSetRSSIFilterReq pRequestBuf; + vos_msg_t msg; + + + pRequestBuf = vos_mem_malloc(sizeof(tSirSetRSSIFilterReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for PNO request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + + pRequestBuf->rssiThreshold = rssiThreshold; + + msg.type = WDA_SET_RSSI_FILTER_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_PNO_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + +eHalStatus pmcUpdateScanParams(tHalHandle hHal, tCsrConfig *pRequest, tCsrChannel *pChannelList, tANI_U8 b11dResolved) +{ + tpSirUpdateScanParams pRequestBuf; + vos_msg_t msg; + int i; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s started", __func__); + + pRequestBuf = vos_mem_malloc(sizeof(tSirUpdateScanParams)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for UpdateScanParams request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + // + // Fill pRequestBuf structure from pRequest + // + pRequestBuf->b11dEnabled = pRequest->Is11eSupportEnabled; + pRequestBuf->b11dResolved = b11dResolved; + pRequestBuf->ucChannelCount = + ( pChannelList->numChannels < SIR_PNO_MAX_NETW_CHANNELS_EX )? + pChannelList->numChannels:SIR_PNO_MAX_NETW_CHANNELS_EX; + + for (i=0; i < pRequestBuf->ucChannelCount; i++) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Channel List %d: %d", __FUNCTION__, i, pChannelList->channelList[i] ); + + pRequestBuf->aChannels[i] = pChannelList->channelList[i]; + } + pRequestBuf->usPassiveMinChTime = pRequest->nPassiveMinChnTime; + pRequestBuf->usPassiveMaxChTime = pRequest->nPassiveMaxChnTime; + pRequestBuf->usActiveMinChTime = pRequest->nActiveMinChnTime; + pRequestBuf->usActiveMaxChTime = pRequest->nActiveMaxChnTime; + pRequestBuf->ucCBState = PHY_SINGLE_CHANNEL_CENTERED; + + msg.type = WDA_UPDATE_SCAN_PARAMS_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_UPDATE_SCAN_PARAMS message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // FEATURE_WLAN_SCAN_PNO + +eHalStatus pmcSetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced) +{ + tSirSetPowerParamsReq* pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpPESession psessionEntry; + + psessionEntry = peGetValidPowerSaveSession(pMac); + if (!forced && (psessionEntry == NULL)) + { + return eHAL_STATUS_NOT_INITIALIZED; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirSetPowerParamsReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for Power Paramrequest", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + + vos_mem_copy(pRequestBuf, pwParams, sizeof(*pRequestBuf)); + + + msg.type = WDA_SET_POWER_PARAMS_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_POWER_PARAMS_REQ message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +eHalStatus pmcGetFilterMatchCount +( + tHalHandle hHal, + FilterMatchCountCallback callbackRoutine, + void *callbackContext, + tANI_U8 sessionId +) +{ + tpSirRcvFltPktMatchRsp pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s", __func__); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session not found ", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltPktMatchRsp)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate " + "memory for Get PC Filter Match Count request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + msg.type = WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + /* Cache the Packet Coalescing Filter Match Count callback information */ + if (NULL != pMac->pmc.FilterMatchCountCB) + { + // Do we need to check if the callback is in use? + // Because we are not sending the same message again when it is pending, + // the only case when the callback is not NULL is that the previous message + //was timed out or failed. + // So, it will be safe to set the callback in this case. + } + + pMac->pmc.FilterMatchCountCB = callbackRoutine; + pMac->pmc.FilterMatchCountCBContext = callbackContext; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ " + "message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* --------------------------------------------------------------------------- + \fn pmcSetGTKOffload + \brief Set GTK offload feature. + \param hHal - The handle returned by macOpen. + \param pGtkOffload - Pointer to the GTK offload request. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcSetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pGtkOffload, + tANI_U8 sessionId) +{ + tpSirGtkOffloadParams pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: KeyReplayCounter: %lld", + __func__, pGtkOffload->ullKeyReplayCounter); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session not found ", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = (tpSirGtkOffloadParams)vos_mem_malloc(sizeof(tSirGtkOffloadParams)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate " + "memory for GTK offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pGtkOffload->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vos_mem_copy(pRequestBuf, pGtkOffload, sizeof(tSirGtkOffloadParams)); + + msg.type = WDA_GTK_OFFLOAD_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post " + "SIR_HAL_SET_GTK_OFFLOAD message to HAL", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn pmcGetGTKOffload + \brief Get GTK offload information. + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Pointer to the GTK Offload Get Info response callback routine. + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set the offload. + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus pmcGetGTKOffload(tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId) +{ + tpSirGtkOffloadGetInfoRspParams pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: Entered", + __func__); + + if(NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session not found ", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = (tpSirGtkOffloadGetInfoRspParams) + vos_mem_malloc(sizeof (tSirGtkOffloadGetInfoRspParams)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate " + "memory for Get GTK offload request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr)); + + msg.type = WDA_GTK_OFFLOAD_GETINFO_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + /* Cache the Get GTK Offload callback information */ + if (NULL != pMac->pmc.GtkOffloadGetInfoCB) + { + // Do we need to check if the callback is in use? + // Because we are not sending the same message again when it is pending, + // the only case when the callback is not NULL is that the previous message was timed out or failed. + // So, it will be safe to set the callback in this case. + } + + pMac->pmc.GtkOffloadGetInfoCB = callbackRoutine; + pMac->pmc.GtkOffloadGetInfoCBContext = callbackContext; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_GTK_OFFLOAD_GETINFO_REQ message to WDA", + __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +v_BOOL_t IsPmcImpsReqFailed (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_BOOL_t impsReqFailStatus; + + impsReqFailStatus = (pMac->pmc.ImpsReqFailed || pMac->pmc.ImpsReqTimerFailed); + + return impsReqFailStatus; + +} + +void pmcResetImpsFailStatus (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->pmc.ImpsReqFailed = VOS_FALSE; + pMac->pmc.ImpsReqTimerFailed = VOS_FALSE; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* ----------------------------------------------------------------------------- + \fn pmcSetBatchScanReq + \brief setting batch scan request in FW + \param hHal - The handle returned by macOpen. + \param sessionId - session ID + \param callbackRoutine - Pointer to set batch scan request callback routine + \param callbackContext - Pointer to set batch scan request callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +eHalStatus pmcSetBatchScanReq(tHalHandle hHal, tSirSetBatchScanReq *pRequest, + tANI_U8 sessionId, hddSetBatchScanReqCallback callbackRoutine, + void *callbackContext) +{ + tpSirSetBatchScanReq pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pRequestBuf = vos_mem_malloc(sizeof(tSirSetBatchScanReq)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for SET BATCH SCAN req", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + /* Cache HDD callback information*/ + pMac->pmc.setBatchScanReqCallback = callbackRoutine; + pMac->pmc.setBatchScanReqCallbackContext = callbackContext; + + pRequestBuf->scanFrequency = pRequest->scanFrequency; + pRequestBuf->numberOfScansToBatch = pRequest->numberOfScansToBatch; + pRequestBuf->bestNetwork = pRequest->bestNetwork; + pRequestBuf->rfBand = pRequest->rfBand; + pRequestBuf->rtt = pRequest->rtt; + + msg.type = WDA_SET_BATCH_SCAN_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_BATCH_SCAN_REQ message to WDA", + __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + \fn pmcTriggerBatchScanResultInd + \brief API to trigger batch scan results indications from FW + \param hHal - The handle returned by macOpen. + \param sessionId - session ID + \param callbackRoutine - Pointer to get batch scan request callback routine + \param callbackContext - Pointer to get batch scan request callback context + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +eHalStatus pmcTriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + hddTriggerBatchScanResultIndCallback callbackRoutine, void *callbackContext +) +{ + tpSirTriggerBatchScanResultInd pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pRequestBuf = vos_mem_malloc(sizeof(tSirTriggerBatchScanResultInd)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_TRIGGER_BATCH_SCAN_RESULT_IND", + __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + /*HDD callback to be called after getting batch scan result ind from FW*/ + pMac->pmc.batchScanResultCallback = callbackRoutine; + pMac->pmc.batchScanResultCallbackContext = callbackContext; + + pRequestBuf->param = pRequest->param; + + msg.type = WDA_TRIGGER_BATCH_SCAN_RESULT_IND; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_TRIGGER_BATCH_SCAN_RESULT_IND message" + " to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* ----------------------------------------------------------------------------- + \fn pmcStopBatchScanInd + \brief Stoping batch scan request in FW + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Pointer to stop batch scan request callback routine + \return eHalStatus + eHAL_STATUS_FAILURE Cannot set batch scan request + eHAL_STATUS_SUCCESS Request accepted. + -----------------------------------------------------------------------------*/ + +eHalStatus pmcStopBatchScanInd(tHalHandle hHal, tSirStopBatchScanInd *pRequest, + tANI_U8 sessionId) +{ + tSirStopBatchScanInd *pRequestBuf; + vos_msg_t msg; + + pRequestBuf = vos_mem_malloc(sizeof(tSirStopBatchScanInd)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for STOP BATCH SCAN IND", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + pRequestBuf->param = pRequest->param; + + msg.type = WDA_STOP_BATCH_SCAN_IND; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_TOP_BATCH_SCAN_IND message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +#endif diff --git a/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c b/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c new file mode 100644 index 000000000000..ed9e32b85335 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/pmc/pmcLogDump.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* +* Name: pmcLogDump.c +* +* Description: Implements the dump commands specific to PMC module +* +* +******************************************************************************/ + +#include "palTypes.h" +#include "aniGlobal.h" +#include "pmcApi.h" +#include "pmc.h" +#include "logDump.h" +#include "smsDebug.h" +#include "sme_Api.h" +#include "cfgApi.h" + +#if defined(ANI_LOGDUMP) + +void dump_pmc_callbackRoutine (void *callbackContext, eHalStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + pmcLog(pMac, LOGW, "*********Received callback from PMC with status = %d\n*********",status); +} + +#ifdef WLAN_WAKEUP_EVENTS +void dump_pmc_callbackRoutine2 (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + pmcLog(pMac, LOGW, "*********Received callback from PMC with reason = %d\n*********",pWakeReasonInd->ulReason); +} +#endif // WLAN_WAKEUP_EVENTS + +void dump_pmc_deviceUpdateRoutine (void *callbackContext, tPmcState pmcState) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + pmcLog(pMac, LOGW, "*********Received msg from PMC: Device is in %s state\n*********", pmcGetPmcStateStr(pmcState)); +} + +static char * +dump_pmc_state( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + char *ptr = p; + + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + + p += log_sprintf( pMac,p, "******** PMC State & Configuration ******** \n"); + p += log_sprintf( pMac,p, " PMC: IMPS Enabled? %d\n", pMac->pmc.impsEnabled); + p += log_sprintf( pMac,p, " PMC: Auto BMPS Timer Enabled? %d\n", pMac->pmc.autoBmpsEntryEnabled); + p += log_sprintf( pMac,p, " PMC: BMPS Enabled? %d\n", pMac->pmc.bmpsEnabled); + p += log_sprintf( pMac,p, " PMC: UAPSD Enabled? %d\n", pMac->pmc.uapsdEnabled); + p += log_sprintf( pMac,p, " PMC: WoWL Enabled? %d\n", pMac->pmc.wowlEnabled); + p += log_sprintf( pMac,p, " PMC: Standby Enabled? %d\n", pMac->pmc.standbyEnabled); + p += log_sprintf( pMac,p, " PMC: Auto BMPS timer period (ms): %d\n", pMac->pmc.bmpsConfig.trafficMeasurePeriod); + p += log_sprintf( pMac,p, " PMC: BMPS Listen Interval (Beacon intervals): %d\n", pMac->pmc.bmpsConfig.bmpsPeriod); + p += log_sprintf( pMac,p, " PMC: Device State = %s\n", pmcGetPmcStateStr(pMac->pmc.pmcState)); + p += log_sprintf( pMac,p, " PMC: RequestFullPowerPending = %d\n", pMac->pmc.requestFullPowerPending); + p += log_sprintf( pMac,p, " PMC: UapsdSessionRequired = %d\n", pMac->pmc.uapsdSessionRequired); + p += log_sprintf( pMac,p, " PMC: wowlModeRequired = %d\n\n", pMac->pmc.wowlModeRequired); + p += log_sprintf( pMac,p, " PMC: isAPWOWExit = %d\n\n", pMac->pmc.isAPWOWExit); + + pmcLog(pMac, LOGW, "\n%s", ptr); + + return p; +} + +static char * +dump_pmc_enable_imps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcEnablePowerSave(pMac, ePMC_IDLE_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_disable_imps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcDisablePowerSave(pMac, ePMC_IDLE_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_request_imps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.impsEnabled = TRUE; + (void)pmcRequestImps(pMac, arg1, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_start_auto_bmps_timer( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.bmpsEnabled = TRUE; + (void)pmcStartAutoBmpsTimer(pMac); + return p; +} + +static char * +dump_pmc_stop_auto_bmps_timer( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcStopAutoBmpsTimer(pMac); + return p; +} + +static char * +dump_pmc_enable_bmps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcEnablePowerSave(pMac, ePMC_BEACON_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_disable_bmps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcDisablePowerSave(pMac, ePMC_BEACON_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_request_bmps( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.bmpsEnabled = TRUE; + (void)sme_RequestBmps(pMac, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_enable_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcEnablePowerSave(pMac, ePMC_UAPSD_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_disable_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcDisablePowerSave(pMac, ePMC_UAPSD_MODE_POWER_SAVE); + return p; +} + +static char * +dump_pmc_start_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.bmpsEnabled = TRUE; + pMac->pmc.uapsdEnabled = TRUE; + (void)pmcStartUapsd(pMac, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_stop_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)pmcStopUapsd(pMac); + return p; +} + +static char * +dump_pmc_request_standby( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + pMac->pmc.standbyEnabled = TRUE; + (void)pmcRequestStandby(pMac, dump_pmc_callbackRoutine, pMac); + return p; +} + +static char * +dump_pmc_request_full_power( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)sme_RequestFullPower(pMac, dump_pmc_callbackRoutine, pMac, eSME_FULL_PWR_NEEDED_BY_HDD); + return p; +} + +static char * +dump_pmc_enter_wowl( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeWowlEnterParams wowlEnterParams; + tSirRetStatus status; + tANI_U32 length; + tANI_U8 sessionId = 0; + + (void) arg4; + + vos_mem_set(&wowlEnterParams, sizeof(tSirSmeWowlEnterParams), 0); + + if (arg1 == 0 && arg2 == 0) + { + pmcLog(pMac, LOGE, + "Requesting WoWL but neither magic pkt and ptrn byte matching is being enabled\n"); + return p; + } + if(arg1 == 1) + { + wowlEnterParams.ucMagicPktEnable = 1; + /* magic packet */ + length = SIR_MAC_ADDR_LENGTH; + status = wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, (tANI_U8 *)wowlEnterParams.magicPtrn, &length); + if (eSIR_SUCCESS != status) + { + pmcLog(pMac, LOGE, + "Reading of WNI_CFG_STA_ID from CFG failed. Using hardcoded STA MAC Addr\n"); + wowlEnterParams.magicPtrn[0] = 0x00; + wowlEnterParams.magicPtrn[1] = 0x0a; + wowlEnterParams.magicPtrn[2] = 0xf5; + wowlEnterParams.magicPtrn[3] = 0x04; + wowlEnterParams.magicPtrn[4] = 0x05; + wowlEnterParams.magicPtrn[5] = 0x06; + } + } + if(arg2 == 1) + { + wowlEnterParams.ucPatternFilteringEnable = 1; + } + + if(arg3 == CSR_ROAM_SESSION_MAX ) + { + pmcLog(pMac, LOGE, "Enter valid sessionId\n"); + return p; + } + pMac->pmc.bmpsEnabled = TRUE; + pMac->pmc.wowlEnabled = TRUE; + + sessionId = (tANI_U8 ) arg3; +#ifdef WLAN_WAKEUP_EVENTS + (void)sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, dump_pmc_callbackRoutine2, pMac, + &wowlEnterParams, sessionId); +#else // WLAN_WAKEUP_EVENTS + (void)sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, &wowlEnterParams, sessionId); +#endif // WLAN_WAKEUP_EVENTS + return p; +} + +static char * +dump_pmc_exit_wowl( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + (void)sme_ExitWowl(pMac, eWOWL_EXIT_USER); + return p; +} + +static char * +dump_pmc_remove_ptrn( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirWowlDelBcastPtrn delPattern; + tANI_U8 sessionId = 0; + (void) arg3; (void) arg4; + + vos_mem_set(&delPattern, sizeof(tSirWowlDelBcastPtrn), 0); + + if((arg1 <= 7) || (arg2 == CSR_ROAM_SESSION_MAX)) + { + delPattern.ucPatternId = (tANI_U8)arg1; + } + else + { + pmcLog(pMac, LOGE, "dump_pmc_remove_ptrn: Invalid pattern Id %d\n",arg1); + return p; + } + + sessionId = (tANI_U8 ) arg2; + (void)pmcWowlDelBcastPattern(pMac, &delPattern, sessionId); + return p; +} + +static char * +dump_pmc_test_uapsd( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeRsp smeRsp; + smeRsp.statusCode = eSIR_SME_SUCCESS; + + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + + pMac->pmc.uapsdEnabled = TRUE; + pMac->pmc.pmcState = BMPS; + + pmcRegisterDeviceStateUpdateInd(pMac, dump_pmc_deviceUpdateRoutine, pMac); + + pmcStartUapsd(pMac, dump_pmc_callbackRoutine, pMac); + smeRsp.messageType = eWNI_PMC_ENTER_UAPSD_RSP; + pmcMessageProcessor(pMac, &smeRsp); + pmcStopUapsd(pMac); + smeRsp.messageType = eWNI_PMC_EXIT_UAPSD_RSP; + pmcMessageProcessor(pMac, &smeRsp); + pmcDeregisterDeviceStateUpdateInd(pMac, dump_pmc_deviceUpdateRoutine); + return p; +} + +static char * +dump_pmc_test_Wowl( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tSirSmeRsp smeRsp; + tSirWowlAddBcastPtrn addPattern; + tSirWowlDelBcastPtrn delPattern; + tSirSmeWowlEnterParams wowlEnterParams; + tANI_U8 sessionId = 0; + + smeRsp.statusCode = eSIR_SME_SUCCESS; + vos_mem_set(&addPattern, sizeof(tSirWowlAddBcastPtrn), 0); + vos_mem_set(&delPattern, sizeof(tSirWowlDelBcastPtrn), 0); + vos_mem_set(&wowlEnterParams, sizeof(tSirSmeWowlEnterParams), 0); + + (void) arg2; (void) arg3; (void) arg4; + + if(arg1 == CSR_ROAM_SESSION_MAX) + { + pmcLog(pMac, LOGE, "dump_pmc_test_Wowl: Invalid sessionId\n"); + return p; + } + + sessionId = (tANI_U8 ) arg1; + //Add pattern + sme_WowlAddBcastPattern(pMac, &addPattern, sessionId); + + //Delete pattern + sme_WowlDelBcastPattern(pMac, &delPattern, sessionId); + + //Force the device into BMPS + pMac->pmc.pmcState = BMPS; + + //Enter Wowl +#ifdef WLAN_WAKEUP_EVENTS + sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, dump_pmc_callbackRoutine2, pMac, + &wowlEnterParams, sessionId); +#else // WLAN_WAKEUP_EVENTS + sme_EnterWowl(pMac, dump_pmc_callbackRoutine, pMac, &wowlEnterParams, sessionId); +#endif // WLAN_WAKEUP_EVENTS + smeRsp.messageType = eWNI_PMC_ENTER_WOWL_RSP; + pmcMessageProcessor(pMac, &smeRsp); + + //Exit Wowl + sme_ExitWowl(pMac, eWOWL_EXIT_USER); + smeRsp.messageType = eWNI_PMC_EXIT_WOWL_RSP; + pmcMessageProcessor(pMac, &smeRsp); + return p; +} + +static tDumpFuncEntry pmcMenuDumpTable[] = { + {0, "PMC (900-925)", NULL}, + // General + {900, "PMC: Dump State + config", dump_pmc_state}, + // IMPS Related + {901, "PMC: Enable IMPS", dump_pmc_enable_imps}, + {902, "PMC: Disable IMPS", dump_pmc_disable_imps}, + {903, "PMC: Request IMPS: Syntax: dump 903 ", dump_pmc_request_imps}, + // BMPS Related + {904, "PMC: Start Auto BMPS Timer", dump_pmc_start_auto_bmps_timer}, + {905, "PMC: Stop Auto BMPS Timer", dump_pmc_stop_auto_bmps_timer}, + {906, "PMC: Request BMPS", dump_pmc_request_bmps}, + // UAPSD Related + {907, "PMC: Enable UAPSD", dump_pmc_enable_uapsd}, + {908, "PMC: Disable UAPSD", dump_pmc_disable_uapsd}, + {909, "PMC: Start UAPSD", dump_pmc_start_uapsd}, + {910, "PMC: Stop UAPSD", dump_pmc_stop_uapsd}, + // Standby Related + {911, "PMC: Request Standby", dump_pmc_request_standby}, + // Full Power Related + {912, "PMC: Request Full Power", dump_pmc_request_full_power}, + //Unit Test Related + {913, "PMC: Test UAPSD", dump_pmc_test_uapsd}, + {914, "PMC: Test WOWL : Syntax :dump 914 ", dump_pmc_test_Wowl}, + // WoWL Related + {915, "PMC: Enter WoWL: Syntax: dump 915 ", dump_pmc_enter_wowl}, + {916, "PMC: Exit WoWL", dump_pmc_exit_wowl}, + {917, "PMC: Remove a pattern: Syntax: dump 917 >", dump_pmc_remove_ptrn}, + {918, "PMC: Enable BMPS", dump_pmc_enable_bmps}, + {919, "PMC: Disable BMPS", dump_pmc_disable_bmps} +}; + +void pmcDumpInit(tHalHandle hHal) +{ + logDumpRegisterTable( (tpAniSirGlobal)hHal, &pmcMenuDumpTable[0], + sizeof(pmcMenuDumpTable)/sizeof(pmcMenuDumpTable[0]) ); +} + +#endif //#if defined(ANI_LOGDUMP) diff --git a/drivers/staging/prima/CORE/SME/src/rrm/sme_rrm.c b/drivers/staging/prima/CORE/SME/src/rrm/sme_rrm.c new file mode 100644 index 000000000000..af18b4f41ec9 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/rrm/sme_rrm.c @@ -0,0 +1,1613 @@ +/* + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file sme_Rrm.c + + \brief implementation for SME RRM APIs + + + ========================================================================*/ + +/* $Header$ */ + +#if defined WLAN_FEATURE_VOWIFI +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "aniGlobal.h" +#include "smeInside.h" +#include "sme_Api.h" +#include "smsDebug.h" +#include "cfgApi.h" + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_event.h" +#include "vos_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#include "csrInsideApi.h" + +#include "rrmGlobal.h" + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +#include "csrEse.h" +#endif + +/* Roam score for a neighbor AP will be calculated based on the below definitions. + The calculated roam score will be used to select the roamable candidate from neighbor AP list */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY 0 /* When we support 11r over the DS, this should have a non-zero value */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY 10 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE 20 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT 0 /* Not used */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS 5 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD 3 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM 8 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA 0 /* We dont support delayed BA */ +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA 3 +#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN 30 + +#ifdef FEATURE_WLAN_ESE +#define RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST 30 +#endif + +v_TIME_t RRM_scan_timer; + +/**--------------------------------------------------------------------------- + + \brief rrmLLPurgeNeighborCache() - + This function purges all the entries in the neighbor cache and frees up all the internal nodes + + \param - pMac - Pointer to the Hal Handle. + - pList - Pointer the List that should be purged. + \return - void + + --------------------------------------------------------------------------*/ +static void rrmLLPurgeNeighborCache(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + tListElem *pEntry; + tRrmNeighborReportDesc *pNeighborReportDesc; + + csrLLLock(pList); + + while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL) + { + pNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + vos_mem_free(pNeighborReportDesc->pNeighborBssDescription); + vos_mem_free(pNeighborReportDesc); + } + + csrLLUnlock(pList); + + return; +} + +/**--------------------------------------------------------------------------- + + \brief rrmIndicateNeighborReportResult() - + This function calls the callback register by the caller while requesting for + neighbor report. This function gets invoked if a neighbor report is received from an AP + or neighbor response wait timer expires. + + \param - pMac - Pointer to the Hal Handle. + - vosStatus - VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE based on whether a valid report is + received or neighbor timer expired + \return - void + + --------------------------------------------------------------------------*/ +void rrmIndicateNeighborReportResult(tpAniSirGlobal pMac, VOS_STATUS vosStatus) +{ + NeighborReportRspCallback callback; + void *callbackContext; + + /* Reset the neighbor response pending status */ + pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE; + + /* Stop the timer if it is already running. The timer should be running only in the SUCCESS case. */ + if (VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer)) + { + smsLog( pMac, LOG1, FL("No entry in neighbor report cache")); + vos_timer_stop(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer); + } + callback = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback; + callbackContext = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext; + + /* Reset the callback and the callback context before calling the callback. It is very likely that there may be a registration in + callback itself. */ + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = NULL; + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = NULL; + + /* Call the callback with the status received from caller */ + if (callback) + callback(callbackContext, vosStatus); +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + // We came here with IAPP AP List + // Make sure we inform CSR of the neighbor list + // for ESE Associations. First clear the cache. + else + if (csrNeighborRoamIsESEAssoc(pMac)) + { + ProcessIAPPNeighborAPList(pMac); + } +#endif + + return; + +} + +/**--------------------------------------------------------------------------- + + \brief sme_RrmBeaconReportXmitInd() - + + Create and send the beacon report Xmit ind message to PE. + + \param - pMac - Pointer to the Hal Handle. + - pResult - scan result. + - measurementDone - flag to indicate that the measurement is done. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, + tCsrScanResultInfo **pResultArr, + tANI_U8 measurementDone, + tANI_U8 bss_count ) +{ + tpSirBssDescription pBssDesc = NULL; + tpSirBeaconReportXmitInd pBeaconRep; + tANI_U16 length, ie_len; + tANI_U8 bssCounter=0, msgCounter=0; + tCsrScanResultInfo *pCurResult=NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Beacon report xmit Ind to PE"); +#endif + + if( NULL == pResultArr && !measurementDone ) + { + smsLog( pMac, LOGE, "Beacon report xmit Ind to PE Failed"); + return eHAL_STATUS_FAILURE; + } + + if (pResultArr) + pCurResult=pResultArr[bssCounter]; + + do + { + length = sizeof(tSirBeaconReportXmitInd); + pBeaconRep = vos_mem_malloc ( length ); + if ( NULL == pBeaconRep ) + { + smsLog( pMac, LOGP, "Unable to allocate memory for beacon report"); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_zero( pBeaconRep, length ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for pBeaconRep")); +#endif + pBeaconRep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND; + pBeaconRep->length = length; + pBeaconRep->uDialogToken = pSmeRrmContext->token; + pBeaconRep->duration = pSmeRrmContext->duration[0]; + pBeaconRep->regClass = pSmeRrmContext->regClass; + vos_mem_copy( pBeaconRep->bssId, pSmeRrmContext->sessionBssId, sizeof(tSirMacAddr) ); + + msgCounter=0; + while (pCurResult) + { + pBssDesc = &pCurResult->BssDescriptor; + if(pBssDesc != NULL) + { + ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length ); + pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc ( + ie_len+sizeof(tSirBssDescription)); + if (NULL == pBeaconRep->pBssDescription[msgCounter]) + break; + vos_mem_zero(pBeaconRep->pBssDescription[msgCounter], + ie_len+sizeof(tSirBssDescription)); + vos_mem_copy( pBeaconRep->pBssDescription[msgCounter], + pBssDesc, + sizeof(tSirBssDescription) ); + vos_mem_copy( &pBeaconRep->pBssDescription[msgCounter]->ieFields[0], + pBssDesc->ieFields, ie_len ); + smsLog( pMac, LOG1, + "...RRM Result Bssid = "MAC_ADDRESS_STR" chan= %d, rssi = -%d", + MAC_ADDR_ARRAY(pBeaconRep->pBssDescription[msgCounter]->bssId), + pBeaconRep->pBssDescription[msgCounter]->channelId, + pBeaconRep->pBssDescription[msgCounter]->rssi * (-1)); + + pBeaconRep->numBssDesc++; + + if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC) + break; + + pCurResult = pResultArr[bssCounter + msgCounter]; + } + else + { + pCurResult = NULL; + break; + } + } + + bssCounter+=msgCounter; + if (!pResultArr || (pCurResult == NULL) || (bssCounter >= bss_count)) + { + pCurResult = NULL; + smsLog(pMac, LOG1, + "Reached to the max/last BSS in pCurResult list"); + } + else + { + pCurResult = pResultArr[bssCounter]; + smsLog(pMac, LOG1, + "Move to the next BSS set in pCurResult list"); + } + + pBeaconRep->fMeasureDone = (pCurResult)?false:measurementDone; + + smsLog(pMac, LOG1, + "SME Sending BcnRepXmit to PE numBss %d msgCounter %d bssCounter %d", + pBeaconRep->numBssDesc, msgCounter, bssCounter); + + status = palSendMBMessage(pMac->hHdd, pBeaconRep); + + } while (pCurResult); + + return status; +} + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +/**--------------------------------------------------------------------------- + + \brief sme_EseSendBeaconReqScanResults() + + This function sends up the scan results received as a part of + beacon request scanning. + This function is called after receiving the scan results per channel + Due to the limitation on the size of the IWEVCUSTOM buffer, we send 3 BSSIDs of + beacon report information in one custom event; + + \param - pMac - Pointer to the Hal Handle. + - sessionId - Session id + - channel - scan results belongs to this channel + - pResultArr - scan result. + - measurementDone - flag to indicate that the measurement is done. + - bss_count - number of bss found + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static eHalStatus sme_EseSendBeaconReqScanResults(tpAniSirGlobal pMac, + tANI_U32 sessionId, + tANI_U8 channel, + tCsrScanResultInfo **pResultArr, + tANI_U8 measurementDone, + tANI_U8 bss_count) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tSirRetStatus fillIeStatus; + tpSirBssDescription pBssDesc = NULL; + tANI_U32 ie_len = 0; + tANI_U32 outIeLen = 0; + tANI_U8 bssCounter = 0; + tCsrScanResultInfo *pCurResult = NULL; + tANI_U8 msgCounter = 0; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tCsrRoamInfo roamInfo; + tSirEseBcnReportRsp bcnReport; + tpSirEseBcnReportRsp pBcnReport = &bcnReport; + tpCsrEseBeaconReqParams pCurMeasReqIe = NULL; + tANI_U8 i = 0; + + if (NULL == pSmeRrmContext) + { + smsLog( pMac, LOGE, "pSmeRrmContext is NULL"); + return eHAL_STATUS_FAILURE; + } + + if (NULL == pResultArr && !measurementDone) + { + smsLog( pMac, LOGE, "Beacon report xmit Ind to HDD Failed"); + return eHAL_STATUS_FAILURE; + } + + if (pResultArr) + pCurResult=pResultArr[bssCounter]; + + vos_mem_zero(&bcnReport, sizeof(tSirEseBcnReportRsp)); + do + { + pCurMeasReqIe = NULL; + for (i = 0; i < pSmeRrmContext->eseBcnReqInfo.numBcnReqIe; i++) + { + if(pSmeRrmContext->eseBcnReqInfo.bcnReq[i].channel == channel) + { + pCurMeasReqIe = &pSmeRrmContext->eseBcnReqInfo.bcnReq[i]; + break; + } + } + if(NULL != pCurMeasReqIe) + pBcnReport->measurementToken = pCurMeasReqIe->measurementToken; + smsLog( pMac, LOG1, "Channel(%d) MeasToken(%d)", channel, pBcnReport->measurementToken); + + msgCounter=0; + while (pCurResult) + { + pBssDesc = &pCurResult->BssDescriptor; + if (NULL != pBssDesc) + { + ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length ); + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.ChanNum = pBssDesc->channelId; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.Spare = 0; + if(NULL != pCurMeasReqIe) + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.MeasDuration = pCurMeasReqIe->measurementDuration; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.PhyType = pBssDesc->nwType; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.RecvSigPower = pBssDesc->rssi; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.ParentTsf = pBssDesc->parentTSF; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.TargetTsf[0] = pBssDesc->timeStamp[0]; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.TargetTsf[1] = pBssDesc->timeStamp[1]; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.BcnInterval = pBssDesc->beaconInterval; + pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.CapabilityInfo = pBssDesc->capabilityInfo; + vos_mem_copy(pBcnReport->bcnRepBssInfo[msgCounter].bcnReportFields.Bssid, + pBssDesc->bssId, sizeof(tSirMacAddr)); + + fillIeStatus = sirFillBeaconMandatoryIEforEseBcnReport(pMac, + (tANI_U8 *)pBssDesc->ieFields, + ie_len, + &(pBcnReport->bcnRepBssInfo[msgCounter].pBuf), + &outIeLen); + if (eSIR_FAILURE == fillIeStatus) + { + continue; + } + pBcnReport->bcnRepBssInfo[msgCounter].ieLen = outIeLen; + + smsLog( pMac, LOG1,"Bssid("MAC_ADDRESS_STR") Channel=%d Rssi=%d", + MAC_ADDR_ARRAY(pBssDesc->bssId), + pBssDesc->channelId, (-1) * pBssDesc->rssi); + + pBcnReport->numBss++; + + if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC) + break; + + pCurResult = pResultArr[msgCounter]; + } + else + { + pCurResult = NULL; + break; + } + } + + bssCounter += msgCounter; + if (!pResultArr || !pCurResult || (bssCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)) + { + pCurResult = NULL; + smsLog(pMac, LOGE, + "Reached to the max/last BSS in pCurResult list"); + } + else + { + pCurResult = pResultArr[bssCounter]; + smsLog(pMac, LOGE, + "Move to the next BSS set in pCurResult list"); + } + + pBcnReport->flag = (measurementDone << 1)|((pCurResult)?true:false); + + smsLog(pMac, LOG1, "SME Sending BcnRep to HDD numBss(%d)" + " msgCounter(%d) bssCounter(%d) flag(%d)", + pBcnReport->numBss, msgCounter, bssCounter, pBcnReport->flag); + + roamInfo.pEseBcnReportRsp = pBcnReport; + status = csrRoamCallCallback(pMac, sessionId, &roamInfo, + 0, eCSR_ROAM_ESE_BCN_REPORT_IND, 0); + + /* Free the memory allocated to IE */ + for (i = 0; i < msgCounter; i++) + { + if (pBcnReport->bcnRepBssInfo[i].pBuf) + vos_mem_free(pBcnReport->bcnRepBssInfo[i].pBuf); + } + } while (pCurResult); + return status; +} + +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +/**--------------------------------------------------------------------------- + + \brief sme_RrmSendScanRequest() - + + This function is called to get the scan result from CSR and send the beacon report + xmit ind message to PE. + + \param - pMac - Pointer to the Hal Handle. + - num_chan - number of channels. + - channel list - list of channels to fetch the result from. + - measurementDone - flag to indicate that the measurement is done. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ +static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, + tANI_U8 num_chan, + tANI_U8* chanList, + tANI_U8 measurementDone ) +{ + tCsrScanResultFilter filter; + tScanResultHandle pResult; + tCsrScanResultInfo *pScanResult, *pNextResult; + tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_DESC]; + eHalStatus status; + tANI_U8 counter=0; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 sessionId; + tCsrRoamInfo *roam_info; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Send scan result to PE "); +#endif + + vos_mem_zero( &filter, sizeof(filter) ); + vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_DESC ); + + filter.BSSIDs.numOfBSSIDs = 1; + filter.BSSIDs.bssid = &pSmeRrmContext->bssId; + + if( pSmeRrmContext->ssId.length ) + { + filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if( filter.SSIDs.SSIDList == NULL ) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") ); + return eHAL_STATUS_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for SSIDList")); +#endif + vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) ); + + filter.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length; + vos_mem_copy(filter.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length); + filter.SSIDs.numOfSSIDs = 1; + } + else + { + filter.SSIDs.numOfSSIDs = 0; + } + + filter.ChannelInfo.numOfChannels = num_chan; + filter.ChannelInfo.ChannelList = chanList; + + filter.fMeasurement = TRUE; + + csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId ); + status = sme_ScanGetResult(pMac, (tANI_U8)sessionId, &filter, &pResult); + + if( filter.SSIDs.SSIDList ) + { + //Free the memory allocated for SSIDList. + vos_mem_free( filter.SSIDs.SSIDList ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Free memory for SSIDList") ); +#endif + } + + smsLog(pMac, LOG1, FL("RRM Measurement Done %d"), measurementDone); + + if (NULL == pResult) + { + // no scan results + // + // Spec. doesnt say anything about such condition. + // Since section 7.4.6.2 (IEEE802.11k-2008) says-rrm report frame should contain + // one or more report IEs. It probably means dont send any respose if no matching + // BSS found. Moreover, there is no flag or field in measurement report IE(7.3.2.22) + // OR beacon report IE(7.3.2.22.6) that can be set to indicate no BSS found on a given channel. + // + // If we finished measurement on all the channels, we still need to + // send a xmit indication with moreToFollow set to MEASURMENT_DONE + // so that PE can clean any context allocated. + if( measurementDone ) + { +#if defined(FEATURE_WLAN_ESE_UPLOAD) + if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource) + { + status = sme_EseSendBeaconReqScanResults(pMac, + sessionId, + chanList[0], + NULL, + measurementDone, + 0); + } + else +#endif /*FEATURE_WLAN_ESE_UPLOAD*/ + status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0); + } + return status; + } + + pScanResult = sme_ScanResultGetFirst(pMac, pResult); + + if( NULL == pScanResult && measurementDone ) + { +#if defined(FEATURE_WLAN_ESE_UPLOAD) + if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource) + { + status = sme_EseSendBeaconReqScanResults(pMac, + sessionId, + chanList[0], + NULL, + measurementDone, + 0); + } + else +#endif /*FEATURE_WLAN_ESE_UPLOAD*/ + status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone, 0 ); + } + + counter=0; + while (pScanResult) + { + pNextResult = sme_ScanResultGetNext(pMac, pResult); + smsLog(pMac, LOG1, "Scan res timer:%lu, rrm scan timer:%lu", + pScanResult->timer, RRM_scan_timer); + if (pScanResult->timer >= RRM_scan_timer) { + roam_info = vos_mem_malloc(sizeof(*roam_info)); + if (NULL == roam_info) { + smsLog(pMac, LOGW, FL("vos_mem_malloc failed:")); + status = eHAL_STATUS_FAILED_ALLOC; + goto rrm_send_scan_results_done; + } + vos_mem_zero(roam_info, sizeof(*roam_info)); + roam_info->pBssDesc = &pScanResult->BssDescriptor; + csrRoamCallCallback(pMac, sessionId, roam_info, 0, + eCSR_ROAM_UPDATE_SCAN_RESULT, eCSR_ROAM_RESULT_NONE); + vos_mem_free(roam_info); + pScanResultsArr[counter++] = pScanResult; + } + pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult); + if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC) + break; + } + + smsLog(pMac, LOG1, " Number of BSS Desc with RRM Scan %d ", counter); + /* + * The beacon report should be sent whether the counter is zero or non-zero. + * There might be a few scan results in the cache but not actually are a + * result of this scan. During that scenario, the counter will be zero. + * The report should be sent and LIM will further cleanup the RRM to + * accept the further incoming requests + * In case the counter is Zero, the pScanResultsArr will be NULL. + * The next level routine does a check for the measurementDone to determine + * whether to send a report or not. + */ + + if (counter || measurementDone) { +#if defined(FEATURE_WLAN_ESE_UPLOAD) + if (eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource) + { + status = sme_EseSendBeaconReqScanResults(pMac, + sessionId, + chanList[0], + pScanResultsArr, + measurementDone, + counter); + } + else +#endif /*FEATURE_WLAN_ESE_UPLOAD*/ + status = sme_RrmSendBeaconReportXmitInd( pMac, + pScanResultsArr, + measurementDone, + counter); + } + +rrm_send_scan_results_done: + sme_ScanResultPurge(pMac, pResult); + + return status; +} +/**--------------------------------------------------------------------------- + + \brief sme_RrmScanRequestCallback() - + + The sme module calls this callback function once it finish the scan request + and this function send the beacon report xmit to PE and starts a timer of + random interval to issue next request. + + \param - halHandle - Pointer to the Hal Handle. + - pContext - Pointer to the data context. + - scanId - Scan ID. + - status - CSR Status. + \return - 0 for success, non zero for failure + + --------------------------------------------------------------------------*/ + +static eHalStatus sme_RrmScanRequestCallback(tHalHandle halHandle, void *pContext, + tANI_U32 scanId, eCsrScanStatus status) +{ + + tANI_U16 interval; + tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 time_tick; + + + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Scan Request callback "); +#endif + //if any more channels are pending, start a timer of a random value within randomization interval. + // + // + if( (pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels ) + { + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false ); + + pSmeRrmContext->currentIndex++; //Advance the current index. + //start the timer to issue next request. + //From timer tick get a random number within 10ms and max randmization interval. + time_tick = vos_timer_get_system_ticks(); + interval = time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Set timer for interval %d ", interval); +#endif + vos_timer_start( &pSmeRrmContext->IterMeasTimer, interval ); + + } + else + { + //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set. + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true ); + vos_mem_free( pSmeRrmContext->channelList.ChannelList ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Free memory for ChannelList") ); +#endif + } + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmIssueScanReq() - This is called to send a scan request as part + of beacon report request . + + \param pMac - pMac global pointer + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmIssueScanReq( tpAniSirGlobal pMac ) +{ + //Issue scan request. + tCsrScanRequest scanRequest; + v_U32_t scanId = 0; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 sessionId; + tSirScanType scanType; + + if ((pSmeRrmContext->currentIndex) >= pSmeRrmContext->channelList.numOfChannels) + return status; + + if( eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource || + eRRM_MSG_SOURCE_LEGACY_ESE == pSmeRrmContext->msgSource ) + scanType = pSmeRrmContext->measMode[pSmeRrmContext->currentIndex]; + else + scanType = pSmeRrmContext->measMode[0]; + + if ((eSIR_ACTIVE_SCAN == scanType) || (eSIR_PASSIVE_SCAN == scanType)) + { +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Issue scan request " ); +#endif + + vos_mem_zero( &scanRequest, sizeof(scanRequest)); + + /* set scanType, active or passive */ + scanRequest.scanType = scanType; + + vos_mem_copy(scanRequest.bssid, + pSmeRrmContext->bssId, sizeof(scanRequest.bssid) ); + + if (pSmeRrmContext->ssId.length) + { + scanRequest.SSIDs.numOfSSIDs = 1; + scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo)); + if (NULL == scanRequest.SSIDs.SSIDList) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") ); + return eHAL_STATUS_FAILURE; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for pSSIDList")); +#endif + vos_mem_zero( scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) ); + scanRequest.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length; + vos_mem_copy(scanRequest.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length); + } + + /* set min and max channel time */ + scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout. + if( eRRM_MSG_SOURCE_ESE_UPLOAD == pSmeRrmContext->msgSource || + eRRM_MSG_SOURCE_LEGACY_ESE == pSmeRrmContext->msgSource ) + scanRequest.maxChnTime = pSmeRrmContext->duration[pSmeRrmContext->currentIndex]; + else + scanRequest.maxChnTime = pSmeRrmContext->duration[0]; + + smsLog( pMac, LOG1, "Scan Type(%s (%d)) Max Dwell Time(%d)", + lim_ScanTypetoString(scanRequest.scanType), + scanRequest.scanType, + scanRequest.maxChnTime ); + + RRM_scan_timer = vos_timer_get_system_time(); + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "For Duration %d ", scanRequest.maxChnTime ); +#endif + + /* set BSSType to default type */ + scanRequest.BSSType = eCSR_BSS_TYPE_ANY; + + /*Scan all the channels */ + scanRequest.ChannelInfo.numOfChannels = 1; + + scanRequest.ChannelInfo.ChannelList = &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex]; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "On channel %d ", pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex] ); +#endif + + /* set requestType to full scan */ + scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN; + + csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId ); + status = sme_ScanRequest( pMac, (tANI_U8)sessionId, &scanRequest, &scanId, &sme_RrmScanRequestCallback, NULL ); + + if ( pSmeRrmContext->ssId.length ) + { + vos_mem_free(scanRequest.SSIDs.SSIDList); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Free memory for SSIDList")); +#endif + } + } + else if (2 == scanType) /* beacon table */ + { + /*In beacon table mode, scan results are taken directly from scan cache + without issuing any scan request. So, it is not proper to update + RRM_scan_timer with latest time and hence made it to zero to satisfy + pScanResult->timer >= RRM_scan_timer */ + RRM_scan_timer = 0; + if ((pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels) + { + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false ); + pSmeRrmContext->currentIndex++; //Advance the current index. + sme_RrmIssueScanReq(pMac); + } + else + { + //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set. + sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true ); + vos_mem_free( pSmeRrmContext->channelList.ChannelList ); + } + } + else + { + smsLog( pMac, LOGE, "Unknown beacon report request mode(%s (%d))", + lim_ScanTypetoString(scanType), scanType); + /* Indicate measurement completion to PE */ + /* If this is not done, pCurrentReq pointer will not be freed and + PE will not handle subsequent Beacon requests */ + sme_RrmSendBeaconReportXmitInd(pMac, NULL, true, 0); + } + + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmProcessBeaconReportReqInd() - This is called to process the Beacon + report request from peer AP forwarded through PE . + + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +void sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tANI_U32 len = 0, i = 0; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Received Beacon report request ind Channel = %d", pBeaconReq->channelInfo.channelNum ); +#endif + //section 11.10.8.1 (IEEE Std 802.11k-2008) + //channel 0 and 255 has special meaning. + if( (pBeaconReq->channelInfo.channelNum == 0) || + ((pBeaconReq->channelInfo.channelNum == 255) && (pBeaconReq->channelList.numChannels == 0) ) ) + { + //Add all the channel in the regulatory domain. + wlan_cfgGetStrLen( pMac, WNI_CFG_VALID_CHANNEL_LIST, &len ); + pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len ); + if( pSmeRrmContext->channelList.ChannelList == NULL ) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") ); + return; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") ); +#endif + csrGetCfgValidChannels( pMac, pSmeRrmContext->channelList.ChannelList, &len ); + pSmeRrmContext->channelList.numOfChannels = (tANI_U8)len; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "channel == 0 performing on all channels"); +#endif + } + else + { + len = 0; + pSmeRrmContext->channelList.numOfChannels = 0; + + //If valid channel is present. We first Measure on the given channel. and + //if there are additional channels present in APchannelreport, measure on these also. + if ( pBeaconReq->channelInfo.channelNum != 255 ) + len = 1; +#if defined WLAN_VOWIFI_DEBUG + else + smsLog( pMac, LOGE, "channel == 255"); +#endif + + len += pBeaconReq->channelList.numChannels; + + pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len ); + if( pSmeRrmContext->channelList.ChannelList == NULL ) + { + smsLog( pMac, LOGP, FL("vos_mem_malloc failed") ); + return; + } +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Allocated memory for ChannelList") ); +#endif + + if ( pBeaconReq->channelInfo.channelNum != 255 ) + { +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "channel == %d ", pBeaconReq->channelInfo.channelNum ); +#endif + if(csrRoamIsChannelValid( pMac, pBeaconReq->channelInfo.channelNum )) + pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels++] = pBeaconReq->channelInfo.channelNum; +#if defined WLAN_VOWIFI_DEBUG + else + smsLog( pMac, LOGE, "is Invalid channel, Ignoring this channel" ); +#endif + } + + for ( i = 0 ; i < pBeaconReq->channelList.numChannels; i++ ) + { + if(csrRoamIsChannelValid( pMac, pBeaconReq->channelList.channelNumber[i] )) + { + pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels] = pBeaconReq->channelList.channelNumber[i]; + pSmeRrmContext->channelList.numOfChannels++; + } + } + } + + //Copy session bssid + vos_mem_copy( pSmeRrmContext->sessionBssId, pBeaconReq->bssId, sizeof(tSirMacAddr) ); + + //copy measurement bssid + vos_mem_copy( pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, sizeof(tSirMacAddr) ); + + //Copy ssid + vos_mem_copy( &pSmeRrmContext->ssId, &pBeaconReq->ssId, sizeof(tAniSSID) ); + + pSmeRrmContext->token = pBeaconReq->uDialogToken; + pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass; + pSmeRrmContext->randnIntvl = VOS_MAX( pBeaconReq->randomizationInterval, pSmeRrmContext->rrmConfig.maxRandnInterval ); + pSmeRrmContext->currentIndex = 0; + pSmeRrmContext->msgSource = pBeaconReq->msgSource; + vos_mem_copy((tANI_U8*)&pSmeRrmContext->measMode, (tANI_U8*)&pBeaconReq->fMeasurementtype, SIR_ESE_MAX_MEAS_IE_REQS); + vos_mem_copy((tANI_U8*)&pSmeRrmContext->duration, (tANI_U8*)&pBeaconReq->measurementDuration, SIR_ESE_MAX_MEAS_IE_REQS); + + sme_RrmIssueScanReq( pMac ); + + return; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmNeighborReportRequest() - This is API can be used to trigger a + Neighbor report from the peer. + + \param sessionId - session identifier on which the request should be made. + \param pNeighborReq - a pointer to a neighbor report request. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId, + tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirNeighborReportReqInd pMsg; + tCsrRoamSession *pSession; + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Request to send Neighbor report request received ")); +#endif + if( !CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + smsLog( pMac, LOGE, FL("Invalid session %d"), sessionId ); + return VOS_STATUS_E_INVAL; + } + pSession = CSR_GET_SESSION( pMac, sessionId ); + + /* If already a report is pending, return failure */ + if (eANI_BOOLEAN_TRUE == pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending) + { + smsLog( pMac, LOGE, FL("Neighbor request already pending.. Not allowed")); + return VOS_STATUS_E_AGAIN; + } + + pMsg = vos_mem_malloc ( sizeof(tSirNeighborReportReqInd) ); + if ( NULL == pMsg ) + { + smsLog( pMac, LOGE, "Unable to allocate memory for Neighbor request"); + return VOS_STATUS_E_NOMEM; + } + + + vos_mem_zero( pMsg, sizeof(tSirNeighborReportReqInd) ); +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL(" Allocated memory for Neighbor request") ); +#endif + + rrmLLPurgeNeighborCache(pMac, &pMac->rrm.rrmSmeContext.neighborReportCache); + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, FL("Purged the neighbor cache before sending Neighbor request: Status = %d"), status ); +#endif + + pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND; + pMsg->length = sizeof( tSirNeighborReportReqInd ); + vos_mem_copy( &pMsg->bssId, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) ); + pMsg->noSSID = pNeighborReq->no_ssid; + vos_mem_copy( &pMsg->ucSSID, &pNeighborReq->ssid, sizeof(tSirMacSSid)); + + status = palSendMBMessage(pMac->hHdd, pMsg); + if( status != eHAL_STATUS_SUCCESS ) + return VOS_STATUS_E_FAILURE; + + /* Neighbor report request message sent successfully to PE. Now register the callbacks */ + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = + callbackInfo->neighborRspCallback; + pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = + callbackInfo->neighborRspCallbackContext; + pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_TRUE; + + /* Start neighbor response wait timer now */ + vos_timer_start(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer, callbackInfo->timeout); + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief rrmCalculateNeighborAPRoamScore() - This API is called while handling + individual neighbor reports from the APs neighbor AP report to + calculate the cumulative roam score before storing it in neighbor + cache. + + \param pNeighborReportDesc - Neighbor BSS Descriptor node for which roam score + should be calculated + + \return void. +--------------------------------------------------------------------------*/ +static void rrmCalculateNeighborAPRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc) +{ + tpSirNeighborBssDescripton pNeighborBssDesc; + tANI_U32 roamScore = 0; + + if (NULL == pNeighborReportDesc) + { + VOS_ASSERT(0); + return; + } + if (NULL == pNeighborReportDesc->pNeighborBssDescription) + { + VOS_ASSERT(0); + return; + } + + pNeighborBssDesc = pNeighborReportDesc->pNeighborBssDescription; + + if (pNeighborBssDesc->bssidInfo.rrmInfo.fMobilityDomain) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameSecurityMode) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameAuthenticator) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapRadioMeasurement) + { + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapSpectrumMeasurement) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapQos) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapApsd) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapDelayedBlockAck) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapImmediateBlockAck) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA; + if (pNeighborBssDesc->bssidInfo.rrmInfo.fApPreauthReachable) + roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY; + } + } + } + } +#ifdef FEATURE_WLAN_ESE + // It has come in the report so its the best score + if (csrNeighborRoamIs11rAssoc(pMac) == FALSE) + { + // IAPP Route so lets make use of this info + // save all AP, as the list does not come all the time + // Save and reuse till the next AP List comes to us. + // Even save our own MAC address. Will be useful next time around. + roamScore += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST; + } +#endif + pNeighborReportDesc->roamScore = roamScore; + + return; +} + +/*-------------------------------------------------------------------------- + \brief rrmStoreNeighborRptByRoamScore() - This API is called to store a given + Neighbor BSS descriptor to the neighbor cache. This function + stores the neighbor BSS descriptors in such a way that descriptors + are sorted by roamScore in descending order + + \param pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache + + \return void. +--------------------------------------------------------------------------*/ +void rrmStoreNeighborRptByRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc) +{ + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + tListElem *pEntry; + tRrmNeighborReportDesc *pTempNeighborReportDesc; + + if (NULL == pNeighborReportDesc) + { + VOS_ASSERT(0); + return; + } + if (NULL == pNeighborReportDesc->pNeighborBssDescription) + { + VOS_ASSERT(0); + return; + } + + if (csrLLIsListEmpty(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK)) + { + smsLog(pMac, LOGE, FL("Neighbor report cache is empty.. Adding a entry now")); + /* Neighbor list cache is empty. Insert this entry in the tail */ + csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK); + return; + } + else + { + /* Should store the neighbor BSS description in the order sorted by roamScore in descending + order. APs with highest roamScore should be the 1st entry in the list */ + pEntry = csrLLPeekHead(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK); + while (pEntry != NULL) + { + pTempNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + if (pTempNeighborReportDesc->roamScore < pNeighborReportDesc->roamScore) + break; + pEntry = csrLLNext(&pSmeRrmContext->neighborReportCache, pEntry, LL_ACCESS_LOCK); + } + + if (pEntry) + /* This BSS roamscore is better than something in the list. Insert this before that one */ + csrLLInsertEntry(&pSmeRrmContext->neighborReportCache, pEntry, &pNeighborReportDesc->List, LL_ACCESS_LOCK); + else + /* All the entries in the list has a better roam Score than this one. Insert this at the last */ + csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK); + } + return; +} + +/*-------------------------------------------------------------------------- + \brief sme_RrmProcessNeighborReport() - This is called to process the Neighbor + report received from PE. + + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmProcessNeighborReport(tpAniSirGlobal pMac, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf; + tpRrmNeighborReportDesc pNeighborReportDesc; + tANI_U8 i = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + +#ifdef FEATURE_WLAN_ESE + // Clear the cache for ESE. + if (csrNeighborRoamIsESEAssoc(pMac)) + { + rrmLLPurgeNeighborCache(pMac, + &pMac->rrm.rrmSmeContext.neighborReportCache); + } +#endif + + for (i = 0; i < pNeighborRpt->numNeighborReports; i++) + { + pNeighborReportDesc = vos_mem_malloc(sizeof(tRrmNeighborReportDesc)); + if (NULL == pNeighborReportDesc) + { + smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report desc"); + status = eHAL_STATUS_FAILED_ALLOC; + goto end; + + } + + vos_mem_zero(pNeighborReportDesc, sizeof(tRrmNeighborReportDesc)); + pNeighborReportDesc->pNeighborBssDescription = vos_mem_malloc(sizeof(tSirNeighborBssDescription)); + if (NULL == pNeighborReportDesc->pNeighborBssDescription) + { + smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report BSS Description"); + vos_mem_free(pNeighborReportDesc); + status = eHAL_STATUS_FAILED_ALLOC; + goto end; + } + vos_mem_zero(pNeighborReportDesc->pNeighborBssDescription, sizeof(tSirNeighborBssDescription)); + vos_mem_copy(pNeighborReportDesc->pNeighborBssDescription, &pNeighborRpt->sNeighborBssDescription[i], + sizeof(tSirNeighborBssDescription)); + +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Received neighbor report with Neighbor BSSID: "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pNeighborRpt->sNeighborBssDescription[i].bssId)); +#endif + + /* Calculate the roam score based on the BSS Capability in the BSSID Information and store it in Neighbor report Desc */ + rrmCalculateNeighborAPRoamScore(pMac, pNeighborReportDesc); + + /* Store the Neighbor report Desc in the cache based on the roam score */ + if ( pNeighborReportDesc->roamScore > 0) + { + rrmStoreNeighborRptByRoamScore(pMac, pNeighborReportDesc); + } + else + { + smsLog(pMac, LOGE, FL("Roam score of BSSID "MAC_ADDRESS_STR" is 0, Ignoring.."), + MAC_ADDR_ARRAY(pNeighborRpt->sNeighborBssDescription[i].bssId)); + + vos_mem_free(pNeighborReportDesc->pNeighborBssDescription); + vos_mem_free(pNeighborReportDesc); + } + } +end: + + if (!csrLLCount(&pMac->rrm.rrmSmeContext.neighborReportCache)) + vosStatus = VOS_STATUS_E_FAILURE; + + /* Received a report from AP. Indicate SUCCESS to the caller if there are some valid reports */ + rrmIndicateNeighborReportResult(pMac, vosStatus); + + return status; +} +/*-------------------------------------------------------------------------- + \brief sme_RrmMsgProcessor() - sme_ProcessMsg() calls this function for the + messages that are handled by SME RRM module. + + \param pMac - Pointer to the global MAC parameter structure. + \param msg_type - the type of msg passed by PE as defined in wniApi.h + \param pMsgBuf - a pointer to a buffer that maps to various structures base + on the message type. + The beginning of the buffer can always map to tSirSmeRsp. + + \return eHAL_STATUS_SUCCESS - Validation is successful. + + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type, + void *pMsgBuf) +{ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, + FL(" Msg = %d for RRM measurement") , msg_type ); + + //switch on the msg type & make the state transition accordingly + switch(msg_type) + { + case eWNI_SME_NEIGHBOR_REPORT_IND: + sme_RrmProcessNeighborReport( pMac, pMsgBuf ); + break; + + case eWNI_SME_BEACON_REPORT_REQ_IND: + sme_RrmProcessBeaconReportReqInd( pMac, pMsgBuf ); + break; + + default: + //err msg + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("sme_RrmMsgProcessor:unknown msg type = %d"), msg_type); + + break; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn rrmIterMeasTimerHandle + + \brief Timer handler to handlet the timeout condition when a specific BT + + stop event does not come back, in which case to restore back the + + heartbeat timer. + + \param pMac - The handle returned by macOpen. + + \return VOID + + ---------------------------------------------------------------------------*/ + +void rrmIterMeasTimerHandle( v_PVOID_t userData ) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) userData; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Randomization timer expired...send on next channel "); +#endif + //Issue a scan req for next channel. + sme_RrmIssueScanReq( pMac ); +} + +/* --------------------------------------------------------------------------- + + \fn rrmNeighborRspTimeoutHandler + + \brief Timer handler to handle the timeout condition when a neighbor request is sent + and no neighbor response is received from the AP + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ + +void rrmNeighborRspTimeoutHandler +( v_PVOID_t userData ) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal) userData; +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Neighbor Response timed out "); +#endif + rrmIndicateNeighborReportResult(pMac, VOS_STATUS_E_FAILURE); + return; +} + +/* --------------------------------------------------------------------------- + + \fn rrmOpen + + \brief + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS + + VOS_STATUS_E_FAILURE success + + VOS_STATUS_SUCCESS failure + + ---------------------------------------------------------------------------*/ + +VOS_STATUS rrmOpen (tpAniSirGlobal pMac) + +{ + + VOS_STATUS vosStatus; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + pSmeRrmContext->rrmConfig.maxRandnInterval = 50; //ms + + vosStatus = vos_timer_init( &pSmeRrmContext->IterMeasTimer, + + VOS_TIMER_TYPE_SW, + + rrmIterMeasTimerHandle, + + (void*) pMac); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer"); + + return VOS_STATUS_E_FAILURE; + } + + vosStatus = vos_timer_init( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer, + + VOS_TIMER_TYPE_SW, + + rrmNeighborRspTimeoutHandler, + + (void*) pMac); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer"); + + return VOS_STATUS_E_FAILURE; + } + + pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE; + + halStatus = csrLLOpen(pMac->hHdd, &pSmeRrmContext->neighborReportCache); + if (eHAL_STATUS_SUCCESS != halStatus) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to open neighbor cache result"); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + + +/* --------------------------------------------------------------------------- + + \fn rrmClose + + \brief + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS + + VOS_STATUS_E_FAILURE success + + VOS_STATUS_SUCCESS failure + + ---------------------------------------------------------------------------*/ + +VOS_STATUS rrmClose (tpAniSirGlobal pMac) + +{ + + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + if( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( &pSmeRrmContext->IterMeasTimer ) ) + { + vosStatus = vos_timer_stop( &pSmeRrmContext->IterMeasTimer ); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Timer stop fail") ); + } + } + + vosStatus = vos_timer_destroy( &pSmeRrmContext->IterMeasTimer ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Fail to destroy timer") ); + + } + + if( VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ) ) + { + vosStatus = vos_timer_stop( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Timer stop fail") ); + } + } + + vosStatus = vos_timer_destroy( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Fail to destroy timer") ); + + } + + rrmLLPurgeNeighborCache(pMac, &pSmeRrmContext->neighborReportCache); + + csrLLClose(&pSmeRrmContext->neighborReportCache); + + return vosStatus; + +} + + + + +/* --------------------------------------------------------------------------- + + \fn rrmReady + + \brief fn + + \param pMac - The handle returned by macOpen. + + \return VOS_STATUS + + ---------------------------------------------------------------------------*/ + +VOS_STATUS rrmReady (tpAniSirGlobal pMac) + +{ + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn rrmChangeDefaultConfigParam + \brief fn + + \param pMac - The handle returned by macOpen. + \param pRrmConfig - pointer to new rrm configs. + + \return VOS_STATUS + + ---------------------------------------------------------------------------*/ +VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig) +{ + vos_mem_copy( &pMac->rrm.rrmSmeContext.rrmConfig, pRrmConfig, sizeof( tRrmConfigParam ) ); + + return VOS_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn smeRrmGetFirstBssEntryFromNeighborCache() + + \brief This function returns the first entry from the neighbor cache to the caller + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tRrmNeighborReportDesc *pTempBssEntry = NULL; + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + + pEntry = csrLLPeekHead( &pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK ); + + if(!pEntry || !csrLLCount(&pSmeRrmContext->neighborReportCache)) + { + //list empty + smsLog(pMac, LOGW, FL("List empty")); + return NULL; + } + + pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + + return pTempBssEntry; +} + +/* --------------------------------------------------------------------------- + + \fn smeRrmGetNextBssEntryFromNeighborCache() + + \brief This function returns the entry next to the given entry from the + neighbor cache to the caller + + \param pMac - The handle returned by macOpen. + + \return VOID + +---------------------------------------------------------------------------*/ +tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac, + tpRrmNeighborReportDesc pBssEntry) +{ + tListElem *pEntry; + tRrmNeighborReportDesc *pTempBssEntry = NULL; + + pEntry = csrLLNext(&pMac->rrm.rrmSmeContext.neighborReportCache, &pBssEntry->List, LL_ACCESS_LOCK); + + if(!pEntry) + { + //list empty + smsLog(pMac, LOGW, FL("List empty")); + return NULL; + } + + pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List ); + + return pTempBssEntry; +} + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) +void csrEseSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession) +{ + tpSirAdjacentApRepInd pAdjRep; + tANI_U16 length; + tANI_U32 roamTS2; + + smsLog( pMac, LOG1, "Adjacent AP Report Msg to PE"); + + length = sizeof(tSirAdjacentApRepInd ); + pAdjRep = vos_mem_malloc ( length ); + + if ( NULL == pAdjRep ) + { + smsLog( pMac, LOGP, "Unable to allocate memory for Adjacent AP report"); + return; + } + + vos_mem_zero( pAdjRep, length ); + pAdjRep->messageType = eWNI_SME_ESE_ADJACENT_AP_REPORT; + pAdjRep->length = length; + pAdjRep->channelNum = pSession->prevOpChannel; + vos_mem_copy( pAdjRep->bssid, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) ); + vos_mem_copy( pAdjRep->prevApMacAddr, &pSession->prevApBssid, sizeof(tSirMacAddr) ); + vos_mem_copy( &pAdjRep->prevApSSID, &pSession->prevApSSID, sizeof(tSirMacSSid) ); + roamTS2 = vos_timer_get_system_time(); + pAdjRep->tsmRoamdelay = roamTS2 - pSession->roamTS1; + pAdjRep->roamReason =SIR_ESE_ASSOC_REASON_UNSPECIFIED; + pAdjRep->clientDissSecs =(pAdjRep->tsmRoamdelay/1000); + + palSendMBMessage(pMac->hHdd, pAdjRep); + + return; +} +#endif /* FEATURE_WLAN_ESE */ +#endif diff --git a/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c b/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c new file mode 100644 index 000000000000..5ca51dc7cea0 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/sme_common/sme_Api.c @@ -0,0 +1,15092 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/**========================================================================= + + \file smeApi.c + + \brief Definitions for SME APIs + + + ========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + + when who what, where, why +---------- --- -------------------------------------------------------- +06/03/10 js Added support to hostapd driven + * deauth/disassoc/mic failure + +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + + +#include "smsDebug.h" +#include "sme_Api.h" +#include "csrInsideApi.h" +#include "smeInside.h" +#include "csrInternal.h" +#include "wlan_qct_wda.h" +#include "halMsgApi.h" +#include "vos_trace.h" +#include "sme_Trace.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "sapApi.h" +#include "macTrace.h" +#include "vos_utils.h" +#include "limSession.h" + +extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); + +#include +#define LOG_SIZE 256 +#define READ_MEMORY_DUMP_CMD 9 +#define TL_INIT_STATE 0 + + +#define CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE 1000*30 //30s + +// TxMB Functions +extern eHalStatus pmcPrepareCommand( tpAniSirGlobal pMac, eSmeCommandType cmdType, void *pvParam, + tANI_U32 size, tSmeCmd **ppCmd ); +extern void pmcReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +extern void qosReleaseCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand ); +extern void csrReleaseRocReqCommand( tpAniSirGlobal pMac); +extern eHalStatus p2pProcessRemainOnChannelCmd(tpAniSirGlobal pMac, tSmeCmd *p2pRemainonChn); +extern eHalStatus sme_remainOnChnRsp( tpAniSirGlobal pMac, tANI_U8 *pMsg); +extern eHalStatus sme_remainOnChnReady( tHalHandle hHal, tANI_U8* pMsg); +extern eHalStatus sme_sendActionCnf( tHalHandle hHal, tANI_U8* pMsg); +extern eHalStatus p2pProcessNoAReq(tpAniSirGlobal pMac, tSmeCmd *pNoACmd); + +static eHalStatus initSmeCmdList(tpAniSirGlobal pMac); +static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ); + +eCsrPhyMode sme_GetPhyMode(tHalHandle hHal); + +eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf); + +void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac); + +eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf); + +eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal); + +eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal); + +#ifdef FEATURE_WLAN_LFR +tANI_BOOLEAN csrIsScanAllowed(tpAniSirGlobal pMac); +#endif + +#ifdef WLAN_FEATURE_11W +eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, + tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm ); +#endif + +//Internal SME APIs +eHalStatus sme_AcquireGlobalLock( tSmeStruct *psSme) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if(psSme) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_acquire( &psSme->lkSmeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + + return (status); +} + + +eHalStatus sme_ReleaseGlobalLock( tSmeStruct *psSme) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if(psSme) + { + if( VOS_IS_STATUS_SUCCESS( vos_lock_release( &psSme->lkSmeGlobalLock) ) ) + { + status = eHAL_STATUS_SUCCESS; + } + } + + return (status); +} + + + +static eHalStatus initSmeCmdList(tpAniSirGlobal pMac) +{ + eHalStatus status; + tSmeCmd *pCmd; + tANI_U32 cmd_idx; + VOS_STATUS vosStatus; + vos_timer_t* cmdTimeoutTimer = NULL; + + pMac->sme.totalSmeCmd = SME_TOTAL_COMMAND; + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeCmdActiveList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeCmdPendingList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeScanCmdActiveList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeScanCmdPendingList))) + goto end; + + if (!HAL_STATUS_SUCCESS(status = csrLLOpen(pMac->hHdd, + &pMac->sme.smeCmdFreeList))) + goto end; + + pCmd = (tSmeCmd *) vos_mem_vmalloc(sizeof(tSmeCmd) * pMac->sme.totalSmeCmd); + if ( NULL == pCmd ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("fail to allocate memory %lu"), + (unsigned long)(sizeof(tSmeCmd) * pMac->sme.totalSmeCmd)); + status = eHAL_STATUS_FAILURE; + } + else + { + status = eHAL_STATUS_SUCCESS; + + vos_mem_set(pCmd, sizeof(tSmeCmd) * pMac->sme.totalSmeCmd, 0); + pMac->sme.pSmeCmdBufAddr = pCmd; + + for (cmd_idx = 0; cmd_idx < pMac->sme.totalSmeCmd; cmd_idx++) + { + csrLLInsertTail(&pMac->sme.smeCmdFreeList, + &pCmd[cmd_idx].Link, LL_ACCESS_LOCK); + } + } + + /* This timer is only to debug the active list command timeout */ + + cmdTimeoutTimer = (vos_timer_t*)vos_mem_malloc(sizeof(vos_timer_t)); + if (cmdTimeoutTimer) + { + pMac->sme.smeCmdActiveList.cmdTimeoutTimer = cmdTimeoutTimer; + vosStatus = + vos_timer_init( pMac->sme.smeCmdActiveList.cmdTimeoutTimer, + VOS_TIMER_TYPE_SW, + activeListCmdTimeoutHandle, + (void*) pMac); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Init Timer fail for active list command process time out"); + vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); + } + else + { + pMac->sme.smeCmdActiveList.cmdTimeoutDuration = + CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE; + } + } +end: + if (!HAL_STATUS_SUCCESS(status)) + smsLog(pMac, LOGE, "failed to initialize sme command list:%d\n", + status); + + return (status); +} + + +void smeReleaseCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd) +{ + pCmd->command = eSmeNoCommand; + csrLLInsertTail(&pMac->sme.smeCmdFreeList, &pCmd->Link, LL_ACCESS_LOCK); +} + + + +static void smeReleaseCmdList(tpAniSirGlobal pMac, tDblLinkList *pList) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + + while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_LOCK)) != NULL) + { + //TODO: base on command type to call release functions + //reinitialize different command types so they can be reused + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + } +} + +static void purgeSmeCmdList(tpAniSirGlobal pMac) +{ + //release any out standing commands back to free command list + smeReleaseCmdList(pMac, &pMac->sme.smeCmdPendingList); + smeReleaseCmdList(pMac, &pMac->sme.smeCmdActiveList); + smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdPendingList); + smeReleaseCmdList(pMac, &pMac->sme.smeScanCmdActiveList); +} + +void purgeSmeSessionCmdList(tpAniSirGlobal pMac, tANI_U32 sessionId, + tDblLinkList *pList, bool flush_all) +{ + //release any out standing commands back to free command list + tListElem *pEntry, *pNext; + tSmeCmd *pCommand; + tDblLinkList localList; + + vos_mem_zero(&localList, sizeof(tDblLinkList)); + if(!HAL_STATUS_SUCCESS(csrLLOpen(pMac->hHdd, &localList))) + { + smsLog(pMac, LOGE, FL(" failed to open list")); + return; + } + + csrLLLock(pList); + pEntry = csrLLPeekHead(pList, LL_ACCESS_NOLOCK); + while(pEntry != NULL) + { + pNext = csrLLNext(pList, pEntry, LL_ACCESS_NOLOCK); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + if (!flush_all && + csr_is_disconnect_full_power_cmd(pCommand)) { + smsLog(pMac, LOGW, FL(" Ignore disconnect")); + pEntry = pNext; + continue; + } + if(pCommand->sessionId == sessionId) + { + if(csrLLRemoveEntry(pList, pEntry, LL_ACCESS_NOLOCK)) + { + csrLLInsertTail(&localList, pEntry, LL_ACCESS_NOLOCK); + } + } + pEntry = pNext; + } + csrLLUnlock(pList); + + while( (pEntry = csrLLRemoveHead(&localList, LL_ACCESS_NOLOCK)) ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeAbortCommand(pMac, pCommand, eANI_BOOLEAN_TRUE); + } + csrLLClose(&localList); +} + + +static eHalStatus freeSmeCmdList(tpAniSirGlobal pMac) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + + purgeSmeCmdList(pMac); + csrLLClose(&pMac->sme.smeCmdPendingList); + csrLLClose(&pMac->sme.smeCmdActiveList); + csrLLClose(&pMac->sme.smeScanCmdPendingList); + csrLLClose(&pMac->sme.smeScanCmdActiveList); + csrLLClose(&pMac->sme.smeCmdFreeList); + + /*destroy active list command time out timer */ + vos_timer_destroy(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); + vos_mem_free(pMac->sme.smeCmdActiveList.cmdTimeoutTimer); + pMac->sme.smeCmdActiveList.cmdTimeoutTimer = NULL; + + status = vos_lock_acquire(&pMac->sme.lkSmeGlobalLock); + if(status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Failed to acquire the lock status = %d"), status); + goto done; + } + + if(NULL != pMac->sme.pSmeCmdBufAddr) + { + vos_mem_vfree(pMac->sme.pSmeCmdBufAddr); + pMac->sme.pSmeCmdBufAddr = NULL; + } + + status = vos_lock_release(&pMac->sme.lkSmeGlobalLock); + if(status != eHAL_STATUS_SUCCESS) + { + smsLog(pMac, LOGE, + FL("Failed to release the lock status = %d"), status); + } +done: + return (status); +} + + +void dumpCsrCommandInfo(tpAniSirGlobal pMac, tSmeCmd *pCmd) +{ + switch( pCmd->command ) + { + case eSmeCommandScan: + smsLog( pMac, LOGE, " scan command reason is %d", pCmd->u.scanCmd.reason ); + break; + + case eSmeCommandRoam: + smsLog( pMac, LOGE, " roam command reason is %d", pCmd->u.roamCmd.roamReason ); + break; + + case eSmeCommandWmStatusChange: + smsLog( pMac, LOGE, " WMStatusChange command type is %d", pCmd->u.wmStatusChangeCmd.Type ); + break; + + case eSmeCommandSetKey: + smsLog( pMac, LOGE, " setKey command auth(%d) enc(%d)", + pCmd->u.setKeyCmd.authType, pCmd->u.setKeyCmd.encType ); + break; + + case eSmeCommandRemoveKey: + smsLog( pMac, LOGE, " removeKey command auth(%d) enc(%d)", + pCmd->u.removeKeyCmd.authType, pCmd->u.removeKeyCmd.encType ); + break; + + default: + smsLog( pMac, LOGE, " default: Unhandled command %d", + pCmd->command); + break; + } +} + +tSmeCmd *smeGetCommandBuffer( tpAniSirGlobal pMac ) +{ + tSmeCmd *pRetCmd = NULL, *pTempCmd = NULL; + tListElem *pEntry; + static int smeCommandQueueFull = 0; + pEntry = csrLLRemoveHead( &pMac->sme.smeCmdFreeList, LL_ACCESS_LOCK ); + + // If we can get another MS Msg buffer, then we are ok. Just link + // the entry onto the linked list. (We are using the linked list + // to keep track of tfhe message buffers). + if ( pEntry ) + { + pRetCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* reset when free list is available */ + smeCommandQueueFull = 0; + } + else + { + int idx = 1; + + //Cannot change pRetCmd here since it needs to return later. + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if( pEntry ) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + } + smsLog( pMac, LOGE, "Out of command buffer.... command (0x%X) stuck", + (pTempCmd) ? pTempCmd->command : eSmeNoCommand ); + if(pTempCmd) + { + if( eSmeCsrCommandMask & pTempCmd->command ) + { + //CSR command is stuck. See what the reason code is for that command + dumpCsrCommandInfo(pMac, pTempCmd); + } + } //if(pTempCmd) + + //dump what is in the pending queue + csrLLLock(&pMac->sme.smeCmdPendingList); + pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK ); + while(pEntry && !smeCommandQueueFull) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* Print only 1st five commands from pending queue. */ + if (idx <= 5) + smsLog( pMac, LOGE, "Out of command buffer.... SME pending command #%d (0x%X)", + idx, pTempCmd->command ); + idx++; + if( eSmeCsrCommandMask & pTempCmd->command ) + { + //CSR command is stuck. See what the reason code is for that command + dumpCsrCommandInfo(pMac, pTempCmd); + } + pEntry = csrLLNext( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); + } + csrLLUnlock(&pMac->sme.smeCmdPendingList); + + idx = 1; + //There may be some more command in CSR's own pending queue + csrLLLock(&pMac->roam.roamCmdPendingList); + pEntry = csrLLPeekHead( &pMac->roam.roamCmdPendingList, LL_ACCESS_NOLOCK ); + while(pEntry && !smeCommandQueueFull) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + /* Print only 1st five commands from CSR pending queue */ + if (idx <= 5) + smsLog( pMac, LOGE, + "Out of command buffer...CSR pending command #%d (0x%X)", + idx, pTempCmd->command ); + idx++; + dumpCsrCommandInfo(pMac, pTempCmd); + pEntry = csrLLNext( &pMac->roam.roamCmdPendingList, pEntry, LL_ACCESS_NOLOCK ); + } + /* + * Increament static variable so that it prints pending command + * only once + */ + smeCommandQueueFull++; + csrLLUnlock(&pMac->roam.roamCmdPendingList); + + vos_state_info_dump_all(); + + if (pMac->roam.configParam.enableFatalEvent) + { + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, + FALSE, FALSE); + } + else + { + /* Trigger SSR */ + vos_wlanRestart(); + } + } + + if( pRetCmd ) + { + vos_mem_set((tANI_U8 *)&pRetCmd->command, sizeof(pRetCmd->command), 0); + vos_mem_set((tANI_U8 *)&pRetCmd->sessionId, sizeof(pRetCmd->sessionId), 0); + vos_mem_set((tANI_U8 *)&pRetCmd->u, sizeof(pRetCmd->u), 0); + } + + return( pRetCmd ); +} + + +void smePushCommand( tpAniSirGlobal pMac, tSmeCmd *pCmd, tANI_BOOLEAN fHighPriority ) +{ + if (!SME_IS_START(pMac)) + { + smsLog( pMac, LOGE, FL("Sme in stop state")); + return; + } + if ( fHighPriority ) + { + csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK ); + } + else + { + csrLLInsertTail( &pMac->sme.smeCmdPendingList, &pCmd->Link, LL_ACCESS_LOCK ); + } + + // process the command queue... + smeProcessPendingQueue( pMac ); + + return; +} + + +static eSmeCommandType smeIsFullPowerNeeded( tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + eSmeCommandType pmcCommand = eSmeNoCommand; + tANI_BOOLEAN fFullPowerNeeded = eANI_BOOLEAN_FALSE; + tPmcState pmcState; + eHalStatus status; + + do + { + pmcState = pmcGetPmcState(pMac); + + status = csrIsFullPowerNeeded( pMac, pCommand, NULL, &fFullPowerNeeded ); + if( !HAL_STATUS_SUCCESS(status) ) + { + //PMC state is not right for the command, drop it + return ( eSmeDropCommand ); + } + if( fFullPowerNeeded ) break; + fFullPowerNeeded = ( ( eSmeCommandAddTs == pCommand->command ) || + ( eSmeCommandDelTs == pCommand->command ) ); + if( fFullPowerNeeded ) break; +#ifdef FEATURE_OEM_DATA_SUPPORT + fFullPowerNeeded = (pmcState == IMPS && + eSmeCommandOemDataReq == pCommand->command); + if(fFullPowerNeeded) break; +#endif + fFullPowerNeeded = (pmcState == IMPS && + eSmeCommandRemainOnChannel == pCommand->command); + if(fFullPowerNeeded) break; + } while(0); + + if( fFullPowerNeeded ) + { + switch( pmcState ) + { + case IMPS: + case STANDBY: + pmcCommand = eSmeCommandExitImps; + break; + + case BMPS: + pmcCommand = eSmeCommandExitBmps; + break; + + case UAPSD: + pmcCommand = eSmeCommandExitUapsd; + break; + + case WOWL: + pmcCommand = eSmeCommandExitWowl; + break; + + default: + break; + } + } + + return ( pmcCommand ); +} + + +//For commands that need to do extra cleanup. +static void smeAbortCommand( tpAniSirGlobal pMac, tSmeCmd *pCommand, tANI_BOOLEAN fStopping ) +{ + if( eSmePmcCommandMask & pCommand->command ) + { + pmcAbortCommand( pMac, pCommand, fStopping ); + } + else if ( eSmeCsrCommandMask & pCommand->command ) + { + csrAbortCommand( pMac, pCommand, fStopping ); + } + else + { + switch( pCommand->command ) + { + case eSmeCommandRemainOnChannel: + if (NULL != pCommand->u.remainChlCmd.callback) + { + remainOnChanCallback callback = + pCommand->u.remainChlCmd.callback; + /* process the msg */ + if( callback ) + { + callback(pMac, pCommand->u.remainChlCmd.callbackCtx, + eCSR_SCAN_ABORT ); + } + } + smeReleaseCommand( pMac, pCommand ); + break; + default: + smeReleaseCommand( pMac, pCommand ); + break; + } + } +} + +tListElem *csrGetCmdToProcess(tpAniSirGlobal pMac, tDblLinkList *pList, + tANI_U8 sessionId, tANI_BOOLEAN fInterlocked) +{ + tListElem *pCurEntry = NULL; + tSmeCmd *pCommand; + + /* Go through the list and return the command whose session id is not + * matching with the current ongoing scan cmd sessionId */ + pCurEntry = csrLLPeekHead( pList, LL_ACCESS_LOCK ); + while (pCurEntry) + { + pCommand = GET_BASE_ADDR(pCurEntry, tSmeCmd, Link); + if (pCommand->sessionId != sessionId) + { + smsLog(pMac, LOG1, "selected the command with different sessionId"); + return pCurEntry; + } + + pCurEntry = csrLLNext(pList, pCurEntry, fInterlocked); + } + + smsLog(pMac, LOG1, "No command pending with different sessionId"); + return NULL; +} + +tANI_BOOLEAN smeProcessScanQueue(tpAniSirGlobal pMac) +{ + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pSmeEntry; + tSmeCmd *pSmeCommand; + tANI_BOOLEAN status = eANI_BOOLEAN_TRUE; + + csrLLLock( &pMac->sme.smeScanCmdActiveList ); + if (csrLLIsListEmpty( &pMac->sme.smeScanCmdActiveList, + LL_ACCESS_NOLOCK )) + { + if (!csrLLIsListEmpty(&pMac->sme.smeScanCmdPendingList, + LL_ACCESS_LOCK)) + { + pEntry = csrLLPeekHead( &pMac->sme.smeScanCmdPendingList, + LL_ACCESS_LOCK ); + if (pEntry) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + //We cannot execute any command in wait-for-key state until setKey is through. + if (CSR_IS_WAIT_FOR_KEY( pMac, pCommand->sessionId)) + { + if (!CSR_IS_SET_KEY_COMMAND(pCommand)) + { + smsLog(pMac, LOGE, + " Cannot process command(%d) while waiting for key", + pCommand->command); + status = eANI_BOOLEAN_FALSE; + goto end; + } + } + + if ((!csrLLIsListEmpty(&pMac->sme.smeCmdActiveList, + LL_ACCESS_LOCK ))) + { + pSmeEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, + LL_ACCESS_LOCK); + if (pEntry) + { + pSmeCommand = GET_BASE_ADDR(pEntry, tSmeCmd, + Link) ; + + /* if scan is running on one interface and SME recei + ves the next command on the same interface then + dont the allow the command to be queued to + smeCmdPendingList. If next scan is allowed on + the same interface the CSR state machine will + get screwed up. */ + if (pSmeCommand->sessionId == pCommand->sessionId) + { + status = eANI_BOOLEAN_FALSE; + goto end; + } + } + } + if ( csrLLRemoveEntry( &pMac->sme.smeScanCmdPendingList, + pEntry, LL_ACCESS_LOCK ) ) + { + csrLLInsertHead( &pMac->sme.smeScanCmdActiveList, + &pCommand->Link, LL_ACCESS_NOLOCK ); + + switch (pCommand->command) + { + case eSmeCommandScan: + smsLog(pMac, LOG1, + " Processing scan offload command "); + csrProcessScanCommand( pMac, pCommand ); + break; + default: + smsLog(pMac, LOGE, + " Something wrong, wrong command enqueued" + " to smeScanCmdPendingList"); + pEntry = csrLLRemoveHead( + &pMac->sme.smeScanCmdActiveList, + LL_ACCESS_NOLOCK ); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeReleaseCommand( pMac, pCommand ); + break; + } + } + } + } + } +end: + csrLLUnlock(&pMac->sme.smeScanCmdActiveList); + return status; +} + +eHalStatus smeProcessPnoCommand(tpAniSirGlobal pMac, tSmeCmd *pCmd) +{ + tpSirPNOScanReq pnoReqBuf; + tSirMsgQ msgQ; + + pnoReqBuf = vos_mem_malloc(sizeof(tSirPNOScanReq)); + if ( NULL == pnoReqBuf ) + { + smsLog(pMac, LOGE, FL("failed to allocate memory")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pnoReqBuf, &(pCmd->u.pnoInfo), sizeof(tSirPNOScanReq)); + + smsLog(pMac, LOG1, FL("post WDA_SET_PNO_REQ comamnd")); + msgQ.type = WDA_SET_PNO_REQ; + msgQ.reserved = 0; + msgQ.bodyptr = pnoReqBuf; + msgQ.bodyval = 0; + wdaPostCtrlMsg( pMac, &msgQ); + + return eHAL_STATUS_SUCCESS; +} + +/** + * sme_process_set_max_tx_power() - Set the Maximum Transmit Power + * + * @pMac: mac pointer. + * @command: cmd param containing bssid, self mac + * and power in db + * + * Set the maximum transmit power dynamically. + * + * Return: eHalStatus + * + */ +eHalStatus sme_process_set_max_tx_power(tpAniSirGlobal pMac, + tSmeCmd *command) +{ + vos_msg_t msg; + tMaxTxPowerParams *max_tx_params = NULL; + + max_tx_params = vos_mem_malloc(sizeof(*max_tx_params)); + if (NULL == max_tx_params) + { + smsLog(pMac, LOGE, FL("fail to allocate memory for max_tx_params")); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(max_tx_params->bssId, + command->u.set_tx_max_pwr.bssid, SIR_MAC_ADDR_LENGTH); + vos_mem_copy(max_tx_params->selfStaMacAddr, + command->u.set_tx_max_pwr.self_sta_mac_addr, + SIR_MAC_ADDR_LENGTH); + max_tx_params->power = + command->u.set_tx_max_pwr.power; + + msg.type = WDA_SET_MAX_TX_POWER_REQ; + msg.reserved = 0; + msg.bodyptr = max_tx_params; + + if(VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + smsLog(pMac, LOGE, + FL("Not able to post WDA_SET_MAX_TX_POWER_REQ message to WDA")); + vos_mem_free(max_tx_params); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} + +/** + * sme_process_set_max_tx_power_per_band() - Set the Maximum Transmit Power + * specific to band dynamically + * @mac_ctx: mac context + * @command: cmd param containing band, and power in db + * + * Set the maximum transmit power dynamically per band + * + * Return: eHalStatus + */ +eHalStatus sme_process_set_max_tx_power_per_band(tpAniSirGlobal mac_ctx, + tSmeCmd *command) +{ + vos_msg_t msg; + tMaxTxPowerPerBandParams *max_tx_params_per_band; + + max_tx_params_per_band = + vos_mem_malloc(sizeof(*max_tx_params_per_band)); + if (max_tx_params_per_band == NULL) { + smsLog(mac_ctx, LOGE, + FL("fail to allocate memory")); + return eHAL_STATUS_FAILURE; + } + + max_tx_params_per_band->bandInfo = + command->u.set_tx_max_pwr_per_band.band; + max_tx_params_per_band->power = + command->u.set_tx_max_pwr_per_band.power; + + msg.type = WDA_SET_MAX_TX_POWER_PER_BAND_REQ; + msg.reserved = 0; + msg.bodyptr = max_tx_params_per_band; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) { + smsLog(mac_ctx, LOGE, + FL("Unable to post message to WDA")); + vos_mem_free(max_tx_params_per_band); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} + + +/** + * sme_process_update_channel_list() - Update channel list + * @mac_ctx: mac context + * @command: cmd param containing band, and power in db + * + * Return: eHalStatus + */ +eHalStatus sme_process_update_channel_list(tpAniSirGlobal mac_ctx, + tSmeCmd *command) +{ + vos_msg_t msg; + + msg.type = WDA_UPDATE_CHAN_LIST_REQ; + msg.reserved = 0; + msg.bodyptr = command->u.chan_list; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) { + smsLog(mac_ctx, LOGE, + FL("Unable to post message to WDA")); + vos_mem_free(command->u.chan_list); + return eHAL_STATUS_FAILURE; + } + return eHAL_STATUS_SUCCESS; +} + +static void smeProcessNanReq(tpAniSirGlobal pMac, tSmeCmd *pCommand ) +{ + tSirMsgQ msgQ; + tSirRetStatus retCode = eSIR_SUCCESS; + + msgQ.type = WDA_NAN_REQUEST; + msgQ.reserved = 0; + msgQ.bodyptr = pCommand->u.pNanReq; + msgQ.bodyval = 0; + + retCode = wdaPostCtrlMsg( pMac, &msgQ ); + if( eSIR_SUCCESS != retCode) + { + vos_mem_free(pCommand->u.pNanReq); + smsLog( pMac, LOGE, + FL("Posting WDA_NAN_REQUEST to WDA failed, reason=%X"), + retCode ); + } + else + { + smsLog(pMac, LOG1, FL("posted WDA_NAN_REQUEST command")); + } +} + +tANI_BOOLEAN smeProcessCommand( tpAniSirGlobal pMac ) +{ + tANI_BOOLEAN fContinue = eANI_BOOLEAN_FALSE; + eHalStatus status = eHAL_STATUS_SUCCESS; + tListElem *pEntry; + tSmeCmd *pCommand; + tListElem *pSmeEntry; + tSmeCmd *pSmeCommand; + eSmeCommandType pmcCommand = eSmeNoCommand; + + // if the ActiveList is empty, then nothing is active so we can process a + // pending command... + //alwasy lock active list before locking pending list + csrLLLock( &pMac->sme.smeCmdActiveList ); + if ( csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) ) + { + if(!csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK)) + { + /* If scan command is pending in the smeScanCmdActive list + * then pick the command from smeCmdPendingList which is + * not matching with the scan command session id. + * At any point of time only one command will be allowed + * on a single session. */ + if ((pMac->fScanOffload) && + (!csrLLIsListEmpty(&pMac->sme.smeScanCmdActiveList, + LL_ACCESS_LOCK))) + { + pSmeEntry = csrLLPeekHead(&pMac->sme.smeScanCmdActiveList, + LL_ACCESS_LOCK); + if (pSmeEntry) + { + pSmeCommand = GET_BASE_ADDR(pSmeEntry, tSmeCmd, Link); + + pEntry = csrGetCmdToProcess(pMac, + &pMac->sme.smeCmdPendingList, + pSmeCommand->sessionId, + LL_ACCESS_LOCK); + goto sme_process_cmd; + } + } + + //Peek the command + pEntry = csrLLPeekHead( &pMac->sme.smeCmdPendingList, LL_ACCESS_LOCK ); +sme_process_cmd: + if( pEntry ) + { + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + + /* Allow only disconnect command + * in wait-for-key state until setKey is through. + */ + if( CSR_IS_WAIT_FOR_KEY( pMac, pCommand->sessionId ) && + !CSR_IS_DISCONNECT_COMMAND( pCommand ) ) + { + if( !CSR_IS_SET_KEY_COMMAND( pCommand ) ) + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smsLog(pMac, LOGE, FL("SessionId %d: Cannot process " + "command(%d) while waiting for key"), + pCommand->sessionId, pCommand->command); + fContinue = eANI_BOOLEAN_FALSE; + goto sme_process_scan_queue; + } + } + pmcCommand = smeIsFullPowerNeeded( pMac, pCommand ); + if( eSmeDropCommand == pmcCommand ) + { + //This command is not ok for current PMC state + if( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) ) + { + smeAbortCommand( pMac, pCommand, eANI_BOOLEAN_FALSE ); + } + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + //tell caller to continue + fContinue = eANI_BOOLEAN_TRUE; + goto sme_process_scan_queue; + } + else if( eSmeNoCommand != pmcCommand ) + { + tExitBmpsInfo exitBmpsInfo; + void *pv = NULL; + tANI_U32 size = 0; + tSmeCmd *pPmcCmd = NULL; + + if( eSmeCommandExitBmps == pmcCommand ) + { + exitBmpsInfo.exitBmpsReason = eSME_REASON_OTHER; + pv = (void *)&exitBmpsInfo; + size = sizeof(tExitBmpsInfo); + } + //pmcCommand has to be one of the exit power save command + status = pmcPrepareCommand( pMac, pmcCommand, pv, size, &pPmcCmd ); + if( HAL_STATUS_SUCCESS( status ) && pPmcCmd ) + { + /* Set the time out to 30 sec */ + pMac->sme.smeCmdActiveList.cmdTimeoutDuration = + CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE; + //Force this command to wake up the chip + csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_COMMAND,pPmcCmd->sessionId, + pPmcCmd->command)); + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + fContinue = pmcProcessCommand( pMac, pPmcCmd ); + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, &pPmcCmd->Link, LL_ACCESS_NOLOCK ) ) + { + pmcReleaseCommand( pMac, pPmcCmd ); + } + } + } + else + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smsLog( pMac, LOGE, FL( "Cannot issue command(0x%X) to wake up the chip. Status = %d"), pmcCommand, status ); + //Let it retry + fContinue = eANI_BOOLEAN_TRUE; + } + goto sme_process_scan_queue; + } + if ( csrLLRemoveEntry( &pMac->sme.smeCmdPendingList, pEntry, LL_ACCESS_LOCK ) ) + { + // we can reuse the pCommand + + /* For ROC set timeot to 30 *3 as Supplicant can retry + * P2P Invitation Request 120 times with 500ms interval. + * For roam command set timeout to 30 * 2 sec. + * There are cases where we try to connect to different + * APs with same SSID one by one until sucessfully conneted + * and thus roam command might take more time if connection + * is rejected by too many APs. + */ + if (eSmeCommandRemainOnChannel == pCommand->command) + pMac->sme.smeCmdActiveList.cmdTimeoutDuration = + CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE * 3; + else if ((eSmeCommandRoam == pCommand->command) && + (eCsrHddIssued == pCommand->u.roamCmd.roamReason)) + pMac->sme.smeCmdActiveList.cmdTimeoutDuration = + CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE * 2; + else + pMac->sme.smeCmdActiveList.cmdTimeoutDuration = + CSR_ACTIVE_LIST_CMD_TIMEOUT_VALUE; + // Insert the command onto the ActiveList... + csrLLInsertHead( &pMac->sme.smeCmdActiveList, &pCommand->Link, LL_ACCESS_NOLOCK ); + + if( pMac->deferImps ) + { + /* IMPS timer is already running so stop it and + * it will get restarted when no command is pending + */ + csrScanStopIdleScanTimer( pMac ); + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + pMac->deferImps = eANI_BOOLEAN_FALSE; + } + + // .... and process the command. + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_COMMAND, pCommand->sessionId, pCommand->command)); + switch ( pCommand->command ) + { + + case eSmeCommandScan: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrProcessScanCommand( pMac, pCommand ); + break; + + case eSmeCommandRoam: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrRoamProcessCommand( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRoam( pMac, pCommand ); + } + } + break; + + case eSmeCommandWmStatusChange: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrRoamProcessWmStatusChangeCommand(pMac, pCommand); + break; + + case eSmeCommandSetKey: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrRoamProcessSetKeyCommand( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandSetKey( pMac, pCommand ); + } + } + break; + + case eSmeCommandRemoveKey: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = csrRoamProcessRemoveKeyCommand( pMac, pCommand ); + if(!HAL_STATUS_SUCCESS(status)) + { + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommandRemoveKey( pMac, pCommand ); + } + } + break; + + case eSmeCommandAddStaSession: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrProcessAddStaSessionCommand( pMac, pCommand ); + break; + case eSmeCommandDelStaSession: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrProcessDelStaSessionCommand( pMac, pCommand ); + break; + case eSmeCommandMacSpoofRequest: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrProcessMacAddrSpoofCommand( pMac, pCommand ); + //We need to re-run the command + fContinue = eANI_BOOLEAN_TRUE; + + // No Rsp expected, free cmd from active list + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommand( pMac, pCommand ); + } + + break; + case eSmeCommandGetFrameLogRequest: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + csrProcessGetFrameLogCommand( pMac, pCommand ); + //We need to re-run the command + fContinue = eANI_BOOLEAN_TRUE; + // No Rsp expected, free cmd from active list + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + csrReleaseCommand( pMac, pCommand ); + } + break; + case eSmeCommandSetMaxTxPower: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + sme_process_set_max_tx_power(pMac, pCommand); + /* We need to re-run the command */ + fContinue = eANI_BOOLEAN_TRUE; + /* No Rsp expected, free cmd from active list */ + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + { + csrReleaseCommand(pMac, pCommand); + } + pMac->max_power_cmd_pending = false; + break; + case eSmeCommandSetMaxTxPowerPerBand: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + sme_process_set_max_tx_power_per_band(pMac, + pCommand); + /* We need to re-run the command */ + fContinue = eANI_BOOLEAN_TRUE; + /* No Rsp expected, free cmd from active list */ + if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) { + csrReleaseCommand(pMac, pCommand); + } + pMac->max_power_cmd_pending = false; + break; + + case eSmeCommandUpdateChannelList: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + sme_process_update_channel_list(pMac, pCommand); + if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) { + csrReleaseCommand(pMac, pCommand); + } + smsLog(pMac, LOG1, + FL("eSmeCommandUpdateChannelList processed")); + fContinue = eANI_BOOLEAN_TRUE; + break; + +#ifdef FEATURE_OEM_DATA_SUPPORT + case eSmeCommandOemDataReq: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + oemData_ProcessOemDataReqCommand(pMac, pCommand); + break; +#endif + case eSmeCommandRemainOnChannel: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + p2pProcessRemainOnChannelCmd(pMac, pCommand); + break; + case eSmeCommandNoAUpdate: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + p2pProcessNoAReq(pMac,pCommand); + case eSmeCommandEnterImps: + case eSmeCommandExitImps: + case eSmeCommandEnterBmps: + case eSmeCommandExitBmps: + case eSmeCommandEnterUapsd: + case eSmeCommandExitUapsd: + case eSmeCommandEnterWowl: + case eSmeCommandExitWowl: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + fContinue = pmcProcessCommand( pMac, pCommand ); + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + } + } + break; + + //Treat standby differently here because caller may not be able to handle + //the failure so we do our best here + case eSmeCommandEnterStandby: + if( csrIsConnStateDisconnected( pMac, pCommand->sessionId ) ) + { + //It can continue + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + fContinue = pmcProcessCommand( pMac, pCommand ); + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + } + } + } + else + { + //Need to issue a disconnect first before processing this command + tSmeCmd *pNewCmd; + + //We need to re-run the command + fContinue = eANI_BOOLEAN_TRUE; + //Pull off the standby command first + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_NOLOCK ) ) + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + //Need to call CSR function here because the disconnect command + //is handled by CSR + pNewCmd = csrGetCommandBuffer( pMac ); + if( NULL != pNewCmd ) + { + //Put the standby command to the head of the pending list first + csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pCommand->Link, + LL_ACCESS_LOCK ); + pNewCmd->command = eSmeCommandRoam; + pNewCmd->u.roamCmd.roamReason = eCsrForcedDisassoc; + //Put the disassoc command before the standby command + csrLLInsertHead( &pMac->sme.smeCmdPendingList, &pNewCmd->Link, + LL_ACCESS_LOCK ); + } + else + { + //Continue the command here + fContinue = pmcProcessCommand( pMac, pCommand ); + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK ) ) + { + pmcReleaseCommand( pMac, pCommand ); + } + } + } + } + else + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smsLog( pMac, LOGE, FL(" failed to remove standby command") ); + VOS_ASSERT(0); + } + } + break; + case eSmeCommandPnoReq: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + status = smeProcessPnoCommand(pMac, pCommand); + if (!HAL_STATUS_SUCCESS(status)){ + smsLog(pMac, LOGE, + FL("failed to post SME PNO SCAN %d"), status); + } + //We need to re-run the command + fContinue = eANI_BOOLEAN_TRUE; + + if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + { + csrReleaseCommand(pMac, pCommand); + } + break; + case eSmeCommandAddTs: + case eSmeCommandDelTs: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + fContinue = qosProcessCommand( pMac, pCommand ); + if( fContinue ) + { + //The command failed, remove it + if( csrLLRemoveEntry( &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_NOLOCK ) ) + { +//#ifndef WLAN_MDM_CODE_REDUCTION_OPT + qosReleaseCommand( pMac, pCommand ); +//#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ + } + } +#endif + break; +#ifdef FEATURE_WLAN_TDLS + case eSmeCommandTdlsSendMgmt: + case eSmeCommandTdlsAddPeer: + case eSmeCommandTdlsDelPeer: + case eSmeCommandTdlsLinkEstablish: + case eSmeCommandTdlsChannelSwitch: // tdlsoffchan + smsLog(pMac, LOG1, + FL("sending TDLS Command 0x%x to PE"), + pCommand->command); + csrLLUnlock(&pMac->sme.smeCmdActiveList); + status = csrTdlsProcessCmd(pMac, pCommand); + if(!HAL_STATUS_SUCCESS(status)) + { + if(csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + csrReleaseCommand(pMac, pCommand); + } + break ; +#endif + case eSmeCommandNanReq: + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + smeProcessNanReq( pMac, pCommand ); + if (csrLLRemoveEntry(&pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + { + csrReleaseCommand(pMac, pCommand); + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "eSmeCommandNanReq processed"); + fContinue = eANI_BOOLEAN_TRUE; + break; + + default: + //something is wrong + //remove it from the active list + smsLog(pMac, LOGE, " csrProcessCommand processes an unknown command %d", pCommand->command); + pEntry = csrLLRemoveHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ); + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + pCommand = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + smeReleaseCommand( pMac, pCommand ); + status = eHAL_STATUS_FAILURE; + break; + } + if(!HAL_STATUS_SUCCESS(status)) + { + fContinue = eANI_BOOLEAN_TRUE; + } + }//if(pEntry) + else + { + //This is odd. Some one else pull off the command. + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + } + } + else + { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + } + } + else + { + //No command waiting + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + //This is only used to restart an idle mode scan, it means at least one other idle scan has finished. + if(pMac->scan.fRestartIdleScan && eANI_BOOLEAN_FALSE == pMac->scan.fCancelIdleScan) + { + tANI_U32 nTime = 0; + + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + if(!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac, &nTime))) + { + csrScanStartIdleScanTimer(pMac, nTime); + } + } + } + } + else { + csrLLUnlock( &pMac->sme.smeCmdActiveList ); + } + +sme_process_scan_queue: + if (pMac->fScanOffload && !(smeProcessScanQueue(pMac))) + fContinue = eANI_BOOLEAN_FALSE; + + return ( fContinue ); +} + +void smeProcessPendingQueue( tpAniSirGlobal pMac ) +{ + while( smeProcessCommand( pMac ) ); +} + + +tANI_BOOLEAN smeCommandPending(tpAniSirGlobal pMac) +{ + return ( !csrLLIsListEmpty( &pMac->sme.smeCmdActiveList, LL_ACCESS_NOLOCK ) || + !csrLLIsListEmpty(&pMac->sme.smeCmdPendingList, LL_ACCESS_NOLOCK) ); +} + + + +//Global APIs + +/*-------------------------------------------------------------------------- + + \brief sme_Open() - Initialze all SME modules and put them at idle state + + The function initializes each module inside SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are at idle state ready to start. + + smeOpen must be called before any other SME APIs can be involved. + smeOpen must be called after macOpen. + This is a synchronous call + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is successfully initialized. + + Other status means SME is failed to be initialized + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Open(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + do { + pMac->sme.state = SME_STATE_STOP; + pMac->sme.currDeviceMode = VOS_STA_MODE; + if( !VOS_IS_STATUS_SUCCESS( vos_lock_init( &pMac->sme.lkSmeGlobalLock ) ) ) + { + smsLog( pMac, LOGE, "sme_Open failed init lock" ); + status = eHAL_STATUS_FAILURE; + break; + } + + status = ccmOpen(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "ccmOpen failed during initialization with status=%d", status ); + break; + } + + status = csrOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "csrOpen failed during initialization with status=%d", status ); + break; + } + + status = pmcOpen(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "pmcOpen failed during initialization with status=%d", status ); + break; + } + +#ifdef FEATURE_WLAN_TDLS + pMac->isTdlsPowerSaveProhibited = 0; +#endif + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + status = sme_QosOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "Qos open failed during initialization with status=%d", status ); + break; + } + + status = btcOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "btcOpen open failed during initialization with status=%d", status ); + break; + } +#endif +#ifdef FEATURE_OEM_DATA_SUPPORT + status = oemData_OemDataReqOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog(pMac, LOGE, + "oemData_OemDataReqOpen failed during initialization with status=%d", status ); + break; + } +#endif + + if(!HAL_STATUS_SUCCESS((status = initSmeCmdList(pMac)))) + break; + + { + v_PVOID_t pvosGCtx = vos_get_global_context(VOS_MODULE_ID_SAP, NULL); + if ( NULL == pvosGCtx ){ + smsLog( pMac, LOGE, "WLANSAP_Open open failed during initialization"); + status = eHAL_STATUS_FAILURE; + break; + } + + status = WLANSAP_Open( pvosGCtx ); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "WLANSAP_Open open failed during initialization with status=%d", status ); + break; + } + } +#if defined WLAN_FEATURE_VOWIFI + status = rrmOpen(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, + "rrmOpen open failed during initialization with status=%d", status ); + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + sme_FTOpen(pMac); +#endif + + sme_p2pOpen(pMac); + smeTraceInit(pMac); + sme_register_debug_callback(); + + }while (0); + + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_set11dinfo() - Set the 11d information about valid channels + and there power using information from nvRAM + This function is called only for AP. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_set11dinfo(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO, NO_SESSION, 0)); + if (NULL == pSmeConfigParams ) { + smsLog( pMac, LOGE, + "Empty config param structure for SME, nothing to update"); + return status; + } + + status = csrSetChannels(hHal, &pSmeConfigParams->csrConfig ); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d", + status ); + } + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_getSoftApDomain() - Get the current regulatory domain of softAp. + + This is a synchronous call + + \param hHal - The handle returned by HostapdAdapter. + \Param v_REGDOMAIN_t - The current Regulatory Domain requested for SoftAp. + + \return eHAL_STATUS_SUCCESS - SME successfully completed the request. + + Other status means, failed to get the current regulatory domain. + \sa +--------------------------------------------------------------------------*/ + +eHalStatus sme_getSoftApDomain(tHalHandle hHal, v_REGDOMAIN_t *domainIdSoftAp) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN, NO_SESSION, 0)); + if (NULL == domainIdSoftAp ) { + smsLog( pMac, LOGE, "Uninitialized domain Id"); + return status; + } + + *domainIdSoftAp = pMac->scan.domainIdCurrent; + status = eHAL_STATUS_SUCCESS; + + return status; +} + + +eHalStatus sme_setRegInfo(tHalHandle hHal, tANI_U8 *apCntryCode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO, NO_SESSION, 0)); + if (NULL == apCntryCode ) { + smsLog( pMac, LOGE, "Empty Country Code, nothing to update"); + return status; + } + + status = csrSetRegInfo(hHal, apCntryCode ); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrSetRegInfo failed with status=%d", + status ); + } + return status; +} + +#ifdef FEATURE_WLAN_SCAN_PNO +/*-------------------------------------------------------------------------- + + \brief sme_UpdateChannelConfig() - Update channel configuration in RIVA. + + It is used at driver start up to inform RIVA of the default channel + configuration. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME update the channel config successfully. + + Other status means SME is failed to update the channel config. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateChannelConfig(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG, NO_SESSION, 0)); + pmcUpdateScanParams( pMac, &(pMac->roam.configParam), + &pMac->scan.base20MHzChannels, FALSE); + return eHAL_STATUS_SUCCESS; +} +#endif // FEATURE_WLAN_SCAN_PNLO + +eHalStatus sme_UpdateChannelList(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = csrUpdateChannelList(pMac); + + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "failed to update the supported channel list"); + } + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_UpdateConfig() - Change configurations for all SME moduels + + The function updates some configuration for modules in SME, CCM, CSR, etc + during SMEs close open sequence. + + Modules inside SME apply the new configuration at the next transaction. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + \Param pSmeConfigParams - a pointer to a caller allocated object of + typedef struct _smeConfigParams. + + \return eHAL_STATUS_SUCCESS - SME update the config parameters successfully. + + Other status means SME is failed to update the config parameters. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateConfig(tHalHandle hHal, tpSmeConfigParams pSmeConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG, NO_SESSION, 0)); + if (NULL == pSmeConfigParams ) { + smsLog( pMac, LOGE, + "Empty config param structure for SME, nothing to update"); + return status; + } + + status = csrChangeDefaultConfigParam(pMac, &pSmeConfigParams->csrConfig); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrChangeDefaultConfigParam failed with status=%d", + status ); + } +#if defined WLAN_FEATURE_P2P_INTERNAL + status = p2pChangeDefaultConfigParam(pMac, &pSmeConfigParams->p2pConfig); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "p2pChangeDefaultConfigParam failed with status=%d", + status ); + } +#endif +#if defined WLAN_FEATURE_VOWIFI + status = rrmChangeDefaultConfigParam(hHal, &pSmeConfigParams->rrmConfig); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "rrmChangeDefaultConfigParam failed with status=%d", + status ); + } +#endif + //For SOC, CFG is set before start + //We don't want to apply global CFG in connect state because that may cause some side affect + if( + csrIsAllSessionDisconnected( pMac) ) + { + csrSetGlobalCfgs(pMac); + } + + /* update the directed scan offload setting */ + pMac->fScanOffload = pSmeConfigParams->fScanOffload; + + if (pMac->fScanOffload) + { + /* If scan offload is enabled then lim has allow the sending of + scan request to firmware even in powersave mode. The firmware has + to take care of exiting from power save mode */ + status = ccmCfgSetInt(hHal, WNI_CFG_SCAN_IN_POWERSAVE, + eANI_BOOLEAN_TRUE, NULL, eANI_BOOLEAN_FALSE); + + if (eHAL_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Could not pass on WNI_CFG_SCAN_IN_POWERSAVE to CCM"); + } + } + pMac->isCoalesingInIBSSAllowed = + pSmeConfigParams->csrConfig.isCoalesingInIBSSAllowed; + pMac->fEnableDebugLog = pSmeConfigParams->fEnableDebugLog; + pMac->fDeferIMPSTime = pSmeConfigParams->fDeferIMPSTime; + pMac->fBtcEnableIndTimerVal = pSmeConfigParams->fBtcEnableIndTimerVal; + + pMac->sta_auth_retries_for_code17 = + pSmeConfigParams->csrConfig.sta_auth_retries_for_code17; + + return status; +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +void sme_ProcessGetGtkInfoRsp( tHalHandle hHal, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return ; + } + if (pMac->pmc.GtkOffloadGetInfoCB == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: HDD callback is null", __func__); + return ; + } + pMac->pmc.GtkOffloadGetInfoCB(pMac->pmc.GtkOffloadGetInfoCBContext, + pGtkOffloadGetInfoRsp); +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_ChangeConfigParams + \brief The SME API exposed for HDD to provide config params to SME during + SMEs stop -> start sequence. + + If HDD changed the domain that will cause a reset. This function will + provide the new set of 11d information for the new domain. Currrently this + API provides info regarding 11d only at reset but we can extend this for + other params (PMC, QoS) which needs to be initialized again at reset. + + This is a synchronous call + + \param hHal - The handle returned by macOpen. + + \Param + pUpdateConfigParam - a pointer to a structure (tCsrUpdateConfigParam) that + currently provides 11d related information like Country code, + Regulatory domain, valid channel list, Tx power per channel, a + list with active/passive scan allowed per valid channel. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ChangeConfigParams(tHalHandle hHal, + tCsrUpdateConfigParam *pUpdateConfigParam) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pUpdateConfigParam ) { + smsLog( pMac, LOGE, + "Empty config param structure for SME, nothing to reset"); + return status; + } + + status = csrChangeConfigParams(pMac, pUpdateConfigParam); + + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrUpdateConfigParam failed with status=%d", + status ); + } + + return status; + +} + +/*-------------------------------------------------------------------------- + + \brief sme_HDDReadyInd() - SME sends eWNI_SME_SYS_READY_IND to PE to inform + that the NIC is ready tio run. + + The function is called by HDD at the end of initialization stage so PE/HAL can + enable the NIC to running state. + + This is a synchronous call + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - eWNI_SME_SYS_READY_IND is sent to PE + successfully. + + Other status means SME failed to send the message to PE. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_HDDReadyInd(tHalHandle hHal) +{ + tSirSmeReadyReq Msg; + eHalStatus status = eHAL_STATUS_FAILURE; + tPmcPowerState powerState; + tPmcSwitchState hwWlanSwitchState; + tPmcSwitchState swWlanSwitchState; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND, NO_SESSION, 0)); + do + { + + Msg.messageType = eWNI_SME_SYS_READY_IND; + Msg.length = sizeof( tSirSmeReadyReq ); + + if (eSIR_FAILURE != uMacPostCtrlMsg( hHal, (tSirMbMsg*)&Msg )) + { + status = eHAL_STATUS_SUCCESS; + } + else + { + smsLog( pMac, LOGE, + "uMacPostCtrlMsg failed to send eWNI_SME_SYS_READY_IND"); + break; + } + + status = pmcQueryPowerState( hHal, &powerState, + &hwWlanSwitchState, &swWlanSwitchState ); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "pmcQueryPowerState failed with status=%d", + status ); + break; + } + + if ( (ePMC_SWITCH_OFF != hwWlanSwitchState) && + (ePMC_SWITCH_OFF != swWlanSwitchState) ) + { + status = csrReady(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "csrReady failed with status=%d", status ); + break; + } + status = pmcReady(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, "pmcReady failed with status=%d", status ); + break; + } +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + if(VOS_STATUS_SUCCESS != btcReady(hHal)) + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, "btcReady failed"); + break; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI + if(VOS_STATUS_SUCCESS != rrmReady(hHal)) + { + status = eHAL_STATUS_FAILURE; + smsLog( pMac, LOGE, "rrmReady failed"); + break; + } +#endif + } + pMac->sme.state = SME_STATE_READY; + } while( 0 ); + + return status; +} + +/** + * sme_set_allowed_action_frames() - Set allowed action frames to FW + * + * @hal: Handler to HAL + * + * This function conveys the list of action frames that needs to be forwarded + * to driver by FW. Rest of the action frames can be dropped in FW.Bitmask is + * set with ALLOWED_ACTION_FRAMES_BITMAP + * + * Return: None + */ +static void sme_set_allowed_action_frames(tHalHandle hal) +{ + eHalStatus status; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + vos_msg_t vos_message; + VOS_STATUS vos_status; + struct sir_allowed_action_frames *sir_allowed_action_frames; + + sir_allowed_action_frames = + vos_mem_malloc(sizeof(*sir_allowed_action_frames)); + if (!sir_allowed_action_frames) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Not able to allocate memory for WDA_SET_ALLOWED_ACTION_FRAMES_IND"); + return; + } + + vos_mem_zero(sir_allowed_action_frames, sizeof(*sir_allowed_action_frames)); + sir_allowed_action_frames->bitmask = ALLOWED_ACTION_FRAMES_BITMAP; + sir_allowed_action_frames->reserved = 0; + + status = sme_AcquireGlobalLock(&mac->sme); + if (status == eHAL_STATUS_SUCCESS) { + /* serialize the req through MC thread */ + vos_message.bodyptr = sir_allowed_action_frames; + vos_message.type = WDA_SET_ALLOWED_ACTION_FRAMES_IND; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, + NO_SESSION, vos_message.type)); + vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &vos_message); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Not able to post WDA_SET_ALLOWED_ACTION_FRAMES_IND message to HAL"); + vos_mem_free(sir_allowed_action_frames); + } + + sme_ReleaseGlobalLock( &mac->sme ); + } else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(sir_allowed_action_frames); + } + return; +} + +/*-------------------------------------------------------------------------- + + \brief sme_Start() - Put all SME modules at ready state. + + The function starts each module in SME, PMC, CCM, CSR, etc. . Upon + successfully return, all modules are ready to run. + This is a synchronous call + \param hHal - The handle returned by macOpen. + + \return eHAL_STATUS_SUCCESS - SME is ready. + + Other status means SME is failed to start + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Start(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + do + { + status = csrStart(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrStart failed during smeStart with status=%d", + status ); + break; + } + + status = pmcStart(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "pmcStart failed during smeStart with status=%d", + status ); + break; + } + + status = WLANSAP_Start(vos_get_global_context(VOS_MODULE_ID_SAP, NULL)); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "WLANSAP_Start failed during smeStart with status=%d", + status ); + break; + } + pMac->sme.state = SME_STATE_START; + }while (0); + + sme_set_allowed_action_frames(hHal); + + return status; +} + + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/****************************************************************************** +* +* Name: sme_PCFilterMatchCountResponseHandler +* +* Description: +* Invoke Packet Coalescing Filter Match Count callback routine +* +* Parameters: +* hHal - HAL handle for device +* pMsg - Pointer to tRcvFltPktMatchRsp structure +* +* Returns: eHalStatus +* +******************************************************************************/ +eHalStatus sme_PCFilterMatchCountResponseHandler(tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp = (tpSirRcvFltPktMatchRsp)pMsg; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + smsLog(pMac, LOG2, "SME: entering " + "sme_FilterMatchCountResponseHandler"); + + /* Call Packet Coalescing Filter Match Count callback routine. */ + if (pMac->pmc.FilterMatchCountCB != NULL) + pMac->pmc.FilterMatchCountCB(pMac->pmc.FilterMatchCountCBContext, + pRcvFltPktMatchRsp); + + smsLog(pMac, LOG1, "%s: status=0x%x", __func__, + pRcvFltPktMatchRsp->status); + + pMac->pmc.FilterMatchCountCB = NULL; + pMac->pmc.FilterMatchCountCBContext = NULL; + } + + return(status); +} +#endif // WLAN_FEATURE_PACKET_FILTERING + + +#ifdef WLAN_FEATURE_11W +/*------------------------------------------------------------------ + * + * Handle the unprotected management frame indication from LIM and + * forward it to HDD. + * + *------------------------------------------------------------------*/ + +eHalStatus sme_UnprotectedMgmtFrmInd( tHalHandle hHal, + tpSirSmeUnprotMgmtFrameInd pSmeMgmtFrm) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + tANI_U32 SessionId = pSmeMgmtFrm->sessionId; + + pRoamInfo.nFrameLength = pSmeMgmtFrm->frameLen; + pRoamInfo.pbFrames = pSmeMgmtFrm->frameBuf; + pRoamInfo.frameType = pSmeMgmtFrm->frameType; + + /* forward the mgmt frame to HDD */ + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_UNPROT_MGMT_FRAME_IND, 0); + + return status; +} +#endif + +#ifdef WLAN_FEATURE_AP_HT40_24G +/* --------------------------------------------------------------------------- + \fn sme_HT2040CoexInfoInd + \brief a Send 20/40 Coex info to SAP layer + + \param tpSirHT2040CoexInfoInd - 20/40 Coex info param + \return eHalStatus + ---------------------------------------------------------------------------*/ + +eHalStatus sme_HT2040CoexInfoInd( tHalHandle hHal, + tpSirHT2040CoexInfoInd pSmeHT2040CoexInfoInd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U32 SessionId = pSmeHT2040CoexInfoInd->sessionId; + tCsrRoamInfo roamInfo = {0}; + + roamInfo.pSmeHT2040CoexInfoInd = pSmeHT2040CoexInfoInd; + + smsLog(pMac, LOGW, FL("HT40MHzIntolerant: %d HT20MHzBssWidthReq: %d"), + roamInfo.pSmeHT2040CoexInfoInd->HT40MHzIntolerant, + roamInfo.pSmeHT2040CoexInfoInd->HT20MHzBssWidthReq); + + smsLog(pMac, LOGW, FL("Total Intolerant Channel: %d"), + roamInfo.pSmeHT2040CoexInfoInd->channel_num); + + /* forward the 20/40 BSS Coex information to HDD */ + smsLog(pMac, LOGW, FL("Sending eCSR_ROAM_2040_COEX_INFO_IND" + " to WLANSAP_RoamCallback ")); + + csrRoamCallCallback(pMac, SessionId, &roamInfo, + 0, eCSR_ROAM_2040_COEX_INFO_IND, 0); + return status; +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/*------------------------------------------------------------------ + * + * Handle the tsm ie indication from LIM and forward it to HDD. + * + *------------------------------------------------------------------*/ + +eHalStatus sme_TsmIeInd(tHalHandle hHal, tSirSmeTsmIEInd *pSmeTsmIeInd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrRoamInfo pRoamInfo = {0}; + tANI_U32 SessionId = pSmeTsmIeInd->sessionId; + + pRoamInfo.tsmIe.tsid= pSmeTsmIeInd->tsmIe.tsid; + pRoamInfo.tsmIe.state= pSmeTsmIeInd->tsmIe.state; + pRoamInfo.tsmIe.msmt_interval= pSmeTsmIeInd->tsmIe.msmt_interval; + + /* forward the tsm ie information to HDD */ + csrRoamCallCallback(pMac, SessionId, &pRoamInfo, 0, eCSR_ROAM_TSM_IE_IND, 0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetCCKMIe + \brief function to store the CCKM IE passed from supplicant and use it while packing + reassociation request + \param hHal - HAL handle for device + \param pCckmIe - pointer to CCKM IE data + \param pCckmIeLen - length of the CCKM IE + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetCCKMIe(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 *pCckmIe, tANI_U8 cckmIeLen) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + csrSetCCKMIe(pMac, sessionId, pCckmIe, cckmIeLen); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetEseBeaconRequest + \brief function to set Ese beacon request parameters + \param hHal - HAL handle for device + \param sessionId - Session id + \param pEseBcnReq - pointer to Ese beacon request + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_SetEseBeaconRequest(tHalHandle hHal, const tANI_U8 sessionId, + const tCsrEseBeaconReq* pEseBcnReq) +{ + eHalStatus status = eSIR_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpSirBeaconReportReqInd pSmeBcnReportReq = NULL; + tCsrEseBeaconReqParams *pBeaconReq = NULL; + tANI_U8 counter = 0; + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext; + + /* Store the info in RRM context */ + vos_mem_copy(&pSmeRrmContext->eseBcnReqInfo, pEseBcnReq, sizeof(tCsrEseBeaconReq)); + + //Prepare the request to send to SME. + pSmeBcnReportReq = vos_mem_malloc(sizeof( tSirBeaconReportReqInd )); + if(NULL == pSmeBcnReportReq) + { + smsLog(pMac, LOGP, "Memory Allocation Failure!!! Ese BcnReq Ind to SME"); + return eSIR_FAILURE; + } + + smsLog(pMac, LOGE, "Sending Beacon Report Req to SME"); + vos_mem_zero( pSmeBcnReportReq, sizeof( tSirBeaconReportReqInd )); + + pSmeBcnReportReq->messageType = eWNI_SME_BEACON_REPORT_REQ_IND; + pSmeBcnReportReq->length = sizeof( tSirBeaconReportReqInd ); + vos_mem_copy( pSmeBcnReportReq->bssId, pSession->connectedProfile.bssid, sizeof(tSirMacAddr) ); + pSmeBcnReportReq->channelInfo.channelNum = 255; + pSmeBcnReportReq->channelList.numChannels = pEseBcnReq->numBcnReqIe; + pSmeBcnReportReq->msgSource = eRRM_MSG_SOURCE_ESE_UPLOAD; + + for (counter = 0; counter < pEseBcnReq->numBcnReqIe; counter++) + { + pBeaconReq = (tCsrEseBeaconReqParams *)&pEseBcnReq->bcnReq[counter]; + pSmeBcnReportReq->fMeasurementtype[counter] = pBeaconReq->scanMode; + pSmeBcnReportReq->measurementDuration[counter] = SYS_TU_TO_MS(pBeaconReq->measurementDuration); + pSmeBcnReportReq->channelList.channelNumber[counter] = pBeaconReq->channel; + } + + sme_RrmProcessBeaconReportReqInd(pMac, pSmeBcnReportReq); + vos_mem_free(pSmeBcnReportReq); + return status; +} + +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ + + +#ifdef WLAN_FEATURE_RMC +eHalStatus sme_IbssPeerInfoResponseHandleer( tHalHandle hHal, + tpSirIbssGetPeerInfoRspParams pIbssPeerInfoParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return eHAL_STATUS_FAILURE; + } + if (pMac->sme.peerInfoParams.peerInfoCbk == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: HDD callback is null", __func__); + return eHAL_STATUS_FAILURE; + } + pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData, + &pIbssPeerInfoParams->ibssPeerInfoRspParams); + return eHAL_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_RMC */ + + +/* --------------------------------------------------------------------------- + \fn sme_getBcnMissRate + \brief function sends 'WDA_GET_BCN_MISS_RATE_REQ' to WDA layer, + \param hHal - HAL handle for device. + \param sessionId - session ID. + \- return Success or Failure. + -------------------------------------------------------------------------*/ + +eHalStatus sme_getBcnMissRate(tHalHandle hHal, tANI_U8 sessionId, void *callback, void *data) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + vos_msg_t vosMessage; + tSirBcnMissRateReq *pMsg; + tCsrRoamSession *pSession; + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg = (tSirBcnMissRateReq *) vos_mem_malloc(sizeof(tSirBcnMissRateReq)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, FL("failed to allocated memory")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pMsg->bssid, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + pMsg->msgLen = sizeof(tSirBcnMissRateReq); + pMsg->callback = callback; + pMsg->data = data; + + vosMessage.type = WDA_GET_BCN_MISS_RATE_REQ; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Set TM Level MSG fail", __func__); + vos_mem_free(pMsg); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_SUCCESS; + } + return eHAL_STATUS_FAILURE; +} + +eHalStatus sme_EncryptMsgResponseHandler(tHalHandle hHal, + tpSirEncryptedDataRspParams pEncRspParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return eHAL_STATUS_FAILURE; + } + if (pMac->sme.pEncMsgInfoParams.pEncMsgCbk == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: HDD callback is null", __func__); + return eHAL_STATUS_FAILURE; + } + pMac->sme.pEncMsgInfoParams.pEncMsgCbk(pMac->sme.pEncMsgInfoParams.pUserData, + &pEncRspParams->encryptedDataRsp); + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_UpdateMaxRateInd(tHalHandle hHal, + tSirSmeUpdateMaxRateParams *pSmeUpdateMaxRateParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 sessionId = pSmeUpdateMaxRateParams->smeSessionId; + + /* forward the information to HDD */ + status = csrRoamCallCallback(pMac, sessionId, NULL, 0, + eCSR_ROAM_UPDATE_MAX_RATE_IND, + pSmeUpdateMaxRateParams->maxRateFlag); + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_ProcessMsg() - The main message processor for SME. + + The function is called by a message dispatcher when to process a message + targeted for SME. + + This is a synchronous call + \param hHal - The handle returned by macOpen. + \param pMsg - A pointer to a caller allocated object of tSirMsgQ. + + \return eHAL_STATUS_SUCCESS - SME successfully process the message. + + Other status means SME failed to process the message to HAL. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (pMsg == NULL) { + smsLog( pMac, LOGE, "Empty message for SME, nothing to process"); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( SME_IS_START(pMac) ) + { + switch (pMsg->type) { // TODO: Will be modified to do a range check for msgs instead of having cases for each msgs + case eWNI_PMC_ENTER_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_IND: + case eWNI_PMC_ENTER_IMPS_RSP: + case eWNI_PMC_EXIT_IMPS_RSP: + case eWNI_PMC_SMPS_STATE_IND: + case eWNI_PMC_ENTER_UAPSD_RSP: + case eWNI_PMC_EXIT_UAPSD_RSP: + case eWNI_PMC_ENTER_WOWL_RSP: + case eWNI_PMC_EXIT_WOWL_RSP: + //PMC + if (pMsg->bodyptr) + { + pmcMessageProcessor(hHal, pMsg->bodyptr); + status = eHAL_STATUS_SUCCESS; + vos_mem_free(pMsg->bodyptr); + } else { + smsLog( pMac, LOGE, "Empty rsp message for PMC, nothing to process"); + } + break; + + case WNI_CFG_SET_CNF: + case WNI_CFG_DNLD_CNF: + case WNI_CFG_GET_RSP: + case WNI_CFG_ADD_GRP_ADDR_CNF: + case WNI_CFG_DEL_GRP_ADDR_CNF: + //CCM + if (pMsg->bodyptr) + { + ccmCfgCnfMsgHandler(hHal, pMsg->bodyptr); + status = eHAL_STATUS_SUCCESS; + vos_mem_free(pMsg->bodyptr); + } else { + smsLog( pMac, LOGE, "Empty rsp message for CCM, nothing to process"); + } + break; + + case eWNI_SME_ADDTS_RSP: + case eWNI_SME_DELTS_RSP: + case eWNI_SME_DELTS_IND: +#ifdef WLAN_FEATURE_VOWIFI_11R + case eWNI_SME_FT_AGGR_QOS_RSP: +#endif + //QoS + if (pMsg->bodyptr) + { +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + status = sme_QosMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); +#endif + } else { + smsLog( pMac, LOGE, "Empty rsp message for QoS, nothing to process"); + } + break; +#if defined WLAN_FEATURE_VOWIFI + case eWNI_SME_NEIGHBOR_REPORT_IND: + case eWNI_SME_BEACON_REPORT_REQ_IND: +#if defined WLAN_VOWIFI_DEBUG + smsLog( pMac, LOGE, "Received RRM message. Message Id = %d", pMsg->type ); +#endif + if ( pMsg->bodyptr ) + { + status = sme_RrmMsgProcessor( pMac, pMsg->type, pMsg->bodyptr ); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty message for RRM, nothing to process"); + } + break; +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT + //Handle the eWNI_SME_OEM_DATA_RSP: + case eWNI_SME_OEM_DATA_RSP: + if(pMsg->bodyptr) + { + status = sme_HandleOemDataRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for oemData_ (eWNI_SME_OEM_DATA_RSP), nothing to process"); + } + smeProcessPendingQueue( pMac ); + break; +#endif + + case eWNI_SME_ADD_STA_SELF_RSP: + if(pMsg->bodyptr) + { + status = csrProcessAddStaSessionRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ADD_STA_SELF_RSP), nothing to process"); + } + break; + case eWNI_SME_DEL_STA_SELF_RSP: + if(pMsg->bodyptr) + { + status = csrProcessDelStaSessionRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_DEL_STA_SELF_RSP), nothing to process"); + } + break; + case eWNI_SME_REMAIN_ON_CHN_RSP: + if(pMsg->bodyptr) + { + status = sme_remainOnChnRsp(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RSP), nothing to process"); + } + break; + case eWNI_SME_REMAIN_ON_CHN_RDY_IND: + if(pMsg->bodyptr) + { + status = sme_remainOnChnReady(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_REMAIN_ON_CHN_RDY_IND), nothing to process"); + } + break; +#ifdef WLAN_FEATURE_AP_HT40_24G + case eWNI_SME_2040_COEX_IND: + if(pMsg->bodyptr) + { + sme_HT2040CoexInfoInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_2040_COEX_IND), nothing to process"); + } + break; +#endif + case eWNI_SME_ACTION_FRAME_SEND_CNF: + if(pMsg->bodyptr) + { + status = sme_sendActionCnf(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for meas (eWNI_SME_ACTION_FRAME_SEND_CNF), nothing to process"); + } + break; + case eWNI_SME_COEX_IND: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if(pMsg->bodyptr) + { + tSirSmeCoexInd *pSmeCoexInd = (tSirSmeCoexInd *)pMsg->bodyptr; + + if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4) + { + smsLog( pMac, LOG1, FL("SIR_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4")); + sme_RequestFullPower(hHal, NULL, NULL, eSME_REASON_OTHER); + pMac->isCoexScoIndSet = 1; + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_FALSE; + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_TRUE; + } + else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4) + { + smsLog( pMac, LOG1, FL("SIR_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4")); + pMac->isCoexScoIndSet = 0; + sme_RequestBmps(hHal, NULL, NULL); + pMac->scan.fRestartIdleScan = eANI_BOOLEAN_TRUE; + pMac->scan.fCancelIdleScan = eANI_BOOLEAN_FALSE; + } + + status = btcHandleCoexInd((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_COEX_IND), nothing to process"); + } + break; + +#ifdef FEATURE_WLAN_SCAN_PNO + case eWNI_SME_PREF_NETWORK_FOUND_IND: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if(pMsg->bodyptr) + { + status = sme_PreferredNetworkFoundInd((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_PREF_NETWORK_FOUND_IND), nothing to process"); + } + break; +#endif // FEATURE_WLAN_SCAN_PNO + + case eWNI_SME_TX_PER_HIT_IND: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMac->sme.pTxPerHitCallback) + { + pMac->sme.pTxPerHitCallback(pMac->sme.pTxPerHitCbContext); + } + break; + + case eWNI_SME_CHANGE_COUNTRY_CODE: + if(pMsg->bodyptr) + { + status = sme_HandleChangeCountryCode((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_CHANGE_COUNTRY_CODE), nothing to process"); + } + break; + + case eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE: + if (pMsg->bodyptr) + { + status = sme_HandleGenericChangeCountryCode((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for message (eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE), nothing to process"); + } + break; + +#ifdef WLAN_FEATURE_PACKET_FILTERING + case eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if(pMsg->bodyptr) + { + status = sme_PCFilterMatchCountResponseHandler((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas " + "(PACKET_COALESCING_FILTER_MATCH_COUNT_RSP), nothing to process"); + } + break; +#endif // WLAN_FEATURE_PACKET_FILTERING + case eWNI_SME_PRE_SWITCH_CHL_IND: + { + status = sme_HandlePreChannelSwitchInd(pMac); + break; + } + + case eWNI_SME_POST_SWITCH_CHL_IND: + { + status = sme_HandlePostChannelSwitchInd(pMac); + break; + } + +#ifdef WLAN_WAKEUP_EVENTS + case eWNI_SME_WAKE_REASON_IND: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if(pMsg->bodyptr) + { + status = sme_WakeReasonIndCallback((void *)pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_WAKE_REASON_IND), nothing to process"); + } + break; +#endif // WLAN_WAKEUP_EVENTS + +#ifdef FEATURE_WLAN_TDLS + /* + * command rescived from PE, SME tdls msg processor shall be called + * to process commands recieved from PE + */ + case eWNI_SME_TDLS_SEND_MGMT_RSP: + case eWNI_SME_TDLS_ADD_STA_RSP: + case eWNI_SME_TDLS_DEL_STA_RSP: + case eWNI_SME_TDLS_DEL_STA_IND: + case eWNI_SME_TDLS_DEL_ALL_PEER_IND: + case eWNI_SME_MGMT_FRM_TX_COMPLETION_IND: + case eWNI_SME_TDLS_LINK_ESTABLISH_RSP: + case eWNI_SME_TDLS_CHANNEL_SWITCH_RSP: + { + if (pMsg->bodyptr) + { + status = tdlsMsgProcessor(pMac, pMsg->type, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for TDLS, \ + nothing to process"); + } + break; + } +#endif + +#ifdef WLAN_FEATURE_11W + case eWNI_SME_UNPROT_MGMT_FRM_IND: + if (pMsg->bodyptr) + { + sme_UnprotectedMgmtFrmInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for meas (eWNI_SME_UNPROT_MGMT_FRM_IND), nothing to process"); + } + break; +#endif +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) + case eWNI_SME_TSM_IE_IND: + { + if (pMsg->bodyptr) + { + sme_TsmIeInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for (eWNI_SME_TSM_IE_IND), nothing to process"); + } + break; + } +#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case eWNI_SME_ROAM_SCAN_OFFLOAD_RSP: + status = csrRoamOffloadScanRspHdlr((void *)pMac, pMsg->bodyval); + break; +#endif // WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMsg->bodyptr) + { + sme_ProcessGetGtkInfoRsp(pMac, pMsg->bodyptr); + vos_mem_zero(pMsg->bodyptr, + sizeof(tSirGtkOffloadGetInfoRspParams)); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, "Empty rsp message for (eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP), nothing to process"); + } + break ; +#endif + +#ifdef FEATURE_WLAN_LPHB + /* LPHB timeout indication arrived, send IND to client */ + case eWNI_SME_LPHB_IND: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMac->sme.pLphbIndCb) + { + pMac->sme.pLphbIndCb(pMac->pAdapter, pMsg->bodyptr); + } + vos_mem_free(pMsg->bodyptr); + + break; +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef WLAN_FEATURE_RMC + case eWNI_SME_IBSS_PEER_INFO_RSP: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMsg->bodyptr) + { + sme_IbssPeerInfoResponseHandleer(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, + "Empty rsp message for (eWNI_SME_IBSS_PEER_INFO_RSP)," + " nothing to process"); + } + break ; + +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_CH_AVOID + /* LPHB timeout indication arrived, send IND to client */ + case eWNI_SME_CH_AVOID_IND: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMac->sme.pChAvoidNotificationCb) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: CH avoid notification", __func__); + pMac->sme.pChAvoidNotificationCb(pMac->pAdapter, pMsg->bodyptr); + } + vos_mem_free(pMsg->bodyptr); + + break; +#endif /* FEATURE_WLAN_CH_AVOID */ + + case eWNI_SME_ENCRYPT_MSG_RSP: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMsg->bodyptr) + { + sme_EncryptMsgResponseHandler(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, + "Empty rsp message for (eWNI_SME_ENCRYPT_MSG_RSP)," + " nothing to process"); + } + break ; + + case eWNI_SME_UPDATE_MAX_RATE_IND: + if (pMsg->bodyptr) + { + sme_UpdateMaxRateInd(pMac, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, + "Empty message for (eWNI_SME_UPDATE_MAX_RATE_IND)," + " nothing to process"); + } + break; + + case eWNI_SME_NAN_EVENT: + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type)); + if (pMsg->bodyptr) + { + sme_NanEvent(hHal, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog(pMac, LOGE, + "Empty message for (eWNI_SME_NAN_EVENT)," + " nothing to process"); + } + break; + + default: + + if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) + && ( pMsg->type <= eWNI_SME_MSG_TYPES_END ) ) + { + //CSR + if (pMsg->bodyptr) + { + status = csrMsgProcessor(hHal, pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + smsLog( pMac, LOGE, "Empty rsp message for CSR, nothing to process"); + } + } + else + { + smsLog( pMac, LOGW, "Unknown message type %d, nothing to process", + pMsg->type); + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + }//switch + } //SME_IS_START + else + { + smsLog( pMac, LOGW, "message type %d in stop state ignored", pMsg->type); + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + smsLog( pMac, LOGW, "Locking failed, bailing out"); + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + + return status; +} + + +//No need to hold the global lock here because this function can only be called +//after sme_Stop. +v_VOID_t sme_FreeMsg( tHalHandle hHal, vos_msg_t* pMsg ) +{ + if( pMsg ) + { + if (pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + } + +} + + +/*-------------------------------------------------------------------------- + + \brief sme_Stop() - Stop all SME modules and put them at idle state + + The function stops each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at idle state ready to start. + + This is a synchronous call + \param hHal - The handle returned by macOpen + \param tHalStopType - reason for stopping + + \return eHAL_STATUS_SUCCESS - SME is stopped. + + Other status means SME is failed to stop but caller should still + consider SME is stopped. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Stop(tHalHandle hHal, tHalStopType stopType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + eHalStatus fail_status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = WLANSAP_Stop(vos_get_global_context(VOS_MODULE_ID_SAP, NULL)); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "WLANSAP_Stop failed during smeStop with status=%d", + status ); + fail_status = status; + } + + p2pStop(hHal); + + status = pmcStop(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "pmcStop failed during smeStop with status=%d", + status ); + fail_status = status; + } + + status = csrStop(pMac, stopType); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrStop failed during smeStop with status=%d", + status ); + fail_status = status; + } + + ccmStop(hHal); + + purgeSmeCmdList(pMac); + + if (!HAL_STATUS_SUCCESS( fail_status )) { + status = fail_status; + } + + pMac->sme.state = SME_STATE_STOP; + + return status; +} + +/*-------------------------------------------------------------------------- + + \brief sme_Close() - Release all SME modules and their resources. + + The function release each module in SME, PMC, CCM, CSR, etc. . Upon + return, all modules are at closed state. + + No SME APIs can be involved after smeClose except smeOpen. + smeClose must be called before macClose. + This is a synchronous call + \param hHal - The handle returned by macOpen + + \return eHAL_STATUS_SUCCESS - SME is successfully close. + + Other status means SME is failed to be closed but caller still cannot + call any other SME functions except smeOpen. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_Close(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + eHalStatus fail_status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = csrClose(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "csrClose failed during sme close with status=%d", + status ); + fail_status = status; + } + + status = WLANSAP_Close(vos_get_global_context(VOS_MODULE_ID_SAP, NULL)); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "WLANSAP_close failed during sme close with status=%d", + status ); + fail_status = status; + } + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + status = btcClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "BTC close failed during sme close with status=%d", + status ); + fail_status = status; + } + + status = sme_QosClose(pMac); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "Qos close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif +#ifdef FEATURE_OEM_DATA_SUPPORT + status = oemData_OemDataReqClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "OEM DATA REQ close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif + + status = ccmClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "ccmClose failed during sme close with status=%d", + status ); + fail_status = status; + } + + status = pmcClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "pmcClose failed during sme close with status=%d", + status ); + fail_status = status; + } +#if defined WLAN_FEATURE_VOWIFI + status = rrmClose(hHal); + if ( ! HAL_STATUS_SUCCESS( status ) ) { + smsLog( pMac, LOGE, "RRM close failed during sme close with status=%d", + status ); + fail_status = status; + } +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + sme_FTClose(hHal); +#endif + sme_p2pClose(hHal); + + freeSmeCmdList(pMac); + + if( !VOS_IS_STATUS_SUCCESS( vos_lock_destroy( &pMac->sme.lkSmeGlobalLock ) ) ) + { + fail_status = eHAL_STATUS_FAILURE; + } + + if (!HAL_STATUS_SUCCESS( fail_status )) { + status = fail_status; + } + + pMac->sme.state = SME_STATE_STOP; + + return status; +} + +v_VOID_t sme_PreClose(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if(!pMac) + return; + + smsLog(pMac, LOGW, FL("Stopping Active CMD List Timer")); + vos_timer_stop( pMac->sme.smeCmdActiveList.cmdTimeoutTimer ); + +} + +#ifdef FEATURE_WLAN_LFR +tANI_BOOLEAN csrIsScanAllowed(tpAniSirGlobal pMac) +{ +#if 0 + switch(pMac->roam.neighborRoamInfo.neighborRoamState) { + case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING: + case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE: + case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING: + return eANI_BOOLEAN_FALSE; + default: + return eANI_BOOLEAN_TRUE; + } +#else + /* + * TODO: always return TRUE for now until + * we figure out why we could be stuck in + * one of the roaming states forever. + */ + return eANI_BOOLEAN_TRUE; +#endif +} +#endif + +/* --------------------------------------------------------------------------- + \fn sco_isScanAllowed + \brief check for scan interface connection status + \param pMac - Pointer to the global MAC parameter structure + \param pScanReq - scan request structure. + + \return tANI_BOOLEAN TRUE to allow scan otherwise FALSE + ---------------------------------------------------------------------------*/ +tANI_BOOLEAN sco_isScanAllowed(tpAniSirGlobal pMac, tCsrScanRequest *pscanReq) +{ + tANI_BOOLEAN ret; + + if (pscanReq->p2pSearch) + ret = csrIsP2pSessionConnected(pMac); + else + ret = csrIsStaSessionConnected(pMac); + + return !ret; +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanRequest + \brief a wrapper function to Request a 11d or full scan from CSR. + This is an asynchronous call + \param pScanRequestID - pointer to an object to get back the request ID + \param callback - a callback function that scan calls upon finish, will not + be called if csrScanRequest returns error + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanRequest(tHalHandle hHal, tANI_U8 sessionId, tCsrScanRequest *pscanReq, + tANI_U32 *pScanRequestID, + csrScanCompleteCallback callback, void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ, sessionId, pscanReq->scanType)); + + smsLog(pMac, LOG1, + FL("isCoexScoIndSet %d disable_scan_during_sco %d is_disconnected %d"), + pMac->isCoexScoIndSet, + pMac->scan.disable_scan_during_sco, + csrIsConnStateDisconnected(pMac, sessionId)); + + if (pMac->isCoexScoIndSet && pMac->scan.disable_scan_during_sco && + csrIsConnStateDisconnected(pMac, sessionId)) { + csrScanFlushResult(pMac); + pMac->scan.disable_scan_during_sco_timer_info.callback = callback; + pMac->scan.disable_scan_during_sco_timer_info.dev = pContext; + pMac->scan.disable_scan_during_sco_timer_info.scan_id= *pScanRequestID; + + vos_timer_start(&pMac->scan.disable_scan_during_sco_timer, + CSR_DISABLE_SCAN_DURING_SCO); + return eHAL_STATUS_SUCCESS; + } + + do + { + if(pMac->scan.fScanEnable && + (pMac->isCoexScoIndSet ? sco_isScanAllowed(pMac, pscanReq) : TRUE)) + { + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + { +#ifdef FEATURE_WLAN_LFR + if(csrIsScanAllowed(pMac)) + { +#endif + status = csrScanRequest( hHal, sessionId, pscanReq, + pScanRequestID, callback, pContext ); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGE, FL("csrScanRequest failed" + " SId=%d"), sessionId); + } +#ifdef FEATURE_WLAN_LFR + } + else + { + smsLog(pMac, LOGE, FL("Scan denied in state %s" + "(sub-state %s)"), + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState), + macTraceGetcsrRoamSubState( + pMac->roam.curSubState[sessionId])); + /*HandOff is in progress. So schedule this scan later*/ + status = eHAL_STATUS_RESOURCES; + } +#endif + } + + sme_ReleaseGlobalLock( &pMac->sme ); + } //sme_AcquireGlobalLock success + else + { + smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed")); + } + } //if(pMac->scan.fScanEnable) + else + { + smsLog(pMac, LOGE, FL("fScanEnable %d isCoexScoIndSet: %d "), + pMac->scan.fScanEnable, pMac->isCoexScoIndSet); + status = eHAL_STATUS_RESOURCES; + } + } while( 0 ); + + return (status); + + +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetResult + \brief a wrapper function to request scan results from CSR. + This is a synchronous call + \param pFilter - If pFilter is NULL, all cached results are returned + \param phResult - an object for the result. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetResult(tHalHandle hHal, tANI_U8 sessionId, tCsrScanResultFilter *pFilter, + tScanResultHandle *phResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS, sessionId,0 )); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanGetResult( hHal, pFilter, phResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + smsLog(pMac, LOG2, FL("exit status %d"), status); + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanFlushResult + \brief a wrapper function to request CSR to clear scan results. + This is a synchronous call + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanFlushResult(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, sessionId,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanFlushResult( hHal ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_FilterScanResults + \brief a wrapper function to request CSR to clear scan results. + This is a synchronous call + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_FilterScanResults(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(macTraceNew(pMac, VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS, sessionId,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + csrScanFilterResults(pMac); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + /* + * --------------------------------------------------------------------------- + * \fn sme_FilterScanDFSResults + * \brief a wrapper function to request CSR to filter BSSIDs on DFS channels + * from the scan results. + * \return eHalStatus + *--------------------------------------------------------------------------- + */ +eHalStatus sme_FilterScanDFSResults(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + csrScanFilterDFSResults(pMac); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_ScanFlushP2PResult(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS, sessionId,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanFlushSelectiveResult( hHal, VOS_TRUE ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetFirst + \brief a wrapper function to request CSR to returns the first element of + scan result. + This is a synchronous call + \param hScanResult - returned from csrScanGetResult + \return tCsrScanResultInfo * - NULL if no result + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetFirst(tHalHandle hHal, + tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrScanResultInfo *pRet = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST, NO_SESSION,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pRet = csrScanResultGetFirst( pMac, hScanResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (pRet); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultGetNext + \brief a wrapper function to request CSR to returns the next element of + scan result. It can be called without calling csrScanResultGetFirst + first + This is a synchronous call + \param hScanResult - returned from csrScanGetResult + \return Null if no result or reach the end + ---------------------------------------------------------------------------*/ +tCsrScanResultInfo *sme_ScanResultGetNext(tHalHandle hHal, + tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrScanResultInfo *pRet = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pRet = csrScanResultGetNext( pMac, hScanResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (pRet); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanSetBGScanparams + \brief a wrapper function to request CSR to set BG scan params in PE + This is a synchronous call + \param pScanReq - BG scan request structure + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanSetBGScanparams(tHalHandle hHal, tANI_U8 sessionId, tCsrBGScanRequest *pScanReq) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if( NULL != pScanReq ) + { + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanSetBGScanparams( hHal, pScanReq ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ScanResultPurge + \brief a wrapper function to request CSR to remove all items(tCsrScanResult) + in the list and free memory for each item + This is a synchronous call + \param hScanResult - returned from csrScanGetResult. hScanResult is + considered gone by + calling this function and even before this function reutrns. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanResultPurge(tHalHandle hHal, tScanResultHandle hScanResult) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE, NO_SESSION,0 )); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanResultPurge( hHal, hScanResult ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetPMKIDCandidateList + \brief a wrapper function to return the PMKID candidate list + This is a synchronous call + \param pPmkidList - caller allocated buffer point to an array of + tPmkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tPmkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tPmkidCandidateInfo. + \Note: pNumItems is a number of tPmkidCandidateInfo, + not sizeof(tPmkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetPMKIDCandidateList(tHalHandle hHal, tANI_U8 sessionId, + tPmkidCandidateInfo *pPmkidList, + tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanGetPMKIDCandidateList( pMac, sessionId, pPmkidList, pNumItems ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*---------------------------------------------------------------------------- + \fn sme_RoamRegisterLinkQualityIndCallback + + \brief + a wrapper function to allow HDD to register a callback handler with CSR for + link quality indications. + + Only one callback may be registered at any time. + In order to deregister the callback, a NULL cback may be provided. + + Registration happens in the task context of the caller. + + \param callback - Call back being registered + \param pContext - user data + + DEPENDENCIES: After CSR open + + \return eHalStatus +-----------------------------------------------------------------------------*/ +eHalStatus sme_RoamRegisterLinkQualityIndCallback(tHalHandle hHal, tANI_U8 sessionId, + csrRoamLinkQualityIndCallback callback, + void *pContext) +{ + return(csrRoamRegisterLinkQualityIndCallback((tpAniSirGlobal)hHal, callback, pContext)); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamRegisterCallback + \brief a wrapper function to allow HDD to register a callback with CSR. + Unlike scan, roam has one callback for all the roam requests + \param callback - a callback function that roam calls upon when state changes + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamRegisterCallback(tHalHandle hHal, + csrRoamCompleteCallback callback, + void *pContext) +{ + return(csrRoamRegisterCallback((tpAniSirGlobal)hHal, callback, pContext)); +} + +eCsrPhyMode sme_GetPhyMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + return pMac->roam.configParam.phyMode; +} + +/* --------------------------------------------------------------------------- + \fn sme_GetChannelBondingMode5G + \brief get the channel bonding mode for 5G band + \param hHal - HAL handle + \return channel bonding mode for 5G + ---------------------------------------------------------------------------*/ +tANI_U32 sme_GetChannelBondingMode5G(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeConfigParams smeConfig; + + sme_GetConfigParam(pMac, &smeConfig); + + return smeConfig.csrConfig.channelBondingMode5GHz; +} + +#ifdef WLAN_FEATURE_AP_HT40_24G +/* --------------------------------------------------------------------------- + \fn sme_GetChannelBondingMode24G + \brief get the channel bonding mode for 2.4G band + \param hHal - HAL handle + \return channel bonding mode for 2.4G + ---------------------------------------------------------------------------*/ +tANI_U32 sme_GetChannelBondingMode24G(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeConfigParams smeConfig; + + sme_GetConfigParam(pMac, &smeConfig); + + return smeConfig.csrConfig.channelBondingAPMode24GHz; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateChannelBondingMode24G + \brief update the channel bonding mode for 2.4G band + \param hHal - HAL handle + \param cbMode - channel bonding mode + \return + ---------------------------------------------------------------------------*/ +void sme_UpdateChannelBondingMode24G(tHalHandle hHal, tANI_U8 cbMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tSmeConfigParams smeConfig; + + vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams)); + sme_GetConfigParam(pMac, &smeConfig); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("Previous Channel Bonding : = %d"), + smeConfig.csrConfig.channelBondingAPMode24GHz); + + smeConfig.csrConfig.channelBondingAPMode24GHz = cbMode; + sme_UpdateConfig(hHal, &smeConfig); + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO, + FL("New Channel Bonding : = %d"), + sme_GetChannelBondingMode24G(hHal)); + return; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetHT2040Mode + + \brief To update HT Operation beacon IE & Channel Bonding. + + \param + + \return eHalStatus SUCCESS + FAILURE or RESOURCES + The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, tANI_U8 cbMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Channel Bonding =%d"), + cbMode); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + status = csrSetHT2040Mode(pMac, sessionId, cbMode); + sme_ReleaseGlobalLock(&pMac->sme ); + } + return (status); +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnect + \brief a wrapper function to request CSR to inititiate an association + This is an asynchronous call. + \param sessionId - the sessionId returned by sme_OpenSession. + \param pProfile - description of the network to which to connect + \param hBssListIn - a list of BSS descriptor to roam to. It is returned + from csrScanGetResult + \param pRoamId - to get back the request ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnect(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (!pMac) + { + return eHAL_STATUS_FAILURE; + } + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0)); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamConnect( pMac, sessionId, pProfile, NULL, pRoamId ); + } + else + { + smsLog(pMac, LOGE, FL("invalid sessionID %d"), sessionId); + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed")); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetPhyMode + + \brief Changes the PhyMode. + + \param hHal - The handle returned by macOpen. + + \param phyMode new phyMode which is to set + + \return eHalStatus SUCCESS. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetPhyMode(tHalHandle hHal, eCsrPhyMode phyMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return eHAL_STATUS_FAILURE; + } + + pMac->roam.configParam.phyMode = phyMode; + pMac->roam.configParam.uCfgDot11Mode = csrGetCfgDot11ModeFromCsrPhyMode(NULL, + pMac->roam.configParam.phyMode, + pMac->roam.configParam.ProprietaryRatesEnabled); + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamReassoc + \brief a wrapper function to request CSR to inititiate a re-association + \param pProfile - can be NULL to join the currently connected AP. In that + case modProfileFields should carry the modified field(s) which could trigger + reassoc + \param modProfileFields - fields which are part of tCsrRoamConnectedProfile + that might need modification dynamically once STA is up & running and this + could trigger a reassoc + \param pRoamId - to get back the request ID + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamReassoc(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamProfile *pProfile, + tCsrRoamModifyProfileFields modProfileFields, + tANI_U32 *pRoamId, v_BOOL_t fForce) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_REASSOC, sessionId, 0)); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + if((NULL == pProfile) && (fForce == 1)) + { + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + /* to force the AP initiate fresh 802.1x authentication need to clear + * the PMKID cache for that set the following boolean. this is needed + * by the HS 2.0 passpoint certification 5.2.a and b testcases */ + pSession->fIgnorePMKIDCache = TRUE; + status = csrReassoc( pMac, sessionId, &modProfileFields, pRoamId , fForce); + } + else + { + status = csrRoamReassoc( pMac, sessionId, pProfile, modProfileFields, pRoamId ); + } + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamConnectToLastProfile + \brief a wrapper function to request CSR to disconnect and reconnect with + the same profile + This is an asynchronous call. + \return eHalStatus. It returns fail if currently connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamConnectToLastProfile(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamConnectToLastProfile( pMac, sessionId ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnect + \brief a wrapper function to request CSR to disconnect from a network + This is an asynchronous call. + \param reason -- To indicate the reason for disconnecting. Currently, only + eCSR_DISCONNECT_REASON_MIC_ERROR is meanful. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDisconnectReason reason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT, sessionId, reason)); + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + /* + * Indicate csr of disconnect so that + * in progress connection, scan for ssid and preauth + * can be aborted + */ + csr_abortConnection(pMac, sessionId); + status = csrRoamDisconnect(pMac, sessionId, reason); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn.sme_abortConnection + \brief a wrapper function to request CSR to stop from connecting a network + \retun void. +---------------------------------------------------------------------------*/ + +void sme_abortConnection(tHalHandle hHal, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + csr_abortConnection( pMac, sessionId); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return; +} + +/* sme_dhcp_done_ind() - send dhcp done ind + * @hal: hal context + * @session_id: session id + * + * Return: void. + */ +void sme_dhcp_done_ind(tHalHandle hal, uint8_t session_id) +{ + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + tCsrRoamSession *session; + + if (!mac_ctx) + return; + + session = CSR_GET_SESSION(mac_ctx, session_id); + if(!session) + { + smsLog(mac_ctx, LOGE, FL(" session %d not found "), session_id); + return; + } + session->dhcp_done = true; +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamStopBss + \brief To stop BSS for Soft AP. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamStopBss(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueStopBssCmd( pMac, sessionId, eANI_BOOLEAN_FALSE ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamDisconnectSta + \brief To disassociate a station. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDisconnectSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pPeerMacAddr +#else + tANI_U8 *pPeerMacAddr +#endif +) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueDisassociateStaCmd( pMac, sessionId, pPeerMacAddr, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamDeauthSta + \brief To disassociate a station. This is an asynchronous API. + \param hHal - Global structure + \param sessionId - sessionId of SoftAP + \param pDelStaParams -Pointer to parameters of the station to deauthenticate + \return eHalStatus SUCCESS Roam callback will be called to indicate actual results + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamDeauthSta(tHalHandle hHal, tANI_U8 sessionId, + struct tagCsrDelStaParams *pDelStaParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA, + sessionId, pDelStaParams->reason_code)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueDeauthStaCmd( pMac, sessionId, pDelStaParams); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamTKIPCounterMeasures + \brief To start or stop TKIP counter measures. This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param pPeerMacAddr - Caller allocated memory filled with peer MAC address (6 bytes) + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamTKIPCounterMeasures(tHalHandle hHal, tANI_U8 sessionId, + tANI_BOOLEAN bEnable) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamIssueTkipCounterMeasures( pMac, sessionId, bEnable); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetAssociatedStas + \brief To probe the list of associated stations from various modules of CORE stack. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param modId - Module from whom list of associtated stations is to be probed. + If an invalid module is passed then by default VOS_MODULE_ID_PE will be probed + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \param pAssocBuf - Caller allocated memory to be filled with associatd stations info + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetAssociatedStas(tHalHandle hHal, tANI_U8 sessionId, + VOS_MODULE_ID modId, void *pUsrContext, + void *pfnSapEventCallback, tANI_U8 *pAssocStasBuf) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetAssociatedStas( pMac, sessionId, modId, pUsrContext, pfnSapEventCallback, pAssocStasBuf ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetWpsSessionOverlap + \brief To get the WPS PBC session overlap information. + \This is an asynchronous API. + \param sessionId - sessionId of SoftAP + \param pUsrContext - Opaque HDD context + \param pfnSapEventCallback - Sap event callback in HDD + \pRemoveMac - pointer to Mac address which needs to be removed from session + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetWpsSessionOverlap(tHalHandle hHal, tANI_U8 sessionId, + void *pUsrContext, void + *pfnSapEventCallback, v_MACADDR_t pRemoveMac) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( NULL == pMac ) + { + VOS_ASSERT(0); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetWpsSessionOverlap( pMac, sessionId, pUsrContext, pfnSapEventCallback, pRemoveMac); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectState + \brief a wrapper function to request CSR to return the current connect state + of Roaming + This is a synchronous call. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectState(tHalHandle hHal, tANI_U8 sessionId, eCsrConnectState *pState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetConnectState( pMac, sessionId, pState ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetConnectProfile + \brief a wrapper function to request CSR to return the current connect + profile. Caller must call csrRoamFreeConnectProfile after it is done + and before reuse for another csrRoamGetConnectProfile call. + This is a synchronous call. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. Failure if not connected + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetConnectProfile(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetConnectProfile( pMac, sessionId, pProfile ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamFreeConnectProfile + \brief a wrapper function to request CSR to free and reinitialize the + profile returned previously by csrRoamGetConnectProfile. + This is a synchronous call. + \param pProfile - pointer to a caller allocated structure + tCsrRoamConnectedProfile + \return eHalStatus. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamFreeConnectProfile(tHalHandle hHal, + tCsrRoamConnectedProfile *pProfile) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamFreeConnectProfile( pMac, pProfile ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamSetPMKIDCache + \brief a wrapper function to request CSR to return the PMKID candidate list + This is a synchronous call. + \param pPMKIDCache - caller allocated buffer point to an array of + tPmkidCacheInfo + \param numItems - a variable that has the number of tPmkidCacheInfo + allocated when retruning, this is either the number needed + or number of items put into pPMKIDCache + \param update_entire_cache - this bool value specifies if the entire pmkid + cache should be overwritten or should it be + updated entry by entry. + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems has the number of + tPmkidCacheInfo. + \Note: pNumItems is a number of tPmkidCacheInfo, + not sizeof(tPmkidCacheInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetPMKIDCache( tHalHandle hHal, tANI_U8 sessionId, + tPmkidCacheInfo *pPMKIDCache, + tANI_U32 numItems, + tANI_BOOLEAN update_entire_cache ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE, sessionId, numItems)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamSetPMKIDCache( pMac, sessionId, pPMKIDCache, + numItems, update_entire_cache ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_RoamDelPMKIDfromCache( tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tANI_U8 *pBSSId, +#else + tANI_U8 *pBSSId, +#endif + tANI_BOOLEAN flush_cache ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE, sessionId, flush_cache)); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamDelPMKIDfromCache( pMac, sessionId, + pBSSId, flush_cache ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityReqIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE CSR + passes to PE to JOIN request or START_BSS request + This is a synchronous call. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityReqIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetWpaRsnReqIE( hHal, sessionId, pLen, pBuf ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetSecurityRspIE + \brief a wrapper function to request CSR to return the WPA or RSN or WAPI IE from + the beacon or probe rsp if connected + This is a synchronous call. + \param pLen - caller allocated memory that has the length of pBuf as input. + Upon returned, *pLen has the needed or IE length in pBuf. + \param pBuf - Caller allocated memory that contain the IE field, if any, + upon return + \param secType - Specifies whether looking for WPA/WPA2/WAPI IE + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetSecurityRspIE(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pLen, + tANI_U8 *pBuf, eCsrSecurityType secType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetWpaRsnRspIE( pMac, sessionId, pLen, pBuf ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + +} + + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetNumPMKIDCache + \brief a wrapper function to request CSR to return number of PMKID cache + entries + This is a synchronous call. + \return tANI_U32 - the number of PMKID cache entries + ---------------------------------------------------------------------------*/ +tANI_U32 sme_RoamGetNumPMKIDCache(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 numPmkidCache = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + numPmkidCache = csrRoamGetNumPMKIDCache( pMac, sessionId ); + status = eHAL_STATUS_SUCCESS; + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (numPmkidCache); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetPMKIDCache + \brief a wrapper function to request CSR to return PMKID cache from CSR + This is a synchronous call. + \param pNum - caller allocated memory that has the space of the number of + pBuf tPmkidCacheInfo as input. Upon returned, *pNum has the + needed or actually number in tPmkidCacheInfo. + \param pPmkidCache - Caller allocated memory that contains PMKID cache, if + any, upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetPMKIDCache(tHalHandle hHal, tANI_U8 sessionId, tANI_U32 *pNum, + tPmkidCacheInfo *pPmkidCache) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrRoamGetPMKIDCache( pMac, sessionId, pNum, pPmkidCache ); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetConfigParam + \brief a wrapper function that HDD calls to get the global settings + currently maintained by CSR. + This is a synchronous call. + \param pParam - caller allocated memory + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetConfigParam(pMac, &pParam->csrConfig); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, "%s csrGetConfigParam failed", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } +#if defined WLAN_FEATURE_P2P_INTERNAL + status = p2pGetConfigParam(pMac, &pParam->p2pConfig); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, "%s p2pGetConfigParam failed", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } +#endif + pParam->fBtcEnableIndTimerVal = pMac->fBtcEnableIndTimerVal; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetInt + \brief a wrapper function that HDD calls to set parameters in CFG. + This is a synchronous call. + \param cfgId - Configuration Parameter ID (type) for STA. + \param ccmValue - The information related to Configuration Parameter ID + which needs to be saved in CFG + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetInt(tHalHandle hHal, tANI_U32 cfgId, tANI_U32 ccmValue, + tCcmCfgSetCallback callback, eAniBoolean toBeSaved) +{ + return(ccmCfgSetInt(hHal, cfgId, ccmValue, callback, toBeSaved)); +} + +/* --------------------------------------------------------------------------- + \fn sme_CfgSetStr + \brief a wrapper function that HDD calls to set parameters in CFG. + This is a synchronous call. + \param cfgId - Configuration Parameter ID (type) for STA. + \param pStr - Pointer to the byte array which carries the information needs + to be saved in CFG + \param length - Length of the data to be saved + \param callback - To be registered by CSR with CCM. Once the CFG done with + saving the information in the database, it notifies CCM & + then the callback will be invoked to notify. + \param toBeSaved - To save the request for future reference + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_CfgSetStr(tHalHandle hHal, tANI_U32 cfgId, tANI_U8 *pStr, + tANI_U32 length, tCcmCfgSetCallback callback, + eAniBoolean toBeSaved) +{ + return(ccmCfgSetStr(hHal, cfgId, pStr, length, callback, toBeSaved)); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetModifyProfileFields + \brief HDD or SME - QOS calls this function to get the current values of + connected profile fields, changing which can cause reassoc. + This function must be called after CFG is downloaded and STA is in connected + state. Also, make sure to call this function to get the current profile + fields before calling the reassoc. So that pModifyProfileFields will have + all the latest values plus the one(s) has been updated as part of reassoc + request. + \param pModifyProfileFields - pointer to the connected profile fields + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetModifyProfileFields(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamModifyProfileFields * pModifyProfileFields) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + status = csrGetModifyProfileFields(pMac, sessionId, pModifyProfileFields); + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_HT40StopOBSSScan + \brief HDD or SME - Command to stop the OBSS scan + THis is implemented only for debugging purpose. + As per spec while operating in 2.4GHz OBSS scan shouldnt be stopped. + \param sessionId - sessionId + changing which can cause reassoc + + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_HT40StopOBSSScan(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if( CSR_IS_SESSION_VALID( pMac, sessionId ) ) + { + csrHT40StopOBSSScan( pMac, sessionId ); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid session sessionId %d", __func__,sessionId); + status = eHAL_STATUS_INVALID_PARAMETER; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/*-------------------------------------------------------------------------- + \fn sme_SetConfigPowerSave + \brief Wrapper fn to change power save configuration in SME (PMC) module. + For BMPS related configuration, this function also updates the CFG + and sends a message to FW to pick up the new values. Note: Calling + this function only updates the configuration and does not enable + the specified power save mode. + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode being modified + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_SetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE, NO_SESSION, 0)); + if (NULL == pConfigParams ) { + smsLog( pMac, LOGE, "Empty config param structure for PMC, " + "nothing to update"); + return eHAL_STATUS_FAILURE; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcSetConfigPowerSave(hHal, psMode, pConfigParams); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*-------------------------------------------------------------------------- + \fn sme_GetConfigPowerSave + \brief Wrapper fn to retrieve power save configuration in SME (PMC) module + \param hHal - The handle returned by macOpen. + \param psMode - Power Saving mode + \param pConfigParams - a pointer to a caller allocated object of type + tPmcSmpsConfigParams or tPmcBmpsConfigParams or tPmcImpsConfigParams + \return eHalStatus + --------------------------------------------------------------------------*/ +eHalStatus sme_GetConfigPowerSave(tHalHandle hHal, tPmcPowerSavingMode psMode, + void *pConfigParams) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE, NO_SESSION, 0)); + if (NULL == pConfigParams ) { + smsLog( pMac, LOGE, "Empty config param structure for PMC, " + "nothing to update"); + return eHAL_STATUS_FAILURE; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcGetConfigPowerSave(hHal, psMode, pConfigParams); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_SignalPowerEvent + \brief Signals to PMC that a power event has occurred. Used for putting + the chip into deep sleep mode. + \param hHal - The handle returned by macOpen. + \param event - the event that has occurred + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SignalPowerEvent (tHalHandle hHal, tPmcPowerEvent event) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcSignalPowerEvent(hHal, event); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_EnablePowerSave + \brief Enables one of the power saving modes. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to enable. If BMPS mode is enabled + while the chip is operating in Full Power, PMC will start + a timer that will try to put the chip in BMPS mode after + expiry. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_EnablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE, NO_SESSION, psMode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcEnablePowerSave(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_DisablePowerSave + \brief Disables one of the power saving modes. + \param hHal - The handle returned by macOpen. + \param psMode - The power saving mode to disable. Disabling does not imply + that device will be brought out of the current PS mode. This + is purely a configuration API. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_DisablePowerSave (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE, NO_SESSION, psMode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcDisablePowerSave(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + } + +/* --------------------------------------------------------------------------- ++ \fn sme_SetHostPowerSave ++ \brief Enables BMPS logic to be controlled by User level apps ++ \param hHal - The handle returned by macOpen. ++ \param psMode - The power saving mode to disable. Disabling does not imply ++ that device will be brought out of the current PS mode. This ++ is purely a configuration API. ++ \return eHalStatus ++ ---------------------------------------------------------------------------*/ +eHalStatus sme_SetHostPowerSave (tHalHandle hHal, v_BOOL_t psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->pmc.isHostPsEn = psMode; + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_StartAutoBmpsTimer + \brief Starts a timer that periodically polls all the registered + module for entry into Bmps mode. This timer is started only if BMPS is + enabled and whenever the device is in full power. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StartAutoBmpsTimer ( tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStartAutoBmpsTimer(hHal); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_StopAutoBmpsTimer + \brief Stops the Auto BMPS Timer that was started using sme_startAutoBmpsTimer + Stopping the timer does not cause a device state change. Only the timer + is stopped. If "Full Power" is desired, use the sme_RequestFullPower API + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StopAutoBmpsTimer ( tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStopAutoBmpsTimer(hHal); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_QueryPowerState + \brief Returns the current power state of the device. + \param hHal - The handle returned by macOpen. + \param pPowerState - pointer to location to return power state (LOW or HIGH) + \param pSwWlanSwitchState - ptr to location to return SW WLAN Switch state + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_QueryPowerState ( + tHalHandle hHal, + tPmcPowerState *pPowerState, + tPmcSwitchState *pSwWlanSwitchState) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcQueryPowerState (hHal, pPowerState, NULL, pSwWlanSwitchState); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_IsPowerSaveEnabled + \brief Checks if the device is able to enter a particular power save mode + This does not imply that the device is in a particular PS mode + \param hHal - The handle returned by macOpen. + \param psMode - the power saving mode + \return eHalStatus + ---------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal, tPmcPowerSavingMode psMode) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_BOOLEAN result = false; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED, NO_SESSION, psMode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + result = pmcIsPowerSaveEnabled(hHal, psMode); + sme_ReleaseGlobalLock( &pMac->sme ); + return result; + } + + return false; +} + +/* --------------------------------------------------------------------------- + \fn sme_RequestFullPower + \brief Request that the device be brought to full power state. When the + device enters Full Power PMC will start a BMPS timer if BMPS PS mode + is enabled. On timer expiry PMC will attempt to put the device in + BMPS mode if following holds true: + - BMPS mode is enabled + - Polling of all modules through the Power Save Check routine passes + - STA is associated to an access point + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \return eHalStatus - status + eHAL_STATUS_SUCCESS - device brought to full power state + eHAL_STATUS_FAILURE - device cannot be brought to full power state + eHAL_STATUS_PMC_PENDING - device is being brought to full power state, + ---------------------------------------------------------------------------*/ +eHalStatus sme_RequestFullPower ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext, + tRequestFullPowerReason fullPowerReason) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER, NO_SESSION, fullPowerReason)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestFullPower(hHal, callbackRoutine, callbackContext, fullPowerReason); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RequestBmps + \brief Request that the device be put in BMPS state. Request will be + accepted only if BMPS mode is enabled and power save check routine + passes. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought to BMPS state + eHAL_STATUS_PMC_PENDING - device is being brought to BMPS state + ---------------------------------------------------------------------------*/ +eHalStatus sme_RequestBmps ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REQUEST_BMPS, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestBmps(hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_SetDHCPTillPowerActiveFlag + \brief Sets/Clears DHCP related flag in PMC to disable/enable auto BMPS + entry by PMC + \param hHal - The handle returned by macOpen. + ---------------------------------------------------------------------------*/ +void sme_SetDHCPTillPowerActiveFlag(tHalHandle hHal, tANI_U8 flag) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG, NO_SESSION, flag)); + // Set/Clear the DHCP flag which will disable/enable auto BMPS entery by PMC + pMac->pmc.remainInPowerActiveTillDHCP = flag; +} + + +/* --------------------------------------------------------------------------- + \fn sme_StartUapsd + \brief Request that the device be put in UAPSD state. If the device is in + Full Power it will be put in BMPS mode first and then into UAPSD + mode. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + eHAL_STATUS_SUCCESS - device is in UAPSD state + eHAL_STATUS_FAILURE - device cannot be brought to UAPSD state + eHAL_STATUS_PMC_PENDING - device is being brought to UAPSD state + eHAL_STATUS_PMC_DISABLED - UAPSD is disabled or BMPS mode is disabled + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StartUapsd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStartUapsd(hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + } + +/* --------------------------------------------------------------------------- + \fn sme_StopUapsd + \brief Request that the device be put out of UAPSD state. Device will be + put in in BMPS state after stop UAPSD completes. + \param hHal - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_SUCCESS - device is put out of UAPSD and back in BMPS state + eHAL_STATUS_FAILURE - device cannot be brought out of UAPSD state + ---------------------------------------------------------------------------*/ +eHalStatus sme_StopUapsd (tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcStopUapsd(hHal); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RequestStandby + \brief Request that the device be put in standby. It is HDD's responsibility + to bring the chip to full power and do a disassoc before calling + this API. + \param hHal - The handle returned by macOpen. + \param - callbackRoutine Callback routine invoked in case of success/failure + \return eHalStatus + eHAL_STATUS_SUCCESS - device is in Standby mode + eHAL_STATUS_FAILURE - device cannot be put in standby mode + eHAL_STATUS_PMC_PENDING - device is being put in standby mode + ---------------------------------------------------------------------------*/ +eHalStatus sme_RequestStandby ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, eHalStatus status), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY, NO_SESSION, 0)); + smsLog( pMac, LOG1, FL(" called") ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestStandby(hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RegisterPowerSaveCheck + \brief Register a power save check routine that is called whenever + the device is about to enter one of the power save modes. + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be registered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +eHalStatus sme_RegisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext), void *checkContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRegisterPowerSaveCheck (hHal, checkRoutine, checkContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_Register11dScanDoneCallback + \brief Register a routine of type csrScanCompleteCallback which is + called whenever an 11d scan is done + \param hHal - The handle returned by macOpen. + \param callback - 11d scan complete routine to be registered + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_Register11dScanDoneCallback ( + tHalHandle hHal, + csrScanCompleteCallback callback) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->scan.callback11dScanDone = callback; + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterPowerSaveCheck + \brief Deregister a power save check routine + \param hHal - The handle returned by macOpen. + \param checkRoutine - Power save check routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterPowerSaveCheck ( + tHalHandle hHal, + tANI_BOOLEAN (*checkRoutine) (void *checkContext)) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcDeregisterPowerSaveCheck (hHal, checkRoutine); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RegisterDeviceStateUpdateInd + \brief Register a callback routine that is called whenever + the device enters a new device state (Full Power, BMPS, UAPSD) + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be registered + \param callbackContext - Cookie to be passed back during callback + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully registered + eHAL_STATUS_FAILURE - not successfully registered + ---------------------------------------------------------------------------*/ +eHalStatus sme_RegisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRegisterDeviceStateUpdateInd (hHal, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_DeregisterDeviceStateUpdateInd + \brief Deregister a routine that was registered for device state changes + \param hHal - The handle returned by macOpen. + \param callbackRoutine - Callback routine to be deregistered + \return eHalStatus + eHAL_STATUS_SUCCESS - successfully deregistered + eHAL_STATUS_FAILURE - not successfully deregistered + ---------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterDeviceStateUpdateInd ( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackContext, tPmcState pmcState)) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcDeregisterDeviceStateUpdateInd (hHal, callbackRoutine); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_WowlAddBcastPattern + \brief Add a pattern for Pattern Byte Matching in Wowl mode. Firmware will + do a pattern match on these patterns when Wowl is enabled during BMPS + mode. Note that Firmware performs the pattern matching only on + broadcast frames and while Libra is in BMPS mode. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be added + \return eHalStatus + eHAL_STATUS_FAILURE Cannot add pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus sme_WowlAddBcastPattern ( + tHalHandle hHal, + tpSirWowlAddBcastPtrn pattern, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcWowlAddBcastPattern (hHal, pattern, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_WowlDelBcastPattern + \brief Delete a pattern that was added for Pattern Byte Matching. + \param hHal - The handle returned by macOpen. + \param pattern - Pattern to be deleted + \return eHalStatus + eHAL_STATUS_FAILURE Cannot delete pattern + eHAL_STATUS_SUCCESS Request accepted. + ---------------------------------------------------------------------------*/ +eHalStatus sme_WowlDelBcastPattern ( + tHalHandle hHal, + tpSirWowlDelBcastPtrn pattern, + tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcWowlDelBcastPattern (hHal, pattern, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_EnterWowl + \brief This is the SME API exposed to HDD to request enabling of WOWL mode. + WoWLAN works on top of BMPS mode. If the device is not in BMPS mode, + SME will will cache the information that WOWL has been enabled and + attempt to put the device in BMPS. On entry into BMPS, SME will + enable the WOWL mode. + Note 1: If we exit BMPS mode (someone requests full power), we + will NOT resume WOWL when we go back to BMPS again. Request for full + power (while in WOWL mode) means disable WOWL and go to full power. + Note 2: Both UAPSD and WOWL work on top of BMPS. On entry into BMPS, SME + will give priority to UAPSD and enable only UAPSD if both UAPSD and WOWL + are required. Currently there is no requirement or use case to support + UAPSD and WOWL at the same time. + + \param hHal - The handle returned by macOpen. + \param enterWowlCallbackRoutine - Callback routine provided by HDD. + Used for success/failure notification by SME + \param enterWowlCallbackContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \param wakeReasonIndCB - Callback routine provided by HDD. + Used for Wake Reason Indication by SME + \param wakeReasonIndCBContext - A cookie passed by HDD, that is passed back to HDD + at the time of callback. + \return eHalStatus + eHAL_STATUS_SUCCESS Device is already in WoWLAN mode + eHAL_STATUS_FAILURE Device cannot enter WoWLAN mode. + eHAL_STATUS_PMC_PENDING Request accepted. SME will enable WOWL after + BMPS mode is entered. + ---------------------------------------------------------------------------*/ +eHalStatus sme_EnterWowl ( + tHalHandle hHal, + void (*enterWowlCallbackRoutine) (void *callbackContext, eHalStatus status), + void *enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + void (*wakeIndicationCB) (void *callbackContext, tpSirWakeReasonInd pWakeReasonInd), + void *wakeIndicationCBContext, +#endif // WLAN_WAKEUP_EVENTS + tpSirSmeWowlEnterParams wowlEnterParams, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ENTER_WOWL, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcEnterWowl (hHal, enterWowlCallbackRoutine, enterWowlCallbackContext, +#ifdef WLAN_WAKEUP_EVENTS + wakeIndicationCB, wakeIndicationCBContext, +#endif // WLAN_WAKEUP_EVENTS + wowlEnterParams, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_ExitWowl + \brief This is the SME API exposed to HDD to request exit from WoWLAN mode. + SME will initiate exit from WoWLAN mode and device will be put in BMPS + mode. + \param hHal - The handle returned by macOpen. + \return eHalStatus + eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode. + eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode. + ---------------------------------------------------------------------------*/ +eHalStatus sme_ExitWowl (tHalHandle hHal, tWowlExitSource wowlExitSrc) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXIT_WOWL, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcExitWowl (hHal, wowlExitSrc); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_RoamSetKey + + \brief To set encryption key. This function should be called only when connected + This is an asynchronous API. + + \param pSetKeyInfo - pointer to a caller allocated object of tCsrSetContextInfo + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetKey(tHalHandle hHal, tANI_U8 sessionId, tCsrRoamSetKey *pSetKey, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 roamId; + tANI_U32 i; + tCsrRoamSession *pSession = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_KEY, sessionId, 0)); + if (pSetKey->keyLength > CSR_MAX_KEY_LEN) + { + smsLog(pMac, LOGE, FL("Invalid key length %d"), pSetKey->keyLength); + return eHAL_STATUS_FAILURE; + } + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + + smsLog(pMac, LOG2, FL("keyLength %d"), pSetKey->keyLength); + + for(i=0; ikeyLength; i++) + smsLog(pMac, LOG2, FL("%02x"), pSetKey->Key[i]); + + smsLog(pMac, LOG2, "\n sessionId=%d roamId=%d", sessionId, roamId); + + pSession = CSR_GET_SESSION(pMac, sessionId); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if(CSR_IS_INFRA_AP(&pSession->connectedProfile)) + { +#ifdef SAP_AUTH_OFFLOAD + if (pMac->sap_auth_offload_sec_type) + { + smsLog(pMac, LOGE, + FL("No set key is required in sap auth offload enable")); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } +#endif + if(pSetKey->keyDirection == eSIR_TX_DEFAULT) + { + if ( ( eCSR_ENCRYPT_TYPE_WEP40 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pSetKey->encType )) + { + pSession->pCurRoamProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY; + } + if ( ( eCSR_ENCRYPT_TYPE_WEP104 == pSetKey->encType ) || + ( eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pSetKey->encType )) + { + pSession->pCurRoamProfile->negotiatedUCEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY; + } + } + } + + status = csrRoamSetKey ( pMac, sessionId, pSetKey, roamId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + //Store sent PTK key time + if(pSetKey->keyDirection == eSIR_TX_RX) + { + vos_record_roam_event(e_HDD_SET_PTK_REQ, NULL, 0); + } + else if(pSetKey->keyDirection == eSIR_RX_ONLY) + { + vos_record_roam_event(e_HDD_SET_GTK_REQ, NULL, 0); + } + else + { + return (status); + } + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_RoamRemoveKey + + \brief To set encryption key. This is an asynchronous API. + + \param pRemoveKey - pointer to a caller allocated object of tCsrRoamRemoveKey + + \param pRoamId Upon success return, this is the id caller can use to identify the request in roamcallback + + \return eHalStatus SUCCESS Roam callback will be called indicate actually results + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamRemoveKey(tHalHandle hHal, tANI_U8 sessionId, + tCsrRoamRemoveKey *pRemoveKey, tANI_U32 *pRoamId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 roamId; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REMOVE_KEY, sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + roamId = GET_NEXT_ROAM_ID(&pMac->roam); + if(pRoamId) + { + *pRoamId = roamId; + } + status = csrRoamIssueRemoveKeyCommand( pMac, sessionId, pRemoveKey, roamId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetRssi + \brief a wrapper function that client calls to register a callback to get RSSI + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetRssi( pMac, callback, + staId, bssId, pContext, pVosContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetSnr + \brief a wrapper function that client calls to register a callback to + get SNR + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetSnr(tHalHandle hHal, + tCsrSnrCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetSnr(pMac, callback, + staId, bssId, pContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/* --------------------------------------------------------------------------- + \fn sme_GetRoamRssi + \brief a wrapper function that client calls to register a callback to get Roam RSSI + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetRoamRssi(tHalHandle hHal, + tCsrRssiCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetRoamRssi( pMac, callback, + staId, bssId, pContext, pVosContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +#endif + +#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) +/* --------------------------------------------------------------------------- + \fn sme_GetTsmStats + \brief a wrapper function that client calls to register a callback to get TSM Stats + + \param callback - SME sends back the requested stats using the callback + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \param pVosContext - vos context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetTsmStats(tHalHandle hHal, + tCsrTsmStatsCallback callback, + tANI_U8 staId, tCsrBssid bssId, + void *pContext, void* pVosContext, tANI_U8 tid) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetTsmStats( pMac, callback, + staId, bssId, pContext, pVosContext, tid); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +#endif + + +/* --------------------------------------------------------------------------- + \fn sme_GetStatistics + \brief a wrapper function that client calls to register a callback to get + different PHY level statistics from CSR. + + \param requesterId - different client requesting for statistics, HDD, UMA/GAN etc + \param statsMask - The different category/categories of stats requester is looking for + \param callback - SME sends back the requested stats using the callback + \param periodicity - If requester needs periodic update in millisec, 0 means + it's an one time request + \param cache - If requester is happy with cached stats + \param staId - The station ID for which the stats is requested for + \param pContext - user context to be passed back along with the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetStatistics(tHalHandle hHal, eCsrStatsRequesterType requesterId, + tANI_U32 statsMask, + tCsrStatsCallback callback, + tANI_U32 periodicity, tANI_BOOLEAN cache, + tANI_U8 staId, void *pContext) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION, periodicity)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetStatistics( pMac, requesterId , statsMask, callback, + periodicity, cache, staId, pContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); + +} + +eHalStatus sme_GetFwStats(tHalHandle hHal, tANI_U32 stats, + void *pContext, tSirFWStatsCallback callback) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + tSirFWStatsGetReq *pGetFWStatsReq; + + smsLog(pMac, LOG1, FL(" ENTER stats = %d "),stats); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme )) + { + pGetFWStatsReq = (tSirFWStatsGetReq *)vos_mem_malloc(sizeof(tSirFWStatsGetReq)); + if ( NULL == pGetFWStatsReq) + { + smsLog(pMac, LOGE, FL("Not able to allocate memory for " + "WDA_FW_STATS_GET_REQ")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pGetFWStatsReq->stats = stats; + pGetFWStatsReq->callback = (tSirFWStatsCallback)callback; + pGetFWStatsReq->data = pContext; + + msg.type = WDA_FW_STATS_GET_REQ; + msg.reserved = 0; + msg.bodyptr = pGetFWStatsReq; + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, &msg)) + { + smsLog(pMac, LOGE, + FL("Not able to post WDA_FW_STATS_GET_REQ message to HAL")); + vos_mem_free(pGetFWStatsReq); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_SUCCESS; + } + return eHAL_STATUS_FAILURE; +} + +/* --------------------------------------------------------------------------- + \fn smeGetTLSTAState + \helper function to get the TL STA State whenever the function is called. + + \param staId - The staID to be passed to the TL + to get the relevant TL STA State + \return the state as tANI_U16 + ---------------------------------------------------------------------------*/ +tANI_U16 smeGetTLSTAState(tHalHandle hHal, tANI_U8 staId) +{ + tANI_U16 tlSTAState = TL_INIT_STATE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + tlSTAState = csrGetTLSTAState( pMac, staId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return tlSTAState; +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetCountryCode + + \brief To return the current country code. If no country code is applied, default country code is + used to fill the buffer. + If 11d supported is turned off, an error is return and the last applied/default country code is used. + This is a synchronous API. + + \param pBuf - pointer to a caller allocated buffer for returned country code. + + \param pbLen For input, this parameter indicates how big is the buffer. + Upon return, this parameter has the number of bytes for country. If pBuf + doesn't have enough space, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U8 *pbLen) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE, NO_SESSION, 0)); + + return ( csrGetCountryCode( pMac, pBuf, pbLen ) ); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_SetCountryCode + + \brief To change the current/default country code. + If 11d supported is turned off, an error is return. + This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for the country code. + + \param pfRestartNeeded A pointer to caller allocated memory, upon successful return, it indicates + whether a reset is required. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetCountryCode(tHalHandle hHal, tANI_U8 *pCountry, tANI_BOOLEAN *pfRestartNeeded) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE, NO_SESSION, 0)); + return ( csrSetCountryCode( pMac, pCountry, pfRestartNeeded ) ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_ResetCountryCodeInformation + \brief this function is to reset the country code current being used back to EEPROM default + this includes channel list and power setting. This is a synchronous API. + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_ResetCountryCodeInformation(tHalHandle hHal, tANI_BOOLEAN *pfRestartNeeded) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrResetCountryCodeInformation( pMac, pfRestartNeeded ) ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetSupportedCountryCode + \brief this function is to get a list of the country code current being supported + \param pBuf - Caller allocated buffer with at least 3 bytes, upon success return, + this has the country code list. 3 bytes for each country code. This may be NULL if + caller wants to know the needed byte count. + \param pbLen - Caller allocated, as input, it indicates the length of pBuf. Upon success return, + this contains the length of the data in pBuf. If pbuf is NULL, as input, *pbLen should be 0. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedCountryCode(tHalHandle hHal, tANI_U8 *pBuf, tANI_U32 *pbLen) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrGetSupportedCountryCode( pMac, pBuf, pbLen ) ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetCurrentRegulatoryDomain + \brief this function is to get the current regulatory domain. This is a synchronous API. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. The function fails if 11d support is turned off. + \param pDomain - Caller allocated buffer to return the current domain. + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t *pDomain) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + if( pDomain ) + { + if( csrIs11dSupported( pMac ) ) + { + *pDomain = csrGetCurrentRegulatoryDomain( pMac ); + status = eHAL_STATUS_SUCCESS; + } + else + { + status = eHAL_STATUS_FAILURE; + } + } + + return ( status ); +} + + +/* --------------------------------------------------------------------------- + \fn sme_SetRegulatoryDomain + \brief this function is to set the current regulatory domain. + This function must be called after CFG is downloaded and all the band/mode setting already passed into + SME. This is a synchronous API. + \param domainId - indicate the domain (defined in the driver) needs to set to. + See v_REGDOMAIN_t for definition + \param pfRestartNeeded - pointer to a caller allocated space. Upon successful return, it indicates whether + a restart is needed to apply the change + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetRegulatoryDomain(tHalHandle hHal, v_REGDOMAIN_t domainId, tANI_BOOLEAN *pfRestartNeeded) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrSetRegulatoryDomain( pMac, domainId, pfRestartNeeded ) ); +} + + +/* --------------------------------------------------------------------------- + + \fn sme_GetRegulatoryDomainForCountry + + \brief To return a regulatory domain base on a country code. This is a synchronous API. + + \param pCountry - pointer to a caller allocated buffer for input country code. + + \param pDomainId Upon successful return, it is the domain that country belongs to. + If it is NULL, returning success means that the country code is known. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetRegulatoryDomainForCountry(tHalHandle hHal, tANI_U8 *pCountry, v_REGDOMAIN_t *pDomainId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return csrGetRegulatoryDomainForCountry(pMac, pCountry, pDomainId, + COUNTRY_QUERY); +} + + + + +/* --------------------------------------------------------------------------- + + \fn sme_GetSupportedRegulatoryDomains + + \brief To return a list of supported regulatory domains. This is a synchronous API. + + \param pDomains - pointer to a caller allocated buffer for returned regulatory domains. + + \param pNumDomains For input, this parameter indicates howm many domains pDomains can hold. + Upon return, this parameter has the number for supported domains. If pDomains + doesn't have enough space for all the supported domains, this function returns + fail status and this parameter contains the number that is needed. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetSupportedRegulatoryDomains(tHalHandle hHal, v_REGDOMAIN_t *pDomains, tANI_U32 *pNumDomains) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + //We support all domains for now + if( pNumDomains ) + { + if( NUM_REG_DOMAINS <= *pNumDomains ) + { + status = eHAL_STATUS_SUCCESS; + } + *pNumDomains = NUM_REG_DOMAINS; + } + if( HAL_STATUS_SUCCESS( status ) ) + { + if( pDomains ) + { + pDomains[0] = REGDOMAIN_FCC; + pDomains[1] = REGDOMAIN_ETSI; + pDomains[2] = REGDOMAIN_JAPAN; + pDomains[3] = REGDOMAIN_WORLD; + pDomains[4] = REGDOMAIN_N_AMER_EXC_FCC; + pDomains[5] = REGDOMAIN_APAC; + pDomains[6] = REGDOMAIN_KOREA; + pDomains[7] = REGDOMAIN_HI_5GHZ; + pDomains[8] = REGDOMAIN_NO_5GHZ; + } + else + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + } + + return ( status ); +} + + +//some support functions +tANI_BOOLEAN sme_Is11dSupported(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrIs11dSupported( pMac ) ); +} + + +tANI_BOOLEAN sme_Is11hSupported(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrIs11hSupported( pMac ) ); +} + + +tANI_BOOLEAN sme_IsWmmSupported(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return ( csrIsWmmSupported( pMac ) ); +} + +//Upper layer to get the list of the base channels to scan for passively 11d info from csr +eHalStatus sme_ScanGetBaseChannels( tHalHandle hHal, tCsrChannelInfo * pChannelInfo ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + return(csrScanGetBaseChannels(pMac,pChannelInfo) ); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ChangeCountryCode + + \brief Change Country code from upperlayer during WLAN driver operation. + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param sendRegHint If we want to send reg hint to nl80211 + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeCountryCode( tHalHandle hHal, + tSmeChangeCountryCallback callback, + tANI_U8 *pCountry, + void *pContext, + void* pVosContext, + tAniBool countryFromUserSpace, + tAniBool sendRegHint ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + tAniChangeCountryCodeReq *pMsg; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOG1, FL(" called")); + + if ((pMac->roam.configParam.Is11dSupportEnabledOriginal == true) && + (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)) + { + + smsLog(pMac, LOGW, "Set Country Code Fail since the STA is associated and userspace does not have priority "); + + sme_ReleaseGlobalLock( &pMac->sme ); + status = eHAL_STATUS_FAILURE; + return status; + } + + pMsg = vos_mem_malloc(sizeof(tAniChangeCountryCodeReq)); + if ( NULL == pMsg ) + { + smsLog(pMac, LOGE, " csrChangeCountryCode: failed to allocate mem for req"); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANGE_COUNTRY_CODE); + pMsg->msgLen = (tANI_U16)sizeof(tAniChangeCountryCodeReq); + vos_mem_copy(pMsg->countryCode, pCountry, 3); + pMsg->countryFromUserSpace = countryFromUserSpace; + pMsg->sendRegHint = sendRegHint; + pMsg->changeCCCallback = callback; + pMsg->pDevContext = pContext; + pMsg->pVosContext = pVosContext; + + msg.type = eWNI_SME_CHANGE_COUNTRY_CODE; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, " sme_ChangeCountryCode failed to post msg to self "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL(" returned")); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/*-------------------------------------------------------------------------- + + \fn sme_GenericChangeCountryCode + + \brief Change Country code from upperlayer during WLAN driver operation. + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \param pCountry New Country Code String + + \param reg_domain regulatory domain + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + +-----------------------------------------------------------------------------*/ +eHalStatus sme_GenericChangeCountryCode( tHalHandle hHal, + tANI_U8 *pCountry, + v_REGDOMAIN_t reg_domain) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + tAniGenericChangeCountryCodeReq *pMsg; + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return status; + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOG1, FL(" called")); + pMsg = vos_mem_malloc(sizeof(tAniGenericChangeCountryCodeReq)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, " sme_GenericChangeCountryCode: failed to allocate mem for req"); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE); + pMsg->msgLen = (tANI_U16)sizeof(tAniGenericChangeCountryCodeReq); + vos_mem_copy(pMsg->countryCode, pCountry, 2); + + pMsg->countryCode[2] = ' '; /* For ASCII space */ + + pMsg->domain_index = reg_domain; + + msg.type = eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + smsLog(pMac, LOGE, "sme_GenericChangeCountryCode failed to post msg to self"); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL(" returned")); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_InitChannels + + \brief Used to initialize CSR channel lists while driver loading + + \param hHal - global pMac structure + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_InitChannels(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return status; + } + + status = csrInitChannels(pMac); + + return status; +} + +#ifdef CONFIG_ENABLE_LINUX_REG +/*------------------------------------------------------------------------- + \fn sme_InitChannelsForCC + + \brief Used to issue regulatory hint to user + + \param hHal - global pMac structure + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. +--------------------------------------------------------------------------*/ + +eHalStatus sme_InitChannelsForCC(tHalHandle hHal, driver_load_type init) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return status; + } + status = csrInitChannelsForCC(pMac, init); + + return status; +} +#endif + +/* --------------------------------------------------------------------------- + + \fn sme_DHCPStartInd + + \brief API to signal the FW about the DHCP Start event. + + \param hHal - HAL handle for device. + + \param device_mode - mode(AP,SAP etc) of the device. + + \param macAddr - MAC address of the device. + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + --------------------------------------------------------------------------*/ +eHalStatus sme_DHCPStartInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 sessionId ) +{ + eHalStatus status; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t vosMessage; + tAniDHCPInd *pMsg; + tCsrRoamSession *pSession; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pSession->dhcp_done = false; + pMsg = (tAniDHCPInd*)vos_mem_malloc(sizeof(tAniDHCPInd)); + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for dhcp start", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pMsg->msgType = WDA_DHCP_START_IND; + pMsg->msgLen = (tANI_U16)sizeof(tAniDHCPInd); + pMsg->device_mode = device_mode; + vos_mem_copy(pMsg->macAddr, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + vosMessage.type = WDA_DHCP_START_IND; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post DHCP Start MSG fail", __func__); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_DHCPStopInd + + \brief API to signal the FW about the DHCP complete event. + + \param hHal - HAL handle for device. + + \param device_mode - mode(AP, SAP etc) of the device. + + \param macAddr - MAC address of the device. + + \return eHalStatus SUCCESS. + FAILURE or RESOURCES The API finished and failed. + --------------------------------------------------------------------------*/ +eHalStatus sme_DHCPStopInd( tHalHandle hHal, + tANI_U8 device_mode, + tANI_U8 sessionId ) +{ + eHalStatus status; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t vosMessage; + tAniDHCPInd *pMsg; + tCsrRoamSession *pSession; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pSession->dhcp_done = true; + pMsg = (tAniDHCPInd*)vos_mem_malloc(sizeof(tAniDHCPInd)); + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for dhcp stop", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = WDA_DHCP_STOP_IND; + pMsg->msgLen = (tANI_U16)sizeof(tAniDHCPInd); + pMsg->device_mode = device_mode; + vos_mem_copy(pMsg->macAddr, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vosMessage.type = WDA_DHCP_STOP_IND; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post DHCP Stop MSG fail", __func__); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +#ifdef WLAN_FEATURE_RMC +/*--------------------------------------------------------------------------- + + \fn sme_TXFailMonitorStopInd + + \brief API to signal the FW to start monitoring TX failures + + \return eHalStatus SUCCESS. + + FAILURE or RESOURCES The API finished and failed. + --------------------------------------------------------------------------*/ +eHalStatus sme_TXFailMonitorStartStopInd(tHalHandle hHal, tANI_U8 tx_fail_count, + void * txFailIndCallback) +{ + eHalStatus status; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tAniTXFailMonitorInd *pMsg; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pMsg = (tAniTXFailMonitorInd*) + vos_mem_malloc(sizeof(tAniTXFailMonitorInd)); + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to allocate memory", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = WDA_TX_FAIL_MONITOR_IND; + pMsg->msgLen = (tANI_U16)sizeof(tAniTXFailMonitorInd); + + //tx_fail_count = 0 should disable the Monitoring in FW + pMsg->tx_fail_count = tx_fail_count; + pMsg->txFailIndCallback = txFailIndCallback; + + vosMessage.type = WDA_TX_FAIL_MONITOR_IND; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post TX Fail monitor Start MSG fail", __func__); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void sme_PERRoamScanStartStop(void *hHal, tANI_U8 start) +{ + eHalStatus status; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tPERRoamScanStart *pMsg; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pMsg = (tPERRoamScanStart *) + vos_mem_malloc(sizeof(tPERRoamScanStart)); + if (NULL == pMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to allocate memory", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + + pMsg->msgType = WDA_PER_ROAM_SCAN_TRIGGER_REQ; + pMsg->msgLen = (tANI_U16)sizeof(*pMsg); + + pMsg->start = start; + + vosMessage.type = WDA_PER_ROAM_SCAN_TRIGGER_REQ; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post TX Fail monitor Start MSG fail", __func__); + vos_mem_free(pMsg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } +} + +/* sme_set_per_roam_rxconfig : set PER config for Rx monitoring + * @hHal: hal pointer + * @staId: station id + * @minRate : rate at which to start monitoring + * @maxRate : Rate at which to stop monitoring + * @minPercentage: minimum % of packets required in minRate to trigger a scan + * @minPktRequired: minimum number of packets required to trigger a scan + * @waitPeriodForNextPERScan: time to wait before start monitoring again once + * roam scan is triggered + * */ + +VOS_STATUS sme_set_per_roam_rxconfig (tHalHandle hHal, v_U8_t staId, + v_U16_t minRate, v_U16_t maxRate, + v_U8_t minPercentage, v_U16_t minPktRequired, + v_U64_t waitPeriodForNextPERScan) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + WLANTL_StartRxRateMonitor(pVosContext, staId, minRate, maxRate, + minPercentage, minPktRequired, + (void *) hHal, waitPeriodForNextPERScan, + sme_PERRoamScanStartStop); + pMac->PERroamCandidatesCnt = 0; + return eHAL_STATUS_SUCCESS; +} + +/* sme_unset_per_roam_rxconfig : unset PER config for Rx monitoring + * */ +VOS_STATUS sme_unset_per_roam_rxconfig (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + vos_mem_set(pMac->previousRoamApInfo, + sizeof(tSirRoamAPInfo) * SIR_PER_ROAM_MAX_CANDIDATE_CNT, 0); + WLANTL_StopRxRateMonitor(pVosContext); + return eHAL_STATUS_SUCCESS; +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_BtcSignalBtEvent + \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the + BT event type and the current operating mode of Libra (full power, + BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy + would be employed. + \param hHal - The handle returned by macOpen. + \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE BT Event not passed to HAL. This can happen + if BTC execution mode is set to BTC_WLAN_ONLY + or BTC_PTA_ONLY. + VOS_STATUS_SUCCESS BT Event passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSignalBtEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = btcSignalBTEvent (hHal, pBtEvent); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_BtcSetConfig + \brief API to change the current Bluetooth Coexistence (BTC) configuration + This function should be invoked only after CFG download has completed. + Calling it after sme_HDDReadyInd is recommended. + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type tSmeBtcConfig. + Caller owns the memory and is responsible for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE Config not passed to HAL. + VOS_STATUS_SUCCESS Config passed to HAL + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = btcSetConfig (hHal, pSmeBtcConfig); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_BtcGetConfig + \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration + \param hHal - The handle returned by macOpen. + \param pSmeBtcConfig - Pointer to a caller allocated object of type + tSmeBtcConfig. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_BtcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; +#ifndef WLAN_MDM_CODE_REDUCTION_OPT + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = btcGetConfig (hHal, pSmeBtcConfig); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#endif + return (status); +} +/* --------------------------------------------------------------------------- + \fn sme_SetCfgPrivacy + \brief API to set configure privacy parameters + \param hHal - The handle returned by macOpen. + \param pProfile - Pointer CSR Roam profile. + \param fPrivacy - This parameter indicates status of privacy + + \return void + ---------------------------------------------------------------------------*/ +void sme_SetCfgPrivacy( tHalHandle hHal, + tCsrRoamProfile *pProfile, + tANI_BOOLEAN fPrivacy + ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + csrSetCfgPrivacy(pMac, pProfile, fPrivacy); + sme_ReleaseGlobalLock( &pMac->sme ); + } +} + +#if defined WLAN_FEATURE_VOWIFI +/* --------------------------------------------------------------------------- + \fn sme_NeighborReportRequest + \brief API to request neighbor report. + \param hHal - The handle returned by macOpen. + \param pRrmNeighborReq - Pointer to a caller allocated object of type + tRrmNeighborReq. Caller owns the memory and is responsible + for freeing it. + \return VOS_STATUS + VOS_STATUS_E_FAILURE - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_NeighborReportRequest (tHalHandle hHal, tANI_U8 sessionId, + tpRrmNeighborReq pRrmNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ, NO_SESSION, 0)); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + status = sme_RrmNeighborReportRequest (hHal, sessionId, pRrmNeighborReq, callbackInfo); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +#endif + +//The following are debug APIs to support direct read/write register/memory +//They are placed in SME because HW cannot be access when in LOW_POWER state +//AND not connected. The knowledge and synchronization is done in SME + +//sme_DbgReadRegister +//Caller needs to validate the input values +VOS_STATUS sme_DbgReadRegister(tHalHandle hHal, v_U32_t regAddr, v_U32_t *pRegValue) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tPmcPowerState PowerState; + tANI_U32 sessionId = 0; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DBG_READREG, NO_SESSION, 0)); + + /* 1) To make Quarky work in FTM mode **************************************/ + + if(eDRIVER_TYPE_MFG == pMac->gDriverType) + { + if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgReadRegister(regAddr, pRegValue)) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; + } + + /* 2) NON FTM mode driver *************************************************/ + + /* Acquire SME global lock */ + if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme)) + { + return VOS_STATUS_E_FAILURE; + } + + if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL))) + { + /* Are we not in IMPS mode? Or are we in connected? Then we're safe*/ + if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState)) + { + if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgReadRegister(regAddr, pRegValue)) + { + status = VOS_STATUS_SUCCESS; + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + + /* This is a hack for Qualky/pttWniSocket + Current implementation doesn't allow pttWniSocket to inform Qualky an error */ + if ( VOS_STATUS_SUCCESS != status ) + { + *pRegValue = 0xDEADBEEF; + status = VOS_STATUS_SUCCESS; + } + + /* Release SME global lock */ + sme_ReleaseGlobalLock(&pMac->sme); + + return (status); +} + + +//sme_DbgWriteRegister +//Caller needs to validate the input values +VOS_STATUS sme_DbgWriteRegister(tHalHandle hHal, v_U32_t regAddr, v_U32_t regValue) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tPmcPowerState PowerState; + tANI_U32 sessionId = 0; + + /* 1) To make Quarky work in FTM mode **************************************/ + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DBG_WRITEREG, NO_SESSION, 0)); + if(eDRIVER_TYPE_MFG == pMac->gDriverType) + { + if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgWriteRegister(regAddr, regValue)) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; + } + + /* 2) NON FTM mode driver *************************************************/ + + /* Acquire SME global lock */ + if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme)) + { + return VOS_STATUS_E_FAILURE; + } + + if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL))) + { + /* Are we not in IMPS mode? Or are we in connected? Then we're safe*/ + if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState)) + { + if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgWriteRegister(regAddr, regValue)) + { + status = VOS_STATUS_SUCCESS; + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + + /* Release SME global lock */ + sme_ReleaseGlobalLock(&pMac->sme); + + return (status); +} + + + +//sme_DbgReadMemory +//Caller needs to validate the input values +//pBuf caller allocated buffer has the length of nLen +VOS_STATUS sme_DbgReadMemory(tHalHandle hHal, v_U32_t memAddr, v_U8_t *pBuf, v_U32_t nLen) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tPmcPowerState PowerState; + tANI_U32 sessionId = 0; + tANI_U32 cmd = READ_MEMORY_DUMP_CMD; + tANI_U32 arg1 = memAddr; + tANI_U32 arg2 = nLen/4; + tANI_U32 arg3 = 4; + tANI_U32 arg4 = 0; + /* 1) To make Quarky work in FTM mode **************************************/ + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DBG_READMEM, NO_SESSION, 0)); + if(eDRIVER_TYPE_MFG == pMac->gDriverType) + { + if (VOS_STATUS_SUCCESS == WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, (tANI_U8*)pBuf, 0)) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; + } + + /* 2) NON FTM mode driver *************************************************/ + + /* Acquire SME global lock */ + if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme)) + { + return VOS_STATUS_E_FAILURE; + } + + if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL))) + { + /* Are we not in IMPS mode? Or are we in connected? Then we're safe*/ + if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState)) + { + if (VOS_STATUS_SUCCESS == WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, (tANI_U8 *)pBuf, 0)) + { + status = VOS_STATUS_SUCCESS; + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + + /* This is a hack for Qualky/pttWniSocket + Current implementation doesn't allow pttWniSocket to inform Qualky an error */ + if (VOS_STATUS_SUCCESS != status) + { + vos_mem_set(pBuf, nLen, 0xCD); + status = VOS_STATUS_SUCCESS; + smsLog(pMac, LOGE, FL(" filled with 0xCD because it cannot access the hardware")); + } + + /* Release SME lock */ + sme_ReleaseGlobalLock(&pMac->sme); + + return (status); +} + + +//sme_DbgWriteMemory +//Caller needs to validate the input values +VOS_STATUS sme_DbgWriteMemory(tHalHandle hHal, v_U32_t memAddr, v_U8_t *pBuf, v_U32_t nLen) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tPmcPowerState PowerState; + tANI_U32 sessionId = 0; + + /* 1) To make Quarky work in FTM mode **************************************/ + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM, NO_SESSION, 0)); + if(eDRIVER_TYPE_MFG == pMac->gDriverType) + { + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; + } + + /* 2) NON FTM mode driver *************************************************/ + + /* Acquire SME global lock */ + if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme)) + { + return VOS_STATUS_E_FAILURE; + } + + if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL))) + { + /* Are we not in IMPS mode? Or are we in connected? Then we're safe*/ + if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState)) + { + if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgWriteMemory(memAddr, (void *)pBuf, nLen)) + { + status = VOS_STATUS_SUCCESS; + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + else + { + status = VOS_STATUS_E_FAILURE; + } + } + + /* Release Global lock */ + sme_ReleaseGlobalLock(&pMac->sme); + + return (status); +} + + +void pmcLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString, ...) +{ + VOS_TRACE_LEVEL vosDebugLevel; + char logBuffer[LOG_SIZE]; + va_list marker; + + /* getting proper Debug level */ + vosDebugLevel = getVosDebugLevel(loglevel); + + /* extracting arguments from pstring */ + va_start( marker, pString ); + vsnprintf(logBuffer, LOG_SIZE, pString, marker); + + VOS_TRACE(VOS_MODULE_ID_PMC, vosDebugLevel, "%s", logBuffer); + va_end( marker ); +} + + +void smsLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + // Verify against current log level + if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_SMS_MODULE_ID )] ) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_SMS_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssWlanCompiledVersion + \brief This API returns the version of the WCNSS WLAN API with + which the HOST driver was built + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version structure to be filled + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssWlanCompiledVersion(tHalHandle hHal, + tSirVersionType *pVersion) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssWlanCompiledVersion(vosContext, pVersion); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssWlanReportedVersion + \brief This API returns the version of the WCNSS WLAN API with + which the WCNSS driver reports it was built + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version structure to be filled + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssWlanReportedVersion(tHalHandle hHal, + tSirVersionType *pVersion) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssWlanReportedVersion(vosContext, pVersion); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssSoftwareVersion + \brief This API returns the version string of the WCNSS driver + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version string buffer to be filled + \param versionBufferSize - THe size of the Version string buffer + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssSoftwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssSoftwareVersion(vosContext, pVersion, + versionBufferSize); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +/* --------------------------------------------------------------------------- + \fn sme_GetWcnssHardwareVersion + \brief This API returns the version string of the WCNSS hardware + \param hHal - The handle returned by macOpen. + \param pVersion - Points to the Version string buffer to be filled + \param versionBufferSize - THe size of the Version string buffer + \return VOS_STATUS + VOS_STATUS_E_INVAL - failure + VOS_STATUS_SUCCESS success + ---------------------------------------------------------------------------*/ +VOS_STATUS sme_GetWcnssHardwareVersion(tHalHandle hHal, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + if( pVersion != NULL ) + { + status = WDA_GetWcnssHardwareVersion(vosContext, pVersion, + versionBufferSize); + } + else + { + status = VOS_STATUS_E_INVAL; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + + +#ifdef FEATURE_WLAN_WAPI +/* --------------------------------------------------------------------------- + \fn sme_RoamSetBKIDCache + \brief The SME API exposed to HDD to allow HDD to provde SME the BKID + candidate list. + \param hHal - Handle to the HAL. The HAL handle is returned by the HAL after + it is opened (by calling halOpen). + \param pBKIDCache - caller allocated buffer point to an array of tBkidCacheInfo + \param numItems - a variable that has the number of tBkidCacheInfo allocated + when retruning, this is the number of items put into pBKIDCache + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems has the number of tBkidCacheInfo. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamSetBKIDCache( tHalHandle hHal, tANI_U32 sessionId, tBkidCacheInfo *pBKIDCache, + tANI_U32 numItems ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamSetBKIDCache( pMac, sessionId, pBKIDCache, numItems ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetBKIDCache + \brief The SME API exposed to HDD to allow HDD to request SME to return its + BKID cache. + \param hHal - Handle to the HAL. The HAL handle is returned by the HAL after + it is opened (by calling halOpen). + \param pNum - caller allocated memory that has the space of the number of + tBkidCacheInfo as input. Upon returned, *pNum has the needed number of entries + in SME cache. + \param pBkidCache - Caller allocated memory that contains BKID cache, if any, + upon return + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough. + ---------------------------------------------------------------------------*/ +eHalStatus sme_RoamGetBKIDCache(tHalHandle hHal, tANI_U32 *pNum, + tBkidCacheInfo *pBkidCache) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + smsLog(pMac, LOGE, FL(" !!!!!!!!!!!!!!!!!!SessionId is hardcoded")); + status = csrRoamGetBKIDCache( pMac, 0, pNum, pBkidCache ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RoamGetNumBKIDCache + \brief The SME API exposed to HDD to allow HDD to request SME to return the + number of BKID cache entries. + \param hHal - Handle to the HAL. The HAL handle is returned by the HAL after + it is opened (by calling halOpen). + \return tANI_U32 - the number of BKID cache entries. + ---------------------------------------------------------------------------*/ +tANI_U32 sme_RoamGetNumBKIDCache(tHalHandle hHal, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U32 numBkidCache = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + numBkidCache = csrRoamGetNumBKIDCache( pMac, sessionId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (numBkidCache); +} + +/* --------------------------------------------------------------------------- + \fn sme_ScanGetBKIDCandidateList + \brief a wrapper function to return the BKID candidate list + \param pBkidList - caller allocated buffer point to an array of + tBkidCandidateInfo + \param pNumItems - pointer to a variable that has the number of + tBkidCandidateInfo allocated when retruning, this is + either the number needed or number of items put into + pPmkidList + \return eHalStatus - when fail, it usually means the buffer allocated is not + big enough and pNumItems + has the number of tBkidCandidateInfo. + \Note: pNumItems is a number of tBkidCandidateInfo, + not sizeof(tBkidCandidateInfo) * something + ---------------------------------------------------------------------------*/ +eHalStatus sme_ScanGetBKIDCandidateList(tHalHandle hHal, tANI_U32 sessionId, + tBkidCandidateInfo *pBkidList, + tANI_U32 *pNumItems ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrScanGetBKIDCandidateList( pMac, sessionId, pBkidList, pNumItems ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +#endif /* FEATURE_WLAN_WAPI */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/***************************************************************************** + OEM DATA related modifications and function additions + *****************************************************************************/ + +/* --------------------------------------------------------------------------- + \fn sme_getOemDataRsp + \brief a wrapper function to obtain the OEM DATA RSP + \param pOemDataRsp - A pointer to the response object + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_getOemDataRsp(tHalHandle hHal, + tOemDataRsp **pOemDataRsp) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + + if(!HAL_STATUS_SUCCESS(status)) + { + break; + } + + if(pMac->oemData.pOemDataRsp != NULL) + { + *pOemDataRsp = pMac->oemData.pOemDataRsp; + } + else + { + status = eHAL_STATUS_FAILURE; + } + + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + + } while(0); + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_OemDataReq + \brief a wrapper function for OEM DATA REQ + \param sessionId - session id to be used. + \param pOemDataReqId - pointer to an object to get back the request ID + \param callback - a callback function that is called upon finish + \param pContext - a pointer passed in for the callback + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_OemDataReq(tHalHandle hHal, + tANI_U8 sessionId, + tOemDataReqConfig *pOemDataReqConfig, + tANI_U32 *pOemDataReqID, + oemData_OemDataReqCompleteCallback callback, + void *pContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + tANI_U32 lOemDataReqId = pMac->oemData.oemDataReqID++; //let it wrap around + + if(pOemDataReqID) + { + *pOemDataReqID = lOemDataReqId; + } + else + { + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + status = oemData_OemDataReq(hHal, sessionId, pOemDataReqConfig, pOemDataReqID, callback, pContext); + + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + } while(0); + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_OemDataReqNew + \brief a wrapper function for OEM DATA REQ NEW + \param pOemDataReqNewConfig - Data to be passed to FW + ---------------------------------------------------------------------------*/ +void sme_OemDataReqNew(tHalHandle hHal, + tOemDataReqNewConfig *pOemDataReqNewConfig) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tOemDataReqNewConfig *pLocalOemDataReqNewConfig; + vos_msg_t vosMessage = {0}; + + pLocalOemDataReqNewConfig = + vos_mem_malloc(sizeof(*pLocalOemDataReqNewConfig)); + + if (!pLocalOemDataReqNewConfig) + { + smsLog(pMac, LOGE, + "Failed to allocate memory for WDA_START_OEM_DATA_REQ_IND_NEW"); + return; + } + + vos_mem_zero(pLocalOemDataReqNewConfig, sizeof(tOemDataReqNewConfig)); + vos_mem_copy(pLocalOemDataReqNewConfig, pOemDataReqNewConfig, + sizeof(tOemDataReqNewConfig)); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pLocalOemDataReqNewConfig; + vosMessage.type = WDA_START_OEM_DATA_REQ_IND_NEW; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + + if(VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s:" + "Failed to post WDA_START_OEM_DATA_REQ_IND_NEW msg to WDA", + __func__); + vos_mem_free(pLocalOemDataReqNewConfig); + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pLocalOemDataReqNewConfig); + } +} + +#endif /*FEATURE_OEM_DATA_SUPPORT*/ + +/*-------------------------------------------------------------------------- + + \brief sme_OpenSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + \param callback - A pointer to the function caller specifies for roam/connect status indication + \param pContext - The context passed with callback + \param pSelfMacAddr - Caller allocated memory filled with self MAC address (6 bytes) + \param pbSessionId - pointer to a caller allocated buffer for returned session ID + + \return eHAL_STATUS_SUCCESS - session is opened. sessionId returned. + + Other status means SME is failed to open the session. + eHAL_STATUS_RESOURCES - no more session available. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_OpenSession(tHalHandle hHal, csrRoamCompleteCallback callback, + void *pContext, tANI_U8 *pSelfMacAddr, + tANI_U8 *pbSessionId) +{ + eHalStatus status; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if( NULL == pbSessionId ) + { + status = eHAL_STATUS_INVALID_PARAMETER; + } + else + { + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamOpenSession(pMac, callback, pContext, + pSelfMacAddr, pbSessionId); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + } + if( NULL != pbSessionId ) + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_OPEN_SESSION,*pbSessionId, 0)); + + return ( status ); +} + + +/*-------------------------------------------------------------------------- + + \brief sme_CloseSession() - Open a session for scan/roam operation. + + This is a synchronous API. + + + \param hHal - The handle returned by macOpen. + + \param sessionId - A previous opened session's ID. + + \return eHAL_STATUS_SUCCESS - session is closed. + + Other status means SME is failed to open the session. + eHAL_STATUS_INVALID_PARAMETER - session is not opened. + \sa + + --------------------------------------------------------------------------*/ +eHalStatus sme_CloseSession(tHalHandle hHal, tANI_U8 sessionId, + tANI_BOOLEAN fSync, + tANI_U8 bPurgeSmeCmdList, + csrRoamSessionCloseCallback callback, + void *pContext) +{ + eHalStatus status; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CLOSE_SESSION, sessionId, 0)); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + status = csrRoamCloseSession(pMac, sessionId, fSync, bPurgeSmeCmdList, + callback, pContext); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return ( status ); +} + +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPSIE + + \brief To update AP's WPS IE. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPWPSIES - pointer to a caller allocated object of tSirAPWPSIEs + + \return eHalStatus – SUCCESS – + + FAILURE or RESOURCES – The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamUpdateAPWPSIE(tHalHandle hHal, tANI_U8 sessionId, tSirAPWPSIEs *pAPWPSIES) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + status = csrRoamUpdateAPWPSIE( pMac, sessionId, pAPWPSIES ); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + + \fn sme_RoamUpdateAPWPARSNIEs + + \brief To update AP's WPA/RSN IEs. This function should be called after SME AP session is created + This is an asynchronous API. + + \param pAPSirRSNie - pointer to a caller allocated object of tSirRSNie with WPS/RSN IEs + + \return eHalStatus – SUCCESS – + + FAILURE or RESOURCES – The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_RoamUpdateAPWPARSNIEs(tHalHandle hHal, tANI_U8 sessionId, tSirRSNie * pAPSirRSNie) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + status = csrRoamUpdateWPARSNIEs( pMac, sessionId, pAPSirRSNie); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +/* --------------------------------------------------------------------------- + + \fn sme_ChangeMCCBeaconInterval + + \brief To update P2P-GO beaconInterval. This function should be called after + disassociating all the station is done + This is an asynchronous API. + + \param + + \return eHalStatus SUCCESS + FAILURE or RESOURCES + The API finished and failed. + + -------------------------------------------------------------------------------*/ +eHalStatus sme_ChangeMCCBeaconInterval(tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG1, FL("Update Beacon PARAMS ")); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrSendChngMCCBeaconInterval( pMac, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + +/*-------------------------------------------------------------------------------* + + \fn sme_sendBTAmpEvent + + \brief to receive the coex priorty request from BT-AMP PAL + and send the BT_AMP link state to HAL + + \param btAmpEvent - btAmpEvent + + \return eHalStatus: SUCCESS : BTAmp event successfully sent to HAL + + FAILURE: API failed + +-------------------------------------------------------------------------------*/ + +eHalStatus sme_sendBTAmpEvent(tHalHandle hHal, tSmeBtAmpEvent btAmpEvent) +{ + vos_msg_t msg; + tpSmeBtAmpEvent ptrSmeBtAmpEvent = NULL; + eHalStatus status = eHAL_STATUS_FAILURE; + + ptrSmeBtAmpEvent = vos_mem_malloc(sizeof(tSmeBtAmpEvent)); + if (NULL == ptrSmeBtAmpEvent) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to allocate memory for BTAmp event", __func__); + return status; + } + + vos_mem_copy(ptrSmeBtAmpEvent, (void*)&btAmpEvent, sizeof(tSmeBtAmpEvent)); + msg.type = WDA_SIGNAL_BTAMP_EVENT; + msg.reserved = 0; + msg.bodyptr = ptrSmeBtAmpEvent; + + //status = halFW_SendBTAmpEventMesg(pMac, event); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post SIR_HAL_SIGNAL_BTAMP_EVENT message to HAL", __func__); + vos_mem_free(ptrSmeBtAmpEvent); + return status; + } + + return eHAL_STATUS_SUCCESS; + +} + +/* --------------------------------------------------------------------------- + \fn smeIssueFastRoamNeighborAPEvent + \brief API to trigger fast BSS roam independent of RSSI triggers + \param hHal - The handle returned by macOpen. + \param bssid - Pointer to the BSSID to roam to. + \param fastRoamTrig - Trigger to Scan or roam + \param channel - channel number on which fastroam is requested + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus smeIssueFastRoamNeighborAPEvent (tHalHandle hHal, + tANI_U8 *bssid, + tSmeFastRoamTrigger fastRoamTrig, + tANI_U8 channel) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: invoked", __func__); + + if (eSME_ROAM_TRIGGER_SCAN == fastRoamTrig) + { + smsLog(pMac, LOG1, FL("CFG Channel list scan... ")); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_SCAN; + vos_mem_copy((void *)(&pNeighborRoamInfo->cfgRoambssId), + (void *)bssid, sizeof(tSirMacAddr)); + smsLog(pMac, LOG1, "Calling Roam Look Up down Event BSSID" + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pNeighborRoamInfo->cfgRoambssId)); + /* + * As FastReassoc is based on assumption that roamable AP should be + * present into the occupied channel list.We shd add i/p channel + * in occupied channel list if roamable-ap(BSSID in fastreassoc cmd) + * aged out prior to connection and there is no scan from aged out + * to till connection indication. + */ + csrAddChannelToOccupiedChannelList(pMac, channel); + vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac); + if (VOS_STATUS_SUCCESS != vosStatus) + { + smsLog(pMac, LOGE, + FL("CFG Channel list scan state failed with status %d "), + vosStatus); + } + } + else if (eSME_ROAM_TRIGGER_FAST_ROAM == fastRoamTrig) + { + vos_mem_copy((void *)(&pNeighborRoamInfo->cfgRoambssId), + (void *)bssid, sizeof(tSirMacAddr)); + pNeighborRoamInfo->cfgRoamEn = eSME_ROAM_TRIGGER_FAST_ROAM; + smsLog(pMac, LOG1, "Roam to BSSID "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pNeighborRoamInfo->cfgRoambssId)); + + vosStatus = csrNeighborRoamReassocIndCallback(pMac->roam.gVosContext, + 0, + pMac, + 0); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + smsLog(pMac, + LOGE, + FL(" Call to csrNeighborRoamReassocIndCallback failed, status = %d"), + vosStatus); + } + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return vosStatus; +} +/* --------------------------------------------------------------------------- + \fn sme_SetHostOffload + \brief API to set the host offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetHostOffload (tHalHandle hHal, tANI_U8 sessionId, + tpSirHostOffloadReq pRequest) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { +#ifdef WLAN_NS_OFFLOAD + if(SIR_IPV6_NS_OFFLOAD == pRequest->offloadType) + { + status = pmcSetNSOffload( hHal, pRequest, sessionId); + } + else +#endif //WLAN_NS_OFFLOAD + { + status = pmcSetHostOffload (hHal, pRequest, sessionId); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* --------------------------------------------------------------------------- + \fn sme_SetGTKOffload + \brief API to set GTK offload information. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetGTKOffload (tHalHandle hHal, tpSirGtkOffloadParams pRequest, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = pmcSetGTKOffload( hHal, pRequest, sessionId ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetGTKOffload + \brief API to get GTK offload information. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the GTK offload response. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetGTKOffload (tHalHandle hHal, GTKOffloadGetInfoCallback callbackRoutine, + void *callbackContext, tANI_U8 sessionId ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcGetGTKOffload(hHal, callbackRoutine, callbackContext, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/* --------------------------------------------------------------------------- + \fn sme_SetKeepAlive + \brief API to set the Keep Alive feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the Keep Alive request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetKeepAlive (tHalHandle hHal, tANI_U8 sessionId, + tpSirKeepAliveReq pRequest) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = pmcSetKeepAlive (hHal, pRequest, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +#ifdef FEATURE_WLAN_SCAN_PNO +/* --------------------------------------------------------------------------- + \fn sme_SetPreferredNetworkList + \brief API to set the Preferred Network List Offload feature. + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the offload request. + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetPreferredNetworkList (tHalHandle hHal, tpSirPNOScanReq pRequest, tANI_U8 sessionId, void (*callbackRoutine) (void *callbackContext, tSirPrefNetworkFoundInd *pPrefNetworkFoundInd), void *callbackContext ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_PREF_NET_LIST, + sessionId, pRequest->ucNetworksCount)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcSetPreferredNetworkList(hHal, pRequest, sessionId, callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_SetRSSIFilter(tHalHandle hHal, v_U8_t rssiThreshold) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcSetRssiFilter(hHal, rssiThreshold); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +#endif // FEATURE_WLAN_SCAN_PNO + +eHalStatus sme_SetPowerParams(tHalHandle hHal, tSirSetPowerParamsReq* pwParams, tANI_BOOLEAN forced) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + pmcSetPowerParams(hHal, pwParams, forced); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_AbortMacScan + \brief API to cancel MAC scan. + \param hHal - The handle returned by macOpen. + \param sessionId - sessionId on which we need to abort scan. + \param reason - Reason to abort the scan. + \return tSirAbortScanStatus Abort scan status + ---------------------------------------------------------------------------*/ +tSirAbortScanStatus sme_AbortMacScan(tHalHandle hHal, tANI_U8 sessionId, + eCsrAbortReason reason) +{ + tSirAbortScanStatus scanAbortStatus = eSIR_ABORT_SCAN_FAILURE; + eHalStatus status; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + scanAbortStatus = csrScanAbortMacScan(pMac, sessionId, reason); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return ( scanAbortStatus ); +} + +/* ---------------------------------------------------------------------------- + \fn sme_GetOperationChannel + \brief API to get current channel on which STA is parked + this function gives channel information only of infra station or IBSS station + \param hHal, pointer to memory location and sessionId + \returns eHAL_STATUS_SUCCESS + eHAL_STATUS_FAILURE +-------------------------------------------------------------------------------*/ +eHalStatus sme_GetOperationChannel(tHalHandle hHal, tANI_U32 *pChannel, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tCsrRoamSession *pSession; + + if (CSR_IS_SESSION_VALID( pMac, sessionId )) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_INFRASTRUCTURE ) || + ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_IBSS ) || + ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_INFRA_AP ) || + ( pSession->connectedProfile.BSSType == eCSR_BSS_TYPE_START_IBSS )) + { + *pChannel =pSession->connectedProfile.operationChannel; + return eHAL_STATUS_SUCCESS; + } + } + return eHAL_STATUS_FAILURE; +}// sme_GetOperationChannel ends here + +/** + * sme_register_mgmt_frame_ind_callback() - Register a callback for + * management frame indication to PE. + * @hHal: hal pointer + * @callback: callback pointer to be registered + * + * This function is used to register a callback for management + * frame indication to PE. + * + * Return: Success if msg is posted to PE else Failure. + */ +eHalStatus sme_register_mgmt_frame_ind_callback(tHalHandle hHal, + sir_mgmt_frame_ind_callback callback) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + struct sir_sme_mgmt_frame_cb_req *msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + + smsLog(pMac, LOG1, FL(": ENTER")); + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + msg = vos_mem_malloc(sizeof(*msg)); + if (NULL == msg) + { + smsLog(pMac, LOGE, + FL("Not able to allocate memory for eWNI_SME_REGISTER_MGMT_FRAME_CB")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + vos_mem_set(msg, sizeof(*msg), 0); + msg->message_type = eWNI_SME_REGISTER_MGMT_FRAME_CB; + msg->length = sizeof(*msg); + + msg->callback = callback; + status = palSendMBMessage(pMac->hHdd, msg); + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } + return eHAL_STATUS_FAILURE; +} + +/* --------------------------------------------------------------------------- + + \fn sme_RegisterMgtFrame + + \brief To register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_RegisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + tSirRegisterMgmtFrame *pMsg; + tANI_U16 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Invalid Sessionid", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + len = sizeof(tSirRegisterMgmtFrame) + matchLen; + + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, len, 0); + pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; + pMsg->length = len; + pMsg->sessionId = sessionId; + pMsg->registerFrame = VOS_TRUE; + pMsg->frameType = frameType; + pMsg->matchLen = matchLen; + vos_mem_copy(pMsg->matchData, matchData, matchLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn sme_DeregisterMgtFrame + + \brief To De-register managment frame of specified type and subtype. + \param frameType - type of the frame that needs to be passed to HDD. + \param matchData - data which needs to be matched before passing frame + to HDD. + \param matchDataLen - Length of matched data. + \return eHalStatus + -------------------------------------------------------------------------------*/ +eHalStatus sme_DeregisterMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, + tANI_U16 frameType, tANI_U8* matchData, tANI_U16 matchLen) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + tSirRegisterMgmtFrame *pMsg; + tANI_U16 len; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !pSession->sessionActive ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s Invalid Sessionid", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + len = sizeof(tSirRegisterMgmtFrame) + matchLen; + + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, len, 0); + pMsg->messageType = eWNI_SME_REGISTER_MGMT_FRAME_REQ; + pMsg->length = len; + pMsg->registerFrame = VOS_FALSE; + pMsg->frameType = frameType; + pMsg->matchLen = matchLen; + vos_mem_copy(pMsg->matchData, matchData, matchLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_RemainOnChannel + \brief API to request remain on channel for 'x' duration. used in p2p in listen state + \param hHal - The handle returned by macOpen. + \param pRequest - channel + \param duration - duration in ms + \param callback - HDD registered callback to process reaminOnChannelRsp + \param context - HDD Callback param + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_RemainOnChannel(tHalHandle hHal, tANI_U8 sessionId, + tANI_U8 channel, tANI_U32 duration, + remainOnChanCallback callback, + void *pContext, + tANI_U8 isP2PProbeReqAllowed) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = p2pRemainOnChannel (hHal, sessionId, channel, duration, callback, pContext, + isP2PProbeReqAllowed +#ifdef WLAN_FEATURE_P2P_INTERNAL + , eP2PRemainOnChnReasonUnknown +#endif + ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ReportProbeReq + \brief API to enable/disable forwarding of probeReq to apps in p2p. + \param hHal - The handle returned by macOpen. + \param falg: to set the Probe request forarding to wpa_supplicant in listen state in p2p + \return eHalStatus + ---------------------------------------------------------------------------*/ + +#ifndef WLAN_FEATURE_CONCURRENT_P2P +eHalStatus sme_ReportProbeReq(tHalHandle hHal, tANI_U8 flag) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + do + { + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + /* call set in context */ + pMac->p2pContext.probeReqForwarding = flag; + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + } while(0); + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_updateP2pIe + \brief API to set the P2p Ie in p2p context + \param hHal - The handle returned by macOpen. + \param p2pIe - Ptr to p2pIe from HDD. + \param p2pIeLength: length of p2pIe + \return eHalStatus + ---------------------------------------------------------------------------*/ + +eHalStatus sme_updateP2pIe(tHalHandle hHal, void *p2pIe, tANI_U32 p2pIeLength) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + if(NULL != pMac->p2pContext.probeRspIe){ + vos_mem_free(pMac->p2pContext.probeRspIe); + pMac->p2pContext.probeRspIeLength = 0; + } + + pMac->p2pContext.probeRspIe = vos_mem_malloc(p2pIeLength); + if (NULL == pMac->p2pContext.probeRspIe) + { + smsLog(pMac, LOGE, "%s: Unable to allocate P2P IE", __func__); + pMac->p2pContext.probeRspIeLength = 0; + status = eHAL_STATUS_FAILURE; + } + else + { + pMac->p2pContext.probeRspIeLength = p2pIeLength; + + sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG2, + pMac->p2pContext.probeRspIe, + pMac->p2pContext.probeRspIeLength ); + vos_mem_copy((tANI_U8 *)pMac->p2pContext.probeRspIe, p2pIe, + p2pIeLength); + } + + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + + smsLog(pMac, LOG2, "exiting function %s", __func__); + + return(status); +} +#endif + +/* --------------------------------------------------------------------------- + \fn sme_sendAction + \brief API to send action frame from supplicant. + \param hHal - The handle returned by macOpen. + \return eHalStatus + ---------------------------------------------------------------------------*/ + +eHalStatus sme_sendAction(tHalHandle hHal, tANI_U8 sessionId, + const tANI_U8 *pBuf, tANI_U32 len, + tANI_U16 wait, tANI_BOOLEAN noack) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SEND_ACTION, sessionId, 0)); + //acquire the lock for the sme object + status = sme_AcquireGlobalLock(&pMac->sme); + if(HAL_STATUS_SUCCESS(status)) + { + p2pSendAction(hHal, sessionId, pBuf, len, wait, noack); + //release the lock for the sme object + sme_ReleaseGlobalLock( &pMac->sme ); + } + + smsLog(pMac, LOGW, "exiting function %s", __func__); + + return(status); +} + +eHalStatus sme_CancelRemainOnChannel(tHalHandle hHal, tANI_U8 sessionId ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN, sessionId, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = p2pCancelRemainOnChannel (hHal, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +//Power Save Related +eHalStatus sme_p2pSetPs(tHalHandle hHal, tP2pPsConfig * data) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + status = p2pSetPs (hHal, data); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_GetFramesLog + \brief a wrapper function that client calls to register a callback to get + mgmt frames logged + \param flag - flag tells to clear OR send the frame log buffer + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_GetFramesLog(tHalHandle hHal, tANI_U8 flag) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pGetFrameLogCmd; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pGetFrameLogCmd = csrGetCommandBuffer(pMac); + if (pGetFrameLogCmd) + { + pGetFrameLogCmd->command = eSmeCommandGetFrameLogRequest; + pGetFrameLogCmd->u.getFramelogCmd.getFrameLogCmdFlag= flag; + + status = csrQueueSmeCommand(pMac, pGetFrameLogCmd, eANI_BOOLEAN_TRUE); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("fail to send msg status = %d\n"), status ); + csrReleaseCommandScan(pMac, pGetFrameLogCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer\n")); + status = eHAL_STATUS_RESOURCES; + } + sme_ReleaseGlobalLock( &pMac->sme); + } + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_InitMgmtFrameLogging + + \brief + SME will pass this request to lower mac to initialize Frame Logging. + + \param + + hHal - The handle returned by macOpen. + + wlanFWLoggingInitParam - Params to initialize frame logging + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_InitMgmtFrameLogging( tHalHandle hHal, + tSirFWLoggingInitParam *wlanFWLoggingInitParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirFWLoggingInitParam msg; + + msg = vos_mem_malloc(sizeof(tSirFWLoggingInitParam)); + + if (NULL == msg) + { + smsLog(pMac, LOGE, FL("Failed to alloc mem of size %zu for msg"), + sizeof(*msg)); + return eHAL_STATUS_FAILED_ALLOC; + } + *msg = *wlanFWLoggingInitParam; + + if ( eHAL_STATUS_SUCCESS == ( status = + sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = msg; + vosMessage.type = WDA_MGMT_LOGGING_INIT_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_free(msg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock error")); + vos_mem_free(msg); + } + return(status); +} +/* --------------------------------------------------------------------------- + + \fn sme_StartRssiMonitoring + + \brief + SME will pass this request to lower mac to start monitoring rssi range on + a bssid. + + \param + + hHal - The handle returned by macOpen. + + tSirRssiMonitorReq req- depict the monitor req params. + + \return eHalStatus + +--------------------------------------------------------------------------- */ +eHalStatus sme_StartRssiMonitoring( tHalHandle hHal, + tSirRssiMonitorReq *req) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if ( eHAL_STATUS_SUCCESS == ( status = + sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = req; + vosMessage.type = WDA_START_RSSI_MONITOR_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_StopRssiMonitoring + + \brief + SME will pass this request to lower mac to stop monitoring rssi range on + a bssid. + + \param + + hHal - The handle returned by macOpen. + + tSirRssiMonitorReq req- depict the monitor req params. + + \return eHalStatus + +--------------------------------------------------------------------------- */ +eHalStatus sme_StopRssiMonitoring(tHalHandle hHal, + tSirRssiMonitorReq *req) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + if ( eHAL_STATUS_SUCCESS == ( status = + sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = req; + vosMessage.type = WDA_STOP_RSSI_MONITOR_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureRxpFilter + + \brief + SME will pass this request to lower mac to set/reset the filter on RXP for + multicast & broadcast traffic. + + \param + + hHal - The handle returned by macOpen. + + filterMask- Currently the API takes a 1 or 0 (set or reset) as filter. + Basically to enable/disable the filter (to filter "all" mcbc traffic) based + on this param. In future we can use this as a mask to set various types of + filters as suggested below: + FILTER_ALL_MULTICAST: + FILTER_ALL_BROADCAST: + FILTER_ALL_MULTICAST_BROADCAST: + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureRxpFilter( tHalHandle hHal, + tpSirWlanSetRxpFilters wlanRxpFilterParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = wlanRxpFilterParam; + vosMessage.type = WDA_CFG_RXP_FILTER_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_update_hal_int_param + + \brief + SME will pass this request to lower mac to indicate that the host needs to + update the cfg item + + \param + + hHal - The handle returned by macOpen. + + cfg_id- cfg param id + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ + +eHalStatus sme_update_cfg_int_param(tHalHandle hHal, + tANI_U32 cfg_id) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirUpdateCfgIntParam updateCfgIntParam = + vos_mem_malloc(sizeof(tSirUpdateCfgIntParam)); + + if (updateCfgIntParam == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_alloc for updateCfgIntParam", __func__); + return eHAL_STATUS_FAILURE; + } + + updateCfgIntParam->cfgId = cfg_id; + /* + * This API expect user must have updated cfg item using cfg API's. + * Hence it just need the cfg param id not the cfg value. + */ + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = updateCfgIntParam; + vosMessage.type = WDA_UPDATE_CFG_INT_PARAM; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + status = eHAL_STATUS_FAILURE; + vos_mem_free(updateCfgIntParam); + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + status = eHAL_STATUS_FAILURE; + vos_mem_free(updateCfgIntParam); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureSuspendInd + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be suspended + + \param + + hHal - The handle returned by macOpen. + + wlanSuspendParam- Depicts the wlan suspend params + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureSuspendInd( tHalHandle hHal, + tpSirWlanSuspendParam wlanSuspendParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = wlanSuspendParam; + vosMessage.type = WDA_WLAN_SUSPEND_IND; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_ConfigureResumeReq + + \brief + SME will pass this request to lower mac to Indicate that the wlan needs to + be Resumed + + \param + + hHal - The handle returned by macOpen. + + wlanResumeParam- Depicts the wlan resume params + + + \return eHalStatus + + +--------------------------------------------------------------------------- */ +eHalStatus sme_ConfigureResumeReq( tHalHandle hHal, + tpSirWlanResumeParam wlanResumeParam) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + /* serialize the req through MC thread */ + vosMessage.bodyptr = wlanResumeParam; + vosMessage.type = WDA_WLAN_RESUME_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraSessionId + + \brief To get the session ID for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + + \return sessionid, -1 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_S8 sme_GetInfraSessionId(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_S8 sessionid = -1; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + sessionid = csrGetInfraSessionId( pMac); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (sessionid); +} + +tANI_U32 sme_get_sessionid_from_activeList(tpAniSirGlobal mac) +{ + tListElem *entry = NULL; + tSmeCmd *command = NULL; + tANI_U32 session_id = 0; + + entry = csrLLPeekHead( &mac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if ( entry ) { + command = GET_BASE_ADDR( entry, tSmeCmd, Link ); + session_id = command->sessionId; + } + + return (session_id); +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetInfraOperationChannel + + \brief To get the operating channel for infra session, if connected + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param sessionId - the sessionId returned by sme_OpenSession. + + \return operating channel, 0 if infra session is not connected + + -------------------------------------------------------------------------------*/ +tANI_U8 sme_GetInfraOperationChannel( tHalHandle hHal, tANI_U8 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 channel = 0; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + channel = csrGetInfraOperationChannel( pMac, sessionId); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (channel); +} + +//This routine will return poerating channel on which other BSS is operating to be used for concurrency mode. +//If other BSS is not up or not connected it will return 0 +tANI_U8 sme_GetConcurrentOperationChannel( tHalHandle hHal ) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tANI_U8 channel = 0; + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + channel = csrGetConcurrentOperationChannel( pMac ); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH, "%s: " + " Other Concurrent Channel = %d", __func__,channel); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (channel); +} + +#ifdef FEATURE_WLAN_SCAN_PNO +/****************************************************************************** +* +* Name: sme_PreferredNetworkFoundInd +* +* Description: +* Invoke Preferred Network Found Indication +* +* Parameters: +* hHal - HAL handle for device +* pMsg - found network description +* +* Returns: eHalStatus +* +******************************************************************************/ +eHalStatus sme_PreferredNetworkFoundInd (tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd = (tSirPrefNetworkFoundInd *)pMsg; + v_U8_t dumpSsId[SIR_MAC_MAX_SSID_LENGTH + 1]; + tANI_U8 ssIdLength = 0; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + if (pPrefNetworkFoundInd->ssId.length > 0) + { + ssIdLength = CSR_MIN(SIR_MAC_MAX_SSID_LENGTH, + pPrefNetworkFoundInd->ssId.length); + vos_mem_copy(dumpSsId, pPrefNetworkFoundInd->ssId.ssId, ssIdLength); + dumpSsId[ssIdLength] = 0; + smsLog(pMac, LOG1, FL(" SSID=%s frame length %d"), + dumpSsId, pPrefNetworkFoundInd->frameLength); + + /* Flush scan results, So as to avoid indication/updation of + * stale entries, which may not have aged out during APPS collapse + */ + sme_ScanFlushResult(hHal,0); + + //Save the frame to scan result + if (pPrefNetworkFoundInd->mesgLen > sizeof(tSirPrefNetworkFoundInd)) + { + //we may have a frame + status = csrScanSavePreferredNetworkFound(pMac, + pPrefNetworkFoundInd); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, FL(" fail to save preferred network")); + } + } + else + { + smsLog(pMac, LOGE, FL(" not enough data length %u needed %zu"), + pPrefNetworkFoundInd->mesgLen, sizeof(tSirPrefNetworkFoundInd)); + } + + /* Call Preferred Netowrk Found Indication callback routine. */ + if (HAL_STATUS_SUCCESS(status) && (pMac->pmc.prefNetwFoundCB != NULL)) + { + pMac->pmc.prefNetwFoundCB( + pMac->pmc.preferredNetworkFoundIndCallbackContext, + pPrefNetworkFoundInd); + } + } + else + { + smsLog(pMac, LOGE, "%s: callback failed - SSID is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + } + + + return(status); +} + +#endif // FEATURE_WLAN_SCAN_PNO + + +eHalStatus sme_GetCfgValidChannels(tHalHandle hHal, tANI_U8 *aValidChannels, tANI_U32 *len) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrGetCfgValidChannels(pMac, aValidChannels, len); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +eHalStatus sme_SetCfgScanControlList(tHalHandle hHal, tANI_U8 *countryCode, tCsrChannel *pChannelList) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + csrSetCfgScanControlList(pMac, countryCode, pChannelList); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetTxPerTracking + + \brief Set Tx PER tracking configuration parameters + + \param hHal - The handle returned by macOpen. + \param pTxPerTrackingConf - Tx PER configuration parameters + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPerTracking(tHalHandle hHal, + void (*pCallbackfn) (void *pCallbackContext), + void *pCallbackContext, + tpSirTxPerTrackingParam pTxPerTrackingParam) +{ + vos_msg_t msg; + tpSirTxPerTrackingParam pTxPerTrackingParamReq = NULL; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) ) + { + pMac->sme.pTxPerHitCallback = pCallbackfn; + pMac->sme.pTxPerHitCbContext = pCallbackContext; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + // free this memory in failure case or WDA request callback function + pTxPerTrackingParamReq = vos_mem_malloc(sizeof(tSirTxPerTrackingParam)); + if (NULL == pTxPerTrackingParamReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to allocate memory for tSirTxPerTrackingParam", __func__); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pTxPerTrackingParamReq, (void*)pTxPerTrackingParam, + sizeof(tSirTxPerTrackingParam)); + msg.type = WDA_SET_TX_PER_TRACKING_REQ; + msg.reserved = 0; + msg.bodyptr = pTxPerTrackingParamReq; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post WDA_SET_TX_PER_TRACKING_REQ message to WDA", __func__); + vos_mem_free(pTxPerTrackingParamReq); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HandleChangeCountryCode + + \brief Change Country code, Reg Domain and channel list + + \details Country Code Priority + 0 = 11D > Configured Country > NV + 1 = Configured Country > 11D > NV + If Supplicant country code is priority than 11d is disabled. + If 11D is enabled, we update the country code after every scan. + Hence when Supplicant country code is priority, we don't need 11D info. + Country code from Supplicant is set as current courtry code. + User can send reset command XX (instead of country code) to reset the + country code to default values which is read from NV. + In case of reset, 11D is enabled and default NV code is Set as current country code + If 11D is priority, + Than Supplicant country code code is set to default code. But 11D code is set as current country code + + \param pMac - The handle returned by macOpen. + \param pMsgBuf - MSG Buffer + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tAniChangeCountryCodeReq *pMsg; + v_REGDOMAIN_t domainIdIoctl; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + static uNvTables nvTables; + pMsg = (tAniChangeCountryCodeReq *)pMsgBuf; + + if (pMac->scan.fcc_constraint) + { + pMac->scan.fcc_constraint = false; + if (VOS_TRUE== vos_mem_compare(pMac->scan.countryCodeCurrent, + pMsg->countryCode, 2)) + { + csrInitGetChannels(pMac); + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + csrScanFilterResults(pMac); + return status ; + } + } + + + /* if the reset Supplicant country code command is triggered, enable 11D, reset the NV country code and return */ + if( VOS_TRUE == vos_mem_compare(pMsg->countryCode, SME_INVALID_COUNTRY_CODE, 2) ) + { + pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal; + + vosStatus = vos_nv_readDefaultCountryTable( &nvTables ); + + /* read the country code from NV and use it */ + if ( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_copy(pMsg->countryCode, + nvTables.defaultCountryTable.countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + else + { + status = eHAL_STATUS_FAILURE; + return status; + } + /* Update the 11d country to default country from NV bin so that when + * callback is received for this default country, driver will not + * disable the 11d taking it as valid country by user. + */ + smsLog(pMac, LOG1, + FL("Set default country code (%c%c) from NV as invalid country received"), + pMsg->countryCode[0],pMsg->countryCode[1]); + vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + else + { + /* if Supplicant country code has priority, disable 11d */ + if(pMac->roam.configParam.fSupplicantCountryCodeHasPriority && + pMsg->countryFromUserSpace) + { + pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + } + } + + /* WEXT set country code means + * 11D should be supported? + * 11D Channel should be enforced? + * 11D Country code should be matched? + * 11D Reg Domian should be matched? + * Country string changed */ + if(pMac->roam.configParam.Is11dSupportEnabled && + pMac->roam.configParam.fEnforce11dChannels && + pMac->roam.configParam.fEnforceCountryCodeMatch && + pMac->roam.configParam.fEnforceDefaultDomain && + !csrSave11dCountryString(pMac, pMsg->countryCode, eANI_BOOLEAN_TRUE)) + { + /* All 11D related options are already enabled + * Country string is not changed + * Do not need do anything for country code change request */ + return eHAL_STATUS_SUCCESS; + } + + /* Set Current Country code and Current Regulatory domain */ + status = csrSetCountryCode(pMac, pMsg->countryCode, NULL); + if(eHAL_STATUS_SUCCESS != status) + { + /* Supplicant country code failed. So give 11D priority */ + pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal; + smsLog(pMac, LOGE, "Set Country Code Fail %d", status); + return status; + } + + /* overwrite the defualt country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, + pMac->scan.countryCodeCurrent, + WNI_CFG_COUNTRY_CODE_LEN); + + /* Get Domain ID from country code */ + status = csrGetRegulatoryDomainForCountry(pMac, + pMac->scan.countryCodeCurrent, + (v_REGDOMAIN_t *) &domainIdIoctl, + COUNTRY_QUERY); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get regId %d"), domainIdIoctl ); + return status; + } + else if (REGDOMAIN_WORLD == domainIdIoctl) + { + /* Supplicant country code is invalid, so we are on world mode now. So + give 11D chance to update */ + pMac->roam.configParam.Is11dSupportEnabled = pMac->roam.configParam.Is11dSupportEnabledOriginal; + smsLog(pMac, LOG1, FL("Country Code unrecognized by driver")); + } + + + status = WDA_SetRegDomain(pMac, domainIdIoctl, pMsg->sendRegHint); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to set regId %d"), domainIdIoctl ); + return status; + } + else + { + //if 11d has priority, clear currentCountryBssid & countryCode11d to get + //set again if we find AP with 11d info during scan + status = csrSetRegulatoryDomain(pMac, domainIdIoctl, NULL); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("fail to set regId.status : %d"), status); + } + if (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) + { + smsLog( pMac, LOGW, FL("Clearing currentCountryBssid, countryCode11d")); + vos_mem_zero(&pMac->scan.currentCountryBssid, sizeof(tCsrBssid)); + vos_mem_zero( pMac->scan.countryCode11d, sizeof( pMac->scan.countryCode11d ) ); + } + } +#ifndef CONFIG_ENABLE_LINUX_REG + /* set to default domain ID */ + pMac->scan.domainIdDefault = pMac->scan.domainIdCurrent; + + /* get the channels based on new cc */ + status = csrInitGetChannels( pMac ); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + return status; + } + + /* reset info based on new cc, and we are done */ + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + /* Country code Changed, Purge Only scan result + * which does not have channel number belong to 11d + * channel list + */ + csrScanFilterResults(pMac); + +#endif + if( pMsg->changeCCCallback ) + { + ((tSmeChangeCountryCallback)(pMsg->changeCCCallback))((void *)pMsg->pDevContext); + } + + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HandleChangeCountryCodeByUser + + \brief Change Country code, Reg Domain and channel list + + If Supplicant country code is priority than 11d is disabled. + If 11D is enabled, we update the country code after every scan. + Hence when Supplicant country code is priority, we don't need 11D info. + Country code from Supplicant is set as current country code. + + \param pMac - The handle returned by macOpen. + \param pMsg - Carrying new CC & domain set in kernel by user + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleChangeCountryCodeByUser(tpAniSirGlobal pMac, + tAniGenericChangeCountryCodeReq *pMsg) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + v_REGDOMAIN_t reg_domain_id; + v_BOOL_t is11dCountry = VOS_FALSE; + + smsLog(pMac, LOG1, FL(" called")); + reg_domain_id = (v_REGDOMAIN_t)pMsg->domain_index; + + if (memcmp(pMsg->countryCode, pMac->scan.countryCode11d, + VOS_COUNTRY_CODE_LEN) == 0) + { + is11dCountry = VOS_TRUE; + } + + smsLog( pMac, LOG1, FL("pMsg->countryCode : %c%c," + "pMac->scan.countryCode11d : %c%c\n"), + pMsg->countryCode[0], pMsg->countryCode[1], + pMac->scan.countryCode11d[0], pMac->scan.countryCode11d[1]); + /* Set the country code given by userspace when 11dOriginal is FALSE + * when 11doriginal is True,is11dCountry =0 and + * fSupplicantCountryCodeHasPriority = 0, then revert the country code, + * and return failure + */ + if (pMac->roam.configParam.Is11dSupportEnabledOriginal == true) + { + if ((!is11dCountry) && (!pMac->roam.configParam.fSupplicantCountryCodeHasPriority)&& + (!pMac->roam.configParam.fEnforceCountryCode) ) + { + + smsLog( pMac, LOGW, FL(" incorrect country being set, nullify this request")); + + status = csrGetRegulatoryDomainForCountry(pMac, + pMac->scan.countryCode11d, + (v_REGDOMAIN_t *) ®_domain_id, + COUNTRY_IE); + + return eHAL_STATUS_FAILURE; + } + } + /* if Supplicant country code has priority, disable 11d */ + if ((!is11dCountry) && + (pMac->roam.configParam.fSupplicantCountryCodeHasPriority) && + (!pMac->roam.configParam.fEnforceCountryCode)) + { + pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE; + smsLog( pMac, LOG1, FL(" 11d is being disabled")); + } + + pMac->roam.configParam.fEnforceCountryCode = eANI_BOOLEAN_FALSE; + vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + + + status = csrSetRegulatoryDomain(pMac, reg_domain_id, NULL); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("fail to set regId.status : %d"), status); + } + status = WDA_SetRegDomain(pMac, reg_domain_id, eSIR_TRUE); + + if (VOS_FALSE == is11dCountry ) + { + /* overwrite the defualt country code */ + vos_mem_copy(pMac->scan.countryCodeDefault, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + /* set to default domain ID */ + pMac->scan.domainIdDefault = pMac->scan.domainIdCurrent; + } + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to set regId %d"), reg_domain_id ); + return status; + } + else + { + //if 11d has priority, clear currentCountryBssid & countryCode11d to get + //set again if we find AP with 11d info during scan + if((!pMac->roam.configParam.fSupplicantCountryCodeHasPriority) && + (VOS_FALSE == is11dCountry )) + { + smsLog( pMac, LOGW, FL("Clearing currentCountryBssid, countryCode11d")); + vos_mem_zero(&pMac->scan.currentCountryBssid, sizeof(tCsrBssid)); + vos_mem_zero( pMac->scan.countryCode11d, sizeof( pMac->scan.countryCode11d ) ); + } + } + + /* get the channels based on new cc */ + status = csrInitGetChannels(pMac); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + return status; + } + + /* reset info based on new cc, and we are done */ + csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE); + if (VOS_TRUE == is11dCountry) + { + pMac->scan.f11dInfoApplied = eANI_BOOLEAN_TRUE; + pMac->scan.f11dInfoReset = eANI_BOOLEAN_FALSE; + } + /* Country code Changed, Purge Only scan result + * which does not have channel number belong to 11d + * channel list + */ + csrScanFilterResults(pMac); + // Do active scans after the country is set by User hints or Country IE + pMac->scan.curScanType = eSIR_ACTIVE_SCAN; + sme_DisconnectConnectedSessions(pMac); + smsLog(pMac, LOG1, FL(" returned")); + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HandleChangeCountryCodeByCore + + \brief Update Country code in the driver if set by kernel as world + + If 11D is enabled, we update the country code after every scan & notify kernel. + This is to make sure kernel & driver are in sync in case of CC found in + driver but not in kernel database + + \param pMac - The handle returned by macOpen. + \param pMsg - Carrying new CC set in kernel + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleChangeCountryCodeByCore(tpAniSirGlobal pMac, tAniGenericChangeCountryCodeReq *pMsg) +{ + eHalStatus status; + + smsLog(pMac, LOG1, FL(" called")); + + //this is to make sure kernel & driver are in sync in case of CC found in + //driver but not in kernel database + if (('0' == pMsg->countryCode[0]) && ('0' == pMsg->countryCode[1])) + { + smsLog( pMac, LOGW, FL("Setting countryCode11d & countryCodeCurrent to world CC")); + vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode, + WNI_CFG_COUNTRY_CODE_LEN); + } + + status = WDA_SetRegDomain(pMac, REGDOMAIN_WORLD, eSIR_TRUE); + + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to set regId") ); + return status; + } + else + { + status = csrSetRegulatoryDomain(pMac, REGDOMAIN_WORLD, NULL); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog( pMac, LOGE, FL("fail to set regId.status : %d"), status); + } + status = csrInitGetChannels(pMac); + if ( status != eHAL_STATUS_SUCCESS ) + { + smsLog( pMac, LOGE, FL(" fail to get Channels ")); + } + else + { + csrInitChannelList(pMac); + } + } + /* Country code Changed, Purge Only scan result + * which does not have channel number belong to 11d + * channel list + */ + csrScanFilterResults(pMac); + smsLog(pMac, LOG1, FL(" returned")); + return eHAL_STATUS_SUCCESS; +} + +/* --------------------------------------------------------------------------- + + \fn sme_DisconnectConnectedSessions + + \brief Disconnect STA and P2P client session if channel is not supported + + If new country code does not support the channel on which STA/P2P client + is connetced, it sends the disconnect to the AP/P2P GO + + \param pMac - The handle returned by macOpen + + \return eHalStatus + + -------------------------------------------------------------------------------*/ + +void sme_DisconnectConnectedSessions(tpAniSirGlobal pMac) +{ + v_U8_t i, sessionId, isChanFound = false; + tANI_U8 currChannel; + + for (sessionId=0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) + { + if (csrIsSessionClientAndConnected(pMac, sessionId)) + { + isChanFound = false; + //Session is connected.Check the channel + currChannel = csrGetInfraOperationChannel(pMac, sessionId); + smsLog(pMac, LOGW, "Current Operating channel : %d, session :%d", + currChannel, sessionId); + for (i=0; i < pMac->scan.base20MHzChannels.numChannels; i++) + { + if (pMac->scan.base20MHzChannels.channelList[i] == currChannel) + { + isChanFound = true; + break; + } + } + + if (!isChanFound) + { + for (i=0; i < pMac->scan.base40MHzChannels.numChannels; i++) + { + if (pMac->scan.base40MHzChannels.channelList[i] == currChannel) + { + isChanFound = true; + break; + } + } + } + if (!isChanFound) + { + smsLog(pMac, LOGW, "%s : Disconnect Session :%d", __func__, sessionId); + csrRoamDisconnect(pMac, sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED); + } + } + } +} +/* --------------------------------------------------------------------------- + + \fn sme_HandleGenericChangeCountryCode + + \brief Change Country code, Reg Domain and channel list + + If Supplicant country code is priority than 11d is disabled. + If 11D is enabled, we update the country code after every scan. + Hence when Supplicant country code is priority, we don't need 11D info. + Country code from kernel is set as current country code. + + \param pMac - The handle returned by macOpen. + \param pMsgBuf - message buffer + + \return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HandleGenericChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf) +{ + tAniGenericChangeCountryCodeReq *pMsg; + v_REGDOMAIN_t reg_domain_id; + + smsLog(pMac, LOG1, FL(" called")); + pMsg = (tAniGenericChangeCountryCodeReq *)pMsgBuf; + reg_domain_id = (v_REGDOMAIN_t)pMsg->domain_index; + + if (REGDOMAIN_COUNT == reg_domain_id) + { + sme_HandleChangeCountryCodeByCore(pMac, pMsg); + } + else + { + sme_HandleChangeCountryCodeByUser(pMac, pMsg); + } + smsLog(pMac, LOG1, FL(" returned")); + return eHAL_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +eHalStatus sme_8023MulticastList (tHalHandle hHal, tANI_U8 sessionId, tpSirRcvFltMcAddrList pMulticastAddrs) +{ + tpSirRcvFltMcAddrList pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = NULL; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: " + "ulMulticastAddrCnt=%d, multicastAddr[0]=%p", __func__, + pMulticastAddrs->ulMulticastAddrCnt, + pMulticastAddrs->multicastAddr[0]); + + /* + *Find the connected Infra / P2P_client connected session + */ + if (CSR_IS_SESSION_VALID(pMac, sessionId) && + csrIsConnStateInfra(pMac, sessionId)) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + } + + if(pSession == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, "%s: Unable to find " + "the right session", __func__); + return eHAL_STATUS_FAILURE; + } + + pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to " + "allocate memory for 8023 Multicast List request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + if( !csrIsConnStateConnectedInfra (pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Ignoring the " + "indication as we are not connected", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRequestBuf, pMulticastAddrs, sizeof(tSirRcvFltMcAddrList)); + + vos_mem_copy(pRequestBuf->selfMacAddr, pSession->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pRequestBuf->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + msg.type = WDA_8023_MULTICAST_LIST_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to " + "post WDA_8023_MULTICAST_LIST message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_ReceiveFilterSetFilter(tHalHandle hHal, tpSirRcvPktFilterCfgType pRcvPktFilterCfg, + tANI_U8 sessionId) +{ + tpSirRcvPktFilterCfgType pRequestBuf; + v_SINT_t allocSize; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + v_U8_t idx=0; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterType=%d, " + "filterId = %d", __func__, + pRcvPktFilterCfg->filterType, pRcvPktFilterCfg->filterId); + + allocSize = sizeof(tSirRcvPktFilterCfgType); + + pRequestBuf = vos_mem_malloc(allocSize); + + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to " + "allocate memory for Receive Filter Set Filter request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + + if( NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Session Not found ", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRcvPktFilterCfg->selfMacAddr, pSession->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pRcvPktFilterCfg->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + vos_mem_copy(pRequestBuf, pRcvPktFilterCfg, allocSize); + + msg.type = WDA_RECEIVE_FILTER_SET_FILTER_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Pkt Flt Req : " + "FT %d FID %d ", + pRequestBuf->filterType, pRequestBuf->filterId); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "Pkt Flt Req : " + "params %d CT %d", + pRequestBuf->numFieldParams, pRequestBuf->coalesceTime); + + for (idx=0; idxnumFieldParams; idx++) + { + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Proto %d Comp Flag %d ", + pRequestBuf->paramsData[idx].protocolLayer, + pRequestBuf->paramsData[idx].cmpFlag); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Data Offset %d Data Len %d", + pRequestBuf->paramsData[idx].dataOffset, + pRequestBuf->paramsData[idx].dataLength); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "CData: %d:%d:%d:%d:%d:%d", + pRequestBuf->paramsData[idx].compareData[0], + pRequestBuf->paramsData[idx].compareData[1], + pRequestBuf->paramsData[idx].compareData[2], + pRequestBuf->paramsData[idx].compareData[3], + pRequestBuf->paramsData[idx].compareData[4], + pRequestBuf->paramsData[idx].compareData[5]); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "MData: %d:%d:%d:%d:%d:%d", + pRequestBuf->paramsData[idx].dataMask[0], + pRequestBuf->paramsData[idx].dataMask[1], + pRequestBuf->paramsData[idx].dataMask[2], + pRequestBuf->paramsData[idx].dataMask[3], + pRequestBuf->paramsData[idx].dataMask[4], + pRequestBuf->paramsData[idx].dataMask[5]); + + } + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post " + "WDA_RECEIVE_FILTER_SET_FILTER message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + +eHalStatus sme_GetFilterMatchCount(tHalHandle hHal, + FilterMatchCountCallback callbackRoutine, + void *callbackContext, + tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "+%s", __func__); + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme))) + { + pmcGetFilterMatchCount(hHal, callbackRoutine, callbackContext, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "-%s", __func__); + + return (status); +} + +eHalStatus sme_ReceiveFilterClearFilter(tHalHandle hHal, tpSirRcvFltPktClearParam pRcvFltPktClearParam, + tANI_U8 sessionId) +{ + tpSirRcvFltPktClearParam pRequestBuf; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, "%s: filterId = %d", __func__, + pRcvFltPktClearParam->filterId); + + pRequestBuf = vos_mem_malloc(sizeof(tSirRcvFltPktClearParam)); + if (NULL == pRequestBuf) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for Receive Filter " + "Clear Filter request", __func__); + return eHAL_STATUS_FAILED_ALLOC; + } + if( NULL == pSession ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session Not find ", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pRcvFltPktClearParam->selfMacAddr, pSession->selfMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pRcvFltPktClearParam->bssId, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + + vos_mem_copy(pRequestBuf, pRcvFltPktClearParam, sizeof(tSirRcvFltPktClearParam)); + + msg.type = WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ; + msg.reserved = 0; + msg.bodyptr = pRequestBuf; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, sessionId, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Not able to post " + "WDA_RECEIVE_FILTER_CLEAR_FILTER message to WDA", __func__); + vos_mem_free(pRequestBuf); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +/* --------------------------------------------------------------------------- + \fn sme_PreChannelSwitchIndFullPowerCB + \brief call back function for the PMC full power request because of pre + channel switch. + \param callbackContext + \param status + ---------------------------------------------------------------------------*/ +void sme_PreChannelSwitchIndFullPowerCB(void *callbackContext, + eHalStatus status) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal)callbackContext; + tSirMbMsg *pMsg; + tANI_U16 msgLen; + + msgLen = (tANI_U16)(sizeof( tSirMbMsg )); + pMsg = vos_mem_malloc(msgLen); + if ( NULL != pMsg ) + { + vos_mem_set(pMsg, msgLen, 0); + pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER); + pMsg->msgLen = pal_cpu_to_be16(msgLen); + status = palSendMBMessage(pMac->hHdd, pMsg); + } + + return; +} + +/* --------------------------------------------------------------------------- + \fn sme_HandlePreChannelSwitchInd + \brief Processes the indcation from PE for pre-channel switch. + \param hHal + \- The handle returned by macOpen. return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestFullPower(hHal, sme_PreChannelSwitchIndFullPowerCB, + pMac, eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_HandlePostChannelSwitchInd + \brief Processes the indcation from PE for post-channel switch. + \param hHal + \- The handle returned by macOpen. return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_HandlePostChannelSwitchInd(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = pmcRequestBmps(hHal, NULL, NULL); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (status); +} + +/* --------------------------------------------------------------------------- + + \fn sme_IsChannelValid + + \brief To check if the channel is valid for currently established domain + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param channel - channel to verify + + \return TRUE/FALSE, TRUE if channel is valid + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsChannelValid(tHalHandle hHal, tANI_U8 channel) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_BOOLEAN valid = FALSE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + + valid = csrRoamIsChannelValid( pMac, channel); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (valid); +} + +/* --------------------------------------------------------------------------- + \fn sme_SetFreqBand + \brief Used to set frequency band. + \param hHal + \eBand band value to be configured + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetFreqBand(tHalHandle hHal, eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrSetBand(hHal, eBand); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_GetFreqBand + \brief Used to get the current band settings. + \param hHal + \pBand pointer to hold band value + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetFreqBand(tHalHandle hHal, eCsrBand *pBand) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + *pBand = csrGetCurrentBand( hHal ); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +#ifdef WLAN_WAKEUP_EVENTS +/****************************************************************************** + \fn sme_WakeReasonIndCallback + + \brief + a callback function called when SME received eWNI_SME_WAKE_REASON_IND event from WDA + + \param hHal - HAL handle for device + \param pMsg - Message body passed from WDA; includes Wake Reason Indication parameter + + \return eHalStatus +******************************************************************************/ +eHalStatus sme_WakeReasonIndCallback (tHalHandle hHal, void* pMsg) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirWakeReasonInd *pWakeReasonInd = (tSirWakeReasonInd *)pMsg; + + if (NULL == pMsg) + { + smsLog(pMac, LOGE, "in %s msg ptr is NULL", __func__); + status = eHAL_STATUS_FAILURE; + } + else + { + smsLog(pMac, LOG2, "SME: entering sme_WakeReasonIndCallback"); + + /* Call Wake Reason Indication callback routine. */ + if (pMac->pmc.wakeReasonIndCB != NULL) + pMac->pmc.wakeReasonIndCB(pMac->pmc.wakeReasonIndCBContext, pWakeReasonInd); + + smsLog(pMac, LOG1, "Wake Reason Indication in %s(), reason=%d", __func__, pWakeReasonInd->ulReason); + } + + return(status); +} +#endif // WLAN_WAKEUP_EVENTS + + +/** + * sme_SetMaxTxPower() - Set the Maximum Transmit Power + * + * @hHal: hal pointer. + * @bssid: bssid to set the power cap for + * @self_mac_addr:self mac address + * @db: power to set in dB + * + * Set the maximum transmit power dynamically. + * + * Return: eHalStatus + * + */ +eHalStatus sme_SetMaxTxPower(tHalHandle hHal, tSirMacAddr bssid, + tSirMacAddr self_mac_addr, v_S7_t db) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *set_max_tx_pwr; + + if (pMac->max_power_cmd_pending) + { + smsLog(pMac, LOG1, + FL("set max tx power already in progress")); + return eHAL_STATUS_RESOURCES; + } + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW, NO_SESSION, 0)); + smsLog(pMac, LOG1, + FL("bssid :" MAC_ADDRESS_STR " self addr: "MAC_ADDRESS_STR" power %d Db"), + MAC_ADDR_ARRAY(bssid), MAC_ADDR_ARRAY(self_mac_addr), db); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + set_max_tx_pwr = csrGetCommandBuffer(pMac); + if (set_max_tx_pwr) + { + set_max_tx_pwr->command = eSmeCommandSetMaxTxPower; + vos_mem_copy(set_max_tx_pwr->u.set_tx_max_pwr.bssid, + bssid, SIR_MAC_ADDR_LENGTH); + vos_mem_copy(set_max_tx_pwr->u.set_tx_max_pwr.self_sta_mac_addr, + self_mac_addr, SIR_MAC_ADDR_LENGTH); + set_max_tx_pwr->u.set_tx_max_pwr.power = db; + pMac->max_power_cmd_pending = true; + status = csrQueueSmeCommand(pMac, set_max_tx_pwr, eANI_BOOLEAN_TRUE); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("fail to send msg status = %d"), status ); + csrReleaseCommandScan(pMac, set_max_tx_pwr); + pMac->max_power_cmd_pending = false; + } + } + else + { + smsLog(pMac, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + sme_ReleaseGlobalLock( &pMac->sme); + } + return (status); +} + +/** + * sme_SetMaxTxPowerPerBand() - Set the Maximum Transmit Power + * specific to band dynamically + * @band: Band for which power needs to be applied + * @dB: power to set in dB + * @hal: HAL handle + * + * Set the maximum transmit power dynamically per band + * + * Return: eHalStatus + */ +eHalStatus sme_SetMaxTxPowerPerBand(eCsrBand band, v_S7_t dB, + tHalHandle hal) +{ + vos_msg_t msg; + eHalStatus status; + tSmeCmd *set_max_tx_pwr_per_band; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + + if (mac_ctx->max_power_cmd_pending) + { + smsLog(mac_ctx, LOG1, + FL("set max tx power already in progress")); + return eHAL_STATUS_RESOURCES; + } + + smsLog(mac_ctx, LOG1, + FL("band : %d power %d dB"), + band, dB); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (HAL_STATUS_SUCCESS(status)) { + set_max_tx_pwr_per_band = csrGetCommandBuffer(mac_ctx); + if (set_max_tx_pwr_per_band) { + set_max_tx_pwr_per_band->command = eSmeCommandSetMaxTxPowerPerBand; + set_max_tx_pwr_per_band->u.set_tx_max_pwr_per_band.band = band; + set_max_tx_pwr_per_band->u.set_tx_max_pwr_per_band.power = dB; + mac_ctx->max_power_cmd_pending = true; + status = csrQueueSmeCommand(mac_ctx, set_max_tx_pwr_per_band, + eANI_BOOLEAN_TRUE); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(mac_ctx, LOGE, FL("fail to send msg status = %d"), status); + csrReleaseCommand(mac_ctx, set_max_tx_pwr_per_band); + mac_ctx->max_power_cmd_pending = false; + } + } else { + smsLog(mac_ctx, LOGE, FL("can not obtain a common buffer")); + status = eHAL_STATUS_RESOURCES; + } + sme_ReleaseGlobalLock(&mac_ctx->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetTxPower + + \brief Set Transmit Power dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param sessionId Target Session ID + \param mW power to set in mW + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_SetTxPower(tHalHandle hHal, v_U8_t sessionId, v_U8_t mW) +{ + + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_TXPOW, NO_SESSION, 0)); + smsLog(pMac, LOG1, FL("set tx power %dmW"), mW); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + status = csrSetTxPower(pMac, sessionId, mW); + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn sme_HideSSID + + \brief hide/show SSID dynamically. Note: this setting will + not persist over reboots. + + \param hHal + \param sessionId + \param ssidHidden 0 - Broadcast SSID, 1 - Disable broadcast SSID + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_HideSSID(tHalHandle hHal, v_U8_t sessionId, v_U8_t ssidHidden) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U16 len; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + tpSirUpdateParams pMsg; + tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId ); + + if(!pSession) + { + smsLog(pMac, LOGE, FL(" session %d not found "), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + if( !pSession->sessionActive ) + VOS_ASSERT(0); + + /* Create the message and send to lim */ + len = sizeof(tSirUpdateParams); + pMsg = vos_mem_malloc(len); + if ( NULL == pMsg ) + status = eHAL_STATUS_FAILURE; + else + { + vos_mem_set(pMsg, sizeof(tSirUpdateParams), 0); + pMsg->messageType = eWNI_SME_HIDE_SSID_REQ; + pMsg->length = len; + /* Data starts from here */ + pMsg->sessionId = sessionId; + pMsg->ssidHidden = ssidHidden; + status = palSendMBMessage(pMac->hHdd, pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + + \fn sme_SetTmLevel + \brief Set Thermal Mitigation Level to RIVA + \param hHal - The handle returned by macOpen. + \param newTMLevel - new Thermal Mitigation Level + \param tmMode - Thermal Mitigation handle mode, default 0 + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetTmLevel(tHalHandle hHal, v_U16_t newTMLevel, v_U16_t tmMode) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tAniSetTmLevelReq *setTmLevelReq = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_TMLEVEL, NO_SESSION, 0)); + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) ) + { + setTmLevelReq = (tAniSetTmLevelReq *)vos_mem_malloc(sizeof(tAniSetTmLevelReq)); + if (NULL == setTmLevelReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for sme_SetTmLevel", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + setTmLevelReq->tmMode = tmMode; + setTmLevelReq->newTmLevel = newTMLevel; + + /* serialize the req through MC thread */ + vosMessage.bodyptr = setTmLevelReq; + vosMessage.type = WDA_SET_TM_LEVEL_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Set TM Level MSG fail", __func__); + vos_mem_free(setTmLevelReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/*--------------------------------------------------------------------------- + + \brief sme_featureCapsExchange() - SME interface to exchange capabilities between + Host and FW. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_featureCapsExchange( tHalHandle hHal) +{ + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_CAPS_EXCH, NO_SESSION, 0)); + WDA_featureCapsExchange(vosContext); +} + +/*--------------------------------------------------------------------------- + + \brief sme_disableFeatureCapablity() - SME interface to disable Active mode offload capablity + in Host. + + \param hHal - HAL handle for device + + \return NONE + +---------------------------------------------------------------------------*/ +void sme_disableFeatureCapablity(tANI_U8 feature_index) +{ + WDA_disableCapablityFeature(feature_index); +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetDefaultCountryCode + + \brief Get the default country code from NV + + \param hHal + \param pCountry + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetDefaultCountryCodeFrmNv(tHalHandle hHal, tANI_U8 *pCountry) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_DEFCCNV, NO_SESSION, 0)); + return csrGetDefaultCountryCodeFrmNv(pMac, pCountry); +} + +/* --------------------------------------------------------------------------- + + \fn sme_GetCurrentCountryCode + + \brief Get the current country code + + \param hHal + \param pCountry + \- return eHalStatus + + -------------------------------------------------------------------------------*/ +eHalStatus sme_GetCurrentCountryCode(tHalHandle hHal, tANI_U8 *pCountry) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_CURCC, NO_SESSION, 0)); + return csrGetCurrentCountryCode(pMac, pCountry); +} + +/* --------------------------------------------------------------------------- + \fn sme_transportDebug + \brief Dynamically monitoring Transport channels + Private IOCTL will querry transport channel status if driver loaded + \param hHal Upper MAC context + \param displaySnapshot Display transport channel snapshot option + \param toggleStallDetect Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + \- return NONE + -------------------------------------------------------------------------*/ +void sme_transportDebug(tHalHandle hHal, v_BOOL_t displaySnapshot, v_BOOL_t toggleStallDetect) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: invalid context", __func__); + return; + } + WDA_TransportChannelDebug(pMac, displaySnapshot, toggleStallDetect); +} + +/* --------------------------------------------------------------------------- + \fn sme_ResetPowerValuesFor5G + \brief Reset the power values for 5G band with NV power values. + \param hHal - HAL handle for device + \- return NONE + -------------------------------------------------------------------------*/ +void sme_ResetPowerValuesFor5G (tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT (hHal); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_RESET_PW5G, NO_SESSION, 0)); + csrSaveChannelPowerForBand(pMac, eANI_BOOLEAN_TRUE); + csrApplyPower2Current(pMac); // Store the channel+power info in the global place: Cfg +} + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamPrefer5GHz + \brief enable/disable Roam prefer 5G runtime option + This function is called through dynamic setConfig callback function + to configure the Roam prefer 5G runtime option + \param hHal - HAL handle for device + \param nRoamPrefer5GHz Enable/Disable Roam prefer 5G runtime option + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamPrefer5GHz(tHalHandle hHal, v_BOOL_t nRoamPrefer5GHz) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_RP5G, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamPrefer5GHz is changed from %d to %d", __func__, + pMac->roam.configParam.nRoamPrefer5GHz, + nRoamPrefer5GHz); + pMac->roam.configParam.nRoamPrefer5GHz = nRoamPrefer5GHz; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_setRoamIntraBand + \brief enable/disable Intra band roaming + This function is called through dynamic setConfig callback function + to configure the intra band roaming + \param hHal - HAL handle for device + \param nRoamIntraBand Enable/Disable Intra band roaming + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setRoamIntraBand(tHalHandle hHal, const v_BOOL_t nRoamIntraBand) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamIntraBand is changed from %d to %d", __func__, + pMac->roam.configParam.nRoamIntraBand, + nRoamIntraBand); + pMac->roam.configParam.nRoamIntraBand = nRoamIntraBand; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanNProbes + \brief function to update roam scan N probes + This function is called through dynamic setConfig callback function + to update roam scan N probes + \param hHal - HAL handle for device + \param nProbes number of probe requests to be sent out + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanNProbes(tHalHandle hHal, const v_U8_t nProbes) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamScanNProbes is changed from %d to %d", __func__, + pMac->roam.configParam.nProbes, + nProbes); + pMac->roam.configParam.nProbes = nProbes; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_NPROBES_CHANGED); + } +#endif + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamScanHomeAwayTime + \brief function to update roam scan Home away time + This function is called through dynamic setConfig callback function + to update roam scan home away time + \param hHal - HAL handle for device + \param nRoamScanAwayTime Scan home away time + \param bSendOffloadCmd If TRUE then send offload command to firmware + If FALSE then command is not sent to firmware + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateRoamScanHomeAwayTime(tHalHandle hHal, const v_U16_t nRoamScanHomeAwayTime, + const eAniBoolean bSendOffloadCmd) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamScanHomeAwayTime is changed from %d to %d", __func__, + pMac->roam.configParam.nRoamScanHomeAwayTime, + nRoamScanHomeAwayTime); + pMac->roam.configParam.nRoamScanHomeAwayTime = nRoamScanHomeAwayTime; + sme_ReleaseGlobalLock( &pMac->sme ); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled && bSendOffloadCmd) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_HOME_AWAY_TIME_CHANGED); + } +#endif + return status; +} + + +/* --------------------------------------------------------------------------- + \fn sme_getRoamIntraBand + \brief get Intra band roaming + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_BOOL_t sme_getRoamIntraBand(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND, NO_SESSION, 0)); + return pMac->roam.configParam.nRoamIntraBand; +} + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanNProbes + \brief get N Probes + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U8_t sme_getRoamScanNProbes(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.nProbes; +} + +/* --------------------------------------------------------------------------- + \fn sme_getRoamScanHomeAwayTime + \brief get Roam scan home away time + \param hHal - HAL handle for device + \- return Success or failure + -------------------------------------------------------------------------*/ +v_U16_t sme_getRoamScanHomeAwayTime(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.nRoamScanHomeAwayTime; +} + + +/* --------------------------------------------------------------------------- + \fn sme_UpdateImmediateRoamRssiDiff + \brief Update nImmediateRoamRssiDiff + This function is called through dynamic setConfig callback function + to configure nImmediateRoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig gImmediateRoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param nImmediateRoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateImmediateRoamRssiDiff(tHalHandle hHal, v_U8_t nImmediateRoamRssiDiff) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set immediate roam rssi diff to" + "%d - old value is %d - roam state is %s", + nImmediateRoamRssiDiff, + pMac->roam.configParam.nImmediateRoamRssiDiff, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.nImmediateRoamRssiDiff = nImmediateRoamRssiDiff; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateRoamRssiDiff + \brief Update RoamRssiDiff + This function is called through dynamic setConfig callback function + to configure RoamRssiDiff + Usage: adb shell iwpriv wlan0 setConfig RoamRssiDiff=[0 .. 125] + \param hHal - HAL handle for device + \param RoamRssiDiff - minimum rssi difference between potential + candidate and current AP. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamRssiDiff(tHalHandle hHal, v_U8_t RoamRssiDiff) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF, NO_SESSION, 0)); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam rssi diff to %d" + " - old value is %d - roam state is %s", + RoamRssiDiff, + pMac->roam.configParam.RoamRssiDiff, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_RSSI_DIFF_CHANGED); + } +#endif + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_UpdateFastTransitionEnabled() - enable/disable Fast Transition support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastTransitionEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isFastTransitionEnabled config successfully. + Other status means SME is failed to update isFastTransitionEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateFastTransitionEnabled(tHalHandle hHal, + v_BOOL_t isFastTransitionEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: FastTransitionEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isFastTransitionEnabled, + isFastTransitionEnabled); + pMac->roam.configParam.isFastTransitionEnabled = isFastTransitionEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateWESMode + \brief Update WES Mode + This function is called through dynamic setConfig callback function + to configure isWESModeEnabled + \param hHal - HAL handle for device + \return eHAL_STATUS_SUCCESS - SME update isWESModeEnabled config successfully. + Other status means SME is failed to update isWESModeEnabled. + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateWESMode(tHalHandle hHal, v_BOOL_t isWESModeEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set WES Mode to %d" + "- old value is %d - roam state is %s", + isWESModeEnabled, + pMac->roam.configParam.isWESModeEnabled, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.isWESModeEnabled = isWESModeEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRoamScanControl + \brief Set roam scan control + This function is called to set roam scan control + if roam scan control is set to 0, roaming scan cache is cleared + any value other than 0 is treated as invalid value + \param hHal - HAL handle for device + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME failure to update + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRoamScanControl(tHalHandle hHal, v_BOOL_t roamScanControl) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan control to %d" + " - old value is %d - roam state is %s", + roamScanControl, + pMac->roam.configParam.nRoamScanControl, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.nRoamScanControl = roamScanControl; + if ( 0 == roamScanControl) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully cleared roam scan cache"); + csrFlushCfgBgScanRoamChannelList(pMac); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_FLUSH_CHANNEL_LIST); + } +#endif + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status ; +} +#endif /* (WLAN_FEATURE_VOWIFI_11R) || (FEATURE_WLAN_ESE) || (FEATURE_WLAN_LFR) */ + +#ifdef FEATURE_WLAN_LFR +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsFastRoamIniFeatureEnabled() - enable/disable LFR support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isFastRoamIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config successfully. + Other status means SME is failed to update isFastRoamIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsFastRoamIniFeatureEnabled(tHalHandle hHal, + const v_BOOL_t isFastRoamIniFeatureEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (pMac->roam.configParam.isFastRoamIniFeatureEnabled == isFastRoamIniFeatureEnabled) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: FastRoam is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", __func__, + pMac->roam.configParam.isFastRoamIniFeatureEnabled, + isFastRoamIniFeatureEnabled); + return eHAL_STATUS_SUCCESS; + } + if (smeNeighborMiddleOfRoaming(hHal)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: In middle of roaming isFastRoamIniFeatureEnabled %d", + __func__, isFastRoamIniFeatureEnabled); + if (!isFastRoamIniFeatureEnabled) + pMac->roam.pending_roam_disable = TRUE; + + return eHAL_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: FastRoamEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isFastRoamIniFeatureEnabled, + isFastRoamIniFeatureEnabled); + pMac->roam.configParam.isFastRoamIniFeatureEnabled = isFastRoamIniFeatureEnabled; + csrNeighborRoamUpdateFastRoamingEnabled(pMac, isFastRoamIniFeatureEnabled); + + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_ConfigFwrRoaming() - enable/disable LFR support at runtime + When Supplicant issue enabled / disable fwr based roaming on the basis + of the Bssid modification in network block ( e.g. AutoJoin mody N/W block) + + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME (enabled/disabled) offload scan successfully. + Other status means SME is failed to (enabled/disabled) offload scan. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_ConfigFwrRoaming(tHalHandle hHal, + const v_BOOL_t isFastRoamEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if (!pMac->roam.configParam.isFastRoamIniFeatureEnabled) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: FastRoam is disabled through ini", __func__); + return eHAL_STATUS_FAILURE; + } + csrNeighborRoamUpdateFastRoamingEnabled(pMac, isFastRoamEnabled); + return eHAL_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsMAWCIniFeatureEnabled() - + Enable/disable LFR MAWC support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isMAWCIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update MAWCEnabled config successfully. + Other status means SME is failed to update MAWCEnabled. + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_UpdateIsMAWCIniFeatureEnabled(tHalHandle hHal, + const v_BOOL_t MAWCEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: MAWCEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.MAWCEnabled, + MAWCEnabled); + pMac->roam.configParam.MAWCEnabled = MAWCEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateEnableFastRoamInConcurrency() - enable/disable LFR if Concurrent session exists + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS + Other status means SME is failed + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateEnableFastRoamInConcurrency(tHalHandle hHal, + v_BOOL_t bFastRoamInConIniFeatureEnabled) +{ + + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = bFastRoamInConIniFeatureEnabled; + if (0 == pMac->roam.configParam.isRoamOffloadScanEnabled) + { + pMac->roam.configParam.bFastRoamInConIniFeatureEnabled = 0; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} +#endif +#endif /* FEATURE_WLAN_LFR */ + +#ifdef FEATURE_WLAN_ESE +/*-------------------------------------------------------------------------- + \brief sme_UpdateIsEseFeatureEnabled() - enable/disable Ese support at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + isEseIniFeatureEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config successfully. + Other status means SME is failed to update isEseIniFeatureEnabled. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateIsEseFeatureEnabled(tHalHandle hHal, + const v_BOOL_t isEseIniFeatureEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (pMac->roam.configParam.isEseIniFeatureEnabled == isEseIniFeatureEnabled) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Ese Mode is already enabled or disabled, nothing to do (returning) old(%d) new(%d)", __func__, + pMac->roam.configParam.isEseIniFeatureEnabled, + isEseIniFeatureEnabled); + return eHAL_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: EseEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isEseIniFeatureEnabled, + isEseIniFeatureEnabled); + pMac->roam.configParam.isEseIniFeatureEnabled = isEseIniFeatureEnabled; + csrNeighborRoamUpdateEseModeEnabled(pMac, isEseIniFeatureEnabled); + + if(TRUE == isEseIniFeatureEnabled) + { + sme_UpdateFastTransitionEnabled(hHal, TRUE); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_ESE_INI_CFG_CHANGED); + } +#endif + return eHAL_STATUS_SUCCESS; +} +#endif /* FEATURE_WLAN_ESE */ + +/*-------------------------------------------------------------------------- + \brief sme_UpdateConfigFwRssiMonitoring() - enable/disable firmware RSSI Monitoring at runtime + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + fEnableFwRssiMonitoring. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update fEnableFwRssiMonitoring. config successfully. + Other status means SME is failed to update fEnableFwRssiMonitoring. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateConfigFwRssiMonitoring(tHalHandle hHal, + v_BOOL_t fEnableFwRssiMonitoring) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + if (ccmCfgSetInt(hHal, WNI_CFG_PS_ENABLE_RSSI_MONITOR, fEnableFwRssiMonitoring, + NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) + { + halStatus = eHAL_STATUS_FAILURE; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failure: Could not pass on WNI_CFG_PS_RSSI_MONITOR configuration info to CCM"); + } + + return (halStatus); +} + +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING +/*-------------------------------------------------------------------------- + \brief sme_setNeighborLookupRssiThreshold() - update neighbor lookup rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborLookupRssiThreshold(tHalHandle hHal, + v_U8_t neighborLookupRssiThreshold) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrNeighborRoamSetLookupRssiThreshold(pMac, neighborLookupRssiThreshold); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set Lookup threshold to %d" + " - old value is %d - roam state is %s", + neighborLookupRssiThreshold, + pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold = + neighborLookupRssiThreshold; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborReassocRssiThreshold() - update neighbor reassoc rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborReassocRssiThreshold(tHalHandle hHal, + v_U8_t neighborReassocRssiThreshold) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set Reassoc threshold to %d" + "- old value is %d - roam state is %s", + neighborReassocRssiThreshold, + pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold = + neighborReassocRssiThreshold; + pMac->roam.neighborRoamInfo.cfgParams.neighborReassocThreshold = + neighborReassocRssiThreshold; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborLookupRssiThreshold() - get neighbor lookup rssi threshold + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getNeighborLookupRssiThreshold(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold; +} + +/*-------------------------------------------------------------------------- + \brief sme_setNeighborScanRefreshPeriod() - set neighbor scan results refresh period + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanRefreshPeriod(tHalHandle hHal, + v_U16_t neighborScanResultsRefreshPeriod) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan refresh period to %d" + " - old value is %d - roam state is %s", + neighborScanResultsRefreshPeriod, + pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod = + neighborScanResultsRefreshPeriod; + pMac->roam.neighborRoamInfo.cfgParams.neighborResultsRefreshPeriod = + neighborScanResultsRefreshPeriod; + + sme_ReleaseGlobalLock( &pMac->sme ); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_NEIGHBOR_SCAN_REFRESH_PERIOD_CHANGED); + } +#endif + return status ; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_UpdateRoamScanOffloadEnabled() - enable/disable roam scan offload feaure + It is used at in the REG_DYNAMIC_VARIABLE macro definition of + gRoamScanOffloadEnabled. + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successfully. + Other status means SME is failed to update. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateRoamScanOffloadEnabled(tHalHandle hHal, + v_BOOL_t nRoamScanOffloadEnabled) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: gRoamScanOffloadEnabled is changed from %d to %d", __func__, + pMac->roam.configParam.isRoamOffloadScanEnabled, + nRoamScanOffloadEnabled); + pMac->roam.configParam.isRoamOffloadScanEnabled = nRoamScanOffloadEnabled; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getNeighborScanRefreshPeriod() - get neighbor scan results refresh period + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_U16_t - Neighbor scan results refresh period value + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanRefreshPeriod(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod; +} + +/*-------------------------------------------------------------------------- + \brief sme_getEmptyScanRefreshPeriod() - get empty scan refresh period + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +v_U16_t sme_getEmptyScanRefreshPeriod(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateEmptyScanRefreshPeriod + \brief Update nEmptyScanRefreshPeriod + This function is called through dynamic setConfig callback function + to configure nEmptyScanRefreshPeriod + Usage: adb shell iwpriv wlan0 setConfig nEmptyScanRefreshPeriod=[0 .. 60] + \param hHal - HAL handle for device + \param nEmptyScanRefreshPeriod - scan period following empty scan results. + \- return Success or failure + -------------------------------------------------------------------------*/ + +eHalStatus sme_UpdateEmptyScanRefreshPeriod(tHalHandle hHal, v_U16_t nEmptyScanRefreshPeriod) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan period to %d -" + "old value is %d - roam state is %s", + nEmptyScanRefreshPeriod, + pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = nEmptyScanRefreshPeriod; + pMac->roam.neighborRoamInfo.cfgParams.emptyScanRefreshPeriod = nEmptyScanRefreshPeriod; + sme_ReleaseGlobalLock( &pMac->sme ); + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_EMPTY_SCAN_REF_PERIOD_CHANGED); + } +#endif + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMinChanTime + \brief Update nNeighborScanMinChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMinTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMinTime=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanMinChanTime - Channel minimum dwell time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMinChanTime(tHalHandle hHal, const v_U16_t nNeighborScanMinChanTime) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set channel min dwell time to %d" + " - old value is %d - roam state is %s", + nNeighborScanMinChanTime, + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = nNeighborScanMinChanTime; + pMac->roam.neighborRoamInfo.cfgParams.minChannelScanTime = nNeighborScanMinChanTime; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanMaxChanTime + \brief Update nNeighborScanMaxChanTime + This function is called through dynamic setConfig callback function + to configure gNeighborScanChannelMaxTime + Usage: adb shell iwpriv wlan0 setConfig gNeighborScanChannelMaxTime=[0 .. 60] + \param hHal - HAL handle for device + \param nNeighborScanMinChanTime - Channel maximum dwell time + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanMaxChanTime(tHalHandle hHal, const v_U16_t nNeighborScanMaxChanTime) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set channel max dwell time to %d" + " - old value is %d - roam state is %s", + nNeighborScanMaxChanTime, + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = nNeighborScanMaxChanTime; + pMac->roam.neighborRoamInfo.cfgParams.maxChannelScanTime = nNeighborScanMaxChanTime; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_SCAN_CH_TIME_CHANGED); + } +#endif + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMinChanTime + \brief get neighbor scan min channel time + \param hHal - The handle returned by macOpen. + \return v_U16_t - channel min time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMinChanTime(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.neighborRoamInfo.cfgParams.minChannelScanTime; +} + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanMaxChanTime + \brief get neighbor scan max channel time + \param hHal - The handle returned by macOpen. + \return v_U16_t - channel max time value + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanMaxChanTime(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.neighborRoamInfo.cfgParams.maxChannelScanTime; +} + +/* --------------------------------------------------------------------------- + \fn sme_setNeighborScanPeriod + \brief Update nNeighborScanPeriod + This function is called through dynamic setConfig callback function + to configure nNeighborScanPeriod + Usage: adb shell iwpriv wlan0 setConfig nNeighborScanPeriod=[0 .. 1000] + \param hHal - HAL handle for device + \param nNeighborScanPeriod - neighbor scan period + \- return Success or failure + -------------------------------------------------------------------------*/ +eHalStatus sme_setNeighborScanPeriod(tHalHandle hHal, const v_U16_t nNeighborScanPeriod) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set neighbor scan period to %d" + " - old value is %d - roam state is %s", + nNeighborScanPeriod, + pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod = nNeighborScanPeriod; + pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod = nNeighborScanPeriod; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_SCAN_HOME_TIME_CHANGED); + } +#endif + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_getNeighborScanPeriod + \brief get neighbor scan period + \param hHal - The handle returned by macOpen. + \return v_U16_t - neighbor scan period + -------------------------------------------------------------------------*/ +v_U16_t sme_getNeighborScanPeriod(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod; +} + +#endif + +#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) + +/*-------------------------------------------------------------------------- + \brief sme_getRoamRssiDiff() - get Roam rssi diff + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_U16_t - Rssi diff value + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_getRoamRssiDiff(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.RoamRssiDiff; +} + +/*-------------------------------------------------------------------------- + \brief sme_ChangeRoamScanChannelList() - Change roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList, + tANI_U8 numChannels) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tANI_U8 oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0}; + tANI_U8 newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0}; + tANI_U8 i = 0, j = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++) + { + if (j < sizeof(oldChannelList)) + { + j += snprintf(oldChannelList + j, sizeof(oldChannelList) - j," %d", + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]); + } + else + { + break; + } + } + } + csrFlushCfgBgScanRoamChannelList(pMac); + csrCreateBgScanRoamChannelList(pMac, pChannelList, numChannels); + sme_SetRoamScanControl(hHal, 1); + if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + j = 0; + for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++) + { + if (j < sizeof(oldChannelList)) + { + j += snprintf(newChannelList + j, sizeof(newChannelList) - j," %d", + pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]); + } + else + { + break; + } + } + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set roam scan channels to %s" + "- old value is %s - roam state is %s", + newChannelList, oldChannelList, + macTraceGetNeighbourRoamState( + pMac->roam.neighborRoamInfo.neighborRoamState)); + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_CHANNEL_LIST_CHANGED); + } +#endif + + return status ; +} + + +#ifdef FEATURE_WLAN_ESE_UPLOAD +/*-------------------------------------------------------------------------- + \brief sme_SetEseRoamScanChannelList() - set ese roam scan channel list + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_SetEseRoamScanChannelList(tHalHandle hHal, + tANI_U8 *pChannelList, + tANI_U8 numChannels) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + tpCsrChannelInfo currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + tANI_U8 oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN*2] = {0}; + tANI_U8 newChannelList[128] = {0}; + tANI_U8 i = 0, j = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if (NULL != currChannelListInfo->ChannelList) + { + for (i = 0; i < currChannelListInfo->numOfChannels; i++) + { + j += snprintf(oldChannelList + j, sizeof(oldChannelList) - j," %d", + currChannelListInfo->ChannelList[i]); + } + } + status = csrCreateRoamScanChannelList(pMac, pChannelList, numChannels, csrGetCurrentBand(hHal)); + + if ( HAL_STATUS_SUCCESS( status )) + { + if (NULL != currChannelListInfo->ChannelList) + { + j = 0; + for (i = 0; i < currChannelListInfo->numOfChannels; i++) + { + j += snprintf(newChannelList + j, sizeof(newChannelList) - j," %d", + currChannelListInfo->ChannelList[i]); + } + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "ESE roam scan channel list successfully set to %s - old value is %s - roam state is %s", + newChannelList, oldChannelList, + macTraceGetNeighbourRoamState(pMac->roam.neighborRoamInfo.neighborRoamState)); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pMac->roam.configParam.isRoamOffloadScanEnabled) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, REASON_CHANNEL_LIST_CHANGED); + } +#endif + + return status ; +} +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getRoamScanChannelList() - get roam scan channel list + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return eHAL_STATUS_SUCCESS - SME update config successful. + Other status means SME is failed to update + \sa + --------------------------------------------------------------------------*/ +eHalStatus sme_getRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList, + tANI_U8 *pNumChannels) +{ + int i = 0; + tANI_U8 *pOutPtr = pChannelList; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo; + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "Roam Scan channel list is NOT yet initialized"); + *pNumChannels = 0; + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } + + *pNumChannels = pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; + for (i = 0; i < (*pNumChannels); i++) + { + pOutPtr[i] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]; + } + pOutPtr[i] = '\0'; + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_getIsEseFeatureEnabled() - get Ese feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the Ese feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsEseFeatureEnabled(tHalHandle hHal) +{ +#ifdef FEATURE_WLAN_ESE + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return csrRoamIsEseIniFeatureEnabled(pMac); +#else + return eANI_BOOLEAN_FALSE; +#endif +} + +/*-------------------------------------------------------------------------- + \brief sme_GetWESMode() - get WES Mode + This is a synchronous call + \param hHal - The handle returned by macOpen + \return v_U8_t - WES Mode Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetWESMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.isWESModeEnabled; +} + +/*-------------------------------------------------------------------------- + \brief sme_GetRoamScanControl() - get scan control + This is a synchronous call + \param hHal - The handle returned by macOpen. + \return v_BOOL_t - Enabled(1)/Disabled(0) + \sa + --------------------------------------------------------------------------*/ +v_BOOL_t sme_GetRoamScanControl(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.nRoamScanControl; +} +#endif + +/*-------------------------------------------------------------------------- + \brief sme_getIsLfrFeatureEnabled() - get LFR feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsLfrFeatureEnabled(tHalHandle hHal) +{ +#ifdef FEATURE_WLAN_LFR + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.isFastRoamIniFeatureEnabled; +#else + return eANI_BOOLEAN_FALSE; +#endif +} + +/*-------------------------------------------------------------------------- + \brief sme_getIsFtFeatureEnabled() - get FT feature enabled or not + This is a synchronuous call + \param hHal - The handle returned by macOpen. + \return TRUE (1) - if the feature is enabled + FALSE (0) - if feature is disabled (compile or runtime) + \sa + --------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_getIsFtFeatureEnabled(tHalHandle hHal) +{ +#ifdef WLAN_FEATURE_VOWIFI_11R + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->roam.configParam.isFastTransitionEnabled; +#else + return eANI_BOOLEAN_FALSE; +#endif +} + + +/* --------------------------------------------------------------------------- + \fn sme_IsFeatureSupportedByFW + \brief Check if a feature is enabled by FW + + \param featEnumValue - Enumeration value from placeHolderInCapBitmap + \- return 1/0 (TRUE/FALSE) + -------------------------------------------------------------------------*/ +tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue) +{ + return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue); +} + +/* --------------------------------------------------------------------------- + \fn sme_IsFeatureSupportedByDriver + \brief Check if a feature is enabled by Driver + + \param featEnumValue - Enumeration value from placeHolderInCapBitmap + \- return 1/0 (TRUE/FALSE) + -------------------------------------------------------------------------*/ + +tANI_U8 sme_IsFeatureSupportedByDriver(tANI_U8 featEnumValue) +{ + return IS_FEATURE_SUPPORTED_BY_DRIVER(featEnumValue); +} + +#ifdef FEATURE_WLAN_TDLS + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsMgmtFrame + \brief API to send TDLS management frames. + + \param peerMac - peer's Mac Adress. + \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsLinkEstablishParams(tHalHandle hHal, + tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrTdlsLinkEstablishParams *tdlsLinkEstablishParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM, + sessionId, tdlsLinkEstablishParams->isOffChannelSupported)); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsSendLinkEstablishParams(hHal, sessionId, peerMac, tdlsLinkEstablishParams) ; + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status ; +} + +// tdlsoffchan + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsChanSwitchReq + \brief API to send TDLS management frames. + + \param peerMac - peer's Mac Adress. + \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsChanSwitchReq(tHalHandle hHal, + tANI_U8 sessionId, + tSirMacAddr peerMac, + tANI_S32 tdlsOffCh, + tANI_S32 tdlsOffChBwOffset, + tANI_U8 tdlsSwMode) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ, + sessionId, tdlsOffCh)); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsSendChanSwitchReq(hHal, sessionId, peerMac, + tdlsOffCh, tdlsOffChBwOffset, + tdlsSwMode); + } + sme_ReleaseGlobalLock( &pMac->sme ); + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_SendTdlsMgmtFrame + \brief API to send TDLS management frames. + + \param peerMac - peer's Mac Adress. + \param frame_type - Type of TDLS mgmt frame to be sent. + \param dialog - dialog token used in the frame. + \param status - status to be incuded in the frame. + \param peerCapability - peer cpabilities + \param buf - additional IEs to be included + \param len - lenght of additional Ies + \param responder - Tdls request type + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_SendTdlsMgmtFrame(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tANI_U8 frame_type, tANI_U8 dialog, + tANI_U16 statusCode, tANI_U32 peerCapability, + tANI_U8 *buf, tANI_U8 len, tANI_U8 responder) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrTdlsSendMgmt sendTdlsReq = {{0}} ; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME, + sessionId, statusCode)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + vos_mem_copy(sendTdlsReq.peerMac, peerMac, sizeof(tSirMacAddr)) ; + sendTdlsReq.frameType = frame_type; + sendTdlsReq.buf = buf; + sendTdlsReq.len = len; + sendTdlsReq.dialog = dialog; + sendTdlsReq.statusCode = statusCode; + sendTdlsReq.responder = responder; + sendTdlsReq.peerCapability = peerCapability; + + status = csrTdlsSendMgmtReq(hHal, sessionId, &sendTdlsReq) ; + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} +/* --------------------------------------------------------------------------- + \fn sme_ChangeTdlsPeerSta + \brief API to Update TDLS peer sta parameters. + + \param peerMac - peer's Mac Adress. + \param staParams - Peer Station Parameters + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_ChangeTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac, +#else + tSirMacAddr peerMac, +#endif + tCsrStaParams *pstaParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (NULL == pstaParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s :pstaParams is NULL",__func__); + return eHAL_STATUS_FAILURE; + } + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA, sessionId, + pstaParams->capability)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsChangePeerSta(hHal, sessionId, peerMac, pstaParams); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} + +/* --------------------------------------------------------------------------- + \fn sme_AddTdlsPeerSta + \brief API to Add TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_AddTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif + ) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA, + sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsAddPeerSta(hHal, sessionId, peerMac); + + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} +/* --------------------------------------------------------------------------- + \fn sme_DeleteTdlsPeerSta + \brief API to Delete TDLS peer sta entry. + + \param peerMac - peer's Mac Adress. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const tSirMacAddr peerMac +#else + tSirMacAddr peerMac +#endif +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA, + sessionId, 0)); + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrTdlsDelPeerSta(hHal, sessionId, peerMac) ; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; + +} +/* --------------------------------------------------------------------------- + \fn sme_SetTdlsPowerSaveProhibited + \API to set/reset the isTdlsPowerSaveProhibited. + + \- return void + -------------------------------------------------------------------------*/ +void sme_SetTdlsPowerSaveProhibited(tHalHandle hHal, v_BOOL_t val) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pMac->isTdlsPowerSaveProhibited = val; + smsLog(pMac, LOG1, FL("isTdlsPowerSaveProhibited is %d"), + pMac->isTdlsPowerSaveProhibited); + return; +} +#endif +/* --------------------------------------------------------------------------- + \fn sme_IsPmcBmps + \API to Check if PMC state is BMPS. + + \- return v_BOOL_t + -------------------------------------------------------------------------*/ +v_BOOL_t sme_IsPmcBmps(tHalHandle hHal) +{ + return (BMPS == pmcGetPmcState(hHal)); +} + +eHalStatus sme_UpdateDfsSetting(tHalHandle hHal, tANI_U8 fUpdateEnableDFSChnlScan) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG2, FL("enter")); + + if (pMac->fActiveScanOnDFSChannels) + { + smsLog(pMac, LOG1, FL("Skip updating fEnableDFSChnlScan" + " as DFS feature is triggered")); + return (status); + } + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMac->scan.fEnableDFSChnlScan = fUpdateEnableDFSChnlScan; + sme_ReleaseGlobalLock( &pMac->sme ); + } + smsLog(pMac, LOG2, FL("exit status %d"), status); + + return (status); +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSRoamMode + \brief Update DFS roam scan mode + This function is called to configure allowDFSChannelRoam + dynamically + \param hHal - HAL handle for device + \param allowDFSChannelRoam - DFS roaming scan mode + mode 0 disable roam scan on DFS channels + mode 1 enables roam scan (passive/active) on DFS channels + \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config + successfully. + Other status means SME failed to update DFS roaming scan config. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSRoamMode(tHalHandle hHal, tANI_U8 allowDFSChannelRoam) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "LFR runtime successfully set AllowDFSChannelRoam Mode to " + "%d - old value is %d", + allowDFSChannelRoam, + pMac->roam.configParam.allowDFSChannelRoam); + pMac->roam.configParam.allowDFSChannelRoam = allowDFSChannelRoam; + sme_ReleaseGlobalLock( &pMac->sme ); + } +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (csrRoamIsRoamOffloadScanEnabled(pMac)) + { + csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG, + REASON_CHANNEL_LIST_CHANGED); + } +#endif + + return status ; +} + +/* --------------------------------------------------------------------------- + \fn sme_UpdateDFSScanMode + \brief Update DFS scan mode + This function is called to configure fEnableDFSChnlScan. + \param hHal - HAL handle for device + \param dfsScanMode - DFS scan mode + mode 0 disable scan on DFS channels + mode 1 enables passive scan on DFS channels + mode 2 enables active scan on DFS channels for static list + \return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config + successfully. + Other status means SME failed to update DFS scan config. + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, tANI_U8 dfsScanMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "DFS scan Mode changed to %d, old value is %d ", + dfsScanMode, + pMac->scan.fEnableDFSChnlScan); + pMac->scan.fEnableDFSChnlScan = dfsScanMode; + sme_ReleaseGlobalLock( &pMac->sme ); + } + + sme_FilterScanDFSResults(hHal); + sme_UpdateChannelList( hHal ); + + return status ; +} + +/*-------------------------------------------------------------------------- + \brief sme_GetDFSScanMode() - get DFS scan mode + \param hHal - The handle returned by macOpen. + \return DFS scan mode + mode 0 disable scan on DFS channels + mode 1 enables passive scan on DFS channels + mode 2 enables active scan on DFS channels for static list + \sa + --------------------------------------------------------------------------*/ +v_U8_t sme_GetDFSScanMode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->scan.fEnableDFSChnlScan; +} + +/* --------------------------------------------------------------------------- + \fn sme_HandleDFSChanScan + \brief Gets Valid channel list and updates scan control list according to + dfsScanMode + \param hHal - HAL handle for device + \return eHAL_STATUS_FAILURE when failed to get valid channel list + Otherwise eHAL_STATUS_SUCCESS - + \sa + -------------------------------------------------------------------------*/ +eHalStatus sme_HandleDFSChanScan(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + tCsrChannel ChannelList; + + /* + * Set Flag to block driver scan type conversion from active to passive + * and vice versa in case if fEnableDFSChnlScan is + * DFS_CHNL_SCAN_ENABLED_ACTIVE + */ + if (DFS_CHNL_SCAN_ENABLED_ACTIVE == + pMac->scan.fEnableDFSChnlScan) + pMac->fActiveScanOnDFSChannels = 1; + else + pMac->fActiveScanOnDFSChannels = 0; + + ChannelList.numChannels = sizeof(ChannelList.channelList); + status = sme_GetCfgValidChannels(hHal, (tANI_U8 *)ChannelList.channelList, + (tANI_U32*)&ChannelList.numChannels); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + FL("Failed to get valid channel list (err=%d)"), status); + return status; + } + + smsLog(pMac, LOG1, FL("Valid Channel list:")); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + ChannelList.channelList, ChannelList.numChannels); + + sme_SetCfgScanControlList(hHal, pMac->scan.countryCodeCurrent, + &ChannelList); + return status ; +} + +/* + * SME API to enable/disable WLAN driver initiated SSR + */ +void sme_UpdateEnableSSR(tHalHandle hHal, tANI_BOOLEAN enableSSR) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG, + "SSR level is changed %d", enableSSR); + /* not serializing this messsage, as this is only going + * to set a variable in WDA/WDI + */ + WDA_SetEnableSSR(enableSSR); + sme_ReleaseGlobalLock(&pMac->sme); + } + return; +} + +/* + * SME API to stringify bonding mode. (hostapd convention) + */ + +static const char* sme_CBMode2String( tANI_U32 mode) +{ + switch (mode) + { + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + return "HT20"; + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + return "HT40-"; /* lower secondary channel */ + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + return "HT40+"; /* upper secondary channel */ +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return "VHT80+40+"; /* upper secondary channels */ + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return "VHT80+40-"; /* 1 lower and 2 upper secondary channels */ + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return "VHT80-40+"; /* 2 lower and 1 upper secondary channels */ + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return "VHT80-40-"; /* lower secondary channels */ +#endif + default: + VOS_ASSERT(0); + return "Unknown"; + } +} + +/* + * SME API to adjust bonding mode to regulatory .. etc. + * + */ +static VOS_STATUS sme_AdjustCBMode(tAniSirGlobal* pMac, + tSmeConfigParams *smeConfig, + tANI_U8 channel) +{ + const tANI_U8 step = SME_START_CHAN_STEP; + tANI_U8 i, startChan = channel, chanCnt = 0, chanBitmap = 0; + tANI_BOOLEAN violation = VOS_FALSE; + tANI_U32 newMode, mode; + tANI_U8 centerChan = channel; + /* to validate 40MHz channels against the regulatory domain */ + tANI_BOOLEAN ht40PhyMode = VOS_FALSE; + + /* get the bonding mode */ + mode = (channel <= 14) ? smeConfig->csrConfig.channelBondingMode24GHz : + smeConfig->csrConfig.channelBondingMode5GHz; + newMode = mode; + + /* get the channels */ + switch (mode) + { + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + startChan = channel; + chanCnt = 1; + break; + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + startChan = channel - step; + chanCnt = 2; + centerChan = channel - CSR_CB_CENTER_CHANNEL_OFFSET; + ht40PhyMode = VOS_TRUE; + break; + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + startChan = channel; + chanCnt=2; + centerChan = channel + CSR_CB_CENTER_CHANNEL_OFFSET; + ht40PhyMode = VOS_TRUE; + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + startChan = channel; + chanCnt = 4; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + startChan = channel - step; + chanCnt = 4; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + startChan = channel - 2*step; + chanCnt = 4; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + startChan = channel - 3*step; + chanCnt = 4; + break; +#endif + default: + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* find violation; also map valid channels to a bitmap */ + for (i = 0; i < chanCnt; i++) + { + if (csrIsValidChannel(pMac, (startChan + (i * step))) == + eHAL_STATUS_SUCCESS) + chanBitmap = chanBitmap | 1 << i; + else + violation = VOS_TRUE; + } + /* validate if 40MHz channel is allowed */ + if (ht40PhyMode) + { + if (!csrRoamIsValid40MhzChannel(pMac, centerChan)) + violation = VOS_TRUE; + } + + /* no channels are valid */ + if (chanBitmap == 0) + { + /* never be in this case */ + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("channel %d %s is not supported"), + channel, + sme_CBMode2String(mode)); + return VOS_STATUS_E_INVAL; + } + + /* fix violation */ + if (violation) + { + const tANI_U8 lowerMask = 0x03, upperMask = 0x0c; + /* fall back to single channel in all exception cases */ + newMode = eCSR_INI_SINGLE_CHANNEL_CENTERED; + + switch (mode) + { + case eCSR_INI_SINGLE_CHANNEL_CENTERED: + /* fall thru */ + case eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY: + /* fall thru */ + case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY: + break; +#ifdef WLAN_FEATURE_11AC + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + if ((chanBitmap & lowerMask) == lowerMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + if ((chanBitmap & lowerMask) == lowerMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + if ((chanBitmap & upperMask) == upperMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + break; + case eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + if ((chanBitmap & upperMask) == upperMask) + newMode = eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + break; +#endif + default: + return VOS_STATUS_E_NOSUPPORT; + break; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + FL("bonding mode adjust: %s to %s"), + sme_CBMode2String(mode), + sme_CBMode2String(newMode)); + + } + + /* check for mode change */ + if (newMode != mode) + { + if (channel <= 14) + smeConfig->csrConfig.channelBondingMode24GHz = newMode; + else + smeConfig->csrConfig.channelBondingMode5GHz = newMode; + } + + return VOS_STATUS_SUCCESS; + +} + +/* + * SME API to determine the channel bonding mode + */ +VOS_STATUS sme_SelectCBMode(tHalHandle hHal, eCsrPhyMode eCsrPhyMode, tANI_U8 channel) +{ + tSmeConfigParams smeConfig; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); +#ifdef WLAN_FEATURE_11AC + tANI_U8 vht80Allowed; +#endif + + if ( +#ifdef WLAN_FEATURE_11AC + eCSR_DOT11_MODE_11ac != eCsrPhyMode && + eCSR_DOT11_MODE_11ac_ONLY != eCsrPhyMode && +#endif + eCSR_DOT11_MODE_11n != eCsrPhyMode && + eCSR_DOT11_MODE_11n_ONLY != eCsrPhyMode && + + eCSR_DOT11_MODE_11a != eCsrPhyMode && + eCSR_DOT11_MODE_11a_ONLY != eCsrPhyMode && + + eCSR_DOT11_MODE_abg != eCsrPhyMode + ) + { + return VOS_STATUS_SUCCESS; + } + + vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams)); + sme_GetConfigParam(pMac, &smeConfig); + + /* If channel bonding mode is not required */ +#ifdef WLAN_FEATURE_AP_HT40_24G + if ( !pMac->roam.configParam.channelBondingMode5GHz + && !smeConfig.csrConfig.apHT40_24GEnabled ) { +#else + if ( !pMac->roam.configParam.channelBondingMode5GHz ) { +#endif + return VOS_STATUS_SUCCESS; + } + + +#ifdef WLAN_FEATURE_11AC + if ( eCSR_DOT11_MODE_11ac == eCsrPhyMode || + eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode ) + { + /* Check if VHT80 is allowed for the channel*/ + vht80Allowed = vos_is_channel_valid_for_vht80(channel); + + if (vht80Allowed) + { + if (channel== 36 || channel == 52 || channel == 100 || + channel == 116 || channel == 149) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + } + else if (channel == 40 || channel == 56 || channel == 104 || + channel == 120 || channel == 153) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + } + else if (channel == 44 || channel == 60 || channel == 108 || + channel == 124 || channel == 157) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + } + else if (channel == 48 || channel == 64 || channel == 112 || + channel == 128 || channel == 144 || channel == 161) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + } + else if (channel == 165) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + } + else /* Set VHT40 */ + { + if (channel== 40 || channel == 48 || channel == 56 || + channel == 64 || channel == 104 || channel == 112 || + channel == 120 || channel == 128 || channel == 136 || + channel == 144 || channel == 153 || channel == 161) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + } + else if (channel== 36 || channel == 44 || channel == 52 || + channel == 60 || channel == 100 || channel == 108 || + channel == 116 || channel == 124 || channel == 132 || + channel == 140 || channel == 149 || channel == 157) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + } + else if (channel == 165) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (smeConfig.csrConfig.apHT40_24GEnabled) + { + if (channel >= 1 && channel <= 7) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + else if (channel >= 8 && channel <= 13) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + else if (channel ==14) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } +#endif + } +#endif + + if ( eCSR_DOT11_MODE_11n == eCsrPhyMode || + eCSR_DOT11_MODE_11n_ONLY == eCsrPhyMode ) + { + if ( channel== 40 || channel == 48 || channel == 56 || + channel == 64 || channel == 104 || channel == 112 || + channel == 120 || channel == 128 || channel == 136 || + channel == 144 || channel == 153 || channel == 161 ) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + } + else if ( channel== 36 || channel == 44 || channel == 52 || + channel == 60 || channel == 100 || channel == 108 || + channel == 116 || channel == 124 || channel == 132 || + channel == 140 || channel == 149 || channel == 157 ) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + } + else if ( channel == 165 ) + { + smeConfig.csrConfig.channelBondingMode5GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } + +#ifdef WLAN_FEATURE_AP_HT40_24G + if (smeConfig.csrConfig.apHT40_24GEnabled) + { + if (channel >= 1 && channel <= 7) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY; + else if (channel >= 8 && channel <= 13) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY; + else if (channel ==14) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + } +#endif + } + + /* + for 802.11a phy mode, channel bonding should be zero. + From default config, it is set as PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3 + through csrChangeDefaultConfigParam function. We will override this + value here. + */ + if ( eCSR_DOT11_MODE_11a == eCsrPhyMode || + eCSR_DOT11_MODE_11a_ONLY == eCsrPhyMode || + eCSR_DOT11_MODE_abg == eCsrPhyMode) + { + smeConfig.csrConfig.channelBondingMode5GHz = 0; +#ifdef WLAN_FEATURE_AP_HT40_24G + } else if ( eCSR_DOT11_MODE_11g_ONLY == eCsrPhyMode) + smeConfig.csrConfig.channelBondingAPMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; +#else + } +#endif + + sme_AdjustCBMode(pMac, &smeConfig, channel); + +#ifdef WLAN_FEATURE_AP_HT40_24G + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("%s cbmode selected=%d bonding mode:%s"), + (channel <= 14) ? "2G" : "5G", + (channel <= 14) ? smeConfig.csrConfig.channelBondingAPMode24GHz : + smeConfig.csrConfig.channelBondingMode5GHz, + (channel <= 14) ? + sme_CBMode2String(smeConfig.csrConfig.channelBondingAPMode24GHz) : + sme_CBMode2String(smeConfig.csrConfig.channelBondingMode5GHz)); +#else + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, + "cbmode selected=%d", smeConfig.csrConfig.channelBondingMode5GHz); +#endif + + sme_UpdateConfig (pMac, &smeConfig); + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief sme_SetCurrDeviceMode() - Sets the current operating device mode. + \param hHal - The handle returned by macOpen. + \param currDeviceMode - Current operating device mode. + --------------------------------------------------------------------------*/ + +void sme_SetCurrDeviceMode (tHalHandle hHal, tVOS_CON_MODE currDeviceMode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->sme.currDeviceMode = currDeviceMode; + return; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*-------------------------------------------------------------------------- + \brief sme_HandoffRequest() - a wrapper function to Request a handoff + from CSR. + This is a synchronous call + \param hHal - The handle returned by macOpen + \param pHandoffInfo - info provided by HDD with the handoff request (namely: + BSSID, channel etc.) + \return eHAL_STATUS_SUCCESS - SME passed the request to CSR successfully. + Other status means SME is failed to send the request. + \sa + --------------------------------------------------------------------------*/ + +eHalStatus sme_HandoffRequest(tHalHandle hHal, + tCsrHandoffRequest *pHandoffInfo) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: invoked", __func__); + status = csrHandoffRequest(pMac, pHandoffInfo); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status ; +} +#endif + +/* + * SME API to check if there is any infra station or + * P2P client is connected + */ +VOS_STATUS sme_isSta_p2p_clientConnected(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if(csrIsInfraConnected(pMac)) + { + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; +} + +/* + * SME API to check if any sessoion connected. + */ +VOS_STATUS sme_is_any_session_connected(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if(csrIsAnySessionConnected(pMac)) + { + + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; +} + + +#ifdef FEATURE_WLAN_LPHB +/* --------------------------------------------------------------------------- + \fn sme_LPHBConfigReq + \API to make configuration LPHB within FW. + \param hHal - The handle returned by macOpen + \param lphdReq - LPHB request argument by client + \param pCallbackfn - LPHB timeout notification callback function pointer + \- return Configuration message posting status, SUCCESS or Fail + -------------------------------------------------------------------------*/ +eHalStatus sme_LPHBConfigReq +( + tHalHandle hHal, + tSirLPHBReq *lphdReq, + void (*pCallbackfn)(void *pAdapter, void *indParam) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ, + NO_SESSION, lphdReq->cmd)); + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if ((LPHB_SET_EN_PARAMS_INDID == lphdReq->cmd) && + (NULL == pCallbackfn) && + (NULL == pMac->sme.pLphbIndCb)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Indication Call back did not registered", __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + else if (NULL != pCallbackfn) + { + pMac->sme.pLphbIndCb = pCallbackfn; + } + + /* serialize the req through MC thread */ + vosMessage.bodyptr = lphdReq; + vosMessage.type = WDA_LPHB_CONF_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Config LPHB MSG fail", __func__); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} +#endif /* FEATURE_WLAN_LPHB */ +/*-------------------------------------------------------------------------- + \brief sme_enable_disable_split_scan() - a wrapper function to set the split + scan parameter. + This is a synchronous call + \param hHal - The handle returned by macOpen + \return NONE. + \sa + --------------------------------------------------------------------------*/ +void sme_enable_disable_split_scan (tHalHandle hHal, tANI_U8 nNumStaChan, + tANI_U8 nNumP2PChan) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pMac->roam.configParam.nNumStaChanCombinedConc = nNumStaChan; + pMac->roam.configParam.nNumP2PChanCombinedConc = nNumP2PChan; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: SCAN nNumStaChanCombinedConc : %d," + "nNumP2PChanCombinedConc : %d ", + __func__, nNumStaChan, nNumP2PChan); + + return; + +} + +/** + * sme_AddPeriodicTxPtrn() - Add Periodic TX Pattern + * @hal: global hal handle + * @addPeriodicTxPtrnParams: request message + * + * Return: eHalStatus enumeration + */ +eHalStatus +sme_AddPeriodicTxPtrn(tHalHandle hal, + struct sSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + struct sSirAddPeriodicTxPtrn *req_msg; + vos_msg_t msg; + + smsLog(mac, LOG1, FL("enter")); + + req_msg = vos_mem_malloc(sizeof(*req_msg)); + if (!req_msg) + { + smsLog(mac, LOGE, FL("vos_mem_malloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + *req_msg = *addPeriodicTxPtrnParams; + + status = sme_AcquireGlobalLock(&mac->sme); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(mac, LOGE, + FL("sme_AcquireGlobalLock failed!(status=%d)"), + status); + vos_mem_free(req_msg); + return status; + } + + /* Serialize the req through MC thread */ + msg.bodyptr = req_msg; + msg.type = WDA_ADD_PERIODIC_TX_PTRN_IND; + vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + smsLog(mac, LOGE, + FL("vos_mq_post_message failed!(err=%d)"), + vos_status); + vos_mem_free(req_msg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&mac->sme); + return status; +} + + +/** + * sme_DelPeriodicTxPtrn() - Delete Periodic TX Pattern + * @hal: global hal handle + * @delPeriodicTxPtrnParams: request message + * + * Return: eHalStatus enumeration + */ +eHalStatus +sme_DelPeriodicTxPtrn(tHalHandle hal, + struct sSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vos_status = VOS_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + struct sSirDelPeriodicTxPtrn *req_msg; + vos_msg_t msg; + + smsLog(mac, LOG1, FL("enter")); + + req_msg = vos_mem_malloc(sizeof(*req_msg)); + + if (!req_msg) + { + smsLog(mac, LOGE, FL("vos_mem_malloc failed")); + return eHAL_STATUS_FAILED_ALLOC; + } + + *req_msg = *delPeriodicTxPtrnParams; + + status = sme_AcquireGlobalLock(&mac->sme); + if (status != eHAL_STATUS_SUCCESS) + { + smsLog(mac, LOGE, + FL("sme_AcquireGlobalLock failed!(status=%d)"), + status); + vos_mem_free(req_msg); + return status; + } + + /* Serialize the req through MC thread */ + msg.bodyptr = req_msg; + msg.type = WDA_DEL_PERIODIC_TX_PTRN_IND; + vos_status = vos_mq_post_message(VOS_MQ_ID_WDA, &msg); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + smsLog(mac, LOGE, + FL("vos_mq_post_message failed!(err=%d)"), + vos_status); + vos_mem_free(req_msg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&mac->sme); + return status; +} + +#ifdef WLAN_FEATURE_RMC +/* --------------------------------------------------------------------------- + \fn sme_EnableRMC + \brief Used to enable RMC + setting will not persist over reboots + \param hHal + \param sessionId + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EnableRMC(tHalHandle hHal, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG1, FL("enable RMC")); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + status = csrEnableRMC(pMac, sessionId); + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_DisableRMC + \brief Used to disable RMC + setting will not persist over reboots + \param hHal + \param sessionId + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_DisableRMC(tHalHandle hHal, tANI_U32 sessionId) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + smsLog(pMac, LOG1, FL("disable RMC")); + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + status = csrDisableRMC(pMac, sessionId); + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} +#endif /* WLAN_FEATURE_RMC */ + +/* --------------------------------------------------------------------------- + \fn sme_SendRateUpdateInd + \brief API to Update rate + \param hHal - The handle returned by macOpen + \param rateUpdateParams - Pointer to rate update params + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SendRateUpdateInd(tHalHandle hHal, tSirRateUpdateInd *rateUpdateParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + vos_msg_t msg; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + msg.type = WDA_RATE_UPDATE_IND; + msg.bodyptr = rateUpdateParams; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,"%s: Not able " + "to post WDA_SET_RMC_RATE_IND to WDA!", + __func__); + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + + return status; +} + +#ifdef WLAN_FEATURE_RMC +/* --------------------------------------------------------------------------- + \fn sme_GetIBSSPeerInfo + \brief Used to disable RMC + setting will not persist over reboots + \param hHal + \param ibssPeerInfoReq multicast Group IP address + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_RequestIBSSPeerInfo(tHalHandle hHal, void *pUserData, + pIbssPeerInfoCb peerInfoCbk, + tANI_BOOLEAN allPeerInfoReqd, + tANI_U8 staIdx) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t vosMessage; + tSirIbssGetPeerInfoReqParams *pIbssInfoReqParams; + + status = sme_AcquireGlobalLock(&pMac->sme); + if ( eHAL_STATUS_SUCCESS == status) + { + pMac->sme.peerInfoParams.peerInfoCbk = peerInfoCbk; + pMac->sme.peerInfoParams.pUserData = pUserData; + + pIbssInfoReqParams = (tSirIbssGetPeerInfoReqParams *) + vos_mem_malloc(sizeof(tSirIbssGetPeerInfoReqParams)); + if (NULL == pIbssInfoReqParams) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for dhcp start", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pIbssInfoReqParams->allPeerInfoReqd = allPeerInfoReqd; + pIbssInfoReqParams->staIdx = staIdx; + + vosMessage.type = WDA_GET_IBSS_PEER_INFO_REQ; + vosMessage.bodyptr = pIbssInfoReqParams; + vosMessage.reserved = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post WDA_GET_IBSS_PEER_INFO_REQ MSG failed", __func__); + vos_mem_free(pIbssInfoReqParams); + vosStatus = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return (vosStatus); +} +#endif + +void smeGetCommandQStatus( tHalHandle hHal ) +{ + tSmeCmd *pTempCmd = NULL; + tListElem *pEntry; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return; + } + + pEntry = csrLLPeekHead( &pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK ); + if( pEntry ) + { + pTempCmd = GET_BASE_ADDR( pEntry, tSmeCmd, Link ); + } + smsLog( pMac, LOGE, "Currently smeCmdActiveList has command (0x%X)", + (pTempCmd) ? pTempCmd->command : eSmeNoCommand ); + if(pTempCmd) + { + if( eSmeCsrCommandMask & pTempCmd->command ) + { + //CSR command is stuck. See what the reason code is for that command + dumpCsrCommandInfo(pMac, pTempCmd); + } + } //if(pTempCmd) + + smsLog( pMac, LOGE, "Currently smeCmdPendingList has %d commands", + csrLLCount(&pMac->sme.smeCmdPendingList)); + + smsLog( pMac, LOGE, "Currently roamCmdPendingList has %d commands", + csrLLCount(&pMac->roam.roamCmdPendingList)); + + return; +} + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* --------------------------------------------------------------------------- + \fn sme_SetBatchScanReq + \brief API to set batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting set batch scan response from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetBatchScanReq +( + tHalHandle hHal, tSirSetBatchScanReq *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, tSirSetBatchScanRsp *pRsp), + void *callbackContext +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if (!pMac) + { + return eHAL_STATUS_FAILURE; + } + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + status = pmcSetBatchScanReq(hHal, pRequest, sessionId, callbackRoutine, + callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_TriggerBatchScanResultInd + \brief API to trigger batch scan result indications from FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to get batch request. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting batch scan result indication from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_TriggerBatchScanResultInd +( + tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId, + void (*callbackRoutine) (void *callbackCtx, void *pRsp), + void *callbackContext +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + status = pmcTriggerBatchScanResultInd(hHal, pRequest, sessionId, + callbackRoutine, callbackContext); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + + +/* --------------------------------------------------------------------------- + \fn sme_StopBatchScanInd + \brief API to stop batch scan request in FW + \param hHal - The handle returned by macOpen. + \param pRequest - Pointer to the batch request. + \param sessionId - session ID + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_StopBatchScanInd +( + tHalHandle hHal, tSirStopBatchScanInd *pRequest, tANI_U8 sessionId +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + status = pmcStopBatchScanInd(hHal, pRequest, sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} + +#endif + +void activeListCmdTimeoutHandle(void *userData) +{ + tHalHandle hHal= (tHalHandle) userData; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + tListElem *pEntry; + tSmeCmd *pTempCmd = NULL; + + if (NULL == pMac) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: pMac is null", __func__); + return; + } + /* Return if no cmd pending in active list as + * in this case we should not be here. + */ + if ((NULL == userData) || + (0 == csrLLCount(&pMac->sme.smeCmdActiveList))) + return; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Active List command timeout Cmd List Count %d", __func__, + csrLLCount(&pMac->sme.smeCmdActiveList) ); + smeGetCommandQStatus(hHal); + + vos_state_info_dump_all(); + + + pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (pEntry) { + pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + } + /* If user initiated scan took more than active list timeout + * abort it. + */ + if (pTempCmd && (eSmeCommandScan == pTempCmd->command) && + (eCsrScanUserRequest == pTempCmd->u.scanCmd.reason)) { + sme_AbortMacScan(hHal, pTempCmd->sessionId, + eCSR_SCAN_ABORT_DEFAULT); + return; + } else if (pTempCmd && + (eSmeCommandRemainOnChannel == pTempCmd->command)) { + /* Ignore if ROC took more than 120 sec */ + return; + } + if (pMac->roam.configParam.enableFatalEvent) + { + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_SME_COMMAND_STUCK, + FALSE, FALSE); + } + else + { + /* Initiate SSR to recover */ + if (!(vos_isLoadUnloadInProgress() || + vos_is_logp_in_progress(VOS_MODULE_ID_SME, NULL))) + { + vos_wlanRestart(); + } + } +} + +#ifdef FEATURE_WLAN_CH_AVOID +/* --------------------------------------------------------------------------- + \fn sme_AddChAvoidCallback + \brief Used to plug in callback function + Which notify channel may not be used with SAP or P2PGO mode. + Notification come from FW. + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_AddChAvoidCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, void *indParam) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Plug in CH AVOID CB", __func__); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if (NULL != pCallbackfn) + { + pMac->sme.pChAvoidNotificationCb = pCallbackfn; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); +} +#endif /* FEATURE_WLAN_CH_AVOID */ + + +/** + * sme_set_rssi_threshold_breached_cb() - set rssi threshold breached callback + * @hal: global hal handle + * @cb: callback function pointer + * + * This function stores the rssi threshold breached callback function. + * + * Return: eHalStatus enumeration. + */ +eHalStatus sme_set_rssi_threshold_breached_cb(tHalHandle hal, + void (*cb)(void *, struct rssi_breach_event *)) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + status = sme_AcquireGlobalLock(&mac->sme); + if (status != eHAL_STATUS_SUCCESS) { + smsLog(mac, LOGE, + FL("sme_AcquireGlobalLock failed!(status=%d)"), + status); + return status; + } + + mac->sme.rssiThresholdBreachedCb = cb; + sme_ReleaseGlobalLock(&mac->sme); + return status; +} + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief API to set link layer stats request to FW + \param hHal - The handle returned by macOpen. + + \Param pStatsReq - a pointer to a caller allocated object of + typedef struct tSirLLStatsSetReq, signifying the parameters to link layer + stats set. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq(tHalHandle hHal, + tSirLLStatsSetReq *pLinkLayerStatsSetReq) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + eHalStatus status = eHAL_STATUS_FAILURE; + tSirLLStatsSetReq *plinkLayerSetReq; + + plinkLayerSetReq = vos_mem_malloc(sizeof(*plinkLayerSetReq)); + if ( !plinkLayerSetReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_LINK_LAYER_STATS_SET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *plinkLayerSetReq = *pLinkLayerStatsSetReq; + + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + msg.type = WDA_LINK_LAYER_STATS_SET_REQ; + msg.reserved = 0; + msg.bodyptr = plinkLayerSetReq; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post SIR_HAL_LL_STATS_SET message to HAL", __func__); + vos_mem_free(plinkLayerSetReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(plinkLayerSetReq); + status = eHAL_STATUS_FAILURE; + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief API to get link layer stats request to FW + \param hHal - The handle returned by macOpen. + + \Param pStatsReq - a pointer to a caller allocated object of + typedef struct tSirLLStatsGetReq, signifying the parameters to link layer + stats get. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq(tHalHandle hHal, + tSirLLStatsGetReq *pLinkLayerStatsGetReq) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + eHalStatus status = eHAL_STATUS_FAILURE; + tSirLLStatsGetReq *pGetStatsReq; + + pGetStatsReq = vos_mem_malloc(sizeof(*pGetStatsReq)); + if ( !pGetStatsReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_LINK_LAYER_STATS_GET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + *pGetStatsReq = *pLinkLayerStatsGetReq; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + msg.type = WDA_LINK_LAYER_STATS_GET_REQ; + msg.reserved = 0; + msg.bodyptr = pGetStatsReq; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post SIR_HAL_LL_STATS_GET message to HAL", __func__); + vos_mem_free(pGetStatsReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pGetStatsReq); + status = eHAL_STATUS_FAILURE; + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief API to clear link layer stats request to FW + \param hHal - The handle returned by macOpen. + + \Param pStatsReq - a pointer to a caller allocated object of + typedef struct tSirLLStatsClearReq, signifying the parameters to link layer + stats clear. + + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq(tHalHandle hHal, + tSirLLStatsClearReq *pLinkLayerStatsClear) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + vos_msg_t msg; + eHalStatus status = eHAL_STATUS_FAILURE; + tSirLLStatsClearReq *pClearStatsReq; + + + + pClearStatsReq = vos_mem_malloc(sizeof(*pClearStatsReq)); + if ( !pClearStatsReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_LINK_LAYER_STATS_CLEAR_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pClearStatsReq = *pLinkLayerStatsClear; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + msg.type = WDA_LINK_LAYER_STATS_CLEAR_REQ; + msg.reserved = 0; + msg.bodyptr = pClearStatsReq; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post SIR_HAL_LL_STATS_CLEAR message to HAL", __func__); + vos_mem_free(pClearStatsReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pClearStatsReq); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief API to trigger Link Layer Statistic indications from FW + \param hHal - The handle returned by macOpen. + \param sessionId - session ID + \param callbackRoutine - HDD callback which needs to be invoked after + getting Link Layer Statistics from FW + \param callbackContext - pAdapter context + \return eHalStatus + ---------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp, + tANI_U8 *macAddr) +) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status; + + if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ))) + { + if (NULL != callbackRoutine) + { + pMac->sme.pLinkLayerStatsIndCallback = callbackRoutine; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + + return status; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + + +eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->fEnableDebugLog = set_value; + return (status); +} + +VOS_STATUS sme_UpdateDSCPtoUPMapping( tHalHandle hHal, + sme_QosWmmUpType *dscpmapping, + v_U8_t sessionId ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + v_U8_t i, j, peSessionId; + tCsrRoamSession *pCsrSession = NULL; + tpPESession pSession = NULL; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pCsrSession = CSR_GET_SESSION( pMac, sessionId ); + + if (pCsrSession == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: CSR Session lookup fails %u", __func__, sessionId); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid session Id %u", __func__, sessionId); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + pSession = peFindSessionByBssid( pMac, + pCsrSession->connectedProfile.bssid, &peSessionId ); + + if (pSession == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session lookup fails for BSSID", __func__); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + if ( !pSession->QosMapSet.present ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: QOS Mapping IE not present", __func__); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + else + { + for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) + { + for (j = pSession->QosMapSet.dscp_range[i][0]; + j <= pSession->QosMapSet.dscp_range[i][1]; j++) + { + if ((pSession->QosMapSet.dscp_range[i][0] == 255) && + (pSession->QosMapSet.dscp_range[i][1] == 255)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: User Priority %d is not used in mapping", + __func__, i); + break; + } + else + { + dscpmapping[j]= i; + } + } + } + for (i = 0; i< pSession->QosMapSet.num_dscp_exceptions; i++) + { + if (pSession->QosMapSet.dscp_exceptions[i][0] != 255) + { + dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0] ] = + pSession->QosMapSet.dscp_exceptions[i][1]; + } + } + } + } + sme_ReleaseGlobalLock( &pMac->sme); + return status; +} + +tANI_BOOLEAN sme_Is11dCountrycode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + if (VOS_TRUE == vos_mem_compare(pMac->scan.countryCodeCurrent, + pMac->scan.countryCode11d, 2)) + { + return eANI_BOOLEAN_TRUE; + } + else + { + return eANI_BOOLEAN_FALSE; + } +} + +eHalStatus sme_SpoofMacAddrReq(tHalHandle hHal, v_MACADDR_t *macaddr) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *pMacSpoofCmd; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + pMacSpoofCmd = csrGetCommandBuffer(pMac); + if (pMacSpoofCmd) + { + pMacSpoofCmd->command = eSmeCommandMacSpoofRequest; + vos_mem_set(&pMacSpoofCmd->u.macAddrSpoofCmd, + sizeof(tSirSpoofMacAddrReq), 0); + vos_mem_copy(pMacSpoofCmd->u.macAddrSpoofCmd.macAddr, + macaddr->bytes, VOS_MAC_ADDRESS_LEN); + + status = csrQueueSmeCommand(pMac, pMacSpoofCmd, false); + if ( !HAL_STATUS_SUCCESS( status ) ) + { + smsLog( pMac, LOGE, FL("fail to send msg status = %d\n"), status ); + csrReleaseCommand(pMac, pMacSpoofCmd); + } + } + else + { + //log error + smsLog(pMac, LOGE, FL("can not obtain a common buffer\n")); + status = eHAL_STATUS_RESOURCES; + } + sme_ReleaseGlobalLock( &pMac->sme); + } + return (status); +} + +#ifdef WLAN_FEATURE_EXTSCAN +/* --------------------------------------------------------------------------- + \fn sme_GetValidChannelsByBand + \brief SME API to fetch all valid channel filtered by band + \param hHal + \param wifiBand: RF band information + \param aValidChannels: Array to store channel info + \param len: number of channels + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_GetValidChannelsByBand (tHalHandle hHal, tANI_U8 wifiBand, + tANI_U32 *aValidChannels, tANI_U8 *pNumChannels) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tANI_U8 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0}; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 numChannels = 0; + tANI_U8 i = 0; + tANI_U32 totValidChannels = WNI_CFG_VALID_CHANNEL_LIST_LEN; + + if (!aValidChannels || !pNumChannels) { + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Output channel list/NumChannels is NULL")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + if ((wifiBand < WIFI_BAND_UNSPECIFIED) || (wifiBand >= WIFI_BAND_MAX)) { + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Invalid wifiBand (%d)"), wifiBand); + return eHAL_STATUS_INVALID_PARAMETER; + } + + status = sme_GetCfgValidChannels(hHal, &chanList[0], + &totValidChannels); + if (!HAL_STATUS_SUCCESS(status)) { + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Failed to get valid channel list (err=%d)"), status); + return status; + } + + switch (wifiBand) { + case WIFI_BAND_UNSPECIFIED: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, FL("Unspecified wifiBand, " + "return all (%d) valid channels"), totValidChannels); + numChannels = totValidChannels; + for (i = 0; i < numChannels; i++) + aValidChannels[i] = vos_chan_to_freq(chanList[i]); + break; + + case WIFI_BAND_BG: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, FL("WIFI_BAND_BG (2.4 GHz)")); + for (i = 0; i < totValidChannels; i++) + if (CSR_IS_CHANNEL_24GHZ(chanList[i])) + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + break; + + case WIFI_BAND_A: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_A (5 GHz without DFS)")); + for (i = 0; i < totValidChannels; i++) + if (CSR_IS_CHANNEL_5GHZ(chanList[i]) && + !CSR_IS_CHANNEL_DFS(chanList[i])) + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + break; + + case WIFI_BAND_ABG: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_ABG (2.4 GHz + 5 GHz; no DFS)")); + for (i = 0; i < totValidChannels; i++) + if ((CSR_IS_CHANNEL_24GHZ(chanList[i]) || + CSR_IS_CHANNEL_5GHZ(chanList[i])) && + !CSR_IS_CHANNEL_DFS(chanList[i])) + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + break; + + case WIFI_BAND_A_DFS_ONLY: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_A_DFS (5 GHz DFS only)")); + for (i = 0; i < totValidChannels; i++) + if (CSR_IS_CHANNEL_5GHZ(chanList[i]) && + CSR_IS_CHANNEL_DFS(chanList[i])) + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + break; + + case WIFI_BAND_A_WITH_DFS: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_A_WITH_DFS (5 GHz with DFS)")); + for (i = 0; i < totValidChannels; i++) + if (CSR_IS_CHANNEL_5GHZ(chanList[i])) + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + break; + + case WIFI_BAND_ABG_WITH_DFS: + smsLog(pMac, VOS_TRACE_LEVEL_INFO, + FL("WIFI_BAND_ABG_WITH_DFS (2.4 GHz + 5 GHz with DFS)")); + for (i = 0; i < totValidChannels; i++) + if (CSR_IS_CHANNEL_24GHZ(chanList[i]) || + CSR_IS_CHANNEL_5GHZ(chanList[i])) + aValidChannels[numChannels++] = + vos_chan_to_freq(chanList[i]); + break; + + default: + smsLog(pMac, VOS_TRACE_LEVEL_ERROR, + FL("Unknown wifiBand (%d))"), wifiBand); + return eHAL_STATUS_INVALID_PARAMETER; + break; + } + *pNumChannels = numChannels; + + return status; +} +/* --------------------------------------------------------------------------- + \fn sme_EXTScanGetCapabilities + \brief SME API to fetch Extended Scan capabilities + \param hHal + \param pReq: Extended Scan capabilities structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanGetCapabilities (tHalHandle hHal, + tSirGetEXTScanCapabilitiesReqParams *pReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirGetEXTScanCapabilitiesReqParams *pGetEXTScanCapabilitiesReq; + + pGetEXTScanCapabilitiesReq = + vos_mem_malloc(sizeof(*pGetEXTScanCapabilitiesReq)); + if ( !pGetEXTScanCapabilitiesReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_EXTSCAN_GET_CAPABILITIES_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pGetEXTScanCapabilitiesReq = *pReq; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pGetEXTScanCapabilitiesReq; + vosMessage.type = WDA_EXTSCAN_GET_CAPABILITIES_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "failed to post WDA_EXTSCAN_GET_CAPABILITIES_REQ ", + __func__); + vos_mem_free(pGetEXTScanCapabilitiesReq); + status = eHAL_STATUS_FAILURE; + } + + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pGetEXTScanCapabilitiesReq); + status = eHAL_STATUS_FAILURE; + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_EXTScanStart + \brief SME API to issue Extended Scan start + \param hHal + \param pStartCmd: Extended Scan start structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanStart (tHalHandle hHal, + tSirEXTScanStartReqParams *pStartCmd) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirEXTScanStartReqParams *pextScanStartReq; + + pextScanStartReq = vos_mem_malloc(sizeof(*pextScanStartReq)); + if ( !pextScanStartReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_EXTSCAN_START_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pextScanStartReq = *pStartCmd; + + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXTSCAN_START, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pextScanStartReq; + vosMessage.type = WDA_EXTSCAN_START_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to post WDA_EXTSCAN_START_REQ", __func__); + vos_mem_free(pextScanStartReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pextScanStartReq); + status = eHAL_STATUS_FAILURE; + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_EXTScanStop + \brief SME API to issue Extended Scan stop + \param hHal + \param pStopReq: Extended Scan stop structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_EXTScanStop(tHalHandle hHal, tSirEXTScanStopReqParams *pStopReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirEXTScanStopReqParams *pEXTScanStopReq; + + pEXTScanStopReq = vos_mem_malloc(sizeof(*pEXTScanStopReq)); + if ( !pEXTScanStopReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_EXTSCAN_STOP_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pEXTScanStopReq = *pStopReq; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXTSCAN_STOP, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pEXTScanStopReq; + vosMessage.type = WDA_EXTSCAN_STOP_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to post WDA_EXTSCAN_STOP_REQ", __func__); + vos_mem_free(pEXTScanStopReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pEXTScanStopReq); + status = eHAL_STATUS_FAILURE; + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_SetBssHotlist + \brief SME API to set BSSID hotlist + \param hHal + \param pSetHotListReq: Extended Scan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetBssHotlist (tHalHandle hHal, + tSirEXTScanSetBssidHotListReqParams *pSetHotListReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirEXTScanSetBssidHotListReqParams *pEXTScanSetBssidHotlistReq; + + pEXTScanSetBssidHotlistReq = + vos_mem_malloc(sizeof(*pEXTScanSetBssidHotlistReq)); + if ( !pEXTScanSetBssidHotlistReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pEXTScanSetBssidHotlistReq = *pSetHotListReq; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_BSS_HOTLIST, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pEXTScanSetBssidHotlistReq; + vosMessage.type = WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to post WDA_EXTSCAN_STOP_REQ", __func__); + vos_mem_free(pEXTScanSetBssidHotlistReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pEXTScanSetBssidHotlistReq); + status = eHAL_STATUS_FAILURE; + } + + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_ResetBssHotlist + \brief SME API to reset BSSID hotlist + \param hHal + \param pSetHotListReq: Extended Scan set hotlist structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_ResetBssHotlist (tHalHandle hHal, + tSirEXTScanResetBssidHotlistReqParams *pResetReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirEXTScanResetBssidHotlistReqParams *pEXTScanHotlistResetReq; + + pEXTScanHotlistResetReq = vos_mem_malloc(sizeof(*pEXTScanHotlistResetReq)); + if ( !pEXTScanHotlistResetReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pEXTScanHotlistResetReq = *pResetReq; + + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_BSS_HOTLIST, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pEXTScanHotlistResetReq; + vosMessage.type = WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to post WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ", + __func__); + vos_mem_free(pEXTScanHotlistResetReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pEXTScanHotlistResetReq); + status = eHAL_STATUS_FAILURE; + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_getCachedResults + \brief SME API to get cached results + \param hHal + \param pCachedResultsReq: Extended Scan get cached results structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_getCachedResults (tHalHandle hHal, + tSirEXTScanGetCachedResultsReqParams *pCachedResultsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirEXTScanGetCachedResultsReqParams *pEXTScanCachedResultsReq; + + pEXTScanCachedResultsReq = + vos_mem_malloc(sizeof(*pEXTScanCachedResultsReq)); + if ( !pEXTScanCachedResultsReq) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "WDA_EXTSCAN_GET_CACHED_RESULTS_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *pEXTScanCachedResultsReq = *pCachedResultsReq; + + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_RX_HDD_EXTSCAN_GET_CACHED_RESULTS, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pEXTScanCachedResultsReq; + vosMessage.type = WDA_EXTSCAN_GET_CACHED_RESULTS_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed tp post WDA_EXTSCAN_GET_CACHED_RESULTS_REQ", + __func__); + vos_mem_free(pEXTScanCachedResultsReq); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed to acquire SME Global Lock")); + vos_mem_free(pEXTScanCachedResultsReq); + status = eHAL_STATUS_FAILURE; + } + return(status); +} + +eHalStatus sme_EXTScanRegisterCallback (tHalHandle hHal, + void (*pEXTScanIndCb)(void *, const tANI_U16, void *), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + pMac->sme.pEXTScanIndCb = pEXTScanIndCb; + pMac->sme.pEXTScanCallbackContext = callbackContext; + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} + +#ifdef FEATURE_OEM_DATA_SUPPORT +eHalStatus sme_OemDataRegisterCallback (tHalHandle hHal, + void (*pOemDataIndCb)(void *, const tANI_U16, void *, tANI_U32), + void *callbackContext) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + pMac->sme.pOemDataIndCb = pOemDataIndCb; + pMac->sme.pOemDataCallbackContext = callbackContext; + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} +#endif + +void sme_SetMiracastMode (tHalHandle hHal,tANI_U8 mode) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + vos_msg_t vosMessage = {0}; + tSirHighPriorityDataInfoInd *phighPriorityDataInfo; + + pMac->miracast_mode = mode; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: miracast_mode: %d", __func__, mode); + + phighPriorityDataInfo = + vos_mem_malloc(sizeof(*phighPriorityDataInfo)); + if ( !phighPriorityDataInfo) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s:" + "Failed to allocate memory for WDA_HIGH_PRIORITY_DATA_INFO_IND", + __func__); + return; + } + + if (mode) + phighPriorityDataInfo->pause = TRUE; + else + phighPriorityDataInfo->pause = FALSE; + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = phighPriorityDataInfo; + vosMessage.type = WDA_HIGH_PRIORITY_DATA_INFO_IND; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + + if(VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s:" + "Failed to post WDA_HIGH_PRIORITY_DATA_INFO_IND msg to WDA", + __func__); + vos_mem_free(phighPriorityDataInfo); + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(phighPriorityDataInfo); + } +} +#endif /* WLAN_FEATURE_EXTSCAN */ + +void sme_resetCoexEevent(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (pMac == NULL) + { + printk("btc: %s pMac is NULL \n",__func__); + return; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("isCoexScoIndSet: %d"), pMac->isCoexScoIndSet); + + if (pMac->isCoexScoIndSet) + { + pMac->isCoexScoIndSet = 0; + ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, 0, + NULL, eANI_BOOLEAN_FALSE); + } + + return; +} + +void sme_disable_dfs_channel(tHalHandle hHal, bool disbale_dfs) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + pMac->scan.fEnableDFSChnlScan = !disbale_dfs; + csrDisableDfsChannel(pMac); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Modified fEnableDFSChnlScan: %d", __func__, + pMac->scan.fEnableDFSChnlScan); +} + +/* --------------------------------------------------------------------------- + \fn sme_Encryptmsgsend + \brief SME API to issue encrypt message request + \param hHal + \param pCmd: Data to be encrypted + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_Encryptmsgsend (tHalHandle hHal, + u8 *pCmd, + int length, + pEncryptMsgRSPCb encMsgCbk) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + u8 *pEncryptMsg; + + pEncryptMsg = vos_mem_malloc(length); + if ( !pEncryptMsg) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for " + "SIR_HAL_ENCRYPT_MSG_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(pEncryptMsg, pCmd, length); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) { + + pMac->sme.pEncMsgInfoParams.pEncMsgCbk = encMsgCbk; + pMac->sme.pEncMsgInfoParams.pUserData = hHal; + /* Serialize the req through MC thread */ + vosMessage.bodyptr = pEncryptMsg; + vosMessage.type = SIR_HAL_ENCRYPT_MSG_REQ; + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type)); + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: failed to post SIR_HAL_ENCRYPT_MSG_REQ", __func__); + vos_mem_free(pEncryptMsg); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(pEncryptMsg); + status = eHAL_STATUS_FAILURE; + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn sme_RegisterBtCoexTDLSCallback + \brief Used to plug in callback function + Which notify btcoex on or off. + Notification come from FW. + \param hHal + \param pCallbackfn : callback function pointer should be plugged in + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_RegisterBtCoexTDLSCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, int ) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: Plug in BtCoex TDLS CB", __func__); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if (NULL != pCallbackfn) + { + pMac->sme.pBtCoexTDLSNotification = pCallbackfn; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} + +/* --------------------------------------------------------------------------- + \fn smeNeighborMiddleOfRoaming + + \brief This function is a wrapper to call csrNeighborMiddleOfRoaming + + \param hHal - The handle returned by macOpen. + + \return eANI_BOOLEAN_TRUE if reassoc in progress, + eANI_BOOLEAN_FALSE otherwise +---------------------------------------------------------------------------*/ + +tANI_BOOLEAN smeNeighborMiddleOfRoaming(tHalHandle hHal) +{ + return (csrNeighborMiddleOfRoaming(PMAC_STRUCT(hHal))); +} + +/* --------------------------------------------------------------------------- + + \fn sme_IsTdlsOffChannelValid + + \brief To check if the channel is valid for currently established domain + This is a synchronous API. + + \param hHal - The handle returned by macOpen. + \param channel - channel to verify + + \return TRUE/FALSE, TRUE if channel is valid + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN sme_IsTdlsOffChannelValid(tHalHandle hHal, tANI_U8 channel) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_BOOLEAN valid = FALSE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + /* check whether off channel is valid and non DFS */ + if (csrRoamIsChannelValid(pMac, channel)) + { + if (!CSR_IS_CHANNEL_DFS(channel)) + valid = TRUE; + else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: configured channel is DFS", __func__); + } + } + else { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: configured channel is not valid", __func__); + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: current country code %c%c channel %d valid %d", + __func__, pMac->scan.countryCodeCurrent[0], + pMac->scan.countryCodeCurrent[1], channel, valid); + return (valid); +} + +tANI_BOOLEAN sme_IsCoexScoIndicationSet(tHalHandle hHal) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tANI_BOOLEAN valid = FALSE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + status = sme_AcquireGlobalLock( &pMac->sme ); + if ( HAL_STATUS_SUCCESS( status ) ) + { + valid = pMac->isCoexScoIndSet; + } + sme_ReleaseGlobalLock( &pMac->sme ); + return (valid); +} +eHalStatus sme_SetMiracastVendorConfig(tHalHandle hHal, + tANI_U32 iniNumBuffAdvert , tANI_U32 set_value) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET]; + tANI_U32 val = SIZE_OF_SUPPORTED_MCS_SET; + + if (ccmCfgGetStr(hHal, WNI_CFG_SUPPORTED_MCS_SET, mcsSet, &val) + != eHAL_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("failed to get ini param, WNI_CFG_SUPPORTED_MCS_SET")); + return eHAL_STATUS_FAILURE; + } + + if (set_value) + { + if (pMac->miracastVendorConfig) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL(" Miracast tuning already enabled!!")); + return eHAL_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Enable Miracast tuning by disabling 64QAM rates, setting 4 blocks for aggregation and disabling probe response for broadcast probe in P2P-GO mode")); + + if (ccmCfgSetInt(hHal, WNI_CFG_NUM_BUFF_ADVERT, 4, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failure: Could not set WNI_CFG_NUM_BUFF_ADVERT")); + return eHAL_STATUS_FAILURE; + } + /* Disable 64QAM rates ie (MCS 5,6 and 7) + */ + mcsSet[0]=0x1F; + } + else + { + if (!pMac->miracastVendorConfig) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL(" Miracast tuning already disabled!!")); + return eHAL_STATUS_SUCCESS; + } + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("Disable Miracast tuning by enabling all MCS rates, setting %d blocks for aggregation and enabling probe response for broadcast probe in P2P-GO mode"), + iniNumBuffAdvert); + + if (ccmCfgSetInt(hHal, WNI_CFG_NUM_BUFF_ADVERT, iniNumBuffAdvert, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failure: Could not set WNI_CFG_NUM_BUFF_ADVERT")); + return eHAL_STATUS_FAILURE; + } + /* Enable all MCS rates) + */ + mcsSet[0]=0xFF; + } + + if (ccmCfgSetStr(hHal, WNI_CFG_SUPPORTED_MCS_SET, mcsSet, + val, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failure: Could not set WNI_CFG_SUPPORTED_MCS_SET")); + return eHAL_STATUS_FAILURE; + } + + pMac->miracastVendorConfig = set_value; + return eHAL_STATUS_SUCCESS; +} + +void sme_SetDefDot11Mode(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + csrSetDefaultDot11Mode(pMac); +} + +/* --------------------------------------------------------------------------- + \fn sme_SetTdls2040BSSCoexistence + \brief API to enable or disable 20_40 BSS Coexistence IE in TDLS frames. + + \param isEnabled - Enable or Disable. + \- return VOS_STATUS_SUCCES + -------------------------------------------------------------------------*/ +eHalStatus sme_SetTdls2040BSSCoexistence(tHalHandle hHal, + tANI_S32 isTdls2040BSSCoexEnabled) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t msg; + tAniSetTdls2040BSSCoex *pMsg; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (HAL_STATUS_SUCCESS( status )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: is2040BSSCoexEnabled %d ", + __func__, isTdls2040BSSCoexEnabled); + pMsg = vos_mem_malloc(sizeof(tAniSetTdls2040BSSCoex)); + if (NULL == pMsg ) + { + smsLog(pMac, LOGE, "failed to allocate mem for SetTdls2040BSSCoex"); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg->msgType = pal_cpu_to_be16( + (tANI_U16)eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ); + pMsg->msgLen = (tANI_U16)sizeof(tAniSetTdls2040BSSCoex); + pMsg->SetTdls2040BSSCoex = isTdls2040BSSCoexEnabled; + + msg.type = eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ; + msg.reserved = 0; + msg.bodyptr = pMsg; + msg.bodyval = 0; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_PE, &msg)) + { + smsLog(pMac, LOGE, + "sme_SetTdls2040BSSCoexistence failed to post msg to PE "); + vos_mem_free((void *)pMsg); + status = eHAL_STATUS_FAILURE; + } + smsLog(pMac, LOG1, FL(" returned")); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetRtsCtsHtVht + \brief API to to enable/disable RTS/CTS for different modes. + + \param set_value - Bit mask value to enable RTS/CTS for different modes. + \- return VOS_STATUS_SUCCES if INdication is posted to + WDA else return eHAL_STATUS_FAILURE + -------------------------------------------------------------------------*/ +eHalStatus sme_SetRtsCtsHtVht(tHalHandle hHal, tANI_U32 set_value) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t msg; + + smsLog(pMac, LOG1, FL(" set_value = %d"), set_value); + + if (ccmCfgSetInt(hHal, WNI_CFG_ENABLE_RTSCTS_HTVHT, set_value, + NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) + { + smsLog(pMac, LOGE, + FL("Failure: Could not set WNI_CFG_ENABLE_RTSCTS_HTVHT")); + return eHAL_STATUS_FAILURE; + } + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme )) + { + vos_mem_zero(&msg, sizeof(vos_msg_t)); + msg.type = WDA_SET_RTS_CTS_HTVHT; + msg.reserved = 0; + msg.bodyval = set_value; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, &msg)) + { + smsLog(pMac, LOGE, + FL("Not able to post WDA_SET_RTS_CTS_HTVHT message to HAL")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_SUCCESS; + } + return eHAL_STATUS_FAILURE; + +} + + +/* --------------------------------------------------------------------------- + \fn sme_fatal_event_logs_req + \brief API to to send flush log command to FW.. + + \param hHal - Mac Context Handle + \- return VOS_STATUS_SUCCES if command is posted to + WDA else return eHAL_STATUS_FAILURE + -------------------------------------------------------------------------*/ +eHalStatus sme_fatal_event_logs_req(tHalHandle hHal, tANI_U32 is_fatal, + tANI_U32 indicator, tANI_U32 reason_code, + tANI_BOOLEAN dump_vos_trace) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpSirFatalEventLogsReqParam pFatalEventLogsReqParams; + + /* Dump last 500 VosTrace */ + if (dump_vos_trace) + vosTraceDumpAll(pMac, 0, 0, 500, 0); + + if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator) + { + vos_flush_host_logs_for_fatal(); + return VOS_STATUS_SUCCESS; + } + + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme )) + { + pFatalEventLogsReqParams = + vos_mem_malloc(sizeof(*pFatalEventLogsReqParams)); + if(NULL == pFatalEventLogsReqParams) + { + smsLog(pMac, LOGE, + FL("vos_mem_alloc failed ")); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_set(pFatalEventLogsReqParams, + sizeof(*pFatalEventLogsReqParams), 0); + pFatalEventLogsReqParams->reason_code = reason_code; + + vos_mem_zero(&msg, sizeof(vos_msg_t)); + msg.type = WDA_FATAL_EVENT_LOGS_REQ; + msg.reserved = 0; + msg.bodyptr = pFatalEventLogsReqParams; + msg.bodyval = 0; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vos_mem_free(pFatalEventLogsReqParams); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + + } + return eHAL_STATUS_FAILURE; +} + + +/** + * sme_handleSetFccChannel() - handle fcc constraint request + * @hal: HAL pointer + * @fcc_constraint: whether to apply or remove fcc constraint + * + * Return: tANI_BOOLEAN. + */ +tANI_BOOLEAN sme_handleSetFccChannel(tHalHandle hHal, tANI_U8 fcc_constraint, + v_U32_t scan_pending) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + status = sme_AcquireGlobalLock(&pMac->sme); + + if (eHAL_STATUS_SUCCESS == status && + (!sme_Is11dSupported(hHal)) ) + { + pMac->scan.fcc_constraint = !fcc_constraint; + + if (scan_pending == TRUE) { + pMac->scan.defer_update_channel_list = true; + } else { + /* update the channel list to the firmware */ + csrUpdateChannelList(pMac); + } + } + + sme_ReleaseGlobalLock(&pMac->sme); + + return status; +} + +eHalStatus sme_enableDisableChanAvoidIndEvent(tHalHandle hHal, tANI_U8 set_value) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t msg; + + smsLog(pMac, LOG1, FL("set_value: %d"), set_value); + if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme )) + { + vos_mem_zero(&msg, sizeof(vos_msg_t)); + msg.type = WDA_SEND_FREQ_RANGE_CONTROL_IND; + msg.reserved = 0; + msg.bodyval = set_value; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } + + return eHAL_STATUS_FAILURE; +} + +eHalStatus sme_DeleteAllTDLSPeers(tHalHandle hHal, uint8_t sessionId) +{ + tSirDelAllTdlsPeers *pMsg; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + + pMsg = vos_mem_malloc(sizeof(tSirDelAllTdlsPeers)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, FL("memory alloc failed")); + return eHAL_STATUS_FAILURE; + } + vos_mem_set(pMsg, sizeof( tSirDelAllTdlsPeers ), 0); + pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEL_ALL_TDLS_PEERS); + pMsg->mesgLen = pal_cpu_to_be16((tANI_U16)sizeof( tSirDelAllTdlsPeers )); + vos_mem_copy(pMsg->bssid, pSession->connectedProfile.bssid, + sizeof(tSirMacAddr)); + status = palSendMBMessage( pMac->hHdd, pMsg ); + return status; +} + + +/** + * sme_FwMemDumpReq() - Send Fwr mem Dump Request + * @hal: HAL pointer + * + * Return: eHalStatus + */ + +eHalStatus sme_FwMemDumpReq(tHalHandle hHal, tAniFwrDumpReq *recv_req) +{ + + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t msg; + tAniFwrDumpReq * send_req; + + send_req = vos_mem_malloc(sizeof(*send_req)); + if(!send_req) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Mem allo failed for FW_MEM_DUMP")); + return eHAL_STATUS_FAILURE; + } + + send_req->fwMemDumpReqCallback = recv_req->fwMemDumpReqCallback; + send_req->fwMemDumpReqContext = recv_req->fwMemDumpReqContext; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + msg.bodyptr = send_req; + msg.type = WDA_FW_MEM_DUMP_REQ; + msg.reserved = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post WDA_FW_MEM_DUMP")); + vos_mem_free(send_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Failed to acquire SME Global Lock")); + vos_mem_free(send_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +eHalStatus sme_set_wificonfig_params(tHalHandle hHal, tSetWifiConfigParams *req) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t msg; + + status = sme_AcquireGlobalLock(&pMac->sme); + + if (eHAL_STATUS_SUCCESS == status){ + + /* serialize the req through MC thread */ + msg.type = WDA_WIFI_CONFIG_REQ; + msg.reserved = 0; + msg.bodyptr = req; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type)); + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "Not able to post SIR_HAL_WIFI_CONFIG_PARAMS message to HAL", __func__); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + } + return status; +} + +eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId, + tANI_U32 *regInfo1, tANI_U32 *regInfo2) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status; + tANI_U8 i; + eAniBoolean found = false; + + status = sme_AcquireGlobalLock(&pMac->sme); + *regInfo1 = 0; + *regInfo2 = 0; + if (HAL_STATUS_SUCCESS(status)) + { + for (i = 0 ; i < WNI_CFG_VALID_CHANNEL_LIST_LEN; i++) + { + if (pMac->scan.defaultPowerTable[i].chanId == chanId) + { + SME_SET_CHANNEL_REG_POWER(*regInfo1, + pMac->scan.defaultPowerTable[i].pwr); + + SME_SET_CHANNEL_MAX_TX_POWER(*regInfo2, + pMac->scan.defaultPowerTable[i].pwr); + + + found = true; + break; + } + } + + if (!found) + status = eHAL_STATUS_FAILURE; + + sme_ReleaseGlobalLock(&pMac->sme); + } + return status; +} + +eHalStatus sme_GetCurrentAntennaIndex(tHalHandle hHal, + tCsrAntennaIndexCallback callback, + void *pContext, tANI_U8 sessionId) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + tSirAntennaDiversitySelectionReq *pMsg; + tCsrRoamSession *pSession; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + vos_msg_t vosMessage; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + pSession = CSR_GET_SESSION( pMac, sessionId ); + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found"), sessionId); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + pMsg = (tSirAntennaDiversitySelectionReq*)vos_mem_malloc(sizeof(*pMsg)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, FL("failed to allocated memory")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pMsg->callback = callback; + pMsg->data = pContext; + + vosMessage.type = WDA_ANTENNA_DIVERSITY_SELECTION_REQ; + vosMessage.bodyptr = pMsg; + vosMessage.reserved = 0; + + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to post message to WDA", __func__); + vos_mem_free(pMsg); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_SUCCESS; + } + return eHAL_STATUS_FAILURE; +} + +eHalStatus sme_setBcnMissPenaltyCount(tHalHandle hHal, + tModifyRoamParamsReqParams *pModifyRoamReqParams) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus; + tModifyRoamParamsReqParams *pMsg; + vos_msg_t msg; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + pMsg = (tModifyRoamParamsReqParams*)vos_mem_malloc(sizeof(*pMsg)); + if (NULL == pMsg) + { + smsLog(pMac, LOGE, FL("failed to allocated memory")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + if (NULL == pModifyRoamReqParams) + { + smsLog(pMac, LOGE, FL("Invalid memory")); + vos_mem_free(pMsg); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + pMsg->param = pModifyRoamReqParams->param; + pMsg->value = pModifyRoamReqParams->value; + vos_mem_zero(&msg, sizeof(vos_msg_t)); + msg.type = WDA_MODIFY_ROAM_PARAMS_IND; + msg.reserved = 0; + msg.bodyptr = pMsg; + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + status = eHAL_STATUS_FAILURE; + vos_mem_free(pMsg); + } + sme_ReleaseGlobalLock( &pMac->sme ); + return status; + } + + return eHAL_STATUS_FAILURE; +} + +/** + * sme_remove_bssid_from_scan_list() - wrapper to remove the bssid from + * scan list + * @hal: hal context. + * @bssid: bssid to be removed + * + * This function remove the given bssid from scan list. + * + * Return: hal status. + */ +eHalStatus sme_remove_bssid_from_scan_list(tHalHandle hal, + tSirMacAddr bssid) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT(hal); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) { + csr_remove_bssid_from_scan_list(pMac, bssid); + sme_ReleaseGlobalLock(&pMac->sme); + } + + return status; +} + +/** + * sme_set_mgmt_frm_via_wq5() - Set INI params sendMgmtPktViaWQ5 to WDA. + * @hal: HAL pointer + * @sendMgmtPktViaWQ5: INI params to enable/disable sending mgmt pkt via WQ5. + * + * Return: void + */ +void sme_set_mgmt_frm_via_wq5(tHalHandle hHal, tANI_BOOLEAN sendMgmtPktViaWQ5) +{ + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + eHalStatus status = eHAL_STATUS_SUCCESS; + + status = sme_AcquireGlobalLock(&pMac->sme); + if (HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "sendMgmtPktViaWQ5 is %d", sendMgmtPktViaWQ5); + /* not serializing this messsage, as this is only going + * to set a variable in WDA/WDI + */ + WDA_SetMgmtPktViaWQ5(sendMgmtPktViaWQ5); + sme_ReleaseGlobalLock(&pMac->sme); + } + return; +} + +/* ARP DEBUG STATS */ + +/** + * sme_set_nud_debug_stats() - sme api to set nud debug stats + * @hHal: handle to hal + * @pSetStatsParam: pointer to set stats param + */ +eHalStatus sme_set_nud_debug_stats(tHalHandle hHal, + setArpStatsParams *pSetStatsParam) +{ + setArpStatsParams *arp_set_param; + vos_msg_t msg; + + arp_set_param = vos_mem_malloc(sizeof(*arp_set_param)); + if (arp_set_param == NULL) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(arp_set_param, pSetStatsParam, sizeof(*arp_set_param)); + + msg.type = WDA_SET_ARP_STATS_REQ; + msg.reserved = 0; + msg.bodyptr = arp_set_param; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post message to WDA")); + vos_mem_free(arp_set_param); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +/** + * sme_get_nud_debug_stats() - sme api to get nud debug stats + * @hHal: handle to hal + * @pGetStatsParam: pointer to set stats param + */ +eHalStatus sme_get_nud_debug_stats(tHalHandle hHal, + getArpStatsParams *pGetStatsParam) +{ + getArpStatsParams *arpGetParams; + vos_msg_t msg; + + arpGetParams = vos_mem_malloc(sizeof(*arpGetParams)); + if (arpGetParams == NULL) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(arpGetParams, pGetStatsParam, sizeof(*arpGetParams)); + + msg.type = WDA_GET_ARP_STATS_REQ; + msg.reserved = 0; + msg.bodyptr = arpGetParams; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post message to WDA")); + vos_mem_free(arpGetParams); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + + +#ifdef SAP_AUTH_OFFLOAD +/** + * sme_set_sap_auth_offload() enable/disable Software AP Auth Offload + * @hHal: hal layer handler + * @sap_auth_offload_info: the information of Software AP Auth offload + * + * This function provide enable/disable Software AP authenticaiton offload + * feature on target firmware + * + * Return: Return eHalStatus. + */ +eHalStatus sme_set_sap_auth_offload(tHalHandle hHal, + struct tSirSapOffloadInfo *sap_auth_offload_info) +{ + vos_msg_t vosMessage; + struct tSirSapOffloadInfo *sme_sap_auth_offload_info; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pMac->sap_auth_offload_sec_type = + sap_auth_offload_info->sap_auth_offload_sec_type; + pMac->sap_auth_offload = sap_auth_offload_info->sap_auth_offload_enable; + + sme_sap_auth_offload_info = + vos_mem_malloc(sizeof(*sme_sap_auth_offload_info)); + + if (!sme_sap_auth_offload_info) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_SET_SAP_AUTH_OFL", + __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + vos_mem_copy(sme_sap_auth_offload_info, sap_auth_offload_info, + sizeof(*sap_auth_offload_info)); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + /* serialize the req through MC thread */ + vosMessage.type = WDA_SET_SAP_AUTH_OFL; + vosMessage.bodyptr = sme_sap_auth_offload_info; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, &vosMessage))) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_SAP_AUTH_OFL to WDA!", + __func__); + vos_mem_free(sme_sap_auth_offload_info); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AcquireGlobalLock error!", + __func__); + vos_mem_free(sme_sap_auth_offload_info); + status = eHAL_STATUS_FAILURE; + } + + return (status); +} +#endif + +#ifdef DHCP_SERVER_OFFLOAD +/** + * sme_set_dhcp_srv_offload() - sme api to set dhcp server offload info + * @hal: handle to hal + * @dhcp_srv_info: pointer to dhcp server info + * + * Return: eHalStatus + * eHAL_STATUS_SUCCESS - success or else failure code + */ +eHalStatus sme_set_dhcp_srv_offload(tHalHandle hal, + sir_dhcp_srv_offload_info_t *dhcp_srv_info) +{ + vos_msg_t vos_msg; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + sir_dhcp_srv_offload_info_t *dhcp_serv_info = NULL; + + dhcp_serv_info = + vos_mem_malloc(sizeof(*dhcp_serv_info)); + if (NULL == dhcp_serv_info) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "Failed to alloc memory"); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(dhcp_serv_info, dhcp_srv_info, + sizeof(*dhcp_serv_info)); + + dhcp_serv_info->bssidx = peFindBssIdxFromSmeSessionId(mac, dhcp_srv_info->bssidx); + status = sme_AcquireGlobalLock(&mac->sme); + if (eHAL_STATUS_SUCCESS == status) { + /* serialize the req through MC thread */ + vos_msg.type = WDA_SET_DHCP_SERVER_OFFLOAD_REQ; + vos_msg.bodyptr = dhcp_serv_info; + + if (!VOS_IS_STATUS_SUCCESS(vos_mq_post_message + (VOS_MODULE_ID_WDA, &vos_msg))) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_DHCP_SERVER_OFFLOAD_REQ to WDA!", + __func__); + vos_mem_free(dhcp_serv_info); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&mac->sme); + } else { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AcquireGlobalLock error!", + __func__); + vos_mem_free(dhcp_serv_info); + } + + return status; +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * sme_set_mdns_offload() - sme API to set mdns offload enable/disable + * @hal: handle to hal pointer + * @mdns_info: pointer to mdns offload info + * + * Return - eHalStatus + */ +eHalStatus sme_set_mdns_offload(tHalHandle hal, + sir_mdns_offload_info_t *mdns_info) +{ + vos_msg_t vos_msg; + sir_mdns_offload_info_t *mdns_offload; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + mdns_offload = vos_mem_malloc(sizeof(*mdns_offload)); + + if (!mdns_offload) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_SET_MDNS_OFFLOAD_CMD", + __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + vos_mem_copy(mdns_offload, mdns_info, sizeof(*mdns_offload)); + mdns_offload->bss_idx = + peFindBssIdxFromSmeSessionId(mac, mdns_info->bss_idx); + status = sme_AcquireGlobalLock(&mac->sme); + if (eHAL_STATUS_SUCCESS == status) { + /* serialize the req through MC thread */ + vos_msg.type = WDA_SET_MDNS_OFFLOAD_CMD; + vos_msg.bodyptr = mdns_offload; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, + &vos_msg))) { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_MDNS_OFFLOAD_CMD to WDA!", + __func__); + vos_mem_free(mdns_offload); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&mac->sme); + } else { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AcquireGlobalLock error!", + __func__); + vos_mem_free(mdns_offload); + } + + return (status); +} + +/** + * sme_set_mdns_fqdn() - SME API to set mDNS Fqdn info + * @hal: hal handle + * @mdns_fqdn: mDNS Fqdn info struct + * + * Return - return eHalStatus + */ +eHalStatus sme_set_mdns_fqdn(tHalHandle hal, + sir_mdns_fqdn_info_t *mdns_fqdn) +{ + vos_msg_t vos_msg; + sir_mdns_fqdn_info_t *fqdn_info; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + fqdn_info = vos_mem_malloc(sizeof(*fqdn_info)); + + if (!fqdn_info) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_SET_MDNS_FQDN_CMD", + __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + vos_mem_copy(fqdn_info, mdns_fqdn, sizeof(*fqdn_info)); + fqdn_info->bss_idx = peFindBssIdxFromSmeSessionId(mac, mdns_fqdn->bss_idx); + status = sme_AcquireGlobalLock(&mac->sme); + if (eHAL_STATUS_SUCCESS == status) { + /* serialize the req through MC thread */ + vos_msg.type = WDA_SET_MDNS_FQDN_CMD; + vos_msg.bodyptr = fqdn_info; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, + &vos_msg))) { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_MDNS_FQDN_CMD to WDA!", + __func__); + vos_mem_free(fqdn_info); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&mac->sme); + } else { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AcquireGlobalLock error!", + __func__); + vos_mem_free(fqdn_info); + } + + return (status); +} + +/** + * sme_set_mdns_resp() - SME API to set mDNS response info + * @hal: hal handle + * @mdns_resp : mDNS response info struct + * + * Return - eHalStatus + */ +eHalStatus sme_set_mdns_resp(tHalHandle hal, + sir_mdns_resp_info_t *mdns_resp) +{ + vos_msg_t vos_msg; + sir_mdns_resp_info_t *resp_info; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + + resp_info = vos_mem_malloc(sizeof(*resp_info)); + + if (!resp_info) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_SET_MDNS_RESPONSE_CMD", + __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + vos_mem_copy(resp_info, mdns_resp, sizeof(*resp_info)); + resp_info->bss_idx = peFindBssIdxFromSmeSessionId(mac, mdns_resp->bss_idx); + status = sme_AcquireGlobalLock(&mac->sme); + if (eHAL_STATUS_SUCCESS == status) { + /* serialize the req through MC thread */ + vos_msg.type = WDA_SET_MDNS_RESPONSE_CMD; + vos_msg.bodyptr = resp_info; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, + &vos_msg))) { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_SET_MDNS_RESPONSE_CMD to WDA!", + __func__); + vos_mem_free(resp_info); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&mac->sme); + } else { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: sme_AcquireGlobalLock error!", + __func__); + vos_mem_free(resp_info); + } + + return (status); +} +#endif /* MDNS_OFFLOAD */ + +/** + * sme_update_hb_threshold() - Set heartbeat Threshold value. + * @hal: HAL pointer + * @cfgId: cfg param id + * @hbThresh: heartbeat threshold value. + * + * Return: Success/Failure + */ +eHalStatus sme_update_hb_threshold(tHalHandle hHal, tANI_U32 cfgId, + tANI_U8 hbThresh, eCsrBand eBand) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if ((hbThresh < WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN) || + (hbThresh > WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX)) { + smsLog(pMac, LOGE, FL("invalid heartbeat threshold %hhu"), hbThresh); + return eHAL_STATUS_FAILURE; + } + + if(eBand == eCSR_BAND_24) + pMac->roam.configParam.HeartbeatThresh24 = hbThresh; + + if(eBand == eCSR_BAND_5G) + pMac->roam.configParam.HeartbeatThresh50 = hbThresh; + + status = sme_update_cfg_int_param(hHal, WNI_CFG_HEART_BEAT_THRESHOLD); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(pMac, LOGE, FL("WLAN set heartbeat threshold FAILED")); + status = eHAL_STATUS_FAILURE; + } + return status; +} + +#ifdef WLAN_FEATURE_APFIND +/** + * sme_apfind_set_cmd() - set apfind configuration to firmware + * @input: pointer to apfind request data. + * + * SME API to set APFIND configuations to firmware. + * + * Return: VOS_STATUS. + */ +VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input) +{ + vos_msg_t msg; + struct hal_apfind_request *data; + size_t data_len; + + data_len = sizeof(struct hal_apfind_request) + input->request_data_len; + data = vos_mem_malloc(data_len); + + if (data == NULL) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Memory allocation failure")); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(data, data_len); + data->request_data_len = input->request_data_len; + if (input->request_data_len) { + vos_mem_copy(data->request_data, + input->request_data, input->request_data_len); + } + + msg.type = WDA_APFIND_SET_CMD; + msg.reserved = 0; + msg.bodyptr = data; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg)) { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + FL("Not able to post WDA_APFIND_SET_CMD message to WDA")); + vos_mem_free(data); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +#endif /* WLAN_FEATURE_APFIND */ + +/** + * sme_capture_tsf_req() - send tsf capture request to firmware + * @hHal: hal handle. + * @cap_tsf_params: capture tsf request params. + * + * Return: hal status. + */ +eHalStatus sme_capture_tsf_req(tHalHandle hHal, tSirCapTsfParams cap_tsf_params) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirCapTsfParams tsf_params = NULL; + VOS_STATUS vos_status; + tCsrRoamSession *pSession; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock(&pMac->sme))) + { + pSession = CSR_GET_SESSION(pMac, cap_tsf_params.session_id); + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found"), + cap_tsf_params.bss_idx); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + tsf_params = (tpSirCapTsfParams) + vos_mem_malloc(sizeof(*tsf_params)); + + if (NULL == tsf_params) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for sme_capture_tsf_req", + __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(&tsf_params->bssid, &pSession->connectedProfile.bssid, + sizeof(tsf_params->bssid)); + + tsf_params->tsf_rsp_cb_func = cap_tsf_params.tsf_rsp_cb_func; + tsf_params->tsf_rsp_cb_ctx = cap_tsf_params.tsf_rsp_cb_ctx; + + /* serialize the req through MC thread */ + /* TODO: check if callback is required */ + vosMessage.bodyptr = tsf_params; + vosMessage.type = eWNI_SME_CAP_TSF_REQ; + + vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Set TM Level MSG fail", __func__); + vos_mem_free(tsf_params); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +eHalStatus sme_del_sta_ba_session_req(tHalHandle hHal, + tDelBaParams sta_del_params) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + ptDelBaParams del_params = NULL; + VOS_STATUS vos_status; + tCsrRoamSession *pSession; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ, NO_SESSION, 0)); + if (eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock(&pMac->sme))) + { + pSession = CSR_GET_SESSION(pMac, sta_del_params.session_id); + if (!pSession) + { + smsLog(pMac, LOGE, FL("session not found")); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + + del_params = (ptDelBaParams) vos_mem_malloc(sizeof(*del_params)); + + if (NULL == del_params) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for sme_del_sta_ba_session_req", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + vos_mem_copy(&del_params->session_id, &pSession->sessionId, + sizeof(del_params->session_id)); + + vosMessage.bodyptr = del_params; + vosMessage.type = eWNI_SME_DEL_BA_SES_REQ; + + vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage); + + if (!VOS_IS_STATUS_SUCCESS(vos_status)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Set TM Level MSG fail", __func__); + vos_mem_free(del_params); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock( &pMac->sme ); + } + return(status); +} + +/** + * sme_get_tsf_req() - send tsf get request to firmware + * @hHal: hal handle. + * @cap_tsf_params: capture tsf request params. + * + * Return: hal status. + */ +eHalStatus sme_get_tsf_req(tHalHandle hHal, tSirCapTsfParams cap_tsf_params) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tpSirCapTsfParams tsf_params = NULL; + VOS_STATUS vosStatus; + tCsrRoamSession *pSession; + + MTRACE(vos_trace(VOS_MODULE_ID_SME, + TRACE_CODE_SME_TX_HDD_GET_TSF_REQ, NO_SESSION, 0)); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + pSession = CSR_GET_SESSION(pMac, cap_tsf_params.session_id); + + if (!pSession) + { + smsLog(pMac, LOGE, FL("session %d not found"), + cap_tsf_params.bss_idx); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + tsf_params = (tpSirCapTsfParams) + vos_mem_malloc(sizeof(*tsf_params)); + if (NULL == tsf_params) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for sme_capture_tsf_req", + __func__); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + + vos_mem_copy(&tsf_params->bssid, &pSession->connectedProfile.bssid, + sizeof(tsf_params->bssid)); + tsf_params->tsf_rsp_cb_func = cap_tsf_params.tsf_rsp_cb_func; + tsf_params->tsf_rsp_cb_ctx = cap_tsf_params.tsf_rsp_cb_ctx; + + /* serialize the req through MC thread */ + /* TODO: check if callback is required */ + vosMessage.bodyptr = tsf_params; + vosMessage.type = eWNI_SME_GET_TSF_REQ; + + vosStatus = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Post Set TM Level MSG fail", __func__); + vos_mem_free(tsf_params); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + return(status); +} diff --git a/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c b/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c new file mode 100644 index 000000000000..fef98d3dd8c1 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/sme_common/sme_FTApi.c @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/**========================================================================= + + \brief Definitions for SME FT APIs + + + ========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include "vos_utils.h" + +#ifdef WLAN_FEATURE_LFR_MBB +#include "csr_roam_mbb.h" +#endif + + +/*-------------------------------------------------------------------------- + Initialize the FT context. + ------------------------------------------------------------------------*/ +void sme_FTOpen(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_SUCCESS; + + //Clear the FT Context. + sme_FTReset(hHal); + status = vos_timer_init(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer,VOS_TIMER_TYPE_SW, + sme_PreauthReassocIntvlTimerCallback, (void *)pMac); + + if (eHAL_STATUS_SUCCESS != status) + { + smsLog(pMac, LOGE, FL("Preauth Reassoc interval Timer allocation failed")); + return; + } + vos_reset_roam_timer_log(); + +#ifdef WLAN_FEATURE_LFR_MBB + status = vos_timer_init(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer, + VOS_TIMER_TYPE_SW, + csr_preauth_reassoc_mbb_timer_callback, + (void *)pMac); + + if (eHAL_STATUS_SUCCESS != status) { + smsLog(pMac, LOGE, FL("pre_auth_reassoc_mbb_timer allocation failed")); + return; + } +#endif +} + +/*-------------------------------------------------------------------------- + Cleanup the SME FT Global context. + ------------------------------------------------------------------------*/ +void sme_FTClose(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + //Clear the FT Context. + sme_FTReset(hHal); + vos_timer_destroy(&pMac->ft.ftSmeContext.preAuthReassocIntvlTimer); + +#ifdef WLAN_FEATURE_LFR_MBB + vos_timer_destroy(&pMac->ft.ftSmeContext.pre_auth_reassoc_mbb_timer); +#endif +} + +void sme_SetFTPreAuthState(tHalHandle hHal, v_BOOL_t state) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + pMac->ft.ftSmeContext.setFTPreAuthState = state; +} + +v_BOOL_t sme_GetFTPreAuthState(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->ft.ftSmeContext.setFTPreAuthState; +} + +/*-------------------------------------------------------------------------- + Each time the supplicant sends down the FT IEs to the driver. + This function is called in SME. This fucntion packages and sends + the FT IEs to PE. + ------------------------------------------------------------------------*/ +void sme_SetFTIEs( tHalHandle hHal, tANI_U8 sessionId, const tANI_U8 *ft_ies, + tANI_U16 ft_ies_length ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) return; + + if (ft_ies == NULL) + { + smsLog( pMac, LOGE, FL(" ft ies is NULL")); + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, "FT IEs Req is received in state %d", + pMac->ft.ftSmeContext.FTState); +#endif + + // Global Station FT State + switch(pMac->ft.ftSmeContext.FTState) + { + case eFT_START_READY: + case eFT_AUTH_REQ_READY: +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, FL("ft_ies_length: %d"), ft_ies_length); +#endif + if ((pMac->ft.ftSmeContext.auth_ft_ies) && + (pMac->ft.ftSmeContext.auth_ft_ies_length)) + { + // Free the one we received last from the supplicant + vos_mem_free(pMac->ft.ftSmeContext.auth_ft_ies); + pMac->ft.ftSmeContext.auth_ft_ies_length = 0; + } + ft_ies_length = VOS_MIN(ft_ies_length, MAX_FTIE_SIZE); + // Save the FT IEs + pMac->ft.ftSmeContext.auth_ft_ies = vos_mem_malloc(ft_ies_length); + if ( NULL == pMac->ft.ftSmeContext.auth_ft_ies ) + { + smsLog( pMac, LOGE, FL("Memory allocation failed for " + "auth_ft_ies")); + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + pMac->ft.ftSmeContext.auth_ft_ies_length = ft_ies_length; + vos_mem_copy((tANI_U8 *)pMac->ft.ftSmeContext.auth_ft_ies, + ft_ies,ft_ies_length); + pMac->ft.ftSmeContext.FTState = eFT_AUTH_REQ_READY; + + break; + + case eFT_AUTH_COMPLETE: + // We will need to re-start preauth. If we received FT IEs in + // eFT_PRE_AUTH_DONE state, it implies there was a rekey in + // our pre-auth state. Hence this implies we need Pre-auth again. + + // OK now inform SME we have no pre-auth list. + // Delete the pre-auth node locally. Set your self back to restart pre-auth + // TBD +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, + "Pre-auth done and now receiving---> AUTH REQ <---- in state %d", + pMac->ft.ftSmeContext.FTState); + smsLog( pMac, LOGE, "Unhandled reception of FT IES in state %d", + pMac->ft.ftSmeContext.FTState); +#endif + break; + + case eFT_REASSOC_REQ_WAIT: + // We are done with pre-auth, hence now waiting for + // reassoc req. This is the new FT Roaming in place + + // At this juncture we are ready to start sending Re-Assoc Req. +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, "New Reassoc Req=%p in state %d", + ft_ies, pMac->ft.ftSmeContext.FTState); +#endif + if ((pMac->ft.ftSmeContext.reassoc_ft_ies) && + (pMac->ft.ftSmeContext.reassoc_ft_ies_length)) + { + // Free the one we received last from the supplicant + vos_mem_free(pMac->ft.ftSmeContext.reassoc_ft_ies); + pMac->ft.ftSmeContext.reassoc_ft_ies_length = 0; + } + + // Save the FT IEs + pMac->ft.ftSmeContext.reassoc_ft_ies = vos_mem_malloc(ft_ies_length); + if ( NULL == pMac->ft.ftSmeContext.reassoc_ft_ies ) + { + smsLog( pMac, LOGE, FL("Memory allocation failed for " + "reassoc_ft_ies")); + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + pMac->ft.ftSmeContext.reassoc_ft_ies_length = ft_ies_length; + vos_mem_copy((tANI_U8 *)pMac->ft.ftSmeContext.reassoc_ft_ies, ft_ies, + ft_ies_length); + + pMac->ft.ftSmeContext.FTState = eFT_SET_KEY_WAIT; +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "ft_ies_length=%d state=%d", ft_ies_length, + pMac->ft.ftSmeContext.FTState); +#endif + + break; + + default: + smsLog( pMac, LOGE, FL(" Unhandled state=%d"), + pMac->ft.ftSmeContext.FTState); + break; + } + sme_ReleaseGlobalLock( &pMac->sme ); +} + +eHalStatus sme_FTSendUpdateKeyInd(tHalHandle hHal, tCsrRoamSetKey * pFTKeyInfo) +{ + tSirFTUpdateKeyInfo *pMsg; + tANI_U16 msgLen; + eHalStatus status = eHAL_STATUS_FAILURE; + tAniEdType tmpEdType; + tSirKeyMaterial *keymaterial = NULL; + tAniEdType edType; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog(pMac, LOG1, FL("keyLength %d"), pFTKeyInfo->keyLength); +#endif + + msgLen = sizeof(tSirFTUpdateKeyInfo); + + pMsg = vos_mem_malloc(msgLen); + if ( NULL == pMsg ) + { + return eHAL_STATUS_FAILURE; + } + + vos_mem_set(pMsg, msgLen, 0); + pMsg->messageType = pal_cpu_to_be16((tANI_U16)eWNI_SME_FT_UPDATE_KEY); + pMsg->length = pal_cpu_to_be16(msgLen); + + keymaterial = &pMsg->keyMaterial; + + keymaterial->length = pFTKeyInfo->keyLength; + + edType = csrTranslateEncryptTypeToEdType( pFTKeyInfo->encType ); + tmpEdType = pal_cpu_to_be32(edType); + keymaterial->edType = tmpEdType; + + // Set the pMsg->keyMaterial.length field (this length is defined as all + // data that follows the edType field + // in the tSirKeyMaterial keyMaterial; field). + // + // !!NOTE: This keyMaterial.length contains the length of a MAX size key, + // though the keyLength can be + // shorter than this max size. Is LIM interpreting this ok ? + keymaterial->numKeys = 1; + keymaterial->key[ 0 ].keyId = pFTKeyInfo->keyId; + keymaterial->key[ 0 ].unicast = (tANI_U8)eANI_BOOLEAN_TRUE; + keymaterial->key[ 0 ].keyDirection = pFTKeyInfo->keyDirection; + + vos_mem_copy(&keymaterial->key[ 0 ].keyRsc, pFTKeyInfo->keyRsc, CSR_MAX_RSC_LEN); + keymaterial->key[ 0 ].paeRole = pFTKeyInfo->paeRole; + + keymaterial->key[ 0 ].keyLength = pFTKeyInfo->keyLength; + + if ( pFTKeyInfo->keyLength && pFTKeyInfo->Key ) + vos_mem_copy(&keymaterial->key[ 0 ].key, pFTKeyInfo->Key, pFTKeyInfo->keyLength); + + vos_mem_copy( &pMsg->bssId[ 0 ], + &pFTKeyInfo->peerMac[ 0 ], + sizeof(tCsrBssid) ); + + smsLog(pMac, LOG1, "BSSID = "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pMsg->bssId)); + + status = palSendMBMessage(pMac->hHdd, pMsg); + + return( status ); +} + +v_BOOL_t sme_GetFTPTKState(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + return pMac->ft.ftSmeContext.setFTPTKState; +} + +void sme_SetFTPTKState(tHalHandle hHal, v_BOOL_t state) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + pMac->ft.ftSmeContext.setFTPTKState = state; +} + +eHalStatus sme_FTUpdateKey( tHalHandle hHal, tCsrRoamSetKey * pFTKeyInfo ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) + { + return eHAL_STATUS_FAILURE; + } + + if (pFTKeyInfo == NULL) + { + smsLog( pMac, LOGE, "%s: pFTKeyInfo is NULL", __func__); + sme_ReleaseGlobalLock( &pMac->sme ); + return eHAL_STATUS_FAILURE; + } + +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "sme_FTUpdateKey is received in state %d", + pMac->ft.ftSmeContext.FTState); +#endif + + // Global Station FT State + switch(pMac->ft.ftSmeContext.FTState) + { + case eFT_SET_KEY_WAIT: + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + //store the PTK send event + vos_record_roam_event(e_HDD_SET_PTK_REQ, NULL, 0); + } + if (sme_GetFTPreAuthState (hHal) == TRUE) + { + status = sme_FTSendUpdateKeyInd(pMac, pFTKeyInfo); + if (status != 0 ) + { + smsLog( pMac, LOGE, "%s: Key set failure %d", __func__, + status); + pMac->ft.ftSmeContext.setFTPTKState = FALSE; + status = eHAL_STATUS_FT_PREAUTH_KEY_FAILED; + } + else + { + pMac->ft.ftSmeContext.setFTPTKState = TRUE; + status = eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS; + smsLog( pMac, LOG1, "%s: Key set success", __func__); + } + sme_SetFTPreAuthState(hHal, FALSE); + } + pMac->ft.ftSmeContext.FTState = eFT_START_READY; +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOG1, "%s: state changed to %d status %d", __func__, + pMac->ft.ftSmeContext.FTState, status); +#endif + break; + + default: + smsLog(pMac, LOG1, FL("Unhandled state=%d"), + pMac->ft.ftSmeContext.FTState); + status = eHAL_STATUS_FAILURE; + break; + } + sme_ReleaseGlobalLock( &pMac->sme ); + + return status; +} +/*-------------------------------------------------------------------------- + * + * HDD Interface to SME. SME now sends the Auth 2 and RIC IEs up to the supplicant. + * The supplicant will then proceed to send down the + * Reassoc Req. + * + *------------------------------------------------------------------------*/ +void sme_GetFTPreAuthResponse( tHalHandle hHal, tANI_U8 *ft_ies, + tANI_U32 ft_ies_ip_len, tANI_U16 *ft_ies_length ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + *ft_ies_length = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) + return; + + /* All or nothing - proceed only if both BSSID and FT IE fit */ + if((ANI_MAC_ADDR_SIZE + + pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ft_ies_length) > ft_ies_ip_len) + { + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + + // hdd needs to pack the bssid also along with the + // auth response to supplicant + vos_mem_copy(ft_ies, pMac->ft.ftSmeContext.preAuthbssId, ANI_MAC_ADDR_SIZE); + + // Copy the auth resp FTIEs + vos_mem_copy(&(ft_ies[ANI_MAC_ADDR_SIZE]), + pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ft_ies, + pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ft_ies_length); + + *ft_ies_length = ANI_MAC_ADDR_SIZE + + pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ft_ies_length; + + pMac->ft.ftSmeContext.FTState = eFT_REASSOC_REQ_WAIT; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, FL(" Filled auth resp = %d"), *ft_ies_length); +#endif + sme_ReleaseGlobalLock( &pMac->sme ); + return; +} + +/*-------------------------------------------------------------------------- + * + * SME now sends the RIC IEs up to the supplicant. + * The supplicant will then proceed to send down the + * Reassoc Req. + * + *------------------------------------------------------------------------*/ +void sme_GetRICIEs( tHalHandle hHal, tANI_U8 *ric_ies, tANI_U32 ric_ies_ip_len, + tANI_U32 *ric_ies_length ) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + eHalStatus status = eHAL_STATUS_FAILURE; + + *ric_ies_length = 0; + + status = sme_AcquireGlobalLock( &pMac->sme ); + if (!( HAL_STATUS_SUCCESS( status ))) + return; + + /* All or nothing */ + if (pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length > + ric_ies_ip_len) + { + sme_ReleaseGlobalLock( &pMac->sme ); + return; + } + + vos_mem_copy(ric_ies, pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies, + pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length); + + *ric_ies_length = pMac->ft.ftSmeContext.psavedFTPreAuthRsp->ric_ies_length; + +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, FL(" Filled ric ies = %d"), *ric_ies_length); +#endif + + sme_ReleaseGlobalLock( &pMac->sme ); + return; +} + +/*-------------------------------------------------------------------------- + * + * Timer callback for the timer that is started between the preauth completion and + * reassoc request to the PE. In this interval, it is expected that the pre-auth response + * and RIC IEs are passed up to the WPA supplicant and received back the necessary FTIEs + * required to be sent in the reassoc request + * + *------------------------------------------------------------------------*/ +void sme_PreauthReassocIntvlTimerCallback(void *context) +{ +#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING + tpAniSirGlobal pMac = (tpAniSirGlobal )context; + csrNeighborRoamRequestHandoff(pMac); +#endif + if (pMac->roam.configParam.roamDelayStatsEnabled) + { + vos_record_roam_event(e_SME_PREAUTH_CALLBACK_HIT, NULL, 0); + } + return; +} + +/*-------------------------------------------------------------------------- + Reset the FT context. + ------------------------------------------------------------------------*/ +void sme_FTReset(tHalHandle hHal) +{ + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + if (pMac == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("pMac is NULL")); + return; + } + if (pMac->ft.ftSmeContext.auth_ft_ies != NULL) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, FL(" Freeing FT Auth IE %p and setting to NULL"), + pMac->ft.ftSmeContext.auth_ft_ies); +#endif + vos_mem_free(pMac->ft.ftSmeContext.auth_ft_ies); + } + pMac->ft.ftSmeContext.auth_ft_ies = NULL; + pMac->ft.ftSmeContext.auth_ft_ies_length = 0; + + if (pMac->ft.ftSmeContext.reassoc_ft_ies != NULL) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, FL(" Freeing FT Reassoc IE %p and setting to NULL"), + pMac->ft.ftSmeContext.auth_ft_ies); +#endif + vos_mem_free(pMac->ft.ftSmeContext.reassoc_ft_ies); + } + pMac->ft.ftSmeContext.reassoc_ft_ies = NULL; + pMac->ft.ftSmeContext.reassoc_ft_ies_length = 0; + + if (pMac->ft.ftSmeContext.psavedFTPreAuthRsp != NULL) + { +#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG + smsLog( pMac, LOGE, FL("Freeing FtPreAuthRsp %p and setting to NULL"), + pMac->ft.ftSmeContext.psavedFTPreAuthRsp); +#endif + vos_mem_free(pMac->ft.ftSmeContext.psavedFTPreAuthRsp); + } + pMac->ft.ftSmeContext.psavedFTPreAuthRsp = NULL; + pMac->ft.ftSmeContext.setFTPreAuthState = FALSE; + pMac->ft.ftSmeContext.setFTPTKState = FALSE; + + if (pMac->ft.ftSmeContext.pCsrFTKeyInfo != NULL) + { + vos_mem_zero(pMac->ft.ftSmeContext.pCsrFTKeyInfo, + sizeof(tCsrRoamSetKey)); + vos_mem_free(pMac->ft.ftSmeContext.pCsrFTKeyInfo); + } + pMac->ft.ftSmeContext.pCsrFTKeyInfo = NULL; + vos_mem_zero(pMac->ft.ftSmeContext.preAuthbssId, ANI_MAC_ADDR_SIZE); + pMac->ft.ftSmeContext.FTState = eFT_START_READY; +} +/* End of File */ +#endif /* WLAN_FEATURE_VOWIFI_11R */ diff --git a/drivers/staging/prima/CORE/SME/src/sme_common/sme_Trace.c b/drivers/staging/prima/CORE/SME/src/sme_common/sme_Trace.c new file mode 100644 index 000000000000..ab2f2bf78b55 --- /dev/null +++ b/drivers/staging/prima/CORE/SME/src/sme_common/sme_Trace.c @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2013-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/************************************************************************ + smeTrace.c + + \brief implementation for trace related APIs + + \author Kiran Kumar Reddy CH L V + + ========================================================================*/ +#include "aniGlobal.h" //for tpAniSirGlobal +#include "smsDebug.h" +#include "macTrace.h" +#include "sme_Trace.h" +#include "smeInternal.h" +#include "smeInside.h" + +#ifndef SME_TRACE_RECORD +void smeTraceInit(tpAniSirGlobal pMac) +{ + return; +} +#endif +#ifdef SME_TRACE_RECORD + + +static tANI_U8* smeTraceGetRxMsgString( tANI_U32 code ) +{ + switch(code) + { + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_CONNECT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_REASSOC); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_BMPS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ENTER_WOWL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXIT_WOWL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_KEY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMOVE_KEY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_STATS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_READREG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_WRITEREG); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_READMEM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_OPEN_SESSION); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CLOSE_SESSION); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SEND_ACTION); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_TXPOW); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_TMLEVEL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_CAPS_EXCH); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_DISABLE_CAP); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_DEFCCNV); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_CURCC); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_RESET_PW5G); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_RP5G); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_SET_SCANCTRL); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA); +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA); +#endif + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_PREF_NET_LIST); +#ifdef FEATURE_WLAN_LPHB + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ); +#endif /* FEATURE_WLAN_LPHB */ + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXTSCAN_START); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXTSCAN_STOP); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_BSS_HOTLIST); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_BSS_HOTLIST); + CASE_RETURN_STRING(TRACE_CODE_SME_RX_HDD_EXTSCAN_GET_CACHED_RESULTS); + default: + return( "UNKNOWN" ); + break; + } +} +static tANI_U8* smeTraceGetCommandString( tANI_U32 command ) +{ + switch(command) + { + CASE_RETURN_STRING(eSmeNoCommand); + CASE_RETURN_STRING(eSmeDropCommand); + CASE_RETURN_STRING(eSmeCsrCommandMask); + CASE_RETURN_STRING(eSmeCommandScan); + CASE_RETURN_STRING(eSmeCommandRoam); + CASE_RETURN_STRING(eSmeCommandWmStatusChange); + CASE_RETURN_STRING(eSmeCommandSetKey); + CASE_RETURN_STRING(eSmeCommandRemoveKey); + CASE_RETURN_STRING(eSmeCommandAddStaSession); + CASE_RETURN_STRING(eSmeCommandDelStaSession); + CASE_RETURN_STRING(eSmeCommandPnoReq); + CASE_RETURN_STRING(eSmeCommandMacSpoofRequest); + CASE_RETURN_STRING(eSmeCommandGetFrameLogRequest); +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING(eSmeCommandTdlsSendMgmt); + CASE_RETURN_STRING(eSmeCommandTdlsAddPeer); + CASE_RETURN_STRING(eSmeCommandTdlsDelPeer); + CASE_RETURN_STRING(eSmeCommandTdlsLinkEstablish); + CASE_RETURN_STRING(eSmeCommandTdlsChannelSwitch); +#endif + CASE_RETURN_STRING(eSmeCommandNanReq); + CASE_RETURN_STRING(eSmePmcCommandMask); + CASE_RETURN_STRING(eSmeCommandEnterImps); + CASE_RETURN_STRING(eSmeCommandExitImps); + CASE_RETURN_STRING(eSmeCommandEnterBmps); + CASE_RETURN_STRING(eSmeCommandExitBmps); + CASE_RETURN_STRING(eSmeCommandEnterUapsd); + CASE_RETURN_STRING(eSmeCommandExitUapsd); + CASE_RETURN_STRING(eSmeCommandEnterWowl); + CASE_RETURN_STRING(eSmeCommandExitWowl); + CASE_RETURN_STRING(eSmeCommandEnterStandby); + CASE_RETURN_STRING(eSmeQosCommandMask); + CASE_RETURN_STRING(eSmeCommandAddTs); + CASE_RETURN_STRING(eSmeCommandDelTs); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(eSmeCommandOemDataReq); +#endif + CASE_RETURN_STRING(eSmeCommandRemainOnChannel); + CASE_RETURN_STRING(eSmeCommandNoAUpdate); + default: + return( "UNKNOWN" ); + break; + } +} +static void smeTraceDump(tpAniSirGlobal pMac, tpvosTraceRecord pRecord, + tANI_U16 recIndex) +{ + switch (pRecord->code) { + case TRACE_CODE_SME_COMMAND: + smsLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, "SME COMMAND:", + smeTraceGetCommandString(pRecord->data), pRecord->data); + break; + case TRACE_CODE_SME_TX_WDA_MSG: + smsLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, "TX WDA Msg:", + macTraceGetWdaMsgString((tANI_U16)pRecord->data), + pRecord->data); + break; + case TRACE_CODE_SME_RX_WDA_MSG: + smsLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, "RX WDA Msg:", + macTraceGetSmeMsgString((tANI_U16)pRecord->data), + pRecord->data); + break; + default: + smsLog(pMac, LOG1, "%04d %012u S%d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, "RX HDD MSG:", + smeTraceGetRxMsgString(pRecord->code), pRecord->data); + break; + } +} + +void smeTraceInit(tpAniSirGlobal pMac) +{ + vosTraceRegister(VOS_MODULE_ID_SME, (tpvosTraceCb)&smeTraceDump); +} + +/** + * sme_state_info_dump() - prints state information of sme layer + */ +static void sme_state_info_dump(void) +{ + tANI_U32 session_id = 0; + tHalHandle hal; + tpAniSirGlobal mac; + v_CONTEXT_t vos_ctx_ptr; + + /* get the global voss context */ + vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + + if (NULL == vos_ctx_ptr) { + VOS_ASSERT(0); + return; + } + + hal = vos_get_context(VOS_MODULE_ID_SME, vos_ctx_ptr); + if (NULL == hal) { + VOS_ASSERT(0); + return; + } + + mac = PMAC_STRUCT(hal); + + session_id = sme_get_sessionid_from_activeList(mac); + smsLog( mac, LOG1, FL(" SessionId %d for active command"), session_id); + + smsLog(mac, LOG1, FL("NeighborRoamState: %d RoamState: %d" + "RoamSubState: %d ConnectState: %d pmcState: %d PmmState: %d"), + mac->roam.neighborRoamInfo.neighborRoamState, + mac->roam.curState[session_id], mac->roam.curSubState[session_id], + mac->roam.roamSession[session_id].connectState, mac->pmc.pmcState, + mac->pmm.gPmmState); +} + +/** + * sme_register_debug_callback() - registration function sme layer + * to print sme state information + */ +void sme_register_debug_callback() +{ + vos_register_debug_callback(VOS_MODULE_ID_SME, &sme_state_info_dump); +} +#endif diff --git a/drivers/staging/prima/CORE/SVC/external/wlan_nlink_common.h b/drivers/staging/prima/CORE/SVC/external/wlan_nlink_common.h new file mode 100644 index 000000000000..6ffcee65573d --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/external/wlan_nlink_common.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + \file wlan_nlink_common.h + + Exports and types for the Netlink Service interface. This header file contains + message types and definitions that is shared between the user space service + (e.g. BTC service) and WLAN kernel module. + + +===========================================================================*/ + +#ifndef WLAN_NLINK_COMMON_H__ +#define WLAN_NLINK_COMMON_H__ + +#include +#include +/*--------------------------------------------------------------------------- + * External Functions + *-------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + *-------------------------------------------------------------------------*/ +#define WLAN_NL_MAX_PAYLOAD 256 /* maximum size for netlink message*/ +#define WLAN_NLINK_PROTO_FAMILY NETLINK_USERSOCK +#define WLAN_NLINK_MCAST_GRP_ID 0x01 + +/*--------------------------------------------------------------------------- + * Type Declarations + *-------------------------------------------------------------------------*/ + +/* + * The following enum defines the target service within WLAN driver for which the + * message is intended for. Each service along with its counterpart + * in the user space, define a set of messages they recognize. + * Each of this message will have an header of type tAniMsgHdr defined below. + * Each Netlink message to/from a kernel module will contain only one + * message which is preceded by a tAniMsgHdr. The maximun size (in bytes) of + * a netlink message is assumed to be MAX_PAYLOAD bytes. + * + * +------------+-------+----------+----------+ + * |Netlink hdr | Align |tAniMsgHdr| msg body | + * +------------+-------+----------|----------+ + */ + +// Message Types +#define WLAN_BTC_QUERY_STATE_REQ 0x01 // BTC --> WLAN +#define WLAN_BTC_BT_EVENT_IND 0x02 // BTC --> WLAN +#define WLAN_BTC_QUERY_STATE_RSP 0x03 // WLAN --> BTC +#define WLAN_MODULE_UP_IND 0x04 // WLAN --> BTC +#define WLAN_MODULE_DOWN_IND 0x05 // WLAN --> BTC +#define WLAN_STA_ASSOC_DONE_IND 0x06 // WLAN --> BTC +#define WLAN_STA_DISASSOC_DONE_IND 0x07 // WLAN --> BTC + +// Special Message Type used by AMP, intercepted by send_btc_nlink_msg() and +// replaced by WLAN_STA_ASSOC_DONE_IND or WLAN_STA_DISASSOC_DONE_IND +#define WLAN_AMP_ASSOC_DONE_IND 0x10 + +// Special Message Type used by SoftAP, intercepted by send_btc_nlink_msg() and +// replaced by WLAN_STA_ASSOC_DONE_IND +#define WLAN_BTC_SOFTAP_BSS_START 0x11 +#define WLAN_MSG_RPS_ENABLE_IND 0x10A +#define WLAN_SVC_IFACE_NUM_QUEUES 6 + +#define WLAN_SVC_SAP_RESTART_IND 0x108 +#define WLAN_SVC_WLAN_TP_IND 0x109 +// Event data for WLAN_BTC_QUERY_STATE_RSP & WLAN_STA_ASSOC_DONE_IND +typedef struct +{ + unsigned char channel; // 0 implies STA not associated to AP +} tWlanAssocData; + +#define ANI_NL_MSG_BASE 0x10 /* Some arbitrary base */ + +typedef enum eAniNlModuleTypes { + ANI_NL_MSG_PUMAC = ANI_NL_MSG_BASE + 0x01,// PTT Socket App + ANI_NL_MSG_PTT = ANI_NL_MSG_BASE + 0x07,// Quarky GUI + WLAN_NL_MSG_BTC, + WLAN_NL_MSG_OEM, + WLAN_NL_MSG_SVC = ANI_NL_MSG_BASE + 0x0A, + ANI_NL_MSG_LOG = ANI_NL_MSG_BASE + 0x0C, + ANI_NL_MSG_MAX +} tAniNlModTypes, tWlanNlModTypes; + +#define WLAN_NL_MSG_BASE ANI_NL_MSG_BASE +#define WLAN_NL_MSG_MAX ANI_NL_MSG_MAX + +struct wlan_rps_data { + char ifname[IFNAMSIZ]; + uint16_t num_queues; + uint16_t cpu_map[WLAN_SVC_IFACE_NUM_QUEUES]; +}; + +//All Netlink messages must contain this header +typedef struct sAniHdr { + unsigned short type; + unsigned short length; +} tAniHdr, tAniMsgHdr; + +#endif //WLAN_NLINK_COMMON_H__ diff --git a/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h b/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h new file mode 100644 index 000000000000..a1f27be514ae --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/inc/wlan_btc_svc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_btc_svc.h + * + ******************************************************************************/ + +#ifndef WLAN_BTC_SVC_H +#define WLAN_BTC_SVC_H + +void send_btc_nlink_msg (int type, int dest_pid); +int btc_activate_service(void *pAdapter); +void btc_deactivate_service(void); + +#endif diff --git a/drivers/staging/prima/CORE/SVC/inc/wlan_logging_sock_svc.h b/drivers/staging/prima/CORE/SVC/inc/wlan_logging_sock_svc.h new file mode 100644 index 000000000000..4ddd24b1f57c --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/inc/wlan_logging_sock_svc.h @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. +* +* Previously licensed under the ISC license by Qualcomm Atheros, Inc. +* +* +* Permission to use, copy, modify, and/or distribute this software for +* any purpose with or without fee is hereby granted, provided that the +* above copyright notice and this permission notice appear in all +* copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +*/ + +/* +* This file was originally distributed by Qualcomm Atheros, Inc. +* under proprietary terms before Copyright ownership was assigned +* to the Linux Foundation. +*/ + +/****************************************************************************** + * wlan_logging_sock_svc.h + * + ******************************************************************************/ + +#ifndef WLAN_LOGGING_SOCK_SVC_H +#define WLAN_LOGGING_SOCK_SVC_H + +#include +#include +#include +#include +#include + + +int wlan_logging_sock_init_svc(void); +int wlan_logging_sock_deinit_svc(void); +int wlan_logging_flush_pkt_queue(void); +int wlan_logging_sock_deactivate_svc(void); +int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length); +int wlan_queue_logpkt_for_app(vos_pkt_t *pPacket, uint32 pkt_type); +void wlan_process_done_indication(uint8 type, uint32 reason_code); +int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf, + int pkt_stats_enabled, int pkt_stats_buff); +void wlan_flush_host_logs_for_fatal(void); + +void wlan_init_log_completion(void); +int wlan_set_log_completion(uint32 is_fatal, + uint32 indicator, + uint32 reason_code); +void wlan_get_log_and_reset_completion(uint32 *is_fatal, + uint32 *indicator, + uint32 *reason_code, + bool reset); +bool wlan_is_log_report_in_progress(void); +void wlan_reset_log_report_in_progress(void); + +void wlan_deinit_log_completion(void); + +void wlan_logging_set_log_level(void); + +#define FW_MEM_DUMP_MAGIC 0x3C3A2D44 + +enum FW_MEM_DUMP_STATE{ + FW_MEM_DUMP_IDLE, + FW_MEM_DUMP_READ_IN_PROGRESS, + FW_MEM_DUMP_WRITE_IN_PROGRESS, + FW_MEM_DUMP_WRITE_DONE, +}; +int wlan_fwr_mem_dump_buffer_allocation(void); +bool wlan_fwr_mem_dump_test_and_set_write_allowed_bit(void); +bool wlan_fwr_mem_dump_test_and_set_read_allowed_bit(void); +void wlan_set_fwr_mem_dump_state(enum FW_MEM_DUMP_STATE fw_mem_dump_state); +void wlan_set_svc_fw_mem_dump_req_cb(void*,void*); +size_t wlan_fwr_mem_dump_fsread_handler(char __user *buf, size_t count, loff_t *pos,loff_t* bytes_left); +void wlan_indicate_mem_dump_complete(bool ); +void wlan_store_fwr_mem_dump_size(uint32 dump_size); +void wlan_free_fwr_mem_dump_buffer(void); + +bool wlan_is_logger_thread(int threadId); +int wlan_pkt_stats_to_user(void *perPktStat); +void wlan_disable_and_flush_pkt_stats(void); + void wlan_fillTxStruct(void *pktStat); + bool wlan_isPktStatsEnabled(void); +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void wlan_report_log_completion(uint32 is_fatal, + uint32 indicator, + uint32 reason_code); +#else +static inline void wlan_report_log_completion(uint32 is_fatal, + uint32 indicator, + uint32 reason_code) +{ + return; +} + +#endif + + +#endif /* WLAN_LOGGING_SOCK_SVC_H */ diff --git a/drivers/staging/prima/CORE/SVC/inc/wlan_nlink_srv.h b/drivers/staging/prima/CORE/SVC/inc/wlan_nlink_srv.h new file mode 100644 index 000000000000..369332d12075 --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/inc/wlan_nlink_srv.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_nlink_srv.h + * + * wlan_nlink_srv is used to RX/TX Netlink messages from user space to kernel + * modules and vice versa. Kernel modules must register a message handler for a + * message type so that the wlan_nlink_srv can invoke the corresponding msg handler + * whenever a Netlink message of a particular type has been received from an + * application. In the opposite direction, wlan_nlink_srv provides a mechanism + * which kernel modules can use to send Netlink messages to applications. + * + ******************************************************************************/ + +#ifndef WLAN_NLINK_SRV_H +#define WLAN_NLINK_SRV_H + +#include +#include +#include + +#define NLINK_MAX_CALLBACKS (WLAN_NL_MSG_MAX - WLAN_NL_MSG_BASE) + +typedef int (* nl_srv_msg_callback)(struct sk_buff * skb); + +int nl_srv_init(void); +#ifdef WLAN_KD_READY_NOTIFIER +void nl_srv_exit(int dst_pid); +#else +void nl_srv_exit(void); +#endif /* WLAN_KD_READY_NOTIFIER */ +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler); +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler); +int nl_srv_ucast(struct sk_buff * skb, int dst_pid, int flag); +int nl_srv_bcast(struct sk_buff * skb); +#ifdef WLAN_KD_READY_NOTIFIER +void nl_srv_nl_ready_indication(void); +void nl_srv_nl_close_indication(int pid); +#endif /* WLAN_KD_READY_NOTIFIER */ +int nl_srv_is_initialized(void); +#endif diff --git a/drivers/staging/prima/CORE/SVC/inc/wlan_ptt_sock_svc.h b/drivers/staging/prima/CORE/SVC/inc/wlan_ptt_sock_svc.h new file mode 100644 index 000000000000..2f2bac6e601f --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/inc/wlan_ptt_sock_svc.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_ptt_sock_svc.c + * + ******************************************************************************/ +#ifndef PTT_SOCK_SVC_H +#define PTT_SOCK_SVC_H +#include +#include +#include +#include +#include +#include +/* + * Quarky Message Format: + * The following is the messaging protocol between Quarky and PTT Socket App. + * The totalMsgLen is the length from Radio till msgBody. The value of Radio + * is always defaulted to 0. The MsgLen is the length from msgId till msgBody. + * The length of the msgBody varies with respect to the MsgId. Buffer space + * for MsgBody is already allocated in the received buffer. So in case of READ + * we just need to populate the values in the received message and send it + * back + * +------------+-------+-------+--------+-------+---------+ + * |TotalMsgLen | Radio | MsgId | MsgLen |Status |MsgBody | + * +------------+-------+-------|--------+-------+---------+ + * <------4----><--4---><---2--><---2---><---4--><---------> + */ +// PTT Socket App Message Ids +#define PTT_MSG_READ_REGISTER 0x3040 +#define PTT_MSG_WRITE_REGISTER 0x3041 +#define PTT_MSG_READ_MEMORY 0x3044 +#define PTT_MSG_WRITE_MEMORY 0x3045 +#define PTT_MSG_LOG_DUMP_DBG 0x32A1 +#define PTT_MSG_FTM_CMDS_TYPE 0x4040 +#define ANI_DRIVER_MSG_START 0x0001 +#define ANI_MSG_APP_REG_REQ (ANI_DRIVER_MSG_START + 0) +#define ANI_MSG_APP_REG_RSP (ANI_DRIVER_MSG_START + 1) +#define ANI_MSG_OEM_DATA_REQ (ANI_DRIVER_MSG_START + 2) +#define ANI_MSG_OEM_DATA_RSP (ANI_DRIVER_MSG_START + 3) +#define ANI_MSG_CHANNEL_INFO_REQ (ANI_DRIVER_MSG_START + 4) +#define ANI_MSG_CHANNEL_INFO_RSP (ANI_DRIVER_MSG_START + 5) +#define ANI_MSG_OEM_ERROR (ANI_DRIVER_MSG_START + 6) + +#define ANI_MAX_RADIOS 3 +#define ANI_NL_MSG_OK 0 +#define ANI_NL_MSG_ERROR -1 +#define INVALID_PID -1 + +#define ANI_NL_MSG_OVERHEAD (NLMSG_SPACE(tAniHdr + 4)) +/* + * Packet Format for READ_REGISTER & WRITE_REGISTER: + * TotalMsgLen : 4 bytes [value=20 bytes] + * Radio : 4 bytes + * MsgId : 2 bytes + * MsgLen : 2 bytes + * Status : 4 bytes + * Address : 4 bytes + * Payload : 4 bytes +*/ +/* + * Packet Format for READ_MEMORY & WRITE_MEMORY : + * TotalMsgLen : 4 bytes [value= 20+LEN_PAYLOAD bytes] + * Radio : 4 bytes + * MsgId : 2 bytes + * MsgLen : 2 bytes + * Status : 4 bytes + * Address : 4 bytes + * Length : 4 bytes [LEN_PAYLOAD] + * Payload : LEN_PAYLOAD bytes +*/ +int ptt_sock_activate_svc(void *pAdapter); +int ptt_sock_deactivate_svc(hdd_context_t *pHddCtx); +int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid, int flag); + +/* + * Format of message exchanged between the PTT Socket App in userspace and the + * WLAN Driver, in either direction. Each msg will begin with this header and + * will followed by the Quarky message + */ +typedef struct sAniNlMsg { + struct nlmsghdr nlh; // Netlink Header + int radio; // unit number of the radio + tAniHdr wmsg; // Airgo Message Header +} tAniNlHdr; +typedef struct sAniNlMgmtLogMsg { + struct nlmsghdr nlh; + int radio; + tAniHdr wmsg; + uint32 frameSize; +} tAniNlLogHdr; +typedef struct sAniAppRegReq { + tAniNlModTypes type; // module id + int pid; // process id +} tAniNlAppRegReq; +typedef struct sAniNlAppRegRsp { + struct nlmsghdr nlh; // NetLink Msg Header + int radio; // Radio unit + tAniHdr wniHdr; // Generic WNI msg header + tAniNlAppRegReq regReq; // The original request msg + int ret; // Return code +} tAniNlAppRegRsp; +#endif diff --git a/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c b/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c new file mode 100644 index 000000000000..f64605d81f21 --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/src/btc/wlan_btc_svc.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_btc_svc.c + * + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +// Global variables +static struct hdd_context_s *pHddCtx; + +static int gWiFiChannel; /* WiFi associated channel 1-13, or 0 (none) */ +static int gAmpChannel; /* AMP associated channel 1-13, or 0 (none) */ +static int gBtcDriverMode = WLAN_HDD_INFRA_STATION; /* Driver mode in BTC */ + + +// Forward declrarion +static int btc_msg_callback (struct sk_buff * skb); +/* + * Send a netlink message to the user space. + * Destination pid as zero implies broadcast + */ +void send_btc_nlink_msg (int type, int dest_pid) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + tAniMsgHdr *aniHdr; + tWlanAssocData *assocData; + skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), GFP_KERNEL); + if(skb == NULL) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: alloc_skb failed\n"); + return; + } + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_type = WLAN_NL_MSG_BTC; + aniHdr = NLMSG_DATA(nlh); + aniHdr->type = type; + + /* Set BTC driver mode correctly based on received events type */ + if(type == WLAN_BTC_SOFTAP_BSS_START) + { + /* Event is SoftAP BSS Start set BTC driver mode to SoftAP */ + gBtcDriverMode = WLAN_HDD_SOFTAP; + } + if(type == WLAN_STA_ASSOC_DONE_IND) + { + /* Event is STA Assoc done set BTC driver mode to INFRA STA*/ + gBtcDriverMode = WLAN_HDD_INFRA_STATION; + } + + switch( type ) + { + case WLAN_STA_DISASSOC_DONE_IND: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "WiFi unassociated; gAmpChannel %d gWiFiChannel %d", gAmpChannel, gWiFiChannel); + + /* If AMP is using a channel (non-zero), no message sent. + Or, if WiFi wasn't using a channel before, no message sent. + Logic presumes same channel has to be used for WiFi and AMP if both are active. + In any case, track the WiFi channel in use (none) */ + if((gAmpChannel != 0) || (gWiFiChannel == 0)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "No msg for AFH will be sent"); + gWiFiChannel = 0; + kfree_skb(skb); + return; + } + gWiFiChannel = 0; + + /* No Break: Fall into next cases */ + + case WLAN_MODULE_UP_IND: + case WLAN_MODULE_DOWN_IND: + aniHdr->length = 0; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + break; + case WLAN_BTC_SOFTAP_BSS_START: + case WLAN_BTC_QUERY_STATE_RSP: + case WLAN_STA_ASSOC_DONE_IND: + aniHdr->length = sizeof(tWlanAssocData); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + sizeof(tWlanAssocData))); + assocData = ( tWlanAssocData *)((char*)aniHdr + sizeof(tAniMsgHdr)); + + assocData->channel = hdd_get_operating_channel( pHddCtx, gBtcDriverMode ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "New WiFi channel %d gAmpChannel %d gWiFiChannel %d", + assocData->channel, gAmpChannel, gWiFiChannel); + + /* If WiFi has finished associating */ + if(type == WLAN_STA_ASSOC_DONE_IND) + { + /* If AMP is using a channel (non-zero), no message sent. + Or, if the WiFi channel did not change, no message sent. + Logic presumes same channel has to be used for WiFi and AMP if both are active. + In any case, track the WiFi channel in use (1-13 or none, in assocData->channel) */ + if((gAmpChannel != 0) || (assocData->channel == gWiFiChannel)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "No msg for AFH will be sent"); + gWiFiChannel = assocData->channel; + kfree_skb(skb); + return; + } + } + if(type == WLAN_BTC_SOFTAP_BSS_START) + { + /*Replace WLAN_BTC_SOFTAP_BSS_START by WLAN_STA_ASSOC_DONE_IND*/ + aniHdr->type = WLAN_STA_ASSOC_DONE_IND; + } + gWiFiChannel = assocData->channel; + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr)+ sizeof(tWlanAssocData)))); + break; + + case WLAN_AMP_ASSOC_DONE_IND: + + /* This is an overloaded type. It means that AMP is connected (dest_pid is channel 1-13), + or it means AMP is now disconnected (dest_pid is 0) */ + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "New AMP channel %d gAmpChannel %d gWiFiChannel %d", dest_pid, gAmpChannel, gWiFiChannel); + /* If WiFi is using a channel (non-zero), no message sent. + Or, if the AMP channel did not change, no message sent. + Logic presumes same channel has to be used for WiFi and AMP if both are active. + In any case, track the AMP channel in use (1-13 or none, in dest_pid) */ + if((gWiFiChannel != 0) || (dest_pid == gAmpChannel)) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "No msg for AFH will be sent"); + gAmpChannel = dest_pid; + kfree_skb(skb); + return; + } + + gAmpChannel = dest_pid; + + /* Fix overloaded parameters and finish message formatting */ + if(dest_pid != 0) + { + aniHdr->type = WLAN_STA_ASSOC_DONE_IND; + aniHdr->length = sizeof(tWlanAssocData); + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + sizeof(tWlanAssocData))); + assocData = ( tWlanAssocData *)((char*)aniHdr + sizeof(tAniMsgHdr)); + assocData->channel = dest_pid; + skb_put(skb, NLMSG_SPACE((sizeof(tAniMsgHdr)+ sizeof(tWlanAssocData)))); + } + else + { + aniHdr->type = WLAN_STA_DISASSOC_DONE_IND; + aniHdr->length = 0; + nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr))); + skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr))); + } + dest_pid = 0; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: Attempt to send unknown nlink message %d\n", type); + kfree_skb(skb); + return; + } + if(dest_pid == 0) + (void)nl_srv_bcast(skb); + else + (void)nl_srv_ucast(skb, dest_pid, MSG_DONTWAIT); +} +/* + * Activate BTC handler. This will register a handler to receive + * netlink messages addressed to WLAN_NL_MSG_BTC from user space + */ +int btc_activate_service(void *pAdapter) +{ + pHddCtx = (struct hdd_context_s*)pAdapter; + + //Register the msg handler for msgs addressed to ANI_NL_MSG_BTC + nl_srv_register(WLAN_NL_MSG_BTC, btc_msg_callback); + return 0; +} + +/**--------------------------------------------------------------------------- + + \brief btc_deactivate_service() - Deactivate btc message handler + + This function unregisters a handler to receive netlink messages + addressed to WLAN_NL_MSG_BTC from user space. + + \return - none + --------------------------------------------------------------------------*/ +void btc_deactivate_service() +{ + //unregister the msg handler for msgs addressed to ANI_NL_MSG_BTC + nl_srv_unregister(WLAN_NL_MSG_BTC, btc_msg_callback); +} +/* + * Callback function invoked by Netlink service for all netlink + * messages (from user space) addressed to WLAN_NL_MSG_BTC + */ +int btc_msg_callback (struct sk_buff * skb) +{ + struct nlmsghdr *nlh; + tAniMsgHdr *msg_hdr; + tSmeBtEvent *btEvent = NULL; + nlh = (struct nlmsghdr *)skb->data; + msg_hdr = NLMSG_DATA(nlh); + + /* Continue with parsing payload. */ + switch(msg_hdr->type) + { + case WLAN_BTC_QUERY_STATE_REQ: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "BTC: Received probe from BTC Service\n"); + send_btc_nlink_msg(WLAN_BTC_QUERY_STATE_RSP, nlh->nlmsg_pid); + break; + case WLAN_BTC_BT_EVENT_IND: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "BTC: Received Bluetooth event indication\n"); + if(msg_hdr->length != sizeof(tSmeBtEvent)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: Size mismatch in BT event data\n"); + break; + } + btEvent = (tSmeBtEvent*)((char*)msg_hdr + sizeof(tAniMsgHdr)); + (void)sme_BtcSignalBtEvent(pHddCtx->hHal, btEvent); + break; + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "BTC: Received Invalid Msg type [%d]\n", msg_hdr->type); + break; + } + return 0; +} diff --git a/drivers/staging/prima/CORE/SVC/src/logging/wlan_logging_sock_svc.c b/drivers/staging/prima/CORE/SVC/src/logging/wlan_logging_sock_svc.c new file mode 100644 index 000000000000..64a252b8a954 --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/src/logging/wlan_logging_sock_svc.c @@ -0,0 +1,2178 @@ +/* +* Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. +* +* Previously licensed under the ISC license by Qualcomm Atheros, Inc. +* +* +* Permission to use, copy, modify, and/or distribute this software for +* any purpose with or without fee is hereby granted, provided that the +* above copyright notice and this permission notice appear in all +* copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +* PERFORMANCE OF THIS SOFTWARE. +*/ + +/* +* This file was originally distributed by Qualcomm Atheros, Inc. +* under proprietary terms before Copyright ownership was assigned +* to the Linux Foundation. +*/ + +/****************************************************************************** + * wlan_logging_sock_svc.c + * + ******************************************************************************/ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vos_memory.h" +#include +#include +#include + + +#define LOGGING_TRACE(level, args...) \ + VOS_TRACE(VOS_MODULE_ID_SVC, level, ## args) + +/* Global variables */ + +#define ANI_NL_MSG_LOG_TYPE 89 +#define ANI_NL_MSG_READY_IND_TYPE 90 +#define ANI_NL_MSG_LOG_PKT_TYPE 91 +#define ANI_NL_MSG_FW_LOG_PKT_TYPE 92 +#define INVALID_PID -1 + +#define MAX_PKTSTATS_LOG_LENGTH 2048 +#define MAX_LOGMSG_LENGTH 4096 +#define LOGGER_MGMT_DATA_PKT_POST 0x001 +#define HOST_LOG_POST 0x002 +#define LOGGER_FW_LOG_PKT_POST 0x003 +#define LOGGER_FATAL_EVENT_POST 0x004 +#define LOGGER_FW_MEM_DUMP_PKT_POST 0x005 +#define LOGGER_FW_MEM_DUMP_PKT_POST_DONE 0x006 +#define HOST_PKT_STATS_POST 0x008 + + +#define LOGGER_MAX_DATA_MGMT_PKT_Q_LEN (8) +#define LOGGER_MAX_FW_LOG_PKT_Q_LEN (16) +#define LOGGER_MAX_FW_MEM_DUMP_PKT_Q_LEN (32) + + +#define NL_BDCAST_RATELIMIT_INTERVAL (5*HZ) +#define NL_BDCAST_RATELIMIT_BURST 1 +#define PTT_MSG_DIAG_CMDS_TYPE 0x5050 +#define DIAG_TYPE_LOGS 1 + +/* Limit FW initiated fatal event to ms */ +#define LIMIT_FW_FATAL_EVENT_MS 10000 + + +/* Qtimer Frequency */ +#define QTIMER_FREQ 19200000 + +static DEFINE_RATELIMIT_STATE(errCnt, \ + NL_BDCAST_RATELIMIT_INTERVAL, \ + NL_BDCAST_RATELIMIT_BURST); + +struct log_msg { + struct list_head node; + unsigned int radio; + unsigned int index; + /* indicates the current filled log length in logbuf */ + unsigned int filled_length; + /* + * Buf to hold the log msg + * tAniHdr + log + */ + char logbuf[MAX_LOGMSG_LENGTH]; +}; + +struct logger_log_complete { + uint32_t is_fatal; + uint32_t indicator; + uint32_t reason_code; + bool is_report_in_progress; + bool is_flush_complete; + uint32_t last_fw_bug_reason; + unsigned long last_fw_bug_timestamp; +}; + +struct fw_mem_dump_logging{ + //It will hold the starting point of mem dump buffer + uint8 *fw_dump_start_loc; + //It will hold the current loc to tell how much data filled + uint8 *fw_dump_current_loc; + uint32 fw_dump_max_size; + vos_pkt_t *fw_mem_dump_queue; + /* Holds number of pkts in fw log vos pkt queue */ + unsigned int fw_mem_dump_pkt_qcnt; + /* Number of dropped pkts for fw dump */ + unsigned int fw_mem_dump_pkt_drop_cnt; + /* Lock to synchronize of queue/dequeue of pkts in fw log pkt queue */ + spinlock_t fw_mem_dump_lock; + /* Fw memory dump status */ + enum FW_MEM_DUMP_STATE fw_mem_dump_status; + /* storage for HDD callback which completes fw mem dump request */ + void * svc_fw_mem_dump_req_cb; + /* storage for HDD callback which completes fw mem dump request arg */ + void * svc_fw_mem_dump_req_cb_arg; +}; + +struct pkt_stats_msg { + struct list_head node; + /* indicates the current filled log length in pktlogbuf */ + struct sk_buff *skb; +}; + +struct perPktStatsInfo{ + v_U32_t lastTxRate; // 802.11 data rate at which the last data frame is transmitted. + v_U32_t txAvgRetry; // Average number of retries per 10 packets. + v_S7_t avgRssi; // Average of the Beacon RSSI. +}; + +struct wlan_logging { + /* Log Fatal and ERROR to console */ + bool log_fe_to_console; + /* Number of buffers to be used for logging */ + int num_buf; + /* Lock to synchronize access to shared logging resource */ + spinlock_t spin_lock; + /* Holds the free node which can be used for filling logs */ + struct list_head free_list; + /* Holds the filled nodes which needs to be indicated to APP */ + struct list_head filled_list; + /* Points to head of logger pkt queue */ + vos_pkt_t *data_mgmt_pkt_queue; + /* Holds number of pkts in vos pkt queue */ + unsigned int data_mgmt_pkt_qcnt; + /* Lock to synchronize of queue/dequeue of pkts in logger pkt queue */ + spinlock_t data_mgmt_pkt_lock; + /* Points to head of logger fw log pkt queue */ + vos_pkt_t *fw_log_pkt_queue; + /* Holds number of pkts in fw log vos pkt queue */ + unsigned int fw_log_pkt_qcnt; + /* Lock to synchronize of queue/dequeue of pkts in fw log pkt queue */ + spinlock_t fw_log_pkt_lock; + /* Wait queue for Logger thread */ + wait_queue_head_t wait_queue; + /* Logger thread */ + struct task_struct *thread; + /* Logging thread sets this variable on exit */ + struct completion shutdown_comp; + /* Indicates to logger thread to exit */ + bool exit; + /* Holds number of dropped logs*/ + unsigned int drop_count; + /* Holds number of dropped vos pkts*/ + unsigned int pkt_drop_cnt; + /* Holds number of dropped fw log vos pkts*/ + unsigned int fw_log_pkt_drop_cnt; + /* current logbuf to which the log will be filled to */ + struct log_msg *pcur_node; + /* Event flag used for wakeup and post indication*/ + unsigned long event_flag; + /* Indicates logger thread is activated */ + bool is_active; + /* data structure for log complete event*/ + struct logger_log_complete log_complete; + spinlock_t bug_report_lock; + struct fw_mem_dump_logging fw_mem_dump_ctx; + int pkt_stat_num_buf; + unsigned int pkt_stat_drop_cnt; + struct list_head pkt_stat_free_list; + struct list_head pkt_stat_filled_list; + struct pkt_stats_msg *pkt_stats_pcur_node; + /* Index of the messages sent to userspace */ + unsigned int pkt_stats_msg_idx; + bool pkt_stats_enabled; + spinlock_t pkt_stats_lock; + struct perPktStatsInfo txPktStatsInfo; +}; + +static struct wlan_logging gwlan_logging; +static struct log_msg *gplog_msg; +static struct pkt_stats_msg *pkt_stats_buffers; + +/* PID of the APP to log the message */ +static int gapp_pid = INVALID_PID; +static char wlan_logging_ready[] = "WLAN LOGGING READY"; + +/* + * Broadcast Logging service ready indication to any Logging application + * Each netlink message will have a message of type tAniMsgHdr inside. + */ +void wlan_logging_srv_nl_ready_indication(void) +{ + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + tAniNlHdr *wnl = NULL; + int payload_len; + int err; + static int rate_limit; + + payload_len = sizeof(tAniHdr) + sizeof(wlan_logging_ready) + + sizeof(wnl->radio); + skb = dev_alloc_skb(NLMSG_SPACE(payload_len)); + if (NULL == skb) { + if (!rate_limit) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "NLINK: skb alloc fail %s", __func__); + } + rate_limit = 1; + return; + } + rate_limit = 0; + + nlh = nlmsg_put(skb, 0, 0, ANI_NL_MSG_LOG, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, + "%s: nlmsg_put() failed for msg size[%d]", + __func__, payload_len); + kfree_skb(skb); + return; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = 0; + wnl->wmsg.type = ANI_NL_MSG_READY_IND_TYPE; + wnl->wmsg.length = sizeof(wlan_logging_ready); + memcpy((char*)&wnl->wmsg + sizeof(tAniHdr), + wlan_logging_ready, + sizeof(wlan_logging_ready)); + + /* sender is in group 1<<0 */ + NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; + + /*multicast the message to all listening processes*/ + err = nl_srv_bcast(skb); + if (err) { + LOGGING_TRACE(VOS_TRACE_LEVEL_INFO_LOW, + "NLINK: Ready Indication Send Fail %s, err %d", + __func__, err); + } + return; +} + +/* Utility function to send a netlink message to an application + * in user space + */ +static int wlan_send_sock_msg_to_app(tAniHdr *wmsg, int radio, + int src_mod, int pid) +{ + int err = -1; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl = NULL; + struct sk_buff *skb; + struct nlmsghdr *nlh; + int wmsg_length = ntohs(wmsg->length); + static int nlmsg_seq; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + pr_err("%s: invalid radio id [%d]", + __func__, radio); + return -EINVAL; + } + + payload_len = wmsg_length + sizeof(wnl->radio) + sizeof(tAniHdr); + + tot_msg_len = NLMSG_SPACE(payload_len); + skb = dev_alloc_skb(tot_msg_len); + if (skb == NULL) { + pr_err("%s: dev_alloc_skb() failed for msg size[%d]", + __func__, tot_msg_len); + return -ENOMEM; + } + nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + pr_err("%s: nlmsg_put() failed for msg size[%d]", + __func__, tot_msg_len); + kfree_skb(skb); + return -ENOMEM; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = radio; + vos_mem_copy(&wnl->wmsg, wmsg, wmsg_length); + + err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); + + return err; +} + +static void set_default_logtoapp_log_level(void) +{ + vos_trace_setValue(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ALL, + VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_PMC, VOS_TRACE_LEVEL_ALL, VOS_TRUE); + vos_trace_setValue(VOS_MODULE_ID_SVC, VOS_TRACE_LEVEL_ALL, VOS_TRUE); +} + +static void clear_default_logtoapp_log_level(void) +{ + int module; + + for (module = 0; module < VOS_MODULE_ID_MAX; module++) { + vos_trace_setValue(module, VOS_TRACE_LEVEL_NONE, + VOS_FALSE); + vos_trace_setValue(module, VOS_TRACE_LEVEL_FATAL, + VOS_TRUE); + vos_trace_setValue(module, VOS_TRACE_LEVEL_ERROR, + VOS_TRUE); + } + + vos_trace_setValue(VOS_MODULE_ID_RSV4, VOS_TRACE_LEVEL_NONE, + VOS_FALSE); +} + +/* Need to call this with spin_lock acquired */ +static int wlan_queue_logmsg_for_app(void) +{ + char *ptr; + int ret = 0; + ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; + ptr[gwlan_logging.pcur_node->filled_length] = '\0'; + + *(unsigned short *)(gwlan_logging.pcur_node->logbuf) = + ANI_NL_MSG_LOG_TYPE; + *(unsigned short *)(gwlan_logging.pcur_node->logbuf + 2) = + gwlan_logging.pcur_node->filled_length; + list_add_tail(&gwlan_logging.pcur_node->node, + &gwlan_logging.filled_list); + + if (!list_empty(&gwlan_logging.free_list)) { + /* Get buffer from free list */ + gwlan_logging.pcur_node = + (struct log_msg *)(gwlan_logging.free_list.next); + list_del_init(gwlan_logging.free_list.next); + } else if (!list_empty(&gwlan_logging.filled_list)) { + /* Get buffer from filled list */ + /* This condition will drop the packet from being + * indicated to app + */ + gwlan_logging.pcur_node = + (struct log_msg *)(gwlan_logging.filled_list.next); + ++gwlan_logging.drop_count; + /* print every 64th drop count */ + if (vos_is_multicast_logging() && + (!(gwlan_logging.drop_count % 0x40))) { + pr_err("%s: drop_count = %u index = %d filled_length = %d\n", + __func__, gwlan_logging.drop_count, + gwlan_logging.pcur_node->index, + gwlan_logging.pcur_node->filled_length); + } + list_del_init(gwlan_logging.filled_list.next); + ret = 1; + } + + /* Reset the current node values */ + gwlan_logging.pcur_node->filled_length = 0; + return ret; +} + +void wlan_fillTxStruct(void *pktStat) +{ + vos_mem_copy(&gwlan_logging.txPktStatsInfo, + (struct perPktStatsInfo *)pktStat, + sizeof(struct perPktStatsInfo)); +} + +bool wlan_isPktStatsEnabled(void) +{ + return gwlan_logging.pkt_stats_enabled; +} + + + +/* Need to call this with spin_lock acquired */ +static int wlan_queue_pkt_stats_for_app(void) +{ + int ret = 0; + + list_add_tail(&gwlan_logging.pkt_stats_pcur_node->node, + &gwlan_logging.pkt_stat_filled_list); + + if (!list_empty(&gwlan_logging.pkt_stat_free_list)) { + /* Get buffer from free list */ + gwlan_logging.pkt_stats_pcur_node = + (struct pkt_stats_msg *)(gwlan_logging.pkt_stat_free_list.next); + list_del_init(gwlan_logging.pkt_stat_free_list.next); + } else if (!list_empty(&gwlan_logging.pkt_stat_filled_list)) { + /* Get buffer from filled list */ + /* This condition will drop the packet from being + * indicated to app + */ + gwlan_logging.pkt_stats_pcur_node = + (struct pkt_stats_msg *)(gwlan_logging.pkt_stat_filled_list.next); + ++gwlan_logging.pkt_stat_drop_cnt; + /* print every 64th drop count */ + if (vos_is_multicast_logging() && + (!(gwlan_logging.pkt_stat_drop_cnt % 0x40))) { + pr_err("%s: drop_count = %u filled_length = %d\n", + __func__, gwlan_logging.pkt_stat_drop_cnt, + gwlan_logging.pkt_stats_pcur_node->skb->len); + } + list_del_init(gwlan_logging.pkt_stat_filled_list.next); + ret = 1; + } + + /* Reset the current node values */ + gwlan_logging.pkt_stats_pcur_node-> skb->len = 0; + return ret; +} + +int wlan_pkt_stats_to_user(void *perPktStat) +{ + bool wake_up_thread = false; + tPerPacketStats *pktstats = perPktStat; + unsigned long flags; + tx_rx_pkt_stats rx_tx_stats; + int total_log_len = 0; + struct sk_buff *ptr; + tpSirMacMgmtHdr hdr; + uint32 rateIdx; + + if (!vos_is_multicast_logging()) + { + return -EIO; + } + if (vos_is_multicast_logging()) { + + vos_mem_zero(&rx_tx_stats, sizeof(tx_rx_pkt_stats)); + + if (pktstats->is_rx){ + rx_tx_stats.ps_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_REMOTE_S); + }else{ + rx_tx_stats.ps_hdr.flags = (1 << PKTLOG_FLG_FRM_TYPE_LOCAL_S); + + } + /*Send log type as PKTLOG_TYPE_PKT_STAT (9)*/ + rx_tx_stats.ps_hdr.log_type = PKTLOG_TYPE_PKT_STAT; + rx_tx_stats.ps_hdr.timestamp = vos_timer_get_system_ticks(); + rx_tx_stats.ps_hdr.missed_cnt = 0; + rx_tx_stats.ps_hdr.size = sizeof(tx_rx_pkt_stats) - + sizeof(pkt_stats_hdr) + pktstats->data_len- + MAX_PKT_STAT_DATA_LEN; + + rx_tx_stats.stats.flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rx_tx_stats.stats.flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER; + if (pktstats->is_rx) + rx_tx_stats.stats.flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX; + + hdr = (tpSirMacMgmtHdr)pktstats->data; + if (hdr->fc.wep) { + rx_tx_stats.stats.flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED; + /* Reset wep bit to parse frame properly */ + hdr->fc.wep = 0; + } + + rx_tx_stats.stats.tid = pktstats->tid; + rx_tx_stats.stats.dxe_timestamp = pktstats->dxe_timestamp; + + if (!pktstats->is_rx) + { + rx_tx_stats.stats.rssi = gwlan_logging.txPktStatsInfo.avgRssi; + rx_tx_stats.stats.num_retries = gwlan_logging.txPktStatsInfo.txAvgRetry; + rateIdx = gwlan_logging.txPktStatsInfo.lastTxRate; + } + else + { + rx_tx_stats.stats.rssi = pktstats->rssi; + rx_tx_stats.stats.num_retries = pktstats->num_retries; + rateIdx = pktstats->rate_idx; + + } + rx_tx_stats.stats.link_layer_transmit_sequence = pktstats->seq_num; + + /* Calculate rate and MCS from rate index */ + if( rateIdx >= 210 && rateIdx <= 217) + rateIdx-=202; + if( rateIdx >= 218 && rateIdx <= 225 ) + rateIdx-=210; + get_rate_and_MCS(&rx_tx_stats.stats, rateIdx); + + vos_mem_copy(rx_tx_stats.stats.data,pktstats->data, pktstats->data_len); + + /* 1+1 indicate '\n'+'\0' */ + total_log_len = sizeof(tx_rx_pkt_stats) + pktstats->data_len - + MAX_PKT_STAT_DATA_LEN; + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + // wlan logging svc resources are not yet initialized + if (!gwlan_logging.pkt_stats_pcur_node) { + pr_err("%s, logging svc not initialized", __func__); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + return -EIO; + } + + ; + + /* Check if we can accomodate more log into current node/buffer */ + if (total_log_len + sizeof(vos_log_pktlog_info) + sizeof(tAniNlHdr) >= + skb_tailroom(gwlan_logging.pkt_stats_pcur_node->skb)) { + wake_up_thread = true; + wlan_queue_pkt_stats_for_app(); + } + ptr = gwlan_logging.pkt_stats_pcur_node->skb; + + + vos_mem_copy(skb_put(ptr, total_log_len), &rx_tx_stats, total_log_len); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + /* Wakeup logger thread */ + if ((true == wake_up_thread)) { + /* If there is logger app registered wakeup the logging + * thread + */ + set_bit(HOST_PKT_STATS_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + } + return 0; +} + +void wlan_disable_and_flush_pkt_stats() +{ + unsigned long flags; + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + if(gwlan_logging.pkt_stats_pcur_node->skb->len){ + wlan_queue_pkt_stats_for_app(); + } + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + set_bit(HOST_PKT_STATS_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); +} + +int wlan_log_to_user(VOS_TRACE_LEVEL log_level, char *to_be_sent, int length) +{ + /* Add the current time stamp */ + char *ptr; + char tbuf[100]; + int tlen; + int total_log_len; + unsigned int *pfilled_length; + bool wake_up_thread = false; + unsigned long flags; + + struct timeval tv; + struct rtc_time tm; + unsigned long local_time; + u64 qtimer_ticks; + + if (!vos_is_multicast_logging()) { + /* + * This is to make sure that we print the logs to kmsg console + * when no logger app is running. This is also needed to + * log the initial messages during loading of driver where even + * if app is running it will not be able to + * register with driver immediately and start logging all the + * messages. + */ + pr_err("%s\n", to_be_sent); + } else { + + /* Format the Log time [hr:min:sec.microsec] */ + do_gettimeofday(&tv); + + /* Convert rtc to local time */ + local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + /* Firmware Time Stamp */ + qtimer_ticks = arch_counter_get_cntpct(); + + tlen = snprintf(tbuf, sizeof(tbuf), "[%02d:%02d:%02d.%06lu] [%016llX]" + " [%.5s] ", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, + qtimer_ticks, current->comm); + /* 1+1 indicate '\n'+'\0' */ + total_log_len = length + tlen + 1 + 1; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + + // wlan logging svc resources are not yet initialized + if (!gwlan_logging.pcur_node) { + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + return -EIO; + } + + pfilled_length = &gwlan_logging.pcur_node->filled_length; + + /* Check if we can accomodate more log into current node/buffer */ + if (MAX_LOGMSG_LENGTH < (*pfilled_length + sizeof(tAniNlHdr) + + total_log_len)) { + wake_up_thread = true; + wlan_queue_logmsg_for_app(); + pfilled_length = &gwlan_logging.pcur_node->filled_length; + } + + ptr = &gwlan_logging.pcur_node->logbuf[sizeof(tAniHdr)]; + + /* Assumption here is that we receive logs which is always less than + * MAX_LOGMSG_LENGTH, where we can accomodate the + * tAniNlHdr + [context][timestamp] + log + * VOS_ASSERT if we cannot accomodate the the complete log into + * the available buffer. + * + * Continue and copy logs to the available length and discard the rest. + */ + if (MAX_LOGMSG_LENGTH < (sizeof(tAniNlHdr) + total_log_len)) { + VOS_ASSERT(0); + total_log_len = MAX_LOGMSG_LENGTH - sizeof(tAniNlHdr) - 2; + } + + vos_mem_copy(&ptr[*pfilled_length], tbuf, tlen); + vos_mem_copy(&ptr[*pfilled_length + tlen], to_be_sent, + min(length, (total_log_len - tlen))); + *pfilled_length += tlen + min(length, total_log_len - tlen); + ptr[*pfilled_length] = '\n'; + *pfilled_length += 1; + + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + /* Wakeup logger thread */ + if ((true == wake_up_thread)) { + /* If there is logger app registered wakeup the logging + * thread + */ + + set_bit(HOST_LOG_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + + if (gwlan_logging.log_fe_to_console + && ((VOS_TRACE_LEVEL_FATAL == log_level) + || (VOS_TRACE_LEVEL_ERROR == log_level))) { + pr_err("%s %s\n",tbuf, to_be_sent); + } + } + + return 0; +} + +static int send_fw_log_pkt_to_user(void) +{ + int ret = -1; + int extra_header_len, nl_payload_len; + struct sk_buff *skb = NULL; + static int nlmsg_seq; + vos_pkt_t *current_pkt; + vos_pkt_t *next_pkt; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + unsigned long flags; + + tAniNlHdr msg_header; + + do { + spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); + + if (!gwlan_logging.fw_log_pkt_queue) { + spin_unlock_irqrestore( + &gwlan_logging.fw_log_pkt_lock, flags); + return -EIO; + } + + /* pick first pkt from queued chain */ + current_pkt = gwlan_logging.fw_log_pkt_queue; + + /* get the pointer to the next packet in the chain */ + status = vos_pkt_walk_packet_chain(current_pkt, &next_pkt, + TRUE); + + /* both "success" and "empty" are acceptable results */ + if (!((status == VOS_STATUS_SUCCESS) || + (status == VOS_STATUS_E_EMPTY))) { + ++gwlan_logging.fw_log_pkt_drop_cnt; + spin_unlock_irqrestore( + &gwlan_logging.fw_log_pkt_lock, flags); + pr_err("%s: Failure walking packet chain", __func__); + return -EIO; + } + + /* update queue head with next pkt ptr which could be NULL */ + gwlan_logging.fw_log_pkt_queue = next_pkt; + --gwlan_logging.fw_log_pkt_qcnt; + spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, flags); + + status = vos_pkt_get_os_packet(current_pkt, (v_VOID_t **)&skb, + TRUE); + if (!VOS_IS_STATUS_SUCCESS(status)) { + ++gwlan_logging.fw_log_pkt_drop_cnt; + pr_err("%s: Failure extracting skb from vos pkt", + __func__); + return -EIO; + } + + /*return vos pkt since skb is already detached */ + vos_pkt_return_packet(current_pkt); + + extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr); + nl_payload_len = extra_header_len + skb->len; + + msg_header.nlh.nlmsg_type = ANI_NL_MSG_LOG; + msg_header.nlh.nlmsg_len = nlmsg_msg_size(nl_payload_len); + msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; + msg_header.nlh.nlmsg_pid = gapp_pid; + msg_header.nlh.nlmsg_seq = nlmsg_seq++; + + msg_header.radio = 0; + + msg_header.wmsg.type = ANI_NL_MSG_FW_LOG_PKT_TYPE; + msg_header.wmsg.length = skb->len; + + if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p]," + " data[%p], req[%zu]", __LINE__, skb->head, + skb->data, sizeof(msg_header)); + return -EIO; + } + + vos_mem_copy(skb_push(skb, sizeof(msg_header)), &msg_header, + sizeof(msg_header)); + + ret = nl_srv_bcast(skb); + if ((ret < 0) && (ret != -ESRCH)) { + pr_info("%s: Send Failed %d drop_count = %u\n", + __func__, ret, ++gwlan_logging.fw_log_pkt_drop_cnt); + } else { + ret = 0; + } + + } while (next_pkt); + + return ret; +} + +static int send_data_mgmt_log_pkt_to_user(void) +{ + int ret = -1; + int extra_header_len, nl_payload_len; + struct sk_buff *skb = NULL; + static int nlmsg_seq; + vos_pkt_t *current_pkt; + vos_pkt_t *next_pkt; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + unsigned long flags; + + tAniNlLogHdr msg_header; + + do { + spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); + + if (!gwlan_logging.data_mgmt_pkt_queue) { + spin_unlock_irqrestore( + &gwlan_logging.data_mgmt_pkt_lock, flags); + return -EIO; + } + + /* pick first pkt from queued chain */ + current_pkt = gwlan_logging.data_mgmt_pkt_queue; + + /* get the pointer to the next packet in the chain */ + status = vos_pkt_walk_packet_chain(current_pkt, &next_pkt, + TRUE); + + /* both "success" and "empty" are acceptable results */ + if (!((status == VOS_STATUS_SUCCESS) || + (status == VOS_STATUS_E_EMPTY))) { + ++gwlan_logging.pkt_drop_cnt; + spin_unlock_irqrestore( + &gwlan_logging.data_mgmt_pkt_lock, flags); + pr_err("%s: Failure walking packet chain", __func__); + return -EIO; + } + + /* update queue head with next pkt ptr which could be NULL */ + gwlan_logging.data_mgmt_pkt_queue = next_pkt; + --gwlan_logging.data_mgmt_pkt_qcnt; + spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, flags); + + status = vos_pkt_get_os_packet(current_pkt, (v_VOID_t **)&skb, + TRUE); + if (!VOS_IS_STATUS_SUCCESS(status)) { + ++gwlan_logging.pkt_drop_cnt; + pr_err("%s: Failure extracting skb from vos pkt", + __func__); + return -EIO; + } + + /*return vos pkt since skb is already detached */ + vos_pkt_return_packet(current_pkt); + + extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr) + + sizeof(msg_header.frameSize); + nl_payload_len = extra_header_len + skb->len; + + msg_header.nlh.nlmsg_type = ANI_NL_MSG_LOG; + msg_header.nlh.nlmsg_len = nlmsg_msg_size(nl_payload_len); + msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; + msg_header.nlh.nlmsg_pid = 0; + msg_header.nlh.nlmsg_seq = nlmsg_seq++; + + msg_header.radio = 0; + + msg_header.wmsg.type = ANI_NL_MSG_LOG_PKT_TYPE; + msg_header.wmsg.length = skb->len + sizeof(uint32); + + msg_header.frameSize = WLAN_MGMT_LOGGING_FRAMESIZE_128BYTES; + + if (unlikely(skb_headroom(skb) < sizeof(msg_header))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p]," + " data[%p], req[%zu]", __LINE__, skb->head, + skb->data, sizeof(msg_header)); + return -EIO; + } + + vos_mem_copy(skb_push(skb, sizeof(msg_header)), &msg_header, + sizeof(msg_header)); + + ret = nl_srv_bcast(skb); + if (ret < 0) { + pr_info("%s: Send Failed %d drop_count = %u\n", + __func__, ret, ++gwlan_logging.pkt_drop_cnt); + } else { + ret = 0; + } + + } while (next_pkt); + + return ret; +} + +static int fill_fw_mem_dump_buffer(void) +{ + struct sk_buff *skb = NULL; + vos_pkt_t *current_pkt; + vos_pkt_t *next_pkt; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + unsigned long flags; + int byte_left = 0; + do { + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + + if (!gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue) { + spin_unlock_irqrestore( + &gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + return -EIO; + } + + /* pick first pkt from queued chain */ + current_pkt = gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue; + + /* get the pointer to the next packet in the chain */ + status = vos_pkt_walk_packet_chain(current_pkt, &next_pkt, + TRUE); + + /* both "success" and "empty" are acceptable results */ + if (!((status == VOS_STATUS_SUCCESS) || + (status == VOS_STATUS_E_EMPTY))) { + spin_unlock_irqrestore( + &gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + pr_err("%s: Failure walking packet chain", __func__); + return -EIO; + } + + /* update queue head with next pkt ptr which could be NULL */ + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue = next_pkt; + --gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_qcnt; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + + status = vos_pkt_get_os_packet(current_pkt, (v_VOID_t **)&skb, + VOS_FALSE); + if (!VOS_IS_STATUS_SUCCESS(status)) { + pr_err("%s: Failure extracting skb from vos pkt", + __func__); + return -EIO; + } + + //Copy data from SKB to mem dump buffer + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + if((skb) && (skb->len != 0)) + { + // Prevent buffer overflow + byte_left = ((int)gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size - + (int)(gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc - gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc)); + if(skb->len > byte_left) + { + vos_mem_copy(gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc, skb->data, byte_left); + //Update the current location ptr + gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc += byte_left; + } + else + { + vos_mem_copy(gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc, skb->data, skb->len); + //Update the current location ptr + gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc += skb->len; + } + } + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + /*return vos pkt since skb is already detached */ + vos_pkt_return_packet(current_pkt); + } while (next_pkt); + + return 0; +} + +static int send_filled_buffers_to_user(void) +{ + int ret = -1; + struct log_msg *plog_msg; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl; + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + static int nlmsg_seq; + unsigned long flags; + static int rate_limit; + + while (!list_empty(&gwlan_logging.filled_list) + && !gwlan_logging.exit) { + + skb = dev_alloc_skb(MAX_LOGMSG_LENGTH); + if (skb == NULL) { + if (!rate_limit) { + pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", + __func__, MAX_LOGMSG_LENGTH, + gwlan_logging.drop_count); + } + rate_limit = 1; + ret = -ENOMEM; + break; + } + rate_limit = 0; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + + plog_msg = (struct log_msg *) + (gwlan_logging.filled_list.next); + list_del_init(gwlan_logging.filled_list.next); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + /* 4 extra bytes for the radio idx */ + payload_len = plog_msg->filled_length + + sizeof(wnl->radio) + sizeof(tAniHdr); + + tot_msg_len = NLMSG_SPACE(payload_len); + nlh = nlmsg_put(skb, 0, nlmsg_seq++, + ANI_NL_MSG_LOG, payload_len, + NLM_F_REQUEST); + if (NULL == nlh) { + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + list_add_tail(&plog_msg->node, + &gwlan_logging.free_list); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, + flags); + pr_err("%s: drop_count = %u\n", __func__, + ++gwlan_logging.drop_count); + pr_err("%s: nlmsg_put() failed for msg size[%d]\n", + __func__, tot_msg_len); + dev_kfree_skb(skb); + skb = NULL; + ret = -EINVAL; + continue; + } + + wnl = (tAniNlHdr *) nlh; + wnl->radio = plog_msg->radio; + vos_mem_copy(&wnl->wmsg, plog_msg->logbuf, + plog_msg->filled_length + + sizeof(tAniHdr)); + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + list_add_tail(&plog_msg->node, + &gwlan_logging.free_list); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + ret = nl_srv_bcast(skb); + if (ret < 0) { + if (__ratelimit(&errCnt)) + { + pr_info("%s: Send Failed %d drop_count = %u\n", + __func__, ret, gwlan_logging.drop_count); + } + gwlan_logging.drop_count++; + skb = NULL; + break; + } else { + skb = NULL; + ret = 0; + } + } + + return ret; +} + + +static int send_per_pkt_stats_to_user(void) +{ + int ret = -1; + struct pkt_stats_msg *plog_msg; + unsigned long flags; + struct sk_buff *skb_new = NULL; + vos_log_pktlog_info pktlog; + tAniNlHdr msg_header; + int extra_header_len, nl_payload_len; + static int nlmsg_seq; + static int rate_limit; + int diag_type; + bool free_old_skb = false; + + while (!list_empty(&gwlan_logging.pkt_stat_filled_list) + && !gwlan_logging.exit) { + skb_new= dev_alloc_skb(MAX_PKTSTATS_LOG_LENGTH); + if (skb_new == NULL) { + if (!rate_limit) { + pr_err("%s: dev_alloc_skb() failed for msg size[%d] drop count = %u\n", + __func__, MAX_LOGMSG_LENGTH, + gwlan_logging.drop_count); + } + rate_limit = 1; + ret = -ENOMEM; + break; + } + + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + + plog_msg = (struct pkt_stats_msg *) + (gwlan_logging.pkt_stat_filled_list.next); + list_del_init(gwlan_logging.pkt_stat_filled_list.next); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + + vos_mem_zero(&pktlog, sizeof(vos_log_pktlog_info)); + vos_log_set_code(&pktlog, LOG_WLAN_PKT_LOG_INFO_C); + + pktlog.version = VERSION_LOG_WLAN_PKT_LOG_INFO_C; + pktlog.buf_len = plog_msg->skb->len; + vos_log_set_length(&pktlog.log_hdr, plog_msg->skb->len + + sizeof(vos_log_pktlog_info)); + pktlog.seq_no = gwlan_logging.pkt_stats_msg_idx++; + + if (unlikely(skb_headroom(plog_msg->skb) < sizeof(vos_log_pktlog_info))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p]," + " data[%p], req[%zu]", __LINE__, plog_msg->skb->head, + plog_msg->skb->data, sizeof(msg_header)); + ret = -EIO; + free_old_skb = true; + goto err; + } + vos_mem_copy(skb_push(plog_msg->skb, sizeof(vos_log_pktlog_info)), &pktlog, + sizeof(vos_log_pktlog_info)); + + if (unlikely(skb_headroom(plog_msg->skb) < sizeof(int))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p]," + " data[%p], req[%zu]", __LINE__, plog_msg->skb->head, + plog_msg->skb->data, sizeof(int)); + ret = -EIO; + free_old_skb = true; + goto err; + } + + diag_type = DIAG_TYPE_LOGS; + vos_mem_copy(skb_push(plog_msg->skb, sizeof(int)), &diag_type, + sizeof(int)); + + extra_header_len = sizeof(msg_header.radio) + sizeof(tAniHdr); + nl_payload_len = extra_header_len + plog_msg->skb->len; + + msg_header.nlh.nlmsg_type = ANI_NL_MSG_PUMAC; + msg_header.nlh.nlmsg_len = nlmsg_msg_size(nl_payload_len); + msg_header.nlh.nlmsg_flags = NLM_F_REQUEST; + msg_header.nlh.nlmsg_pid = 0; + msg_header.nlh.nlmsg_seq = nlmsg_seq++; + + msg_header.radio = 0; + + msg_header.wmsg.type = PTT_MSG_DIAG_CMDS_TYPE; + msg_header.wmsg.length = cpu_to_be16(plog_msg->skb->len); + + if (unlikely(skb_headroom(plog_msg->skb) < sizeof(msg_header))) { + pr_err("VPKT [%d]: Insufficient headroom, head[%p]," + " data[%p], req[%zu]", __LINE__, plog_msg->skb->head, + plog_msg->skb->data, sizeof(msg_header)); + ret = -EIO; + free_old_skb = true; + goto err; + } + + vos_mem_copy(skb_push(plog_msg->skb, sizeof(msg_header)), &msg_header, + sizeof(msg_header)); + + ret = nl_srv_bcast(plog_msg->skb); + if (ret < 0) { + pr_info("%s: Send Failed %d drop_count = %u\n", + __func__, ret, ++gwlan_logging.fw_log_pkt_drop_cnt); + } else { + ret = 0; + } +err: + /* + * Free old skb in case or error before assigning new skb + * to the free list. + */ + if (free_old_skb) + dev_kfree_skb(plog_msg->skb); + spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, flags); + plog_msg->skb = skb_new; + list_add_tail(&plog_msg->node, + &gwlan_logging.pkt_stat_free_list); + spin_unlock_irqrestore(&gwlan_logging.pkt_stats_lock, flags); + ret = 0; + } + + return ret; +} + +/** + * wlan_logging_thread() - The WLAN Logger thread + * @Arg - pointer to the HDD context + * + * This thread logs log message to App registered for the logs. + */ +static int wlan_logging_thread(void *Arg) +{ + int ret_wait_status = 0; + int ret = 0; + unsigned long flags; + set_user_nice(current, -2); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) + daemonize("wlan_logging_thread"); +#endif + while (!gwlan_logging.exit) { + ret_wait_status = wait_event_interruptible( + gwlan_logging.wait_queue, + (test_bit(HOST_LOG_POST, &gwlan_logging.event_flag) || + gwlan_logging.exit || + test_bit(LOGGER_MGMT_DATA_PKT_POST, + &gwlan_logging.event_flag) || + test_bit(LOGGER_FW_LOG_PKT_POST, + &gwlan_logging.event_flag) || + test_bit(LOGGER_FATAL_EVENT_POST, + &gwlan_logging.event_flag) || + test_bit(LOGGER_FW_MEM_DUMP_PKT_POST, &gwlan_logging.event_flag) || + test_bit(LOGGER_FW_MEM_DUMP_PKT_POST_DONE, &gwlan_logging.event_flag)|| + test_bit(HOST_PKT_STATS_POST, + &gwlan_logging.event_flag))); + + if (ret_wait_status == -ERESTARTSYS) { + pr_err("%s: wait_event return -ERESTARTSYS", __func__); + break; + } + + if (gwlan_logging.exit) { + break; + } + + if (test_and_clear_bit(HOST_LOG_POST, + &gwlan_logging.event_flag)) { + ret = send_filled_buffers_to_user(); + if (-ENOMEM == ret) { + msleep(200); + } + if (WLAN_LOG_INDICATOR_HOST_ONLY == + gwlan_logging.log_complete.indicator) + { + vos_send_fatal_event_done(); + } + } + + if (test_and_clear_bit(LOGGER_FW_LOG_PKT_POST, + &gwlan_logging.event_flag)) { + send_fw_log_pkt_to_user(); + } + + if (test_and_clear_bit(LOGGER_MGMT_DATA_PKT_POST, + &gwlan_logging.event_flag)) { + send_data_mgmt_log_pkt_to_user(); + } + + if (test_and_clear_bit(LOGGER_FATAL_EVENT_POST, + &gwlan_logging.event_flag)) { + if (gwlan_logging.log_complete.is_flush_complete == true) { + gwlan_logging.log_complete.is_flush_complete = false; + vos_send_fatal_event_done(); + } + else { + gwlan_logging.log_complete.is_flush_complete = true; + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + /* Flush all current host logs*/ + wlan_queue_logmsg_for_app(); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + set_bit(HOST_LOG_POST,&gwlan_logging.event_flag); + set_bit(LOGGER_FW_LOG_PKT_POST, &gwlan_logging.event_flag); + set_bit(LOGGER_FATAL_EVENT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + } + + if (test_and_clear_bit(LOGGER_FW_MEM_DUMP_PKT_POST, + &gwlan_logging.event_flag)) { + fill_fw_mem_dump_buffer(); + } + if(test_and_clear_bit(LOGGER_FW_MEM_DUMP_PKT_POST_DONE, &gwlan_logging.event_flag)){ + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock,flags); + /*Chnage fw memory dump to indicate write done*/ + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status = FW_MEM_DUMP_WRITE_DONE; + /*reset dropped packet count upon completion of this request*/ + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_drop_cnt = 0; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock,flags); + fill_fw_mem_dump_buffer(); + /* + * Call the registered HDD callback for indicating + * memdump complete. If it's null,then something is + * not right. + */ + if (gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb && + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb_arg) { + ((hdd_fw_mem_dump_req_cb) + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb)( + (struct hdd_fw_mem_dump_req_ctx*) + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb_arg); + + /*invalidate the callback pointers*/ + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock,flags); + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb = NULL; + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb_arg = NULL; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock,flags); + } + } + + if (test_and_clear_bit(HOST_PKT_STATS_POST, + &gwlan_logging.event_flag)) { + send_per_pkt_stats_to_user(); + } + } + + complete_and_exit(&gwlan_logging.shutdown_comp, 0); + + return 0; +} + +/* + * Process all the Netlink messages from Logger Socket app in user space + */ +static int wlan_logging_proc_sock_rx_msg(struct sk_buff *skb) +{ + tAniNlHdr *wnl; + int radio; + int type; + int ret, len; + unsigned long flags; + + if (TRUE == vos_isUnloadInProgress()) + { + pr_info("%s: unload in progress\n",__func__); + return -ENODEV; + } + + wnl = (tAniNlHdr *) skb->data; + radio = wnl->radio; + type = wnl->nlh.nlmsg_type; + + if (radio < 0 || radio > ANI_MAX_RADIOS) { + pr_err("%s: invalid radio id [%d]\n", + __func__, radio); + return -EINVAL; + } + + len = ntohs(wnl->wmsg.length) + sizeof(tAniNlHdr); + + if (len > skb_headlen(skb)) + { + pr_err("%s: invalid length, msgLen:%x skb len:%x headLen: %d data_len: %d", + __func__, len, skb->len, skb_headlen(skb), skb->data_len); + return -EINVAL; + } + + if (gapp_pid != INVALID_PID) { + if (wnl->nlh.nlmsg_pid > gapp_pid) { + gapp_pid = wnl->nlh.nlmsg_pid; + } + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + if (gwlan_logging.pcur_node->filled_length) { + wlan_queue_logmsg_for_app(); + } + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + set_bit(HOST_LOG_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } else { + /* This is to set the default levels (WLAN logging + * default values not the VOS trace default) when + * logger app is registered for the first time. + */ + gapp_pid = wnl->nlh.nlmsg_pid; + } + + ret = wlan_send_sock_msg_to_app(&wnl->wmsg, 0, + ANI_NL_MSG_LOG, wnl->nlh.nlmsg_pid); + if (ret < 0) { + pr_err("wlan_send_sock_msg_to_app: failed"); + } + + return ret; +} + +void wlan_init_log_completion(void) +{ + gwlan_logging.log_complete.indicator = WLAN_LOG_INDICATOR_UNUSED; + gwlan_logging.log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL; + gwlan_logging.log_complete.is_report_in_progress = false; + gwlan_logging.log_complete.reason_code = WLAN_LOG_REASON_CODE_UNUSED; + gwlan_logging.log_complete.last_fw_bug_reason = 0; + gwlan_logging.log_complete.last_fw_bug_timestamp = 0; + + spin_lock_init(&gwlan_logging.bug_report_lock); +} + +int wlan_set_log_completion(uint32 is_fatal, + uint32 indicator, + uint32 reason_code) +{ + unsigned long flags; + + spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags); + gwlan_logging.log_complete.indicator = indicator; + gwlan_logging.log_complete.is_fatal = is_fatal; + gwlan_logging.log_complete.is_report_in_progress = true; + gwlan_logging.log_complete.reason_code = reason_code; + spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags); + return 0; +} +void wlan_get_log_and_reset_completion(uint32 *is_fatal, + uint32 *indicator, + uint32 *reason_code, + bool reset) +{ + unsigned long flags; + + spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags); + *indicator = gwlan_logging.log_complete.indicator; + *is_fatal = gwlan_logging.log_complete.is_fatal; + *reason_code = gwlan_logging.log_complete.reason_code; + if (reset) { + gwlan_logging.log_complete.indicator = + WLAN_LOG_INDICATOR_UNUSED; + gwlan_logging.log_complete.is_fatal = WLAN_LOG_TYPE_NON_FATAL; + gwlan_logging.log_complete.is_report_in_progress = false; + gwlan_logging.log_complete.reason_code = + WLAN_LOG_REASON_CODE_UNUSED; + } + spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags); +} + +bool wlan_is_log_report_in_progress(void) +{ + return gwlan_logging.log_complete.is_report_in_progress; +} + + +void wlan_reset_log_report_in_progress(void) +{ + unsigned long flags; + + spin_lock_irqsave(&gwlan_logging.bug_report_lock, flags); + gwlan_logging.log_complete.is_report_in_progress = false; + spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, flags); +} + + +void wlan_deinit_log_completion(void) +{ + return; +} + + +int wlan_logging_sock_activate_svc(int log_fe_to_console, int num_buf, + int pkt_stats_enabled, int pkt_stats_buff) +{ + int i, j = 0; + unsigned long irq_flag; + bool failure = FALSE; + + pr_info("%s: Initalizing FEConsoleLog = %d NumBuff = %d\n", + __func__, log_fe_to_console, num_buf); + + gapp_pid = INVALID_PID; + + gplog_msg = (struct log_msg *) vmalloc( + num_buf * sizeof(struct log_msg)); + if (!gplog_msg) { + pr_err("%s: Could not allocate memory\n", __func__); + return -ENOMEM; + } + + vos_mem_zero(gplog_msg, (num_buf * sizeof(struct log_msg))); + + gwlan_logging.log_fe_to_console = !!log_fe_to_console; + gwlan_logging.num_buf = num_buf; + + spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag); + INIT_LIST_HEAD(&gwlan_logging.free_list); + INIT_LIST_HEAD(&gwlan_logging.filled_list); + + for (i = 0; i < num_buf; i++) { + list_add(&gplog_msg[i].node, &gwlan_logging.free_list); + gplog_msg[i].index = i; + } + gwlan_logging.pcur_node = (struct log_msg *) + (gwlan_logging.free_list.next); + list_del_init(gwlan_logging.free_list.next); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag); + if(pkt_stats_enabled) + { + pr_info("%s: Initalizing Pkt stats pkt_stats_buff = %d\n", + __func__, pkt_stats_buff); + pkt_stats_buffers = (struct pkt_stats_msg *) kzalloc( + pkt_stats_buff * sizeof(struct pkt_stats_msg), GFP_KERNEL); + if (!pkt_stats_buffers) { + pr_err("%s: Could not allocate memory for Pkt stats\n", __func__); + failure = TRUE; + goto err; + } + + gwlan_logging.pkt_stat_num_buf = pkt_stats_buff; + + gwlan_logging.pkt_stats_msg_idx = 0; + INIT_LIST_HEAD(&gwlan_logging.pkt_stat_free_list); + INIT_LIST_HEAD(&gwlan_logging.pkt_stat_filled_list); + + for (i = 0; i < pkt_stats_buff; i++) { + pkt_stats_buffers[i].skb= dev_alloc_skb(MAX_PKTSTATS_LOG_LENGTH); + if (pkt_stats_buffers[i].skb == NULL) + { + pr_err("%s: Memory alloc failed for skb",__func__); + /* free previously allocated skb and return;*/ + for (j = 0; j= LOGGER_MAX_DATA_MGMT_PKT_Q_LEN) { + status = vos_pkt_walk_packet_chain( + gwlan_logging.data_mgmt_pkt_queue, &next_pkt, TRUE); + /*both "success" and "empty" are acceptable results*/ + if (!((status == VOS_STATUS_SUCCESS) || + (status == VOS_STATUS_E_EMPTY))) { + ++gwlan_logging.pkt_drop_cnt; + spin_unlock_irqrestore( + &gwlan_logging.data_mgmt_pkt_lock, flags); + pr_err("%s: Failure walking packet chain", __func__); + /*keep returning pkts to avoid low resource cond*/ + vos_pkt_return_packet(pPacket); + return VOS_STATUS_E_FAILURE; + } + + free_pkt = gwlan_logging.data_mgmt_pkt_queue; + gwlan_logging.data_mgmt_pkt_queue = next_pkt; + /*returning head of pkt queue. latest pkts are important*/ + --gwlan_logging.data_mgmt_pkt_qcnt; + spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, + flags); + vos_pkt_return_packet(free_pkt); + } else { + spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, + flags); + } + + spin_lock_irqsave(&gwlan_logging.data_mgmt_pkt_lock, flags); + + if (gwlan_logging.data_mgmt_pkt_queue) { + vos_pkt_chain_packet(gwlan_logging.data_mgmt_pkt_queue, + pPacket, TRUE); + } else { + gwlan_logging.data_mgmt_pkt_queue = pPacket; + } + ++gwlan_logging.data_mgmt_pkt_qcnt; + + spin_unlock_irqrestore(&gwlan_logging.data_mgmt_pkt_lock, flags); + + set_bit(LOGGER_MGMT_DATA_PKT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + + return VOS_STATUS_SUCCESS; +} + +/** + * wlan_logging_set_log_level() - Set the logging level + * + * This function is used to set the logging level of host debug messages + * + * Return: None + */ +void wlan_logging_set_log_level(void) +{ + set_default_logtoapp_log_level(); +} + +int wlan_queue_fw_log_pkt_for_app(vos_pkt_t *pPacket) +{ + unsigned long flags; + vos_pkt_t *next_pkt; + vos_pkt_t *free_pkt; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + + spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); + if (gwlan_logging.fw_log_pkt_qcnt >= LOGGER_MAX_FW_LOG_PKT_Q_LEN) { + status = vos_pkt_walk_packet_chain( + gwlan_logging.fw_log_pkt_queue, &next_pkt, TRUE); + /*both "success" and "empty" are acceptable results*/ + if (!((status == VOS_STATUS_SUCCESS) || + (status == VOS_STATUS_E_EMPTY))) { + ++gwlan_logging.fw_log_pkt_drop_cnt; + spin_unlock_irqrestore( + &gwlan_logging.fw_log_pkt_lock, flags); + pr_err("%s: Failure walking packet chain", __func__); + /*keep returning pkts to avoid low resource cond*/ + vos_pkt_return_packet(pPacket); + return VOS_STATUS_E_FAILURE; + } + + free_pkt = gwlan_logging.fw_log_pkt_queue; + gwlan_logging.fw_log_pkt_queue = next_pkt; + /*returning head of pkt queue. latest pkts are important*/ + --gwlan_logging.fw_log_pkt_qcnt; + spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, + flags); + vos_pkt_return_packet(free_pkt); + } else { + spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, + flags); + } + + spin_lock_irqsave(&gwlan_logging.fw_log_pkt_lock, flags); + + if (gwlan_logging.fw_log_pkt_queue) { + vos_pkt_chain_packet(gwlan_logging.fw_log_pkt_queue, + pPacket, TRUE); + } else { + gwlan_logging.fw_log_pkt_queue = pPacket; + } + ++gwlan_logging.fw_log_pkt_qcnt; + + spin_unlock_irqrestore(&gwlan_logging.fw_log_pkt_lock, flags); + + set_bit(LOGGER_FW_LOG_PKT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + + return VOS_STATUS_SUCCESS; +} + +int wlan_queue_fw_mem_dump_for_app(vos_pkt_t *pPacket) +{ + unsigned long flags; + vos_pkt_t *next_pkt; + vos_pkt_t *free_pkt; + VOS_STATUS status = VOS_STATUS_E_FAILURE; + + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + if (gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_qcnt >= LOGGER_MAX_FW_MEM_DUMP_PKT_Q_LEN) { + status = vos_pkt_walk_packet_chain( + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue, &next_pkt, TRUE); + /*both "success" and "empty" are acceptable results*/ + if (!((status == VOS_STATUS_SUCCESS) || + (status == VOS_STATUS_E_EMPTY))) { + spin_unlock_irqrestore( + &gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + pr_err("%s: Failure walking packet chain", __func__); + /*keep returning pkts to avoid low resource cond*/ + vos_pkt_return_packet(pPacket); + return VOS_STATUS_E_FAILURE; + } + + free_pkt = gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue; + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue = next_pkt; + /*returning head of pkt queue. latest pkts are important*/ + --gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_qcnt; + ++gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_drop_cnt ; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, + flags); + pr_info("%s : fw mem_dump pkt cnt --> %d\n" ,__func__, gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_drop_cnt); + vos_pkt_return_packet(free_pkt); + } else { + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, + flags); + } + + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + + if (gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue) { + vos_pkt_chain_packet(gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue, + pPacket, TRUE); + } else { + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_queue = pPacket; + } + ++gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_pkt_qcnt; + + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + + set_bit(LOGGER_FW_MEM_DUMP_PKT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + + return VOS_STATUS_SUCCESS; +} + +int wlan_queue_logpkt_for_app(vos_pkt_t *pPacket, uint32 pkt_type) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + + if (pPacket == NULL) { + pr_err("%s: Null param", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + if (gwlan_logging.is_active == false) { + /*return all packets queued*/ + wlan_logging_flush_pkt_queue(); + + /*return currently received pkt*/ + vos_pkt_return_packet(pPacket); + return VOS_STATUS_E_FAILURE; + } + + switch (pkt_type) { + case WLAN_MGMT_FRAME_LOGS: + status = wlan_queue_data_mgmt_pkt_for_app(pPacket); + break; + + case WLAN_FW_LOGS: + status = wlan_queue_fw_log_pkt_for_app(pPacket); + break; + case WLAN_FW_MEMORY_DUMP: + status = wlan_queue_fw_mem_dump_for_app(pPacket); + break; + + default: + pr_info("%s: Unknown pkt received %d", __func__, pkt_type); + status = VOS_STATUS_E_INVAL; + break; + }; + + return status; +} + +void wlan_process_done_indication(uint8 type, uint32 reason_code) +{ + if (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)) + { + if ((type == WLAN_FW_LOGS) && + (wlan_is_log_report_in_progress() == TRUE)) + { + pr_info("%s: Setting LOGGER_FATAL_EVENT %d\n", + __func__, reason_code); + set_bit(LOGGER_FATAL_EVENT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + return; + } + + if ((type == WLAN_FW_LOGS) && reason_code && + vos_isFatalEventEnabled() && + vos_is_wlan_logging_enabled()) + { + if(wlan_is_log_report_in_progress() == TRUE) + { + pr_info("%s: Setting LOGGER_FATAL_EVENT %d\n", + __func__, reason_code); + set_bit(LOGGER_FATAL_EVENT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + else + { + unsigned long flags; + + /* Drop FW initiated fatal event for + * LIMIT_FW_FATAL_EVENT_MS if received for same reason. + */ + spin_lock_irqsave(&gwlan_logging.bug_report_lock, + flags); + if ((reason_code == + gwlan_logging.log_complete.last_fw_bug_reason) && + ((vos_timer_get_system_time() - + gwlan_logging.log_complete.last_fw_bug_timestamp) + < LIMIT_FW_FATAL_EVENT_MS)) { + spin_unlock_irqrestore( + &gwlan_logging.bug_report_lock, + flags); + pr_info("%s: Ignoring Fatal event from firmware for reason %d\n", + __func__, reason_code); + return; + } + gwlan_logging.log_complete.last_fw_bug_reason = + reason_code; + gwlan_logging.log_complete.last_fw_bug_timestamp = + vos_timer_get_system_time(); + spin_unlock_irqrestore(&gwlan_logging.bug_report_lock, + flags); + + /*Firmware Initiated*/ + pr_info("%s : FW triggered Fatal Event, reason_code : %d\n", __func__, + reason_code); + wlan_set_log_completion(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_FIRMWARE, + reason_code); + set_bit(LOGGER_FATAL_EVENT_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } + } + if(type == WLAN_FW_MEMORY_DUMP && vos_is_wlan_logging_enabled()) + { + pr_info("%s: Setting FW MEM DUMP LOGGER event\n", __func__); + set_bit(LOGGER_FW_MEM_DUMP_PKT_POST_DONE, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } +} +/** + * wlan_flush_host_logs_for_fatal() -flush host logs and send + * fatal event to upper layer. + */ +void wlan_flush_host_logs_for_fatal() +{ + unsigned long flags; + + if (wlan_is_log_report_in_progress()) { + pr_info("%s:flush all host logs Setting HOST_LOG_POST\n", + __func__); + + spin_lock_irqsave(&gwlan_logging.spin_lock, flags); + wlan_queue_logmsg_for_app(); + spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags); + + set_bit(HOST_LOG_POST, &gwlan_logging.event_flag); + wake_up_interruptible(&gwlan_logging.wait_queue); + } +} + + +/** + * wlan_is_logger_thread()- Check if threadid is + * of logger thread + * + * @threadId: passed threadid + * + * This function is called to check if threadid is + * of logger thread. + * + * Return: true if threadid is of logger thread. + */ +bool wlan_is_logger_thread(int threadId) +{ + return ((gwlan_logging.thread) && + (threadId == gwlan_logging.thread->pid)); +} + +int wlan_fwr_mem_dump_buffer_allocation(void) +{ + /*Allocate the dump memory as reported by fw. + or if feature not supported just report to the user */ + if(gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size <= 0) + { + pr_err("%s: fw_mem_dump_req not supported by firmware", __func__); + return -EFAULT; + } + gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc = + (uint8 *)vos_mem_vmalloc(gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size); + gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc = gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc; + if(NULL == gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc) + { + pr_err("%s: fw_mem_dump_req alloc failed for size %d bytes", __func__,gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size); + return -ENOMEM; + } + vos_mem_zero(gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc,gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size); + + return 0; +} + +/*set the current fw mem dump state*/ +void wlan_set_fwr_mem_dump_state(enum FW_MEM_DUMP_STATE fw_mem_dump_state) +{ + unsigned long flags; + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status = fw_mem_dump_state; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); +} +/*check for new request validity and free memory if present from previous request */ +bool wlan_fwr_mem_dump_test_and_set_write_allowed_bit(){ + unsigned long flags; + bool ret = false; + bool write_done = false; + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + + if(gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status == FW_MEM_DUMP_IDLE){ + ret = true; + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status = FW_MEM_DUMP_WRITE_IN_PROGRESS; + } + else if(gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status == FW_MEM_DUMP_WRITE_DONE){ + ret = true; + write_done = true; + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status = FW_MEM_DUMP_WRITE_IN_PROGRESS; + } + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + pr_info("%s:fw mem dump state --> %d ", __func__,gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status); + + if(write_done) + wlan_free_fwr_mem_dump_buffer(); + return ret; +} + +bool wlan_fwr_mem_dump_test_and_set_read_allowed_bit(){ + unsigned long flags; + bool ret=false; + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + if(gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status == FW_MEM_DUMP_WRITE_DONE || + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status == FW_MEM_DUMP_READ_IN_PROGRESS ){ + ret = true; + gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status = FW_MEM_DUMP_READ_IN_PROGRESS; + } + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + //pr_info("%s:fw mem dump state --> %d ", __func__,gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_status); + + return ret; +} +size_t wlan_fwr_mem_dump_fsread_handler(char __user *buf, + size_t count, loff_t *pos,loff_t* bytes_left) +{ + if (buf == NULL || gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc == NULL) + { + pr_err("%s : start loc : %p buf : %p ",__func__,gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc,buf); + return 0; + } + + if (*pos < 0) { + pr_err("Invalid start offset for memdump read"); + return 0; + } else if (*pos >= gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size || !count) { + pr_err("No more data to copy"); + return 0; + } else if (count > gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size - *pos) { + count = gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size - *pos; + } + if (copy_to_user(buf, gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc, count)) { + pr_err("%s copy to user space failed",__func__); + return 0; + } + /* offset(pos) should be updated here based on the copy done*/ + *pos += count; + *bytes_left = gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size - *pos; + return count; +} + +void wlan_set_svc_fw_mem_dump_req_cb (void * fw_mem_dump_req_cb, void * fw_mem_dump_req_cb_arg) +{ + unsigned long flags; + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb = fw_mem_dump_req_cb; + gwlan_logging.fw_mem_dump_ctx.svc_fw_mem_dump_req_cb_arg = fw_mem_dump_req_cb_arg; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); +} + +void wlan_free_fwr_mem_dump_buffer (void ) +{ + unsigned long flags; + void * tmp = NULL; + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + tmp = gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc; + gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc = NULL; + gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc = NULL; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + // Don't set fw_dump_max_size to 0, only free the buffera + if(tmp != NULL) + vos_mem_vfree((void *)tmp); +} + +void wlan_store_fwr_mem_dump_size(uint32 dump_size) +{ + unsigned long flags; + spin_lock_irqsave(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); + //Store the dump size + gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size = dump_size; + spin_unlock_irqrestore(&gwlan_logging.fw_mem_dump_ctx.fw_mem_dump_lock, flags); +} +/** + * wlan_indicate_mem_dump_complete() - When H2H for mem + * dump finish invoke the handler. + * + * This is a handler used to indicate user space about the + * availability for firmware memory dump via vendor event. + * + * Return: None + */ +void wlan_indicate_mem_dump_complete(bool status ) +{ + hdd_context_t *hdd_ctx; + void *vos_ctx; + int ret; + struct sk_buff *skb = NULL; + vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_ctx) { + pr_err("Invalid VOS context"); + return; + } + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + if(!hdd_ctx) { + pr_err("Invalid HDD context"); + return; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) { + pr_err("HDD context is not valid"); + return; + } + + + skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, + sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN); + + if (!skb) { + pr_err("cfg80211_vendor_event_alloc failed"); + return; + } + if(status) + { + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MEMDUMP_SIZE, + gwlan_logging.fw_mem_dump_ctx.fw_dump_max_size)) { + pr_err("nla put fail"); + goto nla_put_failure; + } + } + else + { + pr_err("memdump failed.Returning size 0 to user"); + if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MEMDUMP_SIZE, + 0)) { + pr_err("nla put fail"); + goto nla_put_failure; + } + } + /*indicate mem dump complete*/ + cfg80211_vendor_cmd_reply(skb); + pr_info("Memdump event sent successfully to user space : recvd size %d",(int)(gwlan_logging.fw_mem_dump_ctx.fw_dump_current_loc - gwlan_logging.fw_mem_dump_ctx.fw_dump_start_loc)); + return; + +nla_put_failure: + kfree_skb(skb); + return; +} +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * wlan_report_log_completion() - Report bug report completion to userspace + * @is_fatal: Type of event, fatal or not + * @indicator: Source of bug report, framework/host/firmware + * @reason_code: Reason for triggering bug report + * + * This function is used to report the bug report completion to userspace + * + * Return: None + */ +void wlan_report_log_completion(uint32_t is_fatal, + uint32_t indicator, + uint32_t reason_code) +{ + WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, + struct vos_event_wlan_log_complete); + + wlan_diag_event.is_fatal = is_fatal; + wlan_diag_event.indicator = indicator; + wlan_diag_event.reason_code = reason_code; + wlan_diag_event.reserved = 0; + + WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_LOG_COMPLETE); +} +#endif + +#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */ diff --git a/drivers/staging/prima/CORE/SVC/src/nlink/wlan_nlink_srv.c b/drivers/staging/prima/CORE/SVC/src/nlink/wlan_nlink_srv.c new file mode 100644 index 000000000000..facf905e8948 --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/src/nlink/wlan_nlink_srv.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** +* wlan_nlink_srv.c +* +* This file contains the definitions specific to the wlan_nlink_srv +* +******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vos_memory.h" + +//Global variables +static DEFINE_MUTEX(nl_srv_sem); +static struct sock *nl_srv_sock; +static nl_srv_msg_callback nl_srv_msg_handler[NLINK_MAX_CALLBACKS]; + +#ifdef WLAN_KD_READY_NOTIFIER +const char driverLoaded[] = "KNLREADY"; +const char driverUnLoaded[] = "KNLCLOSE"; +#endif /* WLAN_KD_READY_NOTIFIER */ + +//Forward declaration +static void nl_srv_rcv (struct sk_buff *sk); +static void nl_srv_rcv_skb (struct sk_buff *skb); +static void nl_srv_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh); + +/* + * Initialize the netlink service. + * Netlink service is usable after this. + */ +int nl_srv_init(void) +{ + int retcode = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + struct netlink_kernel_cfg cfg = { + .groups = WLAN_NLINK_MCAST_GRP_ID, + .input = nl_srv_rcv + }; +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + THIS_MODULE, +#endif + &cfg); +#else + nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_PROTO_FAMILY, + WLAN_NLINK_MCAST_GRP_ID, nl_srv_rcv, NULL, THIS_MODULE); +#endif + + if (nl_srv_sock != NULL) { + memset(nl_srv_msg_handler, 0, sizeof(nl_srv_msg_handler)); + } else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLINK: netlink_kernel_create failed"); + retcode = -ECONNREFUSED; + } + return retcode; +} + +/* + * Deinit the netlink service. + * Netlink service is unusable after this. + */ +#ifdef WLAN_KD_READY_NOTIFIER +void nl_srv_exit(int dst_pid) +#else +void nl_srv_exit(void) +#endif /* WLAN_KD_READY_NOTIFIER */ +{ +#ifdef WLAN_KD_READY_NOTIFIER + if (0 != dst_pid) + { + nl_srv_nl_close_indication(dst_pid); + } +#endif /* WLAN_KD_READY_NOTIFIER */ + netlink_kernel_release(nl_srv_sock); + nl_srv_sock = NULL; +} + +/* + * Register a message handler for a specified module. + * Each module (e.g. WLAN_NL_MSG_BTC )will register a + * handler to handle messages addressed to it. + */ +int nl_srv_register(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int retcode = 0; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + msg_handler != NULL) + { + nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = msg_handler; + } + else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: nl_srv_register failed for msg_type %d", msg_type); + retcode = -EINVAL; + } + + return retcode; +} +/* + * Unregister the message handler for a specified module. + */ +int nl_srv_unregister(tWlanNlModTypes msg_type, nl_srv_msg_callback msg_handler) +{ + int retcode = 0; + + if ((msg_type >= WLAN_NL_MSG_BASE) && (msg_type < WLAN_NL_MSG_MAX) && + (nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] == msg_handler)) + { + nl_srv_msg_handler[msg_type - WLAN_NL_MSG_BASE] = NULL; + } + else + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: nl_srv_unregister failed for msg_type %d", msg_type); + retcode = -EINVAL; + } + + return retcode; +} + +/* + * Unicast the message to the process in user space identfied + * by the dst-pid + */ +int nl_srv_ucast(struct sk_buff *skb, int dst_pid, int flag) +{ + int err = -EINVAL; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + NETLINK_CB(skb).pid = 0; //sender's pid +#else + NETLINK_CB(skb).portid = 0; //sender's pid +#endif + NETLINK_CB(skb).dst_group = 0; //not multicast + if (nl_srv_sock != NULL) { + err = netlink_unicast(nl_srv_sock, skb, + dst_pid, flag); + if (err < 0) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: netlink_unicast to pid[%d] failed, ret[%d]", dst_pid, err); + } + else + dev_kfree_skb(skb); + + return err; +} + +/* + * Broadcast the message. Broadcast will return an error if + * there are no listeners + */ +int nl_srv_bcast(struct sk_buff *skb) +{ + int err = -EINVAL; + int flags = GFP_KERNEL; + + if (in_interrupt() || irqs_disabled() || in_atomic()) + flags = GFP_ATOMIC; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) + NETLINK_CB(skb).pid = 0; //sender's pid +#else + NETLINK_CB(skb).portid = 0; //sender's pid +#endif + NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; //destination group + if (nl_srv_sock != NULL) { + err = netlink_broadcast(nl_srv_sock, skb, 0, + WLAN_NLINK_MCAST_GRP_ID, flags); + + if ((err < 0) && (err != -ESRCH)) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: netlink_broadcast failed err = %d", err); + } + else + dev_kfree_skb(skb); + + + return err; +} + +/* + * Processes the Netlink socket input queue. + * Dequeue skb's from the socket input queue and process + * all the netlink messages in that skb, before moving + * to the next skb. + */ +static void nl_srv_rcv (struct sk_buff *sk) +{ + mutex_lock(&nl_srv_sem); + nl_srv_rcv_skb(sk); + mutex_unlock(&nl_srv_sem); +} + +/* + * Each skb could contain multiple Netlink messages. Process all the + * messages in one skb and discard malformed skb's silently. + */ +static void nl_srv_rcv_skb (struct sk_buff *skb) +{ + struct nlmsghdr * nlh; + + while (skb->len >= NLMSG_SPACE(0)) { + u32 rlen; + + nlh = (struct nlmsghdr *)skb->data; + + if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "NLINK: Invalid " + "Netlink message: skb[%p], len[%d], nlhdr[%p], nlmsg_len[%d]", + skb, skb->len, nlh, nlh->nlmsg_len); + return; + } + + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + nl_srv_rcv_msg(skb, nlh); + skb_pull(skb, rlen); + } +} + +/* + * Process a netlink message. + * Each netlink message will have a message of type tAniMsgHdr inside. + */ +static void nl_srv_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh) +{ + int type; + + /* Only requests are handled by kernel now */ + if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: Received Invalid NL Req type [%x]", nlh->nlmsg_flags); + return; + } + + type = nlh->nlmsg_type; + + /* Unknown message */ + if (type < WLAN_NL_MSG_BASE || type >= WLAN_NL_MSG_MAX) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: Received Invalid NL Msg type [%x]", type); + return; + } + + /* + * All the messages must at least carry the tAniMsgHdr + * Drop any message with invalid length + */ + if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(tAniMsgHdr))) { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: Received NL Msg with invalid len[%x]", nlh->nlmsg_len); + return; + } + + // turn type into dispatch table offset + type -= WLAN_NL_MSG_BASE; + + // dispatch to handler + if (nl_srv_msg_handler[type] != NULL) { + (nl_srv_msg_handler[type])(skb); + } else { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + "NLINK: No handler for Netlink Msg [0x%X]", type); + } +} + +#ifdef WLAN_KD_READY_NOTIFIER +/* + * Send Net Link interface ready indication to application daemon + * Each netlink message will have a message of type tAniMsgHdr inside. + */ +void nl_srv_nl_ready_indication +( + void +) +{ + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + int err; + + skb = alloc_skb(NLMSG_SPACE(sizeof(driverLoaded)), GFP_KERNEL); + if (NULL == skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLINK: skb alloc fail %s", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_len = sizeof(driverLoaded); + vos_mem_copy(((char *)nlh) + sizeof(struct nlmsghdr), + driverLoaded, + sizeof(driverLoaded)); + skb_put(skb, NLMSG_SPACE(sizeof(driverLoaded))); + + /* sender is in group 1<<0 */ + NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; + + /*multicast the message to all listening processes*/ + err = netlink_broadcast(nl_srv_sock, skb, 0, 1, GFP_KERNEL); + if (err && (err != -ESRCH)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "NLINK: Ready Indication Send Fail %s, err %d", + __func__, err); + } + return; +} + +/* + * Send Net Link interface close indication to application daemon + * Each netlink message will have a message of type tAniMsgHdr inside. + */ +void nl_srv_nl_close_indication +( + int pid +) +{ + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + int err; + + skb = alloc_skb(sizeof(driverUnLoaded),GFP_KERNEL); + if (NULL == skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "NLINK: skb alloc fail %s", __func__); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + nlh->nlmsg_pid = 0; /* from kernel */ + nlh->nlmsg_flags = 0; + nlh->nlmsg_seq = 0; + nlh->nlmsg_len = sizeof(driverUnLoaded); + vos_mem_copy(((char *)nlh) + sizeof(struct nlmsghdr), + driverUnLoaded, + sizeof(driverUnLoaded)); + skb_put(skb, NLMSG_SPACE(sizeof(driverUnLoaded))); + + /* sender is in group 1<<0 */ + NETLINK_CB(skb).dst_group = 0; + err = netlink_unicast(nl_srv_sock, skb, pid, MSG_DONTWAIT); + if (err) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_LOW, + "NLINK: Close Indication Send Fail %s", __func__); + } + + return; +} +#endif /* WLAN_KD_READY_NOTIFIER */ + +/* + * nl_srv_is_initialized() - This function is used check if the netlink + * service is initialized + * + * This function is used check if the netlink service is initialized + * + * Return: Return -EPERM if the service is not initialized + * + */ +int nl_srv_is_initialized() +{ + if (nl_srv_sock) + return 0; + else + return -EPERM; +} diff --git a/drivers/staging/prima/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c b/drivers/staging/prima/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c new file mode 100644 index 000000000000..5db47dd15761 --- /dev/null +++ b/drivers/staging/prima/CORE/SVC/src/ptt/wlan_ptt_sock_svc.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/****************************************************************************** + * wlan_ptt_sock_svc.c + * + ******************************************************************************/ +#ifdef PTT_SOCK_SVC_ENABLE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PTT_SOCK_DEBUG +#ifdef PTT_SOCK_DEBUG +#define PTT_TRACE(level, args...) VOS_TRACE( VOS_MODULE_ID_HDD, level, ## args) +#else +#define PTT_TRACE(level, args...) +#endif +// Global variables +static struct hdd_context_s *pAdapterHandle; +//Utility function to perform endianess swap +static void ptt_sock_swap_32(void *pBuffer, unsigned int len) +{ + v_U32_t *pBuf32, data; + v_U8_t *pBuf8; + unsigned int i; + len &= ~(sizeof(v_U32_t)-1); + pBuf32 = (v_U32_t *) pBuffer; + pBuf8 = (v_U8_t *) pBuffer; + for (i = 0; i < len; i += 4, ++pBuf32, pBuf8 += 4) { + data = *pBuf32; + pBuf8[0] = (v_U8_t) ((data >> 24) & 0xff); + pBuf8[1] = (v_U8_t) ((data >> 16) & 0xff); + pBuf8[2] = (v_U8_t) ((data >> 8) & 0xff); + pBuf8[3] = (v_U8_t) ((data >> 0) & 0xff); + } +} +#ifdef PTT_SOCK_DEBUG_VERBOSE +//Utility function to perform a hex dump +static void ptt_sock_dump_buf(const unsigned char * pbuf, int cnt) +{ + int i; + for (i = 0; i < cnt ; i++) { + if ((i%16)==0) + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"\n%p:", pbuf); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO," %02X", *pbuf); + pbuf++; + } + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"\n"); +} +#endif +//Utility function to send a netlink message to an application in user space +int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid, int flag) +{ + int err = -1; + int payload_len; + int tot_msg_len; + tAniNlHdr *wnl; + struct sk_buff *skb; + struct nlmsghdr *nlh; + int wmsg_length = be16_to_cpu(wmsg->length); + static int nlmsg_seq; + if (radio < 0 || radio > ANI_MAX_RADIOS) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]\n", + __func__, radio); + return -EINVAL; + } + payload_len = wmsg_length + sizeof(wnl->radio) + sizeof(tAniHdr); + tot_msg_len = NLMSG_SPACE(payload_len); + if ((skb = dev_alloc_skb(tot_msg_len)) == NULL) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: dev_alloc_skb() failed for msg size[%d]\n", + __func__, tot_msg_len); + return -ENOMEM; + } + nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, NLM_F_REQUEST); + if (NULL == nlh) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]\n", + __func__, tot_msg_len); + kfree_skb(skb); + return -ENOMEM; + } + wnl = (tAniNlHdr *) nlh; + wnl->radio = radio; + vos_mem_copy(&wnl->wmsg, wmsg, wmsg_length); +#ifdef PTT_SOCK_DEBUG_VERBOSE + ptt_sock_dump_buf((const unsigned char *)skb->data, skb->len); +#endif + if (pid != INVALID_PID) + { + err = nl_srv_ucast(skb, pid, flag); + } + else + { + err = nl_srv_bcast(skb); + } + if (err) { + PTT_TRACE(VOS_TRACE_LEVEL_INFO, + "%s:Failed sending Msg Type [0x%X] to pid[%d]\n", + __func__, be16_to_cpu(wmsg->type), pid); + } + return err; +} +/* + * Process tregisteration request and send registration response messages + * to the PTT Socket App in user space + */ +static void ptt_sock_proc_reg_req(tAniHdr *wmsg, int radio) +{ + tAniNlAppRegReq *reg_req; + tAniNlAppRegRsp rspmsg; + reg_req = (tAniNlAppRegReq *)(wmsg + 1); + memset((char *)&rspmsg, 0, sizeof(rspmsg)); + //send reg response message to the application + rspmsg.ret = ANI_NL_MSG_OK; + rspmsg.regReq.type = reg_req->type; +#ifdef WLAN_KD_READY_NOTIFIER + /* NL client try to registration + * to make sure connection, broadcast READY notification */ + nl_srv_nl_ready_indication(); +#endif /* WLAN_KD_READY_NOTIFIER */ + /*Save the pid*/ + pAdapterHandle->ptt_pid = reg_req->pid; + rspmsg.regReq.pid= reg_req->pid; + rspmsg.wniHdr.type = cpu_to_be16(ANI_MSG_APP_REG_RSP); + rspmsg.wniHdr.length = cpu_to_be16(sizeof(rspmsg.wniHdr)); + if (ptt_sock_send_msg_to_app((tAniHdr *)&rspmsg.wniHdr, radio, + ANI_NL_MSG_PUMAC, reg_req->pid, MSG_DONTWAIT) < 0) + { + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Error sending ANI_MSG_APP_REG_RSP to pid[%d]\n", + __func__, reg_req->pid); + } +} +/* + * Process all the messages from the PTT Socket App in user space + */ +static void ptt_proc_pumac_msg(struct sk_buff * skb, tAniHdr *wmsg, int radio) +{ + u16 ani_msg_type = be16_to_cpu(wmsg->type); + switch(ani_msg_type) + { + case ANI_MSG_APP_REG_REQ: + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_MSG_APP_REG_REQ [0x%X]\n", + __func__, ani_msg_type); + ptt_sock_proc_reg_req(wmsg, radio); + break; + default: + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Received Unknown Msg Type[0x%X]\n", + __func__, ani_msg_type); + break; + } +} +/* + * Process all the messages from the Quarky Client + */ +static void ptt_proc_quarky_msg(tAniNlHdr *wnl, tAniHdr *wmsg, int radio) +{ + u16 ani_msg_type = be16_to_cpu(wmsg->type); + v_U32_t reg_addr; + v_U32_t reg_val; + v_U32_t len_payload; + v_U8_t* buf; + unsigned int arg1, arg2, arg3, arg4, cmd; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + if (radio < 0 || radio > ANI_MAX_RADIOS) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: ANI Msg [0x%X] invalid radio id [%d]\n", + __func__, ani_msg_type, radio); + return; + } + if(ani_msg_type == ANI_MSG_APP_REG_REQ) + { + ptt_sock_proc_reg_req(wmsg, radio); + } + else + { + switch (ani_msg_type) + { + case PTT_MSG_READ_REGISTER: + reg_addr = *(v_U32_t*) ((char*)wmsg + 8); + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_REGISTER [0x%08X]\n", + __func__, reg_addr); + vosStatus = sme_DbgReadRegister(pAdapterHandle->hHal, reg_addr, ®_val); + *(v_U32_t*) ((char*)wmsg + 12) = reg_val; + if(vosStatus != VOS_STATUS_SUCCESS) + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Read Register [0x%08X] failed!!\n", + __func__, reg_addr); + ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT); + break; + case PTT_MSG_WRITE_REGISTER: + reg_addr = *(v_U32_t*) ((const unsigned char*)wmsg + 8); + reg_val = *(v_U32_t*)((const unsigned char*)wmsg + 12); + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_WRITE_REGISTER Addr [0x%08X] value [0x%08X]\n", + __func__, reg_addr, reg_val); + vosStatus = sme_DbgWriteRegister(pAdapterHandle->hHal, reg_addr, reg_val); + if(vosStatus != VOS_STATUS_SUCCESS) + { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Write Register [0x%08X] value [0x%08X] failed!!\n", + __func__, reg_addr, reg_val); + } + //send message to the app + ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT); + break; + case PTT_MSG_READ_MEMORY: + reg_addr = *(v_U32_t*) ((char*)wmsg + 8); + len_payload = *(v_U32_t*) ((char*)wmsg + 12); + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_READ_MEMORY addr [0x%08X] bytes [0x%08X]\n", + __func__, reg_addr, len_payload); + buf = (v_U8_t*)wmsg + 16; + vosStatus = sme_DbgReadMemory(pAdapterHandle->hHal, reg_addr, buf, len_payload); + if(vosStatus != VOS_STATUS_SUCCESS) { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory read failed for [0x%08X]!!\n", + __func__, reg_addr); + } + ptt_sock_swap_32(buf, len_payload); + //send message to the app + ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT); + break; + case PTT_MSG_WRITE_MEMORY: + reg_addr = *(v_U32_t*) ((char*)wmsg + 8); + len_payload = *(v_U32_t*) ((char*)wmsg + 12); + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_DBG_WRITE_MEMORY addr [0x%08X] bytes [0x%08X]\n", + __func__, reg_addr, len_payload); + buf = (v_U8_t*)wmsg + 16; + ptt_sock_swap_32(buf, len_payload); + vosStatus = sme_DbgWriteMemory(pAdapterHandle->hHal, reg_addr, buf, len_payload); + if(vosStatus != VOS_STATUS_SUCCESS) + { + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Memory write failed for addr [0x%08X]!!\n", + __func__, reg_addr); + } + //send message to the app + ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT); + break; + case PTT_MSG_LOG_DUMP_DBG: + cmd = *(unsigned int *) ((char *)wmsg + 8); + arg1 = *(unsigned int *) ((char *)wmsg + 12); + arg2 = *(unsigned int *) ((char *)wmsg + 16); + arg3 = *(unsigned int *) ((char *)wmsg + 20); + arg4 = *(unsigned int *) ((char *)wmsg + 24); + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: PTT_MSG_LOG_DUMP_DBG %d arg1 %d arg2 %d arg3 %d arg4 %d\n", + __func__, cmd, arg1, arg2, arg3, arg4); + //send message to the app + ptt_sock_send_msg_to_app(wmsg, 0, ANI_NL_MSG_PUMAC, wnl->nlh.nlmsg_pid, MSG_DONTWAIT); + break; + case PTT_MSG_FTM_CMDS_TYPE: + wlan_hdd_process_ftm_cmd(pAdapterHandle,wnl); + break; + default: + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Unknown ANI Msg [0x%X], length [0x%X]\n", + __func__, ani_msg_type, be16_to_cpu(wmsg->length )); + break; + } + } +} +/* + * Process all the Netlink messages from PTT Socket app in user space + */ +static int ptt_sock_rx_nlink_msg (struct sk_buff * skb) +{ + tAniNlHdr *wnl; + int radio; + int type; + + if (0 != wlan_hdd_validate_context(pAdapterHandle)) + return -EINVAL; + + wnl = (tAniNlHdr *) skb->data; + radio = wnl->radio; + type = wnl->nlh.nlmsg_type; + switch (type) { + case ANI_NL_MSG_PUMAC: //Message from the PTT socket APP + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_NL_MSG_PUMAC Msg [0x%X]\n", + __func__, type); + ptt_proc_pumac_msg(skb, &wnl->wmsg, radio); + break; + case ANI_NL_MSG_PTT: //Message from Quarky GUI + PTT_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Received ANI_NL_MSG_PTT Msg [0x%X]\n", + __func__, type); + ptt_proc_quarky_msg(wnl, &wnl->wmsg, radio); + break; + default: + PTT_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Unknown NL Msg [0x%X]\n",__func__, type); + break; + } + return 0; +} +int ptt_sock_activate_svc(void *pAdapter) +{ + pAdapterHandle = (struct hdd_context_s*)pAdapter; + nl_srv_register(ANI_NL_MSG_PUMAC, ptt_sock_rx_nlink_msg); + nl_srv_register(ANI_NL_MSG_PTT, ptt_sock_rx_nlink_msg); +#ifdef WLAN_KD_READY_NOTIFIER + nl_srv_nl_ready_indication(); +#endif /* WLAN_KD_READY_NOTIFIER */ + return 0; +} + +int ptt_sock_deactivate_svc(hdd_context_t *pHddCtx) +{ + nl_srv_unregister(ANI_NL_MSG_PUMAC, ptt_sock_rx_nlink_msg); + nl_srv_unregister(ANI_NL_MSG_PTT, ptt_sock_rx_nlink_msg); + return 0; +} + +#endif //PTT_SOCK_SVC_ENABLE diff --git a/drivers/staging/prima/CORE/SYS/common/inc/wlan_qct_sys.h b/drivers/staging/prima/CORE/SYS/common/inc/wlan_qct_sys.h new file mode 100644 index 000000000000..f85d29d6d81b --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/common/inc/wlan_qct_sys.h @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( WLAN_QCT_SYS_H__ ) +#define WLAN_QCT_SYS_H__ + +/**=========================================================================== + + \file wlan_qct_sys.h + + \brief System module API + + ==========================================================================*/ + +/* $HEADER$ */ + +/*--------------------------------------------------------------------------- + Include files + -------------------------------------------------------------------------*/ +#include +#include +#include + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------- + Type declarations + -------------------------------------------------------------------------*/ + + /*---------------------------------------------------------------------------- + + \brief sysResponseCback() - SYS async resonse callback + + This is a protype for the callback function that SYS makes to various + modules in the system. + + \param pUserData - user data that is passed to the Callback function + when it is invoked. + + \return Nothing + + \sa sysMcStart(), sysMcThreadProbe(), sysTxThreadProbe() + + --------------------------------------------------------------------------*/ +typedef v_VOID_t ( * sysResponseCback ) ( v_VOID_t *pUserData ); +typedef v_VOID_t ( * sysThreadProbeCback ) ( int threadId ); + + + + +typedef enum +{ + SYS_MSG_ID_MC_START, + SYS_MSG_ID_MC_THR_PROBE, + SYS_MSG_ID_MC_TIMER, + + SYS_MSG_ID_TX_THR_PROBE, + SYS_MSG_ID_TX_TIMER, + + SYS_MSG_ID_RX_TIMER, + + SYS_MSG_ID_MC_STOP, + SYS_MSG_ID_FTM_RSP, + + SYS_MSG_ID_RX_THR_PROBE, +} SYS_MSG_ID; + +/*--------------------------------------------------------------------------- + Preprocessor definitions and constants + -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Function declarations and documenation + -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief sysBuildMessageHeader() - Build / initialize a SYS message header + + This function will initialize the SYS message header with the message type + and any internal fields needed for a new SYS message. This function sets + all but the message body, which is up to the caller to setup based on the + specific message being built. + + \note There are internal / reserved items in a SYS message that must be + set correctly for the message to be recognized as a SYS message by + the SYS message handlers. It is important for every SYS message to + be setup / built / initialized through this function. + + \param sysMsgId - a valid message ID for a SYS message. See the + SYS_MSG_ID enum for all the valid SYS message IDs. + + \param pMsg - pointer to the message structure to be setup. + + \return + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysBuildMessageHeader( SYS_MSG_ID sysMsgId, vos_msg_t *pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysOpen() - Open (initialize) the SYS module. + + This function opens the SYS modules. All SYS resources are allocated + as a result of this open call. + + \param pVosContext - pointer to the VOS Context (from which all other + context entities can be derived). + + \return VOS_STATUS_SUCCESS - the SYS module is open. All resources needed + for operation of the SYS modules are allocated and initialized. + + VOS_STATUS_E_RESOURCES - the SYS module open failed because needed + system resources are not available. + + VOS_STATUS_E_FAILURE - the SYS module open failed due to some + unknown reason. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysOpen( v_CONTEXT_t pVosContext ); + + +/*---------------------------------------------------------------------------- + + \brief sysMcStart() - start the system Main Controller thread. + + This function starts the SYS (Main Controller) module. Starting this + module triggers the CFG download to the 'legacy' MAC software. + + \param pVosContext - pointer to the VOS Context + + \param userCallback - this is a callback that is called when the SYS + has completed the 'start' funciton. + + \param pUserData - pointer to some user data entity that is passed to + the callback function as a parameter when invoked. + + \return VOS_STATUS_SUCCESS - + + \todo: We have not 'status' on the callback. How do we notify the + callback that there is a failure ? + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysMcStart( v_CONTEXT_t pVosContext, sysResponseCback userCallback, + v_VOID_t *pUserData ); + + +/*---------------------------------------------------------------------------- + + \brief sysStop() - Stop the SYS module. + + This function stops the SYS module. + + \todo: What else do we need to do on sysStop()? + + \param pVosContext - pointer to the VOS Context + + \return VOS_STATUS_SUCCESS - the SYS module is stopped. + + VOS_STATUS_E_FAILURE - the SYS module open failed to stop. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysStop( v_CONTEXT_t pVosContext ); + + +/*---------------------------------------------------------------------------- + + \brief sysClose() - Close the SYS module. + + This function closes the SYS module. All resources allocated during + sysOpen() are free'd and returned to the system. The Sys module is unable + to operate until opened again through a call to sysOpen(). + + \param pVosContext - pointer to the VOS Context + + \return VOS_STATUS_SUCCESS - the SYS module is closed. + + VOS_STATUS_E_FAILURE - the SYS module open failed to close + + \sa sysOpen(), sysMcStart() + + --------------------------------------------------------------------------*/ +VOS_STATUS sysClose( v_CONTEXT_t pVosContext ); + + +/*---------------------------------------------------------------------------- + + \brief sysMcThreadProbe() - Probe the SYS Main Controller thread + + This function is called during initialization to 'probe' the Main Controller + thread. Probing means a specific message is posted to the SYS module to + assure the Main Controller thread is operating and processing messages + correctly. + + Following the successful 'probe' of the Main Controller thread, the + callback specified on this function is called to notify another entity + that the Main Controller is operational. + + \param pVosContext - pointer to the VOS Context + + \param userCallback - this is a callback that is called when the SYS + has completed probing the Main Controller thread. + + \param pUserData - pointer to some user data entity that is passed to + the callback function as a parameter when invoked. + + \return VOS_STATUS_SUCCESS - + \todo: how do we tell the callback there is a failure? + + \sa sysOpen(), sysMcStart() + + --------------------------------------------------------------------------*/ +v_VOID_t sysMcThreadProbe( v_CONTEXT_t pVosContex, sysResponseCback userCallback, + v_VOID_t *pUserData ); + +/*---------------------------------------------------------------------------- + + \brief sysTxThreadProbe() - Probe the Tx thread + + This function is called during initialization to 'probe' the Tx + thread. Probing means a specific message is posted to the SYS module to + assure the Tx is operating and processing messages correctly. + + Following the successful 'probe' of the Tx, the callback specified + on this function is called to notify another entity that the Tx thread + is operational. + + \param pVosContext - pointer to the VOS Context + + \param userCallback - this is a callback that is called when the SYS + has completed probing the Tx thread. + + \param pUserData - pointer to some user data entity that is passed to + the callback function as a parameter when invoked. + + \return VOS_STATUS_SUCCESS - + \todo: how do we tell the callback there is a failure? + + \sa sysOpen(), sysMcStart() + + --------------------------------------------------------------------------*/ +v_VOID_t sysTxThreadProbe( v_CONTEXT_t pVosContex, sysResponseCback userCallback, + v_VOID_t *pUserData ); + +/*---------------------------------------------------------------------------- + + \brief sysMcProcessMsg() - process SYS messages on the Main Controller thread + + This function processes SYS Messages on the Main Controller thread. + SYS messages consist of all 'legacy' messages (messages bound for legacy + modules like LIM, HAL, PE, etc.) as well as newly defined SYS message + types. + + SYS messages are identified by their type (in the SYS_MESSAGES enum) as + well as a 'cookie' that is in the reserved field of the message structure. + This 'cookie' is introduced to prevent any message type/ID conflicts with + the 'legacy' message types. + + Any module attempting to post a message to the SYS module must set the + message type to one of the types in the SYS_MESSAGE enum *and* must also + set the Reserved field in the message body to SYS_MSG_COOKIE. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - pointer to the message to be processed. + + \return - VOS_STATUS_SUCCESS - the message was processed successfully. + + VOS_STATUS_E_BADMSG - a bad (unknown type) message was received + and subsequently not processed. + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysMcProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysTxProcessMsg() - process SYS messages on the Tx thread + + This function processes SYS Messages on the Tx thread. + SYS messages consist of all 'legacy' messages (messages bound for legacy + modules like LIM, HAL, PE, etc.) as well as newly defined SYS message + types. + + SYS messages are identified by their type (in the SYS_MESSAGES enum) as + well as a 'cookie' that is in the reserved field of the message structure. + This 'cookie' is introduced to prevent any message type/ID conflicts with + the 'legacy' message types. + + Any module attempting to post a message to the SYS module must set the + message type to one of the types in the SYS_MESSAGE enum *and* must also + set the Reserved field in the message body to SYS_MSG_COOKIE. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - pointer to the message to be processed. + + \return - VOS_STATUS_SUCCESS - the message was processed successfully. + + VOS_STATUS_E_BADMSG - a bad (unknown type) message was received + and subsequently not processed. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysTxProcessMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysTxProcessMsg() - process SYS messages on the Rx thread + + This function processes SYS Messages on the Rx thread. + SYS messages consist of all 'legacy' messages (messages bound for legacy + modules like LIM, HAL, PE, etc.) as well as newly defined SYS message + types. + + SYS messages are identified by their type (in the SYS_MESSAGES enum) as + well as a 'cookie' that is in the reserved field of the message structure. + This 'cookie' is introduced to prevent any message type/ID conflicts with + the 'legacy' message types. + + Any module attempting to post a message to the SYS module must set the + message type to one of the types in the SYS_MESSAGE enum *and* must also + set the Reserved field in the message body to SYS_MSG_COOKIE. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - pointer to the message to be processed. + + \return - VOS_STATUS_SUCCESS - the message was processed successfully. + + VOS_STATUS_E_BADMSG - a bad (unknown type) message was received + and subsequently not processed. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS sysRxProcessMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysMcFreeMsg() - free a message queue'd to the Main Controller thread + + This fnction will free a SYS Message that is pending in the main controller + thread queue. These messages are free'd when the message queue needs to be + purged, for example during a Reset of Shutdown of the system. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - the message to be free'd + + \return Nothing. + + --------------------------------------------------------------------------*/ +v_VOID_t sysMcFreeMsg( v_CONTEXT_t pVosContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief sysTxFreeMsg() - free a message queue'd to the Tx thread + + This fnction will free a SYS Message that is pending in the Tx + thread queue. These messages are free'd when the message queue needs to be + purged, for example during a Reset of Shutdown of the system. + + \param pVosContext - pointer to the VOS Context + + \param pMsg - the message to be free'd + + \return Nothing. + + --------------------------------------------------------------------------*/ +v_VOID_t sysTxFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ); + +/*---------------------------------------------------------------------------- + + \brief wlan_sys_ftm() - FTM Cmd Response from halPhy + + This fnction is called by halPhy and carried the FTM command response. + This message is handled by SYS thread and finally the message will be convyed to used space + + + \param pttMsgBuffer - pointer to the pttMsgBuffer + + + \return Nothing. + + --------------------------------------------------------------------------*/ + +void wlan_sys_ftm(void *pMsgPtr); +void wlan_sys_probe(void); + + +#endif // WLAN_QCT_SYS_H__ + diff --git a/drivers/staging/prima/CORE/SYS/common/src/wlan_qct_sys.c b/drivers/staging/prima/CORE/SYS/common/src/wlan_qct_sys.c new file mode 100644 index 000000000000..11f9fe5636e2 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/common/src/wlan_qct_sys.c @@ -0,0 +1,788 @@ +/* + * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + W L A N S Y S T E M M O D U L E + + +DESCRIPTION + This file contains the system module that implements the 'exectution model' + in the Gen6 host software. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ----------------------------------------------------- +12/15/08 sho Resolved AMSS compiler errors and warnings when this + is being ported from WM +07/02/08 lac Added support for eWNI_SME_START_REQ/RSP in init seq +06/26/08 hba Added implementation of mbReceiveMBMsg() +06/26/08 lac Created module. + +===========================================================================*/ + + +#include +#include + +#include // needed for tSirRetStatus +#include // needed for tSirMbMsg +#include // needed for SIR_... message types +#include // needed for WNI_... message types +#include "aniGlobal.h" +#include "wlan_qct_wda.h" +#include "sme_Api.h" +#include "macInitApi.h" +#include "vos_sched.h" + +VOS_STATUS WLANFTM_McProcessMsg (v_VOID_t *message); + + + +// Cookie for SYS messages. Note that anyone posting a SYS Message has to +// write the COOKIE in the reserved field of the message. The SYS Module +// relies on this COOKIE +#define FTM_SYS_MSG_COOKIE 0xFACE + +#define SYS_MSG_COOKIE ( 0xFACE ) + +// need to define FIELD_OFFSET for non-WM platforms +#ifndef FIELD_OFFSET +#define FIELD_OFFSET(x,y) offsetof(x,y) +#endif + +VOS_STATUS sys_SendSmeStartReq( v_CONTEXT_t pVosContext ); + +// add this to the sys Context data... ? +typedef struct +{ + sysResponseCback mcStartCB; + v_VOID_t * mcStartUserData; + +} sysContextData; + +// sysStop 20 Seconds timeout +#define SYS_STOP_TIMEOUT 20000 +static vos_event_t gStopEvt; + +VOS_STATUS sysBuildMessageHeader( SYS_MSG_ID sysMsgId, vos_msg_t *pMsg ) +{ + pMsg->type = sysMsgId; + pMsg->reserved = SYS_MSG_COOKIE; + + return( VOS_STATUS_SUCCESS ); +} + + +VOS_STATUS sysOpen( v_CONTEXT_t pVosContext ) +{ + return( VOS_STATUS_SUCCESS ); +} + + + +v_VOID_t sysStopCompleteCb +( + v_VOID_t *pUserData +) +{ + vos_event_t* pStopEvt = (vos_event_t *) pUserData; + VOS_STATUS vosStatus; +/*-------------------------------------------------------------------------*/ + + vosStatus = vos_event_set( pStopEvt ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) ); + +} /* vos_sys_stop_complete_cback() */ + +VOS_STATUS sysStop( v_CONTEXT_t pVosContext ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t sysMsg; + v_U8_t evtIndex; + + /* Initialize the stop event */ + vosStatus = vos_event_init( &gStopEvt ); + + if(! VOS_IS_STATUS_SUCCESS( vosStatus )) + { + return vosStatus; + } + + /* post a message to SYS module in MC to stop SME and MAC */ + sysBuildMessageHeader( SYS_MSG_ID_MC_STOP, &sysMsg ); + + // Save the user callback and user data + + // finished. + sysMsg.callback = sysStopCompleteCb; + sysMsg.bodyptr = (void *) &gStopEvt; + + // post the message.. + vosStatus = vos_mq_post_message( VOS_MQ_ID_SYS, &sysMsg ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vosStatus = VOS_STATUS_E_BADMSG; + } + + vosStatus = vos_wait_events( &gStopEvt, 1, SYS_STOP_TIMEOUT, &evtIndex ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) ); + + vosStatus = vos_event_destroy( &gStopEvt ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) ); + + return( vosStatus ); +} + + +VOS_STATUS sysClose( v_CONTEXT_t pVosContext ) +{ + return( VOS_STATUS_SUCCESS ); +} + + + + + + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( push ) +#pragma pack( 1 ) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#pragma pack( 1 ) +#endif + +typedef struct sPolFileVersion +{ + unsigned char MajorVersion; + unsigned char MinorVersion; + unsigned char Suffix; + unsigned char Build; + +} tPolFileVersion; + + +typedef struct sPolFileHeader +{ + tPolFileVersion FileVersion; + tPolFileVersion HWCapabilities; + unsigned int FileLength; + unsigned int NumDirectoryEntries; + +} tPolFileHeader; + + +typedef enum ePolFileDirTypes +{ + ePOL_DIR_TYPE_BOOTLOADER = 0, + ePOL_DIR_TYPE_STA_FIRMWARE, + ePOL_DIR_TYPE_AP_FIRMWARE, + ePOL_DIR_TYPE_DIAG_FIRMWARE, + ePOL_DIR_TYPE_STA_CONFIG, + ePOL_DIR_TYPE_AP_CONFIG + +} tPolFileDirTypes; + + +typedef struct sPolFileDirEntry +{ + unsigned int DirEntryType; + unsigned int DirEntryFileOffset; + unsigned int DirEntryLength; + +} tPolFileDirEntry; + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack( pop ) +#endif + + +static unsigned short polFileChkSum( unsigned short *FileData, unsigned long NumWords ) +{ + unsigned long Sum; + + for ( Sum = 0; NumWords > 0; NumWords-- ) + { + Sum += *FileData++; + } + + Sum = (Sum >> 16) + (Sum & 0xffff); // add carry + Sum += (Sum >> 16); // maybe last unsigned short + + return( (unsigned short)( ~Sum ) ); +} + +v_BOOL_t sys_validateStaConfig( void *pImage, unsigned long cbFile, + void **ppStaConfig, v_SIZE_t *pcbStaConfig ) +{ + v_BOOL_t fFound = VOS_FALSE; + tPolFileHeader *pFileHeader = NULL; + tPolFileDirEntry *pDirEntry = NULL; + v_U32_t idx; + + do + { + // Compute the checksum before bothering to copy... + if ( polFileChkSum( ( v_U16_t *)pImage, cbFile / sizeof( v_U16_t ) ) ) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to validate the checksum for CFG binary" ); + break; + } + + pFileHeader = (tPolFileHeader *)pImage; + + *ppStaConfig = NULL; + *pcbStaConfig = 0; + + pDirEntry = ( tPolFileDirEntry* ) ( pFileHeader + 1 ); + + for ( idx = 0; idx < pFileHeader->NumDirectoryEntries; ++idx ) + { + if ( ePOL_DIR_TYPE_STA_CONFIG == pDirEntry[ idx ].DirEntryType ) + { + *ppStaConfig = pDirEntry[ idx ].DirEntryFileOffset + ( v_U8_t * )pFileHeader; + + *pcbStaConfig = pDirEntry[ idx ].DirEntryLength; + + break; + } + + } // End iteration over the header's entries + + if ( NULL != *ppStaConfig ) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO_LOW, + "Found the Station CFG in the CFG binary!!" ); + + fFound = VOS_TRUE; + } + else + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to find Station CFG in the CFG binary" ); + } + + } while( 0 ); + + VOS_ASSERT( VOS_TRUE == fFound ); + + return( fFound ); +} + + + + + + + + + + +VOS_STATUS sysMcProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_VOID_t *hHal; + + if (NULL == pMsg) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer to vos_msg_t", __func__); + return VOS_STATUS_E_INVAL; + } + + // All 'new' SYS messages are identified by a cookie in the reserved + // field of the message as well as the message type. This prevents + // the possibility of overlap in the message types defined for new + // SYS messages with the 'legacy' message types. The legacy messages + // will not have this cookie in the reserved field + if ( SYS_MSG_COOKIE == pMsg->reserved ) + { + // Process all the new SYS messages.. + switch( pMsg->type ) + { + case SYS_MSG_ID_MC_START: + { + /* Handling for this message is not needed now so adding + *debug print and VOS_ASSERT*/ + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + " Received SYS_MSG_ID_MC_START message msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + VOS_ASSERT(0); + break; + } + + case SYS_MSG_ID_MC_STOP: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Processing SYS MC STOP" ); + + // get the HAL context... + hHal = vos_get_context( VOS_MODULE_ID_PE, pVosContext ); + if (NULL == hHal) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid hHal", __func__ ); + } + else + { + vosStatus = sme_Stop( hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + + vosStatus = macStop( hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + + ((sysResponseCback)pMsg->callback)((v_VOID_t *)pMsg->bodyptr); + + vosStatus = VOS_STATUS_SUCCESS; + } + break; + } + + // Process MC thread probe. Just callback to the + // function that is in the message. + case SYS_MSG_ID_MC_THR_PROBE: + { +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if(pMsg->callback) + ((sysThreadProbeCback)pMsg->callback)(current->pid); +#endif + break; + } + + case SYS_MSG_ID_MC_TIMER: + { + vos_timer_callback_t timerCB = pMsg->callback; + + if (NULL != timerCB) + { + vos_ssr_protect(__func__); + timerCB(pMsg->bodyptr); + vos_ssr_unprotect(__func__); + } + break; + } + case SYS_MSG_ID_FTM_RSP: + { + WLANFTM_McProcessMsg((v_VOID_t *)pMsg->bodyptr); + break; + } + default: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Unknown message type in sysMcProcessMsg() msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + break; + } + + } // end switch on message type + + } // end if cookie set + else + { + // Process all 'legacy' messages + switch( pMsg->type ) + { + + default: + { + VOS_ASSERT( 0 ); + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Received SYS message cookie with unidentified " + "MC message type= %d [0x%08X]", pMsg->type, pMsg->type ); + + vosStatus = VOS_STATUS_E_BADMSG; + if (pMsg->bodyptr) + vos_mem_free(pMsg->bodyptr); + break; + } + } // end switch on pMsg->type + } // end else + + return( vosStatus ); +} + + + + +VOS_STATUS sysTxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (NULL == pMsg) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer to vos_msg_t", __func__); + return VOS_STATUS_E_INVAL; + } + + // All 'new' SYS messages are identified by a cookie in the reserved + // field of the message as well as the message type. This prevents + // the possibility of overlap in the message types defined for new + // SYS messages with the 'legacy' message types. The legacy messages + // will not have this cookie in the reserved field + if ( SYS_MSG_COOKIE == pMsg->reserved ) + { + // Process all the new SYS messages.. + switch( pMsg->type ) + { + // Process TX thread probe. Just callback to the + // function that is in the message. + case SYS_MSG_ID_TX_THR_PROBE: + { +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if(pMsg->callback) + ((sysThreadProbeCback)pMsg->callback)(current->pid); +#endif + break; + } + + case SYS_MSG_ID_TX_TIMER: + { + vos_timer_callback_t timerCB = pMsg->callback; + + if (NULL != timerCB) + { + timerCB(pMsg->bodyptr); + } + break; + } + + default: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Unknown message type in sysTxProcessMsg() msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + break; + } + + } // end switch on message type + } // end if cookie set + else + { + VOS_ASSERT( 0 ); + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Received SYS message cookie with unidentified TX message " + " type= %d [0x%08X]", pMsg->type, pMsg->type ); + + vosStatus = VOS_STATUS_E_BADMSG; + } // end else + + return( vosStatus ); +} + + +VOS_STATUS sysRxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (NULL == pMsg) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer to vos_msg_t", __func__); + return VOS_STATUS_E_INVAL; + } + + // All 'new' SYS messages are identified by a cookie in the reserved + // field of the message as well as the message type. This prevents + // the possibility of overlap in the message types defined for new + // SYS messages with the 'legacy' message types. The legacy messages + // will not have this cookie in the reserved field + if ( SYS_MSG_COOKIE == pMsg->reserved ) + { + // Process all the new SYS messages.. + switch( pMsg->type ) + { + case SYS_MSG_ID_RX_TIMER: + { + vos_timer_callback_t timerCB = pMsg->callback; + + if (NULL != timerCB) + { + timerCB(pMsg->bodyptr); + } + break; + } + + case SYS_MSG_ID_RX_THR_PROBE: + { +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + if(pMsg->callback) + ((sysThreadProbeCback)pMsg->callback)(current->pid); +#endif + break; + } + + default: + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Unknown message type in sysRxProcessMsg() msgType= %d [0x%08x]", + pMsg->type, pMsg->type ); + break; + } + + } // end switch on message type + } // end if cookie set + else + { + VOS_ASSERT( 0 ); + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Received SYS message cookie with unidentified RX message " + " type= %d [0x%08X]", pMsg->type, pMsg->type ); + + vosStatus = VOS_STATUS_E_BADMSG; + } // end else + + return( vosStatus ); +} + + +v_VOID_t sysMcFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ) +{ + return; +} + + +v_VOID_t sysTxFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg ) +{ + return; +} + + +void +SysProcessMmhMsg +( + tpAniSirGlobal pMac, + tSirMsgQ* pMsg +) +{ + VOS_MQ_ID targetMQ = VOS_MQ_ID_SYS; +/*-------------------------------------------------------------------------*/ + /* + ** The body of this pMsg is a tSirMbMsg + ** Contrary to Gen4, we cannot free it here! + ** It is up to the callee to free it + */ + + + if (NULL == pMsg) + { + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "NULL Message Pointer"); + VOS_ASSERT(0); + return; + } + + + switch (pMsg->type) + { + /* + ** Following messages are routed to SYS + */ + case WNI_CFG_DNLD_REQ: + case WNI_CFG_DNLD_CNF: + case WDA_APP_SETUP_NTF: + case WDA_NIC_OPER_NTF: + case WDA_RESET_REQ: + case eWNI_SME_START_RSP: + { + /* Forward this message to the SYS module */ + targetMQ = VOS_MQ_ID_SYS; + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Handling for the Message ID %d is removed in SYS\r\n", + pMsg->type); + + VOS_ASSERT(0); + break; + } + + + /* + ** Following messages are routed to HAL + */ + case WNI_CFG_DNLD_RSP: + case WDA_INIT_START_REQ: + { + /* Forward this message to the HAL module */ + targetMQ = VOS_MQ_ID_WDA; + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Handling for the Message ID %d is removed as there is no HAL \r\n", + pMsg->type); + + VOS_ASSERT(0); + break; + } + + case eWNI_SME_START_REQ: + case WNI_CFG_GET_REQ: + case WNI_CFG_SET_REQ: + case WNI_CFG_SET_REQ_NO_RSP: + case eWNI_SME_SYS_READY_IND: + { + /* Forward this message to the PE module */ + targetMQ = VOS_MQ_ID_PE; + break; + } + + + case WNI_CFG_GET_RSP: + case WNI_CFG_SET_CNF: +/* case eWNI_SME_DISASSOC_RSP: + case eWNI_SME_STA_STAT_RSP: + case eWNI_SME_AGGR_STAT_RSP: + case eWNI_SME_GLOBAL_STAT_RSP: + case eWNI_SME_STAT_SUMM_RSP: + case eWNI_PMC_ENTER_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_RSP: + case eWNI_PMC_EXIT_BMPS_IND: + case eWNI_PMC_ENTER_IMPS_RSP: + case eWNI_PMC_EXIT_IMPS_RSP: + case eWNI_PMC_ENTER_UAPSD_RSP: + case eWNI_PMC_EXIT_UAPSD_RSP: + case eWNI_PMC_ENTER_WOWL_RSP: + case eWNI_PMC_EXIT_WOWL_RSP: + case eWNI_SME_SWITCH_CHL_REQ: */ //Taken care by the check in default case + { + /* Forward this message to the SME module */ + targetMQ = VOS_MQ_ID_SME; + break; + } + + default: + { + + if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) && ( pMsg->type <= eWNI_SME_MSG_TYPES_END ) ) + { + targetMQ = VOS_MQ_ID_SME; + break; + } + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Message of ID %d is not yet handled by SYS\r\n", + pMsg->type); + + VOS_ASSERT(0); + } + + } + + + /* + ** Post now the message to the appropriate module for handling + */ + if(VOS_STATUS_SUCCESS != vos_mq_post_message(targetMQ, (vos_msg_t*)pMsg)) + { + //Caller doesn't allocate memory for the pMsg. It allocate memory for bodyptr + /* free the mem and return */ + if(pMsg->bodyptr) + { + vos_mem_free( pMsg->bodyptr); + } + } + +} /* SysProcessMmhMsg() */ + +/*========================================================================== + FUNCTION WLAN_FTM_SYS_FTM + + DESCRIPTION + Called by VOSS to free a given FTM message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + + DEPENDENCIES + FTM must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to FTM's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: + + SIDE EFFECTS + NONE +============================================================================*/ + +void wlan_sys_ftm(void *pMsgPtr) +{ + vos_msg_t vosMessage; + + + + vosMessage.reserved = FTM_SYS_MSG_COOKIE; + vosMessage.type = SYS_MSG_ID_FTM_RSP; + vosMessage.bodyptr = pMsgPtr; + + vos_mq_post_message(VOS_MQ_ID_SYS, &vosMessage); + + return; +} + + + +void wlan_sys_probe(void) +{ + vos_msg_t vosMessage; + + vosMessage.reserved = FTM_SYS_MSG_COOKIE; + vosMessage.type = SYS_MSG_ID_MC_THR_PROBE; + vosMessage.callback = vos_dump_thread_stacks; + vosMessage.bodyptr = NULL; + + vos_mq_post_message(VOS_MQ_ID_SYS, &vosMessage); + + return; +} + diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palApi.h b/drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palApi.h new file mode 100644 index 000000000000..4007612291a4 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palApi.h @@ -0,0 +1,762 @@ +/* + * Copyright (c) 2011-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file palApi.h + + \brief Exports and types for the Platform Abstraction Layer interfaces. + + $Id$ + This file contains all the interfaces for thge Platform Abstration Layer + functions. It is intended to be included in all modules that are using + the PAL interfaces. + + ========================================================================== */ +#ifndef PALAPI_H__ +#define PALAPI_H__ + +#include "halTypes.h" + +/** + \mainpage Platform Abstraction Layer (PAL) + + \section intro Introduction + + palApi is the Platform Abstration Layer. + + This is the latest attempt to abstract the entire Platform, including the + hardware, chip, OS and Bus into a generic API. We are doing this to give + the MAC the ability to call + generic APIs that will allow the MAC to function in an abstract manner + with any Airgo chipset, on any supported OS (Windows and Linux for now) + across any system bus interface (PCI, PCIe, Cardbus, USB, etc.). + + \todo + - palReadRegister: register read + -# add an Open/Close abstraction to accomodate the PAL before the entire MAC is loaded. + -# Review with Linux folks to see this basic scructure works for them. + -# Figure out how to organize the directory structure + - palMemory: memory read/write + - include async versions of read/write register + - palTx: an abstraction for transmit frames that manages the Td and Tm rings + - palRx: an abstracion for receiving frames from a chip across any of the supported buses + - palInterrupt: abstract the interrupts into the HAL + + + \section impl_notes Implementation Notes + + \subsection subsection_codeStructure Code strucure + + */ + + +/** --------------------------------------------------------------------------- + + \fn palReadRegister + + \brief chip and bus agnostic funtion to read a register value + + \param hHdd - HDD context handle + + \param regAddress - address (offset) of the register to be read from the start + of register space. + + \param pRegValue - pointer to the memory where the register contents are written + + \return eHalStatus - status of the register read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadRegister( tHddHandle hHdd, tANI_U32 regAddress, tANI_U32 *pRegValue ); + + +/** --------------------------------------------------------------------------- + + \fn palWriteRegister + + \brief chip and bus agnostic funtion to write a register value + + \param hHdd - HDD context handle + + \param regAddress - address (offset) of the register to be read from the start + of register space. + + \param pRegValue - pointer to the value being written into the register + + \return eHalStatus - status of the register read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWriteRegister( tHddHandle hHdd, tANI_U32 regAddress, tANI_U32 regValue ); + +/** --------------------------------------------------------------------------- + + \fn palAsyncWriteRegister + + \brief chip and bus agnostic async funtion to write a register value + + \param hHdd - HDD context handle + + \param regAddress - address (offset) of the register to be written from the start + of register space. + + \param regValue - value being written into the register + + \return eHalStatus - status of the register write. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ + +eHalStatus palAsyncWriteRegister( tHddHandle hHdd, tANI_U32 regAddress, tANI_U32 regValue ); + + +/** --------------------------------------------------------------------------- + + \fn palReadDeviceMemory + + \brief chip and bus agnostic funtion to read memory from the chip + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the + memory map (as exposed to the host) where the memory will be read from. + + \param pBuffer - pointer to a buffer where the memory will be placed in host + memory space after retreived from the chip. + + \param numBytes - the number of bytes to be read. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palWriteDeviceMemory + + \brief chip and bus agnostic funtion to write memory to the chip + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the on-chip + memory that will be written. + + \param pBuffer - pointer to a buffer that has the source data that will be + written to the chip. + + \param numBytes - the number of bytes to be written. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWriteDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + + +/** --------------------------------------------------------------------------- + + \fn palAllocateMemory + + \brief OS agnostic funtion to allocate host memory. + + \note Host memory that needs to be shared between the host and the + device needs to be allocated with the palAllocateSharedMemory() + and free'd with palFreeSharedMemory() functions. + + \param hHdd - HDD context handle + + \param ppMemory - pointer to a void pointer where the address of the + memory allocated will be placed upon return from this function. + + \param numBytes - the number of bytes to allocate. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +#ifndef FEATURE_WLAN_PAL_MEM_DISABLE + +#ifdef MEMORY_DEBUG +#define palAllocateMemory(hHdd, ppMemory, numBytes) palAllocateMemory_debug(hHdd, ppMemory, numBytes, __FILE__, __LINE__) +eHalStatus palAllocateMemory_debug( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes, char* fileName, tANI_U32 lineNum ); +#else +eHalStatus palAllocateMemory( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes ); +#endif + + +/** --------------------------------------------------------------------------- + + \fn palFreeMemory + + \brief OS agnostic funtion to free host memory that was allocated with + palAllcoateMemory() calls. + + \note Host memory that needs to be shared between the host and the + device needs to be allocated with the palAllocateSharedMemory() + and free'd with palFreeSharedMemory() functions. + + \param hHdd - HDD context handle + + \param pMemory - pointer to memory that will be free'd. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +eHalStatus palFreeMemory( tHddHandle hHdd, void *pMemory ); + + + +/** --------------------------------------------------------------------------- + + \fn palFillMemory + + \brief OS agnostic funtion to fill host memory with a specified byte value + + \param hHdd - HDD context handle + + \param pMemory - pointer to memory that will be filled. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the byte to be written to fill the memory with. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +eHalStatus palFillMemory( tHddHandle hHdd, void *pMemory, tANI_U32 numBytes, tANI_BYTE fillValue ); + +/** --------------------------------------------------------------------------- + + \fn palCopyMemory + + \brief OS agnostic funtion to copy host memory from one location to another + + \param hHdd - HDD context handle + + \param pSrc - pointer to source memory location (to copy from) + + \param pSrc - pointer to destination memory location (to copy to) + + \param numBytes - the number of bytes to be be copied. + + \return eHalStatus - status of the memory copy + + -------------------------------------------------------------------------------*/ +eHalStatus palCopyMemory( tHddHandle hHdd, void *pDst, const void *pSrc, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palFillMemory + + \brief OS agnostic funtion to fill host memory with a specified byte value + + \param hHdd - HDD context handle + + \param pMemory - pointer to memory that will be filled. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the byte to be written to fill the memory with. + + \return eHalStatus - status of the register read. Note that this function + can fail. In the case of a failure, a non-successful return code will be + returned and no memory will be allocated (the *ppMemory will be NULL so don't + try to use it unless the status returns success). + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION +eHalStatus palZeroMemory( tHddHandle hHdd, void *pMemory, tANI_U32 numBytes ) +{ + return( palFillMemory( hHdd, pMemory, numBytes, 0 ) ); +} + + +/** --------------------------------------------------------------------------- + + \fn palEqualMemory + + \brief OS agnostic funtion to compare two pieces of memory, similar to + memcmp function in standard C. + + \param hHdd - HDD context handle + + \param pMemory1 - pointer to one location in memory to compare. + + \param pMemory2 - pointer to second location in memory to compare. + + \param numBytes - the number of bytes to compare. + + \return tANI_BOOLEAN - returns a boolean value that tells if the memory + locations are equal or now equal. + + -------------------------------------------------------------------------------*/ +tANI_BOOLEAN palEqualMemory( tHddHandle hHdd, void *pMemory1, void *pMemory2, tANI_U32 numBytes ); +#endif +/** --------------------------------------------------------------------------- + + \fn palFillDeviceMemory + + \brief OS agnostic funtion to fill device memory with a specified + 32bit value + + \param hHdd - HDD context handle + + \param memOffset - offset of the memory on the device to fill. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the byte pattern to fill into memory on the device + + \return eHalStatus - status of the register read. Note that this function + can fail. + + eHAL_STATUS_DEVICE_MEMORY_LENGTH_ERROR - length of the device memory is not + a multiple of 4 bytes. + + eHAL_STATUS_DEVICE_MEMORY_MISALIGNED - memory address is not aligned on a + 4 byte boundary. + + \note return failure if the memOffset is not 32bit aligned and not a + multiple of 4 bytes (the device does not support anything else). + + -------------------------------------------------------------------------------*/ +eHalStatus palFillDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U32 numBytes, tANI_BYTE fillValue ); + + +/** --------------------------------------------------------------------------- + + \fn palZeroDeviceMemory + + \brief OS agnostic funtion to fill device memory with a specified byte value + + \param hHdd - HDD context handle + + \param memOffset - offset of the memory on the device to fill. + + \param numBytes - the number of bytes to be filled. + + \param fillValue - the 32bit pattern to fill the memory with. + + \return eHalStatus - status of the register read. Note that this function + can fail. + + eHAL_STATUS_DEVICE_MEMORY_LENGTH_ERROR - length of the device memory is not + a multiple of 4 bytes. + + eHAL_STATUS_DEVICE_MEMORY_MISALIGNED - memory address is not aligned on a + 4 byte boundary. + + \note return failure if the memOffset is not 32bit aligned and not a + multiple of 4 bytes (the device does not support anything else). + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION +eHalStatus palZeroDeviceMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U32 numBytes ) +{ + return( palFillDeviceMemory( hHdd, memOffset, numBytes, 0 ) ); +} + +/*---------------------------------------------------------------------------------- + + Allocate a packet for sending through the Tx APIs. + + \param hHdd - HDD context handle + + \param frmType - Frame type + + \param size + + \param data - + + \param ppPacket - + + \return eHalStatus - +----------------------------------------------------------------------------------*/ +eHalStatus palPktAlloc(tHddHandle hHdd, eFrameType frmType, tANI_U16 size, void **data, void **ppPacket) ; + + +// This should return Ssome sort of status..... +void palPktFree( tHddHandle hHdd, eFrameType frmType, void* buf, void *pPacket); + + + +//PAL lock functions +//pHandle -- pointer to a caller allocated tPalSpinLockHandle object +eHalStatus palSpinLockAlloc( tHddHandle hHdd, tPalSpinLockHandle *pHandle ); +//hSpinLock -- a handle returned by palSpinLockAlloc +eHalStatus palSpinLockFree( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ); +//hSpinLock -- a handle returned by palSpinLockAlloc +eHalStatus palSpinLockTake( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ); +//hSpinLock -- a handle returned by palSpinLockAlloc +eHalStatus palSpinLockGive( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ); +//PAL lock functions end + + +//This function send a message to MAC, +//pMsgBuf is a buffer allocated by caller. The actual structure varies base on message type +//The beginning of the buffer can always map to tSirMbMsg +//This function must take care of padding if it is required for the OS +eHalStatus palSendMBMessage(tHddHandle hHdd, void *pBuf); + +extern void palGetUnicastStats(tHddHandle hHdd, tANI_U32 *tx, tANI_U32 *rx); + + +/*---------------------------------------------------------------------------------- + this function is to return a tick count (one tick = ~10ms). It is used to calculate + time difference. + + \param hHdd - HDD context handle + + \return tick count. +----------------------------------------------------------------------------------*/ +tANI_TIMESTAMP palGetTickCount(tHddHandle hHdd); + +/** --------------------------------------------------------------------------- + + \fn palReadRegMemory + + \brief chip and bus agnostic function to read memory from the PHY register space as memory + i.e. to read more than 4 bytes from the contiguous register space + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the + memory map (as exposed to the host) where the memory will be read from. + + \param pBuffer - pointer to a buffer where the memory will be placed in host + memory space after retreived from the chip. + + \param numBytes - the number of bytes to be read. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadRegMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palAsyncWriteRegMemory + + \brief chip and bus agnostic function to write memory to the PHY register space as memory + i.e. to write more than 4 bytes from the contiguous register space. In USB interface, this + API does the write asynchronously. + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the on-chip + memory that will be written. + + \param pBuffer - pointer to a buffer that has the source data that will be + written to the chip. + + \param numBytes - the number of bytes to be written. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palAsyncWriteRegMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + +/** --------------------------------------------------------------------------- + + \fn palWriteRegMemory + \brief chip and bus agnostic function to write memory to the PHY register space as memory + i.e. to write more than 4 bytes from the contiguous register space. The difference from the + above routine is, in USB interface, this routine performs the write synchronously where as + the above routine performs it asynchronously. + + \param hHdd - HDD context handle + + \param memOffset - address (offset) of the memory from the top of the on-chip + memory that will be written. + + \param pBuffer - pointer to a buffer that has the source data that will be + written to the chip. + + \param numBytes - the number of bytes to be written. + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWriteRegMemory( tHddHandle hHdd, tANI_U32 memOffset, tANI_U8 *pBuffer, tANI_U32 numBytes ); + + +/** --------------------------------------------------------------------------- + + \fn palWaitRegVal + + \brief is a blocking function which reads the register and waits for the given number of iterations + until the read value matches the waitRegVal. The delay between is perIterWaitInNanoSec(in nanoseconds) + + \param hHdd - HDD context handle + + \param reg - address of the register to be read + + \param mask - mask to be applied for the read value + + \param waitRegVal - expected value from the register after applying the mask. + + \param perIterWaitInNanoSec - delay between the two iterations in nanoseconds + + \param numIter - max number of reads before the timeout + + \param pReadRegVal - the value read from the register + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palWaitRegVal( tHddHandle hHdd, tANI_U32 reg, tANI_U32 mask, + tANI_U32 waitRegVal, tANI_U32 perIterWaitInNanoSec, + tANI_U32 numIter, tANI_U32 *pReadRegVal ); + +/** --------------------------------------------------------------------------- + + \fn palReadModifyWriteReg + + \brief chip and bus agnostic function to read a PHY register apply the given masks(AND and OR masks) + and writes back the new value to the register + + \param hHdd - HDD context handle + + \param reg - address of the register to be modified. + + \param andMask - The value read will be ANDed with this mask + + \parma orMask - The value after applying the andMask will be ORed with this value + + \return eHalStatus - status of the memory read. Note that this function + can fail. In particular, when the card is removed, this function will return + a failure. + + -------------------------------------------------------------------------------*/ +eHalStatus palReadModifyWriteReg( tHddHandle hHdd, tANI_U32 reg, tANI_U32 andMask, tANI_U32 orMask ); + +//PAL semaphore functions +eHalStatus palSemaphoreAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle, tANI_S32 count ); +eHalStatus palSemaphoreFree( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ); +eHalStatus palSemaphoreTake( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ); +eHalStatus palSemaphoreGive( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ); +eHalStatus palMutexAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) ; +eHalStatus palMutexAllocLocked( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) ; + +//PAL irq/softirq +eAniBoolean pal_in_interrupt(void) ; +void pal_local_bh_disable(void) ; +void pal_local_bh_enable(void) ; + +//PAL byte swap +tANI_U32 pal_be32_to_cpu(tANI_U32 x) ; +tANI_U32 pal_cpu_to_be32(tANI_U32 x) ; +tANI_U16 pal_be16_to_cpu(tANI_U16 x) ; +tANI_U16 pal_cpu_to_be16(tANI_U16 x) ; + + +#if defined( ANI_LITTLE_BYTE_ENDIAN ) + +// Need to eliminate these and use the ani_cpu_to_le, etc. macros.... +ANI_INLINE_FUNCTION unsigned long i_htonl( unsigned long ul ) +{ + return( ( ( ul & 0x000000ff ) << 24 ) | + ( ( ul & 0x0000ff00 ) << 8 ) | + ( ( ul & 0x00ff0000 ) >> 8 ) | + ( ( ul & 0xff000000 ) >> 24 ) ); +} + +ANI_INLINE_FUNCTION unsigned short i_htons( unsigned short us ) +{ + return( ( ( us >> 8 ) & 0x00ff ) + ( ( us << 8 ) & 0xff00 ) ); +} + +ANI_INLINE_FUNCTION unsigned short i_ntohs( unsigned short us ) +{ + return( i_htons( us ) ); +} + +ANI_INLINE_FUNCTION unsigned long i_ntohl( unsigned long ul ) +{ + return( i_htonl( ul ) ); +} + +#endif //#if defined( ANI_LITTLE_BYTE_ENDIAN ) + + +/** --------------------------------------------------------------------------- + + \fn pal_set_U32 + + \brief Assign 32-bit unsigned value to a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param value - The value to assign to the byte array + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_set_U32(tANI_U8 *ptr, tANI_U32 value) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *(ptr) = ( tANI_U8 )( value >> 24 ); + *(ptr + 1) = ( tANI_U8 )( value >> 16 ); + *(ptr + 2) = ( tANI_U8 )( value >> 8 ); + *(ptr + 3) = ( tANI_U8 )( value ); +#else + *(ptr + 3) = ( tANI_U8 )( value >> 24 ); + *(ptr + 2) = ( tANI_U8 )( value >> 16 ); + *(ptr + 1) = ( tANI_U8 )( value >> 8 ); + *(ptr) = ( tANI_U8 )( value ); +#endif + + return (ptr + 4); +} + + +/** --------------------------------------------------------------------------- + + \fn pal_set_U16 + + \brief Assign 16-bit unsigned value to a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param value - The value to assign to the byte array + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_set_U16(tANI_U8 *ptr, tANI_U16 value) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *(ptr) = ( tANI_U8 )( value >> 8 ); + *(ptr + 1) = ( tANI_U8 )( value ); +#else + *(ptr + 1) = ( tANI_U8 )( value >> 8 ); + *(ptr) = ( tANI_U8 )( value ); +#endif + + return (ptr + 2); +} + + +/** --------------------------------------------------------------------------- + + \fn pal_get_U16 + + \brief Retrieve a 16-bit unsigned value from a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param pValue - Pointer to a caller allocated buffer for 16 bit value. Value is to assign + to this location. + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_get_U16(tANI_U8 *ptr, tANI_U16 *pValue) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *pValue = (((tANI_U16) (*ptr << 8)) | + ((tANI_U16) (*(ptr+1)))); +#else + *pValue = (((tANI_U16) (*(ptr+1) << 8)) | + ((tANI_U16) (*ptr))); +#endif + + return (ptr + 2); +} + + +/** --------------------------------------------------------------------------- + + \fn pal_get_U32 + + \brief Retrieve a 32-bit unsigned value from a byte array base on CPU's endianness. + + \note Caller must validate the byte array has enough space to hold the vlaue + + \param ptr - Starting address of a byte array + + \param pValue - Pointer to a caller allocated buffer for 32 bit value. Value is to assign + to this location. + + \return - The address to the byte after the assignment. This may or may not + be valid. Caller to verify. + + -------------------------------------------------------------------------------*/ +ANI_INLINE_FUNCTION tANI_U8 * pal_get_U32(tANI_U8 *ptr, tANI_U32 *pValue) +{ +#if defined( ANI_BIG_BYTE_ENDIAN ) + *pValue = ( (tANI_U32)(*(ptr) << 24) | + (tANI_U32)(*(ptr+1) << 16) | + (tANI_U32)(*(ptr+2) << 8) | + (tANI_U32)(*(ptr+3)) ); +#else + *pValue = ( (tANI_U32)(*(ptr+3) << 24) | + (tANI_U32)(*(ptr+2) << 16) | + (tANI_U32)(*(ptr+1) << 8) | + (tANI_U32)(*(ptr)) ); +#endif + + return (ptr + 4); +} + + +#endif diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palTimer.h b/drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palTimer.h new file mode 100644 index 000000000000..cbb274d0a8a6 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/pal/inc/palTimer.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file palTimer.h + + \brief Define data structure and ptototype for PAL timer. + + $Id$ + ... description... + + ========================================================================== */ + +#if !defined( PALTIMER_H__ ) +#define PALTIMER_H__ + + +/* +PAL TIMER + This timer can be used for every module in Windows side. + On Linus side, this can only be used by timer for HDD. Not for timers used in rtlib, hence it doesn't replace TX_TIMER +*/ + +typedef void * tPalTimerHandle; + +#define PAL_INVALID_TIMER_HANDLE (NULL) + +typedef void (*palTimerCallback)(void *); + +#define PAL_TIMER_TO_MS_UNIT 1000 +#define PAL_TIMER_TO_SEC_UNIT 1000000 + +#ifndef FEATURE_WLAN_PAL_TIMER_DISABLE +//PAL timer functions +//pPalTimer is a pointer to a caller allocated tPalTimer object +//pContext is a pointer to an object that will be passed in when callback is called +//fRestart to set whether the timer is restart after callback returns +#ifdef TIMER_MANAGER +#define palTimerAlloc(hHdd, phPalTimer, pCallback, pContext) \ + palTimerAlloc_debug(hHdd, phPalTimer, pCallback, pContext, __FILE__, __LINE__) +eHalStatus palTimerAlloc_debug( tHddHandle hHdd, tPalTimerHandle *phPalTimer, + palTimerCallback pCallback, void *pContext, char* fileName, v_U32_t lineNum ); +#else +eHalStatus palTimerAlloc(tHddHandle hHdd, tPalTimerHandle *phPalTimer, palTimerCallback pCallback, void *pContext); +#endif +//This function will free the timer +//On Windows platform, it can only be called when device is unloading. +eHalStatus palTimerFree(tHddHandle, tPalTimerHandle); +//To start a timer +//uExpireTime is the timer lapse before timer fires. If the timer is in running state and the fRestart is true, +//uExpireTime is set so that it is the new interval, in units of microseconds +eHalStatus palTimerStart(tHddHandle, tPalTimerHandle, tANI_U32 uExpireTime, tANI_BOOLEAN fRestart); +//palTimerStop will cancel the timer but doesn't guarrantee the callback will not called afterwards +//For Windows, if the driver is halting, the callback is not called after this function returns. +eHalStatus palTimerStop(tHddHandle, tPalTimerHandle); +#endif + +#endif diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palApiComm.c b/drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palApiComm.c new file mode 100644 index 000000000000..c6ce6f488977 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palApiComm.c @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#include +#include // needed for tSirRetStatus +#include + +#include // needed for tSirMbMsg +#include "wlan_qct_wda.h" + +#ifndef FEATURE_WLAN_PAL_MEM_DISABLE + +#ifdef MEMORY_DEBUG +eHalStatus palAllocateMemory_debug( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes, char* fileName, tANI_U32 lineNum ) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + *ppMemory = vos_mem_malloc_debug( numBytes, fileName, lineNum ); + + if ( NULL == *ppMemory ) + { + halStatus = eHAL_STATUS_FAILURE; + } + + return( halStatus ); +} +#else +eHalStatus palAllocateMemory( tHddHandle hHdd, void **ppMemory, tANI_U32 numBytes ) +{ + eHalStatus halStatus = eHAL_STATUS_SUCCESS; + + *ppMemory = vos_mem_malloc( numBytes ); + + if ( NULL == *ppMemory ) + { + halStatus = eHAL_STATUS_FAILURE; + } + + return( halStatus ); +} +#endif + + +eHalStatus palFreeMemory( tHddHandle hHdd, void *pMemory ) +{ + vos_mem_free( pMemory ); + + return( eHAL_STATUS_SUCCESS ); +} + +eHalStatus palFillMemory( tHddHandle hHdd, void *pMemory, tANI_U32 numBytes, tANI_BYTE fillValue ) +{ + vos_mem_set( pMemory, numBytes, fillValue ); + + return( eHAL_STATUS_SUCCESS ); +} + + +eHalStatus palCopyMemory( tHddHandle hHdd, void *pDst, const void *pSrc, tANI_U32 numBytes ) +{ + vos_mem_copy( pDst, pSrc, numBytes ); + + return( eHAL_STATUS_SUCCESS ); +} + + + +tANI_BOOLEAN palEqualMemory( tHddHandle hHdd, void *pMemory1, void *pMemory2, tANI_U32 numBytes ) +{ + return( vos_mem_compare( pMemory1, pMemory2, numBytes ) ); +} +#endif + +eHalStatus palPktAlloc(tHddHandle hHdd, eFrameType frmType, tANI_U16 size, void **data, void **ppPacket) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + VOS_STATUS vosStatus; + + vos_pkt_t *pVosPacket; + + do + { + // we are only handling the 802_11_MGMT frame type for PE/LIM. All other frame types should be + // ported to use the VOSS APIs directly and should not be using this palPktAlloc API. + VOS_ASSERT( HAL_TXRX_FRM_802_11_MGMT == frmType ); + + if ( HAL_TXRX_FRM_802_11_MGMT != frmType ) break; + + // allocate one 802_11_MGMT VOS packet, zero the packet and fail the call if nothing is available. + // if we cannot get this vos packet, fail. + vosStatus = vos_pkt_get_packet( &pVosPacket, VOS_PKT_TYPE_TX_802_11_MGMT, size, 1, VOS_TRUE, NULL, NULL ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) break; + + // Reserve the space at the head of the packet for the caller. If we cannot reserve the space + // then we have to fail (return the packet to voss first!) + vosStatus = vos_pkt_reserve_head( pVosPacket, data, size ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + vos_pkt_return_packet( pVosPacket ); + break; + } + + // Everything went well if we get here. Return the packet pointer to the caller and indicate + // success to the caller. + *ppPacket = (void *)pVosPacket; + + halStatus = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( halStatus ); +} + + + +void palPktFree( tHddHandle hHdd, eFrameType frmType, void* buf, void *pPacket) +{ + vos_pkt_t *pVosPacket = (vos_pkt_t *)pPacket; + VOS_STATUS vosStatus; + + do + { + VOS_ASSERT( pVosPacket ); + + if ( !pVosPacket ) break; + + // we are only handling the 802_11_MGMT frame type for PE/LIM. All other frame types should be + // ported to use the VOSS APIs directly and should not be using this palPktAlloc API. + VOS_ASSERT( HAL_TXRX_FRM_802_11_MGMT == frmType ); + if ( HAL_TXRX_FRM_802_11_MGMT != frmType ) break; + + // return the vos packet to Voss. Nothing to do if this fails since the palPktFree does not + // have a return code. + vosStatus = vos_pkt_return_packet( pVosPacket ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + + } while( 0 ); + + return; +} + + + +tANI_TIMESTAMP palGetTickCount(tHddHandle hHdd) +{ + return( vos_timer_get_system_ticks() ); +} + + +tANI_U32 pal_be32_to_cpu(tANI_U32 x) +{ + return( x ); +} + +tANI_U32 pal_cpu_to_be32(tANI_U32 x) +{ + return(( x ) ); +} + +tANI_U16 pal_be16_to_cpu(tANI_U16 x) +{ + return( ( x ) ); +} + +tANI_U16 pal_cpu_to_be16(tANI_U16 x) +{ + return( ( x ) ); +} + + + +eHalStatus palSpinLockAlloc( tHddHandle hHdd, tPalSpinLockHandle *pHandle ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + VOS_STATUS vosStatus; + vos_lock_t *pLock; + + do + { + pLock = vos_mem_malloc( sizeof( vos_lock_t ) ); + + if ( NULL == pLock ) break; + + vos_mem_set(pLock, sizeof( vos_lock_t ), 0); + + vosStatus = vos_lock_init( pLock ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + vos_mem_free( pLock ); + break; + } + + *pHandle = (tPalSpinLockHandle)pLock; + halStatus = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( halStatus ); +} + + +eHalStatus palSpinLockFree( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + vos_lock_t *pLock = (vos_lock_t *)hSpinLock; + VOS_STATUS vosStatus; + + vosStatus = vos_lock_destroy( pLock ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if we successfully destroy the lock, free + // the memory and indicate success to the caller. + vos_mem_free( pLock ); + + halStatus = eHAL_STATUS_SUCCESS; + } + return( halStatus ); +} + + +eHalStatus palSpinLockTake( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + vos_lock_t *pLock = (vos_lock_t *)hSpinLock; + VOS_STATUS vosStatus; + + vosStatus = vos_lock_acquire( pLock ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if successfully acquire the lock, indicate success + // to the caller. + halStatus = eHAL_STATUS_SUCCESS; + } + + return( halStatus ); +} + + + + + +eHalStatus palSpinLockGive( tHddHandle hHdd, tPalSpinLockHandle hSpinLock ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + vos_lock_t *pLock = (vos_lock_t *)hSpinLock; + VOS_STATUS vosStatus; + + vosStatus = vos_lock_release( pLock ); + if ( VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if successfully acquire the lock, indicate success + // to the caller. + halStatus = eHAL_STATUS_SUCCESS; + } + + return( halStatus ); +} + + +// Caller of this function MUST dynamically allocate memory for pBuf +// because this funciton will free the memory. +eHalStatus palSendMBMessage(tHddHandle hHdd, void *pBuf) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tSirRetStatus sirStatus; + v_CONTEXT_t vosContext; + v_VOID_t *hHal; + + vosContext = vos_get_global_context( VOS_MODULE_ID_HDD, hHdd ); + if (NULL == vosContext) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid vosContext", __func__); + } + else + { + hHal = vos_get_context( VOS_MODULE_ID_SME, vosContext ); + if (NULL == hHal) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid hHal", __func__); + } + else + { + sirStatus = uMacPostCtrlMsg( hHal, pBuf ); + if ( eSIR_SUCCESS == sirStatus ) + { + halStatus = eHAL_STATUS_SUCCESS; + } + } + } + + vos_mem_free( pBuf ); + + return( halStatus ); +} + + + +//All semophore functions are no-op here +//PAL semaphore functions +//All functions MUST return success. If change needs to be made, please check all callers' logic +eHalStatus palSemaphoreAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle, tANI_S32 count ) +{ + (void)hHdd; + (void)pHandle; + (void)count; + if(pHandle) + { + *pHandle = NULL; + } + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palSemaphoreFree( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ) +{ + (void)hHdd; + (void)hSemaphore; + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palSemaphoreTake( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ) +{ + (void)hHdd; + (void)hSemaphore; + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palSemaphoreGive( tHddHandle hHdd, tPalSemaphoreHandle hSemaphore ) +{ + (void)hHdd; + (void)hSemaphore; + + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palMutexAlloc( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) +{ + (void)hHdd; + (void)pHandle; + + if(pHandle) + { + *pHandle = NULL; + } + return (eHAL_STATUS_SUCCESS); +} + +eHalStatus palMutexAllocLocked( tHddHandle hHdd, tPalSemaphoreHandle *pHandle) +{ + (void)hHdd; + (void)pHandle; + + if(pHandle) + { + *pHandle = NULL; + } + return (eHAL_STATUS_SUCCESS); +} + + +eAniBoolean pal_in_interrupt(void) +{ + return (eANI_BOOLEAN_FALSE); +} + +void pal_local_bh_disable(void) +{ +} + +void pal_local_bh_enable(void) +{ +} + diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palTimer.c b/drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palTimer.c new file mode 100644 index 000000000000..d88ceae9ac92 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/pal/src/palTimer.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + + This file contains function implementations for the Platform + Abstration Layer. + + */ + +#include +#include +#include +#include + +#ifndef FEATURE_WLAN_PAL_TIMER_DISABLE +typedef struct sPalTimer +{ + palTimerCallback timerCallback; + void *pContext; + tHddHandle hHdd; // not really needed when mapping to vos timers + tANI_U32 uTimerInterval; //meaningful only is fRestart is true + tANI_BOOLEAN fRestart; + + vos_timer_t vosTimer; + +} tPalTimer, *tpPalTimer; + + + +v_VOID_t internalTimerCallback( v_PVOID_t userData ) +{ + tPalTimer *pPalTimer = (tPalTimer *)userData; + + if ( pPalTimer ) + { + if ( pPalTimer->timerCallback ) + { + pPalTimer->timerCallback( pPalTimer->pContext ); + } + + if ( pPalTimer->fRestart ) + { + palTimerStart( pPalTimer->hHdd, pPalTimer, pPalTimer->uTimerInterval, eANI_BOOLEAN_TRUE ); + } + } +} + +#ifdef TIMER_MANAGER +eHalStatus palTimerAlloc_debug( tHddHandle hHdd, tPalTimerHandle *phPalTimer, + palTimerCallback pCallback, void *pContext, char* fileName, v_U32_t lineNum ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tPalTimer *pPalTimer = NULL; + VOS_STATUS vosStatus; + + do + { + // allocate the internal timer structure. + pPalTimer = vos_mem_malloc( sizeof( tPalTimer ) ); + if ( NULL == pPalTimer ) break; + + // initialize the vos Timer that underlies the pal Timer. + vosStatus = vos_timer_init_debug( &pPalTimer->vosTimer, VOS_TIMER_TYPE_SW, + internalTimerCallback, pPalTimer, fileName, lineNum ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if fail to init the vos timer, free the memory and bail out. + vos_mem_free( pPalTimer ); + break; + } + + // initialize the info in the internal palTimer struct so we can + pPalTimer->timerCallback = pCallback; + pPalTimer->pContext = pContext; + pPalTimer->hHdd = hHdd; + + // return a 'handle' to the caller. + *phPalTimer = pPalTimer; + + halStatus = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( halStatus ); +} +#else +eHalStatus palTimerAlloc( tHddHandle hHdd, tPalTimerHandle *phPalTimer, + palTimerCallback pCallback, void *pContext ) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tPalTimer *pPalTimer = NULL; + VOS_STATUS vosStatus; + + do + { + // allocate the internal timer structure. + pPalTimer = vos_mem_malloc( sizeof( tPalTimer ) ); + if ( NULL == pPalTimer ) break; + + // initialize the vos Timer that underlies the pal Timer. + vosStatus = vos_timer_init( &pPalTimer->vosTimer, VOS_TIMER_TYPE_SW, + internalTimerCallback, pPalTimer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + // if fail to init the vos timer, free the memory and bail out. + vos_mem_free( pPalTimer ); + break; + } + + // initialize the info in the internal palTimer struct so we can + pPalTimer->timerCallback = pCallback; + pPalTimer->pContext = pContext; + pPalTimer->hHdd = hHdd; + + // return a 'handle' to the caller. + *phPalTimer = pPalTimer; + + halStatus = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( halStatus ); +} +#endif + + +eHalStatus palTimerFree( tHddHandle hHdd, tPalTimerHandle hPalTimer ) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + VOS_STATUS vosStatus; + tPalTimer *pPalTimer = (tPalTimer *)hPalTimer; + + do + { + if ( NULL == pPalTimer ) break; + + // Destroy the vos timer... + vosStatus = vos_timer_destroy( &pPalTimer->vosTimer ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) break; + + // Free the memory for the intrnal timer struct... + vos_mem_free( pPalTimer ); + + status = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( status ); +} + + +eHalStatus palTimerStart(tHddHandle hHdd, tPalTimerHandle hPalTimer, tANI_U32 uExpireTime, tANI_BOOLEAN fRestart) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + VOS_STATUS vosStatus; + tANI_U32 expireTimeInMS = 0; + + tPalTimer *pPalTimer = (tPalTimer *)hPalTimer; + + do + { + if ( NULL == pPalTimer ) break; + + pPalTimer->fRestart = fRestart; + pPalTimer->uTimerInterval = uExpireTime; + + // vos Timer takes expiration time in milliseconds. palTimerStart and + // the uTimerIntervl in tPalTimer struct have expiration tiem in + // microseconds. Make and adjustment from microseconds to milliseconds + // before calling the vos_timer_start(). + expireTimeInMS = uExpireTime / 1000; + vosStatus = vos_timer_start( &pPalTimer->vosTimer, expireTimeInMS ); + if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + status = eHAL_STATUS_FAILURE; + break; + } + + status = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( status ); +} + + +eHalStatus palTimerStop(tHddHandle hHdd, tPalTimerHandle hPalTimer) +{ + eHalStatus status = eHAL_STATUS_INVALID_PARAMETER; + + tPalTimer *pPalTimer = (tPalTimer *)hPalTimer; + + do + { + if ( NULL == pPalTimer ) break; + + vos_timer_stop( &pPalTimer->vosTimer ); + + // make sure the timer is not re-started. + pPalTimer->fRestart = eANI_BOOLEAN_FALSE; + + status = eHAL_STATUS_SUCCESS; + + } while( 0 ); + + return( status ); +} + +#endif + + + + diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/platform/inc/VossWrapper.h b/drivers/staging/prima/CORE/SYS/legacy/src/platform/inc/VossWrapper.h new file mode 100644 index 000000000000..49eec9d3aef2 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/platform/inc/VossWrapper.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __VOSS_WRAPPER_H +#define __VOSS_WRAPPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*=========================================================================== + @file VossWrapper.h + + @brief This header file contains the various structure definitions and + function prototypes for the RTOS abstraction layer, implemented for VOSS + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 12/15/08 sho Resolved warnings and errors from AMSS compiler when + this is ported to WM + 11/20/08 sho Renamed this to VossWrapper.h; remove all dependencies + on WM platform and allow this to work on all VOSS enabled + platforms + 06/24/08 tbh Modified the file to remove the dependecy on HDD files as + part of Gen6 bring up process. + 10/29/02 Neelay Das Created file. + +===========================================================================*/ + +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ + +#include "sirTypes.h" +#include "sirParams.h" +#include "sysDef.h" +#include "aniDbgTest.h" +#include "vos_timer.h" +#include "palApi.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "vos_memory.h" + +/* Interlocked Compare Exchange related definitions */ + + + +/* Define basic constants for the ThreadX kernel. */ + +#define TX_NO_WAIT 0 +#define TX_WAIT_FOREVER 0xFFFFFFFFUL +#define TX_AUTO_ACTIVATE 1 +#define TX_NO_ACTIVATE 0 + + + +/* API return values. */ +#define TX_SUCCESS 0x00 +#define TX_QUEUE_FULL 0x01 +// ... +#define TX_NO_INSTANCE 0x0D +// ... +#define TX_TIMER_ERROR 0x15 +#define TX_TICK_ERROR 0x16 +// ... + + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +/* Following macro specifies the number of milliseconds which constitute 1 ThreadX timer tick. Used + for mimicking the ThreadX timer behaviour on VOSS. */ +// Use the same MACRO used by firmware modules to calculate TICKs from mSec +// Mismatch would cause worng timer value to be programmed +#define TX_MSECS_IN_1_TICK SYS_TICK_DUR_MS + +// Signature with which the TX_TIMER struct is initialized, when the timer is created +#define TX_AIRGO_TMR_SIGNATURE 0xDEADBEEF + +#ifdef TIMER_MANAGER +#define tx_timer_create(a, b, c, d, e, f, g) tx_timer_create_intern_debug((v_PVOID_t)pMac, a, b, c, d, e, f, g, __FILE__, __LINE__) +#else +#define tx_timer_create(a, b, c, d, e, f, g) tx_timer_create_intern((v_PVOID_t)pMac, a, b, c, d, e, f, g) +#endif + +/*--------------------------------------------------------------------*/ +/* Timer structure */ +/* This structure is used to implement ThreadX timer facility. Just */ +/* like ThreadX, timer expiration handler executes at the highest */ +/* possible priority level, i.e. DISPATCH_LEVEL. */ +/*--------------------------------------------------------------------*/ +typedef struct TX_TIMER_STRUCT +{ +#ifdef WLAN_DEBUG +#define TIMER_MAX_NAME_LEN 50 + char timerName[TIMER_MAX_NAME_LEN]; +#endif + v_ULONG_t tmrSignature; + v_VOID_t (*pExpireFunc)(v_PVOID_t, tANI_U32); + tANI_U32 expireInput; + v_ULONG_t initScheduleTimeInMsecs; + v_ULONG_t rescheduleTimeInMsecs; + vos_timer_t vosTimer; + + // Pointer to the MAC global structure, which stores the context for the NIC, + // for which this timer is supposed to operate. + v_PVOID_t pMac; + tANI_U8 sessionId; + +} TX_TIMER; + +#define TX_TIMER_VALID(timer) (timer.pMac != 0) + +extern v_ULONG_t tx_time_get(v_VOID_t); +extern v_UINT_t tx_timer_activate(TX_TIMER*); +extern v_UINT_t tx_timer_change(TX_TIMER*, v_ULONG_t, v_ULONG_t); +extern v_UINT_t tx_timer_change_context(TX_TIMER*, tANI_U32); +#ifdef TIMER_MANAGER +extern v_UINT_t tx_timer_create_intern_debug(v_PVOID_t, TX_TIMER*, char *, v_VOID_t(*)(v_PVOID_t, tANI_U32), + tANI_U32, v_ULONG_t, v_ULONG_t, v_ULONG_t, char* fileName, v_U32_t lineNum ); +#else +extern v_UINT_t tx_timer_create_intern(v_PVOID_t, TX_TIMER*, char *, v_VOID_t(*)(v_PVOID_t, tANI_U32), tANI_U32, v_ULONG_t, v_ULONG_t, v_ULONG_t); +#endif +extern v_UINT_t tx_timer_deactivate(TX_TIMER*); +extern v_UINT_t tx_timer_delete(TX_TIMER*); +extern v_BOOL_t tx_timer_running(TX_TIMER*); + +#ifdef __cplusplus +} +#endif + + +#endif + + + diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/platform/src/VossWrapper.c b/drivers/staging/prima/CORE/SYS/legacy/src/platform/src/VossWrapper.c new file mode 100644 index 000000000000..a137cbefb3ac --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/platform/src/VossWrapper.c @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + @file VossWrapper.c + + @brief This source file contains the various function definitions for the + RTOS abstraction layer, implemented for VOSS + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 03/31/09 sho Remove the use of vosTimerIsActive flag as it is not + thread-safe + 02/17/08 sho Fix the timer callback function to work when it is called + after the timer has stopped due to a race condition. + 02/10/08 sho Refactor the TX timer to use VOS timer directly instead + of using VOS utility timer + 12/15/08 sho Resolved errors and warnings from the AMSS compiler when + this is ported from WM + 11/20/08 sho Renamed this to VosWrapper.c; remove all dependencies on + WM platform and allow this to work on all VOSS enabled + platform + 06/24/08 tbh Modified the file to remove the dependecy on HDD files as + part of Gen6 bring up process. + 10/29/02 Neelay Das Created file. + +===========================================================================*/ + +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ +#include "VossWrapper.h" + +#ifdef WLAN_DEBUG +#define TIMER_NAME (timer_ptr->timerName) +#else +#define TIMER_NAME "N/A" +#endif + +/**--------------------------------------------------------------------- + * tx_time_get() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return current system time in units of miliseconds + * + */ +v_ULONG_t tx_time_get( void ) +{ + return(vos_timer_get_system_ticks()); + +} //* tx_time_get() + + +/**--------------------------------------------------------------------- + * tx_timer_activate() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_activate(TX_TIMER *timer_ptr) +{ + VOS_STATUS status; + + // Uncomment the asserts, if the intention is to debug the occurence of the + // following anomalous cnditions. + + // Assert that the timer structure pointer passed, is not NULL + //dbgAssert(NULL != timer_ptr); + + // If the NIC is halting just spoof a successful timer activation, so that all + // the timers can be cleaned up. + + if(NULL == timer_ptr) + return TX_TIMER_ERROR; + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) { + VOS_ASSERT( timer_ptr->tmrSignature == 0 ); + + return TX_TIMER_ERROR; + + } + + // Check for an uninitialized timer + VOS_ASSERT(0 != strlen(TIMER_NAME)); + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s being activated\n", TIMER_NAME); + + status = vos_timer_start( &timer_ptr->vosTimer, + timer_ptr->initScheduleTimeInMsecs ); + + if (VOS_STATUS_SUCCESS == status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s now activated\n", TIMER_NAME); + return TX_SUCCESS; + } + else if (VOS_STATUS_E_ALREADY == status) + { + // starting timer fails because timer is already started; this is okay + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s is already running\n", TIMER_NAME); + return TX_SUCCESS; + } + else + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Timer %s fails to activate\n", TIMER_NAME); + return TX_TIMER_ERROR; + } +} /*** tx_timer_activate() ***/ + + +/**--------------------------------------------------------------------- + * tx_timer_change() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_change(TX_TIMER *timer_ptr, + v_ULONG_t initScheduleTimeInTicks, v_ULONG_t rescheduleTimeInTicks) +{ + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) { + VOS_ASSERT( timer_ptr->tmrSignature == 0 ); + + return TX_TIMER_ERROR; + } + + // changes cannot be applied until timer stops running + if (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&timer_ptr->vosTimer)) + { + timer_ptr->initScheduleTimeInMsecs = TX_MSECS_IN_1_TICK * initScheduleTimeInTicks; + timer_ptr->rescheduleTimeInMsecs = TX_MSECS_IN_1_TICK * rescheduleTimeInTicks; + return TX_SUCCESS; + } + else + { + return TX_TIMER_ERROR; + } +} /*** tx_timer_change() ***/ + +/**--------------------------------------------------------------------- + * tx_timer_change_context() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_change_context(TX_TIMER *timer_ptr, tANI_U32 expiration_input) +{ + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) { + VOS_ASSERT( timer_ptr->tmrSignature == 0 ); + + return TX_TIMER_ERROR; + } + + // changes cannot be applied until timer stops running + if (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&timer_ptr->vosTimer)) + { + timer_ptr->expireInput = expiration_input; + return TX_SUCCESS; + } + else + { + return TX_TIMER_ERROR; + } +} /*** tx_timer_change() ***/ + + +/**--------------------------------------------------------------------- + * tx_main_timer_func() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return None. + * + */ +static v_VOID_t tx_main_timer_func( v_PVOID_t functionContext ) +{ + TX_TIMER *timer_ptr = (TX_TIMER *)functionContext; + + + if (NULL == timer_ptr) + { + VOS_ASSERT(0); + return; + } + + + if (NULL == timer_ptr->pExpireFunc) + { + VOS_ASSERT(0); + return; + } + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Timer %s triggered", TIMER_NAME); + + // Now call the actual timer function, taking the function pointer, + // from the timer structure. + (* timer_ptr->pExpireFunc)( timer_ptr->pMac, timer_ptr->expireInput ); + + // check if this needs to be rescheduled + if (0 != timer_ptr->rescheduleTimeInMsecs) + { + VOS_STATUS status; + status = vos_timer_start( &timer_ptr->vosTimer, + timer_ptr->rescheduleTimeInMsecs ); + timer_ptr->rescheduleTimeInMsecs = 0; + + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN, + "Unable to reschedule timer %s; status=%d", TIMER_NAME, status); + } + } +} /*** tx_timer_change() ***/ + +#ifdef TIMER_MANAGER +v_UINT_t tx_timer_create_intern_debug( v_PVOID_t pMacGlobal, TX_TIMER *timer_ptr, + char *name_ptr, + v_VOID_t ( *expiration_function )( v_PVOID_t, tANI_U32 ), + tANI_U32 expiration_input, v_ULONG_t initScheduleTimeInTicks, + v_ULONG_t rescheduleTimeInTicks, v_ULONG_t auto_activate, + char* fileName, v_U32_t lineNum) +{ + VOS_STATUS status; + + if (NULL == expiration_function) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "NULL timer expiration"); + VOS_ASSERT(0); + return TX_TIMER_ERROR; + } + + if(NULL == name_ptr) + { + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "NULL name pointer for timer"); + VOS_ASSERT(0); + return TX_TIMER_ERROR; + } + + if (!initScheduleTimeInTicks) + return TX_TICK_ERROR; + + if (!timer_ptr) + return TX_TIMER_ERROR; + + // Initialize timer structure + timer_ptr->pExpireFunc = expiration_function; + timer_ptr->expireInput = expiration_input; + timer_ptr->initScheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * initScheduleTimeInTicks; + timer_ptr->rescheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * rescheduleTimeInTicks; + timer_ptr->pMac = pMacGlobal; + + // Set the flag indicating that the timer was created + timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE; + +#ifdef WLAN_DEBUG + // Store the timer name + strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName)); +#endif // Store the timer name, for Debug build only + + status = vos_timer_init_debug( &timer_ptr->vosTimer, VOS_TIMER_TYPE_SW, + tx_main_timer_func, (v_PVOID_t)timer_ptr, fileName, lineNum); + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Cannot create timer for %s\n", TIMER_NAME); + return TX_TIMER_ERROR; + } + + if(0 != rescheduleTimeInTicks) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Creating periodic timer for %s\n", TIMER_NAME); + } + + // Activate this timer if required + if (auto_activate) + { + tx_timer_activate(timer_ptr); + } + + return TX_SUCCESS; + +} //** tx_timer_create() ***/ +#else +v_UINT_t tx_timer_create_intern( v_PVOID_t pMacGlobal, TX_TIMER *timer_ptr, + char *name_ptr, + v_VOID_t ( *expiration_function )( v_PVOID_t, tANI_U32 ), + tANI_U32 expiration_input, v_ULONG_t initScheduleTimeInTicks, + v_ULONG_t rescheduleTimeInTicks, v_ULONG_t auto_activate ) +{ + VOS_STATUS status; + + if((NULL == name_ptr) || (NULL == expiration_function)) + return TX_TIMER_ERROR; + + if (!initScheduleTimeInTicks) + return TX_TICK_ERROR; + + if (!timer_ptr) + return TX_TIMER_ERROR; + + // Initialize timer structure + timer_ptr->pExpireFunc = expiration_function; + timer_ptr->expireInput = expiration_input; + timer_ptr->initScheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * initScheduleTimeInTicks; + timer_ptr->rescheduleTimeInMsecs = + TX_MSECS_IN_1_TICK * rescheduleTimeInTicks; + timer_ptr->pMac = pMacGlobal; + + // Set the flag indicating that the timer was created + timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE; + +#ifdef WLAN_DEBUG + // Store the timer name + strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName)); +#endif // Store the timer name, for Debug build only + + status = vos_timer_init( &timer_ptr->vosTimer, VOS_TIMER_TYPE_SW, + tx_main_timer_func, (v_PVOID_t)timer_ptr ); + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Cannot create timer for %s\n", TIMER_NAME); + return TX_TIMER_ERROR; + } + + if(0 != rescheduleTimeInTicks) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Creating periodic timer for %s\n", TIMER_NAME); + } + + // Activate this timer if required + if (auto_activate) + { + tx_timer_activate(timer_ptr); + } + + return TX_SUCCESS; + +} //** tx_timer_create() ***/ +#endif + + +/**--------------------------------------------------------------------- + * tx_timer_deactivate() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_UINT_t tx_timer_deactivate(TX_TIMER *timer_ptr) +{ + VOS_STATUS vStatus; + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "tx_timer_deactivate() called for timer %s\n", TIMER_NAME); + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) + { + return TX_TIMER_ERROR; + } + + // if the timer is not running then we do not need to do anything here + vStatus = vos_timer_stop( &timer_ptr->vosTimer ); + if (VOS_STATUS_SUCCESS != vStatus) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO_HIGH, + "Unable to stop timer %s; status =%d\n", + TIMER_NAME, vStatus); + } + + return TX_SUCCESS; + +} /*** tx_timer_deactivate() ***/ + +v_UINT_t tx_timer_delete( TX_TIMER *timer_ptr ) +{ + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "tx_timer_delete() called for timer %s\n", TIMER_NAME); + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) + { + return TX_TIMER_ERROR; + } + + vos_timer_destroy( &timer_ptr->vosTimer ); + return TX_SUCCESS; +} /*** tx_timer_delete() ***/ + + + +/**--------------------------------------------------------------------- + * tx_timer_running() + * + * FUNCTION: + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param + * + * @return TX_SUCCESS. + * + */ +v_BOOL_t tx_timer_running(TX_TIMER *timer_ptr) +{ + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "tx_timer_running() called for timer %s\n", TIMER_NAME); + + // Put a check for the free builds + if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) + return VOS_FALSE; + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState( &timer_ptr->vosTimer )) + { + return VOS_TRUE; + } + return VOS_FALSE; + +} /*** tx_timer_running() ***/ diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDebug.h b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDebug.h new file mode 100644 index 000000000000..cc12426200dd --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDebug.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sysGlobal.h contains the logDump utility for system module. + * Author: V. K. Kandarpa + * Date: 01/24/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __SYS_DEBUG_H__ +#define __SYS_DEBUG_H__ + +#include +# include "utilsApi.h" +# include "sirDebug.h" +# include "sirParams.h" + +void sysLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...); + +#endif // __SYS_DEBUG_H__ diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDef.h b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDef.h new file mode 100644 index 000000000000..1839c14b389d --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysDef.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sysDef.h contains the common definitions used to bring up + * Sirius system. + * Author: V. K. Kandarpa + * Date: 04/13/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ + +#ifndef __SYSDEF_H +#define __SYSDEF_H + +/// Sirius system level definitions +// NOTE: Do not program system timer tick duration to less than 1msec + +/// System timer tick duration in nanoseconds +#define SYS_TICK_DUR_NS 10000000 // 10ms +#define SYS_TICK_TO_MICRO_SECOND 10000 + +/// System timer tick duration in milliseconds +#define SYS_TICK_DUR_MS (SYS_TICK_DUR_NS/1000000) + +/// Clocks in a millisecond +#define SYS_CLOCKS_PER_MS 120000 // 120 MHz + +// In Milliseconds +#define SYS_ADD_BA_RSP_DUR 1000 + +/// System timer tick duration in clocks +#define SYS_TICK_DUR_CLK (SYS_TICK_DUR_MS * SYS_CLOCKS_PER_MS) + +/// Number of timer ticks in a second +#define SYS_TICKS_PER_SECOND (1000/SYS_TICK_DUR_MS) + +/// Macro to convert MS to Ticks +#define SYS_MS_TO_TICKS(x) ((x) / SYS_TICK_DUR_MS) + +/// Macro to convert Seconds to Ticks +#define SYS_SEC_TO_TICKS(x) ((x) * SYS_TICKS_PER_SECOND) + +/// Macro to convert Minutes to Ticks +#define SYS_MIN_TO_TICKS(x) (((x) * 60) * SYS_TICKS_PER_SECOND) + +/// MNT task processing interval in seconds +#define SYS_MNT_INTERVAL 60 + +/// MS to Time Units +#define SYS_MS_TO_TU(x) ((x * 1000) >> 10) + +/// TU to MS +#define SYS_TU_TO_MS(x) ((x << 10) / 1000) + +// --------- End of Windows & RTAI ----------- + +/// Message queue definitions + +/// gHalMsgQ +# define SYS_HAL_Q_SIZE 200 // Holds up to 25 messages + +/// gMMHhiPriorityMsgQ +# define SYS_MMH_HI_PRI_Q_SIZE 200 // Holds up to 25 messages + +/// gMMHprotocolMsgQ +# define SYS_MMH_PROT_Q_SIZE 400 // Holds up to 50 messages + +/// gMMHdebugMsgQ +# define SYS_MMH_DEBUG_Q_SIZE 800 // Holds up to 100 messages + +/// gMAINTmsgQ +# define SYS_MNT_Q_SIZE 200 // Holds up to 25 messages + +/// LIM Message Queue +# define SYS_LIM_Q_SIZE 400 // Holds up to 50 messages + +/// Scheduler Message Queue +# define SYS_SCH_Q_SIZE 800 // Holds up to 25 messages + +/// PMM Message Queue +# define SYS_PMM_Q_SIZE 800 // Holds up to 100 messages + +/// TX Message Queue +# define SYS_TX_Q_SIZE 2048 // Holds up to 400 messages + +/// RX Message Queue +# define SYS_RX_Q_SIZE 2048 // Holds up to 400 messages + +/// PTT Message Queue +# define SYS_NIM_PTT_Q_SIZE 200 // Holds up to 25 messages + +/// Thread definitions +// tHAL + +# define SYS_HAL_THREAD_ENTRY_FUNCTION halEntry +# define SYS_HAL_STACK_SIZE 8192 +# define SYS_HAL_THREAD_PRIORITY 2 + +// tDPH + +# define SYS_DPH_THREAD_ENTRY_FUNCTION dphEntry +# define SYS_DPH_STACK_SIZE 8192 +# define SYS_DPH_THREAD_PRIORITY 15 + +// tBBT + +# define SYS_BBT_THREAD_ENTRY_FUNCTION bbtEntry +# define SYS_BBT_STACK_SIZE 8192 +# define SYS_BBT_THREAD_PRIORITY 16 + +// tSCH + +# define SYS_SCH_STACK_SIZE 8192 +# define SYS_SCH_THREAD_PRIORITY 17 + +// tPMM + +# define SYS_PMM_STACK_SIZE 8192 +# define SYS_PMM_THREAD_PRIORITY 17 + +// tLIM + +# define SYS_LIM_THREAD_ENTRY_FUNCTION limEntry +# define SYS_LIM_STACK_SIZE 8192 +# define SYS_LIM_THREAD_PRIORITY 18 + +// tMAINT + +# define SYS_MNT_THREAD_ENTRY_FUNCTION mntEntry +# define SYS_MNT_STACK_SIZE 8192 +# define SYS_MNT_THREAD_PRIORITY 25 + +// tMMH + +# define SYS_MMH_THREAD_ENTRY_FUNCTION mmhEntry +# define SYS_MMH_STACK_SIZE 8192 +# define SYS_MMH_THREAD_PRIORITY 10 + +// tNIM_MNT_PKT_GEN + +# define SYS_NIM_PTT_THREAD_STACK_SIZE 8192 +# define SYS_NIM_PTT_THREAD_PRIORITY 28 + +#endif // __SYSDEF_H diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h new file mode 100644 index 000000000000..800078fc31c0 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysEntryFunc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * This file sysEntryFunc.h contains module entry functions definitions + * Author: V. K. Kandarpa + * Date: 04/13/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + */ +#ifndef __SYS_ENTRY_FUNC_H +#define __SYS_ENTRY_FUNC_H + +#include "aniGlobal.h" + +extern tSirRetStatus sysInitGlobals(tpAniSirGlobal); +extern void sysBbtEntry(tANI_U32 dummy); +extern void sysSchEntry(tANI_U32 dummy); +extern void sysPmmEntry(tANI_U32 dummy); +extern void sysDphEntry(tANI_U32 dummy); +extern void sysLimEntry(tANI_U32 dummy); +extern void sysMmhEntry(tANI_U32 dummy); +extern void sysMntEntry(tANI_U32 dummy); +extern void sysHalEntry(tANI_U32 dummy); +extern void sysNimPttEntry(tANI_U32 dummy); + +#endif // __SYS_ENTRY_FUNC_H diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysStartup.h b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysStartup.h new file mode 100644 index 000000000000..b99c80379c39 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/inc/sysStartup.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + + * + * sysStartup.h: System startup header file. + * Author: V. K. Kandarpa + * Date: 01/29/2002 + * + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ + +# ifndef __SYSSTARTUP_H +# define __SYSSTARTUP_H + +#include "sirParams.h" + +/* Defines */ + +/* Function */ + +extern void sysMACCleanup(void *); +extern tSirRetStatus sysBbtProcessMessageCore(struct sAniSirGlobal *, tpSirMsgQ, + tANI_U32, tANI_U32); + + +# endif /* __SYSSTARTUP_H */ diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/src/macInitApi.c b/drivers/staging/prima/CORE/SYS/legacy/src/system/src/macInitApi.c new file mode 100644 index 000000000000..60a167877ae2 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/src/macInitApi.c @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * macInitApi.c - This file has all the mac level init functions + * for all the defined threads at system level. + * Author: Dinesh Upadhyay + * Date: 04/23/2007 + * History:- + * Date: 04/08/2008 Modified by: Santosh Mandiganal + * Modification Information: Code to allocate and free the memory for DumpTable entry. + * -------------------------------------------------------------------------- + * + */ +/* Standard include files */ +#include "cfgApi.h" // cfgCleanup +#include "limApi.h" // limCleanup +#include "sirTypes.h" +#include "sysDebug.h" +#include "sysEntryFunc.h" +#include "macInitApi.h" +#if defined(ANI_LOGDUMP) +#include "logDump.h" +#endif //#if defined(ANI_LOGDUMP) + +#ifdef TRACE_RECORD +#include "macTrace.h" +#endif + +extern tSirRetStatus halDoCfgInit(tpAniSirGlobal pMac); +extern tSirRetStatus halProcessStartEvent(tpAniSirGlobal pMac); + + + + +tSirRetStatus macReset(tpAniSirGlobal pMac, tANI_U32 rc); + +tSirRetStatus macPreStart(tHalHandle hHal) +{ + tSirRetStatus status = eSIR_SUCCESS; + tANI_BOOLEAN memAllocFailed = eANI_BOOLEAN_FALSE; + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + tANI_U8 i; + + for(i=0; idumpTableEntry[i] = vos_mem_malloc(sizeof(tDumpModuleEntry)); + if ( NULL == pMac->dumpTableEntry[i] ) + { + memAllocFailed = eANI_BOOLEAN_TRUE; + break; + } + else + { + vos_mem_set(pMac->dumpTableEntry[i], sizeof(tSirMbMsg), 0); + } + } + if( memAllocFailed ) + { + while(i>0) + { + i--; + vos_mem_free(pMac->dumpTableEntry[i]); + } + sysLog(pMac, LOGE, FL("pMac->dumpTableEntry is NULL\n")); + status = eSIR_FAILURE; + } + +#if defined(ANI_LOGDUMP) + //logDumpInit must be called before any module starts + logDumpInit(pMac); +#endif //#if defined(ANI_LOGDUMP) + + return status; +} + +tSirRetStatus macStart(tHalHandle hHal, void* pHalMacStartParams) +{ + tSirRetStatus status = eSIR_SUCCESS; + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + + if (NULL == pMac) + { + VOS_ASSERT(0); + status = eSIR_FAILURE; + return status; + } + + pMac->gDriverType = ((tHalMacStartParameters*)pHalMacStartParams)->driverType; + + sysLog(pMac, LOG2, FL("called\n")); + + do + { + pMac->pResetMsg = vos_mem_malloc(sizeof(tSirMbMsg)); + if ( NULL == pMac->pResetMsg ) + { + sysLog(pMac, LOGE, FL("pMac->pResetMsg is NULL\n")); + status = eSIR_FAILURE; + break; + } + else + { + vos_mem_set(pMac->pResetMsg, sizeof(tSirMbMsg), 0); + } + + if (pMac->gDriverType != eDRIVER_TYPE_MFG) + { + status = peStart(pMac); + } + + } while(0); + pMac->sys.abort = false; + + return status; +} + + +/** ------------------------------------------------------------- +\fn macStop +\brief this function will be called from HDD to stop MAC. This function will stop all the mac modules. +\ memory with global context will only be initialized not freed here. +\param tHalHandle hHal +\param tHalStopType +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus macStop(tHalHandle hHal, tHalStopType stopType) +{ + tANI_U8 i; + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + + //In FTM mode, peStart is not called during driver load. + if (pMac->gDriverType != eDRIVER_TYPE_MFG) + peStop(pMac); + + cfgCleanup( pMac ); + // need to free memory if not called in reset context. + // in reset context this memory will be freed by HDD. + if(false == pMac->sys.abort) + { + vos_mem_free(pMac->pResetMsg); + pMac->pResetMsg = NULL; + } + /* Free the DumpTableEntry */ + for(i=0; idumpTableEntry[i]); + } + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn macOpen +\brief this function will be called during init. This function is suppose to allocate all the +\ memory with the global context will be allocated here. +\param tHalHandle pHalHandle +\param tHddHandle hHdd +\param tHalOpenParameters* pHalOpenParams +\return tSirRetStatus + -------------------------------------------------------------*/ + +tSirRetStatus macOpen(tHalHandle *pHalHandle, tHddHandle hHdd, tMacOpenParameters *pMacOpenParms) +{ + tpAniSirGlobal pMac = NULL; + + if(pHalHandle == NULL) + return eSIR_FAILURE; + + /* + * Make sure this adapter is not already opened. (Compare pAdapter pointer in already + * allocated pMac structures.) + * If it is opened just return pointer to previously allocated pMac pointer. + * Or should this result in error? + */ + + /* Allocate pMac */ + pMac = vos_mem_vmalloc(sizeof(tAniSirGlobal)); + if ( NULL == pMac ) + return eSIR_FAILURE; + + /* Initialize the pMac structure */ + vos_mem_set(pMac, sizeof(tAniSirGlobal), 0); + + /** Store the Driver type in pMac Global.*/ + //pMac->gDriverType = pMacOpenParms->driverType; + + /* + * Set various global fields of pMac here + * (Could be platform dependant as some variables in pMac are platform + * dependant) + */ + pMac->hHdd = hHdd; + pMac->pAdapter = hHdd; //This line wil be removed + *pHalHandle = (tHalHandle)pMac; + + { + /* Call various PE (and other layer init here) */ + if( eSIR_SUCCESS != logInit(pMac)) + { + vos_mem_vfree(pMac); + return eSIR_FAILURE; + } + + /* Call routine to initialize CFG data structures */ + if( eSIR_SUCCESS != cfgInit(pMac) ) + { + vos_mem_vfree(pMac); + return eSIR_FAILURE; + } + + sysInitGlobals(pMac); + } + + + return peOpen(pMac, pMacOpenParms); +} + +/** ------------------------------------------------------------- +\fn macClose +\brief this function will be called in shutdown sequence from HDD. All the +\ allocated memory with global context will be freed here. +\param tpAniSirGlobal pMac +\return none + -------------------------------------------------------------*/ + +tSirRetStatus macClose(tHalHandle hHal) +{ + + tpAniSirGlobal pMac = (tpAniSirGlobal) hHal; + + peClose(pMac); + + /* Call routine to free-up all CFG data structures */ + cfgDeInit(pMac); + + logDeinit(pMac); + + // Finally, de-allocate the global MAC datastructure: + vos_mem_vfree( pMac ); + + return eSIR_SUCCESS; +} + +/** ------------------------------------------------------------- +\fn macReset +\brief this function is called to send Reset message to HDD. Then HDD will start the reset process. +\param tpAniSirGlobal pMac +\param tANI_U32 rc +\return tSirRetStatus. + -------------------------------------------------------------*/ + +tSirRetStatus macReset(tpAniSirGlobal pMac, tANI_U32 rc) +{ + tSirRetStatus status = eSIR_SUCCESS; + sysLog(pMac, LOGE, FL("*************No-op. Need to call WDA reset function \n")); + return status; +} + +// ---------------------------------------------------------------------- +/** + * macSysResetReq + * + * FUNCTION: + * All MAC modules use this interface in case of an exception. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param tANI_U32 reset reason code + * @return tANI_U16 - returs the status. + */ + +void +macSysResetReq(tpAniSirGlobal pMac, tANI_U32 rc) +{ + sysLog(pMac, LOGE, FL("Reason Code = 0x%X\n"),rc); + + switch (rc) + { + case eSIR_STOP_BSS: + case eSIR_SME_BSS_RESTART: + case eSIR_RADIO_HW_SWITCH_STATUS_IS_OFF: + case eSIR_CFB_FLAG_STUCK_EXCEPTION: + // FIXME + //macReset(pMac, rc); + break; + + case eSIR_EOF_SOF_EXCEPTION: + case eSIR_BMU_EXCEPTION: + case eSIR_CP_EXCEPTION: + case eSIR_LOW_PDU_EXCEPTION: + case eSIR_USER_TRIG_RESET: + case eSIR_AHB_HANG_EXCEPTION: + default: + macReset(pMac, rc); + break; + + } +} + +// ------------------------------------------------------------- +/** + * macSysResetReqFromHDD + * + * FUNCTION: + * This reset function gets invoked from the HDD to request a reset. + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @return tANI_U16 - returs the status. + */ + +void +macSysResetReqFromHDD(void *pMac, tANI_U32 rc) +{ + macSysResetReq( (tpAniSirGlobal)pMac, rc ); +} + diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysEntryFunc.c b/drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysEntryFunc.c new file mode 100644 index 000000000000..ffa574ab136e --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysEntryFunc.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * sysEntryFunc.cc - This file has all the system level entry functions + * for all the defined threads at system level. + * Author: V. K. Kandarpa + * Date: 01/16/2002 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------------- + * + */ +/* Standard include files */ + +/* Application Specific include files */ +#include "sirCommon.h" +#include "aniGlobal.h" + + +#include "limApi.h" +#include "schApi.h" +#include "utilsApi.h" +#include "pmmApi.h" + +#include "sysDebug.h" +#include "sysDef.h" +#include "sysEntryFunc.h" +#include "sysStartup.h" +#include "limTrace.h" +#include "wlan_qct_wda.h" + +tSirRetStatus +postPTTMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg); + +#include "vos_types.h" +#include "vos_packet.h" + +// --------------------------------------------------------------------------- +/** + * sysInitGlobals + * + * FUNCTION: + * Initializes system level global parameters + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param tpAniSirGlobal Sirius software parameter struct pointer + * @return None + */ + +tSirRetStatus +sysInitGlobals(tpAniSirGlobal pMac) +{ + + vos_mem_set((tANI_U8 *) &pMac->sys, sizeof(pMac->sys), 0); + + pMac->sys.gSysEnableScanMode = 1; + pMac->sys.gSysEnableLinkMonitorMode = 0; + schInitGlobals(pMac); + + return eSIR_SUCCESS; +} + +// --------------------------------------------------------------------------- +/** + * sysBbtProcessMessageCore + * + * FUNCTION: + * Process BBT messages + * + * LOGIC: + * + * ASSUMPTIONS: + * + * NOTE: + * + * @param tpAniSirGlobal A pointer to MAC params instance + * @param pMsg message pointer + * @param tANI_U32 type + * @param tANI_U32 sub type + * @return None + */ +tSirRetStatus +sysBbtProcessMessageCore(tpAniSirGlobal pMac, tpSirMsgQ pMsg, tANI_U32 type, + tANI_U32 subType) +{ + tSirRetStatus ret; + void* pBd; + tMgmtFrmDropReason dropReason; + vos_pkt_t *pVosPkt = (vos_pkt_t *)pMsg->bodyptr; + VOS_STATUS vosStatus = + WDA_DS_PeekRxPacketInfo( pVosPkt, (v_PVOID_t *)&pBd, VOS_FALSE ); + pMac->sys.gSysBbtReceived++; + + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + goto fail; + } + + PELOG3(sysLog(pMac, LOG3, FL("Rx Mgmt Frame Subtype: %d\n"), subType); + sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOG3, (tANI_U8 *)WDA_GET_RX_MAC_HEADER(pBd), WDA_GET_RX_MPDU_LEN(pBd)); + sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOG3, WDA_GET_RX_MPDU_DATA(pBd), WDA_GET_RX_PAYLOAD_LEN(pBd));) + + pMac->sys.gSysFrameCount[type][subType]++; + + if(type == SIR_MAC_MGMT_FRAME) + { + if ((subType == SIR_MAC_MGMT_DEAUTH || + subType == SIR_MAC_MGMT_DISASSOC)&& + limIsDeauthDiassocForDrop(pMac, pBd)) + goto fail; + + if( (dropReason = limIsPktCandidateForDrop(pMac, pBd, subType)) != eMGMT_DROP_NO_DROP) + { + PELOG1(sysLog(pMac, LOG1, FL("Mgmt Frame %d being dropped, reason: %d\n"), subType, dropReason);) + MTRACE(macTrace(pMac, TRACE_CODE_RX_MGMT_DROP, NO_SESSION, dropReason);) + goto fail; + } + //Post the message to PE Queue + ret = (tSirRetStatus) limPostMsgApi(pMac, pMsg); + if (ret != eSIR_SUCCESS) + { + PELOGE(sysLog(pMac, LOGE, FL("posting to LIM2 failed, ret %d\n"), ret);) + goto fail; + } + pMac->sys.gSysBbtPostedToLim++; + } + else if (type == SIR_MAC_DATA_FRAME) + { +#ifdef FEATURE_WLAN_ESE + PELOGW(sysLog(pMac, LOGW, FL("IAPP Frame...\n"));); + //Post the message to PE Queue + ret = (tSirRetStatus) limPostMsgApi(pMac, pMsg); + if (ret != eSIR_SUCCESS) + { + PELOGE(sysLog(pMac, LOGE, FL("posting to LIM2 failed, ret %d\n"), ret);) + goto fail; + } + pMac->sys.gSysBbtPostedToLim++; +#endif + } + else + { + PELOG3(sysLog(pMac, LOG3, "BBT received Invalid type %d subType %d " + "LIM state %X. BD dump is:\n", + type, subType, limGetSmeState(pMac)); + sirDumpBuf(pMac, SIR_SYS_MODULE_ID, LOG3, + (tANI_U8 *) pBd, WLANHAL_RX_BD_HEADER_SIZE);) + + goto fail; + } + + return eSIR_SUCCESS; + +fail: + + pMac->sys.gSysBbtDropped++; + return eSIR_FAILURE; +} + + +void sysLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) +{ + // Verify against current log level + if ( loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_SYS_MODULE_ID )] ) + return; + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_SYS_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +} + + + + + + diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysWinStartup.c b/drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysWinStartup.c new file mode 100644 index 000000000000..87b22738090f --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/system/src/sysWinStartup.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * + * sysWinStartup.cpp: System startup file for Windows platform. + * Author: Rajesh Bhagwat + * Date: 11/01/02 + * History:- + * 11/01/02 Created. + * -------------------------------------------------------------------- + * + */ + +#include "limApi.h" + +#include "utilsApi.h" +#include "sysEntryFunc.h" +#include "sysStartup.h" +#include "cfgApi.h" + +// Routine used to retrieve the Winwrapper context pointer from the pMac structure +extern tpAniSirTxWrapper sysGetTxWrapperContext(void *); + + +tpAniSirTxWrapper +sysGetTxWrapperContext(void *pMac) +{ + return &((tpAniSirGlobal)(pMac))->txWrapper; +} diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h b/drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h new file mode 100644 index 000000000000..e0e338bc6788 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/dot11fdefs.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 +#define DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 +/** + * \file dot11fdefs.h + * + * \brief C defines customizing our framesc-generated code + * + * + * + + * + * 'framesc' generates code written in terms of a number of macros + * intended for customization. + * + * + */ + +#include "parserApi.h" + +// This controls how the "dot11f" code copies memory +#define DOT11F_MEMCPY(ctx, dst, src, len) \ + vos_mem_copy( ( tANI_U8* )( dst ), ( tANI_U8* )( src ), ( len ) ) + +// This controls how the "dot11f" code compares memory +#define DOT11F_MEMCMP(ctx, lhs, rhs, len) \ + ( ! vos_mem_compare( ( tANI_U8* )( lhs ), ( tANI_U8* )( rhs ), ( len ) ) ) + +# if defined ( DBG ) && ( DBG != 0 ) + +# //define DOT11F_ENABLE_LOGGING +# //define DOT11F_DUMP_FRAMES +# define DOT11F_LOG_GATE ( 4 ) +# define FRAMES_SEV_FOR_FRAME(ctx, sig) \ + ( DOT11F_ASSOCREQUEST == (sig) ? 3 : 5 ) + + #if defined( DOT11F_ENABLE_LOGGING ) + +# define DOT11F_HAVE_LOG_MACROS + +# define FRAMES_LOG0(ctx, sev, fmt) \ + dot11fLog((ctx), (sev), (fmt)); + +# define FRAMES_LOG1(ctx, sev, fmt, p1) \ + dot11fLog((ctx), (sev), (fmt), (p1)); + +# define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \ + dot11fLog((ctx), (sev), (fmt), (p1), (p2)); + +# define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \ + dot11fLog((ctx), (sev), (fmt), (p1), (p2), (p3)); + +# define FRAMES_DUMP(ctx, sev, p, n) \ + sirDumpBuf((pCtx), SIR_DBG_MODULE_ID, (sev), (p), (n)); + + #endif //#if defined( DOT11F_ENABLE_LOGGING ) + +# else + +# undef DOT11F_ENABLE_LOGGING +# undef DOT11F_DUMP_FRAMES +# define DOT11F_LOG_GATE ( 1 ) + +# endif + + +// #define DOT11F_ENABLE_DBG_BREAK ( 1 ) + +// Local Variables: +// fill-column: 72 +// indent-tabs-mode: nil +// show-trailing-whitespace: t +// End: + +#endif // DOT11FDEFS_H_82A7B72E_C36C_465D_82A7_139EA5322582 diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/utilsParser.h b/drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/utilsParser.h new file mode 100644 index 000000000000..cc651c8fbd59 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/inc/utilsParser.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file utilsParser.h contains the utility function protos + * used internally by the parser + * Author: Chandra Modumudi + * Date: 02/11/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ +#ifndef __UTILS_PARSE_H__ +#define __UTILS_PARSE_H__ + +#include +#include "sirApi.h" +#include "dot11f.h" +#include "utilsApi.h" + +void ConvertSSID (tpAniSirGlobal, tSirMacSSid*, tDot11fIESSID*); +void ConvertSuppRates (tpAniSirGlobal, tSirMacRateSet*, tDot11fIESuppRates*); +void ConvertFHParams (tpAniSirGlobal, tSirMacFHParamSet*, tDot11fIEFHParamSet*); +void ConvertExtSuppRates (tpAniSirGlobal, tSirMacRateSet*, tDot11fIEExtSuppRates*); +void ConvertQOSCaps (tpAniSirGlobal, tSirMacQosCapabilityIE*, tDot11fIEQOSCapsAp*); +void ConvertQOSCapsStation (tpAniSirGlobal, tSirMacQosCapabilityStaIE*, tDot11fIEQOSCapsStation*); +tSirRetStatus ConvertWPA (tpAniSirGlobal, tSirMacWpaInfo*, tDot11fIEWPA*); +tSirRetStatus ConvertWPAOpaque (tpAniSirGlobal, tSirMacWpaInfo*, tDot11fIEWPAOpaque*); +tSirRetStatus ConvertRSN (tpAniSirGlobal, tSirMacRsnInfo*, tDot11fIERSN*); +tSirRetStatus ConvertRSNOpaque (tpAniSirGlobal, tSirMacRsnInfo*, tDot11fIERSNOpaque*); +void ConvertPowerCaps (tpAniSirGlobal, tSirMacPowerCapabilityIE*, tDot11fIEPowerCaps*); +void ConvertSuppChannels (tpAniSirGlobal, tSirMacSupportedChannelIE*, tDot11fIESuppChannels*); +void ConvertCFParams (tpAniSirGlobal, tSirMacCfParamSet*, tDot11fIECFParams*); +void ConvertTIM (tpAniSirGlobal, tSirMacTim*, tDot11fIETIM*); +void ConvertCountry (tpAniSirGlobal, tSirCountryInformation*, tDot11fIECountry*); +void ConvertWMMParams (tpAniSirGlobal, tSirMacEdcaParamSetIE*, tDot11fIEWMMParams*); +void ConvertERPInfo (tpAniSirGlobal, tSirMacErpInfo*, tDot11fIEERPInfo*); +void ConvertEDCAParam (tpAniSirGlobal, tSirMacEdcaParamSetIE*, tDot11fIEEDCAParamSet*); +void ConvertTSPEC (tpAniSirGlobal, tSirMacTspecIE*, tDot11fIETSPEC*); +tSirRetStatus ConvertTCLAS (tpAniSirGlobal, tSirTclasInfo*, tDot11fIETCLAS*); +void ConvertWMMTSPEC (tpAniSirGlobal, tSirMacTspecIE*, tDot11fIEWMMTSPEC*); +tSirRetStatus ConvertWMMTCLAS (tpAniSirGlobal, tSirTclasInfo*, tDot11fIEWMMTCLAS*); +void ConvertTSDelay (tpAniSirGlobal, tSirMacTsDelayIE*, tDot11fIETSDelay*); +void ConvertSchedule (tpAniSirGlobal, tSirMacScheduleIE*, tDot11fIESchedule*); +void ConvertWMMSchedule (tpAniSirGlobal, tSirMacScheduleIE*, tDot11fIEWMMSchedule*); +tSirRetStatus ConvertWscOpaque (tpAniSirGlobal, tSirAddie*, tDot11fIEWscIEOpaque*); +tSirRetStatus ConvertP2POpaque (tpAniSirGlobal, tSirAddie*, tDot11fIEP2PIEOpaque*); +#ifdef WLAN_FEATURE_WFD +tSirRetStatus ConvertWFDOpaque (tpAniSirGlobal, tSirAddie*, tDot11fIEWFDIEOpaque*); +#endif +void ConvertQosMapsetFrame(tpAniSirGlobal, tSirQosMapSet*, tDot11fIEQosMapSet*); + + +#endif diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c new file mode 100644 index 000000000000..a27f48aa954a --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/dot11f.c @@ -0,0 +1,46067 @@ +/* + * Copyright (c) 2012-2014, 2016, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * \file dot11f.c + * + * \brief Structures, functions & definitions for + * working with 802.11 Frames + * + * + * + * This file was automatically generated by 'framesc' + * Wed Jul 12 16:02:49 2017 from the following file(s): + * + * dot11f.frms + * + * PLEASE DON'T EDIT THIS FILE BY HAND! + * + * + */ + +#if !defined ANI_OS_TYPE_OSX && !defined ANI_OS_TYPE_LINUX && !defined ANI_OS_TYPE_ANDROID +#include /* For memcpy */ +#include /* For _vsnprintf */ +#include /* For offsetof */ +#endif + +#include +#include +#include "dot11fdefs.h" +#include "dot11f.h" + +#if defined ( _MSC_VER ) +# pragma warning (disable: 4244) +# pragma warning (disable: 4505) +# pragma warning (disable: 4702) +# pragma warning (disable: 4996) /* ... was declared deprecated */ +#endif /* Microsoft C/C++ */ + +typedef unsigned char tFRAMES_BOOL; +typedef void (*pfnGeneric_t)(void); + +typedef struct sFFDefn { + const char *name; + tANI_U32 offset; + tANI_U16 sig; + tANI_U8 size; +} tFFDefn; + +typedef struct sIEDefn { + tANI_U32 offset; + tANI_U32 presenceOffset; + tANI_U32 countOffset; + const char *name; + tANI_U16 arraybound; + tANI_U16 minSize; + tANI_U16 maxSize; + tANI_U16 sig; + unsigned char oui[5]; + unsigned char noui; + tANI_U8 eid; + tFRAMES_BOOL fMandatory; +} tIEDefn; + +#if !defined(countof) +#define countof(x) ( sizeof( (x) ) / sizeof( (x)[0] ) ) +#endif + +#if ! defined(DOT11F_MEMCPY) +# define DOT11F_MEMCPY(ctx, dst, src, len) \ + memcpy( (dst), (src), (len) ) \ + +#endif + +#if ! defined(DOT11F_MEMCMP) +# define DOT11F_MEMCMP(ctx, lhs, rhs, len) \ + memcmp( (lhs), (rhs), (len) ) \ + +#endif + +#ifndef DOT11F_HAVE_LOG_SEVERITIES +# define FRLOG_OFF ( 0 ) +# define FRLOGP ( 1 ) +# define FRLOGE ( 2 ) +# define FRLOGW ( 3 ) +# define FRLOG1 ( 4 ) +# define FRLOG2 ( 5 ) +# define FRLOG3 ( 6 ) +# define FRLOG4 ( 7 ) +#endif + +#define FRFL(x) x + +#ifdef DOT11F_ENABLE_LOGGING + +#ifndef DOT11F_HAVE_LOG_MACROS + +#include +#include + +#ifndef DOT11F_LOG_GATE +# define DOT11F_LOG_GATE FRLOGW +#endif // DOT11F_LOG_GATE + +#ifdef WIN32 + +#if defined ( _CONSOLE ) || defined ( _WINDOWS ) || defined ( _DLL ) || defined ( _LIB ) +#include +#define DBGPRINT OutputDebugStringA +#else /* Not User mode */ +#define DBGPRINT DbgPrint +#endif /* User mode */ + +static void framesLog(tpAniSirGlobal pCtx, int nSev, + const char *lpszFormat, ...) +{ +#ifdef WLAN_DEBUG + va_list val; + char buffer[1024]; + (void)pCtx; + if ( nSev <= DOT11F_LOG_GATE ) + { + va_start(val, lpszFormat); + _vsnprintf(buffer, 1024, lpszFormat, val); + va_end(val); + DBGPRINT(buffer); + } +#endif +} +static void framesDump(tpAniSirGlobal pCtx, int nSev, tANI_U8 *pBuf, int nBuf) +{ +#ifdef WLAN_DEBUG + char buffer[35]; + int i, offset; + pCtx; + offset = 0; + if ( nSev > DOT11F_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + _snprintf(buffer, 35, "%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + DBGPRINT(buffer); + } + _snprintf(buffer, 35, "%08x: ", offset); + DBGPRINT(buffer); + for (i = 0; i < nBuf % 8; ++i) + { + _snprintf(buffer, 35, "%02x ", *pBuf); + ++pBuf; + DBGPRINT(buffer); + } + DBGPRINT("\n"); +#endif +} + +#elif defined OS_X /* Not WIN32 */ +static void framesLog(tpAniSirGlobal pCtx, int nSev, + const char *lpszFormat, ...) +{// To fill in when needed using IOLog + +} + +static void framesDump(tpAniSirGlobal pCtx, int nSev, tANI_U8 *pBuf, int nBuf) +{ +} + +#elif defined LINUX + +static void framesLog(tpAniSirGlobal pCtx, int nSev, + const char *lpszFormat, ...) +{ +#ifdef WLAN_DEBUG + va_list marker; + (void)pCtx; + if ( nSev <= DOT11F_LOG_GATE ) + { + va_start( marker, lpszFormat ); + vprintf(lpszFormat, marker); + va_end( marker ); + } +#endif +} + +static void framesDump(tpAniSirGlobal pCtx, int nSev, tANI_U8 *pBuf, int nBuf) +{ +#ifdef WLAN_DEBUG + char buffer[35]; + int i, offset; + (void)pCtx; + offset = 0; + if ( nSev > DOT11F_LOG_GATE ) return; + for (i = 0; i < nBuf/8; ++i) + { + printf("%08x: %02x %02x %02x %02x %02x %02x %02x %02x\n", offset, *pBuf, *(pBuf + 1), *(pBuf + 2), *(pBuf + 3), *(pBuf + 4), *(pBuf + 5), *(pBuf + 6), *(pBuf + 7)); + pBuf += 8; offset += 8; + } + printf("%08x: ", offset); + for (i = 0; i < nBuf % 8; ++i) + { + printf("%02x ", *pBuf); + ++pBuf; + } + printf("\n"); +#endif +} + +#endif /* WIN32 */ + +#define FRAMES_LOG0(ctx, sev, fmt) \ + framesLog((ctx), (sev), (fmt)); +#define FRAMES_LOG1(ctx, sev, fmt, p1) \ + framesLog((ctx), (sev), (fmt), (p1)); +#define FRAMES_LOG2(ctx, sev, fmt, p1, p2) \ + framesLog((ctx), (sev), (fmt), (p1), (p2)); +#define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) \ + framesLog((ctx), (sev), (fmt), (p1), (p2), (p3)); +#define FRAMES_DUMP(ctx, sev, p, n) \ + framesDump((ctx), (sev), (p), (n)); +#ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +#endif + +#endif /* End DOT11F_HAVE_LOG_MACROS */ + +#else // ! DOT11F_ENABLE_LOGGING +# define FRAMES_LOG0(ctx, sev, fmt) +# define FRAMES_LOG1(ctx, sev, fmt, p1) +# define FRAMES_LOG2(ctx, sev, fmt, p1, p2) +# define FRAMES_LOG3(ctx, sev, fmt, p1, p2, p3) +# define FRAMES_DUMP(ctx, sev, p, n) +# ifndef FRAMES_SEV_FOR_FRAME +# define FRAMES_SEV_FOR_FRAME(ctx, sig) FRLOG3 +# endif +#endif // DOT11F_ENABLE_LOGGING + +#if defined( DOT11F_ENABLE_DBG_BREAK ) && defined ( WIN32 ) +# define FRAMES_DBG_BREAK() { _asm int 3 } +#else +# define FRAMES_DBG_BREAK() +#endif + +#if ! defined(DOT11F_PARAMETER_CHECK) +# if defined (DOT11F_HAVE_WIN32_API) + +# define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \ + if (!pBuf || IsBadReadPtr(pBuf, nBuf)) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pFrm || IsBadWritePtr(pFrm, nFrm)) return DOT11F_BAD_OUTPUT_BUFFER \ + +# define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \ + if (!pSrc || IsBadReadPtr(pSrc, 4)) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pBuf || IsBadWritePtr(pBuf, nBuf)) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (IsBadWritePtr(pnConsumed, 4)) return DOT11F_BAD_OUTPUT_BUFFER \ + +# else + +# define DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm) \ + if (!pBuf) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pFrm) return DOT11F_BAD_OUTPUT_BUFFER \ + +# define DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed) \ + if (!pSrc) return DOT11F_BAD_INPUT_BUFFER; \ + if (!pBuf) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (!nBuf) return DOT11F_BAD_OUTPUT_BUFFER; \ + if (!pnConsumed) return DOT11F_BAD_OUTPUT_BUFFER \ + +# endif +#endif + +static void framesntohs(tpAniSirGlobal pCtx, + tANI_U16 *pOut, + tANI_U8 *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, ( tANI_U16* )pOut, pIn, 2); + } + else + { + *pOut = ( tANI_U16 )( *pIn << 8 ) | *( pIn + 1 ); + } +# else + if ( !fMsb ) + { + *pOut = ( tANI_U16 )( *pIn | ( *( pIn + 1 ) << 8 ) ); + } + else + { + DOT11F_MEMCPY(pCtx, ( tANI_U16* )pOut, pIn, 2); + } +# endif +} + +static void framesntohl(tpAniSirGlobal pCtx, + tANI_U32 *pOut, + tANI_U8 *pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, ( tANI_U32* )pOut, pIn, 4); + } + else + { + *pOut = ( tANI_U32 )( *pIn << 24 ) | + ( *( pIn + 1 ) << 16 ) | + ( *( pIn + 2 ) << 8 ) | + ( *( pIn + 3 ) ); + } +# else + if ( !fMsb ) + { + *pOut = ( tANI_U32 )( *( pIn + 3 ) << 24 ) | + ( *( pIn + 2 ) << 16 ) | + ( *( pIn + 1 ) << 8 ) | + ( *( pIn ) ); + } + else + { + *pOut = * ( tANI_U32* )pIn; + } +# endif +} + +static void framesntohq(tpAniSirGlobal pCtx, + tDOT11F_U64 *pOut, + tANI_U8 *pIn, + tFRAMES_BOOL fMsb) +{ +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + framesntohl( pCtx, &((*pOut)[0]), pIn, fMsb); + framesntohl( pCtx, &((*pOut)[1]), pIn + 4, fMsb); +# else + framesntohl( pCtx, &((*pOut)[1]), pIn, fMsb); + framesntohl( pCtx, &((*pOut)[0]), pIn + 4, fMsb); +# endif +} + +static void frameshtons(tpAniSirGlobal pCtx +, tANI_U8 *pOut, + tANI_U16 pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } + else + { + *pOut = ( pIn & 0xff00 ) >> 8; + *( pOut + 1 ) = pIn & 0xff; + } +# else + if ( !fMsb ) + { + *pOut = pIn & 0xff; + *( pOut + 1 ) = ( pIn & 0xff00 ) >> 8; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 2); + } +# endif +} + +static void frameshtonl(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tANI_U32 pIn, + tFRAMES_BOOL fMsb) +{ + (void)pCtx; +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + if ( !fMsb ) + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } + else + { + *pOut = ( pIn & 0xff000000 ) >> 24; + *( pOut + 1 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 2 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 3 ) = ( pIn & 0x000000ff ); + } +# else + if ( !fMsb ) + { + *( pOut ) = ( pIn & 0x000000ff ); + *( pOut + 1 ) = ( pIn & 0x0000ff00 ) >> 8; + *( pOut + 2 ) = ( pIn & 0x00ff0000 ) >> 16; + *( pOut + 3 ) = ( pIn & 0xff000000 ) >> 24; + } + else + { + DOT11F_MEMCPY(pCtx, pOut, &pIn, 4); + } +# endif +} + +static void frameshtonq(tpAniSirGlobal pCtx, + tANI_U8 *pOut, + tDOT11F_U64 pIn, + tFRAMES_BOOL fMsb) +{ +# if defined ( DOT11F_LITTLE_ENDIAN_HOST ) + frameshtonl( pCtx, pOut, pIn[0], fMsb); + frameshtonl( pCtx, pOut + 4, pIn[1], fMsb); +# else + frameshtonl( pCtx, pOut + 4, pIn[1], fMsb); + frameshtonl( pCtx, pOut, pIn[0], fMsb); +# endif +} +static const tIEDefn* FindIEDefn(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tIEDefn IEs[]) +{ + const tIEDefn *pIe; + + (void)pCtx; + + pIe = &(IEs[0]); + while (0xff != pIe->eid) + { + if (*pBuf == pIe->eid) + { + if (0 == pIe->noui) return pIe; + + if ( ( nBuf > (tANI_U32)(pIe->noui + 2) ) && + ( !DOT11F_MEMCMP(pCtx, pBuf + 2, pIe->oui, pIe->noui) ) ) + return pIe; + } + + ++pIe; + } + + return NULL; +} + +static tANI_U32 GetContainerIesLen(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U8 *pnConsumed, + const tIEDefn IEs[]) +{ + const tIEDefn *pIe, *pIeFirst; + tANI_U8 *pBufRemaining = pBuf; + tANI_U32 len = 0; + + (void)pCtx; + + pIeFirst = &(IEs[0]); + + if( *pBufRemaining != pIeFirst->eid ) + return DOT11F_INTERNAL_ERROR; + len += *(pBufRemaining+1); + pBufRemaining += len + 2; + len += 2; + while ( len < nBuf ) + { + if( NULL == (pIe = FindIEDefn(pCtx, pBufRemaining, nBuf + len, IEs))) + break; + if( pIe->eid == pIeFirst->eid ) + break; + len += *(pBufRemaining + 1) + 2; + pBufRemaining += *(pBufRemaining + 1) + 2; + } + + *pnConsumed = len; + return DOT11F_PARSE_SUCCESS; + +} + + + +static tANI_U32 UnpackCore(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tFFDefn FFs[], + const tIEDefn IEs[], + tANI_U8 *pFrm, + size_t nFrm); +static tANI_U32 PackCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tFFDefn FFs[], + const tIEDefn IEs[]); +static tANI_U32 GetPackedSizeCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tIEDefn IEs[]); + + +tANI_U32 dot11fUnpackTlvCommonFunc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tANI_U8 *pDstPresent, tANI_U8 *pDstField) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)tlvlen; /* Shutup the compiler */ + + *pDstPresent = 1; + *pDstField = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvCommonFunc. */ + +tANI_U32 dot11fUnpackTlvCommonFunc2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tANI_U8 *pDstPresent, tANI_U16 *pDstState) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)tlvlen; /* Shutup the compiler */ + + *pDstPresent = 1; + framesntohs(pCtx, pDstState, pBuf, 1); + (void)pCtx; + return status; + +} /* End dot11fUnpackTlvCommonFunc2. */ + +void dot11fUnpackFfCommonFunc(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, tANI_U16 *pDstField) +{ + framesntohs(pCtx, pDstField, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfCommonFunc. */ + +tANI_U32 dot11fUnpackIeCommonFunc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, + tANI_U8 *pDstPresent , tANI_U8 *pDstField) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)ielen; + (void)pBuf; + if ((*pDstPresent)) status = DOT11F_DUPLICATE_IE; + *pDstPresent = 1; + *pDstField = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeComonFunc. */ +typedef struct sTLVDefn { + tANI_U32 offset; + tANI_U32 presenceOffset; + const char * name; + tANI_U16 sig; + tANI_U32 id; + tANI_U32 pec; + tANI_U32 minSize; + tANI_U32 maxSize; + tANI_U8 fMandatory; + tANI_U8 sType; + tANI_U8 sLen; + tANI_U8 fMsb; +} tTLVDefn; + +static const tTLVDefn* FindTLVDefn( tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tTLVDefn TLVs[ ] ) +{ + const tTLVDefn *pTlv; + tANI_U32 pec; + tANI_U16 id; + + pTlv = &( TLVs[ 0 ] ); + (void)pCtx; + if ( pTlv->sType == 2 ) + framesntohs( pCtx, &id, pBuf, 1 ); + else + id = *pBuf; + + while ( 0xffff != pTlv->id ) + { + if ( id == pTlv->id ) + { + if ( 0 == pTlv->pec ) return pTlv; + + if( nBuf > 5 ) + { + pec = ( ( * ( pBuf + 4 ) ) << 16 ) | + ( ( * ( pBuf + 5 ) ) << 8 ) | + * ( pBuf + 6 ); + if ( pec == pTlv->pec ) + { + return pTlv; + } + } + } + + ++pTlv; + } + + return NULL; +} + +static tANI_U32 UnpackTlvCore( tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tTLVDefn TLVs[ ], + tANI_U8 *pFrm, + size_t nFrm ); +static tANI_U32 PackTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tTLVDefn TLVs[], + tANI_U32 *pidx); +static tANI_U32 GetPackedSizeTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tTLVDefn TLVs[]); + +#define SigFfAID ( 0x0001 ) + +void dot11fUnpackFfAction(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfAction *pDst) +{ + pDst->action = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfAction. */ + +#define SigFfAction ( 0x0002 ) + +void dot11fUnpackFfAddBAParameterSet(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfAddBAParameterSet *pDst) +{ + tANI_U16 tmp0__; + framesntohs(pCtx, &tmp0__, pBuf, 0); + pDst->amsduSupported = tmp0__ >> 0 & 0x1; + pDst->policy = tmp0__ >> 1 & 0x1; + pDst->tid = tmp0__ >> 2 & 0xf; + pDst->bufferSize = tmp0__ >> 6 & 0x3ff; + (void)pCtx; +} /* End dot11fUnpackFfAddBAParameterSet. */ + +#define SigFfAddBAParameterSet ( 0x0003 ) + +#define SigFfAuthAlgo ( 0x0004 ) + +#define SigFfAuthSeqNo ( 0x0005 ) + +void dot11fUnpackFfBAStartingSequenceControl(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfBAStartingSequenceControl *pDst) +{ + tANI_U16 tmp1__; + framesntohs(pCtx, &tmp1__, pBuf, 0); + pDst->fragNumber = tmp1__ >> 0 & 0xf; + pDst->ssn = tmp1__ >> 4 & 0xfff; + (void)pCtx; +} /* End dot11fUnpackFfBAStartingSequenceControl. */ + +#define SigFfBAStartingSequenceControl ( 0x0006 ) + +#define SigFfBATimeout ( 0x0007 ) + +#define SigFfBeaconInterval ( 0x0008 ) + +void dot11fUnpackFfCapabilities(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfCapabilities *pDst) +{ + tANI_U16 tmp2__; + framesntohs(pCtx, &tmp2__, pBuf, 0); + pDst->ess = tmp2__ >> 0 & 0x1; + pDst->ibss = tmp2__ >> 1 & 0x1; + pDst->cfPollable = tmp2__ >> 2 & 0x1; + pDst->cfPollReq = tmp2__ >> 3 & 0x1; + pDst->privacy = tmp2__ >> 4 & 0x1; + pDst->shortPreamble = tmp2__ >> 5 & 0x1; + pDst->pbcc = tmp2__ >> 6 & 0x1; + pDst->channelAgility = tmp2__ >> 7 & 0x1; + pDst->spectrumMgt = tmp2__ >> 8 & 0x1; + pDst->qos = tmp2__ >> 9 & 0x1; + pDst->shortSlotTime = tmp2__ >> 10 & 0x1; + pDst->apsd = tmp2__ >> 11 & 0x1; + pDst->rrm = tmp2__ >> 12 & 0x1; + pDst->dsssOfdm = tmp2__ >> 13 & 0x1; + pDst->delayedBA = tmp2__ >> 14 & 0x1; + pDst->immediateBA = tmp2__ >> 15 & 0x1; + (void)pCtx; +} /* End dot11fUnpackFfCapabilities. */ + +#define SigFfCapabilities ( 0x0009 ) + +void dot11fUnpackFfCategory(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfCategory *pDst) +{ + pDst->category = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfCategory. */ + +#define SigFfCategory ( 0x000a ) + +void dot11fUnpackFfCurrentAPAddress(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfCurrentAPAddress *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6); + (void)pCtx; +} /* End dot11fUnpackFfCurrentAPAddress. */ + +#define SigFfCurrentAPAddress ( 0x000b ) + +void dot11fUnpackFfDelBAParameterSet(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfDelBAParameterSet *pDst) +{ + tANI_U16 tmp3__; + framesntohs(pCtx, &tmp3__, pBuf, 0); + pDst->reserved = tmp3__ >> 0 & 0x7ff; + pDst->initiator = tmp3__ >> 11 & 0x1; + pDst->tid = tmp3__ >> 12 & 0xf; + (void)pCtx; +} /* End dot11fUnpackFfDelBAParameterSet. */ + +#define SigFfDelBAParameterSet ( 0x000c ) + +void dot11fUnpackFfDialogToken(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfDialogToken *pDst) +{ + pDst->token = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfDialogToken. */ + +#define SigFfDialogToken ( 0x000d ) + +void dot11fUnpackFfLinkMargin(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfLinkMargin *pDst) +{ + pDst->linkMargin = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfLinkMargin. */ + +#define SigFfLinkMargin ( 0x000e ) + +#define SigFfListenInterval ( 0x000f ) + +void dot11fUnpackFfMagicCode(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfMagicCode *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->magic, pBuf, 6); + (void)pCtx; +} /* End dot11fUnpackFfMagicCode. */ + +#define SigFfMagicCode ( 0x0010 ) + +void dot11fUnpackFfMaxTxPower(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfMaxTxPower *pDst) +{ + pDst->maxTxPower = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfMaxTxPower. */ + +#define SigFfMaxTxPower ( 0x0011 ) + +void dot11fUnpackFfNumOfRepetitions(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfNumOfRepetitions *pDst) +{ + framesntohs(pCtx, &pDst->repetitions, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfNumOfRepetitions. */ + +#define SigFfNumOfRepetitions ( 0x0012 ) + +void dot11fUnpackFfOperatingMode(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfOperatingMode *pDst) +{ + tANI_U8 tmp4__; + tmp4__ = *pBuf; + pDst->chanWidth = tmp4__ >> 0 & 0x3; + pDst->reserved = tmp4__ >> 2 & 0x3; + pDst->rxNSS = tmp4__ >> 4 & 0x7; + pDst->rxNSSType = tmp4__ >> 7 & 0x1; + (void)pCtx; +} /* End dot11fUnpackFfOperatingMode. */ + +#define SigFfOperatingMode ( 0x0013 ) + +void dot11fUnpackFfP2POUI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfP2POUI *pDst) +{ + framesntohl(pCtx, &pDst->oui, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfP2POUI. */ + +#define SigFfP2POUI ( 0x0014 ) + +void dot11fUnpackFfP2POUISubType(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfP2POUISubType *pDst) +{ + pDst->ouiSubtype = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfP2POUISubType. */ + +#define SigFfP2POUISubType ( 0x0015 ) + +void dot11fUnpackFfRCPI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRCPI *pDst) +{ + pDst->rcpi = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRCPI. */ + +#define SigFfRCPI ( 0x0016 ) + +void dot11fUnpackFfRMCDialogToken(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRMCDialogToken *pDst) +{ + framesntohl(pCtx, &pDst->token, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfRMCDialogToken. */ + +#define SigFfRMCDialogToken ( 0x0017 ) + +void dot11fUnpackFfRMCOUI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRMCOUI *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 3); + (void)pCtx; +} /* End dot11fUnpackFfRMCOUI. */ + +#define SigFfRMCOUI ( 0x0018 ) + +void dot11fUnpackFfRMCVersion(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRMCVersion *pDst) +{ + pDst->version = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRMCVersion. */ + +#define SigFfRMCVersion ( 0x0019 ) + +void dot11fUnpackFfRSNI(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRSNI *pDst) +{ + pDst->rsni = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRSNI. */ + +#define SigFfRSNI ( 0x001a ) + +#define SigFfReason ( 0x001b ) + +void dot11fUnpackFfRuler(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRuler *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6); + (void)pCtx; +} /* End dot11fUnpackFfRuler. */ + +#define SigFfRuler ( 0x001c ) + +void dot11fUnpackFfRxAntennaId(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfRxAntennaId *pDst) +{ + pDst->antennaId = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfRxAntennaId. */ + +#define SigFfRxAntennaId ( 0x001d ) + +void dot11fUnpackFfSMPowerModeSet(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfSMPowerModeSet *pDst) +{ + tANI_U8 tmp5__; + tmp5__ = *pBuf; + pDst->PowerSave_En = tmp5__ >> 0 & 0x1; + pDst->Mode = tmp5__ >> 1 & 0x1; + pDst->reserved = tmp5__ >> 2 & 0x3f; + (void)pCtx; +} /* End dot11fUnpackFfSMPowerModeSet. */ + +#define SigFfSMPowerModeSet ( 0x001e ) + +#define SigFfStatus ( 0x001f ) + +void dot11fUnpackFfStatusCode(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfStatusCode *pDst) +{ + pDst->statusCode = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfStatusCode. */ + +#define SigFfStatusCode ( 0x0020 ) + +void dot11fUnpackFfTPCEleID(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTPCEleID *pDst) +{ + pDst->TPCId = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTPCEleID. */ + +#define SigFfTPCEleID ( 0x0021 ) + +void dot11fUnpackFfTPCEleLen(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTPCEleLen *pDst) +{ + pDst->TPCLen = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTPCEleLen. */ + +#define SigFfTPCEleLen ( 0x0022 ) + +void dot11fUnpackFfTSInfo(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTSInfo *pDst) +{ + tANI_U32 tmp6__; + framesntohl(pCtx, &tmp6__, pBuf, 0); + pDst->traffic_type = tmp6__ >> 0 & 0x1; + pDst->tsid = tmp6__ >> 1 & 0xf; + pDst->direction = tmp6__ >> 5 & 0x3; + pDst->access_policy = tmp6__ >> 7 & 0x3; + pDst->aggregation = tmp6__ >> 9 & 0x1; + pDst->psb = tmp6__ >> 10 & 0x1; + pDst->user_priority = tmp6__ >> 11 & 0x7; + pDst->tsinfo_ack_pol = tmp6__ >> 14 & 0x3; + pDst->schedule = tmp6__ >> 16 & 0x1; + pDst->unused = tmp6__ >> 17 & 0x7fff; + (void)pCtx; +} /* End dot11fUnpackFfTSInfo. */ + +#define SigFfTSInfo ( 0x0023 ) + +void dot11fUnpackFfTimeStamp(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTimeStamp *pDst) +{ + framesntohq(pCtx, &pDst->timestamp, pBuf, 0); + (void)pCtx; +} /* End dot11fUnpackFfTimeStamp. */ + +#define SigFfTimeStamp ( 0x0024 ) + +void dot11fUnpackFfTransactionId(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTransactionId *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->transId, pBuf, 2); + (void)pCtx; +} /* End dot11fUnpackFfTransactionId. */ + +#define SigFfTransactionId ( 0x0025 ) + +void dot11fUnpackFfTxAntennaId(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTxAntennaId *pDst) +{ + pDst->antennaId = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTxAntennaId. */ + +#define SigFfTxAntennaId ( 0x0026 ) + +void dot11fUnpackFfTxPower(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfTxPower *pDst) +{ + pDst->txPower = *pBuf; + (void)pCtx; +} /* End dot11fUnpackFfTxPower. */ + +#define SigFfTxPower ( 0x0027 ) + +void dot11fUnpackFfVhtMembershipStatusArray(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfVhtMembershipStatusArray *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->membershipStatusArray, pBuf, 8); + (void)pCtx; +} /* End dot11fUnpackFfVhtMembershipStatusArray. */ + +#define SigFfVhtMembershipStatusArray ( 0x0028 ) + +void dot11fUnpackFfVhtUserPositionArray(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tDot11fFfVhtUserPositionArray *pDst) +{ + DOT11F_MEMCPY(pCtx, pDst->userPositionArray, pBuf, 16); + (void)pCtx; +} /* End dot11fUnpackFfVhtUserPositionArray. */ + +#define SigFfVhtUserPositionArray ( 0x0029 ) + +tANI_U32 dot11fUnpackTlvAuthorizedMACs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVAuthorizedMACs *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->mac, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvAuthorizedMACs. */ + +#define SigTlvAuthorizedMACs ( 0x0001 ) + + +#define SigTlvRequestToEnroll ( 0x0002 ) + + +tANI_U32 dot11fUnpackTlvVersion2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVVersion2 *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp7__; + pDst->present = 1; + tmp7__ = *pBuf; + pBuf += 1; + tlvlen -= 1; + pDst->minor = tmp7__ >> 0 & 0xf; + pDst->major = tmp7__ >> 4 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvVersion2. */ + +#define SigTlvVersion2 ( 0x0003 ) + + +#define SigTlvAPSetupLocked ( 0x0004 ) + + +#define SigTlvAssociationState ( 0x0005 ) + + +tANI_U32 dot11fUnpackTlvChannelList(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVChannelList *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + pDst->num_channelList = (tANI_U8)( tlvlen ); + if (tlvlen > 251){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvChannelList. */ + +#define SigTlvChannelList ( 0x0006 ) + + +#define SigTlvConfigMethods ( 0x0007 ) + + +#define SigTlvConfigurationError ( 0x0008 ) + + +tANI_U32 dot11fUnpackTlvConfigurationTimeout(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVConfigurationTimeout *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->GOConfigTimeout = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->CLConfigTimeout = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvConfigurationTimeout. */ + +#define SigTlvConfigurationTimeout ( 0x0009 ) + + +tANI_U32 dot11fUnpackTlvDeviceName(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVDeviceName *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvDeviceName. */ + +#define SigTlvDeviceName ( 0x000a ) + + +#define SigTlvDevicePasswordID ( 0x000b ) + + +tANI_U32 dot11fUnpackTlvExtendedListenTiming(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVExtendedListenTiming *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + framesntohs(pCtx, &pDst->availibilityPeriod, pBuf, 0); + pBuf += 2; + tlvlen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->availibilityInterval, pBuf, 0); + pBuf += 2; + tlvlen -= (tANI_U8)2; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvExtendedListenTiming. */ + +#define SigTlvExtendedListenTiming ( 0x000c ) + + +#define SigTlvGOIntent ( 0x000d ) + + +tANI_U32 dot11fUnpackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVIntendedP2PInterfaceAddress *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PInterfaceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvIntendedP2PInterfaceAddress. */ + +#define SigTlvIntendedP2PInterfaceAddress ( 0x000e ) + + +#define SigTlvInvitationFlags ( 0x000f ) + + +tANI_U32 dot11fUnpackTlvListenChannel(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVListenChannel *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->channel = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvListenChannel. */ + +#define SigTlvListenChannel ( 0x0010 ) + + +tANI_U32 dot11fUnpackTlvManufacturer(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVManufacturer *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_name = (tANI_U8)( tlvlen ); + if (tlvlen > 64){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->name, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvManufacturer. */ + +#define SigTlvManufacturer ( 0x0011 ) + + +#define SigTlvMinorReasonCode ( 0x0012 ) + + +tANI_U32 dot11fUnpackTlvModelName(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVModelName *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvModelName. */ + +#define SigTlvModelName ( 0x0013 ) + + +tANI_U32 dot11fUnpackTlvModelNumber(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVModelNumber *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvModelNumber. */ + +#define SigTlvModelNumber ( 0x0014 ) + + +tANI_U32 dot11fUnpackTlvNoticeOfAbsence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVNoticeOfAbsence *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->index = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->CTSWindowOppPS = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->num_NoADesc = (tANI_U8)( tlvlen ); + if (tlvlen > 36){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->NoADesc, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvNoticeOfAbsence. */ + +#define SigTlvNoticeOfAbsence ( 0x0015 ) + + +tANI_U32 dot11fUnpackTlvOperatingChannel(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVOperatingChannel *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryString, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->channel = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvOperatingChannel. */ + +#define SigTlvOperatingChannel ( 0x0016 ) + + +tANI_U32 dot11fUnpackTlvP2PCapability(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PCapability *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->deviceCapability = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + pDst->groupCapability = *pBuf; + pBuf += 1; + tlvlen -= (tANI_U8)1; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PCapability. */ + +#define SigTlvP2PCapability ( 0x0017 ) + + +tANI_U32 dot11fUnpackTlvP2PDeviceId(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PDeviceId *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PDeviceId. */ + +#define SigTlvP2PDeviceId ( 0x0018 ) + + + static const tTLVDefn TLVS_P2PDeviceInfo[] = { + {offsetof(tDot11fTLVP2PDeviceInfo, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackTlvP2PDeviceInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PDeviceInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + framesntohs(pCtx, &pDst->configMethod, pBuf, 0); + pBuf += 2; + tlvlen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->primaryDeviceType, pBuf, 8); + pBuf += 8; + tlvlen -= (tANI_U8)8; + (void)pCtx; + status |= UnpackTlvCore(pCtx, + pBuf, + tlvlen, + TLVS_P2PDeviceInfo, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackTlvP2PDeviceInfo. */ + +#define SigTlvP2PDeviceInfo ( 0x0019 ) + + +tANI_U32 dot11fUnpackTlvP2PGroupBssid(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PGroupBssid *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PGroupBssid, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PGroupBssid. */ + +#define SigTlvP2PGroupBssid ( 0x001a ) + + +tANI_U32 dot11fUnpackTlvP2PGroupId(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PGroupId *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->deviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + pDst->num_ssid = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->ssid, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PGroupId. */ + +#define SigTlvP2PGroupId ( 0x001b ) + + +tANI_U32 dot11fUnpackTlvP2PGroupInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PGroupInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_P2PClientInfoDesc = (tANI_U8)( tlvlen ); + DOT11F_MEMCPY(pCtx, pDst->P2PClientInfoDesc, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PGroupInfo. */ + +#define SigTlvP2PGroupInfo ( 0x001c ) + + +#define SigTlvP2PStatus ( 0x001d ) + + +tANI_U32 dot11fUnpackTlvPrimaryDeviceType(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVPrimaryDeviceType *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)tlvlen; /* Shutup the compiler */ + pDst->present = 1; + framesntohs(pCtx, &pDst->primary_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4); + pBuf += 4; + tlvlen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->sub_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvPrimaryDeviceType. */ + +#define SigTlvPrimaryDeviceType ( 0x001e ) + + +#define SigTlvRFBands ( 0x001f ) + + +tANI_U32 dot11fUnpackTlvRequestDeviceType(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVRequestDeviceType *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + framesntohs(pCtx, &pDst->primary_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->oui, pBuf, 4); + pBuf += 4; + tlvlen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->sub_category, pBuf, 1); + pBuf += 2; + tlvlen -= (tANI_U8)2; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvRequestDeviceType. */ + +#define SigTlvRequestDeviceType ( 0x0020 ) + + +#define SigTlvRequestType ( 0x0021 ) + + +#define SigTlvResponseType ( 0x0022 ) + + +#define SigTlvSelectedRegistrar ( 0x0023 ) + + +#define SigTlvSelectedRegistrarConfigMethods ( 0x0024 ) + + +tANI_U32 dot11fUnpackTlvSerialNumber(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVSerialNumber *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + pDst->num_text = (tANI_U8)( tlvlen ); + if (tlvlen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( tlvlen ) ); + pBuf += ( tlvlen ); + tlvlen -= ( tlvlen ); + (void)pCtx; + return status; +} /* End dot11fUnpackTlvSerialNumber. */ + +#define SigTlvSerialNumber ( 0x0025 ) + + +tANI_U32 dot11fUnpackTlvUUID_E(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVUUID_E *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16); + pBuf += 16; + tlvlen -= (tANI_U8)16; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvUUID_E. */ + +#define SigTlvUUID_E ( 0x0026 ) + + +tANI_U32 dot11fUnpackTlvUUID_R(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVUUID_R *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->uuid, pBuf, 16); + pBuf += 16; + tlvlen -= (tANI_U8)16; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvUUID_R. */ + +#define SigTlvUUID_R ( 0x0027 ) + + + static const tTLVDefn TLVS_VendorExtension[] = { + {offsetof(tDot11fTLVVendorExtension, Version2), offsetof(tDot11fTLVVersion2, present), "Version2", SigTlvVersion2, DOT11F_TLV_VERSION2, 0, 3, 3, 0, 1, 1, 1, }, + {offsetof(tDot11fTLVVendorExtension, AuthorizedMACs), offsetof(tDot11fTLVAuthorizedMACs, present), "AuthorizedMACs", SigTlvAuthorizedMACs, DOT11F_TLV_AUTHORIZEDMACS, 0, 8, 8, 0, 1, 1, 1, }, + {offsetof(tDot11fTLVVendorExtension, RequestToEnroll), offsetof(tDot11fTLVRequestToEnroll, present), "RequestToEnroll", SigTlvRequestToEnroll, DOT11F_TLV_REQUESTTOENROLL, 0, 3, 3, 0, 1, 1, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackTlvVendorExtension(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVVendorExtension *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->vendorId, pBuf, 3); + pBuf += 3; + tlvlen -= (tANI_U8)3; + (void)pCtx; + status |= UnpackTlvCore(pCtx, + pBuf, + tlvlen, + TLVS_VendorExtension, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackTlvVendorExtension. */ + +#define SigTlvVendorExtension ( 0x0028 ) + + +tANI_U32 dot11fUnpackTlvVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVVersion *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp8__; + pDst->present = 1; + tmp8__ = *pBuf; + pBuf += 1; + tlvlen -= 1; + pDst->minor = tmp8__ >> 0 & 0xf; + pDst->major = tmp8__ >> 4 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvVersion. */ + +#define SigTlvVersion ( 0x0029 ) + + +#define SigTlvWPSState ( 0x002a ) + + +tANI_U32 dot11fUnpackTlvP2PInterface(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U16 tlvlen, tDot11fTLVP2PInterface *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->P2PDeviceAddress, pBuf, 6); + pBuf += 6; + tlvlen -= (tANI_U8)6; + (void)pCtx; + return status; +} /* End dot11fUnpackTlvP2PInterface. */ + +#define SigTlvP2PInterface ( 0x002b ) + + +#define SigTlvP2PManageability ( 0x002c ) + + +tANI_U32 dot11fUnpackIeAPName(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAPName *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_name = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->name, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeAPName. */ + +#define SigIeAPName ( 0x0001 ) + + +tANI_U32 dot11fUnpackIeBPIndicator(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBPIndicator *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->indicator = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->type = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeBPIndicator. */ + +#define SigIeBPIndicator ( 0x0002 ) + + +tANI_U32 dot11fUnpackIeCondensedCountryStr(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIECondensedCountryStr *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->countryStr, pBuf, 2); + (void)pCtx; + return status; +} /* End dot11fUnpackIeCondensedCountryStr. */ + +#define SigIeCondensedCountryStr ( 0x0003 ) + + +tANI_U32 dot11fUnpackIeGTK(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEGTK *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp9__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp9__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->keyId = tmp9__ >> 0 & 0x3; + pDst->reserved = tmp9__ >> 2 & 0x3feb; + pDst->keyLength = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->RSC, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + pDst->num_key = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->key, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeGTK. */ + +#define SigIeGTK ( 0x0004 ) + + +#define SigIeHCF ( 0x0005 ) + + +tANI_U32 dot11fUnpackIeIGTK(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEIGTK *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->keyID, pBuf, 2); + pBuf += 2; + ielen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->IPN, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + pDst->keyLength = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->key, pBuf, 24); + (void)pCtx; + return status; +} /* End dot11fUnpackIeIGTK. */ + +#define SigIeIGTK ( 0x0006 ) + + +tANI_U32 dot11fUnpackIeLLAttr(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELLAttr *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &pDst->defer_threshold, pBuf, 1); + (void)pCtx; + return status; +} /* End dot11fUnpackIeLLAttr. */ + +#define SigIeLLAttr ( 0x0007 ) + + +tANI_U32 dot11fUnpackIeLoadBalance(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELoadBalance *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + pDst->channel = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeLoadBalance. */ + +#define SigIeLoadBalance ( 0x0008 ) + + +tANI_U32 dot11fUnpackIeLoadInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELoadInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->num_stas, pBuf, 1); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->channel_util, pBuf, 1); + (void)pCtx; + return status; +} /* End dot11fUnpackIeLoadInfo. */ + +#define SigIeLoadInfo ( 0x0009 ) + + +#define SigIePropAssocType ( 0x000a ) + + +tANI_U32 dot11fUnpackIePropCapability(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropCapability *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->capability, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePropCapability. */ + +#define SigIePropCapability ( 0x000b ) + + +tANI_U32 dot11fUnpackIePropChannSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropChannSwitchAnn *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->mode = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->primary_channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->sub_band = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->channel_switch_count = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePropChannSwitchAnn. */ + +#define SigIePropChannSwitchAnn ( 0x000c ) + + +tANI_U32 dot11fUnpackIePropEDCAParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropEDCAParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp10__; + tANI_U8 tmp11__; + tANI_U8 tmp12__; + tANI_U8 tmp13__; + tANI_U8 tmp14__; + tANI_U8 tmp15__; + tANI_U8 tmp16__; + tANI_U8 tmp17__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->qos = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp10__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_aifsn = tmp10__ >> 0 & 0xf; + pDst->acbe_acm = tmp10__ >> 4 & 0x1; + pDst->acbe_aci = tmp10__ >> 5 & 0x3; + pDst->unused1 = tmp10__ >> 7 & 0x1; + tmp11__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_min = tmp11__ >> 0 & 0xf; + pDst->acbe_max = tmp11__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp12__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_aifsn = tmp12__ >> 0 & 0xf; + pDst->acbk_acm = tmp12__ >> 4 & 0x1; + pDst->acbk_aci = tmp12__ >> 5 & 0x3; + pDst->unused2 = tmp12__ >> 7 & 0x1; + tmp13__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_min = tmp13__ >> 0 & 0xf; + pDst->acbk_max = tmp13__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp14__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_aifsn = tmp14__ >> 0 & 0xf; + pDst->acvi_acm = tmp14__ >> 4 & 0x1; + pDst->acvi_aci = tmp14__ >> 5 & 0x3; + pDst->unused3 = tmp14__ >> 7 & 0x1; + tmp15__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_min = tmp15__ >> 0 & 0xf; + pDst->acvi_max = tmp15__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp16__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_aifsn = tmp16__ >> 0 & 0xf; + pDst->acvo_acm = tmp16__ >> 4 & 0x1; + pDst->acvo_aci = tmp16__ >> 5 & 0x3; + pDst->unused4 = tmp16__ >> 7 & 0x1; + tmp17__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_min = tmp17__ >> 0 & 0xf; + pDst->acvo_max = tmp17__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePropEDCAParams. */ + +#define SigIePropEDCAParams ( 0x000d ) + + +tANI_U32 dot11fUnpackIePropQuietBSS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropQuietBSS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->quiet_count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->quiet_period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->quiet_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->quiet_offset, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePropQuietBSS. */ + +#define SigIePropQuietBSS ( 0x000e ) + + +tANI_U32 dot11fUnpackIePropSuppRates(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPropSuppRates *pDst) +{ + tANI_U8 i; + tANI_U8 rate_indx = 0; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + for (i = 0; i < ielen; i++) { + if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) && + (rate_indx < 12)) { + pDst->rates[rate_indx++] = pBuf[i]; + } + } + + if(rate_indx == 0) { + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + pDst->num_rates = rate_indx; + (void)pCtx; + return status; +} /* End dot11fUnpackIePropSuppRates. */ + +#define SigIePropSuppRates ( 0x000f ) + + +tANI_U32 dot11fUnpackIeR0KH_ID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIER0KH_ID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_PMK_R0_ID = (tANI_U8)( ielen ); + if (ielen > 48){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->PMK_R0_ID, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeR0KH_ID. */ + +#define SigIeR0KH_ID ( 0x0010 ) + + +tANI_U32 dot11fUnpackIeR1KH_ID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIER1KH_ID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->PMK_R1_ID, pBuf, 6); + (void)pCtx; + return status; +} /* End dot11fUnpackIeR1KH_ID. */ + +#define SigIeR1KH_ID ( 0x0011 ) + + +tANI_U32 dot11fUnpackIeTSFInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETSFInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->TsfOffset, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->BeaconIntvl, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTSFInfo. */ + +#define SigIeTSFInfo ( 0x0012 ) + + +tANI_U32 dot11fUnpackIeTaurus(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETaurus *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp18__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->baTIDBitmap, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->baPolicy, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &tmp18__, pBuf, 0); + pDst->baBufferSize = tmp18__ >> 0 & 0xfff; + pDst->rsvd = tmp18__ >> 12 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTaurus. */ + +#define SigIeTaurus ( 0x0013 ) + + +tANI_U32 dot11fUnpackIeTitan(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETitan *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->concat_tcid_bitmap = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->compression_tcid_bitmap = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->cb_state = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->rev_fcs_state = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTitan. */ + +#define SigIeTitan ( 0x0014 ) + + +#define SigIeTriggerStaBgScan ( 0x0015 ) + + +tANI_U32 dot11fUnpackIeVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVersion *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &pDst->chip_rev, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + pDst->card_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_build_version = (tANI_U8)( ielen ); + if (ielen > 20){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->build_version, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeVersion. */ + +#define SigIeVersion ( 0x0016 ) + + +tANI_U32 dot11fUnpackIeWDS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWDS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_wdsData = (tANI_U8)( ielen ); + if (ielen > 64){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->wdsData, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWDS. */ + +#define SigIeWDS ( 0x0017 ) + + +tANI_U32 dot11fUnpackIeAPChannelReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAPChannelReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_channelList = (tANI_U8)( ielen ); + if (ielen > 50){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeAPChannelReport. */ + +#define SigIeAPChannelReport ( 0x0018 ) + + +tANI_U32 dot11fUnpackIeBcnReportingDetail(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBcnReportingDetail *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->reportingDetail = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeBcnReportingDetail. */ + +#define SigIeBcnReportingDetail ( 0x0019 ) + + +tANI_U32 dot11fUnpackIeBeaconReportFrmBody(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBeaconReportFrmBody *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_reportedFields = (tANI_U8)( ielen ); + if (ielen > 224){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->reportedFields, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeBeaconReportFrmBody. */ + +#define SigIeBeaconReportFrmBody ( 0x001a ) + + +tANI_U32 dot11fUnpackIeBeaconReporting(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEBeaconReporting *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->reportingCondition = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->threshold = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeBeaconReporting. */ + +#define SigIeBeaconReporting ( 0x001b ) + + +tANI_U32 dot11fUnpackIeMeasurementPilot(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMeasurementPilot *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->measurementPilot = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_vendorSpecific = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeMeasurementPilot. */ + +#define SigIeMeasurementPilot ( 0x001c ) + + +tANI_U32 dot11fUnpackIeMultiBssid(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMultiBssid *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->maxBSSIDIndicator = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_vendorSpecific = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->vendorSpecific, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeMultiBssid. */ + +#define SigIeMultiBssid ( 0x001d ) + + +tANI_U32 dot11fUnpackIeRICData(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERICData *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->Identifier = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->resourceDescCount = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->statusCode, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRICData. */ + +#define SigIeRICData ( 0x001e ) + + +tANI_U32 dot11fUnpackIeRICDescriptor(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERICDescriptor *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->resourceType = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_variableData = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->variableData, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRICDescriptor. */ + +#define SigIeRICDescriptor ( 0x001f ) + + +tANI_U32 dot11fUnpackIeRRMEnabledCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERRMEnabledCap *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp19__; + tANI_U8 tmp20__; + tANI_U8 tmp21__; + tANI_U8 tmp22__; + tANI_U8 tmp23__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp19__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->LinkMeasurement = tmp19__ >> 0 & 0x1; + pDst->NeighborRpt = tmp19__ >> 1 & 0x1; + pDst->parallel = tmp19__ >> 2 & 0x1; + pDst->repeated = tmp19__ >> 3 & 0x1; + pDst->BeaconPassive = tmp19__ >> 4 & 0x1; + pDst->BeaconActive = tmp19__ >> 5 & 0x1; + pDst->BeaconTable = tmp19__ >> 6 & 0x1; + pDst->BeaconRepCond = tmp19__ >> 7 & 0x1; + tmp20__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->FrameMeasurement = tmp20__ >> 0 & 0x1; + pDst->ChannelLoad = tmp20__ >> 1 & 0x1; + pDst->NoiseHistogram = tmp20__ >> 2 & 0x1; + pDst->statistics = tmp20__ >> 3 & 0x1; + pDst->LCIMeasurement = tmp20__ >> 4 & 0x1; + pDst->LCIAzimuth = tmp20__ >> 5 & 0x1; + pDst->TCMCapability = tmp20__ >> 6 & 0x1; + pDst->triggeredTCM = tmp20__ >> 7 & 0x1; + tmp21__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->APChanReport = tmp21__ >> 0 & 0x1; + pDst->RRMMIBEnabled = tmp21__ >> 1 & 0x1; + pDst->operatingChanMax = tmp21__ >> 2 & 0x7; + pDst->nonOperatinChanMax = tmp21__ >> 5 & 0x7; + tmp22__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->MeasurementPilot = tmp22__ >> 0 & 0x7; + pDst->MeasurementPilotEnabled = tmp22__ >> 3 & 0x1; + pDst->NeighborTSFOffset = tmp22__ >> 4 & 0x1; + pDst->RCPIMeasurement = tmp22__ >> 5 & 0x1; + pDst->RSNIMeasurement = tmp22__ >> 6 & 0x1; + pDst->BssAvgAccessDelay = tmp22__ >> 7 & 0x1; + tmp23__ = *pBuf; + pDst->BSSAvailAdmission = tmp23__ >> 0 & 0x1; + pDst->AntennaInformation = tmp23__ >> 1 & 0x1; + pDst->reserved = tmp23__ >> 2 & 0x3f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeRRMEnabledCap. */ + +#define SigIeRRMEnabledCap ( 0x0020 ) + + +tANI_U32 dot11fUnpackIeRequestedInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERequestedInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_requested_eids = (tANI_U8)( ielen ); + DOT11F_MEMCPY(pCtx, pDst->requested_eids, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRequestedInfo. */ + +#define SigIeRequestedInfo ( 0x0021 ) + + +tANI_U32 dot11fUnpackIeSSID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESSID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) + { + status = DOT11F_DUPLICATE_IE; + return status; + } + pDst->present = 1; + pDst->num_ssid = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->ssid, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSSID. */ + +#define SigIeSSID ( 0x0022 ) + + +tANI_U32 dot11fUnpackIeSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESchedule *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp24__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp24__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->aggregation = tmp24__ >> 0 & 0x1; + pDst->tsid = tmp24__ >> 1 & 0xf; + pDst->direction = tmp24__ >> 5 & 0x3; + pDst->reserved = tmp24__ >> 7 & 0x1ff; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_interval, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->spec_interval, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSchedule. */ + +#define SigIeSchedule ( 0x0023 ) + + +tANI_U32 dot11fUnpackIeTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETCLAS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->user_priority = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_mask = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 1: + pDst->info.IpParams.version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.proto = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 6: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3); + pBuf += 3; + ielen -= (tANI_U8)3; + break; + } + break; + case 2: + framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeTCLAS. */ + +#define SigIeTCLAS ( 0x0024 ) + + +#define SigIeTCLASSPROC ( 0x0025 ) + + +tANI_U32 dot11fUnpackIeTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETSDelay *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &pDst->delay, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTSDelay. */ + +#define SigIeTSDelay ( 0x0026 ) + + +tANI_U32 dot11fUnpackIeTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETSPEC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp25__; + tANI_U8 tmp26__; + tANI_U16 tmp27__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp25__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->traffic_type = tmp25__ >> 0 & 0x1; + pDst->tsid = tmp25__ >> 1 & 0xf; + pDst->direction = tmp25__ >> 5 & 0x3; + pDst->access_policy = tmp25__ >> 7 & 0x3; + pDst->aggregation = tmp25__ >> 9 & 0x1; + pDst->psb = tmp25__ >> 10 & 0x1; + pDst->user_priority = tmp25__ >> 11 & 0x7; + pDst->tsinfo_ack_pol = tmp25__ >> 14 & 0x3; + tmp26__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->schedule = tmp26__ >> 0 & 0x1; + pDst->unused = tmp26__ >> 1 & 0x7f; + framesntohs(pCtx, &tmp27__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->size = tmp27__ >> 0 & 0x7fff; + pDst->fixed = tmp27__ >> 15 & 0x1; + framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohl(pCtx, &pDst->min_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->max_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->suspension_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->burst_size, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->delay_bound, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->medium_time, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTSPEC. */ + +#define SigIeTSPEC ( 0x0027 ) + + +tANI_U32 dot11fUnpackIeWMMSchedule(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMSchedule *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp28__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohs(pCtx, &tmp28__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->aggregation = tmp28__ >> 0 & 0x1; + pDst->tsid = tmp28__ >> 1 & 0xf; + pDst->direction = tmp28__ >> 5 & 0x3; + pDst->reserved = tmp28__ >> 7 & 0x1ff; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_interval, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->max_service_dur, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->spec_interval, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMSchedule. */ + +#define SigIeWMMSchedule ( 0x0028 ) + + +tANI_U32 dot11fUnpackIeWMMTCLAS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTCLAS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + pDst->user_priority = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->classifier_mask = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.source, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->info.EthParams.dest, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + framesntohs(pCtx, &pDst->info.EthParams.type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 1: + pDst->info.IpParams.version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.source, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV4Params.dest, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV4Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->info.IpParams.params.IpV4Params.DSCP = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.proto = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->info.IpParams.params.IpV4Params.reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 6: + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.source, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.dest, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.src_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->info.IpParams.params.IpV6Params.dest_port, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + DOT11F_MEMCPY(pCtx, pDst->info.IpParams.params.IpV6Params.flow_label, pBuf, 3); + pBuf += 3; + ielen -= (tANI_U8)3; + break; + } + break; + case 2: + framesntohs(pCtx, &pDst->info.Params8021dq.tag_type, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTCLAS. */ + +#define SigIeWMMTCLAS ( 0x0029 ) + + +tANI_U32 dot11fUnpackIeWMMTCLASPROC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTCLASPROC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + pDst->processing = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTCLASPROC. */ + +#define SigIeWMMTCLASPROC ( 0x002a ) + + +tANI_U32 dot11fUnpackIeWMMTSDelay(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTSDelay *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohl(pCtx, &pDst->delay, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTSDelay. */ + +#define SigIeWMMTSDelay ( 0x002b ) + + +tANI_U32 dot11fUnpackIeWMMTSPEC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMTSPEC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp29__; + tANI_U8 tmp30__; + tANI_U16 tmp31__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohs(pCtx, &tmp29__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->traffic_type = tmp29__ >> 0 & 0x1; + pDst->tsid = tmp29__ >> 1 & 0xf; + pDst->direction = tmp29__ >> 5 & 0x3; + pDst->access_policy = tmp29__ >> 7 & 0x3; + pDst->aggregation = tmp29__ >> 9 & 0x1; + pDst->psb = tmp29__ >> 10 & 0x1; + pDst->user_priority = tmp29__ >> 11 & 0x7; + pDst->tsinfo_ack_pol = tmp29__ >> 14 & 0x3; + tmp30__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->tsinfo_rsvd = tmp30__ >> 0 & 0x7f; + pDst->burst_size_defn = tmp30__ >> 7 & 0x1; + framesntohs(pCtx, &tmp31__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->size = tmp31__ >> 0 & 0x7fff; + pDst->fixed = tmp31__ >> 15 & 0x1; + framesntohs(pCtx, &pDst->max_msdu_size, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohl(pCtx, &pDst->min_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->max_service_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->inactivity_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->suspension_int, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->service_start_time, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->mean_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->peak_data_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->burst_size, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->delay_bound, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohl(pCtx, &pDst->min_phy_rate, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &pDst->surplus_bw_allowance, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->medium_time, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMTSPEC. */ + +#define SigIeWMMTSPEC ( 0x002c ) + + +tANI_U32 dot11fUnpackIeAID(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAID *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->assocId, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeAID. */ + +#define SigIeAID ( 0x002d ) + + + static const tFFDefn FFS_Airgo[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Airgo[ ] = { + {offsetof(tDot11fIEAirgo, PropSuppRates), offsetof(tDot11fIEPropSuppRates, present), 0, "PropSuppRates" , 0, 3, 14, SigIePropSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPSUPPRATES, 0, }, + {offsetof(tDot11fIEAirgo, APName), offsetof(tDot11fIEAPName, present), 0, "APName" , 0, 3, 34, SigIeAPName, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APNAME, 0, }, + {offsetof(tDot11fIEAirgo, HCF), offsetof(tDot11fIEHCF, present), 0, "HCF" , 0, 3, 3, SigIeHCF, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HCF, 0, }, + {offsetof(tDot11fIEAirgo, WDS), offsetof(tDot11fIEWDS, present), 0, "WDS" , 0, 2, 66, SigIeWDS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WDS, 0, }, + {offsetof(tDot11fIEAirgo, BPIndicator), offsetof(tDot11fIEBPIndicator, present), 0, "BPIndicator" , 0, 4, 4, SigIeBPIndicator, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BPINDICATOR, 0, }, + {offsetof(tDot11fIEAirgo, LoadInfo), offsetof(tDot11fIELoadInfo, present), 0, "LoadInfo" , 0, 6, 6, SigIeLoadInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LOADINFO, 0, }, + {offsetof(tDot11fIEAirgo, LoadBalance), offsetof(tDot11fIELoadBalance, present), 0, "LoadBalance" , 0, 9, 9, SigIeLoadBalance, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LOADBALANCE, 0, }, + {offsetof(tDot11fIEAirgo, PropAssocType), offsetof(tDot11fIEPropAssocType, present), 0, "PropAssocType" , 0, 3, 3, SigIePropAssocType, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPASSOCTYPE, 0, }, + {offsetof(tDot11fIEAirgo, LLAttr), offsetof(tDot11fIELLAttr, present), 0, "LLAttr" , 0, 6, 6, SigIeLLAttr, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LLATTR, 0, }, + {offsetof(tDot11fIEAirgo, PropCapability), offsetof(tDot11fIEPropCapability, present), 0, "PropCapability" , 0, 4, 4, SigIePropCapability, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPCAPABILITY, 0, }, + {offsetof(tDot11fIEAirgo, Version), offsetof(tDot11fIEVersion, present), 0, "Version" , 0, 7, 27, SigIeVersion, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VERSION, 0, }, + {offsetof(tDot11fIEAirgo, PropEDCAParams), offsetof(tDot11fIEPropEDCAParams, present), 0, "PropEDCAParams" , 0, 20, 20, SigIePropEDCAParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPEDCAPARAMS, 0, }, + {offsetof(tDot11fIEAirgo, Titan), offsetof(tDot11fIETitan, present), 0, "Titan" , 0, 6, 6, SigIeTitan, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TITAN, 0, }, + {offsetof(tDot11fIEAirgo, PropChannSwitchAnn), offsetof(tDot11fIEPropChannSwitchAnn, present), 0, "PropChannSwitchAnn" , 0, 6, 6, SigIePropChannSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPCHANNSWITCHANN, 0, }, + {offsetof(tDot11fIEAirgo, PropQuietBSS), offsetof(tDot11fIEPropQuietBSS, present), 0, "PropQuietBSS" , 0, 8, 8, SigIePropQuietBSS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PROPQUIETBSS, 0, }, + {offsetof(tDot11fIEAirgo, TriggerStaBgScan), offsetof(tDot11fIETriggerStaBgScan, present), 0, "TriggerStaBgScan" , 0, 3, 3, SigIeTriggerStaBgScan, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TRIGGERSTABGSCAN, 0, }, + {offsetof(tDot11fIEAirgo, Taurus), offsetof(tDot11fIETaurus, present), 0, "Taurus" , 0, 8, 8, SigIeTaurus, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TAURUS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeAirgo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEAirgo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_Airgo, + IES_Airgo, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeAirgo. */ + +#define SigIeAirgo ( 0x002e ) + + +tANI_U32 dot11fUnpackIeCFParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIECFParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->cfp_count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->cfp_period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->cfp_maxduration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->cfp_durremaining, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeCFParams. */ + +#define SigIeCFParams ( 0x002f ) + + +tANI_U32 dot11fUnpackIeChallengeText(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEChallengeText *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_text = (tANI_U8)( ielen ); + if (ielen > 253){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->text, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeChallengeText. */ + +#define SigIeChallengeText ( 0x0030 ) + + +tANI_U32 dot11fUnpackIeChanSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEChanSwitchAnn *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->switchMode = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->newChannel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->switchCount = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeChanSwitchAnn. */ + +#define SigIeChanSwitchAnn ( 0x0031 ) + + +tANI_U32 dot11fUnpackIeCountry(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIECountry *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->country, pBuf, 3); + pBuf += 3; + ielen -= (tANI_U8)3; + if ( ! ielen ) + { + pDst->num_triplets = 0U; + return 0U; + } + else + { + pDst->num_triplets = (tANI_U8)( ielen / 3 ); + if (ielen > 84 * 3){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->triplets, pBuf, ( ielen ) ); + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeCountry. */ + +#define SigIeCountry ( 0x0032 ) + + +#define SigIeDSParams ( 0x0033 ) + + +tANI_U32 dot11fUnpackIeEDCAParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEEDCAParamSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp32__; + tANI_U8 tmp33__; + tANI_U8 tmp34__; + tANI_U8 tmp35__; + tANI_U8 tmp36__; + tANI_U8 tmp37__; + tANI_U8 tmp38__; + tANI_U8 tmp39__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->qos = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp32__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_aifsn = tmp32__ >> 0 & 0xf; + pDst->acbe_acm = tmp32__ >> 4 & 0x1; + pDst->acbe_aci = tmp32__ >> 5 & 0x3; + pDst->unused1 = tmp32__ >> 7 & 0x1; + tmp33__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_acwmin = tmp33__ >> 0 & 0xf; + pDst->acbe_acwmax = tmp33__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp34__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_aifsn = tmp34__ >> 0 & 0xf; + pDst->acbk_acm = tmp34__ >> 4 & 0x1; + pDst->acbk_aci = tmp34__ >> 5 & 0x3; + pDst->unused2 = tmp34__ >> 7 & 0x1; + tmp35__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_acwmin = tmp35__ >> 0 & 0xf; + pDst->acbk_acwmax = tmp35__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp36__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_aifsn = tmp36__ >> 0 & 0xf; + pDst->acvi_acm = tmp36__ >> 4 & 0x1; + pDst->acvi_aci = tmp36__ >> 5 & 0x3; + pDst->unused3 = tmp36__ >> 7 & 0x1; + tmp37__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_acwmin = tmp37__ >> 0 & 0xf; + pDst->acvi_acwmax = tmp37__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp38__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_aifsn = tmp38__ >> 0 & 0xf; + pDst->acvo_acm = tmp38__ >> 4 & 0x1; + pDst->acvo_aci = tmp38__ >> 5 & 0x3; + pDst->unused4 = tmp38__ >> 7 & 0x1; + tmp39__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_acwmin = tmp39__ >> 0 & 0xf; + pDst->acvo_acwmax = tmp39__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeEDCAParamSet. */ + +#define SigIeEDCAParamSet ( 0x0034 ) + + +tANI_U32 dot11fUnpackIeERPInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEERPInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp40__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp40__ = *pBuf; + pDst->non_erp_present = tmp40__ >> 0 & 0x1; + pDst->use_prot = tmp40__ >> 1 & 0x1; + pDst->barker_preamble = tmp40__ >> 2 & 0x1; + pDst->unused = tmp40__ >> 3 & 0x1f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeERPInfo. */ + +#define SigIeERPInfo ( 0x0035 ) + + +tANI_U32 dot11fUnpackIeESECckmOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESECckmOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 20){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeESECckmOpaque. */ + +#define SigIeESECckmOpaque ( 0x0036 ) + + +tANI_U32 dot11fUnpackIeESERadMgmtCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESERadMgmtCap *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp41__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->mgmt_state = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp41__ = *pBuf; + pDst->mbssid_mask = tmp41__ >> 0 & 0x7; + pDst->reserved = tmp41__ >> 3 & 0x1f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeESERadMgmtCap. */ + +#define SigIeESERadMgmtCap ( 0x0037 ) + + +tANI_U32 dot11fUnpackIeESETrafStrmMet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESETrafStrmMet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tsid = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->state = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->msmt_interval, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeESETrafStrmMet. */ + +#define SigIeESETrafStrmMet ( 0x0038 ) + + +tANI_U32 dot11fUnpackIeESETrafStrmRateSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESETrafStrmRateSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tsid = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_tsrates = (tANI_U8)( ielen ); + if (ielen > 8){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->tsrates, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeESETrafStrmRateSet. */ + +#define SigIeESETrafStrmRateSet ( 0x0039 ) + + +tANI_U32 dot11fUnpackIeESETxmitPower(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESETxmitPower *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->power_limit = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeESETxmitPower. */ + +#define SigIeESETxmitPower ( 0x003a ) + + +tANI_U32 dot11fUnpackIeESEVersion(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEESEVersion *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeESEVersion. */ + +#define SigIeESEVersion ( 0x003b ) + + +tANI_U32 dot11fUnpackIeExtCap(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEExtCap *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + + if (!ielen) /* Check to ensure copying of ielen bytes */ + goto endUnpackIeExtCap; + pDst->num_bytes = (tANI_U8)( ielen ); + if (ielen > 9){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->bytes, pBuf, ( ielen ) ); + +endUnpackIeExtCap: + (void)pCtx; + return status; +} /* End dot11fUnpackIeExtCap. */ + +#define SigIeExtCap ( 0x003c ) + + +#define SigIeExtChanSwitchAnn ( 0x003d ) + + +tANI_U32 dot11fUnpackIeExtSuppRates(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEExtSuppRates *pDst) +{ + tANI_U8 i; + tANI_U8 rate_indx = 0; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + for (i = 0; i < ielen; i++) { + if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) && + (rate_indx < 12)) { + pDst->rates[rate_indx++] = pBuf[i]; + } + } + + if(rate_indx == 0) { + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + pDst->num_rates = rate_indx; + (void)pCtx; + return status; +} /* End dot11fUnpackIeExtSuppRates. */ + +#define SigIeExtSuppRates ( 0x003e ) + + +tANI_U32 dot11fUnpackIeFHParamSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFHParamSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->dwell_time, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->hop_set = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->hop_pattern = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->hop_index = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeFHParamSet. */ + +#define SigIeFHParamSet ( 0x003f ) + + +tANI_U32 dot11fUnpackIeFHParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFHParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->radix = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->nchannels = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeFHParams. */ + +#define SigIeFHParams ( 0x0040 ) + + +tANI_U32 dot11fUnpackIeFHPattTable(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFHPattTable *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->flag = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->nsets = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->modulus = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->offset = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_randtable = (tANI_U8)( ielen ); + if (ielen > 251){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->randtable, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeFHPattTable. */ + +#define SigIeFHPattTable ( 0x0041 ) + + + static const tFFDefn FFS_FTInfo[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_FTInfo[ ] = { + {offsetof(tDot11fIEFTInfo, R1KH_ID), offsetof(tDot11fIER1KH_ID, present), 0, "R1KH_ID" , 0, 8, 8, SigIeR1KH_ID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_R1KH_ID, 0, }, + {offsetof(tDot11fIEFTInfo, GTK), offsetof(tDot11fIEGTK, present), 0, "GTK" , 0, 18, 45, SigIeGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_GTK, 0, }, + {offsetof(tDot11fIEFTInfo, R0KH_ID), offsetof(tDot11fIER0KH_ID, present), 0, "R0KH_ID" , 0, 3, 50, SigIeR0KH_ID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_R0KH_ID, 0, }, + {offsetof(tDot11fIEFTInfo, IGTK), offsetof(tDot11fIEIGTK, present), 0, "IGTK" , 0, 35, 35, SigIeIGTK, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IGTK, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeFTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEFTInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp42__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp42__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->reserved = tmp42__ >> 0 & 0xff; + pDst->IECount = tmp42__ >> 8 & 0xff; + DOT11F_MEMCPY(pCtx, pDst->MIC, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + DOT11F_MEMCPY(pCtx, pDst->Anonce, pBuf, 32); + pBuf += 32; + ielen -= (tANI_U8)32; + DOT11F_MEMCPY(pCtx, pDst->Snonce, pBuf, 32); + pBuf += 32; + ielen -= (tANI_U8)32; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_FTInfo, + IES_FTInfo, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeFTInfo. */ + +#define SigIeFTInfo ( 0x0042 ) + + +tANI_U32 dot11fUnpackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHT2040BSSCoexistence *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp43__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp43__ = *pBuf; + pDst->infoRequest = tmp43__ >> 0 & 0x1; + pDst->fortyMHzIntolerant = tmp43__ >> 1 & 0x1; + pDst->twentyMHzBssWidthReq = tmp43__ >> 2 & 0x1; + pDst->obssScanExemptionReq = tmp43__ >> 3 & 0x1; + pDst->obssScanExemptionGrant = tmp43__ >> 4 & 0x1; + pDst->unused = tmp43__ >> 5 & 0x7; + (void)pCtx; + return status; +} /* End dot11fUnpackIeHT2040BSSCoexistence. */ + +#define SigIeHT2040BSSCoexistence ( 0x0043 ) + + +tANI_U32 dot11fUnpackIeHT2040BSSIntolerantReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHT2040BSSIntolerantReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->operatingClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_channelList = (tANI_U8)( ielen ); + if (ielen > 50){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->channelList, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeHT2040BSSIntolerantReport. */ + +#define SigIeHT2040BSSIntolerantReport ( 0x0044 ) + + +tANI_U32 dot11fUnpackIeHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHTCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp44__; + tANI_U8 tmp45__; + tANI_U16 tmp46__; + tANI_U32 tmp47__; + tANI_U8 tmp48__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &tmp44__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->advCodingCap = tmp44__ >> 0 & 0x1; + pDst->supportedChannelWidthSet = tmp44__ >> 1 & 0x1; + pDst->mimoPowerSave = tmp44__ >> 2 & 0x3; + pDst->greenField = tmp44__ >> 4 & 0x1; + pDst->shortGI20MHz = tmp44__ >> 5 & 0x1; + pDst->shortGI40MHz = tmp44__ >> 6 & 0x1; + pDst->txSTBC = tmp44__ >> 7 & 0x1; + pDst->rxSTBC = tmp44__ >> 8 & 0x3; + pDst->delayedBA = tmp44__ >> 10 & 0x1; + pDst->maximalAMSDUsize = tmp44__ >> 11 & 0x1; + pDst->dsssCckMode40MHz = tmp44__ >> 12 & 0x1; + pDst->psmp = tmp44__ >> 13 & 0x1; + pDst->stbcControlFrame = tmp44__ >> 14 & 0x1; + pDst->lsigTXOPProtection = tmp44__ >> 15 & 0x1; + tmp45__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->maxRxAMPDUFactor = tmp45__ >> 0 & 0x3; + pDst->mpduDensity = tmp45__ >> 2 & 0x7; + pDst->reserved1 = tmp45__ >> 5 & 0x7; + DOT11F_MEMCPY(pCtx, pDst->supportedMCSSet, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + framesntohs(pCtx, &tmp46__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->pco = tmp46__ >> 0 & 0x1; + pDst->transitionTime = tmp46__ >> 1 & 0x3; + pDst->reserved2 = tmp46__ >> 3 & 0x1f; + pDst->mcsFeedback = tmp46__ >> 8 & 0x3; + pDst->reserved3 = tmp46__ >> 10 & 0x3f; + framesntohl(pCtx, &tmp47__, pBuf, 0); + pBuf += 4; + ielen -= 4; + pDst->txBF = tmp47__ >> 0 & 0x1; + pDst->rxStaggeredSounding = tmp47__ >> 1 & 0x1; + pDst->txStaggeredSounding = tmp47__ >> 2 & 0x1; + pDst->rxZLF = tmp47__ >> 3 & 0x1; + pDst->txZLF = tmp47__ >> 4 & 0x1; + pDst->implicitTxBF = tmp47__ >> 5 & 0x1; + pDst->calibration = tmp47__ >> 6 & 0x3; + pDst->explicitCSITxBF = tmp47__ >> 8 & 0x1; + pDst->explicitUncompressedSteeringMatrix = tmp47__ >> 9 & 0x1; + pDst->explicitBFCSIFeedback = tmp47__ >> 10 & 0x7; + pDst->explicitUncompressedSteeringMatrixFeedback = tmp47__ >> 13 & 0x7; + pDst->explicitCompressedSteeringMatrixFeedback = tmp47__ >> 16 & 0x7; + pDst->csiNumBFAntennae = tmp47__ >> 19 & 0x3; + pDst->uncompressedSteeringMatrixBFAntennae = tmp47__ >> 21 & 0x3; + pDst->compressedSteeringMatrixBFAntennae = tmp47__ >> 23 & 0x3; + pDst->reserved4 = tmp47__ >> 25 & 0x7f; + tmp48__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->antennaSelection = tmp48__ >> 0 & 0x1; + pDst->explicitCSIFeedbackTx = tmp48__ >> 1 & 0x1; + pDst->antennaIndicesFeedbackTx = tmp48__ >> 2 & 0x1; + pDst->explicitCSIFeedback = tmp48__ >> 3 & 0x1; + pDst->antennaIndicesFeedback = tmp48__ >> 4 & 0x1; + pDst->rxAS = tmp48__ >> 5 & 0x1; + pDst->txSoundingPPDUs = tmp48__ >> 6 & 0x1; + pDst->reserved5 = tmp48__ >> 7 & 0x1; + pDst->num_rsvd = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeHTCaps. */ + +#define SigIeHTCaps ( 0x0045 ) + + +tANI_U32 dot11fUnpackIeHTInfo(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEHTInfo *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp49__; + tANI_U16 tmp50__; + tANI_U16 tmp51__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->primaryChannel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp49__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->secondaryChannelOffset = tmp49__ >> 0 & 0x3; + pDst->recommendedTxWidthSet = tmp49__ >> 2 & 0x1; + pDst->rifsMode = tmp49__ >> 3 & 0x1; + pDst->controlledAccessOnly = tmp49__ >> 4 & 0x1; + pDst->serviceIntervalGranularity = tmp49__ >> 5 & 0x7; + framesntohs(pCtx, &tmp50__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->opMode = tmp50__ >> 0 & 0x3; + pDst->nonGFDevicesPresent = tmp50__ >> 2 & 0x1; + pDst->transmitBurstLimit = tmp50__ >> 3 & 0x1; + pDst->obssNonHTStaPresent = tmp50__ >> 4 & 0x1; + pDst->reserved = tmp50__ >> 5 & 0x7ff; + framesntohs(pCtx, &tmp51__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->basicSTBCMCS = tmp51__ >> 0 & 0x7f; + pDst->dualCTSProtection = tmp51__ >> 7 & 0x1; + pDst->secondaryBeacon = tmp51__ >> 8 & 0x1; + pDst->lsigTXOPProtectionFullSupport = tmp51__ >> 9 & 0x1; + pDst->pcoActive = tmp51__ >> 10 & 0x1; + pDst->pcoPhase = tmp51__ >> 11 & 0x1; + pDst->reserved2 = tmp51__ >> 12 & 0xf; + DOT11F_MEMCPY(pCtx, pDst->basicMCSSet, pBuf, 16); + pBuf += 16; + ielen -= (tANI_U8)16; + pDst->num_rsvd = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->rsvd, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeHTInfo. */ + +#define SigIeHTInfo ( 0x0046 ) + + +tANI_U32 dot11fUnpackIeIBSSParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEIBSSParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->atim, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeIBSSParams. */ + +#define SigIeIBSSParams ( 0x0047 ) + + +tANI_U32 dot11fUnpackIeLinkIdentifier(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIELinkIdentifier *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->InitStaAddr, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + DOT11F_MEMCPY(pCtx, pDst->RespStaAddr, pBuf, 6); + (void)pCtx; + return status; +} /* End dot11fUnpackIeLinkIdentifier. */ + +#define SigIeLinkIdentifier ( 0x0048 ) + + +static const tFFDefn FFS_reportBeacon[ ] = { +{ NULL, 0, 0, 0,}, +}; + +static const tIEDefn IES_reportBeacon[ ] = { + {offsetof(tDot11fIEMeasurementReport, report.Beacon.BeaconReportFrmBody), offsetof(tDot11fIEBeaconReportFrmBody, present), 0, "BeaconReportFrmBody" , 0, 2, 226, SigIeBeaconReportFrmBody, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BEACONREPORTFRMBODY, 0, }, +{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, +}; + +tANI_U32 dot11fUnpackIeMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMeasurementReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp52__; + tANI_U8 tmp53__; + tANI_U8 tmp54__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->token = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp52__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->late = tmp52__ >> 0 & 0x1; + pDst->incapable = tmp52__ >> 1 & 0x1; + pDst->refused = tmp52__ >> 2 & 0x1; + pDst->unused = tmp52__ >> 3 & 0x1f; + pDst->type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if ( ! ielen ) + { + return 0U; + } + else + { + switch (pDst->type) + { + case 0: + pDst->report.Basic.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.Basic.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.Basic.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp53__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->report.Basic.bss = tmp53__ >> 0 & 0x1; + pDst->report.Basic.ofdm_preamble = tmp53__ >> 1 & 0x1; + pDst->report.Basic.unid_signal = tmp53__ >> 2 & 0x1; + pDst->report.Basic.rader = tmp53__ >> 3 & 0x1; + pDst->report.Basic.unmeasured = tmp53__ >> 4 & 0x1; + pDst->report.Basic.unused = tmp53__ >> 5 & 0x7; + break; + case 1: + pDst->report.CCA.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.CCA.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.CCA.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->report.CCA.cca_busy_fraction = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 2: + pDst->report.RPIHistogram.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.RPIHistogram.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.RPIHistogram.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->report.RPIHistogram.rpi0_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi1_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi2_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi3_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi4_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi5_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi6_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.RPIHistogram.rpi7_density = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + break; + case 5: + pDst->report.Beacon.regClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.Beacon.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohq(pCtx, &pDst->report.Beacon.meas_start_time, pBuf, 0); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->report.Beacon.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp54__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->report.Beacon.condensed_PHY = tmp54__ >> 0 & 0x7f; + pDst->report.Beacon.reported_frame_type = tmp54__ >> 7 & 0x1; + pDst->report.Beacon.RCPI = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->report.Beacon.RSNI = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->report.Beacon.BSSID, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + pDst->report.Beacon.antenna_id = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohl(pCtx, &pDst->report.Beacon.parent_TSF, pBuf, 0); + pBuf += 4; + ielen -= (tANI_U8)4; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_reportBeacon, + IES_reportBeacon, + ( tANI_U8* )pDst, + sizeof(*pDst)); + break; + } + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeMeasurementReport. */ + +#define SigIeMeasurementReport ( 0x0049 ) + + +static const tFFDefn FFS_measurement_requestBeacon[ ] = { +{ NULL, 0, 0, 0,}, +}; + +static const tIEDefn IES_measurement_requestBeacon[ ] = { + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.BeaconReporting), offsetof(tDot11fIEBeaconReporting, present), 0, "BeaconReporting" , 0, 4, 4, SigIeBeaconReporting, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BEACONREPORTING, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.BcnReportingDetail), offsetof(tDot11fIEBcnReportingDetail, present), 0, "BcnReportingDetail" , 0, 3, 3, SigIeBcnReportingDetail, {0, 0, 0, 0, 0}, 0, DOT11F_EID_BCNREPORTINGDETAIL, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.RequestedInfo), offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo" , 0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_REQUESTEDINFO, 0, }, + {offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.APChannelReport), offsetof(tDot11fIEAPChannelReport, present), offsetof(tDot11fIEMeasurementRequest, measurement_request.Beacon.num_APChannelReport), "APChannelReport" , 2, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, +{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, +}; + +tANI_U32 dot11fUnpackIeMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMeasurementRequest *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp55__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->measurement_token = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp55__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->parallel = tmp55__ >> 0 & 0x1; + pDst->enable = tmp55__ >> 1 & 0x1; + pDst->request = tmp55__ >> 2 & 0x1; + pDst->report = tmp55__ >> 3 & 0x1; + pDst->durationMandatory = tmp55__ >> 4 & 0x1; + pDst->unused = tmp55__ >> 5 & 0x7; + pDst->measurement_type = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + switch (pDst->measurement_type) + { + case 0: + pDst->measurement_request.Basic.channel_no = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.Basic.meas_start_time, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->measurement_request.Basic.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 1: + pDst->measurement_request.CCA.channel_no = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.CCA.meas_start_time, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->measurement_request.CCA.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 2: + pDst->measurement_request.RPIHistogram.channel_no = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.RPIHistogram.meas_start_time, pBuf, 8); + pBuf += 8; + ielen -= (tANI_U8)8; + framesntohs(pCtx, &pDst->measurement_request.RPIHistogram.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 5: + pDst->measurement_request.Beacon.regClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->measurement_request.Beacon.channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->measurement_request.Beacon.randomization, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->measurement_request.Beacon.meas_duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->measurement_request.Beacon.meas_mode = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + DOT11F_MEMCPY(pCtx, pDst->measurement_request.Beacon.BSSID, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_measurement_requestBeacon, + IES_measurement_requestBeacon, + ( tANI_U8* )pDst, + sizeof(*pDst)); + break; + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeMeasurementRequest. */ + +#define SigIeMeasurementRequest ( 0x004a ) + + +tANI_U32 dot11fUnpackIeMobilityDomain(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEMobilityDomain *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp56__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->MDID, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp56__ = *pBuf; + pDst->overDSCap = tmp56__ >> 0 & 0x1; + pDst->resourceReqCap = tmp56__ >> 1 & 0x1; + pDst->reserved = tmp56__ >> 2 & 0x3f; + (void)pCtx; + return status; +} /* End dot11fUnpackIeMobilityDomain. */ + +#define SigIeMobilityDomain ( 0x004b ) + + + static const tFFDefn FFS_NeighborReport[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NeighborReport[ ] = { + {offsetof(tDot11fIENeighborReport, TSFInfo), offsetof(tDot11fIETSFInfo, present), 0, "TSFInfo" , 0, 6, 6, SigIeTSFInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSFINFO, 0, }, + {offsetof(tDot11fIENeighborReport, CondensedCountryStr), offsetof(tDot11fIECondensedCountryStr, present), 0, "CondensedCountryStr" , 0, 4, 4, SigIeCondensedCountryStr, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CONDENSEDCOUNTRYSTR, 0, }, + {offsetof(tDot11fIENeighborReport, MeasurementPilot), offsetof(tDot11fIEMeasurementPilot, present), 0, "MeasurementPilot" , 0, 3, 258, SigIeMeasurementPilot, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTPILOT, 0, }, + {offsetof(tDot11fIENeighborReport, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fIENeighborReport, MultiBssid), offsetof(tDot11fIEMultiBssid, present), 0, "MultiBssid" , 0, 3, 258, SigIeMultiBssid, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MULTIBSSID, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeNeighborReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIENeighborReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp57__; + tANI_U8 tmp58__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + DOT11F_MEMCPY(pCtx, pDst->bssid, pBuf, 6); + pBuf += 6; + ielen -= (tANI_U8)6; + tmp57__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->APReachability = tmp57__ >> 0 & 0x3; + pDst->Security = tmp57__ >> 2 & 0x1; + pDst->KeyScope = tmp57__ >> 3 & 0x1; + pDst->SpecMgmtCap = tmp57__ >> 4 & 0x1; + pDst->QosCap = tmp57__ >> 5 & 0x1; + pDst->apsd = tmp57__ >> 6 & 0x1; + pDst->rrm = tmp57__ >> 7 & 0x1; + tmp58__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->DelayedBA = tmp58__ >> 0 & 0x1; + pDst->ImmBA = tmp58__ >> 1 & 0x1; + pDst->MobilityDomain = tmp58__ >> 2 & 0x1; + pDst->reserved = tmp58__ >> 3 & 0x1f; + framesntohs(pCtx, &pDst->reserved1, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->regulatoryClass = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->channel = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->PhyType = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_NeighborReport, + IES_NeighborReport, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeNeighborReport. */ + +#define SigIeNeighborReport ( 0x004c ) + + +tANI_U32 dot11fUnpackIeOBSSScanParameters(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEOBSSScanParameters *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->obssScanPassiveDwell, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanActiveDwell, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->bssChannelWidthTriggerScanInterval, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanPassiveTotalPerChannel, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanActiveTotalPerChannel, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->bssWidthChannelTransitionDelayFactor, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->obssScanActivityThreshold, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeOBSSScanParameters. */ + +#define SigIeOBSSScanParameters ( 0x004d ) + + +tANI_U32 dot11fUnpackIeOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEOperatingMode *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp59__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp59__ = *pBuf; + pDst->chanWidth = tmp59__ >> 0 & 0x3; + pDst->reserved = tmp59__ >> 2 & 0x3; + pDst->rxNSS = tmp59__ >> 4 & 0x7; + pDst->rxNSSType = tmp59__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeOperatingMode. */ + +#define SigIeOperatingMode ( 0x004e ) + + + static const tTLVDefn TLVS_P2PAssocReq[ ] = { + {offsetof(tDot11fIEP2PAssocReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PAssocReq, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PAssocReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PAssocReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PAssocReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PAssocReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PAssocReq. */ + +#define SigIeP2PAssocReq ( 0x004f ) + + + static const tTLVDefn TLVS_P2PAssocRes[ ] = { + {offsetof(tDot11fIEP2PAssocRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PAssocRes, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PAssocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PAssocRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PAssocRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PAssocRes. */ + +#define SigIeP2PAssocRes ( 0x0050 ) + + + static const tTLVDefn TLVS_P2PBeacon[ ] = { + {offsetof(tDot11fIEP2PBeacon, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeacon, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeacon, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PBeacon *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PBeacon,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PBeacon. */ + +#define SigIeP2PBeacon ( 0x0051 ) + + + static const tTLVDefn TLVS_P2PBeaconProbeRes[ ] = { + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PBeaconProbeRes, P2PGroupInfo), offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo", SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PBeaconProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PBeaconProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PBeaconProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PBeaconProbeRes. */ + +#define SigIeP2PBeaconProbeRes ( 0x0052 ) + + + static const tTLVDefn TLVS_P2PDeAuth[ ] = { + {offsetof(tDot11fIEP2PDeAuth, MinorReasonCode), offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode", SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE, 0, 4, 4, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDeAuth(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDeAuth *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDeAuth,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDeAuth. */ + +#define SigIeP2PDeAuth ( 0x0053 ) + + + static const tTLVDefn TLVS_P2PDeviceDiscoverabilityReq[ ] = { + {offsetof(tDot11fIEP2PDeviceDiscoverabilityReq, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PDeviceDiscoverabilityReq, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDeviceDiscoverabilityReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDeviceDiscoverabilityReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDeviceDiscoverabilityReq. */ + +#define SigIeP2PDeviceDiscoverabilityReq ( 0x0054 ) + + + static const tTLVDefn TLVS_P2PDeviceDiscoverabilityRes[ ] = { + {offsetof(tDot11fIEP2PDeviceDiscoverabilityRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDeviceDiscoverabilityRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDeviceDiscoverabilityRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDeviceDiscoverabilityRes. */ + +#define SigIeP2PDeviceDiscoverabilityRes ( 0x0055 ) + + + static const tTLVDefn TLVS_P2PDisAssoc[ ] = { + {offsetof(tDot11fIEP2PDisAssoc, MinorReasonCode), offsetof(tDot11fTLVMinorReasonCode, present), "MinorReasonCode", SigTlvMinorReasonCode, DOT11F_TLV_MINORREASONCODE, 0, 4, 4, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PDisAssoc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PDisAssoc *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PDisAssoc,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PDisAssoc. */ + +#define SigIeP2PDisAssoc ( 0x0056 ) + + + static const tTLVDefn TLVS_P2PGONegCnf[ ] = { + {offsetof(tDot11fIEP2PGONegCnf, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegCnf, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegCnf *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegCnf,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegCnf. */ + +#define SigIeP2PGONegCnf ( 0x0057 ) + + + static const tTLVDefn TLVS_P2PGONegReq[ ] = { + {offsetof(tDot11fIEP2PGONegReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, GOIntent), offsetof(tDot11fTLVGOIntent, present), "GOIntent", SigTlvGOIntent, DOT11F_TLV_GOINTENT, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ListenChannel), offsetof(tDot11fTLVListenChannel, present), "ListenChannel", SigTlvListenChannel, DOT11F_TLV_LISTENCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, IntendedP2PInterfaceAddress), offsetof(tDot11fTLVIntendedP2PInterfaceAddress, present), "IntendedP2PInterfaceAddress", SigTlvIntendedP2PInterfaceAddress, DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegReq, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegReq. */ + +#define SigIeP2PGONegReq ( 0x0058 ) + + + static const tTLVDefn TLVS_P2PGONegRes[ ] = { + {offsetof(tDot11fIEP2PGONegRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, GOIntent), offsetof(tDot11fTLVGOIntent, present), "GOIntent", SigTlvGOIntent, DOT11F_TLV_GOINTENT, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, IntendedP2PInterfaceAddress), offsetof(tDot11fTLVIntendedP2PInterfaceAddress, present), "IntendedP2PInterfaceAddress", SigTlvIntendedP2PInterfaceAddress, DOT11F_TLV_INTENDEDP2PINTERFACEADDRESS, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PGONegRes, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegRes. */ + +#define SigIeP2PGONegRes ( 0x0059 ) + + + static const tTLVDefn TLVS_P2PGONegWPS[ ] = { + {offsetof(tDot11fIEP2PGONegWPS, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEP2PGONegWPS, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 1, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PGONegWPS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PGONegWPS *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PGONegWPS,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PGONegWPS. */ + +#define SigIeP2PGONegWPS ( 0x005a ) + + +tANI_U32 dot11fUnpackIeP2PIEOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PIEOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeP2PIEOpaque. */ + +#define SigIeP2PIEOpaque ( 0x005b ) + + + static const tTLVDefn TLVS_P2PInvitationReq[ ] = { + {offsetof(tDot11fIEP2PInvitationReq, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, InvitationFlags), offsetof(tDot11fTLVInvitationFlags, present), "InvitationFlags", SigTlvInvitationFlags, DOT11F_TLV_INVITATIONFLAGS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, P2PGroupBssid), offsetof(tDot11fTLVP2PGroupBssid, present), "P2PGroupBssid", SigTlvP2PGroupBssid, DOT11F_TLV_P2PGROUPBSSID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PInvitationReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PInvitationReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PInvitationReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PInvitationReq. */ + +#define SigIeP2PInvitationReq ( 0x005c ) + + + static const tTLVDefn TLVS_P2PInvitationRes[ ] = { + {offsetof(tDot11fIEP2PInvitationRes, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, ConfigurationTimeout), offsetof(tDot11fTLVConfigurationTimeout, present), "ConfigurationTimeout", SigTlvConfigurationTimeout, DOT11F_TLV_CONFIGURATIONTIMEOUT, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, P2PGroupBssid), offsetof(tDot11fTLVP2PGroupBssid, present), "P2PGroupBssid", SigTlvP2PGroupBssid, DOT11F_TLV_P2PGROUPBSSID, 0, 9, 9, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PInvitationRes, ChannelList), offsetof(tDot11fTLVChannelList, present), "ChannelList", SigTlvChannelList, DOT11F_TLV_CHANNELLIST, 0, 6, 257, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PInvitationRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PInvitationRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PInvitationRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PInvitationRes. */ + +#define SigIeP2PInvitationRes ( 0x005d ) + + + static const tTLVDefn TLVS_P2PNoticeOfAbsence[ ] = { + {offsetof(tDot11fIEP2PNoticeOfAbsence, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PNoticeOfAbsence(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PNoticeOfAbsence *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PNoticeOfAbsence,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PNoticeOfAbsence. */ + +#define SigIeP2PNoticeOfAbsence ( 0x005e ) + + + static const tTLVDefn TLVS_P2PPresenceResponse[ ] = { + {offsetof(tDot11fIEP2PPresenceResponse, P2PStatus), offsetof(tDot11fTLVP2PStatus, present), "P2PStatus", SigTlvP2PStatus, DOT11F_TLV_P2PSTATUS, 0, 4, 4, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PPresenceResponse, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PPresenceResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PPresenceResponse *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PPresenceResponse,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PPresenceResponse. */ + +#define SigIeP2PPresenceResponse ( 0x005f ) + + + static const tTLVDefn TLVS_P2PProbeReq[ ] = { + {offsetof(tDot11fIEP2PProbeReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, P2PDeviceId), offsetof(tDot11fTLVP2PDeviceId, present), "P2PDeviceId", SigTlvP2PDeviceId, DOT11F_TLV_P2PDEVICEID, 0, 9, 9, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, ListenChannel), offsetof(tDot11fTLVListenChannel, present), "ListenChannel", SigTlvListenChannel, DOT11F_TLV_LISTENCHANNEL, 0, 8, 8, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeReq, OperatingChannel), offsetof(tDot11fTLVOperatingChannel, present), "OperatingChannel", SigTlvOperatingChannel, DOT11F_TLV_OPERATINGCHANNEL, 0, 8, 8, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PProbeReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PProbeReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PProbeReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PProbeReq. */ + +#define SigIeP2PProbeReq ( 0x0060 ) + + + static const tTLVDefn TLVS_P2PProbeRes[ ] = { + {offsetof(tDot11fIEP2PProbeRes, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, ExtendedListenTiming), offsetof(tDot11fTLVExtendedListenTiming, present), "ExtendedListenTiming", SigTlvExtendedListenTiming, DOT11F_TLV_EXTENDEDLISTENTIMING, 0, 7, 7, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, NoticeOfAbsence), offsetof(tDot11fTLVNoticeOfAbsence, present), "NoticeOfAbsence", SigTlvNoticeOfAbsence, DOT11F_TLV_NOTICEOFABSENCE, 0, 5, 41, 0, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProbeRes, P2PGroupInfo), offsetof(tDot11fTLVP2PGroupInfo, present), "P2PGroupInfo", SigTlvP2PGroupInfo, DOT11F_TLV_P2PGROUPINFO, 0, 3, 1027, 0, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PProbeRes. */ + +#define SigIeP2PProbeRes ( 0x0061 ) + + + static const tTLVDefn TLVS_P2PProvisionDiscoveryReq[ ] = { + {offsetof(tDot11fIEP2PProvisionDiscoveryReq, P2PCapability), offsetof(tDot11fTLVP2PCapability, present), "P2PCapability", SigTlvP2PCapability, DOT11F_TLV_P2PCAPABILITY, 0, 5, 5, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProvisionDiscoveryReq, P2PDeviceInfo), offsetof(tDot11fTLVP2PDeviceInfo, present), "P2PDeviceInfo", SigTlvP2PDeviceInfo, DOT11F_TLV_P2PDEVICEINFO, 0, 19, 55, 1, 1, 2, 0, }, + {offsetof(tDot11fIEP2PProvisionDiscoveryReq, P2PGroupId), offsetof(tDot11fTLVP2PGroupId, present), "P2PGroupId", SigTlvP2PGroupId, DOT11F_TLV_P2PGROUPID, 0, 9, 41, 1, 1, 2, 0, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PProvisionDiscoveryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PProvisionDiscoveryReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PProvisionDiscoveryReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PProvisionDiscoveryReq. */ + +#define SigIeP2PProvisionDiscoveryReq ( 0x0062 ) + + + static const tTLVDefn TLVS_P2PWSCProvisionDiscoveryRes[ ] = { + {offsetof(tDot11fIEP2PWSCProvisionDiscoveryRes, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEP2PWSCProvisionDiscoveryRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_P2PWSCProvisionDiscoveryRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeP2PWSCProvisionDiscoveryRes. */ + +#define SigIeP2PWSCProvisionDiscoveryRes ( 0x0063 ) + + +tANI_U32 dot11fUnpackIePTIControl(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPTIControl *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tid = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->sequence_control, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIePTIControl. */ + +#define SigIePTIControl ( 0x0064 ) + + +tANI_U32 dot11fUnpackIePUBufferStatus(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPUBufferStatus *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp60__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp60__ = *pBuf; + pDst->ac_bk_traffic_aval = tmp60__ >> 0 & 0x1; + pDst->ac_be_traffic_aval = tmp60__ >> 1 & 0x1; + pDst->ac_vi_traffic_aval = tmp60__ >> 2 & 0x1; + pDst->ac_vo_traffic_aval = tmp60__ >> 3 & 0x1; + pDst->reserved = tmp60__ >> 4 & 0xf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePUBufferStatus. */ + +#define SigIePUBufferStatus ( 0x0065 ) + + +tANI_U32 dot11fUnpackIePowerCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPowerCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->minTxPower = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->maxTxPower = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePowerCaps. */ + +#define SigIePowerCaps ( 0x0066 ) + + +tANI_U32 dot11fUnpackIePowerConstraints(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEPowerConstraints *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->localPowerConstraints = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIePowerConstraints. */ + +#define SigIePowerConstraints ( 0x0067 ) + + +tANI_U32 dot11fUnpackIeQBSSLoad(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQBSSLoad *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->stacount, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + pDst->chautil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->avail, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeQBSSLoad. */ + +#define SigIeQBSSLoad ( 0x0068 ) + + +tANI_U32 dot11fUnpackIeQOSCapsAp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQOSCapsAp *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp61__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp61__ = *pBuf; + pDst->count = tmp61__ >> 0 & 0xf; + pDst->qack = tmp61__ >> 4 & 0x1; + pDst->qreq = tmp61__ >> 5 & 0x1; + pDst->txopreq = tmp61__ >> 6 & 0x1; + pDst->reserved = tmp61__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeQOSCapsAp. */ + +#define SigIeQOSCapsAp ( 0x0069 ) + + +tANI_U32 dot11fUnpackIeQOSCapsStation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQOSCapsStation *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp62__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp62__ = *pBuf; + pDst->acvo_uapsd = tmp62__ >> 0 & 0x1; + pDst->acvi_uapsd = tmp62__ >> 1 & 0x1; + pDst->acbk_uapsd = tmp62__ >> 2 & 0x1; + pDst->acbe_uapsd = tmp62__ >> 3 & 0x1; + pDst->qack = tmp62__ >> 4 & 0x1; + pDst->max_sp_length = tmp62__ >> 5 & 0x3; + pDst->more_data_ack = tmp62__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeQOSCapsStation. */ + +#define SigIeQOSCapsStation ( 0x006a ) + + +tANI_U32 dot11fUnpackIeQosMapSet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQosMapSet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_dscp_exceptions = (tANI_U8)( ielen ); + if (ielen > 60){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->dscp_exceptions, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeQosMapSet. */ + +#define SigIeQosMapSet ( 0x006b ) + + +tANI_U32 dot11fUnpackIeQuiet(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEQuiet *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->duration, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &pDst->offset, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeQuiet. */ + +#define SigIeQuiet ( 0x006c ) + + +tANI_U32 dot11fUnpackIeRCPIIE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERCPIIE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->rcpi = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeRCPIIE. */ + +#define SigIeRCPIIE ( 0x006d ) + + + static const tFFDefn FFS_RICDataDesc[ ] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RICDataDesc[ ] = { + {offsetof(tDot11fIERICDataDesc, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 1, }, + {offsetof(tDot11fIERICDataDesc, RICDescriptor), offsetof(tDot11fIERICDescriptor, present), 0, "RICDescriptor" , 0, 3, 258, SigIeRICDescriptor, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDESCRIPTOR, 0, }, + {offsetof(tDot11fIERICDataDesc, TSPEC), offsetof(tDot11fIETSPEC, present), 0, "TSPEC" , 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSPEC, 0, }, + {offsetof(tDot11fIERICDataDesc, TCLAS), offsetof(tDot11fIETCLAS, present), offsetof(tDot11fIERICDataDesc, num_TCLAS), "TCLAS" , 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, }, + {offsetof(tDot11fIERICDataDesc, TCLASSPROC), offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC" , 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLASSPROC, 0, }, + {offsetof(tDot11fIERICDataDesc, TSDelay), offsetof(tDot11fIETSDelay, present), 0, "TSDelay" , 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSDELAY, 0, }, + {offsetof(tDot11fIERICDataDesc, Schedule), offsetof(tDot11fIESchedule, present), 0, "Schedule" , 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SCHEDULE, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS, present), offsetof(tDot11fIERICDataDesc, num_WMMTCLAS), "WMMTCLAS" , 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6}, 5, DOT11F_EID_WMMTCLAS, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTCLASPROC), offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC" , 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7}, 5, DOT11F_EID_WMMTCLASPROC, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMTSDelay), offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay" , 0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8}, 5, DOT11F_EID_WMMTSDELAY, 0, }, + {offsetof(tDot11fIERICDataDesc, WMMSchedule), offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule" , 0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9}, 5, DOT11F_EID_WMMSCHEDULE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, + }; + +tANI_U32 dot11fUnpackIeRICDataDesc(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERICDataDesc *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + status |= UnpackCore(pCtx, + pBuf, + ielen, + FFS_RICDataDesc, + IES_RICDataDesc, + ( tANI_U8* )pDst, + sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeRICDataDesc. */ + +#define SigIeRICDataDesc ( 0x006e ) + + +tANI_U32 dot11fUnpackIeRSN(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERSN *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->version, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + DOT11F_MEMCPY(pCtx, pDst->gp_cipher_suite, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + if ( ! ielen ) + { + pDst->pwise_cipher_suite_count = 0U; + pDst->akm_suite_count = 0U; + pDst->pmkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->pwise_cipher_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->pwise_cipher_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->pwise_cipher_suites, pBuf, ( pDst->pwise_cipher_suite_count * 4 ) ); + pBuf += ( pDst->pwise_cipher_suite_count * 4 ); + ielen -= ( pDst->pwise_cipher_suite_count * 4 ); + if ( ! ielen ) + { + pDst->akm_suite_count = 0U; + pDst->pmkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->akm_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, ( pDst->akm_suite_count * 4 ) ); + pBuf += ( pDst->akm_suite_count * 4 ); + ielen -= ( pDst->akm_suite_count * 4 ); + if ( ! ielen ) + { + pDst->pmkid_count = 0U; + return 0U; + } + else + { + DOT11F_MEMCPY(pCtx, pDst->RSN_Cap, pBuf, 2); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if ( ! ielen ) + { + pDst->pmkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->pmkid_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->pmkid_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->pmkid, pBuf, ( pDst->pmkid_count * 16 ) ); + pBuf += ( pDst->pmkid_count * 16 ); + ielen -= ( pDst->pmkid_count * 16 ); + if ( ! ielen ) + { + return 0U; + } + else + { + DOT11F_MEMCPY(pCtx, pDst->gp_mgmt_cipher_suite, pBuf, 4); + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeRSN. */ + +#define SigIeRSN ( 0x006f ) + + +tANI_U32 dot11fUnpackIeRSNIIE(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERSNIIE *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->rsni = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeRSNIIE. */ + +#define SigIeRSNIIE ( 0x0070 ) + + +tANI_U32 dot11fUnpackIeRSNOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIERSNOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 253){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeRSNOpaque. */ + +#define SigIeRSNOpaque ( 0x0071 ) + + +tANI_U32 dot11fUnpackIeSuppChannels(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESuppChannels *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_bands = (tANI_U8)( ielen / 2 ); + if (ielen > 48 * 2){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->bands, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSuppChannels. */ + +#define SigIeSuppChannels ( 0x0072 ) + + +tANI_U32 dot11fUnpackIeSuppOperatingClasses(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESuppOperatingClasses *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_classes = (tANI_U8)( ielen ); + if (ielen > 32){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->classes, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeSuppOperatingClasses. */ + +#define SigIeSuppOperatingClasses ( 0x0073 ) + + +tANI_U32 dot11fUnpackIeSuppRates(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIESuppRates *pDst) +{ + tANI_U8 i; + tANI_U8 rate_indx = 0; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + for (i = 0; i < ielen; i++) { + if ((DOT11F_IS_BG_RATE(pBuf[i] & 0x7F)) && + (rate_indx < 12)) { + pDst->rates[rate_indx++] = pBuf[i]; + } + } + + if(rate_indx == 0) { + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + pDst->num_rates = rate_indx; + (void)pCtx; + return status; +} /* End dot11fUnpackIeSuppRates. */ + +#define SigIeSuppRates ( 0x0074 ) + + +tANI_U32 dot11fUnpackIeTIM(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETIM *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->dtim_count = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->dtim_period = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->bmpctl = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->num_vbmp = (tANI_U8)( ielen ); + if (ielen > 251){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->vbmp, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTIM. */ + +#define SigIeTIM ( 0x0075 ) + + +tANI_U32 dot11fUnpackIeTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETPCReport *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->tx_power = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->link_margin = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTPCReport. */ + +#define SigIeTPCReport ( 0x0076 ) + + +tANI_U32 dot11fUnpackIeTPCRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETPCRequest *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeTPCRequest. */ + +#define SigIeTPCRequest ( 0x0077 ) + + +tANI_U32 dot11fUnpackIeTimeoutInterval(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIETimeoutInterval *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->timeoutType = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohl(pCtx, &pDst->timeoutValue, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeTimeoutInterval. */ + +#define SigIeTimeoutInterval ( 0x0078 ) + + +tANI_U32 dot11fUnpackIeVHTCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVHTCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 tmp63__; + tANI_U16 tmp64__; + tANI_U16 tmp65__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohl(pCtx, &tmp63__, pBuf, 0); + pBuf += 4; + ielen -= 4; + pDst->maxMPDULen = tmp63__ >> 0 & 0x3; + pDst->supportedChannelWidthSet = tmp63__ >> 2 & 0x3; + pDst->ldpcCodingCap = tmp63__ >> 4 & 0x1; + pDst->shortGI80MHz = tmp63__ >> 5 & 0x1; + pDst->shortGI160and80plus80MHz = tmp63__ >> 6 & 0x1; + pDst->txSTBC = tmp63__ >> 7 & 0x1; + pDst->rxSTBC = tmp63__ >> 8 & 0x7; + pDst->suBeamFormerCap = tmp63__ >> 11 & 0x1; + pDst->suBeamformeeCap = tmp63__ >> 12 & 0x1; + pDst->csnofBeamformerAntSup = tmp63__ >> 13 & 0x7; + pDst->numSoundingDim = tmp63__ >> 16 & 0x7; + pDst->muBeamformerCap = tmp63__ >> 19 & 0x1; + pDst->muBeamformeeCap = tmp63__ >> 20 & 0x1; + pDst->vhtTXOPPS = tmp63__ >> 21 & 0x1; + pDst->htcVHTCap = tmp63__ >> 22 & 0x1; + pDst->maxAMPDULenExp = tmp63__ >> 23 & 0x7; + pDst->vhtLinkAdaptCap = tmp63__ >> 26 & 0x3; + pDst->rxAntPattern = tmp63__ >> 28 & 0x1; + pDst->txAntPattern = tmp63__ >> 29 & 0x1; + pDst->reserved1 = tmp63__ >> 30 & 0x3; + framesntohs(pCtx, &pDst->rxMCSMap, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &tmp64__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->rxHighSupDataRate = tmp64__ >> 0 & 0x1fff; + pDst->reserved2 = tmp64__ >> 13 & 0x7; + framesntohs(pCtx, &pDst->txMCSMap, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + framesntohs(pCtx, &tmp65__, pBuf, 0); + pDst->txSupDataRate = tmp65__ >> 0 & 0x1fff; + pDst->reserved3 = tmp65__ >> 13 & 0x7; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVHTCaps. */ + +#define SigIeVHTCaps ( 0x0079 ) + + +tANI_U32 dot11fUnpackIeVHTExtBssLoad(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVHTExtBssLoad *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->muMIMOCapStaCount = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->ssUnderUtil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->FortyMHzUtil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->EightyMHzUtil = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->OneSixtyMHzUtil = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeVHTExtBssLoad. */ + +#define SigIeVHTExtBssLoad ( 0x007a ) + + +tANI_U32 dot11fUnpackIeVHTOperation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEVHTOperation *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->chanWidth = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->chanCenterFreqSeg1 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->chanCenterFreqSeg2 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + framesntohs(pCtx, &pDst->basicMCSSet, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeVHTOperation. */ + +#define SigIeVHTOperation ( 0x007b ) + + +tANI_U32 dot11fUnpackIeWAPI(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWAPI *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U16 tmp66__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->version, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + framesntohs(pCtx, &pDst->akm_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->akm_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->akm_suites, pBuf, ( pDst->akm_suite_count * 4 ) ); + pBuf += ( pDst->akm_suite_count * 4 ); + ielen -= ( pDst->akm_suite_count * 4 ); + framesntohs(pCtx, &pDst->unicast_cipher_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->unicast_cipher_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->unicast_cipher_suites, pBuf, ( pDst->unicast_cipher_suite_count * 4 ) ); + pBuf += ( pDst->unicast_cipher_suite_count * 4 ); + ielen -= ( pDst->unicast_cipher_suite_count * 4 ); + DOT11F_MEMCPY(pCtx, pDst->multicast_cipher_suite, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + framesntohs(pCtx, &tmp66__, pBuf, 0); + pBuf += 2; + ielen -= 2; + pDst->preauth = tmp66__ >> 0 & 0x1; + pDst->reserved = tmp66__ >> 1 & 0x7fff; + if ( ! ielen ) + { + pDst->bkid_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->bkid_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->bkid_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->bkid, pBuf, ( pDst->bkid_count * 16 ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWAPI. */ + +#define SigIeWAPI ( 0x007c ) + + +tANI_U32 dot11fUnpackIeWAPIOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWAPIOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 253){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWAPIOpaque. */ + +#define SigIeWAPIOpaque ( 0x007d ) + + +tANI_U32 dot11fUnpackIeWFATPC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWFATPC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->txPower = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->linkMargin = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWFATPC. */ + +#define SigIeWFATPC ( 0x007e ) + + +tANI_U32 dot11fUnpackIeWFDIEOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWFDIEOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWFDIEOpaque. */ + +#define SigIeWFDIEOpaque ( 0x007f ) + + +tANI_U32 dot11fUnpackIeWMMCaps(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMCaps *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp67__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + tmp67__ = *pBuf; + pDst->reserved = tmp67__ >> 0 & 0xf; + pDst->qack = tmp67__ >> 4 & 0x1; + pDst->queue_request = tmp67__ >> 5 & 0x1; + pDst->txop_request = tmp67__ >> 6 & 0x1; + pDst->more_ack = tmp67__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMCaps. */ + +#define SigIeWMMCaps ( 0x0080 ) + + +tANI_U32 dot11fUnpackIeWMMInfoAp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMInfoAp *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp68__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp68__ = *pBuf; + pDst->param_set_count = tmp68__ >> 0 & 0xf; + pDst->reserved = tmp68__ >> 4 & 0x7; + pDst->uapsd = tmp68__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMInfoAp. */ + +#define SigIeWMMInfoAp ( 0x0081 ) + + +tANI_U32 dot11fUnpackIeWMMInfoStation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMInfoStation *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp69__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp69__ = *pBuf; + pDst->acvo_uapsd = tmp69__ >> 0 & 0x1; + pDst->acvi_uapsd = tmp69__ >> 1 & 0x1; + pDst->acbk_uapsd = tmp69__ >> 2 & 0x1; + pDst->acbe_uapsd = tmp69__ >> 3 & 0x1; + pDst->reserved1 = tmp69__ >> 4 & 0x1; + pDst->max_sp_length = tmp69__ >> 5 & 0x3; + pDst->reserved2 = tmp69__ >> 7 & 0x1; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMInfoStation. */ + +#define SigIeWMMInfoStation ( 0x0082 ) + + +tANI_U32 dot11fUnpackIeWMMParams(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWMMParams *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp70__; + tANI_U8 tmp71__; + tANI_U8 tmp72__; + tANI_U8 tmp73__; + tANI_U8 tmp74__; + tANI_U8 tmp75__; + tANI_U8 tmp76__; + tANI_U8 tmp77__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->version = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + pDst->qosInfo = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->reserved2 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + tmp70__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_aifsn = tmp70__ >> 0 & 0xf; + pDst->acbe_acm = tmp70__ >> 4 & 0x1; + pDst->acbe_aci = tmp70__ >> 5 & 0x3; + pDst->unused1 = tmp70__ >> 7 & 0x1; + tmp71__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbe_acwmin = tmp71__ >> 0 & 0xf; + pDst->acbe_acwmax = tmp71__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbe_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp72__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_aifsn = tmp72__ >> 0 & 0xf; + pDst->acbk_acm = tmp72__ >> 4 & 0x1; + pDst->acbk_aci = tmp72__ >> 5 & 0x3; + pDst->unused2 = tmp72__ >> 7 & 0x1; + tmp73__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acbk_acwmin = tmp73__ >> 0 & 0xf; + pDst->acbk_acwmax = tmp73__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acbk_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp74__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_aifsn = tmp74__ >> 0 & 0xf; + pDst->acvi_acm = tmp74__ >> 4 & 0x1; + pDst->acvi_aci = tmp74__ >> 5 & 0x3; + pDst->unused3 = tmp74__ >> 7 & 0x1; + tmp75__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvi_acwmin = tmp75__ >> 0 & 0xf; + pDst->acvi_acwmax = tmp75__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvi_txoplimit, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + tmp76__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_aifsn = tmp76__ >> 0 & 0xf; + pDst->acvo_acm = tmp76__ >> 4 & 0x1; + pDst->acvo_aci = tmp76__ >> 5 & 0x3; + pDst->unused4 = tmp76__ >> 7 & 0x1; + tmp77__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->acvo_acwmin = tmp77__ >> 0 & 0xf; + pDst->acvo_acwmax = tmp77__ >> 4 & 0xf; + framesntohs(pCtx, &pDst->acvo_txoplimit, pBuf, 0); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWMMParams. */ + +#define SigIeWMMParams ( 0x0083 ) + + +tANI_U32 dot11fUnpackIeWPA(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWPA *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + framesntohs(pCtx, &pDst->version, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + if (pDst->version != 0x1) + { + pDst->present = 0; + return ( status | DOT11F_BAD_FIXED_VALUE ); + } + if ( ! ielen ) + { + pDst->multicast_cipher_present = 0U; + pDst->unicast_cipher_count = 0U; + pDst->auth_suite_count = 0U; + return 0U; + } + else + { + pDst->multicast_cipher_present = 1U; + DOT11F_MEMCPY(pCtx, pDst->multicast_cipher, pBuf, 4); + pBuf += 4; + ielen -= (tANI_U8)4; + } + if ( ! ielen ) + { + pDst->unicast_cipher_count = 0U; + pDst->auth_suite_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->unicast_cipher_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->unicast_cipher_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->unicast_ciphers, pBuf, ( pDst->unicast_cipher_count * 4 ) ); + pBuf += ( pDst->unicast_cipher_count * 4 ); + ielen -= ( pDst->unicast_cipher_count * 4 ); + if ( ! ielen ) + { + pDst->auth_suite_count = 0U; + return 0U; + } + else + { + framesntohs(pCtx, &pDst->auth_suite_count, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + } + if (pDst->auth_suite_count > 4){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->auth_suites, pBuf, ( pDst->auth_suite_count * 4 ) ); + pBuf += ( pDst->auth_suite_count * 4 ); + ielen -= ( pDst->auth_suite_count * 4 ); + if ( ! ielen ) + { + return 0U; + } + else + { + framesntohs(pCtx, &pDst->caps, pBuf, 0); + } + (void)pCtx; + return status; +} /* End dot11fUnpackIeWPA. */ + +#define SigIeWPA ( 0x0084 ) + + +tANI_U32 dot11fUnpackIeWPAOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWPAOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWPAOpaque. */ + +#define SigIeWPAOpaque ( 0x0085 ) + + + static const tTLVDefn TLVS_WSC[ ] = { + {offsetof(tDot11fIEWSC, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, UUID_R), offsetof(tDot11fTLVUUID_R, present), "UUID_R", SigTlvUUID_R, DOT11F_TLV_UUID_R, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, AssociationState), offsetof(tDot11fTLVAssociationState, present), "AssociationState", SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ConfigurationError), offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError", SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, SerialNumber), offsetof(tDot11fTLVSerialNumber, present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, RequestType), offsetof(tDot11fTLVRequestType, present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWSC, RequestDeviceType), offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType", SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWSC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWSC *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WSC,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWSC. */ + +#define SigIeWSC ( 0x0086 ) + + +tANI_U32 dot11fUnpackIeWiderBWChanSwitchAnn(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWiderBWChanSwitchAnn *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->newChanWidth = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->newCenterChanFreq0 = *pBuf; + pBuf += 1; + ielen -= (tANI_U8)1; + pDst->newCenterChanFreq1 = *pBuf; + (void)pCtx; + return status; +} /* End dot11fUnpackIeWiderBWChanSwitchAnn. */ + +#define SigIeWiderBWChanSwitchAnn ( 0x0087 ) + + + static const tTLVDefn TLVS_WscAssocReq[ ] = { + {offsetof(tDot11fIEWscAssocReq, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocReq, RequestType), offsetof(tDot11fTLVRequestType, present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocReq, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscAssocReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscAssocReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscAssocReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscAssocReq. */ + +#define SigIeWscAssocReq ( 0x0088 ) + + + static const tTLVDefn TLVS_WscAssocRes[ ] = { + {offsetof(tDot11fIEWscAssocRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscAssocRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscAssocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscAssocRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscAssocRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscAssocRes. */ + +#define SigIeWscAssocRes ( 0x0089 ) + + + static const tTLVDefn TLVS_WscBeacon[ ] = { + {offsetof(tDot11fIEWscBeacon, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeacon, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscBeacon *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscBeacon,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscBeacon. */ + +#define SigIeWscBeacon ( 0x008a ) + + + static const tTLVDefn TLVS_WscBeaconProbeRes[ ] = { + {offsetof(tDot11fIEWscBeaconProbeRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, SerialNumber), offsetof(tDot11fTLVSerialNumber, present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscBeaconProbeRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscBeaconProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscBeaconProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscBeaconProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscBeaconProbeRes. */ + +#define SigIeWscBeaconProbeRes ( 0x008b ) + + +tANI_U32 dot11fUnpackIeWscIEOpaque(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscIEOpaque *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + pDst->num_data = (tANI_U8)( ielen ); + if (ielen > 249){ + pDst->present = 0; + return DOT11F_SKIPPED_BAD_IE; + } + + DOT11F_MEMCPY(pCtx, pDst->data, pBuf, ( ielen ) ); + (void)pCtx; + return status; +} /* End dot11fUnpackIeWscIEOpaque. */ + +#define SigIeWscIEOpaque ( 0x008c ) + + + static const tTLVDefn TLVS_WscProbeReq[ ] = { + {offsetof(tDot11fIEWscProbeReq, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, RequestType), offsetof(tDot11fTLVRequestType, present), "RequestType", SigTlvRequestType, DOT11F_TLV_REQUESTTYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, AssociationState), offsetof(tDot11fTLVAssociationState, present), "AssociationState", SigTlvAssociationState, DOT11F_TLV_ASSOCIATIONSTATE, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ConfigurationError), offsetof(tDot11fTLVConfigurationError, present), "ConfigurationError", SigTlvConfigurationError, DOT11F_TLV_CONFIGURATIONERROR, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeReq, RequestDeviceType), offsetof(tDot11fTLVRequestDeviceType, present), "RequestDeviceType", SigTlvRequestDeviceType, DOT11F_TLV_REQUESTDEVICETYPE, 0, 12, 12, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscProbeReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscProbeReq *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscProbeReq,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscProbeReq. */ + +#define SigIeWscProbeReq ( 0x008d ) + + + static const tTLVDefn TLVS_WscProbeRes[ ] = { + {offsetof(tDot11fIEWscProbeRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, WPSState), offsetof(tDot11fTLVWPSState, present), "WPSState", SigTlvWPSState, DOT11F_TLV_WPSSTATE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, APSetupLocked), offsetof(tDot11fTLVAPSetupLocked, present), "APSetupLocked", SigTlvAPSetupLocked, DOT11F_TLV_APSETUPLOCKED, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, SelectedRegistrar), offsetof(tDot11fTLVSelectedRegistrar, present), "SelectedRegistrar", SigTlvSelectedRegistrar, DOT11F_TLV_SELECTEDREGISTRAR, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, DevicePasswordID), offsetof(tDot11fTLVDevicePasswordID, present), "DevicePasswordID", SigTlvDevicePasswordID, DOT11F_TLV_DEVICEPASSWORDID, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, SelectedRegistrarConfigMethods), offsetof(tDot11fTLVSelectedRegistrarConfigMethods, present), "SelectedRegistrarConfigMethods", SigTlvSelectedRegistrarConfigMethods, DOT11F_TLV_SELECTEDREGISTRARCONFIGMETHODS, 0, 6, 6, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, UUID_E), offsetof(tDot11fTLVUUID_E, present), "UUID_E", SigTlvUUID_E, DOT11F_TLV_UUID_E, 0, 20, 20, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, Manufacturer), offsetof(tDot11fTLVManufacturer, present), "Manufacturer", SigTlvManufacturer, DOT11F_TLV_MANUFACTURER, 0, 4, 68, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ModelName), offsetof(tDot11fTLVModelName, present), "ModelName", SigTlvModelName, DOT11F_TLV_MODELNAME, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ModelNumber), offsetof(tDot11fTLVModelNumber, present), "ModelNumber", SigTlvModelNumber, DOT11F_TLV_MODELNUMBER, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, SerialNumber), offsetof(tDot11fTLVSerialNumber, present), "SerialNumber", SigTlvSerialNumber, DOT11F_TLV_SERIALNUMBER, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, PrimaryDeviceType), offsetof(tDot11fTLVPrimaryDeviceType, present), "PrimaryDeviceType", SigTlvPrimaryDeviceType, DOT11F_TLV_PRIMARYDEVICETYPE, 0, 12, 12, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, DeviceName), offsetof(tDot11fTLVDeviceName, present), "DeviceName", SigTlvDeviceName, DOT11F_TLV_DEVICENAME, 0, 4, 36, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, ConfigMethods), offsetof(tDot11fTLVConfigMethods, present), "ConfigMethods", SigTlvConfigMethods, DOT11F_TLV_CONFIGMETHODS, 0, 6, 6, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, RFBands), offsetof(tDot11fTLVRFBands, present), "RFBands", SigTlvRFBands, DOT11F_TLV_RFBANDS, 0, 5, 5, 0, 2, 2, 1, }, + {offsetof(tDot11fIEWscProbeRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscProbeRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscProbeRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscProbeRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscProbeRes. */ + +#define SigIeWscProbeRes ( 0x008e ) + + + static const tTLVDefn TLVS_WscReassocRes[ ] = { + {offsetof(tDot11fIEWscReassocRes, Version), offsetof(tDot11fTLVVersion, present), "Version", SigTlvVersion, DOT11F_TLV_VERSION, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscReassocRes, ResponseType), offsetof(tDot11fTLVResponseType, present), "ResponseType", SigTlvResponseType, DOT11F_TLV_RESPONSETYPE, 0, 5, 5, 1, 2, 2, 1, }, + {offsetof(tDot11fIEWscReassocRes, VendorExtension), offsetof(tDot11fTLVVendorExtension, present), "VendorExtension", SigTlvVendorExtension, DOT11F_TLV_VENDOREXTENSION, 0, 7, 21, 0, 2, 2, 1, }, + {0, 0, NULL, 0, 0xffff, 0, 0, 0, 0, 0, 0}, + }; + +tANI_U32 dot11fUnpackIeWscReassocRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEWscReassocRes *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pBuf; (void)ielen; /* Shutup the compiler */ + pDst->present = 1; + status = UnpackTlvCore(pCtx,pBuf,ielen,TLVS_WscReassocRes,(tANI_U8*)pDst,sizeof(*pDst)); + return status; +} /* End dot11fUnpackIeWscReassocRes. */ + +#define SigIeWscReassocRes ( 0x008f ) + + +tANI_U32 dot11fUnpackIehs20vendor_ie(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U8 ielen, tDot11fIEhs20vendor_ie *pDst) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U8 tmp78__; + (void) pBuf; (void)ielen; /* Shutup the compiler */ + if (pDst->present) status = DOT11F_DUPLICATE_IE; + pDst->present = 1; + tmp78__ = *pBuf; + pBuf += 1; + ielen -= 1; + pDst->dgaf_dis = tmp78__ >> 0 & 0x1; + pDst->hs_id_present = tmp78__ >> 1 & 0x3; + pDst->reserved = tmp78__ >> 3 & 0x1; + pDst->release_num = tmp78__ >> 4 & 0xf; + if ( ! ielen ) + { + return 0U; + } + else + { + switch (pDst->hs_id_present) + { + case 1: + framesntohs(pCtx, &pDst->hs_id.pps_mo.pps_mo_id, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + case 2: + framesntohs(pCtx, &pDst->hs_id.anqp_domain.anqp_domain_id, pBuf, 0); + pBuf += 2; + ielen -= (tANI_U8)2; + break; + } + } + (void)pCtx; + return status; +} /* End dot11fUnpackIehs20vendor_ie. */ + +#define SigIehs20vendor_ie ( 0x0090 ) + + + static const tFFDefn FFS_AddBAReq[] = { + { "Category", offsetof(tDot11fAddBAReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddBAReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddBAReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "AddBAParameterSet", offsetof(tDot11fAddBAReq, AddBAParameterSet), SigFfAddBAParameterSet , DOT11F_FF_ADDBAPARAMETERSET_LEN, }, + { "BATimeout", offsetof(tDot11fAddBAReq, BATimeout), SigFfBATimeout , DOT11F_FF_BATIMEOUT_LEN, }, + { "BAStartingSequenceControl", offsetof(tDot11fAddBAReq, BAStartingSequenceControl), SigFfBAStartingSequenceControl , DOT11F_FF_BASTARTINGSEQUENCECONTROL_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddBAReq[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddBAReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBAReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddBAReq, IES_AddBAReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Unpacked the AddBAReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BAStartingSequenceControl:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("fragNumber (4): %d\n"), pFrm->BAStartingSequenceControl.fragNumber); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("ssn (12): %d\n"), pFrm->BAStartingSequenceControl.ssn); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBAReq. */ + + static const tFFDefn FFS_AddBARsp[] = { + { "Category", offsetof(tDot11fAddBARsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddBARsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddBARsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Status", offsetof(tDot11fAddBARsp, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "AddBAParameterSet", offsetof(tDot11fAddBARsp, AddBAParameterSet), SigFfAddBAParameterSet , DOT11F_FF_ADDBAPARAMETERSET_LEN, }, + { "BATimeout", offsetof(tDot11fAddBARsp, BATimeout), SigFfBATimeout , DOT11F_FF_BATIMEOUT_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddBARsp[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddBARsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddBARsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddBARsp, IES_AddBARsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Unpacked the AddBARsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBARsp. */ + + static const tFFDefn FFS_AddTSRequest[] = { + { "Category", offsetof(tDot11fAddTSRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddTSRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddTSRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddTSRequest[] = { + {offsetof(tDot11fAddTSRequest, TSPEC), offsetof(tDot11fIETSPEC, present), 0, "TSPEC" , 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSPEC, 1, }, + {offsetof(tDot11fAddTSRequest, TCLAS), offsetof(tDot11fIETCLAS, present), offsetof(tDot11fAddTSRequest, num_TCLAS), "TCLAS" , 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, }, + {offsetof(tDot11fAddTSRequest, TCLASSPROC), offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC" , 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLASSPROC, 0, }, + {offsetof(tDot11fAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fAddTSRequest, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS, present), offsetof(tDot11fAddTSRequest, num_WMMTCLAS), "WMMTCLAS" , 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6}, 5, DOT11F_EID_WMMTCLAS, 0, }, + {offsetof(tDot11fAddTSRequest, WMMTCLASPROC), offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC" , 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7}, 5, DOT11F_EID_WMMTCLASPROC, 0, }, + {offsetof(tDot11fAddTSRequest, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddTSRequest, IES_AddTSRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Unpacked the AddTSRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSRequest. */ + + static const tFFDefn FFS_AddTSResponse[] = { + { "Category", offsetof(tDot11fAddTSResponse, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fAddTSResponse, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fAddTSResponse, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Status", offsetof(tDot11fAddTSResponse, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AddTSResponse[] = { + {offsetof(tDot11fAddTSResponse, TSDelay), offsetof(tDot11fIETSDelay, present), 0, "TSDelay" , 0, 6, 6, SigIeTSDelay, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSDELAY, 1, }, + {offsetof(tDot11fAddTSResponse, TSPEC), offsetof(tDot11fIETSPEC, present), 0, "TSPEC" , 0, 57, 57, SigIeTSPEC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TSPEC, 1, }, + {offsetof(tDot11fAddTSResponse, TCLAS), offsetof(tDot11fIETCLAS, present), offsetof(tDot11fAddTSResponse, num_TCLAS), "TCLAS" , 2, 7, 45, SigIeTCLAS, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLAS, 0, }, + {offsetof(tDot11fAddTSResponse, TCLASSPROC), offsetof(tDot11fIETCLASSPROC, present), 0, "TCLASSPROC" , 0, 3, 3, SigIeTCLASSPROC, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TCLASSPROC, 0, }, + {offsetof(tDot11fAddTSResponse, Schedule), offsetof(tDot11fIESchedule, present), 0, "Schedule" , 0, 16, 16, SigIeSchedule, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SCHEDULE, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTSDelay), offsetof(tDot11fIEWMMTSDelay, present), 0, "WMMTSDelay" , 0, 12, 12, SigIeWMMTSDelay, {0, 80, 242, 2, 8}, 5, DOT11F_EID_WMMTSDELAY, 0, }, + {offsetof(tDot11fAddTSResponse, WMMSchedule), offsetof(tDot11fIEWMMSchedule, present), 0, "WMMSchedule" , 0, 22, 22, SigIeWMMSchedule, {0, 80, 242, 2, 9}, 5, DOT11F_EID_WMMSCHEDULE, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTCLAS), offsetof(tDot11fIEWMMTCLAS, present), offsetof(tDot11fAddTSResponse, num_WMMTCLAS), "WMMTCLAS" , 2, 13, 51, SigIeWMMTCLAS, {0, 80, 242, 2, 6}, 5, DOT11F_EID_WMMTCLAS, 0, }, + {offsetof(tDot11fAddTSResponse, WMMTCLASPROC), offsetof(tDot11fIEWMMTCLASPROC, present), 0, "WMMTCLASPROC" , 0, 9, 9, SigIeWMMTCLASPROC, {0, 80, 242, 2, 7}, 5, DOT11F_EID_WMMTCLASPROC, 0, }, + {offsetof(tDot11fAddTSResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAddTSResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AddTSResponse, IES_AddTSResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Unpacked the AddTSResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSResponse. */ + + static const tFFDefn FFS_AssocRequest[] = { + { "Capabilities", offsetof(tDot11fAssocRequest, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "ListenInterval", offsetof(tDot11fAssocRequest, ListenInterval), SigFfListenInterval , DOT11F_FF_LISTENINTERVAL_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AssocRequest[] = { + {offsetof(tDot11fAssocRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fAssocRequest, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fAssocRequest, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fAssocRequest, PowerCaps), offsetof(tDot11fIEPowerCaps, present), 0, "PowerCaps" , 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCAPS, 0, }, + {offsetof(tDot11fAssocRequest, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fAssocRequest, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fAssocRequest, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fAssocRequest, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque" , 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPAOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fAssocRequest, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fAssocRequest, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fAssocRequest, WscIEOpaque), offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque" , 0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCIEOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, WAPIOpaque), offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque" , 0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPIOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fAssocRequest, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {offsetof(tDot11fAssocRequest, P2PIEOpaque), offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque" , 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PIEOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, WFDIEOpaque), offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque" , 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0}, 4, DOT11F_EID_WFDIEOPAQUE, 0, }, + {offsetof(tDot11fAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {offsetof(tDot11fAssocRequest, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AssocRequest, IES_AssocRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Unpacked the AssocRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocRequest. */ + + static const tFFDefn FFS_AssocResponse[] = { + { "Capabilities", offsetof(tDot11fAssocResponse, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "Status", offsetof(tDot11fAssocResponse, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "AID", offsetof(tDot11fAssocResponse, AID), SigFfAID , DOT11F_FF_AID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_AssocResponse[] = { + {offsetof(tDot11fAssocResponse, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fAssocResponse, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fAssocResponse, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE, present), 0, "RCPIIE" , 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RCPIIE, 0, }, + {offsetof(tDot11fAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE, present), 0, "RSNIIE" , 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNIIE, 0, }, + {offsetof(tDot11fAssocResponse, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fAssocResponse, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fAssocResponse, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fAssocResponse, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {offsetof(tDot11fAssocResponse, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fAssocResponse, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fAssocResponse, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fAssocResponse, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fAssocResponse, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fAssocResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fAssocResponse, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), offsetof(tDot11fAssocResponse, num_WMMTSPEC), "WMMTSPEC" , 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fAssocResponse, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fAssocResponse, WscAssocRes), offsetof(tDot11fIEWscAssocRes, present), 0, "WscAssocRes" , 0, 6, 37, SigIeWscAssocRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCASSOCRES, 0, }, + {offsetof(tDot11fAssocResponse, P2PAssocRes), offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes" , 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PASSOCRES, 0, }, + {offsetof(tDot11fAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fAssocResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fAssocResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAssocResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_AssocResponse, IES_AssocResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Unpacked the AssocResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WscAssocRes:\n")); + if (!pFrm->WscAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscAssocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscAssocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscAssocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscAssocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscAssocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocResponse. */ + + static const tFFDefn FFS_Authentication[] = { + { "AuthAlgo", offsetof(tDot11fAuthentication, AuthAlgo), SigFfAuthAlgo , DOT11F_FF_AUTHALGO_LEN, }, + { "AuthSeqNo", offsetof(tDot11fAuthentication, AuthSeqNo), SigFfAuthSeqNo , DOT11F_FF_AUTHSEQNO_LEN, }, + { "Status", offsetof(tDot11fAuthentication, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Authentication[] = { + {offsetof(tDot11fAuthentication, ChallengeText), offsetof(tDot11fIEChallengeText, present), 0, "ChallengeText" , 0, 3, 255, SigIeChallengeText, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHALLENGETEXT, 0, }, + {offsetof(tDot11fAuthentication, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fAuthentication, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fAuthentication, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fAuthentication, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fAuthentication, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fAuthentication, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackAuthentication(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fAuthentication *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Authentication, IES_Authentication, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Unpacked the Authentication:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthAlgo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthAlgo.algo, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthSeqNo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthSeqNo.no, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("ChallengeText:\n")); + if (!pFrm->ChallengeText.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_text: %d.\n"), pFrm->ChallengeText.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->ChallengeText.text, pFrm->ChallengeText.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAuthentication. */ + + static const tFFDefn FFS_Beacon[] = { + { "TimeStamp", offsetof(tDot11fBeacon, TimeStamp), SigFfTimeStamp , DOT11F_FF_TIMESTAMP_LEN, }, + { "BeaconInterval", offsetof(tDot11fBeacon, BeaconInterval), SigFfBeaconInterval , DOT11F_FF_BEACONINTERVAL_LEN, }, + { "Capabilities", offsetof(tDot11fBeacon, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Beacon[] = { + {offsetof(tDot11fBeacon, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fBeacon, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fBeacon, FHParamSet), offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet" , 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMSET, 0, }, + {offsetof(tDot11fBeacon, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fBeacon, CFParams), offsetof(tDot11fIECFParams, present), 0, "CFParams" , 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CFPARAMS, 0, }, + {offsetof(tDot11fBeacon, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {offsetof(tDot11fBeacon, TIM), offsetof(tDot11fIETIM, present), 0, "TIM" , 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, }, + {offsetof(tDot11fBeacon, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fBeacon, FHParams), offsetof(tDot11fIEFHParams, present), 0, "FHParams" , 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMS, 0, }, + {offsetof(tDot11fBeacon, FHPattTable), offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable" , 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPATTTABLE, 0, }, + {offsetof(tDot11fBeacon, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fBeacon, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fBeacon, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fBeacon, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fBeacon, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fBeacon, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fBeacon, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present), 0, "QBSSLoad" , 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QBSSLOAD, 0, }, + {offsetof(tDot11fBeacon, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fBeacon, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp, present), 0, "QOSCapsAp" , 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSAP, 0, }, + {offsetof(tDot11fBeacon, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fBeacon, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fBeacon, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fBeacon, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fBeacon, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fBeacon, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fBeacon, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fBeacon, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fBeacon, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fBeacon, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fBeacon, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fBeacon, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fBeacon, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fBeacon, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fBeacon, WscBeacon), offsetof(tDot11fIEWscBeacon, present), 0, "WscBeacon" , 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCBEACON, 0, }, + {offsetof(tDot11fBeacon, P2PBeacon), offsetof(tDot11fIEP2PBeacon, present), 0, "P2PBeacon" , 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PBEACON, 0, }, + {offsetof(tDot11fBeacon, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fBeacon, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fBeacon, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fBeacon, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fBeacon, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fBeacon, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fBeacon, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeacon(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Beacon, IES_Beacon, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Unpacked the Beacon:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon. */ + + static const tFFDefn FFS_Beacon1[] = { + { "TimeStamp", offsetof(tDot11fBeacon1, TimeStamp), SigFfTimeStamp , DOT11F_FF_TIMESTAMP_LEN, }, + { "BeaconInterval", offsetof(tDot11fBeacon1, BeaconInterval), SigFfBeaconInterval , DOT11F_FF_BEACONINTERVAL_LEN, }, + { "Capabilities", offsetof(tDot11fBeacon1, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Beacon1[] = { + {offsetof(tDot11fBeacon1, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fBeacon1, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fBeacon1, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fBeacon1, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeacon1(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon1 *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Beacon1, IES_Beacon1, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Unpacked the Beacon1:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon1. */ + + static const tFFDefn FFS_Beacon2[] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Beacon2[] = { + {offsetof(tDot11fBeacon2, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fBeacon2, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fBeacon2, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon2, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fBeacon2, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fBeacon2, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fBeacon2, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fBeacon2, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fBeacon2, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fBeacon2, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fBeacon2, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fBeacon2, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fBeacon2, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fBeacon2, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fBeacon2, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fBeacon2, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon2, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fBeacon2, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fBeacon2, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fBeacon2, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fBeacon2, WscBeacon), offsetof(tDot11fIEWscBeacon, present), 0, "WscBeacon" , 0, 6, 84, SigIeWscBeacon, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCBEACON, 0, }, + {offsetof(tDot11fBeacon2, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fBeacon2, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fBeacon2, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fBeacon2, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fBeacon2, P2PBeacon), offsetof(tDot11fIEP2PBeacon, present), 0, "P2PBeacon" , 0, 6, 61, SigIeP2PBeacon, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PBEACON, 0, }, + {offsetof(tDot11fBeacon2, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fBeacon2, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fBeacon2, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fBeacon2, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fBeacon2, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fBeacon2, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeacon2, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fBeacon2, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeacon2(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeacon2 *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Beacon2, IES_Beacon2, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Unpacked the Beacon2:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon2. */ + + static const tFFDefn FFS_BeaconIEs[] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_BeaconIEs[] = { + {offsetof(tDot11fBeaconIEs, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fBeaconIEs, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fBeaconIEs, FHParamSet), offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet" , 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMSET, 0, }, + {offsetof(tDot11fBeaconIEs, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, CFParams), offsetof(tDot11fIECFParams, present), 0, "CFParams" , 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CFPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, TIM), offsetof(tDot11fIETIM, present), 0, "TIM" , 0, 6, 256, SigIeTIM, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIM, 0, }, + {offsetof(tDot11fBeaconIEs, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fBeaconIEs, FHParams), offsetof(tDot11fIEFHParams, present), 0, "FHParams" , 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, FHPattTable), offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable" , 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPATTTABLE, 0, }, + {offsetof(tDot11fBeaconIEs, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fBeaconIEs, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fBeaconIEs, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fBeaconIEs, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fBeaconIEs, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fBeaconIEs, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fBeaconIEs, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fBeaconIEs, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present), 0, "QBSSLoad" , 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QBSSLOAD, 0, }, + {offsetof(tDot11fBeaconIEs, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fBeaconIEs, QOSCapsAp), offsetof(tDot11fIEQOSCapsAp, present), 0, "QOSCapsAp" , 0, 3, 3, SigIeQOSCapsAp, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSAP, 0, }, + {offsetof(tDot11fBeaconIEs, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fBeaconIEs, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fBeaconIEs, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fBeaconIEs, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fBeaconIEs, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fBeaconIEs, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fBeaconIEs, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeaconIEs, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fBeaconIEs, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fBeaconIEs, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fBeaconIEs, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fBeaconIEs, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {offsetof(tDot11fBeaconIEs, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fBeaconIEs, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fBeaconIEs, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fBeaconIEs, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fBeaconIEs, WscBeaconProbeRes), offsetof(tDot11fIEWscBeaconProbeRes, present), 0, "WscBeaconProbeRes" , 0, 6, 319, SigIeWscBeaconProbeRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCBEACONPROBERES, 0, }, + {offsetof(tDot11fBeaconIEs, P2PBeaconProbeRes), offsetof(tDot11fIEP2PBeaconProbeRes, present), 0, "P2PBeaconProbeRes" , 0, 6, 1150, SigIeP2PBeaconProbeRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PBEACONPROBERES, 0, }, + {offsetof(tDot11fBeaconIEs, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fBeaconIEs, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fBeaconIEs, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fBeaconIEs, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fBeaconIEs, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fBeaconIEs, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {offsetof(tDot11fBeaconIEs, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fBeaconIEs, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackBeaconIEs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fBeaconIEs *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_BeaconIEs, IES_BeaconIEs, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Unpacked the BeaconIEs:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WscBeaconProbeRes:\n")); + if (!pFrm->WscBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->WscBeaconProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPSState:\n")); + if (!pFrm->WscBeaconProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeaconProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeaconProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ResponseType:\n")); + if (!pFrm->WscBeaconProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("UUID_E:\n")); + if (!pFrm->WscBeaconProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Manufacturer:\n")); + if (!pFrm->WscBeaconProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->WscBeaconProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.Manufacturer.name, pFrm->WscBeaconProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelName:\n")); + if (!pFrm->WscBeaconProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelName.text, pFrm->WscBeaconProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelNumber:\n")); + if (!pFrm->WscBeaconProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelNumber.text, pFrm->WscBeaconProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SerialNumber:\n")); + if (!pFrm->WscBeaconProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.SerialNumber.text, pFrm->WscBeaconProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscBeaconProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->WscBeaconProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.DeviceName.text, pFrm->WscBeaconProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RFBands:\n")); + if (!pFrm->WscBeaconProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version2:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PBeaconProbeRes:\n")); + if (!pFrm->P2PBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PBeaconProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeaconProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeaconIEs. */ + + static const tFFDefn FFS_ChannelSwitch[] = { + { "Category", offsetof(tDot11fChannelSwitch, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fChannelSwitch, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ChannelSwitch[] = { + {offsetof(tDot11fChannelSwitch, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 1, }, + {offsetof(tDot11fChannelSwitch, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fChannelSwitch, WiderBWChanSwitchAnn), offsetof(tDot11fIEWiderBWChanSwitchAnn, present), 0, "WiderBWChanSwitchAnn" , 0, 5, 5, SigIeWiderBWChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WIDERBWCHANSWITCHANN, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackChannelSwitch(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fChannelSwitch *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ChannelSwitch, IES_ChannelSwitch, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Unpacked the ChannelSwitch:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackChannelSwitch. */ + + static const tFFDefn FFS_DeAuth[] = { + { "Reason", offsetof(tDot11fDeAuth, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DeAuth[] = { + {offsetof(tDot11fDeAuth, P2PDeAuth), offsetof(tDot11fIEP2PDeAuth, present), 0, "P2PDeAuth" , 0, 6, 10, SigIeP2PDeAuth, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDEAUTH, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDeAuth(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeAuth *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DeAuth, IES_DeAuth, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Unpacked the DeAuth:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("P2PDeAuth:\n")); + if (!pFrm->P2PDeAuth.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDeAuth.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->P2PDeAuth.MinorReasonCode.minorReasonCode, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeAuth. */ + + static const tFFDefn FFS_DelBAInd[] = { + { "Category", offsetof(tDot11fDelBAInd, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDelBAInd, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DelBAParameterSet", offsetof(tDot11fDelBAInd, DelBAParameterSet), SigFfDelBAParameterSet , DOT11F_FF_DELBAPARAMETERSET_LEN, }, + { "Reason", offsetof(tDot11fDelBAInd, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DelBAInd[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDelBAInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelBAInd *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DelBAInd, IES_DelBAInd, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Unpacked the DelBAInd:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("DelBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("reserved (11): %d\n"), pFrm->DelBAParameterSet.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("initiator (1): %d\n"), pFrm->DelBAParameterSet.initiator); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("tid (4): %d\n"), pFrm->DelBAParameterSet.tid); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Reason.code, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelBAInd. */ + + static const tFFDefn FFS_DelTS[] = { + { "Category", offsetof(tDot11fDelTS, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDelTS, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "TSInfo", offsetof(tDot11fDelTS, TSInfo), SigFfTSInfo , DOT11F_FF_TSINFO_LEN, }, + { "Reason", offsetof(tDot11fDelTS, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DelTS[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDelTS *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DelTS, IES_DelTS, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Unpacked the DelTS:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("TSInfo:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("traffic_type (1): %d\n"), pFrm->TSInfo.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsid (4): %d\n"), pFrm->TSInfo.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("direction (2): %d\n"), pFrm->TSInfo.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("access_policy (2): %d\n"), pFrm->TSInfo.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("aggregation (1): %d\n"), pFrm->TSInfo.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("psb (1): %d\n"), pFrm->TSInfo.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("user_priority (3): %d\n"), pFrm->TSInfo.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSInfo.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("schedule (1): %d\n"), pFrm->TSInfo.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("unused (15): %d\n"), pFrm->TSInfo.unused); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Reason.code, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelTS. */ + + static const tFFDefn FFS_DeviceDiscoverabilityReq[] = { + { "Category", offsetof(tDot11fDeviceDiscoverabilityReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDeviceDiscoverabilityReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fDeviceDiscoverabilityReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fDeviceDiscoverabilityReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fDeviceDiscoverabilityReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DeviceDiscoverabilityReq[] = { + {offsetof(tDot11fDeviceDiscoverabilityReq, P2PDeviceDiscoverabilityReq), offsetof(tDot11fIEP2PDeviceDiscoverabilityReq, present), 0, "P2PDeviceDiscoverabilityReq" , 0, 6, 56, SigIeP2PDeviceDiscoverabilityReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDEVICEDISCOVERABILITYREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DeviceDiscoverabilityReq, IES_DeviceDiscoverabilityReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Unpacked the DeviceDiscoverabilityReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceDiscoverabilityReq:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* ) pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.ssid, pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityReq. */ + + static const tFFDefn FFS_DeviceDiscoverabilityRes[] = { + { "Category", offsetof(tDot11fDeviceDiscoverabilityRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fDeviceDiscoverabilityRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fDeviceDiscoverabilityRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fDeviceDiscoverabilityRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fDeviceDiscoverabilityRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_DeviceDiscoverabilityRes[] = { + {offsetof(tDot11fDeviceDiscoverabilityRes, P2PDeviceDiscoverabilityRes), offsetof(tDot11fIEP2PDeviceDiscoverabilityRes, present), 0, "P2PDeviceDiscoverabilityRes" , 0, 6, 10, SigIeP2PDeviceDiscoverabilityRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDEVICEDISCOVERABILITYRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDeviceDiscoverabilityRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_DeviceDiscoverabilityRes, IES_DeviceDiscoverabilityRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Unpacked the DeviceDiscoverabilityRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PDeviceDiscoverabilityRes:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.status, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityRes. */ + + static const tFFDefn FFS_Disassociation[] = { + { "Reason", offsetof(tDot11fDisassociation, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_Disassociation[] = { + {offsetof(tDot11fDisassociation, P2PDisAssoc), offsetof(tDot11fIEP2PDisAssoc, present), 0, "P2PDisAssoc" , 0, 6, 10, SigIeP2PDisAssoc, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PDISASSOC, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackDisassociation(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fDisassociation *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_Disassociation, IES_Disassociation, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Unpacked the Disassociation:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("P2PDisAssoc:\n")); + if (!pFrm->P2PDisAssoc.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDisAssoc.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->P2PDisAssoc.MinorReasonCode.minorReasonCode, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDisassociation. */ + + static const tFFDefn FFS_GODiscoverabilityReq[] = { + { "Category", offsetof(tDot11fGODiscoverabilityReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fGODiscoverabilityReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGODiscoverabilityReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGODiscoverabilityReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GODiscoverabilityReq[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGODiscoverabilityReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGODiscoverabilityReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GODiscoverabilityReq, IES_GODiscoverabilityReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Unpacked the GODiscoverabilityReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGODiscoverabilityReq. */ + + static const tFFDefn FFS_GONegCnf[] = { + { "Category", offsetof(tDot11fGONegCnf, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fGONegCnf, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fGONegCnf, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGONegCnf, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGONegCnf, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GONegCnf[] = { + {offsetof(tDot11fGONegCnf, P2PGONegCnf), offsetof(tDot11fIEP2PGONegCnf, present), 0, "P2PGONegCnf" , 0, 6, 321, SigIeP2PGONegCnf, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PGONEGCNF, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGONegCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegCnf *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GONegCnf, IES_GONegCnf, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Unpacked the GONegCnf:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGONegCnf:\n")); + if (!pFrm->P2PGONegCnf.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegCnf.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegCnf.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegCnf.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegCnf.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegCnf.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.ChannelList.channelList, pFrm->P2PGONegCnf.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegCnf.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.P2PGroupId.ssid, pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegCnf. */ + + static const tFFDefn FFS_GONegReq[] = { + { "Category", offsetof(tDot11fGONegReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fGONegReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fGONegReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGONegReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGONegReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GONegReq[] = { + {offsetof(tDot11fGONegReq, P2PGONegWPS), offsetof(tDot11fIEP2PGONegWPS, present), 0, "P2PGONegWPS" , 0, 6, 17, SigIeP2PGONegWPS, {0, 80, 242, 4, 0}, 4, DOT11F_EID_P2PGONEGWPS, 1, }, + {offsetof(tDot11fGONegReq, P2PGONegReq), offsetof(tDot11fIEP2PGONegReq, present), 0, "P2PGONegReq" , 0, 6, 364, SigIeP2PGONegReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PGONEGREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGONegReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GONegReq, IES_GONegReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Unpacked the GONegReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegReq:\n")); + if (!pFrm->P2PGONegReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegReq.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ListenChannel:\n")); + if (!pFrm->P2PGONegReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PGONegReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.ChannelList.channelList, pFrm->P2PGONegReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_text: %d.\n"), pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.channel, 1); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegReq. */ + + static const tFFDefn FFS_GONegRes[] = { + { "Category", offsetof(tDot11fGONegRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fGONegRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fGONegRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fGONegRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fGONegRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_GONegRes[] = { + {offsetof(tDot11fGONegRes, P2PGONegWPS), offsetof(tDot11fIEP2PGONegWPS, present), 0, "P2PGONegWPS" , 0, 6, 17, SigIeP2PGONegWPS, {0, 80, 242, 4, 0}, 4, DOT11F_EID_P2PGONEGWPS, 1, }, + {offsetof(tDot11fGONegRes, P2PGONegRes), offsetof(tDot11fIEP2PGONegRes, present), 0, "P2PGONegRes" , 0, 6, 394, SigIeP2PGONegRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PGONEGRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackGONegRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fGONegRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_GONegRes, IES_GONegRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Unpacked the GONegRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegRes:\n")); + if (!pFrm->P2PGONegRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegRes.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.ChannelList.channelList, pFrm->P2PGONegRes.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_text: %d.\n"), pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegRes.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegRes.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PGroupId.ssid, pFrm->P2PGONegRes.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegRes. */ + + static const tFFDefn FFS_HT2040BSSCoexistenceManagementActionFrame[] = { + { "Category", offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_HT2040BSSCoexistenceManagementActionFrame[] = { + {offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 1, }, + {offsetof(tDot11fHT2040BSSCoexistenceManagementActionFrame, HT2040BSSIntolerantReport), offsetof(tDot11fIEHT2040BSSIntolerantReport, present), 0, "HT2040BSSIntolerantReport" , 0, 3, 53, SigIeHT2040BSSIntolerantReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSINTOLERANTREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_HT2040BSSCoexistenceManagementActionFrame, IES_HT2040BSSCoexistenceManagementActionFrame, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Unpacked the HT2040BSSCoexistenceManagementActionFrame:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSIntolerantReport:\n")); + if (!pFrm->HT2040BSSIntolerantReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->HT2040BSSIntolerantReport.operatingClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("num_channelList: %d.\n"), pFrm->HT2040BSSIntolerantReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* ) pFrm->HT2040BSSIntolerantReport.channelList, pFrm->HT2040BSSIntolerantReport.num_channelList); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackHT2040BSSCoexistenceManagementActionFrame. */ + + static const tFFDefn FFS_InvitationReq[] = { + { "Category", offsetof(tDot11fInvitationReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fInvitationReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fInvitationReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fInvitationReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fInvitationReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_InvitationReq[] = { + {offsetof(tDot11fInvitationReq, P2PInvitationReq), offsetof(tDot11fIEP2PInvitationReq, present), 0, "P2PInvitationReq" , 0, 6, 385, SigIeP2PInvitationReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PINVITATIONREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackInvitationReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_InvitationReq, IES_InvitationReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Unpacked the InvitationReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PInvitationReq:\n")); + if (!pFrm->P2PInvitationReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("InvitationFlags:\n")); + if (!pFrm->P2PInvitationReq.InvitationFlags.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.InvitationFlags.invitationFlags, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.ChannelList.channelList, pFrm->P2PInvitationReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PGroupId.ssid, pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_text: %d.\n"), pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationReq. */ + + static const tFFDefn FFS_InvitationRes[] = { + { "Category", offsetof(tDot11fInvitationRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fInvitationRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fInvitationRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fInvitationRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fInvitationRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_InvitationRes[] = { + {offsetof(tDot11fInvitationRes, P2PInvitationRes), offsetof(tDot11fIEP2PInvitationRes, present), 0, "P2PInvitationRes" , 0, 6, 289, SigIeP2PInvitationRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PINVITATIONRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackInvitationRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fInvitationRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_InvitationRes, IES_InvitationRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Unpacked the InvitationRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PInvitationRes:\n")); + if (!pFrm->P2PInvitationRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PInvitationRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationRes.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* ) pFrm->P2PInvitationRes.ChannelList.channelList, pFrm->P2PInvitationRes.ChannelList.num_channelList); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationRes. */ + + static const tFFDefn FFS_LinkMeasurementReport[] = { + { "Category", offsetof(tDot11fLinkMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fLinkMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fLinkMeasurementReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "TPCEleID", offsetof(tDot11fLinkMeasurementReport, TPCEleID), SigFfTPCEleID , DOT11F_FF_TPCELEID_LEN, }, + { "TPCEleLen", offsetof(tDot11fLinkMeasurementReport, TPCEleLen), SigFfTPCEleLen , DOT11F_FF_TPCELELEN_LEN, }, + { "TxPower", offsetof(tDot11fLinkMeasurementReport, TxPower), SigFfTxPower , DOT11F_FF_TXPOWER_LEN, }, + { "LinkMargin", offsetof(tDot11fLinkMeasurementReport, LinkMargin), SigFfLinkMargin , DOT11F_FF_LINKMARGIN_LEN, }, + { "RxAntennaId", offsetof(tDot11fLinkMeasurementReport, RxAntennaId), SigFfRxAntennaId , DOT11F_FF_RXANTENNAID_LEN, }, + { "TxAntennaId", offsetof(tDot11fLinkMeasurementReport, TxAntennaId), SigFfTxAntennaId , DOT11F_FF_TXANTENNAID_LEN, }, + { "RCPI", offsetof(tDot11fLinkMeasurementReport, RCPI), SigFfRCPI , DOT11F_FF_RCPI_LEN, }, + { "RSNI", offsetof(tDot11fLinkMeasurementReport, RSNI), SigFfRSNI , DOT11F_FF_RSNI_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_LinkMeasurementReport[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackLinkMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_LinkMeasurementReport, IES_LinkMeasurementReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Unpacked the LinkMeasurementReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleID.TPCId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleLen:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleLen.TPCLen, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("LinkMargin:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->LinkMargin.linkMargin, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RCPI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RCPI.rcpi, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RSNI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RSNI.rsni, 1); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementReport. */ + + static const tFFDefn FFS_LinkMeasurementRequest[] = { + { "Category", offsetof(tDot11fLinkMeasurementRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fLinkMeasurementRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fLinkMeasurementRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "TxPower", offsetof(tDot11fLinkMeasurementRequest, TxPower), SigFfTxPower , DOT11F_FF_TXPOWER_LEN, }, + { "MaxTxPower", offsetof(tDot11fLinkMeasurementRequest, MaxTxPower), SigFfMaxTxPower , DOT11F_FF_MAXTXPOWER_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_LinkMeasurementRequest[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackLinkMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fLinkMeasurementRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Unpacked the LinkMeasurementRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("MaxTxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MaxTxPower.maxTxPower, 1); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementRequest. */ + + static const tFFDefn FFS_MeasurementReport[] = { + { "Category", offsetof(tDot11fMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fMeasurementReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_MeasurementReport[] = { + {offsetof(tDot11fMeasurementReport, MeasurementReport), offsetof(tDot11fIEMeasurementReport, present), 0, "MeasurementReport" , 0, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_MeasurementReport, IES_MeasurementReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Unpacked the MeasurementReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("MeasurementReport:\n")); + if (!pFrm->MeasurementReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport.late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport.incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport.refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport.unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.type, 1); + switch (pFrm->MeasurementReport.type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport.report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport.report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport.report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport.report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport.report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport.report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport.report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport.report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.parent_TSF, 4); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementReport. */ + + static const tFFDefn FFS_MeasurementRequest[] = { + { "Category", offsetof(tDot11fMeasurementRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fMeasurementRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fMeasurementRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_MeasurementRequest[] = { + {offsetof(tDot11fMeasurementRequest, MeasurementRequest), offsetof(tDot11fIEMeasurementRequest, present), offsetof(tDot11fMeasurementRequest, num_MeasurementRequest), "MeasurementRequest" , 4, 16, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fMeasurementRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_MeasurementRequest, IES_MeasurementRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Unpacked the MeasurementRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementRequest. */ + + static const tFFDefn FFS_NeighborReportRequest[] = { + { "Category", offsetof(tDot11fNeighborReportRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fNeighborReportRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fNeighborReportRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NeighborReportRequest[] = { + {offsetof(tDot11fNeighborReportRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackNeighborReportRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_NeighborReportRequest, IES_NeighborReportRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Unpacked the NeighborReportRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportRequest. */ + + static const tFFDefn FFS_NeighborReportResponse[] = { + { "Category", offsetof(tDot11fNeighborReportResponse, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fNeighborReportResponse, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fNeighborReportResponse, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NeighborReportResponse[] = { + {offsetof(tDot11fNeighborReportResponse, NeighborReport), offsetof(tDot11fIENeighborReport, present), offsetof(tDot11fNeighborReportResponse, num_NeighborReport), "NeighborReport" , 4, 15, 548, SigIeNeighborReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_NEIGHBORREPORT, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackNeighborReportResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNeighborReportResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_NeighborReportResponse, IES_NeighborReportResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Unpacked the NeighborReportResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_NeighborReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborReport[%d]:\n"), i); + if (!pFrm->NeighborReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].bssid, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APReachability (2): %d\n"), pFrm->NeighborReport[i].APReachability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Security (1): %d\n"), pFrm->NeighborReport[i].Security); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("KeyScope (1): %d\n"), pFrm->NeighborReport[i].KeyScope); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("SpecMgmtCap (1): %d\n"), pFrm->NeighborReport[i].SpecMgmtCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("QosCap (1): %d\n"), pFrm->NeighborReport[i].QosCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("apsd (1): %d\n"), pFrm->NeighborReport[i].apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("rrm (1): %d\n"), pFrm->NeighborReport[i].rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DelayedBA (1): %d\n"), pFrm->NeighborReport[i].DelayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ImmBA (1): %d\n"), pFrm->NeighborReport[i].ImmBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MobilityDomain (1): %d\n"), pFrm->NeighborReport[i].MobilityDomain); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (5): %d\n"), pFrm->NeighborReport[i].reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].reserved1, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].PhyType, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TSFInfo:\n")); + if (!pFrm->NeighborReport[i].TSFInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.TsfOffset, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.BeaconIntvl, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("CondensedCountryStr:\n")); + if (!pFrm->NeighborReport[i].CondensedCountryStr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].CondensedCountryStr.countryStr, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot:\n")); + if (!pFrm->NeighborReport[i].MeasurementPilot.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MeasurementPilot.measurementPilot, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MeasurementPilot.vendorSpecific, pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->NeighborReport[i].RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("parallel (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("repeated (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("statistics (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (6): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MultiBssid:\n")); + if (!pFrm->NeighborReport[i].MultiBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MultiBssid.maxBSSIDIndicator, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MultiBssid.vendorSpecific, pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportResponse. */ + + static const tFFDefn FFS_NoticeOfAbs[] = { + { "Category", offsetof(tDot11fNoticeOfAbs, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fNoticeOfAbs, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fNoticeOfAbs, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fNoticeOfAbs, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_NoticeOfAbs[] = { + {offsetof(tDot11fNoticeOfAbs, P2PNoticeOfAbsence), offsetof(tDot11fIEP2PNoticeOfAbsence, present), 0, "P2PNoticeOfAbsence" , 0, 6, 47, SigIeP2PNoticeOfAbsence, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PNOTICEOFABSENCE, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackNoticeOfAbs(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fNoticeOfAbs *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_NoticeOfAbs, IES_NoticeOfAbs, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Unpacked the NoticeOfAbs:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNoticeOfAbs. */ + + static const tFFDefn FFS_OperatingMode[] = { + { "Category", offsetof(tDot11fOperatingMode, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fOperatingMode, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "OperatingMode", offsetof(tDot11fOperatingMode, OperatingMode), SigFfOperatingMode , DOT11F_FF_OPERATINGMODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_OperatingMode[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackOperatingMode(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fOperatingMode *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_OperatingMode, IES_OperatingMode, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Unpacked the OperatingMode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("OperatingMode:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackOperatingMode. */ + + static const tFFDefn FFS_PresenceReq[] = { + { "Category", offsetof(tDot11fPresenceReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fPresenceReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fPresenceReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fPresenceReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_PresenceReq[] = { + {offsetof(tDot11fPresenceReq, P2PNoticeOfAbsence), offsetof(tDot11fIEP2PNoticeOfAbsence, present), 0, "P2PNoticeOfAbsence" , 0, 6, 47, SigIeP2PNoticeOfAbsence, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PNOTICEOFABSENCE, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackPresenceReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_PresenceReq, IES_PresenceReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Unpacked the PresenceReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceReq. */ + + static const tFFDefn FFS_PresenceRes[] = { + { "Category", offsetof(tDot11fPresenceRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "P2POUI", offsetof(tDot11fPresenceRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fPresenceRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fPresenceRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_PresenceRes[] = { + {offsetof(tDot11fPresenceRes, P2PPresenceResponse), offsetof(tDot11fIEP2PPresenceResponse, present), 0, "P2PPresenceResponse" , 0, 6, 51, SigIeP2PPresenceResponse, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPRESENCERESPONSE, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackPresenceRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fPresenceRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_PresenceRes, IES_PresenceRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Unpacked the PresenceRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PPresenceResponse:\n")); + if (!pFrm->P2PPresenceResponse.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PPresenceResponse.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PPresenceResponse.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* ) pFrm->P2PPresenceResponse.NoticeOfAbsence.NoADesc, pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceRes. */ + + static const tFFDefn FFS_ProbeRequest[] = { + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProbeRequest[] = { + {offsetof(tDot11fProbeRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fProbeRequest, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fProbeRequest, RequestedInfo), offsetof(tDot11fIERequestedInfo, present), 0, "RequestedInfo" , 0, 2, 257, SigIeRequestedInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_REQUESTEDINFO, 0, }, + {offsetof(tDot11fProbeRequest, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fProbeRequest, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fProbeRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fProbeRequest, WscProbeReq), offsetof(tDot11fIEWscProbeReq, present), 0, "WscProbeReq" , 0, 6, 286, SigIeWscProbeReq, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCPROBEREQ, 0, }, + {offsetof(tDot11fProbeRequest, WFATPC), offsetof(tDot11fIEWFATPC, present), 0, "WFATPC" , 0, 9, 9, SigIeWFATPC, {0, 80, 242, 8, 0}, 5, DOT11F_EID_WFATPC, 0, }, + {offsetof(tDot11fProbeRequest, P2PProbeReq), offsetof(tDot11fIEP2PProbeReq, present), 0, "P2PProbeReq" , 0, 6, 43, SigIeP2PProbeReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROBEREQ, 0, }, + {offsetof(tDot11fProbeRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProbeRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProbeRequest, IES_ProbeRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Unpacked the ProbeRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestedInfo:\n")); + if (!pFrm->RequestedInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_requested_eids: %d.\n"), pFrm->RequestedInfo.num_requested_eids); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->RequestedInfo.requested_eids, pFrm->RequestedInfo.num_requested_eids); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WscProbeReq:\n")); + if (!pFrm->WscProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version:\n")); + if (!pFrm->WscProbeReq.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestType:\n")); + if (!pFrm->WscProbeReq.RequestType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestType.reqType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeReq.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeReq.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeReq.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RFBands:\n")); + if (!pFrm->WscProbeReq.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AssociationState:\n")); + if (!pFrm->WscProbeReq.AssociationState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.AssociationState.state, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigurationError:\n")); + if (!pFrm->WscProbeReq.ConfigurationError.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigurationError.error, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeReq.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeReq.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_name: %d.\n"), pFrm->WscProbeReq.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.Manufacturer.name, pFrm->WscProbeReq.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelName:\n")); + if (!pFrm->WscProbeReq.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelName.text, pFrm->WscProbeReq.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeReq.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelNumber.text, pFrm->WscProbeReq.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeReq.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.DeviceName.text, pFrm->WscProbeReq.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeReq.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version2:\n")); + if (!pFrm->WscProbeReq.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeReq.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.RequestToEnroll.req, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestDeviceType:\n")); + if (!pFrm->WscProbeReq.RequestDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.sub_category, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WFATPC:\n")); + if (!pFrm->WFATPC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.txPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.linkMargin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PProbeReq:\n")); + if (!pFrm->P2PProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PProbeReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ListenChannel:\n")); + if (!pFrm->P2PProbeReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PProbeReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.channel, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeRequest. */ + + static const tFFDefn FFS_ProbeResponse[] = { + { "TimeStamp", offsetof(tDot11fProbeResponse, TimeStamp), SigFfTimeStamp , DOT11F_FF_TIMESTAMP_LEN, }, + { "BeaconInterval", offsetof(tDot11fProbeResponse, BeaconInterval), SigFfBeaconInterval , DOT11F_FF_BEACONINTERVAL_LEN, }, + { "Capabilities", offsetof(tDot11fProbeResponse, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProbeResponse[] = { + {offsetof(tDot11fProbeResponse, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fProbeResponse, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fProbeResponse, FHParamSet), offsetof(tDot11fIEFHParamSet, present), 0, "FHParamSet" , 0, 7, 7, SigIeFHParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMSET, 0, }, + {offsetof(tDot11fProbeResponse, DSParams), offsetof(tDot11fIEDSParams, present), 0, "DSParams" , 0, 3, 3, SigIeDSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_DSPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, CFParams), offsetof(tDot11fIECFParams, present), 0, "CFParams" , 0, 8, 8, SigIeCFParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CFPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, IBSSParams), offsetof(tDot11fIEIBSSParams, present), 0, "IBSSParams" , 0, 4, 4, SigIeIBSSParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_IBSSPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fProbeResponse, FHParams), offsetof(tDot11fIEFHParams, present), 0, "FHParams" , 0, 4, 4, SigIeFHParams, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, FHPattTable), offsetof(tDot11fIEFHPattTable, present), 0, "FHPattTable" , 0, 6, 257, SigIeFHPattTable, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FHPATTTABLE, 0, }, + {offsetof(tDot11fProbeResponse, PowerConstraints), offsetof(tDot11fIEPowerConstraints, present), 0, "PowerConstraints" , 0, 3, 3, SigIePowerConstraints, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCONSTRAINTS, 0, }, + {offsetof(tDot11fProbeResponse, ChanSwitchAnn), offsetof(tDot11fIEChanSwitchAnn, present), 0, "ChanSwitchAnn" , 0, 5, 5, SigIeChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_CHANSWITCHANN, 0, }, + {offsetof(tDot11fProbeResponse, Quiet), offsetof(tDot11fIEQuiet, present), 0, "Quiet" , 0, 8, 8, SigIeQuiet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QUIET, 0, }, + {offsetof(tDot11fProbeResponse, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 0, }, + {offsetof(tDot11fProbeResponse, ERPInfo), offsetof(tDot11fIEERPInfo, present), 0, "ERPInfo" , 0, 3, 3, SigIeERPInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_ERPINFO, 0, }, + {offsetof(tDot11fProbeResponse, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fProbeResponse, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fProbeResponse, QBSSLoad), offsetof(tDot11fIEQBSSLoad, present), 0, "QBSSLoad" , 0, 7, 7, SigIeQBSSLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QBSSLOAD, 0, }, + {offsetof(tDot11fProbeResponse, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fProbeResponse, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fProbeResponse, APChannelReport), offsetof(tDot11fIEAPChannelReport, present), 0, "APChannelReport" , 0, 3, 53, SigIeAPChannelReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_APCHANNELREPORT, 0, }, + {offsetof(tDot11fProbeResponse, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fProbeResponse, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fProbeResponse, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fProbeResponse, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fProbeResponse, ExtChanSwitchAnn), offsetof(tDot11fIEExtChanSwitchAnn, present), 0, "ExtChanSwitchAnn" , 0, 3, 3, SigIeExtChanSwitchAnn, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCHANSWITCHANN, 0, }, + {offsetof(tDot11fProbeResponse, WMMInfoAp), offsetof(tDot11fIEWMMInfoAp, present), 0, "WMMInfoAp" , 0, 9, 9, SigIeWMMInfoAp, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOAP, 0, }, + {offsetof(tDot11fProbeResponse, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fProbeResponse, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fProbeResponse, WAPI), offsetof(tDot11fIEWAPI, present), 0, "WAPI" , 0, 14, 112, SigIeWAPI, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPI, 0, }, + {offsetof(tDot11fProbeResponse, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fProbeResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fProbeResponse, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fProbeResponse, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fProbeResponse, WscProbeRes), offsetof(tDot11fIEWscProbeRes, present), 0, "WscProbeRes" , 0, 6, 319, SigIeWscProbeRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCPROBERES, 0, }, + {offsetof(tDot11fProbeResponse, P2PProbeRes), offsetof(tDot11fIEP2PProbeRes, present), 0, "P2PProbeRes" , 0, 6, 1141, SigIeP2PProbeRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROBERES, 0, }, + {offsetof(tDot11fProbeResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fProbeResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fProbeResponse, VHTExtBssLoad), offsetof(tDot11fIEVHTExtBssLoad, present), 0, "VHTExtBssLoad" , 0, 7, 7, SigIeVHTExtBssLoad, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTEXTBSSLOAD, 0, }, + {offsetof(tDot11fProbeResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fProbeResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fProbeResponse, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProbeResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProbeResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProbeResponse, IES_ProbeResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Unpacked the ProbeResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WscProbeRes:\n")); + if (!pFrm->WscProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->WscProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPSState:\n")); + if (!pFrm->WscProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APSetupLocked:\n")); + if (!pFrm->WscProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->WscProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.Manufacturer.name, pFrm->WscProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelName:\n")); + if (!pFrm->WscProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelName.text, pFrm->WscProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelNumber.text, pFrm->WscProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SerialNumber:\n")); + if (!pFrm->WscProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.SerialNumber.text, pFrm->WscProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.DeviceName.text, pFrm->WscProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RFBands:\n")); + if (!pFrm->WscProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PProbeRes:\n")); + if (!pFrm->P2PProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_NoADesc: %d.\n"), pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeResponse. */ + + static const tFFDefn FFS_ProvisionDiscoveryReq[] = { + { "Category", offsetof(tDot11fProvisionDiscoveryReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fProvisionDiscoveryReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fProvisionDiscoveryReq, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fProvisionDiscoveryReq, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fProvisionDiscoveryReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProvisionDiscoveryReq[] = { + {offsetof(tDot11fProvisionDiscoveryReq, P2PProvisionDiscoveryReq), offsetof(tDot11fIEP2PProvisionDiscoveryReq, present), 0, "P2PProvisionDiscoveryReq" , 0, 6, 107, SigIeP2PProvisionDiscoveryReq, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PPROVISIONDISCOVERYREQ, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProvisionDiscoveryReq, IES_ProvisionDiscoveryReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Unpacked the ProvisionDiscoveryReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PProvisionDiscoveryReq:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_text: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PGroupId.ssid, pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryReq. */ + + static const tFFDefn FFS_ProvisionDiscoveryRes[] = { + { "Category", offsetof(tDot11fProvisionDiscoveryRes, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fProvisionDiscoveryRes, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "P2POUI", offsetof(tDot11fProvisionDiscoveryRes, P2POUI), SigFfP2POUI , DOT11F_FF_P2POUI_LEN, }, + { "P2POUISubType", offsetof(tDot11fProvisionDiscoveryRes, P2POUISubType), SigFfP2POUISubType , DOT11F_FF_P2POUISUBTYPE_LEN, }, + { "DialogToken", offsetof(tDot11fProvisionDiscoveryRes, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ProvisionDiscoveryRes[] = { + {offsetof(tDot11fProvisionDiscoveryRes, P2PWSCProvisionDiscoveryRes), offsetof(tDot11fIEP2PWSCProvisionDiscoveryRes, present), 0, "P2PWSCProvisionDiscoveryRes" , 0, 6, 12, SigIeP2PWSCProvisionDiscoveryRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_P2PWSCPROVISIONDISCOVERYRES, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fProvisionDiscoveryRes *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ProvisionDiscoveryRes, IES_ProvisionDiscoveryRes, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Unpacked the ProvisionDiscoveryRes:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2PWSCProvisionDiscoveryRes:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("ConfigMethods:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.methods, 2); + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryRes. */ + + static const tFFDefn FFS_QosMapConfigure[] = { + { "Category", offsetof(tDot11fQosMapConfigure, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fQosMapConfigure, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_QosMapConfigure[] = { + {offsetof(tDot11fQosMapConfigure, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackQosMapConfigure(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fQosMapConfigure *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_QosMapConfigure, IES_QosMapConfigure, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Unpacked the QosMapConfigure:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackQosMapConfigure. */ + + static const tFFDefn FFS_RMC[] = { + { "Category", offsetof(tDot11fRMC, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "RMCOUI", offsetof(tDot11fRMC, RMCOUI), SigFfRMCOUI , DOT11F_FF_RMCOUI_LEN, }, + { "MagicCode", offsetof(tDot11fRMC, MagicCode), SigFfMagicCode , DOT11F_FF_MAGICCODE_LEN, }, + { "RMCVersion", offsetof(tDot11fRMC, RMCVersion), SigFfRMCVersion , DOT11F_FF_RMCVERSION_LEN, }, + { "Action", offsetof(tDot11fRMC, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "RMCDialogToken", offsetof(tDot11fRMC, RMCDialogToken), SigFfRMCDialogToken , DOT11F_FF_RMCDIALOGTOKEN_LEN, }, + { "Ruler", offsetof(tDot11fRMC, Ruler), SigFfRuler , DOT11F_FF_RULER_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RMC[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackRMC(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRMC *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_RMC, IES_RMC, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Unpacked the RMC:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCOUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCOUI.oui, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("MagicCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->MagicCode.magic, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCVersion:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCVersion.version, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCDialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCDialogToken.token, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Ruler:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Ruler.mac, 6); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRMC. */ + + static const tFFDefn FFS_RadioMeasurementReport[] = { + { "Category", offsetof(tDot11fRadioMeasurementReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fRadioMeasurementReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fRadioMeasurementReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RadioMeasurementReport[] = { + {offsetof(tDot11fRadioMeasurementReport, MeasurementReport), offsetof(tDot11fIEMeasurementReport, present), offsetof(tDot11fRadioMeasurementReport, num_MeasurementReport), "MeasurementReport" , 4, 5, 31, SigIeMeasurementReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackRadioMeasurementReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_RadioMeasurementReport, IES_RadioMeasurementReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Unpacked the RadioMeasurementReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("MeasurementReport[%d]:\n"), i); + if (!pFrm->MeasurementReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport[i].late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport[i].incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport[i].refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].type, 1); + switch (pFrm->MeasurementReport[i].type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport[i].report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport[i].report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport[i].report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.parent_TSF, 4); + break; + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementReport. */ + + static const tFFDefn FFS_RadioMeasurementRequest[] = { + { "Category", offsetof(tDot11fRadioMeasurementRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fRadioMeasurementRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fRadioMeasurementRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "NumOfRepetitions", offsetof(tDot11fRadioMeasurementRequest, NumOfRepetitions), SigFfNumOfRepetitions , DOT11F_FF_NUMOFREPETITIONS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_RadioMeasurementRequest[] = { + {offsetof(tDot11fRadioMeasurementRequest, MeasurementRequest), offsetof(tDot11fIEMeasurementRequest, present), offsetof(tDot11fRadioMeasurementRequest, num_MeasurementRequest), "MeasurementRequest" , 2, 16, 18, SigIeMeasurementRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MEASUREMENTREQUEST, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackRadioMeasurementRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fRadioMeasurementRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Unpacked the RadioMeasurementRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("NumOfRepetitions:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->NumOfRepetitions.repetitions, 2); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementRequest. */ + + static const tFFDefn FFS_ReAssocRequest[] = { + { "Capabilities", offsetof(tDot11fReAssocRequest, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "ListenInterval", offsetof(tDot11fReAssocRequest, ListenInterval), SigFfListenInterval , DOT11F_FF_LISTENINTERVAL_LEN, }, + { "CurrentAPAddress", offsetof(tDot11fReAssocRequest, CurrentAPAddress), SigFfCurrentAPAddress , DOT11F_FF_CURRENTAPADDRESS_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ReAssocRequest[] = { + {offsetof(tDot11fReAssocRequest, SSID), offsetof(tDot11fIESSID, present), 0, "SSID" , 0, 2, 34, SigIeSSID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SSID, 1, }, + {offsetof(tDot11fReAssocRequest, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fReAssocRequest, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fReAssocRequest, PowerCaps), offsetof(tDot11fIEPowerCaps, present), 0, "PowerCaps" , 0, 4, 4, SigIePowerCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_POWERCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fReAssocRequest, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fReAssocRequest, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fReAssocRequest, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fReAssocRequest, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fReAssocRequest, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fReAssocRequest, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {offsetof(tDot11fReAssocRequest, WPAOpaque), offsetof(tDot11fIEWPAOpaque, present), 0, "WPAOpaque" , 0, 8, 255, SigIeWPAOpaque, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPAOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, WMMCaps), offsetof(tDot11fIEWMMCaps, present), 0, "WMMCaps" , 0, 9, 9, SigIeWMMCaps, {0, 80, 242, 2, 5}, 5, DOT11F_EID_WMMCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fReAssocRequest, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fReAssocRequest, WscIEOpaque), offsetof(tDot11fIEWscIEOpaque, present), 0, "WscIEOpaque" , 0, 8, 255, SigIeWscIEOpaque, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCIEOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, WAPIOpaque), offsetof(tDot11fIEWAPIOpaque, present), 0, "WAPIOpaque" , 0, 8, 255, SigIeWAPIOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_WAPIOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fReAssocRequest, ESEVersion), offsetof(tDot11fIEESEVersion, present), 0, "ESEVersion" , 0, 7, 7, SigIeESEVersion, {0, 64, 150, 3, 0}, 4, DOT11F_EID_ESEVERSION, 0, }, + {offsetof(tDot11fReAssocRequest, ESECckmOpaque), offsetof(tDot11fIEESECckmOpaque, present), 0, "ESECckmOpaque" , 0, 12, 26, SigIeESECckmOpaque, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESECCKMOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), offsetof(tDot11fReAssocRequest, num_WMMTSPEC), "WMMTSPEC" , 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fReAssocRequest, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {offsetof(tDot11fReAssocRequest, P2PIEOpaque), offsetof(tDot11fIEP2PIEOpaque, present), 0, "P2PIEOpaque" , 0, 8, 255, SigIeP2PIEOpaque, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PIEOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, WFDIEOpaque), offsetof(tDot11fIEWFDIEOpaque, present), 0, "WFDIEOpaque" , 0, 8, 255, SigIeWFDIEOpaque, {80, 111, 154, 10, 0}, 4, DOT11F_EID_WFDIEOPAQUE, 0, }, + {offsetof(tDot11fReAssocRequest, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fReAssocRequest, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fReAssocRequest, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {offsetof(tDot11fReAssocRequest, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {offsetof(tDot11fReAssocRequest, hs20vendor_ie), offsetof(tDot11fIEhs20vendor_ie, present), 0, "hs20vendor_ie" , 0, 7, 9, SigIehs20vendor_ie, {80, 111, 154, 16, 0}, 4, DOT11F_EID_HS20VENDOR_IE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackReAssocRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ReAssocRequest, IES_ReAssocRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Unpacked the ReAssocRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("CurrentAPAddress:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->CurrentAPAddress.mac, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESECckmOpaque:\n")); + if (!pFrm->ESECckmOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->ESECckmOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESECckmOpaque.data, pFrm->ESECckmOpaque.num_data); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocRequest. */ + + static const tFFDefn FFS_ReAssocResponse[] = { + { "Capabilities", offsetof(tDot11fReAssocResponse, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { "Status", offsetof(tDot11fReAssocResponse, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "AID", offsetof(tDot11fReAssocResponse, AID), SigFfAID , DOT11F_FF_AID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_ReAssocResponse[] = { + {offsetof(tDot11fReAssocResponse, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fReAssocResponse, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fReAssocResponse, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fReAssocResponse, RCPIIE), offsetof(tDot11fIERCPIIE, present), 0, "RCPIIE" , 0, 3, 3, SigIeRCPIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RCPIIE, 0, }, + {offsetof(tDot11fReAssocResponse, RSNIIE), offsetof(tDot11fIERSNIIE, present), 0, "RSNIIE" , 0, 3, 3, SigIeRSNIIE, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNIIE, 0, }, + {offsetof(tDot11fReAssocResponse, RRMEnabledCap), offsetof(tDot11fIERRMEnabledCap, present), 0, "RRMEnabledCap" , 0, 7, 7, SigIeRRMEnabledCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RRMENABLEDCAP, 0, }, + {offsetof(tDot11fReAssocResponse, RSNOpaque), offsetof(tDot11fIERSNOpaque, present), 0, "RSNOpaque" , 0, 8, 255, SigIeRSNOpaque, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSNOPAQUE, 0, }, + {offsetof(tDot11fReAssocResponse, MobilityDomain), offsetof(tDot11fIEMobilityDomain, present), 0, "MobilityDomain" , 0, 5, 5, SigIeMobilityDomain, {0, 0, 0, 0, 0}, 0, DOT11F_EID_MOBILITYDOMAIN, 0, }, + {offsetof(tDot11fReAssocResponse, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fReAssocResponse, RICDataDesc), offsetof(tDot11fIERICDataDesc, present), offsetof(tDot11fReAssocResponse, num_RICDataDesc), "RICDataDesc" , 2, 2, 550, SigIeRICDataDesc, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATADESC, 0, }, + {offsetof(tDot11fReAssocResponse, WPA), offsetof(tDot11fIEWPA, present), 0, "WPA" , 0, 8, 50, SigIeWPA, {0, 80, 242, 1, 0}, 4, DOT11F_EID_WPA, 0, }, + {offsetof(tDot11fReAssocResponse, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fReAssocResponse, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fReAssocResponse, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fReAssocResponse, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fReAssocResponse, ESERadMgmtCap), offsetof(tDot11fIEESERadMgmtCap, present), 0, "ESERadMgmtCap" , 0, 8, 8, SigIeESERadMgmtCap, {0, 64, 150, 1, 0}, 4, DOT11F_EID_ESERADMGMTCAP, 0, }, + {offsetof(tDot11fReAssocResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {offsetof(tDot11fReAssocResponse, ESETxmitPower), offsetof(tDot11fIEESETxmitPower, present), 0, "ESETxmitPower" , 0, 8, 8, SigIeESETxmitPower, {0, 64, 150, 0, 0}, 4, DOT11F_EID_ESETXMITPOWER, 0, }, + {offsetof(tDot11fReAssocResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), offsetof(tDot11fReAssocResponse, num_WMMTSPEC), "WMMTSPEC" , 4, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fReAssocResponse, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {offsetof(tDot11fReAssocResponse, Airgo), offsetof(tDot11fIEAirgo, present), 0, "Airgo" , 0, 5, 232, SigIeAirgo, {0, 10, 245, 0, 0}, 3, DOT11F_EID_AIRGO, 0, }, + {offsetof(tDot11fReAssocResponse, WscReassocRes), offsetof(tDot11fIEWscReassocRes, present), 0, "WscReassocRes" , 0, 6, 37, SigIeWscReassocRes, {0, 80, 242, 4, 0}, 4, DOT11F_EID_WSCREASSOCRES, 0, }, + {offsetof(tDot11fReAssocResponse, P2PAssocRes), offsetof(tDot11fIEP2PAssocRes, present), 0, "P2PAssocRes" , 0, 6, 17, SigIeP2PAssocRes, {80, 111, 154, 9, 0}, 4, DOT11F_EID_P2PASSOCRES, 0, }, + {offsetof(tDot11fReAssocResponse, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fReAssocResponse, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fReAssocResponse, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fReAssocResponse, OBSSScanParameters), offsetof(tDot11fIEOBSSScanParameters, present), 0, "OBSSScanParameters" , 0, 16, 16, SigIeOBSSScanParameters, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OBSSSCANPARAMETERS, 0, }, + {offsetof(tDot11fReAssocResponse, QosMapSet), offsetof(tDot11fIEQosMapSet, present), 0, "QosMapSet" , 0, 2, 62, SigIeQosMapSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSMAPSET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackReAssocResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fReAssocResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_ReAssocResponse, IES_ReAssocResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Unpacked the ReAssocResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WscReassocRes:\n")); + if (!pFrm->WscReassocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscReassocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscReassocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscReassocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscReassocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscReassocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocResponse. */ + + static const tFFDefn FFS_SMPowerSave[] = { + { "Category", offsetof(tDot11fSMPowerSave, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fSMPowerSave, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "SMPowerModeSet", offsetof(tDot11fSMPowerSave, SMPowerModeSet), SigFfSMPowerModeSet , DOT11F_FF_SMPOWERMODESET_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_SMPowerSave[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackSMPowerSave(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSMPowerSave *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_SMPowerSave, IES_SMPowerSave, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Unpacked the SMPowerSave:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("SMPowerModeSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("PowerSave_En (1): %d\n"), pFrm->SMPowerModeSet.PowerSave_En); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Mode (1): %d\n"), pFrm->SMPowerModeSet.Mode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("reserved (6): %d\n"), pFrm->SMPowerModeSet.reserved); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSMPowerSave. */ + + static const tFFDefn FFS_SaQueryReq[] = { + { "Category", offsetof(tDot11fSaQueryReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fSaQueryReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "TransactionId", offsetof(tDot11fSaQueryReq, TransactionId), SigFfTransactionId , DOT11F_FF_TRANSACTIONID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_SaQueryReq[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackSaQueryReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_SaQueryReq, IES_SaQueryReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Unpacked the SaQueryReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryReq. */ + + static const tFFDefn FFS_SaQueryRsp[] = { + { "Category", offsetof(tDot11fSaQueryRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fSaQueryRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "TransactionId", offsetof(tDot11fSaQueryRsp, TransactionId), SigFfTransactionId , DOT11F_FF_TRANSACTIONID_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_SaQueryRsp[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackSaQueryRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fSaQueryRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_SaQueryRsp, IES_SaQueryRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Unpacked the SaQueryRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryRsp. */ + + static const tFFDefn FFS_TDLSDisReq[] = { + { "Category", offsetof(tDot11fTDLSDisReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSDisReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSDisReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSDisReq[] = { + {offsetof(tDot11fTDLSDisReq, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSDisReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSDisReq, IES_TDLSDisReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Unpacked the TDLSDisReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisReq. */ + + static const tFFDefn FFS_TDLSDisRsp[] = { + { "Category", offsetof(tDot11fTDLSDisRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSDisRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSDisRsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Capabilities", offsetof(tDot11fTDLSDisRsp, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSDisRsp[] = { + {offsetof(tDot11fTDLSDisRsp, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fTDLSDisRsp, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fTDLSDisRsp, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fTDLSDisRsp, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, + {offsetof(tDot11fTDLSDisRsp, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSDisRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fTDLSDisRsp, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSDisRsp, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSDisRsp, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, }, + {offsetof(tDot11fTDLSDisRsp, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fTDLSDisRsp, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSDisRsp, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {offsetof(tDot11fTDLSDisRsp, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSDisRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSDisRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSDisRsp, IES_TDLSDisRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Unpacked the TDLSDisRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisRsp. */ + + static const tFFDefn FFS_TDLSPeerTrafficInd[] = { + { "Category", offsetof(tDot11fTDLSPeerTrafficInd, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSPeerTrafficInd, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSPeerTrafficInd, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSPeerTrafficInd[] = { + {offsetof(tDot11fTDLSPeerTrafficInd, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {offsetof(tDot11fTDLSPeerTrafficInd, PTIControl), offsetof(tDot11fIEPTIControl, present), 0, "PTIControl" , 0, 5, 5, SigIePTIControl, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PTICONTROL, 0, }, + {offsetof(tDot11fTDLSPeerTrafficInd, PUBufferStatus), offsetof(tDot11fIEPUBufferStatus, present), 0, "PUBufferStatus" , 0, 3, 3, SigIePUBufferStatus, {0, 0, 0, 0, 0}, 0, DOT11F_EID_PUBUFFERSTATUS, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficInd *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Unpacked the TDLSPeerTrafficInd:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PTIControl:\n")); + if (!pFrm->PTIControl.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.tid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.sequence_control, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PUBufferStatus:\n")); + if (!pFrm->PUBufferStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_bk_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_bk_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_be_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_be_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vi_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vi_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vo_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vo_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("reserved (4): %d\n"), pFrm->PUBufferStatus.reserved); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficInd. */ + + static const tFFDefn FFS_TDLSPeerTrafficRsp[] = { + { "Category", offsetof(tDot11fTDLSPeerTrafficRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSPeerTrafficRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSPeerTrafficRsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSPeerTrafficRsp[] = { + {offsetof(tDot11fTDLSPeerTrafficRsp, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSPeerTrafficRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Unpacked the TDLSPeerTrafficRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficRsp. */ + + static const tFFDefn FFS_TDLSSetupCnf[] = { + { "Category", offsetof(tDot11fTDLSSetupCnf, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSSetupCnf, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "Status", offsetof(tDot11fTDLSSetupCnf, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSSetupCnf, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSSetupCnf[] = { + {offsetof(tDot11fTDLSSetupCnf, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSSetupCnf, EDCAParamSet), offsetof(tDot11fIEEDCAParamSet, present), 0, "EDCAParamSet" , 0, 20, 20, SigIeEDCAParamSet, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EDCAPARAMSET, 0, }, + {offsetof(tDot11fTDLSSetupCnf, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSSetupCnf, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSSetupCnf, HTInfo), offsetof(tDot11fIEHTInfo, present), 0, "HTInfo" , 0, 24, 56, SigIeHTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTINFO, 0, }, + {offsetof(tDot11fTDLSSetupCnf, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSSetupCnf, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 0, }, + {offsetof(tDot11fTDLSSetupCnf, WMMParams), offsetof(tDot11fIEWMMParams, present), 0, "WMMParams" , 0, 26, 26, SigIeWMMParams, {0, 80, 242, 2, 1}, 5, DOT11F_EID_WMMPARAMS, 0, }, + {offsetof(tDot11fTDLSSetupCnf, VHTOperation), offsetof(tDot11fIEVHTOperation, present), 0, "VHTOperation" , 0, 7, 7, SigIeVHTOperation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTOPERATION, 0, }, + {offsetof(tDot11fTDLSSetupCnf, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSSetupCnf(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupCnf *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSSetupCnf, IES_TDLSSetupCnf, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Unpacked the TDLSSetupCnf:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupCnf. */ + + static const tFFDefn FFS_TDLSSetupReq[] = { + { "Category", offsetof(tDot11fTDLSSetupReq, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSSetupReq, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSSetupReq, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Capabilities", offsetof(tDot11fTDLSSetupReq, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSSetupReq[] = { + {offsetof(tDot11fTDLSSetupReq, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 1, }, + {offsetof(tDot11fTDLSSetupReq, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fTDLSSetupReq, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fTDLSSetupReq, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fTDLSSetupReq, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSSetupReq, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fTDLSSetupReq, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, + {offsetof(tDot11fTDLSSetupReq, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fTDLSSetupReq, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSSetupReq, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSSetupReq, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, }, + {offsetof(tDot11fTDLSSetupReq, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fTDLSSetupReq, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSSetupReq, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {offsetof(tDot11fTDLSSetupReq, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fTDLSSetupReq, AID), offsetof(tDot11fIEAID, present), 0, "AID" , 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, }, + {offsetof(tDot11fTDLSSetupReq, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSSetupReq(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupReq *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSSetupReq, IES_TDLSSetupReq, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Unpacked the TDLSSetupReq:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupReq. */ + + static const tFFDefn FFS_TDLSSetupRsp[] = { + { "Category", offsetof(tDot11fTDLSSetupRsp, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSSetupRsp, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "Status", offsetof(tDot11fTDLSSetupRsp, Status), SigFfStatus , DOT11F_FF_STATUS_LEN, }, + { "DialogToken", offsetof(tDot11fTDLSSetupRsp, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "Capabilities", offsetof(tDot11fTDLSSetupRsp, Capabilities), SigFfCapabilities , DOT11F_FF_CAPABILITIES_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSSetupRsp[] = { + {offsetof(tDot11fTDLSSetupRsp, SuppRates), offsetof(tDot11fIESuppRates, present), 0, "SuppRates" , 0, 2, 14, SigIeSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPRATES, 0, }, + {offsetof(tDot11fTDLSSetupRsp, Country), offsetof(tDot11fIECountry, present), 0, "Country" , 0, 5, 257, SigIeCountry, {0, 0, 0, 0, 0}, 0, DOT11F_EID_COUNTRY, 0, }, + {offsetof(tDot11fTDLSSetupRsp, ExtSuppRates), offsetof(tDot11fIEExtSuppRates, present), 0, "ExtSuppRates" , 0, 3, 14, SigIeExtSuppRates, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTSUPPRATES, 0, }, + {offsetof(tDot11fTDLSSetupRsp, SuppChannels), offsetof(tDot11fIESuppChannels, present), 0, "SuppChannels" , 0, 4, 98, SigIeSuppChannels, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPCHANNELS, 0, }, + {offsetof(tDot11fTDLSSetupRsp, RSN), offsetof(tDot11fIERSN, present), 0, "RSN" , 0, 8, 116, SigIeRSN, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RSN, 0, }, + {offsetof(tDot11fTDLSSetupRsp, ExtCap), offsetof(tDot11fIEExtCap, present), 0, "ExtCap" , 0, 3, 11, SigIeExtCap, {0, 0, 0, 0, 0}, 0, DOT11F_EID_EXTCAP, 0, }, + {offsetof(tDot11fTDLSSetupRsp, SuppOperatingClasses), offsetof(tDot11fIESuppOperatingClasses, present), 0, "SuppOperatingClasses" , 0, 3, 34, SigIeSuppOperatingClasses, {0, 0, 0, 0, 0}, 0, DOT11F_EID_SUPPOPERATINGCLASSES, 0, }, + {offsetof(tDot11fTDLSSetupRsp, QOSCapsStation), offsetof(tDot11fIEQOSCapsStation, present), 0, "QOSCapsStation" , 0, 3, 3, SigIeQOSCapsStation, {0, 0, 0, 0, 0}, 0, DOT11F_EID_QOSCAPSSTATION, 0, }, + {offsetof(tDot11fTDLSSetupRsp, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSSetupRsp, TimeoutInterval), offsetof(tDot11fIETimeoutInterval, present), 0, "TimeoutInterval" , 0, 7, 7, SigIeTimeoutInterval, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TIMEOUTINTERVAL, 0, }, + {offsetof(tDot11fTDLSSetupRsp, RICData), offsetof(tDot11fIERICData, present), 0, "RICData" , 0, 6, 6, SigIeRICData, {0, 0, 0, 0, 0}, 0, DOT11F_EID_RICDATA, 0, }, + {offsetof(tDot11fTDLSSetupRsp, HTCaps), offsetof(tDot11fIEHTCaps, present), 0, "HTCaps" , 0, 28, 60, SigIeHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HTCAPS, 0, }, + {offsetof(tDot11fTDLSSetupRsp, HT2040BSSCoexistence), offsetof(tDot11fIEHT2040BSSCoexistence, present), 0, "HT2040BSSCoexistence" , 0, 3, 3, SigIeHT2040BSSCoexistence, {0, 0, 0, 0, 0}, 0, DOT11F_EID_HT2040BSSCOEXISTENCE, 0, }, + {offsetof(tDot11fTDLSSetupRsp, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 0, }, + {offsetof(tDot11fTDLSSetupRsp, WMMInfoStation), offsetof(tDot11fIEWMMInfoStation, present), 0, "WMMInfoStation" , 0, 9, 9, SigIeWMMInfoStation, {0, 80, 242, 2, 0}, 5, DOT11F_EID_WMMINFOSTATION, 0, }, + {offsetof(tDot11fTDLSSetupRsp, AID), offsetof(tDot11fIEAID, present), 0, "AID" , 0, 4, 4, SigIeAID, {0, 0, 0, 0, 0}, 0, DOT11F_EID_AID, 0, }, + {offsetof(tDot11fTDLSSetupRsp, VHTCaps), offsetof(tDot11fIEVHTCaps, present), 0, "VHTCaps" , 0, 14, 14, SigIeVHTCaps, {0, 0, 0, 0, 0}, 0, DOT11F_EID_VHTCAPS, 0, }, + {offsetof(tDot11fTDLSSetupRsp, OperatingMode), offsetof(tDot11fIEOperatingMode, present), 0, "OperatingMode" , 0, 3, 3, SigIeOperatingMode, {0, 0, 0, 0, 0}, 0, DOT11F_EID_OPERATINGMODE, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSSetupRsp(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSSetupRsp *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSSetupRsp, IES_TDLSSetupRsp, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Unpacked the TDLSSetupRsp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupRsp. */ + + static const tFFDefn FFS_TDLSTeardown[] = { + { "Category", offsetof(tDot11fTDLSTeardown, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTDLSTeardown, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "Reason", offsetof(tDot11fTDLSTeardown, Reason), SigFfReason , DOT11F_FF_REASON_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TDLSTeardown[] = { + {offsetof(tDot11fTDLSTeardown, FTInfo), offsetof(tDot11fIEFTInfo, present), 0, "FTInfo" , 0, 84, 222, SigIeFTInfo, {0, 0, 0, 0, 0}, 0, DOT11F_EID_FTINFO, 0, }, + {offsetof(tDot11fTDLSTeardown, LinkIdentifier), offsetof(tDot11fIELinkIdentifier, present), 0, "LinkIdentifier" , 0, 20, 20, SigIeLinkIdentifier, {0, 0, 0, 0, 0}, 0, DOT11F_EID_LINKIDENTIFIER, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTDLSTeardown(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTDLSTeardown *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TDLSTeardown, IES_TDLSTeardown, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Unpacked the TDLSTeardown:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSTeardown. */ + + static const tFFDefn FFS_TPCReport[] = { + { "Category", offsetof(tDot11fTPCReport, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTPCReport, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTPCReport, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TPCReport[] = { + {offsetof(tDot11fTPCReport, TPCReport), offsetof(tDot11fIETPCReport, present), 0, "TPCReport" , 0, 4, 4, SigIeTPCReport, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREPORT, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTPCReport(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCReport *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TPCReport, IES_TPCReport, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Unpacked the TPCReport:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCReport. */ + + static const tFFDefn FFS_TPCRequest[] = { + { "Category", offsetof(tDot11fTPCRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fTPCRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fTPCRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_TPCRequest[] = { + {offsetof(tDot11fTPCRequest, TPCRequest), offsetof(tDot11fIETPCRequest, present), 0, "TPCRequest" , 0, 2, 2, SigIeTPCRequest, {0, 0, 0, 0, 0}, 0, DOT11F_EID_TPCREQUEST, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackTPCRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fTPCRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_TPCRequest, IES_TPCRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Unpacked the TPCRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("TPCRequest:\n")); + if (!pFrm->TPCRequest.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Not present.\n")); + } + else + { + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCRequest. */ + + static const tFFDefn FFS_VHTGidManagementActionFrame[] = { + { "Category", offsetof(tDot11fVHTGidManagementActionFrame, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fVHTGidManagementActionFrame, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "VhtMembershipStatusArray", offsetof(tDot11fVHTGidManagementActionFrame, VhtMembershipStatusArray), SigFfVhtMembershipStatusArray , DOT11F_FF_VHTMEMBERSHIPSTATUSARRAY_LEN, }, + { "VhtUserPositionArray", offsetof(tDot11fVHTGidManagementActionFrame, VhtUserPositionArray), SigFfVhtUserPositionArray , DOT11F_FF_VHTUSERPOSITIONARRAY_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_VHTGidManagementActionFrame[] = { + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fVHTGidManagementActionFrame *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Unpacked the VHTGidManagementActionFrame:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtMembershipStatusArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtMembershipStatusArray.membershipStatusArray, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtUserPositionArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtUserPositionArray.userPositionArray, 16); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackVHTGidManagementActionFrame. */ + + static const tFFDefn FFS_WMMAddTSRequest[] = { + { "Category", offsetof(tDot11fWMMAddTSRequest, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fWMMAddTSRequest, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fWMMAddTSRequest, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "StatusCode", offsetof(tDot11fWMMAddTSRequest, StatusCode), SigFfStatusCode , DOT11F_FF_STATUSCODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_WMMAddTSRequest[] = { + {offsetof(tDot11fWMMAddTSRequest, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 1, }, + {offsetof(tDot11fWMMAddTSRequest, ESETrafStrmRateSet), offsetof(tDot11fIEESETrafStrmRateSet, present), 0, "ESETrafStrmRateSet" , 0, 7, 15, SigIeESETrafStrmRateSet, {0, 64, 150, 8, 0}, 4, DOT11F_EID_ESETRAFSTRMRATESET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackWMMAddTSRequest(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSRequest *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_WMMAddTSRequest, IES_WMMAddTSRequest, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Unpacked the WMMAddTSRequest:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSRequest. */ + + static const tFFDefn FFS_WMMAddTSResponse[] = { + { "Category", offsetof(tDot11fWMMAddTSResponse, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fWMMAddTSResponse, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fWMMAddTSResponse, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "StatusCode", offsetof(tDot11fWMMAddTSResponse, StatusCode), SigFfStatusCode , DOT11F_FF_STATUSCODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_WMMAddTSResponse[] = { + {offsetof(tDot11fWMMAddTSResponse, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 0, }, + {offsetof(tDot11fWMMAddTSResponse, ESETrafStrmMet), offsetof(tDot11fIEESETrafStrmMet, present), 0, "ESETrafStrmMet" , 0, 10, 10, SigIeESETrafStrmMet, {0, 64, 150, 7, 0}, 4, DOT11F_EID_ESETRAFSTRMMET, 0, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackWMMAddTSResponse(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMAddTSResponse *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_WMMAddTSResponse, IES_WMMAddTSResponse, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Unpacked the WMMAddTSResponse:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSResponse. */ + + static const tFFDefn FFS_WMMDelTS[] = { + { "Category", offsetof(tDot11fWMMDelTS, Category), SigFfCategory , DOT11F_FF_CATEGORY_LEN, }, + { "Action", offsetof(tDot11fWMMDelTS, Action), SigFfAction , DOT11F_FF_ACTION_LEN, }, + { "DialogToken", offsetof(tDot11fWMMDelTS, DialogToken), SigFfDialogToken , DOT11F_FF_DIALOGTOKEN_LEN, }, + { "StatusCode", offsetof(tDot11fWMMDelTS, StatusCode), SigFfStatusCode , DOT11F_FF_STATUSCODE_LEN, }, + { NULL, 0, 0, 0,}, + }; + + static const tIEDefn IES_WMMDelTS[] = { + {offsetof(tDot11fWMMDelTS, WMMTSPEC), offsetof(tDot11fIEWMMTSPEC, present), 0, "WMMTSPEC" , 0, 63, 63, SigIeWMMTSPEC, {0, 80, 242, 2, 2}, 5, DOT11F_EID_WMMTSPEC, 1, }, + {0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, }, }; + +tANI_U32 dot11fUnpackWMMDelTS(tpAniSirGlobal pCtx, tANI_U8 *pBuf, tANI_U32 nBuf, tDot11fWMMDelTS *pFrm) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + status = UnpackCore(pCtx, pBuf, nBuf, FFS_WMMDelTS, IES_WMMDelTS, ( tANI_U8* )pFrm, sizeof(*pFrm)); + + (void)i; +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Unpacked the WMMDelTS:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), pBuf, nBuf); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("to:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMDelTS. */ + +static tANI_U32 UnpackCore(tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tFFDefn FFs[], + const tIEDefn IEs[], + tANI_U8 *pFrm, + size_t nFrm) +{ + const tFFDefn *pFf; + const tIEDefn *pIe; + tANI_U8 *pBufRemaining; + tANI_U32 nBufRemaining, status; + tANI_U8 eid, len; + tFRAMES_BOOL *pfFound; + tANI_U32 countOffset = 0; + + DOT11F_PARAMETER_CHECK(pBuf, nBuf, pFrm, nFrm); + (void)nFrm; + + (void)pCtx; + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pIe = &IEs[0]; + while (0xff != pIe->eid) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pIe->offset + + pIe->presenceOffset); + *pfFound = 0U; + if (pIe->countOffset) + { + *( tANI_U16* )(pFrm + pIe->countOffset) = 0U; + } + ++pIe; + } + + pFf = &FFs[0]; + while (pFf->size) + { + if (pFf->size > nBufRemaining) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("Fixed field %s is %d b" + "ytes in size, but there are only %d bytes left i" + "n this frame.\n"), pFf->name, pFf->size, + nBufRemaining); + FRAMES_DBG_BREAK(); + return DOT11F_MISSING_FIXED_FIELD; + } + + switch (pFf->sig) + { + + case SigFfAID: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfAID* )(pFrm + pFf->offset ))->associd)); + break; + case SigFfAction: + dot11fUnpackFfAction(pCtx, pBufRemaining, ( tDot11fFfAction* )(pFrm + pFf->offset )); + break; + case SigFfAddBAParameterSet: + dot11fUnpackFfAddBAParameterSet(pCtx, pBufRemaining, ( tDot11fFfAddBAParameterSet* )(pFrm + pFf->offset )); + break; + case SigFfAuthAlgo: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfAuthAlgo* )(pFrm + pFf->offset ))->algo)); + break; + case SigFfAuthSeqNo: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfAuthSeqNo* )(pFrm + pFf->offset ))->no)); + break; + case SigFfBAStartingSequenceControl: + dot11fUnpackFfBAStartingSequenceControl(pCtx, pBufRemaining, ( tDot11fFfBAStartingSequenceControl* )(pFrm + pFf->offset )); + break; + case SigFfBATimeout: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfBATimeout* )(pFrm + pFf->offset ))->timeout)); + break; + case SigFfBeaconInterval: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfBeaconInterval* )(pFrm + pFf->offset ))->interval)); + break; + case SigFfCapabilities: + dot11fUnpackFfCapabilities(pCtx, pBufRemaining, ( tDot11fFfCapabilities* )(pFrm + pFf->offset )); + break; + case SigFfCategory: + dot11fUnpackFfCategory(pCtx, pBufRemaining, ( tDot11fFfCategory* )(pFrm + pFf->offset )); + break; + case SigFfCurrentAPAddress: + dot11fUnpackFfCurrentAPAddress(pCtx, pBufRemaining, ( tDot11fFfCurrentAPAddress* )(pFrm + pFf->offset )); + break; + case SigFfDelBAParameterSet: + dot11fUnpackFfDelBAParameterSet(pCtx, pBufRemaining, ( tDot11fFfDelBAParameterSet* )(pFrm + pFf->offset )); + break; + case SigFfDialogToken: + dot11fUnpackFfDialogToken(pCtx, pBufRemaining, ( tDot11fFfDialogToken* )(pFrm + pFf->offset )); + break; + case SigFfLinkMargin: + dot11fUnpackFfLinkMargin(pCtx, pBufRemaining, ( tDot11fFfLinkMargin* )(pFrm + pFf->offset )); + break; + case SigFfListenInterval: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfListenInterval* )(pFrm + pFf->offset ))->interval)); + break; + case SigFfMagicCode: + dot11fUnpackFfMagicCode(pCtx, pBufRemaining, ( tDot11fFfMagicCode* )(pFrm + pFf->offset )); + break; + case SigFfMaxTxPower: + dot11fUnpackFfMaxTxPower(pCtx, pBufRemaining, ( tDot11fFfMaxTxPower* )(pFrm + pFf->offset )); + break; + case SigFfNumOfRepetitions: + dot11fUnpackFfNumOfRepetitions(pCtx, pBufRemaining, ( tDot11fFfNumOfRepetitions* )(pFrm + pFf->offset )); + break; + case SigFfOperatingMode: + dot11fUnpackFfOperatingMode(pCtx, pBufRemaining, ( tDot11fFfOperatingMode* )(pFrm + pFf->offset )); + break; + case SigFfP2POUI: + dot11fUnpackFfP2POUI(pCtx, pBufRemaining, ( tDot11fFfP2POUI* )(pFrm + pFf->offset )); + break; + case SigFfP2POUISubType: + dot11fUnpackFfP2POUISubType(pCtx, pBufRemaining, ( tDot11fFfP2POUISubType* )(pFrm + pFf->offset )); + break; + case SigFfRCPI: + dot11fUnpackFfRCPI(pCtx, pBufRemaining, ( tDot11fFfRCPI* )(pFrm + pFf->offset )); + break; + case SigFfRMCDialogToken: + dot11fUnpackFfRMCDialogToken(pCtx, pBufRemaining, ( tDot11fFfRMCDialogToken* )(pFrm + pFf->offset )); + break; + case SigFfRMCOUI: + dot11fUnpackFfRMCOUI(pCtx, pBufRemaining, ( tDot11fFfRMCOUI* )(pFrm + pFf->offset )); + break; + case SigFfRMCVersion: + dot11fUnpackFfRMCVersion(pCtx, pBufRemaining, ( tDot11fFfRMCVersion* )(pFrm + pFf->offset )); + break; + case SigFfRSNI: + dot11fUnpackFfRSNI(pCtx, pBufRemaining, ( tDot11fFfRSNI* )(pFrm + pFf->offset )); + break; + case SigFfReason: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfReason* )(pFrm + pFf->offset ))->code)); + break; + case SigFfRuler: + dot11fUnpackFfRuler(pCtx, pBufRemaining, ( tDot11fFfRuler* )(pFrm + pFf->offset )); + break; + case SigFfRxAntennaId: + dot11fUnpackFfRxAntennaId(pCtx, pBufRemaining, ( tDot11fFfRxAntennaId* )(pFrm + pFf->offset )); + break; + case SigFfSMPowerModeSet: + dot11fUnpackFfSMPowerModeSet(pCtx, pBufRemaining, ( tDot11fFfSMPowerModeSet* )(pFrm + pFf->offset )); + break; + case SigFfStatus: + dot11fUnpackFfCommonFunc(pCtx, pBufRemaining, (tANI_U16*)&((( tDot11fFfStatus* )(pFrm + pFf->offset ))->status)); + break; + case SigFfStatusCode: + dot11fUnpackFfStatusCode(pCtx, pBufRemaining, ( tDot11fFfStatusCode* )(pFrm + pFf->offset )); + break; + case SigFfTPCEleID: + dot11fUnpackFfTPCEleID(pCtx, pBufRemaining, ( tDot11fFfTPCEleID* )(pFrm + pFf->offset )); + break; + case SigFfTPCEleLen: + dot11fUnpackFfTPCEleLen(pCtx, pBufRemaining, ( tDot11fFfTPCEleLen* )(pFrm + pFf->offset )); + break; + case SigFfTSInfo: + dot11fUnpackFfTSInfo(pCtx, pBufRemaining, ( tDot11fFfTSInfo* )(pFrm + pFf->offset )); + break; + case SigFfTimeStamp: + dot11fUnpackFfTimeStamp(pCtx, pBufRemaining, ( tDot11fFfTimeStamp* )(pFrm + pFf->offset )); + break; + case SigFfTransactionId: + dot11fUnpackFfTransactionId(pCtx, pBufRemaining, ( tDot11fFfTransactionId* )(pFrm + pFf->offset )); + break; + case SigFfTxAntennaId: + dot11fUnpackFfTxAntennaId(pCtx, pBufRemaining, ( tDot11fFfTxAntennaId* )(pFrm + pFf->offset )); + break; + case SigFfTxPower: + dot11fUnpackFfTxPower(pCtx, pBufRemaining, ( tDot11fFfTxPower* )(pFrm + pFf->offset )); + break; + case SigFfVhtMembershipStatusArray: + dot11fUnpackFfVhtMembershipStatusArray(pCtx, pBufRemaining, ( tDot11fFfVhtMembershipStatusArray* )(pFrm + pFf->offset )); + break; + case SigFfVhtUserPositionArray: + dot11fUnpackFfVhtUserPositionArray(pCtx, pBufRemaining, ( tDot11fFfVhtUserPositionArray* )(pFrm + pFf->offset )); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I don'" + "t know about the FF signature %d-- this is most " + "likely a 'framesc' bug.\n"), pFf->sig); + return DOT11F_INTERNAL_ERROR; + } + + pBufRemaining += pFf->size; + nBufRemaining -= pFf->size; + ++pFf; + } + + while (nBufRemaining) + { + if (1 == nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGE, FRFL("This frame reports " + "only one byte remaining after it's fixed fields.\n")); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + pIe = FindIEDefn(pCtx, pBufRemaining, nBufRemaining, IEs); + + eid = *pBufRemaining++; --nBufRemaining; + len = *pBufRemaining++; --nBufRemaining; + + if (pIe && pIe->noui) + { + if (pIe->noui > nBufRemaining) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("IE %d reports " + "length %d, but it has an OUI of %d bytes.\n"), + eid, len, pIe->noui); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += pIe->noui; + nBufRemaining -= pIe->noui; + len -= pIe->noui; + } + + if (len > nBufRemaining) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("IE %d reports length %" + "d, but there are only %d bytes remaining in this" + " frame.\n"), eid, len, nBufRemaining); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + if (pIe) + { + if (nBufRemaining < pIe->minSize - pIe->noui - 2U) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but there are onl" + "y %d bytes remaining in this frame.\n"), + pIe->name, pIe->minSize, nBufRemaining); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + status |= DOT11F_INCOMPLETE_IE; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + else + { + if (len > pIe->maxSize - pIe->noui - 2U){ + FRAMES_LOG1(pCtx, FRLOGW, FRFL("The IE %s reports " + "an unexpectedly large size; it is presumably " + "more up-to-date than this parser, but this wa" + "rning may also indicate a corrupt frame.\n"), + pIe->name); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + } + + countOffset = ( (0 != pIe->arraybound) * ( *(tANI_U16* )(pFrm + pIe->countOffset))); + if (0 != pIe->arraybound && countOffset >= pIe->arraybound) { + status |= DOT11F_DUPLICATE_IE; + goto skip_dup_ie; + } + switch (pIe->sig) + { + case SigIeAPName: + status |= dot11fUnpackIeAPName(pCtx, pBufRemaining, len, ( tDot11fIEAPName* )(pFrm + pIe->offset + sizeof(tDot11fIEAPName)*countOffset) ); + break; + case SigIeBPIndicator: + status |= dot11fUnpackIeBPIndicator(pCtx, pBufRemaining, len, ( tDot11fIEBPIndicator* )(pFrm + pIe->offset + sizeof(tDot11fIEBPIndicator)*countOffset) ); + break; + case SigIeCondensedCountryStr: + status |= dot11fUnpackIeCondensedCountryStr(pCtx, pBufRemaining, len, ( tDot11fIECondensedCountryStr* )(pFrm + pIe->offset + sizeof(tDot11fIECondensedCountryStr)*countOffset) ); + break; + case SigIeGTK: + status |= dot11fUnpackIeGTK(pCtx, pBufRemaining, len, ( tDot11fIEGTK* )(pFrm + pIe->offset + sizeof(tDot11fIEGTK)*countOffset) ); + break; + case SigIeHCF: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEHCF* )(pFrm + pIe->offset + sizeof( tDot11fIEHCF)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEHCF* )(pFrm + pIe->offset + sizeof(tDot11fIEHCF)*countOffset ) )->enabled) ); + break; + case SigIeIGTK: + status |= dot11fUnpackIeIGTK(pCtx, pBufRemaining, len, ( tDot11fIEIGTK* )(pFrm + pIe->offset + sizeof(tDot11fIEIGTK)*countOffset) ); + break; + case SigIeLLAttr: + status |= dot11fUnpackIeLLAttr(pCtx, pBufRemaining, len, ( tDot11fIELLAttr* )(pFrm + pIe->offset + sizeof(tDot11fIELLAttr)*countOffset) ); + break; + case SigIeLoadBalance: + status |= dot11fUnpackIeLoadBalance(pCtx, pBufRemaining, len, ( tDot11fIELoadBalance* )(pFrm + pIe->offset + sizeof(tDot11fIELoadBalance)*countOffset) ); + break; + case SigIeLoadInfo: + status |= dot11fUnpackIeLoadInfo(pCtx, pBufRemaining, len, ( tDot11fIELoadInfo* )(pFrm + pIe->offset + sizeof(tDot11fIELoadInfo)*countOffset) ); + break; + case SigIePropAssocType: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEPropAssocType* )(pFrm + pIe->offset + sizeof( tDot11fIEPropAssocType)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEPropAssocType* )(pFrm + pIe->offset + sizeof(tDot11fIEPropAssocType)*countOffset ) )->type) ); + break; + case SigIePropCapability: + status |= dot11fUnpackIePropCapability(pCtx, pBufRemaining, len, ( tDot11fIEPropCapability* )(pFrm + pIe->offset + sizeof(tDot11fIEPropCapability)*countOffset) ); + break; + case SigIePropChannSwitchAnn: + status |= dot11fUnpackIePropChannSwitchAnn(pCtx, pBufRemaining, len, ( tDot11fIEPropChannSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEPropChannSwitchAnn)*countOffset) ); + break; + case SigIePropEDCAParams: + status |= dot11fUnpackIePropEDCAParams(pCtx, pBufRemaining, len, ( tDot11fIEPropEDCAParams* )(pFrm + pIe->offset + sizeof(tDot11fIEPropEDCAParams)*countOffset) ); + break; + case SigIePropQuietBSS: + status |= dot11fUnpackIePropQuietBSS(pCtx, pBufRemaining, len, ( tDot11fIEPropQuietBSS* )(pFrm + pIe->offset + sizeof(tDot11fIEPropQuietBSS)*countOffset) ); + break; + case SigIePropSuppRates: + status |= dot11fUnpackIePropSuppRates(pCtx, pBufRemaining, len, ( tDot11fIEPropSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEPropSuppRates)*countOffset) ); + break; + case SigIeR0KH_ID: + status |= dot11fUnpackIeR0KH_ID(pCtx, pBufRemaining, len, ( tDot11fIER0KH_ID* )(pFrm + pIe->offset + sizeof(tDot11fIER0KH_ID)*countOffset) ); + break; + case SigIeR1KH_ID: + status |= dot11fUnpackIeR1KH_ID(pCtx, pBufRemaining, len, ( tDot11fIER1KH_ID* )(pFrm + pIe->offset + sizeof(tDot11fIER1KH_ID)*countOffset) ); + break; + case SigIeTSFInfo: + status |= dot11fUnpackIeTSFInfo(pCtx, pBufRemaining, len, ( tDot11fIETSFInfo* )(pFrm + pIe->offset + sizeof(tDot11fIETSFInfo)*countOffset) ); + break; + case SigIeTaurus: + status |= dot11fUnpackIeTaurus(pCtx, pBufRemaining, len, ( tDot11fIETaurus* )(pFrm + pIe->offset + sizeof(tDot11fIETaurus)*countOffset) ); + break; + case SigIeTitan: + status |= dot11fUnpackIeTitan(pCtx, pBufRemaining, len, ( tDot11fIETitan* )(pFrm + pIe->offset + sizeof(tDot11fIETitan)*countOffset) ); + break; + case SigIeTriggerStaBgScan: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIETriggerStaBgScan* )(pFrm + pIe->offset + sizeof( tDot11fIETriggerStaBgScan)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIETriggerStaBgScan* )(pFrm + pIe->offset + sizeof(tDot11fIETriggerStaBgScan)*countOffset ) )->enable) ); + break; + case SigIeVersion: + status |= dot11fUnpackIeVersion(pCtx, pBufRemaining, len, ( tDot11fIEVersion* )(pFrm + pIe->offset + sizeof(tDot11fIEVersion)*countOffset) ); + break; + case SigIeWDS: + status |= dot11fUnpackIeWDS(pCtx, pBufRemaining, len, ( tDot11fIEWDS* )(pFrm + pIe->offset + sizeof(tDot11fIEWDS)*countOffset) ); + break; + case SigIeAPChannelReport: + status |= dot11fUnpackIeAPChannelReport(pCtx, pBufRemaining, len, ( tDot11fIEAPChannelReport* )(pFrm + pIe->offset + sizeof(tDot11fIEAPChannelReport)*countOffset) ); + break; + case SigIeBcnReportingDetail: + status |= dot11fUnpackIeBcnReportingDetail(pCtx, pBufRemaining, len, ( tDot11fIEBcnReportingDetail* )(pFrm + pIe->offset + sizeof(tDot11fIEBcnReportingDetail)*countOffset) ); + break; + case SigIeBeaconReportFrmBody: + status |= dot11fUnpackIeBeaconReportFrmBody(pCtx, pBufRemaining, len, ( tDot11fIEBeaconReportFrmBody* )(pFrm + pIe->offset + sizeof(tDot11fIEBeaconReportFrmBody)*countOffset) ); + break; + case SigIeBeaconReporting: + status |= dot11fUnpackIeBeaconReporting(pCtx, pBufRemaining, len, ( tDot11fIEBeaconReporting* )(pFrm + pIe->offset + sizeof(tDot11fIEBeaconReporting)*countOffset) ); + break; + case SigIeMeasurementPilot: + status |= dot11fUnpackIeMeasurementPilot(pCtx, pBufRemaining, len, ( tDot11fIEMeasurementPilot* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementPilot)*countOffset) ); + break; + case SigIeMultiBssid: + status |= dot11fUnpackIeMultiBssid(pCtx, pBufRemaining, len, ( tDot11fIEMultiBssid* )(pFrm + pIe->offset + sizeof(tDot11fIEMultiBssid)*countOffset) ); + break; + case SigIeRICData: + status |= dot11fUnpackIeRICData(pCtx, pBufRemaining, len, ( tDot11fIERICData* )(pFrm + pIe->offset + sizeof(tDot11fIERICData)*countOffset) ); + break; + case SigIeRICDescriptor: + status |= dot11fUnpackIeRICDescriptor(pCtx, pBufRemaining, len, ( tDot11fIERICDescriptor* )(pFrm + pIe->offset + sizeof(tDot11fIERICDescriptor)*countOffset) ); + break; + case SigIeRRMEnabledCap: + status |= dot11fUnpackIeRRMEnabledCap(pCtx, pBufRemaining, len, ( tDot11fIERRMEnabledCap* )(pFrm + pIe->offset + sizeof(tDot11fIERRMEnabledCap)*countOffset) ); + break; + case SigIeRequestedInfo: + status |= dot11fUnpackIeRequestedInfo(pCtx, pBufRemaining, len, ( tDot11fIERequestedInfo* )(pFrm + pIe->offset + sizeof(tDot11fIERequestedInfo)*countOffset) ); + break; + case SigIeSSID: + status |= dot11fUnpackIeSSID(pCtx, pBufRemaining, len, ( tDot11fIESSID* )(pFrm + pIe->offset + sizeof(tDot11fIESSID)*countOffset) ); + break; + case SigIeSchedule: + status |= dot11fUnpackIeSchedule(pCtx, pBufRemaining, len, ( tDot11fIESchedule* )(pFrm + pIe->offset + sizeof(tDot11fIESchedule)*countOffset) ); + break; + case SigIeTCLAS: + status |= dot11fUnpackIeTCLAS(pCtx, pBufRemaining, len, ( tDot11fIETCLAS* )(pFrm + pIe->offset + sizeof(tDot11fIETCLAS)*countOffset) ); + break; + case SigIeTCLASSPROC: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIETCLASSPROC* )(pFrm + pIe->offset + sizeof( tDot11fIETCLASSPROC)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIETCLASSPROC* )(pFrm + pIe->offset + sizeof(tDot11fIETCLASSPROC)*countOffset ) )->processing) ); + break; + case SigIeTSDelay: + status |= dot11fUnpackIeTSDelay(pCtx, pBufRemaining, len, ( tDot11fIETSDelay* )(pFrm + pIe->offset + sizeof(tDot11fIETSDelay)*countOffset) ); + break; + case SigIeTSPEC: + status |= dot11fUnpackIeTSPEC(pCtx, pBufRemaining, len, ( tDot11fIETSPEC* )(pFrm + pIe->offset + sizeof(tDot11fIETSPEC)*countOffset) ); + break; + case SigIeWMMSchedule: + status |= dot11fUnpackIeWMMSchedule(pCtx, pBufRemaining, len, ( tDot11fIEWMMSchedule* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMSchedule)*countOffset) ); + break; + case SigIeWMMTCLAS: + status |= dot11fUnpackIeWMMTCLAS(pCtx, pBufRemaining, len, ( tDot11fIEWMMTCLAS* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTCLAS)*countOffset) ); + break; + case SigIeWMMTCLASPROC: + status |= dot11fUnpackIeWMMTCLASPROC(pCtx, pBufRemaining, len, ( tDot11fIEWMMTCLASPROC* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTCLASPROC)*countOffset) ); + break; + case SigIeWMMTSDelay: + status |= dot11fUnpackIeWMMTSDelay(pCtx, pBufRemaining, len, ( tDot11fIEWMMTSDelay* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTSDelay)*countOffset) ); + break; + case SigIeWMMTSPEC: + status |= dot11fUnpackIeWMMTSPEC(pCtx, pBufRemaining, len, ( tDot11fIEWMMTSPEC* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMTSPEC)*countOffset) ); + break; + case SigIeAID: + status |= dot11fUnpackIeAID(pCtx, pBufRemaining, len, ( tDot11fIEAID* )(pFrm + pIe->offset + sizeof(tDot11fIEAID)*countOffset) ); + break; + case SigIeAirgo: + status |= dot11fUnpackIeAirgo(pCtx, pBufRemaining, len, ( tDot11fIEAirgo* )(pFrm + pIe->offset + sizeof(tDot11fIEAirgo)*countOffset) ); + break; + case SigIeCFParams: + status |= dot11fUnpackIeCFParams(pCtx, pBufRemaining, len, ( tDot11fIECFParams* )(pFrm + pIe->offset + sizeof(tDot11fIECFParams)*countOffset) ); + break; + case SigIeChallengeText: + status |= dot11fUnpackIeChallengeText(pCtx, pBufRemaining, len, ( tDot11fIEChallengeText* )(pFrm + pIe->offset + sizeof(tDot11fIEChallengeText)*countOffset) ); + break; + case SigIeChanSwitchAnn: + status |= dot11fUnpackIeChanSwitchAnn(pCtx, pBufRemaining, len, ( tDot11fIEChanSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEChanSwitchAnn)*countOffset) ); + break; + case SigIeCountry: + status |= dot11fUnpackIeCountry(pCtx, pBufRemaining, len, ( tDot11fIECountry* )(pFrm + pIe->offset + sizeof(tDot11fIECountry)*countOffset) ); + break; + case SigIeDSParams: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEDSParams* )(pFrm + pIe->offset + sizeof( tDot11fIEDSParams)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEDSParams* )(pFrm + pIe->offset + sizeof(tDot11fIEDSParams)*countOffset ) )->curr_channel) ); + break; + case SigIeEDCAParamSet: + status |= dot11fUnpackIeEDCAParamSet(pCtx, pBufRemaining, len, ( tDot11fIEEDCAParamSet* )(pFrm + pIe->offset + sizeof(tDot11fIEEDCAParamSet)*countOffset) ); + break; + case SigIeERPInfo: + status |= dot11fUnpackIeERPInfo(pCtx, pBufRemaining, len, ( tDot11fIEERPInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEERPInfo)*countOffset) ); + break; + case SigIeESECckmOpaque: + status |= dot11fUnpackIeESECckmOpaque(pCtx, pBufRemaining, len, ( tDot11fIEESECckmOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEESECckmOpaque)*countOffset) ); + break; + case SigIeESERadMgmtCap: + status |= dot11fUnpackIeESERadMgmtCap(pCtx, pBufRemaining, len, ( tDot11fIEESERadMgmtCap* )(pFrm + pIe->offset + sizeof(tDot11fIEESERadMgmtCap)*countOffset) ); + break; + case SigIeESETrafStrmMet: + status |= dot11fUnpackIeESETrafStrmMet(pCtx, pBufRemaining, len, ( tDot11fIEESETrafStrmMet* )(pFrm + pIe->offset + sizeof(tDot11fIEESETrafStrmMet)*countOffset) ); + break; + case SigIeESETrafStrmRateSet: + status |= dot11fUnpackIeESETrafStrmRateSet(pCtx, pBufRemaining, len, ( tDot11fIEESETrafStrmRateSet* )(pFrm + pIe->offset + sizeof(tDot11fIEESETrafStrmRateSet)*countOffset) ); + break; + case SigIeESETxmitPower: + status |= dot11fUnpackIeESETxmitPower(pCtx, pBufRemaining, len, ( tDot11fIEESETxmitPower* )(pFrm + pIe->offset + sizeof(tDot11fIEESETxmitPower)*countOffset) ); + break; + case SigIeESEVersion: + status |= dot11fUnpackIeESEVersion(pCtx, pBufRemaining, len, ( tDot11fIEESEVersion* )(pFrm + pIe->offset + sizeof(tDot11fIEESEVersion)*countOffset) ); + break; + case SigIeExtCap: + status |= dot11fUnpackIeExtCap(pCtx, pBufRemaining, len, ( tDot11fIEExtCap* )(pFrm + pIe->offset + sizeof(tDot11fIEExtCap)*countOffset) ); + break; + case SigIeExtChanSwitchAnn: + status |= dot11fUnpackIeCommonFunc(pCtx, pBufRemaining, len, + (tANI_U8*) &((( tDot11fIEExtChanSwitchAnn* )(pFrm + pIe->offset + sizeof( tDot11fIEExtChanSwitchAnn)*countOffset ) )->present), + (tANI_U8*) &((( tDot11fIEExtChanSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEExtChanSwitchAnn)*countOffset ) )->secondaryChannelOffset) ); + break; + case SigIeExtSuppRates: + status |= dot11fUnpackIeExtSuppRates(pCtx, pBufRemaining, len, ( tDot11fIEExtSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEExtSuppRates)*countOffset) ); + break; + case SigIeFHParamSet: + status |= dot11fUnpackIeFHParamSet(pCtx, pBufRemaining, len, ( tDot11fIEFHParamSet* )(pFrm + pIe->offset + sizeof(tDot11fIEFHParamSet)*countOffset) ); + break; + case SigIeFHParams: + status |= dot11fUnpackIeFHParams(pCtx, pBufRemaining, len, ( tDot11fIEFHParams* )(pFrm + pIe->offset + sizeof(tDot11fIEFHParams)*countOffset) ); + break; + case SigIeFHPattTable: + status |= dot11fUnpackIeFHPattTable(pCtx, pBufRemaining, len, ( tDot11fIEFHPattTable* )(pFrm + pIe->offset + sizeof(tDot11fIEFHPattTable)*countOffset) ); + break; + case SigIeFTInfo: + status |= dot11fUnpackIeFTInfo(pCtx, pBufRemaining, len, ( tDot11fIEFTInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEFTInfo)*countOffset) ); + break; + case SigIeHT2040BSSCoexistence: + status |= dot11fUnpackIeHT2040BSSCoexistence(pCtx, pBufRemaining, len, ( tDot11fIEHT2040BSSCoexistence* )(pFrm + pIe->offset + sizeof(tDot11fIEHT2040BSSCoexistence)*countOffset) ); + break; + case SigIeHT2040BSSIntolerantReport: + status |= dot11fUnpackIeHT2040BSSIntolerantReport(pCtx, pBufRemaining, len, ( tDot11fIEHT2040BSSIntolerantReport* )(pFrm + pIe->offset + sizeof(tDot11fIEHT2040BSSIntolerantReport)*countOffset) ); + break; + case SigIeHTCaps: + status |= dot11fUnpackIeHTCaps(pCtx, pBufRemaining, len, ( tDot11fIEHTCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEHTCaps)*countOffset) ); + break; + case SigIeHTInfo: + status |= dot11fUnpackIeHTInfo(pCtx, pBufRemaining, len, ( tDot11fIEHTInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEHTInfo)*countOffset) ); + break; + case SigIeIBSSParams: + status |= dot11fUnpackIeIBSSParams(pCtx, pBufRemaining, len, ( tDot11fIEIBSSParams* )(pFrm + pIe->offset + sizeof(tDot11fIEIBSSParams)*countOffset) ); + break; + case SigIeLinkIdentifier: + status |= dot11fUnpackIeLinkIdentifier(pCtx, pBufRemaining, len, ( tDot11fIELinkIdentifier* )(pFrm + pIe->offset + sizeof(tDot11fIELinkIdentifier)*countOffset) ); + break; + case SigIeMeasurementReport: + status |= dot11fUnpackIeMeasurementReport(pCtx, pBufRemaining, len, ( tDot11fIEMeasurementReport* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementReport)*countOffset) ); + break; + case SigIeMeasurementRequest: + status |= dot11fUnpackIeMeasurementRequest(pCtx, pBufRemaining, len, ( tDot11fIEMeasurementRequest* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementRequest)*countOffset) ); + break; + case SigIeMobilityDomain: + status |= dot11fUnpackIeMobilityDomain(pCtx, pBufRemaining, len, ( tDot11fIEMobilityDomain* )(pFrm + pIe->offset + sizeof(tDot11fIEMobilityDomain)*countOffset) ); + break; + case SigIeNeighborReport: + status |= dot11fUnpackIeNeighborReport(pCtx, pBufRemaining, len, ( tDot11fIENeighborReport* )(pFrm + pIe->offset + sizeof(tDot11fIENeighborReport)*countOffset) ); + break; + case SigIeOBSSScanParameters: + status |= dot11fUnpackIeOBSSScanParameters(pCtx, pBufRemaining, len, ( tDot11fIEOBSSScanParameters* )(pFrm + pIe->offset + sizeof(tDot11fIEOBSSScanParameters)*countOffset) ); + break; + case SigIeOperatingMode: + status |= dot11fUnpackIeOperatingMode(pCtx, pBufRemaining, len, ( tDot11fIEOperatingMode* )(pFrm + pIe->offset + sizeof(tDot11fIEOperatingMode)*countOffset) ); + break; + case SigIeP2PAssocReq: + status |= dot11fUnpackIeP2PAssocReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PAssocReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PAssocReq)*countOffset) ); + break; + case SigIeP2PAssocRes: + status |= dot11fUnpackIeP2PAssocRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PAssocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PAssocRes)*countOffset) ); + break; + case SigIeP2PBeacon: + status |= dot11fUnpackIeP2PBeacon(pCtx, pBufRemaining, len, ( tDot11fIEP2PBeacon* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PBeacon)*countOffset) ); + break; + case SigIeP2PBeaconProbeRes: + status |= dot11fUnpackIeP2PBeaconProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PBeaconProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PBeaconProbeRes)*countOffset) ); + break; + case SigIeP2PDeAuth: + status |= dot11fUnpackIeP2PDeAuth(pCtx, pBufRemaining, len, ( tDot11fIEP2PDeAuth* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDeAuth)*countOffset) ); + break; + case SigIeP2PDeviceDiscoverabilityReq: + status |= dot11fUnpackIeP2PDeviceDiscoverabilityReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PDeviceDiscoverabilityReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityReq)*countOffset) ); + break; + case SigIeP2PDeviceDiscoverabilityRes: + status |= dot11fUnpackIeP2PDeviceDiscoverabilityRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PDeviceDiscoverabilityRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityRes)*countOffset) ); + break; + case SigIeP2PDisAssoc: + status |= dot11fUnpackIeP2PDisAssoc(pCtx, pBufRemaining, len, ( tDot11fIEP2PDisAssoc* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PDisAssoc)*countOffset) ); + break; + case SigIeP2PGONegCnf: + status |= dot11fUnpackIeP2PGONegCnf(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegCnf* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegCnf)*countOffset) ); + break; + case SigIeP2PGONegReq: + status |= dot11fUnpackIeP2PGONegReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegReq)*countOffset) ); + break; + case SigIeP2PGONegRes: + status |= dot11fUnpackIeP2PGONegRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegRes)*countOffset) ); + break; + case SigIeP2PGONegWPS: + status |= dot11fUnpackIeP2PGONegWPS(pCtx, pBufRemaining, len, ( tDot11fIEP2PGONegWPS* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PGONegWPS)*countOffset) ); + break; + case SigIeP2PIEOpaque: + status |= dot11fUnpackIeP2PIEOpaque(pCtx, pBufRemaining, len, ( tDot11fIEP2PIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PIEOpaque)*countOffset) ); + break; + case SigIeP2PInvitationReq: + status |= dot11fUnpackIeP2PInvitationReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PInvitationReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PInvitationReq)*countOffset) ); + break; + case SigIeP2PInvitationRes: + status |= dot11fUnpackIeP2PInvitationRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PInvitationRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PInvitationRes)*countOffset) ); + break; + case SigIeP2PNoticeOfAbsence: + status |= dot11fUnpackIeP2PNoticeOfAbsence(pCtx, pBufRemaining, len, ( tDot11fIEP2PNoticeOfAbsence* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PNoticeOfAbsence)*countOffset) ); + break; + case SigIeP2PPresenceResponse: + status |= dot11fUnpackIeP2PPresenceResponse(pCtx, pBufRemaining, len, ( tDot11fIEP2PPresenceResponse* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PPresenceResponse)*countOffset) ); + break; + case SigIeP2PProbeReq: + status |= dot11fUnpackIeP2PProbeReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PProbeReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PProbeReq)*countOffset) ); + break; + case SigIeP2PProbeRes: + status |= dot11fUnpackIeP2PProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PProbeRes)*countOffset) ); + break; + case SigIeP2PProvisionDiscoveryReq: + status |= dot11fUnpackIeP2PProvisionDiscoveryReq(pCtx, pBufRemaining, len, ( tDot11fIEP2PProvisionDiscoveryReq* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PProvisionDiscoveryReq)*countOffset) ); + break; + case SigIeP2PWSCProvisionDiscoveryRes: + status |= dot11fUnpackIeP2PWSCProvisionDiscoveryRes(pCtx, pBufRemaining, len, ( tDot11fIEP2PWSCProvisionDiscoveryRes* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PWSCProvisionDiscoveryRes)*countOffset) ); + break; + case SigIePTIControl: + status |= dot11fUnpackIePTIControl(pCtx, pBufRemaining, len, ( tDot11fIEPTIControl* )(pFrm + pIe->offset + sizeof(tDot11fIEPTIControl)*countOffset) ); + break; + case SigIePUBufferStatus: + status |= dot11fUnpackIePUBufferStatus(pCtx, pBufRemaining, len, ( tDot11fIEPUBufferStatus* )(pFrm + pIe->offset + sizeof(tDot11fIEPUBufferStatus)*countOffset) ); + break; + case SigIePowerCaps: + status |= dot11fUnpackIePowerCaps(pCtx, pBufRemaining, len, ( tDot11fIEPowerCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEPowerCaps)*countOffset) ); + break; + case SigIePowerConstraints: + status |= dot11fUnpackIePowerConstraints(pCtx, pBufRemaining, len, ( tDot11fIEPowerConstraints* )(pFrm + pIe->offset + sizeof(tDot11fIEPowerConstraints)*countOffset) ); + break; + case SigIeQBSSLoad: + status |= dot11fUnpackIeQBSSLoad(pCtx, pBufRemaining, len, ( tDot11fIEQBSSLoad* )(pFrm + pIe->offset + sizeof(tDot11fIEQBSSLoad)*countOffset) ); + break; + case SigIeQOSCapsAp: + status |= dot11fUnpackIeQOSCapsAp(pCtx, pBufRemaining, len, ( tDot11fIEQOSCapsAp* )(pFrm + pIe->offset + sizeof(tDot11fIEQOSCapsAp)*countOffset) ); + break; + case SigIeQOSCapsStation: + status |= dot11fUnpackIeQOSCapsStation(pCtx, pBufRemaining, len, ( tDot11fIEQOSCapsStation* )(pFrm + pIe->offset + sizeof(tDot11fIEQOSCapsStation)*countOffset) ); + break; + case SigIeQosMapSet: + status |= dot11fUnpackIeQosMapSet(pCtx, pBufRemaining, len, ( tDot11fIEQosMapSet* )(pFrm + pIe->offset + sizeof(tDot11fIEQosMapSet)*countOffset) ); + break; + case SigIeQuiet: + status |= dot11fUnpackIeQuiet(pCtx, pBufRemaining, len, ( tDot11fIEQuiet* )(pFrm + pIe->offset + sizeof(tDot11fIEQuiet)*countOffset) ); + break; + case SigIeRCPIIE: + status |= dot11fUnpackIeRCPIIE(pCtx, pBufRemaining, len, ( tDot11fIERCPIIE* )(pFrm + pIe->offset + sizeof(tDot11fIERCPIIE)*countOffset) ); + break; + case SigIeRICDataDesc: + //reset the pointers back since this is a container IE and it doesnt have its own EID and Len. + pBufRemaining -= 2; nBufRemaining += 2; + if ( pIe && pIe->noui ) + { + pBufRemaining -= pIe->noui; + nBufRemaining += pIe->noui; + len += pIe->noui; + } + status |= GetContainerIesLen(pCtx, pBufRemaining, nBufRemaining, &len, IES_RICDataDesc); + if (status != DOT11F_PARSE_SUCCESS && status != DOT11F_UNKNOWN_IES ) break; + status |= dot11fUnpackIeRICDataDesc(pCtx, pBufRemaining, len, ( tDot11fIERICDataDesc* )(pFrm + pIe->offset + sizeof(tDot11fIERICDataDesc)*countOffset) ); + break; + case SigIeRSN: + status |= dot11fUnpackIeRSN(pCtx, pBufRemaining, len, ( tDot11fIERSN* )(pFrm + pIe->offset + sizeof(tDot11fIERSN)*countOffset) ); + break; + case SigIeRSNIIE: + status |= dot11fUnpackIeRSNIIE(pCtx, pBufRemaining, len, ( tDot11fIERSNIIE* )(pFrm + pIe->offset + sizeof(tDot11fIERSNIIE)*countOffset) ); + break; + case SigIeRSNOpaque: + status |= dot11fUnpackIeRSNOpaque(pCtx, pBufRemaining, len, ( tDot11fIERSNOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIERSNOpaque)*countOffset) ); + break; + case SigIeSuppChannels: + status |= dot11fUnpackIeSuppChannels(pCtx, pBufRemaining, len, ( tDot11fIESuppChannels* )(pFrm + pIe->offset + sizeof(tDot11fIESuppChannels)*countOffset) ); + break; + case SigIeSuppOperatingClasses: + status |= dot11fUnpackIeSuppOperatingClasses(pCtx, pBufRemaining, len, ( tDot11fIESuppOperatingClasses* )(pFrm + pIe->offset + sizeof(tDot11fIESuppOperatingClasses)*countOffset) ); + break; + case SigIeSuppRates: + status |= dot11fUnpackIeSuppRates(pCtx, pBufRemaining, len, ( tDot11fIESuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIESuppRates)*countOffset) ); + break; + case SigIeTIM: + status |= dot11fUnpackIeTIM(pCtx, pBufRemaining, len, ( tDot11fIETIM* )(pFrm + pIe->offset + sizeof(tDot11fIETIM)*countOffset) ); + break; + case SigIeTPCReport: + status |= dot11fUnpackIeTPCReport(pCtx, pBufRemaining, len, ( tDot11fIETPCReport* )(pFrm + pIe->offset + sizeof(tDot11fIETPCReport)*countOffset) ); + break; + case SigIeTPCRequest: + status |= dot11fUnpackIeTPCRequest(pCtx, pBufRemaining, len, ( tDot11fIETPCRequest* )(pFrm + pIe->offset + sizeof(tDot11fIETPCRequest)*countOffset) ); + break; + case SigIeTimeoutInterval: + status |= dot11fUnpackIeTimeoutInterval(pCtx, pBufRemaining, len, ( tDot11fIETimeoutInterval* )(pFrm + pIe->offset + sizeof(tDot11fIETimeoutInterval)*countOffset) ); + break; + case SigIeVHTCaps: + status |= dot11fUnpackIeVHTCaps(pCtx, pBufRemaining, len, ( tDot11fIEVHTCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEVHTCaps)*countOffset) ); + break; + case SigIeVHTExtBssLoad: + status |= dot11fUnpackIeVHTExtBssLoad(pCtx, pBufRemaining, len, ( tDot11fIEVHTExtBssLoad* )(pFrm + pIe->offset + sizeof(tDot11fIEVHTExtBssLoad)*countOffset) ); + break; + case SigIeVHTOperation: + status |= dot11fUnpackIeVHTOperation(pCtx, pBufRemaining, len, ( tDot11fIEVHTOperation* )(pFrm + pIe->offset + sizeof(tDot11fIEVHTOperation)*countOffset) ); + break; + case SigIeWAPI: + status |= dot11fUnpackIeWAPI(pCtx, pBufRemaining, len, ( tDot11fIEWAPI* )(pFrm + pIe->offset + sizeof(tDot11fIEWAPI)*countOffset) ); + break; + case SigIeWAPIOpaque: + status |= dot11fUnpackIeWAPIOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWAPIOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWAPIOpaque)*countOffset) ); + break; + case SigIeWFATPC: + status |= dot11fUnpackIeWFATPC(pCtx, pBufRemaining, len, ( tDot11fIEWFATPC* )(pFrm + pIe->offset + sizeof(tDot11fIEWFATPC)*countOffset) ); + break; + case SigIeWFDIEOpaque: + status |= dot11fUnpackIeWFDIEOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWFDIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWFDIEOpaque)*countOffset) ); + break; + case SigIeWMMCaps: + status |= dot11fUnpackIeWMMCaps(pCtx, pBufRemaining, len, ( tDot11fIEWMMCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMCaps)*countOffset) ); + break; + case SigIeWMMInfoAp: + status |= dot11fUnpackIeWMMInfoAp(pCtx, pBufRemaining, len, ( tDot11fIEWMMInfoAp* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMInfoAp)*countOffset) ); + break; + case SigIeWMMInfoStation: + status |= dot11fUnpackIeWMMInfoStation(pCtx, pBufRemaining, len, ( tDot11fIEWMMInfoStation* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMInfoStation)*countOffset) ); + break; + case SigIeWMMParams: + status |= dot11fUnpackIeWMMParams(pCtx, pBufRemaining, len, ( tDot11fIEWMMParams* )(pFrm + pIe->offset + sizeof(tDot11fIEWMMParams)*countOffset) ); + break; + case SigIeWPA: + status |= dot11fUnpackIeWPA(pCtx, pBufRemaining, len, ( tDot11fIEWPA* )(pFrm + pIe->offset + sizeof(tDot11fIEWPA)*countOffset) ); + break; + case SigIeWPAOpaque: + status |= dot11fUnpackIeWPAOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWPAOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWPAOpaque)*countOffset) ); + break; + case SigIeWSC: + status |= dot11fUnpackIeWSC(pCtx, pBufRemaining, len, ( tDot11fIEWSC* )(pFrm + pIe->offset + sizeof(tDot11fIEWSC)*countOffset) ); + break; + case SigIeWiderBWChanSwitchAnn: + status |= dot11fUnpackIeWiderBWChanSwitchAnn(pCtx, pBufRemaining, len, ( tDot11fIEWiderBWChanSwitchAnn* )(pFrm + pIe->offset + sizeof(tDot11fIEWiderBWChanSwitchAnn)*countOffset) ); + break; + case SigIeWscAssocReq: + status |= dot11fUnpackIeWscAssocReq(pCtx, pBufRemaining, len, ( tDot11fIEWscAssocReq* )(pFrm + pIe->offset + sizeof(tDot11fIEWscAssocReq)*countOffset) ); + break; + case SigIeWscAssocRes: + status |= dot11fUnpackIeWscAssocRes(pCtx, pBufRemaining, len, ( tDot11fIEWscAssocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscAssocRes)*countOffset) ); + break; + case SigIeWscBeacon: + status |= dot11fUnpackIeWscBeacon(pCtx, pBufRemaining, len, ( tDot11fIEWscBeacon* )(pFrm + pIe->offset + sizeof(tDot11fIEWscBeacon)*countOffset) ); + break; + case SigIeWscBeaconProbeRes: + status |= dot11fUnpackIeWscBeaconProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEWscBeaconProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscBeaconProbeRes)*countOffset) ); + break; + case SigIeWscIEOpaque: + status |= dot11fUnpackIeWscIEOpaque(pCtx, pBufRemaining, len, ( tDot11fIEWscIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWscIEOpaque)*countOffset) ); + break; + case SigIeWscProbeReq: + status |= dot11fUnpackIeWscProbeReq(pCtx, pBufRemaining, len, ( tDot11fIEWscProbeReq* )(pFrm + pIe->offset + sizeof(tDot11fIEWscProbeReq)*countOffset) ); + break; + case SigIeWscProbeRes: + status |= dot11fUnpackIeWscProbeRes(pCtx, pBufRemaining, len, ( tDot11fIEWscProbeRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscProbeRes)*countOffset) ); + break; + case SigIeWscReassocRes: + status |= dot11fUnpackIeWscReassocRes(pCtx, pBufRemaining, len, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + sizeof(tDot11fIEWscReassocRes)*countOffset) ); + break; + case SigIehs20vendor_ie: + status |= dot11fUnpackIehs20vendor_ie(pCtx, pBufRemaining, len, ( tDot11fIEhs20vendor_ie* )(pFrm + pIe->offset + sizeof(tDot11fIEhs20vendor_ie)*countOffset) ); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR" + ": I don't know about the IE signature %d" + "-- this is most likely a 'framesc' bug.\n"), + pIe->sig); + FRAMES_DBG_BREAK(); + return DOT11F_INTERNAL_ERROR; + } + if (pIe->arraybound) (++( *(tANI_U16*)(pFrm + pIe->countOffset) )); + } + + + } + else + { + FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown IE %d" + " (length %d)\n"), eid, len); + FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - 2, len); + status |= DOT11F_UNKNOWN_IES; + } + +skip_dup_ie: + pBufRemaining += len; + + if (len > nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGW, FRFL("This IE extends past " + "the buffer as it was defined to us. This could" + "mean a corrupt frame, or just an incorrect leng" + "th parameter.\n")); + FRAMES_DBG_BREAK(); + status |= DOT11F_LAST_IE_TOO_LONG; + goto MandatoryCheck; + } + + nBufRemaining -= len; + + } + +MandatoryCheck: + pIe = &IEs[0]; + while (0xff != pIe->eid) + { + if (pIe->fMandatory) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pIe->offset + + pIe->presenceOffset); + if (!*pfFound) + { + FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandato" + "ry IE %s wasn't seen.\n"), + pIe->name); + FRAMES_DBG_BREAK(); + status |= DOT11F_MANDATORY_IE_MISSING; + } + + } + ++pIe; + } + + return status; +} /* End UnpackCore. */ + +static tANI_U32 UnpackTlvCore( tpAniSirGlobal pCtx, + tANI_U8 *pBuf, + tANI_U32 nBuf, + const tTLVDefn TLVs[ ], + tANI_U8 *pFrm, + size_t nFrm ) +{ + const tTLVDefn *pTlv; + tANI_U32 nBufRemaining, status, npec; + tANI_U16 id, len; + tANI_U8 *pBufRemaining, *pfFound; + + (void)pCtx; // Shutup the compiler + (void)nFrm; + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + // While we have data... + while ( nBufRemaining ) + { + if ( 3 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL( "This frame reports " + "fewer three byte(s) remaining.\n" ) ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + npec = 0U; + + // Look for a matching TLV definition, + pTlv = FindTLVDefn( pCtx, pBufRemaining, nBufRemaining, TLVs ); + // consume the type, + if ( pTlv ) + { + if ( pTlv->sType == 2) + { + framesntohs(pCtx, &id, pBufRemaining, pTlv->fMsb); + pBufRemaining += 2; + nBufRemaining -= 2; + }else + { + id = *pBufRemaining; + pBufRemaining += 1; + nBufRemaining -= 1; + } + // & length, + if ( pTlv->sLen == 2) + { + framesntohs(pCtx, &len, pBufRemaining, pTlv->fMsb); + if ( 2 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL("This frame reports " + "fewer two byte(s) remaining.\n") ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 2; + nBufRemaining -= 2; + }else + { + len = *pBufRemaining; + pBufRemaining += 1; + nBufRemaining -= 1; + } + } + else + { + pBufRemaining += TLVs[0].sType; + nBufRemaining -= TLVs[0].sType; + framesntohs(pCtx, &len, pBufRemaining, (TLVs[0].sType == 2)); + if ( 2 > nBufRemaining ) + { + FRAMES_LOG0( pCtx, FRLOGE, FRFL("This frame reports " + "fewer two byte(s) remaining.\n") ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 2; + nBufRemaining -= 2; + } + + if ( pTlv && pTlv->pec ) + { + npec = 3U; + if ( 3 > nBufRemaining ) + { + FRAMES_LOG2(pCtx, FRLOGW, FRFL("TLV %d reports length" + "%d, but it has a Private Enterprise Code (3 byte" + "s.\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG1, pBuf, nBuf); + FRAMES_LOG2(pCtx, FRLOG1, FRFL("We've parsed %d bytes" + "of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + pBufRemaining += 3; + nBufRemaining -= 3; + len -= 3; + } + + // Whether we found a hit or not, we can validate the reported + // length of this TLV: + if ( len > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGW, FRFL("TLV %d reports length %" + "d, but there are only %d bytes remaining in this f" + "rame.\n"), id, len, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL( "We've parsed %d bytes" + " of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK(); + goto MandatoryCheck; + } + + // Now, *if* we found a hit... + if ( pTlv ) + { + if ( len < pTlv->minSize - npec ) + { + FRAMES_LOG3( pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but the size is only " + "%d bytes.\n"), + pTlv->name, pTlv->minSize, len ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK( ); + goto MandatoryCheck; + } + if ( nBufRemaining < pTlv->minSize - npec - (pTlv->sType + pTlv->sLen) ) + { + FRAMES_LOG3( pCtx, FRLOGW, FRFL("The IE %s must be " + "at least %d bytes in size, but there are only " + "%d bytes remaining in this frame.\n"), + pTlv->name, pTlv->minSize, nBufRemaining ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + status |= DOT11F_INCOMPLETE_TLV; + FRAMES_DBG_BREAK( ); + goto MandatoryCheck; + } + else if ( len > pTlv->maxSize - npec - (pTlv->sType + pTlv->sLen) ) + { + FRAMES_LOG1( pCtx, FRLOGW, FRFL("The TLV %s reports " + "an illegally large size; this TLV is presumably" + "corrupt or otherwise invalid & will be skipped " + "ipped.\n"), pTlv->name ); + FRAMES_DUMP( pCtx, FRLOG1, pBuf, nBuf ); + FRAMES_LOG2( pCtx, FRLOG1, FRFL("We've parsed %d by" + "tes of this buffer, and show %d left.\n"), + pBufRemaining - pBuf, nBufRemaining); + FRAMES_DBG_BREAK(); + status |= DOT11F_SKIPPED_BAD_TLV; + } + else + { + switch (pTlv->sig) + { + case SigTlvAuthorizedMACs: + status |= dot11fUnpackTlvAuthorizedMACs(pCtx, pBufRemaining, len, ( tDot11fTLVAuthorizedMACs* )(pFrm + pTlv->offset )); + break; + case SigTlvRequestToEnroll: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVRequestToEnroll* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVRequestToEnroll*)(pFrm + pTlv->offset ))->req)); + break; + case SigTlvVersion2: + status |= dot11fUnpackTlvVersion2(pCtx, pBufRemaining, len, ( tDot11fTLVVersion2* )(pFrm + pTlv->offset )); + break; + case SigTlvAPSetupLocked: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVAPSetupLocked* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVAPSetupLocked*)(pFrm + pTlv->offset ))->fLocked)); + break; + case SigTlvAssociationState: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVAssociationState* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVAssociationState*)(pFrm + pTlv->offset ))->state)); + break; + case SigTlvChannelList: + status |= dot11fUnpackTlvChannelList(pCtx, pBufRemaining, len, ( tDot11fTLVChannelList* )(pFrm + pTlv->offset )); + break; + case SigTlvConfigMethods: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVConfigMethods* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVConfigMethods*)(pFrm + pTlv->offset ))->methods)); + break; + case SigTlvConfigurationError: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVConfigurationError* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVConfigurationError*)(pFrm + pTlv->offset ))->error)); + break; + case SigTlvConfigurationTimeout: + status |= dot11fUnpackTlvConfigurationTimeout(pCtx, pBufRemaining, len, ( tDot11fTLVConfigurationTimeout* )(pFrm + pTlv->offset )); + break; + case SigTlvDeviceName: + status |= dot11fUnpackTlvDeviceName(pCtx, pBufRemaining, len, ( tDot11fTLVDeviceName* )(pFrm + pTlv->offset )); + break; + case SigTlvDevicePasswordID: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVDevicePasswordID* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVDevicePasswordID*)(pFrm + pTlv->offset ))->id)); + break; + case SigTlvExtendedListenTiming: + status |= dot11fUnpackTlvExtendedListenTiming(pCtx, pBufRemaining, len, ( tDot11fTLVExtendedListenTiming* )(pFrm + pTlv->offset )); + break; + case SigTlvGOIntent: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVGOIntent* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVGOIntent*)(pFrm + pTlv->offset ))->GOIntent)); + break; + case SigTlvIntendedP2PInterfaceAddress: + status |= dot11fUnpackTlvIntendedP2PInterfaceAddress(pCtx, pBufRemaining, len, ( tDot11fTLVIntendedP2PInterfaceAddress* )(pFrm + pTlv->offset )); + break; + case SigTlvInvitationFlags: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVInvitationFlags* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVInvitationFlags*)(pFrm + pTlv->offset ))->invitationFlags)); + break; + case SigTlvListenChannel: + status |= dot11fUnpackTlvListenChannel(pCtx, pBufRemaining, len, ( tDot11fTLVListenChannel* )(pFrm + pTlv->offset )); + break; + case SigTlvManufacturer: + status |= dot11fUnpackTlvManufacturer(pCtx, pBufRemaining, len, ( tDot11fTLVManufacturer* )(pFrm + pTlv->offset )); + break; + case SigTlvMinorReasonCode: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVMinorReasonCode* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVMinorReasonCode*)(pFrm + pTlv->offset ))->minorReasonCode)); + break; + case SigTlvModelName: + status |= dot11fUnpackTlvModelName(pCtx, pBufRemaining, len, ( tDot11fTLVModelName* )(pFrm + pTlv->offset )); + break; + case SigTlvModelNumber: + status |= dot11fUnpackTlvModelNumber(pCtx, pBufRemaining, len, ( tDot11fTLVModelNumber* )(pFrm + pTlv->offset )); + break; + case SigTlvNoticeOfAbsence: + status |= dot11fUnpackTlvNoticeOfAbsence(pCtx, pBufRemaining, len, ( tDot11fTLVNoticeOfAbsence* )(pFrm + pTlv->offset )); + break; + case SigTlvOperatingChannel: + status |= dot11fUnpackTlvOperatingChannel(pCtx, pBufRemaining, len, ( tDot11fTLVOperatingChannel* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PCapability: + status |= dot11fUnpackTlvP2PCapability(pCtx, pBufRemaining, len, ( tDot11fTLVP2PCapability* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PDeviceId: + status |= dot11fUnpackTlvP2PDeviceId(pCtx, pBufRemaining, len, ( tDot11fTLVP2PDeviceId* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PDeviceInfo: + status |= dot11fUnpackTlvP2PDeviceInfo(pCtx, pBufRemaining, len, ( tDot11fTLVP2PDeviceInfo* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PGroupBssid: + status |= dot11fUnpackTlvP2PGroupBssid(pCtx, pBufRemaining, len, ( tDot11fTLVP2PGroupBssid* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PGroupId: + status |= dot11fUnpackTlvP2PGroupId(pCtx, pBufRemaining, len, ( tDot11fTLVP2PGroupId* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PGroupInfo: + status |= dot11fUnpackTlvP2PGroupInfo(pCtx, pBufRemaining, len, ( tDot11fTLVP2PGroupInfo* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PStatus: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVP2PStatus* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVP2PStatus*)(pFrm + pTlv->offset ))->status)); + break; + case SigTlvPrimaryDeviceType: + status |= dot11fUnpackTlvPrimaryDeviceType(pCtx, pBufRemaining, len, ( tDot11fTLVPrimaryDeviceType* )(pFrm + pTlv->offset )); + break; + case SigTlvRFBands: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVRFBands* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVRFBands*)(pFrm + pTlv->offset ))->bands)); + break; + case SigTlvRequestDeviceType: + status |= dot11fUnpackTlvRequestDeviceType(pCtx, pBufRemaining, len, ( tDot11fTLVRequestDeviceType* )(pFrm + pTlv->offset )); + break; + case SigTlvRequestType: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVRequestType* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVRequestType*)(pFrm + pTlv->offset ))->reqType)); + break; + case SigTlvResponseType: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVResponseType* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVResponseType*)(pFrm + pTlv->offset ))->resType)); + break; + case SigTlvSelectedRegistrar: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVSelectedRegistrar* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVSelectedRegistrar*)(pFrm + pTlv->offset ))->selected)); + break; + case SigTlvSelectedRegistrarConfigMethods: + status |= dot11fUnpackTlvCommonFunc2(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVSelectedRegistrarConfigMethods* )(pFrm + pTlv->offset ))->present), (tANI_U16*)&((( tDot11fTLVSelectedRegistrarConfigMethods*)(pFrm + pTlv->offset ))->methods)); + break; + case SigTlvSerialNumber: + status |= dot11fUnpackTlvSerialNumber(pCtx, pBufRemaining, len, ( tDot11fTLVSerialNumber* )(pFrm + pTlv->offset )); + break; + case SigTlvUUID_E: + status |= dot11fUnpackTlvUUID_E(pCtx, pBufRemaining, len, ( tDot11fTLVUUID_E* )(pFrm + pTlv->offset )); + break; + case SigTlvUUID_R: + status |= dot11fUnpackTlvUUID_R(pCtx, pBufRemaining, len, ( tDot11fTLVUUID_R* )(pFrm + pTlv->offset )); + break; + case SigTlvVendorExtension: + status |= dot11fUnpackTlvVendorExtension(pCtx, pBufRemaining, len, ( tDot11fTLVVendorExtension* )(pFrm + pTlv->offset )); + break; + case SigTlvVersion: + status |= dot11fUnpackTlvVersion(pCtx, pBufRemaining, len, ( tDot11fTLVVersion* )(pFrm + pTlv->offset )); + break; + case SigTlvWPSState: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVWPSState* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVWPSState*)(pFrm + pTlv->offset ))->state)); + break; + case SigTlvP2PInterface: + status |= dot11fUnpackTlvP2PInterface(pCtx, pBufRemaining, len, ( tDot11fTLVP2PInterface* )(pFrm + pTlv->offset )); + break; + case SigTlvP2PManageability: + status |= dot11fUnpackTlvCommonFunc(pCtx, pBufRemaining, len, (tANI_U8*)&((( tDot11fTLVP2PManageability* )(pFrm + pTlv->offset ))->present), (tANI_U8*)&((( tDot11fTLVP2PManageability*)(pFrm + pTlv->offset ))->manageability)); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR: I" + " don't know about the TLV signature %d-- thi" + "s is most likely a 'framesc' bug.\n"), + pTlv->sig); + FRAMES_DBG_BREAK(); + return DOT11F_INTERNAL_ERROR; + } // End switch on sig. + } // End if on length check. + + } + else + { + FRAMES_LOG2(pCtx, FRLOG3, FRFL("Skipping unknown TLV %d (" + "length %d)\n"), id, len); + FRAMES_DUMP(pCtx, FRLOG3, pBufRemaining - (pTlv->sType + pTlv->sLen), len); + status |= DOT11F_UNKNOWN_TLVS; + } + + // Advance to the next TLV + pBufRemaining += len; + + if (len > nBufRemaining) + { + FRAMES_LOG0(pCtx, FRLOGW, FRFL("This TLV extends past th" + "e buffer as it was defined to us. This could mean " + "a corrupt frame, or just an incorrect length parame" + "ter.\n")); + FRAMES_DBG_BREAK(); + status |= DOT11F_LAST_TLV_TOO_LONG; + goto MandatoryCheck; + } + + nBufRemaining -= len; + + } // End iteration over TLVs. + +MandatoryCheck: + pTlv = &TLVs[0]; + while (0xffff != pTlv->id) + { + if (pTlv->fMandatory) + { + pfFound = (tANI_U8*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if (!*pfFound) + { + FRAMES_LOG1(pCtx, FRLOGW, FRFL("ERROR: The mandatory " + "TLV %s wasn't seen.\n"), + pTlv->name); + FRAMES_DBG_BREAK(); + status |= DOT11F_MANDATORY_TLV_MISSING; + } + + } + ++pTlv; + } + + return status; +} /* End UnpacTlvkCore. */ +tANI_U32 dot11fGetPackedIETCLAS(tpAniSirGlobal pCtx, tDot11fIETCLAS *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + switch (pIe->classifier_type) + { + case 0: + *pnNeeded += 6; + *pnNeeded += 6; + *pnNeeded += 2; + break; + case 1: + *pnNeeded += 1; + switch (pIe->info.IpParams.version) + { + case 4: + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6: + *pnNeeded += 16; + *pnNeeded += 16; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 3; + break; + } + break; + case 2: + *pnNeeded += 2; + break; + } + break; + } + return status; +} /* End dot11fGetPackedIETCLAS. */ + +tANI_U32 dot11fGetPackedIEWMMTCLAS(tpAniSirGlobal pCtx, tDot11fIEWMMTCLAS *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + switch (pIe->classifier_type) + { + case 0: + *pnNeeded += 6; + *pnNeeded += 6; + *pnNeeded += 2; + break; + case 1: + *pnNeeded += 1; + switch (pIe->info.IpParams.version) + { + case 4: + *pnNeeded += 4; + *pnNeeded += 4; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 6: + *pnNeeded += 16; + *pnNeeded += 16; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 3; + break; + } + break; + case 2: + *pnNeeded += 2; + break; + } + break; + } + return status; +} /* End dot11fGetPackedIEWMMTCLAS. */ + +tANI_U32 dot11fGetPackedIEAirgo(tpAniSirGlobal pCtx, tDot11fIEAirgo *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_Airgo); + break; + } + return status; +} /* End dot11fGetPackedIEAirgo. */ + +tANI_U32 dot11fGetPackedIECountry(tpAniSirGlobal pCtx, tDot11fIECountry *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 3; + if ( pIe->num_triplets ) + { + *pnNeeded += ( pIe->num_triplets * 3 ); + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIECountry. */ + +tANI_U32 dot11fGetPackedIEFTInfo(tpAniSirGlobal pCtx, tDot11fIEFTInfo *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + *pnNeeded += 16; + *pnNeeded += 32; + *pnNeeded += 32; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_FTInfo); + break; + } + return status; +} /* End dot11fGetPackedIEFTInfo. */ + +tANI_U32 dot11fGetPackedIEMeasurementReport(tpAniSirGlobal pCtx, tDot11fIEMeasurementReport *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + if ( pIe->type ) + { + switch (pIe->type) + { + case 0: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + break; + case 1: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + break; + case 2: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + break; + case 5: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 6; + *pnNeeded += 1; + *pnNeeded += 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_reportBeacon); + break; + } + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIEMeasurementReport. */ + +tANI_U32 dot11fGetPackedIEMeasurementRequest(tpAniSirGlobal pCtx, tDot11fIEMeasurementRequest *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + switch (pIe->measurement_type) + { + case 0: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + break; + case 1: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + break; + case 2: + *pnNeeded += 1; + *pnNeeded += 8; + *pnNeeded += 2; + break; + case 5: + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_measurement_requestBeacon); + break; + } + break; + } + return status; +} /* End dot11fGetPackedIEMeasurementRequest. */ + +tANI_U32 dot11fGetPackedIENeighborReport(tpAniSirGlobal pCtx, tDot11fIENeighborReport *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 6; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 2; + *pnNeeded += 1; + *pnNeeded += 1; + *pnNeeded += 1; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_NeighborReport); + break; + } + return status; +} /* End dot11fGetPackedIENeighborReport. */ + +tANI_U32 dot11fGetPackedIEP2PAssocReq(tpAniSirGlobal pCtx, tDot11fIEP2PAssocReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PAssocReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PAssocReq. */ + +tANI_U32 dot11fGetPackedIEP2PAssocRes(tpAniSirGlobal pCtx, tDot11fIEP2PAssocRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PAssocRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PAssocRes. */ + +tANI_U32 dot11fGetPackedIEP2PBeacon(tpAniSirGlobal pCtx, tDot11fIEP2PBeacon *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PBeacon); + break; + } + return status; +} /* End dot11fGetPackedIEP2PBeacon. */ + +tANI_U32 dot11fGetPackedIEP2PBeaconProbeRes(tpAniSirGlobal pCtx, tDot11fIEP2PBeaconProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PBeaconProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PBeaconProbeRes. */ + +tANI_U32 dot11fGetPackedIEP2PDeAuth(tpAniSirGlobal pCtx, tDot11fIEP2PDeAuth *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDeAuth); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDeAuth. */ + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fIEP2PDeviceDiscoverabilityReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDeviceDiscoverabilityReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDeviceDiscoverabilityReq. */ + +tANI_U32 dot11fGetPackedIEP2PDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tDot11fIEP2PDeviceDiscoverabilityRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDeviceDiscoverabilityRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDeviceDiscoverabilityRes. */ + +tANI_U32 dot11fGetPackedIEP2PDisAssoc(tpAniSirGlobal pCtx, tDot11fIEP2PDisAssoc *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PDisAssoc); + break; + } + return status; +} /* End dot11fGetPackedIEP2PDisAssoc. */ + +tANI_U32 dot11fGetPackedIEP2PGONegCnf(tpAniSirGlobal pCtx, tDot11fIEP2PGONegCnf *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegCnf); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegCnf. */ + +tANI_U32 dot11fGetPackedIEP2PGONegReq(tpAniSirGlobal pCtx, tDot11fIEP2PGONegReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegReq. */ + +tANI_U32 dot11fGetPackedIEP2PGONegRes(tpAniSirGlobal pCtx, tDot11fIEP2PGONegRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegRes. */ + +tANI_U32 dot11fGetPackedIEP2PGONegWPS(tpAniSirGlobal pCtx, tDot11fIEP2PGONegWPS *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PGONegWPS); + break; + } + return status; +} /* End dot11fGetPackedIEP2PGONegWPS. */ + +tANI_U32 dot11fGetPackedIEP2PInvitationReq(tpAniSirGlobal pCtx, tDot11fIEP2PInvitationReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PInvitationReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PInvitationReq. */ + +tANI_U32 dot11fGetPackedIEP2PInvitationRes(tpAniSirGlobal pCtx, tDot11fIEP2PInvitationRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PInvitationRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PInvitationRes. */ + +tANI_U32 dot11fGetPackedIEP2PNoticeOfAbsence(tpAniSirGlobal pCtx, tDot11fIEP2PNoticeOfAbsence *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PNoticeOfAbsence); + break; + } + return status; +} /* End dot11fGetPackedIEP2PNoticeOfAbsence. */ + +tANI_U32 dot11fGetPackedIEP2PPresenceResponse(tpAniSirGlobal pCtx, tDot11fIEP2PPresenceResponse *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PPresenceResponse); + break; + } + return status; +} /* End dot11fGetPackedIEP2PPresenceResponse. */ + +tANI_U32 dot11fGetPackedIEP2PProbeReq(tpAniSirGlobal pCtx, tDot11fIEP2PProbeReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PProbeReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PProbeReq. */ + +tANI_U32 dot11fGetPackedIEP2PProbeRes(tpAniSirGlobal pCtx, tDot11fIEP2PProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PProbeRes. */ + +tANI_U32 dot11fGetPackedIEP2PProvisionDiscoveryReq(tpAniSirGlobal pCtx, tDot11fIEP2PProvisionDiscoveryReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PProvisionDiscoveryReq); + break; + } + return status; +} /* End dot11fGetPackedIEP2PProvisionDiscoveryReq. */ + +tANI_U32 dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(tpAniSirGlobal pCtx, tDot11fIEP2PWSCProvisionDiscoveryRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_P2PWSCProvisionDiscoveryRes); + break; + } + return status; +} /* End dot11fGetPackedIEP2PWSCProvisionDiscoveryRes. */ + +tANI_U32 dot11fGetPackedIERICDataDesc(tpAniSirGlobal pCtx, tDot11fIERICDataDesc *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pIe, pnNeeded, IES_RICDataDesc); + break; + } + return status; +} /* End dot11fGetPackedIERICDataDesc. */ + +tANI_U32 dot11fGetPackedIERSN(tpAniSirGlobal pCtx, tDot11fIERSN *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + *pnNeeded += 4; + if ( pIe->pwise_cipher_suite_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->pwise_cipher_suite_count * 4 ); + if ( pIe->akm_suite_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->akm_suite_count * 4 ); + if ( pIe->RSN_Cap ) + { + *pnNeeded += 2; + } + else break; + if ( pIe->pmkid_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->pmkid_count * 16 ); + if ( pIe->gp_mgmt_cipher_suite ) + { + *pnNeeded += 4; + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIERSN. */ + +tANI_U32 dot11fGetPackedIEWAPI(tpAniSirGlobal pCtx, tDot11fIEWAPI *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + *pnNeeded += 2; + *pnNeeded += ( pIe->akm_suite_count * 4 ); + *pnNeeded += 2; + *pnNeeded += ( pIe->unicast_cipher_suite_count * 4 ); + *pnNeeded += 4; + *pnNeeded += 2; + if ( pIe->bkid_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->bkid_count * 16 ); + break; + } + return status; +} /* End dot11fGetPackedIEWAPI. */ + +tANI_U32 dot11fGetPackedIEWPA(tpAniSirGlobal pCtx, tDot11fIEWPA *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 2; + if ( pIe->multicast_cipher_present ) + { + *pnNeeded += 4; + } + else break; + if ( pIe->unicast_cipher_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->unicast_cipher_count * 4 ); + if ( pIe->auth_suite_count ) + { + *pnNeeded += 2; + } + else break; + *pnNeeded += ( pIe->auth_suite_count * 4 ); + if ( pIe->caps ) + { + *pnNeeded += 2; + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIEWPA. */ + +tANI_U32 dot11fGetPackedIEWSC(tpAniSirGlobal pCtx, tDot11fIEWSC *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WSC); + break; + } + return status; +} /* End dot11fGetPackedIEWSC. */ + +tANI_U32 dot11fGetPackedIEWscAssocReq(tpAniSirGlobal pCtx, tDot11fIEWscAssocReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscAssocReq); + break; + } + return status; +} /* End dot11fGetPackedIEWscAssocReq. */ + +tANI_U32 dot11fGetPackedIEWscAssocRes(tpAniSirGlobal pCtx, tDot11fIEWscAssocRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscAssocRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscAssocRes. */ + +tANI_U32 dot11fGetPackedIEWscBeacon(tpAniSirGlobal pCtx, tDot11fIEWscBeacon *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscBeacon); + break; + } + return status; +} /* End dot11fGetPackedIEWscBeacon. */ + +tANI_U32 dot11fGetPackedIEWscBeaconProbeRes(tpAniSirGlobal pCtx, tDot11fIEWscBeaconProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscBeaconProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscBeaconProbeRes. */ + +tANI_U32 dot11fGetPackedIEWscProbeReq(tpAniSirGlobal pCtx, tDot11fIEWscProbeReq *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscProbeReq); + break; + } + return status; +} /* End dot11fGetPackedIEWscProbeReq. */ + +tANI_U32 dot11fGetPackedIEWscProbeRes(tpAniSirGlobal pCtx, tDot11fIEWscProbeRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscProbeRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscProbeRes. */ + +tANI_U32 dot11fGetPackedIEWscReassocRes(tpAniSirGlobal pCtx, tDot11fIEWscReassocRes *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + status = GetPackedSizeTlvCore(pCtx,(tANI_U8*)pIe,pnNeeded,TLVS_WscReassocRes); + break; + } + return status; +} /* End dot11fGetPackedIEWscReassocRes. */ + +tANI_U32 dot11fGetPackedIEhs20vendor_ie(tpAniSirGlobal pCtx, tDot11fIEhs20vendor_ie *pIe, tANI_U32 *pnNeeded) +{ + tANI_U32 status = DOT11F_PARSE_SUCCESS; + (void)pCtx; + while ( pIe->present ) + { + *pnNeeded += 1; + if ( pIe->hs_id_present ) + { + switch (pIe->hs_id_present) + { + case 1: + *pnNeeded += 2; + break; + case 2: + *pnNeeded += 2; + break; + } + } + else break; + break; + } + return status; +} /* End dot11fGetPackedIEhs20vendor_ie. */ + +tANI_U32 dot11fGetPackedAddBAReqSize(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 9; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddBAReq); + return status; +} /* End dot11fGetPackedAddBAReqSize. */ + +tANI_U32 dot11fGetPackedAddBARspSize(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 9; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddBARsp); + return status; +} /* End dot11fGetPackedAddBARspSize. */ + +tANI_U32 dot11fGetPackedAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddTSRequest); + return status; +} /* End dot11fGetPackedAddTSRequestSize. */ + +tANI_U32 dot11fGetPackedAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AddTSResponse); + return status; +} /* End dot11fGetPackedAddTSResponseSize. */ + +tANI_U32 dot11fGetPackedAssocRequestSize(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AssocRequest); + return status; +} /* End dot11fGetPackedAssocRequestSize. */ + +tANI_U32 dot11fGetPackedAssocResponseSize(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_AssocResponse); + return status; +} /* End dot11fGetPackedAssocResponseSize. */ + +tANI_U32 dot11fGetPackedAuthenticationSize(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Authentication); + return status; +} /* End dot11fGetPackedAuthenticationSize. */ + +tANI_U32 dot11fGetPackedBeaconSize(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 12; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Beacon); + return status; +} /* End dot11fGetPackedBeaconSize. */ + +tANI_U32 dot11fGetPackedBeacon1Size(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 12; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Beacon1); + return status; +} /* End dot11fGetPackedBeacon1Size. */ + +tANI_U32 dot11fGetPackedBeacon2Size(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 0; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Beacon2); + return status; +} /* End dot11fGetPackedBeacon2Size. */ + +tANI_U32 dot11fGetPackedBeaconIEsSize(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 0; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_BeaconIEs); + return status; +} /* End dot11fGetPackedBeaconIEsSize. */ + +tANI_U32 dot11fGetPackedChannelSwitchSize(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ChannelSwitch); + return status; +} /* End dot11fGetPackedChannelSwitchSize. */ + +tANI_U32 dot11fGetPackedDeAuthSize(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DeAuth); + return status; +} /* End dot11fGetPackedDeAuthSize. */ + +tANI_U32 dot11fGetPackedDelBAIndSize(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DelBAInd); + return status; +} /* End dot11fGetPackedDelBAIndSize. */ + +tANI_U32 dot11fGetPackedDelTSSize(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DelTS); + return status; +} /* End dot11fGetPackedDelTSSize. */ + +tANI_U32 dot11fGetPackedDeviceDiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DeviceDiscoverabilityReq); + return status; +} /* End dot11fGetPackedDeviceDiscoverabilityReqSize. */ + +tANI_U32 dot11fGetPackedDeviceDiscoverabilityResSize(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_DeviceDiscoverabilityRes); + return status; +} /* End dot11fGetPackedDeviceDiscoverabilityResSize. */ + +tANI_U32 dot11fGetPackedDisassociationSize(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_Disassociation); + return status; +} /* End dot11fGetPackedDisassociationSize. */ + +tANI_U32 dot11fGetPackedGODiscoverabilityReqSize(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GODiscoverabilityReq); + return status; +} /* End dot11fGetPackedGODiscoverabilityReqSize. */ + +tANI_U32 dot11fGetPackedGONegCnfSize(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GONegCnf); + return status; +} /* End dot11fGetPackedGONegCnfSize. */ + +tANI_U32 dot11fGetPackedGONegReqSize(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GONegReq); + return status; +} /* End dot11fGetPackedGONegReqSize. */ + +tANI_U32 dot11fGetPackedGONegResSize(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_GONegRes); + return status; +} /* End dot11fGetPackedGONegResSize. */ + +tANI_U32 dot11fGetPackedHT2040BSSCoexistenceManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_HT2040BSSCoexistenceManagementActionFrame); + return status; +} /* End dot11fGetPackedHT2040BSSCoexistenceManagementActionFrameSize. */ + +tANI_U32 dot11fGetPackedInvitationReqSize(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_InvitationReq); + return status; +} /* End dot11fGetPackedInvitationReqSize. */ + +tANI_U32 dot11fGetPackedInvitationResSize(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_InvitationRes); + return status; +} /* End dot11fGetPackedInvitationResSize. */ + +tANI_U32 dot11fGetPackedLinkMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 11; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_LinkMeasurementReport); + return status; +} /* End dot11fGetPackedLinkMeasurementReportSize. */ + +tANI_U32 dot11fGetPackedLinkMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_LinkMeasurementRequest); + return status; +} /* End dot11fGetPackedLinkMeasurementRequestSize. */ + +tANI_U32 dot11fGetPackedMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_MeasurementReport); + return status; +} /* End dot11fGetPackedMeasurementReportSize. */ + +tANI_U32 dot11fGetPackedMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_MeasurementRequest); + return status; +} /* End dot11fGetPackedMeasurementRequestSize. */ + +tANI_U32 dot11fGetPackedNeighborReportRequestSize(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_NeighborReportRequest); + return status; +} /* End dot11fGetPackedNeighborReportRequestSize. */ + +tANI_U32 dot11fGetPackedNeighborReportResponseSize(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_NeighborReportResponse); + return status; +} /* End dot11fGetPackedNeighborReportResponseSize. */ + +tANI_U32 dot11fGetPackedNoticeOfAbsSize(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_NoticeOfAbs); + return status; +} /* End dot11fGetPackedNoticeOfAbsSize. */ + +tANI_U32 dot11fGetPackedOperatingModeSize(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_OperatingMode); + return status; +} /* End dot11fGetPackedOperatingModeSize. */ + +tANI_U32 dot11fGetPackedPresenceReqSize(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_PresenceReq); + return status; +} /* End dot11fGetPackedPresenceReqSize. */ + +tANI_U32 dot11fGetPackedPresenceResSize(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_PresenceRes); + return status; +} /* End dot11fGetPackedPresenceResSize. */ + +tANI_U32 dot11fGetPackedProbeRequestSize(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 0; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProbeRequest); + return status; +} /* End dot11fGetPackedProbeRequestSize. */ + +tANI_U32 dot11fGetPackedProbeResponseSize(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 12; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProbeResponse); + return status; +} /* End dot11fGetPackedProbeResponseSize. */ + +tANI_U32 dot11fGetPackedProvisionDiscoveryReqSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProvisionDiscoveryReq); + return status; +} /* End dot11fGetPackedProvisionDiscoveryReqSize. */ + +tANI_U32 dot11fGetPackedProvisionDiscoveryResSize(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 8; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ProvisionDiscoveryRes); + return status; +} /* End dot11fGetPackedProvisionDiscoveryResSize. */ + +tANI_U32 dot11fGetPackedQosMapConfigureSize(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 2; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_QosMapConfigure); + return status; +} /* End dot11fGetPackedQosMapConfigureSize. */ + +tANI_U32 dot11fGetPackedRMCSize(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 22; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_RMC); + return status; +} /* End dot11fGetPackedRMCSize. */ + +tANI_U32 dot11fGetPackedRadioMeasurementReportSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_RadioMeasurementReport); + return status; +} /* End dot11fGetPackedRadioMeasurementReportSize. */ + +tANI_U32 dot11fGetPackedRadioMeasurementRequestSize(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_RadioMeasurementRequest); + return status; +} /* End dot11fGetPackedRadioMeasurementRequestSize. */ + +tANI_U32 dot11fGetPackedReAssocRequestSize(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 10; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ReAssocRequest); + return status; +} /* End dot11fGetPackedReAssocRequestSize. */ + +tANI_U32 dot11fGetPackedReAssocResponseSize(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 6; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_ReAssocResponse); + return status; +} /* End dot11fGetPackedReAssocResponseSize. */ + +tANI_U32 dot11fGetPackedSMPowerSaveSize(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_SMPowerSave); + return status; +} /* End dot11fGetPackedSMPowerSaveSize. */ + +tANI_U32 dot11fGetPackedSaQueryReqSize(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_SaQueryReq); + return status; +} /* End dot11fGetPackedSaQueryReqSize. */ + +tANI_U32 dot11fGetPackedSaQueryRspSize(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_SaQueryRsp); + return status; +} /* End dot11fGetPackedSaQueryRspSize. */ + +tANI_U32 dot11fGetPackedTDLSDisReqSize(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSDisReq); + return status; +} /* End dot11fGetPackedTDLSDisReqSize. */ + +tANI_U32 dot11fGetPackedTDLSDisRspSize(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSDisRsp); + return status; +} /* End dot11fGetPackedTDLSDisRspSize. */ + +tANI_U32 dot11fGetPackedTDLSPeerTrafficIndSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSPeerTrafficInd); + return status; +} /* End dot11fGetPackedTDLSPeerTrafficIndSize. */ + +tANI_U32 dot11fGetPackedTDLSPeerTrafficRspSize(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSPeerTrafficRsp); + return status; +} /* End dot11fGetPackedTDLSPeerTrafficRspSize. */ + +tANI_U32 dot11fGetPackedTDLSSetupCnfSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSSetupCnf); + return status; +} /* End dot11fGetPackedTDLSSetupCnfSize. */ + +tANI_U32 dot11fGetPackedTDLSSetupReqSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 5; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSSetupReq); + return status; +} /* End dot11fGetPackedTDLSSetupReqSize. */ + +tANI_U32 dot11fGetPackedTDLSSetupRspSize(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 7; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSSetupRsp); + return status; +} /* End dot11fGetPackedTDLSSetupRspSize. */ + +tANI_U32 dot11fGetPackedTDLSTeardownSize(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TDLSTeardown); + return status; +} /* End dot11fGetPackedTDLSTeardownSize. */ + +tANI_U32 dot11fGetPackedTPCReportSize(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TPCReport); + return status; +} /* End dot11fGetPackedTPCReportSize. */ + +tANI_U32 dot11fGetPackedTPCRequestSize(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 3; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_TPCRequest); + return status; +} /* End dot11fGetPackedTPCRequestSize. */ + +tANI_U32 dot11fGetPackedVHTGidManagementActionFrameSize(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 26; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_VHTGidManagementActionFrame); + return status; +} /* End dot11fGetPackedVHTGidManagementActionFrameSize. */ + +tANI_U32 dot11fGetPackedWMMAddTSRequestSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_WMMAddTSRequest); + return status; +} /* End dot11fGetPackedWMMAddTSRequestSize. */ + +tANI_U32 dot11fGetPackedWMMAddTSResponseSize(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_WMMAddTSResponse); + return status; +} /* End dot11fGetPackedWMMAddTSResponseSize. */ + +tANI_U32 dot11fGetPackedWMMDelTSSize(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U32 *pnNeeded) +{ + tANI_U32 status = 0; + *pnNeeded = 4; + status = GetPackedSizeCore(pCtx, ( tANI_U8* )pFrm, pnNeeded, IES_WMMDelTS); + return status; +} /* End dot11fGetPackedWMMDelTSSize. */ + +static tANI_U32 GetPackedSizeCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tIEDefn IEs[]) +{ + const tIEDefn *pIe; + tANI_U16 i, n; + tANI_U32 status; + tFRAMES_BOOL *pfFound; + tANI_U32 countOffset = 0; + tANI_U32 byteCount = 0; + tANI_U8 pIePresent = 0; + tANI_U32 offset = 0; + + status = DOT11F_PARSE_SUCCESS; + + (void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */ + i=0; n=0; + pIe = &( IEs[0] ); + while ( 0xff != pIe->eid ) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pIe->offset + + pIe->presenceOffset); + if ( *pfFound ) + { + countOffset = ((0 == pIe->arraybound) ? 1 : (*( tANI_U16* )(pFrm + pIe->countOffset)) ); + for (i = 0U; i < countOffset; ++i) + { + *pnNeeded += 2U + pIe->noui; + byteCount = 0; + switch (pIe->sig) + { + case SigIeAPName: + offset = sizeof(tDot11fIEAPName); + byteCount = ((tDot11fIEAPName* )(pFrm + pIe->offset + sizeof(tDot11fIEAPName) * i ))->num_name; + pIePresent = ( (tDot11fIEAPName* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBPIndicator: + offset = sizeof(tDot11fIEBPIndicator); + byteCount = 2; + pIePresent = ( (tDot11fIEBPIndicator* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeCondensedCountryStr: + offset = sizeof(tDot11fIECondensedCountryStr); + byteCount = 2; + pIePresent = ( (tDot11fIECondensedCountryStr* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeGTK: + offset = sizeof(tDot11fIEGTK); + byteCount = ((tDot11fIEGTK* )(pFrm + pIe->offset + sizeof(tDot11fIEGTK) * i ))->num_key + 11; + pIePresent = ( (tDot11fIEGTK* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHCF: + offset = sizeof(tDot11fIEHCF); + byteCount = 1; + pIePresent = ( (tDot11fIEHCF* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeIGTK: + offset = sizeof(tDot11fIEIGTK); + byteCount = 33; + pIePresent = ( (tDot11fIEIGTK* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLLAttr: + offset = sizeof(tDot11fIELLAttr); + byteCount = 4; + pIePresent = ( (tDot11fIELLAttr* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLoadBalance: + offset = sizeof(tDot11fIELoadBalance); + byteCount = 7; + pIePresent = ( (tDot11fIELoadBalance* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLoadInfo: + offset = sizeof(tDot11fIELoadInfo); + byteCount = 4; + pIePresent = ( (tDot11fIELoadInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropAssocType: + offset = sizeof(tDot11fIEPropAssocType); + byteCount = 1; + pIePresent = ( (tDot11fIEPropAssocType* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropCapability: + offset = sizeof(tDot11fIEPropCapability); + byteCount = 2; + pIePresent = ( (tDot11fIEPropCapability* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropChannSwitchAnn: + offset = sizeof(tDot11fIEPropChannSwitchAnn); + byteCount = 4; + pIePresent = ( (tDot11fIEPropChannSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropEDCAParams: + offset = sizeof(tDot11fIEPropEDCAParams); + byteCount = 18; + pIePresent = ( (tDot11fIEPropEDCAParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropQuietBSS: + offset = sizeof(tDot11fIEPropQuietBSS); + byteCount = 6; + pIePresent = ( (tDot11fIEPropQuietBSS* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePropSuppRates: + offset = sizeof(tDot11fIEPropSuppRates); + byteCount = ((tDot11fIEPropSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEPropSuppRates) * i ))->num_rates; + pIePresent = ( (tDot11fIEPropSuppRates* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeR0KH_ID: + offset = sizeof(tDot11fIER0KH_ID); + byteCount = ((tDot11fIER0KH_ID* )(pFrm + pIe->offset + sizeof(tDot11fIER0KH_ID) * i ))->num_PMK_R0_ID; + pIePresent = ( (tDot11fIER0KH_ID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeR1KH_ID: + offset = sizeof(tDot11fIER1KH_ID); + byteCount = 6; + pIePresent = ( (tDot11fIER1KH_ID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTSFInfo: + offset = sizeof(tDot11fIETSFInfo); + byteCount = 4; + pIePresent = ( (tDot11fIETSFInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTaurus: + offset = sizeof(tDot11fIETaurus); + byteCount = 6; + pIePresent = ( (tDot11fIETaurus* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTitan: + offset = sizeof(tDot11fIETitan); + byteCount = 4; + pIePresent = ( (tDot11fIETitan* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTriggerStaBgScan: + offset = sizeof(tDot11fIETriggerStaBgScan); + byteCount = 1; + pIePresent = ( (tDot11fIETriggerStaBgScan* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVersion: + offset = sizeof(tDot11fIEVersion); + byteCount = ((tDot11fIEVersion* )(pFrm + pIe->offset + sizeof(tDot11fIEVersion) * i ))->num_build_version + 5; + pIePresent = ( (tDot11fIEVersion* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWDS: + offset = sizeof(tDot11fIEWDS); + byteCount = ((tDot11fIEWDS* )(pFrm + pIe->offset + sizeof(tDot11fIEWDS) * i ))->num_wdsData; + pIePresent = ( (tDot11fIEWDS* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeAPChannelReport: + offset = sizeof(tDot11fIEAPChannelReport); + byteCount = ((tDot11fIEAPChannelReport* )(pFrm + pIe->offset + sizeof(tDot11fIEAPChannelReport) * i ))->num_channelList + 1; + pIePresent = ( (tDot11fIEAPChannelReport* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBcnReportingDetail: + offset = sizeof(tDot11fIEBcnReportingDetail); + byteCount = 1; + pIePresent = ( (tDot11fIEBcnReportingDetail* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBeaconReportFrmBody: + offset = sizeof(tDot11fIEBeaconReportFrmBody); + byteCount = ((tDot11fIEBeaconReportFrmBody* )(pFrm + pIe->offset + sizeof(tDot11fIEBeaconReportFrmBody) * i ))->num_reportedFields; + pIePresent = ( (tDot11fIEBeaconReportFrmBody* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeBeaconReporting: + offset = sizeof(tDot11fIEBeaconReporting); + byteCount = 2; + pIePresent = ( (tDot11fIEBeaconReporting* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeMeasurementPilot: + offset = sizeof(tDot11fIEMeasurementPilot); + byteCount = ((tDot11fIEMeasurementPilot* )(pFrm + pIe->offset + sizeof(tDot11fIEMeasurementPilot) * i ))->num_vendorSpecific + 1; + pIePresent = ( (tDot11fIEMeasurementPilot* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeMultiBssid: + offset = sizeof(tDot11fIEMultiBssid); + byteCount = ((tDot11fIEMultiBssid* )(pFrm + pIe->offset + sizeof(tDot11fIEMultiBssid) * i ))->num_vendorSpecific + 1; + pIePresent = ( (tDot11fIEMultiBssid* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRICData: + offset = sizeof(tDot11fIERICData); + byteCount = 4; + pIePresent = ( (tDot11fIERICData* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRICDescriptor: + offset = sizeof(tDot11fIERICDescriptor); + byteCount = ((tDot11fIERICDescriptor* )(pFrm + pIe->offset + sizeof(tDot11fIERICDescriptor) * i ))->num_variableData + 1; + pIePresent = ( (tDot11fIERICDescriptor* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRRMEnabledCap: + offset = sizeof(tDot11fIERRMEnabledCap); + byteCount = 5; + pIePresent = ( (tDot11fIERRMEnabledCap* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRequestedInfo: + offset = sizeof(tDot11fIERequestedInfo); + byteCount = ((tDot11fIERequestedInfo* )(pFrm + pIe->offset + sizeof(tDot11fIERequestedInfo) * i ))->num_requested_eids; + pIePresent = ( (tDot11fIERequestedInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSSID: + offset = sizeof(tDot11fIESSID); + byteCount = ((tDot11fIESSID* )(pFrm + pIe->offset + sizeof(tDot11fIESSID) * i ))->num_ssid; + pIePresent = ( (tDot11fIESSID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSchedule: + offset = sizeof(tDot11fIESchedule); + byteCount = 14; + pIePresent = ( (tDot11fIESchedule* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTCLAS: + offset = sizeof(tDot11fIETCLAS); + status |= dot11fGetPackedIETCLAS(pCtx, ( tDot11fIETCLAS* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeTCLASSPROC: + offset = sizeof(tDot11fIETCLASSPROC); + byteCount = 1; + pIePresent = ( (tDot11fIETCLASSPROC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTSDelay: + offset = sizeof(tDot11fIETSDelay); + byteCount = 4; + pIePresent = ( (tDot11fIETSDelay* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTSPEC: + offset = sizeof(tDot11fIETSPEC); + byteCount = 55; + pIePresent = ( (tDot11fIETSPEC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMSchedule: + offset = sizeof(tDot11fIEWMMSchedule); + byteCount = 15; + pIePresent = ( (tDot11fIEWMMSchedule* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMTCLAS: + offset = sizeof(tDot11fIEWMMTCLAS); + status |= dot11fGetPackedIEWMMTCLAS(pCtx, ( tDot11fIEWMMTCLAS* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWMMTCLASPROC: + offset = sizeof(tDot11fIEWMMTCLASPROC); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMTCLASPROC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMTSDelay: + offset = sizeof(tDot11fIEWMMTSDelay); + byteCount = 5; + pIePresent = ( (tDot11fIEWMMTSDelay* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMTSPEC: + offset = sizeof(tDot11fIEWMMTSPEC); + byteCount = 56; + pIePresent = ( (tDot11fIEWMMTSPEC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeAID: + offset = sizeof(tDot11fIEAID); + byteCount = 2; + pIePresent = ( (tDot11fIEAID* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeAirgo: + offset = sizeof(tDot11fIEAirgo); + status |= dot11fGetPackedIEAirgo(pCtx, ( tDot11fIEAirgo* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeCFParams: + offset = sizeof(tDot11fIECFParams); + byteCount = 6; + pIePresent = ( (tDot11fIECFParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeChallengeText: + offset = sizeof(tDot11fIEChallengeText); + byteCount = ((tDot11fIEChallengeText* )(pFrm + pIe->offset + sizeof(tDot11fIEChallengeText) * i ))->num_text; + pIePresent = ( (tDot11fIEChallengeText* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeChanSwitchAnn: + offset = sizeof(tDot11fIEChanSwitchAnn); + byteCount = 3; + pIePresent = ( (tDot11fIEChanSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeCountry: + offset = sizeof(tDot11fIECountry); + status |= dot11fGetPackedIECountry(pCtx, ( tDot11fIECountry* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeDSParams: + offset = sizeof(tDot11fIEDSParams); + byteCount = 1; + pIePresent = ( (tDot11fIEDSParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeEDCAParamSet: + offset = sizeof(tDot11fIEEDCAParamSet); + byteCount = 18; + pIePresent = ( (tDot11fIEEDCAParamSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeERPInfo: + offset = sizeof(tDot11fIEERPInfo); + byteCount = 1; + pIePresent = ( (tDot11fIEERPInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESECckmOpaque: + offset = sizeof(tDot11fIEESECckmOpaque); + byteCount = ((tDot11fIEESECckmOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEESECckmOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEESECckmOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESERadMgmtCap: + offset = sizeof(tDot11fIEESERadMgmtCap); + byteCount = 2; + pIePresent = ( (tDot11fIEESERadMgmtCap* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESETrafStrmMet: + offset = sizeof(tDot11fIEESETrafStrmMet); + byteCount = 4; + pIePresent = ( (tDot11fIEESETrafStrmMet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESETrafStrmRateSet: + offset = sizeof(tDot11fIEESETrafStrmRateSet); + byteCount = ((tDot11fIEESETrafStrmRateSet* )(pFrm + pIe->offset + sizeof(tDot11fIEESETrafStrmRateSet) * i ))->num_tsrates + 1; + pIePresent = ( (tDot11fIEESETrafStrmRateSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESETxmitPower: + offset = sizeof(tDot11fIEESETxmitPower); + byteCount = 2; + pIePresent = ( (tDot11fIEESETxmitPower* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeESEVersion: + offset = sizeof(tDot11fIEESEVersion); + byteCount = 1; + pIePresent = ( (tDot11fIEESEVersion* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeExtCap: + offset = sizeof(tDot11fIEExtCap); + byteCount = ((tDot11fIEExtCap* )(pFrm + pIe->offset + sizeof(tDot11fIEExtCap) * i ))->num_bytes; + pIePresent = ( (tDot11fIEExtCap* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeExtChanSwitchAnn: + offset = sizeof(tDot11fIEExtChanSwitchAnn); + byteCount = 1; + pIePresent = ( (tDot11fIEExtChanSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeExtSuppRates: + offset = sizeof(tDot11fIEExtSuppRates); + byteCount = ((tDot11fIEExtSuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIEExtSuppRates) * i ))->num_rates; + pIePresent = ( (tDot11fIEExtSuppRates* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFHParamSet: + offset = sizeof(tDot11fIEFHParamSet); + byteCount = 5; + pIePresent = ( (tDot11fIEFHParamSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFHParams: + offset = sizeof(tDot11fIEFHParams); + byteCount = 2; + pIePresent = ( (tDot11fIEFHParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFHPattTable: + offset = sizeof(tDot11fIEFHPattTable); + byteCount = ((tDot11fIEFHPattTable* )(pFrm + pIe->offset + sizeof(tDot11fIEFHPattTable) * i ))->num_randtable + 4; + pIePresent = ( (tDot11fIEFHPattTable* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeFTInfo: + offset = sizeof(tDot11fIEFTInfo); + status |= dot11fGetPackedIEFTInfo(pCtx, ( tDot11fIEFTInfo* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeHT2040BSSCoexistence: + offset = sizeof(tDot11fIEHT2040BSSCoexistence); + byteCount = 1; + pIePresent = ( (tDot11fIEHT2040BSSCoexistence* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHT2040BSSIntolerantReport: + offset = sizeof(tDot11fIEHT2040BSSIntolerantReport); + byteCount = ((tDot11fIEHT2040BSSIntolerantReport* )(pFrm + pIe->offset + sizeof(tDot11fIEHT2040BSSIntolerantReport) * i ))->num_channelList + 1; + pIePresent = ( (tDot11fIEHT2040BSSIntolerantReport* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHTCaps: + offset = sizeof(tDot11fIEHTCaps); + byteCount = ((tDot11fIEHTCaps* )(pFrm + pIe->offset + sizeof(tDot11fIEHTCaps) * i ))->num_rsvd + 26; + pIePresent = ( (tDot11fIEHTCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeHTInfo: + offset = sizeof(tDot11fIEHTInfo); + byteCount = ((tDot11fIEHTInfo* )(pFrm + pIe->offset + sizeof(tDot11fIEHTInfo) * i ))->num_rsvd + 22; + pIePresent = ( (tDot11fIEHTInfo* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeIBSSParams: + offset = sizeof(tDot11fIEIBSSParams); + byteCount = 2; + pIePresent = ( (tDot11fIEIBSSParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeLinkIdentifier: + offset = sizeof(tDot11fIELinkIdentifier); + byteCount = 18; + pIePresent = ( (tDot11fIELinkIdentifier* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeMeasurementReport: + offset = sizeof(tDot11fIEMeasurementReport); + status |= dot11fGetPackedIEMeasurementReport(pCtx, ( tDot11fIEMeasurementReport* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeMeasurementRequest: + offset = sizeof(tDot11fIEMeasurementRequest); + status |= dot11fGetPackedIEMeasurementRequest(pCtx, ( tDot11fIEMeasurementRequest* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeMobilityDomain: + offset = sizeof(tDot11fIEMobilityDomain); + byteCount = 3; + pIePresent = ( (tDot11fIEMobilityDomain* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeNeighborReport: + offset = sizeof(tDot11fIENeighborReport); + status |= dot11fGetPackedIENeighborReport(pCtx, ( tDot11fIENeighborReport* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeOBSSScanParameters: + offset = sizeof(tDot11fIEOBSSScanParameters); + byteCount = 14; + pIePresent = ( (tDot11fIEOBSSScanParameters* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeOperatingMode: + offset = sizeof(tDot11fIEOperatingMode); + byteCount = 1; + pIePresent = ( (tDot11fIEOperatingMode* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeP2PAssocReq: + offset = sizeof(tDot11fIEP2PAssocReq); + status |= dot11fGetPackedIEP2PAssocReq(pCtx, ( tDot11fIEP2PAssocReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PAssocRes: + offset = sizeof(tDot11fIEP2PAssocRes); + status |= dot11fGetPackedIEP2PAssocRes(pCtx, ( tDot11fIEP2PAssocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PBeacon: + offset = sizeof(tDot11fIEP2PBeacon); + status |= dot11fGetPackedIEP2PBeacon(pCtx, ( tDot11fIEP2PBeacon* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PBeaconProbeRes: + offset = sizeof(tDot11fIEP2PBeaconProbeRes); + status |= dot11fGetPackedIEP2PBeaconProbeRes(pCtx, ( tDot11fIEP2PBeaconProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDeAuth: + offset = sizeof(tDot11fIEP2PDeAuth); + status |= dot11fGetPackedIEP2PDeAuth(pCtx, ( tDot11fIEP2PDeAuth* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDeviceDiscoverabilityReq: + offset = sizeof(tDot11fIEP2PDeviceDiscoverabilityReq); + status |= dot11fGetPackedIEP2PDeviceDiscoverabilityReq(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDeviceDiscoverabilityRes: + offset = sizeof(tDot11fIEP2PDeviceDiscoverabilityRes); + status |= dot11fGetPackedIEP2PDeviceDiscoverabilityRes(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PDisAssoc: + offset = sizeof(tDot11fIEP2PDisAssoc); + status |= dot11fGetPackedIEP2PDisAssoc(pCtx, ( tDot11fIEP2PDisAssoc* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegCnf: + offset = sizeof(tDot11fIEP2PGONegCnf); + status |= dot11fGetPackedIEP2PGONegCnf(pCtx, ( tDot11fIEP2PGONegCnf* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegReq: + offset = sizeof(tDot11fIEP2PGONegReq); + status |= dot11fGetPackedIEP2PGONegReq(pCtx, ( tDot11fIEP2PGONegReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegRes: + offset = sizeof(tDot11fIEP2PGONegRes); + status |= dot11fGetPackedIEP2PGONegRes(pCtx, ( tDot11fIEP2PGONegRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PGONegWPS: + offset = sizeof(tDot11fIEP2PGONegWPS); + status |= dot11fGetPackedIEP2PGONegWPS(pCtx, ( tDot11fIEP2PGONegWPS* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PIEOpaque: + offset = sizeof(tDot11fIEP2PIEOpaque); + byteCount = ((tDot11fIEP2PIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEP2PIEOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEP2PIEOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeP2PInvitationReq: + offset = sizeof(tDot11fIEP2PInvitationReq); + status |= dot11fGetPackedIEP2PInvitationReq(pCtx, ( tDot11fIEP2PInvitationReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PInvitationRes: + offset = sizeof(tDot11fIEP2PInvitationRes); + status |= dot11fGetPackedIEP2PInvitationRes(pCtx, ( tDot11fIEP2PInvitationRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PNoticeOfAbsence: + offset = sizeof(tDot11fIEP2PNoticeOfAbsence); + status |= dot11fGetPackedIEP2PNoticeOfAbsence(pCtx, ( tDot11fIEP2PNoticeOfAbsence* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PPresenceResponse: + offset = sizeof(tDot11fIEP2PPresenceResponse); + status |= dot11fGetPackedIEP2PPresenceResponse(pCtx, ( tDot11fIEP2PPresenceResponse* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PProbeReq: + offset = sizeof(tDot11fIEP2PProbeReq); + status |= dot11fGetPackedIEP2PProbeReq(pCtx, ( tDot11fIEP2PProbeReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PProbeRes: + offset = sizeof(tDot11fIEP2PProbeRes); + status |= dot11fGetPackedIEP2PProbeRes(pCtx, ( tDot11fIEP2PProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PProvisionDiscoveryReq: + offset = sizeof(tDot11fIEP2PProvisionDiscoveryReq); + status |= dot11fGetPackedIEP2PProvisionDiscoveryReq(pCtx, ( tDot11fIEP2PProvisionDiscoveryReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeP2PWSCProvisionDiscoveryRes: + offset = sizeof(tDot11fIEP2PWSCProvisionDiscoveryRes); + status |= dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(pCtx, ( tDot11fIEP2PWSCProvisionDiscoveryRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIePTIControl: + offset = sizeof(tDot11fIEPTIControl); + byteCount = 3; + pIePresent = ( (tDot11fIEPTIControl* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePUBufferStatus: + offset = sizeof(tDot11fIEPUBufferStatus); + byteCount = 1; + pIePresent = ( (tDot11fIEPUBufferStatus* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePowerCaps: + offset = sizeof(tDot11fIEPowerCaps); + byteCount = 2; + pIePresent = ( (tDot11fIEPowerCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIePowerConstraints: + offset = sizeof(tDot11fIEPowerConstraints); + byteCount = 1; + pIePresent = ( (tDot11fIEPowerConstraints* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQBSSLoad: + offset = sizeof(tDot11fIEQBSSLoad); + byteCount = 5; + pIePresent = ( (tDot11fIEQBSSLoad* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQOSCapsAp: + offset = sizeof(tDot11fIEQOSCapsAp); + byteCount = 1; + pIePresent = ( (tDot11fIEQOSCapsAp* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQOSCapsStation: + offset = sizeof(tDot11fIEQOSCapsStation); + byteCount = 1; + pIePresent = ( (tDot11fIEQOSCapsStation* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQosMapSet: + offset = sizeof(tDot11fIEQosMapSet); + byteCount = ((tDot11fIEQosMapSet* )(pFrm + pIe->offset + sizeof(tDot11fIEQosMapSet) * i ))->num_dscp_exceptions; + pIePresent = ( (tDot11fIEQosMapSet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeQuiet: + offset = sizeof(tDot11fIEQuiet); + byteCount = 6; + pIePresent = ( (tDot11fIEQuiet* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRCPIIE: + offset = sizeof(tDot11fIERCPIIE); + byteCount = 1; + pIePresent = ( (tDot11fIERCPIIE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRICDataDesc: + offset = sizeof(tDot11fIERICDataDesc); + pnNeeded -= 2 ; //Subtract the length and Oui as this is our container IE to group Ies and it doesnt have its own length and OUI. + status |= dot11fGetPackedIERICDataDesc(pCtx, ( tDot11fIERICDataDesc* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeRSN: + offset = sizeof(tDot11fIERSN); + status |= dot11fGetPackedIERSN(pCtx, ( tDot11fIERSN* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeRSNIIE: + offset = sizeof(tDot11fIERSNIIE); + byteCount = 1; + pIePresent = ( (tDot11fIERSNIIE* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeRSNOpaque: + offset = sizeof(tDot11fIERSNOpaque); + byteCount = ((tDot11fIERSNOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIERSNOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIERSNOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSuppChannels: + offset = sizeof(tDot11fIESuppChannels); + byteCount = ((tDot11fIESuppChannels* )(pFrm + pIe->offset + sizeof(tDot11fIESuppChannels) * i ))->num_bands * 2; + pIePresent = ( (tDot11fIESuppChannels* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSuppOperatingClasses: + offset = sizeof(tDot11fIESuppOperatingClasses); + byteCount = ((tDot11fIESuppOperatingClasses* )(pFrm + pIe->offset + sizeof(tDot11fIESuppOperatingClasses) * i ))->num_classes; + pIePresent = ( (tDot11fIESuppOperatingClasses* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeSuppRates: + offset = sizeof(tDot11fIESuppRates); + byteCount = ((tDot11fIESuppRates* )(pFrm + pIe->offset + sizeof(tDot11fIESuppRates) * i ))->num_rates; + pIePresent = ( (tDot11fIESuppRates* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTIM: + offset = sizeof(tDot11fIETIM); + byteCount = ((tDot11fIETIM* )(pFrm + pIe->offset + sizeof(tDot11fIETIM) * i ))->num_vbmp + 3; + pIePresent = ( (tDot11fIETIM* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTPCReport: + offset = sizeof(tDot11fIETPCReport); + byteCount = 2; + pIePresent = ( (tDot11fIETPCReport* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTPCRequest: + offset = sizeof(tDot11fIETPCRequest); + byteCount = 0; + pIePresent = ( (tDot11fIETPCRequest* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeTimeoutInterval: + offset = sizeof(tDot11fIETimeoutInterval); + byteCount = 5; + pIePresent = ( (tDot11fIETimeoutInterval* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVHTCaps: + offset = sizeof(tDot11fIEVHTCaps); + byteCount = 12; + pIePresent = ( (tDot11fIEVHTCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVHTExtBssLoad: + offset = sizeof(tDot11fIEVHTExtBssLoad); + byteCount = 5; + pIePresent = ( (tDot11fIEVHTExtBssLoad* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeVHTOperation: + offset = sizeof(tDot11fIEVHTOperation); + byteCount = 5; + pIePresent = ( (tDot11fIEVHTOperation* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWAPI: + offset = sizeof(tDot11fIEWAPI); + status |= dot11fGetPackedIEWAPI(pCtx, ( tDot11fIEWAPI* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWAPIOpaque: + offset = sizeof(tDot11fIEWAPIOpaque); + byteCount = ((tDot11fIEWAPIOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWAPIOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWAPIOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWFATPC: + offset = sizeof(tDot11fIEWFATPC); + byteCount = 2; + pIePresent = ( (tDot11fIEWFATPC* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWFDIEOpaque: + offset = sizeof(tDot11fIEWFDIEOpaque); + byteCount = ((tDot11fIEWFDIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWFDIEOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWFDIEOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMCaps: + offset = sizeof(tDot11fIEWMMCaps); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMCaps* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMInfoAp: + offset = sizeof(tDot11fIEWMMInfoAp); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMInfoAp* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMInfoStation: + offset = sizeof(tDot11fIEWMMInfoStation); + byteCount = 2; + pIePresent = ( (tDot11fIEWMMInfoStation* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWMMParams: + offset = sizeof(tDot11fIEWMMParams); + byteCount = 19; + pIePresent = ( (tDot11fIEWMMParams* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWPA: + offset = sizeof(tDot11fIEWPA); + status |= dot11fGetPackedIEWPA(pCtx, ( tDot11fIEWPA* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWPAOpaque: + offset = sizeof(tDot11fIEWPAOpaque); + byteCount = ((tDot11fIEWPAOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWPAOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWPAOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWSC: + offset = sizeof(tDot11fIEWSC); + status |= dot11fGetPackedIEWSC(pCtx, ( tDot11fIEWSC* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWiderBWChanSwitchAnn: + offset = sizeof(tDot11fIEWiderBWChanSwitchAnn); + byteCount = 3; + pIePresent = ( (tDot11fIEWiderBWChanSwitchAnn* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWscAssocReq: + offset = sizeof(tDot11fIEWscAssocReq); + status |= dot11fGetPackedIEWscAssocReq(pCtx, ( tDot11fIEWscAssocReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscAssocRes: + offset = sizeof(tDot11fIEWscAssocRes); + status |= dot11fGetPackedIEWscAssocRes(pCtx, ( tDot11fIEWscAssocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscBeacon: + offset = sizeof(tDot11fIEWscBeacon); + status |= dot11fGetPackedIEWscBeacon(pCtx, ( tDot11fIEWscBeacon* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscBeaconProbeRes: + offset = sizeof(tDot11fIEWscBeaconProbeRes); + status |= dot11fGetPackedIEWscBeaconProbeRes(pCtx, ( tDot11fIEWscBeaconProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscIEOpaque: + offset = sizeof(tDot11fIEWscIEOpaque); + byteCount = ((tDot11fIEWscIEOpaque* )(pFrm + pIe->offset + sizeof(tDot11fIEWscIEOpaque) * i ))->num_data; + pIePresent = ( (tDot11fIEWscIEOpaque* )(pFrm + pIe->offset + offset * i ))->present; + break; + case SigIeWscProbeReq: + offset = sizeof(tDot11fIEWscProbeReq); + status |= dot11fGetPackedIEWscProbeReq(pCtx, ( tDot11fIEWscProbeReq* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscProbeRes: + offset = sizeof(tDot11fIEWscProbeRes); + status |= dot11fGetPackedIEWscProbeRes(pCtx, ( tDot11fIEWscProbeRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIeWscReassocRes: + offset = sizeof(tDot11fIEWscReassocRes); + status |= dot11fGetPackedIEWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + case SigIehs20vendor_ie: + offset = sizeof(tDot11fIEhs20vendor_ie); + status |= dot11fGetPackedIEhs20vendor_ie(pCtx, ( tDot11fIEhs20vendor_ie* )(pFrm + pIe->offset + offset * i ), pnNeeded); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the IE signature %d; this is most l" + "ikely a bug in 'framesc'.\n"), pIe->sig); + return DOT11F_INTERNAL_ERROR; + }/*End of switch Case*/ + if( byteCount && pIePresent ) + *pnNeeded += byteCount; + } /*End of for loop*/ + } + ++pIe; + } + return status; + +} + +static tANI_U32 GetPackedSizeTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pFrm, + tANI_U32 *pnNeeded, + const tTLVDefn TLVs[]) +{ + const tTLVDefn *pTlv; + tANI_U32 status; + tFRAMES_BOOL *pfFound; + tANI_U32 byteCount = 0; + tANI_U8 pTlvPresent = 0; + + status = DOT11F_PARSE_SUCCESS; + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pFrm + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound ) + { + *pnNeeded += (pTlv->sType + pTlv->sLen); + if ( pTlv->pec ) *pnNeeded += 3U; + switch (pTlv->sig) + { + case SigTlvAuthorizedMACs: + byteCount = 6; + pTlvPresent = (( tDot11fTLVAuthorizedMACs* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRequestToEnroll: + byteCount = 1; + pTlvPresent = (( tDot11fTLVRequestToEnroll* )(pFrm + pTlv->offset))->present; + break; + case SigTlvVersion2: + byteCount = 1; + pTlvPresent = (( tDot11fTLVVersion2* )(pFrm + pTlv->offset))->present; + break; + case SigTlvAPSetupLocked: + byteCount = 1; + pTlvPresent = (( tDot11fTLVAPSetupLocked* )(pFrm + pTlv->offset))->present; + break; + case SigTlvAssociationState: + byteCount = 2; + pTlvPresent = (( tDot11fTLVAssociationState* )(pFrm + pTlv->offset))->present; + break; + case SigTlvChannelList: + byteCount = ((tDot11fTLVChannelList*)(pFrm + pTlv->offset))->num_channelList+3; + pTlvPresent = (( tDot11fTLVChannelList* )(pFrm + pTlv->offset))->present; + break; + case SigTlvConfigMethods: + byteCount = 2; + pTlvPresent = (( tDot11fTLVConfigMethods* )(pFrm + pTlv->offset))->present; + break; + case SigTlvConfigurationError: + byteCount = 2; + pTlvPresent = (( tDot11fTLVConfigurationError* )(pFrm + pTlv->offset))->present; + break; + case SigTlvConfigurationTimeout: + byteCount = 2; + pTlvPresent = (( tDot11fTLVConfigurationTimeout* )(pFrm + pTlv->offset))->present; + break; + case SigTlvDeviceName: + byteCount = ((tDot11fTLVDeviceName*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVDeviceName* )(pFrm + pTlv->offset))->present; + break; + case SigTlvDevicePasswordID: + byteCount = 2; + pTlvPresent = (( tDot11fTLVDevicePasswordID* )(pFrm + pTlv->offset))->present; + break; + case SigTlvExtendedListenTiming: + byteCount = 4; + pTlvPresent = (( tDot11fTLVExtendedListenTiming* )(pFrm + pTlv->offset))->present; + break; + case SigTlvGOIntent: + byteCount = 1; + pTlvPresent = (( tDot11fTLVGOIntent* )(pFrm + pTlv->offset))->present; + break; + case SigTlvIntendedP2PInterfaceAddress: + byteCount = 6; + pTlvPresent = (( tDot11fTLVIntendedP2PInterfaceAddress* )(pFrm + pTlv->offset))->present; + break; + case SigTlvInvitationFlags: + byteCount = 1; + pTlvPresent = (( tDot11fTLVInvitationFlags* )(pFrm + pTlv->offset))->present; + break; + case SigTlvListenChannel: + byteCount = 5; + pTlvPresent = (( tDot11fTLVListenChannel* )(pFrm + pTlv->offset))->present; + break; + case SigTlvManufacturer: + byteCount = ((tDot11fTLVManufacturer*)(pFrm + pTlv->offset))->num_name; + pTlvPresent = (( tDot11fTLVManufacturer* )(pFrm + pTlv->offset))->present; + break; + case SigTlvMinorReasonCode: + byteCount = 1; + pTlvPresent = (( tDot11fTLVMinorReasonCode* )(pFrm + pTlv->offset))->present; + break; + case SigTlvModelName: + byteCount = ((tDot11fTLVModelName*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVModelName* )(pFrm + pTlv->offset))->present; + break; + case SigTlvModelNumber: + byteCount = ((tDot11fTLVModelNumber*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVModelNumber* )(pFrm + pTlv->offset))->present; + break; + case SigTlvNoticeOfAbsence: + byteCount = ((tDot11fTLVNoticeOfAbsence*)(pFrm + pTlv->offset))->num_NoADesc+2; + pTlvPresent = (( tDot11fTLVNoticeOfAbsence* )(pFrm + pTlv->offset))->present; + break; + case SigTlvOperatingChannel: + byteCount = 5; + pTlvPresent = (( tDot11fTLVOperatingChannel* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PCapability: + byteCount = 2; + pTlvPresent = (( tDot11fTLVP2PCapability* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PDeviceId: + byteCount = 6; + pTlvPresent = (( tDot11fTLVP2PDeviceId* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PDeviceInfo: + status = GetPackedSizeTlvCore(pCtx, ( tANI_U8* )pFrm + pTlv->offset, pnNeeded, TLVS_P2PDeviceInfo); + byteCount = 16; + pTlvPresent = (( tDot11fTLVP2PDeviceInfo* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PGroupBssid: + byteCount = 6; + pTlvPresent = (( tDot11fTLVP2PGroupBssid* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PGroupId: + byteCount = ((tDot11fTLVP2PGroupId*)(pFrm + pTlv->offset))->num_ssid+6; + pTlvPresent = (( tDot11fTLVP2PGroupId* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PGroupInfo: + byteCount = ((tDot11fTLVP2PGroupInfo*)(pFrm + pTlv->offset))->num_P2PClientInfoDesc; + pTlvPresent = (( tDot11fTLVP2PGroupInfo* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PStatus: + byteCount = 1; + pTlvPresent = (( tDot11fTLVP2PStatus* )(pFrm + pTlv->offset))->present; + break; + case SigTlvPrimaryDeviceType: + byteCount = 8; + pTlvPresent = (( tDot11fTLVPrimaryDeviceType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRFBands: + byteCount = 1; + pTlvPresent = (( tDot11fTLVRFBands* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRequestDeviceType: + byteCount = 8; + pTlvPresent = (( tDot11fTLVRequestDeviceType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvRequestType: + byteCount = 1; + pTlvPresent = (( tDot11fTLVRequestType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvResponseType: + byteCount = 1; + pTlvPresent = (( tDot11fTLVResponseType* )(pFrm + pTlv->offset))->present; + break; + case SigTlvSelectedRegistrar: + byteCount = 1; + pTlvPresent = (( tDot11fTLVSelectedRegistrar* )(pFrm + pTlv->offset))->present; + break; + case SigTlvSelectedRegistrarConfigMethods: + byteCount = 2; + pTlvPresent = (( tDot11fTLVSelectedRegistrarConfigMethods* )(pFrm + pTlv->offset))->present; + break; + case SigTlvSerialNumber: + byteCount = ((tDot11fTLVSerialNumber*)(pFrm + pTlv->offset))->num_text; + pTlvPresent = (( tDot11fTLVSerialNumber* )(pFrm + pTlv->offset))->present; + break; + case SigTlvUUID_E: + byteCount = 16; + pTlvPresent = (( tDot11fTLVUUID_E* )(pFrm + pTlv->offset))->present; + break; + case SigTlvUUID_R: + byteCount = 16; + pTlvPresent = (( tDot11fTLVUUID_R* )(pFrm + pTlv->offset))->present; + break; + case SigTlvVendorExtension: + status = GetPackedSizeTlvCore(pCtx, ( tANI_U8* )pFrm + pTlv->offset, pnNeeded, TLVS_VendorExtension); + byteCount = 3; + pTlvPresent = (( tDot11fTLVVendorExtension* )(pFrm + pTlv->offset))->present; + break; + case SigTlvVersion: + byteCount = 1; + pTlvPresent = (( tDot11fTLVVersion* )(pFrm + pTlv->offset))->present; + break; + case SigTlvWPSState: + byteCount = 1; + pTlvPresent = (( tDot11fTLVWPSState* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PInterface: + byteCount = 6; + pTlvPresent = (( tDot11fTLVP2PInterface* )(pFrm + pTlv->offset))->present; + break; + case SigTlvP2PManageability: + byteCount = 1; + pTlvPresent = (( tDot11fTLVP2PManageability* )(pFrm + pTlv->offset))->present; + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the TLV signature %d; this is most l" + "ikely a bug in 'framesc'.\n"), pTlv->sig); + return DOT11F_INTERNAL_ERROR; + } + if(pTlvPresent) { + *pnNeeded += byteCount; + } + } + ++pTlv; + } + return status; +} +void dot11fPackFfAID(tpAniSirGlobal pCtx, + tDot11fFfAID *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->associd, 0); + (void)pCtx; +} /* End dot11fPackFfAID. */ + +void dot11fPackFfAction(tpAniSirGlobal pCtx, + tDot11fFfAction *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->action; + (void)pCtx; +} /* End dot11fPackFfAction. */ + +void dot11fPackFfAddBAParameterSet(tpAniSirGlobal pCtx, + tDot11fFfAddBAParameterSet *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp79__; + tmp79__ = 0U; + tmp79__ |= ( pSrc->amsduSupported << 0 ); + tmp79__ |= ( pSrc->policy << 1 ); + tmp79__ |= ( pSrc->tid << 2 ); + tmp79__ |= ( pSrc->bufferSize << 6 ); + frameshtons(pCtx, pBuf, tmp79__, 0); + (void)pCtx; +} /* End dot11fPackFfAddBAParameterSet. */ + +void dot11fPackFfAuthAlgo(tpAniSirGlobal pCtx, + tDot11fFfAuthAlgo *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->algo, 0); + (void)pCtx; +} /* End dot11fPackFfAuthAlgo. */ + +void dot11fPackFfAuthSeqNo(tpAniSirGlobal pCtx, + tDot11fFfAuthSeqNo *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->no, 0); + (void)pCtx; +} /* End dot11fPackFfAuthSeqNo. */ + +void dot11fPackFfBAStartingSequenceControl(tpAniSirGlobal pCtx, + tDot11fFfBAStartingSequenceControl *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp80__; + tmp80__ = 0U; + tmp80__ |= ( pSrc->fragNumber << 0 ); + tmp80__ |= ( pSrc->ssn << 4 ); + frameshtons(pCtx, pBuf, tmp80__, 0); + (void)pCtx; +} /* End dot11fPackFfBAStartingSequenceControl. */ + +void dot11fPackFfBATimeout(tpAniSirGlobal pCtx, + tDot11fFfBATimeout *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->timeout, 0); + (void)pCtx; +} /* End dot11fPackFfBATimeout. */ + +void dot11fPackFfBeaconInterval(tpAniSirGlobal pCtx, + tDot11fFfBeaconInterval *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->interval, 0); + (void)pCtx; +} /* End dot11fPackFfBeaconInterval. */ + +void dot11fPackFfCapabilities(tpAniSirGlobal pCtx, + tDot11fFfCapabilities *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp81__; + tmp81__ = 0U; + tmp81__ |= ( pSrc->ess << 0 ); + tmp81__ |= ( pSrc->ibss << 1 ); + tmp81__ |= ( pSrc->cfPollable << 2 ); + tmp81__ |= ( pSrc->cfPollReq << 3 ); + tmp81__ |= ( pSrc->privacy << 4 ); + tmp81__ |= ( pSrc->shortPreamble << 5 ); + tmp81__ |= ( pSrc->pbcc << 6 ); + tmp81__ |= ( pSrc->channelAgility << 7 ); + tmp81__ |= ( pSrc->spectrumMgt << 8 ); + tmp81__ |= ( pSrc->qos << 9 ); + tmp81__ |= ( pSrc->shortSlotTime << 10 ); + tmp81__ |= ( pSrc->apsd << 11 ); + tmp81__ |= ( pSrc->rrm << 12 ); + tmp81__ |= ( pSrc->dsssOfdm << 13 ); + tmp81__ |= ( pSrc->delayedBA << 14 ); + tmp81__ |= ( pSrc->immediateBA << 15 ); + frameshtons(pCtx, pBuf, tmp81__, 0); + (void)pCtx; +} /* End dot11fPackFfCapabilities. */ + +void dot11fPackFfCategory(tpAniSirGlobal pCtx, + tDot11fFfCategory *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->category; + (void)pCtx; +} /* End dot11fPackFfCategory. */ + +void dot11fPackFfCurrentAPAddress(tpAniSirGlobal pCtx, + tDot11fFfCurrentAPAddress *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6); + (void)pCtx; +} /* End dot11fPackFfCurrentAPAddress. */ + +void dot11fPackFfDelBAParameterSet(tpAniSirGlobal pCtx, + tDot11fFfDelBAParameterSet *pSrc, + tANI_U8 *pBuf) +{ + tANI_U16 tmp82__; + tmp82__ = 0U; + tmp82__ |= ( pSrc->reserved << 0 ); + tmp82__ |= ( pSrc->initiator << 11 ); + tmp82__ |= ( pSrc->tid << 12 ); + frameshtons(pCtx, pBuf, tmp82__, 0); + (void)pCtx; +} /* End dot11fPackFfDelBAParameterSet. */ + +void dot11fPackFfDialogToken(tpAniSirGlobal pCtx, + tDot11fFfDialogToken *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->token; + (void)pCtx; +} /* End dot11fPackFfDialogToken. */ + +void dot11fPackFfLinkMargin(tpAniSirGlobal pCtx, + tDot11fFfLinkMargin *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->linkMargin; + (void)pCtx; +} /* End dot11fPackFfLinkMargin. */ + +void dot11fPackFfListenInterval(tpAniSirGlobal pCtx, + tDot11fFfListenInterval *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->interval, 0); + (void)pCtx; +} /* End dot11fPackFfListenInterval. */ + +void dot11fPackFfMagicCode(tpAniSirGlobal pCtx, + tDot11fFfMagicCode *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->magic, 6); + (void)pCtx; +} /* End dot11fPackFfMagicCode. */ + +void dot11fPackFfMaxTxPower(tpAniSirGlobal pCtx, + tDot11fFfMaxTxPower *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->maxTxPower; + (void)pCtx; +} /* End dot11fPackFfMaxTxPower. */ + +void dot11fPackFfNumOfRepetitions(tpAniSirGlobal pCtx, + tDot11fFfNumOfRepetitions *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->repetitions, 0); + (void)pCtx; +} /* End dot11fPackFfNumOfRepetitions. */ + +void dot11fPackFfOperatingMode(tpAniSirGlobal pCtx, + tDot11fFfOperatingMode *pSrc, + tANI_U8 *pBuf) +{ + tANI_U8 tmp83__; + tmp83__ = 0U; + tmp83__ |= ( pSrc->chanWidth << 0 ); + tmp83__ |= ( pSrc->reserved << 2 ); + tmp83__ |= ( pSrc->rxNSS << 4 ); + tmp83__ |= ( pSrc->rxNSSType << 7 ); + *pBuf = tmp83__; + (void)pCtx; +} /* End dot11fPackFfOperatingMode. */ + +void dot11fPackFfP2POUI(tpAniSirGlobal pCtx, + tDot11fFfP2POUI *pSrc, + tANI_U8 *pBuf) +{ + frameshtonl(pCtx, pBuf, pSrc->oui, 0); + (void)pCtx; +} /* End dot11fPackFfP2POUI. */ + +void dot11fPackFfP2POUISubType(tpAniSirGlobal pCtx, + tDot11fFfP2POUISubType *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->ouiSubtype; + (void)pCtx; +} /* End dot11fPackFfP2POUISubType. */ + +void dot11fPackFfRCPI(tpAniSirGlobal pCtx, + tDot11fFfRCPI *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->rcpi; + (void)pCtx; +} /* End dot11fPackFfRCPI. */ + +void dot11fPackFfRMCDialogToken(tpAniSirGlobal pCtx, + tDot11fFfRMCDialogToken *pSrc, + tANI_U8 *pBuf) +{ + frameshtonl(pCtx, pBuf, pSrc->token, 0); + (void)pCtx; +} /* End dot11fPackFfRMCDialogToken. */ + +void dot11fPackFfRMCOUI(tpAniSirGlobal pCtx, + tDot11fFfRMCOUI *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 3); + (void)pCtx; +} /* End dot11fPackFfRMCOUI. */ + +void dot11fPackFfRMCVersion(tpAniSirGlobal pCtx, + tDot11fFfRMCVersion *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->version; + (void)pCtx; +} /* End dot11fPackFfRMCVersion. */ + +void dot11fPackFfRSNI(tpAniSirGlobal pCtx, + tDot11fFfRSNI *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->rsni; + (void)pCtx; +} /* End dot11fPackFfRSNI. */ + +void dot11fPackFfReason(tpAniSirGlobal pCtx, + tDot11fFfReason *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->code, 0); + (void)pCtx; +} /* End dot11fPackFfReason. */ + +void dot11fPackFfRuler(tpAniSirGlobal pCtx, + tDot11fFfRuler *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6); + (void)pCtx; +} /* End dot11fPackFfRuler. */ + +void dot11fPackFfRxAntennaId(tpAniSirGlobal pCtx, + tDot11fFfRxAntennaId *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->antennaId; + (void)pCtx; +} /* End dot11fPackFfRxAntennaId. */ + +void dot11fPackFfSMPowerModeSet(tpAniSirGlobal pCtx, + tDot11fFfSMPowerModeSet *pSrc, + tANI_U8 *pBuf) +{ + tANI_U8 tmp84__; + tmp84__ = 0U; + tmp84__ |= ( pSrc->PowerSave_En << 0 ); + tmp84__ |= ( pSrc->Mode << 1 ); + tmp84__ |= ( pSrc->reserved << 2 ); + *pBuf = tmp84__; + (void)pCtx; +} /* End dot11fPackFfSMPowerModeSet. */ + +void dot11fPackFfStatus(tpAniSirGlobal pCtx, + tDot11fFfStatus *pSrc, + tANI_U8 *pBuf) +{ + frameshtons(pCtx, pBuf, pSrc->status, 0); + (void)pCtx; +} /* End dot11fPackFfStatus. */ + +void dot11fPackFfStatusCode(tpAniSirGlobal pCtx, + tDot11fFfStatusCode *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->statusCode; + (void)pCtx; +} /* End dot11fPackFfStatusCode. */ + +void dot11fPackFfTPCEleID(tpAniSirGlobal pCtx, + tDot11fFfTPCEleID *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->TPCId; + (void)pCtx; +} /* End dot11fPackFfTPCEleID. */ + +void dot11fPackFfTPCEleLen(tpAniSirGlobal pCtx, + tDot11fFfTPCEleLen *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->TPCLen; + (void)pCtx; +} /* End dot11fPackFfTPCEleLen. */ + +void dot11fPackFfTSInfo(tpAniSirGlobal pCtx, + tDot11fFfTSInfo *pSrc, + tANI_U8 *pBuf) +{ + tANI_U32 tmp85__; + tmp85__ = 0U; + tmp85__ |= ( pSrc->traffic_type << 0 ); + tmp85__ |= ( pSrc->tsid << 1 ); + tmp85__ |= ( pSrc->direction << 5 ); + tmp85__ |= ( pSrc->access_policy << 7 ); + tmp85__ |= ( pSrc->aggregation << 9 ); + tmp85__ |= ( pSrc->psb << 10 ); + tmp85__ |= ( pSrc->user_priority << 11 ); + tmp85__ |= ( pSrc->tsinfo_ack_pol << 14 ); + tmp85__ |= ( pSrc->schedule << 16 ); + tmp85__ |= ( pSrc->unused << 17 ); + frameshtonl(pCtx, pBuf, tmp85__, 0); + (void)pCtx; +} /* End dot11fPackFfTSInfo. */ + +void dot11fPackFfTimeStamp(tpAniSirGlobal pCtx, + tDot11fFfTimeStamp *pSrc, + tANI_U8 *pBuf) +{ + frameshtonq(pCtx, pBuf, pSrc->timestamp, 0); + (void)pCtx; +} /* End dot11fPackFfTimeStamp. */ + +void dot11fPackFfTransactionId(tpAniSirGlobal pCtx, + tDot11fFfTransactionId *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->transId, 2); + (void)pCtx; +} /* End dot11fPackFfTransactionId. */ + +void dot11fPackFfTxAntennaId(tpAniSirGlobal pCtx, + tDot11fFfTxAntennaId *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->antennaId; + (void)pCtx; +} /* End dot11fPackFfTxAntennaId. */ + +void dot11fPackFfTxPower(tpAniSirGlobal pCtx, + tDot11fFfTxPower *pSrc, + tANI_U8 *pBuf) +{ + *pBuf = pSrc->txPower; + (void)pCtx; +} /* End dot11fPackFfTxPower. */ + +void dot11fPackFfVhtMembershipStatusArray(tpAniSirGlobal pCtx, + tDot11fFfVhtMembershipStatusArray *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->membershipStatusArray, 8); + (void)pCtx; +} /* End dot11fPackFfVhtMembershipStatusArray. */ + +void dot11fPackFfVhtUserPositionArray(tpAniSirGlobal pCtx, + tDot11fFfVhtUserPositionArray *pSrc, + tANI_U8 *pBuf) +{ + DOT11F_MEMCPY(pCtx, pBuf, pSrc->userPositionArray, 16); + (void)pCtx; +} /* End dot11fPackFfVhtUserPositionArray. */ + +tANI_U32 dot11fPackTlvAuthorizedMACs(tpAniSirGlobal pCtx, + tDot11fTLVAuthorizedMACs *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 8; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 1; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 1; *pnConsumed += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->mac, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + *pTlvLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvAuthorizedMACs. */ + +tANI_U32 dot11fPackTlvRequestToEnroll(tpAniSirGlobal pCtx, + tDot11fTLVRequestToEnroll *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 3; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 1; *pnConsumed += 1; + *pBuf = pSrc->req; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + *pTlvLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRequestToEnroll. */ + +tANI_U32 dot11fPackTlvVersion2(tpAniSirGlobal pCtx, + tDot11fTLVVersion2 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp86__; + nNeeded += 3; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 0; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 1; *pnConsumed += 1; + tmp86__ = 0U; + tmp86__ |= ( pSrc->minor << 0 ); + tmp86__ |= ( pSrc->major << 4 ); + *pBuf = tmp86__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pTlvLen) + { + *pTlvLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvVersion2. */ + +tANI_U32 dot11fPackTlvAPSetupLocked(tpAniSirGlobal pCtx, + tDot11fTLVAPSetupLocked *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4183, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->fLocked; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvAPSetupLocked. */ + +tANI_U32 dot11fPackTlvAssociationState(tpAniSirGlobal pCtx, + tDot11fTLVAssociationState *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4098, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->state, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvAssociationState. */ + +tANI_U32 dot11fPackTlvChannelList(tpAniSirGlobal pCtx, + tDot11fTLVChannelList *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_channelList + 6) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 11; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3); + *pnConsumed += 3; + pBuf += 3; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->channelList ), pSrc->num_channelList); + *pnConsumed += pSrc->num_channelList; + pBuf += pSrc->num_channelList; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvChannelList. */ + +tANI_U32 dot11fPackTlvConfigMethods(tpAniSirGlobal pCtx, + tDot11fTLVConfigMethods *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4104, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->methods, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvConfigMethods. */ + +tANI_U32 dot11fPackTlvConfigurationError(tpAniSirGlobal pCtx, + tDot11fTLVConfigurationError *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4105, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->error, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvConfigurationError. */ + +tANI_U32 dot11fPackTlvConfigurationTimeout(tpAniSirGlobal pCtx, + tDot11fTLVConfigurationTimeout *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 5; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->GOConfigTimeout; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->CLConfigTimeout; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvConfigurationTimeout. */ + +tANI_U32 dot11fPackTlvDeviceName(tpAniSirGlobal pCtx, + tDot11fTLVDeviceName *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4113, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvDeviceName. */ + +tANI_U32 dot11fPackTlvDevicePasswordID(tpAniSirGlobal pCtx, + tDot11fTLVDevicePasswordID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4114, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->id, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvDevicePasswordID. */ + +tANI_U32 dot11fPackTlvExtendedListenTiming(tpAniSirGlobal pCtx, + tDot11fTLVExtendedListenTiming *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 7; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 8; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->availibilityPeriod, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->availibilityInterval, 0); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvExtendedListenTiming. */ + +tANI_U32 dot11fPackTlvGOIntent(tpAniSirGlobal pCtx, + tDot11fTLVGOIntent *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 4; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->GOIntent; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvGOIntent. */ + +tANI_U32 dot11fPackTlvIntendedP2PInterfaceAddress(tpAniSirGlobal pCtx, + tDot11fTLVIntendedP2PInterfaceAddress *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 9; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PInterfaceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvIntendedP2PInterfaceAddress. */ + +tANI_U32 dot11fPackTlvInvitationFlags(tpAniSirGlobal pCtx, + tDot11fTLVInvitationFlags *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 18; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->invitationFlags; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvInvitationFlags. */ + +tANI_U32 dot11fPackTlvListenChannel(tpAniSirGlobal pCtx, + tDot11fTLVListenChannel *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 8; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 6; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3); + *pnConsumed += 3; + pBuf += 3; + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvListenChannel. */ + +tANI_U32 dot11fPackTlvManufacturer(tpAniSirGlobal pCtx, + tDot11fTLVManufacturer *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_name + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4129, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->name ), pSrc->num_name); + *pnConsumed += pSrc->num_name; + pBuf += pSrc->num_name; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvManufacturer. */ + +tANI_U32 dot11fPackTlvMinorReasonCode(tpAniSirGlobal pCtx, + tDot11fTLVMinorReasonCode *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 1; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->minorReasonCode; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvMinorReasonCode. */ + +tANI_U32 dot11fPackTlvModelName(tpAniSirGlobal pCtx, + tDot11fTLVModelName *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4131, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvModelName. */ + +tANI_U32 dot11fPackTlvModelNumber(tpAniSirGlobal pCtx, + tDot11fTLVModelNumber *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4132, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvModelNumber. */ + +tANI_U32 dot11fPackTlvNoticeOfAbsence(tpAniSirGlobal pCtx, + tDot11fTLVNoticeOfAbsence *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_NoADesc + 5) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 12; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->index; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->CTSWindowOppPS; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->NoADesc ), pSrc->num_NoADesc); + *pnConsumed += pSrc->num_NoADesc; + pBuf += pSrc->num_NoADesc; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvNoticeOfAbsence. */ + +tANI_U32 dot11fPackTlvOperatingChannel(tpAniSirGlobal pCtx, + tDot11fTLVOperatingChannel *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 8; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 17; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryString, 3); + *pnConsumed += 3; + pBuf += 3; + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvOperatingChannel. */ + +tANI_U32 dot11fPackTlvP2PCapability(tpAniSirGlobal pCtx, + tDot11fTLVP2PCapability *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 2; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->deviceCapability; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->groupCapability; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PCapability. */ + +tANI_U32 dot11fPackTlvP2PDeviceId(tpAniSirGlobal pCtx, + tDot11fTLVP2PDeviceId *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 3; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PDeviceId. */ + +tANI_U32 dot11fPackTlvP2PDeviceInfo(tpAniSirGlobal pCtx, + tDot11fTLVP2PDeviceInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + tANI_U32 idx = 0; + nNeeded += 19; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 13; + pBuf += 1; nBuf -= 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; nBuf -= 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + frameshtons(pCtx, pBuf, pSrc->configMethod, 1); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->primaryDeviceType, 8); + *pnConsumed += 8; + pBuf += 8; + status |= PackTlvCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + TLVS_P2PDeviceInfo, &idx); + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return status; +} /* End dot11fPackTlvP2PDeviceInfo. */ + +tANI_U32 dot11fPackTlvP2PGroupBssid(tpAniSirGlobal pCtx, + tDot11fTLVP2PGroupBssid *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 7; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PGroupBssid, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PGroupBssid. */ + +tANI_U32 dot11fPackTlvP2PGroupId(tpAniSirGlobal pCtx, + tDot11fTLVP2PGroupId *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_ssid + 9) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 15; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->deviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->ssid ), pSrc->num_ssid); + *pnConsumed += pSrc->num_ssid; + pBuf += pSrc->num_ssid; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PGroupId. */ + +tANI_U32 dot11fPackTlvP2PGroupInfo(tpAniSirGlobal pCtx, + tDot11fTLVP2PGroupInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_P2PClientInfoDesc + 3) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 14; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->P2PClientInfoDesc ), pSrc->num_P2PClientInfoDesc); + *pnConsumed += pSrc->num_P2PClientInfoDesc; + pBuf += pSrc->num_P2PClientInfoDesc; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PGroupInfo. */ + +tANI_U32 dot11fPackTlvP2PStatus(tpAniSirGlobal pCtx, + tDot11fTLVP2PStatus *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 0; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->status; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PStatus. */ + +tANI_U32 dot11fPackTlvPrimaryDeviceType(tpAniSirGlobal pCtx, + tDot11fTLVPrimaryDeviceType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 12; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4180, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->primary_category, 1); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->sub_category, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvPrimaryDeviceType. */ + +tANI_U32 dot11fPackTlvRFBands(tpAniSirGlobal pCtx, + tDot11fTLVRFBands *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4156, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->bands; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRFBands. */ + +tANI_U32 dot11fPackTlvRequestDeviceType(tpAniSirGlobal pCtx, + tDot11fTLVRequestDeviceType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 12; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4202, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->primary_category, 1); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->oui, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->sub_category, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRequestDeviceType. */ + +tANI_U32 dot11fPackTlvRequestType(tpAniSirGlobal pCtx, + tDot11fTLVRequestType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4154, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->reqType; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvRequestType. */ + +tANI_U32 dot11fPackTlvResponseType(tpAniSirGlobal pCtx, + tDot11fTLVResponseType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4155, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->resType; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvResponseType. */ + +tANI_U32 dot11fPackTlvSelectedRegistrar(tpAniSirGlobal pCtx, + tDot11fTLVSelectedRegistrar *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4161, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->selected; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvSelectedRegistrar. */ + +tANI_U32 dot11fPackTlvSelectedRegistrarConfigMethods(tpAniSirGlobal pCtx, + tDot11fTLVSelectedRegistrarConfigMethods *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4179, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + frameshtons(pCtx, pBuf, pSrc->methods, 1); + *pnConsumed += 2; + pBuf += 2; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvSelectedRegistrarConfigMethods. */ + +tANI_U32 dot11fPackTlvSerialNumber(tpAniSirGlobal pCtx, + tDot11fTLVSerialNumber *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += ( pSrc->num_text + 4) ; + + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4162, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + pBuf += pSrc->num_text; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvSerialNumber. */ + +tANI_U32 dot11fPackTlvUUID_E(tpAniSirGlobal pCtx, + tDot11fTLVUUID_E *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 20; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4167, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16); + *pnConsumed += 16; + pBuf += 16; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvUUID_E. */ + +tANI_U32 dot11fPackTlvUUID_R(tpAniSirGlobal pCtx, + tDot11fTLVUUID_R *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 20; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4168, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->uuid, 16); + *pnConsumed += 16; + pBuf += 16; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvUUID_R. */ + +tANI_U32 dot11fPackTlvVendorExtension(tpAniSirGlobal pCtx, + tDot11fTLVVendorExtension *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + tANI_U32 idx = 0; + nNeeded += 7; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4169, 1); + pBuf += 2; nBuf -= 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; nBuf -= 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->vendorId, 3); + *pnConsumed += 3; + pBuf += 3; + status |= PackTlvCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + TLVS_VendorExtension, &idx); + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return status; +} /* End dot11fPackTlvVendorExtension. */ + +tANI_U32 dot11fPackTlvVersion(tpAniSirGlobal pCtx, + tDot11fTLVVersion *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp87__; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4170, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + tmp87__ = 0U; + tmp87__ |= ( pSrc->minor << 0 ); + tmp87__ |= ( pSrc->major << 4 ); + *pBuf = tmp87__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvVersion. */ + +tANI_U32 dot11fPackTlvWPSState(tpAniSirGlobal pCtx, + tDot11fTLVWPSState *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + frameshtons( pCtx, pBuf, 4164, 1); + pBuf += 2; *pnConsumed += 2; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->state; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 4, 1); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvWPSState. */ + +tANI_U32 dot11fPackTlvP2PInterface(tpAniSirGlobal pCtx, + tDot11fTLVP2PInterface *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 9; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 16; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->P2PDeviceAddress, 6); + *pnConsumed += 6; + pBuf += 6; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PInterface. */ + +tANI_U32 dot11fPackTlvP2PManageability(tpAniSirGlobal pCtx, + tDot11fTLVP2PManageability *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pTlvLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + while ( pSrc->present ) + { + *pBuf = 10; + pBuf += 1; *pnConsumed += 1; + pTlvLen = pBuf; + pBuf += 2; *pnConsumed += 2; + *pBuf = pSrc->manageability; + *pnConsumed += 1; + pBuf += 1; + break; + } + (void)pCtx; + if (pTlvLen) + { + frameshtons( pCtx, pTlvLen, *pnConsumed - nConsumedOnEntry - 3, 0); + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackTlvP2PManageability. */ + +tANI_U32 dot11fPackIeAPName(tpAniSirGlobal pCtx, + tDot11fIEAPName *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_name; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->name ), pSrc->num_name); + *pnConsumed += pSrc->num_name; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeAPName. */ + +tANI_U32 dot11fPackIeBPIndicator(tpAniSirGlobal pCtx, + tDot11fIEBPIndicator *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 4; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->indicator; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->type; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBPIndicator. */ + +tANI_U32 dot11fPackIeCondensedCountryStr(tpAniSirGlobal pCtx, + tDot11fIECondensedCountryStr *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->countryStr, 2); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeCondensedCountryStr. */ + +tANI_U32 dot11fPackIeGTK(tpAniSirGlobal pCtx, + tDot11fIEGTK *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp88__; + nNeeded += (pSrc->num_key + 11); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp88__ = 0U; + tmp88__ |= ( pSrc->keyId << 0 ); + tmp88__ |= ( pSrc->reserved << 2 ); + frameshtons(pCtx, pBuf, tmp88__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + *pBuf = pSrc->keyLength; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSC, 8); + *pnConsumed += 8; + pBuf += 8; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->key ), pSrc->num_key); + *pnConsumed += pSrc->num_key; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeGTK. */ + +tANI_U32 dot11fPackIeHCF(tpAniSirGlobal pCtx, + tDot11fIEHCF *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->enabled; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHCF. */ + +tANI_U32 dot11fPackIeIGTK(tpAniSirGlobal pCtx, + tDot11fIEIGTK *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 33; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 4; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->keyID, 2); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->IPN, 6); + *pnConsumed += 6; + pBuf += 6; + *pBuf = pSrc->keyLength; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->key, 24); + *pnConsumed += 24; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeIGTK. */ + +tANI_U32 dot11fPackIeLLAttr(tpAniSirGlobal pCtx, + tDot11fIELLAttr *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 9; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtonl(pCtx, pBuf, pSrc->defer_threshold, 1); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLLAttr. */ + +tANI_U32 dot11fPackIeLoadBalance(tpAniSirGlobal pCtx, + tDot11fIELoadBalance *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 7; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 8; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); + *pnConsumed += 6; + pBuf += 6; + *pBuf = pSrc->channel; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLoadBalance. */ + +tANI_U32 dot11fPackIeLoadInfo(tpAniSirGlobal pCtx, + tDot11fIELoadInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 6; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->num_stas, 1); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->channel_util, 1); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLoadInfo. */ + +tANI_U32 dot11fPackIePropAssocType(tpAniSirGlobal pCtx, + tDot11fIEPropAssocType *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 7; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->type; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropAssocType. */ + +tANI_U32 dot11fPackIePropCapability(tpAniSirGlobal pCtx, + tDot11fIEPropCapability *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 10; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->capability, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropCapability. */ + +tANI_U32 dot11fPackIePropChannSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEPropChannSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 15; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->mode; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->primary_channel; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->sub_band; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel_switch_count; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropChannSwitchAnn. */ + +tANI_U32 dot11fPackIePropEDCAParams(tpAniSirGlobal pCtx, + tDot11fIEPropEDCAParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp89__; + tANI_U8 tmp90__; + tANI_U8 tmp91__; + tANI_U8 tmp92__; + tANI_U8 tmp93__; + tANI_U8 tmp94__; + tANI_U8 tmp95__; + tANI_U8 tmp96__; + nNeeded += 18; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 12; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->qos; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved; + *pnConsumed += 1; + pBuf += 1; + tmp89__ = 0U; + tmp89__ |= ( pSrc->acbe_aifsn << 0 ); + tmp89__ |= ( pSrc->acbe_acm << 4 ); + tmp89__ |= ( pSrc->acbe_aci << 5 ); + tmp89__ |= ( pSrc->unused1 << 7 ); + *pBuf = tmp89__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp90__ = 0U; + tmp90__ |= ( pSrc->acbe_min << 0 ); + tmp90__ |= ( pSrc->acbe_max << 4 ); + *pBuf = tmp90__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp91__ = 0U; + tmp91__ |= ( pSrc->acbk_aifsn << 0 ); + tmp91__ |= ( pSrc->acbk_acm << 4 ); + tmp91__ |= ( pSrc->acbk_aci << 5 ); + tmp91__ |= ( pSrc->unused2 << 7 ); + *pBuf = tmp91__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp92__ = 0U; + tmp92__ |= ( pSrc->acbk_min << 0 ); + tmp92__ |= ( pSrc->acbk_max << 4 ); + *pBuf = tmp92__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp93__ = 0U; + tmp93__ |= ( pSrc->acvi_aifsn << 0 ); + tmp93__ |= ( pSrc->acvi_acm << 4 ); + tmp93__ |= ( pSrc->acvi_aci << 5 ); + tmp93__ |= ( pSrc->unused3 << 7 ); + *pBuf = tmp93__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp94__ = 0U; + tmp94__ |= ( pSrc->acvi_min << 0 ); + tmp94__ |= ( pSrc->acvi_max << 4 ); + *pBuf = tmp94__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp95__ = 0U; + tmp95__ |= ( pSrc->acvo_aifsn << 0 ); + tmp95__ |= ( pSrc->acvo_acm << 4 ); + tmp95__ |= ( pSrc->acvo_aci << 5 ); + tmp95__ |= ( pSrc->unused4 << 7 ); + *pBuf = tmp95__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp96__ = 0U; + tmp96__ |= ( pSrc->acvo_min << 0 ); + tmp96__ |= ( pSrc->acvo_max << 4 ); + *pBuf = tmp96__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropEDCAParams. */ + +tANI_U32 dot11fPackIePropQuietBSS(tpAniSirGlobal pCtx, + tDot11fIEPropQuietBSS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 16; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->quiet_count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->quiet_period; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->quiet_duration, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->quiet_offset, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropQuietBSS. */ + +tANI_U32 dot11fPackIePropSuppRates(tpAniSirGlobal pCtx, + tDot11fIEPropSuppRates *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_rates; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 0; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rates ), pSrc->num_rates); + *pnConsumed += pSrc->num_rates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePropSuppRates. */ + +tANI_U32 dot11fPackIeR0KH_ID(tpAniSirGlobal pCtx, + tDot11fIER0KH_ID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_PMK_R0_ID; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 3; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->PMK_R0_ID ), pSrc->num_PMK_R0_ID); + *pnConsumed += pSrc->num_PMK_R0_ID; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeR0KH_ID. */ + +tANI_U32 dot11fPackIeR1KH_ID(tpAniSirGlobal pCtx, + tDot11fIER1KH_ID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->PMK_R1_ID, 6); + *pnConsumed += 6; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeR1KH_ID. */ + +tANI_U32 dot11fPackIeTSFInfo(tpAniSirGlobal pCtx, + tDot11fIETSFInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->TsfOffset, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->BeaconIntvl, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTSFInfo. */ + +tANI_U32 dot11fPackIeTaurus(tpAniSirGlobal pCtx, + tDot11fIETaurus *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp97__; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 18; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->baTIDBitmap, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->baPolicy, 0); + *pnConsumed += 2; + pBuf += 2; + tmp97__ = 0U; + tmp97__ |= ( pSrc->baBufferSize << 0 ); + tmp97__ |= ( pSrc->rsvd << 12 ); + frameshtons(pCtx, pBuf, tmp97__, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + nBuf -= 2 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTaurus. */ + +tANI_U32 dot11fPackIeTitan(tpAniSirGlobal pCtx, + tDot11fIETitan *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 14; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->concat_tcid_bitmap; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->compression_tcid_bitmap; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->cb_state; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->rev_fcs_state; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTitan. */ + +tANI_U32 dot11fPackIeTriggerStaBgScan(tpAniSirGlobal pCtx, + tDot11fIETriggerStaBgScan *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 17; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->enable; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTriggerStaBgScan. */ + +tANI_U32 dot11fPackIeVersion(tpAniSirGlobal pCtx, + tDot11fIEVersion *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_build_version + 5); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 11; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtonl(pCtx, pBuf, pSrc->chip_rev, 0); + *pnConsumed += 4; + pBuf += 4; + *pBuf = pSrc->card_type; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->build_version ), pSrc->num_build_version); + *pnConsumed += pSrc->num_build_version; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVersion. */ + +tANI_U32 dot11fPackIeWDS(tpAniSirGlobal pCtx, + tDot11fIEWDS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_wdsData; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 3; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->wdsData ), pSrc->num_wdsData); + *pnConsumed += pSrc->num_wdsData; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWDS. */ + +tANI_U32 dot11fPackIeAPChannelReport(tpAniSirGlobal pCtx, + tDot11fIEAPChannelReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_channelList + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 51; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->channelList ), pSrc->num_channelList); + *pnConsumed += pSrc->num_channelList; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeAPChannelReport. */ + +tANI_U32 dot11fPackIeBcnReportingDetail(tpAniSirGlobal pCtx, + tDot11fIEBcnReportingDetail *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->reportingDetail; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBcnReportingDetail. */ + +tANI_U32 dot11fPackIeBeaconReportFrmBody(tpAniSirGlobal pCtx, + tDot11fIEBeaconReportFrmBody *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_reportedFields; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->reportedFields ), pSrc->num_reportedFields); + *pnConsumed += pSrc->num_reportedFields; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBeaconReportFrmBody. */ + +tANI_U32 dot11fPackIeBeaconReporting(tpAniSirGlobal pCtx, + tDot11fIEBeaconReporting *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->reportingCondition; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->threshold; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeBeaconReporting. */ + +tANI_U32 dot11fPackIeMeasurementPilot(tpAniSirGlobal pCtx, + tDot11fIEMeasurementPilot *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_vendorSpecific + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 66; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->measurementPilot; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->vendorSpecific ), pSrc->num_vendorSpecific); + *pnConsumed += pSrc->num_vendorSpecific; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeMeasurementPilot. */ + +tANI_U32 dot11fPackIeMultiBssid(tpAniSirGlobal pCtx, + tDot11fIEMultiBssid *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_vendorSpecific + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 71; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->maxBSSIDIndicator; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->vendorSpecific ), pSrc->num_vendorSpecific); + *pnConsumed += pSrc->num_vendorSpecific; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeMultiBssid. */ + +tANI_U32 dot11fPackIeRICData(tpAniSirGlobal pCtx, + tDot11fIERICData *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 57; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->Identifier; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->resourceDescCount; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->statusCode, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRICData. */ + +tANI_U32 dot11fPackIeRICDescriptor(tpAniSirGlobal pCtx, + tDot11fIERICDescriptor *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_variableData + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 75; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->resourceType; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->variableData ), pSrc->num_variableData); + *pnConsumed += pSrc->num_variableData; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRICDescriptor. */ + +tANI_U32 dot11fPackIeRRMEnabledCap(tpAniSirGlobal pCtx, + tDot11fIERRMEnabledCap *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp98__; + tANI_U8 tmp99__; + tANI_U8 tmp100__; + tANI_U8 tmp101__; + tANI_U8 tmp102__; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 70; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp98__ = 0U; + tmp98__ |= ( pSrc->LinkMeasurement << 0 ); + tmp98__ |= ( pSrc->NeighborRpt << 1 ); + tmp98__ |= ( pSrc->parallel << 2 ); + tmp98__ |= ( pSrc->repeated << 3 ); + tmp98__ |= ( pSrc->BeaconPassive << 4 ); + tmp98__ |= ( pSrc->BeaconActive << 5 ); + tmp98__ |= ( pSrc->BeaconTable << 6 ); + tmp98__ |= ( pSrc->BeaconRepCond << 7 ); + *pBuf = tmp98__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp99__ = 0U; + tmp99__ |= ( pSrc->FrameMeasurement << 0 ); + tmp99__ |= ( pSrc->ChannelLoad << 1 ); + tmp99__ |= ( pSrc->NoiseHistogram << 2 ); + tmp99__ |= ( pSrc->statistics << 3 ); + tmp99__ |= ( pSrc->LCIMeasurement << 4 ); + tmp99__ |= ( pSrc->LCIAzimuth << 5 ); + tmp99__ |= ( pSrc->TCMCapability << 6 ); + tmp99__ |= ( pSrc->triggeredTCM << 7 ); + *pBuf = tmp99__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp100__ = 0U; + tmp100__ |= ( pSrc->APChanReport << 0 ); + tmp100__ |= ( pSrc->RRMMIBEnabled << 1 ); + tmp100__ |= ( pSrc->operatingChanMax << 2 ); + tmp100__ |= ( pSrc->nonOperatinChanMax << 5 ); + *pBuf = tmp100__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp101__ = 0U; + tmp101__ |= ( pSrc->MeasurementPilot << 0 ); + tmp101__ |= ( pSrc->MeasurementPilotEnabled << 3 ); + tmp101__ |= ( pSrc->NeighborTSFOffset << 4 ); + tmp101__ |= ( pSrc->RCPIMeasurement << 5 ); + tmp101__ |= ( pSrc->RSNIMeasurement << 6 ); + tmp101__ |= ( pSrc->BssAvgAccessDelay << 7 ); + *pBuf = tmp101__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp102__ = 0U; + tmp102__ |= ( pSrc->BSSAvailAdmission << 0 ); + tmp102__ |= ( pSrc->AntennaInformation << 1 ); + tmp102__ |= ( pSrc->reserved << 2 ); + *pBuf = tmp102__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRRMEnabledCap. */ + +tANI_U32 dot11fPackIeRequestedInfo(tpAniSirGlobal pCtx, + tDot11fIERequestedInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_requested_eids; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 10; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->requested_eids ), pSrc->num_requested_eids); + *pnConsumed += pSrc->num_requested_eids; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRequestedInfo. */ + +tANI_U32 dot11fPackIeSSID(tpAniSirGlobal pCtx, + tDot11fIESSID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_ssid; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 0; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->ssid ), pSrc->num_ssid); + *pnConsumed += pSrc->num_ssid; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSSID. */ + +tANI_U32 dot11fPackIeSchedule(tpAniSirGlobal pCtx, + tDot11fIESchedule *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp103__; + nNeeded += 14; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 15; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp103__ = 0U; + tmp103__ |= ( pSrc->aggregation << 0 ); + tmp103__ |= ( pSrc->tsid << 1 ); + tmp103__ |= ( pSrc->direction << 5 ); + tmp103__ |= ( pSrc->reserved << 7 ); + frameshtons(pCtx, pBuf, tmp103__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_interval, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->spec_interval, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSchedule. */ + +tANI_U32 dot11fPackIeTCLAS(tpAniSirGlobal pCtx, + tDot11fIETCLAS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIETCLAS(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 14; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->user_priority; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_type; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_mask; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6); + *pnConsumed += 6; + pBuf += 6; + frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 1: + *pBuf = pSrc->info.IpParams.version; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4); + *pnConsumed += 4; + pBuf += 4; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.proto; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.reserved; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 6: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 16); + *pnConsumed += 16; + pBuf += 16; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 16); + *pnConsumed += 16; + pBuf += 16; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3); + *pnConsumed += 3; + // fieldsEndFlag = 1 + break; + } + break; + case 2: + frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeTCLAS. */ + +tANI_U32 dot11fPackIeTCLASSPROC(tpAniSirGlobal pCtx, + tDot11fIETCLASSPROC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 44; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->processing; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTCLASSPROC. */ + +tANI_U32 dot11fPackIeTSDelay(tpAniSirGlobal pCtx, + tDot11fIETSDelay *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 43; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtonl(pCtx, pBuf, pSrc->delay, 0); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTSDelay. */ + +tANI_U32 dot11fPackIeTSPEC(tpAniSirGlobal pCtx, + tDot11fIETSPEC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp104__; + tANI_U8 tmp105__; + tANI_U16 tmp106__; + nNeeded += 55; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 13; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp104__ = 0U; + tmp104__ |= ( pSrc->traffic_type << 0 ); + tmp104__ |= ( pSrc->tsid << 1 ); + tmp104__ |= ( pSrc->direction << 5 ); + tmp104__ |= ( pSrc->access_policy << 7 ); + tmp104__ |= ( pSrc->aggregation << 9 ); + tmp104__ |= ( pSrc->psb << 10 ); + tmp104__ |= ( pSrc->user_priority << 11 ); + tmp104__ |= ( pSrc->tsinfo_ack_pol << 14 ); + frameshtons(pCtx, pBuf, tmp104__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp105__ = 0U; + tmp105__ |= ( pSrc->schedule << 0 ); + tmp105__ |= ( pSrc->unused << 1 ); + *pBuf = tmp105__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp106__ = 0U; + tmp106__ |= ( pSrc->size << 0 ); + tmp106__ |= ( pSrc->fixed << 15 ); + frameshtons(pCtx, pBuf, tmp106__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->burst_size, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->medium_time, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTSPEC. */ + +tANI_U32 dot11fPackIeWMMSchedule(tpAniSirGlobal pCtx, + tDot11fIEWMMSchedule *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp107__; + nNeeded += 15; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp107__ = 0U; + tmp107__ |= ( pSrc->aggregation << 0 ); + tmp107__ |= ( pSrc->tsid << 1 ); + tmp107__ |= ( pSrc->direction << 5 ); + tmp107__ |= ( pSrc->reserved << 7 ); + frameshtons(pCtx, pBuf, tmp107__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_interval, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->max_service_dur, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->spec_interval, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMSchedule. */ + +tANI_U32 dot11fPackIeWMMTCLAS(tpAniSirGlobal pCtx, + tDot11fIEWMMTCLAS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEWMMTCLAS(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->user_priority; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_type; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->classifier_mask; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->classifier_type) + { + case 0: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.source, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.EthParams.dest, 6); + *pnConsumed += 6; + pBuf += 6; + frameshtons(pCtx, pBuf, pSrc->info.EthParams.type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 1: + *pBuf = pSrc->info.IpParams.version; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->info.IpParams.version) + { + case 4: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.source, 4); + *pnConsumed += 4; + pBuf += 4; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest, 4); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV4Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->info.IpParams.params.IpV4Params.DSCP; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.proto; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->info.IpParams.params.IpV4Params.reserved; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 6: + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.source, 10); + *pnConsumed += 10; + pBuf += 10; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest, 10); + *pnConsumed += 10; + pBuf += 10; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.src_port, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.dest_port, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->info.IpParams.params.IpV6Params.flow_label, 3); + *pnConsumed += 3; + // fieldsEndFlag = 1 + break; + } + break; + case 2: + frameshtons(pCtx, pBuf, pSrc->info.Params8021dq.tag_type, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeWMMTCLAS. */ + +tANI_U32 dot11fPackIeWMMTCLASPROC(tpAniSirGlobal pCtx, + tDot11fIEWMMTCLASPROC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x7; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->processing; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMTCLASPROC. */ + +tANI_U32 dot11fPackIeWMMTSDelay(tpAniSirGlobal pCtx, + tDot11fIEWMMTSDelay *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x8; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + frameshtonl(pCtx, pBuf, pSrc->delay, 0); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMTSDelay. */ + +tANI_U32 dot11fPackIeWMMTSPEC(tpAniSirGlobal pCtx, + tDot11fIEWMMTSPEC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp108__; + tANI_U8 tmp109__; + tANI_U16 tmp110__; + nNeeded += 38; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp108__ = 0U; + tmp108__ |= ( pSrc->traffic_type << 0 ); + tmp108__ |= ( pSrc->tsid << 1 ); + tmp108__ |= ( pSrc->direction << 5 ); + tmp108__ |= ( pSrc->access_policy << 7 ); + tmp108__ |= ( pSrc->aggregation << 9 ); + tmp108__ |= ( pSrc->psb << 10 ); + tmp108__ |= ( pSrc->user_priority << 11 ); + tmp108__ |= ( pSrc->tsinfo_ack_pol << 14 ); + frameshtons(pCtx, pBuf, tmp108__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp109__ = 0U; + tmp109__ |= ( pSrc->tsinfo_rsvd << 0 ); + tmp109__ |= ( pSrc->burst_size_defn << 7 ); + *pBuf = tmp109__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp110__ = 0U; + tmp110__ |= ( pSrc->size << 0 ); + tmp110__ |= ( pSrc->fixed << 15 ); + frameshtons(pCtx, pBuf, tmp110__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtons(pCtx, pBuf, pSrc->max_msdu_size, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtonl(pCtx, pBuf, pSrc->min_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->max_service_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->inactivity_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->suspension_int, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->service_start_time, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->mean_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->peak_data_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->burst_size, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->delay_bound, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtonl(pCtx, pBuf, pSrc->min_phy_rate, 0); + *pnConsumed += 4; + pBuf += 4; + frameshtons(pCtx, pBuf, pSrc->surplus_bw_allowance, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->medium_time, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMTSPEC. */ + +tANI_U32 dot11fPackIeAID(tpAniSirGlobal pCtx, + tDot11fIEAID *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 197; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->assocId, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeAID. */ + +tANI_U32 dot11fPackIeAirgo(tpAniSirGlobal pCtx, + tDot11fIEAirgo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEAirgo(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xa; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf5; + ++pBuf; --nBuf; ++(*pnConsumed); + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_Airgo, + IES_Airgo); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeAirgo. */ + +tANI_U32 dot11fPackIeCFParams(tpAniSirGlobal pCtx, + tDot11fIECFParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 4; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->cfp_count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->cfp_period; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->cfp_maxduration, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->cfp_durremaining, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeCFParams. */ + +tANI_U32 dot11fPackIeChallengeText(tpAniSirGlobal pCtx, + tDot11fIEChallengeText *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_text; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 16; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->text ), pSrc->num_text); + *pnConsumed += pSrc->num_text; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeChallengeText. */ + +tANI_U32 dot11fPackIeChanSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEChanSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 37; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->switchMode; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->newChannel; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->switchCount; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeChanSwitchAnn. */ + +tANI_U32 dot11fPackIeCountry(tpAniSirGlobal pCtx, + tDot11fIECountry *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIECountry(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 7; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->country, 3); + *pnConsumed += 3; + pBuf += 3; + if ( pSrc->num_triplets ) { + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->triplets ), ( pSrc->num_triplets * 3 )); + *pnConsumed += ( pSrc->num_triplets * 3 ); + // fieldsEndFlag = 1 + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeCountry. */ + +tANI_U32 dot11fPackIeDSParams(tpAniSirGlobal pCtx, + tDot11fIEDSParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 3; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->curr_channel; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeDSParams. */ + +tANI_U32 dot11fPackIeEDCAParamSet(tpAniSirGlobal pCtx, + tDot11fIEEDCAParamSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp111__; + tANI_U8 tmp112__; + tANI_U8 tmp113__; + tANI_U8 tmp114__; + tANI_U8 tmp115__; + tANI_U8 tmp116__; + tANI_U8 tmp117__; + tANI_U8 tmp118__; + nNeeded += 18; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 12; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->qos; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved; + *pnConsumed += 1; + pBuf += 1; + tmp111__ = 0U; + tmp111__ |= ( pSrc->acbe_aifsn << 0 ); + tmp111__ |= ( pSrc->acbe_acm << 4 ); + tmp111__ |= ( pSrc->acbe_aci << 5 ); + tmp111__ |= ( pSrc->unused1 << 7 ); + *pBuf = tmp111__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp112__ = 0U; + tmp112__ |= ( pSrc->acbe_acwmin << 0 ); + tmp112__ |= ( pSrc->acbe_acwmax << 4 ); + *pBuf = tmp112__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp113__ = 0U; + tmp113__ |= ( pSrc->acbk_aifsn << 0 ); + tmp113__ |= ( pSrc->acbk_acm << 4 ); + tmp113__ |= ( pSrc->acbk_aci << 5 ); + tmp113__ |= ( pSrc->unused2 << 7 ); + *pBuf = tmp113__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp114__ = 0U; + tmp114__ |= ( pSrc->acbk_acwmin << 0 ); + tmp114__ |= ( pSrc->acbk_acwmax << 4 ); + *pBuf = tmp114__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp115__ = 0U; + tmp115__ |= ( pSrc->acvi_aifsn << 0 ); + tmp115__ |= ( pSrc->acvi_acm << 4 ); + tmp115__ |= ( pSrc->acvi_aci << 5 ); + tmp115__ |= ( pSrc->unused3 << 7 ); + *pBuf = tmp115__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp116__ = 0U; + tmp116__ |= ( pSrc->acvi_acwmin << 0 ); + tmp116__ |= ( pSrc->acvi_acwmax << 4 ); + *pBuf = tmp116__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp117__ = 0U; + tmp117__ |= ( pSrc->acvo_aifsn << 0 ); + tmp117__ |= ( pSrc->acvo_acm << 4 ); + tmp117__ |= ( pSrc->acvo_aci << 5 ); + tmp117__ |= ( pSrc->unused4 << 7 ); + *pBuf = tmp117__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp118__ = 0U; + tmp118__ |= ( pSrc->acvo_acwmin << 0 ); + tmp118__ |= ( pSrc->acvo_acwmax << 4 ); + *pBuf = tmp118__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeEDCAParamSet. */ + +tANI_U32 dot11fPackIeERPInfo(tpAniSirGlobal pCtx, + tDot11fIEERPInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp119__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 42; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp119__ = 0U; + tmp119__ |= ( pSrc->non_erp_present << 0 ); + tmp119__ |= ( pSrc->use_prot << 1 ); + tmp119__ |= ( pSrc->barker_preamble << 2 ); + tmp119__ |= ( pSrc->unused << 3 ); + *pBuf = tmp119__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeERPInfo. */ + +tANI_U32 dot11fPackIeESECckmOpaque(tpAniSirGlobal pCtx, + tDot11fIEESECckmOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 156; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESECckmOpaque. */ + +tANI_U32 dot11fPackIeESERadMgmtCap(tpAniSirGlobal pCtx, + tDot11fIEESERadMgmtCap *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp120__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->mgmt_state; + *pnConsumed += 1; + pBuf += 1; + tmp120__ = 0U; + tmp120__ |= ( pSrc->mbssid_mask << 0 ); + tmp120__ |= ( pSrc->reserved << 3 ); + *pBuf = tmp120__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESERadMgmtCap. */ + +tANI_U32 dot11fPackIeESETrafStrmMet(tpAniSirGlobal pCtx, + tDot11fIEESETrafStrmMet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 4; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x7; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tsid; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->state; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->msmt_interval, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESETrafStrmMet. */ + +tANI_U32 dot11fPackIeESETrafStrmRateSet(tpAniSirGlobal pCtx, + tDot11fIEESETrafStrmRateSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_tsrates + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x8; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tsid; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->tsrates ), pSrc->num_tsrates); + *pnConsumed += pSrc->num_tsrates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESETrafStrmRateSet. */ + +tANI_U32 dot11fPackIeESETxmitPower(tpAniSirGlobal pCtx, + tDot11fIEESETxmitPower *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 150; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->power_limit; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESETxmitPower. */ + +tANI_U32 dot11fPackIeESEVersion(tpAniSirGlobal pCtx, + tDot11fIEESEVersion *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x40; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x96; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x3; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeESEVersion. */ + +tANI_U32 dot11fPackIeExtCap(tpAniSirGlobal pCtx, + tDot11fIEExtCap *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_bytes; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 127; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->bytes ), pSrc->num_bytes); + *pnConsumed += pSrc->num_bytes; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeExtCap. */ + +tANI_U32 dot11fPackIeExtChanSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEExtChanSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 62; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->secondaryChannelOffset; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeExtChanSwitchAnn. */ + +tANI_U32 dot11fPackIeExtSuppRates(tpAniSirGlobal pCtx, + tDot11fIEExtSuppRates *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_rates; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 50; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rates ), pSrc->num_rates); + *pnConsumed += pSrc->num_rates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeExtSuppRates. */ + +tANI_U32 dot11fPackIeFHParamSet(tpAniSirGlobal pCtx, + tDot11fIEFHParamSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 2; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->dwell_time, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->hop_set; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->hop_pattern; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->hop_index; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeFHParamSet. */ + +tANI_U32 dot11fPackIeFHParams(tpAniSirGlobal pCtx, + tDot11fIEFHParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 8; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->radix; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->nchannels; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeFHParams. */ + +tANI_U32 dot11fPackIeFHPattTable(tpAniSirGlobal pCtx, + tDot11fIEFHPattTable *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_randtable + 4); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 9; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->flag; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->nsets; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->modulus; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->offset; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->randtable ), pSrc->num_randtable); + *pnConsumed += pSrc->num_randtable; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeFHPattTable. */ + +tANI_U32 dot11fPackIeFTInfo(tpAniSirGlobal pCtx, + tDot11fIEFTInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp121__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEFTInfo(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 55; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + tmp121__ = 0U; + tmp121__ |= ( pSrc->reserved << 0 ); + tmp121__ |= ( pSrc->IECount << 8 ); + frameshtons(pCtx, pBuf, tmp121__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->MIC, 16); + *pnConsumed += 16; + pBuf += 16; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->Anonce, 32); + *pnConsumed += 32; + pBuf += 32; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->Snonce, 32); + *pnConsumed += 32; + pBuf += 32; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_FTInfo, + IES_FTInfo); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeFTInfo. */ + +tANI_U32 dot11fPackIeHT2040BSSCoexistence(tpAniSirGlobal pCtx, + tDot11fIEHT2040BSSCoexistence *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp122__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 72; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp122__ = 0U; + tmp122__ |= ( pSrc->infoRequest << 0 ); + tmp122__ |= ( pSrc->fortyMHzIntolerant << 1 ); + tmp122__ |= ( pSrc->twentyMHzBssWidthReq << 2 ); + tmp122__ |= ( pSrc->obssScanExemptionReq << 3 ); + tmp122__ |= ( pSrc->obssScanExemptionGrant << 4 ); + tmp122__ |= ( pSrc->unused << 5 ); + *pBuf = tmp122__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHT2040BSSCoexistence. */ + +tANI_U32 dot11fPackIeHT2040BSSIntolerantReport(tpAniSirGlobal pCtx, + tDot11fIEHT2040BSSIntolerantReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_channelList + 1); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 73; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->operatingClass; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->channelList ), pSrc->num_channelList); + *pnConsumed += pSrc->num_channelList; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHT2040BSSIntolerantReport. */ + +tANI_U32 dot11fPackIeHTCaps(tpAniSirGlobal pCtx, + tDot11fIEHTCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp123__; + tANI_U8 tmp124__; + tANI_U16 tmp125__; + tANI_U32 tmp126__; + tANI_U8 tmp127__; + nNeeded += (pSrc->num_rsvd + 26); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 45; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp123__ = 0U; + tmp123__ |= ( pSrc->advCodingCap << 0 ); + tmp123__ |= ( pSrc->supportedChannelWidthSet << 1 ); + tmp123__ |= ( pSrc->mimoPowerSave << 2 ); + tmp123__ |= ( pSrc->greenField << 4 ); + tmp123__ |= ( pSrc->shortGI20MHz << 5 ); + tmp123__ |= ( pSrc->shortGI40MHz << 6 ); + tmp123__ |= ( pSrc->txSTBC << 7 ); + tmp123__ |= ( pSrc->rxSTBC << 8 ); + tmp123__ |= ( pSrc->delayedBA << 10 ); + tmp123__ |= ( pSrc->maximalAMSDUsize << 11 ); + tmp123__ |= ( pSrc->dsssCckMode40MHz << 12 ); + tmp123__ |= ( pSrc->psmp << 13 ); + tmp123__ |= ( pSrc->stbcControlFrame << 14 ); + tmp123__ |= ( pSrc->lsigTXOPProtection << 15 ); + frameshtons(pCtx, pBuf, tmp123__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp124__ = 0U; + tmp124__ |= ( pSrc->maxRxAMPDUFactor << 0 ); + tmp124__ |= ( pSrc->mpduDensity << 2 ); + tmp124__ |= ( pSrc->reserved1 << 5 ); + *pBuf = tmp124__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->supportedMCSSet, 16); + *pnConsumed += 16; + pBuf += 16; + tmp125__ = 0U; + tmp125__ |= ( pSrc->pco << 0 ); + tmp125__ |= ( pSrc->transitionTime << 1 ); + tmp125__ |= ( pSrc->reserved2 << 3 ); + tmp125__ |= ( pSrc->mcsFeedback << 8 ); + tmp125__ |= ( pSrc->reserved3 << 10 ); + frameshtons(pCtx, pBuf, tmp125__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp126__ = 0U; + tmp126__ |= ( pSrc->txBF << 0 ); + tmp126__ |= ( pSrc->rxStaggeredSounding << 1 ); + tmp126__ |= ( pSrc->txStaggeredSounding << 2 ); + tmp126__ |= ( pSrc->rxZLF << 3 ); + tmp126__ |= ( pSrc->txZLF << 4 ); + tmp126__ |= ( pSrc->implicitTxBF << 5 ); + tmp126__ |= ( pSrc->calibration << 6 ); + tmp126__ |= ( pSrc->explicitCSITxBF << 8 ); + tmp126__ |= ( pSrc->explicitUncompressedSteeringMatrix << 9 ); + tmp126__ |= ( pSrc->explicitBFCSIFeedback << 10 ); + tmp126__ |= ( pSrc->explicitUncompressedSteeringMatrixFeedback << 13 ); + tmp126__ |= ( pSrc->explicitCompressedSteeringMatrixFeedback << 16 ); + tmp126__ |= ( pSrc->csiNumBFAntennae << 19 ); + tmp126__ |= ( pSrc->uncompressedSteeringMatrixBFAntennae << 21 ); + tmp126__ |= ( pSrc->compressedSteeringMatrixBFAntennae << 23 ); + tmp126__ |= ( pSrc->reserved4 << 25 ); + frameshtonl(pCtx, pBuf, tmp126__, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4 ; + tmp127__ = 0U; + tmp127__ |= ( pSrc->antennaSelection << 0 ); + tmp127__ |= ( pSrc->explicitCSIFeedbackTx << 1 ); + tmp127__ |= ( pSrc->antennaIndicesFeedbackTx << 2 ); + tmp127__ |= ( pSrc->explicitCSIFeedback << 3 ); + tmp127__ |= ( pSrc->antennaIndicesFeedback << 4 ); + tmp127__ |= ( pSrc->rxAS << 5 ); + tmp127__ |= ( pSrc->txSoundingPPDUs << 6 ); + tmp127__ |= ( pSrc->reserved5 << 7 ); + *pBuf = tmp127__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rsvd ), pSrc->num_rsvd); + *pnConsumed += pSrc->num_rsvd; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHTCaps. */ + +tANI_U32 dot11fPackIeHTInfo(tpAniSirGlobal pCtx, + tDot11fIEHTInfo *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp128__; + tANI_U16 tmp129__; + tANI_U16 tmp130__; + nNeeded += (pSrc->num_rsvd + 22); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 61; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->primaryChannel; + *pnConsumed += 1; + pBuf += 1; + tmp128__ = 0U; + tmp128__ |= ( pSrc->secondaryChannelOffset << 0 ); + tmp128__ |= ( pSrc->recommendedTxWidthSet << 2 ); + tmp128__ |= ( pSrc->rifsMode << 3 ); + tmp128__ |= ( pSrc->controlledAccessOnly << 4 ); + tmp128__ |= ( pSrc->serviceIntervalGranularity << 5 ); + *pBuf = tmp128__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp129__ = 0U; + tmp129__ |= ( pSrc->opMode << 0 ); + tmp129__ |= ( pSrc->nonGFDevicesPresent << 2 ); + tmp129__ |= ( pSrc->transmitBurstLimit << 3 ); + tmp129__ |= ( pSrc->obssNonHTStaPresent << 4 ); + tmp129__ |= ( pSrc->reserved << 5 ); + frameshtons(pCtx, pBuf, tmp129__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + tmp130__ = 0U; + tmp130__ |= ( pSrc->basicSTBCMCS << 0 ); + tmp130__ |= ( pSrc->dualCTSProtection << 7 ); + tmp130__ |= ( pSrc->secondaryBeacon << 8 ); + tmp130__ |= ( pSrc->lsigTXOPProtectionFullSupport << 9 ); + tmp130__ |= ( pSrc->pcoActive << 10 ); + tmp130__ |= ( pSrc->pcoPhase << 11 ); + tmp130__ |= ( pSrc->reserved2 << 12 ); + frameshtons(pCtx, pBuf, tmp130__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->basicMCSSet, 16); + *pnConsumed += 16; + pBuf += 16; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rsvd ), pSrc->num_rsvd); + *pnConsumed += pSrc->num_rsvd; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeHTInfo. */ + +tANI_U32 dot11fPackIeIBSSParams(tpAniSirGlobal pCtx, + tDot11fIEIBSSParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 6; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->atim, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeIBSSParams. */ + +tANI_U32 dot11fPackIeLinkIdentifier(tpAniSirGlobal pCtx, + tDot11fIELinkIdentifier *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 18; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 101; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->InitStaAddr, 6); + *pnConsumed += 6; + pBuf += 6; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->RespStaAddr, 6); + *pnConsumed += 6; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeLinkIdentifier. */ + +tANI_U32 dot11fPackIeMeasurementReport(tpAniSirGlobal pCtx, + tDot11fIEMeasurementReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp131__; + tANI_U8 tmp132__; + tANI_U8 tmp133__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEMeasurementReport(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 39; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->token; + *pnConsumed += 1; + pBuf += 1; + tmp131__ = 0U; + tmp131__ |= ( pSrc->late << 0 ); + tmp131__ |= ( pSrc->incapable << 1 ); + tmp131__ |= ( pSrc->refused << 2 ); + tmp131__ |= ( pSrc->unused << 3 ); + *pBuf = tmp131__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->type; + *pnConsumed += 1; + pBuf += 1; + if ( pSrc->type ) { + switch (pSrc->type) + { + case 0: + *pBuf = pSrc->report.Basic.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.Basic.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.Basic.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + tmp132__ = 0U; + tmp132__ |= ( pSrc->report.Basic.bss << 0 ); + tmp132__ |= ( pSrc->report.Basic.ofdm_preamble << 1 ); + tmp132__ |= ( pSrc->report.Basic.unid_signal << 2 ); + tmp132__ |= ( pSrc->report.Basic.rader << 3 ); + tmp132__ |= ( pSrc->report.Basic.unmeasured << 4 ); + tmp132__ |= ( pSrc->report.Basic.unused << 5 ); + *pBuf = tmp132__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + case 1: + *pBuf = pSrc->report.CCA.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.CCA.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.CCA.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->report.CCA.cca_busy_fraction; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 2: + *pBuf = pSrc->report.RPIHistogram.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.RPIHistogram.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.RPIHistogram.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->report.RPIHistogram.rpi0_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi1_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi2_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi3_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi4_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi5_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi6_density; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.RPIHistogram.rpi7_density; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + case 5: + *pBuf = pSrc->report.Beacon.regClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.Beacon.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtonq(pCtx, pBuf, pSrc->report.Beacon.meas_start_time, 0); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->report.Beacon.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + tmp133__ = 0U; + tmp133__ |= ( pSrc->report.Beacon.condensed_PHY << 0 ); + tmp133__ |= ( pSrc->report.Beacon.reported_frame_type << 7 ); + *pBuf = tmp133__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->report.Beacon.RCPI; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->report.Beacon.RSNI; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->report.Beacon.BSSID, 6); + *pnConsumed += 6; + pBuf += 6; + *pBuf = pSrc->report.Beacon.antenna_id; + *pnConsumed += 1; + pBuf += 1; + frameshtonl(pCtx, pBuf, pSrc->report.Beacon.parent_TSF, 0); + *pnConsumed += 4; + pBuf += 4; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_reportBeacon, + IES_reportBeacon); + break; + } + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeMeasurementReport. */ + +tANI_U32 dot11fPackIeMeasurementRequest(tpAniSirGlobal pCtx, + tDot11fIEMeasurementRequest *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp134__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEMeasurementRequest(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 38; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->measurement_token; + *pnConsumed += 1; + pBuf += 1; + tmp134__ = 0U; + tmp134__ |= ( pSrc->parallel << 0 ); + tmp134__ |= ( pSrc->enable << 1 ); + tmp134__ |= ( pSrc->request << 2 ); + tmp134__ |= ( pSrc->report << 3 ); + tmp134__ |= ( pSrc->durationMandatory << 4 ); + tmp134__ |= ( pSrc->unused << 5 ); + *pBuf = tmp134__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + *pBuf = pSrc->measurement_type; + *pnConsumed += 1; + pBuf += 1; + switch (pSrc->measurement_type) + { + case 0: + *pBuf = pSrc->measurement_request.Basic.channel_no; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Basic.meas_start_time, 8); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->measurement_request.Basic.meas_duration, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 1: + *pBuf = pSrc->measurement_request.CCA.channel_no; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.CCA.meas_start_time, 8); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->measurement_request.CCA.meas_duration, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 2: + *pBuf = pSrc->measurement_request.RPIHistogram.channel_no; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_start_time, 8); + *pnConsumed += 8; + pBuf += 8; + frameshtons(pCtx, pBuf, pSrc->measurement_request.RPIHistogram.meas_duration, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 5: + *pBuf = pSrc->measurement_request.Beacon.regClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->measurement_request.Beacon.channel; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.randomization, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->measurement_request.Beacon.meas_duration, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->measurement_request.Beacon.meas_mode; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->measurement_request.Beacon.BSSID, 6); + *pnConsumed += 6; + pBuf += 6; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_measurement_requestBeacon, + IES_measurement_requestBeacon); + break; + } + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeMeasurementRequest. */ + +tANI_U32 dot11fPackIeMobilityDomain(tpAniSirGlobal pCtx, + tDot11fIEMobilityDomain *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp135__; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 54; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->MDID, 0); + *pnConsumed += 2; + pBuf += 2; + tmp135__ = 0U; + tmp135__ |= ( pSrc->overDSCap << 0 ); + tmp135__ |= ( pSrc->resourceReqCap << 1 ); + tmp135__ |= ( pSrc->reserved << 2 ); + *pBuf = tmp135__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeMobilityDomain. */ + +tANI_U32 dot11fPackIeNeighborReport(tpAniSirGlobal pCtx, + tDot11fIENeighborReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp136__; + tANI_U8 tmp137__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIENeighborReport(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 52; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->bssid, 6); + *pnConsumed += 6; + pBuf += 6; + tmp136__ = 0U; + tmp136__ |= ( pSrc->APReachability << 0 ); + tmp136__ |= ( pSrc->Security << 2 ); + tmp136__ |= ( pSrc->KeyScope << 3 ); + tmp136__ |= ( pSrc->SpecMgmtCap << 4 ); + tmp136__ |= ( pSrc->QosCap << 5 ); + tmp136__ |= ( pSrc->apsd << 6 ); + tmp136__ |= ( pSrc->rrm << 7 ); + *pBuf = tmp136__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp137__ = 0U; + tmp137__ |= ( pSrc->DelayedBA << 0 ); + tmp137__ |= ( pSrc->ImmBA << 1 ); + tmp137__ |= ( pSrc->MobilityDomain << 2 ); + tmp137__ |= ( pSrc->reserved << 3 ); + *pBuf = tmp137__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->reserved1, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->regulatoryClass; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->channel; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->PhyType; + *pnConsumed += 1; + pBuf += 1; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_NeighborReport, + IES_NeighborReport); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeNeighborReport. */ + +tANI_U32 dot11fPackIeOBSSScanParameters(tpAniSirGlobal pCtx, + tDot11fIEOBSSScanParameters *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 14; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 74; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->obssScanPassiveDwell, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanActiveDwell, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->bssChannelWidthTriggerScanInterval, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanPassiveTotalPerChannel, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanActiveTotalPerChannel, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->bssWidthChannelTransitionDelayFactor, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->obssScanActivityThreshold, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeOBSSScanParameters. */ + +tANI_U32 dot11fPackIeOperatingMode(tpAniSirGlobal pCtx, + tDot11fIEOperatingMode *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp138__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 199; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp138__ = 0U; + tmp138__ |= ( pSrc->chanWidth << 0 ); + tmp138__ |= ( pSrc->reserved << 2 ); + tmp138__ |= ( pSrc->rxNSS << 4 ); + tmp138__ |= ( pSrc->rxNSSType << 7 ); + *pBuf = tmp138__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeOperatingMode. */ + +tANI_U32 dot11fPackIeP2PAssocReq(tpAniSirGlobal pCtx, + tDot11fIEP2PAssocReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PAssocReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PAssocReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PAssocReq. */ + +tANI_U32 dot11fPackIeP2PAssocRes(tpAniSirGlobal pCtx, + tDot11fIEP2PAssocRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PAssocRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PAssocRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PAssocRes. */ + +tANI_U32 dot11fPackIeP2PBeacon(tpAniSirGlobal pCtx, + tDot11fIEP2PBeacon *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PBeacon(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PBeacon+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PBeacon. */ + +tANI_U32 dot11fPackIeP2PBeaconProbeRes(tpAniSirGlobal pCtx, + tDot11fIEP2PBeaconProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PBeaconProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PBeaconProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PBeaconProbeRes. */ + +tANI_U32 dot11fPackIeP2PDeAuth(tpAniSirGlobal pCtx, + tDot11fIEP2PDeAuth *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDeAuth(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDeAuth+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDeAuth. */ + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, + tDot11fIEP2PDeviceDiscoverabilityReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDeviceDiscoverabilityReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDeviceDiscoverabilityReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDeviceDiscoverabilityReq. */ + +tANI_U32 dot11fPackIeP2PDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, + tDot11fIEP2PDeviceDiscoverabilityRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDeviceDiscoverabilityRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDeviceDiscoverabilityRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDeviceDiscoverabilityRes. */ + +tANI_U32 dot11fPackIeP2PDisAssoc(tpAniSirGlobal pCtx, + tDot11fIEP2PDisAssoc *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PDisAssoc(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PDisAssoc+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PDisAssoc. */ + +tANI_U32 dot11fPackIeP2PGONegCnf(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegCnf *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegCnf(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegCnf+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegCnf. */ + +tANI_U32 dot11fPackIeP2PGONegReq(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegReq. */ + +tANI_U32 dot11fPackIeP2PGONegRes(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegRes. */ + +tANI_U32 dot11fPackIeP2PGONegWPS(tpAniSirGlobal pCtx, + tDot11fIEP2PGONegWPS *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PGONegWPS(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PGONegWPS+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PGONegWPS. */ + +tANI_U32 dot11fPackIeP2PIEOpaque(tpAniSirGlobal pCtx, + tDot11fIEP2PIEOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeP2PIEOpaque. */ + +tANI_U32 dot11fPackIeP2PInvitationReq(tpAniSirGlobal pCtx, + tDot11fIEP2PInvitationReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PInvitationReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PInvitationReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PInvitationReq. */ + +tANI_U32 dot11fPackIeP2PInvitationRes(tpAniSirGlobal pCtx, + tDot11fIEP2PInvitationRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PInvitationRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PInvitationRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PInvitationRes. */ + +tANI_U32 dot11fPackIeP2PNoticeOfAbsence(tpAniSirGlobal pCtx, + tDot11fIEP2PNoticeOfAbsence *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PNoticeOfAbsence(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PNoticeOfAbsence+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PNoticeOfAbsence. */ + +tANI_U32 dot11fPackIeP2PPresenceResponse(tpAniSirGlobal pCtx, + tDot11fIEP2PPresenceResponse *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PPresenceResponse(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PPresenceResponse+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PPresenceResponse. */ + +tANI_U32 dot11fPackIeP2PProbeReq(tpAniSirGlobal pCtx, + tDot11fIEP2PProbeReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PProbeReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PProbeReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PProbeReq. */ + +tANI_U32 dot11fPackIeP2PProbeRes(tpAniSirGlobal pCtx, + tDot11fIEP2PProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PProbeRes. */ + +tANI_U32 dot11fPackIeP2PProvisionDiscoveryReq(tpAniSirGlobal pCtx, + tDot11fIEP2PProvisionDiscoveryReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PProvisionDiscoveryReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x9; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PProvisionDiscoveryReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PProvisionDiscoveryReq. */ + +tANI_U32 dot11fPackIeP2PWSCProvisionDiscoveryRes(tpAniSirGlobal pCtx, + tDot11fIEP2PWSCProvisionDiscoveryRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEP2PWSCProvisionDiscoveryRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_P2PWSCProvisionDiscoveryRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeP2PWSCProvisionDiscoveryRes. */ + +tANI_U32 dot11fPackIePTIControl(tpAniSirGlobal pCtx, + tDot11fIEPTIControl *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 105; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tid; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->sequence_control, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePTIControl. */ + +tANI_U32 dot11fPackIePUBufferStatus(tpAniSirGlobal pCtx, + tDot11fIEPUBufferStatus *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp139__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 106; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp139__ = 0U; + tmp139__ |= ( pSrc->ac_bk_traffic_aval << 0 ); + tmp139__ |= ( pSrc->ac_be_traffic_aval << 1 ); + tmp139__ |= ( pSrc->ac_vi_traffic_aval << 2 ); + tmp139__ |= ( pSrc->ac_vo_traffic_aval << 3 ); + tmp139__ |= ( pSrc->reserved << 4 ); + *pBuf = tmp139__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePUBufferStatus. */ + +tANI_U32 dot11fPackIePowerCaps(tpAniSirGlobal pCtx, + tDot11fIEPowerCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 33; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->minTxPower; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->maxTxPower; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePowerCaps. */ + +tANI_U32 dot11fPackIePowerConstraints(tpAniSirGlobal pCtx, + tDot11fIEPowerConstraints *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 32; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->localPowerConstraints; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIePowerConstraints. */ + +tANI_U32 dot11fPackIeQBSSLoad(tpAniSirGlobal pCtx, + tDot11fIEQBSSLoad *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 11; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->stacount, 0); + *pnConsumed += 2; + pBuf += 2; + *pBuf = pSrc->chautil; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->avail, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQBSSLoad. */ + +tANI_U32 dot11fPackIeQOSCapsAp(tpAniSirGlobal pCtx, + tDot11fIEQOSCapsAp *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp140__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 46; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp140__ = 0U; + tmp140__ |= ( pSrc->count << 0 ); + tmp140__ |= ( pSrc->qack << 4 ); + tmp140__ |= ( pSrc->qreq << 5 ); + tmp140__ |= ( pSrc->txopreq << 6 ); + tmp140__ |= ( pSrc->reserved << 7 ); + *pBuf = tmp140__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQOSCapsAp. */ + +tANI_U32 dot11fPackIeQOSCapsStation(tpAniSirGlobal pCtx, + tDot11fIEQOSCapsStation *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp141__; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 46; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp141__ = 0U; + tmp141__ |= ( pSrc->acvo_uapsd << 0 ); + tmp141__ |= ( pSrc->acvi_uapsd << 1 ); + tmp141__ |= ( pSrc->acbk_uapsd << 2 ); + tmp141__ |= ( pSrc->acbe_uapsd << 3 ); + tmp141__ |= ( pSrc->qack << 4 ); + tmp141__ |= ( pSrc->max_sp_length << 5 ); + tmp141__ |= ( pSrc->more_data_ack << 7 ); + *pBuf = tmp141__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQOSCapsStation. */ + +tANI_U32 dot11fPackIeQosMapSet(tpAniSirGlobal pCtx, + tDot11fIEQosMapSet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_dscp_exceptions; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 110; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->dscp_exceptions ), pSrc->num_dscp_exceptions); + *pnConsumed += pSrc->num_dscp_exceptions; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQosMapSet. */ + +tANI_U32 dot11fPackIeQuiet(tpAniSirGlobal pCtx, + tDot11fIEQuiet *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 6; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 40; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->period; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->duration, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->offset, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeQuiet. */ + +tANI_U32 dot11fPackIeRCPIIE(tpAniSirGlobal pCtx, + tDot11fIERCPIIE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 53; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->rcpi; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRCPIIE. */ + +tANI_U32 dot11fPackIeRICDataDesc(tpAniSirGlobal pCtx, + tDot11fIERICDataDesc *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIERICDataDesc(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + status = PackCore(pCtx, + (tANI_U8*)pSrc, + pBuf, + nBuf, + pnConsumed, + FFS_RICDataDesc, + IES_RICDataDesc); + break; + } + (void)pCtx; + return status; +} /* End dot11fPackIeRICDataDesc. */ + +tANI_U32 dot11fPackIeRSN(tpAniSirGlobal pCtx, + tDot11fIERSN *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIERSN(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 48; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->version, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_cipher_suite, 4); + *pnConsumed += 4; + pBuf += 4; + if ( pSrc->pwise_cipher_suite_count ) { + frameshtons(pCtx, pBuf, pSrc->pwise_cipher_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->pwise_cipher_suites ), ( pSrc->pwise_cipher_suite_count * 4 )); + *pnConsumed += ( pSrc->pwise_cipher_suite_count * 4 ); + pBuf += ( pSrc->pwise_cipher_suite_count * 4 ); + if ( pSrc->akm_suite_count ) { + frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->akm_suites ), ( pSrc->akm_suite_count * 4 )); + *pnConsumed += ( pSrc->akm_suite_count * 4 ); + pBuf += ( pSrc->akm_suite_count * 4 ); + if ( pSrc->RSN_Cap ) { + DOT11F_MEMCPY(pCtx, pBuf, pSrc->RSN_Cap, 2); + *pnConsumed += 2; + pBuf += 2; + } + else break; + if ( pSrc->pmkid_count ) { + frameshtons(pCtx, pBuf, pSrc->pmkid_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->pmkid ), ( pSrc->pmkid_count * 16 )); + *pnConsumed += ( pSrc->pmkid_count * 16 ); + pBuf += ( pSrc->pmkid_count * 16 ); + if ( pSrc->gp_mgmt_cipher_suite ) { + DOT11F_MEMCPY(pCtx, pBuf, pSrc->gp_mgmt_cipher_suite, 4); + *pnConsumed += 4; + // fieldsEndFlag = 1 + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeRSN. */ + +tANI_U32 dot11fPackIeRSNIIE(tpAniSirGlobal pCtx, + tDot11fIERSNIIE *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 1; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 65; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->rsni; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRSNIIE. */ + +tANI_U32 dot11fPackIeRSNOpaque(tpAniSirGlobal pCtx, + tDot11fIERSNOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 48; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeRSNOpaque. */ + +tANI_U32 dot11fPackIeSuppChannels(tpAniSirGlobal pCtx, + tDot11fIESuppChannels *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_bands * 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 36; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->bands ), ( pSrc->num_bands * 2 )); + *pnConsumed += ( pSrc->num_bands * 2 ); + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSuppChannels. */ + +tANI_U32 dot11fPackIeSuppOperatingClasses(tpAniSirGlobal pCtx, + tDot11fIESuppOperatingClasses *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_classes; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 59; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->classes ), pSrc->num_classes); + *pnConsumed += pSrc->num_classes; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSuppOperatingClasses. */ + +tANI_U32 dot11fPackIeSuppRates(tpAniSirGlobal pCtx, + tDot11fIESuppRates *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_rates; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 1; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->rates ), pSrc->num_rates); + *pnConsumed += pSrc->num_rates; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeSuppRates. */ + +tANI_U32 dot11fPackIeTIM(tpAniSirGlobal pCtx, + tDot11fIETIM *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += (pSrc->num_vbmp + 3); + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 5; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->dtim_count; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->dtim_period; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->bmpctl; + *pnConsumed += 1; + pBuf += 1; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->vbmp ), pSrc->num_vbmp); + *pnConsumed += pSrc->num_vbmp; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTIM. */ + +tANI_U32 dot11fPackIeTPCReport(tpAniSirGlobal pCtx, + tDot11fIETPCReport *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 35; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->tx_power; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->link_margin; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTPCReport. */ + +tANI_U32 dot11fPackIeTPCRequest(tpAniSirGlobal pCtx, + tDot11fIETPCRequest *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 0; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 34; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTPCRequest. */ + +tANI_U32 dot11fPackIeTimeoutInterval(tpAniSirGlobal pCtx, + tDot11fIETimeoutInterval *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 56; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->timeoutType; + *pnConsumed += 1; + pBuf += 1; + frameshtonl(pCtx, pBuf, pSrc->timeoutValue, 0); + *pnConsumed += 4; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeTimeoutInterval. */ + +tANI_U32 dot11fPackIeVHTCaps(tpAniSirGlobal pCtx, + tDot11fIEVHTCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 tmp142__; + tANI_U16 tmp143__; + tANI_U16 tmp144__; + nNeeded += 12; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 191; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + tmp142__ = 0U; + tmp142__ |= ( pSrc->maxMPDULen << 0 ); + tmp142__ |= ( pSrc->supportedChannelWidthSet << 2 ); + tmp142__ |= ( pSrc->ldpcCodingCap << 4 ); + tmp142__ |= ( pSrc->shortGI80MHz << 5 ); + tmp142__ |= ( pSrc->shortGI160and80plus80MHz << 6 ); + tmp142__ |= ( pSrc->txSTBC << 7 ); + tmp142__ |= ( pSrc->rxSTBC << 8 ); + tmp142__ |= ( pSrc->suBeamFormerCap << 11 ); + tmp142__ |= ( pSrc->suBeamformeeCap << 12 ); + tmp142__ |= ( pSrc->csnofBeamformerAntSup << 13 ); + tmp142__ |= ( pSrc->numSoundingDim << 16 ); + tmp142__ |= ( pSrc->muBeamformerCap << 19 ); + tmp142__ |= ( pSrc->muBeamformeeCap << 20 ); + tmp142__ |= ( pSrc->vhtTXOPPS << 21 ); + tmp142__ |= ( pSrc->htcVHTCap << 22 ); + tmp142__ |= ( pSrc->maxAMPDULenExp << 23 ); + tmp142__ |= ( pSrc->vhtLinkAdaptCap << 26 ); + tmp142__ |= ( pSrc->rxAntPattern << 28 ); + tmp142__ |= ( pSrc->txAntPattern << 29 ); + tmp142__ |= ( pSrc->reserved1 << 30 ); + frameshtonl(pCtx, pBuf, tmp142__, 0); + *pnConsumed += 4; + pBuf += 4; + nBuf -= 4 ; + frameshtons(pCtx, pBuf, pSrc->rxMCSMap, 0); + *pnConsumed += 2; + pBuf += 2; + tmp143__ = 0U; + tmp143__ |= ( pSrc->rxHighSupDataRate << 0 ); + tmp143__ |= ( pSrc->reserved2 << 13 ); + frameshtons(pCtx, pBuf, tmp143__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + frameshtons(pCtx, pBuf, pSrc->txMCSMap, 0); + *pnConsumed += 2; + pBuf += 2; + tmp144__ = 0U; + tmp144__ |= ( pSrc->txSupDataRate << 0 ); + tmp144__ |= ( pSrc->reserved3 << 13 ); + frameshtons(pCtx, pBuf, tmp144__, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + nBuf -= 2 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVHTCaps. */ + +tANI_U32 dot11fPackIeVHTExtBssLoad(tpAniSirGlobal pCtx, + tDot11fIEVHTExtBssLoad *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 193; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->muMIMOCapStaCount; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->ssUnderUtil; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->FortyMHzUtil; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->EightyMHzUtil; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->OneSixtyMHzUtil; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVHTExtBssLoad. */ + +tANI_U32 dot11fPackIeVHTOperation(tpAniSirGlobal pCtx, + tDot11fIEVHTOperation *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 5; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 192; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->chanWidth; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->chanCenterFreqSeg1; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->chanCenterFreqSeg2; + *pnConsumed += 1; + pBuf += 1; + frameshtons(pCtx, pBuf, pSrc->basicMCSSet, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeVHTOperation. */ + +tANI_U32 dot11fPackIeWAPI(tpAniSirGlobal pCtx, + tDot11fIEWAPI *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U16 tmp145__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEWAPI(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 68; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->version, 0); + *pnConsumed += 2; + pBuf += 2; + frameshtons(pCtx, pBuf, pSrc->akm_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->akm_suites ), ( pSrc->akm_suite_count * 4 )); + *pnConsumed += ( pSrc->akm_suite_count * 4 ); + pBuf += ( pSrc->akm_suite_count * 4 ); + frameshtons(pCtx, pBuf, pSrc->unicast_cipher_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->unicast_cipher_suites ), ( pSrc->unicast_cipher_suite_count * 4 )); + *pnConsumed += ( pSrc->unicast_cipher_suite_count * 4 ); + pBuf += ( pSrc->unicast_cipher_suite_count * 4 ); + DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher_suite, 4); + *pnConsumed += 4; + pBuf += 4; + tmp145__ = 0U; + tmp145__ |= ( pSrc->preauth << 0 ); + tmp145__ |= ( pSrc->reserved << 1 ); + frameshtons(pCtx, pBuf, tmp145__, 0); + *pnConsumed += 2; + pBuf += 2; + nBuf -= 2 ; + if ( pSrc->bkid_count ) { + frameshtons(pCtx, pBuf, pSrc->bkid_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->bkid ), ( pSrc->bkid_count * 16 )); + *pnConsumed += ( pSrc->bkid_count * 16 ); + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeWAPI. */ + +tANI_U32 dot11fPackIeWAPIOpaque(tpAniSirGlobal pCtx, + tDot11fIEWAPIOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 68; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWAPIOpaque. */ + +tANI_U32 dot11fPackIeWFATPC(tpAniSirGlobal pCtx, + tDot11fIEWFATPC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x8; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->txPower; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->linkMargin; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWFATPC. */ + +tANI_U32 dot11fPackIeWFDIEOpaque(tpAniSirGlobal pCtx, + tDot11fIEWFDIEOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xa; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWFDIEOpaque. */ + +tANI_U32 dot11fPackIeWMMCaps(tpAniSirGlobal pCtx, + tDot11fIEWMMCaps *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp146__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x5; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp146__ = 0U; + tmp146__ |= ( pSrc->reserved << 0 ); + tmp146__ |= ( pSrc->qack << 4 ); + tmp146__ |= ( pSrc->queue_request << 5 ); + tmp146__ |= ( pSrc->txop_request << 6 ); + tmp146__ |= ( pSrc->more_ack << 7 ); + *pBuf = tmp146__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMCaps. */ + +tANI_U32 dot11fPackIeWMMInfoAp(tpAniSirGlobal pCtx, + tDot11fIEWMMInfoAp *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp147__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp147__ = 0U; + tmp147__ |= ( pSrc->param_set_count << 0 ); + tmp147__ |= ( pSrc->reserved << 4 ); + tmp147__ |= ( pSrc->uapsd << 7 ); + *pBuf = tmp147__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMInfoAp. */ + +tANI_U32 dot11fPackIeWMMInfoStation(tpAniSirGlobal pCtx, + tDot11fIEWMMInfoStation *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp148__; + nNeeded += 2; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + tmp148__ = 0U; + tmp148__ |= ( pSrc->acvo_uapsd << 0 ); + tmp148__ |= ( pSrc->acvi_uapsd << 1 ); + tmp148__ |= ( pSrc->acbk_uapsd << 2 ); + tmp148__ |= ( pSrc->acbe_uapsd << 3 ); + tmp148__ |= ( pSrc->reserved1 << 4 ); + tmp148__ |= ( pSrc->max_sp_length << 5 ); + tmp148__ |= ( pSrc->reserved2 << 7 ); + *pBuf = tmp148__; + *pnConsumed += 1; + // fieldsEndFlag = 1 + nBuf -= 1 ; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMInfoStation. */ + +tANI_U32 dot11fPackIeWMMParams(tpAniSirGlobal pCtx, + tDot11fIEWMMParams *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp149__; + tANI_U8 tmp150__; + tANI_U8 tmp151__; + tANI_U8 tmp152__; + tANI_U8 tmp153__; + tANI_U8 tmp154__; + tANI_U8 tmp155__; + tANI_U8 tmp156__; + nNeeded += 19; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->version; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->qosInfo; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->reserved2; + *pnConsumed += 1; + pBuf += 1; + tmp149__ = 0U; + tmp149__ |= ( pSrc->acbe_aifsn << 0 ); + tmp149__ |= ( pSrc->acbe_acm << 4 ); + tmp149__ |= ( pSrc->acbe_aci << 5 ); + tmp149__ |= ( pSrc->unused1 << 7 ); + *pBuf = tmp149__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp150__ = 0U; + tmp150__ |= ( pSrc->acbe_acwmin << 0 ); + tmp150__ |= ( pSrc->acbe_acwmax << 4 ); + *pBuf = tmp150__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbe_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp151__ = 0U; + tmp151__ |= ( pSrc->acbk_aifsn << 0 ); + tmp151__ |= ( pSrc->acbk_acm << 4 ); + tmp151__ |= ( pSrc->acbk_aci << 5 ); + tmp151__ |= ( pSrc->unused2 << 7 ); + *pBuf = tmp151__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp152__ = 0U; + tmp152__ |= ( pSrc->acbk_acwmin << 0 ); + tmp152__ |= ( pSrc->acbk_acwmax << 4 ); + *pBuf = tmp152__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acbk_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp153__ = 0U; + tmp153__ |= ( pSrc->acvi_aifsn << 0 ); + tmp153__ |= ( pSrc->acvi_acm << 4 ); + tmp153__ |= ( pSrc->acvi_aci << 5 ); + tmp153__ |= ( pSrc->unused3 << 7 ); + *pBuf = tmp153__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp154__ = 0U; + tmp154__ |= ( pSrc->acvi_acwmin << 0 ); + tmp154__ |= ( pSrc->acvi_acwmax << 4 ); + *pBuf = tmp154__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvi_txoplimit, 0); + *pnConsumed += 2; + pBuf += 2; + tmp155__ = 0U; + tmp155__ |= ( pSrc->acvo_aifsn << 0 ); + tmp155__ |= ( pSrc->acvo_acm << 4 ); + tmp155__ |= ( pSrc->acvo_aci << 5 ); + tmp155__ |= ( pSrc->unused4 << 7 ); + *pBuf = tmp155__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + tmp156__ = 0U; + tmp156__ |= ( pSrc->acvo_acwmin << 0 ); + tmp156__ |= ( pSrc->acvo_acwmax << 4 ); + *pBuf = tmp156__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + frameshtons(pCtx, pBuf, pSrc->acvo_txoplimit, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWMMParams. */ + +tANI_U32 dot11fPackIeWPA(tpAniSirGlobal pCtx, + tDot11fIEWPA *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEWPA(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + frameshtons(pCtx, pBuf, pSrc->version, 0); + *pnConsumed += 2; + pBuf += 2; + if ( pSrc->multicast_cipher_present ) { + DOT11F_MEMCPY(pCtx, pBuf, pSrc->multicast_cipher, 4); + *pnConsumed += 4; + pBuf += 4; + } + else break; + if ( pSrc->unicast_cipher_count ) { + frameshtons(pCtx, pBuf, pSrc->unicast_cipher_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->unicast_ciphers ), ( pSrc->unicast_cipher_count * 4 )); + *pnConsumed += ( pSrc->unicast_cipher_count * 4 ); + pBuf += ( pSrc->unicast_cipher_count * 4 ); + if ( pSrc->auth_suite_count ) { + frameshtons(pCtx, pBuf, pSrc->auth_suite_count, 0); + *pnConsumed += 2; + pBuf += 2; + } + else break; + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->auth_suites ), ( pSrc->auth_suite_count * 4 )); + *pnConsumed += ( pSrc->auth_suite_count * 4 ); + pBuf += ( pSrc->auth_suite_count * 4 ); + if ( pSrc->caps ) { + frameshtons(pCtx, pBuf, pSrc->caps, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIeWPA. */ + +tANI_U32 dot11fPackIeWPAOpaque(tpAniSirGlobal pCtx, + tDot11fIEWPAOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x1; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWPAOpaque. */ + +tANI_U32 dot11fPackIeWSC(tpAniSirGlobal pCtx, + tDot11fIEWSC *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWSC(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WSC+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWSC. */ + +tANI_U32 dot11fPackIeWiderBWChanSwitchAnn(tpAniSirGlobal pCtx, + tDot11fIEWiderBWChanSwitchAnn *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += 3; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 194; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = pSrc->newChanWidth; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->newCenterChanFreq0; + *pnConsumed += 1; + pBuf += 1; + *pBuf = pSrc->newCenterChanFreq1; + *pnConsumed += 1; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWiderBWChanSwitchAnn. */ + +tANI_U32 dot11fPackIeWscAssocReq(tpAniSirGlobal pCtx, + tDot11fIEWscAssocReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscAssocReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscAssocReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscAssocReq. */ + +tANI_U32 dot11fPackIeWscAssocRes(tpAniSirGlobal pCtx, + tDot11fIEWscAssocRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscAssocRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscAssocRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscAssocRes. */ + +tANI_U32 dot11fPackIeWscBeacon(tpAniSirGlobal pCtx, + tDot11fIEWscBeacon *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscBeacon(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscBeacon+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscBeacon. */ + +tANI_U32 dot11fPackIeWscBeaconProbeRes(tpAniSirGlobal pCtx, + tDot11fIEWscBeaconProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscBeaconProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscBeaconProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscBeaconProbeRes. */ + +tANI_U32 dot11fPackIeWscIEOpaque(tpAniSirGlobal pCtx, + tDot11fIEWscIEOpaque *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + nNeeded += pSrc->num_data; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; ++(*pnConsumed); + DOT11F_MEMCPY(pCtx, pBuf, &( pSrc->data ), pSrc->num_data); + *pnConsumed += pSrc->num_data; + // fieldsEndFlag = 1 + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return DOT11F_PARSE_SUCCESS; +} /* End dot11fPackIeWscIEOpaque. */ + +tANI_U32 dot11fPackIeWscProbeReq(tpAniSirGlobal pCtx, + tDot11fIEWscProbeReq *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscProbeReq(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscProbeReq+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscProbeReq. */ + +tANI_U32 dot11fPackIeWscProbeRes(tpAniSirGlobal pCtx, + tDot11fIEWscProbeRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscProbeRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscProbeRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscProbeRes. */ + +tANI_U32 dot11fPackIeWscReassocRes(tpAniSirGlobal pCtx, + tDot11fIEWscReassocRes *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 n, idx = 0,idxlast; + tANI_U32 nConsumedSoFar, nConsumedNow; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + tANI_U32 nNeeded = 0U; + status = dot11fGetPackedIEWscReassocRes(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + (void)pCtx; + if (pSrc->present) { + do { + nConsumedSoFar=*pnConsumed; + *pBuf = 221; + ++pBuf; --nBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x0; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0xf2; + ++pBuf; --nBuf; ++(*pnConsumed); + *pBuf = 0x4; + ++pBuf; --nBuf; ++(*pnConsumed); + n = ( 255 - 4) < nBuf ? ( 255 - 4) : nBuf; + nConsumedNow=*pnConsumed; + idxlast=idx; + status = PackTlvCore(pCtx,(tANI_U8*)pSrc,pBuf,n,pnConsumed,TLVS_WscReassocRes+idx,&idx); + nConsumedNow=*pnConsumed-nConsumedNow; + *pIeLen = *pnConsumed - nConsumedSoFar - 2; + pBuf+=nConsumedNow; + nBuf-=nConsumedNow; + } while (DOT11F_BUFFER_OVERFLOW == status && idxlast != idx); + } + return status; +} /* End dot11fPackIeWscReassocRes. */ + +tANI_U32 dot11fPackIehs20vendor_ie(tpAniSirGlobal pCtx, + tDot11fIEhs20vendor_ie *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed) +{ + tANI_U8* pIeLen = 0; + tANI_U32 nConsumedOnEntry = *pnConsumed; + tANI_U32 nNeeded = 0U; + tANI_U8 tmp157__; + tANI_U32 status = DOT11F_PARSE_SUCCESS; + status = dot11fGetPackedIEhs20vendor_ie(pCtx, pSrc, &nNeeded); + if ( ! DOT11F_SUCCEEDED( status ) ) return status; + while ( pSrc->present ) + { + if ( nNeeded > nBuf ) return DOT11F_BUFFER_OVERFLOW; + *pBuf = 221; + ++pBuf; ++(*pnConsumed); + pIeLen = pBuf; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x50; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x6f; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x9a; + ++pBuf; ++(*pnConsumed); + *pBuf = 0x10; + ++pBuf; ++(*pnConsumed); + tmp157__ = 0U; + tmp157__ |= ( pSrc->dgaf_dis << 0 ); + tmp157__ |= ( pSrc->hs_id_present << 1 ); + tmp157__ |= ( pSrc->reserved << 3 ); + tmp157__ |= ( pSrc->release_num << 4 ); + *pBuf = tmp157__; + *pnConsumed += 1; + pBuf += 1; + nBuf -= 1 ; + if ( pSrc->hs_id_present ) { + switch (pSrc->hs_id_present) + { + case 1: + frameshtons(pCtx, pBuf, pSrc->hs_id.pps_mo.pps_mo_id, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + case 2: + frameshtons(pCtx, pBuf, pSrc->hs_id.anqp_domain.anqp_domain_id, 0); + *pnConsumed += 2; + // fieldsEndFlag = 1 + break; + } + } + else break; + break; + } + (void)pCtx; + if (pIeLen) + { + *pIeLen = *pnConsumed - nConsumedOnEntry - 2; + } + return status; +} /* End dot11fPackIehs20vendor_ie. */ + +tANI_U32 dot11fPackAddBAReq(tpAniSirGlobal pCtx, tDot11fAddBAReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddBAReq, IES_AddBAReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Packed the AddBAReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("BAStartingSequenceControl:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("fragNumber (4): %d\n"), pFrm->BAStartingSequenceControl.fragNumber); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("ssn (12): %d\n"), pFrm->BAStartingSequenceControl.ssn); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBAREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBAReq. */ + +tANI_U32 dot11fPackAddBARsp(tpAniSirGlobal pCtx, tDot11fAddBARsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddBARsp, IES_AddBARsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Packed the AddBARsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("AddBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("amsduSupported (1): %d\n"), pFrm->AddBAParameterSet.amsduSupported); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("policy (1): %d\n"), pFrm->AddBAParameterSet.policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("tid (4): %d\n"), pFrm->AddBAParameterSet.tid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("bufferSize (10): %d\n"), pFrm->AddBAParameterSet.bufferSize); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("BATimeout:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), ( tANI_U8* )&pFrm->BATimeout.timeout, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDBARSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddBARsp. */ + +tANI_U32 dot11fPackAddTSRequest(tpAniSirGlobal pCtx, tDot11fAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddTSRequest, IES_AddTSRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Packed the AddTSRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSRequest. */ + +tANI_U32 dot11fPackAddTSResponse(tpAniSirGlobal pCtx, tDot11fAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AddTSResponse, IES_AddTSResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Packed the AddTSResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("schedule (1): %d\n"), pFrm->TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("unused (7): %d\n"), pFrm->TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].classifier_mask, 1); + switch (pFrm->TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.version, 1); + switch (pFrm->TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("reserved (9): %d\n"), pFrm->WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMSchedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ADDTSRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAddTSResponse. */ + +tANI_U32 dot11fPackAssocRequest(tpAniSirGlobal pCtx, tDot11fAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AssocRequest, IES_AssocRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Packed the AssocRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocRequest. */ + +tANI_U32 dot11fPackAssocResponse(tpAniSirGlobal pCtx, tDot11fAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_AssocResponse, IES_AssocResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Packed the AssocResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("WscAssocRes:\n")); + if (!pFrm->WscAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscAssocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscAssocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscAssocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscAssocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscAssocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscAssocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->WscAssocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_ASSOCRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAssocResponse. */ + +tANI_U32 dot11fPackAuthentication(tpAniSirGlobal pCtx, tDot11fAuthentication *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Authentication, IES_Authentication); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Packed the Authentication:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthAlgo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthAlgo.algo, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("AuthSeqNo:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->AuthSeqNo.no, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("ChallengeText:\n")); + if (!pFrm->ChallengeText.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_text: %d.\n"), pFrm->ChallengeText.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->ChallengeText.text, pFrm->ChallengeText.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_AUTHENTICATION), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackAuthentication. */ + +tANI_U32 dot11fPackBeacon(tpAniSirGlobal pCtx, tDot11fBeacon *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Beacon, IES_Beacon); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Packed the Beacon:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon. */ + +tANI_U32 dot11fPackBeacon1(tpAniSirGlobal pCtx, tDot11fBeacon1 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Beacon1, IES_Beacon1); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Packed the Beacon1:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON1), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon1. */ + +tANI_U32 dot11fPackBeacon2(tpAniSirGlobal pCtx, tDot11fBeacon2 *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Beacon2, IES_Beacon2); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Packed the Beacon2:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WscBeacon:\n")); + if (!pFrm->WscBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version:\n")); + if (!pFrm->WscBeacon.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WPSState:\n")); + if (!pFrm->WscBeacon.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeacon.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeacon.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeacon.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeacon.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("UUID_E:\n")); + if (!pFrm->WscBeacon.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RFBands:\n")); + if (!pFrm->WscBeacon.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeacon.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Version2:\n")); + if (!pFrm->WscBeacon.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("minor (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("major (4): %d\n"), pFrm->WscBeacon.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeacon.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeacon.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WscBeacon.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PBeacon:\n")); + if (!pFrm->P2PBeacon.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeacon.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeacon.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeacon.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->P2PBeacon.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->P2PBeacon.NoticeOfAbsence.NoADesc, pFrm->P2PBeacon.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACON2), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeacon2. */ + +tANI_U32 dot11fPackBeaconIEs(tpAniSirGlobal pCtx, tDot11fBeaconIEs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_BeaconIEs, IES_BeaconIEs); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Packed the BeaconIEs:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TIM:\n")); + if (!pFrm->TIM.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.dtim_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TIM.bmpctl, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_vbmp: %d.\n"), pFrm->TIM.num_vbmp); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->TIM.vbmp, pFrm->TIM.num_vbmp); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("QOSCapsAp:\n")); + if (!pFrm->QOSCapsAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("count (4): %d\n"), pFrm->QOSCapsAp.count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->QOSCapsAp.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qreq (1): %d\n"), pFrm->QOSCapsAp.qreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txopreq (1): %d\n"), pFrm->QOSCapsAp.txopreq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->QOSCapsAp.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WscBeaconProbeRes:\n")); + if (!pFrm->WscBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version:\n")); + if (!pFrm->WscBeaconProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WPSState:\n")); + if (!pFrm->WscBeaconProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("APSetupLocked:\n")); + if (!pFrm->WscBeaconProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscBeaconProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ResponseType:\n")); + if (!pFrm->WscBeaconProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("UUID_E:\n")); + if (!pFrm->WscBeaconProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Manufacturer:\n")); + if (!pFrm->WscBeaconProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_name: %d.\n"), pFrm->WscBeaconProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.Manufacturer.name, pFrm->WscBeaconProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelName:\n")); + if (!pFrm->WscBeaconProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelName.text, pFrm->WscBeaconProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ModelNumber:\n")); + if (!pFrm->WscBeaconProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.ModelNumber.text, pFrm->WscBeaconProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("SerialNumber:\n")); + if (!pFrm->WscBeaconProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.SerialNumber.text, pFrm->WscBeaconProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscBeaconProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->WscBeaconProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->WscBeaconProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->WscBeaconProbeRes.DeviceName.text, pFrm->WscBeaconProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ConfigMethods:\n")); + if (!pFrm->WscBeaconProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RFBands:\n")); + if (!pFrm->WscBeaconProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VendorExtension:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Version2:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("minor (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("major (4): %d\n"), pFrm->WscBeaconProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WscBeaconProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PBeaconProbeRes:\n")); + if (!pFrm->P2PBeaconProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PBeaconProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PBeaconProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PBeaconProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->P2PBeaconProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("DeviceName:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_text: %d.\n"), pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PBeaconProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PBeaconProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->P2PBeaconProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PBeaconProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_BEACONIES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackBeaconIEs. */ + +tANI_U32 dot11fPackChannelSwitch(tpAniSirGlobal pCtx, tDot11fChannelSwitch *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ChannelSwitch, IES_ChannelSwitch); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Packed the ChannelSwitch:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("WiderBWChanSwitchAnn:\n")); + if (!pFrm->WiderBWChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newChanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq0, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), ( tANI_U8* )&pFrm->WiderBWChanSwitchAnn.newCenterChanFreq1, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_CHANNELSWITCH), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackChannelSwitch. */ + +tANI_U32 dot11fPackDeAuth(tpAniSirGlobal pCtx, tDot11fDeAuth *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DeAuth, IES_DeAuth); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Packed the DeAuth:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("P2PDeAuth:\n")); + if (!pFrm->P2PDeAuth.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDeAuth.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), ( tANI_U8* )&pFrm->P2PDeAuth.MinorReasonCode.minorReasonCode, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEAUTH), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeAuth. */ + +tANI_U32 dot11fPackDelBAInd(tpAniSirGlobal pCtx, tDot11fDelBAInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DelBAInd, IES_DelBAInd); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Packed the DelBAInd:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("DelBAParameterSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("reserved (11): %d\n"), pFrm->DelBAParameterSet.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("initiator (1): %d\n"), pFrm->DelBAParameterSet.initiator); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("tid (4): %d\n"), pFrm->DelBAParameterSet.tid); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELBAIND), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelBAInd. */ + +tANI_U32 dot11fPackDelTS(tpAniSirGlobal pCtx, tDot11fDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DelTS, IES_DelTS); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Packed the DelTS:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("TSInfo:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("traffic_type (1): %d\n"), pFrm->TSInfo.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsid (4): %d\n"), pFrm->TSInfo.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("direction (2): %d\n"), pFrm->TSInfo.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("access_policy (2): %d\n"), pFrm->TSInfo.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("aggregation (1): %d\n"), pFrm->TSInfo.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("psb (1): %d\n"), pFrm->TSInfo.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("user_priority (3): %d\n"), pFrm->TSInfo.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->TSInfo.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("schedule (1): %d\n"), pFrm->TSInfo.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("unused (15): %d\n"), pFrm->TSInfo.unused); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DELTS), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDelTS. */ + +tANI_U32 dot11fPackDeviceDiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DeviceDiscoverabilityReq, IES_DeviceDiscoverabilityReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Packed the DeviceDiscoverabilityReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceDiscoverabilityReq:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), ( tANI_U8* ) pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.ssid, pFrm->P2PDeviceDiscoverabilityReq.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityReq. */ + +tANI_U32 dot11fPackDeviceDiscoverabilityRes(tpAniSirGlobal pCtx, tDot11fDeviceDiscoverabilityRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_DeviceDiscoverabilityRes, IES_DeviceDiscoverabilityRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Packed the DeviceDiscoverabilityRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PDeviceDiscoverabilityRes:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), ( tANI_U8* )&pFrm->P2PDeviceDiscoverabilityRes.P2PStatus.status, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DEVICEDISCOVERABILITYRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDeviceDiscoverabilityRes. */ + +tANI_U32 dot11fPackDisassociation(tpAniSirGlobal pCtx, tDot11fDisassociation *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_Disassociation, IES_Disassociation); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Packed the Disassociation:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("P2PDisAssoc:\n")); + if (!pFrm->P2PDisAssoc.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("MinorReasonCode:\n")); + if (!pFrm->P2PDisAssoc.MinorReasonCode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), ( tANI_U8* )&pFrm->P2PDisAssoc.MinorReasonCode.minorReasonCode, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_DISASSOCIATION), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackDisassociation. */ + +tANI_U32 dot11fPackGODiscoverabilityReq(tpAniSirGlobal pCtx, tDot11fGODiscoverabilityReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GODiscoverabilityReq, IES_GODiscoverabilityReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Packed the GODiscoverabilityReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GODISCOVERABILITYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGODiscoverabilityReq. */ + +tANI_U32 dot11fPackGONegCnf(tpAniSirGlobal pCtx, tDot11fGONegCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GONegCnf, IES_GONegCnf); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Packed the GONegCnf:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGONegCnf:\n")); + if (!pFrm->P2PGONegCnf.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegCnf.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegCnf.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegCnf.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegCnf.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegCnf.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.ChannelList.channelList, pFrm->P2PGONegCnf.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegCnf.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* )&pFrm->P2PGONegCnf.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), ( tANI_U8* ) pFrm->P2PGONegCnf.P2PGroupId.ssid, pFrm->P2PGONegCnf.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGCNF), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegCnf. */ + +tANI_U32 dot11fPackGONegReq(tpAniSirGlobal pCtx, tDot11fGONegReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GONegReq, IES_GONegReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Packed the GONegReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PGONegReq:\n")); + if (!pFrm->P2PGONegReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegReq.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ListenChannel:\n")); + if (!pFrm->P2PGONegReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PGONegReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.ChannelList.channelList, pFrm->P2PGONegReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("num_text: %d.\n"), pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* ) pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), ( tANI_U8* )&pFrm->P2PGONegReq.OperatingChannel.channel, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegReq. */ + +tANI_U32 dot11fPackGONegRes(tpAniSirGlobal pCtx, tDot11fGONegRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_GONegRes, IES_GONegRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Packed the GONegRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegWPS:\n")); + if (!pFrm->P2PGONegWPS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Version:\n")); + if (!pFrm->P2PGONegWPS.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("minor (4): %d\n"), pFrm->P2PGONegWPS.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("major (4): %d\n"), pFrm->P2PGONegWPS.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DevicePasswordID:\n")); + if (!pFrm->P2PGONegWPS.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegWPS.DevicePasswordID.id, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGONegRes:\n")); + if (!pFrm->P2PGONegRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PGONegRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PCapability:\n")); + if (!pFrm->P2PGONegRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("GOIntent:\n")); + if (!pFrm->P2PGONegRes.GOIntent.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.GOIntent.GOIntent, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PGONegRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PGONegRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("IntendedP2PInterfaceAddress:\n")); + if (!pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.IntendedP2PInterfaceAddress.P2PInterfaceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PGONegRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_channelList: %d.\n"), pFrm->P2PGONegRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.ChannelList.channelList, pFrm->P2PGONegRes.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("DeviceName:\n")); + if (!pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_text: %d.\n"), pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PGONegRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PGONegRes.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* )&pFrm->P2PGONegRes.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("num_ssid: %d.\n"), pFrm->P2PGONegRes.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), ( tANI_U8* ) pFrm->P2PGONegRes.P2PGroupId.ssid, pFrm->P2PGONegRes.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_GONEGRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackGONegRes. */ + +tANI_U32 dot11fPackHT2040BSSCoexistenceManagementActionFrame(tpAniSirGlobal pCtx, tDot11fHT2040BSSCoexistenceManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_HT2040BSSCoexistenceManagementActionFrame, IES_HT2040BSSCoexistenceManagementActionFrame); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Packed the HT2040BSSCoexistenceManagementActionFrame:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("HT2040BSSIntolerantReport:\n")); + if (!pFrm->HT2040BSSIntolerantReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->HT2040BSSIntolerantReport.operatingClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("num_channelList: %d.\n"), pFrm->HT2040BSSIntolerantReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), ( tANI_U8* ) pFrm->HT2040BSSIntolerantReport.channelList, pFrm->HT2040BSSIntolerantReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_HT2040BSSCOEXISTENCEMANAGEMENTACTIONFRAME), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackHT2040BSSCoexistenceManagementActionFrame. */ + +tANI_U32 dot11fPackInvitationReq(tpAniSirGlobal pCtx, tDot11fInvitationReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_InvitationReq, IES_InvitationReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Packed the InvitationReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PInvitationReq:\n")); + if (!pFrm->P2PInvitationReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationReq.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("InvitationFlags:\n")); + if (!pFrm->P2PInvitationReq.InvitationFlags.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.InvitationFlags.invitationFlags, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationReq.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationReq.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.ChannelList.channelList, pFrm->P2PInvitationReq.ChannelList.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PInvitationReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PGroupId.ssid, pFrm->P2PInvitationReq.P2PGroupId.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* )&pFrm->P2PInvitationReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("num_text: %d.\n"), pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), ( tANI_U8* ) pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PInvitationReq.P2PDeviceInfo.DeviceName.num_text); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationReq. */ + +tANI_U32 dot11fPackInvitationRes(tpAniSirGlobal pCtx, tDot11fInvitationRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_InvitationRes, IES_InvitationRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Packed the InvitationRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PInvitationRes:\n")); + if (!pFrm->P2PInvitationRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PInvitationRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ConfigurationTimeout:\n")); + if (!pFrm->P2PInvitationRes.ConfigurationTimeout.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.GOConfigTimeout, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ConfigurationTimeout.CLConfigTimeout, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PInvitationRes.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.OperatingChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("P2PGroupBssid:\n")); + if (!pFrm->P2PInvitationRes.P2PGroupBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.P2PGroupBssid.P2PGroupBssid, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("ChannelList:\n")); + if (!pFrm->P2PInvitationRes.ChannelList.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* )&pFrm->P2PInvitationRes.ChannelList.countryString, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("num_channelList: %d.\n"), pFrm->P2PInvitationRes.ChannelList.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), ( tANI_U8* ) pFrm->P2PInvitationRes.ChannelList.channelList, pFrm->P2PInvitationRes.ChannelList.num_channelList); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_INVITATIONRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackInvitationRes. */ + +tANI_U32 dot11fPackLinkMeasurementReport(tpAniSirGlobal pCtx, tDot11fLinkMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_LinkMeasurementReport, IES_LinkMeasurementReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Packed the LinkMeasurementReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleID.TPCId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TPCEleLen:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TPCEleLen.TPCLen, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("LinkMargin:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->LinkMargin.linkMargin, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("TxAntennaId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->TxAntennaId.antennaId, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RCPI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RCPI.rcpi, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("RSNI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), ( tANI_U8* )&pFrm->RSNI.rsni, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementReport. */ + +tANI_U32 dot11fPackLinkMeasurementRequest(tpAniSirGlobal pCtx, tDot11fLinkMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_LinkMeasurementRequest, IES_LinkMeasurementRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Packed the LinkMeasurementRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("TxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->TxPower.txPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("MaxTxPower:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MaxTxPower.maxTxPower, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_LINKMEASUREMENTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackLinkMeasurementRequest. */ + +tANI_U32 dot11fPackMeasurementReport(tpAniSirGlobal pCtx, tDot11fMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_MeasurementReport, IES_MeasurementReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Packed the MeasurementReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("MeasurementReport:\n")); + if (!pFrm->MeasurementReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport.late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport.incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport.refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport.unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.type, 1); + switch (pFrm->MeasurementReport.type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport.report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport.report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport.report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport.report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport.report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport.report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport.report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport.report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport.report.Beacon.parent_TSF, 4); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementReport. */ + +tANI_U32 dot11fPackMeasurementRequest(tpAniSirGlobal pCtx, tDot11fMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_MeasurementRequest, IES_MeasurementRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Packed the MeasurementRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_MEASUREMENTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackMeasurementRequest. */ + +tANI_U32 dot11fPackNeighborReportRequest(tpAniSirGlobal pCtx, tDot11fNeighborReportRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_NeighborReportRequest, IES_NeighborReportRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Packed the NeighborReportRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportRequest. */ + +tANI_U32 dot11fPackNeighborReportResponse(tpAniSirGlobal pCtx, tDot11fNeighborReportResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_NeighborReportResponse, IES_NeighborReportResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Packed the NeighborReportResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_NeighborReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborReport[%d]:\n"), i); + if (!pFrm->NeighborReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].bssid, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APReachability (2): %d\n"), pFrm->NeighborReport[i].APReachability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Security (1): %d\n"), pFrm->NeighborReport[i].Security); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("KeyScope (1): %d\n"), pFrm->NeighborReport[i].KeyScope); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("SpecMgmtCap (1): %d\n"), pFrm->NeighborReport[i].SpecMgmtCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("QosCap (1): %d\n"), pFrm->NeighborReport[i].QosCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("apsd (1): %d\n"), pFrm->NeighborReport[i].apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("rrm (1): %d\n"), pFrm->NeighborReport[i].rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("DelayedBA (1): %d\n"), pFrm->NeighborReport[i].DelayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ImmBA (1): %d\n"), pFrm->NeighborReport[i].ImmBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MobilityDomain (1): %d\n"), pFrm->NeighborReport[i].MobilityDomain); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (5): %d\n"), pFrm->NeighborReport[i].reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].reserved1, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].PhyType, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TSFInfo:\n")); + if (!pFrm->NeighborReport[i].TSFInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.TsfOffset, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].TSFInfo.BeaconIntvl, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("CondensedCountryStr:\n")); + if (!pFrm->NeighborReport[i].CondensedCountryStr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].CondensedCountryStr.countryStr, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot:\n")); + if (!pFrm->NeighborReport[i].MeasurementPilot.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MeasurementPilot.measurementPilot, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MeasurementPilot.vendorSpecific, pFrm->NeighborReport[i].MeasurementPilot.num_vendorSpecific); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->NeighborReport[i].RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("parallel (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("repeated (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("statistics (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("reserved (6): %d\n"), pFrm->NeighborReport[i].RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("MultiBssid:\n")); + if (!pFrm->NeighborReport[i].MultiBssid.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* )&pFrm->NeighborReport[i].MultiBssid.maxBSSIDIndicator, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("num_vendorSpecific: %d.\n"), pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), ( tANI_U8* ) pFrm->NeighborReport[i].MultiBssid.vendorSpecific, pFrm->NeighborReport[i].MultiBssid.num_vendorSpecific); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NEIGHBORREPORTRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNeighborReportResponse. */ + +tANI_U32 dot11fPackNoticeOfAbs(tpAniSirGlobal pCtx, tDot11fNoticeOfAbs *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_NoticeOfAbs, IES_NoticeOfAbs); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Packed the NoticeOfAbs:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_NOTICEOFABS), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackNoticeOfAbs. */ + +tANI_U32 dot11fPackOperatingMode(tpAniSirGlobal pCtx, tDot11fOperatingMode *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_OperatingMode, IES_OperatingMode); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Packed the OperatingMode:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("OperatingMode:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_OPERATINGMODE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackOperatingMode. */ + +tANI_U32 dot11fPackPresenceReq(tpAniSirGlobal pCtx, tDot11fPresenceReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_PresenceReq, IES_PresenceReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Packed the PresenceReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("P2PNoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* )&pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("num_NoADesc: %d.\n"), pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), ( tANI_U8* ) pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.NoADesc, pFrm->P2PNoticeOfAbsence.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCEREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceReq. */ + +tANI_U32 dot11fPackPresenceRes(tpAniSirGlobal pCtx, tDot11fPresenceRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_PresenceRes, IES_PresenceRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Packed the PresenceRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PPresenceResponse:\n")); + if (!pFrm->P2PPresenceResponse.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("P2PStatus:\n")); + if (!pFrm->P2PPresenceResponse.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PPresenceResponse.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* )&pFrm->P2PPresenceResponse.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("num_NoADesc: %d.\n"), pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), ( tANI_U8* ) pFrm->P2PPresenceResponse.NoticeOfAbsence.NoADesc, pFrm->P2PPresenceResponse.NoticeOfAbsence.num_NoADesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PRESENCERES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackPresenceRes. */ + +tANI_U32 dot11fPackProbeRequest(tpAniSirGlobal pCtx, tDot11fProbeRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProbeRequest, IES_ProbeRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Packed the ProbeRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestedInfo:\n")); + if (!pFrm->RequestedInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_requested_eids: %d.\n"), pFrm->RequestedInfo.num_requested_eids); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->RequestedInfo.requested_eids, pFrm->RequestedInfo.num_requested_eids); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WscProbeReq:\n")); + if (!pFrm->WscProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version:\n")); + if (!pFrm->WscProbeReq.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestType:\n")); + if (!pFrm->WscProbeReq.RequestType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestType.reqType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeReq.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeReq.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeReq.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RFBands:\n")); + if (!pFrm->WscProbeReq.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AssociationState:\n")); + if (!pFrm->WscProbeReq.AssociationState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.AssociationState.state, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ConfigurationError:\n")); + if (!pFrm->WscProbeReq.ConfigurationError.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.ConfigurationError.error, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeReq.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeReq.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_name: %d.\n"), pFrm->WscProbeReq.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.Manufacturer.name, pFrm->WscProbeReq.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelName:\n")); + if (!pFrm->WscProbeReq.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelName.text, pFrm->WscProbeReq.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeReq.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.ModelNumber.text, pFrm->WscProbeReq.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeReq.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("num_text: %d.\n"), pFrm->WscProbeReq.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* ) pFrm->WscProbeReq.DeviceName.text, pFrm->WscProbeReq.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeReq.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Version2:\n")); + if (!pFrm->WscProbeReq.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("minor (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("major (4): %d\n"), pFrm->WscProbeReq.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeReq.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.VendorExtension.RequestToEnroll.req, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("RequestDeviceType:\n")); + if (!pFrm->WscProbeReq.RequestDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WscProbeReq.RequestDeviceType.sub_category, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("WFATPC:\n")); + if (!pFrm->WFATPC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.txPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->WFATPC.linkMargin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PProbeReq:\n")); + if (!pFrm->P2PProbeReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("P2PDeviceId:\n")); + if (!pFrm->P2PProbeReq.P2PDeviceId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.P2PDeviceId.P2PDeviceAddress, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ListenChannel:\n")); + if (!pFrm->P2PProbeReq.ListenChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ListenChannel.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeReq.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("OperatingChannel:\n")); + if (!pFrm->P2PProbeReq.OperatingChannel.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.countryString, 3); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.regulatoryClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->P2PProbeReq.OperatingChannel.channel, 1); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBEREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeRequest. */ + +tANI_U32 dot11fPackProbeResponse(tpAniSirGlobal pCtx, tDot11fProbeResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProbeResponse, IES_ProbeResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Packed the ProbeResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TimeStamp:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TimeStamp.timestamp, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->BeaconInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParamSet:\n")); + if (!pFrm->FHParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.dwell_time, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_set, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_pattern, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParamSet.hop_index, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DSParams:\n")); + if (!pFrm->DSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->DSParams.curr_channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("CFParams:\n")); + if (!pFrm->CFParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_maxduration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->CFParams.cfp_durremaining, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("IBSSParams:\n")); + if (!pFrm->IBSSParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->IBSSParams.atim, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHParams:\n")); + if (!pFrm->FHParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.radix, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHParams.nchannels, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FHPattTable:\n")); + if (!pFrm->FHPattTable.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.flag, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.nsets, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.modulus, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->FHPattTable.offset, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_randtable: %d.\n"), pFrm->FHPattTable.num_randtable); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->FHPattTable.randtable, pFrm->FHPattTable.num_randtable); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PowerConstraints:\n")); + if (!pFrm->PowerConstraints.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->PowerConstraints.localPowerConstraints, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChanSwitchAnn:\n")); + if (!pFrm->ChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchMode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.newChannel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ChanSwitchAnn.switchCount, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Quiet:\n")); + if (!pFrm->Quiet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Quiet.offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ERPInfo:\n")); + if (!pFrm->ERPInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("non_erp_present (1): %d\n"), pFrm->ERPInfo.non_erp_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("use_prot (1): %d\n"), pFrm->ERPInfo.use_prot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("barker_preamble (1): %d\n"), pFrm->ERPInfo.barker_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused (5): %d\n"), pFrm->ERPInfo.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("QBSSLoad:\n")); + if (!pFrm->QBSSLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.stacount, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.chautil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->QBSSLoad.avail, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APChannelReport:\n")); + if (!pFrm->APChannelReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->APChannelReport.regulatoryClass, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_channelList: %d.\n"), pFrm->APChannelReport.num_channelList); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->APChannelReport.channelList, pFrm->APChannelReport.num_channelList); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtChanSwitchAnn:\n")); + if (!pFrm->ExtChanSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ExtChanSwitchAnn.secondaryChannelOffset, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMInfoAp:\n")); + if (!pFrm->WMMInfoAp.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMInfoAp.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("param_set_count (4): %d\n"), pFrm->WMMInfoAp.param_set_count); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (3): %d\n"), pFrm->WMMInfoAp.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("uapsd (1): %d\n"), pFrm->WMMInfoAp.uapsd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WAPI:\n")); + if (!pFrm->WAPI.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.akm_suites, 4 * pFrm->WAPI.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.unicast_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.unicast_cipher_suites, 4 * pFrm->WAPI.unicast_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.multicast_cipher_suite, 4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("preauth (1): %d\n"), pFrm->WAPI.preauth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (15): %d\n"), pFrm->WAPI.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WAPI.bkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WAPI.bkid, 16 * pFrm->WAPI.bkid_count); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WscProbeRes:\n")); + if (!pFrm->WscProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version:\n")); + if (!pFrm->WscProbeRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("WPSState:\n")); + if (!pFrm->WscProbeRes.WPSState.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.WPSState.state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("APSetupLocked:\n")); + if (!pFrm->WscProbeRes.APSetupLocked.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.APSetupLocked.fLocked, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrar:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrar.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrar.selected, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DevicePasswordID:\n")); + if (!pFrm->WscProbeRes.DevicePasswordID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.DevicePasswordID.id, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SelectedRegistrarConfigMethods:\n")); + if (!pFrm->WscProbeRes.SelectedRegistrarConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.SelectedRegistrarConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscProbeRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("UUID_E:\n")); + if (!pFrm->WscProbeRes.UUID_E.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.UUID_E.uuid, 16); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Manufacturer:\n")); + if (!pFrm->WscProbeRes.Manufacturer.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_name: %d.\n"), pFrm->WscProbeRes.Manufacturer.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.Manufacturer.name, pFrm->WscProbeRes.Manufacturer.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelName:\n")); + if (!pFrm->WscProbeRes.ModelName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelName.text, pFrm->WscProbeRes.ModelName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ModelNumber:\n")); + if (!pFrm->WscProbeRes.ModelNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.ModelNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.ModelNumber.text, pFrm->WscProbeRes.ModelNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("SerialNumber:\n")); + if (!pFrm->WscProbeRes.SerialNumber.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.SerialNumber.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.SerialNumber.text, pFrm->WscProbeRes.SerialNumber.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("PrimaryDeviceType:\n")); + if (!pFrm->WscProbeRes.PrimaryDeviceType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.primary_category, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.oui, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.PrimaryDeviceType.sub_category, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->WscProbeRes.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->WscProbeRes.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->WscProbeRes.DeviceName.text, pFrm->WscProbeRes.DeviceName.num_text); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ConfigMethods:\n")); + if (!pFrm->WscProbeRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.ConfigMethods.methods, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RFBands:\n")); + if (!pFrm->WscProbeRes.RFBands.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.RFBands.bands, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscProbeRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscProbeRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("minor (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("major (4): %d\n"), pFrm->WscProbeRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscProbeRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->WscProbeRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PProbeRes:\n")); + if (!pFrm->P2PProbeRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProbeRes.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PProbeRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.ExtendedListenTiming.availibilityInterval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("NoticeOfAbsence:\n")); + if (!pFrm->P2PProbeRes.NoticeOfAbsence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.index, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.NoticeOfAbsence.CTSWindowOppPS, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_NoADesc: %d.\n"), pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.NoticeOfAbsence.NoADesc, pFrm->P2PProbeRes.NoticeOfAbsence.num_NoADesc); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->P2PProbeRes.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("DeviceName:\n")); + if (!pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_text: %d.\n"), pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.text, pFrm->P2PProbeRes.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("P2PGroupInfo:\n")); + if (!pFrm->P2PProbeRes.P2PGroupInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_P2PClientInfoDesc: %d.\n"), pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->P2PProbeRes.P2PGroupInfo.P2PClientInfoDesc, pFrm->P2PProbeRes.P2PGroupInfo.num_P2PClientInfoDesc); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("VHTExtBssLoad:\n")); + if (!pFrm->VHTExtBssLoad.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.muMIMOCapStaCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.ssUnderUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.FortyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.EightyMHzUtil, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->VHTExtBssLoad.OneSixtyMHzUtil, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROBERESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProbeResponse. */ + +tANI_U32 dot11fPackProvisionDiscoveryReq(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProvisionDiscoveryReq, IES_ProvisionDiscoveryReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Packed the ProvisionDiscoveryReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PProvisionDiscoveryReq:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PCapability:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.deviceCapability, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PCapability.groupCapability, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PDeviceInfo:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.P2PDeviceAddress, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.configMethod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.primaryDeviceType, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("DeviceName:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_text: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.text, pFrm->P2PProvisionDiscoveryReq.P2PDeviceInfo.DeviceName.num_text); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("P2PGroupId:\n")); + if (!pFrm->P2PProvisionDiscoveryReq.P2PGroupId.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* )&pFrm->P2PProvisionDiscoveryReq.P2PGroupId.deviceAddress, 6); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("num_ssid: %d.\n"), pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), ( tANI_U8* ) pFrm->P2PProvisionDiscoveryReq.P2PGroupId.ssid, pFrm->P2PProvisionDiscoveryReq.P2PGroupId.num_ssid); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryReq. */ + +tANI_U32 dot11fPackProvisionDiscoveryRes(tpAniSirGlobal pCtx, tDot11fProvisionDiscoveryRes *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ProvisionDiscoveryRes, IES_ProvisionDiscoveryRes); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Packed the ProvisionDiscoveryRes:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUI.oui, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2POUISubType:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2POUISubType.ouiSubtype, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("P2PWSCProvisionDiscoveryRes:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("ConfigMethods:\n")); + if (!pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), ( tANI_U8* )&pFrm->P2PWSCProvisionDiscoveryRes.ConfigMethods.methods, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_PROVISIONDISCOVERYRES), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackProvisionDiscoveryRes. */ + +tANI_U32 dot11fPackQosMapConfigure(tpAniSirGlobal pCtx, tDot11fQosMapConfigure *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_QosMapConfigure, IES_QosMapConfigure); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Packed the QosMapConfigure:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_QOSMAPCONFIGURE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackQosMapConfigure. */ + +tANI_U32 dot11fPackRMC(tpAniSirGlobal pCtx, tDot11fRMC *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_RMC, IES_RMC); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Packed the RMC:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCOUI:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCOUI.oui, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("MagicCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->MagicCode.magic, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCVersion:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCVersion.version, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("RMCDialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->RMCDialogToken.token, 4); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("Ruler:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), ( tANI_U8* )&pFrm->Ruler.mac, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RMC), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRMC. */ + +tANI_U32 dot11fPackRadioMeasurementReport(tpAniSirGlobal pCtx, tDot11fRadioMeasurementReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_RadioMeasurementReport, IES_RadioMeasurementReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Packed the RadioMeasurementReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + for (i = 0; i < pFrm->num_MeasurementReport; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("MeasurementReport[%d]:\n"), i); + if (!pFrm->MeasurementReport[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("late (1): %d\n"), pFrm->MeasurementReport[i].late); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("incapable (1): %d\n"), pFrm->MeasurementReport[i].incapable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("refused (1): %d\n"), pFrm->MeasurementReport[i].refused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (5): %d\n"), pFrm->MeasurementReport[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].type, 1); + switch (pFrm->MeasurementReport[i].type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Basic.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("bss (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.bss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("ofdm_preamble (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.ofdm_preamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unid_signal (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unid_signal); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("rader (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.rader); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unmeasured (1): %d\n"), pFrm->MeasurementReport[i].report.Basic.unmeasured); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("unused (3): %d\n"), pFrm->MeasurementReport[i].report.Basic.unused); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.CCA.cca_busy_fraction, 1); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi0_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi1_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi2_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi3_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi4_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi5_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi6_density, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.RPIHistogram.rpi7_density, 1); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.meas_duration, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("condensed_PHY (7): %d\n"), pFrm->MeasurementReport[i].report.Beacon.condensed_PHY); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("reported_frame_type (1): %d\n"), pFrm->MeasurementReport[i].report.Beacon.reported_frame_type); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RCPI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.RSNI, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.BSSID, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.antenna_id, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), ( tANI_U8* )&pFrm->MeasurementReport[i].report.Beacon.parent_TSF, 4); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementReport. */ + +tANI_U32 dot11fPackRadioMeasurementRequest(tpAniSirGlobal pCtx, tDot11fRadioMeasurementRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_RadioMeasurementRequest, IES_RadioMeasurementRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Packed the RadioMeasurementRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("NumOfRepetitions:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->NumOfRepetitions.repetitions, 2); + for (i = 0; i < pFrm->num_MeasurementRequest; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("MeasurementRequest[%d]:\n"), i); + if (!pFrm->MeasurementRequest[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_token, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("parallel (1): %d\n"), pFrm->MeasurementRequest[i].parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("enable (1): %d\n"), pFrm->MeasurementRequest[i].enable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("request (1): %d\n"), pFrm->MeasurementRequest[i].request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("report (1): %d\n"), pFrm->MeasurementRequest[i].report); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("durationMandatory (1): %d\n"), pFrm->MeasurementRequest[i].durationMandatory); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("unused (3): %d\n"), pFrm->MeasurementRequest[i].unused); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_type, 1); + switch (pFrm->MeasurementRequest[i].measurement_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Basic.meas_duration, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.CCA.meas_duration, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.channel_no, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_start_time, 8); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.RPIHistogram.meas_duration, 2); + break; + case 5: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.regClass, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.randomization, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.meas_mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), ( tANI_U8* )&pFrm->MeasurementRequest[i].measurement_request.Beacon.BSSID, 6); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_RADIOMEASUREMENTREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackRadioMeasurementRequest. */ + +tANI_U32 dot11fPackReAssocRequest(tpAniSirGlobal pCtx, tDot11fReAssocRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ReAssocRequest, IES_ReAssocRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Packed the ReAssocRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ListenInterval:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ListenInterval.interval, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("CurrentAPAddress:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->CurrentAPAddress.mac, 6); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SSID:\n")); + if (!pFrm->SSID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_ssid: %d.\n"), pFrm->SSID.num_ssid); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SSID.ssid, pFrm->SSID.num_ssid); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PowerCaps:\n")); + if (!pFrm->PowerCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.minTxPower, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->PowerCaps.maxTxPower, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WPAOpaque:\n")); + if (!pFrm->WPAOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WPAOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WPAOpaque.data, pFrm->WPAOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMCaps:\n")); + if (!pFrm->WMMCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMCaps.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (4): %d\n"), pFrm->WMMCaps.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("qack (1): %d\n"), pFrm->WMMCaps.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("queue_request (1): %d\n"), pFrm->WMMCaps.queue_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txop_request (1): %d\n"), pFrm->WMMCaps.txop_request); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("more_ack (1): %d\n"), pFrm->WMMCaps.more_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WscIEOpaque:\n")); + if (!pFrm->WscIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WscIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WscIEOpaque.data, pFrm->WscIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WAPIOpaque:\n")); + if (!pFrm->WAPIOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WAPIOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WAPIOpaque.data, pFrm->WAPIOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESEVersion:\n")); + if (!pFrm->ESEVersion.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESEVersion.version, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESECckmOpaque:\n")); + if (!pFrm->ESECckmOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->ESECckmOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESECckmOpaque.data, pFrm->ESECckmOpaque.num_data); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("P2PIEOpaque:\n")); + if (!pFrm->P2PIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->P2PIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->P2PIEOpaque.data, pFrm->P2PIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("WFDIEOpaque:\n")); + if (!pFrm->WFDIEOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_data: %d.\n"), pFrm->WFDIEOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->WFDIEOpaque.data, pFrm->WFDIEOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs20vendor_ie:\n")); + if (!pFrm->hs20vendor_ie.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("dgaf_dis (1): %d\n"), pFrm->hs20vendor_ie.dgaf_dis); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("hs_id_present (2): %d\n"), pFrm->hs20vendor_ie.hs_id_present); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("reserved (1): %d\n"), pFrm->hs20vendor_ie.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("release_num (4): %d\n"), pFrm->hs20vendor_ie.release_num); + switch (pFrm->hs20vendor_ie.hs_id_present) + { + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.pps_mo.pps_mo_id, 2); + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), ( tANI_U8* )&pFrm->hs20vendor_ie.hs_id.anqp_domain.anqp_domain_id, 2); + break; + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocRequest. */ + +tANI_U32 dot11fPackReAssocResponse(tpAniSirGlobal pCtx, tDot11fReAssocResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_ReAssocResponse, IES_ReAssocResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Packed the ReAssocResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AID:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->AID.associd, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIIE:\n")); + if (!pFrm->RCPIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RCPIIE.rcpi, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIIE:\n")); + if (!pFrm->RSNIIE.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RSNIIE.rsni, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMEnabledCap:\n")); + if (!pFrm->RRMEnabledCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LinkMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LinkMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborRpt (1): %d\n"), pFrm->RRMEnabledCap.NeighborRpt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("parallel (1): %d\n"), pFrm->RRMEnabledCap.parallel); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("repeated (1): %d\n"), pFrm->RRMEnabledCap.repeated); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconPassive (1): %d\n"), pFrm->RRMEnabledCap.BeaconPassive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconActive (1): %d\n"), pFrm->RRMEnabledCap.BeaconActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconTable (1): %d\n"), pFrm->RRMEnabledCap.BeaconTable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BeaconRepCond (1): %d\n"), pFrm->RRMEnabledCap.BeaconRepCond); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FrameMeasurement (1): %d\n"), pFrm->RRMEnabledCap.FrameMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ChannelLoad (1): %d\n"), pFrm->RRMEnabledCap.ChannelLoad); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NoiseHistogram (1): %d\n"), pFrm->RRMEnabledCap.NoiseHistogram); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("statistics (1): %d\n"), pFrm->RRMEnabledCap.statistics); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.LCIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LCIAzimuth (1): %d\n"), pFrm->RRMEnabledCap.LCIAzimuth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCMCapability (1): %d\n"), pFrm->RRMEnabledCap.TCMCapability); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("triggeredTCM (1): %d\n"), pFrm->RRMEnabledCap.triggeredTCM); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APChanReport (1): %d\n"), pFrm->RRMEnabledCap.APChanReport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RRMMIBEnabled (1): %d\n"), pFrm->RRMEnabledCap.RRMMIBEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("operatingChanMax (3): %d\n"), pFrm->RRMEnabledCap.operatingChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonOperatinChanMax (3): %d\n"), pFrm->RRMEnabledCap.nonOperatinChanMax); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilot (3): %d\n"), pFrm->RRMEnabledCap.MeasurementPilot); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MeasurementPilotEnabled (1): %d\n"), pFrm->RRMEnabledCap.MeasurementPilotEnabled); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("NeighborTSFOffset (1): %d\n"), pFrm->RRMEnabledCap.NeighborTSFOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RCPIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RCPIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNIMeasurement (1): %d\n"), pFrm->RRMEnabledCap.RSNIMeasurement); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BssAvgAccessDelay (1): %d\n"), pFrm->RRMEnabledCap.BssAvgAccessDelay); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BSSAvailAdmission (1): %d\n"), pFrm->RRMEnabledCap.BSSAvailAdmission); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AntennaInformation (1): %d\n"), pFrm->RRMEnabledCap.AntennaInformation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->RRMEnabledCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RSNOpaque:\n")); + if (!pFrm->RSNOpaque.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_data: %d.\n"), pFrm->RSNOpaque.num_data); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RSNOpaque.data, pFrm->RSNOpaque.num_data); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("MobilityDomain:\n")); + if (!pFrm->MobilityDomain.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->MobilityDomain.MDID, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("overDSCap (1): %d\n"), pFrm->MobilityDomain.overDSCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("resourceReqCap (1): %d\n"), pFrm->MobilityDomain.resourceReqCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (6): %d\n"), pFrm->MobilityDomain.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + for (i = 0; i < pFrm->num_RICDataDesc; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDataDesc[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICData:\n")); + if (!pFrm->RICDataDesc[i].RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RICDescriptor:\n")); + if (!pFrm->RICDataDesc[i].RICDescriptor.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].RICDescriptor.resourceType, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_variableData: %d.\n"), pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->RICDataDesc[i].RICDescriptor.variableData, pFrm->RICDataDesc[i].RICDescriptor.num_variableData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSPEC:\n")); + if (!pFrm->RICDataDesc[i].TSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].TSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].TSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("schedule (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.schedule); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused (7): %d\n"), pFrm->RICDataDesc[i].TSPEC.unused); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].TSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].TSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_TCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].TCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TCLASSPROC:\n")); + if (!pFrm->RICDataDesc[i].TCLASSPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TCLASSPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TSDelay:\n")); + if (!pFrm->RICDataDesc[i].TSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].TSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Schedule:\n")); + if (!pFrm->RICDataDesc[i].Schedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].Schedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].Schedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].Schedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].Schedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].Schedule.spec_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->RICDataDesc[i].WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->RICDataDesc[i].WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSPEC.medium_time, 2); + } + for (i = 0; i < pFrm->RICDataDesc[i].num_WMMTCLAS; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLAS[%d]:\n"), i); + if (!pFrm->RICDataDesc[i].WMMTCLAS[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].user_priority, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_mask, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].classifier_type) + { + case 0: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.source, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.dest, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.EthParams.type, 2); + break; + case 1: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version, 1); + switch (pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.version) + { + case 4: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.source, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.DSCP, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.proto, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV4Params.reserved, 1); + break; + case 6: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.source, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.src_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.dest_port, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.IpParams.params.IpV6Params.flow_label, 3); + break; + } + break; + case 2: + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLAS[i].info.Params8021dq.tag_type, 2); + break; + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTCLASPROC:\n")); + if (!pFrm->RICDataDesc[i].WMMTCLASPROC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTCLASPROC.processing, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSDelay:\n")); + if (!pFrm->RICDataDesc[i].WMMTSDelay.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMTSDelay.delay, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMSchedule:\n")); + if (!pFrm->RICDataDesc[i].WMMSchedule.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (9): %d\n"), pFrm->RICDataDesc[i].WMMSchedule.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.service_interval, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.max_service_dur, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->RICDataDesc[i].WMMSchedule.spec_interval, 2); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WPA:\n")); + if (!pFrm->WPA.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.multicast_cipher, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.unicast_cipher_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.unicast_ciphers, 4 * pFrm->WPA.unicast_cipher_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.auth_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->WPA.auth_suites, 4 * pFrm->WPA.auth_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WPA.caps, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESERadMgmtCap:\n")); + if (!pFrm->ESERadMgmtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESERadMgmtCap.mgmt_state, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("mbssid_mask (3): %d\n"), pFrm->ESERadMgmtCap.mbssid_mask); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved (5): %d\n"), pFrm->ESERadMgmtCap.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETxmitPower:\n")); + if (!pFrm->ESETxmitPower.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.power_limit, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETxmitPower.reserved, 1); + } + for (i = 0; i < pFrm->num_WMMTSPEC; ++i) + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WMMTSPEC[%d]:\n"), i); + if (!pFrm->WMMTSPEC[i].present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC[i].traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC[i].tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC[i].direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC[i].access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC[i].aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC[i].psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC[i].user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC[i].tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC[i].tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC[i].burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC[i].size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC[i].fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC[i].medium_time, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Airgo:\n")); + if (!pFrm->Airgo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropSuppRates:\n")); + if (!pFrm->Airgo.PropSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_rates: %d.\n"), pFrm->Airgo.PropSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.PropSuppRates.rates, pFrm->Airgo.PropSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("APName:\n")); + if (!pFrm->Airgo.APName.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_name: %d.\n"), pFrm->Airgo.APName.num_name); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.APName.name, pFrm->Airgo.APName.num_name); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("HCF:\n")); + if (!pFrm->Airgo.HCF.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.HCF.enabled, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WDS:\n")); + if (!pFrm->Airgo.WDS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_wdsData: %d.\n"), pFrm->Airgo.WDS.num_wdsData); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.WDS.wdsData, pFrm->Airgo.WDS.num_wdsData); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("BPIndicator:\n")); + if (!pFrm->Airgo.BPIndicator.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.indicator, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.BPIndicator.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadInfo:\n")); + if (!pFrm->Airgo.LoadInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.num_stas, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadInfo.channel_util, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LoadBalance:\n")); + if (!pFrm->Airgo.LoadBalance.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LoadBalance.channel, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropAssocType:\n")); + if (!pFrm->Airgo.PropAssocType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropAssocType.type, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("LLAttr:\n")); + if (!pFrm->Airgo.LLAttr.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.LLAttr.defer_threshold, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropCapability:\n")); + if (!pFrm->Airgo.PropCapability.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropCapability.capability, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->Airgo.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.chip_rev, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Version.card_type, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_build_version: %d.\n"), pFrm->Airgo.Version.num_build_version); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->Airgo.Version.build_version, pFrm->Airgo.Version.num_build_version); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropEDCAParams:\n")); + if (!pFrm->Airgo.PropEDCAParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused1 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbe_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbe_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused2 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acbk_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acbk_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused3 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvi_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvi_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aifsn (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_acm (1): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_aci (2): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("unused4 (1): %d\n"), pFrm->Airgo.PropEDCAParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_min (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_min); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("acvo_max (4): %d\n"), pFrm->Airgo.PropEDCAParams.acvo_max); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropEDCAParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Titan:\n")); + if (!pFrm->Airgo.Titan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.concat_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.compression_tcid_bitmap, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.cb_state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Titan.rev_fcs_state, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropChannSwitchAnn:\n")); + if (!pFrm->Airgo.PropChannSwitchAnn.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.mode, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.primary_channel, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.sub_band, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropChannSwitchAnn.channel_switch_count, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("PropQuietBSS:\n")); + if (!pFrm->Airgo.PropQuietBSS.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_count, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_period, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_duration, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.PropQuietBSS.quiet_offset, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("TriggerStaBgScan:\n")); + if (!pFrm->Airgo.TriggerStaBgScan.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.TriggerStaBgScan.enable, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Taurus:\n")); + if (!pFrm->Airgo.Taurus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baTIDBitmap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->Airgo.Taurus.baPolicy, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("baBufferSize (12): %d\n"), pFrm->Airgo.Taurus.baBufferSize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rsvd (4): %d\n"), pFrm->Airgo.Taurus.rsvd); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("WscReassocRes:\n")); + if (!pFrm->WscReassocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version:\n")); + if (!pFrm->WscReassocRes.Version.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.Version.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.Version.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ResponseType:\n")); + if (!pFrm->WscReassocRes.ResponseType.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.ResponseType.resType, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VendorExtension:\n")); + if (!pFrm->WscReassocRes.VendorExtension.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.vendorId, 3); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Version2:\n")); + if (!pFrm->WscReassocRes.VendorExtension.Version2.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("minor (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.minor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("major (4): %d\n"), pFrm->WscReassocRes.VendorExtension.Version2.major); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("AuthorizedMACs:\n")); + if (!pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.AuthorizedMACs.mac, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("RequestToEnroll:\n")); + if (!pFrm->WscReassocRes.VendorExtension.RequestToEnroll.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->WscReassocRes.VendorExtension.RequestToEnroll.req, 1); + } + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PAssocRes:\n")); + if (!pFrm->P2PAssocRes.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("P2PStatus:\n")); + if (!pFrm->P2PAssocRes.P2PStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.P2PStatus.status, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtendedListenTiming:\n")); + if (!pFrm->P2PAssocRes.ExtendedListenTiming.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityPeriod, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->P2PAssocRes.ExtendedListenTiming.availibilityInterval, 2); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("OBSSScanParameters:\n")); + if (!pFrm->OBSSScanParameters.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveDwell, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssChannelWidthTriggerScanInterval, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanPassiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActiveTotalPerChannel, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.bssWidthChannelTransitionDelayFactor, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* )&pFrm->OBSSScanParameters.obssScanActivityThreshold, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("QosMapSet:\n")); + if (!pFrm->QosMapSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("num_dscp_exceptions: %d.\n"), pFrm->QosMapSet.num_dscp_exceptions); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), ( tANI_U8* ) pFrm->QosMapSet.dscp_exceptions, pFrm->QosMapSet.num_dscp_exceptions); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_REASSOCRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackReAssocResponse. */ + +tANI_U32 dot11fPackSMPowerSave(tpAniSirGlobal pCtx, tDot11fSMPowerSave *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_SMPowerSave, IES_SMPowerSave); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Packed the SMPowerSave:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("SMPowerModeSet:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("PowerSave_En (1): %d\n"), pFrm->SMPowerModeSet.PowerSave_En); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("Mode (1): %d\n"), pFrm->SMPowerModeSet.Mode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("reserved (6): %d\n"), pFrm->SMPowerModeSet.reserved); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SMPOWERSAVE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSMPowerSave. */ + +tANI_U32 dot11fPackSaQueryReq(tpAniSirGlobal pCtx, tDot11fSaQueryReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_SaQueryReq, IES_SaQueryReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Packed the SaQueryReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryReq. */ + +tANI_U32 dot11fPackSaQueryRsp(tpAniSirGlobal pCtx, tDot11fSaQueryRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_SaQueryRsp, IES_SaQueryRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Packed the SaQueryRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("TransactionId:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), ( tANI_U8* )&pFrm->TransactionId.transId, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_SAQUERYRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackSaQueryRsp. */ + +tANI_U32 dot11fPackTDLSDisReq(tpAniSirGlobal pCtx, tDot11fTDLSDisReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSDisReq, IES_TDLSDisReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Packed the TDLSDisReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisReq. */ + +tANI_U32 dot11fPackTDLSDisRsp(tpAniSirGlobal pCtx, tDot11fTDLSDisRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSDisRsp, IES_TDLSDisRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Packed the TDLSDisRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSDISRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSDisRsp. */ + +tANI_U32 dot11fPackTDLSPeerTrafficInd(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficInd *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSPeerTrafficInd, IES_TDLSPeerTrafficInd); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Packed the TDLSPeerTrafficInd:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PTIControl:\n")); + if (!pFrm->PTIControl.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.tid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), ( tANI_U8* )&pFrm->PTIControl.sequence_control, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("PUBufferStatus:\n")); + if (!pFrm->PUBufferStatus.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_bk_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_bk_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_be_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_be_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vi_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vi_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("ac_vo_traffic_aval (1): %d\n"), pFrm->PUBufferStatus.ac_vo_traffic_aval); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("reserved (4): %d\n"), pFrm->PUBufferStatus.reserved); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICIND), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficInd. */ + +tANI_U32 dot11fPackTDLSPeerTrafficRsp(tpAniSirGlobal pCtx, tDot11fTDLSPeerTrafficRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSPeerTrafficRsp, IES_TDLSPeerTrafficRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Packed the TDLSPeerTrafficRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSPEERTRAFFICRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSPeerTrafficRsp. */ + +tANI_U32 dot11fPackTDLSSetupCnf(tpAniSirGlobal pCtx, tDot11fTDLSSetupCnf *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSSetupCnf, IES_TDLSSetupCnf); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Packed the TDLSSetupCnf:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("EDCAParamSet:\n")); + if (!pFrm->EDCAParamSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.qos, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.reserved, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->EDCAParamSet.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->EDCAParamSet.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->EDCAParamSet.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->EDCAParamSet.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->EDCAParamSet.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->EDCAParamSet.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->EDCAParamSet.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->EDCAParamSet.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->EDCAParamSet.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->EDCAParamSet.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->EDCAParamSet.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->EDCAParamSet.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->EDCAParamSet.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->EDCAParamSet.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->EDCAParamSet.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->EDCAParamSet.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->EDCAParamSet.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("HTInfo:\n")); + if (!pFrm->HTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.primaryChannel, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryChannelOffset (2): %d\n"), pFrm->HTInfo.secondaryChannelOffset); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("recommendedTxWidthSet (1): %d\n"), pFrm->HTInfo.recommendedTxWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rifsMode (1): %d\n"), pFrm->HTInfo.rifsMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("controlledAccessOnly (1): %d\n"), pFrm->HTInfo.controlledAccessOnly); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("serviceIntervalGranularity (3): %d\n"), pFrm->HTInfo.serviceIntervalGranularity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("opMode (2): %d\n"), pFrm->HTInfo.opMode); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("nonGFDevicesPresent (1): %d\n"), pFrm->HTInfo.nonGFDevicesPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("transmitBurstLimit (1): %d\n"), pFrm->HTInfo.transmitBurstLimit); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssNonHTStaPresent (1): %d\n"), pFrm->HTInfo.obssNonHTStaPresent); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (11): %d\n"), pFrm->HTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("basicSTBCMCS (7): %d\n"), pFrm->HTInfo.basicSTBCMCS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("dualCTSProtection (1): %d\n"), pFrm->HTInfo.dualCTSProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("secondaryBeacon (1): %d\n"), pFrm->HTInfo.secondaryBeacon); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("lsigTXOPProtectionFullSupport (1): %d\n"), pFrm->HTInfo.lsigTXOPProtectionFullSupport); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoActive (1): %d\n"), pFrm->HTInfo.pcoActive); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("pcoPhase (1): %d\n"), pFrm->HTInfo.pcoPhase); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved2 (4): %d\n"), pFrm->HTInfo.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->HTInfo.basicMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("num_rsvd: %d.\n"), pFrm->HTInfo.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* ) pFrm->HTInfo.rsvd, pFrm->HTInfo.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("WMMParams:\n")); + if (!pFrm->WMMParams.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.version, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.qosInfo, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.reserved2, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aifsn (4): %d\n"), pFrm->WMMParams.acbe_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acm (1): %d\n"), pFrm->WMMParams.acbe_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_aci (2): %d\n"), pFrm->WMMParams.acbe_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused1 (1): %d\n"), pFrm->WMMParams.unused1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmin (4): %d\n"), pFrm->WMMParams.acbe_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbe_acwmax (4): %d\n"), pFrm->WMMParams.acbe_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbe_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aifsn (4): %d\n"), pFrm->WMMParams.acbk_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acm (1): %d\n"), pFrm->WMMParams.acbk_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_aci (2): %d\n"), pFrm->WMMParams.acbk_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused2 (1): %d\n"), pFrm->WMMParams.unused2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmin (4): %d\n"), pFrm->WMMParams.acbk_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acbk_acwmax (4): %d\n"), pFrm->WMMParams.acbk_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acbk_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aifsn (4): %d\n"), pFrm->WMMParams.acvi_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acm (1): %d\n"), pFrm->WMMParams.acvi_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_aci (2): %d\n"), pFrm->WMMParams.acvi_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused3 (1): %d\n"), pFrm->WMMParams.unused3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmin (4): %d\n"), pFrm->WMMParams.acvi_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvi_acwmax (4): %d\n"), pFrm->WMMParams.acvi_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvi_txoplimit, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aifsn (4): %d\n"), pFrm->WMMParams.acvo_aifsn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acm (1): %d\n"), pFrm->WMMParams.acvo_acm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_aci (2): %d\n"), pFrm->WMMParams.acvo_aci); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("unused4 (1): %d\n"), pFrm->WMMParams.unused4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmin (4): %d\n"), pFrm->WMMParams.acvo_acwmin); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("acvo_acwmax (4): %d\n"), pFrm->WMMParams.acvo_acwmax); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->WMMParams.acvo_txoplimit, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("VHTOperation:\n")); + if (!pFrm->VHTOperation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanWidth, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg1, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.chanCenterFreqSeg2, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), ( tANI_U8* )&pFrm->VHTOperation.basicMCSSet, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPCNF), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupCnf. */ + +tANI_U32 dot11fPackTDLSSetupReq(tpAniSirGlobal pCtx, tDot11fTDLSSetupReq *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSSetupReq, IES_TDLSSetupReq); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Packed the TDLSSetupReq:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPREQ), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupReq. */ + +tANI_U32 dot11fPackTDLSSetupRsp(tpAniSirGlobal pCtx, tDot11fTDLSSetupRsp *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSSetupRsp, IES_TDLSSetupRsp); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Packed the TDLSSetupRsp:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Status:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Status.status, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Capabilities:\n")); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ess (1): %d\n"), pFrm->Capabilities.ess); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ibss (1): %d\n"), pFrm->Capabilities.ibss); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollable (1): %d\n"), pFrm->Capabilities.cfPollable); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("cfPollReq (1): %d\n"), pFrm->Capabilities.cfPollReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("privacy (1): %d\n"), pFrm->Capabilities.privacy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortPreamble (1): %d\n"), pFrm->Capabilities.shortPreamble); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pbcc (1): %d\n"), pFrm->Capabilities.pbcc); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("channelAgility (1): %d\n"), pFrm->Capabilities.channelAgility); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("spectrumMgt (1): %d\n"), pFrm->Capabilities.spectrumMgt); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qos (1): %d\n"), pFrm->Capabilities.qos); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortSlotTime (1): %d\n"), pFrm->Capabilities.shortSlotTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("apsd (1): %d\n"), pFrm->Capabilities.apsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rrm (1): %d\n"), pFrm->Capabilities.rrm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssOfdm (1): %d\n"), pFrm->Capabilities.dsssOfdm); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->Capabilities.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("immediateBA (1): %d\n"), pFrm->Capabilities.immediateBA); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppRates:\n")); + if (!pFrm->SuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->SuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppRates.rates, pFrm->SuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Country:\n")); + if (!pFrm->Country.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->Country.country, 3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_triplets: %d.\n"), pFrm->Country.num_triplets); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->Country.triplets, 3 * pFrm->Country.num_triplets); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtSuppRates:\n")); + if (!pFrm->ExtSuppRates.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rates: %d.\n"), pFrm->ExtSuppRates.num_rates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtSuppRates.rates, pFrm->ExtSuppRates.num_rates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppChannels:\n")); + if (!pFrm->SuppChannels.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bands: %d.\n"), pFrm->SuppChannels.num_bands); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppChannels.bands, 2 * pFrm->SuppChannels.num_bands); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RSN:\n")); + if (!pFrm->RSN.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.version, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_cipher_suite, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pwise_cipher_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pwise_cipher_suites, 4 * pFrm->RSN.pwise_cipher_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.akm_suite_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.akm_suites, 4 * pFrm->RSN.akm_suite_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.RSN_Cap, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.pmkid_count, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->RSN.pmkid, 16 * pFrm->RSN.pmkid_count); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RSN.gp_mgmt_cipher_suite, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ExtCap:\n")); + if (!pFrm->ExtCap.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_bytes: %d.\n"), pFrm->ExtCap.num_bytes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->ExtCap.bytes, pFrm->ExtCap.num_bytes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("SuppOperatingClasses:\n")); + if (!pFrm->SuppOperatingClasses.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_classes: %d.\n"), pFrm->SuppOperatingClasses.num_classes); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->SuppOperatingClasses.classes, pFrm->SuppOperatingClasses.num_classes); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("QOSCapsStation:\n")); + if (!pFrm->QOSCapsStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->QOSCapsStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->QOSCapsStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("qack (1): %d\n"), pFrm->QOSCapsStation.qack); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->QOSCapsStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("more_data_ack (1): %d\n"), pFrm->QOSCapsStation.more_data_ack); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("TimeoutInterval:\n")); + if (!pFrm->TimeoutInterval.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutType, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->TimeoutInterval.timeoutValue, 4); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("RICData:\n")); + if (!pFrm->RICData.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.Identifier, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.resourceDescCount, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->RICData.statusCode, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HTCaps:\n")); + if (!pFrm->HTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("advCodingCap (1): %d\n"), pFrm->HTCaps.advCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (1): %d\n"), pFrm->HTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mimoPowerSave (2): %d\n"), pFrm->HTCaps.mimoPowerSave); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("greenField (1): %d\n"), pFrm->HTCaps.greenField); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI20MHz (1): %d\n"), pFrm->HTCaps.shortGI20MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI40MHz (1): %d\n"), pFrm->HTCaps.shortGI40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->HTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (2): %d\n"), pFrm->HTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("delayedBA (1): %d\n"), pFrm->HTCaps.delayedBA); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maximalAMSDUsize (1): %d\n"), pFrm->HTCaps.maximalAMSDUsize); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("dsssCckMode40MHz (1): %d\n"), pFrm->HTCaps.dsssCckMode40MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("psmp (1): %d\n"), pFrm->HTCaps.psmp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("stbcControlFrame (1): %d\n"), pFrm->HTCaps.stbcControlFrame); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("lsigTXOPProtection (1): %d\n"), pFrm->HTCaps.lsigTXOPProtection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxRxAMPDUFactor (2): %d\n"), pFrm->HTCaps.maxRxAMPDUFactor); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mpduDensity (3): %d\n"), pFrm->HTCaps.mpduDensity); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (3): %d\n"), pFrm->HTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->HTCaps.supportedMCSSet, 16); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("pco (1): %d\n"), pFrm->HTCaps.pco); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("transitionTime (2): %d\n"), pFrm->HTCaps.transitionTime); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (5): %d\n"), pFrm->HTCaps.reserved2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("mcsFeedback (2): %d\n"), pFrm->HTCaps.mcsFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (6): %d\n"), pFrm->HTCaps.reserved3); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txBF (1): %d\n"), pFrm->HTCaps.txBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxStaggeredSounding (1): %d\n"), pFrm->HTCaps.rxStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txStaggeredSounding (1): %d\n"), pFrm->HTCaps.txStaggeredSounding); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxZLF (1): %d\n"), pFrm->HTCaps.rxZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txZLF (1): %d\n"), pFrm->HTCaps.txZLF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("implicitTxBF (1): %d\n"), pFrm->HTCaps.implicitTxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("calibration (2): %d\n"), pFrm->HTCaps.calibration); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSITxBF (1): %d\n"), pFrm->HTCaps.explicitCSITxBF); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrix (1): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrix); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitBFCSIFeedback (3): %d\n"), pFrm->HTCaps.explicitBFCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitUncompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitUncompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCompressedSteeringMatrixFeedback (3): %d\n"), pFrm->HTCaps.explicitCompressedSteeringMatrixFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csiNumBFAntennae (2): %d\n"), pFrm->HTCaps.csiNumBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("uncompressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.uncompressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("compressedSteeringMatrixBFAntennae (2): %d\n"), pFrm->HTCaps.compressedSteeringMatrixBFAntennae); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved4 (7): %d\n"), pFrm->HTCaps.reserved4); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaSelection (1): %d\n"), pFrm->HTCaps.antennaSelection); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedbackTx (1): %d\n"), pFrm->HTCaps.explicitCSIFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedbackTx (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedbackTx); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("explicitCSIFeedback (1): %d\n"), pFrm->HTCaps.explicitCSIFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("antennaIndicesFeedback (1): %d\n"), pFrm->HTCaps.antennaIndicesFeedback); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAS (1): %d\n"), pFrm->HTCaps.rxAS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSoundingPPDUs (1): %d\n"), pFrm->HTCaps.txSoundingPPDUs); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved5 (1): %d\n"), pFrm->HTCaps.reserved5); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("num_rsvd: %d.\n"), pFrm->HTCaps.num_rsvd); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* ) pFrm->HTCaps.rsvd, pFrm->HTCaps.num_rsvd); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("HT2040BSSCoexistence:\n")); + if (!pFrm->HT2040BSSCoexistence.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("infoRequest (1): %d\n"), pFrm->HT2040BSSCoexistence.infoRequest); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("fortyMHzIntolerant (1): %d\n"), pFrm->HT2040BSSCoexistence.fortyMHzIntolerant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("twentyMHzBssWidthReq (1): %d\n"), pFrm->HT2040BSSCoexistence.twentyMHzBssWidthReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionReq (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionReq); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("obssScanExemptionGrant (1): %d\n"), pFrm->HT2040BSSCoexistence.obssScanExemptionGrant); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("unused (3): %d\n"), pFrm->HT2040BSSCoexistence.unused); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("WMMInfoStation:\n")); + if (!pFrm->WMMInfoStation.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->WMMInfoStation.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvo_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvo_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acvi_uapsd (1): %d\n"), pFrm->WMMInfoStation.acvi_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbk_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbk_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("acbe_uapsd (1): %d\n"), pFrm->WMMInfoStation.acbe_uapsd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (1): %d\n"), pFrm->WMMInfoStation.reserved1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("max_sp_length (2): %d\n"), pFrm->WMMInfoStation.max_sp_length); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (1): %d\n"), pFrm->WMMInfoStation.reserved2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("AID:\n")); + if (!pFrm->AID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->AID.assocId, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("VHTCaps:\n")); + if (!pFrm->VHTCaps.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxMPDULen (2): %d\n"), pFrm->VHTCaps.maxMPDULen); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("supportedChannelWidthSet (2): %d\n"), pFrm->VHTCaps.supportedChannelWidthSet); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("ldpcCodingCap (1): %d\n"), pFrm->VHTCaps.ldpcCodingCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI80MHz (1): %d\n"), pFrm->VHTCaps.shortGI80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("shortGI160and80plus80MHz (1): %d\n"), pFrm->VHTCaps.shortGI160and80plus80MHz); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSTBC (1): %d\n"), pFrm->VHTCaps.txSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxSTBC (3): %d\n"), pFrm->VHTCaps.rxSTBC); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamFormerCap (1): %d\n"), pFrm->VHTCaps.suBeamFormerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("suBeamformeeCap (1): %d\n"), pFrm->VHTCaps.suBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("csnofBeamformerAntSup (3): %d\n"), pFrm->VHTCaps.csnofBeamformerAntSup); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("numSoundingDim (3): %d\n"), pFrm->VHTCaps.numSoundingDim); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformerCap (1): %d\n"), pFrm->VHTCaps.muBeamformerCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("muBeamformeeCap (1): %d\n"), pFrm->VHTCaps.muBeamformeeCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtTXOPPS (1): %d\n"), pFrm->VHTCaps.vhtTXOPPS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("htcVHTCap (1): %d\n"), pFrm->VHTCaps.htcVHTCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("maxAMPDULenExp (3): %d\n"), pFrm->VHTCaps.maxAMPDULenExp); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("vhtLinkAdaptCap (2): %d\n"), pFrm->VHTCaps.vhtLinkAdaptCap); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxAntPattern (1): %d\n"), pFrm->VHTCaps.rxAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txAntPattern (1): %d\n"), pFrm->VHTCaps.txAntPattern); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved1 (2): %d\n"), pFrm->VHTCaps.reserved1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.rxMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxHighSupDataRate (13): %d\n"), pFrm->VHTCaps.rxHighSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved2 (3): %d\n"), pFrm->VHTCaps.reserved2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), ( tANI_U8* )&pFrm->VHTCaps.txMCSMap, 2); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("txSupDataRate (13): %d\n"), pFrm->VHTCaps.txSupDataRate); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved3 (3): %d\n"), pFrm->VHTCaps.reserved3); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("OperatingMode:\n")); + if (!pFrm->OperatingMode.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("chanWidth (2): %d\n"), pFrm->OperatingMode.chanWidth); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("reserved (2): %d\n"), pFrm->OperatingMode.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSS (3): %d\n"), pFrm->OperatingMode.rxNSS); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("rxNSSType (1): %d\n"), pFrm->OperatingMode.rxNSSType); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSSETUPRSP), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSSetupRsp. */ + +tANI_U32 dot11fPackTDLSTeardown(tpAniSirGlobal pCtx, tDot11fTDLSTeardown *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TDLSTeardown, IES_TDLSTeardown); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Packed the TDLSTeardown:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Reason:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->Reason.code, 2); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("FTInfo:\n")); + if (!pFrm->FTInfo.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (8): %d\n"), pFrm->FTInfo.reserved); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IECount (8): %d\n"), pFrm->FTInfo.IECount); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.MIC, 16); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Anonce, 32); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.Snonce, 32); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R1KH_ID:\n")); + if (!pFrm->FTInfo.R1KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.R1KH_ID.PMK_R1_ID, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("GTK:\n")); + if (!pFrm->FTInfo.GTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("keyId (2): %d\n"), pFrm->FTInfo.GTK.keyId); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("reserved (14): %d\n"), pFrm->FTInfo.GTK.reserved); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.GTK.RSC, 8); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_key: %d.\n"), pFrm->FTInfo.GTK.num_key); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.GTK.key, pFrm->FTInfo.GTK.num_key); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("R0KH_ID:\n")); + if (!pFrm->FTInfo.R0KH_ID.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("num_PMK_R0_ID: %d.\n"), pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* ) pFrm->FTInfo.R0KH_ID.PMK_R0_ID, pFrm->FTInfo.R0KH_ID.num_PMK_R0_ID); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("IGTK:\n")); + if (!pFrm->FTInfo.IGTK.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyID, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.IPN, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.keyLength, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->FTInfo.IGTK.key, 24); + } + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("LinkIdentifier:\n")); + if (!pFrm->LinkIdentifier.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.bssid, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.InitStaAddr, 6); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), ( tANI_U8* )&pFrm->LinkIdentifier.RespStaAddr, 6); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TDLSTEARDOWN), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTDLSTeardown. */ + +tANI_U32 dot11fPackTPCReport(tpAniSirGlobal pCtx, tDot11fTPCReport *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TPCReport, IES_TPCReport); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Packed the TPCReport:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("TPCReport:\n")); + if (!pFrm->TPCReport.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.tx_power, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), ( tANI_U8* )&pFrm->TPCReport.link_margin, 1); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREPORT), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCReport. */ + +tANI_U32 dot11fPackTPCRequest(tpAniSirGlobal pCtx, tDot11fTPCRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_TPCRequest, IES_TPCRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Packed the TPCRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("TPCRequest:\n")); + if (!pFrm->TPCRequest.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("Not present.\n")); + } + else + { + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_TPCREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackTPCRequest. */ + +tANI_U32 dot11fPackVHTGidManagementActionFrame(tpAniSirGlobal pCtx, tDot11fVHTGidManagementActionFrame *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_VHTGidManagementActionFrame, IES_VHTGidManagementActionFrame); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Packed the VHTGidManagementActionFrame:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtMembershipStatusArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtMembershipStatusArray.membershipStatusArray, 8); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("VhtUserPositionArray:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), ( tANI_U8* )&pFrm->VhtUserPositionArray.userPositionArray, 16); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_VHTGIDMANAGEMENTACTIONFRAME), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackVHTGidManagementActionFrame. */ + +tANI_U32 dot11fPackWMMAddTSRequest(tpAniSirGlobal pCtx, tDot11fWMMAddTSRequest *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_WMMAddTSRequest, IES_WMMAddTSRequest); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Packed the WMMAddTSRequest:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("ESETrafStrmRateSet:\n")); + if (!pFrm->ESETrafStrmRateSet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* )&pFrm->ESETrafStrmRateSet.tsid, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("num_tsrates: %d.\n"), pFrm->ESETrafStrmRateSet.num_tsrates); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), ( tANI_U8* ) pFrm->ESETrafStrmRateSet.tsrates, pFrm->ESETrafStrmRateSet.num_tsrates); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSREQUEST), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSRequest. */ + +tANI_U32 dot11fPackWMMAddTSResponse(tpAniSirGlobal pCtx, tDot11fWMMAddTSResponse *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_WMMAddTSResponse, IES_WMMAddTSResponse); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Packed the WMMAddTSResponse:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("ESETrafStrmMet:\n")); + if (!pFrm->ESETrafStrmMet.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.tsid, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.state, 1); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), ( tANI_U8* )&pFrm->ESETrafStrmMet.msmt_interval, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMADDTSRESPONSE), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMAddTSResponse. */ + +tANI_U32 dot11fPackWMMDelTS(tpAniSirGlobal pCtx, tDot11fWMMDelTS *pFrm, tANI_U8 *pBuf, tANI_U32 nBuf, tANI_U32 *pnConsumed) +{ + tANI_U32 i = 0; + tANI_U32 status = 0; + (void)i; + *pnConsumed = 0U; + status = PackCore(pCtx, (tANI_U8*)pFrm, pBuf, nBuf, pnConsumed, FFS_WMMDelTS, IES_WMMDelTS); + +# ifdef DOT11F_DUMP_FRAMES + if (!DOT11F_FAILED(status)) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Packed the WMMDelTS:\n")); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Category:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Category.category, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Action:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->Action.action, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("DialogToken:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->DialogToken.token, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("StatusCode:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->StatusCode.statusCode, 1); + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("WMMTSPEC:\n")); + if (!pFrm->WMMTSPEC.present) + { + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("Not present.\n")); + } + else + { + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.version, 1); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("traffic_type (1): %d\n"), pFrm->WMMTSPEC.traffic_type); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsid (4): %d\n"), pFrm->WMMTSPEC.tsid); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("direction (2): %d\n"), pFrm->WMMTSPEC.direction); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("access_policy (2): %d\n"), pFrm->WMMTSPEC.access_policy); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("aggregation (1): %d\n"), pFrm->WMMTSPEC.aggregation); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("psb (1): %d\n"), pFrm->WMMTSPEC.psb); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("user_priority (3): %d\n"), pFrm->WMMTSPEC.user_priority); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_ack_pol (2): %d\n"), pFrm->WMMTSPEC.tsinfo_ack_pol); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("tsinfo_rsvd (7): %d\n"), pFrm->WMMTSPEC.tsinfo_rsvd); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("burst_size_defn (1): %d\n"), pFrm->WMMTSPEC.burst_size_defn); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("size (15): %d\n"), pFrm->WMMTSPEC.size); + FRAMES_LOG1(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("fixed (1): %d\n"), pFrm->WMMTSPEC.fixed); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_msdu_size, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.max_service_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.inactivity_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.suspension_int, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.service_start_time, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.mean_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.peak_data_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.burst_size, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.delay_bound, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.min_phy_rate, 4); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.surplus_bw_allowance, 2); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), ( tANI_U8* )&pFrm->WMMTSPEC.medium_time, 2); + } + FRAMES_LOG0(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), FRFL("to:\n")); + FRAMES_DUMP(pCtx, FRAMES_SEV_FOR_FRAME(pCtx, DOT11F_WMMDELTS), pBuf, nBuf); + } +# endif // DOT11F_DUMP_FRAMES + return status; + +} /* End dot11fUnpackWMMDelTS. */ + +static tANI_U32 PackCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tFFDefn FFs[], + const tIEDefn IEs[]) +{ + const tFFDefn *pFf; + const tIEDefn *pIe; + tFRAMES_BOOL *pfFound; + tANI_U8 *pBufRemaining; + tANI_U16 i; + tANI_U32 nBufRemaining, status, len; + tANI_U32 countOffset = 0; + + (void)pCtx; /* Shutup the compiler if we have no FFs nor IEs... */ + i=0; + + DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed); + + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pFf = &( FFs[0] ); + while ( pFf->size ) + { + if ( pFf->size > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The Fixed Field %s req" + "uires %d bytes, but there are only %d remaining.\n"), + pFf->name, pFf->size, nBufRemaining); + return DOT11F_BUFFER_OVERFLOW; + } + + switch ( pFf->sig ) + { + case SigFfAID: + dot11fPackFfAID(pCtx, (tDot11fFfAID* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAction: + dot11fPackFfAction(pCtx, (tDot11fFfAction* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAddBAParameterSet: + dot11fPackFfAddBAParameterSet(pCtx, (tDot11fFfAddBAParameterSet* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAuthAlgo: + dot11fPackFfAuthAlgo(pCtx, (tDot11fFfAuthAlgo* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfAuthSeqNo: + dot11fPackFfAuthSeqNo(pCtx, (tDot11fFfAuthSeqNo* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfBAStartingSequenceControl: + dot11fPackFfBAStartingSequenceControl(pCtx, (tDot11fFfBAStartingSequenceControl* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfBATimeout: + dot11fPackFfBATimeout(pCtx, (tDot11fFfBATimeout* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfBeaconInterval: + dot11fPackFfBeaconInterval(pCtx, (tDot11fFfBeaconInterval* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfCapabilities: + dot11fPackFfCapabilities(pCtx, (tDot11fFfCapabilities* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfCategory: + dot11fPackFfCategory(pCtx, (tDot11fFfCategory* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfCurrentAPAddress: + dot11fPackFfCurrentAPAddress(pCtx, (tDot11fFfCurrentAPAddress* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfDelBAParameterSet: + dot11fPackFfDelBAParameterSet(pCtx, (tDot11fFfDelBAParameterSet* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfDialogToken: + dot11fPackFfDialogToken(pCtx, (tDot11fFfDialogToken* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfLinkMargin: + dot11fPackFfLinkMargin(pCtx, (tDot11fFfLinkMargin* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfListenInterval: + dot11fPackFfListenInterval(pCtx, (tDot11fFfListenInterval* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfMagicCode: + dot11fPackFfMagicCode(pCtx, (tDot11fFfMagicCode* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfMaxTxPower: + dot11fPackFfMaxTxPower(pCtx, (tDot11fFfMaxTxPower* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfNumOfRepetitions: + dot11fPackFfNumOfRepetitions(pCtx, (tDot11fFfNumOfRepetitions* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfOperatingMode: + dot11fPackFfOperatingMode(pCtx, (tDot11fFfOperatingMode* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfP2POUI: + dot11fPackFfP2POUI(pCtx, (tDot11fFfP2POUI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfP2POUISubType: + dot11fPackFfP2POUISubType(pCtx, (tDot11fFfP2POUISubType* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRCPI: + dot11fPackFfRCPI(pCtx, (tDot11fFfRCPI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRMCDialogToken: + dot11fPackFfRMCDialogToken(pCtx, (tDot11fFfRMCDialogToken* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRMCOUI: + dot11fPackFfRMCOUI(pCtx, (tDot11fFfRMCOUI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRMCVersion: + dot11fPackFfRMCVersion(pCtx, (tDot11fFfRMCVersion* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRSNI: + dot11fPackFfRSNI(pCtx, (tDot11fFfRSNI* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfReason: + dot11fPackFfReason(pCtx, (tDot11fFfReason* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRuler: + dot11fPackFfRuler(pCtx, (tDot11fFfRuler* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfRxAntennaId: + dot11fPackFfRxAntennaId(pCtx, (tDot11fFfRxAntennaId* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfSMPowerModeSet: + dot11fPackFfSMPowerModeSet(pCtx, (tDot11fFfSMPowerModeSet* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfStatus: + dot11fPackFfStatus(pCtx, (tDot11fFfStatus* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfStatusCode: + dot11fPackFfStatusCode(pCtx, (tDot11fFfStatusCode* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTPCEleID: + dot11fPackFfTPCEleID(pCtx, (tDot11fFfTPCEleID* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTPCEleLen: + dot11fPackFfTPCEleLen(pCtx, (tDot11fFfTPCEleLen* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTSInfo: + dot11fPackFfTSInfo(pCtx, (tDot11fFfTSInfo* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTimeStamp: + dot11fPackFfTimeStamp(pCtx, (tDot11fFfTimeStamp* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTransactionId: + dot11fPackFfTransactionId(pCtx, (tDot11fFfTransactionId* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTxAntennaId: + dot11fPackFfTxAntennaId(pCtx, (tDot11fFfTxAntennaId* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfTxPower: + dot11fPackFfTxPower(pCtx, (tDot11fFfTxPower* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfVhtMembershipStatusArray: + dot11fPackFfVhtMembershipStatusArray(pCtx, (tDot11fFfVhtMembershipStatusArray* )(pSrc + pFf->offset), pBufRemaining); + break; + case SigFfVhtUserPositionArray: + dot11fPackFfVhtUserPositionArray(pCtx, (tDot11fFfVhtUserPositionArray* )(pSrc + pFf->offset), pBufRemaining); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the Fixed Field %d; this is most l" + "ikely a bug in 'framesg'.\n"), pFf->sig); + return DOT11F_INTERNAL_ERROR; + } + + pBufRemaining += pFf->size; + nBufRemaining -= pFf->size; + *pnConsumed += pFf->size; + ++pFf; + + } + + pIe = &( IEs[0] ); + while ( 0xff != pIe->eid ) + { + pfFound = (tFRAMES_BOOL*)(pSrc + pIe->offset + + pIe->presenceOffset); + if ( *pfFound && pIe->minSize > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The IE %s takes at le" + "ast %d bytes, but there are only %d left in the b" + "uffer.\n"), pIe->name, pIe->minSize, nBufRemaining); + return DOT11F_BUFFER_OVERFLOW; + } + + + countOffset = ( (0 == pIe->arraybound) ? 1: *(tANI_U16* )(pSrc + pIe->countOffset) ); + for (i = 0; i < countOffset; ++i) + { + len = 0U; + switch ( pIe->sig ) + { + case SigIeAPName: + status |= dot11fPackIeAPName(pCtx, ( tDot11fIEAPName* )(pSrc + pIe->offset + sizeof(tDot11fIEAPName) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBPIndicator: + status |= dot11fPackIeBPIndicator(pCtx, ( tDot11fIEBPIndicator* )(pSrc + pIe->offset + sizeof(tDot11fIEBPIndicator) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeCondensedCountryStr: + status |= dot11fPackIeCondensedCountryStr(pCtx, ( tDot11fIECondensedCountryStr* )(pSrc + pIe->offset + sizeof(tDot11fIECondensedCountryStr) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeGTK: + status |= dot11fPackIeGTK(pCtx, ( tDot11fIEGTK* )(pSrc + pIe->offset + sizeof(tDot11fIEGTK) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHCF: + status |= dot11fPackIeHCF(pCtx, ( tDot11fIEHCF* )(pSrc + pIe->offset + sizeof(tDot11fIEHCF) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeIGTK: + status |= dot11fPackIeIGTK(pCtx, ( tDot11fIEIGTK* )(pSrc + pIe->offset + sizeof(tDot11fIEIGTK) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLLAttr: + status |= dot11fPackIeLLAttr(pCtx, ( tDot11fIELLAttr* )(pSrc + pIe->offset + sizeof(tDot11fIELLAttr) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLoadBalance: + status |= dot11fPackIeLoadBalance(pCtx, ( tDot11fIELoadBalance* )(pSrc + pIe->offset + sizeof(tDot11fIELoadBalance) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLoadInfo: + status |= dot11fPackIeLoadInfo(pCtx, ( tDot11fIELoadInfo* )(pSrc + pIe->offset + sizeof(tDot11fIELoadInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropAssocType: + status |= dot11fPackIePropAssocType(pCtx, ( tDot11fIEPropAssocType* )(pSrc + pIe->offset + sizeof(tDot11fIEPropAssocType) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropCapability: + status |= dot11fPackIePropCapability(pCtx, ( tDot11fIEPropCapability* )(pSrc + pIe->offset + sizeof(tDot11fIEPropCapability) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropChannSwitchAnn: + status |= dot11fPackIePropChannSwitchAnn(pCtx, ( tDot11fIEPropChannSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEPropChannSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropEDCAParams: + status |= dot11fPackIePropEDCAParams(pCtx, ( tDot11fIEPropEDCAParams* )(pSrc + pIe->offset + sizeof(tDot11fIEPropEDCAParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropQuietBSS: + status |= dot11fPackIePropQuietBSS(pCtx, ( tDot11fIEPropQuietBSS* )(pSrc + pIe->offset + sizeof(tDot11fIEPropQuietBSS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePropSuppRates: + status |= dot11fPackIePropSuppRates(pCtx, ( tDot11fIEPropSuppRates* )(pSrc + pIe->offset + sizeof(tDot11fIEPropSuppRates) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeR0KH_ID: + status |= dot11fPackIeR0KH_ID(pCtx, ( tDot11fIER0KH_ID* )(pSrc + pIe->offset + sizeof(tDot11fIER0KH_ID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeR1KH_ID: + status |= dot11fPackIeR1KH_ID(pCtx, ( tDot11fIER1KH_ID* )(pSrc + pIe->offset + sizeof(tDot11fIER1KH_ID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTSFInfo: + status |= dot11fPackIeTSFInfo(pCtx, ( tDot11fIETSFInfo* )(pSrc + pIe->offset + sizeof(tDot11fIETSFInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTaurus: + status |= dot11fPackIeTaurus(pCtx, ( tDot11fIETaurus* )(pSrc + pIe->offset + sizeof(tDot11fIETaurus) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTitan: + status |= dot11fPackIeTitan(pCtx, ( tDot11fIETitan* )(pSrc + pIe->offset + sizeof(tDot11fIETitan) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTriggerStaBgScan: + status |= dot11fPackIeTriggerStaBgScan(pCtx, ( tDot11fIETriggerStaBgScan* )(pSrc + pIe->offset + sizeof(tDot11fIETriggerStaBgScan) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVersion: + status |= dot11fPackIeVersion(pCtx, ( tDot11fIEVersion* )(pSrc + pIe->offset + sizeof(tDot11fIEVersion) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWDS: + status |= dot11fPackIeWDS(pCtx, ( tDot11fIEWDS* )(pSrc + pIe->offset + sizeof(tDot11fIEWDS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeAPChannelReport: + status |= dot11fPackIeAPChannelReport(pCtx, ( tDot11fIEAPChannelReport* )(pSrc + pIe->offset + sizeof(tDot11fIEAPChannelReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBcnReportingDetail: + status |= dot11fPackIeBcnReportingDetail(pCtx, ( tDot11fIEBcnReportingDetail* )(pSrc + pIe->offset + sizeof(tDot11fIEBcnReportingDetail) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBeaconReportFrmBody: + status |= dot11fPackIeBeaconReportFrmBody(pCtx, ( tDot11fIEBeaconReportFrmBody* )(pSrc + pIe->offset + sizeof(tDot11fIEBeaconReportFrmBody) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeBeaconReporting: + status |= dot11fPackIeBeaconReporting(pCtx, ( tDot11fIEBeaconReporting* )(pSrc + pIe->offset + sizeof(tDot11fIEBeaconReporting) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMeasurementPilot: + status |= dot11fPackIeMeasurementPilot(pCtx, ( tDot11fIEMeasurementPilot* )(pSrc + pIe->offset + sizeof(tDot11fIEMeasurementPilot) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMultiBssid: + status |= dot11fPackIeMultiBssid(pCtx, ( tDot11fIEMultiBssid* )(pSrc + pIe->offset + sizeof(tDot11fIEMultiBssid) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRICData: + status |= dot11fPackIeRICData(pCtx, ( tDot11fIERICData* )(pSrc + pIe->offset + sizeof(tDot11fIERICData) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRICDescriptor: + status |= dot11fPackIeRICDescriptor(pCtx, ( tDot11fIERICDescriptor* )(pSrc + pIe->offset + sizeof(tDot11fIERICDescriptor) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRRMEnabledCap: + status |= dot11fPackIeRRMEnabledCap(pCtx, ( tDot11fIERRMEnabledCap* )(pSrc + pIe->offset + sizeof(tDot11fIERRMEnabledCap) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRequestedInfo: + status |= dot11fPackIeRequestedInfo(pCtx, ( tDot11fIERequestedInfo* )(pSrc + pIe->offset + sizeof(tDot11fIERequestedInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSSID: + status |= dot11fPackIeSSID(pCtx, ( tDot11fIESSID* )(pSrc + pIe->offset + sizeof(tDot11fIESSID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSchedule: + status |= dot11fPackIeSchedule(pCtx, ( tDot11fIESchedule* )(pSrc + pIe->offset + sizeof(tDot11fIESchedule) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTCLAS: + status |= dot11fPackIeTCLAS(pCtx, ( tDot11fIETCLAS* )(pSrc + pIe->offset + sizeof(tDot11fIETCLAS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTCLASSPROC: + status |= dot11fPackIeTCLASSPROC(pCtx, ( tDot11fIETCLASSPROC* )(pSrc + pIe->offset + sizeof(tDot11fIETCLASSPROC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTSDelay: + status |= dot11fPackIeTSDelay(pCtx, ( tDot11fIETSDelay* )(pSrc + pIe->offset + sizeof(tDot11fIETSDelay) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTSPEC: + status |= dot11fPackIeTSPEC(pCtx, ( tDot11fIETSPEC* )(pSrc + pIe->offset + sizeof(tDot11fIETSPEC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMSchedule: + status |= dot11fPackIeWMMSchedule(pCtx, ( tDot11fIEWMMSchedule* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMSchedule) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTCLAS: + status |= dot11fPackIeWMMTCLAS(pCtx, ( tDot11fIEWMMTCLAS* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTCLAS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTCLASPROC: + status |= dot11fPackIeWMMTCLASPROC(pCtx, ( tDot11fIEWMMTCLASPROC* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTCLASPROC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTSDelay: + status |= dot11fPackIeWMMTSDelay(pCtx, ( tDot11fIEWMMTSDelay* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTSDelay) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMTSPEC: + status |= dot11fPackIeWMMTSPEC(pCtx, ( tDot11fIEWMMTSPEC* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMTSPEC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeAID: + status |= dot11fPackIeAID(pCtx, ( tDot11fIEAID* )(pSrc + pIe->offset + sizeof(tDot11fIEAID) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeAirgo: + status |= dot11fPackIeAirgo(pCtx, ( tDot11fIEAirgo* )(pSrc + pIe->offset + sizeof(tDot11fIEAirgo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeCFParams: + status |= dot11fPackIeCFParams(pCtx, ( tDot11fIECFParams* )(pSrc + pIe->offset + sizeof(tDot11fIECFParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeChallengeText: + status |= dot11fPackIeChallengeText(pCtx, ( tDot11fIEChallengeText* )(pSrc + pIe->offset + sizeof(tDot11fIEChallengeText) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeChanSwitchAnn: + status |= dot11fPackIeChanSwitchAnn(pCtx, ( tDot11fIEChanSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEChanSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeCountry: + status |= dot11fPackIeCountry(pCtx, ( tDot11fIECountry* )(pSrc + pIe->offset + sizeof(tDot11fIECountry) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeDSParams: + status |= dot11fPackIeDSParams(pCtx, ( tDot11fIEDSParams* )(pSrc + pIe->offset + sizeof(tDot11fIEDSParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeEDCAParamSet: + status |= dot11fPackIeEDCAParamSet(pCtx, ( tDot11fIEEDCAParamSet* )(pSrc + pIe->offset + sizeof(tDot11fIEEDCAParamSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeERPInfo: + status |= dot11fPackIeERPInfo(pCtx, ( tDot11fIEERPInfo* )(pSrc + pIe->offset + sizeof(tDot11fIEERPInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESECckmOpaque: + status |= dot11fPackIeESECckmOpaque(pCtx, ( tDot11fIEESECckmOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEESECckmOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESERadMgmtCap: + status |= dot11fPackIeESERadMgmtCap(pCtx, ( tDot11fIEESERadMgmtCap* )(pSrc + pIe->offset + sizeof(tDot11fIEESERadMgmtCap) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESETrafStrmMet: + status |= dot11fPackIeESETrafStrmMet(pCtx, ( tDot11fIEESETrafStrmMet* )(pSrc + pIe->offset + sizeof(tDot11fIEESETrafStrmMet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESETrafStrmRateSet: + status |= dot11fPackIeESETrafStrmRateSet(pCtx, ( tDot11fIEESETrafStrmRateSet* )(pSrc + pIe->offset + sizeof(tDot11fIEESETrafStrmRateSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESETxmitPower: + status |= dot11fPackIeESETxmitPower(pCtx, ( tDot11fIEESETxmitPower* )(pSrc + pIe->offset + sizeof(tDot11fIEESETxmitPower) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeESEVersion: + status |= dot11fPackIeESEVersion(pCtx, ( tDot11fIEESEVersion* )(pSrc + pIe->offset + sizeof(tDot11fIEESEVersion) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeExtCap: + status |= dot11fPackIeExtCap(pCtx, ( tDot11fIEExtCap* )(pSrc + pIe->offset + sizeof(tDot11fIEExtCap) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeExtChanSwitchAnn: + status |= dot11fPackIeExtChanSwitchAnn(pCtx, ( tDot11fIEExtChanSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEExtChanSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeExtSuppRates: + status |= dot11fPackIeExtSuppRates(pCtx, ( tDot11fIEExtSuppRates* )(pSrc + pIe->offset + sizeof(tDot11fIEExtSuppRates) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFHParamSet: + status |= dot11fPackIeFHParamSet(pCtx, ( tDot11fIEFHParamSet* )(pSrc + pIe->offset + sizeof(tDot11fIEFHParamSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFHParams: + status |= dot11fPackIeFHParams(pCtx, ( tDot11fIEFHParams* )(pSrc + pIe->offset + sizeof(tDot11fIEFHParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFHPattTable: + status |= dot11fPackIeFHPattTable(pCtx, ( tDot11fIEFHPattTable* )(pSrc + pIe->offset + sizeof(tDot11fIEFHPattTable) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeFTInfo: + status |= dot11fPackIeFTInfo(pCtx, ( tDot11fIEFTInfo* )(pSrc + pIe->offset + sizeof(tDot11fIEFTInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHT2040BSSCoexistence: + status |= dot11fPackIeHT2040BSSCoexistence(pCtx, ( tDot11fIEHT2040BSSCoexistence* )(pSrc + pIe->offset + sizeof(tDot11fIEHT2040BSSCoexistence) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHT2040BSSIntolerantReport: + status |= dot11fPackIeHT2040BSSIntolerantReport(pCtx, ( tDot11fIEHT2040BSSIntolerantReport* )(pSrc + pIe->offset + sizeof(tDot11fIEHT2040BSSIntolerantReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHTCaps: + status |= dot11fPackIeHTCaps(pCtx, ( tDot11fIEHTCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEHTCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeHTInfo: + status |= dot11fPackIeHTInfo(pCtx, ( tDot11fIEHTInfo* )(pSrc + pIe->offset + sizeof(tDot11fIEHTInfo) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeIBSSParams: + status |= dot11fPackIeIBSSParams(pCtx, ( tDot11fIEIBSSParams* )(pSrc + pIe->offset + sizeof(tDot11fIEIBSSParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeLinkIdentifier: + status |= dot11fPackIeLinkIdentifier(pCtx, ( tDot11fIELinkIdentifier* )(pSrc + pIe->offset + sizeof(tDot11fIELinkIdentifier) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMeasurementReport: + status |= dot11fPackIeMeasurementReport(pCtx, ( tDot11fIEMeasurementReport* )(pSrc + pIe->offset + sizeof(tDot11fIEMeasurementReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMeasurementRequest: + status |= dot11fPackIeMeasurementRequest(pCtx, ( tDot11fIEMeasurementRequest* )(pSrc + pIe->offset + sizeof(tDot11fIEMeasurementRequest) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeMobilityDomain: + status |= dot11fPackIeMobilityDomain(pCtx, ( tDot11fIEMobilityDomain* )(pSrc + pIe->offset + sizeof(tDot11fIEMobilityDomain) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeNeighborReport: + status |= dot11fPackIeNeighborReport(pCtx, ( tDot11fIENeighborReport* )(pSrc + pIe->offset + sizeof(tDot11fIENeighborReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeOBSSScanParameters: + status |= dot11fPackIeOBSSScanParameters(pCtx, ( tDot11fIEOBSSScanParameters* )(pSrc + pIe->offset + sizeof(tDot11fIEOBSSScanParameters) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeOperatingMode: + status |= dot11fPackIeOperatingMode(pCtx, ( tDot11fIEOperatingMode* )(pSrc + pIe->offset + sizeof(tDot11fIEOperatingMode) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PAssocReq: + status |= dot11fPackIeP2PAssocReq(pCtx, ( tDot11fIEP2PAssocReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PAssocReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PAssocRes: + status |= dot11fPackIeP2PAssocRes(pCtx, ( tDot11fIEP2PAssocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PAssocRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PBeacon: + status |= dot11fPackIeP2PBeacon(pCtx, ( tDot11fIEP2PBeacon* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PBeacon) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PBeaconProbeRes: + status |= dot11fPackIeP2PBeaconProbeRes(pCtx, ( tDot11fIEP2PBeaconProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PBeaconProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDeAuth: + status |= dot11fPackIeP2PDeAuth(pCtx, ( tDot11fIEP2PDeAuth* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDeAuth) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDeviceDiscoverabilityReq: + status |= dot11fPackIeP2PDeviceDiscoverabilityReq(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDeviceDiscoverabilityRes: + status |= dot11fPackIeP2PDeviceDiscoverabilityRes(pCtx, ( tDot11fIEP2PDeviceDiscoverabilityRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDeviceDiscoverabilityRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PDisAssoc: + status |= dot11fPackIeP2PDisAssoc(pCtx, ( tDot11fIEP2PDisAssoc* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PDisAssoc) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegCnf: + status |= dot11fPackIeP2PGONegCnf(pCtx, ( tDot11fIEP2PGONegCnf* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegCnf) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegReq: + status |= dot11fPackIeP2PGONegReq(pCtx, ( tDot11fIEP2PGONegReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegRes: + status |= dot11fPackIeP2PGONegRes(pCtx, ( tDot11fIEP2PGONegRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PGONegWPS: + status |= dot11fPackIeP2PGONegWPS(pCtx, ( tDot11fIEP2PGONegWPS* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PGONegWPS) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PIEOpaque: + status |= dot11fPackIeP2PIEOpaque(pCtx, ( tDot11fIEP2PIEOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PIEOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PInvitationReq: + status |= dot11fPackIeP2PInvitationReq(pCtx, ( tDot11fIEP2PInvitationReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PInvitationReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PInvitationRes: + status |= dot11fPackIeP2PInvitationRes(pCtx, ( tDot11fIEP2PInvitationRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PInvitationRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PNoticeOfAbsence: + status |= dot11fPackIeP2PNoticeOfAbsence(pCtx, ( tDot11fIEP2PNoticeOfAbsence* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PNoticeOfAbsence) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PPresenceResponse: + status |= dot11fPackIeP2PPresenceResponse(pCtx, ( tDot11fIEP2PPresenceResponse* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PPresenceResponse) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PProbeReq: + status |= dot11fPackIeP2PProbeReq(pCtx, ( tDot11fIEP2PProbeReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PProbeReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PProbeRes: + status |= dot11fPackIeP2PProbeRes(pCtx, ( tDot11fIEP2PProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PProvisionDiscoveryReq: + status |= dot11fPackIeP2PProvisionDiscoveryReq(pCtx, ( tDot11fIEP2PProvisionDiscoveryReq* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PProvisionDiscoveryReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeP2PWSCProvisionDiscoveryRes: + status |= dot11fPackIeP2PWSCProvisionDiscoveryRes(pCtx, ( tDot11fIEP2PWSCProvisionDiscoveryRes* )(pSrc + pIe->offset + sizeof(tDot11fIEP2PWSCProvisionDiscoveryRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePTIControl: + status |= dot11fPackIePTIControl(pCtx, ( tDot11fIEPTIControl* )(pSrc + pIe->offset + sizeof(tDot11fIEPTIControl) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePUBufferStatus: + status |= dot11fPackIePUBufferStatus(pCtx, ( tDot11fIEPUBufferStatus* )(pSrc + pIe->offset + sizeof(tDot11fIEPUBufferStatus) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePowerCaps: + status |= dot11fPackIePowerCaps(pCtx, ( tDot11fIEPowerCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEPowerCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIePowerConstraints: + status |= dot11fPackIePowerConstraints(pCtx, ( tDot11fIEPowerConstraints* )(pSrc + pIe->offset + sizeof(tDot11fIEPowerConstraints) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQBSSLoad: + status |= dot11fPackIeQBSSLoad(pCtx, ( tDot11fIEQBSSLoad* )(pSrc + pIe->offset + sizeof(tDot11fIEQBSSLoad) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQOSCapsAp: + status |= dot11fPackIeQOSCapsAp(pCtx, ( tDot11fIEQOSCapsAp* )(pSrc + pIe->offset + sizeof(tDot11fIEQOSCapsAp) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQOSCapsStation: + status |= dot11fPackIeQOSCapsStation(pCtx, ( tDot11fIEQOSCapsStation* )(pSrc + pIe->offset + sizeof(tDot11fIEQOSCapsStation) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQosMapSet: + status |= dot11fPackIeQosMapSet(pCtx, ( tDot11fIEQosMapSet* )(pSrc + pIe->offset + sizeof(tDot11fIEQosMapSet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeQuiet: + status |= dot11fPackIeQuiet(pCtx, ( tDot11fIEQuiet* )(pSrc + pIe->offset + sizeof(tDot11fIEQuiet) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRCPIIE: + status |= dot11fPackIeRCPIIE(pCtx, ( tDot11fIERCPIIE* )(pSrc + pIe->offset + sizeof(tDot11fIERCPIIE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRICDataDesc: + status |= dot11fPackIeRICDataDesc(pCtx, ( tDot11fIERICDataDesc* )(pSrc + pIe->offset + sizeof(tDot11fIERICDataDesc) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRSN: + status |= dot11fPackIeRSN(pCtx, ( tDot11fIERSN* )(pSrc + pIe->offset + sizeof(tDot11fIERSN) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRSNIIE: + status |= dot11fPackIeRSNIIE(pCtx, ( tDot11fIERSNIIE* )(pSrc + pIe->offset + sizeof(tDot11fIERSNIIE) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeRSNOpaque: + status |= dot11fPackIeRSNOpaque(pCtx, ( tDot11fIERSNOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIERSNOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSuppChannels: + status |= dot11fPackIeSuppChannels(pCtx, ( tDot11fIESuppChannels* )(pSrc + pIe->offset + sizeof(tDot11fIESuppChannels) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSuppOperatingClasses: + status |= dot11fPackIeSuppOperatingClasses(pCtx, ( tDot11fIESuppOperatingClasses* )(pSrc + pIe->offset + sizeof(tDot11fIESuppOperatingClasses) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeSuppRates: + status |= dot11fPackIeSuppRates(pCtx, ( tDot11fIESuppRates* )(pSrc + pIe->offset + sizeof(tDot11fIESuppRates) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTIM: + status |= dot11fPackIeTIM(pCtx, ( tDot11fIETIM* )(pSrc + pIe->offset + sizeof(tDot11fIETIM) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTPCReport: + status |= dot11fPackIeTPCReport(pCtx, ( tDot11fIETPCReport* )(pSrc + pIe->offset + sizeof(tDot11fIETPCReport) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTPCRequest: + status |= dot11fPackIeTPCRequest(pCtx, ( tDot11fIETPCRequest* )(pSrc + pIe->offset + sizeof(tDot11fIETPCRequest) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeTimeoutInterval: + status |= dot11fPackIeTimeoutInterval(pCtx, ( tDot11fIETimeoutInterval* )(pSrc + pIe->offset + sizeof(tDot11fIETimeoutInterval) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVHTCaps: + status |= dot11fPackIeVHTCaps(pCtx, ( tDot11fIEVHTCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEVHTCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVHTExtBssLoad: + status |= dot11fPackIeVHTExtBssLoad(pCtx, ( tDot11fIEVHTExtBssLoad* )(pSrc + pIe->offset + sizeof(tDot11fIEVHTExtBssLoad) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeVHTOperation: + status |= dot11fPackIeVHTOperation(pCtx, ( tDot11fIEVHTOperation* )(pSrc + pIe->offset + sizeof(tDot11fIEVHTOperation) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWAPI: + status |= dot11fPackIeWAPI(pCtx, ( tDot11fIEWAPI* )(pSrc + pIe->offset + sizeof(tDot11fIEWAPI) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWAPIOpaque: + status |= dot11fPackIeWAPIOpaque(pCtx, ( tDot11fIEWAPIOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWAPIOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWFATPC: + status |= dot11fPackIeWFATPC(pCtx, ( tDot11fIEWFATPC* )(pSrc + pIe->offset + sizeof(tDot11fIEWFATPC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWFDIEOpaque: + status |= dot11fPackIeWFDIEOpaque(pCtx, ( tDot11fIEWFDIEOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWFDIEOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMCaps: + status |= dot11fPackIeWMMCaps(pCtx, ( tDot11fIEWMMCaps* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMCaps) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMInfoAp: + status |= dot11fPackIeWMMInfoAp(pCtx, ( tDot11fIEWMMInfoAp* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMInfoAp) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMInfoStation: + status |= dot11fPackIeWMMInfoStation(pCtx, ( tDot11fIEWMMInfoStation* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMInfoStation) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWMMParams: + status |= dot11fPackIeWMMParams(pCtx, ( tDot11fIEWMMParams* )(pSrc + pIe->offset + sizeof(tDot11fIEWMMParams) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWPA: + status |= dot11fPackIeWPA(pCtx, ( tDot11fIEWPA* )(pSrc + pIe->offset + sizeof(tDot11fIEWPA) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWPAOpaque: + status |= dot11fPackIeWPAOpaque(pCtx, ( tDot11fIEWPAOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWPAOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWSC: + status |= dot11fPackIeWSC(pCtx, ( tDot11fIEWSC* )(pSrc + pIe->offset + sizeof(tDot11fIEWSC) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWiderBWChanSwitchAnn: + status |= dot11fPackIeWiderBWChanSwitchAnn(pCtx, ( tDot11fIEWiderBWChanSwitchAnn* )(pSrc + pIe->offset + sizeof(tDot11fIEWiderBWChanSwitchAnn) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscAssocReq: + status |= dot11fPackIeWscAssocReq(pCtx, ( tDot11fIEWscAssocReq* )(pSrc + pIe->offset + sizeof(tDot11fIEWscAssocReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscAssocRes: + status |= dot11fPackIeWscAssocRes(pCtx, ( tDot11fIEWscAssocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscAssocRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscBeacon: + status |= dot11fPackIeWscBeacon(pCtx, ( tDot11fIEWscBeacon* )(pSrc + pIe->offset + sizeof(tDot11fIEWscBeacon) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscBeaconProbeRes: + status |= dot11fPackIeWscBeaconProbeRes(pCtx, ( tDot11fIEWscBeaconProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscBeaconProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscIEOpaque: + status |= dot11fPackIeWscIEOpaque(pCtx, ( tDot11fIEWscIEOpaque* )(pSrc + pIe->offset + sizeof(tDot11fIEWscIEOpaque) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscProbeReq: + status |= dot11fPackIeWscProbeReq(pCtx, ( tDot11fIEWscProbeReq* )(pSrc + pIe->offset + sizeof(tDot11fIEWscProbeReq) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscProbeRes: + status |= dot11fPackIeWscProbeRes(pCtx, ( tDot11fIEWscProbeRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscProbeRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIeWscReassocRes: + status |= dot11fPackIeWscReassocRes(pCtx, ( tDot11fIEWscReassocRes* )(pSrc + pIe->offset + sizeof(tDot11fIEWscReassocRes) * i ), pBufRemaining, nBufRemaining, &len); + break; + case SigIehs20vendor_ie: + status |= dot11fPackIehs20vendor_ie(pCtx, ( tDot11fIEhs20vendor_ie* )(pSrc + pIe->offset + sizeof(tDot11fIEhs20vendor_ie) * i ), pBufRemaining, nBufRemaining, &len); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don" + "'t know about the IE %d; this is most likely a b" + "ug in 'framesc'.\n"), pFf->sig); + return DOT11F_INTERNAL_ERROR; + } + + pBufRemaining += len; + nBufRemaining -= len; + *pnConsumed += len; + } + + ++pIe; + + } + + return status; + +} + +static tANI_U32 PackTlvCore(tpAniSirGlobal pCtx, + tANI_U8 *pSrc, + tANI_U8 *pBuf, + tANI_U32 nBuf, + tANI_U32 *pnConsumed, + const tTLVDefn TLVs[], + tANI_U32 *pidx) +{ + const tTLVDefn *pTlv; + tFRAMES_BOOL *pfFound; + tANI_U8 *pBufRemaining; + tANI_U32 nBufRemaining, status, len; + + DOT11F_PARAMETER_CHECK2(pSrc, pBuf, nBuf, pnConsumed); + + (void)pCtx; + status = DOT11F_PARSE_SUCCESS; + pBufRemaining = pBuf; + nBufRemaining = nBuf; + + pTlv = &( TLVs[0] ); + while ( 0xffff != pTlv->id ) + { + pfFound = (tFRAMES_BOOL*)(pSrc + pTlv->offset + + pTlv->presenceOffset); + if ( *pfFound && pTlv->minSize > nBufRemaining ) + { + FRAMES_LOG3(pCtx, FRLOGE, FRFL("The TLV %s takes at least" + " %d bytes, but there are only %d left in the buffer." + "\n"), pTlv->name, pTlv->minSize, nBufRemaining); + return DOT11F_BUFFER_OVERFLOW; + } + + len = 0U; + + if ( *pfFound ) { + switch ( pTlv->sig ) + { + case SigTlvAuthorizedMACs: + status |= dot11fPackTlvAuthorizedMACs(pCtx, ( tDot11fTLVAuthorizedMACs* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRequestToEnroll: + status |= dot11fPackTlvRequestToEnroll(pCtx, ( tDot11fTLVRequestToEnroll* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvVersion2: + status |= dot11fPackTlvVersion2(pCtx, ( tDot11fTLVVersion2* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvAPSetupLocked: + status |= dot11fPackTlvAPSetupLocked(pCtx, ( tDot11fTLVAPSetupLocked* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvAssociationState: + status |= dot11fPackTlvAssociationState(pCtx, ( tDot11fTLVAssociationState* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvChannelList: + status |= dot11fPackTlvChannelList(pCtx, ( tDot11fTLVChannelList* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvConfigMethods: + status |= dot11fPackTlvConfigMethods(pCtx, ( tDot11fTLVConfigMethods* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvConfigurationError: + status |= dot11fPackTlvConfigurationError(pCtx, ( tDot11fTLVConfigurationError* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvConfigurationTimeout: + status |= dot11fPackTlvConfigurationTimeout(pCtx, ( tDot11fTLVConfigurationTimeout* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvDeviceName: + status |= dot11fPackTlvDeviceName(pCtx, ( tDot11fTLVDeviceName* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvDevicePasswordID: + status |= dot11fPackTlvDevicePasswordID(pCtx, ( tDot11fTLVDevicePasswordID* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvExtendedListenTiming: + status |= dot11fPackTlvExtendedListenTiming(pCtx, ( tDot11fTLVExtendedListenTiming* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvGOIntent: + status |= dot11fPackTlvGOIntent(pCtx, ( tDot11fTLVGOIntent* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvIntendedP2PInterfaceAddress: + status |= dot11fPackTlvIntendedP2PInterfaceAddress(pCtx, ( tDot11fTLVIntendedP2PInterfaceAddress* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvInvitationFlags: + status |= dot11fPackTlvInvitationFlags(pCtx, ( tDot11fTLVInvitationFlags* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvListenChannel: + status |= dot11fPackTlvListenChannel(pCtx, ( tDot11fTLVListenChannel* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvManufacturer: + status |= dot11fPackTlvManufacturer(pCtx, ( tDot11fTLVManufacturer* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvMinorReasonCode: + status |= dot11fPackTlvMinorReasonCode(pCtx, ( tDot11fTLVMinorReasonCode* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvModelName: + status |= dot11fPackTlvModelName(pCtx, ( tDot11fTLVModelName* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvModelNumber: + status |= dot11fPackTlvModelNumber(pCtx, ( tDot11fTLVModelNumber* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvNoticeOfAbsence: + status |= dot11fPackTlvNoticeOfAbsence(pCtx, ( tDot11fTLVNoticeOfAbsence* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvOperatingChannel: + status |= dot11fPackTlvOperatingChannel(pCtx, ( tDot11fTLVOperatingChannel* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PCapability: + status |= dot11fPackTlvP2PCapability(pCtx, ( tDot11fTLVP2PCapability* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PDeviceId: + status |= dot11fPackTlvP2PDeviceId(pCtx, ( tDot11fTLVP2PDeviceId* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PDeviceInfo: + status |= dot11fPackTlvP2PDeviceInfo(pCtx, ( tDot11fTLVP2PDeviceInfo* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PGroupBssid: + status |= dot11fPackTlvP2PGroupBssid(pCtx, ( tDot11fTLVP2PGroupBssid* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PGroupId: + status |= dot11fPackTlvP2PGroupId(pCtx, ( tDot11fTLVP2PGroupId* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PGroupInfo: + status |= dot11fPackTlvP2PGroupInfo(pCtx, ( tDot11fTLVP2PGroupInfo* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PStatus: + status |= dot11fPackTlvP2PStatus(pCtx, ( tDot11fTLVP2PStatus* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvPrimaryDeviceType: + status |= dot11fPackTlvPrimaryDeviceType(pCtx, ( tDot11fTLVPrimaryDeviceType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRFBands: + status |= dot11fPackTlvRFBands(pCtx, ( tDot11fTLVRFBands* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRequestDeviceType: + status |= dot11fPackTlvRequestDeviceType(pCtx, ( tDot11fTLVRequestDeviceType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvRequestType: + status |= dot11fPackTlvRequestType(pCtx, ( tDot11fTLVRequestType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvResponseType: + status |= dot11fPackTlvResponseType(pCtx, ( tDot11fTLVResponseType* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvSelectedRegistrar: + status |= dot11fPackTlvSelectedRegistrar(pCtx, ( tDot11fTLVSelectedRegistrar* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvSelectedRegistrarConfigMethods: + status |= dot11fPackTlvSelectedRegistrarConfigMethods(pCtx, ( tDot11fTLVSelectedRegistrarConfigMethods* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvSerialNumber: + status |= dot11fPackTlvSerialNumber(pCtx, ( tDot11fTLVSerialNumber* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvUUID_E: + status |= dot11fPackTlvUUID_E(pCtx, ( tDot11fTLVUUID_E* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvUUID_R: + status |= dot11fPackTlvUUID_R(pCtx, ( tDot11fTLVUUID_R* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvVendorExtension: + status |= dot11fPackTlvVendorExtension(pCtx, ( tDot11fTLVVendorExtension* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvVersion: + status |= dot11fPackTlvVersion(pCtx, ( tDot11fTLVVersion* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvWPSState: + status |= dot11fPackTlvWPSState(pCtx, ( tDot11fTLVWPSState* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PInterface: + status |= dot11fPackTlvP2PInterface(pCtx, ( tDot11fTLVP2PInterface* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + case SigTlvP2PManageability: + status |= dot11fPackTlvP2PManageability(pCtx, ( tDot11fTLVP2PManageability* )(pSrc + pTlv->offset), pBufRemaining, nBufRemaining, &len); + break; + default: + FRAMES_LOG1(pCtx, FRLOGE, FRFL("INTERNAL ERROR-- I don't " + "know about the TLV %d; this is most likely a bug in " + "'framesc'.\n"), pTlv->sig); + return DOT11F_INTERNAL_ERROR; + } + + } /* End if on *pfFound */ + pBufRemaining += len; + nBufRemaining -= len; + *pnConsumed += len; + ++pTlv; + if(len) ++*pidx; + } + + return status; + +} diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logApi.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logApi.c new file mode 100644 index 000000000000..04bae6cef9a4 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logApi.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * logApi.cc - Handles log messages for all the modules. + * Author: Kevin Nguyen + * Date: 02/27/02 + * History:- + * 02/11/02 Created. + * 03/12/02 Rearrange logDebug parameter list and add more params. + * -------------------------------------------------------------------- + * + */ + +#include +#include +#include +#include + +#include +#include "utilsGlobal.h" +#include "macInitApi.h" +#include "palApi.h" + +#include "vos_trace.h" + +#ifdef ANI_OS_TYPE_ANDROID +#include +#endif + + +// --------------------------------------------------------------------- +/** + * logInit() + * + * FUNCTION: + * This function is called to prepare the logging utility. + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param tpAniSirGlobal Sirius software parameter strucutre pointer + * @return None + */ +tSirRetStatus +logInit(tpAniSirGlobal pMac) +{ + tANI_U32 i; + + // Add code to initialize debug level from CFG module + // For now, enable all logging + for (i = 0; i < LOG_ENTRY_NUM; i++) + { +#ifdef SIR_DEBUG + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = LOG1; +#else + pMac->utils.gLogEvtLevel[i] = pMac->utils.gLogDbgLevel[i] = LOGW; +#endif + } + return eSIR_SUCCESS; + +} /*** logInit() ***/ + +void +logDeinit(tpAniSirGlobal pMac) +{ + return; +} + +/** + * logDbg() + * + *FUNCTION: + * This function is called to log a debug message. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * None. + * + *NOTE: + * + * @param tpAniSirGlobal Sirius software parameter strucutre pointer + * @param ModId 8-bit modID + * @param debugLevel debugging level for this message + * @param pStr string parameter pointer + * @return None + */ + + +void logDbg(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr,...) +{ +#ifdef WLAN_DEBUG + if ( debugLevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( modId )] ) + return; + else + { + va_list marker; + + va_start( marker, pStr ); /* Initialize variable arguments. */ + + logDebug(pMac, modId, debugLevel, pStr, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} + +VOS_TRACE_LEVEL getVosDebugLevel(tANI_U32 debugLevel) +{ + switch(debugLevel) + { + case LOGP: + return VOS_TRACE_LEVEL_FATAL; + case LOGE: + return VOS_TRACE_LEVEL_ERROR; + case LOGW: + return VOS_TRACE_LEVEL_WARN; + case LOG1: + return VOS_TRACE_LEVEL_INFO; + case LOG2: + return VOS_TRACE_LEVEL_INFO_HIGH; + case LOG3: + return VOS_TRACE_LEVEL_INFO_MED; + case LOG4: + return VOS_TRACE_LEVEL_INFO_LOW; + default: + return VOS_TRACE_LEVEL_INFO_LOW; + } +} + +static inline VOS_MODULE_ID getVosModuleId(tANI_U8 modId) +{ + switch(modId) + { + case SIR_HAL_MODULE_ID: + case SIR_HAL_EXT_MODULE_ID: + case SIR_PHY_MODULE_ID: + return VOS_MODULE_ID_WDA; + case SIR_PMM_MODULE_ID: + return VOS_MODULE_ID_PMC; + + case SIR_LIM_MODULE_ID: + case SIR_SCH_MODULE_ID: + case SIR_CFG_MODULE_ID: + case SIR_MNT_MODULE_ID: + case SIR_DPH_MODULE_ID: + case SIR_DBG_MODULE_ID: + return VOS_MODULE_ID_PE; + + case SIR_SYS_MODULE_ID: + return VOS_MODULE_ID_SYS; + + case SIR_SMS_MODULE_ID: + return VOS_MODULE_ID_SME; + + default: + return VOS_MODULE_ID_SYS; + } +} + +#define LOG_SIZE 256 +void logDebug(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 debugLevel, const char *pStr, va_list marker) +{ + VOS_TRACE_LEVEL vosDebugLevel; + VOS_MODULE_ID vosModuleId; + char logBuffer[LOG_SIZE]; + + vosDebugLevel = getVosDebugLevel(debugLevel); + vosModuleId = getVosModuleId(modId); + + vsnprintf(logBuffer, LOG_SIZE - 1, pStr, marker); + VOS_TRACE(vosModuleId, vosDebugLevel, "%s", logBuffer); + + // The caller must check loglevel + VOS_ASSERT( ( debugLevel <= pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( modId )] ) && ( LOGP != debugLevel ) ); +} /*** end logDebug() ***/ diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logDump.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logDump.c new file mode 100644 index 000000000000..3e6b1f98060c --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/logDump.c @@ -0,0 +1,454 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + +logDump.c +*/ + +/* + * This file contains the utility functions to dump various + * MAC states and to enable/disable certain features during + * debugging. + * Author: Sandesh Goel + * Date: 02/27/02 + * History:- + * 02/11/02 Created. + * -------------------------------------------------------------------- + * + */ + +/* + * @note : Bytes is to print overflow message information. + */ + +#include "palTypes.h" + +#ifdef ANI_LOGDUMP + +#define MAX_OVERFLOW_MSG 400 +#define MAX_LOGDUMP_SIZE ((4*1024) - MAX_OVERFLOW_MSG) + +#if defined(ANI_OS_TYPE_ANDROID) + +#include + +#endif + + +#include "palApi.h" +#include "aniGlobal.h" +#include "sirCommon.h" +#include +#include + +#include +#include +#include +#include +#include +#include "limUtils.h" +#include "schApi.h" + +#include "pmmApi.h" +#include "limSerDesUtils.h" +#include "limAssocUtils.h" +#include "limSendMessages.h" +#include "limSecurityUtils.h" +//#include "halRadar.h" +#include "logDump.h" +#include "sysDebug.h" +#include "wlan_qct_wda.h" + +#define HAL_LOG_DUMP_CMD_START 0 + +/* Dump command id for Host modules starts from 300 onwards, + * hence do not extend the HAL commands beyond 300. + */ +#define HAL_LOG_DUMP_CMD_END 299 + +static int debug; + + void +logPrintf(tpAniSirGlobal pMac, tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4) +{ + static tANI_U8 buf[MAX_LOGDUMP_SIZE + MAX_OVERFLOW_MSG]; + tANI_U16 bufLen; + pMac->gCurrentLogSize = 0; + + bufLen = (tANI_U16)logRtaiDump(pMac, cmd, arg1, arg2, arg3, arg4, buf); +} + +/** + @brief: This function is used to Aggregate the formated buffer, this + also check the overflow condition and adds the overflow message + to the end of the log Dump buffer reserved of MAX_OVERFLOW_MSG size. + @param: tpAniSirGlobal pMac + @param: char *pBuf + @param: variable arguments... + @return: Returns the number of bytes added to the buffer. + Returns 0 incase of overflow. + + @note: Currently in windows we do not print the Aggregated buffer as there + is a limitation on the number of bytes that can be displayed by DbgPrint + So we print the buffer immediately and we would also aggregate where + the TestDbg might use this buffer to print out at the application level. + */ +int log_sprintf(tpAniSirGlobal pMac, char *pBuf, char *fmt, ...) +{ + tANI_S32 ret = 0; +#ifdef WLAN_DEBUG + + va_list args; + va_start(args, fmt); + + if (pMac->gCurrentLogSize >= MAX_LOGDUMP_SIZE) + return 0; + +#if defined (ANI_OS_TYPE_ANDROID) + ret = vsnprintf(pBuf, (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize), fmt, args); +#endif + + va_end(args); + + /* If an output error is encountered, a negative value is returned by vsnprintf */ + if (ret < 0) + return 0; + + + if ((tANI_U32) ret > (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize)) { + pBuf += (MAX_LOGDUMP_SIZE - pMac->gCurrentLogSize); + pMac->gCurrentLogSize = MAX_LOGDUMP_SIZE; + +#if defined (ANI_OS_TYPE_ANDROID) + ret = snprintf(pBuf, MAX_OVERFLOW_MSG, "\n-> ***********" + "\nOutput Exceeded the Buffer Size, message truncated!!\n<- ***********\n"); +#endif + /* If an output error is encountered, a negative value is returned by snprintf */ + if (ret < 0) + return 0; + + if (ret > MAX_OVERFLOW_MSG) + ret = MAX_OVERFLOW_MSG; + } + + pMac->gCurrentLogSize += ret; + + +#endif //for #ifdef WLAN_DEBUG + return ret; +} + + +char* dumpLOG( tpAniSirGlobal pMac, char *p ) +{ + tANI_U32 i; + + for( i = SIR_FIRST_MODULE_ID; i <= SIR_LAST_MODULE_ID; i++ ) { + p += log_sprintf(pMac, p, "[0x%2x]", i); + switch (i) + { + case SIR_HAL_MODULE_ID: p += log_sprintf( pMac, p, "HAL "); break; + case SIR_HAL_EXT_MODULE_ID: p += log_sprintf( pMac, p, "HAL "); break; + case SIR_CFG_MODULE_ID: p += log_sprintf( pMac, p, "CFG "); break; + case SIR_LIM_MODULE_ID: p += log_sprintf( pMac, p, "LIM "); break; + case SIR_ARQ_MODULE_ID: p += log_sprintf( pMac, p, "ARQ "); break; + case SIR_SCH_MODULE_ID: p += log_sprintf( pMac, p, "SCH "); break; + case SIR_PMM_MODULE_ID: p += log_sprintf( pMac, p, "PMM "); break; + case SIR_MNT_MODULE_ID: p += log_sprintf( pMac, p, "MNT "); break; + case SIR_DBG_MODULE_ID: p += log_sprintf( pMac, p, "DBG "); break; + case SIR_DPH_MODULE_ID: p += log_sprintf( pMac, p, "DPH "); break; + case SIR_SYS_MODULE_ID: p += log_sprintf( pMac, p, "SYS "); break; + case SIR_PHY_MODULE_ID: p += log_sprintf( pMac, p, "PHY "); break; + case SIR_DVT_MODULE_ID: p += log_sprintf( pMac, p, "DVT "); break; + case SIR_SMS_MODULE_ID: p += log_sprintf( pMac, p, "SMS "); break; + default: p += log_sprintf( pMac, p, "UNK ", i); break; + } + + p += log_sprintf( pMac, p, + ": debug level is [0x%x] ", + pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID]); + + switch( pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID] ) + { + case LOGOFF: p += log_sprintf( pMac, p, "LOG disabled\n"); break; + case LOGP: p += log_sprintf( pMac, p, "LOGP(Panic only)\n"); break; + case LOGE: p += log_sprintf( pMac, p, "LOGE(Errors only)\n"); break; + case LOGW: p += log_sprintf( pMac, p, "LOGW(Warnings)\n"); break; + case LOG1: p += log_sprintf( pMac, p, "LOG1(Minimal debug)\n"); break; + case LOG2: p += log_sprintf( pMac, p, "LOG2(Verbose)\n"); break; + case LOG3: p += log_sprintf( pMac, p, "LOG3(Very Verbose)\n"); break; + case LOG4: p += log_sprintf( pMac, p, "LOG4(Very Very Verbose)\n"); break; + default: p += log_sprintf( pMac, p, "Unknown\n"); break; + } + } + + return p; +} + +char* setLOGLevel( tpAniSirGlobal pMac, char *p, tANI_U32 module, tANI_U32 level ) +{ + tANI_U32 i; + + if((module > SIR_LAST_MODULE_ID || module < SIR_FIRST_MODULE_ID) && module != 0xff ) { + p += log_sprintf( pMac, p, "Invalid module id 0x%x\n", module ); + return p; + } + + if( 0xff == module ) { + for( i = SIR_FIRST_MODULE_ID; i <= SIR_LAST_MODULE_ID; i++ ) + pMac->utils.gLogDbgLevel[i - SIR_FIRST_MODULE_ID] = level; + } else { + pMac->utils.gLogDbgLevel[module - SIR_FIRST_MODULE_ID] = level; + } + +#ifdef ANI_PHY_DEBUG + if (module == 0xff || module == SIR_PHY_MODULE_ID) { + pMac->hphy.phy.phyDebugLogLevel = level; + } +#endif + + return dumpLOG( pMac, p ); +} + +static void Log_getCfg(tpAniSirGlobal pMac, tANI_U16 cfgId) +{ +#define CFG_CTL_INT 0x00080000 + if ((pMac->cfg.gCfgEntry[cfgId].control & CFG_CTL_INT) != 0) + { + tANI_U32 val; + + // Get integer parameter + if (wlan_cfgGetInt(pMac, (tANI_U16)cfgId, &val) != eSIR_SUCCESS) + { + sysLog(pMac, LOGE, FL("Get cfgId 0x%x failed\n"), cfgId); + } + else + { + sysLog( pMac, LOGE, FL("WNI_CFG_%s(%d 0x%x) = %ld\n"), gCfgParamName[cfgId], cfgId, cfgId, val ); + } + } + else + { + tANI_U8 buf[CFG_MAX_STR_LEN] = {0} ; + tANI_U32 valueLen ; + + // Get string parameter + valueLen = CFG_MAX_STR_LEN ; + if (wlan_cfgGetStr(pMac, cfgId, buf, &valueLen) != eSIR_SUCCESS) + { + sysLog(pMac, LOGE, FL("Get cfgId 0x%x failed\n"), cfgId); + } + else + { + sysLog( pMac, LOGE, FL("WNI_CFG_%s(%d 0x%x) len=%ld\n"), gCfgParamName[cfgId], cfgId, cfgId, valueLen ); + sirDumpBuf(pMac, SIR_WDA_MODULE_ID, LOG1, buf, valueLen) ; + } + } + + return; +} + +static void Log_setCfg(tpAniSirGlobal pMac, tANI_U16 cfgId, tANI_U32 val) +{ + sysLog(pMac, LOGE, FL("Set %s(0x%x) to value 0x%x\n"), + gCfgParamName[cfgId], cfgId, val); + + if (cfgSetInt(pMac, (tANI_U16)cfgId, val) != eSIR_SUCCESS) + sysLog(pMac, LOGE, FL("setting cfgId 0x%x to value 0x%x failed \n"), + cfgId, val); + return; +} + + +char * dump_cfg_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg2; (void) arg3; (void) arg4; + Log_getCfg(pMac, (tANI_U16) arg1); + return p; +} + +char * dump_cfg_group_get( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + tANI_U32 i, startId, endId; + + (void) arg3; (void) arg4; + + if (arg1 < CFG_PARAM_MAX_NUM) { + startId = arg1; + } else { + p += log_sprintf( pMac, p, "Start CFGID must be less than %d\n", CFG_PARAM_MAX_NUM); + return p; + } + + if ((arg2 == 0) || (arg2 > CFG_PARAM_MAX_NUM)) + arg2 = 30; + + endId = ((startId + arg2) < CFG_PARAM_MAX_NUM) ? (startId + arg2) : CFG_PARAM_MAX_NUM; + + for (i=startId; i < endId; i++) + Log_getCfg(pMac, (tANI_U16) i); + + return p; +} +char * dump_cfg_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg3; (void) arg4; + Log_setCfg(pMac, (tANI_U16) arg1, arg2); + return p; +} + +char * dump_log_level_set( tpAniSirGlobal pMac, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, char *p) +{ + (void) arg1; (void) arg2; (void) arg3; (void) arg4; + p = setLOGLevel( pMac, p, arg1, arg2 ); + return p; +} + + +/* Initialize the index */ +void logDumpInit(tpAniSirGlobal pMac) +{ + pMac->dumpTablecurrentId = 0; + +} + +void logDumpRegisterTable( tpAniSirGlobal pMac, tDumpFuncEntry *pEntry, tANI_U32 nItems ) +{ + + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->nItems = nItems; + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->mindumpid = pEntry->id; + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->maxdumpid = (pEntry + (nItems-1))->id; + pMac->dumpTableEntry[pMac->dumpTablecurrentId]->dumpTable = pEntry; + pMac->dumpTablecurrentId++; +} + + +/* + * print nItems from the menu list ponted to by m + */ +static tANI_U32 print_menu(tpAniSirGlobal pMac, char *p, tANI_U32 startId) +{ + tANI_U32 currentId = 0; + tANI_U32 i, j; + tANI_S32 ret = 0; + tDumpFuncEntry *pEntry = NULL; + tANI_U32 nItems = 0; + + for(i = 0; i < pMac->dumpTablecurrentId; i++) { + pEntry = pMac->dumpTableEntry[i]->dumpTable; + nItems = pMac->dumpTableEntry[i]->nItems; + + for (j = 0; j < nItems; j++, pEntry++) { + if (pEntry->description == NULL) + continue; + + if (pEntry->id == 0) { + ret = log_sprintf( pMac,p, "---- %s\n", pEntry->description); + + if (ret <= 0) + break; + + p += ret; + continue; + } + + if (pEntry->id < startId) + continue; + + ret = log_sprintf(pMac, p, "%4d\t%s\n", pEntry->id, pEntry->description); + + if (ret <= 0) + break; + + currentId = pEntry->id; + p += ret; + } + + if (ret <= 0) + break; + } + + return currentId; +} + +int logRtaiDump( tpAniSirGlobal pMac, tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, tANI_U32 arg4, tANI_U8 *pBuf) +{ + char *p = (char *)pBuf; + tANI_U32 i; + tANI_U32 nItems = 0; + tDumpFuncEntry *pEntry = NULL; + + pMac->gCurrentLogSize = 0; + if (debug) { + p += log_sprintf( pMac,p, "Cmd = %d Args (0x%x,0x%x,0x%x,0x%x)\n\n", + cmd, arg1, arg2, arg3, arg4); + } + + if( cmd == MAX_DUMP_CMD || cmd == 0 ) { + pMac->menuCurrent = print_menu(pMac, p, pMac->menuCurrent); + return pMac->gCurrentLogSize; + } + if(cmd <= HAL_LOG_DUMP_CMD_END) + { + WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, p, 0); + } + else + { + for(i = 0; i < pMac->dumpTablecurrentId; i++) { + if( (cmd > pMac->dumpTableEntry[i]->mindumpid) && (cmd <= pMac->dumpTableEntry[i]->maxdumpid)) { + pEntry = pMac->dumpTableEntry[i]->dumpTable; + nItems = pMac->dumpTableEntry[i]->nItems; + break; + } else { + continue; + } + } + + if((nItems > 0) && (pEntry != NULL)) { + for (i = 0; i < nItems; i++, pEntry++) { + if( cmd == pEntry->id ) { + if ( pEntry->func != NULL ) { + pEntry->func(pMac, arg1, arg2, arg3, arg4, p); + } else { + p += log_sprintf( pMac,p, "Cmd not supported\n"); + } + break; + } + } + } else { + p += log_sprintf( pMac,p, "Cmd not found \n"); + } + } + if (debug) + p += log_sprintf( pMac,p, "Returned %d bytes\n", pMac->gCurrentLogSize); + + return pMac->gCurrentLogSize; + +} + +#endif diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c new file mode 100644 index 000000000000..ba7c97aba797 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/macTrace.c @@ -0,0 +1,1121 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + + \file macTrace.c + + \brief implementation for trace related APIs + + \author Sunit Bhatia + + + ========================================================================*/ + + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +#include "macTrace.h" +#include "wlan_qct_wda.h" + +#include "wlan_hdd_assoc.h" +#include "wlan_hdd_main.h" +#ifdef CONFIG_CFG80211 +#include "wlan_hdd_p2p.h" +#endif +#include "csrNeighborRoam.h" +#include "csrInternal.h" +#include "limGlobal.h" +#include "limTypes.h" +#include "wlan_qct_tl.h" +#include "wlan_qct_wda.h" +#include "vos_trace.h" + +#ifdef TRACE_RECORD + +/* --------------------------------------------------------------------------- + \fn macTraceGetHDDWlanConnState + \function to get string equivalent of a value + from the enum eConnectionState. + + \param connState - the value from the enum + \return the string equivalent of connState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetHDDWlanConnState(tANI_U16 connState) +{ + switch(connState) + { + CASE_RETURN_STRING(eConnectionState_NotConnected); + CASE_RETURN_STRING(eConnectionState_Connecting); + CASE_RETURN_STRING(eConnectionState_Associated); + CASE_RETURN_STRING(eConnectionState_IbssDisconnected); + CASE_RETURN_STRING(eConnectionState_IbssConnected); + CASE_RETURN_STRING(eConnectionState_Disconnecting); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetP2PConnState + \function to get string equivalent of a value + from the enum tP2PConnectionStatus. + + \param connState - the value from the enum + \return the string equivalent of connState + ---------------------------------------------------------------------------*/ +#ifdef WLAN_FEATURE_P2P_DEBUG +tANI_U8* macTraceGetP2PConnState(tANI_U16 connState) +{ + switch(connState) + { + CASE_RETURN_STRING(P2P_NOT_ACTIVE); + CASE_RETURN_STRING(P2P_GO_NEG_PROCESS); + CASE_RETURN_STRING(P2P_GO_NEG_COMPLETED); + CASE_RETURN_STRING(P2P_CLIENT_CONNECTING_STATE_1); + CASE_RETURN_STRING(P2P_GO_COMPLETED_STATE); + CASE_RETURN_STRING(P2P_CLIENT_CONNECTED_STATE_1); + CASE_RETURN_STRING(P2P_CLIENT_DISCONNECTED_STATE); + CASE_RETURN_STRING(P2P_CLIENT_CONNECTING_STATE_2); + CASE_RETURN_STRING(P2P_CLIENT_COMPLETED_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} +#endif + +/* --------------------------------------------------------------------------- + \fn macTraceGetNeighbourRoamState + \function to get string equivalent of a value + from the enum eCsrNeighborRoamState. + + \param neighbourRoamState - the value from the enum + \return the string equivalent of neighbourRoamState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetNeighbourRoamState(tANI_U16 neighbourRoamState) +{ + switch(neighbourRoamState) + { + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CLOSED); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_INIT); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING); + #ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING); + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE); + #endif /* WLAN_FEATURE_VOWIFI_11R */ + #ifdef WLAN_FEATURE_LFR_MBB + CASE_RETURN_STRING(eCSR_NEIGHBOR_ROAM_STATE_MBB_PREAUTH_REASSOC); + #endif + CASE_RETURN_STRING(eNEIGHBOR_STATE_MAX); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetcsrRoamState + \function to get string equivalent of a value + from the enum eCsrRoamState. + + \param csrRoamState - the value from the enum + \return the string equivalent of csrRoamState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetcsrRoamState(tANI_U16 csrRoamState) +{ + switch(csrRoamState) + { + CASE_RETURN_STRING(eCSR_ROAMING_STATE_STOP); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_IDLE); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_SCANNING); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINING); + CASE_RETURN_STRING(eCSR_ROAMING_STATE_JOINED); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetcsrRoamSubState + \function to get string equivalent of a value + from the enum eCsrRoamSubState. + + \param csrRoamSubState - the value from the enum + \return the string equivalent of csrRoamSubState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetcsrRoamSubState(tANI_U16 csrRoamSubState) +{ + switch(csrRoamSubState) + { + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_NONE); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_START_BSS_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOIN_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_REASSOC_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_STOP_BSS_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISCONNECT_CONTINUE_ROAMING); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_AUTH_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_CONFIG); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DEAUTH_REQ); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_NOTHING_TO_JOIN); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_REASSOC_FAILURE); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_FORCED); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_WAIT_FOR_KEY); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_DISASSOC_HANDOFF); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_NO_TRAFFIC); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_NON_REALTIME_TRAFFIC); + CASE_RETURN_STRING(eCSR_ROAM_SUBSTATE_JOINED_REALTIME_TRAFFIC); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetLimSmeState + \function to get string equivalent of a value + from the enum tLimSmeStates. + + \param limState - the value from the enum + \return the string equivalent of limState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetLimSmeState(tANI_U16 limState) +{ + switch(limState) + { + CASE_RETURN_STRING(eLIM_SME_OFFLINE_STATE); + CASE_RETURN_STRING(eLIM_SME_IDLE_STATE); + CASE_RETURN_STRING(eLIM_SME_SUSPEND_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_JOIN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_ASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_REASSOC_LINK_FAIL_STATE); + CASE_RETURN_STRING(eLIM_SME_JOIN_FAILURE_STATE); + CASE_RETURN_STRING(eLIM_SME_ASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_REASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_STATE); + CASE_RETURN_STRING(eLIM_SME_LINK_EST_WT_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_PRE_AUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DISASSOC_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_DEAUTH_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_START_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_WT_STOP_BSS_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_STATE); + CASE_RETURN_STRING(eLIM_SME_CHANNEL_SCAN_STATE); + CASE_RETURN_STRING(eLIM_SME_NORMAL_CHANNEL_SCAN_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetLimMlmState + \function to get string equivalent of a value + from the enum tLimMlmStates. + + \param mlmState - the value from the enum + \return the string equivalent of mlmState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetLimMlmState(tANI_U16 mlmState) +{ + switch(mlmState) + { + CASE_RETURN_STRING(eLIM_MLM_OFFLINE_STATE); + CASE_RETURN_STRING(eLIM_MLM_IDLE_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_PROBE_RESP_STATE); + CASE_RETURN_STRING(eLIM_MLM_PASSIVE_SCAN_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_JOIN_BEACON_STATE); + CASE_RETURN_STRING(eLIM_MLM_JOINED_STATE); + CASE_RETURN_STRING(eLIM_MLM_BSS_STARTED_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME2_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME3_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_AUTH_FRAME4_STATE); + CASE_RETURN_STRING(eLIM_MLM_AUTH_RSP_TIMEOUT_STATE); + CASE_RETURN_STRING(eLIM_MLM_AUTHENTICATED_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_REASSOC_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_ASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_MLM_REASSOCIATED_STATE); + CASE_RETURN_STRING(eLIM_MLM_LINK_ESTABLISHED_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ASSOC_CNF_STATE); + CASE_RETURN_STRING(eLIM_MLM_LEARN_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_DEL_BSS_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_ADD_STA_RSP_STATE); + CASE_RETURN_STRING(eLIM_MLM_WT_DEL_STA_RSP_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +/* --------------------------------------------------------------------------- + \fn macTraceGetTLState + \function to get string equivalent of a value + from the enum WLANTL_STAStateType. + + \param tlState - the value from the enum + \return the string equivalent of tlState + ---------------------------------------------------------------------------*/ +tANI_U8* macTraceGetTLState(tANI_U16 tlState) +{ + switch(tlState) + { + CASE_RETURN_STRING(WLANTL_STA_INIT); + CASE_RETURN_STRING(WLANTL_STA_CONNECTED); + CASE_RETURN_STRING(WLANTL_STA_AUTHENTICATED); + CASE_RETURN_STRING(WLANTL_STA_DISCONNECTED); + CASE_RETURN_STRING(WLANTL_STA_MAX_STATE); + + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetSmeMsgString( tANI_U16 smeMsg ) +{ + switch( smeMsg ) + { + CASE_RETURN_STRING(eWNI_SME_START_REQ); + CASE_RETURN_STRING(eWNI_SME_START_RSP); + CASE_RETURN_STRING(eWNI_SME_SYS_READY_IND); + CASE_RETURN_STRING(eWNI_SME_SCAN_REQ); + CASE_RETURN_STRING(eWNI_SME_SCAN_ABORT_IND); + CASE_RETURN_STRING(eWNI_SME_SCAN_RSP); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(eWNI_SME_OEM_DATA_REQ); + CASE_RETURN_STRING(eWNI_SME_OEM_DATA_RSP); +#endif + CASE_RETURN_STRING(eWNI_SME_JOIN_REQ); + CASE_RETURN_STRING(eWNI_SME_JOIN_RSP); + CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_REQ); + CASE_RETURN_STRING(eWNI_SME_SETCONTEXT_RSP); + CASE_RETURN_STRING(eWNI_SME_REASSOC_REQ); + CASE_RETURN_STRING(eWNI_SME_REASSOC_RSP); + CASE_RETURN_STRING(eWNI_SME_AUTH_REQ); + CASE_RETURN_STRING(eWNI_SME_AUTH_RSP); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_REQ); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_RSP); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_IND); + CASE_RETURN_STRING(eWNI_SME_DISASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_DEAUTH_REQ); + CASE_RETURN_STRING(eWNI_SME_DEAUTH_RSP); + CASE_RETURN_STRING(eWNI_SME_DEAUTH_IND); + CASE_RETURN_STRING(eWNI_SME_WM_STATUS_CHANGE_NTF); + CASE_RETURN_STRING(eWNI_SME_IBSS_NEW_PEER_IND); + CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_DEPARTED_IND); + CASE_RETURN_STRING(eWNI_SME_START_BSS_REQ); + CASE_RETURN_STRING(eWNI_SME_START_BSS_RSP); + CASE_RETURN_STRING(eWNI_SME_AUTH_IND); + CASE_RETURN_STRING(eWNI_SME_ASSOC_IND); + CASE_RETURN_STRING(eWNI_SME_ASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_REASSOC_IND); + CASE_RETURN_STRING(eWNI_SME_REASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_RSP); + CASE_RETURN_STRING(eWNI_SME_STOP_BSS_REQ); + CASE_RETURN_STRING(eWNI_SME_STOP_BSS_RSP); + CASE_RETURN_STRING(eWNI_SME_DEL_BA_PEER_IND); + CASE_RETURN_STRING(eWNI_SME_DEFINE_QOS_REQ); + CASE_RETURN_STRING(eWNI_SME_DEFINE_QOS_RSP); + CASE_RETURN_STRING(eWNI_SME_DELETE_QOS_REQ); + CASE_RETURN_STRING(eWNI_SME_DELETE_QOS_RSP); + CASE_RETURN_STRING(eWNI_SME_PROMISCUOUS_MODE_REQ); + CASE_RETURN_STRING(eWNI_SME_PROMISCUOUS_MODE_RSP); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_START_REQ); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_START_RSP); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_STOP_REQ); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_STOP_RSP); + CASE_RETURN_STRING(eWNI_SME_LINK_TEST_REPORT_IND); + CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_BSS_IND); + CASE_RETURN_STRING(eWNI_SME_MEASUREMENT_REQ); + CASE_RETURN_STRING(eWNI_SME_MEASUREMENT_RSP); + CASE_RETURN_STRING(eWNI_SME_MEASUREMENT_IND); + CASE_RETURN_STRING(eWNI_SME_SET_WDS_INFO_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_WDS_INFO_RSP); + CASE_RETURN_STRING(eWNI_SME_WDS_INFO_IND); + CASE_RETURN_STRING(eWNI_SME_SET_POWER_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_POWER_RSP); + CASE_RETURN_STRING(eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_REQ); + CASE_RETURN_STRING(eWNI_SME_CLIENT_SIDE_LOAD_BALANCE_RSP); + CASE_RETURN_STRING(eWNI_SME_SELECT_CHANNEL_REQ); + CASE_RETURN_STRING(eWNI_SME_SELECT_CHANNEL_RSP); + CASE_RETURN_STRING(eWNI_SME_SET_PROPRIETARY_IE_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_PROPRIETARY_IE_RSP); // #endif + CASE_RETURN_STRING(eWNI_SME_DISCARD_SKB_NTF); // Used to cleanup SKBs by HDD + CASE_RETURN_STRING(eWNI_SME_DEAUTH_CNF); + CASE_RETURN_STRING(eWNI_SME_MIC_FAILURE_IND); + CASE_RETURN_STRING(eWNI_SME_ADDTS_REQ); + CASE_RETURN_STRING(eWNI_SME_ADDTS_RSP); + CASE_RETURN_STRING(eWNI_SME_ADDTS_CNF); + CASE_RETURN_STRING(eWNI_SME_ADDTS_IND); + CASE_RETURN_STRING(eWNI_SME_DELTS_REQ); + CASE_RETURN_STRING(eWNI_SME_DELTS_RSP); + CASE_RETURN_STRING(eWNI_SME_DELTS_IND); + CASE_RETURN_STRING(eWNI_SME_SET_BACKGROUND_SCAN_MODE_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_PRIMARY_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_PRIMARY_RSP); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_SECONDARY_REQ); + CASE_RETURN_STRING(eWNI_SME_SWITCH_CHL_CB_SECONDARY_RSP); + CASE_RETURN_STRING(eWNI_SME_PROBE_REQ); + CASE_RETURN_STRING(eWNI_SME_STA_STAT_REQ); + CASE_RETURN_STRING(eWNI_SME_STA_STAT_RSP); + CASE_RETURN_STRING(eWNI_SME_AGGR_STAT_REQ); + CASE_RETURN_STRING(eWNI_SME_AGGR_STAT_RSP); + CASE_RETURN_STRING(eWNI_SME_GLOBAL_STAT_REQ); + CASE_RETURN_STRING(eWNI_SME_GLOBAL_STAT_RSP); + CASE_RETURN_STRING(eWNI_SME_STAT_SUMM_REQ); + CASE_RETURN_STRING(eWNI_SME_STAT_SUMM_RSP); + CASE_RETURN_STRING(eWNI_SME_REMOVEKEY_REQ); + CASE_RETURN_STRING(eWNI_SME_REMOVEKEY_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_SCANNED_CHANNEL_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_SCANNED_CHANNEL_RSP); + CASE_RETURN_STRING(eWNI_SME_SET_TX_POWER_REQ); + CASE_RETURN_STRING(eWNI_SME_SET_TX_POWER_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_TX_POWER_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_TX_POWER_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_NOISE_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_NOISE_RSP); + CASE_RETURN_STRING(eWNI_SME_LOW_RSSI_IND); + CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_STATISTICS_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_RSSI_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_ASSOC_STAS_REQ); + CASE_RETURN_STRING(eWNI_SME_TKIP_CNTR_MEAS_REQ); + CASE_RETURN_STRING(eWNI_SME_UPDATE_APWPSIE_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_WPSPBC_SESSION_REQ); + CASE_RETURN_STRING(eWNI_SME_WPS_PBC_PROBE_REQ_IND); + CASE_RETURN_STRING(eWNI_SME_SET_APWPARSNIEs_REQ); + CASE_RETURN_STRING(eWNI_SME_UPPER_LAYER_ASSOC_CNF); + CASE_RETURN_STRING(eWNI_SME_HIDE_SSID_REQ); + CASE_RETURN_STRING(eWNI_SME_CHNG_MCC_BEACON_INTERVAL); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHANNEL_REQ); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_IND); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_RSP); + CASE_RETURN_STRING(eWNI_SME_REMAIN_ON_CHN_RDY_IND); + CASE_RETURN_STRING(eWNI_SME_SEND_ACTION_FRAME_IND); + CASE_RETURN_STRING(eWNI_SME_ACTION_FRAME_SEND_CNF); + CASE_RETURN_STRING(eWNI_SME_ABORT_REMAIN_ON_CHAN_IND); + CASE_RETURN_STRING(eWNI_SME_UPDATE_NOA); + CASE_RETURN_STRING(eWNI_SME_CLEAR_DFS_CHANNEL_LIST); + CASE_RETURN_STRING(eWNI_SME_PRE_CHANNEL_SWITCH_FULL_POWER); + CASE_RETURN_STRING(eWNI_SME_GET_SNR_REQ); + CASE_RETURN_STRING(eWNI_SME_LOST_LINK_PARAMS_IND); + CASE_RETURN_STRING(eWNI_PMC_MSG_TYPES_BEGIN); + + //General Power Save Messages + CASE_RETURN_STRING(eWNI_PMC_PWR_SAVE_CFG); + + //BMPS Messages + CASE_RETURN_STRING(eWNI_PMC_ENTER_BMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_BMPS_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_BMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_BMPS_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_BMPS_IND); + + //IMPS Messages. + CASE_RETURN_STRING(eWNI_PMC_ENTER_IMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_IMPS_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_IMPS_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_IMPS_RSP); + + //UAPSD Messages + CASE_RETURN_STRING(eWNI_PMC_ENTER_UAPSD_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_UAPSD_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_UAPSD_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_UAPSD_RSP); + + CASE_RETURN_STRING(eWNI_PMC_SMPS_STATE_IND); + CASE_RETURN_STRING(eWNI_PMC_WOWL_ADD_BCAST_PTRN); + CASE_RETURN_STRING(eWNI_PMC_WOWL_DEL_BCAST_PTRN); + CASE_RETURN_STRING(eWNI_PMC_ENTER_WOWL_REQ); + CASE_RETURN_STRING(eWNI_PMC_ENTER_WOWL_RSP); + CASE_RETURN_STRING(eWNI_PMC_EXIT_WOWL_REQ); + CASE_RETURN_STRING(eWNI_PMC_EXIT_WOWL_RSP); + +#ifdef WLAN_FEATURE_PACKET_FILTERING + CASE_RETURN_STRING(eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP); +#endif // WLAN_FEATURE_PACKET_FILTERING +#if defined WLAN_FEATURE_VOWIFI + CASE_RETURN_STRING(eWNI_SME_RRM_MSG_TYPE_BEGIN); + CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_REQ_IND); + CASE_RETURN_STRING(eWNI_SME_NEIGHBOR_REPORT_IND); + CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_REQ_IND); + CASE_RETURN_STRING(eWNI_SME_BEACON_REPORT_RESP_XMIT_IND); +#endif + CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_REQ); + CASE_RETURN_STRING(eWNI_SME_ADD_STA_SELF_RSP); + CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_REQ); + CASE_RETURN_STRING(eWNI_SME_DEL_STA_SELF_RSP); +#if defined WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_REQ); + CASE_RETURN_STRING(eWNI_SME_FT_PRE_AUTH_RSP); + CASE_RETURN_STRING(eWNI_SME_FT_UPDATE_KEY); + CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_REQ); + CASE_RETURN_STRING(eWNI_SME_FT_AGGR_QOS_RSP); +#endif +#if defined FEATURE_WLAN_ESE + CASE_RETURN_STRING(eWNI_SME_ESE_ADJACENT_AP_REPORT); +#endif + CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_REQ); + CASE_RETURN_STRING(eWNI_SME_COEX_IND); +#ifdef FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING(eWNI_SME_PREF_NETWORK_FOUND_IND); +#endif // FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING(eWNI_SME_TX_PER_HIT_IND); + CASE_RETURN_STRING(eWNI_SME_CHANGE_COUNTRY_CODE); + CASE_RETURN_STRING(eWNI_SME_GENERIC_CHANGE_COUNTRY_CODE); + CASE_RETURN_STRING(eWNI_SME_PRE_SWITCH_CHL_IND); + CASE_RETURN_STRING(eWNI_SME_POST_SWITCH_CHL_IND); + CASE_RETURN_STRING(eWNI_SME_MAX_ASSOC_EXCEEDED); + CASE_RETURN_STRING(eWNI_SME_BTAMP_LOG_LINK_IND);//to serialize the create/accpet LL req from HCI +#ifdef WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP); +#endif // WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_RSP); +#ifdef FEATURE_WLAN_LPHB + CASE_RETURN_STRING(eWNI_SME_LPHB_IND); +#endif /* FEATURE_WLAN_LPHB */ +#ifdef FEATURE_WLAN_CH_AVOID + CASE_RETURN_STRING(eWNI_SME_CH_AVOID_IND); +#endif /* FEATURE_WLAN_CH_AVOID */ +#ifdef WLAN_WAKEUP_EVENTS + CASE_RETURN_STRING(eWNI_SME_WAKE_REASON_IND); +#endif // WLAN_WAKEUP_EVENTS + CASE_RETURN_STRING(eWNI_SME_EXCLUDE_UNENCRYPTED); + CASE_RETURN_STRING(eWNI_SME_RSSI_IND); //RSSI indication from TL to be serialized on MC thread +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING(eWNI_SME_TDLS_SEND_MGMT_REQ); + CASE_RETURN_STRING(eWNI_SME_TDLS_SEND_MGMT_RSP); + CASE_RETURN_STRING(eWNI_SME_TDLS_ADD_STA_REQ); + CASE_RETURN_STRING(eWNI_SME_TDLS_ADD_STA_RSP); + CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_STA_REQ); + CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_STA_RSP); + CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_STA_IND); + CASE_RETURN_STRING(eWNI_SME_TDLS_DEL_ALL_PEER_IND); + CASE_RETURN_STRING(eWNI_SME_MGMT_FRM_TX_COMPLETION_IND); + CASE_RETURN_STRING(eWNI_SME_TDLS_LINK_ESTABLISH_REQ); + CASE_RETURN_STRING(eWNI_SME_TDLS_LINK_ESTABLISH_RSP); + CASE_RETURN_STRING(eWNI_SME_TDLS_CHANNEL_SWITCH_REQ); + CASE_RETURN_STRING(eWNI_SME_TDLS_CHANNEL_SWITCH_RSP); +#endif + CASE_RETURN_STRING(eWNI_SME_SET_BCN_FILTER_REQ); + CASE_RETURN_STRING(eWNI_SME_RESET_AP_CAPS_CHANGED); +#ifdef WLAN_FEATURE_11W + CASE_RETURN_STRING(eWNI_SME_UNPROT_MGMT_FRM_IND); +#endif + CASE_RETURN_STRING(eWNI_SME_CANDIDATE_FOUND_IND); + CASE_RETURN_STRING(eWNI_SME_HANDOFF_REQ); +#ifdef WLAN_FEATURE_RMC + CASE_RETURN_STRING(eWNI_SME_ENABLE_RMC_REQ); + CASE_RETURN_STRING(eWNI_SME_DISABLE_RMC_REQ); + CASE_RETURN_STRING(eWNI_SME_IBSS_PEER_INFO_RSP); +#endif + CASE_RETURN_STRING(eWNI_SME_GET_ROAM_RSSI_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_ROAM_RSSI_RSP); + CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_TSM_STATS_RSP); + CASE_RETURN_STRING(eWNI_SME_TSM_IE_IND); + CASE_RETURN_STRING(eWNI_SME_HT40_OBSS_SCAN_IND); + CASE_RETURN_STRING(eWNI_SME_HT40_STOP_OBSS_SCAN_IND); + CASE_RETURN_STRING(eWNI_SME_NAN_EVENT); + CASE_RETURN_STRING(eWNI_SME_ENCRYPT_MSG_RSP); +#ifdef WLAN_FEATURE_AP_HT40_24G + CASE_RETURN_STRING(eWNI_SME_SET_HT_2040_MODE); + CASE_RETURN_STRING(eWNI_SME_2040_COEX_IND); +#endif + CASE_RETURN_STRING(eWNI_SME_MAC_SPOOF_ADDR_IND); + CASE_RETURN_STRING(eWNI_SME_UPDATE_MAX_RATE_IND); + CASE_RETURN_STRING(eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ); + CASE_RETURN_STRING(eWNI_SME_REGISTER_MGMT_FRAME_CB); +#ifdef WLAN_FEATURE_LFR_MBB + CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_REQ); + CASE_RETURN_STRING(eWNI_SME_MBB_PRE_AUTH_REASSOC_RSP); +#endif + CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END); + CASE_RETURN_STRING(eWNI_SME_CAP_TSF_REQ); + CASE_RETURN_STRING(eWNI_SME_GET_TSF_REQ); + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + + +tANI_U8* macTraceGetWdaMsgString( tANI_U16 wdaMsg ) +{ + switch( wdaMsg ) + { + CASE_RETURN_STRING(WDA_APP_SETUP_NTF); + CASE_RETURN_STRING(WDA_NIC_OPER_NTF); + CASE_RETURN_STRING(WDA_INIT_START_REQ); + CASE_RETURN_STRING(WDA_RESET_REQ); + CASE_RETURN_STRING(WDA_HDD_ADDBA_REQ); + CASE_RETURN_STRING(WDA_HDD_ADDBA_RSP); + CASE_RETURN_STRING(WDA_DELETEBA_IND); + CASE_RETURN_STRING(WDA_BA_FAIL_IND); + CASE_RETURN_STRING(WDA_TL_FLUSH_AC_REQ); + CASE_RETURN_STRING(WDA_TL_FLUSH_AC_RSP); + + CASE_RETURN_STRING(WDA_ITC_MSG_TYPES_BEGIN); + CASE_RETURN_STRING(WDA_WDT_KAM_RSP); + CASE_RETURN_STRING(WDA_TIMER_TEMP_MEAS_REQ); + CASE_RETURN_STRING(WDA_TIMER_PERIODIC_STATS_COLLECT_REQ); + CASE_RETURN_STRING(WDA_CAL_REQ_NTF); + CASE_RETURN_STRING(WDA_MNT_OPEN_TPC_TEMP_MEAS_REQ); + CASE_RETURN_STRING(WDA_CCA_MONITOR_INTERVAL_TO); + CASE_RETURN_STRING(WDA_CCA_MONITOR_DURATION_TO); + CASE_RETURN_STRING(WDA_CCA_MONITOR_START); + CASE_RETURN_STRING(WDA_CCA_MONITOR_STOP); + CASE_RETURN_STRING(WDA_CCA_CHANGE_MODE); + CASE_RETURN_STRING(WDA_TIMER_WRAP_AROUND_STATS_COLLECT_REQ); + + CASE_RETURN_STRING(WDA_ADD_STA_REQ); + CASE_RETURN_STRING(WDA_ADD_STA_RSP); + CASE_RETURN_STRING(WDA_ADD_STA_SELF_RSP); + CASE_RETURN_STRING(WDA_DEL_STA_SELF_RSP); + CASE_RETURN_STRING(WDA_DELETE_STA_REQ); + CASE_RETURN_STRING(WDA_DELETE_STA_RSP); + CASE_RETURN_STRING(WDA_ADD_BSS_REQ); + CASE_RETURN_STRING(WDA_ADD_BSS_RSP); + CASE_RETURN_STRING(WDA_DELETE_BSS_REQ); + CASE_RETURN_STRING(WDA_DELETE_BSS_RSP); + CASE_RETURN_STRING(WDA_INIT_SCAN_REQ); + CASE_RETURN_STRING(WDA_INIT_SCAN_RSP); + CASE_RETURN_STRING(WDA_START_SCAN_REQ); + CASE_RETURN_STRING(WDA_START_SCAN_RSP); + CASE_RETURN_STRING(WDA_END_SCAN_REQ); + CASE_RETURN_STRING(WDA_END_SCAN_RSP); + CASE_RETURN_STRING(WDA_FINISH_SCAN_REQ); + CASE_RETURN_STRING(WDA_FINISH_SCAN_RSP); + CASE_RETURN_STRING(WDA_SEND_BEACON_REQ); + CASE_RETURN_STRING(WDA_SEND_BEACON_RSP); + + CASE_RETURN_STRING(WDA_INIT_CFG_REQ); + CASE_RETURN_STRING(WDA_INIT_CFG_RSP); + + CASE_RETURN_STRING(WDA_INIT_WM_CFG_REQ); + CASE_RETURN_STRING(WDA_INIT_WM_CFG_RSP); + + CASE_RETURN_STRING(WDA_SET_BSSKEY_REQ); + CASE_RETURN_STRING(WDA_SET_BSSKEY_RSP); + CASE_RETURN_STRING(WDA_SET_STAKEY_REQ); + CASE_RETURN_STRING(WDA_SET_STAKEY_RSP); + CASE_RETURN_STRING(WDA_DPU_STATS_REQ); + CASE_RETURN_STRING(WDA_DPU_STATS_RSP); + CASE_RETURN_STRING(WDA_GET_DPUINFO_REQ); + CASE_RETURN_STRING(WDA_GET_DPUINFO_RSP); + + CASE_RETURN_STRING(WDA_UPDATE_EDCA_PROFILE_IND); + + CASE_RETURN_STRING(WDA_UPDATE_STARATEINFO_REQ); + CASE_RETURN_STRING(WDA_UPDATE_STARATEINFO_RSP); + + CASE_RETURN_STRING(WDA_UPDATE_BEACON_IND); + CASE_RETURN_STRING(WDA_UPDATE_CF_IND); + CASE_RETURN_STRING(WDA_CHNL_SWITCH_REQ); + CASE_RETURN_STRING(WDA_ADD_TS_REQ); + CASE_RETURN_STRING(WDA_DEL_TS_REQ); + CASE_RETURN_STRING(WDA_SOFTMAC_TXSTAT_REPORT); + CASE_RETURN_STRING(WDA_MBOX_SENDMSG_COMPLETE_IND); + CASE_RETURN_STRING(WDA_EXIT_BMPS_REQ); + CASE_RETURN_STRING(WDA_EXIT_BMPS_RSP); + CASE_RETURN_STRING(WDA_EXIT_BMPS_IND); + CASE_RETURN_STRING(WDA_ENTER_BMPS_REQ); + CASE_RETURN_STRING(WDA_ENTER_BMPS_RSP); + CASE_RETURN_STRING(WDA_BMPS_STATUS_IND); + CASE_RETURN_STRING(WDA_MISSED_BEACON_IND); + + CASE_RETURN_STRING(WDA_CFG_RXP_FILTER_REQ); + CASE_RETURN_STRING(WDA_CFG_RXP_FILTER_RSP); + CASE_RETURN_STRING(WDA_SWITCH_CHANNEL_RSP); + CASE_RETURN_STRING(WDA_P2P_NOA_ATTR_IND); + CASE_RETURN_STRING(WDA_P2P_NOA_START_IND); + CASE_RETURN_STRING(WDA_PWR_SAVE_CFG); + + CASE_RETURN_STRING(WDA_REGISTER_PE_CALLBACK); + CASE_RETURN_STRING(WDA_SOFTMAC_MEM_READREQUEST); + CASE_RETURN_STRING(WDA_SOFTMAC_MEM_WRITEREQUEST); + + CASE_RETURN_STRING(WDA_SOFTMAC_MEM_READRESPONSE); + CASE_RETURN_STRING(WDA_SOFTMAC_BULKREGWRITE_CONFIRM); + CASE_RETURN_STRING(WDA_SOFTMAC_BULKREGREAD_RESPONSE); + CASE_RETURN_STRING(WDA_SOFTMAC_HOSTMESG_MSGPROCESSRESULT); + + CASE_RETURN_STRING(WDA_ADDBA_REQ); + CASE_RETURN_STRING(WDA_ADDBA_RSP); + CASE_RETURN_STRING(WDA_DELBA_IND); + CASE_RETURN_STRING(WDA_DEL_BA_IND); + CASE_RETURN_STRING(WDA_MIC_FAILURE_IND); + + CASE_RETURN_STRING(WDA_DELBA_REQ); + CASE_RETURN_STRING(WDA_IBSS_STA_ADD); + CASE_RETURN_STRING(WDA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND); + CASE_RETURN_STRING(WDA_SET_LINK_STATE); + CASE_RETURN_STRING(WDA_SET_LINK_STATE_RSP); + CASE_RETURN_STRING(WDA_ENTER_IMPS_REQ); + CASE_RETURN_STRING(WDA_ENTER_IMPS_RSP); + CASE_RETURN_STRING(WDA_EXIT_IMPS_RSP); + CASE_RETURN_STRING(WDA_EXIT_IMPS_REQ); + CASE_RETURN_STRING(WDA_SOFTMAC_HOSTMESG_PS_STATUS_IND); + CASE_RETURN_STRING(WDA_POSTPONE_ENTER_IMPS_RSP); + CASE_RETURN_STRING(WDA_STA_STAT_REQ); + CASE_RETURN_STRING(WDA_GLOBAL_STAT_REQ); + CASE_RETURN_STRING(WDA_AGGR_STAT_REQ); + CASE_RETURN_STRING(WDA_STA_STAT_RSP); + CASE_RETURN_STRING(WDA_GLOBAL_STAT_RSP); + CASE_RETURN_STRING(WDA_AGGR_STAT_RSP); + CASE_RETURN_STRING(WDA_STAT_SUMM_REQ); + CASE_RETURN_STRING(WDA_STAT_SUMM_RSP); + CASE_RETURN_STRING(WDA_REMOVE_BSSKEY_REQ); + CASE_RETURN_STRING(WDA_REMOVE_BSSKEY_RSP); + CASE_RETURN_STRING(WDA_REMOVE_STAKEY_REQ); + CASE_RETURN_STRING(WDA_REMOVE_STAKEY_RSP); + CASE_RETURN_STRING(WDA_SET_STA_BCASTKEY_REQ); + CASE_RETURN_STRING(WDA_SET_STA_BCASTKEY_RSP); + CASE_RETURN_STRING(WDA_REMOVE_STA_BCASTKEY_REQ); + CASE_RETURN_STRING(WDA_REMOVE_STA_BCASTKEY_RSP); + CASE_RETURN_STRING(WDA_ADD_TS_RSP); + CASE_RETURN_STRING(WDA_DPU_MIC_ERROR); + + CASE_RETURN_STRING(WDA_TIMER_BA_ACTIVITY_REQ); + CASE_RETURN_STRING(WDA_TIMER_CHIP_MONITOR_TIMEOUT); + CASE_RETURN_STRING(WDA_TIMER_TRAFFIC_ACTIVITY_REQ); + CASE_RETURN_STRING(WDA_TIMER_ADC_RSSI_STATS); +#ifdef WLAN_FEATURE_11W + CASE_RETURN_STRING(WDA_EXCLUDE_UNENCRYPTED_IND); +#endif +#ifdef FEATURE_WLAN_ESE + CASE_RETURN_STRING(WDA_TSM_STATS_REQ); + CASE_RETURN_STRING(WDA_TSM_STATS_RSP); +#endif + CASE_RETURN_STRING(WDA_UPDATE_UAPSD_IND); + CASE_RETURN_STRING(WDA_SET_MIMOPS_REQ); + CASE_RETURN_STRING(WDA_SET_MIMOPS_RSP); + CASE_RETURN_STRING(WDA_SYS_READY_IND ); + CASE_RETURN_STRING(WDA_SET_TX_POWER_REQ); + CASE_RETURN_STRING(WDA_SET_TX_POWER_RSP); + CASE_RETURN_STRING(WDA_GET_TX_POWER_REQ); + CASE_RETURN_STRING(WDA_GET_TX_POWER_RSP); + CASE_RETURN_STRING(WDA_GET_NOISE_REQ ); + CASE_RETURN_STRING(WDA_GET_NOISE_RSP); + CASE_RETURN_STRING(WDA_SET_TX_PER_TRACKING_REQ); + + CASE_RETURN_STRING(WDA_TRANSMISSION_CONTROL_IND); + CASE_RETURN_STRING(WDA_INIT_RADAR_IND); + + CASE_RETURN_STRING(WDA_BEACON_PRE_IND ); + CASE_RETURN_STRING(WDA_ENTER_UAPSD_REQ); + CASE_RETURN_STRING(WDA_ENTER_UAPSD_RSP); + CASE_RETURN_STRING(WDA_EXIT_UAPSD_REQ ); + CASE_RETURN_STRING(WDA_EXIT_UAPSD_RSP ); + CASE_RETURN_STRING(WDA_LOW_RSSI_IND ); + CASE_RETURN_STRING(WDA_BEACON_FILTER_IND); + CASE_RETURN_STRING(WDA_WOWL_ADD_BCAST_PTRN); + CASE_RETURN_STRING(WDA_WOWL_DEL_BCAST_PTRN); + CASE_RETURN_STRING(WDA_WOWL_ENTER_REQ); + CASE_RETURN_STRING(WDA_WOWL_ENTER_RSP); + CASE_RETURN_STRING(WDA_WOWL_EXIT_REQ ); + CASE_RETURN_STRING(WDA_WOWL_EXIT_RSP ); + CASE_RETURN_STRING(WDA_TX_COMPLETE_IND); + CASE_RETURN_STRING(WDA_TIMER_RA_COLLECT_AND_ADAPT); + CASE_RETURN_STRING(WDA_GET_STATISTICS_REQ); + CASE_RETURN_STRING(WDA_GET_STATISTICS_RSP); + CASE_RETURN_STRING(WDA_SET_KEY_DONE); + + CASE_RETURN_STRING(WDA_BTC_SET_CFG); + CASE_RETURN_STRING(WDA_SIGNAL_BT_EVENT); + CASE_RETURN_STRING(WDA_HANDLE_FW_MBOX_RSP); + CASE_RETURN_STRING(WDA_UPDATE_PROBE_RSP_TEMPLATE_IND); + CASE_RETURN_STRING(WDA_SIGNAL_BTAMP_EVENT); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(WDA_START_OEM_DATA_REQ ); + CASE_RETURN_STRING(WDA_START_OEM_DATA_RSP); + CASE_RETURN_STRING(WDA_FINISH_OEM_DATA_REQ); +#endif //SUPPORT_BEACON_FILTER + CASE_RETURN_STRING(WDA_SET_MAX_TX_POWER_REQ); + CASE_RETURN_STRING(WDA_SET_MAX_TX_POWER_RSP); + CASE_RETURN_STRING(WDA_SET_MAX_TX_POWER_PER_BAND_RSP); + CASE_RETURN_STRING(WDA_SET_MAX_TX_POWER_PER_BAND_REQ); + CASE_RETURN_STRING(WDA_SEND_MSG_COMPLETE); + CASE_RETURN_STRING(WDA_SET_HOST_OFFLOAD); + CASE_RETURN_STRING(WDA_SET_KEEP_ALIVE); +#ifdef WLAN_NS_OFFLOAD + CASE_RETURN_STRING(WDA_SET_NS_OFFLOAD); +#endif //WLAN_NS_OFFLOAD + CASE_RETURN_STRING(WDA_ADD_STA_SELF_REQ); + CASE_RETURN_STRING(WDA_DEL_STA_SELF_REQ); + CASE_RETURN_STRING(WDA_SET_P2P_GO_NOA_REQ); + CASE_RETURN_STRING(WDA_SET_TDLS_LINK_ESTABLISH_REQ); + CASE_RETURN_STRING(WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP); + CASE_RETURN_STRING(WDA_TX_COMPLETE_TIMEOUT_IND); + CASE_RETURN_STRING(WDA_TIMER_TRAFFIC_STATS_IND); + CASE_RETURN_STRING(WDA_WLAN_SUSPEND_IND); + CASE_RETURN_STRING(WDA_WLAN_RESUME_REQ); + CASE_RETURN_STRING(WDA_MSG_TYPES_END); + CASE_RETURN_STRING(WDA_MMH_TXMB_READY_EVT); + CASE_RETURN_STRING(WDA_MMH_RXMB_DONE_EVT); + CASE_RETURN_STRING(WDA_MMH_MSGQ_NE_EVT); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(WDA_AGGR_QOS_REQ); + CASE_RETURN_STRING(WDA_AGGR_QOS_RSP); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + CASE_RETURN_STRING(WDA_FTM_CMD_REQ); + CASE_RETURN_STRING(WDA_FTM_CMD_RSP); +#ifdef FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING(WDA_SET_PNO_REQ); + CASE_RETURN_STRING(WDA_SET_RSSI_FILTER_REQ); + CASE_RETURN_STRING(WDA_UPDATE_SCAN_PARAMS_REQ); + CASE_RETURN_STRING(WDA_SET_PNO_CHANGED_IND); +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + CASE_RETURN_STRING(WDA_ROAM_SCAN_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_ROAM_SCAN_OFFLOAD_RSP); + CASE_RETURN_STRING(WDA_PER_ROAM_SCAN_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_PER_ROAM_SCAN_OFFLOAD_RSP); + CASE_RETURN_STRING(WDA_PER_ROAM_SCAN_TRIGGER_REQ); + CASE_RETURN_STRING(WDA_PER_ROAM_SCAN_TRIGGER_RSP); +#endif +#ifdef WLAN_WAKEUP_EVENTS + CASE_RETURN_STRING(WDA_WAKE_REASON_IND); +#endif // WLAN_WAKEUP_EVENTS +#ifdef WLAN_FEATURE_PACKET_FILTERING + CASE_RETURN_STRING(WDA_8023_MULTICAST_LIST_REQ); + CASE_RETURN_STRING(WDA_RECEIVE_FILTER_SET_FILTER_REQ); + CASE_RETURN_STRING(WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ); + CASE_RETURN_STRING(WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP); + CASE_RETURN_STRING(WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ); +#endif // WLAN_FEATURE_PACKET_FILTERING + CASE_RETURN_STRING(WDA_SET_POWER_PARAMS_REQ); +#ifdef WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(WDA_GTK_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_GTK_OFFLOAD_GETINFO_REQ); + CASE_RETURN_STRING(WDA_GTK_OFFLOAD_GETINFO_RSP); +#endif //WLAN_FEATURE_GTK_OFFLOAD + CASE_RETURN_STRING(WDA_SET_TM_LEVEL_REQ); +#ifdef WLAN_FEATURE_11AC + CASE_RETURN_STRING(WDA_UPDATE_OP_MODE); +#endif + CASE_RETURN_STRING(WDA_GET_ROAM_RSSI_REQ); + CASE_RETURN_STRING(WDA_GET_ROAM_RSSI_RSP); + CASE_RETURN_STRING(WDA_NAN_REQUEST); + CASE_RETURN_STRING(WDA_START_SCAN_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_START_SCAN_OFFLOAD_RSP); + CASE_RETURN_STRING(WDA_STOP_SCAN_OFFLOAD_REQ); + CASE_RETURN_STRING(WDA_STOP_SCAN_OFFLOAD_RSP); + CASE_RETURN_STRING(WDA_UPDATE_CHAN_LIST_RSP); + CASE_RETURN_STRING(WDA_RX_SCAN_EVENT); + CASE_RETURN_STRING(WDA_IBSS_PEER_INACTIVITY_IND); +#ifdef FEATURE_WLAN_LPHB + CASE_RETURN_STRING(WDA_LPHB_WAIT_EXPIRE_IND); +#endif +#ifdef WLAN_FEATURE_RMC + CASE_RETURN_STRING(WDA_RMC_BECOME_RULER); + CASE_RETURN_STRING(WDA_RMC_RULER_SELECT_RESP); + CASE_RETURN_STRING(WDA_RMC_RULER_REQ); + CASE_RETURN_STRING(WDA_RMC_UPDATE_IND); + CASE_RETURN_STRING(WDA_GET_IBSS_PEER_INFO_RSP); +#endif +#ifdef FEATURE_WLAN_BATCH_SCAN + CASE_RETURN_STRING(WDA_SET_BATCH_SCAN_REQ); + CASE_RETURN_STRING(WDA_SET_BATCH_SCAN_RSP); + CASE_RETURN_STRING(WDA_STOP_BATCH_SCAN_IND); + CASE_RETURN_STRING(WDA_TRIGGER_BATCH_SCAN_RESULT_IND); +#endif + CASE_RETURN_STRING(WDA_UPDATE_CHAN_LIST_REQ); + CASE_RETURN_STRING(WDA_GET_BCN_MISS_RATE_REQ); + CASE_RETURN_STRING(WDA_DHCP_START_IND); + CASE_RETURN_STRING(WDA_DHCP_STOP_IND); + CASE_RETURN_STRING(WDA_MGMT_LOGGING_INIT_REQ); +#ifdef FEATURE_WLAN_LPHB + CASE_RETURN_STRING(WDA_LPHB_CONF_REQ); +#endif /* FEATURE_WLAN_LPHB */ + CASE_RETURN_STRING(WDA_ADD_PERIODIC_TX_PTRN_IND); + CASE_RETURN_STRING(WDA_DEL_PERIODIC_TX_PTRN_IND); + CASE_RETURN_STRING(WDA_RATE_UPDATE_IND); +#ifdef WLAN_FEATURE_RMC + CASE_RETURN_STRING(WDA_GET_IBSS_PEER_INFO_REQ); + CASE_RETURN_STRING(WDA_TX_FAIL_MONITOR_IND); +#endif /* WLAN_FEATURE_RMC */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + CASE_RETURN_STRING(WDA_LINK_LAYER_STATS_SET_REQ); + CASE_RETURN_STRING(WDA_LINK_LAYER_STATS_GET_REQ); + CASE_RETURN_STRING(WDA_LINK_LAYER_STATS_CLEAR_REQ); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef WLAN_FEATURE_EXTSCAN + CASE_RETURN_STRING(WDA_EXTSCAN_GET_CAPABILITIES_REQ); + CASE_RETURN_STRING(WDA_EXTSCAN_START_REQ); + CASE_RETURN_STRING(WDA_EXTSCAN_STOP_REQ); + CASE_RETURN_STRING(WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ); + CASE_RETURN_STRING(WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ); + CASE_RETURN_STRING(WDA_EXTSCAN_GET_CACHED_RESULTS_REQ); + CASE_RETURN_STRING(WDA_HIGH_PRIORITY_DATA_INFO_IND); +#endif /* WLAN_FEATURE_EXTSCAN */ + CASE_RETURN_STRING(WDA_HT40_OBSS_SCAN_IND); + CASE_RETURN_STRING(WDA_HT40_OBSS_STOP_SCAN_IND); + CASE_RETURN_STRING(WDA_ENCRYPT_MSG_REQ); + CASE_RETURN_STRING(WDA_ENCRYPT_MSG_RSP); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + CASE_RETURN_STRING(WDA_LINK_LAYER_STATS_RESULTS_RSP); +#endif +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING(WDA_SET_TDLS_CHAN_SWITCH_REQ); + CASE_RETURN_STRING(WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP); +#endif + CASE_RETURN_STRING(WDA_FW_STATS_GET_REQ); + CASE_RETURN_STRING(WDA_SET_RTS_CTS_HTVHT); + CASE_RETURN_STRING(WDA_MON_START_REQ); + CASE_RETURN_STRING(WDA_MON_STOP_REQ); + CASE_RETURN_STRING(WDA_SPOOF_MAC_ADDR_REQ); + CASE_RETURN_STRING(WDA_LOST_LINK_PARAMS_IND); +#ifdef DHCP_SERVER_OFFLOAD + CASE_RETURN_STRING(WDA_SET_DHCP_SERVER_OFFLOAD_REQ); +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + CASE_RETURN_STRING(WDA_SET_MDNS_OFFLOAD_CMD); + CASE_RETURN_STRING(WDA_SET_MDNS_FQDN_CMD); + CASE_RETURN_STRING(WDA_SET_MDNS_RESPONSE_CMD); + CASE_RETURN_STRING(WDA_GET_MDNS_STATUS_CMD); +#endif + CASE_RETURN_STRING(WDA_CAP_TSF_REQ); + CASE_RETURN_STRING(WDA_GET_TSF_REQ); + CASE_RETURN_STRING(WDA_SET_ARP_STATS_REQ); + CASE_RETURN_STRING(WDA_GET_ARP_STATS_REQ); + default: + return((tANI_U8*) "UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetLimMsgString( tANI_U16 limMsg ) +{ + switch( limMsg ) + { + CASE_RETURN_STRING(SIR_LIM_RETRY_INTERRUPT_MSG); + CASE_RETURN_STRING(SIR_BB_XPORT_MGMT_MSG ); + CASE_RETURN_STRING(SIR_LIM_INV_KEY_INTERRUPT_MSG ); + CASE_RETURN_STRING(SIR_LIM_KEY_ID_INTERRUPT_MSG ); + CASE_RETURN_STRING(SIR_LIM_REPLAY_THRES_INTERRUPT_MSG ); + CASE_RETURN_STRING(SIR_LIM_TD_DUMMY_CALLBACK_MSG ); + CASE_RETURN_STRING(SIR_LIM_SCH_CLEAN_MSG ); + CASE_RETURN_STRING(SIR_LIM_RADAR_DETECT_IND); + CASE_RETURN_STRING(SIR_LIM_DEL_TS_IND); + CASE_RETURN_STRING(SIR_LIM_ADD_BA_IND ); + CASE_RETURN_STRING(SIR_LIM_DEL_BA_ALL_IND); + CASE_RETURN_STRING(SIR_LIM_DELETE_STA_CONTEXT_IND); + CASE_RETURN_STRING(SIR_LIM_DEL_BA_IND ); + CASE_RETURN_STRING(SIR_LIM_UPDATE_BEACON); + CASE_RETURN_STRING(SIR_LIM_MIN_CHANNEL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_MAX_CHANNEL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_JOIN_FAIL_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_AUTH_FAIL_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_AUTH_RSP_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_ASSOC_FAIL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_REASSOC_FAIL_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_HEART_BEAT_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_CHANNEL_SCAN_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_PROBE_HB_FAILURE_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_ADDTS_RSP_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_LINK_TEST_DURATION_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_CNF_WAIT_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_KEEPALIVE_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_CHANNEL_SWITCH_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_QUIET_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_QUIET_BSS_TIMEOUT ); + CASE_RETURN_STRING(SIR_LIM_WPS_OVERLAP_TIMEOUT); +#ifdef WLAN_FEATURE_VOWIFI_11R + CASE_RETURN_STRING(SIR_LIM_FT_PREAUTH_RSP_TIMEOUT); +#endif + CASE_RETURN_STRING(SIR_LIM_REMAIN_CHN_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE); +#ifdef WMM_APSD + CASE_RETURN_STRING(SIR_LIM_WMM_APSD_SP_START_MSG_TYPE ); + CASE_RETURN_STRING(SIR_LIM_WMM_APSD_SP_END_MSG_TYPE ); +#endif + CASE_RETURN_STRING(SIR_LIM_BEACON_GEN_IND ); + CASE_RETURN_STRING(SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT); +#ifdef FEATURE_WLAN_ESE + CASE_RETURN_STRING(SIR_LIM_ESE_TSM_TIMEOUT); +#endif + CASE_RETURN_STRING(SIR_LIM_DISASSOC_ACK_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_DEAUTH_ACK_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT); + +#ifdef WLAN_FEATURE_LFR_MBB + CASE_RETURN_STRING(SIR_LIM_PREAUTH_MBB_RSP_TIMEOUT); + CASE_RETURN_STRING(SIR_LIM_REASSOC_MBB_RSP_TIMEOUT); + +#endif + + CASE_RETURN_STRING(SIR_LIM_AUTH_RETRY_TIMEOUT); + + CASE_RETURN_STRING(SIR_LIM_MSG_TYPES_END); + CASE_RETURN_STRING(LIM_MLM_SCAN_REQ); + CASE_RETURN_STRING(LIM_MLM_SCAN_CNF); + CASE_RETURN_STRING(LIM_MLM_START_REQ); + CASE_RETURN_STRING(LIM_MLM_START_CNF); + CASE_RETURN_STRING(LIM_MLM_JOIN_REQ); + CASE_RETURN_STRING(LIM_MLM_JOIN_CNF); + CASE_RETURN_STRING(LIM_MLM_AUTH_REQ); + CASE_RETURN_STRING(LIM_MLM_AUTH_CNF); + CASE_RETURN_STRING(LIM_MLM_AUTH_IND); + CASE_RETURN_STRING(LIM_MLM_ASSOC_REQ); + CASE_RETURN_STRING(LIM_MLM_ASSOC_CNF); + CASE_RETURN_STRING(LIM_MLM_ASSOC_IND); + CASE_RETURN_STRING(LIM_MLM_DISASSOC_REQ); + CASE_RETURN_STRING(LIM_MLM_DISASSOC_CNF); + CASE_RETURN_STRING(LIM_MLM_DISASSOC_IND); + CASE_RETURN_STRING(LIM_MLM_REASSOC_REQ); + CASE_RETURN_STRING(LIM_MLM_REASSOC_CNF); + CASE_RETURN_STRING(LIM_MLM_REASSOC_IND); + CASE_RETURN_STRING(LIM_MLM_DEAUTH_REQ); + CASE_RETURN_STRING(LIM_MLM_DEAUTH_CNF); + CASE_RETURN_STRING(LIM_MLM_DEAUTH_IND); + CASE_RETURN_STRING(LIM_MLM_TSPEC_REQ); + CASE_RETURN_STRING(LIM_MLM_TSPEC_CNF); + CASE_RETURN_STRING(LIM_MLM_SETKEYS_REQ); + CASE_RETURN_STRING(LIM_MLM_SETKEYS_CNF); + CASE_RETURN_STRING(LIM_MLM_PURGE_STA_IND); + CASE_RETURN_STRING(LIM_MLM_ADDBA_REQ); + CASE_RETURN_STRING(LIM_MLM_ADDBA_CNF); + CASE_RETURN_STRING(LIM_MLM_ADDBA_RSP); + CASE_RETURN_STRING(LIM_MLM_DELBA_REQ); + CASE_RETURN_STRING(LIM_MLM_DELBA_CNF); + CASE_RETURN_STRING(LIM_MLM_REMOVEKEY_REQ); + CASE_RETURN_STRING(LIM_MLM_REMOVEKEY_CNF); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING(LIM_MLM_OEM_DATA_REQ); + CASE_RETURN_STRING(LIM_MLM_OEM_DATA_CNF); +#endif + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetCfgMsgString( tANI_U16 cfgMsg ) +{ + switch( cfgMsg ) + { + CASE_RETURN_STRING(WNI_CFG_PARAM_UPDATE_IND); + CASE_RETURN_STRING(WNI_CFG_DNLD_REQ); + CASE_RETURN_STRING(WNI_CFG_DNLD_CNF); + CASE_RETURN_STRING(WNI_CFG_GET_RSP); + CASE_RETURN_STRING(WNI_CFG_SET_CNF); + CASE_RETURN_STRING(SIR_CFG_PARAM_UPDATE_IND); + CASE_RETURN_STRING(SIR_CFG_DOWNLOAD_COMPLETE_IND); + CASE_RETURN_STRING(WNI_CFG_DNLD_RSP); + CASE_RETURN_STRING(WNI_CFG_GET_REQ); + CASE_RETURN_STRING(WNI_CFG_SET_REQ); + CASE_RETURN_STRING(WNI_CFG_SET_REQ_NO_RSP); + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetInfoLogString( tANI_U16 infoLog ) +{ + switch( infoLog ) + { + CASE_RETURN_STRING(eLOG_NODROP_MISSED_BEACON_SCENARIO); + CASE_RETURN_STRING(eLOG_PROC_DEAUTH_FRAME_SCENARIO); + default: + return( (tANI_U8*)"UNKNOWN" ); + break; + } +} + +tANI_U8* macTraceGetModuleString( tANI_U8 moduleId ) +{ + return ((tANI_U8*)"PE"); + //return gVosTraceInfo[moduleId].moduleNameStr; +} + +void macTraceReset(tpAniSirGlobal pMac) +{ +} + +void macTrace(tpAniSirGlobal pMac, tANI_U8 code, tANI_U8 session, tANI_U32 data) +{ + //Today macTrace is being invoked by PE only, need to remove this function once PE is migrated to using new trace API. + macTraceNew(pMac, VOS_MODULE_ID_PE, code, session, data); +} + +void macTraceNew(tpAniSirGlobal pMac, tANI_U8 module, tANI_U8 code, tANI_U8 session, tANI_U32 data) +{ + vos_trace(module, code, session, data); +} + +tANI_U8* macTraceMsgString(tpAniSirGlobal pMac, tANI_U32 msgType) +{ + tANI_U16 msgId = (tANI_U16)MAC_TRACE_GET_MSG_ID(msgType); + tANI_U8 moduleId = (tANI_U8)MAC_TRACE_GET_MODULE_ID(msgType); + + switch(moduleId) + { + case SIR_LIM_MODULE_ID: + if(msgId >= SIR_LIM_ITC_MSG_TYPES_BEGIN) + return macTraceGetLimMsgString((tANI_U16)msgType); + else + return macTraceGetSmeMsgString((tANI_U16)msgType); + break; + case SIR_WDA_MODULE_ID: + return macTraceGetWdaMsgString((tANI_U16)msgType); + case SIR_CFG_MODULE_ID: + return macTraceGetCfgMsgString((tANI_U16)msgType); + default: + return ((tANI_U8*)"Unknown MsgType"); + } +} + +#endif diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parsemactrace.cmm b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parsemactrace.cmm new file mode 100644 index 000000000000..82ec953ee16f --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parsemactrace.cmm @@ -0,0 +1,973 @@ +;Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + +;Previously licensed under the ISC license by Qualcomm Atheros, Inc. + +;Permission to use, copy, modify, and/or distribute this software for +;any purpose with or without fee is hereby granted, provided that the +;above copyright notice and this permission notice appear in all +;copies. + +;THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +;WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +;WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +;AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +;DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +;PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +;TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +;PERFORMANCE OF THIS SOFTWARE. + +;This file was originally distributed by Qualcomm Atheros, Inc. +;under proprietary terms before Copyright ownership was assigned +;to the Linux Foundation. + +;parsemactrace.cmm - This script parses MAC trace table in UMAC layer +;This script relies on message id's placed in interface header file. +;If some message ID's are changed later, since they do not use enum, this script +;might show incorrect data. So message ID's should always be in sync +;Author: Saluja, Harpreet +;Date: 09/09/2013 +;History:- +;Date Modified by Modification Information +;-------------------------------------------------------------------- + + +ENTRY &FILE + +IF "&FILE"=="" +( +DIALOG.file *.txt +ENTRY &FILE +) + +OPEN #1 "&FILE" /Create /Write /Append + + +Var.NEW char [256][50] \halmsgtype + +Var.SET \halmsgtype[0x20]="SIR_HAL_RADAR_DETECTED_IND" +Var.SET \halmsgtype[0x21]="SIR_HAL_WDT_KAM_RSP" +Var.SET \halmsgtype[0x22]="SIR_HAL_TIMER_TEMP_MEAS_REQ" +Var.SET \halmsgtype[0x23]="SIR_HAL_TIMER_PERIODIC_STATS_COLLECT_REQ" +Var.SET \halmsgtype[0x24]="SIR_HAL_CAL_REQ_NTF" +Var.SET \halmsgtype[0x25]="SIR_HAL_MNT_OPEN_TPC_TEMP_MEAS_REQ" +Var.SET \halmsgtype[0x26]="SIR_HAL_CCA_MONITOR_INTERVAL_TO" +Var.SET \halmsgtype[0x27]="SIR_HAL_CCA_MONITOR_DURATION_TO" +Var.SET \halmsgtype[0x28]="SIR_HAL_CCA_MONITOR_START" +Var.SET \halmsgtype[0x29]="SIR_HAL_CCA_MONITOR_STOP" +Var.SET \halmsgtype[0x2A]="SIR_HAL_CCA_CHANGE_MODE" +Var.SET \halmsgtype[0x2B]="SIR_HAL_TIMER_WRAP_AROUND_STATS_COLLECT_REQ" +Var.SET \halmsgtype[0x2D]="SIR_HAL_ADD_STA_REQ" +Var.SET \halmsgtype[0x2E]="SIR_HAL_ADD_STA_RSP" +Var.SET \halmsgtype[0x2F]="SIR_HAL_DELETE_STA_REQ" +Var.SET \halmsgtype[0x30]="SIR_HAL_DELETE_STA_RSP" +Var.SET \halmsgtype[0x31]="SIR_HAL_ADD_BSS_REQ" +Var.SET \halmsgtype[0x32]="SIR_HAL_ADD_BSS_RSP" +Var.SET \halmsgtype[0x33]="SIR_HAL_DELETE_BSS_REQ" +Var.SET \halmsgtype[0x34]="SIR_HAL_DELETE_BSS_RSP" +Var.SET \halmsgtype[0x35]="SIR_HAL_INIT_SCAN_REQ" +Var.SET \halmsgtype[0x36]="SIR_HAL_INIT_SCAN_RSP" +Var.SET \halmsgtype[0x37]="SIR_HAL_START_SCAN_REQ" +Var.SET \halmsgtype[0x38]="SIR_HAL_START_SCAN_RSP" +Var.SET \halmsgtype[0x39]="SIR_HAL_END_SCAN_REQ" +Var.SET \halmsgtype[0x3A]="SIR_HAL_END_SCAN_RSP" +Var.SET \halmsgtype[0x3B]="SIR_HAL_FINISH_SCAN_REQ" +Var.SET \halmsgtype[0x3C]="SIR_HAL_FINISH_SCAN_RSP" +Var.SET \halmsgtype[0x3D]="SIR_HAL_SEND_BEACON_REQ" +Var.SET \halmsgtype[0x3E]="SIR_HAL_SEND_BEACON_RSP" +Var.SET \halmsgtype[0x3F]="SIR_HAL_INIT_CFG_REQ" +Var.SET \halmsgtype[0x40]="SIR_HAL_INIT_CFG_RSP" +Var.SET \halmsgtype[0x41]="SIR_HAL_INIT_WM_CFG_REQ" +Var.SET \halmsgtype[0x42]="SIR_HAL_INIT_WM_CFG_RSP" +Var.SET \halmsgtype[0x43]="SIR_HAL_SET_BSSKEY_REQ" +Var.SET \halmsgtype[0x44]="SIR_HAL_SET_BSSKEY_RSP" +Var.SET \halmsgtype[0x45]="SIR_HAL_SET_STAKEY_REQ" +Var.SET \halmsgtype[0x46]="SIR_HAL_SET_STAKEY_RSP" +Var.SET \halmsgtype[0x47]="SIR_HAL_DPU_STATS_REQ" +Var.SET \halmsgtype[0x48]="SIR_HAL_DPU_STATS_RSP" +Var.SET \halmsgtype[0x49]="SIR_HAL_GET_DPUINFO_REQ" +Var.SET \halmsgtype[0x4A]="SIR_HAL_GET_DPUINFO_RSP" +Var.SET \halmsgtype[0x4B]="SIR_HAL_UPDATE_EDCA_PROFILE_IND" +Var.SET \halmsgtype[0x4D]="SIR_HAL_UPDATE_STARATEINFO_REQ" +Var.SET \halmsgtype[0x4E]="SIR_HAL_UPDATE_STARATEINFO_RSP" +Var.SET \halmsgtype[0x4F]="SIR_HAL_UPDATE_BEACON_IND" +Var.SET \halmsgtype[0x50]="SIR_HAL_UPDATE_CF_IND" +Var.SET \halmsgtype[0x51]="SIR_HAL_CHNL_SWITCH_REQ" +Var.SET \halmsgtype[0x52]="SIR_HAL_ADD_TS_REQ" +Var.SET \halmsgtype[0x53]="SIR_HAL_DEL_TS_REQ" +Var.SET \halmsgtype[0x54]="SIR_HAL_SOFTMAC_TXSTAT_REPORT" +Var.SET \halmsgtype[0x5D]="SIR_HAL_MBOX_SENDMSG_COMPLETE_IND" +Var.SET \halmsgtype[0x55]="SIR_HAL_EXIT_BMPS_REQ" +Var.SET \halmsgtype[0x56]="SIR_HAL_EXIT_BMPS_RSP" +Var.SET \halmsgtype[0x57]="SIR_HAL_EXIT_BMPS_IND" +Var.SET \halmsgtype[0x58]="SIR_HAL_ENTER_BMPS_REQ" +Var.SET \halmsgtype[0x59]="SIR_HAL_ENTER_BMPS_RSP" +Var.SET \halmsgtype[0x5A]="SIR_HAL_BMPS_STATUS_IND" +Var.SET \halmsgtype[0x5B]="SIR_HAL_MISSED_BEACON_IND" +Var.SET \halmsgtype[0x5C]="SIR_HAL_SWITCH_CHANNEL_RSP" +Var.SET \halmsgtype[0x5E]="SIR_HAL_PWR_SAVE_CFG" +Var.SET \halmsgtype[0x5F]="SIR_HAL_REGISTER_PE_CALLBACK" +Var.SET \halmsgtype[0x60]="SIR_HAL_SOFTMAC_MEM_READREQUEST" +Var.SET \halmsgtype[0x61]="SIR_HAL_SOFTMAC_MEM_WRITEREQUEST" +Var.SET \halmsgtype[0x62]="SIR_HAL_SOFTMAC_MEM_READRESPONSE" +Var.SET \halmsgtype[0x63]="SIR_HAL_SOFTMAC_BULKREGWRITE_CONFIRM" +Var.SET \halmsgtype[0x64]="SIR_HAL_SOFTMAC_BULKREGREAD_RESPONSE" +Var.SET \halmsgtype[0x65]="SIR_HAL_SOFTMAC_HOSTMESG_MSGPROCESSRESULT" +Var.SET \halmsgtype[0x66]="SIR_HAL_ADDBA_REQ" +Var.SET \halmsgtype[0x67]="SIR_HAL_ADDBA_RSP" +Var.SET \halmsgtype[0x68]="SIR_HAL_DELBA_IND" +Var.SET \halmsgtype[0x69]="SIR_HAL_DEL_BA_IND" +Var.SET \halmsgtype[0x6A]="SIR_HAL_DELBA_REQ" +Var.SET \halmsgtype[0x6B]="SIR_HAL_IBSS_STA_ADD" +Var.SET \halmsgtype[0x6C]="SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND" +Var.SET \halmsgtype[0x6D]="SIR_HAL_SET_LINK_STATE" +Var.SET \halmsgtype[0x6E]="SIR_HAL_ENTER_IMPS_REQ" +Var.SET \halmsgtype[0x6F]="SIR_HAL_ENTER_IMPS_RSP" +Var.SET \halmsgtype[0x70]="SIR_HAL_EXIT_IMPS_RSP" +Var.SET \halmsgtype[0x71]="SIR_HAL_EXIT_IMPS_REQ" +Var.SET \halmsgtype[0x72]="SIR_HAL_SOFTMAC_HOSTMESG_PS_STATUS_IND" +Var.SET \halmsgtype[0x73]="SIR_HAL_POSTPONE_ENTER_IMPS_RSP" +Var.SET \halmsgtype[0x74]="SIR_HAL_STA_STAT_REQ" +Var.SET \halmsgtype[0x75]="SIR_HAL_GLOBAL_STAT_REQ" +Var.SET \halmsgtype[0x76]="SIR_HAL_AGGR_STAT_REQ" +Var.SET \halmsgtype[0x77]="SIR_HAL_STA_STAT_RSP" +Var.SET \halmsgtype[0x78]="SIR_HAL_GLOBAL_STAT_RSP" +Var.SET \halmsgtype[0x79]="SIR_HAL_AGGR_STAT_RSP" +Var.SET \halmsgtype[0x7A]="SIR_HAL_STAT_SUMM_REQ" +Var.SET \halmsgtype[0x7C]="SIR_HAL_STAT_SUMM_RSP" +Var.SET \halmsgtype[0x7D]="SIR_HAL_REMOVE_BSSKEY_REQ" +Var.SET \halmsgtype[0x7E]="SIR_HAL_REMOVE_BSSKEY_RSP" +Var.SET \halmsgtype[0x7F]="SIR_HAL_REMOVE_STAKEY_REQ" +Var.SET \halmsgtype[0x80]="SIR_HAL_REMOVE_STAKEY_RSP" +Var.SET \halmsgtype[0x81]="SIR_HAL_SET_STA_BCASTKEY_REQ" +Var.SET \halmsgtype[0x82]="SIR_HAL_SET_STA_BCASTKEY_RSP" +Var.SET \halmsgtype[0x83]="SIR_HAL_REMOVE_STA_BCASTKEY_REQ" +Var.SET \halmsgtype[0x84]="SIR_HAL_REMOVE_STA_BCASTKEY_RSP" +Var.SET \halmsgtype[0x85]="SIR_HAL_ADD_TS_RSP" +Var.SET \halmsgtype[0x86]="SIR_HAL_DPU_MIC_ERROR" +Var.SET \halmsgtype[0x87]="SIR_HAL_TIMER_BA_ACTIVITY_REQ" +Var.SET \halmsgtype[0x88]="SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT" +Var.SET \halmsgtype[0x89]="SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ" +Var.SET \halmsgtype[0x8A]="SIR_HAL_TIMER_ADC_RSSI_STATS" +Var.SET \halmsgtype[0x8B]="SIR_HAL_MIC_FAILURE_IND" +Var.SET \halmsgtype[0x8C]="SIR_HAL_UPDATE_UAPSD_IND" +Var.SET \halmsgtype[0x8D]="SIR_HAL_SET_MIMOPS_REQ" +Var.SET \halmsgtype[0x8E]="SIR_HAL_SET_MIMOPS_RSP" +Var.SET \halmsgtype[0x8F]="SIR_HAL_SYS_READY_IND" +Var.SET \halmsgtype[0x90]="SIR_HAL_SET_TX_POWER_REQ" +Var.SET \halmsgtype[0x91]="SIR_HAL_SET_TX_POWER_RSP" +Var.SET \halmsgtype[0x92]="SIR_HAL_GET_TX_POWER_REQ" +Var.SET \halmsgtype[0x93]="SIR_HAL_GET_TX_POWER_RSP" +Var.SET \halmsgtype[0x94]="SIR_HAL_GET_NOISE_REQ" +Var.SET \halmsgtype[0x95]="SIR_HAL_GET_NOISE_RSP" +Var.SET \halmsgtype[0x96]="SIR_HAL_TRANSMISSION_CONTROL_IND" +Var.SET \halmsgtype[0x97]="SIR_HAL_INIT_RADAR_IND" +Var.SET \halmsgtype[0x98]="SIR_HAL_BEACON_PRE_IND" +Var.SET \halmsgtype[0x99]="SIR_HAL_ENTER_UAPSD_REQ" +Var.SET \halmsgtype[0x9A]="SIR_HAL_ENTER_UAPSD_RSP" +Var.SET \halmsgtype[0x9B]="SIR_HAL_EXIT_UAPSD_REQ" +Var.SET \halmsgtype[0x9C]="SIR_HAL_EXIT_UAPSD_RSP" +Var.SET \halmsgtype[0x9D]="SIR_HAL_LOW_RSSI_IND" +Var.SET \halmsgtype[0x9E]="SIR_HAL_BEACON_FILTER_IND" +Var.SET \halmsgtype[0x9F]="SIR_HAL_WOWL_ADD_BCAST_PTRN" +Var.SET \halmsgtype[0xA0]="SIR_HAL_WOWL_DEL_BCAST_PTRN" +Var.SET \halmsgtype[0xA1]="SIR_HAL_WOWL_ENTER_REQ" +Var.SET \halmsgtype[0xA2]="SIR_HAL_WOWL_ENTER_RSP" +Var.SET \halmsgtype[0xA3]="SIR_HAL_WOWL_EXIT_REQ" +Var.SET \halmsgtype[0xA4]="SIR_HAL_WOWL_EXIT_RSP" +Var.SET \halmsgtype[0xA5]="SIR_HAL_TX_COMPLETE_IND" +Var.SET \halmsgtype[0xA6]="SIR_HAL_TIMER_RA_COLLECT_AND_ADAPT" +Var.SET \halmsgtype[0xA7]="SIR_HAL_GET_STATISTICS_REQ" +Var.SET \halmsgtype[0xA8]="SIR_HAL_GET_STATISTICS_RSP" +Var.SET \halmsgtype[0xA9]="SIR_HAL_SET_KEY_DONE" +Var.SET \halmsgtype[0xAA]="SIR_HAL_BTC_SET_CFG" +Var.SET \halmsgtype[0xAB]="SIR_HAL_SIGNAL_BT_EVENT" +Var.SET \halmsgtype[0xAC]="SIR_HAL_HANDLE_FW_MBOX_RSP" +Var.SET \halmsgtype[0xAD]="SIR_HAL_UPDATE_PROBE_RSP_TEMPLATE_IND" +Var.SET \halmsgtype[0xAE]="SIR_LIM_ADDR2_MISS_IND" +Var.SET \halmsgtype[0xAF]="SIR_HAL_START_OEM_DATA_REQ" +Var.SET \halmsgtype[0xB0]="SIR_HAL_START_OEM_DATA_RSP" +Var.SET \halmsgtype[0xB1]="SIR_HAL_FINISH_OEM_DATA_REQ" +Var.SET \halmsgtype[0xB2]="SIR_HAL_SET_MAX_TX_POWER_REQ" +Var.SET \halmsgtype[0xB3]="SIR_HAL_SET_MAX_TX_POWER_RSP" +Var.SET \halmsgtype[0xB4]="SIR_HAL_SEND_MSG_COMPLETE" +Var.SET \halmsgtype[0xB5]="SIR_HAL_SET_HOST_OFFLOAD" +Var.SET \halmsgtype[0xB6]="SIR_HAL_ADD_STA_SELF_REQ" +Var.SET \halmsgtype[0xB7]="SIR_HAL_ADD_STA_SELF_RSP" +Var.SET \halmsgtype[0xB8]="SIR_HAL_DEL_STA_SELF_REQ" +Var.SET \halmsgtype[0xB9]="SIR_HAL_DEL_STA_SELF_RSP" +Var.SET \halmsgtype[0xBA]="SIR_HAL_SIGNAL_BTAMP_EVENT" +Var.SET \halmsgtype[0xBB]="SIR_HAL_CFG_RXP_FILTER_REQ" +Var.SET \halmsgtype[0xBC]="SIR_HAL_CFG_RXP_FILTER_RSP" +Var.SET \halmsgtype[0xBD]="SIR_HAL_AGGR_ADD_TS_REQ" +Var.SET \halmsgtype[0xBE]="SIR_HAL_AGGR_ADD_TS_RSP" +Var.SET \halmsgtype[0xBF]="SIR_HAL_AGGR_QOS_REQ" +Var.SET \halmsgtype[0xC0]="SIR_HAL_AGGR_QOS_RSP" +Var.SET \halmsgtype[0xC1]="SIR_HAL_SET_P2P_GO_NOA_REQ" +Var.SET \halmsgtype[0xC2]="SIR_HAL_P2P_NOA_ATTR_IND" +Var.SET \halmsgtype[0xC3]="SIR_HAL_P2P_NOA_START_IND" +Var.SET \halmsgtype[0xC5]="SIR_HAL_SET_LINK_STATE_RSP" +Var.SET \halmsgtype[0xC6]="SIR_HAL_WLAN_SUSPEND_IND" +Var.SET \halmsgtype[0xC7]="SIR_HAL_WLAN_RESUME_REQ" +Var.SET \halmsgtype[0xC8]="SIR_HAL_SET_KEEP_ALIVE" +Var.SET \halmsgtype[0xC9]="SIR_HAL_SET_NS_OFFLOAD" +Var.SET \halmsgtype[0xCA]="SIR_HAL_SET_PNO_REQ" +Var.SET \halmsgtype[0xCB]="SIR_HAL_SET_PNO_CHANGED_IND" +Var.SET \halmsgtype[0xCC]="SIR_HAL_UPDATE_SCAN_PARAMS" +Var.SET \halmsgtype[0xCD]="SIR_HAL_SET_RSSI_FILTER_REQ" +Var.SET \halmsgtype[0xCE]="SIR_HAL_SET_TX_PER_TRACKING_REQ" +Var.SET \halmsgtype[0xCF]="SIR_HAL_8023_MULTICAST_LIST_REQ" +Var.SET \halmsgtype[0xD0]="SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ" +Var.SET \halmsgtype[0xD1]="SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ" +Var.SET \halmsgtype[0xD2]="SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP" +Var.SET \halmsgtype[0xD3]="SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ" +Var.SET \halmsgtype[0xD4]="SIR_HAL_SET_POWER_PARAMS_REQ" +Var.SET \halmsgtype[0xD5]="SIR_HAL_GTK_OFFLOAD_REQ" +Var.SET \halmsgtype[0xD6]="SIR_HAL_GTK_OFFLOAD_GETINFO_REQ" +Var.SET \halmsgtype[0xD7]="SIR_HAL_GTK_OFFLOAD_GETINFO_RSP" +Var.SET \halmsgtype[0xD8]="SIR_HAL_TSM_STATS_REQ" +Var.SET \halmsgtype[0xD9]="SIR_HAL_TSM_STATS_RSP" +Var.SET \halmsgtype[0xDA]="SIR_HAL_WAKE_REASON_IND" +Var.SET \halmsgtype[0xDB]="SIR_HAL_SET_TM_LEVEL_REQ" +Var.SET \halmsgtype[0xDC]="SIR_HAL_UPDATE_OP_MODE" +Var.SET \halmsgtype[0xDD]="SIR_HAL_TDLS_LINK_ESTABLISH" +Var.SET \halmsgtype[0xDE]="SIR_HAL_TDLS_LINK_TEARDOWN" +Var.SET \halmsgtype[0xE3]="SIR_HAL_TRAFFIC_STATS_IND" +Var.SET \halmsgtype[0xE5]="SIR_HAL_START_SCAN_OFFLOAD_REQ" +Var.SET \halmsgtype[0xE6]="SIR_HAL_START_SCAN_OFFLOAD_RSP" +Var.SET \halmsgtype[0xE7]="SIR_HAL_UPDATE_CHAN_LIST_REQ" +Var.SET \halmsgtype[0xE8]="SIR_HAL_UPDATE_CHAN_LIST_RSP" +Var.SET \halmsgtype[0xE9]="SIR_HAL_STOP_SCAN_OFFLOAD_REQ" +Var.SET \halmsgtype[0xEA]="SIR_HAL_STOP_SCAN_OFFLOAD_RSP" +Var.SET \halmsgtype[0xEB]="SIR_HAL_RX_SCAN_EVENT" +Var.SET \halmsgtype[0xEC]="SIR_HAL_DHCP_START_IND" +Var.SET \halmsgtype[0xED]="SIR_HAL_DHCP_STOP_IND" +Var.SET \halmsgtype[0xEE]="SIR_HAL_IBSS_PEER_INACTIVITY_IND" +Var.SET \halmsgtype[0xEF]="SIR_HAL_LPHB_CONF_IND" +Var.SET \halmsgtype[0xF0]="SIR_HAL_LPHB_WAIT_EXPIRE_IND" +Var.SET \halmsgtype[0xF1]="SIR_HAL_ADD_PERIODIC_TX_PTRN_IND" +Var.SET \halmsgtype[0xF2]="SIR_HAL_DEL_PERIODIC_TX_PTRN_IND" +Var.SET \halmsgtype[0xF3]="SIR_HAL_RMC_BECOME_LEADER" +Var.SET \halmsgtype[0xF4]="SIR_HAL_RMC_LEADER_SELECT_RESP" +Var.SET \halmsgtype[0xF5]="SIR_HAL_RMC_LEADER_REQ" +Var.SET \halmsgtype[0xF6]="SIR_HAL_RMC_UPDATE_IND" +Var.SET \halmsgtype[0xF7]="SIR_HAL_IBSS_PEER_INFO_REQ" +Var.SET \halmsgtype[0xF8]="SIR_HAL_IBSS_PEER_INFO_RSP" +Var.SET \halmsgtype[0xF9]="SIR_HAL_RATE_UPDATE_IND" +Var.SET \halmsgtype[0xFA]="SIR_HAL_IBSS_ROUTE_TABLE_UPDATE_IND" +Var.SET \halmsgtype[0xFB]="SIR_HAL_TX_FAIL_MONITOR_IND" +Var.SET \halmsgtype[0xFC]="SIR_HAL_IBSS_PEER_INFO_RSP" +Var.SET \halmsgtype[0xFD]="SIR_HAL_RATE_UPDATE_IND" + + +Var.NEW char [256][100] \tlcodetype + +Var.SET \tlcodetype[0x00]="TRACE_CODE_TL_STA_STATE" +Var.SET \tlcodetype[0x01]="TRACE_CODE_TL_EAPOL_PKT_PENDING" +Var.SET \tlcodetype[0x02]="TRACE_CODE_TL_GET_FRAMES_EAPOL" +Var.SET \tlcodetype[0x03]="TRACE_CODE_TL_RX_CONN_EAPOL" +Var.SET \tlcodetype[0x04]="TRACE_CODE_TL_REGISTER_STA_CLIENT" +Var.SET \tlcodetype[0x05]="TRACE_CODE_TL_SUSPEND_DATA_TX" +Var.SET \tlcodetype[0x06]="TRACE_CODE_TL_RESUME_DATA_TX" +Var.SET \tlcodetype[0x07]="TRACE_CODE_TL_STA_PKT_PENDING" +Var.SET \tlcodetype[0x08]="TRACE_CODE_TL_QUEUE_CURRENT" +Var.SET \tlcodetype[0x09]="TRACE_CODE_TL_REORDER_TIMER_EXP_CB" +Var.SET \tlcodetype[0x0A]="TRACE_CODE_TL_BA_SESSION_DEL" +Var.SET \tlcodetype[0x0B]="TRACE_CODE_TL_ASSOC_FAILED" +Var.SET \tlcodetype[0x0C]="TRACE_CODE_TL_FORWARD_CACHED_FRAMES" +Var.SET \tlcodetype[0x0D]="TRACE_CODE_TL_FLUSH_CACHED_FRAMES" +Var.SET \tlcodetype[0x0E]="TRACE_CODE_TL_CACHE_FRAME" + +Var.NEW char [256][100] \smecodetype + +Var.SET \smecodetype[0x00]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_REQ" +Var.SET \smecodetype[0x01]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_GET_RESULTS" +Var.SET \smecodetype[0x02]="TRACE_CODE_SME_RX_HDD_MSG_CONNECT" +Var.SET \smecodetype[0x03]="TRACE_CODE_SME_RX_HDD_MSG_SET_11DINFO" +Var.SET \smecodetype[0x04]="TRACE_CODE_SME_RX_HDD_MSG_GET_SOFTAP_DOMAIN" +Var.SET \smecodetype[0x05]="TRACE_CODE_SME_RX_HDD_MSG_SET_REGINFO" +Var.SET \smecodetype[0x06]="TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CHANNEL_CONFIG" +Var.SET \smecodetype[0x07]="TRACE_CODE_SME_RX_HDD_MSG_UPDATE_CONFIG" +Var.SET \smecodetype[0x08]="TRACE_CODE_SME_RX_HDD_MSG_HDDREADYIND" +Var.SET \smecodetype[0x09]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_RESULTS" +Var.SET \smecodetype[0x0A]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_FLUSH_P2PRESULTS" +Var.SET \smecodetype[0x0B]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETFIRST" +Var.SET \smecodetype[0x0C]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_GETNEXT" +Var.SET \smecodetype[0x0D]="TRACE_CODE_SME_RX_HDD_MSG_SCAN_RESULT_PURGE" +Var.SET \smecodetype[0x0E]="TRACE_CODE_SME_RX_HDD_ROAM_REASSOC" +Var.SET \smecodetype[0x0F]="TRACE_CODE_SME_RX_HDD_ROAM_DISCONNECT" +Var.SET \smecodetype[0x10]="TRACE_CODE_SME_RX_HDD_ROAM_GET_CONNECTPROFILE" +Var.SET \smecodetype[0x11]="TRACE_CODE_SME_RX_HDD_ROAM_FREE_CONNECTPROFILE" +Var.SET \smecodetype[0x12]="TRACE_CODE_SME_RX_HDD_ROAM_SET_PMKIDCACHE" +Var.SET \smecodetype[0x13]="TRACE_CODE_SME_RX_HDD_GET_CONFIGPARAM" +Var.SET \smecodetype[0x14]="TRACE_CODE_SME_RX_HDD_GET_MODPROFFIELDS" +Var.SET \smecodetype[0x15]="TRACE_CODE_SME_RX_HDD_SET_CONFIG_PWRSAVE" +Var.SET \smecodetype[0x16]="TRACE_CODE_SME_RX_HDD_GET_CONFIG_PWRSAVE" +Var.SET \smecodetype[0x17]="TRACE_CODE_SME_RX_HDD_ENABLE_PWRSAVE" +Var.SET \smecodetype[0x18]="TRACE_CODE_SME_RX_HDD_DISABLE_PWRSAVE" +Var.SET \smecodetype[0x19]="TRACE_CODE_SME_RX_HDD_START_AUTO_BMPSTIMER" +Var.SET \smecodetype[0x1A]="TRACE_CODE_SME_RX_HDD_STOP_AUTO_BMPSTIMER" +Var.SET \smecodetype[0x1B]="TRACE_CODE_SME_RX_HDD_IS_PWRSAVE_ENABLED" +Var.SET \smecodetype[0x1C]="TRACE_CODE_SME_RX_HDD_REQUEST_FULLPOWER" +Var.SET \smecodetype[0x1D]="TRACE_CODE_SME_RX_HDD_REQUEST_BMPS" +Var.SET \smecodetype[0x1E]="TRACE_CODE_SME_RX_HDD_SET_DHCP_FLAG" +Var.SET \smecodetype[0x1F]="TRACE_CODE_SME_RX_HDD_REQUEST_STANDBY" +Var.SET \smecodetype[0x20]="TRACE_CODE_SME_RX_HDD_WOWL_ADDBCAST_PATTERN" +Var.SET \smecodetype[0x21]="TRACE_CODE_SME_RX_HDD_WOWL_DELBCAST_PATTERN" +Var.SET \smecodetype[0x22]="TRACE_CODE_SME_RX_HDD_ENTER_WOWL" +Var.SET \smecodetype[0x23]="TRACE_CODE_SME_RX_HDD_EXIT_WOWL" +Var.SET \smecodetype[0x24]="TRACE_CODE_SME_RX_HDD_SET_KEY" +Var.SET \smecodetype[0x25]="TRACE_CODE_SME_RX_HDD_REMOVE_KEY" +Var.SET \smecodetype[0x26]="TRACE_CODE_SME_RX_HDD_GET_STATS" +Var.SET \smecodetype[0x27]="TRACE_CODE_SME_RX_HDD_GET_CNTRYCODE" +Var.SET \smecodetype[0x28]="TRACE_CODE_SME_RX_HDD_SET_CNTRYCODE" +Var.SET \smecodetype[0x29]="TRACE_CODE_SME_RX_HDD_CHANGE_CNTRYCODE" +Var.SET \smecodetype[0x2A]="TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT" +Var.SET \smecodetype[0x2B]="TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG" +Var.SET \smecodetype[0x2C]="TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG" +Var.SET \smecodetype[0x2D]="TRACE_CODE_SME_RX_HDD_SET_CFGPRIVACY" +Var.SET \smecodetype[0x2E]="TRACE_CODE_SME_RX_HDD_NEIGHBOR_REPORTREQ" +Var.SET \smecodetype[0x2F]="TRACE_CODE_SME_RX_HDD_DBG_READREG" +Var.SET \smecodetype[0x30]="TRACE_CODE_SME_RX_HDD_DBG_WRITEREG" +Var.SET \smecodetype[0x31]="TRACE_CODE_SME_RX_HDD_DBG_READMEM" +Var.SET \smecodetype[0x32]="TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM" +Var.SET \smecodetype[0x33]="TRACE_CODE_SME_RX_HDD_OPEN_SESSION" +Var.SET \smecodetype[0x34]="TRACE_CODE_SME_RX_HDD_CLOSE_SESSION" +Var.SET \smecodetype[0x35]="TRACE_CODE_SME_RX_HDD_SET_HOSTOFFLOAD" +Var.SET \smecodetype[0x36]="TRACE_CODE_SME_RX_HDD_SET_GTKOFFLOAD" +Var.SET \smecodetype[0x37]="TRACE_CODE_SME_RX_HDD_GET_GTKOFFLOAD" +Var.SET \smecodetype[0x38]="TRACE_CODE_SME_RX_HDD_SET_POWERPARAMS" +Var.SET \smecodetype[0x39]="TRACE_CODE_SME_RX_HDD_ABORT_MACSCAN" +Var.SET \smecodetype[0x3A]="TRACE_CODE_SME_RX_HDD_REGISTER_MGMTFR" +Var.SET \smecodetype[0x3B]="TRACE_CODE_SME_RX_HDD_DEREGISTER_MGMTFR" +Var.SET \smecodetype[0x3C]="TRACE_CODE_SME_RX_HDD_REMAIN_ONCHAN" +Var.SET \smecodetype[0x3D]="TRACE_CODE_SME_RX_HDD_SEND_ACTION" +Var.SET \smecodetype[0x3E]="TRACE_CODE_SME_RX_HDD_CANCEL_REMAIN_ONCHAN" +Var.SET \smecodetype[0x3F]="TRACE_CODE_SME_RX_HDD_CONFIG_RXPFIL" +Var.SET \smecodetype[0x40]="TRACE_CODE_SME_RX_HDD_CONFIG_SUSPENDIND" +Var.SET \smecodetype[0x41]="TRACE_CODE_SME_RX_HDD_CONFIG_RESUMEREQ" +Var.SET \smecodetype[0x42]="TRACE_CODE_SME_RX_HDD_SET_MAXTXPOW" +Var.SET \smecodetype[0x43]="TRACE_CODE_SME_RX_HDD_SET_TXPOW" +Var.SET \smecodetype[0x44]="TRACE_CODE_SME_RX_HDD_SET_TMLEVEL" +Var.SET \smecodetype[0x45]="TRACE_CODE_SME_RX_HDD_CAPS_EXCH" +Var.SET \smecodetype[0x46]="TRACE_CODE_SME_RX_HDD_DISABLE_CAP" +Var.SET \smecodetype[0x47]="TRACE_CODE_SME_RX_HDD_GET_DEFCCNV" +Var.SET \smecodetype[0x48]="TRACE_CODE_SME_RX_HDD_GET_CURCC" +Var.SET \smecodetype[0x49]="TRACE_CODE_SME_RX_HDD_RESET_PW5G" +Var.SET \smecodetype[0x4A]="TRACE_CODE_SME_RX_HDD_UPDATE_RP5G" +Var.SET \smecodetype[0x4B]="TRACE_CODE_SME_RX_HDD_SET_ROAMIBAND" +Var.SET \smecodetype[0x4C]="TRACE_CODE_SME_RX_HDD_GET_ROAMIBAND" +Var.SET \smecodetype[0x4D]="TRACE_CODE_SME_RX_HDD_UPDATE_RSSIDIFF" +Var.SET \smecodetype[0x4E]="TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF" +Var.SET \smecodetype[0x4F]="TRACE_CODE_SME_RX_HDD_UPDATE_FTENABLED" +Var.SET \smecodetype[0x50]="TRACE_CODE_SME_RX_HDD_UPDATE_WESMODE" +Var.SET \smecodetype[0x51]="TRACE_CODE_SME_RX_HDD_SET_SCANCTRL" +;deprecated Var.SET \smecodetype[0x52]="TRACE_CODE_SME_RX_HDD_EXTSCAN_GET_CAPABILITIES" +Var.SET \smecodetype[0x52]="TRACE_CODE_SME_RX_HDD_EXTSCAN_START" +Var.SET \smecodetype[0x53]="TRACE_CODE_SME_RX_HDD_EXTSCAN_STOP" +Var.SET \smecodetype[0x54]="TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_BSS_HOTLIST" +Var.SET \smecodetype[0x55]="TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_BSS_HOTLIST" +Var.SET \smecodetype[0x56]="TRACE_CODE_SME_RX_HDD_EXTSCAN_GET_CACHED_RESULTS" +Var.SET \smecodetype[0x57]="TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_SSID_HOTLIST" +Var.SET \smecodetype[0x58]="TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_SSID_HOTLIST" +Var.SET \smecodetype[0x59]="TRACE_CODE_SME_RX_HDD_MSG_DEAUTH_STA" +;#ifdef FEATURE_WLAN_TDLS //assuming this flag is enabled by default +Var.SET \smecodetype[0x5A]="TRACE_CODE_SME_RX_HDD_TDLS_LINK_ESTABLISH_PARAM" +Var.SET \smecodetype[0x5B]="TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ" +Var.SET \smecodetype[0x5C]="TRACE_CODE_SME_RX_HDD_TDLS_SEND_MGMT_FRAME" +Var.SET \smecodetype[0x5D]="TRACE_CODE_SME_RX_HDD_TDLS_CHANGE_PEER_STA" +Var.SET \smecodetype[0x5E]="TRACE_CODE_SME_RX_HDD_TDLS_ADD_PEER_STA" +Var.SET \smecodetype[0x5F]="TRACE_CODE_SME_RX_HDD_TDLS_DEL_PEER_STA" +;#endif +Var.SET \smecodetype[0x60]="TRACE_CODE_SME_RX_HDD_PREF_NET_LIST" +;#ifdef FEATURE_WLAN_LPHB //assuming this flag is enabled by default +Var.SET \smecodetype[0x61]="TRACE_CODE_SME_RX_HDD_LPHB_CONFIG_REQ" +;#endif /* FEATURE_WLAN_LPHB */ +Var.SET \smecodetype[0x62]="TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE" +;From here hardcoded to 250 in host code +Var.SET \smecodetype[0xFA]="TRACE_CODE_SME_COMMAND" +Var.SET \smecodetype[0xFB]="TRACE_CODE_SME_TX_WDA_MSG" +Var.SET \smecodetype[0xFC]="TRACE_CODE_SME_RX_WDA_MSG" + +Var.NEW char [256][50] \cfgmsgtype + +Var.SET \cfgmsgtype[0xB0]="SIR_CFG_PARAM_UPDATE_IND" +Var.SET \cfgmsgtype[0xB1]="SIR_CFG_DOWNLOAD_COMPLETE_IND" + + +Var.NEW char [256][50] \limmsgtype + +Var.SET \limmsgtype[0xB3]="SIR_LIM_RETRY_INTERRUPT_MSG" +Var.SET \limmsgtype[0xB4]="SIR_BB_XPORT_MGMT_MSG" +Var.SET \limmsgtype[0xB7]="SIR_LIM_INV_KEY_INTERRUPT_MSG" +Var.SET \limmsgtype[0xB8]="SIR_LIM_KEY_ID_INTERRUPT_MSG" +Var.SET \limmsgtype[0xB9]="SIR_LIM_REPLAY_THRES_INTERRUPT_MSG" +Var.SET \limmsgtype[0xBA]="SIR_LIM_TD_DUMMY_CALLBACK_MSG" +Var.SET \limmsgtype[0xBB]="SIR_LIM_SCH_CLEAN_MSG" +Var.SET \limmsgtype[0xBC]="SIR_LIM_RADAR_DETECT_IND" +Var.SET \limmsgtype[0xBE]="SIR_LIM_DEL_TS_IND" +Var.SET \limmsgtype[0xBF]="SIR_LIM_ADD_BA_IND" +Var.SET \limmsgtype[0xC0]="SIR_LIM_DEL_BA_ALL_IND" +Var.SET \limmsgtype[0xC1]="SIR_LIM_DELETE_STA_CONTEXT_IND" +Var.SET \limmsgtype[0xC2]="SIR_LIM_DEL_BA_IND" +Var.SET \limmsgtype[0xC3]="SIR_LIM_UPDATE_BEACON" +Var.SET \limmsgtype[0xD0]="SIR_LIM_MIN_CHANNEL_TIMEOUT" +Var.SET \limmsgtype[0xD1]="SIR_LIM_MAX_CHANNEL_TIMEOUT" +Var.SET \limmsgtype[0xD2]="SIR_LIM_JOIN_FAIL_TIMEOUT" +Var.SET \limmsgtype[0xD3]="SIR_LIM_AUTH_FAIL_TIMEOUT" +Var.SET \limmsgtype[0xD4]="SIR_LIM_AUTH_RSP_TIMEOUT" +Var.SET \limmsgtype[0xD5]="SIR_LIM_ASSOC_FAIL_TIMEOUT" +Var.SET \limmsgtype[0xD6]="SIR_LIM_REASSOC_FAIL_TIMEOUT" +Var.SET \limmsgtype[0xD7]="SIR_LIM_HEART_BEAT_TIMEOUT" +Var.SET \limmsgtype[0xD9]="SIR_LIM_PREAUTH_CLNUP_TIMEOUT" +Var.SET \limmsgtype[0xDA]="SIR_LIM_CHANNEL_SCAN_TIMEOUT" +Var.SET \limmsgtype[0xDB]="SIR_LIM_PROBE_HB_FAILURE_TIMEOUT" +Var.SET \limmsgtype[0xDC]="SIR_LIM_ADDTS_RSP_TIMEOUT" +Var.SET \limmsgtype[0xE0]="SIR_LIM_MEASUREMENT_IND_TIMEOUT" +Var.SET \limmsgtype[0xE1]="SIR_LIM_LEARN_INTERVAL_TIMEOUT" +Var.SET \limmsgtype[0xE2]="SIR_LIM_LEARN_DURATION_TIMEOUT" +Var.SET \limmsgtype[0xE3]="SIR_LIM_LINK_TEST_DURATION_TIMEOUT" +Var.SET \limmsgtype[0xE6]="SIR_LIM_HASH_MISS_THRES_TIMEOUT" +Var.SET \limmsgtype[0xE7]="SIR_LIM_CNF_WAIT_TIMEOUT" +Var.SET \limmsgtype[0xE8]="SIR_LIM_KEEPALIVE_TIMEOUT" +Var.SET \limmsgtype[0xE9]="SIR_LIM_UPDATE_OLBC_CACHEL_TIMEOUT" +Var.SET \limmsgtype[0xEA]="SIR_LIM_CHANNEL_SWITCH_TIMEOUT" +Var.SET \limmsgtype[0xEB]="SIR_LIM_QUIET_TIMEOUT" +Var.SET \limmsgtype[0xEC]="SIR_LIM_QUIET_BSS_TIMEOUT" +Var.SET \limmsgtype[0xED]="SIR_LIM_WPS_OVERLAP_TIMEOUT" +Var.SET \limmsgtype[0xEE]="SIR_LIM_FT_PREAUTH_RSP_TIMEOUT" +Var.SET \limmsgtype[0xEF]="SIR_LIM_REMAIN_CHN_TIMEOUT" +Var.SET \limmsgtype[0xF0]="SIR_LIM_INSERT_SINGLESHOT_NOA_TIMEOUT" +Var.SET \limmsgtype[0xF1]="SIR_LIM_WMM_APSD_SP_START_MSG_TYPE" +Var.SET \limmsgtype[0xF2]="SIR_LIM_WMM_APSD_SP_END_MSG_TYPE" +Var.SET \limmsgtype[0xF3]="SIR_LIM_BEACON_GEN_IND" +Var.SET \limmsgtype[0xF4]="SIR_LIM_PERIODIC_PROBE_REQ_TIMEOUT" +Var.SET \limmsgtype[0xF5]="SIR_LIM_CCX_TSM_TIMEOUT" +Var.SET \limmsgtype[0xF6]="SIR_LIM_DISASSOC_ACK_TIMEOUT" +Var.SET \limmsgtype[0xF7]="SIR_LIM_DEAUTH_ACK_TIMEOUT" +Var.SET \limmsgtype[0xF8]="SIR_LIM_PERIODIC_JOIN_PROBE_REQ_TIMEOUT" +Var.SET \limmsgtype[0xF9]="SIR_LIM_TDLS_DISCOVERY_RSP_WAIT" +Var.SET \limmsgtype[0xFA]="SIR_LIM_TDLS_LINK_SETUP_RSP_TIMEOUT" +Var.SET \limmsgtype[0xFB]="SIR_LIM_TDLS_LINK_SETUP_CNF_TIMEOUT" +Var.SET \limmsgtype[0xFC]="SIR_LIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE" +Var.SET \limmsgtype[0xFF]="SIR_LIM_MSG_TYPES_END" + + +Var.NEW char [256][50] \schmsgtype + +Var.SET \schmsgtype[0x0]="SIR_SCH_CHANNEL_SWITCH_REQUEST" +Var.SET \schmsgtype[0x1]="SIR_SCH_START_SCAN_REQ" +Var.SET \schmsgtype[0x2]="SIR_SCH_START_SCAN_RSP" +Var.SET \schmsgtype[0x3]="SIR_SCH_END_SCAN_NTF" +Var.SET \schmsgtype[0xFF]="SIR_SCH_MSG_TYPES_END" + +Var.NEW char [256][50] \pmmmsgtype + +Var.SET \pmmmsgtype[0x0]="SIR_PMM_CHANGE_PM_MODE" +Var.SET \pmmmsgtype[0x1]="SIR_PMM_CHANGE_IMPS_MODE" +Var.SET \pmmmsgtype[0xFF]="SIR_PMM_MSG_TYPES_END" + + +Var.NEW char [256][50] \mntmsgtype + +Var.SET \mntmsgtype[0x0]="SIR_MNT_RELEASE_BD" +Var.SET \mntmsgtype[0xFF]="SIR_MNT_MSG_TYPES_END" + +Var.NEW char [256][50] \dvtmsgtype + +Var.SET \dvtmsgtype[0xF]="SIR_DVT_ITC_MSG_TYPES_BEGIN" + +Var.NEW char [0x301][50] \pttmsgtype + +Var.SET \pttmsgtype[0x0]="SIR_PTT_MSG_TYPES_BEGIN" +Var.SET \pttmsgtype[0x300]="SIR_PTT_MSG_TYPES_END" + + +Var.NEW char [18][50] \code + +Var.SET \code[0]="TRACE_CODE_MLM_STATE" +Var.SET \code[1]="TRACE_CODE_SME_STATE" +Var.SET \code[2]="TRACE_CODE_TX_MGMT" +Var.SET \code[3]="TRACE_CODE_RX_MGMT" +Var.SET \code[4]="TRACE_CODE_RX_MGMT_TSF" +Var.SET \code[5]="TRACE_CODE_TX_COMPLETE" +Var.SET \code[6]="TRACE_CODE_TX_SME_MSG" +Var.SET \code[7]="TRACE_CODE_RX_SME_MSG" +Var.SET \code[8]="TRACE_CODE_TX_WDA_MSG" +Var.SET \code[9]="TRACE_CODE_RX_WDA_MSG" +Var.SET \code[10]="TRACE_CODE_TX_LIM_MSG" +Var.SET \code[11]="TRACE_CODE_RX_LIM_MSG" +Var.SET \code[12]="TRACE_CODE_TX_CFG_MSG" +Var.SET \code[13]="TRACE_CODE_RX_CFG_MSG" +Var.SET \code[14]="TRACE_CODE_RX_MGMT_DROP" +Var.SET \code[15]="TRACE_CODE_TIMER_ACTIVATE" +Var.SET \code[16]="TRACE_CODE_TIMER_DEACTIVATE" +Var.SET \code[17]="TRACE_CODE_INFO_LOG" + + +Var.NEW char [13][50] \module + + +Var.SET \module[0]="VOS_MODULE_ID_BAP" +Var.SET \module[1]="VOS_MODULE_ID_TL" +Var.SET \module[3]="VOS_MODULE_ID_SAL" +Var.SET \module[4]="VOS_MODULE_ID_SSC" +Var.SET \module[2]="VOS_MODULE_ID_WDI" +Var.SET \module[5]="VOS_MODULE_ID_HDD" +Var.SET \module[6]="VOS_MODULE_ID_SME" +Var.SET \module[7]="VOS_MODULE_ID_PE" +Var.SET \module[8]="VOS_MODULE_ID_WDA" +Var.SET \module[9]="VOS_MODULE_ID_SYS" +Var.SET \module[10]="VOS_MODULE_ID_VOSS" +Var.SET \module[11]="VOS_MODULE_ID_SAP" +Var.SET \module[12]="VOS_MODULE_ID_HDD_SOFTAP" + +Var.NEW char [16][50] \mgmttype + +Var.SET \mgmttype[0]="SIR_MAC_MGMT_ASSOC_REQ" +Var.SET \mgmttype[1]="SIR_MAC_MGMT_ASSOC_RSP" +Var.SET \mgmttype[2]="SIR_MAC_MGMT_REASSOC_REQ" +Var.SET \mgmttype[3]="SIR_MAC_MGMT_REASSOC_RSP" +Var.SET \mgmttype[4]="SIR_MAC_MGMT_PROBE_REQ" +Var.SET \mgmttype[5]="SIR_MAC_MGMT_PROBE_RSP" +Var.SET \mgmttype[8]="SIR_MAC_MGMT_BEACON" +Var.SET \mgmttype[9]="SIR_MAC_MGMT_ATIM" +Var.SET \mgmttype[10]="SIR_MAC_MGMT_DISASSOC" +Var.SET \mgmttype[11]="SIR_MAC_MGMT_AUTH" +Var.SET \mgmttype[12]="SIR_MAC_MGMT_DEAUTH" +Var.SET \mgmttype[13]="SIR_MAC_MGMT_ACTION" +Var.SET \mgmttype[15]="SIR_MAC_MGMT_RESERVED15" + +Var.NEW char [30][50] \limtimertype + +Var.SET \limtimertype[0]="eLIM_MIN_CHANNEL_TIMER" +Var.SET \limtimertype[1]="eLIM_MAX_CHANNEL_TIMER" +Var.SET \limtimertype[2]="eLIM_JOIN_FAIL_TIMER" +Var.SET \limtimertype[3]="eLIM_AUTH_FAIL_TIMER" +Var.SET \limtimertype[4]="eLIM_AUTH_RESP_TIMER" +Var.SET \limtimertype[5]="eLIM_ASSOC_FAIL_TIMER" +Var.SET \limtimertype[6]="eLIM_REASSOC_FAIL_TIMER" +Var.SET \limtimertype[7]="eLIM_PRE_AUTH_CLEANUP_TIMER" +Var.SET \limtimertype[8]="eLIM_HEART_BEAT_TIMER" +Var.SET \limtimertype[9]="eLIM_BACKGROUND_SCAN_TIMER" +Var.SET \limtimertype[10]="eLIM_KEEPALIVE_TIMER" +Var.SET \limtimertype[11]="eLIM_CNF_WAIT_TIMER" +Var.SET \limtimertype[12]="eLIM_AUTH_RSP_TIMER" +Var.SET \limtimertype[13]="eLIM_UPDATE_OLBC_CACHE_TIMER" +Var.SET \limtimertype[14]="eLIM_PROBE_AFTER_HB_TIMER" +Var.SET \limtimertype[15]="eLIM_ADDTS_RSP_TIMER" +Var.SET \limtimertype[16]="eLIM_CHANNEL_SWITCH_TIMER" +Var.SET \limtimertype[17]="eLIM_LEARN_DURATION_TIMER" +Var.SET \limtimertype[18]="eLIM_QUIET_TIMER" +Var.SET \limtimertype[19]="eLIM_QUIET_BSS_TIMER" +Var.SET \limtimertype[20]="eLIM_WPS_OVERLAP_TIMER" +Var.SET \limtimertype[21]="eLIM_FT_PREAUTH_RSP_TIMER" +Var.SET \limtimertype[22]="eLIM_REMAIN_CHN_TIMER" +Var.SET \limtimertype[23]="eLIM_PERIODIC_PROBE_REQ_TIMER" +;#ifdef FEATURE_WLAN_CCX +;Var.SET \limtimertype[0]="eLIM_TSM_TIMER" +;#endif +;#ifdef FEATURE_WLAN_TDLS_INTERNAL +;Var.SET \limtimertype[0]="eLIM_TDLS_DISCOVERY_RSP_WAIT" +;Var.SET \limtimertype[0]="eLIM_TDLS_LINK_SETUP_RSP_TIMEOUT" +;Var.SET \limtimertype[0]="eLIM_TDLS_LINK_SETUP_CNF_TIMEOUT" +;#endif +Var.SET \limtimertype[25]="eLIM_DISASSOC_ACK_TIMER" +Var.SET \limtimertype[26]="eLIM_DEAUTH_ACK_TIMER" +Var.SET \limtimertype[27]="eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER" +Var.SET \limtimertype[28]="eLIM_INSERT_SINGLESHOT_NOA_TIMER" +Var.SET \limtimertype[29]="eLIM_CONVERT_ACTIVE_CHANNEL_TO_PASSIVE" + + + +Var.NEW char [256][100] \hddcodetype + +Var.SET \hddcodetype[0x00]="TRACE_CODE_HDD_OPEN_REQUEST" +Var.SET \hddcodetype[0x01]="TRACE_CODE_HDD_STOP_REQUEST" +Var.SET \hddcodetype[0x02]="TRACE_CODE_HDD_TX_TIMEOUT" +Var.SET \hddcodetype[0x03]="TRACE_CODE_HDD_P2P_DEV_ADDR_IOCTL" +Var.SET \hddcodetype[0x04]="TRACE_CODE_HDD_SETSUSPENDMODE_IOCTL" +Var.SET \hddcodetype[0x05]="TRACE_CODE_HDD_SETROAMTRIGGER_IOCTL" +Var.SET \hddcodetype[0x06]="TRACE_CODE_HDD_GETROAMTRIGGER_IOCTL" +Var.SET \hddcodetype[0x07]="TRACE_CODE_HDD_SETROAMSCANPERIOD_IOCTL" +Var.SET \hddcodetype[0x08]="TRACE_CODE_HDD_GETROAMSCANPERIOD_IOCTL" +Var.SET \hddcodetype[0x09]="TRACE_CODE_HDD_SETROAMDELTA_IOCTL" +Var.SET \hddcodetype[0x0A]="TRACE_CODE_HDD_GETROAMDELTA_IOCTL" +Var.SET \hddcodetype[0x0B]="TRACE_CODE_HDD_GETBAND_IOCTL" +Var.SET \hddcodetype[0x0C]="TRACE_CODE_HDD_GETCOUNTRYREV_IOCTL" +Var.SET \hddcodetype[0x0D]="TRACE_CODE_HDD_SETROAMSCANCHANNELS_IOCTL" +Var.SET \hddcodetype[0x0E]="TRACE_CODE_HDD_GETROAMSCANCHANNELS_IOCTL" +Var.SET \hddcodetype[0x0F]="TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST" +Var.SET \hddcodetype[0x10]="TRACE_CODE_HDD_HOSTAPD_STOP_REQUEST" +Var.SET \hddcodetype[0x11]="TRACE_CODE_HDD_HOSTAPD_UNINIT_REQUEST" +Var.SET \hddcodetype[0x12]="TRACE_CODE_HDD_SOFTAP_TX_TIMEOUT" +Var.SET \hddcodetype[0x13]="TRACE_CODE_HDD_HOSTAPD_SET_MAC_ADDR" +Var.SET \hddcodetype[0x14]="TRACE_CODE_HDD_HOSTAPD_P2P_SET_NOA_IOCTL" +Var.SET \hddcodetype[0x15]="TRACE_CODE_HDD_HOSTAPD_P2P_SET_PS_IOCTL" +Var.SET \hddcodetype[0x16]="TRACE_CODE_HDD_HOSTAPD_SET_SAP_CHANNEL_LIST_IOCTL" +Var.SET \hddcodetype[0x17]="TRACE_CODE_HDD_ADD_VIRTUAL_INTF" +Var.SET \hddcodetype[0x18]="TRACE_CODE_HDD_DEL_VIRTUAL_INTF" +Var.SET \hddcodetype[0x19]="TRACE_CODE_HDD_CHANGE_VIRTUAL_INTF" +Var.SET \hddcodetype[0x1A]="TRACE_CODE_HDD_CFG80211_START_AP" +Var.SET \hddcodetype[0x1B]="TRACE_CODE_HDD_CFG80211_CHANGE_BEACON" +Var.SET \hddcodetype[0x1C]="TRACE_CODE_HDD_CFG80211_STOP_AP" +Var.SET \hddcodetype[0x1D]="TRACE_CODE_HDD_CFG80211_CHANGE_BSS" +Var.SET \hddcodetype[0x1E]="TRACE_CODE_HDD_CFG80211_ADD_KEY" +Var.SET \hddcodetype[0x1F]="TRACE_CODE_HDD_CFG80211_GET_KEY" +Var.SET \hddcodetype[0x20]="TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY" +Var.SET \hddcodetype[0x21]="TRACE_CODE_HDD_CFG80211_CONNECT" +Var.SET \hddcodetype[0x22]="TRACE_CODE_HDD_CFG80211_DISCONNECT" +Var.SET \hddcodetype[0x23]="TRACE_CODE_HDD_CFG80211_JOIN_IBSS" +Var.SET \hddcodetype[0x24]="TRACE_CODE_HDD_CFG80211_LEAVE_IBSS" +Var.SET \hddcodetype[0x25]="TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS" +Var.SET \hddcodetype[0x26]="TRACE_CODE_HDD_CFG80211_SET_TXPOWER" +Var.SET \hddcodetype[0x27]="TRACE_CODE_HDD_CFG80211_GET_TXPOWER" +Var.SET \hddcodetype[0x28]="TRACE_CODE_HDD_CFG80211_SET_CHANNEL" +Var.SET \hddcodetype[0x29]="TRACE_CODE_HDD_CFG80211_ADD_BEACON" +Var.SET \hddcodetype[0x2A]="TRACE_CODE_HDD_CFG80211_SET_BEACON" +Var.SET \hddcodetype[0x2B]="TRACE_CODE_HDD_CFG80211_CHANGE_IFACE" +Var.SET \hddcodetype[0x2C]="TRACE_CODE_HDD_CHANGE_STATION" +Var.SET \hddcodetype[0x2D]="TRACE_CODE_HDD_CFG80211_UPDATE_BSS" +Var.SET \hddcodetype[0x2E]="TRACE_CODE_HDD_CFG80211_SCAN" +Var.SET \hddcodetype[0x2F]="TRACE_CODE_HDD_REMAIN_ON_CHANNEL" +Var.SET \hddcodetype[0x30]="TRACE_CODE_HDD_REMAINCHANREADYHANDLER" +Var.SET \hddcodetype[0x31]="TRACE_CODE_HDD_CFG80211_CANCEL_REMAIN_ON_CHANNEL" +Var.SET \hddcodetype[0x32]="TRACE_CODE_HDD_ACTION" +Var.SET \hddcodetype[0x33]="TRACE_CODE_HDD_MGMT_TX_CANCEL_WAIT" +Var.SET \hddcodetype[0x34]="TRACE_CODE_HDD_CFG80211_GET_STA" +Var.SET \hddcodetype[0x35]="TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT" +Var.SET \hddcodetype[0x36]="TRACE_CODE_HDD_CFG80211_DEL_STA" +Var.SET \hddcodetype[0x37]="TRACE_CODE_HDD_CFG80211_ADD_STA" +Var.SET \hddcodetype[0x38]="TRACE_CODE_HDD_CFG80211_SET_PMKSA" +Var.SET \hddcodetype[0x39]="TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES" +Var.SET \hddcodetype[0x3A]="TRACE_CODE_HDD_CFG80211_TDLS_MGMT" +Var.SET \hddcodetype[0x3B]="TRACE_CODE_HDD_CFG80211_TDLS_OPER" +Var.SET \hddcodetype[0x3C]="TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA" +Var.SET \hddcodetype[0x3D]="TRACE_CODE_HDD_UNSUPPORTED_IOCTL" +Var.SET \hddcodetype[0x3E]="TRACE_CODE_HDD_SETROAMSCANCHANNELMINTIME_IOCTL" +Var.SET \hddcodetype[0x3F]="TRACE_CODE_HDD_GETROAMSCANCHANNELMINTIME_IOCTL" +Var.SET \hddcodetype[0x40]="TRACE_CODE_HDD_STOP_NETDEV" +Var.SET \hddcodetype[0x41]="TRACE_CODE_HDD_WAKE_NETDEV" +Var.SET \hddcodetype[0x42]="TRACE_CODE_HDD_FLUSH_TX_QUEUES" +Var.SET \hddcodetype[0x43]="TRACE_CODE_HDD_CFG80211_RESUME_WLAN" +Var.SET \hddcodetype[0x44]="TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN" +Var.SET \hddcodetype[0x45]="TRACE_CODE_HDD_CFG80211_SET_MAC_ACL" +Var.SET \hddcodetype[0x46]="TRACE_CODE_HDD_CFG80211_TESTMODE" +Var.SET \hddcodetype[0x47]="TRACE_CODE_HDD_CFG80211_DUMP_SURVEY" +Var.SET \hddcodetype[0x48]="TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START" +Var.SET \hddcodetype[0x49]="TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP" +Var.SET \hddcodetype[0x4A]="TRACE_CODE_HDD_CFG80211_DEL_PMKSA" + +&TRACETYPESIZE=v.value(sizeof(tvosTraceRecord)) +&TRACESIZE=v.value(sizeof(gvosTraceTbl)) +&TRACEMAXINDEX=v.value(&TRACESIZE/&TRACETYPESIZE) + +&HEAD=v.value(gvosTraceData.head) +&TAIL=v.value(gvosTraceData.tail) + +IF ((&HEAD>&TRACEMAXINDEX)||(&TAIL>&TRACEMAXINDEX)||(&TAIL==&HEAD)) +( + GOTO ENDSCRIPT +) + +&INDEX=&HEAD + +TRACESTART: + +&TIME=v.value(gvosTraceTbl[&INDEX].time) +&MODULE=v.value(gvosTraceTbl[&INDEX].module) +&CODE=v.value(gvosTraceTbl[&INDEX].code) +&SESSION=v.value(gvosTraceTbl[&INDEX].session) +&DATA=v.value(gvosTraceTbl[&INDEX].data) + + + WRITE #1 "TIME: " &TIME + Var.Write #1 %STRING \module[&MODULE] + +IF (&MODULE==0x7) +( +if (&CODE>=0)&&(&CODE<=0x12) +( + Var.Write #1 %STRING \code[&CODE] " [" %Hex &CODE "]" +) + + IF (&SESSION==0xFF) + ( + WRITE #1 "NO SESSION" + ) + ELSE + ( + WRITE #1 "SESSION: " &SESSION + ) + + +;0 TRACE_CODE_MLM_STATE +IF (&CODE==0x0) +( + Var.NEW tLimMlmStates \mlmstate + Var.Set \mlmstate=&DATA + ;Var.Write #1 \mlmstate %Hex &DATA +) + +;1 TRACE_CODE_SME_STATE +IF (&CODE==0x1) +( + Var.NEW tLimSmeStates \smestate + Var.Set \smestate=&DATA + Var.Write #1 \smestate %Hex &DATA +) + +;2 TRACE_CODE_TX_MGMT +IF (&CODE==0x2) +( + WRITE #1 "DATA: " &DATA +) + +;3 TRACE_CODE_RX_MGMT +IF (&CODE==0x3) +( + &SERIAL=v.value(&DATA>>16) + &SUBTYPE=v.value(&DATA&0xFF) + if (&SUBTYPE<=0xF) + ( + Var.Write #1 %STRING \mgmttype[&SUBTYPE] + WRITE #1 "SEQ NUM: " &SERIAL + ) + else + ( + WRITE #1 "INCORRECT DATA" + ) +) + +;4 TRACE_CODE_RX_MGMT_TSF +IF (&CODE==0x4) +( + WRITE #1 "BEACON TS: " &DATA +) + +;5 TRACE_CODE_TX_COMPLETE +IF (&CODE==0x5) +( + Var.Write #1 %STRING \mgmttype[&DATA] %Hex &DATA +) + +;14 TRACE_CODE_RX_MGMT_DROP +IF (&CODE==0xE) +( + Var.NEW tMgmtFrmDropReason \dropreason + Var.Set \dropreason=&DATA + Var.Write #1 \dropreason %Hex &DATA +) + + +;15 TRACE_CODE_TIMER_ACTIVATE/DEACTIVATE +IF (&CODE==0xF)||(&CODE==0x10) +( + Var.Write #1 %STRING \limtimertype[&DATA] %Hex &DATA +) + +;6 TRACE_CODE_TX_SME_MSG +IF (&CODE==0x6) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x12)&&(&DATA>=0x12B0) +( +Var.Write #1 %STRING \limmsgtype[&MSG] %Hex &MSG +) +IF (&DATA>=0x1500) +( + Var.NEW enum eWniMsgTypes \smemsg + Var.Set \smemsg=&DATA + Var.Write #1 \smemsg %Hex &DATA + ) +) + +;7 TRACE_CODE_RX_SME_MSG +IF (&CODE==0x7) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x12)&&(&DATA>=0x12B0) +( +Var.Write #1 %STRING \limmsgtype[&MSG] %Hex &MSG +) +IF (&DATA>=0x1500) +( + Var.NEW enum eWniMsgTypes \smemsg + Var.Set \smemsg=&DATA + Var.Write #1 \smemsg %Hex &DATA +) +) + +;8 TRACE_CODE_TX_WDA_MSG +IF (&CODE==0x8) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x10) +( +Var.Write #1 %STRING \halmsgtype[&MSG] %Hex &MSG +) +) + +;9 TRACE_CODE_RX_WDA_MSG +IF (&CODE==0x9) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x10) +( +Var.Write #1 %STRING \halmsgtype[&MSG] %Hex &MSG +) +) + +;10 TRACE_CODE_TX_LIM_MSG +IF (&CODE==0xA) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x12)&&(&DATA>=0x12B0) +( +Var.Write #1 %STRING \limmsgtype[&MSG] %Hex &MSG +) +IF (&DATA>=0x1500) +( + Var.NEW enum eWniMsgTypes \smemsg + Var.Set \smemsg=&DATA + Var.Write #1 \smemsg %Hex &DATA +) +) + +;11 TRACE_CODE_RX_LIM_MSG +IF (&CODE==0xB) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x12)&&(&DATA>=0x12B0) +( +Var.Write #1 %STRING \limmsgtype[&MSG] %Hex &MSG +) +IF (&DATA>=0x1500) +( + Var.NEW enum eWniMsgTypes \smemsg + &DATA=v.value(&DATA&0xFFFF) + Var.Set \smemsg=&DATA + Var.Write #1 \smemsg %Hex &DATA +) +) + +;12 TRACE_CODE_TX_CFG_MSG +IF (&CODE==0xC) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x11)&&(&DATA>=0x11B0) +( +Var.Write #1 %STRING \cfgmsgtype[&MSG] %Hex &MSG +) +) + +;13 TRACE_CODE_RX_CFG_MSG +IF (&CODE==0xD) +( +&MOD=v.value(&DATA>>8) +&MSG=v.value(&DATA&0xFF) +IF (&MOD==0x11)&&(&DATA>=0x11B0) +( +Var.Write #1 %STRING \cfgmsgtype[&MSG] %Hex &MSG +) +) + +IF (&DATA>=0x1500) +( + Var.NEW enum eWniMsgTypes \smemsg + &DATA=v.value(&DATA&0xFFFF) + Var.Set \smemsg=&DATA + Var.Write #1 \smemsg %Hex &DATA +) + +) + +IF (&MODULE==0x1) +( + Var.Write #1 %STRING \tlcodetype[&CODE] %Hex &CODE + WRITE #1 "DATA: " &DATA + + IF (&SESSION==0xFF) + ( + WRITE #1 "NO SESSION" + ) + ELSE + ( + WRITE #1 "SESSION: " &SESSION + ) +) + + +IF (&MODULE==0x6) +( + + IF ((&CODE>=0x0)&&(&CODE<=0x62)) + ( + Var.Write #1 %STRING \smecodetype[&CODE] %Hex &CODE + ) + ELSE + ( + IF ((&CODE>=0xFA)&&(&CODE<=0xFC)) + ( + Var.Write #1 %STRING \smecodetype[&CODE] %Hex &CODE + ) + ELSE + ( + WRITE #1 "CODE: " &CODE + ) + ) + WRITE #1 "DATA: " &DATA + + IF (&SESSION==0xFF) + ( + WRITE #1 "NO SESSION" + ) + ELSE + ( + WRITE #1 "SESSION: " &SESSION + ) +) + +IF (&MODULE==0x5) +( + + IF ((&CODE>=0x0)&&(&CODE<=0x4A)) + ( + Var.Write #1 %STRING \hddcodetype[&CODE] %Hex &CODE + ) + ELSE + ( + WRITE #1 "CODE: " &CODE + ) + WRITE #1 "DATA: " &DATA + + IF (&SESSION==0xFF) + ( + WRITE #1 "NO SESSION" + ) + ELSE + ( + WRITE #1 "SESSION: " &SESSION + ) +) + +WRITE #1 " " + +&INDEX=v.value((&INDEX+1)%(&TRACEMAXINDEX)) + + IF (&INDEX!=&HEAD) + ( + GOTO TRACESTART + ) + + + +ENDSCRIPT: +CLOSE #1 +ENDDO diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c new file mode 100644 index 000000000000..142be12bda6e --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/parserApi.c @@ -0,0 +1,5620 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* + * This file parserApi.cc contains the code for parsing + * 802.11 messages. + * Author: Pierre Vandwalle + * Date: 03/18/02 + * History:- + * Date Modified by Modification Information + * -------------------------------------------------------------------- + * + */ + +#include "sirApi.h" +#include "aniGlobal.h" +#include "parserApi.h" +#include "cfgApi.h" +#include "limUtils.h" +#include "utilsParser.h" +#include "limSerDesUtils.h" +#include "schApi.h" +#include "palApi.h" +#include "wmmApsd.h" +#if defined WLAN_FEATURE_VOWIFI +#include "rrmApi.h" +#endif + +#define DOT11F_RSN_VERSION 1 /* current supported version */ +#define DOT11F_RSN_OUI_SIZE 4 +#define DOT11F_RSN_CSE_NULL 0x00 +#define DOT11F_RSN_CSE_WEP40 0x01 +#define DOT11F_RSN_CSE_TKIP 0x02 +#define DOT11F_RSN_CSE_WRAP 0x03 +#define DOT11F_RSN_CSE_CCMP 0x04 +#define DOT11F_RSN_CSE_WEP104 0x05 +#define DOT11F_RSN_CSE_AES_CMAC 0x06 + +static const tANI_U8 sirRSNOui[][ DOT11F_RSN_OUI_SIZE ] = { + { 0x00, 0x0F, 0xAC, 0x00 }, /* group cipher */ + { 0x00, 0x0F, 0xAC, 0x01 }, /* WEP-40 or RSN */ + { 0x00, 0x0F, 0xAC, 0x02 }, /* TKIP or RSN-PSK */ + { 0x00, 0x0F, 0xAC, 0x03 }, /* Reserved */ + { 0x00, 0x0F, 0xAC, 0x04 }, /* AES-CCMP */ + { 0x00, 0x0F, 0xAC, 0x05 }, /* WEP-104 */ + { 0x00, 0x40, 0x96, 0x00 }, /* CCKM */ + /* BIP (encryption type) or RSN-PSK-SHA256 (authentication type) */ + { 0x00, 0x0F, 0xAC, 0x06 }, + /* RSN-8021X-SHA256 (authentication type) */ + { 0x00, 0x0F, 0xAC, 0x05 } +}; + + + +//////////////////////////////////////////////////////////////////////// +void dot11fLog(tpAniSirGlobal pMac, int loglevel, const char *pString,...) +{ +#ifdef WLAN_DEBUG + if( (tANI_U32)loglevel > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE( SIR_DBG_MODULE_ID )] ) + { + return; + } + else + { + va_list marker; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_DBG_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ + } +#endif +} + +void +swapBitField16(tANI_U16 in, tANI_U16 *out) +{ +# ifdef ANI_LITTLE_BIT_ENDIAN + *out = in; +# else // Big-Endian... + *out = ( ( in & 0x8000 ) >> 15 ) | + ( ( in & 0x4000 ) >> 13 ) | + ( ( in & 0x2000 ) >> 11 ) | + ( ( in & 0x1000 ) >> 9 ) | + ( ( in & 0x0800 ) >> 7 ) | + ( ( in & 0x0400 ) >> 5 ) | + ( ( in & 0x0200 ) >> 3 ) | + ( ( in & 0x0100 ) >> 1 ) | + ( ( in & 0x0080 ) << 1 ) | + ( ( in & 0x0040 ) << 3 ) | + ( ( in & 0x0020 ) << 5 ) | + ( ( in & 0x0010 ) << 7 ) | + ( ( in & 0x0008 ) << 9 ) | + ( ( in & 0x0004 ) << 11 ) | + ( ( in & 0x0002 ) << 13 ) | + ( ( in & 0x0001 ) << 15 ); +# endif // ANI_LITTLE_BIT_ENDIAN +} + +void +swapBitField32(tANI_U32 in, tANI_U32 *out) +{ +# ifdef ANI_LITTLE_BIT_ENDIAN + *out = in; +# else // Big-Endian... + *out = ( ( in & 0x80000000 ) >> 31 ) | + ( ( in & 0x40000000 ) >> 29 ) | + ( ( in & 0x20000000 ) >> 27 ) | + ( ( in & 0x10000000 ) >> 25 ) | + ( ( in & 0x08000000 ) >> 23 ) | + ( ( in & 0x04000000 ) >> 21 ) | + ( ( in & 0x02000000 ) >> 19 ) | + ( ( in & 0x01000000 ) >> 17 ) | + ( ( in & 0x00800000 ) >> 15 ) | + ( ( in & 0x00400000 ) >> 13 ) | + ( ( in & 0x00200000 ) >> 11 ) | + ( ( in & 0x00100000 ) >> 9 ) | + ( ( in & 0x00080000 ) >> 7 ) | + ( ( in & 0x00040000 ) >> 5 ) | + ( ( in & 0x00020000 ) >> 3 ) | + ( ( in & 0x00010000 ) >> 1 ) | + ( ( in & 0x00008000 ) << 1 ) | + ( ( in & 0x00004000 ) << 3 ) | + ( ( in & 0x00002000 ) << 5 ) | + ( ( in & 0x00001000 ) << 7 ) | + ( ( in & 0x00000800 ) << 9 ) | + ( ( in & 0x00000400 ) << 11 ) | + ( ( in & 0x00000200 ) << 13 ) | + ( ( in & 0x00000100 ) << 15 ) | + ( ( in & 0x00000080 ) << 17 ) | + ( ( in & 0x00000040 ) << 19 ) | + ( ( in & 0x00000020 ) << 21 ) | + ( ( in & 0x00000010 ) << 23 ) | + ( ( in & 0x00000008 ) << 25 ) | + ( ( in & 0x00000004 ) << 27 ) | + ( ( in & 0x00000002 ) << 29 ) | + ( ( in & 0x00000001 ) << 31 ); +# endif // ANI_LITTLE_BIT_ENDIAN +} + +inline static void __printWMMParams(tpAniSirGlobal pMac, tDot11fIEWMMParams *pWmm) +{ + limLog(pMac, LOG1, FL("WMM Parameters Received: ")); + limLog(pMac, LOG1, FL("BE: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d "), + pWmm->acbe_aifsn, pWmm->acbe_acm, pWmm->acbe_aci, pWmm->acbe_acwmin, pWmm->acbe_acwmax, pWmm->acbe_txoplimit); + + limLog(pMac, LOG1, FL("BK: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d "), + pWmm->acbk_aifsn, pWmm->acbk_acm, pWmm->acbk_aci, pWmm->acbk_acwmin, pWmm->acbk_acwmax, pWmm->acbk_txoplimit); + + limLog(pMac, LOG1, FL("VI: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d "), + pWmm->acvi_aifsn, pWmm->acvi_acm, pWmm->acvi_aci, pWmm->acvi_acwmin, pWmm->acvi_acwmax, pWmm->acvi_txoplimit); + + limLog(pMac, LOG1, FL("VO: aifsn %d, acm %d, aci %d, cwmin %d, cwmax %d, txop %d "), + pWmm->acvo_aifsn, pWmm->acvo_acm, pWmm->acvo_aci, pWmm->acvo_acwmin, pWmm->acvo_acwmax, pWmm->acvo_txoplimit); + + return; +} + +//////////////////////////////////////////////////////////////////////// +// Functions for populating "dot11f" style IEs + + +// return: >= 0, the starting location of the IE in rsnIEdata inside tSirRSNie +// < 0, cannot find +int FindIELocation( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tANI_U8 EID) +{ + int idx, ieLen, bytesLeft; + int ret_val = -1; + + // Here's what's going on: 'rsnIe' looks like this: + + // typedef struct sSirRSNie + // { + // tANI_U16 length; + // tANI_U8 rsnIEdata[SIR_MAC_MAX_IE_LENGTH+2]; + // } tSirRSNie, *tpSirRSNie; + + // other code records both the WPA & RSN IEs (including their EIDs & + // lengths) into the array 'rsnIEdata'. We may have: + + // With WAPI support, there may be 3 IEs here + // It can be only WPA IE, or only RSN IE or only WAPI IE + // Or two or all three of them with no particular ordering + + // The if/then/else statements that follow are here to figure out + // whether we have the WPA IE, and where it is if we *do* have it. + + //Save the first IE length + ieLen = pRsnIe->rsnIEdata[ 1 ] + 2; + idx = 0; + bytesLeft = pRsnIe->length; + + while( 1 ) + { + if ( EID == pRsnIe->rsnIEdata[ idx ] ) + { + //Found it + return (idx); + } + else if ( EID != pRsnIe->rsnIEdata[ idx ] && + // & if no more IE, + bytesLeft <= (tANI_U16)( ieLen ) ) + { + dot11fLog( pMac, LOG3, FL("No IE (%d) in FindIELocation."), EID ); + return ret_val; + } + bytesLeft -= ieLen; + ieLen = pRsnIe->rsnIEdata[ idx + 1 ] + 2; + idx += ieLen; + } + + return ret_val; +} + + +tSirRetStatus +PopulateDot11fCapabilities(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + tpPESession psessionEntry) +{ + tANI_U16 cfg; + tSirRetStatus nSirStatus; + + nSirStatus = cfgGetCapabilityInfo( pMac, &cfg,psessionEntry ); + if ( eSIR_SUCCESS != nSirStatus ) + { + dot11fLog( pMac, LOGP, FL("Failed to retrieve the Capabilities b" + "itfield from CFG (%d)."), nSirStatus ); + return nSirStatus; + } + +#if 0 + if ( sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_11EQOS ) ) + { + SIR_MAC_CLEAR_CAPABILITY( cfg, QOS ); + } +#endif + swapBitField16( cfg, ( tANI_U16* )pDot11f ); + + return eSIR_SUCCESS; +} // End PopulateDot11fCapabilities. + +tSirRetStatus +PopulateDot11fCapabilities2(tpAniSirGlobal pMac, + tDot11fFfCapabilities *pDot11f, + tpDphHashNode pSta, + tpPESession psessionEntry) +{ + tANI_U16 cfg; + tSirRetStatus nSirStatus; + nSirStatus = cfgGetCapabilityInfo( pMac, &cfg ,psessionEntry); + if ( eSIR_SUCCESS != nSirStatus ) + { + dot11fLog( pMac, LOGP, FL("Failed to retrieve the Capabilities b" + "itfield from CFG (%d)."), nSirStatus ); + return nSirStatus; + } + + if ( ( NULL != pSta ) && pSta->aniPeer && + PROP_CAPABILITY_GET( 11EQOS, pSta->propCapability ) ) + { + SIR_MAC_CLEAR_CAPABILITY( cfg, QOS ); + } + + swapBitField16( cfg, ( tANI_U16* )pDot11f ); + + return eSIR_SUCCESS; + +} // End PopulateDot11fCapabilities2. + +void +PopulateDot11fChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEChanSwitchAnn *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->switchMode = psessionEntry->gLimChannelSwitch.switchMode; + pDot11f->newChannel = psessionEntry->gLimChannelSwitch.primaryChannel; + pDot11f->switchCount = ( tANI_U8 ) psessionEntry->gLimChannelSwitch.switchCount; + + pDot11f->present = 1; +} // End PopulateDot11fChanSwitchAnn. + +void +PopulateDot11fExtChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEExtChanSwitchAnn *pDot11f, + tpPESession psessionEntry) +{ + //Has to be updated on the cb state basis + pDot11f->secondaryChannelOffset = + psessionEntry->gLimChannelSwitch.secondarySubBand; + + pDot11f->present = 1; +} + +#ifdef WLAN_FEATURE_11AC +void +PopulateDot11fWiderBWChanSwitchAnn(tpAniSirGlobal pMac, + tDot11fIEWiderBWChanSwitchAnn *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->present = 1; + pDot11f->newChanWidth = psessionEntry->gLimWiderBWChannelSwitch.newChanWidth; + pDot11f->newCenterChanFreq0 = psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq0; + pDot11f->newCenterChanFreq1 = psessionEntry->gLimWiderBWChannelSwitch.newCenterChanFreq1; +} +#endif + +tSirRetStatus +PopulateDot11fCountry(tpAniSirGlobal pMac, + tDot11fIECountry *pDot11f, + tpPESession psessionEntry) +{ + tANI_U32 len, maxlen, codelen; + tANI_U16 item; + tSirRetStatus nSirStatus; + tSirRFBand rfBand; + tANI_U8 temp[CFG_MAX_STR_LEN], code[3]; + + if (psessionEntry->lim11dEnabled ) + { + limGetRfBand(pMac, &rfBand, psessionEntry); + if (rfBand == SIR_BAND_5_GHZ) + { + item = WNI_CFG_MAX_TX_POWER_5; + maxlen = WNI_CFG_MAX_TX_POWER_5_LEN; + } + else + { + item = WNI_CFG_MAX_TX_POWER_2_4; + maxlen = WNI_CFG_MAX_TX_POWER_2_4_LEN; + } + + CFG_GET_STR( nSirStatus, pMac, item, temp, len, maxlen ); + + if ( 3 > len ) + { + // no limit on tx power, cannot include the IE because at least + // one (channel,num,tx power) must be present + return eSIR_SUCCESS; + } + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_COUNTRY_CODE, + code, codelen, 3 ); + + vos_mem_copy( pDot11f->country, code, codelen ); + + if(len > MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE) + { + dot11fLog( pMac, LOGE, FL("len:%d is out of bounds, resetting."), len); + len = MAX_SIZE_OF_TRIPLETS_IN_COUNTRY_IE; + } + + pDot11f->num_triplets = ( tANI_U8 ) ( len / 3 ); + vos_mem_copy( ( tANI_U8* )pDot11f->triplets, temp, len ); + + pDot11f->present = 1; + } + + return eSIR_SUCCESS; +} // End PopulateDot11fCountry. + +tSirRetStatus +PopulateDot11fDSParams(tpAniSirGlobal pMac, + tDot11fIEDSParams *pDot11f, tANI_U8 channel, + tpPESession psessionEntry) +{ + if (IS_24G_CH(channel)) + { + // .11b/g mode PHY => Include the DS Parameter Set IE: + pDot11f->curr_channel = channel; + pDot11f->present = 1; + } + + return eSIR_SUCCESS; +} // End PopulateDot11fDSParams. + +#define SET_AIFSN(aifsn) (((aifsn) < 2) ? 2 : (aifsn)) + + +void +PopulateDot11fEDCAParamSet(tpAniSirGlobal pMac, + tDot11fIEEDCAParamSet *pDot11f, + tpPESession psessionEntry) +{ + + if ( psessionEntry->limQosEnabled ) + { + //change to bitwise operation, after this is fixed in frames. + pDot11f->qos = (tANI_U8)(0xf0 & (psessionEntry->gLimEdcaParamSetCount << 4) ); + + // Fill each EDCA parameter set in order: be, bk, vi, vo + pDot11f->acbe_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn) ); + pDot11f->acbe_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm ); + pDot11f->acbe_aci = ( 0x3 & SIR_MAC_EDCAACI_BESTEFFORT ); + pDot11f->acbe_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min ); + pDot11f->acbe_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max ); + pDot11f->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit; + + pDot11f->acbk_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn) ); + pDot11f->acbk_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm ); + pDot11f->acbk_aci = ( 0x3 & SIR_MAC_EDCAACI_BACKGROUND ); + pDot11f->acbk_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min ); + pDot11f->acbk_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max ); + pDot11f->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit; + + pDot11f->acvi_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn) ); + pDot11f->acvi_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm ); + pDot11f->acvi_aci = ( 0x3 & SIR_MAC_EDCAACI_VIDEO ); + pDot11f->acvi_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min ); + pDot11f->acvi_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max ); + pDot11f->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit; + + pDot11f->acvo_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn) ); + pDot11f->acvo_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm ); + pDot11f->acvo_aci = ( 0x3 & SIR_MAC_EDCAACI_VOICE ); + pDot11f->acvo_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min ); + pDot11f->acvo_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max ); + pDot11f->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit; + + pDot11f->present = 1; + } + +} // End PopluateDot11fEDCAParamSet. + +tSirRetStatus +PopulateDot11fERPInfo(tpAniSirGlobal pMac, + tDot11fIEERPInfo *pDot11f, + tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U32 val; + tSirRFBand rfBand = SIR_BAND_UNKNOWN; + + limGetRfBand(pMac, &rfBand, psessionEntry); + if(SIR_BAND_2_4_GHZ == rfBand) + { + pDot11f->present = 1; + + val = psessionEntry->cfgProtection.fromllb; + if(!val ){ + dot11fLog( pMac, LOG1, FL("11B protection not enabled. Not populating ERP IE %d" ),val ); + return eSIR_SUCCESS; + } + + if (psessionEntry->gLim11bParams.protectionEnabled) + { + pDot11f->non_erp_present = 1; + pDot11f->use_prot = 1; + } + + if ( psessionEntry->gLimOlbcParams.protectionEnabled ) + { + //FIXME_PROTECTION: we should be setting non_erp present also. + //check the test plan first. + pDot11f->use_prot = 1; + } + + + if((psessionEntry->gLimNoShortParams.numNonShortPreambleSta) + || !psessionEntry->beaconParams.fShortPreamble){ + pDot11f->barker_preamble = 1; + + } + // if protection always flag is set, advertise protection enabled + // regardless of legacy stations presence + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_11G_PROTECTION_ALWAYS, val ); + + if ( val ) + { + pDot11f->use_prot = 1; + } + } + + return eSIR_SUCCESS; +} // End PopulateDot11fERPInfo. + +tSirRetStatus +PopulateDot11fExtSuppRates(tpAniSirGlobal pMac, tANI_U8 nChannelNum, + tDot11fIEExtSuppRates *pDot11f, + tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U32 nRates = 0; + tANI_U8 rates[SIR_MAC_RATESET_EID_MAX]; + + /* Use the ext rates present in session entry whenever nChannelNum is set to OPERATIONAL + else use the ext supported rate set from CFG, which is fixed and does not change dynamically and is used for + sending mgmt frames (lile probe req) which need to go out before any session is present. + */ + if(POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum ) + { + if(psessionEntry != NULL) + { + nRates = psessionEntry->extRateSet.numRates; + vos_mem_copy( rates, psessionEntry->extRateSet.rate, + nRates); + } + else + { + dot11fLog( pMac, LOGE, FL("no session context exists while" + " populating Operational Rate Set")); + } + } + else if ( HIGHEST_24GHZ_CHANNEL_NUM >= nChannelNum ) + { + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET, + rates, nRates, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET_LEN ); + } + + if ( 0 != nRates ) + { + pDot11f->num_rates = ( tANI_U8 )nRates; + vos_mem_copy( pDot11f->rates, rates, nRates ); + pDot11f->present = 1; + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fExtSuppRates. + +tSirRetStatus +PopulateDot11fExtSuppRates1(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIEExtSuppRates *pDot11f) +{ + tANI_U32 nRates; + tSirRetStatus nSirStatus; + tANI_U8 rates[SIR_MAC_MAX_NUMBER_OF_RATES]; + + if ( 14 < nChannelNum ) + { + pDot11f->present = 0; + return eSIR_SUCCESS; + } + + // N.B. I have *no* idea why we're calling 'wlan_cfgGetStr' with an argument + // of WNI_CFG_SUPPORTED_RATES_11A here, but that's what was done + // previously & I'm afraid to change it! + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + + if ( 0 != nRates ) + { + pDot11f->num_rates = ( tANI_U8 ) nRates; + vos_mem_copy( pDot11f->rates, rates, nRates ); + pDot11f->present = 1; + } + + return eSIR_SUCCESS; +} // PopulateDot11fExtSuppRates1. + +tSirRetStatus +PopulateDot11fHTCaps(tpAniSirGlobal pMac, + tpPESession psessionEntry, + tDot11fIEHTCaps *pDot11f) +{ + tANI_U32 nCfgValue, nCfgLen; + tANI_U8 nCfgValue8; + tSirRetStatus nSirStatus; + tSirMacHTParametersInfo *pHTParametersInfo; + union { + tANI_U16 nCfgValue16; + tSirMacHTCapabilityInfo htCapInfo; + tSirMacExtendedHTCapabilityInfo extHtCapInfo; + } uHTCapabilityInfo; + + tSirMacTxBFCapabilityInfo *pTxBFCapabilityInfo; + tSirMacASCapabilityInfo *pASCapabilityInfo; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_CAP_INFO, nCfgValue ); + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->advCodingCap = uHTCapabilityInfo.htCapInfo.advCodingCap; + pDot11f->mimoPowerSave = uHTCapabilityInfo.htCapInfo.mimoPowerSave; + pDot11f->greenField = uHTCapabilityInfo.htCapInfo.greenField; + pDot11f->shortGI20MHz = uHTCapabilityInfo.htCapInfo.shortGI20MHz; + pDot11f->shortGI40MHz = uHTCapabilityInfo.htCapInfo.shortGI40MHz; + pDot11f->txSTBC = uHTCapabilityInfo.htCapInfo.txSTBC; + pDot11f->rxSTBC = uHTCapabilityInfo.htCapInfo.rxSTBC; + pDot11f->delayedBA = uHTCapabilityInfo.htCapInfo.delayedBA; + pDot11f->maximalAMSDUsize = uHTCapabilityInfo.htCapInfo.maximalAMSDUsize; + pDot11f->dsssCckMode40MHz = uHTCapabilityInfo.htCapInfo.dsssCckMode40MHz; + pDot11f->psmp = uHTCapabilityInfo.htCapInfo.psmp; + pDot11f->stbcControlFrame = uHTCapabilityInfo.htCapInfo.stbcControlFrame; + pDot11f->lsigTXOPProtection = uHTCapabilityInfo.htCapInfo.lsigTXOPProtection; + + // All sessionized entries will need the check below + if (psessionEntry == NULL) // Only in case of NO session + { + pDot11f->supportedChannelWidthSet = uHTCapabilityInfo.htCapInfo.supportedChannelWidthSet; + } + else + { + pDot11f->supportedChannelWidthSet = psessionEntry->htSupportedChannelWidthSet; + } + + /* Ensure that shortGI40MHz is Disabled if supportedChannelWidthSet is + eHT_CHANNEL_WIDTH_20MHZ */ + if(pDot11f->supportedChannelWidthSet == eHT_CHANNEL_WIDTH_20MHZ) + { + pDot11f->shortGI40MHz = 0; + } + + + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_AMPDU_PARAMS, nCfgValue ); + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + pHTParametersInfo = ( tSirMacHTParametersInfo* ) &nCfgValue8; + + pDot11f->maxRxAMPDUFactor = pHTParametersInfo->maxRxAMPDUFactor; + pDot11f->mpduDensity = pHTParametersInfo->mpduDensity; + pDot11f->reserved1 = pHTParametersInfo->reserved; + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_MCS_SET, + pDot11f->supportedMCSSet, nCfgLen, + SIZE_OF_SUPPORTED_MCS_SET ); + + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_EXT_HT_CAP_INFO, nCfgValue ); + + uHTCapabilityInfo.nCfgValue16 = nCfgValue & 0xFFFF; + + pDot11f->pco = uHTCapabilityInfo.extHtCapInfo.pco; + pDot11f->transitionTime = uHTCapabilityInfo.extHtCapInfo.transitionTime; + pDot11f->mcsFeedback = uHTCapabilityInfo.extHtCapInfo.mcsFeedback; + + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_TX_BF_CAP, nCfgValue ); + + pTxBFCapabilityInfo = ( tSirMacTxBFCapabilityInfo* ) &nCfgValue; + pDot11f->txBF = pTxBFCapabilityInfo->txBF; + pDot11f->rxStaggeredSounding = pTxBFCapabilityInfo->rxStaggeredSounding; + pDot11f->txStaggeredSounding = pTxBFCapabilityInfo->txStaggeredSounding; + pDot11f->rxZLF = pTxBFCapabilityInfo->rxZLF; + pDot11f->txZLF = pTxBFCapabilityInfo->txZLF; + pDot11f->implicitTxBF = pTxBFCapabilityInfo->implicitTxBF; + pDot11f->calibration = pTxBFCapabilityInfo->calibration; + pDot11f->explicitCSITxBF = pTxBFCapabilityInfo->explicitCSITxBF; + pDot11f->explicitUncompressedSteeringMatrix = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrix; + pDot11f->explicitBFCSIFeedback = pTxBFCapabilityInfo->explicitBFCSIFeedback; + pDot11f->explicitUncompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitUncompressedSteeringMatrixFeedback; + pDot11f->explicitCompressedSteeringMatrixFeedback = pTxBFCapabilityInfo->explicitCompressedSteeringMatrixFeedback; + pDot11f->csiNumBFAntennae = pTxBFCapabilityInfo->csiNumBFAntennae; + pDot11f->uncompressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->uncompressedSteeringMatrixBFAntennae; + pDot11f->compressedSteeringMatrixBFAntennae = pTxBFCapabilityInfo->compressedSteeringMatrixBFAntennae; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_AS_CAP, nCfgValue ); + + nCfgValue8 = ( tANI_U8 ) nCfgValue; + + pASCapabilityInfo = ( tSirMacASCapabilityInfo* ) &nCfgValue8; + pDot11f->antennaSelection = pASCapabilityInfo->antennaSelection; + pDot11f->explicitCSIFeedbackTx = pASCapabilityInfo->explicitCSIFeedbackTx; + pDot11f->antennaIndicesFeedbackTx = pASCapabilityInfo->antennaIndicesFeedbackTx; + pDot11f->explicitCSIFeedback = pASCapabilityInfo->explicitCSIFeedback; + pDot11f->antennaIndicesFeedback = pASCapabilityInfo->antennaIndicesFeedback; + pDot11f->rxAS = pASCapabilityInfo->rxAS; + pDot11f->txSoundingPPDUs = pASCapabilityInfo->txSoundingPPDUs; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fHTCaps. +#ifdef WLAN_FEATURE_11AC + +void limLogVHTCap(tpAniSirGlobal pMac, + tDot11fIEVHTCaps *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("maxMPDULen (2): %d"), pDot11f->maxMPDULen); + limLog(pMac, LOG1, FL("supportedChannelWidthSet (2): %d"), pDot11f->supportedChannelWidthSet); + limLog(pMac, LOG1, FL("ldpcCodingCap (1): %d"), pDot11f->ldpcCodingCap); + limLog(pMac, LOG1, FL("shortGI80MHz (1): %d"), pDot11f->shortGI80MHz); + limLog(pMac, LOG1, FL("shortGI160and80plus80MHz (1): %d"), pDot11f->shortGI160and80plus80MHz); + limLog(pMac, LOG1, FL("txSTBC (1): %d"), pDot11f->txSTBC); + limLog(pMac, LOG1, FL("rxSTBC (3): %d"), pDot11f->rxSTBC); + limLog(pMac, LOG1, FL("suBeamFormerCap (1): %d"), pDot11f->suBeamFormerCap); + limLog(pMac, LOG1, FL("suBeamformeeCap (1): %d"), pDot11f->suBeamformeeCap); + limLog(pMac, LOG1, FL("csnofBeamformerAntSup (3): %d"), pDot11f->csnofBeamformerAntSup); + limLog(pMac, LOG1, FL("numSoundingDim (3): %d"), pDot11f->numSoundingDim); + limLog(pMac, LOG1, FL("muBeamformerCap (1): %d"), pDot11f->muBeamformerCap); + limLog(pMac, LOG1, FL("muBeamformeeCap (1): %d"), pDot11f->muBeamformeeCap); + limLog(pMac, LOG1, FL("vhtTXOPPS (1): %d"), pDot11f->vhtTXOPPS); + limLog(pMac, LOG1, FL("htcVHTCap (1): %d"), pDot11f->htcVHTCap); + limLog(pMac, LOG1, FL("maxAMPDULenExp (3): %d"), pDot11f->maxAMPDULenExp); + limLog(pMac, LOG1, FL("vhtLinkAdaptCap (2): %d"), pDot11f->vhtLinkAdaptCap); + limLog(pMac, LOG1, FL("rxAntPattern (1): %d"), pDot11f->vhtLinkAdaptCap); + limLog(pMac, LOG1, FL("txAntPattern (1): %d"), pDot11f->vhtLinkAdaptCap); + limLog(pMac, LOG1, FL("reserved1 (2): %d"), pDot11f->reserved1); + limLog(pMac, LOG1, FL("rxMCSMap (16): %d"), pDot11f->rxMCSMap); + limLog(pMac, LOG1, FL("rxHighSupDataRate (13): %d"), pDot11f->rxHighSupDataRate); + limLog(pMac, LOG1, FL("reserve (3): %d"), pDot11f->reserved2); + limLog(pMac, LOG1, FL("txMCSMap (16): %d"), pDot11f->txMCSMap); + limLog(pMac, LOG1, FL("txSupDataRate (13): %d"), pDot11f->txSupDataRate); + limLog(pMac, LOG1, FL("reserv (3): %d"), pDot11f->reserved3); +#endif /* DUMP_MGMT_CNTNTS */ +} + +void limLogVHTOperation(tpAniSirGlobal pMac, + tDot11fIEVHTOperation *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("chanWidth : %d"), pDot11f->chanWidth); + limLog(pMac, LOG1, FL("chanCenterFreqSeg1: %d"), pDot11f->chanCenterFreqSeg1); + limLog(pMac, LOG1, FL("chanCenterFreqSeg2: %d"), pDot11f->chanCenterFreqSeg2); + limLog(pMac, LOG1, FL("basicMCSSet: %d"), pDot11f->basicMCSSet); +#endif /* DUMP_MGMT_CNTNTS */ +} + +void limLogVHTExtBssLoad(tpAniSirGlobal pMac, + tDot11fIEVHTExtBssLoad *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("muMIMOCapStaCount : %d"), pDot11f->muMIMOCapStaCount); + limLog(pMac, LOG1, FL("ssUnderUtil: %d"), pDot11f->ssUnderUtil); + limLog(pMac, LOG1, FL("FortyMHzUtil: %d"), pDot11f->FortyMHzUtil); + limLog(pMac, LOG1, FL("EightyMHzUtil: %d"), pDot11f->EightyMHzUtil); + limLog(pMac, LOG1, FL("OneSixtyMHzUtil: %d"), pDot11f->OneSixtyMHzUtil); +#endif /* DUMP_MGMT_CNTNTS */ +} + + +void limLogOperatingMode( tpAniSirGlobal pMac, + tDot11fIEOperatingMode *pDot11f) +{ +#ifdef DUMP_MGMT_CNTNTS + limLog(pMac, LOG1, FL("ChanWidth : %d"), pDot11f->chanWidth); + limLog(pMac, LOG1, FL("reserved: %d"), pDot11f->reserved); + limLog(pMac, LOG1, FL("rxNSS: %d"), pDot11f->rxNSS); + limLog(pMac, LOG1, FL("rxNSS Type: %d"), pDot11f->rxNSSType); +#endif /* DUMP_MGMT_CNTNTS */ +} + +void limLogQosMapSet(tpAniSirGlobal pMac, tSirQosMapSet *pQosMapSet) +{ + tANI_U8 i; + if (pQosMapSet->num_dscp_exceptions > 21) + pQosMapSet->num_dscp_exceptions = 21; + limLog(pMac, LOG1, FL("num of dscp exceptions : %d"), + pQosMapSet->num_dscp_exceptions); + for (i=0; i < pQosMapSet->num_dscp_exceptions; i++) + { + limLog(pMac, LOG1, FL("dscp value: %d"), + pQosMapSet->dscp_exceptions[i][0]); + limLog(pMac, LOG1, FL("User priority value: %d"), + pQosMapSet->dscp_exceptions[i][1]); + } + for (i=0;i<8;i++) + { + limLog(pMac, LOG1, FL("dscp low for up %d: %d"),i, + pQosMapSet->dscp_range[i][0]); + limLog(pMac, LOG1, FL("dscp high for up %d: %d"),i, + pQosMapSet->dscp_range[i][1]); + } +} + +tSirRetStatus +PopulateDot11fVHTCaps(tpAniSirGlobal pMac, + tDot11fIEVHTCaps *pDot11f, + tANI_U8 nChannelNum, + tAniBool isProbeRspAssocRspBeacon) +{ + tSirRetStatus nStatus; + tANI_U32 nCfgValue=0; + tAniBool disableMcs9 = eSIR_FALSE; + + if (nChannelNum <= SIR_11B_CHANNEL_END) + disableMcs9 = pMac->roam.configParam.channelBondingMode24GHz? + eSIR_FALSE:eSIR_TRUE; + else + disableMcs9 = + pMac->roam.configParam.channelBondingMode5GHz? + eSIR_FALSE: eSIR_TRUE; + pDot11f->present = 1; + + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MAX_MPDU_LENGTH, nCfgValue ); + pDot11f->maxMPDULen = (nCfgValue & 0x0003); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SUPPORTED_CHAN_WIDTH_SET, + nCfgValue ); + pDot11f->supportedChannelWidthSet = (nCfgValue & 0x0003); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_LDPC_CODING_CAP, nCfgValue ); + pDot11f->ldpcCodingCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SHORT_GI_80MHZ, nCfgValue ); + pDot11f->shortGI80MHz= (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SHORT_GI_160_AND_80_PLUS_80MHZ, + nCfgValue ); + pDot11f->shortGI160and80plus80MHz = (nCfgValue & 0x0001); + + if (nChannelNum && (SIR_BAND_2_4_GHZ == limGetRFBand(nChannelNum))) + { + pDot11f->shortGI80MHz = 0; + pDot11f->shortGI160and80plus80MHz = 0; + } + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TXSTBC, nCfgValue ); + pDot11f->txSTBC = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RXSTBC, nCfgValue ); + pDot11f->rxSTBC = (nCfgValue & 0x0007); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SU_BEAMFORMER_CAP, nCfgValue ); + pDot11f->suBeamFormerCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SU_BEAMFORMEE_CAP, nCfgValue ); + pDot11f->suBeamformeeCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, + nCfgValue ); + pDot11f->csnofBeamformerAntSup = (nCfgValue & 0x0007); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_NUM_SOUNDING_DIMENSIONS, + nCfgValue ); + pDot11f->numSoundingDim = (nCfgValue & 0x0007); + + /* muBeamformerCap should be 0 for non AP and + * muBeamformeeCap should be 0 for AP + */ + if(eSIR_TRUE == isProbeRspAssocRspBeacon) + { + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MU_BEAMFORMER_CAP, nCfgValue ); + pDot11f->muBeamformerCap = (nCfgValue & 0x0001); + pDot11f->muBeamformeeCap = 0; + } + else + { + pDot11f->muBeamformerCap = 0; + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MU_BEAMFORMEE_CAP, nCfgValue ); + /* Enable only if FW and host both support the MU_MIMO feature + */ + pDot11f->muBeamformeeCap = IS_MUMIMO_BFORMEE_CAPABLE ? (nCfgValue & 0x0001): 0; + } + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TXOP_PS, nCfgValue ); + pDot11f->vhtTXOPPS = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_HTC_VHTC_CAP, nCfgValue ); + pDot11f->htcVHTCap = (nCfgValue & 0x0001); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, nCfgValue ); + pDot11f->maxAMPDULenExp = (nCfgValue & 0x0007); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_LINK_ADAPTATION_CAP, nCfgValue ); + pDot11f->vhtLinkAdaptCap = (nCfgValue & 0x0003); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RX_ANT_PATTERN, nCfgValue ); + pDot11f->rxAntPattern = nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_ANT_PATTERN, nCfgValue ); + pDot11f->txAntPattern = nCfgValue; + + pDot11f->reserved1= 0; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RX_MCS_MAP, nCfgValue ); + + if (eSIR_TRUE == disableMcs9) + nCfgValue = (nCfgValue & 0xFFFC) | 0x1; + pDot11f->rxMCSMap = (nCfgValue & 0x0000FFFF); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE, + nCfgValue ); + pDot11f->rxHighSupDataRate = (nCfgValue & 0x00001FFF); + + pDot11f->reserved2= 0; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_MCS_MAP, nCfgValue ); + + if (eSIR_TRUE == disableMcs9) + nCfgValue = (nCfgValue & 0xFFFC) | 0x1; + pDot11f->txMCSMap = (nCfgValue & 0x0000FFFF); + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE, + nCfgValue ); + pDot11f->txSupDataRate = (nCfgValue & 0x00001FFF); + + pDot11f->reserved3= 0; + + limLogVHTCap(pMac, pDot11f); + + return eSIR_SUCCESS; + +} + +tSirRetStatus +PopulateDot11fVHTOperation(tpAniSirGlobal pMac, + tDot11fIEVHTOperation *pDot11f, + tANI_U8 nChannelNum) +{ + tSirRetStatus nStatus; + tANI_U32 nCfgValue=0; + tAniBool disableMcs9 = eSIR_FALSE; + + if (nChannelNum <= SIR_11B_CHANNEL_END) + disableMcs9 = pMac->roam.configParam.channelBondingMode24GHz? + eSIR_FALSE:eSIR_TRUE; + else + disableMcs9 = + pMac->roam.configParam.channelBondingMode5GHz? + eSIR_FALSE: eSIR_TRUE; + + pDot11f->present = 1; + + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CHANNEL_WIDTH, nCfgValue ); + pDot11f->chanWidth = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT1, + nCfgValue ); + pDot11f->chanCenterFreqSeg1 = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_CHANNEL_CENTER_FREQ_SEGMENT2, + nCfgValue ); + pDot11f->chanCenterFreqSeg2 = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_BASIC_MCS_SET,nCfgValue ); + + if (eSIR_TRUE == disableMcs9) + nCfgValue = (nCfgValue & 0xFFFC) | 0x1; + pDot11f->basicMCSSet = (tANI_U16)nCfgValue; + + limLogVHTOperation(pMac,pDot11f); + + return eSIR_SUCCESS; + +} + +tSirRetStatus +PopulateDot11fVHTExtBssLoad(tpAniSirGlobal pMac, + tDot11fIEVHTExtBssLoad *pDot11f) +{ + tSirRetStatus nStatus; + tANI_U32 nCfgValue=0; + + pDot11f->present = 1; + + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_MU_MIMO_CAP_STA_COUNT, + nCfgValue ); + pDot11f->muMIMOCapStaCount = (tANI_U8)nCfgValue; + + nCfgValue = 0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_SS_UNDER_UTIL,nCfgValue ); + pDot11f->ssUnderUtil = (tANI_U8)nCfgValue; + + nCfgValue=0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_40MHZ_UTILIZATION,nCfgValue ); + pDot11f->FortyMHzUtil = (tANI_U8)nCfgValue; + + nCfgValue=0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_80MHZ_UTILIZATION,nCfgValue ); + pDot11f->EightyMHzUtil = (tANI_U8)nCfgValue; + + nCfgValue=0; + CFG_GET_INT( nStatus, pMac, WNI_CFG_VHT_160MHZ_UTILIZATION,nCfgValue ); + pDot11f->EightyMHzUtil = (tANI_U8)nCfgValue; + + limLogVHTExtBssLoad(pMac,pDot11f); + + return eSIR_SUCCESS; +} + +#ifdef WLAN_FEATURE_AP_HT40_24G +tSirRetStatus +PopulateDot11fOBSSScanParameters(tpAniSirGlobal pMac, + tDot11fIEOBSSScanParameters *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->present = 1; + + pDot11f->obssScanPassiveDwell = + psessionEntry->obssHT40ScanParam.OBSSScanPassiveDwellTime; + + pDot11f->obssScanActiveDwell = + psessionEntry->obssHT40ScanParam.OBSSScanActiveDwellTime; + + pDot11f->bssChannelWidthTriggerScanInterval = + psessionEntry->obssHT40ScanParam.BSSChannelWidthTriggerScanInterval; + + pDot11f->obssScanPassiveTotalPerChannel = + psessionEntry->obssHT40ScanParam.OBSSScanPassiveTotalPerChannel; + + pDot11f->obssScanActiveTotalPerChannel = + psessionEntry->obssHT40ScanParam.OBSSScanActiveTotalPerChannel; + + pDot11f->bssWidthChannelTransitionDelayFactor = + psessionEntry->obssHT40ScanParam.BSSWidthChannelTransitionDelayFactor; + + pDot11f->obssScanActivityThreshold = + psessionEntry->obssHT40ScanParam.OBSSScanActivityThreshold; + + return eSIR_SUCCESS; +} +#endif + +tSirRetStatus +PopulateDot11fExtCap(tpAniSirGlobal pMac, + tDot11fIEExtCap *pDot11f, + tpPESession psessionEntry) +{ + struct s_ext_cap *p_ext_cap = (struct s_ext_cap *)pDot11f->bytes; + +#ifdef WLAN_FEATURE_11AC + if (psessionEntry->vhtCapability && + psessionEntry->limSystemRole != eLIM_STA_IN_IBSS_ROLE ) + { + p_ext_cap->operModeNotification = 1; + pDot11f->present = 1; + } +#endif + /* while operating in 2.4GHz only then STA need to advertize + the bss co-ex capability*/ + if (psessionEntry->currentOperChannel <= RF_CHAN_14) + { +#ifdef WLAN_FEATURE_AP_HT40_24G + if(((IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + && pMac->roam.configParam.channelBondingMode24GHz) + || pMac->roam.configParam.apHT40_24GEnabled) +#else + if((IS_HT40_OBSS_SCAN_FEATURE_ENABLE) + && pMac->roam.configParam.channelBondingMode24GHz) +#endif + { + p_ext_cap->bssCoexistMgmtSupport = 1; + pDot11f->present = 1; + } + } + + if (pDot11f->present) + { + /* Need to compute the num_bytes based on bits set */ + pDot11f->num_bytes = lim_compute_ext_cap_ie_length(pDot11f); + } + return eSIR_SUCCESS; +} + +tSirRetStatus +PopulateDot11fOperatingMode(tpAniSirGlobal pMac, + tDot11fIEOperatingMode *pDot11f, + tpPESession psessionEntry) +{ + pDot11f->present = 1; + + pDot11f->chanWidth = psessionEntry->gLimOperatingMode.chanWidth; + pDot11f->rxNSS = psessionEntry->gLimOperatingMode.rxNSS; + pDot11f->rxNSSType = psessionEntry->gLimOperatingMode.rxNSSType; + + return eSIR_SUCCESS; +} + +#endif +tSirRetStatus +PopulateDot11fHTInfo(tpAniSirGlobal pMac, + tDot11fIEHTInfo *pDot11f, + tpPESession psessionEntry ) +{ + tANI_U32 nCfgValue, nCfgLen; + tANI_U8 htInfoField1; + tANI_U16 htInfoField2; + tSirRetStatus nSirStatus; + tSirMacHTInfoField1 *pHTInfoField1; + tSirMacHTInfoField2 *pHTInfoField2; + union { + tANI_U16 nCfgValue16; + tSirMacHTInfoField3 infoField3; + }uHTInfoField; + union { + tANI_U16 nCfgValue16; + tSirMacHTInfoField2 infoField2; + }uHTInfoField2={0}; + + + #if 0 + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_CURRENT_CHANNEL, nCfgValue ); + #endif // TO SUPPORT BT-AMP + + if (NULL == psessionEntry) + { + PELOGE(limLog(pMac, LOG1, + FL("Invalid session entry in PopulateDot11fHTInfo()"));) + return eSIR_FAILURE; + } + + pDot11f->primaryChannel = psessionEntry->currentOperChannel; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD1, nCfgValue ); + + htInfoField1 = ( tANI_U8 ) nCfgValue; + + pHTInfoField1 = ( tSirMacHTInfoField1* ) &htInfoField1; + pHTInfoField1->rifsMode = psessionEntry->beaconParams.fRIFSMode; + pHTInfoField1->serviceIntervalGranularity = pMac->lim.gHTServiceIntervalGranularity; + + if (psessionEntry == NULL) + { + PELOGE(limLog(pMac, LOG1, + FL("Keep the value retrieved from cfg for secondary channel offset and recommended Tx Width set"));) + } + else + { + pHTInfoField1->secondaryChannelOffset = psessionEntry->htSecondaryChannelOffset; + pHTInfoField1->recommendedTxWidthSet = psessionEntry->htRecommendedTxWidthSet; + } + + if((psessionEntry) && (psessionEntry->limSystemRole == eLIM_AP_ROLE)){ + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2, nCfgValue ); + + uHTInfoField2.nCfgValue16 = nCfgValue & 0xFFFF; // this is added for fixing CRs on MDM9K platform - 257951, 259577 + + uHTInfoField2.infoField2.opMode = psessionEntry->htOperMode; + uHTInfoField2.infoField2.nonGFDevicesPresent = psessionEntry->beaconParams.llnNonGFCoexist; + uHTInfoField2.infoField2.obssNonHTStaPresent = psessionEntry->beaconParams.gHTObssMode; /*added for Obss */ + + uHTInfoField2.infoField2.reserved = 0; + + }else{ + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD2, nCfgValue ); + + htInfoField2 = ( tANI_U16 ) nCfgValue; + + pHTInfoField2 = ( tSirMacHTInfoField2* ) &htInfoField2; + pHTInfoField2->opMode = pMac->lim.gHTOperMode; + pHTInfoField2->nonGFDevicesPresent = pMac->lim.gHTNonGFDevicesPresent; + pHTInfoField2->obssNonHTStaPresent = pMac->lim.gHTObssMode; /*added for Obss */ + + pHTInfoField2->reserved = 0; + } + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_HT_INFO_FIELD3, nCfgValue ); + + + uHTInfoField.nCfgValue16 = nCfgValue & 0xFFFF; + + + uHTInfoField.infoField3.basicSTBCMCS = pMac->lim.gHTSTBCBasicMCS; + uHTInfoField.infoField3.dualCTSProtection = pMac->lim.gHTDualCTSProtection; + uHTInfoField.infoField3.secondaryBeacon = pMac->lim.gHTSecondaryBeacon; + uHTInfoField.infoField3.lsigTXOPProtectionFullSupport = psessionEntry->beaconParams.fLsigTXOPProtectionFullSupport; + uHTInfoField.infoField3.pcoActive = pMac->lim.gHTPCOActive; + uHTInfoField.infoField3.pcoPhase = pMac->lim.gHTPCOPhase; + uHTInfoField.infoField3.reserved = 0; + + + pDot11f->secondaryChannelOffset = pHTInfoField1->secondaryChannelOffset; + pDot11f->recommendedTxWidthSet = pHTInfoField1->recommendedTxWidthSet; + pDot11f->rifsMode = pHTInfoField1->rifsMode; + pDot11f->controlledAccessOnly = pHTInfoField1->controlledAccessOnly; + pDot11f->serviceIntervalGranularity = pHTInfoField1->serviceIntervalGranularity; + + pDot11f->opMode = uHTInfoField2.infoField2.opMode; + pDot11f->nonGFDevicesPresent = uHTInfoField2.infoField2.nonGFDevicesPresent; + pDot11f->obssNonHTStaPresent = uHTInfoField2.infoField2.obssNonHTStaPresent; + pDot11f->reserved = uHTInfoField2.infoField2.reserved; + + + pDot11f->basicSTBCMCS = uHTInfoField.infoField3.basicSTBCMCS; + pDot11f->dualCTSProtection = uHTInfoField.infoField3.dualCTSProtection; + pDot11f->secondaryBeacon = uHTInfoField.infoField3.secondaryBeacon; + pDot11f->lsigTXOPProtectionFullSupport = uHTInfoField.infoField3.lsigTXOPProtectionFullSupport; + pDot11f->pcoActive = uHTInfoField.infoField3.pcoActive; + pDot11f->pcoPhase = uHTInfoField.infoField3.pcoPhase; + pDot11f->reserved2 = uHTInfoField.infoField3.reserved; + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_BASIC_MCS_SET, + pDot11f->basicMCSSet, nCfgLen, + SIZE_OF_BASIC_MCS_SET ); + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fHTInfo. + +void +PopulateDot11fIBSSParams(tpAniSirGlobal pMac, + tDot11fIEIBSSParams *pDot11f, tpPESession psessionEntry) +{ + if ( eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + pDot11f->present = 1; + // ATIM duration is always set to 0 + pDot11f->atim = 0; + } + +} // End PopulateDot11fIBSSParams. + + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +PopulateDot11fMeasurementReport0(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f) +{ + pDot11f->token = pReq->measReqIE.measToken; + pDot11f->late = 0; + pDot11f->incapable = 0; + pDot11f->refused = 1; + pDot11f->type = SIR_MAC_BASIC_MEASUREMENT_TYPE; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulatedDot11fMeasurementReport0. + +tSirRetStatus +PopulateDot11fMeasurementReport1(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f) +{ + pDot11f->token = pReq->measReqIE.measToken; + pDot11f->late = 0; + pDot11f->incapable = 0; + pDot11f->refused = 1; + pDot11f->type = SIR_MAC_CCA_MEASUREMENT_TYPE; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulatedDot11fMeasurementReport1. + +tSirRetStatus +PopulateDot11fMeasurementReport2(tpAniSirGlobal pMac, + tpSirMacMeasReqActionFrame pReq, + tDot11fIEMeasurementReport *pDot11f) +{ + pDot11f->token = pReq->measReqIE.measToken; + pDot11f->late = 0; + pDot11f->incapable = 0; + pDot11f->refused = 1; + pDot11f->type = SIR_MAC_RPI_MEASUREMENT_TYPE; + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulatedDot11fMeasurementReport2. +#endif + +void +PopulateDot11fPowerCaps(tpAniSirGlobal pMac, + tDot11fIEPowerCaps *pCaps, + tANI_U8 nAssocType, + tpPESession psessionEntry) +{ + if (nAssocType == LIM_REASSOC) + { + pCaps->minTxPower = psessionEntry->pLimReAssocReq->powerCap.minTxPower; + pCaps->maxTxPower = psessionEntry->pLimReAssocReq->powerCap.maxTxPower; + }else + { + pCaps->minTxPower = psessionEntry->pLimJoinReq->powerCap.minTxPower; + pCaps->maxTxPower = psessionEntry->pLimJoinReq->powerCap.maxTxPower; + + } + + pCaps->present = 1; +} // End PopulateDot11fPowerCaps. + +tSirRetStatus +PopulateDot11fPowerConstraints(tpAniSirGlobal pMac, + tDot11fIEPowerConstraints *pDot11f) +{ + tANI_U32 cfg; + tSirRetStatus nSirStatus; + + CFG_GET_INT( nSirStatus, pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, cfg ); + + pDot11f->localPowerConstraints = ( tANI_U8 )cfg; + pDot11f->present = 1; + + return eSIR_SUCCESS; +} // End PopulateDot11fPowerConstraints. + +void +PopulateDot11fQOSCapsAp(tpAniSirGlobal pMac, + tDot11fIEQOSCapsAp *pDot11f, tpPESession psessionEntry) +{ + pDot11f->count = psessionEntry->gLimEdcaParamSetCount; + pDot11f->reserved = 0; + pDot11f->txopreq = 0; + pDot11f->qreq = 0; + pDot11f->qack = 0; + pDot11f->present = 1; +} // End PopulatedDot11fQOSCaps. + +void +PopulateDot11fQOSCapsStation(tpAniSirGlobal pMac, + tDot11fIEQOSCapsStation *pDot11f) +{ + tANI_U32 val = 0; + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max SP Length "));) + + pDot11f->more_data_ack = 0; + pDot11f->max_sp_length = (tANI_U8)val; + pDot11f->qack = 0; + + if (pMac->lim.gUapsdEnable) + { + pDot11f->acbe_uapsd = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + pDot11f->acbk_uapsd = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + pDot11f->acvi_uapsd = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + pDot11f->acvo_uapsd = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + pDot11f->present = 1; +} // End PopulatedDot11fQOSCaps. + +tSirRetStatus +PopulateDot11fRSN(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSN *pDot11f) +{ + tANI_U32 status; + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_RSN ) ) ) + { + status = dot11fUnpackIeRSN( pMac, + pRsnIe->rsnIEdata + idx + 2, //EID, length + pRsnIe->rsnIEdata[ idx + 1 ], + pDot11f ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog( pMac, LOGE, FL("Parse failure in PopulateDot11fRS" + "N (0x%08x)."), + status ); + return eSIR_FAILURE; + } + dot11fLog( pMac, LOG2, FL("dot11fUnpackIeRSN returned 0x%08x in " + "PopulateDot11fRSN."), status ); + } + + } + + return eSIR_SUCCESS; +} // End PopulateDot11fRSN. + +tSirRetStatus PopulateDot11fRSNOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIERSNOpaque *pDot11f ) +{ + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_RSN ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pRsnIe->rsnIEdata[ idx + 1 ]; + vos_mem_copy( pDot11f->data, + pRsnIe->rsnIEdata + idx + 2, // EID, len + pRsnIe->rsnIEdata[ idx + 1 ] ); + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fRSNOpaque. + + + +#if defined(FEATURE_WLAN_WAPI) + +tSirRetStatus +PopulateDot11fWAPI(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPI *pDot11f) + { + tANI_U32 status; + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WAPI ) ) ) + { + status = dot11fUnpackIeWAPI( pMac, + pRsnIe->rsnIEdata + idx + 2, //EID, length + pRsnIe->rsnIEdata[ idx + 1 ], + pDot11f ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog( pMac, LOGE, FL("Parse failure in PopulateDot11fWAPI (0x%08x)."), + status ); + return eSIR_FAILURE; + } + dot11fLog( pMac, LOG2, FL("dot11fUnpackIeRSN returned 0x%08x in " + "PopulateDot11fWAPI."), status ); + } + } + + return eSIR_SUCCESS; +} // End PopulateDot11fWAPI. + +tSirRetStatus PopulateDot11fWAPIOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWAPIOpaque *pDot11f ) +{ + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WAPI ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pRsnIe->rsnIEdata[ idx + 1 ]; + vos_mem_copy ( pDot11f->data, + pRsnIe->rsnIEdata + idx + 2, // EID, len + pRsnIe->rsnIEdata[ idx + 1 ] ); + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fWAPIOpaque. + + +#endif //defined(FEATURE_WLAN_WAPI) + +void +PopulateDot11fSSID(tpAniSirGlobal pMac, + tSirMacSSid *pInternal, + tDot11fIESSID *pDot11f) +{ + pDot11f->present = 1; + pDot11f->num_ssid = pInternal->length; + if ( pInternal->length ) + { + vos_mem_copy( ( tANI_U8* )pDot11f->ssid, ( tANI_U8* )&pInternal->ssId, + pInternal->length ); + } +} // End PopulateDot11fSSID. + +tSirRetStatus +PopulateDot11fSSID2(tpAniSirGlobal pMac, + tDot11fIESSID *pDot11f) +{ + tANI_U32 nCfg; + tSirRetStatus nSirStatus; + + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SSID, pDot11f->ssid, nCfg, 32 ); + pDot11f->num_ssid = ( tANI_U8 )nCfg; + pDot11f->present = 1; + return eSIR_SUCCESS; +} // End PopulateDot11fSSID2. + +void +PopulateDot11fSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIESchedule *pDot11f) +{ + pDot11f->aggregation = pSchedule->info.aggregation; + pDot11f->tsid = pSchedule->info.tsid; + pDot11f->direction = pSchedule->info.direction; + pDot11f->reserved = pSchedule->info.rsvd; + pDot11f->service_start_time = pSchedule->svcStartTime; + pDot11f->service_interval = pSchedule->svcInterval; + pDot11f->max_service_dur = pSchedule->maxSvcDuration; + pDot11f->spec_interval = pSchedule->specInterval; + + pDot11f->present = 1; +} // End PopulateDot11fSchedule. + +void +PopulateDot11fSuppChannels(tpAniSirGlobal pMac, + tDot11fIESuppChannels *pDot11f, + tANI_U8 nAssocType, + tpPESession psessionEntry) +{ + tANI_U8 i; + tANI_U8 *p; + + if (nAssocType == LIM_REASSOC) + { + p = ( tANI_U8* )psessionEntry->pLimReAssocReq->supportedChannels.channelList; + pDot11f->num_bands = psessionEntry->pLimReAssocReq->supportedChannels.numChnl; + }else + { + p = ( tANI_U8* )psessionEntry->pLimJoinReq->supportedChannels.channelList; + pDot11f->num_bands = psessionEntry->pLimJoinReq->supportedChannels.numChnl; + } + for ( i = 0U; i < pDot11f->num_bands; ++i, ++p) + { + pDot11f->bands[i][0] = *p; + pDot11f->bands[i][1] = 1; + } + + pDot11f->present = 1; + +} // End PopulateDot11fSuppChannels. + +tSirRetStatus +PopulateDot11fSuppRates(tpAniSirGlobal pMac, + tANI_U8 nChannelNum, + tDot11fIESuppRates *pDot11f,tpPESession psessionEntry) +{ + tSirRetStatus nSirStatus; + tANI_U32 nRates; + tANI_U8 rates[SIR_MAC_MAX_NUMBER_OF_RATES]; + + /* Use the operational rates present in session entry whenever nChannelNum is set to OPERATIONAL + else use the supported rate set from CFG, which is fixed and does not change dynamically and is used for + sending mgmt frames (lile probe req) which need to go out before any session is present. + */ + if(POPULATE_DOT11F_RATES_OPERATIONAL == nChannelNum ) + { + #if 0 + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_OPERATIONAL_RATE_SET, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + #endif //TO SUPPORT BT-AMP + if(psessionEntry != NULL) + { + nRates = psessionEntry->rateSet.numRates; + vos_mem_copy( rates, psessionEntry->rateSet.rate, + nRates); + } + else + { + dot11fLog( pMac, LOGE, FL("no session context exists while populating Operational Rate Set")); + nRates = 0; + } + } + else if ( 14 >= nChannelNum ) + { + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11B, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + } + else + { + CFG_GET_STR( nSirStatus, pMac, WNI_CFG_SUPPORTED_RATES_11A, + rates, nRates, SIR_MAC_MAX_NUMBER_OF_RATES ); + } + + if ( 0 != nRates ) + { + pDot11f->num_rates = ( tANI_U8 )nRates; + vos_mem_copy( pDot11f->rates, rates, nRates ); + pDot11f->present = 1; + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fSuppRates. + +/** + * PopulateDot11fRatesTdls() - populate supported rates and + * extended supported rates IE. + * @p_mac gloabl - header. + * @p_supp_rates - pointer to supported rates IE + * @p_ext_supp_rates - pointer to extended supported rates IE + * + * This function populates the supported rates and extended supported + * rates IE based in the STA capability. If the number of rates + * supported is less than MAX_NUM_SUPPORTED_RATES, only supported rates + * IE is populated. + * + * Return: tSirRetStatus eSIR_SUCCESS on Success and eSIR_FAILURE + * on failure. + */ + +tSirRetStatus +PopulateDot11fRatesTdls(tpAniSirGlobal p_mac, + tDot11fIESuppRates *p_supp_rates, + tDot11fIEExtSuppRates *p_ext_supp_rates, + tANI_U8 curr_oper_channel) +{ + tSirMacRateSet temp_rateset; + tSirMacRateSet temp_rateset2; + uint32_t val, i; + uint32_t self_dot11mode = 0; + + wlan_cfgGetInt(p_mac, WNI_CFG_DOT11_MODE, &self_dot11mode); + + /** + * Include 11b rates only when the device configured + * in auto, 11a/b/g or 11b_only and also if current base + * channel is 5 GHz then no need to advertise the 11b rates. + * If devices to move 2.4GHz off-channel then they can communicate + * in 11g rates i.e. (6, 9, 12, 18, 24, 36 and 54). + */ + limLog(p_mac, LOG1, FL("Current operating channel %d self_dot11mode = %d"), + curr_oper_channel, self_dot11mode); + + if ((curr_oper_channel <= SIR_11B_CHANNEL_END) && + ((self_dot11mode == WNI_CFG_DOT11_MODE_ALL) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11A) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11AC) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11N) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11G) || + (self_dot11mode == WNI_CFG_DOT11_MODE_11B))) + { + val = WNI_CFG_SUPPORTED_RATES_11B_LEN; + wlan_cfgGetStr(p_mac, WNI_CFG_SUPPORTED_RATES_11B, + (tANI_U8 *)&temp_rateset.rate, &val); + temp_rateset.numRates = (tANI_U8) val; + } + else + { + temp_rateset.numRates = 0; + } + + /* Include 11a rates when the device configured in non-11b mode */ + if (!IS_DOT11_MODE_11B(self_dot11mode)) + { + val = WNI_CFG_SUPPORTED_RATES_11A_LEN; + wlan_cfgGetStr(p_mac, WNI_CFG_SUPPORTED_RATES_11A, + (tANI_U8 *)&temp_rateset2.rate, &val); + temp_rateset2.numRates = (tANI_U8) val; + } + else + { + temp_rateset2.numRates = 0; + } + + if ((temp_rateset.numRates + temp_rateset2.numRates) > + SIR_MAC_MAX_NUMBER_OF_RATES) + { + limLog(p_mac, LOGP, FL("more than %d rates in CFG"), + SIR_MAC_MAX_NUMBER_OF_RATES); + return eSIR_FAILURE; + } + + /** + * copy all rates in temp_rateset, + * there are SIR_MAC_MAX_NUMBER_OF_RATES rates max + */ + for (i = 0; i < temp_rateset2.numRates; i++) + temp_rateset.rate[i + temp_rateset.numRates] = + temp_rateset2.rate[i]; + + temp_rateset.numRates += temp_rateset2.numRates; + + if (temp_rateset.numRates <= MAX_NUM_SUPPORTED_RATES) + { + p_supp_rates->num_rates = temp_rateset.numRates; + vos_mem_copy(p_supp_rates->rates, temp_rateset.rate, + p_supp_rates->num_rates); + p_supp_rates->present = 1; + } + else /* Populate extended capability as well */ + { + p_supp_rates->num_rates = MAX_NUM_SUPPORTED_RATES; + vos_mem_copy(p_supp_rates->rates, temp_rateset.rate, + p_supp_rates->num_rates); + p_supp_rates->present = 1; + p_ext_supp_rates->num_rates = temp_rateset.numRates - + MAX_NUM_SUPPORTED_RATES; + vos_mem_copy(p_ext_supp_rates->rates, + (tANI_U8 *)temp_rateset.rate + + MAX_NUM_SUPPORTED_RATES, + p_ext_supp_rates->num_rates); + p_ext_supp_rates->present = 1; + } + + return eSIR_SUCCESS; + +} /* End PopulateDot11fRatesTdls */ + +tSirRetStatus +PopulateDot11fTPCReport(tpAniSirGlobal pMac, + tDot11fIETPCReport *pDot11f, + tpPESession psessionEntry) +{ + tANI_U16 staid, txPower; + tSirRetStatus nSirStatus; + + nSirStatus = limGetMgmtStaid( pMac, &staid, psessionEntry); + if ( eSIR_SUCCESS != nSirStatus ) + { + dot11fLog( pMac, LOG1, FL("Failed to get the STAID in Populat" + "eDot11fTPCReport; limGetMgmtStaid " + "returned status %d."), + nSirStatus ); + return eSIR_FAILURE; + } + + // FramesToDo: This function was "misplaced" in the move to Gen4_TVM... + // txPower = halGetRateToPwrValue( pMac, staid, pMac->lim.gLimCurrentChannelId, isBeacon ); + txPower = 0; + pDot11f->tx_power = ( tANI_U8 )txPower; + pDot11f->link_margin = 0; + pDot11f->present = 1; + + return eSIR_SUCCESS; +} // End PopulateDot11fTPCReport. + + +void PopulateDot11fTSInfo(tSirMacTSInfo *pInfo, + tDot11fFfTSInfo *pDot11f) +{ + pDot11f->traffic_type = pInfo->traffic.trafficType; + pDot11f->tsid = pInfo->traffic.tsid; + pDot11f->direction = pInfo->traffic.direction; + pDot11f->access_policy = pInfo->traffic.accessPolicy; + pDot11f->aggregation = pInfo->traffic.aggregation; + pDot11f->psb = pInfo->traffic.psb; + pDot11f->user_priority = pInfo->traffic.userPrio; + pDot11f->tsinfo_ack_pol = pInfo->traffic.ackPolicy; + pDot11f->schedule = pInfo->schedule.schedule; +} // End PopulatedDot11fTSInfo. + +void PopulateDot11fWMM(tpAniSirGlobal pMac, + tDot11fIEWMMInfoAp *pInfo, + tDot11fIEWMMParams *pParams, + tDot11fIEWMMCaps *pCaps, + tpPESession psessionEntry) +{ + if ( psessionEntry->limWmeEnabled ) + { + if ( eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + //if ( ! sirIsPropCapabilityEnabled( pMac, SIR_MAC_PROP_CAPABILITY_WME ) ) + { + PopulateDot11fWMMInfoAp( pMac, pInfo, psessionEntry ); + } + } + else + { + { + PopulateDot11fWMMParams( pMac, pParams, psessionEntry); + } + + if ( psessionEntry->limWsmEnabled ) + { + PopulateDot11fWMMCaps( pCaps ); + } + } + } +} // End PopulateDot11fWMM. + +void PopulateDot11fWMMCaps(tDot11fIEWMMCaps *pCaps) +{ + pCaps->version = SIR_MAC_OUI_VERSION_1; + pCaps->qack = 0; + pCaps->queue_request = 1; + pCaps->txop_request = 0; + pCaps->more_ack = 0; + pCaps->present = 1; +} // End PopulateDot11fWmmCaps. + +#ifdef FEATURE_WLAN_ESE +void PopulateDot11fReAssocTspec(tpAniSirGlobal pMac, tDot11fReAssocRequest *pReassoc, tpPESession psessionEntry) +{ + tANI_U8 numTspecs = 0, idx; + tTspecInfo *pTspec = NULL; + + numTspecs = psessionEntry->pLimReAssocReq->eseTspecInfo.numTspecs; + pTspec = &psessionEntry->pLimReAssocReq->eseTspecInfo.tspec[0]; + pReassoc->num_WMMTSPEC = numTspecs; + if (numTspecs) { + for (idx=0; idxtspec, &pReassoc->WMMTSPEC[idx]); + pTspec->tspec.mediumTime = 0; + pTspec++; + } + } +} +#endif + +void PopulateDot11fWMMInfoAp(tpAniSirGlobal pMac, tDot11fIEWMMInfoAp *pInfo, + tpPESession psessionEntry) +{ + pInfo->version = SIR_MAC_OUI_VERSION_1; + + /* WMM Specification 3.1.3, 3.2.3 + * An IBSS staion shall always use its default WMM parameters. + */ + if ( eLIM_STA_IN_IBSS_ROLE == psessionEntry->limSystemRole ) + { + pInfo->param_set_count = 0; + pInfo->uapsd = 0; + } + else + { + pInfo->param_set_count = ( 0xf & psessionEntry->gLimEdcaParamSetCount ); + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ){ + pInfo->uapsd = ( 0x1 & psessionEntry->apUapsdEnable ); + } + else + pInfo->uapsd = ( 0x1 & pMac->lim.gUapsdEnable ); + } + pInfo->present = 1; +} + +void PopulateDot11fWMMInfoStation(tpAniSirGlobal pMac, tDot11fIEWMMInfoStation *pInfo) +{ + tANI_U32 val = 0; + + limLog(pMac, LOG1, FL("populate WMM IE in Setup Request Frame")); + pInfo->version = SIR_MAC_OUI_VERSION_1; + pInfo->acvo_uapsd = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + pInfo->acvi_uapsd = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + pInfo->acbk_uapsd = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + pInfo->acbe_uapsd = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_SP_LENGTH, &val) != eSIR_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("could not retrieve Max SP Length "));) + pInfo->max_sp_length = (tANI_U8)val; + pInfo->present = 1; +} + +void PopulateDot11fWMMParams(tpAniSirGlobal pMac, + tDot11fIEWMMParams *pParams, + tpPESession psessionEntry) +{ + pParams->version = SIR_MAC_OUI_VERSION_1; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE) + pParams->qosInfo = + (psessionEntry->apUapsdEnable << 7) | ((tANI_U8)(0x0f & psessionEntry->gLimEdcaParamSetCount)); + else + pParams->qosInfo = + (pMac->lim.gUapsdEnable << 7) | ((tANI_U8)(0x0f & psessionEntry->gLimEdcaParamSetCount)); + + // Fill each EDCA parameter set in order: be, bk, vi, vo + pParams->acbe_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[0].aci.aifsn) ); + pParams->acbe_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[0].aci.acm ); + pParams->acbe_aci = ( 0x3 & SIR_MAC_EDCAACI_BESTEFFORT ); + pParams->acbe_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.min ); + pParams->acbe_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[0].cw.max ); + pParams->acbe_txoplimit = psessionEntry->gLimEdcaParamsBC[0].txoplimit; + + pParams->acbk_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[1].aci.aifsn) ); + pParams->acbk_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[1].aci.acm ); + pParams->acbk_aci = ( 0x3 & SIR_MAC_EDCAACI_BACKGROUND ); + pParams->acbk_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.min ); + pParams->acbk_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[1].cw.max ); + pParams->acbk_txoplimit = psessionEntry->gLimEdcaParamsBC[1].txoplimit; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ) + pParams->acvi_aifsn = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].aci.aifsn ); + else + pParams->acvi_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[2].aci.aifsn) ); + + + + pParams->acvi_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[2].aci.acm ); + pParams->acvi_aci = ( 0x3 & SIR_MAC_EDCAACI_VIDEO ); + pParams->acvi_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.min ); + pParams->acvi_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[2].cw.max ); + pParams->acvi_txoplimit = psessionEntry->gLimEdcaParamsBC[2].txoplimit; + + if(psessionEntry->limSystemRole == eLIM_AP_ROLE ) + pParams->acvo_aifsn = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].aci.aifsn ); + else + pParams->acvo_aifsn = ( 0xf & SET_AIFSN(psessionEntry->gLimEdcaParamsBC[3].aci.aifsn) ); + + pParams->acvo_acm = ( 0x1 & psessionEntry->gLimEdcaParamsBC[3].aci.acm ); + pParams->acvo_aci = ( 0x3 & SIR_MAC_EDCAACI_VOICE ); + pParams->acvo_acwmin = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.min ); + pParams->acvo_acwmax = ( 0xf & psessionEntry->gLimEdcaParamsBC[3].cw.max ); + pParams->acvo_txoplimit = psessionEntry->gLimEdcaParamsBC[3].txoplimit; + + pParams->present = 1; + +} // End PopulateDot11fWMMParams. + +void PopulateDot11fWMMSchedule(tSirMacScheduleIE *pSchedule, + tDot11fIEWMMSchedule *pDot11f) +{ + pDot11f->version = 1; + pDot11f->aggregation = pSchedule->info.aggregation; + pDot11f->tsid = pSchedule->info.tsid; + pDot11f->direction = pSchedule->info.direction; + pDot11f->reserved = pSchedule->info.rsvd; + pDot11f->service_start_time = pSchedule->svcStartTime; + pDot11f->service_interval = pSchedule->svcInterval; + pDot11f->max_service_dur = pSchedule->maxSvcDuration; + pDot11f->spec_interval = pSchedule->specInterval; + + pDot11f->present = 1; +} // End PopulateDot11fWMMSchedule. + +tSirRetStatus +PopulateDot11fWPA(tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPA *pDot11f) +{ + tANI_U32 status; + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WPA ) ) ) + { + status = dot11fUnpackIeWPA( pMac, + pRsnIe->rsnIEdata + idx + 2 + 4, // EID, length, OUI + pRsnIe->rsnIEdata[ idx + 1 ] - 4, // OUI + pDot11f ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog( pMac, LOGE, FL("Parse failure in PopulateDot11fWP" + "A (0x%08x)."), + status ); + return eSIR_FAILURE; + } + } + } + + return eSIR_SUCCESS; +} // End PopulateDot11fWPA. + + + +tSirRetStatus PopulateDot11fWPAOpaque( tpAniSirGlobal pMac, + tpSirRSNie pRsnIe, + tDot11fIEWPAOpaque *pDot11f ) +{ + int idx; + + if ( pRsnIe->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, pRsnIe, DOT11F_EID_WPA ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pRsnIe->rsnIEdata[ idx + 1 ] - 4; + vos_mem_copy( pDot11f->data, + pRsnIe->rsnIEdata + idx + 2 + 4, // EID, len, OUI + pRsnIe->rsnIEdata[ idx + 1 ] - 4 ); // OUI + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fWPAOpaque. + +//////////////////////////////////////////////////////////////////////// + +tSirRetStatus +sirGetCfgPropCaps(tpAniSirGlobal pMac, tANI_U16 *caps) +{ +#if 0 + tANI_U32 val; + + *caps = 0; + if (wlan_cfgGetInt(pMac, WNI_CFG_PROPRIETARY_ANI_FEATURES_ENABLED, &val) + != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve PropFeature enabled flag")); + return eSIR_FAILURE; + } + if (wlan_cfgGetInt(pMac, WNI_CFG_PROP_CAPABILITY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("could not retrieve PROP_CAPABLITY flag")); + return eSIR_FAILURE; + } + + *caps = (tANI_U16) val; +#endif + return eSIR_SUCCESS; +} + +tSirRetStatus +sirConvertProbeReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirProbeReq pProbeReq) +{ + tANI_U32 status; + tDot11fProbeRequest pr; + + // Ok, zero-init our [out] parameter, + vos_mem_set( (tANI_U8*)pProbeReq, sizeof(tSirProbeReq), 0); + + // delegate to the framesc-generated code, + status = dot11fUnpackProbeRequest(pMac, pFrame, nFrame, &pr); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Probe Request (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking a Probe Request (0x%08x, %d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fProbeRequestto' a 'tSirProbeReq'... + if ( ! pr.SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!"));) + } + else + { + pProbeReq->ssidPresent = 1; + ConvertSSID( pMac, &pProbeReq->ssId, &pr.SSID ); + } + + if ( ! pr.SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!"));) + return eSIR_FAILURE; + } + else + { + pProbeReq->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pProbeReq->supportedRates, &pr.SuppRates ); + } + + if ( pr.ExtSuppRates.present ) + { + pProbeReq->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pProbeReq->extendedRates, &pr.ExtSuppRates ); + } + + if ( pr.HTCaps.present ) + { + vos_mem_copy( &pProbeReq->HTCaps, &pr.HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pr.WscProbeReq.present ) + { + pProbeReq->wscIePresent = 1; + vos_mem_copy(&pProbeReq->probeReqWscIeInfo, &pr.WscProbeReq, sizeof(tDot11fIEWscProbeReq)); + } +#ifdef WLAN_FEATURE_11AC + if ( pr.VHTCaps.present ) + { + vos_mem_copy( &pProbeReq->VHTCaps, &pr.VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } +#endif + + + if ( pr.P2PProbeReq.present ) + { + pProbeReq->p2pIePresent = 1; + } + + return eSIR_SUCCESS; + +} // End sirConvertProbeReqFrame2Struct. + +/* function ValidateAndRectifyIEs checks for the malformed frame. + * The frame would contain fixed IEs of 12 bytes follwed by Variable IEs + * (Tagged elements). + * Every Tagged IE has tag number, tag length and data. Tag length indicates + * the size of data in bytes. + * This function checks for size of Frame recived with the sum of all IEs. + * And also rectifies missing optional fields in IE. + * + * NOTE : Presently this function rectifies RSN capability in RSN IE, can + * extended to rectify other optional fields in other IEs. + * + */ +tSirRetStatus ValidateAndRectifyIEs(tpAniSirGlobal pMac, + tANI_U8 *pMgmtFrame, + tANI_U32 nFrameBytes, + tANI_U32 *nMissingRsnBytes) +{ + tANI_U32 length = SIZE_OF_FIXED_PARAM; + tANI_U8 *refFrame; + + // Frame contains atleast one IE + if (nFrameBytes > (SIZE_OF_FIXED_PARAM + 2)) + { + while (length < nFrameBytes) + { + /*refFrame points to next IE */ + refFrame = pMgmtFrame + length; + length += (tANI_U32)(SIZE_OF_TAG_PARAM_NUM + SIZE_OF_TAG_PARAM_LEN + + (*(refFrame + SIZE_OF_TAG_PARAM_NUM))); + } + if (length != nFrameBytes) + { + /* Workaround : Some APs may not include RSN Capability but + * the length of which is included in RSN IE length. + * this may cause in updating RSN Capability with junk value. + * To avoid this, add RSN Capability value with default value. + * Going further we can have such workaround for other IEs + */ + if ((*refFrame == RSNIEID) && + (length == (nFrameBytes + RSNIE_CAPABILITY_LEN))) + { + //Assume RSN Capability as 00 + vos_mem_set( ( tANI_U8* ) (pMgmtFrame + (nFrameBytes)), + RSNIE_CAPABILITY_LEN, DEFAULT_RSNIE_CAP_VAL ); + *nMissingRsnBytes = RSNIE_CAPABILITY_LEN; + limLog(pMac, LOG1, + FL("Added RSN Capability to the RSNIE as 0x00 0x00")); + + return eHAL_STATUS_SUCCESS; + } else { + /* Workaround: Some APs may add extra 0x00 padding after IEs. + * Return true to allow these probe response frames proceed. + */ + if (nFrameBytes - length > 0) { + tANI_U32 i; + tANI_BOOLEAN zero_padding = VOS_TRUE; + + for (i = length; i < nFrameBytes; i ++) { + if (pMgmtFrame[i-1] != 0x0) { + zero_padding = VOS_FALSE; + break; + } + } + + if (zero_padding) { + return eHAL_STATUS_SUCCESS; + } + } + } + + return eSIR_FAILURE; + } + } + return eHAL_STATUS_SUCCESS; +} + +tSirRetStatus sirConvertProbeFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirProbeRespBeacon pProbeResp) +{ + tANI_U32 status; + tDot11fProbeResponse *pr; + + // Ok, zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pProbeResp, sizeof(tSirProbeRespBeacon), 0 ); + + pr = vos_mem_vmalloc(sizeof(tDot11fProbeResponse)); + if ( NULL == pr ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + + vos_mem_set( ( tANI_U8* )pr, sizeof(tDot11fProbeResponse), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackProbeResponse( pMac, pFrame, nFrame, pr ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Probe Response (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + vos_mem_vfree(pr); + return eSIR_FAILURE; + } + + // & "transliterate" from a 'tDot11fProbeResponse' to a 'tSirProbeRespBeacon'... + + // Timestamp + vos_mem_copy( ( tANI_U8* )pProbeResp->timeStamp, ( tANI_U8* )&pr->TimeStamp, + sizeof(tSirMacTimeStamp) ); + + // Beacon Interval + pProbeResp->beaconInterval = pr->BeaconInterval.interval; + + // Capabilities + pProbeResp->capabilityInfo.ess = pr->Capabilities.ess; + pProbeResp->capabilityInfo.ibss = pr->Capabilities.ibss; + pProbeResp->capabilityInfo.cfPollable = pr->Capabilities.cfPollable; + pProbeResp->capabilityInfo.cfPollReq = pr->Capabilities.cfPollReq; + pProbeResp->capabilityInfo.privacy = pr->Capabilities.privacy; + pProbeResp->capabilityInfo.shortPreamble = pr->Capabilities.shortPreamble; + pProbeResp->capabilityInfo.pbcc = pr->Capabilities.pbcc; + pProbeResp->capabilityInfo.channelAgility = pr->Capabilities.channelAgility; + pProbeResp->capabilityInfo.spectrumMgt = pr->Capabilities.spectrumMgt; + pProbeResp->capabilityInfo.qos = pr->Capabilities.qos; + pProbeResp->capabilityInfo.shortSlotTime = pr->Capabilities.shortSlotTime; + pProbeResp->capabilityInfo.apsd = pr->Capabilities.apsd; + pProbeResp->capabilityInfo.rrm = pr->Capabilities.rrm; + pProbeResp->capabilityInfo.dsssOfdm = pr->Capabilities.dsssOfdm; + pProbeResp->capabilityInfo.delayedBA = pr->Capabilities.delayedBA; + pProbeResp->capabilityInfo.immediateBA = pr->Capabilities.immediateBA; + + if ( ! pr->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!"));) + } + else + { + pProbeResp->ssidPresent = 1; + ConvertSSID( pMac, &pProbeResp->ssId, &pr->SSID ); + } + + if ( ! pr->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!"));) + } + else + { + pProbeResp->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pProbeResp->supportedRates, &pr->SuppRates ); + } + + if ( pr->ExtSuppRates.present ) + { + pProbeResp->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pProbeResp->extendedRates, &pr->ExtSuppRates ); + } + + + if ( pr->CFParams.present ) + { + pProbeResp->cfPresent = 1; + ConvertCFParams( pMac, &pProbeResp->cfParamSet, &pr->CFParams ); + } + + if ( pr->Country.present ) + { + pProbeResp->countryInfoPresent = 1; + ConvertCountry( pMac, &pProbeResp->countryInfoParam, &pr->Country ); + } + + if ( pr->EDCAParamSet.present ) + { + pProbeResp->edcaPresent = 1; + ConvertEDCAParam( pMac, &pProbeResp->edcaParams, &pr->EDCAParamSet ); + } + + if ( pr->ChanSwitchAnn.present ) + { + pProbeResp->channelSwitchPresent = 1; + vos_mem_copy( &pProbeResp->channelSwitchIE, &pr->ChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn) ); + } + + if ( pr->ExtChanSwitchAnn.present ) + { + pProbeResp->extChannelSwitchPresent = 1; + vos_mem_copy ( &pProbeResp->extChannelSwitchIE, &pr->ExtChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn) ); + } + + if( pr->TPCReport.present) + { + pProbeResp->tpcReportPresent = 1; + vos_mem_copy( &pProbeResp->tpcReport, &pr->TPCReport, sizeof(tDot11fIETPCReport)); + } + + if( pr->PowerConstraints.present) + { + pProbeResp->powerConstraintPresent = 1; + vos_mem_copy( &pProbeResp->localPowerConstraint, &pr->PowerConstraints, + sizeof(tDot11fIEPowerConstraints)); + } + + if ( pr->Quiet.present ) + { + pProbeResp->quietIEPresent = 1; + vos_mem_copy( &pProbeResp->quietIE, &pr->Quiet, sizeof(tDot11fIEQuiet) ); + } + + if ( pr->HTCaps.present ) + { + vos_mem_copy( &pProbeResp->HTCaps, &pr->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pr->HTInfo.present ) + { + vos_mem_copy( &pProbeResp->HTInfo, &pr->HTInfo, sizeof( tDot11fIEHTInfo ) ); + } + + if ( pr->DSParams.present ) + { + pProbeResp->dsParamsPresent = 1; + pProbeResp->channelNumber = pr->DSParams.curr_channel; + } + else if(pr->HTInfo.present) + { + pProbeResp->channelNumber = pr->HTInfo.primaryChannel; + } + + if ( pr->RSNOpaque.present ) + { + pProbeResp->rsnPresent = 1; + ConvertRSNOpaque( pMac, &pProbeResp->rsn, &pr->RSNOpaque ); + } + + if ( pr->WPA.present ) + { + pProbeResp->wpaPresent = 1; + ConvertWPA( pMac, &pProbeResp->wpa, &pr->WPA ); + } + + if ( pr->WMMParams.present ) + { + pProbeResp->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pProbeResp->edcaParams, &pr->WMMParams ); + PELOG1(limLog(pMac, LOG1, FL("WMM Parameter present in Probe Response Frame!")); + __printWMMParams(pMac, &pr->WMMParams);) + } + + if ( pr->WMMInfoAp.present ) + { + pProbeResp->wmeInfoPresent = 1; + PELOG1(limLog(pMac, LOG1, FL("WMM Information Element present in Probe Response Frame!"));) + } + + if ( pr->WMMCaps.present ) + { + pProbeResp->wsmCapablePresent = 1; + } + + + if ( pr->ERPInfo.present ) + { + pProbeResp->erpPresent = 1; + ConvertERPInfo( pMac, &pProbeResp->erpIEInfo, &pr->ERPInfo ); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pr->MobilityDomain.present) + { + // MobilityDomain + pProbeResp->mdiePresent = 1; + vos_mem_copy( (tANI_U8 *)&(pProbeResp->mdie[0]), (tANI_U8 *)&(pr->MobilityDomain.MDID), + sizeof(tANI_U16) ); + pProbeResp->mdie[2] = ((pr->MobilityDomain.overDSCap << 0) | (pr->MobilityDomain.resourceReqCap << 1)); +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG2, FL("mdie=%02x%02x%02x"), (unsigned int)pProbeResp->mdie[0], + (unsigned int)pProbeResp->mdie[1], (unsigned int)pProbeResp->mdie[2]); +#endif + } +#endif + +#if defined(FEATURE_WLAN_ESE) || defined(WLAN_FEATURE_ROAM_SCAN_OFFLOAD) + if (pr->QBSSLoad.present) + { + vos_mem_copy(&pProbeResp->QBSSLoad, &pr->QBSSLoad, sizeof(tDot11fIEQBSSLoad)); + } +#endif + if (pr->P2PProbeRes.present) + { + vos_mem_copy( &pProbeResp->P2PProbeRes, &pr->P2PProbeRes, + sizeof(tDot11fIEP2PProbeRes) ); + } +#ifdef WLAN_FEATURE_11AC + if ( pr->VHTCaps.present ) + { + vos_mem_copy( &pProbeResp->VHTCaps, &pr->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( pr->VHTOperation.present ) + { + vos_mem_copy( &pProbeResp->VHTOperation, &pr->VHTOperation, sizeof( tDot11fIEVHTOperation) ); + } + if ( pr->VHTExtBssLoad.present ) + { + vos_mem_copy( &pProbeResp->VHTExtBssLoad, &pr->VHTExtBssLoad, sizeof( tDot11fIEVHTExtBssLoad) ); + } +#endif + sir_copy_hs20_ie(&pProbeResp->hs20vendor_ie, &pr->hs20vendor_ie); + + vos_mem_vfree(pr); + return eSIR_SUCCESS; + +} // End sirConvertProbeFrame2Struct. + +tSirRetStatus +sirConvertAssocReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirAssocReq pAssocReq) +{ + tDot11fAssocRequest *ar; + tANI_U32 status; + + ar = vos_mem_malloc(sizeof(tDot11fAssocRequest)); + if ( NULL == ar ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAssocReq, sizeof(tSirAssocReq), 0 ); + vos_mem_set( ( tANI_U8* )ar, sizeof( tDot11fAssocRequest ), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackAssocRequest( pMac, pFrame, nFrame, ar ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Association Request (0x%08x, %d bytes):"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + vos_mem_free(ar); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking an Assoication Request (0x%08x, %d bytes):"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAssocRequest' to a 'tSirAssocReq'... + + // make sure this is seen as an assoc request + pAssocReq->reassocRequest = 0; + + // Capabilities + pAssocReq->capabilityInfo.ess = ar->Capabilities.ess; + pAssocReq->capabilityInfo.ibss = ar->Capabilities.ibss; + pAssocReq->capabilityInfo.cfPollable = ar->Capabilities.cfPollable; + pAssocReq->capabilityInfo.cfPollReq = ar->Capabilities.cfPollReq; + pAssocReq->capabilityInfo.privacy = ar->Capabilities.privacy; + pAssocReq->capabilityInfo.shortPreamble = ar->Capabilities.shortPreamble; + pAssocReq->capabilityInfo.pbcc = ar->Capabilities.pbcc; + pAssocReq->capabilityInfo.channelAgility = ar->Capabilities.channelAgility; + pAssocReq->capabilityInfo.spectrumMgt = ar->Capabilities.spectrumMgt; + pAssocReq->capabilityInfo.qos = ar->Capabilities.qos; + pAssocReq->capabilityInfo.shortSlotTime = ar->Capabilities.shortSlotTime; + pAssocReq->capabilityInfo.apsd = ar->Capabilities.apsd; + pAssocReq->capabilityInfo.rrm = ar->Capabilities.rrm; + pAssocReq->capabilityInfo.dsssOfdm = ar->Capabilities.dsssOfdm; + pAssocReq->capabilityInfo.delayedBA = ar->Capabilities.delayedBA; + pAssocReq->capabilityInfo.immediateBA = ar->Capabilities.immediateBA; + + // Listen Interval + pAssocReq->listenInterval = ar->ListenInterval.interval; + + // SSID + if ( ar->SSID.present ) + { + pAssocReq->ssidPresent = 1; + ConvertSSID( pMac, &pAssocReq->ssId, &ar->SSID ); + } + + // Supported Rates + if ( ar->SuppRates.present ) + { + pAssocReq->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pAssocReq->supportedRates, &ar->SuppRates ); + } + + // Extended Supported Rates + if ( ar->ExtSuppRates.present ) + { + pAssocReq->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pAssocReq->extendedRates, &ar->ExtSuppRates ); + } + + // QOS Capabilities: + if ( ar->QOSCapsStation.present ) + { + pAssocReq->qosCapabilityPresent = 1; + ConvertQOSCapsStation( pMac, &pAssocReq->qosCapability, &ar->QOSCapsStation ); + } + + // WPA + if ( ar->WPAOpaque.present ) + { + pAssocReq->wpaPresent = 1; + ConvertWPAOpaque( pMac, &pAssocReq->wpa, &ar->WPAOpaque ); + } + + // RSN + if ( ar->RSNOpaque.present ) + { + pAssocReq->rsnPresent = 1; + ConvertRSNOpaque( pMac, &pAssocReq->rsn, &ar->RSNOpaque ); + } + + // WSC IE + if (ar->WscIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWscOpaque(pMac, &pAssocReq->addIE, &ar->WscIEOpaque); + } + + + if(ar->P2PIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertP2POpaque( pMac, &pAssocReq->addIE, &ar->P2PIEOpaque); + } +#ifdef WLAN_FEATURE_WFD + if(ar->WFDIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWFDOpaque( pMac, &pAssocReq->addIE, &ar->WFDIEOpaque); + } +#endif + + // Power Capabilities + if ( ar->PowerCaps.present ) + { + pAssocReq->powerCapabilityPresent = 1; + ConvertPowerCaps( pMac, &pAssocReq->powerCapability, &ar->PowerCaps ); + } + + // Supported Channels + if ( ar->SuppChannels.present ) + { + pAssocReq->supportedChannelsPresent = 1; + ConvertSuppChannels( pMac, &pAssocReq->supportedChannels, &ar->SuppChannels ); + } + + if ( ar->HTCaps.present ) + { + vos_mem_copy( &pAssocReq->HTCaps, &ar->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( ar->WMMInfoStation.present ) + { + pAssocReq->wmeInfoPresent = 1; + vos_mem_copy( &pAssocReq->WMMInfoStation, &ar->WMMInfoStation, + sizeof( tDot11fIEWMMInfoStation ) ); + + } + + + if ( ar->WMMCaps.present ) pAssocReq->wsmCapablePresent = 1; + + if ( ! pAssocReq->ssidPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without SSID IE."));) + vos_mem_free(ar); + return eSIR_FAILURE; + } + + if ( !pAssocReq->suppRatesPresent && !pAssocReq->extendedRatesPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without supp rate IE."));) + vos_mem_free(ar); + return eSIR_FAILURE; + } + +#ifdef WLAN_FEATURE_11AC + if ( ar->VHTCaps.present ) + { + vos_mem_copy( &pAssocReq->VHTCaps, &ar->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + limLog( pMac, LOGW, FL("Received Assoc Req with VHT Cap")); + limLogVHTCap( pMac, &pAssocReq->VHTCaps); + } + if ( ar->OperatingMode.present ) + { + vos_mem_copy( &pAssocReq->operMode, &ar->OperatingMode, sizeof (tDot11fIEOperatingMode)); + limLog( pMac, LOGW, FL("Received Assoc Req with Operating Mode IE")); + limLogOperatingMode( pMac, &pAssocReq->operMode); + } +#endif + vos_mem_free(ar); + return eSIR_SUCCESS; + +} // End sirConvertAssocReqFrame2Struct. + +tSirRetStatus +sirConvertAssocRespFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirAssocRsp pAssocRsp) +{ + static tDot11fAssocResponse ar; + tANI_U32 status; + tANI_U8 cnt =0; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAssocRsp, sizeof(tSirAssocRsp), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackAssocResponse( pMac, pFrame, nFrame, &ar); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Association Response (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking an Association Response (0x%08x, %d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAssocResponse' a 'tSirAssocRsp'... + + // Capabilities + pAssocRsp->capabilityInfo.ess = ar.Capabilities.ess; + pAssocRsp->capabilityInfo.ibss = ar.Capabilities.ibss; + pAssocRsp->capabilityInfo.cfPollable = ar.Capabilities.cfPollable; + pAssocRsp->capabilityInfo.cfPollReq = ar.Capabilities.cfPollReq; + pAssocRsp->capabilityInfo.privacy = ar.Capabilities.privacy; + pAssocRsp->capabilityInfo.shortPreamble = ar.Capabilities.shortPreamble; + pAssocRsp->capabilityInfo.pbcc = ar.Capabilities.pbcc; + pAssocRsp->capabilityInfo.channelAgility = ar.Capabilities.channelAgility; + pAssocRsp->capabilityInfo.spectrumMgt = ar.Capabilities.spectrumMgt; + pAssocRsp->capabilityInfo.qos = ar.Capabilities.qos; + pAssocRsp->capabilityInfo.shortSlotTime = ar.Capabilities.shortSlotTime; + pAssocRsp->capabilityInfo.apsd = ar.Capabilities.apsd; + pAssocRsp->capabilityInfo.rrm = ar.Capabilities.rrm; + pAssocRsp->capabilityInfo.dsssOfdm = ar.Capabilities.dsssOfdm; + pAssocRsp->capabilityInfo.delayedBA = ar.Capabilities.delayedBA; + pAssocRsp->capabilityInfo.immediateBA = ar.Capabilities.immediateBA; + + pAssocRsp->statusCode = ar.Status.status; + pAssocRsp->aid = ar.AID.associd; + + if ( ! ar.SuppRates.present ) + { + pAssocRsp->suppRatesPresent = 0; + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!"));) + } + else + { + pAssocRsp->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pAssocRsp->supportedRates, &ar.SuppRates ); + } + + if ( ar.ExtSuppRates.present ) + { + pAssocRsp->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pAssocRsp->extendedRates, &ar.ExtSuppRates ); + } + + if ( ar.EDCAParamSet.present ) + { + pAssocRsp->edcaPresent = 1; + ConvertEDCAParam( pMac, &pAssocRsp->edca, &ar.EDCAParamSet ); + } + if (ar.ExtCap.present) + { + struct s_ext_cap *p_ext_cap; + vos_mem_copy(&pAssocRsp->ExtCap, &ar.ExtCap, sizeof(tDot11fIEExtCap)); + + p_ext_cap = (struct s_ext_cap *)&pAssocRsp->ExtCap.bytes; + limLog(pMac, LOG1, + FL("ExtCap is present, TDLSChanSwitProhibited: %d"), + p_ext_cap->TDLSChanSwitProhibited); + } + if ( ar.WMMParams.present ) + { + pAssocRsp->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pAssocRsp->edca, &ar.WMMParams); + limLog(pMac, LOG1, FL("WMM Parameter Element present in Association Response Frame!")); + __printWMMParams(pMac, &ar.WMMParams); + } + + if ( ar.HTCaps.present ) + { + limLog(pMac, LOG1, FL("Received Assoc Response with HT Cap")); + vos_mem_copy( &pAssocRsp->HTCaps, &ar.HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( ar.HTInfo.present ) + { limLog(pMac, LOG1, FL("Received Assoc Response with HT Info")); + vos_mem_copy( &pAssocRsp->HTInfo, &ar.HTInfo, sizeof( tDot11fIEHTInfo ) ); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (ar.MobilityDomain.present) + { + // MobilityDomain + pAssocRsp->mdiePresent = 1; + vos_mem_copy( (tANI_U8 *)&(pAssocRsp->mdie[0]), (tANI_U8 *)&(ar.MobilityDomain.MDID), + sizeof(tANI_U16) ); + pAssocRsp->mdie[2] = ((ar.MobilityDomain.overDSCap << 0) | (ar.MobilityDomain.resourceReqCap << 1)); +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("new mdie=%02x%02x%02x"), (unsigned int)pAssocRsp->mdie[0], + (unsigned int)pAssocRsp->mdie[1], (unsigned int)pAssocRsp->mdie[2]); +#endif + } + + if ( ar.FTInfo.present ) + { +#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG + limLog(pMac, LOG1, FL("FT Info present %d %d %d"), ar.FTInfo.R0KH_ID.num_PMK_R0_ID, + ar.FTInfo.R0KH_ID.present, + ar.FTInfo.R1KH_ID.present); +#endif + pAssocRsp->ftinfoPresent = 1; + vos_mem_copy( &pAssocRsp->FTInfo, &ar.FTInfo, sizeof(tDot11fIEFTInfo) ); + } +#endif + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (ar.num_RICDataDesc && ar.num_RICDataDesc <= 2) { + for (cnt=0; cnt < ar.num_RICDataDesc; cnt++) { + if (ar.RICDataDesc[cnt].present) { + vos_mem_copy( &pAssocRsp->RICData[cnt], &ar.RICDataDesc[cnt], + sizeof(tDot11fIERICDataDesc)); + } + } + pAssocRsp->num_RICData = ar.num_RICDataDesc; + pAssocRsp->ricPresent = TRUE; + } +#endif + +#ifdef FEATURE_WLAN_ESE + if (ar.num_WMMTSPEC) { + pAssocRsp->num_tspecs = ar.num_WMMTSPEC; + for (cnt=0; cnt < ar.num_WMMTSPEC; cnt++) { + vos_mem_copy( &pAssocRsp->TSPECInfo[cnt], &ar.WMMTSPEC[cnt], + (sizeof(tDot11fIEWMMTSPEC)*ar.num_WMMTSPEC)); + } + pAssocRsp->tspecPresent = TRUE; + } + + if(ar.ESETrafStrmMet.present) + { + pAssocRsp->tsmPresent = 1; + vos_mem_copy(&pAssocRsp->tsmIE.tsid, + &ar.ESETrafStrmMet.tsid,sizeof(tSirMacESETSMIE)); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( ar.VHTCaps.present ) + { + vos_mem_copy( &pAssocRsp->VHTCaps, &ar.VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + limLog( pMac, LOG1, FL("Received Assoc Response with VHT Cap")); + limLogVHTCap(pMac, &pAssocRsp->VHTCaps); + } + if ( ar.VHTOperation.present ) + { + vos_mem_copy( &pAssocRsp->VHTOperation, &ar.VHTOperation, sizeof( tDot11fIEVHTOperation) ); + limLog( pMac, LOG1, FL("Received Assoc Response with VHT Operation")); + limLogVHTOperation(pMac, &pAssocRsp->VHTOperation); + } +#endif + if(ar.OBSSScanParameters.present) + { + vos_mem_copy( &pAssocRsp->OBSSScanParameters, &ar.OBSSScanParameters, + sizeof( tDot11fIEOBSSScanParameters)); + } + if ( ar.QosMapSet.present ) + { + pAssocRsp->QosMapSet.present = 1; + ConvertQosMapsetFrame( pMac, &pAssocRsp->QosMapSet, &ar.QosMapSet); + limLog( pMac, LOG1, FL("Received Assoc Response with Qos Map Set")); + limLogQosMapSet(pMac, &pAssocRsp->QosMapSet); + } + return eSIR_SUCCESS; +} // End sirConvertAssocRespFrame2Struct. + +tSirRetStatus +sirConvertReassocReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirAssocReq pAssocReq) +{ + static tDot11fReAssocRequest ar; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAssocReq, sizeof(tSirAssocReq), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackReAssocRequest( pMac, pFrame, nFrame, &ar ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse a Re-association Request (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking a Re-association Request (0x%08x, %d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fReAssocRequest' to a 'tSirAssocReq'... + + // make sure this is seen as a re-assoc request + pAssocReq->reassocRequest = 1; + + // Capabilities + pAssocReq->capabilityInfo.ess = ar.Capabilities.ess; + pAssocReq->capabilityInfo.ibss = ar.Capabilities.ibss; + pAssocReq->capabilityInfo.cfPollable = ar.Capabilities.cfPollable; + pAssocReq->capabilityInfo.cfPollReq = ar.Capabilities.cfPollReq; + pAssocReq->capabilityInfo.privacy = ar.Capabilities.privacy; + pAssocReq->capabilityInfo.shortPreamble = ar.Capabilities.shortPreamble; + pAssocReq->capabilityInfo.pbcc = ar.Capabilities.pbcc; + pAssocReq->capabilityInfo.channelAgility = ar.Capabilities.channelAgility; + pAssocReq->capabilityInfo.spectrumMgt = ar.Capabilities.spectrumMgt; + pAssocReq->capabilityInfo.qos = ar.Capabilities.qos; + pAssocReq->capabilityInfo.shortSlotTime = ar.Capabilities.shortSlotTime; + pAssocReq->capabilityInfo.apsd = ar.Capabilities.apsd; + pAssocReq->capabilityInfo.rrm = ar.Capabilities.rrm; + pAssocReq->capabilityInfo.dsssOfdm = ar.Capabilities.dsssOfdm; + pAssocReq->capabilityInfo.delayedBA = ar.Capabilities.delayedBA; + pAssocReq->capabilityInfo.immediateBA = ar.Capabilities.immediateBA; + + // Listen Interval + pAssocReq->listenInterval = ar.ListenInterval.interval; + + // SSID + if ( ar.SSID.present ) + { + pAssocReq->ssidPresent = 1; + ConvertSSID( pMac, &pAssocReq->ssId, &ar.SSID ); + } + + // Supported Rates + if ( ar.SuppRates.present ) + { + pAssocReq->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pAssocReq->supportedRates, &ar.SuppRates ); + } + + // Extended Supported Rates + if ( ar.ExtSuppRates.present ) + { + pAssocReq->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pAssocReq->extendedRates, + &ar.ExtSuppRates ); + } + + // QOS Capabilities: + if ( ar.QOSCapsStation.present ) + { + pAssocReq->qosCapabilityPresent = 1; + ConvertQOSCapsStation( pMac, &pAssocReq->qosCapability, &ar.QOSCapsStation ); + } + + // WPA + if ( ar.WPAOpaque.present ) + { + pAssocReq->wpaPresent = 1; + ConvertWPAOpaque( pMac, &pAssocReq->wpa, &ar.WPAOpaque ); + } + + // RSN + if ( ar.RSNOpaque.present ) + { + pAssocReq->rsnPresent = 1; + ConvertRSNOpaque( pMac, &pAssocReq->rsn, &ar.RSNOpaque ); + } + + + // Power Capabilities + if ( ar.PowerCaps.present ) + { + pAssocReq->powerCapabilityPresent = 1; + ConvertPowerCaps( pMac, &pAssocReq->powerCapability, &ar.PowerCaps ); + } + + // Supported Channels + if ( ar.SuppChannels.present ) + { + pAssocReq->supportedChannelsPresent = 1; + ConvertSuppChannels( pMac, &pAssocReq->supportedChannels, &ar.SuppChannels ); + } + + if ( ar.HTCaps.present ) + { + vos_mem_copy( &pAssocReq->HTCaps, &ar.HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( ar.WMMInfoStation.present ) + { + pAssocReq->wmeInfoPresent = 1; + vos_mem_copy( &pAssocReq->WMMInfoStation, &ar.WMMInfoStation, + sizeof( tDot11fIEWMMInfoStation ) ); + + } + + if ( ar.WMMCaps.present ) pAssocReq->wsmCapablePresent = 1; + + if ( ! pAssocReq->ssidPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without SSID IE."));) + return eSIR_FAILURE; + } + + if ( ! pAssocReq->suppRatesPresent && ! pAssocReq->extendedRatesPresent ) + { + PELOG2(limLog(pMac, LOG2, FL("Received Assoc without supp rate IE."));) + return eSIR_FAILURE; + } + + // Why no call to 'updateAssocReqFromPropCapability' here, like + // there is in 'sirConvertAssocReqFrame2Struct'? + + // WSC IE + if (ar.WscIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWscOpaque(pMac, &pAssocReq->addIE, &ar.WscIEOpaque); + } + + if(ar.P2PIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertP2POpaque( pMac, &pAssocReq->addIE, &ar.P2PIEOpaque); + } + +#ifdef WLAN_FEATURE_WFD + if(ar.WFDIEOpaque.present) + { + pAssocReq->addIEPresent = 1; + ConvertWFDOpaque( pMac, &pAssocReq->addIE, &ar.WFDIEOpaque); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( ar.VHTCaps.present ) + { + vos_mem_copy( &pAssocReq->VHTCaps, &ar.VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( ar.OperatingMode.present ) + { + vos_mem_copy( &pAssocReq->operMode, &ar.OperatingMode, sizeof( tDot11fIEOperatingMode ) ); + limLog( pMac, LOGW, FL("Received Assoc Req with Operating Mode IE")); + limLogOperatingMode( pMac, &pAssocReq->operMode); + } +#endif + return eSIR_SUCCESS; + +} // End sirConvertReassocReqFrame2Struct. + + +#if defined(FEATURE_WLAN_ESE_UPLOAD) +tSirRetStatus +sirFillBeaconMandatoryIEforEseBcnReport(tpAniSirGlobal pMac, + tANI_U8 *pPayload, + const tANI_U32 nPayload, + tANI_U8 **outIeBuf, + tANI_U32 *pOutIeLen) +{ + tDot11fBeaconIEs *pBies = NULL; + tANI_U32 status = eHAL_STATUS_SUCCESS; + tSirRetStatus retStatus = eSIR_SUCCESS; + tSirEseBcnReportMandatoryIe eseBcnReportMandatoryIe; + + /* To store how many bytes are required to be allocated + for Bcn report mandatory Ies */ + tANI_U16 numBytes = 0, freeBytes = 0; + tANI_U8 *pos = NULL; + + // Zero-init our [out] parameter, + vos_mem_set( (tANI_U8*)&eseBcnReportMandatoryIe, sizeof(eseBcnReportMandatoryIe), 0 ); + pBies = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( NULL == pBies ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + vos_mem_zero(pBies, sizeof(tDot11fBeaconIEs)); + + // delegate to the framesc-generated code, + status = dot11fUnpackBeaconIEs( pMac, pPayload, nPayload, pBies ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse Beacon IEs (0x%08x, %d bytes)"), + status, nPayload); + vos_mem_free(pBies); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes)"), + status, nPayload ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + } + + // & "transliterate" from a 'tDot11fBeaconIEs' to a 'eseBcnReportMandatoryIe'... + if ( !pBies->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!"));) + } + else + { + eseBcnReportMandatoryIe.ssidPresent = 1; + ConvertSSID( pMac, &eseBcnReportMandatoryIe.ssId, &pBies->SSID ); + /* 1 for EID, 1 for length and length bytes */ + numBytes += 1 + 1 + eseBcnReportMandatoryIe.ssId.length; + } + + if ( !pBies->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!"));) + } + else + { + eseBcnReportMandatoryIe.suppRatesPresent = 1; + ConvertSuppRates( pMac, &eseBcnReportMandatoryIe.supportedRates, &pBies->SuppRates ); + numBytes += 1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates; + } + + if ( pBies->FHParamSet.present) + { + eseBcnReportMandatoryIe.fhParamPresent = 1; + ConvertFHParams( pMac, &eseBcnReportMandatoryIe.fhParamSet, &pBies->FHParamSet ); + numBytes += 1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX; + } + + if ( pBies->DSParams.present ) + { + eseBcnReportMandatoryIe.dsParamsPresent = 1; + eseBcnReportMandatoryIe.dsParamSet.channelNumber = pBies->DSParams.curr_channel; + numBytes += 1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX; + } + + if ( pBies->CFParams.present ) + { + eseBcnReportMandatoryIe.cfPresent = 1; + ConvertCFParams( pMac, &eseBcnReportMandatoryIe.cfParamSet, &pBies->CFParams ); + numBytes += 1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX; + } + + if ( pBies->IBSSParams.present ) + { + eseBcnReportMandatoryIe.ibssParamPresent = 1; + eseBcnReportMandatoryIe.ibssParamSet.atim = pBies->IBSSParams.atim; + numBytes += 1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX; + } + + if ( pBies->TIM.present ) + { + eseBcnReportMandatoryIe.timPresent = 1; + eseBcnReportMandatoryIe.tim.dtimCount = pBies->TIM.dtim_count; + eseBcnReportMandatoryIe.tim.dtimPeriod = pBies->TIM.dtim_period; + eseBcnReportMandatoryIe.tim.bitmapControl = pBies->TIM.bmpctl; + /* As per the ESE spec, May truncate and report first 4 octets only */ + numBytes += 1 + 1 + SIR_MAC_TIM_EID_MIN; + } + + if ( pBies->RRMEnabledCap.present ) + { + eseBcnReportMandatoryIe.rrmPresent = 1; + vos_mem_copy( &eseBcnReportMandatoryIe.rmEnabledCapabilities, &pBies->RRMEnabledCap, sizeof( tDot11fIERRMEnabledCap ) ); + numBytes += 1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX; + } + + *outIeBuf = vos_mem_malloc(numBytes); + if (NULL == *outIeBuf) + { + limLog(pMac, LOGP, FL("Memory Allocation failure")); + vos_mem_free(pBies); + return eSIR_FAILURE; + } + pos = *outIeBuf; + *pOutIeLen = numBytes; + freeBytes = numBytes; + + /* Start filling the output Ie with Mandatory IE information */ + /* Fill SSID IE */ + if (eseBcnReportMandatoryIe.ssidPresent) + { + if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.ssId.length)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy SSID")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_SSID_EID; + pos++; + *pos = eseBcnReportMandatoryIe.ssId.length; + pos++; + vos_mem_copy(pos, (tANI_U8*)eseBcnReportMandatoryIe.ssId.ssId, + eseBcnReportMandatoryIe.ssId.length); + pos += eseBcnReportMandatoryIe.ssId.length; + freeBytes -= (1 + 1 + eseBcnReportMandatoryIe.ssId.length); + } + + /* Fill Supported Rates IE */ + if (eseBcnReportMandatoryIe.suppRatesPresent) + { + if (freeBytes < (1 + 1 + eseBcnReportMandatoryIe.supportedRates.numRates)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy Rates IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + if (eseBcnReportMandatoryIe.supportedRates.numRates <= + SIR_MAC_RATESET_EID_MAX) { + *pos = SIR_MAC_RATESET_EID; + pos++; + *pos = eseBcnReportMandatoryIe.supportedRates.numRates; + pos++; + vos_mem_copy(pos, + (tANI_U8*)eseBcnReportMandatoryIe.supportedRates.rate, + eseBcnReportMandatoryIe.supportedRates.numRates); + pos += eseBcnReportMandatoryIe.supportedRates.numRates; + freeBytes -= (1 + 1 + + eseBcnReportMandatoryIe.supportedRates.numRates); + } + } + + /* Fill FH Parameter set IE */ + if (eseBcnReportMandatoryIe.fhParamPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy FHIE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_FH_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_FH_PARAM_SET_EID_MAX; + pos++; + vos_mem_copy(pos, (tANI_U8*)&eseBcnReportMandatoryIe.fhParamSet, + SIR_MAC_FH_PARAM_SET_EID_MAX); + pos += SIR_MAC_FH_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_FH_PARAM_SET_EID_MAX); + } + + /* Fill DS Parameter set IE */ + if (eseBcnReportMandatoryIe.dsParamsPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy DS IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_DS_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_DS_PARAM_SET_EID_MAX; + pos++; + *pos = eseBcnReportMandatoryIe.dsParamSet.channelNumber; + pos += SIR_MAC_DS_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_DS_PARAM_SET_EID_MAX); + } + + /* Fill CF Parameter set */ + if (eseBcnReportMandatoryIe.cfPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy CF IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_CF_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_CF_PARAM_SET_EID_MAX; + pos++; + vos_mem_copy(pos, (tANI_U8*)&eseBcnReportMandatoryIe.cfParamSet, + SIR_MAC_CF_PARAM_SET_EID_MAX); + pos += SIR_MAC_CF_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_CF_PARAM_SET_EID_MAX); + } + + /* Fill IBSS Parameter set IE */ + if (eseBcnReportMandatoryIe.ibssParamPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy IBSS IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_IBSS_PARAM_SET_EID; + pos++; + *pos = SIR_MAC_IBSS_PARAM_SET_EID_MAX; + pos++; + vos_mem_copy(pos, (tANI_U8*)&eseBcnReportMandatoryIe.ibssParamSet.atim, + SIR_MAC_IBSS_PARAM_SET_EID_MAX); + pos += SIR_MAC_IBSS_PARAM_SET_EID_MAX; + freeBytes -= (1 + 1 + SIR_MAC_IBSS_PARAM_SET_EID_MAX); + } + + /* Fill TIM IE */ + if (eseBcnReportMandatoryIe.timPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_TIM_EID_MIN)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy TIM IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_TIM_EID; + pos++; + *pos = SIR_MAC_TIM_EID_MIN; + pos++; + vos_mem_copy(pos, (tANI_U8*)&eseBcnReportMandatoryIe.tim, + SIR_MAC_TIM_EID_MIN); + pos += SIR_MAC_TIM_EID_MIN; + freeBytes -= (1 + 1 + SIR_MAC_TIM_EID_MIN); + } + + /* Fill RM Capability IE */ + if (eseBcnReportMandatoryIe.rrmPresent) + { + if (freeBytes < (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX)) + { + limLog(pMac, LOGP, FL("Insufficient memory to copy RRM IE")); + retStatus = eSIR_FAILURE; + goto err_bcnrep; + } + *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID; + pos++; + *pos = SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX; + pos++; + vos_mem_copy(pos, (tANI_U8*)&eseBcnReportMandatoryIe.rmEnabledCapabilities, + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX); + freeBytes -= (1 + 1 + SIR_MAC_RM_ENABLED_CAPABILITY_EID_MAX); + } + + if (freeBytes != 0) + { + limLog(pMac, LOGP, FL("Mismatch in allocation and copying of IE in Bcn Rep")); + retStatus = eSIR_FAILURE; + } + +err_bcnrep: + /* The message counter would not be incremented in case of + * returning failure and hence next time, this function gets + * called, it would be using the same msg ctr for a different + * BSS.So, it is good to clear the memory allocated for a BSS + * that is returning failure.On success, the caller would take + * care of freeing up the memory*/ + if (retStatus == eSIR_FAILURE) + { + vos_mem_free(*outIeBuf); + *outIeBuf = NULL; + } + vos_mem_free(pBies); + return retStatus; +} + +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + +tSirRetStatus +sirParseBeaconIE(tpAniSirGlobal pMac, + tpSirProbeRespBeacon pBeaconStruct, + tANI_U8 *pPayload, + tANI_U32 nPayload) +{ + tDot11fBeaconIEs *pBies; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pBeaconStruct, sizeof(tSirProbeRespBeacon), 0 ); + + pBies = vos_mem_malloc(sizeof(tDot11fBeaconIEs)); + if ( NULL == pBies ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + vos_mem_zero(pBies, sizeof(tDot11fBeaconIEs)); + + // delegate to the framesc-generated code, + status = dot11fUnpackBeaconIEs( pMac, pPayload, nPayload, pBies ); + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse Beacon IEs (0x%08x, %d bytes)"), + status, nPayload); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + vos_mem_free(pBies); + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking Beacon IEs (0x%08x, %d bytes)"), + status, nPayload ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + } + + // & "transliterate" from a 'tDot11fBeaconIEs' to a 'tSirProbeRespBeacon'... + if ( ! pBies->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!"));) + } + else + { + pBeaconStruct->ssidPresent = 1; + ConvertSSID( pMac, &pBeaconStruct->ssId, &pBies->SSID ); + } + + if ( ! pBies->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!"));) + } + else + { + pBeaconStruct->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pBeaconStruct->supportedRates, &pBies->SuppRates ); + } + + if ( pBies->ExtSuppRates.present ) + { + pBeaconStruct->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pBeaconStruct->extendedRates, &pBies->ExtSuppRates ); + } + + if ( pBies->CFParams.present ) + { + pBeaconStruct->cfPresent = 1; + ConvertCFParams( pMac, &pBeaconStruct->cfParamSet, &pBies->CFParams ); + } + + if ( pBies->TIM.present ) + { + pBeaconStruct->timPresent = 1; + ConvertTIM( pMac, &pBeaconStruct->tim, &pBies->TIM ); + } + + if ( pBies->Country.present ) + { + pBeaconStruct->countryInfoPresent = 1; + ConvertCountry( pMac, &pBeaconStruct->countryInfoParam, &pBies->Country ); + } + + // 11h IEs + if(pBies->TPCReport.present) + { + pBeaconStruct->tpcReportPresent = 1; + vos_mem_copy( &pBeaconStruct->tpcReport, + &pBies->TPCReport, + sizeof( tDot11fIETPCReport)); + } + + if(pBies->PowerConstraints.present) + { + pBeaconStruct->powerConstraintPresent = 1; + vos_mem_copy( &pBeaconStruct->localPowerConstraint, + &pBies->PowerConstraints, + sizeof(tDot11fIEPowerConstraints)); + } +#ifdef FEATURE_WLAN_ESE + if(pBies->ESETxmitPower.present) + { + pBeaconStruct->eseTxPwr.present = 1; + pBeaconStruct->eseTxPwr.power_limit = pBies->ESETxmitPower.power_limit; + } + if (pBies->QBSSLoad.present) + { + vos_mem_copy( &pBeaconStruct->QBSSLoad, &pBies->QBSSLoad, sizeof(tDot11fIEQBSSLoad)); + } +#endif + + if ( pBies->EDCAParamSet.present ) + { + pBeaconStruct->edcaPresent = 1; + ConvertEDCAParam( pMac, &pBeaconStruct->edcaParams, &pBies->EDCAParamSet ); + } + + // QOS Capabilities: + if ( pBies->QOSCapsAp.present ) + { + pBeaconStruct->qosCapabilityPresent = 1; + ConvertQOSCaps( pMac, &pBeaconStruct->qosCapability, &pBies->QOSCapsAp ); + } + + + + if ( pBies->ChanSwitchAnn.present ) + { + pBeaconStruct->channelSwitchPresent = 1; + vos_mem_copy( &pBeaconStruct->channelSwitchIE, &pBies->ChanSwitchAnn, + sizeof(tDot11fIEChanSwitchAnn)); + } + + if ( pBies->ExtChanSwitchAnn.present) + { + pBeaconStruct->extChannelSwitchPresent= 1; + vos_mem_copy( &pBeaconStruct->extChannelSwitchIE, &pBies->ExtChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn)); + } + + if ( pBies->Quiet.present ) + { + pBeaconStruct->quietIEPresent = 1; + vos_mem_copy( &pBeaconStruct->quietIE, &pBies->Quiet, sizeof(tDot11fIEQuiet) ); + } + + if ( pBies->HTCaps.present ) + { + vos_mem_copy( &pBeaconStruct->HTCaps, &pBies->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pBies->HTInfo.present ) + { + vos_mem_copy( &pBeaconStruct->HTInfo, &pBies->HTInfo, sizeof( tDot11fIEHTInfo ) ); + } + + if ( pBies->DSParams.present ) + { + pBeaconStruct->dsParamsPresent = 1; + pBeaconStruct->channelNumber = pBies->DSParams.curr_channel; + } + else if(pBies->HTInfo.present) + { + pBeaconStruct->channelNumber = pBies->HTInfo.primaryChannel; + } + + if ( pBies->RSN.present ) + { + pBeaconStruct->rsnPresent = 1; + ConvertRSN( pMac, &pBeaconStruct->rsn, &pBies->RSN ); + } + + if ( pBies->WPA.present ) + { + pBeaconStruct->wpaPresent = 1; + ConvertWPA( pMac, &pBeaconStruct->wpa, &pBies->WPA ); + } + + if ( pBies->WMMParams.present ) + { + pBeaconStruct->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pBeaconStruct->edcaParams, &pBies->WMMParams ); + } + + if ( pBies->WMMInfoAp.present ) + { + pBeaconStruct->wmeInfoPresent = 1; + } + + if ( pBies->WMMCaps.present ) + { + pBeaconStruct->wsmCapablePresent = 1; + } + + + if ( pBies->ERPInfo.present ) + { + pBeaconStruct->erpPresent = 1; + ConvertERPInfo( pMac, &pBeaconStruct->erpIEInfo, &pBies->ERPInfo ); + } + +#ifdef WLAN_FEATURE_11AC + if ( pBies->VHTCaps.present ) + { + pBeaconStruct->VHTCaps.present = 1; + vos_mem_copy( &pBeaconStruct->VHTCaps, &pBies->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( pBies->VHTOperation.present ) + { + pBeaconStruct->VHTOperation.present = 1; + vos_mem_copy( &pBeaconStruct->VHTOperation, &pBies->VHTOperation, + sizeof( tDot11fIEVHTOperation) ); + } + if ( pBies->VHTExtBssLoad.present ) + { + pBeaconStruct->VHTExtBssLoad.present = 1; + vos_mem_copy( &pBeaconStruct->VHTExtBssLoad, &pBies->VHTExtBssLoad, + sizeof( tDot11fIEVHTExtBssLoad) ); + } + if( pBies->OperatingMode.present) + { + pBeaconStruct->OperatingMode.present = 1; + vos_mem_copy( &pBeaconStruct->OperatingMode, &pBies->OperatingMode, + sizeof( tDot11fIEOperatingMode) ); + } + +#endif + if (pBies->ExtCap.present ) + { + pBeaconStruct->ExtCap.present = 1; + vos_mem_copy( &pBeaconStruct->ExtCap, &pBies->ExtCap, + sizeof(tDot11fIEExtCap)); + } + sir_copy_hs20_ie(&pBeaconStruct->hs20vendor_ie, &pBies->hs20vendor_ie); + + vos_mem_free(pBies); + + + return eSIR_SUCCESS; + +} // End sirParseBeaconIE. + +tSirRetStatus +sirConvertBeaconFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tpSirProbeRespBeacon pBeaconStruct) +{ + tDot11fBeacon *pBeacon; + tANI_U32 status, nPayload; + tANI_U8 *pPayload; + tpSirMacMgmtHdr pHdr; + tANI_U8 mappedRXCh; + tANI_U8 rfBand; + + pPayload = WDA_GET_RX_MPDU_DATA( pFrame ); + nPayload = WDA_GET_RX_PAYLOAD_LEN( pFrame ); + pHdr = WDA_GET_RX_MAC_HEADER( pFrame ); + mappedRXCh = WDA_GET_RX_CH( pFrame ); + rfBand = WDA_GET_RX_RFBAND( pFrame ); + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pBeaconStruct, sizeof(tSirProbeRespBeacon), 0 ); + + pBeacon = vos_mem_vmalloc(sizeof(tDot11fBeacon)); + if ( NULL == pBeacon ) + status = eHAL_STATUS_FAILURE; + else + status = eHAL_STATUS_SUCCESS; + if (!HAL_STATUS_SUCCESS(status)) + { + limLog(pMac, LOGE, FL("Failed to allocate memory") ); + return eSIR_FAILURE; + } + + vos_mem_set( ( tANI_U8* )pBeacon, sizeof(tDot11fBeacon), 0 ); + + // get the MAC address out of the BD, + vos_mem_copy( pBeaconStruct->bssid, pHdr->sa, 6 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackBeacon( pMac, pPayload, nPayload, pBeacon ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse Beacon IEs (0x%08x, %d bytes)"), + status, nPayload); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pPayload, nPayload);) + vos_mem_vfree(pBeacon); + return eSIR_FAILURE; + } + + // & "transliterate" from a 'tDot11fBeacon' to a 'tSirProbeRespBeacon'... + // Timestamp + vos_mem_copy( ( tANI_U8* )pBeaconStruct->timeStamp, ( tANI_U8* )&pBeacon->TimeStamp, + sizeof(tSirMacTimeStamp) ); + + // Beacon Interval + pBeaconStruct->beaconInterval = pBeacon->BeaconInterval.interval; + + // Capabilities + pBeaconStruct->capabilityInfo.ess = pBeacon->Capabilities.ess; + pBeaconStruct->capabilityInfo.ibss = pBeacon->Capabilities.ibss; + pBeaconStruct->capabilityInfo.cfPollable = pBeacon->Capabilities.cfPollable; + pBeaconStruct->capabilityInfo.cfPollReq = pBeacon->Capabilities.cfPollReq; + pBeaconStruct->capabilityInfo.privacy = pBeacon->Capabilities.privacy; + pBeaconStruct->capabilityInfo.shortPreamble = pBeacon->Capabilities.shortPreamble; + pBeaconStruct->capabilityInfo.pbcc = pBeacon->Capabilities.pbcc; + pBeaconStruct->capabilityInfo.channelAgility = pBeacon->Capabilities.channelAgility; + pBeaconStruct->capabilityInfo.spectrumMgt = pBeacon->Capabilities.spectrumMgt; + pBeaconStruct->capabilityInfo.qos = pBeacon->Capabilities.qos; + pBeaconStruct->capabilityInfo.shortSlotTime = pBeacon->Capabilities.shortSlotTime; + pBeaconStruct->capabilityInfo.apsd = pBeacon->Capabilities.apsd; + pBeaconStruct->capabilityInfo.rrm = pBeacon->Capabilities.rrm; + pBeaconStruct->capabilityInfo.dsssOfdm = pBeacon->Capabilities.dsssOfdm; + pBeaconStruct->capabilityInfo.delayedBA = pBeacon->Capabilities.delayedBA; + pBeaconStruct->capabilityInfo.immediateBA = pBeacon->Capabilities.immediateBA; + + if ( ! pBeacon->SSID.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE SSID not present!"));) + } + else + { + pBeaconStruct->ssidPresent = 1; + ConvertSSID( pMac, &pBeaconStruct->ssId, &pBeacon->SSID ); + } + + if ( ! pBeacon->SuppRates.present ) + { + PELOGW(limLog(pMac, LOGW, FL("Mandatory IE Supported Rates not present!"));) + } + else + { + pBeaconStruct->suppRatesPresent = 1; + ConvertSuppRates( pMac, &pBeaconStruct->supportedRates, &pBeacon->SuppRates ); + } + + if ( pBeacon->ExtSuppRates.present ) + { + pBeaconStruct->extendedRatesPresent = 1; + ConvertExtSuppRates( pMac, &pBeaconStruct->extendedRates, &pBeacon->ExtSuppRates ); + } + + + if ( pBeacon->CFParams.present ) + { + pBeaconStruct->cfPresent = 1; + ConvertCFParams( pMac, &pBeaconStruct->cfParamSet, &pBeacon->CFParams ); + } + + if ( pBeacon->TIM.present ) + { + pBeaconStruct->timPresent = 1; + ConvertTIM( pMac, &pBeaconStruct->tim, &pBeacon->TIM ); + } + + if ( pBeacon->Country.present ) + { + pBeaconStruct->countryInfoPresent = 1; + ConvertCountry( pMac, &pBeaconStruct->countryInfoParam, &pBeacon->Country ); + } + + // QOS Capabilities: + if ( pBeacon->QOSCapsAp.present ) + { + pBeaconStruct->qosCapabilityPresent = 1; + ConvertQOSCaps( pMac, &pBeaconStruct->qosCapability, &pBeacon->QOSCapsAp ); + } + + if ( pBeacon->EDCAParamSet.present ) + { + pBeaconStruct->edcaPresent = 1; + ConvertEDCAParam( pMac, &pBeaconStruct->edcaParams, &pBeacon->EDCAParamSet ); + } + + if ( pBeacon->ChanSwitchAnn.present ) + { + pBeaconStruct->channelSwitchPresent = 1; + vos_mem_copy( &pBeaconStruct->channelSwitchIE, &pBeacon->ChanSwitchAnn, + sizeof(tDot11fIEChanSwitchAnn) ); + } + + if ( pBeacon->ExtChanSwitchAnn.present ) + { + pBeaconStruct->extChannelSwitchPresent = 1; + vos_mem_copy( &pBeaconStruct->extChannelSwitchIE, &pBeacon->ExtChanSwitchAnn, + sizeof(tDot11fIEExtChanSwitchAnn) ); + } + + if( pBeacon->TPCReport.present) + { + pBeaconStruct->tpcReportPresent = 1; + vos_mem_copy( &pBeaconStruct->tpcReport, &pBeacon->TPCReport, + sizeof(tDot11fIETPCReport)); + } + + if( pBeacon->PowerConstraints.present) + { + pBeaconStruct->powerConstraintPresent = 1; + vos_mem_copy( &pBeaconStruct->localPowerConstraint, &pBeacon->PowerConstraints, + sizeof(tDot11fIEPowerConstraints)); + } + + if ( pBeacon->Quiet.present ) + { + pBeaconStruct->quietIEPresent = 1; + vos_mem_copy( &pBeaconStruct->quietIE, &pBeacon->Quiet, sizeof(tDot11fIEQuiet)); + } + + if ( pBeacon->HTCaps.present ) + { + vos_mem_copy( &pBeaconStruct->HTCaps, &pBeacon->HTCaps, sizeof( tDot11fIEHTCaps ) ); + } + + if ( pBeacon->HTInfo.present ) + { + vos_mem_copy( &pBeaconStruct->HTInfo, &pBeacon->HTInfo, sizeof( tDot11fIEHTInfo) ); + + } + + if ( pBeacon->DSParams.present ) + { + pBeaconStruct->dsParamsPresent = 1; + pBeaconStruct->channelNumber = pBeacon->DSParams.curr_channel; + } + else if(pBeacon->HTInfo.present) + { + pBeaconStruct->channelNumber = pBeacon->HTInfo.primaryChannel; + } + else + { + if ((!rfBand) || IS_5G_BAND(rfBand)) + pBeaconStruct->channelNumber = limUnmapChannel(mappedRXCh); + else if (IS_24G_BAND(rfBand)) + pBeaconStruct->channelNumber = mappedRXCh; + else + { + /*Only 0, 1, 2 are expected values for RF band from FW + * if FW fixes are not present then rf band value will + * be 0, else either 1 or 2 are expected from FW, 3 is + * not expected from FW */ + PELOGE(limLog(pMac, LOGE, + FL("Channel info is not present in Beacon and" + " mapping is not done correctly"));) + pBeaconStruct->channelNumber = mappedRXCh; + } + } + + if ( pBeacon->RSN.present ) + { + pBeaconStruct->rsnPresent = 1; + ConvertRSN( pMac, &pBeaconStruct->rsn, &pBeacon->RSN ); + } + + if ( pBeacon->WPA.present ) + { + pBeaconStruct->wpaPresent = 1; + ConvertWPA( pMac, &pBeaconStruct->wpa, &pBeacon->WPA ); + } + + if ( pBeacon->WMMParams.present ) + { + pBeaconStruct->wmeEdcaPresent = 1; + ConvertWMMParams( pMac, &pBeaconStruct->edcaParams, &pBeacon->WMMParams ); + PELOG1(limLog(pMac, LOG1, FL("WMM Parameter present in Beacon Frame!")); + __printWMMParams(pMac, &pBeacon->WMMParams); ) + } + + if ( pBeacon->WMMInfoAp.present ) + { + pBeaconStruct->wmeInfoPresent = 1; + PELOG1(limLog(pMac, LOG1, FL("WMM Info present in Beacon Frame!"));) + } + + if ( pBeacon->WMMCaps.present ) + { + pBeaconStruct->wsmCapablePresent = 1; + } + + if ( pBeacon->ERPInfo.present ) + { + pBeaconStruct->erpPresent = 1; + ConvertERPInfo( pMac, &pBeaconStruct->erpIEInfo, &pBeacon->ERPInfo ); + } + +#ifdef WLAN_FEATURE_VOWIFI_11R + if (pBeacon->MobilityDomain.present) + { + // MobilityDomain + pBeaconStruct->mdiePresent = 1; + vos_mem_copy( (tANI_U8 *)&(pBeaconStruct->mdie[0]), + (tANI_U8 *)&(pBeacon->MobilityDomain.MDID), sizeof(tANI_U16) ); + pBeaconStruct->mdie[2] = ((pBeacon->MobilityDomain.overDSCap << 0) | (pBeacon->MobilityDomain.resourceReqCap << 1)); + + } +#endif + +#ifdef FEATURE_WLAN_ESE + if (pBeacon->ESETxmitPower.present) + { + //ESE Tx Power + pBeaconStruct->eseTxPwr.present = 1; + vos_mem_copy(&pBeaconStruct->eseTxPwr, + &pBeacon->ESETxmitPower, + sizeof(tDot11fIEESETxmitPower)); + } +#endif + +#ifdef WLAN_FEATURE_11AC + if ( pBeacon->VHTCaps.present ) + { + vos_mem_copy( &pBeaconStruct->VHTCaps, &pBeacon->VHTCaps, sizeof( tDot11fIEVHTCaps ) ); + } + if ( pBeacon->VHTOperation.present ) + { + vos_mem_copy( &pBeaconStruct->VHTOperation, &pBeacon->VHTOperation, + sizeof( tDot11fIEVHTOperation) ); + } + if ( pBeacon->VHTExtBssLoad.present ) + { + vos_mem_copy( &pBeaconStruct->VHTExtBssLoad, &pBeacon->VHTExtBssLoad, + sizeof( tDot11fIEVHTExtBssLoad) ); + } + if(pBeacon->OperatingMode.present) + { + vos_mem_copy( &pBeaconStruct->OperatingMode, &pBeacon->OperatingMode, + sizeof( tDot11fIEOperatingMode) ); + } + if(pBeacon->WiderBWChanSwitchAnn.present) + { + pBeaconStruct->WiderBWChanSwitchAnnPresent = 1; + vos_mem_copy( &pBeaconStruct->WiderBWChanSwitchAnn, &pBeacon->WiderBWChanSwitchAnn, + sizeof( tDot11fIEWiderBWChanSwitchAnn)); + } +#endif + if(pBeacon->OBSSScanParameters.present) + { + vos_mem_copy( &pBeaconStruct->OBSSScanParameters, + &pBeacon->OBSSScanParameters, + sizeof( tDot11fIEOBSSScanParameters)); + } + sir_copy_hs20_ie(&pBeaconStruct->hs20vendor_ie, &pBeacon->hs20vendor_ie); + + vos_mem_vfree(pBeacon); + return eSIR_SUCCESS; + +} // End sirConvertBeaconFrame2Struct. + +tSirRetStatus +sirConvertAuthFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tpSirMacAuthFrameBody pAuth) +{ + static tDot11fAuthentication auth; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAuth, sizeof(tSirMacAuthFrameBody), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackAuthentication( pMac, pFrame, nFrame, &auth ); + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Authentication frame (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpacking an Authentication frame (0x%08x, %d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAuthentication' to a 'tSirMacAuthFrameBody'... + pAuth->authAlgoNumber = auth.AuthAlgo.algo; + pAuth->authTransactionSeqNumber = auth.AuthSeqNo.no; + pAuth->authStatusCode = auth.Status.status; + + if ( auth.ChallengeText.present ) + { + pAuth->type = SIR_MAC_CHALLENGE_TEXT_EID; + pAuth->length = auth.ChallengeText.num_text; + vos_mem_copy( pAuth->challengeText, auth.ChallengeText.text, auth.ChallengeText.num_text ); + } + + return eSIR_SUCCESS; + +} // End sirConvertAuthFrame2Struct. + +tSirRetStatus +sirConvertAddtsReq2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirAddtsReqInfo *pAddTs) +{ + tDot11fAddTSRequest addts = {{0}}; + tDot11fWMMAddTSRequest wmmaddts = {{0}}; + tANI_U8 j; + tANI_U16 i; + tANI_U32 status; + + if ( SIR_MAC_QOS_ADD_TS_REQ != *( pFrame + 1 ) ) + { + limLog( pMac, LOGE, FL("sirConvertAddtsReq2Struct invoked " + "with an Action of %d; this is not " + "supported & is probably an error."), + *( pFrame + 1 ) ); + return eSIR_FAILURE; + } + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAddTs, sizeof(tSirAddtsReqInfo), 0 ); + + // delegate to the framesc-generated code, + switch ( *pFrame ) + { + case SIR_MAC_ACTION_QOS_MGMT: + status = dot11fUnpackAddTSRequest( pMac, pFrame, nFrame, &addts ); + break; + case SIR_MAC_ACTION_WME: + status = dot11fUnpackWMMAddTSRequest( pMac, pFrame, nFrame, &wmmaddts ); + break; + default: + limLog( pMac, LOGE, FL("sirConvertAddtsReq2Struct invoked " + "with a Category of %d; this is not" + " supported & is probably an error."), + *pFrame ); + return eSIR_FAILURE; + } + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Add TS Request f" + "rame (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpackin" + "g an Add TS Request frame (0x%08x," + "%d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAddTSRequest' or a + // 'tDot11WMMAddTSRequest' to a 'tSirMacAddtsReqInfo'... + if ( SIR_MAC_ACTION_QOS_MGMT == *pFrame ) + { + pAddTs->dialogToken = addts.DialogToken.token; + + if ( addts.TSPEC.present ) + { + ConvertTSPEC( pMac, &pAddTs->tspec, &addts.TSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory TSPEC element missing in Add TS Request.") ); + return eSIR_FAILURE; + } + + if ( addts.num_TCLAS ) + { + pAddTs->numTclas = (tANI_U8)addts.num_TCLAS; + + for ( i = 0U; i < addts.num_TCLAS; ++i ) + { + if ( eSIR_SUCCESS != ConvertTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.TCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.TCLASSPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.TCLASSPROC.processing; + } + + if ( addts.WMMTSPEC.present ) + { + pAddTs->wsmTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &addts.WMMTSPEC ); + } + + if ( addts.num_WMMTCLAS ) + { + j = (tANI_U8)(pAddTs->numTclas + addts.num_WMMTCLAS); + if ( SIR_MAC_TCLASIE_MAXNUM > j ) j = SIR_MAC_TCLASIE_MAXNUM; + + for ( i = pAddTs->numTclas; i < j; ++i ) + { + if ( eSIR_SUCCESS != ConvertWMMTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.WMMTCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.WMMTCLASPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.WMMTCLASPROC.processing; + } + + if ( 1 < pAddTs->numTclas && ( ! pAddTs->tclasProcPresent ) ) + { + limLog( pMac, LOGE, FL("%d TCLAS IE but not TCLASPROC IE."), + pAddTs->numTclas ); + return eSIR_FAILURE; + } + } + else + { + pAddTs->dialogToken = wmmaddts.DialogToken.token; + + if ( wmmaddts.WMMTSPEC.present ) + { + pAddTs->wmeTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &wmmaddts.WMMTSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory WME TSPEC element missing!") ); + return eSIR_FAILURE; + } + } + + return eSIR_SUCCESS; + +} // End sirConvertAddtsReq2Struct. + +tSirRetStatus +sirConvertAddtsRsp2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirAddtsRspInfo *pAddTs) +{ + tDot11fAddTSResponse addts = {{0}}; + tDot11fWMMAddTSResponse wmmaddts = {{0}}; + tANI_U8 j; + tANI_U16 i; + tANI_U32 status; + + if ( SIR_MAC_QOS_ADD_TS_RSP != *( pFrame + 1 ) ) + { + limLog( pMac, LOGE, FL("sirConvertAddtsRsp2Struct invoked " + "with an Action of %d; this is not " + "supported & is probably an error."), + *( pFrame + 1 ) ); + return eSIR_FAILURE; + } + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pAddTs, sizeof(tSirAddtsRspInfo), 0 ); + vos_mem_set( ( tANI_U8* )&addts, sizeof(tDot11fAddTSResponse), 0 ); + vos_mem_set( ( tANI_U8* )&wmmaddts, sizeof(tDot11fWMMAddTSResponse), 0 ); + + + // delegate to the framesc-generated code, + switch ( *pFrame ) + { + case SIR_MAC_ACTION_QOS_MGMT: + status = dot11fUnpackAddTSResponse( pMac, pFrame, nFrame, &addts ); + break; + case SIR_MAC_ACTION_WME: + status = dot11fUnpackWMMAddTSResponse( pMac, pFrame, nFrame, &wmmaddts ); + break; + default: + limLog( pMac, LOGE, FL("sirConvertAddtsRsp2Struct invoked " + "with a Category of %d; this is not" + " supported & is probably an error."), + *pFrame ); + return eSIR_FAILURE; + } + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Add TS Response f" + "rame (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + limLog( pMac, LOGW, FL("There were warnings while unpackin" + "g an Add TS Response frame (0x%08x," + "%d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fAddTSResponse' or a + // 'tDot11WMMAddTSResponse' to a 'tSirMacAddtsRspInfo'... + if ( SIR_MAC_ACTION_QOS_MGMT == *pFrame ) + { + pAddTs->dialogToken = addts.DialogToken.token; + pAddTs->status = ( tSirMacStatusCodes )addts.Status.status; + + if ( addts.TSDelay.present ) + { + ConvertTSDelay( pMac, &pAddTs->delay, &addts.TSDelay ); + } + + // TS Delay is present iff status indicates its presence + if ( eSIR_MAC_TS_NOT_CREATED_STATUS == pAddTs->status && ! addts.TSDelay.present ) + { + limLog( pMac, LOGW, FL("Missing TSDelay IE.") ); + } + + if ( addts.TSPEC.present ) + { + ConvertTSPEC( pMac, &pAddTs->tspec, &addts.TSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory TSPEC element missing in Add TS Response.") ); + return eSIR_FAILURE; + } + + if ( addts.num_TCLAS ) + { + pAddTs->numTclas = (tANI_U8)addts.num_TCLAS; + + for ( i = 0U; i < addts.num_TCLAS; ++i ) + { + if ( eSIR_SUCCESS != ConvertTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.TCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.TCLASSPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.TCLASSPROC.processing; + } +#ifdef FEATURE_WLAN_ESE + if(addts.ESETrafStrmMet.present) + { + pAddTs->tsmPresent = 1; + vos_mem_copy(&pAddTs->tsmIE.tsid, + &addts.ESETrafStrmMet.tsid,sizeof(tSirMacESETSMIE)); + } +#endif + if ( addts.Schedule.present ) + { + pAddTs->schedulePresent = 1; + ConvertSchedule( pMac, &pAddTs->schedule, &addts.Schedule ); + } + + if ( addts.WMMSchedule.present ) + { + pAddTs->schedulePresent = 1; + ConvertWMMSchedule( pMac, &pAddTs->schedule, &addts.WMMSchedule ); + } + + if ( addts.WMMTSPEC.present ) + { + pAddTs->wsmTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &addts.WMMTSPEC ); + } + + if ( addts.num_WMMTCLAS ) + { + j = (tANI_U8)(pAddTs->numTclas + addts.num_WMMTCLAS); + if ( SIR_MAC_TCLASIE_MAXNUM > j ) j = SIR_MAC_TCLASIE_MAXNUM; + + for ( i = pAddTs->numTclas; i < j; ++i ) + { + if ( eSIR_SUCCESS != ConvertWMMTCLAS( pMac, &( pAddTs->tclasInfo[i] ), &( addts.WMMTCLAS[i] ) ) ) + { + limLog( pMac, LOGE, FL("Failed to convert a TCLAS IE.") ); + return eSIR_FAILURE; + } + } + } + + if ( addts.WMMTCLASPROC.present ) + { + pAddTs->tclasProcPresent = 1; + pAddTs->tclasProc = addts.WMMTCLASPROC.processing; + } + + if ( 1 < pAddTs->numTclas && ( ! pAddTs->tclasProcPresent ) ) + { + limLog( pMac, LOGE, FL("%d TCLAS IE but not TCLASPROC IE."), + pAddTs->numTclas ); + return eSIR_FAILURE; + } + } + else + { + pAddTs->dialogToken = wmmaddts.DialogToken.token; + pAddTs->status = ( tSirMacStatusCodes )wmmaddts.StatusCode.statusCode; + + if ( wmmaddts.WMMTSPEC.present ) + { + pAddTs->wmeTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pAddTs->tspec, &wmmaddts.WMMTSPEC ); + } + else + { + limLog( pMac, LOGE, FL("Mandatory WME TSPEC element missing!") ); + return eSIR_FAILURE; + } + +#ifdef FEATURE_WLAN_ESE + if(wmmaddts.ESETrafStrmMet.present) + { + pAddTs->tsmPresent = 1; + vos_mem_copy(&pAddTs->tsmIE.tsid, + &wmmaddts.ESETrafStrmMet.tsid,sizeof(tSirMacESETSMIE)); + } +#endif + + } + + return eSIR_SUCCESS; + +} // End sirConvertAddtsRsp2Struct. + +tSirRetStatus +sirConvertDeltsReq2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirDeltsReqInfo *pDelTs) +{ + tDot11fDelTS delts = {{0}}; + tDot11fWMMDelTS wmmdelts = {{0}}; + tANI_U32 status; + + if ( SIR_MAC_QOS_DEL_TS_REQ != *( pFrame + 1 ) ) + { + limLog( pMac, LOGE, FL("sirConvertDeltsRsp2Struct invoked " + "with an Action of %d; this is not " + "supported & is probably an error."), + *( pFrame + 1 ) ); + return eSIR_FAILURE; + } + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pDelTs, sizeof(tSirDeltsReqInfo), 0 ); + + // delegate to the framesc-generated code, + switch ( *pFrame ) + { + case SIR_MAC_ACTION_QOS_MGMT: + status = dot11fUnpackDelTS( pMac, pFrame, nFrame, &delts ); + break; + case SIR_MAC_ACTION_WME: + status = dot11fUnpackWMMDelTS( pMac, pFrame, nFrame, &wmmdelts ); + break; + default: + limLog( pMac, LOGE, FL("sirConvertDeltsRsp2Struct invoked " + "with a Category of %d; this is not" + " supported & is probably an error."), + *pFrame ); + return eSIR_FAILURE; + } + + if ( DOT11F_FAILED( status ) ) + { + limLog(pMac, LOGE, FL("Failed to parse an Del TS Request f" + "rame (0x%08x, %d bytes)"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpackin" + "g an Del TS Request frame (0x%08x," + "%d bytes):"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fDelTSResponse' or a + // 'tDot11WMMDelTSResponse' to a 'tSirMacDeltsReqInfo'... + if ( SIR_MAC_ACTION_QOS_MGMT == *pFrame ) + { + pDelTs->tsinfo.traffic.trafficType = (tANI_U16)delts.TSInfo.traffic_type; + pDelTs->tsinfo.traffic.tsid = (tANI_U16)delts.TSInfo.tsid; + pDelTs->tsinfo.traffic.direction = (tANI_U16)delts.TSInfo.direction; + pDelTs->tsinfo.traffic.accessPolicy = (tANI_U16)delts.TSInfo.access_policy; + pDelTs->tsinfo.traffic.aggregation = (tANI_U16)delts.TSInfo.aggregation; + pDelTs->tsinfo.traffic.psb = (tANI_U16)delts.TSInfo.psb; + pDelTs->tsinfo.traffic.userPrio = (tANI_U16)delts.TSInfo.user_priority; + pDelTs->tsinfo.traffic.ackPolicy = (tANI_U16)delts.TSInfo.tsinfo_ack_pol; + + pDelTs->tsinfo.schedule.schedule = (tANI_U8)delts.TSInfo.schedule; + } + else + { + if ( wmmdelts.WMMTSPEC.present ) + { + pDelTs->wmeTspecPresent = 1; + ConvertWMMTSPEC( pMac, &pDelTs->tspec, &wmmdelts.WMMTSPEC ); + } + else + { + dot11fLog( pMac, LOGE, FL("Mandatory WME TSPEC element missing!") ); + return eSIR_FAILURE; + } + } + + return eSIR_SUCCESS; + +} // End sirConvertDeltsReq2Struct. + +tSirRetStatus +sirConvertQosMapConfigureFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tANI_U32 nFrame, + tSirQosMapSet *pQosMapSet) +{ + tDot11fQosMapConfigure mapConfigure; + tANI_U32 status; + status = dot11fUnpackQosMapConfigure(pMac, pFrame, nFrame, &mapConfigure); + if ( DOT11F_FAILED( status ) || !mapConfigure.QosMapSet.present ) + { + dot11fLog(pMac, LOGE, FL("Failed to parse or QosMapSet not present(0x%08x, %d bytes):"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpacking Qos Map Configure frame (0x%08x, %d bytes):"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + pQosMapSet->present = mapConfigure.QosMapSet.present; + ConvertQosMapsetFrame(pMac->hHdd, pQosMapSet, &mapConfigure.QosMapSet); + limLogQosMapSet(pMac, pQosMapSet); + return eSIR_SUCCESS; +} + +#ifdef ANI_SUPPORT_11H +tSirRetStatus +sirConvertTpcReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tpSirMacTpcReqActionFrame pTpcReqFrame, + tANI_U32 nFrame) +{ + tDot11fTPCRequest req; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pTpcReqFrame, sizeof(tSirMacTpcReqActionFrame), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackTPCRequest( pMac, pFrame, nFrame, &req ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOGE, FL("Failed to parse a TPC Request frame (0x%08x, %d bytes):"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpacking a TPC Request frame (0x%08x, %d bytes):"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fTPCRequest' to a + // 'tSirMacTpcReqActionFrame'... + pTpcReqFrame->actionHeader.category = req.Category.category; + pTpcReqFrame->actionHeader.actionID = req.Action.action; + pTpcReqFrame->actionHeader.dialogToken = req.DialogToken.token; + if ( req.TPCRequest.present ) + { + pTpcReqFrame->type = DOT11F_EID_TPCREQUEST; + pTpcReqFrame->length = 0; + } + else + { + dot11fLog( pMac, LOGW, FL("!!!Rcv TPC Req of inalid type!") ); + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; + +} // End sirConvertTpcReqFrame2Struct. + + +tSirRetStatus +sirConvertMeasReqFrame2Struct(tpAniSirGlobal pMac, + tANI_U8 *pFrame, + tpSirMacMeasReqActionFrame pMeasReqFrame, + tANI_U32 nFrame) +{ + tDot11fMeasurementRequest mr; + tANI_U32 status; + + // Zero-init our [out] parameter, + vos_mem_set( ( tANI_U8* )pMeasReqFrame, sizeof(*pMeasReqFrame), 0 ); + + // delegate to the framesc-generated code, + status = dot11fUnpackMeasurementRequest( pMac, pFrame, nFrame, &mr ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOGE, FL("Failed to parse a Measurement Request frame (0x%08x, %d bytes):"), + status, nFrame); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + return eSIR_FAILURE; + } + else if ( DOT11F_WARNED( status ) ) + { + dot11fLog( pMac, LOGW, FL("There were warnings while unpacking a Measurement Request frame (0x%08x, %d bytes)"), + status, nFrame ); + PELOG2(sirDumpBuf(pMac, SIR_DBG_MODULE_ID, LOG2, pFrame, nFrame);) + } + + // & "transliterate" from a 'tDot11fMeasurementRequest' to a + // 'tpSirMacMeasReqActionFrame'... + pMeasReqFrame->actionHeader.category = mr.Category.category; + pMeasReqFrame->actionHeader.actionID = mr.Action.action; + pMeasReqFrame->actionHeader.dialogToken = mr.DialogToken.token; + + if ( 0 == mr.num_MeasurementRequest ) + { + dot11fLog( pMac, LOGE, FL("Missing mandatory IE in Measurement Request Frame.") ); + return eSIR_FAILURE; + } + else if ( 1 < mr.num_MeasurementRequest ) + { + limLog( pMac, LOGW, FL("Warning: dropping extra Measurement Request IEs!") ); + } + + pMeasReqFrame->measReqIE.type = DOT11F_EID_MEASUREMENTREQUEST; + pMeasReqFrame->measReqIE.length = DOT11F_IE_MEASUREMENTREQUEST_MIN_LEN; + pMeasReqFrame->measReqIE.measToken = mr.MeasurementRequest[0].measurement_token; + pMeasReqFrame->measReqIE.measReqMode = ( mr.MeasurementRequest[0].reserved << 3 ) | + ( mr.MeasurementRequest[0].enable << 2 ) | + ( mr.MeasurementRequest[0].request << 1 ) | + ( mr.MeasurementRequest[0].report /*<< 0*/ ); + pMeasReqFrame->measReqIE.measType = mr.MeasurementRequest[0].measurement_type; + + pMeasReqFrame->measReqIE.measReqField.channelNumber = mr.MeasurementRequest[0].channel_no; + + vos_mem_copy( pMeasReqFrame->measReqIE.measReqField.measStartTime, + mr.MeasurementRequest[0].meas_start_time, 8 ); + + pMeasReqFrame->measReqIE.measReqField.measDuration = mr.MeasurementRequest[0].meas_duration; + + return eSIR_SUCCESS; + +} // End sirConvertMeasReqFrame2Struct. +#endif + + +void +PopulateDot11fTSPEC(tSirMacTspecIE *pOld, + tDot11fIETSPEC *pDot11f) +{ + pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType; + pDot11f->tsid = pOld->tsinfo.traffic.tsid; + pDot11f->direction = pOld->tsinfo.traffic.direction; + pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy; + pDot11f->aggregation = pOld->tsinfo.traffic.aggregation; + pDot11f->psb = pOld->tsinfo.traffic.psb; + pDot11f->user_priority = pOld->tsinfo.traffic.userPrio; + pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy; + pDot11f->schedule = pOld->tsinfo.schedule.schedule; + /* As defined in IEEE 802.11-2007, section 7.3.2.30 + * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed + */ + pDot11f->size = ( pOld->nomMsduSz & 0x7fff ); + pDot11f->fixed = ( pOld->nomMsduSz & 0x8000 ) ? 1 : 0; + pDot11f->max_msdu_size = pOld->maxMsduSz; + pDot11f->min_service_int = pOld->minSvcInterval; + pDot11f->max_service_int = pOld->maxSvcInterval; + pDot11f->inactivity_int = pOld->inactInterval; + pDot11f->suspension_int = pOld->suspendInterval; + pDot11f->service_start_time = pOld->svcStartTime; + pDot11f->min_data_rate = pOld->minDataRate; + pDot11f->mean_data_rate = pOld->meanDataRate; + pDot11f->peak_data_rate = pOld->peakDataRate; + pDot11f->burst_size = pOld->maxBurstSz; + pDot11f->delay_bound = pOld->delayBound; + pDot11f->min_phy_rate = pOld->minPhyRate; + pDot11f->surplus_bw_allowance = pOld->surplusBw; + pDot11f->medium_time = pOld->mediumTime; + + pDot11f->present = 1; + +} // End PopulateDot11fTSPEC. + +void +PopulateDot11fWMMTSPEC(tSirMacTspecIE *pOld, + tDot11fIEWMMTSPEC *pDot11f) +{ + pDot11f->traffic_type = pOld->tsinfo.traffic.trafficType; + pDot11f->tsid = pOld->tsinfo.traffic.tsid; + pDot11f->direction = pOld->tsinfo.traffic.direction; + pDot11f->access_policy = pOld->tsinfo.traffic.accessPolicy; + pDot11f->aggregation = pOld->tsinfo.traffic.aggregation; + pDot11f->psb = pOld->tsinfo.traffic.psb; + pDot11f->user_priority = pOld->tsinfo.traffic.userPrio; + pDot11f->tsinfo_ack_pol = pOld->tsinfo.traffic.ackPolicy; + pDot11f->burst_size_defn = pOld->tsinfo.traffic.burstSizeDefn; + /* As defined in IEEE 802.11-2007, section 7.3.2.30 + * Nominal MSDU size: Bit[0:14]=Size, Bit[15]=Fixed + */ + pDot11f->size = ( pOld->nomMsduSz & 0x7fff ); + pDot11f->fixed = ( pOld->nomMsduSz & 0x8000 ) ? 1 : 0; + pDot11f->max_msdu_size = pOld->maxMsduSz; + pDot11f->min_service_int = pOld->minSvcInterval; + pDot11f->max_service_int = pOld->maxSvcInterval; + pDot11f->inactivity_int = pOld->inactInterval; + pDot11f->suspension_int = pOld->suspendInterval; + pDot11f->service_start_time = pOld->svcStartTime; + pDot11f->min_data_rate = pOld->minDataRate; + pDot11f->mean_data_rate = pOld->meanDataRate; + pDot11f->peak_data_rate = pOld->peakDataRate; + pDot11f->burst_size = pOld->maxBurstSz; + pDot11f->delay_bound = pOld->delayBound; + pDot11f->min_phy_rate = pOld->minPhyRate; + pDot11f->surplus_bw_allowance = pOld->surplusBw; + pDot11f->medium_time = pOld->mediumTime; + + pDot11f->version = 1; + pDot11f->present = 1; + +} // End PopulateDot11fWMMTSPEC. + +#if defined(FEATURE_WLAN_ESE) + +// Fill the ESE version currently supported +void PopulateDot11fESEVersion(tDot11fIEESEVersion *pESEVersion) +{ + pESEVersion->present = 1; + pESEVersion->version = ESE_VERSION_SUPPORTED; +} + +// Fill the ESE ie for the station. +// The State is Normal (1) +// The MBSSID for station is set to 0. +void PopulateDot11fESERadMgmtCap(tDot11fIEESERadMgmtCap *pESERadMgmtCap) +{ + pESERadMgmtCap->present = 1; + pESERadMgmtCap->mgmt_state = RM_STATE_NORMAL; + pESERadMgmtCap->mbssid_mask = 0; + pESERadMgmtCap->reserved = 0; +} + +tSirRetStatus PopulateDot11fESECckmOpaque( tpAniSirGlobal pMac, + tpSirCCKMie pCCKMie, + tDot11fIEESECckmOpaque *pDot11f ) +{ + int idx; + + if ( pCCKMie->length ) + { + if( 0 <= ( idx = FindIELocation( pMac, (tpSirRSNie)pCCKMie, DOT11F_EID_ESECCKMOPAQUE ) ) ) + { + pDot11f->present = 1; + pDot11f->num_data = pCCKMie->cckmIEdata[ idx + 1 ] - 4; // Dont include OUI + vos_mem_copy(pDot11f->data, + pCCKMie->cckmIEdata + idx + 2 + 4, // EID, len, OUI + pCCKMie->cckmIEdata[ idx + 1 ] - 4 ); // Skip OUI + } + } + + return eSIR_SUCCESS; + +} // End PopulateDot11fESECckmOpaque. + +void PopulateDot11TSRSIE(tpAniSirGlobal pMac, + tSirMacESETSRSIE *pOld, + tDot11fIEESETrafStrmRateSet *pDot11f, + tANI_U8 rate_length) +{ + pDot11f->tsid = pOld->tsid; + vos_mem_copy(pDot11f->tsrates, pOld->rates,rate_length); + pDot11f->num_tsrates = rate_length; + pDot11f->present = 1; +} +#endif + + +tSirRetStatus +PopulateDot11fTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIETCLAS *pDot11f) +{ + pDot11f->user_priority = pOld->tclas.userPrio; + pDot11f->classifier_type = pOld->tclas.classifierType; + pDot11f->classifier_mask = pOld->tclas.classifierMask; + + switch ( pDot11f->classifier_type ) + { + case SIR_MAC_TCLASTYPE_ETHERNET: + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.source, + ( tANI_U8* )&pOld->tclasParams.eth.srcAddr, 6 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.dest, + ( tANI_U8* )&pOld->tclasParams.eth.dstAddr, 6 ); + pDot11f->info.EthParams.type = pOld->tclasParams.eth.type; + break; + case SIR_MAC_TCLASTYPE_TCPUDPIP: + pDot11f->info.IpParams.version = pOld->version; + if ( SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version ) + { + vos_mem_copy( pDot11f->info.IpParams.params. + IpV4Params.source, + pOld->tclasParams.ipv4.srcIpAddr, 4 ); + vos_mem_copy( pDot11f->info.IpParams.params. + IpV4Params.dest, + pOld->tclasParams.ipv4.dstIpAddr, 4 ); + pDot11f->info.IpParams.params.IpV4Params.src_port = + pOld->tclasParams.ipv4.srcPort; + pDot11f->info.IpParams.params.IpV4Params.dest_port = + pOld->tclasParams.ipv4.dstPort; + pDot11f->info.IpParams.params.IpV4Params.DSCP = + pOld->tclasParams.ipv4.dscp; + pDot11f->info.IpParams.params.IpV4Params.proto = + pOld->tclasParams.ipv4.protocol; + pDot11f->info.IpParams.params.IpV4Params.reserved = + pOld->tclasParams.ipv4.rsvd; + } + else + { + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.source, + ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, 16 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.dest, + ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, 16 ); + pDot11f->info.IpParams.params.IpV6Params.src_port = + pOld->tclasParams.ipv6.srcPort; + pDot11f->info.IpParams.params.IpV6Params.dest_port = + pOld->tclasParams.ipv6.dstPort; + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.flow_label, + ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, 3 ); + } + break; + case SIR_MAC_TCLASTYPE_8021DQ: + pDot11f->info.Params8021dq.tag_type = pOld->tclasParams.t8021dq.tag; + break; + default: + limLog( pMac, LOGE, FL("Bad TCLAS type %d in PopulateDot11fTCLAS."), + pDot11f->classifier_type ); + return eSIR_FAILURE; + } + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fTCLAS. + +tSirRetStatus +PopulateDot11fWMMTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIEWMMTCLAS *pDot11f) +{ + pDot11f->version = 1; + pDot11f->user_priority = pOld->tclas.userPrio; + pDot11f->classifier_type = pOld->tclas.classifierType; + pDot11f->classifier_mask = pOld->tclas.classifierMask; + + switch ( pDot11f->classifier_type ) + { + case SIR_MAC_TCLASTYPE_ETHERNET: + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.source, + ( tANI_U8* )&pOld->tclasParams.eth.srcAddr, 6 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.EthParams.dest, + ( tANI_U8* )&pOld->tclasParams.eth.dstAddr, 6 ); + pDot11f->info.EthParams.type = pOld->tclasParams.eth.type; + break; + case SIR_MAC_TCLASTYPE_TCPUDPIP: + pDot11f->info.IpParams.version = pOld->version; + if ( SIR_MAC_TCLAS_IPV4 == pDot11f->info.IpParams.version ) + { + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV4Params.source, + ( tANI_U8* )pOld->tclasParams.ipv4.srcIpAddr, 4 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV4Params.dest, + ( tANI_U8* )pOld->tclasParams.ipv4.dstIpAddr, 4 ); + pDot11f->info.IpParams.params.IpV4Params.src_port = + pOld->tclasParams.ipv4.srcPort; + pDot11f->info.IpParams.params.IpV4Params.dest_port = + pOld->tclasParams.ipv4.dstPort; + pDot11f->info.IpParams.params.IpV4Params.DSCP = + pOld->tclasParams.ipv4.dscp; + pDot11f->info.IpParams.params.IpV4Params.proto = + pOld->tclasParams.ipv4.protocol; + pDot11f->info.IpParams.params.IpV4Params.reserved = + pOld->tclasParams.ipv4.rsvd; + } + else + { + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.source, + ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, 16 ); + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.dest, + ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, 16 ); + pDot11f->info.IpParams.params.IpV6Params.src_port = + pOld->tclasParams.ipv6.srcPort; + pDot11f->info.IpParams.params.IpV6Params.dest_port = + pOld->tclasParams.ipv6.dstPort; + vos_mem_copy( ( tANI_U8* )&pDot11f->info.IpParams.params. + IpV6Params.flow_label, + ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, 3 ); + } + break; + case SIR_MAC_TCLASTYPE_8021DQ: + pDot11f->info.Params8021dq.tag_type = pOld->tclasParams.t8021dq.tag; + break; + default: + limLog( pMac, LOGE, FL("Bad TCLAS type %d in PopulateDot11fTCLAS."), + pDot11f->classifier_type ); + return eSIR_FAILURE; + } + + pDot11f->present = 1; + + return eSIR_SUCCESS; + +} // End PopulateDot11fWMMTCLAS. + + +tSirRetStatus PopulateDot11fWsc(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f) +{ + + tANI_U32 wpsState; + + pDot11f->Version.present = 1; + pDot11f->Version.major = 0x01; + pDot11f->Version.minor = 0x00; + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_STATE, &wpsState) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_STATE ); + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8) wpsState; + + pDot11f->APSetupLocked.present = 0; + + pDot11f->SelectedRegistrar.present = 0; + + pDot11f->DevicePasswordID.present = 0; + + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + pDot11f->UUID_E.present = 0; + + pDot11f->RFBands.present = 0; + + pDot11f->present = 1; + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f) +{ + const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo); + tANI_U32 devicepasswdId; + + + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked; + + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar; + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_DEVICE_PASSWORD_ID, &devicepasswdId) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_DEVICE_PASSWORD_ID ); + + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = (tANI_U16) devicepasswdId; + + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pWscIeInfo->selectedRegistrarConfigMethods; + + // UUID_E and RF Bands are applicable only for dual band AP + + return eSIR_SUCCESS; +} + +tSirRetStatus DePopulateDot11fWscRegistrarInfo(tpAniSirGlobal pMac, + tDot11fIEWscBeacon *pDot11f) +{ + pDot11f->APSetupLocked.present = 0; + pDot11f->SelectedRegistrar.present = 0; + pDot11f->DevicePasswordID.present = 0; + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + return eSIR_SUCCESS; +} +tSirRetStatus PopulateDot11fProbeResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscProbeRes *pDot11f, tpPESession psessionEntry) +{ + + tSirWPSProbeRspIE *pSirWPSProbeRspIE; + + pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE; + + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) + { + pDot11f->present = 1; + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((pSirWPSProbeRspIE->Version & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (pSirWPSProbeRspIE->Version & 0x0F); + } + else + { + pDot11f->present = 0; + pDot11f->Version.present = 0; + } + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_STATE_PRESENT) + { + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8)pSirWPSProbeRspIE->wpsState; + } + else + pDot11f->WPSState.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_APSETUPLOCK_PRESENT) + { + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pSirWPSProbeRspIE->APSetupLocked; + } + else + pDot11f->APSetupLocked.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRA_PRESENT) + { + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pSirWPSProbeRspIE->SelectedRegistra; + } + else + pDot11f->SelectedRegistrar.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_DEVICEPASSWORDID_PRESENT) + { + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = pSirWPSProbeRspIE->DevicePasswordID; + } + else + pDot11f->DevicePasswordID.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT) + { + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pSirWPSProbeRspIE->SelectedRegistraCfgMethod; + } + else + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) + { + pDot11f->ResponseType.present = 1; + pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType; + } + else + pDot11f->ResponseType.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_UUIDE_PRESENT) + { + pDot11f->UUID_E.present = 1; + vos_mem_copy(pDot11f->UUID_E.uuid, pSirWPSProbeRspIE->UUID_E, WNI_CFG_WPS_UUID_LEN); + } + else + pDot11f->UUID_E.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_MANUFACTURE_PRESENT) + { + pDot11f->Manufacturer.present = 1; + pDot11f->Manufacturer.num_name = pSirWPSProbeRspIE->Manufacture.num_name; + vos_mem_copy(pDot11f->Manufacturer.name, pSirWPSProbeRspIE->Manufacture.name, + pSirWPSProbeRspIE->Manufacture.num_name); + } + else + pDot11f->Manufacturer.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) + { + pDot11f->ModelName.present = 1; + pDot11f->ModelName.num_text = pSirWPSProbeRspIE->ModelName.num_text; + vos_mem_copy(pDot11f->ModelName.text, pSirWPSProbeRspIE->ModelName.text, + pDot11f->ModelName.num_text); + } + else + pDot11f->ModelName.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_MODELNUMBER_PRESENT) + { + pDot11f->ModelNumber.present = 1; + pDot11f->ModelNumber.num_text = pSirWPSProbeRspIE->ModelNumber.num_text; + vos_mem_copy(pDot11f->ModelNumber.text, pSirWPSProbeRspIE->ModelNumber.text, + pDot11f->ModelNumber.num_text); + } + else + pDot11f->ModelNumber.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_SERIALNUMBER_PRESENT) + { + pDot11f->SerialNumber.present = 1; + pDot11f->SerialNumber.num_text = pSirWPSProbeRspIE->SerialNumber.num_text; + vos_mem_copy(pDot11f->SerialNumber.text, pSirWPSProbeRspIE->SerialNumber.text, + pDot11f->SerialNumber.num_text); + } + else + pDot11f->SerialNumber.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT) + { + pDot11f->PrimaryDeviceType.present = 1; + vos_mem_copy(pDot11f->PrimaryDeviceType.oui, pSirWPSProbeRspIE->PrimaryDeviceOUI, + sizeof(pSirWPSProbeRspIE->PrimaryDeviceOUI)); + pDot11f->PrimaryDeviceType.primary_category = (tANI_U16)pSirWPSProbeRspIE->PrimaryDeviceCategory; + pDot11f->PrimaryDeviceType.sub_category = (tANI_U16)pSirWPSProbeRspIE->DeviceSubCategory; + } + else + pDot11f->PrimaryDeviceType.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_DEVICENAME_PRESENT) + { + pDot11f->DeviceName.present = 1; + pDot11f->DeviceName.num_text = pSirWPSProbeRspIE->DeviceName.num_text; + vos_mem_copy(pDot11f->DeviceName.text, pSirWPSProbeRspIE->DeviceName.text, + pDot11f->DeviceName.num_text); + } + else + pDot11f->DeviceName.present = 0; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_CONFIGMETHODS_PRESENT) + { + pDot11f->ConfigMethods.present = 1; + pDot11f->ConfigMethods.methods = pSirWPSProbeRspIE->ConfigMethod; + } + else + pDot11f->ConfigMethods.present = 0; + + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RF_BANDS_PRESENT) + { + pDot11f->RFBands.present = 1; + pDot11f->RFBands.bands = pSirWPSProbeRspIE->RFBand; + } + else + pDot11f->RFBands.present = 0; + + return eSIR_SUCCESS; +} +tSirRetStatus PopulateDot11fAssocResWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscAssocRes *pDot11f, tpPESession psessionEntry) +{ + tSirWPSProbeRspIE *pSirWPSProbeRspIE; + + pSirWPSProbeRspIE = &psessionEntry->APWPSIEs.SirWPSProbeRspIE; + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) + { + pDot11f->present = 1; + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((pSirWPSProbeRspIE->Version & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (pSirWPSProbeRspIE->Version & 0x0F); + } + else + { + pDot11f->present = 0; + pDot11f->Version.present = 0; + } + + if(pSirWPSProbeRspIE->FieldPresent & SIR_WPS_PROBRSP_RESPONSETYPE_PRESENT) + { + pDot11f->ResponseType.present = 1; + pDot11f->ResponseType.resType = pSirWPSProbeRspIE->ResponseType; + } + else + pDot11f->ResponseType.present = 0; + + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fBeaconWPSIEs(tpAniSirGlobal pMac, tDot11fIEWscBeacon *pDot11f, tpPESession psessionEntry) +{ + + tSirWPSBeaconIE *pSirWPSBeaconIE; + + pSirWPSBeaconIE = &psessionEntry->APWPSIEs.SirWPSBeaconIE; + + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_PROBRSP_VER_PRESENT) + { + pDot11f->present = 1; + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((pSirWPSBeaconIE->Version & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (pSirWPSBeaconIE->Version & 0x0F); + } + else + { + pDot11f->present = 0; + pDot11f->Version.present = 0; + } + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_STATE_PRESENT) + { + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8)pSirWPSBeaconIE->wpsState; + } + else + pDot11f->WPSState.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_APSETUPLOCK_PRESENT) + { + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pSirWPSBeaconIE->APSetupLocked; + } + else + pDot11f->APSetupLocked.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRA_PRESENT) + { + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pSirWPSBeaconIE->SelectedRegistra; + } + else + pDot11f->SelectedRegistrar.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_DEVICEPASSWORDID_PRESENT) + { + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = pSirWPSBeaconIE->DevicePasswordID; + } + else + pDot11f->DevicePasswordID.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT) + { + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pSirWPSBeaconIE->SelectedRegistraCfgMethod; + } + else + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_UUIDE_PRESENT) + { + pDot11f->UUID_E.present = 1; + vos_mem_copy(pDot11f->UUID_E.uuid, pSirWPSBeaconIE->UUID_E, WNI_CFG_WPS_UUID_LEN); + } + else + pDot11f->UUID_E.present = 0; + + + if(pSirWPSBeaconIE->FieldPresent & SIR_WPS_BEACON_RF_BANDS_PRESENT) + { + pDot11f->RFBands.present = 1; + pDot11f->RFBands.bands = pSirWPSBeaconIE->RFBand; + } + else + pDot11f->RFBands.present = 0; + + return eSIR_SUCCESS; +} +tSirRetStatus PopulateDot11fWscInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f) +{ + tANI_U32 cfgMethods; + tANI_U32 cfgStrLen; + tANI_U32 val; + tANI_U32 wpsVersion, wpsState; + + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_VERSION, &wpsVersion) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_VERSION ); + + pDot11f->Version.present = 1; + pDot11f->Version.major = (tANI_U8) ((wpsVersion & 0xF0)>>4); + pDot11f->Version.minor = (tANI_U8) (wpsVersion & 0x0F); + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_STATE, &wpsState) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_STATE ); + + pDot11f->WPSState.present = 1; + pDot11f->WPSState.state = (tANI_U8) wpsState; + + pDot11f->APSetupLocked.present = 0; + + pDot11f->SelectedRegistrar.present = 0; + + pDot11f->DevicePasswordID.present = 0; + + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + pDot11f->ResponseType.present = 1; + if ((pMac->lim.wscIeInfo.reqType == REQ_TYPE_REGISTRAR) || + (pMac->lim.wscIeInfo.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)){ + pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X; + } + else{ + pDot11f->ResponseType.resType = RESP_TYPE_AP; + } + + /* UUID is a 16 byte long binary. Still use wlan_cfgGetStr to get it. */ + pDot11f->UUID_E.present = 1; + cfgStrLen = WNI_CFG_WPS_UUID_LEN; + if (wlan_cfgGetStr(pMac, + WNI_CFG_WPS_UUID, + pDot11f->UUID_E.uuid, + &cfgStrLen) != eSIR_SUCCESS) + { + *(pDot11f->UUID_E.uuid) = '\0'; + } + + pDot11f->Manufacturer.present = 1; + cfgStrLen = WNI_CFG_MANUFACTURER_NAME_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MANUFACTURER_NAME, + pDot11f->Manufacturer.name, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->Manufacturer.num_name = 0; + *(pDot11f->Manufacturer.name) = '\0'; + } + else + { + pDot11f->Manufacturer.num_name = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->Manufacturer.name[cfgStrLen - 1] = '\0'; + } + + pDot11f->ModelName.present = 1; + cfgStrLen = WNI_CFG_MODEL_NAME_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MODEL_NAME, + pDot11f->ModelName.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->ModelName.num_text = 0; + *(pDot11f->ModelName.text) = '\0'; + } + else + { + pDot11f->ModelName.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->ModelName.text[cfgStrLen - 1] = '\0'; + } + + pDot11f->ModelNumber.present = 1; + cfgStrLen = WNI_CFG_MODEL_NUMBER_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MODEL_NUMBER, + pDot11f->ModelNumber.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->ModelNumber.num_text = 0; + *(pDot11f->ModelNumber.text) = '\0'; + } + else + { + pDot11f->ModelNumber.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->ModelNumber.text[cfgStrLen - 1] = '\0'; + } + + pDot11f->SerialNumber.present = 1; + cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_VERSION_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MANUFACTURER_PRODUCT_VERSION, + pDot11f->SerialNumber.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->SerialNumber.num_text = 0; + *(pDot11f->SerialNumber.text) = '\0'; + } + else + { + pDot11f->SerialNumber.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->SerialNumber.text[cfgStrLen - 1] = '\0'; + } + + pDot11f->PrimaryDeviceType.present = 1; + + if (wlan_cfgGetInt(pMac, WNI_CFG_WPS_PRIMARY_DEVICE_CATEGORY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get prim device category failed")); + } + else + pDot11f->PrimaryDeviceType.primary_category = (tANI_U16) val; + + if (wlan_cfgGetInt(pMac, WNI_CFG_WPS_PIMARY_DEVICE_OUI, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get prim device OUI failed")); + } + else + { + *(pDot11f->PrimaryDeviceType.oui) = (tANI_U8)((val >> 24)& 0xff); + *(pDot11f->PrimaryDeviceType.oui+1) = (tANI_U8)((val >> 16)& 0xff); + *(pDot11f->PrimaryDeviceType.oui+2) = (tANI_U8)((val >> 8)& 0xff); + *(pDot11f->PrimaryDeviceType.oui+3) = (tANI_U8)((val & 0xff)); + } + + if (wlan_cfgGetInt(pMac, WNI_CFG_WPS_DEVICE_SUB_CATEGORY, &val) != eSIR_SUCCESS) + { + limLog(pMac, LOGP, FL("cfg get prim device sub category failed")); + } + else + pDot11f->PrimaryDeviceType.sub_category = (tANI_U16) val; + + pDot11f->DeviceName.present = 1; + cfgStrLen = WNI_CFG_MANUFACTURER_PRODUCT_NAME_LEN - 1; + if (wlan_cfgGetStr(pMac, + WNI_CFG_MANUFACTURER_PRODUCT_NAME, + pDot11f->DeviceName.text, + &cfgStrLen) != eSIR_SUCCESS) + { + pDot11f->DeviceName.num_text = 0; + *(pDot11f->DeviceName.text) = '\0'; + } + else + { + pDot11f->DeviceName.num_text = (tANI_U8) (cfgStrLen & 0x000000FF); + pDot11f->DeviceName.text[cfgStrLen - 1] = '\0'; + } + + if (wlan_cfgGetInt(pMac, + WNI_CFG_WPS_CFG_METHOD, + &cfgMethods) != eSIR_SUCCESS) + { + pDot11f->ConfigMethods.present = 0; + pDot11f->ConfigMethods.methods = 0; + } + else + { + pDot11f->ConfigMethods.present = 1; + pDot11f->ConfigMethods.methods = (tANI_U16) (cfgMethods & 0x0000FFFF); + } + + pDot11f->RFBands.present = 0; + + pDot11f->present = 1; + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f) +{ + const struct sLimWscIeInfo *const pWscIeInfo = &(pMac->lim.wscIeInfo); + tANI_U32 devicepasswdId; + + pDot11f->APSetupLocked.present = 1; + pDot11f->APSetupLocked.fLocked = pWscIeInfo->apSetupLocked; + + pDot11f->SelectedRegistrar.present = 1; + pDot11f->SelectedRegistrar.selected = pWscIeInfo->selectedRegistrar; + + if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_DEVICE_PASSWORD_ID, &devicepasswdId) != eSIR_SUCCESS) + limLog(pMac, LOGP,"Failed to cfg get id %d", WNI_CFG_WPS_DEVICE_PASSWORD_ID ); + + pDot11f->DevicePasswordID.present = 1; + pDot11f->DevicePasswordID.id = (tANI_U16) devicepasswdId; + + pDot11f->SelectedRegistrarConfigMethods.present = 1; + pDot11f->SelectedRegistrarConfigMethods.methods = pWscIeInfo->selectedRegistrarConfigMethods; + + // UUID_E and RF Bands are applicable only for dual band AP + + return eSIR_SUCCESS; +} + +tSirRetStatus DePopulateDot11fWscRegistrarInfoInProbeRes(tpAniSirGlobal pMac, + tDot11fIEWscProbeRes *pDot11f) +{ + pDot11f->APSetupLocked.present = 0; + pDot11f->SelectedRegistrar.present = 0; + pDot11f->DevicePasswordID.present = 0; + pDot11f->SelectedRegistrarConfigMethods.present = 0; + + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fAssocResWscIE(tpAniSirGlobal pMac, + tDot11fIEWscAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq) +{ + tDot11fIEWscAssocReq parsedWscAssocReq = { 0, }; + tANI_U8 *wscIe; + + + wscIe = limGetWscIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata, pRcvdAssocReq->addIE.length); + if(wscIe != NULL) + { + // retreive WSC IE from given AssocReq + dot11fUnpackIeWscAssocReq( pMac, + wscIe + 2 + 4, // EID, length, OUI + wscIe[ 1 ] - 4, // length without OUI + &parsedWscAssocReq ); + pDot11f->present = 1; + // version has to be 0x10 + pDot11f->Version.present = 1; + pDot11f->Version.major = 0x1; + pDot11f->Version.minor = 0x0; + + pDot11f->ResponseType.present = 1; + + if ((parsedWscAssocReq.RequestType.reqType == REQ_TYPE_REGISTRAR) || + (parsedWscAssocReq.RequestType.reqType == REQ_TYPE_WLAN_MANAGER_REGISTRAR)) + { + pDot11f->ResponseType.resType = RESP_TYPE_ENROLLEE_OPEN_8021X; + } + else + { + pDot11f->ResponseType.resType = RESP_TYPE_AP; + } + // Version infomration should be taken from our capability as well as peers + // TODO: currently it takes from peers only + if(parsedWscAssocReq.VendorExtension.present && + parsedWscAssocReq.VendorExtension.Version2.present) + { + pDot11f->VendorExtension.present = 1; + pDot11f->VendorExtension.vendorId[0] = 0x00; + pDot11f->VendorExtension.vendorId[1] = 0x37; + pDot11f->VendorExtension.vendorId[2] = 0x2A; + pDot11f->VendorExtension.Version2.present = 1; + pDot11f->VendorExtension.Version2.major = parsedWscAssocReq.VendorExtension.Version2.major; + pDot11f->VendorExtension.Version2.minor = parsedWscAssocReq.VendorExtension.Version2.minor; + } + } + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11AssocResP2PIE(tpAniSirGlobal pMac, + tDot11fIEP2PAssocRes *pDot11f, + tpSirAssocReq pRcvdAssocReq) +{ + tANI_U8 *p2pIe; + + p2pIe = limGetP2pIEPtr(pMac, pRcvdAssocReq->addIE.addIEdata, pRcvdAssocReq->addIE.length); + if(p2pIe != NULL) + { + pDot11f->present = 1; + pDot11f->P2PStatus.present = 1; + pDot11f->P2PStatus.status = eSIR_SUCCESS; + pDot11f->ExtendedListenTiming.present = 0; + } + return eSIR_SUCCESS; +} + +#if defined WLAN_FEATURE_VOWIFI + +tSirRetStatus PopulateDot11fWFATPC( tpAniSirGlobal pMac, + tDot11fIEWFATPC *pDot11f, tANI_U8 txPower, tANI_U8 linkMargin ) +{ + pDot11f->txPower = txPower; + pDot11f->linkMargin = linkMargin; + pDot11f->present = 1; + + return eSIR_SUCCESS; +} + +tSirRetStatus PopulateDot11fBeaconReport( tpAniSirGlobal pMac, tDot11fIEMeasurementReport *pDot11f, tSirMacBeaconReport *pBeaconReport ) +{ + + pDot11f->report.Beacon.regClass = pBeaconReport->regClass; + pDot11f->report.Beacon.channel = pBeaconReport->channel; + vos_mem_copy( pDot11f->report.Beacon.meas_start_time, pBeaconReport->measStartTime, + sizeof(pDot11f->report.Beacon.meas_start_time) ); + pDot11f->report.Beacon.meas_duration = pBeaconReport->measDuration; + pDot11f->report.Beacon.condensed_PHY = pBeaconReport->phyType; + pDot11f->report.Beacon.reported_frame_type = !pBeaconReport->bcnProbeRsp; + pDot11f->report.Beacon.RCPI = pBeaconReport->rcpi; + pDot11f->report.Beacon.RSNI = pBeaconReport->rsni; + vos_mem_copy( pDot11f->report.Beacon.BSSID, pBeaconReport->bssid, sizeof(tSirMacAddr)); + pDot11f->report.Beacon.antenna_id = pBeaconReport->antennaId; + pDot11f->report.Beacon.parent_TSF = pBeaconReport->parentTSF; + + if( pBeaconReport->numIes ) + { + pDot11f->report.Beacon.BeaconReportFrmBody.present = 1; + vos_mem_copy( pDot11f->report.Beacon.BeaconReportFrmBody.reportedFields, + pBeaconReport->Ies, pBeaconReport->numIes ); + pDot11f->report.Beacon.BeaconReportFrmBody.num_reportedFields = pBeaconReport->numIes; + } + + return eSIR_SUCCESS; + +} + +tSirRetStatus PopulateDot11fRRMIe( tpAniSirGlobal pMac, tDot11fIERRMEnabledCap *pDot11f, tpPESession psessionEntry ) +{ + tpRRMCaps pRrmCaps; + + pRrmCaps = rrmGetCapabilities( pMac, psessionEntry ); + + pDot11f->LinkMeasurement = pRrmCaps->LinkMeasurement ; + pDot11f->NeighborRpt = pRrmCaps->NeighborRpt ; + pDot11f->parallel = pRrmCaps->parallel ; + pDot11f->repeated = pRrmCaps->repeated ; + pDot11f->BeaconPassive = pRrmCaps->BeaconPassive ; + pDot11f->BeaconActive = pRrmCaps->BeaconActive ; + pDot11f->BeaconTable = pRrmCaps->BeaconTable ; + pDot11f->BeaconRepCond = pRrmCaps->BeaconRepCond ; + pDot11f->FrameMeasurement = pRrmCaps->FrameMeasurement ; + pDot11f->ChannelLoad = pRrmCaps->ChannelLoad ; + pDot11f->NoiseHistogram = pRrmCaps->NoiseHistogram ; + pDot11f->statistics = pRrmCaps->statistics ; + pDot11f->LCIMeasurement = pRrmCaps->LCIMeasurement ; + pDot11f->LCIAzimuth = pRrmCaps->LCIAzimuth ; + pDot11f->TCMCapability = pRrmCaps->TCMCapability ; + pDot11f->triggeredTCM = pRrmCaps->triggeredTCM ; + pDot11f->APChanReport = pRrmCaps->APChanReport ; + pDot11f->RRMMIBEnabled = pRrmCaps->RRMMIBEnabled ; + pDot11f->operatingChanMax = pRrmCaps->operatingChanMax ; + pDot11f->nonOperatinChanMax = pRrmCaps->nonOperatingChanMax ; + pDot11f->MeasurementPilot = pRrmCaps->MeasurementPilot ; + pDot11f->MeasurementPilotEnabled = pRrmCaps->MeasurementPilotEnabled ; + pDot11f->NeighborTSFOffset = pRrmCaps->NeighborTSFOffset ; + pDot11f->RCPIMeasurement = pRrmCaps->RCPIMeasurement ; + pDot11f->RSNIMeasurement = pRrmCaps->RSNIMeasurement ; + pDot11f->BssAvgAccessDelay = pRrmCaps->BssAvgAccessDelay ; + pDot11f->BSSAvailAdmission = pRrmCaps->BSSAvailAdmission ; + pDot11f->AntennaInformation = pRrmCaps->AntennaInformation ; + + pDot11f->present = 1; + return eSIR_SUCCESS; +} +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R +void PopulateMDIE( tpAniSirGlobal pMac, + tDot11fIEMobilityDomain *pDot11f, tANI_U8 mdie[SIR_MDIE_SIZE] ) +{ + pDot11f->present = 1; + pDot11f->MDID = (tANI_U16)((mdie[1] << 8) | (mdie[0])); + + // Plugfest fix + pDot11f->overDSCap = (mdie[2] & 0x01); + pDot11f->resourceReqCap = ((mdie[2] >> 1) & 0x01); + +} + +void PopulateFTInfo( tpAniSirGlobal pMac, + tDot11fIEFTInfo *pDot11f ) +{ + pDot11f->present = 1; + pDot11f->IECount = 0; //TODO: put valid data during reassoc. + //All other info is zero. + +} +#endif + +void PopulateDot11fAssocRspRates ( tpAniSirGlobal pMac, tDot11fIESuppRates *pSupp, + tDot11fIEExtSuppRates *pExt, tANI_U16 *_11bRates, tANI_U16 *_11aRates ) +{ + tANI_U8 num_supp = 0, num_ext = 0; + tANI_U8 i,j; + + for( i = 0 ; (i < SIR_NUM_11B_RATES && _11bRates[i]) ; i++, num_supp++ ) + { + pSupp->rates[num_supp] = (tANI_U8)_11bRates[i]; + } + for( j = 0 ; (j < SIR_NUM_11A_RATES && _11aRates[j]) ; j++ ) + { + if( num_supp < 8 ) + pSupp->rates[num_supp++] = (tANI_U8)_11aRates[j]; + else + pExt->rates[num_ext++] = (tANI_U8)_11aRates[j]; + } + + if( num_supp ) + { + pSupp->num_rates = num_supp; + pSupp->present = 1; + } + if( num_ext ) + { + pExt->num_rates = num_ext; + pExt->present = 1; + } +} + +void PopulateDot11fTimeoutInterval( tpAniSirGlobal pMac, + tDot11fIETimeoutInterval *pDot11f, + tANI_U8 type, tANI_U32 value ) +{ + pDot11f->present = 1; + pDot11f->timeoutType = type; + pDot11f->timeoutValue = value; +} +#ifdef SAP_AUTH_OFFLOAD +tSirRetStatus +sap_auth_offload_construct_rsn_opaque( tDot11fIERSN *pdot11f_rsn, + tDot11fIERSNOpaque *pdot11f) +{ + tANI_U32 data_len=0; + tANI_U8 *ptr; + tANI_U32 element_len=0; + tANI_U32 count=0; + ptr = (tANI_U8 *)pdot11f->data; + if (pdot11f_rsn->present) + { + pdot11f->present = pdot11f_rsn->present; + element_len = sizeof(pdot11f_rsn->version); + vos_mem_copy(ptr, &pdot11f_rsn->version, element_len); + ptr += element_len; + data_len += element_len; + element_len = sizeof(pdot11f_rsn->gp_cipher_suite); + vos_mem_copy(ptr, pdot11f_rsn->gp_cipher_suite, element_len); + ptr += element_len; + data_len += element_len; + + if (pdot11f_rsn->pwise_cipher_suite_count) + { + element_len = sizeof(pdot11f_rsn->pwise_cipher_suite_count); + vos_mem_copy(ptr, + &pdot11f_rsn->pwise_cipher_suite_count, + element_len); + ptr += element_len; + data_len += element_len; + for (count = 0; count < pdot11f_rsn->pwise_cipher_suite_count; + count++) + { + element_len = DOT11F_RSN_OUI_SIZE; + vos_mem_copy(ptr, + &pdot11f_rsn->pwise_cipher_suites[count][0], + element_len); + ptr += element_len; + data_len += element_len; + } + } + + if (pdot11f_rsn->akm_suite_count) + { + element_len = sizeof(pdot11f_rsn->akm_suite_count); + vos_mem_copy(ptr, &pdot11f_rsn->akm_suite_count, element_len); + ptr += element_len; + data_len += element_len; + for (count = 0; count < pdot11f_rsn->akm_suite_count; count++) + { + element_len = DOT11F_RSN_OUI_SIZE; + vos_mem_copy(ptr, + &pdot11f_rsn->akm_suites[count][0], + element_len); + ptr += element_len; + data_len += element_len; + } + } + + element_len = sizeof(pdot11f_rsn->RSN_Cap); + vos_mem_copy(ptr, pdot11f_rsn->RSN_Cap, element_len); + ptr += element_len; + data_len += element_len; + } + pdot11f->num_data = data_len; + return eSIR_SUCCESS; +} + +void +sap_auth_offload_update_rsn_ie( tpAniSirGlobal pmac, + tDot11fIERSNOpaque *pdot11f) +{ + tDot11fIERSN *pdot11f_rsn; + pdot11f_rsn = vos_mem_malloc(sizeof(tDot11fIERSN)); + vos_mem_set(pdot11f_rsn, sizeof(tDot11fIERSN), 0); + /* Assign RSN IE for Software AP Authentication offload security */ + if (pmac->sap_auth_offload && pmac->sap_auth_offload_sec_type) + { + switch (pmac->sap_auth_offload_sec_type) + { + case eSIR_OFFLOAD_WPA2PSK_CCMP: + /* Only Support one kind of Cipher Suit for + * Software AP authentication offload + */ + pdot11f_rsn->present = 1; + pdot11f_rsn->version = 1; + vos_mem_copy(pdot11f_rsn->gp_cipher_suite, + &sirRSNOui[DOT11F_RSN_CSE_CCMP][0], + DOT11F_RSN_OUI_SIZE); + pdot11f_rsn->pwise_cipher_suite_count = 1; + vos_mem_copy(&(pdot11f_rsn->pwise_cipher_suites[0][0]), + &sirRSNOui[DOT11F_RSN_CSE_CCMP][0], + DOT11F_RSN_OUI_SIZE); + pdot11f_rsn->akm_suite_count = 1; + vos_mem_copy(&(pdot11f_rsn->akm_suites[0][0]), + &sirRSNOui[DOT11F_RSN_CSE_TKIP][0], + DOT11F_RSN_OUI_SIZE); + pdot11f_rsn->pmkid_count = 0; + /* Construct RSN IE into RSNOpaque*/ + sap_auth_offload_construct_rsn_opaque(pdot11f_rsn, pdot11f); + break; + default: + dot11fLog( pmac, LOGE, + FL("The security type is not definied for " + "Software AP authentication offload!\n")); + break; + } + } +} +#endif /* SAP_AUTH_OFFLOAD */ + +/** + * sir_copy_hs20_ie() - Update HS 2.0 Information Element. + * @dest: dest HS IE buffer to be updated + * @src: src HS IE buffer + * + * Update HS2.0 IE info from src to dest + * + * Return: void + */ +void sir_copy_hs20_ie(tDot11fIEhs20vendor_ie *dest, tDot11fIEhs20vendor_ie *src) +{ + if (src->present) { + vos_mem_copy(dest, src, + sizeof(tDot11fIEhs20vendor_ie) - + sizeof(src->hs_id)); + if (src->hs_id_present) + vos_mem_copy(&dest->hs_id, + &src->hs_id, + sizeof(src->hs_id)); + } +} + +// parserApi.c ends here. diff --git a/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsApi.c b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsApi.c new file mode 100644 index 000000000000..d1105bec5ac3 --- /dev/null +++ b/drivers/staging/prima/CORE/SYS/legacy/src/utils/src/utilsApi.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +//================================================================== +// +// File: utilsApi.cc +// +// Description: Implemention of a few utility routines. +// +// Author: Neelay Das +// +// +// +// Change gHistory: +// 12/15/2003 - NDA - Initial version. +// +//=================================================================== + + +#include "utilsApi.h" + + + + + +// ------------------------------------------------------------------- +/** + * sirDumpBuf() + * + * FUNCTION: + * This function is called to dump a buffer with a certain level + * + * LOGIC: + * + * ASSUMPTIONS: + * None. + * + * NOTE: + * + * @param pBuf: buffer pointer + * @return None. + */ +void +sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size) +{ + tANI_U32 i; + + if (level > pMac->utils.gLogDbgLevel[LOG_INDEX_FOR_MODULE(modId)]) + return; + + logDbg(pMac, modId, level, FL("Dumping %d bytes in host order\n"), size); + + for (i=0; (i+7)length = pNew->num_ssid; + vos_mem_copy( pOld->ssId, pNew->ssid, pNew->num_ssid ); +} + +void ConvertSuppRates(tpAniSirGlobal pMac, + tSirMacRateSet *pOld, + tDot11fIESuppRates *pNew) +{ + pOld->numRates = pNew->num_rates; + vos_mem_copy( pOld->rate, pNew->rates, pNew->num_rates ); +} + +void ConvertExtSuppRates(tpAniSirGlobal pMac, + tSirMacRateSet *pOld, + tDot11fIEExtSuppRates *pNew) +{ + pOld->numRates = pNew->num_rates; + vos_mem_copy( pOld->rate, pNew->rates, pNew->num_rates ); +} + + +void ConvertQOSCaps(tpAniSirGlobal pMac, + tSirMacQosCapabilityIE *pOld, + tDot11fIEQOSCapsAp *pNew) +{ + pOld->type = 46; + pOld->length = 1; + + pOld->qosInfo.count = pNew->count; +} + + +void ConvertQOSCapsStation(tpAniSirGlobal pMac, + tSirMacQosCapabilityStaIE *pOld, + tDot11fIEQOSCapsStation *pNew) +{ + pOld->type = 46; + pOld->length = 1; + + pOld->qosInfo.moreDataAck = pNew->more_data_ack; + pOld->qosInfo.maxSpLen = pNew->max_sp_length; + pOld->qosInfo.qack = pNew->qack; + pOld->qosInfo.acbe_uapsd = pNew->acbe_uapsd; + pOld->qosInfo.acbk_uapsd = pNew->acbk_uapsd; + pOld->qosInfo.acvi_uapsd = pNew->acvi_uapsd; + pOld->qosInfo.acvo_uapsd = pNew->acvo_uapsd; +} + +tSirRetStatus ConvertWPA(tpAniSirGlobal pMac, + tSirMacWpaInfo *pOld, + tDot11fIEWPA *pNew) +{ + // This is awful, I know, but the old code just rammed the IE into an + // array... + tANI_U8 buffer[257]; + tANI_U32 status, written = 0, nbuffer = 257; + status = dot11fPackIeWPA( pMac, pNew, buffer, nbuffer, &written ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOG2, FL("Failed to re-pack the WPA IE (0x%0x" + "8).\n"), status); + return eSIR_FAILURE; + } + + pOld->length = (tANI_U8)written - 2; + vos_mem_copy( pOld->info, buffer + 2, pOld->length ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertWPAOpaque( tpAniSirGlobal pMac, + tSirMacWpaInfo *pOld, + tDot11fIEWPAOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the OUI! + pOld->length = pNew->num_data + 4; + pOld->info[ 0 ] = 0x00; + pOld->info[ 1 ] = 0x50; + pOld->info[ 2 ] = 0xf2; + pOld->info[ 3 ] = 0x01; + vos_mem_copy( pOld->info + 4, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertWscOpaque( tpAniSirGlobal pMac, + tSirAddie *pOld, + tDot11fIEWscIEOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the vendorIE and OUI ! + tANI_U8 curAddIELen = pOld->length; + + pOld->length = curAddIELen + pNew->num_data + 6; + pOld->addIEdata[ curAddIELen++ ] = 0xdd; + pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4; + pOld->addIEdata[ curAddIELen++ ] = 0x00; + pOld->addIEdata[ curAddIELen++ ] = 0x50; + pOld->addIEdata[ curAddIELen++ ] = 0xf2; + pOld->addIEdata[ curAddIELen++ ] = 0x04; + vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertP2POpaque( tpAniSirGlobal pMac, + tSirAddie *pOld, + tDot11fIEP2PIEOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the vendorIE and OUI ! + tANI_U8 curAddIELen = pOld->length; + + pOld->length = curAddIELen + pNew->num_data + 6; + pOld->addIEdata[ curAddIELen++ ] = 0xdd; + pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4; + pOld->addIEdata[ curAddIELen++ ] = 0x50; + pOld->addIEdata[ curAddIELen++ ] = 0x6f; + pOld->addIEdata[ curAddIELen++ ] = 0x9A; + pOld->addIEdata[ curAddIELen++ ] = 0x09; + vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} + +#ifdef WLAN_FEATURE_WFD +tSirRetStatus ConvertWFDOpaque( tpAniSirGlobal pMac, + tSirAddie *pOld, + tDot11fIEWFDIEOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. Note that we need to explicitly add the vendorIE and OUI ! + tANI_U8 curAddIELen = pOld->length; + + pOld->length = curAddIELen + pNew->num_data + 6; + pOld->addIEdata[ curAddIELen++ ] = 0xdd; + pOld->addIEdata[ curAddIELen++ ] = pNew->num_data + 4; + pOld->addIEdata[ curAddIELen++ ] = 0x50; + pOld->addIEdata[ curAddIELen++ ] = 0x6f; + pOld->addIEdata[ curAddIELen++ ] = 0x9A; + pOld->addIEdata[ curAddIELen++ ] = 0x0a; + vos_mem_copy( pOld->addIEdata + curAddIELen, pNew->data, pNew->num_data ); + + return eSIR_SUCCESS; +} +#endif + +tSirRetStatus ConvertRSN(tpAniSirGlobal pMac, + tSirMacRsnInfo *pOld, + tDot11fIERSN *pNew) +{ + tANI_U8 buffer[257]; + tANI_U32 status, written = 0, nbuffer = 257; + status = dot11fPackIeRSN( pMac, pNew, buffer, nbuffer, &written ); + if ( DOT11F_FAILED( status ) ) + { + dot11fLog(pMac, LOG2, FL("Failed to re-pack the RSN IE (0x%0x" + "8).\n"), status); + return eSIR_FAILURE; + } + + pOld->length = (tANI_U8)written - 2; + vos_mem_copy( pOld->info, buffer + 2, pOld->length ); + + return eSIR_SUCCESS; +} + +tSirRetStatus ConvertRSNOpaque( tpAniSirGlobal pMac, + tSirMacRsnInfo *pOld, + tDot11fIERSNOpaque *pNew ) +{ + // This is awful, I know, but the old code just rammed the IE into + // an opaque array. + pOld->length = pNew->num_data; + vos_mem_copy( pOld->info, pNew->data, pOld->length ); + + return eSIR_SUCCESS; +} + +void ConvertPowerCaps(tpAniSirGlobal pMac, + tSirMacPowerCapabilityIE *pOld, + tDot11fIEPowerCaps *pNew) +{ + pOld->type = 33; + pOld->length = 2; + pOld->minTxPower = pNew->minTxPower; + pOld->maxTxPower = pNew->maxTxPower; +} + +void ConvertSuppChannels(tpAniSirGlobal pMac, + tSirMacSupportedChannelIE *pOld, + tDot11fIESuppChannels *pNew) +{ + pOld->type = 36; + pOld->length = ( pNew->num_bands * 2 ); + vos_mem_copy( ( tANI_U8* )pOld->supportedChannels, ( tANI_U8* )pNew->bands, pOld->length ); +} + +void ConvertCFParams(tpAniSirGlobal pMac, + tSirMacCfParamSet *pOld, + tDot11fIECFParams *pNew) +{ + pOld->cfpCount = pNew->cfp_count; + pOld->cfpPeriod = pNew->cfp_period; + pOld->cfpMaxDuration = pNew->cfp_maxduration; + pOld->cfpDurRemaining = pNew->cfp_durremaining; +} + +void ConvertFHParams (tpAniSirGlobal pMac, + tSirMacFHParamSet *pOld, + tDot11fIEFHParamSet *pNew) +{ + pOld->dwellTime = pNew->dwell_time; + pOld->hopSet = pNew->hop_set; + pOld->hopPattern = pNew->hop_pattern; + pOld->hopIndex = pNew->hop_index; +} + +void ConvertTIM(tpAniSirGlobal pMac, + tSirMacTim *pOld, + tDot11fIETIM *pNew) +{ + pOld->dtimCount = pNew->dtim_count; + pOld->dtimPeriod = pNew->dtim_period; + pOld->bitmapControl = pNew->bmpctl; + pOld->bitmapLength = pNew->num_vbmp; + + vos_mem_copy( pOld->bitmap, pNew->vbmp, pNew->num_vbmp ); +} + +void ConvertCountry(tpAniSirGlobal pMac, + tSirCountryInformation *pOld, + tDot11fIECountry *pNew) +{ + int i; + + vos_mem_copy( pOld->countryString, pNew->country, COUNTRY_STRING_LENGTH ); + + pOld->numIntervals = pNew->num_triplets; + + for (i = 0; i < pNew->num_triplets; ++i) + { + pOld->channelTransmitPower[i].channelNumber = pNew->triplets[i][0]; + pOld->channelTransmitPower[i].numChannel = pNew->triplets[i][1]; + pOld->channelTransmitPower[i].maxTransmitPower = pNew->triplets[i][2]; + } +} + +void ConvertWMMParams(tpAniSirGlobal pMac, + tSirMacEdcaParamSetIE *pOld, + tDot11fIEWMMParams *pNew) +{ + pOld->type = 221; + pOld->length = 24; + + vos_mem_copy( ( tANI_U8* )&pOld->qosInfo, ( tANI_U8* )&pNew->qosInfo, 1 ); + + pOld->acbe.aci.aifsn = pNew->acbe_aifsn; + pOld->acbe.aci.acm = pNew->acbe_acm; + pOld->acbe.aci.aci = pNew->acbe_aci; + pOld->acbe.cw.min = pNew->acbe_acwmin; + pOld->acbe.cw.max = pNew->acbe_acwmax; + pOld->acbe.txoplimit = pNew->acbe_txoplimit; + + pOld->acbk.aci.aifsn = pNew->acbk_aifsn; + pOld->acbk.aci.acm = pNew->acbk_acm; + pOld->acbk.aci.aci = pNew->acbk_aci; + pOld->acbk.cw.min = pNew->acbk_acwmin; + pOld->acbk.cw.max = pNew->acbk_acwmax; + pOld->acbk.txoplimit = pNew->acbk_txoplimit; + + pOld->acvi.aci.aifsn = pNew->acvi_aifsn; + pOld->acvi.aci.acm = pNew->acvi_acm; + pOld->acvi.aci.aci = pNew->acvi_aci; + pOld->acvi.cw.min = pNew->acvi_acwmin; + pOld->acvi.cw.max = pNew->acvi_acwmax; + pOld->acvi.txoplimit = pNew->acvi_txoplimit; + + pOld->acvo.aci.aifsn = pNew->acvo_aifsn; + pOld->acvo.aci.acm = pNew->acvo_acm; + pOld->acvo.aci.aci = pNew->acvo_aci; + pOld->acvo.cw.min = pNew->acvo_acwmin; + pOld->acvo.cw.max = pNew->acvo_acwmax; + pOld->acvo.txoplimit = pNew->acvo_txoplimit; +} + +void ConvertERPInfo(tpAniSirGlobal pMac, + tSirMacErpInfo *pOld, + tDot11fIEERPInfo *pNew) +{ + pOld->nonErpPresent = pNew->non_erp_present; + pOld->useProtection = pNew->use_prot; + pOld->barkerPreambleMode = pNew->barker_preamble; +} + +void ConvertEDCAParam(tpAniSirGlobal pMac, + tSirMacEdcaParamSetIE *pOld, + tDot11fIEEDCAParamSet *pNew) +{ + pOld->type = 12; + pOld->length = 20; + + vos_mem_copy( ( tANI_U8* )&pOld->qosInfo, ( tANI_U8* )&pNew->qos, 1 ); + + pOld->acbe.aci.aifsn = pNew->acbe_aifsn; + pOld->acbe.aci.acm = pNew->acbe_acm; + pOld->acbe.aci.aci = pNew->acbe_aci; + pOld->acbe.cw.min = pNew->acbe_acwmin; + pOld->acbe.cw.max = pNew->acbe_acwmax; + pOld->acbe.txoplimit = pNew->acbe_txoplimit; + + pOld->acbk.aci.aifsn = pNew->acbk_aifsn; + pOld->acbk.aci.acm = pNew->acbk_acm; + pOld->acbk.aci.aci = pNew->acbk_aci; + pOld->acbk.cw.min = pNew->acbk_acwmin; + pOld->acbk.cw.max = pNew->acbk_acwmax; + pOld->acbk.txoplimit = pNew->acbk_txoplimit; + + pOld->acvi.aci.aifsn = pNew->acvi_aifsn; + pOld->acvi.aci.acm = pNew->acvi_acm; + pOld->acvi.aci.aci = pNew->acvi_aci; + pOld->acvi.cw.min = pNew->acvi_acwmin; + pOld->acvi.cw.max = pNew->acvi_acwmax; + pOld->acvi.txoplimit = pNew->acvi_txoplimit; + + pOld->acvo.aci.aifsn = pNew->acvo_aifsn; + pOld->acvo.aci.acm = pNew->acvo_acm; + pOld->acvo.aci.aci = pNew->acvo_aci; + pOld->acvo.cw.min = pNew->acvo_acwmin; + pOld->acvo.cw.max = pNew->acvo_acwmax; + pOld->acvo.txoplimit = pNew->acvo_txoplimit; + +} + +void ConvertTSPEC(tpAniSirGlobal pMac, + tSirMacTspecIE *pOld, + tDot11fIETSPEC *pNew) +{ + pOld->tsinfo.traffic.trafficType = (tANI_U16)pNew->traffic_type; + pOld->tsinfo.traffic.tsid = (tANI_U16)pNew->tsid; + pOld->tsinfo.traffic.direction = (tANI_U16)pNew->direction; + pOld->tsinfo.traffic.accessPolicy = (tANI_U16)pNew->access_policy; + pOld->tsinfo.traffic.aggregation = (tANI_U16)pNew->aggregation; + pOld->tsinfo.traffic.psb = (tANI_U16)pNew->psb; + pOld->tsinfo.traffic.userPrio = (tANI_U16)pNew->user_priority; + pOld->tsinfo.traffic.ackPolicy = (tANI_U16)pNew->tsinfo_ack_pol; + + pOld->tsinfo.schedule.schedule = (tANI_U8)pNew->schedule; + + pOld->nomMsduSz = pNew->size; + pOld->maxMsduSz = pNew->max_msdu_size; + pOld->minSvcInterval = pNew->min_service_int; + pOld->maxSvcInterval = pNew->max_service_int; + pOld->inactInterval = pNew->inactivity_int; + pOld->suspendInterval = pNew->suspension_int; + pOld->svcStartTime = pNew->service_start_time; + pOld->minDataRate = pNew->min_data_rate; + pOld->meanDataRate = pNew->mean_data_rate; + pOld->peakDataRate = pNew->peak_data_rate; + pOld->maxBurstSz = pNew->burst_size; + pOld->delayBound = pNew->delay_bound; + pOld->minPhyRate = pNew->min_phy_rate; + pOld->surplusBw = pNew->surplus_bw_allowance; + pOld->mediumTime = pNew->medium_time; +} + +tSirRetStatus ConvertTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIETCLAS *pNew) +{ + tANI_U32 length = 0; + + if ( DOT11F_FAILED( dot11fGetPackedIETCLAS( pMac, pNew, &length ) ) ) + { + return eSIR_FAILURE; + } + + pOld->tclas.type = DOT11F_EID_TCLAS; + pOld->tclas.length = (tANI_U8)length; + pOld->tclas.userPrio = pNew->user_priority; + pOld->tclas.classifierType = pNew->classifier_type; + pOld->tclas.classifierMask = pNew->classifier_mask; + + switch ( pNew->classifier_type ) + { + case 0: + vos_mem_copy( pOld->tclasParams.eth.srcAddr, pNew->info.EthParams.source, 6 ); + vos_mem_copy( pOld->tclasParams.eth.dstAddr, pNew->info.EthParams.dest, 6 ); + pOld->tclasParams.eth.type = pNew->info.EthParams.type; + break; + case 1: + pOld->version = pNew->info.IpParams.version; + if ( 4 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv4.version = 4; + vos_mem_copy( pOld->tclasParams.ipv4.srcIpAddr, + pNew->info.IpParams.params.IpV4Params.source, 4 ); + vos_mem_copy( pOld->tclasParams.ipv4.dstIpAddr, + pNew->info.IpParams.params.IpV4Params.dest, 4 ); + pOld->tclasParams.ipv4.srcPort = pNew->info.IpParams.params.IpV4Params.src_port; + pOld->tclasParams.ipv4.dstPort = pNew->info.IpParams.params.IpV4Params.dest_port; + pOld->tclasParams.ipv4.dscp = pNew->info.IpParams.params.IpV4Params.DSCP; + pOld->tclasParams.ipv4.protocol = pNew->info.IpParams.params.IpV4Params.proto; + pOld->tclasParams.ipv4.rsvd = pNew->info.IpParams.params.IpV4Params.reserved; + } + else if ( 6 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv6.version = 6; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.source, 16 ); + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.dest, 16 ); + pOld->tclasParams.ipv6.srcPort = pNew->info.IpParams.params.IpV6Params.src_port; + pOld->tclasParams.ipv6.dstPort = pNew->info.IpParams.params.IpV6Params.dest_port; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.flow_label, 3 ); + } + else + { + return eSIR_FAILURE; + } + break; + case 2: + pOld->tclasParams.t8021dq.tag = pNew->info.Params8021dq.tag_type; + break; + default: + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +void ConvertWMMTSPEC(tpAniSirGlobal pMac, + tSirMacTspecIE *pOld, + tDot11fIEWMMTSPEC *pNew) +{ + pOld->tsinfo.traffic.trafficType = (tANI_U16)pNew->traffic_type; + pOld->tsinfo.traffic.tsid = (tANI_U16)pNew->tsid; + pOld->tsinfo.traffic.direction = (tANI_U16)pNew->direction; + pOld->tsinfo.traffic.accessPolicy = (tANI_U16)pNew->access_policy; + pOld->tsinfo.traffic.aggregation = (tANI_U16)pNew->aggregation; + pOld->tsinfo.traffic.psb = (tANI_U16)pNew->psb; + pOld->tsinfo.traffic.userPrio = (tANI_U16)pNew->user_priority; + pOld->tsinfo.traffic.ackPolicy = (tANI_U16)pNew->tsinfo_ack_pol; + pOld->nomMsduSz = (pNew->fixed << 15) | pNew->size; + pOld->maxMsduSz = pNew->max_msdu_size; + pOld->minSvcInterval = pNew->min_service_int; + pOld->maxSvcInterval = pNew->max_service_int; + pOld->inactInterval = pNew->inactivity_int; + pOld->suspendInterval = pNew->suspension_int; + pOld->svcStartTime = pNew->service_start_time; + pOld->minDataRate = pNew->min_data_rate; + pOld->meanDataRate = pNew->mean_data_rate; + pOld->peakDataRate = pNew->peak_data_rate; + pOld->maxBurstSz = pNew->burst_size; + pOld->delayBound = pNew->delay_bound; + pOld->minPhyRate = pNew->min_phy_rate; + pOld->surplusBw = pNew->surplus_bw_allowance; + pOld->mediumTime = pNew->medium_time; +} + +tSirRetStatus ConvertWMMTCLAS(tpAniSirGlobal pMac, + tSirTclasInfo *pOld, + tDot11fIEWMMTCLAS *pNew) +{ + tANI_U32 length = 0; + + if ( DOT11F_FAILED( dot11fGetPackedIEWMMTCLAS( pMac, pNew, &length ) ) ) + { + return eSIR_FAILURE; + } + + pOld->tclas.type = DOT11F_EID_WMMTCLAS; + pOld->tclas.length = (tANI_U8)length; + pOld->tclas.userPrio = pNew->user_priority; + pOld->tclas.classifierType = pNew->classifier_type; + pOld->tclas.classifierMask = pNew->classifier_mask; + + switch ( pNew->classifier_type ) + { + case 0: + vos_mem_copy( pOld->tclasParams.eth.srcAddr, pNew->info.EthParams.source, 6 ); + vos_mem_copy( pOld->tclasParams.eth.dstAddr, pNew->info.EthParams.dest, 6 ); + pOld->tclasParams.eth.type = pNew->info.EthParams.type; + break; + case 1: + pOld->version = pNew->info.IpParams.version; + if ( 4 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv4.version = 4; + vos_mem_copy( pOld->tclasParams.ipv4.srcIpAddr, + pNew->info.IpParams.params.IpV4Params.source, 4 ); + vos_mem_copy( pOld->tclasParams.ipv4.dstIpAddr, + pNew->info.IpParams.params.IpV4Params.dest, 4 ); + pOld->tclasParams.ipv4.srcPort = pNew->info.IpParams.params.IpV4Params.src_port; + pOld->tclasParams.ipv4.dstPort = pNew->info.IpParams.params.IpV4Params.dest_port; + pOld->tclasParams.ipv4.dscp = pNew->info.IpParams.params.IpV4Params.DSCP; + pOld->tclasParams.ipv4.protocol = pNew->info.IpParams.params.IpV4Params.proto; + pOld->tclasParams.ipv4.rsvd = pNew->info.IpParams.params.IpV4Params.reserved; + } + else if ( 6 == pNew->info.IpParams.version ) + { + pOld->tclasParams.ipv6.version = 6; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.srcIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.source, 16 ); + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.dstIpAddr, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.dest, 16 ); + pOld->tclasParams.ipv6.srcPort = pNew->info.IpParams.params.IpV6Params.src_port; + pOld->tclasParams.ipv6.dstPort = pNew->info.IpParams.params.IpV6Params.dest_port; + vos_mem_copy( ( tANI_U8* )pOld->tclasParams.ipv6.flowLabel, + ( tANI_U8* )pNew->info.IpParams.params.IpV6Params.flow_label, 3 ); + } + else + { + return eSIR_FAILURE; + } + break; + case 2: + pOld->tclasParams.t8021dq.tag = pNew->info.Params8021dq.tag_type; + break; + default: + return eSIR_FAILURE; + } + + return eSIR_SUCCESS; +} + +void ConvertTSDelay(tpAniSirGlobal pMac, + tSirMacTsDelayIE *pOld, + tDot11fIETSDelay *pNew) +{ + pOld->type = DOT11F_EID_TSDELAY; + pOld->length = 4U; + pOld->delay = pNew->delay; +} + +void ConvertSchedule(tpAniSirGlobal pMac, + tSirMacScheduleIE *pOld, + tDot11fIESchedule *pNew) +{ + pOld->type = DOT11F_EID_SCHEDULE; + pOld->length = DOT11F_IE_SCHEDULE_MIN_LEN; + + pOld->info.aggregation = pNew->aggregation; + pOld->info.tsid = pNew->tsid; + pOld->info.direction = pNew->direction; + + pOld->svcStartTime = pNew->service_start_time; + pOld->svcInterval = pNew->service_interval; + pOld->specInterval = pNew->spec_interval; +} + +void ConvertWMMSchedule(tpAniSirGlobal pMac, + tSirMacScheduleIE *pOld, + tDot11fIEWMMSchedule *pNew) +{ + pOld->type = DOT11F_EID_WMMSCHEDULE; + pOld->length = DOT11F_IE_WMMSCHEDULE_MIN_LEN; + + pOld->info.aggregation = pNew->aggregation; + pOld->info.tsid = pNew->tsid; + pOld->info.direction = pNew->direction; + + pOld->svcStartTime = pNew->service_start_time; + pOld->svcInterval = pNew->service_interval; + pOld->specInterval = pNew->spec_interval; +} + +/** + @brief : This functions converts the given buffer till given size to Big endian format assuming the + bus is 32 bit. The size should be four byte aligned. + @param : ptr to be converted, size + @return : void +*/ + +void ConverttoBigEndian(void *ptr, tANI_U16 size) +{ + tANI_U8 *temp_ptr; + tANI_U32 *dest_ptr; + + dest_ptr = (tANI_U32 *)ptr; + while(size) + { + temp_ptr = (tANI_U8 *) dest_ptr; + *dest_ptr = (temp_ptr[0] << 24) | (temp_ptr[1] << 16) | (temp_ptr[2] << 8) | temp_ptr[3]; + dest_ptr++; + size -= 4; + } +} + + +void CreateScanDataNullFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, + tANI_U8 pwrMgmt, tSirMacAddr bssid, tSirMacAddr selfMacAddr) +{ + + macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL; + macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = pwrMgmt; + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 0; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + macMgmtHdr->seqControl.fragNum = 0; + macMgmtHdr->seqControl.seqNumLo = 0; + macMgmtHdr->seqControl.seqNumHi = 2; + vos_mem_copy( (void *)&macMgmtHdr->da, + (void *)bssid, sizeof(tSirMacAddr)); + vos_mem_copy( (void *)&macMgmtHdr->sa, + (void *)selfMacAddr, sizeof(tSirMacAddr)); + vos_mem_copy( (void *)&macMgmtHdr->bssId, + (void *)bssid, sizeof(tSirMacAddr)); + + return; +} + + +void CreateScanCtsFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tSirMacAddr selfMac) +{ + macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 0; + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 0; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + vos_mem_copy( (void *)macMgmtHdr->da, (void *)selfMac, sizeof(tSirMacAddr)); + + return; +} + +void ConvertQosMapsetFrame(tpAniSirGlobal pMac, tSirQosMapSet* Qos, tDot11fIEQosMapSet* dot11fIE) +{ + tANI_U8 i,j=0; + if (dot11fIE->num_dscp_exceptions > 58) + dot11fIE->num_dscp_exceptions = 58; + if (dot11fIE->num_dscp_exceptions < 16) + return; + Qos->num_dscp_exceptions = (dot11fIE->num_dscp_exceptions - 16)/2; + for (i=0;inum_dscp_exceptions;i++) + { + Qos->dscp_exceptions[i][0] = dot11fIE->dscp_exceptions[j]; + j++; + Qos->dscp_exceptions[i][1] = dot11fIE->dscp_exceptions[j]; + j++; + } + for (i=0;i<8;i++) + { + Qos->dscp_range[i][0] = dot11fIE->dscp_exceptions[j]; + j++; + Qos->dscp_range[i][1] = dot11fIE->dscp_exceptions[j]; + j++; + } +} + +/** + @brief : This functions creates a DATA_NULL/CTS2SELF frame in Big endian format + @param : Global MAC structure, pointer to return the created packet, role which is Station/AP + @return : void +*/ + +void CreateInitScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role) +{ +#if 0 + tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable; + + if (role == eSYSTEM_STA_ROLE) + { + macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL; + macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 1; // Needed for station + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 1; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + macMgmtHdr->seqControl.fragNum = 0; + macMgmtHdr->seqControl.seqNumLo = 0; + macMgmtHdr->seqControl.seqNumHi = 2; + vos_mem_copy( (void *)&macMgmtHdr->da, (void *)pSta[0].bssId, 6); + vos_mem_copy( &macMgmtHdr->sa, pSta[0].staAddr, 6); + vos_mem_copy( (void *)&macMgmtHdr->bssId, (void *)pSta[0].bssId, 6); + } + else if (role == eSYSTEM_AP_ROLE || role == eSYSTEM_STA_IN_IBSS_ROLE) + { + macMgmtHdr->fc.type = SIR_MAC_CTRL_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_CTRL_CTS; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 0; // Needed for station + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 0; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + vos_mem_copy( (void *)macMgmtHdr->da, (void *)pSta[0].staAddr, 6); + } + return; +#endif +} + +/** + @brief : This functions creates a DATA_NULL frame in Big endian format + @param : Global MAC structure, pointer to return the created packet, role which is Station/AP + @return : void +*/ + + +void CreateFinishScanRawFrame(tpAniSirGlobal pMac, tSirMacMgmtHdr *macMgmtHdr, tBssSystemRole role) +{ +#if 0 + tpStaStruct pSta = (tpStaStruct) pMac->hal.halMac.staTable; + + if (role == eSYSTEM_STA_ROLE) + { + macMgmtHdr->fc.type = SIR_MAC_DATA_FRAME; + macMgmtHdr->fc.subType = SIR_MAC_DATA_NULL; + macMgmtHdr->fc.protVer = SIR_MAC_PROTOCOL_VERSION; + macMgmtHdr->fc.order = 0; + macMgmtHdr->fc.wep = 0; + macMgmtHdr->fc.moreData =0; + macMgmtHdr->fc.powerMgmt = 0; // Needed for station + macMgmtHdr->fc.retry = 0; + macMgmtHdr->fc.moreFrag = 0; + macMgmtHdr->fc.fromDS = 0; + macMgmtHdr->fc.toDS = 1; + macMgmtHdr->durationLo = (tANI_U8) (SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff); + macMgmtHdr->durationHi = (tANI_U8) ((SIR_MAC_MAX_DURATION_MICRO_SECONDS & 0xff00) >> 8); + macMgmtHdr->seqControl.fragNum = 0; + macMgmtHdr->seqControl.seqNumLo = 0; + macMgmtHdr->seqControl.seqNumHi = 2; + vos_mem_copy( (void *)macMgmtHdr->da, (void *)pSta[0].bssId, 6); + vos_mem_copy( macMgmtHdr->sa, pSta[0].staAddr, 6); + vos_mem_copy( (void *)macMgmtHdr->bssId, (void *)pSta[0].bssId, 6); + + } + + return; +#endif +} + + +// utilsParser.c ends here. diff --git a/drivers/staging/prima/CORE/TL/inc/tlDebug.h b/drivers/staging/prima/CORE/TL/inc/tlDebug.h new file mode 100644 index 000000000000..585412d24629 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/inc/tlDebug.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __TL_DEBUG_H__ +#define __TL_DEBUG_H__ +#if !defined (ANI_OS_TYPE_ANDROID) +#include +#endif +#include +#include "vos_trace.h" +#ifdef WLAN_DEBUG +#ifdef WLAN_MDM_DATAPATH_OPT +#define TLLOGP(x0) x0 +#define TLLOGE(x0) x0 +#define TLLOGW(x0) x0 +#define TLLOG1(x) {} +#define TLLOG2(x) {} +#define TLLOG3(x) {} +#define TLLOG4(x) {} + +#else /*WLAN_MDM_DATAPATH_OPT*/ + +#define TLLOGP(x0) x0 +#define TLLOGE(x0) x0 +#define TLLOGW(x0) x0 +#define TLLOG1(x0) x0 + +#ifdef TL_DEBUG_LOG2 +#define TLLOG2(x0) x0 +#else + #define TLLOG2(x0) +#endif + +#ifdef TL_DEBUG_LOG3 +#define TLLOG3(x0) x0 +#else + #define TLLOG3(x0) +#endif + +#ifdef TL_DEBUG_LOG4 +#define TLLOG4(x0) x0 +#else + #define TLLOG4(x0) +#endif + + +#endif /*WLAN_MDM_DATAPATH_OPT*/ + +#else /* WLAN DEBUG */ + +#define TLLOGP(x) x +#define TLLOGE(x) x +#define TLLOGW(x) x +#define TLLOG1(x) {} +#define TLLOG2(x) {} +#define TLLOG3(x) {} +#define TLLOG4(x) {} +#endif /* WLAN DEBUG */ + + +#endif // __TL_DEBUG_H__ + diff --git a/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h b/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h new file mode 100644 index 000000000000..45f3b9db2f47 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl.h @@ -0,0 +1,3430 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_WLANTL_H +#define WLAN_QCT_WLANTL_H + +/*=========================================================================== + + W L A N T R A N S P O R T L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan transport layer + module. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +01/08/10 lti Added TL Data Caching +10/15/09 rnair Modifying STADescType struct +10/06/09 rnair Adding support for WAPI +09/22/09 lti Add deregistration API for management client +02/02/09 sch Add Handoff support +12/09/08 lti Fixes for AMSS compilation +09/05/08 lti Fixes after QOS unit testing +08/06/08 lti Added QOS support +05/01/08 lti Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_api.h" +#include "vos_packet.h" +#include "sirApi.h" +#include "csrApi.h" +#include "sapApi.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANTL_LLC_OUI_OFFSET 3 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANTL_LLC_OUI_SIZE 3 + +/*Offset of the LLC/SNAP header*/ +#define WLANTL_LLC_SNAP_OFFSET 0 + +/*Size of the LLC/SNAP header*/ +#define WLANTL_LLC_SNAP_SIZE 8 + +/* Number of Tx Queues, this should be same as NUM_TX_QUEUES in HDD */ +#define WLANTL_NUM_TX_QUEUES 5 + +/*============================================================================ + * GENERIC STRUCTURES - not belonging to TL + * TO BE MOVED TO A GLOBAL HEADER + ============================================================================*/ +/*Maximum number of ACs */ +#define WLANTL_MAX_AC 4 + +/* Maximum number of station supported by TL, including BC. */ +#define WLAN_MAX_STA_COUNT (HAL_NUM_STA) +#define WLAN_NON32_STA_COUNT 14 +/* The symbolic station ID return to HDD to specify the packet is bc/mc */ +#define WLAN_RX_BCMC_STA_ID (WLAN_MAX_STA_COUNT + 1) + +/* The symbolic station ID return to HDD to specify the packet is to soft-AP itself */ +#define WLAN_RX_SAP_SELF_STA_ID (WLAN_MAX_STA_COUNT + 2) + +/* Used by HDS systme. This station ID is used by TL to tell upper layer that + this packet is for WDS and not for a loopback for an associated station. */ +#define WLANTL_RX_WDS_STAID WLAN_MAX_STA_COUNT + +/* Station ID used for BC traffic. This value will be used when upper layer registers + the broadcast client or allocate station strcuture to keep per-station info.*/ +//#define WLANTL_BC_STA_ID 0x00 + + +#define WLANTL_MAX_TID 15 +/* Default RSSI average Alpha */ +#define WLANTL_HO_DEFAULT_ALPHA 5 +#define WLANTL_HO_TDLS_ALPHA 7 + +// Choose the largest possible value that can be accomodates in 8 bit signed +// variable. +#define SNR_HACK_BMPS (127) +#define IS_BROADCAST_ADD(_a) \ + ((_a)[0] == 0xff && \ + (_a)[1] == 0xff && \ + (_a)[2] == 0xff && \ + (_a)[3] == 0xff && \ + (_a)[4] == 0xff && \ + (_a)[5] == 0xff) + +#define IS_MULTICAST_ADD(_a) (*(_a) & 0x01) + +/*-------------------------------------------------------------------------- + Access category enum used by TL + - order must be kept as these values are used to setup the AC mask + --------------------------------------------------------------------------*/ +typedef enum +{ + /* The values from 0-3 correspond both to the TL tx queue + * id and the also the AC corresponding to the packets queued + */ + WLANTL_AC_BK = 0, + WLANTL_AC_BE = 1, + WLANTL_AC_VI = 2, + WLANTL_AC_VO = 3, + /* WLANTL_AC_HIGH_PRIO corresponds to the new queue + * added for handling eapol/wapi/dhcp packets. The AC for the + * packets in this queue has to be extracted separately + */ + WLANTL_AC_HIGH_PRIO = 4 +}WLANTL_ACEnumType; + +typedef struct +{ + v_MACADDR_t selfMac; + v_MACADDR_t spoofMac; +}WLANTL_SpoofMacAddr; + +/*--------------------------------------------------------------------------- + STA Type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Indicates a link to an AP*/ + WLAN_STA_INFRA = 0, + + /* AD-hoc link*/ + WLAN_STA_IBSS, + + /* BT-AMP link*/ + WLAN_STA_BT_AMP, + + /* SoftAP station */ + WLAN_STA_SOFTAP, + +#ifdef FEATURE_WLAN_TDLS + /* TDLS direct link */ + WLAN_STA_TDLS, /* 4 */ +#endif + + + /* Invalid link*/ + WLAN_STA_MAX + +}WLAN_STAType; + +/*--------------------------------------------------------------------------- + BAP Management frame type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* BT-AMP packet of type data */ + WLANTL_BT_AMP_TYPE_DATA = 0x0001, + + /* BT-AMP packet of type activity report */ + WLANTL_BT_AMP_TYPE_AR = 0x0002, + + /* BT-AMP packet of type security frame */ + WLANTL_BT_AMP_TYPE_SEC = 0x0003, + + /* BT-AMP packet of type Link Supervision request frame */ + WLANTL_BT_AMP_TYPE_LS_REQ = 0x0004, + + /* BT-AMP packet of type Link Supervision reply frame */ + WLANTL_BT_AMP_TYPE_LS_REP = 0x0005, + + /* Invalid Frame */ + WLANTL_BAP_INVALID_FRAME + +} WLANTL_BAPFrameEnumType; + +/* Type used to specify LWM threshold unit */ +typedef enum { + WLAN_LWM_THRESHOLD_BYTE = 0, + + WLAN_LWM_THRESHOLD_PACKET +} WLAN_LWM_Threshold_Type; + +/*--------------------------------------------------------------------------- + TL States +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Transition in this state made upon creation*/ + WLANTL_STA_INIT = 0, + + /* Transition happens after Assoc success if second level authentication + is needed*/ + WLANTL_STA_CONNECTED, + + /* Transition happens when second level auth is successful and keys are + properly installed */ + WLANTL_STA_AUTHENTICATED, + + /* Transition happens when connectivity is lost*/ + WLANTL_STA_DISCONNECTED, + + WLANTL_STA_MAX_STATE +}WLANTL_STAStateType; + + +/*--------------------------------------------------------------------------- + STA Descriptor Type +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA unique identifier, originating from HAL*/ + v_U8_t ucSTAId; + + /*STA MAC Address*/ + v_MACADDR_t vSTAMACAddress; + + /*BSSID for IBSS*/ + v_MACADDR_t vBSSIDforIBSS; + + /*Self MAC Address*/ + v_MACADDR_t vSelfMACAddress; + + /*Type of the STA*/ + WLAN_STAType wSTAType; + + /*flag for setting the state of the QOS for the link*/ + v_U8_t ucQosEnabled; + + /*enable FT in TL */ + v_U8_t ucSwFrameTXXlation; + v_U8_t ucSwFrameRXXlation; + + /*Flag for signaling TL if LLC header needs to be added for outgoing + packets*/ + v_U8_t ucAddRmvLLC; + + /*Flag for signaling if the privacy bit needs to be set*/ + v_U8_t ucProtectedFrame; + + /*DPU Signature used for unicast data - used for data caching*/ + v_U8_t ucUcastSig; + /*Flag to indicate if STA is a WAPI STA*/ + v_U8_t ucIsWapiSta; + +#ifdef FEATURE_WLAN_ESE + /*Flag to indicate if STA is a ESE STA*/ + v_U8_t ucIsEseSta; +#endif + + /*DPU Signature used for broadcast data - used for data caching*/ + v_U8_t ucBcastSig; + + /*Initial state at which the STA should be brought up to*/ + WLANTL_STAStateType ucInitState; + /* 1 means replay check is needed for the station, + 0 means replay check is not needed for the station*/ + v_BOOL_t ucIsReplayCheckValid; +}WLAN_STADescType; + +/*--------------------------------------------------------------------------- + TL Configuration +---------------------------------------------------------------------------*/ +typedef struct +{ + /*AC weight for WFQ*/ + v_U8_t ucAcWeights[WLANTL_NUM_TX_QUEUES]; + + /*Delayed trigger frame timmer: - used by TL to send trigger frames less + often when it has established that the App is suspended*/ + v_U32_t uDelayedTriggerFrmInt; + + /* Min Threshold for Processing Frames in TL */ + v_U8_t uMinFramesProcThres; + + /* Re-order Aging Time */ + v_U16_t ucReorderAgingTime[WLANTL_MAX_AC]; +}WLANTL_ConfigInfoType; + +/*--------------------------------------------------------------------------- + TSPEC Direction Enum Type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* uplink */ + WLANTL_TX_DIR = 0, + + /* downlink */ + WLANTL_RX_DIR = 1, + + /*bidirectional*/ + WLANTL_BI_DIR = 2, +}WLANTL_TSDirType; + +/*============================================================================ + * GENERIC STRUCTURES - END + ============================================================================*/ + + + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + TL Error Type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Generic error */ + WLANTL_ERROR = 0, + + /* No rx callback registered for data path */ + WLANTL_NO_RX_DATA_CB, + + /* No rx callback registered for management path*/ + WLANTL_NO_RX_MGMT_CB, + + /* Generic memory error*/ + WLANTL_MEM_ERROR, + + /* Bus error notified by BAL */ + WLANTL_BUS_ERROR + +}WLANTL_ErrorType; + +/*--------------------------------------------------------------------------- + STA priority type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* STA gets to tx every second round*/ + WLANTL_STA_PRI_VERY_LOW = -2, + + /* STA gets to tx every other round*/ + WLANTL_STA_PRI_LOW = -1, + + /* STA gets to tx each time */ + WLANTL_STA_PRI_NORMAL = 0, + + /* STA gets to tx twice each time*/ + WLANTL_STA_PRI_HIGH = 1, + + /* STA gets to tx three times each time*/ + WLANTL_STA_PRI_VERY_HIGH = 2 + +}WLANTL_STAPriorityType; + +/*--------------------------------------------------------------------------- + Meta information requested from HDD by TL +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Save the AC of the packet */ + WLANTL_ACEnumType ac; + + /* TID of the packet being sent */ + v_U8_t ucTID; + + /* UP of the packet being sent */ + v_U8_t ucUP; + + /* notifying TL if this is an EAPOL frame or not */ + v_U8_t ucIsEapol; +#ifdef FEATURE_WLAN_WAPI + /* notifying TL if this is a WAI frame or not */ + v_U8_t ucIsWai; +#endif + /* frame is 802.11 and it does not need translation */ + v_U8_t ucDisableFrmXtl; + + /* frame is broadcast */ + v_U8_t ucBcast; + + /* frame is multicast */ + v_U8_t ucMcast; + + /* frame type */ + v_U8_t ucType; + + /* timestamp */ + v_U16_t usTimeStamp; + + /* STA has more packets to send */ + v_BOOL_t bMorePackets; + /* notifying TL if this is an ARP frame or not */ + v_U8_t ucIsArp; + v_U32_t ucTxBdToken; +}WLANTL_MetaInfoType; + +/*--------------------------------------------------------------------------- + Meta information provided by TL to HDD on rx path +---------------------------------------------------------------------------*/ +typedef struct +{ + /* UP of the packet being sent */ + v_U8_t ucUP; + /* Address 3 Index of the received packet */ + v_U16_t ucDesSTAId; + /*Rssi based on the received packet */ + v_S7_t rssiAvg; + #ifdef FEATURE_WLAN_TDLS + /* Packet received on direct link/AP link */ + v_U8_t isStaTdls; + #endif +}WLANTL_RxMetaInfoType; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* per interface per access category statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + /* access category (VI, VO, BE, BK) */ + v_U8_t ac; + + /*Number of successfully transmitted unicast data pkts (ACK rcvd) */ + v_U32_t txMpdu; + + /* number of received unicast mpdu */ + v_U32_t rxMpdu; + + /* umber of succesfully transmitted multicast data packets + * STA case: implies ACK received from AP for the unicast packet in which mcast + * pkt was sent + */ + v_U32_t txMcast; + + /* number of received multicast data packets */ + v_U32_t rxMcast; + + /* number of received unicast a-mpdu */ + v_U32_t rxAmpdu; + + /* number of transmitted unicast a-mpdus */ + v_U32_t txAmpdu; + + /* number of data pkt losses (no ACK) */ + v_U32_t mpduLost; + + /* total number of data pkt retries */ + v_U32_t retries; + + /* number of short data pkt retries */ + v_U32_t retriesShort; + + /* number of long data pkt retries */ + v_U32_t retriesLong; + + /* data pkt min contention time (usecs) */ + v_U32_t contentionTimeMin; + + /* data pkt max contention time (usecs) */ + v_U32_t contentionTimeMax; + + /* data pkt avg contention time (usecs) */ + v_U32_t contentionTimeAvg; + + /* num of data pkts used for contention statistics */ + v_U32_t contentionNumSamples; +}WLANTL_AccessCategoryStatsType; + +/* per interface statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + /* access point beacon received count from connected AP */ + v_U32_t beaconRx; + + /* access point mgmt frames received count from connected AP (including + * Beacon) + */ + v_U32_t mgmtRx; + + /* action frames received count */ + v_U32_t mgmtActionRx; + + /* action frames transmit count */ + v_U32_t mgmtActionTx; + + /* access Point Beacon and Management frames RSSI (averaged) */ + v_U32_t rssiMgmt; + + /* access Point Data Frames RSSI (averaged) from connected AP */ + v_U32_t rssiData; + + /* access Point ACK RSSI (averaged) from connected AP */ + v_U32_t rssiAck; + + WLANTL_AccessCategoryStatsType accessCategoryStats[WLANTL_MAX_AC]; + +}WLANTL_InterfaceStatsType; + + +#endif + +/*--------------------------------------------------------------------------- + Handoff support and statistics defines and enum types +---------------------------------------------------------------------------*/ +/* Threshold crossed event type definitions */ +#define WLANTL_HO_THRESHOLD_NA 0x00 +#define WLANTL_HO_THRESHOLD_DOWN 0x01 +#define WLANTL_HO_THRESHOLD_UP 0x02 +#define WLANTL_HO_THRESHOLD_CROSS 0x04 + +/* Realtime traffic status */ +typedef enum +{ + WLANTL_HO_RT_TRAFFIC_STATUS_OFF, + WLANTL_HO_RT_TRAFFIC_STATUS_ON +} WLANTL_HO_RT_TRAFFIC_STATUS_TYPE; + +/* Non-Realtime traffic status */ +typedef enum +{ + WLANTL_HO_NRT_TRAFFIC_STATUS_OFF, + WLANTL_HO_NRT_TRAFFIC_STATUS_ON +} WLANTL_HO_NRT_TRAFFIC_STATUS_TYPE; + +/* Statistics type TL supported */ +typedef enum +{ + WLANTL_STATIC_TX_UC_FCNT, + WLANTL_STATIC_TX_MC_FCNT, + WLANTL_STATIC_TX_BC_FCNT, + WLANTL_STATIC_TX_UC_BCNT, + WLANTL_STATIC_TX_MC_BCNT, + WLANTL_STATIC_TX_BC_BCNT, + WLANTL_STATIC_RX_UC_FCNT, + WLANTL_STATIC_RX_MC_FCNT, + WLANTL_STATIC_RX_BC_FCNT, + WLANTL_STATIC_RX_UC_BCNT, + WLANTL_STATIC_RX_MC_BCNT, + WLANTL_STATIC_RX_BC_BCNT, + WLANTL_STATIC_RX_BCNT, + WLANTL_STATIC_RX_BCNT_CRC_OK, + WLANTL_STATIC_RX_RATE +} WLANTL_TRANSFER_STATIC_TYPE; + +/*--------------------------------------------------------------------------- + Handoff support and statistics structures +---------------------------------------------------------------------------*/ +typedef struct +{ + WLANTL_HO_RT_TRAFFIC_STATUS_TYPE rtTrafficStatus; + WLANTL_HO_NRT_TRAFFIC_STATUS_TYPE nrtTrafficStatus; +} WLANTL_HO_TRAFFIC_STATUS_TYPE; + +typedef tSap_SoftapStats WLANTL_TRANSFER_STA_TYPE; + +/* Under here not public items, just use for internal */ +/* 3 SME 1 HDD */ +#define WLANTL_MAX_AVAIL_THRESHOLD 5 +#define WLANTL_HS_NUM_CLIENT 2 +#define WLANTL_SINGLE_CLNT_THRESHOLD 4 + +typedef enum +{ + WLANTL_DEBUG_TX_SNAPSHOT = 1<<0, + WLANTL_DEBUG_FW_CLEANUP = 1<<1, + WLANTL_DEBUG_KICKDXE = 1<<2 +}WLANTL_DebugFlags; + +/*---------------------------------------------------------------------------- + * TL callback types + *--------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the tx complete callback registered with TL. + + TL will call this to notify the client when a transmission for a + packet has ended. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_TxCompCBType)( v_PVOID_t pvosGCtx, + vos_pkt_t* pFrameDataBuff, + VOS_STATUS wTxSTAtus ); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HDD + ---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the fetch packet callback registered with TL. + + It is called by the TL when the scheduling algorithms allows for + transmission of another packet to the module. + It will be called in the context of the BAL fetch transmit packet + function, initiated by the bus lower layer. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle + to TL's or HDD's control block can be extracted + from its context + + IN/OUT + pucSTAId: the Id of the station for which TL is requesting a + packet, in case HDD does not maintain per station + queues it can give the next packet in its queue + and put in the right value for the + pucAC: access category requested by TL, if HDD does not have + packets on this AC it can choose to service another AC + queue in the order of priority + + OUT + vosDataBuff: pointer to the VOSS data buffer that was transmitted + tlMetaInfo: meta info related to the data frame + + + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_STAFetchPktCBType)( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo); + +typedef VOS_STATUS (*WLANTL_MonRxCBType)( v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + int conversion); +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the receive callback registered with TL. + + TL will call this to notify the client when a packet was received + for a registered STA. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's or HDD's control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was received + (it may be a linked list) + ucSTAId: station id + pRxMetaInfo: meta info for the received packet(s) + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_STARxCBType)( v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + v_U8_t ucSTAId, + WLANTL_RxMetaInfoType* pRxMetaInfo); +/** + * WLANTL_FwdEapolCBType() - Call back to forward Eapol packet + * @pvosGCtx : pointer to vos global context + * @vosDataBuff: pointer to vos packet + * + * Return: None + * + */ +typedef void (*WLANTL_FwdEapolCBType) (v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff); + +/*---------------------------------------------------------------------------- + INTERACTION WITH BAP + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the receive callback registered with TL for BAP. + + The registered reception callback is being triggered by TL whenever a + frame was received and it was filtered as a non-data BT AMP packet. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the received packet; + no chaining will be done on this path + frameType: type of the frame to be indicated to BAP. + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_BAPRxCBType)( v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + WLANTL_BAPFrameEnumType frameType); + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Callback registered with TL for BAP, this is required inorder for + TL to inform BAP, that the flush operation requested has been completed. + + The registered reception callback is being triggered by TL whenever a + frame SIR_TL_HAL_FLUSH_AC_RSP is received by TL from HAL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the received packet; + no chaining will be done on this path + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_FlushOpCompCBType)( v_PVOID_t pvosGCtx, + v_U8_t ucStaId, + v_U8_t ucTID, + v_U8_t status); +/*---------------------------------------------------------------------------- + INTERACTION WITH PE + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the receive callback registered with TL for PE. + + Upon receipt of a management frame TL will call the registered receive + callback and forward this frame to the interested module, in our case PE. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management frame + received + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_MgmtFrmRxCBType)( v_PVOID_t pvosGCtx, + v_PVOID_t vosBuff); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HAL + ---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the fetch packet callback registered with TL. + + HAL calls this API when it wishes to suspend transmission for a + particular STA. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station for which the request is made; + a value of 0 assumes suspend on all active station + pfnSuspendTxCB: pointer to the suspend result notification in case the + call is asynchronous + + RETURN VALUE + The result code associated with performing the operation + +----------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_SuspendCBType)( v_PVOID_t pvosGCtx, + v_U8_t* ucSTAId, + VOS_STATUS vosStatus); + + +/*========================================================================== + + DESCRIPTION + Traffic status changed callback function + Should be registered to let client know that traffic status is changed + REF WLANTL_RegGetTrafficStatus + + PARAMETERS + pAdapter Global handle pointer + trafficStatus RT and NRT current traffic status + pUserCtxt pre registered client context + + RETURN VALUE + VOS_STATUS + + SIDE EFFECTS + NONE + +============================================================================*/ +/* IF traffic status is changed, send notification to SME */ +typedef VOS_STATUS (*WLANTL_TrafficStatusChangedCBType) +( + v_PVOID_t pAdapter, + WLANTL_HO_TRAFFIC_STATUS_TYPE trafficStatus, + v_PVOID_t pUserCtxt +); + +/*========================================================================== + + DESCRIPTION + RSSI threshold crossed notification callback function + REF WLANTL_RegRSSIIndicationCB + + PARAMETERS + pAdapter Global handle pointer + rssiNotification Notification event type + pUserCtxt pre registered client context + + RETURN VALUE + + SIDE EFFECTS + +============================================================================*/ +/* If RSSI realm is changed, send notification to Clients, SME, HDD */ +typedef VOS_STATUS (*WLANTL_RSSICrossThresholdCBType) +( + v_PVOID_t pAdapter, + v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + v_S7_t avgRssi +); + +typedef struct +{ + // Common for all types are requests + v_U16_t msgType; // message type is same as the request type + v_U16_t msgLen; // length of the entire request + v_U8_t sessionId; //sme Session Id + v_U8_t rssiNotification; + v_U8_t avgRssi; + v_PVOID_t tlCallback; + v_PVOID_t pAdapter; + v_PVOID_t pUserCtxt; +} WLANTL_TlIndicationReq; + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_Open + + DESCRIPTION + Called by HDD at driver initialization. TL will initialize all its + internal resources and will wait for the call to start to register + with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pTLConfig: TL Configuration + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Open +( + v_PVOID_t pvosGCtx, + WLANTL_ConfigInfoType* pTLConfig +); + +/*========================================================================== + + FUNCTION WLANTL_Start + + DESCRIPTION + Called by HDD as part of the overall start procedure. TL will use this + call to register with BAL as a transport layer entity. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; see BAL API + for more info + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Start +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_Stop + + DESCRIPTION + Called by HDD to stop operation in TL, before close. TL will suspend all + frame transfer operation and will wait for the close request to clean up + its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Stop +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_Close + + DESCRIPTION + Called by HDD during general driver close procedure. TL will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Close +( + v_PVOID_t pvosGCtx +); + +/*=========================================================================== + + FUNCTION WLANTL_StartForwarding + + DESCRIPTION + + This function is used to ask serialization through TX thread of the + cached frame forwarding (if statation has been registered in the mean while) + or flushing (if station has not been registered by the time) + + In case of forwarding, upper layer is only required to call WLANTL_RegisterSTAClient() + and doesn't need to call this function explicitly. TL will handle this inside + WLANTL_RegisterSTAClient(). + + In case of flushing, upper layer is required to call this function explicitly + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + ucSTAId: station id + + RETURN VALUE + + The result code associated with performing the operation + Please check return values of vos_tx_mq_serialize. + + SIDE EFFECTS + If TL was asked to perform WLANTL_CacheSTAFrame() in WLANTL_RxFrames(), + either WLANTL_RegisterSTAClient() or this function must be called + within reasonable time. Otherwise, TL will keep cached vos buffer until + one of this function is called, and may end up with system buffer exhasution. + + It's an upper layer's responsibility to call this function in case of + flushing + +============================================================================*/ +VOS_STATUS +WLANTL_StartForwarding +( + v_U8_t ucSTAId, + v_U8_t ucUcastSig, + v_U8_t ucBcastSig +); + +/*---------------------------------------------------------------------------- + INTERACTION WITH HDD + ---------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION WLANTL_ConfigureSwFrameTXXlationForAll + + DESCRIPTION + Function to disable/enable frame translation for all association stations. + + DEPENDENCIES + + PARAMETERS + IN + pvosGCtx: VOS context + EnableFrameXlation TRUE means enable SW translation for all stations. + . + + RETURN VALUE + + void. + +============================================================================*/ +void +WLANTL_ConfigureSwFrameTXXlationForAll +( + v_PVOID_t pvosGCtx, + v_BOOL_t enableFrameXlation +); + +VOS_STATUS WLANTL_SetMonRxCbk(v_PVOID_t pvosGCtx, WLANTL_MonRxCBType pfnMonRx); +void WLANTL_SetIsConversionReq(v_PVOID_t pvosGCtx, v_BOOL_t isConversionReq); +/*=========================================================================== + + FUNCTION WLANTL_RegisterSTAClient + + DESCRIPTION + + This function is used by HDD to register as a client for data services + with TL. HDD will call this API for each new station that it adds, + thus having the flexibility of registering different callback for each + STA it services. + + DEPENDENCIES + + TL must have been initialized before this gets called. + + Restriction: + Main thread will have higher priority that Tx and Rx threads thus + guaranteeing that a station will be added before any data can be + received for it. (This enables TL to be lock free) + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pfnStARx: function pointer to the receive packet handler from HDD + pfnSTATxComp: function pointer to the transmit complete confirmation + handler from HDD + pfnSTAFetchPkt: function pointer to the packet retrieval routine in HDD + wSTADescType: STA Descriptor, contains information related to the + new added STA + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterSTAClient +( + v_PVOID_t pvosGCtx, + WLANTL_STARxCBType pfnSTARx, + WLANTL_TxCompCBType pfnSTATxComp, + WLANTL_STAFetchPktCBType pfnSTAFetchPkt, + WLAN_STADescType* wSTADescType , + v_S7_t rssi +); + +/*=========================================================================== + + FUNCTION WLANTL_UpdateTdlsSTAClient + + DESCRIPTION + + HDD will call this API when ENABLE_LINK happens and HDD want to + register QoS or other params for TDLS peers. + + DEPENDENCIES + + A station must have been registered before the WMM/QOS registration is + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + wSTADescType: STA Descriptor, contains information related to the + new added STA + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_UpdateTdlsSTAClient +( + v_PVOID_t pvosGCtx, + WLAN_STADescType* wSTADescType +); + + +/*=========================================================================== + + FUNCTION WLANTL_ClearSTAClient + + DESCRIPTION + + HDD will call this API when it no longer needs data services for the + particular station. + + DEPENDENCIES + + A station must have been registered before the clear registration is + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA to be cleared + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ClearSTAClient +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId +); + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/*========================================================================== + + FUNCTION WLANTL_CollectStats + + DESCRIPTION + Utility function used by TL to send the statitics + + DEPENDENCIES + + + PARAMETERS + + IN + + ucSTAId: station for which the statistics need to collected + + vosDataBuff: it will contain the pointer to the corresponding + structure + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_CollectInterfaceStats +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_InterfaceStatsType *vosDataBuff +); + +/*========================================================================== + + FUNCTION WLANTL_ClearInterfaceStats + + DESCRIPTION + Utility function used by TL to clear the statitics + + DEPENDENCIES + + + PARAMETERS + + IN + + ucSTAId: station for which the statistics need to collected + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ClearInterfaceStats +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t statsClearReqMask +); +#endif + +/*=========================================================================== + + FUNCTION WLANTL_ChangeSTAState + + DESCRIPTION + + HDD will make this notification whenever a change occurs in the + connectivity state of a particular STA. + + DEPENDENCIES + + A station must have been registered before the change state can be + called. + + RESTRICTION: A station is being notified as authenticated before the + keys are installed in HW. This way if a frame is received + before the keys are installed DPU will drop that frame. + + Main thread has higher priority that Tx and Rx threads thus guaranteeing + the following: + - a station will be in assoc state in TL before TL receives any data + for it + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + tlSTAState: the new state of the connection to the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ChangeSTAState +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAStateType tlSTAState +); + +/*=========================================================================== + + FUNCTION WLANTL_STAPtkInstalled + + DESCRIPTION + + HDD will make this notification whenever PTK is installed for the STA + + DEPENDENCIES + + A station must have been registered before the change state can be + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA for which Pairwise key is + installed + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STAPtkInstalled +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId +); +/*=========================================================================== + + FUNCTION WLANTL_GetSTAState + + DESCRIPTION + + Returns connectivity state of a particular STA. + + DEPENDENCIES + + A station must have been registered before its state can be retrieved. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + + OUT + ptlSTAState: the current state of the connection to the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetSTAState +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAStateType *ptlSTAState +); + +/*=========================================================================== + + FUNCTION WLANTL_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. + + DEPENDENCIES + + A station must have been registered before the packet pending + notification can be sent. + + RESTRICTION: TL will not count packets for pending notification. + HDD is expected to send the notification only when + non-empty event gets triggered. Worst case scenario + is that TL might end up making a call when Hdds + queues are actually empty. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + ucAC: access category of the non-empty queue + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STAPktPending +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucAc +); + +/*========================================================================== + + FUNCTION WLANTL_SetSTAPriority + + DESCRIPTION + + TL exposes this API to allow upper layers a rough control over the + priority of transmission for a given station when supporting multiple + connections. + + DEPENDENCIES + + A station must have been registered before the change in priority can be + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that has to change priority + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_SetSTAPriority +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAPriorityType tlSTAPri +); + +/*---------------------------------------------------------------------------- + INTERACTION WITH BAP + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_RegisterBAPClient + + DESCRIPTION + Called by SME to register itself as client for non-data BT-AMP packets. + + DEPENDENCIES + TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + pfnTlBAPRxFrm: pointer to the receive processing routine for non-data + BT-AMP packets + pfnFlushOpCompleteCb: + pointer to the function that will inform BAP that the + flush operation is complete. + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: BAL client was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterBAPClient +( + v_PVOID_t pvosGCtx, + WLANTL_BAPRxCBType pfnTlBAPRx, + WLANTL_FlushOpCompCBType pfnFlushOpCompleteCb +); + + +/*========================================================================== + + FUNCTION WLANTL_TxBAPFrm + + DESCRIPTION + BAP calls this when it wants to send a frame to the module + + DEPENDENCIES + BAP must be registered with TL before this function can be called. + + RESTRICTION: BAP CANNOT push any packets to TL until it did not receive + a tx complete from the previous packet, that means BAP + sends one packet, wait for tx complete and then + sends another one + + If BAP sends another packet before TL manages to process the + previously sent packet call will end in failure + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAP's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the packet to be + transmitted + pMetaInfo: meta information about the packet + pfnTlBAPTxComp: pointer to a transmit complete routine for notifying + the result of the operation over the bus + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: BAL client was not yet registered + VOS_STATUS_E_BUSY: The previous BT-AMP packet was not yet transmitted + VOS_STATUS_SUCCESS: Everything is good :) + + Other failure messages may be returned from the BD header handling + routines, please check apropriate API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxBAPFrm +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + WLANTL_MetaInfoType* pMetaInfo, + WLANTL_TxCompCBType pfnTlBAPTxComp +); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH SME + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_GetRssi + + DESCRIPTION + TL will extract the RSSI information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puRssi: the average value of the RSSI + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetRssi +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_S7_t* puRssi +); + +/*========================================================================== + + FUNCTION WLANTL_GetSnr + + DESCRIPTION + TL will extract the SNR information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puSnr: the average value of the SNR + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetSnr +( + tANI_U8 ucSTAId, + tANI_S8* pSnr +); + +/*========================================================================== + + FUNCTION WLANTL_GetLinkQuality + + DESCRIPTION + TL will extract the LinkQuality information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puLinkQuality: the average value of the LinkQuality + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetLinkQuality +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U32_t* puLinkQuality +); + +/*========================================================================== + + FUNCTION WLANTL_FlushStaTID + + DESCRIPTION + TL provides this API as an interface to SME (BAP) layer. TL inturn posts a + message to HAL. This API is called by the SME inorder to perform a flush + operation. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + ucTid: Tspec ID for the new BA session + + OUT + The response for this post is received in the main thread, via a response + message from HAL to TL. + + RETURN VALUE + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANTL_FlushStaTID +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid +); + +/*---------------------------------------------------------------------------- + INTERACTION WITH PE + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_updateSpoofMacAddr + + DESCRIPTION + Called by HDD to update macaddr + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + spoofMacAddr: spoofed mac adderess + selfMacAddr: self Mac Address + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_updateSpoofMacAddr +( + v_PVOID_t pvosGCtx, + v_MACADDR_t* spoofMacAddr, + v_MACADDR_t* selfMacAddr +); +/*========================================================================== + + FUNCTION WLANTL_RegisterMgmtFrmClient + + DESCRIPTION + Called by PE to register as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + pfnTlMgmtFrmRx: pointer to the receive processing routine for + management frames + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterMgmtFrmClient +( + v_PVOID_t pvosGCtx, + WLANTL_MgmtFrmRxCBType pfnTlMgmtFrmRx +); + +/*========================================================================== + + FUNCTION WLANTL_DeRegisterMgmtFrmClient + + DESCRIPTION + Called by PE to deregister as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was never registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_DeRegisterMgmtFrmClient +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_TxMgmtFrm + + DESCRIPTION + Called by PE when it want to send out a management frame. + HAL will also use this API for the few frames it sends out, they are not + management frames howevere it is accepted that an exception will be + allowed ONLY for the usage of HAL. + Generic data frames SHOULD NOT travel through this function. + + DEPENDENCIES + TL must be initialized before this API can be called. + + RESTRICTION: If PE sends another packet before TL manages to process the + previously sent packet call will end in failure + + Frames comming through here must be 802.11 frames, frame + translation in UMA will be automatically disabled. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context;a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management + frame to be transmitted + usFrmLen: the length of the frame to be transmitted; information + is already included in the vOSS buffer + wFrmType: the type of the frame being transmitted + tid: tid used to transmit this frame + pfnCompTxFunc: function pointer to the transmit complete routine + pvBDHeader: pointer to the BD header, if NULL it means it was not + yet constructed and it lies within TL's responsibility + to do so; if not NULL it is expected that it was + already packed inside the vos packet + ucAckResponse: flag notifying it an interrupt is needed for the + acknowledgement received when the frame is sent out + the air and ; the interrupt will be processed by HAL, + only one such frame can be pending in the system at + one time. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was not yet registered + VOS_STATUS_E_BUSY: The previous Mgmt packet was not yet transmitted + VOS_STATUS_SUCCESS: Everything is good :) + + Other failure messages may be returned from the BD header handling + routines, please check apropriate API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxMgmtFrm +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosFrmBuf, + v_U16_t usFrmLen, + v_U8_t ucFrmType, + v_U8_t tid, + WLANTL_TxCompCBType pfnCompTxFunc, + v_PVOID_t voosBDHeader, + v_U32_t ucAckResponse, + v_U32_t ucTxBdToken +); + + +/*---------------------------------------------------------------------------- + INTERACTION WITH HAL + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_ResetNotification + + DESCRIPTION + HAL notifies TL when the module is being reset. + Currently not used. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResetNotification +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_SuspendDataTx + + DESCRIPTION + HAL calls this API when it wishes to suspend transmission for a + particular STA. + + DEPENDENCIES + The STA for which the request is made must be first registered with + TL by HDD. + + RESTRICTION: In case of a suspend, the flag write and read will not be + locked: worst case scenario one more packet can get + through before the flag gets updated (we can make this + write atomic as well to guarantee consistency) + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pucSTAId: identifier of the station for which the request is made; + a value of NULL assumes suspend on all active station + pfnSuspendTxCB: pointer to the suspend result notification in case the + call is asynchronous + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_SuspendDataTx +( + v_PVOID_t pvosGCtx, + v_U8_t* ucSTAId, + WLANTL_SuspendCBType pfnSuspendTx +); + +/*========================================================================== + + FUNCTION WLANTL_ResumeDataTx + + DESCRIPTION + Called by HAL to resume data transmission for a given STA. + + WARNING: If a station was individually suspended a global resume will + not resume that station + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pucSTAId: identifier of the station which is being resumed; NULL + translates into global resume + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResumeDataTx +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId +); + + +/*---------------------------------------------------------------------------- + CLIENT INDEPENDENT INTERFACE + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_GetTxPktCount + + DESCRIPTION + TL will provide the number of transmitted packets counted per + STA per TID. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + ucTid: identifier of the tspec + + OUT + puTxPktCount: the number of packets tx packet for this STA and TID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetTxPktCount +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid, + v_U32_t* puTxPktCount +); + +/*========================================================================== + + FUNCTION WLANTL_GetRxPktCount + + DESCRIPTION + TL will provide the number of received packets counted per + STA per TID. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + ucTid: identifier of the tspec + + OUT + puTxPktCount: the number of packets rx packet for this STA and TID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetRxPktCount +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid, + v_U32_t* puRxPktCount +); + +/*========================================================================== + + FUNCTION WLANTL_IsEAPOLPending + + DESCRIPTION + + HDD calls this function when hdd_tx_timeout occurs. This checks whether + EAPOL is pending. + + DEPENDENCIES + + HDD must have registered with TL at least one STA before this function + can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context + + RETURN VALUE + + The result code associated with performing the operation + + Success : Indicates EAPOL frame is pending and sta is in connected state + + Failure : EAPOL frame is not pending + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANTL_IsEAPOLPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + VOSS SCHEDULER INTERACTION + ==========================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_McProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + main thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_McProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_RxProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + rx thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RxProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_McFreeMsg + + DESCRIPTION + Called by VOSS to free a given TL message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + For now, TL does not allocate any body so this function shout translate + into a NOOP + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_McFreeMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_TxProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + tx thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_McFreeMsg + + DESCRIPTION + Called by VOSS to free a given TL message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + For now, TL does not allocate any body so this function shout translate + into a NOOP + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxFreeMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +); + + +/*========================================================================== + FUNCTION WLANTL_EnableUAPSDForAC + + DESCRIPTION + Called by HDD to enable UAPSD in TL. TL is in charge for sending trigger + frames. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: station Id + ucACId: AC for which U-APSD is being enabled + ucTid TSpec Id + uServiceInt: service interval used by TL to send trigger frames + uSuspendInt: suspend interval used by TL to determine that an + app is idle and should start sending trigg frms less often + wTSDir: direction of TSpec + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_EnableUAPSDForAC +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucACId, + v_U8_t ucTid, + v_U8_t ucUP, + v_U32_t uServiceInt, + v_U32_t uSuspendInt, + WLANTL_TSDirType wTSDir +); + + +/*========================================================================== + FUNCTION WLANTL_DisableUAPSDForAC + + DESCRIPTION + Called by HDD to disable UAPSD in TL. TL will stop sending trigger + frames. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: station Id + ucACId: AC for which U-APSD is being enabled + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_DisableUAPSDForAC +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucACId +); + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING +/*========================================================================== + FUNCTION WLANTL_RegRSSIIndicationCB + + DESCRIPTION Registration function to get notification if RSSI cross + threshold. + Client should register threshold, direction, and notification + callback function pointer + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in rssiValue - RSSI threshold value + in triggerEvent - Cross direction should be notified + UP, DOWN, and CROSS + in crossCBFunction - Notification CB Function + in usrCtxt - user context + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_RegRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID, + v_PVOID_t usrCtxt +); + +/*========================================================================== + FUNCTION WLANTL_DeregRSSIIndicationCB + + DESCRIPTION Remove specific threshold from list + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in rssiValue - RSSI threshold value + in triggerEvent - Cross direction should be notified + UP, DOWN, and CROSS + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_DeregRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_BMPSRSSIRegionChangedNotification +( + v_PVOID_t pAdapter, + tpSirRSSINotification pRSSINotification +); + +/*========================================================================== + FUNCTION WLANTL_SetAlpha + + DESCRIPTION ALPLA is weight value to calculate AVG RSSI + avgRSSI = (ALPHA * historyRSSI) + ((10 - ALPHA) * newRSSI) + avgRSSI has (ALPHA * 10)% of history RSSI weight and + (10 - ALPHA)% of newRSSI weight + This portion is dynamically configurable. + Default is ? + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in valueAlpah - ALPHA + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_SetAlpha +( + v_PVOID_t pAdapter, + v_U8_t valueAlpha +); + +/*========================================================================== + FUNCTION WLANTL_RegGetTrafficStatus + + DESCRIPTION Registration function for traffic status monitoring + During measure period count data frames. + If frame count is larger then IDLE threshold set as traffic ON + or OFF. + And traffic status is changed send report to client with + registered callback function + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in idleThreshold - Traffic on or off threshold + in measurePeriod - Traffic state check period + in trfficStatusCB - traffic status changed notification + CB function + in usrCtxt - user context + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_RegGetTrafficStatus +( + v_PVOID_t pAdapter, + v_U32_t idleThreshold, + v_U32_t measurePeriod, + WLANTL_TrafficStatusChangedCBType trfficStatusCB, + v_PVOID_t usrCtxt +); +#endif +/*========================================================================== + FUNCTION WLANTL_GetStatistics + + DESCRIPTION Get traffic statistics for identified station + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + out statBuffer - traffic statistics buffer + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetStatistics +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STA_TYPE *statBuffer, + v_U8_t STAid +); + +/*========================================================================== + FUNCTION WLANTL_ResetStatistics + + DESCRIPTION Reset statistics structure for identified station ID + Reset means set values as 0 + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_ResetStatistics +( + v_PVOID_t pAdapter, + v_U8_t STAid +); + +/*========================================================================== + FUNCTION WLANTL_GetSpecStatistic + + DESCRIPTION Get specific field within statistics structure for + identified station ID + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + in STAid - Station ID + out buffer - Statistic value + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetSpecStatistic +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STATIC_TYPE statType, + v_U32_t *buffer, + v_U8_t STAid +); + +/*========================================================================== + FUNCTION WLANTL_ResetSpecStatistic + + DESCRIPTION Reset specific field within statistics structure for + identified station ID + Reset means set as 0 + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + in STAid - Station ID + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_ResetSpecStatistic +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STATIC_TYPE statType, + v_U8_t STAid +); +/*=============================================================================== + FUNCTION WLANTL_IsReplayPacket + + DESCRIPTION This function does replay check for valid stations + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS currentReplayCounter current replay counter taken from RX BD + previousReplayCounter previous replay counter taken from TL CB + + RETRUN VOS_TRUE packet is a replay packet + VOS_FALSE packet is not a replay packet + + SIDE EFFECTS none + ===============================================================================*/ +v_BOOL_t WLANTL_IsReplayPacket +( + v_U64_t currentReplayCounter, + v_U64_t previousReplayCounter +); + +/*=============================================================================== + FUNCTION WLANTL_GetReplayCounterFromRxBD + + DESCRIPTION This function extracts 48-bit replay packet number from RX BD + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS pucRxHeader pointer to RX BD header + + RETRUN v_U64_t Packet number extarcted from RX BD + + SIDE EFFECTS none + ===============================================================================*/ +v_U64_t +WLANTL_GetReplayCounterFromRxBD +( + v_U8_t *pucRxBDHeader +); + + + +/* + DESCRIPTION + TL returns the weight currently maintained in TL. + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + + OUT + pACWeights: Caller allocated memory for filling in weights + + RETURN VALUE VOS_STATUS +*/ +VOS_STATUS +WLANTL_GetACWeights +( + v_PVOID_t pvosGCtx, + v_U8_t* pACWeights +); + + +/* + DESCRIPTION + Change the weight currently maintained by TL. + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + pACWeights: Caller allocated memory contain the weights to use + + + RETURN VALUE VOS_STATUS +*/ +VOS_STATUS +WLANTL_SetACWeights +( + v_PVOID_t pvosGCtx, + v_U8_t* pACWeights +); + +/*========================================================================== + FUNCTION WLANTL_GetSoftAPStatistics + + DESCRIPTION Collect the cumulative statistics for all Softap stations + + DEPENDENCIES NONE + + PARAMETERS in pvosGCtx - Pointer to the global vos context + bReset - If set TL statistics will be cleared after reading + out statsSum - pointer to collected statistics + + RETURN VALUE VOS_STATUS_SUCCESS : if the Statistics are successfully extracted + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetSoftAPStatistics(v_PVOID_t pAdapter, WLANTL_TRANSFER_STA_TYPE *statsSum, v_BOOL_t bReset); + +#ifdef __cplusplus + } +#endif + +/*=========================================================================== + + FUNCTION WLANTL_EnableCaching + + DESCRIPTION + + This function is used to enable caching only when assoc/reassoc req is send. + that is cache packets only for such STA ID. + + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + staId: station id. + + RETURN VALUE + + none + +============================================================================*/ +void WLANTL_EnableCaching(v_U8_t staId); + + /*=========================================================================== + + FUNCTION WLANTL_AssocFailed + + DESCRIPTION + + This function is used by PE to notify TL that cache needs to flushed + when association is not successfully completed + + Internally, TL post a message to TX_Thread to serialize the request to + keep lock-free mechanism. + + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + ucSTAId: station id + + RETURN VALUE + + none + + SIDE EFFECTS + There may be race condition that PE call this API and send another association + request immediately with same staId before TX_thread can process the message. + + To avoid this, we might need PE to wait for TX_thread process the message, + but this is not currently implemented. + +============================================================================*/ +void WLANTL_AssocFailed(v_U8_t staId); + + +/*=============================================================================== + FUNCTION WLANTL_PostResNeeded + + DESCRIPTION This function posts message to TL to reserve BD/PDU memory + + DEPENDENCIES None + + PARAMETERS pvosGCtx + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_PostResNeeded(v_PVOID_t pvosGCtx); + +/*=========================================================================== + + FUNCTION WLANTL_Finish_ULA + + DESCRIPTION + This function is used by HDD to notify TL to finish Upper layer authentication + incase the last EAPOL packet is pending in the TL queue. + To avoid the race condition between sme set key and the last EAPOL packet + the HDD module calls this function just before calling the sme_RoamSetKey. + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + callbackRoutine: HDD Callback function. + callbackContext : HDD userdata context. + + RETURN VALUE + + VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS WLANTL_Finish_ULA( void (*callbackRoutine) (void *callbackContext), + void *callbackContext); + +/*=============================================================================== + FUNCTION WLANTL_UpdateRssiBmps + + DESCRIPTION This function updates the TL's RSSI (in BMPS mode) + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + rssi RSSI (BMPS mode) RSSI in BMPS mode + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateRssiBmps(v_PVOID_t pvosGCtx, v_U8_t staId, v_S7_t rssi); + +/*=============================================================================== + FUNCTION WLANTL_UpdateSnrBmps + + DESCRIPTION This function updates the TL's SNR (in BMPS mode) + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + snr SNR (BMPS mode) SNR in BMPS mode + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateSnrBmps(v_PVOID_t pvosGCtx, v_U8_t staId, v_S7_t snr); + +/*========================================================================== + FUNCTION WLANTL_SetTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to indicate that WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_SetTxXmitPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_IsTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to know whether WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + 0: No WDA_DS_TX_START_XMIT msg pending + 1: Msg WDA_DS_TX_START_XMIT already pending in TL msg queue + + SIDE EFFECTS + +============================================================================*/ + +v_BOOL_t +WLANTL_IsTxXmitPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_ClearTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to indicate that no WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_ClearTxXmitPending +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_UpdateSTABssIdforIBSS + + DESCRIPTION + HDD will call this API to update the BSSID for this Station. + + DEPENDENCIES + The HDD Should registered the staID with TL before calling this function. + + PARAMETERS + + IN + pvosGCtx: Pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + IN + ucSTAId The Station ID for Bssid to be updated + IN + pBssid BSSID to be updated + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ + +VOS_STATUS +WLANTL_UpdateSTABssIdforIBSS +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t *pBssid +); + + + +/*=============================================================================== + FUNCTION WLANTL_UpdateLinkCapacity + + DESCRIPTION This function updates the STA's Link Capacity in TL + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + linkCapacity linkCapacity Link Capacity + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void +WLANTL_UpdateLinkCapacity +( + v_PVOID_t pvosGCtx, + v_U8_t staId, + v_U32_t linkCapacity); + +/*=========================================================================== + + FUNCTION WLANTL_GetSTALinkCapacity + + DESCRIPTION + + Returns Link Capacity of a particular STA. + + DEPENDENCIES + + A station must have been registered before its state can be retrieved. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + + OUT + plinkCapacity: the current link capacity the connection to + the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_GetSTALinkCapacity +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U32_t *plinkCapacity +); + +/*=========================================================================== + FUNCTION WLANTL_TxThreadDebugHandler + + DESCRIPTION + Printing TL Snapshot dump, processed under TxThread context, currently + information regarding the global TlCb struture. Dumps information related + to per active STA connection currently in use by TL. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + pvosGCtx: Pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS +============================================================================*/ + +v_VOID_t +WLANTL_TxThreadDebugHandler +( + v_PVOID_t *pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_TLDebugMessage + + DESCRIPTION + Post a TL Snapshot request, posts message in TxThread. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + displaySnapshot Boolean showing whether to dump the snapshot or not. + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_TLDebugMessage +( + v_U32_t debugFlags +); + +/*========================================================================== + FUNCTION WLANTL_FatalError + + DESCRIPTION + Fatal error reported in TX path, post an event to TX Thread for further + handling + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + VOID + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANTL_FatalError +( + v_VOID_t +); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void WLANTL_StartRxRateMonitor(v_PVOID_t pvosGCtx, wpt_uint8 staId, + wpt_uint16 minRate, + wpt_uint16 maxRate, wpt_uint8 minPercentage, + wpt_uint16 minPktRequired, void *hHal, + wpt_uint64 timeToWait, + void (*triggerRoamScanfn) (void *, wpt_uint8)); + +void WLANTL_StopRxRateMonitor(v_PVOID_t pvosGCtx); +#endif +#ifdef WLAN_FEATURE_RMC +VOS_STATUS +WLANTL_EnableRMC +( + v_PVOID_t pvosGCtx, + v_MACADDR_t *pMcastAddr +); + + +VOS_STATUS +WLANTL_DisableRMC +( + v_PVOID_t pvosGCtx, + v_MACADDR_t *pMcastAddr +); + +/*============================================================================= + FUNCTION WLANTL_SetMcastDuplicateDetection + + DESCRIPTION + This function sets multicate duplicate detection operation. + If enable is 1, the detection is enabled, else it is disabled. + + DEPENDENCIES + + PARAMETERS + + IN + + pvosGCtx : Pointer to VOS global context + enable : Boolean to enable or disable + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Sanity check on input failed + + VOS_STATUS_SUCCESS: Everything is good :) + + Other return values are possible coming from the called functions. + Please check API for additional info. + + SIDE EFFECTS + +==============================================================================*/ +VOS_STATUS +WLANTL_SetMcastDuplicateDetection +( + v_PVOID_t pvosGCtx, + v_U8_t enable +); +#endif /* WLAN_FEATURE_RMC */ + +/* + * WLANTL_ResetRxSSN - reset last rx ssn + * @pvosGCtx: global vos context + * @ucSTAId: station id + * + * This function resets the last ssn of all tids of the station + * for whom BA reorder session exists. + * + * Return: none + */ +void WLANTL_ResetRxSSN(v_PVOID_t pvosGCtx, uint8_t ucSTAId); + +/* + * WLANTL_SetDataPktFilter - Set data filter flag + * @pvosGCtx: global vos context + * @ucSTAId: station id + * @flag: packet data filter flag + * + * This function sets the data pkt filter flag of all tids + * of the station for whom BA reorder session exists. + * + * Return: none + */ +void WLANTL_SetDataPktFilter(v_PVOID_t pvosGCtx, uint8_t ucSTAId, bool flag); + +/** + * WLANTL_SampleTx() - collect tx samples + * @data: TL context pointer + * + * This function records the frames fetched from stations + * during TX sample interval + * + * Return: void + */ +void WLANTL_SampleTx(void *data); + +/* + * WLANTL_EnablePreAssocCaching - Enable caching during pre-assoc + * @staid: sta client where frames are cached + * + * Return: none + */ +void WLANTL_EnablePreAssocCaching(void); + +/* + * WLANTL_PreAssocForward - Forward the cached packets + * + * This function forwards or flushes the packets after + * pre assoc success/failure. + * + * Return: none + */ +void WLANTL_PreAssocForward(bool flag); + +/* make before break */ +void WLANTL_RegisterFwdEapol(v_PVOID_t pvosGCtx, + WLANTL_FwdEapolCBType pfnFwdEapol); + +/** + * WLANTL_SetARPFWDatapath() - keep or remove FW in data path for ARP + * @pvosGCtx: global vos context + * @flag: value to keep or remove FW from data path + * + * Return: void + */ +void WLANTL_SetARPFWDatapath(void * pvosGCtx, bool flag); +#endif /* #ifndef WLAN_QCT_WLANTL_H */ diff --git a/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl_trace.h b/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl_trace.h new file mode 100644 index 000000000000..066db2d91125 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/inc/wlan_qct_tl_trace.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*********************************************************************** + wlan_qct_tl_trace.h + + \brief definition for trace related APIs + + ========================================================================*/ +#ifndef __WLAN_QCT_TL_TRACE_H__ +#define __WLAN_QCT_TL_TRACE_H__ + + +#include "macTrace.h" + +#define NO_SESSION 0xFF + +typedef enum { + TRACE_CODE_TL_STA_STATE, + TRACE_CODE_TL_EAPOL_PKT_PENDING, + TRACE_CODE_TL_GET_FRAMES_EAPOL, + TRACE_CODE_TL_RX_CONN_EAPOL, + TRACE_CODE_TL_REGISTER_STA_CLIENT, + TRACE_CODE_TL_SUSPEND_DATA_TX, + TRACE_CODE_TL_RESUME_DATA_TX, + TRACE_CODE_TL_STA_PKT_PENDING, + TRACE_CODE_TL_QUEUE_CURRENT, + TRACE_CODE_TL_REORDER_TIMER_EXP_CB, + TRACE_CODE_TL_BA_SESSION_DEL, + TRACE_CODE_TL_ASSOC_FAILED, + TRACE_CODE_TL_FORWARD_CACHED_FRAMES, + TRACE_CODE_TL_FLUSH_CACHED_FRAMES, + TRACE_CODE_TL_CACHE_FRAME, +}WLANTL_TraceCode; + +void tlTraceDump(void *pMac, tpvosTraceRecord pRecord, tANI_U16 recIndex); +void tlTraceInit(void); + +#endif diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c new file mode 100755 index 000000000000..e5786c036f96 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl.c @@ -0,0 +1,14993 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*=========================================================================== + + + W L A N _ Q C T _ T L . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Transport Layer. + + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2013-08-19 rajekuma Added RMC support +2010-07-13 c_shinde Fixed an issue where WAPI rekeying was failing because + WAI frame sent out during rekeying had the protected bit + set to 1. +2010-05-06 rnair Changed name of variable from usLlcType to usEtherType + Changed function name from GetLLCType to GetEtherType + Fixed 802.3 to 802.11 frame translation issue where two + bytes of the LLC header was getting overwritten in the + non-Qos path +2010-05-06 rnair RxAuth path fix for modifying the header before ether + type is retreived (Detected while testing rekeying + in WAPI Volans) +2010-02-19 bad Fixed 802.11 to 802.3 ft issues with WAPI +2010-02-19 rnair WAPI: If frame is a WAI frame in TxConn and TxAuth, TL + does frame translation. +2010-02-01 rnair WAPI: Fixed a bug where the value of ucIsWapiSta was not + being set in the TL control block in the RegisterSTA func. +2010-01-08 lti Added TL Data Caching +2009-11-04 rnair WAPI: Moving common functionality to a seperate function + called WLANTL_GetLLCType +2009-10-15 rnair WAPI: Featurizing WAPI code +2009-10-09 rnair WAPI: Modifications to authenticated state handling of Rx data +2009-10-06 rnair Adding support for WAPI +2009-09-22 lti Add deregistration API for management client +2009-07-16 rnair Temporary fix to let TL fetch packets when multiple + peers exist in an IBSS +2009-06-10 lti Fix for checking TID value of meta info on TX - prevent + memory overwrite + Fix for properly checking the sta id for resuming trigger + frame generation +2009-05-14 lti Fix for sending out trigger frames +2009-05-15 lti Addr3 filtering +2009-04-13 lti Assert if packet larger then allowed + Drop packet that fails flatten +2009-04-02 lti Performance fixes for TL +2009-02-19 lti Added fix for LLC management on Rx Connect +2009-01-16 lti Replaced peek data with extract data for non BD opertions + Extracted frame control in Tl and pass to HAL for frame + type evaluation +2009-02-02 sch Add handoff support +2008-12-09 lti Fixes for AMSS compilation + Removed assert on receive when there is no station +2008-12-02 lti Fix fo trigger frame generation +2008-10-31 lti Fix fo TL tx suspend +2008-10-01 lti Merged in fixes from reordering + Disabled part of UAPSD functionality in TL + (will be re-enabled once UAPSD is tested) + Fix for UAPSD multiple enable +2008-08-10 lti Fixes following UAPSD testing + Fixed infinite loop on mask computation when STA no reg +2008-08-06 lti Fixes after QOS unit testing +2008-08-06 lti Added QOS support +2008-07-23 lti Fix for vos packet draining +2008-07-17 lti Fix for data type value + Added frame translation code in TL + Avoid returning failure to PE in case previous frame is + still pending; fail previous and cache new one for tx + Get frames returning boolean true if more frames are pending +2008-07-03 lti Fixes following pre-integration testing +2008-06-26 lti Fixes following unit testing + Added alloc and free for TL context + Using atomic set u8 instead of u32 +2008-05-16 lti Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_tl.h" +#include "wlan_qct_wda.h" +#include "wlan_qct_tli.h" +#include "wlan_qct_tli_ba.h" +#include "wlan_qct_tl_hosupport.h" +#include "vos_types.h" +#include "vos_trace.h" +#include "wlan_qct_tl_trace.h" +#include "tlDebug.h" +#include "cfgApi.h" +#ifdef FEATURE_WLAN_WAPI +/*Included to access WDI_RxBdType */ +#include "wlan_qct_wdi_bd.h" +#endif +/*Enables debugging behavior in TL*/ +#define TL_DEBUG +/*Enables debugging FC control frame in TL*/ +//#define TL_DEBUG_FC +//#define WLAN_SOFTAP_FLOWCTRL_EN +//#define BTAMP_TEST +#ifdef TL_DEBUG_FC +#include +#include // wpalReadRegister +#endif + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +/*LLC header value*/ +static v_U8_t WLANTL_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; + +#ifdef FEATURE_WLAN_ESE +/*Aironet SNAP header value*/ +static v_U8_t WLANTL_AIRONET_SNAP_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 }; +#endif //FEATURE_WLAN_ESE + +/*BT-AMP packet LLC OUI value*/ +const v_U8_t WLANTL_BT_AMP_OUI[] = {0x00, 0x19, 0x58 }; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +extern const v_U8_t WLANTL_TID_2_AC[WLAN_MAX_TID]; + +#endif + +#define WLANTL_MAX_SNR_DATA_SAMPLES 20 + +#ifdef VOLANS_PERF +#define WLANTL_BD_PDU_INTERRUPT_ENABLE_THRESHOLD 120 +#define WLANTL_BD_PDU_INTERRUPT_GET_THRESHOLD 120 + +/* TL BD/PDU threshold to enable interrupt */ +int bdPduInterruptEnableThreshold = WLANTL_BD_PDU_INTERRUPT_ENABLE_THRESHOLD; +int bdPduInterruptGetThreshold = WLANTL_BD_PDU_INTERRUPT_GET_THRESHOLD; +#endif /* VOLANS_PERF */ + +/*-----------------------------------* + | Type(2b) | Sub-type(4b) | + *-----------------------------------*/ +#define WLANTL_IS_DATA_FRAME(_type_sub) \ + ( WLANTL_DATA_FRAME_TYPE == ( (_type_sub) & 0x30 )) + +#define WLANTL_IS_QOS_DATA_FRAME(_type_sub) \ + (( WLANTL_DATA_FRAME_TYPE == ( (_type_sub) & 0x30 )) && \ + ( WLANTL_80211_DATA_QOS_SUBTYPE == ( (_type_sub) & 0xF ))) + +#define WLANTL_IS_MGMT_FRAME(_type_sub) \ + ( WLANTL_MGMT_FRAME_TYPE == ( (_type_sub) & 0x30 )) + +#define WLANTL_IS_MGMT_ACTION_FRAME(_type_sub) \ + (( WLANTL_MGMT_FRAME_TYPE == ( (_type_sub) & 0x30 )) && \ + ( ( WLANTL_80211_MGMT_ACTION_SUBTYPE == ( (_type_sub) & 0xF )) || \ + ( WLANTL_80211_MGMT_ACTION_NO_ACK_SUBTYPE == ( (_type_sub) & 0xF )))) + +#define WLANTL_IS_PROBE_REQ(_type_sub) \ + ( WLANTL_MGMT_PROBE_REQ_FRAME_TYPE == ( (_type_sub) & 0x3F )) + +#define WLANTL_IS_CTRL_FRAME(_type_sub) \ + ( WLANTL_CTRL_FRAME_TYPE == ( (_type_sub) & 0x30 )) + +#ifdef FEATURE_WLAN_TDLS +#define WLANTL_IS_TDLS_FRAME(_eth_type) \ + ( WLANTL_LLC_TDLS_TYPE == ( _eth_type)) +#endif + +/*MAX Allowed len processed by TL - MAx MTU + 802.3 header + BD+DXE+XTL*/ +#define WLANTL_MAX_ALLOWED_LEN (1514 + 100) + +#define WLANTL_DATA_FLOW_MASK 0x0F + +//some flow_control define +//LWM mode will be enabled for this station if the egress/ingress falls below this ratio +#define WLANTL_LWM_EGRESS_INGRESS_THRESHOLD (0.75) + +//Get enough sample to do the LWM related calculation +#define WLANTL_LWM_INGRESS_SAMPLE_THRESHOLD (64) + +//Maximal on-fly packet per station in LWM mode +#define WLANTL_STA_BMU_THRESHOLD_MAX (256) + +#define WLANTL_AC_MASK (0x7) +#define WLANTL_STAID_OFFSET (0x6) + +/* UINT32 type endian swap */ +#define SWAP_ENDIAN_UINT32(a) ((a) = ((a) >> 0x18 ) |(((a) & 0xFF0000) >> 0x08) | \ + (((a) & 0xFF00) << 0x08) | (((a) & 0xFF) << 0x18)) + +/* Maximum value of SNR that can be calculated by the HW */ +#define WLANTL_MAX_HW_SNR 35 + +#define DISABLE_ARP_TOGGLE 0 +#define ENABLE_ARP_TOGGLE 1 +#define SEND_ARP_ON_WQ5 2 + +#define WLANTL_RATE_RATIO_THRESHOLD 2 +#define WLANTL_PER_THRESHOLD 5 +#define WLANTL_QUEUE_THRESHOLD 60 +#define WLANTL_GOOD_STA_WEIGHT 1 +#define WLANTL_WEIGHT_THRESHOLD 50 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +#define TL_LITTLE_BIT_ENDIAN + +typedef struct +{ + + + v_U8_t protVer :2; + v_U8_t type :2; + v_U8_t subType :4; + + v_U8_t toDS :1; + v_U8_t fromDS :1; + v_U8_t moreFrag :1; + v_U8_t retry :1; + v_U8_t powerMgmt :1; + v_U8_t moreData :1; + v_U8_t wep :1; + v_U8_t order :1; + + +} WLANTL_MACFCType; + +/* 802.11 header */ +typedef struct +{ + /* Frame control field */ + WLANTL_MACFCType wFrmCtrl; + + /* Duration ID */ + v_U16_t usDurationId; + + /* Address 1 field */ + v_U8_t vA1[VOS_MAC_ADDR_SIZE]; + + /* Address 2 field */ + v_U8_t vA2[VOS_MAC_ADDR_SIZE]; + + /* Address 3 field */ + v_U8_t vA3[VOS_MAC_ADDR_SIZE]; + + /* Sequence control field */ + v_U16_t usSeqCtrl; + + // Find the size of the mandatory header size. +#define WLAN80211_MANDATORY_HEADER_SIZE \ + (sizeof(WLANTL_MACFCType) + sizeof(v_U16_t) + \ + (3 * (sizeof(v_U8_t) * VOS_MAC_ADDR_SIZE)) + \ + sizeof(v_U16_t)) + + /* Optional A4 address */ + v_U8_t optvA4[VOS_MAC_ADDR_SIZE]; + + /* Optional QOS control field */ + v_U16_t usQosCtrl; +}WLANTL_80211HeaderType; + +/* 802.3 header */ +typedef struct +{ + /* Destination address field */ + v_U8_t vDA[VOS_MAC_ADDR_SIZE]; + + /* Source address field */ + v_U8_t vSA[VOS_MAC_ADDR_SIZE]; + + /* Length field */ + v_U16_t usLenType; +}WLANTL_8023HeaderType; + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +#define WLAN_TL_INVALID_U_SIG 255 +#define WLAN_TL_INVALID_B_SIG 255 +#define ENTER() VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__) + +#define WLAN_TL_AC_ARRAY_2_MASK( _pSTA, _ucACMask, i ) \ + do\ + {\ + _ucACMask = 0; \ + for ( i = 0; i < WLANTL_NUM_TX_QUEUES; i++ ) \ + { \ + if ( 0 != (_pSTA)->aucACMask[i] ) \ + { \ + _ucACMask |= ( 1 << i ); \ + } \ + } \ + } while (0); + + +/* Following is the copy of g11bRateInfo to understand rate index at TL */ +#define WLANTL_MAX_RATE_NUM 137 +typedef struct +{ + uint32 phyRate; //unit in Mega bits per sec X 10 + uint32 tputRate; //unit in Mega bits per sec X 10 + uint32 tputBpms; //unit in Bytes per msec = (tputRateX1024x1024)/(8x10X1000) ~= (tputRate*13) + uint32 tputBpus; //unit in Bytes per usec: round off to integral value +}WLANTL_RateInfo; + +WLANTL_RateInfo gTLRateInfo[WLANTL_MAX_RATE_NUM] = { + //11b rates + { 10, 9, 117, 0}, //index 0 + { 20, 17, 221, 0}, //index 1 + { 55, 41, 533, 0}, //index 2 + { 110, 68, 884, 0}, //index 3 + + //11b short preamble + { 10, 10, 130, 0}, //index 4 + { 20, 18, 234, 0}, //index 5 + { 55, 44, 572, 0}, //index 6 + { 110, 77, 1001, 0}, //index 7 + + //11ag + { 60, 50, 650, 1}, //index 8 + { 90, 70, 910, 1}, //index 9 + { 120, 100, 1300, 1}, //index 10 + { 180, 150, 1950, 2}, //index 11 + { 240, 190, 2470, 2}, //index 12 + { 360, 280, 3640, 4}, //index 13 + { 480, 350, 4550, 5}, //index 14 + { 540, 380, 4940, 6}, //index 15 + + //11n SIMO + { 65, 54, 702, 1}, //index 16 + { 130, 108, 1404, 1}, //index 17 + { 195, 161, 2093, 2}, //index 18 + { 260, 217, 2821, 3}, //index 19 + { 390, 326, 4238, 4}, //index 20 + { 520, 435, 5655, 6}, //index 21 + { 585, 492, 6396, 6}, //index 22 + { 650, 548, 7124, 7}, //index 23 + + //11n SIMO SGI + { 72, 59, 767, 1}, //index 24 + { 144, 118, 1534, 2}, //index 25 + { 217, 180, 2340, 2}, //index 26 + { 289, 243, 3159, 3}, //index 27 + { 434, 363, 4719, 5}, //index 28 + { 578, 486, 6318, 6}, //index 29 + { 650, 548, 7124, 7}, //index 30 + { 722, 606, 7878, 8}, //index 31 + + //11n GF SIMO + { 65, 54, 702, 1}, //index 32 + { 130, 108, 1404, 1}, //index 33 + { 195, 161, 2093, 2}, //index 34 + { 260, 217, 2821, 3}, //index 35 + { 390, 326, 4238, 4}, //index 36 + { 520, 435, 5655, 6}, //index 37 + { 585, 492, 6396, 6}, //index 38 + { 650, 548, 7124, 7}, //index 39 + + //11n SIMO CB MCS 0 - 7 + { 135, 110, 1430, 1}, //index 40 + { 270, 223, 2899, 3}, //index 41 + { 405, 337, 4381, 4}, //index 42 + { 540, 454, 5902, 6}, //index 43 + { 810, 679, 8827, 9}, //index 44 + { 1080, 909, 11817, 12}, //index 45 + { 1215, 1022, 13286, 13}, //index 46 + { 1350, 1137, 14781, 15}, //index 47 + + //11n SIMO CB SGI MCS 0 - 7 + { 150, 121, 1573, 2}, //index 48 + { 300, 249, 3237, 3}, //index 49 + { 450, 378, 4914, 5}, //index 50 + { 600, 503, 6539, 7}, //index 51 + { 900, 758, 9854, 10}, //index 52 + { 1200, 1010, 13130, 13}, //index 53 + { 1350, 1137, 14781, 15}, //index 54 + { 1500, 1262, 16406, 16}, //index 55 + + //11n SIMO GF CB MCS 0 - 7 + { 135, 110, 1430, 1}, //index 56 + { 270, 223, 2899, 3}, //index 57 + { 405, 337, 4381, 4}, //index 58 + { 540, 454, 5902, 6}, //index 59 + { 810, 679, 8827, 9}, //index 60 + { 1080, 909, 11817, 12}, //index 61 + { 1215, 1022, 13286, 13}, //index 62 + { 1350, 1137, 14781, 15}, //index 63 + + //11AC + { 1350, 675, 8775, 9}, //reserved 64 + { 1350, 675, 8775, 9}, //reserved 65 + { 65, 45, 585, 1}, //index 66 + { 130, 91, 1183, 1}, //index 67 + { 195, 136, 1768, 2}, //index 68 + { 260, 182, 2366, 2}, //index 69 + { 390, 273, 3549, 4}, //index 70 + { 520, 364, 4732, 5}, //index 71 + { 585, 409, 5317, 5}, //index 72 + { 650, 455, 5915, 6}, //index 73 + { 780, 546, 7098, 7}, //index 74 + { 1350, 675, 8775, 9}, //reserved 75 + { 1350, 675, 8775, 9}, //reserved 76 + { 1350, 675, 8775, 9}, //reserved 77 + { 1350, 675, 8775, 9}, //index 78 + { 1350, 675, 8775, 9}, //index 79 + { 1350, 675, 8775, 9}, //index 80 + { 1350, 675, 8775, 9}, //index 81 + { 1350, 675, 8775, 9}, //index 82 + { 1350, 675, 8775, 9}, //index 83 + { 655, 458, 5954, 6}, //index 84 + { 722, 505, 6565, 7}, //index 85 + { 866, 606, 7878, 8}, //index 86 + { 1350, 675, 8775, 9}, //reserved 87 + { 1350, 675, 8775, 9}, //reserved 88 + { 1350, 675, 8775, 9}, //reserved 89 + { 135, 94, 1222, 1}, //index 90 + { 270, 189, 2457, 2}, //index 91 + { 405, 283, 3679, 4}, //index 92 + { 540, 378, 4914, 5}, //index 93 + { 810, 567, 7371, 7}, //index 94 + { 1080, 756, 9828, 10}, //index 95 + { 1215, 850, 11050, 11}, //index 96 + { 1350, 675, 8775, 9}, //index 97 + { 1350, 675, 8775, 9}, //index 98 + { 1620, 810, 10530, 11}, //index 99 + { 1800, 900, 11700, 12}, //index 100 + { 1350, 675, 8775, 9}, //reserved 101 + { 1350, 675, 8775, 9}, //index 102 + { 1350, 675, 8775, 9}, //index 103 + { 1350, 675, 8775, 9}, //index 104 + { 1350, 675, 8775, 9}, //index 105 + { 1350, 675, 8775, 9}, //index 106 + { 1200, 840, 10920, 11}, //index 107 + { 1350, 675, 8775, 9}, //index 108 + { 1500, 750, 9750, 10}, //index 109 + { 1350, 675, 8775, 9}, //index 110 + { 1800, 900, 11700, 12}, //index 111 + { 2000, 1000, 13000, 13}, //index 112 + { 1350, 675, 8775, 9}, //index 113 + { 292, 204, 2652, 3}, //index 114 + { 585, 409, 5317, 5}, //index 115 + { 877, 613, 7969, 8}, //index 116 + { 1170, 819, 10647, 11}, //index 117 + { 1755, 877, 11401, 11}, //index 118 + { 2340, 1170, 15210, 15}, //index 119 + { 2632, 1316, 17108, 17}, //index 120 + { 2925, 1462, 19006, 19}, //index 121 + { 1350, 675, 8775, 9}, //index 122 + { 3510, 1755, 22815, 23}, //index 123 + { 3900, 1950, 25350, 25}, //index 124 + { 1350, 675, 8775, 9}, //reserved 125 + { 1350, 675, 8775, 9}, //index 126 + { 1350, 675, 8775, 9}, //index 127 + { 1350, 675, 8775, 9}, //index 128 + { 1350, 675, 8775, 9}, //index 129 + { 1350, 675, 8775, 9}, //index 130 + { 1350, 675, 8775, 9}, //index 131 + { 2925, 1462, 19006, 19}, //index 132 + { 3250, 1625, 21125, 21}, //index 133 + { 1350, 675, 8775, 9}, //index 134 + { 3900, 1950, 25350, 25}, //index 135 + { 4333, 2166, 28158, 28} //index 136 + }; + + + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +static VOS_STATUS +WLANTL_GetEtherType +( + v_U8_t * aucBDHeader, + vos_pkt_t * vosDataBuff, + v_U8_t ucMPDUHLen, + v_U16_t * usEtherType +); + + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions +* -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Function Declarations and Documentation + * -------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION WLANTL_FreeClientMemory + + DESCRIPTION + It frees up the memory allocated to all the STA clients in TLCB block + Can be called inside Close, Stop or when some FAULT occurs + + DEPENDENCIES + + PARAMETERS + + IN + pClientSTA: Pointer to the global client pointer array + + RETURN VALUE + + SIDE EFFECTS + +============================================================================*/ +void WLANTL_FreeClientMemory +(WLANTL_STAClientType* pClientSTA[WLAN_MAX_STA_COUNT]) +{ + v_U32_t i = 0; + for(i =0; i < WLAN_MAX_STA_COUNT; i++) + { + if( NULL != pClientSTA[i] ) + { + vos_mem_free(pClientSTA[i]); + } + pClientSTA[i] = NULL; + } + return; +} + +/*========================================================================== + + FUNCTION WLANTL_Open + + DESCRIPTION + Called by HDD at driver initialization. TL will initialize all its + internal resources and will wait for the call to start to register + with the other modules. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pTLConfig: TL Configuration + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Open +( + v_PVOID_t pvosGCtx, + WLANTL_ConfigInfoType* pTLConfig +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U8_t ucIndex; + tHalHandle smeContext; + v_U32_t i = 0; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + VOS_STATUS status = VOS_STATUS_SUCCESS; +#endif + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + ENTER(); + vos_alloc_context( pvosGCtx, VOS_MODULE_ID_TL, + (void*)&pTLCb, sizeof(WLANTL_CbType)); + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (( NULL == pTLCb ) || ( NULL == pTLConfig ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL: Invalid input pointer on WLANTL_Open TL %p Config %p", pTLCb, pTLConfig )); + return VOS_STATUS_E_FAULT; + } + + /* Set the default log level to VOS_TRACE_LEVEL_ERROR */ + vos_trace_setLevel(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR); + + smeContext = vos_get_context(VOS_MODULE_ID_SME, pvosGCtx); + if ( NULL == smeContext ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid smeContext", __func__)); + return VOS_STATUS_E_FAULT; + } + + /* Zero out the memory so we are OK, when CleanCB is called.*/ + vos_mem_zero((v_VOID_t *)pTLCb, sizeof(WLANTL_CbType)); + + /*------------------------------------------------------------------------ + Clean up TL control block, initialize all values + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_Open")); + + for ( i =0; iatlSTAClients[i] = vos_mem_malloc(sizeof(WLANTL_STAClientType)); + /* Allocating memory for LEGACY STA COUNT so as to avoid regression issues. */ + if ( NULL == pTLCb->atlSTAClients[i] ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLAN TL: StaClient allocation failed")); + WLANTL_FreeClientMemory(pTLCb->atlSTAClients); + vos_free_context(pvosGCtx, VOS_MODULE_ID_TL, pTLCb); + return VOS_STATUS_E_FAULT; + } + vos_mem_zero((v_VOID_t *) pTLCb->atlSTAClients[i], sizeof(WLANTL_STAClientType)); + } + else + { + pTLCb->atlSTAClients[i] = NULL; + } + } + + pTLCb->reorderBufferPool = vos_mem_vmalloc(sizeof(WLANTL_REORDER_BUFFER_T) * WLANTL_MAX_BA_SESSION); + if (NULL == pTLCb->reorderBufferPool) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLAN TL: Reorder buffer allocation failed")); + WLANTL_FreeClientMemory(pTLCb->atlSTAClients); + vos_free_context(pvosGCtx, VOS_MODULE_ID_TL, pTLCb); + return VOS_STATUS_E_FAULT; + } + + vos_mem_zero((v_VOID_t *)pTLCb->reorderBufferPool, sizeof(WLANTL_REORDER_BUFFER_T) * WLANTL_MAX_BA_SESSION); + + WLANTL_CleanCB(pTLCb, 0 /*do not empty*/); + + for ( ucIndex = 0; ucIndex < WLANTL_NUM_TX_QUEUES ; ucIndex++) + { + pTLCb->tlConfigInfo.ucAcWeights[ucIndex] = pTLConfig->ucAcWeights[ucIndex]; + } + + for ( ucIndex = 0; ucIndex < WLANTL_MAX_AC ; ucIndex++) + { + pTLCb->tlConfigInfo.ucReorderAgingTime[ucIndex] = pTLConfig->ucReorderAgingTime[ucIndex]; + } + + // scheduling init to be the last one of previous round + pTLCb->uCurServedAC = WLANTL_AC_VO; + pTLCb->ucCurLeftWeight = pTLCb->tlConfigInfo.ucAcWeights[pTLCb->uCurServedAC]; + pTLCb->ucCurrentSTA = WLAN_MAX_STA_COUNT-1; + + vos_timer_init(&pTLCb->tx_frames_timer, VOS_TIMER_TYPE_SW, + WLANTL_SampleTx, (void *)pTLCb); +#if 0 + //flow control field init + vos_mem_zero(&pTLCb->tlFCInfo, sizeof(tFcTxParams_type)); + //bit 0: set (Bd/pdu count) bit 1: set (request station PS change notification) + pTLCb->tlFCInfo.fcConfig = 0x1; +#endif + + pTLCb->vosTxFCBuf = NULL; + pTLCb->tlConfigInfo.uMinFramesProcThres = + pTLConfig->uMinFramesProcThres; + +#ifdef FEATURE_WLAN_TDLS + pTLCb->ucTdlsPeerCount = 0; +#endif + + pTLCb->tlConfigInfo.uDelayedTriggerFrmInt = + pTLConfig->uDelayedTriggerFrmInt; + + /*------------------------------------------------------------------------ + Allocate internal resources + ------------------------------------------------------------------------*/ + vos_pkt_get_packet(&pTLCb->vosDummyBuf, VOS_PKT_TYPE_RX_RAW, 1, 1, + 1/*true*/,NULL, NULL); + + WLANTL_InitBAReorderBuffer(pvosGCtx); +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* Initialize Handoff support modue + * RSSI measure and Traffic state monitoring */ + status = WLANTL_HSInit(pvosGCtx); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Handoff support module init fail")); + WLANTL_FreeClientMemory(pTLCb->atlSTAClients); + vos_mem_vfree(pTLCb->reorderBufferPool); + vos_free_context(pvosGCtx, VOS_MODULE_ID_TL, pTLCb); + return status; + } +#endif + +#ifdef WLAN_FEATURE_RMC + status = WLANTL_RmcInit(pvosGCtx); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "RMC module init fail")); + return status; + } +#endif + + pTLCb->isBMPS = VOS_FALSE; + pmcRegisterDeviceStateUpdateInd( smeContext, + WLANTL_PowerStateChangedCB, pvosGCtx ); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_Open */ + +/*========================================================================== + + FUNCTION WLANTL_Start + + DESCRIPTION + Called by HDD as part of the overall start procedure. TL will use this + call to register with BAL as a transport layer entity. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other codes can be returned as a result of a BAL failure; see BAL API + for more info + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Start +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U32_t uResCount = WDA_TLI_MIN_RES_DATA; + VOS_STATUS vosStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + ENTER(); + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_Start")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Register with WDA as transport layer client + Request resources for tx from bus + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLAN TL:WLANTL_Start")); + + tlTraceInit(); + vosStatus = WDA_DS_Register( pvosGCtx, + WLANTL_TxComp, + WLANTL_RxFrames, + WLANTL_GetFrames, + WLANTL_ResourceCB, + WDA_TLI_MIN_RES_DATA, + pvosGCtx, + &uResCount ); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:TL failed to register with BAL/WDA, Err: %d", + vosStatus)); + return vosStatus; + } + + /* Enable transmission */ + vos_atomic_set_U8( &pTLCb->ucTxSuspended, 0); + pTLCb->uResCount = uResCount; + + vos_timer_start(&pTLCb->tx_frames_timer, WLANTL_SAMPLE_INTERVAL); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_Start */ + +/*========================================================================== + + FUNCTION WLANTL_Stop + + DESCRIPTION + Called by HDD to stop operation in TL, before close. TL will suspend all + frame transfer operation and will wait for the close request to clean up + its resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Stop +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U8_t ucIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + ENTER(); + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Stop TL and empty Station list + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_Stop")); + + /* Disable transmission */ + vos_atomic_set_U8( &pTLCb->ucTxSuspended, 1); + + if ( NULL != pTLCb->tlMgmtFrmClient.vosPendingDataBuff ) + { + vos_pkt_return_packet(pTLCb->tlMgmtFrmClient.vosPendingDataBuff); + pTLCb->tlMgmtFrmClient.vosPendingDataBuff = NULL; + } + + if ( NULL != pTLCb->tlBAPClient.vosPendingDataBuff ) + { + vos_pkt_return_packet(pTLCb->tlBAPClient.vosPendingDataBuff); + pTLCb->tlBAPClient.vosPendingDataBuff = NULL; + } + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + if(VOS_STATUS_SUCCESS != WLANTL_HSStop(pvosGCtx)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "Handoff Support module stop fail")); + } +#endif + + if (VOS_TIMER_STATE_STOPPED != + vos_timer_getCurrentState(&pTLCb->tx_frames_timer)) + vos_timer_stop(&pTLCb->tx_frames_timer); + + /*------------------------------------------------------------------------- + Clean client stations + -------------------------------------------------------------------------*/ + for ( ucIndex = 0; ucIndex < WLAN_MAX_STA_COUNT; ucIndex++) + { + if ( NULL != pTLCb->atlSTAClients[ucIndex] ) + { + WLANTL_CleanSTA(pTLCb->atlSTAClients[ucIndex], 1 /*empty all queues*/); + } + } + + + return VOS_STATUS_SUCCESS; +}/* WLANTL_Stop */ + +/*========================================================================== + + FUNCTION WLANTL_Close + + DESCRIPTION + Called by HDD during general driver close procedure. TL will clean up + all the internal resources. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a page + fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Close +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + tHalHandle smeContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + ENTER(); + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Deregister from PMC + ------------------------------------------------------------------------*/ + smeContext = vos_get_context(VOS_MODULE_ID_SME, pvosGCtx); + if ( NULL == smeContext ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid smeContext", __func__)); + // continue so that we can cleanup as much as possible + } + else + { + pmcDeregisterDeviceStateUpdateInd( smeContext, WLANTL_PowerStateChangedCB ); + } + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + if(VOS_STATUS_SUCCESS != WLANTL_HSDeInit(pvosGCtx)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "Handoff Support module DeInit fail")); + } +#endif + +#ifdef WLAN_FEATURE_RMC + if(VOS_STATUS_SUCCESS != WLANTL_RmcDeInit(pvosGCtx)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "RMC module DeInit fail")); + } +#endif + + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pTLCb->tx_frames_timer)) { + vos_timer_stop(&pTLCb->tx_frames_timer); + } + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy(&pTLCb->tx_frames_timer))) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot deallocate TX frames sample timer", __func__)); + } + + /*------------------------------------------------------------------------ + Cleanup TL control block. + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: WLANTL_Close")); + WLANTL_CleanCB(pTLCb, 1 /* empty queues/lists/pkts if any*/); + + WLANTL_FreeClientMemory(pTLCb->atlSTAClients); + + vos_mem_vfree(pTLCb->reorderBufferPool); + + /*------------------------------------------------------------------------ + Free TL context from VOSS global + ------------------------------------------------------------------------*/ + vos_free_context(pvosGCtx, VOS_MODULE_ID_TL, pTLCb); + return VOS_STATUS_SUCCESS; +}/* WLANTL_Close */ + +/*---------------------------------------------------------------------------- + INTERACTION WITH HDD + ---------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION WLANTL_ConfigureSwFrameTXXlationForAll + + DESCRIPTION + Function to disable/enable frame translation for all association stations. + + DEPENDENCIES + + PARAMETERS + IN + pvosGCtx: VOS context + EnableFrameXlation TRUE means enable SW translation for all stations. + . + + RETURN VALUE + + void. + +============================================================================*/ +void +WLANTL_ConfigureSwFrameTXXlationForAll +( + v_PVOID_t pvosGCtx, + v_BOOL_t enableFrameXlation +) +{ + v_U8_t ucIndex; + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx); + WLANTL_STAClientType* pClientSTA = NULL; + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on " + "WLANTL_ConfigureSwFrameTXXlationForAll")); + return; + } + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLANTL_ConfigureSwFrameTXXlationForAll: Configure SW frameXlation %d", + enableFrameXlation)); + + for ( ucIndex = 0; ucIndex < WLAN_MAX_TID; ucIndex++) + { + pClientSTA = pTLCb->atlSTAClients[ucIndex]; + if ( NULL != pClientSTA && 0 != pClientSTA->ucExists ) + { +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // if this station was not allocated resources to perform HW-based + // TX frame translation then force SW-based TX frame translation + // otherwise use the frame translation supplied by the client + if (!WDA_IsHwFrameTxTranslationCapable(pvosGCtx, ucIndex)) + { + pClientSTA->wSTADesc.ucSwFrameTXXlation = 1; + } + else +#endif + pClientSTA->wSTADesc.ucSwFrameTXXlation = enableFrameXlation; + } + } +} + +/*=========================================================================== + + FUNCTION WLANTL_StartForwarding + + DESCRIPTION + + This function is used to ask serialization through TX thread of the + cached frame forwarding (if statation has been registered in the mean while) + or flushing (if station has not been registered by the time) + + In case of forwarding, upper layer is only required to call WLANTL_RegisterSTAClient() + and doesn't need to call this function explicitly. TL will handle this inside + WLANTL_RegisterSTAClient(). + + In case of flushing, upper layer is required to call this function explicitly + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + ucSTAId: station id + + RETURN VALUE + + The result code associated with performing the operation + Please check return values of vos_tx_mq_serialize. + + SIDE EFFECTS + If TL was asked to perform WLANTL_CacheSTAFrame() in WLANTL_RxFrames(), + either WLANTL_RegisterSTAClient() or this function must be called + within reasonable time. Otherwise, TL will keep cached vos buffer until + one of this function is called, and may end up with system buffer exhasution. + + It's an upper layer's responsibility to call this function in case of + flushing + +============================================================================*/ + +VOS_STATUS +WLANTL_StartForwarding +( + v_U8_t ucSTAId, + v_U8_t ucUcastSig, + v_U8_t ucBcastSig +) +{ + vos_msg_t sMessage; + v_U32_t uData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /* Signal the OS to serialize our event */ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "Serializing TL Start Forwarding Cached for control STA %d", + ucSTAId ); + + vos_mem_zero( &sMessage, sizeof(vos_msg_t) ); + + uData = ucSTAId | (ucUcastSig << 8 ) | (ucBcastSig << 16); + sMessage.bodyval = uData; + sMessage.type = WLANTL_RX_FWD_CACHED; + + return vos_rx_mq_serialize(VOS_MQ_ID_TL, &sMessage); + +} /* WLANTL_StartForwarding() */ + +/*=========================================================================== + + FUNCTION WLANTL_EnableCaching + + DESCRIPTION + + This function is used to enable caching only when assoc/reassoc req is send. + that is cache packets only for such STA ID. + + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + staId: station id + + RETURN VALUE + + none + +============================================================================*/ +void WLANTL_EnableCaching(v_U8_t staId) +{ + v_PVOID_t pvosGCtx= vos_get_global_context(VOS_MODULE_ID_TL,NULL); + WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on " + "WLANTL_EnableCaching")); + return; + } + pTLCb->atlSTAClients[staId]->enableCaching = 1; +} + +/*=========================================================================== + + FUNCTION WLANTL_AssocFailed + + DESCRIPTION + + This function is used by PE to notify TL that cache needs to flushed' + when association is not successfully completed + + Internally, TL post a message to TX_Thread to serialize the request to + keep lock-free mechanism. + + + DEPENDENCIES + + TL must have been initialized before this gets called. + + + PARAMETERS + + ucSTAId: station id + + RETURN VALUE + + none + + SIDE EFFECTS + There may be race condition that PE call this API and send another association + request immediately with same staId before TX_thread can process the message. + + To avoid this, we might need PE to wait for TX_thread process the message, + but this is not currently implemented. + +============================================================================*/ +void WLANTL_AssocFailed(v_U8_t staId) +{ + // flushing frames and forwarding frames uses the same message + // the only difference is what happens when the message is processed + // if the STA exist, the frames will be forwarded + // and if it doesn't exist, the frames will be flushed + // in this case we know it won't exist so the DPU index signature values don't matter + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_ASSOC_FAILED, + staId, 0)); + + if(!VOS_IS_STATUS_SUCCESS(WLANTL_StartForwarding(staId,0,0))) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " %s fails to start forwarding (staId %d)", __func__, staId); + } +} + + /*=========================================================================== + + FUNCTION WLANTL_Finish_ULA + + DESCRIPTION + This function is used by HDD to notify TL to finish Upper layer authentication + incase the last EAPOL packet is pending in the TL queue. + To avoid the race condition between sme set key and the last EAPOL packet + the HDD module calls this function just before calling the sme_RoamSetKey. + + DEPENDENCIES + + TL must have been initialized before this gets called. + + PARAMETERS + + callbackRoutine: HDD Callback function. + callbackContext : HDD userdata context. + + RETURN VALUE + + VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS WLANTL_Finish_ULA( void (*callbackRoutine) (void *callbackContext), + void *callbackContext) +{ + return WDA_DS_FinishULA( callbackRoutine, callbackContext); +} + + +/*=========================================================================== + + FUNCTION WLANTL_RegisterSTAClient + + DESCRIPTION + + This function is used by HDD to register as a client for data services + with TL. HDD will call this API for each new station that it adds, + thus having the flexibility of registering different callback for each + STA it services. + + DEPENDENCIES + + TL must have been initialized before this gets called. + + Restriction: + Main thread will have higher priority that Tx and Rx threads thus + guaranteeing that a station will be added before any data can be + received for it. (This enables TL to be lock free) + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pfnStARx: function pointer to the receive packet handler from HDD + pfnSTATxComp: function pointer to the transmit complete confirmation + handler from HDD + pfnSTAFetchPkt: function pointer to the packet retrieval routine in HDD + wSTADescType: STA Descriptor, contains information related to the + new added STA + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterSTAClient +( + v_PVOID_t pvosGCtx, + WLANTL_STARxCBType pfnSTARx, + WLANTL_TxCompCBType pfnSTATxComp, + WLANTL_STAFetchPktCBType pfnSTAFetchPkt, + WLAN_STADescType* pwSTADescType, + v_S7_t rssi +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + v_U8_t ucTid = 0;/*Local variable to clear previous replay counters of STA on all TIDs*/ + v_U32_t istoggleArpEnb = 0; + tpAniSirGlobal pMac; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + ENTER(); + if (( NULL == pwSTADescType ) || ( NULL == pfnSTARx ) || + ( NULL == pfnSTAFetchPkt )) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_RegisterSTAClient")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( pwSTADescType->ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_RegisterSTAClient")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_RegisterSTAClient")); + return VOS_STATUS_E_FAULT; + } + + //Code for checking and allocating memory for new STA + if ( NULL == pTLCb->atlSTAClients[pwSTADescType->ucSTAId] ){ + pTLCb->atlSTAClients[pwSTADescType->ucSTAId] = vos_mem_malloc(sizeof(WLANTL_STAClientType)); + if ( NULL == pTLCb->atlSTAClients[pwSTADescType->ucSTAId] ){ + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: STA Client memory allocation failed in WLANTL_RegisterSTAClient")); + return VOS_STATUS_E_FAILURE; + } + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: STA Client memory allocation in WLANTL_RegisterSTAClient")); + vos_mem_zero((v_VOID_t *) pTLCb->atlSTAClients[pwSTADescType->ucSTAId],sizeof(WLANTL_STAClientType)); + } + + //Assigning the pointer to local variable for easy access in future + pClientSTA = pTLCb->atlSTAClients[pwSTADescType->ucSTAId]; + if ( 0 != pClientSTA->ucExists ) + { + pClientSTA->ucExists++; + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was already registered on WLANTL_RegisterSTAClient")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Register station with TL + ------------------------------------------------------------------------*/ + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_REGISTER_STA_CLIENT, + pwSTADescType->ucSTAId, (unsigned ) + (*(pwSTADescType->vSTAMACAddress.bytes+2)<<24 | + *(pwSTADescType->vSTAMACAddress.bytes+3)<<16 | + *(pwSTADescType->vSTAMACAddress.bytes+4)<<8 | + *(pwSTADescType->vSTAMACAddress.bytes+5)))); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Registering STA Client ID: %d", pwSTADescType->ucSTAId )); + + pClientSTA->pfnSTARx = pfnSTARx; + pClientSTA->pfnSTAFetchPkt = pfnSTAFetchPkt; + + /* Only register if different from NULL - TL default Tx Comp Cb will + release the vos packet */ + if ( NULL != pfnSTATxComp ) + { + pClientSTA->pfnSTATxComp = pfnSTATxComp; + } + + pClientSTA->tlState = WLANTL_STA_INIT; + pClientSTA->tlPri = WLANTL_STA_PRI_NORMAL; + pClientSTA->wSTADesc.ucSTAId = pwSTADescType->ucSTAId; + pClientSTA->ptkInstalled = 0; + pClientSTA->disassoc_progress = VOS_FALSE; + + pMac = vos_get_context(VOS_MODULE_ID_PE, pvosGCtx); + if ( NULL != pMac ) + { + wlan_cfgGetInt(pMac, WNI_CFG_TOGGLE_ARP_BDRATES, &istoggleArpEnb); + } + pClientSTA->arpRate = istoggleArpEnb ? ENABLE_ARP_TOGGLE : DISABLE_ARP_TOGGLE; + pClientSTA->arpOnWQ5 = istoggleArpEnb == SEND_ARP_ON_WQ5; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Registering STA Client ID: %d with UC %d and BC %d toggleArp :%hhu", + pwSTADescType->ucSTAId, pwSTADescType->ucUcastSig, + pwSTADescType->ucBcastSig, pClientSTA->arpRate)); + + pClientSTA->wSTADesc.wSTAType = pwSTADescType->wSTAType; + + pClientSTA->wSTADesc.ucQosEnabled = pwSTADescType->ucQosEnabled; + + pClientSTA->wSTADesc.ucAddRmvLLC = pwSTADescType->ucAddRmvLLC; + + pClientSTA->wSTADesc.ucProtectedFrame = pwSTADescType->ucProtectedFrame; + +#ifdef FEATURE_WLAN_ESE + pClientSTA->wSTADesc.ucIsEseSta = pwSTADescType->ucIsEseSta; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Registering STA Client ID: %d QoS %d Add LLC %d ProtFrame %d EseSta %d", + pwSTADescType->ucSTAId, + pwSTADescType->ucQosEnabled, + pwSTADescType->ucAddRmvLLC, + pwSTADescType->ucProtectedFrame, + pwSTADescType->ucIsEseSta)); +#else + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Registering STA Client ID: %d QoS %d Add LLC %d ProtFrame %d", + pwSTADescType->ucSTAId, + pwSTADescType->ucQosEnabled, + pwSTADescType->ucAddRmvLLC, + pwSTADescType->ucProtectedFrame)); + +#endif //FEATURE_WLAN_ESE +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // if this station was not allocated resources to perform HW-based + // TX frame translation then force SW-based TX frame translation + // otherwise use the frame translation supplied by the client + + if (!WDA_IsHwFrameTxTranslationCapable(pvosGCtx, pwSTADescType->ucSTAId) + || ( WLAN_STA_BT_AMP == pwSTADescType->wSTAType)) + { + pwSTADescType->ucSwFrameTXXlation = 1; + } +#endif + + pClientSTA->wSTADesc.ucSwFrameTXXlation = pwSTADescType->ucSwFrameTXXlation; + pClientSTA->wSTADesc.ucSwFrameRXXlation = pwSTADescType->ucSwFrameRXXlation; + +#ifdef FEATURE_WLAN_WAPI + pClientSTA->wSTADesc.ucIsWapiSta = pwSTADescType->ucIsWapiSta; +#endif /* FEATURE_WLAN_WAPI */ + + vos_copy_macaddr( &pClientSTA->wSTADesc.vSTAMACAddress, &pwSTADescType->vSTAMACAddress); + + vos_copy_macaddr( &pClientSTA->wSTADesc.vBSSIDforIBSS, &pwSTADescType->vBSSIDforIBSS); + + vos_copy_macaddr( &pClientSTA->wSTADesc.vSelfMACAddress, &pwSTADescType->vSelfMACAddress); + + /* In volans release L replay check is done at TL */ + pClientSTA->ucIsReplayCheckValid = pwSTADescType->ucIsReplayCheckValid; + pClientSTA->ulTotalReplayPacketsDetected = 0; +/*Clear replay counters of the STA on all TIDs*/ + for(ucTid = 0; ucTid < WLANTL_MAX_TID ; ucTid++) + { + pClientSTA->ullReplayCounter[ucTid] = 0; + } + + /*-------------------------------------------------------------------- + Set the AC for the registered station to the highest priority AC + Even if this AC is not supported by the station, correction will be + made in the main TL loop after the supported mask is properly + updated in the pending packets call + --------------------------------------------------------------------*/ + pClientSTA->ucCurrentAC = WLANTL_AC_HIGH_PRIO; + pClientSTA->ucCurrentWeight = 0; + pClientSTA->ucServicedAC = WLANTL_AC_BK; + pClientSTA->ucEapolPktPending = 0; + + vos_mem_zero( pClientSTA->aucACMask, sizeof(pClientSTA->aucACMask)); + + vos_mem_zero( &pClientSTA->wUAPSDInfo, sizeof(pClientSTA->wUAPSDInfo)); + + /*-------------------------------------------------------------------- + Reordering info and AMSDU de-aggregation + --------------------------------------------------------------------*/ + vos_mem_zero( pClientSTA->atlBAReorderInfo, + sizeof(pClientSTA->atlBAReorderInfo[0])* + WLAN_MAX_TID); + + vos_mem_zero( pClientSTA->aucMPDUHeader, + WLANTL_MPDU_HEADER_LEN); + + pClientSTA->ucMPDUHeaderLen = 0; + pClientSTA->vosAMSDUChain = NULL; + pClientSTA->vosAMSDUChainRoot = NULL; + + + /* Reorder LOCK + * During handle normal RX frame within RX thread, + * if MC thread try to preempt, ADDBA, DELBA, TIMER + * Context should be protected from race */ + for (ucTid = 0; ucTid < WLAN_MAX_TID ; ucTid++) + { + if (!VOS_IS_STATUS_SUCCESS( + vos_lock_init(&pClientSTA->atlBAReorderInfo[ucTid].reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Lock Init Fail")); + return VOS_STATUS_E_FAILURE; + } + } + /*-------------------------------------------------------------------- + Stats info + --------------------------------------------------------------------*/ + vos_mem_zero( pClientSTA->auRxCount, + sizeof(pClientSTA->auRxCount[0])* + WLAN_MAX_TID); + + vos_mem_zero( pClientSTA->auTxCount, + sizeof(pClientSTA->auRxCount[0])* + WLAN_MAX_TID); + /* Initial RSSI is always reported as zero because TL doesnt have enough + data to calculate RSSI. So to avoid reporting zero, we are initializing + RSSI with RSSI saved in BssDescription during scanning. */ + pClientSTA->rssiAvg = rssi; + pClientSTA->rssiAvgBmps = rssi; +#ifdef FEATURE_WLAN_TDLS + if(WLAN_STA_TDLS == pClientSTA->wSTADesc.wSTAType) + { + /* If client is TDLS, use TDLS specific alpha */ + pClientSTA->rssiAlpha = WLANTL_HO_TDLS_ALPHA; + } + else + { + pClientSTA->rssiAlpha = WLANTL_HO_DEFAULT_ALPHA; + } +#else + pClientSTA->rssiAlpha = WLANTL_HO_DEFAULT_ALPHA; +#endif /* FEATURE_WLAN_TDLS */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + pClientSTA->rssiDataAlpha = WLANTL_HO_DEFAULT_ALPHA; + pClientSTA->interfaceStats.accessCategoryStats[0].ac = WLANTL_AC_BK; + pClientSTA->interfaceStats.accessCategoryStats[1].ac = WLANTL_AC_BE; + pClientSTA->interfaceStats.accessCategoryStats[2].ac = WLANTL_AC_VI; + pClientSTA->interfaceStats.accessCategoryStats[3].ac = WLANTL_AC_VO; +#endif + + /*Tx not suspended and station fully registered*/ + vos_atomic_set_U8( + &pClientSTA->ucTxSuspended, 0); + + /* Used until multiple station support will be added*/ + pTLCb->ucRegisteredStaId = pwSTADescType->ucSTAId; + + /* Save the BAP station ID for future usage */ + if ( WLAN_STA_BT_AMP == pwSTADescType->wSTAType ) + { + pTLCb->tlBAPClient.ucBAPSTAId = pwSTADescType->ucSTAId; + } + + /*------------------------------------------------------------------------ + Statistics info + -----------------------------------------------------------------------*/ + memset(&pClientSTA->trafficStatistics, + 0, sizeof(WLANTL_TRANSFER_STA_TYPE)); + + + /*------------------------------------------------------------------------ + Start with the state suggested by client caller + -----------------------------------------------------------------------*/ + pClientSTA->tlState = pwSTADescType->ucInitState; + /*----------------------------------------------------------------------- + After all the init is complete we can mark the existance flag + ----------------------------------------------------------------------*/ + pClientSTA->ucExists++; + + //flow control fields init + pClientSTA->ucLwmModeEnabled = FALSE; + pClientSTA->ucLwmEventReported = FALSE; + pClientSTA->bmuMemConsumed = 0; + pClientSTA->uIngress_length = 0; + pClientSTA->uBuffThresholdMax = WLANTL_STA_BMU_THRESHOLD_MAX; + + pClientSTA->uLwmThreshold = WLANTL_STA_BMU_THRESHOLD_MAX / 3; + + //@@@ HDDSOFTAP does not queue unregistered packet for now + if ( WLAN_STA_SOFTAP != pwSTADescType->wSTAType ) + { + /*------------------------------------------------------------------------ + Forward received frames while STA was not yet registered + - ----------------------------------------------------------------------*/ + if(!VOS_IS_STATUS_SUCCESS(WLANTL_StartForwarding( pwSTADescType->ucSTAId, + pwSTADescType->ucUcastSig, + pwSTADescType->ucBcastSig))) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " %s fails to start forwarding", __func__); + } +#ifdef FEATURE_WLAN_TDLS + if( WLAN_STA_TDLS == pwSTADescType->wSTAType ) + pTLCb->ucTdlsPeerCount++; +#endif + } +#ifdef WLAN_FEATURE_RMC + vos_lock_init(&pClientSTA->mcLock); +#endif /* WLAN_FEATURE_RMC */ + + return VOS_STATUS_SUCCESS; +}/* WLANTL_RegisterSTAClient */ + +/*=========================================================================== + + FUNCTION WLANTL_ClearSTAClient + + DESCRIPTION + + HDD will call this API when it no longer needs data services for the + particular station. + + DEPENDENCIES + + A station must have been registered before the clear registration is + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA to be cleared + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ClearSTAClient +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U8_t ucIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + ENTER(); + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_ClearSTAClient")); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ClearSTAClient")); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_ClearSTAClient")); + /* Clean packets cached for the STA */ + WLANTL_StartForwarding(ucSTAId,0,0); + return VOS_STATUS_E_EXISTS; + } + + /* Delete BA sessions on all TID's */ + for (ucIndex = 0; ucIndex < WLAN_MAX_TID ; ucIndex++) + { + WLANTL_BaSessionDel(pvosGCtx, ucSTAId, ucIndex); + vos_lock_destroy(&pTLCb->atlSTAClients[ucSTAId]->atlBAReorderInfo[ucIndex].reorderLock); + } + +#ifdef FEATURE_WLAN_TDLS + /* decrement ucTdlsPeerCount only if it is non-zero */ + if(WLAN_STA_TDLS == pTLCb->atlSTAClients[ucSTAId]->wSTADesc.wSTAType + && pTLCb->ucTdlsPeerCount) + pTLCb->ucTdlsPeerCount--; +#endif + + /*------------------------------------------------------------------------ + Clear station + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Clearing STA Client ID: %d", ucSTAId )); + WLANTL_CleanSTA(pTLCb->atlSTAClients[ucSTAId], 1 /*empty packets*/); + +#ifdef WLAN_FEATURE_RMC + /*-------------------------------------------------------------------- + Delete multicast entries for duplicate detection + --------------------------------------------------------------------*/ + WLANTL_McastDeleteAllEntries(pTLCb->atlSTAClients[ucSTAId]); + + vos_lock_destroy(&pTLCb->atlSTAClients[ucSTAId]->mcLock); +#endif /* WLAN_FEATURE_RMC */ + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Clearing STA Reset History RSSI and Region number")); + pTLCb->hoSupport.currentHOState.historyRSSI = 0; + pTLCb->hoSupport.currentHOState.regionNumber = 0; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_ClearSTAClient */ + +/*=========================================================================== + + FUNCTION WLANTL_ChangeSTAState + + DESCRIPTION + + HDD will make this notification whenever a change occurs in the + connectivity state of a particular STA. + + DEPENDENCIES + + A station must have been registered before the change state can be + called. + + RESTRICTION: A station is being notified as authenticated before the + keys are installed in HW. This way if a frame is received + before the keys are installed DPU will drop that frame. + + Main thread has higher priority that Tx and Rx threads thus guaranteeing + the following: + - a station will be in assoc state in TL before TL receives any data + for it + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + tlSTAState: the new state of the connection to the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ChangeSTAState +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAStateType tlSTAState +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( tlSTAState >= WLANTL_STA_MAX_STATE ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Change STA state + No need to lock this operation, see restrictions above + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Changing state for STA Client ID: %d from %d to %d", + ucSTAId, pTLCb->atlSTAClients[ucSTAId]->tlState, tlSTAState)); + + MTRACE(vos_trace(VOS_MODULE_ID_TL, + TRACE_CODE_TL_STA_STATE, ucSTAId,tlSTAState )); + + pTLCb->atlSTAClients[ucSTAId]->tlState = tlSTAState; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_ChangeSTAState */ + +/*=========================================================================== + + FUNCTION WLANTL_UpdateTdlsSTAClient + + DESCRIPTION + + HDD will call this API when ENABLE_LINK happens and HDD want to + register QoS or other params for TDLS peers. + + DEPENDENCIES + + A station must have been registered before the WMM/QOS registration is + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + wSTADescType: STA Descriptor, contains information related to the + new added STA + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_UpdateTdlsSTAClient +( + v_PVOID_t pvosGCtx, + WLAN_STADescType* pwSTADescType +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb || ( WLAN_MAX_STA_COUNT <= pwSTADescType->ucSTAId)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_UpdateTdlsSTAClient")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[pwSTADescType->ucSTAId]; + if ((NULL == pClientSTA) || 0 == pClientSTA->ucExists) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station not exists")); + return VOS_STATUS_E_FAILURE; + } + + pClientSTA->wSTADesc.ucQosEnabled = pwSTADescType->ucQosEnabled; + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: %s: ucQosEnabled of pwSTADescType: %d" + "pClientSTA->wSTADesc: %d", + __func__, pwSTADescType->ucQosEnabled, + pClientSTA->wSTADesc.ucQosEnabled)); + + return VOS_STATUS_SUCCESS; + +} + +VOS_STATUS WLANTL_SetMonRxCbk(v_PVOID_t pvosGCtx, WLANTL_MonRxCBType pfnMonRx) +{ + WLANTL_CbType* pTLCb = NULL ; + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_RegisterSTAClient")); + return VOS_STATUS_E_FAULT; + } + pTLCb->pfnMonRx = pfnMonRx; + return VOS_STATUS_SUCCESS; +} + +void WLANTL_SetIsConversionReq(v_PVOID_t pvosGCtx, v_BOOL_t isConversionReq) +{ + WLANTL_CbType* pTLCb = NULL ; + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_RegisterSTAClient")); + return; + } + pTLCb->isConversionReq = isConversionReq; + return; +} + + +/*=========================================================================== + + FUNCTION WLANTL_STAPtkInstalled + + DESCRIPTION + + HDD will make this notification whenever PTK is installed for the STA + + DEPENDENCIES + + A station must have been registered before the change state can be + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA for which Pairwise key is + installed + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STAPtkInstalled +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Invalid TL pointer from pvosGCtx"))); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Client Memory was not allocated"))); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Station was not previously registered"))); + return VOS_STATUS_E_EXISTS; + } + + pTLCb->atlSTAClients[ucSTAId]->ptkInstalled = 1; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STAPtkInstalled */ + +/*=========================================================================== + + FUNCTION WLANTL_GetSTAState + + DESCRIPTION + + Returns connectivity state of a particular STA. + + DEPENDENCIES + + A station must have been registered before its state can be retrieved. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + + OUT + ptlSTAState: the current state of the connection to the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetSTAState +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAStateType *ptlSTAState +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == ptlSTAState ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_GetSTAState")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_GetSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_GetSTAState")); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Station was not previously registered on WLANTL_GetSTAState")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Get STA state + ------------------------------------------------------------------------*/ + *ptlSTAState = pTLCb->atlSTAClients[ucSTAId]->tlState; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetSTAState */ + +/*========================================================================== + FUNCTION WLANTL_UpdateSTABssIdforIBSS + + DESCRIPTION + HDD will call this API to update the BSSID for this Station. + + DEPENDENCIES + The HDD Should registered the staID with TL before calling this function. + + PARAMETERS + + IN + pvosGCtx: Pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + IN + ucSTAId The Station ID for Bssid to be updated + IN + pBssid BSSID to be updated + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ + + +VOS_STATUS +WLANTL_UpdateSTABssIdforIBSS +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t *pBssid +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested %s", __func__)); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx %s", __func__)); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Station was not previously registered %s", __func__)); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Update the IBSS BSSID + ------------------------------------------------------------------------*/ + vos_mem_copy( &pTLCb->atlSTAClients[ucSTAId]->wSTADesc.vBSSIDforIBSS, + pBssid, sizeof(v_MACADDR_t)); + + return VOS_STATUS_SUCCESS; +} + +/*=========================================================================== + + FUNCTION WLANTL_STAPktPending + + DESCRIPTION + + HDD will call this API when a packet is pending transmission in its + queues. + + DEPENDENCIES + + A station must have been registered before the packet pending + notification can be sent. + + RESTRICTION: TL will not count packets for pending notification. + HDD is expected to send the notification only when + non-empty event gets triggered. Worst case scenario + is that TL might end up making a call when Hdds + queues are actually empty. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that is pending transmission + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STAPktPending +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucAc +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:Packet pending indication for STA: %d AC: %d", ucSTAId, ucAc); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_STAPktPending")); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STAPktPending")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_STAPktPending")); + return VOS_STATUS_E_EXISTS; + } + + /*--------------------------------------------------------------------- + Temporary fix to enable TL to fetch packets when multiple peers join + an IBSS. To fix CR177301. Needs to go away when the actual fix of + going through all STA's in round robin fashion gets merged in from + BT AMP branch. + --------------------------------------------------------------------*/ + pTLCb->ucRegisteredStaId = ucSTAId; + + if( WLANTL_STA_CONNECTED == pClientSTA->tlState ) + { /* EAPOL_HI_PRIORITY : need to find out whether EAPOL is pending before + WLANTL_FetchPacket()/WLANTL_TxConn() is called. + change STA_AUTHENTICATED != tlState to CONNECTED == tlState + to make sure TL is indeed waiting for EAPOL. + Just in the case when STA got disconnected shortly after connectection */ + pClientSTA->ucEapolPktPending = 1; + + MTRACE(vos_trace(VOS_MODULE_ID_TL, + TRACE_CODE_TL_EAPOL_PKT_PENDING, ucSTAId, ucAc)); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Packet pending indication for STA: %d AC: %d State: %d", + ucSTAId, ucAc, pClientSTA->tlState); + } + + /*----------------------------------------------------------------------- + Enable this AC in the AC mask in order for TL to start servicing it + Set packet pending flag + To avoid race condition, serialize the updation of AC and AC mask + through WLANTL_TX_STAID_AC_IND message. + -----------------------------------------------------------------------*/ + + pClientSTA->aucACMask[ucAc] = 1; + + vos_atomic_set_U8( &pClientSTA->ucPktPending, 1); + + /*------------------------------------------------------------------------ + Check if there are enough resources for transmission and tx is not + suspended. + ------------------------------------------------------------------------*/ + if (( pTLCb->uResCount >= WDA_TLI_MIN_RES_DATA ) && + ( 0 == pTLCb->ucTxSuspended )) + { + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Issuing Xmit start request to BAL")); + WDA_DS_StartXmit(pvosGCtx); + } + else + { + /*--------------------------------------------------------------------- + No error code is sent because TL will resume tx autonomously if + resources become available or tx gets resumed + ---------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Request to send but condition not met. Res: %d,Suspend: %d", + pTLCb->uResCount, pTLCb->ucTxSuspended ); + } + return VOS_STATUS_SUCCESS; +}/* WLANTL_STAPktPending */ + +/*========================================================================== + + FUNCTION WLANTL_SetSTAPriority + + DESCRIPTION + + TL exposes this API to allow upper layers a rough control over the + priority of transmission for a given station when supporting multiple + connections. + + DEPENDENCIES + + A station must have been registered before the change in priority can be + called. + + PARAMETERS + + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier for the STA that has to change priority + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_SetSTAPriority +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_STAPriorityType tlSTAPri +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_SetSTAPriority")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_SetSTAPriority")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_SetSTAPriority")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Re-analize if lock is needed when adding multiple stations + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Changing state for STA Pri ID: %d from %d to %d", + ucSTAId, pClientSTA->tlPri, tlSTAPri)); + pClientSTA->tlPri = tlSTAPri; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_SetSTAPriority */ + + +/*---------------------------------------------------------------------------- + INTERACTION WITH BAP + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_RegisterBAPClient + + DESCRIPTION + Called by SME to register itself as client for non-data BT-AMP packets. + + DEPENDENCIES + TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + pfnTlBAPRxFrm: pointer to the receive processing routine for non-data + BT-AMP packets + pfnFlushOpCompleteCb: + pointer to the call back function, for the Flush operation + completion. + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: BAL client was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterBAPClient +( + v_PVOID_t pvosGCtx, + WLANTL_BAPRxCBType pfnTlBAPRxFrm, + WLANTL_FlushOpCompCBType pfnFlushOpCompleteCb +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pfnTlBAPRxFrm ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_RegisterBAPClient")); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == pfnFlushOpCompleteCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid Flush Complete Cb parameter sent on WLANTL_RegisterBAPClient")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_RegisterBAPClient")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Make sure this is the first registration attempt + ------------------------------------------------------------------------*/ + if ( 0 != pTLCb->tlBAPClient.ucExists ) + { + pTLCb->tlBAPClient.ucExists++; + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:BAP client was already registered")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Register station with TL + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Registering BAP Client" )); + + pTLCb->tlBAPClient.ucExists++; + + if ( NULL != pfnTlBAPRxFrm ) + { + pTLCb->tlBAPClient.pfnTlBAPRx = pfnTlBAPRxFrm; + } + + pTLCb->tlBAPClient.pfnFlushOpCompleteCb = pfnFlushOpCompleteCb; + + pTLCb->tlBAPClient.vosPendingDataBuff = NULL; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_RegisterBAPClient */ + + +/*========================================================================== + + FUNCTION WLANTL_TxBAPFrm + + DESCRIPTION + BAP calls this when it wants to send a frame to the module + + DEPENDENCIES + BAP must be registered with TL before this function can be called. + + RESTRICTION: BAP CANNOT push any packets to TL until it did not receive + a tx complete from the previous packet, that means BAP + sends one packet, wait for tx complete and then + sends another one + + If BAP sends another packet before TL manages to process the + previously sent packet call will end in failure + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAP's control block can be extracted from its context + vosDataBuff: pointer to the vOSS buffer containing the packet to be + transmitted + pMetaInfo: meta information about the packet + pfnTlBAPTxComp: pointer to a transmit complete routine for notifying + the result of the operation over the bus + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: BAL client was not yet registered + VOS_STATUS_E_BUSY: The previous BT-AMP packet was not yet transmitted + VOS_STATUS_SUCCESS: Everything is good :) + + Other failure messages may be returned from the BD header handling + routines, please check apropriate API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxBAPFrm +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + WLANTL_MetaInfoType* pMetaInfo, + WLANTL_TxCompCBType pfnTlBAPTxComp +) +{ + WLANTL_CbType* pTLCb = NULL; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_MACADDR_t vDestMacAddr; + v_U16_t usPktLen; + v_U8_t ucStaId = 0; + v_U8_t extraHeadSpace = 0; + v_U8_t ucWDSEnabled = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_TxBAPFrm")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Ensure that BAP client was registered previously + ------------------------------------------------------------------------*/ + if (( 0 == pTLCb->tlBAPClient.ucExists ) || + ( WLANTL_STA_ID_INVALID(pTLCb->tlBAPClient.ucBAPSTAId) )) + { + pTLCb->tlBAPClient.ucExists++; + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:BAP client not register on WLANTL_TxBAPFrm")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Check if any BT-AMP Frm is pending + ------------------------------------------------------------------------*/ + if ( NULL != pTLCb->tlBAPClient.vosPendingDataBuff ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:BT-AMP Frame already pending tx in TL on WLANTL_TxBAPFrm")); + return VOS_STATUS_E_BUSY; + } + + /*------------------------------------------------------------------------ + Save buffer and notify BAL; no lock is needed if the above restriction + is met + Save the tx complete fnct pointer as tl specific data in the vos buffer + ------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------ + Translate 802.3 frame to 802.11 + ------------------------------------------------------------------------*/ + ucStaId = pTLCb->tlBAPClient.ucBAPSTAId; + if ( NULL == pTLCb->atlSTAClients[ucStaId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + if (( 0 == pMetaInfo->ucDisableFrmXtl ) && + ( 0 != pTLCb->atlSTAClients[ucStaId]->wSTADesc.ucSwFrameTXXlation )) + { + vosStatus = WLANTL_Translate8023To80211Header( vosDataBuff, &vosStatus, + pTLCb, &ucStaId, + pMetaInfo, &ucWDSEnabled, + &extraHeadSpace); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Error when translating header WLANTL_TxBAPFrm")); + + return vosStatus; + } + + pMetaInfo->ucDisableFrmXtl = 1; + } + + /*------------------------------------------------------------------------- + Call HAL to fill BD header + -------------------------------------------------------------------------*/ + + /* Adding Type, SubType which was missing for EAPOL from BAP */ + pMetaInfo->ucType |= (WLANTL_80211_DATA_TYPE << 4); + pMetaInfo->ucType |= (WLANTL_80211_DATA_QOS_SUBTYPE); + + vosStatus = WDA_DS_BuildTxPacketInfo( pvosGCtx, vosDataBuff , + &vDestMacAddr, pMetaInfo->ucDisableFrmXtl, + &usPktLen, pTLCb->atlSTAClients[ucStaId]->wSTADesc.ucQosEnabled, + ucWDSEnabled, extraHeadSpace, pMetaInfo->ucType, + &pTLCb->atlSTAClients[ucStaId]->wSTADesc.vSelfMACAddress, + pMetaInfo->ucTID, 0 /* No ACK */, pMetaInfo->usTimeStamp, + pMetaInfo->ucIsEapol || pMetaInfo->ucIsWai, pMetaInfo->ucIsArp, + pMetaInfo->ucUP, pMetaInfo->ucTxBdToken); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed while building TX header %d", vosStatus)); + return vosStatus; + } + + if ( NULL != pfnTlBAPTxComp ) + { + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)pfnTlBAPTxComp); + } + else + { + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)WLANTL_TxCompDefaultCb); + + } + + vos_atomic_set( (uintptr_t*)&pTLCb->tlBAPClient.vosPendingDataBuff, + (uintptr_t)vosDataBuff); + + /*------------------------------------------------------------------------ + Check if thre are enough resources for transmission and tx is not + suspended. + ------------------------------------------------------------------------*/ + if (( pTLCb->uResCount >= WDA_TLI_MIN_RES_BAP ) && + ( 0 == pTLCb->ucTxSuspended )) + { + WDA_DS_StartXmit(pvosGCtx); + } + else + { + /*--------------------------------------------------------------------- + No error code is sent because TL will resume tx autonomously if + resources become available or tx gets resumed + ---------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Request to send from BAP but condition not met.Res: %d," + "Suspend: %d", pTLCb->uResCount, pTLCb->ucTxSuspended )); + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_TxBAPFrm */ + + +/*---------------------------------------------------------------------------- + INTERACTION WITH SME + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_GetRssi + + DESCRIPTION + TL will extract the RSSI information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puRssi: the average value of the RSSI + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetRssi +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_S7_t* pRssi +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pRssi ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_GetRssi")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_GetRssi")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_GetRssi")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_GetRssi")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Copy will not be locked; please read restriction + ------------------------------------------------------------------------*/ + if(pTLCb->isBMPS || IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) + { + *pRssi = pClientSTA->rssiAvgBmps; + /* Check If RSSI is zero because we are reading rssAvgBmps updated by HAL in + previous GetStatsRequest. It may be updated as zero by Hal because EnterBmps + might not have happend by that time. Hence reading the most recent Rssi + calcluated by TL*/ + if(0 == *pRssi) + { + *pRssi = pClientSTA->rssiAvg; + } + } + else + { + *pRssi = pClientSTA->rssiAvg; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_GetRssi for STA: %d RSSI: %d%s", + ucSTAId, *pRssi, + pTLCb->isBMPS ? " in BMPS" : "")); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetRssi */ + +/*========================================================================== + + FUNCTION WLANTL_GetSnr + + DESCRIPTION + TL will extract the SNR information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + pSnr: the average value of the SNR + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetSnr +( + tANI_U8 ucSTAId, + tANI_S8* pSnr +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (NULL == pSnr) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on %s", __func__)); + return VOS_STATUS_E_INVAL; + } + + if (WLANTL_STA_ID_INVALID(ucSTAId)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on %s", __func__)); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(vos_get_global_context(VOS_MODULE_ID_TL, NULL)); + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on %s", __func__)); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if (NULL == pClientSTA) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if (0 == pClientSTA->ucExists) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on %s", __func__)); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Copy will not be locked; please read restriction + ------------------------------------------------------------------------*/ + if (pTLCb->isBMPS) + { + *pSnr = pClientSTA->snrAvgBmps; + } + else + { + /* SNR is averaged over WLANTL_MAX_SNR_DATA_SAMPLES, if there are not enough + * data samples (snridx) to calculate the average then return the + * average for the window of prevoius 20 packets. And if there aren't + * enough samples and the average for previous window of 20 packets is + * not available then return a predefined value + * + * NOTE: the SNR_HACK_BMPS value is defined to 127, documents from HW + * team reveal that the SNR value has a ceiling well below 127 dBm, + * so if SNR has value of 127 the userspace applications can know that + * the SNR has not been computed yet because enough data was not + * available for SNR calculation + */ + if (pClientSTA->snrIdx > (WLANTL_MAX_SNR_DATA_SAMPLES/2) + || !(pClientSTA->prevSnrAvg)) + { + *pSnr = pClientSTA->snrSum / pClientSTA->snrIdx; + } + else if (pClientSTA->prevSnrAvg) + { + *pSnr = pClientSTA->prevSnrAvg; + } + else + { + *pSnr = SNR_HACK_BMPS; + } + } + + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_GetSnr for STA: %d SNR: %d%s", + ucSTAId, *pSnr, + pTLCb->isBMPS ? " in BMPS" : ""); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetSnr */ +/*========================================================================== + + FUNCTION WLANTL_GetLinkQuality + + DESCRIPTION + TL will extract the SNR information from every data packet from the + ongoing traffic and will store it. It will provide the result to SME + upon request. + + DEPENDENCIES + + WARNING: the read and write of this value will not be protected + by locks, therefore the information obtained after a read + might not always be consistent. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + + OUT + puLinkQuality: the average value of the SNR + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: STA was not yet registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetLinkQuality +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U32_t* puLinkQuality +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == puLinkQuality ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid parameter sent on WLANTL_GetLinkQuality")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid station id requested on WLANTL_GetLinkQuality")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid TL pointer from pvosGCtx on WLANTL_GetLinkQuality")); + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Station was not previously registered on WLANTL_GetLinkQuality")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Copy will not be locked; please read restriction + ------------------------------------------------------------------------*/ + *puLinkQuality = pClientSTA->uLinkQualityAvg; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLANTL_GetLinkQuality for STA: %d LinkQuality: %d", ucSTAId, *puLinkQuality)); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetLinkQuality */ + +/*========================================================================== + + FUNCTION WLANTL_FlushStaTID + + DESCRIPTION + TL provides this API as an interface to SME (BAP) layer. TL inturn posts a + message to HAL. This API is called by the SME inorder to perform a flush + operation. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + ucSTAId: station identifier for the requested value + ucTid: Tspec ID for the new BA session + + OUT + The response for this post is received in the main thread, via a response + message from HAL to TL. + + RETURN VALUE + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANTL_FlushStaTID +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid +) +{ + WLANTL_CbType* pTLCb = NULL; + tpFlushACReq FlushACReqPtr = NULL; + vos_msg_t vosMessage; + + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid station id requested on WLANTL_FlushStaTID")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid TL pointer from pvosGCtx on WLANTL_FlushStaTID")); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Station was not previously registered on WLANTL_FlushStaTID")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + We need to post a message with the STA, TID value to HAL. HAL performs the flush + ------------------------------------------------------------------------*/ + FlushACReqPtr = vos_mem_malloc(sizeof(tFlushACReq)); + + if ( NULL == FlushACReqPtr ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: fatal failure, cannot allocate Flush Req structure")); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + // Start constructing the message for HAL + FlushACReqPtr->mesgType = SIR_TL_HAL_FLUSH_AC_REQ; + FlushACReqPtr->mesgLen = sizeof(tFlushACReq); + FlushACReqPtr->mesgLen = sizeof(tFlushACReq); + FlushACReqPtr->ucSTAId = ucSTAId; + FlushACReqPtr->ucTid = ucTid; + + vosMessage.type = WDA_TL_FLUSH_AC_REQ; + vosMessage.bodyptr = (void *)FlushACReqPtr; + + vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + return VOS_STATUS_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + INTERACTION WITH PE + ---------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION WLANTL_updateSpoofMacAddr + + DESCRIPTION + Called by HDD to update macaddr + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + spoofMacAddr: spoofed mac adderess + selfMacAddr: self Mac Address + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_updateSpoofMacAddr +( + v_PVOID_t pvosGCtx, + v_MACADDR_t* spoofMacAddr, + v_MACADDR_t* selfMacAddr +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState"); + return VOS_STATUS_E_FAULT; + } + + vos_mem_copy(pTLCb->spoofMacAddr.selfMac.bytes, selfMacAddr, + VOS_MAC_ADDRESS_LEN); + vos_mem_copy(pTLCb->spoofMacAddr.spoofMac.bytes, spoofMacAddr, + VOS_MAC_ADDRESS_LEN); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "TL: SelfSTA mac Addr for current Scan "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pTLCb->spoofMacAddr.selfMac.bytes)); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_updateSpoofMacAddr */ +/*========================================================================== + + FUNCTION WLANTL_RegisterMgmtFrmClient + + DESCRIPTION + Called by PE to register as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + pfnTlMgmtFrmRx: pointer to the receive processing routine for + management frames + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was already registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RegisterMgmtFrmClient +( + v_PVOID_t pvosGCtx, + WLANTL_MgmtFrmRxCBType pfnTlMgmtFrmRx +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pfnTlMgmtFrmRx ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_RegisterMgmtFrmClient")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Make sure this is the first registration attempt + ------------------------------------------------------------------------*/ + if ( 0 != pTLCb->tlMgmtFrmClient.ucExists ) + { + pTLCb->tlMgmtFrmClient.ucExists++; + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Management frame client was already registered")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Register station with TL + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Registering Management Frame Client" )); + + pTLCb->tlMgmtFrmClient.ucExists++; + + if ( NULL != pfnTlMgmtFrmRx ) + { + pTLCb->tlMgmtFrmClient.pfnTlMgmtFrmRx = pfnTlMgmtFrmRx; + } + + pTLCb->tlMgmtFrmClient.vosPendingDataBuff = NULL; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_RegisterMgmtFrmClient */ + +/*========================================================================== + + FUNCTION WLANTL_DeRegisterMgmtFrmClient + + DESCRIPTION + Called by PE to deregister as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL's control block can be extracted from its context + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was never registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_DeRegisterMgmtFrmClient +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Make sure this is the first registration attempt + ------------------------------------------------------------------------*/ + if ( 0 == pTLCb->tlMgmtFrmClient.ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Management frame client was never registered")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Clear registration with TL + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Deregistering Management Frame Client" )); + + pTLCb->tlMgmtFrmClient.pfnTlMgmtFrmRx = WLANTL_MgmtFrmRxDefaultCb; + if ( NULL != pTLCb->tlMgmtFrmClient.vosPendingDataBuff) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Management cache buffer not empty on deregistering" + " - dropping packet" )); + vos_pkt_return_packet(pTLCb->tlMgmtFrmClient.vosPendingDataBuff); + + pTLCb->tlMgmtFrmClient.vosPendingDataBuff = NULL; + } + + pTLCb->tlMgmtFrmClient.ucExists = 0; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_RegisterMgmtFrmClient */ + +/*========================================================================== + + FUNCTION WLANTL_TxMgmtFrm + + DESCRIPTION + Called by PE when it want to send out a management frame. + HAL will also use this API for the few frames it sends out, they are not + management frames howevere it is accepted that an exception will be + allowed ONLY for the usage of HAL. + Generic data frames SHOULD NOT travel through this function. + + DEPENDENCIES + TL must be initialized before this API can be called. + + RESTRICTION: If PE sends another packet before TL manages to process the + previously sent packet call will end in failure + + Frames comming through here must be 802.11 frames, frame + translation in UMA will be automatically disabled. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context;a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management + frame to be transmitted + usFrmLen: the length of the frame to be transmitted; information + is already included in the vOSS buffer + wFrmType: the type of the frame being transmitted + tid: tid used to transmit this frame + pfnCompTxFunc: function pointer to the transmit complete routine + pvBDHeader: pointer to the BD header, if NULL it means it was not + yet constructed and it lies within TL's responsibility + to do so; if not NULL it is expected that it was + already packed inside the vos packet + ucAckResponse: flag notifying it an interrupt is needed for the + acknowledgement received when the frame is sent out + the air and ; the interrupt will be processed by HAL, + only one such frame can be pending in the system at + one time. + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Mgmt Frame client was not yet registered + VOS_STATUS_E_BUSY: The previous Mgmt packet was not yet transmitted + VOS_STATUS_SUCCESS: Everything is good :) + + Other failure messages may be returned from the BD header handling + routines, please check apropriate API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxMgmtFrm +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosFrmBuf, + v_U16_t usFrmLen, + v_U8_t wFrmType, + v_U8_t ucTid, + WLANTL_TxCompCBType pfnCompTxFunc, + v_PVOID_t pvBDHeader, + v_U32_t ucAckResponse, + v_U32_t ucTxBdToken +) +{ + WLANTL_CbType* pTLCb = NULL; + v_MACADDR_t vDestMacAddr; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U16_t usPktLen; + v_U32_t usTimeStamp = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == vosFrmBuf ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_TxMgmtFrm")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_TxMgmtFrm")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Ensure that management frame client was previously registered + ------------------------------------------------------------------------*/ + if ( 0 == pTLCb->tlMgmtFrmClient.ucExists ) + { + pTLCb->tlMgmtFrmClient.ucExists++; + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Management Frame client not register on WLANTL_TxMgmtFrm")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Check if any Mgmt Frm is pending + ------------------------------------------------------------------------*/ + //vosTempBuff = pTLCb->tlMgmtFrmClient.vosPendingDataBuff; + if ( NULL != pTLCb->tlMgmtFrmClient.vosPendingDataBuff ) + { + + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Management Frame already pending tx in TL: failing old one")); + + + /*Failing the tx for the previous packet enqued by PE*/ + //vos_atomic_set( (uintptr_t*)&pTLCb->tlMgmtFrmClient.vosPendingDataBuff, + // (uintptr_t)NULL); + + //vos_pkt_get_user_data_ptr( vosTempBuff, VOS_PKT_USER_DATA_ID_TL, + // (v_PVOID_t)&pfnTxComp); + + /*it should never be NULL - default handler should be registered if none*/ + //if ( NULL == pfnTxComp ) + //{ + // VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + // "NULL pointer to Tx Complete on WLANTL_TxMgmtFrm"); + // VOS_ASSERT(0); + // return VOS_STATUS_E_FAULT; + //} + + //pfnTxComp( pvosGCtx, vosTempBuff, VOS_STATUS_E_RESOURCES ); + //return VOS_STATUS_E_BUSY; + + + //pfnCompTxFunc( pvosGCtx, vosFrmBuf, VOS_STATUS_E_RESOURCES); + return VOS_STATUS_E_RESOURCES; + } + + + /*------------------------------------------------------------------------ + Check if BD header was build, if not construct + ------------------------------------------------------------------------*/ + if ( NULL == pvBDHeader ) + { + v_MACADDR_t* pvAddr2MacAddr; + v_U8_t uQosHdr = VOS_FALSE; + + /* Get address 2 of Mangement Frame to give to WLANHAL_FillTxBd */ + vosStatus = vos_pkt_peek_data( vosFrmBuf, + WLANTL_MAC_ADDR_ALIGN(1) + VOS_MAC_ADDR_SIZE, + (v_PVOID_t)&pvAddr2MacAddr, VOS_MAC_ADDR_SIZE); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Failed while attempting to get addr2 %d", vosStatus)); + return vosStatus; + } + + /* ESE IAPP/TDLS Frame which are data frames but technically used + * for management functionality comes through route. + */ + if (WLANTL_IS_QOS_DATA_FRAME(wFrmType)) \ + { + uQosHdr = VOS_TRUE; + } + + if (WLANTL_IS_PROBE_REQ(wFrmType)) + { + if (VOS_TRUE == vos_mem_compare((v_VOID_t*) pvAddr2MacAddr, + (v_VOID_t*) &pTLCb->spoofMacAddr.spoofMac, VOS_MAC_ADDRESS_LEN)) + { + pvAddr2MacAddr = (v_PVOID_t)pTLCb->spoofMacAddr.selfMac.bytes; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "TL: using self sta addr to get staidx for spoofed probe req " + MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pvAddr2MacAddr->bytes)); + } + } + + /*---------------------------------------------------------------------- + Call WDA to build TX header + ----------------------------------------------------------------------*/ + vosStatus = WDA_DS_BuildTxPacketInfo( pvosGCtx, vosFrmBuf , &vDestMacAddr, + 1 /* always 802.11 frames*/, &usPktLen, uQosHdr /*qos not enabled !!!*/, + 0 /* WDS off */, 0, wFrmType, pvAddr2MacAddr, ucTid, + ucAckResponse, usTimeStamp, 0, 0, 0, ucTxBdToken); + + + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Failed while attempting to build TX header %d", vosStatus)); + return vosStatus; + } + }/* if BD header not present */ + + /*------------------------------------------------------------------------ + Save buffer and notify BAL; no lock is needed if the above restriction + is met + Save the tx complete fnct pointer as tl specific data in the vos buffer + ------------------------------------------------------------------------*/ + if ( NULL != pfnCompTxFunc ) + { + vos_pkt_set_user_data_ptr( vosFrmBuf, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)pfnCompTxFunc); + } + else + { + vos_pkt_set_user_data_ptr( vosFrmBuf, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)WLANTL_TxCompDefaultCb); + + } + vos_atomic_set( (uintptr_t*)&pTLCb->tlMgmtFrmClient.vosPendingDataBuff, + (uintptr_t)vosFrmBuf); + + /*------------------------------------------------------------------------ + Check if thre are enough resources for transmission and tx is not + suspended. + ------------------------------------------------------------------------*/ + if ( pTLCb->uResCount >= WDA_TLI_MIN_RES_MF ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Issuing Xmit start request to BAL for MGMT")); + vosStatus = WDA_DS_StartXmit(pvosGCtx); + if(VOS_STATUS_SUCCESS != vosStatus) + { + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:WDA_DS_StartXmit fails. vosStatus %d", vosStatus)); + vos_atomic_set( (uintptr_t*)&pTLCb->tlMgmtFrmClient.vosPendingDataBuff,0); + } + return vosStatus; + + } + else + { + /*--------------------------------------------------------------------- + No error code is sent because TL will resume tx autonomously if + resources become available or tx gets resumed + ---------------------------------------------------------------------*/ + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Request to send for Mgmt Frm but condition not met. Res: %d", + pTLCb->uResCount)); + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_TxMgmtFrm */ + +/*---------------------------------------------------------------------------- + INTERACTION WITH HAL + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_ResetNotification + + DESCRIPTION + HAL notifies TL when the module is being reset. + Currently not used. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResetNotification +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ResetNotification")); + return VOS_STATUS_E_FAULT; + } + + WLANTL_CleanCB(pTLCb, 1 /*empty all queues and pending packets*/); + return VOS_STATUS_SUCCESS; +}/* WLANTL_ResetNotification */ + +/*========================================================================== + + FUNCTION WLANTL_SuspendDataTx + + DESCRIPTION + HAL calls this API when it wishes to suspend transmission for a + particular STA. + + DEPENDENCIES + The STA for which the request is made must be first registered with + TL by HDD. + + RESTRICTION: In case of a suspend, the flag write and read will not be + locked: worst case scenario one more packet can get + through before the flag gets updated (we can make this + write atomic as well to guarantee consistency) + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pucSTAId: identifier of the station for which the request is made; + a value of NULL assumes suspend on all active station + pfnSuspendTxCB: pointer to the suspend result notification in case the + call is asynchronous + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_SuspendDataTx +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + WLANTL_SuspendCBType pfnSuspendTx +) +{ + WLANTL_CbType* pTLCb = NULL; + vos_msg_t vosMsg; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_SuspendDataTx")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Check the type of request: generic suspend, or per station suspend + ------------------------------------------------------------------------*/ + if (NULL == pucSTAId) + { + /* General Suspend Request received */ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:General suspend requested")); + vos_atomic_set_U8( &pTLCb->ucTxSuspended, 1); + vosMsg.reserved = WLAN_MAX_STA_COUNT; + } + else + { + if ( WLANTL_STA_ID_INVALID( *pucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id %d requested on WLANTL_SuspendDataTx", *pucSTAId)); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[*pucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid pTLCb->atlSTAClients pointer for STA Id :%d on " + "WLANTL_SuspendDataTx", *pucSTAId)); + return VOS_STATUS_E_FAULT; + } + + if ( 0 == pTLCb->atlSTAClients[*pucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station %d was not previously registered on WLANTL_SuspendDataTx", *pucSTAId)); + return VOS_STATUS_E_EXISTS; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Suspend request for station: %d", *pucSTAId)); + vos_atomic_set_U8( &pTLCb->atlSTAClients[*pucSTAId]->ucTxSuspended, 1); + vosMsg.reserved = *pucSTAId; + } + + /*------------------------------------------------------------------------ + Serialize request through TX thread + ------------------------------------------------------------------------*/ + vosMsg.type = WLANTL_TX_SIG_SUSPEND; + vosMsg.bodyptr = (v_PVOID_t)pfnSuspendTx; + + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_SUSPEND_DATA_TX, + vosMsg.reserved , 0 )); + + if(!VOS_IS_STATUS_SUCCESS(vos_tx_mq_serialize( VOS_MQ_ID_TL, &vosMsg))) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " %s fails to post message", __func__); + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_SuspendDataTx */ + +/*========================================================================== + + FUNCTION WLANTL_ResumeDataTx + + DESCRIPTION + Called by HAL to resume data transmission for a given STA. + + WARNING: If a station was individually suspended a global resume will + not resume that station + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pucSTAId: identifier of the station which is being resumed; NULL + translates into global resume + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_ResumeDataTx +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ResumeDataTx")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Check to see the type of resume + ------------------------------------------------------------------------*/ + if ( NULL == pucSTAId ) + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_RESUME_DATA_TX, + 41 , 0 )); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:General resume requested")); + vos_atomic_set_U8( &pTLCb->ucTxSuspended, 0); + } + else + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_RESUME_DATA_TX, + *pucSTAId , 0 )); + + if ( WLANTL_STA_ID_INVALID( *pucSTAId )) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id %d requested on WLANTL_ResumeDataTx", *pucSTAId)); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[*pucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid pTLCb->atlSTAClients pointer for STA Id :%d on " + "WLANTL_ResumeDataTx", *pucSTAId)); + return VOS_STATUS_E_FAULT; + } + + if ( 0 == pTLCb->atlSTAClients[*pucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station %d was not previously registered on WLANTL_ResumeDataTx", *pucSTAId)); + return VOS_STATUS_E_EXISTS; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Resume request for station: %d", *pucSTAId)); + vos_atomic_set_U8( &pTLCb->atlSTAClients[*pucSTAId]->ucTxSuspended, 0); + } + + /*------------------------------------------------------------------------ + Resuming transmission + ------------------------------------------------------------------------*/ + if (( pTLCb->uResCount >= WDA_TLI_MIN_RES_MF ) && + ( 0 == pTLCb->ucTxSuspended )) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Resuming transmission")); + return WDA_DS_StartXmit(pvosGCtx); + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_ResumeDataTx */ + +/*========================================================================== + FUNCTION WLANTL_SuspendCB + + DESCRIPTION + Callback function for serializing Suspend signal through Tx thread + + DEPENDENCIES + Just notify HAL that suspend in TL is complete. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pUserData: user data sent with the callback + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_SuspendCB +( + v_PVOID_t pvosGCtx, + WLANTL_SuspendCBType pfnSuspendCB, + v_U16_t usReserved +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U8_t ucSTAId = (v_U8_t)usReserved; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pfnSuspendCB ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: No Call back processing requested WLANTL_SuspendCB")); + return VOS_STATUS_SUCCESS; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_SuspendCB")); + return VOS_STATUS_E_FAULT; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + pfnSuspendCB(pvosGCtx, NULL, VOS_STATUS_SUCCESS); + } + else + { + pfnSuspendCB(pvosGCtx, &ucSTAId, VOS_STATUS_SUCCESS); + } + + return VOS_STATUS_SUCCESS; +}/*WLANTL_SuspendCB*/ + + +/*---------------------------------------------------------------------------- + CLIENT INDEPENDENT INTERFACE + ---------------------------------------------------------------------------*/ + +/*========================================================================== + + FUNCTION WLANTL_GetTxPktCount + + DESCRIPTION + TL will provide the number of transmitted packets counted per + STA per TID. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + ucTid: identifier of the tspec + + OUT + puTxPktCount: the number of packets tx packet for this STA and TID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetTxPktCount +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid, + v_U32_t* puTxPktCount +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == puTxPktCount ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_GetTxPktCount")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) || WLANTL_TID_INVALID( ucTid) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id %d/tid %d requested on WLANTL_GetTxPktCount", + ucSTAId, ucTid)); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check if station exists + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_GetTxPktCount")); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_GetTxPktCount %d", + ucSTAId)); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Return data + ------------------------------------------------------------------------*/ + //VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_MED, + // "WLAN TL:Requested tx packet count for STA: %d, TID: %d", + // ucSTAId, ucTid); + + *puTxPktCount = pTLCb->atlSTAClients[ucSTAId]->auTxCount[ucTid]; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetTxPktCount */ + +/*========================================================================== + + FUNCTION WLANTL_GetRxPktCount + + DESCRIPTION + TL will provide the number of received packets counted per + STA per TID. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + ucTid: identifier of the tspec + + OUT + puTxPktCount: the number of packets rx packet for this STA and TID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetRxPktCount +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucTid, + v_U32_t* puRxPktCount +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == puRxPktCount ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_GetRxPktCount")); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) || WLANTL_TID_INVALID( ucTid) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id %d/tid %d requested on WLANTL_GetRxPktCount", + ucSTAId, ucTid)); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_GetRxPktCount")); + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not previously registered on WLANTL_GetRxPktCount")); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Return data + ------------------------------------------------------------------------*/ + TLLOG3(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_MED, + "WLAN TL:Requested rx packet count for STA: %d, TID: %d", + ucSTAId, ucTid)); + + *puRxPktCount = pClientSTA->auRxCount[ucTid]; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetRxPktCount */ + +VOS_STATUS +WLANTL_TxFCFrame +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_IsEAPOLPending + + DESCRIPTION + + HDD calls this function when hdd_tx_timeout occurs. This checks whether + EAPOL is pending. + + DEPENDENCIES + + HDD must have registered with TL at least one STA before this function + can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context + + RETURN VALUE + + The result code associated with performing the operation + + Success : Indicates EAPOL frame is pending and sta is in connected state + + Failure : EAPOL frame is not pending + + SIDE EFFECTS +============================================================================*/ +VOS_STATUS +WLANTL_IsEAPOLPending +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U32_t i = 0; + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer for pvosGCtx")); + return VOS_STATUS_E_FAILURE; + } + /*--------------------------------------------------------------------- + Check to see if there was any EAPOL packet is pending + *--------------------------------------------------------------------*/ + for ( i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if ((NULL != pTLCb->atlSTAClients[i]) && + (pTLCb->atlSTAClients[i]->ucExists) && + (0 == pTLCb->atlSTAClients[i]->ucTxSuspended) && + (WLANTL_STA_CONNECTED == pTLCb->atlSTAClients[i]->tlState) && + (pTLCb->atlSTAClients[i]->ucPktPending) + ) + return VOS_STATUS_SUCCESS; + } + return VOS_STATUS_E_FAILURE; +} + +/*============================================================================ + TL INTERNAL API DEFINITION +============================================================================*/ + +/*========================================================================== + + FUNCTION WLANTL_GetFrames + + DESCRIPTION + + BAL calls this function at the request of the lower bus interface. + When this request is being received TL will retrieve packets from HDD + in accordance with the priority rules and the count supplied by BAL. + + DEPENDENCIES + + HDD must have registered with TL at least one STA before this function + can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAL's control block can be extracted from its context + uSize: maximum size accepted by the lower layer + uFlowMask TX flow control mask for Prima. Each bit is defined as + WDA_TXFlowEnumType + + OUT + vosDataBuff: it will contain a pointer to the first buffer supplied + by TL, if there is more than one packet supplied, TL + will chain them through vOSS buffers + + RETURN VALUE + + The result code associated with performing the operation + + 1 or more: number of required resources if there are still frames to fetch + 0 : error or HDD queues are drained + + SIDE EFFECTS + + NOTE + + Featurized uFlowMask. If we want to remove featurization, we need to change + BAL on Volans. + +============================================================================*/ +v_U32_t +WLANTL_GetFrames +( + v_PVOID_t pvosGCtx, + vos_pkt_t **ppFrameDataBuff, + v_U32_t uSize, + v_U8_t uFlowMask, + v_BOOL_t* pbUrgent +) +{ + vos_pkt_t** pvosDataBuff = (vos_pkt_t**)ppFrameDataBuff; + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + v_U32_t uRemaining = uSize; + vos_pkt_t* vosRoot; + vos_pkt_t* vosTempBuf; + WLANTL_STAFuncType pfnSTAFsm; + v_U16_t usPktLen; + v_U32_t uResLen; + v_U8_t ucSTAId; + v_U8_t ucAC; + vos_pkt_t* vosDataBuff; + v_U32_t uTotalPktLen; + v_U32_t i=0; + v_U32_t j=0; + v_U32_t ucResult = 0; + VOS_STATUS vosStatus; + WLANTL_STAEventType wSTAEvent; + tBssSystemRole systemRole; + tpAniSirGlobal pMac; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (( NULL == pTLCb ) || ( NULL == pvosDataBuff )) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return ucResult; + } + + pMac = vos_get_context(VOS_MODULE_ID_PE, pvosGCtx); + if ( NULL == pMac ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pMac", __func__)); + return ucResult; + } + + vosDataBuff = pTLCb->vosDummyBuf; /* Just to avoid checking for NULL at + each iteration */ + + pTLCb->uResCount = uSize; + + /*----------------------------------------------------------------------- + Save the root as we will walk this chain as we fill it + -----------------------------------------------------------------------*/ + vosRoot = vosDataBuff; + + /*----------------------------------------------------------------------- + There is still data - until FSM function says otherwise + -----------------------------------------------------------------------*/ + pTLCb->bUrgent = FALSE; + + while (( pTLCb->tlConfigInfo.uMinFramesProcThres < pTLCb->uResCount ) && + ( 0 < uRemaining )) + { + systemRole = wdaGetGlobalSystemRole(pMac); +#ifdef WLAN_SOFTAP_FLOWCTRL_EN +/* FIXME: The code has been disabled since it is creating issues in power save */ + if (eSYSTEM_AP_ROLE == systemRole) + { + if (pTLCb->done_once == 0 && NULL == pTLCb->vosTxFCBuf) + { + WLANTL_TxFCFrame (pvosGCtx); + pTLCb->done_once ++; + } + } + if ( NULL != pTLCb->vosTxFCBuf ) + { + //there is flow control packet waiting to be sent + WDA_TLI_PROCESS_FRAME_LEN( pTLCb->vosTxFCBuf, usPktLen, uResLen, uTotalPktLen); + + if ( ( pTLCb->uResCount > uResLen ) && + ( uRemaining > uTotalPktLen ) && + ( uFlowMask & ( 1 << WDA_TXFLOW_FC ) ) ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Chaining FC frame first on GetFrame")); + + vos_pkt_chain_packet( vosDataBuff, pTLCb->vosTxFCBuf, 1 /*true*/ ); + + vos_atomic_set( (uintptr_t*)&pTLCb->vosTxFCBuf, (uintptr_t) NULL); + + /*FC frames cannot be delayed*/ + pTLCb->bUrgent = TRUE; + + /*Update remaining len from SSC */ + uRemaining -= (usPktLen + WDA_DXE_HEADER_SIZE); + + /*Update resource count */ + pTLCb->uResCount -= uResLen; + } + else + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:send fc out of source %s", __func__)); + ucResult = ( pTLCb->uResCount > uResLen )?VOS_TRUE:VOS_FALSE; + break; /* Out of resources or reached max len */ + } + } + else +#endif //WLAN_SOFTAP_FLOWCTRL_EN + + if (( NULL != pTLCb->tlMgmtFrmClient.vosPendingDataBuff ) && + ( uFlowMask & ( 1 << WDA_TXFLOW_MGMT ) ) ) + { + WDA_TLI_PROCESS_FRAME_LEN( pTLCb->tlMgmtFrmClient.vosPendingDataBuff, + usPktLen, uResLen, uTotalPktLen); + + if (usPktLen > WLANTL_MAX_ALLOWED_LEN) + { + usPktLen = WLANTL_MAX_ALLOWED_LEN; + VOS_ASSERT(0); + } + + if ( ( pTLCb->uResCount > uResLen ) && + ( uRemaining > uTotalPktLen ) && + ( uFlowMask & ( 1 << WDA_TXFLOW_MGMT ) ) ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Chaining management frame on GetFrame")); + + vos_pkt_chain_packet( vosDataBuff, + pTLCb->tlMgmtFrmClient.vosPendingDataBuff, + 1 /*true*/ ); + + vos_atomic_set( (uintptr_t*)&pTLCb->tlMgmtFrmClient. + vosPendingDataBuff, (uintptr_t)NULL); + + /*management frames cannot be delayed*/ + pTLCb->bUrgent = TRUE; + + /*Update remaining len from SSC */ + uRemaining -= (usPktLen + WDA_DXE_HEADER_SIZE); + + /*Update resource count */ + pTLCb->uResCount -= uResLen; + } + else + { + ucResult = ( pTLCb->uResCount > uResLen )?VOS_TRUE:VOS_FALSE; + break; /* Out of resources or reached max len */ + } + } + else if (( pTLCb->tlBAPClient.vosPendingDataBuff ) && + ( WDA_TLI_MIN_RES_BAP <= pTLCb->uResCount ) && + ( 0 == pTLCb->ucTxSuspended ) ) + { + WDA_TLI_PROCESS_FRAME_LEN( pTLCb->tlBAPClient.vosPendingDataBuff, + usPktLen, uResLen, uTotalPktLen); + + if (usPktLen > WLANTL_MAX_ALLOWED_LEN) + { + usPktLen = WLANTL_MAX_ALLOWED_LEN; + VOS_ASSERT(0); + } + + if ( ( pTLCb->uResCount > (uResLen + WDA_TLI_MIN_RES_MF ) ) && + ( uRemaining > uTotalPktLen )) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Chaining BT-AMP frame on GetFrame")); + + vos_pkt_chain_packet( vosDataBuff, + pTLCb->tlBAPClient.vosPendingDataBuff, + 1 /*true*/ ); + + /*BAP frames cannot be delayed*/ + pTLCb->bUrgent = TRUE; + + vos_atomic_set( (uintptr_t*)&pTLCb->tlBAPClient.vosPendingDataBuff, + (uintptr_t) NULL); + + /*Update remaining len from SSC */ + uRemaining -= (usPktLen + WDA_DXE_HEADER_SIZE); + + /*Update resource count */ + pTLCb->uResCount -= uResLen; + } + else + { + ucResult = uResLen + WDA_TLI_MIN_RES_MF; + break; /* Out of resources or reached max len */ + } + } + /* note: this feature implemented only after WLAN_INGETRATED_SOC */ + /* search 'EAPOL_HI_PRIORITY' will show EAPOL HI_PRIORITY change in TL and WDI + by default, EAPOL will be treated as higher priority, which means + use mgmt_pool and DXE_TX_HI prority channel. + this is introduced to address EAPOL failure under high background traffic + with multi-channel concurrent mode. But this change works in SCC or standalone, too. + see CR#387009 and WCNSOS-8 + */ + else if (( WDA_TLI_MIN_RES_MF <= pTLCb->uResCount )&& + ( 0 == pTLCb->ucTxSuspended ) && + ( uFlowMask & ( 1 << WDA_TXFLOW_MGMT ) ) + ) + { + vosTempBuf = NULL; + /*--------------------------------------------------------------------- + Check to see if there was any EAPOL packet is pending + *--------------------------------------------------------------------*/ + for ( i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if ((NULL != pTLCb->atlSTAClients[i]) && + (pTLCb->atlSTAClients[i]->ucExists) && + (0 == pTLCb->atlSTAClients[i]->ucTxSuspended) && + (WLANTL_STA_CONNECTED == pTLCb->atlSTAClients[i]->tlState) && + (pTLCb->atlSTAClients[i]->ucPktPending) + ) + break; + } + + if (i >= WLAN_MAX_STA_COUNT) + { + /* No More to Serve Exit Get Frames */ + break; + } + /* Serve EAPOL frame with HI_FLOW_MASK */ + ucSTAId = i; + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + MTRACE(vos_trace(VOS_MODULE_ID_TL, + TRACE_CODE_TL_GET_FRAMES_EAPOL, ucSTAId, pClientSTA->tlState)); + + if (pClientSTA->wSTADesc.wSTAType == WLAN_STA_INFRA) + { + if(0 != pClientSTA->aucACMask[WLANTL_AC_HIGH_PRIO]) + { + pClientSTA->ucCurrentAC = WLANTL_AC_HIGH_PRIO; + pTLCb->uCurServedAC = WLANTL_AC_HIGH_PRIO; + } + else + break; + } + else + { + for (j = WLANTL_MAX_AC ; j > 0; j--) + { + if (0 != pClientSTA->aucACMask[j-1]) + { + pClientSTA->ucCurrentAC = j-1; + pTLCb->uCurServedAC = j-1; + break; + } + } + } + + wSTAEvent = WLANTL_TX_EVENT; + + pfnSTAFsm = tlSTAFsm[pClientSTA->tlState]. + pfnSTATbl[wSTAEvent]; + + if ( NULL != pfnSTAFsm ) + { + pClientSTA->ucNoMoreData = 0; + vosStatus = pfnSTAFsm( pvosGCtx, ucSTAId, &vosTempBuf, VOS_FALSE); + + if (( VOS_STATUS_SUCCESS != vosStatus ) && + ( NULL != vosTempBuf )) + { + pClientSTA->pfnSTATxComp( pvosGCtx, vosTempBuf, vosStatus ); + vosTempBuf = NULL; + break; + }/* status success*/ + } + + if (NULL != vosTempBuf) + { + WDA_TLI_PROCESS_FRAME_LEN( vosTempBuf, usPktLen, uResLen, uTotalPktLen); + + if (usPktLen > WLANTL_MAX_ALLOWED_LEN) + { + usPktLen = WLANTL_MAX_ALLOWED_LEN; + VOS_ASSERT(0); + } + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL:Resources needed by frame: %d", uResLen)); + + if ( ( pTLCb->uResCount >= (uResLen + WDA_TLI_MIN_RES_MF ) ) && + ( uRemaining > uTotalPktLen ) + ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Chaining data frame on GetFrame")); + + vos_pkt_chain_packet( vosDataBuff, vosTempBuf, 1 /*true*/ ); + + /*EAPOL frame cannot be delayed*/ + pTLCb->bUrgent = TRUE; + + vosTempBuf = NULL; + + /*Update remaining len from SSC */ + uRemaining -= (usPktLen + WDA_DXE_HEADER_SIZE); + + /*Update resource count */ + pTLCb->uResCount -= uResLen; + + //fow control update + pClientSTA->uIngress_length += uResLen; + pClientSTA->uBuffThresholdMax = (pClientSTA->uBuffThresholdMax >= uResLen) ? + (pClientSTA->uBuffThresholdMax - uResLen) : 0; + pClientSTA->ucEapolPktPending = 0; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:GetFrames STA: %d EAPOLPktPending %d", + ucSTAId, pClientSTA->ucEapolPktPending); + } + } + else + { // no EAPOL frames exit Get frames + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:GetFrames STA: %d, no EAPOL frame, continue.", + ucSTAId)); + continue; + } + } + + else if (( WDA_TLI_MIN_RES_DATA <= pTLCb->uResCount ) && + ( 0 == pTLCb->ucTxSuspended ) && + ( uFlowMask & WLANTL_DATA_FLOW_MASK)) + { + /*--------------------------------------------------------------------- + Check to see if there was any packet left behind previously due to + size constraints + ---------------------------------------------------------------------*/ + vosTempBuf = NULL; + + if ( NULL != pTLCb->vosTempBuf ) + { + vosTempBuf = pTLCb->vosTempBuf; + pTLCb->vosTempBuf = NULL; + ucSTAId = pTLCb->ucCachedSTAId; + ucAC = pTLCb->ucCachedAC; + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + continue; + } + + pTLCb->atlSTAClients[ucSTAId]->ucNoMoreData = 0; + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Chaining cached data frame on GetFrame")); + } + else + { + WLAN_TLGetNextTxIds( pvosGCtx, &ucSTAId); + if (ucSTAId >= WLAN_MAX_STA_COUNT) + { + /* Packets start coming in even after insmod Without * + starting Hostapd or Interface being up * + During which cases STAID is invaled and hence + the check. HalMsg_ScnaComplete Triggers */ + + break; + } + /* ucCurrentAC should have correct AC to be served by calling + WLAN_TLGetNextTxIds */ + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + continue; + } + + ucAC = pClientSTA->ucCurrentAC; + + pClientSTA->ucNoMoreData = 1; + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL: %s get one data frame, station ID %d ", __func__, ucSTAId)); + /*------------------------------------------------------------------- + Check to see that STA is valid and tx is not suspended + -------------------------------------------------------------------*/ + if ( ( ! WLANTL_STA_ID_INVALID( ucSTAId ) ) && + ( 0 == pClientSTA->ucTxSuspended ) && + ( 0 == pClientSTA->fcStaTxDisabled) ) + { + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL: %s sta id valid and not suspended ",__func__)); + wSTAEvent = WLANTL_TX_EVENT; + + pfnSTAFsm = tlSTAFsm[pClientSTA->tlState]. + pfnSTATbl[wSTAEvent]; + + if ( NULL != pfnSTAFsm ) + { + pClientSTA->ucNoMoreData = 0; + vosStatus = pfnSTAFsm( pvosGCtx, ucSTAId, &vosTempBuf, VOS_FALSE); + + if (( VOS_STATUS_SUCCESS != vosStatus ) && + ( NULL != vosTempBuf )) + { + pClientSTA->pfnSTATxComp( pvosGCtx, + vosTempBuf, + vosStatus ); + vosTempBuf = NULL; + }/* status success*/ + }/*NULL function state*/ + }/* valid STA id and ! suspended*/ + else + { + if ( ! WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Not fetching frame because suspended for sta ID %d", + ucSTAId)); + } + } + }/* data */ + + if ( NULL != vosTempBuf ) + { + WDA_TLI_PROCESS_FRAME_LEN( vosTempBuf, usPktLen, uResLen, uTotalPktLen); + + if (usPktLen > WLANTL_MAX_ALLOWED_LEN) + { + usPktLen = WLANTL_MAX_ALLOWED_LEN; + VOS_ASSERT(0); + } + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL:Resources needed by frame: %d", uResLen)); + + if ( ( pTLCb->uResCount >= (uResLen + WDA_TLI_MIN_RES_BAP ) ) && + ( uRemaining > uTotalPktLen ) && + ( uFlowMask & WLANTL_DATA_FLOW_MASK ) ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Chaining data frame on GetFrame")); + + vos_pkt_chain_packet( vosDataBuff, vosTempBuf, 1 /*true*/ ); + vosTempBuf = NULL; + + /*Update remaining len from SSC */ + uRemaining -= (usPktLen + WDA_DXE_HEADER_SIZE); + + /*Update resource count */ + pTLCb->uResCount -= uResLen; + + //fow control update + pClientSTA->uIngress_length += uResLen; + pClientSTA->uBuffThresholdMax = (pClientSTA->uBuffThresholdMax >= uResLen) ? + (pClientSTA->uBuffThresholdMax - uResLen) : 0; + + pClientSTA->tx_frames ++; + + } + else + { + /* Store this for later tx - already fetched from HDD */ + pTLCb->vosTempBuf = vosTempBuf; + pTLCb->ucCachedSTAId = ucSTAId; + pTLCb->ucCachedAC = ucAC; + ucResult = uResLen + WDA_TLI_MIN_RES_BAP; + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "min %d res required by TL.", ucResult )); + break; /* Out of resources or reached max len */ + } + } + else + { + for ( i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if (NULL != pTLCb->atlSTAClients[i] && (pTLCb->atlSTAClients[i]->ucExists) && + (pTLCb->atlSTAClients[i]->ucPktPending) && + (pTLCb->atlSTAClients[i]->disassoc_progress == VOS_FALSE)) + { + /* There is station to be Served */ + break; + } + } + if (i >= WLAN_MAX_STA_COUNT) + { + /* No More to Serve Exit Get Frames */ + break; + } + else + { + /* More to be Served */ + continue; + } + } + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Returning from GetFrame: resources = %d suspended = %d", + pTLCb->uResCount, pTLCb->ucTxSuspended)); + /* TL is starving even when DXE is not in low resource condition + Return min resource number required and Let DXE deceide what to do */ + if(( 0 == pTLCb->ucTxSuspended ) && + ( uFlowMask & WLANTL_DATA_FLOW_MASK ) ) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:Returning from GetFrame: resources = %d", + pTLCb->uResCount)); + ucResult = WDA_TLI_MIN_RES_DATA; + } + break; /*out of min data resources*/ + } + + pTLCb->usPendingTxCompleteCount++; + /* Move data buffer up one packet */ + vos_pkt_walk_packet_chain( vosDataBuff, &vosDataBuff, 0/*false*/ ); + } + + /*---------------------------------------------------------------------- + Packet chain starts at root + 1 + ----------------------------------------------------------------------*/ + vos_pkt_walk_packet_chain( vosRoot, &vosDataBuff, 1/*true*/ ); + + *pvosDataBuff = vosDataBuff; + if (pbUrgent) + { + *pbUrgent = pTLCb->bUrgent; + } + else + { + VOS_ASSERT( pbUrgent ); + } + return ucResult; +}/* WLANTL_GetFrames */ + + +/*========================================================================== + + FUNCTION WLANTL_TxComp + + DESCRIPTION + It is being called by BAL upon asynchronous notification of the packet + or packets being sent over the bus. + + DEPENDENCIES + Tx complete cannot be called without a previous transmit. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAL's control block can be extracted from its context + vosDataBuff: it will contain a pointer to the first buffer for which + the BAL report is being made, if there is more then one + packet they will be chained using vOSS buffers. + wTxStatus: the status of the transmitted packet, see above chapter + on HDD interaction for a list of possible values + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxComp +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pFrameDataBuff, + VOS_STATUS wTxStatus +) +{ + vos_pkt_t* vosDataBuff = (vos_pkt_t*)pFrameDataBuff; + WLANTL_CbType* pTLCb = NULL; + WLANTL_TxCompCBType pfnTxComp = NULL; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_pkt_t* vosTempTx = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == vosDataBuff ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Extraneous NULL data pointer on WLANTL_TxComp")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_TxComp")); + return VOS_STATUS_E_FAULT; + } + + while ((0 < pTLCb->usPendingTxCompleteCount) && + ( VOS_STATUS_SUCCESS == vosStatus ) && + ( NULL != vosDataBuff)) + { + vos_pkt_get_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)&pfnTxComp); + + /*it should never be NULL - default handler should be registered if none*/ + if ( NULL == pfnTxComp ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:NULL pointer to Tx Complete on WLANTL_TxComp")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Calling Tx complete for pkt %p in function %p", + vosDataBuff, pfnTxComp)); + + vosTempTx = vosDataBuff; + vosStatus = vos_pkt_walk_packet_chain( vosDataBuff, + &vosDataBuff, 1/*true*/); + + pfnTxComp( pvosGCtx, vosTempTx, wTxStatus ); + + pTLCb->usPendingTxCompleteCount--; + } + + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: current TL values are: resources = %d " + "pTLCb->usPendingTxCompleteCount = %d", + pTLCb->uResCount, pTLCb->usPendingTxCompleteCount)); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_TxComp */ + +/*========================================================================== + + FUNCTION WLANTL_CacheSTAFrame + + DESCRIPTION + Internal utility function for for caching incoming data frames that do + not have a registered station yet. + + DEPENDENCIES + TL must be initiailized before this function gets called. + In order to benefit from thsi caching, the components must ensure that + they will only register with TL at the moment when they are fully setup + and ready to receive incoming data + + PARAMETERS + + IN + + pTLCb: TL control block + ucSTAId: station id + vosTempBuff: the data packet + uDPUSig: DPU signature of the incoming packet + bBcast: true if packet had the MC/BC bit set + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL or STA Id invalid ; access + would cause a page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +static VOS_STATUS +WLANTL_CacheSTAFrame +( + WLANTL_CbType* pTLCb, + v_U8_t ucSTAId, + vos_pkt_t* vosTempBuff, + v_U32_t uDPUSig, + v_U8_t bBcast, + v_U8_t ucFrmType +) +{ + v_U8_t ucUcastSig; + v_U8_t ucBcastSig; + v_BOOL_t bOldSTAPkt; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pTLCb ) || ( NULL == vosTempBuff ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Invalid input pointer on WLANTL_CacheSTAFrame TL %p" + " Packet %p", pTLCb, vosTempBuff )); + return VOS_STATUS_E_FAULT; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_CacheSTAFrame")); + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Attempting to cache pkt for STA %d, BD DPU Sig: %d with sig UC: %d, BC: %d", + ucSTAId, uDPUSig, + pClientSTA->wSTADesc.ucUcastSig, + pClientSTA->wSTADesc.ucBcastSig)); + + if(WLANTL_IS_CTRL_FRAME(ucFrmType)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: No need to cache CTRL frame. Dropping")); + vos_pkt_return_packet(vosTempBuff); + return VOS_STATUS_SUCCESS; + } + + /*------------------------------------------------------------------------- + Check if the packet that we are trying to cache belongs to the old + registered station (if any) or the new (potentially)upcoming station + + - If the STA with this Id was never registered with TL - the signature + will be invalid; + - If the STA was previously registered TL will have cached the former + set of DPU signatures + -------------------------------------------------------------------------*/ + if ( bBcast ) + { + ucBcastSig = (v_U8_t)uDPUSig; + bOldSTAPkt = (( WLAN_TL_INVALID_B_SIG != + pClientSTA->wSTADesc.ucBcastSig ) && + ( ucBcastSig == pClientSTA->wSTADesc.ucBcastSig )); + } + else + { + ucUcastSig = (v_U8_t)uDPUSig; + bOldSTAPkt = (( WLAN_TL_INVALID_U_SIG != + pClientSTA->wSTADesc.ucUcastSig ) && + ( ucUcastSig == pClientSTA->wSTADesc.ucUcastSig )); + } + + /*------------------------------------------------------------------------ + If the value of the DPU SIG matches the old, this packet will not + be cached as it belonged to the former association + In case the SIG does not match - this is a packet for a potentially new + associated station + -------------------------------------------------------------------------*/ + if ( bOldSTAPkt || bBcast ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Data packet matches old sig for sig DPU: %d UC: %d, " + "BC: %d - dropping", + uDPUSig, + pClientSTA->wSTADesc.ucUcastSig, + pClientSTA->wSTADesc.ucBcastSig)); + vos_pkt_return_packet(vosTempBuff); + } + else + { + if ( NULL == pClientSTA->vosBegCachedFrame ) + { + /*this is the first frame that we are caching */ + pClientSTA->vosBegCachedFrame = vosTempBuff; + + pClientSTA->tlCacheInfo.cacheInitTime = vos_timer_get_system_time(); + pClientSTA->tlCacheInfo.cacheDoneTime = + pClientSTA->tlCacheInfo.cacheInitTime; + pClientSTA->tlCacheInfo.cacheSize = 1; + + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_CACHE_FRAME, + ucSTAId, pClientSTA->tlCacheInfo.cacheSize)); + + } + else + { + /*this is a subsequent frame that we are caching: chain to the end */ + vos_pkt_chain_packet(pClientSTA->vosEndCachedFrame, + vosTempBuff, VOS_TRUE); + + pClientSTA->tlCacheInfo.cacheDoneTime = vos_timer_get_system_time(); + pClientSTA->tlCacheInfo.cacheSize ++; + + if (pClientSTA->tlCacheInfo.cacheSize % WLANTL_CACHE_TRACE_WATERMARK == 0) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Cache High watermark for staid:%d (%d)", + __func__,ucSTAId, pClientSTA->tlCacheInfo.cacheSize); + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_CACHE_FRAME, + ucSTAId, pClientSTA->tlCacheInfo.cacheSize)); + } + } + pClientSTA->vosEndCachedFrame = vosTempBuff; + }/*else new packet*/ + + return VOS_STATUS_SUCCESS; +}/*WLANTL_CacheSTAFrame*/ + +/*========================================================================== + + FUNCTION WLANTL_FlushCachedFrames + + DESCRIPTION + Internal utility function used by TL to flush the station cache + + DEPENDENCIES + TL must be initiailized before this function gets called. + + PARAMETERS + + IN + + vosDataBuff: it will contain a pointer to the first cached buffer + received, + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + + NOTE + This function doesn't re-initialize vosDataBuff to NULL. It's caller's + responsibility to do so, if required, after this function call. + Because of this restriction, we decide to make this function to static + so that upper layer doesn't need to be aware of this restriction. + +============================================================================*/ +static VOS_STATUS +WLANTL_FlushCachedFrames +( + vos_pkt_t* vosDataBuff +) +{ + /*---------------------------------------------------------------------- + Return the entire chain to vos if there are indeed cache frames + ----------------------------------------------------------------------*/ + if ( NULL != vosDataBuff ) + { + vos_pkt_return_packet(vosDataBuff); + } + + return VOS_STATUS_SUCCESS; +}/*WLANTL_FlushCachedFrames*/ + +/*========================================================================== + + FUNCTION WLANTL_ForwardSTAFrames + + DESCRIPTION + Internal utility function for either forwarding cached data to the station after + the station has been registered, or flushing cached data if the station has not + been registered. + + + DEPENDENCIES + TL must be initiailized before this function gets called. + + PARAMETERS + + IN + + pTLCb: TL control block + ucSTAId: station id + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + This function doesn't re-initialize vosDataBuff to NULL. It's caller's + responsibility to do so, if required, after this function call. + Because of this restriction, we decide to make this function to static + so that upper layer doesn't need to be aware of this restriction. + +============================================================================*/ +static VOS_STATUS +WLANTL_ForwardSTAFrames +( + void* pvosGCtx, + v_U8_t ucSTAId, + v_U8_t ucUcastSig, + v_U8_t ucBcastSig +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Invalid input pointer on WLANTL_ForwardSTAFrames TL %p", + pTLCb )); + return VOS_STATUS_E_FAULT; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_ForwardSTAFrames")); + return VOS_STATUS_E_FAULT; + } + + //WLAN_TL_LOCK_STA_CACHE(pTLCb->atlSTAClients[ucSTAId]); + + /*------------------------------------------------------------------------ + Check if station has not been registered in the mean while + if not registered, flush cached frames. + ------------------------------------------------------------------------*/ + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Station has been deleted for STA %d - flushing cache", ucSTAId)); + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_FLUSH_CACHED_FRAMES, + ucSTAId, pClientSTA->tlCacheInfo.cacheSize)); + WLANTL_FlushCachedFrames(pClientSTA->vosBegCachedFrame); + goto done; + } + + /*------------------------------------------------------------------------ + Forwarding cache frames received while the station was in the process + of being registered with the rest of the SW components + + Access to the cache must be locked; similarly updating the signature and + the existence flag must be synchronized because these values are checked + during cached + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Preparing to fwd packets for STA %d", ucSTAId)); + + /*----------------------------------------------------------------------- + Save the new signature values + ------------------------------------------------------------------------*/ + pClientSTA->wSTADesc.ucUcastSig = ucUcastSig; + pClientSTA->wSTADesc.ucBcastSig = ucBcastSig; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Fwd-ing packets for STA %d UC %d BC %d", + ucSTAId, ucUcastSig, ucBcastSig)); + + /*------------------------------------------------------------------------- + Check to see if we have any cached data to forward + -------------------------------------------------------------------------*/ + if ( NULL != pClientSTA->vosBegCachedFrame ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Fwd-ing Cached packets for station %d", ucSTAId )); + + WLANTL_RxCachedFrames( pTLCb, + ucSTAId, + pClientSTA->vosBegCachedFrame); + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: NO cached packets for station %d", ucSTAId )); + } + +done: + /*------------------------------------------------------------------------- + Clear the station cache + -------------------------------------------------------------------------*/ + pClientSTA->vosBegCachedFrame = NULL; + pClientSTA->vosEndCachedFrame = NULL; + pClientSTA->tlCacheInfo.cacheSize = 0; + pClientSTA->tlCacheInfo.cacheClearTime = vos_timer_get_system_time(); + + /*----------------------------------------------------------------------- + After all the init is complete we can mark the existance flag + ----------------------------------------------------------------------*/ + pClientSTA->enableCaching = 0; + + //WLAN_TL_UNLOCK_STA_CACHE(pTLCb->atlSTAClients[ucSTAId]); + return VOS_STATUS_SUCCESS; + +}/*WLANTL_ForwardSTAFrames*/ + + +#if defined(FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_ESE_UPLOAD) +/*========================================================================== + + FUNCTION WLANTL_IsIAPPFrame + + DESCRIPTION + Internal utility function for detecting incoming ESE IAPP frames + + DEPENDENCIES + + PARAMETERS + + IN + + pvBDHeader: pointer to the BD header + vosTempBuff: the data packet + + IN/OUT + pFirstDataPktArrived: static from caller function; used for rssi + computation + RETURN VALUE + The result code associated with performing the operation + + VOS_TRUE: It is a IAPP frame + VOS_FALSE: It is NOT IAPP frame + + SIDE EFFECTS + +============================================================================*/ +v_BOOL_t +WLANTL_IsIAPPFrame +( + v_PVOID_t pvBDHeader, + vos_pkt_t* vosTempBuff +) +{ + v_U16_t usMPDUDOffset; + v_U8_t ucOffset; + v_U8_t ucSnapHdr[WLANTL_LLC_SNAP_SIZE]; + v_SIZE_t usSnapHdrSize = WLANTL_LLC_SNAP_SIZE; + VOS_STATUS vosStatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Check if OUI field is present. + -------------------------------------------------------------------------*/ + if ( VOS_FALSE == WDA_IS_RX_LLC_PRESENT(pvBDHeader) ) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:LLC header removed, cannot determine BT-AMP type -" + "dropping pkt")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + return VOS_TRUE; + } + usMPDUDOffset = (v_U8_t)WDA_GET_RX_MPDU_DATA_OFFSET(pvBDHeader); + ucOffset = (v_U8_t)usMPDUDOffset + WLANTL_LLC_SNAP_OFFSET; + + vosStatus = vos_pkt_extract_data( vosTempBuff, ucOffset, + (v_PVOID_t)ucSnapHdr, &usSnapHdrSize); + + if (( VOS_STATUS_SUCCESS != vosStatus)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "Unable to extract Snap Hdr of data packet -" + "dropping pkt")); + return VOS_FALSE; + } + + /*------------------------------------------------------------------------ + Check if this is IAPP frame by matching Aironet Snap hdr. + -------------------------------------------------------------------------*/ + // Compare returns 1 if values are same and 0 + // if not the same. + if (( WLANTL_LLC_SNAP_SIZE != usSnapHdrSize ) || + ( 0 == vos_mem_compare(ucSnapHdr, (v_PVOID_t)WLANTL_AIRONET_SNAP_HEADER, + WLANTL_LLC_SNAP_SIZE ) )) + { + return VOS_FALSE; + } + + return VOS_TRUE; + +} +#endif //FEATURE_WLAN_ESE + +/*========================================================================== + + FUNCTION WLANTL_ProcessBAPFrame + + DESCRIPTION + Internal utility function for processing incoming BT-AMP frames + + DEPENDENCIES + TL must be initiailized before this function gets called. + Bothe the BT-AMP station and the BAP Ctrl path must have been previously + registered with TL. + + PARAMETERS + + IN + + pvBDHeader: pointer to the BD header + vosTempBuff: the data packet + pTLCb: TL control block + ucSTAId: station id + + IN/OUT + pFirstDataPktArrived: static from caller function; used for rssi + computation + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +v_BOOL_t +WLANTL_ProcessBAPFrame +( + v_PVOID_t pvBDHeader, + vos_pkt_t* vosTempBuff, + WLANTL_CbType* pTLCb, + v_U8_t* pFirstDataPktArrived, + v_U8_t ucSTAId +) +{ + v_U16_t usMPDUDOffset; + v_U8_t ucOffset; + v_U8_t ucOUI[WLANTL_LLC_OUI_SIZE]; + v_SIZE_t usOUISize = WLANTL_LLC_OUI_SIZE; + VOS_STATUS vosStatus; + v_U16_t usType; + v_SIZE_t usTypeLen = sizeof(usType); + v_U8_t ucMPDUHOffset; + v_U8_t ucMPDUHLen = 0; + v_U16_t usActualHLen = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Extract OUI and type from LLC and validate; if non-data send to BAP + -------------------------------------------------------------------------*/ + if ( VOS_FALSE == WDA_IS_RX_LLC_PRESENT(pvBDHeader) ) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:LLC header removed, cannot determine BT-AMP type -" + "dropping pkt")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + return VOS_TRUE; + } + + usMPDUDOffset = (v_U8_t)WDA_GET_RX_MPDU_DATA_OFFSET(pvBDHeader); + ucMPDUHOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(pvBDHeader); + ucMPDUHLen = (v_U8_t)WDA_GET_RX_MPDU_HEADER_LEN(pvBDHeader); + ucOffset = (v_U8_t)usMPDUDOffset + WLANTL_LLC_OUI_OFFSET; + + vosStatus = vos_pkt_extract_data( vosTempBuff, ucOffset, + (v_PVOID_t)ucOUI, &usOUISize); + +#if 0 + // Compare returns 1 if values are same and 0 + // if not the same. + if (( WLANTL_LLC_OUI_SIZE != usOUISize ) || + ( 0 == vos_mem_compare(ucOUI, (v_PVOID_t)WLANTL_BT_AMP_OUI, + WLANTL_LLC_OUI_SIZE ) )) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "LLC header points to diff OUI in BT-AMP station -" + "dropping pkt")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + return VOS_TRUE; + } +#endif + /*------------------------------------------------------------------------ + Extract LLC OUI and ensure that this is indeed a BT-AMP frame + ------------------------------------------------------------------------*/ + vosStatus = vos_pkt_extract_data( vosTempBuff, + ucOffset + WLANTL_LLC_OUI_SIZE, + (v_PVOID_t)&usType, &usTypeLen); + + if (( VOS_STATUS_SUCCESS != vosStatus) || + ( sizeof(usType) != usTypeLen )) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "Unable to extract type on incoming BAP packet -" + "dropping pkt")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + return VOS_TRUE; + } + + /*------------------------------------------------------------------------ + Check if this is BT-AMP data or ctrl packet(RSN, LinkSvision, ActivityR) + ------------------------------------------------------------------------*/ + usType = vos_be16_to_cpu(usType); + + if (WLANTL_BAP_IS_NON_DATA_PKT_TYPE(usType)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Non-data packet received over BT-AMP link: %d, => BAP", + usType)); + + /*Flatten packet as BAP expects to be able to peek*/ + if ( VOS_STATUS_SUCCESS != vos_pkt_flatten_rx_pkt(&vosTempBuff)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Cannot flatten BT-AMP packet - dropping")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + return VOS_TRUE; + } + + /* Send packet to BAP client*/ + if ( VOS_STATUS_SUCCESS != WDA_DS_TrimRxPacketInfo( vosTempBuff ) ) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:BD header corrupted - dropping packet")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + return VOS_TRUE; + } + + if ( 0 == WDA_GET_RX_FT_DONE(pvBDHeader) ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Non-data packet received over BT-AMP link: Sending it for " + "frame Translation")); + + if (usMPDUDOffset > ucMPDUHOffset) + { + usActualHLen = usMPDUDOffset - ucMPDUHOffset; + } + + /* software frame translation for BTAMP WDS.*/ + WLANTL_Translate80211To8023Header( vosTempBuff, &vosStatus, usActualHLen, + ucMPDUHLen, pTLCb,ucSTAId, VOS_FALSE); + + } + if (pTLCb->tlBAPClient.pfnTlBAPRx) + pTLCb->tlBAPClient.pfnTlBAPRx( vos_get_global_context(VOS_MODULE_ID_TL,pTLCb), + vosTempBuff, + (WLANTL_BAPFrameEnumType)usType ); + else + { + VOS_ASSERT(0); + } + + return VOS_TRUE; + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: BAP DATA packet received over BT-AMP link: %d, => BAP", + usType)); + /*!!!FIX ME!!*/ + #if 0 + /*-------------------------------------------------------------------- + For data packet collect phy stats RSSI and Link Quality + Calculate the RSSI average and save it. Continuous average is done. + --------------------------------------------------------------------*/ + if ( *pFirstDataPktArrived == 0) + { + pTLCb->atlSTAClients[ucSTAId].rssiAvg = + WLANHAL_GET_RSSI_AVERAGE( pvBDHeader ); + pTLCb->atlSTAClients[ucSTAId].uLinkQualityAvg = + WLANHAL_RX_BD_GET_SNR( pvBDHeader ); + + // Rcvd 1st pkt, start average from next time + *pFirstDataPktArrived = 1; + } + else + { + pTLCb->atlSTAClients[ucSTAId].rssiAvg = + (WLANHAL_GET_RSSI_AVERAGE( pvBDHeader ) + + pTLCb->atlSTAClients[ucSTAId].rssiAvg)/2; + pTLCb->atlSTAClients[ucSTAId].uLinkQualityAvg = + (WLANHAL_RX_BD_GET_SNR( pvBDHeader ) + + pTLCb->atlSTAClients[ucSTAId].uLinkQualityAvg)/2; + }/*Else, first data packet*/ + #endif + }/*BT-AMP data packet*/ + + return VOS_FALSE; +}/*WLANTL_ProcessBAPFrame*/ + + +/*========================================================================== + + FUNCTION WLANTL_ProcessFCFrame + + DESCRIPTION + Internal utility function for processing incoming Flow Control frames. Enable + or disable LWM mode based on the information. + + DEPENDENCIES + TL must be initiailized before this function gets called. + FW sends up special flow control frame. + + PARAMETERS + + IN + pvosGCtx pointer to vos global context + pvBDHeader: pointer to the BD header + pTLCb: TL control block + pvBDHeader pointer to BD header. + + IN/OUT + pFirstDataPktArrived: static from caller function; used for rssi + computation + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input frame are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + The ingress and egress of each station will be updated. If needed, LWM mode will + be enabled or disabled based on the flow control algorithm. + +============================================================================*/ +v_BOOL_t +WLANTL_ProcessFCFrame +( + v_PVOID_t pvosGCtx, + vos_pkt_t* pvosDataBuff, + v_PVOID_t pvBDHeader +) +{ +#if 1 //enable processing of only fcStaTxDisabled bitmap for now. the else part is old better qos code. + // need to revisit the old code for full implementation. + v_U8_t ucSTAId; + v_U16_t ucStaValidBitmap; + v_U16_t ucStaTxDisabledBitmap; + WLANTL_CbType* pTLCb = NULL; + #ifdef TL_DEBUG_FC + v_U32_t rxTimeStamp; + v_U32_t curTick; + #endif + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_SuspendDataTx")); + return VOS_STATUS_E_FAULT; + } + ucStaValidBitmap = WDA_GET_RX_FC_VALID_STA_MASK(pvBDHeader); + ucStaTxDisabledBitmap = WDA_GET_RX_FC_STA_TX_DISABLED_BITMAP(pvBDHeader); +#ifdef TL_DEBUG_FC + rxTimeStamp = WDA_GET_RX_TIMESTAMP(pvBDHeader); + /* hard code of MTU_GLOBAL_TIMER_ADDR to calculate the time between generated and processed */ + wpalReadRegister(0x03081400+0x1D4, &curTick); + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%ld (%ld-%ld): Disabled %x Valid %x", curTick > rxTimeStamp ? curTick - rxTimeStamp : rxTimeStamp - (0xFFFFFFFF - curTick), + curTick, rxTimeStamp, ucStaTxDisabledBitmap, ucStaValidBitmap)); +#endif + for(ucSTAId = 0; ucStaValidBitmap != 0; ucStaValidBitmap >>=1, ucStaTxDisabledBitmap >>= 1, ucSTAId ++) + { + if ( (0 == (ucStaValidBitmap & 0x1)) || (pTLCb->atlSTAClients[ucSTAId] && (0 == pTLCb->atlSTAClients[ucSTAId]->ucExists)) ) + continue; + + if (ucStaTxDisabledBitmap & 0x1) + { + WLANTL_SuspendDataTx(pvosGCtx, &ucSTAId, NULL); + } + else + { + WLANTL_ResumeDataTx(pvosGCtx, &ucSTAId); + } + } + +#else + VOS_STATUS vosStatus; + tpHalFcRxBd pvFcRxBd = NULL; + v_U8_t ucBitCheck = 0x1; + v_U8_t ucStaValid = 0; + v_U8_t ucSTAId = 0; + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "Received FC Response"); + if ( (NULL == pTLCb) || (NULL == pvosDataBuff)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid pointer in %s", __func__)); + return VOS_STATUS_E_FAULT; + } + vosStatus = vos_pkt_peek_data( pvosDataBuff, 0, (v_PVOID_t)&pvFcRxBd, + sizeof(tHalFcRxBd)); + + if ( (VOS_STATUS_SUCCESS != vosStatus) || (NULL == pvFcRxBd) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:wrong FC Rx packet")); + return VOS_STATUS_E_INVAL; + } + + // need to swap bytes in the FC contents. + WLANHAL_SwapFcRxBd(&pvFcRxBd->fcSTATxQLen[0]); + + //logic to enable/disable LWM mode for each station + for( ucStaValid = (v_U8_t)pvFcRxBd->fcSTAValidMask; ucStaValid; ucStaValid >>= 1, ucBitCheck <<= 1, ucSTAId ++) + { + if ( (0 == (ucStaValid & 0x1)) || (0 == pTLCb->atlSTAClients[ucSTAId].ucExists) ) + { + continue; + } + + if ( pvFcRxBd->fcSTAThreshIndMask & ucBitCheck ) + { + //LWM event is reported by FW. Able to fetch more packet + if( pTLCb->atlSTAClients[ucSTAId].ucLwmModeEnabled ) + { + //Now memory usage is below LWM. Station can send more packets. + pTLCb->atlSTAClients[ucSTAId].ucLwmEventReported = TRUE; + } + else + { + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL: FW report LWM event but the station %d is not in LWM mode", ucSTAId)); + } + } + + //calculate uEgress_length/uIngress_length only after receiving enough packets + if (WLANTL_LWM_INGRESS_SAMPLE_THRESHOLD <= pTLCb->atlSTAClients[ucSTAId].uIngress_length) + { + //check memory usage info to see whether LWM mode should be enabled for the station + v_U32_t uEgress_length = pTLCb->atlSTAClients[ucSTAId].uIngress_length + + pTLCb->atlSTAClients[ucSTAId].bmuMemConsumed - pvFcRxBd->fcSTATxQLen[ucSTAId]; + + //if ((float)uEgress_length/(float)pTLCb->atlSTAClients[ucSTAId].uIngress_length + // <= WLANTL_LWM_EGRESS_INGRESS_THRESHOLD) + if ( (pTLCb->atlSTAClients[ucSTAId].uIngress_length > uEgress_length) && + ((pTLCb->atlSTAClients[ucSTAId].uIngress_length - uEgress_length ) >= + (pTLCb->atlSTAClients[ucSTAId].uIngress_length >> 2)) + ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Enable LWM mode for station %d", ucSTAId)); + pTLCb->atlSTAClients[ucSTAId].ucLwmModeEnabled = TRUE; + } + else + { + if( pTLCb->atlSTAClients[ucSTAId].ucLwmModeEnabled ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Disable LWM mode for station %d", ucSTAId)); + pTLCb->atlSTAClients[ucSTAId].ucLwmModeEnabled = FALSE; + } + + } + + //remember memory usage in FW starting from this round + pTLCb->atlSTAClients[ucSTAId].bmuMemConsumed = pvFcRxBd->fcSTATxQLen[ucSTAId]; + pTLCb->atlSTAClients[ucSTAId].uIngress_length = 0; + } //(WLANTL_LWM_INGRESS_SAMPLE_THRESHOLD <= pTLCb->atlSTAClients[ucSTAId].uIngress_length) + + if( pTLCb->atlSTAClients[ucSTAId].ucLwmModeEnabled ) + { + //always update current maximum allowed memeory usage + pTLCb->atlSTAClients[ucSTAId].uBuffThresholdMax = WLANTL_STA_BMU_THRESHOLD_MAX - + pvFcRxBd->fcSTATxQLen[ucSTAId]; + } + + } +#endif + + return VOS_STATUS_SUCCESS; +} + +/** + * WLANTL_FlowControl() - TX Flow control + * @pTLCb: TL context pointer + * @pvosDataBuff: Firmware indication data buffer + * + * This function implenets the algorithm to flow control TX traffic in case + * of SAP and SAP + STA concurrency. + * + * Algorithm goal is to fetch more packets from good peer than bad peer by + * introducing weights for each station connected. Weight of each station is + * calcutated by taking ratio of max RA rate of the peers to its rate. If the + * ratio is less than two based on number of queued frames in the station BTQM + * weight is modified. If the queued frames reaches the defined threshold weight + * is assigned as four. Here weight is inversely proportional to the number of + * packets fetch. + * + * Return true if flow controlled or false otherwise. + */ +static bool WLANTL_FlowControl(WLANTL_CbType* pTLCb, vos_pkt_t* pvosDataBuff) +{ + WLANTL_FlowControlInfo *fc_data = NULL; + WLANTL_PerStaFlowControlParam *sta_fc_params = NULL; + uint8_t num_stas; + struct sk_buff *skb = NULL; + uint16_t data_len; + uint8_t *staid; + uint16_t max_rate = 0; + uint8_t i; + + vos_pkt_get_packet_length(pvosDataBuff, &data_len); + if (!data_len) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Null fw indication data", __func__)); + return false; + } + + vos_pkt_get_os_packet(pvosDataBuff, (v_VOID_t **)&skb, 0); + fc_data = (WLANTL_FlowControlInfo *)skb->data; + num_stas = fc_data->num_stas; + if (!num_stas) { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s: No connected stations", __func__)); + return true; + } + + /* Skip flow control for one connected station */ + if (1 == num_stas) + return true; + + staid = (uint8_t *)vos_mem_malloc(WLAN_MAX_STA_COUNT); + if (!staid) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: mem allocation failure", __func__)); + return false; + } + vos_mem_set((uint8_t *)staid, WLAN_MAX_STA_COUNT, 0); + + sta_fc_params = (WLANTL_PerStaFlowControlParam *)(&fc_data->num_stas + 1); + + for(i = 0; i < num_stas; i ++, sta_fc_params ++) { + staid[i] = sta_fc_params->sta_id; + + if (!pTLCb->atlSTAClients[staid[i]]) + continue; + + pTLCb->atlSTAClients[staid[i]]->per = sta_fc_params->avg_per; + pTLCb->atlSTAClients[staid[i]]->queue = sta_fc_params->queue_len; + pTLCb->atlSTAClients[staid[i]]->trate = sta_fc_params->rate; + max_rate = max_rate > pTLCb->atlSTAClients[staid[i]]->trate ? + max_rate : pTLCb->atlSTAClients[staid[i]]->trate; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: sta_id:%d in:%d queue:%d avg_per:%d rate:%d", __func__, + staid[i], pTLCb->atlSTAClients[staid[i]]->tx_samples_sum, + pTLCb->atlSTAClients[staid[i]]->queue, + pTLCb->atlSTAClients[staid[i]]->per, + pTLCb->atlSTAClients[staid[i]]->trate)); + } + + for (i = 0; i < num_stas; i++) { + pTLCb->atlSTAClients[staid[i]]->weight = + max_rate/pTLCb->atlSTAClients[staid[i]]->trate; + if (pTLCb->atlSTAClients[staid[i]]->weight >= + WLANTL_RATE_RATIO_THRESHOLD) { + if (!pTLCb->atlSTAClients[staid[i]]->set_flag) { + vos_set_hdd_bad_sta(staid[i]); + pTLCb->atlSTAClients[staid[i]]->set_flag = true; + } + /** + * If station's link becomes very bad rssi below -90dbm then because + * of high PER rate high number of packets are stuck in BTQM which is + * affecting the good peers throughput. So throttle further the bad + * link traffic. + */ + if ((pTLCb->atlSTAClients[staid[i]]->weight > + WLANTL_WEIGHT_THRESHOLD) && + (pTLCb->atlSTAClients[staid[i]]->queue > + WLANTL_QUEUE_THRESHOLD)) + pTLCb->atlSTAClients[staid[i]]->weight *= 2; + } + if (pTLCb->atlSTAClients[staid[i]]->weight < + WLANTL_RATE_RATIO_THRESHOLD) { + if (pTLCb->atlSTAClients[staid[i]]->per >= WLANTL_PER_THRESHOLD && + pTLCb->atlSTAClients[staid[i]]->queue > WLANTL_QUEUE_THRESHOLD + && !pTLCb->atlSTAClients[staid[i]]->set_flag) { + pTLCb->atlSTAClients[staid[i]]->weight *= 2; + vos_set_hdd_bad_sta(staid[i]); + pTLCb->atlSTAClients[staid[i]]->set_flag = true; + } + else if (pTLCb->atlSTAClients[staid[i]]->set_flag) { + vos_reset_hdd_bad_sta(staid[i]); + pTLCb->atlSTAClients[staid[i]]->set_flag = false; + } + } + } + vos_mem_free(staid); + return true; +} + +/** + * WLANTL_CacheEapol() - cache eapol frames + * @pTLCb : pointer to TL context + * @vosTempBuff: pointer to vos packet buff + * + * Return: None + * + */ +static void WLANTL_CacheEapol(WLANTL_CbType* pTLCb, vos_pkt_t* vosTempBuff) +{ + if ((NULL == pTLCb) || (NULL == vosTempBuff)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid input pointer", __func__)); + return; + } + + if (NULL == pTLCb->vosEapolCachedFrame) { + TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s: Cache Eapol frame", __func__)); + pTLCb->vosEapolCachedFrame = vosTempBuff; + } + else { + TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s: Drop duplicate EAPOL frame", __func__)); + vos_pkt_return_packet(vosTempBuff); + } +} + +/*========================================================================== + + FUNCTION WLANTL_RxFrames + + DESCRIPTION + Callback registered by TL and called by BAL when a packet is received + over the bus. Upon the call of this function TL will make the necessary + decision with regards to the forwarding or queuing of this packet and + the layer it needs to be delivered to. + + DEPENDENCIES + TL must be initiailized before this function gets called. + If the frame carried is a data frame then the station for which it is + destined to must have been previously registered with TL. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAL's control block can be extracted from its context + + vosDataBuff: it will contain a pointer to the first buffer received, + if there is more then one packet they will be chained + using vOSS buffers. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RxFrames +( + v_PVOID_t pvosGCtx, + vos_pkt_t *pFrameDataBuff +) +{ + vos_pkt_t* vosDataBuff = (vos_pkt_t*)pFrameDataBuff; + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + WLANTL_STAFuncType pfnSTAFsm; + vos_pkt_t* vosTempBuff; + v_U8_t ucSTAId; + VOS_STATUS vosStatus; + v_U8_t ucFrmType; + v_PVOID_t pvBDHeader = NULL; + WLANTL_STAEventType wSTAEvent = WLANTL_RX_EVENT; + v_U8_t ucTid = 0; + v_BOOL_t broadcast = VOS_FALSE; + v_BOOL_t selfBcastLoopback = VOS_FALSE; + static v_U8_t first_data_pkt_arrived; + v_U32_t uDPUSig; + v_U16_t usPktLen; + v_BOOL_t bForwardIAPPwithLLC = VOS_FALSE; +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + v_S7_t currentAvgRSSI = 0; + v_U8_t ac; +#endif + uint8_t ucMPDUHLen; + uint16_t seq_no; + uint16_t usEtherType = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:TL Receive Frames called")); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == vosDataBuff ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_RxFrames")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Popolaute timestamp as the time when packet arrives + ---------------------------------------------------------------------- */ + vosDataBuff->timestamp = vos_timer_get_system_ticks(); + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + /*--------------------------------------------------------------------- + Save the initial buffer - this is the first received buffer + ---------------------------------------------------------------------*/ + vosTempBuff = vosDataBuff; + + while (NULL != vosDataBuff) + { + broadcast = VOS_FALSE; + selfBcastLoopback = VOS_FALSE; + + vos_pkt_walk_packet_chain( vosDataBuff, &vosDataBuff, 1/*true*/ ); + + if( vos_get_conparam() == VOS_MONITOR_MODE ) + { + if( pTLCb->isConversionReq ) + WLANTL_MonTranslate80211To8023Header(vosTempBuff, pTLCb); + + pTLCb->pfnMonRx(pvosGCtx, vosTempBuff, pTLCb->isConversionReq); + vosTempBuff = vosDataBuff; + continue; + } + + /*--------------------------------------------------------------------- + Peek at BD header - do not remove + !!! Optimize me: only part of header is needed; not entire one + ---------------------------------------------------------------------*/ + vosStatus = WDA_DS_PeekRxPacketInfo( vosTempBuff, (v_PVOID_t)&pvBDHeader, 1/*Swap BD*/ ); + + if ( NULL == pvBDHeader ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Cannot extract BD header")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + /*--------------------------------------------------------------------- + Check if FC frame reported from FW + ---------------------------------------------------------------------*/ + if(WDA_IS_RX_FC(pvBDHeader)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:receive one FC frame")); + + WLANTL_FlowControl(pTLCb, vosTempBuff); + + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + /* AMSDU HW bug fix + * After 2nd AMSDU subframe HW could not handle BD correctly + * HAL workaround is needed */ + if(WDA_GET_RX_ASF(pvBDHeader)) + { + WDA_DS_RxAmsduBdFix(pvosGCtx, pvBDHeader); + } + + /*--------------------------------------------------------------------- + Extract frame control field from 802.11 header if present + (frame translation not done) + ---------------------------------------------------------------------*/ + + vosStatus = WDA_DS_GetFrameTypeSubType( pvosGCtx, vosTempBuff, + pvBDHeader, &ucFrmType ); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Cannot extract Frame Control Field")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + vos_pkt_get_packet_length(vosTempBuff, &usPktLen); + + /*--------------------------------------------------------------------- + Check if management and send to PE + ---------------------------------------------------------------------*/ + + if ( WLANTL_IS_MGMT_FRAME(ucFrmType)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Sending packet to management client")); + if ( VOS_STATUS_SUCCESS != vos_pkt_flatten_rx_pkt(&vosTempBuff)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Cannot flatten packet - dropping")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + ucSTAId = (v_U8_t)WDA_GET_RX_STAID( pvBDHeader ); + /* Read RSSI and update */ + if(!WLANTL_STA_ID_INVALID(ucSTAId)) + { +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* Read RSSI and update */ + vosStatus = WLANTL_HSHandleRXFrame(pvosGCtx, + WLANTL_MGMT_FRAME_TYPE, + pvBDHeader, + ucSTAId, + VOS_FALSE, + NULL); +#else + vosStatus = WLANTL_ReadRSSI(pvosGCtx, pvBDHeader, ucSTAId); +#endif + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "Handle RX Management Frame fail within Handoff " + "support module")); + /* Do Not Drop packet at here + * Revisit why HO module return fail + * vos_pkt_return_packet(vosTempBuff); + * vosTempBuff = vosDataBuff; + * continue; + */ + } + vosStatus = WLANTL_ReadSNR(pvosGCtx, pvBDHeader, ucSTAId); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + FL("Failed to Read SNR"))); + } +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + if ( NULL != pClientSTA) + { + pClientSTA->interfaceStats.mgmtRx++; + } +#endif + } + + pTLCb->tlMgmtFrmClient.pfnTlMgmtFrmRx( pvosGCtx, vosTempBuff); + } + else /* Data Frame */ + { + ucSTAId = (v_U8_t)WDA_GET_RX_STAID( pvBDHeader ); + ucTid = (v_U8_t)WDA_GET_RX_TID( pvBDHeader ); + uDPUSig = WDA_GET_RX_DPUSIG(pvBDHeader); + ucMPDUHLen = (uint8_t)WDA_GET_RX_MPDU_HEADER_LEN(pvBDHeader); + seq_no = (uint16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Data packet received for STA %d", ucSTAId)); + + /*------------------------------------------------------------------ + This should be corrected when multipe sta support is added !!! + for now bcast frames will be sent to the last registered STA + ------------------------------------------------------------------*/ + if ( WDA_IS_RX_BCAST(pvBDHeader)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:TL rx Bcast frame - sending to last registered station")); + broadcast = VOS_TRUE; + /*------------------------------------------------------------------- + If Addr1 is b/mcast, but Addr3 is our own self MAC, it is a b/mcast + pkt we sent looping back to us. To be dropped if we are non BTAMP + -------------------------------------------------------------------*/ + if( WLANHAL_RX_BD_ADDR3_SELF_IDX == + (v_U8_t)WDA_GET_RX_ADDR3_IDX( pvBDHeader )) + { + selfBcastLoopback = VOS_TRUE; + } + }/*if bcast*/ + + /* Pre assoc cache eapol */ + if (pTLCb->preassoc_caching) + { + WLANTL_GetEtherType(pvBDHeader,vosTempBuff, ucMPDUHLen, &usEtherType); + if (WLANTL_LLC_8021X_TYPE != usEtherType) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s: RX Frame not EAPOL EtherType %d", + __func__, usEtherType); + vos_pkt_return_packet(vosTempBuff); + } + else + { + WLANTL_CacheEapol(pTLCb, vosTempBuff); + TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:TL preassoc_caching is enabled seq No: %d", seq_no)); + } + + vosTempBuff = vosDataBuff; + continue; + } + + if (WLANTL_STA_ID_INVALID(ucSTAId)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:STAId %d. Invalid STA ID dropping pkt", + ucSTAId)); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + if (WLANTL_TID_INVALID( ucTid)) { + /* There is a possibility AP uses wrong TID. In that case to avoid + dropping EAPOL packet in the driver use TID to zero.*/ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:Invalid Tid: %d Frame type: %d", ucTid, ucFrmType); + WDA_GET_RX_TID( pvBDHeader ) = 0; + ucTid = 0; + } + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + ac = WLANTL_TID_2_AC[ucTid]; +#endif + + /*---------------------------------------------------------------------- + No need to lock cache access because cache manipulation only happens + in the transport thread/task context + - These frames are to be forwarded to the station upon registration + which happens in the main thread context + The caching here can happen in either Tx or Rx thread depending + on the current SSC scheduling + - also we need to make sure that the frames in the cache are fwd-ed to + the station before the new incoming ones + -----------------------------------------------------------------------*/ + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + if (NULL == pClientSTA) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:STA not allocated memory. Dropping packet")); + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + +#ifdef FEATURE_WLAN_TDLS + if (( pClientSTA->ucExists ) && + (WLAN_STA_TDLS == pClientSTA->wSTADesc.wSTAType) && + (pClientSTA->ucTxSuspended)) + vos_atomic_set_U8( &pClientSTA->ucTxSuspended, 0 ); + else if ( !broadcast && (pClientSTA->ucExists == 0 ) ) + { + tpSirMacMgmtHdr pMacHeader = WDA_GET_RX_MAC_HEADER( pvBDHeader ); + + /* from the direct peer while it is not registered to TL yet */ + if ( (pMacHeader->fc.fromDS == 0) && + (pMacHeader->fc.toDS == 0) ) + { + v_U8_t ucAddr3STAId; + + ucAddr3STAId = WDA_GET_RX_ADDR3_IDX(pvBDHeader); + + if ( WLANTL_STA_ID_INVALID(ucAddr3STAId) ) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:STA ID %d invalid - dropping pkt", ucAddr3STAId)); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + if (!(pTLCb->atlSTAClients[ucAddr3STAId] && pTLCb->atlSTAClients[ucAddr3STAId]->ucExists && + (WLAN_STA_INFRA == pTLCb->atlSTAClients[ucAddr3STAId]->wSTADesc.wSTAType) && + (WLANTL_STA_AUTHENTICATED == pTLCb->atlSTAClients[ucAddr3STAId]->tlState))) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "%s: staId %d addr3Id %d tlState %d. Unkown Receiver/Transmitter Dropping packet", __func__, + ucSTAId, ucAddr3STAId, pTLCb->atlSTAClients[ucAddr3STAId]->tlState)); + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + else + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "%s: staId %d doesn't exist, but mapped to AP staId %d", __func__, + ucSTAId, ucAddr3STAId)); + ucSTAId = ucAddr3STAId; + pClientSTA = pTLCb->atlSTAClients[ucAddr3STAId]; + } + } + } +#endif + + if (( pClientSTA->enableCaching == 1 ) && + /*Dont buffer Broadcast/Multicast frames. If AP transmits bursts of Broadcast/Multicast data frames, + * libra buffers all Broadcast/Multicast packets after authentication with AP, + * So it will lead to low resource condition in Rx Data Path.*/ + ( WDA_IS_RX_BCAST(pvBDHeader) == 0 )) + { + if( WDA_IsSelfSTA(pvosGCtx,ucSTAId)) + { + //drop packet for Self STA index + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "%s: Packet dropped for Self STA with staId %d ", __func__, ucSTAId )); + + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + /* Station has not yet been registered with TL - cache the frame */ + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "%s: staId %d exist %d tlState %d cache rx frame", __func__, ucSTAId, + pClientSTA->ucExists, pClientSTA->tlState)); + WLANTL_CacheSTAFrame( pTLCb, ucSTAId, vosTempBuff, uDPUSig, broadcast, ucFrmType); + vosTempBuff = vosDataBuff; + continue; + } + +#ifdef FEATURE_WLAN_ESE_UPLOAD + if ((pClientSTA->wSTADesc.ucIsEseSta)|| broadcast) + { + /*-------------------------------------------------------------------- + Filter the IAPP frames for ESE connection; + if data it will return false and it + will be routed through the regular data path + --------------------------------------------------------------------*/ + if ( WLANTL_IsIAPPFrame(pvBDHeader, + vosTempBuff)) + { + bForwardIAPPwithLLC = VOS_TRUE; + } + } +#endif + +#if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) + if ((pClientSTA->wSTADesc.ucIsEseSta)|| broadcast) + { + /*-------------------------------------------------------------------- + Filter the IAPP frames for ESE connection; + if data it will return false and it + will be routed through the regular data path + --------------------------------------------------------------------*/ + if ( WLANTL_IsIAPPFrame(pvBDHeader, + vosTempBuff)) + { + if ( VOS_STATUS_SUCCESS != vos_pkt_flatten_rx_pkt(&vosTempBuff)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Cannot flatten packet - dropping")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + } else { + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: Received ESE IAPP Frame")); + + pTLCb->tlMgmtFrmClient.pfnTlMgmtFrmRx( pvosGCtx, vosTempBuff); + } + vosTempBuff = vosDataBuff; + continue; + } + } +#endif /* defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) */ + + if ( WLAN_STA_BT_AMP == pClientSTA->wSTADesc.wSTAType ) + { + /*-------------------------------------------------------------------- + Process the ctrl BAP frame; if data it will return false and it + will be routed through the regular data path + --------------------------------------------------------------------*/ + if ( WLANTL_ProcessBAPFrame( pvBDHeader, + vosTempBuff, + pTLCb, + &first_data_pkt_arrived, + ucSTAId)) + { + vosTempBuff = vosDataBuff; + continue; + } + }/*if BT-AMP station*/ + else if(selfBcastLoopback == VOS_TRUE) + { + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + /*--------------------------------------------------------------------- + Data packet received, send to state machine + ---------------------------------------------------------------------*/ + wSTAEvent = WLANTL_RX_EVENT; + + pfnSTAFsm = tlSTAFsm[pClientSTA->tlState]. + pfnSTATbl[wSTAEvent]; + + if ( NULL != pfnSTAFsm ) + { +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* Read RSSI and update */ + vosStatus = WLANTL_HSHandleRXFrame(pvosGCtx, + WLANTL_DATA_FRAME_TYPE, + pvBDHeader, + ucSTAId, + broadcast, + vosTempBuff); + broadcast = VOS_FALSE; +#else + vosStatus = WLANTL_ReadRSSI(pvosGCtx, pvBDHeader, ucSTAId); +#endif + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "Handle RX Data Frame fail within Handoff support module")); + /* Do Not Drop packet at here + * Revisit why HO module return fail + * vos_pkt_return_packet(vosTempBuff); + * vosTempBuff = vosDataBuff; + * continue; + */ + } +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + if ( NULL != pClientSTA) + { + tpSirMacMgmtHdr pMacHeader = WDA_GET_RX_MAC_HEADER( pvBDHeader ); + if (!IS_BROADCAST_ADD(pMacHeader->da) && IS_MULTICAST_ADD(pMacHeader->da)) + { + pClientSTA->interfaceStats.accessCategoryStats[ac].rxMcast++; + } + + WLANTL_HSGetDataRSSI(pvosGCtx, pvBDHeader, ucSTAId, + ¤tAvgRSSI); + pClientSTA->interfaceStats.rssiData = currentAvgRSSI; + + pClientSTA->interfaceStats.accessCategoryStats[ac].rxMpdu++; + if (WDA_IS_RX_AN_AMPDU (pvBDHeader)) + { + pClientSTA->interfaceStats.accessCategoryStats[ac].rxAmpdu++; + } + } + + +#endif + vosStatus = WLANTL_ReadSNR(pvosGCtx, pvBDHeader, ucSTAId); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + FL("Failed to Read SNR"))); + } + + pfnSTAFsm( pvosGCtx, ucSTAId, &vosTempBuff, bForwardIAPPwithLLC); + } + else + { + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:NULL state function, STA:%d, State: %d- dropping packet", + ucSTAId, pClientSTA->tlState)); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + }/* else data frame*/ + + vosTempBuff = vosDataBuff; + }/*while chain*/ + + return VOS_STATUS_SUCCESS; +}/* WLANTL_RxFrames */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/*========================================================================== + + FUNCTION WLANTL_CollectInterfaceStats + + DESCRIPTION + Utility function used by TL to send the statitics + + DEPENDENCIES + + + PARAMETERS + + IN + + ucSTAId: station for which the statistics need to collected + + vosDataBuff: it will contain the pointer to the corresponding + structure + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_CollectInterfaceStats +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_InterfaceStatsType *vosDataBuff +) +{ + WLANTL_CbType* pTLCb = NULL; + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_CollectStats")); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_CollectStats")); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: collect WIFI_STATS_IFACE results")); + + vos_mem_copy(vosDataBuff, &pTLCb->atlSTAClients[ucSTAId]->interfaceStats, + sizeof(WLANTL_InterfaceStatsType)); + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION WLANTL_ClearInterfaceStats + + DESCRIPTION + Utility function used by TL to clear the statitics + + DEPENDENCIES + + + PARAMETERS + + IN + + ucSTAId: station for which the statistics need to collected + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ClearInterfaceStats +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U8_t statsClearReqMask +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_CollectStats")); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_CollectStats")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + if ( NULL == pClientSTA ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ((statsClearReqMask & WIFI_STATS_IFACE_AC) || + (statsClearReqMask & WIFI_STATS_IFACE)) { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:cleared WIFI_STATS_IFACE_AC results")); + pClientSTA->interfaceStats.accessCategoryStats[0].rxMcast = 0; + pClientSTA->interfaceStats.accessCategoryStats[1].rxMcast = 0; + pClientSTA->interfaceStats.accessCategoryStats[2].rxMcast = 0; + pClientSTA->interfaceStats.accessCategoryStats[3].rxMcast = 0; + + pClientSTA->interfaceStats.accessCategoryStats[0].rxMpdu = 0; + pClientSTA->interfaceStats.accessCategoryStats[1].rxMpdu = 0; + pClientSTA->interfaceStats.accessCategoryStats[2].rxMpdu = 0; + pClientSTA->interfaceStats.accessCategoryStats[3].rxMpdu = 0; + + pClientSTA->interfaceStats.accessCategoryStats[0].rxAmpdu = 0; + pClientSTA->interfaceStats.accessCategoryStats[1].rxAmpdu = 0; + pClientSTA->interfaceStats.accessCategoryStats[2].rxAmpdu = 0; + pClientSTA->interfaceStats.accessCategoryStats[3].rxAmpdu = 0; + } + + if (statsClearReqMask & WIFI_STATS_IFACE) { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:cleared WIFI_STATS_IFACE results")); + pClientSTA->interfaceStats.mgmtRx = 0; + pClientSTA->interfaceStats.rssiData = 0; + return VOS_STATUS_SUCCESS; + } + + return VOS_STATUS_SUCCESS; +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/*========================================================================== + + FUNCTION WLANTL_RxCachedFrames + + DESCRIPTION + Utility function used by TL to forward the cached frames to a particular + station; + + DEPENDENCIES + TL must be initiailized before this function gets called. + If the frame carried is a data frame then the station for which it is + destined to must have been previously registered with TL. + + PARAMETERS + + IN + pTLCb: pointer to TL handle + + ucSTAId: station for which we need to forward the packets + + vosDataBuff: it will contain a pointer to the first cached buffer + received, if there is more then one packet they will be + chained using vOSS buffers. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RxCachedFrames +( + WLANTL_CbType* pTLCb, + v_U8_t ucSTAId, + vos_pkt_t* vosDataBuff +) +{ + WLANTL_STAClientType* pClientSTA = NULL; + WLANTL_STAFuncType pfnSTAFsm; + vos_pkt_t* vosTempBuff; + VOS_STATUS vosStatus; + v_PVOID_t pvBDHeader = NULL; + WLANTL_STAEventType wSTAEvent = WLANTL_RX_EVENT; + v_U8_t ucTid = 0; + v_BOOL_t broadcast = VOS_FALSE; + v_BOOL_t bSigMatch = VOS_FALSE; + v_BOOL_t selfBcastLoopback = VOS_FALSE; + static v_U8_t first_data_pkt_arrived; + v_U32_t uDPUSig; + v_U8_t ucUcastSig; + v_U8_t ucBcastSig; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:TL Receive Cached Frames called")); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == vosDataBuff ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_RxFrames")); + return VOS_STATUS_E_INVAL; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_FORWARD_CACHED_FRAMES, + ucSTAId, 1<<16 | pClientSTA->tlCacheInfo.cacheSize)); + + /*--------------------------------------------------------------------- + Save the initial buffer - this is the first received buffer + ---------------------------------------------------------------------*/ + vosTempBuff = vosDataBuff; + + while ( NULL != vosTempBuff ) + { + broadcast = VOS_FALSE; + selfBcastLoopback = VOS_FALSE; + + vos_pkt_walk_packet_chain( vosDataBuff, &vosDataBuff, 1/*true*/ ); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Sending new cached packet to station %d", ucSTAId)); + /*--------------------------------------------------------------------- + Peek at BD header - do not remove + !!! Optimize me: only part of header is needed; not entire one + ---------------------------------------------------------------------*/ + vosStatus = WDA_DS_PeekRxPacketInfo( vosTempBuff, (v_PVOID_t)&pvBDHeader, 0 ); + + if ( NULL == pvBDHeader ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Cannot extract BD header")); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + uDPUSig = WDA_GET_RX_DPUSIG( pvBDHeader ); + + /* AMSDU HW bug fix + * After 2nd AMSDU subframe HW could not handle BD correctly + * HAL workaround is needed */ + if(WDA_GET_RX_ASF(pvBDHeader)) + { + WDA_DS_RxAmsduBdFix(vos_get_global_context(VOS_MODULE_ID_TL,pTLCb), + pvBDHeader); + } + + ucTid = (v_U8_t)WDA_GET_RX_TID( pvBDHeader ); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Data packet cached for STA %d", ucSTAId); + + /*------------------------------------------------------------------ + This should be corrected when multipe sta support is added !!! + for now bcast frames will be sent to the last registered STA + ------------------------------------------------------------------*/ + if ( WDA_IS_RX_BCAST(pvBDHeader)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:TL rx Bcast frame ")); + broadcast = VOS_TRUE; + + /* If Addr1 is b/mcast, but Addr3 is our own self MAC, it is a b/mcast + * pkt we sent looping back to us. To be dropped if we are non BTAMP + */ + if( WLANHAL_RX_BD_ADDR3_SELF_IDX == + (v_U8_t)WDA_GET_RX_ADDR3_IDX( pvBDHeader )) + { + selfBcastLoopback = VOS_TRUE; + } + }/*if bcast*/ + + /*------------------------------------------------------------------------- + Check if the packet that we cached matches the DPU signature of the + newly added station + -------------------------------------------------------------------------*/ + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( broadcast ) + { + ucBcastSig = (v_U8_t)uDPUSig; + bSigMatch = (( WLAN_TL_INVALID_B_SIG != + pClientSTA->wSTADesc.ucBcastSig ) && + ( ucBcastSig == pClientSTA->wSTADesc.ucBcastSig )); + } + else + { + ucUcastSig = (v_U8_t)uDPUSig; + bSigMatch = (( WLAN_TL_INVALID_U_SIG != + pClientSTA->wSTADesc.ucUcastSig ) && + ( ucUcastSig == pClientSTA->wSTADesc.ucUcastSig )); + } + + /*------------------------------------------------------------------------- + If the packet doesn't match - drop it + -------------------------------------------------------------------------*/ + if ( !bSigMatch ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_MED, + "WLAN TL: Cached packet does not match DPU Sig of the new STA - drop " + " DPU Sig %d UC %d BC %d B %d", + uDPUSig, + pClientSTA->wSTADesc.ucUcastSig, + pClientSTA->wSTADesc.ucBcastSig, + broadcast)); + + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + + }/*if signature mismatch*/ + + /*------------------------------------------------------------------------ + Check if BT-AMP frame: + - additional processing needed in this case to separate BT-AMP date + from BT-AMP Ctrl path + ------------------------------------------------------------------------*/ + if ( WLAN_STA_BT_AMP == pClientSTA->wSTADesc.wSTAType ) + { + /*-------------------------------------------------------------------- + Process the ctrl BAP frame; if data it will return false and it + will be routed through the regular data path + --------------------------------------------------------------------*/ + if ( WLANTL_ProcessBAPFrame( pvBDHeader, + vosTempBuff, + pTLCb, + &first_data_pkt_arrived, + ucSTAId)) + { + vosTempBuff = vosDataBuff; + continue; + } + }/*if BT-AMP station*/ + else if(selfBcastLoopback == VOS_TRUE) + { + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + /*--------------------------------------------------------------------- + Data packet received, send to state machine + ---------------------------------------------------------------------*/ + wSTAEvent = WLANTL_RX_EVENT; + + pfnSTAFsm = tlSTAFsm[pClientSTA->tlState]. + pfnSTATbl[wSTAEvent]; + + if ( NULL != pfnSTAFsm ) + { +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + /* Read RSSI and update */ + vosStatus = WLANTL_HSHandleRXFrame(vos_get_global_context( + VOS_MODULE_ID_TL,pTLCb), + WLANTL_DATA_FRAME_TYPE, + pvBDHeader, + ucSTAId, + broadcast, + vosTempBuff); + broadcast = VOS_FALSE; +#else + vosStatus = WLANTL_ReadRSSI(vos_get_global_context(VOS_MODULE_ID_TL,pTLCb), pvBDHeader, ucSTAId); +#endif + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Handle RX Data Frame fail within Handoff support module")); + /* Do Not Drop packet at here + * Revisit why HO module return fail + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + */ + } + pfnSTAFsm( vos_get_global_context(VOS_MODULE_ID_TL,pTLCb), ucSTAId, + &vosTempBuff, VOS_FALSE); + } + else + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:NULL state function, STA:%d, State: %d- dropping packet", + ucSTAId, pClientSTA->tlState)); + /* Drop packet */ + vos_pkt_return_packet(vosTempBuff); + vosTempBuff = vosDataBuff; + continue; + } + + vosTempBuff = vosDataBuff; + }/*while chain*/ + + return VOS_STATUS_SUCCESS; +}/* WLANTL_RxCachedFrames */ + +/** + * WLANTL_ForwardPkts() - forward cached eapol frames + * @pvosGCtx: pointer to vos global context + * @data: value to indicate either forward or flush + * + * Return: None + * + */ +static VOS_STATUS WLANTL_ForwardPkts(void* pvosGCtx, uint32_t data) +{ + WLANTL_CbType* pTLCb = NULL; + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid input pointer", __func__)); + return VOS_STATUS_E_FAULT; + } + + if (!data) { + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Pre assoc fail flush cache", __func__)); + WLANTL_FlushCachedFrames(pTLCb->vosEapolCachedFrame); + goto done; + } + + /* forward packets to HDD */ + if (NULL != pTLCb->vosEapolCachedFrame) { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: forward pre assoc cached frames", __func__)); + WLANTL_MonTranslate80211To8023Header(pTLCb->vosEapolCachedFrame, pTLCb); + pTLCb->pfnEapolFwd(pvosGCtx, pTLCb->vosEapolCachedFrame); + } + +done: + pTLCb->vosEapolCachedFrame = NULL; + pTLCb->preassoc_caching = false; + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANTL_RxProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + rx thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RxProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t uData; + v_U8_t ucSTAId; + v_U8_t ucUcastSig; + v_U8_t ucBcastSig; + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == message ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_RxProcessMessage")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Process message + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Received message: %d through rx flow", message->type)); + + switch( message->type ) + { + + case WLANTL_RX_FWD_CACHED: + /*--------------------------------------------------------------------- + The data sent with the message has the following structure: + | 00 | ucBcastSignature | ucUcastSignature | ucSTAID | + each field above is one byte + ---------------------------------------------------------------------*/ + uData = message->bodyval; + ucSTAId = ( uData & 0x000000FF); + ucUcastSig = ( uData & 0x0000FF00)>>8; + ucBcastSig = (v_U8_t)(( uData & 0x00FF0000)>>16); + vosStatus = WLANTL_ForwardSTAFrames( pvosGCtx, ucSTAId, + ucUcastSig, ucBcastSig); + break; + + case WLANTL_RX_FWD_PRE_ASSOC_CACHED: + uData = message->bodyval; + vosStatus = WLANTL_ForwardPkts(pvosGCtx, uData); + break; + + default: + /*no processing for now*/ + break; + } + + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION WLANTL_ResourceCB + + DESCRIPTION + Called by the TL when it has packets available for transmission. + + DEPENDENCIES + The TL must be registered with BAL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or BAL's control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResourceCB +( + v_PVOID_t pvosGCtx, + v_U32_t uCount +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + + pTLCb->uResCount = uCount; + + + /*----------------------------------------------------------------------- + Resume Tx if enough res and not suspended + -----------------------------------------------------------------------*/ + if (( pTLCb->uResCount >= WDA_TLI_MIN_RES_MF ) && + ( 0 == pTLCb->ucTxSuspended )) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Issuing Xmit start request to BAL for avail res ASYNC")); + return WDA_DS_StartXmit(pvosGCtx); + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_ResourceCB */ + + +/*========================================================================== + FUNCTION WLANTL_IsTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to know whether WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + 0: No WDA_DS_TX_START_XMIT msg pending + 1: Msg WDA_DS_TX_START_XMIT already pending in TL msg queue + + SIDE EFFECTS + +============================================================================*/ +v_BOOL_t +WLANTL_IsTxXmitPending +( + v_PVOID_t pvosGCtx +) +{ + + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Invalid TL pointer from pvosGCtx in WLANTL_IsTxXmitPending ")); + return FALSE; + } + + return pTLCb->isTxTranmitMsgPending; + +}/*WLANTL_IsTxXmitPending */ + +/*========================================================================== + FUNCTION WLANTL_SetTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to indicate that WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_SetTxXmitPending +( + v_PVOID_t pvosGCtx +) +{ + + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Invalid TL pointer from pvosGCtx in WLANTL_SetTxXmitPending")); + return; + } + + pTLCb->isTxTranmitMsgPending = 1; + return; + +}/*WLANTL_SetTxXmitPending */ + +/*========================================================================== + FUNCTION WLANTL_ClearTxXmitPending + + DESCRIPTION + Called by the WDA when it wants to indicate that no WDA_DS_TX_START_XMIT msg + is pending in TL msg queue + + DEPENDENCIES + The TL must be registered with WDA before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_ClearTxXmitPending +( + v_PVOID_t pvosGCtx +) +{ + + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Invalid TL pointer from pvosGCtx in WLANTL_ClearTxXmitPending ")); + return; + } + + pTLCb->isTxTranmitMsgPending = 0; + return; +}/*WLANTL_ClearTxXmitPending */ + +/*========================================================================== + FUNCTION WLANTL_TxThreadDebugHandler + + DESCRIPTION + Printing TL Snapshot dump, processed under TxThread context, currently + information regarding the global TlCb struture. Dumps information related + to per active STA connection currently in use by TL. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_TxThreadDebugHandler +( + v_PVOID_t *pVosContext +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + int i = 0; + v_U8_t uFlowMask; // TX FlowMask from WDA + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL: %s Enter ", __func__)); + + pTLCb = VOS_GET_TL_CB(pVosContext); + + if ( NULL == pVosContext || NULL == pTLCb ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Global VoS Context or TL Context are NULL")); + return; + } + + if (VOS_STATUS_SUCCESS == WDA_DS_GetTxFlowMask(pVosContext, &uFlowMask)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WDA uTxFlowMask: 0x%x", uFlowMask)); + } + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "************************TL DUMP INFORMATION**************")); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "uDelayedTriggerFrmInt:%d\tuMinFramesProcThres:%d", + pTLCb->tlConfigInfo.uDelayedTriggerFrmInt, + pTLCb->tlConfigInfo.uMinFramesProcThres)); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Management Frame Client exists: %d", + pTLCb->tlMgmtFrmClient.ucExists)); + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "usPendingTxCompleteCount: %d\tucTxSuspended: %d", + pTLCb->usPendingTxCompleteCount, + pTLCb->ucTxSuspended)); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "uResCount: %d", pTLCb->uResCount)); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "ucRegisteredStaId: %d\tucCurrentSTA: %d", + pTLCb->ucRegisteredStaId, pTLCb->ucCurrentSTA)); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "UrgentFrameProcessing: %s\tuFramesProcThres: %d", + (pTLCb->bUrgent?"True":"False"), pTLCb->uFramesProcThres)); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "isTxTranmitMsgPending: %d\t isBMPS: %s", + pTLCb->isTxTranmitMsgPending, pTLCb->isBMPS?"True":"False")); + +#ifdef FEATURE_WLAN_TDLS + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "TDLS Peer Count: %d", pTLCb->ucTdlsPeerCount)); +#endif + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "++++++++++++++++++++Registerd Client Information++++++++++")); + + for ( i =0; iatlSTAClients[i]; + if( NULL == pClientSTA || 0 == pClientSTA->ucExists) + { + continue; + } + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "######################STA Index: %d ############################",i)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "WLAN_STADescType:")); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "STAId: %d\t STA MAC Address: %pM", pClientSTA->wSTADesc.ucSTAId, + pClientSTA->wSTADesc.vSTAMACAddress.bytes)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "STA Type: %d\tProtectedFrame: %d", + pClientSTA->wSTADesc.wSTAType, pClientSTA->wSTADesc.ucProtectedFrame)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "QoS: %d\tRxFrameTrans: %d\tTxFrameTrans: %d", + pClientSTA->wSTADesc.ucQosEnabled, pClientSTA->wSTADesc.ucSwFrameRXXlation, + pClientSTA->wSTADesc.ucSwFrameTXXlation)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "ucUcastSig: %d\tucBcastSig: %d", pClientSTA->wSTADesc.ucUcastSig, + pClientSTA->wSTADesc.ucBcastSig)); + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "ClientIndex: %d\t Exists: %d", i, pClientSTA->ucExists)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "TL State: %d\t TL Priority: %d", pClientSTA->tlState, + pClientSTA->tlPri)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "ucTxSuspended: %d\tucPktPending: %d", pClientSTA->ucTxSuspended, + pClientSTA->ucPktPending)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "ucEAPOLPktPending: %d\tucNoMoreData: %d", + pClientSTA->ucEapolPktPending, pClientSTA->ucNoMoreData)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "enableCaching: %d\t fcStaTxDisabled: %d", pClientSTA->enableCaching, + pClientSTA->fcStaTxDisabled)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "ucCurrentAC: %d\tucServicedAC: %d", pClientSTA->ucCurrentAC, + pClientSTA->ucServicedAC)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "TID: %d\tautTxCount[0]: %d\tauRxCount[0]: %d",0, pClientSTA->auTxCount[0], + pClientSTA->auRxCount[0])); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "aucAcMask[0]: %d\taucAcMask[1]: %d\taucAcMask[2]: %d\taucAcMask[3]: %d\t", + pClientSTA->aucACMask[0], pClientSTA->aucACMask[1], + pClientSTA->aucACMask[2], pClientSTA->aucACMask[3])); + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + + "ucCurrentWeight: %d", pClientSTA->ucCurrentWeight)); + + if( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "TrafficStatistics for SOFTAP Station:")); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "RUF=%d\tRMF=%d\tRBF=%d", pClientSTA->trafficStatistics.rxUCFcnt, + pClientSTA->trafficStatistics.rxMCFcnt, + pClientSTA->trafficStatistics.rxBCFcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "RUB=%d\tRMB=%d\tRBB=%d", pClientSTA->trafficStatistics.rxUCBcnt, + pClientSTA->trafficStatistics.rxMCBcnt, + pClientSTA->trafficStatistics.rxBCBcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "TUF=%d\tTMF=%d\tTBF=%d", pClientSTA->trafficStatistics.txUCFcnt, + pClientSTA->trafficStatistics.txMCFcnt, + pClientSTA->trafficStatistics.txBCFcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "TUB=%d\tTMB=%d\tTBB=%d", pClientSTA->trafficStatistics.txUCBcnt, + pClientSTA->trafficStatistics.txMCBcnt, + pClientSTA->trafficStatistics.txBCBcnt)); + } + + } + return; +} + +/*========================================================================== + FUNCTION WLANTL_FatalErrorHandler + + DESCRIPTION + Handle Fatal errors detected on the TX path. + Currently issues SSR to recover from the error. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or WDA's control block can be extracted from its context + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WLANTL_FatalErrorHandler +( + v_PVOID_t *pVosContext +) +{ + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL: %s Enter ", __func__)); + + if ( NULL == pVosContext ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Global VoS Context or TL Context are NULL", + __func__)); + return; + } + + /* + * Issue SSR. vos_wlanRestart has tight checks to make sure that + * we do not send an FIQ if previous FIQ is not processed + */ + vos_wlanRestart(); +} + +/*========================================================================== + FUNCTION WLANTL_TLDebugMessage + + DESCRIPTION + Post a TL Snapshot request, posts message in TxThread. + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + IN + displaySnapshot Boolean showing whether to dump the snapshot or not. + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_TLDebugMessage +( + v_U32_t debugFlags +) +{ + vos_msg_t vosMsg; + VOS_STATUS status; + + if(debugFlags & WLANTL_DEBUG_TX_SNAPSHOT) + { + vosMsg.reserved = 0; + vosMsg.bodyptr = NULL; + vosMsg.type = WLANTL_TX_SNAPSHOT; + + status = vos_tx_mq_serialize( VOS_MODULE_ID_TL, &vosMsg); + if(status != VOS_STATUS_SUCCESS) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "TX Msg Posting Failed with status: %d",status)); + return; + } + } + if (debugFlags & WLANTL_DEBUG_FW_CLEANUP) + { + vosMsg.reserved = 0; + vosMsg.bodyptr = NULL; + vosMsg.type = WLANTL_TX_FW_DEBUG; + + status = vos_tx_mq_serialize( VOS_MODULE_ID_TL, &vosMsg); + if(status != VOS_STATUS_SUCCESS) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "TX Msg Posting Failed with status: %d",status)); + return; + } + } + if(debugFlags & WLANTL_DEBUG_KICKDXE) + { + vosMsg.reserved = 0; + vosMsg.bodyptr = NULL; + vosMsg.type = WLANTL_TX_KICKDXE; + + status = vos_tx_mq_serialize( VOS_MODULE_ID_TL, &vosMsg); + if(status != VOS_STATUS_SUCCESS) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "TX Msg Posting Failed with status: %d",status)); + return; + } + } + return; +} + +/*========================================================================== + FUNCTION WLANTL_FatalError + + DESCRIPTION + Fatal error reported in TX path, post an event to TX Thread for further + handling + + DEPENDENCIES + The TL must be initialized before this gets called. + + PARAMETERS + + VOID + + RETURN VALUE None + + SIDE EFFECTS + +============================================================================*/ + +v_VOID_t +WLANTL_FatalError +( + v_VOID_t +) +{ + vos_msg_t vosMsg; + VOS_STATUS status; + + vosMsg.reserved = 0; + vosMsg.bodyptr = NULL; + vosMsg.type = WLANTL_TX_FATAL_ERROR; + + status = vos_tx_mq_serialize( VOS_MODULE_ID_TL, &vosMsg); + if(status != VOS_STATUS_SUCCESS) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: TX Msg Posting Failed with status: %d", + __func__,status)); + } + return; +} +/*============================================================================ + TL STATE MACHINE +============================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_STATxConn + + DESCRIPTION + Transmit in connected state - only EAPOL and WAI packets allowed + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the tx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other return values are possible coming from the called functions. + Please check API for additional info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STATxConn +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC +) +{ + v_U16_t usPktLen; + VOS_STATUS vosStatus; + v_MACADDR_t vDestMacAddr; + vos_pkt_t* vosDataBuff = NULL; + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + WLANTL_MetaInfoType tlMetaInfo; + v_U8_t ucTypeSubtype = 0; + v_U8_t ucTid; + v_U8_t extraHeadSpace = 0; + v_U8_t ucWDSEnabled = 0; + v_U8_t ucAC, ucACMask, i; + v_U32_t txFlag = HAL_TX_NO_ENCRYPTION_MASK; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STATxConn"); + *pvosDataBuff = NULL; + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------- + Disable AC temporary - if successfull retrieve re-enable + The order is justified because of the possible scenario + - TL tryes to fetch packet for AC and it returns NULL + - TL analyzes the data it has received to see if there are + any more pkts available for AC -> if not TL will disable AC + - however it is possible that while analyzing results TL got + preempted by a pending indication where the mask was again set + TL will not check again and as a result when it resumes + execution it will disable AC + To prevent this the AC will be disabled here and if retrieve + is successfull it will be re-enabled + -------------------------------------------------------------------*/ + + + //LTI:pTLCb->atlSTAClients[ucSTAId]. + //LTI: aucACMask[pTLCb->atlSTAClients[ucSTAId].ucCurrentAC] = 0; + + /*------------------------------------------------------------------------ + Fetch packet from HDD + ------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_TDLS + if ((WLAN_STA_SOFTAP != pClientSTA->wSTADesc.wSTAType) && + !(vos_concurrent_open_sessions_running()) && + !pTLCb->ucTdlsPeerCount) + { +#else + if ((WLAN_STA_SOFTAP != pClientSTA->wSTADesc.wSTAType) && + !(vos_concurrent_open_sessions_running())) + { +#endif + ucAC = pClientSTA->ucCurrentAC; + + /*------------------------------------------------------------------- + Disable AC temporary - if successfull retrieve re-enable + The order is justified because of the possible scenario + - TL tryes to fetch packet for AC and it returns NULL + - TL analyzes the data it has received to see if there are + any more pkts available for AC -> if not TL will disable AC + - however it is possible that while analyzing results TL got + preempted by a pending indication where the mask was again set + TL will not check again and as a result when it resumes + execution it will disable AC + To prevent this the AC will be disabled here and if retrieve + is successfull it will be re-enabled + -------------------------------------------------------------------*/ + pClientSTA->aucACMask[ucAC] = 0; + } + else + { + //softap case + ucAC = pTLCb->uCurServedAC; + pClientSTA->aucACMask[ucAC] = 0; + } + + /*You make an initial assumption that HDD has no more data and if the + assumption was wrong you reset the flags to their original state + This will prevent from exposing a race condition between checking with HDD + for packets and setting the flags to false*/ + //LTI: vos_atomic_set_U8( &pTLCb->atlSTAClients[ucSTAId].ucPktPending, 0); + //LTI: pTLCb->atlSTAClients[ucSTAId].ucNoMoreData = 1; + vos_atomic_set_U8( &pClientSTA->ucPktPending, 0); + WLAN_TL_AC_ARRAY_2_MASK( pClientSTA, ucACMask, i); + /*You make an initial assumption that HDD has no more data and if the + assumption was wrong you reset the flags to their original state + This will prevent from exposing a race condition between checking with HDD + for packets and setting the flags to false*/ + if ( 0 == ucACMask ) + { + pClientSTA->ucNoMoreData = 1; + } + else + { + vos_atomic_set_U8( &pClientSTA->ucPktPending, 1); + } + + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: WLANTL_STATxConn fetching packet from HDD for AC: %d AC Mask: %d Pkt Pending: %d", + ucAC, ucACMask, pClientSTA->ucPktPending); + + /*------------------------------------------------------------------------ + Fetch tx packet from HDD + ------------------------------------------------------------------------*/ + + vosStatus = pClientSTA->pfnSTAFetchPkt( pvosGCtx, + &ucSTAId, + ucAC, + &vosDataBuff, &tlMetaInfo ); + + if (( VOS_STATUS_SUCCESS != vosStatus ) || ( NULL == vosDataBuff )) + { + TLLOG1(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:No more data at HDD status %d", vosStatus)); + *pvosDataBuff = NULL; + + /*-------------------------------------------------------------------- + Reset AC for the serviced station to the highest priority AC + -> due to no more data at the station + Even if this AC is not supported by the station, correction will be + made in the main TL loop + --------------------------------------------------------------------*/ + pClientSTA->ucCurrentAC = WLANTL_AC_HIGH_PRIO; + pClientSTA->ucCurrentWeight = 0; + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: WLANTL_STATxConn no more packets in HDD for AC: %d AC Mask: %d", + ucAC, ucACMask); + + return vosStatus; + } + + /*There are still packets in HDD - set back the pending packets and + the no more data assumption*/ + vos_atomic_set_U8( &pClientSTA->ucPktPending, 1); + pClientSTA->ucNoMoreData = 0; + pClientSTA->aucACMask[ucAC] = 1; + +#ifdef WLAN_PERF + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAL, + (v_PVOID_t)0); + +#endif /*WLAN_PERF*/ + + +#ifdef FEATURE_WLAN_WAPI + /*------------------------------------------------------------------------ + If the packet is neither an Eapol packet nor a WAI packet then drop it + ------------------------------------------------------------------------*/ + if ( 0 == tlMetaInfo.ucIsEapol && 0 == tlMetaInfo.ucIsWai ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:Only EAPOL or WAI packets allowed before authentication")); + + /* Fail tx for packet */ + pClientSTA->pfnSTATxComp( pvosGCtx, vosDataBuff, + VOS_STATUS_E_BADMSG); + vosDataBuff = NULL; + *pvosDataBuff = NULL; + return VOS_STATUS_SUCCESS; + } +#else + if ( 0 == tlMetaInfo.ucIsEapol ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Received non EAPOL packet before authentication")); + + /* Fail tx for packet */ + pClientSTA->pfnSTATxComp( pvosGCtx, vosDataBuff, + VOS_STATUS_E_BADMSG); + vosDataBuff = NULL; + *pvosDataBuff = NULL; + return VOS_STATUS_SUCCESS; + } +#endif /* FEATURE_WLAN_WAPI */ + + /*------------------------------------------------------------------------- + Check TID + -------------------------------------------------------------------------*/ + ucTid = tlMetaInfo.ucTID; + + /*Make sure TID is valid*/ + if ( WLANTL_TID_INVALID(ucTid)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Invalid TID sent in meta info %d - defaulting to 0 (BE)", + ucTid)); + ucTid = 0; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Attaching BD header to pkt on WLANTL_STATxConn")); + +#ifdef FEATURE_WLAN_WAPI + /*------------------------------------------------------------------------ + Translate 802.3 frame to 802.11 if Frame translation is enabled or if + frame is a WAI frame. + ------------------------------------------------------------------------*/ + if ( ( 1 == tlMetaInfo.ucIsWai ) || + ( 0 == tlMetaInfo.ucDisableFrmXtl ) ) +#else + /*------------------------------------------------------------------------ + Translate 802.3 frame to 802.11 if Frame translation is enabled + ------------------------------------------------------------------------*/ + if ( ( 0 == tlMetaInfo.ucDisableFrmXtl ) && + ( 0 != pClientSTA->wSTADesc.ucSwFrameTXXlation) ) +#endif //#ifdef FEATURE_WLAN_WAPI + { + vosStatus = WLANTL_Translate8023To80211Header( vosDataBuff, &vosStatus, + pTLCb, &ucSTAId, + &tlMetaInfo, &ucWDSEnabled, + &extraHeadSpace); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Error when translating header WLANTL_STATxConn")); + + return vosStatus; + } + + tlMetaInfo.ucDisableFrmXtl = 1; + } + + /*------------------------------------------------------------------------- + Call HAL to fill BD header + -------------------------------------------------------------------------*/ + ucTypeSubtype |= (WLANTL_80211_DATA_TYPE << 4); + + if ( pClientSTA->wSTADesc.ucQosEnabled ) + { + ucTypeSubtype |= (WLANTL_80211_DATA_QOS_SUBTYPE); + } + +#ifdef FEATURE_WLAN_WAPI + /* TL State does not transition to AUTHENTICATED till GTK is installed, So in + * case of WPA where GTK handshake is done after the 4 way handshake, the + * unicast 2/2 EAPOL packet from the STA->AP has to be encrypted even before + * the TL is in authenticated state. Since the PTK has been installed + * already (after the 4 way handshake) we make sure that all traffic + * is encrypted henceforth.(Note: TL is still not in AUTHENTICATED state so + * we will only allow EAPOL data or WAI in case of WAPI) + */ + if (tlMetaInfo.ucIsEapol && pClientSTA->ptkInstalled) + { + txFlag = 0; + } +#else + if (pClientSTA->ptkInstalled) + { + txFlag = 0; + } +#endif + + vosStatus = (VOS_STATUS)WDA_DS_BuildTxPacketInfo( pvosGCtx, vosDataBuff , &vDestMacAddr, + tlMetaInfo.ucDisableFrmXtl, &usPktLen, + pClientSTA->wSTADesc.ucQosEnabled, ucWDSEnabled, + extraHeadSpace, + ucTypeSubtype, &pClientSTA->wSTADesc.vSelfMACAddress, + ucTid, txFlag, + tlMetaInfo.usTimeStamp, tlMetaInfo.ucIsEapol || tlMetaInfo.ucIsWai, + tlMetaInfo.ucIsArp, tlMetaInfo.ucUP, tlMetaInfo.ucTxBdToken); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed while attempting to fill BD %d", vosStatus)); + *pvosDataBuff = NULL; + return vosStatus; + } + + /*----------------------------------------------------------------------- + Update tx counter for BA session query for tx side + !1 - should this be done for EAPOL frames? + -----------------------------------------------------------------------*/ + pClientSTA->auTxCount[ucTid]++; + + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)pClientSTA->pfnSTATxComp ); + + /*------------------------------------------------------------------------ + Save data to input pointer for TL core + ------------------------------------------------------------------------*/ + *pvosDataBuff = vosDataBuff; + /*security frames cannot be delayed*/ + pTLCb->bUrgent = TRUE; + + /* TX Statistics */ + if (!(tlMetaInfo.ucBcast || tlMetaInfo.ucMcast)) + { + /* This is TX UC frame */ + pClientSTA->trafficStatistics.txUCFcnt++; + pClientSTA->trafficStatistics.txUCBcnt += usPktLen; + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STATxConn */ + + +/*========================================================================== + FUNCTION WLANTL_STATxAuth + + DESCRIPTION + Transmit in authenticated state - all data allowed + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the tx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other return values are possible coming from the called functions. + Please check API for additional info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STATxAuth +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC +) +{ + v_U16_t usPktLen; + VOS_STATUS vosStatus; + v_MACADDR_t vDestMacAddr; + vos_pkt_t* vosDataBuff = NULL; + WLANTL_CbType* pTLCb = NULL; + WLANTL_MetaInfoType tlMetaInfo; + v_U8_t ucTypeSubtype = 0; + WLANTL_ACEnumType ucAC; + WLANTL_ACEnumType ucNextAC; + v_U8_t ucTid; + v_U8_t ucSwFrmXtl = 0; + v_U8_t extraHeadSpace = 0; + WLANTL_STAClientType *pStaClient = NULL; + v_U8_t ucWDSEnabled = 0; + v_U32_t ucTxFlag = 0; + v_U8_t ucACMask, i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (( NULL == pTLCb ) || ( NULL == pvosDataBuff )) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid input params on WLANTL_STATxAuth TL %p DB %p", + pTLCb, pvosDataBuff)); + if (NULL != pvosDataBuff) + { + *pvosDataBuff = NULL; + } + if(NULL != pTLCb) + { + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + pTLCb->atlSTAClients[ucSTAId]->ucNoMoreData = 1; + } + return VOS_STATUS_E_FAULT; + } + pStaClient = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pStaClient ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + vos_mem_zero(&tlMetaInfo, sizeof(tlMetaInfo)); + /*------------------------------------------------------------------------ + Fetch packet from HDD + ------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_TDLS + if ((WLAN_STA_SOFTAP != pStaClient->wSTADesc.wSTAType) && + (!vos_concurrent_open_sessions_running()) && + !pTLCb->ucTdlsPeerCount) + { +#else + if ((WLAN_STA_SOFTAP != pStaClient->wSTADesc.wSTAType) && + (!vos_concurrent_open_sessions_running())) + { +#endif + ucAC = pStaClient->ucCurrentAC; + + /*------------------------------------------------------------------- + Disable AC temporary - if successfull retrieve re-enable + The order is justified because of the possible scenario + - TL tryes to fetch packet for AC and it returns NULL + - TL analyzes the data it has received to see if there are + any more pkts available for AC -> if not TL will disable AC + - however it is possible that while analyzing results TL got + preempted by a pending indication where the mask was again set + TL will not check again and as a result when it resumes + execution it will disable AC + To prevent this the AC will be disabled here and if retrieve + is successfull it will be re-enabled + -------------------------------------------------------------------*/ + pStaClient->aucACMask[pStaClient->ucCurrentAC] = 0; + + // don't reset it, as other AC queues in HDD may have packets + //vos_atomic_set_U8( &pStaClient->ucPktPending, 0); + } + else + { + //softap case + ucAC = pTLCb->uCurServedAC; + pStaClient->aucACMask[ucAC] = 0; + + //vos_atomic_set_U8( &pStaClient->ucPktPending, 0); + } + + WLAN_TL_AC_ARRAY_2_MASK( pStaClient, ucACMask, i); + /*You make an initial assumption that HDD has no more data and if the + assumption was wrong you reset the flags to their original state + This will prevent from exposing a race condition between checking with HDD + for packets and setting the flags to false*/ + if ( 0 == ucACMask ) + { + vos_atomic_set_U8( &pStaClient->ucPktPending, 0); + pStaClient->ucNoMoreData = 1; + } + + vosStatus = pStaClient->pfnSTAFetchPkt( pvosGCtx, + &ucSTAId, + ucAC, + &vosDataBuff, &tlMetaInfo ); + + + if (( VOS_STATUS_SUCCESS != vosStatus ) || ( NULL == vosDataBuff )) + { + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:Failed while attempting to fetch pkt from HDD QId:%d status:%d", + ucAC, vosStatus); + *pvosDataBuff = NULL; + /*-------------------------------------------------------------------- + Reset AC for the serviced station to the highest priority AC + -> due to no more data at the station + Even if this AC is not supported by the station, correction will be + made in the main TL loop + --------------------------------------------------------------------*/ + pStaClient->ucCurrentAC = WLANTL_AC_HIGH_PRIO; + pStaClient->ucCurrentWeight = 0; + + return vosStatus; + } + + WLANTL_StatHandleTXFrame(pvosGCtx, ucSTAId, vosDataBuff, NULL, &tlMetaInfo); + + /*There are still packets in HDD - set back the pending packets and + the no more data assumption*/ + vos_atomic_set_U8( &pStaClient->ucPktPending, 1); + pStaClient->ucNoMoreData = 0; + + if (WLAN_STA_SOFTAP != pStaClient->wSTADesc.wSTAType) + { + // don't need to set it, as we don't reset it in this function. + //vos_atomic_set_U8( &pTLCb->atlSTAClients[ucSTAId].ucPktPending, 1); + } + +#ifdef WLAN_PERF + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAL, + (v_PVOID_t)0); +#endif /*WLAN_PERF*/ + + /*------------------------------------------------------------------------- + Check TID + -------------------------------------------------------------------------*/ + ucTid = tlMetaInfo.ucTID; + + /*Make sure TID is valid*/ + if ( WLANTL_TID_INVALID(ucTid)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Invalid TID sent in meta info %d - defaulting to 0 (BE)", + ucTid)); + ucTid = 0; + } + + /*Save for UAPSD timer consideration*/ + pStaClient->ucServicedAC = ucAC; + + if ( ucAC == pStaClient->ucCurrentAC ) + { + pStaClient->aucACMask[pStaClient->ucCurrentAC] = 1; + pStaClient->ucCurrentWeight--; + } + else + { + pStaClient->ucCurrentAC = ucAC; + pStaClient->ucCurrentWeight = pTLCb->tlConfigInfo.ucAcWeights[ucAC] - 1; + + pStaClient->aucACMask[pStaClient->ucCurrentAC] = 1; + + } + + if (WLAN_STA_SOFTAP != pStaClient->wSTADesc.wSTAType) + { + if ( 0 == pStaClient->ucCurrentWeight ) + { + WLANTL_ACEnumType tempAC = ucAC; + /*----------------------------------------------------------------------- + Choose next AC - !!! optimize me + -----------------------------------------------------------------------*/ + while ( 0 != ucACMask ) + { + if(tempAC == WLANTL_AC_BK) + ucNextAC = WLANTL_AC_HIGH_PRIO; + else + ucNextAC = (tempAC - 1); + + if ( 0 != pStaClient->aucACMask[ucNextAC] ) + { + pStaClient->ucCurrentAC = ucNextAC; + pStaClient->ucCurrentWeight = pTLCb->tlConfigInfo.ucAcWeights[ucNextAC]; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Changing serviced AC to: %d with Weight: %d", + pStaClient->ucCurrentAC , + pStaClient->ucCurrentWeight)); + break; + } + tempAC = ucNextAC; + } + } + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Attaching BD header to pkt on WLANTL_STATxAuth")); + + /*------------------------------------------------------------------------ + Translate 802.3 frame to 802.11 + ------------------------------------------------------------------------*/ + if ( 0 == tlMetaInfo.ucDisableFrmXtl ) + { + /* Needs frame translation */ + // if the client has not enabled SW-only frame translation + // and if the frame is a unicast frame + // (HW frame translation does not support multiple broadcast domains + // so we use SW frame translation for broadcast/multicast frames) +#ifdef FEATURE_WLAN_WAPI + // and if the frame is not a WAPI frame +#endif + // then use HW_based frame translation + + if ( ( 0 == pStaClient->wSTADesc.ucSwFrameTXXlation ) && + ( 0 == tlMetaInfo.ucBcast ) && + ( 0 == tlMetaInfo.ucMcast ) +#ifdef FEATURE_WLAN_WAPI + && ( tlMetaInfo.ucIsWai != 1 ) +#endif + ) + { +#ifdef WLAN_PERF + v_U32_t uFastFwdOK = 0; + + /* HW based translation. See if the frame could be fast forwarded */ + WDA_TLI_FastHwFwdDataFrame( pvosGCtx, vosDataBuff , &vosStatus, + &uFastFwdOK, &tlMetaInfo, &pStaClient->wSTADesc); + + if( VOS_STATUS_SUCCESS == vosStatus ) + { + if(uFastFwdOK) + { + /* Packet could be fast forwarded now */ + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)pStaClient->pfnSTATxComp ); + + *pvosDataBuff = vosDataBuff; + + /* TODO: Do we really need to update WLANTL_HSHandleTXFrame() + stats for every pkt? */ + pStaClient->auTxCount[tlMetaInfo.ucTID]++; + return vosStatus; + } + /* can't be fast forwarded, fall through normal (slow) path. */ + } + else + { + + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed while attempting to fastFwd BD %d", vosStatus)); + *pvosDataBuff = NULL; + return vosStatus; + } +#endif /*WLAN_PERF*/ + } + else + { + /* SW based translation */ + + vosStatus = WLANTL_Translate8023To80211Header( vosDataBuff, &vosStatus, + pTLCb, &ucSTAId, + &tlMetaInfo, &ucWDSEnabled, + &extraHeadSpace); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Error when translating header WLANTL_STATxAuth")); + return vosStatus; + } + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL software translation success")); + ucSwFrmXtl = 1; + tlMetaInfo.ucDisableFrmXtl = 1; + } + } +#ifdef FEATURE_WLAN_TDLS + /*In case of TDLS, if the packet is destined to TDLS STA ucSTAId may + change. so update the pStaClient accordingly */ + pStaClient = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pStaClient ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "pStaClient is NULL %s", __func__)); + return VOS_STATUS_E_FAILURE; + } +#endif + /*------------------------------------------------------------------------- + Call HAL to fill BD header + -------------------------------------------------------------------------*/ + ucTypeSubtype |= (WLANTL_80211_DATA_TYPE << 4); + + if ( pStaClient->wSTADesc.ucQosEnabled ) + { + ucTypeSubtype |= (WLANTL_80211_DATA_QOS_SUBTYPE); + } + + /* ucAC now points to TL Q ID with a new queue added in TL, + * hence look for the uapsd info for the correct AC that + * this packet belongs to. + */ + ucTxFlag = (0 != pStaClient->wUAPSDInfo[tlMetaInfo.ac].ucSet)? + HAL_TRIGGER_ENABLED_AC_MASK:0; + +#ifdef FEATURE_WLAN_WAPI + if ( pStaClient->wSTADesc.ucIsWapiSta == 1 ) + { +#ifdef LIBRA_WAPI_SUPPORT + ucTxFlag = ucTxFlag | HAL_WAPI_STA_MASK; +#endif //LIBRA_WAPI_SUPPORT + if ( tlMetaInfo.ucIsWai == 1 ) + { + ucTxFlag = ucTxFlag | HAL_TX_NO_ENCRYPTION_MASK; + } + } +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_TDLS + if ( pStaClient->wSTADesc.wSTAType == WLAN_STA_TDLS ) + { + ucTxFlag = ucTxFlag | HAL_TDLS_PEER_STA_MASK; + } +#endif /* FEATURE_WLAN_TDLS */ + if( tlMetaInfo.ucIsArp ) + { + if (pTLCb->track_arp) + { + if (vos_check_arp_target_ip(vosDataBuff)) + { + ucTxFlag |= HAL_USE_FW_IN_TX_PATH; + ucTxFlag |= HAL_TXCOMP_REQUESTED_MASK; + tlMetaInfo.ucTxBdToken = ++ pTLCb->txbd_token; + } + } + + if (pStaClient->arpOnWQ5) + { + ucTxFlag |= HAL_USE_FW_IN_TX_PATH; + } + if (pStaClient->arpRate == 0) + { + ucTxFlag |= HAL_USE_BD_RATE_1_MASK; + } + else if (pStaClient->arpRate == 1 || pStaClient->arpRate == 3) + { + pStaClient->arpRate ^= 0x2; + ucTxFlag |= HAL_USE_BD_RATE_1_MASK<<(pStaClient->arpRate-1); + } + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "arp pkt sending on BD rate: %hhu", pStaClient->arpRate)); + } + + vosStatus = (VOS_STATUS)WDA_DS_BuildTxPacketInfo( pvosGCtx, + vosDataBuff , &vDestMacAddr, + tlMetaInfo.ucDisableFrmXtl, &usPktLen, + pStaClient->wSTADesc.ucQosEnabled, ucWDSEnabled, + extraHeadSpace, + ucTypeSubtype, &pStaClient->wSTADesc.vSelfMACAddress, + ucTid, ucTxFlag, tlMetaInfo.usTimeStamp, + tlMetaInfo.ucIsEapol, tlMetaInfo.ucIsArp, tlMetaInfo.ucUP, + tlMetaInfo.ucTxBdToken); + + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Fill TX BD Error status %d", vosStatus)); + + return vosStatus; + } + + /* TX Statistics */ + if (!(tlMetaInfo.ucBcast || tlMetaInfo.ucMcast)) + { + /* This is TX UC frame */ + pStaClient->trafficStatistics.txUCFcnt++; + pStaClient->trafficStatistics.txUCBcnt += usPktLen; + } + +#ifndef FEATURE_WLAN_TDLS + /*----------------------------------------------------------------------- + Update tx counter for BA session query for tx side + -----------------------------------------------------------------------*/ + pStaClient->auTxCount[ucTid]++; +#else + pTLCb->atlSTAClients[ucSTAId]->auTxCount[ucTid]++; +#endif + + /* This code is to send traffic with lower priority AC when we does not + get admitted to send it. Today HAL does not downgrade AC so this code + does not get executed.(In other words, HAL doesn’t change tid. The if + statement is always false.) + NOTE: In the case of LA downgrade occurs in HDD (that was the change + Phani made during WMM-AC plugfest). If WM & BMP also took this approach, + then there will be no need for any AC downgrade logic in TL/WDI. */ +#if 0 + if (( ucTid != tlMetaInfo.ucTID ) && + ( 0 != pStaClient->wSTADesc.ucQosEnabled ) && + ( 0 != ucSwFrmXtl )) + { + /*--------------------------------------------------------------------- + !! FIX me: Once downgrading is clear put in the proper change + ---------------------------------------------------------------------*/ + ucQCOffset = WLANHAL_TX_BD_HEADER_SIZE + WLANTL_802_11_HEADER_LEN; + + //!!!Fix this replace peek with extract + vos_pkt_peek_data( vosDataBuff, ucQCOffset,(v_PVOID_t)&pucQosCtrl, + sizeof(*pucQosCtrl)); + *pucQosCtrl = ucTid; //? proper byte order + } +#endif + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed while attempting to fill BD %d", vosStatus)); + *pvosDataBuff = NULL; + return vosStatus; + } + + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)pStaClient->pfnSTATxComp ); + + *pvosDataBuff = vosDataBuff; + + /*BE & BK can be delayed, VO and VI not frames cannot be delayed*/ + if ( pStaClient->ucServicedAC > WLANTL_AC_BE ) + { + pTLCb->bUrgent= TRUE; + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STATxAuth */ + +/*========================================================================== + FUNCTION WLANTL_STATxDisc + + DESCRIPTION + Transmit in disconnected state - no data allowed + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the tx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STATxDisc +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STATxAuth")); + *pvosDataBuff = NULL; + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Error + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Packet should not be transmitted in state disconnected ignoring" + " request")); + + *pvosDataBuff = NULL; + pClientSTA->ucNoMoreData = 1; + + //Should not be anything pending in disconnect state + vos_atomic_set_U8( &pClientSTA->ucPktPending, 0); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STATxDisc */ + +/*========================================================================== + FUNCTION WLANTL_STARxConn + + DESCRIPTION + Receive in connected state - only EAPOL + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the tx/rx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STARxConn +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + v_U16_t usEtherType = 0; + v_U16_t usPktLen; + v_U8_t ucMPDUHOffset; + v_U16_t usMPDUDOffset; + v_U16_t usMPDULen; + v_U8_t ucMPDUHLen; + v_U16_t usActualHLen = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_pkt_t* vosDataBuff; + v_PVOID_t aucBDHeader; + v_U8_t ucTid; + WLANTL_RxMetaInfoType wRxMetaInfo; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pvosDataBuff ) || ( NULL == ( vosDataBuff = *pvosDataBuff ))) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_STARxConn")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ChangeSTAState")); + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Extract BD header and check if valid + ------------------------------------------------------------------------*/ + vosStatus = WDA_DS_PeekRxPacketInfo( vosDataBuff, (v_PVOID_t)&aucBDHeader, 0/*Swap BD*/ ); + + if ( NULL == aucBDHeader ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Cannot extract BD header")); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAULT; + } + + + ucMPDUHOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(aucBDHeader); + usMPDUDOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(aucBDHeader); + usMPDULen = (v_U16_t)WDA_GET_RX_MPDU_LEN(aucBDHeader); + ucMPDUHLen = (v_U8_t)WDA_GET_RX_MPDU_HEADER_LEN(aucBDHeader); + ucTid = (v_U8_t)WDA_GET_RX_TID(aucBDHeader); + + vos_pkt_get_packet_length( vosDataBuff, &usPktLen); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d", + ucMPDUHOffset, usMPDUDOffset, usMPDULen, ucMPDUHLen)); + + /*It will cut out the 802.11 header if not used*/ + if ( VOS_STATUS_SUCCESS != WDA_DS_TrimRxPacketInfo( vosDataBuff ) ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:BD header corrupted - dropping packet")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; + } + + vosStatus = WLANTL_GetEtherType(aucBDHeader,vosDataBuff,ucMPDUHLen,&usEtherType); + + if( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { +#ifdef FEATURE_WLAN_WAPI + /* If frame is neither an EAPOL frame nor a WAI frame then we drop the frame*/ + /* TODO: Do we need a check to see if we are in WAPI mode? If not is it possible */ + /* that we get an EAPOL packet in WAPI mode or vice versa? */ + if ( WLANTL_LLC_8021X_TYPE != usEtherType && WLANTL_LLC_WAI_TYPE != usEtherType ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:RX Frame not EAPOL or WAI EtherType %d - dropping", usEtherType ); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + } +#else + if ( WLANTL_LLC_8021X_TYPE != usEtherType ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:RX Frame not EAPOL EtherType %d - dropping", usEtherType); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + } +#endif /* FEATURE_WLAN_WAPI */ + else /* Frame is an EAPOL frame or a WAI frame*/ + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, + TRACE_CODE_TL_RX_CONN_EAPOL, ucSTAId, usEtherType )); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:RX Frame EAPOL EtherType %d - processing", usEtherType); + + if (( 0 == WDA_GET_RX_FT_DONE(aucBDHeader) ) && + ( 0 != pClientSTA->wSTADesc.ucSwFrameRXXlation)) + { + if (usMPDUDOffset > ucMPDUHOffset) + { + usActualHLen = usMPDUDOffset - ucMPDUHOffset; + } + + vosStatus = WLANTL_Translate80211To8023Header( vosDataBuff, &vosStatus, usActualHLen, + ucMPDUHLen, pTLCb, ucSTAId, bForwardIAPPwithLLC); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Failed to translate from 802.11 to 802.3 - dropping")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return vosStatus; + } + } + /*------------------------------------------------------------------- + Increment receive counter + -------------------------------------------------------------------*/ + if ( !WLANTL_TID_INVALID( ucTid) ) + { + pClientSTA->auRxCount[ucTid]++; + } + else + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid tid %d (Station ID %d) on %s", + ucTid, ucSTAId, __func__)); + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_E_FAILURE; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Sending EAPoL frame to station %d AC %d", ucSTAId, ucTid)); + + /*------------------------------------------------------------------- + !!!Assuming TID = UP mapping + -------------------------------------------------------------------*/ + wRxMetaInfo.ucUP = ucTid; + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL %s:Sending data chain to station", __func__)); + if ( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType ) + { + wRxMetaInfo.ucDesSTAId = WLAN_RX_SAP_SELF_STA_ID; + pClientSTA->pfnSTARx( pvosGCtx, vosDataBuff, ucSTAId, + &wRxMetaInfo ); + } + else + pClientSTA->pfnSTARx( pvosGCtx, vosDataBuff, ucSTAId, + &wRxMetaInfo ); + }/*EAPOL frame or WAI frame*/ + }/*vos status success*/ + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STARxConn */ + +/*========================================================================== + FUNCTION WLANTL_FwdPktToHDD + + DESCRIPTION + Determine the Destation Station ID and route the Frame to Upper Layer + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the rx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_FwdPktToHDD +( + v_PVOID_t pvosGCtx, + vos_pkt_t* pvosDataBuff, + v_U8_t ucSTAId +) +{ + v_MACADDR_t DestMacAddress; + v_MACADDR_t *pDestMacAddress = &DestMacAddress; + v_SIZE_t usMacAddSize = VOS_MAC_ADDR_SIZE; + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + vos_pkt_t* vosDataBuff ; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U32_t* STAMetaInfoPtr; + vos_pkt_t* vosNextDataBuff ; + v_U8_t ucDesSTAId; + WLANTL_RxMetaInfoType wRxMetaInfo; + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pvosDataBuff ) || ( NULL == ( vosDataBuff = pvosDataBuff ))) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_FwdPktToHdd")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_FwdPktToHdd")); + return VOS_STATUS_E_FAULT; + } + + if(WLANTL_STA_ID_INVALID(ucSTAId)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"ucSTAId %d is not valid", + ucSTAId)); + return VOS_STATUS_E_INVAL; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /* This the change required for SoftAp to handle Reordered Buffer. Since a STA + may have packets destined to multiple destinations we have to process each packet + at a time and determine its Destination. So the Voschain provided by Reorder code + is unchain and forwarded to Upper Layer after Determining the Destination */ + + vosDataBuff = pvosDataBuff; + while (vosDataBuff != NULL) + { + vos_pkt_walk_packet_chain( vosDataBuff, &vosNextDataBuff, 1/*true*/ ); + vos_pkt_get_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t *)&STAMetaInfoPtr ); + wRxMetaInfo.ucUP = (v_U8_t)((uintptr_t)STAMetaInfoPtr & WLANTL_AC_MASK); + ucDesSTAId = (v_U8_t)(((uintptr_t)STAMetaInfoPtr) >> WLANTL_STAID_OFFSET); + + vosStatus = vos_pkt_extract_data( vosDataBuff, 0, (v_VOID_t *)pDestMacAddress, &usMacAddSize); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: recv corrupted data packet")); + vos_pkt_return_packet(vosDataBuff); + return vosStatus; + } + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "station mac "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(pDestMacAddress->bytes))); + + if (vos_is_macaddr_broadcast( pDestMacAddress ) || vos_is_macaddr_group(pDestMacAddress)) + { + // destination is mc/bc station + ucDesSTAId = WLAN_RX_BCMC_STA_ID; + TLLOG4(VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s: BC/MC packet, id %d", __func__, WLAN_RX_BCMC_STA_ID)); + } + else + { + if (vos_is_macaddr_equal(pDestMacAddress, &pClientSTA->wSTADesc.vSelfMACAddress)) + { + // destination is AP itself + ucDesSTAId = WLAN_RX_SAP_SELF_STA_ID; + TLLOG4(VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s: packet to AP itself, id %d", __func__, WLAN_RX_SAP_SELF_STA_ID)); + } + else if (( WLAN_MAX_STA_COUNT <= ucDesSTAId ) || (NULL != pTLCb->atlSTAClients[ucDesSTAId] && pTLCb->atlSTAClients[ucDesSTAId]->ucExists == 0)) + { + // destination station is something else + TLLOG4(VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_INFO_LOW, + "%s: get an station index larger than WLAN_MAX_STA_COUNT %d", __func__, ucDesSTAId)); + ucDesSTAId = WLAN_RX_SAP_SELF_STA_ID; + } + + + //loopback unicast station comes here + } + + wRxMetaInfo.ucUP = (v_U8_t)((uintptr_t)STAMetaInfoPtr & WLANTL_AC_MASK); + wRxMetaInfo.ucDesSTAId = ucDesSTAId; + + vosStatus = pClientSTA->pfnSTARx( pvosGCtx, vosDataBuff, ucDesSTAId, + &wRxMetaInfo ); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: failed to send pkt to HDD")); + vos_pkt_return_packet(vosDataBuff); + + return vosStatus; + } + vosDataBuff = vosNextDataBuff; + } + return VOS_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +void WLANTL_StopRxRateMonitor(v_PVOID_t pvosGCtx) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (!pTLCb) + return; + pTLCb->gDsRxRoamStats.running = eWLAN_PAL_FALSE; +} + +void WLANTL_StartRxRateMonitor(v_PVOID_t pvosGCtx, v_U8_t staId, + v_U16_t minRate, + v_U16_t maxRate, v_U8_t minPercentage, + v_U16_t minPktRequired, void *hHal, + v_U64_t timeToWait, + void (*triggerRoamScanfn) (void *, v_U8_t)) +{ + + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (!pTLCb) + return; + + pTLCb->gDsRxRoamStats.running = eWLAN_PAL_TRUE; + pTLCb->gDsRxRoamStats.index = 0; + pTLCb->gDsRxRoamStats.lastTriggerTime = jiffies_to_msecs(jiffies); + pTLCb->gDsRxRoamStats.maxRate = maxRate; + pTLCb->gDsRxRoamStats.minRate = minRate; + pTLCb->gDsRxRoamStats.staId = staId; + pTLCb->gDsRxRoamStats.minPercentage = minPercentage; + pTLCb->gDsRxRoamStats.timeToWait = timeToWait * 1000; + pTLCb->gDsRxRoamStats.intialPktToStart = 0; + pTLCb->gDsRxRoamStats.minPktRequired = minPktRequired; + pTLCb->gDsRxRoamStats.triggerRoamScanfn = triggerRoamScanfn; + pTLCb->gDsRxRoamStats.hHal = hHal; + vos_mem_zero(pTLCb->gDsRxRoamStats.rxRoamStats, ROAM_MAX_INDEX_NUM * + sizeof(WLANTL_RoamTrafficStatsType)); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_DEBUG, + "staId=%d, minRate=%d maxRate=%d minPercentage=%d minPktRequired=%d", + staId, minRate, maxRate, minPercentage, minPktRequired); +} + +void static WLANTL_ClearAllRoamStats(WLANTL_CbType *pTLCb) +{ + pTLCb->gDsRxRoamStats.index = 0; + pTLCb->gDsRxRoamStats.totalPkt = 0; + pTLCb->gDsRxRoamStats.lowRatePkt = 0; + pTLCb->gDsRxRoamStats.intialPktToStart = 0; + vos_mem_zero(pTLCb->gDsRxRoamStats.rxRoamStats, ROAM_MAX_INDEX_NUM * + sizeof(WLANTL_RoamTrafficStatsType)); +} + +/* + * WLANTL_ClearRoamStatsTillIndex : This API will clear older data + * at the indexes. + * + * Since its a circular buffer we don't know if we are filling + * data first time or some older data was already present at + * the index. In that case we should clear the older data from + * current index to new index and subtract this data from + * global count as well before filling new one. + */ +static inline void WLANTL_ClearRoamStatsTillIndex(WLANTL_CbType *pTLCb, + v_U8_t newIndex) +{ + while (pTLCb->gDsRxRoamStats.index < newIndex) + { + pTLCb->gDsRxRoamStats.index++; + pTLCb->gDsRxRoamStats.totalPkt -= + pTLCb->gDsRxRoamStats. + rxRoamStats[pTLCb->gDsRxRoamStats.index].totalPktRcvd; + pTLCb->gDsRxRoamStats.lowRatePkt -= + pTLCb->gDsRxRoamStats. + rxRoamStats[pTLCb->gDsRxRoamStats.index].lowRateRxPacketsRcvd; + pTLCb->gDsRxRoamStats. + rxRoamStats[pTLCb->gDsRxRoamStats.index].totalPktRcvd = 0; + pTLCb->gDsRxRoamStats. + rxRoamStats[pTLCb->gDsRxRoamStats.index].lowRateRxPacketsRcvd = 0; + } +} + + +static void WLANTL_ClearOldPERStats(WLANTL_CbType *pTLCb, v_U8_t incrementCnt) +{ + v_U8_t newIndex; + + newIndex = (pTLCb->gDsRxRoamStats.index + incrementCnt) % + ROAM_MAX_INDEX_NUM; + + /* We have crossed the max limit of buffer, clear the stats + * till ROAM_MAX_INDEX_NUM and set index as 0 */ + if ((pTLCb->gDsRxRoamStats.index + incrementCnt) >= + ROAM_MAX_INDEX_NUM) + { + WLANTL_ClearRoamStatsTillIndex(pTLCb, ROAM_MAX_INDEX_NUM - 1); + pTLCb->gDsRxRoamStats.index = -1; + } + /* Clear the stats from current index till new index */ + WLANTL_ClearRoamStatsTillIndex(pTLCb, newIndex); +} + +/* + * This API implements a circular buffer to store rate stats for a station to + * trigger PER based roam scan. + * API will start monitoring only if DUT gets continues packets which are below + * configured rate. In the upper rates, this should have minimal effect on data + * throughput. + * + * This API will store stats in a circular buffer of size ROAM_MAX_INDEX_NUM + * where each index will have time duration of ROAM_PER_INDEX_TIME. + * Using a buffer instead of counter will help to maintain stats of time + * duration ROAM_PER_INDEX_TIME * ROAM_MAX_INDEX_NUM. Whenever host gets a new + * packet, it will remove last ROAM_PER_INDEX_TIME duration of packets from + * global entry and index entry and fill new data. + * + * Global stats of data also be maintained so that host need not to parse whole + * buffer while checking the trigger condition + * Each of the index will be having the packets stats at duration of + * ROAM_PER_INDEX_TIME from the first packet which arrived in that. + * Global index will be used to calculate new index position to fill once host + * gets a packet. + */ +static void WLANTL_updatePERStats(WLANTL_CbType *pTLCb, + v_U8_t rateIndex) +{ + v_U8_t incrementCnt = 0; + v_U64_t currentTime, timeDifference; + + /* + * Host will start monitoring Rx rates only if it gets + * MIN_PKTS_TO_START_MONTIOR number of pkts continuously below min rate + * This will make sure we never do this much processing in high + * rates/throughput cases + */ + + if(pTLCb->gDsRxRoamStats.intialPktToStart < MIN_PKTS_TO_START_MONTIOR) + { + if (gTLRateInfo[rateIndex].phyRate < pTLCb->gDsRxRoamStats.minRate) + pTLCb->gDsRxRoamStats.intialPktToStart++; + else + pTLCb->gDsRxRoamStats.intialPktToStart = 0; + return; + } + + currentTime = jiffies_to_msecs(jiffies); + /* + * scan was triggered in last timeToWait time duration + * Wait for timeToWait before monitoring again. + */ + if((currentTime - pTLCb->gDsRxRoamStats.lastTriggerTime) < + pTLCb->gDsRxRoamStats.timeToWait) + return; + + /* paket above max rate, clear current stats and montior again */ + if (gTLRateInfo[rateIndex].phyRate >= + pTLCb->gDsRxRoamStats.maxRate) + { + WLANTL_ClearAllRoamStats(pTLCb); + /* Stop any PER based scan if going on */ + pTLCb->gDsRxRoamStats. + triggerRoamScanfn(pTLCb->gDsRxRoamStats.hHal, 0); + return; + } + + timeDifference = currentTime - + pTLCb->gDsRxRoamStats.rxRoamStats[pTLCb->gDsRxRoamStats.index].time; + + if (timeDifference) + incrementCnt = do_div(timeDifference, ROAM_PER_INDEX_TIME); + + /* More that ROAM_PER_INDEX_TIME has esclapsed, + * fill data at new index */ + if (incrementCnt) + { + if (incrementCnt > ROAM_MAX_INDEX_NUM) + { + /* + * Clear all stats, these are older than + * ROAM_MAX_INDEX_NUM * ROAM_PER_INDEX_TIME (Max buffer time) + */ + WLANTL_ClearAllRoamStats(pTLCb); + pTLCb->gDsRxRoamStats.index = 0; + } + else + WLANTL_ClearOldPERStats(pTLCb, incrementCnt); + + pTLCb->gDsRxRoamStats.rxRoamStats + [pTLCb->gDsRxRoamStats.index].time = currentTime; + } + + /* If pkt rate below minRate, increment low pkts counts */ + if (gTLRateInfo[rateIndex].phyRate < + pTLCb->gDsRxRoamStats.minRate) + { + pTLCb->gDsRxRoamStats. + rxRoamStats[pTLCb->gDsRxRoamStats.index]. + lowRateRxPacketsRcvd++; + pTLCb->gDsRxRoamStats.lowRatePkt++; + } + /* Increment total pkts counts */ + pTLCb->gDsRxRoamStats. + rxRoamStats[pTLCb->gDsRxRoamStats.index].totalPktRcvd++; + pTLCb->gDsRxRoamStats.totalPkt++; + + /* Check if we have reached threshold value to trigger a roam scan */ + if ((pTLCb->gDsRxRoamStats.totalPkt != 0) && + (pTLCb->gDsRxRoamStats.totalPkt > + pTLCb->gDsRxRoamStats.minPktRequired)&& + ((pTLCb->gDsRxRoamStats.lowRatePkt * 100) > + (pTLCb->gDsRxRoamStats.totalPkt * + pTLCb->gDsRxRoamStats.minPercentage))) + { + /* callback handler to trigger a roam scan */ + if (pTLCb->gDsRxRoamStats.triggerRoamScanfn) + pTLCb->gDsRxRoamStats. + triggerRoamScanfn(pTLCb->gDsRxRoamStats.hHal, 1); + + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_DEBUG, + "PER Roam: triggerring roam scan totalPkt =%lu lowRatePkt %lu minPktRequired %u minPercentage %d", + (long unsigned int) pTLCb->gDsRxRoamStats.totalPkt, + (long unsigned int) pTLCb->gDsRxRoamStats.lowRatePkt, + (unsigned int) pTLCb->gDsRxRoamStats.minPktRequired, + pTLCb->gDsRxRoamStats.minPercentage); + + WLANTL_ClearAllRoamStats(pTLCb); + /* save current time as last trigger time */ + pTLCb->gDsRxRoamStats.lastTriggerTime = currentTime; + } +} +#endif + +/*========================================================================== + FUNCTION WLANTL_STARxAuth + + DESCRIPTION + Receive in authenticated state - all data allowed + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the rx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STARxAuth +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + v_U8_t ucAsf; /* AMSDU sub frame */ + v_U16_t usMPDUDOffset; + v_U8_t ucMPDUHOffset; + v_U16_t usMPDULen; + v_U8_t ucMPDUHLen; + v_U16_t usActualHLen = 0; + v_U8_t ucTid; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + v_U8_t rxRate; + v_U8_t type; +#endif +#ifdef FEATURE_WLAN_WAPI + v_U16_t usEtherType = 0; + tSirMacMgmtHdr *hdr; +#endif + v_U16_t usPktLen; + vos_pkt_t* vosDataBuff ; + v_PVOID_t aucBDHeader; + VOS_STATUS vosStatus; + WLANTL_RxMetaInfoType wRxMetaInfo; + static v_U8_t ucPMPDUHLen; + v_U32_t* STAMetaInfoPtr; + v_U8_t ucEsf=0; /* first subframe of AMSDU flag */ + v_U64_t ullcurrentReplayCounter=0; /*current replay counter*/ + v_U64_t ullpreviousReplayCounter=0; /*previous replay counter*/ + v_U16_t ucUnicastBroadcastType=0; /*It denotes whether received frame is UC or BC*/ + struct _BARFrmStruct *pBarFrame = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pvosDataBuff ) || ( NULL == ( vosDataBuff = *pvosDataBuff ))) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_STARxAuth")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_STARxAuth")); + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Extract BD header and check if valid + ------------------------------------------------------------------------*/ + WDA_DS_PeekRxPacketInfo( vosDataBuff, (v_PVOID_t)&aucBDHeader, 0 ); + + ucMPDUHOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(aucBDHeader); + usMPDUDOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(aucBDHeader); + usMPDULen = (v_U16_t)WDA_GET_RX_MPDU_LEN(aucBDHeader); + ucMPDUHLen = (v_U8_t)WDA_GET_RX_MPDU_HEADER_LEN(aucBDHeader); + ucTid = (v_U8_t)WDA_GET_RX_TID(aucBDHeader); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + rxRate = (v_U8_t)WDA_GET_RX_MAC_RATE_IDX(aucBDHeader); + type = (v_U8_t)WDA_GET_RX_TYPE(aucBDHeader); +#endif + + /* Fix for a hardware bug. + * H/W does not update the tid field in BD header for BAR frames. + * Fix is to read the tid field from MAC header of BAR frame */ + if( (WDA_GET_RX_TYPE(aucBDHeader) == SIR_MAC_CTRL_FRAME) && + (WDA_GET_RX_SUBTYPE(aucBDHeader) == SIR_MAC_CTRL_BAR)) + { + pBarFrame = (struct _BARFrmStruct *)(WDA_GET_RX_MAC_HEADER(aucBDHeader)); + ucTid = pBarFrame->barControl.numTID; + } + + /*Host based replay check is needed for unicast data frames*/ + ucUnicastBroadcastType = (v_U16_t)WDA_IS_RX_BCAST(aucBDHeader); + if(0 != ucMPDUHLen) + { + ucPMPDUHLen = ucMPDUHLen; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d" + " Tid %d BD %d", + ucMPDUHOffset, usMPDUDOffset, usMPDULen, ucMPDUHLen, ucTid, + WLANHAL_RX_BD_HEADER_SIZE)); + + vos_pkt_get_packet_length( vosDataBuff, &usPktLen); + + if ( VOS_STATUS_SUCCESS != WDA_DS_TrimRxPacketInfo( vosDataBuff ) ) + { + if((WDA_GET_RX_ASF(aucBDHeader) && !WDA_GET_RX_ESF(aucBDHeader))) + { + /* AMSDU case, ucMPDUHOffset = 0 + * it should be hancdled seperatly */ + if(( usMPDUDOffset > ucMPDUHOffset ) && + ( usMPDULen >= ucMPDUHLen ) && ( usPktLen >= usMPDULen ) && + ( !WLANTL_TID_INVALID(ucTid) )) + { + ucMPDUHOffset = usMPDUDOffset - WLANTL_MPDU_HEADER_LEN; + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:BD header corrupted - dropping packet")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; + } + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:BD header corrupted - dropping packet")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; + } + } + +#ifdef WLAN_FEATURE_RMC + if (pTLCb->multicastDuplicateDetectionEnabled && + (WLAN_STA_IBSS == pClientSTA->wSTADesc.wSTAType) && + WLANTL_IS_DATA_FRAME(WDA_GET_RX_TYPE_SUBTYPE(aucBDHeader))) + { + /* + * Multicast duplicate detection is only for frames received in + * IBSS mode. + */ + if (VOS_TRUE == WLANTL_IsDuplicateMcastFrm(pClientSTA, vosDataBuff)) + { + pTLCb->mcastDupCnt++; + /* Duplicate multicast data packet, drop the packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; + } + } +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_WAPI + if ( pClientSTA->wSTADesc.ucIsWapiSta ) + { + vosStatus = WLANTL_GetEtherType(aucBDHeader, vosDataBuff, ucMPDUHLen, &usEtherType); + if( VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + if ( WLANTL_LLC_WAI_TYPE == usEtherType ) + { + hdr = WDA_GET_RX_MAC_HEADER(aucBDHeader); + if ( hdr->fc.wep ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:WAI frame was received encrypted - dropping")); + /* Drop packet */ + /*Temporary fix added to fix wapi rekey issue*/ + vos_pkt_return_packet(vosDataBuff); + return vosStatus; //returning success + } + } + else + { + if ( WLANHAL_RX_IS_UNPROTECTED_WPI_FRAME(aucBDHeader) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Non-WAI frame was received unencrypted - dropping")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return vosStatus; //returning success + } + } + } + else //could not extract EtherType - this should not happen + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Could not extract EtherType")); + //Packet is already freed + return vosStatus; //returning failure + } + } +#endif /* FEATURE_WLAN_WAPI */ + + /*---------------------------------------------------------------------- + Increment receive counter + !! not sure this is the best place to increase this - pkt might be + dropped below or delayed in TL's queues + - will leave it here for now + ------------------------------------------------------------------------*/ + if ( !WLANTL_TID_INVALID( ucTid) ) + { + pClientSTA->auRxCount[ucTid]++; + } + else + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid tid %d (Station ID %d) on %s", + ucTid, ucSTAId, __func__)); + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_E_FAILURE; + } + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + if (pTLCb->gDsRxRoamStats.running && + (ucSTAId == pTLCb->gDsRxRoamStats.staId) && + (rxRate < WLANTL_MAX_RATE_NUM) && (type == SIR_MAC_DATA_FRAME)) + { + WLANTL_updatePERStats(pTLCb, rxRate); + } +#endif + /*------------------------------------------------------------------------ + Check if AMSDU and send for processing if so + ------------------------------------------------------------------------*/ + ucAsf = (v_U8_t)WDA_GET_RX_ASF(aucBDHeader); + + if ( 0 != ucAsf ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Packet is AMSDU sub frame - sending for completion")); + vosStatus = WLANTL_AMSDUProcess( pvosGCtx, &vosDataBuff, aucBDHeader, ucSTAId, + ucMPDUHLen, usMPDULen ); + if(NULL == vosDataBuff) + { + //Packet is already freed + return VOS_STATUS_SUCCESS; + } + } + /* After AMSDU header handled + * AMSDU frame just same with normal frames */ + /*------------------------------------------------------------------- + Translating header if necesary + !! Fix me: rmv comments below + ----------------------------------------------------------------------*/ + if (( 0 == WDA_GET_RX_FT_DONE(aucBDHeader) ) && + ( 0 != pClientSTA->wSTADesc.ucSwFrameRXXlation) && + ( WLANTL_IS_DATA_FRAME(WDA_GET_RX_TYPE_SUBTYPE(aucBDHeader)) )) + { + if(0 == ucMPDUHLen) + { + ucMPDUHLen = ucPMPDUHLen; + } + if (usMPDUDOffset > ucMPDUHOffset) + { + usActualHLen = usMPDUDOffset - ucMPDUHOffset; + } + vosStatus = WLANTL_Translate80211To8023Header( vosDataBuff, &vosStatus, usActualHLen, + ucMPDUHLen, pTLCb, ucSTAId, bForwardIAPPwithLLC); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Failed to translate from 802.11 to 802.3 - dropping")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + return vosStatus; + } + } + /* Softap requires additional Info such as Destination STAID and Access + Category. Voschain or Buffer returned by BA would be unchain and this + Meta Data would help in routing the packets to appropriate Destination */ + if( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType) + { + STAMetaInfoPtr = (v_U32_t *)(uintptr_t)(ucTid | (WDA_GET_RX_ADDR3_IDX(aucBDHeader) << WLANTL_STAID_OFFSET)); + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)STAMetaInfoPtr); + } + + /*------------------------------------------------------------------------ + Check to see if re-ordering session is in place + ------------------------------------------------------------------------*/ + if ( 0 != pClientSTA->atlBAReorderInfo[ucTid].ucExists ) + { + WLANTL_MSDUReorder( pTLCb, &vosDataBuff, aucBDHeader, ucSTAId, ucTid ); + } + +if(0 == ucUnicastBroadcastType +#ifdef FEATURE_ON_CHIP_REORDERING + && (WLANHAL_IsOnChipReorderingEnabledForTID(pvosGCtx, ucSTAId, ucTid) != TRUE) +#endif +) +{ + /* replay check code : check whether replay check is needed or not */ + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + /* replay check is needed for the station */ + + /* check whether frame is AMSDU frame */ + if ( 0 != ucAsf ) + { + /* Since virgo can't send AMSDU frames this leg of the code + was not tested properly, it needs to be tested properly*/ + /* Frame is AMSDU frame. As per 802.11n only first + subframe will have replay counter */ + ucEsf = WDA_GET_RX_ESF( aucBDHeader ); + if( 0 != ucEsf ) + { + v_BOOL_t status; + /* Getting 48-bit replay counter from the RX BD */ + ullcurrentReplayCounter = WDA_DS_GetReplayCounter(aucBDHeader); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: AMSDU currentReplayCounter [0x%llX]",ullcurrentReplayCounter); + + /* Getting 48-bit previous replay counter from TL control block */ + ullpreviousReplayCounter = pClientSTA->ullReplayCounter[ucTid]; + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: AMSDU previousReplayCounter [0x%llX]",ullpreviousReplayCounter); + + /* It is first subframe of AMSDU thus it + conatains replay counter perform the + replay check for this first subframe*/ + status = WLANTL_IsReplayPacket( ullcurrentReplayCounter, ullpreviousReplayCounter); + if(VOS_FALSE == status) + { + /* Not a replay paket, update previous replay counter in TL CB */ + pClientSTA->ullReplayCounter[ucTid] = ullcurrentReplayCounter; + } + else + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: AMSDU Drop the replay packet with PN : [0x%llX]",ullcurrentReplayCounter); + + pClientSTA->ulTotalReplayPacketsDetected++; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: AMSDU total dropped replay packets on STA ID %X is [0x%X]", + ucSTAId, pClientSTA->ulTotalReplayPacketsDetected); + + /* Drop the packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; + } + } + } + else + { + v_BOOL_t status; + + /* Getting 48-bit replay counter from the RX BD */ + ullcurrentReplayCounter = WDA_DS_GetReplayCounter(aucBDHeader); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: Non-AMSDU currentReplayCounter [0x%llX]",ullcurrentReplayCounter); + + /* Getting 48-bit previous replay counter from TL control block */ + ullpreviousReplayCounter = pClientSTA->ullReplayCounter[ucTid]; + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: Non-AMSDU previousReplayCounter [0x%llX]",ullpreviousReplayCounter); + + /* It is not AMSDU frame so perform + reaply check for each packet, as + each packet contains valid replay counter*/ + status = WLANTL_IsReplayPacket( ullcurrentReplayCounter, ullpreviousReplayCounter); + if(VOS_FALSE == status) + { + /* Not a replay paket, update previous replay counter in TL CB */ + pClientSTA->ullReplayCounter[ucTid] = ullcurrentReplayCounter; + } + else + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Non-AMSDU Drop the replay packet with PN : [0x%llX]",ullcurrentReplayCounter); + + pClientSTA->ulTotalReplayPacketsDetected++; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Non-AMSDU total dropped replay packets on STA ID %X is [0x%X]", + ucSTAId, pClientSTA->ulTotalReplayPacketsDetected); + + /* Repaly packet, drop the packet */ + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; + } + } + } +} +/*It is a broadast packet DPU has already done replay check for + broadcast packets no need to do replay check of these packets*/ + + if ( NULL != vosDataBuff ) + { + if( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType) + { + WLANTL_FwdPktToHDD( pvosGCtx, vosDataBuff, ucSTAId ); + } + else + { + wRxMetaInfo.ucUP = ucTid; + wRxMetaInfo.rssiAvg = pClientSTA->rssiAvg; +#ifdef FEATURE_WLAN_TDLS + if (WLAN_STA_TDLS == pClientSTA->wSTADesc.wSTAType) + { + wRxMetaInfo.isStaTdls = TRUE; + } + else + { + wRxMetaInfo.isStaTdls = FALSE; + } +#endif + pClientSTA->pfnSTARx( pvosGCtx, vosDataBuff, ucSTAId, + &wRxMetaInfo ); + } + }/* if not NULL */ + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STARxAuth */ + + +/*========================================================================== + FUNCTION WLANTL_STARxDisc + + DESCRIPTION + Receive in disconnected state - no data allowed + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the rx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_STARxDisc +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pvosDataBuff ) || ( NULL == *pvosDataBuff )) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_STARxDisc")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Error - drop packet + ------------------------------------------------------------------------*/ + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Packet should not be received in state disconnected" + " - dropping")); + vos_pkt_return_packet(*pvosDataBuff); + *pvosDataBuff = NULL; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_STARxDisc */ + +/*========================================================================== + Processing main loops for MAIN and TX threads + ==========================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_McProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + main thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_McProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +) +{ + WLANTL_CbType* pTLCb = NULL; + tAddBAInd* ptAddBaInd = NULL; + tDelBAInd* ptDelBaInd = NULL; + tAddBARsp* ptAddBaRsp = NULL; + vos_msg_t vosMessage; + VOS_STATUS vosStatus; + tpFlushACRsp FlushACRspPtr; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == message ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_ProcessMainMessage")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_ProcessMainMessage")); + return VOS_STATUS_E_FAULT; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Received message: %d through main flow", message->type)); + + switch( message->type ) + { + case WDA_TL_FLUSH_AC_RSP: + // Extract the message from the message body + FlushACRspPtr = (tpFlushACRsp)(message->bodyptr); + // Make sure the call back function is not null. + if ( NULL == pTLCb->tlBAPClient.pfnFlushOpCompleteCb ) + { + VOS_ASSERT(0); + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer pfnFlushOpCompleteCb")); + return VOS_STATUS_E_FAULT; + } + + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Received message: Flush complete received by TL")); + + // Since we have the response back from HAL, just call the BAP client + // registered call back from TL. There is only 1 possible + // BAP client. So directly reference tlBAPClient + pTLCb->tlBAPClient.pfnFlushOpCompleteCb( pvosGCtx, + FlushACRspPtr->ucSTAId, + FlushACRspPtr->ucTid, FlushACRspPtr->status ); + + // Free the PAL memory, we are done with it. + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Flush complete received by TL: Freeing %p", FlushACRspPtr)); + vos_mem_free((v_VOID_t *)FlushACRspPtr); + break; + + case WDA_HDD_ADDBA_REQ: + ptAddBaInd = (tAddBAInd*)(message->bodyptr); + vosStatus = WLANTL_BaSessionAdd( pvosGCtx, + ptAddBaInd->baSession.baSessionID, + ptAddBaInd->baSession.STAID, + ptAddBaInd->baSession.baTID, + (v_U32_t)ptAddBaInd->baSession.baBufferSize, + ptAddBaInd->baSession.winSize, + ptAddBaInd->baSession.SSN); + ptAddBaRsp = vos_mem_malloc(sizeof(*ptAddBaRsp)); + + if ( NULL == ptAddBaRsp ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: fatal failure, cannot allocate BA Rsp structure")); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + if ( VOS_STATUS_SUCCESS == vosStatus ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Sending success indication to HAL for ADD BA")); + /*Send success*/ + ptAddBaRsp->mesgType = WDA_HDD_ADDBA_RSP; + vosMessage.type = WDA_HDD_ADDBA_RSP; + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Sending failure indication to HAL for ADD BA")); + + /*Send failure*/ + ptAddBaRsp->mesgType = WDA_BA_FAIL_IND; + vosMessage.type = WDA_BA_FAIL_IND; + } + + ptAddBaRsp->mesgLen = sizeof(tAddBARsp); + ptAddBaRsp->baSessionID = ptAddBaInd->baSession.baSessionID; + /* This is default, reply win size has to be handled BA module, FIX THIS */ + ptAddBaRsp->replyWinSize = WLANTL_MAX_WINSIZE; + vosMessage.bodyptr = ptAddBaRsp; + + vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage ); + WLANTL_McFreeMsg (pvosGCtx, message); + break; + case WDA_DELETEBA_IND: + ptDelBaInd = (tDelBAInd*)(message->bodyptr); + vosStatus = WLANTL_BaSessionDel(pvosGCtx, + ptDelBaInd->staIdx, + ptDelBaInd->baTID); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to del BA session STA:%d TID:%d Status :%d", + ptDelBaInd->staIdx, + ptDelBaInd->baTID, + vosStatus)); + } + WLANTL_McFreeMsg (pvosGCtx, message); + break; + default: + /*no processing for now*/ + break; + } + + return VOS_STATUS_SUCCESS; +}/* WLANTL_ProcessMainMessage */ + +/*========================================================================== + FUNCTION WLANTL_McFreeMsg + + DESCRIPTION + Called by VOSS to free a given TL message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + For now, TL does not allocate any body so this function shout translate + into a NOOP + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_McFreeMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == message ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_McFreeMsg")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_McFreeMsg")); + return VOS_STATUS_E_FAULT; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Received message: %d through main free", message->type)); + + switch( message->type ) + { + case WDA_HDD_ADDBA_REQ: + case WDA_DELETEBA_IND: + /*vos free body pointer*/ + vos_mem_free(message->bodyptr); + message->bodyptr = NULL; + break; + default: + /*no processing for now*/ + break; + } + + return VOS_STATUS_SUCCESS; +}/*WLANTL_McFreeMsg*/ + +/*========================================================================== + FUNCTION WLANTL_TxProcessMsg + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + tx thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxProcessMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + void (*callbackRoutine) (void *callbackContext); + void *callbackContext; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == message ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_ProcessTxMessage")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Process message + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Received message: %d through tx flow", message->type)); + + switch( message->type ) + { + case WLANTL_TX_SIG_SUSPEND: + vosStatus = WLANTL_SuspendCB( pvosGCtx, + (WLANTL_SuspendCBType)message->bodyptr, + message->reserved); + break; + case WLANTL_TX_RES_NEEDED: + vosStatus = WLANTL_GetTxResourcesCB( pvosGCtx ); + break; + + case WDA_DS_TX_START_XMIT: + WLANTL_ClearTxXmitPending(pvosGCtx); + vosStatus = WDA_DS_TxFrames( pvosGCtx ); + break; + + case WDA_DS_FINISH_ULA: + callbackContext = message->bodyptr; + callbackRoutine = message->callback; + if ( NULL != callbackRoutine ) + { + callbackRoutine(callbackContext); + } + break; + + case WLANTL_TX_SNAPSHOT: + /*Dumping TL State and then continuing to print + the DXE Dump*/ + WLANTL_TxThreadDebugHandler(pvosGCtx); + WDA_TransportChannelDebug(NULL, VOS_TRUE, VOS_FALSE); + break; + + case WLANTL_TX_FATAL_ERROR: + WLANTL_FatalErrorHandler(pvosGCtx); + break; + + case WLANTL_TX_FW_DEBUG: + vos_fwDumpReq(274, 0, 0, 0, 0, 1); //Async event + break; + + case WLANTL_TX_KICKDXE: + WDA_TransportKickDxe(); + break; + + default: + /*no processing for now*/ + break; + } + + return vosStatus; +}/* WLANTL_TxProcessMsg */ + +/*========================================================================== + FUNCTION WLANTL_McFreeMsg + + DESCRIPTION + Called by VOSS to free a given TL message on the Main thread when there + are messages pending in the queue when the whole system is been reset. + For now, TL does not allocate any body so this function shout translate + into a NOOP + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxFreeMsg +( + v_PVOID_t pvosGCtx, + vos_msg_t* message +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*Nothing to do for now!!!*/ + return VOS_STATUS_SUCCESS; +}/*WLANTL_TxFreeMsg*/ + +/*========================================================================== + + FUNCTION WLANTL_TxFCFrame + + DESCRIPTION + Internal utility function to send FC frame. Enable + or disable LWM mode based on the information. + + DEPENDENCIES + TL must be initiailized before this function gets called. + FW sends up special flow control frame. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input pointers are NULL. + VOS_STATUS_E_FAULT: Something is wrong. + VOS_STATUS_SUCCESS: Everything is good. + + SIDE EFFECTS + Newly formed FC frame is generated and waits to be transmitted. Previously unsent frame will + be released. + +============================================================================*/ +VOS_STATUS +WLANTL_TxFCFrame +( + v_PVOID_t pvosGCtx +) +{ +#if 0 + WLANTL_CbType* pTLCb = NULL; + VOS_STATUS vosStatus; + tpHalFcTxBd pvFcTxBd = NULL; + vos_pkt_t * pPacket = NULL; + v_U8_t ucSTAId = 0; + v_U8_t ucBitCheck = 1; + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: Send FC frame %s", __func__); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pvosGCtx ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter %s", __func__)); + return VOS_STATUS_E_INVAL; + } + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid pointer in %s \n", __func__)); + return VOS_STATUS_E_INVAL; + } + + //Get one voss packet + vosStatus = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT, sizeof(tHalFcTxBd), 1, + VOS_FALSE, NULL, NULL ); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + return VOS_STATUS_E_INVAL; + } + + vosStatus = vos_pkt_reserve_head( pPacket, (void *)&pvFcTxBd, sizeof(tHalFcTxBd)); + + if( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: failed to reserve FC TX BD %d\n",__func__, sizeof(tHalFcTxBd))); + vos_pkt_return_packet( pPacket ); + return VOS_STATUS_E_FAULT; + } + + //Generate most recent tlFCInfo. Most fields are correct. + pTLCb->tlFCInfo.fcSTAThreshEnabledMask = 0; + pTLCb->tlFCInfo.fcSTATxMoreDataMask = 0; + for( ucSTAId = 0, ucBitCheck = 1 ; ucSTAId < WLAN_MAX_STA_COUNT; ucBitCheck <<= 1, ucSTAId ++) + { + if (0 == pTLCb->atlSTAClients[ucSTAId].ucExists) + { + continue; + } + + if (pTLCb->atlSTAClients[ucSTAId].ucPktPending) + { + pTLCb->tlFCInfo.fcSTATxMoreDataMask |= ucBitCheck; + } + + if ( (pTLCb->atlSTAClients[ucSTAId].ucLwmModeEnabled) && + (pTLCb->atlSTAClients[ucSTAId].bmuMemConsumed > pTLCb->atlSTAClients[ucSTAId].uLwmThreshold)) + { + pTLCb->tlFCInfo.fcSTAThreshEnabledMask |= ucBitCheck; + + pTLCb->tlFCInfo.fcSTAThresh[ucSTAId] = (tANI_U8)pTLCb->atlSTAClients[ucSTAId].uLwmThreshold; + + pTLCb->atlSTAClients[ucSTAId].ucLwmEventReported = FALSE; + } + + } + + //request immediate feedback + pTLCb->tlFCInfo.fcConfig |= 0x4; + + //fill in BD to sent + vosStatus = WLANHAL_FillFcTxBd(pvosGCtx, &pTLCb->tlFCInfo, (void *)pvFcTxBd); + + if( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Fill FC TX BD unsuccessful\n", __func__)); + vos_pkt_return_packet( pPacket ); + return VOS_STATUS_E_FAULT; + } + + if (NULL != pTLCb->vosTxFCBuf) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Previous FC TX BD not sent\n", __func__)); + vos_pkt_return_packet(pTLCb->vosTxFCBuf); + } + + pTLCb->vosTxFCBuf = pPacket; + + vos_pkt_set_user_data_ptr( pPacket, VOS_PKT_USER_DATA_ID_TL, + (v_PVOID_t)WLANTL_TxCompDefaultCb); + vosStatus = WDA_DS_StartXmit(pvosGCtx); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: send FC frame leave %s", __func__)); +#endif + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION WLANTL_GetTxResourcesCB + + DESCRIPTION + Processing function for Resource needed signal. A request will be issued + to BAL to get more tx resources. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetTxResourcesCB +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U32_t uResCount = WDA_TLI_MIN_RES_DATA; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_U8_t ucMgmt = 0; + v_U8_t ucBAP = 0; + v_U8_t ucData = 0; +#ifdef WLAN_SOFTAP_FLOWCTRL_EN + tBssSystemRole systemRole; + tpAniSirGlobal pMac; +#endif + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on" + " WLANTL_ProcessTxMessage")); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Get tx resources from BAL + ------------------------------------------------------------------------*/ + vosStatus = WDA_DS_GetTxResources( pvosGCtx, &uResCount ); + + if ( (VOS_STATUS_SUCCESS != vosStatus) && (VOS_STATUS_E_RESOURCES != vosStatus)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:TL failed to get resources from BAL, Err: %d", + vosStatus)); + return vosStatus; + } + + /* Currently only Linux BAL returns the E_RESOURCES error code when it is running + out of BD/PDUs. To make use of this interrupt for throughput enhancement, similar + changes should be done in BAL code of AMSS and WM */ + if (VOS_STATUS_E_RESOURCES == vosStatus) + { +#ifdef VOLANS_PERF + WLANHAL_EnableIdleBdPduInterrupt(pvosGCtx, (tANI_U8)bdPduInterruptGetThreshold); + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Enabling Idle BD/PDU interrupt, Current resources = %d", uResCount); +#else + return VOS_STATUS_E_FAILURE; +#endif + } + + pTLCb->uResCount = uResCount; + + +#ifdef WLAN_SOFTAP_FLOWCTRL_EN + /* FIXME: disabled since creating issues in power-save, needs to be addressed */ + pTLCb->sendFCFrame ++; + pMac = vos_get_context(VOS_MODULE_ID_WDA, pvosGCtx); + systemRole = wdaGetGlobalSystemRole(pMac); + if (eSYSTEM_AP_ROLE == systemRole) + { + if (pTLCb->sendFCFrame % 16 == 0) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Transmit FC")); + WLANTL_TxFCFrame (pvosGCtx); + } + } +#endif //WLAN_SOFTAP_FLOWCTRL_EN + + ucData = ( pTLCb->uResCount >= WDA_TLI_MIN_RES_DATA ); + ucBAP = ( pTLCb->uResCount >= WDA_TLI_MIN_RES_BAP ) && + ( NULL != pTLCb->tlBAPClient.vosPendingDataBuff ); + ucMgmt = ( pTLCb->uResCount >= WDA_TLI_MIN_RES_MF ) && + ( NULL != pTLCb->tlMgmtFrmClient.vosPendingDataBuff ); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Eval Resume tx Res: %d DATA: %d BAP: %d MGMT: %d", + pTLCb->uResCount, ucData, ucBAP, ucMgmt)); + + if (( 0 == pTLCb->ucTxSuspended ) && + (( 0 != ucData ) || ( 0 != ucMgmt ) || ( 0 != ucBAP ) ) ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Issuing Xmit start request to BAL for avail res SYNC")); + vosStatus =WDA_DS_StartXmit(pvosGCtx); + } + return vosStatus; +}/*WLANTL_GetTxResourcesCB*/ + +/*========================================================================== + Utility functions + ==========================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_Translate8023To80211Header + + DESCRIPTION + Inline function for translating and 802.11 header into an 802.3 header. + + DEPENDENCIES + + + PARAMETERS + + IN + pTLCb: TL control block + IN/OUT + ucStaId: station ID. Incase of TDLS, this returns actual TDLS + station ID used + + IN/OUT + vosDataBuff: vos data buffer, will contain the new header on output + + OUT + pvosStatus: status of the operation + + RETURN VALUE + + VOS_STATUS_SUCCESS: Everything is good :) + + Other error codes might be returned from the vos api used in the function + please check those return values. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Translate8023To80211Header +( + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + WLANTL_CbType* pTLCb, + v_U8_t *pucStaId, + WLANTL_MetaInfoType *tlMetaInfo, + v_U8_t *ucWDSEnabled, + v_U8_t *extraHeadSpace +) +{ + WLANTL_8023HeaderType w8023Header; + WLANTL_80211HeaderType *pw80211Header; // Allocate an aligned BD and then fill it. + VOS_STATUS vosStatus; + v_U8_t MandatoryucHeaderSize = WLAN80211_MANDATORY_HEADER_SIZE; + v_U8_t ucHeaderSize = 0; + v_VOID_t *ppvBDHeader = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + v_U8_t ucQoSOffset = WLAN80211_MANDATORY_HEADER_SIZE; + v_U8_t ucStaId; +#ifdef FEATURE_WLAN_ESE_UPLOAD + v_BOOL_t bIAPPTxwithLLC = VOS_FALSE; + v_SIZE_t wIAPPSnapSize = WLANTL_LLC_HEADER_LEN; + v_U8_t wIAPPSnap[WLANTL_LLC_HEADER_LEN] = {0}; +#endif + *ucWDSEnabled = 0; // default WDS off. + vosStatus = vos_pkt_pop_head( vosDataBuff, &w8023Header, + sizeof(w8023Header)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Packet pop header fails on WLANTL_Translate8023To80211Header")); + return vosStatus; + } + + if( NULL == pucStaId ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Invalid pointer for StaId")); + return VOS_STATUS_E_INVAL; + } + ucStaId = *pucStaId; + pClientSTA = pTLCb->atlSTAClients[ucStaId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + +#ifdef FEATURE_WLAN_TDLS + + if ( WLAN_STA_INFRA == pTLCb->atlSTAClients[ucStaId]->wSTADesc.wSTAType + && pTLCb->ucTdlsPeerCount ) + { + v_U8_t ucIndex = 0; + for ( ucIndex = 0; ucIndex < WLAN_MAX_STA_COUNT ; ucIndex++) + { + if ( ucIndex != ucStaId && pTLCb->atlSTAClients[ucIndex] && pTLCb->atlSTAClients[ucIndex]->ucExists && + (pTLCb->atlSTAClients[ucIndex]->tlState == WLANTL_STA_AUTHENTICATED) && + (!pTLCb->atlSTAClients[ucIndex]->ucTxSuspended) && + vos_mem_compare( (void*)pTLCb->atlSTAClients[ucIndex]->wSTADesc.vSTAMACAddress.bytes, + (void*)w8023Header.vDA, 6) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL: Got a TDLS station. Using that index")); + ucStaId = ucIndex; + *pucStaId = ucStaId; + pClientSTA = pTLCb->atlSTAClients[ucStaId]; + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + break; + } + } + } +#endif + +#ifdef FEATURE_WLAN_ESE_UPLOAD +if ((0 == w8023Header.usLenType) && (pClientSTA->wSTADesc.ucIsEseSta)) +{ + vos_pkt_extract_data(vosDataBuff,0,&wIAPPSnap[0],&wIAPPSnapSize); + if (vos_mem_compare(wIAPPSnap,WLANTL_AIRONET_SNAP_HEADER,WLANTL_LLC_HEADER_LEN)) + { + /*The SNAP and the protocol type are already in the data buffer. + They are filled by the application (wpa_supplicant). So, Skip Adding LLC below.*/ + bIAPPTxwithLLC = VOS_TRUE; + } + else + { + bIAPPTxwithLLC = VOS_FALSE; + } +} +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + + if ((0 != pClientSTA->wSTADesc.ucAddRmvLLC) +#ifdef FEATURE_WLAN_ESE_UPLOAD + && (!bIAPPTxwithLLC) +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + ) + { + /* Push the length */ + vosStatus = vos_pkt_push_head(vosDataBuff, + &w8023Header.usLenType, sizeof(w8023Header.usLenType)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Packet push ether type fails on" + " WLANTL_Translate8023To80211Header")); + return vosStatus; + } + +#ifdef BTAMP_TEST + // The STA side will execute this, a hack to test BTAMP by using the + // infra setup. On real BTAMP this will come from BAP itself. + { + static v_U8_t WLANTL_BT_AMP_LLC_HEADER[] = {0xAA, 0xAA, 0x03, 0x00, 0x19, 0x58 }; + vosStatus = vos_pkt_push_head(vosDataBuff, WLANTL_BT_AMP_LLC_HEADER, + sizeof(WLANTL_BT_AMP_LLC_HEADER)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Packet push LLC header fails on" + " WLANTL_Translate8023To80211Header")); + return vosStatus; + } + } +#else + vosStatus = vos_pkt_push_head(vosDataBuff, WLANTL_LLC_HEADER, + sizeof(WLANTL_LLC_HEADER)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Packet push LLC header fails on" + " WLANTL_Translate8023To80211Header")); + return vosStatus; + } +#endif + }/*If add LLC is enabled*/ + else + { +#ifdef FEATURE_WLAN_ESE_UPLOAD + bIAPPTxwithLLC = VOS_FALSE; /*Reset the Flag here to start afresh with the next TX pkt*/ +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: STA Client registered to not remove LLC" + " WLANTL_Translate8023To80211Header")); + } + +#ifdef BTAMP_TEST + pClientSTA->wSTADesc.wSTAType = WLAN_STA_BT_AMP; +#endif + + // Find the space required for the 802.11 header format + // based on the frame control fields. + ucHeaderSize = MandatoryucHeaderSize; + if (pClientSTA->wSTADesc.ucQosEnabled) + { + ucHeaderSize += sizeof(pw80211Header->usQosCtrl); + } + if (pClientSTA->wSTADesc.wSTAType == WLAN_STA_BT_AMP) + { + ucHeaderSize += sizeof(pw80211Header->optvA4); + ucQoSOffset += sizeof(pw80211Header->optvA4); + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + " WLANTL_Translate8023To80211Header : Header size = %d ", ucHeaderSize)); + + vos_pkt_reserve_head( vosDataBuff, &ppvBDHeader, ucHeaderSize ); + if ( NULL == ppvBDHeader ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:VOSS packet corrupted ")); + *pvosStatus = VOS_STATUS_E_INVAL; + return *pvosStatus; + } + + + // OK now we have the space. Fill the 80211 header + /* Fill A2 */ + pw80211Header = (WLANTL_80211HeaderType *)(ppvBDHeader); + // only clear the required space. + vos_mem_set( pw80211Header, ucHeaderSize, 0 ); + vos_mem_copy( pw80211Header->vA2, w8023Header.vSA, VOS_MAC_ADDR_SIZE); + + +#ifdef FEATURE_WLAN_WAPI + if (( WLANTL_STA_AUTHENTICATED == pClientSTA->tlState || + pClientSTA->ptkInstalled ) && (tlMetaInfo->ucIsWai != 1)) +#else + if ( WLANTL_STA_AUTHENTICATED == pClientSTA->tlState || + pClientSTA->ptkInstalled ) +#endif + { + pw80211Header->wFrmCtrl.wep = + pClientSTA->wSTADesc.ucProtectedFrame; + } + + pw80211Header->usDurationId = 0; + pw80211Header->usSeqCtrl = 0; + + pw80211Header->wFrmCtrl.type = WLANTL_80211_DATA_TYPE; + + + + if(pClientSTA->wSTADesc.ucQosEnabled) + { + pw80211Header->wFrmCtrl.subType = WLANTL_80211_DATA_QOS_SUBTYPE; + + *((v_U16_t *)((v_U8_t *)ppvBDHeader + ucQoSOffset)) = tlMetaInfo->ucUP; + + } + else + { + pw80211Header->wFrmCtrl.subType = 0; + tlMetaInfo->ucUP = 0; + tlMetaInfo->ucTID = 0; + + // NO NO NO - there is not enough memory allocated to write the QOS ctrl + // field, it will overwrite the first 2 bytes of the data packet(LLC header) + // pw80211Header->usQosCtrl = 0; + } + + + switch( pClientSTA->wSTADesc.wSTAType ) + { + case WLAN_STA_IBSS: + pw80211Header->wFrmCtrl.toDS = 0; + pw80211Header->wFrmCtrl.fromDS = 0; + + vos_copy_macaddr( (v_MACADDR_t*)&pw80211Header->vA1, + (v_MACADDR_t*)&w8023Header.vDA); + vos_mem_copy( pw80211Header->vA3, + &pClientSTA->wSTADesc.vBSSIDforIBSS , + VOS_MAC_ADDR_SIZE); + break; + + case WLAN_STA_BT_AMP: + *ucWDSEnabled = 1; // WDS on. + pw80211Header->wFrmCtrl.toDS = 1; + pw80211Header->wFrmCtrl.fromDS = 1; + vos_copy_macaddr( (v_MACADDR_t*)&pw80211Header->vA1, + &pClientSTA->wSTADesc.vSTAMACAddress); + vos_mem_copy( pw80211Header->vA2, + w8023Header.vSA, VOS_MAC_ADDR_SIZE); + vos_copy_macaddr( (v_MACADDR_t*)&pw80211Header->vA3, + &pClientSTA->wSTADesc.vSTAMACAddress); + /* fill the optional A4 header */ + vos_mem_copy( pw80211Header->optvA4, + w8023Header.vSA, VOS_MAC_ADDR_SIZE); + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "BTAMP CASE NOW ---------staid=%d", + ucStaId)); + break; + + case WLAN_STA_SOFTAP: + *ucWDSEnabled = 0; // WDS off. + pw80211Header->wFrmCtrl.toDS = 0; + pw80211Header->wFrmCtrl.fromDS = 1; + /*Copy the DA to A1*/ + vos_mem_copy( pw80211Header->vA1, w8023Header.vDA , VOS_MAC_ADDR_SIZE); + vos_copy_macaddr( (v_MACADDR_t*)&pw80211Header->vA2, + &pClientSTA->wSTADesc.vSelfMACAddress); + vos_mem_copy( pw80211Header->vA3, + w8023Header.vSA, VOS_MAC_ADDR_SIZE); + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "sw 802 to 80211 softap case ---------staid=%d", + ucStaId)); + break; +#ifdef FEATURE_WLAN_TDLS + case WLAN_STA_TDLS: + pw80211Header->wFrmCtrl.toDS = 0; + pw80211Header->wFrmCtrl.fromDS = 0; + /*Fix me*/ + vos_copy_macaddr( (v_MACADDR_t*)&pw80211Header->vA1, + &pClientSTA->wSTADesc.vSTAMACAddress); + vos_mem_copy( pw80211Header->vA3, + &pClientSTA->wSTADesc.vBSSIDforIBSS , + VOS_MAC_ADDR_SIZE); + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + ("TL:TDLS CASE NOW ---------staid=%d"), ucStaId); + break; +#endif + case WLAN_STA_INFRA: + default: + pw80211Header->wFrmCtrl.toDS = 1; + pw80211Header->wFrmCtrl.fromDS = 0; + vos_copy_macaddr( (v_MACADDR_t*)&pw80211Header->vA1, + &pClientSTA->wSTADesc.vSTAMACAddress); + vos_mem_copy( pw80211Header->vA3, w8023Header.vDA , VOS_MAC_ADDR_SIZE); + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "REGULAR INFRA LINK CASE---------staid=%d", + ucStaId)); + break; + } + // OK now we have the space. Fill the 80211 header + /* Fill A2 */ + pw80211Header = (WLANTL_80211HeaderType *)(ppvBDHeader); + return VOS_STATUS_SUCCESS; +}/*WLANTL_Translate8023To80211Header*/ + + +/*============================================================================= + BEGIN LOG FUNCTION !!! Remove me or clean me +=============================================================================*/ +#if 0 //def WLANTL_DEBUG + +#define WLANTL_DEBUG_FRAME_BYTE_PER_LINE 16 +#define WLANTL_DEBUG_FRAME_BYTE_PER_BYTE 4 + +static v_VOID_t WLANTL_DebugFrame +( + v_PVOID_t dataPointer, + v_U32_t dataSize +) +{ + v_U8_t lineBuffer[WLANTL_DEBUG_FRAME_BYTE_PER_LINE]; + v_U32_t numLines; + v_U32_t numBytes; + v_U32_t idx; + v_U8_t *linePointer; + + numLines = dataSize / WLANTL_DEBUG_FRAME_BYTE_PER_LINE; + numBytes = dataSize % WLANTL_DEBUG_FRAME_BYTE_PER_LINE; + linePointer = (v_U8_t *)dataPointer; + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR, "WLAN TL:Frame Debug Frame Size %d, Pointer 0x%p", dataSize, dataPointer)); + for(idx = 0; idx < numLines; idx++) + { + memset(lineBuffer, 0, WLANTL_DEBUG_FRAME_BYTE_PER_LINE); + memcpy(lineBuffer, linePointer, WLANTL_DEBUG_FRAME_BYTE_PER_LINE); + TLLOGE(VOS_TRACE(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x", + lineBuffer[0], lineBuffer[1], lineBuffer[2], lineBuffer[3], lineBuffer[4], lineBuffer[5], lineBuffer[6], lineBuffer[7], + lineBuffer[8], lineBuffer[9], lineBuffer[10], lineBuffer[11], lineBuffer[12], lineBuffer[13], lineBuffer[14], lineBuffer[15])); + linePointer += WLANTL_DEBUG_FRAME_BYTE_PER_LINE; + } + + if(0 == numBytes) + return; + + memset(lineBuffer, 0, WLANTL_DEBUG_FRAME_BYTE_PER_LINE); + memcpy(lineBuffer, linePointer, numBytes); + for(idx = 0; idx < WLANTL_DEBUG_FRAME_BYTE_PER_LINE / WLANTL_DEBUG_FRAME_BYTE_PER_BYTE; idx++) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_SAL, VOS_TRACE_LEVEL_ERROR, "WLAN TL:0x%2x 0x%2x 0x%2x 0x%2x", + lineBuffer[idx * WLANTL_DEBUG_FRAME_BYTE_PER_BYTE], lineBuffer[1 + idx * WLANTL_DEBUG_FRAME_BYTE_PER_BYTE], + lineBuffer[2 + idx * WLANTL_DEBUG_FRAME_BYTE_PER_BYTE], lineBuffer[3 + idx * WLANTL_DEBUG_FRAME_BYTE_PER_BYTE])); + if(((idx + 1) * WLANTL_DEBUG_FRAME_BYTE_PER_BYTE) >= numBytes) + break; + } + + return; +} +#endif + +/*============================================================================= + END LOG FUNCTION +=============================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_Translate80211To8023Header + + DESCRIPTION + Inline function for translating and 802.11 header into an 802.3 header. + + DEPENDENCIES + + + PARAMETERS + + IN + pTLCb: TL control block + ucStaId: station ID + ucHeaderLen: Length of the header from BD + ucActualHLen: Length of header including padding or any other trailers + + IN/OUT + vosDataBuff: vos data buffer, will contain the new header on output + + OUT + pvosStatus: status of the operation + + RETURN VALUE + + The result code associated with performing the operation + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Translate80211To8023Header +( + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + v_U16_t usActualHLen, + v_U8_t ucHeaderLen, + WLANTL_CbType* pTLCb, + v_U8_t ucSTAId, + v_BOOL_t bForwardIAPPwithLLC +) +{ + WLANTL_8023HeaderType w8023Header; + WLANTL_80211HeaderType w80211Header; + v_U8_t aucLLCHeader[WLANTL_LLC_HEADER_LEN]; + VOS_STATUS vosStatus; + v_U16_t usDataStartOffset = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + if ( sizeof(w80211Header) < ucHeaderLen ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Warning !: Check the header size for the Rx frame structure=%d received=%dn", + sizeof(w80211Header), ucHeaderLen)); + ucHeaderLen = sizeof(w80211Header); + } + + // This will take care of headers of all sizes, 3 address, 3 addr QOS, + // WDS non-QOS and WDS QoS etc. We have space for all in the 802.11 header structure. + vosStatus = vos_pkt_pop_head( vosDataBuff, &w80211Header, ucHeaderLen); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to pop 80211 header from packet %d", + vosStatus)); + + return vosStatus; + } + + switch ( w80211Header.wFrmCtrl.fromDS ) + { + case 0: + if ( w80211Header.wFrmCtrl.toDS ) + { + //SoftAP AP mode + vos_mem_copy( w8023Header.vDA, w80211Header.vA3, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA2, VOS_MAC_ADDR_SIZE); + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL SoftAP: 802 3 DA %08x SA %08x", + w8023Header.vDA, w8023Header.vSA)); + } + else + { + /* IBSS */ + vos_mem_copy( w8023Header.vDA, w80211Header.vA1, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA2, VOS_MAC_ADDR_SIZE); + } + break; + case 1: + if ( w80211Header.wFrmCtrl.toDS ) + { + /* BT-AMP case */ + vos_mem_copy( w8023Header.vDA, w80211Header.vA1, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA2, VOS_MAC_ADDR_SIZE); + } + else + { /* Infra */ + vos_mem_copy( w8023Header.vDA, w80211Header.vA1, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA3, VOS_MAC_ADDR_SIZE); + } + break; + } + + if( usActualHLen > ucHeaderLen ) + { + usDataStartOffset = usActualHLen - ucHeaderLen; + } + + if ( 0 < usDataStartOffset ) + { + vosStatus = vos_pkt_trim_head( vosDataBuff, usDataStartOffset ); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to trim header from packet %d", + vosStatus)); + return vosStatus; + } + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 != pTLCb->atlSTAClients[ucSTAId]->wSTADesc.ucAddRmvLLC +#ifdef FEATURE_WLAN_ESE_UPLOAD + && (!bForwardIAPPwithLLC) +#endif /* FEATURE_WLAN_ESE_UPLOAD */ + ) + { + // Extract the LLC header + vosStatus = vos_pkt_pop_head( vosDataBuff, aucLLCHeader, + WLANTL_LLC_HEADER_LEN); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL: Failed to pop LLC header from packet %d", + vosStatus)); + + return vosStatus; + } + + //Extract the length + vos_mem_copy(&w8023Header.usLenType, + &aucLLCHeader[WLANTL_LLC_HEADER_LEN - sizeof(w8023Header.usLenType)], + sizeof(w8023Header.usLenType) ); + } + else + { + vosStatus = vos_pkt_get_packet_length(vosDataBuff, + &w8023Header.usLenType); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to get packet length %d", + vosStatus)); + + return vosStatus; + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: BTAMP len (ethertype) fld = %d", + w8023Header.usLenType)); + w8023Header.usLenType = vos_cpu_to_be16(w8023Header.usLenType); + } + + vos_pkt_push_head(vosDataBuff, &w8023Header, sizeof(w8023Header)); + +#ifdef BTAMP_TEST + { + // AP side will execute this. + v_U8_t *temp_w8023Header = NULL; + vosStatus = vos_pkt_peek_data( vosDataBuff, 0, + &temp_w8023Header, sizeof(w8023Header) ); + } +#endif +#if 0 /*TL_DEBUG*/ + vos_pkt_get_packet_length(vosDataBuff, &usLen); + vos_pkt_pop_head( vosDataBuff, aucData, usLen); + + WLANTL_DebugFrame(aucData, usLen); + + vos_pkt_push_head(vosDataBuff, aucData, usLen); + +#endif + + *pvosStatus = VOS_STATUS_SUCCESS; + + return VOS_STATUS_SUCCESS; +}/*WLANTL_Translate80211To8023Header*/ + +VOS_STATUS +WLANTL_MonTranslate80211To8023Header +( + vos_pkt_t* vosDataBuff, + WLANTL_CbType* pTLCb +) +{ + v_U16_t usMPDUDOffset; + v_U8_t ucMPDUHOffset; + v_U8_t ucMPDUHLen; + v_U16_t usActualHLen = 0; + v_U16_t usDataStartOffset = 0; + v_PVOID_t aucBDHeader; + WLANTL_8023HeaderType w8023Header; + WLANTL_80211HeaderType w80211Header; + VOS_STATUS vosStatus; + v_U8_t aucLLCHeader[WLANTL_LLC_HEADER_LEN]; + + WDA_DS_PeekRxPacketInfo( vosDataBuff, (v_PVOID_t)&aucBDHeader, 0 ); + ucMPDUHOffset = (v_U8_t)WDA_GET_RX_MPDU_HEADER_OFFSET(aucBDHeader); + usMPDUDOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(aucBDHeader); + ucMPDUHLen = (v_U8_t)WDA_GET_RX_MPDU_HEADER_LEN(aucBDHeader); + if (usMPDUDOffset > ucMPDUHOffset) + { + usActualHLen = usMPDUDOffset - ucMPDUHOffset; + } + + if ( sizeof(w80211Header) < ucMPDUHLen ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Warning !: Check the header size for the Rx frame structure=%d received=%dn", + sizeof(w80211Header), ucMPDUHLen)); + ucMPDUHLen = sizeof(w80211Header); + } + + vosStatus = vos_pkt_pop_head( vosDataBuff, &w80211Header, ucMPDUHLen); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to pop 80211 header from packet %d", + vosStatus)); + + return vosStatus; + } + switch ( w80211Header.wFrmCtrl.fromDS ) + { + case 0: + if ( w80211Header.wFrmCtrl.toDS ) + { + vos_mem_copy( w8023Header.vDA, w80211Header.vA3, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA2, VOS_MAC_ADDR_SIZE); + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL SoftAP: 802 3 DA %08x SA %08x", + w8023Header.vDA, w8023Header.vSA)); + } + else + { + vos_mem_copy( w8023Header.vDA, w80211Header.vA1, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA2, VOS_MAC_ADDR_SIZE); + } + break; + case 1: + if ( w80211Header.wFrmCtrl.toDS ) + { + vos_mem_copy( w8023Header.vDA, w80211Header.vA1, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA2, VOS_MAC_ADDR_SIZE); + } + else + { + vos_mem_copy( w8023Header.vDA, w80211Header.vA1, VOS_MAC_ADDR_SIZE); + vos_mem_copy( w8023Header.vSA, w80211Header.vA3, VOS_MAC_ADDR_SIZE); + } + break; + } + if( usActualHLen > ucMPDUHLen ) + { + usDataStartOffset = usActualHLen - ucMPDUHLen; + } + + if ( 0 < usDataStartOffset ) + { + vosStatus = vos_pkt_trim_head( vosDataBuff, usDataStartOffset ); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to trim header from packet %d", + vosStatus)); + return vosStatus; + } + } + // Extract the LLC header + vosStatus = vos_pkt_pop_head( vosDataBuff, aucLLCHeader, + WLANTL_LLC_HEADER_LEN); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL: Failed to pop LLC header from packet %d", + vosStatus)); + + return vosStatus; + } + + //Extract the length + vos_mem_copy(&w8023Header.usLenType, + &aucLLCHeader[WLANTL_LLC_HEADER_LEN - sizeof(w8023Header.usLenType)], + sizeof(w8023Header.usLenType) ); + + vos_pkt_push_head(vosDataBuff, &w8023Header, sizeof(w8023Header)); + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WLANTL_FindFrameTypeBcMcUc + + DESCRIPTION + Utility function to find whether received frame is broadcast, multicast + or unicast. + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pTLCb: pointer to the TL's control block + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the vos buffer + + IN/OUT + pucBcMcUc: pointer to buffer, will contain frame type on return + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_BADMSG: failed to extract info from data buffer + VOS_STATUS_SUCCESS: success + + SIDE EFFECTS + None. +============================================================================*/ +VOS_STATUS +WLANTL_FindFrameTypeBcMcUc +( + WLANTL_CbType *pTLCb, + v_U8_t ucSTAId, + vos_pkt_t *vosDataBuff, + v_U8_t *pucBcMcUc +) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + v_PVOID_t aucBDHeader; + v_PVOID_t pvPeekData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ((NULL == pTLCb) || + (NULL == vosDataBuff) || + (NULL == pucBcMcUc)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter in WLANTL_FindFrameTypeBcMcUc")); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Extract BD header and check if valid + ------------------------------------------------------------------------*/ + vosStatus = WDA_DS_PeekRxPacketInfo(vosDataBuff, (v_PVOID_t)&aucBDHeader, 0/*Swap BD*/ ); + + if (NULL == aucBDHeader) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:WLANTL_FindFrameTypeBcMcUc - Cannot extract BD header")); + VOS_ASSERT(0); + return VOS_STATUS_E_BADMSG; + } + + if ((0 == WDA_GET_RX_FT_DONE(aucBDHeader)) && + (0 != pTLCb->atlSTAClients[ucSTAId]->wSTADesc.ucSwFrameRXXlation)) + { + /* Its an 802.11 frame, extract MAC address 1 */ + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_FindFrameTypeBcMcUc - 802.11 frame, peeking Addr1")); + vosStatus = vos_pkt_peek_data(vosDataBuff, WLANTL_MAC_ADDR_ALIGN(1), + (v_PVOID_t)&pvPeekData, VOS_MAC_ADDR_SIZE); + } + else + { + /* Its an 802.3 frame, extract Destination MAC address */ + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_FindFrameTypeBcMcUc - 802.3 frame, peeking DA")); + vosStatus = vos_pkt_peek_data(vosDataBuff, WLANTL_MAC_ADDR_ALIGN(0), + (v_PVOID_t)&pvPeekData, VOS_MAC_ADDR_SIZE); + } + + if (VOS_STATUS_SUCCESS != vosStatus) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:WLANTL_FindFrameTypeBcMcUc - Failed to peek MAC address")); + return vosStatus; + } + + if (((tANI_U8 *)pvPeekData)[0] == 0xff) + { + *pucBcMcUc = WLANTL_FRAME_TYPE_BCAST; + } + else + { + if ((((tANI_U8 *)pvPeekData)[0] & 0x01) == 0x01) + *pucBcMcUc = WLANTL_FRAME_TYPE_MCAST; + else + *pucBcMcUc = WLANTL_FRAME_TYPE_UCAST; + } + + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:WLANTL_FindFrameTypeBcMcUc - Addr1Byte1 is: %x", + ((tANI_U8 *)pvPeekData)[0])); + + return VOS_STATUS_SUCCESS; +} + +#if 0 +#ifdef WLAN_PERF +/*========================================================================== + FUNCTION WLANTL_FastHwFwdDataFrame + + DESCRIPTION + Fast path function to quickly forward a data frame if HAL determines BD + signature computed here matches the signature inside current VOSS packet. + If there is a match, HAL and TL fills in the swapped packet length into + BD header and DxE header, respectively. Otherwise, packet goes back to + normal (slow) path and a new BD signature would be tagged into BD in this + VOSS packet later by the WLANHAL_FillTxBd() function. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff Ptr to VOSS packet + pMetaInfo For getting frame's TID + pStaInfo For checking STA type + + OUT + pvosStatus returned status + puFastFwdOK Flag to indicate whether frame could be fast forwarded + + RETURN VALUE + No return. + + SIDE EFFECTS + +============================================================================*/ +static void +WLANTL_FastHwFwdDataFrame +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + v_U32_t* puFastFwdOK, + WLANTL_MetaInfoType* pMetaInfo, + WLAN_STADescType* pStaInfo + +) +{ + v_PVOID_t pvPeekData; + v_U8_t ucDxEBDWLANHeaderLen = WLANTL_BD_HEADER_LEN(0) + sizeof(WLANBAL_sDXEHeaderType); + v_U8_t ucIsUnicast; + WLANBAL_sDXEHeaderType *pDxEHeader; + v_PVOID_t pvBDHeader; + v_PVOID_t pucBuffPtr; + v_U16_t usPktLen; + + /*----------------------------------------------------------------------- + Extract packet length + -----------------------------------------------------------------------*/ + + vos_pkt_get_packet_length( vosDataBuff, &usPktLen); + + /*----------------------------------------------------------------------- + Extract MAC address + -----------------------------------------------------------------------*/ + *pvosStatus = vos_pkt_peek_data( vosDataBuff, + WLANTL_MAC_ADDR_ALIGN(0), + (v_PVOID_t)&pvPeekData, + VOS_MAC_ADDR_SIZE ); + + if ( VOS_STATUS_SUCCESS != *pvosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed while attempting to extract MAC Addr %d", + *pvosStatus)); + *pvosStatus = VOS_STATUS_E_INVAL; + return; + } + + /*----------------------------------------------------------------------- + Reserve head room for DxE header, BD, and WLAN header + -----------------------------------------------------------------------*/ + + vos_pkt_reserve_head( vosDataBuff, &pucBuffPtr, + ucDxEBDWLANHeaderLen ); + if ( NULL == pucBuffPtr ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:No enough space in VOSS packet %p for DxE/BD/WLAN header", vosDataBuff)); + *pvosStatus = VOS_STATUS_E_INVAL; + return; + } + pDxEHeader = (WLANBAL_sDXEHeaderType *)pucBuffPtr; + pvBDHeader = (v_PVOID_t) &pDxEHeader[1]; + + /* UMA Tx acceleration is enabled. + * UMA would help convert frames to 802.11, fill partial BD fields and + * construct LLC header. To further accelerate this kind of frames, + * HAL would attempt to reuse the BD descriptor if the BD signature + * matches to the saved BD descriptor. + */ + if(pStaInfo->wSTAType == WLAN_STA_IBSS) + ucIsUnicast = !(((tANI_U8 *)pvPeekData)[0] & 0x01); + else + ucIsUnicast = 1; + + *puFastFwdOK = (v_U32_t) WLANHAL_TxBdFastFwd(pvosGCtx, pvPeekData, pMetaInfo->ucTID, ucIsUnicast, pvBDHeader, usPktLen ); + + /* Can't be fast forwarded. Trim the VOS head back to original location. */ + if(! *puFastFwdOK){ + vos_pkt_trim_head(vosDataBuff, ucDxEBDWLANHeaderLen); + }else{ + /* could be fast forwarded. Now notify BAL DxE header filling could be completely skipped + */ + v_U32_t uPacketSize = WLANTL_BD_HEADER_LEN(0) + usPktLen; + vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAL, + (v_PVOID_t)uPacketSize); + pDxEHeader->size = SWAP_ENDIAN_UINT32(uPacketSize); + } + *pvosStatus = VOS_STATUS_SUCCESS; + return; +} +#endif /*WLAN_PERF*/ +#endif + +#if 0 +/*========================================================================== + FUNCTION WLANTL_PrepareBDHeader + + DESCRIPTION + Inline function for preparing BD header before HAL processing. + + DEPENDENCIES + Just notify HAL that suspend in TL is complete. + + PARAMETERS + + IN + vosDataBuff: vos data buffer + ucDisableFrmXtl: is frame xtl disabled + + OUT + ppvBDHeader: it will contain the BD header + pvDestMacAdddr: it will contain the destination MAC address + pvosStatus: status of the combined processing + pusPktLen: packet len. + + RETURN VALUE + No return. + + SIDE EFFECTS + +============================================================================*/ +void +WLANTL_PrepareBDHeader +( + vos_pkt_t* vosDataBuff, + v_PVOID_t* ppvBDHeader, + v_MACADDR_t* pvDestMacAdddr, + v_U8_t ucDisableFrmXtl, + VOS_STATUS* pvosStatus, + v_U16_t* pusPktLen, + v_U8_t ucQosEnabled, + v_U8_t ucWDSEnabled, + v_U8_t extraHeadSpace +) +{ + v_U8_t ucHeaderOffset; + v_U8_t ucHeaderLen; + v_U8_t ucBDHeaderLen = WLANTL_BD_HEADER_LEN(ucDisableFrmXtl); + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /*------------------------------------------------------------------------- + Get header pointer from VOSS + !!! make sure reserve head zeros out the memory + -------------------------------------------------------------------------*/ + vos_pkt_get_packet_length( vosDataBuff, pusPktLen); + + if ( WLANTL_MAC_HEADER_LEN(ucDisableFrmXtl) > *pusPktLen ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Length of the packet smaller than expected network" + " header %d", *pusPktLen )); + + *pvosStatus = VOS_STATUS_E_INVAL; + return; + } + + vos_pkt_reserve_head( vosDataBuff, ppvBDHeader, + ucBDHeaderLen ); + if ( NULL == *ppvBDHeader ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:VOSS packet corrupted on Attach BD header")); + *pvosStatus = VOS_STATUS_E_INVAL; + return; + } + + /*----------------------------------------------------------------------- + Extract MAC address + -----------------------------------------------------------------------*/ + { + v_SIZE_t usMacAddrSize = VOS_MAC_ADDR_SIZE; + *pvosStatus = vos_pkt_extract_data( vosDataBuff, + ucBDHeaderLen + + WLANTL_MAC_ADDR_ALIGN(ucDisableFrmXtl), + (v_PVOID_t)pvDestMacAdddr, + &usMacAddrSize ); + } + if ( VOS_STATUS_SUCCESS != *pvosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed while attempting to extract MAC Addr %d", + *pvosStatus)); + } + else + { + /*--------------------------------------------------------------------- + Fill MPDU info fields: + - MPDU data start offset + - MPDU header start offset + - MPDU header length + - MPDU length - this is a 16b field - needs swapping + --------------------------------------------------------------------*/ + ucHeaderOffset = ucBDHeaderLen; + ucHeaderLen = WLANTL_MAC_HEADER_LEN(ucDisableFrmXtl); + + if ( 0 != ucDisableFrmXtl ) + { + if ( 0 != ucQosEnabled ) + { + ucHeaderLen += WLANTL_802_11_HEADER_QOS_CTL; + } + + // Similar to Qos we need something for WDS format ! + if ( ucWDSEnabled != 0 ) + { + // If we have frame translation enabled + ucHeaderLen += WLANTL_802_11_HEADER_ADDR4_LEN; + } + if ( extraHeadSpace != 0 ) + { + // Decrease the packet length with the extra padding after the header + *pusPktLen = *pusPktLen - extraHeadSpace; + } + } + + WLANHAL_TX_BD_SET_MPDU_HEADER_LEN( *ppvBDHeader, ucHeaderLen); + WLANHAL_TX_BD_SET_MPDU_HEADER_OFFSET( *ppvBDHeader, ucHeaderOffset); + WLANHAL_TX_BD_SET_MPDU_DATA_OFFSET( *ppvBDHeader, + ucHeaderOffset + ucHeaderLen + extraHeadSpace); + WLANHAL_TX_BD_SET_MPDU_LEN( *ppvBDHeader, *pusPktLen); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: VALUES ARE HLen=%x Hoff=%x doff=%x len=%x ex=%d", + ucHeaderLen, ucHeaderOffset, + (ucHeaderOffset + ucHeaderLen + extraHeadSpace), + *pusPktLen, extraHeadSpace)); + }/* if peek MAC success*/ + +}/* WLANTL_PrepareBDHeader */ +#endif + +//THIS IS A HACK AND NEEDS TO BE FIXED FOR CONCURRENCY +/*========================================================================== + FUNCTION WLAN_TLGetNextTxIds + + DESCRIPTION + Gets the next station and next AC in the list that should be served by the TL. + + Multiple Station Scheduling and TL queue management. + + 4 HDD BC/MC data packet queue status is specified as Station 0's status. Weights used + in WFQ algorith are initialized in WLANTL_OPEN and contained in tlConfigInfo field. + Each station has fields of ucPktPending and AC mask to tell whether a AC has traffic + or not. + + Stations are served in a round-robin fashion from highest priority to lowest priority. + The number of round-robin times of each prioirty equals to the WFQ weights and differetiates + the traffic of different prioirty. As such, stations can not provide low priority packets if + high priority packets are all served. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + OUT + pucSTAId: Station ID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good + + SIDE EFFECTS + + TL context contains currently served station ID in ucCurrentSTA field, currently served AC + in uCurServedAC field, and unserved weights of current AC in uCurLeftWeight. + When existing from the function, these three fields are changed accordingly. + +============================================================================*/ +VOS_STATUS +WLAN_TLAPGetNextTxIds +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId +) +{ + WLANTL_CbType* pTLCb; + v_U8_t ucACFilter = 1; + v_U8_t ucNextSTA, ucTempSTA; + v_BOOL_t isServed = TRUE; //current round has find a packet or not + v_U8_t ucACLoopNum = WLANTL_AC_HIGH_PRIO + 1; //number of loop to go + v_U8_t uFlowMask; // TX FlowMask from WDA + uint8 ucACMask; + uint8 i = 0; + uint8 j; + uint8 minWeightSta; + uint32_t sta_bitmask = 0; + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + //ENTER(); + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLAN_TLAPGetNextTxIds")); + return VOS_STATUS_E_FAULT; + } + + if ( VOS_STATUS_SUCCESS != WDA_DS_GetTxFlowMask( pvosGCtx, &uFlowMask ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed to retrieve Flow control mask from WDA")); + return VOS_STATUS_E_FAULT; + } + + /* The flow mask does not differentiate between different ACs/Qs + * since we use a single dxe channel for all ACs/Qs, hence it is + * enough to check that there are dxe resources on data channel + */ + uFlowMask &= WLANTL_DATA_FLOW_MASK; + + if (0 == uFlowMask) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: No resources to send packets")); + + // Setting STA Id to invalid if mask is 0 + *pucSTAId = WLAN_MAX_STA_COUNT; + return VOS_STATUS_E_FAULT; + } + + ucNextSTA = pTLCb->ucCurrentSTA; + + ++ucNextSTA; + + if ( WLAN_MAX_STA_COUNT <= ucNextSTA ) + ucNextSTA = 0; + + isServed = FALSE; + if ( 0 == pTLCb->ucCurLeftWeight ) + { + //current prioirty is done + if ( WLANTL_AC_BK == (WLANTL_ACEnumType)pTLCb->uCurServedAC ) + { + //end of current VO, VI, BE, BK loop. Reset priority. + pTLCb->uCurServedAC = WLANTL_AC_HIGH_PRIO; + } + else + { + pTLCb->uCurServedAC --; + } + + pTLCb->ucCurLeftWeight = pTLCb->tlConfigInfo.ucAcWeights[pTLCb->uCurServedAC]; + + } // (0 == pTLCb->ucCurLeftWeight) + + ucTempSTA = ucNextSTA; + minWeightSta = ucNextSTA; + + //decide how many loops to go. if current loop is partial, do one extra to make sure + //we cover every station + if ((1 == pTLCb->ucCurLeftWeight) && (ucNextSTA != 0)) + { + ucACLoopNum ++; // now is 5 loops + } + + /* Start with highest priority. ucNextSTA, pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight + all have previous values.*/ + for (; ucACLoopNum > 0; ucACLoopNum--) + { + + ucACFilter = 1 << pTLCb->uCurServedAC; + + // pTLCb->ucCurLeftWeight keeps previous results. + for (; (pTLCb->ucCurLeftWeight > 0) ; pTLCb->ucCurLeftWeight-- ) + { + + for ( ; ucNextSTA < WLAN_MAX_STA_COUNT; ucNextSTA ++ ) + { + if(NULL == pTLCb->atlSTAClients[ucNextSTA]) + { + continue; + } + WLAN_TL_AC_ARRAY_2_MASK (pTLCb->atlSTAClients[ucNextSTA], ucACMask, i); + + if ( (0 == pTLCb->atlSTAClients[ucNextSTA]->ucExists) || + ((0 == pTLCb->atlSTAClients[ucNextSTA]->ucPktPending) && !(ucACMask)) || + (0 == (ucACMask & ucACFilter)) ) + + { + //current station does not exist or have any packet to serve. + continue; + } + + if ((WLANTL_STA_AUTHENTICATED != pTLCb->atlSTAClients[ucNextSTA]->tlState) + || (pTLCb->atlSTAClients[ucNextSTA]->disassoc_progress == VOS_TRUE )) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s Sta %d not in auth state so skipping it.", + __func__, ucNextSTA)); + continue; + } + + //go to next station if current station can't send due to flow control + //Station is allowed to send when it is not in LWM mode. When station is in LWM mode, + //station is allowed to send only after FW reports FW memory is below threshold and on-fly + //packets are less then allowed value + if ( (TRUE == pTLCb->atlSTAClients[ucNextSTA]->ucLwmModeEnabled) && + ((FALSE == pTLCb->atlSTAClients[ucNextSTA]->ucLwmEventReported) || + (0 < pTLCb->atlSTAClients[ucNextSTA]->uBuffThresholdMax)) + ) + { + continue; + } + + /* + * Initial weight is 0 is for all the stations. As part of FW TX stats + * indication to host, good peer weight is updated to one and the + * remaining peers weight is updated based on their RA rates and BTQM + * queued frames length. TL skips fetching the packet until the station + * has got chances equal to its weight. + */ + if (pTLCb->atlSTAClients[ucNextSTA]->weight > WLANTL_GOOD_STA_WEIGHT) { + if (pTLCb->atlSTAClients[ucNextSTA]->weight_count <= + pTLCb->atlSTAClients[ucNextSTA]->weight) + { + if (pTLCb->atlSTAClients[minWeightSta]->weight <= 1) + minWeightSta = ucNextSTA; + else if (pTLCb->atlSTAClients[ucNextSTA]->weight < + pTLCb->atlSTAClients[minWeightSta]->weight) { + minWeightSta = ucNextSTA; + } + sta_bitmask |= (1 << ucNextSTA); + pTLCb->atlSTAClients[ucNextSTA]->weight_count++; + continue; + } + else + pTLCb->atlSTAClients[ucNextSTA]->weight_count = 0; + } + + // Find a station. Weight is updated already. + *pucSTAId = ucNextSTA; + pTLCb->ucCurrentSTA = ucNextSTA; + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = pTLCb->uCurServedAC; + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + " TL serve one station AC: %d W: %d StaId: %d", + pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA )); + + pTLCb->ucCurLeftWeight--; + return VOS_STATUS_SUCCESS; + } //STA loop + + for (j = 0; j < ucTempSTA; j++) { + if (NULL == pTLCb->atlSTAClients[j]) + continue; + + WLAN_TL_AC_ARRAY_2_MASK (pTLCb->atlSTAClients[j], ucACMask, i); + + if ((0 == pTLCb->atlSTAClients[j]->ucExists) || + ((0 == pTLCb->atlSTAClients[j]->ucPktPending) && !(ucACMask)) || + (0 == (ucACMask & ucACFilter))) + continue; + + if ((WLANTL_STA_AUTHENTICATED != pTLCb->atlSTAClients[j]->tlState) || + (pTLCb->atlSTAClients[j]->disassoc_progress == VOS_TRUE)) { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s Sta %d not in auth state so skipping it.", + __func__, ucNextSTA)); + continue; + } + + if ((TRUE == pTLCb->atlSTAClients[j]->ucLwmModeEnabled) && + ((FALSE == pTLCb->atlSTAClients[j]->ucLwmEventReported) || + (0 < pTLCb->atlSTAClients[j]->uBuffThresholdMax))) + continue; + + if (pTLCb->atlSTAClients[j]->weight > WLANTL_GOOD_STA_WEIGHT) { + if (pTLCb->atlSTAClients[j]->weight_count <= + pTLCb->atlSTAClients[j]->weight) + { + if (pTLCb->atlSTAClients[minWeightSta]->weight <= 1) + minWeightSta = j; + else if (pTLCb->atlSTAClients[j]->weight < + pTLCb->atlSTAClients[minWeightSta]->weight) { + minWeightSta = j; + } + sta_bitmask |= (1 << j); + pTLCb->atlSTAClients[j]->weight_count++; + continue; + } + else + pTLCb->atlSTAClients[j]->weight_count = 0; + } + + *pucSTAId = j; + pTLCb->ucCurrentSTA = j; + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = pTLCb->uCurServedAC; + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + " TL serve one station AC: %d W: %d StaId: %d", + pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA )); + pTLCb->ucCurLeftWeight--; + return VOS_STATUS_SUCCESS; + } + + /* Fecth packet from the stations with minimum weight among them */ + if (pTLCb->atlSTAClients[minWeightSta] && + pTLCb->atlSTAClients[minWeightSta]->ucPktPending) + { + *pucSTAId = minWeightSta; + pTLCb->ucCurrentSTA = minWeightSta; + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = pTLCb->uCurServedAC; + + for (j = 0; sta_bitmask != 0; sta_bitmask >>= 1, j++) + { + if (0 == (sta_bitmask & 0x1)) + continue; + + if (minWeightSta == j) + continue; + /* To ensure fairness between stations */ + pTLCb->atlSTAClients[j]->weight_count += + pTLCb->atlSTAClients[minWeightSta]->weight - + pTLCb->atlSTAClients[minWeightSta]->weight_count; + } + pTLCb->atlSTAClients[minWeightSta]->weight_count = 0; + + TLLOG4(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + " TL serve one station AC: %d W: %d StaId: %d", + pTLCb->uCurServedAC, pTLCb->ucCurLeftWeight, pTLCb->ucCurrentSTA )); + pTLCb->ucCurLeftWeight--; + return VOS_STATUS_SUCCESS; + } + + ucNextSTA = 0; + if ( FALSE == isServed ) + { + //current loop finds no packet.no need to repeat for the same priority + break; + } + //current loop is partial loop. go for one more loop. + isServed = FALSE; + + } //Weight loop + + if (WLANTL_AC_BK == pTLCb->uCurServedAC) + { + pTLCb->uCurServedAC = WLANTL_AC_HIGH_PRIO; + } + else + { + pTLCb->uCurServedAC--; + } + pTLCb->ucCurLeftWeight = pTLCb->tlConfigInfo.ucAcWeights[pTLCb->uCurServedAC]; + + }// AC loop + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + " TL can't find one station to serve" )); + + pTLCb->uCurServedAC = WLANTL_AC_BK; + pTLCb->ucCurLeftWeight = 1; + //invalid number will be captured by caller + pTLCb->ucCurrentSTA = WLAN_MAX_STA_COUNT; + + *pucSTAId = pTLCb->ucCurrentSTA; + return VOS_STATUS_E_FAULT; +} + + +/*========================================================================== + FUNCTION WLAN_TLGetNextTxIds + + DESCRIPTION + Gets the next station and next AC in the list + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + OUT + pucSTAId: Station ID + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLAN_TLGetNextTxIds +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId +) +{ + WLANTL_CbType* pTLCb; + v_U8_t ucNextAC; + v_U8_t ucNextSTA; + v_U8_t ucCount; + v_U8_t uFlowMask; // TX FlowMask from WDA + v_U8_t ucACMask = 0; + v_U8_t i = 0; + + tBssSystemRole systemRole; //RG HACK to be removed + tpAniSirGlobal pMac; + + pMac = vos_get_context(VOS_MODULE_ID_PE, pvosGCtx); + if ( NULL == pMac ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pMac", __func__)); + return VOS_STATUS_E_FAULT; + } + + systemRole = wdaGetGlobalSystemRole(pMac); + + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLAN_TLGetNextTxIds")); + return VOS_STATUS_E_FAULT; + } + +#ifdef FEATURE_WLAN_TDLS + if ((eSYSTEM_AP_ROLE == systemRole) || + (eSYSTEM_STA_IN_IBSS_ROLE == systemRole) || + (vos_concurrent_open_sessions_running()) || pTLCb->ucTdlsPeerCount) +#else + if ((eSYSTEM_AP_ROLE == systemRole) || + (eSYSTEM_STA_IN_IBSS_ROLE == systemRole) || + (vos_concurrent_open_sessions_running())) +#endif + { + return WLAN_TLAPGetNextTxIds(pvosGCtx,pucSTAId); + } + + + if ( VOS_STATUS_SUCCESS != WDA_DS_GetTxFlowMask( pvosGCtx, &uFlowMask ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Failed to retrieve Flow control mask from WDA")); + return VOS_STATUS_E_FAULT; + } + + /* The flow mask does not differentiate between different ACs/Qs + * since we use a single dxe channel for all ACs/Qs, hence it is + * enough to check that there are dxe resources on data channel + */ + uFlowMask &= WLANTL_DATA_FLOW_MASK; + + if (0 == uFlowMask) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: No resources to send packets")); + + // Setting STA id to invalid if mask is 0 + *pucSTAId = WLAN_MAX_STA_COUNT; + return VOS_STATUS_E_FAULT; + } + + /*STA id - no priority yet implemented */ + /*----------------------------------------------------------------------- + Choose the next STA for tx - for now go in a round robin fashion + through all the stations that have pending packets + -------------------------------------------------------------------------*/ + ucNextSTA = pTLCb->ucCurrentSTA; + + pTLCb->ucCurrentSTA = WLAN_MAX_STA_COUNT; + for ( ucCount = 0; + ucCount < WLAN_MAX_STA_COUNT; + ucCount++ ) + { + ucNextSTA = ( (ucNextSTA+1) >= WLAN_MAX_STA_COUNT )?0:(ucNextSTA+1); + if(NULL == pTLCb->atlSTAClients[ucNextSTA]) + { + continue; + } + + if ((pTLCb->atlSTAClients[ucNextSTA]->weight > WLANTL_GOOD_STA_WEIGHT) && + (pTLCb->atlSTAClients[ucNextSTA]->ucPktPending)) { + if (pTLCb->atlSTAClients[ucNextSTA]->weight_count <= + pTLCb->atlSTAClients[ucNextSTA]->weight) { + pTLCb->atlSTAClients[ucNextSTA]->weight_count++; + continue; + } + else + pTLCb->atlSTAClients[ucNextSTA]->weight_count = 0; + } + + if (( pTLCb->atlSTAClients[ucNextSTA]->ucExists ) && + ( pTLCb->atlSTAClients[ucNextSTA]->ucPktPending )) + { + if (WLANTL_STA_AUTHENTICATED == pTLCb->atlSTAClients[ucNextSTA]->tlState) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "STA ID: %d on WLAN_TLGetNextTxIds", *pucSTAId)); + pTLCb->ucCurrentSTA = ucNextSTA; + break; + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s Sta %d is not in auth state, skipping this sta.", + __func__, ucNextSTA)); + } + } + } + + *pucSTAId = pTLCb->ucCurrentSTA; + + if ( WLANTL_STA_ID_INVALID( *pucSTAId ) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:No station registered with TL at this point")); + + return VOS_STATUS_E_FAULT; + + } + + /*Convert the array to a mask for easier operation*/ + WLAN_TL_AC_ARRAY_2_MASK( pTLCb->atlSTAClients[*pucSTAId], ucACMask, i); + + if ( 0 == ucACMask ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Mask 0 " + "STA ID: %d on WLAN_TLGetNextTxIds", *pucSTAId)); + + /*setting STA id to invalid if mask is 0*/ + *pucSTAId = WLAN_MAX_STA_COUNT; + + return VOS_STATUS_E_FAULT; + } + + /*----------------------------------------------------------------------- + AC is updated whenever a packet is fetched from HDD -> the current + weight of such an AC cannot be 0 -> in this case TL is expected to + exit this function at this point during the main Tx loop + -----------------------------------------------------------------------*/ + if ( 0 < pTLCb->atlSTAClients[*pucSTAId]->ucCurrentWeight ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Maintaining serviced AC to: %d for Weight: %d", + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC , + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentWeight)); + return VOS_STATUS_SUCCESS; + } + + /*----------------------------------------------------------------------- + Choose highest priority AC - !!! optimize me + -----------------------------------------------------------------------*/ + ucNextAC = pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC; + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Next AC: %d", ucNextAC)); + + while ( 0 != ucACMask ) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + " AC Mask: %d Next: %d Res : %d", + ucACMask, ( 1 << ucNextAC ), ( ucACMask & ( 1 << ucNextAC )))); + + if ( 0 != ( ucACMask & ( 1 << ucNextAC ))) + { + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC = + (WLANTL_ACEnumType)ucNextAC; + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentWeight = + pTLCb->tlConfigInfo.ucAcWeights[ucNextAC]; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Switching serviced AC to: %d with Weight: %d", + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC , + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentWeight)); + break; + } + + if (ucNextAC == WLANTL_AC_BK) + ucNextAC = WLANTL_AC_HIGH_PRIO; + else + ucNextAC--; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Next AC %d", ucNextAC)); + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + " C AC: %d C W: %d", + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentAC, + pTLCb->atlSTAClients[*pucSTAId]->ucCurrentWeight)); + + return VOS_STATUS_SUCCESS; +}/* WLAN_TLGetNextTxIds */ + + + +/*========================================================================== + DEFAULT HANDLERS: Registered at initialization with TL + ==========================================================================*/ + +/*========================================================================== + + FUNCTION WLANTL_MgmtFrmRxDefaultCb + + DESCRIPTION + Default Mgmt Frm rx callback: asserts all the time. If this function gets + called it means there is no registered rx cb pointer for Mgmt Frm. + + DEPENDENCIES + + PARAMETERS + Not used. + + RETURN VALUE + + VOS_STATUS_E_FAILURE: Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_MgmtFrmRxDefaultCb +( + v_PVOID_t pvosGCtx, + v_PVOID_t vosBuff +) +{ + if ( NULL != vosBuff ) + { + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Fatal failure: No registered Mgmt Frm client on pkt RX")); + /* Drop packet */ + vos_pkt_return_packet((vos_pkt_t *)vosBuff); + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: No registered Mgmt Frm client on pkt RX. Load/Unload in progress, Ignore")); + + return VOS_STATUS_E_FAILURE; +}/*WLANTL_MgmtFrmRxDefaultCb*/ + +/*========================================================================== + + FUNCTION WLANTL_BAPRxDefaultCb + + DESCRIPTION + Default BAP rx callback: asserts all the time. If this function gets + called it means there is no registered rx cb pointer for BAP. + + DEPENDENCIES + + PARAMETERS + Not used. + + RETURN VALUE + + VOS_STATUS_E_FAILURE: Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_BAPRxDefaultCb +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + WLANTL_BAPFrameEnumType frameType +) +{ + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Fatal failure: No registered BAP client on BAP pkt RX")); +#ifndef BTAMP_TEST + VOS_ASSERT(0); +#endif + return VOS_STATUS_E_FAILURE; +}/*WLANTL_MgmtFrmRxDefaultCb*/ + +/*========================================================================== + + FUNCTION WLANTL_STARxDefaultCb + + DESCRIPTION + Default STA rx callback: asserts all the time. If this function gets + called it means there is no registered rx cb pointer for station. + (Mem corruption most likely, it should never happen) + + DEPENDENCIES + + PARAMETERS + Not used. + + RETURN VALUE + + VOS_STATUS_E_FAILURE: Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_STARxDefaultCb +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + v_U8_t ucSTAId, + WLANTL_RxMetaInfoType* pRxMetaInfo +) +{ + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: No registered STA client rx cb for STAID: %d dropping pkt", + ucSTAId)); + vos_pkt_return_packet(vosDataBuff); + return VOS_STATUS_SUCCESS; +}/*WLANTL_MgmtFrmRxDefaultCb*/ + + +/*========================================================================== + + FUNCTION WLANTL_STAFetchPktDefaultCb + + DESCRIPTION + Default fetch callback: asserts all the time. If this function gets + called it means there is no registered fetch cb pointer for station. + (Mem corruption most likely, it should never happen) + + DEPENDENCIES + + PARAMETERS + Not used. + + RETURN VALUE + + VOS_STATUS_E_FAILURE: Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_STAFetchPktDefaultCb +( + v_PVOID_t pvosGCtx, + v_U8_t* pucSTAId, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +) +{ + TLLOGP(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Fatal failure: No registered STA client on data pkt RX")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; +}/*WLANTL_MgmtFrmRxDefaultCb*/ + +/*========================================================================== + + FUNCTION WLANTL_TxCompDefaultCb + + DESCRIPTION + Default tx complete handler. It will release the completed pkt to + prevent memory leaks. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation; please + check vos_pkt_return_packet for possible error codes. + + Please check vos_pkt_return_packet API for possible return values. + +============================================================================*/ +VOS_STATUS +WLANTL_TxCompDefaultCb +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +) +{ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:TXComp not registered, releasing pkt to prevent mem leak")); + return vos_pkt_return_packet(vosDataBuff); +}/*WLANTL_TxCompDefaultCb*/ + + +/*========================================================================== + Cleanup functions + ==========================================================================*/ + +/*========================================================================== + + FUNCTION WLANTL_CleanCB + + DESCRIPTION + Cleans TL control block + + DEPENDENCIES + + PARAMETERS + + IN + pTLCb: pointer to TL's control block + ucEmpty: set if TL has to clean up the queues and release pedning pkts + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_CleanCB +( + WLANTL_CbType* pTLCb, + v_U8_t ucEmpty +) +{ + v_U8_t ucIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_CleanCB")); + return VOS_STATUS_E_INVAL; + } + + /* number of packets sent to BAL waiting for tx complete confirmation */ + pTLCb->usPendingTxCompleteCount = 0; + + /* global suspend flag */ + vos_atomic_set_U8( &pTLCb->ucTxSuspended, 1); + + /* resource flag */ + pTLCb->uResCount = 0; + + + /*------------------------------------------------------------------------- + Client stations + -------------------------------------------------------------------------*/ + for ( ucIndex = 0; ucIndex < WLAN_MAX_STA_COUNT ; ucIndex++) + { + if(NULL != pTLCb->atlSTAClients[ucIndex]) + { + WLANTL_CleanSTA( pTLCb->atlSTAClients[ucIndex], ucEmpty); + } + } + + /*------------------------------------------------------------------------- + Management Frame client + -------------------------------------------------------------------------*/ + pTLCb->tlMgmtFrmClient.ucExists = 0; + + if ( ( 0 != ucEmpty) && + ( NULL != pTLCb->tlMgmtFrmClient.vosPendingDataBuff )) + { + vos_pkt_return_packet(pTLCb->tlMgmtFrmClient.vosPendingDataBuff); + } + + pTLCb->tlMgmtFrmClient.vosPendingDataBuff = NULL; + + /* set to a default cb in order to prevent constant checking for NULL */ + pTLCb->tlMgmtFrmClient.pfnTlMgmtFrmRx = WLANTL_MgmtFrmRxDefaultCb; + + /*------------------------------------------------------------------------- + BT AMP client + -------------------------------------------------------------------------*/ + pTLCb->tlBAPClient.ucExists = 0; + + if (( 0 != ucEmpty) && + ( NULL != pTLCb->tlBAPClient.vosPendingDataBuff )) + { + vos_pkt_return_packet(pTLCb->tlBAPClient.vosPendingDataBuff); + } + + if (( 0 != ucEmpty) && + ( NULL != pTLCb->vosDummyBuf )) + { + vos_pkt_return_packet(pTLCb->vosDummyBuf); + } + + pTLCb->tlBAPClient.vosPendingDataBuff = NULL; + + pTLCb->vosDummyBuf = NULL; + pTLCb->vosTempBuf = NULL; + pTLCb->ucCachedSTAId = WLAN_MAX_STA_COUNT; + + /* set to a default cb in order to prevent constant checking for NULL */ + pTLCb->tlBAPClient.pfnTlBAPRx = WLANTL_BAPRxDefaultCb; + + pTLCb->ucRegisteredStaId = WLAN_MAX_STA_COUNT; + + return VOS_STATUS_SUCCESS; + +}/* WLANTL_CleanCB*/ + +/*========================================================================== + + FUNCTION WLANTL_CleanSTA + + DESCRIPTION + Cleans a station control block. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucEmpty: if set the queues and pending pkts will be emptyed + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_CleanSTA +( + WLANTL_STAClientType* ptlSTAClient, + v_U8_t ucEmpty +) +{ + v_U8_t ucIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == ptlSTAClient ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_CleanSTA")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Clear station from TL + ------------------------------------------------------------------------*/ + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Clearing STA Client ID: %d, Empty flag: %d", + ptlSTAClient->wSTADesc.ucSTAId, ucEmpty )); + + ptlSTAClient->pfnSTARx = WLANTL_STARxDefaultCb; + ptlSTAClient->pfnSTATxComp = WLANTL_TxCompDefaultCb; + ptlSTAClient->pfnSTAFetchPkt = WLANTL_STAFetchPktDefaultCb; + + ptlSTAClient->tlState = WLANTL_STA_INIT; + ptlSTAClient->tlPri = WLANTL_STA_PRI_NORMAL; + + vos_zero_macaddr( &ptlSTAClient->wSTADesc.vSTAMACAddress ); + vos_zero_macaddr( &ptlSTAClient->wSTADesc.vBSSIDforIBSS ); + vos_zero_macaddr( &ptlSTAClient->wSTADesc.vSelfMACAddress ); + + ptlSTAClient->wSTADesc.ucSTAId = 0; + ptlSTAClient->wSTADesc.wSTAType = WLAN_STA_MAX; + + ptlSTAClient->wSTADesc.ucQosEnabled = 0; + ptlSTAClient->wSTADesc.ucAddRmvLLC = 0; + ptlSTAClient->wSTADesc.ucSwFrameTXXlation = 0; + ptlSTAClient->wSTADesc.ucSwFrameRXXlation = 0; + ptlSTAClient->wSTADesc.ucProtectedFrame = 0; + ptlSTAClient->disassoc_progress = VOS_FALSE; + /*------------------------------------------------------------------------- + AMSDU information for the STA + -------------------------------------------------------------------------*/ + if ( ( 0 != ucEmpty ) && + ( NULL != ptlSTAClient->vosAMSDUChainRoot )) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "WLAN TL:Non NULL vosAMSDUChainRoot on WLANTL_CleanSTA, " + "suspecting a memory corruption")); + + } + + ptlSTAClient->vosAMSDUChain = NULL; + ptlSTAClient->vosAMSDUChainRoot = NULL; + + vos_mem_zero( (v_PVOID_t)ptlSTAClient->aucMPDUHeader, + WLANTL_MPDU_HEADER_LEN); + ptlSTAClient->ucMPDUHeaderLen = 0; + + /*------------------------------------------------------------------------- + Reordering information for the STA + -------------------------------------------------------------------------*/ + for ( ucIndex = 0; ucIndex < WLAN_MAX_TID ; ucIndex++) + { + if(0 == ptlSTAClient->atlBAReorderInfo[ucIndex].ucExists) + { + continue; + } + if(NULL != ptlSTAClient->atlBAReorderInfo[ucIndex].reorderBuffer) + { + ptlSTAClient->atlBAReorderInfo[ucIndex].reorderBuffer->isAvailable = VOS_TRUE; + memset(&ptlSTAClient->atlBAReorderInfo[ucIndex].reorderBuffer->arrayBuffer[0], 0, WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t)); + } + vos_timer_destroy(&ptlSTAClient->atlBAReorderInfo[ucIndex].agingTimer); + memset(&ptlSTAClient->atlBAReorderInfo[ucIndex], 0, sizeof(WLANTL_BAReorderType)); + } + + /*------------------------------------------------------------------------- + QOS information for the STA + -------------------------------------------------------------------------*/ + ptlSTAClient->ucCurrentAC = WLANTL_AC_HIGH_PRIO; + ptlSTAClient->ucCurrentWeight = 0; + ptlSTAClient->ucServicedAC = WLANTL_AC_BK; + + vos_mem_zero( ptlSTAClient->aucACMask, sizeof(ptlSTAClient->aucACMask)); + vos_mem_zero( &ptlSTAClient->wUAPSDInfo, sizeof(ptlSTAClient->wUAPSDInfo)); + + + /*-------------------------------------------------------------------- + Stats info + --------------------------------------------------------------------*/ + vos_mem_zero( ptlSTAClient->auRxCount, + sizeof(ptlSTAClient->auRxCount[0])* WLAN_MAX_TID); + vos_mem_zero( ptlSTAClient->auTxCount, + sizeof(ptlSTAClient->auTxCount[0])* WLAN_MAX_TID); + ptlSTAClient->rssiAvg = 0; + + /*Tx not suspended and station fully registered*/ + vos_atomic_set_U8( &ptlSTAClient->ucTxSuspended, 0); + vos_atomic_set_U8( &ptlSTAClient->ucNoMoreData, 1); + + if ( 0 == ucEmpty ) + { + ptlSTAClient->wSTADesc.ucUcastSig = WLAN_TL_INVALID_U_SIG; + ptlSTAClient->wSTADesc.ucBcastSig = WLAN_TL_INVALID_B_SIG; + } + + ptlSTAClient->ucExists = 0; + + /*-------------------------------------------------------------------- + Statistics info + --------------------------------------------------------------------*/ + memset(&ptlSTAClient->trafficStatistics, + 0, + sizeof(WLANTL_TRANSFER_STA_TYPE)); + + /*fix me!!: add new values from the TL Cb for cleanup */ + return VOS_STATUS_SUCCESS; +}/* WLANTL_CleanSTA */ + + +/*========================================================================== + FUNCTION WLANTL_EnableUAPSDForAC + + DESCRIPTION + Called by HDD to enable UAPSD. TL in turn calls WDA API to enable the + logic in FW/SLM to start sending trigger frames. Previously TL had the + trigger frame logic which later moved down to FW. Hence + HDD -> TL -> WDA -> FW call flow. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: station Id + ucAC: AC for which U-APSD is being enabled + ucTid: TID for which U-APSD is setup + ucUP: used to place in the trigger frame generation + ucServiceInt: service interval used by TL to send trigger frames + ucSuspendInt: suspend interval used by TL to determine that an + app is idle and should start sending trigg frms less often + wTSDir: direction of TSpec + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_EnableUAPSDForAC +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucAC, + v_U8_t ucTid, + v_U8_t ucUP, + v_U32_t uServiceInt, + v_U32_t uSuspendInt, + WLANTL_TSDirType wTSDir +) +{ + + WLANTL_CbType* pTLCb = NULL; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tUapsdInfo halUAPSDInfo; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (( NULL == pTLCb ) || WLANTL_STA_ID_INVALID( ucSTAId ) + || WLANTL_AC_INVALID(ucAC)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid input params on WLANTL_EnableUAPSDForAC" + " TL: %p STA: %d AC: %d", + pTLCb, ucSTAId, ucAC)); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*Set this flag in order to remember that this is a trigger enabled AC*/ + pTLCb->atlSTAClients[ucSTAId]->wUAPSDInfo[ucAC].ucSet = 1; + +#ifdef FEATURE_WLAN_TDLS + if(pTLCb->atlSTAClients[ucSTAId]->wSTADesc.wSTAType != WLAN_STA_TDLS) +#endif + { + if( 0 == uServiceInt ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Input params on WLANTL_EnableUAPSDForAC" + " SI: %d", uServiceInt )); + } + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Enabling U-APSD in FW for STA: %d AC: %d SI: %d SPI: %d " + "DI: %d", + ucSTAId, ucAC, uServiceInt, uSuspendInt, + pTLCb->tlConfigInfo.uDelayedTriggerFrmInt)); + + /*Save all info for HAL*/ + halUAPSDInfo.staidx = ucSTAId; + halUAPSDInfo.ac = ucAC; + halUAPSDInfo.up = ucUP; + halUAPSDInfo.srvInterval = uServiceInt; + halUAPSDInfo.susInterval = uSuspendInt; + halUAPSDInfo.delayInterval = pTLCb->tlConfigInfo.uDelayedTriggerFrmInt; + + /*Notify HAL*/ + vosStatus = WDA_EnableUapsdAcParams(pvosGCtx, ucSTAId, &halUAPSDInfo); + } + return vosStatus; + +}/*WLANTL_EnableUAPSDForAC*/ + + +/*========================================================================== + FUNCTION WLANTL_DisableUAPSDForAC + + DESCRIPTION + Called by HDD to disable UAPSD. TL in turn calls WDA API to disable the + logic in FW/SLM to stop sending trigger frames. Previously TL had the + trigger frame logic which later moved down to FW. Hence + HDD -> TL -> WDA -> FW call flow. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: station Id + ucAC: AC for which U-APSD is being enabled + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_DisableUAPSDForAC +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucAC +) +{ + WLANTL_CbType* pTLCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (( NULL == pTLCb ) || WLANTL_STA_ID_INVALID( ucSTAId ) + || WLANTL_AC_INVALID(ucAC) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid input params on WLANTL_DisableUAPSDForAC" + " TL: %p STA: %d AC: %d", pTLCb, ucSTAId, ucAC )); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*Reset this flag as this is no longer a trigger enabled AC*/ + pTLCb->atlSTAClients[ucSTAId]->wUAPSDInfo[ucAC].ucSet = 1; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Disabling U-APSD in FW for STA: %d AC: %d ", + ucSTAId, ucAC)); + + /*Notify HAL*/ + WDA_DisableUapsdAcParams(pvosGCtx, ucSTAId, ucAC); + + return VOS_STATUS_SUCCESS; +}/* WLANTL_DisableUAPSDForAC */ + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING +/*========================================================================== + FUNCTION WLANTL_RegRSSIIndicationCB + + DESCRIPTION Registration function to get notification if RSSI cross + threshold. + Client should register threshold, direction, and notification + callback function pointer + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in rssiValue - RSSI threshold value + in triggerEvent - Cross direction should be notified + UP, DOWN, and CROSS + in crossCBFunction - Notification CB Function + in usrCtxt - user context + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_RegRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID, + v_PVOID_t usrCtxt +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = WLANTL_HSRegRSSIIndicationCB(pAdapter, + rssiValue, + triggerEvent, + crossCBFunction, + moduleID, + usrCtxt); + + return status; +} + +/*========================================================================== + FUNCTION WLANTL_DeregRSSIIndicationCB + + DESCRIPTION Remove specific threshold from list + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in rssiValue - RSSI threshold value + in triggerEvent - Cross direction should be notified + UP, DOWN, and CROSS + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_DeregRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = WLANTL_HSDeregRSSIIndicationCB(pAdapter, + rssiValue, + triggerEvent, + crossCBFunction, + moduleID); + return status; +} + +/*========================================================================== + FUNCTION WLANTL_SetAlpha + + DESCRIPTION ALPLA is weight value to calculate AVG RSSI + avgRSSI = (ALPHA * historyRSSI) + ((10 - ALPHA) * newRSSI) + avgRSSI has (ALPHA * 10)% of history RSSI weight and + (10 - ALPHA)% of newRSSI weight + This portion is dynamically configurable. + Default is ? + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in valueAlpah - ALPHA + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_SetAlpha +( + v_PVOID_t pAdapter, + v_U8_t valueAlpha +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = WLANTL_HSSetAlpha(pAdapter, valueAlpha); + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_BMPSRSSIRegionChangedNotification +( + v_PVOID_t pAdapter, + tpSirRSSINotification pRSSINotification +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = WLANTL_HSBMPSRSSIRegionChangedNotification(pAdapter, pRSSINotification); + return status; +} + +/*========================================================================== + FUNCTION WLANTL_RegGetTrafficStatus + + DESCRIPTION Registration function for traffic status monitoring + During measure period count data frames. + If frame count is larger then IDLE threshold set as traffic ON + or OFF. + And traffic status is changed send report to client with + registered callback function + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in idleThreshold - Traffic on or off threshold + in measurePeriod - Traffic state check period + in trfficStatusCB - traffic status changed notification + CB function + in usrCtxt - user context + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_RegGetTrafficStatus +( + v_PVOID_t pAdapter, + v_U32_t idleThreshold, + v_U32_t measurePeriod, + WLANTL_TrafficStatusChangedCBType trfficStatusCB, + v_PVOID_t usrCtxt +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = WLANTL_HSRegGetTrafficStatus(pAdapter, + idleThreshold, + measurePeriod, + trfficStatusCB, + usrCtxt); + return status; +} +#endif +/*========================================================================== + FUNCTION WLANTL_GetStatistics + + DESCRIPTION Get traffic statistics for identified station + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + out statBuffer - traffic statistics buffer + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetStatistics +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STA_TYPE *statBuffer, + v_U8_t STAid +) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + WLANTL_STAClientType* pClientSTA = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_TRANSFER_STA_TYPE *statistics = NULL; + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer on WLANTL_GetStatistics")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[STAid]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if(0 == pClientSTA->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: %d STA ID does not exist", STAid)); + return VOS_STATUS_E_INVAL; + } + + if(NULL == statBuffer) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL statistics buffer pointer on WLANTL_GetStatistics")); + return VOS_STATUS_E_INVAL; + } + + statistics = &pClientSTA->trafficStatistics; + vos_mem_copy(statBuffer, statistics, sizeof(WLANTL_TRANSFER_STA_TYPE)); + + return status; +} + +/*========================================================================== + FUNCTION WLANTL_ResetStatistics + + DESCRIPTION Reset statistics structure for identified station ID + Reset means set values as 0 + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_ResetStatistics +( + v_PVOID_t pAdapter, + v_U8_t STAid +) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + WLANTL_STAClientType* pClientSTA = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_TRANSFER_STA_TYPE *statistics = NULL; + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer on WLANTL_GetStatistics")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[STAid]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if(0 == pClientSTA->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: %d STA ID does not exist", STAid)); + return VOS_STATUS_E_INVAL; + } + + statistics = &pClientSTA->trafficStatistics; + vos_mem_zero((v_VOID_t *)statistics, sizeof(WLANTL_TRANSFER_STA_TYPE)); + + return status; +} + +/*========================================================================== + FUNCTION WLANTL_GetSpecStatistic + + DESCRIPTION Get specific field within statistics structure for + identified station ID + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + in STAid - Station ID + out buffer - Statistic value + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetSpecStatistic +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STATIC_TYPE statType, + v_U32_t *buffer, + v_U8_t STAid +) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + WLANTL_STAClientType* pClientSTA = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_TRANSFER_STA_TYPE *statistics = NULL; + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer on WLANTL_GetStatistics")); + return VOS_STATUS_E_FAULT; + } + pClientSTA = pTLCb->atlSTAClients[STAid]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if(0 == pClientSTA->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: %d STA ID does not exist", STAid)); + return VOS_STATUS_E_INVAL; + } + + if(NULL == buffer) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL statistic buffer pointer on WLANTL_GetStatistics")); + return VOS_STATUS_E_INVAL; + } + + statistics = &pClientSTA->trafficStatistics; + switch(statType) + { + case WLANTL_STATIC_TX_UC_FCNT: + *buffer = statistics->txUCFcnt; + break; + + case WLANTL_STATIC_TX_MC_FCNT: + *buffer = statistics->txMCFcnt; + break; + + case WLANTL_STATIC_TX_BC_FCNT: + *buffer = statistics->txBCFcnt; + break; + + case WLANTL_STATIC_TX_UC_BCNT: + *buffer = statistics->txUCBcnt; + break; + + case WLANTL_STATIC_TX_MC_BCNT: + *buffer = statistics->txMCBcnt; + break; + + case WLANTL_STATIC_TX_BC_BCNT: + *buffer = statistics->txBCBcnt; + break; + + case WLANTL_STATIC_RX_UC_FCNT: + *buffer = statistics->rxUCFcnt; + break; + + case WLANTL_STATIC_RX_MC_FCNT: + *buffer = statistics->rxMCFcnt; + break; + + case WLANTL_STATIC_RX_BC_FCNT: + *buffer = statistics->rxBCFcnt; + break; + + case WLANTL_STATIC_RX_UC_BCNT: + *buffer = statistics->rxUCBcnt; + break; + + case WLANTL_STATIC_RX_MC_BCNT: + *buffer = statistics->rxMCBcnt; + break; + + case WLANTL_STATIC_RX_BC_BCNT: + *buffer = statistics->rxBCBcnt; + break; + + case WLANTL_STATIC_RX_BCNT: + *buffer = statistics->rxBcnt; + break; + + case WLANTL_STATIC_RX_BCNT_CRC_OK: + *buffer = statistics->rxBcntCRCok; + break; + + case WLANTL_STATIC_RX_RATE: + *buffer = statistics->rxRate; + break; + + default: + *buffer = 0; + status = VOS_STATUS_E_INVAL; + break; + } + + + return status; +} + +/*========================================================================== + FUNCTION WLANTL_ResetSpecStatistic + + DESCRIPTION Reset specific field within statistics structure for + identified station ID + Reset means set as 0 + + DEPENDENCIES NONE + + PARAMETERS in pAdapter - Global handle + in statType - specific statistics field to reset + in STAid - Station ID + + RETURN VALUE VOS_STATUS + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_ResetSpecStatistic +( + v_PVOID_t pAdapter, + WLANTL_TRANSFER_STATIC_TYPE statType, + v_U8_t STAid +) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + WLANTL_STAClientType* pClientSTA = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_TRANSFER_STA_TYPE *statistics = NULL; + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer on WLANTL_GetStatistics")); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[STAid]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if(0 == pClientSTA->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: %d STA ID does not exist", STAid)); + return VOS_STATUS_E_INVAL; + } + + statistics = &pClientSTA->trafficStatistics; + switch(statType) + { + case WLANTL_STATIC_TX_UC_FCNT: + statistics->txUCFcnt = 0; + break; + + case WLANTL_STATIC_TX_MC_FCNT: + statistics->txMCFcnt = 0; + break; + + case WLANTL_STATIC_TX_BC_FCNT: + statistics->txBCFcnt = 0; + break; + + case WLANTL_STATIC_TX_UC_BCNT: + statistics->txUCBcnt = 0; + break; + + case WLANTL_STATIC_TX_MC_BCNT: + statistics->txMCBcnt = 0; + break; + + case WLANTL_STATIC_TX_BC_BCNT: + statistics->txBCBcnt = 0; + break; + + case WLANTL_STATIC_RX_UC_FCNT: + statistics->rxUCFcnt = 0; + break; + + case WLANTL_STATIC_RX_MC_FCNT: + statistics->rxMCFcnt = 0; + break; + + case WLANTL_STATIC_RX_BC_FCNT: + statistics->rxBCFcnt = 0; + break; + + case WLANTL_STATIC_RX_UC_BCNT: + statistics->rxUCBcnt = 0; + break; + + case WLANTL_STATIC_RX_MC_BCNT: + statistics->rxMCBcnt = 0; + break; + + case WLANTL_STATIC_RX_BC_BCNT: + statistics->rxBCBcnt = 0; + break; + + case WLANTL_STATIC_RX_BCNT: + statistics->rxBcnt = 0; + break; + + case WLANTL_STATIC_RX_BCNT_CRC_OK: + statistics->rxBcntCRCok = 0; + break; + + case WLANTL_STATIC_RX_RATE: + statistics->rxRate = 0; + break; + + default: + status = VOS_STATUS_E_INVAL; + break; + } + + return status; +} + + +/*========================================================================== + + FUNCTION + + DESCRIPTION Read RSSI value out of a RX BD + + PARAMETERS: Caller must validate all parameters + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_ReadRSSI +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + v_S7_t currentRSSI, currentRSSI0, currentRSSI1; + + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "%s Invalid TL handle", __func__)); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == tlCtxt->atlSTAClients[STAid] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + currentRSSI0 = WLANTL_GETRSSI0(pBDHeader); + currentRSSI1 = WLANTL_GETRSSI1(pBDHeader); + currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1; + + tlCtxt->atlSTAClients[STAid]->rssiAvg = currentRSSI; + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION Read SNR value out of a RX BD + + PARAMETERS: Caller must validate all parameters + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_ReadSNR +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + v_S7_t currentSNR; + + + if (NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Invalid TL handle", __func__)); + return VOS_STATUS_E_INVAL; + } + + if (NULL == tlCtxt->atlSTAClients[STAid]) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + currentSNR = WLANTL_GETSNR(pBDHeader); + + /* SNR reported in the Buffer Descriptor is scaled up by 2(SNR*2), + * Get the correct SNR value + */ + currentSNR = currentSNR >> 1; + + /* SNR reported by HW cannot be more than 35dB due to HW limitations */ + currentSNR = (WLANTL_MAX_HW_SNR > currentSNR ? currentSNR : + WLANTL_MAX_HW_SNR); + + TLLOG2(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: snrsum: %d snridx: %d prevsnravg: %d", + __func__, + tlCtxt->atlSTAClients[STAid]->snrSum, + tlCtxt->atlSTAClients[STAid]->snrIdx, + tlCtxt->atlSTAClients[STAid]->prevSnrAvg)); + + /* The SNR returned for all purposes is the average SNR over + * WLANTL_MAX_SNR_DATA_SMAPLES.When data samples + * > WLANTL_MAX_SNR_DATA_SAMPLES are obtained, + * store the average of the samples in prevSnrAvg + * and start a new averaging window. The prevSnrAvg is used when + * enough data samples are not available when applications + * actually query for SNR. + * + * SEE: WLANTL_GetSnr() + */ + if (tlCtxt->atlSTAClients[STAid]->snrIdx >= WLANTL_MAX_SNR_DATA_SAMPLES) + { + tlCtxt->atlSTAClients[STAid]->prevSnrAvg = + tlCtxt->atlSTAClients[STAid]->snrSum / + tlCtxt->atlSTAClients[STAid]->snrIdx; + tlCtxt->atlSTAClients[STAid]->snrSum = 0; + tlCtxt->atlSTAClients[STAid]->snrIdx = 0; + } + tlCtxt->atlSTAClients[STAid]->snrSum += currentSNR; + tlCtxt->atlSTAClients[STAid]->snrIdx += 1; + + return VOS_STATUS_SUCCESS; +} + +/* + DESCRIPTION + TL returns the weight currently maintained in TL. + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + + OUT + pACWeights: Caller allocated memory for filling in weights + + RETURN VALUE VOS_STATUS +*/ +VOS_STATUS +WLANTL_GetACWeights +( + v_PVOID_t pvosGCtx, + v_U8_t* pACWeights +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U8_t ucIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pACWeights ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_GetACWeights")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_GetACWeights")); + return VOS_STATUS_E_FAULT; + } + for ( ucIndex = 0; ucIndex < WLANTL_MAX_AC ; ucIndex++) + { + pACWeights[ucIndex] = pTLCb->tlConfigInfo.ucAcWeights[ucIndex]; + } + + return VOS_STATUS_SUCCESS; +} + + + +/* + DESCRIPTION + Change the weight currently maintained by TL. + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + or SME's control block can be extracted from its context + pACWeights: Caller allocated memory contain the weights to use + + + RETURN VALUE VOS_STATUS +*/ +VOS_STATUS +WLANTL_SetACWeights +( + v_PVOID_t pvosGCtx, + v_U8_t* pACWeights +) +{ + WLANTL_CbType* pTLCb = NULL; + v_U8_t ucIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pACWeights ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_GetACWeights")); + return VOS_STATUS_E_INVAL; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_GetACWeights")); + return VOS_STATUS_E_FAULT; + } + for ( ucIndex = 0; ucIndex < WLANTL_MAX_AC ; ucIndex++) + { + pTLCb->tlConfigInfo.ucAcWeights[ucIndex] = pACWeights[ucIndex]; + } + + pTLCb->tlConfigInfo.ucAcWeights[WLANTL_AC_HIGH_PRIO] = pACWeights[WLANTL_AC_VO]; + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +void WLANTL_PowerStateChangedCB +( + v_PVOID_t pAdapter, + tPmcState newState +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + + if (NULL == tlCtxt) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid TL Control Block", __func__ ); + return; + } + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Power state changed, new state is %d", newState ); + switch(newState) + { + case FULL_POWER: + tlCtxt->isBMPS = VOS_FALSE; + break; + + case BMPS: +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + WLANTL_SetFWRSSIThresholds(pAdapter); +#endif + + tlCtxt->isBMPS = VOS_TRUE; + break; + + case IMPS: + case LOW_POWER: + case REQUEST_BMPS: + case REQUEST_FULL_POWER: + case REQUEST_IMPS: + case STOPPED: + case REQUEST_START_UAPSD: + case REQUEST_STOP_UAPSD: + case UAPSD: + case REQUEST_STANDBY: + case STANDBY: + case REQUEST_ENTER_WOWL: + case REQUEST_EXIT_WOWL: + case WOWL: + TLLOGW(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, "Not handle this events %d", newState )); + break; + + default: + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "Not a valid event %d", newState )); + break; + } + + return; +} +/*========================================================================== + FUNCTION WLANTL_GetEtherType + + DESCRIPTION Extract Ether type information from the BD + + DEPENDENCIES NONE + + PARAMETERS in aucBDHeader - BD header + in vosDataBuff - data buffer + in ucMPDUHLen - MPDU header length + out pUsEtherType - pointer to Ethertype + + RETURN VALUE VOS_STATUS_SUCCESS : if the EtherType is successfully extracted + VOS_STATUS_FAILURE : if the EtherType extraction failed and + the packet was dropped + + SIDE EFFECTS NONE + +============================================================================*/ +static VOS_STATUS WLANTL_GetEtherType +( + v_U8_t * aucBDHeader, + vos_pkt_t * vosDataBuff, + v_U8_t ucMPDUHLen, + v_U16_t * pUsEtherType +) +{ + v_U8_t ucOffset; + v_U16_t usEtherType = *pUsEtherType; + v_SIZE_t usLLCSize = sizeof(usEtherType); + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + /*------------------------------------------------------------------------ + Check if LLC is present - if not, TL is unable to determine type + ------------------------------------------------------------------------*/ + if ( VOS_FALSE == WDA_IS_RX_LLC_PRESENT( aucBDHeader ) ) + { + ucOffset = WLANTL_802_3_HEADER_LEN - sizeof(usEtherType); + } + else + { + ucOffset = ucMPDUHLen + WLANTL_LLC_PROTO_TYPE_OFFSET; + } + + /*------------------------------------------------------------------------ + Extract LLC type + ------------------------------------------------------------------------*/ + vosStatus = vos_pkt_extract_data( vosDataBuff, ucOffset, + (v_PVOID_t)&usEtherType, &usLLCSize); + + if (( VOS_STATUS_SUCCESS != vosStatus ) || + ( sizeof(usEtherType) != usLLCSize )) + + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Error extracting Ether type from data packet")); + /* Drop packet */ + vos_pkt_return_packet(vosDataBuff); + vosStatus = VOS_STATUS_E_FAILURE; + } + else + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Ether type retrieved before endianess conv: %d", + usEtherType)); + + usEtherType = vos_be16_to_cpu(usEtherType); + *pUsEtherType = usEtherType; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:Ether type retrieved: %d", usEtherType)); + } + + return vosStatus; +} + +/*========================================================================== + FUNCTION WLANTL_GetSoftAPStatistics + + DESCRIPTION Collect the cumulative statistics for all Softap stations + + DEPENDENCIES NONE + + PARAMETERS in pvosGCtx - Pointer to the global vos context + bReset - If set TL statistics will be cleared after reading + out statsSum - pointer to collected statistics + + RETURN VALUE VOS_STATUS_SUCCESS : if the Statistics are successfully extracted + + SIDE EFFECTS NONE + +============================================================================*/ +VOS_STATUS WLANTL_GetSoftAPStatistics(v_PVOID_t pAdapter, WLANTL_TRANSFER_STA_TYPE *statsSum, v_BOOL_t bReset) +{ + v_U8_t i = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + WLANTL_TRANSFER_STA_TYPE statBufferTemp; + vos_mem_zero((v_VOID_t *)&statBufferTemp, sizeof(WLANTL_TRANSFER_STA_TYPE)); + vos_mem_zero((v_VOID_t *)statsSum, sizeof(WLANTL_TRANSFER_STA_TYPE)); + + + if ( NULL == pTLCb ) + { + return VOS_STATUS_E_FAULT; + } + + // Sum up all the statistics for stations of Soft AP from TL + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) + { + if ( NULL == pTLCb->atlSTAClients[i]) + { + continue; + } + if (pTLCb->atlSTAClients[i]->wSTADesc.wSTAType == WLAN_STA_SOFTAP) + { + vosStatus = WLANTL_GetStatistics(pAdapter, &statBufferTemp, i);// Can include staId 1 because statistics not collected for it + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + return VOS_STATUS_E_FAULT; + + // Add to the counters + statsSum->txUCFcnt += statBufferTemp.txUCFcnt; + statsSum->txMCFcnt += statBufferTemp.txMCFcnt; + statsSum->txBCFcnt += statBufferTemp.txBCFcnt; + statsSum->txUCBcnt += statBufferTemp.txUCBcnt; + statsSum->txMCBcnt += statBufferTemp.txMCBcnt; + statsSum->txBCBcnt += statBufferTemp.txBCBcnt; + statsSum->rxUCFcnt += statBufferTemp.rxUCFcnt; + statsSum->rxMCFcnt += statBufferTemp.rxMCFcnt; + statsSum->rxBCFcnt += statBufferTemp.rxBCFcnt; + statsSum->rxUCBcnt += statBufferTemp.rxUCBcnt; + statsSum->rxMCBcnt += statBufferTemp.rxMCBcnt; + statsSum->rxBCBcnt += statBufferTemp.rxBCBcnt; + + if (bReset) + { + vosStatus = WLANTL_ResetStatistics(pAdapter, i); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + return VOS_STATUS_E_FAULT; + } + } + } + + return vosStatus; +} + +/*=============================================================================== + FUNCTION WLANTL_IsReplayPacket + + DESCRIPTION This function does replay check for valid stations + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS currentReplayCounter current replay counter taken from RX BD + previousReplayCounter previous replay counter taken from TL CB + + RETRUN VOS_TRUE packet is a replay packet + VOS_FALSE packet is not a replay packet + + SIDE EFFECTS none + ===============================================================================*/ +v_BOOL_t +WLANTL_IsReplayPacket +( + v_U64_t ullcurrentReplayCounter, + v_U64_t ullpreviousReplayCounter +) +{ + /* Do the replay check by comparing previous received replay counter with + current received replay counter*/ + if(ullpreviousReplayCounter < ullcurrentReplayCounter) + { + /* Valid packet not replay */ + return VOS_FALSE; + } + else + { + + /* Current packet number is less than or equal to previuos received + packet no, this means current packet is replay packet */ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Replay packet found with replay counter :[0x%llX]",ullcurrentReplayCounter); + + return VOS_TRUE; + } +} + +#if 0 +/*=============================================================================== + FUNCTION WLANTL_GetReplayCounterFromRxBD + + DESCRIPTION This function extracts 48-bit replay packet number from RX BD + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS pucRxHeader pointer to RX BD header + + RETRUN v_U64_t Packet number extarcted from RX BD + + SIDE EFFECTS none + ===============================================================================*/ +v_U64_t +WLANTL_GetReplayCounterFromRxBD +( + v_U8_t *pucRxBDHeader +) +{ +/* 48-bit replay counter is created as follows + from RX BD 6 byte PMI command: + Addr : AES/TKIP + 0x38 : pn3/tsc3 + 0x39 : pn2/tsc2 + 0x3a : pn1/tsc1 + 0x3b : pn0/tsc0 + + 0x3c : pn5/tsc5 + 0x3d : pn4/tsc4 */ + +#ifdef ANI_BIG_BYTE_ENDIAN + v_U64_t ullcurrentReplayCounter = 0; + /* Getting 48-bit replay counter from the RX BD */ + ullcurrentReplayCounter = WLANHAL_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); + ullcurrentReplayCounter <<= 16; + ullcurrentReplayCounter |= (( WLANHAL_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0xFFFF0000) >> 16); + return ullcurrentReplayCounter; +#else + v_U64_t ullcurrentReplayCounter = 0; + /* Getting 48-bit replay counter from the RX BD */ + ullcurrentReplayCounter = (WLANHAL_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0x0000FFFF); + ullcurrentReplayCounter <<= 32; + ullcurrentReplayCounter |= WLANHAL_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); + return ullcurrentReplayCounter; +#endif +} +#endif + +/*=============================================================================== + FUNCTION WLANTL_PostResNeeded + + DESCRIPTION This function posts message to TL to reserve BD/PDU memory + + DEPENDENCIES None + + PARAMETERS pvosGCtx + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_PostResNeeded(v_PVOID_t pvosGCtx) +{ + vos_msg_t vosMsg; + + vosMsg.reserved = 0; + vosMsg.bodyptr = NULL; + vosMsg.type = WLANTL_TX_RES_NEEDED; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: BD/PDU available interrupt received, Posting message to TL"); + if(!VOS_IS_STATUS_SUCCESS(vos_tx_mq_serialize( VOS_MQ_ID_TL, &vosMsg))) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " %s fails to post message", __func__); + } +} + +/*=============================================================================== + FUNCTION WLANTL_UpdateRssiBmps + + DESCRIPTION This function updates the TL's RSSI (in BMPS mode) + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + rssi RSSI (BMPS mode) RSSI in BMPS mode + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateRssiBmps(v_PVOID_t pvosGCtx, v_U8_t staId, v_S7_t rssi) +{ + WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx); + + if (NULL != pTLCb && NULL != pTLCb->atlSTAClients[staId]) + { + pTLCb->atlSTAClients[staId]->rssiAvgBmps = rssi; + } +} + +/*=============================================================================== + FUNCTION WLANTL_UpdateSnrBmps + + DESCRIPTION This function updates the TL's SNR (in BMPS mode) + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + snr SNR (BMPS mode) SNR in BMPS mode + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateSnrBmps(v_PVOID_t pvosGCtx, v_U8_t staId, v_S7_t snr) +{ + WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx); + + if (NULL != pTLCb && NULL != pTLCb->atlSTAClients[staId]) + { + pTLCb->atlSTAClients[staId]->snrAvgBmps = snr; + } +} + +/*=============================================================================== + FUNCTION WLANTL_UpdateLinkCapacity + + DESCRIPTION This function updates the STA's Link Capacity in TL + + DEPENDENCIES None + + PARAMETERS + + pvosGCtx VOS context VOS Global context + staId Station ID Station ID + linkCapacity linkCapacity Link Capacity + + RETURN None + + SIDE EFFECTS none + ===============================================================================*/ + +void WLANTL_UpdateLinkCapacity(v_PVOID_t pvosGCtx, v_U8_t staId, v_U32_t linkCapacity) +{ + WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx); + + if (NULL != pTLCb && NULL != pTLCb->atlSTAClients[staId]) + { + pTLCb->atlSTAClients[staId]->linkCapacity = linkCapacity; + } +} + + +/*=========================================================================== + + FUNCTION WLANTL_GetSTALinkCapacity + + DESCRIPTION + + Returns Link Capacity of a particular STA. + + DEPENDENCIES + + A station must have been registered before its state can be retrieved. + + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station + + OUT + plinkCapacity: the current link capacity the connection to + the given station + + + RETURN VALUE + + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer to + TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetSTALinkCapacity +( + v_PVOID_t pvosGCtx, + v_U8_t ucSTAId, + v_U32_t *plinkCapacity +) +{ + WLANTL_CbType* pTLCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == plinkCapacity ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Invalid parameter"))); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Invalid station id"))); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Invalid TL pointer from pvosGCtx"))); + return VOS_STATUS_E_FAULT; + } + + if ( NULL == pTLCb->atlSTAClients[ucSTAId] ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + FL("WLAN TL:Client Memory was not allocated"))); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pTLCb->atlSTAClients[ucSTAId]->ucExists ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + FL("WLAN TL:Station was not previously registered"))); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Get STA state + ------------------------------------------------------------------------*/ + *plinkCapacity = pTLCb->atlSTAClients[ucSTAId]->linkCapacity; + + return VOS_STATUS_SUCCESS; +}/* WLANTL_GetSTALinkCapacity */ + +/* + * WLANTL_ResetRxSSN - reset last rx ssn + * @pvosGCtx: global vos context + * @ucSTAId: station id + * + * This function resets the last ssn of all tids of the station + * for whom BA reorder session exists. + * + * Return: none + */ +void WLANTL_ResetRxSSN(v_PVOID_t pvosGCtx, uint8_t ucSTAId) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + uint8_t i; + + if (WLANTL_STA_ID_INVALID(ucSTAId)) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested WLANTL_ResetRxSSN")); + return; + } + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx WLANTL_ResetRxSSN")); + return; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + for (i = 0; i < WLAN_MAX_TID ; i++) { + if (0 == pClientSTA->atlBAReorderInfo[i].ucExists) { + continue; + } + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: Last RxSSN reset to zero for tid %d", i)); + pClientSTA->atlBAReorderInfo[i].LastSN = 0; + } +} + +void WLANTL_SetDataPktFilter(v_PVOID_t pvosGCtx, uint8_t ucSTAId, bool flag) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType* pClientSTA = NULL; + uint8_t i; + + if (WLANTL_STA_ID_INVALID(ucSTAId)) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid station id requested", __func__)); + return; + } + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid TL pointer from pvosGCtx", __func__)); + return; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + for (i = 0; i < WLAN_MAX_TID ; i++) { + if (0 == pClientSTA->atlBAReorderInfo[i].ucExists) + continue; + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL: Last RxSSN reset to zero for tid %d", i)); + pClientSTA->atlBAReorderInfo[i].set_data_filter = flag; + } +} + +/** + * WLANTL_ShiftArrByOne() - utility function to shift array by one + * @arr: pointer to array + * @len: length of the array + * + * Caller responsibility to provide the correct length of the array + * other may leads to bugs. + * + * Return: void + */ +static void WLANTL_ShiftArrByOne(uint32_t *arr, uint8_t len) +{ + int i; + for (i = 0; i < len - 1; i ++) + arr[i] = arr[i + 1]; + arr[i] = 0; +} + +/** + * WLANTL_SampleTx() - collect tx samples + * @data: TL context pointer + * + * This function records the last five tx bytes sent samples + * collected after tx_bytes_timer expire. + * + * Return: void + */ +void WLANTL_SampleTx(void *data) +{ + WLANTL_CbType* pTLCb = (WLANTL_CbType *)data; + WLANTL_STAClientType* pClientSTA = NULL; + uint8_t count = pTLCb->sample_count; + uint8_t i; + + for ( i = 0; i < WLAN_MAX_STA_COUNT; i++) { + if (NULL != pTLCb->atlSTAClients[i] && + pTLCb->atlSTAClients[i]->ucExists) { + pClientSTA = pTLCb->atlSTAClients[i]; + + if (count > (WLANTL_SAMPLE_COUNT - 1)) { + count = WLANTL_SAMPLE_COUNT - 1; + pClientSTA->tx_samples_sum -= pClientSTA->tx_sample[0]; + WLANTL_ShiftArrByOne(pClientSTA->tx_sample, WLANTL_SAMPLE_COUNT); + } + + pClientSTA->tx_sample[count] = pClientSTA->tx_frames; + pClientSTA->tx_samples_sum += pClientSTA->tx_sample[count]; + pClientSTA->tx_frames = 0; + count++; + pTLCb->sample_count = count; + } + } + + vos_timer_start(&pTLCb->tx_frames_timer, WLANTL_SAMPLE_INTERVAL); +} + +/** + * WLANTL_EnablePreAssocCaching() - Enable caching EAPOL frames + * + * Return: None + * + */ +void WLANTL_EnablePreAssocCaching(void) +{ + v_PVOID_t pvosGCtx= vos_get_global_context(VOS_MODULE_ID_TL,NULL); + WLANTL_CbType* pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb ) { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid TL pointer for global context", __func__)); + return; + } + + pTLCb->vosEapolCachedFrame = NULL; + pTLCb->preassoc_caching = true; +} + +/** + * WLANTL_ForwardPreAssoc() - forward cached eapol frames + * @flag: Value to forward or flush + * + * Return: vos status + * + */ +static VOS_STATUS WLANTL_ForwardPreAssoc(bool flag) +{ + vos_msg_t sMessage; + + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " ---- Serializing TL for forwarding pre assoc cache frames"); + + vos_mem_zero( &sMessage, sizeof(vos_msg_t)); + sMessage.type = WLANTL_RX_FWD_PRE_ASSOC_CACHED; + sMessage.bodyval = flag; + + return vos_rx_mq_serialize(VOS_MQ_ID_TL, &sMessage); +} + +/** + * WLANTL_PreAssocForward() - forward cached eapol frames + * @flag: Value to forward or flush + * + * Return: None + * + */ +void WLANTL_PreAssocForward(bool flag) +{ + if(!VOS_IS_STATUS_SUCCESS(WLANTL_ForwardPreAssoc(flag))) + { + VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " %s fails to forward packets", __func__); + } +} + +/** + * WLANTL_RegisterFwdEapol() - register call back to forward cached eapol frame + * @pvosGCtx : pointer to vos global context + * @pfnFwdEapol: call back function pointer + * + * Return: None + * + */ +void WLANTL_RegisterFwdEapol(v_PVOID_t pvosGCtx, + WLANTL_FwdEapolCBType pfnFwdEapol) +{ + WLANTL_CbType* pTLCb = NULL; + pTLCb = VOS_GET_TL_CB(pvosGCtx); + + pTLCb->pfnEapolFwd = pfnFwdEapol; + +} + + /** + * WLANTL_SetARPFWDatapath() - keep or remove FW in data path for ARP + * + * @flag: value to keep or remove FW from data path + * + * Return: void + */ +void WLANTL_SetARPFWDatapath(void * pvosGCtx, bool flag) +{ + + WLANTL_CbType* pTLCb = NULL; + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid TL pointer from pvosGCtx", __func__)); + return; + } + + pTLCb->track_arp = flag; + +} + +#ifdef WLAN_FEATURE_RMC +VOS_STATUS WLANTL_RmcInit +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tANI_U8 count; + + /*sanity check*/ + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + for ( count = 0; count < WLANTL_RMC_HASH_TABLE_SIZE; count++ ) + { + pTLCb->rmcSession[count] = NULL; + } + + vos_lock_init(&pTLCb->rmcLock); + + pTLCb->multicastDuplicateDetectionEnabled = 1; + pTLCb->rmcDataPathEnabled = 0; + + return status; +} + + +VOS_STATUS WLANTL_RmcDeInit +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *pTLCb = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + tANI_U8 count; + WLANTL_RMC_SESSION *pNode; + WLANTL_RMC_SESSION *pPrev; + + /*sanity check*/ + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + for ( count = 0; count < WLANTL_RMC_HASH_TABLE_SIZE; count++ ) + { + pNode = pTLCb->rmcSession[count]; + while (pNode) + { + pPrev = pNode; + pNode = pNode->next; + vos_mem_free((v_VOID_t * )pPrev); + } + } + + vos_lock_destroy(&pTLCb->rmcLock); + + return status; +} + + +tANI_U8 WLANTL_RmcHashRmcSession ( v_MACADDR_t *pMcastAddr ) +{ + tANI_U32 sum; + tANI_U8 hash; + + sum = (pMcastAddr->bytes[0] + pMcastAddr->bytes[1] + pMcastAddr->bytes[2] + + pMcastAddr->bytes[3] + pMcastAddr->bytes[4] + pMcastAddr->bytes[5]); + + hash = (tANI_U8)(sum & ((WLANTL_RMC_HASH_TABLE_SIZE - 1))); + + return hash; +} + + +WLANTL_RMC_SESSION* WLANTL_RmcLookUpRmcSession +( + WLANTL_RMC_SESSION *rmcSession[], + v_MACADDR_t *pMcastAddr +) +{ + WLANTL_RMC_SESSION *pNode; + tANI_U8 index; + + /*sanity check*/ + if (NULL == pMcastAddr) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Sanity check failed pMcastAddr %p", pMcastAddr)); + return NULL; + } + + index = WLANTL_RmcHashRmcSession(pMcastAddr); + pNode = rmcSession[index]; + while ( pNode ) + { + if (vos_is_macaddr_equal( &(pNode->rmcAddr), pMcastAddr)) + { + return pNode; + } + pNode = pNode->next; + } + + return NULL; +} + +WLANTL_RMC_SESSION *WLANTL_RmcAddRmcSession +( + WLANTL_RMC_SESSION *rmcSession[], + v_MACADDR_t *pMcastAddr +) +{ + WLANTL_RMC_SESSION *pNode; + tANI_U8 index; + + index = WLANTL_RmcHashRmcSession(pMcastAddr); + pNode = WLANTL_RmcLookUpRmcSession(rmcSession, pMcastAddr); + if ( NULL != pNode ) + { + /*already exists*/ + return NULL; + } + else + { + pNode = (WLANTL_RMC_SESSION *)vos_mem_malloc(sizeof(*pNode)); + if (pNode) + { + vos_mem_copy( &(pNode->rmcAddr), pMcastAddr, + sizeof(pNode->rmcAddr) ); + pNode->next = rmcSession[index]; + rmcSession[index] = pNode; + return pNode; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_malloc failed can't enable RMC session", + __func__); + return NULL; + } + } +} + +tANI_U8 +WLANTL_RmcDeleteRmcSession +( + WLANTL_RMC_SESSION *rmcSession[], + v_MACADDR_t *pMcastAddr +) +{ + WLANTL_RMC_SESSION *pHead; + WLANTL_RMC_SESSION *pNode; + WLANTL_RMC_SESSION *pPrev; + tANI_U8 index; + + index = WLANTL_RmcHashRmcSession(pMcastAddr); + pHead = pNode = rmcSession[index]; + while (pNode) + { + if (vos_is_macaddr_equal( &(pNode->rmcAddr), pMcastAddr)) + { + if (pHead == pNode) + { + rmcSession[index] = pNode->next; + } + else + { + pPrev->next = pNode->next; + } + vos_mem_free((v_VOID_t * )pNode); + return 1; + } + pPrev = pNode; + pNode = pNode->next; + } + + return 0; +} + +VOS_STATUS +WLANTL_ProcessRmcCommand +( + WLANTL_CbType* pTLCb, + v_MACADDR_t *pMcastAddr, + tANI_U32 command +) +{ + VOS_STATUS status; + tANI_U32 count; + tANI_U32 rmcActive; + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire( &(pTLCb->rmcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Get Lock Fail", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*add or delete node from active rmc hash table*/ + if (command) + { + /*add requested rmc session in active rmc session list*/ + if (WLANTL_RmcAddRmcSession(pTLCb->rmcSession, pMcastAddr)) + { + TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "RMC session " MAC_ADDRESS_STR " added in TL hash table", + MAC_ADDR_ARRAY(pMcastAddr->bytes) ) ); + pTLCb->rmcDataPathEnabled = TRUE; + status = VOS_STATUS_SUCCESS; + } + else + { + TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "RMC session " MAC_ADDRESS_STR " already exists in TL hash" + " table", MAC_ADDR_ARRAY(pMcastAddr->bytes) ) ); + status = VOS_STATUS_E_FAILURE; + } + } + else + { + /*delete requested rmc session from active rmc session list*/ + if (WLANTL_RmcDeleteRmcSession(pTLCb->rmcSession, pMcastAddr)) + { + TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "RMC session " MAC_ADDRESS_STR " deleted from TL hash table", + MAC_ADDR_ARRAY(pMcastAddr->bytes)) ); + status = VOS_STATUS_SUCCESS; + rmcActive = FALSE; + for ( count = 0; count < WLANTL_RMC_HASH_TABLE_SIZE; count++ ) + { + if (pTLCb->rmcSession[count]) + { + rmcActive = TRUE; + break; + } + } + if (TRUE == rmcActive) + { + pTLCb->rmcDataPathEnabled = TRUE; + } + else + { + pTLCb->rmcDataPathEnabled = FALSE; + } + } + else + { + TLLOGE( VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "RMC session " MAC_ADDRESS_STR " doesn't exist in TL hash" + " table", MAC_ADDR_ARRAY(pMcastAddr->bytes) ) ); + status = VOS_STATUS_E_FAILURE; + } + } + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_release(&(pTLCb->rmcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Release Lock Fail", __func__)); + return VOS_STATUS_E_FAILURE; + } + + return status; +}/* End of WLANTL_ProcessRmcCommand */ + +VOS_STATUS +WLANTL_EnableRMC +( + v_PVOID_t pvosGCtx, + v_MACADDR_t *pMcastTransmitterAddr +) +{ + WLANTL_CbType* pTLCb; + VOS_STATUS status; + + /*sanity check*/ + if ( (NULL == pvosGCtx) || (NULL == pMcastTransmitterAddr) ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: Sanity check failed pvosGCtx %p aMcastAddr %p", + __func__, pvosGCtx, pMcastTransmitterAddr)); + return VOS_STATUS_E_FAILURE; + } + + /*sanity check*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: pTLCb is NULL", __func__)); + return VOS_STATUS_E_FAILURE; + } + + status = WLANTL_ProcessRmcCommand(pTLCb, pMcastTransmitterAddr , 1); + + return status; +} /* End of WLANTL_EnableRMC */ + + +VOS_STATUS +WLANTL_DisableRMC +( + v_PVOID_t pvosGCtx, + v_MACADDR_t *pMcastTransmitterAddr +) +{ + WLANTL_CbType* pTLCb; + VOS_STATUS status; + + /*Sanity check*/ + if ((NULL == pvosGCtx) || (NULL == pMcastTransmitterAddr)) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: Sanity check failed pvosGCtx %p aMcastAddr %p", + __func__, pvosGCtx, pMcastTransmitterAddr)); + return VOS_STATUS_E_FAILURE; + } + + /*Sanity check*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: pTLCb is NULL", __func__)); + return VOS_STATUS_E_FAILURE; + } + + status = WLANTL_ProcessRmcCommand(pTLCb, pMcastTransmitterAddr, 0); + + return status; +} /* End of WLANTL_DisableRMC */ + + +/*============================================================================= + Duplicate Multicast Detection Functions +==============================================================================*/ + +/*============================================================================= + FUNCTION WLANTL_IsDuplicateMcastFrm + + DESCRIPTION + This function checks for duplicast multicast frames and drops them. + + DEPENDENCIES + + PARAMETERS + + IN + + pClientSTA : Pointer to WLANTL_STAClientType + aucBDHeader : Pointer to BD header + + RETURN VALUE + + VOS_FALSE: This frame is not a duplicate + + VOS_TRUE: This frame is a duplicate + +==============================================================================*/ +v_U8_t +WLANTL_IsDuplicateMcastFrm +( + WLANTL_STAClientType *pClientSTA, + vos_pkt_t *vosDataBuff +) +{ + v_U8_t duplicate = VOS_FALSE; + WLANTL_RMC_SESSION *pNode; + v_U16_t usSeqCtrl; + v_MACADDR_t mcastAddr; + VOS_STATUS vosStatus; + v_PVOID_t pvPeekData; + + /* Get address 1 of Data Frame */ + vosStatus = vos_pkt_peek_data(vosDataBuff, WLANTL_MAC_ADDR_ALIGN(1), + (v_PVOID_t)&pvPeekData, VOS_MAC_ADDR_SIZE); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to get Addr 1 of 80211 header from packet %d", + vosStatus)); + return VOS_FALSE; + } + + /* Copy address 1 of Data Frame */ + vos_mem_copy(&mcastAddr.bytes, pvPeekData, VOS_MAC_ADDR_SIZE); + + /* + * We perform duplicate detection for only multicast data frames + */ + if (vos_is_macaddr_group(&mcastAddr) && + !vos_is_macaddr_broadcast(&mcastAddr)) + { + /* Get sequence control of Data Frame */ + vosStatus = vos_pkt_peek_data(vosDataBuff, + (WLANTL_MAC_ADDR_ALIGN(1) + (3 * VOS_MAC_ADDR_SIZE)), + (v_PVOID_t)&pvPeekData, sizeof(v_U16_t)); + + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL: Failed to get Sequence Control from packet %d", + vosStatus)); + return VOS_FALSE; + } + + /* Copy sequence control from the Data Frame */ + usSeqCtrl = *(v_U16_t *)pvPeekData; + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&(pClientSTA->mcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Get Lock Fail", __func__)); + return VOS_FALSE; + } + + pNode = WLANTL_RmcLookUpRmcSession(pClientSTA->mcastSession, + &mcastAddr); + if (NULL == pNode) + { + /* If the session does not exist, add it. */ + pNode = WLANTL_RmcAddRmcSession(pClientSTA->mcastSession, + &mcastAddr); + /* If we could not add a entry, skip duplicate detection */ + if (NULL == pNode) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Failed to add multicast session", __func__)); + if (!VOS_IS_STATUS_SUCCESS + (vos_lock_release(&(pClientSTA->mcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Release Lock Fail", __func__)); + } + return VOS_FALSE; + } + /* Initialize the sequence control value. */ + pNode->mcSeqCtl = usSeqCtrl; + } + else + { + /* + * Check if the sequence number of this frame matches the last + * we have seen. + */ + if (pNode->mcSeqCtl == usSeqCtrl) + { + pNode->rxMCDupcnt++; + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s Rx Multicast Duplicate %d " MAC_ADDRESS_STR + " (Seq %x)", __func__, + pNode->rxMCDupcnt, MAC_ADDR_ARRAY(mcastAddr.bytes), + usSeqCtrl)); + duplicate = VOS_TRUE; + } + else + { + /* Update the last seen sequence number */ + pNode->mcSeqCtl = usSeqCtrl; + } + } + + if (!VOS_IS_STATUS_SUCCESS (vos_lock_release(&(pClientSTA->mcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Release Lock Fail", __func__)); + } + } + + return duplicate; +} + +/*============================================================================= + FUNCTION WLANTL_McastDeleteAllEntries + + DESCRIPTION + This function removes all multicast entries used for duplicate detection + + DEPENDENCIES + + PARAMETERS + + IN + + pClientSTA : Pointer to WLANTL_STAClientType + + RETURN VALUE + + None + +==============================================================================*/ +void +WLANTL_McastDeleteAllEntries(WLANTL_STAClientType * pClientSTA) +{ + WLANTL_RMC_SESSION *pNode, **head; + int index; + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s Deleting all multicast entries", __func__)); + + if (!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&(pClientSTA->mcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Get Lock Fail", __func__)); + return; + } + + for (index = 0; index < WLANTL_RMC_HASH_TABLE_SIZE; index++) + { + head = &pClientSTA->mcastSession[index]; + + pNode = *head; + + while (pNode) + { + *head = pNode->next; + /* free the group entry */ + vos_mem_free(pNode); + pNode = *head; + } + } + + if (!VOS_IS_STATUS_SUCCESS (vos_lock_release(&(pClientSTA->mcLock)))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s Release Lock Fail", __func__)); + } +} + +/*============================================================================= + FUNCTION WLANTL_SetMcastDuplicateDetection + + DESCRIPTION + This function sets multicate duplicate detection operation. + If enable is 1, the detection is enabled, else it is disabled. + + DEPENDENCIES + + PARAMETERS + + IN + + pvosGCtx : Pointer to VOS global context + enable : Boolean to enable or disable + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: Sanity check on input failed + + VOS_STATUS_SUCCESS: Everything is good :) + + Other return values are possible coming from the called functions. + Please check API for additional info. + + SIDE EFFECTS + +==============================================================================*/ +VOS_STATUS +WLANTL_SetMcastDuplicateDetection +( + v_PVOID_t pvosGCtx, + v_U8_t enable +) +{ + WLANTL_CbType* pTLCb; + + /*Sanity check*/ + if (NULL == pvosGCtx) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: Sanity check failed pvosGCtx %p", + __func__, pvosGCtx)); + return VOS_STATUS_E_FAILURE; + } + + /*Sanity check*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: pTLCb is NULL", __func__)); + return VOS_STATUS_E_FAILURE; + } + + switch (enable) + { + default: + /* + * Any value other than 0 or 1 is used to dump the + * duplicate count. + */ + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: Multicast Duplicate Count %d", + __func__, pTLCb->mcastDupCnt)); + break; + case 0: + case 1: + pTLCb->multicastDuplicateDetectionEnabled = enable; + break; + } + + return VOS_STATUS_SUCCESS; +} + +#endif /* WLAN_FEATURE_RMC */ diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c new file mode 100644 index 000000000000..b97af6cfdf16 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_ba.c @@ -0,0 +1,1929 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + W L A N _ Q C T _ T L _ B A. C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Transport Layer + Block Ack session support. Also included are the AMSDU de-aggregation + completion and MSDU re-ordering functionality. + + The functions externalized by this module are to be called ONLY by the main + TL module or the HAL layer. + + DEPENDENCIES: + + Are listed for each API below. +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-10-xx dli Change ucCIndex to point to the slot the next frame to be expected to fwd +2008-08-22 sch Update based on unit test +2008-07-31 lti Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_tl.h" +#include "wlan_qct_wda.h" +#include "wlan_qct_tli.h" +#include "wlan_qct_tli_ba.h" +#include "wlan_qct_hal.h" +#include "wlan_qct_tl_trace.h" +#include "vos_trace.h" +#include "vos_types.h" +#include "vos_list.h" +#include "vos_lock.h" +#include "tlDebug.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +//#define WLANTL_REORDER_DEBUG_MSG_ENABLE +#define WLANTL_BA_REORDERING_AGING_TIMER 30 /* 30 millisec */ +#define WLANTL_BA_MIN_FREE_RX_VOS_BUFFER 0 /* RX VOS buffer low threshold */ +#define CSN_WRAP_AROUND_THRESHOLD 3000 /* CSN wrap around threshold */ + + +const v_U8_t WLANTL_TID_2_AC[WLAN_MAX_TID] = { WLANTL_AC_BE, + WLANTL_AC_BK, + WLANTL_AC_BK, + WLANTL_AC_BE, + WLANTL_AC_VI, + WLANTL_AC_VI, + WLANTL_AC_VO, + WLANTL_AC_VO }; + +/*========================================================================== + + FUNCTION tlReorderingAgingTimerExpierCB + + DESCRIPTION + After aging timer expiered, all Qed frames have to be routed to upper + layer. Otherwise, there is possibilitied that ahng some frames + + PARAMETERS + v_PVOID_t timerUdata Timer callback user data + Has information about where frames should be + routed + + RETURN VALUE + VOS_STATUS_SUCCESS General success + VOS_STATUS_E_INVAL Invalid frame handle + +============================================================================*/ +v_VOID_t WLANTL_ReorderingAgingTimerExpierCB +( + v_PVOID_t timerUdata +) +{ + WLANTL_TIMER_EXPIER_UDATA_T *expireHandle; + WLANTL_BAReorderType *ReorderInfo; + WLANTL_CbType *pTLHandle; + WLANTL_STAClientType* pClientSTA = NULL; + vos_pkt_t *vosDataBuff; + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t ucSTAID; + v_U8_t ucTID; + v_U8_t opCode; + WLANTL_RxMetaInfoType wRxMetaInfo; + v_U32_t fwIdx = 0; + WDI_DS_RxMetaInfoType *pRxMetadata; + vos_pkt_t *pCurrent; + vos_pkt_t *pNext; + v_S15_t seq; + v_U32_t cIndex; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if(NULL == timerUdata) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Callback User data NULL")); + return; + } + + expireHandle = (WLANTL_TIMER_EXPIER_UDATA_T *)timerUdata; + ucSTAID = (v_U8_t)expireHandle->STAID; + ucTID = expireHandle->TID; + if(WLANTL_STA_ID_INVALID(ucSTAID) || WLANTL_TID_INVALID(ucTID)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"SID %d or TID %d is not valid", + ucSTAID, ucTID)); + return; + } + + pTLHandle = (WLANTL_CbType *)expireHandle->pTLHandle; + if(NULL == pTLHandle) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"TL Control block NULL")); + return; + } + + pClientSTA = pTLHandle->atlSTAClients[ucSTAID]; + if( NULL == pClientSTA ){ + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "TL:STA Memory not allocated STA ID: %d, %s", ucSTAID, __func__)); + return; + } + + ReorderInfo = &pClientSTA->atlBAReorderInfo[ucTID]; + if(NULL == ReorderInfo) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reorder data NULL, this could not happen SID %d, TID %d", + ucSTAID, ucTID)); + return; + } + + if(0 == pClientSTA->atlBAReorderInfo[ucTID].ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reorder session doesn't exist SID %d, TID %d", + ucSTAID, ucTID)); + return; + } + + if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(&ReorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Get LOCK Fail")); + return; + } + + if( 0 == pClientSTA->atlBAReorderInfo[ucTID].ucExists ) + { + vos_lock_release(&ReorderInfo->reorderLock); + return; + } + + opCode = WLANTL_OPCODE_FWDALL_DROPCUR; + vosDataBuff = NULL; + + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_REORDER_TIMER_EXP_CB, + ucSTAID , opCode )); + + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"BA timeout with %d pending frames, curIdx %d", ReorderInfo->pendingFramesCount, ReorderInfo->ucCIndex)); + + if(ReorderInfo->pendingFramesCount == 0) + { + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail")); + } + return; + } + + if(0 == ReorderInfo->ucCIndex) + { + fwIdx = ReorderInfo->winSize; + } + else + { + fwIdx = ReorderInfo->ucCIndex - 1; + } + + /* Do replay check before giving packets to upper layer + replay check code : check whether replay check is needed or not */ + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + v_U64_t ullpreviousReplayCounter = 0; + v_U64_t ullcurrentReplayCounter = 0; + v_U8_t ucloopCounter = 0; + v_BOOL_t status = 0; + + /*Do replay check for all packets which are in Reorder buffer */ + for(ucloopCounter = 0; ucloopCounter < WLANTL_MAX_WINSIZE; ucloopCounter++) + { + /*Get previous reply counter*/ + ullpreviousReplayCounter = pClientSTA->ullReplayCounter[ucTID]; + + /*Get current replay counter of packet in reorder buffer*/ + ullcurrentReplayCounter = ReorderInfo->reorderBuffer->ullReplayCounter[ucloopCounter]; + + /*Check for holes, if a hole is found in Reorder buffer then + no need to do replay check on it, skip the current + hole and do replay check on other packets*/ + if(NULL != (ReorderInfo->reorderBuffer->arrayBuffer[ucloopCounter])) + { + status = WLANTL_IsReplayPacket(ullcurrentReplayCounter, ullpreviousReplayCounter); + if(VOS_TRUE == status) + { + /*Increment the debug counter*/ + pClientSTA->ulTotalReplayPacketsDetected++; + + /*A replay packet found*/ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLANTL_ReorderingAgingTimerExpierCB: total dropped replay packets on STA ID %X is [0x%X]", + ucSTAID, pClientSTA->ulTotalReplayPacketsDetected); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLANTL_ReorderingAgingTimerExpierCB: replay packet found with PN : [0x%llX]", + ullcurrentReplayCounter); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLANTL_ReorderingAgingTimerExpierCB: Drop the replay packet with PN : [0x%llX]", + ullcurrentReplayCounter); + + ReorderInfo->reorderBuffer->arrayBuffer[ucloopCounter] = NULL; + ReorderInfo->reorderBuffer->ullReplayCounter[ucloopCounter] = 0; + } + else + { + /*Not a replay packet update previous replay counter*/ + pClientSTA->ullReplayCounter[ucTID] = ullcurrentReplayCounter; + } + } + else + { + /* A hole detected in Reorder buffer*/ + //BAMSGERROR("WLANTL_ReorderingAgingTimerExpierCB,hole detected\n",0,0,0); + + } + } + } + + cIndex = ReorderInfo->ucCIndex; + status = WLANTL_ChainFrontPkts(fwIdx, opCode, + &vosDataBuff, ReorderInfo, NULL); + ReorderInfo->ucCIndex = cIndex; + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make packet chain fail with Qed frames %d", status)); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail")); + } + return; + } + + if(NULL == pClientSTA->pfnSTARx) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Callback function NULL with STAID %d", ucSTAID)); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail")); + } + return; + } + + if(NULL == vosDataBuff) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"No pending frames, why triggered timer? ")); + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail")); + } + return; + } + + pCurrent = vosDataBuff; + + while (pCurrent != NULL) + { + vos_pkt_walk_packet_chain(pCurrent, &pNext, VOS_FALSE); + + if (NULL == pNext) + { + /* This is the last packet, retrieve its sequence number */ + pRxMetadata = WDI_DS_ExtractRxMetaData(VOS_TO_WPAL_PKT(pCurrent)); + seq = WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pRxMetadata); + } + pCurrent = pNext; + } + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%s: Sending out Frame no: %d to HDD", __func__, seq)); + ReorderInfo->LastSN = seq; + + if( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType) + { + WLANTL_FwdPktToHDD( expireHandle->pAdapter, vosDataBuff, ucSTAID); + } + else + { + wRxMetaInfo.ucUP = ucTID; + pClientSTA->pfnSTARx(expireHandle->pAdapter, + vosDataBuff, ucSTAID, &wRxMetaInfo); + } + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(&ReorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_ReorderingAgingTimerExpierCB, Release LOCK Fail")); + } + return; +}/*WLANTL_ReorderingAgingTimerExpierCB*/ + +/*---------------------------------------------------------------------------- + INTERACTION WITH TL Main + ---------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION WLANTL_InitBAReorderBuffer + + DESCRIPTION + Init Reorder buffer array + + PARAMETERS + v_PVOID_t pvosGCtx Global context + + RETURN VALUE + NONE + +============================================================================*/ + +void WLANTL_InitBAReorderBuffer +( + v_PVOID_t pvosGCtx +) +{ + WLANTL_CbType *pTLCb; + v_U32_t idx; + v_U32_t pIdx; + + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if (NULL == pTLCb) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid TL Control Block", __func__)); + return; + } + + for(idx = 0; idx < WLANTL_MAX_BA_SESSION; idx++) + { + pTLCb->reorderBufferPool[idx].isAvailable = VOS_TRUE; + for(pIdx = 0; pIdx < WLANTL_MAX_WINSIZE; pIdx++) + { + pTLCb->reorderBufferPool[idx].arrayBuffer[pIdx] = NULL; + pTLCb->reorderBufferPool[idx].ullReplayCounter[pIdx] = 0; + } + } + + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"BA reorder buffer init")); + return; +} + +/*========================================================================== + + FUNCTION WLANTL_BaSessionAdd + + DESCRIPTION + HAL notifies TL when a new Block Ack session is being added. + + DEPENDENCIES + A BA session on Rx needs to be added in TL before the response is + being sent out + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station for which requested the BA + session + ucTid: Tspec ID for the new BA session + uSize: size of the reordering window + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered or BA session already + exists + VOS_STATUS_E_NOSUPPORT: Not yet supported + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_BaSessionAdd +( + v_PVOID_t pvosGCtx, + v_U16_t sessionID, + v_U32_t ucSTAId, + v_U8_t ucTid, + v_U32_t uBufferSize, + v_U32_t winSize, + v_U32_t SSN +) +{ + WLANTL_CbType *pTLCb = NULL; + WLANTL_STAClientType *pClientSTA = NULL; + WLANTL_BAReorderType *reorderInfo; + v_U32_t idx; + VOS_STATUS status = VOS_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_TID_INVALID(ucTid)) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_BaSessionAdd"); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_BaSessionAdd"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_BaSessionAdd"); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if ( 0 == pClientSTA->ucExists ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Station was not yet registered on WLANTL_BaSessionAdd"); + return VOS_STATUS_E_EXISTS; + } + + reorderInfo = &pClientSTA->atlBAReorderInfo[ucTid]; + if (!VOS_IS_STATUS_SUCCESS( + vos_lock_acquire(&reorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Release LOCK Fail", __func__)); + return VOS_STATUS_E_FAULT; + } + /*------------------------------------------------------------------------ + Verify that BA session was not already added + ------------------------------------------------------------------------*/ + if ( 0 != reorderInfo->ucExists ) + { + reorderInfo->ucExists++; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:BA session already exists on WLANTL_BaSessionAdd"); + vos_lock_release(&reorderInfo->reorderLock); + return VOS_STATUS_E_EXISTS; + } + + /*------------------------------------------------------------------------ + Initialize new BA session + ------------------------------------------------------------------------*/ + for(idx = 0; idx < WLANTL_MAX_BA_SESSION; idx++) + { + if(VOS_TRUE == pTLCb->reorderBufferPool[idx].isAvailable) + { + pClientSTA->atlBAReorderInfo[ucTid].reorderBuffer = + &(pTLCb->reorderBufferPool[idx]); + pTLCb->reorderBufferPool[idx].isAvailable = VOS_FALSE; + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"%dth buffer available, buffer PTR 0x%p", + idx, + pClientSTA->atlBAReorderInfo[ucTid].reorderBuffer + )); + break; + } + } + + + if (WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType) + { + if (WLANTL_MAX_BA_SESSION == idx) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Number of Add BA request received more than allowed"); + vos_lock_release(&reorderInfo->reorderLock); + return VOS_STATUS_E_NOSUPPORT; + } + } + reorderInfo->timerUdata.pAdapter = pvosGCtx; + reorderInfo->timerUdata.pTLHandle = (v_PVOID_t)pTLCb; + reorderInfo->timerUdata.STAID = ucSTAId; + reorderInfo->timerUdata.TID = ucTid; + + /* BA aging timer */ + status = vos_timer_init(&reorderInfo->agingTimer, + VOS_TIMER_TYPE_SW, + WLANTL_ReorderingAgingTimerExpierCB, + (v_PVOID_t)(&reorderInfo->timerUdata)); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Timer Init Fail", __func__)); + vos_lock_release(&reorderInfo->reorderLock); + return status; + } + + pClientSTA->atlBAReorderInfo[ucTid].ucExists++; + pClientSTA->atlBAReorderInfo[ucTid].usCount = 0; + pClientSTA->atlBAReorderInfo[ucTid].ucCIndex = 0; + if(0 == winSize) + { + pClientSTA->atlBAReorderInfo[ucTid].winSize = WLANTL_MAX_WINSIZE; + } + else + { + pClientSTA->atlBAReorderInfo[ucTid].winSize = winSize; + } + pClientSTA->atlBAReorderInfo[ucTid].SSN = SSN; + pClientSTA->atlBAReorderInfo[ucTid].sessionID = sessionID; + pClientSTA->atlBAReorderInfo[ucTid].pendingFramesCount = 0; + pClientSTA->atlBAReorderInfo[ucTid].LastSN = SSN; + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:New BA session added for STA: %d TID: %d", + ucSTAId, ucTid)); + + if(!VOS_IS_STATUS_SUCCESS( + vos_lock_release(&reorderInfo->reorderLock))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Release LOCK Fail", __func__)); + return VOS_STATUS_E_FAULT; + } + return VOS_STATUS_SUCCESS; +}/* WLANTL_BaSessionAdd */ + +/*========================================================================== + + FUNCTION WLANTL_BaSessionDel + + DESCRIPTION + HAL notifies TL when a new Block Ack session is being deleted. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station for which requested the BA + session + ucTid: Tspec ID for the new BA session + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered or BA session already + exists + VOS_STATUS_E_NOSUPPORT: Not yet supported + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_BaSessionDel +( + v_PVOID_t pvosGCtx, + v_U16_t ucSTAId, + v_U8_t ucTid +) +{ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType *pClientSTA = NULL; + vos_pkt_t* vosDataBuff = NULL; + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + VOS_STATUS lockStatus = VOS_STATUS_E_FAILURE; + WLANTL_BAReorderType* reOrderInfo = NULL; + WLANTL_RxMetaInfoType wRxMetaInfo; + v_U32_t fwIdx = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( WLANTL_TID_INVALID(ucTid)) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_BaSessionDel"); + return VOS_STATUS_E_INVAL; + } + + if ( WLANTL_STA_ID_INVALID( ucSTAId ) ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid station id requested on WLANTL_BaSessionDel"); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract TL control block and check existance + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_BaSessionDel"); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if (( 0 == pClientSTA->ucExists ) && + ( 0 == pClientSTA->atlBAReorderInfo[ucTid].ucExists )) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Station was not yet registered on WLANTL_BaSessionDel"); + return VOS_STATUS_E_EXISTS; + } + else if(( 0 == pClientSTA->ucExists ) && + ( 0 != pClientSTA->atlBAReorderInfo[ucTid].ucExists )) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "STA was deleted but BA info is still there, just remove BA info"); + + reOrderInfo = &pClientSTA->atlBAReorderInfo[ucTid]; + reOrderInfo->reorderBuffer->isAvailable = VOS_TRUE; + memset(&reOrderInfo->reorderBuffer->arrayBuffer[0], + 0, + WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t)); + vos_timer_destroy(&reOrderInfo->agingTimer); + memset(reOrderInfo, 0, sizeof(WLANTL_BAReorderType)); + + return VOS_STATUS_SUCCESS; + } + + /*------------------------------------------------------------------------ + Verify that BA session was added + ------------------------------------------------------------------------*/ + if ( 0 == pClientSTA->atlBAReorderInfo[ucTid].ucExists ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL:BA session does not exists on WLANTL_BaSessionDel"); + return VOS_STATUS_E_EXISTS; + } + + + /*------------------------------------------------------------------------ + Send all pending packets to HDD + ------------------------------------------------------------------------*/ + reOrderInfo = &pClientSTA->atlBAReorderInfo[ucTid]; + + /*------------------------------------------------------------------------ + Invalidate reorder info here. This ensures that no packets are + bufferd after reorder buffer is cleaned. + */ + lockStatus = vos_lock_acquire(&reOrderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Unable to acquire reorder vos lock in %s", __func__)); + return lockStatus; + } + pClientSTA->atlBAReorderInfo[ucTid].ucExists = 0; + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Fwd all packets to HDD on WLANTL_BaSessionDel")); + + if(0 == reOrderInfo->ucCIndex) + { + fwIdx = reOrderInfo->winSize; + } + else + { + fwIdx = reOrderInfo->ucCIndex - 1; + } + + if(0 != reOrderInfo->pendingFramesCount) + { + vosStatus = WLANTL_ChainFrontPkts(fwIdx, + WLANTL_OPCODE_FWDALL_DROPCUR, + &vosDataBuff, reOrderInfo, pTLCb); + } + + if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != vosDataBuff)) + { + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: Chaining was successful sending all pkts to HDD : %x", + vosDataBuff )); + + if ( WLAN_STA_SOFTAP == pClientSTA->wSTADesc.wSTAType ) + { + WLANTL_FwdPktToHDD( pvosGCtx, vosDataBuff, ucSTAId); + } + else + { + wRxMetaInfo.ucUP = ucTid; + pClientSTA->pfnSTARx( pvosGCtx, vosDataBuff, ucSTAId, + &wRxMetaInfo ); + } + } + + /*------------------------------------------------------------------------ + Delete reordering timer + ------------------------------------------------------------------------*/ + if(VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&reOrderInfo->agingTimer)) + { + vosStatus = vos_timer_stop(&reOrderInfo->agingTimer); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer stop fail: %d", vosStatus)); + vos_lock_release(&reOrderInfo->reorderLock); + return vosStatus; + } + } + + if(VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&reOrderInfo->agingTimer)) + { + vosStatus = vos_timer_destroy(&reOrderInfo->agingTimer); + } + else + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer is not stopped state current state is %d", + vos_timer_getCurrentState(&reOrderInfo->agingTimer))); + } + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WLAN TL:Failed to destroy reorder timer on WLANTL_BaSessionAdd"); + } + + /*------------------------------------------------------------------------ + Delete session + ------------------------------------------------------------------------*/ + pClientSTA->atlBAReorderInfo[ucTid].usCount = 0; + pClientSTA->atlBAReorderInfo[ucTid].ucCIndex = 0; + reOrderInfo->winSize = 0; + reOrderInfo->SSN = 0; + reOrderInfo->sessionID = 0; + reOrderInfo->LastSN = 0; + + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_BA_SESSION_DEL, + ucSTAId, ucTid )); + + TLLOG2(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN TL: BA session deleted for STA: %d TID: %d", + ucSTAId, ucTid)); + + memset((v_U8_t *)(&reOrderInfo->reorderBuffer->arrayBuffer[0]), + 0, + WLANTL_MAX_WINSIZE * sizeof(v_PVOID_t)); + reOrderInfo->reorderBuffer->isAvailable = VOS_TRUE; + + vos_lock_release(&reOrderInfo->reorderLock); + return VOS_STATUS_SUCCESS; +}/* WLANTL_BaSessionDel */ + + +/*---------------------------------------------------------------------------- + INTERACTION WITH TL main module + ---------------------------------------------------------------------------*/ + +/*========================================================================== + AMSDU sub-frame processing module + ==========================================================================*/ +/*========================================================================== + FUNCTION WLANTL_AMSDUProcess + + DESCRIPTION + Process A-MSDU sub-frame. Start of chain if marked as first frame. + Linked at the end of the existing AMSDU chain. + + DEPENDENCIES + + PARAMETERS + + IN/OUT: + vosDataBuff: vos packet for the received data + outgoing contains the root of the chain for the rx + aggregated MSDU if the frame is marked as last; otherwise + NULL + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + pvBDHeader: pointer to the BD header + ucSTAId: Station ID + ucMPDUHLen: length of the MPDU header + usMPDULen: length of the MPDU + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_AMSDUProcess +( + v_PVOID_t pvosGCtx, + vos_pkt_t** ppVosDataBuff, + v_PVOID_t pvBDHeader, + v_U8_t ucSTAId, + v_U8_t ucMPDUHLen, + v_U16_t usMPDULen +) +{ + v_U8_t ucFsf; /* First AMSDU sub frame */ + v_U8_t ucAef; /* Error in AMSDU sub frame */ + WLANTL_CbType* pTLCb = NULL; + WLANTL_STAClientType *pClientSTA = NULL; + v_U8_t MPDUHeaderAMSDUHeader[WLANTL_MPDU_HEADER_LEN + TL_AMSDU_SUBFRM_HEADER_LEN]; + v_U16_t subFrameLength; + v_U16_t paddingSize; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + v_U16_t MPDUDataOffset; + v_U16_t packetLength; + static v_U32_t numAMSDUFrames; + vos_pkt_t* vosDataBuff; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == ppVosDataBuff ) || (NULL == *ppVosDataBuff) || ( NULL == pvBDHeader ) || + ( WLANTL_STA_ID_INVALID(ucSTAId)) ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid parameter sent on WLANTL_AMSDUProcess"); + return VOS_STATUS_E_INVAL; + } + + vosDataBuff = *ppVosDataBuff; + /*------------------------------------------------------------------------ + Extract TL control block + ------------------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_AMSDUProcess"); + return VOS_STATUS_E_FAULT; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Check frame + ------------------------------------------------------------------------*/ + ucAef = (v_U8_t)WDA_GET_RX_AEF( pvBDHeader ); + ucFsf = (v_U8_t)WDA_GET_RX_ESF( pvBDHeader ); + /* On Prima, MPDU data offset not includes BD header size */ + MPDUDataOffset = (v_U16_t)WDA_GET_RX_MPDU_DATA_OFFSET(pvBDHeader); + + if ( WLANHAL_RX_BD_AEF_SET == ucAef ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Error in AMSDU - dropping entire chain")); + + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + + if((0 != ucMPDUHLen) && ucFsf) + { + /* + * This is first AMSDU sub frame + * AMSDU Header should be removed + * MPDU header should be stored into context to recover next frames + */ + /* Assumed here Address4 is never part of AMSDU received at TL */ + if (ucMPDUHLen > WLANTL_MPDU_HEADER_LEN) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"MPDU Header length (%d) is greater",ucMPDUHLen)); + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + + vStatus = vos_pkt_pop_head(vosDataBuff, MPDUHeaderAMSDUHeader, ucMPDUHLen + TL_AMSDU_SUBFRM_HEADER_LEN); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Pop MPDU AMSDU Header fail")); + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + pClientSTA->ucMPDUHeaderLen = ucMPDUHLen; + vos_mem_copy(pClientSTA->aucMPDUHeader, MPDUHeaderAMSDUHeader, ucMPDUHLen); + /* AMSDU header stored to handle garbage data within next frame */ + } + else + { + /* Trim garbage, size is frameLoop */ + if(MPDUDataOffset > 0) + { + vStatus = vos_pkt_trim_head(vosDataBuff, MPDUDataOffset); + } + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trim Garbage Data fail")); + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + + /* Remove MPDU header and AMSDU header from the packet */ + vStatus = vos_pkt_pop_head(vosDataBuff, MPDUHeaderAMSDUHeader, ucMPDUHLen + TL_AMSDU_SUBFRM_HEADER_LEN); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"AMSDU Header Pop fail")); + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + } /* End of henalding not first sub frame specific */ + + /* Put in MPDU header into all the frame */ + vStatus = vos_pkt_push_head(vosDataBuff, pClientSTA->aucMPDUHeader, pClientSTA->ucMPDUHeaderLen); + if(!VOS_IS_STATUS_SUCCESS(vStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"MPDU Header Push back fail")); + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + + /* Find Padding and remove */ + vos_mem_copy(&subFrameLength, MPDUHeaderAMSDUHeader + ucMPDUHLen + WLANTL_AMSDU_SUBFRAME_LEN_OFFSET, sizeof(v_U16_t)); + subFrameLength = vos_be16_to_cpu(subFrameLength); + paddingSize = usMPDULen - ucMPDUHLen - subFrameLength - TL_AMSDU_SUBFRM_HEADER_LEN; + + vos_pkt_get_packet_length(vosDataBuff, &packetLength); + if((paddingSize > 0) && (paddingSize < packetLength)) + { + /* There is padding bits, remove it */ + vos_pkt_trim_tail(vosDataBuff, paddingSize); + } + else if(0 == paddingSize) + { + /* No Padding bits */ + /* Do Nothing */ + } + else + { + /* Padding size is larger than Frame size, Actually negative */ + /* Not a valid case, not a valid frame, drop it */ + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Padding Size is negative, no possible %d", paddingSize)); + vos_pkt_return_packet(vosDataBuff); + *ppVosDataBuff = NULL; + return VOS_STATUS_SUCCESS; /*Not a transport error*/ + } + + numAMSDUFrames++; + if(0 == (numAMSDUFrames % 5000)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%u AMSDU frames arrived", numAMSDUFrames)); + } + return VOS_STATUS_SUCCESS; +}/* WLANTL_AMSDUProcess */ + +/*========================================================================== + Re-ordering module + ==========================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_MSDUReorder + + DESCRIPTION + MSDU reordering + + DEPENDENCIES + + PARAMETERS + + IN + + vosDataBuff: vos packet for the received data + pvBDHeader: pointer to the BD header + ucSTAId: Station ID + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANTL_MSDUReorder +( + WLANTL_CbType *pTLCb, + vos_pkt_t **vosDataBuff, + v_PVOID_t pvBDHeader, + v_U8_t ucSTAId, + v_U8_t ucTid +) +{ + WLANTL_BAReorderType *currentReorderInfo; + WLANTL_STAClientType *pClientSTA = NULL; + vos_pkt_t *vosPktIdx; + v_U8_t ucOpCode; + v_U8_t ucSlotIdx; + v_U8_t ucFwdIdx; + v_U16_t CSN; + v_U32_t ucCIndexOrig; + VOS_STATUS status = VOS_STATUS_SUCCESS; + VOS_STATUS lockStatus = VOS_STATUS_SUCCESS; + VOS_STATUS timerStatus = VOS_STATUS_SUCCESS; + VOS_TIMER_STATE timerState; + v_SIZE_t rxFree; + v_U64_t ullreplayCounter = 0; /* 48-bit replay counter */ + v_U8_t ac; + v_U16_t reorderTime; + if((NULL == pTLCb) || (*vosDataBuff == NULL)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid ARG pTLCb 0x%p, vosDataBuff 0x%p", + pTLCb, *vosDataBuff)); + return VOS_STATUS_E_INVAL; + } + + pClientSTA = pTLCb->atlSTAClients[ucSTAId]; + + if ( NULL == pClientSTA ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + currentReorderInfo = &pClientSTA->atlBAReorderInfo[ucTid]; + + lockStatus = vos_lock_acquire(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + + if( pClientSTA->atlBAReorderInfo[ucTid].ucExists == 0 ) + { + vos_lock_release(¤tReorderInfo->reorderLock); + return VOS_STATUS_E_INVAL; + } + ucOpCode = (v_U8_t)WDA_GET_RX_REORDER_OPCODE(pvBDHeader); + ucSlotIdx = (v_U8_t)WDA_GET_RX_REORDER_SLOT_IDX(pvBDHeader); + ucFwdIdx = (v_U8_t)WDA_GET_RX_REORDER_FWD_IDX(pvBDHeader); + CSN = (v_U16_t)WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pvBDHeader); + + + +#ifdef WLANTL_HAL_VOLANS + /* Replay check code : check whether replay check is needed or not */ + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + /* Getting 48-bit replay counter from the RX BD */ + ullreplayCounter = WDA_DS_GetReplayCounter(aucBDHeader); + } +#endif + +#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"opCode %d SI %d, FI %d, CI %d seqNo %d", ucOpCode, ucSlotIdx, ucFwdIdx, currentReorderInfo->ucCIndex, CSN)); +#else + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"opCode %d SI %d, FI %d, CI %d seqNo %d", ucOpCode, ucSlotIdx, ucFwdIdx, currentReorderInfo->ucCIndex, CSN)); +#endif + + // remember our current CI so that later we can tell if it advanced + ucCIndexOrig = currentReorderInfo->ucCIndex; + + switch(ucOpCode) + { + case WLANTL_OPCODE_INVALID: + /* Do nothing just pass through current frame */ + break; + + case WLANTL_OPCODE_QCUR_FWDBUF: + if ((currentReorderInfo->LastSN > CSN) && + !(currentReorderInfo->set_data_filter)) + { + if ((currentReorderInfo->LastSN - CSN) < CSN_WRAP_AROUND_THRESHOLD) + { + //this frame is received after BA timer is expired, discard it + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "(QCUR_FWDBUF) dropping old frame, SN=%d LastSN=%d", + CSN, currentReorderInfo->LastSN)); + if (vos_is_arp_pkt((*vosDataBuff)->pSkb, true)) + vos_update_arp_rx_drop_reorder(); + + status = vos_pkt_return_packet(*vosDataBuff); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "(QCUR_FWDBUF) drop old frame fail %d", status)); + } + *vosDataBuff = NULL; + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if (!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + } + currentReorderInfo->LastSN = CSN; + if(0 == currentReorderInfo->pendingFramesCount) + { + //This frame will be fwd'ed to the OS. The next slot is the one we expect next + currentReorderInfo->ucCIndex = (ucSlotIdx + 1) % currentReorderInfo->winSize; + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + status = WLANTL_QueueCurrent(currentReorderInfo, + vosDataBuff, + ucSlotIdx); + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + WLANTL_FillReplayCounter(currentReorderInfo, + ullreplayCounter, ucSlotIdx); + } + if(VOS_STATUS_E_RESOURCES == status) + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT, + currentReorderInfo->sessionID , ucOpCode )); + + /* This is the case slot index is already cycle one route, route all the frames Qed */ + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDALL_QCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1); + *vosDataBuff = vosPktIdx; + currentReorderInfo->pendingFramesCount = 0; + } + else + { + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_QCUR_FWDBUF, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + currentReorderInfo->ucCIndex = ucFwdIdx; + *vosDataBuff = vosPktIdx; + } + break; + + case WLANTL_OPCODE_FWDBUF_FWDCUR: + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDBUF_FWDCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + + if(NULL == vosPktIdx) + { + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Nothing to chain, just send current frame")); + } + else + { + status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain with CUR frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + *vosDataBuff = vosPktIdx; + } + //ucFwdIdx is the slot this packet supposes to take but there is a hole there + //It looks that the chip will put the next packet into the slot ucFwdIdx. + currentReorderInfo->ucCIndex = ucFwdIdx; + break; + + case WLANTL_OPCODE_QCUR: + if ((currentReorderInfo->LastSN > CSN) && + !(currentReorderInfo->set_data_filter)) + { + if ((currentReorderInfo->LastSN - CSN) < CSN_WRAP_AROUND_THRESHOLD) + { + // this frame is received after BA timer is expired, so disard it + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "(QCUR) dropping old frame, SN=%d LastSN=%d", + CSN, currentReorderInfo->LastSN)); + status = vos_pkt_return_packet(*vosDataBuff); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "*** (QCUR) drop old frame fail %d", status)); + } + *vosDataBuff = NULL; + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if (!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + } + + status = WLANTL_QueueCurrent(currentReorderInfo, + vosDataBuff, + ucSlotIdx); + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + WLANTL_FillReplayCounter(currentReorderInfo, + ullreplayCounter, ucSlotIdx); + } + if(VOS_STATUS_E_RESOURCES == status) + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT, + currentReorderInfo->sessionID , ucOpCode )); + + /* This is the case slot index is already cycle one route, route all the frames Qed */ + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDALL_QCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1); + *vosDataBuff = vosPktIdx; + currentReorderInfo->pendingFramesCount = 0; + } + else + { + /* Since current Frame is Qed, no frame will be routed */ + *vosDataBuff = NULL; + } + break; + + case WLANTL_OPCODE_FWDBUF_QUEUECUR: + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDBUF_QUEUECUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + //This opCode means the window shift. Enforce the current Index + currentReorderInfo->ucCIndex = ucFwdIdx; + + status = WLANTL_QueueCurrent(currentReorderInfo, + vosDataBuff, + ucSlotIdx); + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + WLANTL_FillReplayCounter(currentReorderInfo, + ullreplayCounter, ucSlotIdx); + } + if(VOS_STATUS_E_RESOURCES == status) + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT, + currentReorderInfo->sessionID , ucOpCode )); + + vos_pkt_return_packet(vosPktIdx); + /* This is the case slot index is already cycle one route, route all the frames Qed */ + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDALL_QCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + status = vos_pkt_chain_packet(vosPktIdx, *vosDataBuff, 1); + *vosDataBuff = vosPktIdx; + currentReorderInfo->pendingFramesCount = 0; + } + *vosDataBuff = vosPktIdx; + break; + + case WLANTL_OPCODE_FWDBUF_DROPCUR: + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDBUF_DROPCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + + //Since BAR frame received, set the index to the right location + currentReorderInfo->ucCIndex = ucFwdIdx; + + /* Current frame has to be dropped, BAR frame */ + status = vos_pkt_return_packet(*vosDataBuff); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Drop BAR frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + *vosDataBuff = vosPktIdx; + break; + + case WLANTL_OPCODE_FWDALL_DROPCUR: + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDALL_DROPCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + + //Since BAR frame received and beyond cur window, set the index to the right location + currentReorderInfo->ucCIndex = 0; + + status = vos_pkt_return_packet(*vosDataBuff); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Drop BAR frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + + *vosDataBuff = vosPktIdx; + break; + + case WLANTL_OPCODE_FWDALL_QCUR: + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(currentReorderInfo->winSize, + WLANTL_OPCODE_FWDALL_DROPCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make chain with buffered frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + status = WLANTL_QueueCurrent(currentReorderInfo, + vosDataBuff, + ucSlotIdx); + if(VOS_TRUE == pClientSTA->ucIsReplayCheckValid) + { + WLANTL_FillReplayCounter(currentReorderInfo, + ullreplayCounter, ucSlotIdx); + } + + if(VOS_STATUS_E_RESOURCES == status) + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT, + currentReorderInfo->sessionID , ucOpCode )); + } + + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Q Current frame fail %d", + status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + currentReorderInfo->ucCIndex = ucSlotIdx; + *vosDataBuff = vosPktIdx; + break; + + case WLANTL_OPCODE_TEARDOWN: + // do we have a procedure in place to teardown BA? + + // fall through to drop the current packet + case WLANTL_OPCODE_DROPCUR: + vos_pkt_return_packet(*vosDataBuff); + *vosDataBuff = NULL; + break; + + default: + break; + } + + /* Check the available VOS RX buffer size + * If remaining VOS RX buffer is too few, have to make space + * Route all the Qed frames upper layer + * Otherwise, RX thread could be stall */ + vos_pkt_get_available_buffer_pool(VOS_PKT_TYPE_RX_RAW, &rxFree); + if(WLANTL_BA_MIN_FREE_RX_VOS_BUFFER >= rxFree) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "RX Free: %d", rxFree)); + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "RX free buffer count is too low, Pending frame count is %d", + currentReorderInfo->pendingFramesCount)); + vosPktIdx = NULL; + status = WLANTL_ChainFrontPkts(ucFwdIdx, + WLANTL_OPCODE_FWDALL_DROPCUR, + &vosPktIdx, + currentReorderInfo, + pTLCb); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Make frame chain fail %d", status)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return status; + } + if(NULL != *vosDataBuff) + { + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Already something, Chain it")); + vos_pkt_chain_packet(*vosDataBuff, vosPktIdx, 1); + } + else + { + *vosDataBuff = vosPktIdx; + } + currentReorderInfo->pendingFramesCount = 0; + } + + /* + * Current aging timer logic: + * 1) if we forwarded any packets and the timer is running: + * stop the timer + * 2) if there are packets queued and the timer is not running: + * start the timer + * 3) if timer is running and no pending frame: + * stop the timer + */ + timerState = vos_timer_getCurrentState(¤tReorderInfo->agingTimer); + if ((VOS_TIMER_STATE_RUNNING == timerState) && + ((ucCIndexOrig != currentReorderInfo->ucCIndex) || + (0 == currentReorderInfo->pendingFramesCount))) + { + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"HOLE filled, Pending Frames Count %d", + currentReorderInfo->pendingFramesCount)); + + // we forwarded some packets so stop aging the current hole + timerStatus = vos_timer_stop(¤tReorderInfo->agingTimer); + timerState = VOS_TIMER_STATE_STOPPED; + + // ignore the returned status since there is a race condition + // whereby between the time we called getCurrentState() and the + // time we call stop() the timer could have fired. In that case + // stop() will return an error, but we don't care since the + // timer has stopped + } + + if (currentReorderInfo->pendingFramesCount > 0) + { + if (VOS_TIMER_STATE_STOPPED == timerState) + { + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is a new HOLE, Pending Frames Count %d", + currentReorderInfo->pendingFramesCount)); + ac = WLANTL_TID_2_AC[ucTid]; + if (WLANTL_AC_INVALID(ac)) + { + reorderTime = WLANTL_BA_REORDERING_AGING_TIMER; + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid AC %d using default reorder time %d", + ac, reorderTime)); + } + else + { + reorderTime = pTLCb->tlConfigInfo.ucReorderAgingTime[ac]; + } + timerStatus = vos_timer_start(¤tReorderInfo->agingTimer, + reorderTime); + if(!VOS_IS_STATUS_SUCCESS(timerStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer start fail: %d", timerStatus)); + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return timerStatus; + } + } + else + { + // we didn't forward any packets and the timer was already + // running so we're still aging the same hole + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Still HOLE, Pending Frames Count %d", + currentReorderInfo->pendingFramesCount)); + } + } + + lockStatus = vos_lock_release(¤tReorderInfo->reorderLock); + if(!VOS_IS_STATUS_SUCCESS(lockStatus)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_MSDUReorder, Release LOCK Fail")); + return lockStatus; + } + return VOS_STATUS_SUCCESS; +}/* WLANTL_MSDUReorder */ + + +/*========================================================================== + Utility functions + ==========================================================================*/ + +/*========================================================================== + + FUNCTION WLANTL_QueueCurrent + + DESCRIPTION + It will queue a packet at a given slot index in the MSDU reordering list. + + DEPENDENCIES + + PARAMETERS + + IN + pwBaReorder: pointer to the BA reordering session info + vosDataBuff: data buffer to be queued + ucSlotIndex: slot index + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is OK + + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANTL_QueueCurrent +( + WLANTL_BAReorderType* pwBaReorder, + vos_pkt_t** vosDataBuff, + v_U8_t ucSlotIndex +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"vos Packet has to be Qed 0x%p", + *vosDataBuff)); + if(NULL != pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex]) + { + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT, + pwBaReorder->sessionID , pwBaReorder->pendingFramesCount )); + + MTRACE(vos_trace(VOS_MODULE_ID_TL, TRACE_CODE_TL_QUEUE_CURRENT, + pwBaReorder->sessionID , ucSlotIndex )); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"One Cycle rounded, lost many frames already, not in Q %d", + pwBaReorder->pendingFramesCount)); + return VOS_STATUS_E_RESOURCES; + } + + pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex] = + (v_PVOID_t)(*vosDataBuff); + pwBaReorder->pendingFramesCount++; + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Assigned, Pending Frames %d at slot %d, dataPtr 0x%x", + pwBaReorder->pendingFramesCount, + ucSlotIndex, + pwBaReorder->reorderBuffer->arrayBuffer[ucSlotIndex])); + + return status; +}/*WLANTL_QueueCurrent*/ + +/*========================================================================== + + FUNCTION WLANTL_ChainFrontPkts + + DESCRIPTION + It will remove all the packets from the front of a vos list and chain + them to a vos pkt . + + DEPENDENCIES + + PARAMETERS + + IN + ucCount: number of packets to extract + pwBaReorder: pointer to the BA reordering session info + + OUT + vosDataBuff: data buffer containing the extracted chain of packets + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_SUCCESS: Everything is OK + + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANTL_ChainFrontPkts +( + v_U32_t fwdIndex, + v_U8_t opCode, + vos_pkt_t **vosDataBuff, + WLANTL_BAReorderType *pwBaReorder, + WLANTL_CbType *pTLCb +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U32_t idx; + v_PVOID_t currentDataPtr = NULL; + int negDetect; +#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE +#define WLANTL_OUT_OF_WINDOW_IDX 65 + v_U32_t frameIdx[2] = {0, 0}, ffidx = fwdIndex, idx2 = WLANTL_OUT_OF_WINDOW_IDX; + int pending = pwBaReorder->pendingFramesCount, start = WLANTL_OUT_OF_WINDOW_IDX, end; +#endif + + if(pwBaReorder->ucCIndex >= fwdIndex) + { + fwdIndex += pwBaReorder->winSize; + } + + if((WLANTL_OPCODE_FWDALL_DROPCUR == opCode) || + (WLANTL_OPCODE_FWDALL_QCUR == opCode)) + { + fwdIndex = pwBaReorder->ucCIndex + pwBaReorder->winSize; + } + + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Current Index %d, FWD Index %d, reorderBuffer 0x%p", + pwBaReorder->ucCIndex % pwBaReorder->winSize, + fwdIndex % pwBaReorder->winSize, + pwBaReorder->reorderBuffer)); + + negDetect = pwBaReorder->pendingFramesCount; + for(idx = pwBaReorder->ucCIndex; idx <= fwdIndex; idx++) + { + currentDataPtr = + pwBaReorder->reorderBuffer->arrayBuffer[idx % pwBaReorder->winSize]; + if(NULL != currentDataPtr) + { +#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE + idx2 = (idx >= pwBaReorder->winSize) ? (idx - pwBaReorder->winSize) : idx; + frameIdx[idx2 / 32] |= 1 << (idx2 % 32); + if(start == WLANTL_OUT_OF_WINDOW_IDX) start = idx2; +#endif + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is buffered frame %d", + idx % pwBaReorder->winSize)); + if(NULL == *vosDataBuff) + { + *vosDataBuff = (vos_pkt_t *)currentDataPtr; + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"This is new head %d", + idx % pwBaReorder->winSize)); + } + else + { + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"There is bufered Just add %d", + idx % pwBaReorder->winSize)); + vos_pkt_chain_packet(*vosDataBuff, + (vos_pkt_t *)currentDataPtr, + VOS_TRUE); + } + pwBaReorder->reorderBuffer->arrayBuffer[idx % pwBaReorder->winSize] + = NULL; + pwBaReorder->pendingFramesCount--; + negDetect--; + if(negDetect < 0) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"This is not possible, some balance has problem")); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Slot Index %d, set as NULL, Pending Frames %d", + idx % pwBaReorder->winSize, + pwBaReorder->pendingFramesCount + )); + pwBaReorder->ucCIndex = (idx + 1) % pwBaReorder->winSize; + } + else + { + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Empty Array %d", + idx % pwBaReorder->winSize)); + } + TLLOG4(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW,"Current Index %d, winSize %d", + pwBaReorder->ucCIndex, + pwBaReorder->winSize + )); + } + +#ifdef WLANTL_REORDER_DEBUG_MSG_ENABLE + end = idx2; + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Fwd 0x%08X-%08X opCode %d fwdIdx %d windowSize %d pending frame %d fw no. %d from idx %d to %d", + frameIdx[1], frameIdx[0], opCode, ffidx, pwBaReorder->winSize, pending, pending - negDetect, start, end)); +#endif + + return status; +}/*WLANTL_ChainFrontPkts*/ +/*========================================================================== + + FUNCTION WLANTL_FillReplayCounter + + DESCRIPTION + It will fill repaly counter at a given slot index in the MSDU reordering list. + + DEPENDENCIES + + PARAMETERS + + IN + pwBaReorder : pointer to the BA reordering session info + replayCounter: replay counter to be filled + ucSlotIndex : slot index + + RETURN VALUE + NONE + + + SIDE EFFECTS + NONE + + ============================================================================*/ +void WLANTL_FillReplayCounter +( + WLANTL_BAReorderType* pwBaReorder, + v_U64_t ullreplayCounter, + v_U8_t ucSlotIndex +) +{ + + //BAMSGDEBUG("replay counter to be filled in Qed frames %llu", + //replayCounter, 0, 0); + + pwBaReorder->reorderBuffer->ullReplayCounter[ucSlotIndex] = ullreplayCounter; + //BAMSGDEBUG("Assigned, replay counter Pending Frames %d at slot %d, replay counter[0x%llX]\n", + //pwBaReorder->pendingFramesCount, + //ucSlotIndex, + //pwBaReorder->reorderBuffer->ullReplayCounter); + return; +}/*WLANTL_FillReplayCounter*/ + diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.c new file mode 100644 index 000000000000..950f3f0f32c6 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.c @@ -0,0 +1,2131 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + W L A N _ Q C T _ T L _ HOSUPPORT. C + + OVERVIEW: + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +02/19/09 lti Vos trace fix +02/06/09 sch Dereg Bug fix +12/11/08 sch Initial creation + +===========================================================================*/ +#include "wlan_qct_tl.h" +#include "wlan_qct_wda.h" +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_tl_hosupport.h" +#include "wlan_qct_tli.h" +#include "tlDebug.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +//#define WLANTL_HO_DEBUG_MSG +//#define WLANTL_HO_UTEST + +#define WLANTL_HO_DEFAULT_RSSI 0xFF +#define WLANTL_HO_INVALID_RSSI -100 +/* RSSI sampling period, usec based + * To reduce performance overhead + * Current default 500msec */ +#define WLANTL_HO_SAMPLING_PERIOD 500000 + + + +/* Get and release lock */ +#define THSGETLOCK(a, b) \ + do \ + { \ + if(!VOS_IS_STATUS_SUCCESS(vos_lock_acquire(b))) \ + { \ + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%s Get Lock Fail", a)); \ + return VOS_STATUS_E_FAILURE; \ + } \ + }while(0) + +#define THSRELEASELOCK(a, b) \ + do \ + { \ + if(!VOS_IS_STATUS_SUCCESS(vos_lock_release(b))) \ + { \ + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"%s Release Lock Fail", a)); \ + return VOS_STATUS_E_FAILURE; \ + } \ + }while(0) + +const v_U8_t WLANTL_HO_TID_2_AC[WLAN_MAX_TID] = {WLANTL_AC_BE, + WLANTL_AC_BK, + WLANTL_AC_BK, + WLANTL_AC_BE, + WLANTL_AC_VI, + WLANTL_AC_VI, + WLANTL_AC_VO, + WLANTL_AC_VO}; +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/* Temporary threshold store place for BMPS */ +typedef struct +{ + v_S7_t rssi; + v_U8_t event; +} WLANTL_HSTempPSIndType; + +#ifdef RSSI_HACK +/* This is a dummy averaged RSSI value that can be controlled using dump commands + * to trigger TL to issue handoff related events. We will be using dump 362 + * value to change its value */ +int dumpCmdRSSI = -48; +#endif + +#ifdef WLANTL_HO_UTEST +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +static v_S7_t rssi; +static v_S7_t direction; +void TLHS_UtestHandleNewRSSI(v_S7_t *newRSSI, v_PVOID_t pAdapter) +{ + if(0 == rssi) + { + direction = -1; + } + else if(-90 == rssi) + { + direction = 1; + } + + *newRSSI = rssi; + rssi += direction; + + return; +} +#endif /* WLANTL_HO_UTEST */ + +#ifdef WLANTL_HO_DEBUG_MSG +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +void WLANTL_StatDebugDisplay +( + v_U8_t STAid, + WLANTL_TRANSFER_STA_TYPE *statistics +) +{ + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"=================================================")); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Statistics for STA %d", STAid)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX UC Fcnt %5d, MC Fcnt %5d, BC Fcnt %5d", + statistics->rxUCFcnt, statistics->rxMCFcnt, statistics->rxBCFcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX UC Bcnt %5d, MC Bcnt %5d, BC Bcnt %5d", + statistics->rxUCBcnt, statistics->rxMCBcnt, statistics->rxBCBcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX UC Fcnt %5d, MC Fcnt %5d, BC Fcnt %5d", + statistics->txUCFcnt, statistics->txMCFcnt, statistics->txBCFcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX UC Bcnt %5d, MC Bcnt %5d, BC Bcnt %5d", + statistics->txUCBcnt, statistics->txMCBcnt, statistics->txBCBcnt)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TRX Bcnt %5d, CRCOK Bcnt %5d, RXRate %5d", + statistics->rxBcnt, statistics->rxBcntCRCok, statistics->rxRate)); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"=================================================")); + return; +} +#endif /* WLANTL_HO_DEBUG_MSG */ + +#ifdef WLANTL_DEBUG +void WLANTLPrintPktsRcvdPerRateIdx(v_PVOID_t pAdapter, v_U8_t staId, v_BOOL_t flush) +{ + v_U16_t ii; + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return; + } + + if(NULL == tlCtxt->atlSTAClients[staId]) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return; + } + + if(0 == tlCtxt->atlSTAClients[staId]->ucExists ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID does not exist", staId)); + return; + } + + if(flush) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "flushed rateIdx counters")); + + for(ii = 0; ii < MAX_RATE_INDEX; ii++) + tlCtxt->atlSTAClients[staId]->trafficStatistics.pktCounterRateIdx[ii] = 0; + + return; + } + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "pkts per rate Index")); + + for(ii = 0; ii < MAX_RATE_INDEX; ii++) + { + /* printing int the below format + * " rateIndex = pktCount "*/ + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%d = %d", ii+1, + tlCtxt->atlSTAClients[staId]->trafficStatistics.pktCounterRateIdx[ii])); + } + + return; +} + +void WLANTLPrintPktsRcvdPerRssi(v_PVOID_t pAdapter, v_U8_t staId, v_BOOL_t flush) +{ + v_U16_t ii,jj; + v_U32_t count = 0; + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return; + } + + if(NULL == tlCtxt->atlSTAClients[staId]) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return; + } + + if(0 == tlCtxt->atlSTAClients[staId]->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID does not exist", staId)); + return; + } + + if(flush) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "flushed rssi counters")); + + for(ii = 0; ii < MAX_NUM_RSSI; ii++) + tlCtxt->atlSTAClients[staId]->trafficStatistics.pktCounterRssi[ii] = 0; + + return; + } + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "pkts per RSSI")); + + for(ii = 0; ii < MAX_NUM_RSSI; ii += MAX_RSSI_INTERVAL) + { + count = 0; + + for(jj = ii; jj < (ii + MAX_RSSI_INTERVAL); jj++) + count += tlCtxt->atlSTAClients[staId]->trafficStatistics.pktCounterRssi[jj]; + + /* prints are in the below format + * " fromRSSI - toRSSI = pktCount " */ + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + " %d - %d = %d", + ii, ii+(MAX_RSSI_INTERVAL - 1), count)); + } + return; +} +#endif + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +void WLANTL_HSDebugDisplay +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + v_U8_t idx, sIdx; + v_BOOL_t regionFound = VOS_FALSE; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO; + WLANTL_HO_SUPPORT_TYPE *hoSupport; + + if (NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid TL Context", + __func__)); + return; + } + + currentHO = &(tlCtxt->hoSupport.currentHOState); + hoSupport = &(tlCtxt->hoSupport); + + + for(idx = 0; idx < currentHO->numThreshold; idx++) + { + if(idx == currentHO->regionNumber) + { + regionFound = VOS_TRUE; + if(VOS_TRUE == tlCtxt->isBMPS) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO," ----> CRegion %d, hRSSI:NA, BMPS, Alpha %d", + currentHO->regionNumber, currentHO->alpha)); + } + else + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO," ----> CRegion %d, hRSSI %d, Alpha %d", + currentHO->regionNumber, + currentHO->historyRSSI, + currentHO->alpha)); + } + } + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx]) + { + if(VOS_MODULE_ID_HDD == hoSupport->registeredInd[idx].whoIsClient[sIdx]) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Client HDD pCB %p, triggerEvt %d, RSSI %d", + hoSupport->registeredInd[idx].crossCBFunction[sIdx], + hoSupport->registeredInd[idx].triggerEvent[sIdx], + hoSupport->registeredInd[idx].rssiValue)); + } + else + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Client SME pCB %p, triggerEvt %d, RSSI %d", + hoSupport->registeredInd[idx].crossCBFunction[sIdx], + hoSupport->registeredInd[idx].triggerEvent[sIdx], + hoSupport->registeredInd[idx].rssiValue)); + } + } + } + } + + if(VOS_FALSE == regionFound) + { + if(VOS_TRUE == tlCtxt->isBMPS) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO," ----> CRegion %d, hRSSI:NA, BMPS, Alpha %d", + currentHO->regionNumber, currentHO->alpha)); + } + else + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO," ----> CRegion %d, hRSSI %d, Alpha %d", + currentHO->regionNumber, + currentHO->historyRSSI, + currentHO->alpha)); + } + } + + return; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_SetFWRSSIThresholds +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_HO_SUPPORT_TYPE *hoSupport; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO; + tSirRSSIThresholds bmpsThresholds; + WLANTL_HSTempPSIndType tempIndSet[WLANTL_SINGLE_CLNT_THRESHOLD]; + v_U8_t bmpsLoop; + v_U8_t bmpsInd; + v_U8_t clientLoop; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + WLANTL_HSDebugDisplay(pAdapter); + currentHO = &(tlCtxt->hoSupport.currentHOState); + hoSupport = &(tlCtxt->hoSupport); + + memset((v_U8_t *)&tempIndSet[0], 0, WLANTL_SINGLE_CLNT_THRESHOLD * sizeof(WLANTL_HSTempPSIndType)); + memset(&bmpsThresholds, 0, sizeof(tSirRSSIThresholds)); + + bmpsInd = 0; + for(bmpsLoop = 0; bmpsLoop < WLANTL_MAX_AVAIL_THRESHOLD; bmpsLoop++) + { + for(clientLoop = 0; clientLoop < WLANTL_HS_NUM_CLIENT; clientLoop++) + { + if(0 != hoSupport->registeredInd[bmpsLoop].triggerEvent[clientLoop]) + { + if(bmpsInd == WLANTL_SINGLE_CLNT_THRESHOLD) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Single Client Threshold should be less than %d", WLANTL_SINGLE_CLNT_THRESHOLD)); + break; + } + tempIndSet[bmpsInd].rssi = hoSupport->registeredInd[bmpsLoop].rssiValue; + tempIndSet[bmpsInd].event = hoSupport->registeredInd[bmpsLoop].triggerEvent[clientLoop]; + bmpsInd++; + break; + } + } + } + + bmpsThresholds.ucRssiThreshold1 = tempIndSet[0].rssi; + if((WLANTL_HO_THRESHOLD_DOWN == tempIndSet[0].event) || + (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[0].event)) + { + bmpsThresholds.bRssiThres1NegNotify = 1; + } + if((WLANTL_HO_THRESHOLD_UP == tempIndSet[0].event) || + (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[0].event)) + { + bmpsThresholds.bRssiThres1PosNotify = 1; + } + + bmpsThresholds.ucRssiThreshold2 = tempIndSet[1].rssi; + if((WLANTL_HO_THRESHOLD_DOWN == tempIndSet[1].event) || + (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[1].event)) + { + bmpsThresholds.bRssiThres2NegNotify = 1; + } + if((WLANTL_HO_THRESHOLD_UP == tempIndSet[1].event) || + (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[1].event)) + { + bmpsThresholds.bRssiThres2PosNotify = 1; + } + + bmpsThresholds.ucRssiThreshold3 = tempIndSet[2].rssi; + if((WLANTL_HO_THRESHOLD_DOWN == tempIndSet[2].event) || + (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[2].event)) + { + bmpsThresholds.bRssiThres3NegNotify = 1; + } + if((WLANTL_HO_THRESHOLD_UP == tempIndSet[2].event) || + (WLANTL_HO_THRESHOLD_CROSS == tempIndSet[2].event)) + { + bmpsThresholds.bRssiThres3PosNotify = 1; + } + + WDA_SetRSSIThresholds(hoSupport->macCtxt, &bmpsThresholds); + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_StatHandleRXFrame +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid, + v_BOOL_t isBroadcast, + vos_pkt_t *dataBuffer +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_TRANSFER_STA_TYPE *statistics; + v_U16_t packetSize; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == tlCtxt->atlSTAClients[STAid] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + + if(NULL == dataBuffer) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Management Frame, not need to handle with Stat")); + return status; + } + + if(0 == tlCtxt->atlSTAClients[STAid]->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID is not exist", STAid)); + return VOS_STATUS_E_INVAL; + } + + statistics = &tlCtxt->atlSTAClients[STAid]->trafficStatistics; + vos_pkt_get_packet_length(dataBuffer, &packetSize); + + if(isBroadcast) + { + /* Above flag is set for both broadcast and multicast frame. So + find frame type to distinguish between multicast and broadcast. + Ideally, it would be better if BD header has a field to indicate + multicast frame and then we would not need to call below function */ + + v_U8_t ucFrameCastType; + + status = WLANTL_FindFrameTypeBcMcUc(tlCtxt, STAid, dataBuffer, + &ucFrameCastType); + + if (VOS_STATUS_SUCCESS != status) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: failed to distinguish if Rx frame is broadcast or multicast")); + return status; + } + + switch (ucFrameCastType) + { + case WLANTL_FRAME_TYPE_BCAST: + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX BC frame")); + statistics->rxBCFcnt++; + statistics->rxBCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE); + break; + + case WLANTL_FRAME_TYPE_MCAST: + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX MC frame")); + statistics->rxMCFcnt++; + statistics->rxMCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE); + break; + + case WLANTL_FRAME_TYPE_UCAST: + /* error - for unicast frame we should not reach here */ + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: BD header indicates broadcast but MAC address indicates unicast")); + return VOS_STATUS_E_INVAL; + break; + + default: + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: error in finding bc/mc/uc type of the received frame")); + return VOS_STATUS_E_INVAL; + break; + } + } + else + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is RX UC frame")); + statistics->rxUCFcnt++; + statistics->rxUCBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE); + } + + /* TODO caculation is needed, dimension of 500kbps */ + statistics->rxRate = WDA_GET_RX_MAC_RATE_IDX(pBDHeader); + +#ifdef WLANTL_DEBUG + if( (statistics->rxRate - 1) < MAX_RATE_INDEX) + tlCtxt->atlSTAClients[STAid]->trafficStatistics.pktCounterRateIdx[statistics->rxRate - 1]++; + + /* Check if the +ve value of RSSI is within the valid range. + * And increment pkt counter based on RSSI */ + if( (v_U16_t)((WDA_GET_RX_RSSI_DB(pBDHeader)) * (-1)) < MAX_NUM_RSSI) + tlCtxt->atlSTAClients[STAid]->trafficStatistics.pktCounterRssi[(v_U16_t)((WDA_GET_RX_RSSI_DB(pBDHeader)) * (-1))]++; +#endif + TLLOG1(VOS_TRACE (VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_MED, + "****Received rate Index = %d type=%d subtype=%d****", + statistics->rxRate,WDA_GET_RX_TYPE(pBDHeader),WDA_GET_RX_SUBTYPE(pBDHeader))); + + statistics->rxBcnt += (packetSize - WLANHAL_RX_BD_HEADER_SIZE); + +#ifdef WLANTL_HO_DEBUG_MSG + WLANTL_StatDebugDisplay(STAid, statistics); +#endif /* WLANTL_HO_DEBUG_MSG */ + + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_StatHandleTXFrame +( + v_PVOID_t pAdapter, + v_U8_t STAid, + vos_pkt_t *dataBuffer, + v_PVOID_t pBDHeader, + WLANTL_MetaInfoType *txMetaInfo +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_TRANSFER_STA_TYPE *statistics; + v_U16_t packetSize; + + if((NULL == tlCtxt) || (NULL == dataBuffer)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == tlCtxt->atlSTAClients[STAid] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + if(0 == tlCtxt->atlSTAClients[STAid]->ucExists) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLAN TL: %d STA ID is not exist", STAid)); + return VOS_STATUS_E_INVAL; + } + + /* TODO : BC/MC/UC have to be determined by MAC address */ + statistics = &tlCtxt->atlSTAClients[STAid]->trafficStatistics; + vos_pkt_get_packet_length(dataBuffer, &packetSize); + if(txMetaInfo->ucBcast) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is BC frame")); + statistics->txBCFcnt++; + statistics->txBCBcnt += packetSize; + } + else if(txMetaInfo->ucMcast) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This TX is MC frame")); + statistics->txMCFcnt++; + statistics->txMCBcnt += packetSize; + } + else + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is TX UC frame")); + statistics->txUCFcnt++; + statistics->txUCBcnt += packetSize; + } + +#ifdef WLANTL_HO_DEBUG_MSG + WLANTL_StatDebugDisplay(STAid, statistics); +#endif /* WLANTL_HO_DEBUG_MSG */ + + return status; +} + +/*========================================================================== + + FUNCTION WLANTL_HSTrafficStatusTimerExpired + + DESCRIPTION If traffic status monitoring timer is expiered, + Count how may frames have sent and received during + measure period and if traffic status is changed + send notification to Client(SME) + + PARAMETERS pAdapter + Global handle + + RETURN VALUE + +============================================================================*/ +v_VOID_t WLANTL_HSTrafficStatusTimerExpired +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + WLANTL_HO_TRAFFIC_STATUS_HANDLE_TYPE *trafficHandle = NULL; + WLANTL_HO_TRAFFIC_STATUS_TYPE newTraffic; + v_U32_t rtFrameCount; + v_U32_t nrtFrameCount; + v_BOOL_t trafficStatusChanged = VOS_FALSE; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return; + } + + /* Get rt and nrt frame count sum */ + trafficHandle = &tlCtxt->hoSupport.currentTraffic; + rtFrameCount = trafficHandle->rtRXFrameCount + trafficHandle->rtTXFrameCount; + nrtFrameCount = trafficHandle->nrtRXFrameCount + trafficHandle->nrtTXFrameCount; + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Traffic status timer expired RT FC %d, NRT FC %d", rtFrameCount, nrtFrameCount)); + + /* Get current traffic status */ + if(rtFrameCount > trafficHandle->idleThreshold) + { + newTraffic.rtTrafficStatus = WLANTL_HO_RT_TRAFFIC_STATUS_ON; + } + else + { + newTraffic.rtTrafficStatus = WLANTL_HO_RT_TRAFFIC_STATUS_OFF; + } + + if(nrtFrameCount > trafficHandle->idleThreshold) + { + newTraffic.nrtTrafficStatus = WLANTL_HO_NRT_TRAFFIC_STATUS_ON; + } + else + { + newTraffic.nrtTrafficStatus = WLANTL_HO_NRT_TRAFFIC_STATUS_OFF; + } + + /* Differentiate with old traffic status */ + if(trafficHandle->trafficStatus.rtTrafficStatus != newTraffic.rtTrafficStatus) + { + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"RT Traffic status changed from %d to %d", + trafficHandle->trafficStatus.rtTrafficStatus, + newTraffic.rtTrafficStatus)); + trafficStatusChanged = VOS_TRUE; + } + if(trafficHandle->trafficStatus.nrtTrafficStatus != newTraffic.nrtTrafficStatus) + { + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"NRT Traffic status changed from %d to %d", + trafficHandle->trafficStatus.nrtTrafficStatus, + newTraffic.nrtTrafficStatus)); + trafficStatusChanged = VOS_TRUE; + } + + /* If traffic status is changed send notification to client */ + if((VOS_TRUE == trafficStatusChanged) && (NULL != trafficHandle->trafficCB)) + { + trafficHandle->trafficCB(pAdapter, newTraffic, trafficHandle->usrCtxt); + trafficHandle->trafficStatus.rtTrafficStatus = newTraffic.rtTrafficStatus; + trafficHandle->trafficStatus.nrtTrafficStatus = newTraffic.nrtTrafficStatus; + } + else if((VOS_TRUE == trafficStatusChanged) && (NULL == trafficHandle->trafficCB)) + { + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"Traffic status is changed but not need to report")); + } + + /* Reset frame counters */ + trafficHandle->rtRXFrameCount = 0; + trafficHandle->rtTXFrameCount = 0; + trafficHandle->nrtRXFrameCount = 0; + trafficHandle->nrtTXFrameCount = 0; + + if(NULL != trafficHandle->trafficCB) + { + /* restart timer only when the callback is not NULL */ + vos_timer_start(&trafficHandle->trafficTimer, trafficHandle->measurePeriod); + } + + return; +} + + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSGetRSSI +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid, + v_S7_t *currentAvgRSSI +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_S7_t currentRSSI, currentRSSI0, currentRSSI1; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL; + + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == tlCtxt->atlSTAClients[STAid] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /* + Compute RSSI only for the last MPDU of an AMPDU. + Only last MPDU carries the Phy Stats Values + */ + if (WDA_IS_RX_AN_AMPDU (pBDHeader)) { + if (!WDA_IS_RX_LAST_MPDU(pBDHeader)) { + return VOS_STATUS_E_FAILURE; + } + } + + currentHO = &tlCtxt->hoSupport.currentHOState; + + currentRSSI0 = WLANTL_GETRSSI0(pBDHeader); + currentRSSI1 = WLANTL_GETRSSI1(pBDHeader); + currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1; + + if (0 == currentRSSI) + return VOS_STATUS_E_INVAL; + +#ifdef WLANTL_HO_UTEST + TLHS_UtestHandleNewRSSI(¤tRSSI, pAdapter); +#endif /* WLANTL_HO_UTEST */ + + if(0 == tlCtxt->atlSTAClients[STAid]->rssiAvg) + { + *currentAvgRSSI = currentRSSI; + } + else + { + *currentAvgRSSI = ((tlCtxt->atlSTAClients[STAid]->rssiAvg * + tlCtxt->atlSTAClients[STAid]->rssiAlpha) + + (currentRSSI * (10 - tlCtxt->atlSTAClients[STAid]->rssiAlpha))) / 10; + } + +#ifdef RSSI_HACK + *currentAvgRSSI = (v_S7_t)dumpCmdRSSI; +#endif + + tlCtxt->atlSTAClients[STAid]->rssiAvg = *currentAvgRSSI; + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current new RSSI is %d, averaged RSSI is %d", currentRSSI, *currentAvgRSSI)); + return status; +} + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/*========================================================================== + + FUNCTION WLANTL_HSGetDataRSSI + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSGetDataRSSI +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid, + v_S7_t *currentAvgRSSI +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_S7_t currentRSSI, currentRSSI0, currentRSSI1; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL; + + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if ( NULL == tlCtxt->atlSTAClients[STAid] ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Client Memory was not allocated on %s", __func__)); + return VOS_STATUS_E_FAILURE; + } + + /* + * Compute RSSI only for the last MPDU of an AMPDU. + * Only last MPDU carries the Phy Stats Values + */ + if (WDA_IS_RX_AN_AMPDU (pBDHeader)) { + if (!WDA_IS_RX_LAST_MPDU(pBDHeader)) { + return VOS_STATUS_E_FAILURE; + } + } + + currentHO = &tlCtxt->hoSupport.currentHOState; + + currentRSSI0 = WLANTL_GETRSSI0(pBDHeader); + currentRSSI1 = WLANTL_GETRSSI0(pBDHeader); + currentRSSI = (currentRSSI0 > currentRSSI1) ? currentRSSI0 : currentRSSI1; + + if (0 == currentRSSI) + return VOS_STATUS_E_INVAL; + +#ifdef WLANTL_HO_UTEST + TLHS_UtestHandleNewRSSI(¤tRSSI, pAdapter); +#endif /* WLANTL_HO_UTEST */ + + if(0 == tlCtxt->atlSTAClients[STAid]->rssiDataAvg) + { + *currentAvgRSSI = currentRSSI; + } + else + { + *currentAvgRSSI = ((tlCtxt->atlSTAClients[STAid]->rssiDataAvg * + tlCtxt->atlSTAClients[STAid]->rssiDataAlpha) + + (currentRSSI * + (10 - tlCtxt->atlSTAClients[STAid]->rssiDataAlpha))) / 10; + } + + + tlCtxt->atlSTAClients[STAid]->rssiDataAvg = *currentAvgRSSI; + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "Current new Data RSSI is %d, averaged Data RSSI is %d", + currentRSSI, *currentAvgRSSI)); + return status; +} +#endif + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSBMPSRSSIRegionChangedNotification +( + v_PVOID_t pAdapter, + tpSirRSSINotification pRSSINotification +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO; + WLANTL_HO_SUPPORT_TYPE *hoSupport; + WLANTL_RSSICrossThresholdCBType cbFunction = NULL; + v_PVOID_t usrCtxt = NULL; + v_U8_t evtType = WLANTL_HO_THRESHOLD_NA; + v_U32_t preFWNotification = 0; + v_U32_t curFWNotification = 0; + v_U8_t newRegionNumber = 0; + v_U8_t pRegionNumber = 0, nRegionNumber = 0; + v_U32_t isSet; + v_U8_t idx, sIdx; + + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if(NULL == pRSSINotification) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid FW RSSI Notification")); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + THSGETLOCK("WLANTL_HSBMPSRSSIRegionChangedNotification", + &tlCtxt->hoSupport.hosLock); + currentHO = &(tlCtxt->hoSupport.currentHOState); + hoSupport = &(tlCtxt->hoSupport); + preFWNotification = currentHO->fwNotification; + + isSet = pRSSINotification->bRssiThres1PosCross; + curFWNotification |= isSet << 5; + isSet = pRSSINotification->bRssiThres2PosCross; + curFWNotification |= isSet << 4; + isSet = pRSSINotification->bRssiThres3PosCross; + curFWNotification |= isSet << 3; + isSet = pRSSINotification->bRssiThres1NegCross; + curFWNotification |= isSet << 2; + isSet = pRSSINotification->bRssiThres2NegCross; + curFWNotification |= isSet << 1; + isSet = pRSSINotification->bRssiThres3NegCross; + curFWNotification |= isSet; + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current FW Notification is 0x%x", (v_U32_t)curFWNotification )); + + currentHO->fwNotification = curFWNotification; + + if(0 == preFWNotification) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"This is the first time notification from FW Value is 0x%x", curFWNotification)); + preFWNotification = curFWNotification; + } + else if(preFWNotification == curFWNotification) + { + THSRELEASELOCK("WLANTL_HSBMPSRSSIRegionChangedNotification", + &tlCtxt->hoSupport.hosLock); + return status; + } + + if(1 == pRSSINotification->bRssiThres1PosCross) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 0")); + pRegionNumber = 0; + } + else if(1 == pRSSINotification->bRssiThres2PosCross) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 1")); + pRegionNumber = 1; + } + else if(1 == pRSSINotification->bRssiThres3PosCross) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"POS Cross to Region 2")); + pRegionNumber = 2; + } + + if(1 == pRSSINotification->bRssiThres3NegCross) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 3")); + nRegionNumber = 3; + } + else if(1 == pRSSINotification->bRssiThres2NegCross) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 2")); + nRegionNumber = 2; + } + else if(1 == pRSSINotification->bRssiThres1NegCross) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"NEG Cross to Region 1")); + nRegionNumber = 1; + } + + newRegionNumber = (nRegionNumber > pRegionNumber) ? nRegionNumber : pRegionNumber; + if((currentHO->regionNumber) && (newRegionNumber == currentHO->regionNumber)) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"No Region Change with BMPS mode")); + preFWNotification = curFWNotification; + THSRELEASELOCK("WLANTL_HSBMPSRSSIRegionChangedNotification", + &tlCtxt->hoSupport.hosLock); + return status; + } + else if(newRegionNumber > currentHO->regionNumber) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Region Increase Worse RSSI")); + for(idx = currentHO->regionNumber; idx < newRegionNumber; idx++) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if((WLANTL_HO_THRESHOLD_DOWN == hoSupport->registeredInd[idx].triggerEvent[sIdx]) || + (WLANTL_HO_THRESHOLD_CROSS == hoSupport->registeredInd[idx].triggerEvent[sIdx])) + { + if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx]) + { + cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx]; + usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx]; + + evtType = WLANTL_HO_THRESHOLD_DOWN; + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx)); + currentHO->regionNumber = newRegionNumber; + status = cbFunction(pAdapter, evtType, usrCtxt, pRSSINotification->avgRssi); + } + } + } + } + } + else + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Region Decrease Better RSSI")); + idx = (currentHO->regionNumber)?(currentHO->regionNumber-1):0; + while (idx >= newRegionNumber) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if((WLANTL_HO_THRESHOLD_UP & hoSupport->registeredInd[idx].triggerEvent[sIdx]) || + (WLANTL_HO_THRESHOLD_CROSS & hoSupport->registeredInd[idx].triggerEvent[sIdx])) + { + if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx]) + { + cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx]; + usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx]; + + evtType = WLANTL_HO_THRESHOLD_UP; + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx)); + currentHO->regionNumber = newRegionNumber; + status = cbFunction(pAdapter, evtType, usrCtxt, pRSSINotification->avgRssi); + } + } + } + if (!idx--) + break; + } + } + + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"BMPS State, MSG from FW, Trigger Event %d, region index %d", + evtType, currentHO->regionNumber)); + + THSRELEASELOCK("WLANTL_HSBMPSRSSIRegionChangedNotification", + &tlCtxt->hoSupport.hosLock); + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSHandleRSSIChange +( + v_PVOID_t pAdapter, + v_S7_t currentRSSI +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t currentRegion = 0; + v_U8_t idx, sIdx; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO; + WLANTL_HO_SUPPORT_TYPE *hoSupport; + WLANTL_RSSICrossThresholdCBType cbFunction = NULL; + v_PVOID_t usrCtxt = NULL; + v_U8_t evtType = WLANTL_HO_THRESHOLD_NA; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + currentHO = &(tlCtxt->hoSupport.currentHOState); + hoSupport = &(tlCtxt->hoSupport); + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"CRegion %d, NThreshold %d, HRSSI %d", + currentHO->regionNumber, + currentHO->numThreshold, + currentHO->historyRSSI)); + + /* Find where is current region */ + for(idx = 0; idx < currentHO->numThreshold; idx++) + { + if(hoSupport->registeredInd[idx].rssiValue < currentRSSI) + { + currentRegion = idx; + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found region %d, not bottom", currentRegion)); + break; + } + } + + /* If could not find then new RSSI is belong to bottom region */ + if(idx == currentHO->numThreshold) + { + currentRegion = idx; + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current region is bottom %d", idx)); + } + + /* This is a hack. Actual assignment was happening after the below checks. This hack is needed till TL + posts message and nothing else in the callback indicating UP/DOWN event to the registered module */ + currentHO->historyRSSI = currentRSSI; + + if(currentRegion == currentHO->regionNumber) + { + currentHO->historyRSSI = currentRSSI; + return status; + } + else if(currentRegion > currentHO->regionNumber) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Region Increase Worse RSSI")); + for(idx = currentHO->regionNumber; idx < currentRegion; idx++) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if((WLANTL_HO_THRESHOLD_DOWN == hoSupport->registeredInd[idx].triggerEvent[sIdx]) || + (WLANTL_HO_THRESHOLD_CROSS == hoSupport->registeredInd[idx].triggerEvent[sIdx])) + { + if(NULL != hoSupport->registeredInd[idx].crossCBFunction[sIdx]) + { + cbFunction = hoSupport->registeredInd[idx].crossCBFunction[sIdx]; + usrCtxt = hoSupport->registeredInd[idx].usrCtxt[sIdx]; + + evtType = WLANTL_HO_THRESHOLD_DOWN; + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx].triggerEvent[sIdx], idx)); + status = WLANTL_HSSerializeTlIndication(pAdapter, evtType, usrCtxt, cbFunction, currentRSSI); + } + } + } + } + } + else + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Region Decrease Better RSSI")); + for(idx = currentHO->regionNumber; idx > currentRegion; idx--) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if((WLANTL_HO_THRESHOLD_UP & hoSupport->registeredInd[idx - 1].triggerEvent[sIdx]) || + (WLANTL_HO_THRESHOLD_CROSS & hoSupport->registeredInd[idx - 1].triggerEvent[sIdx])) + { + if(NULL != hoSupport->registeredInd[idx - 1].crossCBFunction[sIdx]) + { + cbFunction = hoSupport->registeredInd[idx - 1].crossCBFunction[sIdx]; + usrCtxt = hoSupport->registeredInd[idx - 1].usrCtxt[sIdx]; + + evtType = WLANTL_HO_THRESHOLD_UP; + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Trigger Event %d, region index %d", hoSupport->registeredInd[idx - 1].triggerEvent[sIdx], idx - 1)); + status = WLANTL_HSSerializeTlIndication(pAdapter, evtType, usrCtxt, cbFunction, currentRSSI); + } + } + } + } + } + + currentHO->historyRSSI = currentRSSI; + currentHO->regionNumber = currentRegion; + WLANTL_HSDebugDisplay(pAdapter); + + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Client fail to handle region change in normal mode %d", status)); + } + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSHandleRXFrame +( + v_PVOID_t pAdapter, + v_U8_t frameType, + v_PVOID_t pBDHeader, + v_U8_t STAid, + v_BOOL_t isBroadcast, + vos_pkt_t *dataBuffer +) +{ + WLANTL_CURRENT_HO_STATE_TYPE *currentHO = NULL; + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_S7_t currentAvgRSSI = 0; + v_U8_t ac; + v_U32_t currentTimestamp; + v_U8_t tid; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + THSGETLOCK("WLANTL_HSHandleRXFrame", &tlCtxt->hoSupport.hosLock); + WLANTL_StatHandleRXFrame(pAdapter, pBDHeader, STAid, isBroadcast, dataBuffer); + + /* If this frame is not management frame increase frame count */ + if((0 != tlCtxt->hoSupport.currentTraffic.idleThreshold) && + (WLANTL_MGMT_FRAME_TYPE != frameType)) + { + tid = WDA_GET_RX_TID( pBDHeader ); + + /* If AP uses TID greater than 8 for EAPOL packet connection will not + be established. To ensure no connection fail use TID as zero.*/ + if (WLANTL_TID_INVALID(tid)) { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "WLAN TL:Invalid Tid: %d", tid); + tid = 0; + } + + ac = WLANTL_HO_TID_2_AC[(v_U8_t)tid]; + + /* Only Voice traffic is handled as real time traffic */ + if(WLANTL_AC_VO == ac) + { + tlCtxt->hoSupport.currentTraffic.rtRXFrameCount++; + } + else + { + tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount++; + } + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"RX frame AC %d, RT Frame Count %d, NRT Frame Count %d", + ac, + tlCtxt->hoSupport.currentTraffic.rtRXFrameCount, + tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount)); + } + + currentHO = &tlCtxt->hoSupport.currentHOState; + if(VOS_TRUE == tlCtxt->isBMPS) + { + WLANTL_HSGetRSSI(pAdapter, pBDHeader, STAid, ¤tAvgRSSI); + currentHO->historyRSSI = currentAvgRSSI; + THSRELEASELOCK("WLANTL_HSHandleRXFrame", &tlCtxt->hoSupport.hosLock); + return status; + } + + currentTimestamp = WDA_GET_RX_TIMESTAMP(pBDHeader); + if((currentTimestamp - currentHO->sampleTime) < WLANTL_HO_SAMPLING_PERIOD) + { + THSRELEASELOCK("WLANTL_HSHandleRXFrame", &tlCtxt->hoSupport.hosLock); + return status; + } + currentHO->sampleTime = currentTimestamp; + + /* Get Current RSSI from BD Heaser */ + status = WLANTL_HSGetRSSI(pAdapter, pBDHeader, STAid, ¤tAvgRSSI); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Get RSSI Fail")); + THSRELEASELOCK("WLANTL_HSHandleRXFrame", &tlCtxt->hoSupport.hosLock); + return status; + } +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + if(!IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE) +#endif + { + /* If any threshold is not registerd, DO NOTHING! */ + if(0 == tlCtxt->hoSupport.currentHOState.numThreshold) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"There is no thresholds pass")); + } + else + { + /* Handle current RSSI value, region, notification, etc */ + status = WLANTL_HSHandleRSSIChange(pAdapter, currentAvgRSSI); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Handle new RSSI fail")); + THSRELEASELOCK("WLANTL_HSHandleRXFrame", + &tlCtxt->hoSupport.hosLock); + return status; + } + } + } + + THSRELEASELOCK("WLANTL_HSHandleRXFrame", &tlCtxt->hoSupport.hosLock); + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSHandleTXFrame +( + v_PVOID_t pAdapter, + v_U8_t ac, + v_U8_t STAid, + vos_pkt_t *dataBuffer, + v_PVOID_t bdHeader +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + /* Traffic status report is not registered, JUST DO NOTHING */ + if(0 == tlCtxt->hoSupport.currentTraffic.idleThreshold) + { + return VOS_STATUS_SUCCESS; + } + + + /* Only Voice traffic is handled as real time traffic */ + if(WLANTL_AC_VO == ac) + { + tlCtxt->hoSupport.currentTraffic.rtTXFrameCount++; + } + else + { + tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount++; + } + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"TX frame AC %d, RT Frame Count %d, NRT Frame Count %d", + ac, + tlCtxt->hoSupport.currentTraffic.rtTXFrameCount, + tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount)); + + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSRegRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID, + v_PVOID_t usrCtxt +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t idx, sIdx; + WLANTL_HO_SUPPORT_TYPE *hoSupport; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO; + v_U8_t clientOrder = 0; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if((-1 < rssiValue) || (NULL == crossCBFunction)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Reg Invalid Argument")); + return VOS_STATUS_E_INVAL; + } + + THSGETLOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + + currentHO = &(tlCtxt->hoSupport.currentHOState); + hoSupport = &(tlCtxt->hoSupport); + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Make Registration Module %d, Event %d, RSSI %d", moduleID, triggerEvent, rssiValue)); + + if((WLANTL_MAX_AVAIL_THRESHOLD < currentHO->numThreshold) || + (WLANTL_MAX_AVAIL_THRESHOLD == currentHO->numThreshold)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"No more available slot, please DEL first %d", + currentHO->numThreshold)); + THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return VOS_STATUS_E_RESOURCES; + } + + if(0 == currentHO->numThreshold) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"First Registration")); + hoSupport->registeredInd[0].rssiValue = rssiValue; + hoSupport->registeredInd[0].triggerEvent[0] = triggerEvent; + hoSupport->registeredInd[0].crossCBFunction[0] = crossCBFunction; + hoSupport->registeredInd[0].usrCtxt[0] = usrCtxt; + hoSupport->registeredInd[0].whoIsClient[0] = moduleID; + hoSupport->registeredInd[0].numClient++; + } + else + { + for(idx = 0; idx < currentHO->numThreshold; idx++) + { + if(rssiValue == hoSupport->registeredInd[idx].rssiValue) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Reg CB P %p, registered CB P %p", + crossCBFunction, + hoSupport->registeredInd[idx].crossCBFunction[sIdx])); + if(crossCBFunction == hoSupport->registeredInd[idx].crossCBFunction[sIdx]) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Same RSSI %d, Same CB %p already registered", + rssiValue, crossCBFunction)); + WLANTL_HSDebugDisplay(pAdapter); + THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return status; + } + } + + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if(NULL == hoSupport->registeredInd[idx].crossCBFunction[sIdx]) + { + clientOrder = sIdx; + break; + } + } + hoSupport->registeredInd[idx].triggerEvent[clientOrder] = triggerEvent; + hoSupport->registeredInd[idx].crossCBFunction[clientOrder] = crossCBFunction; + hoSupport->registeredInd[idx].usrCtxt[clientOrder] = usrCtxt; + hoSupport->registeredInd[idx].whoIsClient[clientOrder] = moduleID; + hoSupport->registeredInd[idx].numClient++; + WLANTL_HSDebugDisplay(pAdapter); + THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return status; + } + } + for(idx = 0; idx < currentHO->numThreshold; idx++) + { + if(rssiValue > hoSupport->registeredInd[idx].rssiValue) + { + for(sIdx = (currentHO->numThreshold - 1); (sIdx > idx) || (sIdx == idx); sIdx--) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "Shift %d array to %d", sIdx, sIdx + 1)); + vos_mem_copy(&hoSupport->registeredInd[sIdx + 1], &hoSupport->registeredInd[sIdx], sizeof(WLANTL_HO_RSSI_INDICATION_TYPE)); + memset(&hoSupport->registeredInd[sIdx], 0, sizeof(WLANTL_HO_RSSI_INDICATION_TYPE)); + if(0 == sIdx) + { + break; + } + } + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Put in Here %d", idx)); + hoSupport->registeredInd[idx].rssiValue = rssiValue; + hoSupport->registeredInd[idx].triggerEvent[0] = triggerEvent; + hoSupport->registeredInd[idx].crossCBFunction[0] = crossCBFunction; + hoSupport->registeredInd[idx].usrCtxt[0] = usrCtxt; + hoSupport->registeredInd[idx].whoIsClient[0] = moduleID; + hoSupport->registeredInd[idx].numClient++; + break; + } + } + if(currentHO->numThreshold == idx) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, "New threshold put in bottom")); + + hoSupport->registeredInd[currentHO->numThreshold].rssiValue = rssiValue; + hoSupport->registeredInd[currentHO->numThreshold].triggerEvent[0] = triggerEvent; + hoSupport->registeredInd[currentHO->numThreshold].crossCBFunction[0] = crossCBFunction; + hoSupport->registeredInd[currentHO->numThreshold].usrCtxt[0] = usrCtxt; + hoSupport->registeredInd[currentHO->numThreshold].whoIsClient[0] = moduleID; + hoSupport->registeredInd[currentHO->numThreshold].numClient++; + } + } + + currentHO->numThreshold++; + if((VOS_FALSE == tlCtxt->isBMPS) && (rssiValue > currentHO->historyRSSI)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Added Threshold above current RSSI level, old RN %d", currentHO->regionNumber)); + if(4 > currentHO->regionNumber) + { + currentHO->regionNumber++; + } + else + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Current region number is max %d, cannot increase anymore", currentHO->regionNumber)); + } + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"increase region number without notification %d", currentHO->regionNumber)); + } + else if(VOS_TRUE == tlCtxt->isBMPS) + { + if(0 != currentHO->regionNumber) + { + if(hoSupport->registeredInd[currentHO->regionNumber].rssiValue < rssiValue) + { + currentHO->regionNumber++; + if((WLANTL_HO_THRESHOLD_DOWN == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Registered RSSI value larger than Current RSSI, and DOWN event, Send Notification")); + WLANTL_HSSerializeTlIndication(pAdapter, WLANTL_HO_THRESHOLD_DOWN, usrCtxt, crossCBFunction, + hoSupport->registeredInd[currentHO->regionNumber].rssiValue); + } + } + else if((currentHO->regionNumber < (currentHO->numThreshold - 1)) && + (hoSupport->registeredInd[currentHO->regionNumber + 1].rssiValue > rssiValue)) + { + if((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Registered RSSI value smaller than Current RSSI")); + } + } + } + else + { + if(hoSupport->registeredInd[currentHO->regionNumber].rssiValue > rssiValue) + { + if((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Registered RSSI value smaller than Current RSSI")); + } + } + } + } + + if((VOS_FALSE == tlCtxt->isBMPS) && + (rssiValue >= currentHO->historyRSSI) && (0 != currentHO->historyRSSI) && + ((WLANTL_HO_THRESHOLD_DOWN == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Registered RSSI value larger than Current RSSI, and DOWN event, Send Notification")); + WLANTL_HSSerializeTlIndication(pAdapter, WLANTL_HO_THRESHOLD_DOWN, usrCtxt, crossCBFunction, currentHO->historyRSSI); + } + else if((VOS_FALSE == tlCtxt->isBMPS) && + (rssiValue < currentHO->historyRSSI) && (0 != currentHO->historyRSSI) && + ((WLANTL_HO_THRESHOLD_UP == triggerEvent) || (WLANTL_HO_THRESHOLD_CROSS == triggerEvent))) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Registered RSSI value smaller than Current RSSI, and UP event, Send Notification")); + WLANTL_HSSerializeTlIndication(pAdapter, WLANTL_HO_THRESHOLD_UP, usrCtxt, crossCBFunction, currentHO->historyRSSI); + } + + if((VOS_TRUE == tlCtxt->isBMPS) || (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Register into FW, now BMPS")); + /* this function holds the lock across a downstream WDA function call, this is violates some lock + ordering checks done on some HLOS see CR323221*/ + THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + WLANTL_SetFWRSSIThresholds(pAdapter); + THSGETLOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + } + + WLANTL_HSDebugDisplay(pAdapter); + THSRELEASELOCK("WLANTL_HSRegRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSDeregRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t idx, sIdx; + WLANTL_HO_SUPPORT_TYPE *hoSupport; + WLANTL_CURRENT_HO_STATE_TYPE *currentHO; + v_BOOL_t bmpsAbove = VOS_FALSE; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if(0 == tlCtxt->hoSupport.currentHOState.numThreshold) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Empty list, can not remove")); + return VOS_STATUS_E_EMPTY; + } + + THSGETLOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + currentHO = &(tlCtxt->hoSupport.currentHOState); + hoSupport = &(tlCtxt->hoSupport); + + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"DEL target RSSI %d, event %d", rssiValue, triggerEvent)); + + if((VOS_TRUE == tlCtxt->isBMPS) && (0 < currentHO->regionNumber)) + { + if(rssiValue >= hoSupport->registeredInd[currentHO->regionNumber - 1].rssiValue) + { + bmpsAbove = VOS_TRUE; + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Remove Threshold larger than current region")); + } + } + + for(idx = 0; idx < currentHO->numThreshold; idx++) + { + if(rssiValue == hoSupport->registeredInd[idx].rssiValue) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + if(crossCBFunction == tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx]) + { + tlCtxt->hoSupport.registeredInd[idx].triggerEvent[sIdx] = 0; + tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx] = NULL; + tlCtxt->hoSupport.registeredInd[idx].usrCtxt[sIdx] = NULL; + tlCtxt->hoSupport.registeredInd[idx].whoIsClient[sIdx] = 0; + tlCtxt->hoSupport.registeredInd[idx].numClient--; + } + } + if(0 != tlCtxt->hoSupport.registeredInd[idx].numClient) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found Multiple idx is %d", idx)); + WLANTL_HSDebugDisplay(pAdapter); + THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return status; + } + else + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Found Single idx is %d", idx)); + break; + } + } + } + if(idx == currentHO->numThreshold) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Could not find entry, maybe invalid arg")); + THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return VOS_STATUS_E_INVAL; + } + + for(idx = 0; idx < currentHO->numThreshold; idx++) + { + if(rssiValue == hoSupport->registeredInd[idx].rssiValue) + { + if((currentHO->numThreshold - 1) == idx) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Remove target is last one")); + /* Does not need move any element, just remove last array entry */ + } + else + { + for(sIdx = idx; sIdx < (currentHO->numThreshold - 1); sIdx++) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Shift up from %d to %d", sIdx + 1, sIdx)); + vos_mem_copy(&hoSupport->registeredInd[sIdx], &hoSupport->registeredInd[sIdx + 1], sizeof(WLANTL_HO_RSSI_INDICATION_TYPE)); + } + } + break; + } + } + /* Common remove last array entry */ + tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].rssiValue = WLANTL_HO_DEFAULT_RSSI; + for(idx = 0; idx < WLANTL_HS_NUM_CLIENT; idx++) + { + tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].triggerEvent[idx] = WLANTL_HO_THRESHOLD_NA; + tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].crossCBFunction[idx] = NULL; + tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].usrCtxt[idx] = NULL; + tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].whoIsClient[idx] = 0; + tlCtxt->hoSupport.registeredInd[currentHO->numThreshold - 1].numClient = 0; + } + + if( ((VOS_FALSE == tlCtxt->isBMPS) && (rssiValue >= currentHO->historyRSSI)) + || ((VOS_TRUE == tlCtxt->isBMPS) && (VOS_TRUE == bmpsAbove)) ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "Removed Threshold above current RSSI level, old RN %d", + currentHO->regionNumber)); + if(0 < currentHO->regionNumber) + { + currentHO->regionNumber--; + } + else + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "Current Region number is 0, cannot decrease anymore")); + } + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "Decrease region number without notification %d", + currentHO->regionNumber)); + } + + /* Decrease number of thresholds */ + tlCtxt->hoSupport.currentHOState.numThreshold--; + /*Reset the FW notification*/ + tlCtxt->hoSupport.currentHOState.fwNotification=0; + + if((VOS_TRUE == tlCtxt->isBMPS) || (IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE)) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Register into FW, now BMPS")); + /* this function holds the lock across a downstream WDA function call, this is violates some lock + ordering checks done on some HLOS see CR323221*/ + THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + WLANTL_SetFWRSSIThresholds(pAdapter); + THSGETLOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + } + + /* Based on new threshold set recalculated current RSSI status */ + if(0 < tlCtxt->hoSupport.currentHOState.numThreshold) + { + } + else if(0 == tlCtxt->hoSupport.currentHOState.numThreshold) + { + currentHO->regionNumber = 0; + TLLOGW(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN,"No registered Threshold")); + /* What should do? */ + } + + WLANTL_HSDebugDisplay(pAdapter); + THSRELEASELOCK("WLANTL_HSDeregRSSIIndicationCB", &tlCtxt->hoSupport.hosLock); + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSSetAlpha +( + v_PVOID_t pAdapter, + int valueAlpha +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + THSGETLOCK("WLANTL_HSSetAlpha", &tlCtxt->hoSupport.hosLock); + tlCtxt->hoSupport.currentHOState.alpha = (v_U8_t)valueAlpha; + THSRELEASELOCK("WLANTL_HSSetAlpha", &tlCtxt->hoSupport.hosLock); + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSRegGetTrafficStatus +( + v_PVOID_t pAdapter, + v_U32_t idleThreshold, + v_U32_t period, + WLANTL_TrafficStatusChangedCBType trfficStatusCB, + v_PVOID_t usrCtxt +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + if((0 == idleThreshold) || (0 == period) || (NULL == trfficStatusCB)) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid Argument Passed from SME")); + return VOS_STATUS_E_INVAL; + } + + tlCtxt->hoSupport.currentTraffic.idleThreshold = idleThreshold; + tlCtxt->hoSupport.currentTraffic.measurePeriod = period; + tlCtxt->hoSupport.currentTraffic.trafficCB = trfficStatusCB; + tlCtxt->hoSupport.currentTraffic.usrCtxt = usrCtxt; + + vos_timer_start(&tlCtxt->hoSupport.currentTraffic.trafficTimer, + tlCtxt->hoSupport.currentTraffic.measurePeriod); + + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSInit +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_U8_t idx, sIdx; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } +#ifdef WLANTL_HO_UTEST + rssi = 0; + direction = -1; +#endif /* WLANTL_HO_UTEST */ + + /* set default current HO status */ + tlCtxt->hoSupport.currentHOState.alpha = WLANTL_HO_DEFAULT_ALPHA; + tlCtxt->hoSupport.currentHOState.historyRSSI = 0; + tlCtxt->hoSupport.currentHOState.numThreshold = 0; + tlCtxt->hoSupport.currentHOState.regionNumber = 0; + tlCtxt->hoSupport.currentHOState.sampleTime = 0; + + /* set default current traffic status */ + tlCtxt->hoSupport.currentTraffic.trafficStatus.rtTrafficStatus + = WLANTL_HO_RT_TRAFFIC_STATUS_OFF; + tlCtxt->hoSupport.currentTraffic.trafficStatus.nrtTrafficStatus + = WLANTL_HO_NRT_TRAFFIC_STATUS_OFF; + tlCtxt->hoSupport.currentTraffic.idleThreshold = 0; + tlCtxt->hoSupport.currentTraffic.measurePeriod = 0; + tlCtxt->hoSupport.currentTraffic.rtRXFrameCount = 0; + tlCtxt->hoSupport.currentTraffic.rtTXFrameCount = 0; + tlCtxt->hoSupport.currentTraffic.nrtRXFrameCount = 0; + tlCtxt->hoSupport.currentTraffic.nrtTXFrameCount = 0; + tlCtxt->hoSupport.currentTraffic.trafficCB = NULL; + + /* Initialize indication array */ + for(idx = 0; idx < WLANTL_MAX_AVAIL_THRESHOLD; idx++) + { + for(sIdx = 0; sIdx < WLANTL_HS_NUM_CLIENT; sIdx++) + { + tlCtxt->hoSupport.registeredInd[idx].triggerEvent[sIdx] = WLANTL_HO_THRESHOLD_NA; + tlCtxt->hoSupport.registeredInd[idx].crossCBFunction[sIdx] = NULL; + tlCtxt->hoSupport.registeredInd[idx].usrCtxt[sIdx] = NULL; + tlCtxt->hoSupport.registeredInd[idx].whoIsClient[sIdx] = 0; + } + tlCtxt->hoSupport.registeredInd[idx].rssiValue = WLANTL_HO_DEFAULT_RSSI; + tlCtxt->hoSupport.registeredInd[idx].numClient = 0; + } + + vos_timer_init(&tlCtxt->hoSupport.currentTraffic.trafficTimer, + VOS_TIMER_TYPE_SW, + WLANTL_HSTrafficStatusTimerExpired, + pAdapter); + + + vos_lock_init(&tlCtxt->hoSupport.hosLock); + tlCtxt->hoSupport.macCtxt = vos_get_context(VOS_MODULE_ID_SME, pAdapter); + + return status; +} + + +/*========================================================================== + + FUNCTION WLANTL_HSDeInit + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ + +VOS_STATUS WLANTL_HSDeInit +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + // Destroy the timer... + status = vos_timer_destroy( &tlCtxt->hoSupport.currentTraffic.trafficTimer ); + if ( !VOS_IS_STATUS_SUCCESS( status ) ) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"WLANTL_HSStop: Timer Destroy Fail Status %d", status)); + } + return status; +} + + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSStop +( + v_PVOID_t pAdapter +) +{ + WLANTL_CbType *tlCtxt = VOS_GET_TL_CB(pAdapter); + VOS_STATUS status = VOS_STATUS_SUCCESS; + VOS_TIMER_STATE timerState; + + if(NULL == tlCtxt) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Invalid TL handle")); + return VOS_STATUS_E_INVAL; + } + + timerState = vos_timer_getCurrentState(&tlCtxt->hoSupport.currentTraffic.trafficTimer); + if(VOS_TIMER_STATE_RUNNING == timerState) + { + TLLOG1(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO,"Stop Traffic status monitoring timer")); + status = vos_timer_stop(&tlCtxt->hoSupport.currentTraffic.trafficTimer); + } + if(VOS_STATUS_SUCCESS != status) + { + TLLOGE(VOS_TRACE(VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR,"Timer Stop Failed, Status %d", status)); + } + + //Deregister the traffic Status + tlCtxt->hoSupport.currentTraffic.idleThreshold = 0; + tlCtxt->hoSupport.currentTraffic.measurePeriod = 0; + tlCtxt->hoSupport.currentTraffic.trafficCB = NULL; + tlCtxt->hoSupport.currentTraffic.usrCtxt = NULL; + + return status; +} + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSSerializeTlIndication +( + v_PVOID_t pAdapter, + v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + WLANTL_RSSICrossThresholdCBType cbFunction, + v_U8_t avgRssi +) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + vos_msg_t msg; + WLANTL_TlIndicationReq *pMsg; + + pMsg = vos_mem_malloc(sizeof(WLANTL_TlIndicationReq)); + if ( NULL == pMsg ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "In %s, failed to allocate mem for req", __func__); + return VOS_STATUS_E_NOMEM; + } + + pMsg->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_RSSI_IND); + pMsg->msgLen = (tANI_U16)sizeof(WLANTL_TlIndicationReq); + pMsg->sessionId = 0;//for now just pass 0 + pMsg->pAdapter = pAdapter; + pMsg->pUserCtxt = pUserCtxt; + pMsg->rssiNotification = rssiNotification; + pMsg->avgRssi = avgRssi; + pMsg->tlCallback = cbFunction; + + + msg.type = eWNI_SME_RSSI_IND; + msg.bodyptr = pMsg; + msg.reserved = 0; + + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &msg)) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "In %s, failed to post msg to self", __func__); + vos_mem_free(pMsg); + status = VOS_STATUS_E_FAILURE; + } + + return status; +} + +#endif //WLAN_FEATURE_NEIGHBOR_ROAMING diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.h b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.h new file mode 100644 index 000000000000..b2b0c693e68e --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_hosupport.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_TL_HOSUPPORT_H +#define WLAN_QCT_TL_HOSUPPORT_H + +/*=========================================================================== + + W L A N T R A N S P O R T L A Y E R + HO SUPPORT I N T E R N A L A P I + + +DESCRIPTION + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +12/11/08 sch Initial creation + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ +#include "wlan_qct_tl.h" + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSGetDataRSSI +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid, + v_S7_t *currentAvgRSSI +); +#endif + +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSHandleRXFrame +( + v_PVOID_t pAdapter, + v_U8_t frameType, + v_PVOID_t pBDHeader, + v_U8_t STAid, + v_BOOL_t isBroadcast, + vos_pkt_t *dataBuffer +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSHandleTXFrame +( + v_PVOID_t pAdapter, + v_U8_t ac, + v_U8_t STAid, + vos_pkt_t *dataBuffer, + v_PVOID_t bdHeader +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSRegRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID, + v_PVOID_t usrCtxt +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSDeregRSSIIndicationCB +( + v_PVOID_t pAdapter, + v_S7_t rssiValue, + v_U8_t triggerEvent, + WLANTL_RSSICrossThresholdCBType crossCBFunction, + VOS_MODULE_ID moduleID +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSBMPSRSSIRegionChangedNotification +( + v_PVOID_t pAdapter, + tpSirRSSINotification pRSSINotification +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSSetAlpha +( + v_PVOID_t pAdapter, + int valueAlpha +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSRegGetTrafficStatus +( + v_PVOID_t pAdapter, + v_U32_t idleThreshold, + v_U32_t period, + WLANTL_TrafficStatusChangedCBType trfficStatusCB, + v_PVOID_t usrCtxt +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSInit +( + v_PVOID_t pAdapter +); + + +/*========================================================================== + + FUNCTION WLANTL_HSDeInit + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ + +VOS_STATUS WLANTL_HSDeInit +( + v_PVOID_t pAdapter +); + + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSStop +( + v_PVOID_t pAdapter +); + +VOS_STATUS WLANTL_SetFWRSSIThresholds +( + v_PVOID_t pAdapter +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_HSSerializeTlIndication +( + v_PVOID_t pAdapter, + v_U8_t rssiNotification, + v_PVOID_t pUserCtxt, + WLANTL_RSSICrossThresholdCBType cbFunction, + v_U8_t avgRssi +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION + + PARAMETERS + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_StatHandleTXFrame +( + v_PVOID_t pAdapter, + v_U8_t STAid, + vos_pkt_t *dataBuffer, + v_PVOID_t pBDHeader, + WLANTL_MetaInfoType *txMetaInfo +); + +#endif + +#endif /* WLAN_QCT_TL_HOSUPPORT_H */ diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_trace.c b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_trace.c new file mode 100644 index 000000000000..39b4a5f469ad --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tl_trace.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/************************************************************************ + wlan_qct_tl_trace.c + + \brief implementation for trace related APIs + + ========================================================================*/ + +#include "vos_trace.h" +#include "vos_types.h" +#include "wlan_qct_tl_trace.h" +#include "tlDebug.h" + +static v_U8_t* tlTraceGetEventString(v_U32_t code) +{ + switch(code) + { + CASE_RETURN_STRING(TRACE_CODE_TL_STA_STATE); + CASE_RETURN_STRING(TRACE_CODE_TL_EAPOL_PKT_PENDING); + CASE_RETURN_STRING(TRACE_CODE_TL_GET_FRAMES_EAPOL); + CASE_RETURN_STRING(TRACE_CODE_TL_RX_CONN_EAPOL); + CASE_RETURN_STRING(TRACE_CODE_TL_REGISTER_STA_CLIENT); + CASE_RETURN_STRING(TRACE_CODE_TL_SUSPEND_DATA_TX); + CASE_RETURN_STRING(TRACE_CODE_TL_RESUME_DATA_TX); + CASE_RETURN_STRING(TRACE_CODE_TL_STA_PKT_PENDING); + CASE_RETURN_STRING(TRACE_CODE_TL_QUEUE_CURRENT); + CASE_RETURN_STRING(TRACE_CODE_TL_REORDER_TIMER_EXP_CB); + CASE_RETURN_STRING(TRACE_CODE_TL_BA_SESSION_DEL); + CASE_RETURN_STRING(TRACE_CODE_TL_ASSOC_FAILED); + CASE_RETURN_STRING(TRACE_CODE_TL_FORWARD_CACHED_FRAMES); + CASE_RETURN_STRING(TRACE_CODE_TL_FLUSH_CACHED_FRAMES); + CASE_RETURN_STRING(TRACE_CODE_TL_CACHE_FRAME); + default: + return ("UNKNOWN"); + break; + } +} + +void tlTraceDump(void *pMac, tpvosTraceRecord pRecord, v_U16_t recIndex) +{ + TLLOGE( VOS_TRACE (VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "%04d %012u S%-3d %-14s %-30s(0x%x)", + recIndex, pRecord->time, pRecord->session, + " TL Event: ", + tlTraceGetEventString (pRecord->code), + pRecord->data)); +} + +void tlTraceInit() +{ + vosTraceRegister(VOS_MODULE_ID_TL, (tpvosTraceCb)&tlTraceDump); +} diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h b/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h new file mode 100644 index 000000000000..cb6414a61436 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tli.h @@ -0,0 +1,1964 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_TLI_H +#define WLAN_QCT_TLI_H + +/*=========================================================================== + + W L A N T R A N S P O R T L A Y E R + I N T E R N A L A P I + + +DESCRIPTION + This file contains the internal declarations used within wlan transport + layer module. + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/13 rajekuma Added RMC support in TL +02/19/10 bad Fixed 802.11 to 802.3 ft issues with WAPI +01/14/10 rnair Fixed the byte order for the WAI packet type. +01/08/10 lti Added TL Data Caching +10/09/09 rnair Add support for WAPI +02/02/09 sch Add Handoff support +12/09/08 lti Fixes for AMSS compilation +12/02/08 lti Fix fo trigger frame generation +10/31/08 lti Fix fo TL tx suspend +10/01/08 lti Merged in fixes from reordering +09/05/08 lti Fixes following QOS unit testing +08/06/08 lti Added QOS support +07/18/08 lti Fixes following integration + Added frame translation +06/26/08 lti Fixes following unit testing +05/05/08 lti Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_packet.h" +#include "vos_api.h" +#include "vos_timer.h" +#include "vos_mq.h" +#include "vos_list.h" +#include "wlan_qct_tl.h" +#include "pmcApi.h" +#include "wlan_qct_hal.h" + + +#define STATIC static +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*Maximum number of TIDs */ +#define WLAN_MAX_TID 8 + +/*Offset of the OUI field inside the LLC/SNAP header*/ +#define WLANTL_LLC_OUI_OFFSET 3 + +/*Size of the OUI type field inside the LLC/SNAP header*/ +#define WLANTL_LLC_OUI_SIZE 3 + +/*Offset of the protocol type field inside the LLC/SNAP header*/ +#define WLANTL_LLC_PROTO_TYPE_OFFSET (WLANTL_LLC_OUI_OFFSET + WLANTL_LLC_OUI_SIZE) + +/*Size of the protocol type field inside the LLC/SNAP header*/ +#define WLANTL_LLC_PROTO_TYPE_SIZE 2 + +/*802.1x protocol type */ +#define WLANTL_LLC_8021X_TYPE 0x888E + +/*WAPI protocol type */ +#define WLANTL_LLC_WAI_TYPE 0x88b4 +#define WLANTL_ETHERTYPE_ARP 0x0806 + +#ifdef FEATURE_WLAN_TDLS +#define WLANTL_LLC_TDLS_TYPE 0x890d +#endif + +/*Length offset inside the AMSDU sub-frame header*/ +#define WLANTL_AMSDU_SUBFRAME_LEN_OFFSET 12 + +/*802.3 header definitions*/ +#define WLANTL_802_3_HEADER_LEN 14 + +/* Offset of DA field in a 802.3 header*/ +#define WLANTL_802_3_HEADER_DA_OFFSET 0 + +/*802.11 header definitions - header len without QOS ctrl field*/ +#define WLANTL_802_11_HEADER_LEN 24 + +/*802.11 header length + QOS ctrl field*/ +#define WLANTL_MPDU_HEADER_LEN 32 + +/*802.11 header definitions*/ +#define WLANTL_802_11_MAX_HEADER_LEN 40 + +/*802.11 header definitions - qos ctrl field len*/ +#define WLANTL_802_11_HEADER_QOS_CTL 2 + +/*802.11 header definitions - ht ctrl field len*/ +#define WLANTL_802_11_HEADER_HT_CTL 4 + +/* Offset of Addr1 field in a 802.11 header*/ +#define WLANTL_802_11_HEADER_ADDR1_OFFSET 4 + +/*802.11 ADDR4 MAC addr field len */ +#define WLANTL_802_11_HEADER_ADDR4_LEN VOS_MAC_ADDR_SIZE + +/* Length of an AMSDU sub-frame */ +#define TL_AMSDU_SUBFRM_HEADER_LEN 14 + +/* Length of the LLC header*/ +#define WLANTL_LLC_HEADER_LEN 8 + +/*As per 802.11 spec */ +#define WLANTL_MGMT_FRAME_TYPE 0x00 +#define WLANTL_CTRL_FRAME_TYPE 0x10 +#define WLANTL_DATA_FRAME_TYPE 0x20 + +#define WLANTL_MGMT_PROBE_REQ_FRAME_TYPE 0x04 + +/*Value of the data type field in the 802.11 frame */ +#define WLANTL_80211_DATA_TYPE 0x02 +#define WLANTL_80211_DATA_QOS_SUBTYPE 0x08 +#define WLANTL_80211_NULL_QOS_SUBTYPE 0x0C +#define WLANTL_80211_MGMT_ACTION_SUBTYPE 0x0D +#define WLANTL_80211_MGMT_ACTION_NO_ACK_SUBTYPE 0x0E + +/*Defines for internal utility functions */ +#define WLANTL_FRAME_TYPE_BCAST 0xff +#define WLANTL_FRAME_TYPE_MCAST 0x01 +#define WLANTL_FRAME_TYPE_UCAST 0x00 + +#define WLANTL_FRAME_TYPESUBTYPE_MASK 0x3F + +#ifdef WLAN_FEATURE_RMC +#define WLANTL_RMC_HASH_TABLE_SIZE (32) +#endif + +#define WLANTL_SAMPLE_INTERVAL 50 +#define WLANTL_SAMPLE_COUNT 2 + +/*------------------------------------------------------------------------- + BT-AMP related definition - !!! should probably be moved to BT-AMP header +---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Helper macros +---------------------------------------------------------------------------*/ + /*Checks STA index validity*/ +#define WLANTL_STA_ID_INVALID( _staid )( _staid >= WLAN_MAX_STA_COUNT ) + +/*As per Libra behavior */ +#define WLANTL_STA_ID_BCAST 0xFF + +/*Checks TID validity*/ +#define WLANTL_TID_INVALID( _tid ) ( _tid >= WLAN_MAX_TID ) + +/*Checks AC validity*/ +#define WLANTL_AC_INVALID( _tid ) ( _tid >= WLANTL_MAX_AC ) + +/*Determines the addr field offset based on the frame xtl bit*/ +#define WLANTL_MAC_ADDR_ALIGN( _dxtl ) \ + ( ( 0 == _dxtl ) ? \ + WLANTL_802_3_HEADER_DA_OFFSET: WLANTL_802_11_HEADER_ADDR1_OFFSET ) + +/*Determines the header len based on the disable xtl field*/ +#define WLANTL_MAC_HEADER_LEN( _dxtl) \ + ( ( 0 == _dxtl )? \ + WLANTL_802_3_HEADER_LEN:WLANTL_802_11_HEADER_LEN ) + +/*Determines the necesary length of the BD header - in case + UMA translation is enabled enough room needs to be left in front of the + packet for the 802.11 header to be inserted*/ +#define WLANTL_BD_HEADER_LEN( _dxtl ) \ + ( ( 0 == _dxtl )? \ + (WLANHAL_TX_BD_HEADER_SIZE+WLANTL_802_11_MAX_HEADER_LEN): WLANHAL_TX_BD_HEADER_SIZE ) + + +#define WLAN_TL_CEIL( _a, _b) (( 0 != (_a)%(_b))? (_a)/(_b) + 1: (_a)/(_b)) + +/*get TL control block from vos global context */ +#define VOS_GET_TL_CB(_pvosGCtx) \ + ((WLANTL_CbType*)vos_get_context( VOS_MODULE_ID_TL, _pvosGCtx)) + +/* Check whether Rx frame is LS or EAPOL packet (other than data) */ +#define WLANTL_BAP_IS_NON_DATA_PKT_TYPE(usType) \ + ((WLANTL_BT_AMP_TYPE_AR == usType) || (WLANTL_BT_AMP_TYPE_SEC == usType) || \ + (WLANTL_BT_AMP_TYPE_LS_REQ == usType) || (WLANTL_BT_AMP_TYPE_LS_REP == usType)) + +/*get RSSI0 from a RX BD*/ +/* 7 bits in phystats represent -100dBm to +27dBm */ +#define WLAN_TL_RSSI_CORRECTION 100 +#define WLANTL_GETRSSI0(pBD) (WDA_GETRSSI0(pBD) - WLAN_TL_RSSI_CORRECTION) + +/*get RSSI1 from a RX BD*/ +#define WLANTL_GETRSSI1(pBD) (WDA_GETRSSI1(pBD) - WLAN_TL_RSSI_CORRECTION) + +#define WLANTL_GETSNR(pBD) WDA_GET_RX_SNR(pBD) + +/* Check whether Rx frame is LS or EAPOL packet (other than data) */ +#define WLANTL_BAP_IS_NON_DATA_PKT_TYPE(usType) \ + ((WLANTL_BT_AMP_TYPE_AR == usType) || (WLANTL_BT_AMP_TYPE_SEC == usType) || \ + (WLANTL_BT_AMP_TYPE_LS_REQ == usType) || (WLANTL_BT_AMP_TYPE_LS_REP == usType)) + +#define WLANTL_CACHE_TRACE_WATERMARK 100 +/*--------------------------------------------------------------------------- + TL signals for TX thread +---------------------------------------------------------------------------*/ +typedef enum +{ + /*Suspend signal - following serialization of a HAL suspend request*/ + WLANTL_TX_SIG_SUSPEND = 0, + + /*Res need signal - triggered when all pending TxComp have been received + and TL is low on resources*/ + WLANTL_TX_RES_NEEDED = 1, + + /* Forwarding RX cached frames. This is not used anymore as it is + replaced by WLANTL_RX_FWD_CACHED in RX thread*/ + WLANTL_TX_FWD_CACHED = 2, + + /* Serialized STAID AC Indication */ + WLANTL_TX_STAID_AC_IND = 3, + + /* Serialzie TX transmit request */ + WLANTL_TX_START_XMIT = 4, + + /* Serialzie Finish UL Authentication request */ + WLANTL_FINISH_ULA = 5, + + /* Serialized Snapshot request indication */ + WLANTL_TX_SNAPSHOT = 6, + + /* Detected a fatal error issue SSR */ + WLANTL_TX_FATAL_ERROR = 7, + + WLANTL_TX_FW_DEBUG = 8, + + WLANTL_TX_KICKDXE = 9, + + WLANTL_TX_MAX +}WLANTL_TxSignalsType; + + +/*--------------------------------------------------------------------------- + TL signals for RX thread +---------------------------------------------------------------------------*/ +typedef enum +{ + + /* Forwarding RX cached frames */ + WLANTL_RX_FWD_CACHED = 0, + + /* Forward pre assoc cached frames */ + WLANTL_RX_FWD_PRE_ASSOC_CACHED = 1, +}WLANTL_RxSignalsType; + +/*--------------------------------------------------------------------------- + STA Event type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Transmit frame event */ + WLANTL_TX_EVENT = 0, + + /* Receive frame event */ + WLANTL_RX_EVENT = 1, + + WLANTL_MAX_EVENT +}WLANTL_STAEventType; + +/*--------------------------------------------------------------------------- + + DESCRIPTION + State machine used by transport layer for receiving or transmitting + packets. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the tx/rx vos buffer + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef VOS_STATUS (*WLANTL_STAFuncType)( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/*--------------------------------------------------------------------------- + STA FSM Entry type +---------------------------------------------------------------------------*/ +typedef struct +{ + WLANTL_STAFuncType pfnSTATbl[WLANTL_MAX_EVENT]; +} WLANTL_STAFsmEntryType; + +/* Receive in connected state - only EAPOL or WAI*/ +VOS_STATUS WLANTL_STARxConn( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/* Transmit in connected state - only EAPOL or WAI*/ +VOS_STATUS WLANTL_STATxConn( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/* Receive in authenticated state - all data allowed*/ +VOS_STATUS WLANTL_STARxAuth( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/* Transmit in authenticated state - all data allowed*/ +VOS_STATUS WLANTL_STATxAuth( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/* Receive in disconnected state - no data allowed*/ +VOS_STATUS WLANTL_STARxDisc( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/* Transmit in disconnected state - no data allowed*/ +VOS_STATUS WLANTL_STATxDisc( v_PVOID_t pAdapter, + v_U8_t ucSTAId, + vos_pkt_t** pvosDataBuff, + v_BOOL_t bForwardIAPPwithLLC); + +/* TL State Machine */ +STATIC const WLANTL_STAFsmEntryType tlSTAFsm[WLANTL_STA_MAX_STATE] = +{ + /* WLANTL_STA_INIT */ + { { + NULL, /* WLANTL_TX_EVENT - no packets should get transmitted*/ + NULL, /* WLANTL_RX_EVENT - no packets should be received - drop*/ + } }, + + /* WLANTL_STA_CONNECTED */ + { { + WLANTL_STATxConn, /* WLANTL_TX_EVENT - only EAPoL or WAI frames are allowed*/ + WLANTL_STARxConn, /* WLANTL_RX_EVENT - only EAPoL or WAI frames can be rx*/ + } }, + + /* WLANTL_STA_AUTHENTICATED */ + { { + WLANTL_STATxAuth, /* WLANTL_TX_EVENT - all data frames allowed*/ + WLANTL_STARxAuth, /* WLANTL_RX_EVENT - all data frames can be rx */ + } }, + + /* WLANTL_STA_DISCONNECTED */ + { { + WLANTL_STATxDisc, /* WLANTL_TX_EVENT - do nothing */ + WLANTL_STARxDisc, /* WLANTL_RX_EVENT - frames will still be fwd-ed*/ + } } +}; + +/*--------------------------------------------------------------------------- + Reordering information +---------------------------------------------------------------------------*/ + +#define WLANTL_MAX_WINSIZE 64 +#define WLANTL_MAX_BA_SESSION 40 + +typedef struct +{ + v_BOOL_t isAvailable; + v_U64_t ullReplayCounter[WLANTL_MAX_WINSIZE]; + v_PVOID_t arrayBuffer[WLANTL_MAX_WINSIZE]; +} WLANTL_REORDER_BUFFER_T; + + +/* To handle Frame Q aging, timer is needed + * After timer expired, Qed frames have to be routed to upper layer + * WLANTL_TIMER_EXPIER_UDATA_T is user data type for timer callback + */ +typedef struct +{ + /* Global contect, HAL, HDD need this */ + v_PVOID_t pAdapter; + + /* TL context handle */ + v_PVOID_t pTLHandle; + + /* Current STAID, to know STA context */ + v_U32_t STAID; + + v_U8_t TID; +} WLANTL_TIMER_EXPIER_UDATA_T; + +typedef struct +{ + /*specifies if re-order session exists*/ + v_U8_t ucExists; + + /* Current Index */ + v_U32_t ucCIndex; + + /* Count of the total packets in list*/ + v_U16_t usCount; + + /* vos ttimer to handle Qed frames aging */ + vos_timer_t agingTimer; + + /* Q windoe size */ + v_U32_t winSize; + + /* Available RX frame buffer size */ + v_U32_t bufferSize; + + /* Start Sequence number */ + v_U32_t SSN; + + /* BA session ID, generate by HAL */ + v_U32_t sessionID; + + v_U32_t currentESN; + + v_U32_t pendingFramesCount; + + vos_lock_t reorderLock; + + /* Aging timer callback user data */ + WLANTL_TIMER_EXPIER_UDATA_T timerUdata; + + WLANTL_REORDER_BUFFER_T *reorderBuffer; + + v_U16_t LastSN; + bool set_data_filter; +}WLANTL_BAReorderType; + + +/*--------------------------------------------------------------------------- + UAPSD information +---------------------------------------------------------------------------*/ +typedef struct +{ + /* flag set when a UAPSD session with triggers generated in fw is being set*/ + v_U8_t ucSet; +}WLANTL_UAPSDInfoType; + +#ifdef WLAN_FEATURE_RMC +struct tTL_RMCList +{ + struct tTL_RMCList *next; + v_MACADDR_t rmcAddr; + v_U16_t mcSeqCtl; + v_U32_t rxMCDupcnt; +}; + +typedef struct tTL_RMCList WLANTL_RMC_SESSION; +#endif + +/*--------------------------------------------------------------------------- + per-STA cache info +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U16_t cacheSize; + v_TIME_t cacheInitTime; + v_TIME_t cacheDoneTime; + v_TIME_t cacheClearTime; +}WLANTL_CacheInfoType; + + +/*--------------------------------------------------------------------------- + STA Client type +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Flag that keeps track of registration; only one STA with unique + ID allowed */ + v_U8_t ucExists; + + /* Function pointer to the receive packet handler from HDD */ + WLANTL_STARxCBType pfnSTARx; + + /* Function pointer to the transmit complete confirmation handler + from HDD */ + WLANTL_TxCompCBType pfnSTATxComp; + + /* Function pointer to the packet retrieval routine in HDD */ + WLANTL_STAFetchPktCBType pfnSTAFetchPkt; + + /* Reordering information for the STA */ + WLANTL_BAReorderType atlBAReorderInfo[WLAN_MAX_TID]; + + /* STA Descriptor, contains information related to the new added STA */ + WLAN_STADescType wSTADesc; + + /* Current connectivity state of the STA */ + WLANTL_STAStateType tlState; + + /* Station priority */ + WLANTL_STAPriorityType tlPri; + + /* Value of the averaged RSSI for this station */ + v_S7_t rssiAvg; + + /* Value of the averaged RSSI for this station in BMPS */ + v_S7_t rssiAvgBmps; + + /* Value of the Alpha to calculate RSSI average */ + v_S7_t rssiAlpha; + + /* Value of the averaged RSSI for this station */ + v_U32_t uLinkQualityAvg; + + /* Sum of SNR for snrIdx number of consecutive frames */ + v_U32_t snrSum; + + /* Number of consecutive frames over which snrSum is calculated */ + v_S7_t snrIdx; + + /* Average SNR of previous 20 frames */ + v_S7_t prevSnrAvg; + + /* Average SNR returned by fw */ + v_S7_t snrAvgBmps; + + /* Tx packet count per station per TID */ + v_U32_t auTxCount[WLAN_MAX_TID]; + + /* Rx packet count per station per TID */ + v_U32_t auRxCount[WLAN_MAX_TID]; + + /* Suspend flag */ + v_U8_t ucTxSuspended; + + /* Pointer to the AMSDU chain maintained by the AMSDU de-aggregation + completion sub-module */ + vos_pkt_t* vosAMSDUChainRoot; + + /* Pointer to the root of the chain */ + vos_pkt_t* vosAMSDUChain; + + /* Used for saving/restoring frame header for 802.3/11 AMSDU sub-frames */ + v_U8_t aucMPDUHeader[WLANTL_MPDU_HEADER_LEN]; + + /* length of the header */ + v_U8_t ucMPDUHeaderLen; + + /* Enabled ACs currently serviced by TL (automatic setup in TL)*/ + v_U8_t aucACMask[WLANTL_NUM_TX_QUEUES]; + + /* Current AC to be retrieved */ + WLANTL_ACEnumType ucCurrentAC; + + /*Packet pending flag - set if tx is pending for the station*/ + v_U8_t ucPktPending; + + /*EAPOL Packet pending flag - set if EAPOL packet is pending for the station*/ + v_U8_t ucEapolPktPending; + + /*used on tx packet to signal when there is no more data to tx for the + moment=> packets can be passed to BAL */ + v_U8_t ucNoMoreData; + + /* Last serviced AC to be retrieved */ + WLANTL_ACEnumType ucServicedAC; + + /* Current weight for the AC */ + v_U8_t ucCurrentWeight; + + /* Info used for UAPSD trigger frame generation */ + WLANTL_UAPSDInfoType wUAPSDInfo[WLANTL_MAX_AC]; + + /* flag to signal if a trigger frames is pending */ + v_U8_t ucPendingTrigFrm; + + WLANTL_TRANSFER_STA_TYPE trafficStatistics; + + /*Members needed for packet caching in TL*/ + /*Begining of the cached packets chain*/ + vos_pkt_t* vosBegCachedFrame; + + /*Begining of the cached packets chain*/ + vos_pkt_t* vosEndCachedFrame; + + WLANTL_CacheInfoType tlCacheInfo; + /* LWM related fields */ + + v_BOOL_t enableCaching; + + //current station is slow. LWM mode is enabled. + v_BOOL_t ucLwmModeEnabled; + //LWM events is reported when LWM mode is on. Able to send more traffic + //under the constraints of uBuffThresholdMax + v_BOOL_t ucLwmEventReported; + + //v_U8_t uLwmEventReported; + + /* Flow control fields */ + //memory used in previous round + v_U8_t bmuMemConsumed; + + //the number packets injected in this round + v_U32_t uIngress_length; + + //number of packets allowed in current round beforing receiving new FW memory updates + v_U32_t uBuffThresholdMax; + + + // v_U32_t uEgress_length; + + // v_U32_t uIngress_length; + + // v_U32_t uBuffThresholdMax; + + // v_U32_t uBuffThresholdUsed; + + /* Value used to set LWM in FW. Initialized to 1/3* WLAN_STA_BMU_THRESHOLD_MAX + In the future, it can be dynamically adjusted if we find the reason to implement + such algorithm. */ + v_U32_t uLwmThreshold; + + //tx disable forced by Riva software + v_U16_t fcStaTxDisabled; + + /** HDD buffer status for packet scheduling. Once HDD + * stores a new packet in a previously empty queue, it + * will call TL interface to set the fields. The fields + * will be cleaned by TL when TL can't fetch more packets + * from the queue. */ + // the fields are ucPktPending and ucACMask; + + /* Queue to keep unicast station management frame */ + vos_list_t pStaManageQ; + + /* 1 means replay check is needed for the station, + * 0 means replay check is not needed for the station*/ + v_BOOL_t ucIsReplayCheckValid; + + /* It contains 48-bit replay counter per TID*/ + v_U64_t ullReplayCounter[WLANTL_MAX_TID]; + + /* It contains no of replay packets found per STA. + It is for debugging purpose only.*/ + v_U32_t ulTotalReplayPacketsDetected; + + /* Set when pairwise key is installed, if ptkInstalled is + 1 then we have to encrypt the data irrespective of TL + state (CONNECTED/AUTHENTICATED) */ + v_U8_t ptkInstalled; + + v_U32_t linkCapacity; + +#ifdef WLAN_FEATURE_RMC + WLANTL_RMC_SESSION *mcastSession[WLANTL_RMC_HASH_TABLE_SIZE]; + vos_lock_t mcLock; +#endif + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + + /* Value of the averaged Data RSSI for this station */ + v_S7_t rssiDataAvg; + + /* Value of the averaged Data RSSI for this station in BMPS */ + v_S7_t rssiDataAvgBmps; + + /* Value of the Alpha to calculate Data RSSI average */ + v_S7_t rssiDataAlpha; + + WLANTL_InterfaceStatsType interfaceStats; +#endif + /* BD Rate for transmitting ARP packets */ + v_U8_t arpRate; + v_BOOL_t arpOnWQ5; + + /* Disassoc in progress */ + v_BOOL_t disassoc_progress; + + /* sample timer Tx frames */ + uint64_t tx_frames; + uint32_t tx_sample[WLANTL_SAMPLE_COUNT]; + uint64_t tx_samples_sum; + + /* flow control */ + uint8_t weight; + uint8_t weight_count; + uint8_t per; + uint8_t set_flag; + uint16_t queue; + uint16_t trate; + +}WLANTL_STAClientType; + +/*--------------------------------------------------------------------------- + BAP Client type +---------------------------------------------------------------------------*/ +typedef struct +{ + /* flag that keeps track of registration; only one non-data BT-AMP client + allowed */ + v_U8_t ucExists; + + /* pointer to the receive processing routine for non-data BT-AMP frames */ + WLANTL_BAPRxCBType pfnTlBAPRx; + + /* pointer to the flush call back complete function */ + WLANTL_FlushOpCompCBType pfnFlushOpCompleteCb; + + /* pointer to the non-data BT-AMP frame pending transmission */ + vos_pkt_t* vosPendingDataBuff; + + /* BAP station ID */ + v_U8_t ucBAPSTAId; +}WLANTL_BAPClientType; + + +/*--------------------------------------------------------------------------- + Management Frame Client type +---------------------------------------------------------------------------*/ +typedef struct +{ + /* flag that keeps track of registration; only one management frame + client allowed */ + v_U8_t ucExists; + + /* pointer to the receive processing routine for management frames */ + WLANTL_MgmtFrmRxCBType pfnTlMgmtFrmRx; + + /* pointer to the management frame pending transmission */ + vos_pkt_t* vosPendingDataBuff; +}WLANTL_MgmtFrmClientType; + +typedef struct +{ + WLANTL_TrafficStatusChangedCBType trafficCB; + WLANTL_HO_TRAFFIC_STATUS_TYPE trafficStatus; + v_U32_t idleThreshold; + v_U32_t measurePeriod; + v_U32_t rtRXFrameCount; + v_U32_t rtTXFrameCount; + v_U32_t nrtRXFrameCount; + v_U32_t nrtTXFrameCount; + vos_timer_t trafficTimer; + v_PVOID_t usrCtxt; +} WLANTL_HO_TRAFFIC_STATUS_HANDLE_TYPE; + +typedef struct +{ + v_S7_t rssiValue; + v_U8_t triggerEvent[WLANTL_HS_NUM_CLIENT]; + v_PVOID_t usrCtxt[WLANTL_HS_NUM_CLIENT]; + v_U8_t whoIsClient[WLANTL_HS_NUM_CLIENT]; + WLANTL_RSSICrossThresholdCBType crossCBFunction[WLANTL_HS_NUM_CLIENT]; + v_U8_t numClient; +} WLANTL_HO_RSSI_INDICATION_TYPE; + +typedef struct +{ + v_U8_t numThreshold; + v_U8_t regionNumber; + v_S7_t historyRSSI; + v_U8_t alpha; + v_U32_t sampleTime; + v_U32_t fwNotification; +} WLANTL_CURRENT_HO_STATE_TYPE; + +typedef struct +{ + WLANTL_HO_RSSI_INDICATION_TYPE registeredInd[WLANTL_MAX_AVAIL_THRESHOLD]; + WLANTL_CURRENT_HO_STATE_TYPE currentHOState; + WLANTL_HO_TRAFFIC_STATUS_HANDLE_TYPE currentTraffic; + v_PVOID_t macCtxt; + vos_lock_t hosLock; +} WLANTL_HO_SUPPORT_TYPE; + +typedef struct { + uint8 sta_id; + uint8 avg_per; + uint16 queue_len; + uint16_t rate; + uint16_t reserved; +} WLANTL_PerStaFlowControlParam; + +typedef struct { + uint8 num_stas; + WLANTL_PerStaFlowControlParam *sta_fc_info; +} WLANTL_FlowControlInfo; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define ROAM_MAX_INDEX_NUM 50 +#define ROAM_PER_INDEX_TIME 500 /* (msec) */ +#define MIN_PKTS_TO_START_MONTIOR 10 + +typedef struct +{ + v_U64_t lowRateRxPacketsRcvd; + v_U64_t totalPktRcvd; + v_U64_t time; +}WLANTL_RoamTrafficStatsType; + +typedef struct { + v_U8_t running; + v_U8_t staId; + v_S7_t index; + v_U8_t intialPktToStart; + v_U8_t minPercentage; + v_U16_t minRate; + v_U16_t maxRate; + v_U32_t minPktRequired; + v_U64_t totalPkt; + v_U64_t timeToWait; + v_U64_t lowRatePkt; + v_U64_t lastTriggerTime; + WLANTL_RoamTrafficStatsType rxRoamStats[ROAM_MAX_INDEX_NUM]; + void (*triggerRoamScanfn) (void *, v_U8_t); + void *hHal; +}WLANTL_RoamMonitorType; +#endif + +/*--------------------------------------------------------------------------- + TL control block type +---------------------------------------------------------------------------*/ +typedef struct +{ + /* TL configuration information */ + WLANTL_ConfigInfoType tlConfigInfo; + + /* list of the active stations */ + WLANTL_STAClientType* atlSTAClients[WLAN_MAX_STA_COUNT]; + + + /* information on the management frame client */ + WLANTL_MgmtFrmClientType tlMgmtFrmClient; + + /* information on the BT AMP client */ + WLANTL_BAPClientType tlBAPClient; + + /* number of packets sent to BAL waiting for tx complete confirmation */ + v_U16_t usPendingTxCompleteCount; + + /* global suspend flag */ + v_U8_t ucTxSuspended; + + /* resource flag */ + v_U32_t uResCount; + + /* dummy vos buffer - used for chains */ + vos_pkt_t* vosDummyBuf; + + /* temporary buffer for storing the packet that no longer fits */ + vos_pkt_t* vosTempBuf; + + /* The value of the station id and AC for the cached buffer */ + v_U8_t ucCachedSTAId; + v_U8_t ucCachedAC; + + /* Last registered STA - until multiple sta support is added this will + be used always for tx */ + v_U8_t ucRegisteredStaId; + + /*Current TL STA used for TX*/ + v_U8_t ucCurrentSTA; + + WLANTL_REORDER_BUFFER_T *reorderBufferPool; /* Allocate memory for [WLANTL_MAX_BA_SESSION] sessions */ + + WLANTL_HO_SUPPORT_TYPE hoSupport; + + v_BOOL_t bUrgent; + + + /* resource flag */ + v_U32_t bd_pduResCount; + + /* time interval to evaluate LWM mode*/ + //vos_timer_t tThresholdSamplingTimer; + +#if 0 + //information fields for flow control + tFcTxParams_type tlFCInfo; +#endif + + vos_pkt_t* vosTxFCBuf; + + /* LWM mode is enabled or not for each station. Bit-wise operation.32 station maximum. */ + // v_U32_t uStaLwmMask; + + /* LWM event is reported by FW. */ + // v_U32_t uStaLwmEventReported; + + /** Multiple Station Scheduling and TL queue management. + 4 HDD BC/MC data packet queue status is specified as Station 0's status. Weights used + in WFQ algorith are initialized in WLANTL_OPEN and contained in tlConfigInfo field. + Each station has fields of ucPktPending and AC mask to tell whether a AC has traffic + or not. + + Stations are served in a round-robin fashion from highest priority to lowest priority. + The number of round-robin times of each prioirty equals to the WFQ weights and differetiates + the traffic of different prioirty. As such, stations can not provide low priority packets if + high priority packets are all served. + */ + + /* Currently served station id. Reuse ucCurrentSTA field. */ + //v_U8_t uCurStaId; + + /* Current served station ID in round-robin method to traverse all stations.*/ + WLANTL_ACEnumType uCurServedAC; + + WLANTL_SpoofMacAddr spoofMacAddr; + + /* How many weights have not been served in current AC. */ + v_U8_t ucCurLeftWeight; + + /* BC/MC management queue. Current implementation uses queue size 1. Will check whether + size N is supported. */ + vos_list_t pMCBCManageQ; + + v_U32_t sendFCFrame; + + v_U8_t done_once; + v_U8_t uFramesProcThres; +#ifdef FEATURE_WLAN_TDLS + /*number of total TDLS peers registered to TL + Incremented at WLANTL_RegisterSTAClient(staType == WLAN_STA_TDLS) + Decremented at WLANTL_ClearSTAClient(staType == WLAN_STA_TDLS) */ + v_U8_t ucTdlsPeerCount; +#endif + /*whether we are in BMPS/UAPSD/WOWL mode, since the latter 2 need to be BMPS first*/ + v_BOOL_t isBMPS; + /* Whether WDA_DS_TX_START_XMIT msg is pending or not */ + v_BOOL_t isTxTranmitMsgPending; + +#ifdef WLAN_FEATURE_RMC + WLANTL_RMC_SESSION *rmcSession[WLANTL_RMC_HASH_TABLE_SIZE]; + vos_lock_t rmcLock; + v_U8_t multicastDuplicateDetectionEnabled; + v_U8_t rmcDataPathEnabled; + v_U32_t mcastDupCnt; +#endif + WLANTL_MonRxCBType pfnMonRx; + v_BOOL_t isConversionReq; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WLANTL_RoamMonitorType gDsRxRoamStats; +#endif + + /* TX sample data timer */ + vos_timer_t tx_frames_timer; + uint8_t sample_count; + + bool preassoc_caching; + vos_pkt_t* vosEapolCachedFrame; + WLANTL_FwdEapolCBType pfnEapolFwd; + + uint8_t track_arp; + uint32_t txbd_token; + +}WLANTL_CbType; + + +/*========================================================================== + + FUNCTION WLANTL_GetFrames + + DESCRIPTION + + BAL calls this function at the request of the lower bus interface. + When this request is being received TL will retrieve packets from HDD + in accordance with the priority rules and the count supplied by BAL. + + DEPENDENCIES + + HDD must have registered with TL at least one STA before this function + can be called. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + or BAL's control block can be extracted from its context + uSize: maximum size accepted by the lower layer + uFlowMask TX flow control mask. Each bit is defined as + WDA_TXFlowEnumType + + OUT + vosDataBuff: it will contain a pointer to the first buffer supplied + by TL, if there is more than one packet supplied, TL + will chain them through vOSS buffers + + RETURN VALUE + + The result code associated with performing the operation + + 1 or more: number of required resources if there are still frames to fetch + For Volans, it's BD/PDU numbers. For Prima, it's free DXE descriptors. + 0 : error or HDD queues are drained + + SIDE EFFECTS + +============================================================================*/ +v_U32_t +WLANTL_GetFrames +( + v_PVOID_t pAdapter, + vos_pkt_t **ppFrameDataBuff, + v_U32_t uSize, + v_U8_t uFlowMask, + v_BOOL_t* pbUrgent +); + +/*========================================================================== + + FUNCTION WLANTL_TxComp + + DESCRIPTION + It is being called by BAL upon asynchronous notification of the packet + or packets being sent over the bus. + + DEPENDENCIES + Tx complete cannot be called without a previous transmit. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + or BAL's control block can be extracted from its context + vosDataBuff: it will contain a pointer to the first buffer for which + the BAL report is being made, if there is more then one + packet they will be chained using vOSS buffers. + wTxSTAtus: the status of the transmitted packet, see above chapter + on HDD interaction for a list of possible values + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_TxComp +( + v_PVOID_t pAdapter, + vos_pkt_t *pFrameDataBuff, + VOS_STATUS wTxStatus +); + +/*========================================================================== + + FUNCTION WLANTL_RxFrames + + DESCRIPTION + Callback registered by TL and called by BAL when a packet is received + over the bus. Upon the call of this function TL will make the necessary + decision with regards to the forwarding or queuing of this packet and + the layer it needs to be delivered to. + + DEPENDENCIES + TL must be initiailized before this function gets called. + If the frame carried is a data frame then the station for which it is + destined to must have been previously registered with TL. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + or BAL's control block can be extracted from its context + + vosDataBuff: it will contain a pointer to the first buffer received, + if there is more then one packet they will be chained + using vOSS buffers. + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RxFrames +( + v_PVOID_t pAdapter, + vos_pkt_t *pFrameDataBuff +); + +/*========================================================================== + + FUNCTION WLANTL_RxCachedFrames + + DESCRIPTION + Utility function used by TL to forward the cached frames to a particular + station; + + DEPENDENCIES + TL must be initiailized before this function gets called. + If the frame carried is a data frame then the station for which it is + destined to must have been previously registered with TL. + + PARAMETERS + + IN + pTLCb: pointer to TL handle + + ucSTAId: station for which we need to forward the packets + + vosDataBuff: it will contain a pointer to the first cached buffer + received, if there is more then one packet they will be + chained using vOSS buffers. + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_RxCachedFrames +( + WLANTL_CbType* pTLCb, + v_U8_t ucSTAId, + vos_pkt_t* vosDataBuff +); + +/*========================================================================== + FUNCTION WLANTL_ResourceCB + + DESCRIPTION + Called by the TL when it has packets available for transmission. + + DEPENDENCIES + The TL must be registered with BAL before this function can be called. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + or BAL's control block can be extracted from its context + uCount: avail resource count obtained from hw + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ResourceCB +( + v_PVOID_t pAdapter, + v_U32_t uCount +); + + +/*========================================================================== + FUNCTION WLANTL_ProcessMainMessage + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + main thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ProcessMainMessage +( + v_PVOID_t pAdapter, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLANTL_ProcessTxMessage + + DESCRIPTION + Called by VOSS when a message was serialized for TL through the + tx thread/task. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + control block can be extracted from its context + message: type and content of the message + + + RETURN VALUE + + The result code associated with performing the operation + VOS_STATUS_SUCCESS: Everything is good :) + + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_ProcessTxMessage +( + v_PVOID_t pAdapter, + vos_msg_t* message +); + +/*========================================================================== + FUNCTION WLAN_TLGetNextTxIds + + DESCRIPTION + Gets the next station and next AC in the list + + DEPENDENCIES + + PARAMETERS + + OUT + pucSTAId: STAtion ID + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLAN_TLGetNextTxIds +( + v_PVOID_t pAdapter, + v_U8_t* pucSTAId +); + +/*========================================================================== + + FUNCTION WLANTL_CleanCb + + DESCRIPTION + Cleans TL control block + + DEPENDENCIES + + PARAMETERS + + IN + pTLCb: pointer to TL's control block + ucEmpty: set if TL has to clean up the queues and release pedning pkts + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_CleanCB +( + WLANTL_CbType* pTLCb, + v_U8_t ucEmpty +); + +/*========================================================================== + + FUNCTION WLANTL_CleanSTA + + DESCRIPTION + Cleans a station control block. + + DEPENDENCIES + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + control block can be extracted from its context + ucEmpty: if set the queues and pending pkts will be emptyed + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_CleanSTA +( + WLANTL_STAClientType* ptlSTAClient, + v_U8_t ucEmpty +); + +/*========================================================================== + FUNCTION WLANTL_GetTxResourcesCB + + DESCRIPTION + Processing function for Resource needed signal. A request will be issued + to BAL to get mor tx resources. + + DEPENDENCIES + The TL must be initialized before this function can be called. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + Other values can be returned as a result of a function call, please check + corresponding API for more info. + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_GetTxResourcesCB +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WLANTL_PrepareBDHeader + + DESCRIPTION + Callback function for serializing Suspend signal through Tx thread + + DEPENDENCIES + Just notify HAL that suspend in TL is complete. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + control block can be extracted from its context + pUserData: user data sent with the callback + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +void +WLANTL_PrepareBDHeader +( + vos_pkt_t* vosDataBuff, + v_PVOID_t* ppvBDHeader, + v_MACADDR_t* pvDestMacAdddr, + v_U8_t ucDisableFrmXtl, + VOS_STATUS* pvosSTAtus, + v_U16_t* usPktLen, + v_U8_t ucQosEnabled, + v_U8_t ucWDSEnabled, + v_U8_t extraHeadSpace +); + +/*========================================================================== + FUNCTION WLANTL_Translate8023To80211Header + + DESCRIPTION + Inline function for translating and 802.3 header into an 802.11 header. + + DEPENDENCIES + + + PARAMETERS + + IN + pTLCb: TL control block + + *pucStaId Station ID. In case of TDLS, this return the actual + station index used to transmit. + + IN/OUT + vosDataBuff: vos data buffer, will contain the new header on output + + OUT + pvosStatus: status of the operation + + RETURN VALUE + No return. + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Translate8023To80211Header +( + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + WLANTL_CbType* pTLCb, + v_U8_t *pucStaId, + WLANTL_MetaInfoType* pTlMetaInfo, + v_U8_t *ucWDSEnabled, + v_U8_t *extraHeadSpace +); +/*========================================================================== + FUNCTION WLANTL_Translate80211To8023Header + + DESCRIPTION + Inline function for translating and 802.11 header into an 802.3 header. + + DEPENDENCIES + + + PARAMETERS + + IN + pTLCb: TL control block + ucStaId: station ID + ucHeaderLen: Length of the header from BD + ucActualHLen: Length of header including padding or any other trailers + + IN/OUT + vosDataBuff: vos data buffer, will contain the new header on output + + OUT + pvosStatus: status of the operation + + RETURN VALUE + Status of the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_Translate80211To8023Header +( + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + v_U16_t usActualHLen, + v_U8_t ucHeaderLen, + WLANTL_CbType* pTLCb, + v_U8_t ucSTAId, + v_BOOL_t bForwardIAPPwithLLC +); + +VOS_STATUS +WLANTL_MonTranslate80211To8023Header +( + vos_pkt_t* vosDataBuff, + WLANTL_CbType* pTLCb +); +/*========================================================================== + FUNCTION WLANTL_FindFrameTypeBcMcUc + + DESCRIPTION + Utility function to find whether received frame is broadcast, multicast + or unicast. + + DEPENDENCIES + The STA must be registered with TL before this function can be called. + + PARAMETERS + + IN + pTLCb: pointer to the TL's control block + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the vos buffer + + IN/OUT + pucBcMcUc: pointer to buffer, will contain frame type on return + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_BADMSG: failed to extract info from data buffer + VOS_STATUS_SUCCESS: success + + SIDE EFFECTS + None. +============================================================================*/ +VOS_STATUS +WLANTL_FindFrameTypeBcMcUc +( + WLANTL_CbType *pTLCb, + v_U8_t ucSTAId, + vos_pkt_t *vosDataBuff, + v_U8_t *pucBcMcUc +); + +/*========================================================================== + + FUNCTION WLANTL_MgmtFrmRxDefaultCb + + DESCRIPTION + Default Mgmt Frm rx callback: asserts all the time. If this function gets + called it means there is no registered rx cb pointer for Mgmt Frm. + + DEPENDENCIES + + PARAMETERS + + Not used. + + RETURN VALUE + Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_MgmtFrmRxDefaultCb +( + v_PVOID_t pAdapter, + v_PVOID_t vosBuff +); + +/*========================================================================== + + FUNCTION WLANTL_STARxDefaultCb + + DESCRIPTION + Default BAP rx callback: asserts all the time. If this function gets + called it means there is no registered rx cb pointer for BAP. + + DEPENDENCIES + + PARAMETERS + + Not used. + + RETURN VALUE + Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_BAPRxDefaultCb +( + v_PVOID_t pAdapter, + vos_pkt_t* vosDataBuff, + WLANTL_BAPFrameEnumType frameType +); + +/*========================================================================== + + FUNCTION WLANTL_STARxDefaultCb + + DESCRIPTION + Default STA rx callback: asserts all the time. If this function gets + called it means there is no registered rx cb pointer for station. + (Mem corruption most likely, it should never happen) + + DEPENDENCIES + + PARAMETERS + + Not used. + + RETURN VALUE + Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_STARxDefaultCb +( + v_PVOID_t pAdapter, + vos_pkt_t* vosDataBuff, + v_U8_t ucSTAId, + WLANTL_RxMetaInfoType* pRxMetaInfo +); + +/*========================================================================== + + FUNCTION WLANTL_STAFetchPktDefaultCb + + DESCRIPTION + Default fetch callback: asserts all the time. If this function gets + called it means there is no registered fetch cb pointer for station. + (Mem corruption most likely, it should never happen) + + DEPENDENCIES + + PARAMETERS + + Not used. + + RETURN VALUE + Always FAILURE. + +============================================================================*/ +VOS_STATUS +WLANTL_STAFetchPktDefaultCb +( + v_PVOID_t pAdapter, + v_U8_t* pucSTAId, + WLANTL_ACEnumType ucAC, + vos_pkt_t** vosDataBuff, + WLANTL_MetaInfoType* tlMetaInfo +); + +/*========================================================================== + + FUNCTION WLANTL_TxCompDefaultCb + + DESCRIPTION + Default tx complete handler. It will release the completed pkt to + prevent memory leaks. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation; please + check vos_pkt_return_pkt for possible error codes. + +============================================================================*/ +VOS_STATUS +WLANTL_TxCompDefaultCb +( + v_PVOID_t pAdapter, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +); + +/*========================================================================== + + FUNCTION WLANTL_PackUpTriggerFrame + + DESCRIPTION + Packs up a trigger frame and places it in TL's cache for tx and notifies + BAL + + DEPENDENCIES + + PARAMETERS + + IN + pTLCb: pointer to the TL control block + pfnSTATxComp: Tx Complete Cb to be used when frame is received + ucSTAId: station id + ucAC: access category + + RETURN VALUE + None + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_PackUpTriggerFrame +( + WLANTL_CbType* pTLCb, + WLANTL_TxCompCBType pfnSTATxComp, + v_U8_t ucSTAId, + WLANTL_ACEnumType ucAC +); + +/*========================================================================== + + FUNCTION WLANTL_TxCompTriggFrameSI + + DESCRIPTION + Tx complete handler for the service interval trigger frame. + It will restart the SI timer. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + + ============================================================================*/ +VOS_STATUS +WLANTL_TxCompTriggFrameSI +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +); + +/*========================================================================== + + FUNCTION WLANTL_TxCompTriggFrameSI + + DESCRIPTION + Tx complete handler for the service interval trigger frame. + It will restart the SI timer. + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to + TL/HAL/PE/BAP/HDD control block can be extracted from + its context + vosDataBuff: pointer to the VOSS data buffer that was transmitted + wTxSTAtus: status of the transmission + + + RETURN VALUE + The result code associated with performing the operation + +============================================================================*/ +VOS_STATUS +WLANTL_TxCompTriggFrameDI +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS wTxSTAtus +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION Read RSSI value out of a RX BD + + PARAMETERS: Caller must validate all parameters + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_ReadRSSI +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid +); + +/*========================================================================== + + FUNCTION + + DESCRIPTION Read SNR value out of a RX BD + + PARAMETERS: Caller must validate all parameters + + RETURN VALUE + +============================================================================*/ +VOS_STATUS WLANTL_ReadSNR +( + v_PVOID_t pAdapter, + v_PVOID_t pBDHeader, + v_U8_t STAid +); + + +void WLANTL_PowerStateChangedCB +( + v_PVOID_t pAdapter, + tPmcState newState +); + +/*========================================================================== + FUNCTION WLANTL_FwdPktToHDD + + DESCRIPTION + Determine the Destation Station ID and route the Frame to Upper Layer + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station being processed + vosDataBuff: pointer to the rx vos buffer + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: invalid input parameters + VOS_STATUS_E_FAULT: pointer to TL cb is NULL ; access would cause a + page fault + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WLANTL_FwdPktToHDD +( + v_PVOID_t pvosGCtx, + vos_pkt_t* pvosDataBuff, + v_U8_t ucSTAId +); + +#ifdef WLAN_FEATURE_RMC +VOS_STATUS WLANTL_RmcInit +( + v_PVOID_t pAdapter +); + +VOS_STATUS WLANTL_RmcDeInit +( + v_PVOID_t pAdapter +); + + +tANI_U8 WLANTL_RmcHashRmcSession ( v_MACADDR_t *pMcastAddr ); + + +WLANTL_RMC_SESSION *WLANTL_RmcLookUpRmcSession +( + WLANTL_RMC_SESSION *rmcSession[], + v_MACADDR_t *pMcastAddr +); + +WLANTL_RMC_SESSION *WLANTL_RmcAddRmcSession +( + WLANTL_RMC_SESSION *rmcSession[], + v_MACADDR_t *pMcastAddr +); + +tANI_U8 +WLANTL_RmcDeleteRmcSession +( + WLANTL_RMC_SESSION *rmcSession[], + v_MACADDR_t *pMcastAddr +); + +VOS_STATUS +WLANTL_ProcessRmcCommand +( + WLANTL_CbType* pTLCb, + v_MACADDR_t *pMcastAddr, + tANI_U32 command +); + +/*============================================================================= + FUNCTION WLANTL_IsDuplicateMcastFrm + + DESCRIPTION + This function checks for duplicast multicast frames and drops them. + + DEPENDENCIES + + PARAMETERS + + IN + + pClientSTA : Pointer to WLANTL_STAClientType + aucBDHeader : Pointer to BD header + + RETURN VALUE + + VOS_FALSE: This frame is not a duplicate + + VOS_TRUE: This frame is a duplicate + +==============================================================================*/ +v_U8_t +WLANTL_IsDuplicateMcastFrm +( + WLANTL_STAClientType *pClientSTA, + vos_pkt_t* vosDataBuff +); + +/*============================================================================= + FUNCTION WLANTL_McastDeleteAllEntries + + DESCRIPTION + This function removes all multicast entries used for duplicate detection + + DEPENDENCIES + + PARAMETERS + + IN + + pClientSTA : Pointer to WLANTL_STAClientType + + RETURN VALUE + + None + +==============================================================================*/ +void +WLANTL_McastDeleteAllEntries(WLANTL_STAClientType * pClientSTA); + +#endif /*WLAN_FEATURE_RMC*/ + +#endif /* #ifndef WLAN_QCT_TLI_H */ diff --git a/drivers/staging/prima/CORE/TL/src/wlan_qct_tli_ba.h b/drivers/staging/prima/CORE/TL/src/wlan_qct_tli_ba.h new file mode 100644 index 000000000000..6265e8921e60 --- /dev/null +++ b/drivers/staging/prima/CORE/TL/src/wlan_qct_tli_ba.h @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_TLI_BA_H +#define WLAN_QCT_TLI_BA_H + +/*=========================================================================== + + W L A N T R A N S P O R T L A Y E R + B L O C K A C K I N T E R N A L A P I + + +DESCRIPTION + This file contains the internal declarations used within wlan transport + layer module for BA session support, AMSDU de-aggregation and + MSDU reordering. + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/22/08 sch Update based on unit test +07/31/08 lti Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_tli.h" + +/*--------------------------------------------------------------------------- + Re-order opcode filled in by RPE + !!! fix me: (check with RPE doc if the codes are correct) + ---------------------------------------------------------------------------*/ +typedef enum +{ + WLANTL_OPCODE_INVALID = 0, + WLANTL_OPCODE_QCUR_FWDBUF = 1, + WLANTL_OPCODE_FWDBUF_FWDCUR = 2, + WLANTL_OPCODE_QCUR = 3, + WLANTL_OPCODE_FWDBUF_QUEUECUR = 4, + WLANTL_OPCODE_FWDBUF_DROPCUR = 5, + WLANTL_OPCODE_FWDALL_DROPCUR = 6, + WLANTL_OPCODE_FWDALL_QCUR = 7, + WLANTL_OPCODE_TEARDOWN = 8, + WLANTL_OPCODE_DROPCUR = 9, + WLANTL_OPCODE_MAX +}WLANTL_OpCodeEnumType; + +void WLANTL_InitBAReorderBuffer +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + + FUNCTION WLANTL_BaSessionAdd + + DESCRIPTION + HAL notifies TL when a new Block Ack session is being added. + + DEPENDENCIES + A BA session on Rx needs to be added in TL before the response is + being sent out + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station for which requested the BA + session + ucTid: Tspec ID for the new BA session + uSize: size of the reordering window + + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered or BA session already + exists + VOS_STATUS_E_NOSUPPORT: Not yet supported + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_BaSessionAdd +( + v_PVOID_t pvosGCtx, + v_U16_t sessionID, + v_U32_t ucSTAId, + v_U8_t ucTid, + v_U32_t uBufferSize, + v_U32_t winSize, + v_U32_t SSN +); + +/*========================================================================== + + FUNCTION WLANTL_BaSessionDel + + DESCRIPTION + HAL notifies TL when a new Block Ack session is being deleted. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx: pointer to the global vos context; a handle to TL's + control block can be extracted from its context + ucSTAId: identifier of the station for which requested the BA + session + ucTid: Tspec ID for the new BA session + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_INVAL: Input parameters are invalid + VOS_STATUS_E_FAULT: Station ID is outside array boundaries or pointer + to TL cb is NULL ; access would cause a page fault + VOS_STATUS_E_EXISTS: Station was not registered or BA session already + exists + VOS_STATUS_E_NOSUPPORT: Not yet supported + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_BaSessionDel +( + v_PVOID_t pvosGCtx, + v_U16_t ucSTAId, + v_U8_t ucTid +); + +/*========================================================================== + FUNCTION WLANTL_AMSDUProcess + + DESCRIPTION + Process A-MSDU sub-frame. Start of chain if marked as first frame. + Linked at the end of the existing AMSDU chain. + + + DEPENDENCIES + + PARAMETERS + + IN/OUT: + vosDataBuff: vos packet for the received data + outgoing contains the root of the chain for the rx + aggregated MSDU if the frame is marked as last; otherwise + NULL + + IN + pAdapter: pointer to the global adapter context; a handle to TL's + control block can be extracted from its context + pvBDHeader: pointer to the BD header + ucSTAId: STAtion ID + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_AMSDUProcess +( + v_PVOID_t pvosGCtx, + vos_pkt_t** ppVosDataBuff, + v_PVOID_t pvBDHeader, + v_U8_t ucSTAId, + v_U8_t ucMPDUHLen, + v_U16_t usMPDULen +); + +/*========================================================================== + FUNCTION WLANTL_MSDUReorder + + DESCRIPTION + MSDU reordering + + DEPENDENCIES + + PARAMETERS + + IN + + vosDataBuff: vos packet for the received data + pvBDHeader: pointer to the BD header + ucSTAId: STAtion ID + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_MSDUReorder +( + WLANTL_CbType *pTLCb, + vos_pkt_t **vosDataBuff, + v_PVOID_t pvBDHeader, + v_U8_t ucSTAId, + v_U8_t ucTid +); + + +/*========================================================================== + Utility functions + ==========================================================================*/ + +/*========================================================================== + FUNCTION WLANTL_AMSDUCompleteFrame + + DESCRIPTION + Complete AMSDU de-aggregation + + DEPENDENCIES + + PARAMETERS + + IN/OUT: + vosDataBuff: vos packet for the received data + + IN + pvBDHeader: pointer to the BD header + ucSTAId: STAtion ID + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_AMSDUCompleteFrame +( + vos_pkt_t* vosDataBuff, + v_U8_t ucMPDUHLen, + v_U16_t usMPDULen +); + +/*========================================================================== + + FUNCTION WLANTL_QueueCurrent + + DESCRIPTION + It will queue a packet at a given slot index in the MSDU reordering list. + + DEPENDENCIES + + PARAMETERS + + IN + pwBaReorder: pointer to the BA reordering session info + vosDataBuff: data buffer to be queued + ucSlotIndex: slot index + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_SUCCESS: Everything is OK + + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WLANTL_QueueCurrent +( + WLANTL_BAReorderType* pwBaReorder, + vos_pkt_t** vosDataBuff, + v_U8_t ucSlotIndex +); + +/*========================================================================== + + FUNCTION WLANTL_ChainFrontPkts + + DESCRIPTION + It will remove all the packets from the front of a vos list and chain + them to a vos pkt . + + DEPENDENCIES + + PARAMETERS + + IN + ucCount: number of packets to extract + pwBaReorder: pointer to the BA reordering session info + + OUT + vosDataBuff: data buffer containing the extracted chain of packets + + RETURN VALUE + The result code associated with performing the operation + + VOS_STATUS_E_SUCCESS: Everything is OK + + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANTL_ChainFrontPkts +( + v_U32_t fwdIndex, + v_U8_t opCode, + vos_pkt_t **vosDataBuff, + WLANTL_BAReorderType *pwBaReorder, + WLANTL_CbType *pTLCb +); + +/*========================================================================== + + FUNCTION WLANTL_FillReplayCounter + + DESCRIPTION + It will fill repaly counter at a given slot index in the MSDU reordering list. + + DEPENDENCIES + + PARAMETERS + + IN + pwBaReorder : pointer to the BA reordering session info + replayCounter: replay counter to be filled + ucSlotIndex : slot index + + RETURN VALUE + NONE + + + SIDE EFFECTS + NONE + + ============================================================================*/ +void WLANTL_FillReplayCounter +( + WLANTL_BAReorderType* pwBaReorder, + v_U64_t replayCounter, + v_U8_t ucSlotIndex +); + +#endif /* #ifndef WLAN_QCT_TLI_H */ diff --git a/drivers/staging/prima/CORE/VOSS/inc/event_defs.h b/drivers/staging/prima/CORE/VOSS/inc/event_defs.h new file mode 100644 index 000000000000..869017202a43 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/event_defs.h @@ -0,0 +1,1925 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef EVENT_DEFS_H +#define EVENT_DEFS_H + + +typedef enum +{ + EVENT_DROP_ID = 0, + + EVENT_BAND_CLASS_CHANGE = 0x0100, /* Includes band class as payload */ + EVENT_CDMA_CH_CHANGE, /* Includes cdma channel as payload */ + EVENT_BS_P_REV_CHANGE, /* Includes BS p_rev as payload */ + EVENT_P_REV_IN_USE_CHANGE, /* Includes p_rev_in_use as payload */ + EVENT_SID_CHANGE, /* Includes SID as payload */ + EVENT_NID_CHANGE, /* Includes NID as payload */ + EVENT_PZID_CHANGE, /* Includes PZID as payload */ + EVENT_PDE_SESSION_END, /* No payload */ + EVENT_OP_MODE_CHANGE, /* Includes operation mode as payload */ + EVENT_MESSAGE_RECEIVED, /* Includes channel and message ID as + payload */ + EVENT_MESSAGE_TRANSMITTED, /* Includes channel and message ID as + payload */ + EVENT_TIMER_EXPIRED, /* Includes timer ID as payload */ + EVENT_COUNTER_THRESHOLD, /* Includes counter ID as payload */ + EVENT_CALL_PROCESSING_STATE_CHANGE, /* Includes new state and old state as + payload */ + EVENT_CALL_CONTROL_INSTANTIATED, /* Includes con_ref as payload */ + EVENT_CALL_CONTROL_STATE_CHANGE, /* Includes con_ref, old substate and + new substate as payload */ + EVENT_CALL_CONTROL_TERMINATED, /* Includes con_ref as payload */ + EVENT_REG_ZONE_CHANGE, /* Includes reg_zone as payload */ + EVENT_SLOTTED_MODE_OPERATION, /* Includes enter/exit bit as payload */ + EVENT_QPCH_IN_USE, /* Includes enable/disable bit as payload */ + EVENT_IDLE_HANDOFF, /* Includes pn_offset as payload */ + EVENT_ACCESS_HANDOFF, /* Includes pn_offset as payload */ + EVENT_ACCESS_PROBE_HANDOFF, /* Includes pn_offset as payload */ + EVENT_SOFT_HANDOFF, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_HARD_HANDOFF_FREQ_CHANGE, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_HARD_HANDOFF_FRAME_OFFSET_CHANGE, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_HARD_HANDOFF_DISJOINT_ASET, + /* Includes pn_offsets of each BS in aset and indicators whether BS in SCH + aset*/ + EVENT_UNSUCCESSFUL_HARD_HANDOFF, /* No payload */ + EVENT_TMSI_ASSIGNED, /* Includes TMSI as payload */ + EVENT_SERVICE_NEGOTIATION_COMPLETED,/* No payload */ + EVENT_SO_NEGOTIATION_COMPLETED, /* No payload */ + EVENT_ENTER_CONTROL_HOLD_MODE, /* No payload */ + EVENT_EXIT_CONTROL_HOLD_MODE, /* No payload */ + EVENT_START_FWD_SUPP_BURST_ASSGN, /* Includes SCH rate as payload */ + EVENT_END_FWD_SUPP_BURST_ASSGN, /* No payload */ + EVENT_START_REV_SUPP_BURST_ASSGN, /* Includes SCH rate as payload */ + EVENT_END_REV_SUPP_BURST_ASSGN, /* No payload */ + EVENT_DTX, /* No payload */ + EVENT_T_ADD_ABORT, /* No payload */ + EVENT_CH_IND_CHANGE, /* Include ch_ind as payload */ + EVENT_TRANSMITTER_DISABLED, /* No payload */ + EVENT_TRANSMITTER_ENABLED, /* No payload */ + EVENT_SMS_RECEIVED, /* No payload */ + EVENT_SMS_SENT, /* No payload */ + EVENT_INACTIVITY_TIMER_EXPIRED, /* No payload */ + EVENT_DORMANT_TIMER_EXPIRED, /* No payload */ + EVENT_ACCESS_ATTEMPT_FAIL_MAX_PROBES_SENT, /* No payload */ + EVENT_ACCESS_ATTEMPT_FAIL_LOSS_OF_PC_OR_FCCC, /* No payload */ + EVENT_PCH_ACQUIRED, /* Includes pagech and pn_offset + as payload */ + EVENT_BCCH_ACQUIRED, /* Includes walsh code for BCCH and + pn_offset as payload */ + EVENT_FFCH_ACQUIRED, /* Payload: 14 bytes */ + EVENT_FDCCH_ACQUIRED, /* Payload: 14 bytes */ + EVENT_FFCH_PLUS_DCCH_ACQUIRED, /* No payload */ + EVENT_REGISTRATION_PERFORMED, /* Includes reg_type as payload */ + EVENT_NEW_SYSTEM_IDLE_HANDOFF, /* No payload */ + EVENT_SYSTEM_RESELECTION, /* Includes ecio and ps as payload */ + EVENT_RESCAN, /* No payload */ + EVENT_PROTOCOL_MISMATCH, /* No payload */ + EVENT_LOCK, /* No payload */ + EVENT_UNLOCK, /* No payload */ + EVENT_ACCESS_DENIED, /* No payload */ + EVENT_NDSS_OFF, /* No payload */ + EVENT_RELEASE, /* Payload: 1 byte */ + EVENT_ERROR, /* No payload */ + EVENT_REDIRECTION, /* No payload */ + EVENT_REGISTRATION_REJECTED, /* No payload */ + EVENT_WRONG_SYSTEM, /* No payload */ + EVENT_WRONG_NETWORK, /* No payload */ + EVENT_LOSS_OF_ACQ_AFTER_SLEEP, /* No payload */ + EVENT_POWER_DOWN, /* No payload */ + EVENT_CALL_RELEASE_REQUEST, /* No payload */ + EVENT_SERVICE_INACTIVE, /* No payload */ + EVENT_EXTENDED_RELEASE, /* No payload */ + + EVENT_HDR_MSG_RX, /* protocol, msg- 3 bytes */ + EVENT_HDR_RXMSG_IGNORED_STATE, /* protocol, msg- 3 bytes */ + EVENT_HDR_RXMSG_IGNORED_SEQ, /* protocol, msg- 3 bytes */ + EVENT_HDR_TXMSG_ACKED, /* protocol, msg- 3 bytes */ + EVENT_HDR_TXMSG_DROPPED, /* protocol, msg- 3 bytes */ + EVENT_HDR_STATE_CHANGE, /* protocol, from, to - 5 bytes */ + EVENT_HDR_ALMP_OBEYING_REDIRECTION, /* No payload */ + EVENT_HDR_ALMP_CONNECTION_CLOSED, /* No payload */ + EVENT_HDR_ALMP_T_SD_RESELECT, /* No payload */ + EVENT_HDR_ALMP_CONNECTION_OPENED, /* No payload */ + EVENT_HDR_HMP_QUEUED_MSG, /* protocol, msg- 3 bytes */ + EVENT_HDR_HMP_SENT_MSG, /* protocol, msg, chan, is_reliable - 5 bytes */ + EVENT_HDR_HMP_ABORTING_ACMAC_ACTIVATION, /* No payload */ + EVENT_HDR_IDLE_T_CONFIG_RSP, /* No payload */ + EVENT_HDR_IDLE_T_AT_SETUP, /* No payload */ + EVENT_HDR_IDLE_T_SUSPEND, /* No payload */ + EVENT_HDR_IDLE_CONNECTION_DENIED, /* No payload */ + EVENT_HDR_INIT_T_SYNC_ACQ, /* No payload */ + EVENT_HDR_INIT_PROTOCOL_MISMATCH, /* No payload */ + EVENT_HDR_OVHD_INFO_CURRENT, /* No payload */ + EVENT_HDR_OVHD_T_QC_SUPERVISION, /* No payload */ + EVENT_HDR_OVHD_T_SP_SUPERVISION, /* No payload */ + EVENT_HDR_OVHD_T_AP_SUPERVISION, /* No payload */ + EVENT_HDR_OVHD_IGNORED_MSG_UNEXPECTED_LINK, /* msg, exp_link.chan_num, + exp_link.pilot, rx_link.chan_num, + rx_link.pilot - 10 bytes */ + EVENT_HDR_OVHD_IGNORED_SP_MSG_DIFF_SEC_SIG, /* exp_sig, rx_sig - 8 bytes */ + EVENT_HDR_OVHD_IGNORED_AP_MSG_DIFF_ACC_SIG, /* exp_sig, rx_sig - 8 bytes */ + EVENT_HDR_OVHD_IGNORED_SP_MSG_DIFF_SEC_ID, /* No payload */ + EVENT_HDR_OVHD_SP_MSG_RX, /* No payload */ + EVENT_HDR_OVHD_AP_MSG_RX, /* No payload */ + EVENT_HDR_RUP_T_CONNECTION_SETUP, /* No payload */ + EVENT_HDR_SLP_MAX_RETRIES, /* msg - 2 bytes */ + EVENT_HDR_LMAC_ACQ_FAIL_PILOT, /* No payload */ + EVENT_HDR_LMAC_ACQ_SUCCESS, /* No payload */ + EVENT_HDR_LMAC_NETWORK_LOST, /* No payload */ + EVENT_HDR_LMAC_IDLE_HO, /* new_pilot - 2 bytes */ + EVENT_HDR_LMAC_CHAN_CHANGE_COMPLETE, /* No payload */ + EVENT_HDR_LMAC_ACCESS_HO_NEEDED, /* suggested_pilot - 2 bytes */ + EVENT_HDR_LMAC_ACCESS_HO_COMPLETE, /* new_pilot - 2 bytes */ + EVENT_HDR_LMAC_ACQUIRE, /* channel 2 bytes */ + EVENT_HDR_LMAC_CHANGING_CC_HASH, /* cc_hash - 1 byte */ + EVENT_HDR_LMAC_IDLE_CHAN_CHANGE, /* channel - 2 bytes */ + EVENT_HDR_CMAC_T_SUPERVISION, /* No payload */ + EVENT_HDR_AMAC_START_ACCESS, /* No payload */ + EVENT_HDR_AMAC_PROBING_STOPPED, /* No payload */ + EVENT_HDR_AMAC_ACCESS_COMPLETE, /* No payload */ + EVENT_HDR_AMAC_ACCESS_ABORTED, /* No payload */ + EVENT_HDR_AMAC_MAX_PROBES, /* No payload */ + EVENT_HDR_FMAC_DROP_PKT, /* No payload */ + EVENT_HDR_RMAC_T_RATE_LIMIT, /* No payload */ + EVENT_HDR_RMAC_TX_STARTED, /* No payload */ + EVENT_HDR_RMAC_TX_STOPPED, /* No payload */ + EVENT_HDR_SMP_T_KEEP_ALIVE, /* No payload */ + EVENT_HDR_AMP_ASSIGN_MSG_IGNORED_FRESH, /* No payload */ + EVENT_HDR_AMP_T_AT_RESPONSE, /* No payload */ + EVENT_HDR_AMP_T_DUAL_ADDRESS, /* No payload */ + EVENT_HDR_SCP_BEGIN_CONFIGURATION, /* No payload */ + EVENT_HDR_SCP_T_CONFIG_RSP, /* No payload */ + EVENT_HDR_SCP_T_AN_INIT_STATE, /* No payload */ + + EVENT_WCDMA_L1_STATE, /* l1_state - 1 byte */ + EVENT_WCDMA_IMSI, /* IMSI - 9 bytes */ + EVENT_GSM_L1_STATE, /* GSM l1_state - 1 byte */ + EVENT_RANDOM_ACCESS_REQUEST, /* GSM Random Access Request - 4 bytes */ + EVENT_HIGH_LEVEL_CALL_PROCESSING_STATE_CHANGE, /* Puma requested event */ + /* (same payload as CALL_PROCESSING_STATE_CHANGE) */ + EVENT_ENCRYPTION_FAILURE, /* Puma event, no payload */ + EVENT_ACCT_BLOCKED, /* Puma event, no payload */ + EVENT_COMMON_CHANNEL_MONITORED, /* Puma event, 1 byte payload */ + EVENT_SOFT_HANDOFF_V2, /* Puma event, 14 byte payload */ + EVENT_HARD_HANDOFF_FREQ_CHANGE_V2, /* Puma event, 14 byte payload */ + EVENT_HARD_HANDOFF_FRAME_OFFSET_CHANGE_V2, /* Puma event, 14 byte payload */ + EVENT_HARD_HANDOFF_DISJOINT_ASET_V2, /* Puma event, 14 byte payload */ + EVENT_WCDMA_NEW_REFERENCE_CELL, + EVENT_CALL_CONTROL_CONREF_CHANGE, /* Puma event, 2 byte payload */ + + EVENT_GPS_SESSION_BEGIN, + EVENT_GPS_SESSION_END, + EVENT_GPS_WAITING_ON_SA, + EVENT_GPS_PPM_START, + EVENT_GPS_PPM_RESULTS, + EVENT_GPS_PPM_END, + EVENT_GPS_VISIT_BEGIN, + EVENT_GPS_VISIT_END, + EVENT_GPS_CDMA_RESUMED_AFTER_GPS_VISIT, + EVENT_GPS_PD_SESSION_BEGIN, + EVENT_GPS_PD_SESSION_END, /* Payload: 1 byte PDSM substate */ + EVENT_GPS_IS801_RX, /* Payload, 1 byte msg_type */ + EVENT_GPS_IS801_TX, /* Payload: 1 byte msg_type */ + EVENT_POWERUP, + EVENT_WCDMA_ASET, + EVENT_CM_CALL_STATE, /* (1 byte payload: overall call state) */ + EVENT_CM_OPERATIONAL_MODE, /* (1 byte payload: op mode) */ + EVENT_CM_SYSTEM_MODE, /* (1 byte payload: sys_mode) */ + + EVENT_DEEP_SLEEP, /* no payload */ + EVENT_WAKEUP, /* unsigned long (4 bytes) payload */ + EVENT_ACQUISITION_MODE, /* unsigned char (1 byte) payload */ + EVENT_ACQUISITION_TYPE, /* unsigned char (1 byte) payload */ + EVENT_ACP_EXIT, /* unsigned char (1 byte) payload */ + EVENT_CDMA_EXIT, /* unsigned char (1 byte) payload */ + + EVENT_HDR_HYBRID_POWER_SAVE, /* No payload */ + EVENT_HDR_DEEP_SLEEP, /* No payload */ + EVENT_HDR_RESELECTION, /* No payload */ + EVENT_SAM_LOCK_GRANTED, /* +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT + +void vos_event_report_payload(v_U16_t event_Id, v_U16_t length, v_VOID_t *pPayload); +/*--------------------------------------------------------------------------- + Allocate an event payload holder +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_EVENT_DEF( payload_name, payload_type ) \ + payload_type(payload_name) + +/*--------------------------------------------------------------------------- + Report the event +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_EVENT_REPORT( payload_ptr, ev_id ) \ + do \ + { \ + vos_event_report_payload( ev_id, \ + sizeof( *(payload_ptr) ), \ + (void *)(payload_ptr) ); \ + \ + } while (0) + +#else /* FEATURE_WLAN_DIAG_SUPPORT */ + +#define WLAN_VOS_DIAG_EVENT_DEF( payload_name, payload_type ) +#define WLAN_VOS_DIAG_EVENT_REPORT( payload_ptr, ev_id ) + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void vos_log_wlock_diag(uint32_t reason, const char *wake_lock_name, + uint32_t timeout, uint32_t status); +#else +static inline void vos_log_wlock_diag(uint32_t reason, + const char *wake_lock_name, + uint32_t timeout, uint32_t status) +{ + +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_DIAG_CORE_EVENT_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_diag_core_log.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_diag_core_log.h new file mode 100644 index 000000000000..9851497a373a --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_diag_core_log.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_DIAG_CORE_LOG_H ) +#define __I_VOS_DIAG_CORE_LOG_H + +/**========================================================================= + + \file i_vos_diag_core_event.h + + \brief android-specific definitions for vOSS DIAG logs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +//FIXME To be removed when DIAG support is added. This definiton should be +//picked from log.h file above. +typedef struct +{ + /* Specifies the length, in bytes of the entry, including this header. */ + v_U16_t len; + + /* Specifies the log code for the entry*/ + v_U16_t code; + + /*Time Stamp lo*/ + v_U32_t ts_lo; + + /*Time Stamp hi*/ + v_U32_t ts_hi; +}__packed log_hdr_type; + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void vos_log_set_code (v_VOID_t *ptr, v_U16_t code); +void vos_log_set_length (v_VOID_t *ptr, v_U16_t length); +void vos_log_set_timestamp (v_VOID_t *plog_hdr_ptr); +void vos_log_submit(v_VOID_t *plog_hdr_ptr); + +/*--------------------------------------------------------------------------- + Allocate an event payload holder +---------------------------------------------------------------------------*/ + +#define WLAN_VOS_DIAG_LOG_ALLOC( payload_ptr, payload_type, log_code ) \ + do \ + { \ + payload_ptr = ( payload_type *)vos_mem_malloc(sizeof(payload_type));\ + \ + if( payload_ptr ) \ + { \ + vos_mem_zero(payload_ptr, sizeof(payload_type)); \ + vos_log_set_code(payload_ptr, log_code); \ + vos_log_set_length(payload_ptr, sizeof(payload_type)); \ + } \ + } while (0) + +/*--------------------------------------------------------------------------- + Report the event +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_LOG_REPORT( payload_ptr ) \ + do \ + { \ + if( payload_ptr) \ + { \ + vos_log_submit( payload_ptr); \ + vos_mem_free(payload_ptr); \ + } \ + } while (0) + +/*--------------------------------------------------------------------------- + Free the payload +---------------------------------------------------------------------------*/ +#define WLAN_VOS_DIAG_LOG_FREE( payload_ptr ) \ + do \ + { \ + if( payload_ptr) \ + { \ + vos_mem_free(payload_ptr); \ + } \ + } while (0) + + +#else /* FEATURE_WLAN_DIAG_SUPPORT */ + +#define WLAN_VOS_DIAG_LOG_ALLOC( payload_ptr, payload_type, log_code ) +#define WLAN_VOS_DIAG_LOG_REPORT( payload_ptr ) +#define WLAN_VOS_DIAG_LOG_FREE( payload_ptr ) + +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_DIAG_CORE_LOG_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_event.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_event.h new file mode 100644 index 000000000000..a3f7ac95f4f5 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_event.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_EVENT_H ) +#define __I_VOS_EVENT_H + +/**========================================================================= + + \file i_vos_event.h + + \brief Linux-specific definitions for vOSS Events + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define LINUX_EVENT_COOKIE 0x12341234 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef struct evt +{ + struct completion complete; + v_U32_t cookie; +} vos_event_t; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_EVENT_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_list.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_list.h new file mode 100644 index 000000000000..53b1d4bb15cd --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_list.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_LIST_H ) +#define __I_VOS_LIST_H + +/**========================================================================= + + \file i_vos_list.h + + \brief Linux-specific definitions for vOSS lists + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct vos_linux_list_s +{ + struct list_head anchor; + v_SIZE_t count; + struct mutex lock; + v_U32_t cookie; +} vos_list_t; + +typedef struct list_head vos_list_node_t; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_LIST_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_lock.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_lock.h new file mode 100644 index 000000000000..0a6610318152 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_lock.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_LOCK_H ) +#define __I_VOS_LOCK_H + +/**========================================================================= + + \file i_vos_lock.h + + \brief Linux-specific definitions for vOSS Locks + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#if defined(WLAN_OPEN_SOURCE) +#include +#endif + + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +typedef struct vos_lock_s +{ + struct mutex m_lock; + v_U32_t cookie; + int processID; + v_U32_t state; + v_U8_t refcount; +} vos_lock_t; + +typedef spinlock_t vos_spin_lock_t; + +#if defined(WLAN_OPEN_SOURCE) +typedef struct wake_lock vos_wake_lock_t; +#else +typedef int vos_wake_lock_t; +#endif + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_LOCK_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_packet.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_packet.h new file mode 100644 index 000000000000..f0bc8abb6ee3 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_packet.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_PACKET_H ) +#define __I_VOS_PACKET_H + +/**========================================================================= + + \file i_vos_packet.h + + \brief virtual Operating System Servies (vOSS) + + Network Protocol packet/buffer internal include file + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include + +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +// Definitions for the various VOS packet pools. Following are defines +// for the SIZE and the NUMBER of vos packets in the vos packet pools. +// Note that all of the code is written to allocate and manage the vos +// packet pools based on these #defines only. For example, if you want to +// change the number of RX_RAW packets, simply change the #define that +// defines the number of RX_RAW packets and rebuild VOSS. + +// the number of Receive vos packets used exclusively for vos packet +// allocations of type VOS_PKT_TYPE_RX_RAW +#define VPKT_NUM_RX_RAW_PACKETS (1024) + +// the number of Transmit Management vos packets, used exclusively for +// vos packet allocations of type VOS_PKT_TYPE_TX_802_11_MGMT +#define VPKT_NUM_TX_MGMT_PACKETS ( 6 ) + +// the number of Transmit Data vos packets, used exclusively for +// vos packet allocations of type VOS_PKT_TYPE_TX_802_3_DATA or +// VOS_PKT_TYPE_TX_802_11_DATA +#define VPKT_NUM_TX_DATA_PACKETS ( 128 ) + +// the number of VOS Packets we need. This is the memory we need to +// allocate for the vos Packet structures themselves. We need vos +// packet structures for all of the packet types (RX_RAW, TX_MGMT, and +// TX_DATA). +#define VPKT_NUM_VOS_PKT_BUFFERS \ + ( VPKT_NUM_RX_RAW_PACKETS \ + + VPKT_NUM_TX_MGMT_PACKETS \ + + VPKT_NUM_TX_DATA_PACKETS ) + +// the number of Receive vos packets that we accumulate in the +// replenish pool before we attempt to replenish them +#define VPKT_RX_REPLENISH_THRESHOLD ( VPKT_NUM_RX_RAW_PACKETS >> 2 ) + +// magic number which can be used to verify that a structure pointer being +// dereferenced is really referencing a struct vos_pkt_t +#define VPKT_MAGIC_NUMBER 0x56504B54 /* VPKT in ASCII */ + +// while allocating the skb->data is cache aligned, so the memory allocated +// is more than VPKT_SIZE_BUFFER +#define VPKT_SIZE_BUFFER_ALIGNED SKB_DATA_ALIGN(VPKT_SIZE_BUFFER) +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + + +/// implementation specific vos packet type +struct vos_pkt_t +{ + + //palPacket MUST be the first member of vos_pkt_t + wpt_packet palPacket; + + // Node for linking vos packets into a free list + struct list_head node; + + // Node for chaining vos packets into a packet chain + struct vos_pkt_t *pNext; + + // pointer to an OS specific packet descriptor + struct sk_buff *pSkb; + + // packet type + VOS_PKT_TYPE packetType; + + // timestamp + v_TIME_t timestamp; + + // user data pointers + v_VOID_t *pvUserData[ VOS_PKT_USER_DATA_ID_MAX ]; + + // magic number for verifying this is really a struct vos_pkt_t + v_U32_t magic; +}; + + +// Parameters from the vos_pkt_get_packet() call that needs +// to be saved in 'low resource' conditions. We need all the +// parameters from the original call to vos_pkt_get_packet() +// to resolve the packet request when one become available. +typedef struct +{ + vos_pkt_get_packet_callback callback; + + v_VOID_t *userData; + + v_SIZE_t dataSize; + v_SIZE_t numPackets; + v_BOOL_t zeroBuffer; + +} vos_pkt_low_resource_info; + + + +// vOSS Packet Context - all context / internal data needed for the +// vOSS pPacket module. This consiste of: +// - memory for the vos Packet structures +// - memory for the vos Packet Head / Tail buffers +// - memory for the Rx Raw data buffers +// - memory for the Tx Mgmt data buffers. +typedef struct vos_pkt_context_s +{ + // place to save the vos Context + v_CONTEXT_t vosContext; + + // the memory for the vos Packet structures.... + struct vos_pkt_t vosPktBuffers[ VPKT_NUM_VOS_PKT_BUFFERS ]; + + // These are the lists to keep the constructed VOS packets that are + // available for allocation. There are separate free vos packet + // pools for RX_RAW without attached skb, RX_RAW with attached skb, + // TX_DATA, and TX_MGMT. + struct list_head rxReplenishList; + struct list_head rxRawFreeList; + struct list_head txDataFreeList; + struct list_head txMgmtFreeList; + + //Existing list_size opearation traverse the list. Too slow for data path. + //Add the field to enable faster flow control on tx path + v_U32_t uctxDataFreeListCount; + + // We keep a separate count of the number of RX_RAW packets + // waiting to be replenished + v_SIZE_t rxReplenishListCount; + + // Count for the number of packets that could not be replenished + // because the memory allocation API failed + v_SIZE_t rxReplenishFailCount; + //Existing list_size opearation traverse the list. Too slow for data path. + //Add the field for a faster rx path + v_SIZE_t rxRawFreeListCount; + + // Number of RX Raw packets that will be reserved; this is a configurable + // value to the driver to save the memory usage. + v_SIZE_t numOfRxRawPackets; + + // These are the structs to keep low-resource callback information. + // There are separate low-resource callback information blocks for + // RX_RAW, TX_DATA, and TX_MGMT. + vos_pkt_low_resource_info rxRawLowResourceInfo; + vos_pkt_low_resource_info txDataLowResourceInfo; + vos_pkt_low_resource_info txMgmtLowResourceInfo; + + struct mutex rxReplenishListLock; + struct mutex rxRawFreeListLock; + struct mutex txDataFreeListLock; + struct mutex txMgmtFreeListLock; + + /*Meta Information to be transported with the packet*/ + WDI_DS_TxMetaInfoType txMgmtMetaInfo[VPKT_NUM_TX_MGMT_PACKETS]; + WDI_DS_TxMetaInfoType txDataMetaInfo[VPKT_NUM_TX_DATA_PACKETS]; + WDI_DS_RxMetaInfoType rxMetaInfo[VPKT_NUM_RX_RAW_PACKETS]; + +} vos_pkt_context_t; + + + +/*--------------------------------------------------------------------------- + + \brief vos_packet_open() - initialize the vOSS Packet module + + The \a vos_packet_open() function initializes the vOSS Packet + module. + + \param pVosContext - pointer to the global vOSS Context + + \param pVosPacketContext - pointer to a previously allocated + buffer big enough to hold the vos Packet context. + + \param vosPacketContextSize - the size allocated for the vos + packet context. + + \return VOS_STATUS_SUCCESS - vos Packet module was successfully + initialized and is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the vos Packet module + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the vos packet module + + VOS_STATUS_E_INVAL - Invalid parameter passed to the vos open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the vos packet + module + + \sa vos_packet_close() + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_packet_open( v_VOID_t *pVosContext, + vos_pkt_context_t *pVosPacketContext, + v_SIZE_t vosPacketContextSize ); + + +/*--------------------------------------------------------------------------- + + \brief vos_packet_close() - Close the vOSS Packet module + + The \a vos_packet_close() function closes the vOSS Packet module + Upon successful close all resources allocated from the OS will be + relinquished. + + \param pVosContext - pointer to the global vOSS Context + + \return VOS_STATUS_SUCCESS - Packet module was successfully closed. + + VOS_STATUS_E_INVAL - Invalid parameter passed to the packet + close function + + VOS_STATUS_E_FAILURE - Failure to close the vos Packet module + + \sa vos_packet_open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_packet_close( v_PVOID_t pVosContext ); + +#endif // !defined( __I_VOS_PACKET_H ) diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_timer.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_timer.h new file mode 100644 index 000000000000..e789af45d495 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_timer.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_TIMER_H ) +#define __I_VOS_TIMER_H + +/**========================================================================= + + \file i_vos_timer.h + + \brief Linux-specific definitions for vOSS packets + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef struct vos_timer_platform_s +{ + struct timer_list Timer; + int threadID; + v_U32_t cookie; + spinlock_t spinlock; + +} vos_timer_platform_t; + +/* + * TODOs: Need to add deferred timer implementation + * +*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __I_VOS_TIMER_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_trace.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_trace.h new file mode 100644 index 000000000000..4708a3ed1ad9 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_trace.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_TRACE_H ) +#define __I_VOS_TRACE_H + +#if !defined(__printf) +#define __printf(a,b) +#endif + +/**========================================================================= + + \file i_vos_trace.h + + \brief Linux-specific definitions for VOSS trace + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +/**---------------------------------------------------------------------------- + + \brief VOS_TRACE() / vos_trace_msg() - Trace / logging API + + Users wishing to add tracing information to their code should use + VOS_TRACE. VOS_TRACE() will compile into a call to vos_trace_msg() when + tracing is enabled. + + \param module - module identifier. A member of the VOS_MODULE_ID + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param strFormat - format string. The message to be logged. This format + string contains printf-like replacement parameters, which follow + this parameter in the variable argument list. + + \return nothing + + --------------------------------------------------------------------------*/ +void __printf(3,4) vos_trace_msg( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, + char *strFormat, ... ); + +void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, + void *data, int buf_len ); + +void vos_trace_display(void); + +void vos_trace_setValue( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, v_U8_t on ); + + +// VOS_TRACE is the macro invoked to add trace messages to code. See the +// documenation for vos_trace_msg() for the parameters etc. for this function. +// +// NOTE: Code VOS_TRACE() macros into the source code. Do not code directly +// to the vos_trace_msg() function. +// +// NOTE 2: vos tracing is totally turned off if WLAN_DEBUG is *not* defined. +// This allows us to build 'performance' builds where we can measure performance +// without being bogged down by all the tracing in the code. +#if defined( WLAN_DEBUG ) +#define VOS_TRACE vos_trace_msg +#define VOS_TRACE_HEX_DUMP vos_trace_hex_dump +#else +#define VOS_TRACE(arg...) +#define VOS_TRACE_HEX_DUMP(arg...) +#endif + + +void __printf(3,4) vos_snprintf(char *strBuffer, unsigned int size, + char *strFormat, ...); +#define VOS_SNPRINTF vos_snprintf + +#ifdef VOS_ENABLE_TRACING + + +#define VOS_ASSERT( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS ASSERT in %s Line %d\n", __func__, __LINE__); \ + WARN_ON(1); \ + } \ + } while(0) + +#else + + + // This code will be used for compilation if tracing is to be compiled out + // of the code so these functions/macros are 'do nothing' + VOS_INLINE_FN void vos_trace_msg( VOS_MODULE_ID module, ... ){} + + #define VOS_ASSERT( _condition ) + +#endif + +#ifdef PANIC_ON_BUG + +#define VOS_BUG( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS BUG in %s Line %d\n", __func__, __LINE__); \ + BUG_ON(1); \ + } \ + } while(0) + +#else + +#define VOS_BUG( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS BUG in %s Line %d\n", __func__, __LINE__); \ + WARN_ON(1); \ + } \ + } while(0) + +#endif + +#define VOS_RETURN_ADDRESS __builtin_return_address(0) + +#define VOS_SMP_MB smp_mb() + +#endif diff --git a/drivers/staging/prima/CORE/VOSS/inc/i_vos_types.h b/drivers/staging/prima/CORE/VOSS/inc/i_vos_types.h new file mode 100644 index 000000000000..72c7421a6527 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/i_vos_types.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __I_VOS_TYPES_H ) +#define __I_VOS_TYPES_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**========================================================================= + + \file i_vos_Types.h + + \brief virtual Operating System Servies (vOSS) Types + + Linux specific basic type definitions + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +/* + * 1. GNU C/C++ Compiler + * + * How to detect gcc : __GNUC__ + * How to detect gcc version : + * major version : __GNUC__ (2 = 2.x, 3 = 3.x, 4 = 4.x) + * minor version : __GNUC_MINOR__ + * + * 2. Microsoft C/C++ Compiler + * + * How to detect msc : _MSC_VER + * How to detect msc version : + * _MSC_VER (1200 = MSVC 6.0, 1300 = MSVC 7.0, ...) + * + */ + +// MACROs to help with compiler and OS specifics. +// \note: may need to get a little more sophisticated than this and define +// these to specific 'VERSIONS' of the compiler and OS. Until we have a +// need for that, lets go with this. +#if defined( _MSC_VER ) + +#define VOS_COMPILER_MSC +#define VOS_OS_WINMOBILE // assuming that if we build with MSC, OS is WinMobile + +#elif defined( __GNUC__ ) + +#define VOS_COMPILER_GNUC +#define VOS_OS_LINUX // assuming if building with GNUC, OS is Linux + +#endif + + +// VOS definitions (compiler specific) for Packing structures. Note that the +// Windows compiler defines a way to pack a 'range' of code in a file. To +// accomodate this, we have to include a file that has the packing #pragmas +// These files are called +// vos_pack_range_n_start.h where "n" is the packing aligment. For example, +// vos_pack_range_2_start.h is included in the file where you want to +// start packing on a 2 byte alignment. vos_pack_range_end.h is included +// in the file where you want to stop the packing. +// +// Other compilers allow packing individual strucutres so we have a series +// of macros that are added to the structure to define the packing attributes. +// For example, VOS_PACK_STRUCT_2 will add the attributes to pack an +// individual structure on a 2 byte boundary. +// +// So what does a coder have to do to properly pack a structure for all the +// supported compilers? You have to add two includes around *all* the +// structures you want packed the same way and you also have to add the +// VOS_PACK_STRUCT_n macros to the individual structures. +// +// For example to properly pack myStruct on a 2 byte boundary for all +// voss supported compilers, the following needs coded... +// +// +// #include +// +// typedef struct +// { +// unsigned char c; +// long int i; +// } myStruct VOS_PACK_STRUCT_2; +// +// +// note... you can include other structure definitions in here that have the +// same 2 byte packing +// +// #include + + +// /todo: not sure what the flag is to identify the Microsoft compiler for WinMobile +// Let's leave this out for now and just include the defintions for WinMobile. Need +// to address this when we move to support other operating systems. Probably best to +// define some of our own 'types' or preprocessor flags like VOS_COMPILER_TYPE, +// VOS_OS_TYPE, etc. and then all our code can base on those flags/types independent +// of the operating system, compiler, etc. +#if defined( VOS_COMPILER_MSC ) + + +#define VOS_INLINE_FN __inline + +// does nothing on Windows. packing individual structs is not +// supported on the Windows compiler. +#define VOS_PACK_STRUCT_1 +#define VOS_PACK_STRUCT_2 +#define VOS_PACK_STRUCT_4 +#define VOS_PACK_STRUCT_8 +#define VOS_PACK_STRUCT_16 + +#elif defined( VOS_COMPILER_GNUC ) + +#define VOS_INLINE_FN static inline + +#else +#error "Compiling with an unknown compiler!!" +#endif + + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/// unsigned 8-bit types +typedef u8 v_U8_t; +typedef u8 v_UCHAR_t; +typedef u8 v_BYTE_t; + +/// unsigned 16-bit types +typedef u16 v_U16_t; +typedef unsigned short v_USHORT_t; + +/// unsigned 32-bit types +typedef u32 v_U32_t; +// typedef atomic_t v_U32AT_t; +typedef unsigned long v_ULONG_t; + +/// unsigned 64-bit types +typedef u64 v_U64_t; + +/// unsigned integer types +typedef unsigned int v_UINT_t; + +/// signed 8-bit types +typedef s8 v_S7_t; +typedef signed char v_SCHAR_t; + +/// signed 16-bit types +typedef s16 v_S15_t; +typedef signed short v_SSHORT_t; + +/// signed 32-bit types +typedef s32 v_S31_t; +typedef signed long v_SLONG_t; + +/// signed integer types +typedef signed int v_SINT_t; + +/// Boolean types +typedef unsigned char v_BOOL_t; + +/// void type +#define v_VOID_t void + +#endif // __I_VOSS_TYPES_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/log_codes.h b/drivers/staging/prima/CORE/VOSS/inc/log_codes.h new file mode 100644 index 000000000000..250727dde408 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/log_codes.h @@ -0,0 +1,2084 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef LOG_CODES_H +#define LOG_CODES_H + +/*=========================================================================== + + Log Code Definitions + +General Description + This file contains log code definitions and is shared with the tools. + +Copyright (c) 1991-2010 by QUALCOMM, Inc. All Rights Reserved. +===========================================================================*/ + +/* DO NOT MODIFY THIS FILE WITHOUT PRIOR APPROVAL +** +** Log codes, by design, are a tightly controlled set of values. +** Developers may not create log codes at will. +** +** Request new logs using the following process: +** +** 1. Send email to asw.diag.request requesting log codassignments. +** 2. Identify the log needed by name. +** 3. Provide a brief description for the log. +** +*/ + +/*=========================================================================== + + Edit History + +$Header: //source/qcom/qct/core/services/diag/api/inc/main/latest/log_codes.h#9 $ + +when who what, where, why +-------- --- ---------------------------------------------------------- +07/30/09 dhao Consolidate log_codes_apps.h +07/30/09 dhao Add Last log code definition for Equip ID 11 +06/26/09 dhao Update format the macro +06/24/09 sar Reverted last change. +06/24/09 sar Added log code for LOG_MC_STM_C. +11/02/01 sfh Featurize common NAS log codes for UMTS. +10/30/01 sfh Added log code for LOG_GPS_FATPATH_INFO_C. +10/24/01 sfh Added updates for UMTS equipment ID and log codes. +06/27/01 lad Added multiple equipment ID support. +05/22/01 sfh Reserved log codes 158 - 168. +05/21/01 sfh Keep confusing XXX_BASE_C names for backwards compatibility. +05/16/01 sfh Reserved log code 155. +05/08/01 sfh Reserved log codes 150 - 154. +04/06/01 lad Added definitions of base IDs (such as LOG_WCDMA_BASE_C). + This is currently using temporary ID values in the 0x1000 + range. +02/23/01 lad Created file from DMSS log.h. Log codes only + +===========================================================================*/ +#include + +/* ------------------------------------------------------------------------- + * Data Declarations + * ------------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------------- + * Log equipment IDs. + * The most significant 4 bits of the 16 bit log code is the equipment ID. + * Orignally, the mobile was to have an ID, and base stations and other + * IDs. As QCT technology diversifies, new equipment IDs are assigned to new + * technology areas. 0x2000 and 0x3000 are reserved for legacy reasons, so + * the first + * addition starts at 0x4000. + * ------------------------------------------------------------------------- */ + +#define LOG_1X_BASE_C ((v_U16_t) 0x1000) +#define LOG_WCDMA_BASE_C ((v_U16_t) 0x4000) +#define LOG_GSM_BASE_C ((v_U16_t) 0x5000) +#define LOG_LBS_BASE_C ((v_U16_t) 0x6000) +#define LOG_UMTS_BASE_C ((v_U16_t) 0x7000) +#define LOG_TDMA_BASE_C ((v_U16_t) 0x8000) +#define LOG_DTV_BASE_C ((v_U16_t) 0xA000) +#define LOG_APPS_BASE_C ((v_U16_t) 0xB000) +#define LOG_LTE_BASE_C ((v_U16_t) (0xB000 + 0x0010)) +#define LOG_LTE_LAST_C ((v_U16_t) 0xB1FF) +#define LOG_WIMAX_BASE_C ((v_U16_t) 0xB400) +#define LOG_DSP_BASE_C ((v_U16_t) 0xC000) + +#define LOG_TOOLS_BASE_C ((v_U16_t) 0xF000) + +/* LOG_BASE_C is what was used before expanding the use of the equipment ID. + * TODO: Once all targets are using the "core" diag system, this should be + * ommitted. */ +#define LOG_BASE_C LOG_1X_BASE_C + +/* ------------------------------------------------------------------------- + * Log Codes + * These codes identify the kind of information contained in a log entry. + * They are used in conjunction with the 'code' field of the log entry + * header. The data types associated with each code are defined below. + * ------------------------------------------------------------------------- */ + +/* The upper 4 bits of the 16 bit log entry code specify which type + * of equipment created the log entry. */ + +/* 0 Mobile Station temporal analyzer entry */ +#define LOG_TA_C (0x0 + LOG_1X_BASE_C) + +/* 1 AGC values and closed loop power control entry */ +#define LOG_AGC_PCTL_C (0x1 + LOG_1X_BASE_C) + +/* 2 Forward link frame rates and types entry */ +#define LOG_F_MUX1_C (0x2 + LOG_1X_BASE_C) + +/* 3 Reverse link frame rates and types entry */ +#define LOG_R_MUX1_C (0x3 + LOG_1X_BASE_C) + +/* 4 Access channel message entry */ +#define LOG_AC_MSG_C (0x4 + LOG_1X_BASE_C) + +/* 5 Reverse link traffic channel message entry */ +#define LOG_R_TC_MSG_C (0x5 + LOG_1X_BASE_C) + +/* 6 Sync channel message entry */ +#define LOG_SC_MSG_C (0x6 + LOG_1X_BASE_C) + +/* 7 Paging channel message entry */ +#define LOG_PC_MSG_C (0x7 + LOG_1X_BASE_C) + +/* 8 Forward link traffic channel message entry */ +#define LOG_F_TC_MSG_C (0x8 + LOG_1X_BASE_C) + +/* 9 Forward link vocoder packet entry */ +#define LOG_VOC_FOR_C (0x9 + LOG_1X_BASE_C) + +/* 10 Reverse link vocoder packet entry */ +#define LOG_VOC_REV_C (0xA + LOG_1X_BASE_C) + +/* 11 Temporal analyzer finger info only */ +#define LOG_FING_C (0xB + LOG_1X_BASE_C) + +/* 12 Searcher pathlog info (Reused old SRCH logtype) */ +#define LOG_SRCH_C (0xC + LOG_1X_BASE_C) + +/* 13 Position and speed information read from ETAK */ +#define LOG_ETAK_C (0xD + LOG_1X_BASE_C) + +/* 14 Markov frame statistics */ +#define LOG_MAR_C (0xE + LOG_1X_BASE_C) + +/* 15 New and improved temporal analyzer searcher info */ +#define LOG_SRCH2_C (0xF + LOG_1X_BASE_C) + +/* 16 The Fujitsu handset information */ +#define LOG_HANDSET_C (0x10 + LOG_1X_BASE_C) + +/* 17 Vocoder bit error rate mask */ +#define LOG_ERRMASK_C (0x11 + LOG_1X_BASE_C) + +/* 18 Analog voice channel information */ +#define LOG_ANALOG_INFO_C (0x12 + LOG_1X_BASE_C) + +/* 19 Access probe information */ +#define LOG_ACC_INFO_C (0x13 + LOG_1X_BASE_C) + +/* 20 Position & speed info read from GPS receiver */ +#define LOG_GPS_C (0x14 + LOG_1X_BASE_C) + +/* 21 Test Command information */ +#define LOG_TEST_CMD_C (0x15 + LOG_1X_BASE_C) + +/* 22 Sparse (20ms) AGC / closed loop power control entry */ +#define LOG_S_AGC_PCTL_C (0x16 + LOG_1X_BASE_C) + +/* 23 Notification of a band class change */ +#define LOG_BAND_CHANGE_C (0x17 + LOG_1X_BASE_C) + +/* 24 DM debug messages, if being logged via log services */ +#define LOG_DBG_MSG_C (0x18 + LOG_1X_BASE_C) + +/* 25 General temporal analyzer entry */ +#define LOG_GENRL_TA_C (0x19 + LOG_1X_BASE_C) + +/* 26 General temporal analyzer w/supplemental channels */ +#define LOG_GENRL_TA_SUP_CH_C (0x1A + LOG_1X_BASE_C) + +/* Featurization Removal requested by CMI +#ifdef FEATURE_PLT +*/ + +/* 27 Decoder raw bits logging */ +#define LOG_PLT_C (0x1B + LOG_1X_BASE_C) + +/* Featurization Removal requested by CMI +#else +27 EFS Usage Info - No implementation as yet +#define LOG_EFS_INFO_C (0x1B + LOG_1X_BASE_C) +#endif +*/ + +/* 28 Analog Forward Channel */ +#define LOG_ANALOG_FORW_C (0x1C + LOG_1X_BASE_C) + +/* 29 Analog Reverse Channel */ +#define LOG_ANALOG_REVS_C (0x1D + LOG_1X_BASE_C) + +/* 30 Analog Handoff Entry */ +#define LOG_ANALOG_HANDOFF_C (0x1E + LOG_1X_BASE_C) + +/* 31 FM Slot Statistis entry */ +#define LOG_ANALOG_FMSLOT_C (0x1F + LOG_1X_BASE_C) + +/* 32 FOCC Word Sync Count entry */ +#define LOG_ANALOG_WS_COUNT_C (0x20 + LOG_1X_BASE_C) + +/* 33 */ +#define LOG_RLP_PACKET_C (0x21 + LOG_1X_BASE_C) + +/* 34 */ +#define LOG_ASYNC_TCP_SEG_C (0x22 + LOG_1X_BASE_C) + +/* 35 */ +#define LOG_PACKET_DATA_IP_PACKETS_C (0x23 + LOG_1X_BASE_C) + +/* 36 */ +#define LOG_FNBDT_MESSAGE_LOG_C (0x24 + LOG_1X_BASE_C) + +/* Begin IS-2000 LOG features */ + +/* 37 RLP RX Frames logging */ +#define LOG_RLP_RX_FRAMES_C (0x25 + LOG_1X_BASE_C) + +/* 38 RLP TX Frames logging */ +#define LOG_RLP_TX_FRAMES_C (0x26 + LOG_1X_BASE_C) + +/* 39 Reserved for additions to RLP frames */ +#define LOG_RLP_RSVD1_C (0x27 + LOG_1X_BASE_C) + +/* 40 Reserved for additions to RLP frames */ +#define LOG_RLP_RSVD2_C (0x28 + LOG_1X_BASE_C) + +/* 41 Forward Link Frame Types logging */ +#define LOG_FWD_FRAME_TYPES_C (0x29 + LOG_1X_BASE_C) + +/* 42 Reverse Link Frame Types logging */ +#define LOG_REV_FRAME_TYPES_C (0x2A + LOG_1X_BASE_C) + +/* 43 Fast Forward Power Control Parameters logging */ +#define LOG_FFWD_PCTRL_C (0x2B + LOG_1X_BASE_C) + +/* 44 Reverse Power Control Parameters logging */ +#define LOG_REV_PCTRL_C (0x2C + LOG_1X_BASE_C) + +/* 45 Searcher and Finger Information logging */ +#define LOG_SRCH_FING_INFO_C (0x2D + LOG_1X_BASE_C) + +/* 46 Service Configuration logging */ +#define LOG_SVC_CONFIG_C (0x2E + LOG_1X_BASE_C) + +/* 47 Active Set Configuration logging */ +#define LOG_ASET_CONFIG_C (0x2F + LOG_1X_BASE_C) + +/* 48 Quick Paging Channel logging */ +#define LOG_QPCH_C (0x30 + LOG_1X_BASE_C) + +/* 49 RLP Statistics logging */ +#define LOG_RLP_STAT_C (0x31 + LOG_1X_BASE_C) + +/* 50 Simple Test Data Service Option logging */ +#define LOG_STDSO_C (0x32 + LOG_1X_BASE_C) + +/* 51 Pilot Phase Measurement results logging */ +#define LOG_SRCH_PPM_RES_C (0x33 + LOG_1X_BASE_C) + +/* 52 Pilot Phase Measurement Data Base logging */ +#define LOG_SRCH_PPM_DB_C (0x34 + LOG_1X_BASE_C) + +/* 53 Pilot Phase Measurement search results logging */ +#define LOG_SRCH_PPM_C (0x35 + LOG_1X_BASE_C) + +/* 54 IS-801 forward link message */ +#define LOG_GPS_FWD_MSG_C (0x36 + LOG_1X_BASE_C) + +/* 55 IS-801 reverse link message */ +#define LOG_GPS_REV_MSG_C (0x37 + LOG_1X_BASE_C) + +/* 56 GPS search session statistics */ +#define LOG_GPS_STATS_MSG_C (0x38 + LOG_1X_BASE_C) + +/* 57 GPS search results */ +#define LOG_GPS_SRCH_PEAKS_MSG_C (0x39 + LOG_1X_BASE_C) + +/* 58 Factory Testmode logging */ +#define LOG_FTM_C (0x3A + LOG_1X_BASE_C) + +/* 59 Multiple Peak Logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_INFO_C (0x3B + LOG_1X_BASE_C) + +/* 60 Post processed search results logs */ +#define LOG_SRCH_GPS_POST_PROC_C (0x3C + LOG_1X_BASE_C) + +/* 61 FULL Test Data Service Option logging */ +#define LOG_FTDSO_C (0x3D + LOG_1X_BASE_C) + +/* 62 Bluetooth logging */ +#define LOG_BT_RESERVED_CODES_BASE_C (0x3E + LOG_1X_BASE_C) +/* Keep confusing name for backwards compatibility. */ +#define LOG_BT_BASE_C LOG_BT_RESERVED_CODES_BASE_C + +/* 92 Bluetooth's last log code */ +#define LOG_BT_LAST_C (30 + LOG_BT_RESERVED_CODES_BASE_C) + +/* 93 HDR log codes */ +#define LOG_HDR_RESERVED_CODES_BASE_C (0x5D + LOG_1X_BASE_C) +/* Keep confusing name for backwards compatibility. */ +#define LOG_HDR_BASE_C LOG_HDR_RESERVED_CODES_BASE_C + +/* 143 is HDR's last log code */ +#define LOG_HDR_LAST_C (50 + LOG_HDR_RESERVED_CODES_BASE_C) + +/* 144 IS2000 DCCH Forward link channel */ +#define LOG_FOR_DCCH_MSG_C (0x90 + LOG_1X_BASE_C) +#define LOG_DCCH_FWD_C LOG_FOR_DCCH_MSG_C + +/* 145 IS2000 DCCH Forward link channel */ +#define LOG_REV_DCCH_MSG_C (0x91 + LOG_1X_BASE_C) +#define LOG_DCCH_REV_C LOG_REV_DCCH_MSG_C + +/* 146 IS2000 DCCH Forward link channel */ +#define LOG_ZREX_C (0x92 + LOG_1X_BASE_C) + +/* 147 Active set info logging, similar to ASET_CONFIG, but simpler. */ +#define LOG_ASET_INFO_C (0x93 + LOG_1X_BASE_C) + +/* 148 Pilot Phase Measurement four-shoulder-search resutlts logging */ +#define LOG_SRCH_PPM_4SHOULDER_RES_C (0x94 + LOG_1X_BASE_C) + +/* 149 Extended Pilot Phase Measurement Data Base logging */ +#define LOG_SRCH_EXT_PPM_DB_C (0x95 + LOG_1X_BASE_C) + +/* 150 GPS Visit Parameters */ +#define LOG_GPS_VISIT_PARAMETERS_C (0x96 + LOG_1X_BASE_C) + +/* 151 GPS Measurement */ +#define LOG_GPS_MEASUREMENT_C (0x97 + LOG_1X_BASE_C) + +/* 152 UIM Data */ +#define LOG_UIM_DATA_C (0x98 + LOG_1X_BASE_C) + +/* 153 STDSO plus P2 */ +#define LOG_STDSO_P2_C (0x99 + LOG_1X_BASE_C) + +/* 154 FTDSO plus P2 */ +#define LOG_FTDSO_P2_C (0x9A + LOG_1X_BASE_C) + +/* 155 Search PPM Statistics */ +#define LOG_SRCH_PPM_STATS_C (0x9B + LOG_1X_BASE_C) + +/* 156 PPP Tx Frames */ +#define LOG_PPP_TX_FRAMES_C (0x9C + LOG_1X_BASE_C) + +/* 157 PPP Rx Frames */ +#define LOG_PPP_RX_FRAMES_C (0x9D + LOG_1X_BASE_C) + +/* 158-187 SSL reserved log codes */ +#define LOG_SSL_RESERVED_CODES_BASE_C (0x9E + LOG_1X_BASE_C) +#define LOG_SSL_LAST_C (29 + LOG_SSL_RESERVED_CODES_BASE_C) + +/* 188-199 Puma reserved log codes */ +/* 188 QPCH, version 2 */ +#define LOG_QPCH_VER_2_C (0xBC + LOG_1X_BASE_C) + +/* 189 Enhanced Access Probe */ +#define LOG_EA_PROBE_C (0xBD + LOG_1X_BASE_C) + +/* 190 BCCH Frame Information */ +#define LOG_BCCH_FRAME_INFO_C (0xBE + LOG_1X_BASE_C) + +/* 191 FCCCH Frame Information */ +#define LOG_FCCCH_FRAME_INFO_C (0xBF + LOG_1X_BASE_C) + +/* 192 FDCH Frame Information */ +#define LOG_FDCH_FRAME_INFO_C (0xC0 + LOG_1X_BASE_C) + +/* 193 RDCH Frame Information */ +#define LOG_RDCH_FRAME_INFO_C (0xC1 + LOG_1X_BASE_C) + +/* 194 FFPC Information */ +#define LOG_FFPC_INFO_C (0xC2 + LOG_1X_BASE_C) + +/* 195 RPC Information */ +#define LOG_RPC_INFO_C (0xC3 + LOG_1X_BASE_C) + +/* 196 Searcher and Finger Information */ +#define LOG_SRCH_FING_INFO_VER_2_C (0xC4 + LOG_1X_BASE_C) + +/* 197 Service Configuration, version 2 */ +#define LOG_SRV_CONFIG_VER_2_C (0xC5 + LOG_1X_BASE_C) + +/* 198 Active Set Information, version 2 */ +#define LOG_ASET_INFO_VER_2_C (0xC6 + LOG_1X_BASE_C) + +/* 199 Reduced Active Set */ +#define LOG_REDUCED_ASET_INFO_C (0xC7 + LOG_1X_BASE_C) + +/* 200 Search Triage Info */ +#define LOG_SRCH_TRIAGE_INFO_C (0xC8 + LOG_1X_BASE_C) + +/* 201 RDA Frame Information */ +#define LOG_RDA_FRAME_INFO_C (0xC9 + LOG_1X_BASE_C) + +/* 202 gpsOne fatpath information */ +#define LOG_GPS_FATPATH_INFO_C (0xCA + LOG_1X_BASE_C) + +/* 203 Extended AGC */ +#define LOG_EXTENDED_AGC_C (0xCB + LOG_1X_BASE_C) + +/* 204 Transmit AGC */ +#define LOG_TRANSMIT_AGC_C (0xCC + LOG_1X_BASE_C) + +/* 205 I/Q Offset registers */ +#define LOG_IQ_OFFSET_REGISTERS_C (0xCD + LOG_1X_BASE_C) + +/* 206 DACC I/Q Accumulator registers */ +#define LOG_DACC_IQ_ACCUMULATOR_C (0xCE + LOG_1X_BASE_C) + +/* 207 Register polling results */ +#define LOG_REGISTER_POLLING_RESULTS_C (0xCF + LOG_1X_BASE_C) + +/* 208 System arbitration module */ +#define LOG_AT_SAM_C (0xD0 + LOG_1X_BASE_C) + +/* 209 Diablo searcher finger log */ +#define LOG_DIABLO_SRCH_FING_INFO_C (0xD1 + LOG_1X_BASE_C) + +/* 210 log reserved for dandrus */ +#define LOG_SD20_LAST_ACTION_C (0xD2 + LOG_1X_BASE_C) + +/* 211 log reserved for dandrus */ +#define LOG_SD20_LAST_ACTION_HYBRID_C (0xD3 + LOG_1X_BASE_C) + +/* 212 log reserved for dandrus */ +#define LOG_SD20_SS_OBJECT_C (0xD4 + LOG_1X_BASE_C) + +/* 213 log reserved for dandrus */ +#define LOG_SD20_SS_OBJECT_HYBRID_C (0xD5 + LOG_1X_BASE_C) + +/* 214 log reserved for jpinos */ +#define LOG_BCCH_SIGNALING_C (0xD6 + LOG_1X_BASE_C) + +/* 215 log reserved for jpinos */ +#define LOG_REACH_SIGNALING_C (0xD7 + LOG_1X_BASE_C) + +/* 216 log reserved for jpinos */ +#define LOG_FCCCH_SIGNALING_C (0xD8 + LOG_1X_BASE_C) + +/* 217 RDA Frame Information 2 */ +#define LOG_RDA_FRAME_INFO_2_C (0xD9 + LOG_1X_BASE_C) + +/* 218 */ +#define LOG_GPS_BIT_EDGE_RESULTS_C (0xDA + LOG_1X_BASE_C) + +/* 219 */ +#define LOG_PE_DATA_C (0xDB + LOG_1X_BASE_C) + +/* 220 */ +#define LOG_PE_PARTIAL_DATA_C (0xDC + LOG_1X_BASE_C) + +/* 221 */ +#define LOG_GPS_SINGLE_PEAK_SRCH_RESULTS_C (0xDD + LOG_1X_BASE_C) + +/* 222 */ +#define LOG_SRCH4_SAMPRAM_C (0xDE + LOG_1X_BASE_C) + +/* 223 */ +#define HDR_AN_PPP_TX_FRAMES (0xDF + LOG_1X_BASE_C) + +/* 224 */ +#define HDR_AN_PPP_RX_FRAMES (0xE0 + LOG_1X_BASE_C) + +/* 225 */ +#define LOG_GPS_SCHEDULER_TRACE_C (0xE1 + LOG_1X_BASE_C) + +/* 226 */ +#define LOG_MPEG4_YUV_FRAME_C (0xE2 + LOG_1X_BASE_C) + +/* 227 */ +#define LOG_MPEG4_CLIP_STATS_C (0xE3 + LOG_1X_BASE_C) + +/* 228 */ +#define LOG_MPEG4_CLIP_STATS_VER2_C (0xE4 + LOG_1X_BASE_C) + +/* 226-241 MMEG reserved. */ +#define LOG_MPEG_RESERVED_CODES_BASE_C (0xF1 + LOG_1X_BASE_C) + +/* 242-274 BREW reserved log range */ +#define LOG_BREW_RESERVED_CODES_BASE_C (0xF2 + LOG_1X_BASE_C) +#define LOG_BREW_LAST_C (32 + LOG_BREW_RESERVED_CODES_BASE_C) + +/* 275-339 PPP Extended Frames */ +#define LOG_PPP_FRAMES_RESERVED_CODES_BASE_C (0x113 + LOG_1X_BASE_C) +#define LOG_PPP_FRAMES_LAST_C (64 + LOG_PPP_FRAMES_RESERVED_CODES_BASE_C) + +#define LOG_PPP_EXT_FRAMED_RX_UM_C (0x113 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_RX_RM_C (0x114 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_RX_AN_C (0x115 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_FRAMED_TX_UM_C (0x123 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_TX_RM_C (0x124 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_FRAMED_TX_AN_C (0x125 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_UNFRAMED_RX_UM_C (0x133 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_RX_RM_C (0x134 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_RX_AN_C (0x135 + LOG_1X_BASE_C) + +#define LOG_PPP_EXT_UNFRAMED_TX_UM_C (0x143 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_TX_RM_C (0x144 + LOG_1X_BASE_C) +#define LOG_PPP_EXT_UNFRAMED_TX_AN_C (0x145 + LOG_1X_BASE_C) + +/* 340 LOG_PE_DATA_EXT_C */ +#define LOG_PE_DATA_EXT_C (0x154 + LOG_1X_BASE_C) + +/* REX Subsystem logs */ +#define LOG_MEMDEBUG_C (0x155 + LOG_1X_BASE_C) +#define LOG_SYSPROFILE_C (0x156 + LOG_1X_BASE_C) +#define LOG_TASKPROFILE_C (0x157 + LOG_1X_BASE_C) +#define LOG_COREDUMP_C (0x158 + LOG_1X_BASE_C) + +/* 341-349 REX subsystem logs */ +#define LOG_REX_RESERVED_CODES_BASE_C (0x155 + LOG_1X_BASE_C) +#define LOG_REX_LAST_C (8 + LOG_REX_RESERVED_CODES_BASE_C) + +/* 350 LOG_PE_PARTIAL_DATA_EXT_C */ +#define LOG_PE_PARTIAL_DATA_EXT_C (0x15E + LOG_1X_BASE_C) + +/* 351 LOG_DIAG_STRESS_TEST_C */ +#define LOG_DIAG_STRESS_TEST_C (0x15F + LOG_1X_BASE_C) + +/* 352 LOG_WMS_READ_C */ +#define LOG_WMS_READ_C (0x160 + LOG_1X_BASE_C) + +/* 353 Search Triage Info Version 2 */ +#define LOG_SRCH_TRIAGE_INFO2_C (0x161 + LOG_1X_BASE_C) + +/* 354 RLP Rx FDCH Frames */ +#define LOG_RLP_RX_FDCH_FRAMES_C (0x162 + LOG_1X_BASE_C) + + +/* 355 RLP Tx FDCH Frames */ +#define LOG_RLP_TX_FDCH_FRAMES_C (0x163 + LOG_1X_BASE_C) + +/* 356-371 QTV subsystem logs */ +#define LOG_QTV_RESERVED_CODES_BASE_C (0x164 + LOG_1X_BASE_C) +#define LOG_QTV_LAST_C (15 + LOG_QTV_RESERVED_CODES_BASE_C) + +/* 372 Searcher 4 1X */ +#define LOG_SRCH4_1X_C (0x174 + LOG_1X_BASE_C) + +/* 373 Searcher sleep statistics */ +#define LOG_SRCH_SLEEP_STATS_C (0x175 + LOG_1X_BASE_C) + +/* 374 Service Configuration, version 3 */ +#define LOG_SRV_CONFIG_VER_3_C (0x176 + LOG_1X_BASE_C) + +/* 375 Searcher 4 HDR */ +#define LOG_SRCH4_HDR_C (0x177 + LOG_1X_BASE_C) + +/* 376 Searcher 4 AFLT */ +#define LOG_SRCH4_AFLT_C (0x178 + LOG_1X_BASE_C) + +/* 377 Enhanced Finger Information */ +#define LOG_ENH_FING_INFO_C (0x179 + LOG_1X_BASE_C) + +/* 378 DV Information */ +#define LOG_DV_INFO_C (0x17A + LOG_1X_BASE_C) + +/* 379 WMS set routes information */ +#define LOG_WMS_SET_ROUTES_C (0x17B + LOG_1X_BASE_C) + +/* 380 FTM Version 2 Logs */ +#define LOG_FTM_VER_2_C (0x17C + LOG_1X_BASE_C) + +/* 381 GPS Multipeak logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_SIMPLIFIED_INFO_C (0x17D + LOG_1X_BASE_C) + +/* 382 GPS Multipeak logging */ +#define LOG_SRCH_GPS_MULTI_PEAKS_VERBOSE_INFO_C (0x17E + LOG_1X_BASE_C) + +/* 383-403 HDR reserved logs */ +#define LOG_HDR_RESERVED_CODES_BASE_2_C (0x17F + LOG_1X_BASE_C) +#define LOG_HDR_LAST_2_C (20 + LOG_HDR_RESERVED_CODES_BASE_2_C) + +/* RLP Rx - PDCH partial MuxPDU5 frames */ +#define LOG_RLP_RX_PDCH_PARTIAL_MUXPDU5_FRAMES_C (0x194 + LOG_1X_BASE_C) + +/* RLP Tx - PDCH partial MuxPDU5 frames */ +#define LOG_RLP_TX_PDCH_PARTIAL_MUXPDU5_FRAMES_C (0x195 + LOG_1X_BASE_C) + +/* RLP Rx internal details */ +#define LOG_RLP_RX_INTERNAL_DETAILS_C (0x196 + LOG_1X_BASE_C) + +/* RLP Tx internal details */ +#define LOG_RLP_TX_INTERNAL_DETAILS_C (0x197 + LOG_1X_BASE_C) + +/* MPEG4 Clip Statistics version 3 */ +#define LOG_MPEG4_CLIP_STATS_VER3_C (0x198 + LOG_1X_BASE_C) + +/* Mobile IP Performance */ +#define LOG_MOBILE_IP_PERFORMANCE_C (0x199 + LOG_1X_BASE_C) + +/* 410-430 Searcher reserved logs */ +#define LOG_SEARCHER_RESERVED_CODES_BASE_C (0x19A + LOG_1X_BASE_C) +#define LOG_SEARCHER_LAST_2_C (21 + LOG_SEARCHER_RESERVED_CODES_BASE_C) + +/* 432-480 QTV reserved logs */ +#define LOG_QTV2_RESERVED_CODES_BASE_C (0x1B0 + LOG_1X_BASE_C) +#define LOG_QTV2_LAST_C (48 + LOG_QTV2_RESERVED_CODES_BASE_C) + +#define LOG_QTV_PDS2_STATS (0x1B6 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_REQUEST (0x1B7 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_RESP_HEADER (0x1B8 + LOG_1X_BASE_C) +#define LOG_QTV_PDS2_GET_RESP_PCKT (0x1B9 + LOG_1X_BASE_C) +#define LOG_QTV_CMX_AUDIO_INPUT_DATA_C (0x1BA + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_OPTIONS_C (0x1BB + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_GET_PARAMETER_C (0x1BC + LOG_1X_BASE_C) +#define LOG_QTV_RTSP_SET_PARAMETER_C (0x1BD + LOG_1X_BASE_C) +#define LOG_QTV_VIDEO_BITSTREAM (0x1BE + LOG_1X_BASE_C) +#define LOG_ARM_VIDEO_DECODE_STATS (0x1BF + LOG_1X_BASE_C) +#define LOG_QTV_DSP_SLICE_BUFFER_C (0x1C0 + LOG_1X_BASE_C) +#define LOG_QTV_CMD_LOGGING_C (0x1C1 + LOG_1X_BASE_C) +#define LOG_QTV_AUDIO_FRAME_PTS_INFO_C (0x1C2 + LOG_1X_BASE_C) +#define LOG_QTV_VIDEO_FRAME_DECODE_INFO_C (0x1C3 + LOG_1X_BASE_C) +#define LOG_QTV_RTCP_COMPOUND_RR_C (0x1C4 + LOG_1X_BASE_C) +#define LOG_QTV_FRAME_BUFFER_RELEASE_REASON_C (0x1C5 + LOG_1X_BASE_C) +#define LOG_QTV_AUDIO_CHANNEL_SWITCH_FRAME_C (0x1C6 + LOG_1X_BASE_C) +#define LOG_QTV_RTP_DECRYPTED_PKT_C (0x1C7 + LOG_1X_BASE_C) +#define LOG_QTV_PCR_DRIFT_RATE_C (0x1C8 + LOG_1X_BASE_C) + +/* GPS PDSM logs */ +#define LOG_PDSM_POSITION_REPORT_CALLBACK_C (0x1E1 + LOG_1X_BASE_C) +#define LOG_PDSM_PD_EVENT_CALLBACK_C (0x1E2 + LOG_1X_BASE_C) +#define LOG_PDSM_PA_EVENT_CALLBACK_C (0x1E3 + LOG_1X_BASE_C) +#define LOG_PDSM_NOTIFY_VERIFY_REQUEST_C (0x1E4 + LOG_1X_BASE_C) +#define LOG_PDSM_RESERVED1_C (0x1E5 + LOG_1X_BASE_C) +#define LOG_PDSM_RESERVED2_C (0x1E6 + LOG_1X_BASE_C) + +/* Searcher Demodulation Status log */ +#define LOG_SRCH_DEMOD_STATUS_C (0x1E7 + LOG_1X_BASE_C) + +/* Searcher Call Statistics log */ +#define LOG_SRCH_CALL_STATISTICS_C (0x1E8 + LOG_1X_BASE_C) + +/* GPS MS-MPC Forward link */ +#define LOG_MS_MPC_FWD_LINK_C (0x1E9 + LOG_1X_BASE_C) + +/* GPS MS-MPC Reverse link */ +#define LOG_MS_MPC_REV_LINK_C (0x1EA + LOG_1X_BASE_C) + +/* Protocol Services Data */ +#define LOG_DATA_PROTOCOL_LOGGING_C (0x1EB + LOG_1X_BASE_C) + +/* MediaFLO reserved log codes */ +#define LOG_MFLO_RESERVED_CODES_BASE_C (0x1EC + LOG_1X_BASE_C) +#define LOG_MFLO_LAST_C (99 + LOG_MFLO_RESERVED_CODES_BASE_C) + +/* GPS demodulation tracking header info */ +#define LOG_GPS_DEMOD_TRACKING_HEADER_C (0x250 + LOG_1X_BASE_C) + +/* GPS demodulation tracking results */ +#define LOG_GPS_DEMOD_TRACKING_C (0x251 + LOG_1X_BASE_C) + +/* GPS bit edge logs from demod tracking */ +#define LOG_GPS_DEMOD_BIT_EDGE_C (0x252 + LOG_1X_BASE_C) + +/* GPS demodulation soft decisions */ +#define LOG_GPS_DEMOD_SOFT_DECISIONS_C (0x253 + LOG_1X_BASE_C) + +/* GPS post-processed demod tracking results */ +#define LOG_GPS_DEMOD_TRACKING_POST_PROC_C (0x254 + LOG_1X_BASE_C) + +/* GPS subframe log */ +#define LOG_GPS_DEMOD_SUBFRAME_C (0x255 + LOG_1X_BASE_C) + +/* F-CPCCH Quality Information */ +#define LOG_F_CPCCH_QUALITY_INFO_C (0x256 + LOG_1X_BASE_C) + +/* Reverse PDCCH/PDCH Frame Information */ +#define LOG_R_PDCCH_R_PDCH_FRAME_INFO_C (0x257 + LOG_1X_BASE_C) + +/* Forward G Channel Information */ +#define LOG_F_GCH_INFO_C (0x258 + LOG_1X_BASE_C) + +/* Forward G Channel Frame Information */ +#define LOG_F_GCH_FRAME_INFO_C (0x259 + LOG_1X_BASE_C) + +/* Forward RC Channel Information */ +#define LOG_F_RCCH_INFO_C (0x25A + LOG_1X_BASE_C) + +/* Forward ACK Channel Information */ +#define LOG_F_ACKCH_INFO_C (0x25B + LOG_1X_BASE_C) + +/* Forward ACK Channel ACKDA Information */ +#define LOG_F_ACKCH_ACKDA_C (0x25C + LOG_1X_BASE_C) + +/* Reverse REQ Channel Information */ +#define LOG_R_REQCH_INFO_C (0x25D + LOG_1X_BASE_C) + +/* Sleep Task Statistics */ +#define LOG_SLEEP_STATS_C (0x25E + LOG_1X_BASE_C) + +/* Sleep controller statistics 1X */ +#define LOG_1X_SLEEP_CONTROLLER_STATS_C (0x25F + LOG_1X_BASE_C) + +/* Sleep controller statistics HDR */ +#define LOG_HDR_SLEEP_CONTROLLER_STATS_C (0x260 + LOG_1X_BASE_C) + +/* Sleep controller statistics GSM */ +#define LOG_GSM_SLEEP_CONTROLLER_STATS_C (0x261 + LOG_1X_BASE_C) + +/* Sleep controller statistics WCDMA */ +#define LOG_WCDMA_SLEEP_CONTROLLER_STATS_C (0x262 + LOG_1X_BASE_C) + +/* Sleep task and controller reserved logs */ +#define LOG_SLEEP_APPS_STATS_C (0x263 + LOG_1X_BASE_C) +#define LOG_SLEEP_STATS_RESERVED2_C (0x264 + LOG_1X_BASE_C) +#define LOG_SLEEP_STATS_RESERVED3_C (0x265 + LOG_1X_BASE_C) + +/* DV Information placeholder channel logs */ +#define LOG_PDCCH_LO_SELECTED_C (0x266 + LOG_1X_BASE_C) +#define LOG_PDCCH_HI_SELECTED_C (0x267 + LOG_1X_BASE_C) +#define LOG_WALSH_SELECTED_C (0x268 + LOG_1X_BASE_C) +#define LOG_PDCH_BE_SELECTED_C (0x269 + LOG_1X_BASE_C) +#define LOG_PDCCH_LLR_SELECTED_C (0x26A + LOG_1X_BASE_C) +#define LOG_CQI_ACK_LO_SELECTED_C (0x26B + LOG_1X_BASE_C) +#define LOG_CQI_ACK_HI_SELECTED_C (0x26C + LOG_1X_BASE_C) +#define LOG_RL_GAIN_SELECTED_C (0x26D + LOG_1X_BASE_C) +#define LOG_PDCCH0_SNDA_SELECTED_C (0x26E + LOG_1X_BASE_C) +#define LOG_PDCCH1_SNDA_SELECTED_C (0x26F + LOG_1X_BASE_C) + +/* 624 WMS Message List */ +#define LOG_WMS_MESSAGE_LIST_C (0x270 + LOG_1X_BASE_C) + +/* 625 Multimode Generic SIM Driver Interface */ +#define LOG_MM_GENERIC_SIM_DRIVER_C (0x271 + LOG_1X_BASE_C) + +/* 626 Generic SIM Toolkit Task */ +#define LOG_GENERIC_SIM_TOOLKIT_TASK_C (0x272 + LOG_1X_BASE_C) + +/* 627 Call Manager Phone events log */ +#define LOG_CM_PH_EVENT_C (0x273 + LOG_1X_BASE_C) + +/* 628 WMS Set Message List */ +#define LOG_WMS_SET_MESSAGE_LIST_C (0x274 + LOG_1X_BASE_C) + +/* 629-704 HDR reserved logs */ +#define LOG_HDR_RESERVED_CODES_BASE_3_C (0x275 + LOG_1X_BASE_C) +#define LOG_HDR_LAST_3_C (75 + LOG_HDR_RESERVED_CODES_BASE_3_C) + +/* 705 Call Manager call event log */ +#define LOG_CM_CALL_EVENT_C (0x2C1 + LOG_1X_BASE_C) + +/* 706-738 QVP reserved logs */ +#define LOG_QVP_RESERVED_CODES_BASE_C (0x2C2 + LOG_1X_BASE_C) +#define LOG_QVP_LAST_C (32 + LOG_QVP_RESERVED_CODES_BASE_C) + +/* 739 GPS PE Position Report log */ +#define LOG_GPS_PE_POSITION_REPORT_C (0x2E3 + LOG_1X_BASE_C) + +/* 740 GPS PE Position Report Extended log */ +#define LOG_GPS_PE_POSITION_REPORT_EXT_C (0x2E4 + LOG_1X_BASE_C) + +/* 741 log */ +#define LOG_MDDI_HOST_STATS_C (0x2E5 + LOG_1X_BASE_C) + +/* GPS Decoded Ephemeris */ +#define LOG_GPS_DECODED_EPHEMERIS_C (0x2E6 + LOG_1X_BASE_C) + +/* GPS Decoded Almanac */ +#define LOG_GPS_DECODED_ALMANAC_C (0x2E7 + LOG_1X_BASE_C) + +/* Transceiver Resource Manager */ +#define LOG_TRANSCEIVER_RESOURCE_MGR_C (0x2E8 + LOG_1X_BASE_C) + +/* GPS Position Engine Info */ +#define LOG_GPS_POSITION_ENGINE_INFO_C (0x2E9 + LOG_1X_BASE_C) + +/* 746-810 RAPTOR reserved log range */ +#define LOG_RAPTOR_RESERVED_CODES_BASE_C (0x2EA + LOG_1X_BASE_C) +#define LOG_RAPTOR_LAST_C (64 + LOG_RAPTOR_RESERVED_CODES_BASE_C) + +/* QOS Specification Logging */ + +/* QOS Requested Log */ +#define LOG_QOS_REQUESTED_C (0x32B + LOG_1X_BASE_C) + +/* QOS Granted Log */ +#define LOG_QOS_GRANTED_C (0x32C + LOG_1X_BASE_C) + +/* QOS State Log */ +#define LOG_QOS_STATE_C (0x32D + LOG_1X_BASE_C) + +#define LOG_QOS_MODIFIED_C (0x32E + LOG_1X_BASE_C) + +#define LOG_QDJ_ENQUEUE_C (0x32F + LOG_1X_BASE_C) +#define LOG_QDJ_DEQUEUE_C (0x330 + LOG_1X_BASE_C) +#define LOG_QDJ_UPDATE_C (0x331 + LOG_1X_BASE_C) +#define LOG_QDTX_ENCODER_C (0x332 + LOG_1X_BASE_C) +#define LOG_QDTX_DECODER_C (0x333 + LOG_1X_BASE_C) + +#define LOG_PORT_ASSIGNMENT_STATUS_C (0x334 + LOG_1X_BASE_C) + +/* Protocol Services reserved log codes */ +#define LOG_PS_RESERVED_CODES_BASE_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_LAST_C (25 + LOG_PS_RESERVED_C) + +#define LOG_PS_STAT_IP_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_IPV4_C (0x335 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_IPV6_C (0x336 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_ICMPV4_C (0x337 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_ICMPV6_C (0x338 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_TCP_C (0x339 + LOG_1X_BASE_C) +#define LOG_PS_STAT_GLOBAL_UDP_C (0x33A + LOG_1X_BASE_C) + +/* Protocol Services describe all TCP instances */ +#define LOG_PS_STAT_DESC_ALL_TCP_INST_C (0x33B + LOG_1X_BASE_C) + +/* Protocol Services describe all memory pool instances */ +#define LOG_PS_STAT_DESC_ALL_MEM_POOL_INST_C (0x33C + LOG_1X_BASE_C) + +/* Protocol Services describe all IFACE instances */ +#define LOG_PS_STAT_DESC_ALL_IFACE_INST_C (0x33D + LOG_1X_BASE_C) + +/* Protocol Services describe all PPP instances */ +#define LOG_PS_STAT_DESC_ALL_PPP_INST_C (0x33E + LOG_1X_BASE_C) + +/* Protocol Services describe all ARP instances */ +#define LOG_PS_STAT_DESC_ALL_ARP_INST_C (0x33F + LOG_1X_BASE_C) + +/* Protocol Services describe delta instance */ +#define LOG_PS_STAT_DESC_DELTA_INST_C (0x340 + LOG_1X_BASE_C) + +/* Protocol Services instance TCP statistics */ +#define LOG_PS_STAT_TCP_INST_C (0x341 + LOG_1X_BASE_C) + +/* Protocol Services instance UDP statistics */ +#define LOG_PS_STAT_UDP_INST_C (0x342 + LOG_1X_BASE_C) + +/* Protocol Services instance PPP statistics */ +#define LOG_PS_STAT_PPP_INST_C (0x343 + LOG_1X_BASE_C) + +/* Protocol Services instance IFACE statistics */ +#define LOG_PS_STAT_IFACE_INST_C (0x344 + LOG_1X_BASE_C) + +/* Protocol Services instance memory statistics */ +#define LOG_PS_STAT_MEM_INST_C (0x345 + LOG_1X_BASE_C) + +/* Protocol Services instance flow statistics */ +#define LOG_PS_STAT_FLOW_INST_C (0x346 + LOG_1X_BASE_C) + +/* Protocol Services instance physical link statistics */ +#define LOG_PS_STAT_PHYS_LINK_INST_C (0x347 + LOG_1X_BASE_C) + +/* Protocol Services instance ARP statistics */ +#define LOG_PS_STAT_ARP_INST_C (0x348 + LOG_1X_BASE_C) + +/* Protocol Services instance LLC statistics */ +#define LOG_PS_STAT_LLC_INST_C (0x349 + LOG_1X_BASE_C) + +/* Protocol Services instance IPHC statistics */ +#define LOG_PS_STAT_IPHC_INST_C (0x34A + LOG_1X_BASE_C) + +/* Protocol Services instance ROHC statistics */ +#define LOG_PS_STAT_ROHC_INST_C (0x34B + LOG_1X_BASE_C) + +/* Protocol Services instance RSVP statistics */ +#define LOG_PS_STAT_RSVP_INST_C (0x34C + LOG_1X_BASE_C) + +/* Protocol Services describe all LLC instances */ +#define LOG_PS_STAT_DESC_ALL_LLC_INST_C (0x34D + LOG_1X_BASE_C) + +/* Protocol Services describe all RSVP instances */ +#define LOG_PS_STAT_DESC_ALL_RSVP_INST_C (0x34E + LOG_1X_BASE_C) + +/* Call Manager Serving System event log */ +#define LOG_CM_SS_EVENT_C (0x34F + LOG_1X_BASE_C) + +/* VcTcxo manager’s automatic frequency control log */ +#define LOG_TCXOMGR_AFC_DATA_C (0x350 + LOG_1X_BASE_C) + +/* Clock transactions and general clocks status log */ +#define LOG_CLOCK_C (0x351 + LOG_1X_BASE_C) + +/* GPS search processed peak results and their associated search parameters */ +#define LOG_GPS_PROCESSED_PEAK_C (0x352 + LOG_1X_BASE_C) + +#define LOG_MDSP_LOG_CHUNKS_C (0x353 + LOG_1X_BASE_C) + +/* Periodic RSSI update log */ +#define LOG_WLAN_RSSI_UPDATE_C (0x354 + LOG_1X_BASE_C) + +/* Periodic Link Layer statistics log */ +#define LOG_WLAN_LL_STAT_C (0x355 + LOG_1X_BASE_C) + +/* QOS Extended State Log */ +#define LOG_QOS_STATE_EX_C (0x356 + LOG_1X_BASE_C) + +/* Bluetooth host HCI transmitted data */ +#define LOG_BT_HOST_HCI_TX_C (0x357 + LOG_1X_BASE_C) + +/* Bluetooth host HCI received data */ +#define LOG_BT_HOST_HCI_RX_C (0x358 + LOG_1X_BASE_C) + +/* Internal - GPS PE Position Report Part 3 */ +#define LOG_GPS_PE_POSITION_REPORT_PART3_C (0x359 + LOG_1X_BASE_C) + +/* Extended log code which logs requested QoS */ +#define LOG_QOS_REQUESTED_EX_C (0x35A + LOG_1X_BASE_C) + +/* Extended log code which logs granted QoS */ +#define LOG_QOS_GRANTED_EX_C (0x35B + LOG_1X_BASE_C) + +/* Extended log code which logs modified QoS */ +#define LOG_QOS_MODIFIED_EX_C (0x35C + LOG_1X_BASE_C) + +/* Bus Monitor Profiling Info */ +#define LOG_BUS_MON_PROF_INFO_C (0x35D + LOG_1X_BASE_C) + +/* Pilot Phase Measurement Search results */ +#define LOG_SRCH_PPM_RES_VER_2_C (0x35E + LOG_1X_BASE_C) + +/* Pilot Phase Measurement Data Base */ +#define LOG_SRCH_PPM_DB_VER_2_C (0x35F + LOG_1X_BASE_C) + +/* Pilot Phase Measurement state machine */ +#define LOG_PPM_SM_C (0x360 + LOG_1X_BASE_C) + +/* Robust Header Compression - Compressor */ +#define LOG_ROHC_COMPRESSOR_C (0x361 + LOG_1X_BASE_C) + +/* Robust Header Compression - Decompressor */ +#define LOG_ROHC_DECOMPRESSOR_C (0x362 + LOG_1X_BASE_C) + +/* Robust Header Compression - Feedback Compressor */ +#define LOG_ROHC_FEEDBACK_COMPRESSOR_C (0x363 + LOG_1X_BASE_C) + +/* Robust Header Compression - Feedback Decompressor */ +#define LOG_ROHC_FEEDBACK_DECOMPRESSOR_C (0x364 + LOG_1X_BASE_C) + +/* Bluetooth HCI commands */ +#define LOG_BT_HCI_CMD_C (0x365 + LOG_1X_BASE_C) + +/* Bluetooth HCI events */ +#define LOG_BT_HCI_EV_C (0x366 + LOG_1X_BASE_C) + +/* Bluetooth HCI Transmitted ACL data */ +#define LOG_BT_HCI_TX_ACL_C (0x367 + LOG_1X_BASE_C) + +/* Bluetooth HCI Received ACL data */ +#define LOG_BT_HCI_RX_ACL_C (0x368 + LOG_1X_BASE_C) + +/* Bluetooth SOC H4 Deep Sleep */ +#define LOG_BT_SOC_H4DS_C (0x369 + LOG_1X_BASE_C) + +/* UMTS to CDMA Handover Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_MSG_C (0x36A + LOG_1X_BASE_C) + +/* Graphic Event Data */ +#define LOG_PROFILER_GRAPHIC_DATA_C (0x36B + LOG_1X_BASE_C) + +/* Audio Event Data */ +#define LOG_PROFILER_AUDIO_DATA_C (0x36C + LOG_1X_BASE_C) + +/* GPS Spectral Information */ +#define LOG_GPS_SPECTRAL_INFO_C (0x36D + LOG_1X_BASE_C) + +/* AHB Performance Monitor LOG data */ +#define LOG_APM_C (0x36E + LOG_1X_BASE_C) + +/* GPS Clock Report */ +#define LOG_CONVERGED_GPS_CLOCK_REPORT_C (0x36F + LOG_1X_BASE_C) + +/* GPS Position Report */ +#define LOG_CONVERGED_GPS_POSITION_REPORT_C (0x370 + LOG_1X_BASE_C) + +/* GPS Measurement Report */ +#define LOG_CONVERGED_GPS_MEASUREMENT_REPORT_C (0x371 + LOG_1X_BASE_C) + +/* GPS RF Status Report */ +#define LOG_CONVERGED_GPS_RF_STATUS_REPORT_C (0x372 + LOG_1X_BASE_C) + +/* VOIP To CDMA Handover Message - Obsoleted by 0x138B - 0x138D */ +#define LOG_VOIP_TO_CDMA_HANDOVER_MSG_C (0x373 + LOG_1X_BASE_C) + +/* GPS Prescribed Dwell Result */ +#define LOG_GPS_PRESCRIBED_DWELL_RESULT_C (0x374 + LOG_1X_BASE_C) + +/* CGPS IPC Data */ +#define LOG_CGPS_IPC_DATA_C (0x375 + LOG_1X_BASE_C) + +/* CGPS Non IPC Data */ +#define LOG_CGPS_NON_IPC_DATA_C (0x376 + LOG_1X_BASE_C) + +/* CGPS Session Report */ +#define LOG_CGPS_REP_EVT_LOG_PACKET_C (0x377 + LOG_1X_BASE_C) + +/* CGPS PDSM Get Position */ +#define LOG_CGPS_PDSM_GET_POSITION_C (0x378 + LOG_1X_BASE_C) + +/* CGPS PDSM Set Parameters */ +#define LOG_CGPS_PDSM_SET_PARAMETERS_C (0x379 + LOG_1X_BASE_C) + +/* CGPS PDSM End Session */ +#define LOG_CGPS_PDSM_END_SESSION_C (0x37A + LOG_1X_BASE_C) + +/* CGPS PDSM Notify Verify Response */ +#define LOG_CGPS_PDSM_NOTIFY_VERIFY_RESP_C (0x37B + LOG_1X_BASE_C) + +/* CGPS PDSM Position Report Callback */ +#define LOG_CGPS_PDSM_POSITION_REPORT_CALLBACK_C (0x37C + LOG_1X_BASE_C) + +/* CGPS PDSM PD Event Callback */ +#define LOG_CGPS_PDSM_PD_EVENT_CALLBACK_C (0x37D + LOG_1X_BASE_C) + +/* CGPS PDSM PA Event Callback */ +#define LOG_CGPS_PDSM_PA_EVENT_CALLBACK_C (0x37E + LOG_1X_BASE_C) + +/* CGPS PDSM Notify Verify Request Callback */ +#define LOG_CGPS_PDSM_NOTIFY_VERIFY_REQUEST_C (0x37F + LOG_1X_BASE_C) + +/* CGPS PDSM PD Command Error Callback */ +#define LOG_CGPS_PDSM_PD_CMD_ERR_CALLBACK_C (0x380 + LOG_1X_BASE_C) + +/* CGPS PDSM PA Command Error Callback */ +#define LOG_CGPS_PDSM_PA_CMD_ERR_CALLBACK_C (0x381 + LOG_1X_BASE_C) + +/* CGPS PDSM Position Error */ +#define LOG_CGPS_PDSM_POS_ERROR_C (0x382 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status Position Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_POS_REPORT_C (0x383 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status NMEA Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_NMEA_REPORT_C (0x384 + LOG_1X_BASE_C) + +/* CGPS PDSM Extended Status Measurement Report */ +#define LOG_CGPS_PDSM_EXT_STATUS_MEAS_REPORT_C (0x385 + LOG_1X_BASE_C) + +/* CGPS Report Server TX Packet */ +#define LOG_CGPS_REP_SVR_TX_LOG_PACKET_C (0x386 + LOG_1X_BASE_C) + +/* CGPS Report Server RX Packet */ +#define LOG_CGPS_REP_SVR_RX_LOG_PACKET_C (0x387 + LOG_1X_BASE_C) + +/* UMTS To CDMA Handover Paging Channel Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_PCH_MSG_C (0x388 + LOG_1X_BASE_C) + +/* UMTS To CDMA Handover Traffic Channel Message */ +#define LOG_UMTS_TO_CDMA_HANDOVER_TCH_MSG_C (0x389 + LOG_1X_BASE_C) + +/* Converged GPS IQ Report */ +#define LOG_CONVERGED_GPS_IQ_REPORT_C (0x38A + LOG_1X_BASE_C) + +/* VOIP To CDMA Paging Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_PCH_HANDOVER_MSG_C (0x38B + LOG_1X_BASE_C) + +/* VOIP To CDMA Access Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_ACH_HANDOVER_MSG_C (0x38C + LOG_1X_BASE_C) + +/* VOIP To CDMA Forward Traffic Channel Handover Message */ +#define LOG_VOIP_TO_CDMA_FTC_HANDOVER_MSG_C (0x38D + LOG_1X_BASE_C) + +/* QMI reserved logs */ +#define LOG_QMI_RESERVED_CODES_BASE_C (0x38E + LOG_1X_BASE_C) +#define LOG_QMI_LAST_C (32 + LOG_QMI_RESERVED_CODES_BASE_C) + +/* QOS Info Code Update Log */ +#define LOG_QOS_INFO_CODE_UPDATE_C (0x3AF + LOG_1X_BASE_C) + +/* Transmit(Uplink) Vocoder PCM Packet Log */ +#define LOG_TX_PCM_PACKET_C (0x3B0 + LOG_1X_BASE_C) + +/* Audio Vocoder Data Paths */ +#define LOG_AUDVOC_DATA_PATHS_PACKET_C (0x3B0 + LOG_1X_BASE_C) + +/* Receive(Downlink) Vocoder PCM Packet Log */ +#define LOG_RX_PCM_PACKET_C (0x3B1 + LOG_1X_BASE_C) + +/* CRC of YUV frame log */ +#define LOG_DEC_CRC_FRAME_C (0x3B2 + LOG_1X_BASE_C) + +/* FLUTE Session Information */ +#define LOG_FLUTE_SESSION_INFO_C (0x3B3 + LOG_1X_BASE_C) + +/* FLUTE ADP File Information */ +#define LOG_FLUTE_ADP_FILE_INFO_C (0x3B4 + LOG_1X_BASE_C) + +/* FLUTE File Request Information */ +#define LOG_FLUTE_FILE_REQ_INFO_C (0x3B5 + LOG_1X_BASE_C) + +/* FLUTE FDT Instance Information */ +#define LOG_FLUTE_FDT_INST_C (0x3B6 + LOG_1X_BASE_C) + +/* FLUTE FDT Information */ +#define LOG_FLUTE_FDT_INFO_C (0x3B7 + LOG_1X_BASE_C) + +/* FLUTE File Log Packet Information */ +#define LOG_FLUTE_FILE_INFO_C (0x3B8 + LOG_1X_BASE_C) + +/* 3G 1X Parameter Overhead Information */ +#define LOG_VOIP_TO_CDMA_3G1X_PARAMETERS_C (0x3B9 + LOG_1X_BASE_C) + +/* CGPS ME Job Info */ +#define LOG_CGPS_ME_JOB_INFO_C (0x3BA + LOG_1X_BASE_C) + +/* CGPS ME SV Lists */ +#define LOG_CPGS_ME_SV_LISTS_C (0x3BB + LOG_1X_BASE_C) + +/* Flexible Profiling Status */ +#define LOG_PROFDIAG_GEN_STATUS_C (0x3BC + LOG_1X_BASE_C) + +/* Flexible Profiling Results */ +#define LOG_PROFDIAG_GEN_PROF_C (0x3BD + LOG_1X_BASE_C) + +/* FLUTE ADP File Content Log Packet Information */ +#define LOG_FLUTE_ADP_FILE_C (0x3BE + LOG_1X_BASE_C) + +/* FLUTE FDT Instance File Content Log Packet Information */ +#define LOG_FLUTE_FDT_INST_FILE_C (0x3BF + LOG_1X_BASE_C) + +/* FLUTE FDT Entries Information */ +#define LOG_FLUTE_FDT_ENTRIES_INFO_C (0x3C0 + LOG_1X_BASE_C) + +/* FLUTE File Contents Log Packet Information */ +#define LOG_FLUTE_FILE_C (0x3C1 + LOG_1X_BASE_C) + +/* CGPS ME Time-Transfer Info */ +#define LOG_CGPS_ME_TIME_TRANSFER_INFO_C (0x3C2 + LOG_1X_BASE_C) + +/* CGPS ME UMTS Time-Tagging Info */ +#define LOG_CGPS_ME_UMTS_TIME_TAGGING_INFO_C (0x3C3 + LOG_1X_BASE_C) + +/* CGPS ME Generic Time Estimate Put lnfo */ +#define LOG_CGPS_ME_TIME_EST_PUT_INFO_C (0x3C4 + LOG_1X_BASE_C) + +/* CGPS ME Generic Freq Estimate Put lnfo */ +#define LOG_CGPS_ME_FREQ_EST_PUT_INFO_C (0x3C5 + LOG_1X_BASE_C) + +/* CGPS Slow Clock Report */ +#define LOG_CGPS_SLOW_CLOCK_REPORT_C (0x3C6 + LOG_1X_BASE_C) + +/* Converged GPS Medium Grid */ +#define LOG_CONVERGED_GPS_MEDIUM_GRID_C (0x3C7 + LOG_1X_BASE_C) + +/* Static information about the driver or device */ +#define LOG_SNSD_INFO_C (0x3C8 + LOG_1X_BASE_C) + +/* Dynamic state information about the device or driver */ +#define LOG_SNSD_STATE_C (0x3C9 + LOG_1X_BASE_C) + +/* Data from a driver */ +#define LOG_SNSD_DATA (0x3CA + LOG_1X_BASE_C) +#define LOG_SNSD_DATA_C (0x3CA + LOG_1X_BASE_C) + +/* CGPS Cell DB Cell Change Info */ +#define LOG_CGPS_CELLDB_CELL_CHANGE_INFO_C (0x3CB + LOG_1X_BASE_C) + +/* xScalar YUV frame log */ +#define LOG_DEC_XSCALE_YUV_FRAME_C (0x3CC + LOG_1X_BASE_C) + +/* CRC of xScaled YUV frame log */ +#define LOG_DEC_XSCALE_CRC_FRAME_C (0x3CD + LOG_1X_BASE_C) + +/* CGPS Frequency Estimate Report */ +#define LOG_CGPS_FREQ_EST_REPORT_C (0x3CE + LOG_1X_BASE_C) + +/* GPS DCME Srch Job Completed */ +#define LOG_GPS_DCME_SRCH_JOB_COMPLETED_C (0x3CF + LOG_1X_BASE_C) + +/* CGPS ME Fastscan results */ +#define LOG_CGPS_ME_FASTSCAN_RESULTS_C (0x3D0 + LOG_1X_BASE_C) + +/* XO frequency Estimation log */ +#define LOG_XO_FREQ_EST_C (0x3D1 + LOG_1X_BASE_C) + +/* Tcxomgr field calibration data */ +#define LOG_TCXOMGR_FIELD_CAL_C (0x3D2 + LOG_1X_BASE_C) + +/* UMB Call Processing Connection Attempt */ +#define LOG_UMBCP_CONNECTION_ATTEMPT_C (0x3D3 + LOG_1X_BASE_C) + +/* UMB Call Processing Connection Release */ +#define LOG_UMBCP_CONNECTION_RELEASE_C (0x3D4 + LOG_1X_BASE_C) + +/* UMB Call Processing Page Message */ +#define LOG_UMBCP_PAGE_MESSAGE_C (0x3D5 + LOG_1X_BASE_C) + +/* UMB Call Processing OVHD Information */ +#define LOG_UMBCP_OVHD_INFO_C (0x3D6 + LOG_1X_BASE_C) + +/* UMB Call Processing Session Attempt */ +#define LOG_UMBCP_SESSION_ATTEMPT_C (0x3D7 + LOG_1X_BASE_C) + +/* UMB Call Processing Route Information */ +#define LOG_UMBCP_ROUTE_INFO_C (0x3D8 + LOG_1X_BASE_C) + +/* UMB Call Processing State Information */ +#define LOG_UMBCP_STATE_INFO_C (0x3D9 + LOG_1X_BASE_C) + +/* UMB Call Processing SNP */ +#define LOG_UMBCP_SNP_C (0x3DA + LOG_1X_BASE_C) + +/* CGPS Session Early Exit Decision */ +#define LOG_CGPS_SESSION_EARLY_EXIT_DECISION_C (0x3DB + LOG_1X_BASE_C) + +/* GPS RF Linearity Status */ +#define LOG_CGPS_ME_RF_LINEARITY_INFO_C (0x3DC + LOG_1X_BASE_C) + +/* CGPS ME 5ms IQ Sums */ +#define LOG_CGPS_ME_5MS_IQ_SUMS_C (0x3DD + LOG_1X_BASE_C) + +/* CGPS ME 20ms IQ Sums */ +#define LOG_CPGS_ME_20MS_IQ_SUMS_C (0x3DE + LOG_1X_BASE_C) + +/* ROHC Compressor Statistics */ +#define LOG_ROHC_COMPRESSOR_STATS_C (0x3DF + LOG_1X_BASE_C) + +/* ROHC Decompressor Statistics */ +#define LOG_ROHC_DECOMPRESSOR_STATS_C (0x3E0 + LOG_1X_BASE_C) + +/* Sensors - Kalman filter information */ +#define LOG_SENSOR_KF_INFO_C (0x3E1 + LOG_1X_BASE_C) + +/* Sensors - Integrated measurements */ +#define LOG_SENSOR_INT_MEAS_C (0x3E2 + LOG_1X_BASE_C) + +/* Sensors - Bias calibration values */ +#define LOG_SENSOR_BIAS_CALIBRATION_C (0x3E3 + LOG_1X_BASE_C) + +/* Log codes 0x13E4-0x13E7 are not following standard log naming convention */ + +/* DTV ISDB-T Transport Stream Packets */ +#define LOG_DTV_ISDB_TS_PACKETS (0x3E4 + LOG_1X_BASE_C) + +/* DTV ISDB-T PES Packets */ +#define LOG_DTV_ISDB_PES_PACKETS (0x3E5 + LOG_1X_BASE_C) + +/* DTV ISDB-T Sections */ +#define LOG_DTV_ISDB_SECTIONS (0x3E6 + LOG_1X_BASE_C) + +/* DTV ISDB-T Buffering */ +#define LOG_DTV_ISDB_BUFFERING (0x3E7 + LOG_1X_BASE_C) + +/* WLAN System Acquisition and Handoff */ +#define LOG_WLAN_SYS_ACQ_HO_C (0x3E8 + LOG_1X_BASE_C) + +/* WLAN General Configurable Parameters */ +#define LOG_WLAN_GEN_CONFIG_PARAMS_C (0x3E9 + LOG_1X_BASE_C) + +/* UMB Physical Layer Channel and Interference Estimation */ +#define LOG_UMB_PHY_RX_DPICH_CIE_C (0x3EA + LOG_1X_BASE_C) + +/* UMB Physical Layer MMSE/MRC Demodulated Data Symbols (Low) */ +#define LOG_UMB_PHY_RX_DATA_DEMOD_LOW_C (0x3EB + LOG_1X_BASE_C) + +/* UMB Physical Layer MMSE/MRC Demodulated Data Symbols (High) */ +#define LOG_UMB_PHY_RX_DATA_DEMOD_HIGH_C (0x3EC + LOG_1X_BASE_C) + +/* UMB Physical Layer DCH Decoder */ +#define LOG_UMB_PHY_RX_DCH_DECODER_C (0x3ED + LOG_1X_BASE_C) + +/* UMB Physical Layer DCH Statistics */ +#define LOG_UMB_PHY_DCH_STATISTICS_C (0x3EE + LOG_1X_BASE_C) + +/* UMB Physical Layer CqiPich Processing */ +#define LOG_UMB_PHY_RX_CQIPICH_C (0x3EF + LOG_1X_BASE_C) + +/* UMB Physical Layer MIMO/SIMO in CqiPich (High) */ +#define LOG_UMB_PHY_RX_CQIPICH_CHANTAPS_HIGH_C (0x3F0 + LOG_1X_BASE_C) + +/* UMB Physical Layer MIMO/SIMO in CquiPich (Low) */ +#define LOG_UMB_PHY_RX_CQIPICH_CHANTAPS_LOW_C (0x3F1 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time-Domain Channel Taps (High) */ +#define LOG_UMB_PHY_RX_PPICH_CHAN_EST_HIGH_C (0x3F2 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time-Domain Channel Taps (Low) */ +#define LOG_UMB_PHY_RX_PPICH_CHAN_EST_LOW_C (0x3F3 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator */ +#define LOG_UMB_PHY_TX_PICH_CONFIG_C (0x3F4 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACK (High) */ +#define LOG_UMB_PHY_TX_ACK_HIGH_C (0x3F5 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACK (Low) */ +#define LOG_UMB_PHY_TX_ACK_LOW_C (0x3F6 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-PICH */ +#define LOG_UMB_PHY_TX_PICH_C (0x3F7 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ACH (Access) */ +#define LOG_UMB_PHY_TX_ACH_C (0x3F8 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ODDCCH (High) */ +#define LOG_UMB_PHY_TX_ODCCH_HIGH_C (0x3F9 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-ODDCCH (Low) */ +#define LOG_UMB_PHY_TX_ODCCH_LOW_C (0x3FA + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-CDCCH */ +#define LOG_UMB_PHY_TX_RCDCCH_CONFIG_C (0x3FB + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for CQI sent on RCDCCH */ +#define LOG_UMB_PHY_TX_NONFLSS_CQICH_C (0x3FC + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for CQI sent on RCDCCH */ +#define LOG_UMB_PHY_TX_FLSS_CQICH_C (0x3FD + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for PACH sent on RCDCCH */ +#define LOG_UMB_PHY_TX_PAHCH_C (0x3FE + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for REQ sent on RCDCCH */ +#define LOG_UMB_PHY_TX_REQCH_C (0x3FF + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for PSD sent on RCDCCH */ +#define LOG_UMB_PHY_TX_PSDCH_C (0x400 + LOG_1X_BASE_C) + +/* UMB Physical Layer AT Modulator for R-DCH */ +#define LOG_UMB_PHY_TX_DCH_C (0x401 + LOG_1X_BASE_C) + +/* UMB Physical Layer Time/Frequency/RxPower Estimate */ +#define LOG_UMB_PHY_RX_TIME_FREQ_POWER_ESTIMATE_C (0x402 + LOG_1X_BASE_C) + +/* UMB Physical Layer FLCS Processing */ +#define LOG_UMB_PHY_RX_FLCS_PROCESSING_C (0x403 + LOG_1X_BASE_C) + +/* UMB Physical Layer PBCCH Processing */ +#define LOG_UMB_PHY_RX_PBCCH_PROCESSING_C (0x404 + LOG_1X_BASE_C) + +/* UMB Physical Layer SBCCH Processing */ +#define LOG_UMB_PHY_RX_SBCCH_PROCESSING_C (0x405 + LOG_1X_BASE_C) + +/* UMB Physical Layer QPCH Processing */ +#define LOG_UMB_PHY_RX_QPCH_PROCESSING_C (0x406 + LOG_1X_BASE_C) + +/* UMB Physical Layer MRC Demodulated Data Symbols (Preamble SBCCH/QPCH) */ +#define LOG_UMB_PHY_RX_SBCCH_DEMOD_C (0x407 + LOG_1X_BASE_C) + +/* UMB Physical Layer MRC Demodulated Data Symbols (Preamble PBCCH) */ +#define LOG_UMB_PHY_RX_PBCCH_DEMOD_C (0x408 + LOG_1X_BASE_C) + +/* UMB Physical Layer VCQI */ +#define LOG_UMB_PHY_RX_VCQI_C (0x409 + LOG_1X_BASE_C) + +/* UMB Physical Layer Acquisition Algorithm */ +#define LOG_UMB_PHY_RX_INITIAL_ACQUISITION_C (0x40A + LOG_1X_BASE_C) + +/* UMB Physical Layer Handoff Search Algorithm */ +#define LOG_UMB_PHY_RX_HANDOFF_SEARCH_C (0x40B + LOG_1X_BASE_C) + +/* UMB RF RFFE Configuration Info */ +#define LOG_UMB_AT_RFFE_CONFG_C (0x40C + LOG_1X_BASE_C) + +/* UMB RF Calibrated Values After Powerup */ +#define LOG_UMB_AT_RFFE_RX_CALIB_C (0x40D + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Acquisition Mode */ +#define LOG_UMB_AT_RFFE_RX_ACQ_C (0x40E + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Idle Mode */ +#define LOG_UMB_AT_RFFE_RX_IDLE_C (0x40F + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Connected Mode */ +#define LOG_UMB_AT_RFFE_RX_CONNECTED_C (0x410 + LOG_1X_BASE_C) + +/* UMB RF AGC Block in Connected Mode (FTM) */ +#define LOG_UMB_AT_RFFE_RX_CONNECTED_FTM_C (0x411 + LOG_1X_BASE_C) + +/* UMB RF Jammer Detector Functionality */ +#define LOG_UMB_AT_RFFE_RX_JAMMER_DETECTOR_FUNCTIONALITY_C (0x412 + LOG_1X_BASE_C) + +/* UMB RF Jammer Detector Response */ +#define LOG_UMB_AT_RFFE_RX_JAMMER_DETECTOR_RESPONSE_C (0x413 + LOG_1X_BASE_C) + +/* UMB RF RFFE TX Power Control */ +#define LOG_UMB_AT_RFFE_TX_BETA_SCALING_C (0x414 + LOG_1X_BASE_C) + +/* UMB Searcher Dump */ +#define LOG_UMB_SEARCHER_DUMP_C (0x415 + LOG_1X_BASE_C) + +/* UMB System Acquire */ +#define LOG_UMB_SYSTEM_ACQUIRE_C (0x416 + LOG_1X_BASE_C) + +/* UMB Set Maintenance */ +#define LOG_UMB_SET_MAINTENANCE_C (0x417 + LOG_1X_BASE_C) + +/* UMB QPCH */ +#define LOG_UMB_QPCH_C (0x418 + LOG_1X_BASE_C) + +/* UMB RLL Forward Partial RP Packet */ +#define LOG_UMB_RLL_FORWARD_PARTIAL_RP_C (0x419 + LOG_1X_BASE_C) + +/* UMB RLL Reverse Partial RP Packet */ +#define LOG_UMB_RLL_REVERSE_PARTIAL_RP_C (0x41A + LOG_1X_BASE_C) + +/* UMB RLL Forward Signal Packet */ +#define LOG_UMB_RLL_FORWARD_SIGNAL_C (0x41B + LOG_1X_BASE_C) + +/* UMB RLL Reverse Signal Packet */ +#define LOG_UMB_RLL_REVERSE_SIGNAL_C (0x41C + LOG_1X_BASE_C) + +/* UMB RLL Forward Statistics */ +#define LOG_UMB_RLL_FORWARD_STATS_C (0x41D + LOG_1X_BASE_C) + +/* UMB RLL Reverse Statistics */ +#define LOG_UMB_RLL_REVERSE_STATS_C (0x41E + LOG_1X_BASE_C) + +/* UMB RLL IRTP */ +#define LOG_UMB_RLL_IRTP_C (0x41F + LOG_1X_BASE_C) + +/* UMB AP Forward Link MAC Packets */ +#define LOG_UMB_AP_FL_MAC_PACKET_C (0x420 + LOG_1X_BASE_C) + +/* UMB AP Reverse Link MAC Packets */ +#define LOG_UMB_AP_RL_MAC_PACKET_C (0x421 + LOG_1X_BASE_C) + +/* GPS Performance Statistics log */ +#define LOG_CGPS_PERFORMANCE_STATS_C (0x422 + LOG_1X_BASE_C) + +/* UMB Searcher General Status */ +#define LOG_UMB_SRCH_GENERAL_STATUS_C (0x423 + LOG_1X_BASE_C) + +/* UMB Superframe Scheduler */ +#define LOG_UMB_SUPERFRAME_SCHEDULER_C (0x424 + LOG_1X_BASE_C) + +/* UMB Sector List */ +#define LOG_UMB_SECTOR_LIST_C (0x425 + LOG_1X_BASE_C) + +/* UMB MAC Access Attempt Command */ +#define LOG_UMB_MAC_ACCESS_ATTEMPT_CMD_C (0x426 + LOG_1X_BASE_C) + +/* UMB MAC Access Probe Information */ +#define LOG_UMB_MAC_ACCESS_PROBE_INFO_C (0x427 + LOG_1X_BASE_C) + +/* UMB MAC RTCMAC Package Information */ +#define LOG_UMB_MAC_RTCMAC_PKG_INFO_C (0x428 + LOG_1X_BASE_C) + +/* UMB MAC Super Frame Information */ +#define LOG_UMB_MAC_SI_INFO_C (0x429 + LOG_1X_BASE_C) + +/* UMB MAC Quick Channel Information */ +#define LOG_UMB_MAC_QCI_INFO_C (0x42A + LOG_1X_BASE_C) + +/* UMB MAC Paging Id List */ +#define LOG_UMB_MAC_PAGING_ID_LIST_C (0x42B + LOG_1X_BASE_C) + +/* UMB MAC Quick Paging Channel Information */ +#define LOG_UMB_MAC_QPCH_INFO_C (0x42C + LOG_1X_BASE_C) + +/* UMB MAC FTCMAC Information */ +#define LOG_UMB_MAC_FTCMAC_PKG_INFO_C (0x42D + LOG_1X_BASE_C) + +/* UMB MAC Access Grant Receiving */ +#define LOG_UMB_MAC_ACCESS_GRANT_C (0x42E + LOG_1X_BASE_C) + +/* UMB MAC Generic Debug Log */ +#define LOG_UMB_MAC_GEN_DEBUG_LOG_PKG_C (0x42F + LOG_1X_BASE_C) + +/* CGPS Frequency Bias Estimate */ +#define LOG_CGPS_MC_FREQ_BIAS_EST_C (0x430 + LOG_1X_BASE_C) + +/* UMB MAC Request Report Information Log */ +#define LOG_UMB_MAC_REQCH_REPORT_INFO_C (0x431 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Token Bucket Information Log */ +#define LOG_UMB_MAC_RLQOS_TOKEN_BUCKET_INFO_C (0x432 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Stream Information Log */ +#define LOG_UMB_MAC_RLQOS_STREAM_INFO_C (0x433 + LOG_1X_BASE_C) + +/* UMB MAC Reverse Link QoS Allotment Information Log */ +#define LOG_UMB_MAC_RLQOS_ALLOTMENT_INFO_C (0x434 + LOG_1X_BASE_C) + +/* UMB Searcher Recent State Machine Transactions */ +#define LOG_UMB_SRCH_STM_ACTIVITY_C (0x435 + LOG_1X_BASE_C) + +/* Performance Counters on ARM11 Profiling Information */ +#define LOG_ARM11_PERF_CNT_INFO_C (0x436 + LOG_1X_BASE_C) + +/* Protocol Services describe all flow instances */ +#define LOG_PS_STAT_DESC_ALL_FLOW_INST_C (0x437 + LOG_1X_BASE_C) + +/* Protocol Services describe all physical link instances */ +#define LOG_PS_STAT_DESC_ALL_PHYS_LINK_INST_C (0x438 + LOG_1X_BASE_C) + +/* Protocol Services describe all UDP instances */ +#define LOG_PS_STAT_DESC_ALL_UDP_INST_C (0x439 + LOG_1X_BASE_C) + +/* Searcher 4 Multi-Carrier HDR */ +#define LOG_SRCH4_MC_HDR_C (0x43A + LOG_1X_BASE_C) + +/* Protocol Services describe all IPHC instances */ +#define LOG_PS_STAT_DESC_ALL_IPHC_INST_C (0x43B + LOG_1X_BASE_C) + +/* Protocol Services describe all ROHC instances */ +#define LOG_PS_STAT_DESC_ALL_ROHC_INST_C (0x43C + LOG_1X_BASE_C) + +/* BCast security add program information */ +#define LOG_BCAST_SEC_ADD_PROGRAM_INFO_C (0x43D + LOG_1X_BASE_C) + +/* BCast security add program complete */ +#define LOG_BCAST_SEC_ADD_PROGRAM_COMPLETE_C (0x43E + LOG_1X_BASE_C) + +/* BCast security SDP parse */ +#define LOG_BCAST_SEC_SDP_PARSE_C (0x43F + LOG_1X_BASE_C) + +/* CGPS ME dynamic power optimization status */ +#define LOG_CGPS_ME_DPO_STATUS_C (0x440 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session start */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_START_C (0x441 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session stop */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_STOP_C (0x442 + LOG_1X_BASE_C) + +/* CGPS PDSM on demand session not started */ +#define LOG_CGPS_PDSM_ON_DEMAND_SESSION_NOT_STARTED_C (0x443 + LOG_1X_BASE_C) + +/* CGPS PDSM extern coarse position inject start */ +#define LOG_CGPS_PDSM_EXTERN_COARSE_POS_INJ_START_C (0x444 + LOG_1X_BASE_C) + +/* DTV ISDB-T TMCC information */ +#define LOG_DTV_ISDB_TMCC_C (0x445 + LOG_1X_BASE_C) + +/* RF development */ +#define LOG_RF_DEV_C (0x446 + LOG_1X_BASE_C) + +/* RF RFM API */ +#define LOG_RF_RFM_API_C (0x447 + LOG_1X_BASE_C) + +/* RF RFM state */ +#define LOG_RF_RFM_STATE_C (0x448 + LOG_1X_BASE_C) + +/* 1X RF Warmup */ +#define LOG_1X_RF_WARMUP_C (0x449 + LOG_1X_BASE_C) + +/* 1X RF power limiting */ +#define LOG_1X_RF_PWR_LMT_C (0x44A + LOG_1X_BASE_C) + +/* 1X RF state */ +#define LOG_1X_RF_STATE_C (0x44B + LOG_1X_BASE_C) + +/* 1X RF sleep */ +#define LOG_1X_RF_SLEEP_C (0x44C + LOG_1X_BASE_C) + +/* 1X RF TX state */ +#define LOG_1X_RF_TX_STATE_C (0x44D + LOG_1X_BASE_C) + +/* 1X RF IntelliCeiver state */ +#define LOG_1X_RF_INT_STATE_C (0x44E + LOG_1X_BASE_C) + +/* 1X RF RX ADC clock */ +#define LOG_1X_RF_RX_ADC_CLK_C (0x44F + LOG_1X_BASE_C) + +/* 1X RF LNA switch point */ +#define LOG_1X_RF_LNA_SWITCHP_C (0x450 + LOG_1X_BASE_C) + +/* 1X RF RX calibration */ +#define LOG_1X_RF_RX_CAL_C (0x451 + LOG_1X_BASE_C) + +/* 1X RF API */ +#define LOG_1X_RF_API_C (0x452 + LOG_1X_BASE_C) + +/* 1X RF RX PLL locking status */ +#define LOG_1X_RF_RX_PLL_LOCK_C (0x453 + LOG_1X_BASE_C) + +/* 1X RF voltage regulator */ +#define LOG_1X_RF_VREG_C (0x454 + LOG_1X_BASE_C) + +/* CGPS DIAG successful fix count */ +#define LOG_CGPS_DIAG_SUCCESSFUL_FIX_COUNT_C (0x455 + LOG_1X_BASE_C) + +/* CGPS MC track dynamic power optimization status */ +#define LOG_CGPS_MC_TRACK_DPO_STATUS_C (0x456 + LOG_1X_BASE_C) + +/* CGPS MC SBAS demodulated bits */ +#define LOG_CGPS_MC_SBAS_DEMOD_BITS_C (0x457 + LOG_1X_BASE_C) + +/* CGPS MC SBAS demodulated soft symbols */ +#define LOG_CGPS_MC_SBAS_DEMOD_SOFT_SYMBOLS_C (0x458 + LOG_1X_BASE_C) + +/* Data Services PPP configuration */ +#define LOG_DS_PPP_CONFIG_PARAMS_C (0x459 + LOG_1X_BASE_C) + +/* Data Services physical link configuration */ +#define LOG_DS_PHYS_LINK_CONFIG_PARAMS_C (0x45A + LOG_1X_BASE_C) + +/* Data Services PPP device configuration */ +#define LOG_PS_PPP_DEV_CONFIG_PARAMS_C (0x45B + LOG_1X_BASE_C) + +/* CGPS PDSM GPS state information */ +#define LOG_CGPS_PDSM_GPS_STATE_INFO_C (0x45C + LOG_1X_BASE_C) + +/* CGPS PDSM EXT status GPS state information */ +#define LOG_CGPS_PDSM_EXT_STATUS_GPS_STATE_INFO_C (0x45D + LOG_1X_BASE_C) + +/* CGPS ME Rapid Search Report */ +#define LOG_CGPS_ME_RAPID_SEARCH_REPORT_C (0x45E + LOG_1X_BASE_C) + +/* CGPS PDSM XTRA-T session */ +#define LOG_CGPS_PDSM_XTRA_T_SESSION_C (0x45F + LOG_1X_BASE_C) + +/* CGPS PDSM XTRA-T upload */ +#define LOG_CGPS_PDSM_XTRA_T_UPLOAD_C (0x460 + LOG_1X_BASE_C) + +/* CGPS Wiper Position Report */ +#define LOG_CGPS_WIPER_POSITION_REPORT_C (0x461 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard HTTP Digest Request Info */ +#define LOG_DTV_DVBH_SEC_SC_HTTP_DIGEST_REQ_C (0x462 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard HTTP Digest Response Info */ +#define LOG_DTV_DVBH_SEC_SC_HTTP_DIGEST_RSP_C (0x463 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Registration Request Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_REG_REQ_C (0x464 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Registration Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_REG_COMPLETE_C (0x465 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Deregistration Request Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_DEREG_REQ_C (0x466 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Services Deregistration Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_SVC_DEREG_COMPLETE_C (0x467 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Request Info */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_REQ_C (0x468 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Request Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_REQ_COMPLETE_C (0x469 + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Program Selection Info */ +#define LOG_DTV_DVBH_SEC_SC_PROG_SEL_C (0x46A + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Program Selection Complete Info */ +#define LOG_DTV_DVBH_SEC_SC_PROG_SEL_COMPLETE_C (0x46B + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_C (0x46C + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard LTKM Verification Message */ +#define LOG_DTV_DVBH_SEC_SC_LTKM_VERIFICATION_C (0x46D + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard Parental Control Message */ +#define LOG_DTV_DVBH_SEC_SC_PARENTAL_CTRL_C (0x46E + LOG_1X_BASE_C) + +/* DTV DVBH Security SmartCard STKM */ +#define LOG_DTV_DVBH_SEC_SC_STKM_C (0x46F + LOG_1X_BASE_C) + +/* Protocol Services Statistics Global Socket */ +#define LOG_PS_STAT_GLOBAL_SOCK_C (0x470 + LOG_1X_BASE_C) + +/* MCS Application Manager */ +#define LOG_MCS_APPMGR_C (0x471 + LOG_1X_BASE_C) + +/* MCS MSGR */ +#define LOG_MCS_MSGR_C (0x472 + LOG_1X_BASE_C) + +/* MCS QTF */ +#define LOG_MCS_QTF_C (0x473 + LOG_1X_BASE_C) + +/* Sensors Stationary Detector Output */ +#define LOG_STATIONARY_DETECTOR_OUTPUT_C (0x474 + LOG_1X_BASE_C) + +/* Print out the ppm data portion */ +#define LOG_CGPS_PDSM_EXT_STATUS_MEAS_REPORT_PPM_C (0x475 + LOG_1X_BASE_C) + +/* GNSS Position Report */ +#define LOG_GNSS_POSITION_REPORT_C (0x476 + LOG_1X_BASE_C) + +/* GNSS GPS Measurement Report */ +#define LOG_GNSS_GPS_MEASUREMENT_REPORT_C (0x477 + LOG_1X_BASE_C) + +/* GNSS Clock Report */ +#define LOG_GNSS_CLOCK_REPORT_C (0x478 + LOG_1X_BASE_C) + +/* GNSS Demod Soft Decision */ +#define LOG_GNSS_DEMOD_SOFT_DECISIONS_C (0x479 + LOG_1X_BASE_C) + +/* GNSS ME 5MS IQ sum */ +#define LOG_GNSS_ME_5MS_IQ_SUMS_C (0x47A + LOG_1X_BASE_C) + +/* GNSS CD DB report */ +#define LOG_GNSS_CD_DB_REPORT_C (0x47B + LOG_1X_BASE_C) + +/* GNSS PE WLS position report */ +#define LOG_GNSS_PE_WLS_POSITION_REPORT_C (0x47C + LOG_1X_BASE_C) + +/* GNSS PE KF position report */ +#define LOG_GNSS_PE_KF_POSITION_REPORT_C (0x47D + LOG_1X_BASE_C) + +/* GNSS PRX RF HW status report */ +#define LOG_GNSS_PRX_RF_HW_STATUS_REPORT_C (0x47E + LOG_1X_BASE_C) + +/* GNSS DRX RF HW status report */ +#define LOG_GNSS_DRX_RF_HW_STATUS_REPORT_C (0x47F + LOG_1X_BASE_C) + +/* GNSS Glonass Measurement report */ +#define LOG_GNSS_GLONASS_MEASUREMENT_REPORT_C (0x480 + LOG_1X_BASE_C) + +/* GNSS GPS HBW RXD measurement */ +#define LOG_GNSS_GPS_HBW_RXD_MEASUREMENT_C (0x481 + LOG_1X_BASE_C) + +/* GNSS PDSM position report callback */ +#define LOG_GNSS_PDSM_POSITION_REPORT_CALLBACK_C (0x482 + LOG_1X_BASE_C) + +/* ISense Request String */ +#define LOG_ISENSE_REQUEST_STR_C (0x483 + LOG_1X_BASE_C) + +/* ISense Response String */ +#define LOG_ISENSE_RESPONSE_STR_C (0x484 + LOG_1X_BASE_C) + +/* Bluetooth SOC General Log Packet*/ +#define LOG_BT_SOC_GENERAL_C (0x485 + LOG_1X_BASE_C) + +/* QCRil Call Flow */ +#define LOG_QCRIL_CALL_FLOW_C (0x486 + LOG_1X_BASE_C) + +/* CGPS Wideband FFT stats */ +#define LOG_CGPS_WB_FFT_STATS_C (0x487 + LOG_1X_BASE_C) + +/* CGPS Slow Clock Calibration Report*/ +#define LOG_CGPS_SLOW_CLOCK_CALIB_REPORT_C (0x488 + LOG_1X_BASE_C) + +/* SNS GPS TIMESTAMP */ +#define LOG_SNS_GPS_TIMESTAMP_C (0x489 + LOG_1X_BASE_C) + +/* GNSS Search Strategy Task Allocation */ +#define LOG_GNSS_SEARCH_STRATEGY_TASK_ALLOCATION_C (0x48A + LOG_1X_BASE_C) + +/* RF MC STM state */ +#define LOG_1XHDR_MC_STATE_C (0x48B + LOG_1X_BASE_C) + +/* Record in the Sparse Network DB */ +#define LOG_CGPS_SNDB_RECORD_C (0x48C + LOG_1X_BASE_C) + +/* Record removed from the DB */ +#define LOG_CGPS_SNDB_REMOVE_C (0x48D + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_GNSS_CC_PERFORMANCE_STATS_C (0x48E + LOG_1X_BASE_C) + +/* GNSS PDSM Set Paramerters */ +#define LOG_GNSS_PDSM_SET_PARAMETERS_C (0x48F + LOG_1X_BASE_C) + +/* GNSS PDSM PD Event Callback */ +#define LOG_GNSS_PDSM_PD_EVENT_CALLBACK_C (0x490 + LOG_1X_BASE_C) + +/* GNSS PDSM PA Event Callback */ +#define LOG_GNSS_PDSM_PA_EVENT_CALLBACK_C (0x491 + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_CGPS_RESERVED2_C (0x492 + LOG_1X_BASE_C) + +/* CGPS Reserved */ +#define LOG_CGPS_RESERVED3_C (0x493 + LOG_1X_BASE_C) + +/* GNSS PDSM EXT Status MEAS Report */ +#define LOG_GNSS_PDSM_EXT_STATUS_MEAS_REPORT_C (0x494 + LOG_1X_BASE_C) + +/* GNSS SM Error */ +#define LOG_GNSS_SM_ERROR_C (0x495 + LOG_1X_BASE_C) + +/* WLAN Scan */ +#define LOG_WLAN_SCAN_C (0x496 + LOG_1X_BASE_C) + +/* WLAN IBSS */ +#define LOG_WLAN_IBSS_C (0x497 + LOG_1X_BASE_C) + +/* WLAN 802.11d*/ +#define LOG_WLAN_80211D_C (0x498 + LOG_1X_BASE_C) + +/* WLAN Handoff */ +#define LOG_WLAN_HANDOFF_C (0x499 + LOG_1X_BASE_C) + +/* WLAN QoS EDCA */ +#define LOG_WLAN_QOS_EDCA_C (0x49A + LOG_1X_BASE_C) + +/* WLAN Beacon Update */ +#define LOG_WLAN_BEACON_UPDATE_C (0x49B + LOG_1X_BASE_C) + +/* WLAN Power save wow add pattern */ +#define LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C (0x49C + LOG_1X_BASE_C) + +/* WLAN WCM link metrics */ +#define LOG_WLAN_WCM_LINKMETRICS_C (0x49D + LOG_1X_BASE_C) + +/* WLAN wps scan complete*/ +#define LOG_WLAN_WPS_SCAN_COMPLETE_C (0x49E + LOG_1X_BASE_C) + +/* WLAN WPS WSC Message */ +#define LOG_WLAN_WPS_WSC_MESSAGE_C (0x49F + LOG_1X_BASE_C) + +/* WLAN WPS credentials */ +#define LOG_WLAN_WPS_CREDENTIALS_C (0x4A0 + LOG_1X_BASE_C) + +/* WLAN Linklayer stat*/ +#define LOG_WLAN_LINKLAYER_STAT_C (0x4A1 + LOG_1X_BASE_C) + +/* WLAN Qos TSpec*/ +#define LOG_WLAN_QOS_TSPEC_C (0x4A2 + LOG_1X_BASE_C) + +/* PMIC Vreg Control */ +#define LOG_PM_VREG_CONTROL_C (0x4A3 + LOG_1X_BASE_C) + +/* PMIC Vreg Level */ +#define LOG_PM_VREG_LEVEL_C (0x4A4 + LOG_1X_BASE_C) + +/* PMIC Vreg State */ +#define LOG_PM_VREG_STATE_C (0x4A5 + LOG_1X_BASE_C) + +/* CGPS SM EPH Randomization info */ +#define LOG_CGPS_SM_EPH_RANDOMIZATION_INFO_C (0x4A6 + LOG_1X_BASE_C) + +/* Audio calibration data */ +#define LOG_QACT_DATA_C (0x4A7 + LOG_1X_BASE_C) + +/* Compass 2D Tracked Calibration Set */ +#define LOG_SNS_VCPS_2D_TRACKED_CAL_SET (0x4A8 + LOG_1X_BASE_C) + +/* Compass 3D Tracked Calibration Set */ +#define LOG_SNS_VCPS_3D_TRACKED_CAL_SET (0x4A9 + LOG_1X_BASE_C) + +/* Calibration metric */ +#define LOG_SNS_VCPS_CAL_METRIC (0x4AA + LOG_1X_BASE_C) + +/* Accelerometer distance */ +#define LOG_SNS_VCPS_ACCEL_DIST (0x4AB + LOG_1X_BASE_C) + +/* Plane update */ +#define LOG_SNS_VCPS_PLANE_UPDATE (0x4AC + LOG_1X_BASE_C) + +/* Location report */ +#define LOG_SNS_VCPS_LOC_REPORT (0x4AD + LOG_1X_BASE_C) + +/* CM Active subscription */ +#define LOG_CM_PH_EVENT_SUBSCRIPTION_PREF_INFO_C (0x4AE + LOG_1X_BASE_C) + +/* DSDS version of CM call event */ +#define LOG_CM_DS_CALL_EVENT_C (0x4AF + LOG_1X_BASE_C) + +/* Sensors ?MobiSens Output */ +#define LOG_MOBISENS_OUTPUT_C (0x4B0 + LOG_1X_BASE_C) + +/* Accelerometer Data */ +#define LOG_ACCEL_DATA_C (0x4B1 + LOG_1X_BASE_C) + +/* Accelerometer Compensated Data */ +#define LOG_ACCEL_COMP_DATA_C (0x4B2 + LOG_1X_BASE_C) + +/* Motion State Data */ +#define LOG_MOTION_STATE_DATA_C (0x4B3 + LOG_1X_BASE_C) + +/* Stationary Position Indicator */ +#define LOG_STAT_POS_IND_C (0x4B4 + LOG_1X_BASE_C) + +/* Motion State Features */ +#define LOG_MOTION_STATE_FEATURES_C (0x4B5 + LOG_1X_BASE_C) + +/* Motion State Hard Decision */ +#define LOG_MOTION_STATE_HARD_DECISION_C (0x4B6 + LOG_1X_BASE_C) + +/* Motion State Soft Decision */ +#define LOG_MOTION_STATE_SOFT_DECISION_C (0x4B7 + LOG_1X_BASE_C) + +/* Sensors Software Version */ +#define LOG_SENSORS_SOFTWARE_VERSION_C (0x4B8 + LOG_1X_BASE_C) + +/* MobiSens Stationary Position Indicator Log Packet */ +#define LOG_MOBISENS_SPI_C (0x4B9 + LOG_1X_BASE_C) + +/* XO calibration raw IQ data */ +#define LOG_XO_IQ_DATA_C (0x4BA + LOG_1X_BASE_C) + +/*DTV CMMB Control Tabl Updated*/ +#define LOG_DTV_CMMB_CONTROL_TABLE_UPDATE ((0x4BB) + LOG_1X_BASE_C) + +/*DTV CMMB Media API Buffering Status*/ +#define LOG_DTV_CMMB_MEDIA_BUFFERING_STATUS ((0x4BC) + LOG_1X_BASE_C) + +/*DTV CMMB *Emergency Broadcast Data*/ +#define LOG_DTV_CMMB_CONTROL_EMERGENCY_BCAST ((0x4BD) + LOG_1X_BASE_C) + +/*DTV CMMB EMM/ECM Data*/ +#define LOG_DTV_CMMB_CAS_EMM_ECM ((0x4BE) + LOG_1X_BASE_C) + +/*DTV CMMB HW Status*/ +#define LOG_DTV_CMMB_HW_PERFORMANCE ((0x4BF) + LOG_1X_BASE_C) + +/*DTV CMMB ESSG Program Indication Information*/ +#define LOG_DTV_CMMB_ESG_PROGRAM_INDICATION_INFORMATION ((0x4C0) + LOG_1X_BASE_C) + +/* Sensors ¨C binary output of converted sensor data */ +#define LOG_CONVERTED_SENSOR_DATA_C ((0x4C1) + LOG_1X_BASE_C) + +/* CM Subscription event */ +#define LOG_CM_SUBSCRIPTION_EVENT_C ((0x4C2) + LOG_1X_BASE_C) + +/* Sensor Ambient Light Data */ +#define LOG_SNS_ALS_DATA_C ((0x4C3) + LOG_1X_BASE_C) + +/*Sensor Ambient Light Adaptive Data */ +#define LOG_SNS_ALS_DATA_ADAPTIVE_C ((0x4C4) + LOG_1X_BASE_C) + +/*Sensor Proximity Distance Data */ +#define LOG_SNS_PRX_DIST_DATA_C ((0x4C5) + LOG_1X_BASE_C) + +/*Sensor Proximity Data */ +#define LOG_SNS_PRX_DATA_C ((0x4C6) + LOG_1X_BASE_C) + +#define LOG_GNSS_SBAS_REPORT_C ((0x4C7) + LOG_1X_BASE_C) + +#define LOG_CPU_MONITOR_MODEM_C ((0x4C8) + LOG_1X_BASE_C) + +#define LOG_CPU_MONITOR_APPS_C ((0x4C9) + LOG_1X_BASE_C) + +#define LOG_BLAST_TASKPROFILE_C ((0x4CA) + LOG_1X_BASE_C) + +#define LOG_BLAST_SYSPROFILE_C ((0x4CB) + LOG_1X_BASE_C) + +#define LOG_FM_RADIO_FTM_C ((0x4CC) + LOG_1X_BASE_C) + +#define LOG_FM_RADIO_C ((0x4CD) + LOG_1X_BASE_C) + +#define LOG_UIM_DS_DATA_C ((0x4CE) + LOG_1X_BASE_C) + +#define LOG_QMI_CALL_FLOW_C ((0x4CF) + LOG_1X_BASE_C) + +#define LOG_APR_MODEM_C ((0x4D0) + LOG_1X_BASE_C) + +#define LOG_APR_APPS_C ((0x4D1) + LOG_1X_BASE_C) + +#define LOG_APR_ADSP_C ((0x4D2) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_RX_RAW_PACKET_C ((0x4D3) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_TX_RAW_PACKET_C ((0x4D4) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_RX_FRAME_PACKET_C ((0x4D5) + LOG_1X_BASE_C) + +#define LOG_DATA_MUX_TX_FRAME_PACKET_C ((0x4D6) + LOG_1X_BASE_C) + +#define LOG_CGPS_PDSM_EXT_STATUS_POS_INJ_REQ_INFO_C ((0x4D7) + LOG_1X_BASE_C) + +#define LOG_TEMPERATURE_MONITOR_C ((0x4D8) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_REST_DETECT_C ((0x4D9) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_ORIENTATION_C ((0x4DA) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_FACING_C ((0x4DB) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_BASIC_C ((0x4DC) + LOG_1X_BASE_C) + +#define LOG_SNS_GESTURES_HINBYE_C ((0x4DD) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_MEASUREMENT_REPORT_C ((0x4DE) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_POSITION_REPORT_C ((0x4E0) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRE_SVPOLY_REPORT_C ((0x4E1) + LOG_1X_BASE_C) + +#define LOG_GNSS_OEMDRSYNC_C ((0x4E2) + LOG_1X_BASE_C) + +#define LOG_SNS_MGR_EVENT_NOTIFY_C ((0x4E3) + LOG_1X_BASE_C) + +#define LOG_SNS_MGR_EVENT_REGISTER_C ((0x4E4) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_BEGIN_C ((0x4E5) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_PPM_SUSPEND_C ((0x4E6) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_REPORT_THROTTLED_C ((0x4E7) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_REPORT_FIRED_C ((0x4E8) + LOG_1X_BASE_C) + +#define LOG_GNSS_PDSM_PPM_SESSION_END_C ((0x4E9) + LOG_1X_BASE_C) + +#define LOG_TRSP_DATA_STALL_C ((0x801) + LOG_1X_BASE_C) + +#define LOG_WLAN_PKT_LOG_INFO_C ((0x8E0) + LOG_1X_BASE_C) + + +/* The last defined DMSS log code */ +#define LOG_1X_LAST_C ((0x8E0) + LOG_1X_BASE_C) + + +/* This is only here for old (pre equipment ID update) logging code */ +#define LOG_LAST_C ( LOG_1X_LAST_C & 0xFFF ) + + +/* ------------------------------------------------------------------------- + * APPS LOG definition: + * The max number of 16 log codes is assigned for Apps. + * The last apps log code could be 0xB00F. + * Below definition is consolidated from log_codes_apps.h + * ------------------------------------------------------------------------- */ + +/* ======================== APPS Profiling ======================== */ +#define LOG_APPS_SYSPROFILE_C (0x01 + LOG_APPS_BASE_C) +#define LOG_APPS_TASKPROFILE_C (0x02 + LOG_APPS_BASE_C) + +/* The last defined APPS log code */ +/* Change it to (0x02 + LOG_LTE_LAST_C) to allow LTE log codes */ +#define LOG_APPS_LAST_C (0x02 + LOG_LTE_LAST_C) + +/* ------------------------------------------------------------------------- + * Log Equipment IDs. + * The number is represented by 4 bits. + * ------------------------------------------------------------------------- */ +typedef enum { + LOG_EQUIP_ID_OEM = 0, /* 3rd party OEM (licensee) use */ + LOG_EQUIP_ID_1X = 1, /* Traditional 1X line of products */ + LOG_EQUIP_ID_RSVD2 = 2, + LOG_EQUIP_ID_RSVD3 = 3, + LOG_EQUIP_ID_WCDMA = 4, + LOG_EQUIP_ID_GSM = 5, + LOG_EQUIP_ID_LBS = 6, + LOG_EQUIP_ID_UMTS = 7, + LOG_EQUIP_ID_TDMA = 8, + LOG_EQUIP_ID_BOA = 9, + LOG_EQUIP_ID_DTV = 10, + LOG_EQUIP_ID_APPS = 11, + LOG_EQUIP_ID_DSP = 12, + + LOG_EQUIP_ID_LAST_DEFAULT = LOG_EQUIP_ID_DSP + +} log_equip_id_enum_type; + +#define LOG_EQUIP_ID_MAX 0xF /* The equipment ID is 4 bits */ + +/* Note that these are the official values and are used by default in + diagtune.h. +*/ +#define LOG_EQUIP_ID_0_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_1_LAST_CODE_DEFAULT LOG_1X_LAST_C +#define LOG_EQUIP_ID_2_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_3_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_4_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_5_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_6_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_7_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_8_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_9_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_10_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_11_LAST_CODE_DEFAULT LOG_LTE_LAST_C +#define LOG_EQUIP_ID_12_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_13_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_14_LAST_CODE_DEFAULT 0 +#define LOG_EQUIP_ID_15_LAST_CODE_DEFAULT 0 + +#endif /* LOG_CODES_H */ diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_api.h b/drivers/staging/prima/CORE/VOSS/inc/vos_api.h new file mode 100644 index 000000000000..5c7fd8c0e7c6 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_api.h @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_API_H ) +#define __VOS_API_H + +/**========================================================================= + + \file vos_Api.h + + \brief virtual Operating System Services (vOSS) API + + Header file that inludes all the vOSS API definitions. + + + ========================================================================*/ + /*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 06/23/08 hba Added vos_preOpen() + 05/18/08 lac Created module. +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +// one stop shopping. This brings in the entire vOSS API. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * enum userspace_log_level - Log level at userspace + * @LOG_LEVEL_NO_COLLECTION: verbose_level 0 corresponds to no collection + * @LOG_LEVEL_NORMAL_COLLECT: verbose_level 1 correspond to normal log level, + * with minimal user impact. this is the default value + * @LOG_LEVEL_ISSUE_REPRO: verbose_level 2 are enabled when user is lazily + * trying to reproduce a problem, wifi performances and power can be impacted + * but device should not otherwise be significantly impacted + * @LOG_LEVEL_ACTIVE: verbose_level 3+ are used when trying to + * actively debug a problem + * + * Various log levels defined in the userspace for logging applications + */ +enum userspace_log_level { + LOG_LEVEL_NO_COLLECTION, + LOG_LEVEL_NORMAL_COLLECT, + LOG_LEVEL_ISSUE_REPRO, + LOG_LEVEL_ACTIVE, +}; + +/** + * enum wifi_driver_log_level - Log level defined in the driver for logging + * @WLAN_LOG_LEVEL_OFF: No logging + * @WLAN_LOG_LEVEL_NORMAL: Default logging + * @WLAN_LOG_LEVEL_REPRO: Normal debug level + * @WLAN_LOG_LEVEL_ACTIVE: Active debug level + * + * Log levels defined for logging by the wifi driver + */ +enum wifi_driver_log_level { + WLAN_LOG_LEVEL_OFF, + WLAN_LOG_LEVEL_NORMAL, + WLAN_LOG_LEVEL_REPRO, + WLAN_LOG_LEVEL_ACTIVE, +}; + +/** + * enum wifi_logging_ring_id - Ring id of logging entities + * @RING_ID_WAKELOCK: Power events ring id + * @RING_ID_CONNECTIVITY: Connectivity event ring id + * @RING_ID_PER_PACKET_STATS: Per packet statistic ring id + * + * This enum has the ring id values of logging rings + */ +enum wifi_logging_ring_id { + RING_ID_WAKELOCK, + RING_ID_CONNECTIVITY, + RING_ID_PER_PACKET_STATS, +}; + +/* 15 Min */ +#define WLAN_POWER_COLLAPSE_FAIL_THRESHOLD (1000 * 60 * 15) +/** + * enum log_event_type - Type of event initiating bug report + * @WLAN_LOG_TYPE_NON_FATAL: Non fatal event + * @WLAN_LOG_TYPE_FATAL: Fatal event + * + * Enum indicating the type of event that is initiating the bug report + */ +enum log_event_type { + WLAN_LOG_TYPE_NON_FATAL, + WLAN_LOG_TYPE_FATAL, +}; + +/** + * enum log_event_indicator - Module triggering bug report + * @WLAN_LOG_INDICATOR_UNUSED: Unused + * @WLAN_LOG_INDICATOR_FRAMEWORK: Framework triggers bug report + * @WLAN_LOG_INDICATOR_HOST_DRIVER: Host driver triggers bug report + * @WLAN_LOG_INDICATOR_FIRMWARE: FW initiates bug report + * @WLAN_LOG_INDICATOR_IOCTL: Bug report is initiated by IOCTL + * @WLAN_LOG_INDICATOR_HOST_ONLY: Host initiated and only Host + * logs are needed + * + * Enum indicating the module that triggered the bug report + */ +enum log_event_indicator { + WLAN_LOG_INDICATOR_UNUSED, + WLAN_LOG_INDICATOR_FRAMEWORK, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_INDICATOR_FIRMWARE, + WLAN_LOG_INDICATOR_IOCTL, + WLAN_LOG_INDICATOR_HOST_ONLY, +}; + +/** + * enum log_event_host_reason_code - Reason code for bug report + * @WLAN_LOG_REASON_CODE_UNUSED: Unused + * @WLAN_LOG_REASON_ROAM_FAIL: Driver initiated roam has failed + * @WLAN_LOG_REASON_THREAD_STUCK: Monitor Health of host threads and report + * fatal event if some thread is stuck + * @WLAN_LOG_REASON_DATA_STALL: Unable to send/receive data due to low resource + * scenario for a prolonged period + * @WLAN_LOG_REASON_SME_COMMAND_STUCK: SME command is stuck in SME active queue + * @WLAN_LOG_REASON_QUEUE_FULL: Defer queue becomes full for a prolonged period + * @WLAN_LOG_REASON_POWER_COLLAPSE_FAIL: Unable to allow apps power collapse + * for a prolonged period + * @WLAN_LOG_REASON_MALLOC_FAIL: Memory allocation Fails + * @WLAN_LOG_REASON_VOS_MSG_UNDER_RUN: VOS Core runs out of message wrapper + * @WLAN_LOG_REASON_IOCTL: Initiated by IOCTL + * @WLAN_LOG_REASON_CODE_FRAMEWORK: Initiated by framework + * @WLAN_LOG_REASON_DEL_BSS_STA_FAIL: DEL BSS/STA rsp is failure + * @WLAN_LOG_REASON_ADD_BSS_STA_FAIL: ADD BSS/STA rsp is failure + * @WLAN_LOG_REASON_ENTER_IMPS_BMPS_FAIL: Enter IMPS/BMPS rsp failure + * @WLAN_LOG_REASON_EXIT_IMPS_BMPS_FAIL: Exit IMPS/BMPS rsp failure + * @WLAN_LOG_REASON_HDD_TIME_OUT: Wait for event Timeout in HDD layer + * @WLAN_LOG_REASON_MGMT_FRAME_TIMEOUT:Management frame timedout + * @WLAN_LOG_REASON_SME_OUT_OF_CMD_BUFL sme out of cmd buffer + * @WLAN_LOG_REASON_SCAN_NOT_ALLOWED: scan not allowed due to connection states + * This enum contains the different reason codes for bug report + */ +enum log_event_host_reason_code { + WLAN_LOG_REASON_CODE_UNUSED, + WLAN_LOG_REASON_ROAM_FAIL, + WLAN_LOG_REASON_THREAD_STUCK, + WLAN_LOG_REASON_DATA_STALL, + WLAN_LOG_REASON_SME_COMMAND_STUCK, + WLAN_LOG_REASON_QUEUE_FULL, + WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, + WLAN_LOG_REASON_MALLOC_FAIL, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + WLAN_LOG_REASON_IOCTL, + WLAN_LOG_REASON_CODE_FRAMEWORK, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + WLAN_LOG_REASON_ENTER_IMPS_BMPS_FAIL, + WLAN_LOG_REASON_EXIT_IMPS_BMPS_FAIL, + WLAN_LOG_REASON_HDD_TIME_OUT, + WLAN_LOG_REASON_MGMT_FRAME_TIMEOUT, + WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF, + WLAN_LOG_REASON_SCAN_NOT_ALLOWED, +}; + +/** + * vos_wdi_trace_event_type: Trace type for WDI Write/Read + * VOS_WDI_READ: Log the WDI read event + * VOS_WDI_WRITE: Log the WDI write event + */ +typedef enum +{ + VOS_WDI_READ, + VOS_WDI_WRITE, +} vos_wdi_trace_event_type; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/**-------------------------------------------------------------------------- + + \brief vos_preOpen() - PreOpen the vOSS Module + + The \a vos_preOpen() function allocates the Vos Context, but do not + initialize all the members. This overal initialization will happen + at vos_Open(). + The reason why we need vos_preOpen() is to get a minimum context + where to store BAL and SAL relative data, which happens before + vos_Open() is called. + + \param pVosContext: A pointer to where to store the VOS Context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preOpen ( v_CONTEXT_t *pVosContext ); + +VOS_STATUS vos_preClose( v_CONTEXT_t *pVosContext ); + + +VOS_STATUS vos_preStart( v_CONTEXT_t vosContext ); + + +VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, void *devHandle ); + +VOS_STATUS vos_mon_start( v_CONTEXT_t vosContext ); + +VOS_STATUS vos_mon_stop( v_CONTEXT_t vosContext ); + +VOS_STATUS vos_start( v_CONTEXT_t vosContext ); + +VOS_STATUS vos_stop( v_CONTEXT_t vosContext ); + +VOS_STATUS vos_close( v_CONTEXT_t vosContext ); + +/* vos shutdown will not close control transport and will not handshake with Riva */ +VOS_STATUS vos_shutdown( v_CONTEXT_t vosContext ); + +/* the wda interface to shutdown */ +VOS_STATUS vos_wda_shutdown( v_CONTEXT_t vosContext ); + +/**--------------------------------------------------------------------------- + + \brief vos_get_context() - get context data area + + Each module in the system has a context / data area that is allocated + and maanged by voss. This API allows any user to get a pointer to its + allocated context data area from the VOSS global context. + + \param vosContext - the VOSS Global Context. + + \param moduleId - the module ID, who's context data are is being retrived. + + \return - pointer to the context data area. + + - NULL if the context data is not allocated for the module ID + specified + + --------------------------------------------------------------------------*/ +v_VOID_t *vos_get_context( VOS_MODULE_ID moduleId, + v_CONTEXT_t vosContext ); + + +/**--------------------------------------------------------------------------- + + \brief vos_get_global_context() - get VOSS global Context + + This API allows any user to get the VOS Global Context pointer from a + module context data area. + + \param moduleContext - the input module context pointer + + \param moduleId - the module ID who's context pointer is input in + moduleContext. + + \return - pointer to the VOSS global context + + - NULL if the function is unable to retreive the VOSS context. + + --------------------------------------------------------------------------*/ +v_CONTEXT_t vos_get_global_context( VOS_MODULE_ID moduleId, + v_VOID_t *moduleContext ); + +v_U8_t vos_is_logp_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext); +void vos_set_logp_in_progress(VOS_MODULE_ID moduleId, v_U8_t value); + +v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext); +void vos_set_load_unload_in_progress(VOS_MODULE_ID moduleId, v_U8_t value); + +v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext); +void vos_set_reinit_in_progress(VOS_MODULE_ID moduleId, v_U8_t value); +VOS_STATUS vos_logger_pkt_serialize(vos_pkt_t *pPacket, uint32 pkt_type); +bool vos_is_log_report_in_progress(void); +void vos_reset_log_report_in_progress(void); +int vos_set_log_completion(uint32 is_fatal, uint32 indicator, uint32 reason_code); +void vos_get_log_and_reset_completion(uint32 *is_fatal, + uint32 *indicator, uint32 *reason_code, bool reset); +v_BOOL_t vos_isFatalEventEnabled(void); +VOS_STATUS vos_fatal_event_logs_req( uint32_t is_fatal, uint32_t indicator, + uint32_t reason_code, bool wait_required, + bool dump_vos_trace); +VOS_STATUS vos_process_done_indication(v_U8_t type, v_U32_t reason_code); +void vos_flush_host_logs_for_fatal(void); + +void vos_send_fatal_event_done(void); + + +/**--------------------------------------------------------------------------- + + \brief vos_alloc_context() - allocate a context within the VOSS global Context + + This API allows any user to allocate a user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being allocated. + + \param ppModuleContext - pointer to location where the pointer to the + allocated context is returned. Note this + output pointer is valid only if the API + returns VOS_STATUS_SUCCESS + + \param size - the size of the context area to be allocated. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + allocated successfully. The pointer to the context area + can be found in *ppModuleContext. + \note This function returns VOS_STATUS_SUCCESS if the + module context was already allocated and the size + allocated matches the size on this call. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context allocated. + + VOS_STATUS_E_EXISTS - vos could allocate the requested context + because a context for this module ID already exists and it is + a *different* size that specified on this call. + + VOS_STATUS_E_NOMEM - vos could not allocate memory for the + requested context area. + + \sa vos_get_context(), vos_free_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_alloc_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t **ppModuleContext, v_SIZE_t size ); + + +/**--------------------------------------------------------------------------- + + \brief vos_free_context() - free an allocated a context within the + VOSS global Context + + This API allows a user to free the user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being free + + \param pModuleContext - pointer to module context area to be free'd. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + free'd. The pointer to the context area is not longer + available. + + VOS_STATUS_E_FAULT - pVosContext or pModuleContext are not + valid pointers. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context free'd. + + VOS_STATUS_E_EXISTS - vos could not free the requested + context area because a context for this module ID does not + exist in the global vos context. + + \sa vos_get_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_free_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t *pModuleContext ); +v_BOOL_t vos_is_apps_power_collapse_allowed(void* pHddCtx); + +/** + @brief vos_wlanShutdown() - This API will shutdown WLAN driver + + This function is called when Riva subsystem crashes. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Called when Riva goes down, this will shutdown WLAN + driver without handshaking with Riva. + 2. re-init: Next API + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanShutdown(void); + +/** + @brief vos_wlanReInit() - This API will re-init WLAN driver + + This function is called when Riva subsystem reboots. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Previous API + 2. re-init: Called when Riva comes back after the crash. This will + re-initialize WLAN driver. In some cases re-open may be + referred instead of re-init. + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanReInit(void); + +/** + @brief vos_wlanRestart() - This API will reload WLAN driver. + + This function is called if driver detects any fatal state which + can be recovered by a WLAN module reload ( Android framwork initiated ). + Note that this API will not initiate any RIVA subsystem restart. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanRestart(void); + +/** + @brief vos_fwDumpReq() + + This function is called to issue dump commands to Firmware + + @param + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + async - asynchronous event. Don't wait for completion. + @return + NONE +*/ +v_VOID_t vos_fwDumpReq(tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, tANI_U8 async); + +v_VOID_t vos_flush_work(struct work_struct *work); +v_VOID_t vos_flush_delayed_work(struct delayed_work *dwork); + +v_VOID_t vos_init_work(struct work_struct *work , void *callbackptr); +v_VOID_t vos_init_delayed_work(struct delayed_work *dwork , void *callbackptr); + +v_U64_t vos_get_monotonic_boottime(void); + +VOS_STATUS vos_randomize_n_bytes(void *mac_addr, tANI_U32 n); + +v_BOOL_t vos_is_wlan_in_badState(VOS_MODULE_ID moduleId, + v_VOID_t *moduleContext); +v_VOID_t vos_set_roam_delay_stats_enabled(v_U8_t value); +v_U8_t vos_get_roam_delay_stats_enabled(v_VOID_t); +v_U32_t vos_get_dxeReplenishRXTimerVal(void); +v_BOOL_t vos_get_dxeSSREnable(void); + +v_U8_t vos_is_fw_logging_enabled(void); +v_U8_t vos_is_fw_ev_logging_enabled(void); + +v_U8_t vos_is_fw_logging_supported(void); +void vos_set_multicast_logging(uint8_t value); +v_U8_t vos_is_multicast_logging(void); +void vos_set_ring_log_level(v_U32_t ring_id, v_U32_t log_level); +v_U8_t vos_get_ring_log_level(v_U32_t ring_id); +void get_rate_and_MCS(per_packet_stats *stats, uint32 rateindex); + +v_BOOL_t vos_isUnloadInProgress(void); +v_BOOL_t vos_isLoadUnloadInProgress(void); + +bool vos_get_rx_wow_dump(void); +void vos_set_rx_wow_dump(bool value); + +void vos_set_hdd_bad_sta(uint8_t sta_id); +void vos_reset_hdd_bad_sta(uint8_t sta_id); + +void vos_probe_threads(void); +void vos_per_pkt_stats_to_user(void *perPktStat); +void vos_updatePktStatsInfo(void * pktStat); +bool vos_is_wlan_logging_enabled(void); + +v_BOOL_t vos_is_probe_rsp_offload_enabled(void); +void vos_set_snoc_high_freq_voting(bool enable); +void vos_smd_dump_stats(void); +void vos_log_wdi_event(uint16 msg, vos_wdi_trace_event_type event); +void vos_dump_wdi_events(void); + +bool vos_check_arp_target_ip(vos_pkt_t *pPacket); +void vos_update_arp_fw_tx_delivered(void); +void vos_update_arp_rx_drop_reorder(void); +#endif // if !defined __VOS_NVITEM_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h b/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h new file mode 100644 index 000000000000..ac7b39b2aea2 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_event.h @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_DIAG_CORE_EVENT_H ) +#define __VOS_DIAG_CORE_EVENT_H + +/**========================================================================= + + \file vos_event.h + + \brief virtual Operating System Services (vOSS) DIAG Events + + Definitions for vOSS Events + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "vos_pack_align.h" +#include "i_vos_diag_core_event.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define WAKE_LOCK_NAME_LEN 80 + + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_SECURITY + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t authMode; + v_U8_t encryptionModeUnicast; + v_U8_t encryptionModeMulticast; + v_U8_t pmkIDMatch; + v_U8_t bssid[6]; + v_U8_t keyId; + v_U8_t status; +} vos_event_wlan_security_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_STATUS_V2 + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t ssid[32]; + v_U8_t bssType; + v_U8_t rssi; + v_U8_t channel; + v_U8_t qosCapability; + v_U8_t authType; + v_U8_t encryptionType; + v_U8_t reason; + v_U8_t reasonDisconnect; +} vos_event_wlan_status_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_HANDOFF + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t currentApBssid[6]; + v_U8_t currentApRssi; + v_U8_t candidateApBssid[6]; + v_U8_t candidateApRssi; +} vos_event_wlan_handoff_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_VCC + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t rssi; + v_U8_t txPer; + v_U8_t rxPer; + int linkQuality; +} vos_event_wlan_vcc_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_QOS + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t reasonCode; +} vos_event_wlan_qos_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_PE + ------------------------------------------------------------------------*/ +typedef struct +{ + char bssid[6]; + v_U16_t event_type; + v_U16_t sme_state; + v_U16_t mlm_state; + v_U16_t status; + v_U16_t reason_code; +} vos_event_wlan_pe_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucBaBufferSize; + v_U16_t usBaSSN; + v_U8_t fInitiator; +} vos_event_wlan_add_block_ack_success_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_ADD_BLOCK_ACK_FAILED + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucReasonCode; + v_U8_t fInitiator; +} vos_event_wlan_add_block_ack_failed_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_DELETE_BLOCK_ACK_SUCCESS + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucDeleteReasonCode; +} vos_event_wlan_add_block_ack_deleted_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_DELETE_BLOCK_ACK_FAILED + ------------------------------------------------------------------------*/ +typedef struct +{ + char ucBaPeerMac[6]; + v_U8_t ucBaTid; + v_U8_t ucDeleteReasonCode; + v_U8_t ucFailReasonCode; +} vos_event_wlan_add_block_ack_delete_failed_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BSS_PROTECTION + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t event_type; + v_U8_t prot_type; +} vos_event_wlan_bss_prot_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BRINGUP_STATUS + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U16_t wlanStatus; + char driverVersion[10]; +} vos_event_wlan_bringup_status_payload_type; + +VOS_PACK_START + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_POWERSAVE_GENERIC + ------------------------------------------------------------------------*/ +typedef VOS_PACK_PRE struct +{ + v_U8_t event_subtype; + v_U32_t imps_period; + v_U8_t full_power_request_reason; + v_U8_t pmc_current_state; + v_U8_t enable_disable_powersave_mode; + v_U8_t winmob_d_power_state; + v_U8_t dtim_period; + v_U16_t final_listen_intv; + v_U16_t bmps_auto_timer_duration; + v_U16_t bmps_period; +} VOS_PACK_POST vos_event_wlan_powersave_payload_type; + +VOS_PACK_END + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_POWERSAVE_WOW + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t event_subtype; + v_U8_t wow_type; + v_U8_t wow_magic_pattern[6]; + v_U8_t wow_del_ptrn_id; + v_U8_t wow_wakeup_cause; + v_U8_t wow_wakeup_cause_pbm_ptrn_id; +} vos_event_wlan_powersave_wow_payload_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_BTC + ------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t eventId; + v_U8_t btAddr[6]; + v_U16_t connHandle; + v_U8_t connStatus; + v_U8_t linkType; + v_U8_t scoInterval; + v_U8_t scoWindow; + v_U8_t retransWindow; + v_U8_t mode; +} vos_event_wlan_btc_type; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_EAPOL + ------------------------------------------------------------------------*/ +struct vos_event_wlan_eapol +{ + uint8_t event_sub_type; + uint8_t eapol_packet_type; + uint16_t eapol_key_info; + uint16_t eapol_rate; + uint8_t dest_addr[6]; + uint8_t src_addr[6]; +}; +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_WAKE_LOCK + ------------------------------------------------------------------------*/ +/* + * struct vos_event_wlan_wake_lock - Structure holding the wakelock information + * @status: Whether the wakelock is taken/released + * @reason: Reason for taking this wakelock + * @timeout: Timeout value in case of timed wakelocks + * @name_len: Length of the name of the wakelock that will follow + * @name: Name of the wakelock + * + * This structure will hold the wakelock informations + */ +struct vos_event_wlan_wake_lock +{ + uint32_t status; + uint32_t reason; + uint32_t timeout; + uint32_t name_len; + char name[WAKE_LOCK_NAME_LEN]; +}; + +/** + * struct vos_event_tdls_teardown - tdls teardown diag event + * @reason: reason for tear down + * @peer_mac: peer mac + * + * This structure contain tdls teardown diag event info + */ + +struct vos_event_tdls_teardown { + uint32_t reason; + uint8_t peer_mac[6]; +}; + +/** + * struct vos_event_tdls_enable_link - tdls enable link event + * @peer_mac: peer mac + * @is_off_chan_supported: if off channel supported + * @is_off_chan_configured: if off channel configured + * @is_off_chan_established: if off channel established + * + * This structure contain tdls enable link diag event info + */ +struct vos_event_tdls_enable_link { + uint8_t peer_mac[6]; + uint8_t is_off_chan_supported; + uint8_t is_off_chan_configured; + uint8_t is_off_chan_established; +}; + +/** + * struct vos_event_suspend - suspend/resume state + * @state: suspend/resume state + * + * This structure contains suspend resume diag event info + */ + +struct vos_event_suspend { + uint8_t state; +}; + +/** + * struct vos_event_offload_req - offload state + * @offload_type: offload type + * @state: enabled or disabled state + * + * This structure contains offload diag event info + */ + +struct vos_event_offload_req { + uint8_t offload_type; + uint8_t state; +}; + +/** + * struct vos_event_tdls_scan_rejected - scan + * rejected due to tdls + * @status: rejected status + * + * This structure contains scan rejected due to + * tdls event info + */ +struct vos_event_tdls_scan_rejected { + uint8_t status; +}; + +/** + * struct vos_event_tx_rx_mgmt - for TX RX management frame + * @event_id: event ID + * @tx_rx: tx or rx + * @type: type of frame + * @action_sub_type: action frame type + * @peer_mac: peer mac + * + * This structure contains tdls TX RX management frame info + */ +struct vos_event_tx_rx_mgmt { + uint8_t event_id; + uint8_t tx_rx; + uint8_t type; + uint8_t action_sub_type; + uint8_t peer_mac[6]; +}; + + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_LOG_COMPLETE + ------------------------------------------------------------------------*/ +/** + * struct vos_event_wlan_log_complete - Holds log completion details + * @is_fatal: Indicates if the event is fatal or not + * @indicator: Source of the bug report - Framework/Host/Firmware + * @reason_code: Reason for triggering bug report + * @reserved: Reserved field + * + * This structure holds the log completion related information + */ +struct vos_event_wlan_log_complete { + uint32_t is_fatal; + uint32_t indicator; + uint32_t reason_code; + uint32_t reserved; +}; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_SSR_REINIT_SUBSYSTEM + ------------------------------------------------------------------------*/ +/** + * struct host_event_wlan_css - Holds diag event details + * @status: Indicates the status of event + * + * This structure holds the host diag event related information + */ + +struct host_event_wlan_ssr_reinit { + uint32_t status; +}; + +/*------------------------------------------------------------------------- + Event ID: EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM + ------------------------------------------------------------------------*/ +/** + * struct host_event_wlan_ssr_shutdown - Holds diag event details + * @status: Indicates the status of event + * + * This structure holds the host diag event related information + */ + +struct host_event_wlan_ssr_shutdown { + uint32_t status; +}; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +/** + * enum host_ssr_events - Enum containing ssr subtype + * @SSR_SUB_SYSTEM_REINIT: Indicate ssr reinit state + * @SSR_SUB_SYSTEM_SHUTDOWN: Indicate ssr shutdown state + * + */ +enum host_ssr_events { + SSR_SUB_SYSTEM_REINIT, + SSR_SUB_SYSTEM_SHUTDOWN, +}; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +enum wifi_connectivity_events { + WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED, + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED, +}; + +/* + * enum wake_lock_reason - Reason for taking wakelock +* @WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT: Driver initialization + * @WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT: Driver re-initialization + * @WIFI_POWER_EVENT_WAKELOCK_SCAN: Scan request/response handling + * @WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN: Driver resume + * @WIFI_POWER_EVENT_WAKELOCK_ROC: Remain on channel request/response handling + * @WIFI_POWER_EVENT_WAKELOCK_HOLD_RX: Wakelocks taken for receive + * @WIFI_POWER_EVENT_WAKELOCK_SAP: SoftAP related wakelocks + * This enum has the reason codes why the wakelocks were taken/released + */ +enum wake_lock_reason { + WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT, + WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT, + WIFI_POWER_EVENT_WAKELOCK_SCAN, + WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN, + WIFI_POWER_EVENT_WAKELOCK_ROC, + WIFI_POWER_EVENT_WAKELOCK_HOLD_RX, + WIFI_POWER_EVENT_WAKELOCK_SAP, + WIFI_POWER_EVENT_WAKELOCK_FIND_AP_INDICATION, +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __VOS_DIAG_CORE_EVENT_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_log.h b/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_log.h new file mode 100644 index 000000000000..adf6b2f1d342 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_diag_core_log.h @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_DIAG_CORE_LOG_H ) +#define __VOS_DIAG_CORE_LOG_H + +/**========================================================================= + + \file vos_event.h + + \brief virtual Operating System Services (vOSS) DIAG logs + + Definitions for vOSS Events + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "i_vos_diag_core_log.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_LOG_MAX_NUM_SSID 21 +#define VOS_LOG_MAX_NUM_BSSID 21 +#define VOS_LOG_MAX_SSID_SIZE 32 +#define VOS_LOG_MAX_BSSID_SIZE 6 +#define VOS_LOG_MAX_NUM_CHANNEL 64 +#define VOS_LOG_MAX_NUM_HO_CANDIDATE_APS 20 +#define VOS_LOG_MAX_WOW_PTRN_SIZE 128 +#define VOS_LOG_MAX_WOW_PTRN_MASK_SIZE 16 +/* Version to be updated whenever format of vos_log_pktlog_info changes */ +#define VERSION_LOG_WLAN_PKT_LOG_INFO_C 1 + +enum { + PKTLOG_FLG_FRM_TYPE_LOCAL_S = 0, + PKTLOG_FLG_FRM_TYPE_REMOTE_S, + PKTLOG_FLG_FRM_TYPE_UNKNOWN_S +}; + +/* Format of the packet stats event*/ +typedef struct { + v_U16_t flags; + v_U16_t missed_cnt; + v_U16_t log_type; + v_U16_t size; + v_U32_t timestamp; +}__attribute__((packed))pkt_stats_hdr ; + +/* Per packet data info */ +#define PER_PACKET_ENTRY_FLAGS_DIRECTION_TX 1 // 0: TX, 1: RX +#define PER_PACKET_ENTRY_FLAGS_TX_SUCCESS 2 // whether packet was transmitted or + // received/decrypted successfully +#define PER_PACKET_ENTRY_FLAGS_80211_HEADER 4 // has full 802.11 header, else has 802.3 header +#define PER_PACKET_ENTRY_FLAGS_PROTECTED 8 // whether packet was encrypted +#define STATS_MAX_RATE_INDEX 136 + + +enum { + S_BW20, + S_BW40, + S_BW80, + S_BW160 +}; +enum { + PREAMBLE_CCK, + PREAMBLE_OFDM, + PREAMBLE_HT, + PREAMBLE_VHT +}; + +typedef struct{ + v_U16_t rate; + v_U16_t preamble; + v_U8_t bw; + v_U8_t short_gi; +}rateidx_to_rate_bw_preamble_sgi; + + +typedef struct { + v_U16_t rate : 4; + v_U16_t nss : 2; + v_U16_t preamble : 2; + v_U16_t bw : 2; + v_U16_t short_gi : 1; + v_U16_t reserved : 5; +} mcs_stats; + +typedef struct { + v_U8_t flags; + v_U8_t tid; // transmit or received tid + mcs_stats MCS; // modulation and bandwidth + v_S7_t rssi; // TX: RSSI of ACK for that packet + // RX: RSSI of packet + v_U8_t num_retries; // number of attempted retries + v_U16_t last_transmit_rate; // last transmit rate in .5 mbps + v_U16_t link_layer_transmit_sequence; // receive sequence for that MPDU packet + v_U64_t dxe_timestamp; // DXE timestamp + v_U64_t start_contention_timestamp; // 0 Not supported + v_U64_t transmit_success_timestamp; // 0 Not Supported + /* Whole frame for management/EAPOl/DHCP frames and 802.11 + LLC + * header + 40 bytes or full frame whichever is smaller for + * remaining Data packets + */ + v_U8_t data[MAX_PKT_STAT_DATA_LEN]; +} __attribute__((packed)) per_packet_stats; + +typedef struct +{ + pkt_stats_hdr ps_hdr; + per_packet_stats stats; +}tx_rx_pkt_stats; + + +/*--------------------------------------------------------------------------- + This packet contains the scan results of the recent scan operation + LOG_WLAN_SCAN_C 0x1496 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t eventId; + v_U8_t numSsid; + v_U8_t ssid[VOS_LOG_MAX_NUM_SSID][VOS_LOG_MAX_SSID_SIZE]; + v_U8_t bssid[VOS_LOG_MAX_NUM_BSSID][VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t totalSsid; + v_U8_t minChnTime; + v_U8_t maxChnTime; + v_U16_t timeBetweenBgScan; + v_U8_t BSSMode; + v_U8_t numChannel; + v_U8_t channels[VOS_LOG_MAX_NUM_CHANNEL]; + v_U16_t status; +} vos_log_scan_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to IBSS connection setup + LOG_WLAN_IBSS_C 0x1497 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t eventId; + v_U8_t channelSetting; + v_U8_t bssid[VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t peerMacAddr[VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t ssid[VOS_LOG_MAX_SSID_SIZE]; + v_U8_t operatingChannel; + v_U8_t beaconInterval; + v_U8_t status; +} vos_log_ibss_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to 802.11D + LOG_WLAN_80211D_C 0x1498 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t eventId; + v_U8_t numChannel; + v_U8_t Channels[VOS_LOG_MAX_NUM_CHANNEL]; + v_U8_t TxPwr[VOS_LOG_MAX_NUM_CHANNEL]; + v_U8_t countryCode[3]; + v_U8_t supportMultipleDomain; +} vos_log_802_11d_pkt_type; + +/*--------------------------------------------------------------------------- +This is a log packet which contains below handoff information: +- Current AP + RSSI (if already associated) +- Candidate AP + RSSI (before association and when the list is updated) +- For each BSSID in candidate list, provide RSSI, QoS and security compatibility +LOG_WLAN_HANDOFF_C 0x1499 +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U8_t ssid[9]; + v_U8_t bssid[VOS_LOG_MAX_BSSID_SIZE]; + v_U8_t channel_id; + v_U32_t qos_score; + v_U32_t sec_score; + v_U32_t rssi_score; + v_U32_t overall_score; + v_U32_t tx_per; /* represented as a % */ + v_U32_t rx_per; /* represented as a % */ + +} vos_log_ho_ap_info; + +typedef struct +{ + log_hdr_type hdr; + v_U32_t num_aps; + vos_log_ho_ap_info current_ap_info; + vos_log_ho_ap_info candidate_ap_info[VOS_LOG_MAX_NUM_HO_CANDIDATE_APS]; +} vos_log_ho_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to the EDCA parameters + advertised by the AP + LOG_WLAN_QOS_EDCA_C 0x149A +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t aci_be; + v_U8_t cw_be; + v_U16_t txoplimit_be; + v_U8_t aci_bk; + v_U8_t cw_bk; + v_U16_t txoplimit_bk; + v_U8_t aci_vi; + v_U8_t cw_vi; + v_U16_t txoplimit_vi; + v_U8_t aci_vo; + v_U8_t cw_vo; + v_U16_t txoplimit_vo; +} vos_log_qos_edca_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the total number of beacon received value + LOG_WLAN_BEACON_UPDATE_C 0x149B +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U32_t bcn_rx_cnt; +} vos_log_beacon_update_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the information related to a WoW patern value when set + LOG_WLAN_POWERSAVE_WOW_ADD_PTRN_C 0x149C +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t pattern_id; + v_U8_t pattern_byte_offset; + v_U8_t pattern_size; + v_U8_t pattern[VOS_LOG_MAX_WOW_PTRN_SIZE]; + v_U8_t pattern_mask_size; + v_U8_t pattern_mask[VOS_LOG_MAX_WOW_PTRN_MASK_SIZE]; +} vos_log_powersave_wow_add_ptrn_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the PHY & MAC layer statistics sent by lower layer + _WLAN_LINKLAYER_STAT_C 0x14A1 +---------------------------------------------------------------------------*/ +typedef struct +{ + v_U32_t retry_cnt[4]; + v_U32_t multiple_retry_cnt[4]; + v_U32_t tx_frm_cnt[4]; + v_U32_t rx_frm_cnt; + v_U32_t frm_dup_cnt; + v_U32_t fail_cnt[4]; + v_U32_t rts_fail_cnt; + v_U32_t ack_fail_cnt; + v_U32_t rts_succ_cnt; + v_U32_t rx_discard_cnt; + v_U32_t rx_error_cnt; + v_U32_t tx_byte_cnt; + +} summaryStatsInfo; + +typedef struct +{ + v_U32_t rx_frag_cnt; + v_U32_t promiscuous_rx_frag_cnt; + v_U32_t rx_input_sensitivity; + v_U32_t max_pwr; + v_U32_t sync_fail_cnt; + v_U32_t tx_rate; + +} globalClassAStatsInfo; + +typedef struct +{ + v_U32_t uc_rx_wep_unencrypted_frm_cnt; + v_U32_t uc_rx_mic_fail_cnt; + v_U32_t uc_tkip_icv_err; + v_U32_t uc_aes_ccmp_format_err; + v_U32_t uc_aes_ccmp_replay_cnt; + v_U32_t uc_aes_ccmp_decrpt_err; + v_U32_t uc_wep_undecryptable_cnt; + v_U32_t uc_wep_icv_err; + v_U32_t uc_rx_decrypt_succ_cnt; + v_U32_t uc_rx_decrypt_fail_cnt; + v_U32_t mcbc_rx_wep_unencrypted_frm_cnt; + v_U32_t mcbc_rx_mic_fail_cnt; + v_U32_t mcbc_tkip_icv_err; + v_U32_t mcbc_aes_ccmp_format_err; + v_U32_t mcbc_aes_ccmp_replay_cnt; + v_U32_t mcbc_aes_ccmp_decrpt_err; + v_U32_t mcbc_wep_undecryptable_cnt; + v_U32_t mcbc_wep_icv_err; + v_U32_t mcbc_rx_decrypt_succ_cnt; + v_U32_t mcbc_rx_decrypt_fail_cnt; + +} globalClassBStatsInfo; + +typedef struct +{ + v_U32_t rx_amsdu_cnt; + v_U32_t rx_ampdu_cnt; + v_U32_t tx_20_frm_cnt; + v_U32_t rx_20_frm_cnt; + v_U32_t rx_mpdu_in_ampdu_cnt; + v_U32_t ampdu_delimiter_crc_err; + +} globalClassCStatsInfo; + +typedef struct +{ + v_U32_t tx_uc_frm_cnt; + v_U32_t tx_mc_frm_cnt; + v_U32_t tx_bc_frm_cnt; + v_U32_t rx_uc_frm_cnt; + v_U32_t rx_mc_frm_cnt; + v_U32_t rx_bc_frm_cnt; + v_U32_t tx_uc_byte_cnt[4]; + v_U32_t tx_mc_byte_cnt; + v_U32_t tx_bc_byte_cnt; + v_U32_t rx_uc_byte_cnt[4]; + v_U32_t rx_mc_byte_cnt; + v_U32_t rx_bc_byte_cnt; + v_U32_t rx_byte_cnt; + v_U32_t num_rx_bytes_crc_ok; + v_U32_t rx_rate; + +} globalClassDStatsInfo; + +typedef struct +{ + v_U32_t tx_frag_cnt[4]; + v_U32_t tx_ampdu_cnt; + v_U32_t tx_mpdu_in_ampdu_cnt; +} perStaStatsInfo; + +typedef struct +{ + log_hdr_type hdr; + v_U8_t version; + v_U8_t reserved[3]; + v_U32_t stat_mask; + summaryStatsInfo summaryStats; + globalClassAStatsInfo globalClassAStats; + globalClassBStatsInfo globalClassBStats; + globalClassCStatsInfo globalClassCStats; + globalClassDStatsInfo globalClassDStats; + perStaStatsInfo perStaStats; +} vos_log_statistics_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains the Tspec info negotiated with the AP for the + specific AC + LOG_WLAN_QOS_TSPEC_C 0x14A2 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_U8_t tsinfo[3]; + v_U16_t nominal_msdu_size; + v_U16_t maximum_msdu_size; + v_U32_t min_service_interval; + v_U32_t max_service_interval; + v_U32_t inactivity_interval; + v_U32_t suspension_interval; + v_U32_t svc_start_time; + v_U32_t min_data_rate; + v_U32_t mean_data_rate; + v_U32_t peak_data_rate; + v_U32_t max_burst_size; + v_U32_t delay_bound; + v_U32_t min_phy_rate; + v_U16_t surplus_bw_allowance; + v_U16_t medium_time; +} vos_log_qos_tspec_pkt_type; + +/*--------------------------------------------------------------------------- + This packet contains data information when stall detected + LOG_TRSP_DATA_STALL_C 0x1801 +---------------------------------------------------------------------------*/ + +typedef struct +{ + char channelName[4]; + v_U32_t numDesc; + v_U32_t numFreeDesc; + v_U32_t numRsvdDesc; + v_U32_t headDescOrder; + v_U32_t tailDescOrder; + v_U32_t ctrlRegVal; + v_U32_t statRegVal; + v_U32_t numValDesc; + v_U32_t numInvalDesc; +} vos_log_data_stall_channel_type; + +typedef struct +{ + log_hdr_type hdr; + v_U32_t PowerState; + v_U32_t numFreeBd; + vos_log_data_stall_channel_type dxeChannelInfo[8]; +} vos_log_data_stall_type; + +/*--------------------------------------------------------------------------- + This packet contains the rssi value from BSS descriptor + LOG_WLAN_RSSI_UPDATE_C 0x1354 +---------------------------------------------------------------------------*/ +typedef struct +{ + log_hdr_type hdr; + v_S7_t rssi; +} vos_log_rssi_pkt_type; + +/** + * struct vos_log_pktlog_info - Packet log info + * @log_hdr: Log header + * @buf_len: Length of the buffer that follows + * @buf: Buffer containing the packet log info + * + * Structure containing the packet log information + * LOG_WLAN_PKT_LOG_INFO_C 0x18E0 + */ +typedef struct +{ + log_hdr_type log_hdr; + uint32_t version; + uint32_t seq_no; + uint32_t buf_len; +}__attribute__((packed))vos_log_pktlog_info; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __VOS_DIAG_CORE_LOG_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_event.h b/drivers/staging/prima/CORE/VOSS/inc/vos_event.h new file mode 100644 index 000000000000..c0394641a803 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_event.h @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_EVENT_H ) +#define __VOS_EVENT_H + +/**========================================================================= + + \file vos_event.h + + \brief virtual Operating System Services (vOSS) Events + + Definitions for vOSS Events + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "vos_types.h" +#include "i_vos_event.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#define INIT_COMPLETION(event) reinit_completion(&event) +#endif + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + + \brief vos_event_init() - initialize a vOSS event + + The \a vos_lock_event() function initializes the specified event. Upon + successful initialization, the state of the event becomes initialized + and not 'signaled. + + An event must be initialized before it may be used in any other lock + functions. + + Attempting to initialize an already initialized event results in + a failure. + + \param lock - pointer to the opaque event object to initialize + + \return VOS_STATUS_SUCCESS - event was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the event + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the event + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by event, a previously + initialized, but not yet destroyed, event. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_init( vos_event_t *event ); + +/*-------------------------------------------------------------------------- + + \brief vos_event_set() - set a vOSS event + + The state of the specified event is set to 'signalled by calling + \a vos_event_set(). The state of the event remains signalled until an + explicit call to vos_event_reset(). + + Any threads waiting on the event as a result of a vos_event_wait() will + be unblocked and available to be scheduled for execution when the event + is signaled by a call to \a vos_event_set(). + + \param event - the event to set to the signalled state + + \return VOS_STATUS_SUCCESS - the event was successfully signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_set( vos_event_t * event ); + + +/*-------------------------------------------------------------------------- + + \brief vos_event_reset() - reset a vOSS event + + The state of the specified event is set to 'NOT signalled' by calling + \a vos_event_reset(). The state of the event remains NOT signalled until an + explicit call to vos_event_set(). + + This function sets the event to a NOT signalled state even if the event was + signalled multiple times before being signaled. + + \param event - the event to set to the NOT signalled state + + \return VOS_STATUS_SUCCESS - the event state was successfully change to + NOT signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_reset( vos_event_t * event ); + + +/*-------------------------------------------------------------------------- + + \brief vos_event_destroy() - Destroy a vOSS event + + The \a vos_event_destroy() function shall destroy the event object + referenced by event. After a successful return from \a vos_event_destroy() + the event object becomes, in effect, uninitialized. + + A destroyed event object can be reinitialized using vos_event_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS event functions to manipulate the lock such + as vos_event_set() will fail if the event is destroyed. Therefore, + don't use the event after it has been destroyed until it has + been re-initialized. + + \param event - the event object to be destroyed. + + \return VOS_STATUS_SUCCESS - event was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by event while it is still being + referenced (there are threads waiting on this event) + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_destroy( vos_event_t *event ); + +// TODO: this is being removed and a stub exists currently to avoid +// compiler errors +VOS_STATUS vos_wait_events( vos_event_t *events, v_U8_t numEvents, + v_U32_t timeout, v_U8_t *pEventIndex ); + +/*---------------------------------------------------------------------------- + + \brief vos_wait_single_event() - Waits for a single event to be set. + + This API waits for the event to be set. + + \param pEvent - pointer to an event to wait on. + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by the event being + set. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before the + event was set. + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - pEvent is an invalid pointer. + + \sa vos_wait_multiple_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_single_event( vos_event_t *pEvent, v_U32_t timeout ); + +/*---------------------------------------------------------------------------- + + \brief vos_wait_multiple_events() - Waits for event(s) to be set. + + This API waits for any event in the input array of events to be + set. The caller is blocked waiting any event in the array to be + set or for the timeout to occur. + + If multiple events in the array are set, only one event is identified + in the return from this call as satisfying the wait condition. The + caller is responsible for calling \a vos_wait_events() again to find + the other events that are set. + + \param pEventList - pointer to an array of event pointers + + \param numEvents - Number of events + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \param pEventIndex - This is a pointer to the location where the index of + the event in the event array that satisfied the wait because + the event was set. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by one of the events + in the event array being set. The index into the event arry + that satisfied the wait can be found at *pEventIndex. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before any of + the events were set. + + VOS_STATUS_E_INVAL - At least one of the values specified in the + event array refers to an uninitialized event object. The invalid + event is identified by the index in *pEventIndex. Note that only + the first uninitialized event is detected when this error is + returned. + + VOS_STATUS_E_EMPTY - the events array is empty. This condition + is detected by numEvents being 0 on input. + + VOS_STATUS_E_FAULT - event or pEventIndex is an invalid pointer. + + \sa vos_wait_single_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_multiple_events( vos_event_t **pEventList, v_U8_t numEvents, + v_U32_t timeout, v_U8_t *pEventIndex ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __VOSS_EVENT_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_getBin.h b/drivers/staging/prima/CORE/VOSS/inc/vos_getBin.h new file mode 100644 index 000000000000..8bf26bab84ec --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_getBin.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_GETBIN_H ) +#define __VOS_GETBIN_H + +/**========================================================================= + + \file vos_getBin.h + + \brief virtual Operating System Services (vOSS) binary APIs + + Binary retrieval definitions and APIs. + + These APIs allow components to retrieve binary contents (firmware, + configuration data, etc.) from a storage medium on the platform. + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/// Binary IDs +typedef enum +{ + /// Binary ID for firmware + VOS_BINARY_ID_FIRMWARE, + + /// Binary ID for Configuration data + VOS_BINARY_ID_CONFIG, + + /// Binary ID for country code to regulatory domain mapping + VOS_BINARY_ID_COUNTRY_INFO, + + /// Binary ID for Handoff Configuration data + VOS_BINARY_ID_HO_CONFIG, + + /// Binary ID for Dictionary Configuration data + VOS_BINARY_ID_DICT_CONFIG + + +} VOS_BINARY_ID; + + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +/**--------------------------------------------------------------------------- + + \brief vos_get_binary_blob() - get binary data from platform + + This API allows components to get binary data from the platform independent + of where the data is stored on the device. + +
    +
  • Firmware +
  • Configuration Data +
+ + \param binaryId - identifies the binary data to return to the caller. + + \param pBuffer - a pointer to the buffer where the binary data will be + retrieved. Memory for this buffer is allocated by the caller + and free'd by the caller. vOSS will fill this buffer with + raw binary data and update the *pBufferSize with the exact + size of the data that has been retreived. + + Input value of NULL is valid and will cause the API to return + the size of the binary data in *pBufferSize. + + \param pBufferSize - pointer to a variable that upon input contains the + size of the data buffer available at pBuffer. Upon success, this + variable is updated with the size of the binary data that was + retreived and written to the buffer at pBuffer. + + Input value of 0 is valid and will cause the API to return + the size of the binary data in *pBufferSize. + + \return VOS_STATUS_SUCCESS - the binary data has been successfully + retreived and written to the buffer. + + VOS_STATUS_E_INVAL - The value specified by binaryId does not + refer to a valid VOS Binary ID. + + VOS_STATUS_E_FAULT - pBufferSize is not a valid pointer to a + variable that the API can write to. + + VOS_STATUS_E_NOMEM - the memory referred to by pBuffer and + *pBufferSize is not big enough to contain the binary. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_get_binary_blob( VOS_BINARY_ID binaryId, + v_VOID_t *pBuffer, v_SIZE_t *pBufferSize ); + +/**---------------------------------------------------------------------------- + \brief vos_get_conparam()- function to read the insmod parameters +-----------------------------------------------------------------------------*/ +tVOS_CON_MODE vos_get_conparam( void ); +tVOS_CONCURRENCY_MODE vos_get_concurrency_mode( void ); +v_BOOL_t vos_concurrent_open_sessions_running(void); +v_BOOL_t vos_max_concurrent_connections_reached(void); + +#endif // !defined __VOS_GETBIN_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_list.h b/drivers/staging/prima/CORE/VOSS/inc/vos_list.h new file mode 100644 index 000000000000..bc43d1bf0551 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_list.h @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_LIST_H ) +#define __VOS_LIST_H + +/**========================================================================= + + \file vos_list.h + + \brief virtual Operating System Services (vOSS) List APIs + + Definitions for vOSS Linked Lists API + + Lists are implemented as a doubly linked list. An item in a list can + be of any type as long as the datatype contains a field of type + vos_link_t. + + In general, a list is a doubly linked list of items with a pointer + to the front of the list and a pointer to the end of the list. The + list items contain a forward and back link. + + List Nodes + ============= =========================== + +-------+ + | Front |------------->+---------+ +---------+ + +-------+ | Next |---->| Next |---->NULL + | Back |-+ +---------+ +---------+ + +-------+ | NULL<----| Prev |<----| Prev | + | +---------+ +---------+ + | |User Data| |User Data| + | +---------+ +---------+ + | ^ + | | + +---------------------------------+ + + This linked list API is implemented with appropriate locking + mechanisms to assure operations on the list are thread safe. + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/**--------------------------------------------------------------------------- + + \brief vos_list_init() - initialize a vOS Linked List + + The \a vos_list_init() function initializes the specified linked list + 'object'. Upon successful initialization, the state of the list + becomes initialized and available for use through the other vos_list_xxx + APIs. + + A list must be initialized by calling vos_list_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized list results in + a failure. + + \param pList - pointer to the opaque list object to initialize + + \return VOS_STATUS_SUCCESS - list was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the list + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the list + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by list, a previously + initialized, but not yet destroyed, list. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + + \sa vos_list_destroy() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_init( vos_list_t *pList ); + + +/**------------------------------------------------------------------------- + + \brief vos_list_destroy() - Destroy a vOSS List + + The \a vos_list_destroy() function shall destroy the list object + referenced by pList. After a successful return from \a vos_list_destroy() + the list object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using vos_list_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS list functions to manipulate the list such + will fail if the list or has not been initialized or is destroyed. + Therefore, don't use the list after it has been destroyed until it has + been re-initialized. + + \param pLlist - pointer to the list object to be destroyed. + + \return VOS_STATUS_SUCCESS - list was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by pList that is still has + nodes. The list must be empty before it can be destroyed. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_destroy( vos_list_t *pList ); + +/*-------------------------------------------------------------------------- + + \brief vos_list_lock() - Lock a vOSS List + + The \a vos_list_lock() function shall lock the list object to prevent + other tasks from operating on this list. The list remains locked until + a call to vos_list_unlock() is made. + + Each list function already operate within a critical section. + However it is sometimes necessary to lock a list over a series of list + function calls. + + For example, when one needs to search a node on a list and insert another + node after it, one would want to lock this list for the entire process + in case another task attempts to manipulate this list. + + \param pLlist - pointer to the list object to be locked. + + \return VOS_STATUS_SUCCESS - list was successfully locked. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + + \sa vos_list_unlock() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_lock( vos_list_t *pList ); + +/*-------------------------------------------------------------------------- + + \brief vos_list_unlock() - Unlock a vOSS List + + The \a vos_list_unlock() function shall unlock the list object to allow + other tasks to use this list. This function is only called when + the vos_list_lock() is previously called in the current task. + + \param pLlist - pointer to the list object to be unlocked. + + \return VOS_STATUS_SUCCESS - list was successfully unlocked. + + VOS_STATUS_E_FAULT - pList is an invalid pointer. + + \sa vos_list_lock() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_unlock( vos_list_t *pList ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_front() - insert node at front of a linked list + + The vos_list_insert_front() API will insert a node at the front of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or pNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_front( vos_list_t *pList, vos_list_node_t *pNode ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_back() - insert node at back of a linked list + + The vos_list_insert_back() API will insert a node at the back of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the back of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or pNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_back( vos_list_t *pList, vos_list_node_t *pNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_back_size() - insert node at back of a linked list and + return the size AFTER the enqueue. This size is determined in a race free + manner i.e. while the list is locked for the enqueue operation + + The vos_list_insert_back_size() API will insert a node at the back of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \param pSize - Pointer to a size variable, where the size of the + list will be returned. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the back of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or pNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_back_size( vos_list_t *pList, vos_list_node_t *pNode, v_SIZE_t *pSize ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_remove_front() - remove node at front of a linked list + + The vos_list_remove_front() API will remove a node at the front of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or ppNode is an + invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_front( vos_list_t *pList, vos_list_node_t **ppNode ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_remove_back() - remove node at back of a linked list + + The vos_list_remove_back() API will remove a node at the back of + a properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the back of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList is an invalid pointer or ppNode is an + invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_back( vos_list_t *pList, vos_list_node_t **ppNode ); + + +/*---------------------------------------------------------------------------- + + \brief vos_list_size() - return the size of of a linked list + + The vos_list_size() API will return the number of nodes on the + given vOS List object. + + \param pList - Pointer to list object where the node will be counted + + \param pSize - Pointer to a size variable, where the size of the + list will be returned. + + \return VOS_STATUS_SUCCESS - list size of the properly initialized + vos list object has been returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList or pSize are not valid pointers + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_size( vos_list_t *pList, v_SIZE_t *pSize ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_front() - peek at the node at front of a linked list + + The vos_list_peek_front() API will return a pointer to the node at the + front of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the front of the list. + + \return VOS_STATUS_SUCCESS - list node at the front of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_front( vos_list_t *pList, vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_back() - peek at the node at back of a linked list + + The vos_list_peek_back() API will return a pointer to the node at the + back of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the back of the list. + + \return VOS_STATUS_SUCCESS - list node at the back of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_peek_back(), vos_list_remove_back(), vos_list_peek_front(), + vos_list_remove_front() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_back( vos_list_t *pList, vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_next() - peek at the node after the specified node + + The vos_list_peek_next() API will return a pointer to the node following the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node that follows the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node following pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_next( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_peek_prev() - peek at the node before the specified node + + The vos_list_peek_prev() API will return a pointer to the node before the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node before the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node before pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_peek_prev( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_before() - insert node at front of a specified + list node + + The vos_list_insert_before() API will insert a node onto a properly + initialized vOS List object in front of the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + in front of. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_before( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ); + +/**--------------------------------------------------------------------------- + + \brief vos_list_insert_after() - insert node behind a specified list node + + The vos_list_insert_after() API will insert a node onto a properly + initialized vOS List object after the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + after. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_after( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ); + + +/**--------------------------------------------------------------------------- + + \brief vos_list_remove_node() - remove specified node from vOS list list + + The vos_list_remove_node() API will remove a specified node from the + properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to the node to be removed from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + + VOS_STATUS_E_FAULT - pList or pNodeToRemove is not a valid pointer + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_node( vos_list_t *pList, vos_list_node_t *pNodeToRemove ); + + + +#endif // __VOS_LIST_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_lock.h b/drivers/staging/prima/CORE/VOSS/inc/vos_lock.h new file mode 100644 index 000000000000..9cce9503ac55 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_lock.h @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_LOCK_H ) +#define __VOS_LOCK_H + +/**========================================================================= + + \file vos_lock.h + + \brief virtual Operating System Servies (vOS) Locks + + Definitions for vOSS Locks + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_status.h" +#include "i_vos_lock.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + + \brief vos_lock_init() - initialize a vOSS lock + + The \a vos_lock_init() function initializes the specified lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - lock was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the lock + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the lock + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by lock, a previously + initialized, but not yet destroyed, lock. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_init( vos_lock_t *lock ); + +/*-------------------------------------------------------------------------- + + \brief vos_lock_acquire() - acquire a lock + + A lock object is acquired by calling \a vos_lock_acquire(). If the lock + is already locked, the calling thread shall block until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param lock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_acquire( vos_lock_t * lock ); + + +/*-------------------------------------------------------------------------- + + \brief vos_lock_release() - release a lock + + The \a vos_lock_release() function shall release the lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param lock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_PERM - Operation is not permitted. The calling + thread does not own the lock. + + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_release( vos_lock_t *lock ); + + +/*-------------------------------------------------------------------------- + + \brief vos_lock_destroy() - Destroy a vOSS Lock + + The \a vos_lock_destroy() function shall destroy the lock object + referenced by lock. After a successful return from \a vos_lock_destroy() + the lock object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using vos_lock_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS lock functions to manipulate the lock such + as vos_lock_acquire() will fail if the lock is destroyed. Therefore, + don't use the lock after it has been destroyed until it has + been re-initialized. + + \param lock - the lock object to be destroyed. + + \return VOS_STATUS_SUCCESS - lock was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by lock while it is locked + or still referenced. + + VOS_STATUS_E_INVAL - The value specified by lock is invalid. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_destroy( vos_lock_t *lock ); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_init() - initializes a vOSS spin lock + + The vos_spin_lock_init() function initializes the specified spin lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_spin_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param pLock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - spin lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_init(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_acquire() - acquires a spin lock + + A lock object is acquired by calling \a vos_spin_lock_acquire(). If the lock + is already locked, the calling thread shall spin until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param pLock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_acquire(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_release() - releases a lock + + The \a vos_lock_release() function shall release the spin lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param pLock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_release(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_destroy() - releases resource of a lock + + \param pLock - pointer to a lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_destroy(vos_spin_lock_t *pLock); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_init() - initializes a vOSS wake lock + + \param pLock - the wake lock to initialize + name - wakelock name + + \return VOS_STATUS_SUCCESS - wake lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_acquire() - acquires a wake lock + + \param pLock - the wake lock to acquire + reason - reason for taking wakelock + + \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_acquire(vos_wake_lock_t *pLock, uint32_t reason); +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_timeout_release() - release a wake lock with a timeout + + \param pLock - the wake lock to release + reason - reason for taking wakelock + + \return VOS_STATUS_SUCCESS - the wake lock was successfully released + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_timeout_release(vos_wake_lock_t *pLock, + v_U32_t msec, uint32_t reason); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_release() - releases a wake lock + + \param pLock - the wake lock to release + reason - reason for taking wakelock + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_release(vos_wake_lock_t *pLock, uint32_t reason); + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_destroy() - destroys a wake lock + + \param pLock - the wake lock to destroy + + \return VOS_STATUS_SUCCESS - the lock was successfully destroyed + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock); + +#endif // __VOSS_LOCK_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_memory.h b/drivers/staging/prima/CORE/VOSS/inc/vos_memory.h new file mode 100644 index 000000000000..fd064c6f5957 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_memory.h @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_MEMORY_H ) +#define __VOS_MEMORY_H + +/**========================================================================= + + \file vos_memory.h + + \brief virtual Operating System Servies (vOSS) + + Memory management functions + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#ifdef MEMORY_DEBUG +v_VOID_t vos_mem_init(v_VOID_t); +v_VOID_t vos_mem_exit(v_VOID_t); +void vos_mem_clean(void); +#endif + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_mem_malloc() - vOSS Memory Allocation + + This function will dynamicallly allocate the specified number of bytes of + memory. + + \param size - the number of bytes of memory to allocate. + + \return Upon successful allocate, returns a non-NULL pointer to the + allocated memory. If this function is unable to allocate the amount of + memory specified (for any reason) it returns NULL. + + \sa + + --------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +#define vos_mem_malloc(size) vos_mem_malloc_debug(size, __FILE__, __LINE__) +v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum); +#else +v_VOID_t * vos_mem_malloc( v_SIZE_t size ); +#endif + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_free() - vOSS Free Memory + + This function will free the memory pointed to by 'ptr'. + + \param ptr - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_free( v_VOID_t *ptr ); + + +/*---------------------------------------------------------------------------- + + \fn vos_mem_set() - set (fill) memory with a specified byte value. + + \param pMemory - pointer to memory that will be set + + \param numBytes - the number of bytes to be set + + \param value - the byte set in memory + + \return - Nothing. + + \sa vos_mem_zero() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_set( v_VOID_t *ptr, v_SIZE_t numBytes, v_BYTE_t value ); + + +/*---------------------------------------------------------------------------- + + \fn vos_mem_zero() - zero out memory + + This function sets the memory location to all zeros, essentially clearing + the memory. + + \param pMemory - pointer to memory that will be set to zero + + \param numBytes - the number of bytes zero + + \param value - the byte set in memory + + \return - Nothing. + + \sa vos_mem_set() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_zero( v_VOID_t *ptr, v_SIZE_t numBytes ); + +static __inline__ unsigned long vos_htonl(unsigned long ul) +{ + return( ( ( ul & 0x000000ff ) << 24 ) | + ( ( ul & 0x0000ff00 ) << 8 ) | + ( ( ul & 0x00ff0000 ) >> 8 ) | + ( ( ul & 0xff000000 ) >> 24 ) ); +} + +void vos_buff_to_hl_buff (v_U8_t *buffer, int size); +/*---------------------------------------------------------------------------- + + \brief vos_mem_copy() - Copy memory + + Copy host memory from one location to another, similar to memcpy in + standard C. Note this function does not specifically handle overlapping + source and destination memory locations. Calling this function with + overlapping source and destination memory locations will result in + unpredictable results. Use vos_mem_move() if the memory locations + for the source and destination are overlapping (or could be overlapping!) + + \param pDst - pointer to destination memory location (to copy to) + + \param pSrc - pointer to source memory location (to copy from) + + \param numBytes - number of bytes to copy. + + \return - Nothing + + \sa vos_mem_move() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_copy( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ); + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_move() - Move memory + + Move host memory from one location to another, similar to memmove in + standard C. Note this function *does* handle overlapping + source and destination memory locations. + + \param pDst - pointer to destination memory location (to move to) + + \param pSrc - pointer to source memory location (to move from) + + \param numBytes - number of bytes to move. + + \return - Nothing + + \sa vos_mem_move() + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_move( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ); + +/** --------------------------------------------------------------------------- + + \fn vos_mem_compare() + + \brief vos_mem_compare() - Memory compare + + Function to compare two pieces of memory, similar to memcmp function + in standard C. + + \param pMemory1 - pointer to one location in memory to compare. + + \param pMemory2 - pointer to second location in memory to compare. + + \param numBytes - the number of bytes to compare. + + \return v_BOOL_t - returns a boolean value that tells if the memory + locations are equal or not equal. + + -------------------------------------------------------------------------------*/ +v_BOOL_t vos_mem_compare( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_VOID_t *pMemory1, +#else + v_VOID_t *pMemory1, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_VOID_t *pMemory2, +#else + v_VOID_t *pMemory2, +#endif + v_U32_t numBytes); + + +/** --------------------------------------------------------------------------- + + \fn vos_mem_compare2() + + \brief vos_mem_compare2() - Memory compare + + Function to compare two pieces of memory, similar to memcmp function + in standard C. + + \param pMemory1 - pointer to one location in memory to compare. + + \param pMemory2 - pointer to second location in memory to compare. + + \param numBytes - the number of bytes to compare. + + \return v_SINT_t - returns a boolean value that tells if the memory + locations are equal or not equal. + 0 -- equal + < 0 -- *pMemory1 is less than *pMemory2 + > 0 -- *pMemory1 is bigger than *pMemory2 + + -------------------------------------------------------------------------------*/ +v_SINT_t vos_mem_compare2( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes ); + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_malloc() - vOSS DMA Memory Allocation + + This function will dynamicallly allocate the specified number of bytes of + memory. This memory will have special attributes making it DMA friendly i.e. + it will exist in contiguous, 32-byte aligned uncached memory. A normal + vos_mem_malloc does not yield memory with these attributes. + + NOTE: the special DMA friendly memory is very scarce and this API must be + used sparingly + + \param size - the number of bytes of memory to allocate. + + \return Upon successful allocate, returns a non-NULL pointer to the + allocated memory. If this function is unable to allocate the amount of + memory specified (for any reason) it returns NULL. + + \sa + + --------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +#define vos_mem_dma_malloc(size) vos_mem_dma_malloc_debug(size, __FILE__, __LINE__) +v_VOID_t * vos_mem_dma_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum); +#else +v_VOID_t * vos_mem_dma_malloc( v_SIZE_t size ); +#endif + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_free() - vOSS DMA Free Memory + + This function will free special DMA friendly memory pointed to by 'ptr'. + + \param ptr - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_dma_free( v_VOID_t *ptr ); + +#ifdef DMA_DIRECT_ACCESS +/*---------------------------------------------------------------------------- + + \brief vos_mem_set_dma_ptr() - vOSS DMA memory poiter set by SAL + + This function will set DMA Physical memory pointer. + + + \param dmaBuffer - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_set_dma_ptr(unsigned char *dmaBuffer); +#endif /* DMA_DIRECT_ACCESS */ + + +/*---------------------------------------------------------------------------- + + \brief vos_mem_vmalloc() - allocate memory which is virtually contiguous + + Wrapper function for vmalloc + + \param size memory size to be allocated + + \return on success returns starting address of allocated memory or NULL + + --------------------------------------------------------------------------*/ +v_VOID_t * vos_mem_vmalloc(v_SIZE_t size); + +/*---------------------------------------------------------------------------- + + \brief vos_mem_vfree() - free memory allocated by vmalloc + + Wrapper function for vfree + + \param address starting address of the memory to be freed + + \return Nothing + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_vfree(void *addr); + +#endif // __VOSS_LOCK_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_mq.h b/drivers/staging/prima/CORE/VOSS/inc/vos_mq.h new file mode 100644 index 000000000000..e82dd006ec80 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_mq.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_MQ_H ) +#define __VOS_MQ_H + +/**========================================================================= + + \file vos_mq.h + + \brief virtual Operating System Services (vOSS) message queue APIs + + Message Queue Definitions and API + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/// vos Message Type. +/// This represnets a message that can be posted to another module through +/// the voss Message Queues. +/// +/// \note This is mapped directly to the tSirMsgQ for backward +/// compatibility with the legacy MAC code. + +typedef struct vos_msg_s +{ + v_U16_t type; + /* + * This field can be used as sequence number/dialog token for matching + * requests and responses. + */ + v_U16_t reserved; + /** + * Based on the type either a bodyptr pointer into + * memory or bodyval as a 32 bit data is used. + * bodyptr: is always a freeable pointer, one should always + * make sure that bodyptr is always freeable. + * + * Messages should use either bodyptr or bodyval; not both !!!. + */ + void *bodyptr; + + v_U32_t bodyval; + + /* + * Some messages provide a callback function. The function signature + * must be agreed upon between the two entities exchanging the message + */ + void *callback; + +} vos_msg_t; + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/// Message Queue IDs +typedef enum +{ + /// Message Queue ID for messages bound for SME + VOS_MQ_ID_SME = VOS_MODULE_ID_SME, + + /// Message Queue ID for messages bound for PE + VOS_MQ_ID_PE = VOS_MODULE_ID_PE, + + /// Message Queue ID for messages bound for WDA + VOS_MQ_ID_WDA = VOS_MODULE_ID_WDA, + + /// Message Queue ID for messages bound for TL + VOS_MQ_ID_TL = VOS_MODULE_ID_TL, + + /// Message Queue ID for messages bound for the SYS module + VOS_MQ_ID_SYS = VOS_MODULE_ID_SYS, + + /// Message Queue ID for messages bound for WDI + VOS_MQ_ID_WDI = VOS_MODULE_ID_WDI, + +} VOS_MQ_ID; + + +/**--------------------------------------------------------------------------- + + \brief vos_mq_post_message() - post a message to a message queue + + This API allows messages to be posted to a specific message queue. Messages + can be posted to the following message queues: + +
    +
  • SME +
  • PE +
  • HAL +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is posted to the message queue. If the consumer of the + message needs anything in this message, it needs to copy the contents + before returning from the message queue handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_mq_post_message( VOS_MQ_ID msgQueueId, vos_msg_t *message ); + +/**-------------------------------------------------------------------------- + \brief vos_mq_post_message_high_pri() - posts a high priority message to + a message queue + + This API allows messages to be posted to the head of a specific message + queue. Messages can be posted to the following message queues: + +
    +
  • SME +
  • PE +
  • HAL +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is posted to the message queue. If the consumer of the + message needs anything in this message, it needs to copy the contents + before returning from the message queue handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_mq_post_message_high_pri(VOS_MQ_ID msgQueueId, vos_msg_t *message); + + +/**--------------------------------------------------------------------------- + + \brief vos_tx_mq_serialize() - serialize a message to the Tx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Tx execution flow can be posted only + to the following queue. + +
    +
  • TL +
  • WDI/SSC +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_tx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *message ); + +/**--------------------------------------------------------------------------- + + \brief vos_rx_mq_serialize() - serialize a message to the Rx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Rx execution flow can be posted only + to the following queue. + +
    +
  • WDI +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_rx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *message ); + + +#endif // if !defined __VOS_MQ_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_nvitem.h b/drivers/staging/prima/CORE/VOSS/inc/vos_nvitem.h new file mode 100644 index 000000000000..c180d1ce3e00 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_nvitem.h @@ -0,0 +1,810 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_NVITEM_H ) +#define __VOS_NVITEM_H + +/**========================================================================= + + \file vos_nvitem.h + + \brief virtual Operating System Services (vOSS): Non-Volatile storage API + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "vos_status.h" +#include "wlan_nv.h" +#include "wlan_nv2.h" + +/* Maximum number of channels per country can be ignored */ +#define MAX_CHANNELS_IGNORE 10 +#define MAX_COUNTRY_IGNORE 5 + +#define TX_POWER_DEFAULT 30//in dbm + +typedef struct sCsrIgnoreChannels +{ + tANI_U8 countryCode[NV_FIELD_COUNTRY_CODE_SIZE]; + tANI_U16 channelList[MAX_CHANNELS_IGNORE]; + tANI_U16 channelCount; +}tCsrIgnoreChannels; + +extern tCsrIgnoreChannels countryIgnoreList[]; + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +// NV Items with their parameters are specified below +// Parameters include: enum label in VNV_TYPE (_name), +// element count (_cnt), element size (_size), +// enum of first element in NV module (_label) + +/* + * The VOS NV Item Table is compliant to AMSS NV service files of: + * //source/qcom/qct/wconnect/wlan/private/csw/nv/ @ CL 431102 + * + * VNV_REGULATORY_DOMAIN_TABLE - contains regulatory domain information; + * the table is stored as $(REGDOMAIN_COUNT) NV items where each NV item + * contains information for one domain; see definition of v_REGDOMAIN_t + * for the regulatory domains + * + * VNV_FIELD_IMAGE - contains various elements such as MAC addresses + * + * VNV_RATE_TO_POWER_TABLE - table of power for each of 25 PHY rates + * + * VNV_DEFAULT_LOCATION - default country code and regulatory domain + * + * VNV_MAXIMUM_TX_POWER + * + * VNV_RX_SENSITIVITY - table of sensitivity for each of %(MAC_RATE_COUNT) MAC + * rates; see definition of v_MAC_RATE_t for the MAC rates + * + * VNV_NETWORK_TYPE - either A, B or G type + * + * VOV_QFUSE - 16 byte QFUSE data + */ +#define VNV_ITEM_TABLE \ +ADD_VNV_ITEM( VNV_REGULARTORY_DOMAIN_TABLE, REGDOMAIN_COUNT, 144, \ + NV_WLAN_REGULATORY_DOMAIN_FCC_I ) \ +ADD_VNV_ITEM( VNV_FIELD_IMAGE, 1, 52, NV_WLAN_FIELD_IMAGE_I ) \ +ADD_VNV_ITEM( VNV_RATE_TO_POWER_TABLE, 2, 66, NV_WLAN_RATE_TO_POWER_LIST_I )\ +ADD_VNV_ITEM( VNV_DEFAULT_LOCATION, 1, 4, NV_WLAN_DEFAULT_LOCATION_INFO_I ) \ +ADD_VNV_ITEM( VNV_TPC_POWER_TABLE, 14, 128, NV_WLAN_TPC_POWER_TABLE_I ) \ +ADD_VNV_ITEM( VNV_TPC_PDADC_OFFSETS, 14, 2, NV_WLAN_TPC_PDADC_OFFSETS_I ) \ +ADD_VNV_ITEM( VNV_MAXIMUM_TX_POWER, 1, 1, NV_WLAN_MAX_TX_POWER_I ) \ +ADD_VNV_ITEM( VNV_RX_SENSITIVITY, 1, MAC_RATE_COUNT, NV_WLAN_RX_SENSITIVITY_I)\ +ADD_VNV_ITEM( VNV_NETWORK_TYPE, 1, 1, NV_WLAN_NETWORK_TYPE_I ) \ +ADD_VNV_ITEM( VNV_CAL_MEMORY, 1, 3460, NV_WLAN_CAL_MEMORY_I ) \ +ADD_VNV_ITEM( VNV_FW_CONFIG, 1, 32, NV_WLAN_FW_CONFIG_I ) \ +ADD_VNV_ITEM( VNV_RSSI_CHANNEL_OFFSETS, 2, 56, NV_WLAN_RSSI_CHANNEL_OFFSETS_I ) \ +ADD_VNV_ITEM( VNV_HW_CAL_VALUES, 1, 48, NV_WLAN_HW_CAL_VALUES_I ) \ +ADD_VNV_ITEM( VNV_ANTENNA_PATH_LOSS, 14, 2, NV_WLAN_ANTENNA_PATH_LOSS_I ) \ +ADD_VNV_ITEM( VNV_PACKET_TYPE_POWER_LIMITS, 42, 2, NV_WLAN_PACKET_TYPE_POWER_LIMITS_I ) \ +ADD_VNV_ITEM( VNV_OFDM_CMD_PWR_OFFSET, 1, 2, NV_WLAN_OFDM_CMD_PWR_OFFSET_I ) \ +ADD_VNV_ITEM( VNV_TX_BB_FILTER_MODE, 1, 4, NV_TX_BB_FILTER_MODE_I ) \ +ADD_VNV_ITEM( VNV_FREQUENCY_FOR_1_3V_SUPPLY, 1, 4, NV_FREQUENCY_FOR_1_3V_SUPPLY_I ) \ +ADD_VNV_ITEM( VNV_TABLE_VIRTUAL_RATE, 1, 4, VNV_TABLE_VIRTUAL_RATE_I ) \ + + +#define VOS_COUNTRY_CODE_LEN 2 +#define VOS_MAC_ADDRESS_LEN 6 +#define VOS_MAC_ADDR_LAST_3_BYTES 3 +#define VOS_MAC_ADDR_FIRST_3_BYTES 3 +#define VOS_NV_FREQUENCY_FOR_1_3V_SUPPLY_3P2MH 0 //3.2 Mhz +#define VOS_NV_FREQUENCY_FOR_1_3V_SUPPLY_1P6MH 1 //1.6 Mhz + + +/*! + * The path (from the root of the DPP_FOLDER_PATH\QCOM) to the file containing + * the CLPC provisioning data. This is being temporarily put here. This should go + * to esp_dpp.h where the WLAN_PROVISION_DATA is present. + */ +#define CLPC_PROVISION_DATA L"WLAN_CLPC.PROVISION" +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) +#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR +#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR +#endif +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +// enum of RX sensitivity table index +typedef enum +{ + // 11b + MAC_RATE_11B_1_MBPS, + MAC_RATE_11B_2_MBPS, + MAC_RATE_11B_5_5_MBPS, + MAC_RATE_11B_11_MBPS, + + // 11g + MAC_RATE_11G_6_MBPS, + MAC_RATE_11G_9_MBPS, + MAC_RATE_11G_12_MBPS, + MAC_RATE_11G_18_MBPS, + MAC_RATE_11G_24_MBPS, + MAC_RATE_11G_36_MBPS, + MAC_RATE_11G_48_MBPS, + MAC_RATE_11G_54_MBPS, + + // 11n + MAC_RATE_11N_MCS_0, + MAC_RATE_11N_MCS_1, + MAC_RATE_11N_MCS_2, + MAC_RATE_11N_MCS_3, + MAC_RATE_11N_MCS_4, + MAC_RATE_11N_MCS_5, + MAC_RATE_11N_MCS_6, + MAC_RATE_11N_MCS_7, + + MAC_RATE_COUNT + +} v_MAC_RATE_t; + +// enum of regulatory doamains in WLAN +typedef enum +{ + REGDOMAIN_FCC, + REGDOMAIN_ETSI, + REGDOMAIN_JAPAN, + REGDOMAIN_WORLD, + REGDOMAIN_N_AMER_EXC_FCC, + REGDOMAIN_APAC, + REGDOMAIN_KOREA, + REGDOMAIN_HI_5GHZ, + REGDOMAIN_NO_5GHZ, + // add new regulatory domain here + REGDOMAIN_COUNT +} +v_REGDOMAIN_t; + +typedef enum +{ + COUNTRY_NV, + COUNTRY_IE, + COUNTRY_USER, + COUNTRY_CELL_BASE, + //add new sources here + COUNTRY_QUERY, + COUNTRY_MAX = COUNTRY_QUERY +} +v_CountryInfoSource_t; + +//enum of NV version +typedef enum +{ + E_NV_V2, + E_NV_V3, + E_NV_INVALID +} eNvVersionType; + +// enum of supported NV items in VOSS +typedef enum +{ +#define ADD_VNV_ITEM(_name, _cnt, _size, _label) _name, + VNV_ITEM_TABLE +#undef ADD_VNV_ITEM + VNV_TYPE_COUNT +} +VNV_TYPE; + +// country code type +typedef v_U8_t v_COUNTRYCODE_t[VOS_COUNTRY_CODE_LEN]; + +// MAC address type +typedef v_U8_t v_MAC_ADDRESS_t[VOS_MAC_ADDRESS_LEN]; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +const char * voss_DomainIdtoString(const v_U8_t domainIdCurrent); +/**------------------------------------------------------------------------ + + \brief vos_nv_init() - initialize the NV module + + The \a vos_nv_init() initializes the NV module. This read the binary + file for country code and regulatory domain information. + + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_init(void); + +/**------------------------------------------------------------------------ + + \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of + a country given its country code + + The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of + a country given its country code. This is done from reading a cached + copy of the binary file. + + \param pRegDomain - pointer to regulatory domain + + \param countryCode - country code + + \param source - source of country code + + \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country + VOS_STATUS_E_FAULT - invalid pointer error + VOS_STATUS_E_EMPTY - country code table is empty + VOS_STATUS_E_EXISTS - given country code does not exist in table + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain, + const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source); + +/**------------------------------------------------------------------------ + + \brief vos_nv_getSupportedCountryCode() - get the list of supported + country codes + + The \a vos_nv_getSupportedCountryCode() encodes the list of supported + country codes with paddings in the provided buffer + + \param pBuffer - pointer to buffer where supported country codes + and paddings are encoded; this may be set to NULL + if user wishes to query the required buffer size to + get the country code list + + \param pBufferSize - this is the provided buffer size on input; + this is the required or consumed buffer size on output + + \return VOS_STATUS_SUCCESS - country codes are successfully encoded + VOS_STATUS_E_NOMEM - country codes are not encoded because either + the buffer is NULL or buffer size is + sufficient + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize, + v_SIZE_t paddingSize ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_setValidity() - set the validity of an NV item. + + The \a vos_nv_setValidity() validates and invalidates an NV item. The + validity information is stored in NV memory. + One would get the VOS_STATUS_E_EXISTS error when reading an invalid item. + An item becomes valid when one has written to it successfully. + + \param type - NV item type + + \param itemIsValid - boolean value indicating the item's validity + + \return VOS_STATUS_SUCCESS - validity is set successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAILURE - unknown error + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_getValidity() - get the validity of an NV item. + + The \a vos_nv_getValidity() indicates if an NV item is valid. The + validity information is stored in NV memory. + One would get the VOS_STATUS_E_EXISTS error when reading an invalid item. + An item becomes valid when one has written to it successfully. + + \param type - NV item type + + \param pItemIsValid- pointer to the boolean value indicating the item's + validity + + \return VOS_STATUS_SUCCESS - validity is determined successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAILURE - unknown error + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_read() - read a NV item to an output buffer + + The \a vos_nv_read() reads a NV item to an output buffer. If the item is + an array, this function would read the entire array. One would get a + VOS_STATUS_E_EXISTS error when reading an invalid item. + + For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE, + if a default buffer is provided (with a non-NULL value), + the default buffer content is copied to the output buffer. + + \param type - NV item type + + \param outputBuffer - output buffer + + \param defaultBuffer - default buffer + + \param bufferSize - output buffer size + + \return VOS_STATUS_SUCCESS - NV item is read successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAULT - defaultBuffer point is NULL + VOS_STATUS_E_EXISTS - NV type is unsupported + VOS_STATUS_E_FAILURE - unknown error + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputBuffer, + v_VOID_t *defaultBuffer, v_SIZE_t bufferSize ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_readAtIndex() - read an element of a NV array to an output + buffer + + The \a vos_nv_readAtIndex() reads an element of a NV item to an output + buffer. If the item is not array, this function only works for index of 0. + One would get a VOS_STATUS_E_EXISTS error when reading an invalid item. + + For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE, + if a default buffer is provided (with a non-NULl value), + the default buffer content is copied to the output buffer. + + \param type - NV item type + + \param index - NV array index + + \param outputBuffer - output buffer + + \param defaultBuffer - default buffer + + \param bufferSize - output buffer size + + \return VOS_STATUS_SUCCESS - NV item is read successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAULT - defaultBuffer point is NULL + VOS_STATUS_E_EXISTS - NV type is unsupported + VOS_STATUS_E_FAILURE - unknown error + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readAtIndex( VNV_TYPE type, v_UINT_t index, + v_VOID_t *outputBuffer, v_VOID_t *defaultBuffer, v_SIZE_t bufferSize ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_write() - write to a NV item from an input buffer + + The \a vos_nv_write() writes to a NV item from an input buffer. This would + validate the NV item if the write operation is successful. + + \param type - NV item type + + \param inputBuffer - input buffer + + \param inputBufferSize - input buffer size + + \return VOS_STATUS_SUCCESS - NV item is read successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAULT - outputBuffer pointer is NULL + VOS_STATUS_E_EXISTS - NV type is unsupported + VOS_STATUS_E_FAILURE - unknown error + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_write( VNV_TYPE type, v_VOID_t *inputBuffer, + v_SIZE_t inputBufferSize ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_writeAtIndex() - write to an element of a NV array from an + input buffer + + The \a vos_nv_writeAtIndex() writes to an element of a NV array from an + input buffer. If the item is not an array, this function only works for + an array index of 0. This would automatically validate the NV item if the + write operation is successful. + + \param type - NV item type + + \param index - NV array index + + \param inputBuffer - input buffer + + \param inputBufferSize - input buffer size + + \return VOS_STATUS_SUCCESS - NV item is read successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAULT - outputBuffer pointer is NULL + VOS_STATUS_E_EXISTS - NV type is unsupported + VOS_STATUS_E_FAILURE - unknown error + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_writeAtIndex( VNV_TYPE type, v_UINT_t index, + v_VOID_t *inputBuffer, v_SIZE_t inputBufferSize ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_getElementCount() - return element count of a NV array + + The \a vos_nv_getElementCount() returns element count of a NV array + + \param type - NV item type + + \return count if type is valid; 0 otherwise + + \sa + + -------------------------------------------------------------------------*/ +VOS_INLINE_FN v_SIZE_t vos_nv_getElementCount( VNV_TYPE type ) +{ + switch (type) + { +#define ADD_VNV_ITEM(_name, _cnt, _size, _label) case (_name): return (_cnt); + VNV_ITEM_TABLE +#undef ADD_VNV_ITEM + default: + return 0; + } +} + +/**------------------------------------------------------------------------ + + \brief vos_nv_getElementSize() - return size of a NV element + + The \a vos_nv_getElementSize() returns size of a NV element. + + \param type - NV item type + + \return size if type is valid; 0 otherwise + + \sa + + -------------------------------------------------------------------------*/ +VOS_INLINE_FN v_SIZE_t vos_nv_getElementSize( VNV_TYPE type ) +{ + switch (type) + { +#define ADD_VNV_ITEM(_name, _cnt, _size, _label) case (_name): return (_size); + VNV_ITEM_TABLE +#undef ADD_VNV_ITEM + default: + return 0; + } +} + +/**------------------------------------------------------------------------ + + \brief vos_nv_getItemSize() - return size of a NV item + + The \a vos_nv_getItemSize() returns size of a NV item. + + \param type - NV item type + + \return size of a NV item array if type is valid; 0 otherwise + + \sa + + -------------------------------------------------------------------------*/ +VOS_INLINE_FN v_SIZE_t vos_nv_getItemSize( VNV_TYPE type ) +{ + return vos_nv_getElementCount(type) * vos_nv_getElementSize(type); +} + +// TODO: HAL NV interface should be used to access individual NV items +// instead of below functions once that is ready + +/**------------------------------------------------------------------------ + + \brief vos_nv_readTxAntennaCount() - return number of TX antenna + + \param pTxAntennaCount - antenna count + + \return status of the NV read operation + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_readRxAntennaCount() - return number of RX antenna + + \param pRxAntennaCount - antenna count + + \return status of the NV read operation + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_readMacAddress() - return the MAC address + + \param pMacAddress - MAC address + + \return status of the NV read operation + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses + + \param pMacAddress - MAC address + \param macCount - Count of valid MAC addresses to get from NV field + + \return status of the NV read operation + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t* pMacAddr, v_U8_t macCount); + +/**------------------------------------------------------------------------ + \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain + \return default regulatory domain + \sa + -------------------------------------------------------------------------*/ +v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void ); + +/**------------------------------------------------------------------------ + \brief vos_nv_getSupportedChannels() - function to return the list of + supported channels + \param p20MhzChannels - list of 20 Mhz channels + \param pNum20MhzChannels - number of 20 Mhz channels + \param p40MhzChannels - list of 20 Mhz channels + \param pNum40MhzChannels - number of 20 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels, + v_U8_t *p40MhzChannels, int *pNum40MhzChannels); + +/**------------------------------------------------------------------------ + \brief vos_nv_readDefaultCountryTable() - return the default Country table + \param table data - a union to return the default country table data in. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData ); + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelListWithPower() - function to return the list of + supported channels with the power limit info too. + \param pChannels20MHz - list of 20 Mhz channels + \param pNum20MHzChannelsFound - number of 20 Mhz channels + \param pChannels40MHz - list of 20 Mhz channels + \param pNum40MHzChannelsFound - number of 20 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *pChannels20MHz /*[NUM_LEGIT_RF_CHANNELS] */, + tANI_U8 *pNum20MHzChannelsFound, + tChannelListWithPower *pChannels40MHz /*[NUM_CHAN_BOND_CHANNELS] */, + tANI_U8 *pNum40MHzChannelsFound + ); + +/**------------------------------------------------------------------------ + + \brief vos_nv_open() - initialize the NV module + + The \a vos_nv_open() initializes the NV module. This function read the binary + file qcom_nv.bin for macaddress,country code,regulatory domain information and etc. + + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_open(void); + +/**------------------------------------------------------------------------ + + \brief vos_nv_close() - uninitialize the NV module + + The \a vos_nv_init() uninitializes the NV module. This function release the binary + file qcom_nv.bin data buffer. + + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_nv_close(void); + +/**------------------------------------------------------------------------ + \brief vos_nv_getNVBuffer - + \param pBuffer - to return the buffer address + pSize - buffer size. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer, v_SIZE_t *pSize); + +/**------------------------------------------------------------------------ + \brief vos_nv_getNVEncodedBuffer - + \param pBuffer - to return the buffer address + pSize - buffer size. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer, v_SIZE_t *pSize); + + +/**------------------------------------------------------------------------ + \brief vos_nv_getNVDictionary - + \param pBuffer - to return the buffer address + pSize - buffer size. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer, v_SIZE_t *pSize); + +/**------------------------------------------------------------------------ + \brief vos_nv_isEmbeddedNV() - NV.bin is embedded or not + + \return VOS_STATUS_SUCCESS - if NV is embedded + otherwise - NOT embedded + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_isEmbeddedNV(void); + +/**------------------------------------------------------------------------ + \brief vos_nv_setNVEncodedBuffer() - set Encode Buffer + + \return VOS_STATUS_SUCCESS - if able to set encoded buffer successfully + otherwise - NOT able to set encoded data + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size); + +/**------------------------------------------------------------------------ + \brief vos_nv_get_dictionary_data() - read dictionary data + + \return VOS_STATUS_SUCCESS - if dictionary data is read successfully + otherwise - NOT able to read dictionary data + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_get_dictionary_data(void); + +/**------------------------------------------------------------------------ + \brief vos_nv_setRegDomain - + \param clientCtxt - Client Context, Not used for PRIMA + regId - Regulatory Domain ID + sendRegHint - send hint to cfg80211 + \return status set REG domain operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + v_BOOL_t sendRegHint); + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelEnabledState - + \param rfChannel - input channel number to know enabled state + \return eNVChannelEnabledType enabled state for channel + * enabled + * disabled + * DFS + \sa + -------------------------------------------------------------------------*/ + +eNVChannelEnabledType vos_nv_getChannelEnabledState +( + v_U32_t rfChannel +); + +VOS_STATUS vos_init_wiphy_from_nv_bin(void); + +/**------------------------------------------------------------------------ + \brief vos_nv_getNvVersion - + \param NONE + \return eNvVersionType NV.bin version + * E_NV_V2 + * E_NV_V3 + * E_NV_INVALID + \sa + -------------------------------------------------------------------------*/ +eNvVersionType vos_nv_getNvVersion +( + void +); + + +/**------------------------------------------------------------------------ + \brief vos_chan_to_freq - + \param - input channel number to know channel frequency + \return Channel frequency + \sa + -------------------------------------------------------------------------*/ +v_U16_t vos_chan_to_freq(v_U8_t chanNum); + +/**------------------------------------------------------------------------ + \brief vos_freq_to_chan - + \param - input channel frequency to know channel number + \return Channel frequency + \sa + -------------------------------------------------------------------------*/ +v_U8_t vos_freq_to_chan(v_U32_t freq); + +/**------------------------------------------------------------------------ + \brief vos_is_nv_country_non_zero - + \param NONE + \return Success if default Country is Non-Zero + \sa + -------------------------------------------------------------------------*/ + +v_BOOL_t vos_is_nv_country_non_zero +( + void +); + +/**------------------------------------------------------------------------ + \brief vos_is_channel_valid_for_vht80 - + \param chan + \return TRUE if channel is 80 mhz + \sa + -------------------------------------------------------------------------*/ + +v_BOOL_t vos_is_channel_valid_for_vht80(v_U32_t chan); + +#ifdef CONFIG_ENABLE_LINUX_REG +/**------------------------------------------------------------------------ + \brief vos_getCurrentCountryCode - + \param countrycode + \return None + \sa + -------------------------------------------------------------------------*/ + +void vos_getCurrentCountryCode +( + tANI_U8 *cc +); +#endif + +int vos_update_nv_table_from_wiphy_band(void *hdd_ctx, + void *wiphy,v_U8_t nBandCapability); + +#endif // __VOS_NVITEM_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_pack_align.h b/drivers/staging/prima/CORE/VOSS/inc/vos_pack_align.h new file mode 100644 index 000000000000..6dde5184a605 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_pack_align.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_PACK_ALIGN_H ) +#define __VOS_PACK_ALIGN_H + +/**========================================================================= + + \file vos_pack_align.h + + \brief virtual Operating System Servies (vOS) pack and align primitives + + Definitions for platform independent means of packing and aligning + data structures + + + ========================================================================*/ + +/* + + Place the macro VOS_PACK_START above a structure declaration to pack. We + are not going to allow modifying the pack size because pack size cannot be + specified in AMSS and GNU. Place the macro VOS_PACK_END below a structure + declaration to stop the pack. This requirement is necessitated by Windows + which need pragma based prolog and epilog. + + Pack-size > 1-byte is not supported since gcc and arm do not support that. + + Here are some examples + + 1. Pack-size 1-byte foo_t across all platforms + + VOS_PACK_START + typedef VOS_PACK_PRE struct foo_s { ... } VOS_PACK_POST foo_t; + VOS_PACK_END + + 2. 2-byte alignment for foo_t across all platforms + + typedef VOS_ALIGN_PRE(2) struct foo_s { ... } VOS_ALIGN_POST(2) foo_t; + + 3. Pack-size 1-byte and 2-byte alignment for foo_t across all platforms + + VOS_PACK_START + typedef VOS_PACK_PRE VOS_ALIGN_PRE(2) struct foo_s { ... } VOS_ALIGN_POST(2) VOS_PACK_POST foo_t; + VOS_PACK_END + +*/ + +#if defined __GNUC__ + + #define VOS_PACK_START + #define VOS_PACK_END + + #define VOS_PACK_PRE + #define VOS_PACK_POST __attribute__((__packed__)) + + #define VOS_ALIGN_PRE(__value) + #define VOS_ALIGN_POST(__value) __attribute__((__aligned__(__value))) + +#elif defined __arm + + #define VOS_PACK_START + #define VOS_PACK_END + + #define VOS_PACK_PRE __packed + #define VOS_PACK_POST + + #define VOS_ALIGN_PRE(__value) __align(__value) + #define VOS_ALIGN_POST(__value) + +#elif defined _MSC_VER + +#define VOS_PACK_START __pragma(pack(push,1)) +#define VOS_PACK_END __pragma(pack(pop)) + + #define VOS_PACK_PRE + #define VOS_PACK_POST + + #define VOS_ALIGN_PRE(__value) __declspec(align(__value)) + #define VOS_ALIGN_POST(__value) + +#else + + #error Unsupported compiler!!! + +#endif + +#endif // __VOSS_PACK_ALIGN_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h b/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h new file mode 100644 index 000000000000..ad838d7bcf96 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_packet.h @@ -0,0 +1,1185 @@ +/* + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_PKT_H ) +#define __VOS_PKT_H + +/**========================================================================= + + \file vos_packet.h + + \brief virtual Operating System Services (vOSS) network Packet APIs + + Network Protocol packet/buffer support interfaces + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_PKT_PROTO_TYPE_EAPOL 0x02 +#define VOS_PKT_PROTO_TYPE_DHCP 0x04 +#define VOS_PKT_PROTO_TYPE_ARP 0x08 +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +struct vos_pkt_t; +typedef struct vos_pkt_t vos_pkt_t; + + +/// data vector +typedef struct +{ + /// address of data + v_VOID_t *pData; + + /// number of bytes at address + v_U32_t numBytes; + +} vos_pkt_data_vector_t; + + + +/// voss Packet Types +typedef enum +{ + /// voss Packet is used to transmit 802.11 Management frames. + VOS_PKT_TYPE_TX_802_11_MGMT, + + /// voss Packet is used to transmit 802.11 Data frames. + VOS_PKT_TYPE_TX_802_11_DATA, + + /// voss Packet is used to transmit 802.3 Data frames. + VOS_PKT_TYPE_TX_802_3_DATA, + + /// voss Packet contains Received data of an unknown frame type + VOS_PKT_TYPE_RX_RAW, + + /// Invalid sentinel value + VOS_PKT_TYPE_MAXIMUM + +} VOS_PKT_TYPE; + +/// user IDs. These IDs are needed on the vos_pkt_get/set_user_data_ptr() +/// to identify the user area in the voss Packet. +typedef enum +{ + VOS_PKT_USER_DATA_ID_TL =0, + VOS_PKT_USER_DATA_ID_BAL, + VOS_PKT_USER_DATA_ID_WDA, + VOS_PKT_USER_DATA_ID_HDD, + VOS_PKT_USER_DATA_ID_BAP, + VOS_PKT_USER_DATA_ID_BSL, + + VOS_PKT_USER_DATA_ID_MAX + +} VOS_PKT_USER_DATA_ID; + +/**------------------------------------------------------------------------ + + \brief voss asynchronous get_packet callback function + + This is a callback function invoked when vos_pkt_get_packet() cannot + get the requested packet and the caller specified a callback to be + invoked when packets are available. + + \param pPacket - the packet obtained by voss for the caller. + + \param userData - the userData field given on the vos_pkt_get_packet() + call + + \return + + \sa + + ------------------------------------------------------------------------*/ +typedef VOS_STATUS ( *vos_pkt_get_packet_callback )( vos_pkt_t *pPacket, + v_VOID_t *userData ); + +/* + * include the OS-specific packet abstraction + * we include it here since the abstraction probably needs to access the + * generic types defined above + */ +#include "i_vos_packet.h" + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet() - Get a voss Packets + + Gets a voss Packets from an internally managed packet pool. + + \param ppPacket - pointer to location where the voss Packet pointer is + returned. If multiple packets are requested, they + will be chained onto this first packet. + + \param pktType - the packet type to be retreived. Valid packet types are: +
    +
  • VOS_PKT_TYPE_TX_802_11_MGMT - voss packet is for Transmitting 802.11 + Management frames. + +
  • VOS_PKT_TYPE_RX_RAW - voss Packet contains a buffer for Receiving + raw frames of unknown type. +
+ + \param dataSize - the Data size needed in the voss Packet. + + \param numPackets - the number of packets requested. + + \param zeroBuffer - parameter that tells the API to zero the data buffer + in this voss Packet. +
    +
  • VOS_TRUE - the API will zero out the entire data buffer. + +
  • VOS_FALSE - the API will not zero out the data buffer. +
+ + \note If enough room for headers to transmit or receive the packet is not + available, this API will fail. + + \param callback - This callback function, if provided, is invoked in the + case when resources are not available at the time of the call to + get packets. This callback function is invoked when packets are + available. + + \param userData - This user data is passed back to the caller in the + callback function, if the callback is invoked. + + \return VOS_STATUS_SUCCESS - the API was able to get a vos_packet for the + requested type. *ppPacket contains a pointer to the packet. + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets for 802_11_MGMT and + RX_RAW packet types. This status is also returned if the + numPackets or dataSize are invalid. + + VOS_STATUS_E_RESOURCES - unable to get resources needed to get + a vos packet. If a callback function is specified and this + status is returned from the API, the callback will be called + when resources are available to fulfill the original request. + + Note that the low resources condition is indicated to the caller + by returning VOS_STATUS_E_RESOURCES. This status is the only + non-success status that indicates to the caller that the callback + will be called when resources are available. All other status + indicate failures that are not recoverable and the 'callback' + will not be called. + + VOS_STATUS_E_FAILURE - The API returns this status when unable + to get a packet from the packet pool because the pool + is depleted and the caller did not specify a low resource callback. + + VOS_STATUS_E_ALREADY - This status is returned when the VOS + packet pool is in a 'low resource' condition and cannot + accomodate any more calls to retrieve packets from that + pool. Note this is a FAILURE and the 'low resource' callback + will *not* be called. + + VOS_STATUS_E_FAULT - ppPacket does not specify a valid pointer. + + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet( vos_pkt_t **ppPacket, VOS_PKT_TYPE pktType, + v_SIZE_t dataSize, v_SIZE_t numPackets, + v_BOOL_t zeroBuffer, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_wrap_data_packets() - Wrap an OS provided data packet in a + vos packet. + + Takes as input an OS provided data packet and 'wraps' that packet in a + vos_packet, returning the vos_packet to the caller. + + This function is intended to be called from the HDD to wrap Tx data packets + from the OS into vos_packets before sending them to TL for transmission. + + \param ppPacket - pointer to location where the voss Packet pointer is + returned. If multiple packets are requested, they + will be chained onto this first packet. + + \param pktType - the packet type to be retreived. Valid packet types are: +
    +
  • VOS_PKT_TYPE_802_3_DATA - voss packet is for Transmitting 802.3 + data frames. + +
  • VOS_PKT_TYPE_802_11_DATA - voss Packet is for Transmitting 802.11 + data frames. +
+ + \param pOSPacket - a pointer to the Transmit packet provided by the OS. This + OS provided packet will be wrapped into a vos_packet_t. Note this + OS packet pointer can be NULL. The OS packet pointer can be inserted + into a VOS packet of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA through vos_pkt_set_os_packet(). + + \note If enough room for headers to transmit or receive the packet is not + available, this API will fail. + + \param callback - This callback function, if provided, is invoked in the + case where packets are not available at the time of the call to + return the packets to the caller (a 'low resource' condition). + + When packets become available, the callback callback function is + invoked to return a VOS packet to the caller. Note that the + OS Packet is *not* inserted into the VOS packet when it is returned + to the low resource callback. It is up to the caller to insert + the OS packet into the VOS packet by calling vos_pkt_set_os_packet() + + \param userData - This user data is passed back to the caller in the + callback function, if the callback is invoked. + + \return VOS_STATUS_SUCCESS - the API was able to get a vos_packet for the + requested type. *ppPacket contains a pointer to the packet. + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets for 802_11_MGMT and + RX_RAW packet types. + + VOS_STATUS_E_RESOURCES - unable to get resources needed to get + a vos packet. If a callback function is specified and this + status is returned from the API, the callback will be called + when resources are available to fulfill the original request. + + Note that the low resources condition is indicated to the caller + by returning VOS_STATUS_E_RESOURCES. This status is the only + non-success status that indicates to the caller that the callback + will be called when resources are available. All other status + indicate failures that are not recoverable and the 'callback' + will not be called. + + VOS_STATUS_E_FAILURE - The API returns this status when unable + to get a packet from the packet pool because the pool + is depleted and the caller did not specify a low resource callback. + + VOS_STATUS_E_ALREADY - This status is returned when the VOS + packet pool is in a 'low resource' condition and cannot + accomodate any more calls to retrieve packets from that + pool. Note this is a FAILURE and the 'low resource' callback + will *not* be called. + + VOS_STATUS_E_FAULT - ppPacket or pOSPacket do not specify valid + pointers. + + \sa vos_pkt_set_os_packet() + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_wrap_data_packet( vos_pkt_t **ppPacket, VOS_PKT_TYPE pktType, + v_VOID_t *pOSPacket, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ); + + +/*--------------------------------------------------------------------------- + + \brief vos_pkt_set_os_packet() - set the OS packet in a VOS data packet + + This API inserts an OS packet into a previously retreived VOS packet. + This API only applies to VOS packets of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA. + + There are cases where a user will need to get a VOS data packet without + having the OS packet to insert/wrap into the data packet. This could happen + if the user calls vos_pkt_wrap_data_packet() without the OS packet. + + Also, when the user hit a 'low resource' situation for data packets, the + low resource callback is going to return a VOS packet without an OS packet + attached to it. The caller who gets the packet through the low resource + callback uses this API to insert an OS packet into the VOS packet that + was returned through the low resource callback. + + \param pPacket - the voss Packet to insert the OS packet into. + + \param pOSPacket - a pointer to the Transmit packet provided by the OS. This + OS provided packet will be wrapped into a vos_packet_t. Note this + OS packet pointer can be NULL. The OS packet pointer can be inserted + into a VOS packet of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA through vos_pkt_set_os_packet(). + + Caller beware. If there is a valid OS packet wrapped into this + VOS packet already, this API will blindly overwrite the OS packet + with the new one specified on this API call. If you need to determine + or retreive the current OS packet from a VOS packet, call + vos_pkt_get_os_packet() first. + + \return VOS_STATUS_SUCCESS - the API was able to insert the OS packet into + the vos_packet. + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets of type + VOS_PKT_TYPE_802_3_DATA or VOS_PKT_TYPE_802_11_DATA. + + VOS_STATUS_E_FAULT - pPacket does not specify a valid pointer. + + \sa vos_pkt_get_os_packet() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_set_os_packet( vos_pkt_t *pPacket, v_VOID_t *pOSPacket ); + + + +/*--------------------------------------------------------------------------- + + \brief vos_pkt_get_os_packet() - get the OS packet in a VOS data packet + + This API returns the OS packet that is inserted in a VOS packet. + This API only applies to VOS packets of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA. + + \param pPacket - the voss Packet to return the OS packet from. + + \param ppOSPacket - a pointer to the location where the OS packet pointer + retreived from the VOS packet will be returned. Note this OS packet + pointer can be NULL, meaning there is no OS packet attached to this + VOS data packet. + + \param clearOSPacket - a boolean value that tells the API to clear out the + OS packet pointer from the VOS packet. Setting this to 'true' will + essentially remove the OS packet from the VOS packet. 'false' means + the OS packet remains chained to the VOS packet. In either case, + the OS packet pointer is returned to the caller. + + \return VOS_STATUS_SUCCESS - the API was able to retreive the OS packet + pointer from the VOS packet and return it to the caller in + *ppOsPacket + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets of type + VOS_PKT_TYPE_802_3_DATA or VOS_PKT_TYPE_802_11_DATA. + + VOS_STATUS_E_FAULT - pPacket or ppOsPacket does not specify a valid + pointers. + + \sa vos_pkt_set_os_packet(), vos_pkt_wrap_data_packet(), vos_pkt_return_packet() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_os_packet( vos_pkt_t *pPacket, v_VOID_t **ppOSPacket, + v_BOOL_t clearOSPacket ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_user_data_ptr() - return a pointer to user data area + of a voss Packet + + This API returns a pointer to a specified user Data area in the voss + Packet. User data areas are uniqua areas of the voss Packet that can + be used by specific components to store private data. These areas are + identified by a user "ID" and should only be accessed by the component + specified. + + \param pPacket - the voss Packet to retreive the user data pointer from. + + \param userID - the identifier for the user data area in the voss Packet + to get. + + User IDs and user data areas in the voss Packet are + available for: + - Transport Layer (TL) + - Bus Abstraction Layer (BAL) + - SDIO Services Component (SSC) + - Host Device Driver (HDD) + + \param ppUserData - pointer to location to return the pointer to the user + data. + + \return - Nothing. + + \sa + + ----------------------------------------------------------------------------*/ +v_VOID_t vos_pkt_get_user_data_ptr( vos_pkt_t *pPacket, VOS_PKT_USER_DATA_ID userID, + v_VOID_t **ppUserData ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_set_user_data_ptr() - set the user data pointer of a voss + Packet + + This API sets a pointer in the specified user Data area in the voss + Packet. User data areas are uniqua areas of the voss Packet that can + be used by specific components to store private data. These areas are + identified by a user "ID" and should only be accessed by the component + specified. + + Note: The size of the user data areas in the voss Packet are fixed. The + size of a single pointer is available in each user area. + + \param pPacket - the voss Packet to set the user pointer. + + \param userID - the identifier for the user data area in the voss Packet + to set. + + User IDs and user data areas in the voss Packet are + available for: + - Transport Layer (TL) + - Bus Abstraction Layer (BAL) + - SDIO Services Component (SSC) + - Host Device Driver (HDD) + + \param pUserData - pointer value to set in the user data area of the voss + packet.. + + \return - Nothing. + + \sa + + ----------------------------------------------------------------------------*/ +v_VOID_t vos_pkt_set_user_data_ptr( vos_pkt_t *pPacket, VOS_PKT_USER_DATA_ID userID, + v_VOID_t *pUserData ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_return_packet() - Return a voss Packet (chain) to vOSS + + This API returns a voss Packet to the internally managed packet pool. + + Note: If there are multiple packets chained to this packet, the entire + packet chain is returned to vOSS. The caller must unchain the + packets throgh vos_pkt_get_next_packet() and return them individually + if all packets in the packet chain are not to be returned. + + \param pPacket - the voss Packet(s) to return. Note all packets chained + to this packet are returned to vOSS. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_return_packet( vos_pkt_t *pPacket ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_chain_packet() - chain a voss Packet to another packet + + This API chains a voss Packet to another voss Packet, creating a packet + chain. Packets can be chained before or after the current packet in the + packet chain. + + \param pPacket - pointer to a voss packet to chain to + + \param pChainPacket - pointer to packet to chain + + \param chainAfter - boolean to specify to chain packet after or before + the input packet +
    +
  • true - chain packet AFTER pPacket (chain behind) +
  • false - chain packet BEFORE pPacket (chain in front) +
+ + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_chain_packet( vos_pkt_t *pPacket, vos_pkt_t *pChainPacket, + v_BOOL_t chainAfter ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_walk_packet_chain() - Walk packet chain and (possibly) + unchain packets + + This API will walk the voss Packet and unchain the packet from the chain, + if specified. The 'next' packet in the packet chain is returned as the + packet chain is traversed. + + \param pPacket - input vos_packet walk + + \param ppChainedPacket - pointer to location to return the 'next' voss + packet pointer in the packet chain. + NULL means there is was not packet chained + to this packet. + + \param unchainPacket - Flag that specifies if the caller wants the packet + to be removed from the packet chain. This is + provided to allow the caller to walk the packet chain + with or without breaking the chain. + +
    +
  • true - when set 'true' the API will return + the 'next' packet pointer in the voss Packte chain and + *WILL* unchain the input packet from the packet chain. + +
  • NOT false - when set 'false' the API will return + the 'next' packet pointer in the voss Packet chain but + *WILL NOT* unchain the packet chain. This option gives + the caller the ability to walk the packet chain without + modifying it in the process. +
+ + \note Having the packets chained has an implicaiton on how the return + packet API (vos_pkt_return_packet() ) operates. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket, vos_pkt_t **ppChainedPacket, + v_BOOL_t unchainPacket ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_data_vector() - Get data vectors from a voss Packet + + This API gets the complete set of Vectors (pointer / length pairs) that + describe all of the data that makes up the voss Packet. + + \param pPacket - pointer to the vOSS Packet to get the pointer/length + vector from + + \param pVector - pointer to the vector array where the vectors are returned. + + \param pNumVectors - Number of vector's in the vector array (at pVector). + On successful return, *pNumVectors is updated with the + number of pointer/length vectors at pVector populated + with valid vectors. + + Call with NULL pVector or 0 vectorSize, will return the size of vector + needed (in *pNumVectors) + + Caller allocates and frees the vector memory. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_data_vector( vos_pkt_t *pPacket, vos_pkt_data_vector_t *pVector, + v_SIZE_t *pNumVectors ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_extract_data() - Extract data from the voss Packet. + + This API extracts data from a voss Packet, copying the data into the + supplied output buffer. Note the data is copied from the vos packet + but the data remains in the vos packet and the size is unaffected. + + \param pPacket - the voss Packet to get the data from. + + \param pktOffset - the offset from the start of the voss Packet to get the + data. (i.e. 0 would be the beginning of the voss Packet). + + \param pOutputBuffer - Pointer to the location where the voss Packet data + will be copied. + + \param pOutputBufferSize - on input, contains the amount of data to extract + into the output buffer. Upon return, contains the amount of data + extracted into the output buffer. + + Note: an input of 0 in *pOutputBufferSize, means to copy *all* + data in the voss Packet into the output buffer. The caller is + responsible for assuring the output buffer size is big enough + since the size of the buffer is not being passed in! + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket, v_SIZE_t pktOffset, + v_VOID_t *pOutputBuffer, v_SIZE_t *pOutputBufferSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_extract_data_chain() - Extract data from a voss Packet chain. + + This API extracts *all* the data from a voss Packet chain, copying the + data into the supplied output buffer. Note the data is copied from + the vos packet chain but the data remains in the vos packet and the + size of the vos packets are unaffected. + + \param pPacket - the first voss Packet in the voss packet chain to + extract data. + + \param pOutputBuffer - Pointer to the location where the voss Packet data + will be copied. + + \param pOutputBufferSize - on input, contains the maximum amount of data + that can be extracted into the output buffer. Upon return, contains + the amount of data extracted from the packet chain. + + \return VOS_STATUS_SUCCESS - the data from the entire packet chain is + extracted and found at *pOutputBuffer. *pOutputBufferSize bytes + were extracted. + + VOS_STATUS_E_FAULT - pPacket, pOutputBuffer, or pOutputBufferSize + is not a valid pointer. + + VOS_STATUS_E_NOMEM - there is not enough room to extract the data + from the entire packet chain. *pOutputBufferSize has been updated + with the size needed to extract the entier packet chain. + + \sa vos_pkt_extract_data() + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_extract_data_chain( vos_pkt_t *pPacket, v_VOID_t *pOutputBuffer, + v_SIZE_t *pOutputBufferSize ); + + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_peek_data() - peek into voss Packet at given offset + + This API provides a pointer to a specified offset into a voss Packet, + allowing the caller to peek at a given number of bytes in the voss Packet. + Upon successful return, the caller can access "numBytes" of data at + "pPacketData". + + This API will fail if the data length requested to peek at is not in + contiguous memory in the voss Packet. In this case, the caller should + use vos_pkt_extract_data() to have the data copied into a caller supplied + buffer. + + \param pPacket - the vOSS Packet to peek into + + \param pktOffset - the offset into the voss Packet data to peek into. + + \param ppPacketData - pointer to the location where the pointer to the + packet data at pktOffset will be returned. + + \param numBytes - the number of bytes the caller wishes to peek at. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket, v_SIZE_t pktOffset, + v_VOID_t **ppPacketData, v_SIZE_t numBytes ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_type() - Get packet type for a voss Packet + + This API returns the packet Type for a voss Packet. + + \param pPacket - the voss Packet to get the packet type from. + + \param pPacketType - location to return the packet type for the voss Packet + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_type( vos_pkt_t *pPacket, VOS_PKT_TYPE *pPacketType ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_length() - Get packet length for a voss Packet + + This API returns the total length of the data in a voss Packet. + + \param pPacket - the voss Packet to get the packet length from. + + \param pPacketSize - location to return the total size of the data contained + in the voss Packet. + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket, v_U16_t *pPacketSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_chain_length() - Get length of a vos packet chain + + This API returns the total length of the data in a voss Packet chain. + + \param pPacket - the voss Packet at the start of the packet chain. This API + will calculate the length of data in the packet chain stating with + this packet. + + \param pPacketSize - location to return the total size of the data contained + in the voss Packet. + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_chain_length( vos_pkt_t *pPacketChain, v_SIZE_t *pPacketChainSize ); + + + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_push_head() - push data on the front a of a voss Packet + + This API will push data onto the front of a voss Packet. The data will be + appended in front of any data already contained in the voss Packet. + + \param pPacket - the voss Packet to modify. + + \param pData - pointer to the data to push onto the head of the voss Packet. + + \param dataSize - the size of the data to put onto the head of the voss Packet. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket, v_VOID_t *pData, v_SIZE_t dataSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_reserve_head() - Reserve space at the front of a voss Packet + + This API will reserve space at the front of a voss Packet. The caller can + then copy data into this reserved space using memcpy() like functions. This + allows the caller to reserve space and build headers directly in this + reserved space in the voss Packet. + + Upon successful return, the length of the voss Packet is increased by + dataSize. + + < put a before / after picture here> + + \param pPacket - the voss Packet to modify. + + \param ppData - pointer to the location where the pointer to the reserved + space is returned. Upon successful return, the caller has + write / read access to the data space at *ppData for length + dataSize to build headers, etc. + + \param dataSize - the size of the data to reserve at the head of the voss + Packet. Upon successful return, the length of the voss + Packet is increased by dataSize. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket, v_VOID_t **ppData, + v_SIZE_t dataSize ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_reserve_head_fast()- Reserve space at the front of a voss Pkt + + This API will reserve space at the front of a voss Packet. The caller can + then copy data into this reserved space using memcpy() like functions. This + allows the caller to reserve space and build headers directly in this + reserved space in the voss Packet. + + Upon successful return, the length of the voss Packet is increased by + dataSize. + + Same as above API but no memset to 0. + + < put a before / after picture here> + + \param pPacket - the voss Packet to modify. + + \param ppData - pointer to the location where the pointer to the reserved + space is returned. Upon successful return, the caller has + write / read access to the data space at *ppData for length + dataSize to build headers, etc. + + \param dataSize - the size of the data to reserve at the head of the voss + Packet. Upon successful return, the length of the voss + Packet is increased by dataSize. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_reserve_head_fast( vos_pkt_t *pPacket, + v_VOID_t **ppData, + v_SIZE_t dataSize ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_pop_head() - Remove data from the front of the voss Packet + + This API removes data from the front of a voss Packet. The data is + copied into the output buffer described by pData and pDataSize + + \param pPacket - the voss Packet to operate on. + + \param pData - pointer to the data buffer where the data removed from the + voss Packet is placed. + + \param dataSize - The amount of space to remove from the head of the voss + Packet. The output buffer (at *pData) must contain at + least this amount of space. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket, v_VOID_t *pData, v_SIZE_t dataSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_trim_head() - Skip over bytes at the front of a voss Packet + + This API moves the pointers at the head of a voss Packet to essentially + skip over data at the front of a voss Packet. Upon successful return, the + length of the voss Packet is reduced by dataSize and the starting pointer + to the voss Packet is adjusted to eliminate the data from the start of the + voss Packet. + + This API has the opposite effect of \a vos_pkt_reserve_head(). + + \param pPacket - the voss Packet to operate on. + + \param dataSize - The amount of space to skip at the start of the voss + Packet. + + Note that upon return, the data skipped over is + inaccessible to the caller. If the caller needs access + to the head data, use vos_pkt_pop_head() or + vos_pkt_extract_data() to get a copy of the data. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_trim_head( vos_pkt_t *pPacket, v_SIZE_t dataSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_push_tail() - push data on the end a of a voss Packet + + This API will push data onto the end of a voss Packet. The data will be + appended to the end of any data already contained in the voss Packet. + + \param pPacket - the voss Packet to modify. + + \param pData - pointer to the data to push onto the tail of the voss Packet. + + \param dataSize - the size of the data to put onto the tail of the voss Packet. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_push_tail( vos_pkt_t *pPacket, v_VOID_t *pData, v_SIZE_t dataSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_reserve_tail() - Reserve space at the end of a voss Packet + + This API will reserve space at the end of a voss Packet. The caller can + then copy data into this reserved space using memcpy() like functions. This + allows the caller to reserve space and build headers directly in this + reserved space in the voss Packet. + + Upon successful return, the length of the voss Packet is increased by + dataSize. + + \param pPacket - the voss Packet to modify. + + \param ppData - pointer to the location where the pointer to the reserved + space is returned. Upon successful return, the caller has + write / read access to the data space at *ppData for length + dataSize to build headers, etc. + + \param dataSize - the size of the data to reserve at the head of the voss + Packet. Upon successful return, the length of the voss + Packet is increased by dataSize. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_reserve_tail( vos_pkt_t *pPacket, v_VOID_t **ppData, + v_SIZE_t dataSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_pop_tail() - Remove data from the end of the voss Packet + + This API removes data from the end of a voss Packet. The data is + copied into the output buffer described by pData and pDataSize + + \param pPacket - the voss Packet to operate on. + + \param pData - pointer to the data buffer where the data removed from the + voss Packet is placed. + + \param dataSize - The amount of space to remove from the end of the voss + Packet. The output buffer (at *pData) must contain at + least this amount of space. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_pop_tail( vos_pkt_t *pPacket, v_VOID_t *pData, v_SIZE_t dataSize ); + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_trim_tail() - Skip over bytes at the end of a voss Packet + + This API moves the pointers at the head of a voss Packet to essentially + skip over data at the end of a voss Packet. Upon successful return, the + length of the voss Packet is reduced by dataSize and voss Packet is + adjusted to eliminate the data from the end of the voss Packet. + + This API has the opposite effect of \a vos_pkt_reserve_tail(). + + \param pPacket - the voss Packet to operate on. + + \param dataSize - The amount of space to remove at the end of the voss + Packet. + + Note that upon return, the data skipped over is + inaccessible to the caller. If the caller needs access + to the tail data, use vos_pkt_pop_tail() or + vos_pkt_extract_data() to get a copy of the data. + + \return + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_trim_tail( vos_pkt_t *pPacket, v_SIZE_t dataSize ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_timestamp() - Retrive the timestamp attribute from the + specified VOSS packet + + \param pPacket - the voss Packet to operate on. + + \param pTstamp - the timestamp will be returned here. + + \return VOS_STATUS_E_FAULT - invalid parameter(s) specified + + VOS_STATUS_SUCCESS - timestamp retrived successfully + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket, v_TIME_t* pTstamp ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_flatten_rx_pkt() - Transform a platform based RX VOSS + packet into a flat buffer based VOSS packet if needed. This is needed in cases + where for reasons of efficiency we want the RX packets to be very platform specific + (for e.g. DSM based on AMSS, etc). However platform independent code may rely + on making calls on the VOSS packet which can only be supported by the flat buffer + based implementation of a RX packet. This API will allocate a new VOSS packet + with flat buffer, extract the data from the input VOSS packet and then release + the input VOSS packet. The new VOSS packet will be returned from this call. + + \param ppPacket - the voss Packet to operate on. on input contains + the platform based packet. On output contains the flat + buffer based packet. Any applicable resources + are freed as part of this call. + + \return VOS_STATUS_E_FAULT - invalid parameter specified + + VOS_STATUS_E_INVAL - packet type not RX_RAW + + VOS_STATUS_SUCCESS - transform successful + + other VOSS status - other errors encountered + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_flatten_rx_pkt( vos_pkt_t **ppPacket ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_set_rx_length() - Set the length of a received packet + + This API set the length of the data inside the packet after a DMA has occurred + on rx, it will also set the tail pointer to the end of the data. + + \param pPacket - the voss Packet to operate on. + + \param pktLen - The size of the data placed in the Rx packet during DMA. + + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_set_rx_length( vos_pkt_t *pPacket, v_SIZE_t pktLen ); + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_available_buffer_pool() - Get avaliable VOS packet size + VOSS Packet pool is limitted resource + VOSS Client need to know how many packet pool is still avaliable to control the flow + + \param pktType - Packet type want to know free buffer count + VOS_PKT_TYPE_TX_802_11_MGMT, management free buffer count, + VOS_PKT_TYPE_TX_802_11_DATA + VOS_PKT_TYPE_TX_802_3_DATA, TX free buffer count + VOS_PKT_TYPE_RX_RAW, RX free buffer count + + vosFreeBuffer - free frame buffer size + + \return VOS_STATUS_E_INVAL - invalid input parameter + + VOS_STATUS_SUCCESS - Get size success + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_available_buffer_pool +( + VOS_PKT_TYPE pktType, + v_SIZE_t *vosFreeBuffer +); + +/** + @brief vos_pkt_get_num_of_rx_raw_pkts() - Get the number of RX packets + that should be allocated. + + This function is called by VOS packet module to know how many RX raw + packets it should allocate/reserve. This value can be configured thru + Kernel device tree to save memory usage. + + @param + NONE + @return + v_SIZE_t the number of packets to allocate + +*/ +v_SIZE_t vos_pkt_get_num_of_rx_raw_pkts(void); + +/** + @brief vos_pkt_get_num_of_rx_pkt_alloc_failures() - Get the number of times + skb allocation failed while replenishing packets + + + @param + NONE + @return + v_SIZE_t the number of times packet allocation failed + +*/ +v_SIZE_t vos_pkt_get_num_of_rx_pkt_alloc_failures(void); + +v_U8_t vos_pkt_get_proto_type +( + void *pskb, + v_U8_t tracking_map +); + +/** + @brief vos_get_pkt_head() - Get skb head pointer + + @param + pPacket - the voss Packet to operate on + @return + v_PVOID_t - skb head pointer + +*/ +v_PVOID_t vos_get_pkt_head(vos_pkt_t *pPacket); + +/** + + @brief vos_get_pkt_end() - Get skb end pointer + + @param + pPacket - the voss Packet to operate on + @return + v_PVOID_t - skb end pointer + +*/ +v_PVOID_t vos_get_pkt_end(vos_pkt_t *pPacket); + +/** + + @brief vos_recover_tail() - Recover corrupted tail of skb + + @param + pPacket - the voss Packet to operate on + @return + v_VOID_t - None + +*/ +v_VOID_t vos_recover_tail(vos_pkt_t *pPacket); + +/** + @breaf vos_is_arp_pkt() - Check the packet is ARP or not. + + @param + pskb - pointer to skb + is_translated - header translation check + @return + TRUE - if packet is ARP + FALSE -if packet is not ARP +*/ +bool vos_is_arp_pkt(void *pskb, bool is_translated); + +#endif // !defined( __VOS_PKT_H ) diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_status.h b/drivers/staging/prima/CORE/VOSS/inc/vos_status.h new file mode 100644 index 000000000000..b41f56d3a93c --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_status.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_STATUS_H ) +#define __VOS_STATUS_H + +/**========================================================================= + + \file vos_Status.h + + \brief virtual Operating System Services (vOSS) Status codes + + Basic status codes/definitions used by vOSS + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef enum +{ + /// Request succeeded! + VOS_STATUS_SUCCESS, + + /// Request failed because system resources (other than memory) to + /// fulfill request are not available. + VOS_STATUS_E_RESOURCES, + + /// Request failed because not enough memory is available to + /// fulfill the request. + VOS_STATUS_E_NOMEM, + + /// Request could not be fulfilled at this time. Try again later. + VOS_STATUS_E_AGAIN, + + /// Request failed because there of an invalid request. This is + /// typically the result of invalid parameters on the request. + VOS_STATUS_E_INVAL, + + /// Request failed because handling the request would cause a + /// system fault. This error is typically returned when an + /// invalid pointer to memory is detected. + VOS_STATUS_E_FAULT, + + /// Request refused becayse a request is already in progress and + /// another cannot be handled currently. + VOS_STATUS_E_ALREADY, + + /// Request failed because the message (type) is bad, invalid, or + /// not properly formatted. + VOS_STATUS_E_BADMSG, + + /// Request failed because device or resource is busy. + VOS_STATUS_E_BUSY, + + /// Request did not complete because it was canceled. + VOS_STATUS_E_CANCELED, + + /// Request did not complete because it was aborted. + VOS_STATUS_E_ABORTED, + + /// Request failed because the request is valid, though not supported + /// by the entity processing the request. + VOS_STATUS_E_NOSUPPORT, + + /// Operation is not permitted. + VOS_STATUS_E_PERM, + + /// Request failed because of an empty condition + VOS_STATUS_E_EMPTY, + + /// Existance failure. Operation could not be completed because + /// something exists or does not exist. + VOS_STATUS_E_EXISTS, + + /// Operation timed out + VOS_STATUS_E_TIMEOUT, + + /// Request failed for some unknown reason. Note don't use this + /// status unless nothing else applies + VOS_STATUS_E_FAILURE + +} VOS_STATUS; + +/// Macro to determine if a VOS_STATUS type is success. All callers +/// wanting to interpret VOS_STATUS should use this macro to check +/// for success to protect against the VOS_STATUS definitions +/// changing. +/// +/// Use like this... +/// +/// if ( VOS_STATUS_SUCCESS( vosStatus ) ) ... +/// +#define VOS_IS_STATUS_SUCCESS( status ) ( VOS_STATUS_SUCCESS == ( status ) ) + + + +#endif // if !defined __VOS_STATUS_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_threads.h b/drivers/staging/prima/CORE/VOSS/inc/vos_threads.h new file mode 100644 index 000000000000..2b3bdd7af955 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_threads.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_THREADS_H ) +#define __VOS_THREADS_H + +/**========================================================================= + + \file vos_threads.h + + \brief virtual Operating System Services (vOSS) Threading APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_sleep() - sleep + + The \a vos_sleep() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param msInterval - the number of milliseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep( v_U32_t msInterval ); + +/*---------------------------------------------------------------------------- + + \brief vos_sleep_us() - sleep + + The \a vos_sleep_us() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param usInterval - the number of microseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep_us( v_U32_t usInterval ); + + +/*---------------------------------------------------------------------------- + + \brief vos_busy_wait() - busy wait + + The \a vos_busy_wait() function places the current thread in busy wait + until the specified time out interval elapses. If the interval is greater + than 50us on WM, the behaviour is undefined. + + \param usInterval - the number of microseconds to busy wait. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_busy_wait( v_U32_t usInterval ); + +#endif // __VOS_THREADS_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h b/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h new file mode 100644 index 000000000000..12e2f7cc13c1 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_timer.h @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_TIMER_H ) +#define __VOS_TIMER_H + +/**========================================================================= + + \file vos_timer.h + + \brief virtual Operating System Servies (vOS) + + Definitions for vOSS Timer services + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include + +#ifdef TIMER_MANAGER +#include "wlan_hdd_dp_utils.h" +#endif + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_TIMER_STATE_COOKIE 0x12 + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ +/// vos Timer callback function prototype (well, actually a prototype for +/// a pointer to this callback function) +typedef v_VOID_t ( *vos_timer_callback_t )( v_PVOID_t userData ); + +typedef enum +{ + /// pure software timer. No guarantee the apps processor will + /// awaken when these timers expire. + VOS_TIMER_TYPE_SW, + + /// These timers can awaken the Apps processor from power collapse + /// when these timers expire. + /// \todo I really dont like this name :-) + VOS_TIMER_TYPE_WAKE_APPS + +} VOS_TIMER_TYPE; + +typedef enum +{ + VOS_TIMER_STATE_UNUSED = VOS_TIMER_STATE_COOKIE, + VOS_TIMER_STATE_STOPPED, + VOS_TIMER_STATE_STARTING, + VOS_TIMER_STATE_RUNNING, +} VOS_TIMER_STATE; + +#ifdef TIMER_MANAGER +struct vos_timer_s; +typedef struct timer_node_s +{ + hdd_list_node_t pNode; + char* fileName; + unsigned int lineNum; + struct vos_timer_s *vosTimer; +}timer_node_t; +#endif + +typedef struct vos_timer_s +{ +#ifdef TIMER_MANAGER + timer_node_t *ptimerNode; +#endif + + vos_timer_platform_t platformInfo; + vos_timer_callback_t callback; + v_PVOID_t userData; + vos_lock_t lock; + VOS_TIMER_TYPE type; + VOS_TIMER_STATE state; +} vos_timer_t; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +void vos_timer_manager_init(void); +void vos_timer_exit(void); +#endif + +/*--------------------------------------------------------------------------- + + \brief vos_timer_getCurrentState() - Get the current state of the timer + + \param pTimer - the timer object + + \return timer state + + \sa + +---------------------------------------------------------------------------*/ +VOS_TIMER_STATE vos_timer_getCurrentState( vos_timer_t *pTimer ); + +/*-------------------------------------------------------------------------- + + \brief vos_timer_init() - Initialize a vOSS timer. + + This API initializes a vOS Timer object. + + The \a vos_timer_init() initializes a vOS Timer object. A timer must be + initialized by calling vos_timer_initialize() before it may be used in + any other timer functions. + + Attempting to initialize timer that is already initialized results in + a failure. A destroyed timer object can be re-initialized with a call to + \a vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer such + as vos_timer_set() will fail if the timer is not initialized or has + been destroyed. Therefore, don't use the timer after it has been + destroyed until it has been re-initialized. + + All callback will be executed within the VOS main thread unless it is + initialized from the Tx thread flow, in which case it will be executed + within the tx thread flow. + + \param timer - pointer to the opaque timer object to initialize + + \param timerType - specifies the type of timer. We have two different + timer types. +
    +
  1. VOS_TIMER_TYPE_SW - Pure software timer. The Apps processor + may not be awoken when this timer expires. +
  2. VOS_TIMER_TYPE_WAKE_APPS - The Apps processor will be awoken + from power collapse when this type of timer expires. +
+ + \param callback - the callback function to be called when the timer + expires. + + \param userData - a user data (or context) that is returned to the + callback function as a parameter when the timer expires. + + \return VOS_STATUS_SUCCESS - timer was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the timer + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the timer + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to initialize the object referenced by timer, a previously + initialized but not yet destroyed timer. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +#define vos_timer_init(timer, timerType, callback, userdata) \ + vos_timer_init_debug(timer, timerType, callback, userdata, \ + __FILE__, __LINE__) + +VOS_STATUS vos_timer_init_debug( vos_timer_t *timer, VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData, + char* fileName, v_U32_t lineNum ); + +#define vos_timer_init_deferrable(timer, timerType, callback, userdata) \ + vos_timer_init_deferrable_debug(timer, timerType, \ + callback, userdata, __FILE__, __LINE__) + +VOS_STATUS vos_timer_init_deferrable_debug( vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData, + char* fileName, v_U32_t lineNum ); +#else +VOS_STATUS vos_timer_init( vos_timer_t *timer, VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData ); +VOS_STATUS vos_timer_init_deferrable( vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, v_PVOID_t userData ); +#endif + +/*--------------------------------------------------------------------------- + + \brief vos_timer_destroy() - Destroy a vOSS Timer object + + The \a vos_timer_destroy() function shall destroy the timer object. + After a successful return from \a vos_timer_destroy() the timer + object becomes, in effect, uninitialized. + + A destroyed timer object can be re-initialized by calling + vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer, such + as vos_timer_set() will fail if the lock is destroyed. Therefore, + don't use the timer after it has been destroyed until it has + been re-initialized. + + \param timer - the timer object to be destroyed. + + \return VOS_STATUS_SUCCESS - timer was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by timer while it is still + still referenced. The timer must be stopped before it can be + destroyed. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_destroy( vos_timer_t *timer ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_start() - Start a vOSS Timer object + + The \a vos_timer_start() function starts a timer to expire after the + specified interval, thus running the timer callback function when + the interval expires. + + A timer only runs once (a one-shot timer). To re-start the + timer, vos_timer_start() has to be called after the timer runs + or has been cancelled. + + \param timer - the timer object to be started + + \param expirationTime - expiration time for the timer (in milliseconds) + The expiration time cannot be less than 10 ms. + + \return VOS_STATUS_SUCCESS - timer was successfully started. + + VOS_STATUS_E_ALREADY - The implementation has detected an attempt + to start a timer while it is already started. The timer must + be stopped or expire before it can be started again. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_start( vos_timer_t *timer, v_U32_t expirationTime ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_stop() - Stop a vOSS Timer + + The \a vos_timer_stop() function stops a timer that has been started but + has not expired, essentially cancelling the 'start' request. + + After a timer is stopped, it goes back to the state it was in after it + was created and can be started again via a call to vos_timer_start(). + + \param timer - the timer object to be stopped + + \return VOS_STATUS_SUCCESS - timer was successfully stopped. + + VOS_STATUS_E_EMPTY - The implementation has detected an attempt + to stop a timer that has not been started or has already + expired. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_stop( vos_timer_t *timer ); + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_ticks() - Get the system time in 10ms ticks + + The \a vos_timer_get_system_ticks() function returns the current number + of timer ticks in 10msec intervals. This function is suitable timestamping + and calculating time intervals by calculating the difference between two + timestamps. + + \returns - The current system tick count (in 10msec intervals). This + function cannot fail. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_ticks( v_VOID_t ); + +/** + * vos_system_time_after() - Check if a is later than b + * @a: Time stamp value a + * @b: Time stamp value b + * + * Return: + * true if a is after b else false + */ +static inline bool vos_system_time_after(v_TIME_t a, v_TIME_t b) +{ + return (long)(b) - (long)(a) < 0; +} + + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_time() - Get the system time in milliseconds + + The \a vos_timer_get_system_time() function returns the number of milliseconds + that have elapsed since the system was started + + \returns - The current system time in milliseconds. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_time( v_VOID_t ); + +v_BOOL_t vos_timer_is_initialized(vos_timer_t *timer); + +void vos_process_wd_timer(void); +void vos_wdthread_init_timer_work(void *callbackptr); +void vos_wdthread_flush_timer_work(void); +#endif // #if !defined __VOSS_TIMER_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_trace.h b/drivers/staging/prima/CORE/VOSS/inc/vos_trace.h new file mode 100644 index 000000000000..538f58d02258 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_trace.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_TRACE_H ) +#define __VOS_TRACE_H + +/**========================================================================= + + \file vos_trace.h + + \brief virtual Operating System Servies (vOS) + + Trace, logging, and debugging definitions and APIs + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include // For VOS_MODULE_ID... +#include // For va_list... +#include +#include + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +typedef enum +{ + // NONE means NO traces will be logged. This value is in place for the + // vos_trace_setlevel() to allow the user to turn off all traces. + VOS_TRACE_LEVEL_NONE = 0, + + // the following trace levels are the ones that 'callers' of VOS_TRACE() + // can specify in for the VOS_TRACE_LEVEL parameter. Traces are classified + // by severity (FATAL being more serious than INFO for example). + VOS_TRACE_LEVEL_FATAL, + VOS_TRACE_LEVEL_ERROR, + VOS_TRACE_LEVEL_WARN, + VOS_TRACE_LEVEL_INFO, + VOS_TRACE_LEVEL_INFO_HIGH, + VOS_TRACE_LEVEL_INFO_MED, + VOS_TRACE_LEVEL_INFO_LOW, + VOS_TRACE_LEVEL_DEBUG, + + // ALL means all trace levels will be active. This value is in place for the + // vos_trace_setlevel() to allow the user to turn ON all traces. + VOS_TRACE_LEVEL_ALL, + + + // not a real level. Used to identify the maximum number of + // VOS_TRACE_LEVELs defined. + VOS_TRACE_LEVEL_MAX + +} VOS_TRACE_LEVEL; + +/* Log types. These types are defined in mailbox*/ +typedef enum +{ + WLAN_MGMT_FRAME_LOGS = 0, + WLAN_FW_LOGS = 1, + WLAN_FW_MEMORY_DUMP = 2 +}FrameLoggingType; + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define ASSERT_BUFFER_SIZE ( 512 ) + +// below definition is obsolete and is no longer being used in BMP and WM +// TODO: remove this once this is not used on Android +#define VOS_ENABLE_TRACING +#define MAX_VOS_TRACE_RECORDS 4000 +#define INVALID_VOS_TRACE_ADDR 0xffffffff +#define DEFAULT_VOS_TRACE_DUMP_COUNT 0 + +#include + +#ifdef TRACE_RECORD + +#define CASE_RETURN_STRING( str ) \ + case ( ( str ) ): return( (tANI_U8*)(#str) ); + +#define MTRACE(p) p +#define NO_SESSION 0xFF + +#else +#define MTRACE(p) { } + +#endif + +/*-------------------------------------------------------------------------- + Structure definition + ------------------------------------------------------------------------*/ +typedef struct svosTraceRecord +{ + v_U32_t time; + v_U8_t module; + v_U8_t code; + v_U8_t session; + v_U32_t data; +}tvosTraceRecord, *tpvosTraceRecord; + +typedef struct svosTraceData +{ + // MTRACE logs are stored in ring buffer where head represents the position + // of first record, tail represents the position of last record added till + // now and num is the count of total record added. + v_U32_t head; + v_U32_t tail; + v_U32_t num; + v_U16_t numSinceLastDump; + + //Config for controlling the trace + v_U8_t enable; + v_U16_t dumpCount; //will dump after number of records reach this number. + +}tvosTraceData; + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------- + + \brief vos_trace_setLevel() - Set the trace level for a particular module + + This is an external API that allows trace levels to be set for each module. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \return nothing + + \sa + --------------------------------------------------------------------------*/ +void vos_trace_setLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level ); + +/**---------------------------------------------------------------------------- + + \brief vos_trace_getLevel() - Get the trace level + + This is an external API that returns a boolean value to signify if a + particular trace level is set for the specified module. + + \param level - trace level. A member of the VOS_TRACE_LEVEL enumeration + indicating the severity of the condition causing the trace + message to be issued. + + Note that individual trace levels are the only valid values + for this API. VOS_TRACE_LEVEL_NONE and VOS_TRACE_LEVEL_ALL + are not valid input and will return FALSE + + \return VOS_FALSE - the specified trace level for the specified module is OFF + + VOS_TRUE - the specified trace level for the specified module is ON + + \sa vos_trace_setLevel() + --------------------------------------------------------------------------*/ +v_BOOL_t vos_trace_getLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level ); + +typedef void (*tpvosTraceCb) (void *pMac, tpvosTraceRecord, v_U16_t); +typedef void (*tp_vos_state_info_cb) (void); + +void vos_trace(v_U8_t module, v_U8_t code, v_U8_t session, v_U32_t data); +void vosTraceRegister(VOS_MODULE_ID, tpvosTraceCb); +void vos_register_debug_callback(VOS_MODULE_ID moduleID, + tp_vos_state_info_cb vosStateInfoCb); +VOS_STATUS vos_trace_spin_lock_init(void); +void vosTraceInit(void); +void vos_register_debugcb_init(void); +void vosTraceEnable(v_U32_t, v_U8_t enable); +void vosTraceDumpAll(void*, v_U8_t, v_U8_t, v_U32_t, v_U32_t); +void vos_state_info_dump_all(void); +#endif diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_types.h b/drivers/staging/prima/CORE/VOSS/inc/vos_types.h new file mode 100755 index 000000000000..70387494ad41 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_types.h @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_TYPES_H ) +#define __VOS_TYPES_H + +/**========================================================================= + \file vos_Types.h + + \brief virtual Operating System Servies (vOS) + + Basic type definitions + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "i_vos_types.h" +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +// macro to get maximum of two values. +#define VOS_MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) ) + +// macro to get minimum of two values +#define VOS_MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) ) + +// macro to get the ceiling of an integer division operation... +#define VOS_CEIL_DIV( _a, _b ) (( 0 != (_a) % (_b) ) ? ( (_a) / (_b) + 1 ) : ( (_a) / (_b) )) + +// macro to return the floor of an integer division operation +#define VOS_FLOOR_DIV( _a, _b ) ( ( (_a) - ( (_a) % (_b) ) ) / (_b) ) + +#define VOS_SWAP_U16(_x) \ + ( ( ( (_x) << 8 ) & 0xFF00 ) | ( ( (_x) >> 8 ) & 0x00FF ) ) + +#define VOS_SWAP_U32(_x) \ + (( ( ( (_x) << 24 ) & 0xFF000000 ) | ( ( (_x) >> 24 ) & 0x000000FF ) ) | \ + ( ( ( (_x) << 8 ) & 0x00FF0000 ) | ( ( (_x) >> 8 ) & 0x0000FF00 ) )) + +/* Length enough to include full DHCP/EAPOL/Management frame */ +#define MAX_PKT_STAT_DATA_LEN 800 + +// Endian operations for Big Endian and Small Endian modes +#ifdef ANI_LITTLE_BYTE_ENDIAN + +#define vos_cpu_to_be32(_x) VOS_SWAP_U32(_x) +#define vos_be32_to_cpu(_x) VOS_SWAP_U32(_x) +#define vos_cpu_to_be16(_x) VOS_SWAP_U16(_x) +#define vos_be16_to_cpu(_x) VOS_SWAP_U16(_x) +#define vos_cpu_to_le32(_x) (_x) +#define vos_le32_to_cpu(_x) (_x) +#define vos_cpu_to_le16(_x) (_x) +#define vos_le16_to_cpu(_x) (_x) + +#endif + +#ifdef ANI_BIG_BYTE_ENDIAN + +#define vos_cpu_to_be32(_x) (_x) +#define vos_be32_to_cpu(_x) (_x) +#define vos_cpu_to_be16(_x) (_x) +#define vos_be16_to_cpu(_x) (_x) +#define vos_cpu_to_le32(_x) VOS_SWAP_U32(_x) +#define vos_le32_to_cpu(_x) VOS_SWAP_U32(_x) +#define vos_cpu_to_le16(_x) VOS_SWAP_U16(_x) +#define vos_le16_to_cpu(_x) VOS_SWAP_U16(_x) + +#endif + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/// Module IDs. These are generic IDs that identify the various modules +/// in the software system. +typedef enum +{ + VOS_MODULE_ID_BAP = 0, + VOS_MODULE_ID_TL = 1, + VOS_MODULE_ID_WDI = 2, + VOS_MODULE_ID_SVC = 3, + // 4 is unused for historical purposes + VOS_MODULE_ID_RSV4 = 4, + VOS_MODULE_ID_HDD = 5, + VOS_MODULE_ID_SME = 6, + VOS_MODULE_ID_PE = 7, + VOS_MODULE_ID_WDA = 8, + VOS_MODULE_ID_SYS = 9, + VOS_MODULE_ID_VOSS = 10, + VOS_MODULE_ID_SAP = 11, + VOS_MODULE_ID_HDD_SOFTAP = 12, + VOS_MODULE_ID_PMC = 13, + VOS_MODULE_ID_HDD_DATA = 14, + VOS_MODULE_ID_HDD_SAP_DATA = 15, + + // not a real module ID. This is used to identify the maxiumum + // number of VOS_MODULE_IDs and should always be at the END of + // this enum. If IDs are added, they need to go in front of this + VOS_MODULE_ID_MAX + +} VOS_MODULE_ID; + + +/// Concurrency role. These are generic IDs that identify the various roles +/// in the software system. +typedef enum +{ /*ON linux maintain 1-1 corespondence with device_mode_t in hdd*/ + VOS_STA_MODE=0, + VOS_STA_SAP_MODE=1, //to support softAp mode . This is misleading. It means AP MODE only. + //The constant name has historical reason + VOS_P2P_CLIENT_MODE, + VOS_P2P_GO_MODE, + VOS_MONITOR_MODE, + VOS_FTM_MODE = 5, + VOS_IBSS_MODE, + VOS_P2P_DEVICE, + VOS_MAX_NO_OF_MODE +} tVOS_CON_MODE; + +//This is a bit pattern to be set for each mode +//bit 0 - sta mode +//bit 1 - ap mode +//bit 2 - p2p client mode +//bit 3 - p2p go mode +typedef enum +{ + VOS_STA=1, + VOS_SAP=2, + VOS_STA_SAP=3, //to support sta, softAp mode . This means STA+AP mode + VOS_P2P_CLIENT=4, + VOS_P2P_GO=8, + VOS_MAX_CONCURRENCY_PERSONA=4 +} tVOS_CONCURRENCY_MODE; + +#if !defined( NULL ) +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +enum +{ + VOS_FALSE = 0, + VOS_TRUE = ( !VOS_FALSE ) +}; + +/// pointer to void types +typedef v_VOID_t *v_PVOID_t; + +/// "Size" type... +typedef v_UINT_t v_SIZE_t; + +/// 'Time' type +typedef v_ULONG_t v_TIME_t; + +// typedef for VOSS Context... +typedef v_VOID_t *v_CONTEXT_t; + + +/// MAC address data type and corresponding macros/functions to +/// manipulate MAC addresses... +/// Macro defining the size of a MAC Address... +#define VOS_MAC_ADDR_SIZE ( 6 ) + +typedef struct +{ + /// the bytes that make up the macAddress. + v_BYTE_t bytes[ VOS_MAC_ADDR_SIZE ]; + +} v_MACADDR_t; + + +/// This macro is used to initialize a vOSS MacAddress to the +/// broadcast MacAddress. It is used like this... +/// v_MACADDR_t macAddress = VOS_MAC_ADDR_BROADCAST_INITIALIZER; +#define VOS_MAC_ADDR_BROADCAST_INITIALIZER { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } + +/// This macro is used to initialize a vOSS MacAddress to zero +/// It is used like this... +/// v_MACADDR_t macAddress = VOS_MAC_ADDR_ZERO_INITIALIZER; +#define VOS_MAC_ADDR_ZERO_INITIALIZER { { 0, 0, 0, 0, 0, 0 } } + + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_equal() - compare two vOSS MacAddress + + This function returns a boolean that tells if a two vOSS MacAddress' + are equivalent. + + \param pMacAddr1 - pointer to one voss MacAddress to compare + \param pMacAddr2 - pointer to the other voss MacAddress to compare + + \return true - the MacAddress's are equal + not true - the MacAddress's are not equal + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_equal( v_MACADDR_t *pMacAddr1, + v_MACADDR_t *pMacAddr2 ) +{ + return ( 0 == memcmp( pMacAddr1, pMacAddr2, VOS_MAC_ADDR_SIZE ) ); +} + + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_zero() - check for a MacAddress of all zeros. + + This function returns a boolean that tells if a MacAddress is made up of + all zeros. + + \param pMacAddr - pointer to the v_MACADDR_t to check. + + \return true - the MacAddress is all Zeros + not true - the MacAddress is not all Zeros. + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_zero( v_MACADDR_t *pMacAddr ) +{ + v_MACADDR_t zeroMacAddr = VOS_MAC_ADDR_ZERO_INITIALIZER; + + return( vos_is_macaddr_equal( pMacAddr, &zeroMacAddr ) ); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_zero_macaddr() - zero out a MacAddress + + This function zeros out a vOSS MacAddress type. + + \param pMacAddr - pointer to the v_MACADDR_t to zero. + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t vos_zero_macaddr( v_MACADDR_t *pMacAddr ) +{ + memset( pMacAddr, 0, VOS_MAC_ADDR_SIZE ); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_group() - check for a MacAddress is a 'group' address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "group" address. Group addresses have the 'group address bit' turned + on in the MacAddress. Group addresses are made up of Broadcast and + Multicast addresses. + + \param pMacAddr1 - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a Group address + not true - the input MacAddress is not a Group address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_group( v_MACADDR_t *pMacAddr ) +{ + return( pMacAddr->bytes[ 0 ] & 0x01 ); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_broadcast() - check for a MacAddress is a broadcast address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "broadcast" address. + + \param pMacAddr - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a broadcast address + not true - the input MacAddress is not a broadcast address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_broadcast( v_MACADDR_t *pMacAddr ) +{ + v_MACADDR_t broadcastMacAddr = VOS_MAC_ADDR_BROADCAST_INITIALIZER; + + return( vos_is_macaddr_equal( pMacAddr, &broadcastMacAddr ) ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_multicast() - check for a MacAddress is a multicast address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "Multicast" address. + + \param pMacAddr - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a Multicast address + not true - the input MacAddress is not a Multicast address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_multicast( v_MACADDR_t *pMacAddr ) +{ + return( vos_is_macaddr_group( pMacAddr ) && + !vos_is_macaddr_broadcast( pMacAddr ) ); +} + + + +/*---------------------------------------------------------------------------- + + \brief vos_is_macaddr_directed() - check for a MacAddress is a directed address + + This function returns a boolean that tells if a the input vOSS MacAddress + is a "directed" address. + + \param pMacAddr - pointer to the voss MacAddress to check + + \return true - the input MacAddress is a directed address + not true - the input MacAddress is not a directed address + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_BOOL_t vos_is_macaddr_directed( v_MACADDR_t *pMacAddr ) +{ + return( !vos_is_macaddr_group( pMacAddr ) ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_copy_macaddr() - copy a vOSS MacAddress + + This function copies a vOSS MacAddress into another vOSS MacAddress. + + \param pDst - pointer to the voss MacAddress to copy TO (the destination) + \param pSrc - pointer to the voss MacAddress to copy FROM (the source) + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t vos_copy_macaddr( v_MACADDR_t *pDst, v_MACADDR_t *pSrc ) +{ + *pDst = *pSrc; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_set_macaddr_broadcast() - set a vOSS MacAddress to the 'broadcast' + + This function sets a vOSS MacAddress to the 'broadcast' MacAddress. Broadcast + MacAddress contains all 0xFF bytes. + + \param pMacAddr - pointer to the voss MacAddress to set to broadcast + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +VOS_INLINE_FN v_VOID_t vos_set_macaddr_broadcast( v_MACADDR_t *pMacAddr ) +{ + memset( pMacAddr, 0xff, VOS_MAC_ADDR_SIZE ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_set() - set a variable atomically + + \param pTarget - pointer to the variable to set. + + \param value - the value to set in the variable. + + \return This function returns the value previously in the uintptr_t before + the new value is set. + + \sa vos_atomic_increment_U32(), vos_atomic_decrement_U32() + + --------------------------------------------------------------------------*/ +uintptr_t vos_atomic_set( uintptr_t *pTarget, uintptr_t value ); + + +// TODO: the below function is a stub to perform atomic set on a BYTE +// Clearly the function below is not an atomic function +VOS_INLINE_FN v_U8_t vos_atomic_set_U8( v_U8_t *pVariable, v_U8_t value ) +{ + if (pVariable == NULL) + { + return 0; + } + *pVariable = value; + return value; +} + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_increment_U32() - Increment a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to increment. + + \return This function returns the value of the variable after the + increment occurs. + + \sa vos_atomic_decrement_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_increment_U32( v_U32_t *pTarget ); + + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_decrement_U32() - Decrement a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to decrement. + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_decrement_U32( v_U32_t *pTarget ); + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_increment_U32_by_value() - Increment a U32 variable atomically + by a given value + + \param pTarget - pointer to the v_U32_t to decrement. + \param value - the value that needs to be added to target + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_increment_U32_by_value( v_U32_t *pTarget, v_U32_t value ); + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_decrement_U32_by_value() - Decrement a U32 variable atomically + by a given value + + \param pTarget - pointer to the v_U32_t to decrement. + \param value - the value that needs to be substracted from target + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_decrement_U32_by_value( v_U32_t *pTarget, v_U32_t value ); + + +v_U32_t vos_get_skip_ssid_check(void); + +v_U32_t vos_get_skip_11e_check(void); + + + +#endif // if !defined __VOSS_TYPES_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/vos_utils.h b/drivers/staging/prima/CORE/VOSS/inc/vos_utils.h new file mode 100644 index 000000000000..59ce11261cc4 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/vos_utils.h @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#if !defined( __VOS_UTILS_H ) +#define __VOS_UTILS_H + +/**========================================================================= + + \file vos_utils.h + + \brief virtual Operating System Services (vOSS) utility APIs + + Various utility functions + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +//#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +#define VOS_DIGEST_SHA1_SIZE 20 +#define VOS_DIGEST_MD5_SIZE 16 +#define VOS_BAND_2GHZ 1 +#define VOS_BAND_5GHZ 2 + +#define VOS_24_GHZ_CHANNEL_14 14 + + +/* Type of packet log events. + */ +#define PKTLOG_TYPE_PKT_STAT 9 + + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +VOS_STATUS vos_crypto_init( v_U32_t *phCryptProv ); + +VOS_STATUS vos_crypto_deinit( v_U32_t hCryptProv ); + + + +/** + * vos_rand_get_bytes + + * FUNCTION: + * Returns cryptographically secure pseudo-random bytes. + * + * + * @param pbBuf - the caller allocated location where the bytes should be copied + * @param numBytes the number of bytes that should be generated and + * copied + * + * @return VOS_STATUS_SUCCSS if the operation succeeds +*/ +VOS_STATUS vos_rand_get_bytes( v_U32_t handle, v_U8_t *pbBuf, v_U32_t numBytes ); + + +/** + * vos_sha1_hmac_str + * + * FUNCTION: + * Generate the HMAC-SHA1 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant SHA1 HMAC (20B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ +VOS_STATUS vos_sha1_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *text, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *key, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_SHA1_SIZE]);/* caller digest to be filled in */ + +/** + * vos_md5_hmac_str + * + * FUNCTION: + * Generate the HMAC-MD5 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant MD5 HMAC (16B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ +VOS_STATUS vos_md5_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *text, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *key, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_MD5_SIZE]);/* caller digest to be filled in */ + + + +VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U8_t *Encrypted, + v_U8_t *pKey); /* pointer to authentication key */ + + +VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U8_t *pDecrypted, + v_U8_t *pKey); /* pointer to authentication key */ + +v_U8_t vos_chan_to_band(v_U32_t chan); +void vos_get_wlan_unsafe_channel(v_U16_t *unsafeChannelList, + v_U16_t buffer_size, v_U16_t *unsafeChannelCount); + +typedef struct { + v_BOOL_t is_rx; + v_U8_t tid; // transmit or received tid + v_U8_t num_retries; // number of attempted retries + v_U8_t rssi; // TX: RSSI of ACK for that packet + // RX: RSSI of packet + v_U32_t rate_idx; // last transmit rate in .5 mbps + v_U16_t seq_num; // receive sequence for that MPDU packet + v_U64_t dxe_timestamp; // DXE timestamp + v_U32_t data_len; + /* Whole frame for management/EAPOl/DHCP frames and 802.11 + LLC + * header + 40 bytes or full frame whichever is smaller for + * remaining Data packets + */ + v_U8_t data[MAX_PKT_STAT_DATA_LEN]; +} tPerPacketStats; + +typedef struct { + v_U32_t lastTxRate; // 802.11 data rate at which the last data frame is transmitted. + v_U32_t txAvgRetry; // Average number of retries per 10 packets. + v_S7_t avgRssi; // Average of the Beacon RSSI. +} tPerTxPacketFrmFw; + +#define ROAM_DELAY_TABLE_SIZE 10 + +enum e_roaming_event +{ + e_HDD_DISABLE_TX_QUEUE = 0, + e_SME_PREAUTH_REASSOC_START, + e_SME_PREAUTH_CALLBACK_HIT, + e_SME_ISSUE_REASSOC_REQ, + e_LIM_SEND_REASSOC_REQ, + e_HDD_SEND_REASSOC_RSP, + e_SME_DISASSOC_ISSUE, + e_SME_DISASSOC_COMPLETE, + e_LIM_ADD_BS_REQ, + e_LIM_ADD_BS_RSP, + e_HDD_ENABLE_TX_QUEUE, + e_HDD_SET_PTK_REQ, + e_HDD_SET_GTK_REQ, + e_HDD_SET_PTK_RSP, + e_HDD_SET_GTK_RSP, + e_HDD_FIRST_XMIT_TIME, + e_DXE_FIRST_XMIT_TIME, + e_SME_VO_ADDTS_REQ, + e_SME_VO_ADDTS_RSP, + e_SME_VI_ADDTS_REQ, + e_SME_VI_ADDTS_RSP, + e_CACHE_ROAM_DELAY_DATA, + e_CACHE_ROAM_PEER_MAC, + e_TL_FIRST_XMIT_TIME, + e_HDD_RX_PKT_CBK_TIME, + e_DXE_RX_PKT_TIME, + + e_ROAM_EVENT_MAX +}; + +typedef enum +{ + eVOS_AUTH_TYPE_NONE, //never used + // MAC layer authentication types + eVOS_AUTH_TYPE_OPEN_SYSTEM, + eVOS_AUTH_TYPE_SHARED_KEY, + eVOS_AUTH_TYPE_AUTOSWITCH, + + // Upper layer authentication types + eVOS_AUTH_TYPE_WPA, + eVOS_AUTH_TYPE_WPA_PSK, + eVOS_AUTH_TYPE_WPA_NONE, + + eVOS_AUTH_TYPE_RSN, + eVOS_AUTH_TYPE_RSN_PSK, +#if defined WLAN_FEATURE_VOWIFI_11R + eVOS_AUTH_TYPE_FT_RSN, + eVOS_AUTH_TYPE_FT_RSN_PSK, +#endif +#ifdef FEATURE_WLAN_WAPI + eVOS_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + eVOS_AUTH_TYPE_WAPI_WAI_PSK, +#endif /* FEATURE_WLAN_WAPI */ +#ifdef FEATURE_WLAN_ESE + eVOS_AUTH_TYPE_CCKM_WPA, + eVOS_AUTH_TYPE_CCKM_RSN, +#endif /* FEATURE_WLAN_ESE */ +#ifdef WLAN_FEATURE_11W + eVOS_AUTH_TYPE_RSN_PSK_SHA256, +#endif + eVOS_NUM_OF_SUPPORT_AUTH_TYPE, + eVOS_AUTH_TYPE_FAILED = 0xff, + eVOS_AUTH_TYPE_UNKNOWN = eVOS_AUTH_TYPE_FAILED, + +}eVosAuthType; + + +typedef struct sRoamDelayMetaInfo +{ + v_BOOL_t log_tl; + v_U8_t hdd_monitor_tx;//monitor the tx @ hdd basically (Eapol , First Tx Data Frame ) + v_U8_t hdd_monitor_rx;//monitor the rx @ hdd basically (Eapol ) + v_U8_t dxe_monitor_tx;//monitor the tx @ dxe basically (Eapol , First Tx Data Frame ) + v_U8_t dxe_monitor_rx;//monitor the rx @ dxe basically (Eapol ) + v_BOOL_t log_dxe_tx_isr; + v_U8_t peer_mac_addr[6]; + v_ULONG_t hdd_first_xmit_time; + v_ULONG_t preauth_reassoc_start_time; + v_ULONG_t preauth_cb_time; + v_ULONG_t disable_tx_queues_time; + v_ULONG_t lim_add_bss_req_time; + v_ULONG_t issue_reassoc_req_time; + v_ULONG_t hdd_sendassoc_rsp_time; + v_ULONG_t enable_tx_queues_reassoc_time; + v_ULONG_t set_ptk_roam_key_time; + v_ULONG_t set_gtk_roam_key_time; + v_ULONG_t complete_ptk_roam_key_time; + v_ULONG_t complete_gtk_roam_key_time; + v_ULONG_t dxe_first_tx_time; + v_ULONG_t send_reassoc_req_time; + v_ULONG_t disassoc_comp_time; + v_ULONG_t disassoc_issue_time; + v_ULONG_t lim_add_bss_rsp_time; + v_ULONG_t tl_fetch_pkt_time; + v_ULONG_t dxe_tx_isr_time; + v_ULONG_t hdd_eapol_m1; + v_ULONG_t hdd_eapol_m2; + v_ULONG_t hdd_eapol_m3; + v_ULONG_t hdd_eapol_m4; + v_ULONG_t dxe_eapol_m1; + v_ULONG_t dxe_eapol_m2; + v_ULONG_t dxe_eapol_m3; + v_ULONG_t dxe_eapol_m4; + v_ULONG_t hdd_first_pkt_len; + v_U8_t hdd_first_pkt_data[50]; + v_ULONG_t dxe_first_pkt_len; + v_U8_t dxe_first_pkt_data[75]; + v_ULONG_t hdd_addts_vo_req_time; + v_ULONG_t hdd_addts_vo_rsp_time; + v_ULONG_t hdd_addts_vi_req_time; + v_ULONG_t hdd_addts_vi_rsp_time; + eVosAuthType hdd_auth_type; + +} tRoamDelayMetaInfo, *tpRoamDelayMetaInfo; + +extern tRoamDelayMetaInfo gRoamDelayMetaInfo; +extern tRoamDelayMetaInfo *gpRoamDelayTable; +extern v_BOOL_t gRoamDelayCurrentIndex; + +v_BOOL_t vos_roam_delay_stats_init(void); +v_BOOL_t vos_roam_delay_stats_deinit(void); +void vos_reset_roam_timer_log(void); +void vos_dump_roam_time_log_service(void); +void vos_record_roam_event(enum e_roaming_event, void *pBuff, v_ULONG_t buff_len); +v_U32_t vos_copy_80211_data(void *pBuff, v_U8_t *dst, v_U8_t frametype); +extern v_U8_t vos_get_ring_log_level(v_U32_t ring_id); +bool vos_isPktStatsEnabled(void); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +void vos_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx, + uint8_t type, uint8_t sub_type, uint8_t *peer_mac); +#else +static inline +void vos_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx, + uint8_t type, uint8_t sub_type, uint8_t *peer_mac) + +{ + return; +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +#endif // #if !defined __VOSS_UTILS_H diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_hdd_misc.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_hdd_misc.h new file mode 100644 index 000000000000..7c2d62ad86c3 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_hdd_misc.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_HDD_MISC_H +#define WLAN_HDD_MISC_H + +#ifdef MSM_PLATFORM +#ifdef QC_WLAN_CHIPSET_PRIMA +#define WLAN_INI_FILE "wlan/prima/WCNSS_qcom_cfg.ini" +#define WLAN_CFG_FILE "wlan/prima/WCNSS_cfg.dat" +#define WLAN_FW_FILE "" +#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" +#define WLAN_DICT_FILE "wlan/prima/WCNSS_wlan_dictionary.dat" +#define WLAN_COUNTRY_INFO_FILE "wlan/prima/WCNSS_wlan_country_info.dat" +#define WLAN_HO_CFG_FILE "wlan/prima/WCNSS_wlan_ho_config" +#else +#define WLAN_INI_FILE "wlan/volans/WCN1314_qcom_cfg.ini" +#define WLAN_CFG_FILE "wlan/volans/WCN1314_cfg.dat" +#define WLAN_FW_FILE "wlan/volans/WCN1314_qcom_fw.bin" +#define WLAN_NV_FILE "wlan/volans/WCN1314_qcom_wlan_nv.bin" +#define WLAN_DICT_FILE "" +#define WLAN_COUNTRY_INFO_FILE "wlan/volans/WCN1314_wlan_country_info.dat" +#define WLAN_HO_CFG_FILE "wlan/volans/WCN1314_wlan_ho_config" +#endif // ANI_CHIPSET +#else +#define WLAN_INI_FILE "wlan/qcom_cfg.ini" +#define WLAN_CFG_FILE "wlan/cfg.dat" +#define WLAN_FW_FILE "wlan/qcom_fw.bin" +#define WLAN_NV_FILE "wlan/qcom_wlan_nv.bin" +#define WLAN_DICT_FILE "" +#define WLAN_COUNTRY_INFO_FILE "wlan/wlan_country_info.dat" +#define WLAN_HO_CFG_FILE "wlan/wlan_ho_config" +#endif // MSM_PLATFORM + + +VOS_STATUS hdd_request_firmware(char *pfileName,v_VOID_t *pCtx,v_VOID_t **ppfw_data, v_SIZE_t *pSize); + +VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx); + +VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize); + +VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName, v_VOID_t *pBuffer, v_SIZE_t *pBufSize); +#if 0 + +VOS_STATUS hdd_release_firmware(char *pFileName,v_VOID_t *pCtx); + +VOS_STATUS hdd_get_cfg_file_size(v_VOID_t *pCtx, char *pFileName, v_SIZE_t *pBufSize); + +VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName, v_VOID_t *pBuffer, v_SIZE_t *pBufSize); + +#endif + +tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void ); + +#endif /* WLAN_HDD_MISC_H */ + diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser.h new file mode 100644 index 000000000000..816f658553fb --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined __WLAN_NV_PARSER_H +#define __WLAN_NV_PARSER_H + +#include + +VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize, sHalNv *); + +#endif diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser_internal.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser_internal.h new file mode 100644 index 000000000000..a92b952b69e5 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_parser_internal.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined _WLAN_NV_PARSER_INTERNAL_H +#define _WLAN_NV_PARSER_INTERNAL_H + +#include "wlan_nv_types.h" + +/* + * local prototypes + */ +static _NV_TEMPLATE_PROCESS_RC processNvTemplate(_NV_STREAM_BUF *pStream, + int len); +static _NV_TEMPLATE_PROCESS_RC processNvTemplateTable(_NV_STREAM_BUF *pStream, + int len); +static int constructATemplateTable(_NV_STREAM_BUF *pStream, int len, + char *tableStrName); +static _NV_TEMPLATE_PROCESS_RC compareWithBuiltinTable(int idxFromBin, + char *tableNameFromBin); +static _NV_TEMPLATE_PROCESS_RC compare2Tables(int idxFromBin, int idxBuiltin); +static _NV_TEMPLATE_PROCESS_RC compare2FieldsAndCopyFromBin( + _NV_TEMPLATE_TABLE *pTableBuiltin, _NV_TEMPLATE_TABLE *pTableFromBin, + int idxBuiltin, int idxFromBin); +static _NV_TEMPLATE_PROCESS_RC compare2FieldIDType( + _NV_TEMPLATE_TABLE *pTableBuiltIn, _NV_TEMPLATE_TABLE *pTableFromBin, + int idxBuiltin, int idxFromBin); +static _NV_TEMPLATE_PROCESS_RC compare2FieldStorageTypeAndSizes( + _NV_TEMPLATE_TABLE *pTableBuiltIn, _NV_TEMPLATE_TABLE *pTableFromBin, + int idxBuiltin, int idxFromBin); +static _NV_TEMPLATE_PROCESS_RC compare2StorageSize(int idxBuiltIn, + int idxFromBin, int sizeBuiltIn, int sizeFromBin, + tANI_U8 sizeBuiltInLowByte, tANI_U8 sizeFromBinLowByte); +static _NV_TEMPLATE_PROCESS_RC processNvTemplateEnum(_NV_STREAM_BUF *pStream, + int len); +static void compareEnumWithBuiltin(char *enumStr, int enumIdxFromBin); +static _NV_TEMPLATE_PROCESS_RC compare2EnumEntriesAndCopy(int idxFromBin, + int idxBuiltin); +static int constructATemplateEnum(_NV_STREAM_BUF *pStream, int len, + char *enumStr); +static void processNvData(_NV_STREAM_BUF *pStream, int len); +static int numElemSingular(_NV_TEMPLATE_TABLE *pTableEntry,int); +static int numElemArray1(_NV_TEMPLATE_TABLE *pTableEntry,int); +static int numElemArray2(_NV_TEMPLATE_TABLE *pTableEntry,int); +static int numElemArray3(_NV_TEMPLATE_TABLE *pTableEntry,int); +static void parseSubDataTable4Size(int tableIdx, int numElem); +static void getBasicDataSize(_NV_TEMPLATE_TABLE *pTableEntry); +static int getNumElemOutOfStorageSize(int fieldStorageSize, + tANI_U8 fieldStorageSizeLowByte,int); + +static int getFieldCount(int tableIdx, int fieldIdi, int numElem, + int nvBin); +static void parseDataTable_new(_NV_STREAM_BUF *pStream, int* pos, + int tableIdx, int addOffset, int tableBaseOffset); +static int getBuiltInFieldCount (int tblIdBin, char *tableNameFromBin, + int *tblIdBuiltIn, int *fieldIdBuitIn, int *numElem); +static void parseSubDataTableAndCopy(int tableIdx, int numElem, int numElem2, + int numElem3, int fieldId, _NV_STREAM_BUF *pStream, int* pos, + int addOffset, int tableBaseOffset, int localAddOffset); + +/* + * typedef's + */ + +typedef int (*pF_NumElemBasedOnStorageType)(_NV_TEMPLATE_TABLE *pTableEntry, + int nvBin); + +#endif + + diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_stream.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_stream.h new file mode 100644 index 000000000000..9ec790457e68 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_stream.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined _WLAN_NV_STREAM_H +#define _WLAN_NV_STREAM_H + +#include "wlan_nv_types.h" + +typedef tANI_U8 _NV_STREAM_BUF; + +typedef struct { + _NV_STREAM_BUF *dataBuf; + tANI_U32 currentIndex; + tANI_U32 totalLength; +}_STREAM_BUF; + +extern _STREAM_BUF streamBuf; + +typedef enum { + RC_FAIL, + RC_SUCCESS, +} _STREAM_RC; + +typedef enum { + STREAM_READ, + STREAM_WRITE, +} _STREAM_OPERATION; + +_STREAM_RC nextStream (tANI_U32 *length, tANI_U8 *dataBuf); +_STREAM_RC initReadStream ( tANI_U8 *readBuf, tANI_U32 length); + +#endif diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_api.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_api.h new file mode 100644 index 000000000000..1bbe877e7fc0 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_api.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined _WLAN_NV_TEMPLATE_API_H +#define _WLAN_NV_TEMPLATE_API_H + +#include "wlan_nv_types.h" + +/* +* API Prototypes +* These are meant to be exposed to outside applications +*/ +//extern void writeNvData(void); +//extern VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize, sHalNv *); + +/* +* Parsing control bitmap +*/ +#define _ABORT_WHEN_MISMATCH_MASK 0x00000001 /*set: abort when mismatch, clear: continue taking matched entries*/ +#define _IGNORE_THE_APPENDED_MASK 0x00000002 /*set: ignore, clear: take*/ + +#define _FLAG_AND_ABORT(b) (((b) & _ABORT_WHEN_MISMATCH_MASK) ? 1 : 0) + +#endif /*#if !defined(_WLAN_NV_TEMPLATE_API_H) */ diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_builtin.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_builtin.h new file mode 100644 index 000000000000..8b8c7a13fa95 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_builtin.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined _WLAN_NV_TEMPLATE_BUILTIN_H +#define _WLAN_NV_TEMPLATE_BUILTIN_H + + +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + when who what, where, why + -------- --- ----------------------------------------------- + 04/10/13 kumarpra nv built in creation +===========================================================================*/ + + +/* + ----------------------------------------- + This file is generated by nvTmplRun Parser + ----------------------------------------- + To be auto-generated, or + This is the source file and the header file can be generated from this + template file. + + Template constructs + 1. TABLE_: struct + 2. INDEX_ENUM: enums, e.g. {RATE_OFDM_6M,RATE_OFDM_54M} + 3. INDEX_INT: int, e.g.{min, max, increment} + 3. Basic data types: tANI_U8, tANI_S8, tANI_U32, tANI_S32 + 4. Storage types: + 4.1 SINGULAR: one element of basic data type + 4.2 ARRAY_1: one dimensional array, x-axis + 4.3 ARRAY_2: two dimensional array, (x, y) + 4.4 ARRAY_3: three dimensional array, (x, y, z) + 4.5 ARRAY_4: four dimensional array, (x, y, z, t) + + Implementation notes + 1. Flow of changing NV data format: (TBD) Either change the template and + generate the header file, or modify header file and auto-generate + the template. + 2. Flow of writing NV data: encode the template in the data stream, so the + NV data is "self-sufficient". No separate template, no compability + issue, no need of version control. + 3. Flow of reading NV data: parse the binary NV data stream based on the + template info in the data stream. + 4. The above NV logic is decoupled from the actual data content, a generic, + content ergonostic parser (reading) and encoder (writing). + The NV logic is common code shared by tools, s/w + (both host and firmware), and off-line utilities. + 5. NV data parsing and "acceptanace" into an s/w moduel data structure can + be "configured" in several ways: + 5.1 only total matching of all fields, otherwise, reject the whole data + stream (a table). + 5.2 partial matching of fields allowed and the rest fields assume + reasonal default values, + The choice can be determined later, but the capability is provided. + 6. We could also design in this selection on an individua table base. + To design such capability, reserve some header bits in the data stream. + 7. The NV data streams can be modified, replaced, or intact with a new data + stream of the same table ID added to NV data. + The choice can be determined later, but the NV scheme provides such + capability. + 8. The template construct definitions can be common to all tables + (tbd: in a common section) or table specific, or updated in a + subsequent format section. + The use cases are: + - An index enum (e.g. RF channels) is common to all tables when the NV + data is created. Later new enums are added (e.g. + additional channels), one can choose to add the new index enum for new + tables appended to the NV data, or replace the + old table with new template info and data. + The template precedence is table specific then common, and later + "common" overwrites "earlier" commmon. + - A new field is added to the table, the user decides to replace the + old table data, he can simply encode the template info in the + data stream. + - In the same scenario (a new field is added), the user decides to + append a new table, he can encode the template + in the new data table and append it to NV data, or write a new common + template section and append the data. + + Key "ingredients", (re-iterate the most important features and capabilities) + 1. How to parse the data is embedded in the NV data itself. It removes the + dependency on header file matching, + version checking, compatibility among tools, host and firmware. + 2. Table field ID enables "partial" data acceptance in an s/w module data + structure. Whether full matching or reject the whole table, or "partial" + acceptance, the capabiilty is in place and further ensures the robust + NV data extensibility and compatibility. + 3. The table granularity, data stream based NV data has variable length + and flexibility of modifying an existing table data, replacing the + whole data, or leaving the existing data table intact and appending + a new table. + Misc notes: + 1. For endianness, support only 4 bytes integer or 4 1-byte + 2. String identifier needs to be shortened to save storage + 3. string_field_name, field type, field storage class, storage size +*/ + + +#include "wlan_nv_types.h" + +int allocNvBinTable(int tblIdx, int numEntries); +int allocNvBinEnum(int enumIdx, int numEntries); + +typedef enum _nvFieldSizeEnums { + INDEX_ENUM_ALL = 0, + INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS, + INDEX_ENUM_NUM_REG_DOMAINS, + INDEX_ENUM_NUM_RF_SUBBANDS, + INDEX_ENUM_NUM_RF_CHANNELS, + INDEX_ENUM_NUM_2_4GHZ_CHANNELS, + INDEX_ENUM_NUM_802_11_MODES, + INDEX_ENUM_NUM_HAL_PHY_RATES, + INDEX_ENUM_BUILTIN_LAST, + INDEX_ENUM_BUILTIN_MAX, +} _NV_FIELD_SIZE_ENUMS; + +#define INDEX_ENUM_MAX MAX(INDEX_ENUM_PREDEFINED_MAX, INDEX_ENUM_BUILTIN_MAX) + +int getEnumNoOfFields(int enumIdx); +extern _NV_TEMPLATE_ENUM NvEnumsBuiltIn[/*INDEX_ENUM_MAX*/][ENUM_ENTRIES_MAX]; + +typedef enum _nvTableIDs { + TABLE_sHalNv, + TABLE_sNvFields, + TABLE_sRegulatoryChannel, + TABLE_sRssiChannelOffsets, + TABLE_sCalData, + TABLE_sTxBbFilterMode, + TABLE_sOfdmCmdPwrOffset, + TABLE_sDefaultCountry, + TABLE_sFwConfig, + TABLE_tTpcPowerTable, + TABLE_tRateGroupPwr, + TABLE_tRateGroupPwrVR, + TABLE_sRegulatoryDomains, + TABLE_sHwCalValues, + TABLE_sNvTables, + TABLE_BUILTIN_LAST, + TABLE_BUILTIN_MAX, +} _NV_TABLE_ID; + +#define TABLES_MAX MAX(TABLE_PREDEFINED_MAX, TABLE_BUILTIN_MAX) + +int getTableNoOfFields(int tblIdx); +extern _NV_TEMPLATE_TABLE NvTablesBuiltIn[/*TABLES_MAX*/][TABLE_ENTRIES_MAX]; + +#endif //#if !defined(_WLAN_NV_TEMPLATEBUILTIN_H) diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_internal.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_internal.h new file mode 100644 index 000000000000..f6ace16b99db --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_template_internal.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined _WLAN_NV_TEMPLATE_INTERNAL_H +#define _WLAN_NV_TEMPLATE_INTERNAL_H + +/* + Template constructs + 1. TABLE_: struct + 2. INDEX_ENUM: enums, e.g. {RATE_OFDM_6M,RATE_OFDM_54M} + 3. INDEX_INT: int, e.g.{min, max, increment} + 3. Basic data types: tANI_U8, tANI_S8, tANI_U32, tANI_S32 + 4. Storage types: + 4.1 SINGULAR: one element of basic data type + 4.2 ARRAY_1: one dimensional array, x-axis + 4.3 ARRAY_2: two dimensional array, (x, y) + 4.4 ARRAY_3: three dimensional array, (x, y, z) + + Implementation notes + 1. Flow of changing NV data format: (TBD) Either change the template and + generate the header file, or + modify header file and auto-generate the template. + 2. Flow of writing NV data: encode the template in the data stream, so the + NV data is "self-sufficient". + No separate template, no compability issue, no need of version control. + 3. Flow of reading NV data: parse the binary NV data stream based on the + template info in the data stream. + 4. The above NV logic is decoupled from the actual data content, a + generic, content ergonostic parser (reading) and encoder (writing). + The NV logic is common code shared by tools, s/w + (both host and firmware), and off-line utilities. + 5. NV data parsing and "acceptanace" into an s/w moduel data structure can + be "configured" in several ways: + 5.1 only total matching of all fields, otherwise, reject the whole data + stream (a table). + 5.2 partial matching of fields allowed and the rest fields assume + reasonal default values, + The choice can be determined later, but the capability is provided. + 6. We could also design in this selection on an individua table base. + To design such capability, reserve some header bits in the data stream. + 7. The NV data streams can be modified, replaced, or intact with a new + data stream of the same table ID added to NV data. + The choice can be determined later, but the NV scheme provides such + capability. + 8. The template construct definitions can be common to all tables + (tbd: in a common section) or table specific, or updated + in a subsequent format section. + The use cases are: + - An index enum (e.g. RF channels) is common to all tables when the NV + data is created. Later new enums are added (e.g. + additional channels), one can choose to add the new index enum for new + tables appended to the NV data, or replace the + old table with new template info and data. + The template precedence is table specific then common, and later + "common" overwrites "earlier" commmon. + - A new field is added to the table, the user decides to replace the old + table data, he can simply encode the template + info in the data stream. + - In the same scenario (a new field is added), the user decides to + append a new table, he can encode the template + in the new data table and append it to NV data, or write a new common + template section and append the data. + + Key "ingredients", (re-iterate the most important features and capabilities) + 1. How to parse the data is embedded in the NV data itself. It removes the + dependency on header file matching, + version checking, compatibility among tools, host and firmware. + 2. Table field ID enables "partial" data acceptance in an s/w module data + structure. Whether full matching or reject the whole table, or "partial" + acceptance, the capabiilty is in place and further ensures the robust + NV data extensibility and compatibility. + 3. The table granularity, data stream based NV data has variable length + and flexibility of modifying an existing table data, replacing + the whole data,or leaving the existing data table intact and + appending a new table. + Misc notes: + 1. For endianness, support only 4 bytes integer or 4 1-byte + 2. String identifier needs to be shortened to save storage + 3. string_field_name, field type, field storage class, storage size +*/ + +#include "wlan_nv_types.h" + +/* + * Stream header bitmap + * streamType + * bitmap[7] + * / \ + * 1: template 0: data + * bitmap[6] + * / \ + * 0: enum 1: table + * + */ +/* Stream header type[7], 0: data, 1: template */ +#define STREAM_HEADER_TYPE_MASK 0x80 +#define STREAM_HEADER_TYPE_LSB 7 +#define IsStreamTemplate(b) (((b) & (STREAM_HEADER_TYPE_MASK)) ? 1 : 0) + +/* Stream header template type [6], 0: enum; 1: table */ +#define STREAM_HEADER_TEMPLATE_TYPE_MASK 0x40 +#define STREAM_HEADER_TEMPLATE_TYPE_LSB 6 +#define IsTemplateStreamTable(b) (((b) & (STREAM_HEADER_TEMPLATE_TYPE_MASK)) ? 1 : 0) + +/* + * Field identifier bitmap + * + * field identifier + * bitmap[7] + * / \ + * 0: table/enum 1: basic data type + * bitmap[6:0] bitmap[6:0] + * | | + * tableIdx/ data types (U8, U32, etc.) + * enumIdx + */ +/* Field Identifier type [7] + * 0: table + * 1: basic data types + * Note that + * - bit[7] table value=0 makes the table ID following data header stream or + * template header stream identical to field ID + * - tableIdx 0 is the "table of all tables", a.k.a. table content of all + * table indexes + * - enumIdx 0 is the "enum of all enums", a.k.a. table content of all enum + * indexes + */ + +#define FIELD_ID_TYPE_MASK 0x80 +#define FIELD_ID_TYPE_LSB 7 +#define IsFieldTypeBasicData(b) (((b) & (FIELD_ID_TYPE_MASK)) ? 1 : 0) + +/* Field Identifier table index [6:0] */ +#define FIELD_ID_TABLE_OR_ENUM_IDX_MASK 0x7f +#define FIELD_ID_TABLE_OR_ENUM_IDX_LSB 0 +#define _TABLE_IDX(b) (((b) & ~FIELD_ID_TYPE_MASK) | ((b) & FIELD_ID_TABLE_OR_ENUM_IDX_MASK)) +#define IsIdxTableOfAllTables(b) (((b) & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ? 0 : 1) +#define IsIdxEnumOfAllEnums(b) (((b) & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) ? 0 : 1) + +/* Field Identifier basic data types [6:0] + * 0: U8 + * 1: U32 + * 2: S8 + * 3: S32 + * 4: U16 + * 5: S16 + */ + +#define FIELD_ID_BASIC_DATA_TYPES_MASK 0x7F +#define FIELD_ID_BASIC_DATA_TYPES_LSB 0 + +typedef enum { + _FIELD_ID_DATA_TYPE_U8 = 0, + _FIELD_ID_DATA_TYPE_U32, + _FIELD_ID_DATA_TYPE_S8, + _FIELD_ID_DATA_TYPE_S32, + _FIELD_ID_DATA_TYPE_U16, + _FIELD_ID_DATA_TYPE_S16, + _FIELD_ID_DATA_TYPE_LAST, +} _FIELD_ID_BASIC_DATA_TYPE; + +#define TheBasicDataType(b) (((b) & (FIELD_ID_BASIC_DATA_TYPES_MASK)) >> FIELD_ID_BASIC_DATA_TYPES_LSB) +#define _ID_U8 ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_U8)) +#define _ID_U32 ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_U32)) +#define _ID_S8 ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_S8)) +#define _ID_S32 ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_S32)) +#define _ID_U16 ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_U16)) +#define _ID_S16 ((FIELD_ID_TYPE_MASK) | (_FIELD_ID_DATA_TYPE_S16)) + +/* + * field storage class + */ +typedef enum { + SINGULAR = 0, + ARRAY_1, + ARRAY_2, + ARRAY_3, + STORAGE_TYPE_LAST, +} _FIELD_ID_STORAGE_TYPE; + +#define _STORAGE_TYPE(b) ((b) & 0x3) +#define _STORAGE_SIZE1(byteLow, byteHigh) (((((byteHigh) >> 2) & 0x3) << 7) | (((byteLow) >> FIELD_SIZE_VALUE_LSB) & FIELD_SIZE_VALUE_MASK)) +#define _STORAGE_SIZE2(byteLow, byteHigh) (((((byteHigh) >> 4) & 0x3) << 7) | (((byteLow) >> FIELD_SIZE_VALUE_LSB) & FIELD_SIZE_VALUE_MASK)) +#define _STORAGE_SIZE3(byteLow, byteHigh) (((((byteHigh) >> 6) & 0x3) << 7) | (((byteLow) >> FIELD_SIZE_VALUE_LSB) & FIELD_SIZE_VALUE_MASK)) + +#define _ADD_SIZE1(b) ((((b) >> 7) & 0x3) << 2) +#define _ADD_SIZE2(b) ((((b) >> 7) & 0x3) << 4) +#define _ADD_SIZE3(b) ((((b) >> 7) & 0x3) << 6) + +/* + * Field storage size type [7] + * / \ + * 1: int 0: enum + * bitmap[6:0] bitmap[6:0] + * | | + * max int index enum index into enum tables + * + * Note that enum=0 makes the template enum ID following template stream byte + * identical to enum field storage size type + * + * Field storage size value [6:0] + */ +#define FIELD_SIZE_TYPE_MASK 0x80 +#define FIELD_SIZE_TYPE_LSB 7 +#define FIELD_SIZE_TYPE_BIT(t) (((t)<< (FIELD_SIZE_TYPE_LSB)) & (FIELD_SIZE_TYPE_MASK)) +#define IsFieldSizeInt(b) (((b) & (FIELD_SIZE_TYPE_MASK)) ? 1 : 0) + +typedef enum { + FIELD_SIZE_IDX_ENUM = 0, + FIELD_SIZE_IDX_INT = 1, +} FIELD_SIZE_TYPE; + +#define FIELD_SIZE_VALUE_MASK 0x7f +#define FIELD_SIZE_VALUE_LSB 0 +#define FIELD_SIZE_VALUE_BITS(val) (((val) << (FIELD_SIZE_VALUE_LSB)) & (FIELD_SIZE_VALUE_MASK)) + +/* + * NV table storage struct in an s/w module + */ +#define _TABLE_NAME_LEN 2 +#define _TABLE_FIELD_FULL_NAME_LEN 47 + +typedef struct _nvTemplateTableStructInternal { + tANI_U8 fieldName[_TABLE_NAME_LEN + 1]; + tANI_U8 fieldId; + tANI_U8 fieldStorageType; + tANI_U8 fieldStorageSize1; + tANI_U8 fieldStorageSize2; + tANI_U8 fieldStorageSize3; + tANI_U32 offset; //void *offset; + tANI_U8 fieldFullName[_TABLE_FIELD_FULL_NAME_LEN +1]; +} _NV_TEMPLATE_TABLE; + +#define _OFFSET_NOT_SET 0xFFFFFFFF +#define TABLE_PREDEFINED_MAX 50 +#define TABLE_ENTRIES_MAX 50 +#define _LIST_OF_TABLES_IDX 0 +#define _TABLE_FIELDS_POS 2 +#define _ENUM_START_POS 2 +#define _TABLE_FIELD_MIN_LEN 4 +#define _ENUM_MIN_LEN 3 + +#define _ENUM_NAME_LEN _TABLE_NAME_LEN +#define _ENUM_FULL_NAME_LEN 47 +typedef struct _nvTemplateEnumStruct { + tANI_U8 enumName[3]; // 2 char string + tANI_U8 enumValue; + tANI_U8 enumValuePeer; + tANI_U8 enumFullName[_ENUM_FULL_NAME_LEN +1]; +} _NV_TEMPLATE_ENUM; +#define INDEX_ENUM_PREDEFINED_MAX 20 +#define ENUM_ENTRIES_MAX 200 + +typedef enum { + _MIS_MATCH = 0, + _MATCH, +} _NV_TEMPLATE_PROCESS_RC; + +#define _NV_BIN_STREAM_HEADER_BYTE 0 +#define _NV_BIN_STREAM_TABLE_ID_BYTE 1 +#define _NV_BIN_STREAM_ENUM_ID_BYTE 1 +#define _NV_BIN_DATA_STREAM_TABLEID_BYTE 1 +#define _NV_BIN_ENUM_TEMPLATE_ENTRY_SIZE 3 +#define _NV_LIST_OF_TABLE_ID 0 + +/* + * Stream write + */ +#define _STREAM_HEADER_POS 0 +#define _ENUM_STREAM_HEADER_POS _STREAM_HEADER_POS +#define _TABLE_STREAM_HEADER_POS _STREAM_HEADER_POS +#define _TEMPLATE_INDEX_HEADER_POS 1 +#define _ENUM_INDEX_HEADER_POS _TEMPLATE_INDEX_HEADER_POS +#define _TABLE_INDEX_HEADER_POS _TEMPLATE_INDEX_HEADER_POS + +/* + * Additional typedef + */ +typedef struct _enumMetaData { + _NV_TEMPLATE_PROCESS_RC match; +} _ENUM_META_DATA; + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define _NV_STREAM_LEN_MAX 35000 + +/* + * Error code should be expanded, this is the beginning set + */ +typedef enum { + _OK = 0, + _RESET_STREAM_FAILED, + _WRITE_STREAM_FAILED, + _STREAM_NOT_FIT_BUF, + _SW_BIN_MISMATCH, + _INSUFFICIENT_FOR_FIELD_PARSER_ERROR, + _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES, + _ENUM_NOT_FOUND_IN_BUILT_IN, +} _ErrorCode; + +/* + * Use the stream test stub + */ +//#define _USE_STREAM_STUB +#define RESET_STREAM(b) resetStream(b) +#define NEXT_STREAM(b,c) nextStream(b,c) + +#endif /*#if !defined(_WLAN_NV_TEMPLATE_INTERNAL_H)*/ diff --git a/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_types.h b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_types.h new file mode 100644 index 000000000000..461eb57f730b --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/inc/wlan_nv_types.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined __WLAN_NV_TYPES_H +#define __WLAN_NV_TYPES_H + +#include "halLegacyPalTypes.h" +#include "halCompiler.h" +#include "vos_status.h" +#include + +typedef char tANI_BOOL; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define nul '\0' + +#endif diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_api.c b/drivers/staging/prima/CORE/VOSS/src/vos_api.c new file mode 100644 index 000000000000..8e048bad1938 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_api.c @@ -0,0 +1,3893 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_api.c + + \brief Stub file for all virtual Operating System Services (vOSS) APIs + + ========================================================================*/ + /*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 03/29/09 kanand Created module. +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "vos_sched.h" +#include +#include "sirTypes.h" +#include "sirApi.h" +#include "sirMacProtDef.h" +#include "sme_Api.h" +#include "macInitApi.h" +#include "wlan_qct_sys.h" +#include "wlan_qct_tl.h" +#include "wlan_hdd_misc.h" +#include "i_vos_packet.h" +#include "vos_nvitem.h" +#include "wlan_qct_wda.h" +#include "wlan_hdd_main.h" +#include +#include "wlan_hdd_cfg80211.h" +#include "vos_diag_core_log.h" + +#include + +#include "sapApi.h" +#include "vos_trace.h" +#include "vos_utils.h" +#include + +#ifdef WLAN_BTAMP_FEATURE +#include "bapApi.h" +#include "bapInternal.h" +#include "bap_hdd_main.h" +#endif //WLAN_BTAMP_FEATURE +#include "wlan_qct_wdi_cts.h" + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * ------------------------------------------------------------------------*/ +/* Amount of time to wait for WDA to perform an asynchronous activity. + This value should be larger than the timeout used by WDI to wait for + a response from WCNSS since in the event that WCNSS is not responding, + WDI should handle that timeout */ +#define VOS_WDA_TIMEOUT 15000 + +/* Approximate amount of time to wait for WDA to stop WDI */ +#define VOS_WDA_STOP_TIMEOUT WDA_STOP_TIMEOUT + +/* Approximate amount of time to wait for WDA to issue a DUMP req */ +#define VOS_WDA_RESP_TIMEOUT WDA_STOP_TIMEOUT + +/* Trace index for WDI Read/Write */ +#define VOS_TRACE_INDEX_MAX 256 + +/* ARP Target IP offset */ +#define VOS_ARP_TARGET_IP_OFFSET 58 + +/*--------------------------------------------------------------------------- + * Data definitions + * ------------------------------------------------------------------------*/ +static VosContextType gVosContext; +static pVosContextType gpVosContext; +static v_U8_t vos_multicast_logging; + +struct vos_wdi_trace +{ + vos_wdi_trace_event_type event; + uint16 message; + uint64 time; +}; + +static struct vos_wdi_trace gvos_wdi_msg_trace[VOS_TRACE_INDEX_MAX]; +uint16 gvos_wdi_msg_trace_index = 0; + +/*--------------------------------------------------------------------------- + * Forward declaration + * ------------------------------------------------------------------------*/ +v_VOID_t vos_sys_probe_thread_cback ( v_VOID_t *pUserData ); + +v_VOID_t vos_core_return_msg(v_PVOID_t pVContext, pVosMsgWrapper pMsgWrapper); + +v_VOID_t vos_fetch_tl_cfg_parms ( WLANTL_ConfigInfoType *pTLConfig, + hdd_config_t * pConfig ); + + +/*--------------------------------------------------------------------------- + + \brief vos_preOpen() - PreOpen the vOSS Module + + The \a vos_preOpen() function allocates the Vos Context, but do not + initialize all the members. This overal initialization will happen + at vos_Open(). + The reason why we need vos_preOpen() is to get a minimum context + where to store BAL and SAL relative data, which happens before + vos_Open() is called. + + \param pVosContext: A pointer to where to store the VOS Context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_Open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preOpen ( v_CONTEXT_t *pVosContext ) +{ + if ( pVosContext == NULL) + return VOS_STATUS_E_FAILURE; + + /* Allocate the VOS Context */ + *pVosContext = NULL; + gpVosContext = &gVosContext; + + if (NULL == gpVosContext) + { + /* Critical Error ...Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to allocate VOS Context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_RESOURCES; + } + + vos_mem_zero(gpVosContext, sizeof(VosContextType)); + + *pVosContext = gpVosContext; + + /* Initialize the spinlock */ + vos_trace_spin_lock_init(); + /* it is the right time to initialize MTRACE structures */ + #if defined(TRACE_RECORD) + vosTraceInit(); + #endif + vos_register_debugcb_init(); + + return VOS_STATUS_SUCCESS; + +} /* vos_preOpen()*/ + + +/*--------------------------------------------------------------------------- + + \brief vos_preClose() - PreClose the vOSS Module + + The \a vos_preClose() function frees the Vos Context. + + \param pVosContext: A pointer to where the VOS Context was stored + + + \return VOS_STATUS_SUCCESS - Always successful + + + \sa vos_preClose() + \sa vos_close() +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preClose( v_CONTEXT_t *pVosContext ) +{ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: De-allocating the VOS Context", __func__); + + if (( pVosContext == NULL) || (*pVosContext == NULL)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vOS Context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (gpVosContext != *pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Context mismatch", __func__); + return VOS_STATUS_E_FAILURE; + } + + *pVosContext = gpVosContext = NULL; + + return VOS_STATUS_SUCCESS; + +} /* vos_preClose()*/ + +/*--------------------------------------------------------------------------- + + \brief vos_open() - Open the vOSS Module + + The \a vos_open() function opens the vOSS Scheduler + Upon successful initialization: + + - All VOS submodules should have been initialized + + - The VOS scheduler should have opened + + - All the WLAN SW components should have been opened. This includes + SYS, MAC, SME, WDA and TL. + + + \param devHandle: pointer to the OS specific device handle + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_preOpen() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, void *devHandle ) + +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int iter = 0; + tSirRetStatus sirStatus = eSIR_SUCCESS; + tMacOpenParameters macOpenParms; + WLANTL_ConfigInfoType TLConfig; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening VOSS", __func__); + + if (NULL == gpVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Trying to open VOSS without a PreOpen", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Initialize the timer module */ + vos_timer_module_init(); + + /* Initialize the probe event */ + if (vos_event_init(&gpVosContext->ProbeEvent) != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unable to init probeEvent", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + if (vos_event_init( &(gpVosContext->wdaCompleteEvent) ) != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unable to init wdaCompleteEvent", __func__); + VOS_ASSERT(0); + + goto err_probe_event; + } + if (vos_event_init( &(gpVosContext->fwLogsComplete) ) != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unable to init fwLogsComplete", __func__); + VOS_ASSERT(0); + + goto err_wda_complete_event; + } + + /* Initialize the free message queue */ + vStatus = vos_mq_init(&gpVosContext->freeVosMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to initialize VOS free message queue", __func__); + VOS_ASSERT(0); + goto err_fw_logs_complete_event; + } + + for (iter = 0; iter < VOS_CORE_MAX_MESSAGES; iter++) + { + (gpVosContext->aMsgWrappers[iter]).pVosMsg = + &(gpVosContext->aMsgBuffers[iter]); + INIT_LIST_HEAD(&gpVosContext->aMsgWrappers[iter].msgNode); + vos_mq_put(&gpVosContext->freeVosMq, &(gpVosContext->aMsgWrappers[iter])); + } + + /* Now Open the VOS Scheduler */ + vStatus= vos_sched_open(gpVosContext, &gpVosContext->vosSched, + sizeof(VosSchedContext)); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open VOS Scheduler", __func__); + VOS_ASSERT(0); + goto err_msg_queue; + } + + /* + ** Need to open WDA first because it calls WDI_Init, which calls wpalOpen + ** The reason that is needed becasue vos_packet_open need to use PAL APIs + */ + + /*Open the WDA module */ + vos_mem_set(&macOpenParms, sizeof(macOpenParms), 0); + /* UMA is supported in hardware for performing the + ** frame translation 802.11 <-> 802.3 + */ + macOpenParms.frameTransRequired = 1; + macOpenParms.driverType = eDRIVER_TYPE_PRODUCTION; + vStatus = WDA_open( gpVosContext, devHandle, &macOpenParms ); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open WDA module", __func__); + VOS_ASSERT(0); + goto err_sched_close; + } + + /* Initialize here the VOS Packet sub module */ + vStatus = vos_packet_open( gpVosContext, &gpVosContext->vosPacket, + sizeof( vos_pkt_context_t ) ); + + if ( !VOS_IS_STATUS_SUCCESS( vStatus ) ) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open VOS Packet Module", __func__); + VOS_ASSERT(0); + goto err_wda_close; + } + + /* Open the SYS module */ + vStatus = sysOpen(gpVosContext); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open SYS module", __func__); + VOS_ASSERT(0); + goto err_packet_close; + } + +#ifndef CONFIG_ENABLE_LINUX_REG + /* initialize the NV module */ + vStatus = vos_nv_open(); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + // NV module cannot be initialized + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to initialize the NV module", __func__); + goto err_sys_close; + } +#endif + + /* If we arrive here, both threads dispacthing messages correctly */ + + /* Now proceed to open the MAC */ + + /* UMA is supported in hardware for performing the + frame translation 802.11 <-> 802.3 */ + macOpenParms.frameTransRequired = 1; + sirStatus = macOpen(&(gpVosContext->pMACContext), gpVosContext->pHDDContext, + &macOpenParms); + + if (eSIR_SUCCESS != sirStatus) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open MAC", __func__); + VOS_ASSERT(0); + goto err_nv_close; + } + + /* Now proceed to open the SME */ + vStatus = sme_Open(gpVosContext->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open SME", __func__); + VOS_ASSERT(0); + goto err_mac_close; + } + + /* Now proceed to open TL. Read TL config first */ + vos_fetch_tl_cfg_parms ( &TLConfig, + ((hdd_context_t*)(gpVosContext->pHDDContext))->cfg_ini); + + vStatus = WLANTL_Open(gpVosContext, &TLConfig); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + /* Critical Error ... Cannot proceed further */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to open TL", __func__); + VOS_ASSERT(0); + goto err_sme_close; + } + + if (gpVosContext->roamDelayStatsEnabled && + !vos_roam_delay_stats_init()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Could not init roamDelayStats", __func__); + } + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS successfully Opened", __func__); + + gpVosContext->snoc_high_freq_voting = false; + spin_lock_init(&gpVosContext->freq_voting_lock); + *pVosContext = gpVosContext; + + return VOS_STATUS_SUCCESS; + + +err_sme_close: + sme_Close(gpVosContext->pMACContext); + +err_mac_close: + macClose(gpVosContext->pMACContext); + +err_nv_close: + +#ifndef CONFIG_ENABLE_LINUX_REG + vos_nv_close(); + +err_sys_close: +#endif + + sysClose(gpVosContext); + +err_packet_close: + vos_packet_close( gpVosContext ); + +err_wda_close: + WDA_close(gpVosContext); + +err_sched_close: + vos_sched_close(gpVosContext); + + +err_msg_queue: + vos_mq_deinit(&gpVosContext->freeVosMq); + +err_fw_logs_complete_event: + vos_event_destroy( &gpVosContext->fwLogsComplete); + +err_wda_complete_event: + vos_event_destroy( &gpVosContext->wdaCompleteEvent ); + +err_probe_event: + vos_event_destroy(&gpVosContext->ProbeEvent); + + return VOS_STATUS_E_FAILURE; + +} /* vos_open() */ + +/*--------------------------------------------------------------------------- + + \brief vos_preStart() - + + The \a vos_preStart() function to download CFG. + including: + - ccmStart + + - WDA: triggers the CFG download + + + \param pVosContext: The VOS context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_start + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_preStart( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; + + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "vos prestart"); + + if (gpVosContext != pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Context mismatch", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (pVosContext->pMACContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: MAC NULL context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (pVosContext->pWDAContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + /* call macPreStart */ + vStatus = macPreStart(gpVosContext->pMACContext); + if ( !VOS_IS_STATUS_SUCCESS(vStatus) ) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed at macPreStart "); + return VOS_STATUS_E_FAILURE; + } + + /* call ccmStart */ + ccmStart(gpVosContext->pMACContext); + + /* Reset wda wait event */ + vos_event_reset(&gpVosContext->wdaCompleteEvent); + + + /*call WDA pre start*/ + vStatus = WDA_preStart(gpVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_FATAL, + "Failed to WDA prestart"); + macStop(gpVosContext->pMACContext, HAL_STOP_TYPE_SYS_DEEP_SLEEP); + ccmStop(gpVosContext->pMACContext); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Need to update time out of complete */ + vStatus = vos_wait_single_event( &gpVosContext->wdaCompleteEvent, + VOS_WDA_TIMEOUT ); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_preStart reporting other error", __func__); + } + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Test MC thread by posting a probe message to SYS", __func__); + wlan_sys_probe(); + + macStop(gpVosContext->pMACContext, HAL_STOP_TYPE_SYS_DEEP_SLEEP); + ccmStop(gpVosContext->pMACContext); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_mon_start( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; + + if (pVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: mismatch in context",__func__); + return VOS_STATUS_E_FAILURE; + } + + if (( pVosContext->pWDAContext == NULL) || ( pVosContext->pTLContext == NULL)) + { + if (pVosContext->pWDAContext == NULL) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + else + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: TL NULL context", __func__); + + return VOS_STATUS_E_FAILURE; + } + + /* Reset wda wait event */ + vos_event_reset(&pVosContext->wdaCompleteEvent); + + /*call WDA pre start*/ + vStatus = WDA_preStart(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR, + "Failed to WDA prestart "); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Need to update time out of complete */ + vStatus = vos_wait_single_event( &pVosContext->wdaCompleteEvent, 1000); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete",__func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_preStart reporting other error",__func__); + } + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAILURE; + } + + vStatus = WDA_NVDownload_Start(pVosContext); + + if ( vStatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start NV Download",__func__); + return VOS_STATUS_E_FAILURE; + } + + vStatus = vos_wait_single_event(&(pVosContext->wdaCompleteEvent), 1000 * 30); + + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA_NVDownload_Start complete",__func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_NVDownload_Start reporting other error",__func__); + } + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + vStatus = WDA_start(pVosContext); + if (vStatus != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start WDA",__func__); + return VOS_STATUS_E_FAILURE; + } + + /** START TL */ + vStatus = WLANTL_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start TL", __func__); + goto err_wda_stop; + } + + return VOS_STATUS_SUCCESS; + +err_wda_stop: + vos_event_reset(&(pVosContext->wdaCompleteEvent)); + WDA_stop(pVosContext, HAL_STOP_TYPE_RF_KILL); + vStatus = vos_wait_single_event(&(pVosContext->wdaCompleteEvent), 1000); + if(vStatus != VOS_STATUS_SUCCESS) + { + if(vStatus == VOS_STATUS_E_TIMEOUT) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA_stop complete",__func__); + + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_stop reporting other error",__func__); + } + VOS_ASSERT(0); + } + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS vos_mon_stop( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: HAL_STOP is requested", __func__); + + vosStatus = WDA_stop( vosContext, HAL_STOP_TYPE_RF_KILL ); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + WDA_setNeedShutdown(vosContext); + } + else + { + vosStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), + VOS_WDA_STOP_TIMEOUT ); + + if ( vosStatus != VOS_STATUS_SUCCESS ) + { + if ( vosStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_stop reporting other error", __func__ ); + } + WDA_setNeedShutdown(vosContext); + } + } + + vosStatus = WLANTL_Stop( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + + \brief vos_start() - Start the Libra SW Modules + + The \a vos_start() function starts all the components of the Libra SW + including: + - SAL/BAL, which in turn starts SSC + + - the MAC (HAL and PE) + + - SME + + - TL + + - SYS: triggers the CFG download + + + \param pVosContext: The VOS context + + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_preStart() + \sa vos_open() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_start( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + tSirRetStatus sirStatus = eSIR_SUCCESS; + pVosContextType pVosContext = (pVosContextType)vosContext; + tHalMacStartParameters halStartParams; + hdd_context_t *pHddCtx = NULL; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Starting Libra SW", __func__); + + /* We support only one instance for now ...*/ + if (gpVosContext != pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: mismatch in context", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (( pVosContext->pWDAContext == NULL) || ( pVosContext->pMACContext == NULL) + || ( pVosContext->pTLContext == NULL)) + { + if (pVosContext->pWDAContext == NULL) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA NULL context", __func__); + else if (pVosContext->pMACContext == NULL) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: MAC NULL context", __func__); + else + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: TL NULL context", __func__); + + return VOS_STATUS_E_FAILURE; + } + + /* WDA_Start will be called after NV image download because the + NV image data has to be updated at HAL before HAL_Start gets executed*/ + + /* Start the NV Image Download */ + + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + + vStatus = WDA_NVDownload_Start(pVosContext); + + if ( vStatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start NV Download", __func__); + return VOS_STATUS_E_FAILURE; + } + + vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), + VOS_WDA_TIMEOUT ); + + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA_NVDownload_start complete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_NVDownload_start reporting other error", __func__); + } + VOS_ASSERT(0); + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) + { + if (isSsrPanicOnFailure()) + VOS_BUG(0); + } + WDA_setNeedShutdown(vosContext); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: WDA_NVDownload_start correctly started", __func__); + + /* Start the WDA */ + vStatus = WDA_start(pVosContext); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to start WDA - WDA_shutdown needed %d ", + __func__, vStatus); + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + WDA_setNeedShutdown(vosContext); + vos_smd_dump_stats(); + vos_dump_wdi_events(); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Test MC thread by posting a probe message to SYS", + __func__); + wlan_sys_probe(); + } + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: WDA correctly started", __func__); + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if (!pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: HDD context is null", __func__); + goto err_wda_stop; + } + + pHddCtx->wifi_turn_on_time_since_boot = vos_get_monotonic_boottime(); + + /* Start the MAC */ + vos_mem_zero((v_PVOID_t)&halStartParams, sizeof(tHalMacStartParameters)); + + /* Start the MAC */ + sirStatus = macStart(pVosContext->pMACContext,(v_PVOID_t)&halStartParams); + + if (eSIR_SUCCESS != sirStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start MAC", __func__); + goto err_wda_stop; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MAC correctly started", __func__); + + /* START SME */ + vStatus = sme_Start(pVosContext->pMACContext); + + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start SME", __func__); + goto err_mac_stop; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: SME correctly started", __func__); + + /** START TL */ + vStatus = WLANTL_Start(pVosContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to start TL", __func__); + goto err_sme_stop; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TL correctly started"); + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: VOSS Start is successful!!", __func__); + + return VOS_STATUS_SUCCESS; + + +err_sme_stop: + sme_Stop(pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET); + +err_mac_stop: + macStop( pVosContext->pMACContext, HAL_STOP_TYPE_SYS_RESET ); + +err_wda_stop: + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + vStatus = WDA_stop( pVosContext, HAL_STOP_TYPE_RF_KILL); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vStatus ) ); + WDA_setNeedShutdown(vosContext); + } + else + { + vStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), + VOS_WDA_TIMEOUT ); + if( vStatus != VOS_STATUS_SUCCESS ) + { + if( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Timeout occurred before WDA_stop complete", __func__); + + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: WDA_stop reporting other error", __func__); + } + VOS_ASSERT( 0 ); + WDA_setNeedShutdown(vosContext); + } + } + + return VOS_STATUS_E_FAILURE; + +} /* vos_start() */ + + +/* vos_stop function */ +VOS_STATUS vos_stop( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + + /* WDA_Stop is called before the SYS so that the processing of Riva + pending responces will not be handled during uninitialization of WLAN driver */ + vos_event_reset( &(gpVosContext->wdaCompleteEvent) ); + + vosStatus = WDA_stop( vosContext, HAL_STOP_TYPE_RF_KILL ); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + WDA_setNeedShutdown(vosContext); + } + else + { + if(wcnss_device_is_shutdown()) + { + vosStatus = VOS_STATUS_E_TIMEOUT; + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Wait for WDA_Stop complete event not needed due to SSR", + __func__); + } + else + { + vosStatus = vos_wait_single_event( &(gpVosContext->wdaCompleteEvent), + VOS_WDA_STOP_TIMEOUT ); + } + + if ( vosStatus != VOS_STATUS_SUCCESS ) + { + if ( vosStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA complete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_stop reporting other error", __func__ ); + } + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Test MC thread by posting a probe message to SYS", __func__); + wlan_sys_probe(); + WDA_setNeedShutdown(vosContext); + } + } + + /* SYS STOP will stop SME and MAC */ + vosStatus = sysStop( vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = WLANTL_Stop( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to stop TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + return VOS_STATUS_SUCCESS; +} + + +/* vos_close function */ +VOS_STATUS vos_close( v_CONTEXT_t vosContext ) +{ + VOS_STATUS vosStatus; + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close BAP", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif // WLAN_BTAMP_FEATURE + + + vosStatus = WLANTL_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = sme_Close( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SME", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close MAC", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + ((pVosContextType)vosContext)->pMACContext = NULL; + +#ifndef CONFIG_ENABLE_LINUX_REG + vosStatus = vos_nv_close(); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close NV", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif + + vosStatus = sysClose( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + if ( TRUE == WDA_needShutdown(vosContext )) + { + /* if WDA stop failed, call WDA shutdown to cleanup WDA/WDI */ + vosStatus = WDA_shutdown( vosContext, VOS_TRUE ); + if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) + { + hdd_set_ssr_required( HDD_SSR_REQUIRED ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to shutdown WDA", __func__ ); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + } + else + { + vosStatus = WDA_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + } + + /* Let DXE return packets in WDA_close and then free them here */ + vosStatus = vos_packet_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close VOSS Packet", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq); + + vosStatus = vos_event_destroy(&gpVosContext->fwLogsComplete); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy fwLogsComplete", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy wdaCompleteEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy ProbeEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + if (gpVosContext->roamDelayStatsEnabled && + !vos_roam_delay_stats_deinit()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Could not deinit roamDelayStats", __func__); + } + + vos_wdthread_flush_timer_work(); + + return VOS_STATUS_SUCCESS; +} + + +/**--------------------------------------------------------------------------- + + \brief vos_get_context() - get context data area + + Each module in the system has a context / data area that is allocated + and maanged by voss. This API allows any user to get a pointer to its + allocated context data area from the VOSS global context. + + \param vosContext - the VOSS Global Context. + + \param moduleId - the module ID, who's context data are is being retrived. + + \return - pointer to the context data area. + + - NULL if the context data is not allocated for the module ID + specified + + --------------------------------------------------------------------------*/ +v_VOID_t* vos_get_context( VOS_MODULE_ID moduleId, + v_CONTEXT_t pVosContext ) +{ + v_PVOID_t pModContext = NULL; + + if (pVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos context pointer is null", __func__); + return NULL; + } + + if (gpVosContext != pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pVosContext != gpVosContext", __func__); + return NULL; + } + + switch(moduleId) + { + case VOS_MODULE_ID_TL: + { + pModContext = gpVosContext->pTLContext; + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case VOS_MODULE_ID_BAP: + { + pModContext = gpVosContext->pBAPContext; + break; + } +#endif //WLAN_BTAMP_FEATURE + + case VOS_MODULE_ID_SAP: + { + pModContext = gpVosContext->pSAPContext; + break; + } + + case VOS_MODULE_ID_HDD_SOFTAP: + { + pModContext = gpVosContext->pHDDSoftAPContext; + break; + } + + case VOS_MODULE_ID_HDD: + { + pModContext = gpVosContext->pHDDContext; + break; + } + + case VOS_MODULE_ID_SME: + case VOS_MODULE_ID_PE: + case VOS_MODULE_ID_PMC: + { + /* + ** In all these cases, we just return the MAC Context + */ + pModContext = gpVosContext->pMACContext; + break; + } + + case VOS_MODULE_ID_WDA: + { + /* For WDA module */ + pModContext = gpVosContext->pWDAContext; + break; + } + + case VOS_MODULE_ID_VOSS: + { + /* For SYS this is VOS itself*/ + pModContext = gpVosContext; + break; + } + + default: + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i " + "does not have its context maintained by VOSS", __func__, moduleId); + VOS_ASSERT(0); + return NULL; + } + } + + if (pModContext == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i " + "context is Null", __func__, moduleId); + } + + return pModContext; + +} /* vos_get_context()*/ + + +/**--------------------------------------------------------------------------- + + \brief vos_get_global_context() - get VOSS global Context + + This API allows any user to get the VOS Global Context pointer from a + module context data area. + + \param moduleContext - the input module context pointer + + \param moduleId - the module ID who's context pointer is input in + moduleContext. + + \return - pointer to the VOSS global context + + - NULL if the function is unable to retreive the VOSS context. + + --------------------------------------------------------------------------*/ +v_CONTEXT_t vos_get_global_context( VOS_MODULE_ID moduleId, + v_VOID_t *moduleContext ) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + } + + return gpVosContext; + +} /* vos_get_global_context() */ + + +v_U8_t vos_is_logp_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return 1; + } + + return gpVosContext->isLogpInProgress; +} + +void vos_set_logp_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + + gpVosContext->isLogpInProgress = value; +} + +v_U8_t vos_is_load_unload_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return 0; + } + + return gpVosContext->isLoadUnloadInProgress; +} + +void vos_set_load_unload_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + + gpVosContext->isLoadUnloadInProgress = value; +} + +v_U8_t vos_is_reinit_in_progress(VOS_MODULE_ID moduleId, v_VOID_t *moduleContext) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return 1; + } + + return gpVosContext->isReInitInProgress; +} + +void vos_set_reinit_in_progress(VOS_MODULE_ID moduleId, v_U8_t value) +{ + if (gpVosContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: global voss context is NULL", __func__); + return; + } + + gpVosContext->isReInitInProgress = value; +} + + +/**--------------------------------------------------------------------------- + + \brief vos_alloc_context() - allocate a context within the VOSS global Context + + This API allows any user to allocate a user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being allocated. + + \param ppModuleContext - pointer to location where the pointer to the + allocated context is returned. Note this + output pointer is valid only if the API + returns VOS_STATUS_SUCCESS + + \param size - the size of the context area to be allocated. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + allocated successfully. The pointer to the context area + can be found in *ppModuleContext. + \note This function returns VOS_STATUS_SUCCESS if the + module context was already allocated and the size + allocated matches the size on this call. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context allocated. + + VOS_STATUS_E_EXISTS - vos could allocate the requested context + because a context for this module ID already exists and it is + a *different* size that specified on this call. + + VOS_STATUS_E_NOMEM - vos could not allocate memory for the + requested context area. + + \sa vos_get_context(), vos_free_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_alloc_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t **ppModuleContext, v_SIZE_t size ) +{ + v_VOID_t ** pGpModContext = NULL; + + if ( pVosContext == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is null", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (( gpVosContext != pVosContext) || ( ppModuleContext == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: context mismatch or null param passed", __func__); + return VOS_STATUS_E_FAILURE; + } + + switch(moduleID) + { + case VOS_MODULE_ID_TL: + { + pGpModContext = &(gpVosContext->pTLContext); + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case VOS_MODULE_ID_BAP: + { + pGpModContext = &(gpVosContext->pBAPContext); + break; + } +#endif //WLAN_BTAMP_FEATURE + + case VOS_MODULE_ID_SAP: + { + pGpModContext = &(gpVosContext->pSAPContext); + break; + } + + case VOS_MODULE_ID_WDA: + { + pGpModContext = &(gpVosContext->pWDAContext); + break; + } + case VOS_MODULE_ID_SME: + case VOS_MODULE_ID_PE: + case VOS_MODULE_ID_PMC: + case VOS_MODULE_ID_HDD: + case VOS_MODULE_ID_HDD_SOFTAP: + default: + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Module ID %i " + "does not have its context allocated by VOSS", __func__, moduleID); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + } + + if ( NULL != *pGpModContext) + { + /* + ** Context has already been allocated! + ** Prevent double allocation + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Module ID %i context has already been allocated", + __func__, moduleID); + return VOS_STATUS_E_EXISTS; + } + + /* + ** Dynamically allocate the context for module + */ + + *ppModuleContext = kmalloc(size, GFP_KERNEL); + + + if ( *ppModuleContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Failed to " + "allocate Context for module ID %i", __func__, moduleID); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + if (moduleID==VOS_MODULE_ID_TL) + { + vos_mem_zero(*ppModuleContext, size); + } + + *pGpModContext = *ppModuleContext; + + return VOS_STATUS_SUCCESS; + +} /* vos_alloc_context() */ + + +/**--------------------------------------------------------------------------- + + \brief vos_free_context() - free an allocated a context within the + VOSS global Context + + This API allows a user to free the user context area within the + VOS Global Context. + + \param pVosContext - pointer to the global Vos context + + \param moduleId - the module ID who's context area is being free + + \param pModuleContext - pointer to module context area to be free'd. + + \return - VOS_STATUS_SUCCESS - the context for the module ID has been + free'd. The pointer to the context area is not longer + available. + + VOS_STATUS_E_FAULT - pVosContext or pModuleContext are not + valid pointers. + + VOS_STATUS_E_INVAL - the moduleId is not a valid or does + not identify a module that can have a context free'd. + + VOS_STATUS_E_EXISTS - vos could not free the requested + context area because a context for this module ID does not + exist in the global vos context. + + \sa vos_get_context() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_free_context( v_VOID_t *pVosContext, VOS_MODULE_ID moduleID, + v_VOID_t *pModuleContext ) +{ + v_VOID_t ** pGpModContext = NULL; + + if (( pVosContext == NULL) || ( gpVosContext != pVosContext) || + ( pModuleContext == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or context mismatch", __func__); + return VOS_STATUS_E_FAILURE; + } + + + switch(moduleID) + { + case VOS_MODULE_ID_TL: + { + pGpModContext = &(gpVosContext->pTLContext); + break; + } + +#ifdef WLAN_BTAMP_FEATURE + case VOS_MODULE_ID_BAP: + { + pGpModContext = &(gpVosContext->pBAPContext); + break; + } +#endif //WLAN_BTAMP_FEATURE + + case VOS_MODULE_ID_SAP: + { + pGpModContext = &(gpVosContext->pSAPContext); + break; + } + + case VOS_MODULE_ID_WDA: + { + pGpModContext = &(gpVosContext->pWDAContext); + break; + } + case VOS_MODULE_ID_HDD: + case VOS_MODULE_ID_SME: + case VOS_MODULE_ID_PE: + case VOS_MODULE_ID_PMC: + case VOS_MODULE_ID_HDD_SOFTAP: + default: + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Module ID %i " + "does not have its context allocated by VOSS", __func__, moduleID); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + } + + if ( NULL == *pGpModContext) + { + /* + ** Context has not been allocated or freed already! + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,"%s: Module ID %i " + "context has not been allocated or freed already", __func__,moduleID); + return VOS_STATUS_E_FAILURE; + } + + if (*pGpModContext != pModuleContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pGpModContext != pModuleContext", __func__); + return VOS_STATUS_E_FAILURE; + } + + if(pModuleContext != NULL) + kfree(pModuleContext); + + *pGpModContext = NULL; + + return VOS_STATUS_SUCCESS; + +} /* vos_free_context() */ + + +bool vos_is_log_report_in_progress(void) +{ + return wlan_is_log_report_in_progress(); +} + +void vos_reset_log_report_in_progress(void) +{ + return wlan_reset_log_report_in_progress(); +} + + + + +int vos_set_log_completion(uint32 is_fatal, + uint32 indicator, + uint32 reason_code) +{ + return wlan_set_log_completion(is_fatal, + indicator,reason_code); +} + +void vos_get_log_and_reset_completion(uint32 *is_fatal, + uint32 *indicator, + uint32 *reason_code, + bool reset) +{ + wlan_get_log_and_reset_completion(is_fatal, indicator, reason_code, reset); +} + + + +void vos_send_fatal_event_done(void) +{ + /*Complete the fwLogsComplete Event*/ + VosContextType *vos_context; + uint32_t is_fatal, indicator, reason_code; + + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_context) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is Invalid", __func__); + return; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: vos_event_set for fwLogsComplete", __func__); + if (vos_event_set(&vos_context->fwLogsComplete)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed for fwLogsComplete", __func__); + return; + } + /*The below API will reset is_report_in_progress flag*/ + vos_get_log_and_reset_completion(&is_fatal, &indicator, + &reason_code, true); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "is_fatal : %d, indicator: %d, reason_code=%d", + is_fatal, indicator, reason_code); + wlan_report_log_completion(is_fatal, indicator, reason_code); + + /* Do ssr after reporting fatal event to recover from + * below conditions + */ + if ((WLAN_LOG_INDICATOR_HOST_DRIVER == indicator) && + (WLAN_LOG_REASON_SME_COMMAND_STUCK == reason_code || + WLAN_LOG_REASON_SME_OUT_OF_CMD_BUF == reason_code || + WLAN_LOG_REASON_SCAN_NOT_ALLOWED == reason_code)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Do SSR for reason_code=%d", reason_code); + vos_wlanRestart(); + } +} + +/** + * vos_isFatalEventEnabled() + * + * Return TRUE if Fatal event is enabled is in progress. + * + */ +v_BOOL_t vos_isFatalEventEnabled(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return FALSE; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return FALSE; + } + + return pHddCtx->cfg_ini->enableFatalEvent; +} + +/**--------------------------------------------------------------------------- + + \brief __vos_fatal_event_logs_req() - used to send flush command to FW + + This API is wrapper to SME flush API. + + \param is_fatal - fatal or non fatal event + indicator - Tyoe of indicator framework/Host/FW + reason_code - reason code for flush logs + + \return VOS_STATUS_SUCCESS - if command is sent successfully. + VOS_STATUS_E_FAILURE - if command is not sent successfully. + --------------------------------------------------------------------------*/ +VOS_STATUS __vos_fatal_event_logs_req( uint32_t is_fatal, + uint32_t indicator, + uint32_t reason_code, + bool wait_required, + bool dump_vos_trace) +{ + VOS_STATUS vosStatus; + eHalStatus status; + VosContextType *vos_context; + hdd_context_t *pHddCtx = NULL; + + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_context) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is Invalid", __func__); + return VOS_STATUS_E_FAILURE; + } + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, vos_context ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + if(!pHddCtx->cfg_ini->wlanLoggingEnable) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Wlan logging not enabled", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (!pHddCtx->cfg_ini->enableFatalEvent || !pHddCtx->is_fatal_event_log_sup) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Fatal event not enabled", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (pHddCtx->isLoadUnloadInProgress || + vos_context->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: un/Load/SSR in progress", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (vos_is_log_report_in_progress() == true) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Fatal Event Req already in progress - dropping! type:%d, indicator=%d reason_code=%d", + __func__, is_fatal, indicator, reason_code); + return VOS_STATUS_E_FAILURE; + } + + vosStatus = vos_set_log_completion(is_fatal, indicator, reason_code); + if (VOS_STATUS_SUCCESS != vosStatus) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to set log trigger params for fatalEvent", __func__); + return VOS_STATUS_E_FAILURE; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Triggering fatal Event: type:%d, indicator=%d reason_code=%d", + __func__, is_fatal, indicator, reason_code); + + status = vos_event_reset(&gpVosContext->fwLogsComplete); + if(!HAL_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("fwLogsComplete reset failed:%d"),status); + return VOS_STATUS_E_FAILURE; + } + status = sme_fatal_event_logs_req(vos_context->pMACContext, + is_fatal, indicator, + reason_code, dump_vos_trace); + + if (HAL_STATUS_SUCCESS(status) && (wait_required == TRUE)) + { + + /* Need to update time out of complete */ + vosStatus = vos_wait_single_event(&gpVosContext->fwLogsComplete, + WAIT_TIME_FW_LOGS); + if ( vosStatus != VOS_STATUS_SUCCESS ) + { + if ( vosStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before fwLogsComplete", __func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: fwLogsComplete reporting other error", __func__); + } + /*Done indication is not received.So reset the bug report in progress*/ + vos_reset_log_report_in_progress(); + return VOS_STATUS_E_FAILURE; + } + } + if (HAL_STATUS_SUCCESS( status )) + return VOS_STATUS_SUCCESS; + else + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS vos_fatal_event_logs_req( uint32_t is_fatal, + uint32_t indicator, + uint32_t reason_code, + bool wait_required, + bool dump_vos_trace) +{ + VOS_STATUS status; + + vos_ssr_protect(__func__); + status = __vos_fatal_event_logs_req(is_fatal, indicator, reason_code, + wait_required, dump_vos_trace); + vos_ssr_unprotect(__func__); + + return status; +} + +/**--------------------------------------------------------------------------- + + \brief vos_process_done_indication() - Process the done indication for fatal event, + FW memory dump + + This API processes the done indication and wakeup the logger thread accordingly. + + \param type - Type for which done indication is received. + + + \return VOS_STATUS_SUCCESS - the pkt has been successfully queued. + VOS_STATUS_E_FAILURE - the pkt queue handler has reported + a failure. + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_process_done_indication(v_U8_t type, v_U32_t reason_code) +{ + wlan_process_done_indication(type, reason_code); + return VOS_STATUS_SUCCESS; +} + +/** + * vos_flush_host_logs_for_fatal() -flush host logs and send + * fatal event to upper layer. + */ +void vos_flush_host_logs_for_fatal(void) +{ + wlan_flush_host_logs_for_fatal(); + return; +} + + +/**--------------------------------------------------------------------------- + + \brief vos_logger_pkt_serialize() - queue a logging vos pkt + + This API allows single vos pkt to be queued and later sent to userspace by + logger thread. + + \param pPacket - a pointer to a vos pkt to be queued + pkt_type - type of pkt to be queued + + \return VOS_STATUS_SUCCESS - the pkt has been successfully queued. + VOS_STATUS_E_FAILURE - the pkt queue handler has reported + a failure. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_logger_pkt_serialize( vos_pkt_t *pPacket, uint32 pkt_type) +{ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + return wlan_queue_logpkt_for_app(pPacket, pkt_type); +#else + return vos_pkt_return_packet(pPacket); +#endif +} + +void vos_per_pkt_stats_to_user(void *perPktStat) +{ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_pkt_stats_to_user(perPktStat); +#else + return; +#endif + + + +} + +void vos_updatePktStatsInfo(void * pktStat) +{ +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_fillTxStruct(pktStat); +#else + return; +#endif + +} + + +/**--------------------------------------------------------------------------- + + \brief vos_mq_post_message() - post a message to a message queue + + This API allows messages to be posted to a specific message queue. Messages + can be posted to the following message queues: + +
    +
  • SME +
  • PE +
  • HAL +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is posted to the message queue. If the consumer of the + message needs anything in this message, it needs to copy the contents + before returning from the message queue handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_mq_post_message( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + /// Message Queue ID for messages bound for SME + case VOS_MQ_ID_SME: + { + pTargetMq = &(gpVosContext->vosSched.smeMcMq); + break; + } + + /// Message Queue ID for messages bound for PE + case VOS_MQ_ID_PE: + { + pTargetMq = &(gpVosContext->vosSched.peMcMq); + break; + } + + /// Message Queue ID for messages bound for WDA + case VOS_MQ_ID_WDA: + { + pTargetMq = &(gpVosContext->vosSched.wdaMcMq); + break; + } + + /// Message Queue ID for messages bound for WDI + case VOS_MQ_ID_WDI: + { + pTargetMq = &(gpVosContext->vosSched.wdiMcMq); + break; + } + + /// Message Queue ID for messages bound for TL + case VOS_MQ_ID_TL: + { + pTargetMq = &(gpVosContext->vosSched.tlMcMq); + break; + } + + /// Message Queue ID for messages bound for the SYS module + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysMcMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s: Trying to queue msg into unknown MC Msg queue ID %d"), + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + VOS_ASSERT(NULL !=pTargetMq); + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Core run out of message wrapper", __func__); + if (!gpVosContext->vosWrapperFullReported) + { + gpVosContext->vosWrapperFullReported = 1; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + FALSE, TRUE); + } + return VOS_STATUS_E_RESOURCES; + } + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put(pTargetMq, pMsgWrapper); + + set_bit(MC_POST_EVENT, &gpVosContext->vosSched.mcEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.mcWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_mq_post_message()*/ + + +/**-------------------------------------------------------------------------- + \brief vos_mq_post_message_high_pri() - posts a high priority message to + a message queue + + This API allows messages to be posted to the head of a specific message + queue. Messages can be posted to the following message queues: + +
    +
  • SME +
  • PE +
  • HAL +
  • TL +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is posted to the message queue. If the consumer of the + message needs anything in this message, it needs to copy the contents + before returning from the message queue handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_mq_post_message_high_pri(VOS_MQ_ID msgQueueId, vos_msg_t *pMsg) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + /// Message Queue ID for messages bound for SME + case VOS_MQ_ID_SME: + { + pTargetMq = &(gpVosContext->vosSched.smeMcMq); + break; + } + + /// Message Queue ID for messages bound for PE + case VOS_MQ_ID_PE: + { + pTargetMq = &(gpVosContext->vosSched.peMcMq); + break; + } + + /// Message Queue ID for messages bound for WDA + case VOS_MQ_ID_WDA: + { + pTargetMq = &(gpVosContext->vosSched.wdaMcMq); + break; + } + + /// Message Queue ID for messages bound for WDI + case VOS_MQ_ID_WDI: + { + pTargetMq = &(gpVosContext->vosSched.wdiMcMq); + break; + } + + /// Message Queue ID for messages bound for TL + case VOS_MQ_ID_TL: + { + pTargetMq = &(gpVosContext->vosSched.tlMcMq); + break; + } + + /// Message Queue ID for messages bound for the SYS module + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysMcMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s: Trying to queue msg into unknown MC Msg queue ID %d"), + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + VOS_ASSERT(NULL !=pTargetMq); + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Core run out of message wrapper", __func__); + if (!gpVosContext->vosWrapperFullReported) + { + gpVosContext->vosWrapperFullReported = 1; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + FALSE, TRUE); + } + return VOS_STATUS_E_RESOURCES; + } + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put_front(pTargetMq, pMsgWrapper); + + set_bit(MC_POST_EVENT, &gpVosContext->vosSched.mcEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.mcWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_mq_post_message_high_pri()*/ + + + +/**--------------------------------------------------------------------------- + + \brief vos_tx_mq_serialize() - serialize a message to the Tx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Tx execution flow can be posted only + to the following queue. + +
    +
  • TL +
  • SSC/WDI +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_tx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + /// Message Queue ID for messages bound for SME + case VOS_MQ_ID_TL: + { + pTargetMq = &(gpVosContext->vosSched.tlTxMq); + break; + } + + /// Message Queue ID for messages bound for SSC + case VOS_MQ_ID_WDI: + { + pTargetMq = &(gpVosContext->vosSched.wdiTxMq); + break; + } + + /// Message Queue ID for messages bound for the SYS module + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysTxMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to queue msg into unknown Tx Msg queue ID %d", + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: VOS Core run out of message wrapper", __func__); + if (!gpVosContext->vosWrapperFullReported) + { + gpVosContext->vosWrapperFullReported = 1; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + FALSE, TRUE); + } + + return VOS_STATUS_E_RESOURCES; + } + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put(pTargetMq, pMsgWrapper); + + set_bit(TX_POST_EVENT, &gpVosContext->vosSched.txEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.txWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_tx_mq_serialize()*/ + +/**--------------------------------------------------------------------------- + + \brief vos_rx_mq_serialize() - serialize a message to the Rx execution flow + + This API allows messages to be posted to a specific message queue in the + Tx excution flow. Messages for the Rx execution flow can be posted only + to the following queue. + +
    +
  • TL +
  • WDI +
+ + \param msgQueueId - identifies the message queue upon which the message + will be posted. + + \param message - a pointer to a message buffer. Body memory for this message + buffer is allocated by the caller and free'd by the vOSS after the + message is dispacthed to the appropriate component. If the consumer + of the message needs to keep anything in the body, it needs to copy + the contents before returning from the message handler. + + \return VOS_STATUS_SUCCESS - the message has been successfully posted + to the message queue. + + VOS_STATUS_E_INVAL - The value specified by msgQueueId does not + refer to a valid Message Queue Id. + + VOS_STATUS_E_FAULT - message is an invalid pointer. + + VOS_STATUS_E_FAILURE - the message queue handler has reported + an unknown failure. + + \sa + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_rx_mq_serialize( VOS_MQ_ID msgQueueId, vos_msg_t *pMsg ) +{ + pVosMqType pTargetMq = NULL; + pVosMsgWrapper pMsgWrapper = NULL; + if ((gpVosContext == NULL) || (pMsg == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params or global vos context is null", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + switch (msgQueueId) + { + + case VOS_MQ_ID_SYS: + { + pTargetMq = &(gpVosContext->vosSched.sysRxMq); + break; + } + + /// Message Queue ID for messages bound for WDI + case VOS_MQ_ID_WDI: + { + pTargetMq = &(gpVosContext->vosSched.wdiRxMq); + break; + } + case VOS_MQ_ID_TL: + { + pTargetMq = &(gpVosContext->vosSched.tlRxMq); + break; + } + + default: + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Trying to queue msg into unknown Rx Msg queue ID %d", + __func__, msgQueueId); + + return VOS_STATUS_E_FAILURE; + } + + if (pTargetMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pTargetMq == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + + /* + ** Try and get a free Msg wrapper + */ + pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq); + + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Core run out of message wrapper", __func__); + if (!gpVosContext->vosWrapperFullReported) + { + gpVosContext->vosWrapperFullReported = 1; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + FALSE, TRUE); + } + + return VOS_STATUS_E_RESOURCES; + } + + /* + ** Copy the message now + */ + vos_mem_copy( (v_VOID_t*)pMsgWrapper->pVosMsg, + (v_VOID_t*)pMsg, sizeof(vos_msg_t)); + + vos_mq_put(pTargetMq, pMsgWrapper); + + set_bit(RX_POST_EVENT, &gpVosContext->vosSched.rxEventFlag); + wake_up_interruptible(&gpVosContext->vosSched.rxWaitQueue); + + return VOS_STATUS_SUCCESS; + +} /* vos_rx_mq_serialize()*/ + +v_VOID_t +vos_sys_probe_thread_cback +( + v_VOID_t *pUserData +) +{ + if (gpVosContext != pUserData) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosContext != pUserData", __func__); + return; + } + + if (vos_event_set(&gpVosContext->ProbeEvent)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + return; + } + +} /* vos_sys_probe_thread_cback() */ + +v_VOID_t vos_WDAComplete_cback +( + v_VOID_t *pUserData +) +{ + + if (gpVosContext != pUserData) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosContext != pUserData", __func__); + return; + } + + if (vos_event_set(&gpVosContext->wdaCompleteEvent)!= VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos_event_set failed", __func__); + return; + } + +} /* vos_WDAComplete_cback() */ + +v_VOID_t vos_core_return_msg +( + v_PVOID_t pVContext, + pVosMsgWrapper pMsgWrapper +) +{ + pVosContextType pVosContext = (pVosContextType) pVContext; + + VOS_ASSERT( gpVosContext == pVosContext); + + if (gpVosContext != pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosContext != pVosContext", __func__); + return; + } + + VOS_ASSERT( NULL !=pMsgWrapper ); + + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper == NULL in function", __func__); + return; + } + + /* + ** Return the message on the free message queue + */ + INIT_LIST_HEAD(&pMsgWrapper->msgNode); + vos_mq_put(&pVosContext->freeVosMq, pMsgWrapper); + +} /* vos_core_return_msg() */ + + +/** + @brief vos_fetch_tl_cfg_parms() - this function will attempt to read the + TL config params from the registry + + @param pAdapter : [inout] pointer to TL config block + + @return + None + +*/ +v_VOID_t +vos_fetch_tl_cfg_parms +( + WLANTL_ConfigInfoType *pTLConfig, + hdd_config_t * pConfig +) +{ + if (pTLConfig == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s NULL ptr passed in!", __func__); + return; + } + + pTLConfig->ucAcWeights[0] = pConfig->WfqBkWeight; + pTLConfig->ucAcWeights[1] = pConfig->WfqBeWeight; + pTLConfig->ucAcWeights[2] = pConfig->WfqViWeight; + pTLConfig->ucAcWeights[3] = pConfig->WfqVoWeight; + pTLConfig->ucAcWeights[4] = pConfig->WfqVoWeight; + pTLConfig->ucReorderAgingTime[0] = pConfig->BkReorderAgingTime;/*WLANTL_AC_BK*/ + pTLConfig->ucReorderAgingTime[1] = pConfig->BeReorderAgingTime;/*WLANTL_AC_BE*/ + pTLConfig->ucReorderAgingTime[2] = pConfig->ViReorderAgingTime;/*WLANTL_AC_VI*/ + pTLConfig->ucReorderAgingTime[3] = pConfig->VoReorderAgingTime;/*WLANTL_AC_VO*/ + pTLConfig->uDelayedTriggerFrmInt = pConfig->DelayedTriggerFrmInt; + pTLConfig->uMinFramesProcThres = pConfig->MinFramesProcThres; + +} + +v_BOOL_t vos_is_apps_power_collapse_allowed(void* pHddCtx) +{ + return hdd_is_apps_power_collapse_allowed((hdd_context_t*) pHddCtx); +} + +/*--------------------------------------------------------------------------- + + \brief vos_shutdown() - shutdown VOS + + - All VOS submodules are closed. + + - All the WLAN SW components should have been opened. This includes + SYS, MAC, SME and TL. + + + \param vosContext: Global vos context + + + \return VOS_STATUS_SUCCESS - Operation successfull & vos is shutdown + + VOS_STATUS_E_FAILURE - Failure to close + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_shutdown(v_CONTEXT_t vosContext) +{ + VOS_STATUS vosStatus; + +#ifdef WLAN_BTAMP_FEATURE + vosStatus = WLANBAP_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close BAP", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } +#endif // WLAN_BTAMP_FEATURE + + vosStatus = WLANTL_Close(vosContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close TL", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = sme_Close( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SME", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = macClose( ((pVosContextType)vosContext)->pMACContext); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close MAC", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + ((pVosContextType)vosContext)->pMACContext = NULL; + + vosStatus = sysClose( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close SYS", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + /* Let DXE return packets in WDA_close and then free them here */ + vosStatus = vos_packet_close( vosContext ); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to close VOSS Packet", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vos_mq_deinit(&((pVosContextType)vosContext)->freeVosMq); + + vosStatus = vos_event_destroy(&gpVosContext->fwLogsComplete); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy fwLogsComplete", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + + vosStatus = vos_event_destroy(&gpVosContext->wdaCompleteEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy wdaCompleteEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + vosStatus = vos_event_destroy(&gpVosContext->ProbeEvent); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to destroy ProbeEvent", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + + \brief vos_wda_shutdown() - VOS interface to wda shutdown + + - WDA/WDI shutdown + + \param vosContext: Global vos context + + + \return VOS_STATUS_SUCCESS - Operation successfull + + VOS_STATUS_E_FAILURE - Failure to close + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_wda_shutdown(v_CONTEXT_t vosContext) +{ + VOS_STATUS vosStatus; + vosStatus = WDA_shutdown(vosContext, VOS_FALSE); + + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: failed to shutdown WDA", __func__); + VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) ); + } + return vosStatus; +} +/** + @brief vos_wlanShutdown() - This API will shutdown WLAN driver + + This function is called when Riva subsystem crashes. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Called when Riva goes down, this will shutdown WLAN + driver without handshaking with Riva. + 2. re-init: Next API + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanShutdown(void) +{ + VOS_STATUS vstatus; + vstatus = vos_watchdog_wlan_shutdown(); + return vstatus; +} +/** + @brief vos_wlanReInit() - This API will re-init WLAN driver + + This function is called when Riva subsystem reboots. There are two + methods (or operations) in WLAN driver to handle Riva crash, + 1. shutdown: Previous API + 2. re-init: Called when Riva comes back after the crash. This will + re-initialize WLAN driver. In some cases re-open may be + referred instead of re-init. + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_wlanReInit(void) +{ + VOS_STATUS vstatus; + vstatus = vos_watchdog_wlan_re_init(); + return vstatus; +} +/** + @brief vos_wlanRestart() - This API will reload WLAN driver. + + This function is called if driver detects any fatal state which + can be recovered by a WLAN module reload ( Android framwork initiated ). + Note that this API will not initiate any RIVA subsystem restart. + + The function wlan_hdd_restart_driver protects against re-entrant calls. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + VOS_STATUS_E_EMPTY - No configured interface + VOS_STATUS_E_ALREADY - Request already in progress + + +*/ +VOS_STATUS vos_wlanRestart(void) +{ + VOS_STATUS vstatus; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Check whether driver load unload is in progress */ + if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Driver load/unload is in progress, retry later.", __func__); + return VOS_STATUS_E_AGAIN; + } + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + if(!pVosContext) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* Reload the driver */ + vstatus = wlan_hdd_restart_driver(pHddCtx); + return vstatus; +} + + +/** + @brief vos_fwDumpReq() + + This function is called to issue dump commands to Firmware + + @param + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + async - asynchronous event. Don't wait for completion. + @return + NONE +*/ +v_VOID_t vos_fwDumpReq(tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, + tANI_U32 arg3, tANI_U32 arg4, tANI_U8 async) +{ + WDA_HALDumpCmdReq(NULL, cmd, arg1, arg2, arg3, arg4, NULL, async); +} + +v_U64_t vos_get_monotonic_boottime(void) +{ + struct timespec ts; + wcnss_get_monotonic_boottime(&ts); + return (((v_U64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000)); +} + +/**--------------------------------------------------------------------------- + + \brief vos_randomize_n_bytes() - HDD Random Mac Addr Generator + + This generates the random mac address for WLAN interface + + \param - mac_addr - pointer to Mac address + + \return - 0 for success, < 0 for failure + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_randomize_n_bytes(void *start_addr, tANI_U32 n) +{ + + if (start_addr == NULL ) + return VOS_STATUS_E_FAILURE; + + get_random_bytes( start_addr, n); + + return eHAL_STATUS_SUCCESS; +} + +/**--------------------------------------------------------------------------- + + \brief vos_is_wlan_in_badState() - get isFatalError flag from WD Ctx + + \param - VOS_MODULE_ID - module id + - moduleContext - module context + + \return - isFatalError value if WDCtx is valid otherwise true + + --------------------------------------------------------------------------*/ +v_BOOL_t vos_is_wlan_in_badState(VOS_MODULE_ID moduleId, + v_VOID_t *moduleContext) +{ + struct _VosWatchdogContext *pVosWDCtx = get_vos_watchdog_ctxt(); + + if (pVosWDCtx == NULL){ + VOS_TRACE(moduleId, VOS_TRACE_LEVEL_ERROR, + "%s: global wd context is null", __func__); + + return TRUE; + } + return pVosWDCtx->isFatalError; +} + +/**--------------------------------------------------------------------------- + + \brief vos_is_fw_logging_enabled() - + + API to check if firmware is configured to send logs using DXE channel + + \param - None + + \return - 0: firmware logging is not enabled (it may or may not + be supported) + 1: firmware logging is enabled + + --------------------------------------------------------------------------*/ +v_U8_t vos_is_fw_logging_enabled(void) +{ + return hdd_is_fw_logging_enabled(); +} + +/**--------------------------------------------------------------------------- + + \brief vos_is_fw_ev_logging_enabled() - + + API to check if firmware is configured to send live logs using DXE channel + + \param - None + + \return - 0: firmware logging is not enabled (it may or may not + be supported) + 1: firmware logging is enabled + + --------------------------------------------------------------------------*/ +v_U8_t vos_is_fw_ev_logging_enabled(void) +{ + return hdd_is_fw_ev_logging_enabled(); +} + +/**--------------------------------------------------------------------------- + + \brief vos_is_fw_logging_supported() - + + API to check if firmware supports to send logs using DXE channel + + \param - None + + \return - 0: firmware logging is not supported + 1: firmware logging is supported + + --------------------------------------------------------------------------*/ +v_U8_t vos_is_fw_logging_supported(void) +{ + return IS_FRAME_LOGGING_SUPPORTED_BY_FW; +} +/**--------------------------------------------------------------------------- + + \brief vos_set_roam_delay_stats_enabled() - + + API to set value of roamDelayStatsEnabled in vos context + + \param - value to be updated + + \return - NONE + + --------------------------------------------------------------------------*/ + +v_VOID_t vos_set_roam_delay_stats_enabled(v_U8_t value) +{ + gpVosContext->roamDelayStatsEnabled = value; +} + + +/**--------------------------------------------------------------------------- + + \brief vos_get_roam_delay_stats_enabled() - + + API to get value of roamDelayStatsEnabled from vos context + + \param - NONE + + \return - value of roamDelayStatsEnabled + + --------------------------------------------------------------------------*/ + +v_U8_t vos_get_roam_delay_stats_enabled(v_VOID_t) +{ + return gpVosContext->roamDelayStatsEnabled; +} + +v_U32_t vos_get_dxeReplenishRXTimerVal(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__); + return 0; + } + + return pHddCtx->cfg_ini->dxeReplenishRXTimerVal; +} + +v_BOOL_t vos_get_dxeSSREnable(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Global VOS context is Null", __func__); + return FALSE; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__); + return FALSE; + } + + return pHddCtx->cfg_ini->dxeSSREnable; +} + +v_VOID_t vos_flush_work(struct work_struct *work) +{ +#if defined (WLAN_OPEN_SOURCE) + cancel_work_sync(work); +#else + wcnss_flush_work(work); +#endif +} + +v_VOID_t vos_flush_delayed_work(struct delayed_work *dwork) +{ +#if defined (WLAN_OPEN_SOURCE) + cancel_delayed_work_sync(dwork); +#else + wcnss_flush_delayed_work(dwork); +#endif +} + +v_VOID_t vos_init_work(struct work_struct *work , void *callbackptr) +{ +#if defined (WLAN_OPEN_SOURCE) + INIT_WORK(work,callbackptr); +#else + wcnss_init_work(work, callbackptr); +#endif +} + +v_VOID_t vos_init_delayed_work(struct delayed_work *dwork , void *callbackptr) +{ +#if defined (WLAN_OPEN_SOURCE) + INIT_DELAYED_WORK(dwork,callbackptr); +#else + wcnss_init_delayed_work(dwork, callbackptr); +#endif +} + +/** + * vos_set_multicast_logging() - Set mutlicast logging value + * @value: Value of multicast logging + * + * Set the multicast logging value which will indicate + * whether to multicast host and fw messages even + * without any registration by userspace entity + * + * Return: None + */ +void vos_set_multicast_logging(uint8_t value) +{ + vos_multicast_logging = value; +} + +/** + * vos_is_multicast_logging() - Get multicast logging value + * + * Get the multicast logging value which will indicate + * whether to multicast host and fw messages even + * without any registration by userspace entity + * + * Return: 0 - Multicast logging disabled, 1 - Multicast logging enabled + */ +v_U8_t vos_is_multicast_logging(void) +{ + return vos_multicast_logging; +} + +/** + * vos_isLoadUnloadInProgress() + * + * Return TRUE if load/unload is in progress. + * + */ +v_BOOL_t vos_isLoadUnloadInProgress(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return FALSE; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return FALSE; + } + + return ( 0 != pHddCtx->isLoadUnloadInProgress); +} + +/** + * vos_isUnloadInProgress() + * + * Return TRUE if unload is in progress. + * + */ +v_BOOL_t vos_isUnloadInProgress(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return FALSE; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return FALSE; + } + + return (WLAN_HDD_UNLOAD_IN_PROGRESS == pHddCtx->isLoadUnloadInProgress); +} + +/** + *vos_get_rx_wow_dump() + * + * Return true/flase to dump RX packet + * + */ +bool vos_get_rx_wow_dump(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return FALSE; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return FALSE; + } + + return pHddCtx->rx_wow_dump; +} + +/** + *vos_set_rx_wow_dump() - Set RX wow pkt dump + *@value: Value of RX wow pkt dump + * + * Return none. + * + */ +void vos_set_rx_wow_dump(bool value) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + + pHddCtx->rx_wow_dump = value; +} + +/** + * vos_set_hdd_bad_sta() - Set bad link peer sta id + * @sta_id: sta id of the bad peer + * + * Return none. + */ +void vos_set_hdd_bad_sta(uint8_t sta_id) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + + pHddCtx->bad_sta[sta_id] = 1; +} + +/** + * vos_reset_hdd_bad_sta() - Reset the bad peer sta_id + * @sta_id: sta id of the peer + * + * Return none. + */ +void vos_reset_hdd_bad_sta(uint8_t sta_id) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + + pHddCtx->bad_sta[sta_id] = 0; +} + +/** + * vos_probe_threads() - VOS API to post messages + * to all the threads to detect if they are active or not + * + * Return none. + * + */ +void vos_probe_threads(void) +{ + vos_msg_t msg; + + msg.callback = vos_wd_reset_thread_stuck_count; + /* Post Message to MC Thread */ + sysBuildMessageHeader(SYS_MSG_ID_MC_THR_PROBE, &msg); + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SYS, &msg)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Unable to post SYS_MSG_ID_MC_THR_PROBE message to MC thread")); + } + + /* Post Message to Tx Thread */ + sysBuildMessageHeader(SYS_MSG_ID_TX_THR_PROBE, &msg); + if (VOS_STATUS_SUCCESS != vos_tx_mq_serialize(VOS_MQ_ID_SYS, &msg)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Unable to post SYS_MSG_ID_TX_THR_PROBE message to TX thread")); + } + + /* Post Message to Rx Thread */ + sysBuildMessageHeader(SYS_MSG_ID_RX_THR_PROBE, &msg); + if (VOS_STATUS_SUCCESS != vos_rx_mq_serialize(VOS_MQ_ID_SYS, &msg)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Unable to post SYS_MSG_ID_RX_THR_PROBE message to RX thread")); + } +} + +/** + * vos_set_ring_log_level() - Convert HLOS values to driver log levels + * @ring_id: ring_id + * @log_levelvalue: Log level specificed + * + * This function sets the log level of a particular ring + * + * Return: None + */ + void vos_set_ring_log_level(v_U32_t ring_id, v_U32_t log_level) +{ + VosContextType *vos_context; + v_U32_t log_val; + + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_context) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is Invald", __func__); + return; + } + + switch (log_level) { + case LOG_LEVEL_NO_COLLECTION: + log_val = WLAN_LOG_LEVEL_OFF; + break; + case LOG_LEVEL_NORMAL_COLLECT: + log_val = WLAN_LOG_LEVEL_NORMAL; + break; + case LOG_LEVEL_ISSUE_REPRO: + log_val = WLAN_LOG_LEVEL_REPRO; + break; + case LOG_LEVEL_ACTIVE: + default: + log_val = WLAN_LOG_LEVEL_ACTIVE; + break; + } + + if (ring_id == RING_ID_WAKELOCK) { + vos_context->wakelock_log_level = log_val; + return; + } else if (ring_id == RING_ID_CONNECTIVITY) { + vos_context->connectivity_log_level = log_val; + return; + } else if (ring_id == RING_ID_PER_PACKET_STATS) { + vos_context->packet_stats_log_level = log_val; + if (WLAN_LOG_LEVEL_ACTIVE != log_val) + wlan_disable_and_flush_pkt_stats(); + + return; + } +} +/** + * vos_get_ring_log_level() - Get the a ring id's log level + * @ring_id: Ring id + * + * Fetch and return the log level corresponding to a ring id + * + * Return: Log level corresponding to the ring ID + */ +v_U8_t vos_get_ring_log_level(v_U32_t ring_id) +{ + VosContextType *vos_context; + + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_context) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is Invald", __func__); + return WLAN_LOG_LEVEL_OFF; + } + + if (ring_id == RING_ID_WAKELOCK) + return vos_context->wakelock_log_level; + else if (ring_id == RING_ID_CONNECTIVITY) + return vos_context->connectivity_log_level; + else if (ring_id == RING_ID_PER_PACKET_STATS) + return vos_context->packet_stats_log_level; + + return WLAN_LOG_LEVEL_OFF; +} + +/* elements are rate, preamable, bw, short_gi */ +rateidx_to_rate_bw_preamble_sgi rateidx_to_rate_bw_preamble_sgi_table[] = +{ +/*11B CCK Long preamble (0-3)*/ +{ 10, PREAMBLE_CCK, S_BW20, 0},{ 20, PREAMBLE_CCK, S_BW20, 0}, +{ 55, PREAMBLE_CCK, S_BW20, 0},{ 110, PREAMBLE_CCK, S_BW20, 0}, +/*11B CCK Short preamble (4-7)*/ +{ 10, PREAMBLE_CCK, S_BW20, 0},{ 20, PREAMBLE_CCK, S_BW20, 0}, +{ 55, PREAMBLE_CCK, S_BW20, 0},{ 110, PREAMBLE_CCK, S_BW20, 0}, +/*11G/A (8-15)*/ +{ 60, PREAMBLE_OFDM, S_BW20, 0},{ 90, PREAMBLE_OFDM, S_BW20, 0}, +{ 120, PREAMBLE_OFDM, S_BW20, 0},{ 180, PREAMBLE_OFDM, S_BW20, 0}, +{ 240, PREAMBLE_OFDM, S_BW20, 0},{ 360, PREAMBLE_OFDM, S_BW20, 0}, +{ 480, PREAMBLE_OFDM, S_BW20, 0},{ 540, PREAMBLE_OFDM, S_BW20, 0}, +/*HT20 LGI MCS 0-7 (16-23)*/ +{ 65, PREAMBLE_HT, S_BW20, 0},{ 130, PREAMBLE_HT, S_BW20, 0}, +{ 195, PREAMBLE_HT, S_BW20, 0},{ 260, PREAMBLE_HT, S_BW20, 0}, +{ 390, PREAMBLE_HT, S_BW20, 0},{ 520, PREAMBLE_HT, S_BW20, 0}, +{ 585, PREAMBLE_HT, S_BW20, 0},{ 650, PREAMBLE_HT, S_BW20, 0}, +/*HT20 SGI MCS 0-7 (24-31)*/ +{ 72, PREAMBLE_HT, S_BW20, 1},{ 144, PREAMBLE_HT, S_BW20, 1}, +{ 217, PREAMBLE_HT, S_BW20, 1},{ 289, PREAMBLE_HT, S_BW20, 1}, +{ 433, PREAMBLE_HT, S_BW20, 1},{ 578, PREAMBLE_HT, S_BW20, 1}, +{ 650, PREAMBLE_HT, S_BW20, 1},{ 722, PREAMBLE_HT, S_BW20, 1}, +/*HT20 Greenfield MCS 0-7 rates (32-39)*/ +{ 65, PREAMBLE_HT, S_BW20, 0},{ 130, PREAMBLE_HT, S_BW20, 0}, +{ 195, PREAMBLE_HT, S_BW20, 0},{ 260, PREAMBLE_HT, S_BW20, 0}, +{ 390, PREAMBLE_HT, S_BW20, 0},{ 520, PREAMBLE_HT, S_BW20, 0}, +{ 585, PREAMBLE_HT, S_BW20, 0},{ 650, PREAMBLE_HT, S_BW20, 0}, +/*HT40 LGI MCS 0-7 (40-47)*/ +{ 135, PREAMBLE_HT, S_BW40, 0},{ 270, PREAMBLE_HT, S_BW40, 0}, +{ 405, PREAMBLE_HT, S_BW40, 0},{ 540, PREAMBLE_HT, S_BW40, 0}, +{ 810, PREAMBLE_HT, S_BW40, 0},{ 1080, PREAMBLE_HT, S_BW40, 0}, +{ 1215, PREAMBLE_HT, S_BW40, 0},{ 1350, PREAMBLE_HT, S_BW40, 0}, +/*HT40 SGI MCS 0-7 (48-55)*/ +{ 150, PREAMBLE_HT, S_BW40, 1},{ 300, PREAMBLE_HT, S_BW40, 1}, +{ 450, PREAMBLE_HT, S_BW40, 1},{ 600, PREAMBLE_HT, S_BW40, 1}, +{ 900, PREAMBLE_HT, S_BW40, 1},{ 1200, PREAMBLE_HT, S_BW40, 1}, +{ 1350, PREAMBLE_HT, S_BW40, 1},{ 1500, PREAMBLE_HT, S_BW40, 1}, +/*HT40 Greenfield MCS 0-7 rates (56-63) 64-65 are dummy*/ +{ 135, PREAMBLE_HT, S_BW40, 0},{ 270, PREAMBLE_HT, S_BW40, 0}, +{ 405, PREAMBLE_HT, S_BW40, 0},{ 540, PREAMBLE_HT, S_BW40, 0}, +{ 810, PREAMBLE_HT, S_BW40, 0},{ 1080, PREAMBLE_HT, S_BW40, 0}, +{ 1215, PREAMBLE_HT, S_BW40, 0},{ 1350, PREAMBLE_HT, S_BW40, 0}, +/*64-65 are dummy*/ +{ 1350, PREAMBLE_HT, S_BW40, 0},{ 1350, PREAMBLE_HT, S_BW40, 0}, +/*VHT20 LGI MCS 0-9 rates (66-75)*/ +{ 65, PREAMBLE_VHT, S_BW20, 0},{ 130, PREAMBLE_VHT, S_BW20, 0}, +{ 195, PREAMBLE_VHT, S_BW20, 0},{ 260, PREAMBLE_VHT, S_BW20, 0}, +{ 390, PREAMBLE_VHT, S_BW20, 0},{ 520, PREAMBLE_VHT, S_BW20, 0}, +{ 585, PREAMBLE_VHT, S_BW20, 0},{ 650, PREAMBLE_VHT, S_BW20, 0}, +{ 780, PREAMBLE_VHT, S_BW20, 0},{ 865, PREAMBLE_VHT, S_BW20, 0}, +/*76-77 are dummy*/ +{ 865, PREAMBLE_VHT, S_BW20, 0},{ 865, PREAMBLE_VHT, S_BW20, 0}, +/*VHT20 SGI MCS 0-9 rates (78-87)*/ +{ 72, PREAMBLE_VHT, S_BW20, 1},{ 144, PREAMBLE_VHT, S_BW20, 1}, +{ 217, PREAMBLE_VHT, S_BW20, 1},{ 289, PREAMBLE_VHT, S_BW20, 1}, +{ 433, PREAMBLE_VHT, S_BW20, 1},{ 578, PREAMBLE_VHT, S_BW20, 1}, +{ 650, PREAMBLE_VHT, S_BW20, 1},{ 722, PREAMBLE_VHT, S_BW20, 1}, +{ 867, PREAMBLE_VHT, S_BW20, 1},{ 961, PREAMBLE_VHT, S_BW20, 1}, +/*88-89 are dummy*/ +{ 961, PREAMBLE_VHT, S_BW20, 1},{ 961, PREAMBLE_VHT, S_BW20, 1}, +/*VHT40 LGI MCS 0-9 rates (90-101) 98,101 is Dummy*/ +{ 135, PREAMBLE_VHT, S_BW40, 0},{ 270, PREAMBLE_VHT, S_BW40, 0}, +{ 405, PREAMBLE_VHT, S_BW40, 0},{ 540, PREAMBLE_VHT, S_BW40, 0}, +{ 810, PREAMBLE_VHT, S_BW40, 0},{ 1080, PREAMBLE_VHT, S_BW40, 0}, +{ 1215, PREAMBLE_VHT, S_BW40, 0},{ 1350, PREAMBLE_VHT, S_BW40, 0}, +{ 1350, PREAMBLE_VHT, S_BW40, 0},{ 1620, PREAMBLE_VHT, S_BW40, 0}, +{ 1800, PREAMBLE_VHT, S_BW40, 0},{ 1800, PREAMBLE_VHT, S_BW40, 0}, +/*VHT40 SGI MCS 0-9 rates (102-112) 110, 113 is Dummy*/ +{ 150, PREAMBLE_VHT, S_BW40, 1},{ 300, PREAMBLE_VHT, S_BW40, 1}, +{ 450, PREAMBLE_VHT, S_BW40, 1},{ 600, PREAMBLE_VHT, S_BW40, 1}, +{ 900, PREAMBLE_VHT, S_BW40, 1},{ 1200, PREAMBLE_VHT, S_BW40, 1}, +{ 1350, PREAMBLE_VHT, S_BW40, 1},{ 1500, PREAMBLE_VHT, S_BW40, 1}, +{ 1500, PREAMBLE_VHT, S_BW40, 1},{ 1800, PREAMBLE_VHT, S_BW40, 1}, +{ 2000, PREAMBLE_VHT, S_BW40, 1},{ 2000, PREAMBLE_VHT, S_BW40, 1}, +/*VHT80 LGI MCS 0-9 rates (114-125) 122, 125 is Dummy*/ +{ 293, PREAMBLE_VHT, S_BW80, 0},{ 585, PREAMBLE_VHT, S_BW80, 0}, +{ 878, PREAMBLE_VHT, S_BW80, 0},{ 1170, PREAMBLE_VHT, S_BW80, 0}, +{ 1755, PREAMBLE_VHT, S_BW80, 0},{ 2340, PREAMBLE_VHT, S_BW80, 0}, +{ 2633, PREAMBLE_VHT, S_BW80, 0},{ 2925, PREAMBLE_VHT, S_BW80, 0}, +{ 2925, PREAMBLE_VHT, S_BW80, 0},{ 3510, PREAMBLE_VHT, S_BW80, 0}, +{ 3900, PREAMBLE_VHT, S_BW80, 0},{ 3900, PREAMBLE_VHT, S_BW80, 0}, +/*VHT80 SGI MCS 0-9 rates (126-136) 134 is Dummy*/ +{ 325, PREAMBLE_VHT, S_BW80, 1},{ 650, PREAMBLE_VHT, S_BW80, 1}, +{ 975, PREAMBLE_VHT, S_BW80, 1},{ 1300, PREAMBLE_VHT, S_BW80, 1}, +{ 1950, PREAMBLE_VHT, S_BW80, 1},{ 2600, PREAMBLE_VHT, S_BW80, 1}, +{ 2925, PREAMBLE_VHT, S_BW80, 1},{ 3250, PREAMBLE_VHT, S_BW80, 1}, +{ 3250, PREAMBLE_VHT, S_BW80, 1},{ 3900, PREAMBLE_VHT, S_BW80, 1}, +{ 4333, PREAMBLE_VHT, S_BW80, 1}, +}; + +void get_rate_and_MCS(per_packet_stats *stats, uint32 rateindex) +{ + rateidx_to_rate_bw_preamble_sgi *ratetbl; + + if (STATS_MAX_RATE_INDEX < rateindex) + rateindex = STATS_MAX_RATE_INDEX; + ratetbl= &rateidx_to_rate_bw_preamble_sgi_table[rateindex]; + stats->last_transmit_rate = ratetbl->rate/5; + stats->MCS.nss = 0; + if (0 <= rateindex && rateindex <= 7) + stats->MCS.rate = 7 - rateindex; + else if (8 <= rateindex && rateindex <= 15) + { + switch(rateindex) + { + case 8:stats->MCS.rate = 3; break; + case 9:stats->MCS.rate = 7; break; + case 10:stats->MCS.rate = 2; break; + case 11:stats->MCS.rate = 6; break; + case 12:stats->MCS.rate = 1; break; + case 13:stats->MCS.rate = 5; break; + case 14:stats->MCS.rate = 0; break; + case 15:stats->MCS.rate = 4; break; + } + } + else if(16 <= rateindex && rateindex <= 23) + stats->MCS.rate = rateindex - 16; + else if(24 <= rateindex && rateindex <= 31) + stats->MCS.rate = rateindex - 24; + else if(32 <= rateindex && rateindex <= 39) + stats->MCS.rate = rateindex - 32; + else if(40 <= rateindex && rateindex <= 47) + stats->MCS.rate = rateindex - 40; + else if(48 <= rateindex && rateindex <= 55) + stats->MCS.rate = rateindex - 48; + else if(56 <= rateindex && rateindex <= 63) + stats->MCS.rate = rateindex - 56; + else if(66 <= rateindex && rateindex <= 75) + stats->MCS.rate = rateindex - 66; + else if(78 <= rateindex && rateindex <= 87) + stats->MCS.rate = rateindex - 78; + else if(90 <= rateindex && rateindex <= 100) + stats->MCS.rate = rateindex - 90; + else if(78 <= rateindex && rateindex <= 87) + stats->MCS.rate = rateindex - 78; + else if(90 <= rateindex && rateindex <= 97) + stats->MCS.rate = rateindex - 90; + else if(99 <= rateindex && rateindex <= 100) + stats->MCS.rate = rateindex - 91; + else if(102 <= rateindex && rateindex <= 109) + stats->MCS.rate = rateindex - 102; + else if(111 <= rateindex && rateindex <= 112) + stats->MCS.rate = rateindex - 103; + else if(114 <= rateindex && rateindex <= 121) + stats->MCS.rate = rateindex - 114; + else if(123 <= rateindex && rateindex <= 124) + stats->MCS.rate = rateindex - 115; + else if(126 <= rateindex && rateindex <= 133) + stats->MCS.rate = rateindex - 126; + else if(135 <= rateindex && rateindex <= 136) + stats->MCS.rate = rateindex - 127; + else /*Invalid rate index mark it 0*/ + stats->MCS.rate = 0; + stats->MCS.preamble = ratetbl->preamble; + stats->MCS.bw = ratetbl->bw; + stats->MCS.short_gi = ratetbl->short_gi; +} + +bool vos_isPktStatsEnabled(void) +{ + bool value; + value = wlan_isPktStatsEnabled(); + return (value); +} + +bool vos_is_wlan_logging_enabled(void) +{ + v_CONTEXT_t vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + hdd_context_t *hdd_ctx; + + if(!vos_ctx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return false; + } + + hdd_ctx = vos_get_context(VOS_MODULE_ID_HDD, vos_ctx); + + if(!hdd_ctx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null", __func__); + return false; + } + + if (!hdd_ctx->cfg_ini->wlanLoggingEnable) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Logging framework not enabled!", __func__); + return false; + } + + return true; +} + +/**--------------------------------------------------------------------------- + + \brief vos_is_probe_rsp_offload_enabled - + + API to check if probe response offload feature is enabled from ini + + \param - None + + \return - 0: probe response offload is disabled + 1: probe response offload is enabled + + --------------------------------------------------------------------------*/ +v_BOOL_t vos_is_probe_rsp_offload_enabled(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return FALSE; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, + pVosContext); + if (!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return FALSE; + } + + return pHddCtx->cfg_ini->sap_probe_resp_offload; +} + + +/** + * vos_set_snoc_high_freq_voting() - enable/disable high freq voting + * @enable: true if need to be enabled + * + * enable/disable high freq voting + * + * Return: Void + */ +#ifdef HAVE_WCNSS_SNOC_HIGH_FREQ_VOTING +void vos_set_snoc_high_freq_voting(bool enable) +{ + VosContextType *vos_ctx = NULL; + + /* Get the Global VOSS Context */ + vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (!vos_ctx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is NULL", __func__); + return; + } + + spin_lock(&vos_ctx->freq_voting_lock); + if (vos_ctx->snoc_high_freq_voting != enable) + { + vos_ctx->snoc_high_freq_voting = enable; + spin_unlock(&vos_ctx->freq_voting_lock); + wcnss_snoc_vote(enable); + return; + } + spin_unlock(&vos_ctx->freq_voting_lock); +} +#else +void vos_set_snoc_high_freq_voting(bool enable) +{ + return; +} +#endif + +void vos_smd_dump_stats(void) +{ + WCTS_Dump_Smd_status(); +} + +void vos_log_wdi_event(uint16 msg, vos_wdi_trace_event_type event) +{ + + if (gvos_wdi_msg_trace_index >= VOS_TRACE_INDEX_MAX) + { + gvos_wdi_msg_trace_index = 0; + } + + gvos_wdi_msg_trace[gvos_wdi_msg_trace_index].event = event; + gvos_wdi_msg_trace[gvos_wdi_msg_trace_index].time = + vos_get_monotonic_boottime(); + gvos_wdi_msg_trace[gvos_wdi_msg_trace_index].message = msg; + gvos_wdi_msg_trace_index++; + + return; +} + +void vos_dump_wdi_events(void) +{ + int i; + + for(i = 0; i < VOS_TRACE_INDEX_MAX; i++) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s:event:%d time:%lld msg:%d ",__func__, + gvos_wdi_msg_trace[i].event, + gvos_wdi_msg_trace[i].time, + gvos_wdi_msg_trace[i].message); + } +} + +/** + * vos_check_arp_target_ip() - check if the Target IP is gateway IP + * @pPacket: pointer to vos packet + * + * Return: true if the IP is of gateway or false otherwise + */ +bool vos_check_arp_target_ip(vos_pkt_t *pPacket) +{ + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + hdd_context_t *pHddCtx = NULL; + struct sk_buff *skb; + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return false; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return false; + } + + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: NULL pointer", __func__); + return false; + } + + if ( VOS_STATUS_SUCCESS != + vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE )) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: OS PKT pointer is NULL", __func__); + return false; + } + + if (pHddCtx->track_arp_ip == + (v_U32_t)(*(v_U32_t *)(skb->data + VOS_ARP_TARGET_IP_OFFSET))) + return true; + + return false; +} + +/** + * vos_update_arp_fw_tx_delivered() - update the ARP stats host to FW deliver + * count + * + * Return: None + */ +void vos_update_arp_fw_tx_delivered(void) +{ + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t * pAdapter; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + uint8_t status; + + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && 0 == status) + { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + break; + + status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + pAdapter->hdd_stats.hddArpStats.tx_host_fw_sent++; +} + +/** + * vos_update_arp_rx_drop_reorder() - update the RX ARP stats drop due + * reorder logic at host + * + * Return: None + */ +void vos_update_arp_rx_drop_reorder(void) +{ + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + hdd_context_t *pHddCtx = NULL; + hdd_adapter_t * pAdapter; + hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL; + uint8_t status; + + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return; + } + + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: HDD context is Null", __func__); + return; + } + + status = hdd_get_front_adapter(pHddCtx, &pAdapterNode); + + while (NULL != pAdapterNode && 0 == status) + { + pAdapter = pAdapterNode->pAdapter; + if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) + break; + + status = hdd_get_next_adapter (pHddCtx, pAdapterNode, &pNext); + pAdapterNode = pNext; + } + + pAdapter->hdd_stats.hddArpStats.rx_host_drop_reorder++; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_diag.c b/drivers/staging/prima/CORE/VOSS/src/vos_diag.c new file mode 100644 index 000000000000..dbc2a5cae21f --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_diag.c @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + FILE: vos_diag.c + + OVERVIEW: This source file contains definitions for vOS diag APIs + + DEPENDENCIES: +============================================================================*/ + +#include "vos_types.h" +#include "i_vos_diag_core_log.h" +#include "i_vos_diag_core_event.h" +#include "wlan_hdd_main.h" +#include "wlan_nlink_common.h" +#include "vos_sched.h" +#include "wlan_ptt_sock_svc.h" +#include "wlan_nlink_srv.h" + + +#define PTT_MSG_DIAG_CMDS_TYPE 0x5050 + +#define DIAG_TYPE_LOGS 1 +#define DIAG_TYPE_EVENTS 2 + +#define DIAG_SWAP16(A) ((((tANI_U16)(A) & 0xff00) >> 8) | (((tANI_U16)(A) & 0x00ff) << 8)) + + + +typedef struct event_report_s +{ + v_U32_t diag_type; + v_U16_t event_id; + v_U16_t length; +} event_report_t; + + +/**--------------------------------------------------------------------------- + + \brief vos_log_set_code() - + + This function sets the logging code in the given log record. + + \param - ptr - Pointer to the log header type. + - code - log code. + \return - None + + --------------------------------------------------------------------------*/ + +void vos_log_set_code (v_VOID_t *ptr, v_U16_t code) +{ + if (ptr) + { + /* All log packets are required to start with 'log_header_type'. */ + ((log_hdr_type *) ptr)->code = code; + } + +} + +/**--------------------------------------------------------------------------- + + \brief vos_log_set_length() - + + This function sets the length field in the given log record. + + \param - ptr - Pointer to the log header type. + - length - log length. + + \return - None + + --------------------------------------------------------------------------*/ + +void vos_log_set_length (v_VOID_t *ptr, v_U16_t length) +{ + if(ptr) + { + /* All log packets are required to start with 'log_header_type'. */ + ((log_hdr_type *) ptr)->len = (v_U16_t) length; + } +} + +/**--------------------------------------------------------------------------- + + \brief vos_log_submit() - + + This function sends the log data to the ptt socket app only if it is registered with the driver. + + \param - ptr - Pointer to the log header type. + + \return - None + + --------------------------------------------------------------------------*/ + +void vos_log_submit(v_VOID_t *plog_hdr_ptr) +{ + + log_hdr_type *pHdr = (log_hdr_type*) plog_hdr_ptr; + + tAniHdr *wmsg = NULL; + v_U8_t *pBuf; + struct hdd_context_s *pHddCtx; + v_CONTEXT_t pVosContext= NULL; + v_U16_t data_len; + v_U16_t total_len; + + + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + /*Get the Hdd Context */ + pHddCtx = ((VosContextType*)(pVosContext))->pHDDContext; + + if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Unloading/Loading in Progress. Ignore!!!", __func__); + return; + } + + if (nl_srv_is_initialized() != 0) + return; + +#ifdef WLAN_KD_READY_NOTIFIER + /* NL is not ready yet, WLAN KO started first */ + if ((pHddCtx->kd_nl_init) && (!pHddCtx->ptt_pid)) + { + nl_srv_nl_ready_indication(); + } +#endif /* WLAN_KD_READY_NOTIFIER */ + + /* Send the log data to the ptt app only if it is registered with the wlan driver*/ + if(vos_is_multicast_logging()) + { + data_len = pHdr->len; + + total_len = sizeof(tAniHdr)+sizeof(v_U32_t)+data_len; + + pBuf = (v_U8_t*)vos_mem_malloc(total_len); + + if(!pBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "vos_mem_malloc failed"); + return; + } + + vos_mem_zero((v_VOID_t*)pBuf,total_len); + + wmsg = (tAniHdr*)pBuf; + wmsg->type = PTT_MSG_DIAG_CMDS_TYPE; + wmsg->length = total_len; + wmsg->length = DIAG_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + + /* Diag Type events or log */ + *(v_U32_t*)pBuf = DIAG_TYPE_LOGS; + pBuf += sizeof(v_U32_t); + + + vos_mem_copy(pBuf, pHdr,data_len); + + if (ptt_sock_send_msg_to_app(wmsg, 0, + ANI_NL_MSG_PUMAC, INVALID_PID, MSG_DONTWAIT) < 0) + { + vos_mem_free((v_VOID_t *)wmsg); + return; + } + + vos_mem_free((v_VOID_t*)wmsg); + } + return; +} + +/** + * vos_log_wlock_diag() - This function is used to send wake lock diag events + * @reason: Reason why the wakelock was taken or released + * @wake_lock_name: Function in which the wakelock was taken or released + * @timeout: Timeout value in case of timed wakelocks + * @status: Status field indicating whether the wake lock was taken/released + * + * This function is used to send wake lock diag events to user space + * + * Return: None + * + */ +void vos_log_wlock_diag(uint32_t reason, const char *wake_lock_name, + uint32_t timeout, uint32_t status) +{ + VosContextType *vos_context; + WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, + struct vos_event_wlan_wake_lock); + + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!vos_context) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "vos context is Invald"); + return; + } + if (nl_srv_is_initialized() != 0 || + vos_context->wakelock_log_level == WLAN_LOG_LEVEL_OFF) + return; + + wlan_diag_event.status = status; + wlan_diag_event.reason = reason; + wlan_diag_event.timeout = timeout; + wlan_diag_event.name_len = strlen(wake_lock_name); + strlcpy(&wlan_diag_event.name[0], + wake_lock_name, + wlan_diag_event.name_len+1); + + WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_WAKE_LOCK); +} + + +/**--------------------------------------------------------------------------- + + \brief vos_event_report_payload() - + + This function sends the event data to the ptt socket app only if it is registered with the driver. + + \param - ptr - Pointer to the log header type. + + \return - None + + --------------------------------------------------------------------------*/ + +void vos_event_report_payload(v_U16_t event_Id, v_U16_t length, v_VOID_t *pPayload) +{ + + + tAniHdr *wmsg = NULL; + v_U8_t *pBuf; + struct hdd_context_s *pHddCtx; + v_CONTEXT_t pVosContext= NULL; + event_report_t *pEvent_report; + v_U16_t total_len; + + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vos context is NULL", __func__); + return; + } + + /*Get the Hdd Context */ + pHddCtx = ((VosContextType*)(pVosContext))->pHDDContext; + if (!pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: hdd context is NULL", __func__); + return; + } + + if (nl_srv_is_initialized() != 0) + return; + +#ifdef WLAN_KD_READY_NOTIFIER + /* NL is not ready yet, WLAN KO started first */ + if ((pHddCtx->kd_nl_init) && (!pHddCtx->ptt_pid)) + { + nl_srv_nl_ready_indication(); + } +#endif /* WLAN_KD_READY_NOTIFIER */ + + /* Send the log data to the ptt app only if it is registered with the wlan driver*/ + if(vos_is_multicast_logging()) + { + total_len = sizeof(tAniHdr)+sizeof(event_report_t)+length; + + pBuf = (v_U8_t*)vos_mem_malloc(total_len); + + if(!pBuf) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "vos_mem_malloc failed"); + return; + } + wmsg = (tAniHdr*)pBuf; + wmsg->type = PTT_MSG_DIAG_CMDS_TYPE; + wmsg->length = total_len; + wmsg->length = DIAG_SWAP16(wmsg->length); + pBuf += sizeof(tAniHdr); + + pEvent_report = (event_report_t*)pBuf; + pEvent_report->diag_type = DIAG_TYPE_EVENTS; + pEvent_report->event_id = event_Id; + pEvent_report->length = length; + + pBuf += sizeof(event_report_t); + + vos_mem_copy(pBuf, pPayload,length); + + if( ptt_sock_send_msg_to_app(wmsg, 0, + ANI_NL_MSG_PUMAC, INVALID_PID, MSG_DONTWAIT) < 0) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, + ("Ptt Socket error sending message to the app!!")); + vos_mem_free((v_VOID_t*)wmsg); + return; + } + + vos_mem_free((v_VOID_t*)wmsg); + } + + return; + +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_event.c b/drivers/staging/prima/CORE/VOSS/src/vos_event.c new file mode 100644 index 000000000000..505455e23798 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_event.c @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + FILE: vos_event.c + + OVERVIEW: This source file contains definitions for vOS event APIs + The five APIs mentioned in this file are used for + initializing, setting, resetting, destroying an event and + waiting on an occurance of an event among multiple events. + + DEPENDENCIES: + +============================================================================*/ + +/*============================================================================ + EDIT HISTORY FOR MODULE + +============================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_event.h" +#include "vos_trace.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + + \brief vos_event_init() - initializes a vOSS event + + The vos_event_init() function initializes the specified event. Upon + successful initialization, the state of the event becomes initialized + and not signaled. + + An event must be initialized before it may be used in any other event + functions. + + Attempting to initialize an already initialized event results in + a failure. + + \param lock - pointer to the opaque event object to initialize + + \return VOS_STATUS_SUCCESS - event was successfully initialized and + is ready to be used. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by event, a previously + initialized, but not yet destroyed, event. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be created due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the event + + ***VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the event + + \sa + + ( *** indicates return values do NOT exist yet ) + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_init ( vos_event_t* event ) +{ + + // Check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check for 'already initialized' event + if ( LINUX_EVENT_COOKIE == event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Initialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_BUSY; + } + + // initialize new event + init_completion(&event->complete); + event->cookie = LINUX_EVENT_COOKIE; + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_event_set() - sets a vOSS event + + The state of the specified event is set to 'signalled by calling + \a vos_event_set(). + + Any threads waiting on the event as a result of a vos_event_wait() will + be unblocked and available to be scheduled for execution when the event + is signaled by a call to \a vos_event_set(). + + \param event - the event to set to the signalled state + + \return VOS_STATUS_SUCCESS - the event was successfully signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be signaled due to + unknown reasons + + \sa + + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_event_set ( vos_event_t* event ) +{ + + // Check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check if event refers to an initialized object + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + complete(&event->complete); + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_event_reset() - resets a vOSS event - This function isn't required + for Linux. Therefore, it doesn't do much. + + The state of the specified event is set to 'NOT signalled' by calling + \a vos_event_reset(). The state of the event remains NOT signalled until an + explicit call to vos_event_set(). + + This function sets the event to a NOT signalled state even if the event was + signalled multiple times before being signaled. + + \param event - the event to set to the NOT signalled state + + \return VOS_STATUS_SUCCESS - the event state was successfully change to + NOT signalled. + + VOS_STATUS_E_INVAL - The value specified by event does not refer + to an initialized event object. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be signaled due to + unknown reasons + + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_event_reset ( vos_event_t* event ) +{ + + // check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check to make sure it is an 'already initialized' event + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // (re)initialize event + INIT_COMPLETION(event->complete); + return VOS_STATUS_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_wait_events() - Waits for the first event(s) to be set. + + This API waits for any event in the input array of events to be + set. The caller is blocked waiting any event in the array to be + set or for the timeout to occur. + + If multiple events in the array are set, only one event is identified + in the return from this call as satisfying the wait condition. The + caller is responsible for calling \a vos_wait_events() again to find + the other events that are set. + + \param events - pointer to an array of events to wait on. + + \param numEvents - Number of events in the events array to wait on. + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \param pEventIndex - This is a pointer to the location where the index of + the event in the event array that satisfied the wait because + the event was set. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by one of the events + in the event array being set. The index into the event arry + that satisfied the wait can be found at *pEventIndex. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before any of + the events were set. + + VOS_STATUS_E_INVAL - At least one of the values specified in the + event array refers to an uninitialized event object. + + VOS_STATUS_E_ABORTED - The event due to which the wait was aborted + is identified by the index in *pEventIndex. + + VOS_STATUS_E_EMPTY - the events array is empty. This condition + is detected by numEvents being 0 on input. + + VOS_STATUS_E_FAULT - event or pEventIndex is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + \sa + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_events ( vos_event_t* events, + v_U8_t numEvents, v_U32_t timeout, + v_U8_t *pEventIndex ) +{ + + return vos_wait_single_event(events,timeout); +} + +/*-------------------------------------------------------------------------- + + \brief vos_event_destroy() - Destroys a vOSS event - This function doesn't do + much in Linux. There is no need for the caller to explicitly destroy an event + after use. + + The os_event_destroy() function shall destroy the event object + referenced by event. After a successful return from \a vos_event_destroy() + the event object becomes, in effect, uninitialized. + + A destroyed event object can be reinitialized using vos_event_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS event functions to manipulate the lock such + as vos_event_set() will fail if the event is destroyed. Therefore, + don't use the event after it has been destroyed until it has + been re-initialized. + + \param event - the event object to be destroyed. + + \return VOS_STATUS_SUCCESS - event was successfully destroyed. + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - event is an invalid pointer. + + VOS_STATUS_E_FAILURE - event could not be signaled due to + unknown reasons + + ***VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by event while it is still being + referenced (there are threads waiting on this event) + \sa + + ( *** indicates return values do NOT exist yet ) + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_event_destroy ( vos_event_t* event ) +{ + // check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check to make sure it is an 'already initialized' event + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // make sure nobody is waiting on the event + complete_all(&event->complete); + + // destroy the event + memset(event, 0, sizeof(vos_event_t)); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_wait_single_event() - Waits for a single event to be set. + + This API waits for the event to be set. + + \param pEvent - pointer to an event to wait on. + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by the event being + set. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before the + event was set. + + VOS_STATUS_E_INVAL - The value specified by event is invalid. + + VOS_STATUS_E_FAULT - pEvent is an invalid pointer. + + \sa vos_wait_multiple_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_single_event ( vos_event_t* event, v_U32_t timeout) +{ + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s cannot be called from interrupt context!!!", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check for null pointer + if ( NULL == event ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "NULL event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // check if cookie is same as that of initialized event + if ( LINUX_EVENT_COOKIE != event->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Uninitialized event passed into %s", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if (timeout) + { + long ret; + ret = + wait_for_completion_timeout(&event->complete, + msecs_to_jiffies(timeout)); + if ( 0 >= ret ) + { + return VOS_STATUS_E_TIMEOUT; + } + } + else + { + int ret; + ret = wait_for_completion_interruptible(&event->complete); + if ( 0 != ret ) + { + // negative means interrupted + return VOS_STATUS_E_TIMEOUT; + } + } + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_wait_multiple_events() - Waits for event(s) to be set. + This is a duplicate of vos_wait_events() function. It ends up calling + vos_wait_events() with the params passed in. + + This API waits for any event in the input array of events to be + set. The caller is blocked waiting any event in the array to be + set or for the timeout to occur. + + If multiple events in the array are set, only one event is identified + in the return from this call as satisfying the wait condition. The + caller is responsible for calling \a vos_wait_events() again to find + the other events that are set. + + \param pEventList - pointer to an array of event pointers + + \param numEvents - Number of events + + \param timeout - Timeout value (in milliseconds). This function returns + if this interval elapses, regardless if any of the events have + been set. An input value of 0 for this timeout parameter means + to wait infinitely, meaning a timeout will never occur. + + \param pEventIndex - This is a pointer to the location where the index of + the event in the event array that satisfied the wait because + the event was set. + + \return VOS_STATUS_SUCCESS - the wait was satisifed by one of the events + in the event array being set. The index into the event arry + that satisfied the wait can be found at *pEventIndex. + + VOS_STATUS_E_TIMEOUT - the timeout interval elapsed before any of + the events were set. + + VOS_STATUS_E_INVAL - At least one of the values specified in the + event array refers to an uninitialized event object. The invalid + event is identified by the index in *pEventIndex. Note that only + the first uninitialized event is detected when this error is + returned. + + VOS_STATUS_E_EMPTY - the events array is empty. This condition + is detected by numEvents being 0 on input. + + VOS_STATUS_E_FAULT - event or pEventIndex is an invalid pointer. + + \sa vos_wait_single_events() + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wait_multiple_events( vos_event_t **events, v_U8_t numEvents, + v_U32_t timeout, v_U8_t *pEventIndex ) +{ + // NO LONGER SUPPORTED + return VOS_STATUS_E_FAILURE; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_getBin.c b/drivers/staging/prima/CORE/VOSS/src/vos_getBin.c new file mode 100644 index 000000000000..38d9ac4ffc48 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_getBin.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/* $HEADER$ */ +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include +#include // for softmac direct file i/o +#include +#include +#include +#include +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ +extern tVOS_CONCURRENCY_MODE hdd_get_concurrency_mode ( void ); + +/**----------------------------------------------------------------------------- + Function declarations and documenation + ----------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + \brief vos_get_binary_blob() - get binary data from platform + This API allows components to get binary data from the platform independent + of where the data is stored on the device. +
    +
  • Firmware +
  • Configuration Data + \param binaryId - identifies the binary data to return to the caller. + raw binary data and update the *pBufferSize with the exact + size of the data that has been retreived. + the size of the binary data in *pBufferSize. + size of the data buffer available at pBuffer. Upon success, this + retreived and written to the buffer at pBuffer. + Input value of 0 is valid and will cause the API to return + the size of the binary data in *pBufferSize. + retreived and written to the buffer. + refer to a valid VOS Binary ID. + variable that the API can write to. + *pBufferSize is not big enough to contain the binary. + \sa + --------------------------------------------------------------------------*/ +VOS_STATUS vos_get_binary_blob( VOS_BINARY_ID binaryId, + v_VOID_t *pBuffer, v_SIZE_t *pBufferSize ) +{ + VOS_STATUS VosSts = VOS_STATUS_SUCCESS; + char *pFileName; + + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL); + + // get the correct file name from binary Id + switch (binaryId) + { + case VOS_BINARY_ID_CONFIG: + pFileName = WLAN_CFG_FILE; + break; + case VOS_BINARY_ID_COUNTRY_INFO: + pFileName = WLAN_COUNTRY_INFO_FILE; + break; + case VOS_BINARY_ID_HO_CONFIG: + pFileName = WLAN_HO_CFG_FILE; + break; + case VOS_BINARY_ID_DICT_CONFIG: + pFileName = WLAN_DICT_FILE; + break; + default: + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Invalid binaryID"); + return VosSts; + } + if(0 == *pBufferSize ) + { + /* just a file size request. set the value and return VOS_STATUS_E_NOMEM*/ + VosSts = hdd_get_cfg_file_size(((VosContextType*)(pVosContext))->pHDDContext,pFileName,pBufferSize); + + if ( !VOS_IS_STATUS_SUCCESS( VosSts )) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : vos_open failed",__func__); + + return VOS_STATUS_E_FAILURE; + } + VosSts = VOS_STATUS_E_NOMEM; + } + else + { + if(NULL != pBuffer) { + // read the contents into the buffer + VosSts = hdd_read_cfg_file(((VosContextType*)(pVosContext))->pHDDContext,pFileName,pBuffer,pBufferSize); + } + else { + VosSts = VOS_STATUS_E_FAILURE; + } + } + + return VosSts; +} + + +tVOS_CON_MODE vos_get_conparam( void ) +{ + tVOS_CON_MODE con_mode; + con_mode = hdd_get_conparam ( ); + return con_mode; +} +tVOS_CONCURRENCY_MODE vos_get_concurrency_mode( void ) +{ + tVOS_CONCURRENCY_MODE con_mode; + con_mode = hdd_get_concurrency_mode ( ); + return con_mode; +} + +v_BOOL_t vos_concurrent_open_sessions_running(void) +{ + v_U8_t i=0; + v_U8_t j=0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + for (i=0; i < VOS_MAX_NO_OF_MODE; i++) + { + j += pHddCtx->no_of_open_sessions[i]; + } + } + } + + return (j>1); +} + +/**--------------------------------------------------------------------------- + * + * \brief vos_max_concurrent_connections_reached() + * + * This function checks for presence of concurrency where more than + * one connection exists and it returns TRUE if the max concurrency is + * reached. + * + * Example: + * STA + STA (wlan0 and wlan1 are connected) - returns TRUE + * STA + STA (wlan0 connected and wlan1 disconnected) - returns FALSE + * DUT with P2P-GO + P2P-CLIENT connection) - returns TRUE + * + * \param - None + * + * \return - VOS_TRUE or VOS_FALSE + * + * --------------------------------------------------------------------------*/ +v_BOOL_t vos_max_concurrent_connections_reached (void) +{ + v_U8_t i = 0, j = 0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + + if (NULL != pVosContext) { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) { + for (i = 0; i < VOS_MAX_NO_OF_MODE; i++) + j += pHddCtx->no_of_active_sessions[i]; + + return (j > (pHddCtx->cfg_ini->gMaxConcurrentActiveSessions - 1)); + } + } + + return VOS_FALSE; +} + diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_list.c b/drivers/staging/prima/CORE/VOSS/src/vos_list.c new file mode 100644 index 000000000000..66fbda7d7fbc --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_list.c @@ -0,0 +1,932 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**============================================================================= + + vos_list.c + + \brief + + Description... + + + + ==============================================================================**/ +/* $HEADER$ */ + +/**----------------------------------------------------------------------------- + Include files + ----------------------------------------------------------------------------*/ +#include +#include + +/**----------------------------------------------------------------------------- + Preprocessor definitions and constants + ----------------------------------------------------------------------------*/ +#define VOS_LIST_COOKIE 0xabadfeed + + +/**----------------------------------------------------------------------------- + Type declarations + ----------------------------------------------------------------------------*/ + +/**----------------------------------------------------------------------------- + Function declarations and documenation + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_list_init( vos_list_t *pList ) +{ + if ( pList == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie == VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: already initialized list", __func__); + return VOS_STATUS_E_BUSY; + } + + mutex_init(&pList->lock); + + INIT_LIST_HEAD( &pList->anchor ); + + pList->count = 0; + pList->cookie = VOS_LIST_COOKIE; + + return( VOS_STATUS_SUCCESS ); +} + + +VOS_STATUS vos_list_destroy( vos_list_t *pList ) +{ + int rc; + if (pList == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->count !=0 ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list length not equal to zero", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_BUSY; + } + + // clear the cookie. This indicates the list is destroyed. + pList->cookie = 0; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_list_insert_front( vos_list_t *pList, vos_list_node_t *pNode ) +{ + int rc; + + if ( ( pList == NULL) || ( pNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + list_add( pNode, &pList->anchor ); + + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_list_insert_back( vos_list_t *pList, vos_list_node_t *pNode ) +{ + int rc; + + if ( ( pList == NULL) || ( pNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + list_add_tail( pNode, &pList->anchor ); + + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_list_insert_back_size( vos_list_t *pList, vos_list_node_t *pNode, v_SIZE_t *pSize ) +{ + int rc; + if ( ( pList == NULL) || ( pNode == NULL) || (pSize == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + list_add_tail( pNode, &pList->anchor ); + + pList->count++; + *pSize = pList->count; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_list_remove_front( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + // the assumption here is that pList is the head of the list (dummy + // node) and points to first and last element in circular linked list + if ( ( pList == NULL ) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty( &pList->anchor ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.next; + + *ppNode = listptr; + + list_del(pList->anchor.next); + + pList->count--; + mutex_unlock(&pList->lock); + return VOS_STATUS_SUCCESS; +} + + + +VOS_STATUS vos_list_remove_back( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + // the assumption here is that pList is the head of the list (dummy node) and points to first and + // last element in circular linked list + if ( ( pList == NULL ) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty( &pList->anchor ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + listptr = pList->anchor.prev; + + *ppNode = listptr; + + list_del(pList->anchor.prev); + + pList->count--; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_list_size( vos_list_t *pList, v_SIZE_t *pSize ) +{ + int rc; + if ( ( pList ==NULL) || ( pSize == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + *pSize = pList->count; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_front() - peek at the node at front of a linked list + + The vos_list_peek_front() API will return a pointer to the node at the + front of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the front of the list. + + \return VOS_STATUS_SUCCESS - list node at the front of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_front( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + if ( ( pList == NULL) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + listptr = pList->anchor.next; + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_back() - peek at the node at back of a linked list + + The vos_list_peek_back() API will return a pointer to the node at the + back of a properly initialized vOS List object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the back of the list. + + \return VOS_STATUS_SUCCESS - list node at the back of the list was + successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + VOS_STATUS_E_FAULT - pList or or ppNode is an invalid pointer. + + \sa vos_list_peek_back(), vos_list_remove_back(), vos_list_peek_front(), + vos_list_remove_front() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_back( vos_list_t *pList, vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc; + + if ( ( pList == NULL) || ( ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + listptr = pList->anchor.prev; + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_next() - peek at the node after the specified node + + The vos_list_peek_next() API will return a pointer to the node following the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node that follows the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node following pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - There is no 'next' node (the input node is + at the back of the list). + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_next( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + listptr = pNode->next; + if (listptr == &pList->anchor) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_peek_prev() - peek at the node before the specified node + + The vos_list_peek_prev() API will return a pointer to the node before the + specified node on a properly initialized vOS List object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node before the + pNode node on the list. + + \return VOS_STATUS_SUCCESS - list node before pNode on the properly + initialized list is successfully returned. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - There is no 'previous' node (the input node is + at the front of the list). + + VOS_STATUS_E_FAULT - pList, pNode or ppNode is an invalid pointer. + + \sa vos_list_remove_back() + + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_list_peek_prev( vos_list_t *pList, vos_list_node_t *pNode, + vos_list_node_t **ppNode ) +{ + struct list_head * listptr; + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (ppNode == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + listptr = pNode->prev; + + if (listptr == &pList->anchor) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + *ppNode = listptr; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_insert_before() - insert node at front of a specified + list node + + The vos_list_insert_before() API will insert a node onto a properly + initialized vOS List object in front of the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + in front of. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_before( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ) +{ + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (pNodeToInsert == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_add(pNodeToInsert, pNode); + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_list_insert_after() - insert node behind a specified list node + + The vos_list_insert_after() API will insert a node onto a properly + initialized vOS List object after the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + after. + + \return VOS_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_FAULT - pList, pNodeToInsert, or pNode are + invalid pointer(s) + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_insert_after( vos_list_t *pList, vos_list_node_t *pNodeToInsert, + vos_list_node_t *pNode ) +{ + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL) || ( pNode == NULL) || (pNodeToInsert == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNode is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNode) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_add_tail(pNodeToInsert, pNode); + pList->count++; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} + +/*---------------------------------------------------------------------------- + + \brief vos_list_remove_node() - remove specified node from vOS list list + + The vos_list_remove_node() API will remove a specified node from the + properly initialized vOS List object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to the node to be removed from the list. + + \return VOS_STATUS_SUCCESS - list node was successfully removed from + the list. + + VOS_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + VOS_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + + VOS_STATUS_E_FAULT - pList or pNodeToRemove is not a valid pointer + + \sa + + --------------------------------------------------------------------------*/ +VOS_STATUS vos_list_remove_node( vos_list_t *pList, vos_list_node_t *pNodeToRemove ) +{ + int rc, found = 0; + vos_list_node_t *tmp; + + if ( ( pList == NULL ) || ( pNodeToRemove == NULL) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( pList->cookie != VOS_LIST_COOKIE ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list not initialized", __func__); + return VOS_STATUS_E_INVAL; + } + + rc = mutex_lock_interruptible(&pList->lock); + if (rc) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock list", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( list_empty(&pList->anchor) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: list empty", __func__); + mutex_unlock(&pList->lock); + return VOS_STATUS_E_EMPTY; + } + + // verify that pNodeToRemove is indeed part of list pList + list_for_each(tmp, &pList->anchor) + { + if (tmp == pNodeToRemove) + { + found = 1; + break; + } + } + if (found == 0) + return VOS_STATUS_E_INVAL; + + list_del(pNodeToRemove); + pList->count--; + mutex_unlock(&pList->lock); + + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_lock.c b/drivers/staging/prima/CORE/VOSS/src/vos_lock.c new file mode 100644 index 000000000000..60e0c3dae140 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_lock.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + FILE: vos_lock.c + + OVERVIEW: This source file contains definitions for vOS lock APIs + The four APIs mentioned in this file are used for + initializing , acquiring, releasing and destroying a lock. + the lock are implemented using critical sections + + DEPENDENCIES: + +============================================================================*/ + +/*============================================================================ + EDIT HISTORY FOR MODULE + +============================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + +#include "vos_lock.h" +#include "vos_memory.h" +#include "vos_trace.h" +#include "i_vos_diag_core_event.h" +#include "vos_diag_core_event.h" +#include + + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +#define WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT 0 +#define WIFI_POWER_EVENT_WAKELOCK_TAKEN 0 +#define WIFI_POWER_EVENT_WAKELOCK_RELEASED 1 + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +#define LINUX_LOCK_COOKIE 0x12345678 +enum +{ + LOCK_RELEASED = 0x11223344, + LOCK_ACQUIRED, + LOCK_DESTROYED +}; + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + + \brief vos_lock_init() - initializes a vOSS lock + + The vos_lock_init() function initializes the specified lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - lock was successfully initialized and + is ready to be used. + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the lock + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by lock, a previously + initialized, but not yet destroyed, lock. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the lock + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_init ( vos_lock_t *lock ) +{ + + //check for invalid pointer + if ( lock == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in",__func__); + return VOS_STATUS_E_FAULT; + } + // check for 'already initialized' lock + if ( LINUX_LOCK_COOKIE == lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: already initialized lock",__func__); + return VOS_STATUS_E_BUSY; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return VOS_STATUS_E_FAULT; + } + + // initialize new lock + mutex_init( &lock->m_lock ); + lock->cookie = LINUX_LOCK_COOKIE; + lock->state = LOCK_RELEASED; + lock->processID = 0; + lock->refcount = 0; + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_lock_acquire() - acquires a lock + + A lock object is acquired by calling \a vos_lock_acquire(). If the lock + is already locked, the calling thread shall block until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param lock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_acquire ( vos_lock_t* lock ) +{ + int rc; + //Check for invalid pointer + if ( lock == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in",__func__); + return VOS_STATUS_E_FAULT; + } + // check if lock refers to an initialized object + if ( LINUX_LOCK_COOKIE != lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: uninitialized lock",__func__); + return VOS_STATUS_E_INVAL; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return VOS_STATUS_E_FAULT; + } + if ((lock->processID == current->pid) && + (lock->state == LOCK_ACQUIRED)) + { + lock->refcount++; +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: %x %d %d", __func__, lock, current->pid, lock->refcount); +#endif + return VOS_STATUS_SUCCESS; + } + // Acquire a Lock + mutex_lock( &lock->m_lock ); + rc = mutex_is_locked( &lock->m_lock ); + if (rc == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: unable to lock mutex (rc = %d)", __func__, rc); + return VOS_STATUS_E_FAILURE; + } + + +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: %x %d", __func__, lock, current->pid); +#endif + if ( LOCK_DESTROYED != lock->state ) + { + lock->processID = current->pid; + lock->refcount++; + lock->state = LOCK_ACQUIRED; + return VOS_STATUS_SUCCESS; + } + else + { + // lock is already destroyed + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: Lock is already destroyed", __func__); + mutex_unlock(&lock->m_lock); + return VOS_STATUS_E_FAILURE; + } +} + + +/*-------------------------------------------------------------------------- + + \brief vos_lock_release() - releases a lock + + The \a vos_lock_release() function shall release the lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param lock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + VOS_STATUS_E_INVAL - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_FAULT - The value specified by lock does not refer + to an initialized lock object. + + VOS_STATUS_E_PERM - Operation is not permitted. The calling + thread does not own the lock. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_release ( vos_lock_t *lock ) +{ + //Check for invalid pointer + if ( lock == NULL ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in",__func__); + return VOS_STATUS_E_FAULT; + } + + // check if lock refers to an uninitialized object + if ( LINUX_LOCK_COOKIE != lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: uninitialized lock",__func__); + return VOS_STATUS_E_INVAL; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return VOS_STATUS_E_FAULT; + } + + // CurrentThread = GetCurrentThreadId(); + // Check thread ID of caller against thread ID + // of the thread which acquire the lock + if ( lock->processID != current->pid ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: current task pid does not match original task pid!!",__func__); +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: Lock held by=%d being released by=%d", __func__, lock->processID, current->pid); +#endif + + return VOS_STATUS_E_PERM; + } + if ((lock->processID == current->pid) && + (lock->state == LOCK_ACQUIRED)) + { + if (lock->refcount > 0) lock->refcount--; + } +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: %x %d %d", __func__, lock, lock->processID, lock->refcount); +#endif + if (lock->refcount) return VOS_STATUS_SUCCESS; + + lock->processID = 0; + lock->refcount = 0; + lock->state = LOCK_RELEASED; + // Release a Lock + mutex_unlock( &lock->m_lock ); +#ifdef VOS_NESTED_LOCK_DEBUG + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"%s: Freeing lock %x %d %d", lock, lock->processID, lock->refcount); +#endif + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_lock_destroy() - Destroys a vOSS Lock - probably not required + for Linux. It may not be required for the caller to destroy a lock after + usage. + + The \a vos_lock_destroy() function shall destroy the lock object + referenced by lock. After a successful return from \a vos_lock_destroy() + the lock object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using vos_lock_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to vOSS lock functions to manipulate the lock such + as vos_lock_acquire() will fail if the lock is destroyed. Therefore, + don't use the lock after it has been destroyed until it has + been re-initialized. + + \param lock - the lock object to be destroyed. + + \return VOS_STATUS_SUCCESS - lock was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by lock while it is locked + or still referenced. + + VOS_STATUS_E_INVAL - The value specified by lock is invalid. + + VOS_STATUS_E_FAULT - lock is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_lock_destroy( vos_lock_t *lock ) +{ + //Check for invalid pointer + if ( NULL == lock ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: NULL pointer passed in", __func__); + return VOS_STATUS_E_FAULT; + } + + if ( LINUX_LOCK_COOKIE != lock->cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: uninitialized lock", __func__); + return VOS_STATUS_E_INVAL; + } + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return VOS_STATUS_E_FAULT; + } + + // check if lock is released + if (!mutex_trylock(&lock->m_lock)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s: lock is not released", __func__); + return VOS_STATUS_E_BUSY; + } + lock->cookie = 0; + lock->state = LOCK_DESTROYED; + lock->processID = 0; + lock->refcount = 0; + + mutex_unlock(&lock->m_lock); + + + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_init() - initializes a vOSS spin lock + + The vos_spin_lock_init() function initializes the specified spin lock. Upon + successful initialization, the state of the lock becomes initialized + and unlocked. + + A lock must be initialized by calling vos_spin_lock_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized lock results in + a failure. + + \param pLock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - spin lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_spin_lock_init(vos_spin_lock_t *pLock) +{ + spin_lock_init(pLock); + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_acquire() - acquires a spin lock + + A lock object is acquired by calling \a vos_spin_lock_acquire(). If the lock + is already locked, the calling thread shall spin until the lock becomes + available. This operation shall return with the lock object referenced by + lock in the locked state with the calling thread as its owner. + + \param pLock - the lock object to acquire + + \return VOS_STATUS_SUCCESS - the lock was successfully acquired by + the calling thread. + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_acquire(vos_spin_lock_t *pLock) +{ + spin_lock(pLock); + return VOS_STATUS_SUCCESS; +} +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_release() - releases a lock + + The \a vos_lock_release() function shall release the spin lock object + referenced by 'lock'. + + If a thread attempts to release a lock that it unlocked or is not + initialized, an error is returned. + + \param pLock - the lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_release(vos_spin_lock_t *pLock) +{ + spin_unlock(pLock); + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_spin_lock_destroy() - releases resource of a lock + + \param pLock - the pointer to a lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + \sa + ------------------------------------------------------------------------*/ +VOS_STATUS vos_spin_lock_destroy(vos_spin_lock_t *pLock) +{ + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_init() - initializes a vOSS wake lock + + \param pLock - the wake lock to initialize + name - wakelock name + + \return VOS_STATUS_SUCCESS - wake lock was successfully initialized and + is ready to be used. + --------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_init(vos_wake_lock_t *pLock, const char *name) +{ +#if defined(WLAN_OPEN_SOURCE) + wake_lock_init(pLock, WAKE_LOCK_SUSPEND, name); +#endif + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + * vos_wake_lock_name() - This function returns the name of the wakelock + * @pLock: Pointer to the wakelock + * + * This function returns the name of the wakelock + * + * Return: Pointer to the name if it is valid or a default string + * + --------------------------------------------------------------------------*/ +static const char* vos_wake_lock_name(vos_wake_lock_t *pLock) +{ +#if !(defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK)) + return "UNNAMED_WAKELOCK"; +#else + if (pLock->ws.name) + return pLock->ws.name; + else + return "UNNAMED_WAKELOCK"; +#endif +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_acquire() - acquires a wake lock + + \param pLock - the wake lock to acquire + + \return VOS_STATUS_SUCCESS - the wake lock was successfully acquired + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_acquire(vos_wake_lock_t *pLock, + uint32_t reason) +{ + vos_log_wlock_diag(reason, vos_wake_lock_name(pLock), + WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT, + WIFI_POWER_EVENT_WAKELOCK_TAKEN); +#if defined(WLAN_OPEN_SOURCE) + wake_lock(pLock); +#else + wcnss_prevent_suspend(); +#endif + return VOS_STATUS_SUCCESS; + +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_timeout_release() - release a wake lock with a timeout + + \param pLock - the wake lock to release + reason - reason for taking wakelock + + \return VOS_STATUS_SUCCESS - the wake lock was successfully released + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_timeout_release(vos_wake_lock_t *pLock, + v_U32_t msec, uint32_t reason) +{ + /* Avoid reporting rx and tx wavelocks + * event to diag as it may cause performance + * issues. + */ + if (WIFI_POWER_EVENT_WAKELOCK_HOLD_RX != reason) + { + vos_log_wlock_diag(reason, vos_wake_lock_name(pLock), msec, + WIFI_POWER_EVENT_WAKELOCK_TAKEN); + } + +#if defined(WLAN_OPEN_SOURCE) + wake_lock_timeout(pLock, msecs_to_jiffies(msec)); +#else + /* Do nothing as there is no API in wcnss for timeout*/ +#endif + return VOS_STATUS_SUCCESS; + +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_release() - releases a wake lock + + \param pLock - the wake lock to release + + \return VOS_STATUS_SUCCESS - the lock was successfully released + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_release(vos_wake_lock_t *pLock, uint32_t reason) +{ + vos_log_wlock_diag(reason, vos_wake_lock_name(pLock), + WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT, + WIFI_POWER_EVENT_WAKELOCK_RELEASED); + +#if defined(WLAN_OPEN_SOURCE) + wake_unlock(pLock); +#else + wcnss_allow_suspend(); +#endif + return VOS_STATUS_SUCCESS; + + +} + +/*-------------------------------------------------------------------------- + + \brief vos_wake_lock_destroy() - destroys a wake lock + + \param pLock - the wake lock to destroy + + \return VOS_STATUS_SUCCESS - the lock was successfully destroyed + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_wake_lock_destroy(vos_wake_lock_t *pLock) +{ + +#if defined(WLAN_OPEN_SOURCE) + wake_lock_destroy(pLock); +#endif + return VOS_STATUS_SUCCESS; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_memory.c b/drivers/staging/prima/CORE/VOSS/src/vos_memory.c new file mode 100644 index 000000000000..e87cfd3ea8dc --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_memory.c @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + @file vos_memory.c + + @brief Virtual Operating System Services Memory API + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + +===========================================================================*/ + +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ +#include "vos_memory.h" +#include "vos_trace.h" +#include "vos_api.h" +#include + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC +#include +#define WCNSS_PRE_ALLOC_GET_THRESHOLD (4*1024) +#endif +#define VOS_GET_MEMORY_TIME_THRESHOLD 300 + +#ifdef MEMORY_DEBUG +#include "wlan_hdd_dp_utils.h" + +hdd_list_t vosMemList; + +static v_U8_t WLAN_MEM_HEADER[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68 }; +static v_U8_t WLAN_MEM_TAIL[] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87}; +static int memory_dbug_flag; + +struct s_vos_mem_struct +{ + hdd_list_node_t pNode; + char* fileName; + unsigned int lineNum; + unsigned int size; + v_U8_t header[8]; +}; +#endif + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Type Declarations + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * Data definitions + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + * External Function implementation + * ------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +void vos_mem_init() +{ + /* Initalizing the list with maximum size of 60000 */ + hdd_list_init(&vosMemList, 60000); + memory_dbug_flag = 1; + return; +} + +void vos_mem_clean() +{ + v_SIZE_t listSize; + hdd_list_size(&vosMemList, &listSize); + + if(listSize) + { + hdd_list_node_t* pNode; + VOS_STATUS vosStatus; + + struct s_vos_mem_struct* memStruct; + char* prev_mleak_file = ""; + unsigned int prev_mleak_lineNum = 0; + unsigned int prev_mleak_sz = 0; + unsigned int mleak_cnt = 0; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: List is not Empty. listSize %d ", __func__, (int)listSize); + + do + { + spin_lock(&vosMemList.lock); + vosStatus = hdd_list_remove_front(&vosMemList, &pNode); + spin_unlock(&vosMemList.lock); + if(VOS_STATUS_SUCCESS == vosStatus) + { + memStruct = (struct s_vos_mem_struct*)pNode; + + /* Take care to log only once multiple memory leaks from + * the same place */ + if(strcmp(prev_mleak_file, memStruct->fileName) || + (prev_mleak_lineNum != memStruct->lineNum) || + (prev_mleak_sz != memStruct->size)) + { + if(mleak_cnt != 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%d Time Memory Leak@ File %s, @Line %d, size %d", + mleak_cnt, prev_mleak_file, prev_mleak_lineNum, + prev_mleak_sz); + } + prev_mleak_file = memStruct->fileName; + prev_mleak_lineNum = memStruct->lineNum; + prev_mleak_sz = memStruct->size; + mleak_cnt = 0; + } + mleak_cnt++; + + kfree((v_VOID_t*)memStruct); + } + }while(vosStatus == VOS_STATUS_SUCCESS); + + /* Print last memory leak from the module */ + if(mleak_cnt) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%d Time memory Leak@ File %s, @Line %d, size %d", + mleak_cnt, prev_mleak_file, prev_mleak_lineNum, + prev_mleak_sz); + } + + +#ifdef CONFIG_HALT_KMEMLEAK + BUG_ON(0); +#endif + } +} + +void vos_mem_exit() +{ + if (memory_dbug_flag) + { + vos_mem_clean(); + hdd_list_destroy(&vosMemList); + } +} + +v_VOID_t * vos_mem_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum) +{ + struct s_vos_mem_struct* memStruct; + v_VOID_t* memPtr = NULL; + v_SIZE_t new_size; + int flags = GFP_KERNEL; + unsigned long IrqFlags; + unsigned long time_before_kmalloc; + + + if (size > (1024*1024) || size == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: called with invalid arg %u !!!", __func__, size); + return NULL; + } + + if (in_interrupt() || irqs_disabled() || in_atomic()) + { + flags = GFP_ATOMIC; + } + + if (!memory_dbug_flag) + { +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + v_VOID_t* pmem; + if (size > WCNSS_PRE_ALLOC_GET_THRESHOLD) + { + pmem = wcnss_prealloc_get(size); + if (NULL != pmem) + return pmem; + } +#endif + time_before_kmalloc = vos_timer_get_system_time(); + memPtr = kmalloc(size, flags); + + /* If time taken by kmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD + * msec */ + if (vos_timer_get_system_time() - time_before_kmalloc >= + VOS_GET_MEMORY_TIME_THRESHOLD) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: kmalloc took %lu msec for size %d called from %pS at line %d", + __func__, + vos_timer_get_system_time() - time_before_kmalloc, + size, (void *)_RET_IP_, lineNum); + if ((flags != GFP_ATOMIC) && (NULL == memPtr)) + { + WARN_ON(1); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_MALLOC_FAIL, + false, true); + } + return memPtr; + } + + new_size = size + sizeof(struct s_vos_mem_struct) + 8; + + time_before_kmalloc = vos_timer_get_system_time(); + memStruct = (struct s_vos_mem_struct*)kmalloc(new_size, flags); + /* If time taken by kmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD + * msec */ + if (vos_timer_get_system_time() - time_before_kmalloc >= + VOS_GET_MEMORY_TIME_THRESHOLD) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: kmalloc took %lu msec for size %d called from %pS at line %d", + __func__, + vos_timer_get_system_time() - time_before_kmalloc, + size, (void *)_RET_IP_, lineNum); + + if(memStruct != NULL) + { + VOS_STATUS vosStatus; + + memStruct->fileName = fileName; + memStruct->lineNum = lineNum; + memStruct->size = size; + + vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)); + vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL)); + + spin_lock_irqsave(&vosMemList.lock, IrqFlags); + vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode); + spin_unlock_irqrestore(&vosMemList.lock, IrqFlags); + if(VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus); + } + + memPtr = (v_VOID_t*)(memStruct + 1); + } + if ((flags != GFP_ATOMIC) && (NULL == memStruct)) + { + WARN_ON(1); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_MALLOC_FAIL, + false, true); + } + return memPtr; +} + +v_VOID_t vos_mem_free( v_VOID_t *ptr ) +{ + + unsigned long IrqFlags; + if (ptr == NULL) + return; + + if (!memory_dbug_flag) + { +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if (wcnss_prealloc_put(ptr)) + return; +#endif + kfree(ptr); + } + else + { + VOS_STATUS vosStatus; + struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1; + + spin_lock_irqsave(&vosMemList.lock, IrqFlags); + vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode); + spin_unlock_irqrestore(&vosMemList.lock, IrqFlags); + + if(VOS_STATUS_SUCCESS == vosStatus) + { + if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + } + if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + } + kfree((v_VOID_t*)memStruct); + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Unallocated memory (double free?)", __func__); + VOS_BUG(0); + } + } +} +#else +v_VOID_t * vos_mem_malloc( v_SIZE_t size ) +{ + int flags = GFP_KERNEL; + v_VOID_t* memPtr = NULL; +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + v_VOID_t* pmem; +#endif + unsigned long time_before_kmalloc; + + if (size > (1024*1024) || size == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: called with invalid arg %u !!!", __func__, size); + return NULL; + } + if (in_interrupt() || irqs_disabled() || in_atomic()) + { + flags = GFP_ATOMIC; + } +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if(size > WCNSS_PRE_ALLOC_GET_THRESHOLD) + { + pmem = wcnss_prealloc_get(size); + if(NULL != pmem) + return pmem; + } +#endif + time_before_kmalloc = vos_timer_get_system_time(); + memPtr = kmalloc(size, flags); + /* If time taken by kmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD + * msec */ + if (vos_timer_get_system_time() - time_before_kmalloc >= + VOS_GET_MEMORY_TIME_THRESHOLD) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: kmalloc took %lu msec for size %d from %pS", + __func__, + vos_timer_get_system_time() - time_before_kmalloc, + size, (void *)_RET_IP_); + + if ((flags != GFP_ATOMIC) && (NULL == memPtr)) + { + WARN_ON(1); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_MALLOC_FAIL, + false, true); + } + return memPtr; + +} + +v_VOID_t vos_mem_free( v_VOID_t *ptr ) +{ + if (ptr == NULL) + return; + +#ifdef CONFIG_WCNSS_MEM_PRE_ALLOC + if(wcnss_prealloc_put(ptr)) + return; +#endif + + kfree(ptr); +} +#endif + +v_VOID_t * vos_mem_vmalloc(v_SIZE_t size) +{ + v_VOID_t* memPtr = NULL; + unsigned long time_before_vmalloc; + + if (size == 0 || size >= (1024*1024)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s invalid size: %u", __func__, size); + return NULL; + } + time_before_vmalloc = vos_timer_get_system_time(); + memPtr = vmalloc(size); + /* If time taken by vmalloc is greater than VOS_GET_MEMORY_TIME_THRESHOLD + * msec + */ + if (vos_timer_get_system_time() - time_before_vmalloc >= + VOS_GET_MEMORY_TIME_THRESHOLD) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vmalloc took %lu msec for size %d from %pS", + __func__, + vos_timer_get_system_time() - time_before_vmalloc, + size, (void *)_RET_IP_); + return memPtr; +} + +v_VOID_t vos_mem_vfree(void *addr) +{ + if (addr == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s NULL address passed to free", __func__); + return; + } + + vfree(addr); + return; +} + +v_VOID_t vos_mem_set( v_VOID_t *ptr, v_SIZE_t numBytes, v_BYTE_t value ) +{ + if (ptr == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__); + return; + } + memset(ptr, value, numBytes); +} + +void vos_buff_to_hl_buff (tANI_U8 *buffer, int size) +{ + int *val, i; + if (size % 4 != 0) + VOS_TRACE(VOS_MODULE_ID_PE,VOS_TRACE_LEVEL_ERROR, + "%s: size should be multiple of 4, size %d", + __func__, size); + + val = (int *)buffer; + + for (i=0; i<(size/4); i++) + *(val+i) = vos_htonl ((unsigned long)(*(val+i))); +} + +v_VOID_t vos_mem_zero( v_VOID_t *ptr, v_SIZE_t numBytes ) +{ + if (0 == numBytes) + { + // special case where ptr can be NULL + return; + } + + if (ptr == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s called with NULL parameter ptr", __func__); + return; + } + memset(ptr, 0, numBytes); + +} + +v_VOID_t vos_mem_copy( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ) +{ + if (0 == numBytes) + { + // special case where pDst or pSrc can be NULL + return; + } + + if ((pDst == NULL) || (pSrc==NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s called with NULL parameter, source:%p destination:%p", + __func__, pSrc, pDst); + VOS_ASSERT(0); + return; + } + memcpy(pDst, pSrc, numBytes); +} + +v_VOID_t vos_mem_move( v_VOID_t *pDst, const v_VOID_t *pSrc, v_SIZE_t numBytes ) +{ + if (0 == numBytes) + { + // special case where pDst or pSrc can be NULL + return; + } + + if ((pDst == NULL) || (pSrc==NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s called with NULL parameter, source:%p destination:%p", + __func__, pSrc, pDst); + VOS_ASSERT(0); + return; + } + memmove(pDst, pSrc, numBytes); +} + +v_BOOL_t vos_mem_compare( +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_VOID_t *pMemory1, +#else + v_VOID_t *pMemory1, +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) + const v_VOID_t *pMemory2, +#else + v_VOID_t *pMemory2, +#endif + v_U32_t numBytes ) +{ + if (0 == numBytes) + { + // special case where pMemory1 or pMemory2 can be NULL + return VOS_TRUE; + } + + if ((pMemory1 == NULL) || (pMemory2==NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s called with NULL parameter, p1:%p p2:%p", + __func__, pMemory1, pMemory2); + VOS_ASSERT(0); + return VOS_FALSE; + } + return (memcmp(pMemory1, pMemory2, numBytes)?VOS_FALSE:VOS_TRUE); +} + + +v_SINT_t vos_mem_compare2( v_VOID_t *pMemory1, v_VOID_t *pMemory2, v_U32_t numBytes ) + +{ + return( (v_SINT_t) memcmp( pMemory1, pMemory2, numBytes ) ); +} + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_malloc() - vOSS DMA Memory Allocation + + This function will dynamicallly allocate the specified number of bytes of + memory. This memory will have special attributes making it DMA friendly i.e. + it will exist in contiguous, 32-byte aligned uncached memory. A normal + vos_mem_malloc does not yield memory with these attributes. + + NOTE: the special DMA friendly memory is very scarce and this API must be + used sparingly + + On WM, there is nothing special about this memory. SDHC allocates the + DMA friendly buffer and copies the data into it + + \param size - the number of bytes of memory to allocate. + + \return Upon successful allocate, returns a non-NULL pointer to the + allocated memory. If this function is unable to allocate the amount of + memory specified (for any reason) it returns NULL. + + \sa + + --------------------------------------------------------------------------*/ +#ifdef MEMORY_DEBUG +v_VOID_t * vos_mem_dma_malloc_debug( v_SIZE_t size, char* fileName, v_U32_t lineNum) +{ + struct s_vos_mem_struct* memStruct; + v_VOID_t* memPtr = NULL; + v_SIZE_t new_size; + + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return NULL; + } + + if (!memory_dbug_flag) + return kmalloc(size, GFP_KERNEL); + + new_size = size + sizeof(struct s_vos_mem_struct) + 8; + + memStruct = (struct s_vos_mem_struct*)kmalloc(new_size,GFP_KERNEL); + + if(memStruct != NULL) + { + VOS_STATUS vosStatus; + + memStruct->fileName = fileName; + memStruct->lineNum = lineNum; + memStruct->size = size; + + vos_mem_copy(&memStruct->header[0], &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)); + vos_mem_copy( (v_U8_t*)(memStruct + 1) + size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL)); + + spin_lock(&vosMemList.lock); + vosStatus = hdd_list_insert_front(&vosMemList, &memStruct->pNode); + spin_unlock(&vosMemList.lock); + if(VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to insert node into List vosStatus %d", __func__, vosStatus); + } + + memPtr = (v_VOID_t*)(memStruct + 1); + } + + return memPtr; +} + +v_VOID_t vos_mem_dma_free( v_VOID_t *ptr ) +{ + if (ptr == NULL) + return; + + if (memory_dbug_flag) + { + VOS_STATUS vosStatus; + struct s_vos_mem_struct* memStruct = ((struct s_vos_mem_struct*)ptr) - 1; + + spin_lock(&vosMemList.lock); + vosStatus = hdd_list_remove_node(&vosMemList, &memStruct->pNode); + spin_unlock(&vosMemList.lock); + + if(VOS_STATUS_SUCCESS == vosStatus) + { + if(0 == vos_mem_compare(memStruct->header, &WLAN_MEM_HEADER[0], sizeof(WLAN_MEM_HEADER)) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Header is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + } + if(0 == vos_mem_compare( (v_U8_t*)ptr + memStruct->size, &WLAN_MEM_TAIL[0], sizeof(WLAN_MEM_TAIL ) ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Memory Trailer is corrupted. MemInfo: Filename %s, LineNum %d", + memStruct->fileName, (int)memStruct->lineNum); + } + kfree((v_VOID_t*)memStruct); + } + } + else + kfree(ptr); +} +#else +v_VOID_t* vos_mem_dma_malloc( v_SIZE_t size ) +{ + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return NULL; + } + return kmalloc(size, GFP_KERNEL); +} + +/*---------------------------------------------------------------------------- + + \brief vos_mem_dma_free() - vOSS DMA Free Memory + + This function will free special DMA friendly memory pointed to by 'ptr'. + + On WM, there is nothing special about the memory being free'd. SDHC will + take care of free'ing the DMA friendly buffer + + \param ptr - pointer to the starting address of the memory to be + free'd. + + \return Nothing + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_mem_dma_free( v_VOID_t *ptr ) +{ + if (ptr == NULL) + return; + kfree(ptr); +} +#endif diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_mq.c b/drivers/staging/prima/CORE/VOSS/src/vos_mq.c new file mode 100644 index 000000000000..91ed20674001 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_mq.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_mq.c + + \brief virtual Operating System Services (vOSS) message queue APIs + + Message Queue Definitions and API + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include "vos_sched.h" +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + + \brief vos_mq_init() - Initialize the vOSS Scheduler + + The \a vos_mq_init() function initializes the Message queue. + + \param pMq - pointer to the message queue + + \return VOS_STATUS_SUCCESS - Message queue was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - Invalid parameter passed to the message + queue initialize function. + + \sa vos_mq_init() + +---------------------------------------------------------------------------*/ +__inline VOS_STATUS vos_mq_init(pVosMqType pMq) +{ + + /* Some quick sanity check*/ + if (pMq == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return VOS_STATUS_E_FAILURE; + } + + /* + ** Now initialize the lock + */ + spin_lock_init(&pMq->mqLock); + + /* + ** Now initialize the List data structure + */ + INIT_LIST_HEAD(&pMq->mqList); + + return VOS_STATUS_SUCCESS; + +} /* vos_mq_init()*/ + +/*--------------------------------------------------------------------------- + + \brief vos_mq_deinit() - DeInitialize the vOSS Scheduler + + The \a vos_mq_init() function de-initializes the Message queue. + + \param pMq - pointer to the message queue + + \return None + + \sa vos_mq_deinit() + +---------------------------------------------------------------------------*/ +__inline void vos_mq_deinit(pVosMqType pMq) +{ + /* + ** Some quick sanity check + */ + if (pMq == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return ; + } + + /* we don't have to do anything with the embedded list or spinlock */ + +}/* vos_mq_deinit() */ + + +/*--------------------------------------------------------------------------- + + \brief vos_mq_put() - Add a message to the message queue + + The \a vos_mq_put() function add a message to the Message queue. + + \param pMq - pointer to the message queue + + \param pMsgWrapper - Msg Wrapper containing the message + + \return None + + \sa vos_mq_put() + +---------------------------------------------------------------------------*/ +__inline void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper) +{ + unsigned long flags; + + /* + ** Some quick sanity check + */ + if ((pMq == NULL) || (pMsgWrapper == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return ; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + + list_add_tail(&pMsgWrapper->msgNode, &pMq->mqList); + + spin_unlock_irqrestore(&pMq->mqLock, flags); + +} /* vos_mq_put() */ + +/*--------------------------------------------------------------------------- + + \brief vos_mq_put_front() - Add a message to the head of message queue + + The \a vos_mq_put_front() function add a message to the head of Message queue. + + \param pMq - pointer to the message queue + + \param pMsgWrapper - Msg Wrapper containing the message + + \return None + + \sa vos_mq_put() + +---------------------------------------------------------------------------*/ +void vos_mq_put_front(pVosMqType pMq, pVosMsgWrapper pMsgWrapper) +{ + unsigned long flags; + + /* + ** Some quick sanity check + */ + if ((pMq == NULL) || (pMsgWrapper == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return ; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + + list_add(&pMsgWrapper->msgNode, &pMq->mqList); + + spin_unlock_irqrestore(&pMq->mqLock, flags); + +} /* vos_mq_put_front() */ + + +/*--------------------------------------------------------------------------- + + \brief vos_mq_get() - Get a message with its wrapper from a message queue + + The \a vos_mq_get() function retrieve a message with its wrapper from + the Message queue. + + \param pMq - pointer to the message queue + + \return pointer to the Message Wrapper + + \sa vos_mq_get() + +---------------------------------------------------------------------------*/ +__inline pVosMsgWrapper vos_mq_get(pVosMqType pMq) +{ + pVosMsgWrapper pMsgWrapper = NULL; + + /* + ** Some quick sanity check + */ + struct list_head * listptr; + unsigned long flags; + + if (pMq == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return NULL; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + + if( list_empty(&pMq->mqList) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "%s: VOS Message Queue is empty",__func__); + } + else + { + listptr = pMq->mqList.next; + pMsgWrapper = (pVosMsgWrapper)list_entry(listptr, VosMsgWrapper, msgNode); + list_del(pMq->mqList.next); + } + + spin_unlock_irqrestore(&pMq->mqLock, flags); + + return pMsgWrapper; + +} /* vos_mq_get() */ + + +/*--------------------------------------------------------------------------- + + \brief vos_is_mq_empty() - Return if the MQ is empty + + The \a vos_is_mq_empty() returns true if the queue is empty + + \param pMq - pointer to the message queue + + \return pointer to the Message Wrapper + + \sa vos_mq_get() + +---------------------------------------------------------------------------*/ +__inline v_BOOL_t vos_is_mq_empty(pVosMqType pMq) +{ + v_BOOL_t state = VOS_FALSE; + unsigned long flags; + + /* + ** Some quick sanity check + */ + if (pMq == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pointer passed",__func__); + return VOS_STATUS_E_FAILURE; + } + + spin_lock_irqsave(&pMq->mqLock, flags); + state = list_empty(&pMq->mqList)?VOS_TRUE:VOS_FALSE; + spin_unlock_irqrestore(&pMq->mqLock, flags); + + return state; + +} /* vos_mq_get() */ + + diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_nvitem.c b/drivers/staging/prima/CORE/VOSS/src/vos_nvitem.c new file mode 100644 index 000000000000..5b4c6047d895 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_nvitem.c @@ -0,0 +1,4832 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*============================================================================ + FILE: vos_nvitem.c + OVERVIEW: This source file contains definitions for vOS NV Item APIs + DEPENDENCIES: NV, remote API client, WinCE REX +============================================================================*/ +/*============================================================================ + EDIT HISTORY FOR MODULE +============================================================================*/ +// the following is used to disable warning for having too many labels in +// the 'nv_items_enum_type' + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "aniGlobal.h" +#include "vos_nvitem.h" +#include "vos_trace.h" +#include "vos_api.h" +#include "wlan_hdd_misc.h" +#include "vos_sched.h" +#include "sme_Api.h" +#include "wlan_nv_parser.h" +#include "wlan_hdd_main.h" +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) +#define IEEE80211_CHAN_NO_80MHZ 1<<7 +#endif + +#ifdef CONFIG_ENABLE_LINUX_REG + +static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT; +static char linux_reg_cc[2] = {0, 0}; +static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT; + +#else + +/* Cant access pAdapter in this file so defining a new variable to wait when changing country*/ +static struct completion change_country_code; + +#endif + +static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */ +static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */ +static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE; +static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE; + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#define VALIDITY_BITMAP_NV_ID NV_WLAN_VALIDITY_BITMAP_I +#define VALIDITY_BITMAP_SIZE 32 +#define MAX_COUNTRY_COUNT 300 +//To be removed when NV support is fully functional +#define VOS_HARD_CODED_MAC {0, 0x0a, 0xf5, 4, 5, 6} + +#define DEFAULT_NV_VALIDITY_BITMAP 0xFFFFFFFF +#define MAGIC_NUMBER 0xCAFEBABE + +#define MIN(a, b) (a > b ? b : a) +#define MAX(a, b) (a > b ? a : b) + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +// this wrapper structure is identical to nv_cmd_type except the +// data_ptr type is changed void* to avoid exceeding the debug information +// module size as there are too many elements within nv_items_type union + +// structure for code and regulatory domain of a single country +typedef struct +{ + v_U8_t regDomain; + v_COUNTRYCODE_t countryCode; +} CountryInfo_t; +// structure of table to map country code and regulatory domain +typedef struct +{ + v_U16_t countryCount; + CountryInfo_t countryInfo[MAX_COUNTRY_COUNT]; +} CountryInfoTable_t; +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ +// cache of country info table; +// this is re-initialized from data on binary file +// loaded on driver initialization if available + +#ifdef CONFIG_ENABLE_LINUX_REG +static struct +chan_to_ht_40_index_map chan_to_ht_40_index[NUM_20MHZ_RF_CHANNELS] = +{ + /* ht_40_minus_index, ht_40_plus_index */ + {INVALID_RF_CHANNEL, RF_CHAN_BOND_3}, //RF_CHAN_1, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_4}, //RF_CHAN_2, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_5}, //RF_CHAN_3, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_6}, //RF_CHAN_4, + {RF_CHAN_BOND_3, RF_CHAN_BOND_7}, //RF_CHAN_5, + {RF_CHAN_BOND_4, RF_CHAN_BOND_8}, //RF_CHAN_6, + {RF_CHAN_BOND_5, RF_CHAN_BOND_9}, //RF_CHAN_7, + {RF_CHAN_BOND_6, RF_CHAN_BOND_10}, //RF_CHAN_8, + {RF_CHAN_BOND_7, RF_CHAN_BOND_11}, //RF_CHAN_9, + {RF_CHAN_BOND_8, INVALID_RF_CHANNEL}, //RF_CHAN_10, + {RF_CHAN_BOND_9, INVALID_RF_CHANNEL}, //RF_CHAN_11, + {RF_CHAN_BOND_10, INVALID_RF_CHANNEL}, //RF_CHAN_12, + {RF_CHAN_BOND_11, INVALID_RF_CHANNEL}, //RF_CHAN_13, + {INVALID_RF_CHANNEL, INVALID_RF_CHANNEL},//RF_CHAN_14, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_242}, //RF_CHAN_240, + {RF_CHAN_BOND_242, RF_CHAN_BOND_246}, //RF_CHAN_244, + {RF_CHAN_BOND_246, RF_CHAN_BOND_250}, //RF_CHAN_248, + {RF_CHAN_BOND_250, INVALID_RF_CHANNEL}, //RF_CHAN_252, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_210}, //RF_CHAN_208, + {RF_CHAN_BOND_210, RF_CHAN_BOND_214}, //RF_CHAN_212, + {RF_CHAN_BOND_214, INVALID_RF_CHANNEL}, //RF_CHAN_216, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_38}, //RF_CHAN_36, + {RF_CHAN_BOND_38, RF_CHAN_BOND_42}, //RF_CHAN_40, + {RF_CHAN_BOND_42, RF_CHAN_BOND_46}, //RF_CHAN_44, + {RF_CHAN_BOND_46, RF_CHAN_BOND_50}, //RF_CHAN_48, + {RF_CHAN_BOND_50, RF_CHAN_BOND_54}, //RF_CHAN_52, + {RF_CHAN_BOND_54, RF_CHAN_BOND_58}, //RF_CHAN_56, + {RF_CHAN_BOND_58, RF_CHAN_BOND_62}, //RF_CHAN_60, + {RF_CHAN_BOND_62, INVALID_RF_CHANNEL}, //RF_CHAN_64, + {INVALID_RF_CHANNEL, RF_CHAN_BOND_102}, //RF_CHAN_100, + {RF_CHAN_BOND_102, RF_CHAN_BOND_106}, //RF_CHAN_104, + {RF_CHAN_BOND_106, RF_CHAN_BOND_110}, //RF_CHAN_108, + {RF_CHAN_BOND_110, RF_CHAN_BOND_114}, //RF_CHAN_112, + {RF_CHAN_BOND_114, RF_CHAN_BOND_118}, //RF_CHAN_116, + {RF_CHAN_BOND_118, RF_CHAN_BOND_122}, //RF_CHAN_120, + {RF_CHAN_BOND_122, RF_CHAN_BOND_126}, //RF_CHAN_124, + {RF_CHAN_BOND_126, RF_CHAN_BOND_130}, //RF_CHAN_128, + {RF_CHAN_BOND_130, RF_CHAN_BOND_134}, //RF_CHAN_132, + {RF_CHAN_BOND_134, RF_CHAN_BOND_138}, //RF_CHAN_136, + {RF_CHAN_BOND_138, RF_CHAN_BOND_142}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {RF_CHAN_BOND_142, INVALID_RF_CHANNEL}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + {INVALID_RF_CHANNEL, RF_CHAN_BOND_151}, //RF_CHAN_149, + {RF_CHAN_BOND_151, RF_CHAN_BOND_155}, //RF_CHAN_153, + {RF_CHAN_BOND_155, RF_CHAN_BOND_159}, //RF_CHAN_157, + {RF_CHAN_BOND_159, RF_CHAN_BOND_163}, //RF_CHAN_161, + {RF_CHAN_BOND_163, INVALID_RF_CHANNEL}, //RF_CHAN_165, +}; + +static CountryInfoTable_t countryInfoTable = +{ + /* the first entry in the table is always the world domain */ + 139, + { + {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN + {REGDOMAIN_ETSI, {'A', 'D'}}, // ANDORRA + {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE + {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA + {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA + {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES + {REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA + {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA + {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA + {REGDOMAIN_ETSI, {'A', 'U'}}, //AUSTRALIA + {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA + {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN + {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA + {REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS + {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH + {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM + {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA + {REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN + {REGDOMAIN_ETSI, {'B', 'L'}}, // + {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA + {REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM + {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA + {REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL + {REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS + {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS + {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE + {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA + {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND + {REGDOMAIN_APAC, {'C', 'L'}}, //CHILE + {REGDOMAIN_APAC, {'C', 'N'}}, //CHINA + {REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA + {REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA + {REGDOMAIN_ETSI, {'C', 'S'}}, + {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS + {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC + {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY + {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK + {REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC + {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA + {REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR + {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA + {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT + {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN + {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND + {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE + {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM + {REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA + {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA + {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA + {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND + {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE + {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE + {REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA + {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM + {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY + {REGDOMAIN_ETSI, {'I', 'D'}}, //INDONESIA + {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND + {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL + {REGDOMAIN_APAC, {'I', 'N'}}, //INDIA + {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF + {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD + {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY + {REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA + {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN + {REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN + {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA + {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA + {REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF + {REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF + {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT + {REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN + {REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON + {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN + {REGDOMAIN_WORLD, {'L', 'K'}}, //SRI-LANKA + {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA + {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG + {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA + {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO + {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO + {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF + {REGDOMAIN_WORLD, {'M','N'}}, //MONGOLIA + {REGDOMAIN_APAC, {'M', 'O'}}, //MACAO + {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS + {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE + {REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA + {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS + {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI + {REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO + {REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA + {REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA + {REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA + {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS + {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY + {REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL + {REGDOMAIN_APAC, {'N', 'Z'}}, //NEW-ZEALAND + {REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN + {REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA + {REGDOMAIN_WORLD, {'P', 'E'}}, //PERU + {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA + {REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA + {REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES + {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN + {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND + {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO + {REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED + {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL + {REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY + {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR + {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION + {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA + {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA + {REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA + {REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA + {REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA + {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN + {REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE + {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA + {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA + {REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR + {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC + {REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND + {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA + {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY + {REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO + {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA + {REGDOMAIN_ETSI, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF + {REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE + {REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA + {REGDOMAIN_FCC, {'U', 'S'}}, //USA + {REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY + {REGDOMAIN_ETSI, {'U', 'Z'}}, //UZBEKISTAN + {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA + {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US + {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM + {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN + {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE + {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA + {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE + {REGDOMAIN_JAPAN, {'X', 'A'}}, //JAPAN PASSIVE + } +}; + +#else + +// cache of country info table; +// this is re-initialized from data on binary file +// loaded on driver initialization if available +static CountryInfoTable_t countryInfoTable = +{ + 254, + { + { REGDOMAIN_FCC, {'U', 'S'}}, //USA - must be the first country code + { REGDOMAIN_ETSI, {'A', 'D'}}, //ANDORRA + { REGDOMAIN_ETSI, {'A', 'E'}}, //UAE + { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'F'}}, //AFGHANISTAN + { REGDOMAIN_WORLD, {'A', 'G'}}, //ANTIGUA AND BARBUDA + { REGDOMAIN_FCC, {'A', 'I'}}, //ANGUILLA + { REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA + { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'M'}}, //ARMENIA + { REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES + { REGDOMAIN_NO_5GHZ, {'A', 'O'}}, //ANGOLA + { REGDOMAIN_WORLD, {'A', 'Q'}}, //ANTARCTICA + { REGDOMAIN_WORLD, {'A', 'R'}}, //ARGENTINA + { REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA + { REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA + { REGDOMAIN_WORLD, {'A', 'U'}}, //AUSTRALIA + { REGDOMAIN_ETSI, {'A', 'W'}}, //ARUBA + { REGDOMAIN_WORLD, {'A', 'X'}}, //ALAND ISLANDS + { REGDOMAIN_N_AMER_EXC_FCC, {'A', 'Z'}}, //AZERBAIJAN + { REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA + { REGDOMAIN_APAC, {'B', 'B'}}, //BARBADOS + { REGDOMAIN_HI_5GHZ, {'B', 'D'}}, //BANGLADESH + { REGDOMAIN_ETSI, {'B', 'E'}}, //BELGIUM + { REGDOMAIN_HI_5GHZ, {'B', 'F'}}, //BURKINA FASO + { REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA + { REGDOMAIN_APAC, {'B', 'H'}}, //BAHRAIN + { REGDOMAIN_NO_5GHZ, {'B', 'I'}}, //BURUNDI + { REGDOMAIN_NO_5GHZ, {'B', 'J'}}, //BENIN + { REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA + { REGDOMAIN_APAC, {'B', 'N'}}, //BRUNEI DARUSSALAM + { REGDOMAIN_HI_5GHZ, {'B', 'O'}}, //BOLIVIA + { REGDOMAIN_WORLD, {'B', 'R'}}, //BRAZIL + { REGDOMAIN_APAC, {'B', 'S'}}, //BAHAMAS + { REGDOMAIN_NO_5GHZ, {'B', 'T'}}, //BHUTAN + { REGDOMAIN_WORLD, {'B', 'V'}}, //BOUVET ISLAND + { REGDOMAIN_ETSI, {'B', 'W'}}, //BOTSWANA + { REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS + { REGDOMAIN_HI_5GHZ, {'B', 'Z'}}, //BELIZE + { REGDOMAIN_FCC, {'C', 'A'}}, //CANADA + { REGDOMAIN_WORLD, {'C', 'C'}}, //COCOS (KEELING) ISLANDS + { REGDOMAIN_NO_5GHZ, {'C', 'D'}}, //CONGO, THE DEMOCRATIC REPUBLIC OF THE + { REGDOMAIN_NO_5GHZ, {'C', 'F'}}, //CENTRAL AFRICAN REPUBLIC + { REGDOMAIN_NO_5GHZ, {'C', 'G'}}, //CONGO + { REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND + { REGDOMAIN_NO_5GHZ, {'C', 'I'}}, //COTE D'IVOIRE + { REGDOMAIN_WORLD, {'C', 'K'}}, //COOK ISLANDS + { REGDOMAIN_APAC, {'C', 'L'}}, //CHILE + { REGDOMAIN_NO_5GHZ, {'C', 'M'}}, //CAMEROON + { REGDOMAIN_APAC, {'C', 'N'}}, //CHINA + { REGDOMAIN_APAC, {'C', 'O'}}, //COLOMBIA + { REGDOMAIN_APAC, {'C', 'R'}}, //COSTA RICA + { REGDOMAIN_NO_5GHZ, {'C', 'U'}}, //CUBA + { REGDOMAIN_ETSI, {'C', 'V'}}, //CAPE VERDE + { REGDOMAIN_WORLD, {'C', 'X'}}, //CHRISTMAS ISLAND + { REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS + { REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC + { REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY + { REGDOMAIN_NO_5GHZ, {'D', 'J'}}, //DJIBOUTI + { REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK + { REGDOMAIN_WORLD, {'D', 'M'}}, //DOMINICA + { REGDOMAIN_APAC, {'D', 'O'}}, //DOMINICAN REPUBLIC + { REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA + { REGDOMAIN_APAC, {'E', 'C'}}, //ECUADOR + { REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA + { REGDOMAIN_N_AMER_EXC_FCC, {'E', 'G'}}, //EGYPT + { REGDOMAIN_WORLD, {'E', 'H'}}, //WESTERN SAHARA + { REGDOMAIN_NO_5GHZ, {'E', 'R'}}, //ERITREA + { REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN + { REGDOMAIN_ETSI, {'E', 'T'}}, //ETHIOPIA + { REGDOMAIN_ETSI, {'E', 'U'}}, //Europe (SSGFI) + { REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND + { REGDOMAIN_NO_5GHZ, {'F', 'J'}}, //FIJI + { REGDOMAIN_WORLD, {'F', 'K'}}, //FALKLAND ISLANDS (MALVINAS) + { REGDOMAIN_WORLD, {'F', 'M'}}, //MICRONESIA, FEDERATED STATES OF + { REGDOMAIN_WORLD, {'F', 'O'}}, //FAROE ISLANDS + { REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE + { REGDOMAIN_NO_5GHZ, {'G', 'A'}}, //GABON + { REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM + { REGDOMAIN_WORLD, {'G', 'D'}}, //GRENADA + { REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA + { REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA + { REGDOMAIN_WORLD, {'G', 'G'}}, //GUERNSEY + { REGDOMAIN_WORLD, {'G', 'H'}}, //GHANA + { REGDOMAIN_WORLD, {'G', 'I'}}, //GIBRALTAR + { REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND + { REGDOMAIN_NO_5GHZ, {'G', 'M'}}, //GAMBIA + { REGDOMAIN_NO_5GHZ, {'G', 'N'}}, //GUINEA + { REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE + { REGDOMAIN_NO_5GHZ, {'G', 'Q'}}, //EQUATORIAL GUINEA + { REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE + { REGDOMAIN_WORLD, {'G', 'S'}}, //SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS + { REGDOMAIN_APAC, {'G', 'T'}}, //GUATEMALA + { REGDOMAIN_FCC, {'G', 'U'}}, //GUAM + { REGDOMAIN_NO_5GHZ, {'G', 'W'}}, //GUINEA-BISSAU + { REGDOMAIN_HI_5GHZ, {'G', 'Y'}}, //GUYANA + { REGDOMAIN_WORLD, {'H', 'K'}}, //HONGKONG + { REGDOMAIN_WORLD, {'H', 'M'}}, //HEARD ISLAND AND MCDONALD ISLANDS + { REGDOMAIN_WORLD, {'H', 'N'}}, //HONDURAS + { REGDOMAIN_ETSI, {'H', 'R'}}, //CROATIA + { REGDOMAIN_ETSI, {'H', 'T'}}, //HAITI + { REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY + { REGDOMAIN_HI_5GHZ, {'I', 'D'}}, //INDONESIA + { REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND + { REGDOMAIN_N_AMER_EXC_FCC, {'I', 'L'}}, //ISRAEL + { REGDOMAIN_WORLD, {'I', 'M'}}, //ISLE OF MAN + { REGDOMAIN_APAC, {'I', 'N'}}, //INDIA + { REGDOMAIN_WORLD, {'I', 'O'}}, //BRITISH INDIAN OCEAN TERRITORY + { REGDOMAIN_NO_5GHZ, {'I', 'Q'}}, //IRAQ + { REGDOMAIN_HI_5GHZ, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF + { REGDOMAIN_ETSI, {'I', 'S'}}, //ICELAND + { REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY + { REGDOMAIN_JAPAN, {'J', '1'}}, //Japan alternate 1 + { REGDOMAIN_JAPAN, {'J', '2'}}, //Japan alternate 2 + { REGDOMAIN_JAPAN, {'J', '3'}}, //Japan alternate 3 + { REGDOMAIN_JAPAN, {'J', '4'}}, //Japan alternate 4 + { REGDOMAIN_JAPAN, {'J', '5'}}, //Japan alternate 5 + { REGDOMAIN_WORLD, {'J', 'E'}}, //JERSEY + { REGDOMAIN_WORLD, {'J', 'M'}}, //JAMAICA + { REGDOMAIN_APAC, {'J', 'O'}}, //JORDAN + { REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN + { REGDOMAIN_KOREA, {'K', '1'}}, //Korea alternate 1 + { REGDOMAIN_KOREA, {'K', '2'}}, //Korea alternate 2 + { REGDOMAIN_KOREA, {'K', '3'}}, //Korea alternate 3 + { REGDOMAIN_KOREA, {'K', '4'}}, //Korea alternate 4 + { REGDOMAIN_APAC, {'K', 'E'}}, //KENYA + { REGDOMAIN_NO_5GHZ, {'K', 'G'}}, //KYRGYZSTAN + { REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA + { REGDOMAIN_WORLD, {'K', 'I'}}, //KIRIBATI + { REGDOMAIN_NO_5GHZ, {'K', 'M'}}, //COMOROS + { REGDOMAIN_WORLD, {'K', 'N'}}, //SAINT KITTS AND NEVIS + { REGDOMAIN_WORLD, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF + { REGDOMAIN_KOREA, {'K', 'R'}}, //KOREA, REPUBLIC OF + { REGDOMAIN_N_AMER_EXC_FCC, {'K', 'W'}}, //KUWAIT + { REGDOMAIN_FCC, {'K', 'Y'}}, //CAYMAN ISLANDS + { REGDOMAIN_WORLD, {'K', 'Z'}}, //KAZAKHSTAN + { REGDOMAIN_WORLD, {'L', 'A'}}, //LAO PEOPLE'S DEMOCRATIC REPUBLIC + { REGDOMAIN_WORLD, {'L', 'B'}}, //LEBANON + { REGDOMAIN_WORLD, {'L', 'C'}}, //SAINT LUCIA + { REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN + { REGDOMAIN_WORLD, {'L', 'K'}}, //SRI LANKA + { REGDOMAIN_WORLD, {'L', 'R'}}, //LIBERIA + { REGDOMAIN_ETSI, {'L', 'S'}}, //LESOTHO + { REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA + { REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG + { REGDOMAIN_ETSI, {'L', 'V'}}, //LATVIA + { REGDOMAIN_NO_5GHZ, {'L', 'Y'}}, //LIBYAN ARAB JAMAHIRIYA + { REGDOMAIN_APAC, {'M', 'A'}}, //MOROCCO + { REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO + { REGDOMAIN_ETSI, {'M', 'D'}}, //MOLDOVA, REPUBLIC OF + { REGDOMAIN_ETSI, {'M', 'E'}}, //MONTENEGRO + { REGDOMAIN_NO_5GHZ, {'M', 'G'}}, //MADAGASCAR + { REGDOMAIN_WORLD, {'M', 'H'}}, //MARSHALL ISLANDS + { REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF + { REGDOMAIN_NO_5GHZ, {'M', 'L'}}, //MALI + { REGDOMAIN_WORLD, {'M', 'M'}}, //MYANMAR + { REGDOMAIN_WORLD, {'M', 'N'}}, //MONGOLIA + { REGDOMAIN_APAC, {'M', 'O'}}, //MACAO + { REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS + { REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE + { REGDOMAIN_ETSI, {'M', 'R'}}, //MAURITANIA + { REGDOMAIN_ETSI, {'M', 'S'}}, //MONTSERRAT + { REGDOMAIN_ETSI, {'M', 'T'}}, //MALTA + { REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS + { REGDOMAIN_APAC, {'M', 'V'}}, //MALDIVES + { REGDOMAIN_HI_5GHZ, {'M', 'W'}}, //MALAWI + { REGDOMAIN_APAC, {'M', 'X'}}, //MEXICO + { REGDOMAIN_APAC, {'M', 'Y'}}, //MALAYSIA + { REGDOMAIN_WORLD, {'M', 'Z'}}, //MOZAMBIQUE + { REGDOMAIN_WORLD, {'N', 'A'}}, //NAMIBIA + { REGDOMAIN_NO_5GHZ, {'N', 'C'}}, //NEW CALEDONIA + { REGDOMAIN_WORLD, {'N', 'E'}}, //NIGER + { REGDOMAIN_WORLD, {'N', 'F'}}, //NORFOLD ISLAND + { REGDOMAIN_WORLD, {'N', 'G'}}, //NIGERIA + { REGDOMAIN_WORLD, {'N', 'I'}}, //NICARAGUA + { REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS + { REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY + { REGDOMAIN_APAC, {'N', 'P'}}, //NEPAL + { REGDOMAIN_NO_5GHZ, {'N', 'R'}}, //NAURU + { REGDOMAIN_WORLD, {'N', 'U'}}, //NIUE + { REGDOMAIN_APAC, {'N', 'Z'}}, //NEW ZEALAND + { REGDOMAIN_ETSI, {'O', 'M'}}, //OMAN + { REGDOMAIN_APAC, {'P', 'A'}}, //PANAMA + { REGDOMAIN_WORLD, {'P', 'E'}}, //PERU + { REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA + { REGDOMAIN_WORLD, {'P', 'G'}}, //PAPUA NEW GUINEA + { REGDOMAIN_WORLD, {'P', 'H'}}, //PHILIPPINES + { REGDOMAIN_HI_5GHZ, {'P', 'K'}}, //PAKISTAN + { REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND + { REGDOMAIN_WORLD, {'P', 'M'}}, //SAINT PIERRE AND MIQUELON + { REGDOMAIN_WORLD, {'P', 'N'}}, //WORLDPITCAIRN + { REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO + { REGDOMAIN_WORLD, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED + { REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL + { REGDOMAIN_WORLD, {'P', 'W'}}, //PALAU + { REGDOMAIN_WORLD, {'P', 'Y'}}, //PARAGUAY + { REGDOMAIN_HI_5GHZ, {'Q', 'A'}}, //QATAR + { REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION + { REGDOMAIN_ETSI, {'R', 'O'}}, //ROMANIA + { REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA + { REGDOMAIN_APAC, {'R', 'U'}}, //RUSSIA + { REGDOMAIN_WORLD, {'R', 'W'}}, //RWANDA + { REGDOMAIN_WORLD, {'S', 'A'}}, //SAUDI ARABIA + { REGDOMAIN_NO_5GHZ, {'S', 'B'}}, //SOLOMON ISLANDS + { REGDOMAIN_NO_5GHZ, {'S', 'C'}}, //SEYCHELLES + { REGDOMAIN_WORLD, {'S', 'D'}}, //SUDAN + { REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN + { REGDOMAIN_APAC, {'S', 'G'}}, //SINGAPORE + { REGDOMAIN_WORLD, {'S', 'H'}}, //SAINT HELENA + { REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA + { REGDOMAIN_WORLD, {'S', 'J'}}, //SVALBARD AND JAN MAYEN + { REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA + { REGDOMAIN_WORLD, {'S', 'L'}}, //SIERRA LEONE + { REGDOMAIN_ETSI, {'S', 'M'}}, //SAN MARINO + { REGDOMAIN_ETSI, {'S', 'N'}}, //SENEGAL + { REGDOMAIN_NO_5GHZ, {'S', 'O'}}, //SOMALIA + { REGDOMAIN_NO_5GHZ, {'S', 'R'}}, //SURINAME + { REGDOMAIN_WORLD, {'S', 'T'}}, //SAO TOME AND PRINCIPE + { REGDOMAIN_APAC, {'S', 'V'}}, //EL SALVADOR + { REGDOMAIN_NO_5GHZ, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC + { REGDOMAIN_NO_5GHZ, {'S', 'Z'}}, //SWAZILAND + { REGDOMAIN_ETSI, {'T', 'C'}}, //TURKS AND CAICOS ISLANDS + { REGDOMAIN_NO_5GHZ, {'T', 'D'}}, //CHAD + { REGDOMAIN_ETSI, {'T', 'F'}}, //FRENCH SOUTHERN TERRITORIES + { REGDOMAIN_NO_5GHZ, {'T', 'G'}}, //TOGO + { REGDOMAIN_WORLD, {'T', 'H'}}, //THAILAND + { REGDOMAIN_NO_5GHZ, {'T', 'J'}}, //TAJIKISTAN + { REGDOMAIN_WORLD, {'T', 'K'}}, //TOKELAU + { REGDOMAIN_WORLD, {'T', 'L'}}, //TIMOR-LESTE + { REGDOMAIN_NO_5GHZ, {'T', 'M'}}, //TURKMENISTAN + { REGDOMAIN_N_AMER_EXC_FCC, {'T', 'N'}}, //TUNISIA + { REGDOMAIN_NO_5GHZ, {'T', 'O'}}, //TONGA + { REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY + { REGDOMAIN_WORLD, {'T', 'T'}}, //TRINIDAD AND TOBAGO + { REGDOMAIN_NO_5GHZ, {'T', 'V'}}, //TUVALU + { REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PROVINCE OF CHINA + { REGDOMAIN_HI_5GHZ, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF + { REGDOMAIN_WORLD, {'U', 'A'}}, //UKRAINE + { REGDOMAIN_KOREA, {'U', 'G'}}, //UGANDA + { REGDOMAIN_FCC, {'U', 'M'}}, //UNITED STATES MINOR OUTLYING ISLANDS + { REGDOMAIN_WORLD, {'U', 'Y'}}, //URUGUAY + { REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN + { REGDOMAIN_ETSI, {'V', 'A'}}, //HOLY SEE (VATICAN CITY STATE) + { REGDOMAIN_WORLD, {'V', 'C'}}, //SAINT VINCENT AND THE GRENADINES + { REGDOMAIN_HI_5GHZ, {'V', 'E'}}, //VENEZUELA + { REGDOMAIN_ETSI, {'V', 'G'}}, //VIRGIN ISLANDS, BRITISH + { REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US + { REGDOMAIN_FCC, {'V', 'N'}}, //VIET NAM + { REGDOMAIN_NO_5GHZ, {'V', 'U'}}, //VANUATU + { REGDOMAIN_WORLD, {'W', 'F'}}, //WALLIS AND FUTUNA + { REGDOMAIN_N_AMER_EXC_FCC, {'W', 'S'}}, //SOMOA + { REGDOMAIN_NO_5GHZ, {'Y', 'E'}}, //YEMEN + { REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE + { REGDOMAIN_WORLD, {'Z', 'A'}}, //SOUTH AFRICA + { REGDOMAIN_APAC, {'Z', 'M'}}, //ZAMBIA + { REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE + } +}; + +#endif + + +typedef struct nvEFSTable_s +{ + v_U32_t nvValidityBitmap; + sHalNv halnv; +} nvEFSTable_t; +nvEFSTable_t *gnvEFSTable; +/* EFS Table to send the NV structure to HAL*/ +static nvEFSTable_t *pnvEFSTable; +static v_U8_t *pnvEncodedBuf; +static v_U8_t *pnvtmpBuf; +static v_U8_t *pDictFile; +static v_U8_t *pEncodedBuf; +static v_SIZE_t nvReadEncodeBufSize; +static v_SIZE_t nDictionarySize; +static v_U32_t magicNumber; + +/* NV2 specific, No CH 144 support + * For NV_FTM operation, NV2 structure should be maintained + * This will be used only for the NV_FTM operation */ +typedef struct nvEFSTableV2_s +{ + v_U32_t nvValidityBitmap; + sHalNvV2 halnvV2; +} nvEFSTableV2_t; +nvEFSTableV2_t *gnvEFSTableV2; + +const tRfChannelProps rfChannels[NUM_RF_CHANNELS] = +{ + //RF_SUBBAND_2_4_GHZ + //freq, chan#, band + { 2412, 1 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_1, + { 2417, 2 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_2, + { 2422, 3 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_3, + { 2427, 4 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_4, + { 2432, 5 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_5, + { 2437, 6 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_6, + { 2442, 7 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_7, + { 2447, 8 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_8, + { 2452, 9 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_9, + { 2457, 10 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_10, + { 2462, 11 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_11, + { 2467, 12 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_12, + { 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13, + { 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14, + { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240, + { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244, + { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248, + { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252, + { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208, + { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212, + { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216, + { 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36, + { 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40, + { 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44, + { 5240, 48 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_48, + { 5260, 52 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_52, + { 5280, 56 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_56, + { 5300, 60 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_60, + { 5320, 64 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_64, + { 5500, 100, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_100, + { 5520, 104, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_104, + { 5540, 108, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_108, + { 5560, 112, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_112, + { 5580, 116, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_116, + { 5600, 120, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_120, + { 5620, 124, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_124, + { 5640, 128, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_128, + { 5660, 132, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_132, + { 5680, 136, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_136, + { 5700, 140, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + { 5720, 144, RF_SUBBAND_5_MID_GHZ}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + { 5745, 149, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_149, + { 5765, 153, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_153, + { 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157, + { 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161, + { 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165, + { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3, + { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4, + { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5, + { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6, + { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7, + { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8, + { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9, + { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10, + { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11, + { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242, + { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246, + { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250, + { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210, + { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214, + { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38, + { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42, + { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46, + { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50, + { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54, + { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58, + { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62, + { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102, + { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106, + { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110, + { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114, + { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118, + { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122, + { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126, + { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130, + { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134, + { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138, +#ifdef FEATURE_WLAN_CH144 + { 5730, 142, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_142, +#endif /* FEATURE_WLAN_CH144 */ + { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151, + { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155, + { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159, + { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163, +}; + +extern const sHalNv nvDefaults; + +const sRegulatoryChannel * regChannels = nvDefaults.tables.regDomains[0].channels; + + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ +VOS_STATUS wlan_write_to_efs (v_U8_t *pData, v_U16_t data_len); +const char * voss_DomainIdtoString(v_U8_t domainIdCurrent) +{ + switch (domainIdCurrent) + { + CASE_RETURN_STRING( REGDOMAIN_FCC ); + CASE_RETURN_STRING( REGDOMAIN_ETSI ); + CASE_RETURN_STRING( REGDOMAIN_JAPAN ); + CASE_RETURN_STRING( REGDOMAIN_WORLD ); + CASE_RETURN_STRING( REGDOMAIN_N_AMER_EXC_FCC ); + CASE_RETURN_STRING( REGDOMAIN_APAC ); + CASE_RETURN_STRING( REGDOMAIN_KOREA ); + CASE_RETURN_STRING( REGDOMAIN_HI_5GHZ ); + CASE_RETURN_STRING( REGDOMAIN_NO_5GHZ ); + CASE_RETURN_STRING( REGDOMAIN_COUNT ); + default: + return "Regulation Domain Unknown"; + } +} +/**------------------------------------------------------------------------ + \brief vos_nv_init() - initialize the NV module + The \a vos_nv_init() initializes the NV module. This read the binary + file for country code and regulatory domain information. + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_init(void) +{ + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_get_dictionary_data() - get the dictionary data required for + \ tools + \return VOS_STATUS_SUCCESS - dictionary data is read successfully + otherwise - not successful + \sa +-------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_get_dictionary_data(void) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + + if (MAGIC_NUMBER != magicNumber) + { + return VOS_STATUS_SUCCESS; + } + + nDictionarySize = 0; + + vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, NULL, + &nDictionarySize ); + if (VOS_STATUS_E_NOMEM != vosStatus) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Error obtaining binary size" ); +/// NOTE: +/// We can still work without a dictionary file.. + return VOS_STATUS_SUCCESS; + } + + // malloc a buffer to read in the Configuration binary file. + pDictFile = vos_mem_malloc( nDictionarySize ); + if (NULL == pDictFile) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Unable to allocate memory for the CFG binary [size= %d bytes]", + nDictionarySize ); + vosStatus = VOS_STATUS_E_NOMEM; + goto fail; + } + + /* Get the entire CFG file image... */ + vosStatus = vos_get_binary_blob( VOS_BINARY_ID_DICT_CONFIG, pDictFile, + &nDictionarySize ); + if (!VOS_IS_STATUS_SUCCESS( vosStatus )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Error: Cannot retrieve CFG file image from vOSS. [size= %d bytes]", + nDictionarySize ); + return VOS_STATUS_SUCCESS; + } + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "Dict file image from vOSS. [size= %d bytes]", nDictionarySize ); + +fail: + return vosStatus; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_parseV2bin() - Parse NV2 binary + Parse NV2 BIN, and assign contents to common NV structure. + \param pnvEncodedBuf + NV Bin read buffer + \param nvReadBufSize + NV Bin read size + \param halNv + common NV structure storage pointer + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_parseV2bin(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize, + sHalNv *halNv) +{ + sHalNvV2 *nv2Table; + tANI_U16 copyLoop; + tANI_U16 channelLoop; + void *targetPtr; + void *sourcePtr; + + v_U32_t structSize = 0; + + nv2Table = (sHalNvV2 *)pnvEncodedBuf; + /* NV Field Default Copy */ + vos_mem_copy((char *)&halNv->fields, + (char *)&nv2Table->fields, + sizeof(sNvFields)); + structSize += sizeof(sNvFields); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(sNvFields) %zu, structSize %d", + __func__, sizeof(sNvFields), structSize); + + /* NV Table, tRateGroupPwr, NOT depends on channel count */ + vos_mem_copy((char *)halNv->tables.pwrOptimum, + (char *)nv2Table->tables.pwrOptimum, + sizeof(halNv->tables.pwrOptimum)); + structSize += sizeof(halNv->tables.pwrOptimum); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.pwrOptimum) %zu, structSize %d", + __func__, sizeof(halNv->tables.pwrOptimum), structSize); + + /* NV Table, regDomains, edepends on channel count */ + for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++) + { + vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].antennaGain, + (char *)nv2Table->tables.regDomains[copyLoop].antennaGain, + sizeof(halNv->tables.regDomains[copyLoop].antennaGain)); + structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain); + + vos_mem_copy((char *)halNv->tables.regDomains[copyLoop].bRatePowerOffset, + (char *)nv2Table->tables.regDomains[copyLoop].bRatePowerOffset, + sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset)); + structSize += sizeof(halNv->tables.regDomains[copyLoop].bRatePowerOffset); + } + + for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++) + { + targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].channels[0]); + sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].channels[0]); + /* Cannot blindly copy + * Each single CH should be assigned */ + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + /* NV2 CH144 is disabled */ + halNv->tables.regDomains[copyLoop].channels[channelLoop].enabled = + NV_CHANNEL_DISABLE; + targetPtr = targetPtr + sizeof(sRegulatoryChannel); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + + vos_mem_copy(targetPtr, sourcePtr, sizeof(sRegulatoryChannel)); + targetPtr = targetPtr + sizeof(sRegulatoryChannel); + sourcePtr = sourcePtr + sizeof(sRegulatoryChannel); + structSize += sizeof(halNv->tables.regDomains[copyLoop].antennaGain); + } + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.regDomains[copyLoop].antennaGain) %zu, structSize %d", + __func__, sizeof(halNv->tables.regDomains[copyLoop].antennaGain), structSize); + + for (copyLoop = 0; copyLoop < NUM_REG_DOMAINS; copyLoop++) + { + targetPtr = (char *)&(halNv->tables.regDomains[copyLoop].gnRatePowerOffset[0]); + sourcePtr = (char *)&(nv2Table->tables.regDomains[copyLoop].gnRatePowerOffset[0]); + /* Cannot blindly copy + * Each single CH should be assigned */ + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(uAbsPwrPrecision); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(uAbsPwrPrecision)); + targetPtr = targetPtr + sizeof(uAbsPwrPrecision); + sourcePtr = sourcePtr + sizeof(uAbsPwrPrecision); + structSize += sizeof(sizeof(uAbsPwrPrecision)); + } + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(uAbsPwrPrecision) %zu, structSize %d", + __func__, sizeof(uAbsPwrPrecision), structSize); + + /* nvTable, defaultCountryTable, NOT depends on channel counts */ + vos_mem_copy((char *)&halNv->tables.defaultCountryTable, + (char *)&nv2Table->tables.defaultCountryTable, + sizeof(halNv->tables.defaultCountryTable)); + structSize += sizeof(halNv->tables.defaultCountryTable); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.defaultCountryTable) %zu, structSize %d", + __func__, sizeof(halNv->tables.defaultCountryTable), structSize); + + /* NV Table, plutCharacterized, depends on channel count + * Cannot blindly copy + * Each single CH should be assigned */ + targetPtr = (char *)&(halNv->tables.plutCharacterized[0]); + sourcePtr = (char *)&(nv2Table->tables.plutCharacterized[0]); + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(tTpcPowerTable); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(tTpcPowerTable)); + targetPtr = targetPtr + sizeof(tTpcPowerTable); + sourcePtr = sourcePtr + sizeof(tTpcPowerTable); + structSize += sizeof(tTpcPowerTable); + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(tTpcPowerTable) %zu, structSize %d", + __func__, sizeof(tTpcPowerTable), structSize); + + /* NV Table, plutPdadcOffset, depends on channel count + * Cannot blindly copy + * Each single CH should be assigned */ + targetPtr = (char *)&(halNv->tables.plutPdadcOffset[0]); + sourcePtr = (char *)&(nv2Table->tables.plutPdadcOffset[0]); + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(int16); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(int16)); + targetPtr = targetPtr + sizeof(int16); + sourcePtr = sourcePtr + sizeof(int16); + structSize += sizeof(int16); + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.plutPdadcOffset) %zu, structSize %d", + __func__, sizeof(int16), structSize); + + /* NV Table, pwrOptimum_virtualRate, NOT depends on channel count */ + vos_mem_copy((char *)halNv->tables.pwrOptimum_virtualRate, + (char *)nv2Table->tables.pwrOptimum_virtualRate, + sizeof(halNv->tables.pwrOptimum_virtualRate)); + structSize += sizeof(halNv->tables.pwrOptimum_virtualRate); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.pwrOptimum_virtualRate) %zu, structSize %d", + __func__, sizeof(halNv->tables.pwrOptimum_virtualRate), structSize); + + /* NV Table, fwConfig, NOT depends on channel count */ + vos_mem_copy((char *)&halNv->tables.fwConfig, + (char *)&nv2Table->tables.fwConfig, + sizeof(halNv->tables.fwConfig)); + structSize += sizeof(halNv->tables.fwConfig); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.fwConfig) %zu, structSize %d", + __func__, sizeof(halNv->tables.fwConfig), structSize); + + /* NV Table, rssiChanOffsets, depends on channel count + * Cannot blindly copy + * Each single CH should be assigned */ + for (copyLoop = 0; copyLoop < 2; copyLoop++) + { + targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]); + sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].bRssiOffset[0]); + /* Cannot blindly copy + * Each single CH should be assigned */ + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(int16); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(int16)); + targetPtr = targetPtr + sizeof(int16); + sourcePtr = sourcePtr + sizeof(int16); + structSize += sizeof(int16); + } + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d", + __func__, sizeof(int16), structSize); + + for (copyLoop = 0; copyLoop < 2; copyLoop++) + { + targetPtr = (char *)&(halNv->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]); + sourcePtr = (char *)&(nv2Table->tables.rssiChanOffsets[copyLoop].gnRssiOffset[0]); + /* Cannot blindly copy + * Each single CH should be assigned */ + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(int16); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(int16)); + targetPtr = targetPtr + sizeof(int16); + sourcePtr = sourcePtr + sizeof(int16); + structSize += sizeof(int16); + } + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(tables.rssiChanOffsets) %zu, structSize %d", + __func__, sizeof(int16), structSize); + + /* NV Table, hwCalValues, NOT depends on channel count */ + vos_mem_copy((char *)&halNv->tables.hwCalValues, + (char *)&nv2Table->tables.hwCalValues, + sizeof(halNv->tables.hwCalValues)); + structSize += sizeof(halNv->tables.fwConfig); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.hwCalValues) %zu, structSize %d", + __func__, sizeof(halNv->tables.hwCalValues), structSize); + + /* NV Table, antennaPathLoss, depends on channel count + * Cannot blindly copy + * Each single CH should be assigned */ + targetPtr = (char *)&(halNv->tables.antennaPathLoss[0]); + sourcePtr = (char *)&(nv2Table->tables.antennaPathLoss[0]); + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(int16); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(int16)); + targetPtr = targetPtr + sizeof(int16); + sourcePtr = sourcePtr + sizeof(int16); + structSize += sizeof(int16); + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.antennaPathLoss) %zu, structSize %d", + __func__, sizeof(int16), structSize); + + /* NV Table, pktTypePwrLimits, depends on channel count + * Cannot blindly copy + * Each single CH should be assigned */ + for (copyLoop = 0; copyLoop < NUM_802_11_MODES; copyLoop++) + { + targetPtr = (char *)&(halNv->tables.pktTypePwrLimits[copyLoop][0]); + sourcePtr = (char *)&(nv2Table->tables.pktTypePwrLimits[copyLoop][0]); + /* Cannot blindly copy + * Each single CH should be assigned */ + for (channelLoop = 0; channelLoop < NUM_RF_CHANNELS; channelLoop++) + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == channelLoop) || (RF_CHAN_BOND_142 == channelLoop)) + { + targetPtr = targetPtr + sizeof(int16); + } + else +#endif /* FEATURE_WLAN_CH144 */ + { + vos_mem_copy(targetPtr, sourcePtr, sizeof(int16)); + targetPtr = targetPtr + sizeof(int16); + sourcePtr = sourcePtr + sizeof(int16); + structSize += sizeof(int16); + } + } + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.pktTypePwrLimits) %zu, structSize %d", + __func__, sizeof(int16), structSize); + + /* NV Table, ofdmCmdPwrOffset, NOT depends on channel count */ + vos_mem_copy((char *)&halNv->tables.ofdmCmdPwrOffset, + (char *)&nv2Table->tables.ofdmCmdPwrOffset, + sizeof(halNv->tables.ofdmCmdPwrOffset)); + structSize += sizeof(halNv->tables.ofdmCmdPwrOffset); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.ofdmCmdPwrOffset) %zu, structSize %d", + __func__, sizeof(halNv->tables.ofdmCmdPwrOffset), structSize); + + /* NV Table, txbbFilterMode, NOT depends on channel count */ + vos_mem_copy((char *)&halNv->tables.txbbFilterMode, + (char *)&nv2Table->tables.txbbFilterMode, + sizeof(halNv->tables.txbbFilterMode)); + structSize += sizeof(halNv->tables.ofdmCmdPwrOffset); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: sizeof(halNv->tables.txbbFilterMode) %zu, structSize %d", + __func__, sizeof(halNv->tables.txbbFilterMode), structSize); + + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_open() - Open NV operation + Read NV bin file and prepare NV common structure + \return VOS_STATUS_SUCCESS - module is initialized successfully + otherwise - module is not initialized + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_open(void) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_CONTEXT_t pVosContext= NULL; + v_SIZE_t bufSize; + v_SIZE_t nvReadBufSize; + v_BOOL_t itemIsValid = VOS_FALSE; + v_U32_t dataOffset; + sHalNv *pnvData = NULL; + hdd_context_t *pHddCtx = NULL; + + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL == pVosContext) + { + return (eHAL_STATUS_FAILURE); + } + + status = hdd_request_firmware(WLAN_NV_FILE, + ((VosContextType*)(pVosContext))->pHDDContext, + (v_VOID_t**)&pnvtmpBuf, &nvReadBufSize); + + if ((!VOS_IS_STATUS_SUCCESS( status )) || (!pnvtmpBuf)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: unable to download NV file %s", + __func__, WLAN_NV_FILE); + return VOS_STATUS_E_RESOURCES; + } + + pnvEncodedBuf = (v_U8_t *)vos_mem_vmalloc(nvReadBufSize); + + if (NULL == pnvEncodedBuf) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(pnvEncodedBuf, pnvtmpBuf, nvReadBufSize); + release_firmware(((hdd_context_t*)((VosContextType*) + (pVosContext))->pHDDContext)->nv); + + vos_mem_copy(&magicNumber, &pnvEncodedBuf[sizeof(v_U32_t)], sizeof(v_U32_t)); + + /// Allocate buffer with maximum length.. + pEncodedBuf = (v_U8_t *)vos_mem_vmalloc(nvReadBufSize); + + if (NULL == pEncodedBuf) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + vos_mem_vfree(pnvEncodedBuf); + return VOS_STATUS_E_NOMEM; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "NV Table Size %zu", sizeof(nvEFSTable_t)); + + pnvEFSTable = (nvEFSTable_t *)vos_mem_vmalloc(sizeof(nvEFSTable_t)); + if (NULL == pnvEFSTable) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + vos_mem_vfree(pnvEncodedBuf); + vos_mem_vfree(pEncodedBuf); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero((void *)pnvEFSTable, sizeof(nvEFSTable_t)); + + // Default NV version, NOT_VALID + ((VosContextType*)(pVosContext))->nvVersion = E_NV_INVALID; + if (MAGIC_NUMBER == magicNumber) + { + bufSize = sizeof(nvEFSTable_t); + gnvEFSTable = (nvEFSTable_t*)pnvEncodedBuf; + pnvData = (sHalNv *)vos_mem_malloc(sizeof(sHalNv)); + + if (NULL == pnvData) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + vos_mem_vfree(pnvEncodedBuf); + vos_mem_vfree(pEncodedBuf); + vos_mem_vfree(pnvEFSTable); + return VOS_STATUS_E_NOMEM; + } + + memset(pnvData, 0, sizeof(sHalNv)); + + /// Data starts from offset of validity bit map + magic number.. + dataOffset = sizeof(v_U32_t) + sizeof(v_U32_t); + + status = nvParser(&pnvEncodedBuf[dataOffset], + (nvReadBufSize-dataOffset), pnvData); + + ///ignore validity bit map + nvReadEncodeBufSize = nvReadBufSize - sizeof(v_U32_t); + + vos_mem_copy(pEncodedBuf, &pnvEncodedBuf[sizeof(v_U32_t)], + nvReadEncodeBufSize); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "readEncodeBufSize %d",nvReadEncodeBufSize); + + if (VOS_STATUS_SUCCESS == status) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "Embedded NV parsed success !!productId %d couple Type %d wlan RevId %d", + pnvData->fields.productId, + pnvData->fields.couplerType, + pnvData->fields.wlanNvRevId); + + vos_mem_copy(&gnvEFSTable->halnv, pnvData, sizeof(sHalNv)); + + nvReadBufSize = sizeof(sHalNv) + sizeof(v_U32_t); + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "nvParser failed %d",status); + + if (nvReadBufSize != sizeof(sHalNv)) { + vos_mem_vfree(pEncodedBuf); + pEncodedBuf = (v_U8_t *)vos_mem_vmalloc(sizeof(sHalNv)); + + if (!pEncodedBuf) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + vos_mem_free(pnvData); + vos_mem_vfree(pnvEncodedBuf); + vos_mem_vfree(pnvEFSTable); + return VOS_STATUS_E_NOMEM; + } + } + + nvReadBufSize = 0; + + vos_mem_copy(pEncodedBuf, &nvDefaults, sizeof(sHalNv)); + + nvReadEncodeBufSize = sizeof(sHalNv); + } + vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv)); + + /* NV verion is NV3 */ + ((VosContextType*)(pVosContext))->nvVersion = E_NV_V3; + } + else + { + bufSize = sizeof(nvEFSTableV2_t); + + /*Copying the NV defaults */ + vos_mem_copy(&(pnvEFSTable->halnv), &nvDefaults, sizeof(sHalNv)); + /* NV2 structure should be maintained to support NV_FTM */ + gnvEFSTableV2 = (nvEFSTableV2_t * )pnvEncodedBuf; + + /* Size mismatch + * NV 1 case, use default NV table */ + if (nvReadBufSize != bufSize) + { + pnvEFSTable->nvValidityBitmap = DEFAULT_NV_VALIDITY_BITMAP; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Size mismatch INVALID NV FILE %d %d!!!", + nvReadBufSize, bufSize); + vos_mem_vfree(pnvEncodedBuf); + vos_mem_vfree(pEncodedBuf); + vos_mem_vfree(pnvEFSTable); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "NV_2: readBufferSize %u, EFSV2DefaultSize %zu", + nvReadBufSize, sizeof(nvEFSTableV2_t)); + + /* From here, NV2 will be stored into NV3 structure */ + dataOffset = sizeof(v_U32_t); + nvReadEncodeBufSize = sizeof(sHalNvV2); + if (nvReadBufSize != nvReadEncodeBufSize) + { + vos_mem_vfree(pEncodedBuf); + pEncodedBuf = (v_U8_t *)vos_mem_vmalloc(nvReadEncodeBufSize); + if (!pEncodedBuf) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : failed to allocate memory for NV", __func__); + vos_mem_vfree(pnvEncodedBuf); + vos_mem_vfree(pnvEFSTable); + return VOS_STATUS_E_NOMEM; + } + } + vos_mem_copy(pEncodedBuf, + &pnvEncodedBuf[dataOffset], + nvReadBufSize - dataOffset); + +#ifdef FEATURE_WLAN_CH144 + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "Default NV2 size %zu", sizeof(nvDefaultsV2)); +#else + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "Default NV2 size %zu", sizeof(nvDefaults)); +#endif /* FEATURE_WLAN_CH144 */ + /* First assign value with NV default */ +#ifdef FEATURE_WLAN_CH144 + vos_nv_parseV2bin((tANI_U8 *)&nvDefaultsV2, + sizeof(sHalNvV2), + &pnvEFSTable->halnv); +#else + vos_nv_parseV2bin((tANI_U8 *)&nvDefaults, + sizeof(sHalNvV2), + &pnvEFSTable->halnv); +#endif /* FEATURE_WLAN_CH144 */ + + /* Actual update from NV.bin */ + vos_nv_parseV2bin(pEncodedBuf, + nvReadEncodeBufSize, + &pnvEFSTable->halnv); + + vos_mem_copy((void *)&pnvEFSTable->nvValidityBitmap, + pnvEncodedBuf, sizeof(v_U32_t)); + gnvEFSTable = pnvEFSTable; + + /* NV verion is NV2 */ + ((VosContextType*)(pVosContext))->nvVersion = E_NV_V2; + } + + if (NULL != pnvData) + { + vos_mem_free(pnvData); + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "INFO: NV version = %d is loaded, driver supports NV version = %d", + gnvEFSTable->halnv.fields.nvVersion, WLAN_NV_VERSION); + + /* Copying the read nv data to the globa NV EFS table */ + { + /* Version mismatch */ + if (gnvEFSTable->halnv.fields.nvVersion != WLAN_NV_VERSION) + { + if ((WLAN_NV_VERSION == NV_VERSION_11N_11AC_FW_CONFIG) && + (gnvEFSTable->halnv.fields.nvVersion == NV_VERSION_11N_11AC_COUPER_TYPE)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "INFO: Using Coupler Type field instead of FW Config table, " + "make sure that this is intended or may impact performance."); + } +#ifdef FEATURE_WLAN_CH144 + else if ((WLAN_NV_VERSION == NV_VERSION_CH144_CONFIG) && + (((VosContextType*)(pVosContext))->nvVersion == E_NV_V2)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "INFO: Driver supports NV3 CH144 by default, " + "NV2 is currently loaded, NV2 will be used."); + } +#endif /* FEATURE_WLAN_CH144 */ + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "INFO: NV loaded doesn't match with driver default NV, " + "driver default NV will be used, may impact performance."); + + return VOS_STATUS_SUCCESS; + } + } + + pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap; + /* Copy the valid fields to the NV Global structure */ + if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) { + + if(vos_nv_read( VNV_FIELD_IMAGE, (v_VOID_t *)&pnvEFSTable->halnv.fields, + NULL, sizeof(sNvFields) ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_RATE_TO_POWER_TABLE, + (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0], + NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE, + (v_VOID_t *)&pnvEFSTable->halnv.tables.regDomains[0], + NULL, sizeof(sRegulatoryDomains) * NUM_REG_DOMAINS ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_DEFAULT_LOCATION, + (v_VOID_t *)&pnvEFSTable->halnv.tables.defaultCountryTable, + NULL, sizeof(sDefaultCountry) ) != VOS_STATUS_SUCCESS) + goto error; + } + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) + { + if (!vos_mem_compare(pHddCtx->cfg_ini->overrideCountryCode, + CFG_OVERRIDE_COUNTRY_CODE_DEFAULT, 3)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Overriding NV Country(%c%c) from INI (%c%c)"), + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0], + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1], + pHddCtx->cfg_ini->overrideCountryCode[0], + pHddCtx->cfg_ini->overrideCountryCode[1]); + vos_mem_copy(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode, + pHddCtx->cfg_ini->overrideCountryCode, + 3); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + } + + if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_TPC_POWER_TABLE, + (v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0], + NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_TPC_PDADC_OFFSETS, + (v_VOID_t *)&pnvEFSTable->halnv.tables.plutPdadcOffset[0], + NULL, sizeof(tANI_U16) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS) + goto error; + } + } + if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_RSSI_CHANNEL_OFFSETS, + (v_VOID_t *)&pnvEFSTable->halnv.tables.rssiChanOffsets[0], + NULL, sizeof(sRssiChannelOffsets) * 2 ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_HW_CAL_VALUES, (v_VOID_t *)&pnvEFSTable->halnv + .tables.hwCalValues, NULL, sizeof(sHwCalValues) ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_FW_CONFIG, (v_VOID_t *)&pnvEFSTable->halnv + .tables.fwConfig, NULL, sizeof(sFwConfig) ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_ANTENNA_PATH_LOSS, + (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL, + sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS) + goto error; + } + } + if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS, + (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL, + sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET, + (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL, + sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS) + goto error; + } + } + + if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read(VNV_TX_BB_FILTER_MODE, + (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL, + sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS) + goto error; + } + } + if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) == + VOS_STATUS_SUCCESS) + { + if (itemIsValid == VOS_TRUE) + { + if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE, + (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL, + sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS) + goto error; + } + } + } + + return VOS_STATUS_SUCCESS; +error: + vos_mem_vfree(pnvEFSTable); + vos_mem_vfree(pEncodedBuf); + vos_mem_vfree(pnvEncodedBuf); + return eHAL_STATUS_FAILURE ; +} + +VOS_STATUS vos_nv_close(void) +{ + v_CONTEXT_t pVosContext= NULL; + /*Get the global context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + ((hdd_context_t*)((VosContextType*)(pVosContext))->pHDDContext)->nv = NULL; + vos_mem_vfree(pnvEFSTable); + vos_mem_vfree(pEncodedBuf); + vos_mem_free(pDictFile); + vos_mem_vfree(pnvEncodedBuf); + /* + * Reset the linux_reg identifier to allow + * driver to send fresh regulatory hint to + * the kernel in case of a static driver reload + * under strict regulatory domain. + */ + linux_reg_cc[0] = '0'; + linux_reg_cc[1] = '0'; + + gnvEFSTable=NULL; + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getSupportedCountryCode() - get the list of supported + country codes + The \a vos_nv_getSupportedCountryCode() encodes the list of supported + country codes with paddings in the provided buffer + \param pBuffer - pointer to buffer where supported country codes + and paddings are encoded; this may be set to NULL + if user wishes to query the required buffer size to + get the country code list + \param pBufferSize - this is the provided buffer size on input; + this is the required or consumed buffer size on output + \return VOS_STATUS_SUCCESS - country codes are successfully encoded + VOS_STATUS_E_NOMEM - country codes are not encoded because either + the buffer is NULL or buffer size is + sufficient + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize, + v_SIZE_t paddingSize ) +{ + v_SIZE_t providedBufferSize = *pBufferSize; + int i; + // pBufferSize now points to the required buffer size + *pBufferSize = countryInfoTable.countryCount * (VOS_COUNTRY_CODE_LEN + paddingSize ); + if ( NULL == pBuffer || providedBufferSize < *pBufferSize ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("Insufficient memory for country code list")); + return VOS_STATUS_E_NOMEM; + } + for (i = 0; i < countryInfoTable.countryCount; i++) + { + vos_mem_copy( pBuffer, countryInfoTable.countryInfo[i].countryCode, VOS_COUNTRY_CODE_LEN ); + pBuffer += (VOS_COUNTRY_CODE_LEN + paddingSize ); + } + return VOS_STATUS_SUCCESS; +} +/**------------------------------------------------------------------------ + \brief vos_nv_readTxAntennaCount() - return number of TX antenna + \param pTxAntennaCount - antenna count + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readTxAntennaCount( v_U8_t *pTxAntennaCount ) +{ + sNvFields fieldImage; + VOS_STATUS status; + status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL, + sizeof(fieldImage) ); + if (VOS_STATUS_SUCCESS == status) + { + *pTxAntennaCount = fieldImage.numOfTxChains; + } + return status; +} +/**------------------------------------------------------------------------ + \brief vos_nv_readRxAntennaCount() - return number of RX antenna + \param pRxAntennaCount - antenna count + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readRxAntennaCount( v_U8_t *pRxAntennaCount ) +{ + sNvFields fieldImage; + VOS_STATUS status; + status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL, + sizeof(fieldImage) ); + if (VOS_STATUS_SUCCESS == status) + { + *pRxAntennaCount = fieldImage.numOfRxChains; + } + return status; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_readMacAddress() - return the MAC address + \param pMacAddress - MAC address + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readMacAddress( v_MAC_ADDRESS_t pMacAddress ) +{ + sNvFields fieldImage; + VOS_STATUS status; + status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL, + sizeof(fieldImage) ); + if (VOS_STATUS_SUCCESS == status) + { + vos_mem_copy( pMacAddress, fieldImage.macAddr, VOS_MAC_ADDRESS_LEN ); + } + else + { + //This part of the code can be removed when NV is programmed + const v_U8_t macAddr[VOS_MAC_ADDRESS_LEN] = VOS_HARD_CODED_MAC; + vos_mem_copy( pMacAddress, macAddr, VOS_MAC_ADDRESS_LEN ); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "fail to get MAC address from NV, hardcoded to "MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(macAddr)); + status = VOS_STATUS_SUCCESS; + } + return status; +} + +/**------------------------------------------------------------------------ + + \brief vos_nv_readMultiMacAddress() - return the Multiple MAC addresses + + \param pMacAddress - MAC address + \param macCount - Count of valid MAC addresses to get from NV field + + \return status of the NV read operation + + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readMultiMacAddress( v_U8_t *pMacAddress, + v_U8_t macCount ) +{ + sNvFields fieldImage; + VOS_STATUS status; + v_U8_t countLoop; + v_U8_t *pNVMacAddress; + + if((0 == macCount) || (VOS_MAX_CONCURRENCY_PERSONA < macCount) || + (NULL == pMacAddress)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + " Invalid Parameter from NV Client macCount %d, pMacAddress %p", + macCount, pMacAddress); + } + + status = vos_nv_read( VNV_FIELD_IMAGE, &fieldImage, NULL, + sizeof(fieldImage) ); + if (VOS_STATUS_SUCCESS == status) + { + pNVMacAddress = fieldImage.macAddr; + for(countLoop = 0; countLoop < macCount; countLoop++) + { + vos_mem_copy(pMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN), + pNVMacAddress + (countLoop * VOS_MAC_ADDRESS_LEN), + VOS_MAC_ADDRESS_LEN); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_readMultiMacAddress Get NV Field Fail"); + } + + return status; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_setValidity() - set the validity of an NV item. + The \a vos_nv_setValidity() validates and invalidates an NV item. The + validity information is stored in NV memory. + One would get the VOS_STATUS_E_EXISTS error when reading an invalid item. + An item becomes valid when one has written to it successfully. + \param type - NV item type + \param itemIsValid - boolean value indicating the item's validity + \return VOS_STATUS_SUCCESS - validity is set successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAILURE - unknown error + \sa + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_nv_setValidity( VNV_TYPE type, v_BOOL_t itemIsValid ) +{ + v_U32_t lastNvValidityBitmap; + v_U32_t newNvValidityBitmap; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + // check if the current NV type is valid + if (VNV_TYPE_COUNT <= type) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s: invalid type=%d"), __func__, type ); + return VOS_STATUS_E_INVAL; + } + // read the validity bitmap + lastNvValidityBitmap = gnvEFSTable->nvValidityBitmap; + // modify the validity bitmap + if (itemIsValid) + { + newNvValidityBitmap = lastNvValidityBitmap | (1 << type); + // commit to NV store if bitmap has been modified + if (newNvValidityBitmap != lastNvValidityBitmap) + { + gnvEFSTable->nvValidityBitmap = newNvValidityBitmap; + } + } + else + { + newNvValidityBitmap = lastNvValidityBitmap & (~(1 << type)); + if (newNvValidityBitmap != lastNvValidityBitmap) + { + gnvEFSTable->nvValidityBitmap = newNvValidityBitmap; + status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t)); + if (! VOS_IS_STATUS_SUCCESS(status)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!")); + status = VOS_STATUS_E_FAULT; + } + } + } + + return status; +} +/**------------------------------------------------------------------------ + \brief vos_nv_getValidity() - get the validity of an NV item. + The \a vos_nv_getValidity() indicates if an NV item is valid. The + validity information is stored in NV memory. + One would get the VOS_STATUS_E_EXISTS error when reading an invalid item. + An item becomes valid when one has written to it successfully. + \param type - NV item type + \param pItemIsValid- pointer to the boolean value indicating the item's + validity + \return VOS_STATUS_SUCCESS - validity is determined successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAILURE - unknown error + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getValidity( VNV_TYPE type, v_BOOL_t *pItemIsValid ) +{ + v_U32_t nvValidityBitmap = gnvEFSTable->nvValidityBitmap; + // check if the current NV type is valid + if (VNV_TYPE_COUNT <= type) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s: invalid type=%d"), __func__, type ); + return VOS_STATUS_E_INVAL; + } + *pItemIsValid = (v_BOOL_t)((nvValidityBitmap >> type) & 1); + return VOS_STATUS_SUCCESS; +} +/**------------------------------------------------------------------------ + \brief vos_nv_read() - read a NV item to an output buffer + The \a vos_nv_read() reads a NV item to an output buffer. If the item is + an array, this function would read the entire array. One would get a + VOS_STATUS_E_EXISTS error when reading an invalid item. + For error conditions of VOS_STATUS_E_EXISTS and VOS_STATUS_E_FAILURE, + if a default buffer is provided (with a non-NULL value), + the default buffer content is copied to the output buffer. + \param type - NV item type + \param outputBuffer - output buffer + \param defaultBuffer - default buffer + \param bufferSize - output buffer size + \return VOS_STATUS_SUCCESS - NV item is read successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAULT - defaultBuffer point is NULL + VOS_STATUS_E_EXISTS - NV type is unsupported + VOS_STATUS_E_FAILURE - unknown error + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_read( VNV_TYPE type, v_VOID_t *outputVoidBuffer, + v_VOID_t *defaultBuffer, v_SIZE_t bufferSize ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SIZE_t itemSize; + v_BOOL_t itemIsValid = VOS_TRUE; + + // sanity check + if (VNV_TYPE_COUNT <= type) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s: invalid type=%d"), __func__, type ); + return VOS_STATUS_E_INVAL; + } + if (NULL == outputVoidBuffer) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Buffer provided is NULL") ); + return VOS_STATUS_E_FAULT; + } + if (0 == bufferSize) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("NV type=%d is invalid"), type ); + return VOS_STATUS_E_INVAL; + } + // check if the NV item has valid data + status = vos_nv_getValidity( type, &itemIsValid ); + if (!itemIsValid) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "NV type=%d does not have valid data", type ); + return VOS_STATUS_E_EMPTY; + } + switch(type) + { + case VNV_FIELD_IMAGE: + itemSize = sizeof(gnvEFSTable->halnv.fields); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.fields,bufferSize); + } + break; + case VNV_RATE_TO_POWER_TABLE: + itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum[0],bufferSize); + } + break; + case VNV_REGULARTORY_DOMAIN_TABLE: + itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.regDomains[0],bufferSize); + } + break; + case VNV_DEFAULT_LOCATION: + itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.defaultCountryTable,bufferSize); + } + break; + case VNV_TPC_POWER_TABLE: + itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutCharacterized[0],bufferSize); + } + break; + case VNV_TPC_PDADC_OFFSETS: + itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.plutPdadcOffset[0],bufferSize); + } + break; + case VNV_RSSI_CHANNEL_OFFSETS: + + itemSize = sizeof(gnvEFSTable->halnv.tables.rssiChanOffsets); + + if(bufferSize != itemSize) { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.rssiChanOffsets[0],bufferSize); + } + break; + case VNV_HW_CAL_VALUES: + + itemSize = sizeof(gnvEFSTable->halnv.tables.hwCalValues); + + if(bufferSize != itemSize) { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.hwCalValues,bufferSize); + } + break; + case VNV_FW_CONFIG: + + itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig); + + if(bufferSize != itemSize) { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.fwConfig,bufferSize); + } + break; + case VNV_ANTENNA_PATH_LOSS: + itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.antennaPathLoss[0],bufferSize); + } + break; + case VNV_PACKET_TYPE_POWER_LIMITS: + itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,gnvEFSTable->halnv.tables.pktTypePwrLimits,bufferSize); + } + break; + case VNV_OFDM_CMD_PWR_OFFSET: + itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.ofdmCmdPwrOffset,bufferSize); + } + break; + case VNV_TX_BB_FILTER_MODE: + itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.txbbFilterMode,bufferSize); + } + break; + + + case VNV_TABLE_VIRTUAL_RATE: + itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate); + if(bufferSize != itemSize) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize, + itemSize); + status = VOS_STATUS_E_INVAL; + } + else { + vos_mem_copy(outputVoidBuffer,&gnvEFSTable->halnv.tables.pwrOptimum_virtualRate,bufferSize); + } + break; + + default: + break; + } + return status; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_write() - write to a NV item from an input buffer + The \a vos_nv_write() writes to a NV item from an input buffer. This would + validate the NV item if the write operation is successful. + NV2 dedicated operation + \param type - NV item type + \param inputBuffer - input buffer + \param inputBufferSize - input buffer size + \return VOS_STATUS_SUCCESS - NV item is read successfully + VOS_STATUS_E_INVAL - one of the parameters is invalid + VOS_STATUS_E_FAULT - outputBuffer pointer is NULL + VOS_STATUS_E_EXISTS - NV type is unsupported + VOS_STATUS_E_FAILURE - unknown error + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_write(VNV_TYPE type, v_VOID_t *inputVoidBuffer, + v_SIZE_t bufferSize) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_SIZE_t itemSize; + + // sanity check + if (VNV_TYPE_COUNT <= type) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: invalid type=%d", __func__, type); + return VOS_STATUS_E_INVAL; + } + if (NULL == inputVoidBuffer) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "Buffer provided is NULL"); + return VOS_STATUS_E_FAULT; + } + if (0 == bufferSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "NV type=%d is invalid", type); + return VOS_STATUS_E_INVAL; + } + + switch (type) + { + case VNV_FIELD_IMAGE: + itemSize = sizeof(gnvEFSTableV2->halnvV2.fields); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.fields, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_RATE_TO_POWER_TABLE: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize,itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum[0], + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_REGULARTORY_DOMAIN_TABLE: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.regDomains); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.regDomains[0], + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_DEFAULT_LOCATION: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.defaultCountryTable); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.defaultCountryTable, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_TPC_POWER_TABLE: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutCharacterized); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.plutCharacterized[0], + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_TPC_PDADC_OFFSETS: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.plutPdadcOffset); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.plutPdadcOffset[0], + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_RSSI_CHANNEL_OFFSETS: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.rssiChanOffsets); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.rssiChanOffsets[0], + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_HW_CAL_VALUES: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.hwCalValues); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.hwCalValues, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_FW_CONFIG: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.fwConfig); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.fwConfig, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_ANTENNA_PATH_LOSS: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.antennaPathLoss); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.antennaPathLoss[0], + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_PACKET_TYPE_POWER_LIMITS: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(gnvEFSTableV2->halnvV2.tables.pktTypePwrLimits, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_OFDM_CMD_PWR_OFFSET: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.ofdmCmdPwrOffset, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_TX_BB_FILTER_MODE: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.txbbFilterMode); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.txbbFilterMode, + inputVoidBuffer, + bufferSize); + } + break; + + case VNV_TABLE_VIRTUAL_RATE: + itemSize = sizeof(gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate); + if (bufferSize != itemSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "type = %d buffer size=%d is less than data size=%d", + type, bufferSize, itemSize); + status = VOS_STATUS_E_INVAL; + } + else + { + vos_mem_copy(&gnvEFSTableV2->halnvV2.tables.pwrOptimum_virtualRate, + inputVoidBuffer, + bufferSize); + } + break; + + default: + break; + } + + if (VOS_STATUS_SUCCESS == status) + { + // set NV item to have valid data + status = vos_nv_setValidity(type, VOS_TRUE); + if (! VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_setValidity failed!!!"); + status = VOS_STATUS_E_FAULT; + } + + status = wlan_write_to_efs((v_U8_t*)gnvEFSTableV2, sizeof(*gnvEFSTableV2)); + if (!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_write_to_efs failed!!!"); + status = VOS_STATUS_E_FAULT; + } + } + + return status; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelListWithPower() - function to return the list of + supported channels with the power limit info too. + \param pChannels20MHz - list of 20 Mhz channels + \param pNum20MHzChannelsFound - number of 20 Mhz channels + \param pChannels40MHz - list of 20 Mhz channels + \param pNum40MHzChannelsFound - number of 20 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getChannelListWithPower(tChannelListWithPower *channels20MHz /*[NUM_LEGIT_RF_CHANNELS] */, + tANI_U8 *num20MHzChannelsFound, + tChannelListWithPower *channels40MHz /*[NUM_CHAN_BOND_CHANNELS] */, + tANI_U8 *num40MHzChannelsFound + ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + int i, count; + + //TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV + // or pass it as a parameter to NV from SME? + + if( channels20MHz && num20MHzChannelsFound ) + { + count = 0; + for( i = 0; i <= RF_CHAN_14; i++ ) + { + if( regChannels[i].enabled ) + { + channels20MHz[count].chanId = rfChannels[i].channelNum; + channels20MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + if( regChannels[i].enabled ) + { + channels20MHz[count].chanId = rfChannels[i].channelNum; + channels20MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + *num20MHzChannelsFound = (tANI_U8)count; + } + + if( channels40MHz && num40MHzChannelsFound ) + { + count = 0; + //center channels for 2.4 Ghz 40 MHz channels + for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ ) + { + + if( regChannels[i].enabled ) + { + channels40MHz[count].chanId = rfChannels[i].channelNum; + channels40MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + //center channels for 5 Ghz 40 MHz channels + for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ ) + { + + if( regChannels[i].enabled ) + { + channels40MHz[count].chanId = rfChannels[i].channelNum; + channels40MHz[count++].pwr = regChannels[i].pwrLimit; + } + } + *num40MHzChannelsFound = (tANI_U8)count; + } + return (status); +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getDefaultRegDomain() - return the default regulatory domain + \return default regulatory domain + \sa + -------------------------------------------------------------------------*/ + +v_REGDOMAIN_t vos_nv_getDefaultRegDomain( void ) +{ + return countryInfoTable.countryInfo[0].regDomain; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getSupportedChannels() - function to return the list of + supported channels + \param p20MhzChannels - list of 20 Mhz channels + \param pNum20MhzChannels - number of 20 Mhz channels + \param p40MhzChannels - list of 40 Mhz channels + \param pNum40MhzChannels - number of 40 Mhz channels + \return status of the NV read operation + \Note: 40Mhz not currently supported + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getSupportedChannels( v_U8_t *p20MhzChannels, int *pNum20MhzChannels, + v_U8_t *p40MhzChannels, int *pNum40MhzChannels) +{ + VOS_STATUS status = VOS_STATUS_E_INVAL; + int i, count = 0; + + if( p20MhzChannels && pNum20MhzChannels ) + { + if( *pNum20MhzChannels >= NUM_RF_CHANNELS ) + { + for( i = 0; i <= RF_CHAN_14; i++ ) + { + p20MhzChannels[count++] = rfChannels[i].channelNum; + } + for( i = RF_CHAN_36; i <= RF_CHAN_165; i++ ) + { + p20MhzChannels[count++] = rfChannels[i].channelNum; + } + status = VOS_STATUS_SUCCESS; + } + *pNum20MhzChannels = count; + } + + return (status); +} + +/**------------------------------------------------------------------------ + \brief vos_nv_readDefaultCountryTable() - return the default Country table + \param table data - a union to return the default country table data in. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData ) +{ + + VOS_STATUS status = VOS_STATUS_SUCCESS; + vos_mem_copy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry)); + pr_info("DefaultCountry is %c%c\n", + tableData->defaultCountryTable.countryCode[0], + tableData->defaultCountryTable.countryCode[1]); + return status; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getBuffer - + \param pBuffer - to return the buffer address + pSize - buffer size. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getNVBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize) +{ + eNvVersionType nvVersion; + + nvVersion = vos_nv_getNvVersion(); + + if (E_NV_V3 == nvVersion) + { + /* Send the NV V3 structure and size */ + *pNvBuffer = (v_VOID_t *)(&pnvEFSTable->halnv); + *pSize = sizeof(sHalNv); + } + else if (E_NV_V2 == nvVersion) + { + /* Send the NV V2 structure and size */ + *pNvBuffer = (v_VOID_t *)(&gnvEFSTableV2->halnvV2); + *pSize = sizeof(sHalNvV2); + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s : Invalid NV version %d", __func__, nvVersion); + return VOS_STATUS_E_INVAL; + } + + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getBuffer - + \param pBuffer - to return the buffer address + pSize - buffer size. + \return status of the NV read operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getNVEncodedBuffer(v_VOID_t **pNvBuffer,v_SIZE_t *pSize) +{ + /* Send the NV structure and size */ + *pNvBuffer = (v_VOID_t *)(pEncodedBuf); + *pSize = nvReadEncodeBufSize; + return VOS_STATUS_SUCCESS; +} + + +VOS_STATUS vos_nv_getNVDictionary(v_VOID_t **pNvBuffer,v_SIZE_t *pSize) +{ + /* Send the NV structure and size */ + *pNvBuffer = (v_VOID_t *)(pDictFile); + *pSize = nDictionarySize; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_nv_isEmbeddedNV(v_VOID_t) +{ + if (MAGIC_NUMBER == magicNumber) + { + return VOS_STATUS_SUCCESS; + } + + return VOS_STATUS_E_FAILURE; +} + +VOS_STATUS vos_nv_setNVEncodedBuffer(v_U8_t *pNvBuffer, v_SIZE_t size) +{ + vos_mem_copy(pEncodedBuf, &pNvBuffer[sizeof(v_U32_t)], + (size-sizeof(v_U32_t))); + + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getChannelEnabledState - + \param rfChannel - input channel enum to know evabled state + \return eNVChannelEnabledType enabled state for channel + * enabled + * disabled + * DFS + \sa + -------------------------------------------------------------------------*/ +eNVChannelEnabledType vos_nv_getChannelEnabledState +( + v_U32_t rfChannel +) +{ + v_U32_t channelLoop; + eRfChannels channelEnum = INVALID_RF_CHANNEL; + + for(channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) + { + if(rfChannels[channelLoop].channelNum == rfChannel) + { + channelEnum = (eRfChannels)channelLoop; + break; + } + } + + if(INVALID_RF_CHANNEL == channelEnum) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_getChannelEnabledState, invalid channel %d", rfChannel); + return NV_CHANNEL_INVALID; + } + + return regChannels[channelEnum].enabled; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getNvVersion - + \param NONE + \return eNvVersionType NV.bin version + * E_NV_V2 + * E_NV_V3 + * E_NV_INVALID + \sa + -------------------------------------------------------------------------*/ +eNvVersionType vos_nv_getNvVersion +( + void +) +{ + VosContextType *vosCtxt = NULL; + + vosCtxt = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (vosCtxt) + { + return vosCtxt->nvVersion; + } + + return E_NV_INVALID; +} + +/****************************************************************** + Add CRDA regulatory support +*******************************************************************/ + +static int bw20_ch_index_to_bw40_ch_index(int k) +{ + int m = -1; + if (k >= RF_CHAN_1 && k <= RF_CHAN_14) + { + m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ; + if (m > RF_CHAN_BOND_11) + m = RF_CHAN_BOND_11; + } + else if (k >= RF_CHAN_240 && k <= RF_CHAN_216) + { + m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ; + if (m > RF_CHAN_BOND_214) + m = RF_CHAN_BOND_214; + } + else if (k >= RF_CHAN_36 && k <= RF_CHAN_64) + { + m = k - RF_CHAN_36 + RF_CHAN_BOND_38; + if (m > RF_CHAN_BOND_62) + m = RF_CHAN_BOND_62; + } +#ifdef FEATURE_WLAN_CH144 + else if (k >= RF_CHAN_100 && k <= RF_CHAN_144) +#else + else if (k >= RF_CHAN_100 && k <= RF_CHAN_140) +#endif /* FEATURE_WLAN_CH144 */ + { + m = k - RF_CHAN_100 + RF_CHAN_BOND_102; +#ifdef FEATURE_WLAN_CH144 + if (m > RF_CHAN_BOND_142) + m = RF_CHAN_BOND_142; +#else + if (m > RF_CHAN_BOND_138) + m = RF_CHAN_BOND_138; +#endif /* FEATURE_WLAN_CH144 */ + } + else if (k >= RF_CHAN_149 && k <= RF_CHAN_165) + { + m = k - RF_CHAN_149 + RF_CHAN_BOND_151; + if (m > RF_CHAN_BOND_163) + m = RF_CHAN_BOND_163; + } +return m; +} + +void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id) +{ + int k; + pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n", + countryCode[0], countryCode[1], domain_id); + for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled = + NV_CHANNEL_ENABLE; + /* Max Tx Power 20dBm */ + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20; + } + /* enable ch 12 to ch 14 passive scan */ + pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n"); + for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled = + NV_CHANNEL_DFS; + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0; + } + pr_info(" enable 5GHz to scan passively by setting DFS flag.\n"); + for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled = + NV_CHANNEL_DFS; + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0; + } +#ifdef PASSIVE_SCAN_4_9GHZ + pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n"); + for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled = + NV_CHANNEL_DFS; + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0; + } +#endif + if (domain_id == NUM_REG_DOMAINS-1) + { /* init time */ + crda_alpha2[0] = countryCode[0]; + crda_alpha2[1] = countryCode[1]; + crda_regulatory_entry_valid = VOS_TRUE; + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0]; + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1]; + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I'; + pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1; + } + if (domain_id == NUM_REG_DOMAINS-2) + { /* none-default country */ + run_time_alpha2[0] = countryCode[0]; + run_time_alpha2[1] = countryCode[1]; + crda_regulatory_run_time_entry_valid = VOS_TRUE; + } +} + +static int crda_regulatory_entry_post_processing(struct wiphy *wiphy, + struct regulatory_request *request, + v_U8_t nBandCapability, + int domain_id) +{ + if (request->alpha2[0] == '0' && request->alpha2[1] == '0') { + pr_info("Country 00 special handling to enable passive scan.\n"); + crda_regulatory_entry_default(request->alpha2, domain_id); + } + return 0; +} + +/* create_crda_regulatory_entry should be called from user command or 11d country IE */ +static int create_crda_regulatory_entry(struct wiphy *wiphy, + struct regulatory_request *request, + v_U8_t nBandCapability) +{ + int i, j, m; + int k = 0, n = 0; + + if (run_time_alpha2[0]==request->alpha2[0] && + run_time_alpha2[1]==request->alpha2[1] && + crda_regulatory_run_time_entry_valid == VOS_TRUE) + return 0; /* already created */ + + /* 20MHz channels */ + if (nBandCapability == eCSR_BAND_24) + pr_info("BandCapability is set to 2G only.\n"); + for (i=0,m=0;ibands[i] == NULL) + { + return -1; + } + // internal channels[] is one continous array for both 2G and 5G bands + // m is internal starting channel index for each band + if (i == 0) + m = 0; + else + m = wiphy->bands[i-1]->n_channels + m; + for (j=0;jbands[i]->n_channels;j++) + { + // k = (m + j) is internal current channel index for 20MHz channel + // n is internal channel index for corresponding 40MHz channel + k = m + j; + n = bw20_ch_index_to_bw40_ch_index(k); + if (n == -1) + return -1; + if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED) + { + if (pnvEFSTable == NULL) + { + pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n"); + return -1; + } + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled = + NV_CHANNEL_DISABLE; + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled = + NV_CHANNEL_DISABLE; + //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum, + // rfChannels[n].channelNum); + } + else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR) + { + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled = + NV_CHANNEL_DFS; + // max_power is in mBm = 100 * dBm + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit = + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100); + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0) + { + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled = + NV_CHANNEL_DFS; + // 40MHz channel power is half of 20MHz (-3dB) ?? + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit = + (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3); + } + } + else // Enable is only last flag we support + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion())) + { + //Do not enable channel 144 when NV version is not NV3 + } + else +#endif + { + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].\ + channels[k].enabled = NV_CHANNEL_ENABLE; + } + + // max_power is in dBm + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit = + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100); + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0) + { + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled = + NV_CHANNEL_ENABLE; + // 40MHz channel power is half of 20MHz (-3dB) ?? + pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit = + (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3); + } + } + /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is + real gain which should be provided by the real design */ + } + } + if (k == 0) + return -1; + run_time_alpha2[0] = request->alpha2[0]; + run_time_alpha2[1] = request->alpha2[1]; + crda_regulatory_run_time_entry_valid = VOS_TRUE; + crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2); +return 0; +} + + +v_BOOL_t is_crda_regulatory_entry_valid(void) +{ +return crda_regulatory_entry_valid; +} + +/* Handling routines for the conversion from regd rules (start/end freq) to channel index +start freq + 10000 = center freq of the 20MHz start channel +end freq - 10000 = center freq of the 20MHz end channel +start freq + 20000 = center freq of the 40MHz start channel +end freq - 20000 = center freq of the 40MHz end channel +*/ +static int bw20_start_freq_to_channel_index(u32 freq_khz) +{ + int i; + u32 center_freq = freq_khz + 10000; + + //Has to compare from low freq to high freq + //RF_SUBBAND_2_4_GHZ + for (i=RF_CHAN_1;i<=RF_CHAN_14;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216 + for (i=RF_CHAN_240;i<=RF_CHAN_216;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_LOW_GHZ + for (i=RF_CHAN_36;i<=RF_CHAN_64;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_MID_GHZ +#ifdef FEATURE_WLAN_CH144 + for (i=RF_CHAN_100;i<=RF_CHAN_144;i++) +#else + for (i=RF_CHAN_100;i<=RF_CHAN_140;i++) +#endif /* FEATURE_WLAN_CH144 */ + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_HIGH_GHZ + for (i=RF_CHAN_149;i<=RF_CHAN_165;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; +return -1; +} + +static int bw20_end_freq_to_channel_index(u32 freq_khz) +{ + int i; + u32 center_freq = freq_khz - 10000; + + //Has to compare from high freq to low freq + //RF_SUBBAND_5_HIGH_GHZ + for (i=RF_CHAN_165;i>=RF_CHAN_149;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_MID_GHZ +#ifdef FEATURE_WLAN_CH144 + for (i=RF_CHAN_144;i>=RF_CHAN_100;i--) +#else + for (i=RF_CHAN_140;i>=RF_CHAN_100;i--) +#endif /* FEATURE_WLAN_CH144 */ + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_LOW_GHZ + for (i=RF_CHAN_64;i>=RF_CHAN_36;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240 + for (i=RF_CHAN_216;i>=RF_CHAN_240;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_2_4_GHZ + for (i=RF_CHAN_14;i>=RF_CHAN_1;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + return -1; +} + +static int bw40_start_freq_to_channel_index(u32 freq_khz) +{ + int i; + u32 center_freq = freq_khz + 20000; + + //Has to compare from low freq to high freq + //RF_SUBBAND_2_4_GHZ + for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214 + for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_LOW_GHZ + for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_MID_GHZ +#ifdef FEATURE_WLAN_CH144 + for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_142;i++) +#else + for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++) +#endif /* RF_CHAN_BOND_142 */ + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_HIGH_GHZ + for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++) + if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000) + return i; +return -1; +} + +static int bw40_end_freq_to_channel_index(u32 freq_khz) +{ + int i; + u32 center_freq = freq_khz - 20000; + + //Has to compare from high freq to low freq + //RF_SUBBAND_5_HIGH_GHZ + for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_MID_GHZ +#ifdef FEATURE_WLAN_CH144 + for (i=RF_CHAN_BOND_142;i>=RF_CHAN_BOND_102;i--) +#else + for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--) +#endif /* FEATURE_WLAN_CH144 */ + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_5_LOW_GHZ + for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242 + for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; + //RF_SUBBAND_2_4_GHZ + for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--) + if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000) + return i; +return -1; +} + +static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability) +{ + switch (nBandCapability) + { + case eCSR_BAND_ALL: + return VOS_TRUE; + case eCSR_BAND_24: + if (j >= RF_CHAN_1 && j <= RF_CHAN_14) + return VOS_TRUE; + if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11) + return VOS_TRUE; // 2.4G 40MHz channel + break; + case eCSR_BAND_5G: + if (j >= RF_CHAN_240 && j <= RF_CHAN_165) + return VOS_TRUE; + if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163) + return VOS_TRUE; // 2.4G 40MHz channel + break; + default: + break; + } + return VOS_FALSE; +} + +/* create_crda_regulatory_entry_from_regd should be called during init time */ +static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy, + struct regulatory_request *request, + v_U8_t nBandCapability) +{ + int i, j, n, domain_id; + int bw20_start_channel_index, bw20_end_channel_index; + int bw40_start_channel_index, bw40_end_channel_index; + + if (wiphy == NULL || wiphy->regd == NULL) + { + wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n"); + return -1; + } + if (crda_regulatory_entry_valid == VOS_FALSE) + domain_id = NUM_REG_DOMAINS-1; /* init time */ + else + domain_id = NUM_REG_DOMAINS-2; /* none-default country */ + for (n = 0; n < NUM_RF_CHANNELS; n++) + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE; + + for (i=0;iregd->n_reg_rules;i++) + { + wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i); + bw20_start_channel_index = + bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz); + bw20_end_channel_index = + bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz); + if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1) + { + wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n", + wiphy->regd->reg_rules[i].freq_range.start_freq_khz, + wiphy->regd->reg_rules[i].freq_range.end_freq_khz); + continue; // skip this rull, but continue to next rule + } + wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n", + wiphy->regd->reg_rules[i].freq_range.start_freq_khz, + wiphy->regd->reg_rules[i].freq_range.end_freq_khz, + bw20_start_channel_index, bw20_end_channel_index); + for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++) + { + if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE) + { + wiphy_dbg(wiphy, "info: CH %d is not in capable band\n", + rfChannels[j].channelNum); + continue; // skip this channel, continue to next + } + if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS) + { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS; + wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum, + wiphy->regd->reg_rules[i].power_rule.max_eirp); + } + if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_PASSIVE_SCAN) + { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS; + wiphy_dbg(wiphy, "info: CH %d is Passive, max EIRP (mBm) is %d\n", rfChannels[j].channelNum, + wiphy->regd->reg_rules[i].power_rule.max_eirp); + } + else + { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE; + wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum, + wiphy->regd->reg_rules[i].power_rule.max_eirp); + } + /* max_eirp is in mBm (= 100 * dBm) unit */ + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit = + (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100); + } + /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is + real gain which should be provided by the real design */ + if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000) + { + wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n"); + bw40_start_channel_index = + bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz); + bw40_end_channel_index = + bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz); + if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1) + { + wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n", + wiphy->regd->reg_rules[i].freq_range.start_freq_khz, + wiphy->regd->reg_rules[i].freq_range.end_freq_khz); + continue; // skip this rull, but continue to next rule + } + wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n", + wiphy->regd->reg_rules[i].freq_range.start_freq_khz, + wiphy->regd->reg_rules[i].freq_range.end_freq_khz, + bw40_start_channel_index, bw40_end_channel_index); + for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++) + { + if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE) + continue; // skip this channel, continue to next + if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS) + { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS; + wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum); + } + else + { + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE; + wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum); + } + /* set 40MHz channel power as half (- 3 dB) of 20MHz */ + pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit = + (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3); + } + } + } + /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR, + NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add + these flags and has no implementation yet. */ + if (crda_regulatory_entry_valid == VOS_FALSE) + { /* init time */ + crda_alpha2[0] = request->alpha2[0]; + crda_alpha2[1] = request->alpha2[1]; + crda_regulatory_entry_valid = VOS_TRUE; + } + else + { /* none-default country */ + run_time_alpha2[0] = request->alpha2[0]; + run_time_alpha2[1] = request->alpha2[1]; + crda_regulatory_run_time_entry_valid = VOS_TRUE; + } + crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id); + return 0; +} + +/**------------------------------------------------------------------------ + \brief vos_chan_to_freq - + \param - input channel number to know channel frequency + \return Channel frequency + \sa + -------------------------------------------------------------------------*/ +v_U16_t vos_chan_to_freq(v_U8_t chanNum) +{ + int i; + + for (i = 0; i < NUM_RF_CHANNELS; i++) + { + if (rfChannels[i].channelNum == chanNum) + { + return rfChannels[i].targetFreq; + } + } + + return (0); +} + +/**------------------------------------------------------------------------ + \brief vos_freq_to_chan - + \param - input frequency to know channel number + \return Channel frequency + \sa + -------------------------------------------------------------------------*/ +v_U8_t vos_freq_to_chan(v_U32_t freq) +{ + int i; + + for (i = 0; i < NUM_RF_CHANNELS; i++) + { + if (rfChannels[i].targetFreq == freq) + { + return rfChannels[i].channelNum; + } + } + + return (0); +} + +/* function to tell about if Default country is Non-Zero */ +v_BOOL_t vos_is_nv_country_non_zero() +{ + v_BOOL_t status = VOS_FALSE; + if (!(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] == '0' && + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] == '0')) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "Default Country is Non-Zero\n"); + return VOS_TRUE; + } + + return status ; +} + +v_BOOL_t vos_is_channel_valid_for_vht80(v_U32_t chan) +{ + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + v_U16_t freq; + v_U32_t i, band; + struct wiphy *wiphy; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + return VOS_FALSE; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pVosContext pointer") ); + return VOS_FALSE; + } + /* no 80Mhz in 2.4 GHz*/ + if (chan <= RF_CHAN_14) + return VOS_FALSE; + + band = IEEE80211_BAND_5GHZ; + freq = vos_chan_to_freq(chan); + wiphy = pHddCtx->wiphy; + + for (i = 0; i < wiphy->bands[band]->n_channels; i++) + { + if (freq == + wiphy->bands[band]->channels[i].center_freq) + { + if (wiphy->bands[band]->channels[i].flags & + IEEE80211_CHAN_NO_80MHZ) + { + return VOS_FALSE; + } + return VOS_TRUE; + } + } + return VOS_FALSE; +} + +#ifdef CONFIG_ENABLE_LINUX_REG + +static inline int bw20_ch_index_to_bw40_plus_minus_ch_index(int k, + eChannnelBondingTypes cbflag ) +{ + if (k >= NUM_20MHZ_RF_CHANNELS) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s invlaid channel index %d",__func__, k); + return INVALID_RF_CHANNEL; + } + + if (RF_CHAN_BOND_HT40_PLUS == cbflag) + return chan_to_ht_40_index[k].ht_40_plus_index; + else + return chan_to_ht_40_index[k].ht_40_minus_index; +} +/**------------------------------------------------------------------------ + \brief vos_nv_setRegDomain - + \param clientCtxt - Client Context, Not used for PRIMA + regId - Regulatory Domain ID + sendRegHint - send hint to nl80211 + \return status set REG domain operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + v_BOOL_t sendRegHint) +{ + + if (regId >= REGDOMAIN_COUNT) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VOS set reg domain, invalid REG domain ID %d", regId); + return VOS_STATUS_E_INVAL; + } + + /* Set correct channel information based on REG Domain */ + regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels; + + return VOS_STATUS_SUCCESS; +} + +/**------------------------------------------------------------------------ + \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of + a country given its country code + The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of + a country given its country code. This is done from reading a cached + copy of the binary file. + \param pRegDomain - pointer to regulatory domain + \param countryCode - country code + \param source - source of the country code + \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country + VOS_STATUS_E_FAULT - invalid pointer error + VOS_STATUS_E_EMPTY - country code table is empty + VOS_STATUS_E_EXISTS - given country code does not exist in table + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain, + const v_COUNTRYCODE_t country_code, v_CountryInfoSource_t source) +{ + + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + int i; + int wait_result; + + /* sanity checks */ + if (NULL == pRegDomain) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid reg domain pointer") ); + return VOS_STATUS_E_FAULT; + } + + *pRegDomain = REGDOMAIN_COUNT; + + if (NULL == country_code) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Country code array is NULL")); + return VOS_STATUS_E_FAULT; + } + + if (0 == countryInfoTable.countryCount) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Reg domain table is empty") ); + return VOS_STATUS_E_EMPTY; + } + + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + else + return VOS_STATUS_E_EXISTS; + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + return VOS_STATUS_E_FAULT; + } + + temp_reg_domain = REGDOMAIN_COUNT; + /* lookup the country in the local database */ + for (i = 0; i < countryInfoTable.countryCount && + REGDOMAIN_COUNT == temp_reg_domain; i++) + { + if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode, + VOS_COUNTRY_CODE_LEN) == 0) + { + /* country code is found */ + /* record the temporary regulatory_domain as well */ + temp_reg_domain = countryInfoTable.countryInfo[i].regDomain; + break; + } + } + + if (REGDOMAIN_COUNT == temp_reg_domain) { + + /* the country was not found in the driver database + * so we will return the REGDOMAIN_WORLD to SME/CSR + */ + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("Country %c%c does not map to any Regulatory domain"), + country_code[0], country_code[1]); + + temp_reg_domain = REGDOMAIN_WORLD; + } + + if (COUNTRY_QUERY == source) + { + *pRegDomain = temp_reg_domain; + return VOS_STATUS_SUCCESS; + } + + wiphy = pHddCtx->wiphy; + + if (false == wiphy->registered) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("wiphy is not yet registered with the kernel") ); + return VOS_STATUS_E_FAULT; + } + + /* We need to query the kernel to get the regulatory information + for this country */ + + + /* First compare the country code with the existing current country code + . If both are same there is no need to query any database */ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("regdomain request")); + + if ((country_code[0] == linux_reg_cc[0]) && + (country_code[1] == linux_reg_cc[1])) { + + /* country code already exists */ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + (" country code already exists")); + + *pRegDomain = cur_reg_domain; + + return VOS_STATUS_SUCCESS; + } + else { + + /* get the regulatory information from the kernel + database */ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + (" get country information from kernel db")); + + + if (COUNTRY_NV == source) + { + INIT_COMPLETION(pHddCtx->linux_reg_req); + regulatory_hint(wiphy, country_code); + /* Wait for 300ms*/ + wait_result = wait_for_completion_interruptible_timeout( + &pHddCtx->linux_reg_req, + msecs_to_jiffies(LINUX_REG_WAIT_TIME)); + + /* if the country information does not exist with the kernel, + then the driver callback would not be called */ + + if (wait_result >= 0) { + + /* the driver callback was called. this means the country + regulatory information was found in the kernel database. + The callback would have updated the internal database. Here + update the country and the return value for the regulatory + domain */ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("runtime country code is found in kernel db")); + + *pRegDomain = temp_reg_domain; + cur_reg_domain = temp_reg_domain; + linux_reg_cc[0] = country_code[0]; + linux_reg_cc[1] = country_code[1]; + + return VOS_STATUS_SUCCESS; + } + else { + + /* the country information has not been found in the kernel + database, return failure */ + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + ("runtime country code is not found in kernel db")); + + return VOS_STATUS_E_EXISTS; + } + } + else if (COUNTRY_IE == source || COUNTRY_USER == source) + { + INIT_COMPLETION(pHddCtx->linux_reg_req); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + regulatory_hint_user(country_code,NL80211_USER_REG_HINT_USER); +#else + regulatory_hint_user(country_code); +#endif + wait_result = wait_for_completion_interruptible_timeout( + &pHddCtx->linux_reg_req, + msecs_to_jiffies(LINUX_REG_WAIT_TIME)); + + /* if the country information does not exist with the kernel, + then the driver callback would not be called */ + + if (wait_result >= 0) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "runtime country code : %c%c is found in kernel db", + country_code[0], country_code[1]); + *pRegDomain = temp_reg_domain; + } + + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "runtime country code : %c%c is not found" + " in kernel db", + country_code[0], country_code[1]); + + return VOS_STATUS_E_EXISTS; + } + } + + } + + return VOS_STATUS_SUCCESS; +} + +int vos_update_nv_table_from_wiphy_band(void *hdd_ctx, + void *pwiphy,v_U8_t nBandCapability) +{ + int i, j, m; + int k = 0, n = 0; + const struct ieee80211_reg_rule *reg_rule; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) + int err; +#endif + hdd_context_t *pHddCtx = (hdd_context_t *)hdd_ctx; + struct wiphy *wiphy = (struct wiphy *)pwiphy; + + for (i = 0, m = 0; ibands[i] == NULL) + { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "error: wiphy->bands is NULL, i = %d", i); + continue; + } + + /* internal channels[] is one continous array for both 2G and 5G bands + m is internal starting channel index for each band */ + + if (i == 0) + m = 0; + else + m = wiphy->bands[i-1]->n_channels + m; + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + + /* k = (m + j) is internal current channel index for 20MHz channel + n is internal channel index for corresponding 40MHz channel */ + + k = m + j; + + /* If the regulatory rules for a country do not explicilty + * require a passive scan on a frequency, lift the passive + * scan restriction + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + reg_rule = freq_reg_info(wiphy, + MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq)); +#else + err = freq_reg_info(wiphy, + MHZ_TO_KHZ(wiphy->bands[i]->channels[j].center_freq), + 0, ®_rule); +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + if (!IS_ERR(reg_rule)) +#else + if (0 == err) +#endif + { + /* When Country code in nv.bin file is Non Zero and Reg Domain + * is world; it's neither CUSTOM nor STRICT. In this Case + * if country code is Non-Zero and domain is world; driver + * will not change channel to active. + */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + if (!(wiphy->regulatory_flags & REGULATORY_STRICT_REG)) +#else + if (!(wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY )) +#endif + { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Remove passive scan restriction for %u", + __func__, wiphy->bands[i]->channels[j].center_freq); + wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + wiphy->bands[i]->channels[j].max_power = + (int) MBM_TO_DBM(reg_rule->power_rule.max_eirp); + } + } + + if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED) + { + if (pnvEFSTable == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "error: pnvEFSTable is NULL, probably not parsed nv.bin yet"); + return -1; + } + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].enabled = + NV_CHANNEL_DISABLE; + if (INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k , RF_CHAN_BOND_HT40_MINUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + if (INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k , RF_CHAN_BOND_HT40_PLUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + } + /* nv cannot distinguish between DFS and passive channels */ + else if (wiphy->bands[i]->channels[j].flags & + (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN | + IEEE80211_CHAN_INDOOR_ONLY)) + { + if (wiphy->bands[i]->channels[j].flags & + IEEE80211_CHAN_INDOOR_ONLY) + wiphy->bands[i]->channels[j].flags |= + IEEE80211_CHAN_PASSIVE_SCAN; +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion())) + { + //Do not enable channel 144 when NV version is not NV3 + } + else +#endif + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].\ + channels[k].enabled = NV_CHANNEL_DFS; + } + + if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit + && !wiphy->bands[i]->channels[j].max_power) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Both NV and DB.txt power limit is zero." + "Setting default value %d"),TX_POWER_DEFAULT); + wiphy->bands[i]->channels[j].max_power = TX_POWER_DEFAULT; + } + + else if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit + || !wiphy->bands[i]->channels[j].max_power) + { + wiphy->bands[i]->channels[j].max_power = + MAX(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit, + ((wiphy->bands[i]->channels[j].max_power))); + } + + // Cap the TX power by the power limits specified in NV for the regdomain + if (gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit + && wiphy->bands[i]->channels[j].max_power) + { + wiphy->bands[i]->channels[j].max_power = + MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit, + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power))); + } + + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit = + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)); + + /* Disable the center channel if neither HT40+ nor HT40- is allowed + */ + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == + IEEE80211_CHAN_NO_HT40 ) + { + if ( INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + if ( INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + } + else + { + if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40PLUS)) + { + if (INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DFS; + + /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from + * wiphy limits, since wiphy has same limits for 20MHz and 40MHz + * channels + */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit = + MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit, + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3))); + } + } + if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40MINUS)) + { + if (INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DFS; + + /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from + * wiphy limits, since wiphy has same limits for 20MHz and 40MHz + * channels + */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit = + MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit, + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3))); + } + } + } + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0) + { + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + else + { + pHddCtx->isVHT80Allowed = 1; + } + } + } + else /* Enable is only last flag we support */ + { +#ifdef FEATURE_WLAN_CH144 + if ((RF_CHAN_144 == k) && (E_NV_V3 != vos_nv_getNvVersion())) + { + //Do not enable channel 144 when NV version is not NV3 + } + else +#endif + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].\ + channels[k].enabled = NV_CHANNEL_ENABLE; + } + + if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit + && !wiphy->bands[i]->channels[j].max_power) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("Both NV and DB.txt power limit is zero." + "Setting default value %d"),TX_POWER_DEFAULT); + wiphy->bands[i]->channels[j].max_power = TX_POWER_DEFAULT; + } + + else if (!gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit + || !wiphy->bands[i]->channels[j].max_power) + { + wiphy->bands[i]->channels[j].max_power = + MAX(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit, + ((wiphy->bands[i]->channels[j].max_power))); + } + + // Cap the TX power by the power limits specified in NV for the regdomain + if (gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit + && wiphy->bands[i]->channels[j].max_power) + { + wiphy->bands[i]->channels[j].max_power = + MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit, + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power))); + } + + /* max_power is in dBm */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[k].pwrLimit = + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)); + + /* Disable the center channel if neither HT40+ nor HT40- is allowed + */ + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == + IEEE80211_CHAN_NO_HT40 ) + { + if ( INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + if ( INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_DISABLE; + } + } + else + { + if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40PLUS)) + { + if (INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_PLUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_ENABLE; + + /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from + * wiphy limits, since wiphy has same limits for 20MHz and 40MHz + * channels + */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit = + MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit, + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3))); + } + } + if (!(wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40MINUS)) + { + if (INVALID_RF_CHANNEL != + (n = bw20_ch_index_to_bw40_plus_minus_ch_index( k, RF_CHAN_BOND_HT40_MINUS))) + { + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].enabled = + NV_CHANNEL_ENABLE; + + /* 40MHz channel power is half of 20MHz (-3dB), so subtract 3dB from + * wiphy limits, since wiphy has same limits for 20MHz and 40MHz + * channels + */ + pnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit = + MIN(gnvEFSTable->halnv.tables.regDomains[temp_reg_domain].channels[n].pwrLimit, + (tANI_S8) ((wiphy->bands[i]->channels[j].max_power-3))); + } + } + } + if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_80MHZ) == 0) + { + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + else + { + pHddCtx->isVHT80Allowed = 1; + } + } + + } + + + } + } + + if (k == 0) + return -1; + + return 0; +} + +/* create_linux_regulatory_entry to populate internal structures from wiphy */ +static int create_linux_regulatory_entry(struct wiphy *wiphy, + struct regulatory_request *request, + v_U8_t nBandCapability) +{ + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + } + else + { + pHddCtx->isVHT80Allowed = 0; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pVosContext pointer") ); + } + + /* 20MHz channels */ + if (nBandCapability == eCSR_BAND_24) + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "BandCapability is set to 2G only"); + return vos_update_nv_table_from_wiphy_band(pHddCtx, wiphy, nBandCapability); + + +} + +/* + * Function: wlan_hdd_linux_reg_notifier + * This function is called from cfg80211 core to provide regulatory settings + * after new country is requested or intersected (init, user input or 11d) + * This function is used to create a CRDA regulatory settings entry into internal + * regulatory setting table. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void __wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +#else +int __wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +#endif +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + eCsrBand nBandCapability = eCSR_BAND_ALL; + v_COUNTRYCODE_t country_code; + int i, j; + v_BOOL_t isVHT80Allowed; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "cfg80211 reg notifier callback for country for initiator %d", request->initiator); + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + if (vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("SSR is in progress") ); + goto do_comp; + } + + if (WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s Unload is in progress"), __func__ ); + goto do_comp; + } + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("%s: Req initiator %d CC=%c%c"), __func__, + request->initiator, request->alpha2[0], request->alpha2[1]); + + sme_GetFreqBand(pHddCtx->hHal, &nBandCapability); + /* first check if this callback is in response to the driver callback */ + + if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER) + { + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + temp_reg_domain = REGDOMAIN_COUNT; + /* lookup the country in the local database */ + for (i = 0; i < countryInfoTable.countryCount && + REGDOMAIN_COUNT == temp_reg_domain; i++) + { + if (memcmp(request->alpha2, countryInfoTable.countryInfo[i].countryCode, + VOS_COUNTRY_CODE_LEN) == 0) + { + /* country code is found */ + /* record the temporary regulatory_domain as well */ + temp_reg_domain = countryInfoTable.countryInfo[i].regDomain; + break; + } + } + if (REGDOMAIN_COUNT == temp_reg_domain) + temp_reg_domain = REGDOMAIN_WORLD; + + cur_reg_domain = temp_reg_domain; + } + + isVHT80Allowed = pHddCtx->isVHT80Allowed; + if (create_linux_regulatory_entry(wiphy, request, nBandCapability) == 0) + { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + (" regulatory entry created")); + } + if (pHddCtx->isVHT80Allowed != isVHT80Allowed) + { + hdd_checkandupdate_phymode( pHddCtx); + } + linux_reg_cc[0] = request->alpha2[0]; + linux_reg_cc[1] = request->alpha2[1]; + + } + + else if (request->initiator == NL80211_REGDOM_SET_BY_USER || + request->initiator == NL80211_REGDOM_SET_BY_CORE) + { + /* Copy the country of kernel, so that we will not send the reg hint + * if kernel country and driver country are same during load. + */ + linux_reg_cc[0] = request->alpha2[0]; + linux_reg_cc[1] = request->alpha2[1]; + /* first lookup the country in the local database */ + + if (!(pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] == '0' && + pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] == '0') && + (request->initiator == NL80211_REGDOM_SET_BY_CORE) && + (vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + (" Default Country in nv is non Zero and Driver load/unload" + "is in progress; avoid updating country from kernel\n")); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + country_code[0] = request->alpha2[0]; + country_code[1] = request->alpha2[1]; + + temp_reg_domain = REGDOMAIN_COUNT; + for (i = 0; i < countryInfoTable.countryCount && + REGDOMAIN_COUNT == temp_reg_domain; i++) + { + if (memcmp(country_code, countryInfoTable.countryInfo[i].countryCode, + VOS_COUNTRY_CODE_LEN) == 0) + { + /* country code is found */ + /* record the temporary regulatory_domain as well */ + temp_reg_domain = countryInfoTable.countryInfo[i].regDomain; + break; + } + } + + if (REGDOMAIN_COUNT == temp_reg_domain) + temp_reg_domain = REGDOMAIN_WORLD; + + isVHT80Allowed = pHddCtx->isVHT80Allowed; + if (create_linux_regulatory_entry(wiphy, request, + nBandCapability) == 0) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + (" regulatory entry created")); + + } + if (pHddCtx->isVHT80Allowed != isVHT80Allowed) + { + hdd_checkandupdate_phymode( pHddCtx); + } + + cur_reg_domain = temp_reg_domain; + + /* now pass the new country information to sme */ + if (request->alpha2[0] == '0' && request->alpha2[1] == '0') + { + sme_GenericChangeCountryCode(pHddCtx->hHal, country_code, + REGDOMAIN_COUNT); + } + else + { + sme_GenericChangeCountryCode(pHddCtx->hHal, country_code, + temp_reg_domain); + } + } + + /* Mark channels 36-48 as passive for US CC */ + + if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER || + (request->initiator == NL80211_REGDOM_SET_BY_CORE)|| + (request->initiator == NL80211_REGDOM_SET_BY_USER)) + { + if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC && + wiphy->bands[IEEE80211_BAND_5GHZ]) + { + for (j=0; jbands[IEEE80211_BAND_5GHZ]->n_channels; j++) + { + // UNII-1 band channels are passive when domain is FCC. + if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) && + ((request->alpha2[0]== 'U'&& request->alpha2[1]=='S') && + pHddCtx->nEnableStrictRegulatoryForFCC)) + { + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + } + } + } + } +do_comp: + if ((request->initiator == NL80211_REGDOM_SET_BY_DRIVER) || + (request->initiator == NL80211_REGDOM_SET_BY_USER)) + { + complete(&pHddCtx->linux_reg_req); + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + vos_ssr_protect(__func__); + __wlan_hdd_linux_reg_notifier(wiphy, request); + vos_ssr_unprotect(__func__); + return; +} +#else +int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_linux_reg_notifier(wiphy, request); + vos_ssr_unprotect(__func__); + return ret; +} +#endif + +/* initialize wiphy from NV.bin */ +VOS_STATUS vos_init_wiphy_from_nv_bin(void) +{ + int i, j, m; + int k = 0; + v_REGDOMAIN_t reg_domain; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if (NULL != pVosContext) + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + else + return VOS_STATUS_E_EXISTS; + + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + return VOS_STATUS_E_FAULT; + } + + wiphy = pHddCtx->wiphy; + + if (('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0]) + && + ('0' == pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1])) + { + /* default country is world roaming */ + + reg_domain = REGDOMAIN_WORLD; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; +#else + wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; +#endif + } + else if (REGDOMAIN_WORLD == + pnvEFSTable->halnv.tables.defaultCountryTable.regDomain) { + + reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain; + } + else { + + reg_domain = pnvEFSTable->halnv.tables.defaultCountryTable.regDomain; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) + wiphy->regulatory_flags |= REGULATORY_STRICT_REG; +#else + wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; +#endif + } + + temp_reg_domain = cur_reg_domain = reg_domain; + + m = 0; + for (i = 0; i < IEEE80211_NUM_BANDS; i++) + { + + if (wiphy->bands[i] == NULL) + { + continue; + } + + /* internal channels[] is one continous array for both 2G and 5G bands + m is internal starting channel index for each band */ + + for (j = 0; j < wiphy->bands[i]->n_channels; j++) + { + /* k = (m + j) is internal current channel index */ + k = m + j; + + if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled == + NV_CHANNEL_DISABLE) + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + + else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled == + NV_CHANNEL_DFS) { + + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + + wiphy->bands[i]->channels[j].max_power = + (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit); + } + + else if (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].enabled == + NV_CHANNEL_ENABLE) { + + wiphy->bands[i]->channels[j].max_power = + (pnvEFSTable->halnv.tables.regDomains[reg_domain].channels[k].pwrLimit); + } + } + + m += wiphy->bands[i]->n_channels; + } + + return VOS_STATUS_SUCCESS; +} + + +/**------------------------------------------------------------------------ + \brief vos_getCurrentCountryCode - + \param CC - country code + \return None + \sa + -------------------------------------------------------------------------*/ + +void vos_getCurrentCountryCode( tANI_U8 *cc) +{ + vos_mem_copy(cc, linux_reg_cc, 2); +} + +#else + +/**------------------------------------------------------------------------ + \brief vos_nv_setRegDomain - + \param clientCtxt - Client Context, Not used for PRIMA + regId - Regulatory Domain ID + sendRegHint - send hint to nl80211 + \return status set REG domain operation + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_setRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + v_BOOL_t sendRegHint) +{ + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + /* Client Context Argumant not used for PRIMA */ + if (regId >= REGDOMAIN_COUNT) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VOS set reg domain, invalid REG domain ID %d", regId); + return VOS_STATUS_E_INVAL; + } + + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (NULL != pVosContext) + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + else + return VOS_STATUS_E_EXISTS; + /* Set correct channel information based on REG Domain */ + regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels; + + /* when CRDA is not running then we are world roaming. + In this case if 11d is enabled, then country code should + be update on basis of world roaming */ + if (NULL != pHddCtx && sendRegHint) + { + wiphy = pHddCtx->wiphy; + regulatory_hint(wiphy, "00"); + } + return VOS_STATUS_SUCCESS; +} + + +/**------------------------------------------------------------------------ + \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of + a country given its country code + The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of + a country given its country code. This is done from reading a cached + copy of the binary file. + \param pRegDomain - pointer to regulatory domain + \param countryCode - country code + \param source - source of the country code + \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country + VOS_STATUS_E_FAULT - invalid pointer error + VOS_STATUS_E_EMPTY - country code table is empty + VOS_STATUS_E_EXISTS - given country code does not exist in table + \sa + -------------------------------------------------------------------------*/ +VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain, + const v_COUNTRYCODE_t countryCode, v_CountryInfoSource_t source) +{ + int i; + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + struct wiphy *wiphy = NULL; + int status; + + // sanity checks + if (NULL == pRegDomain) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid reg domain pointer") ); + return VOS_STATUS_E_FAULT; + } + *pRegDomain = REGDOMAIN_COUNT; + + if (NULL == countryCode) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Country code array is NULL") ); + return VOS_STATUS_E_FAULT; + } + if (0 == countryInfoTable.countryCount) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Reg domain table is empty") ); + return VOS_STATUS_E_EMPTY; + } + /* If CRDA regulatory settings is valid, i.e. crda is enabled + and reg_notifier is called back. + Intercept here and redirect to the Reg domain table's CRDA + entry if country code is crda's country. + last one NUM_REG_DOMAINS-1 is reserved for crda */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "vos_nv_getRegDomainFromCountryCode %c%c", + countryCode[0], countryCode[1]); + + if (crda_regulatory_entry_valid == VOS_TRUE) + { + if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1]) + { + *pRegDomain = NUM_REG_DOMAINS-1; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "vos_nv_getRegDomainFromCountryCode return crda init entry"); + return VOS_STATUS_SUCCESS; + } + if (run_time_alpha2[0]==countryCode[0] && + run_time_alpha2[1]==countryCode[1] && + crda_regulatory_run_time_entry_valid == VOS_TRUE) + { + *pRegDomain = NUM_REG_DOMAINS-2; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "vos_nv_getRegDomainFromCountryCode return crda none-default country entry"); + return VOS_STATUS_SUCCESS; + } + else + { + crda_regulatory_run_time_entry_valid = VOS_FALSE; + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (NULL != pVosContext) + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + else + return VOS_STATUS_E_EXISTS; + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("Invalid pHddCtx pointer") ); + return VOS_STATUS_E_FAULT; + } + + wiphy = pHddCtx->wiphy; + + INIT_COMPLETION(pHddCtx->driver_crda_req); + regulatory_hint(wiphy, countryCode); + status = wait_for_completion_interruptible_timeout( + &pHddCtx->driver_crda_req, + msecs_to_jiffies(CRDA_WAIT_TIME)); + if (!status) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout waiting for CRDA REQ", __func__); + } + + if (crda_regulatory_run_time_entry_valid == VOS_TRUE) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry"); + return VOS_STATUS_SUCCESS; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry"); + return VOS_STATUS_E_EXISTS; + } + } + + // iterate the country info table until end of table or the country code + // is found + for (i = 0; i < countryInfoTable.countryCount && + REGDOMAIN_COUNT == *pRegDomain; i++) + { + if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode, + VOS_COUNTRY_CODE_LEN) == 0) + { + // country code is found + *pRegDomain = countryInfoTable.countryInfo[i].regDomain; + } + } + if (REGDOMAIN_COUNT != *pRegDomain) + { + return VOS_STATUS_SUCCESS; + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + ("country code is not found")); + return VOS_STATUS_E_EXISTS; + } +} +/* FUNCTION: vos_nv_change_country_code_cb +* to wait for contry code completion +*/ +void* vos_nv_change_country_code_cb(void *pAdapter) +{ + struct completion *change_code_cng = pAdapter; + complete(change_code_cng); + return NULL; +} + +/* + * Function: wlan_hdd_crda_reg_notifier + * This function is called from cfg80211 core to provide regulatory settings + * after new country is requested or intersected (init, user input or 11d) + * This function is used to create a CRDA regulatory settings entry into internal + * regulatory setting table. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void __wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +#else +int __wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +#endif +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + v_REGDOMAIN_t domainIdCurrent; + tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN]; + tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN; + eCsrBand nBandCapability = eCSR_BAND_ALL; + int i,j,k,m,n; + int countryIndex = -1; + + wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country" + " %c%c\n", request->alpha2[0], request->alpha2[1]); + + /* During load and SSR, vos_open (which will lead to WDA_SetRegDomain) + * is called before we assign pHddCtx->hHal so we might get it as + * NULL here leading to crash. + */ + if (NULL == pHddCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s Invalid pHddCtx pointer"), __func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + if((WLAN_HDD_IS_UNLOAD_IN_PROGRESS(pHddCtx)) || + pHddCtx->isLogpInProgress) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + ("%s load/unload or SSR is in progress Ignore"), __func__ ); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + if (request->initiator == NL80211_REGDOM_SET_BY_USER) + { + int status; + wiphy_dbg(wiphy, "info: set by user\n"); + memset(ccode, 0, WNI_CFG_COUNTRY_CODE_LEN); + vos_mem_copy(ccode, request->alpha2, 2); + init_completion(&change_country_code); + /* We will process hints by user from nl80211 in driver. + * sme_ChangeCountryCode will set the country to driver + * and update the regdomain. + * when we return back to nl80211 from this callback, the nl80211 will + * send NL80211_CMD_REG_CHANGE event to the hostapd waking it up to + * query channel list from nl80211. Thus we need to update the channels + * according to reg domain set by user before returning to nl80211 so + * that hostapd will gets the updated channels. + * The argument sendRegHint in sme_ChangeCountryCode is + * set to eSIR_FALSE (hint is from nl80211 and thus + * no need to notify nl80211 back)*/ + status = sme_ChangeCountryCode(pHddCtx->hHal, + (void *)(tSmeChangeCountryCallback) + vos_nv_change_country_code_cb, + ccode, + &change_country_code, + pHddCtx->pvosContext, + eSIR_FALSE, + eSIR_FALSE); + if (eHAL_STATUS_SUCCESS == status) + { + status = wait_for_completion_interruptible_timeout( + &change_country_code, + msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY)); + if(status <= 0) + { + wiphy_dbg(wiphy, "info: set country timed out\n"); + } + } + else + { + wiphy_dbg(wiphy, "info: unable to set country by user\n"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + // ToDo + /* Don't change default country code to CRDA country code by user req */ + /* Shouldcall sme_ChangeCountryCode to send a message to trigger read + regd for new country settings */ + //sme_ChangeCountryCode(pHddCtx->hHal, NULL, + // &country_code[0], pAdapter, pHddCtx->pvosContext); + } + sme_GetFreqBand(pHddCtx->hHal, &nBandCapability); + if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) + { + wiphy_dbg(wiphy, "info: set by country IE\n"); + if (create_crda_regulatory_entry(wiphy, request, nBandCapability) != 0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + // ToDo + /* Intersect of 11d and crda settings */ + + /* Don't change default country code to CRDA country code by 11d req */ + /* for every adapter call sme_ChangeCountryCode to trigger read regd + for intersected new country settings */ + // sme_ChangeCountryCode(pHddCtx->hHal, NULL, + // &country_code[0], pAdapter, pHddCtx->pvosContext); + } + else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER || + (request->initiator == NL80211_REGDOM_SET_BY_CORE)|| + (request->initiator == NL80211_REGDOM_SET_BY_USER)) + { + if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen)) + { + wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal, + ccode, (v_REGDOMAIN_t *) &domainIdCurrent)) + { + wiphy_dbg(wiphy, "info: set by driver ERROR\n"); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } + + wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]); + for (n = 0; n < MAX_COUNTRY_IGNORE; n++) + { + if (vos_mem_compare(ccode, countryIgnoreList[n].countryCode, VOS_COUNTRY_CODE_LEN)) + { + countryIndex = n; + break; + } + } + /* if set by driver itself, it means driver can accept the crda + regulatory settings and wiphy->regd should be populated with crda + settings. iwiphy->bands doesn't seem to set ht40 flags in kernel + correctly, this may be fixed by later kernel */ + + for (i = 0, m = 0; i < IEEE80211_NUM_BANDS; i++) + { + if (NULL == wiphy->bands[i]) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "error: wiphy->bands[i] is NULL, i = %d", i); + continue; + } + + // internal channels[] is one continous array for both 2G and 5G bands + // m is internal starting channel index for each band + if (0 == i) + { + m = 0; + } + else + { + m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m; + } + + for (j=0; jbands[i]->n_channels; j++) + { + // k = (m + j) is internal current channel index for 20MHz channel + // n is internal channel index for corresponding 40MHz channel + k = m + j; + if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only + { + // Enable social channels for P2P + if ((2412 == wiphy->bands[i]->channels[j].center_freq || + 2437 == wiphy->bands[i]->channels[j].center_freq || + 2462 == wiphy->bands[i]->channels[j].center_freq ) && + NV_CHANNEL_ENABLE == regChannels[k].enabled) + { + wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED; + } + else + { + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + } + continue; + } + else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only + { + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + continue; + } + + if (NV_CHANNEL_DISABLE == regChannels[k].enabled || + NV_CHANNEL_INVALID == regChannels[k].enabled) + { + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + } + else if (NV_CHANNEL_DFS == regChannels[k].enabled) + { + wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED + |IEEE80211_CHAN_RADAR); + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + } + else + { + wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED + |IEEE80211_CHAN_PASSIVE_SCAN + |IEEE80211_CHAN_NO_IBSS + |IEEE80211_CHAN_RADAR); + } + + if (countryIndex != -1) + { + for (n = 0; n < MAX_CHANNELS_IGNORE; n++) + { + v_U16_t freq = vos_chan_to_freq(countryIgnoreList[countryIndex].channelList[n]); + if (wiphy->bands[i]->channels[j].center_freq == freq) + { + wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED + |IEEE80211_CHAN_PASSIVE_SCAN + |IEEE80211_CHAN_NO_IBSS + |IEEE80211_CHAN_RADAR); + wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED; + } + } + } + + } + } + + /* Haven't seen any condition that will set by driver after init. + If we do, then we should also call sme_ChangeCountryCode */ + + /* To Disable the strict regulatory FCC rule, need set + gEnableStrictRegulatoryForFCC to zero from INI. + By default regulatory FCC rule enable or set to 1, and + in this case one can control dynamically using IOCTL + (nEnableStrictRegulatoryForFCC). + If gEnableStrictRegulatoryForFCC is set to zero then + IOCTL operation is inactive */ + + if ( pHddCtx->cfg_ini->gEnableStrictRegulatoryForFCC && + wiphy->bands[IEEE80211_BAND_5GHZ]) + { + for (j=0; jbands[IEEE80211_BAND_5GHZ]->n_channels; j++) + { + // UNII-1 band channels are passive when domain is FCC. + if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) && + ((domainIdCurrent == REGDOMAIN_FCC) && + pHddCtx->nEnableStrictRegulatoryForFCC)) + { + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN; + } + else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) && + ((domainIdCurrent != REGDOMAIN_FCC) || + !pHddCtx->nEnableStrictRegulatoryForFCC)) + { + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + //Marking channels 52-144 as Radar channels if they are enabled + k = wiphy->bands[IEEE80211_BAND_2GHZ]->n_channels + j; + + if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5260 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5280 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5300 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5320 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5500 || + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5520) && + ((regChannels[k].enabled == NV_CHANNEL_ENABLE) || + (regChannels[k].enabled == NV_CHANNEL_DFS))) + { + wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_RADAR; + } + } + } + + if (request->initiator == NL80211_REGDOM_SET_BY_CORE) + { + request->processed = 1; + } + } + + complete(&pHddCtx->wiphy_channel_update_event); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) +void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + vos_ssr_protect(__func__); + __wlan_hdd_crda_reg_notifier(wiphy, request); + vos_ssr_unprotect(__func__); + return; +} +#else +int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + int ret; + vos_ssr_protect(__func__); + ret = __wlan_hdd_crda_reg_notifier(wiphy, request); + vos_ssr_unprotect(__func__); + return ret; +} +#endif + +#endif diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_packet.c b/drivers/staging/prima/CORE/VOSS/src/vos_packet.c new file mode 100644 index 000000000000..733217687af9 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_packet.c @@ -0,0 +1,3214 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_packet.c + + \brief virtual Operating System Services (vOSS) network Packet APIs + + Network Protocol packet/buffer support interfaces + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ +/* Protocol specific packet tracking feature */ +#define VOS_PKT_PROT_ETH_TYPE_OFFSET 12 +#define VOS_PKT_PROT_IP_OFFSET 14 +#define VOS_PKT_PROT_IP_HEADER_SIZE 20 +#define VOS_PKT_PROT_DHCP_SRV_PORT 67 +#define VOS_PKT_PROT_DHCP_CLI_PORT 68 +#define VOS_PKT_PROT_EAPOL_ETH_TYPE 0x888E +#define VOS_PKT_PROT_ARP_ETH_TYPE 0x0806 +#define VOS_PKT_GET_HEAD(skb) (skb->head) +#define VOS_PKT_GET_END(skb) (skb->end) + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + Data definitions + ------------------------------------------------------------------------*/ +static vos_pkt_context_t *gpVosPacketContext; + +/*------------------------------------------------------------------------- + Function declarations and documentation + ------------------------------------------------------------------------*/ + +static VOS_STATUS vos_pkti_packet_init( struct vos_pkt_t *pPkt, + VOS_PKT_TYPE pktType ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + // fixed fields + pPkt->packetType = pktType; + pPkt->magic = VPKT_MAGIC_NUMBER; + + // some packet types need an attached skb + switch (pktType) + { + case VOS_PKT_TYPE_RX_RAW: + case VOS_PKT_TYPE_TX_802_11_MGMT: + // these need an attached skb. + // we preallocate a fixed-size skb and reserve the entire buffer + // as headroom since that is what other components expect + pPkt->pSkb = alloc_skb(VPKT_SIZE_BUFFER , in_interrupt()? GFP_ATOMIC : GFP_KERNEL); + if (likely(pPkt->pSkb)) + { + skb_reserve(pPkt->pSkb, VPKT_SIZE_BUFFER); + } + else + { + vosStatus = VOS_STATUS_E_NOMEM; + } + + /* Init PAL Packet */ + WPAL_PACKET_SET_BD_POINTER(&(pPkt->palPacket), NULL); + WPAL_PACKET_SET_BD_PHYS(&(pPkt->palPacket), NULL); + WPAL_PACKET_SET_BD_LENGTH(&(pPkt->palPacket), 0); + WPAL_PACKET_SET_OS_STRUCT_POINTER(&(pPkt->palPacket), NULL); + + break; + default: + // no attached skb needed + break; + } + + return vosStatus; +} + + + +static VOS_STATUS vos_pkti_list_destroy( struct list_head *pList ) +{ + struct vos_pkt_t *pVosPacket; + + if (unlikely(NULL == pList)) + { + // something is fishy -- don't even bother trying + // clean up this list since it is apparently hosed + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pList", __LINE__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + list_for_each_entry(pVosPacket, pList, node) + { + + // is this really an initialized vos packet? + if (unlikely(VPKT_MAGIC_NUMBER != pVosPacket->magic)) + { + // no, so don't try any deinitialization on it, and + // since we can't trust the linkages, stop trying + // to destroy the list + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + VOS_ASSERT(0); + break; + } + + // does this vos packet have an skb attached? + if (pVosPacket->pSkb) + { + // yes, so give it back to the kernel + kfree_skb(pVosPacket->pSkb); + pVosPacket->pSkb = NULL; + } + + // the vos packet itself is a static portion of the vos packet context + // so there is no deallocation we have to do with it. just clear the + // magic so we no longer think it is valid + pVosPacket->magic = 0; + + } + + // all nodes of the list have been processed so reinitialize the list + INIT_LIST_HEAD(pList); + + return VOS_STATUS_SUCCESS; +} + + +static void vos_pkti_replenish_raw_pool(void) +{ + struct sk_buff * pSkb; + struct vos_pkt_t *pVosPacket; + v_BOOL_t didOne = VOS_FALSE; + vos_pkt_get_packet_callback callback; + + // if there are no packets in the replenish pool then we can't do anything + mutex_lock(&gpVosPacketContext->rxReplenishListLock); + if (likely(0 == gpVosPacketContext->rxReplenishListCount)) + { + mutex_unlock(&gpVosPacketContext->rxReplenishListLock); + return; + } + + // we only replenish if the Rx Raw pool is empty or the Replenish pool + // reaches a high water mark + mutex_lock(&gpVosPacketContext->rxRawFreeListLock); + + if ((gpVosPacketContext->rxReplenishListCount < + gpVosPacketContext->numOfRxRawPackets/4) && + (!list_empty(&gpVosPacketContext->rxRawFreeList))) + { + mutex_unlock(&gpVosPacketContext->rxRawFreeListLock); + mutex_unlock(&gpVosPacketContext->rxReplenishListLock); + return; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: Packet replenish activated", __LINE__); + + // try to replenish all of the packets in the replenish pool + while (gpVosPacketContext->rxReplenishListCount) + { + // we preallocate a fixed-size skb and reserve the entire buffer + // as headroom since that is what other components expect + pSkb = alloc_skb(VPKT_SIZE_BUFFER, GFP_ATOMIC); + if (unlikely(NULL == pSkb)) + { + gpVosPacketContext->rxReplenishFailCount++; + break; + } + skb_reserve(pSkb, VPKT_SIZE_BUFFER); + + // remove a vos packet from the replenish pool + pVosPacket = list_first_entry(&gpVosPacketContext->rxReplenishList, + struct vos_pkt_t, node); + list_del(&pVosPacket->node); + gpVosPacketContext->rxReplenishListCount--; + + // attach the skb to the vos packet + pVosPacket->pSkb = pSkb; + + // add it to the Rx Raw Free Pool + list_add_tail(&pVosPacket->node, &gpVosPacketContext->rxRawFreeList); + gpVosPacketContext->rxRawFreeListCount++; + + didOne = VOS_TRUE; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: [%p] Packet replenished", + __LINE__, pVosPacket); + + } + + // if we replenished anything and if there is a callback waiting + // then invoke the callback + if ((VOS_TRUE == didOne) && + (gpVosPacketContext->rxRawLowResourceInfo.callback)) + { + // remove the first record from the free pool + pVosPacket = list_first_entry(&gpVosPacketContext->rxRawFreeList, + struct vos_pkt_t, node); + list_del(&pVosPacket->node); + gpVosPacketContext->rxRawFreeListCount--; + + // clear out the User Data pointers in the voss packet.. + memset(&pVosPacket->pvUserData, 0, sizeof(pVosPacket->pvUserData)); + + // initialize the 'chain' pointer to NULL. + pVosPacket->pNext = NULL; + + // timestamp the vos packet. + pVosPacket->timestamp = vos_timer_get_system_ticks(); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: [%p] Packet replenish callback", + __LINE__, pVosPacket); + + callback = gpVosPacketContext->rxRawLowResourceInfo.callback; + gpVosPacketContext->rxRawLowResourceInfo.callback = NULL; + mutex_unlock(&gpVosPacketContext->rxRawFreeListLock); + mutex_unlock(&gpVosPacketContext->rxReplenishListLock); + callback(pVosPacket, gpVosPacketContext->rxRawLowResourceInfo.userData); + } + else + { + mutex_unlock(&gpVosPacketContext->rxRawFreeListLock); + mutex_unlock(&gpVosPacketContext->rxReplenishListLock); + } +} + + +#if defined( WLAN_DEBUG ) +static char *vos_pkti_packet_type_str(VOS_PKT_TYPE pktType) +{ + switch (pktType) + { + case VOS_PKT_TYPE_TX_802_11_MGMT: + return "TX_802_11_MGMT"; + break; + + case VOS_PKT_TYPE_TX_802_11_DATA: + return "TX_802_11_DATA"; + break; + + case VOS_PKT_TYPE_TX_802_3_DATA: + return "TX_802_3_DATA"; + break; + + case VOS_PKT_TYPE_RX_RAW: + return "RX_RAW"; + break; + + default: + return "UNKNOWN"; + break; + } +} +#endif // defined( WLAN_DEBUG ) + +/*--------------------------------------------------------------------------- + + \brief vos_packet_open() - initialize the vOSS Packet module + + The \a vos_packet_open() function initializes the vOSS Packet + module. + + \param pVosContext - pointer to the global vOSS Context + + \param pVosPacketContext - pointer to a previously allocated + buffer big enough to hold the vos Packet context. + + \param vosPacketContextSize - the size allocated for the vos + packet context. + + \return VOS_STATUS_SUCCESS - vos Packet module was successfully + initialized and is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the vos Packet module + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the vos packet module + + VOS_STATUS_E_INVAL - Invalid parameter passed to the vos open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the vos packet + module + + \sa vos_packet_close() + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_packet_open( v_VOID_t *pVosContext, + vos_pkt_context_t *pVosPacketContext, + v_SIZE_t vosPacketContextSize ) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + unsigned int freePacketIndex; + unsigned int idx; + struct vos_pkt_t *pPkt; + struct list_head *pFreeList; + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "Enter:%s",__func__); + + do + { + + if (NULL == pVosContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pVosContext", __LINE__); + vosStatus = VOS_STATUS_E_INVAL; + break; + } + + if (NULL == pVosPacketContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pVosPacketContext", __LINE__); + vosStatus = VOS_STATUS_E_INVAL; + break; + } + + if (sizeof(vos_pkt_context_t) != vosPacketContextSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: invalid vosPacketContextSize, %zu vs %d", + __LINE__, sizeof(vos_pkt_context_t), vosPacketContextSize); + vosStatus = VOS_STATUS_E_INVAL; + break; + } + + // clear the vos packet context. in the process this will + // initialize the low resource info blocks + memset(pVosPacketContext, 0, vosPacketContextSize); + + // save a global pointer to the vos packet context. + gpVosPacketContext = pVosPacketContext; + + // save the vos Context pointer in the vos Packet Context. + pVosPacketContext->vosContext = pVosContext; + + // initialize the rx Replenish pool (initially empty) + mutex_init(&gpVosPacketContext->rxReplenishListLock); + INIT_LIST_HEAD(&pVosPacketContext->rxReplenishList); + pVosPacketContext->rxReplenishListCount = 0; + + // index into the packet context's vosPktBuffer[] array + freePacketIndex = 0; + + // initialize the rxRaw free list pool + mutex_init(&gpVosPacketContext->rxRawFreeListLock); + pFreeList = &pVosPacketContext->rxRawFreeList; + pVosPacketContext->rxRawFreeListCount = 0; + INIT_LIST_HEAD(pFreeList); + + pVosPacketContext->numOfRxRawPackets = vos_pkt_get_num_of_rx_raw_pkts(); + + // fill the rxRaw free list + for (idx = 0; idx < pVosPacketContext->numOfRxRawPackets; idx++) + { + pPkt = &pVosPacketContext->vosPktBuffers[freePacketIndex++]; + vosStatus = vos_pkti_packet_init(pPkt, VOS_PKT_TYPE_RX_RAW); + + WPAL_PACKET_SET_METAINFO_POINTER(&(pPkt->palPacket), + (void*)&pVosPacketContext->rxMetaInfo[idx]); + WPAL_PACKET_SET_TYPE(&(pPkt->palPacket), + eWLAN_PAL_PKT_TYPE_RX_RAW); + + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Packet init failure", __LINE__); + break; + } + list_add_tail(&pPkt->node, pFreeList); + pVosPacketContext->rxRawFreeListCount++; + } + + // exit if any problems so far + if (VOS_STATUS_SUCCESS != vosStatus) + { + break; + } + + // initialize the txData free list pool + mutex_init(&gpVosPacketContext->txDataFreeListLock); + pFreeList = &pVosPacketContext->txDataFreeList; + INIT_LIST_HEAD(pFreeList); + + // fill the txData free list + for (idx = 0; idx < VPKT_NUM_TX_DATA_PACKETS; idx++) + { + pPkt = &pVosPacketContext->vosPktBuffers[freePacketIndex++]; + vosStatus = vos_pkti_packet_init(pPkt, VOS_PKT_TYPE_TX_802_3_DATA); + WPAL_PACKET_SET_METAINFO_POINTER(&(pPkt->palPacket), + (void*)&pVosPacketContext->txDataMetaInfo[idx]); + WPAL_PACKET_SET_TYPE(&(pPkt->palPacket), + eWLAN_PAL_PKT_TYPE_TX_802_3_DATA); + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Packet init failure", __LINE__); + break; + } + list_add_tail(&pPkt->node, pFreeList); + pVosPacketContext->uctxDataFreeListCount++; + } + + // exit if any problems so far + if (VOS_STATUS_SUCCESS != vosStatus) + { + break; + } + + // initialize the txMgmt free list pool + mutex_init(&gpVosPacketContext->txMgmtFreeListLock); + pFreeList = &pVosPacketContext->txMgmtFreeList; + INIT_LIST_HEAD(pFreeList); + + // fill the txMgmt free list + for (idx = 0; idx < VPKT_NUM_TX_MGMT_PACKETS; idx++) + { + pPkt = &pVosPacketContext->vosPktBuffers[freePacketIndex++]; + + vosStatus = vos_pkti_packet_init(pPkt, VOS_PKT_TYPE_TX_802_11_MGMT); + + WPAL_PACKET_SET_METAINFO_POINTER(&(pPkt->palPacket), + (void*)&pVosPacketContext->txMgmtMetaInfo[idx]); + WPAL_PACKET_SET_TYPE(&(pPkt->palPacket), + eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT); + + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Packet init failure", __LINE__); + break; + } + list_add_tail(&pPkt->node, pFreeList); + } + + // exit if any problems so far + if (VOS_STATUS_SUCCESS != vosStatus) + { + break; + } + + } while (0); + + return vosStatus; +} + + + +/*--------------------------------------------------------------------------- + + \brief vos_packet_close() - Close the vOSS Packet module + + The \a vos_packet_close() function closes the vOSS Packet module + Upon successful close all resources allocated from the OS will be + relinquished. + + \param pVosContext - pointer to the global vOSS Context + + \return VOS_STATUS_SUCCESS - Packet module was successfully closed. + + VOS_STATUS_E_INVAL - Invalid parameter passed to the packet + close function + + VOS_STATUS_E_FAILURE - Failure to close the vos Packet module + + \sa vos_packet_open() + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_packet_close( v_PVOID_t pVosContext ) +{ + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "Enter:%s",__func__); + + if (unlikely(NULL == pVosContext)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pVosContext", __LINE__); + return VOS_STATUS_E_INVAL; + } + + if (unlikely(gpVosPacketContext->vosContext != pVosContext)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: invalid pVosContext", __LINE__); + return VOS_STATUS_E_INVAL; + } + + + mutex_lock(&gpVosPacketContext->txMgmtFreeListLock); + (void) vos_pkti_list_destroy(&gpVosPacketContext->txMgmtFreeList); + mutex_unlock(&gpVosPacketContext->txMgmtFreeListLock); + + mutex_lock(&gpVosPacketContext->txDataFreeListLock); + (void) vos_pkti_list_destroy(&gpVosPacketContext->txDataFreeList); + gpVosPacketContext->uctxDataFreeListCount = 0; + mutex_unlock(&gpVosPacketContext->txDataFreeListLock); + + mutex_lock(&gpVosPacketContext->rxRawFreeListLock); + (void) vos_pkti_list_destroy(&gpVosPacketContext->rxRawFreeList); + gpVosPacketContext->rxRawFreeListCount = 0; + mutex_unlock(&gpVosPacketContext->rxRawFreeListLock); + + mutex_lock(&gpVosPacketContext->rxReplenishListLock); + (void) vos_pkti_list_destroy(&gpVosPacketContext->rxReplenishList); + gpVosPacketContext->rxReplenishListCount = 0; + mutex_unlock(&gpVosPacketContext->rxReplenishListLock); + + + + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet() - Get a voss Packet + + Gets a voss Packet from an internally managed packet pool. + + \param ppPacket - pointer to location where the voss Packet pointer is + returned. If multiple packets are requested, they + will be chained onto this first packet. + + \param pktType - the packet type to be retreived. Valid packet types are: +
      +
    • VOS_PKT_TYPE_TX_802_11_MGMT - voss packet is for Transmitting + 802.11 Management frames. + +
    • VOS_PKT_TYPE_RX_RAW - voss Packet contains a buffer for Receiving + raw frames of unknown type. +
    + + \param dataSize - the Data size needed in the voss Packet. + + \param numPackets - the number of packets requested. + + \param zeroBuffer - parameter that tells the API to zero the data buffer + in this voss Packet. +
      +
    • VOS_TRUE - the API will zero out the entire data buffer. + +
    • VOS_FALSE - the API will not zero out the data buffer. +
    + + \note If enough room for headers to transmit or receive the packet is not + available, this API will fail. + + \param callback - This callback function, if provided, is invoked in the + case when resources are not available at the time of the call to + get packets. This callback function is invoked when packets are + available. + + \param userData - This user data is passed back to the caller in the + callback function, if the callback is invoked. + + \return VOS_STATUS_SUCCESS - the API was able to get a vos_packet for the + requested type. *ppPacket contains a pointer to the packet. + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets for 802_11_MGMT and + RX_RAW packet types. This status is also returned if the + numPackets or dataSize are invalid. + + VOS_STATUS_E_RESOURCES - unable to get resources needed to get + a vos packet. If a callback function is specified and this + status is returned from the API, the callback will be called + when resources are available to fulfill the original request. + + Note that the low resources condition is indicated to the caller + by returning VOS_STATUS_E_RESOURCES. This status is the only + non-success status that indicates to the caller that the callback + will be called when resources are available. All other status + indicate failures that are not recoverable and the 'callback' + will not be called. + + VOS_STATUS_E_FAILURE - The API returns this status when unable + to get a packet from the packet pool because the pool + is depleted and the caller did not specify a low resource callback. + + VOS_STATUS_E_ALREADY - This status is returned when the VOS + packet pool is in a 'low resource' condition and cannot + accomodate any more calls to retrieve packets from that + pool. Note this is a FAILURE and the 'low resource' callback + will *not* be called. + + VOS_STATUS_E_FAULT - ppPacket does not specify a valid pointer. + + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet( vos_pkt_t **ppPacket, + VOS_PKT_TYPE pktType, + v_SIZE_t dataSize, + v_SIZE_t numPackets, + v_BOOL_t zeroBuffer, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ) +{ + struct list_head *pPktFreeList; + vos_pkt_low_resource_info *pLowResourceInfo; + struct vos_pkt_t *pVosPacket; + v_SIZE_t *pCount = NULL; + struct mutex *mlock; + + // Validate the return parameter pointer + if (unlikely(NULL == ppPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL ppPacket", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // we only support getting 1 packet at this time (as do WM & AMSS) + if (unlikely(1 != numPackets)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: invalid numPackets, %d", __LINE__, numPackets); + return VOS_STATUS_E_INVAL; + } + + // Validate the dataSize is within range + if (unlikely((0 == dataSize) || (dataSize > VPKT_SIZE_BUFFER))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: invalid dataSize, %d", __LINE__, dataSize); + return VOS_STATUS_E_INVAL; + } + + // determine which packet pool and low resource block we should use. + // this API is only valid for TX MGMT and RX RAW packets + // (TX DATA will use vos_pkt_wrap_data_packet()) + switch (pktType) + { + + case VOS_PKT_TYPE_RX_RAW: + pPktFreeList = &gpVosPacketContext->rxRawFreeList; + pLowResourceInfo = &gpVosPacketContext->rxRawLowResourceInfo; + mlock = &gpVosPacketContext->rxRawFreeListLock; + + // see if we need to replenish the Rx Raw pool + vos_pkti_replenish_raw_pool(); + pCount = &gpVosPacketContext->rxRawFreeListCount; + + break; + + case VOS_PKT_TYPE_TX_802_11_MGMT: + pPktFreeList = &gpVosPacketContext->txMgmtFreeList; + pLowResourceInfo = &gpVosPacketContext->txMgmtLowResourceInfo; + mlock = &gpVosPacketContext->txMgmtFreeListLock; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: invalid packet type %d[%s]", + __LINE__, pktType, vos_pkti_packet_type_str(pktType)); + return VOS_STATUS_E_INVAL; + } + + // is there already a low resource callback registered for this pool? + // we only support one callback per pool, so if one is already registered + // then we know we are already in a low-resource condition + if (unlikely(pLowResourceInfo->callback)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Low resource handler already registered", + __LINE__); + return VOS_STATUS_E_ALREADY; + } + + mutex_lock(mlock); + // are there vos packets on the associated free pool? + if (unlikely(list_empty(pPktFreeList))) + { + // allocation failed + // did the caller specify a callback? + if (unlikely(NULL == callback)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Low resource condition and no callback provided", + __LINE__); + mutex_unlock(mlock); + + return VOS_STATUS_E_FAILURE; + } + + // save the low resource information so that we can invoke the + // callback when a packet becomes available + pLowResourceInfo->callback = callback; + pLowResourceInfo->userData = userData; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Low resource condition for packet type %d[%s]", + __LINE__, pktType, vos_pkti_packet_type_str(pktType)); + mutex_unlock(mlock); + + return VOS_STATUS_E_RESOURCES; + } + + // remove the first record from the free pool + pVosPacket = list_first_entry(pPktFreeList, struct vos_pkt_t, node); + list_del(&pVosPacket->node); + if (NULL != pCount) + { + (*pCount)--; + } + mutex_unlock(mlock); + + // clear out the User Data pointers in the voss packet.. + memset(&pVosPacket->pvUserData, 0, sizeof(pVosPacket->pvUserData)); + + // initialize the 'chain' pointer to NULL. + pVosPacket->pNext = NULL; + + // set the packet type. + pVosPacket->packetType = pktType; + + // timestamp the vos packet. + pVosPacket->timestamp = vos_timer_get_system_ticks(); + + // zero the data buffer if the user asked for it to be cleared. + if (unlikely(zeroBuffer)) + { + memset(pVosPacket->pSkb->head, + 0, + skb_end_pointer(pVosPacket->pSkb) - pVosPacket->pSkb->head); + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: [%p] Packet allocated, type %d[%s]", + __LINE__, pVosPacket, pktType, vos_pkti_packet_type_str(pktType)); + + *ppPacket = pVosPacket; + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_wrap_data_packets() - Wrap an OS provided data packet in a + vos packet. + + Takes as input an OS provided data packet and 'wraps' that packet in a + vos_packet, returning the vos_packet to the caller. + + This function is intended to be called from the HDD to wrap Tx data packets + from the OS into vos_packets before sending them to TL for transmission. + + \param ppPacket - pointer to location where the voss Packet pointer is + returned. If multiple packets are requested, they + will be chained onto this first packet. + + \param pktType - the packet type to be retreived. Valid packet types are: +
      +
    • VOS_PKT_TYPE_802_3_DATA - voss packet is for Transmitting 802.3 + data frames. + +
    • VOS_PKT_TYPE_802_11_DATA - voss Packet is for Transmitting 802.11 + data frames. +
    + + \param pOSPacket - a pointer to the Transmit packet provided by the OS. This + OS provided packet will be wrapped into a vos_packet_t. Note this + OS packet pointer can be NULL. The OS packet pointer can be inserted + into a VOS packet of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA through vos_pkt_set_os_packet(). + + \note If enough room for headers to transmit or receive the packet is not + available, this API will fail. + + \param callback - This callback function, if provided, is invoked in the + case where packets are not available at the time of the call to + return the packets to the caller (a 'low resource' condition). + + When packets become available, the callback callback function is + invoked to return a VOS packet to the caller. Note that the + OS Packet is *not* inserted into the VOS packet when it is returned + to the low resource callback. It is up to the caller to insert + the OS packet into the VOS packet by calling vos_pkt_set_os_packet() + + \param userData - This user data is passed back to the caller in the + callback function, if the callback is invoked. + + \return VOS_STATUS_SUCCESS - the API was able to get a vos_packet for the + requested type. *ppPacket contains a pointer to the packet. + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets for 802_11_MGMT and + RX_RAW packet types. + + VOS_STATUS_E_RESOURCES - unable to get resources needed to get + a vos packet. If a callback function is specified and this + status is returned from the API, the callback will be called + when resources are available to fulfill the original request. + + Note that the low resources condition is indicated to the caller + by returning VOS_STATUS_E_RESOURCES. This status is the only + non-success status that indicates to the caller that the callback + will be called when resources are available. All other status + indicate failures that are not recoverable and the 'callback' + will not be called. + + VOS_STATUS_E_FAILURE - The API returns this status when unable + to get a packet from the packet pool because the pool + is depleted and the caller did not specify a low resource callback. + + VOS_STATUS_E_ALREADY - This status is returned when the VOS + packet pool is in a 'low resource' condition and cannot + accomodate any more calls to retrieve packets from that + pool. Note this is a FAILURE and the 'low resource' callback + will *not* be called. + + VOS_STATUS_E_FAULT - ppPacket or pOSPacket do not specify valid + pointers. + + \sa vos_pkt_set_os_packet() + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_wrap_data_packet( vos_pkt_t **ppPacket, + VOS_PKT_TYPE pktType, + v_VOID_t *pOSPacket, + vos_pkt_get_packet_callback callback, + v_VOID_t *userData ) +{ + struct list_head *pPktFreeList; + vos_pkt_low_resource_info *pLowResourceInfo; + struct vos_pkt_t *pVosPacket; + struct mutex *mlock; + + // Validate the return parameter pointer + if (unlikely(NULL == ppPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL ppPacket", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate the packet type. Only Tx Data packets can have an OS + // packet attached to them (Tx Mgmt and Rx Raw have OS packets + // pre-attached to them) + if (unlikely(VOS_PKT_TYPE_TX_802_3_DATA != pktType)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: invalid pktType %d", __LINE__, pktType); + return VOS_STATUS_E_INVAL; + } + + // determine which packet pool and low resource block we should use. + pPktFreeList = &gpVosPacketContext->txDataFreeList; + pLowResourceInfo = &gpVosPacketContext->txDataLowResourceInfo; + mlock = &gpVosPacketContext->txDataFreeListLock; + + mutex_lock(mlock); + + // is there already a low resource callback registered for this pool? + // we only support one callback per pool, so if one is already registered + // then we know we are already in a low-resource condition + if (unlikely(pLowResourceInfo->callback)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Low resource handler already registered", + __LINE__); + mutex_unlock(mlock); + return VOS_STATUS_E_ALREADY; + } + + // are there vos packets on the associated free pool? + if (unlikely(list_empty(pPktFreeList))) + { + // allocation failed + // did the caller specify a callback? + if (unlikely(NULL == callback)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Low resource condition and no callback provided", + __LINE__); + mutex_unlock(mlock); + return VOS_STATUS_E_FAILURE; + } + + // save the low resource information so that we can invoke the + // callback when a packet becomes available + pLowResourceInfo->callback = callback; + pLowResourceInfo->userData = userData; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Low resource condition for pool %s", + __LINE__, vos_pkti_packet_type_str(pktType)); + mutex_unlock(mlock); + return VOS_STATUS_E_RESOURCES; + } + + // remove the first record from the free pool + pVosPacket = list_first_entry(pPktFreeList, struct vos_pkt_t, node); + list_del(&pVosPacket->node); + gpVosPacketContext->uctxDataFreeListCount --; + mutex_unlock(mlock); + + // clear out the User Data pointers in the voss packet.. + memset(&pVosPacket->pvUserData, 0, sizeof(pVosPacket->pvUserData)); + + // initialize the 'chain' pointer to NULL. + pVosPacket->pNext = NULL; + + // set the packet type. + pVosPacket->packetType = pktType; + + // set the skb pointer + pVosPacket->pSkb = (struct sk_buff *) pOSPacket; + + // timestamp the vos packet. + pVosPacket->timestamp = vos_timer_get_system_ticks(); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: [%p] Packet allocated, type %s", + __LINE__, pVosPacket, vos_pkti_packet_type_str(pktType)); + + *ppPacket = pVosPacket; + return VOS_STATUS_SUCCESS; +} + + + +/*--------------------------------------------------------------------------- + + \brief vos_pkt_set_os_packet() - set the OS packet in a VOS data packet + + This API inserts an OS packet into a previously retreived VOS packet. + This API only applies to VOS packets of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA. + + There are cases where a user will need to get a VOS data packet without + having the OS packet to insert/wrap into the data packet. This could happen + if the user calls vos_pkt_wrap_data_packet() without the OS packet. + + Also, when the user hit a 'low resource' situation for data packets, the + low resource callback is going to return a VOS packet without an OS packet + attached to it. The caller who gets the packet through the low resource + callback uses this API to insert an OS packet into the VOS packet that + was returned through the low resource callback. + + \param pPacket - the voss Packet to insert the OS packet into. + + \param pOSPacket - a pointer to the Transmit packet provided by the OS. This + OS provided packet will be wrapped into a vos_packet_t. Note this + OS packet pointer can be NULL. The OS packet pointer can be inserted + into a VOS packet of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA through vos_pkt_set_os_packet(). + + Caller beware. If there is a valid OS packet wrapped into this + VOS packet already, this API will blindly overwrite the OS packet + with the new one specified on this API call. If you need to determine + or retreive the current OS packet from a VOS packet, call + vos_pkt_get_os_packet() first. + + \return VOS_STATUS_SUCCESS - the API was able to insert the OS packet into + the vos_packet. + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets of type + VOS_PKT_TYPE_802_3_DATA or VOS_PKT_TYPE_802_11_DATA. + + VOS_STATUS_E_FAULT - pPacket does not specify a valid pointer. + + \sa vos_pkt_get_os_packet() + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_set_os_packet( vos_pkt_t *pPacket, + v_VOID_t *pOSPacket ) +{ + // Validate the input parameter pointers + if (unlikely((NULL == pPacket)||(NULL == pOSPacket))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate the packet type. Only Tx Data packets can have an OS + // packet attached to them (Tx Mgmt and Rx Raw have OS packets + // pre-attached to them) + if (unlikely(VOS_PKT_TYPE_TX_802_3_DATA != pPacket->packetType)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: invalid packet type %d[%s]", + __LINE__, pPacket->packetType, + vos_pkti_packet_type_str(pPacket->packetType)); + return VOS_STATUS_E_INVAL; + } + + // Is there already a packet attached? If so, just warn and continue + if (unlikely(pPacket->pSkb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Packet previously attached", __LINE__); + } + + // attach + pPacket->pSkb = (struct sk_buff *) pOSPacket; + + return VOS_STATUS_SUCCESS; +} + + +/*--------------------------------------------------------------------------- + + \brief vos_pkt_get_os_packet() - get the OS packet in a VOS data packet + + This API returns the OS packet that is inserted in a VOS packet. + This API only applies to VOS packets of type VOS_PKT_TYPE_802_3_DATA or + VOS_PKT_TYPE_802_11_DATA. + + \param pPacket - the voss Packet to return the OS packet from. + + \param ppOSPacket - a pointer to the location where the OS packet pointer + retreived from the VOS packet will be returned. Note this OS packet + pointer can be NULL, meaning there is no OS packet attached to this + VOS data packet. + + \param clearOSPacket - a boolean value that tells the API to clear out the + OS packet pointer from the VOS packet. Setting this to 'true' will + essentially remove the OS packet from the VOS packet. 'false' means + the OS packet remains chained to the VOS packet. In either case, + the OS packet pointer is returned to the caller. + + \return VOS_STATUS_SUCCESS - the API was able to retreive the OS packet + pointer from the VOS packet and return it to the caller in + *ppOsPacket + + VOS_STATUS_E_INVAL - pktType is not a valid packet type. This + API only supports getting vos packets of type + VOS_PKT_TYPE_802_3_DATA or VOS_PKT_TYPE_802_11_DATA. + + VOS_STATUS_E_FAULT - pPacket or ppOsPacket does not specify a valid + pointers. + + \sa vos_pkt_set_os_packet(), vos_pkt_wrap_data_packet(), + vos_pkt_return_packet() + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_os_packet( vos_pkt_t *pPacket, + v_VOID_t **ppOSPacket, + v_BOOL_t clearOSPacket ) +{ + // Validate the input and output parameter pointers + if (unlikely((NULL == pPacket)||(NULL == ppOSPacket))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get OS packet pointer + *ppOSPacket = (v_VOID_t *) pPacket->pSkb; + + // clear it? + if (clearOSPacket) + { + pPacket->pSkb = NULL; + } + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_user_data_ptr() - return a pointer to user data area + of a voss Packet + + This API returns a pointer to a specified user Data area in the voss + Packet. User data areas are uniqua areas of the voss Packet that can + be used by specific components to store private data. These areas are + identified by a user "ID" and should only be accessed by the component + specified. + + \param pPacket - the voss Packet to retreive the user data pointer from. + + \param userID - the identifier for the user data area in the voss Packet + to get. + + User IDs and user data areas in the voss Packet are + available for: + - Transport Layer (TL) + - Bus Abstraction Layer (BAL) + - SDIO Services Component (SSC) + - Host Device Driver (HDD) + + \param ppUserData - pointer to location to return the pointer to the user + data. + + \return - Nothing. + + \sa + + ---------------------------------------------------------------------------*/ +v_VOID_t vos_pkt_get_user_data_ptr( vos_pkt_t *pPacket, + VOS_PKT_USER_DATA_ID userID, + v_VOID_t **ppUserData ) +{ + // Validate the input and output parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + if (ppUserData != NULL) + { + *ppUserData = NULL; + } + return; + } + + // Validate that this really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + *ppUserData = NULL; + return; + } + + // Validate userID + if (unlikely(userID >= VOS_PKT_USER_DATA_ID_MAX)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Invalid user ID [%d]", __LINE__, userID); + *ppUserData = NULL; + return; + } + + // retreive the user data pointer from the vos Packet and + // return it to the caller. + *ppUserData = pPacket->pvUserData[userID]; + + return; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_set_user_data_ptr() - set the user data pointer of a voss + Packet + + This API sets a pointer in the specified user Data area in the voss + Packet. User data areas are uniqua areas of the voss Packet that can + be used by specific components to store private data. These areas are + identified by a user "ID" and should only be accessed by the component + specified. + + Note: The size of the user data areas in the voss Packet are fixed. The + size of a single pointer is available in each user area. + + \param pPacket - the voss Packet to set the user pointer. + + \param userID - the identifier for the user data area in the voss Packet + to set. + + User IDs and user data areas in the voss Packet are + available for: + - Transport Layer (TL) + - Bus Abstraction Layer (BAL) + - SDIO Services Component (SSC) + - Host Device Driver (HDD) + + \param pUserData - pointer value to set in the user data area of the voss + packet.. + + \return - Nothing. + + \sa + + ---------------------------------------------------------------------------*/ +v_VOID_t vos_pkt_set_user_data_ptr( vos_pkt_t *pPacket, + VOS_PKT_USER_DATA_ID userID, + v_VOID_t *pUserData ) +{ + // Validate the input parameter pointer + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return; + } + + // Validate userID + if (unlikely(userID >= VOS_PKT_USER_DATA_ID_MAX)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Invalid user ID [%d]", __LINE__, userID); + return; + } + + // retreive the user data pointer from the vos Packet and + // return it to the caller. + pPacket->pvUserData[userID] = pUserData; + + return; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_return_packet() - Return a voss Packet (chain) to vOSS + + This API returns a voss Packet to the internally managed packet pool. + + Note: If there are multiple packets chained to this packet, the entire + packet chain is returned to vOSS. The caller must unchain the + packets through vos_pkt_get_next_packet() and return them individually + if all packets in the packet chain are not to be returned. + + \param pPacket - the voss Packet(s) to return. Note all packets chained + to this packet are returned to vOSS. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_return_packet( vos_pkt_t *pPacket ) +{ + vos_pkt_t *pNext; + struct list_head *pPktFreeList; + vos_pkt_low_resource_info *pLowResourceInfo; + vos_pkt_get_packet_callback callback; + v_SIZE_t *pCount; + VOS_PKT_TYPE packetType = VOS_PKT_TYPE_TX_802_3_DATA; + v_BOOL_t lowResource; + struct mutex * mlock; + + // Validate the input parameter pointer + if (unlikely(NULL == pPacket)) + { + return VOS_STATUS_E_INVAL; + } + + // iterate though all packets in the chain + while (pPacket) + { + // unlink this packet from the chain + pNext = pPacket->pNext; + pPacket->pNext = NULL; + + lowResource = VOS_FALSE; + // Validate that this really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + //If an skb is attached then reset the pointers + if (pPacket->pSkb) + { + pPacket->pSkb->len = 0; + pPacket->pSkb->data = pPacket->pSkb->head; + skb_reset_tail_pointer(pPacket->pSkb); + skb_reserve(pPacket->pSkb, VPKT_SIZE_BUFFER); + } + + pCount = NULL; + // determine which packet pool and low resource block we should use. + switch (pPacket->packetType) + { + case VOS_PKT_TYPE_RX_RAW: + // if this packet still has an skb attached, we can put it + // back in the free pool, otherwise we need to put it in the + // replenish pool + if (pPacket->pSkb) + { + pPktFreeList = &gpVosPacketContext->rxRawFreeList; + pLowResourceInfo = &gpVosPacketContext->rxRawLowResourceInfo; + pCount = &gpVosPacketContext->rxRawFreeListCount; + mlock = &gpVosPacketContext->rxRawFreeListLock; + } + else + { + pPktFreeList = &gpVosPacketContext->rxReplenishList; + pLowResourceInfo = NULL; + pCount = &gpVosPacketContext->rxReplenishListCount; + mlock = &gpVosPacketContext->rxReplenishListLock; + } + packetType = VOS_PKT_TYPE_RX_RAW; + break; + + case VOS_PKT_TYPE_TX_802_11_MGMT: + + pPktFreeList = &gpVosPacketContext->txMgmtFreeList; + pLowResourceInfo = &gpVosPacketContext->txMgmtLowResourceInfo; + mlock = &gpVosPacketContext->txMgmtFreeListLock; + + break; + + case VOS_PKT_TYPE_TX_802_3_DATA: + pPktFreeList = &gpVosPacketContext->txDataFreeList; + pLowResourceInfo = &gpVosPacketContext->txDataLowResourceInfo; + mlock = &gpVosPacketContext->txDataFreeListLock; + gpVosPacketContext->uctxDataFreeListCount ++; + break; + + default: + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: invalid packet type %d[%s]", + __LINE__, pPacket->packetType, + vos_pkti_packet_type_str(pPacket->packetType)); + + return VOS_STATUS_E_INVAL; + } + + + // is there a low resource condition pending for this packet type? + if (pLowResourceInfo && pLowResourceInfo->callback) + { + // pLowResourceInfo->callback is modified from threads (different CPU's). + // So a mutex is enough to protect is against a race condition. + // mutex is SMP safe + mutex_lock(mlock); + callback = pLowResourceInfo->callback; + pLowResourceInfo->callback = NULL; + mutex_unlock(mlock); + + // only one context can get a valid callback + if(callback) + { + // [DEBUG] + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,"VPKT [%d]: recycle %p", __LINE__, pPacket); + + // yes, so rather than placing the packet back in the free pool + // we will invoke the low resource callback + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: [%p] Packet recycled, type %d[%s]", + __LINE__, pPacket, pPacket->packetType, + vos_pkti_packet_type_str(pPacket->packetType)); + + // clear out the User Data pointers in the voss packet.. + memset(&pPacket->pvUserData, 0, sizeof(pPacket->pvUserData)); + + // initialize the 'chain' pointer to NULL. + pPacket->pNext = NULL; + + // timestamp the vos packet. + pPacket->timestamp = vos_timer_get_system_ticks(); + + callback(pPacket, pLowResourceInfo->userData); + + // We did process low resource condition + lowResource = VOS_TRUE; + } + } + + + if(!lowResource) + { + // this packet does not satisfy a low resource condition + // so put it back in the appropriate free pool + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "VPKT [%d]: [%p] Packet returned, type %d[%s]", + __LINE__, pPacket, pPacket->packetType, + vos_pkti_packet_type_str(pPacket->packetType)); + mutex_lock(mlock); + list_add_tail(&pPacket->node, pPktFreeList); + + if (pCount) + { + (*pCount)++; + } + mutex_unlock(mlock); + } + + // move to next packet in the chain + pPacket = pNext; + + } // while (pPacket) + + // see if we need to replenish the Rx Raw pool + if (VOS_PKT_TYPE_RX_RAW == packetType) + { + vos_pkti_replenish_raw_pool(); + } + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_chain_packet() - chain a voss Packet to another packet + + This API chains a voss Packet to another voss Packet, creating a packet + chain. Packets can be chained before or after the current packet in the + packet chain. + + \param pPacket - pointer to a voss packet to chain to + + \param pChainPacket - pointer to packet to chain + + \param chainAfter - boolean to specify to chain packet after or before + the input packet +
      +
    • true - chain packet AFTER pPacket (chain behind) +
    • false - chain packet BEFORE pPacket (chain in front) +
    + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_chain_packet( vos_pkt_t *pPacket, + vos_pkt_t *pChainPacket, + v_BOOL_t chainAfter ) +{ + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == pChainPacket))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that these are really initialized vos packets + if (unlikely((VPKT_MAGIC_NUMBER != pPacket->magic) || + (VPKT_MAGIC_NUMBER != pChainPacket->magic))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // swap pointers if we chain before + if (unlikely(VOS_FALSE == chainAfter)) + { + vos_pkt_t *pTmp = pPacket; + pPacket = pChainPacket; + pChainPacket = pTmp; + } + + // find the end of the chain + while (pPacket->pNext) + { + pPacket = pPacket->pNext; + } + + // attach + pPacket->pNext = pChainPacket; + + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_walk_packet_chain() - Walk packet chain and (possibly) + unchain packets + + This API will walk the voss Packet and unchain the packet from the chain, + if specified. The 'next' packet in the packet chain is returned as the + packet chain is traversed. + + \param pPacket - input vos_packet walk + + \param ppChainedPacket - pointer to location to return the 'next' voss + packet pointer in the packet chain. + NULL means there is was not packet chained + to this packet. + + \param unchainPacket - Flag that specifies if the caller wants the packet + to be removed from the packet chain. This is + provided to allow the caller to walk the packet chain + with or without breaking the chain. + +
      +
    • true - when set 'true' the API will return + the 'next' packet pointer in the voss Packte chain and + *WILL* unchain the input packet from the packet chain. + +
    • NOT false - when set 'false' the API will return + the 'next' packet pointer in the voss Packet chain but + *WILL NOT* unchain the packet chain. This option gives + the caller the ability to walk the packet chain without + modifying it in the process. +
    + + \note Having the packets chained has an implicaiton on how the return + packet API (vos_pkt_return_packet() ) operates. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_walk_packet_chain( vos_pkt_t *pPacket, + vos_pkt_t **ppChainedPacket, + v_BOOL_t unchainPacket ) +{ + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == ppChainedPacket))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get next packet + *ppChainedPacket = pPacket->pNext; + + // if asked to unchain, then unchain it + if (VOS_FALSE != unchainPacket) + { + pPacket->pNext = NULL; + } + + // if end of the chain, indicate empty to the caller + if (*ppChainedPacket) + { + return VOS_STATUS_SUCCESS; + } + else + { + return VOS_STATUS_E_EMPTY; + } +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_data_vector() - Get data vectors from a voss Packet + + This API gets the complete set of Vectors (pointer / length pairs) that + describe all of the data that makes up the voss Packet. + + \param pPacket - pointer to the vOSS Packet to get the pointer/length + vector from + + \param pVector - pointer to the vector array where the vectors are returned. + + \param pNumVectors - Number of vector's in the vector array (at pVector). + On successful return, *pNumVectors is updated with the + number of pointer/length vectors at pVector populated + with valid vectors. + + Call with NULL pVector or 0 vectorSize, will return the size of vector + needed (in *pNumVectors) + + Caller allocates and frees the vector memory. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_data_vector( vos_pkt_t *pPacket, + vos_pkt_data_vector_t *pVector, + v_SIZE_t *pNumVectors ) +{ + // not supported + + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_extract_data() - Extract data from the voss Packet. + + This API extracts data from a voss Packet, copying the data into the + supplied output buffer. Note the data is copied from the vos packet + but the data remains in the vos packet and the size is unaffected. + + \param pPacket - the voss Packet to get the data from. + + \param pktOffset - the offset from the start of the voss Packet to get the + data. (i.e. 0 would be the beginning of the voss Packet). + + \param pOutputBuffer - Pointer to the location where the voss Packet data + will be copied. + + \param pOutputBufferSize - on input, contains the amount of data to extract + into the output buffer. Upon return, contains the amount of data + extracted into the output buffer. + + Note: an input of 0 in *pOutputBufferSize, means to copy *all* + data in the voss Packet into the output buffer. The caller is + responsible for assuring the output buffer size is big enough + since the size of the buffer is not being passed in! + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_extract_data( vos_pkt_t *pPacket, + v_SIZE_t pktOffset, + v_VOID_t *pOutputBuffer, + v_SIZE_t *pOutputBufferSize ) +{ + v_SIZE_t len; + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || + (NULL == pOutputBuffer) || + (NULL == pOutputBufferSize))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get number of bytes requested + len = *pOutputBufferSize; + + // if 0 is input in the *pOutputBufferSize, then the user wants us to + // extract *all* the data in the buffer. Otherwise, the user has + // specified the output buffer size in *pOutputBufferSize. In the + // case where the output buffer size is specified, let's validate that + // it is big enough. + // + // \note: i'm not crazy about this. we should enforce the output + // buffer size on input so this API is not going to cause crashes + // because buffers are too small and the caller inputs 0 == don't care + // to check the size... !! + if (0 == len) + { + len = skb->len - pktOffset; + + // return # of bytes copied + *pOutputBufferSize = len; + } + else + { + // make sure we aren't extracting past the end of the packet + if (len > (skb->len - pktOffset)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Request overrun, " + "req offset %d, req size %d, packet size %d", + __LINE__, pktOffset, len, skb->len); + return VOS_STATUS_E_INVAL; + } + } + + // copy the data + vos_mem_copy(pOutputBuffer, &skb->data[pktOffset], len); + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_extract_data_chain() - Extract data from a voss Packet chain. + + This API extracts *all* the data from a voss Packet chain, copying the + data into the supplied output buffer. Note the data is copied from + the vos packet chain but the data remains in the vos packet and the + size of the vos packets are unaffected. + + \param pPacket - the first voss Packet in the voss packet chain to + extract data. + + \param pOutputBuffer - Pointer to the location where the voss Packet data + will be copied. + + \param pOutputBufferSize - on input, contains the maximum amount of data + that can be extracted into the output buffer. Upon return, contains + the amount of data extracted from the packet chain. + + \return VOS_STATUS_SUCCESS - the data from the entire packet chain is + extracted and found at *pOutputBuffer. *pOutputBufferSize bytes + were extracted. + + VOS_STATUS_E_FAULT - pPacket, pOutputBuffer, or pOutputBufferSize + is not a valid pointer. + + VOS_STATUS_E_NOMEM - there is not enough room to extract the data + from the entire packet chain. *pOutputBufferSize has been updated + with the size needed to extract the entier packet chain. + + \sa vos_pkt_extract_data() + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_extract_data_chain( vos_pkt_t *pPacket, + v_VOID_t *pOutputBuffer, + v_SIZE_t *pOutputBufferSize ) +{ + VOS_STATUS vosStatus; + v_SIZE_t len; + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || + (NULL == pOutputBuffer) || + (NULL == pOutputBufferSize))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get the length of the entire packet chain. + vosStatus = vos_pkt_get_packet_chain_length(pPacket, &len); + if (unlikely(VOS_STATUS_SUCCESS != vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Unable to get packet chain length", __LINE__); + return VOS_STATUS_E_FAILURE; + } + + // if the output buffer size is too small, return NOMEM and update + // the actual size needed in *pOutputBufferSize + if (len > *pOutputBufferSize) + { + *pOutputBufferSize = len; + return VOS_STATUS_E_NOMEM; + } + + // walk through each packet in the chain, copying the data + while (pPacket) + { + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + vos_mem_copy(pOutputBuffer, skb->data, skb->len); + pOutputBuffer += skb->len; + + pPacket = pPacket->pNext; + } + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_peek_data() - peek into voss Packet at given offset + + This API provides a pointer to a specified offset into a voss Packet, + allowing the caller to peek at a given number of bytes in the voss Packet. + Upon successful return, the caller can access "numBytes" of data at + "pPacketData". + + This API will fail if the data length requested to peek at is not in + contiguous memory in the voss Packet. In this case, the caller should + use vos_pkt_extract_data() to have the data copied into a caller supplied + buffer. + + \param pPacket - the vOSS Packet to peek into + + \param pktOffset - the offset into the voss Packet data to peek into. + + \param ppPacketData - pointer to the location where the pointer to the + packet data at pktOffset will be returned. + + \param numBytes - the number of bytes the caller wishes to peek at. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_peek_data( vos_pkt_t *pPacket, + v_SIZE_t pktOffset, + v_VOID_t **ppPacketData, + v_SIZE_t numBytes ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || + (NULL == ppPacketData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate numBytes + if (unlikely(0 == numBytes)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid numBytes", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // check for overflow + if (unlikely((pktOffset + numBytes) > skb->len)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "VPKT [%d]: Packet overflow, offset %d size %d len %d", + __LINE__, pktOffset, numBytes, skb->len); + return VOS_STATUS_E_INVAL; + } + + // return pointer to the requested data + *ppPacketData = &skb->data[pktOffset]; + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_type() - Get packet type for a voss Packet + + This API returns the packet Type for a voss Packet. + + \param pPacket - the voss Packet to get the packet type from. + + \param pPacketType - location to return the packet type for the voss Packet + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_type( vos_pkt_t *pPacket, + VOS_PKT_TYPE *pPacketType ) +{ + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || + (NULL == pPacketType))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // return the requested information + *pPacketType = pPacket->packetType; + return VOS_STATUS_SUCCESS; +} + + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_length() - Get packet length for a voss Packet + + This API returns the total length of the data in a voss Packet. + + \param pPacket - the voss Packet to get the packet length from. + + \param pPacketSize - location to return the total size of the data contained + in the voss Packet. + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_length( vos_pkt_t *pPacket, + v_U16_t *pPacketSize ) +{ + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || + (NULL == pPacketSize))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate the skb + if (unlikely(NULL == pPacket->pSkb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // return the requested information + *pPacketSize = pPacket->pSkb->len; + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_packet_chain_length() - Get length of a vos packet chain + + This API returns the total length of the data in a voss Packet chain. + + \param pPacket - the voss Packet at the start of the packet chain. This API + will calculate the length of data in the packet chain stating with + this packet. + + \param pPacketSize - location to return the total size of the data contained + in the voss Packet. + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_packet_chain_length( vos_pkt_t *pPacketChain, + v_SIZE_t *pPacketChainSize ) +{ + v_SIZE_t chainSize = 0; + + // Validate the parameter pointers + if (unlikely((NULL == pPacketChain) || + (NULL == pPacketChainSize))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // walk through each packet in the chain, adding its length + while (pPacketChain) + { + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacketChain->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate the skb + if (unlikely(NULL == pPacketChain->pSkb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + chainSize += pPacketChain->pSkb->len; + pPacketChain = pPacketChain->pNext; + } + + // return result + *pPacketChainSize = chainSize; + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_push_head() - push data on the front a of a voss Packet + + This API will push data onto the front of a voss Packet. The data will be + appended in front of any data already contained in the voss Packet. + + \param pPacket - the voss Packet to modify. + + \param pData - pointer to the data to push onto the head of the voss Packet. + + \param dataSize - the size of the data to put onto the head of the voss + Packet. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_push_head( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == pData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is headroom. As a performance optimization we + // can omit this check later since skb_push() will also perform the + // check (except skb_push() will panic the kernel) + if (unlikely(skb_headroom(skb) < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Insufficient headroom, " + "head[%p], data[%p], req[%d]", + __LINE__, skb->head, skb->data, dataSize); + return VOS_STATUS_E_INVAL; + } + + // actually push the data + vos_mem_copy(skb_push(skb, dataSize), pData, dataSize); + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_reserve_head() - Reserve space at the front of a voss Packet + + This API will reserve space at the front of a voss Packet. The caller can + then copy data into this reserved space using memcpy() like functions. This + allows the caller to reserve space and build headers directly in this + reserved space in the voss Packet. + + Upon successful return, the length of the voss Packet is increased by + dataSize. + + < put a before / after picture here> + + \param pPacket - the voss Packet to modify. + + \param ppData - pointer to the location where the pointer to the reserved + space is returned. Upon successful return, the caller has + write / read access to the data space at *ppData for length + dataSize to build headers, etc. + + \param dataSize - the size of the data to reserve at the head of the voss + Packet. Upon successful return, the length of the voss + Packet is increased by dataSize. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_reserve_head( vos_pkt_t *pPacket, + v_VOID_t **ppData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + struct sk_buff *newskb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == ppData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is headroom. As a performance optimization we + // can omit this check later since skb_push() will also perform the + // check (except skb_push() will panic the kernel) + if (unlikely(skb_headroom(skb) < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Insufficient headroom, " + "head[%p], data[%p], req[%d]", + __LINE__, skb->head, skb->data, dataSize); + + if ((newskb = skb_realloc_headroom(skb, dataSize)) == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Failed to realloc headroom", __LINE__); + return VOS_STATUS_E_INVAL; + } + + kfree_skb(skb); + skb = newskb; + + // set the skb pointer + pPacket->pSkb = newskb; + } + + // actually allocate the headroom + *ppData = skb_push(skb, dataSize); + // Zero out so we dont take the fastpath on Android. + memset( (void *)*ppData, 0, dataSize ); + + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_reserve_head_fast() - Reserve space at the front of a voss Packet + + This API will reserve space at the front of a voss Packet. The caller can + then copy data into this reserved space using memcpy() like functions. This + allows the caller to reserve space and build headers directly in this + reserved space in the voss Packet. + + Upon successful return, the length of the voss Packet is increased by + dataSize. + + Same as above APi but no memset to 0 at the end. + + < put a before / after picture here> + + \param pPacket - the voss Packet to modify. + + \param ppData - pointer to the location where the pointer to the reserved + space is returned. Upon successful return, the caller has + write / read access to the data space at *ppData for length + dataSize to build headers, etc. + + \param dataSize - the size of the data to reserve at the head of the voss + Packet. Upon successful return, the length of the voss + Packet is increased by dataSize. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_reserve_head_fast( vos_pkt_t *pPacket, + v_VOID_t **ppData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + struct sk_buff *newskb; + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is headroom. As a performance optimization we + // can omit this check later since skb_push() will also perform the + // check (except skb_push() will panic the kernel) + if (unlikely(skb_headroom(skb) < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: Insufficient headroom, " + "head[%p], data[%p], req[%d]", + __LINE__, skb->head, skb->data, dataSize); + + if ((newskb = skb_realloc_headroom(skb, dataSize)) == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Failed to realloc headroom", __LINE__); + return VOS_STATUS_E_INVAL; + } + + kfree_skb(skb); + skb = newskb; + + // set the skb pointer + pPacket->pSkb = newskb; + } + + // actually allocate the headroom + *ppData = skb_push(skb, dataSize); + // Zero out so we dont take the fastpath on Android. + //memset( (void *)*ppData, 0, dataSize ); + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_pop_head() - Remove data from the front of the voss Packet + + This API removes data from the front of a voss Packet. The data is + copied into the output buffer described by pData and pDataSize + + \param pPacket - the voss Packet to operate on. + + \param pData - pointer to the data buffer where the data removed from the + voss Packet is placed. + + \param dataSize - The amount of space to remove from the head of the voss + Packet. The output buffer (at *pData) must contain at + least this amount of space. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_pop_head( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == pData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is enough data to pop + if (unlikely(skb->len < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]", + __LINE__, skb->len, dataSize); + return VOS_STATUS_E_INVAL; + } + + // copy the data + vos_mem_copy(pData, skb->data, dataSize); + skb_pull(skb, dataSize); + + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_trim_head() - Skip over bytes at the front of a voss Packet + + This API moves the pointers at the head of a voss Packet to essentially + skip over data at the front of a voss Packet. Upon successful return, the + length of the voss Packet is reduced by dataSize and the starting pointer + to the voss Packet is adjusted to eliminate the data from the start of the + voss Packet. + + This API has the opposite effect of \a vos_pkt_reserve_head(). + + \param pPacket - the voss Packet to operate on. + + \param dataSize - The amount of space to skip at the start of the voss + Packet. + + Note that upon return, the data skipped over is + inaccessible to the caller. If the caller needs access + to the head data, use vos_pkt_pop_head() or + vos_pkt_extract_data() to get a copy of the data. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_trim_head( vos_pkt_t *pPacket, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is enough data to trim + if (unlikely(skb->len < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: trim exceeds packet size, len[%d], req[%d]", + __LINE__, skb->len, dataSize); + return VOS_STATUS_E_INVAL; + } + + // adjust the skb + skb_pull(skb, dataSize); + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_push_tail() - push data on the end a of a voss Packet + + This API will push data onto the end of a voss Packet. The data will be + appended to the end of any data already contained in the voss Packet. + + \param pPacket - the voss Packet to modify. + + \param pData - pointer to the data to push onto the tail of the voss Packet. + + \param dataSize - the size of the data to put onto the tail of the voss Packet. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_push_tail( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == pData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is tailroom. As a performance optimization we + // can omit this check later since skb_put() will also perform the + // check (except skb_put() will panic the kernel) + if (unlikely(skb_tailroom(skb) < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Insufficient tailroom, " + "tail[%p], end[%p], req[%d]", + __LINE__, skb_tail_pointer(skb), + skb_end_pointer(skb), dataSize); + return VOS_STATUS_E_INVAL; + } + + // actually push the data + vos_mem_copy(skb_put(skb, dataSize), pData, dataSize); + + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_reserve_tail() - Reserve space at the end of a voss Packet + + This API will reserve space at the end of a voss Packet. The caller can + then copy data into this reserved space using memcpy() like functions. This + allows the caller to reserve space and build headers directly in this + reserved space in the voss Packet. + + Upon successful return, the length of the voss Packet is increased by + dataSize. + + \param pPacket - the voss Packet to modify. + + \param ppData - pointer to the location where the pointer to the reserved + space is returned. Upon successful return, the caller has + write / read access to the data space at *ppData for length + dataSize to build headers, etc. + + \param dataSize - the size of the data to reserve at the head of the voss + Packet. Upon successful return, the length of the voss + Packet is increased by dataSize. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_reserve_tail( vos_pkt_t *pPacket, + v_VOID_t **ppData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == ppData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is tailroom. As a performance optimization we + // can omit this check later since skb_put() will also perform the + // check (except skb_put() will panic the kernel) + if (unlikely(skb_tailroom(skb) < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Insufficient tailroom, " + "tail[%p], end[%p], req[%d]", + __LINE__, skb_tail_pointer(skb), + skb_end_pointer(skb), dataSize); + return VOS_STATUS_E_INVAL; + } + + // actually allocate the space + *ppData = skb_put(skb, dataSize); + + return VOS_STATUS_SUCCESS; +} + + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_pop_tail() - Remove data from the end of the voss Packet + + This API removes data from the end of a voss Packet. The data is + copied into the output buffer described by pData and pDataSize + + \param pPacket - the voss Packet to operate on. + + \param pData - pointer to the data buffer where the data removed from the + voss Packet is placed. + + \param dataSize - The amount of space to remove from the end of the voss + Packet. The output buffer (at *pData) must contain at + least this amount of space. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_pop_tail( vos_pkt_t *pPacket, + v_VOID_t *pData, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || (NULL == pData))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is enough data to pop + if (unlikely(skb->len < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]", + __LINE__, skb->len, dataSize); + return VOS_STATUS_E_INVAL; + } + + // adjust pointers (there isn't a native Linux API for this) + skb->tail -= dataSize; + skb->len -= dataSize; + + // actually push the data + vos_mem_copy(pData, skb_tail_pointer(skb), dataSize); + + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_trim_tail() - Skip over bytes at the end of a voss Packet + + This API moves the pointers at the head of a voss Packet to essentially + skip over data at the end of a voss Packet. Upon successful return, the + length of the voss Packet is reduced by dataSize and voss Packet is + adjusted to eliminate the data from the end of the voss Packet. + + This API has the opposite effect of \a vos_pkt_reserve_tail(). + + \param pPacket - the voss Packet to operate on. + + \param dataSize - The amount of space to remove at the end of the voss + Packet. + + Note that upon return, the data skipped over is + inaccessible to the caller. If the caller needs access + to the tail data, use vos_pkt_pop_tail() or + vos_pkt_extract_data() to get a copy of the data. + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_trim_tail( vos_pkt_t *pPacket, + v_SIZE_t dataSize ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Make sure there is enough data to pop + if (unlikely(skb->len < dataSize)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN, + "VPKT [%d]: pop exceeds packet size, len[%d], req[%d]", + __LINE__, skb->len, dataSize); + return VOS_STATUS_E_INVAL; + } + + // adjust pointers (there isn't a native Linux API for this) + skb->tail -= dataSize; + skb->len -= dataSize; + + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_timestamp() - Retrive the timestamp attribute from the + specified VOSS packet + + \param pPacket - the voss Packet to operate on. + + \param pTstamp - the timestamp will be returned here. + + \return VOS_STATUS_E_FAULT - invalid parameter(s) specified + + VOS_STATUS_SUCCESS - timestamp retrived successfully + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_timestamp( vos_pkt_t *pPacket, + v_TIME_t* pTstamp ) +{ + // Validate the parameter pointers + if (unlikely((NULL == pPacket) || + (NULL == pTstamp))) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // return the requested information + *pTstamp = pPacket->timestamp; + return VOS_STATUS_SUCCESS; +} + + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_flatten_rx_pkt() - Transform a platform based RX VOSS + packet into a flat buffer based VOSS packet if needed. This is needed in + cases where for reasons of efficiency we want the RX packets to be very + platform specific (for e.g. DSM based on AMSS, etc). However platform + independent code may rely on making calls on the VOSS packet which can only + be supported by the flat buffer based implementation of a RX packet. This API + will allocate a new VOSS packet with flat buffer, extract the data from the + input VOSS packet and then release the input VOSS packet. The new VOSS packet + will be returned from this call. + + \param ppPacket - the voss Packet to operate on. On input contains + the platform based packet. On output contains the flat + buffer based packet. Any applicable resources + are freed as part of this call. + + \return VOS_STATUS_E_FAULT - invalid parameter specified + + VOS_STATUS_E_INVAL - packet type not RX_RAW + + VOS_STATUS_SUCCESS - transform successful + + other VOSS status - other errors encountered + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_flatten_rx_pkt( vos_pkt_t **ppPacket ) +{ + // Linux/Android skbs are already flat, no work required + return VOS_STATUS_SUCCESS; +} + +/**-------------------------------------------------------------------------- + + \brief vos_pkt_set_rx_length() - Set the length of a received packet + + This API set the length of the data inside the packet after a DMA has occurred + on rx, it will also set the tail pointer to the end of the data. + + \param pPacket - the voss Packet to operate on. + + \param pktLen - The size of the data placed in the Rx packet during DMA. + + + \return + + \sa + + ---------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_set_rx_length( vos_pkt_t *pPacket, + v_SIZE_t pktLen ) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // Validate that this is really an initialized vos packet + if (unlikely(VPKT_MAGIC_NUMBER != pPacket->magic)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: Invalid magic", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // get pointer to the skb + skb = pPacket->pSkb; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL skb", __LINE__); + return VOS_STATUS_E_INVAL; + } + + // adjust pointers (there isn't a native Linux API for this) + // ?? - is this sufficient? + skb_set_tail_pointer(skb, pktLen); + skb->len = pktLen; + + return VOS_STATUS_SUCCESS; + +} +/**-------------------------------------------------------------------------- + + \brief vos_pkt_get_available_buffer_pool() - Get avaliable VOS packet size + VOSS Packet pool is limitted resource + VOSS Client need to know how many packet pool is still avaliable to control + the flow + + \param pktType - Packet type want to know free buffer count + VOS_PKT_TYPE_TX_802_11_MGMT, management free buffer count, + VOS_PKT_TYPE_TX_802_11_DATA + VOS_PKT_TYPE_TX_802_3_DATA, TX free buffer count + VOS_PKT_TYPE_RX_RAW, RX free buffer count + + vosFreeBuffer - free frame buffer size + + \return VOS_STATUS_E_INVAL - invalid input parameter + + VOS_STATUS_SUCCESS - Get size success + + \sa + + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_pkt_get_available_buffer_pool (VOS_PKT_TYPE pktType, + v_SIZE_t *vosFreeBuffer) +{ + struct list_head *pList; + struct list_head *pNode; + v_SIZE_t count; + struct mutex *mlock; + + if (NULL == vosFreeBuffer) + { + return VOS_STATUS_E_INVAL; + } + + switch (pktType) + { + case VOS_PKT_TYPE_TX_802_11_MGMT: + pList = &gpVosPacketContext->txMgmtFreeList; + mlock = &gpVosPacketContext->txMgmtFreeListLock; + break; + + case VOS_PKT_TYPE_TX_802_11_DATA: + case VOS_PKT_TYPE_TX_802_3_DATA: + if (VOS_STA_SAP_MODE == hdd_get_conparam()) + { + *vosFreeBuffer = gpVosPacketContext->uctxDataFreeListCount; + return VOS_STATUS_SUCCESS; + } + else + { + pList = &gpVosPacketContext->txDataFreeList; + mlock = &gpVosPacketContext->txDataFreeListLock; + } + break; + + case VOS_PKT_TYPE_RX_RAW: + // if the caller is curious how many raw packets are available + // then he probably wants as many packets to be available as + // possible so replenish the raw pool + vos_pkti_replenish_raw_pool(); + // Return the pre-calculated count 'rxRawFreeListCount' + *vosFreeBuffer = gpVosPacketContext->rxRawFreeListCount; + return VOS_STATUS_SUCCESS; + break; + + default: + return (VOS_STATUS_E_INVAL); + } + + count = 0; + mutex_lock(mlock); + list_for_each(pNode, pList) + { + count++; + } + mutex_unlock(mlock); + *vosFreeBuffer = count; + return VOS_STATUS_SUCCESS; +} + +/** + @brief vos_pkt_get_num_of_rx_raw_pkts() - Get the number of RX packets + that should be allocated. + + This function is called by VOS packet module to know how many RX raw + packets it should allocate/reserve. This value can be configured thru + Kernel device tree to save memory usage. + + @param + NONE + @return + v_SIZE_t the number of packets to allocate + +*/ +v_SIZE_t vos_pkt_get_num_of_rx_raw_pkts(void) +{ +#ifdef HAVE_WCNSS_RX_BUFF_COUNT + v_SIZE_t buffCount; + + buffCount = wcnss_get_wlan_rx_buff_count(); + return (buffCount > VPKT_NUM_RX_RAW_PACKETS ? + VPKT_NUM_RX_RAW_PACKETS : buffCount); +#else + return VPKT_NUM_RX_RAW_PACKETS; +#endif +} + +/** + @brief vos_pkt_get_num_of_rx_raw_pkts() - Get the number of times + skb allocation failed while replenishing packets + + + @param + NONE + @return + v_SIZE_t the number of times packet allocation failed + +*/ +v_SIZE_t vos_pkt_get_num_of_rx_pkt_alloc_failures(void) +{ + v_SIZE_t failCount; + + mutex_lock(&gpVosPacketContext->rxReplenishListLock); + mutex_lock(&gpVosPacketContext->rxRawFreeListLock); + + failCount = gpVosPacketContext->rxReplenishFailCount; + + mutex_unlock(&gpVosPacketContext->rxReplenishListLock); + mutex_unlock(&gpVosPacketContext->rxRawFreeListLock); + + return failCount; +} + +v_U8_t vos_pkt_get_proto_type +( + void *pskb, + v_U8_t tracking_map +) +{ + v_U8_t pkt_proto_type = 0; + v_U16_t ether_type; + v_U16_t SPort; + v_U16_t DPort; + struct sk_buff *skb = NULL; + + + if (NULL == pskb) + { + return pkt_proto_type; + } + else + { + skb = (struct sk_buff *)pskb; + } + + /* EAPOL Tracking enabled */ + if (VOS_PKT_PROTO_TYPE_EAPOL & tracking_map) + { + ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET)); + if (VOS_PKT_PROT_EAPOL_ETH_TYPE == VOS_SWAP_U16(ether_type)) + { + pkt_proto_type |= VOS_PKT_PROTO_TYPE_EAPOL; + } + } + + /* ARP Tracking Enabled */ + if (VOS_PKT_PROTO_TYPE_ARP & tracking_map) + { + ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET)); + if (VOS_PKT_PROT_ARP_ETH_TYPE == VOS_SWAP_U16(ether_type)) + { + pkt_proto_type |= VOS_PKT_PROTO_TYPE_ARP; + } + } + + /* DHCP Tracking enabled */ + if (VOS_PKT_PROTO_TYPE_DHCP & tracking_map) + { + SPort = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_IP_OFFSET + + VOS_PKT_PROT_IP_HEADER_SIZE)); + DPort = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_IP_OFFSET + + VOS_PKT_PROT_IP_HEADER_SIZE + sizeof(v_U16_t))); + if (((VOS_PKT_PROT_DHCP_SRV_PORT == VOS_SWAP_U16(SPort)) && + (VOS_PKT_PROT_DHCP_CLI_PORT == VOS_SWAP_U16(DPort))) || + ((VOS_PKT_PROT_DHCP_CLI_PORT == VOS_SWAP_U16(SPort)) && + (VOS_PKT_PROT_DHCP_SRV_PORT == VOS_SWAP_U16(DPort)))) + { + pkt_proto_type |= VOS_PKT_PROTO_TYPE_DHCP; + } + } + + /* Protocol type map */ + return pkt_proto_type; +} + +bool vos_is_arp_pkt(void *pskb, bool is_translated) +{ + v_U16_t ether_type; + struct sk_buff *skb = NULL; +#define HEADER_OFFSET_802_11 20 + + if (NULL == pskb) + { + return FALSE; + } + + skb = (struct sk_buff *)pskb; + + if (is_translated) + ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET + HEADER_OFFSET_802_11)); + else + ether_type = (v_U16_t)(*(v_U16_t *)(skb->data + VOS_PKT_PROT_ETH_TYPE_OFFSET)); + + if (VOS_PKT_PROT_ARP_ETH_TYPE == VOS_SWAP_U16(ether_type)) + { + return TRUE; + } + else + { + return FALSE; + } +#undef HEADER_OFFSET_802_11 +} + +v_PVOID_t vos_get_pkt_head(vos_pkt_t *pPacket) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return NULL; + } + + if ( VOS_STATUS_SUCCESS != + vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE )) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "OS-PKT [%d]: OS PKT pointer is NULL", __LINE__); + return NULL; + } + + return VOS_PKT_GET_HEAD(skb); +} + +v_PVOID_t vos_get_pkt_end(vos_pkt_t *pPacket) +{ + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return NULL; + } + + if ( VOS_STATUS_SUCCESS != + vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE )) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "OS-PKT [%d]: OS PKT pointer is NULL", __LINE__); + return NULL; + } + + /* find end point if skb->end is an offset */ +#ifdef NET_SKBUFF_DATA_USES_OFFSET + return VOS_PKT_GET_HEAD(skb) + VOS_PKT_GET_END(skb); +#else + return VOS_PKT_GET_END(skb); +#endif +} + +v_VOID_t vos_recover_tail(vos_pkt_t *pPacket) +{ + struct skb_shared_info *shinfo; + struct sk_buff *skb; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "VPKT [%d]: NULL pointer", __LINE__); + return; + } + + if ( VOS_STATUS_SUCCESS != + vos_pkt_get_os_packet(pPacket, (void**)&skb, VOS_FALSE )) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "OS-PKT [%d]: OS PKT pointer is NULL", __LINE__); + return; + } + + shinfo = skb_shinfo(skb); + memset(shinfo, 0, sizeof(struct skb_shared_info)); + atomic_set(&shinfo->dataref, 1); + kmemcheck_annotate_variable(shinfo->destructor_arg); + + return; +} + +#ifdef VOS_PACKET_UNIT_TEST +#include "vos_packet_test.c" +#endif diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_sched.c b/drivers/staging/prima/CORE/VOSS/src/vos_sched.c new file mode 100644 index 000000000000..19d6f0b41907 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_sched.c @@ -0,0 +1,2228 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + @file vos_sched.c + @brief VOS Scheduler Implementation + +===========================================================================*/ +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + when who what, where, why + -------- --- -------------------------------------------------------- +===========================================================================*/ +/*--------------------------------------------------------------------------- + * Include Files + * ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vos_sched.h" +#include +#include "wlan_qct_wda.h" +#include "wlan_qct_pal_msg.h" +#include +#include +#include + +/*--------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * ------------------------------------------------------------------------*/ +#define VOS_SCHED_THREAD_HEART_BEAT INFINITE +/* Milli seconds to delay SSR thread when an Entry point is Active */ +#define SSR_WAIT_SLEEP_TIME 100 +/* MAX iteration count to wait for Entry point to exit before + * we proceed with SSR in WD Thread + */ +#define MAX_SSR_WAIT_ITERATIONS 200 +/* Timer value for detecting thread stuck issues */ +#define THREAD_STUCK_TIMER_VAL 5000 // 5 seconds +#define THREAD_STUCK_COUNT 6 + +#define MC_Thread 0 +#define TX_Thread 1 +#define RX_Thread 2 + +static atomic_t ssr_protect_entry_count; + +/*--------------------------------------------------------------------------- + * Type Declarations + * ------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + * Data definitions + * ------------------------------------------------------------------------*/ +static pVosSchedContext gpVosSchedContext; +static pVosWatchdogContext gpVosWatchdogContext; + +/*--------------------------------------------------------------------------- + * Forward declaration + * ------------------------------------------------------------------------*/ +static int VosMCThread(void *Arg); +static int VosWDThread(void *Arg); +static int VosTXThread(void *Arg); +static int VosRXThread(void *Arg); +void vos_sched_flush_rx_mqs(pVosSchedContext SchedContext); +extern v_VOID_t vos_core_return_msg(v_PVOID_t pVContext, pVosMsgWrapper pMsgWrapper); +/*--------------------------------------------------------------------------- + * External Function implementation + * ------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + \brief vos_sched_open() - initialize the vOSS Scheduler + The \a vos_sched_open() function initializes the vOSS Scheduler + Upon successful initialization: + - All the message queues are initialized + - The Main Controller thread is created and ready to receive and + dispatch messages. + - The Tx thread is created and ready to receive and dispatch messages + + \param pVosContext - pointer to the global vOSS Context + \param pVosSchedContext - pointer to a previously allocated buffer big + enough to hold a scheduler context. + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the scheduler + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + \sa vos_sched_open() + -------------------------------------------------------------------------*/ +VOS_STATUS +vos_sched_open +( + v_PVOID_t pVosContext, + pVosSchedContext pSchedContext, + v_SIZE_t SchedCtxSize +) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; +/*-------------------------------------------------------------------------*/ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening the VOSS Scheduler",__func__); + // Sanity checks + if ((pVosContext == NULL) || (pSchedContext == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + return VOS_STATUS_E_FAILURE; + } + if (sizeof(VosSchedContext) != SchedCtxSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Incorrect VOS Sched Context size passed",__func__); + return VOS_STATUS_E_INVAL; + } + vos_mem_zero(pSchedContext, sizeof(VosSchedContext)); + pSchedContext->pVContext = pVosContext; + vStatus = vos_sched_init_mqs(pSchedContext); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to initialize VOS Scheduler MQs",__func__); + return vStatus; + } + // Initialize the helper events and event queues + init_completion(&pSchedContext->McStartEvent); + init_completion(&pSchedContext->TxStartEvent); + init_completion(&pSchedContext->RxStartEvent); + init_completion(&pSchedContext->McShutdown); + init_completion(&pSchedContext->TxShutdown); + init_completion(&pSchedContext->RxShutdown); + init_completion(&pSchedContext->ResumeMcEvent); + init_completion(&pSchedContext->ResumeTxEvent); + init_completion(&pSchedContext->ResumeRxEvent); + + spin_lock_init(&pSchedContext->McThreadLock); + spin_lock_init(&pSchedContext->TxThreadLock); + spin_lock_init(&pSchedContext->RxThreadLock); + + init_waitqueue_head(&pSchedContext->mcWaitQueue); + pSchedContext->mcEventFlag = 0; + init_waitqueue_head(&pSchedContext->txWaitQueue); + pSchedContext->txEventFlag= 0; + init_waitqueue_head(&pSchedContext->rxWaitQueue); + pSchedContext->rxEventFlag= 0; + /* + ** This initialization is critical as the threads will later access the + ** global contexts normally, + ** + ** I shall put some memory barrier here after the next piece of code but + ** I am keeping it simple for now. + */ + gpVosSchedContext = pSchedContext; + + //Create the VOSS Main Controller thread + pSchedContext->McThread = kthread_create(VosMCThread, pSchedContext, + "VosMCThread"); + if (IS_ERR(pSchedContext->McThread)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS Main Thread Controller",__func__); + goto MC_THREAD_START_FAILURE; + } + wake_up_process(pSchedContext->McThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Main Controller thread Created",__func__); + + pSchedContext->TxThread = kthread_create(VosTXThread, pSchedContext, + "VosTXThread"); + if (IS_ERR(pSchedContext->TxThread)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS TX Thread",__func__); + goto TX_THREAD_START_FAILURE; + } + wake_up_process(pSchedContext->TxThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + ("VOSS TX thread Created")); + + pSchedContext->RxThread = kthread_create(VosRXThread, pSchedContext, + "VosRXThread"); + if (IS_ERR(pSchedContext->RxThread)) + { + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create VOSS RX Thread",__func__); + goto RX_THREAD_START_FAILURE; + + } + wake_up_process(pSchedContext->RxThread); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + ("VOSS RX thread Created")); + + /* + ** Now make sure all threads have started before we exit. + ** Each thread should normally ACK back when it starts. + */ + wait_for_completion_interruptible(&pSchedContext->McStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS MC Thread has started",__func__); + wait_for_completion_interruptible(&pSchedContext->TxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Tx Thread has started",__func__); + wait_for_completion_interruptible(&pSchedContext->RxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Rx Thread has started",__func__); + + /* + ** We're good now: Let's get the ball rolling!!! + */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Scheduler successfully Opened",__func__); + return VOS_STATUS_SUCCESS; + + +RX_THREAD_START_FAILURE: + //Try and force the Tx thread controller to exit + set_bit(MC_SHUTDOWN_EVENT, &pSchedContext->txEventFlag); + set_bit(MC_POST_EVENT, &pSchedContext->txEventFlag); + wake_up_interruptible(&pSchedContext->txWaitQueue); + //Wait for TX to exit + wait_for_completion_interruptible(&pSchedContext->TxShutdown); + +TX_THREAD_START_FAILURE: + //Try and force the Main thread controller to exit + set_bit(MC_SHUTDOWN_EVENT, &pSchedContext->mcEventFlag); + set_bit(MC_POST_EVENT, &pSchedContext->mcEventFlag); + wake_up_interruptible(&pSchedContext->mcWaitQueue); + //Wait for MC to exit + wait_for_completion_interruptible(&pSchedContext->McShutdown); + +MC_THREAD_START_FAILURE: + //De-initialize all the message queues + vos_sched_deinit_mqs(pSchedContext); + return VOS_STATUS_E_RESOURCES; + +} /* vos_sched_open() */ + +VOS_STATUS vos_watchdog_open +( + v_PVOID_t pVosContext, + pVosWatchdogContext pWdContext, + v_SIZE_t wdCtxSize +) +{ +/*-------------------------------------------------------------------------*/ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Opening the VOSS Watchdog module",__func__); + //Sanity checks + if ((pVosContext == NULL) || (pWdContext == NULL)) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + return VOS_STATUS_E_FAILURE; + } + if (sizeof(VosWatchdogContext) != wdCtxSize) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Incorrect VOS Watchdog Context size passed",__func__); + return VOS_STATUS_E_INVAL; + } + vos_mem_zero(pWdContext, sizeof(VosWatchdogContext)); + pWdContext->pVContext = pVosContext; + + //Initialize the helper events and event queues + init_completion(&pWdContext->WdStartEvent); + init_completion(&pWdContext->WdShutdown); + init_waitqueue_head(&pWdContext->wdWaitQueue); + pWdContext->wdEventFlag = 0; + + // Initialize the lock + spin_lock_init(&pWdContext->wdLock); + spin_lock_init(&pWdContext->thread_stuck_lock); + + //Create the Watchdog thread + pWdContext->WdThread = kthread_create(VosWDThread, pWdContext,"VosWDThread"); + + if (IS_ERR(pWdContext->WdThread)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Could not Create Watchdog thread",__func__); + return VOS_STATUS_E_RESOURCES; + } + else + { + gpVosWatchdogContext = pWdContext; + wake_up_process(pWdContext->WdThread); + } + /* + ** Now make sure thread has started before we exit. + ** Each thread should normally ACK back when it starts. + */ + wait_for_completion_interruptible(&pWdContext->WdStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: VOSS Watchdog Thread has started",__func__); + return VOS_STATUS_SUCCESS; +} /* vos_watchdog_open() */ +/*--------------------------------------------------------------------------- + \brief VosMcThread() - The VOSS Main Controller thread + The \a VosMcThread() is the VOSS main controller thread: + \param Arg - pointer to the global vOSS Sched Context + \return Thread exit code + \sa VosMcThread() + -------------------------------------------------------------------------*/ +static int +VosMCThread +( + void * Arg +) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)Arg; + pVosMsgWrapper pMsgWrapper = NULL; + tpAniSirGlobal pMacContext = NULL; + tSirRetStatus macStatus = eSIR_SUCCESS; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Bad Args passed", __func__); + return 0; + } + set_user_nice(current, -2); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("MC_Thread"); +#endif + + /* + ** Ack back to the context from which the main controller thread has been + ** created. + */ + complete(&pSchedContext->McStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MC Thread %d (%s) starting up",__func__, current->pid, current->comm); + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + + while(!shutdown) + { + // This implements the execution model algorithm + retWaitStatus = wait_event_interruptible(pSchedContext->mcWaitQueue, + test_bit(MC_POST_EVENT, &pSchedContext->mcEventFlag) || + test_bit(MC_SUSPEND_EVENT, &pSchedContext->mcEventFlag)); + + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(MC_POST_EVENT, &pSchedContext->mcEventFlag); + + while(1) + { + // Check if MC needs to shutdown + if(test_bit(MC_SHUTDOWN_EVENT, &pSchedContext->mcEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MC thread signaled to shutdown", __func__); + shutdown = VOS_TRUE; + /* Check for any Suspend Indication */ + if (test_and_clear_bit(MC_SUSPEND_EVENT, + &pSchedContext->mcEventFlag)) + { + /* Unblock anyone waiting on suspend */ + complete(&pHddCtx->mc_sus_event_var); + } + break; + } + /* + ** Check the WDI queue + ** Service it till the entire queue is empty + */ + if (!vos_is_mq_empty(&pSchedContext->wdiMcMq)) + { + wpt_msg *pWdiMsg; + /* + ** Service the WDI message queue + */ + pMsgWrapper = vos_mq_get(&pSchedContext->wdiMcMq); + + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_BUG(0); + break; + } + + pWdiMsg = (wpt_msg *)pMsgWrapper->pVosMsg->bodyptr; + + if(pWdiMsg == NULL || pWdiMsg->callback == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDI Msg or Callback is NULL", __func__); + VOS_BUG(0); + break; + } + + pWdiMsg->callback(pWdiMsg); + + /* + ** return message to the Core + */ + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + + continue; + } + + // Check the SYS queue first + if (!vos_is_mq_empty(&pSchedContext->sysMcMq)) + { + // Service the SYS message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SYS MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->sysMcMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = sysMcProcessMsg(pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing SYS message",__func__); + } + //return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check the WDA queue + if (!vos_is_mq_empty(&pSchedContext->wdaMcMq)) + { + // Service the WDA message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS WDA MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->wdaMcMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WDA_McProcessMsg( pSchedContext->pVContext, pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing WDA message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check the PE queue + if (!vos_is_mq_empty(&pSchedContext->peMcMq)) + { + // Service the PE message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS PE MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->peMcMq); + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + + /* Need some optimization*/ + pMacContext = vos_get_context(VOS_MODULE_ID_PE, pSchedContext->pVContext); + if (NULL == pMacContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "MAC Context not ready yet"); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + macStatus = peProcessMessages( pMacContext, (tSirMsgQ*)pMsgWrapper->pVosMsg); + if (eSIR_SUCCESS != macStatus) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing PE message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + /** Check the SME queue **/ + if (!vos_is_mq_empty(&pSchedContext->smeMcMq)) + { + /* Service the SME message queue */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SME MC Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->smeMcMq); + if (NULL == pMsgWrapper) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + + /* Need some optimization*/ + pMacContext = vos_get_context(VOS_MODULE_ID_SME, pSchedContext->pVContext); + if (NULL == pMacContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "MAC Context not ready yet"); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + vStatus = sme_ProcessMsg( (tHalHandle)pMacContext, pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing SME message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + /** Check the TL queue **/ + if (!vos_is_mq_empty(&pSchedContext->tlMcMq)) + { + // Service the TL message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + ("Servicing the VOS TL MC Message queue")); + pMsgWrapper = vos_mq_get(&pSchedContext->tlMcMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WLANTL_McProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TL message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + /* Check for any Suspend Indication */ + if (test_and_clear_bit(MC_SUSPEND_EVENT, + &pSchedContext->mcEventFlag)) + { + spin_lock(&pSchedContext->McThreadLock); + INIT_COMPLETION(pSchedContext->ResumeMcEvent); + /* Mc Thread Suspended */ + complete(&pHddCtx->mc_sus_event_var); + spin_unlock(&pSchedContext->McThreadLock); + + /* Wait foe Resume Indication */ + wait_for_completion_interruptible(&pSchedContext->ResumeMcEvent); + } + break; //All queues are empty now + } // while message loop processing + } // while TRUE + // If we get here the MC thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: MC Thread exiting!!!!", __func__); + complete_and_exit(&pSchedContext->McShutdown, 0); +} /* VosMCThread() */ + +v_BOOL_t isSsrPanicOnFailure(void) +{ + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return FALSE; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if((NULL == pHddCtx) || (NULL == pHddCtx->cfg_ini)) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null", __func__); + return FALSE; + } + + return (pHddCtx->cfg_ini->fIsSsrPanicOnFailure); +} +/** + * vos_wd_detect_thread_stuck()- Detect thread stuck + * by probing the MC, TX, RX threads and take action if + * Thread doesnt respond. + * + * This function is called to detect thread stuck + * and probe threads. + * + * Return: void + */ +static void vos_wd_detect_thread_stuck(void) +{ + unsigned long flags; + + spin_lock_irqsave(&gpVosWatchdogContext->thread_stuck_lock, flags); + + if ((gpVosWatchdogContext->mcThreadStuckCount == THREAD_STUCK_COUNT) || + (gpVosWatchdogContext->txThreadStuckCount == THREAD_STUCK_COUNT) || + (gpVosWatchdogContext->rxThreadStuckCount == THREAD_STUCK_COUNT)) + { + spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock, flags); + hddLog(LOGE, FL("Thread Stuck count reached threshold!!!" + "MC Count %d RX count %d TX count %d"), + gpVosWatchdogContext->mcThreadStuckCount, + gpVosWatchdogContext->rxThreadStuckCount, + gpVosWatchdogContext->txThreadStuckCount); + return; + } + + if (gpVosWatchdogContext->mcThreadStuckCount || + gpVosWatchdogContext->txThreadStuckCount || + gpVosWatchdogContext->rxThreadStuckCount) + { + spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock, flags); + + hddLog(LOG1, FL("MC Count %d RX count %d TX count %d"), + gpVosWatchdogContext->mcThreadStuckCount, + gpVosWatchdogContext->rxThreadStuckCount, + gpVosWatchdogContext->txThreadStuckCount); + + if (gpVosWatchdogContext->mcThreadStuckCount) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Invoking dump stack for MC thread",__func__); + vos_dump_stack(MC_Thread); + } + if (gpVosWatchdogContext->txThreadStuckCount) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Invoking dump stack for TX thread",__func__); + vos_dump_stack(TX_Thread); + } + if (gpVosWatchdogContext->rxThreadStuckCount) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Invoking dump stack for RX thread",__func__); + vos_dump_stack(RX_Thread); + } + + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_ONLY, + WLAN_LOG_REASON_THREAD_STUCK, + FALSE, TRUE); + + spin_lock_irqsave(&gpVosWatchdogContext->thread_stuck_lock, flags); + } + + /* Increment the thread stuck count for all threads */ + gpVosWatchdogContext->mcThreadStuckCount++; + gpVosWatchdogContext->txThreadStuckCount++; + gpVosWatchdogContext->rxThreadStuckCount++; + + spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock, flags); + vos_probe_threads(); + + /* Restart the timer */ + if (VOS_STATUS_SUCCESS != + vos_timer_start(&gpVosWatchdogContext->threadStuckTimer, + THREAD_STUCK_TIMER_VAL)) + hddLog(LOGE, FL("Unable to start thread stuck timer")); +} + +/** + * wlan_wd_detect_thread_stuck_cb()- Call back of the + * thread stuck timer. + * @priv: timer data. + * This function is called when the thread stuck timer + * expire to detect thread stuck and probe threads. + * + * Return: void + */ +static void vos_wd_detect_thread_stuck_cb(void *priv) +{ + if (!(vos_is_logp_in_progress(VOS_MODULE_ID_SYS, NULL) || + vos_is_load_unload_in_progress(VOS_MODULE_ID_SYS, NULL))) + { + set_bit(WD_WLAN_DETECT_THREAD_STUCK, + &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + } +} + +/** + * vos_thread_stuck_timer_init - Initialize thread stuck timer + * + * @pWdContext: watchdog context. + * + * Return: void + */ +void vos_thread_stuck_timer_init(pVosWatchdogContext pWdContext) +{ + if (vos_timer_init_deferrable(&pWdContext->threadStuckTimer, + VOS_TIMER_TYPE_SW, + vos_wd_detect_thread_stuck_cb, NULL)) + hddLog(LOGE, FL("Unable to initialize thread stuck timer")); + else + { + if (VOS_STATUS_SUCCESS != + vos_timer_start(&pWdContext->threadStuckTimer, + THREAD_STUCK_TIMER_VAL)) + hddLog(LOGE, FL("Unable to start thread stuck timer")); + else + hddLog(LOG1, FL("Successfully started thread stuck timer")); + } + +} + +/** + * wlan_logging_reset_thread_stuck_count()- Callback to + * probe msg sent to Threads. + * + * @threadId: passed threadid + * + * This function is called to by the thread after + * processing the probe msg, with their own thread id. + * + * Return: void. + */ +void vos_wd_reset_thread_stuck_count(int threadId) +{ + unsigned long flags; + + spin_lock_irqsave(&gpVosWatchdogContext->thread_stuck_lock, flags); + if (vos_sched_is_mc_thread(threadId)) + gpVosWatchdogContext->mcThreadStuckCount = 0; + else if (vos_sched_is_tx_thread(threadId)) + gpVosWatchdogContext->txThreadStuckCount = 0; + else if (vos_sched_is_rx_thread(threadId)) + gpVosWatchdogContext->rxThreadStuckCount = 0; + spin_unlock_irqrestore(&gpVosWatchdogContext->thread_stuck_lock, flags); +} + +/*--------------------------------------------------------------------------- + \brief VosWdThread() - The VOSS Watchdog thread + The \a VosWdThread() is the Watchdog thread: + \param Arg - pointer to the global vOSS Sched Context + \return Thread exit code + \sa VosMcThread() + -------------------------------------------------------------------------*/ +static int +VosWDThread +( + void * Arg +) +{ + pVosWatchdogContext pWdContext = (pVosWatchdogContext)Arg; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + int count = 0; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + set_user_nice(current, -3); + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Bad Args passed", __func__); + return 0; + } + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!pVosContext) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + + if(!pHddCtx) + { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("WD_Thread"); +#endif + + /* + ** Ack back to the context from which the Watchdog thread has been + ** created. + */ + complete(&pWdContext->WdStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Watchdog Thread %d (%s) starting up",__func__, current->pid, current->comm); + + while(!shutdown) + { + // This implements the Watchdog execution model algorithm + retWaitStatus = wait_event_interruptible(pWdContext->wdWaitQueue, + test_bit(WD_POST_EVENT, &pWdContext->wdEventFlag)); + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(WD_POST_EVENT, &pWdContext->wdEventFlag); + while(1) + { + + /* Post Msg to detect thread stuck. */ + if (test_and_clear_bit(WD_WLAN_DETECT_THREAD_STUCK, + &pWdContext->wdEventFlag)) + { + vos_wd_detect_thread_stuck(); + /* + * Process here and return without processing any SSR + * related logic. + */ + break; + } + /* Check for any Active Entry Points + * If active, delay SSR until no entry point is active or + * delay until count is decremented to ZERO + */ + count = MAX_SSR_WAIT_ITERATIONS; + while (count) + { + if (!atomic_read(&ssr_protect_entry_count)) + { + /* no external threads are executing */ + break; + } + /* at least one external thread is executing */ + if (--count) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Waiting for active entry points to exit", __func__); + msleep(SSR_WAIT_SLEEP_TIME); + } + } + /* at least one external thread is executing */ + if (!count) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Continuing SSR when %d Entry points are still active", + __func__, atomic_read(&ssr_protect_entry_count)); + } + // Check if Watchdog needs to shutdown + if(test_bit(WD_SHUTDOWN_EVENT, &pWdContext->wdEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Watchdog thread signaled to shutdown", __func__); + clear_bit(WD_SHUTDOWN_EVENT, &pWdContext->wdEventFlag); + shutdown = VOS_TRUE; + break; + } + /* subsystem restart: shutdown event handler */ + else if(test_bit(WD_WLAN_SHUTDOWN_EVENT, &pWdContext->wdEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog thread signaled to perform WLAN shutdown",__func__); + clear_bit(WD_WLAN_SHUTDOWN_EVENT, &pWdContext->wdEventFlag); + + //Perform WLAN shutdown + if(!pWdContext->resetInProgress) + { + pWdContext->resetInProgress = true; + vosStatus = hdd_wlan_shutdown(); + + if (! VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to shutdown WLAN",__func__); + VOS_ASSERT(0); + goto err_reset; + } + } + } + /* subsystem restart: re-init event handler */ + else if(test_bit(WD_WLAN_REINIT_EVENT, &pWdContext->wdEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog thread signaled to perform WLAN re-init",__func__); + clear_bit(WD_WLAN_REINIT_EVENT, &pWdContext->wdEventFlag); + + //Perform WLAN re-init + if(!pWdContext->resetInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Do WLAN re-init only when it is shutdown !!",__func__); + break; + } + vosStatus = hdd_wlan_re_init(); + + if (! VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Failed to re-init WLAN",__func__); + VOS_ASSERT(0); + pWdContext->isFatalError = true; + } + else + { + pWdContext->isFatalError = false; + pHddCtx->isLogpInProgress = FALSE; + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); + } + atomic_set(&pHddCtx->isRestartInProgress, 0); + pWdContext->resetInProgress = false; + complete(&pHddCtx->ssr_comp_var); + } + else + { + //Unnecessary wakeup - Should never happen!! + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog thread woke up unnecessarily",__func__); + } + break; + } // while message loop processing + } // while shutdown + + vos_timer_destroy(&pWdContext->threadStuckTimer); + // If we get here the Watchdog thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Watchdog Thread exiting !!!!", __func__); + complete_and_exit(&pWdContext->WdShutdown, 0); + +err_reset: + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog Thread Failed to Reset, Exiting!!!!", __func__); + return 0; + +} /* VosMCThread() */ + +/*--------------------------------------------------------------------------- + \brief VosTXThread() - The VOSS Main Tx thread + The \a VosTxThread() is the VOSS main controller thread: + \param Arg - pointer to the global vOSS Sched Context + + \return Thread exit code + \sa VosTxThread() + -------------------------------------------------------------------------*/ +static int VosTXThread ( void * Arg ) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)Arg; + pVosMsgWrapper pMsgWrapper = NULL; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + + set_user_nice(current, -1); + +#ifdef WLAN_FEATURE_11AC_HIGH_TP + set_wake_up_idle(true); +#endif + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Bad Args passed", __func__); + return 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("TX_Thread"); +#endif + + /* + ** Ack back to the context from which the main controller thread has been + ** created. + */ + complete(&pSchedContext->TxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: TX Thread %d (%s) starting up!",__func__, current->pid, current->comm); + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + + + while(!shutdown) + { + // This implements the execution model algorithm + retWaitStatus = wait_event_interruptible(pSchedContext->txWaitQueue, + test_bit(TX_POST_EVENT, &pSchedContext->txEventFlag) || + test_bit(TX_SUSPEND_EVENT, &pSchedContext->txEventFlag)); + + + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(TX_POST_EVENT, &pSchedContext->txEventFlag); + + while(1) + { + if(test_bit(TX_SHUTDOWN_EVENT, &pSchedContext->txEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: TX thread signaled to shutdown", __func__); + shutdown = VOS_TRUE; + /* Check for any Suspend Indication */ + if (test_and_clear_bit(TX_SUSPEND_EVENT, + &pSchedContext->txEventFlag)) + { + /* Unblock anyone waiting on suspend */ + complete(&pHddCtx->tx_sus_event_var); + } + break; + } + // Check the SYS queue first + if (!vos_is_mq_empty(&pSchedContext->sysTxMq)) + { + // Service the SYS message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SYS TX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->sysTxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = sysTxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TX SYS message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check now the TL queue + if (!vos_is_mq_empty(&pSchedContext->tlTxMq)) + { + // Service the TL message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS TL TX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->tlTxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WLANTL_TxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TX TL message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + // Check the WDI queue + if (!vos_is_mq_empty(&pSchedContext->wdiTxMq)) + { + wpt_msg *pWdiMsg; + pMsgWrapper = vos_mq_get(&pSchedContext->wdiTxMq); + + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_BUG(0); + break; + } + + pWdiMsg = (wpt_msg *)pMsgWrapper->pVosMsg->bodyptr; + + if(pWdiMsg == NULL || pWdiMsg->callback == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDI Msg or Callback is NULL", __func__); + VOS_BUG(0); + break; + } + + pWdiMsg->callback(pWdiMsg); + + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + + continue; + } + /* Check for any Suspend Indication */ + if (test_and_clear_bit(TX_SUSPEND_EVENT, + &pSchedContext->txEventFlag)) + { + spin_lock(&pSchedContext->TxThreadLock); + INIT_COMPLETION(pSchedContext->ResumeTxEvent); + /* Tx Thread Suspended */ + complete(&pHddCtx->tx_sus_event_var); + spin_unlock(&pSchedContext->TxThreadLock); + /* Wait foe Resume Indication */ + wait_for_completion_interruptible(&pSchedContext->ResumeTxEvent); + } + + break; //All queues are empty now + } // while message loop processing + } // while TRUE + // If we get here the TX thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: TX Thread exiting!!!!", __func__); + complete_and_exit(&pSchedContext->TxShutdown, 0); +} /* VosTxThread() */ + +/*--------------------------------------------------------------------------- + \brief VosRXThread() - The VOSS Main Rx thread + The \a VosRxThread() is the VOSS Rx controller thread: + \param Arg - pointer to the global vOSS Sched Context + + \return Thread exit code + \sa VosRxThread() + -------------------------------------------------------------------------*/ + +static int VosRXThread ( void * Arg ) +{ + pVosSchedContext pSchedContext = (pVosSchedContext)Arg; + pVosMsgWrapper pMsgWrapper = NULL; + int retWaitStatus = 0; + v_BOOL_t shutdown = VOS_FALSE; + hdd_context_t *pHddCtx = NULL; + v_CONTEXT_t pVosContext = NULL; + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + + set_user_nice(current, -1); + +#ifdef WLAN_FEATURE_11AC_HIGH_TP + set_wake_up_idle(true); +#endif + + if (Arg == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Bad Args passed", __func__); + return 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) + daemonize("RX_Thread"); +#endif + + /* + ** Ack back to the context from which the main controller thread has been + ** created. + */ + complete(&pSchedContext->RxStartEvent); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: RX Thread %d (%s) starting up!",__func__, current->pid, current->comm); + + /* Get the Global VOSS Context */ + pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if(!pVosContext) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Global VOS context is Null", __func__); + return 0; + } + + /* Get the HDD context */ + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if(!pHddCtx) { + hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__); + return 0; + } + + while(!shutdown) + { + // This implements the execution model algorithm + retWaitStatus = wait_event_interruptible(pSchedContext->rxWaitQueue, + test_bit(RX_POST_EVENT, &pSchedContext->rxEventFlag) || + test_bit(RX_SUSPEND_EVENT, &pSchedContext->rxEventFlag)); + + + if(retWaitStatus == -ERESTARTSYS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wait_event_interruptible returned -ERESTARTSYS", __func__); + break; + } + clear_bit(RX_POST_EVENT, &pSchedContext->rxEventFlag); + + while(1) + { + if(test_bit(RX_SHUTDOWN_EVENT, &pSchedContext->rxEventFlag)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: RX thread signaled to shutdown", __func__); + shutdown = VOS_TRUE; + /* Check for any Suspend Indication */ + if (test_and_clear_bit(RX_SUSPEND_EVENT, + &pSchedContext->rxEventFlag)) + { + /* Unblock anyone waiting on suspend */ + complete(&pHddCtx->rx_sus_event_var); + } + break; + } + + + // Check the SYS queue first + if (!vos_is_mq_empty(&pSchedContext->sysRxMq)) + { + // Service the SYS message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS SYS RX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->sysRxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = sysRxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing TX SYS message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + // Check now the TL queue + if (!vos_is_mq_empty(&pSchedContext->tlRxMq)) + { + // Service the TL message queue + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Servicing the VOS TL RX Message queue",__func__); + pMsgWrapper = vos_mq_get(&pSchedContext->tlRxMq); + if (pMsgWrapper == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pMsgWrapper is NULL", __func__); + VOS_ASSERT(0); + break; + } + vStatus = WLANTL_RxProcessMsg( pSchedContext->pVContext, + pMsgWrapper->pVosMsg); + if (!VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Issue Processing RX TL message",__func__); + } + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + continue; + } + + // Check the WDI queue + if (!vos_is_mq_empty(&pSchedContext->wdiRxMq)) + { + wpt_msg *pWdiMsg; + pMsgWrapper = vos_mq_get(&pSchedContext->wdiRxMq); + if ((NULL == pMsgWrapper) || (NULL == pMsgWrapper->pVosMsg)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: wdiRxMq message is NULL", __func__); + VOS_BUG(0); + // we won't return this wrapper since it is corrupt + } + else + { + pWdiMsg = (wpt_msg *)pMsgWrapper->pVosMsg->bodyptr; + if ((NULL == pWdiMsg) || (NULL == pWdiMsg->callback)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDI Msg or callback is NULL", __func__); + VOS_BUG(0); + } + else + { + // invoke the message handler + pWdiMsg->callback(pWdiMsg); + } + + // return message to the Core + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + continue; + } + + /* Check for any Suspend Indication */ + if (test_and_clear_bit(RX_SUSPEND_EVENT, + &pSchedContext->rxEventFlag)) + { + spin_lock(&pSchedContext->RxThreadLock); + INIT_COMPLETION(pSchedContext->ResumeRxEvent); + /* Rx Thread Suspended */ + complete(&pHddCtx->rx_sus_event_var); + spin_unlock(&pSchedContext->RxThreadLock); + + /* Wait for Resume Indication */ + wait_for_completion_interruptible(&pSchedContext->ResumeRxEvent); + } + + break; //All queues are empty now + } // while message loop processing + } // while TRUE + // If we get here the RX thread must exit + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: RX Thread exiting!!!!", __func__); + complete_and_exit(&pSchedContext->RxShutdown, 0); +} /* VosRxThread() */ + +/*--------------------------------------------------------------------------- + \brief vos_sched_close() - Close the vOSS Scheduler + The \a vos_sched_closes() function closes the vOSS Scheduler + Upon successful closing: + - All the message queues are flushed + - The Main Controller thread is closed + - The Tx thread is closed + + \param pVosContext - pointer to the global vOSS Context + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + \sa vos_sched_close() +---------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_close ( v_PVOID_t pVosContext ) +{ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: invoked", __func__); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return VOS_STATUS_E_FAILURE; + } + + // shut down MC Thread + set_bit(MC_SHUTDOWN_EVENT, &gpVosSchedContext->mcEventFlag); + set_bit(MC_POST_EVENT, &gpVosSchedContext->mcEventFlag); + wake_up_interruptible(&gpVosSchedContext->mcWaitQueue); + //Wait for MC to exit + wait_for_completion(&gpVosSchedContext->McShutdown); + gpVosSchedContext->McThread = 0; + + // shut down TX Thread + set_bit(TX_SHUTDOWN_EVENT, &gpVosSchedContext->txEventFlag); + set_bit(TX_POST_EVENT, &gpVosSchedContext->txEventFlag); + wake_up_interruptible(&gpVosSchedContext->txWaitQueue); + //Wait for TX to exit + wait_for_completion(&gpVosSchedContext->TxShutdown); + gpVosSchedContext->TxThread = 0; + + // shut down RX Thread + set_bit(RX_SHUTDOWN_EVENT, &gpVosSchedContext->rxEventFlag); + set_bit(RX_POST_EVENT, &gpVosSchedContext->rxEventFlag); + wake_up_interruptible(&gpVosSchedContext->rxWaitQueue); + //Wait for RX to exit + wait_for_completion(&gpVosSchedContext->RxShutdown); + gpVosSchedContext->RxThread = 0; + + //Clean up message queues of TX and MC thread + vos_sched_flush_mc_mqs(gpVosSchedContext); + vos_sched_flush_tx_mqs(gpVosSchedContext); + vos_sched_flush_rx_mqs(gpVosSchedContext); + + //Deinit all the queues + vos_sched_deinit_mqs(gpVosSchedContext); + + return VOS_STATUS_SUCCESS; +} /* vox_sched_close() */ + +VOS_STATUS vos_watchdog_close ( v_PVOID_t pVosContext ) +{ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: vos_watchdog closing now", __func__); + if (gpVosWatchdogContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosWatchdogContext is NULL",__func__); + return VOS_STATUS_E_FAILURE; + } + set_bit(WD_SHUTDOWN_EVENT, &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + //Wait for Watchdog thread to exit + wait_for_completion(&gpVosWatchdogContext->WdShutdown); + return VOS_STATUS_SUCCESS; +} /* vos_watchdog_close() */ + +/*--------------------------------------------------------------------------- + \brief vos_sched_init_mqs: Initialize the vOSS Scheduler message queues + The \a vos_sched_init_mqs() function initializes the vOSS Scheduler + message queues. + \param pVosSchedContext - pointer to the Scheduler Context. + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + \sa vos_sched_init_mqs() + -------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_init_mqs ( pVosSchedContext pSchedContext ) +{ + VOS_STATUS vStatus = VOS_STATUS_SUCCESS; + // Now intialize all the message queues + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the WDA MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->wdaMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init WDA MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the PE MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->peMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init PE MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the SME MC Message queue", __func__); + vStatus = vos_mq_init(&pSchedContext->smeMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SME MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the TL MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->tlMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init TL MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the SYS MC Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->sysMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SYS MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the WDI MC Message queue",__func__); + + vStatus = vos_mq_init(&pSchedContext->wdiMcMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init WDI MC Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the TL Tx Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->tlTxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init TL TX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the TL Rx Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->tlRxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init TL RX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the WDI Tx Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->wdiTxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init WDI TX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the WDI Rx Message queue",__func__); + + vStatus = vos_mq_init(&pSchedContext->wdiRxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init WDI RX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Initializing the SYS Tx Message queue",__func__); + vStatus = vos_mq_init(&pSchedContext->sysTxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SYS TX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + + vStatus = vos_mq_init(&pSchedContext->sysRxMq); + if (! VOS_IS_STATUS_SUCCESS(vStatus)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to init SYS RX Message queue",__func__); + VOS_ASSERT(0); + return vStatus; + } + return VOS_STATUS_SUCCESS; +} /* vos_sched_init_mqs() */ + +/*--------------------------------------------------------------------------- + \brief vos_sched_deinit_mqs: Deinitialize the vOSS Scheduler message queues + The \a vos_sched_init_mqs() function deinitializes the vOSS Scheduler + message queues. + \param pVosSchedContext - pointer to the Scheduler Context. + \return None + \sa vos_sched_deinit_mqs() + -------------------------------------------------------------------------*/ +void vos_sched_deinit_mqs ( pVosSchedContext pSchedContext ) +{ + // Now de-intialize all message queues + // MC WDA + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the WDA MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->wdaMcMq); + //MC PE + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the PE MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->peMcMq); + //MC SME + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the SME MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->smeMcMq); + //MC TL + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the TL MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->tlMcMq); + //MC SYS + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the SYS MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->sysMcMq); + // MC WDI + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the WDI MC Message queue",__func__); + vos_mq_deinit(&pSchedContext->wdiMcMq); + + //Tx TL + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the TL Tx Message queue",__func__); + vos_mq_deinit(&pSchedContext->tlTxMq); + + //Rx TL + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s De-Initializing the TL Rx Message queue",__func__); + vos_mq_deinit(&pSchedContext->tlRxMq); + + //Tx WDI + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: DeInitializing the WDI Tx Message queue",__func__); + vos_mq_deinit(&pSchedContext->wdiTxMq); + + + //Rx WDI + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: DeInitializing the WDI Rx Message queue",__func__); + vos_mq_deinit(&pSchedContext->wdiRxMq); + + //Tx SYS + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: DeInitializing the SYS Tx Message queue",__func__); + vos_mq_deinit(&pSchedContext->sysTxMq); + + //Rx SYS + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: DeInitializing the SYS Rx Message queue",__func__); + vos_mq_deinit(&pSchedContext->sysRxMq); + +} /* vos_sched_deinit_mqs() */ + +/*------------------------------------------------------------------------- + this helper function flushes all the MC message queues + -------------------------------------------------------------------------*/ +void vos_sched_flush_mc_mqs ( pVosSchedContext pSchedContext ) +{ + pVosMsgWrapper pMsgWrapper = NULL; + pVosContextType vosCtx; + + /* + ** Here each of the MC thread MQ shall be drained and returned to the + ** Core. Before returning a wrapper to the Core, the VOS message shall be + ** freed first + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + ("Flushing the MC Thread message queue") ); + + if (NULL == pSchedContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pSchedContext is NULL", __func__); + return; + } + + vosCtx = (pVosContextType)(pSchedContext->pVContext); + if (NULL == vosCtx) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: vosCtx is NULL", __func__); + return; + } + + /* Flush the SYS Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->sysMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC SYS message type %d ",__func__, + pMsgWrapper->pVosMsg->type ); + sysMcFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the WDA Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->wdaMcMq) )) + { + if(pMsgWrapper->pVosMsg != NULL) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC WDA MSG message type %d", + __func__, pMsgWrapper->pVosMsg->type ); + if (pMsgWrapper->pVosMsg->bodyptr) { + vos_mem_free((v_VOID_t*)pMsgWrapper->pVosMsg->bodyptr); + } + + pMsgWrapper->pVosMsg->bodyptr = NULL; + pMsgWrapper->pVosMsg->bodyval = 0; + pMsgWrapper->pVosMsg->type = 0; + } + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + + /* Flush the WDI Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->wdiMcMq) )) + { + if(pMsgWrapper->pVosMsg != NULL) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC WDI MSG message type %d", + __func__, pMsgWrapper->pVosMsg->type ); + + /* MSG body pointer is not NULL + * and MSG type is 0 + * This MSG is not posted by SMD NOTIFY + * We have to free MSG body */ + if ((pMsgWrapper->pVosMsg->bodyptr) && (!pMsgWrapper->pVosMsg->type)) + { + vos_mem_free((v_VOID_t*)pMsgWrapper->pVosMsg->bodyptr); + } + /* MSG body pointer is not NULL + * and MSG type is not 0 + * This MSG is posted by SMD NOTIFY + * We should not free MSG body */ + else if ((pMsgWrapper->pVosMsg->bodyptr) && pMsgWrapper->pVosMsg->type) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: SMD NOTIFY MSG, do not free body", + __func__); + } + pMsgWrapper->pVosMsg->bodyptr = NULL; + pMsgWrapper->pVosMsg->bodyval = 0; + pMsgWrapper->pVosMsg->type = 0; + } + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + + /* Flush the PE Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->peMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC PE MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + peFreeMsg(vosCtx->pMACContext, (tSirMsgQ*)pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the SME Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->smeMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC SME MSG message type %d", __func__, + pMsgWrapper->pVosMsg->type ); + sme_FreeMsg(vosCtx->pMACContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the TL Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->tlMcMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing MC TL message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + WLANTL_McFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } +} /* vos_sched_flush_mc_mqs() */ + +/*------------------------------------------------------------------------- + This helper function flushes all the TX message queues + ------------------------------------------------------------------------*/ +void vos_sched_flush_tx_mqs ( pVosSchedContext pSchedContext ) +{ + pVosMsgWrapper pMsgWrapper = NULL; + /* + ** Here each of the TX thread MQ shall be drained and returned to the + ** Core. Before returning a wrapper to the Core, the VOS message shall + ** be freed first + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Flushing the TX Thread message queue",__func__); + + if (NULL == pSchedContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pSchedContext is NULL", __func__); + return; + } + + /* Flush the SYS Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->sysTxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing TX SYS message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the TL Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->tlTxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing TX TL MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + WLANTL_TxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } + /* Flush the WDI Mq */ + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->wdiTxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing TX WDI MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + vos_core_return_msg(pSchedContext->pVContext, pMsgWrapper); + } +} /* vos_sched_flush_tx_mqs() */ +/*------------------------------------------------------------------------- + This helper function flushes all the RX message queues + ------------------------------------------------------------------------*/ +void vos_sched_flush_rx_mqs ( pVosSchedContext pSchedContext ) +{ + pVosMsgWrapper pMsgWrapper = NULL; + /* + ** Here each of the RX thread MQ shall be drained and returned to the + ** Core. Before returning a wrapper to the Core, the VOS message shall + ** be freed first + */ + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Flushing the RX Thread message queue",__func__); + + if (NULL == pSchedContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: pSchedContext is NULL", __func__); + return; + } + + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->wdiRxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing RX WDI MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + } + + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->tlRxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing RX TL MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + } + + while( NULL != (pMsgWrapper = vos_mq_get(&pSchedContext->sysRxMq) )) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, + VOS_TRACE_LEVEL_INFO, + "%s: Freeing RX SYS MSG message type %d",__func__, + pMsgWrapper->pVosMsg->type ); + sysTxFreeMsg(pSchedContext->pVContext, pMsgWrapper->pVosMsg); + } + +}/* vos_sched_flush_rx_mqs() */ + +/*------------------------------------------------------------------------- + This helper function helps determine if thread id is of TX thread + ------------------------------------------------------------------------*/ +int vos_sched_is_tx_thread(int threadID) +{ + // Make sure that Vos Scheduler context has been initialized + VOS_ASSERT( NULL != gpVosSchedContext); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return 0; + } + return ((gpVosSchedContext->TxThread) && (threadID == gpVosSchedContext->TxThread->pid)); +} +/*------------------------------------------------------------------------- + This helper function helps determine if thread id is of RX thread + ------------------------------------------------------------------------*/ +int vos_sched_is_rx_thread(int threadID) +{ + // Make sure that Vos Scheduler context has been initialized + VOS_ASSERT( NULL != gpVosSchedContext); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return 0; + } + return ((gpVosSchedContext->RxThread) && (threadID == gpVosSchedContext->RxThread->pid)); +} + +/*------------------------------------------------------------------------- + This helper function helps determine if thread id is of MC thread + ------------------------------------------------------------------------*/ +int vos_sched_is_mc_thread(int threadID) +{ + // Make sure that Vos Scheduler context has been initialized + VOS_ASSERT( NULL != gpVosSchedContext); + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + return 0; + } + return ((gpVosSchedContext->McThread) && + (threadID == gpVosSchedContext->McThread->pid)); +} + +/*------------------------------------------------------------------------- + Helper function to get the scheduler context + ------------------------------------------------------------------------*/ +pVosSchedContext get_vos_sched_ctxt(void) +{ + //Make sure that Vos Scheduler context has been initialized + if (gpVosSchedContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosSchedContext == NULL",__func__); + } + return (gpVosSchedContext); +} +/*------------------------------------------------------------------------- + Helper function to get the watchdog context + ------------------------------------------------------------------------*/ +pVosWatchdogContext get_vos_watchdog_ctxt(void) +{ + //Make sure that Vos Scheduler context has been initialized + if (gpVosWatchdogContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosWatchdogContext == NULL",__func__); + } + return (gpVosWatchdogContext); +} +/** + @brief vos_watchdog_wlan_shutdown() + + This function is called to shutdown WLAN driver during SSR. + Adapters are disabled, and the watchdog task will be signalled + to shutdown WLAN driver. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_watchdog_wlan_shutdown(void) +{ + v_CONTEXT_t pVosContext = NULL; + hdd_context_t *pHddCtx = NULL; + + if (NULL == gpVosWatchdogContext) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Watchdog not enabled. LOGP ignored.", __func__); + return VOS_STATUS_E_FAILURE; + } + + if (gpVosWatchdogContext->isFatalError) + { + /* If we hit this, it means wlan driver is in bad state and needs + * driver unload and load. + */ + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Driver in bad state and need unload and load", __func__); + return VOS_STATUS_E_FAILURE; + } + + + pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, pVosContext ); + if (NULL == pHddCtx) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid HDD Context", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* Take the lock here */ + spin_lock(&gpVosWatchdogContext->wdLock); + + /* reuse the existing 'reset in progress' */ + if (gpVosWatchdogContext->resetInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Shutdown already in Progress. Ignoring signaling Watchdog", + __func__); + /* Release the lock here */ + spin_unlock(&gpVosWatchdogContext->wdLock); + return VOS_STATUS_E_FAILURE; + } + /* reuse the existing 'logp in progress', eventhough it is not + * exactly the same */ + else if (pHddCtx->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: shutdown/re-init already in Progress. Ignoring signaling Watchdog", + __func__); + /* Release the lock here */ + spin_unlock(&gpVosWatchdogContext->wdLock); + return VOS_STATUS_E_FAILURE; + } + + if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Load/unload in Progress. Ignoring signaling Watchdog", + __func__); + /* wcnss has crashed, and SSR has alredy been started by Kernel driver. + * So disable SSR from WLAN driver */ + hdd_set_ssr_required( HDD_SSR_DISABLED ); + + /* Release the lock here before returning */ + spin_unlock(&gpVosWatchdogContext->wdLock); + return VOS_STATUS_E_FAILURE; + } + /* Set the flags so that all commands from userspace get blocked right away */ + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + pHddCtx->isLogpInProgress = TRUE; + + /* Release the lock here */ + spin_unlock(&gpVosWatchdogContext->wdLock); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: WLAN driver is shutting down ", __func__); + + /* Update Riva Reset Statistics */ + pHddCtx->hddRivaResetStats++; +#ifdef CONFIG_HAS_EARLYSUSPEND + if(VOS_STATUS_SUCCESS != hdd_wlan_reset_initialization()) + { + VOS_ASSERT(0); + } +#endif + + set_bit(WD_WLAN_SHUTDOWN_EVENT, &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + + return VOS_STATUS_SUCCESS; +} + +/** + @brief vos_watchdog_wlan_re_init() + + This function is called to re-initialize WLAN driver, and this is + called when Riva SS reboots. + + @param + NONE + @return + VOS_STATUS_SUCCESS - Operation completed successfully. + VOS_STATUS_E_FAILURE - Operation failed. + +*/ +VOS_STATUS vos_watchdog_wlan_re_init(void) +{ + /* Make sure that Vos Watchdog context has been initialized */ + if (gpVosWatchdogContext == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: gpVosWatchdogContext == NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + /* watchdog task is still running, it is not closed in shutdown */ + set_bit(WD_WLAN_REINIT_EVENT, &gpVosWatchdogContext->wdEventFlag); + set_bit(WD_POST_EVENT, &gpVosWatchdogContext->wdEventFlag); + wake_up_interruptible(&gpVosWatchdogContext->wdWaitQueue); + + return VOS_STATUS_SUCCESS; +} + +/** + @brief vos_ssr_protect() + + This function is called to keep track of active driver entry points + + @param + caller_func - Name of calling function. + @return + void +*/ +void vos_ssr_protect(const char *caller_func) +{ + int count; + count = atomic_inc_return(&ssr_protect_entry_count); +} + +/** + @brief vos_ssr_unprotect() + + @param + caller_func - Name of calling function. + @return + void +*/ +void vos_ssr_unprotect(const char *caller_func) +{ + int count; + count = atomic_dec_return(&ssr_protect_entry_count); +} +/** + * vos_is_wd_thread()- Check if threadid is + * of Watchdog thread + * + * @threadId: passed threadid + * + * This function is called to check if threadid is + * of wd thread. + * + * Return: true if threadid is of wd thread. + */ +bool vos_is_wd_thread(int threadId) +{ + /* Make sure that Vos Watchdog context has been initialized */ + if (gpVosWatchdogContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "%s: gpVosWatchdogContext == NULL", __func__); + return false; + } + + return ((gpVosWatchdogContext->WdThread) && + (threadId == gpVosWatchdogContext->WdThread->pid)); +} + +void vos_dump_stack(uint8_t thread_id) +{ + switch (thread_id) + { + case MC_Thread: + wcnss_dump_stack(gpVosSchedContext->McThread); + break; + case TX_Thread: + wcnss_dump_stack(gpVosSchedContext->TxThread); + break; + case RX_Thread: + wcnss_dump_stack(gpVosSchedContext->RxThread); + break; + default: + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid thread %d invoked",__func__, thread_id); + } +} + +void vos_dump_thread_stacks(int threadId) +{ + /* Make sure that Vos Watchdog context has been initialized */ + if (gpVosWatchdogContext == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: gpVosWatchdogContext == NULL", __func__); + return; + } + hddLog(LOGE, FL("Thread Stuck count reached threshold!!!" + "MC Count %d RX count %d TX count %d"), + gpVosWatchdogContext->mcThreadStuckCount, + gpVosWatchdogContext->rxThreadStuckCount, + gpVosWatchdogContext->txThreadStuckCount); + + vos_dump_stack(MC_Thread); + vos_dump_stack(TX_Thread); + vos_dump_stack(RX_Thread); +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_sched.h b/drivers/staging/prima/CORE/VOSS/src/vos_sched.h new file mode 100644 index 000000000000..09b8038e1a90 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_sched.h @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __VOS_SCHED_H ) +#define __VOS_SCHED_H + +/**========================================================================= + + \file vos_sched.h + + \brief virtual Operating System Servies (vOSS) + + Definitions for some of the internal data type that is internally used + by the vOSS scheduler on Windows Mobile. + + This file defines a vOSS message queue on Win Mobile and give some + insights about how the scheduler implements the execution model supported + by vOSS. + + + + ========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 09/15/08 lac Removed hardcoded #define for VOS_TRACE. + 06/12/08 hba Created module. + +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include "i_vos_types.h" +#include "i_vos_packet.h" +#include +#include +#include + + +#define TX_POST_EVENT 0x000 +#define TX_SUSPEND_EVENT 0x001 +#define MC_POST_EVENT 0x000 +#define MC_SUSPEND_EVENT 0x001 +#define RX_POST_EVENT 0x000 +#define RX_SUSPEND_EVENT 0x001 +#define TX_SHUTDOWN_EVENT 0x002 +#define MC_SHUTDOWN_EVENT 0x002 +#define RX_SHUTDOWN_EVENT 0x002 + +#define WD_POST_EVENT 0x000 +#define WD_SHUTDOWN_EVENT 0x001 +#define WD_CHIP_RESET_EVENT 0x002 +#define WD_WLAN_SHUTDOWN_EVENT 0x003 +#define WD_WLAN_REINIT_EVENT 0x004 +#define WD_WLAN_DETECT_THREAD_STUCK 0x005 + + + + +/* +** Maximum number of messages in the system +** These are buffers to account for all current messages +** with some accounting of what we think is a +** worst-case scenario. Must be able to handle all +** incoming frames, as well as overhead for internal +** messaging +*/ +#define VOS_CORE_MAX_MESSAGES (VPKT_NUM_RX_RAW_PACKETS + 32) + + +/* +** vOSS Message queue definition. +*/ +typedef struct _VosMqType +{ + /* Lock use to synchronize access to this message queue */ + spinlock_t mqLock; + + /* List of vOS Messages waiting on this queue */ + struct list_head mqList; + +} VosMqType, *pVosMqType; + + +/* +** vOSS Scheduler context +** The scheduler context contains the following: +** ** the messages queues +** ** the handle to the tread +** ** pointer to the events that gracefully shutdown the MC and Tx threads +** +*/ +typedef struct _VosSchedContext +{ + /* Place holder to the VOSS Context */ + v_PVOID_t pVContext; + /* WDA Message queue on the Main thread*/ + VosMqType wdaMcMq; + + + + /* PE Message queue on the Main thread*/ + VosMqType peMcMq; + + /* SME Message queue on the Main thread*/ + VosMqType smeMcMq; + + /* TL Message queue on the Main thread */ + VosMqType tlMcMq; + + /* SYS Message queue on the Main thread */ + VosMqType sysMcMq; + + /* WDI Message queue on the Main thread*/ + VosMqType wdiMcMq; + + /* WDI Message queue on the Tx Thread*/ + VosMqType wdiTxMq; + + /* WDI Message queue on the Rx Thread*/ + VosMqType wdiRxMq; + + /* TL Message queue on the Tx thread */ + VosMqType tlTxMq; + + /* TL Message queue on the Rx thread */ + VosMqType tlRxMq; + + /* SYS Message queue on the Tx thread */ + VosMqType sysTxMq; + + VosMqType sysRxMq; + + /* Handle of Event for MC thread to signal startup */ + struct completion McStartEvent; + + /* Handle of Event for Tx thread to signal startup */ + struct completion TxStartEvent; + + /* Handle of Event for Rx thread to signal startup */ + struct completion RxStartEvent; + + struct task_struct* McThread; + + /* TX Thread handle */ + + struct task_struct* TxThread; + + /* RX Thread handle */ + struct task_struct* RxThread; + + + /* completion object for MC thread shutdown */ + struct completion McShutdown; + + /* completion object for Tx thread shutdown */ + struct completion TxShutdown; + + /* completion object for Rx thread shutdown */ + struct completion RxShutdown; + + /* Wait queue for MC thread */ + wait_queue_head_t mcWaitQueue; + + unsigned long mcEventFlag; + + /* Wait queue for Tx thread */ + wait_queue_head_t txWaitQueue; + + unsigned long txEventFlag; + + /* Wait queue for Rx thread */ + wait_queue_head_t rxWaitQueue; + + unsigned long rxEventFlag; + + /* Completion object to resume Mc thread */ + struct completion ResumeMcEvent; + + /* Completion object to resume Tx thread */ + struct completion ResumeTxEvent; + + /* Completion object to resume Rx thread */ + struct completion ResumeRxEvent; + + /* lock to make sure that McThread and TxThread Suspend/resume mechanism is in sync*/ + spinlock_t McThreadLock; + spinlock_t TxThreadLock; + spinlock_t RxThreadLock; + +} VosSchedContext, *pVosSchedContext; + +/* +** VOSS watchdog context +** The watchdog context contains the following: +** The messages queues and events +** The handle to the thread +** +*/ +typedef struct _VosWatchdogContext +{ + + /* Place holder to the VOSS Context */ + v_PVOID_t pVContext; + + /* Handle of Event for Watchdog thread to signal startup */ + struct completion WdStartEvent; + + /* Watchdog Thread handle */ + + struct task_struct* WdThread; + + /* completion object for Watchdog thread shutdown */ + struct completion WdShutdown; + + /* Wait queue for Watchdog thread */ + wait_queue_head_t wdWaitQueue; + + /* Event flag for events handled by Watchdog */ + unsigned long wdEventFlag; + + v_BOOL_t resetInProgress; + + v_BOOL_t isFatalError; + + /* Lock for preventing multiple reset being triggered simultaneously */ + spinlock_t wdLock; + /* Timer to detect thread stuck issue */ + vos_timer_t threadStuckTimer; + /* Count for each thread to determine thread stuck */ + unsigned int mcThreadStuckCount; + unsigned int txThreadStuckCount; + unsigned int rxThreadStuckCount; + /* lock to synchronize access to the thread stuck counts */ + spinlock_t thread_stuck_lock; + +} VosWatchdogContext, *pVosWatchdogContext; + +/* +** vOSS Sched Msg Wrapper +** Wrapper messages so that they can be chained to their respective queue +** in the scheduler. +*/ +typedef struct _VosMsgWrapper +{ + /* Message node */ + struct list_head msgNode; + + /* the Vos message it is associated to */ + vos_msg_t *pVosMsg; + +} VosMsgWrapper, *pVosMsgWrapper; + + +typedef struct vos_wdthread_timer_work { + vos_timer_callback_t callback; + v_PVOID_t userData; + struct list_head node; +}vos_wdthread_timer_work_t; + +typedef struct _VosContextType +{ + /* Messages buffers */ + vos_msg_t aMsgBuffers[VOS_CORE_MAX_MESSAGES]; + + VosMsgWrapper aMsgWrappers[VOS_CORE_MAX_MESSAGES]; + + /* Free Message queue*/ + VosMqType freeVosMq; + + /* Scheduler Context */ + VosSchedContext vosSched; + + /* Watchdog Context */ + VosWatchdogContext vosWatchdog; + + /* HDD Module Context */ + v_VOID_t *pHDDContext; + + /* HDD SoftAP Module Context */ + v_VOID_t *pHDDSoftAPContext; + + /* TL Module Context */ + v_VOID_t *pTLContext; + + /* MAC Module Context */ + v_VOID_t *pMACContext; + + /* BAP Context */ + v_VOID_t *pBAPContext; + + /* SAP Context */ + v_VOID_t *pSAPContext; + + /* VOS Packet Context */ + vos_pkt_context_t vosPacket; + + vos_event_t ProbeEvent; + + volatile v_U8_t isLogpInProgress; + + vos_event_t wdaCompleteEvent; + + /* WDA Context */ + v_VOID_t *pWDAContext; + + volatile v_U8_t isLoadUnloadInProgress; + + /* SSR re-init in progress */ + volatile v_U8_t isReInitInProgress; + + /* NV BIN Version */ + eNvVersionType nvVersion; + + /* Roam delay statistic enabled in ini*/ + v_U8_t roamDelayStatsEnabled; + + /*Fw log complete Event*/ + vos_event_t fwLogsComplete; + v_U32_t wakelock_log_level; + v_U32_t connectivity_log_level; + v_U32_t packet_stats_log_level; + v_U8_t vosWrapperFullReported; + vos_wdthread_timer_work_t wdthread_timer_work; + struct list_head wdthread_timer_work_list; + struct work_struct wdthread_work; + spinlock_t wdthread_work_lock; + bool snoc_high_freq_voting; + spinlock_t freq_voting_lock; +} VosContextType, *pVosContextType; + + + +/*--------------------------------------------------------------------------- + Function declarations and documenation +---------------------------------------------------------------------------*/ + +int vos_sched_is_tx_thread(int threadID); +int vos_sched_is_rx_thread(int threadID); +int vos_sched_is_mc_thread(int threadID); +void vos_thread_stuck_timer_init(pVosWatchdogContext pWdContext); + +/*--------------------------------------------------------------------------- + + \brief vos_sched_open() - initialize the vOSS Scheduler + + The \a vos_sched_open() function initializes the vOSS Scheduler + Upon successful initialization: + + - All the message queues are initialized + + - The Main Controller thread is created and ready to receive and + dispatch messages. + + - The Tx thread is created and ready to receive and dispatch messages + + + \param pVosContext - pointer to the global vOSS Context + + \param pVosSchedContext - pointer to a previously allocated buffer big + enough to hold a scheduler context. + \ + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the scheduler + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the scheduler + + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_sched_open() + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_open( v_PVOID_t pVosContext, + pVosSchedContext pSchedCxt, + v_SIZE_t SchedCtxSize); + +/*--------------------------------------------------------------------------- + + \brief vos_watchdog_open() - initialize the vOSS watchdog + + The \a vos_watchdog_open() function initializes the vOSS watchdog. Upon successful + initialization, the watchdog thread is created and ready to receive and process messages. + + + \param pVosContext - pointer to the global vOSS Context + + \param pWdContext - pointer to a previously allocated buffer big + enough to hold a watchdog context. + + \return VOS_STATUS_SUCCESS - Watchdog was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the Watchdog + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the Watchdog + + VOS_STATUS_E_INVAL - Invalid parameter passed to the Watchdog Open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the Watchdog/ + + \sa vos_watchdog_open() + + -------------------------------------------------------------------------*/ + +VOS_STATUS vos_watchdog_open + +( + v_PVOID_t pVosContext, + pVosWatchdogContext pWdContext, + v_SIZE_t wdCtxSize +); + +/*--------------------------------------------------------------------------- + + \brief vos_sched_close() - Close the vOSS Scheduler + + The \a vos_sched_closes() function closes the vOSS Scheduler + Upon successful closing: + + - All the message queues are flushed + + - The Main Controller thread is closed + + - The Tx thread is closed + + + \param pVosContext - pointer to the global vOSS Context + + \return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and + is ready to be used. + + VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open + function + + VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/ + + \sa vos_sched_close() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_sched_close( v_PVOID_t pVosContext); + +/*--------------------------------------------------------------------------- + + \brief vos_watchdog_close() - Close the vOSS Watchdog + + The \a vos_watchdog_close() function closes the vOSS Watchdog + Upon successful closing: + + - The Watchdog thread is closed + + + \param pVosContext - pointer to the global vOSS Context + + \return VOS_STATUS_SUCCESS - Watchdog was successfully initialized and + is ready to be used. + + VOS_STATUS_E_INVAL - Invalid parameter passed + + VOS_STATUS_E_FAILURE - Failure to initialize the Watchdog/ + + \sa vos_watchdog_close() + +---------------------------------------------------------------------------*/ +VOS_STATUS vos_watchdog_close ( v_PVOID_t pVosContext ); + +/* Helper routines provided to other VOS API's */ +VOS_STATUS vos_mq_init(pVosMqType pMq); +void vos_mq_deinit(pVosMqType pMq); +void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper); +void vos_mq_put_front(pVosMqType pMq, pVosMsgWrapper pMsgWrapper); +pVosMsgWrapper vos_mq_get(pVosMqType pMq); +v_BOOL_t vos_is_mq_empty(pVosMqType pMq); +pVosSchedContext get_vos_sched_ctxt(void); +pVosWatchdogContext get_vos_watchdog_ctxt(void); +VOS_STATUS vos_sched_init_mqs (pVosSchedContext pSchedContext); +void vos_sched_deinit_mqs (pVosSchedContext pSchedContext); +void vos_sched_flush_mc_mqs (pVosSchedContext pSchedContext); +void vos_sched_flush_tx_mqs (pVosSchedContext pSchedContext); +void vos_sched_flush_rx_mqs (pVosSchedContext pSchedContext); +void clearWlanResetReason(void); + +void vos_timer_module_init( void ); +VOS_STATUS vos_watchdog_wlan_shutdown(void); +VOS_STATUS vos_watchdog_wlan_re_init(void); +v_BOOL_t isSsrPanicOnFailure(void); +void vos_ssr_protect(const char *caller_func); +void vos_ssr_unprotect(const char *caller_func); +void vos_wd_reset_thread_stuck_count(int threadId); +bool vos_is_wd_thread(int threadId); +void vos_dump_stack(uint8_t value); +void vos_dump_thread_stacks(int threadId); + +#endif // #if !defined __VOSS_SCHED_H diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_threads.c b/drivers/staging/prima/CORE/VOSS/src/vos_threads.c new file mode 100644 index 000000000000..df6f7beaeb83 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_threads.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_threads.c + + \brief virtual Operating System Services (vOSS) Threading APIs + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_sleep() - sleep + + The \a vos_sleep() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param msInterval - the number of milliseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep( v_U32_t msInterval ) +{ + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return; + } + msleep_interruptible(msInterval); +} + +/*---------------------------------------------------------------------------- + + \brief vos_sleep_us() - sleep + + The \a vos_sleep_us() function suspends the execution of the current thread + until the specified time out interval elapses. + + \param usInterval - the number of microseconds to suspend the current thread. + A value of 0 may or may not cause the current thread to yield. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_sleep_us( v_U32_t usInterval ) +{ + unsigned long timeout = usecs_to_jiffies(usInterval) + 1; + if (in_interrupt()) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s cannot be called from interrupt context!!!", __func__); + return; + } + while (timeout && !signal_pending(current)) + timeout = schedule_timeout_interruptible(timeout); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_busy_wait() - busy wait + + The \a vos_busy_wait() function places the current thread in busy wait + until the specified time out interval elapses. If the interval is greater + than 50us on WM, the behaviour is undefined. + + \param usInterval - the number of microseconds to busy wait. + + \return Nothing. + + \sa + + --------------------------------------------------------------------------*/ +v_VOID_t vos_busy_wait( v_U32_t usInterval ) +{ + udelay(usInterval); +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_timer.c b/drivers/staging/prima/CORE/VOSS/src/vos_timer.c new file mode 100644 index 000000000000..44e8681f2609 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_timer.c @@ -0,0 +1,1091 @@ +/* + * Copyright (c) 2012-2013, 2015-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_timer.c + + \brief virtual Operating System Servies (vOS) + + Definitions for vOSS Timer services + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +#include "wlan_qct_sys.h" +#include "vos_sched.h" +#include + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define LINUX_TIMER_COOKIE 0x12341234 +#define LINUX_INVALID_TIMER_COOKIE 0xfeedface +#define TMR_INVALID_ID ( 0 ) + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ +static unsigned int persistentTimerCount; +static vos_lock_t persistentTimerCountLock; +// static sleep_okts_handle sleepClientHandle; + +/*------------------------------------------------------------------------- + Function declarations and documenation + ------------------------------------------------------------------------*/ +// TBD: Need to add code for deferred timers implementation + +// clean up timer states after it has been deactivated +// check and try to allow sleep after a timer has been stopped or expired +static void tryAllowingSleep( VOS_TIMER_TYPE type ) +{ + if ( VOS_TIMER_TYPE_WAKE_APPS == type ) + { + // vos_lock_acquire( &persistentTimerCountLock ); + persistentTimerCount--; + if ( 0 == persistentTimerCount ) + { + // since the number of persistent timers has decreased from 1 to 0, + // the timer should allow sleep + //sleep_assert_okts( sleepClientHandle ); + } + //vos_lock_release( &persistentTimerCountLock ); + } +} + + +/*---------------------------------------------------------------------------- + + \brief vos_linux_timer_callback() - internal vos entry point which is + called when the timer interval expires + + This function in turn calls the vOS client callback and changes the + state of the timer from running (ACTIVE) to expired (INIT). + + + \param data - pointer to the timer control block which describes the + timer that expired + + \return nothing + + Note: function signature is defined by the Linux kernel. The fact + that the argument is "unsigned long" instead of "void *" is + unfortunately imposed upon us. But we can safely pass a pointer via + this parameter for LP32 and LP64 architectures. + + --------------------------------------------------------------------------*/ + +static void vos_linux_timer_callback (unsigned long data) +{ + vos_timer_t *timer = ( vos_timer_t *)data; + vos_msg_t msg; + VOS_STATUS vStatus; + unsigned long flags; + + vos_timer_callback_t callback=NULL; + v_PVOID_t userData=NULL; + int threadId; + VOS_TIMER_TYPE type=VOS_TIMER_TYPE_SW; + v_CONTEXT_t vos_context = NULL; + pVosContextType vos_global_context; + vos_wdthread_timer_work_t *wdthread_timer_work; + + VOS_ASSERT(timer); + + if (timer == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "%s Null pointer passed in!",__func__); + return; + } + + threadId = timer->platformInfo.threadID; + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + switch ( timer->state ) + { + case VOS_TIMER_STATE_STARTING: + // we are in this state because someone just started the timer, MM timer + // got started and expired, but the time content have not bee updated + // this is a rare race condition! + timer->state = VOS_TIMER_STATE_STOPPED; + vStatus = VOS_STATUS_E_ALREADY; + break; + case VOS_TIMER_STATE_STOPPED: + vStatus = VOS_STATUS_E_ALREADY; + break; + case VOS_TIMER_STATE_UNUSED: + vStatus = VOS_STATUS_E_EXISTS; + break; + case VOS_TIMER_STATE_RUNNING: + // need to go to stop state here because the call-back function may restart + // timer (to emulate periodic timer) + timer->state = VOS_TIMER_STATE_STOPPED; + // copy the relevant timer information to local variables; + // once we exist from this critical section, the timer content may be modified + // by other tasks + callback = timer->callback; + userData = timer->userData; + threadId = timer->platformInfo.threadID; + type = timer->type; + vStatus = VOS_STATUS_SUCCESS; + break; + default: + VOS_ASSERT(0); + vStatus = VOS_STATUS_E_FAULT; + break; + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + if ( VOS_STATUS_SUCCESS != vStatus ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "TIMER callback called in a wrong state=%d", timer->state); + return; + } + + tryAllowingSleep( type ); + + if (callback == NULL) + { + VOS_ASSERT(0); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: No TIMER callback, Could not enqueue timer to any queue", + __func__); + return; + } + + // If timer has expired then call vos_client specific callback + if ( vos_sched_is_tx_thread( threadId ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on TX thread"); + + //Serialize to the Tx thread + sysBuildMessageHeader( SYS_MSG_ID_TX_TIMER, &msg ); + msg.callback = callback; + msg.bodyptr = userData; + msg.bodyval = 0; + + if(vos_tx_mq_serialize( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS) + return; + } + else if ( vos_sched_is_rx_thread( threadId ) ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on RX thread"); + + //Serialize to the Rx thread + sysBuildMessageHeader( SYS_MSG_ID_RX_TIMER, &msg ); + msg.callback = callback; + msg.bodyptr = userData; + msg.bodyval = 0; + + if(vos_rx_mq_serialize( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS) + return; + } +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + else if (vos_is_wd_thread(threadId)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on wd thread"); + vos_context = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + if(!vos_context) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return; + } + vos_global_context = (pVosContextType)vos_context; + wdthread_timer_work = vos_mem_malloc(sizeof(*wdthread_timer_work)); + if (NULL == wdthread_timer_work) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: No memory available", __func__); + return; + } + wdthread_timer_work->callback = callback; + wdthread_timer_work->userData = userData; + spin_lock(&vos_global_context->wdthread_work_lock); + list_add(&wdthread_timer_work->node, + &vos_global_context->wdthread_timer_work_list); + spin_unlock(&vos_global_context->wdthread_work_lock); + + schedule_work(&vos_global_context->wdthread_work); + return; + } +#endif + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "TIMER callback: running on MC thread"); + + // Serialize to the MC thread + sysBuildMessageHeader( SYS_MSG_ID_MC_TIMER, &msg ); + msg.callback = callback; + msg.bodyptr = userData; + msg.bodyval = 0; + + if(vos_mq_post_message( VOS_MQ_ID_SYS, &msg ) == VOS_STATUS_SUCCESS) + return; + } + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Could not enqueue timer to any queue", __func__); + VOS_ASSERT(0); +} + +/*--------------------------------------------------------------------------- + + \brief vos_timer_getCurrentState() - Get the current state of the timer + + \param pTimer - the timer object + + \return timer state + + \sa + +---------------------------------------------------------------------------*/ +VOS_TIMER_STATE vos_timer_getCurrentState( vos_timer_t *pTimer ) +{ + if ( NULL == pTimer ) + { + VOS_ASSERT(0); + return VOS_TIMER_STATE_UNUSED; + } + + switch ( pTimer->state ) + { + case VOS_TIMER_STATE_STOPPED: + case VOS_TIMER_STATE_STARTING: + case VOS_TIMER_STATE_RUNNING: + case VOS_TIMER_STATE_UNUSED: + return pTimer->state; + default: + VOS_ASSERT(0); + return VOS_TIMER_STATE_UNUSED; + } +} + +/*---------------------------------------------------------------------------- + + \brief vos_timer_module_init() - Initializes a vOSS timer module. + + This API initializes the VOSS timer module. This needs to be called + exactly once prior to using any VOSS timers. + + \sa + + --------------------------------------------------------------------------*/ + +void vos_timer_module_init( void ) +{ + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, + "Initializing the VOSS timer module"); + vos_lock_init( &persistentTimerCountLock ); +} + +#ifdef TIMER_MANAGER +#include "wlan_hdd_dp_utils.h" + +hdd_list_t vosTimerList; + +static void vos_timer_clean(void); + +void vos_timer_manager_init() +{ + /* Initalizing the list with maximum size of 60000 */ + hdd_list_init(&vosTimerList, 1000); + return; +} + +static void vos_timer_clean() +{ + v_SIZE_t listSize; + unsigned long flags; + + hdd_list_size(&vosTimerList, &listSize); + + if (listSize) + { + hdd_list_node_t* pNode; + VOS_STATUS vosStatus; + + timer_node_t *ptimerNode; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: List is not Empty. listSize %d ", + __func__, (int)listSize); + + do + { + spin_lock_irqsave(&vosTimerList.lock, flags); + vosStatus = hdd_list_remove_front(&vosTimerList, &pNode); + spin_unlock_irqrestore(&vosTimerList.lock, flags); + if (VOS_STATUS_SUCCESS == vosStatus) + { + ptimerNode = (timer_node_t*)pNode; + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "Timer Leak@ File %s, @Line %d", + ptimerNode->fileName, (int)ptimerNode->lineNum); + + vos_mem_free(ptimerNode); + } + } while (vosStatus == VOS_STATUS_SUCCESS); + } +} + +void vos_timer_exit() +{ + vos_timer_clean(); + hdd_list_destroy(&vosTimerList); +} +#endif + +/*-------------------------------------------------------------------------- + + \brief vos_timer_init() - Initialize a vOSS timer. + + This API initializes a vOS Timer object. + + The \a vos_timer_init() initializes a vOS Timer object. A timer must be + initialized by calling vos_timer_initialize() before it may be used in + any other timer functions. + + Attempting to initialize timer that is already initialized results in + a failure. A destroyed timer object can be re-initialized with a call to + \a vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer such + as vos_timer_set() will fail if the timer is not initialized or has + been destroyed. Therefore, don't use the timer after it has been + destroyed until it has been re-initialized. + + All callback will be executed within the VOS main thread unless it is + initialized from the Tx thread flow, in which case it will be executed + within the tx thread flow. + + \param timer - pointer to the opaque timer object to initialize + + \param timerType - specifies the type of timer. We have two different + timer types. +
      +
    1. VOS_TIMER_TYPE_SW - Pure software timer. The Apps processor + may not be awoken when this timer expires. +
    2. VOS_TIMER_TYPE_WAKE_APPS - The Apps processor will be awoken + from power collapse when this type of timer expires. +
    + + \param callback - the callback function to be called when the timer + expires. + + \param userData - a user data (or context) that is returned to the + callback function as a parameter when the timer expires. + + \return VOS_STATUS_SUCCESS - timer was successfully initialized and + is ready to be used. + + VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initialize the timer + + VOS_STATUS_E_NOMEM - insufficient memory exists to initialize + the timer + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to initialize the object referenced by timer, a previously + initialized but not yet destroyed timer. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +static inline VOS_STATUS __vos_timer_init_debug(vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, + v_PVOID_t userData, + bool deferrable, + char* fileName, + v_U32_t lineNum) +{ + VOS_STATUS vosStatus; + unsigned long flags; + // Check for invalid pointer + if ((timer == NULL) || (callback == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + timer->ptimerNode = vos_mem_malloc(sizeof(timer_node_t)); + + if (timer->ptimerNode == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for timeNode", + __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + vos_mem_set(timer->ptimerNode, sizeof(timer_node_t), 0); + + timer->ptimerNode->fileName = fileName; + timer->ptimerNode->lineNum = lineNum; + timer->ptimerNode->vosTimer = timer; + + spin_lock_irqsave(&vosTimerList.lock, flags); + vosStatus = hdd_list_insert_front(&vosTimerList, &timer->ptimerNode->pNode); + spin_unlock_irqrestore(&vosTimerList.lock, flags); + if (VOS_STATUS_SUCCESS != vosStatus) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to insert node into List vosStatus %d", + __func__, vosStatus); + } + + /* set the various members of the timer structure + * with arguments passed or with default values + */ + spin_lock_init(&timer->platformInfo.spinlock); + if(deferrable) + init_timer_deferrable(&(timer->platformInfo.Timer)); + else + init_timer(&(timer->platformInfo.Timer)); + timer->platformInfo.Timer.function = vos_linux_timer_callback; + timer->platformInfo.Timer.data = (unsigned long)timer; + timer->callback = callback; + timer->userData = userData; + timer->type = timerType; + timer->platformInfo.cookie = LINUX_TIMER_COOKIE; + timer->platformInfo.threadID = 0; + timer->state = VOS_TIMER_STATE_STOPPED; + + return VOS_STATUS_SUCCESS; +} + +VOS_STATUS vos_timer_init_debug(vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, + v_PVOID_t userData, + char* fileName, + v_U32_t lineNum) +{ + return __vos_timer_init_debug(timer, timerType, + callback, userData, false, fileName, lineNum); +} + +VOS_STATUS vos_timer_init_deferrable_debug(vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, + v_PVOID_t userData, + char* fileName, + v_U32_t lineNum) +{ + return __vos_timer_init_debug(timer, timerType, + callback, userData, true, fileName, lineNum); +} +#else +static inline VOS_STATUS __vos_timer_init(vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, + v_PVOID_t userData, + bool deferrable) +{ + /* Check for invalid pointer */ + if ((timer == NULL) || (callback == NULL)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null params being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + /* set the various members of the timer structure + * with arguments passed or with default values + */ + spin_lock_init(&timer->platformInfo.spinlock); + if(deferrable) + init_timer_deferrable(&(timer->platformInfo.Timer)); + else + init_timer(&(timer->platformInfo.Timer)); + timer->platformInfo.Timer.function = vos_linux_timer_callback; + timer->platformInfo.Timer.data = (unsigned long)timer; + timer->callback = callback; + timer->userData = userData; + timer->type = timerType; + timer->platformInfo.cookie = LINUX_TIMER_COOKIE; + timer->platformInfo.threadID = 0; + timer->state = VOS_TIMER_STATE_STOPPED; + + return VOS_STATUS_SUCCESS; +} +VOS_STATUS vos_timer_init(vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, + v_PVOID_t userData) +{ + return __vos_timer_init(timer, timerType, + callback, userData, false); + +} + +VOS_STATUS vos_timer_init_deferrable(vos_timer_t *timer, + VOS_TIMER_TYPE timerType, + vos_timer_callback_t callback, + v_PVOID_t userData) +{ + return __vos_timer_init(timer, timerType, + callback, userData, true); +} +#endif + + +/*--------------------------------------------------------------------------- + + \brief vos_timer_destroy() - Destroy a vOSS Timer object + + The \a vos_timer_destroy() function shall destroy the timer object. + After a successful return from \a vos_timer_destroy() the timer + object becomes, in effect, uninitialized. + + A destroyed timer object can be re-initialized by calling + vos_timer_init(). The results of otherwise referencing the object + after it has been destroyed are undefined. + + Calls to vOSS timer functions to manipulate the timer, such + as vos_timer_set() will fail if the lock is destroyed. Therefore, + don't use the timer after it has been destroyed until it has + been re-initialized. + + \param timer - the timer object to be destroyed. + + \return VOS_STATUS_SUCCESS - timer was successfully destroyed. + + VOS_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by timer while it is still + still referenced. The timer must be stopped before it can be + destroyed. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + +---------------------------------------------------------------------------*/ +#ifdef TIMER_MANAGER +VOS_STATUS vos_timer_destroy ( vos_timer_t *timer ) +{ + VOS_STATUS vStatus=VOS_STATUS_SUCCESS; + unsigned long flags; + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null timer pointer being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy uninitialized timer",__func__); + return VOS_STATUS_E_INVAL; + } + + spin_lock_irqsave(&vosTimerList.lock, flags); + vStatus = hdd_list_remove_node(&vosTimerList, &timer->ptimerNode->pNode); + spin_unlock_irqrestore(&vosTimerList.lock, flags); + if(vStatus != VOS_STATUS_SUCCESS) + { + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + vos_mem_free(timer->ptimerNode); + + + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + switch ( timer->state ) + { + case VOS_TIMER_STATE_STARTING: + vStatus = VOS_STATUS_E_BUSY; + break; + case VOS_TIMER_STATE_RUNNING: + /* Stop the timer first */ + del_timer(&(timer->platformInfo.Timer)); + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_STOPPED: + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_UNUSED: + vStatus = VOS_STATUS_E_ALREADY; + break; + default: + vStatus = VOS_STATUS_E_FAULT; + break; + } + + if ( VOS_STATUS_SUCCESS == vStatus ) + { + timer->platformInfo.cookie = LINUX_INVALID_TIMER_COOKIE; + timer->state = VOS_TIMER_STATE_UNUSED; + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + return vStatus; + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy timer in state = %d",__func__, timer->state); + VOS_ASSERT(0); + + return vStatus; +} + +#else +VOS_STATUS vos_timer_destroy ( vos_timer_t *timer ) +{ + VOS_STATUS vStatus=VOS_STATUS_SUCCESS; + unsigned long flags; + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Null timer pointer being passed",__func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAULT; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy uninitialized timer",__func__); + return VOS_STATUS_E_INVAL; + } + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + switch ( timer->state ) + { + case VOS_TIMER_STATE_STARTING: + vStatus = VOS_STATUS_E_BUSY; + break; + case VOS_TIMER_STATE_RUNNING: + /* Stop the timer first */ + del_timer(&(timer->platformInfo.Timer)); + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_STOPPED: + vStatus = VOS_STATUS_SUCCESS; + break; + case VOS_TIMER_STATE_UNUSED: + vStatus = VOS_STATUS_E_ALREADY; + break; + default: + vStatus = VOS_STATUS_E_FAULT; + break; + } + + if ( VOS_STATUS_SUCCESS == vStatus ) + { + timer->platformInfo.cookie = LINUX_INVALID_TIMER_COOKIE; + timer->state = VOS_TIMER_STATE_UNUSED; + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + return vStatus; + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot destroy timer in state = %d",__func__, timer->state); + VOS_ASSERT(0); + + return vStatus; +} +#endif + +/*-------------------------------------------------------------------------- + + \brief vos_timer_start() - Start a vOSS Timer object + + The \a vos_timer_start() function starts a timer to expire after the + specified interval, thus running the timer callback function when + the interval expires. + + A timer only runs once (a one-shot timer). To re-start the + timer, vos_timer_start() has to be called after the timer runs + or has been cancelled. + + \param timer - the timer object to be started + + \param expirationTime - expiration time for the timer (in milliseconds) + + \return VOS_STATUS_SUCCESS - timer was successfully started. + + VOS_STATUS_E_ALREADY - The implementation has detected an attempt + to start a timer while it is already started. The timer must + be stopped or expire before it can be started again. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + -------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_start( vos_timer_t *timer, v_U32_t expirationTime ) +{ + unsigned long flags; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "Timer Addr inside voss_start : 0x%p ", timer ); + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Null timer pointer being passed", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot start uninitialized timer",__func__); + if ( LINUX_INVALID_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_ASSERT(0); + } + return VOS_STATUS_E_INVAL; + } + + // Check if timer has expiration time less than 10 ms + if ( expirationTime < 10 ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot start a " + "timer with expiration less than 10 ms", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // make sure the remainer of the logic isn't interrupted + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + // Ensure if the timer can be started + if ( VOS_TIMER_STATE_STOPPED != timer->state ) + { + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Cannot start timer in state = %d ",__func__, timer->state); + return VOS_STATUS_E_ALREADY; + } + + // Start the timer + mod_timer( &(timer->platformInfo.Timer), + jiffies + msecs_to_jiffies(expirationTime)); + + timer->state = VOS_TIMER_STATE_RUNNING; + + // Get the thread ID on which the timer is being started + timer->platformInfo.threadID = current->pid; + + if ( VOS_TIMER_TYPE_WAKE_APPS == timer->type ) + { + persistentTimerCount++; + if ( 1 == persistentTimerCount ) + { + // Since we now have one persistent timer, we need to disallow sleep + // sleep_negate_okts( sleepClientHandle ); + } + } + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_stop() - Stop a vOSS Timer + + The \a vos_timer_stop() function stops a timer that has been started but + has not expired, essentially cancelling the 'start' request. + + After a timer is stopped, it goes back to the state it was in after it + was created and can be started again via a call to vos_timer_start(). + + \param timer - the timer object to be stopped + + \return VOS_STATUS_SUCCESS - timer was successfully stopped. + + VOS_STATUS_E_INVAL - The value specified by timer is invalid. + + VOS_STATUS_E_FAULT - timer is an invalid pointer. + \sa + + ------------------------------------------------------------------------*/ +VOS_STATUS vos_timer_stop ( vos_timer_t *timer ) +{ + unsigned long flags; + + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Timer Addr inside voss_stop : 0x%p",__func__,timer ); + + // Check for invalid pointer + if ( NULL == timer ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s Null timer pointer being passed", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + // Check if timer refers to an uninitialized object + if ( LINUX_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Cannot stop uninitialized timer",__func__); + if ( LINUX_INVALID_TIMER_COOKIE != timer->platformInfo.cookie ) + { + VOS_ASSERT(0); + } + return VOS_STATUS_E_INVAL; + } + + // Ensure the timer state is correct + spin_lock_irqsave( &timer->platformInfo.spinlock,flags ); + + if ( VOS_TIMER_STATE_RUNNING != timer->state ) + { + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Cannot stop timer in state = %d", + __func__, timer->state); + return VOS_STATUS_SUCCESS; + } + + timer->state = VOS_TIMER_STATE_STOPPED; + + del_timer(&(timer->platformInfo.Timer)); + + spin_unlock_irqrestore( &timer->platformInfo.spinlock,flags ); + + tryAllowingSleep( timer->type ); + + return VOS_STATUS_SUCCESS; +} + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_ticks() - Get the system time in 10ms ticks + + The \a vos_timer_get_system_ticks() function returns the current number + of timer ticks in 10msec intervals. This function is suitable timestamping + and calculating time intervals by calculating the difference between two + timestamps. + + \returns - The current system tick count (in 10msec intervals). This + function cannot fail. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_ticks( v_VOID_t ) +{ + return( jiffies_to_msecs(jiffies) / 10 ); +} + + +/*-------------------------------------------------------------------------- + + \brief vos_timer_get_system_time() - Get the system time in milliseconds + + The \a vos_timer_get_system_time() function returns the number of milliseconds + that have elapsed since the system was started + + \returns - The current system time in milliseconds. + + \sa + + ------------------------------------------------------------------------*/ +v_TIME_t vos_timer_get_system_time( v_VOID_t ) +{ + struct timeval tv; + do_gettimeofday(&tv); + return tv.tv_sec*1000 + tv.tv_usec/1000; +} + +/*-------------------------------------------------------------------------- + + \brief vos_timer_is_initialized() - check if timer is initialized or not + + The \a vos_timer_is_initialized() function returns VOS_TRUE if timer is + initialized and VOS_FALSE if timer is not initialized + + \returns - VOS_TRUE or VOS_FALSE + + \sa + + ------------------------------------------------------------------------*/ +v_BOOL_t vos_timer_is_initialized(vos_timer_t *timer) +{ + if (LINUX_TIMER_COOKIE == timer->platformInfo.cookie) + return VOS_TRUE; + else + return VOS_FALSE; +} + +/** + * vos_wdthread_init_timer_work() - Initialize timer work + * @callbackptr: timer work callback + * + * Initialize watchdog thread timer work structure and linked + * list. + * return - void + */ +void vos_wdthread_init_timer_work(void *callbackptr) +{ + pVosContextType context; + + context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!context) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return; + } + + spin_lock_init(&context->wdthread_work_lock); + INIT_LIST_HEAD(&context->wdthread_timer_work_list); +#if defined (WLAN_OPEN_SOURCE) + INIT_WORK(&context->wdthread_work, callbackptr); +#else + wcnss_init_work(&context->wdthread_work, callbackptr); +#endif +} + +/** + * vos_wdthread_flush_timer_work() - Flush timer work + * + * Flush watchdog thread timer work structure. + * return - void + */ +void vos_wdthread_flush_timer_work() +{ + pVosContextType context; + + context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + if (!context) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return; + } + +#if defined (WLAN_OPEN_SOURCE) + cancel_work_sync(&context->wdthread_work); +#else + wcnss_flush_work(&context->wdthread_work); +#endif +} + +/** + * __vos_process_wd_timer() - Handle wathdog thread timer work + * + * Process watchdog thread timer work. + * return - void + */ +static void __vos_process_wd_timer(void) +{ + v_CONTEXT_t vos_context = NULL; + pVosContextType vos_global_context; + vos_wdthread_timer_work_t *wdthread_timer_work; + struct list_head *pos, *next; + + vos_context = vos_get_global_context(VOS_MODULE_ID_SYS, NULL); + + if(!vos_context) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Global VOS context is Null", __func__); + return; + } + + vos_global_context = (pVosContextType)vos_context; + + spin_lock(&vos_global_context->wdthread_work_lock); + list_for_each_safe(pos, next, + &vos_global_context->wdthread_timer_work_list) { + wdthread_timer_work = list_entry(pos, + vos_wdthread_timer_work_t, + node); + list_del(pos); + spin_unlock(&vos_global_context->wdthread_work_lock); + if (NULL != wdthread_timer_work->callback) + wdthread_timer_work->callback(wdthread_timer_work->userData); + vos_mem_free(wdthread_timer_work); + spin_lock(&vos_global_context->wdthread_work_lock); + } + spin_unlock(&vos_global_context->wdthread_work_lock); + + return; +} + +/** + * vos_process_wd_timer() - Wrapper function to handle timer work + * + * Wrapper function to process timer work. + * return - void + */ +void vos_process_wd_timer(void) +{ + vos_ssr_protect(__func__); + __vos_process_wd_timer(); + vos_ssr_unprotect(__func__); +} + diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_trace.c b/drivers/staging/prima/CORE/VOSS/src/vos_trace.c new file mode 100644 index 000000000000..fda24aa2fc80 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_trace.c @@ -0,0 +1,703 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_trace.c + + \brief virtual Operating System Servies (vOS) + + Trace, logging, and debugging definitions and APIs + + + ========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + -------- --- -------------------------------------------------------- + 09/16/08 hvm Adding ability to set multiple trace levels per component + 09/11/08 lac Added trace levels per component. Cleanup from review. + 08/14/08 vpai Particular modules and desired level can be selected + 06/20/08 vpai Created Module +===========================================================================*/ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include +#include +#include +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define VOS_TRACE_BUFFER_SIZE ( 512 ) + +// macro to map vos trace levels into the bitmask +#define VOS_TRACE_LEVEL_TO_MODULE_BITMASK( _level ) ( ( 1 << (_level) ) ) + +typedef struct +{ + // Trace level for a module, as a bitmask. The bits in this mask + // are ordered by VOS_TRACE_LEVEL. For example, each bit represents + // one of the bits in VOS_TRACE_LEVEL that may be turned on to have + // traces at that level logged, i.e. if VOS_TRACE_LEVEL_ERROR is + // == 2, then if bit 2 (low order) is turned ON, then ERROR traces + // will be printed to the trace log. + // + // Note that all bits turned OFF means no traces. + v_U16_t moduleTraceLevel; + + // 3 character string name for the module + unsigned char moduleNameStr[ 4 ]; // 3 chars plus the NULL + +} moduleTraceInfo; + +#define VOS_DEFAULT_TRACE_LEVEL \ + ((1<= VOS_TRACE_LEVEL_MAX ) + { + pr_err("%s: Invalid trace level %d passed in!\n", __func__, level); + return; + } + + // Treat 'none' differently. NONE means we have to run off all + // the bits in the bit mask so none of the traces appear. Anything other + // than 'none' means we need to turn ON a bit in the bitmask. + if ( VOS_TRACE_LEVEL_NONE == level ) + { + gVosTraceInfo[ module ].moduleTraceLevel = VOS_TRACE_LEVEL_NONE; + } + else + { + // Set the desired bit in the bit mask for the module trace level. + gVosTraceInfo[ module ].moduleTraceLevel |= VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ); + } +} + +void vos_trace_setValue( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, v_U8_t on) +{ + // Make sure the caller is passing in a valid LEVEL. + if ( level < 0 || level >= VOS_TRACE_LEVEL_MAX ) + { + pr_err("%s: Invalid trace level %d passed in!\n", __func__, level); + return; + } + + // Make sure the caller is passing in a valid module. + if ( module < 0 || module >= VOS_MODULE_ID_MAX ) + { + pr_err("%s: Invalid module id %d passed in!\n", __func__, module); + return; + } + + // Treat 'none' differently. NONE means we have to turn off all + // the bits in the bit mask so none of the traces appear. + if ( VOS_TRACE_LEVEL_NONE == level ) + { + gVosTraceInfo[ module ].moduleTraceLevel = VOS_TRACE_LEVEL_NONE; + } + // Treat 'All' differently. All means we have to turn on all + // the bits in the bit mask so all of the traces appear. + else if ( VOS_TRACE_LEVEL_ALL == level ) + { + gVosTraceInfo[ module ].moduleTraceLevel = 0xFFFF; + } + + else + { + if (on) + // Set the desired bit in the bit mask for the module trace level. + gVosTraceInfo[ module ].moduleTraceLevel |= VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ); + else + // Clear the desired bit in the bit mask for the module trace level. + gVosTraceInfo[ module ].moduleTraceLevel &= ~(VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level )); + } +} + + +v_BOOL_t vos_trace_getLevel( VOS_MODULE_ID module, VOS_TRACE_LEVEL level ) +{ + v_BOOL_t traceOn = VOS_FALSE; + + if ( ( VOS_TRACE_LEVEL_NONE == level ) || + ( VOS_TRACE_LEVEL_ALL == level ) || + ( level >= VOS_TRACE_LEVEL_MAX ) ) + { + traceOn = VOS_FALSE; + } + else + { + traceOn = ( level & gVosTraceInfo[ module ].moduleTraceLevel ) ? VOS_TRUE : VOS_FALSE; + } + + return( traceOn ); +} + +void vos_snprintf(char *strBuffer, unsigned int size, char *strFormat, ...) +{ + va_list val; + + va_start( val, strFormat ); + snprintf (strBuffer, size, strFormat, val); + va_end( val ); +} + +#ifdef VOS_ENABLE_TRACING + +/*---------------------------------------------------------------------------- + + \brief vos_trace_msg() - Externally called trace function + + Checks the level of severity and accordingly prints the trace messages + + \param module - module identifier. A member of the VOS_MODULE_ID + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param strFormat - format string. The message to be logged. This format + string contains printf-like replacement parameters, which follow + this parameter in the variable argument list. + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +void vos_trace_msg( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, char *strFormat, ... ) +{ + char strBuffer[VOS_TRACE_BUFFER_SIZE]; + int n; + + // Print the trace message when the desired level bit is set in the module + // tracel level mask. + if ( gVosTraceInfo[ module ].moduleTraceLevel & VOS_TRACE_LEVEL_TO_MODULE_BITMASK( level ) ) + { + // the trace level strings in an array. these are ordered in the same order + // as the trace levels are defined in the enum (see VOS_TRACE_LEVEL) so we + // can index into this array with the level and get the right string. The + // vos trace levels are... + // none, Fatal, Error, Warning, Info, InfoHigh, InfoMed, InfoLow, Debug + static const char * TRACE_LEVEL_STR[] = { " ", "F ", "E ", "W ", "I ", "IH", "IM", "IL", "D" }; + va_list val; + va_start(val, strFormat); + + // print the prefix string into the string buffer... + n = snprintf(strBuffer, VOS_TRACE_BUFFER_SIZE, "wlan: [%2s:%3s] ", + (char *) TRACE_LEVEL_STR[ level ], + (char *) gVosTraceInfo[ module ].moduleNameStr ); + + // print the formatted log message after the prefix string. + if ((n >= 0) && (n < VOS_TRACE_BUFFER_SIZE)) + { + vsnprintf(strBuffer + n, VOS_TRACE_BUFFER_SIZE - n, strFormat, val ); + +#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE + wlan_log_to_user(level, (char *)strBuffer, strlen(strBuffer)); +#else + pr_err("%s\n", strBuffer); +#endif + } + va_end(val); + } +} + +void vos_trace_display(void) +{ + VOS_MODULE_ID moduleId; + + pr_err(" 1)FATAL 2)ERROR 3)WARN 4)INFO 5)INFO_H 6)INFO_M 7)INFO_L 8)DEBUG\n"); + for (moduleId = 0; moduleId < VOS_MODULE_ID_MAX; ++moduleId) + { + pr_err("%2d)%s %s %s %s %s %s %s %s %s\n", + (int)moduleId, + gVosTraceInfo[moduleId].moduleNameStr, + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_FATAL)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_ERROR)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_WARN)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_HIGH)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_MED)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_INFO_LOW)) ? "X":" ", + (gVosTraceInfo[moduleId].moduleTraceLevel & (1 << VOS_TRACE_LEVEL_DEBUG)) ? "X":" " + ); + } +} + +/*---------------------------------------------------------------------------- + + \brief vos_trace_hex_dump() - Externally called hex dump function + + Checks the level of severity and accordingly prints the trace messages + + \param module - module identifier. A member of the VOS_MODULE_ID + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the VOS_TRACE_LEVEL + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param data - . The base address of the buffer to be logged. + + \param buf_len - . The size of the buffer to be logged. + + \return nothing + + \sa + --------------------------------------------------------------------------*/ +void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level, + void *data, int buf_len ) +{ + char *buf = (char *)data; + int i; + for (i=0; (i+7) ]. + - Decimal number, i.e. 64 decimal value shows only SME module, + 128 decimal value shows only PE module, 192 decimal value shows PE and SME. + + \param - bitmask_of_moduleId - as explained above set bitmask according to + enum of the modules. + 32 [dec] = 0010 0000 [bin] + 64 [dec] = 0100 0000 [bin] + 128 [dec] = 1000 0000 [bin] + \param - enable - can be true or false. + True implies enabling MTRACE, false implies disabling MTRACE. + ---------------------------------------------------------------------------*/ +void vosTraceEnable(v_U32_t bitmask_of_moduleId, v_U8_t enable) +{ + int i; + if (bitmask_of_moduleId) + { + for (i=0; i> i) & 1 )) + { + if(enable) + { + if (NULL != vostraceRestoreCBTable[i]) + { + vostraceCBTable[i] = vostraceRestoreCBTable[i]; + } + } + else + { + vostraceRestoreCBTable[i] = vostraceCBTable[i]; + vostraceCBTable[i] = NULL; + } + } + } + } + + else + { + if(enable) + { + for (i=0; i MAX_VOS_TRACE_RECORDS) + { + gvosTraceData.num = MAX_VOS_TRACE_RECORDS; + } + + if (INVALID_VOS_TRACE_ADDR == gvosTraceData.head) + { + /* first record */ + gvosTraceData.head = 0; + gvosTraceData.tail = 0; + } + else + { + /* queue is not empty */ + v_U32_t tail = gvosTraceData.tail + 1; + + if (MAX_VOS_TRACE_RECORDS == tail) + { + tail = 0; + } + + if (gvosTraceData.head == tail) + { + /* full */ + if (MAX_VOS_TRACE_RECORDS == ++gvosTraceData.head) + { + gvosTraceData.head = 0; + } + } + + gvosTraceData.tail = tail; + } + + rec = &gvosTraceTbl[gvosTraceData.tail]; + rec->code = code; + rec->session = session; + rec->data = data; + rec->time = vos_timer_get_system_time(); + rec->module = module; + gvosTraceData.numSinceLastDump ++; + spin_unlock_irqrestore(<raceLock, flags); +} + + +/*----------------------------------------------------------------------------- + \brief vos_trace_spin_lock_init() - Initializes the lock variable before use + + This function will be called from vos_preOpen, we will have lock available + to use ASAP. + ----------------------------------------------------------------------------*/ +VOS_STATUS vos_trace_spin_lock_init() +{ + spin_lock_init(<raceLock); + + return VOS_STATUS_SUCCESS; +} + +/*----------------------------------------------------------------------------- + \brief vosTraceRegister() - Registers the call back functions to display the + messages in particular format mentioned in these call back functions. + + this functions should be called by interested module in their init part as + we will be ready to register as soon as modules are up. + + \param moduleID - enum value of module + \param vostraceCb - call back functions to display the messages in particular + format. + ----------------------------------------------------------------------------*/ +void vosTraceRegister(VOS_MODULE_ID moduleID, tpvosTraceCb vostraceCb) +{ + vostraceCBTable[moduleID] = vostraceCb; +} + +/*------------------------------------------------------------------------------ + \brief vosTraceDumpAll() - Dump data from ring buffer via call back functions + registered with VOSS + + This function will be called up on issueing ioctl call as mentioned following + [iwpriv wlan0 dumplog 0 0 ] + + - number lines to dump starting from tail to head. + + - if anybody wants to know how many messages were recorded + for particular module/s mentioned by setbit in bitmask from last messages. + it is optional, if you don't provide then it will dump everything from buffer. + + \param pMac - context of particular module + \param code - + \param session - + \param count - number of lines to dump starting from tail to head + ----------------------------------------------------------------------------*/ +void vosTraceDumpAll(void *pMac, v_U8_t code, v_U8_t session, + v_U32_t count, v_U32_t bitmask_of_module) +{ + tvosTraceRecord pRecord; + tANI_S32 i, tail; + + + if (!gvosTraceData.enable) + { + VOS_TRACE( VOS_MODULE_ID_SYS, + VOS_TRACE_LEVEL_ERROR, "Tracing Disabled"); + return; + } + + VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO, + "Total Records: %d, Head: %d, Tail: %d", + gvosTraceData.num, gvosTraceData.head, gvosTraceData.tail); + + /* Aquire the lock so that only one thread at a time can read the ring buffer */ + spin_lock(<raceLock); + + if (gvosTraceData.head != INVALID_VOS_TRACE_ADDR) + { + i = gvosTraceData.head; + tail = gvosTraceData.tail; + + if (count) + { + if (count > gvosTraceData.num) + { + count = gvosTraceData.num; + } + if (tail >= (count - 1)) + { + i = tail - count + 1; + } + else if (count != MAX_VOS_TRACE_RECORDS) + { + i = MAX_VOS_TRACE_RECORDS - ((count - 1) - tail); + } + } + + pRecord = gvosTraceTbl[i]; + /* right now we are not using numSinceLastDump member but in future + we might re-visit and use this member to track how many latest + messages got added while we were dumping from ring buffer */ + gvosTraceData.numSinceLastDump = 0; + spin_unlock(<raceLock); + for (;;) + { + if ((code == 0 || (code == pRecord.code)) && + (vostraceCBTable[pRecord.module] != NULL)) + { + if (0 == bitmask_of_module) + { + vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i); + } + else + { + if (bitmask_of_module & (1 << pRecord.module)) + { + vostraceCBTable[pRecord.module](pMac, &pRecord, (v_U16_t)i); + } + } + } + + if (i == tail) + { + break; + } + i += 1; + + spin_lock(<raceLock); + if (MAX_VOS_TRACE_RECORDS == i) + { + i = 0; + pRecord= gvosTraceTbl[0]; + } + else + { + pRecord = gvosTraceTbl[i]; + } + spin_unlock(<raceLock); + } + } + else + { + spin_unlock(<raceLock); + } +} + +/** + * vos_register_debug_callback() - stores callback handlers to print + * state information + */ +void vos_register_debug_callback(VOS_MODULE_ID moduleID, + tp_vos_state_info_cb vos_state_infocb) +{ + vos_state_info_table[moduleID] = vos_state_infocb; +} + +/** + * vos_state_info_dump_all() - it invokes callback of layer which registered + * its callback to print its state information. + * @cb_context: call back context to be passed + */ +void vos_state_info_dump_all() +{ + v_U8_t module; + + for (module = 0; module < VOS_MODULE_ID_MAX; module++) { + if (NULL != vos_state_info_table[module]) + vos_state_info_table[module](); + } +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_types.c b/drivers/staging/prima/CORE/VOSS/src/vos_types.c new file mode 100644 index 000000000000..52de3ad8e7f7 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_types.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file vos_Types.c + + \brief virtual Operating System Servies (vOS) + + Basic type definitions + + + ========================================================================*/ + +/* $Header$ */ + +/*-------------------------------------------------------------------------- + Include Files + ------------------------------------------------------------------------*/ +#include "vos_types.h" +#include "vos_trace.h" + +//#include "wlan_libra_config.h" + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + Type declarations + ------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_set - set a variable atomically + + \param pTarget - pointer to the uintptr_t to set. + + \param value - the value to set in the uintptr_t variable. + + \return This function returns the value previously in the uintptr_t before + the new value is set. + + \sa vos_atomic_increment_U32(), vos_atomic_decrement_U32() + + --------------------------------------------------------------------------*/ +uintptr_t vos_atomic_set( uintptr_t *pTarget, uintptr_t value ) +{ + uintptr_t oldval; + unsigned long flags; + + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + oldval = *pTarget; + *pTarget = value; + local_irq_restore(flags); + // v_U32_t prev = atomic_read(pTarget); + // atomic_set(pTarget, value); + return oldval; +} + + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_increment_U32() - Increment a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to increment. + + \return This function returns the value of the variable after the + increment occurs. + + \sa vos_atomic_decrement_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_increment_U32( v_U32_t *pTarget ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + ++*pTarget; + local_irq_restore(flags); + return *pTarget; + // return atomic_inc_return(pTarget); +} + + +/*---------------------------------------------------------------------------- + + \brief vos_atomic_decrement_U32() - Decrement a U32 variable atomically + + \param pTarget - pointer to the v_U32_t to decrement. + + \return This function returns the value of the variable after the + decrement occurs. + + \sa vos_atomic_increment_U32(), vos_atomic_set_U32() + + --------------------------------------------------------------------------*/ +v_U32_t vos_atomic_decrement_U32( v_U32_t *pTarget ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + // return atomic_dec_return(pTarget); + local_irq_save(flags); + --*pTarget; + local_irq_restore(flags); + return (*pTarget); +} + +v_U32_t vos_atomic_increment_U32_by_value( v_U32_t *pTarget, v_U32_t value ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + *pTarget += value ; + local_irq_restore(flags); + return (*pTarget); +} + +v_U32_t vos_atomic_decrement_U32_by_value( v_U32_t *pTarget, v_U32_t value ) +{ + unsigned long flags; + if (pTarget == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "NULL ptr passed into %s",__func__); + return 0; + } + local_irq_save(flags); + *pTarget -= value ; + local_irq_restore(flags); + return (*pTarget); + +} + + +v_U32_t vos_get_skip_ssid_check(void) +{ +/**This is needed by only AMSS for interoperatability **/ + + return 1; +} + + +v_U32_t vos_get_skip_11e_check(void) +{ + /* this is needed only for AMSS for interopratability **/ + return 1; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/vos_utils.c b/drivers/staging/prima/CORE/VOSS/src/vos_utils.c new file mode 100644 index 000000000000..879c376e18c0 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/vos_utils.c @@ -0,0 +1,1576 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*============================================================================ + FILE: vos_utils.c + + OVERVIEW: This source file contains definitions for vOS crypto APIs + The four APIs mentioned in this file are used for + initializing, and de-initializing a crypto context, and + obtaining truly random data (for keys), as well as + SHA1 HMAC, and AES encrypt and decrypt routines. + + The routines include: + vos_crypto_init() - Initializes Crypto module + vos_crypto_deinit() - De-initializes Crypto module + vos_rand_get_bytes() - Generates random byte + vos_sha1_hmac_str() - Generate the HMAC-SHA1 of a string given a key + vos_encrypt_AES() - Generate AES Encrypted byte stream + vos_decrypt_AES() - Decrypts an AES Encrypted byte stream + + DEPENDENCIES: + +============================================================================*/ + +/*============================================================================ + EDIT HISTORY FOR MODULE + +============================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ + +#include "vos_trace.h" +#include "vos_utils.h" +#include "vos_memory.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include "vos_diag_core_event.h" + + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ +extern struct crypto_ahash *wcnss_wlan_crypto_alloc_ahash(const char *alg_name, + unsigned int type, + unsigned int mask); + +extern int wcnss_wlan_crypto_ahash_digest(struct ahash_request *req); +extern void wcnss_wlan_crypto_free_ahash(struct crypto_ahash *tfm); +extern int wcnss_wlan_crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key, + unsigned int keylen); +extern struct crypto_ablkcipher *wcnss_wlan_crypto_alloc_ablkcipher(const char *alg_name, + u32 type, u32 mask); +extern void wcnss_wlan_ablkcipher_request_free(struct ablkcipher_request *req); +extern void wcnss_wlan_crypto_free_ablkcipher(struct crypto_ablkcipher *tfm); + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Function Definitions and Documentation + * -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + + \brief vos_crypto_init() - Initializes Crypto module + + The vos_crypto_init() function initializes Crypto module. + + \param phCryptProv - pointer to the Crypt handle + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ +VOS_STATUS vos_crypto_init( v_U32_t *phCryptProv ) +{ + VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + + // This implementation doesn't require a crypto context + *phCryptProv = 0; + uResult = VOS_STATUS_SUCCESS; + return ( uResult ); +} + +VOS_STATUS vos_crypto_deinit( v_U32_t hCryptProv ) +{ + VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + + // CryptReleaseContext succeeded + uResult = VOS_STATUS_SUCCESS; + + return ( uResult ); +} + +/*-------------------------------------------------------------------------- + + \brief vos_rand_get_bytes() - Generates random byte + + The vos_rand_get_bytes() function generate random bytes. + + Buffer should be allocated before calling vos_rand_get_bytes(). + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ +VOS_STATUS vos_rand_get_bytes( v_U32_t cryptHandle, v_U8_t *pbBuf, v_U32_t numBytes ) +{ + VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + //v_UINT_t uCode; +// HCRYPTPROV hCryptProv = (HCRYPTPROV) cryptHandle; + + //check for invalid pointer + if ( NULL == pbBuf ) + { + uResult = VOS_STATUS_E_FAULT; + return ( uResult ); + } + +//#if 0 + // get_random_bytes() is a void procedure + get_random_bytes( pbBuf, numBytes); + // "Random sequence generated." + uResult = VOS_STATUS_SUCCESS; +//#endif + + return ( uResult ); +} + + +/** + * vos_sha1_hmac_str + * + * FUNCTION: + * Generate the HMAC-SHA1 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant SHA1 HMAC (20B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ + +struct hmac_sha1_result { + struct completion completion; + int err; +}; + +static void hmac_sha1_complete(struct crypto_async_request *req, int err) +{ + struct hmac_sha1_result *r = req->data; + if (err == -EINPROGRESS) + return; + r->err = err; + complete(&r->completion); +} + +int hmac_sha1(v_U8_t *key, v_U8_t ksize, char *plaintext, v_U8_t psize, + v_U8_t *output, v_U8_t outlen) +{ + int ret = 0; + struct crypto_ahash *tfm; + struct scatterlist sg; + struct ahash_request *req; + struct hmac_sha1_result tresult; + void *hash_buff = NULL; + + unsigned char hash_result[64]; + int i; + + memset(output, 0, outlen); + + init_completion(&tresult.completion); + + tfm = wcnss_wlan_crypto_alloc_ahash("hmac(sha1)", CRYPTO_ALG_TYPE_AHASH, + CRYPTO_ALG_TYPE_AHASH_MASK); + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ahash failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to allocate request for hmac(sha1)"); + ret = -ENOMEM; + goto err_req; + } + + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + hmac_sha1_complete, &tresult); + + hash_buff = kzalloc(psize, GFP_KERNEL); + if (!hash_buff) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to kzalloc hash_buff"); + ret = -ENOMEM; + goto err_hash_buf; + } + + memset(hash_result, 0, 64); + vos_mem_copy(hash_buff, plaintext, psize); + sg_init_one(&sg, hash_buff, psize); + + if (ksize) { + crypto_ahash_clear_flags(tfm, ~0); + ret = wcnss_wlan_crypto_ahash_setkey(tfm, key, ksize); + + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_ahash_setkey failed"); + goto err_setkey; + } + } + + ahash_request_set_crypt(req, &sg, hash_result, psize); + ret = wcnss_wlan_crypto_ahash_digest(req); + + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "ret 0x%x", ret); + + switch (ret) { + case 0: + for (i=0; i< outlen; i++) + output[i] = hash_result[i]; + break; + case -EINPROGRESS: + case -EBUSY: + ret = wait_for_completion_interruptible(&tresult.completion); + if (!ret && !tresult.err) { + for (i=0; i< outlen; i++) + output[i] = hash_result[i]; + INIT_COMPLETION(tresult.completion); + break; + } else { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "wait_for_completion_interruptible failed"); + if (!ret) + ret = tresult.err; + goto out; + } + default: + goto out; + } + +out: +err_setkey: + kfree(hash_buff); +err_hash_buf: + ahash_request_free(req); +err_req: + wcnss_wlan_crypto_free_ahash(tfm); +err_tfm: + return ret; +} + +VOS_STATUS vos_sha1_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *pKey, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_SHA1_SIZE])/* caller digest to be filled in */ +{ + int ret = 0; + + ret = hmac_sha1( + pKey, //v_U8_t *key, + (v_U8_t) keyLen, //v_U8_t ksize, + (char *)pText, //char *plaintext, + (v_U8_t) textLen, //v_U8_t psize, + digest, //v_U8_t *output, + VOS_DIGEST_SHA1_SIZE //v_U8_t outlen + ); + + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"hmac_sha1() call failed"); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + +/** + * vos_md5_hmac_str + * + * FUNCTION: + * Generate the HMAC-MD5 of a string given a key. + * + * LOGIC: + * Standard HMAC processing from RFC 2104. The code is provided in the + * appendix of the RFC. + * + * ASSUMPTIONS: + * The RFC is correct. + * + * @param text text to be hashed + * @param textLen length of text + * @param key key to use for HMAC + * @param keyLen length of key + * @param digest holds resultant MD5 HMAC (20B) + * + * @return VOS_STATUS_SUCCSS if the operation succeeds + * + */ +struct hmac_md5_result { + struct completion completion; + int err; +}; + +static void hmac_md5_complete(struct crypto_async_request *req, int err) +{ + struct hmac_md5_result *r = req->data; + if (err == -EINPROGRESS) + return; + r->err = err; + complete(&r->completion); +} + +int hmac_md5(v_U8_t *key, v_U8_t ksize, char *plaintext, v_U8_t psize, + v_U8_t *output, v_U8_t outlen) +{ + int ret = 0; + struct crypto_ahash *tfm; + struct scatterlist sg; + struct ahash_request *req; + struct hmac_md5_result tresult = {.err = 0}; + void *hash_buff = NULL; + + unsigned char hash_result[64]; + int i; + + memset(output, 0, outlen); + + init_completion(&tresult.completion); + + tfm = wcnss_wlan_crypto_alloc_ahash("hmac(md5)", CRYPTO_ALG_TYPE_AHASH, + CRYPTO_ALG_TYPE_AHASH_MASK); + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ahash failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ahash_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to allocate request for hmac(md5)"); + ret = -ENOMEM; + goto err_req; + } + + ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + hmac_md5_complete, &tresult); + + hash_buff = kzalloc(psize, GFP_KERNEL); + if (!hash_buff) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "failed to kzalloc hash_buff"); + ret = -ENOMEM; + goto err_hash_buf; + } + + memset(hash_result, 0, 64); + vos_mem_copy(hash_buff, plaintext, psize); + sg_init_one(&sg, hash_buff, psize); + + if (ksize) { + crypto_ahash_clear_flags(tfm, ~0); + ret = wcnss_wlan_crypto_ahash_setkey(tfm, key, ksize); + + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_ahash_setkey failed"); + goto err_setkey; + } + } + + ahash_request_set_crypt(req, &sg, hash_result, psize); + ret = wcnss_wlan_crypto_ahash_digest(req); + + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "ret 0x%x", ret); + + switch (ret) { + case 0: + for (i=0; i< outlen; i++) + output[i] = hash_result[i]; + break; + case -EINPROGRESS: + case -EBUSY: + ret = wait_for_completion_interruptible(&tresult.completion); + if (!ret && !tresult.err) { + for (i=0; i< outlen; i++) + output[i] = hash_result[i]; + INIT_COMPLETION(tresult.completion); + break; + } else { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "wait_for_completion_interruptible failed"); + if (!ret) + ret = tresult.err; + goto out; + } + default: + goto out; + } + +out: +err_setkey: + kfree(hash_buff); +err_hash_buf: + ahash_request_free(req); +err_req: + wcnss_wlan_crypto_free_ahash(tfm); +err_tfm: + return ret; +} + +VOS_STATUS vos_md5_hmac_str(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U32_t textLen, /* length of data stream */ + v_U8_t *pKey, /* pointer to authentication key */ + v_U32_t keyLen, /* length of authentication key */ + v_U8_t digest[VOS_DIGEST_MD5_SIZE])/* caller digest to be filled in */ +{ + int ret = 0; + + ret = hmac_md5( + pKey, //v_U8_t *key, + (v_U8_t) keyLen, //v_U8_t ksize, + (char *)pText, //char *plaintext, + (v_U8_t) textLen, //v_U8_t psize, + digest, //v_U8_t *output, + VOS_DIGEST_MD5_SIZE //v_U8_t outlen + ); + + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"hmac_md5() call failed"); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + + +struct ecb_aes_result { + struct completion completion; + int err; +}; + +static void ecb_aes_complete(struct crypto_async_request *req, int err) +{ + struct ecb_aes_result *r = req->data; + if (err == -EINPROGRESS) + return; + r->err = err; + complete(&r->completion); +} + + +/*-------------------------------------------------------------------------- + + \brief vos_encrypt_AES() - Generate AES Encrypted byte stream + + The vos_encrypt_AES() function generates the encrypted byte stream for given text. + + Buffer should be allocated before calling vos_rand_get_bytes(). + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ + +#define IV_SIZE_AES_128 16 +#define KEY_SIZE_AES_128 16 +#define AES_BLOCK_SIZE 16 + +VOS_STATUS vos_encrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pPlainText, /* pointer to data stream */ + v_U8_t *pCiphertext, + v_U8_t *pKey) /* pointer to authentication key */ +{ +// VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + struct ecb_aes_result result; + struct ablkcipher_request *req; + struct crypto_ablkcipher *tfm; + int ret = 0; + char iv[IV_SIZE_AES_128]; + struct scatterlist sg_in; + struct scatterlist sg_out; + + init_completion(&result.completion); + + tfm = wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ablkcipher failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ablkcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)"); + ret = -ENOMEM; + goto err_req; + } + + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + ecb_aes_complete, &result); + + + crypto_ablkcipher_clear_flags(tfm, ~0); + + ret = crypto_ablkcipher_setkey(tfm, pKey, KEY_SIZE_AES_128); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed"); + goto err_setkey; + } + + memset(iv, 0, IV_SIZE_AES_128); + + sg_init_one(&sg_in, pPlainText, AES_BLOCK_SIZE); + + sg_init_one(&sg_out, pCiphertext, AES_BLOCK_SIZE); + + ablkcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv); + + crypto_ablkcipher_encrypt(req); + + + +// ------------------------------------- +err_setkey: + wcnss_wlan_ablkcipher_request_free(req); +err_req: + wcnss_wlan_crypto_free_ablkcipher(tfm); +err_tfm: + //return ret; + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + +/*-------------------------------------------------------------------------- + + \brief vos_decrypt_AES() - Decrypts an AES Encrypted byte stream + + The vos_decrypt_AES() function decrypts the encrypted byte stream. + + Buffer should be allocated before calling vos_rand_get_bytes(). + + Attempting to initialize an already initialized lock results in + a failure. + + \param lock - pointer to the opaque lock object to initialize + + \return VOS_STATUS_SUCCESS - Successfully generated random memory. + + VOS_STATUS_E_FAULT - pbBuf is an invalid pointer. + + VOS_STATUS_E_FAILURE - default return value if it fails due to + unknown reasons + + ***VOS_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable + \sa + + ( *** return value not considered yet ) + --------------------------------------------------------------------------*/ + +VOS_STATUS vos_decrypt_AES(v_U32_t cryptHandle, /* Handle */ + v_U8_t *pText, /* pointer to data stream */ + v_U8_t *pDecrypted, + v_U8_t *pKey) /* pointer to authentication key */ +{ +// VOS_STATUS uResult = VOS_STATUS_E_FAILURE; + struct ecb_aes_result result; + struct ablkcipher_request *req; + struct crypto_ablkcipher *tfm; + int ret = 0; + char iv[IV_SIZE_AES_128]; + struct scatterlist sg_in; + struct scatterlist sg_out; + + init_completion(&result.completion); + + tfm = wcnss_wlan_crypto_alloc_ablkcipher( "cbc(aes)", 0, 0); + if (IS_ERR(tfm)) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_alloc_ablkcipher failed"); + ret = PTR_ERR(tfm); + goto err_tfm; + } + + req = ablkcipher_request_alloc(tfm, GFP_KERNEL); + if (!req) { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Failed to allocate request for cbc(aes)"); + ret = -ENOMEM; + goto err_req; + } + + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + ecb_aes_complete, &result); + + + crypto_ablkcipher_clear_flags(tfm, ~0); + + ret = crypto_ablkcipher_setkey(tfm, pKey, KEY_SIZE_AES_128); + if (ret) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR, "crypto_cipher_setkey failed"); + goto err_setkey; + } + + memset(iv, 0, IV_SIZE_AES_128); + + sg_init_one(&sg_in, pText, AES_BLOCK_SIZE); + + sg_init_one(&sg_out, pDecrypted, AES_BLOCK_SIZE); + + ablkcipher_request_set_crypt(req, &sg_in, &sg_out, AES_BLOCK_SIZE, iv); + + crypto_ablkcipher_decrypt(req); + + + +// ------------------------------------- +err_setkey: + wcnss_wlan_ablkcipher_request_free(req); +err_req: + wcnss_wlan_crypto_free_ablkcipher(tfm); +err_tfm: + //return ret; + if (ret != 0) { + VOS_TRACE(VOS_MODULE_ID_VOSS,VOS_TRACE_LEVEL_ERROR,"%s() call failed", __func__); + return VOS_STATUS_E_FAULT; + } + + return VOS_STATUS_SUCCESS; +} + +v_U8_t vos_chan_to_band(v_U32_t chan) +{ + if (chan <= VOS_24_GHZ_CHANNEL_14) + return VOS_BAND_2GHZ; + + return VOS_BAND_5GHZ; +} + +void vos_get_wlan_unsafe_channel(v_U16_t *unsafeChannelList, + v_U16_t buffer_size, v_U16_t *unsafeChannelCount) +{ + /* Get unsafe channel list from cached location */ + wcnss_get_wlan_unsafe_channel(unsafeChannelList, buffer_size, + unsafeChannelCount); +} + + +#include +#include "vos_timer.h" +#include "i_vos_packet.h" + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define DXE_DATA_MAGIC_NO 0x010 +#define DXE_MGMT_MAGIC_NO 0x011 + +//Define gRoamDelayMetaInfo +tRoamDelayMetaInfo gRoamDelayMetaInfo = {0}; +tRoamDelayMetaInfo *gpRoamDelayTable = NULL; +v_BOOL_t gRoamDelayCurrentIndex = 0; + +#define VOS_ETHERTYPE_802_1_X ( 0x888E ) +#define VOS_ETHERTYPE_802_1_X_SIZE ( 2 ) +//802.3 frame header have SRC MAC (6), DST(6),next will PROTOCOL type +#define VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_3_PKT ( 12 ) + +//802.11 header wil have 26 byte (Inculding QoS Info) +//8Byte LLC / SNAP header in which last two byte will be PROTOCOL type +//So offset will 32 if it is QoS data pkt else it will be 30 +#define VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_11_PKT ( 32 ) +#define VOS_QOS_DATA_VALUE ( 0x88 ) +#define VOS_NON_QOS_DATA_VALUE ( 0x80 ) + +//802.11 header wil have 24 byte excluding qos +#define VOS_802_11_HEADER_SIZE ( 24 ) +#define VOS_QOS_SIZE ( 2 ) +#define VOS_LLC_HEADER_SIZE (8) +#define VOS_IP_HEADER_SIZE (20) +#define VOS_TCP_MIN_HEADER_SIZE (20) +#define VOS_DEF_PKT_STATS_LEN_TO_COPY \ + (VOS_802_11_HEADER_SIZE + VOS_LLC_HEADER_SIZE \ + + VOS_IP_HEADER_SIZE + VOS_TCP_MIN_HEADER_SIZE) +// DHCP Port number +#define VOS_DHCP_SOURCE_PORT 0x4400 +#define VOS_DHCP_DESTINATION_PORT 0x4300 + + + +// Frame Type definitions +#define VOS_MAC_MGMT_FRAME 0x0 +#define VOS_MAC_CTRL_FRAME 0x1 +#define VOS_MAC_DATA_FRAME 0x2 + +#define MONITOR_STOP 0x0 +#define MONITOR_START 0x1 +#define MONITOR_EAPOL_DONE 0x2 +#define MONITOR_FIRST_DATA_DONE 0x4 + +v_BOOL_t vos_skb_is_eapol(struct sk_buff *skb, + v_SIZE_t pktOffset, + v_SIZE_t numBytes) +{ + void *pBuffer = NULL; + v_BOOL_t fEAPOL = VOS_FALSE; + + // Validate the skb + if (unlikely(NULL == skb)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "vos_skb_is_eapol [%d]: NULL skb", __LINE__); + return VOS_FALSE; + } + // check for overflow + if (unlikely((pktOffset + numBytes) > skb->len)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "vos_skb_is_eapol [%d]: Packet overflow, offset %d size %d len %d", + __LINE__, pktOffset, numBytes, skb->len); + return VOS_FALSE; + } + //check for the Qos Data, if Offset length is more 12. + //it means it will 802.11 header skb + if((pktOffset > VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_3_PKT) + && (skb->data[0] == VOS_NON_QOS_DATA_VALUE)) + { + // reduced 2 byte of Qos ctrl field in DOT11 header + pktOffset = pktOffset - 2; + } + pBuffer = &skb->data[pktOffset]; + if (pBuffer && vos_be16_to_cpu( *(unsigned short*)pBuffer ) == VOS_ETHERTYPE_802_1_X ) + { + fEAPOL = VOS_TRUE; + } + return fEAPOL; +} + +v_BOOL_t vos_roam_delay_stats_init(void) +{ + if (gpRoamDelayTable == NULL) + { + gpRoamDelayTable = vmalloc(sizeof(tRoamDelayMetaInfo) * ROAM_DELAY_TABLE_SIZE); + if (gpRoamDelayTable == NULL) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, "Memory allocation failed"); + return VOS_FALSE; + } + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "Memory is already allocated"); + return VOS_FALSE; + } + + return VOS_TRUE; +} + + +v_BOOL_t vos_roam_delay_stats_deinit(void) +{ + if (gpRoamDelayTable != NULL) + { + vfree(gpRoamDelayTable); + gpRoamDelayTable = NULL; + } + else + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO, "Memory is already freed"); + return VOS_FALSE; + } + + return VOS_TRUE; +} + +void vos_record_roam_event(enum e_roaming_event roam_event, void *pBuff, v_ULONG_t buff_len) +{ + if (gpRoamDelayTable == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam delay table is not initialized\n"); + return; + } + switch(roam_event) + { + case e_HDD_DISABLE_TX_QUEUE: + gRoamDelayMetaInfo.hdd_monitor_tx = MONITOR_STOP; + gRoamDelayMetaInfo.disable_tx_queues_time = vos_timer_get_system_time(); + break; + case e_SME_PREAUTH_REASSOC_START: + gRoamDelayMetaInfo.preauth_reassoc_start_time = vos_timer_get_system_time(); + break; + case e_SME_PREAUTH_CALLBACK_HIT: + gRoamDelayMetaInfo.preauth_cb_time = vos_timer_get_system_time(); + break; + case e_SME_ISSUE_REASSOC_REQ: + gRoamDelayMetaInfo.issue_reassoc_req_time = vos_timer_get_system_time(); + //HACK buff len will carry the AuthType + gRoamDelayMetaInfo.hdd_auth_type = buff_len; + break; + case e_LIM_SEND_REASSOC_REQ: + gRoamDelayMetaInfo.send_reassoc_req_time = vos_timer_get_system_time(); + //we can enable the rx eapol monitoring ASAP we send the REASSOC REQ Because + //there is very less delay in between REASSOC RSP and M1 Sent by the AP + gRoamDelayMetaInfo.hdd_monitor_rx = MONITOR_START; + gRoamDelayMetaInfo.dxe_monitor_rx = MONITOR_START; + break; + case e_CACHE_ROAM_PEER_MAC: + vos_mem_copy(&gRoamDelayMetaInfo.peer_mac_addr, pBuff, buff_len); + break; + case e_HDD_SEND_REASSOC_RSP: + gRoamDelayMetaInfo.hdd_sendassoc_rsp_time = vos_timer_get_system_time(); + break; + case e_SME_DISASSOC_ISSUE: + gRoamDelayMetaInfo.disassoc_issue_time = vos_timer_get_system_time(); + break; + case e_SME_DISASSOC_COMPLETE: + gRoamDelayMetaInfo.disassoc_comp_time = vos_timer_get_system_time(); + break; + case e_LIM_ADD_BS_REQ: + gRoamDelayMetaInfo.lim_add_bss_req_time = vos_timer_get_system_time(); + break; + case e_LIM_ADD_BS_RSP: + gRoamDelayMetaInfo.lim_add_bss_rsp_time = vos_timer_get_system_time(); + break; + case e_HDD_ENABLE_TX_QUEUE: + gRoamDelayMetaInfo.hdd_monitor_tx = MONITOR_START; + gRoamDelayMetaInfo.enable_tx_queues_reassoc_time = vos_timer_get_system_time(); + break; + case e_HDD_SET_PTK_REQ: + gRoamDelayMetaInfo.set_ptk_roam_key_time = vos_timer_get_system_time(); + break; + case e_HDD_SET_GTK_REQ: + gRoamDelayMetaInfo.set_gtk_roam_key_time = vos_timer_get_system_time(); + break; + case e_HDD_SET_PTK_RSP: + gRoamDelayMetaInfo.complete_ptk_roam_key_time = vos_timer_get_system_time(); + //vos_mem_copy(&gRoamDelayMetaInfo.peer_mac_addr, pBuff, buff_len); + break; + case e_HDD_SET_GTK_RSP: + gRoamDelayMetaInfo.complete_gtk_roam_key_time = vos_timer_get_system_time(); + break; + case e_TL_FIRST_XMIT_TIME: + if(gRoamDelayMetaInfo.log_tl) + { + gRoamDelayMetaInfo.tl_fetch_pkt_time = vos_timer_get_system_time(); + gRoamDelayMetaInfo.log_tl = VOS_FALSE; + } + break; + case e_HDD_FIRST_XMIT_TIME: + if(gRoamDelayMetaInfo.hdd_monitor_tx != MONITOR_STOP) + { + struct sk_buff *skb = (struct sk_buff *)pBuff; + if(!skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "event e_HDD_FIRST_XMIT_TIME skb is null"); + return; + } + if((gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_RSN_PSK) || + (gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_WPA_PSK)) + { + //Hdd xmit will have only 802.3 pkt so offset will pass as accordingly + if(vos_skb_is_eapol(skb, VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_3_PKT, + VOS_ETHERTYPE_802_1_X_SIZE) == VOS_TRUE) + { + if(gRoamDelayMetaInfo.hdd_eapol_m2 == 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"HDD XMIT m2"); + gRoamDelayMetaInfo.hdd_eapol_m2 = vos_timer_get_system_time(); + gRoamDelayMetaInfo.dxe_monitor_tx = MONITOR_START; + } + else if((gRoamDelayMetaInfo.hdd_eapol_m2) && (gRoamDelayMetaInfo.hdd_eapol_m4 == 0)) + { + gRoamDelayMetaInfo.hdd_eapol_m4 = vos_timer_get_system_time(); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"HDD XMIT m4"); + gRoamDelayMetaInfo.hdd_monitor_tx = MONITOR_EAPOL_DONE; + //We should return from here so can cache the time for first data pkt + return; + } + } + } + else + { + gRoamDelayMetaInfo.hdd_monitor_tx = MONITOR_EAPOL_DONE; + gRoamDelayMetaInfo.dxe_monitor_tx = MONITOR_START; + } + //Eapol is done it must be first data frame capture it + if(gRoamDelayMetaInfo.hdd_monitor_tx == MONITOR_EAPOL_DONE) + { + gRoamDelayMetaInfo.hdd_first_pkt_len = 50; + gRoamDelayMetaInfo.hdd_first_xmit_time = vos_timer_get_system_time(); + gRoamDelayMetaInfo.log_tl = VOS_TRUE; + gRoamDelayMetaInfo.hdd_monitor_tx = MONITOR_STOP; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "HDD %s XMIT first data frame after roaming", __func__); + if(skb->len < gRoamDelayMetaInfo.hdd_first_pkt_len) + gRoamDelayMetaInfo.hdd_first_pkt_len = skb->len; + vos_mem_copy(&gRoamDelayMetaInfo.hdd_first_pkt_data, + skb->data,gRoamDelayMetaInfo.hdd_first_pkt_len); + } + } + break; + case e_HDD_RX_PKT_CBK_TIME: + if(gRoamDelayMetaInfo.hdd_monitor_rx != MONITOR_STOP) + { + struct sk_buff *skb = (struct sk_buff *)pBuff; + if(!skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "event e_HDD_RX_PKT_CBK_TIME skb is null"); + return; + } + if((gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_RSN_PSK) || + (gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_WPA_PSK)) + { + if(vos_skb_is_eapol(skb, VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_3_PKT, + VOS_ETHERTYPE_802_1_X_SIZE) == VOS_TRUE) + { + if(gRoamDelayMetaInfo.hdd_eapol_m1 == 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"HDD recv m1"); + gRoamDelayMetaInfo.hdd_eapol_m1 = vos_timer_get_system_time(); + } + else if((gRoamDelayMetaInfo.hdd_eapol_m1) && (gRoamDelayMetaInfo.hdd_eapol_m3 == 0)) + { + gRoamDelayMetaInfo.hdd_eapol_m3 = vos_timer_get_system_time(); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"HDD recv m3"); + gRoamDelayMetaInfo.hdd_monitor_rx = MONITOR_EAPOL_DONE; + } + } + } + else + { + gRoamDelayMetaInfo.hdd_monitor_rx = MONITOR_EAPOL_DONE; + } + if(gRoamDelayMetaInfo.hdd_monitor_rx == MONITOR_EAPOL_DONE) + { + gRoamDelayMetaInfo.hdd_monitor_rx = MONITOR_STOP; + } + } + break; + case e_DXE_RX_PKT_TIME: + if(gRoamDelayMetaInfo.dxe_monitor_rx != MONITOR_STOP) + { + vos_pkt_t *vos_pkt = NULL; + struct sk_buff *skb = NULL; + vos_pkt = (vos_pkt_t *)pBuff; + if(!vos_pkt) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "event e_DXE_RX_PKT_TIME vos_pkt is null"); + return; + } + skb = vos_pkt->pSkb; + if(!skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "event e_DXE_RX_PKT_TIME skb is null"); + return; + } + //DXE can RECV MGMT and DATA frame, we are interetsed in only DATA frame + if(buff_len & VOS_MAC_DATA_FRAME) + { + if((gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_RSN_PSK) || + (gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_WPA_PSK)) + { + if(vos_skb_is_eapol(skb, VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_11_PKT, + VOS_ETHERTYPE_802_1_X_SIZE) == VOS_TRUE) + { + if(gRoamDelayMetaInfo.dxe_eapol_m1 == 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"DXE recv m1"); + gRoamDelayMetaInfo.dxe_eapol_m1 = vos_timer_get_system_time(); + } + else if((gRoamDelayMetaInfo.dxe_eapol_m1) && (gRoamDelayMetaInfo.dxe_eapol_m3 == 0)) + { + gRoamDelayMetaInfo.dxe_eapol_m3 = vos_timer_get_system_time(); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"DXE recv m3"); + gRoamDelayMetaInfo.dxe_monitor_rx = MONITOR_EAPOL_DONE; + } + } + } + else + { + gRoamDelayMetaInfo.dxe_monitor_rx = MONITOR_EAPOL_DONE; + } + if(gRoamDelayMetaInfo.dxe_monitor_rx == MONITOR_EAPOL_DONE) + { + gRoamDelayMetaInfo.dxe_monitor_rx = MONITOR_STOP; + } + } + /* + else + { + printk("e_DXE_RX_PKT_TIME dump mgmt frames"); + vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, &skb->data[0], skb->len); + } + */ + } + break; + case e_DXE_FIRST_XMIT_TIME: + if(gRoamDelayMetaInfo.dxe_monitor_tx != MONITOR_STOP) + { + vos_pkt_t *vos_pkt = NULL; + struct sk_buff *skb = NULL; + vos_pkt = (vos_pkt_t *)pBuff; + if(!vos_pkt) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "event e_DXE_FIRST_XMIT_TIME vos_pkt is null"); + return; + } + skb = vos_pkt->pSkb; + if(!skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "event e_DXE_FIRST_XMIT_TIME skb is null"); + return; + } + //DXE can Txmit MGMT and DATA frame, we are interetsed in only DATA frame + if(buff_len & VOS_MAC_DATA_FRAME) + { + if((gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_RSN_PSK) || + (gRoamDelayMetaInfo.hdd_auth_type == eVOS_AUTH_TYPE_WPA_PSK)) + { + if(vos_skb_is_eapol(skb, VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_11_PKT, + VOS_ETHERTYPE_802_1_X_SIZE) == VOS_TRUE) + { + if(gRoamDelayMetaInfo.dxe_eapol_m2 == 0) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"DXE XMIT m2"); + gRoamDelayMetaInfo.dxe_eapol_m2 = vos_timer_get_system_time(); + } + else if((gRoamDelayMetaInfo.dxe_eapol_m2) && (gRoamDelayMetaInfo.dxe_eapol_m4 == 0)) + { + gRoamDelayMetaInfo.dxe_eapol_m4 = vos_timer_get_system_time(); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"DXE XMIT m4"); + gRoamDelayMetaInfo.dxe_monitor_tx = MONITOR_EAPOL_DONE; + //We should return from here so can cache the time for first data pkt + return; + } + } + } + else + { + gRoamDelayMetaInfo.dxe_monitor_tx = MONITOR_EAPOL_DONE; + } + //HACK buff len is getting used as FRAME TYPE + if(gRoamDelayMetaInfo.dxe_monitor_tx == MONITOR_EAPOL_DONE) + { + gRoamDelayMetaInfo.dxe_first_tx_time = vos_timer_get_system_time(); + gRoamDelayMetaInfo.dxe_monitor_tx = MONITOR_STOP; + gRoamDelayMetaInfo.dxe_first_pkt_len = 75; + if(skb->len < gRoamDelayMetaInfo.dxe_first_pkt_len) + gRoamDelayMetaInfo.dxe_first_pkt_len = skb->len; + vos_mem_copy(&gRoamDelayMetaInfo.dxe_first_pkt_data, skb->data, + gRoamDelayMetaInfo.dxe_first_pkt_len); + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "DXE %s XMIT first data frame after roaming", __func__); + } + } + } + break; + case e_SME_VO_ADDTS_REQ: + gRoamDelayMetaInfo.hdd_addts_vo_req_time = vos_timer_get_system_time(); + break; + case e_SME_VO_ADDTS_RSP: + gRoamDelayMetaInfo.hdd_addts_vo_rsp_time = vos_timer_get_system_time(); + break; + case e_SME_VI_ADDTS_REQ: + gRoamDelayMetaInfo.hdd_addts_vi_req_time = vos_timer_get_system_time(); + break; + case e_SME_VI_ADDTS_RSP: + gRoamDelayMetaInfo.hdd_addts_vi_rsp_time = vos_timer_get_system_time(); + break; + case e_CACHE_ROAM_DELAY_DATA: + //Let us copy roam meta info + if(gRoamDelayCurrentIndex > ROAM_DELAY_TABLE_SIZE) + gRoamDelayCurrentIndex = 0; + vos_mem_copy(&gpRoamDelayTable[gRoamDelayCurrentIndex++], + &gRoamDelayMetaInfo, sizeof(gRoamDelayMetaInfo)); + vos_mem_set(&gRoamDelayMetaInfo, sizeof(gRoamDelayMetaInfo), 0); + break; + default: + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, + "%s Invalid roam_event = %d received ", __func__, roam_event); + break; + } +} + +void vos_reset_roam_timer_log(void) +{ + if (gpRoamDelayTable != NULL) + { + //Set zero to whole gpRoamDelayTable + vos_mem_set(gpRoamDelayTable, (sizeof(tRoamDelayMetaInfo) * ROAM_DELAY_TABLE_SIZE), 0); + } +} + +void vos_dump_roam_time_log_service(void) +{ + v_SLONG_t slA, slB, slC, slD, slE, slF, slG, slH, slI, slJ, slK, slL, slM, slRoamDelay; + tRoamDelayMetaInfo currentRoamDelayInfo; + v_ULONG_t index = 0,i=0; + + if (gpRoamDelayTable == NULL) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "Roam delay table is not initialized\n"); + return; + } + //Let us first copy the current gRoamDelayMetaInfo into gpRoamDelayTable + if(gRoamDelayCurrentIndex > ROAM_DELAY_TABLE_SIZE) + gRoamDelayCurrentIndex = 0; + vos_mem_copy(&gpRoamDelayTable[gRoamDelayCurrentIndex++], &gRoamDelayMetaInfo, sizeof(gRoamDelayMetaInfo)); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "** RoamDelay = ( dxe_first_tx_time - disable_tx_queues_time)\n"); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||========================" + "===============|====== A ======|====== B ======|====== C ======|" + "====== D ======|====== E ======|====== F ======|====== G ======|" + "====== H ======|====== I ======|====== J ======|====== K ======|" + "====== L ======|====== M ======||\n"); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||Sl | Peer MAC address |" + " **RoamDelay** | PreAuth Timer | Disassoc Issue| Add BSS Req |" + " AddBssRsp to | ReassocReq to | ReassocRsp to | Disable to |" + " M1-M2 DXE SW | M1-M2 HDD SW | M3-M4 DXE SW | M3-M4 HDD SW |" + " ReassocRsp to | HDD to DXE ||\n"); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||No.| |" + " ************* | to Roam Start | to Complete | to Rsp time |" + " Reassoc Req | ReassocRsp | Enable Tx Que | Enable Tx Que |" + " | | | |" + " Set GTK | 1st data frame||\n"); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||========================" + "================================================================" + "================================================================" + "================================================================" + "===============================||\n"); + + for (index = 0; index < gRoamDelayCurrentIndex; index++) + { + currentRoamDelayInfo = gpRoamDelayTable[index]; + /* PreAuth Timer to Roam Start */ + slA = (currentRoamDelayInfo.preauth_cb_time - + currentRoamDelayInfo.preauth_reassoc_start_time); + + /* Disassoc Issue to Complete */ + slB = (currentRoamDelayInfo.disassoc_comp_time - + currentRoamDelayInfo.disassoc_issue_time); + + /* Add BSS Req to Rsp time */ + slC = (currentRoamDelayInfo.lim_add_bss_rsp_time - + currentRoamDelayInfo.lim_add_bss_req_time); + + /* AddBssRsp to Reassoc Req */ + slD = (currentRoamDelayInfo.send_reassoc_req_time - + currentRoamDelayInfo.lim_add_bss_rsp_time); + + /* ReassocReq to ReassocRsp */ + slE = (currentRoamDelayInfo.hdd_sendassoc_rsp_time - + currentRoamDelayInfo.send_reassoc_req_time); + + /* ReassocRsp to Enable Tx Que */ + slF = (currentRoamDelayInfo.enable_tx_queues_reassoc_time - + currentRoamDelayInfo.hdd_sendassoc_rsp_time); + + /* Disable to Enable Tx Que */ + slG = (currentRoamDelayInfo.enable_tx_queues_reassoc_time - + currentRoamDelayInfo.disable_tx_queues_time); + + /* M1-M2 DXE SW */ + slH = (currentRoamDelayInfo.dxe_eapol_m2 - + currentRoamDelayInfo.dxe_eapol_m1); + + /* M1-M2 HDD SW */ + slI = (currentRoamDelayInfo.hdd_eapol_m2 - + currentRoamDelayInfo.hdd_eapol_m1); + + /* M3-M4 DXE SW */ + slJ = (currentRoamDelayInfo.dxe_eapol_m4 - + currentRoamDelayInfo.dxe_eapol_m3); + + /* M3-M4 HDD SW */ + slK = (currentRoamDelayInfo.hdd_eapol_m4 - + currentRoamDelayInfo.hdd_eapol_m3); + + /* ReassocRsp to Set GTK */ + slL = (currentRoamDelayInfo.set_gtk_roam_key_time - + currentRoamDelayInfo.hdd_sendassoc_rsp_time); + + /* HDD to DXE 1st data frame */ + slM = (currentRoamDelayInfo.dxe_first_tx_time - + currentRoamDelayInfo.hdd_first_xmit_time); + + /* Calculate roam delay */ + slRoamDelay = (currentRoamDelayInfo.dxe_first_tx_time - + currentRoamDelayInfo.disable_tx_queues_time); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||%2ld:|<"MAC_ADDRESS_STR">|" + "%14ld |%14ld |%14ld |%14ld |" + "%14ld |%14ld |%14ld |%14ld |" + "%14ld |%14ld |%14ld |%14ld |" + "%14ld |%14ld ||\n", + (index+1), MAC_ADDR_ARRAY(currentRoamDelayInfo.peer_mac_addr), + slRoamDelay, slA, slB, slC, + slD, slE, slF, slG, + slH, slI, slJ, slK, + slL, slM ); + } + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||========================" + "================================================================" + "================================================================" + "================================================================" + "===============================||\n"); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||== More Details =====================" + "===============================||\n"); + + for (index = 0; index < gRoamDelayCurrentIndex; index++) + { + + currentRoamDelayInfo = gpRoamDelayTable[index]; + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||%2ld: Peer Mac: <"MAC_ADDRESS_STR">\n", + (index+1), MAC_ADDR_ARRAY(currentRoamDelayInfo.peer_mac_addr) + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||preauth_reassoc_start_time : %14ld\n", + currentRoamDelayInfo.preauth_reassoc_start_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||preauth_cb_time : %14ld\n", + currentRoamDelayInfo.preauth_cb_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||disable_tx_queues_time : %14ld\n", + currentRoamDelayInfo.disable_tx_queues_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||disassoc_issue_time : %14ld\n", + currentRoamDelayInfo.disassoc_issue_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||lim_add_bss_req_time : %14ld\n", + currentRoamDelayInfo.lim_add_bss_req_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||lim_add_bss_rsp_time : %14ld\n", + currentRoamDelayInfo.lim_add_bss_rsp_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||disassoc_comp_time : %14ld\n", + currentRoamDelayInfo.disassoc_comp_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||send_reassoc_req_time : %14ld\n", + currentRoamDelayInfo.send_reassoc_req_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_sendassoc_rsp_time : %14ld\n", + currentRoamDelayInfo.hdd_sendassoc_rsp_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||enable_tx_queues_time : %14ld\n", + currentRoamDelayInfo.enable_tx_queues_reassoc_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_eapol_m1 : %14ld\n", + currentRoamDelayInfo.hdd_eapol_m1 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_eapol_m2 : %14ld\n", + currentRoamDelayInfo.hdd_eapol_m2 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_eapol_m3 : %14ld\n", + currentRoamDelayInfo.hdd_eapol_m3 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_eapol_m4 : %14ld\n", + currentRoamDelayInfo.hdd_eapol_m4 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||dxe_eapol_m1 : %14ld\n", + currentRoamDelayInfo.dxe_eapol_m1 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||dxe_eapol_m2 : %14ld\n", + currentRoamDelayInfo.dxe_eapol_m2 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||dxe_eapol_m3 : %14ld\n", + currentRoamDelayInfo.dxe_eapol_m3 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||dxe_eapol_m4 : %14ld\n", + currentRoamDelayInfo.dxe_eapol_m4 + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||set_ptk_roam_key_time : %14ld\n", + currentRoamDelayInfo.set_ptk_roam_key_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||set_gtk_roam_key_time : %14ld\n", + currentRoamDelayInfo.set_gtk_roam_key_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||tl_fetch_pkt_time : %14ld\n", + currentRoamDelayInfo.tl_fetch_pkt_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_first_xmit_time : %14ld\n", + currentRoamDelayInfo.hdd_first_xmit_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||dxe_first_tx_time : %14ld\n", + currentRoamDelayInfo.dxe_first_tx_time + ); + + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "||hdd_first_pkt_data : \n" + ); + + + for (i=0; ipSkb; + if(!skb) + { + VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + " skb is null"); + return 0; + } + if (VOS_MAC_MGMT_FRAME == frametype) + { + length_to_copy = skb->len; + } + else + { + length_to_copy = VOS_DEF_PKT_STATS_LEN_TO_COPY; + if(skb->data[0] == VOS_QOS_DATA_VALUE) + length_to_copy += VOS_QOS_SIZE; + + /* Copy whole skb data if DHCP or EAPOL pkt.Here length_to_copy + * will give the pointer to IP header and adding VOS_IP_HEADER_SIZE + * to it will give the DHCP port number. + */ + if (((skb->len > (length_to_copy + VOS_IP_HEADER_SIZE)) && + ((*((u16*)((u8*)skb->data + length_to_copy + VOS_IP_HEADER_SIZE)) + == VOS_DHCP_SOURCE_PORT) || + (*((u16*)((u8*)skb->data + length_to_copy + VOS_IP_HEADER_SIZE)) + == VOS_DHCP_DESTINATION_PORT))) || + vos_skb_is_eapol(skb, + VOS_ETHERTYPE_802_1_X_FRAME_OFFSET_IN_802_11_PKT, + VOS_ETHERTYPE_802_1_X_SIZE)) + { + length_to_copy = skb->len; + } + } + + if (length_to_copy > skb->len) + { + length_to_copy = skb->len; + } + if (length_to_copy > MAX_PKT_STAT_DATA_LEN) + { + length_to_copy = MAX_PKT_STAT_DATA_LEN; + } + + vos_mem_copy(dst, skb->data, length_to_copy); + return length_to_copy; +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/** + * vos_tdls_tx_rx_mgmt_event()- send tdls mgmt rx tx event + * + * @event_id: event id + * @tx_rx: tx or rx + * @type: type of frame + * @action_sub_type: action frame type + * @peer_mac: peer mac + * + * This Function sendsend tdls mgmt rx tx diag event + * + * Return: void. + */ +void vos_tdls_tx_rx_mgmt_event(uint8_t event_id, uint8_t tx_rx, + uint8_t type, uint8_t action_sub_type, uint8_t *peer_mac) +{ + WLAN_VOS_DIAG_EVENT_DEF(tdls_tx_rx_mgmt, + struct vos_event_tx_rx_mgmt); + vos_mem_zero(&tdls_tx_rx_mgmt, sizeof(tdls_tx_rx_mgmt)); + + tdls_tx_rx_mgmt.event_id = event_id; + tdls_tx_rx_mgmt.tx_rx = tx_rx; + tdls_tx_rx_mgmt.type = type; + tdls_tx_rx_mgmt.action_sub_type = action_sub_type; + vos_mem_copy(tdls_tx_rx_mgmt.peer_mac, + peer_mac, VOS_MAC_ADDR_SIZE); + WLAN_VOS_DIAG_EVENT_REPORT(&tdls_tx_rx_mgmt, + EVENT_WLAN_TX_RX_MGMT); +} +#endif diff --git a/drivers/staging/prima/CORE/VOSS/src/wlan_nv_parser.c b/drivers/staging/prima/CORE/VOSS/src/wlan_nv_parser.c new file mode 100644 index 000000000000..7317c361a555 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/wlan_nv_parser.c @@ -0,0 +1,2147 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + when who what, where, why + -------- --- ----------------------------------------------------- + 04/10/13 kumarpra nv parser creation +===========================================================================*/ + +#include +#include "wlan_nv.h" + +/* + * NV stream layer service + */ +#include "wlan_nv_stream.h" +#include "wlan_nv_template_internal.h" +#include "wlan_nv_parser_internal.h" +#include "wlan_nv_template_api.h" +#include "wlan_nv_template_builtin.h" + +extern void vos_mem_copy( void *pDst, const void *pSrc, unsigned int numBytes ); + +#define _RECURSIVE_DATA_TABLE_PARSING +// Recursive/iterative switch !! Default iterative +#define _RECURSIVE_VERSION + +/* + * Build process should have created the built-in templates in + * "wlan_nv_templateBuiltIn.c" + * Include its auto-generated companion header file + * "wlan_nv_templateBuiltIn.h" + * + * The main definitions are + * _NV_TEMPLATE_TABLE NvTablesBuiltIn[]; + * + */ + +/* + * Parsing control bitmap + */ +tANI_U32 gNVParsingControlLo; +static int subTableSize; +static int fieldSize; +static sHalNv *gpnvData_t; +/* store enum comparison results*/ +static _ENUM_META_DATA enumMetaDataFromBin[INDEX_ENUM_MAX]; + + +/* + * This data copy logic ignores the enum or int data types, + * but simply copy the whole chunk to the NV data structure + */ +typedef struct { + int idxSubFromBin; + int idxSubBuiltin; +} _SUBTABLES_QUEUE; + +pF_NumElemBasedOnStorageType numElemBasedOnStorageType[] = { + numElemSingular, // SINGULAR=0 + numElemArray1, // ARRAY_1=1 + numElemArray2, // ARRAY_2=2 + numElemArray3, // ARRAY_3=3 +}; + +static int sizeOneElemBasedOnFieldIdBasicDataType[] = { + 1, // _FIELD_ID_DATA_TYPE_U8 =0 + 4, // _FIELD_ID_DATA_TYPE_U32 + 1, // _FIELD_ID_DATA_TYPE_S8 + 4, // _FIELD_ID_DATA_TYPE_S32 + 2, // _FIELD_ID_DATA_TYPE_U16 + 2, // _FIELD_ID_DATA_TYPE_S16 +}; + +static _NV_STREAM_BUF nvStream[_NV_STREAM_LEN_MAX]; +static int subTableRd, subTableWr; + +#if !defined(_RECURSIVE_VERSION) +#define _SUBTABLES_MAX 32 +static _SUBTABLES_QUEUE subTablesQueue[_SUBTABLES_MAX]; +#endif + +/*============================================================================== +* +* Storage for NvTablesFromBin +* +*=============================================================================== +*/ + +/* + * Init NvTablesFromBin + * All entries are initialized to 0, pointers to NULL +*/ + +_NV_TEMPLATE_TABLE NvTablesFromBin[TABLES_MAX][TABLE_ENTRIES_MAX] = { + { /* TABLE_LAST*/ + {{nul}, 0, 0, 0, 0, 0, 0, {nul}}, + }, +}; + +static void initNvTablesFromBin(void) +{ + int i, j; + + for (i = 0; i < TABLES_MAX; i++) { + for (j = 0; j < TABLE_ENTRIES_MAX; j++) { + NvTablesFromBin[i][j].fieldName[0] = nul; + NvTablesFromBin[i][j].fieldName[1] = nul; + NvTablesFromBin[i][j].fieldName[2] = nul; + NvTablesFromBin[i][j].fieldId = 0; + NvTablesFromBin[i][j].fieldStorageType = 0; + NvTablesFromBin[i][j].fieldStorageSize1 = 0; + NvTablesFromBin[i][j].fieldStorageSize2 = 0; + NvTablesFromBin[i][j].fieldStorageSize3 = 0; + NvTablesFromBin[i][j].offset = 0; + NvTablesFromBin[i][j].fieldFullName[0] = nul; + NvTablesFromBin[i][j].fieldFullName[1] = nul; + NvTablesFromBin[i][j].fieldFullName[2] = nul; + } + } + + return; +} + +/*============================================================================== +* +* Storage for NvEnumsFromBin +* +* ============================================================================== +*/ + +/* + * Prepare the NV enum templates storage parsed from nv.bin + * They are used later for parsing the nv.bin data + * All entries are initialized to 0, pointers to NULL + */ + +_NV_TEMPLATE_ENUM NvEnumsFromBin[INDEX_ENUM_MAX][ENUM_ENTRIES_MAX] = { + { /* INDEX_ENUM_LAST */ + {{nul}, 0, 0, {nul}}, + }, +}; + +static void initNvEnumsFromBin(void) +{ + int i, j; + + for(i = 0; i < INDEX_ENUM_MAX; i++) { + for(j = 0; j < ENUM_ENTRIES_MAX; j++) { + NvEnumsFromBin[i][j].enumName[0] = nul; + NvEnumsFromBin[i][j].enumName[1] = nul; + NvEnumsFromBin[i][j].enumName[2] = nul; + NvEnumsFromBin[i][j].enumValue = 0; + NvEnumsFromBin[i][j].enumValuePeer = 0xFF; + NvEnumsFromBin[i][j].enumFullName[0] = nul; + } + } + return; +} + + +// ============================================================================= +// +// Parse template streams +// +// ============================================================================= + +/* + * Read nv.bin to extract the template info + * _NV_TEMPLATE_TABLE NvTablesFromBin[]; + */ + +/* + * Parse nv.bin data and extract to the build-in data storage + * + * There are two outcomes from earlier templates comparison operation. + * different or identical + * If identical, this operation will most likely take place. + * If different, + * One is to simply indicate to the user and abort reading the nv.bin data + * The other is to continue this operation, and extract the matching entries + * in nv.bin + */ + +/* + * The template based NV logic: + * - the s/w module has the built-in templates + * - nv.bin is read one stream at a time, sequentially from beginning to end + * - if the stream is an enum stream, + * - add to nv.bin template data structure + * - compare with the built in template, by the string ID + * - if two match, move on + * - if not match, indicate mismatch, act based on the global logic + * _ selection + * - if abort, exit here + * - if extract-matching-ones, + * - copy the enum from the built-in template over to a separate + * _ column + * - when the enum comparison is done, all correlated enums have + * - a built-in enum value + * - all mismtached ones have 0xff + * - else if the stream is a table + * - add to nv.bin template data structure + * - compare with the built-in template, by the field string ID + * - if two tables match, move on + * - if not match, indicate mismatch and proceed based on the global + * - logic selection + * - if abort, exit here + * - if extract-matching-ones, + * - copy the built-in template offset to a separate column + * - eles if the stream is a data stream + * - parse the data stream based on the accumulated NV templates so far, + * - note at this point, + * - 1. the accumulated templates may be incomplete, to make up the + * - whole NV structure + * - 2. some will be "overwritten" by later templates definitions + * - that change the earlier templates) + * - how to parse? + * - based on the nv.bin accumulated templates so far, + * - select the table definition from the data stream, + * - find the corresponding table template, + * - start parsing data based on the template's field string IDs, + * - field by field sequentially. + * - if the field is a nested table, + * - go inside to the next level + * - if the field is a basic type, + * - copy data of the given size to the offset which is the + * - offset in the built-in nv data storage + * - end of the logic + */ + +/*---------------------------------------------------------------------------- + \brief nvParser() - parse nv data provided in input buffer and store + \ output in sHalNv + \param inputEncodedbuffer, length, sHalNv - ptr to input stream, + \param length, sHalNv + \return success when successfully decode and copy to sHalNv structure + \sa +-----------------------------------------------------------------------------*/ + +VOS_STATUS nvParser(tANI_U8 *pnvEncodedBuf, tANI_U32 nvReadBufSize, + sHalNv *hal_nv) +{ + _STREAM_RC streamRc; + _NV_STREAM_BUF *pStream = &nvStream[0]; + tANI_U32 len; + _ErrorCode errCode = _OK; + VOS_STATUS ret = VOS_STATUS_SUCCESS; + gpnvData_t = hal_nv; + + // prepare storages for parsing nv.bin + initNvTablesFromBin(); + initNvEnumsFromBin(); + + // init stream read pointer + initReadStream(pnvEncodedBuf, nvReadBufSize); + + // get and process streams one by one + while (RC_FAIL != (streamRc = NEXT_STREAM(&len, &nvStream[0])) ) { + // need to copy, stream layer is freeing it + if (len > _NV_STREAM_LEN_MAX) { + errCode = _STREAM_NOT_FIT_BUF; + goto _error; + } + // template or data + if (IsStreamTemplate(pStream[_NV_BIN_STREAM_HEADER_BYTE])) { + if (_MIS_MATCH == processNvTemplate(pStream, len)) { + if (_FLAG_AND_ABORT(gNVParsingControlLo) ) { + errCode = _SW_BIN_MISMATCH; + break; + } + } + } + else { + processNvData(pStream, len); + } + } + +_error: + if (_OK != errCode) { + ret = VOS_STATUS_E_INVAL; + } + + // all done + return ret; +} + +static _NV_TEMPLATE_PROCESS_RC processNvTemplate(_NV_STREAM_BUF *pStream, + int len) +{ + // Table or enum + if (IsTemplateStreamTable(pStream[_NV_BIN_STREAM_HEADER_BYTE])) { + return processNvTemplateTable(pStream, len); + } + else { + return processNvTemplateEnum(pStream, len); + } +} + +/* ----------------------------------------------------------------------------- + * + * Parse one table template stream in nv.bin + * The length of table templates varies, based on the field ID class, + * field size type + */ + +static _NV_TEMPLATE_PROCESS_RC processNvTemplateTable(_NV_STREAM_BUF *pStream, + int len) +{ + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + char tableNameFromBin[_TABLE_NAME_LEN +1]; + int tableIdxFromBin; + + // construct the template table in the NvTablesFromBin + memset((void*)tableNameFromBin, '\0', (size_t) (_TABLE_NAME_LEN +1)); + tableIdxFromBin = constructATemplateTable(pStream, len, tableNameFromBin); + + // fetch the table name from the first entry, the Table of all tables + // search for the corresponding table in NvDataBuiltIn + if (tableIdxFromBin) { + rc = compareWithBuiltinTable(tableIdxFromBin, tableNameFromBin); + } + // done + return rc; +} + +static int getOffsetFromBuiltIn(char *tableNameFromBin) +{ + int offset = _OFFSET_NOT_SET; + int i; + + _NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn; + // search NvTablesBuiltIn for the same string named table, and its idx + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTableBuiltin[0][i].fieldName[0]) { + break; + } + if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) { + offset = pTableBuiltin[0][i].offset; + break; + } + } + return offset; +} + +/* + * Construct a table template in the NvTablesFromBin + * it returns the newly constructed table, for comparison with NvTablesBuiltIn + */ +static int constructATemplateTable(_NV_STREAM_BUF *pStream, int len, + char *tableStrName) +{ + int pos = 0; + _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin; + int tableIdx, entryIdx; + int i; + _ErrorCode errCode = _OK; + + tableIdx = (pStream[_NV_BIN_STREAM_TABLE_ID_BYTE] & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + + if (IsIdxTableOfAllTables(tableIdx)) { + } + else { + // find the string name of the table + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTable[0][i].fieldName[0]) { + break; + } + if ((pTable[0][i].fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK) == + tableIdx) { + strlcpy(tableStrName, pTable[0][i].fieldName, (_TABLE_NAME_LEN +1)); + break; + } + } + if (TABLE_ENTRIES_MAX == i) { + // if string name not found, don't know what to do + errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES; + goto _error; + } + } + + // check if the table is already populated + if (nul != pTable[tableIdx][0].fieldName[0]) { // there is data in that enty + // tbd: decision logic based on Parsing Control (bitmap) + } + + // overwrite table entry, tableIdx + pos = _TABLE_FIELDS_POS; + entryIdx = 0; + while (pos < len) { + if (!(pos <= (len - _TABLE_FIELD_MIN_LEN))) { + // error condition + errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR; + break; + } + + // populate the entry + memset(pTable[tableIdx][entryIdx].fieldName, '\0', + (size_t) (_TABLE_NAME_LEN + 1)); + memset(pTable[tableIdx][entryIdx].fieldFullName, '\0', + (size_t) (_TABLE_FIELD_FULL_NAME_LEN + 1)); + pTable[tableIdx][entryIdx].fieldName[0] = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldName[1] = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldId = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldStorageType = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldStorageSize1 = 0; + pTable[tableIdx][entryIdx].fieldStorageSize2 = 0; + pTable[tableIdx][entryIdx].fieldStorageSize3 = 0; + pTable[tableIdx][entryIdx].offset = + getOffsetFromBuiltIn(pTable[tableIdx][entryIdx].fieldName); + + if (SINGULAR == + _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) { + } + else if (ARRAY_1 == + _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) { + pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++]; + } + else if (ARRAY_2 == + _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) { + pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++]; + } + else if (ARRAY_3 == + _STORAGE_TYPE(pTable[tableIdx][entryIdx].fieldStorageType)) { + pTable[tableIdx][entryIdx].fieldStorageSize1 = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldStorageSize2 = pStream[pos++]; + pTable[tableIdx][entryIdx].fieldStorageSize3 = pStream[pos++]; + } + // + entryIdx++; + } + +_error: + if (_OK != errCode) { + } + + // all done + return tableIdx; +} + +/* ----------------------------------------------------------------------------- + * + * Table Compare logic: + * + * 1. the fields need to be in the same order. Looping through fields doesn't + * guarantee order. + * 2. whenever mismatch occurs in this "same-order" comparison, flag. + * 3. If extract matching entries' option is selected, proceed to nv.bin table + * and extract data. + * + * Note + * "compareWithBuiltinTable" is the initiating point. + * "compare2Tables" is the top level compare logic. + * it is naturally implemented as a recursive call, but out of stack + * overflow concern, + * it is also implemented as an iterative loop. + * + */ + +static _NV_TEMPLATE_PROCESS_RC compareWithBuiltinTable(int idxFromBin, + char *tableNameFromBin) +{ + int i; + _NV_TEMPLATE_TABLE (*pTableBuiltin)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn; + int tableIdxBuiltin = 0; + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + _ErrorCode errCode = _OK; + + // search NvTablesBuiltIn for the same string named table, and its idx + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTableBuiltin[0][i].fieldName[0]) { + break; + } + if (!strcmp(tableNameFromBin, pTableBuiltin[0][i].fieldName)) { + tableIdxBuiltin = (pTableBuiltin[0][i].fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + break; + } + } + + // compare and copy values + if (!tableIdxBuiltin) { + errCode = _TABLE_NON_EXIST_IN_TABLE_OF_ALL_TABLES; + rc = _MIS_MATCH; + } + else { + subTableRd = 0; + subTableWr = 0; + + // fire the comparison logic + if (_MIS_MATCH == compare2Tables(idxFromBin, tableIdxBuiltin)) { + rc = _MIS_MATCH; + } + + // for iterative version + // return code (rc) should only be set to _MIS_MATCH when it happens at + // least once +#if !defined(_RECURSIVE_VERSION) + { + int idxSubFromBin, idxSubBuiltin; + while (subTableRd != subTableWr) { + idxSubFromBin = subTablesQueue[subTableRd].idxSubFromBin; + idxSubBuiltin = subTablesQueue[subTableRd].idxSubBuiltin; + if (_MIS_MATCH == compare2Tables(idxSubFromBin, idxSubBuiltin)) { + rc = _MIS_MATCH; + } + // increment read pointer + subTableRd = (subTableRd+1) % _SUBTABLES_MAX; + } + } +#endif //#if !defined(_RECURSIVE_VERSION) + } + +//_error: + if (_OK != errCode) { + //printf("Error %d \n", errCode); + } + + // + return rc; +} + +static _NV_TEMPLATE_PROCESS_RC compare2Tables(int idxFromBin, int idxBuiltin) +{ + int i, j; + _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX]; + _NV_TEMPLATE_TABLE (*pTableFromBin)[TABLE_ENTRIES_MAX]; + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + + pTableBuiltIn = NvTablesBuiltIn; + pTableFromBin = NvTablesFromBin; + + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) || + // end of table occurs in either table + (nul == pTableFromBin[idxFromBin][i].fieldName[0])) { + // end of table occurs in either table + if ((nul == pTableBuiltIn[idxBuiltin][i].fieldName[0]) && + (nul == pTableFromBin[idxFromBin][i].fieldName[0])) { + rc = _MATCH; + } + else { + rc = _MIS_MATCH; + + for (j=0; joffset = pTableBuiltIn->offset; + +_end: + return rc; +} + +static _NV_TEMPLATE_PROCESS_RC compare2FieldIDType( + _NV_TEMPLATE_TABLE *pTableBuiltIn, + _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltin, int idxFromBin) +{ + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + + if (IsFieldTypeBasicData(pTableBuiltIn->fieldId)) { + if (pTableBuiltIn->fieldId == pTableFromBin->fieldId) { + rc = _MATCH; + } + else { + rc = _MIS_MATCH; + } + } + else { // field is a table + int idxSubBuiltin = pTableBuiltIn->fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK; + int idxSubFromBin = pTableFromBin->fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK; +#if defined(_RECURSIVE_VERSION) + rc = compare2Tables(idxSubFromBin, idxSubBuiltin); +#else + { + subTablesQueue[subTableWr].idxSubFromBin = idxSubFromBin; + subTablesQueue[subTableWr].idxSubBuiltin = idxSubBuiltin; + subTableWr = (subTableWr +1) % _SUBTABLES_MAX; + } +#endif //#if defined(_RECURSIVE_VERSION) + } + + return rc; +} + + +static _NV_TEMPLATE_PROCESS_RC compare2FieldStorageTypeAndSizes( + _NV_TEMPLATE_TABLE *pTableBuiltIn, + _NV_TEMPLATE_TABLE *pTableFromBin, int idxBuiltIn, int idxFromBin) +{ + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + + if (_STORAGE_TYPE(pTableBuiltIn->fieldStorageType) == + _STORAGE_TYPE(pTableFromBin->fieldStorageType)) { + if (SINGULAR == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) { + rc = _MATCH; + } + else if (ARRAY_1 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) { + if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin, + _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1, + pTableBuiltIn->fieldStorageType), + _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1, + pTableFromBin->fieldStorageType), + pTableBuiltIn->fieldStorageSize1, + pTableFromBin->fieldStorageSize1)) ) { + + rc = _MATCH; + } + } + else if (ARRAY_2 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) { + if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin, + _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1, + pTableBuiltIn->fieldStorageType), + _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1, + pTableFromBin->fieldStorageType), + pTableBuiltIn->fieldStorageSize1, + pTableFromBin->fieldStorageSize1)) && + (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin, + _STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2, + pTableBuiltIn->fieldStorageType), + _STORAGE_SIZE2(pTableFromBin->fieldStorageSize2, + pTableFromBin->fieldStorageType), + pTableBuiltIn->fieldStorageSize2, + pTableFromBin->fieldStorageSize2)) ) { + rc = _MATCH; + } + } + else if (ARRAY_3 == _STORAGE_TYPE(pTableBuiltIn->fieldStorageType)) { + if ((_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin, + _STORAGE_SIZE1(pTableBuiltIn->fieldStorageSize1, + pTableBuiltIn->fieldStorageType), + _STORAGE_SIZE1(pTableFromBin->fieldStorageSize1, + pTableFromBin->fieldStorageType), + pTableBuiltIn->fieldStorageSize1, + pTableFromBin->fieldStorageSize1)) && + (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin, + _STORAGE_SIZE2(pTableBuiltIn->fieldStorageSize2, + pTableBuiltIn->fieldStorageType), + _STORAGE_SIZE2(pTableFromBin->fieldStorageSize2, + pTableFromBin->fieldStorageType), + pTableBuiltIn->fieldStorageSize2, + pTableFromBin->fieldStorageSize2)) && + (_MATCH == compare2StorageSize(idxBuiltIn, idxFromBin, + _STORAGE_SIZE3(pTableBuiltIn->fieldStorageSize3, + pTableBuiltIn->fieldStorageType), + _STORAGE_SIZE3(pTableFromBin->fieldStorageSize3, + pTableFromBin->fieldStorageType), + pTableBuiltIn->fieldStorageSize3, + pTableFromBin->fieldStorageSize3)) ) { + rc = _MATCH; + } + } + } + else { + rc = _MIS_MATCH; + } + return rc; +} + +static _NV_TEMPLATE_PROCESS_RC compare2StorageSize(int idxBuiltIn, + int idxFromBin, int sizeBuiltIn, + int sizeFromBin, tANI_U8 sizeBuiltInLowByte, tANI_U8 sizeFromBinLowByte) +{ + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + + if (IsFieldSizeInt(sizeBuiltInLowByte) && + IsFieldSizeInt(sizeFromBinLowByte)) { + if (sizeBuiltIn == sizeFromBin) { + rc = _MATCH; + } + else { + rc = _MIS_MATCH; + } + } + else if (!IsFieldSizeInt(sizeBuiltInLowByte) && + !IsFieldSizeInt(sizeFromBinLowByte)) { + // enums should have been compared when enum streams are parsed + // The implication is that the enum streams should go before tables' + rc = enumMetaDataFromBin[idxFromBin].match; + } + else { + rc = _MIS_MATCH; + } + + return rc; +} + +/* + * ---------------------------------------------------------------------------- + * + * Parse one enum template stream in nv.bin + */ +static _NV_TEMPLATE_PROCESS_RC processNvTemplateEnum(_NV_STREAM_BUF *pStream, + int len) +{ + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + char enumStr[_ENUM_NAME_LEN + 1]; + //_NV_TEMPLATE_ENUM *pEnum; + int enumIdx; + + // construct the enum template in the NvEnumsFromBin + memset((void*)enumStr, '\0', (size_t) (_ENUM_NAME_LEN + 1)); + enumIdx = constructATemplateEnum(pStream, len, enumStr); + + // Compare the enum template + // also record compare results for later use in the table + // templates parsing where + // the fields may be indexed by enums + // if enumIdx ==0, didn't construct any entry, + // (or only the first entry) + if (enumIdx) { + compareEnumWithBuiltin(enumStr, enumIdx); + } + + return rc; +} + +static void compareEnumWithBuiltin(char *enumStr, int enumIdxFromBin) +{ + int i; + int enumIdxBuiltin = 0; + _NV_TEMPLATE_ENUM (*pEnumBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn; + _ErrorCode errCode = _OK; + + for (i = 0; i < ENUM_ENTRIES_MAX; i++) { + if (nul == pEnumBuiltin[0][i].enumName[0]) { + break; + } + if (!strcmp(enumStr, pEnumBuiltin[0][i].enumName)) { + enumIdxBuiltin = pEnumBuiltin[0][i].enumValue; + break; + } + } + if (!enumIdxBuiltin) { + errCode = _ENUM_NOT_FOUND_IN_BUILT_IN; + return; + } + else { + compare2EnumEntriesAndCopy(enumIdxFromBin, enumIdxBuiltin); + } + +//_error: + if (_OK != errCode) { + //printf("Error %d\n", errCode); + } + + return; +} + +static _NV_TEMPLATE_PROCESS_RC compare2EnumEntriesAndCopy(int idxFromBin, + int idxBuiltin) +{ + int i,j; + _NV_TEMPLATE_PROCESS_RC rc = _MATCH; + _NV_TEMPLATE_ENUM (*enumsFromBin)[ENUM_ENTRIES_MAX] = NvEnumsFromBin; + _NV_TEMPLATE_ENUM (*enumsBuiltin)[ENUM_ENTRIES_MAX] = NvEnumsBuiltIn; + + // need to go through all enums + for (i = 0; i < ENUM_ENTRIES_MAX; i++) { + // end conditions: either both reach the end (match), + // or one of them reaching the end (mismatch) + if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) || + (nul == enumsFromBin[idxFromBin][i].enumName[0])) { + if ((nul == enumsBuiltin[idxBuiltin][i].enumName[0]) && + (nul == enumsFromBin[idxFromBin][i].enumName[0])) { + // fully matched + rc = _MATCH; + break; + } + else { + rc = _MIS_MATCH; + for (j = 0; j < ENUM_ENTRIES_MAX; j++) { + if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) { + break; + } + if (!strcmp((const char*)enumsFromBin[idxFromBin][i].enumName, + (const char*)enumsBuiltin[idxBuiltin][j].enumName)) { + enumsFromBin[idxFromBin][i].enumValuePeer = + enumsBuiltin[idxBuiltin][j].enumValue; + break; + } + } + break; + } + } + else { + if (!strcmp(enumsBuiltin[idxBuiltin][i].enumName, + enumsFromBin[idxFromBin][i].enumName)) { + // copy builtIn enum value to fromBin + enumsFromBin[idxFromBin][i].enumValuePeer = + enumsBuiltin[idxBuiltin][i].enumValue; + } + else { + // mismatch, but still loop through the whole enum list + // for the "ahead" and "behind" scenarios + rc = _MIS_MATCH; + for (j = 0; j < ENUM_ENTRIES_MAX; j++) { + if (nul == enumsBuiltin[idxBuiltin][j].enumName[0]) { + break; + } + if (!strcmp(enumsFromBin[idxFromBin][i].enumName, + enumsBuiltin[idxBuiltin][j].enumName)) { + enumsFromBin[idxFromBin][i].enumValuePeer = + enumsBuiltin[idxBuiltin][j].enumValue; + break; + } + } + } + } + } + + // record match or mismatch for later data parsing use + enumMetaDataFromBin[idxFromBin].match = rc; + + // all done + return rc; +} + +static int constructATemplateEnum(_NV_STREAM_BUF *pStream, int len, + char *enumStr) +{ + int pos = 0; + _NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX]; + int enumIdx = 0; + int i; + int entryIdx; + _ErrorCode errCode = _OK; + + enumIdx = (pStream[_NV_BIN_STREAM_ENUM_ID_BYTE] & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + pEnum = NvEnumsFromBin; + + // find its string name + // the logic: + // since the nv.bin doesn't encode the enum string name in the actual enum + // stream, only the first "enum of all enums" + // has the names of all enums. + if (IsIdxEnumOfAllEnums(enumIdx)) { + } + else { + for (i = 0; i < ENUM_ENTRIES_MAX; i++) { + if (nul == pEnum[0][i].enumName[0]) { + break; + } + if (pEnum[0][i].enumValue == enumIdx) { + strlcpy(enumStr, pEnum[0][i].enumName,(_ENUM_NAME_LEN + 1)); + break; + } + } + if (ENUM_ENTRIES_MAX == i) { + // without a string name, don't know what to do with the enum indexed + errCode = _ENUM_NOT_FOUND_IN_BUILT_IN; + goto _error; + } + } + + // Found the enum string name, now parsing decision time ... + // Is the entry already populated? + if (nul != pEnum[enumIdx][0].enumName[0]) { // there is data in that entry + // TBD: + // the logic here depends on how we support "parsing data based on the + // latest template". + // one way is to overwrite the template, so the subsequent parsing will + // be based on the "latest". + // the second way is to "append" the template, and the parsing should + // always be based on the "last" of the same name + // for simplicity, support the first approach for now. + // + // the logic: + // based on the parsing control (bitmap), we may proceed on overwriting + // enums with blind faith that the writing logic is correct, + // or ignore the appended. + // + } + + // overwrite entry, enumIdx + pos = _ENUM_START_POS; + entryIdx = 0; + while (pos < len) { + if (!(pos <= (len - _ENUM_MIN_LEN))) { + // error condition + errCode = _INSUFFICIENT_FOR_FIELD_PARSER_ERROR; + break; + } + + // populate the entry + memset(pEnum[enumIdx][entryIdx].enumName, '\0', + (size_t) (_ENUM_NAME_LEN +1)); + memset(pEnum[enumIdx][entryIdx].enumFullName, '\0', + (size_t) (_ENUM_FULL_NAME_LEN +1)); + pEnum[enumIdx][entryIdx].enumName[0] = pStream[pos++]; + pEnum[enumIdx][entryIdx].enumName[1] = pStream[pos++]; + pEnum[enumIdx][entryIdx].enumValue = pStream[pos++]; + entryIdx++; + } + +_error: + if (_OK != errCode) { + //printf("Error %d\n", errCode); + } + + // all done + return enumIdx; +} + +/* ----------------------------------------------------------------------------- + * + * Process data stream + * The purpose is to copy nv.bin data into built in NV data structure. + * This is the parser function. + * + * Next phase: + * With NV data in the s/w module data structure, nv.bin conforming + * to the new format can be generated. That is the nv.bin generation logic.) + * + * Data stream has the following format + * + * delimiter|streamHeader|tableID|data....|CRC|delimiter + * Note + * 1. delimiters are not present in the stream data, pStream. + * 2. nested tables do NOT have table IDs with them. + * + */ +// NV data, per built in templates +// Recursive table parsing, which is naturally depth-first +// If iterative, a bit hard to implement + +static void parseSubDataTable4Size(int tableIdx, int numElem) +{ + _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin; + int idxSubTable; + int i; + int numSubElem = 0, idx=0; + + // "apply" template to data -- parsing the actual NV data, + // so far we have been parsing and building templates + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTable[tableIdx][i].fieldName[0]) { + // data parsing done for this stream + break; + } + if (IsFieldTypeBasicData(pTable[tableIdx][i].fieldId)) { + getBasicDataSize(&(pTable[tableIdx][i])); + } + else { + // number of element + idx = + _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType); + numSubElem = numElemBasedOnStorageType[idx]( + &(pTable[tableIdx][i]), 1); + // get size of the sub-table + idxSubTable = (pTable[tableIdx][i].fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + // recursive calls for the total size of the subtable + parseSubDataTable4Size(idxSubTable, numSubElem); + } + } + // update subTableSize for the number of elements + subTableSize *= numElem; + + return; +} + +static void copyDataToBuiltInFromBin(int tableIdx,int fieldId, + _NV_STREAM_BUF *pStream, int *pos, int addOffset, int tableBaseOffset) +{ + int i,j,k,storageType; + int idx=0, size1=0, size2=0, size3=0; + int enumIdx1=0, enumIdx2=0, enumIdx3=0, sizeOneElem=0; + int isFirstFieldEnum=0,isSecondFieldEnum=0,isThirdFieldEnum=0; + int index,index1,index2; + int dindex,dindex1,dindex2,totalSize; + int offset=0,sizeBuiltIn,tableIdxBuiltIn,fieldIdBuiltIn; + int idxBuiltIn=0, size1BuiltIn=0, size2BuiltIn=0, size3BuiltIn=0; + int size1Bin=0, size2Bin=0, size3Bin=0, numElemBuiltIn; + int sizeOneElemBuiltIn=0, field; + unsigned char *ptr, *dptr; + _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin; + _NV_TEMPLATE_TABLE (*pTableBuiltIn)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn; + + storageType = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType); + field = pTable[tableIdx][fieldId].fieldId; + sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK]; + sizeBuiltIn = getBuiltInFieldCount(tableIdx, + pTable[tableIdx][fieldId].fieldName, + &tableIdxBuiltIn,&fieldIdBuiltIn,&numElemBuiltIn); + + field = pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldId; + sizeOneElemBuiltIn = sizeOneElemBasedOnFieldIdBasicDataType[field & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK]; + + if (storageType == SINGULAR ) { + ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset; + dptr = (unsigned char *)&pStream[*pos]; + + if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) { + idx = _STORAGE_TYPE(pTable[tableIdx][fieldId].fieldStorageType); + size1Bin = numElemBasedOnStorageType[idx]( + &(pTable[tableIdx][fieldId]), 1); + field = pTable[tableIdx][fieldId].fieldId; + sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK]; + + idxBuiltIn = _STORAGE_TYPE( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + size1BuiltIn = numElemBasedOnStorageType[idx]( + &(pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn]), 0); + + size1 = size1Bin; + if (size1 > size1BuiltIn) { + size1 = size1BuiltIn; + } + } + totalSize = size1 * sizeOneElem; + + offset = 0; + for (i = 0; i < size1; i++) { + vos_mem_copy(&ptr[offset], &dptr[offset], sizeOneElem); + offset = offset + sizeOneElem; + } + + *pos = *pos + (size1Bin * sizeOneElem); + } + else { + if (ARRAY_1 == storageType) { + ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset; + dptr = (unsigned char *)&pStream[*pos]; + + idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1, + pTable[tableIdx][fieldId].fieldStorageType); + size1Bin = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize1, 1); + + idx = _STORAGE_SIZE1( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size1BuiltIn = getNumElemOutOfStorageSize(idx, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0); + + size1 = size1Bin; + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) { + enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + isFirstFieldEnum = 1; + } + else { + isFirstFieldEnum = 0; + if (size1 > size1BuiltIn) { + size1 = size1BuiltIn; + } + } + + offset = 0; + for (i = 0; i < size1; i++) { + if (isFirstFieldEnum) { + if (NvEnumsFromBin[enumIdx1][i].enumValuePeer != 0xFF) { + index = NvEnumsFromBin[enumIdx1][i].enumValuePeer; + dindex = NvEnumsFromBin[enumIdx1][i].enumValue; + + index = index * sizeOneElem; + dindex = dindex * sizeOneElem; + + vos_mem_copy(&ptr[index], &dptr[dindex], sizeOneElem); + } + } + else { + vos_mem_copy(&ptr[offset], &dptr[offset], sizeOneElem); + offset = offset + sizeOneElem; + } + } + + *pos = *pos + (size1Bin * sizeOneElem); + } + else if (ARRAY_2 == storageType) { + ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset; + dptr = (unsigned char *)&pStream[*pos]; + + idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1, + pTable[tableIdx][fieldId].fieldStorageType); + size1Bin = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize1, 1); + + idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2, + pTable[tableIdx][fieldId].fieldStorageType); + + size2Bin = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize2, 1); + + idx = _STORAGE_SIZE1( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size1BuiltIn = getNumElemOutOfStorageSize(idx, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, 0); + + idx = _STORAGE_SIZE2( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size2BuiltIn = getNumElemOutOfStorageSize(idx, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, 0); + + size1 = size1Bin; + size2 = size2Bin; + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) { + enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + isFirstFieldEnum = 1; + } + else { + isFirstFieldEnum = 0; + if (size1 > size1BuiltIn) { + size1 = size1BuiltIn; + } + } + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) { + enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + isSecondFieldEnum = 1; + } + else { + isSecondFieldEnum = 0; + if (size2 > size2BuiltIn) { + size2 = size2BuiltIn; + } + } + + offset = 0; + + for (i = 0; i < size1; i++) { + if (isFirstFieldEnum) { + if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) { + continue; + } + + index = NvEnumsFromBin[enumIdx1][i].enumValuePeer; + dindex = NvEnumsFromBin[enumIdx1][i].enumValue; + } + else { + index = dindex = i; + } + + for (j = 0; j < size2; j++) { + if (isSecondFieldEnum) { + if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) { + continue; + } + + index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer; + dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue; + } + else { + index1 = dindex1 = j; + } + + vos_mem_copy(&ptr[(index1 + index * size2BuiltIn)*sizeOneElem], + &dptr[(dindex1+dindex*size2Bin)*sizeOneElem], sizeOneElem); + offset = offset + sizeOneElem; + } + } + + *pos = *pos + size2Bin * size1Bin * sizeOneElem; + } + else if (ARRAY_3 == storageType) { + ptr = ((unsigned char*)gpnvData_t) + tableBaseOffset + addOffset; + dptr = (unsigned char *)&pStream[*pos]; + + idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1, + pTable[tableIdx][fieldId].fieldStorageType); + size1Bin = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize1, 1); + + idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2, + pTable[tableIdx][fieldId].fieldStorageType); + size2Bin = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize2, 1); + + idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3, + pTable[tableIdx][fieldId].fieldStorageType); + size3Bin = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize3, 1); + + idx = _STORAGE_SIZE1( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size1BuiltIn = getNumElemOutOfStorageSize(idx, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, + 0); + + idx = _STORAGE_SIZE2( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size2BuiltIn = getNumElemOutOfStorageSize(idx, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, + 0); + + idx = _STORAGE_SIZE3( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size3BuiltIn = getNumElemOutOfStorageSize(idx, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize3, + 0); + + size1 = size1Bin; + size2 = size2Bin; + size3 = size3Bin; + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) { + enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + isFirstFieldEnum = 1; + } + else { + isFirstFieldEnum = 0; + if (size1 > size1BuiltIn) { + size1 = size1BuiltIn; + } + } + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) { + enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + isSecondFieldEnum = 1; + } + else { + isSecondFieldEnum = 0; + if (size2 > size2BuiltIn) { + size2 = size2BuiltIn; + } + } + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) { + enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + isThirdFieldEnum = 1; + } + else { + isThirdFieldEnum = 0; + if (size3 > size3BuiltIn) { + size3 = size3BuiltIn; + } + } + + offset = 0; + for (i = 0; i < size1; i++) { + if (isFirstFieldEnum) { + if (NvEnumsFromBin[enumIdx1][i].enumValuePeer == 0xFF) { + continue; + } + + index = NvEnumsFromBin[enumIdx1][i].enumValuePeer; + dindex = NvEnumsFromBin[enumIdx1][i].enumValue; + } + else { + index = dindex = i; + } + + for (j = 0; j < size2; j++) { + if (isSecondFieldEnum) { + if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) { + continue; + } + + index1 = NvEnumsFromBin[enumIdx2][j].enumValuePeer; + dindex1 = NvEnumsFromBin[enumIdx2][j].enumValue; + } + else { + index1 = dindex1 = j; + } + + for (k = 0; k < size3; k++) { + if (isThirdFieldEnum) { + if (NvEnumsFromBin[enumIdx2][j].enumValuePeer == 0xFF) { + continue; + } + + index2 = NvEnumsFromBin[enumIdx3][k].enumValuePeer; + dindex2 = NvEnumsFromBin[enumIdx3][k].enumValue; + } + else { + index2 = dindex2 = k; + } + + vos_mem_copy(&ptr[(index2 + (index1 * size2BuiltIn) + + (index * size3BuiltIn * size2BuiltIn)) * sizeOneElem], + &dptr[(dindex2 + (dindex1 * size2Bin) + + (dindex * size3Bin * size2Bin))*sizeOneElem], + sizeOneElem); + + offset = offset + sizeOneElem; + } + } + } + + *pos = *pos + size1Bin * size2Bin * size3Bin * sizeOneElem; + } + else { + } + } +} + +// search NvTablesBuiltIn for the same string named table, and its idx +static int getBuiltInFieldCount (int tableIdxBin, char *tableNameFromBin, + int *tblIdBuiltIn, int *fieldIdBuitIn, int *numElements) +{ + int i,idx,numElem,tableIdxBuiltin=0,fieldCnt; + _NV_TEMPLATE_TABLE (*pTableBin)[TABLE_ENTRIES_MAX] = NvTablesFromBin; + _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesBuiltIn; + int found=0, fieldIndex = 0; + + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTableBin[0][i].fieldName[0]) { + break; + } + + if ((pTableBin[0][i].fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK) == tableIdxBin) { + found = 1; + break; + } + } + + if (!found) { + return -1; + } + + //fieldName index got from tableId from Bin + fieldIndex = i; + found = 0; + + for (i=0;i> FIELD_SIZE_VALUE_LSB); + } + } + else if (ARRAY_2 == storageType) { + idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1, + pTable[tableIdx][fieldId].fieldStorageType); + size1 = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize1,nvBin); + + idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2, + pTable[tableIdx][fieldId].fieldStorageType); + + size2 = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize2,nvBin); + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) { + enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + } + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) { + enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + } + } + else if (ARRAY_3 == storageType) { + idx = _STORAGE_SIZE1(pTable[tableIdx][fieldId].fieldStorageSize1, + pTable[tableIdx][fieldId].fieldStorageType); + size1 = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize1,nvBin); + + idx = _STORAGE_SIZE2(pTable[tableIdx][fieldId].fieldStorageSize2, + pTable[tableIdx][fieldId].fieldStorageType); + size2 = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize2,nvBin); + + idx = _STORAGE_SIZE3(pTable[tableIdx][fieldId].fieldStorageSize3, + pTable[tableIdx][fieldId].fieldStorageType); + size3 = getNumElemOutOfStorageSize(idx, + pTable[tableIdx][fieldId].fieldStorageSize3,nvBin); + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize1)) { + enumIdx1 = ((pTable[tableIdx][fieldId].fieldStorageSize1 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + } + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize2)) { + enumIdx2 = ((pTable[tableIdx][fieldId].fieldStorageSize2 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + } + + if (!IsFieldSizeInt(pTable[tableIdx][fieldId].fieldStorageSize3)) { + enumIdx3 = ((pTable[tableIdx][fieldId].fieldStorageSize3 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + } + } + else { + } + } + + if (IsFieldTypeBasicData(pTable[tableIdx][fieldId].fieldId)) { + field = pTable[tableIdx][fieldId].fieldId; + sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[field & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK]; + if ( size3 ) { + fieldSize = fieldSize + size3 * size2 * size1 * sizeOneElem; + } + else if ( size2 ) { + fieldSize = fieldSize + size2 * size1 * sizeOneElem; + } + else if ( size1 ) { + fieldSize = fieldSize + size1 * sizeOneElem; + } + else { + } + } + else { + idxSubTable = (pTable[tableIdx][fieldId].fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + + for (j=0; j> FIELD_SIZE_VALUE_LSB); + if (NvEnumsFromBin[enumIdx][l].enumValuePeer == 0xFF) { + *pos = *pos + (fieldCount/size1Bin) * numElem * numElem2; + continue; + } + } + else { + if ((l+1) > size3BuiltIn) { + *pos = *pos + (fieldCount/size1Bin) * numElem * numElem2; + continue; + } + } + } + for (m=0; m < numElem2; m++) { + if (storageType == ARRAY_2) { + idx1 = _STORAGE_SIZE2( + pTable[tableIdx][fieldId].fieldStorageSize2, + pTable[tableIdx][fieldId].fieldStorageType); + size2Bin = getNumElemOutOfStorageSize(idx1, + pTable[tableIdx][fieldId].fieldStorageSize2, 1); + + fieldSize = 0; + getBuiltInFieldCount(tableIdx, + pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn, + &fieldIdBuiltIn, &numElemBuiltIn); + + idx1 = _STORAGE_SIZE2( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size2BuiltIn = getNumElemOutOfStorageSize(idx1, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize2, + 0); + + if (!IsFieldSizeInt( + pTable[tableIdx][fieldId].fieldStorageSize2)) { + enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize2 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + if (NvEnumsFromBin[enumIdx][m].enumValuePeer == 0xFF) { + *pos = *pos + (fieldCount/size1Bin) * numElem; + continue; + } + } + else { + if ((m+1) > size2BuiltIn) { + *pos = *pos + (fieldCount/size1Bin) * numElem; + continue; + } + } + } + for (j=0; j < numElem; j++) { + if (storageType == ARRAY_1) { + fieldSize = 0; + getBuiltInFieldCount(tableIdx, + pTable[tableIdx][fieldId].fieldName, &tableIdxBuiltIn, + &fieldIdBuiltIn, &numElemBuiltIn); + + idx1 = _STORAGE_SIZE1( + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageType); + + size1BuiltIn = getNumElemOutOfStorageSize(idx1, + pTableBuiltIn[tableIdxBuiltIn][fieldIdBuiltIn].fieldStorageSize1, + 0); + + if (!IsFieldSizeInt( + pTable[tableIdx][fieldId].fieldStorageSize1)) { + enumIdx = ((pTable[tableIdx][fieldId].fieldStorageSize1 & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + if (NvEnumsFromBin[enumIdx][j].enumValuePeer == 0xFF) { + *pos = *pos + (fieldCount/size1Bin); + continue; + } + } + else { + if ((j+1) > size1BuiltIn) { + *pos = *pos + (fieldCount/size1Bin); + continue; + } + } + } + + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTable[idxSubTable][i].fieldName[0]) { + // data parsing done for this stream + break; + } + + idx = _STORAGE_TYPE(pTable[idxSubTable][i].fieldStorageType); + numSubElem = numElemBasedOnStorageType[idx]( + &(pTable[idxSubTable][i]),1); + numSubElem2 = numSubElem3 = 1; + + if (idx == ARRAY_1) { + idx1 = _STORAGE_SIZE1( + pTable[idxSubTable][i].fieldStorageSize1, + pTable[idxSubTable][i].fieldStorageType); + numSubElem = getNumElemOutOfStorageSize(idx1, + pTable[idxSubTable][i].fieldStorageSize1, 1); + } + else if (idx == ARRAY_2) { + idx1 = _STORAGE_SIZE1( + pTable[idxSubTable][i].fieldStorageSize1, + pTable[idxSubTable][i].fieldStorageType); + numSubElem = getNumElemOutOfStorageSize(idx1, + pTable[idxSubTable][i].fieldStorageSize1, 1); + + idx1 = _STORAGE_SIZE2( + pTable[idxSubTable][i].fieldStorageSize2, + pTable[idxSubTable][i].fieldStorageType); + numSubElem2 = getNumElemOutOfStorageSize(idx1, + pTable[idxSubTable][i].fieldStorageSize2, 1); + } + else if (idx == ARRAY_3) { + idx1 = _STORAGE_SIZE1( + pTable[idxSubTable][i].fieldStorageSize1, + pTable[idxSubTable][i].fieldStorageType); + numSubElem = getNumElemOutOfStorageSize(idx1, + pTable[idxSubTable][i].fieldStorageSize1, 1); + + idx1 = _STORAGE_SIZE2( + pTable[idxSubTable][i].fieldStorageSize2, + pTable[idxSubTable][i].fieldStorageType); + numSubElem2 = getNumElemOutOfStorageSize(idx1, + pTable[idxSubTable][i].fieldStorageSize2, 1); + + idx1 = _STORAGE_SIZE3( + pTable[idxSubTable][i].fieldStorageSize3, + pTable[idxSubTable][i].fieldStorageType); + numSubElem3 = getNumElemOutOfStorageSize(idx1, + pTable[idxSubTable][i].fieldStorageSize3, 1); + } + + if (_OFFSET_NOT_SET != pTable[idxSubTable][i].offset) { + if ( pTable[tableIdx][fieldId].offset == addOffset ) { + parseSubDataTableAndCopy(idxSubTable, numSubElem, + numSubElem2, numSubElem3, i, pStream, pos, + addOffset, tableBaseOffset, localAddOffset); + } + else { + // NOT the first Entry in the table.. + if ( !pTable[tableIdx][fieldId].offset ) { + parseSubDataTableAndCopy(idxSubTable, numSubElem, + numSubElem2, numSubElem3, i, pStream, pos, + addOffset, tableBaseOffset, localAddOffset); + } + else { + //First Entry in the the table.. + //(Sending parent offset..) + parseSubDataTableAndCopy(idxSubTable, numSubElem, + numSubElem2, numSubElem3, i, pStream, pos, + addOffset, tableBaseOffset, + pTable[tableIdx][fieldId].offset); + } + } + } + else { + fieldSize = 0; + fieldCount = getFieldCount(idxSubTable, i, numSubElem, 1); + *pos += fieldCount; + } + } + + localAddOffset = localAddOffset + incAddOffset; + } + } + } + } + + return; +} + +static void processNvData(_NV_STREAM_BUF *pStream, int len) +{ + int tableIdx, pos, idx = 0, addOffset = 0, i; + int numElem = 0, additionalOffset = 0, tableBaseOffset = 0; + _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin; + + // fetch the table template + pos = 0; // stream header byte is already checked, that's why we are here + pos += _NV_BIN_DATA_STREAM_TABLEID_BYTE; + tableIdx = (pStream[_NV_BIN_DATA_STREAM_TABLEID_BYTE] & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + pos++; + + // call the table parsing + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTable[0][i].fieldName[0]) { + break; + } + if (tableIdx == _TABLE_IDX(pTable[0][i].fieldId)) { + // Table base offset, stored in the "table of all tables" (index 0), + // will be added to + // fields relative offset in all tables. + tableBaseOffset = pTable[0][i].offset; + + idx = _STORAGE_TYPE(pTable[0][i].fieldStorageType); + + // number of element + numElem = numElemBasedOnStorageType[idx](&(pTable[0][i]),1); + + // recursive calls for the total size of the subtable, which may + // contain nested tables + subTableSize = 0; + parseSubDataTable4Size(tableIdx, numElem); + + // additional offset for EACH subsequent table element + additionalOffset = subTableSize/numElem; + + break; + } + } + + if (numElem) { + for (i = 0; i < numElem; i++) { + addOffset = (i * additionalOffset); + parseDataTable_new(pStream, &pos, tableIdx, addOffset, + tableBaseOffset); + } + } + + // the above recursive data table parser takes care of the nested tables + // all done + return; +} + +static void parseDataTable_new(_NV_STREAM_BUF *pStream, int* pos, int tableIdx, + int addOffset, int tableBaseOffset) +{ + _NV_TEMPLATE_TABLE (*pTable)[TABLE_ENTRIES_MAX] = NvTablesFromBin; + int i, idx, fieldCount; + int numElem, numElem2, numElem3, storageType, idxSubTable; + + // "apply" template to data -- parsing the actual NV data, + // so far we have been parsing and building templates + for (i = 0; i < TABLE_ENTRIES_MAX; i++) { + if (nul == pTable[tableIdx][i].fieldName[0]) { + // data parsing done for this stream + break; + } + + // get size of the sub-table + idxSubTable = (pTable[tableIdx][i].fieldId & + FIELD_ID_TABLE_OR_ENUM_IDX_MASK); + + idx = _STORAGE_TYPE(pTable[tableIdx][i].fieldStorageType); + + numElem = numElemBasedOnStorageType[idx](&(pTable[tableIdx][i]),1); + + addOffset = pTable[tableIdx][i].offset; + + fieldSize = 0; + fieldCount = getFieldCount(tableIdx, i, numElem, 1); + + numElem2 = numElem3 = 1; + + if (idx == ARRAY_1 ) { + storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1, + pTable[tableIdx][i].fieldStorageType); + numElem = getNumElemOutOfStorageSize(storageType, + pTable[tableIdx][i].fieldStorageSize1, 1); + } + else if (idx == ARRAY_2) { + storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1, + pTable[tableIdx][i].fieldStorageType); + + numElem = getNumElemOutOfStorageSize(storageType, + pTable[tableIdx][i].fieldStorageSize1, 1); + + storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2, + pTable[tableIdx][i].fieldStorageType); + + numElem2 = getNumElemOutOfStorageSize(storageType, + pTable[tableIdx][i].fieldStorageSize2, 1); + } + else if (idx == ARRAY_3) { + storageType = _STORAGE_SIZE1(pTable[tableIdx][i].fieldStorageSize1, + pTable[tableIdx][i].fieldStorageType); + + numElem = getNumElemOutOfStorageSize(storageType, + pTable[tableIdx][i].fieldStorageSize1, 1); + + storageType = _STORAGE_SIZE2(pTable[tableIdx][i].fieldStorageSize2, + pTable[tableIdx][i].fieldStorageType); + + numElem2 = getNumElemOutOfStorageSize(storageType, + pTable[tableIdx][i].fieldStorageSize2, 1); + + storageType = _STORAGE_SIZE3(pTable[tableIdx][i].fieldStorageSize3, + pTable[tableIdx][i].fieldStorageType); + + numElem3 = getNumElemOutOfStorageSize(storageType, + pTable[tableIdx][i].fieldStorageSize3, 1); + } + + if (_OFFSET_NOT_SET != pTable[tableIdx][i].offset) { + parseSubDataTableAndCopy(tableIdx, numElem, numElem2, numElem3, i, + pStream, pos, addOffset, tableBaseOffset, 0); + } + else { + *pos += fieldCount; + } + } +} + +static void getBasicDataSize(_NV_TEMPLATE_TABLE *pTableEntry) +{ + int numElem, sizeOneElem, totalSize; + int idx, idx1; + + // number of element + idx = _STORAGE_TYPE(pTableEntry->fieldStorageType); + numElem = numElemBasedOnStorageType[idx](pTableEntry, 1); + + // size of each element + idx1 = pTableEntry->fieldId & FIELD_ID_TABLE_OR_ENUM_IDX_MASK; + sizeOneElem = sizeOneElemBasedOnFieldIdBasicDataType[idx1]; + + // total size in bytes + totalSize = numElem * sizeOneElem; + + // all done, update global + subTableSize += totalSize; + + return; +} + +static int numElemSingular(_NV_TEMPLATE_TABLE *pTableEntry, int unused) +{ + return 1; +} + +static int getNumElemOutOfStorageSize(int fieldStorageSize, + uint8 fieldStorageSizeLowByte, int nvBin) +{ + int ret = 0; + if (IsFieldSizeInt(fieldStorageSizeLowByte)) { + return fieldStorageSize; + } + else { + int maxEnumVal=0, i; + _NV_TEMPLATE_ENUM (*pEnum)[ENUM_ENTRIES_MAX]; + int enumIdx = ((fieldStorageSizeLowByte & + FIELD_SIZE_VALUE_MASK) >> FIELD_SIZE_VALUE_LSB); + + if (nvBin) { + pEnum = NvEnumsFromBin; + } + else { + pEnum = NvEnumsBuiltIn; + } + + for (i = 0; i < ENUM_ENTRIES_MAX; i++) { + if (nul == pEnum[enumIdx][i].enumName[0]) { + if ( i == 0 ) { + maxEnumVal = 0; + } + else { + maxEnumVal = pEnum[enumIdx][i-1].enumValue; + } + break; + } + } + ret = (maxEnumVal + 1); + return ret; // +1 to count for 0 to maxEnumVal + } +} + +static int numElemArray1(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin) +{ + int fieldStorageSize = 0; + + fieldStorageSize = getNumElemOutOfStorageSize(_STORAGE_SIZE1( + pTableEntry->fieldStorageSize1, pTableEntry->fieldStorageType), + pTableEntry->fieldStorageSize1, nvBin); + + return fieldStorageSize; +} + +static int numElemArray2(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin) +{ + int fieldStorageSize1,fieldStorageSize2,fieldStorageSize; + + fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1( + pTableEntry->fieldStorageSize1, + pTableEntry->fieldStorageType), + pTableEntry->fieldStorageSize1, nvBin); + + fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2( + pTableEntry->fieldStorageSize2, + pTableEntry->fieldStorageType), + pTableEntry->fieldStorageSize2, nvBin); + + fieldStorageSize = fieldStorageSize1 * fieldStorageSize2; + + return fieldStorageSize; +} + +static int numElemArray3(_NV_TEMPLATE_TABLE *pTableEntry, int nvBin) +{ + int fieldStorageSize1,fieldStorageSize2,fieldStorageSize3,fieldStorageSize; + + fieldStorageSize1 = getNumElemOutOfStorageSize(_STORAGE_SIZE1( + pTableEntry->fieldStorageSize1, + pTableEntry->fieldStorageType), + pTableEntry->fieldStorageSize1, nvBin); + + fieldStorageSize2 = getNumElemOutOfStorageSize(_STORAGE_SIZE2( + pTableEntry->fieldStorageSize2, + pTableEntry->fieldStorageType), + pTableEntry->fieldStorageSize2, nvBin); + + fieldStorageSize3 = getNumElemOutOfStorageSize(_STORAGE_SIZE3( + pTableEntry->fieldStorageSize3, + pTableEntry->fieldStorageType), + pTableEntry->fieldStorageSize3, nvBin); + + fieldStorageSize = fieldStorageSize1 * fieldStorageSize2 * fieldStorageSize3; + + return fieldStorageSize; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/wlan_nv_stream_read.c b/drivers/staging/prima/CORE/VOSS/src/wlan_nv_stream_read.c new file mode 100644 index 000000000000..1cbc335585b7 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/wlan_nv_stream_read.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + when who what, where, why + -------- --- -------------------------------------------------------- + 04/10/13 kumarpra nv stream layer creation +===========================================================================*/ + +#include "vos_memory.h" +#include "wlan_nv_stream.h" + +_STREAM_BUF streamBuf; + +static tANI_U32 deCodeData(tANI_U8 *ipdata, tANI_U32 length, tANI_U8 *opdata, + tANI_U32 *currentIndex); + +/*---------------------------------------------------------------------------- + \brief initReadStream() - stream Initialization + This function will initialize stream read + \param readBuf, length - ptr to read Buffer, number of bytes + \return success on init + \sa +--------------------------------------------------------------------------*/ +_STREAM_RC initReadStream(tANI_U8 *readBuf, tANI_U32 length) +{ + _STREAM_RC rc = RC_SUCCESS; + streamBuf.currentIndex = 0; + streamBuf.totalLength = 0; + streamBuf.totalLength = length; + streamBuf.dataBuf = (_NV_STREAM_BUF *)&readBuf[0]; + return rc; +} + +/*---------------------------------------------------------------------------- + \brief nextStream() - get next Stream in buffer + This function will provide next stream in the buffere initalized + \param readBuf, length - ptr to stream length, stream data + \return success when stream length is non-zero else error + \sa +--------------------------------------------------------------------------*/ + +_STREAM_RC nextStream(tANI_U32 *length, tANI_U8 *dataBuf) +{ + _STREAM_RC rc = RC_SUCCESS; + + if (streamBuf.currentIndex >= streamBuf.totalLength) + { + *length = 0; + } + else + { + *length = deCodeData(&streamBuf.dataBuf[streamBuf.currentIndex], + (streamBuf.totalLength - streamBuf.currentIndex), dataBuf, + &streamBuf.currentIndex); + } + + if (*length == 0) + { + rc = RC_FAIL; + } + + return rc; +} + +/*---------------------------------------------------------------------------- + \brief decodeData() - decode the input data + This function will decode stream read + \param readBuf, length - ptr to input stream, length, output stream data, + \index pointer + \return success when stream length is non-zero else error + \sa +--------------------------------------------------------------------------*/ + +tANI_U32 deCodeData(tANI_U8 *ipdata, tANI_U32 length, tANI_U8 *opdata, + tANI_U32 *currentIndex) +{ + tANI_U16 oplength = 0; + + oplength = ipdata[0]; + oplength = oplength | (ipdata[1] << 8); + + vos_mem_copy(opdata, &ipdata[sizeof(tANI_U16)], oplength); + + *currentIndex = *currentIndex + sizeof(tANI_U16) + oplength; + + return oplength; +} diff --git a/drivers/staging/prima/CORE/VOSS/src/wlan_nv_template_builtin.c b/drivers/staging/prima/CORE/VOSS/src/wlan_nv_template_builtin.c new file mode 100644 index 000000000000..14c6eadf5242 --- /dev/null +++ b/drivers/staging/prima/CORE/VOSS/src/wlan_nv_template_builtin.c @@ -0,0 +1,848 @@ +/* + * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header:$ $DateTime: $ $Author: $ + + when who what, where, why + -------- --- ----------------------------------------------- + 04/10/13 kumarpra nv built in creation +===========================================================================*/ + + +/* + ----------------------------------------- + This file is generated by nvTmplRun Parser + ----------------------------------------- + To be auto-generated, or + This is the source file and the header file can be generated from this + template file. + + Template constructs + 1. TABLE_: struct + 2. INDEX_ENUM: enums, e.g. {RATE_OFDM_6M,RATE_OFDM_54M} + 3. INDEX_INT: int, e.g.{min, max, increment} + 3. Basic data types: tANI_U8, tANI_S8, tANI_U32, tANI_S32 + 4. Storage types: + 4.1 SINGULAR: one element of basic data type + 4.2 ARRAY_1: one dimensional array, x-axis + 4.3 ARRAY_2: two dimensional array, (x, y) + 4.4 ARRAY_3: three dimensional array, (x, y, z) + 4.5 ARRAY_4: four dimensional array, (x, y, z, t) + + Implementation notes + 1. Flow of changing NV data format: (TBD) Either change the template and + generate the header file, or modify header file and auto-generate + the template. + 2. Flow of writing NV data: encode the template in the data stream, so the + NV data is "self-sufficient". No separate template, no compability + issue, no need of version control. + 3. Flow of reading NV data: parse the binary NV data stream based on the + template info in the data stream. + 4. The above NV logic is decoupled from the actual data content, a generic, + content ergonostic parser (reading) and encoder (writing). + The NV logic is common code shared by tools, s/w + (both host and firmware), and off-line utilities. + 5. NV data parsing and "acceptanace" into an s/w moduel data structure can + be "configured" in several ways: + 5.1 only total matching of all fields, otherwise, reject the whole data + stream (a table). + 5.2 partial matching of fields allowed and the rest fields assume + reasonal default values, + The choice can be determined later, but the capability is provided. + 6. We could also design in this selection on an individual table base. + To design such capability, reserve some header bits in the data stream. + 7. The NV data streams can be modified, replaced, or intact with a new data + stream of the same table ID added to NV data. + The choice can be determined later, but the NV scheme provides such + capability. + 8. The template construct definitions can be common to all tables + (tbd: in a common section) or table specific, or updated in a + subsequent format section. + The use cases are: + - An index enum (e.g. RF channels) is common to all tables when the NV + data is created. Later new enums are added (e.g. + additional channels), one can choose to add the new index enum for new + tables appended to the NV data, or replace the + old table with new template info and data. + The template precedence is table specific then common, and later + "common" overwrites "earlier" commmon. + - A new field is added to the table, the user decides to replace the + old table data, he can simply encode the template info in the + data stream. + - In the same scenario (a new field is added), the user decides to + append a new table, he can encode the template + in the new data table and append it to NV data, or write a new common + template section and append the data. + + Key "ingredients", (re-iterate the most important features and capabilities) + 1. How to parse the data is embedded in the NV data itself. It removes the + dependency on header file matching, + version checking, compatibility among tools, host and firmware. + 2. Table field ID enables "partial" data acceptance in an s/w module data + structure. Whether full matching or reject the whole table, or "partial" + acceptance, the capabiilty is in place and further ensures the robust + NV data extensibility and compatibility. + 3. The table granularity, data stream based NV data has variable length + and flexibility of modifying an existing table data, replacing the + whole data, or leaving the existing data table intact and appending + a new table. + Misc notes: + 1. For endianness, support only 4 bytes integer or 4 1-byte + 2. String identifier needs to be shortened to save storage + 3. string_field_name, field type, field storage class, storage size +*/ + + +#include "wlan_nv_types.h" +#include "wlan_nv_stream.h" +#include "wlan_nv.h" +#include "wlan_nv_template_internal.h" +#include "wlan_nv_template_api.h" +#include "wlan_nv_template_builtin.h" + + + +static int enumNoOfFieldArray[INDEX_ENUM_BUILTIN_MAX] = + {7,1,9,5,40,14,3,55}; + +_NV_TEMPLATE_ENUM NvEnumsBuiltIn[/*INDEX_ENUM_MAX*/][ENUM_ENTRIES_MAX] = { + { // INDEX_ENUM_ALL + {"j1",INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS,0,{nul}}, + {"j2",INDEX_ENUM_NUM_REG_DOMAINS,0,{nul}}, + {"j3",INDEX_ENUM_NUM_RF_SUBBANDS,0,{nul}}, + {"j4",INDEX_ENUM_NUM_RF_CHANNELS,0,{nul}}, + {"j5",INDEX_ENUM_NUM_2_4GHZ_CHANNELS,0,{nul}}, + {"j6",INDEX_ENUM_NUM_802_11_MODES,0,{nul}}, + {"j7",INDEX_ENUM_NUM_HAL_PHY_RATES,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_ALL + + { // INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS + {"a1",PHY_TX_CHAIN_0,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS + + { // INDEX_ENUM_NUM_REG_DOMAINS + {"a3",REG_DOMAIN_FCC,0,{nul}}, + {"a4",REG_DOMAIN_ETSI,0,{nul}}, + {"a5",REG_DOMAIN_JAPAN,0,{nul}}, + {"a6",REG_DOMAIN_WORLD,0,{nul}}, + {"a7",REG_DOMAIN_N_AMER_EXC_FCC,0,{nul}}, + {"a8",REG_DOMAIN_APAC,0,{nul}}, + {"a9",REG_DOMAIN_KOREA,0,{nul}}, + {"ba",REG_DOMAIN_HI_5GHZ,0,{nul}}, + {"bb",REG_DOMAIN_NO_5GHZ,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_REG_DOMAINS + + { // INDEX_ENUM_NUM_RF_SUBBANDS + {"bd",RF_SUBBAND_2_4_GHZ,0,{nul}}, + {"be",RF_SUBBAND_5_LOW_GHZ,0,{nul}}, + {"bf",RF_SUBBAND_5_MID_GHZ,0,{nul}}, + {"bg",RF_SUBBAND_5_HIGH_GHZ,0,{nul}}, + {"bh",RF_SUBBAND_4_9_GHZ,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_RF_SUBBANDS + + { // INDEX_ENUM_NUM_RF_CHANNELS + {"bj",RF_CHAN_1,0,{nul}}, + {"bk",RF_CHAN_2,0,{nul}}, + {"bl",RF_CHAN_3,0,{nul}}, + {"bm",RF_CHAN_4,0,{nul}}, + {"bn",RF_CHAN_5,0,{nul}}, + {"bo",RF_CHAN_6,0,{nul}}, + {"bp",RF_CHAN_7,0,{nul}}, + {"bq",RF_CHAN_8,0,{nul}}, + {"br",RF_CHAN_9,0,{nul}}, + {"bs",RF_CHAN_10,0,{nul}}, + {"bt",RF_CHAN_11,0,{nul}}, + {"bu",RF_CHAN_12,0,{nul}}, + {"bv",RF_CHAN_13,0,{nul}}, + {"bw",RF_CHAN_14,0,{nul}}, + {"bx",RF_CHAN_240,0,{nul}}, + {"by",RF_CHAN_244,0,{nul}}, + {"bz",RF_CHAN_248,0,{nul}}, + {"b0",RF_CHAN_252,0,{nul}}, + {"b1",RF_CHAN_208,0,{nul}}, + {"b2",RF_CHAN_212,0,{nul}}, + {"b3",RF_CHAN_216,0,{nul}}, + {"b4",RF_CHAN_36,0,{nul}}, + {"b5",RF_CHAN_40,0,{nul}}, + {"b6",RF_CHAN_44,0,{nul}}, + {"b7",RF_CHAN_48,0,{nul}}, + {"b8",RF_CHAN_52,0,{nul}}, + {"b9",RF_CHAN_56,0,{nul}}, + {"ca",RF_CHAN_60,0,{nul}}, + {"cb",RF_CHAN_64,0,{nul}}, + {"cc",RF_CHAN_100,0,{nul}}, + {"cd",RF_CHAN_104,0,{nul}}, + {"ce",RF_CHAN_108,0,{nul}}, + {"cf",RF_CHAN_112,0,{nul}}, + {"cg",RF_CHAN_116,0,{nul}}, + {"ch",RF_CHAN_120,0,{nul}}, + {"ci",RF_CHAN_124,0,{nul}}, + {"cj",RF_CHAN_128,0,{nul}}, + {"ck",RF_CHAN_132,0,{nul}}, + {"cl",RF_CHAN_136,0,{nul}}, + {"cm",RF_CHAN_140,0,{nul}}, +#ifdef FEATURE_WLAN_CH144 + {"kt",RF_CHAN_144,0,{nul}}, +#endif /* FEATURE_WLAN_CH144 */ + {"cn",RF_CHAN_149,0,{nul}}, + {"co",RF_CHAN_153,0,{nul}}, + {"cp",RF_CHAN_157,0,{nul}}, + {"cq",RF_CHAN_161,0,{nul}}, + {"cr",RF_CHAN_165,0,{nul}}, + {"cs",RF_CHAN_BOND_3,0,{nul}}, + {"ct",RF_CHAN_BOND_4,0,{nul}}, + {"cu",RF_CHAN_BOND_5,0,{nul}}, + {"cv",RF_CHAN_BOND_6,0,{nul}}, + {"cw",RF_CHAN_BOND_7,0,{nul}}, + {"cx",RF_CHAN_BOND_8,0,{nul}}, + {"cy",RF_CHAN_BOND_9,0,{nul}}, + {"cz",RF_CHAN_BOND_10,0,{nul}}, + {"c0",RF_CHAN_BOND_11,0,{nul}}, + {"c1",RF_CHAN_BOND_242,0,{nul}}, + {"c2",RF_CHAN_BOND_246,0,{nul}}, + {"c3",RF_CHAN_BOND_250,0,{nul}}, + {"c4",RF_CHAN_BOND_210,0,{nul}}, + {"c5",RF_CHAN_BOND_214,0,{nul}}, + {"c6",RF_CHAN_BOND_38,0,{nul}}, + {"c7",RF_CHAN_BOND_42,0,{nul}}, + {"c8",RF_CHAN_BOND_46,0,{nul}}, + {"c9",RF_CHAN_BOND_50,0,{nul}}, + {"da",RF_CHAN_BOND_54,0,{nul}}, + {"db",RF_CHAN_BOND_58,0,{nul}}, + {"dc",RF_CHAN_BOND_62,0,{nul}}, + {"dd",RF_CHAN_BOND_102,0,{nul}}, + {"de",RF_CHAN_BOND_106,0,{nul}}, + {"df",RF_CHAN_BOND_110,0,{nul}}, + {"dg",RF_CHAN_BOND_114,0,{nul}}, + {"dh",RF_CHAN_BOND_118,0,{nul}}, + {"di",RF_CHAN_BOND_122,0,{nul}}, + {"dj",RF_CHAN_BOND_126,0,{nul}}, + {"dk",RF_CHAN_BOND_130,0,{nul}}, + {"dl",RF_CHAN_BOND_134,0,{nul}}, + {"dm",RF_CHAN_BOND_138,0,{nul}}, +#ifdef FEATURE_WLAN_CH144 + {"ku",RF_CHAN_BOND_142,0,{nul}}, +#endif /* FEATURE_WLAN_CH144 */ + {"dn",RF_CHAN_BOND_151,0,{nul}}, + {"do",RF_CHAN_BOND_155,0,{nul}}, + {"dp",RF_CHAN_BOND_159,0,{nul}}, + {"dq",RF_CHAN_BOND_163,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_RF_CHANNELS + + { // INDEX_ENUM_NUM_2_4GHZ_CHANNELS + {"ke",RF_CHAN_1_1,0,{nul}}, + {"kf",RF_CHAN_2_1,0,{nul}}, + {"kg",RF_CHAN_3_1,0,{nul}}, + {"kh",RF_CHAN_4_1,0,{nul}}, + {"ki",RF_CHAN_5_1,0,{nul}}, + {"kj",RF_CHAN_6_1,0,{nul}}, + {"kk",RF_CHAN_7_1,0,{nul}}, + {"kl",RF_CHAN_8_1,0,{nul}}, + {"km",RF_CHAN_9_1,0,{nul}}, + {"kn",RF_CHAN_10_1,0,{nul}}, + {"ko",RF_CHAN_11_1,0,{nul}}, + {"kp",RF_CHAN_12_1,0,{nul}}, + {"kq",RF_CHAN_13_1,0,{nul}}, + {"kr",RF_CHAN_14_1,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_2_4GHZ_CHANNELS + + { // INDEX_ENUM_NUM_802_11_MODES + {"d6",MODE_802_11B,0,{nul}}, + {"d7",MODE_802_11AG,0,{nul}}, + {"d8",MODE_802_11N,0,{nul}}, + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_802_11_MODES + + { // INDEX_ENUM_NUM_HAL_PHY_RATES + {"ez",HAL_PHY_RATE_11B_LONG_1_MBPS,0,{nul}}, + {"e0",HAL_PHY_RATE_11B_LONG_2_MBPS,0,{nul}}, + {"e1",HAL_PHY_RATE_11B_LONG_5_5_MBPS,0,{nul}}, + {"e2",HAL_PHY_RATE_11B_LONG_11_MBPS,0,{nul}}, + {"e3",HAL_PHY_RATE_11B_SHORT_2_MBPS,0,{nul}}, + {"e4",HAL_PHY_RATE_11B_SHORT_5_5_MBPS,0,{nul}}, + {"e5",HAL_PHY_RATE_11B_SHORT_11_MBPS,0,{nul}}, + {"e6",HAL_PHY_RATE_11A_6_MBPS,0,{nul}}, + {"e7",HAL_PHY_RATE_11A_9_MBPS,0,{nul}}, + {"e8",HAL_PHY_RATE_11A_12_MBPS,0,{nul}}, + {"e9",HAL_PHY_RATE_11A_18_MBPS,0,{nul}}, + {"fa",HAL_PHY_RATE_11A_24_MBPS,0,{nul}}, + {"fb",HAL_PHY_RATE_11A_36_MBPS,0,{nul}}, + {"fc",HAL_PHY_RATE_11A_48_MBPS,0,{nul}}, + {"fd",HAL_PHY_RATE_11A_54_MBPS,0,{nul}}, + {"fe",HAL_PHY_RATE_11A_DUP_6_MBPS,0,{nul}}, + {"ff",HAL_PHY_RATE_11A_DUP_9_MBPS,0,{nul}}, + {"fg",HAL_PHY_RATE_11A_DUP_12_MBPS,0,{nul}}, + {"fh",HAL_PHY_RATE_11A_DUP_18_MBPS,0,{nul}}, + {"fi",HAL_PHY_RATE_11A_DUP_24_MBPS,0,{nul}}, + {"fj",HAL_PHY_RATE_11A_DUP_36_MBPS,0,{nul}}, + {"fk",HAL_PHY_RATE_11A_DUP_48_MBPS,0,{nul}}, + {"fl",HAL_PHY_RATE_11A_DUP_54_MBPS,0,{nul}}, + {"fm",HAL_PHY_RATE_MCS_1NSS_6_5_MBPS,0,{nul}}, + {"fn",HAL_PHY_RATE_MCS_1NSS_13_MBPS,0,{nul}}, + {"fo",HAL_PHY_RATE_MCS_1NSS_19_5_MBPS,0,{nul}}, + {"fp",HAL_PHY_RATE_MCS_1NSS_26_MBPS,0,{nul}}, + {"fq",HAL_PHY_RATE_MCS_1NSS_39_MBPS,0,{nul}}, + {"fr",HAL_PHY_RATE_MCS_1NSS_52_MBPS,0,{nul}}, + {"fs",HAL_PHY_RATE_MCS_1NSS_58_5_MBPS,0,{nul}}, + {"ft",HAL_PHY_RATE_MCS_1NSS_65_MBPS,0,{nul}}, + {"fu",HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS,0,{nul}}, + {"fv",HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS,0,{nul}}, + {"fw",HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS,0,{nul}}, + {"fx",HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS,0,{nul}}, + {"fy",HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS,0,{nul}}, + {"fz",HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS,0,{nul}}, + {"f0",HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS,0,{nul}}, + {"f1",HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS,0,{nul}}, + {"f2",HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS,0,{nul}}, + {"f3",HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS,0,{nul}}, + {"f4",HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS,0,{nul}}, + {"f5",HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS,0,{nul}}, + {"f6",HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS,0,{nul}}, + {"f7",HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS,0,{nul}}, + {"f8",HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS,0,{nul}}, + {"f9",HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS,0,{nul}}, + {"ga",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS,0,{nul}}, + {"gb",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS,0,{nul}}, + {"gc",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS,0,{nul}}, + {"gd",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS,0,{nul}}, + {"ge",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS,0,{nul}}, + {"gf",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS,0,{nul}}, + {"gg",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS,0,{nul}}, + {"gh",HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS,0,{nul}}, +#ifdef WLAN_FEATURE_11AC + {"gj",HAL_PHY_RATE_11AC_DUP_6_MBPS,0,{nul}}, + {"gk",HAL_PHY_RATE_11AC_DUP_9_MBPS,0,{nul}}, + {"gl",HAL_PHY_RATE_11AC_DUP_12_MBPS,0,{nul}}, + {"gm",HAL_PHY_RATE_11AC_DUP_18_MBPS,0,{nul}}, + {"gn",HAL_PHY_RATE_11AC_DUP_24_MBPS,0,{nul}}, + {"go",HAL_PHY_RATE_11AC_DUP_36_MBPS,0,{nul}}, + {"gp",HAL_PHY_RATE_11AC_DUP_48_MBPS,0,{nul}}, + {"gq",HAL_PHY_RATE_11AC_DUP_54_MBPS,0,{nul}}, + {"gr",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_6_5_MBPS,0,{nul}}, + {"gs",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_13_MBPS,0,{nul}}, + {"gt",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_19_5_MBPS,0,{nul}}, + {"gu",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_26_MBPS,0,{nul}}, + {"gv",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_39_MBPS,0,{nul}}, + {"gw",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_52_MBPS,0,{nul}}, + {"gx",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_58_5_MBPS,0,{nul}}, + {"gy",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_65_MBPS,0,{nul}}, + {"gz",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_78_MBPS,0,{nul}}, +#ifdef WCN_PRONTO + {"j8",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS,0,{nul}}, +#endif + {"g0",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_7_2_MBPS,0,{nul}}, + {"g1",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_14_4_MBPS,0,{nul}}, + {"g2",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_21_6_MBPS,0,{nul}}, + {"g3",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_28_8_MBPS,0,{nul}}, + {"g4",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_43_3_MBPS,0,{nul}}, + {"g5",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_57_7_MBPS,0,{nul}}, + {"g6",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_65_MBPS,0,{nul}}, + {"g7",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_72_2_MBPS,0,{nul}}, + {"g8",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_86_6_MBPS,0,{nul}}, +#ifdef WCN_PRONTO + {"j9",HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS,0,{nul}}, +#endif + {"g9",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS,0,{nul}}, + {"ha",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS,0,{nul}}, + {"hb",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS,0,{nul}}, + {"hc",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS,0,{nul}}, + {"hd",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS,0,{nul}}, + {"he",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS,0,{nul}}, + {"hf",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS,0,{nul}}, + {"hg",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS,0,{nul}}, + {"hh",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS,0,{nul}}, + {"hi",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS,0,{nul}}, + {"hj",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS,0,{nul}}, + {"hk",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS,0,{nul}}, + {"hl",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS,0,{nul}}, + {"hm",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS,0,{nul}}, + {"hn",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS,0,{nul}}, + {"ho",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS,0,{nul}}, + {"hp",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS,0,{nul}}, + {"hq",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS,0,{nul}}, + {"hr",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS,0,{nul}}, + {"hs",HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS,0,{nul}}, + {"ht",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS,0,{nul}}, + {"hu",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS,0,{nul}}, + {"hv",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS,0,{nul}}, + {"hw",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS,0,{nul}}, + {"hx",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS,0,{nul}}, + {"hy",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS,0,{nul}}, + {"hz",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS,0,{nul}}, + {"h0",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS,0,{nul}}, + {"h1",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS,0,{nul}}, + {"h2",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS,0,{nul}}, + {"h3",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS,0,{nul}}, + {"h4",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS,0,{nul}}, + {"h5",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS,0,{nul}}, + {"h6",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS,0,{nul}}, + {"h7",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS,0,{nul}}, + {"h8",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS,0,{nul}}, + {"h9",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS,0,{nul}}, + {"ia",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS,0,{nul}}, + {"ib",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS,0,{nul}}, + {"ic",HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS,0,{nul}}, +#endif + {{nul},0, 0,{nul}}, + }, // INDEX_ENUM_NUM_HAL_PHY_RATES + + { //INDEX_ENUM_LAST + {{nul},0, 0,{nul}}, + }, //INDEX_ENUM_LAST +}; // END _NV_TEMPLATE_ENUM + + +int getEnumNoOfFields(int enumIdx){ +#ifdef FEATURE_WLAN_CH144 + enumNoOfFieldArray[4] = enumNoOfFieldArray[4] + 1; +#endif + enumNoOfFieldArray[4] = enumNoOfFieldArray[4] + 36; +#ifdef FEATURE_WLAN_CH144 + enumNoOfFieldArray[4] = enumNoOfFieldArray[4] + 1; +#endif +#ifdef WLAN_FEATURE_11AC + enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 17; +#ifdef WCN_PRONTO + enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 1; +#endif + enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 9; +#ifdef WCN_PRONTO + enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 1; +#endif + enumNoOfFieldArray[7] = enumNoOfFieldArray[7] + 40; +#endif + + return enumNoOfFieldArray[enumIdx]; +} + + +static int tableNoOfFieldArray[TABLE_BUILTIN_MAX] = + {14,12,2,2,16,1,2,2,23,1,1,1,4,2,13}; + +_NV_TEMPLATE_TABLE NvTablesBuiltIn[/*TABLES_MAX*/][TABLE_ENTRIES_MAX] = { + { // TABLE_sHalNv + {"jz",_TABLE_IDX(TABLE_sNvFields),SINGULAR,0,0,0, + ((char *)&(nvDefaults.fields) - (char *)&nvDefaults),"fields"}, + {"jm",_TABLE_IDX(TABLE_tRateGroupPwr),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0, + ((char *)&(nvDefaults.tables.pwrOptimum[0]) - (char *)&nvDefaults.tables), + "pwrOptimum"}, + {"dx",_TABLE_IDX(TABLE_sRegulatoryChannel),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0].channels[0]) - + (char *)&nvDefaults.tables.regDomains[0]),"channels"}, + {"jn",_TABLE_IDX(TABLE_sRegulatoryDomains),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_REG_DOMAINS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0]) - (char *)&nvDefaults.tables), + "regDomains"}, + {"jo",_TABLE_IDX(TABLE_sDefaultCountry),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.defaultCountryTable) - + (char *)&nvDefaults.tables),"defaultCountryTable"}, + {"jp",_TABLE_IDX(TABLE_tTpcPowerTable),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.plutCharacterized[0]) - + (char *)&nvDefaults.tables),"plutCharacterized"}, + {"jr",_TABLE_IDX(TABLE_tRateGroupPwrVR),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0, + ((char *)&(nvDefaults.tables.pwrOptimum_virtualRate[0]) - + (char *)&nvDefaults.tables),"pwrOptimum_virtualRate"}, + {"js",_TABLE_IDX(TABLE_sFwConfig),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig) - (char *)&nvDefaults.tables), + "fwConfig"}, + {"jt",_TABLE_IDX(TABLE_sRssiChannelOffsets),(_ADD_SIZE1(2)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|(FIELD_SIZE_VALUE_BITS(2))), + 0,0,((char *)&(nvDefaults.tables.rssiChanOffsets[0]) - + (char *)&nvDefaults.tables),"rssiChanOffsets"}, + {"er",_TABLE_IDX(TABLE_sCalData),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData) - + (char *)&nvDefaults.tables.hwCalValues),"calData"}, + {"ju",_TABLE_IDX(TABLE_sHwCalValues),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues) - (char *)&nvDefaults.tables), + "hwCalValues"}, + {"jx",_TABLE_IDX(TABLE_sOfdmCmdPwrOffset),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.ofdmCmdPwrOffset) - (char *)&nvDefaults.tables), + "ofdmCmdPwrOffset"}, + {"jy",_TABLE_IDX(TABLE_sTxBbFilterMode),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.txbbFilterMode) - (char *)&nvDefaults.tables), + "txbbFilterMode"}, + {"j0",_TABLE_IDX(TABLE_sNvTables),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables) - (char *)&nvDefaults),"tables"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sHalNv + + { // TABLE_sNvFields + {"ap",_ID_U16,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.productId) - + (char *)&nvDefaults.fields),"productId"}, + {"aq",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.productBands) - + (char *)&nvDefaults.fields),"productBands"}, + {"ar",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.wlanNvRevId) - + (char *)&nvDefaults.fields),"wlanNvRevId"}, + {"as",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.numOfTxChains) - + (char *)&nvDefaults.fields),"numOfTxChains"}, + {"at",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.numOfRxChains) - + (char *)&nvDefaults.fields),"numOfRxChains"}, + {"au",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0, + ((char *)&(nvDefaults.fields.macAddr[0]) - (char *)&nvDefaults.fields), + "macAddr"}, + {"av",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0, + ((char *)&(nvDefaults.fields.macAddr2[0]) - (char *)&nvDefaults.fields), + "macAddr2"}, + {"aw",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0, + ((char *)&(nvDefaults.fields.macAddr3[0]) - (char *)&nvDefaults.fields), + "macAddr3"}, + {"ax",_ID_U8,(_ADD_SIZE1(NV_FIELD_MAC_ADDR_SIZE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NV_FIELD_MAC_ADDR_SIZE))),0,0, + ((char *)&(nvDefaults.fields.macAddr4[0]) - (char *)&nvDefaults.fields), + "macAddr4"}, + {"ay",_ID_U8,(_ADD_SIZE1(NV_FIELD_MFG_SN_SIZE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NV_FIELD_MFG_SN_SIZE))),0,0, + ((char *)&(nvDefaults.fields.mfgSN[0]) - (char *)&nvDefaults.fields),"mfgSN"} + , + {"az",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.couplerType) - + (char *)&nvDefaults.fields),"couplerType"}, + {"a0",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.fields.nvVersion) - + (char *)&nvDefaults.fields),"nvVersion"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sNvFields + + { // TABLE_sRegulatoryChannel + {"dv",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.regDomains[0].channels[0].enabled) - + (char *)&nvDefaults.tables.regDomains[0].channels[0]),"enabled"}, + {"dw",_ID_S8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.regDomains[0].channels[0].pwrLimit) - + (char *)&nvDefaults.tables.regDomains[0].channels[0]),"pwrLimit"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sRegulatoryChannel + + { // TABLE_sRssiChannelOffsets + {"d1",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.rssiChanOffsets[0].bRssiOffset[0]) - + (char *)&nvDefaults.tables.rssiChanOffsets[0]),"bRssiOffset"}, + {"d2",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.rssiChanOffsets[0].gnRssiOffset[0]) - + (char *)&nvDefaults.tables.rssiChanOffsets[0]),"gnRssiOffset"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sRssiChannelOffsets + + { // TABLE_sCalData + {"ea",_ID_U16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHd2G) - + (char *)&nvDefaults.tables.hwCalValues.calData),"psSlpTimeOvrHd2G"}, + {"eb",_ID_U16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHd5G) - + (char *)&nvDefaults.tables.hwCalValues.calData),"psSlpTimeOvrHd5G"}, + {"ec",_ID_U16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHdxLNA5G) - + (char *)&nvDefaults.tables.hwCalValues.calData),"psSlpTimeOvrHdxLNA5G"}, + {"ed",_ID_U8,SINGULAR,0,0,0, + (((char *)&(nvDefaults.tables.hwCalValues.calData.psSlpTimeOvrHdxLNA5G) + + sizeof(uint16)) - (char *)&nvDefaults.tables.hwCalValues.calData), + "nv_TxBBFSel9MHz"}, + {"ee",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam2) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam2"}, + {"ef",_ID_U16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.custom_tcxo_reg8) - + (char *)&nvDefaults.tables.hwCalValues.calData),"custom_tcxo_reg8"}, + {"eg",_ID_U16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.custom_tcxo_reg9) - + (char *)&nvDefaults.tables.hwCalValues.calData),"custom_tcxo_reg9"}, + {"eh",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam3) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam3"}, + {"ei",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam4) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam4"}, + {"ej",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam5) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam5"}, + {"ek",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam6) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam6"}, + {"el",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam7) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam7"}, + {"em",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam8) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam8"}, + {"en",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam9) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam9"}, + {"eo",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam10) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam10"}, + {"ep",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData.hwParam11) - + (char *)&nvDefaults.tables.hwCalValues.calData),"hwParam11"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sCalData + + { // TABLE_sTxBbFilterMode + {"es",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.txbbFilterMode.txFirFilterMode) - + (char *)&nvDefaults.tables.txbbFilterMode),"txFirFilterMode"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sTxBbFilterMode + + { // TABLE_sOfdmCmdPwrOffset + {"et",_ID_S16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.ofdmCmdPwrOffset.ofdmPwrOffset) - + (char *)&nvDefaults.tables.ofdmCmdPwrOffset),"ofdmPwrOffset"}, + {"eu",_ID_S16,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.ofdmCmdPwrOffset.rsvd) - + (char *)&nvDefaults.tables.ofdmCmdPwrOffset),"rsvd"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sOfdmCmdPwrOffset + + { // TABLE_sDefaultCountry + {"if",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.defaultCountryTable.regDomain) - + (char *)&nvDefaults.tables.defaultCountryTable),"regDomain"}, + {"ig",_ID_U8,(_ADD_SIZE1(NV_FIELD_COUNTRY_CODE_SIZE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NV_FIELD_COUNTRY_CODE_SIZE))),0,0, + ((char *)&(nvDefaults.tables.defaultCountryTable.countryCode[0]) - + (char *)&nvDefaults.tables.defaultCountryTable),"countryCode"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sDefaultCountry + + { // TABLE_sFwConfig + {"ih",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.skuID) - + (char *)&nvDefaults.tables.fwConfig),"skuID"}, + {"ii",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.tpcMode2G) + - (char *)&nvDefaults.tables.fwConfig),"tpcMode2G"}, + {"ij",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.tpcMode5G) + - (char *)&nvDefaults.tables.fwConfig),"tpcMode5G"}, + {"ik",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.configItem1) - + (char *)&nvDefaults.tables.fwConfig),"configItem1"}, + {"il",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xPA2G) - + (char *)&nvDefaults.tables.fwConfig),"xPA2G"}, + {"im",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xPA5G) - + (char *)&nvDefaults.tables.fwConfig),"xPA5G"}, + {"in",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.extPaCtrl0Polarity) - + (char *)&nvDefaults.tables.fwConfig),"extPaCtrl0Polarity"}, + {"io",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.extPaCtrl1Polarity) - + (char *)&nvDefaults.tables.fwConfig),"extPaCtrl1Polarity"}, + {"ip",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xLNA2G) - + (char *)&nvDefaults.tables.fwConfig),"xLNA2G"}, + {"iq",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xLNA5G) - + (char *)&nvDefaults.tables.fwConfig),"xLNA5G"}, + {"ir",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xCoupler2G) + - (char *)&nvDefaults.tables.fwConfig),"xCoupler2G"}, + {"is",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xCoupler5G) + - (char *)&nvDefaults.tables.fwConfig),"xCoupler5G"}, + {"it",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xPdet2G) - + (char *)&nvDefaults.tables.fwConfig),"xPdet2G"}, + {"iu",_ID_U8,SINGULAR,0,0,0,((char *)&(nvDefaults.tables.fwConfig.xPdet5G) - + (char *)&nvDefaults.tables.fwConfig),"xPdet5G"}, + {"iv",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.enableDPD2G) - + (char *)&nvDefaults.tables.fwConfig),"enableDPD2G"}, + {"iw",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.enableDPD5G) - + (char *)&nvDefaults.tables.fwConfig),"enableDPD5G"}, + {"ix",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.pdadcSelect2G) - + (char *)&nvDefaults.tables.fwConfig),"pdadcSelect2G"}, + {"iy",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.pdadcSelect5GLow) - + (char *)&nvDefaults.tables.fwConfig),"pdadcSelect5GLow"}, + {"iz",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.pdadcSelect5GMid) - + (char *)&nvDefaults.tables.fwConfig),"pdadcSelect5GMid"}, + {"i0",_ID_U8,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.pdadcSelect5GHigh) - + (char *)&nvDefaults.tables.fwConfig),"pdadcSelect5GHigh"}, + {"i1",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.configItem2) - + (char *)&nvDefaults.tables.fwConfig),"configItem2"}, + {"i2",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.configItem3) - + (char *)&nvDefaults.tables.fwConfig),"configItem3"}, + {"i3",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig.configItem4) - + (char *)&nvDefaults.tables.fwConfig),"configItem4"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sFwConfig + + { // TABLE_tTpcPowerTable + {"kc",_ID_U8,(_ADD_SIZE2(TPC_MEM_POWER_LUT_DEPTH)|ARRAY_2), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_PHY_MAX_TX_CHAINS))), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(TPC_MEM_POWER_LUT_DEPTH))),0, + ((char *)&(nvDefaults.tables.plutCharacterized[0]) - + (char *)&nvDefaults.tables.plutCharacterized[0]),"tTpcPowerTable"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_tTpcPowerTable + + { // TABLE_tRateGroupPwr + {"kb",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_HAL_PHY_RATES))),0,0, + ((char *)&(nvDefaults.tables.pwrOptimum[0]) - + (char *)&nvDefaults.tables.pwrOptimum[0]),"tRateGroupPwr"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_tRateGroupPwr + + { // TABLE_tRateGroupPwrVR + {"kd",_ID_U32,(_ADD_SIZE1(NUM_RF_VR_RATE)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))| + (FIELD_SIZE_VALUE_BITS(NUM_RF_VR_RATE))),0,0, + ((char *)&(nvDefaults.tables.pwrOptimum_virtualRate[0]) - + (char *)&nvDefaults.tables.pwrOptimum_virtualRate[0]),"tRateGroupPwrVR"}, + + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_tRateGroupPwrVR + + { // TABLE_sRegulatoryDomains + {"dx",_TABLE_IDX(TABLE_sRegulatoryChannel),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0].channels[0]) - + (char *)&nvDefaults.tables.regDomains[0]),"channels"}, + {"dy",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0].antennaGain[0]) - + (char *)&nvDefaults.tables.regDomains[0]),"antennaGain"}, + {"dz",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_2_4GHZ_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0].bRatePowerOffset[0]) - + (char *)&nvDefaults.tables.regDomains[0]),"bRatePowerOffset"}, + {"d0",_ID_U32,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0].gnRatePowerOffset[0]) - + (char *)&nvDefaults.tables.regDomains[0]),"gnRatePowerOffset"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sRegulatoryDomains + + { // TABLE_sHwCalValues + {"eq",_ID_U32,SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.validBmap) - + (char *)&nvDefaults.tables.hwCalValues),"validBmap"}, + {"er",_TABLE_IDX(TABLE_sCalData),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues.calData) - + (char *)&nvDefaults.tables.hwCalValues),"calData"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sHwCalValues + + { // TABLE_sNvTables + {"jm",_TABLE_IDX(TABLE_tRateGroupPwr),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0, + ((char *)&(nvDefaults.tables.pwrOptimum[0]) - (char *)&nvDefaults.tables), + "pwrOptimum"}, + {"jn",_TABLE_IDX(TABLE_sRegulatoryDomains),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_REG_DOMAINS))),0,0, + ((char *)&(nvDefaults.tables.regDomains[0]) - (char *)&nvDefaults.tables), + "regDomains"}, + {"jo",_TABLE_IDX(TABLE_sDefaultCountry),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.defaultCountryTable) - + (char *)&nvDefaults.tables),"defaultCountryTable"}, + {"jp",_TABLE_IDX(TABLE_tTpcPowerTable),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.plutCharacterized[0]) - + (char *)&nvDefaults.tables),"plutCharacterized"}, + {"jq",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.plutPdadcOffset[0]) - + (char *)&nvDefaults.tables),"plutPdadcOffset"}, + {"jr",_TABLE_IDX(TABLE_tRateGroupPwrVR),(ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_SUBBANDS))),0,0, + ((char *)&(nvDefaults.tables.pwrOptimum_virtualRate[0]) - + (char *)&nvDefaults.tables),"pwrOptimum_virtualRate"}, + {"js",_TABLE_IDX(TABLE_sFwConfig),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.fwConfig) - (char *)&nvDefaults.tables), + "fwConfig"}, + {"jt",_TABLE_IDX(TABLE_sRssiChannelOffsets),(_ADD_SIZE1(2)|ARRAY_1), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_INT))|(FIELD_SIZE_VALUE_BITS(2))), + 0,0,((char *)&(nvDefaults.tables.rssiChanOffsets[0]) - + (char *)&nvDefaults.tables),"rssiChanOffsets"}, + {"ju",_TABLE_IDX(TABLE_sHwCalValues),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.hwCalValues) - (char *)&nvDefaults.tables), + "hwCalValues"}, + {"jv",_ID_S16,(ARRAY_1),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0,0, + ((char *)&(nvDefaults.tables.antennaPathLoss[0]) - + (char *)&nvDefaults.tables),"antennaPathLoss"}, + {"jw",_ID_S16,(ARRAY_2),((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_802_11_MODES))), + ((FIELD_SIZE_TYPE_BIT(FIELD_SIZE_IDX_ENUM))| + (FIELD_SIZE_VALUE_BITS(INDEX_ENUM_NUM_RF_CHANNELS))),0, + ((char *)&(nvDefaults.tables.pktTypePwrLimits[0][0]) - + (char *)&nvDefaults.tables),"pktTypePwrLimits"}, + {"jx",_TABLE_IDX(TABLE_sOfdmCmdPwrOffset),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.ofdmCmdPwrOffset) - (char *)&nvDefaults.tables), + "ofdmCmdPwrOffset"}, + {"jy",_TABLE_IDX(TABLE_sTxBbFilterMode),SINGULAR,0,0,0, + ((char *)&(nvDefaults.tables.txbbFilterMode) - (char *)&nvDefaults.tables), + "txbbFilterMode"}, + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, // TABLE_sNvTables + + { //INDEX_TABLE_LAST + {{nul}, 0, 0, 0, 0, 0, 0,{nul}}, + }, //INDEX_TABLE_LAST +}; // END _NV_TEMPLATE_TABLE + +int getTableNoOfFields(int tblIdx) +{ + return tableNoOfFieldArray[tblIdx]; +} diff --git a/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h b/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h new file mode 100644 index 000000000000..83d0267f8df5 --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/inc/legacy/halMsgApi.h @@ -0,0 +1,1449 @@ +/* + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + +#ifndef _HALMSGAPI_H_ +#define _HALMSGAPI_H_ + +#include "halTypes.h" +#include "sirApi.h" +#include "sirParams.h" + +#define HAL_NUM_BSSID 2 +/* operMode in ADD BSS message */ +#define BSS_OPERATIONAL_MODE_AP 0 +#define BSS_OPERATIONAL_MODE_STA 1 + +/* STA entry type in add sta message */ +#define STA_ENTRY_SELF 0 +#define STA_ENTRY_OTHER 1 +#define STA_ENTRY_BSSID 2 +#define STA_ENTRY_BCAST 3 //Special station id for transmitting broadcast frames. +#define STA_ENTRY_PEER STA_ENTRY_OTHER +#ifdef FEATURE_WLAN_TDLS +#define STA_ENTRY_TDLS_PEER 4 +#endif /* FEATURE_WLAN_TDLS */ + +#define STA_ENTRY_TRANSMITTER STA_ENTRY_SELF +#define STA_ENTRY_RECEIVER STA_ENTRY_OTHER + +#define HAL_STA_INVALID_IDX 0xFF +#define HAL_BSS_INVALID_IDX 0xFF + +#define HAL_BSSPERSONA_INVALID_IDX 0xFF + +#define WLAN_BSS_PROTECTION_ON 1 +#define WLAN_BSS_PROTECTION_OFF 0 + +/* Station index allocation after Broadcast station */ +#define HAL_MAX_NUM_BCAST_STATIONS 1 +#define HAL_MIN_BCAST_STA_INDEX ((HAL_MAX_NUM_BCAST_STATIONS>0)?0:HAL_STA_INVALID_IDX) +#define HAL_MAX_BCAST_STA_INDEX ((HAL_MAX_NUM_BCAST_STATIONS>0)?(HAL_MAX_NUM_BCAST_STATIONS - 1):HAL_STA_INVALID_IDX) +#define HAL_MIN_STA_INDEX ((HAL_MAX_BCAST_STA_INDEX!=HAL_STA_INVALID_IDX)?(HAL_MAX_BCAST_STA_INDEX+1):0) +#define HAL_MAX_STA_INDEX (HAL_NUM_STA) + +/* Compilation flags for enabling disabling selfSta and bcastSta per BSS */ +#define HAL_SELF_STA_PER_BSS 1 +#define HAL_BCAST_STA_PER_BSS 1 + +//invalid channel id. +#define HAL_INVALID_CHANNEL_ID 0 + +#ifdef SAP_AUTH_OFFLOAD +#define MAX_CONNECT_REQ_LENGTH 512 +#endif + +/* BSS index used when no BSS is associated with the station. For example, + * driver creates only one self station without valid BSS while scanning. + * Then this index is used to tell softmac that BSS is not valid. + */ +#define BSSIDX_INVALID 254 + +#define HAL_IS_VALID_BSS_INDEX(pMac, bssIdx) ((BSSIDX_INVALID != (bssIdx)) && ((bssIdx) < (pMac)->hal.memMap.maxBssids)) + +// Beacon structure +typedef __ani_attr_pre_packed struct sAniBeaconStruct +{ + tANI_U32 beaconLength; // Indicates the beacon length + tSirMacMgmtHdr macHdr; // MAC Header for beacon + // Beacon body follows here +} __ani_attr_packed tAniBeaconStruct, *tpAniBeaconStruct; + +// probeRsp template structure +typedef __ani_attr_pre_packed struct sAniProbeRspStruct +{ + tSirMacMgmtHdr macHdr; // MAC Header for probeRsp + // probeRsp body follows here +} __ani_attr_packed tAniProbeRspStruct, *tpAniProbeRspStruct; + + +// Per TC parameters +typedef struct +{ + tANI_U8 disableTx; + tANI_U8 disableRx; + tANI_U8 rxCompBA; // 1: expect to see frames with compressed BA coming from this peer MAC + tANI_U8 rxBApolicy; // immediate ACK or delayed ACK for frames from this peer MAC + tANI_U8 txCompBA; // 1: using compressed BA to send to this peer MAC + tANI_U8 txBApolicy; // immediate ACK or delayed ACK for frames to this peer MAC + tANI_U8 rxUseBA; + tANI_U8 txUseBA; + tANI_U8 rxBufferSize; + tANI_U8 txBufferSize; + tANI_U16 txBAWaitTimeout; + tANI_U16 rxBAWaitTimeout; +} tTCParams; + + +typedef struct +{ + // First two fields bssid and assocId are used to find staid for sta. + // BSSID of STA + tSirMacAddr bssId; + + // ASSOC ID, as assigned by PE/LIM. This needs to be assigned + // on a per BSS basis + tANI_U16 assocId; + + // Field to indicate if this is sta entry for itself STA adding entry for itself + // or remote (AP adding STA after successful association. + // This may or may not be required in production driver. + tANI_U8 staType; // 0 - Self, 1 other/remote, 2 - bssid + + tANI_U8 shortPreambleSupported; + + // MAC Address of STA + tSirMacAddr staMac; + + // Listen interval. + tANI_U16 listenInterval; + + // Support for 11e/WMM + tANI_U8 wmmEnabled; + + // + // U-APSD Flags: 1b per AC + // Encoded as follows: + // b7 b6 b5 b4 b3 b2 b1 b0 + // X X X X BE BK VI VO + // + tANI_U8 uAPSD; + + // Max SP Length + tANI_U8 maxSPLen; + + // 11n HT capable STA + tANI_U8 htCapable; + + // 11n Green Field preamble support + // 0 - Not supported, 1 - Supported + // Add it to RA related fields of sta entry in HAL + tANI_U8 greenFieldCapable; + + // TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz + tANI_U8 txChannelWidthSet; + + // MIMO Power Save + tSirMacHTMIMOPowerSaveState mimoPS; + + // RIFS mode: 0 - NA, 1 - Allowed + tANI_U8 rifsMode; + + // L-SIG TXOP Protection mechanism + // 0 - No Support, 1 - Supported + // SG - there is global field. + tANI_U8 lsigTxopProtection; + + // delayed ba support + tANI_U8 delBASupport; + // delayed ba support... TBD + +#ifdef ANI_DVT_DEBUG + //These 6 fields are used only by DVT driver to pass selected + //rates to Softmac through HAL. + tANI_U8 primaryRateIndex, secondaryRateIndex, tertiaryRateIndex; + tANI_U8 primaryRateIndex40, secondaryRateIndex40, tertiaryRateIndex40; +#endif + + // FIXME + //Add these fields to message + tANI_U8 us32MaxAmpduDuration; //in units of 32 us. + tANI_U8 maxAmpduSize; // 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k + tANI_U8 maxAmpduDensity; // 3 : 0~7 : 2^(11nAMPDUdensity -4) + tANI_U8 maxAmsduSize; // 1 : 3839 bytes, 0 : 7935 bytes + + // TC parameters + tTCParams staTCParams[STACFG_MAX_TC]; + + // Compression and Concat parameters for DPU + tANI_U16 deCompEnable; + tANI_U16 compEnable; + tANI_U16 concatSeqRmv; + tANI_U16 concatSeqIns; + + + //11n Parameters + + /** + HT STA should set it to 1 if it is enabled in BSS + HT STA should set it to 0 if AP does not support it. + This indication is sent to HAL and HAL uses this flag + to pickup up appropriate 40Mhz rates. + */ + tANI_U8 fDsssCckMode40Mhz; + + + //short GI support for 40Mhz packets + tANI_U8 fShortGI40Mhz; + + //short GI support for 20Mhz packets + tANI_U8 fShortGI20Mhz; + + + + /* + * All the legacy and airgo supported rates. + * These rates are the intersection of peer and self capabilities. + */ + tSirSupportedRates supportedRates; + + + + + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_ADD_STA_REQ is reported here + eHalStatus status; + // Station index; valid only when 'status' field value is eHAL_STATUS_SUCCESS + tANI_U8 staIdx; + + //BSSID of BSS to which the station is associated. + //This should be filled back in by HAL, and sent back to LIM as part of + //the response message, so LIM can cache it in the station entry of hash table. + //When station is deleted, LIM will make use of this bssIdx to delete + //BSS from hal tables and from softmac. + tANI_U8 bssIdx; + + /* this requires change in testDbg. I will change it later after coordinating with Diag team. + tANI_U8 fFwdTrigerSOSPtoHost; //trigger to start service period + tANI_U8 fFwdTrigerEOSPtoHost; //trigger to end service period + */ + + //HAL should update the existing STA entry, if this flag is set. + //PE will set this flag in case of reassoc, where we want to resue the + //the old staID and still return success. + tANI_U8 updateSta; + //A flag to indicate to HAL if the response message is required. + tANI_U8 respReqd; + + /* Robust Management Frame (RMF) enabled/disabled */ + tANI_U8 rmfEnabled; + + /* The unicast encryption type in the association */ + tANI_U32 encryptType; + + /*The DPU signatures will be sent eventually to TL to help it determine the + association to which a packet belongs to*/ + /*Unicast DPU index*/ + tANI_U8 ucUcastSig; + + /*Broadcast DPU index*/ + tANI_U8 ucBcastSig; + + tANI_U8 sessionId; //PE session id for PE<->HAL interface + // HAL just sends back what it receives. + + /*if this is a P2P Capable Sta*/ + tANI_U8 p2pCapableSta; + tANI_U32 currentOperChan; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; + tANI_U8 vhtTxBFCapable; + tANI_U8 vhtTxMUBformeeCapable; +#endif + + tANI_U8 htLdpcCapable; + tANI_U8 vhtLdpcCapable; +#ifdef SAP_AUTH_OFFLOAD + tANI_U8 dpuIndex; + tANI_U8 bcastDpuIndex; + tANI_U8 bcastMgmtDpuIdx; + tANI_U8 ucMgmtSig; +#endif + +} tAddStaParams, *tpAddStaParams; + + +typedef struct +{ + // Station index + tANI_U16 staIdx; + tANI_U16 templIdx; + tANI_U8 rateIdx; + + // The return status of SIR_HAL_UPDATE_STARATEINFO_REQ is reported here + eHalStatus status; + + //A flag to indicate to HAL if the response message is required. + tANI_U8 respReqd; + +} tUpdateTxCmdTemplParams, *tpUpdateTxCmdTemplParams; +//FIXME: change the structure name + + + + + + + + +typedef struct +{ + // index of STA to delete - this should be the same as the index returned + // as part of the AddSta + tANI_U16 staIdx; + tANI_U16 assocId; + eHalStatus status; // Status of SIR_HAL_DELETE_STA_REQ is reported here + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // PE session id now added to all HAL<->PE transacations + // HAL sends it back unmodified. +} tDeleteStaParams, * tpDeleteStaParams; + +/* + * This is used by PE to configure the key information on a given station. + * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate + * a preconfigured key from a BSS the station assoicated with; otherwise + * a new key descriptor is created based on the key field. + */ +typedef struct +{ + tANI_U16 staIdx; + tAniEdType encType; // Encryption/Decryption type + tAniWepType wepType; // valid only for WEP + tANI_U8 defWEPIdx; // Default WEP key, valid only for static WEP, must between 0 and 3 + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; // valid only for non-static WEP encyrptions + tANI_U8 singleTidRc; // 1=Single TID based Replay Count, 0=Per TID based RC + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // status of SIR_HAL_SET_STAKEY_REQ is reported here + tANI_U8 sessionId; // PE session id for PE<->HAL interface + + // PE session id now added to all HAL<->PE transacations + // HAL sends back response with no modification +} tSetStaKeyParams, *tpSetStaKeyParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_ADD_BSS_REQ +// +typedef struct +{ + // MAC Address/BSSID + tSirMacAddr bssId; +#ifdef HAL_SELF_STA_PER_BSS + // Self Mac Address + tSirMacAddr selfMacAddr; +#endif + // BSS type + // FIXME - Is this reqd? Do we want to isolate BSS/IBSS parameters? + tSirBssType bssType; + + // AP - 0; STA - 1 ; + tANI_U8 operMode; + + // Network type - b/g/a/MixedMode/GreenField/Legacy + // TODO - This enum to be updated for HT support + // Review FIXME - Why is this needed? + tSirNwType nwType; + + tANI_U8 shortSlotTimeSupported; + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20Coexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 fRIFSMode; + + // Beacon Interval + tSirMacBeaconInterval beaconInterval; + + // DTIM period + tANI_U8 dtimPeriod; + + // CF Param Set + // Review FIXME - Does HAL need this? + tSirMacCfParamSet cfParamSet; + + // MAC Rate Set + // Review FIXME - Does HAL need this? + tSirMacRateSet rateSet; + + // 802.11n related HT parameters that are dynamic + + // Enable/Disable HT capabilities + tANI_U8 htCapable; + + // Enable/Disable OBSS protection + tANI_U8 obssProtEnabled; + + // RMF enabled/disabled + tANI_U8 rmfEnabled; + + // HT Operating Mode + // Review FIXME - Does HAL need this? + tSirMacHTOperatingMode htOperMode; + + // Dual CTS Protection: 0 - Unused, 1 - Used + tANI_U8 dualCTSProtection; + + // TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz + tANI_U8 txChannelWidthSet; + + // Current Operating Channel + tANI_U8 currentOperChannel; + + // Current Extension Channel, if applicable + tANI_U8 currentExtChannel; + + // Add a STA entry for "itself" - + // On AP - Add the AP itself in an "STA context" + // On STA - Add the AP to which this STA is joining in an "STA context" + tAddStaParams staContext; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_ADD_BSS_REQ is reported here + eHalStatus status; + // BSS index allocated by HAL. + // valid only when 'status' field is eHAL_STATUS_SUCCESS + tANI_U16 bssIdx; + + // Broadcast DPU descriptor index allocated by HAL and used for broadcast/multicast packets. + // valid only when 'status' field is eHAL_STATUS_SUCCESS + tANI_U8 bcastDpuDescIndx; + + // DPU signature to be used for broadcast/multicast packets + // valid only when 'status' field is eHAL_STATUS_SUCCESS + tANI_U8 bcastDpuSignature; + + // DPU descriptor index allocated by HAL, used for bcast/mcast management packets + tANI_U8 mgmtDpuDescIndx; + + // DPU signature to be used for bcast/mcast management packets + tANI_U8 mgmtDpuSignature; + + //HAL should update the existing BSS entry, if this flag is set. + //PE will set this flag in case of reassoc, where we want to resue the + //the old bssID and still return success. + tANI_U8 updateBss; + + // Add BSSID info for rxp filter in IBSS mode + tSirMacSSid ssId; + + //HAL will send the response message to LIM only when this flag is set. + //LIM will set this flag, whereas DVT will not set this flag. + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // PE session id now added to all HAL<->PE transacations + // HAL Sends the sessionId unmodified. + +#if defined WLAN_FEATURE_VOWIFI + tPowerdBm txMgmtPower; //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm maxTxPower; //max power to be used after applying the power constraint, if any +#endif + +#if defined WLAN_FEATURE_VOWIFI_11R + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +#endif + + tANI_U8 ucMaxProbeRespRetryLimit; //probe Response Max retries + tANI_U8 bHiddenSSIDEn; //To Enable Hidden ssid. + tANI_U8 bProxyProbeRespEn; //To Enable Disable FW Proxy Probe Resp + tANI_U8 halPersona; //Persona for the BSS can be STA,AP,GO,CLIENT value same as tVOS_CON_MODE + + //Spectrum Management Capability, 1 - Enabled, 0 - Disabled. + tANI_U8 bSpectrumMgtEnabled; +#ifdef WLAN_FEATURE_11AC + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; +#endif +} tAddBssParams, * tpAddBssParams; + +typedef struct +{ + tANI_U8 bssIdx; + // The return status of SIR_HAL_DELETE_BSS_REQ is reported here + eHalStatus status; + //HAL will send the response message to LIM only when this flag is set. + //LIM will set this flag, whereas DVT will not set this flag. + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL sends it back unmodified. + tSirMacAddr bssid; // Will be removed for PE-HAL integration +} tDeleteBssParams, * tpDeleteBssParams; + +// +// UAPSD AC mask: 1b per AC +// LSB 4 bits for delivery enabled setting. msb 4 bits for trigger enabled settings. +// Encoded as follows: +// b7 b6 b5 b4 b3 b2 b1 b0 +// BE BK VI VO BE BK VI VO + +typedef struct +{ + tANI_U8 staIdx; + tANI_U8 uapsdACMask; + tANI_U8 maxSpLen; +} tUpdateUapsdParams, * tpUpdateUapsdParams; + +typedef struct sSirScanEntry +{ + tANI_U8 bssIdx[HAL_NUM_BSSID]; + tANI_U8 activeBSScnt; +}tSirScanEntry, *ptSirScanEntry; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_INIT_SCAN_REQ +// +typedef struct { + + eHalSysMode scanMode; + + tSirMacAddr bssid; + + tANI_U8 notifyBss; + + tANI_U8 useNoA; + + // If this flag is set HAL notifies PE when SMAC returns status. + tANI_U8 notifyHost; + + tANI_U8 frameLength; + tANI_U8 frameType; // Data NULL or CTS to self + + // Indicates the scan duration (in ms) + tANI_U16 scanDuration; + + // For creation of CTS-to-Self and Data-NULL MAC packets + tSirMacMgmtHdr macMgmtHdr; + + tSirScanEntry scanEntry; + + // when this flag is set, HAL should check for link traffic prior to scan + tSirLinkTrafficCheck checkLinkTraffic; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_INIT_SCAN_REQ is reported here + eHalStatus status; + +} tInitScanParams, * tpInitScanParams; + +typedef enum eDelStaReasonCode{ + HAL_DEL_STA_REASON_CODE_KEEP_ALIVE = 0x1, + HAL_DEL_STA_REASON_CODE_TIM_BASED = 0x2, + HAL_DEL_STA_REASON_CODE_RA_BASED = 0x3, + HAL_DEL_STA_REASON_CODE_UNKNOWN_A2 = 0x4 +}tDelStaReasonCode; + +// +// Msg header is used from tSirMsgQ +// Msg Type = SIR_LIM_DELETE_STA_CONTEXT_IND +// +typedef struct { + tANI_U16 assocId; + tANI_U16 staId; + tSirMacAddr bssId; // TO SUPPORT BT-AMP + // HAL copies bssid from the sta table. + tSirMacAddr addr2; // + tANI_U16 reasonCode; // To unify the keepalive / unknown A2 / tim-based disa +} tDeleteStaContext, * tpDeleteStaContext; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_START_SCAN_REQ +// FIXME - Can we just use tSirMsgQ directly, instead of using this structure? +// +typedef struct { + + // Indicates the current scan channel + tANI_U8 scanChannel; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_START_SCAN_REQ is reported here + eHalStatus status; + +#if defined WLAN_FEATURE_VOWIFI + tANI_U32 startTSF[2]; + tPowerdBm txMgmtPower; //HAL fills in the tx power used for mgmt frames in this field. +#endif +} tStartScanParams, * tpStartScanParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_END_SCAN_REQ +// FIXME - Can we just use tSirMsgQ directly, instead of using this structure? +// +typedef struct { + + // Indicates the current scan channel + tANI_U8 scanChannel; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_END_SCAN_REQ is reported here + eHalStatus status; + +} tEndScanParams, * tpEndScanParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_FINISH_SCAN_REQ +// +typedef struct { + + // Identifies the operational state of the AP/STA. + // In case of the STA, only if the operState is non-zero will the rest of + // the parameters that follow be decoded + // In case of the AP, all parameters are valid + // + // 0 - Idle state, 1 - Link Established + + eHalSysMode scanMode; + + tSirMacAddr bssid; + + // Current operating channel + tANI_U8 currentOperChannel; + + // If 20/40 MHz is operational, this will indicate the 40 MHz extension + // channel in combination with the control channel + ePhyChanBondState cbState; + + // For an STA, indicates if a Data NULL frame needs to be sent + // to the AP with FrameControl.PwrMgmt bit set to 0 + tANI_U8 notifyBss; + + tANI_U8 notifyHost; + + tANI_U8 frameLength; + tANI_U8 frameType; // Data NULL or CTS to self + + // For creation of CTS-to-Self and Data-NULL MAC packets + tSirMacMgmtHdr macMgmtHdr; + + tSirScanEntry scanEntry; + + /* + * Following parameters are for returning status and station index from HAL to PE + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_FINISH_SCAN_REQ is reported here + eHalStatus status; + +} tFinishScanParams, * tpFinishScanParams; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +typedef struct +{ + tSirMacAddr selfMacAddr; + eHalStatus status; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tStartOemDataReq, *tpStartOemDataReq; + +typedef struct +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tStartOemDataRsp, *tpStartOemDataRsp; +#endif + +typedef struct sBeaconGenStaInfo { + tANI_U16 assocId; + tANI_U32 staTxAckCnt; +}tBeaconGenStaInfo, *tpBeaconGenStaInfo; +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_LIM_BEACON_GEN_IND +// + +typedef struct sBeaconGenParams { + // Identifies the BSSID for which it is time to generate a beacon + tANI_U8 bssIdx; + tSirMacAddr bssId; +#ifdef FIXME_VOLANS + tANI_U8 numOfSta; /* Number of stations in power save, who have data pending*/ + tANI_U8 numOfStaWithoutData; /* Number of stations in power save, who don't have any data pending*/ + tANI_U8 fBroadcastTrafficPending ; + tANI_U8 dtimCount; +#endif + tANI_U8 rsvd[3]; /** Align the Structure to 4 bytes as unalligned access will happen if + the staInfo is being Accessed */ +/** NOTE: tBeaconGenStaInfo staInfo[xx]; Depending on the Number of STA in PS, Every time + this array is being allocated and piled up at the End*/ +} tBeaconGenParams, * tpBeaconGenParams; + +typedef struct { + tSirMacAddr bssId; + tANI_U8 *beacon; // Beacon data. + tANI_U32 beaconLength; //length of the template. + tANI_U32 timIeOffset; //TIM IE offset from the beginning of the template. + tANI_U16 p2pIeOffset; //P2P IE offset from the begining of the template +} tSendbeaconParams, * tpSendbeaconParams; + +typedef struct sSendProbeRespParams { + tSirMacAddr bssId; + tANI_U8 *pProbeRespTemplate; + tANI_U32 probeRespTemplateLen; + tANI_U32 ucProxyProbeReqValidIEBmap[8]; +} tSendProbeRespParams, * tpSendProbeRespParams; + +/* + * This is used by PE to create a set of WEP keys for a given BSS. + */ +typedef struct +{ + tANI_U8 bssIdx; + tAniEdType encType; + tANI_U8 numKeys; + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; + tANI_U8 singleTidRc; // 1=Single TID based Replay Count, 0=Per TID based RC + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // status of SIR_HAL_SET_BSSKEY_REQ is reported here + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL sends this unmodified in the response +} tSetBssKeyParams, *tpSetBssKeyParams; + +/* + * This is used by PE to Remove the key information on a given station. + */ +typedef struct +{ + tANI_U16 staIdx; + tAniEdType encType; // Encryption/Decryption type + tANI_U8 keyId; + tANI_BOOLEAN unicast; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // return status of SIR_HAL_REMOVE_STAKEY_REQ + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL Sends back the PE session + // id unmodified +} tRemoveStaKeyParams, *tpRemoveStaKeyParams; + +/* + * This is used by PE to remove keys for a given BSS. + */ +typedef struct +{ + tANI_U8 bssIdx; + tAniEdType encType; + tANI_U8 keyId; + tANI_U8 wepType; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + eHalStatus status; // return status of SIR_HAL_REMOVE_BSSKEY_REQ + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL Sends back the PE session + // id unmodified +} tRemoveBssKeyParams, *tpRemoveBssKeyParams; + +typedef struct +{ + // index of STA to get the statistics from + tANI_U16 staIdx; + tANI_U8 encMode; + // The return status of SIR_HAL_DPU_STATS_REQ is reported here + eHalStatus status; + // The return statistics + tANI_U32 sendBlocks; + tANI_U32 recvBlocks; + tANI_U32 replays; + tANI_U8 micErrorCnt; + tANI_U32 protExclCnt; + tANI_U16 formatErrCnt; + tANI_U16 unDecryptableCnt; + tANI_U32 decryptErrCnt; + tANI_U32 decryptOkCnt; + +} tDpuStatsParams, * tpDpuStatsParams; + + +/* + * Get the DPU signature based on a given staId + */ +typedef struct +{ + tANI_U16 staIdx; + /* + * Following parameter is for returning status + * via response message. HAL does not read them. + */ + // The return status of SIR_HAL_SET_BSSKEY_REQ is reported here + eHalStatus status; + tANI_U8 dpuDescIndx; + tANI_U8 dpuSignature; +} tGetDpuParams, *tpGetDpuParams; + + + +//HAL MSG: SIR_HAL_UPDATE_BEACON_IND +typedef struct +{ + + tANI_U8 bssIdx; + + //shortPreamble mode. HAL should update all the STA rates when it + //receives this message + tANI_U8 fShortPreamble; + //short Slot time. + tANI_U8 fShortSlotTime; + //Beacon Interval + tANI_U16 beaconInterval; + //Protection related + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20MhzCoexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 fRIFSMode; + + tANI_U16 paramChangeBitmap; +}tUpdateBeaconParams, *tpUpdateBeaconParams; + +typedef struct +{ + tANI_U16 opMode; + tANI_U16 staId; +}tUpdateVHTOpMode, *tpUpdateVHTOpMode; + +//HAL MSG: SIR_HAL_UPDATE_CF_IND +typedef struct +{ + + tANI_U8 bssIdx; + + /* + * cfpCount indicates how many DTIMs (including the current frame) appear before the next CFP start. + * A CFPCount of 0 indicates that the current DTIM marks the start of the CFP. + */ + tANI_U8 cfpCount; + + /* cfpPeriod indicates the number of DTIM intervals between the start of CFPs. */ + tANI_U8 cfpPeriod; + +}tUpdateCFParams, *tpUpdateCFParams; + + + +//HAL MSG: SIR_HAL_UPDATE_DTIM_IND +//This message not required, as Softmac is supposed to read these values from the beacon. +//PE should not look at TIM element + +/* +typedef struct +{ + tANI_U8 bssIdx; + + + //The DTIM Count field indicates how many beacons (including the current frame) appear before the next + // DTIM. A DTIM Count of 0 indicates that the current TIM is a DTIM. + // + tANI_U8 dtimCount; + + + // The DTIM Period field indicates the number of Beacon intervals between successive DTIMs. If all TIMs are + // DTIMs, the DTIM Period field has the value 1. The DTIM Period value 0 is reserved. + // + tANI_U8 dtimPeriod; + +}tUpdateDtimParams, *tpUpdateDtimParams; +*/ + +typedef enum +{ + eHAL_CHANNEL_SWITCH_SOURCE_SCAN, + eHAL_CHANNEL_SWITCH_SOURCE_LISTEN, + eHAL_CHANNEL_SWITCH_SOURCE_MCC, + eHAL_CHANNEL_SWITCH_SOURCE_CSA, + eHAL_CHANNEL_SWITCH_SOURCE_MAX = 0x7fffffff +} eHalChanSwitchSource; + + +//HAL MSG: SIR_HAL_CHNL_SWITCH_REQ +typedef struct +{ + tANI_U8 channelNumber; +#ifndef WLAN_FEATURE_VOWIFI + tANI_U8 localPowerConstraint; +#endif /* WLAN_FEATURE_VOWIFI */ + ePhyChanBondState secondaryChannelOffset; + tANI_U8 peSessionId; +#if defined WLAN_FEATURE_VOWIFI + tPowerdBm txMgmtPower; //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm maxTxPower; + tSirMacAddr selfStaMacAddr; + //the request has power constraints, this should be applied only to that session +#endif + eHalChanSwitchSource channelSwitchSrc; + + /* VO Wifi comment: BSSID is needed to identify which session issued this request. As the + request has power constraints, this should be applied only to that session */ + /* V IMP: Keep bssId field at the end of this msg. It is used to mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since it is at the end of this struct + */ + tSirMacAddr bssId; + + eHalStatus status; + +}tSwitchChannelParams, *tpSwitchChannelParams; + +typedef void (*tpSetLinkStateCallback)(tpAniSirGlobal pMac, void *msgParam ); + +typedef struct sLinkStateParams +{ + // SIR_HAL_SET_LINK_STATE + tSirMacAddr bssid; + tSirMacAddr selfMacAddr; + tSirLinkState state; + tpSetLinkStateCallback callback; + void *callbackArg; +#ifdef WLAN_FEATURE_VOWIFI_11R + int ft; + void * session; +#endif +} tLinkStateParams, * tpLinkStateParams; + + +typedef struct +{ + tANI_U16 staIdx; + tANI_U16 tspecIdx; //TSPEC handler uniquely identifying a TSPEC for a STA in a BSS + tSirMacTspecIE tspec; + eHalStatus status; + tANI_U8 sessionId; //PE session id for PE<->HAL interface +} tAddTsParams, *tpAddTsParams; + +typedef struct +{ + tANI_U16 staIdx; + tANI_U16 tspecIdx; //TSPEC identifier uniquely identifying a TSPEC for a STA in a BSS + tSirMacAddr bssId; //TO SUPPORT BT-AMP + +} tDelTsParams, *tpDelTsParams; + +#ifdef WLAN_FEATURE_VOWIFI_11R + +#define HAL_QOS_NUM_TSPEC_MAX 2 +#define HAL_QOS_NUM_AC_MAX 4 + +typedef struct +{ + tANI_U16 staIdx; + tANI_U16 tspecIdx; //TSPEC handler uniquely identifying a TSPEC for a STA in a BSS + tSirMacTspecIE tspec[HAL_QOS_NUM_AC_MAX]; + eHalStatus status[HAL_QOS_NUM_AC_MAX]; + tANI_U8 sessionId; //PE session id for PE<->HAL interface +}tAggrAddTsParams, *tpAggrAddTsParams; + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + + +typedef tSirRetStatus (*tHalMsgCallback)(tpAniSirGlobal pMac, tANI_U32 mesgId, void *mesgParam ); + + +typedef struct +{ + tANI_U16 bssIdx; + tANI_BOOLEAN highPerformance; + tSirMacEdcaParamRecord acbe; // best effort + tSirMacEdcaParamRecord acbk; // background + tSirMacEdcaParamRecord acvi; // video + tSirMacEdcaParamRecord acvo; // voice +} tEdcaParams, *tpEdcaParams; + +/* +* Function Prototypes +*/ + +eHalStatus halMsg_setPromiscMode(tpAniSirGlobal pMac); + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_ADDBA_REQ +// +typedef struct sAddBAParams +{ + + // Station Index + tANI_U16 staIdx; + + // Peer MAC Address + tSirMacAddr peerMacAddr; + + // ADDBA Action Frame dialog token + // HAL will not interpret this object + tANI_U8 baDialogToken; + + // TID for which the BA is being setup + // This identifies the TC or TS of interest + tANI_U8 baTID; + + // 0 - Delayed BA (Not supported) + // 1 - Immediate BA + tANI_U8 baPolicy; + + // Indicates the number of buffers for this TID (baTID) + // NOTE - This is the requested buffer size. When this + // is processed by HAL and subsequently by HDD, it is + // possible that HDD may change this buffer size. Any + // change in the buffer size should be noted by PE and + // advertized appropriately in the ADDBA response + tANI_U16 baBufferSize; + + // BA timeout in TU's + // 0 means no timeout will occur + tANI_U16 baTimeout; + + // b0..b3 - Fragment Number - Always set to 0 + // b4..b15 - Starting Sequence Number of first MSDU + // for which this BA is setup + tANI_U16 baSSN; + + // ADDBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + // + // Following parameters are for returning status from + // HAL to PE via response message. HAL does not read them + // + // The return status of SIR_HAL_ADDBA_REQ is reported + // in the SIR_HAL_ADDBA_RSP message + eHalStatus status; + + // Indicating to HAL whether a response message is required. + tANI_U8 respReqd; + tANI_U8 sessionId; // PE session id for PE<->HAL interface + // HAL Sends back the PE session + // id unmodified + +} tAddBAParams, * tpAddBAParams; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_DELBA_IND +// +typedef struct sDelBAParams +{ + + // Station Index + tANI_U16 staIdx; + + // TID for which the BA session is being deleted + tANI_U8 baTID; + + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + // FIXME - Do we need a response for this? + // Maybe just the IND/REQ will suffice? + // + // Following parameters are for returning status from + // HAL to PE via response message. HAL does not read them + // + // The return status of SIR_HAL_DELBA_REQ is reported + // in the SIR_HAL_DELBA_RSP message + //eHalStatus status; + +} tDelBAParams, * tpDelBAParams; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_SET_MIMOPS_REQ +// +typedef struct sSet_MIMOPS +{ + // Station Index + tANI_U16 staIdx; + + // MIMO Power Save State + tSirMacHTMIMOPowerSaveState htMIMOPSState; + // The return status of SIR_HAL_SET_MIMOPS_REQ is reported + // in the SIR_HAL_SET_MIMOPS_RSP message + eHalStatus status; + tANI_U8 fsendRsp; + +} tSetMIMOPS, * tpSetMIMOPS; + + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_EXIT_BMPS_REQ +// +typedef struct sExitBmpsParams +{ + tANI_U8 sendDataNull; + eHalStatus status; + tANI_U8 bssIdx; +} tExitBmpsParams, *tpExitBmpsParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_ENTER_UAPSD_REQ +// +typedef struct sUapsdParams +{ + tANI_U8 bkDeliveryEnabled:1; + tANI_U8 beDeliveryEnabled:1; + tANI_U8 viDeliveryEnabled:1; + tANI_U8 voDeliveryEnabled:1; + tANI_U8 bkTriggerEnabled:1; + tANI_U8 beTriggerEnabled:1; + tANI_U8 viTriggerEnabled:1; + tANI_U8 voTriggerEnabled:1; + eHalStatus status; + tANI_U8 bssIdx; +}tUapsdParams, *tpUapsdParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_EXIT_UAPSD_REQ +// +typedef struct sExitUapsdParams +{ + eHalStatus status; + tANI_U8 bssIdx; +}tExitUapsdParams, *tpExitUapsdParams; + +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_LIM_DEL_BA_IND +// +typedef struct sBADeleteParams +{ + + // Station Index + tANI_U16 staIdx; + + // Peer MAC Address, whose BA session has timed out + tSirMacAddr peerMacAddr; + + // TID for which a BA session timeout is being triggered + tANI_U8 baTID; + + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + + tANI_U32 reasonCode; + + tSirMacAddr bssId; // TO SUPPORT BT-AMP + // HAL copies the sta bssid to this. +} tBADeleteParams, * tpBADeleteParams; + + +// Mesg Type = SIR_LIM_ADD_BA_IND +typedef struct sBaActivityInd +{ + tANI_U16 baCandidateCnt; + //baCandidateCnt is followed by BA Candidate List ( tAddBaCandidate) + + tSirMacAddr bssId; // TO SUPPORT BT-AMP +} tBaActivityInd, * tpBaActivityInd; + + +// Mesg Type = SIR_LIM_IBSS_PEER_INACTIVITY_IND +typedef struct sIbssPeerInactivityInd +{ + tANI_U8 bssIdx; + tANI_U8 staIdx; + tSirMacAddr staAddr; +}tIbssPeerInactivityInd, *tpIbssPeerInactivityInd; + + +typedef struct tHalIndCB +{ + + tHalMsgCallback pHalIndCB; + +}tHalIndCB,*tpHalIndCB; + +/** Max number of bytes required for stations bitmap aligned at 4 bytes boundary */ +#define HALMSG_NUMBYTES_STATION_BITMAP(x) (((x / 32) + ((x % 32)?1:0)) * 4) + +typedef struct sControlTxParams +{ + tANI_BOOLEAN stopTx; + /* Master flag to stop or resume all transmission, Once this flag is set, + * softmac doesnt look for any other details. + */ + tANI_U8 fCtrlGlobal; + /* If this flag is set, staBitmap[] is valid */ + tANI_U8 ctrlSta; + /* If this flag is set, bssBitmap and beaconBitmap is valid */ + tANI_U8 ctrlBss; + + /* When ctrlBss is set, this bitmap contains bitmap of BSS indices to be + * stopped for resumed for transmission. + * This is 32 bit bitmap, not array of bytes. + */ + tANI_U32 bssBitmap; + /* When ctrlBss is set, this bitmap contains bitmap of BSS indices to be + * stopped for resumed for beacon transmission. + */ + tANI_U32 beaconBitmap; + + /** + * Memory for the station bitmap will be allocated later based on + * the number of station supported. + */ +} tTxControlParams, * tpTxControlParams; + +typedef struct sEnterBmpsParams +{ + //TBTT value derived from the last beacon + tANI_U8 bssIdx; + tANI_U64 tbtt; + tANI_U8 dtimCount; + //DTIM period given to HAL during association may not be valid, + //if association is based on ProbeRsp instead of beacon. + tANI_U8 dtimPeriod; + + // For ESE and 11R Roaming + tANI_U8 bRssiFilterEnable; + tANI_U32 rssiFilterPeriod; + tANI_U32 numBeaconPerRssiAverage; + + eHalStatus status; + tANI_U8 respReqd; +}tEnterBmpsParams, *tpEnterBmpsParams; + +//BMPS response +typedef struct sEnterBmpsRspParams +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +}tEnterBmpsRspParams, *tpEnterBmpsRspParams; +// +// Mesg header is used from tSirMsgQ +// Mesg Type = SIR_HAL_SET_MAX_TX_POWER_REQ +// +typedef struct sMaxTxPowerParams +{ + tSirMacAddr bssId; // BSSID is needed to identify which session issued this request. As + //the request has power constraints, this should be applied only to that session + tSirMacAddr selfStaMacAddr; + //In request, + //power == MaxTx power to be used. + //In response, + //power == tx power used for management frames. + tPowerdBm power; +}tMaxTxPowerParams, *tpMaxTxPowerParams; + +typedef struct sMaxTxPowerPerBandParams +{ + eCsrBand bandInfo; + tPowerdBm power; +}tMaxTxPowerPerBandParams, *tpMaxTxPowerPerBandParams; + +typedef struct sAddStaSelfParams +{ + tSirMacAddr selfMacAddr; + tVOS_CON_MODE currDeviceMode; + tANI_U32 status; +}tAddStaSelfParams, *tpAddStaSelfParams; + +typedef struct sAbortScanParams +{ + tANI_U8 SessionId; +}tAbortScanParams, *tpAbortScanParams; + +typedef struct sDelStaSelfParams +{ + tSirMacAddr selfMacAddr; + + tANI_U32 status; +}tDelStaSelfParams, *tpDelStaSelfParams; + +typedef struct +{ + tSirMacAddr macAddr; +} tSpoofMacAddrReqParams, *tpSpoofMacAddrReqParams; + +typedef struct sP2pPsParams +{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; +}tP2pPsParams, *tpP2pPsParams; + +#define HAL_MAX_SUPP_CHANNELS 128 +#define HAL_MAX_SUPP_OPER_CLASSES 32 + +typedef struct sTdlsLinkEstablishParams +{ + tANI_U16 staIdx; + tANI_U8 isResponder; + tANI_U8 uapsdQueues; + tANI_U8 maxSp; + tANI_U8 isBufsta; + tANI_U8 isOffChannelSupported; + tANI_U8 peerCurrOperClass; + tANI_U8 selfCurrOperClass; + tANI_U8 validChannelsLen; + tANI_U8 validChannels[HAL_MAX_SUPP_CHANNELS]; + tANI_U8 validOperClassesLen; + tANI_U8 validOperClasses[HAL_MAX_SUPP_OPER_CLASSES]; + tANI_U32 status; +}tTdlsLinkEstablishParams, *tpTdlsLinkEstablishParams; + +// tdlsoffchan +typedef struct sTdlsChanSwitchParams +{ + tANI_U16 staIdx; + tANI_U8 tdlsOffCh; // Target Off Channel + tANI_U8 tdlsOffChBwOffset;// Target Off Channel Bandwidth offset + tANI_U8 tdlsSwMode; // TDLS Off Channel Mode + tANI_U8 operClass; //Operating class corresponding to target channel + tANI_U32 status; +}tTdlsChanSwitchParams, *tpTdlsChanSwitchParams; + +static inline void halGetTxTSFtimer(tpAniSirGlobal pMac, + tSirMacTimeStamp *pTime) +{ +} + +extern void SysProcessMmhMsg(tpAniSirGlobal pMac, tSirMsgQ* pMsg); + +/* Beacon Filtering data structures */ +typedef __ani_attr_pre_packed struct sBeaconFilterMsg +{ + tANI_U16 capabilityInfo; + tANI_U16 capabilityMask; + tANI_U16 beaconInterval; + tANI_U16 ieNum; + tANI_U8 bssIdx; + tANI_U8 reserved; +} __ani_attr_packed tBeaconFilterMsg, *tpBeaconFilterMsg; + +typedef __ani_attr_pre_packed struct sEidByteInfo +{ + tANI_U8 offset; + tANI_U8 value; + tANI_U8 bitMask; + tANI_U8 ref; +} __ani_attr_packed tEidByteInfo, *tpEidByteInfo; + + +/* The above structure would be followed by multiple of below mentioned +structure */ +typedef __ani_attr_pre_packed struct sBeaconFilterIe +{ + tANI_U8 elementId; + tANI_U8 checkIePresence; + tEidByteInfo byte; +} __ani_attr_packed tBeaconFilterIe, *tpBeaconFilterIe; + +typedef __ani_attr_pre_packed struct sRemBeaconFilterMsg +{ + tANI_U8 ucIeCount; + tANI_U8 ucRemIeId[1]; +} __ani_attr_packed tRemBeaconFilterMsg, *tpRemBeaconFilterMsg; + +typedef struct sNanRequest +{ + tANI_U16 request_data_len; + tANI_U8 request_data[1]; +} tNanRequest, *tpNanRequest; + + +#ifdef SAP_AUTH_OFFLOAD +struct sap_offload_add_sta_req +{ + tANI_U32 assoc_id; + tANI_U32 conn_req_len; + tANI_U8 conn_req[MAX_CONNECT_REQ_LENGTH]; +}; +struct sap_offload_del_sta_req +{ + tANI_U32 assoc_id; + tANI_U32 reason_code; + tANI_U32 flags; + tSirMacAddr sta_mac; +}; +#endif /* SAP_AUTH_OFFLOAD */ + +#endif /* _HALMSGAPI_H_ */ + diff --git a/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h b/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h new file mode 100644 index 000000000000..67becef9bcf6 --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/inc/legacy/halTypes.h @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file halTypes.h + + \brief This header captures types that must be shared in common with individual + module headers before inclusion into halCommonApi.h. + + $Id$ + + + ========================================================================== */ + +#ifndef HALTYPES_H +#define HALTYPES_H +#ifndef WINXP_APPS_BUILD //TODO: this header dependency does not belong in this file + +#endif /* WINXP_APPS_BUILD */ + +#include "palTypes.h" +#include "wlan_nv.h" + +#define OFFSET_OF(structType,fldName) (&((structType*)0)->fldName) + +/** ------------------------------------------------------------------------- * + + \typedef tHalHandle + + \brief Handle to the HAL. The HAL handle is returned by the HAL after it + is opened (by calling halOpen). + + -------------------------------------------------------------------------- */ +typedef void *tHalHandle; + +// define a value for an invalid HAL handle..... +#define HAL_INVALID_HAL_HANDLE ( NULL ) + + +/** ------------------------------------------------------------------------- * + + \enum eHalStatus + + \brief Enumeration of all status codes returned by the higher level + HAL interface functions. + + -------------------------------------------------------------------------- */ +typedef enum +{ + eHAL_STATUS_SUCCESS, + + // general failure. This status applies to all failure that are not covered + // by more specific return codes. + eHAL_STATUS_FAILURE, + eHAL_STATUS_FAILED_ALLOC, + eHAL_STATUS_RESOURCES, + + // the HAL has not been opened and a HAL function is being attempted. + eHAL_STATUS_NOT_OPEN, + + // function failed due to the card being removed... + eHAL_STATUS_CARD_NOT_PRESENT, + + //halInterrupt status + eHAL_STATUS_INTERRUPT_ENABLED, + eHAL_STATUS_INTERRUPT_DISABLED, + eHAL_STATUS_NO_INTERRUPTS, + eHAL_STATUS_INTERRUPT_PRESENT, + eHAL_STATUS_ALL_INTERRUPTS_PROCESSED, + eHAL_STATUS_INTERRUPT_NOT_PROCESSED, //interrupt cleared but no Isr to process + + // a parameter on the PAL function call is not valid. + eHAL_STATUS_INVALID_PARAMETER, + + // the PAL has not been initialized... + eHAL_STATUS_NOT_INITIALIZED, + + // Error codes for PE-HAL message API + eHAL_STATUS_INVALID_STAIDX, + eHAL_STATUS_INVALID_BSSIDX, + eHAL_STATUS_STA_TABLE_FULL, // No space to add more STA, sta table full. + eHAL_STATUS_BSSID_TABLE_FULL, + eHAL_STATUS_DUPLICATE_BSSID, + eHAL_STATUS_DUPLICATE_STA, + eHAL_STATUS_BSSID_INVALID, + eHAL_STATUS_STA_INVALID, + eHAL_STATUS_INVALID_KEYID, + eHAL_STATUS_INVALID_SIGNATURE, + + //DXE + eHAL_STATUS_DXE_FAILED_NO_DESCS, + eHAL_STATUS_DXE_CHANNEL_NOT_CONFIG, // Channel not configured + eHAL_STATUS_DXE_CHANNEL_MISUSE, // Specified operation inconsistent w/ configuration + eHAL_STATUS_DXE_VIRTUAL_MEM_ALLOC_ERROR, // + eHAL_STATUS_DXE_SHARED_MEM_ALLOC_ERROR, // + eHAL_STATUS_DXE_INVALID_CHANNEL, + eHAL_STATUS_DXE_INVALID_CALLBACK, + eHAL_STATUS_DXE_INCONSISTENT_DESC_COUNT, + eHAL_STATUS_DXE_XFR_QUEUE_ERROR, + eHAL_STATUS_DXE_INVALID_BUFFER, + eHAL_STATUS_DXE_INCOMPLETE_PACKET, + eHAL_STATUS_DXE_INVALID_PARAMETER, + eHAL_STATUS_DXE_CH_ALREADY_CONFIGURED, + eHAL_STATUS_DXE_USB_INVALID_EP, + eHAL_STATUS_DXE_GEN_ERROR, + + + // status codes added for the ImageValidate library + eHAL_STATUS_E_NULL_VALUE, + eHAL_STATUS_E_FILE_NOT_FOUND, + eHAL_STATUS_E_FILE_INVALID_CONTENT, + eHAL_STATUS_E_MALLOC_FAILED, + eHAL_STATUS_E_FILE_READ_FAILED, + eHAL_STATUS_E_IMAGE_INVALID, + eHAL_STATUS_E_IMAGE_UNSUPPORTED, + + // status code returned by device memory calls when memory is + // not aligned correctly. + eHAL_STATUS_DEVICE_MEMORY_MISALIGNED, // memory access is not aligned on a 4 byte boundary + eHAL_STATUS_DEVICE_MEMORY_LENGTH_ERROR, // memory access is not a multiple of 4 bytes + + // Generic status code to indicate network congestion. + eHAL_STATUS_NET_CONGESTION, + + // various status codes for Rx packet dropped conditions... Note the Min and Max + // enums that bracked the Rx Packet Dropped status codes. There is code that + // looks at the various packet dropped conditions so make sure these min / max + // enums remain accurate. + eHAL_STATUS_RX_PACKET_DROPPED, + eHAL_STATUS_RX_PACKET_DROPPED_MIN = eHAL_STATUS_RX_PACKET_DROPPED, + eHAL_STATUS_RX_PACKET_DROPPED_NULL_DATA, + eHAL_STATUS_RX_PACKET_DROPPED_WDS_FRAME, + eHAL_STATUS_RX_PACKET_DROPPED_FILTERED, + eHAL_STATUS_RX_PACKET_DROPPED_GROUP_FROM_SELF, + eHAL_STATUS_RX_PACKET_DROPPED_MAX = eHAL_STATUS_RX_PACKET_DROPPED_GROUP_FROM_SELF, + + // Status indicating that PMU did not power up and hence indicative of the fact that the clocks are not on + eHAL_STATUS_PMU_NOT_POWERED_UP, + + // Queuing code for BA message API + eHAL_STATUS_BA_ENQUEUED, // packets have been buffered in Host + eHAL_STATUS_BA_INVALID, + + // A-MPDU/BA related Error codes + eHAL_STATUS_BA_RX_BUFFERS_FULL, + eHAL_STATUS_BA_RX_MAX_SESSIONS_REACHED, + eHAL_STATUS_BA_RX_INVALID_SESSION_ID, + + // !!LAC - can we rework the code so these are not needed? + eHAL_STATUS_BA_RX_DROP_FRAME, + eHAL_STATUS_BA_RX_INDICATE_FRAME, + eHAL_STATUS_BA_RX_ENQUEUE_FRAME, + + // PMC return codes. + eHAL_STATUS_PMC_PENDING, + eHAL_STATUS_PMC_DISABLED, + eHAL_STATUS_PMC_NOT_NOW, + eHAL_STATUS_PMC_AC_POWER, + eHAL_STATUS_PMC_SYS_ERROR, + eHAL_STATUS_PMC_CANNOT_ENTER_IMPS, + eHAL_STATUS_PMC_ALREADY_IN_IMPS, + + eHAL_STATUS_HEARTBEAT_TMOUT, + eHAL_STATUS_NTH_BEACON_DELIVERY, + + //CSR + eHAL_STATUS_CSR_WRONG_STATE, + + // DPU + eHAL_STATUS_DPU_DESCRIPTOR_TABLE_FULL, + eHAL_STATUS_DPU_MICKEY_TABLE_FULL, + + // HAL-FW messages + eHAL_STATUS_FW_MSG_FAILURE, // Error in Hal-FW message interface + eHAL_STATUS_FW_MSG_TIMEDOUT, + eHAL_STATUS_FW_MSG_INVALID, + eHAL_STATUS_FW_SEND_MSG_FAILED, + eHAL_STATUS_FW_PS_BUSY, + + eHAL_STATUS_TIMER_START_FAILED, + eHAL_STATUS_TIMER_STOP_FAILED, + + eHAL_STATUS_TL_SUSPEND_TIMEOUT, + + eHAL_STATUS_UMA_DESCRIPTOR_TABLE_FULL, + + eHAL_STATUS_SET_CHAN_ALREADY_ON_REQUESTED_CHAN, + +#ifdef WLAN_FEATURE_VOWIFI_11R + eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS, + eHAL_STATUS_FT_PREAUTH_KEY_FAILED, +#endif + //CMD not Queued in SME + eHAL_STATUS_CMD_NOT_QUEUED, + +#ifdef WLAN_FEATURE_LFR_MBB + eHAL_STATUS_MBB_DEL_BSS_FAIL, + eHAL_STATUS_MBB_ADD_BSS_FAIL, +#endif + + // not a real status. Just a way to mark the maximum in the enum. + eHAL_STATUS_MAX + +} eHalStatus; + +typedef enum +{ + HAL_STOP_TYPE_SYS_RESET, + HAL_STOP_TYPE_SYS_DEEP_SLEEP, + HAL_STOP_TYPE_RF_KILL, +}tHalStopType; + +// macro to check for SUCCESS value of the halStatus +#define HAL_STATUS_SUCCESS( variable ) ( eHAL_STATUS_SUCCESS == ( variable ) ) + +/// Bit value data structure +typedef enum sHalBitVal // For Bit operations +{ + eHAL_CLEAR, + eHAL_SET +}tHalBitVal; + +// ------------------------------------------------------------- +/// MMH APIs +enum { + eHI_PRI, + ePROT, + eDBG +}; + +/// System role definition on a per BSS +typedef enum eBssSystemRole +{ + eSYSTEM_UNKNOWN_ROLE, + eSYSTEM_AP_ROLE, + eSYSTEM_STA_IN_IBSS_ROLE, + eSYSTEM_STA_ROLE, + eSYSTEM_BTAMP_STA_ROLE, + eSYSTEM_BTAMP_AP_ROLE, + + eSYSTEM_LAST_ROLE, + eSYSTEM_MULTI_BSS_ROLE = eSYSTEM_LAST_ROLE +} tBssSystemRole; + + +// --------------------------------------- +// Channel Bonding Sideband configuration +// --------------------------------------- +typedef enum sHalCBsidebandType +{ + eHAL_SIDEBAND_CENTER=0, + eHAL_SIDEBAND_LOWER, + eHAL_SIDEBAND_UPPER, + eHAL_SIDEBAND_COPY +}tHalCBsidebandType; + + +/// HAL states +typedef enum { + eHAL_IDLE, + eHAL_INIT, + eHAL_CFG, //CFG download completed. + eHAL_STARTED, //halProcessStartEvent compelted. + eHAL_SYS_READY, //Sys_ready msg received from HDD. + eHAL_NORMAL, //Sys_ready msg received from HDD and halProcessStartEvent completed. +} tHAL_STATE; + + + + +// Type to define softmac mode (also system mode) +typedef enum +{ + //3- Promisc, 2 - Scan, 1 - Learn 0 - Normal + eHAL_SYS_MODE_NORMAL = 0, + eHAL_SYS_MODE_LEARN, + eHAL_SYS_MODE_SCAN, + eHAL_SYS_MODE_PROMISC, + eHAL_SYS_MODE_SUSPEND_LINK, + eHAL_SYS_MODE_ROAM_SCAN, + eHAL_SYS_MODE_ROAM_SUSPEND_LINK, +} eHalSysMode; + + + + +// HAL frame types. Used on the TxRx APIs and the +// corresponding PAL routines. +typedef enum { + + HAL_TXRX_FRM_RAW, + HAL_TXRX_FRM_ETH2, + HAL_TXRX_FRM_802_3, + HAL_TXRX_FRM_802_11_MGMT, + HAL_TXRX_FRM_802_11_CTRL, + HAL_TXRX_FRM_802_11_DATA, + HAL_TXRX_FRM_IGNORED, //This frame will be dropped + HAL_TXRX_FRM_MAX + +} eFrameType; + + +typedef enum +{ + ANI_TXDIR_IBSS = 0, + ANI_TXDIR_TODS, + ANI_TXDIR_FROMDS, + ANI_TXDIR_WDS + +} eFrameTxDir; + +typedef enum +{ + eRF_BAND_UNKNOWN = 0, + eRF_BAND_2_4_GHZ = 1, + eRF_BAND_5_GHZ = 2 +} eRfBandMode; + + +#ifndef __offsetof +#define __offsetof(type, field) ((tANI_U32)(&((type *)0)->field)) +#endif + +#ifndef offsetof +#define offsetof(type, field) __offsetof(type, field) +#endif + +#define HAL_MAX_TXPOWER_INVALID 127 + +/* These are the min/max tx power (non virtual rates) range + * supported by rome/prima hardware + */ +#define MIN_TX_PWR_CAP 8 +#define MAX_TX_PWR_CAP 22 + +/* Moving the miscellaneous defination required by UMAC are moved here from + * volansdefs.h */ +/* -------------------------------------------------------------------- + * Support definitions for taurus + * -------------------------------------------------------------------- + */ + +/* + * Volans supports 8 stations in hardware + * + * Volans without Virtual STA feature can only support 8 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 6 Soft AP Stations (hard) + * + * Volans with Virtual STA feature supports 14 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 2 General Purpose Stations to support Virtual STAs (hard) + * 10 Soft AP Stations (4 hard/6 virtual) + */ + +#define HAL_INVALID_BSSIDX (HAL_NUM_BSSID + 1) +#define HAL_NUM_UMA_DESC_ENTRIES 8 +#define MAX_NUM_OF_BACKOFFS 8 + +#define IS_VALID_BSSIDX(__x) \ + ((__x) < HAL_NUM_BSSID) + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define HAL_NUM_ASSOC_STA 32 +#define HAL_NUM_STA 41 +#define HAL_NUM_HW_STA 16 +#define HAL_NUM_GPSTA 4 +#define HAL_NUM_VSTA (HAL_NUM_STA - HAL_NUM_HW_STA) + +#define QWLANFW_MAX_NUM_VSTA HAL_NUM_VSTA +#define QWLANFW_VSTA_INVALID_IDX (HAL_NUM_STA + 1) +#define QWLAN_VSTA_MIN_IDX HAL_NUM_HW_STA +#define QWLANFW_NUM_GPSTA HAL_NUM_GPSTA + + +#define IS_VSTA_VALID_IDX(__x) \ + ((__x) != QWLANFW_VSTA_INVALID_IDX) + +#define IS_VSTA_IDX(__x) \ + (((__x) >= QWLAN_VSTA_MIN_IDX) && ((__x) < HAL_NUM_STA)) + + +// is the STA a General Purpose STA? +#define IS_GPSTA_IDX(__x) \ + (((__x) >= (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) && \ + ((__x) < HAL_NUM_HW_STA)) + +// is the STA a HW STA (excluding GP STAs) +#define IS_HWSTA_IDX(__x) \ + ((__x) < (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) + +#else +/*In prima 12 HW stations are supported including BCAST STA(staId 0) + and SELF STA(staId 1) so total ASSOC stations which can connect to Prima + SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations. */ +#define HAL_NUM_STA 12 +#define HAL_NUM_ASSOC_STA 10 +#define HAL_NUM_HW_STA 12 +#endif + +/* + * From NOVA Mac Arch document + * Encryp. mode The encryption mode + * 000: Encryption functionality is not enabled + * 001: Encryption is set to WEP + * 010: Encryption is set to WEP 104 + * 011: Encryption is set to TKIP + * 100: Encryption is set to AES + * 101 - 111: Reserved for future + */ + +#define HAL_ENC_POLICY_NULL 0 +#define HAL_ENC_POLICY_WEP40 1 +#define HAL_ENC_POLICY_WEP104 2 +#define HAL_ENC_POLICY_TKIP 3 +#define HAL_ENC_POLICY_AES_CCM 4 + +#define STACFG_MAX_TC 8 + + +#endif + diff --git a/drivers/staging/prima/CORE/WDA/inc/legacy/palTypes.h b/drivers/staging/prima/CORE/WDA/inc/legacy/palTypes.h new file mode 100644 index 000000000000..47123a3a4dd5 --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/inc/legacy/palTypes.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( PALTYPES_H__ ) +#define PALTYPES_H__ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file palTypes.h + + \brief Exports and types for the Platform Abstraction Layer typedefs. + These are common typedefs that can be used across Platforms (OS/compiler + and bus types). All common code should adhere to these common types. + + $Id$ + + ... description... + + ========================================================================== */ +#ifndef WINXP_APPS_BUILD +#include "vos_types.h" +#include "vos_api.h" +#endif /* WINXP_APPS_BUILD */ + +#include "halLegacyPalTypes.h" + +#ifndef MK_IMAGE_HDR + +// +// Validate the Bus type being built.... +// +#if defined(ANI_BUS_TYPE_PCI) + +#if defined( ANI_BUS_TYPE_PCIe ) || defined( ANI_BUS_TYPE_PLATFORM ) +#error "more than one ANI_BUS_TYPE_xxx is defined for this build" +#endif // + +#elif defined( ANI_BUS_TYPE_PCIe ) + +#if defined( ANI_BUS_TYPE_PCI ) || defined( ANI_BUS_TYPE_PLATFORM ) +#error "more than one ANI_BUS_TYPE_xxx is defined for this build" +#endif + +#elif defined( ANI_BUS_TYPE_PLATFORM ) + +#if defined( ANI_BUS_TYPE_PCIe ) || defined(ANI_BUS_TYPE_PCI) +#error "more than one ANI_BUS_TYPE_xxx is defined for this build" +#endif + +#elif !( defined( ANI_BUS_TYPE_PCIe ) || defined(ANI_BUS_TYPE_PCI) || defined( ANI_BUS_TYPE_PLATFORM ) ) + +#error "NONE of the ANI_BUS_TYPE_xxx are defined for this build" + +#endif + + +// +// Validate the OS Type being built... +// + +#if defined(ANI_OS_TYPE_ANDROID) // ANDROID + +#if defined(ANI_OS_TYPE_QNX) +#error "more than one ANI_OS_TYPE_xxx is defined for this build" +#endif + +#elif defined( ANI_OS_TYPE_QNX ) // QNX + +#if defined(ANI_OS_TYPE_ANDROID) +#error "more than one ANI_OS_TYPE_xxx is defined for this build" +#endif + + +#elif !defined(ANI_OS_TYPE_ANDROID) && !defined(ANI_OS_TYPE_QNX) // NONE +#error "NONE of the ANI_OS_TYPE_xxx are defined for this build" +#endif + + +// +// Validate the compiler... +// +#if ( defined( ANI_COMPILER_TYPE_MSVC ) && defined( ANI_COMPILER_TYPE_GCC ) && defined( ANI_COMPILER_TYPE_RVCT ) ) +#error "more than one ANI_COMPILER_TYPE_xxx is defined for this build" + +#elif !( defined( ANI_COMPILER_TYPE_MSVC ) || defined( ANI_COMPILER_TYPE_GCC ) || defined( ANI_COMPILER_TYPE_RVCT ) ) +#error "NONE of the ANI_COMPILER_TYPE_xxx are defined for this build" + +#endif + + + +// some differences related to the compiler being used... +#if defined ( ANI_COMPILER_TYPE_GCC ) + +#define ANI_INLINE_FUNCTION static __inline__ + +#elif defined( ANI_COMPILER_TYPE_MSVC ) + +#define ANI_INLINE_FUNCTION __inline + +#elif defined( ANI_COMPILER_TYPE_RVCT ) + +#define ANI_INLINE_FUNCTION INLINE + +#else + +#error "invalid ANI_COMPILER_TYPE definition" + +#endif +#endif + + + + +// Common type definitions... + + +typedef tANI_U32 tANI_U32_OR_PTR; + +// Buffer address; could be virt or phys; could be 32- or 64-bit depending on compile option +typedef tANI_U32_OR_PTR tANI_BUFFER_ADDR; +// which boolean is the most usefule...or both ? + +typedef enum tagAniBoolean +{ + eANI_BOOLEAN_FALSE = 0, + eANI_BOOLEAN_TRUE, + + eANI_BOOLEAN_OFF = 0, + eANI_BOOLEAN_ON = 1, +} eAniBoolean; + + + +// +// MAC address data type... +// +// review the usefulness of this type. I suspect this type is not +// real useful unless we provide some 'helper' functions to manage +// the MAC addresses. +// +#define ANI_MAC_ADDR_SIZE ( 6 ) +typedef tANI_U8 tAniMacAddr[ ANI_MAC_ADDR_SIZE ]; + + + + + +/** ------------------------------------------------------------------------- * + + \typedef tHddHandle + + \brief Handle to the HDD. The HDD handle is given to the HAL from + the HDD on halOpen. The HDD handle is an input to all HDD/PAL function + calls and represents an opaque handle to the HDD instance that is tied + to the HAL instance, opened through halOpen. + + The HDD must be able to derive it's internal instance structure pointer + through this handle. hint hint... + + -------------------------------------------------------------------------- */ +typedef void *tHddHandle; +// define a value for an invalid HAL handle..... +#define HDD_INVALID_HDD_HANDLE ( NULL ) + + +// For packet classification routines +#define PAL_BIT_MASK(offset) (1 << (offset)) +#define PAL_PKT_FLD_DSCP_OFFSET 0 +#define PAL_PKT_FLD_8021P_OFFSET 1 + +#define PAL_PKT_FLD_DSCP_MASK PAL_BIT_MASK(PAL_PKT_FLD_DSCP_OFFSET) +#define PAL_PKT_FLD_8021P_MASK PAL_BIT_MASK(PAL_PKT_FLD_8021P_OFFSET) + + + +/* +This represent an object for a spin lock and it is platform dependant +*/ +//User of this variable must initialize it to PAL_INVALID_SPINLOCK_HANDLE in order for validation to work. +typedef void * tPalSpinLockHandle; + +#define PAL_INVALID_SPINLOCK_HANDLE (NULL) + +/* + * This represent an object for a semaphore and it is platform dependant + */ +typedef void * tPalSemaphoreHandle; + + +#define PAL_TICKS_PER_SECOND 100 + +#endif diff --git a/drivers/staging/prima/CORE/WDA/inc/legacy/wlan_qct_hal.h b/drivers/staging/prima/CORE/WDA/inc/legacy/wlan_qct_hal.h new file mode 100644 index 000000000000..3d1909c5724b --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/inc/legacy/wlan_qct_hal.h @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_HAL_H +#define WLAN_QCT_HAL_H +#include "vos_status.h" +#include "halTypes.h" +#ifndef PALTYPES_H__ + + +/// unsigned 8-bit types +#define tANI_U8 v_U8_t + +/// unsigned 16-bit types +#define tANI_U16 v_U16_t + +/// unsigned 32-bit types +#define tANI_U32 v_U32_t + +/// signed 8-bit types +#define tANI_S8 v_S7_t + +/// signed 16-bit types +#define tANI_S16 v_S15_t + +/// signed 32-bit types +#define tANI_S32 v_S31_t + +#define eHalStatus VOS_STATUS + +#endif +#define QWLAN_HAL_DXE0_MASTERID 5 + +typedef struct sHalBdGeneric { + /* 0x00 */ + // ENDIAN BEGIN + tANI_U32 dpuRF : 8; + tANI_U32 dpuSignature:3; /* Signature on RA's DPU descriptor */ + tANI_U32 staSignature:3; + tANI_U32 reserved : 14; + tANI_U32 dpuNE : 1; + tANI_U32 dpuNC : 1; + tANI_U32 bdt : 2; /* BD type */ + // ENDIAN END + + /* 0x04 */ + // ENDIAN BEGIN + tANI_U32 reserved1:32; + // ENDIAN END + + + /* 0x08 */ + // ENDIAN BEGIN + tANI_U32 headPduIdx : 16; /* Head PDU index */ + tANI_U32 tailPduIdx : 16; /* Tail PDU index */ + // ENDIAN END + + /* 0x0c */ + // ENDIAN BEGIN + tANI_U32 mpduHeaderLength : 8; /* MPDU header length */ + tANI_U32 mpduHeaderOffset : 8; /* MPDU header start offset */ + tANI_U32 mpduDataOffset : 9; /* MPDU data start offset */ + tANI_U32 pduCount : 7; /* PDU count */ + // ENDIAN END + + /* 0x10 */ + // ENDIAN BEGIN + tANI_U32 mpduLength : 16; /* MPDU length */ + tANI_U32 reserved3:4; /* DPU compression feedback */ + tANI_U32 tid : 4; /* Traffic identifier, tid */ + tANI_U32 rateIndex : 8; + // ENDIAN END + + /* 0x14 */ + // ENDIAN BEGIN + tANI_U32 dpuDescIdx : 8; + tANI_U32 addr1Index : 8; //A1 index after RxP binary search + tANI_U32 addr2Index : 8; //A2 index after RxP binary search + tANI_U32 addr3Index : 8; //A3 index after RxP binary search + // ENDIAN END +//}__ani_attr_packed __ani_attr_aligned_4 tHalBdGeneric, *tpHalBdGeneric; +} tHalBdGeneric, *tpHalBdGeneric; + + +/* + * PDU without BD + */ + +typedef struct sHalPdu { + tANI_U8 payload[124]; + tANI_U32 nextPduIdx; /* LSB 16 bits */ +//} __ani_attr_packed __ani_attr_aligned_4 tHalPdu, *tpHalPdu; +} tHalPdu, *tpHalPdu; + +/* UAPSD parameters passed per AC to HAL from TL */ +typedef struct sUapsdInfo { + tANI_U8 staidx; // STA index + tANI_U8 ac; // Access Category + tANI_U8 up; // User Priority + tANI_U32 srvInterval; // Service Interval + tANI_U32 susInterval; // Suspend Interval + tANI_U32 delayInterval; // Delay Interval +} tUapsdInfo, tpUapsdInfo; + +#define HAL_TXBD_BDRATE_DEFAULT 0 +#define HAL_TXBD_BDRATE_FIRST 1 +#define HAL_TXBD_BDRATE_SECOND 2 +#define HAL_TXBD_BDRATE_THIRD 3 + +#define HAL_FRAME_TYPE_MASK 0x30 +#define HAL_FRAME_TYPE_OFFSET 0x4 +#define HAL_FRAME_SUBTYPE_MASK 0x0F + +#define HAL_TXBD_BD_SSN_FILL_HOST 0 +#define HAL_TXBD_BD_SSN_FILL_DPU_NON_QOS 1 +#define HAL_TXBD_BD_SSN_FILL_DPU_QOS 2 + +#define HAL_ACKPOLICY_ACK_REQUIRED 0 +#define HAL_ACKPOLICY_ACK_NOTREQUIRED 1 + +#define HAL_BDRATE_BCDATA_FRAME 1 +#define HAL_BDRATE_BCMGMT_FRAME 2 +#define HAL_BDRATE_CTRL_FRAME 3 + +/* Default values for FillTx BD */ +#define HAL_DEFAULT_UNICAST_ENABLED 1 +#define HAL_RMF_DISABLED 0 +#define HAL_RMF_ENABLED 1 +#define HAL_NO_ENCRYPTION_DISABLED 0 +#define HAL_NO_ENCRYPTION_ENABLED 1 + +#define WLANHAL_RX_BD_ADDR3_SELF_IDX 0 + +// Should not use tHalTxBd nor tHalRxBd. UMAC doesn't know these HAL structure. +#define WLANHAL_TX_BD_HEADER_SIZE 40 +#define WLANHAL_RX_BD_HEADER_SIZE 76 + + +#define WLANHAL_RX_BD_HEADER_OFFSET 0 + +#define WLANHAL_RX_BD_GET_MPDU_H_OFFSET( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduHeaderOffset) + +#define WLANHAL_RX_BD_GET_MPDU_D_OFFSET( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduDataOffset) + +#define WLANHAL_RX_BD_GET_MPDU_LEN( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduLength) + +#define WLANHAL_RX_BD_GET_MPDU_H_LEN( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->mpduHeaderLength) + +#define WLANHAL_RX_BD_GET_FT( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->ft) + +#define WLANHAL_RX_BD_GET_LLC( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->llc) + +#define WLANHAL_RX_BD_GET_TID( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->tid) + +#define WLANHAL_RX_BD_GET_ASF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->asf) + +#define WLANHAL_RX_BD_GET_AEF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->aef) + +#define WLANHAL_RX_BD_GET_LSF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->lsf) + +#define WLANHAL_RX_BD_GET_ESF( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->esf) + +#define WLANHAL_RX_BD_GET_STA_ID( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->addr2Index) +#define WLANHAL_RX_BD_GET_ADDR3_IDX( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->addr3Index) +#define WLANHAL_RX_BD_GET_ADDR1_IDX( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->addr1Index) + +#define WLANHAL_TX_BD_GET_TID( _pvBDHeader ) (((tpHalTxBd)_pvBDHeader)->tid) +#define WLANHAL_TX_BD_GET_STA_ID( _pvBDHeader ) (((tpHalTxBd)_pvBDHeader)->staIndex) + +#define WLANHAL_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->dpuSignature) + +#define WLANHAL_FC_RX_BD_REPORT_CONTENT_SIZE (2 * HAL_NUM_STA * sizeof(tANI_U8)) // size of fcSTATxQLen[HAL_NUM_STA]+fcSTACurTxRate[HAL_NUM_STA] +#define WLANHAL_FC_TX_BD_HEADER_SIZE sizeof(tHalFcTxBd) +#define WLANHAL_RX_BD_GET_FC( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fc) +#define WLANHAL_RX_BD_GET_RX_TIME_STAMP( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->mclkRxTimestamp) +#define WLANHAL_RX_BD_GET_STA_VALID_MASK( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTAValidMask) +#define WLANHAL_RX_BD_GET_STA_PS_STATE( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTAPwrSaveStateMask) +#define WLANHAL_RX_BD_GET_STA_TH_IND( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTAThreshIndMask) +#define WLANHAL_RX_BD_GET_STA_TXQ_STATUS( _pvBDHeader ) (((tpHalFcRxBd)_pvBDHeader)->fcSTATxQStatus) +#define WLANHAL_RX_BD_GET_STA_TXQ_LEN( _pvBDHeader, staIdx ) (((tpHalFcRxBd)_pvBDHeader)->fcSTATxQLen[staIdx]) +#define WLANHAL_RX_BD_GET_STA_CUR_TX_RATE( _pvBDHeader, staIdx ) (((tpHalFcRxBd)_pvBDHeader)->fcSTACurTxRate[staIdx]) + +#define WLANHAL_TX_BD_GET_RMF(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rmf) + +#define WLANHAL_TX_BD_GET_UB(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->ub) + +#define WLANHAL_RX_BD_GET_RMF(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rmf) + +#define WLANHAL_RX_BD_GET_UB(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->ub) + +#define WLANHAL_RX_BD_GET_RATEINDEX(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rateIndex) + +#define WLANHAL_RX_BD_GET_TIMESTAMP(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->mclkRxTimestamp) + +#define tHalFcRxBd halFcRxBd_type +#define tpHalFcRxBd phalFcRxBd_type +#define tHalFcTxBd halFcTxBd_type +#define tpHalFcTxBd pHalFcTxBd_type +#define tHalFcTxParams tFcTxParams_type +#define tHalFcRxParams tFcRxParams_type +#define tpHalFcTxParams pFcTxParams_type +#define tpHalFcRxParams pFcRxParams_type + +/*------------ RSSI and SNR Information extraction -------------*/ +#define WLANHAL_RX_BD_GET_RSSI0( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats0) >> 24) & 0x7f) +#define WLANHAL_RX_BD_GET_RSSI1( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats0) >> 16) & 0xff) +#define WLANHAL_RX_BD_GET_RSSI2( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats0) >> 0) & 0xff) +#define WLANHAL_RX_BD_GET_RSSI3( _pvBDHeader ) \ + ((((tpHalRxBd)_pvBDHeader)->phyStats0) & 0xff) + +// Get the average of the 4 values. +#define WLANHAL_GET_RSSI_AVERAGE( _pvBDHeader ) \ + (((WLANHAL_RX_BD_GET_RSSI0(_pvBDHeader)) + \ + (WLANHAL_RX_BD_GET_RSSI1(_pvBDHeader)) + \ + (WLANHAL_RX_BD_GET_RSSI2(_pvBDHeader)) + \ + (WLANHAL_RX_BD_GET_RSSI3(_pvBDHeader))) / 4) + +// Get the SNR value from PHY Stats +#define WLANHAL_RX_BD_GET_SNR( _pvBDHeader ) \ + (((((tpHalRxBd)_pvBDHeader)->phyStats1) >> 24) & 0xff) +/*-----------------------------------------------------------------*/ +#define WLANHAL_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((tpHalRxBd)_pvBDHeader)->dpuSignature) + + +#define WLANHAL_TX_BD_SET_MPDU_DATA_OFFSET( _bd, _off ) (((tpHalTxBd)_bd)->mpduDataOffset = _off) + +#define WLANHAL_TX_BD_SET_MPDU_HEADER_OFFSET( _bd, _off ) (((tpHalTxBd)_bd)->mpduHeaderOffset = _off) + +#define WLANHAL_TX_BD_SET_MPDU_HEADER_LEN( _bd, _len ) (((tpHalTxBd)_bd)->mpduHeaderLength = _len) + +#define WLANHAL_TX_BD_SET_MPDU_LEN( _bd, _len ) (((tpHalTxBd)_bd)->mpduLength = _len) + +#define WLANHAL_RX_BD_GET_BA_OPCODE(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->reorderOpcode) + +#define WLANHAL_RX_BD_GET_BA_FI(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->reorderFwdIdx) + +#define WLANHAL_RX_BD_GET_BA_SI(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->reorderSlotIdx) + +#define WLANHAL_RX_BD_GET_BA_CSN(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->currentPktSeqNo) + +#define WLANHAL_RX_BD_GET_BA_ESN(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->expectedPktSeqNo) + +#define WLANHAL_RX_BD_GET_RXP_FLAGS(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->rxpFlags) + +#define WLANHAL_RX_BD_GET_TYPE_SUBTYPE(_pvBDHeader) (((tpHalRxBd)_pvBDHeader)->frameTypeSubtype) +#define WLANHAL_RX_BD_SET_TYPE_SUBTYPE( _bd, _typeSubtype ) (((tpHalRxBd)_bd)->frameTypeSubtype = _typeSubtype) + + +#define WLANHAL_RX_BD_ASF_SET 1 /*The value of the field when set and pkt is AMSDU*/ + +#define WLANHAL_RX_BD_FSF_SET 1 + +#define WLANHAL_RX_BD_LSF_SET 1 + +#define WLANHAL_RX_BD_AEF_SET 1 + + +#define WLANHAL_RX_BD_LLC_PRESENT 0 /*The value of the field when LLC is present*/ + +#define WLANHAL_RX_BD_FT_DONE 1 /* The value of the field when frame xtl was done*/ + +/*DPU_FEEDBACK_WPI_UNPROTECTED macro defined in volansdefs.h which is not available + for UMAC in prima so declared it here */ +#define DPU_FEEDBACK_WPI_UNPROTECTED 0x20 +#define WLANHAL_RX_IS_UNPROTECTED_WPI_FRAME(_pvBDHeader) \ + (DPU_FEEDBACK_WPI_UNPROTECTED == ((WDI_DS_RxMetaInfoType *)_pvBDHeader)->dpuFeedback) + +/*========================================================================== + + FUNCTION WLANHAL_RxBD_GetFrameTypeSubType + + DESCRIPTION + Called by TL to retrieve the type/subtype of the received frame. + + DEPENDENCIES + TL should pass a valid RxBD buffer pointer. + + PARAMETERS + + IN + pvBDHeader: Void pointer to the RxBD buffer. + usFrmCtrl:the frame ctrl of the 802.11 header + + RETURN VALUE + A byte which contains both type and subtype info. LSB four bytes (b0 to b3) + is subtype and b5-b6 is type info. + + SIDE EFFECTS + +============================================================================*/ + +tANI_U8 WLANHAL_RxBD_GetFrameTypeSubType(v_PVOID_t _pvBDHeader, tANI_U16 usFrmCtrl); + + +#define HAL_TXCOMP_REQUESTED_MASK 0x1 //bit 0 for TxComp intr requested. +#define HAL_USE_SELF_STA_REQUESTED_MASK 0x2 //bit 1 for STA overwrite with selfSta Requested. +#define HAL_TX_NO_ENCRYPTION_MASK 0x4 //bit 2. If set, the frame is not to be encrypted +#if defined(LIBRA_WAPI_SUPPORT) +#define HAL_WAPI_STA_MASK 0x8 //bit 3. If set, this frame is for WAPI station +#endif + +#define HAL_TRIGGER_ENABLED_AC_MASK 0x10 //bit 4 for data frames belonging to trigger enabled AC +#define HAL_USE_NO_ACK_REQUESTED_MASK 0x20 + +#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames +#define HAL_USE_PEER_STA_REQUESTED_MASK 0x80 //bit 7 will be used to control frames for p2p interface + +#ifdef FEATURE_WLAN_TDLS +#define HAL_TDLS_PEER_STA_MASK 0x80 //bit 7 set for TDLS peer station +#endif + +#ifdef WLAN_FEATURE_RMC +#define HAL_RMC_REQUESTED_MASK 0x100 +#endif + +#define HAL_USE_BD_RATE_1_MASK 0x1000 // bit 12 for BD RATE 1 +#define HAL_USE_BD_RATE_2_MASK 0x2000 // bit 13 for BD RATE 1 +#define HAL_USE_BD_RATE_3_MASK 0x4000 // bit 14 for BD RATE 1 +#define HAL_USE_FW_IN_TX_PATH 0x200 //bit 9 to send via WQ5 +/*========================================================================== + + FUNCTION WLANHAL_FillTxBd + + DESCRIPTION + Called by PE to register as a client for management frames delivery. + + DEPENDENCIES + TL must be initialized before this API can be called. + + PARAMETERS + + IN + pAdapter: pointer to the global adapter context;a handle to TL's + control block can be extracted from its context + vosFrmBuf: pointer to a vOSS buffer containing the management + frame to be transmitted + usFrmLen: the length of the frame to be transmitted; information + is already included in the vOSS buffer + wFrmType: the type of the frame being transmitted + tid: tid used to transmit this frame + pfnCompTxFunc: function pointer to the transmit complete routine + voosBDHeader: pointer to the BD header + txFlag: can have appropriate bit setting as required + + #define HAL_TXCOMP_REQUESTED_MASK 0x1 //bit 0 for TxComp intr requested. + #define HAL_USE_SELF_STA_REQUESTED_MASK 0x2 //bit 1 for STA overwrite with selfSta Requested. + #define HAL_TX_NO_ENCRYPTION_MASK 0x4 //bit 2. If set, the frame is not to be encrypted +#if defined(FEATURE_WLAN_WAPI) + #define HAL_WAPI_STA_MASK 0x8 //bit 3. If set, this frame is for WAPI station +#endif + + uTimestamp: pkt timestamp + + + RETURN VALUE + The result code associated with performing the operation + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WLANHAL_FillTxBd(void *pAdapter, tANI_U8 typeSubtype, void *pDestMacAddr, void *pAddr2, + tANI_U8* ptid, tANI_U8 disableFrmXtl, void *pTxBd, tANI_U32 txFlag, tANI_U32 timeStamp); + +VOS_STATUS WLANHAL_FillFcTxBd(void *pVosGCtx, void *pFcParams, void *pFcTxBd); +/** To swap the report part of FC RxBD */ +void WLANHAL_SwapFcRxBd(tANI_U8 *pBd); + +/* To swap the data */ +void WLANHAL_Swap32Bytes(tANI_U8* pData, tANI_U32 size); + +/** To swap the RxBD */ +void WLANHAL_SwapRxBd(tANI_U8 *pBd); +void WLANHAL_RxAmsduBdFix(void *pVosGCtx,v_PVOID_t _pvBDHeader); + +#ifdef WLAN_PERF +tANI_U32 WLANHAL_TxBdFastFwd(void *pAdapter, tANI_U8 *pDestMac, tANI_U8 tid, tANI_U8 unicastDst, void *pTxBd, tANI_U16); +#endif + +VOS_STATUS WLANHAL_EnableUapsdAcParams(void* pVosGCtx, tANI_U8 staIdx, tUapsdInfo *pUapsdInfo); +VOS_STATUS WLANHAL_DisableUapsdAcParams(void* pVosGCtx, tANI_U8 staIdx, tANI_U8 ac); + +VOS_STATUS WLANHAL_EnableIdleBdPduInterrupt(void* pVosGCtx, tANI_U8 idleBdPduThreshold); + +#ifdef FEATURE_ON_CHIP_REORDERING +tANI_U8 WLANHAL_IsOnChipReorderingEnabledForTID(void* pVosGCtx, tANI_U8 staIdx, tANI_U8 tid); +#endif + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +v_BOOL_t WLANHAL_IsHwFrameTxTranslationCapable(v_PVOID_t pVosGCtx, tANI_U8 staIdx); +#endif + +#define tHalRxBd halRxBd_type +#define tpHalRxBd phalRxBd_type + +#define tHalTxBd halTxBd_type +#define tpHalTxBd pHalTxBd_type + +#ifdef BA_PARAM_STRUCTURE +#else +#define BA_PARAM_STRUCTURE +// +// HAL --> TL +// Messages indicating the setup and/or teardown of +// A-MPDU/BA sessions with a given peer HT MAC entity +// + +// +// A data structure identifying all of the variables +// in a typical A-MPDU/BA setup +// +typedef struct sBAParams +{ + + // A unique BA Session ID that has been assigned by HAL + // for the curent BA Session + tANI_U16 baSessionID; + + // TID for which the BA session has been setup + tANI_U8 baTID; + + // BA Buffer Size allocated for the current BA session //Should be deleted. needs TL change. use winSize instead + tANI_U8 baBufferSize; + + tANI_U16 SSN; + tANI_U8 winSize; + tANI_U8 STAID; + +} tBAParams, *tpBAParams; + +// +// TL -> HAL +// tSirMsgQ.type = SIR_HAL_HDD_ADDBA_RSP +// +typedef struct sAddBARsp +{ + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + //BA session ID + tANI_U16 baSessionID; + + tANI_U16 replyWinSize; +}tAddBARsp, *tpAddBARsp; + +// +// HAL -> TL +// tSirMsgQ.type = SIR_HAL_ADDBA_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = "allocated" instance of tpAddBAInd +// +typedef struct sAddBAInd +{ + + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + tBAParams baSession; + +} tAddBAInd, *tpAddBAInd; + +// +// HAL -> TL +// tSirMsgQ.type = SIR_HAL_DELBA_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = "allocated" instance of tpDelBAInd +// +// TL -> HAL +// tSirMsgQ.type = SIR_HAL_BA_FAIL_IND +// tSirMsgQ.reserved = 0 +// tSirMsgQ.body = "allocated" instance of tpDelBAInd +// +typedef struct sDelBAInd +{ + tANI_U8 staIdx; + + tANI_U8 baTID; + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + +} tDelBAInd, *tpDelBAInd; +#endif + +/*=============================================== + * + * TL <-> HAL structures + * + *=============================================== + */ +// +// TL -> HAL +// tSirMsgQ.type = SIR_HAL_TL_FLUSH_AC_REQ +// +typedef struct sFlushACReq +{ + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + +} tFlushACReq, *tpFlushACReq; + +// +// +// HAL -> TL +// tSirMsgQ.type = SIR_HAL_TL_FLUSH_AC_RSP +// +typedef struct sFlushACRsp +{ + // Message Type + tANI_U16 mesgType; + + // Message Length + tANI_U16 mesgLen; + + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + + // status of the Flush operation + tANI_U8 status; +} tFlushACRsp, *tpFlushACRsp; + +#endif + diff --git a/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h b/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h new file mode 100644 index 000000000000..997c80d5fcbe --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda.h @@ -0,0 +1,2217 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_WDA_H +#define WLAN_QCT_WDA_H + +/*=========================================================================== + + W L A N DEVICE ADAPTATION L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan adaptation layer for Prima + and Volans. + + For Volans this layer is actually a thin layer that maps all WDA messages and + functions to equivalent HAL messages and functions. The reason this layer was introduced + was to keep the UMAC identical across Prima and Volans. This layer provides the glue + between SME, PE , TL and HAL. + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------- +10/05/2011 haparna Adding support for Keep Alive Feature +01/27/2011 rnair Adding WDA support for Volans. +12/08/2010 seokyoun Move down HAL interfaces from TL to WDA + for UMAC convergence btween Volans/Libra and Prima +08/25/2010 adwivedi WDA Context and exposed API's +=========================================================================== */ + +#include "aniGlobal.h" + + +# include "wlan_qct_wdi_ds.h" + + +/* Add Include */ + +typedef enum +{ + WDA_INIT_STATE, + WDA_START_STATE, + WDA_READY_STATE, + WDA_PRE_ASSOC_STATE, + WDA_BA_UPDATE_TL_STATE, + WDA_BA_UPDATE_LIM_STATE, + WDA_STOP_STATE, + WDA_CLOSE_STATE +}WDA_state; + +typedef enum +{ + WDA_PROCESS_SET_LINK_STATE, + WDA_IGNORE_SET_LINK_STATE +}WDA_processSetLinkStateStatus; + +typedef enum +{ + WDA_DISABLE_BA, + WDA_ENABLE_BA +}WDA_BaEnableFlags; + +typedef enum +{ + WDA_INVALID_STA_INDEX, + WDA_VALID_STA_INDEX +}WDA_ValidStaIndex; +typedef enum +{ + eWDA_AUTH_TYPE_NONE, //never used + // MAC layer authentication types + eWDA_AUTH_TYPE_OPEN_SYSTEM, + // Upper layer authentication types + eWDA_AUTH_TYPE_WPA, + eWDA_AUTH_TYPE_WPA_PSK, + + eWDA_AUTH_TYPE_RSN, + eWDA_AUTH_TYPE_RSN_PSK, + eWDA_AUTH_TYPE_FT_RSN, + eWDA_AUTH_TYPE_FT_RSN_PSK, + eWDA_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + eWDA_AUTH_TYPE_WAPI_WAI_PSK, + eWDA_AUTH_TYPE_CCKM_WPA, + eWDA_AUTH_TYPE_CCKM_RSN, + eWDA_AUTH_TYPE_RSN_PSK_SHA256, + eWDA_AUTH_TYPE_RSN_8021X_SHA256, +}WDA_AuthType; + +#define IS_FW_IN_TX_PATH_FEATURE_ENABLE ((WDI_getHostWlanFeatCaps(FW_IN_TX_PATH)) & (WDA_getFwWlanFeatCaps(FW_IN_TX_PATH))) +#define IS_MUMIMO_BFORMEE_CAPABLE ((WDI_getHostWlanFeatCaps(MU_MIMO)) & (WDA_getFwWlanFeatCaps(MU_MIMO))) +#define IS_FEATURE_BCN_FLT_DELTA_ENABLE ((WDI_getHostWlanFeatCaps(BCN_IE_FLT_DELTA)) & (WDA_getFwWlanFeatCaps(BCN_IE_FLT_DELTA))) +#define IS_FEATURE_FW_STATS_ENABLE ((WDI_getHostWlanFeatCaps(FW_STATS)) & (WDA_getFwWlanFeatCaps(FW_STATS))) +/*-------------------------------------------------------------------------- + Utilities + --------------------------------------------------------------------------*/ + +#define WDA_TLI_CEIL( _a, _b) (( 0 != (_a)%(_b))? (_a)/(_b) + 1: (_a)/(_b)) + +/* + * Check the version number and find if MCC feature is supported or not + */ +#define IS_MCC_SUPPORTED (WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual( 0, 1, 1, 0)) +#define IS_FEATURE_SUPPORTED_BY_FW(featEnumValue) (!!WDA_getFwWlanFeatCaps(featEnumValue)) +#define IS_FEATURE_SUPPORTED_BY_DRIVER(featEnumValue) (!!WDA_getHostWlanFeatCaps(featEnumValue)) + +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE +#define IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE ((WDA_getFwWlanFeatCaps(WLANACTIVE_OFFLOAD)) & (WDI_getHostWlanFeatCaps(WLANACTIVE_OFFLOAD))) +#else +#define IS_ACTIVEMODE_OFFLOAD_FEATURE_ENABLE 0 +#endif + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE ((WDI_getHostWlanFeatCaps(WLAN_ROAM_SCAN_OFFLOAD)) & (WDA_getFwWlanFeatCaps(WLAN_ROAM_SCAN_OFFLOAD))) +#else +#define IS_ROAM_SCAN_OFFLOAD_FEATURE_ENABLE 0 +#endif + +#define IS_DYNAMIC_WMM_PS_ENABLED ((WDI_getHostWlanFeatCaps(DYNAMIC_WMM_PS)) & (WDA_getFwWlanFeatCaps(DYNAMIC_WMM_PS))) + +/* Check if heartbeat offload is enabled */ +#define IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE ((WDI_getHostWlanFeatCaps(IBSS_HEARTBEAT_OFFLOAD)) & (WDA_getFwWlanFeatCaps(IBSS_HEARTBEAT_OFFLOAD))) + +#ifdef FEATURE_WLAN_TDLS +#define IS_ADVANCE_TDLS_ENABLE ((WDI_getHostWlanFeatCaps(ADVANCE_TDLS)) & (WDA_getFwWlanFeatCaps(ADVANCE_TDLS))) +#else +#define IS_ADVANCE_TDLS_ENABLE 0 +#endif +#define IS_HT40_OBSS_SCAN_FEATURE_ENABLE ((WDA_getFwWlanFeatCaps(HT40_OBSS_SCAN)) & (WDI_getHostWlanFeatCaps(HT40_OBSS_SCAN))) +#define IS_FRAME_LOGGING_SUPPORTED_BY_FW WDA_getFwWlanFeatCaps(MGMT_FRAME_LOGGING) + +typedef enum { + MODE_11A = 0, /* 11a Mode */ + MODE_11G = 1, /* 11b/g Mode */ + MODE_11B = 2, /* 11b Mode */ + MODE_11GONLY = 3, /* 11g only Mode */ + MODE_11NA_HT20 = 4, /* 11a HT20 mode */ + MODE_11NG_HT20 = 5, /* 11g HT20 mode */ + MODE_11NA_HT40 = 6, /* 11a HT40 mode */ + MODE_11NG_HT40 = 7, /* 11g HT40 mode */ + MODE_11AC_VHT20 = 8, + MODE_11AC_VHT40 = 9, + MODE_11AC_VHT80 = 10, +// MODE_11AC_VHT160 = 11, + MODE_11AC_VHT20_2G = 11, + MODE_11AC_VHT40_2G = 12, + MODE_11AC_VHT80_2G = 13, + MODE_UNKNOWN = 14, + MODE_MAX = 14 +} WLAN_PHY_MODE; + +#define WLAN_HAL_CHAN_FLAG_HT40_PLUS 6 +#define WLAN_HAL_CHAN_FLAG_PASSIVE 7 +#define WLAN_HAL_CHAN_ADHOC_ALLOWED 8 +#define WLAN_HAL_CHAN_AP_DISABLED 9 +#define WLAN_HAL_CHAN_FLAG_DFS 10 +#define WLAN_HAL_CHAN_FLAG_ALLOW_HT 11 /* HT is allowed on this channel */ +#define WLAN_HAL_CHAN_FLAG_ALLOW_VHT 12 /* VHT is allowed on this channel */ + +#define WDA_SET_CHANNEL_FLAG(pwda_channel,flag) do { \ + (pwda_channel)->channel_info |= (1 << flag); \ + } while(0) + +#define WDA_SET_CHANNEL_MODE(pwda_channel,val) do { \ + (pwda_channel)->channel_info &= 0xffffffc0; \ + (pwda_channel)->channel_info |= (val); \ + } while(0) + +#define WDA_SET_CHANNEL_MAX_POWER(pwda_channel,val) do { \ + (pwda_channel)->reg_info_1 &= 0xffff00ff; \ + (pwda_channel)->reg_info_1 |= ((val&0xff) << 8); \ + } while(0) + +#define WDA_SET_CHANNEL_REG_POWER(pwda_channel,val) do { \ + (pwda_channel)->reg_info_1 &= 0xff00ffff; \ + (pwda_channel)->reg_info_1 |= ((val&0xff) << 16); \ + } while(0) +#define WDA_SET_CUURENT_REG_DOMAIN(pwda_channel, val) do { \ + (pwda_channel)->reg_info_2 |= ((val&0x7) << 24); \ + (pwda_channel)->reg_info_2 |= 0x80000000; \ + } while(0) +#define WDA_SET_CHANNEL_MIN_POWER(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_1 &= 0xffffff00; \ + (pwlan_hal_update_channel)->reg_info_1 |= (val&0xff); \ + } while(0) +#define WDA_SET_CHANNEL_ANTENNA_MAX(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_2 &= 0xffffff00; \ + (pwlan_hal_update_channel)->reg_info_2 |= (val&0xff); \ + } while(0) +#define WDA_SET_CHANNEL_REG_CLASSID(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_1 &= 0x00ffffff; \ + (pwlan_hal_update_channel)->reg_info_1 |= ((val&0xff) << 24); \ + } while(0) + +#define WDA_IS_MCAST_FLT_ENABLE_IN_FW (WDA_getFwWlanFeatCaps(WLAN_MCADDR_FLT)) + +/*-------------------------------------------------------------------------- + Definitions for Data path APIs + --------------------------------------------------------------------------*/ + +/*As per 802.11 spec */ +#define WDA_TLI_MGMT_FRAME_TYPE 0x00 +#define WDA_TLI_CTRL_FRAME_TYPE 0x10 +#define WDA_TLI_DATA_FRAME_TYPE 0x20 + +/*802.3 header definitions*/ +#define WDA_TLI_802_3_HEADER_LEN 14 +/*802.11 header definitions - header len without QOS ctrl field*/ +#define WDA_TLI_802_11_HEADER_LEN 24 + +/*Determines the header len based on the disable xtl field*/ +#define WDA_TLI_MAC_HEADER_LEN( _dxtl) \ + ( ( 0 == _dxtl )? \ + WDA_TLI_802_3_HEADER_LEN:WDA_TLI_802_11_HEADER_LEN ) + +/* TX channel enum type: + + We have five types of TX packets so far and want to block/unblock each + traffic individually according to, for example, low resouce condition. + Define five TX channels for UMAC here. WDA can map these logical + channels to physical DXE channels if needed. +*/ +typedef enum +{ + WDA_TXFLOW_AC_BK = 0, + WDA_TXFLOW_AC_BE = 1, + WDA_TXFLOW_AC_VI = 2, + WDA_TXFLOW_AC_VO = 3, + WDA_TXFLOW_MGMT = 4, + WDA_TXFLOW_BAP = 1, /* BAP is sent as BE */ + WDA_TXFLOW_FC = 1, /* FC is sent as BE */ + WDA_TXFLOW_MAX +} WDA_TXFlowEnumType; + +#define WDA_TXFLOWMASK 0x1F /* 1~4bit:low priority ch / 5bit: high */ + +/* --------------------------------------------------------------------- + Libra and Volans specifics + + TODO Consider refactoring it and put it into two separate headers, + one for Prima and one for Volans + ----------------------------------------------------------------------*/ + +/* For backward compatability with SDIO. It's BAL header size for SDIO + interface. It's nothing for integrated SOC */ +#define WDA_DXE_HEADER_SIZE 0 + + +/*Minimum resources needed - arbitrary*/ + +/*DXE + SD*/ +#define WDA_WLAN_LIBRA_HEADER_LEN (20 + 8) + +#define WDA_TLI_BD_PDU_RESERVE_THRESHOLD 10 + + +# define WDA_TLI_MIN_RES_MF 1 +# define WDA_TLI_MIN_RES_BAP 2 +# define WDA_TLI_MIN_RES_DATA 3 + +# define WDA_NUM_STA 8 + +/* For backward compatability with SDIO. + + For SDIO interface, calculate the TX frame length and number of PDU + to transfter the frame. + + _vosBuff: IN VOS pakcet buffer pointer + _usPktLen: OUT VOS packet length in bytes + _uResLen: OUT Number of PDU to hold this VOS packet + _uTotalPktLen: OUT Totoal packet length including BAL header size + + For integrated SOC, _usPktLen and _uTotalPktLen is VOS pakcet length + which does include BD header length. _uResLen is hardcoded 2. + */ + +#ifdef WINDOWS_DT +#define WDA_TLI_PROCESS_FRAME_LEN( _vosBuff, _usPktLen, \ + _uResLen, _uTotalPktLen) \ + do \ + { \ + _usPktLen = wpalPacketGetFragCount((wpt_packet*)_vosBuff) + 1/*BD*/;\ + _uResLen = _usPktLen; \ + _uTotalPktLen = _usPktLen; \ + } \ + while ( 0 ) +#else /* WINDOWS_DT */ +#define WDA_TLI_PROCESS_FRAME_LEN( _vosBuff, _usPktLen, \ + _uResLen, _uTotalPktLen) \ + do \ + { \ + _usPktLen = 2; /* Need 1 descriptor per a packet + packet*/ \ + _uResLen = 2; /* Assume that we spends two DXE descriptor */ \ + _uTotalPktLen = _usPktLen; \ + } \ + while ( 0 ) +#endif /* WINDOWS_DT */ + + + +/*-------------------------------------------------------------------------- + Message Definitions + --------------------------------------------------------------------------*/ + +/* TX Tranmit request message. It serializes TX request to TX thread. + The message is processed in TL. +*/ +#define WDA_DS_TX_START_XMIT WLANTL_TX_START_XMIT +#define WDA_DS_FINISH_ULA WLANTL_FINISH_ULA + +#define VOS_TO_WPAL_PKT(_vos_pkt) ((wpt_packet*)_vos_pkt) + +#define WDA_TX_PACKET_FREED 0X0 + +/* Approximate amount of time to wait for WDA to stop WDI considering 1 pendig req too*/ +#define WDA_STOP_TIMEOUT ( (WDI_RESPONSE_TIMEOUT * 2) + WDI_SET_POWER_STATE_TIMEOUT + 5) +/*-------------------------------------------------------------------------- + Functions + --------------------------------------------------------------------------*/ + +/* For data client */ +typedef VOS_STATUS (*WDA_DS_TxCompleteCallback) ( v_PVOID_t pContext, vos_pkt_t *pFrameDataBuff, VOS_STATUS txStatus ); +typedef VOS_STATUS (*WDA_DS_RxPacketCallback) ( v_PVOID_t pContext, vos_pkt_t *pFrameDataBuff ); +typedef v_U32_t (*WDA_DS_TxPacketCallback) ( v_PVOID_t pContext, + vos_pkt_t **ppFrameDataBuff, + v_U32_t uSize, + v_U8_t uFlowMask, + v_BOOL_t *pbUrgent ); +typedef VOS_STATUS (*WDA_DS_ResourceCB) ( v_PVOID_t pContext, v_U32_t uCount ); + + +/* For management client */ +typedef VOS_STATUS (*WDA_DS_TxCompleteCb)( v_PVOID_t pContext, wpt_packet *pFrame ); +typedef VOS_STATUS (*WDA_DS_RxCompleteCb)( v_PVOID_t pContext, wpt_packet *pFrame ); +typedef VOS_STATUS (*WDA_DS_TxFlowControlCb)( v_PVOID_t pContext, v_U8_t acMask ); +typedef void (*pWDATxRxCompFunc)( v_PVOID_t pContext, void *pData ); + +//callback function for TX complete +//parameter 1 - global pMac pointer +//parameter 2 - txComplete status : 1- success, 0 - failure. +typedef eHalStatus (*pWDAAckFnTxComp)(tpAniSirGlobal, void *pData); + +#ifdef WLAN_FEATURE_RMC +typedef void (*WDA_txFailIndCallback)(tANI_U8 *, tANI_U8); +#endif /* WLAN_FEATURE_RMC */ + +typedef void (*WDA_suspend_req_callback)(tANI_U8 *, tANI_U8); + +typedef struct +{ + tANI_U16 ucValidStaIndex ; + /* + * each bit in ucUseBaBitmap represent BA is enabled or not for this tid + * tid0 ..bit0, tid1..bit1 and so on.. + */ + tANI_U8 ucUseBaBitmap ; + tANI_U8 bssIdx; + tANI_U32 currentOperChan; + tANI_U32 framesTxed[STACFG_MAX_TC]; +}tWdaStaInfo, *tpWdaStaInfo ; + +/* group all the WDA timers into this structure */ +typedef struct +{ + /* BA activity check timer */ + TX_TIMER baActivityChkTmr ; + + /* Tx Complete Timeout timer */ + TX_TIMER TxCompleteTimer ; + + /* Traffic Stats timer */ + TX_TIMER trafficStatsTimer ; +}tWdaTimers ; + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WDA_MAX_STA (41) +#else +#define WDA_MAX_STA (16) +#endif +typedef enum +{ + WDA_ADDSTA_REQ_NO_MEM = 0, + WDA_ADDSTA_REQ_WDI_FAIL = 1, + WDA_ADDSTA_RSP_NO_MEM = 2, + WDA_ADDSTA_RSP_WDI_FAIL = 3, + WDA_ADDSTA_MAX +} WDA_AddSelfStaFailReasonDebug; + +/*AddSelfSta Request and Response Debug*/ +typedef struct +{ + wpt_uint8 wdiAddStaSelfStaReqCounter; + wpt_uint8 wdiAddStaSelfStaRspCounter; + wpt_uint8 wdiAddStaSelfStaFailCounter; + wpt_uint8 ucSTASelfIdx; /* received SelfStaIdx*/ + wpt_uint8 wdaAddSelfStaFailReason; +} tWDA_AddSelfStaDebugParams; + +#define BMPS_IMPS_FAILURE_REPORT_THRESHOLD 10 + +/* Continous Response failure counts */ +typedef struct +{ + wpt_uint8 enterBmpsFailureCount; + wpt_uint8 exitBmpsFailureCount; + wpt_uint8 enterImpsFailureCount; + wpt_uint8 exitImpsFailureCount; +} tWDA_RespFailureCounts; + + +typedef struct +{ + v_PVOID_t pVosContext; /* global VOSS context*/ + v_PVOID_t pWdiContext; /* WDI context */ + WDA_state wdaState ; /* WDA state tracking */ + v_PVOID_t wdaWdiCfgApiMsgParam ; /* WDI API paramter tracking */ + v_PVOID_t wdaWdiCfgUpdateIntMsg ; /* WDI API CFG update param tracking */ + vos_event_t wdaWdiEvent; /* WDI API sync event */ + + /* Event to wait for tx completion */ + vos_event_t txFrameEvent; + + /* call back function for tx complete*/ + pWDATxRxCompFunc pTxCbFunc; + /* call back function for tx packet ack */ + pWDAAckFnTxComp pAckTxCbFunc; + tANI_U32 frameTransRequired; + tSirMacAddr macBSSID; /*BSSID of the network */ + tSirMacAddr macSTASelf; /*Self STA MAC*/ + + /* TX channel mask for flow control */ + v_U8_t uTxFlowMask; + /* TL's TX resource callback */ + WDA_DS_ResourceCB pfnTxResourceCB; + /* TL's TX complete callback */ + WDA_DS_TxCompleteCallback pfnTxCompleteCallback; + + tWdaStaInfo wdaStaInfo[WDA_MAX_STA]; + + tANI_U8 wdaMaxSta; + tWdaTimers wdaTimers; + + /* STA, AP, IBSS, MULTI-BSS etc.*/ + tBssSystemRole wdaGlobalSystemRole; + + /* driver mode, PRODUCTION or FTM */ + tDriverType driverMode; + + /* FTM Command Request tracking */ + v_PVOID_t wdaFTMCmdReq; + + /* Event to wait for suspend data tx*/ + vos_event_t suspendDataTxEvent; + /* Status frm TL after suspend/resume Tx */ + tANI_U8 txStatus; + /* Flag set to true when TL suspend timesout.*/ + tANI_U8 txSuspendTimedOut; + + vos_event_t waitOnWdiIndicationCallBack; + + /* version information */ + tSirVersionType wcnssWlanCompiledVersion; + tSirVersionType wcnssWlanReportedVersion; + tSirVersionString wcnssSoftwareVersionString; + tSirVersionString wcnssHardwareVersionString; + + + tSirLinkState linkState; + /* set, when BT AMP session is going on */ + v_BOOL_t wdaAmpSessionOn; + v_BOOL_t needShutdown; + v_BOOL_t wdiFailed; + v_BOOL_t wdaTimersCreated; + uintptr_t VosPacketToFree; + + /* Event to wait for WDA stop on FTM mode */ + vos_event_t ftmStopDoneEvent; + + tWDA_AddSelfStaDebugParams wdaAddSelfStaParams; + +#ifdef WLAN_FEATURE_RMC + WDA_txFailIndCallback txFailIndCallback; +#endif /* WLAN_FEATURE_RMC */ + tWDA_RespFailureCounts failureCounts; + wpt_uint8 mgmtTxfailureCnt; + uint8_t mgmt_pktfree_fail; + vos_lock_t mgmt_pkt_lock; + +} tWDA_CbContext ; + +typedef struct +{ + v_PVOID_t pWdaContext; /* pointer to WDA context*/ + v_PVOID_t wdaMsgParam; /* PE parameter tracking */ + v_PVOID_t wdaWdiApiMsgParam; /* WDI API paramter tracking */ +} tWDA_ReqParams; + +typedef struct +{ + v_PVOID_t pWdaContext; /* pointer to WDA context*/ + v_PVOID_t wdaMsgParam; /* PE parameter tracking */ + v_PVOID_t wdaWdiApiMsgParam; /* WDI API paramter tracking */ + v_BOOL_t wdaHALDumpAsync; /* Async Request */ + +} tWDA_HalDumpReqParams; + +/* + * FUNCTION: WDA_open + * open WDA context + */ + +VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t devHandle, + tMacOpenParameters *pMacParams ) ; + +/* + * FUNCTION: WDA_preStart + * Trigger DAL-AL to start CFG download + */ +VOS_STATUS WDA_start(v_PVOID_t pVosContext) ; + +VOS_STATUS WDA_NVDownload_Start(v_PVOID_t pVosContext); + +/* + * FUNCTION: WDA_preStart + * Trigger WDA to start CFG download + */ +VOS_STATUS WDA_preStart(v_PVOID_t pVosContext) ; +/* + * FUNCTION: WDA_stop + * stop WDA + */ +VOS_STATUS WDA_stop(v_PVOID_t pVosContext,tANI_U8 reason); + +/* + * FUNCTION: WDA_close + * close WDA context + */ +VOS_STATUS WDA_close(v_PVOID_t pVosContext); +/* + * FUNCTION: WDA_shutdown + * Shutdown will not close the control transport, added by SSR + */ +VOS_STATUS WDA_shutdown(v_PVOID_t pVosContext, wpt_boolean closeTransport); + +/* + * FUNCTION: WDA_setNeedShutdown + * WDA stop failed or WDA NV Download failed + */ +void WDA_setNeedShutdown(v_PVOID_t pVosContext); +/* + * FUNCTION: WDA_needShutdown + * WDA requires a shutdown rather than a close + */ +v_BOOL_t WDA_needShutdown(v_PVOID_t pVosContext); + +/* + * FUNCTION: WDA_McProcessMsg + * DAL-AL message processing entry function + */ + +VOS_STATUS WDA_McProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) ; + +/* ----------------------------------------------------------------- + * WDA data path API's + * ----------------------------------------------------------------*/ +/* + * FUNCTION: WDA_MgmtDSRegister + * Send Message back to PE + */ + +VOS_STATUS WDA_MgmtDSRegister(tWDA_CbContext *pWDA, + WDA_DS_TxCompleteCb WDA_TxCompleteCallback, + WDA_DS_RxCompleteCb WDA_RxCompleteCallback, + WDA_DS_TxFlowControlCb WDA_TxFlowCtrlCallback + ) ; +/* + * FUNCTION: WDA_MgmtDSTxPacket + * Forward TX management frame to WDI + */ + +VOS_STATUS WDA_TxPacket(tWDA_CbContext *pWDA, + void *pFrmBuf, + tANI_U16 frmLen, + eFrameType frmType, + eFrameTxDir txDir, + tANI_U8 tid, + pWDATxRxCompFunc pCompFunc, + void *pData, + pWDAAckFnTxComp pAckTxComp, + tANI_U32 txFlag, + tANI_U32 txBdToken + ); + +/* + * FUNCTION: WDA_PostMsgApi + * API fpr PE to post Message to WDA + */ +VOS_STATUS WDA_PostMsgApi(tpAniSirGlobal pMac, tSirMsgQ *pMsg) ; + +/* --------------------------------------------------------- + * FUNCTION: wdaGetGlobalSystemRole() + * + * Get the global HAL system role. + * --------------------------------------------------------- + */ +tBssSystemRole wdaGetGlobalSystemRole(tpAniSirGlobal pMac); + +/* maximum wait time for WDA complete event (correct value has to be derived) + * for now giving the value 1000 ms */ +#define WDA_WDI_COMPLETION_TIME_OUT 30000 /* in ms */ + +#define WDA_TL_TX_FRAME_TIMEOUT 10000 /* in msec a very high upper limit of 5,000 msec */ +#define WDA_TL_SUSPEND_TIMEOUT 2000 /* in ms unit */ + +/*Tag used by WDA to mark a timed out frame*/ +#define WDA_TL_TX_MGMT_TIMED_OUT 0xDEAD + +#define WDA_TL_TX_SUSPEND_SUCCESS 0 +#define WDA_TL_TX_SUSPEND_FAILURE 1 + +#define DPU_FEEDBACK_UNPROTECTED_ERROR 0x0F + + +/* --------------------------------------------------------------------------- + + RX Meta info access for Integrated SOC + RX BD header access for NON Integrated SOC + + These MACRO are for RX frames that are on flat buffers + + ---------------------------------------------------------------------------*/ + +/* WDA_GET_RX_MAC_HEADER *****************************************************/ +# define WDA_GET_RX_MAC_HEADER(pRxMeta) \ + (tpSirMacMgmtHdr)( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->mpduHeaderPtr ) + +/* WDA_GET_RX_MPDUHEADER3A ****************************************************/ +# define WDA_GET_RX_MPDUHEADER3A(pRxMeta) \ + (tpSirMacDataHdr3a)( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->mpduHeaderPtr ) + +/* WDA_GET_RX_MPDU_HEADER_LEN *************************************************/ +# define WDA_GET_RX_MPDU_HEADER_LEN(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->mpduHeaderLength ) + +/* WDA_GET_RX_MPDU_LEN ********************************************************/ +# define WDA_GET_RX_MPDU_LEN(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->mpduLength ) + +/* WDA_GET_RX_PAYLOAD_LEN ****************************************************/ +# define WDA_GET_RX_PAYLOAD_LEN(pRxMeta) \ + ( WDA_GET_RX_MPDU_LEN(pRxMeta) - WDA_GET_RX_MPDU_HEADER_LEN(pRxMeta) ) + +/* WDA_GET_RX_MAC_RATE_IDX ***************************************************/ +# define WDA_GET_RX_MAC_RATE_IDX(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->rateIndex ) + +/* WDA_GET_RX_MPDU_DATA ******************************************************/ +# define WDA_GET_RX_MPDU_DATA(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->mpduDataPtr ) + +/* WDA_GET_RX_MPDU_DATA_OFFSET ***********************************************/ +// For Integrated SOC: When UMAC receive the packet. BD is already stripped off. +// Data offset is the MPDU header length +# define WDA_GET_RX_MPDU_DATA_OFFSET(pRxMeta) WDA_GET_RX_MPDU_HEADER_LEN(pRxMeta) + +/* WDA_GET_RX_MPDU_HEADER_OFFSET *********************************************/ +// For Integrated SOC: We UMAC receive the frame, +// BD is gone and MAC header at offset 0 +# define WDA_GET_RX_MPDU_HEADER_OFFSET(pRxMeta) 0 + +/* WDA_GET_RX_UNKNOWN_UCAST **************************************************/ +# define WDA_GET_RX_UNKNOWN_UCAST(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->unknownUcastPkt ) + +/* WDA_GET_RX_TID ************************************************************/ +# define WDA_GET_RX_TID(pRxMeta) ( ((WDI_DS_RxMetaInfoType *)(pRxMeta))->tid ) + +/* WDA_GET_RX_STAID **********************************************************/ +# define WDA_GET_RX_STAID(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->staId) + +/* WDA_GET_RX_ADDR3_IDX ******************************************************/ +# define WDA_GET_RX_ADDR3_IDX(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->addr3Idx) + +/* WDA_GET_RX_CH *************************************************************/ +# define WDA_GET_RX_CH(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->rxChannel) + +/* WDA_GET_RX_RFBAND *********************************************************/ +# define WDA_GET_RX_RFBAND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->rfBand) + +/* WDA_GET_RX_DPUSIG *********************************************************/ +# define WDA_GET_RX_DPUSIG(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->dpuSig) + +/* WDA_IS_RX_BCAST ***********************************************************/ +# define WDA_IS_RX_BCAST(pRxMeta) \ + ( (1 == ((WDI_DS_RxMetaInfoType*)(pRxMeta))->bcast) ? VOS_TRUE : VOS_FALSE ) + +/* WDA_GET_RX_FT_DONE ********************************************************/ +# define WDA_GET_RX_FT_DONE(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->ft) + +/* WDA_GET_RX_DPU_FEEDBACK **************************************************/ +# define WDA_GET_RX_DPU_FEEDBACK(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->dpuFeedback) + +/* WDA_GET_RX_ASF ************************************************************/ +# define WDA_GET_RX_ASF(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->amsdu_asf) + +/* WDA_GET_RX_AEF ************************************************************/ +# define WDA_GET_RX_AEF(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->amsdu_aef) + +/* WDA_GET_RX_ESF ************************************************************/ +# define WDA_GET_RX_ESF(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->amsdu_esf) + +/* WDA_GET_RX_BEACON_SENT ****************************************************/ +# define WDA_GET_RX_BEACON_SENT(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->bsf) + +/* WDA_GET_RX_TSF_LATER *****************************************************/ +# define WDA_GET_RX_TSF_LATER(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->rtsf) + +/* WDA_GET_RX_TYPE ***********************************************************/ +# define WDA_GET_RX_TYPE(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->type) + +/* WDA_GET_RX_SUBTYPE ********************************************************/ +# define WDA_GET_RX_SUBTYPE(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->subtype) + +/* WDA_GET_RX_TYPE_SUBTYPE ****************************************************/ +# define WDA_GET_RX_TYPE_SUBTYPE(pRxMeta) \ + ((WDA_GET_RX_TYPE(pRxMeta)<<4)|WDA_GET_RX_SUBTYPE(pRxMeta)) + +/* WDA_GET_RX_REORDER_OPCODE : For MSDU reorder *******************************/ +# define WDA_GET_RX_REORDER_OPCODE(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->ampdu_reorderOpcode) + +/* WDA_GET_RX_REORDER_SLOT_IDX : For MSDU reorder ****************************/ +# define WDA_GET_RX_REORDER_SLOT_IDX(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->ampdu_reorderSlotIdx) + +/* WDA_GET_RX_REORDER_FWD_IDX : For MSDU reorder *****************************/ +# define WDA_GET_RX_REORDER_FWD_IDX(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->ampdu_reorderFwdIdx) + +/* WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO : Fro MSDU reorder **********************/ +# define WDA_GET_RX_REORDER_CUR_PKT_SEQ_NO(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->currentPktSeqNo) + +/* WDA_IS_RX_LLC_PRESENT *****************************************************/ +# define WDA_IS_RX_LLC_PRESENT(pRxMeta) \ + ( (0 == ((WDI_DS_RxMetaInfoType*)(pRxMeta))->llcr) ? VOS_TRUE : VOS_FALSE ) + +# define WDA_IS_LOGGING_DATA(pRxMeta) \ + ((0 == ((WDI_DS_RxMetaInfoType*)(pRxMeta))->loggingData) ? VOS_FALSE \ + : VOS_TRUE) + +#define WLANWDA_HO_IS_AN_AMPDU 0x4000 +#define WLANWDA_HO_LAST_MPDU_OF_AMPDU 0x400 + +/* WDA_IS_RX_AN_AMPDU ********************************************************/ +# define WDA_IS_RX_AN_AMPDU(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType*)(pRxMeta))->rxpFlags & WLANWDA_HO_IS_AN_AMPDU ) + +/* WDA_IS_RX_LAST_MPDU *******************************************************/ +# define WDA_IS_RX_LAST_MPDU(pRxMeta) \ + ( ((WDI_DS_RxMetaInfoType*)(pRxMeta))->rxpFlags & WLANWDA_HO_LAST_MPDU_OF_AMPDU ) + +/* WDA_GET_RX_TIMESTAMP *****************************************************/ +# define WDA_GET_RX_TIMESTAMP(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->mclkRxTimestamp) + +/* WDA_IS_RX_IN_SCAN *********************************************************/ +# define WDA_IS_RX_IN_SCAN(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->scan) +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* WDA_GET_OFFLOADSCANLEARN **************************************************/ +# define WDA_GET_OFFLOADSCANLEARN(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->offloadScanLearn) +/* WDA_GET_ROAMCANDIDATEIND **************************************************/ +# define WDA_GET_ROAMCANDIDATEIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->roamCandidateInd) +# define WDA_IF_PER_ROAMCANDIDATEIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->perRoamCndInd) +#endif +#ifdef WLAN_FEATURE_EXTSCAN +#define WDA_GET_EXTSCANFULLSCANRESIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->extscanBuffer) +#endif + +#ifdef SAP_AUTH_OFFLOAD +#define WDA_GET_SAP_AUTHOFFLOADIND(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->indType) +#endif + +/* WDA_GET_RX_RSSI_DB ********************************************************/ +// Volans RF +# define WDA_RSSI_OFFSET 100 +# define WDA_GET_RSSI_DB(rssi0) ((int)rssi0 - WDA_RSSI_OFFSET) +# define WDA_GET_RX_RSSI_DB(pRxMeta) \ + WDA_GET_RSSI_DB((((WDI_DS_RxMetaInfoType*)(pRxMeta))->rssi0)) + +/* WDA_GET_RX_SNR ************************************************************/ +# define WDA_GET_RX_SNR(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->snr) + +/* WDA_IS_RX_FC **************************************************************/ +// Flow control frames +/* FIXME WDA should provide the meta info which indicates FC frame + In the meantime, use hardcoded FALSE, since we don't support FC yet */ +# define WDA_IS_RX_FC(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fc) + +/* WDA_GET_RX_FC_VALID_STA_MASK **********************************************/ +# define WDA_GET_RX_FC_VALID_STA_MASK(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fcSTAValidMask) + +/* WDA_GET_RX_FC_PWRSAVE_STA_MASK ********************************************/ +# define WDA_GET_RX_FC_PWRSAVE_STA_MASK(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fcSTAPwrSaveStateMask) + +/* WDA_GET_RX_FC_STA_THRD_IND_MASK ********************************************/ +# define WDA_GET_RX_FC_STA_THRD_IND_MASK(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fcSTAThreshIndMask) + +/* WDA_GET_RX_FC_FORCED_STA_TX_DISABLED_BITMAP ********************************************/ +# define WDA_GET_RX_FC_STA_TX_DISABLED_BITMAP(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fcStaTxDisabledBitmap) + +/* WDA_GET_RX_FC_STA_TXQ_LEN *************************************************/ +# define WDA_GET_RX_FC_STA_TXQ_LEN(pRxMeta, staId) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fcSTATxQLen[(staId)]) + +/* WDA_GET_RX_FC_STA_CUR_TXRATE **********************************************/ +# define WDA_GET_RX_FC_STA_CUR_TXRATE(pRxMeta, staId) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->fcSTACurTxRate[(staId)]) + +/* WDA_GET_RX_REPLAY_COUNT ***************************************************/ +# define WDA_GET_RX_REPLAY_COUNT(pRxMeta) \ + (((WDI_DS_RxMetaInfoType*)(pRxMeta))->replayCount) + +/* WDA_GETRSSI0 ***************************************************************/ +# define WDA_GETRSSI0(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->rssi0) + +/* WDA_GETRSSI1 ***************************************************************/ +# define WDA_GETRSSI1(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->rssi1) + +/* WDA_GET_RX_RMF *****************************************************/ +#ifdef WLAN_FEATURE_11W +# define WDA_GET_RX_RMF(pRxMeta) (((WDI_DS_RxMetaInfoType*)(pRxMeta))->rmf) +#endif + +/* --------------------------------------------------------------------*/ + +uint8 WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision); +uint8 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision); + + +VOS_STATUS WDA_GetWcnssWlanCompiledVersion(v_PVOID_t pvosGCtx, + tSirVersionType *pVersion); +VOS_STATUS WDA_GetWcnssWlanReportedVersion(v_PVOID_t pvosGCtx, + tSirVersionType *pVersion); +VOS_STATUS WDA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize); +VOS_STATUS WDA_GetWcnssHardwareVersion(v_PVOID_t pvosGCtx, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize); + +VOS_STATUS WDA_SetUapsdAcParamsReq(v_PVOID_t , v_U8_t , tUapsdInfo *); +VOS_STATUS WDA_ClearUapsdAcParamsReq(v_PVOID_t , v_U8_t , wpt_uint8 ); +VOS_STATUS WDA_SetRSSIThresholdsReq(tpAniSirGlobal , tSirRSSIThresholds *); +// Just declare the function extern here and save some time. +extern tSirRetStatus halMmhForwardMBmsg(void*, tSirMbMsg*); +tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); + + +#define WDA_MAX_TXPOWER_INVALID HAL_MAX_TXPOWER_INVALID + +//WDA Messages to HAL messages Mapping +#if 0 +//Required by SME +//#define WDA_SIGNAL_BT_EVENT SIR_HAL_SIGNAL_BT_EVENT - this is defined in sirParams.h +//#define WDA_BTC_SET_CFG SIR_HAL_BTC_SET_CFG + +//Required by PE +#define WDA_HOST_MSG_START SIR_HAL_HOST_MSG_START +#define WDA_INITIAL_CAL_FAILED_NTF SIR_HAL_INITIAL_CAL_FAILED_NTF +#define WDA_SHUTDOWN_REQ SIR_HAL_SHUTDOWN_REQ +#define WDA_SHUTDOWN_CNF SIR_HAL_SHUTDOWN_CNF +#define WDA_RADIO_ON_OFF_IND SIR_HAL_RADIO_ON_OFF_IND +#define WDA_RESET_CNF SIR_HAL_RESET_CNF +#define WDA_SetRegDomain \ + (eHalStatus halPhySetRegDomain(tHalHandle hHal, eRegDomainId regDomain)) +#endif + +#define WDA_APP_SETUP_NTF SIR_HAL_APP_SETUP_NTF +#define WDA_NIC_OPER_NTF SIR_HAL_NIC_OPER_NTF +#define WDA_INIT_START_REQ SIR_HAL_INIT_START_REQ +#define WDA_RESET_REQ SIR_HAL_RESET_REQ +#define WDA_HDD_ADDBA_REQ SIR_HAL_HDD_ADDBA_REQ +#define WDA_HDD_ADDBA_RSP SIR_HAL_HDD_ADDBA_RSP +#define WDA_DELETEBA_IND SIR_HAL_DELETEBA_IND +#define WDA_BA_FAIL_IND SIR_HAL_BA_FAIL_IND +#define WDA_TL_FLUSH_AC_REQ SIR_TL_HAL_FLUSH_AC_REQ +#define WDA_TL_FLUSH_AC_RSP SIR_HAL_TL_FLUSH_AC_RSP + +#define WDA_MSG_TYPES_BEGIN SIR_HAL_MSG_TYPES_BEGIN +#define WDA_EXT_MSG_TYPES_BEGIN SIR_HAL_EXT_MSG_TYPES_BEGIN +#define WDA_ITC_MSG_TYPES_BEGIN SIR_HAL_ITC_MSG_TYPES_BEGIN +#define WDA_RADAR_DETECTED_IND SIR_HAL_RADAR_DETECTED_IND +#define WDA_WDT_KAM_RSP SIR_HAL_WDT_KAM_RSP +#define WDA_TIMER_TEMP_MEAS_REQ SIR_HAL_TIMER_TEMP_MEAS_REQ +#define WDA_TIMER_PERIODIC_STATS_COLLECT_REQ SIR_HAL_TIMER_PERIODIC_STATS_COLLECT_REQ +#define WDA_CAL_REQ_NTF SIR_HAL_CAL_REQ_NTF +#define WDA_MNT_OPEN_TPC_TEMP_MEAS_REQ SIR_HAL_MNT_OPEN_TPC_TEMP_MEAS_REQ +#define WDA_CCA_MONITOR_INTERVAL_TO SIR_HAL_CCA_MONITOR_INTERVAL_TO +#define WDA_CCA_MONITOR_DURATION_TO SIR_HAL_CCA_MONITOR_DURATION_TO +#define WDA_CCA_MONITOR_START SIR_HAL_CCA_MONITOR_START +#define WDA_CCA_MONITOR_STOP SIR_HAL_CCA_MONITOR_STOP +#define WDA_CCA_CHANGE_MODE SIR_HAL_CCA_CHANGE_MODE +#define WDA_TIMER_WRAP_AROUND_STATS_COLLECT_REQ SIR_HAL_TIMER_WRAP_AROUND_STATS_COLLECT_REQ + +/* + * New Taurus related messages + */ +#define WDA_ADD_STA_REQ SIR_HAL_ADD_STA_REQ +#define WDA_ADD_STA_RSP SIR_HAL_ADD_STA_RSP +#define WDA_ADD_STA_SELF_RSP SIR_HAL_ADD_STA_SELF_RSP +#define WDA_DEL_STA_SELF_RSP SIR_HAL_DEL_STA_SELF_RSP +#define WDA_DELETE_STA_REQ SIR_HAL_DELETE_STA_REQ +#define WDA_DELETE_STA_RSP SIR_HAL_DELETE_STA_RSP +#define WDA_ADD_BSS_REQ SIR_HAL_ADD_BSS_REQ +#define WDA_ADD_BSS_RSP SIR_HAL_ADD_BSS_RSP +#define WDA_DELETE_BSS_REQ SIR_HAL_DELETE_BSS_REQ +#define WDA_DELETE_BSS_RSP SIR_HAL_DELETE_BSS_RSP +#define WDA_INIT_SCAN_REQ SIR_HAL_INIT_SCAN_REQ +#define WDA_INIT_SCAN_RSP SIR_HAL_INIT_SCAN_RSP +#define WDA_START_SCAN_REQ SIR_HAL_START_SCAN_REQ +#define WDA_START_SCAN_RSP SIR_HAL_START_SCAN_RSP +#define WDA_END_SCAN_REQ SIR_HAL_END_SCAN_REQ +#define WDA_END_SCAN_RSP SIR_HAL_END_SCAN_RSP +#define WDA_FINISH_SCAN_REQ SIR_HAL_FINISH_SCAN_REQ +#define WDA_FINISH_SCAN_RSP SIR_HAL_FINISH_SCAN_RSP +#define WDA_SEND_BEACON_REQ SIR_HAL_SEND_BEACON_REQ +#define WDA_SEND_BEACON_RSP SIR_HAL_SEND_BEACON_RSP + +#define WDA_INIT_CFG_REQ SIR_HAL_INIT_CFG_REQ +#define WDA_INIT_CFG_RSP SIR_HAL_INIT_CFG_RSP + +#define WDA_INIT_WM_CFG_REQ SIR_HAL_INIT_WM_CFG_REQ +#define WDA_INIT_WM_CFG_RSP SIR_HAL_INIT_WM_CFG_RSP + +#define WDA_SET_BSSKEY_REQ SIR_HAL_SET_BSSKEY_REQ +#define WDA_SET_BSSKEY_RSP SIR_HAL_SET_BSSKEY_RSP +#define WDA_SET_STAKEY_REQ SIR_HAL_SET_STAKEY_REQ +#define WDA_SET_STAKEY_RSP SIR_HAL_SET_STAKEY_RSP +#define WDA_DPU_STATS_REQ SIR_HAL_DPU_STATS_REQ +#define WDA_DPU_STATS_RSP SIR_HAL_DPU_STATS_RSP +#define WDA_GET_DPUINFO_REQ SIR_HAL_GET_DPUINFO_REQ +#define WDA_GET_DPUINFO_RSP SIR_HAL_GET_DPUINFO_RSP + +#define WDA_UPDATE_EDCA_PROFILE_IND SIR_HAL_UPDATE_EDCA_PROFILE_IND + +#define WDA_UPDATE_STARATEINFO_REQ SIR_HAL_UPDATE_STARATEINFO_REQ +#define WDA_UPDATE_STARATEINFO_RSP SIR_HAL_UPDATE_STARATEINFO_RSP + +#define WDA_UPDATE_BEACON_IND SIR_HAL_UPDATE_BEACON_IND +#define WDA_UPDATE_CF_IND SIR_HAL_UPDATE_CF_IND +#define WDA_CHNL_SWITCH_REQ SIR_HAL_CHNL_SWITCH_REQ +#define WDA_ADD_TS_REQ SIR_HAL_ADD_TS_REQ +#define WDA_DEL_TS_REQ SIR_HAL_DEL_TS_REQ +#define WDA_SOFTMAC_TXSTAT_REPORT SIR_HAL_SOFTMAC_TXSTAT_REPORT + +#define WDA_MBOX_SENDMSG_COMPLETE_IND SIR_HAL_MBOX_SENDMSG_COMPLETE_IND +#define WDA_EXIT_BMPS_REQ SIR_HAL_EXIT_BMPS_REQ +#define WDA_EXIT_BMPS_RSP SIR_HAL_EXIT_BMPS_RSP +#define WDA_EXIT_BMPS_IND SIR_HAL_EXIT_BMPS_IND +#define WDA_ENTER_BMPS_REQ SIR_HAL_ENTER_BMPS_REQ +#define WDA_ENTER_BMPS_RSP SIR_HAL_ENTER_BMPS_RSP +#define WDA_BMPS_STATUS_IND SIR_HAL_BMPS_STATUS_IND +#define WDA_MISSED_BEACON_IND SIR_HAL_MISSED_BEACON_IND + +#define WDA_CFG_RXP_FILTER_REQ SIR_HAL_CFG_RXP_FILTER_REQ +#define WDA_CFG_RXP_FILTER_RSP SIR_HAL_CFG_RXP_FILTER_RSP + +#define WDA_SWITCH_CHANNEL_RSP SIR_HAL_SWITCH_CHANNEL_RSP +#define WDA_P2P_NOA_ATTR_IND SIR_HAL_P2P_NOA_ATTR_IND +#define WDA_P2P_NOA_START_IND SIR_HAL_P2P_NOA_START_IND +#define WDA_PWR_SAVE_CFG SIR_HAL_PWR_SAVE_CFG + +#define WDA_REGISTER_PE_CALLBACK SIR_HAL_REGISTER_PE_CALLBACK +#define WDA_SOFTMAC_MEM_READREQUEST SIR_HAL_SOFTMAC_MEM_READREQUEST +#define WDA_SOFTMAC_MEM_WRITEREQUEST SIR_HAL_SOFTMAC_MEM_WRITEREQUEST + +#define WDA_SOFTMAC_MEM_READRESPONSE SIR_HAL_SOFTMAC_MEM_READRESPONSE +#define WDA_SOFTMAC_BULKREGWRITE_CONFIRM SIR_HAL_SOFTMAC_BULKREGWRITE_CONFIRM +#define WDA_SOFTMAC_BULKREGREAD_RESPONSE SIR_HAL_SOFTMAC_BULKREGREAD_RESPONSE +#define WDA_SOFTMAC_HOSTMESG_MSGPROCESSRESULT SIR_HAL_SOFTMAC_HOSTMESG_MSGPROCESSRESULT + +#define WDA_ADDBA_REQ SIR_HAL_ADDBA_REQ +#define WDA_ADDBA_RSP SIR_HAL_ADDBA_RSP +#define WDA_DELBA_IND SIR_HAL_DELBA_IND +#define WDA_DEL_BA_IND SIR_HAL_DEL_BA_IND +#define WDA_MIC_FAILURE_IND SIR_HAL_MIC_FAILURE_IND +#define WDA_LOST_LINK_PARAMS_IND SIR_HAL_LOST_LINK_PARAMS_IND + +//message from sme to initiate delete block ack session. +#define WDA_DELBA_REQ SIR_HAL_DELBA_REQ +#define WDA_IBSS_STA_ADD SIR_HAL_IBSS_STA_ADD +#define WDA_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND SIR_HAL_TIMER_ADJUST_ADAPTIVE_THRESHOLD_IND +#define WDA_SET_LINK_STATE SIR_HAL_SET_LINK_STATE +#define WDA_SET_LINK_STATE_RSP SIR_HAL_SET_LINK_STATE_RSP +#define WDA_ENTER_IMPS_REQ SIR_HAL_ENTER_IMPS_REQ +#define WDA_ENTER_IMPS_RSP SIR_HAL_ENTER_IMPS_RSP +#define WDA_EXIT_IMPS_RSP SIR_HAL_EXIT_IMPS_RSP +#define WDA_EXIT_IMPS_REQ SIR_HAL_EXIT_IMPS_REQ +#define WDA_SOFTMAC_HOSTMESG_PS_STATUS_IND SIR_HAL_SOFTMAC_HOSTMESG_PS_STATUS_IND +#define WDA_POSTPONE_ENTER_IMPS_RSP SIR_HAL_POSTPONE_ENTER_IMPS_RSP +#define WDA_STA_STAT_REQ SIR_HAL_STA_STAT_REQ +#define WDA_GLOBAL_STAT_REQ SIR_HAL_GLOBAL_STAT_REQ +#define WDA_AGGR_STAT_REQ SIR_HAL_AGGR_STAT_REQ +#define WDA_STA_STAT_RSP SIR_HAL_STA_STAT_RSP +#define WDA_GLOBAL_STAT_RSP SIR_HAL_GLOBAL_STAT_RSP +#define WDA_AGGR_STAT_RSP SIR_HAL_AGGR_STAT_RSP +#define WDA_STAT_SUMM_REQ SIR_HAL_STAT_SUMM_REQ +#define WDA_STAT_SUMM_RSP SIR_HAL_STAT_SUMM_RSP +#define WDA_REMOVE_BSSKEY_REQ SIR_HAL_REMOVE_BSSKEY_REQ +#define WDA_REMOVE_BSSKEY_RSP SIR_HAL_REMOVE_BSSKEY_RSP +#define WDA_REMOVE_STAKEY_REQ SIR_HAL_REMOVE_STAKEY_REQ +#define WDA_REMOVE_STAKEY_RSP SIR_HAL_REMOVE_STAKEY_RSP +#define WDA_SET_STA_BCASTKEY_REQ SIR_HAL_SET_STA_BCASTKEY_REQ +#define WDA_SET_STA_BCASTKEY_RSP SIR_HAL_SET_STA_BCASTKEY_RSP +#define WDA_REMOVE_STA_BCASTKEY_REQ SIR_HAL_REMOVE_STA_BCASTKEY_REQ +#define WDA_REMOVE_STA_BCASTKEY_RSP SIR_HAL_REMOVE_STA_BCASTKEY_RSP +#define WDA_ADD_TS_RSP SIR_HAL_ADD_TS_RSP +#define WDA_DPU_MIC_ERROR SIR_HAL_DPU_MIC_ERROR +#define WDA_TIMER_BA_ACTIVITY_REQ SIR_HAL_TIMER_BA_ACTIVITY_REQ +#define WDA_TIMER_CHIP_MONITOR_TIMEOUT SIR_HAL_TIMER_CHIP_MONITOR_TIMEOUT +#define WDA_TIMER_TRAFFIC_ACTIVITY_REQ SIR_HAL_TIMER_TRAFFIC_ACTIVITY_REQ +#define WDA_TIMER_ADC_RSSI_STATS SIR_HAL_TIMER_ADC_RSSI_STATS +#define WDA_TIMER_TRAFFIC_STATS_IND SIR_HAL_TRAFFIC_STATS_IND + +#ifdef WLAN_FEATURE_11W +#define WDA_EXCLUDE_UNENCRYPTED_IND SIR_HAL_EXCLUDE_UNENCRYPTED_IND +#endif + +#ifdef FEATURE_WLAN_ESE +#define WDA_TSM_STATS_REQ SIR_HAL_TSM_STATS_REQ +#define WDA_TSM_STATS_RSP SIR_HAL_TSM_STATS_RSP +#endif +#define WDA_UPDATE_PROBE_RSP_IE_BITMAP_IND SIR_HAL_UPDATE_PROBE_RSP_IE_BITMAP_IND +#define WDA_UPDATE_UAPSD_IND SIR_HAL_UPDATE_UAPSD_IND + +#define WDA_SET_MIMOPS_REQ SIR_HAL_SET_MIMOPS_REQ +#define WDA_SET_MIMOPS_RSP SIR_HAL_SET_MIMOPS_RSP +#define WDA_SYS_READY_IND SIR_HAL_SYS_READY_IND +#define WDA_SET_TX_POWER_REQ SIR_HAL_SET_TX_POWER_REQ +#define WDA_SET_TX_POWER_RSP SIR_HAL_SET_TX_POWER_RSP +#define WDA_GET_TX_POWER_REQ SIR_HAL_GET_TX_POWER_REQ +#define WDA_GET_TX_POWER_RSP SIR_HAL_GET_TX_POWER_RSP +#define WDA_GET_NOISE_REQ SIR_HAL_GET_NOISE_REQ +#define WDA_GET_NOISE_RSP SIR_HAL_GET_NOISE_RSP +#define WDA_SET_TX_PER_TRACKING_REQ SIR_HAL_SET_TX_PER_TRACKING_REQ + +/* Messages to support transmit_halt and transmit_resume */ +#define WDA_TRANSMISSION_CONTROL_IND SIR_HAL_TRANSMISSION_CONTROL_IND +/* Indication from LIM to HAL to Initialize radar interrupt */ +#define WDA_INIT_RADAR_IND SIR_HAL_INIT_RADAR_IND +/* Messages to support transmit_halt and transmit_resume */ + + +#define WDA_BEACON_PRE_IND SIR_HAL_BEACON_PRE_IND +#define WDA_ENTER_UAPSD_REQ SIR_HAL_ENTER_UAPSD_REQ +#define WDA_ENTER_UAPSD_RSP SIR_HAL_ENTER_UAPSD_RSP +#define WDA_EXIT_UAPSD_REQ SIR_HAL_EXIT_UAPSD_REQ +#define WDA_EXIT_UAPSD_RSP SIR_HAL_EXIT_UAPSD_RSP +#define WDA_LOW_RSSI_IND SIR_HAL_LOW_RSSI_IND +#define WDA_BEACON_FILTER_IND SIR_HAL_BEACON_FILTER_IND +/// PE <-> HAL WOWL messages +#define WDA_WOWL_ADD_BCAST_PTRN SIR_HAL_WOWL_ADD_BCAST_PTRN +#define WDA_WOWL_DEL_BCAST_PTRN SIR_HAL_WOWL_DEL_BCAST_PTRN +#define WDA_WOWL_ENTER_REQ SIR_HAL_WOWL_ENTER_REQ +#define WDA_WOWL_ENTER_RSP SIR_HAL_WOWL_ENTER_RSP +#define WDA_WOWL_EXIT_REQ SIR_HAL_WOWL_EXIT_REQ +#define WDA_WOWL_EXIT_RSP SIR_HAL_WOWL_EXIT_RSP +#define WDA_TX_COMPLETE_IND SIR_HAL_TX_COMPLETE_IND +#define WDA_TIMER_RA_COLLECT_AND_ADAPT SIR_HAL_TIMER_RA_COLLECT_AND_ADAPT +/// PE <-> HAL statistics messages +#define WDA_GET_STATISTICS_REQ SIR_HAL_GET_STATISTICS_REQ +#define WDA_GET_STATISTICS_RSP SIR_HAL_GET_STATISTICS_RSP +#define WDA_SET_KEY_DONE SIR_HAL_SET_KEY_DONE + +/// PE <-> HAL BTC messages +#define WDA_BTC_SET_CFG SIR_HAL_BTC_SET_CFG +#define WDA_SIGNAL_BT_EVENT SIR_HAL_SIGNAL_BT_EVENT +#define WDA_HANDLE_FW_MBOX_RSP SIR_HAL_HANDLE_FW_MBOX_RSP +#define WDA_UPDATE_PROBE_RSP_TEMPLATE_IND SIR_HAL_UPDATE_PROBE_RSP_TEMPLATE_IND +#define WDA_SIGNAL_BTAMP_EVENT SIR_HAL_SIGNAL_BTAMP_EVENT + +#ifdef FEATURE_OEM_DATA_SUPPORT +/* PE <-> HAL OEM_DATA RELATED MESSAGES */ +#define WDA_START_OEM_DATA_REQ SIR_HAL_START_OEM_DATA_REQ +#define WDA_START_OEM_DATA_RSP SIR_HAL_START_OEM_DATA_RSP +#define WDA_FINISH_OEM_DATA_REQ SIR_HAL_FINISH_OEM_DATA_REQ +#endif + +#define WDA_SET_MAX_TX_POWER_REQ SIR_HAL_SET_MAX_TX_POWER_REQ +#define WDA_SET_MAX_TX_POWER_RSP SIR_HAL_SET_MAX_TX_POWER_RSP + +#define WDA_SET_MAX_TX_POWER_PER_BAND_REQ \ + SIR_HAL_SET_MAX_TX_POWER_PER_BAND_REQ +#define WDA_SET_MAX_TX_POWER_PER_BAND_RSP \ + SIR_HAL_SET_MAX_TX_POWER_PER_BAND_RSP + +#define WDA_SEND_MSG_COMPLETE SIR_HAL_SEND_MSG_COMPLETE + +/// PE <-> HAL Host Offload message +#define WDA_SET_HOST_OFFLOAD SIR_HAL_SET_HOST_OFFLOAD + +/// PE <-> HAL Keep Alive message +#define WDA_SET_KEEP_ALIVE SIR_HAL_SET_KEEP_ALIVE + +#ifdef WLAN_NS_OFFLOAD +#define WDA_SET_NS_OFFLOAD SIR_HAL_SET_NS_OFFLOAD +#endif //WLAN_NS_OFFLOAD +#define WDA_ADD_STA_SELF_REQ SIR_HAL_ADD_STA_SELF_REQ +#define WDA_DEL_STA_SELF_REQ SIR_HAL_DEL_STA_SELF_REQ + +#define WDA_SET_P2P_GO_NOA_REQ SIR_HAL_SET_P2P_GO_NOA_REQ +#define WDA_SET_TDLS_LINK_ESTABLISH_REQ SIR_HAL_TDLS_LINK_ESTABLISH_REQ +#define WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP SIR_HAL_TDLS_LINK_ESTABLISH_REQ_RSP + +#define WDA_TX_COMPLETE_TIMEOUT_IND (WDA_MSG_TYPES_END - 1) +#define WDA_WLAN_SUSPEND_IND SIR_HAL_WLAN_SUSPEND_IND +#define WDA_WLAN_RESUME_REQ SIR_HAL_WLAN_RESUME_REQ +#define WDA_MSG_TYPES_END SIR_HAL_MSG_TYPES_END + +#define WDA_MMH_TXMB_READY_EVT SIR_HAL_MMH_TXMB_READY_EVT +#define WDA_MMH_RXMB_DONE_EVT SIR_HAL_MMH_RXMB_DONE_EVT +#define WDA_MMH_MSGQ_NE_EVT SIR_HAL_MMH_MSGQ_NE_EVT + +#ifdef WLAN_FEATURE_VOWIFI_11R +#define WDA_AGGR_QOS_REQ SIR_HAL_AGGR_QOS_REQ +#define WDA_AGGR_QOS_RSP SIR_HAL_AGGR_QOS_RSP +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/* FTM CMD MSG */ +#define WDA_FTM_CMD_REQ SIR_PTT_MSG_TYPES_BEGIN +#define WDA_FTM_CMD_RSP SIR_PTT_MSG_TYPES_END + +#ifdef FEATURE_WLAN_SCAN_PNO +/*Requests sent to lower driver*/ +#define WDA_SET_PNO_REQ SIR_HAL_SET_PNO_REQ +#define WDA_SET_RSSI_FILTER_REQ SIR_HAL_SET_RSSI_FILTER_REQ +#define WDA_UPDATE_SCAN_PARAMS_REQ SIR_HAL_UPDATE_SCAN_PARAMS + +/*Indication comming from lower driver*/ +#define WDA_SET_PNO_CHANGED_IND SIR_HAL_SET_PNO_CHANGED_IND +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +#define WDA_ROAM_SCAN_OFFLOAD_REQ SIR_HAL_ROAM_SCAN_OFFLOAD_REQ +#define WDA_ROAM_SCAN_OFFLOAD_RSP SIR_HAL_ROAM_SCAN_OFFLOAD_RSP +#define WDA_PER_ROAM_SCAN_OFFLOAD_REQ SIR_HAL_PER_ROAM_SCAN_OFFLOAD_REQ +#define WDA_PER_ROAM_SCAN_OFFLOAD_RSP SIR_HAL_PER_ROAM_SCAN_OFFLOAD_RSP +#define WDA_PER_ROAM_SCAN_TRIGGER_REQ SIR_HAL_PER_ROAM_SCAN_TRIGGER_REQ +#define WDA_PER_ROAM_SCAN_TRIGGER_RSP SIR_HAL_PER_ROAM_SCAN_TRIGGER_RSP +#endif +#define WDA_UPDATE_CFG_INT_PARAM SIR_HAL_UPDATE_CFG_INT_PARAM + +#ifdef WLAN_WAKEUP_EVENTS +#define WDA_WAKE_REASON_IND SIR_HAL_WAKE_REASON_IND +#endif // WLAN_WAKEUP_EVENTS + +#ifdef WLAN_FEATURE_PACKET_FILTERING +#define WDA_8023_MULTICAST_LIST_REQ SIR_HAL_8023_MULTICAST_LIST_REQ +#define WDA_RECEIVE_FILTER_SET_FILTER_REQ SIR_HAL_RECEIVE_FILTER_SET_FILTER_REQ +#define WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ +#define WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP SIR_HAL_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP +#define WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ SIR_HAL_RECEIVE_FILTER_CLEAR_FILTER_REQ +#endif // WLAN_FEATURE_PACKET_FILTERING + +#define WDA_SET_POWER_PARAMS_REQ SIR_HAL_SET_POWER_PARAMS_REQ +#define WDA_DHCP_START_IND SIR_HAL_DHCP_START_IND +#define WDA_DHCP_STOP_IND SIR_HAL_DHCP_STOP_IND + +#ifdef WLAN_FEATURE_RMC +#define WDA_TX_FAIL_MONITOR_IND SIR_HAL_TX_FAIL_MONITOR_IND +#endif /* WLAN_FEATURE_RMC */ + + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +#define WDA_GTK_OFFLOAD_REQ SIR_HAL_GTK_OFFLOAD_REQ +#define WDA_GTK_OFFLOAD_GETINFO_REQ SIR_HAL_GTK_OFFLOAD_GETINFO_REQ +#define WDA_GTK_OFFLOAD_GETINFO_RSP SIR_HAL_GTK_OFFLOAD_GETINFO_RSP +#endif //WLAN_FEATURE_GTK_OFFLOAD + +#define WDA_SET_TM_LEVEL_REQ SIR_HAL_SET_TM_LEVEL_REQ + +#ifdef WLAN_FEATURE_11AC +#define WDA_UPDATE_OP_MODE SIR_HAL_UPDATE_OP_MODE +#endif + +#define WDA_GET_ROAM_RSSI_REQ SIR_HAL_GET_ROAM_RSSI_REQ +#define WDA_GET_ROAM_RSSI_RSP SIR_HAL_GET_ROAM_RSSI_RSP + +#define WDA_NAN_REQUEST SIR_HAL_NAN_REQUEST + +#define WDA_START_SCAN_OFFLOAD_REQ SIR_HAL_START_SCAN_OFFLOAD_REQ +#define WDA_START_SCAN_OFFLOAD_RSP SIR_HAL_START_SCAN_OFFLOAD_RSP +#define WDA_STOP_SCAN_OFFLOAD_REQ SIR_HAL_STOP_SCAN_OFFLOAD_REQ +#define WDA_STOP_SCAN_OFFLOAD_RSP SIR_HAL_STOP_SCAN_OFFLOAD_RSP +#define WDA_UPDATE_CHAN_LIST_REQ SIR_HAL_UPDATE_CHAN_LIST_REQ +#define WDA_UPDATE_CHAN_LIST_RSP SIR_HAL_UPDATE_CHAN_LIST_RSP +#define WDA_RX_SCAN_EVENT SIR_HAL_RX_SCAN_EVENT +#define WDA_IBSS_PEER_INACTIVITY_IND SIR_HAL_IBSS_PEER_INACTIVITY_IND + +#ifdef FEATURE_WLAN_LPHB +#define WDA_LPHB_CONF_REQ SIR_HAL_LPHB_CONF_IND +#define WDA_LPHB_WAIT_EXPIRE_IND SIR_HAL_LPHB_WAIT_EXPIRE_IND +#endif /* FEATURE_WLAN_LPHB */ + +#define WDA_ADD_PERIODIC_TX_PTRN_IND SIR_HAL_ADD_PERIODIC_TX_PTRN_IND +#define WDA_DEL_PERIODIC_TX_PTRN_IND SIR_HAL_DEL_PERIODIC_TX_PTRN_IND + +#define WDA_RATE_UPDATE_IND SIR_HAL_RATE_UPDATE_IND + +#ifdef WLAN_FEATURE_RMC +#define WDA_RMC_BECOME_RULER SIR_HAL_RMC_BECOME_RULER +#define WDA_RMC_RULER_SELECT_RESP SIR_HAL_RMC_RULER_SELECT_RESP +#define WDA_RMC_RULER_REQ SIR_HAL_RMC_RULER_REQ +#define WDA_RMC_UPDATE_IND SIR_HAL_RMC_UPDATE_IND +/* IBSS peer info related message */ +#define WDA_GET_IBSS_PEER_INFO_REQ SIR_HAL_IBSS_PEER_INFO_REQ +#define WDA_GET_IBSS_PEER_INFO_RSP SIR_HAL_IBSS_PEER_INFO_RSP +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +#define WDA_SET_BATCH_SCAN_REQ SIR_HAL_SET_BATCH_SCAN_REQ +#define WDA_SET_BATCH_SCAN_RSP SIR_HAL_SET_BATCH_SCAN_RSP +#define WDA_STOP_BATCH_SCAN_IND SIR_HAL_STOP_BATCH_SCAN_IND +#define WDA_TRIGGER_BATCH_SCAN_RESULT_IND SIR_HAL_TRIGGER_BATCH_SCAN_RESULT_IND +#endif + +#define WDA_HT40_OBSS_SCAN_IND SIR_HAL_HT40_OBSS_SCAN_IND +#define WDA_HT40_OBSS_STOP_SCAN_IND SIR_HAL_HT40_OBSS_STOP_SCAN_IND + +#define WDA_GET_BCN_MISS_RATE_REQ SIR_HAL_BCN_MISS_RATE_REQ +#define WDA_ENCRYPT_MSG_REQ SIR_HAL_ENCRYPT_MSG_REQ +#define WDA_ENCRYPT_MSG_RSP SIR_HAL_ENCRYPT_MSG_RSP + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define WDA_LINK_LAYER_STATS_CLEAR_REQ SIR_HAL_LL_STATS_CLEAR_REQ +#define WDA_LINK_LAYER_STATS_SET_REQ SIR_HAL_LL_STATS_SET_REQ +#define WDA_LINK_LAYER_STATS_GET_REQ SIR_HAL_LL_STATS_GET_REQ +#define WDA_LINK_LAYER_STATS_RESULTS_RSP SIR_HAL_LL_STATS_RESULTS_RSP +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef FEATURE_WLAN_TDLS +// tdlsoffchan +#define WDA_SET_TDLS_CHAN_SWITCH_REQ SIR_HAL_TDLS_CHAN_SWITCH_REQ +#define WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP SIR_HAL_TDLS_CHAN_SWITCH_REQ_RSP +#endif + +#define WDA_FW_STATS_GET_REQ SIR_HAL_FW_STATS_GET_REQ +#define WDA_SET_RTS_CTS_HTVHT SIR_HAL_SET_RTS_CTS_HTVHT +#define WDA_MON_START_REQ SIR_HAL_MON_START_REQ +#define WDA_MON_STOP_REQ SIR_HAL_MON_STOP_REQ +#define WDA_START_RSSI_MONITOR_REQ SIR_HAL_RSSI_MON_START_REQ +#define WDA_STOP_RSSI_MONITOR_REQ SIR_HAL_RSSI_MON_STOP_REQ + +#ifdef DHCP_SERVER_OFFLOAD +#define WDA_SET_DHCP_SERVER_OFFLOAD_REQ SIR_HAL_SET_DHCP_SERVER_OFFLOAD_REQ +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD +#define WDA_SET_MDNS_OFFLOAD_CMD SIR_HAL_SET_MDNS_OFFLOAD +#define WDA_SET_MDNS_FQDN_CMD SIR_HAL_SET_MDNS_FQDN +#define WDA_SET_MDNS_RESPONSE_CMD SIR_HAL_SET_MDNS_RESPONSE +#define WDA_GET_MDNS_STATUS_CMD SIR_HAL_GET_MDNS_STATUS +#endif /* MDNS_OFFLOAD */ + +/* ARP Debug */ +#define WDA_SET_ARP_STATS_REQ SIR_HAL_SET_ARP_STATS_REQ +#define WDA_GET_ARP_STATS_REQ SIR_HAL_GET_ARP_STATS_REQ + +tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg); + +eHalStatus WDA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + tAniBool sendRegHint); + +#ifdef WLAN_FEATURE_EXTSCAN +#define WDA_EXTSCAN_GET_CAPABILITIES_REQ SIR_HAL_EXTSCAN_GET_CAPABILITIES_REQ +#define WDA_EXTSCAN_GET_CAPABILITIES_RSP SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP +#define WDA_EXTSCAN_START_REQ SIR_HAL_EXTSCAN_START_REQ +#define WDA_EXTSCAN_START_RSP SIR_HAL_EXTSCAN_START_RSP +#define WDA_EXTSCAN_STOP_REQ SIR_HAL_EXTSCAN_STOP_REQ +#define WDA_EXTSCAN_STOP_RSP SIR_HAL_EXTSCAN_STOP_RSP +#define WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_REQ +#define WDA_EXTSCAN_SET_BSSID_HOTLIST_RSP SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP +#define WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_REQ +#define WDA_EXTSCAN_RESET_BSSID_HOTLIST_RSP SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP +#define WDA_EXTSCAN_SET_SSID_HOTLIST_REQ SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_REQ +#define WDA_EXTSCAN_SET_SSID_HOTLIST_RSP SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP +#define WDA_EXTSCAN_RESET_SSID_HOTLIST_REQ SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_REQ +#define WDA_EXTSCAN_RESET_SSID_HOTLIST_RSP SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP + +#define WDA_EXTSCAN_GET_CACHED_RESULTS_REQ SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_REQ +#define WDA_EXTSCAN_GET_CACHED_RESULTS_RSP SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP + +#define WDA_EXTSCAN_PROGRESS_IND SIR_HAL_EXTSCAN_PROGRESS_IND +#define WDA_EXTSCAN_SCAN_AVAILABLE_IND SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND +#define WDA_EXTSCAN_SCAN_RESULT_IND SIR_HAL_EXTSCAN_SCAN_RESULT_IND +#define WDA_EXTSCAN_BSSID_HOTLIST_RESULT_IND SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND +#define WDA_EXTSCAN_SSID_HOTLIST_RESULT_IND SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND +#endif /* WLAN_FEATURE_EXTSCAN */ + +#define WDA_SPOOF_MAC_ADDR_REQ SIR_HAL_SPOOF_MAC_ADDR_REQ +#define WDA_SPOOF_MAC_ADDR_RSP SIR_HAL_SPOOF_MAC_ADDR_RSP + +#define WDA_MGMT_LOGGING_INIT_REQ SIR_HAL_MGMT_LOGGING_INIT_REQ +#define WDA_GET_FRAME_LOG_REQ SIR_HAL_GET_FRAME_LOG_REQ +#define WDA_SEND_LOG_DONE_IND SIR_HAL_SEND_LOG_DONE_IND + +#define WDA_FATAL_EVENT_LOGS_REQ SIR_HAL_FATAL_EVENT_LOGS_REQ + +#define WDA_SEND_FREQ_RANGE_CONTROL_IND SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND + +#ifdef WLAN_FEATURE_EXTSCAN +#define WDA_HIGH_PRIORITY_DATA_INFO_IND SIR_HAL_HIGH_PRIORITY_DATA_INFO_IND +#endif /* WLAN_FEATURE_EXTSCAN */ + +#define WDA_FW_MEM_DUMP_REQ SIR_HAL_FW_MEM_DUMP_REQ + +#define WDA_WIFI_CONFIG_REQ SIR_HAL_WIFI_CONFIG_PARAMS + +#define WDA_ANTENNA_DIVERSITY_SELECTION_REQ SIR_HAL_ANTENNA_DIVERSITY_SELECTION_REQ +#ifdef FEATURE_OEM_DATA_SUPPORT +#define WDA_START_OEM_DATA_REQ_IND_NEW SIR_HAL_START_OEM_DATA_REQ_IND_NEW +#define WDA_START_OEM_DATA_RSP_IND_NEW SIR_HAL_START_OEM_DATA_RSP_IND_NEW +#endif + +#define WDA_MODIFY_ROAM_PARAMS_IND SIR_HAL_MODIFY_ROAM_PARAMS_IND +#define WDA_SET_ALLOWED_ACTION_FRAMES_IND SIR_HAL_SET_ALLOWED_ACTION_FRAMES + +#define WDA_PAUSE_TL_IND SIR_HAL_PAUSE_TL_IND + +#ifdef SAP_AUTH_OFFLOAD +#define WDA_SAP_OFL_ADD_STA SIR_HAL_SAP_OFL_ADD_STA +#define WDA_SAP_OFL_DEL_STA SIR_HAL_SAP_OFL_DEL_STA +#define WDA_SET_SAP_AUTH_OFL SIR_HAL_SET_SAP_AUTH_OFL +#endif /* SAP_AUTH_OFFLOAD */ + +#ifdef WLAN_FEATURE_APFIND +#define WDA_APFIND_SET_CMD SIR_HAL_APFIND_SET_CMD +#define WDA_AP_FIND_IND SIR_HAL_AP_FIND_IND +#endif /* WLAN_FEATURE_APFIND */ + +#define WDA_CAP_TSF_REQ SIR_HAL_CAP_TSF_REQ +#define WDA_GET_TSF_REQ SIR_HAL_GET_TSF_REQ + + +#define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames + +#define halTxFrame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, pData, txFlag) \ + (eHalStatus)( WDA_TxPacket(\ + vos_get_context(VOS_MODULE_ID_WDA, vos_get_global_context(VOS_MODULE_ID_WDA, (hHal))),\ + (pFrmBuf),\ + (frmLen),\ + (frmType),\ + (txDir),\ + (tid),\ + (pCompFunc),\ + (pData),\ + (NULL), \ + (txFlag), \ + (0)) ) + +#define halTxFrameWithTxComplete(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, pData, pCBackFnTxComp, txFlag, txBdToken) \ + (eHalStatus)( WDA_TxPacket(\ + vos_get_context(VOS_MODULE_ID_WDA, vos_get_global_context(VOS_MODULE_ID_WDA, (hHal))),\ + (pFrmBuf),\ + (frmLen),\ + (frmType),\ + (txDir),\ + (tid),\ + (pCompFunc),\ + (pData),\ + (pCBackFnTxComp), \ + (txFlag), \ + (txBdToken)) ) + +/* ----------------------------------------------------------------- + WDA data path API's for TL + -------------------------------------------------------------------*/ + +v_BOOL_t WDA_IsHwFrameTxTranslationCapable(v_PVOID_t pVosGCtx, + tANI_U8 staIdx); + +v_BOOL_t WDA_IsSelfSTA(v_PVOID_t pVosGCtx,tANI_U8 staIdx); + +# define WDA_EnableUapsdAcParams(vosGCtx, staId, uapsdInfo) \ + WDA_SetUapsdAcParamsReq(vosGCtx, staId, uapsdInfo) + +# define WDA_DisableUapsdAcParams(vosGCtx, staId, ac) \ + WDA_ClearUapsdAcParamsReq(vosGCtx, staId, ac) + +# define WDA_SetRSSIThresholds(pMac, pThresholds) \ + WDA_SetRSSIThresholdsReq(pMac, pThresholds) + +#define WDA_UpdateRssiBmps(pvosGCtx, staId, rssi) \ + WLANTL_UpdateRssiBmps(pvosGCtx, staId, rssi) + +#define WDA_UpdateSnrBmps(pvosGCtx, staId, rssi) \ + WLANTL_UpdateSnrBmps(pvosGCtx, staId, snr) + +#define WDA_GetSnr(staId, snr) \ + WLANTL_GetSnr(staId, snr) + +#define WDA_UpdateLinkCapacity(pvosGCtx, staId, linkCapacity) \ + WLANTL_UpdateLinkCapacity(pvosGCtx, staId, linkCapacity) + +#ifdef WLAN_PERF +/*========================================================================== + FUNCTION WDA_TLI_FastHwFwdDataFrame + + DESCRIPTION + For NON integrated SOC, this function is called by TL. + + Fast path function to quickly forward a data frame if HAL determines BD + signature computed here matches the signature inside current VOSS packet. + If there is a match, HAL and TL fills in the swapped packet length into + BD header and DxE header, respectively. Otherwise, packet goes back to + normal (slow) path and a new BD signature would be tagged into BD in this + VOSS packet later by the WLANHAL_FillTxBd() function. + + TODO For integrated SOC, this function does nothing yet. Pima SLM/HAL + should provide the equivelant functionality. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff Ptr to VOSS packet + pMetaInfo For getting frame's TID + pStaInfo For checking STA type + + OUT + pvosStatus returned status + puFastFwdOK Flag to indicate whether frame could be fast forwarded + + RETURN VALUE + No return. + + SIDE EFFECTS + +============================================================================*/ +void WDA_TLI_FastHwFwdDataFrame +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + v_U32_t* puFastFwdOK, + WLANTL_MetaInfoType* pMetaInfo, + WLAN_STADescType* pStaInfo +); +#endif /* WLAN_PERF */ + +/*========================================================================== + FUNCTION WDA_DS_Register + + DESCRIPTION + Register TL client to WDA. This function registers TL RX/TX functions + to WDI by calling WDI_DS_Register. + + + For NON integrated SOC, this function calls WLANBAL_RegTlCbFunctions + to register TL's RX/TX functions to BAL + + TODO + For Prima, pfnResourceCB gets called in WDTS_OOResourceNotification. + The uCount parameter is AC mask. It should be redefined to use the + same resource callback function. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + pfnTxCompleteCallback TX complete callback upon TX completion + pfnRxPacketCallback RX callback + pfnResourceCB gets called when updating TX PDU number + uResTheshold minimum TX PDU size for a packet + pCallbackContext WDI calls callback function with it + VOS global context pointer + OUT + uAvailableTxBuf available TX PDU numbder. + BAL returns it for NON integrated SOC + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_Register +( + v_PVOID_t pvosGCtx, + WDA_DS_TxCompleteCallback pfnTxCompleteCallback, + WDA_DS_RxPacketCallback pfnRxPacketCallback, + WDA_DS_TxPacketCallback pfnTxPacketCallback, + WDA_DS_ResourceCB pfnResourceCB, + v_U32_t uResTheshold, + v_PVOID_t pCallbackContext, + v_U32_t *uAvailableTxBuf +); + +/*========================================================================== + FUNCTION WDA_DS_StartXmit + + DESCRIPTION + Serialize TX transmit reques to TX thread. + + TODO This sends TX transmit request to TL. It should send to WDI for + abstraction. + + For NON integrated SOC, this function calls WLANBAL_StartXmit + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_StartXmit +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WDA_DS_FinishULA + + DESCRIPTION + Serialize Finish Upper Level Authentication reques to TX thread. + + DEPENDENCIES + + PARAMETERS + + IN + callbackRoutine routine to be called in TX thread + callbackContext user data for the above routine + + RETURN VALUE + please see vos_tx_mq_serialize + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_FinishULA +( + void (*callbackRoutine) (void *callbackContext), + void *callbackContext +); + +/*========================================================================== + FUNCTION WDA_DS_BuildTxPacketInfo + + DESCRIPTION + Build TX meta info for integrated SOC. + + Same function calls HAL for reserve BD header space into VOS packet and + HAL function to fill it. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff vos data buffer + pvDestMacAddr destination MAC address ponter + ucDisableFrmXtl Is frame xtl disabled? + ucQosEnabled Is QoS enabled? + ucWDSEnabled Is WDS enabled? + extraHeadSpace Extra head bytes. If it's not 0 due to 4 bytes align + of BD header. + typeSubtype typeSubtype from MAC header or TX metainfo/BD + pAddr2 address 2 + uTid tid + txFlag + timeStamp + ucIsEapol + ucIsArp + ucUP + + OUT + *pusPktLen Packet length + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_BuildTxPacketInfo +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + v_MACADDR_t* pvDestMacAddr, + v_U8_t ucDisableFrmXtl, + v_U16_t* pusPktLen, + v_U8_t ucQosEnabled, + v_U8_t ucWDSEnabled, + v_U8_t extraHeadSpace, + v_U8_t typeSubtype, + v_PVOID_t pAddr2, + v_U8_t uTid, + v_U32_t txFlag, + v_U32_t timeStamp, + v_U8_t ucIsEapol, + v_U8_t ucIsArp, + v_U8_t ucUP, + v_U32_t ucTxBdToken +); + +/*========================================================================== + FUNCTION WDA_DS_PeekRxPacketInfo + + DESCRIPTION + Return RX metainfo pointer for for integrated SOC. + + Same function will return BD header pointer. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + pvDestMacAddr destination MAC address ponter + bSwap Want to swap BD header? For backward compatability + It does nothing for integrated SOC + OUT + *ppRxHeader RX metainfo pointer + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_PeekRxPacketInfo +( + vos_pkt_t *vosDataBuff, + v_PVOID_t *ppRxHeader, + v_BOOL_t bSwap +); + +/*========================================================================== + FUNCTION WDA_DS_TrimRxPacketInfo + + DESCRIPTION + Trim/Remove RX BD header for NON integrated SOC. + It does nothing for integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_TrimRxPacketInfo +( + vos_pkt_t *vosDataBuff +); + +/*========================================================================== + FUNCTION WDA_DS_GetTxResources + + DESCRIPTION + It does return hardcoded value for Prima. It should bigger number than 0. + Returning 0 will put TL in out-of-resource condition for TX. + + Return current PDU resources from BAL for NON integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + OUT + puResCount available PDU number for TX + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetTxResources +( + v_PVOID_t pvosGCtx, + v_U32_t* puResCount +); + +/*========================================================================== + FUNCTION WDA_DS_GetRssi + + DESCRIPTION + Get RSSI + + TODO It returns hardcoded value in the meantime since WDA/WDI does nothing + support it yet for Prima. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + OUT + puRssi RSSI + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetRssi +( + v_PVOID_t pvosGCtx, + v_S7_t* puRssi +); + +/*========================================================================== + FUNCTION WDA_DS_RxAmsduBdFix + + DESCRIPTION + For backward compatability with Libra/Volans. Need to call HAL function + for HW BD bug fix + + It does nothing for integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + pvBDHeader BD header pointer + + OUT + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_RxAmsduBdFix +( + v_PVOID_t pvosGCtx, + v_PVOID_t pvBDHeader +); + +/*========================================================================== + FUNCTION WDA_DS_GetFrameTypeSubType + + DESCRIPTION + Get typeSubtype from the packet. The BD header should have this. + But some reason, Libra/Volans read it from 802.11 header and save it + back to BD header. So for NON integrated SOC, this function does + the same. + + For integrated SOC, WDI does the same, not TL. + It does return typeSubtype from RX meta info for integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff vos data buffer + pRxHeader RX meta info or BD header pointer + + OUT + ucTypeSubtype typeSubtype + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetFrameTypeSubType +( + v_PVOID_t pvosGCtx, + vos_pkt_t *vosDataBuff, + v_PVOID_t pRxHeader, + v_U8_t *ucTypeSubtype +); + +/*========================================================================== + FUNCTION WDA_DS_GetReplayCounter + + DESCRIPTION + Return replay counter from BD header or RX meta info + + DEPENDENCIES + + PARAMETERS + + IN + pRxHeader RX meta info or BD header pointer + + OUT + + RETURN VALUE + Replay Counter + + SIDE EFFECTS + +============================================================================*/ +v_U64_t +WDA_DS_GetReplayCounter +( + v_PVOID_t pRxHeader +); + +/*========================================================================== + FUNCTION WDA_DS_GetReplayCounter + + DESCRIPTION + HO support. Set RSSI threshold via HAL function for NON integrated SOC + + TODO + Same function should be provided by WDA/WDI for Prima. + + DEPENDENCIES + + PARAMETERS + + IN + pMac MAC global pointer + pThresholds pointer of threshold structure to set. + + OUT + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_SetRSSIThresholds +( + tpAniSirGlobal pMac, + tpSirRSSIThresholds pThresholds +); + +/*========================================================================== + FUNCTION WDA_DS_TxFrames + + DESCRIPTION + Pull packets from TL and push them to WDI. It gets invoked upon + WDA_DS_TX_START_XMIT. + + This function is equivelant of WLANSSC_Transmit in Libra/Volans. + + TODO + This function should be implemented and moved in WDI. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + + OUT + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_TxFrames +( + v_PVOID_t pvosGCtx +); + +/*========================================================================== + FUNCTION WDA_DS_TxFlowControlCallback + + DESCRIPTION + Invoked by WDI to control TX flow. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + uFlowMask TX channel mask for flow control + Defined in WDA_TXFlowEnumType + + OUT + + RETURN VALUE + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WDA_DS_TxFlowControlCallback +( + v_PVOID_t pvosGCtx, + v_U8_t uFlowMask +); + +/*========================================================================== + FUNCTION WDA_DS_GetTxFlowMask + + DESCRIPTION + return TX flow mask control value + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + + OUT + uFlowMask TX channel mask for flow control + Defined in WDA_TXFlowEnumType + + RETURN VALUE + VOS_STATUS_E_INVAL: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetTxFlowMask +( + v_PVOID_t pvosGCtx, + v_U8_t* puFlowMask +); + +/*========================================================================== + FUNCTION WDA_HALDumpCmdReq + + DESCRIPTION + Send Dump commandsto WDI + + DEPENDENCIES + + PARAMETERS + + IN + pMac MAC global pointer + cmd Hal dump command + arg1 Dump command argument 1 + arg2 Dump command argument 2 + arg3 Dump command argument 3 + arg4 Dump command argument 4 + async Asynchronous event. Doesn't wait for rsp. + + OUT + pBuffer Dump command Response buffer + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WDA_HALDumpCmdReq(tpAniSirGlobal pMac,tANI_U32 cmd, + tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, + tANI_U32 arg4, tANI_U8 *pBuffer, wpt_boolean async); + +/*========================================================================== + FUNCTION WDA_featureCapsExchange + + DESCRIPTION + WDA API to invoke capability exchange between host and FW + + DEPENDENCIES + + PARAMETERS + + IN + pVosContext VOS context + + OUT + NONE + + RETURN VALUE + NONE + + SIDE EFFECTS +============================================================================*/ +void WDA_featureCapsExchange(v_PVOID_t pVosContext); + +void WDA_disableCapablityFeature(tANI_U8 feature_index); +/*========================================================================== + FUNCTION WDA_getHostWlanFeatCaps + + DESCRIPTION + Wrapper for WDI API, that will return if the feature (enum value).passed + to this API is supported or not in Host + + DEPENDENCIES + + PARAMETERS + + IN + featEnumValue enum value for the feature as in placeHolderInCapBitmap in wlan_hal_msg.h. + + OUT + NONE + + RETURN VALUE + 0 - implies feature is NOT Supported + any non zero value - implies feature is SUPPORTED + + SIDE EFFECTS +============================================================================*/ +tANI_U8 WDA_getHostWlanFeatCaps(tANI_U8 featEnumValue); + +/*========================================================================== + FUNCTION WDA_getFwWlanFeatCaps + + DESCRIPTION + Wrapper for WDI API, that will return if the feature (enum value).passed + to this API is supported or not in FW + + DEPENDENCIES + + PARAMETERS + + IN + featEnumValue enum value for the feature as in placeHolderInCapBitmap in wlan_hal_msg.h. + + OUT + NONE + + RETURN VALUE + 0 - implies feature is NOT Supported + any non zero value - implies feature is SUPPORTED + + SIDE EFFECTS +============================================================================*/ +tANI_U8 WDA_getFwWlanFeatCaps(tANI_U8 featEnumValue); + +/*========================================================================== + FUNCTION WDA_TransportChannelDebug + + DESCRIPTION + Display Transport Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + PARAMETERS + pMac : upper MAC context pointer + displaySnapshot : Display DXE snapshot option + debugFlags : Enable stall detect features + defined by WPAL_DeviceDebugFlags + These features may effect + data performance. + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_TransportChannelDebug +( + tpAniSirGlobal pMac, + v_BOOL_t displaySnapshot, + v_U8_t debugFlags +); + +/*========================================================================== + FUNCTION WDA_TransportKickDxe + + DESCRIPTION + Request Kick DXE when first hdd TX time out + happens + + PARAMETERS + NONE + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_TransportKickDxe(void); + +/*========================================================================== + FUNCTION WDA_TrafficStatsTimerActivate + + DESCRIPTION + API to activate/deactivate Traffic Stats timer. Traffic stats timer is only needed during MCC + PARAMETERS + activate : Activate or not + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_TrafficStatsTimerActivate(wpt_boolean activate); + +/*========================================================================== + FUNCTION WDA_SetEnableSSR + + DESCRIPTION + API to enable/disable SSR on WDI timeout + + PARAMETERS + enableSSR : enable/disable SSR + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_SetEnableSSR(v_BOOL_t enableSSR); + + +void WDA_FWLoggingDXEdoneInd(v_U32_t logType); + +void WDA_SetMgmtPktViaWQ5(v_BOOL_t sendMgmtPktViaWQ5); + +#define CAP_TSF_REQUEST 0 +#define GET_TSF_REQUEST 1 + +VOS_STATUS WDA_ProcessCapTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params); +VOS_STATUS WDA_ProcessGetTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params); +#endif diff --git a/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda_msg.h b/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda_msg.h new file mode 100644 index 000000000000..67d2666d0b0c --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/inc/wlan_qct_wda_msg.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_MSG_MAP_H +#define WLAN_QCT_MSG_MAP_H + +/*=========================================================================== + + W L A N DEVICE ADAPTATION L A Y E R + MSG MAPPING + + +DESCRIPTION + This file contains the external API exposed by the wlan adaptation layer + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------- +25/08/2010 adwivedi MAP WDA messages on Legacy HAL messages +=========================================================================== */ + +/* Add Include */ +#include "wlan_qct_pack_align.h" + + +#define WDA_CONFIG_PARAM_UPDATE_REQ SIR_CFG_PARAM_UPDATE_IND + +#define ALIGNED_WORD_SIZE 4 + +/* Config format required by HAL for each CFG item*/ +WPT_PACK_START +typedef WPT_PACK_PRE struct +{ + /* Cfg Id. The Id required by HAL is exported by HAL + * in shared header file between UMAC and HAL.*/ + tANI_U16 type; + + /* Length of the Cfg. This parameter is used to go to next cfg + * in the TLV format.*/ + tANI_U16 length; + + /* Padding bytes for unaligned address's */ + tANI_U16 padBytes; + + /* Reserve bytes for making cfgVal to align address */ + tANI_U16 reserved; + + /* Following the uCfgLen field there should be a 'uCfgLen' bytes + * containing the uCfgValue ; tANI_U8 uCfgValue[uCfgLen] */ +}WPT_PACK_POST tHalCfg, *tpHalCfg; +WPT_PACK_END + +/////#define WDA_UT +#ifdef WDA_UT +#define WDA_WDI_EVENT_MSG 0x00FF +void WDI_processEvent(void *wdiEventData, void *pUserData); +#endif + +#endif diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_nv.c b/drivers/staging/prima/CORE/WDA/src/wlan_nv.c new file mode 100644 index 000000000000..18100b1bf996 --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/src/wlan_nv.c @@ -0,0 +1,10481 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file wlan_nv.c + + \brief Contains collection of table default values to use in + case a table is not found in NV + + $Id$ + + ========================================================================== */ + +#ifndef WLAN_NV_C +#define WLAN_NV_C + +#include "wlan_nv2.h" +#include "wlan_hal_msg.h" + +const sHalNv nvDefaults = +{ + { + 0, // tANI_U16 productId; + 1, // tANI_U8 productBands; + 2, // tANI_U8 wlanNvRevId; //0: WCN1312, 1: WCN1314, 2: WCN3660 + 1, // tANI_U8 numOfTxChains; + 1, // tANI_U8 numOfRxChains; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { "\0" }, + 0, // tANI_U8 couplerType; + WLAN_NV_VERSION, // tANI_U8 nvVersion; + }, //fields + + { + // NV_TABLE_RATE_POWER_SETTINGS + { + // typedef tANI_S16 tPowerdBm; + //typedef tPowerdBm tRateGroupPwr[NUM_HAL_PHY_RATES]; + //tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; + //2.4G + { + //802.11b Rates + {1900}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + //11A 20MHz Rates + {1700}, // HAL_PHY_RATE_11A_6_MBPS, + {1700}, // HAL_PHY_RATE_11A_9_MBPS, + {1700}, // HAL_PHY_RATE_11A_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_18_MBPS, + {1600}, // HAL_PHY_RATE_11A_24_MBPS, + {1550}, // HAL_PHY_RATE_11A_36_MBPS, + {1550}, // HAL_PHY_RATE_11A_48_MBPS, + {1550}, // HAL_PHY_RATE_11A_54_MBPS, + + //DUP 11A 40MHz Rates + {1700}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + //MCS Index #0-7(20/40MHz) + {1700}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + //MCS Index #8-15(20/40MHz) + {1700}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATURE_11AC + //11AC rates + //11A duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + //11ac 20MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + + //11ac 40MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + //11ac 80MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_2_4_GHZ + // 5G Low + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DUP 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11AC rates + ///11A duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11ac 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + //11ac 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_5_LOW_GHZ + // 5G Mid + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_111AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // // RF_SUBBAND_5_MID_GHZ + // 5G High + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_5_HIGH_GHZ, + // 4.9G + + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_4_9_GHZ + }, + + // NV_TABLE_REGULATORY_DOMAINS + { + // typedef struct + // { + // tANI_BOOLEAN enabled; + // tPowerdBm pwrLimit; + // }sRegulatoryChannel; + + // typedef struct + // { + // sRegulatoryChannel channels[NUM_RF_CHANNELS]; + // uAbsPwrPrecision antennaGain[NUM_RF_SUBBANDS]; + // uAbsPwrPrecision bRatePowerOffset[NUM_2_4GHZ_CHANNELS]; + // }sRegulatoryDomains; + + //sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; + + + { // REG_DOMAIN_FCC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_11, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_12, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + {0}, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_FCC end + + { // REG_DOMAIN_ETSI start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 19}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 19}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_ETSI end + + { // REG_DOMAIN_JAPAN start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_13, + {NV_CHANNEL_ENABLE, 18}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_120, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_124, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_JAPAN end + + { // REG_DOMAIN_WORLD start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_120, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_124, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + {0}, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_WORLD end + + { // REG_DOMAIN_N_AMER_EXC_FCC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_11, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_12, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_N_AMER_EXC_FCC end + + { // REG_DOMAIN_APAC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + {0}, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_APAC end + + { // REG_DOMAIN_KOREA start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + {0}, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_KOREA end + + { // REG_DOMAIN_HI_5GHZ start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + {0}, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_HI_5GHZ end + + { // REG_DOMAIN_NO_5GHZ start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + }, //sRegulatoryChannel end + + { + {0}, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + } // REG_DOMAIN_NO_5GHZ end + }, + + // NV_TABLE_DEFAULT_COUNTRY + { + // typedef struct + // { + // tANI_U8 regDomain; //from eRegDomainId + // tANI_U8 countryCode[NV_FIELD_COUNTRY_CODE_SIZE]; // string identifier + // }sDefaultCountry; + + 0, // regDomain + { 'U', 'S', 'I' } // countryCode + }, + + //NV_TABLE_TPC_POWER_TABLE + { + //ch 1 + { + { + 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 , 6 , 7 , 8 , 8 , 9 , 10 , 10 , 11 , 13 , 14 , 15 , 17 , + 19 , 20 , 21 , 22 , 23 , 25 , 26 , 27 , 28 , 29 , 30 , 30 , 31 , 32 , 33 , 34 , 35 , 35 , 36 , 37 , 38 , 39 , 40 , + 40 , 41 , 42 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 , 49 , 50 , 50 , 51 , 51 , 52 , 52 , 53 , 53 , + 54 , 54 , 55 , 55 , 56 , 56 , 57 , 57 , 58 , 58 , 58 , 59 , 59 , 59 , 60 , 60 , 60 , 61 , 61 , 61 , 62 , 62 , 62 , + 63 , 63 , 63 , 64 , 64 , 65 , 65 , 65 , 66 , 66 , 66 , 67 , 67 , 67 , 68 , 68 , 68 , 69 , 69 , 69 , 69 , 70 , 70 , + 70 , 70 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 76 , + 76 , 76 , 76 , 76 , 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 81 , + 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 83 , 84 , 84 , 84 , 84 , 84 , 84 , 85 , 85 , 85 , + 85 , 85 , 85 , 86 , 86 , 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 88 , 88 , 89 , + 89 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 90 , 90 , 90 , 91 , 91 , 91 , 91 , 91 , 91 , 92 , 92 , 92 , 92 , 92 , + 92 , 92 , 93 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 95 , 95 , 96 , 96 + } + }, //RF_CHAN_1 + + //ch 2 + { + { + 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 , 6 , 7 , 8 , 8 , 9 , 10 , 10 , 11 , 13 , 14 , 15 , 17 , + 19 , 20 , 21 , 22 , 23 , 25 , 26 , 27 , 28 , 29 , 30 , 30 , 31 , 32 , 33 , 34 , 35 , 35 , 36 , 37 , 38 , 39 , 40 , + 40 , 41 , 42 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 , 49 , 50 , 50 , 51 , 51 , 52 , 52 , 53 , 53 , + 54 , 54 , 55 , 55 , 56 , 56 , 57 , 57 , 58 , 58 , 58 , 59 , 59 , 59 , 60 , 60 , 60 , 61 , 61 , 61 , 62 , 62 , 62 , + 63 , 63 , 63 , 64 , 64 , 65 , 65 , 65 , 66 , 66 , 66 , 67 , 67 , 67 , 68 , 68 , 68 , 69 , 69 , 69 , 69 , 70 , 70 , + 70 , 70 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 76 , + 76 , 76 , 76 , 76 , 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 81 , + 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 83 , 84 , 84 , 84 , 84 , 84 , 84 , 85 , 85 , 85 , + 85 , 85 , 85 , 86 , 86 , 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 88 , 88 , 89 , + 89 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 90 , 90 , 90 , 91 , 91 , 91 , 91 , 91 , 91 , 92 , 92 , 92 , 92 , 92 , + 92 , 92 , 93 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 95 , 95 , 96 , 96 + } + }, //RF_CHAN_2 + + //ch 3 + { + { + 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 , 6 , 7 , 8 , 8 , 9 , 10 , 10 , 11 , 13 , 14 , 15 , 17 , + 19 , 20 , 21 , 22 , 23 , 25 , 26 , 27 , 28 , 29 , 30 , 30 , 31 , 32 , 33 , 34 , 35 , 35 , 36 , 37 , 38 , 39 , 40 , + 40 , 41 , 42 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 , 49 , 50 , 50 , 51 , 51 , 52 , 52 , 53 , 53 , + 54 , 54 , 55 , 55 , 56 , 56 , 57 , 57 , 58 , 58 , 58 , 59 , 59 , 59 , 60 , 60 , 60 , 61 , 61 , 61 , 62 , 62 , 62 , + 63 , 63 , 63 , 64 , 64 , 65 , 65 , 65 , 66 , 66 , 66 , 67 , 67 , 67 , 68 , 68 , 68 , 69 , 69 , 69 , 69 , 70 , 70 , + 70 , 70 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 76 , + 76 , 76 , 76 , 76 , 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 81 , + 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 83 , 84 , 84 , 84 , 84 , 84 , 84 , 85 , 85 , 85 , + 85 , 85 , 85 , 86 , 86 , 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 88 , 88 , 89 , + 89 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 90 , 90 , 90 , 91 , 91 , 91 , 91 , 91 , 91 , 92 , 92 , 92 , 92 , 92 , + 92 , 92 , 93 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 95 , 95 , 96 , 96 + } + }, //RF_CHAN_3 + + //ch 4 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_4 + + //ch 5 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_5 + + //ch 6 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_6 + + //ch 7 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_7 + + //ch 8 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_8 + + //ch 9 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_9 + + //ch 10 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_10 + + //ch 11 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_11 + + //ch 12 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_12 + + //ch 13 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_13 + + //ch 14 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_14 + + //5200 base: ch240 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_240 + + //5200 base: ch244 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_244 + + //5200 base: ch248 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_248 + + //5200 base: ch252 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_252 + + //5200 base: ch208 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_208 + + //5200 base: ch212 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_212 + + //5200 base: ch216 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_216 + + //5200 base: ch36 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_36 + + //5200 base: ch40 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_40 + + //5200 base: ch44 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_44 + + //5200 base: ch48 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_48 + + //5200 base: ch52 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_52 + + //5200 base: ch56 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_56 + + //5500: ch 60 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_60 + + //5500: ch 64 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_64 + + //5500: ch 100 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_100 + + //5500: ch 104 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_104 + + //5500: ch 108 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_108 + + //5500: ch 112 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_112 + + //5500: ch 116 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_116 + + //5500: ch 120 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_120 + + //5500: ch 124 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_124 + + //5500: ch 128 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_128 + + //5500: ch 132 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_132 + + //5500: ch 136 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_136 + + //5500: ch 140 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_140 + +#ifdef FEATURE_WLAN_CH144 + //5500: ch 144 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_144 +#endif /* FEATURE_WLAN_CH144 */ + + //5500: ch 149 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_149 + + //5500: ch 153 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_153 + + //5500: ch 157 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_157 + + //5500: ch 161 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_161 + + //5500: ch 165 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_165 + + // CB starts + //ch 3 + { + { + 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 , 6 , 7 , 8 , 8 , 9 , 10 , 10 , 11 , 13 , 14 , 15 , 17 , + 19 , 20 , 21 , 22 , 23 , 25 , 26 , 27 , 28 , 29 , 30 , 30 , 31 , 32 , 33 , 34 , 35 , 35 , 36 , 37 , 38 , 39 , 40 , + 40 , 41 , 42 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 , 49 , 50 , 50 , 51 , 51 , 52 , 52 , 53 , 53 , + 54 , 54 , 55 , 55 , 56 , 56 , 57 , 57 , 58 , 58 , 58 , 59 , 59 , 59 , 60 , 60 , 60 , 61 , 61 , 61 , 62 , 62 , 62 , + 63 , 63 , 63 , 64 , 64 , 65 , 65 , 65 , 66 , 66 , 66 , 67 , 67 , 67 , 68 , 68 , 68 , 69 , 69 , 69 , 69 , 70 , 70 , + 70 , 70 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 76 , + 76 , 76 , 76 , 76 , 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 81 , + 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 83 , 84 , 84 , 84 , 84 , 84 , 84 , 85 , 85 , 85 , + 85 , 85 , 85 , 86 , 86 , 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 88 , 88 , 89 , + 89 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 90 , 90 , 90 , 91 , 91 , 91 , 91 , 91 , 91 , 92 , 92 , 92 , 92 , 92 , + 92 , 92 , 93 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 95 , 95 , 96 , 96 + } + }, //RF_CHAN_BOND_3 + + //ch 4 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_BOND_4 + + //ch 5 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_BOND_5 + + //ch 6 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_BOND_6 + + //ch 7 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_BOND_7 + + //ch 8 + { + { + 10 , 10 , 11 , 12 , 12 , 13 , 14 , 15 , 15 , 16 , 17 , 17 , 18 , 19 , 20 , 20 , 22 , 23 , 25 , 26 , 28 , 29 , 31 , + 33 , 34 , 36 , 37 , 38 , 40 , 41 , 42 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 52 , 53 , 54 , 55 , 55 , 56 , + 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 64 , 64 , 65 , 66 , 66 , 67 , 67 , 68 , 68 , 69 , 69 , 70 , + 70 , 71 , 71 , 71 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , 74 , 74 , 74 , 75 , 75 , 76 , 76 , 76 , 77 , 77 , 77 , 78 , + 78 , 78 , 79 , 79 , 79 , 80 , 80 , 80 , 81 , 81 , 81 , 82 , 82 , 82 , 83 , 83 , 83 , 84 , 84 , 84 , 85 , 85 , 85 , + 86 , 86 , 86 , 86 , 87 , 87 , 87 , 87 , 88 , 88 , 88 , 88 , 88 , 89 , 89 , 89 , 89 , 90 , 90 , 90 , 90 , 91 , 91 , + 91 , 91 , 91 , 92 , 92 , 92 , 92 , 93 , 93 , 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , 95 , 95 , 96 , 96 , 96 , + 96 , 97 , 97 , 97 , 97 , 97 , 98 , 98 , 98 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 , 99 , 100 , 100 , 100 , + 100 , 101 , 101 , 101 , 101 , 101 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 102 , 103 , 103 , 103 , 103 , + 103 , 103 , 104 , 104 , 104 , 104 , 104 , 105 , 105 , 105 , 105 , 105 , 106 , 106 , 106 , 106 , 106 , 106 , 107 , + 107 , 107 , 107 , 107 , 107 , 107 , 108 , 108 , 108 , 108 , 108 , 108 , 109 , 109 , 109 , 109 , 109 , 109 , 109 , + 110 , 110 , 110 , 110 , 110 , 110 , 110 , 110 , 111 , 111 , 111 , 111 , 111 , 112 , 112 , 112 + } + }, //RF_CHAN_BOND_8 + + //ch 9 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_BOND_9 + + //ch 10 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_BOND_10 + + //ch 11 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 2 , 2 , 3 , 5 , 6 , 7 , 9 , 10 , 11 , 13 , + 14 , 15 , 16 , 17 , 18 , 20 , 21 , 22 , 22 , 23 , 23 , 24 , 24 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 28 , 29 , 29 , + 30 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 34 , 35 , 36 , 36 , 37 , 37 , 38 , 38 , 39 , 39 , 40 , 40 , 41 , 41 , + 42 , 42 , 43 , 43 , 44 , 44 , 45 , 45 , 46 , 46 , 47 , 47 , 47 , 48 , 48 , 49 , 49 , 49 , 50 , 50 , 50 , 51 , 51 , + 51 , 51 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 56 , 56 , 56 , 57 , 57 , 57 , 57 , 58 , + 58 , 58 , 59 , 59 , 59 , 59 , 60 , 60 , 60 , 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , + 64 , 64 , 64 , 64 , 65 , 65 , 65 , 65 , 65 , 66 , 66 , 66 , 66 , 67 , 67 , 67 , 67 , 67 , 68 , 68 , 68 , 68 , 69 , + 69 , 69 , 69 , 70 , 70 , 70 , 70 , 70 , 71 , 71 , 71 , 71 , 71 , 72 , 72 , 72 , 72 , 72 , 72 , 73 , 73 , 73 , 73 , + 73 , 73 , 74 , 74 , 74 , 74 , 74 , 74 , 75 , 75 , 75 , 75 , 75 , 75 , 76 , 76 , 76 , 76 , 76 , 76 , 76 , 77 , 77 , + 77 , 77 , 77 , 77 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 79 , 79 , 79 , 79 , 79 , 79 , 80 , 80 , 80 , 80 , 80 , 80 , + 81 , 81 , 81 , 81 , 81 , 81 , 81 , 82 , 82 , 82 , 82 , 82 , 82 , 83 , 83 , 83 , 83 , 84 , 84 , 85 , 85 + } + }, //RF_CHAN_BOND_11 + + //5200 base: ch242 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_242 + + //5200 base: ch246 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_246 + + //5200 base: ch250 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_250 + + //5200 base: ch210 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_210 + + //5200 base: ch214 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_214 + + //5200 base: ch38 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_38 + + //5200 base: ch42 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_42 + + //5200 base: ch46 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_46 + + //5200 base: ch50 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_50 + + //5200 base: ch54 + { + { + 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 6, + 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 10 , 11 , 11 , 11 , 11 , 12 , + 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 16 , 16 , 16 , 17 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , + 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 , 25 , 25 , 25 , 25 , 26 , + 26 , 26 , 26 , 27 , 27 , 27 , 27 , 28 , 28 , 28 , 28 , 29 , 29 , 29 , 29 , 29 , 30 , 30 , 30 , 30 , 31 , 31 , 31 , + 31 , 32 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , + 37 , 37 , 37 , 37 , 37 , 37 , 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , + 40 , 40 , 41 , 41 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 42 , 42 , 43 , 43 , 43 , 43 , 43 , 44 , 44 , 44 , 44 , + 44 , 44 , 45 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 47 , 47 , 48 , 48 , + 48 , 48 , 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , + 51 , 52 , 52 , 52 , 52 , 52 , 53 , 53 , 53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 60 + } + }, //RF_CHAN_BOND_54 + + //5500: ch 58 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_58 + + //5500: ch 62 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_62 + + //5500: ch 102 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_102 + + //5500: ch 106 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_106 + + //5500: ch 110 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_110 + + //5500: ch 114 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_114 + + //5500: ch 118 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 0 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_118 + + //5500: ch 122 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_122 + + //5500: ch 126 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_126 + + //5500: ch 130 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_130 + + //5500: ch 134 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_134 + + //5500: ch 138 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_138 + +#ifdef FEATURE_WLAN_CH144 + //5500: ch 142 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + + //5500: ch 151 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_151 + + //5500: ch 155 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_155 + + //5500: ch 159 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_159 + + //5500: ch 163 + { + { + 4 , 4 , 5 , 5 , 5 , 5 , 5 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 10 , 10 , 10 , 11 , 11, + 11 , 11 , 12 , 12 , 12 , 12 , 12 , 12 , 13 , 13 , 13 , 14 , 14 , 14 , 15 , 15 , 15 , 15 , 15 , 16 , 16 , 16 , 16, + 16 , 16 , 17 , 17 , 18 , 18 , 18 , 19 , 19 , 19 , 20 , 20 , 20 , 21 , 21 , 21 , 22 , 22 , 22 , 23 , 23 , 23 , 24, + 24 , 24 , 25 , 25 , 25 , 26 , 26 , 26 , 27 , 27 , 27 , 28 , 28 , 28 , 29 , 29 , 29 , 30 , 30 , 30 , 31 , 31 , 31, + 31 , 32 , 32 , 32 , 33 , 33 , 33 , 33 , 34 , 34 , 34 , 34 , 35 , 35 , 35 , 35 , 36 , 36 , 36 , 36 , 37 , 37 , 37, + 37 , 38 , 38 , 38 , 38 , 39 , 39 , 39 , 39 , 40 , 40 , 40 , 40 , 41 , 41 , 41 , 41 , 42 , 42 , 42 , 42 , 43 , 43, + 43 , 43 , 44 , 44 , 44 , 45 , 45 , 45 , 45 , 45 , 46 , 46 , 46 , 46 , 46 , 46 , 47 , 47 , 47 , 47 , 47 , 48 , 48, + 48 , 48 , 48 , 49 , 49 , 49 , 49 , 49 , 49 , 50 , 50 , 50 , 50 , 50 , 51 , 51 , 51 , 51 , 51 , 52 , 52 , 52 , 52, + 52 , 52 , 53 , 53 , 53 , 53 , 53 , 53 , 54 , 54 , 54 , 54 , 54 , 54 , 55 , 55 , 55 , 55 , 55 , 55 , 56 , 56 , 56, + 56 , 56 , 56 , 57 , 57 , 57 , 57 , 57 , 57 , 58 , 58 , 58 , 58 , 58 , 58 , 59 , 59 , 59 , 59 , 59 , 59 , 60 , 60, + 60 , 61 , 61 , 61 , 61 , 62 , 62 , 62 , 62 , 62 , 63 , 63 , 63 , 63 , 63 , 64 , 64 , 64 , 65 , 66 , 66 + } + }, //RF_CHAN_BOND_163 + }, + + //NV_TABLE_TPC_PDADC_OFFSETS + { + 98, // RF_CHAN_1 + 101, // RF_CHAN_2 + 101, // RF_CHAN_3 + 100, // RF_CHAN_4 + 98, // RF_CHAN_5 + 97, // RF_CHAN_6 + 94, // RF_CHAN_7 + 94, // RF_CHAN_8 + 92, // RF_CHAN_9 + 90, // RF_CHAN_10 + 94, // RF_CHAN_11 + 95, // RF_CHAN_12 + 97, // RF_CHAN_13 + 104, // RF_CHAN_14 + 100, // RF_CHAN_240 + 100, // RF_CHAN_244 + 100, // RF_CHAN_248 + 100, // RF_CHAN_252 + 100, // RF_CHAN_208 + 100, // RF_CHAN_212 + 100, // RF_CHAN_216 + 100, // RF_CHAN_36 + 100, // RF_CHAN_40 + 100, // RF_CHAN_44 + 100, // RF_CHAN_48 + 100, // RF_CHAN_52 + 100, // RF_CHAN_56 + 100, // RF_CHAN_60 + 100, // RF_CHAN_64 + 100, // RF_CHAN_100 + 100, // RF_CHAN_104 + 100, // RF_CHAN_108 + 100, // RF_CHAN_112 + 100, // RF_CHAN_116 + 100, // RF_CHAN_120 + 100, // RF_CHAN_124 + 100, // RF_CHAN_128 + 100, // RF_CHAN_132 + 100, // RF_CHAN_136 + 100, // RF_CHAN_140 +#ifdef FEATURE_WLAN_CH144 + 100, // RF_CHAN_144 +#endif /* FEATURE_WLAN_CH144 */ + 100, // RF_CHAN_149 + 100, // RF_CHAN_153 + 100, // RF_CHAN_157 + 100, // RF_CHAN_161 + 100, // RF_CHAN_165 + //CHANNEL BONDED CHANNELS + 100, // RF_CHAN_BOND_3 + 100, // RF_CHAN_BOND_4 + 100, // RF_CHAN_BOND_5 + 100, // RF_CHAN_BOND_6 + 100, // RF_CHAN_BOND_7 + 100, // RF_CHAN_BOND_8 + 100, // RF_CHAN_BOND_9 + 100, // RF_CHAN_BOND_10 + 100, // RF_CHAN_BOND_11 + 100, // RF_CHAN_BOND_242 + 100, // RF_CHAN_BOND_246 + 100, // RF_CHAN_BOND_250 + 100, // RF_CHAN_BOND_210 + 100, // RF_CHAN_BOND_214 + 100, // RF_CHAN_BOND_38 + 100, // RF_CHAN_BOND_42 + 100, // RF_CHAN_BOND_46 + 100, // RF_CHAN_BOND_50 + 100, // RF_CHAN_BOND_54 + 100, // RF_CHAN_BOND_58 + 100, // RF_CHAN_BOND_62 + 100, // RF_CHAN_BOND_102 + 100, // RF_CHAN_BOND_106 + 100, // RF_CHAN_BOND_110 + 100, // RF_CHAN_BOND_114 + 100, // RF_CHAN_BOND_118 + 100, // RF_CHAN_BOND_122 + 100, // RF_CHAN_BOND_126 + 100, // RF_CHAN_BOND_130 + 100, // RF_CHAN_BOND_134 + 100, // RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + 100, // RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + 100, // RF_CHAN_BOND_151 + 100, // RF_CHAN_BOND_155 + 100, // RF_CHAN_BOND_159 + 100, // RF_CHAN_BOND_163 + }, + + //NV_TABLE_VIRTUAL_RATE + // typedef tANI_S16 tPowerdBm; + //typedef tPowerdBm tRateGroupPwr[NUM_HAL_PHY_RATES]; + //tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; + { + // 2.4G RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G Low RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G Middle RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G High RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 4.9G RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + } + }, + +#if 0 //FIXME_PRIMA + //NV_TABLE_CAL_MEMORY + { + 0x7FFF, // tANI_U16 process_monitor; + 0x00, // tANI_U8 hdet_cal_code; + 0x00, // tANI_U8 rxfe_gm_2; + + 0x00, // tANI_U8 tx_bbf_rtune; + 0x00, // tANI_U8 pa_rtune_reg; + 0x00, // tANI_U8 rt_code; + 0x00, // tANI_U8 bias_rtune; + + 0x00, // tANI_U8 bb_bw1; + 0x00, // tANI_U8 bb_bw2; + { 0x00, 0x00 }, // tANI_U8 reserved[2]; + + 0x00, // tANI_U8 bb_bw3; + 0x00, // tANI_U8 bb_bw4; + 0x00, // tANI_U8 bb_bw5; + 0x00, // tANI_U8 bb_bw6; + + 0x7FFF, // tANI_U16 rcMeasured; + 0x00, // tANI_U8 tx_bbf_ct; + 0x00, // tANI_U8 tx_bbf_ctr; + + 0x00, // tANI_U8 csh_maxgain_reg; + 0x00, // tANI_U8 csh_0db_reg; + 0x00, // tANI_U8 csh_m3db_reg; + 0x00, // tANI_U8 csh_m6db_reg; + + 0x00, // tANI_U8 cff_0db_reg; + 0x00, // tANI_U8 cff_m3db_reg; + 0x00, // tANI_U8 cff_m6db_reg; + 0x00, // tANI_U8 rxfe_gpio_ctl_1; + + 0x00, // tANI_U8 mix_bal_cnt_2; + 0x00, // tANI_S8 rxfe_lna_highgain_bias_ctl_delta; + 0x00, // tANI_U8 rxfe_lna_load_ctune; + 0x00, // tANI_U8 rxfe_lna_ngm_rtune; + + 0x00, // tANI_U8 rx_im2_i_cfg0; + 0x00, // tANI_U8 rx_im2_i_cfg1; + 0x00, // tANI_U8 rx_im2_q_cfg0; + 0x00, // tANI_U8 rx_im2_q_cfg1; + + 0x00, // tANI_U8 pll_vfc_reg3_b0; + 0x00, // tANI_U8 pll_vfc_reg3_b1; + 0x00, // tANI_U8 pll_vfc_reg3_b2; + 0x00, // tANI_U8 pll_vfc_reg3_b3; + + 0x7FFF, // tANI_U16 tempStart; + 0x7FFF, // tANI_U16 tempFinish; + + { //txLoCorrections + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // tTxLoCorrections txLoValues; + + { //sTxIQChannel + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // sTxIQChannel txIqValues; + + { //sRxIQChannel + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // sRxIQChannel rxIqValues; + + { // tTpcConfig clpcData[MAX_TPC_CHANNELS] + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_1 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_2 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_3 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_4 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_5 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_6 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_7 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_8 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_9 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_10 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_11 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_12 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_13 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + } // RF_CHAN_14 + }, // tTpcConfig clpcData[MAX_TPC_CHANNELS]; + + { + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_1: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_2: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_3: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_4: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_5: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_6: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_7: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_8: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_9: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_10: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_11: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_12: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_13: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } } // RF_CHAN_14: pdadc_offset, reserved[2] + } // tTpcParams clpcParams[MAX_TPC_CHANNELS]; + + }, //NV_TABLE_CAL_MEMORY +#endif + //NV_TABLE_FW_CONFIG + { + 0, //skuID + 0, //tpcMode2G + 0, //tpcMode5G + 0, //reserved1 + + 0, //xPA2G + 0, //xPA5G; + 0, //paPolarityTx; + 0, //paPolarityRx; + + 0, //xLNA2G; + 0, //xLNA5G; + 0, //xCoupler2G; + 0, //xCoupler5G; + + 0, //xPdet2G; + 0, //xPdet5G; + 0, //enableDPD2G; + 1, //enableDPD5G; + + 1, //pdadcSelect2G; + 1, //pdadcSelect5GLow; + 1, //pdadcSelect5GMid; + 1, //pdadcSelect5GHigh; + + 0, //reserved2 + 0, //reserved3 + 0, //reserved4 + }, + + + //NV_TABLE_RSSI_CHANNEL_OFFSETS + { + //PHY_RX_CHAIN_0 + { + //bRssiOffset + { + 240, //RF_CHAN_1, + 240, //RF_CHAN_2, + 240, //RF_CHAN_3, + 240, //RF_CHAN_4, + 240, //RF_CHAN_5, + 240, //RF_CHAN_6, + 240, //RF_CHAN_7, + 240, //RF_CHAN_8, + 240, //RF_CHAN_9, + 240, //RF_CHAN_10, + 240, //RF_CHAN_11, + 240, //RF_CHAN_12, + 240, //RF_CHAN_13, + 240, //RF_CHAN_14, + 180, //RF_CHAN_240, + 180, //RF_CHAN_244, + 180, //RF_CHAN_248, + 180, //RF_CHAN_252, + 180, //RF_CHAN_208, + 180, //RF_CHAN_212, + 180, //RF_CHAN_216, + 180, //RF_CHAN_36, + 180, //RF_CHAN_40, + 180, //RF_CHAN_44, + 180, //RF_CHAN_48, + 180, //RF_CHAN_52, + 180, //RF_CHAN_56, + 180, //RF_CHAN_60, + 180, //RF_CHAN_64, + 180, //RF_CHAN_100, + 180, //RF_CHAN_104, + 180, //RF_CHAN_108, + 180, //RF_CHAN_112, + 180, //RF_CHAN_116, + 180, //RF_CHAN_120, + 180, //RF_CHAN_124, + 180, //RF_CHAN_128, + 180, //RF_CHAN_132, + 180, //RF_CHAN_136, + 180, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + 180, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + 180, //RF_CHAN_149, + 180, //RF_CHAN_153, + 180, //RF_CHAN_157, + 180, //RF_CHAN_161, + 180, //RF_CHAN_165, + 240, //RF_CHAN_BOND_3 + 240, //RF_CHAN_BOND_4 + 240, //RF_CHAN_BOND_5 + 240, //RF_CHAN_BOND_6 + 240, //RF_CHAN_BOND_7 + 240, //RF_CHAN_BOND_8 + 240, //RF_CHAN_BOND_9 + 240, //RF_CHAN_BOND_10 + 240, //RF_CHAN_BOND_11 + 180, //RF_CHAN_BOND_242 + 180, //RF_CHAN_BOND_246 + 180, //RF_CHAN_BOND_250 + 180, //RF_CHAN_BOND_210 + 180, //RF_CHAN_BOND_214 + 180, //RF_CHAN_BOND_38, + 180, //RF_CHAN_BOND_42, + 180, //RF_CHAN_BOND_46, + 180, //RF_CHAN_BOND_50, + 180, //RF_CHAN_BOND_54 + 180, //RF_CHAN_BOND_58 + 180, //RF_CHAN_BOND_62 + 180, //RF_CHAN_BOND_102 + 180, //RF_CHAN_BOND_106 + 180, //RF_CHAN_BOND_110 + 180, //RF_CHAN_BOND_114 + 180, //RF_CHAN_BOND_118 + 180, //RF_CHAN_BOND_122 + 180, //RF_CHAN_BOND_126 + 180, //RF_CHAN_BOND_130 + 180, //RF_CHAN_BOND_134 + 180, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + 180, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + 180, //RF_CHAN_BOND_151 + 180, //RF_CHAN_BOND_155 + 180, //RF_CHAN_BOND_159 + 180, //RF_CHAN_BOND_163 + }, + + //gnRssiOffset + { + 240, //RF_CHAN_1, + 240, //RF_CHAN_2, + 240, //RF_CHAN_3, + 240, //RF_CHAN_4, + 240, //RF_CHAN_5, + 240, //RF_CHAN_6, + 240, //RF_CHAN_7, + 240, //RF_CHAN_8, + 240, //RF_CHAN_9, + 240, //RF_CHAN_10, + 240, //RF_CHAN_11, + 240, //RF_CHAN_12, + 240, //RF_CHAN_13, + 240, //RF_CHAN_14, + 180, //RF_CHAN_240, + 180, //RF_CHAN_244, + 180, //RF_CHAN_248, + 180, //RF_CHAN_252, + 180, //RF_CHAN_208, + 180, //RF_CHAN_212, + 180, //RF_CHAN_216, + 180, //RF_CHAN_36, + 180, //RF_CHAN_40, + 180, //RF_CHAN_44, + 180, //RF_CHAN_48, + 180, //RF_CHAN_52, + 180, //RF_CHAN_56, + 180, //RF_CHAN_60, + 180, //RF_CHAN_64, + 180, //RF_CHAN_100, + 180, //RF_CHAN_104, + 180, //RF_CHAN_108, + 180, //RF_CHAN_112, + 180, //RF_CHAN_116, + 180, //RF_CHAN_120, + 180, //RF_CHAN_124, + 180, //RF_CHAN_128, + 180, //RF_CHAN_132, + 180, //RF_CHAN_136, + 180, //RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + 180, //RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + 180, //RF_CHAN_149, + 180, //RF_CHAN_153, + 180, //RF_CHAN_157, + 180, //RF_CHAN_161, + 180, //RF_CHAN_165, + 240, //RF_CHAN_BOND_3 + 240, //RF_CHAN_BOND_4 + 240, //RF_CHAN_BOND_5 + 240, //RF_CHAN_BOND_6 + 240, //RF_CHAN_BOND_7 + 240, //RF_CHAN_BOND_8 + 240, //RF_CHAN_BOND_9 + 240, //RF_CHAN_BOND_10 + 240, //RF_CHAN_BOND_11 + 180, //RF_CHAN_BOND_242 + 180, //RF_CHAN_BOND_246 + 180, //RF_CHAN_BOND_250 + 180, //RF_CHAN_BOND_210 + 180, //RF_CHAN_BOND_214 + 180, //RF_CHAN_BOND_38, + 180, //RF_CHAN_BOND_42, + 180, //RF_CHAN_BOND_46, + 180, //RF_CHAN_BOND_50, + 180, //RF_CHAN_BOND_54 + 180, //RF_CHAN_BOND_58 + 180, //RF_CHAN_BOND_62 + 180, //RF_CHAN_BOND_102 + 180, //RF_CHAN_BOND_106 + 180, //RF_CHAN_BOND_110 + 180, //RF_CHAN_BOND_114 + 180, //RF_CHAN_BOND_118 + 180, //RF_CHAN_BOND_122 + 180, //RF_CHAN_BOND_126 + 180, //RF_CHAN_BOND_130 + 180, //RF_CHAN_BOND_134 + 180, //RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + 180, //RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + 180, //RF_CHAN_BOND_151 + 180, //RF_CHAN_BOND_155 + 180, //RF_CHAN_BOND_159 + 180, //RF_CHAN_BOND_163 + }, + }, + //rsvd + { + //bRssiOffset + {0}, // apply to all channles + + //gnRssiOffset + {0} // apply to all channles + } + }, + + //NV_TABLE_HW_CAL_VALUES + { + 0x0, //validBmap + { + 1400, //psSlpTimeOvrHd2G; + 1400, //psSlpTimeOvrHd5G; + + 1600, //psSlpTimeOvrHdxLNA5G; + 0, //nv_TxBBFSel9MHz + 0, //hwParam1 + 0, //hwParam2 + + 0x1B, //custom_tcxo_reg8 + 0xFF, //custom_tcxo_reg9 + + 0, //hwParam3; + 0, //hwParam4; + 0, //hwParam5; + 0, //hwParam6; + 0, //hwParam7; + 0, //hwParam8; + 0, //hwParam9; + 0, //hwParam10; + 0, //hwParam11; + } + }, + + + //NV_TABLE_ANTENNA_PATH_LOSS + { + 280, // RF_CHAN_1 + 270, // RF_CHAN_2 + 270, // RF_CHAN_3 + 270, // RF_CHAN_4 + 270, // RF_CHAN_5 + 270, // RF_CHAN_6 + 280, // RF_CHAN_7 + 280, // RF_CHAN_8 + 290, // RF_CHAN_9 + 300, // RF_CHAN_10 + 300, // RF_CHAN_11 + 310, // RF_CHAN_12 + 310, // RF_CHAN_13 + 310, // RF_CHAN_14 + 280, // RF_CHAN_240 + 280, // RF_CHAN_244 + 280, // RF_CHAN_248 + 280, // RF_CHAN_252 + 280, // RF_CHAN_208 + 280, // RF_CHAN_212 + 280, // RF_CHAN_216 + 280, // RF_CHAN_36 + 280, // RF_CHAN_40 + 280, // RF_CHAN_44 + 280, // RF_CHAN_48 + 280, // RF_CHAN_52 + 280, // RF_CHAN_56 + 280, // RF_CHAN_60 + 280, // RF_CHAN_64 + 280, // RF_CHAN_100 + 280, // RF_CHAN_104 + 280, // RF_CHAN_108 + 280, // RF_CHAN_112 + 280, // RF_CHAN_116 + 280, // RF_CHAN_120 + 280, // RF_CHAN_124 + 280, // RF_CHAN_128 + 280, // RF_CHAN_132 + 280, // RF_CHAN_136 + 280, // RF_CHAN_140 +#ifdef FEATURE_WLAN_CH144 + 280, // RF_CHAN_144 +#endif /* FEATURE_WLAN_CH144 */ + 280, // RF_CHAN_149 + 280, // RF_CHAN_153 + 280, // RF_CHAN_157 + 280, // RF_CHAN_161 + 280, // RF_CHAN_165 + //CHANNEL BONDED CHANNELS + 280, // RF_CHAN_BOND_3 + 280, // RF_CHAN_BOND_4 + 280, // RF_CHAN_BOND_5 + 280, // RF_CHAN_BOND_6 + 280, // RF_CHAN_BOND_7 + 280, // RF_CHAN_BOND_8 + 280, // RF_CHAN_BOND_9 + 280, // RF_CHAN_BOND_10 + 280, // RF_CHAN_BOND_11 + 280, // RF_CHAN_BOND_242 + 280, // RF_CHAN_BOND_246 + 280, // RF_CHAN_BOND_250 + 280, // RF_CHAN_BOND_210 + 280, // RF_CHAN_BOND_214 + 280, // RF_CHAN_BOND_38 + 280, // RF_CHAN_BOND_42 + 280, // RF_CHAN_BOND_46 + 280, // RF_CHAN_BOND_50 + 280, // RF_CHAN_BOND_54 + 280, // RF_CHAN_BOND_58 + 280, // RF_CHAN_BOND_62 + 280, // RF_CHAN_BOND_102 + 280, // RF_CHAN_BOND_106 + 280, // RF_CHAN_BOND_110 + 280, // RF_CHAN_BOND_114 + 280, // RF_CHAN_BOND_118 + 280, // RF_CHAN_BOND_122 + 280, // RF_CHAN_BOND_126 + 280, // RF_CHAN_BOND_130 + 280, // RF_CHAN_BOND_134 + 280, // RF_CHAN_BOND_138 +#ifdef FEATURE_WLAN_CH144 + 280, // RF_CHAN_BOND_142 +#endif /* FEATURE_WLAN_CH144 */ + 280, // RF_CHAN_BOND_151 + 280, // RF_CHAN_BOND_155 + 280, // RF_CHAN_BOND_159 + 280, // RF_CHAN_BOND_163 + }, + + //NV_TABLE_PACKET_TYPE_POWER_LIMITS + { + { 2150 }, // applied to all channels, MODE_802_11B + { 1850 }, // applied to all channels,MODE_802_11AG + { 1750 } // applied to all channels,MODE_802_11N + }, + + //NV_TABLE_OFDM_CMD_PWR_OFFSET + { + 0, 0 + }, + + //NV_TABLE_TX_BB_FILTER_MODE + { + 0 + } + + } // tables +}; + +const sHalNvV2 nvDefaultsV2 = +{ + { + 0, // tANI_U16 productId; + 1, // tANI_U8 productBands; + 2, // tANI_U8 wlanNvRevId; //0: WCN1312, 1: WCN1314, 2: WCN3660 + 1, // tANI_U8 numOfTxChains; + 1, // tANI_U8 numOfRxChains; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // tANI_U8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; + { "\0" }, + 0, // tANI_U8 couplerType; + WLAN_NV_VERSION, // tANI_U8 nvVersion; + }, //fields + + { + // NV_TABLE_RATE_POWER_SETTINGS + { + // typedef tANI_S16 tPowerdBm; + //typedef tPowerdBm tRateGroupPwr[NUM_HAL_PHY_RATES]; + //tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; + //2.4G + { + //802.11b Rates + {1900}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {1900}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {1900}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + //11A 20MHz Rates + {1700}, // HAL_PHY_RATE_11A_6_MBPS, + {1700}, // HAL_PHY_RATE_11A_9_MBPS, + {1700}, // HAL_PHY_RATE_11A_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_18_MBPS, + {1600}, // HAL_PHY_RATE_11A_24_MBPS, + {1550}, // HAL_PHY_RATE_11A_36_MBPS, + {1550}, // HAL_PHY_RATE_11A_48_MBPS, + {1550}, // HAL_PHY_RATE_11A_54_MBPS, + + //DUP 11A 40MHz Rates + {1700}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + //MCS Index #0-7(20/40MHz) + {1700}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + //MCS Index #8-15(20/40MHz) + {1700}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1700}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1650}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATURE_11AC + //11AC rates + //11A duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + //11ac 20MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + {0000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + + //11ac 40MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + {0000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + //11ac 80MHZ NG, SG + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + {0000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_2_4_GHZ + // 5G Low + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DUP 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11AC rates + ///11A duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11ac 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + //11ac 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_5_LOW_GHZ + // 5G Mid + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_111AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // // RF_SUBBAND_5_MID_GHZ + // 5G High + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_5_HIGH_GHZ, + // 4.9G + + { + //802.11b Rates + {0}, // HAL_PHY_RATE_11B_LONG_1_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_2_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_LONG_11_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_2_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + {0}, // HAL_PHY_RATE_11B_SHORT_11_MBPS, + + ///11A 20MHz Rates + {1600}, // HAL_PHY_RATE_11A_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_12_MBPS, + {1550}, // HAL_PHY_RATE_11A_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_54_MBPS, + + ///DU P 11A 40MHz Rates + {1600}, // HAL_PHY_RATE_11A_DUP_6_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_9_MBPS, + {1600}, // HAL_PHY_RATE_11A_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11A_DUP_18_MBPS, + {1550}, // HAL_PHY_RATE_11A_DUP_24_MBPS, + {1450}, // HAL_PHY_RATE_11A_DUP_36_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_48_MBPS, + {1400}, // HAL_PHY_RATE_11A_DUP_54_MBPS, + + ///MCSS Index #0-7(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_13_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_26_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_39_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_52_MBPS, + {1350}, // HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_65_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + ///MCSS Index #8-15(20/40MHz) + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + {1550}, // HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + {1600}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + {1500}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + {1450}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + {1400}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + {1300}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + {1200}, // HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATUURE_11AC + ///11CAC rates + ///11Ad duplicate 80MHz Rates + {1700}, // HAL_PHY_RATE_11AC_DUP_6_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_9_MBPS, + {1700}, // HAL_PHY_RATE_11AC_DUP_12_MBPS, + {1650}, // HAL_PHY_RATE_11AC_DUP_18_MBPS, + {1600}, // HAL_PHY_RATE_11AC_DUP_24_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_36_MBPS, + {1550}, // HAL_PHY_RATE_11AC_DUP_48_MBPS, + {1500}, // HAL_PHY_RATE_11AC_DUP_54_MBPS, + + ///11a c 20MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_6_5_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_13_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_19_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_26_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_39_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_52_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_65_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_NGI_78_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_7_2_MBPS, + {1400}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_14_4_MBPS, + {1350}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_21_6_MBPS, + {1300}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_28_8_MBPS, + {1250}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_43_3_MBPS, + {1200}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_57_7_MBPS, + {1100}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_72_2_MBPS, + { 900}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_CB_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + { 800}, // HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + //11ac 40MHZ NG, SG + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + {1400}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS, + {1300}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + {1250}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + {1000}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + { 900}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + { 800}, // HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + + ///11a c 80MHZ NG, SG + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + {1300}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS, + {1100}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + {1000}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + { 900}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + { 800}, // HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif + }, // RF_SUBBAND_4_9_GHZ + }, + + // NV_TABLE_REGULATORY_DOMAINS + { + // typedef struct + // { + // tANI_BOOLEAN enabled; + // tPowerdBm pwrLimit; + // }sRegulatoryChannel; + + // typedef struct + // { + // sRegulatoryChannel channels[NUM_RF_CHANNELS]; + // uAbsPwrPrecision antennaGain[NUM_RF_SUBBANDS]; + // uAbsPwrPrecision bRatePowerOffset[NUM_2_4GHZ_CHANNELS]; + // }sRegulatoryDomains; + + //sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; + + + { // REG_DOMAIN_FCC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_11, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_12, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_FCC end + + { // REG_DOMAIN_ETSI start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 19}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 19}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 23}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_ETSI end + + { // REG_DOMAIN_JAPAN start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_13, + {NV_CHANNEL_ENABLE, 18}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_120, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_124, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_JAPAN end + + { // REG_DOMAIN_WORLD start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_52, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_56, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_60, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DFS, 22}, //RF_CHAN_100, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_104, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_108, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_112, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_116, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_120, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_124, + {NV_CHANNEL_DFS, 0}, //RF_CHAN_128, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_132, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_136, + {NV_CHANNEL_DFS, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_WORLD end + + { // REG_DOMAIN_N_AMER_EXC_FCC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_11, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_12, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_N_AMER_EXC_FCC end + + { // REG_DOMAIN_APAC start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 26}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 16}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_APAC end + + { // REG_DOMAIN_KOREA start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 15}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_KOREA end + + { // REG_DOMAIN_HI_5GHZ start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band, none CB + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 14}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + + //4.9GHz Band, none CB + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_240, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_244, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_248, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_252, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_208, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_212, + {NV_CHANNEL_DISABLE, 23}, //RF_CHAN_216, + + //5GHz Low & Mid U-NII Band, none CB + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_36, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_40, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_44, + {NV_CHANNEL_ENABLE, 17}, //RF_CHAN_48, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_52, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_56, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_60, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_64, + + //5GHz Mid Band - ETSI, none CB + {NV_CHANNEL_DISABLE, 22}, //RF_CHAN_100, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_104, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_108, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_112, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_116, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_120, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_124, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_128, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_132, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_136, + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_140, + + //5GHz High U-NII Band, none CB + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_149, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_153, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_157, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_161, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_165, + + //2.4GHz Band, channel bonded channels + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_3, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_4, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_5, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_6, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_7, + {NV_CHANNEL_ENABLE, 30}, //RF_CHAN_BOND_8, + {NV_CHANNEL_ENABLE, 22}, //RF_CHAN_BOND_9, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_10, + {NV_CHANNEL_ENABLE, 0}, //RF_CHAN_BOND_11, + + // 4.9GHz Band, channel bonded channels + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_242, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_246, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_250, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_210, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_214, + + //5GHz Low & Mid U-NII Band, channel bonded channels + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_38, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_42, + {NV_CHANNEL_ENABLE, 20}, //RF_CHAN_BOND_46, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_50, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_54, + {NV_CHANNEL_ENABLE, 27}, //RF_CHAN_BOND_58, + {NV_CHANNEL_ENABLE, 25}, //RF_CHAN_BOND_62, + + //5GHz Mid Band - ETSI, channel bonded channels + {NV_CHANNEL_DISABLE, 24}, //RF_CHAN_BOND_102 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_106 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_110 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_114 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_118 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_122 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_126 + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_130 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_134 + {NV_CHANNEL_DISABLE, 27}, //RF_CHAN_BOND_138 + + //5GHz High U-NII Band, channel bonded channels + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_151, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_155, + {NV_CHANNEL_DISABLE, 30}, //RF_CHAN_BOND_159, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_BOND_163 + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + }, // REG_DOMAIN_HI_5GHZ end + + { // REG_DOMAIN_NO_5GHZ start + { //sRegulatoryChannel start + //enabled, pwrLimit + //2.4GHz Band + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_1, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_2, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_3, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_4, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_5, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_6, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_7, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_8, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_9, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_10, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_11, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_12, + {NV_CHANNEL_ENABLE, 12}, //RF_CHAN_13, + {NV_CHANNEL_DISABLE, 0}, //RF_CHAN_14, + }, //sRegulatoryChannel end + + { + { 0 }, // RF_SUBBAND_2_4_GHZ + {0}, // RF_SUBBAND_5_LOW_GHZ + {0}, // RF_SUBBAND_5_MID_GHZ + {0}, // RF_SUBBAND_5_HIGH_GHZ + {0} // RF_SUBBAND_4_9_GHZ + }, + + { // bRatePowerOffset start + //2.4GHz Band + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + }, // bRatePowerOffset end + + { // gnRatePowerOffset start + //apply to all 2.4 and 5G channels + { 0 }, //RF_CHAN_1, + { 0 }, //RF_CHAN_2, + { 0 }, //RF_CHAN_3, + { 0 }, //RF_CHAN_4, + { 0 }, //RF_CHAN_5, + { 0 }, //RF_CHAN_6, + { 0 }, //RF_CHAN_7, + { 0 }, //RF_CHAN_8, + { 0 }, //RF_CHAN_9, + { 0 }, //RF_CHAN_10, + { 0 }, //RF_CHAN_11, + { 0 }, //RF_CHAN_12, + { 0 }, //RF_CHAN_13, + { 0 }, //RF_CHAN_14, + } // gnRatePowerOffset end + } // REG_DOMAIN_NO_5GHZ end + }, + + // NV_TABLE_DEFAULT_COUNTRY + { + // typedef struct + // { + // tANI_U8 regDomain; //from eRegDomainId + // tANI_U8 countryCode[NV_FIELD_COUNTRY_CODE_SIZE]; // string identifier + // }sDefaultCountry; + + 0, // regDomain + { 'U', 'S', 'I' } // countryCode + }, + + //NV_TABLE_TPC_POWER_TABLE + { + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 56 , //9 + 58 , //10 + 59 , //11 + 60 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 65 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 75 , //26 + 76 , //27 + 77 , //28 + 78 , //29 + 78 , //30 + 79 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 82 , //35 + 83 , //36 + 83 , //37 + 84 , //38 + 85 , //39 + 86 , //40 + 86 , //41 + 87 , //42 + 88 , //43 + 89 , //44 + 89 , //45 + 90 , //46 + 91 , //47 + 91 , //48 + 92 , //49 + 92 , //50 + 93 , //51 + 93 , //52 + 94 , //53 + 94 , //54 + 95 , //55 + 95 , //56 + 95 , //57 + 96 , //58 + 96 , //59 + 97 , //60 + 97 , //61 + 98 , //62 + 98 , //63 + 98 , //64 + 99 , //65 + 99 , //66 + 99 , //67 + 100, //68 + 100, //69 + 100, //70 + 101, //71 + 101, //72 + 102, //73 + 102, //74 + 102, //75 + 102, //76 + 103, //77 + 103, //78 + 103, //79 + 103, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_1 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 52 , //7 + 54 , //8 + 56 , //9 + 57 , //10 + 59 , //11 + 60 , //12 + 61 , //13 + 62 , //14 + 64 , //15 + 65 , //16 + 66 , //17 + 67 , //18 + 68 , //19 + 69 , //20 + 70 , //21 + 71 , //22 + 72 , //23 + 73 , //24 + 74 , //25 + 75 , //26 + 75 , //27 + 76 , //28 + 77 , //29 + 78 , //30 + 79 , //31 + 79 , //32 + 80 , //33 + 81 , //34 + 82 , //35 + 82 , //36 + 83 , //37 + 84 , //38 + 85 , //39 + 85 , //40 + 86 , //41 + 87 , //42 + 88 , //43 + 88 , //44 + 89 , //45 + 89 , //46 + 90 , //47 + 91 , //48 + 91 , //49 + 92 , //50 + 92 , //51 + 93 , //52 + 93 , //53 + 94 , //54 + 94 , //55 + 95 , //56 + 95 , //57 + 96 , //58 + 96 , //59 + 96 , //60 + 97 , //61 + 97 , //62 + 98 , //63 + 98 , //64 + 98 , //65 + 99 , //66 + 99 , //67 + 99 , //68 + 100, //69 + 100, //70 + 101, //71 + 101, //72 + 101, //73 + 101, //74 + 102, //75 + 102, //76 + 102, //77 + 103, //78 + 103, //79 + 103, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 107, //103 + 107, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_2 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 52 , //7 + 54 , //8 + 55 , //9 + 57 , //10 + 58 , //11 + 60 , //12 + 61 , //13 + 62 , //14 + 64 , //15 + 65 , //16 + 66 , //17 + 67 , //18 + 68 , //19 + 69 , //20 + 70 , //21 + 71 , //22 + 72 , //23 + 73 , //24 + 74 , //25 + 75 , //26 + 75 , //27 + 76 , //28 + 77 , //29 + 78 , //30 + 78 , //31 + 79 , //32 + 80 , //33 + 81 , //34 + 82 , //35 + 82 , //36 + 83 , //37 + 84 , //38 + 84 , //39 + 85 , //40 + 86 , //41 + 87 , //42 + 87 , //43 + 88 , //44 + 89 , //45 + 89 , //46 + 90 , //47 + 90 , //48 + 91 , //49 + 91 , //50 + 92 , //51 + 93 , //52 + 93 , //53 + 94 , //54 + 94 , //55 + 94 , //56 + 95 , //57 + 95 , //58 + 96 , //59 + 96 , //60 + 97 , //61 + 97 , //62 + 97 , //63 + 98 , //64 + 98 , //65 + 99 , //66 + 99 , //67 + 99 , //68 + 100, //69 + 100, //70 + 100, //71 + 101, //72 + 101, //73 + 101, //74 + 102, //75 + 102, //76 + 102, //77 + 103, //78 + 103, //79 + 103, //80 + 103, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 105, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 107, + } + }, //RF_CHAN_3 + { + { + 0 , //0 + 42 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 57 , //9 + 58 , //10 + 60 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 75 , //26 + 76 , //27 + 77 , //28 + 78 , //29 + 78 , //30 + 79 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 82 , //35 + 83 , //36 + 84 , //37 + 84 , //38 + 85 , //39 + 86 , //40 + 87 , //41 + 87 , //42 + 88 , //43 + 88 , //44 + 89 , //45 + 90 , //46 + 90 , //47 + 91 , //48 + 91 , //49 + 92 , //50 + 92 , //51 + 93 , //52 + 93 , //53 + 94 , //54 + 94 , //55 + 95 , //56 + 95 , //57 + 95 , //58 + 96 , //59 + 96 , //60 + 97 , //61 + 97 , //62 + 98 , //63 + 98 , //64 + 98 , //65 + 99 , //66 + 99 , //67 + 99 , //68 + 100, //69 + 100, //70 + 100, //71 + 101, //72 + 101, //73 + 101, //74 + 102, //75 + 102, //76 + 102, //77 + 103, //78 + 103, //79 + 103, //80 + 103, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 104, //88 + 104, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 106, + } + }, //RF_CHAN_4 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 54 , //8 + 56 , //9 + 57 , //10 + 59 , //11 + 60 , //12 + 62 , //13 + 63 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 69 , //20 + 71 , //21 + 72 , //22 + 72 , //23 + 73 , //24 + 74 , //25 + 75 , //26 + 76 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 79 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 83 , //36 + 84 , //37 + 85 , //38 + 86 , //39 + 87 , //40 + 87 , //41 + 88 , //42 + 89 , //43 + 89 , //44 + 90 , //45 + 91 , //46 + 91 , //47 + 92 , //48 + 92 , //49 + 93 , //50 + 93 , //51 + 94 , //52 + 94 , //53 + 95 , //54 + 95 , //55 + 96 , //56 + 96 , //57 + 96 , //58 + 97 , //59 + 97 , //60 + 98 , //61 + 98 , //62 + 98 , //63 + 99 , //64 + 99 , //65 + 100, //66 + 100, //67 + 100, //68 + 101, //69 + 101, //70 + 101, //71 + 102, //72 + 102, //73 + 102, //74 + 103, //75 + 103, //76 + 103, //77 + 103, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 105, //83 + 105, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 106, + } + }, //RF_CHAN_5 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 56 , //9 + 58 , //10 + 59 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 65 , //16 + 66 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 80 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 83 , //36 + 84 , //37 + 85 , //38 + 86 , //39 + 87 , //40 + 87 , //41 + 88 , //42 + 89 , //43 + 89 , //44 + 90 , //45 + 91 , //46 + 91 , //47 + 92 , //48 + 92 , //49 + 93 , //50 + 93 , //51 + 94 , //52 + 94 , //53 + 95 , //54 + 95 , //55 + 96 , //56 + 96 , //57 + 97 , //58 + 97 , //59 + 98 , //60 + 98 , //61 + 98 , //62 + 99 , //63 + 99 , //64 + 100, //65 + 100, //66 + 100, //67 + 101, //68 + 101, //69 + 101, //70 + 102, //71 + 102, //72 + 102, //73 + 103, //74 + 103, //75 + 103, //76 + 103, //77 + 104, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 105, //83 + 105, //84 + 105, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_6 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 53 , //7 + 55 , //8 + 56 , //9 + 58 , //10 + 60 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 64 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 80 , //31 + 80 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 84 , //36 + 84 , //37 + 85 , //38 + 86 , //39 + 87 , //40 + 87 , //41 + 88 , //42 + 88 , //43 + 89 , //44 + 90 , //45 + 90 , //46 + 91 , //47 + 91 , //48 + 92 , //49 + 92 , //50 + 93 , //51 + 93 , //52 + 94 , //53 + 94 , //54 + 95 , //55 + 95 , //56 + 96 , //57 + 96 , //58 + 97 , //59 + 97 , //60 + 97 , //61 + 98 , //62 + 98 , //63 + 99 , //64 + 99 , //65 + 99 , //66 + 100, //67 + 100, //68 + 100, //69 + 101, //70 + 101, //71 + 101, //72 + 102, //73 + 102, //74 + 102, //75 + 103, //76 + 103, //77 + 103, //78 + 103, //79 + 104, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 105, //86 + 105, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 106, //105 + 106, //106 + 106, //107 + 106, //108 + 106, //109 + 106, //110 + 106, //111 + 106, //112 + 106, //113 + 106, //114 + 106, //115 + 106, //116 + 106, //117 + 106, //118 + 106, //119 + 106, //120 + 106, //121 + 106, //122 + 106, //123 + 106, //124 + 106, //125 + 106, //126 + 106, //127 + 106, + } + }, //RF_CHAN_7 + { + { + 0 , //0 + 40 , //1 + 42 , //2 + 45 , //3 + 47 , //4 + 49 , //5 + 51 , //6 + 52 , //7 + 54 , //8 + 56 , //9 + 58 , //10 + 59 , //11 + 61 , //12 + 62 , //13 + 63 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 68 , //18 + 69 , //19 + 70 , //20 + 71 , //21 + 72 , //22 + 73 , //23 + 74 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 77 , //28 + 78 , //29 + 79 , //30 + 80 , //31 + 81 , //32 + 81 , //33 + 82 , //34 + 83 , //35 + 84 , //36 + 85 , //37 + 86 , //38 + 86 , //39 + 87 , //40 + 88 , //41 + 89 , //42 + 89 , //43 + 90 , //44 + 91 , //45 + 91 , //46 + 92 , //47 + 92 , //48 + 93 , //49 + 93 , //50 + 94 , //51 + 94 , //52 + 95 , //53 + 95 , //54 + 96 , //55 + 96 , //56 + 97 , //57 + 97 , //58 + 97 , //59 + 98 , //60 + 98 , //61 + 99 , //62 + 99 , //63 + 99 , //64 + 100, //65 + 100, //66 + 100, //67 + 101, //68 + 101, //69 + 102, //70 + 102, //71 + 102, //72 + 103, //73 + 103, //74 + 103, //75 + 104, //76 + 104, //77 + 104, //78 + 104, //79 + 105, //80 + 105, //81 + 105, //82 + 105, //83 + 105, //84 + 105, //85 + 105, //86 + 105, //87 + 106, //88 + 106, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 106, //99 + 106, //100 + 106, //101 + 106, //102 + 106, //103 + 106, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_8 + { + { + 0 , //0 + 41 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 54 , //7 + 56 , //8 + 58 , //9 + 59 , //10 + 60 , //11 + 62 , //12 + 63 , //13 + 64 , //14 + 66 , //15 + 67 , //16 + 68 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 78 , //27 + 79 , //28 + 79 , //29 + 80 , //30 + 81 , //31 + 82 , //32 + 83 , //33 + 83 , //34 + 84 , //35 + 85 , //36 + 86 , //37 + 87 , //38 + 87 , //39 + 88 , //40 + 89 , //41 + 89 , //42 + 90 , //43 + 91 , //44 + 91 , //45 + 92 , //46 + 92 , //47 + 93 , //48 + 93 , //49 + 94 , //50 + 94 , //51 + 95 , //52 + 95 , //53 + 96 , //54 + 96 , //55 + 97 , //56 + 97 , //57 + 98 , //58 + 98 , //59 + 98 , //60 + 99 , //61 + 99 , //62 + 100, //63 + 100, //64 + 100, //65 + 101, //66 + 101, //67 + 101, //68 + 102, //69 + 102, //70 + 103, //71 + 103, //72 + 103, //73 + 104, //74 + 104, //75 + 104, //76 + 104, //77 + 105, //78 + 105, //79 + 105, //80 + 105, //81 + 105, //82 + 105, //83 + 106, //84 + 106, //85 + 106, //86 + 106, //87 + 106, //88 + 106, //89 + 106, //90 + 106, //91 + 106, //92 + 106, //93 + 106, //94 + 106, //95 + 106, //96 + 106, //97 + 106, //98 + 107, //99 + 107, //100 + 107, //101 + 107, //102 + 107, //103 + 107, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_9 + { + { + 0 , //0 + 41 , //1 + 43 , //2 + 47 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 53 , //7 + 55 , //8 + 57 , //9 + 58 , //10 + 60 , //11 + 62 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 67 , //16 + 68 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 81 , //31 + 82 , //32 + 83 , //33 + 84 , //34 + 85 , //35 + 85 , //36 + 86 , //37 + 87 , //38 + 88 , //39 + 89 , //40 + 89 , //41 + 90 , //42 + 90 , //43 + 91 , //44 + 92 , //45 + 92 , //46 + 93 , //47 + 94 , //48 + 94 , //49 + 95 , //50 + 95 , //51 + 96 , //52 + 96 , //53 + 96 , //54 + 97 , //55 + 97 , //56 + 98 , //57 + 98 , //58 + 99 , //59 + 99 , //60 + 99 , //61 + 100, //62 + 100, //63 + 101, //64 + 101, //65 + 102, //66 + 102, //67 + 102, //68 + 103, //69 + 103, //70 + 103, //71 + 104, //72 + 104, //73 + 104, //74 + 105, //75 + 105, //76 + 105, //77 + 105, //78 + 105, //79 + 106, //80 + 106, //81 + 106, //82 + 106, //83 + 106, //84 + 106, //85 + 106, //86 + 106, //87 + 106, //88 + 107, //89 + 107, //90 + 107, //91 + 107, //92 + 107, //93 + 107, //94 + 107, //95 + 107, //96 + 107, //97 + 107, //98 + 107, //99 + 107, //100 + 107, //101 + 107, //102 + 107, //103 + 107, //104 + 107, //105 + 107, //106 + 107, //107 + 107, //108 + 107, //109 + 107, //110 + 107, //111 + 107, //112 + 107, //113 + 107, //114 + 107, //115 + 107, //116 + 107, //117 + 107, //118 + 107, //119 + 107, //120 + 107, //121 + 107, //122 + 107, //123 + 107, //124 + 107, //125 + 107, //126 + 107, //127 + 107, + } + }, //RF_CHAN_10 + { + { + 0 , //0 + 42 , //1 + 44 , //2 + 47 , //3 + 49 , //4 + 51 , //5 + 52 , //6 + 54 , //7 + 55 , //8 + 57 , //9 + 58 , //10 + 60 , //11 + 61 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 81 , //31 + 82 , //32 + 82 , //33 + 83 , //34 + 84 , //35 + 85 , //36 + 86 , //37 + 86 , //38 + 87 , //39 + 88 , //40 + 89 , //41 + 90 , //42 + 90 , //43 + 91 , //44 + 91 , //45 + 92 , //46 + 92 , //47 + 93 , //48 + 93 , //49 + 94 , //50 + 94 , //51 + 95 , //52 + 96 , //53 + 96 , //54 + 97 , //55 + 97 , //56 + 97 , //57 + 98 , //58 + 98 , //59 + 99 , //60 + 99 , //61 + 100, //62 + 100, //63 + 100, //64 + 101, //65 + 101, //66 + 101, //67 + 102, //68 + 102, //69 + 102, //70 + 103, //71 + 103, //72 + 103, //73 + 103, //74 + 103, //75 + 103, //76 + 104, //77 + 104, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 105, //88 + 105, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 105, //105 + 105, //106 + 105, //107 + 105, //108 + 105, //109 + 105, //110 + 105, //111 + 105, //112 + 105, //113 + 105, //114 + 105, //115 + 105, //116 + 105, //117 + 105, //118 + 105, //119 + 105, //120 + 105, //121 + 105, //122 + 105, //123 + 105, //124 + 105, //125 + 105, //126 + 105, //127 + } + }, //RF_CHAN_11 + { + { + 0 , //0 + 41 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 54 , //7 + 56 , //8 + 57 , //9 + 59 , //10 + 60 , //11 + 61 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 66 , //16 + 67 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 76 , //25 + 77 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 80 , //31 + 81 , //32 + 82 , //33 + 83 , //34 + 83 , //35 + 84 , //36 + 85 , //37 + 86 , //38 + 86 , //39 + 87 , //40 + 88 , //41 + 88 , //42 + 89 , //43 + 90 , //44 + 90 , //45 + 91 , //46 + 92 , //47 + 92 , //48 + 93 , //49 + 93 , //50 + 94 , //51 + 94 , //52 + 95 , //53 + 95 , //54 + 96 , //55 + 96 , //56 + 96 , //57 + 97 , //58 + 97 , //59 + 98 , //60 + 98 , //61 + 99 , //62 + 99 , //63 + 99 , //64 + 100, //65 + 100, //66 + 100, //67 + 101, //68 + 101, //69 + 101, //70 + 102, //71 + 102, //72 + 102, //73 + 103, //74 + 103, //75 + 103, //76 + 103, //77 + 103, //78 + 103, //79 + 103, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 104, //88 + 104, //89 + 104, //90 + 104, //91 + 104, //92 + 104, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 105, //105 + 105, //106 + 105, //107 + 105, //108 + 105, //109 + 105, //110 + 105, //111 + 105, //112 + 105, //113 + 105, //114 + 105, //115 + 105, //116 + 105, //117 + 105, //118 + 105, //119 + 105, //120 + 105, //121 + 105, //122 + 105, //123 + 105, //124 + 105, //125 + 105, //126 + 105, //127 + 105, + } + }, //RF_CHAN_12 + { + { + 0 , //0 + 42 , //1 + 44 , //2 + 46 , //3 + 48 , //4 + 50 , //5 + 52 , //6 + 54 , //7 + 56 , //8 + 58 , //9 + 59 , //10 + 60 , //11 + 61 , //12 + 63 , //13 + 64 , //14 + 65 , //15 + 66 , //16 + 68 , //17 + 69 , //18 + 70 , //19 + 71 , //20 + 72 , //21 + 73 , //22 + 74 , //23 + 75 , //24 + 75 , //25 + 76 , //26 + 77 , //27 + 78 , //28 + 79 , //29 + 80 , //30 + 80 , //31 + 81 , //32 + 82 , //33 + 83 , //34 + 83 , //35 + 84 , //36 + 85 , //37 + 86 , //38 + 86 , //39 + 87 , //40 + 88 , //41 + 89 , //42 + 89 , //43 + 90 , //44 + 91 , //45 + 91 , //46 + 92 , //47 + 93 , //48 + 93 , //49 + 94 , //50 + 94 , //51 + 95 , //52 + 95 , //53 + 96 , //54 + 96 , //55 + 97 , //56 + 97 , //57 + 97 , //58 + 98 , //59 + 98 , //60 + 99 , //61 + 99 , //62 + 100, //63 + 100, //64 + 100, //65 + 101, //66 + 101, //67 + 101, //68 + 102, //69 + 102, //70 + 102, //71 + 103, //72 + 103, //73 + 103, //74 + 103, //75 + 103, //76 + 103, //77 + 104, //78 + 104, //79 + 104, //80 + 104, //81 + 104, //82 + 104, //83 + 104, //84 + 104, //85 + 104, //86 + 104, //87 + 104, //88 + 104, //89 + 105, //90 + 105, //91 + 105, //92 + 105, //93 + 105, //94 + 105, //95 + 105, //96 + 105, //97 + 105, //98 + 105, //99 + 105, //100 + 105, //101 + 105, //102 + 105, //103 + 105, //104 + 105, //105 + 105, //106 + 105, //107 + 105, //108 + 105, //109 + 105, //110 + 105, //111 + 105, //112 + 105, //113 + 105, //114 + 105, //115 + 105, //116 + 105, //117 + 105, //118 + 105, //119 + 105, //120 + 105, //121 + 105, //122 + 105, //123 + 105, //124 + 105, //125 + 105, //126 + 105, //127 + 105, + } + }, //RF_CHAN_13 + { + { + 0, //0 + 40, //1 + 43, //2 + 45, //3 + 47, //4 + 49, //5 + 50, //6 + 52, //7 + 54, //8 + 56, //9 + 57, //10 + 58, //11 + 59, //12 + 60, //13 + 62, //14 + 63, //15 + 64, //16 + 65, //17 + 66, //18 + 67, //19 + 68, //20 + 69, //21 + 70, //22 + 71, //23 + 72, //24 + 73, //25 + 74, //26 + 74, //27 + 75, //28 + 76, //29 + 77, //30 + 78, //31 + 78, //32 + 79, //33 + 80, //34 + 81, //35 + 82, //36 + 83, //37 + 83, //38 + 84, //39 + 85, //40 + 85, //41 + 86, //42 + 87, //43 + 87, //44 + 88, //45 + 89, //46 + 89, //47 + 90, //48 + 90, //49 + 91, //50 + 91, //51 + 92, //52 + 92, //53 + 93, //54 + 93, //55 + 94, //56 + 94, //57 + 95, //58 + 95, //59 + 96, //60 + 96, //61 + 96, //62 + 97, //63 + 97, //64 + 97, //65 + 98, //66 + 98, //67 + 98, //68 + 98, //69 + 99, //70 + 99, //71 + 99, //72 + 99, //73 + 99, //74 + 99, //75 + 99, //76 + 99, //77 + 99, //78 + 99, //79 + 100, //80 + 100, //81 + 100, //82 + 100, //83 + 100, //84 + 100, //85 + 100, //86 + 100, //87 + 100, //88 + 100, //89 + 100, //90 + 100, //91 + 100, //92 + 100, //93 + 100, //94 + 100, //95 + 100, //96 + 100, //97 + 100, //98 + 100, //99 + 100, //100 + 100, //101 + 100, //102 + 100, //103 + 100, //104 + 100, //105 + 100, //106 + 100, //107 + 100, //108 + 100, //109 + 100, //110 + 100, //111 + 100, //112 + 100, //113 + 100, //114 + 100, //115 + 100, //116 + 100, //117 + 100, //118 + 100, //119 + 100, //120 + 100, //121 + 100, //122 + 100, //123 + 100, //124 + 100, //125 + 100, //126 + 100, //127 + 100, + } + }, //RF_CHAN_14 + }, + + //NV_TABLE_TPC_PDADC_OFFSETS + { + 98, // RF_CHAN_1 + 101, // RF_CHAN_2 + 101, // RF_CHAN_3 + 100, // RF_CHAN_4 + 98, // RF_CHAN_5 + 97, // RF_CHAN_6 + 94, // RF_CHAN_7 + 94, // RF_CHAN_8 + 92, // RF_CHAN_9 + 90, // RF_CHAN_10 + 94, // RF_CHAN_11 + 95, // RF_CHAN_12 + 97, // RF_CHAN_13 + 104, // RF_CHAN_14 + 100, // RF_CHAN_240 + 100, // RF_CHAN_244 + 100, // RF_CHAN_248 + 100, // RF_CHAN_252 + 100, // RF_CHAN_208 + 100, // RF_CHAN_212 + 100, // RF_CHAN_216 + 100, // RF_CHAN_36 + 100, // RF_CHAN_40 + 100, // RF_CHAN_44 + 100, // RF_CHAN_48 + 100, // RF_CHAN_52 + 100, // RF_CHAN_56 + 100, // RF_CHAN_60 + 100, // RF_CHAN_64 + 100, // RF_CHAN_100 + 100, // RF_CHAN_104 + 100, // RF_CHAN_108 + 100, // RF_CHAN_112 + 100, // RF_CHAN_116 + 100, // RF_CHAN_120 + 100, // RF_CHAN_124 + 100, // RF_CHAN_128 + 100, // RF_CHAN_132 + 100, // RF_CHAN_136 + 100, // RF_CHAN_140 + 100, // RF_CHAN_149 + 100, // RF_CHAN_153 + 100, // RF_CHAN_157 + 100, // RF_CHAN_161 + 100, // RF_CHAN_165 + //CHANNEL BONDED CHANNELS + 100, // RF_CHAN_BOND_3 + 100, // RF_CHAN_BOND_4 + 100, // RF_CHAN_BOND_5 + 100, // RF_CHAN_BOND_6 + 100, // RF_CHAN_BOND_7 + 100, // RF_CHAN_BOND_8 + 100, // RF_CHAN_BOND_9 + 100, // RF_CHAN_BOND_10 + 100, // RF_CHAN_BOND_11 + 100, // RF_CHAN_BOND_242 + 100, // RF_CHAN_BOND_246 + 100, // RF_CHAN_BOND_250 + 100, // RF_CHAN_BOND_210 + 100, // RF_CHAN_BOND_214 + 100, // RF_CHAN_BOND_38 + 100, // RF_CHAN_BOND_42 + 100, // RF_CHAN_BOND_46 + 100, // RF_CHAN_BOND_50 + 100, // RF_CHAN_BOND_54 + 100, // RF_CHAN_BOND_58 + 100, // RF_CHAN_BOND_62 + 100, // RF_CHAN_BOND_102 + 100, // RF_CHAN_BOND_106 + 100, // RF_CHAN_BOND_110 + 100, // RF_CHAN_BOND_114 + 100, // RF_CHAN_BOND_118 + 100, // RF_CHAN_BOND_122 + 100, // RF_CHAN_BOND_126 + 100, // RF_CHAN_BOND_130 + 100, // RF_CHAN_BOND_134 + 100, // RF_CHAN_BOND_138 + 100, // RF_CHAN_BOND_151 + 100, // RF_CHAN_BOND_155 + 100, // RF_CHAN_BOND_159 + 100, // RF_CHAN_BOND_163 + }, + + //NV_TABLE_VIRTUAL_RATE + // typedef tANI_S16 tPowerdBm; + //typedef tPowerdBm tRateGroupPwr[NUM_HAL_PHY_RATES]; + //tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; + { + // 2.4G RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G Low RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G Middle RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 5G High RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + }, + // 4.9G RF Subband + { + //802.11b Rates + {100}, // HAL_PHY_VRATE_11A_54_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_65_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_72_2_MBPS, + {100}, // HAL_PHY_VRATE_MCS_1NSS_CB_135_MBPS + {100}, // HAL_PHY_VRATE_MCS_1NSS_MM_SG_CB_150_MBPS, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + {100}, // RESERVED, + } + }, + +#if 0 //FIXME_PRIMA + //NV_TABLE_CAL_MEMORY + { + 0x7FFF, // tANI_U16 process_monitor; + 0x00, // tANI_U8 hdet_cal_code; + 0x00, // tANI_U8 rxfe_gm_2; + + 0x00, // tANI_U8 tx_bbf_rtune; + 0x00, // tANI_U8 pa_rtune_reg; + 0x00, // tANI_U8 rt_code; + 0x00, // tANI_U8 bias_rtune; + + 0x00, // tANI_U8 bb_bw1; + 0x00, // tANI_U8 bb_bw2; + { 0x00, 0x00 }, // tANI_U8 reserved[2]; + + 0x00, // tANI_U8 bb_bw3; + 0x00, // tANI_U8 bb_bw4; + 0x00, // tANI_U8 bb_bw5; + 0x00, // tANI_U8 bb_bw6; + + 0x7FFF, // tANI_U16 rcMeasured; + 0x00, // tANI_U8 tx_bbf_ct; + 0x00, // tANI_U8 tx_bbf_ctr; + + 0x00, // tANI_U8 csh_maxgain_reg; + 0x00, // tANI_U8 csh_0db_reg; + 0x00, // tANI_U8 csh_m3db_reg; + 0x00, // tANI_U8 csh_m6db_reg; + + 0x00, // tANI_U8 cff_0db_reg; + 0x00, // tANI_U8 cff_m3db_reg; + 0x00, // tANI_U8 cff_m6db_reg; + 0x00, // tANI_U8 rxfe_gpio_ctl_1; + + 0x00, // tANI_U8 mix_bal_cnt_2; + 0x00, // tANI_S8 rxfe_lna_highgain_bias_ctl_delta; + 0x00, // tANI_U8 rxfe_lna_load_ctune; + 0x00, // tANI_U8 rxfe_lna_ngm_rtune; + + 0x00, // tANI_U8 rx_im2_i_cfg0; + 0x00, // tANI_U8 rx_im2_i_cfg1; + 0x00, // tANI_U8 rx_im2_q_cfg0; + 0x00, // tANI_U8 rx_im2_q_cfg1; + + 0x00, // tANI_U8 pll_vfc_reg3_b0; + 0x00, // tANI_U8 pll_vfc_reg3_b1; + 0x00, // tANI_U8 pll_vfc_reg3_b2; + 0x00, // tANI_U8 pll_vfc_reg3_b3; + + 0x7FFF, // tANI_U16 tempStart; + 0x7FFF, // tANI_U16 tempFinish; + + { //txLoCorrections + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x00, 0x00 }, // TX_GAIN_STEP_0 + { 0x00, 0x00 }, // TX_GAIN_STEP_1 + { 0x00, 0x00 }, // TX_GAIN_STEP_2 + { 0x00, 0x00 }, // TX_GAIN_STEP_3 + { 0x00, 0x00 }, // TX_GAIN_STEP_4 + { 0x00, 0x00 }, // TX_GAIN_STEP_5 + { 0x00, 0x00 }, // TX_GAIN_STEP_6 + { 0x00, 0x00 }, // TX_GAIN_STEP_7 + { 0x00, 0x00 }, // TX_GAIN_STEP_8 + { 0x00, 0x00 }, // TX_GAIN_STEP_9 + { 0x00, 0x00 }, // TX_GAIN_STEP_10 + { 0x00, 0x00 }, // TX_GAIN_STEP_11 + { 0x00, 0x00 }, // TX_GAIN_STEP_12 + { 0x00, 0x00 }, // TX_GAIN_STEP_13 + { 0x00, 0x00 }, // TX_GAIN_STEP_14 + { 0x00, 0x00 } // TX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // tTxLoCorrections txLoValues; + + { //sTxIQChannel + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // TX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // TX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // sTxIQChannel txIqValues; + + { //sRxIQChannel + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_1 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_2 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_3 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_4 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_5 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_6 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_7 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_8 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_9 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_10 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_11 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_12 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + }, //RF_CHAN_13 + { + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_0 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_1 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_2 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_3 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_4 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_5 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_6 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_7 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_8 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_9 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_10 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_11 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_12 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_13 + { 0x0000, 0x0000, 0x0000 }, // RX_GAIN_STEP_14 + { 0x0000, 0x0000, 0x0000 } // RX_GAIN_STEP_15 + } //RF_CHAN_14 + }, // sRxIQChannel rxIqValues; + + { // tTpcConfig clpcData[MAX_TPC_CHANNELS] + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_1 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_2 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_3 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_4 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_5 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_6 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_7 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_8 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_9 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_10 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_11 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_12 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + }, // RF_CHAN_13 + { + { + { + { 0x00, 0x00 }, //CAL_POINT_0 + { 0x00, 0x00 }, //CAL_POINT_1 + { 0x00, 0x00 }, //CAL_POINT_2 + { 0x00, 0x00 }, //CAL_POINT_3 + { 0x00, 0x00 }, //CAL_POINT_4 + { 0x00, 0x00 }, //CAL_POINT_5 + { 0x00, 0x00 }, //CAL_POINT_6 + { 0x00, 0x00 } //CAL_POINT_7 + } // PHY_TX_CHAIN_0 + } // empirical + } // RF_CHAN_14 + }, // tTpcConfig clpcData[MAX_TPC_CHANNELS]; + + { + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_1: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_2: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_3: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_4: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_5: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_6: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_7: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_8: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_9: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_10: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_11: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_12: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } }, // RF_CHAN_13: pdadc_offset, reserved[2] + { 0x0000, { 0x00, 0x00 } } // RF_CHAN_14: pdadc_offset, reserved[2] + } // tTpcParams clpcParams[MAX_TPC_CHANNELS]; + + }, //NV_TABLE_CAL_MEMORY +#endif + //NV_TABLE_FW_CONFIG + { + 0, //skuID + 0, //tpcMode2G + 0, //tpcMode5G + 0, //reserved1 + + 0, //xPA2G + 0, //xPA5G; + 0, //paPolarityTx; + 0, //paPolarityRx; + + 0, //xLNA2G; + 0, //xLNA5G; + 0, //xCoupler2G; + 0, //xCoupler5G; + + 0, //xPdet2G; + 0, //xPdet5G; + 0, //enableDPD2G; + 1, //enableDPD5G; + + 1, //pdadcSelect2G; + 1, //pdadcSelect5GLow; + 1, //pdadcSelect5GMid; + 1, //pdadcSelect5GHigh; + + 0, //reserved2 + 0, //reserved3 + 0, //reserved4 + }, + + + //NV_TABLE_RSSI_CHANNEL_OFFSETS + { + //PHY_RX_CHAIN_0 + { + //bRssiOffset + {300}, // apply to all channles + + //gnRssiOffset + {300} // apply to all channles + }, + //rsvd + { + //bRssiOffset + {0}, // apply to all channles + + //gnRssiOffset + {0} // apply to all channles + } + }, + + //NV_TABLE_HW_CAL_VALUES + { + 0x0, //validBmap + { + 1400, //psSlpTimeOvrHd2G; + 1400, //psSlpTimeOvrHd5G; + + 1600, //psSlpTimeOvrHdxLNA5G; + 0, //nv_TxBBFSel9MHz + 0, //hwParam1 + 0, //hwParam2 + + 0x1B, //custom_tcxo_reg8 + 0xFF, //custom_tcxo_reg9 + + 0, //hwParam3; + 0, //hwParam4; + 0, //hwParam5; + 0, //hwParam6; + 0, //hwParam7; + 0, //hwParam8; + 0, //hwParam9; + 0, //hwParam10; + 0, //hwParam11; + } + }, + + + //NV_TABLE_ANTENNA_PATH_LOSS + { + 280, // RF_CHAN_1 + 270, // RF_CHAN_2 + 270, // RF_CHAN_3 + 270, // RF_CHAN_4 + 270, // RF_CHAN_5 + 270, // RF_CHAN_6 + 280, // RF_CHAN_7 + 280, // RF_CHAN_8 + 290, // RF_CHAN_9 + 300, // RF_CHAN_10 + 300, // RF_CHAN_11 + 310, // RF_CHAN_12 + 310, // RF_CHAN_13 + 310, // RF_CHAN_14 + 280, // RF_CHAN_240 + 280, // RF_CHAN_244 + 280, // RF_CHAN_248 + 280, // RF_CHAN_252 + 280, // RF_CHAN_208 + 280, // RF_CHAN_212 + 280, // RF_CHAN_216 + 280, // RF_CHAN_36 + 280, // RF_CHAN_40 + 280, // RF_CHAN_44 + 280, // RF_CHAN_48 + 280, // RF_CHAN_52 + 280, // RF_CHAN_56 + 280, // RF_CHAN_60 + 280, // RF_CHAN_64 + 280, // RF_CHAN_100 + 280, // RF_CHAN_104 + 280, // RF_CHAN_108 + 280, // RF_CHAN_112 + 280, // RF_CHAN_116 + 280, // RF_CHAN_120 + 280, // RF_CHAN_124 + 280, // RF_CHAN_128 + 280, // RF_CHAN_132 + 280, // RF_CHAN_136 + 280, // RF_CHAN_140 + 280, // RF_CHAN_149 + 280, // RF_CHAN_153 + 280, // RF_CHAN_157 + 280, // RF_CHAN_161 + 280, // RF_CHAN_165 + //CHANNEL BONDED CHANNELS + 280, // RF_CHAN_BOND_3 + 280, // RF_CHAN_BOND_4 + 280, // RF_CHAN_BOND_5 + 280, // RF_CHAN_BOND_6 + 280, // RF_CHAN_BOND_7 + 280, // RF_CHAN_BOND_8 + 280, // RF_CHAN_BOND_9 + 280, // RF_CHAN_BOND_10 + 280, // RF_CHAN_BOND_11 + 280, // RF_CHAN_BOND_242 + 280, // RF_CHAN_BOND_246 + 280, // RF_CHAN_BOND_250 + 280, // RF_CHAN_BOND_210 + 280, // RF_CHAN_BOND_214 + 280, // RF_CHAN_BOND_38 + 280, // RF_CHAN_BOND_42 + 280, // RF_CHAN_BOND_46 + 280, // RF_CHAN_BOND_50 + 280, // RF_CHAN_BOND_54 + 280, // RF_CHAN_BOND_58 + 280, // RF_CHAN_BOND_62 + 280, // RF_CHAN_BOND_102 + 280, // RF_CHAN_BOND_106 + 280, // RF_CHAN_BOND_110 + 280, // RF_CHAN_BOND_114 + 280, // RF_CHAN_BOND_118 + 280, // RF_CHAN_BOND_122 + 280, // RF_CHAN_BOND_126 + 280, // RF_CHAN_BOND_130 + 280, // RF_CHAN_BOND_134 + 280, // RF_CHAN_BOND_138 + 280, // RF_CHAN_BOND_151 + 280, // RF_CHAN_BOND_155 + 280, // RF_CHAN_BOND_159 + 280, // RF_CHAN_BOND_163 + }, + + //NV_TABLE_PACKET_TYPE_POWER_LIMITS + { + { 2150 }, // applied to all channels, MODE_802_11B + { 1850 }, // applied to all channels,MODE_802_11AG + { 1750 } // applied to all channels,MODE_802_11N + }, + + //NV_TABLE_OFDM_CMD_PWR_OFFSET + { + 0, 0 + }, + + //NV_TABLE_TX_BB_FILTER_MODE + { + 0 + } + + } // tables +}; + +#endif + + diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c new file mode 100644 index 000000000000..a26f81b875db --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda.c @@ -0,0 +1,23524 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*=========================================================================== + W L A N _ Q C T _ WDA . C + OVERVIEW: + This software unit holds the implementation of the WLAN Transport Layer. + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + DEPENDENCIES: + Are listed for each API below. + +===========================================================================*/ +/*=========================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + $Header$$DateTime$$Author$ + + when who what, where, why +---------- --- ------------------------------------------------- +10/05/2011 haparna Adding support for Keep Alive Feature +2010-12-30 smiryala UMAC convergence changes +2010-08-19 adwivedi WLAN DAL AL(WDA) layer for Prima +===========================================================================*/ +#include "vos_mq.h" +#include "vos_api.h" +#include "vos_packet.h" +#include "vos_nvitem.h" +#include "sirApi.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_pal_device.h" +#include "wlan_qct_wda.h" +#include "wlan_qct_wda_msg.h" +#include "wlan_qct_wdi_cfg.h" +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_hal_cfg.h" +/**********************/ +#include "wniApi.h" +#include "cfgApi.h" +#include "limApi.h" +#include "wlan_qct_tl.h" +#include "wlan_qct_tli_ba.h" +#include "limUtils.h" +#include "btcApi.h" +#include "vos_sched.h" +#include "pttMsgApi.h" +#include "wlan_qct_sys.h" +/* Used MACRO's */ +/* Get WDA context from vOSS module */ +#define WDA_2_4_GHZ_MAX_FREQ 3000 +#define VOS_GET_WDA_CTXT(a) vos_get_context(VOS_MODULE_ID_WDA, a) +#define VOS_GET_MAC_CTXT(a) vos_get_context(VOS_MODULE_ID_PE, a) +#define WDA_BA_TX_FRM_THRESHOLD (5) +#define CONVERT_WDI2SIR_STATUS(x) \ + ((WDI_STATUS_SUCCESS != (x)) ? eSIR_FAILURE : eSIR_SUCCESS) + +/* Threshold to print tx time taken in ms*/ +#define WDA_TX_TIME_THRESHOLD 1000 +/* Recover with ssr if tx timeouts continuously + * for threshold number of times. + */ +#define WDA_TX_FAILURE_RECOVERY_THRESHOLD 5 +/* BTQM flush FW dump command */ +#define WDA_TX_FW_RECOVERY_THRESHOLD 3 + +#define IS_WDI_STATUS_FAILURE(status) \ + ((WDI_STATUS_SUCCESS != (status)) && (WDI_STATUS_PENDING != (status))) +#define CONVERT_WDI2VOS_STATUS(x) \ + ((IS_WDI_STATUS_FAILURE(x)) ? VOS_STATUS_E_FAILURE : VOS_STATUS_SUCCESS) + +/* macro's for acessing TL API/data structures */ +#define WDA_TL_GET_STA_STATE(a, b, c) WLANTL_GetSTAState(a, b, c) +#define WDA_TL_GET_TX_PKTCOUNT(a, b, c, d) WLANTL_GetTxPktCount(a, b, c, d) +#define WDA_GET_BA_TXFLAG(a, b, c) \ + (((a)->wdaStaInfo[(b)].ucUseBaBitmap) & (1 << (c))) + +#define WDA_SET_BA_TXFLAG(a, b, c) \ + (((a)->wdaStaInfo[(b)].ucUseBaBitmap) |= (1 << (c))) + +#define WDA_CLEAR_BA_TXFLAG(a, b, c) \ + (((a)->wdaStaInfo[b].ucUseBaBitmap) &= ~(1 << c)) +#define WDA_TL_BA_SESSION_ADD(a, b, c, d, e, f, g) \ + WLANTL_BaSessionAdd(a, b, c, d, e, f, g) +/* timer related Macros */ +#define WDA_CREATE_TIMER(a, b, c, d, e, f, g) \ + tx_timer_create(a, b, c, d, e, f, g) +#define WDA_START_TIMER(a) tx_timer_activate(a) +#define WDA_STOP_TIMER(a) tx_timer_deactivate(a) +#define WDA_DESTROY_TIMER(a) tx_timer_delete(a) +#define WDA_WDI_START_TIMEOUT (WDI_RESPONSE_TIMEOUT + 5000) + +#define WDA_LAST_POLLED_THRESHOLD(a, curSta, tid) \ + ((a)->wdaStaInfo[curSta].framesTxed[tid] + WDA_BA_TX_FRM_THRESHOLD) +#define WDA_BA_MAX_WINSIZE (64) +#define WDA_INVALID_KEY_INDEX 0xFF +#define WDA_NUM_PWR_SAVE_CFG 11 +#define WDA_TX_COMPLETE_TIME_OUT_VALUE 1000 +#define WDA_TRAFFIC_STATS_TIME_OUT_VALUE 1000 + +#define WDA_MAX_RETRIES_TILL_RING_EMPTY 1000 /* MAX 10000 msec = 10 seconds wait */ + +#define WDA_WAIT_MSEC_TILL_RING_EMPTY 10 /* 10 msec wait per cycle */ +#define WDA_IS_NULL_MAC_ADDRESS(mac_addr) \ + ((mac_addr[0] == 0x00) && (mac_addr[1] == 0x00) && (mac_addr[2] == 0x00) &&\ + (mac_addr[3] == 0x00) && (mac_addr[4] == 0x00) && (mac_addr[5] == 0x00)) + +#define WDA_MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define WDA_MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define WDA_DUMPCMD_WAIT_TIMEOUT 10000 +#define WDA_BA_MAX_RETRY_THRESHOLD 10 +#define WDA_BA_RETRY_TIME 300000 /* Time is in msec, equal to 5 mins */ + +/* extern declarations */ +extern void vos_WDAComplete_cback(v_PVOID_t pVosContext); +extern wpt_uint8 WDI_GetActiveSessionsCount (void *pWDICtx, wpt_macAddr macBSSID, wpt_boolean skipBSSID); + +/* forward declarations */ +void WDA_SendMsg(tWDA_CbContext *pWDA, tANI_U16 msgType, + void *pBodyptr, tANI_U32 bodyVal) ; +VOS_STATUS WDA_prepareConfigTLV(v_PVOID_t pVosContext, + WDI_StartReqParamsType *wdiStartParams ) ; +VOS_STATUS WDA_wdiCompleteCB(v_PVOID_t pVosContext) ; +VOS_STATUS WDA_ProcessSetTxPerTrackingReq(tWDA_CbContext *pWDA, tSirTxPerTrackingParam *pTxPerTrackingParams); + +extern v_BOOL_t sys_validateStaConfig( void *pImage, unsigned long cbFile, + void **ppStaConfig, v_SIZE_t *pcbStaConfig ) ; +void processCfgDownloadReq(tpAniSirGlobal pMac) ; +void WDA_UpdateBSSParams(tWDA_CbContext *pWDA, + WDI_ConfigBSSReqInfoType *wdiBssParams, tAddBssParams *wdaBssParams) ; +void WDA_UpdateSTAParams(tWDA_CbContext *pWDA, + WDI_ConfigStaReqInfoType *wdiStaParams, tAddStaParams *wdaStaParams) ; +void WDA_lowLevelIndCallback(WDI_LowLevelIndType *wdiLowLevelInd, + void* pUserData ) ; +static VOS_STATUS wdaCreateTimers(tWDA_CbContext *pWDA) ; +static VOS_STATUS wdaDestroyTimers(tWDA_CbContext *pWDA); +bool WDA_AllowAddBA(tpAniSirGlobal pMAc, tANI_U8 staId, tANI_U8 tid); +void WDA_BaCheckActivity(tWDA_CbContext *pWDA) ; +void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA); +void WDA_HALDumpCmdCallback(WDI_HALDumpCmdRspParamsType *wdiRspParams, void* pUserData); +#ifdef WLAN_FEATURE_VOWIFI_11R +VOS_STATUS WDA_ProcessAggrAddTSReq(tWDA_CbContext *pWDA, tAggrAddTsParams *pAggrAddTsReqParams); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +void WDA_TimerHandler(v_VOID_t *pWDA, tANI_U32 timerInfo) ; +void WDA_ProcessTxCompleteTimeOutInd(tWDA_CbContext* pContext) ; +VOS_STATUS WDA_ResumeDataTx(tWDA_CbContext *pWDA); +#ifdef FEATURE_WLAN_SCAN_PNO +static VOS_STATUS WDA_ProcessSetPrefNetworkReq(tWDA_CbContext *pWDA, tSirPNOScanReq *pPNOScanReqParams); +static VOS_STATUS WDA_ProcessSetRssiFilterReq(tWDA_CbContext *pWDA, tSirSetRSSIFilterReq* pRssiFilterParams); +static VOS_STATUS WDA_ProcessUpdateScanParams(tWDA_CbContext *pWDA, tSirUpdateScanParams *pUpdateScanParams); +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +VOS_STATUS WDA_ProcessRoamScanOffloadReq(tWDA_CbContext *pWDA,tSirRoamOffloadScanReq *pRoamOffloadScanReqParams); +VOS_STATUS WDA_ProcessPERRoamScanOffloadReq(tWDA_CbContext *pWDA, + tSirPERRoamOffloadScanReq *pPERRoamOffloadScanReqParams); +void WDA_RoamOffloadScanReqCallback(WDI_Status status, void* pUserData); +void WDA_PERRoamOffloadScanReqCallback(WDI_Status status, void* pUserData); +void WDA_PERRoamTriggerScanReqCallback(WDI_Status status, void* pUserData); +void WDA_ConvertSirAuthToWDIAuth(WDI_AuthType *AuthType, v_U8_t csrAuthType); +void WDA_ConvertSirEncToWDIEnc(WDI_EdType *EncrType, v_U8_t csrEncrType); +#endif +#ifdef WLAN_FEATURE_PACKET_FILTERING +static VOS_STATUS WDA_Process8023MulticastListReq ( + tWDA_CbContext *pWDA, + tSirRcvFltMcAddrList *pRcvFltMcAddrLis + ); +static VOS_STATUS WDA_ProcessReceiveFilterSetFilterReq ( + tWDA_CbContext *pWDA, + tSirRcvPktFilterCfgType *pRcvPktFilterCfg + ); +static VOS_STATUS WDA_ProcessPacketFilterMatchCountReq ( + tWDA_CbContext *pWDA, + tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp + ); +static VOS_STATUS WDA_ProcessReceiveFilterClearFilterReq ( + tWDA_CbContext *pWDA, + tSirRcvFltPktClearParam *pRcvFltPktClearParam + ); +#endif // WLAN_FEATURE_PACKET_FILTERING +VOS_STATUS WDA_ProcessSetPowerParamsReq(tWDA_CbContext *pWDA, tSirSetPowerParamsReq *pPowerParams); +static VOS_STATUS WDA_ProcessTxControlInd(tWDA_CbContext *pWDA, + tpTxControlParams pTxCtrlParam); +VOS_STATUS WDA_GetWepKeysFromCfg( tWDA_CbContext *pWDA, + v_U8_t *pDefaultKeyId, + v_U8_t *pNumKeys, + WDI_KeysType *pWdiKeys ); + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +static VOS_STATUS WDA_ProcessGTKOffloadReq(tWDA_CbContext *pWDA, tpSirGtkOffloadParams pGtkOffloadParams); +static VOS_STATUS WDA_ProcessGTKOffloadGetInfoReq(tWDA_CbContext *pWDA, tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +v_VOID_t WDA_ProcessGetBcnMissRateReq(tWDA_CbContext *pWDA, + tSirBcnMissRateReq *pData); + +VOS_STATUS WDA_ProcessSetTmLevelReq(tWDA_CbContext *pWDA, + tAniSetTmLevelReq *setTmLevelReq); +#ifdef WLAN_FEATURE_11AC +VOS_STATUS WDA_ProcessUpdateOpMode(tWDA_CbContext *pWDA, + tUpdateVHTOpMode *pData); +#endif + +#ifdef FEATURE_WLAN_LPHB +VOS_STATUS WDA_ProcessLPHBConfReq(tWDA_CbContext *pWDA, + tSirLPHBReq *pData); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef WLAN_FEATURE_RMC +void WDA_IBSSPeerInfoRequestHandler(v_PVOID_t pVosContext, + v_PVOID_t pData); +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_EXTSCAN +VOS_STATUS WDA_ProcessEXTScanStartReq(tWDA_CbContext *pWDA, + tSirEXTScanStartReqParams *wdaRequest); +VOS_STATUS WDA_ProcessEXTScanStopReq(tWDA_CbContext *pWDA, + tSirEXTScanStopReqParams *wdaRequest); +VOS_STATUS WDA_ProcessEXTScanGetCachedResultsReq(tWDA_CbContext *pWDA, + tSirEXTScanGetCachedResultsReqParams *wdaRequest); +VOS_STATUS WDA_ProcessEXTScanGetCapabilitiesReq(tWDA_CbContext *pWDA, + tSirGetEXTScanCapabilitiesReqParams *wdaRequest); +VOS_STATUS WDA_ProcessEXTScanSetBSSIDHotlistReq(tWDA_CbContext *pWDA, + tSirEXTScanSetBssidHotListReqParams *wdaRequest); +VOS_STATUS WDA_ProcessEXTScanResetBSSIDHotlistReq(tWDA_CbContext *pWDA, + tSirEXTScanResetBssidHotlistReqParams *wdaRequest); +VOS_STATUS WDA_ProcessHighPriorityDataInfoInd(tWDA_CbContext *pWDA, + tSirHighPriorityDataInfoInd *wdaRequest); +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +VOS_STATUS WDA_ProcessLLStatsSetReq(tWDA_CbContext *pWDA, + tSirLLStatsSetReq *wdaRequest); + +VOS_STATUS WDA_ProcessLLStatsGetReq(tWDA_CbContext *pWDA, + tSirLLStatsGetReq *wdaRequest); + +VOS_STATUS WDA_ProcessLLStatsClearReq(tWDA_CbContext *pWDA, + tSirLLStatsClearReq *wdaRequest); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +v_VOID_t WDA_ProcessFWStatsGetReq(tWDA_CbContext *pWDA, + tSirFWStatsGetReq *wdaRequest); + +VOS_STATUS WDA_ProcessEncryptMsgReq(tWDA_CbContext *pWDA, + u8 *wdaRequest); +VOS_STATUS +WDA_ProcessSetRtsCtsHTVhtInd(tWDA_CbContext *pWDA, + tANI_U32 val); + +VOS_STATUS +WDA_ProcessFwrMemDumpReq(tWDA_CbContext *pWDA, + tAniFwrDumpReq* pFwrMemDumpReq); + +VOS_STATUS WDA_ProcessMonStartReq( tWDA_CbContext *pWDA, void* wdaRequest); +VOS_STATUS WDA_ProcessMonStopReq( tWDA_CbContext *pWDA, void* wdaRequest); +VOS_STATUS WDA_ProcessEnableDisableCAEventInd(tWDA_CbContext *pWDA, tANI_U8 val); + +VOS_STATUS WDA_ProcessWifiConfigReq(tWDA_CbContext *pWDA, + tSetWifiConfigParams *pwdaWificonfig); + +VOS_STATUS WDA_ProcessStartOemDataReqIndNew(tWDA_CbContext *pWDA, + tOemDataReqNewConfig *pOemDataReqNewConfig); + + +v_VOID_t WDA_ProcessAntennaDiversitySelectionReq(tWDA_CbContext *pWDA, + tSirAntennaDiversitySelectionReq *pData); + +VOS_STATUS WDA_ProcessBcnMissPenaltyCount(tWDA_CbContext *pWDA, + tModifyRoamParamsReqParams *params); +/* + * FUNCTION: WDA_ProcessNanRequest + * Process NAN request + */ +VOS_STATUS WDA_ProcessNanRequest(tWDA_CbContext *pWDA, + tNanRequest *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + WDI_NanRequestType *wdiRequest = NULL; + size_t wdiReqLength = sizeof(WDI_NanRequestType) + - sizeof(wdiRequest->request_data) + + wdaRequest->request_data_len; + + wdiRequest = (WDI_NanRequestType *)vos_mem_malloc(wdiReqLength); + + if (NULL == wdiRequest) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure, size : %zu", __func__, + wdiReqLength); + vos_mem_free(wdaRequest); + return VOS_STATUS_E_NOMEM; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA: Process Nan Request length: %zu", wdiReqLength); + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure for tWDA_ReqParams", __func__); + VOS_ASSERT(0); + vos_mem_free(wdaRequest); + vos_mem_free(wdiRequest); + return VOS_STATUS_E_NOMEM; + } + + wdiRequest->request_data_len = wdaRequest->request_data_len; + + vos_mem_copy( wdiRequest->request_data, + wdaRequest->request_data, + wdaRequest->request_data_len); + + vos_mem_free(wdaRequest); + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = NULL; + pWdaParams->wdaWdiApiMsgParam = wdiRequest; + + status = WDI_NanRequest(wdiRequest, pWdaParams); + + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + } + + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/** + * wda_state_info_dump() - prints state information of wda layer + */ +static void wda_state_info_dump(void) +{ + v_CONTEXT_t vos_ctx_ptr = NULL; + tWDA_CbContext *wda = NULL ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + /* Get the Global VOSS Context */ + vos_ctx_ptr = vos_get_global_context(VOS_MODULE_ID_VOSS, NULL); + + if (NULL != vos_ctx_ptr) + wda = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, + vos_ctx_ptr ); + else { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: Invalid Global VOSS Context", __func__); + VOS_ASSERT(0); + return; + } + + if (NULL != wda) + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "wdaState: %d linkState: %d", wda->wdaState, + wda->linkState); + else { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WDA Context", __func__); + VOS_ASSERT(0); + } +} + +/** + * wda_register_debug_callback() - registration function for wda layer + * to print wda state information + */ +static void wda_register_debug_callback(void) +{ + vos_register_debug_callback(VOS_MODULE_ID_WDA, &wda_state_info_dump); +} + +/* + * FUNCTION: WDA_open + * Allocate the WDA context + */ +VOS_STATUS WDA_open(v_PVOID_t pVosContext, v_PVOID_t devHandle, + tMacOpenParameters *pMacParams ) +{ + tWDA_CbContext *wdaContext; + VOS_STATUS status; + WDI_DeviceCapabilityType wdiDevCapability = {0} ; + /* Allocate WDA context */ + status = vos_alloc_context(pVosContext, VOS_MODULE_ID_WDA, + (v_VOID_t **)&wdaContext, sizeof(tWDA_CbContext)) ; + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, "%s: Failed to " + "allocate context for WDA - status = %d",__func__, status); + return VOS_STATUS_E_NOMEM; + } + /*__asm int 3;*/ + vos_mem_zero(wdaContext,sizeof(tWDA_CbContext)); + + /* Initialize data structures */ + wdaContext->pVosContext = pVosContext; + wdaContext->wdaState = WDA_INIT_STATE; + wdaContext->uTxFlowMask = WDA_TXFLOWMASK; + vos_lock_init(&wdaContext->mgmt_pkt_lock); + + /* Initialize WDA-WDI synchronization event */ + status = vos_event_init(&wdaContext->wdaWdiEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDI Sync Event init failed - status = %d", status); + goto error; + } + /* Init Frame transfer event */ + status = vos_event_init(&wdaContext->txFrameEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Mgmt Frame Event init failed - status = %d", status); + goto error; + } + status = vos_event_init(&wdaContext->suspendDataTxEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS suspend data tx Event init failed - status = %d", status); + goto error; + } + status = vos_event_init(&wdaContext->waitOnWdiIndicationCallBack); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS wait On Wdi Ind Event init failed - status = %d", status); + goto error; + } + vos_trace_setLevel(VOS_MODULE_ID_WDA,VOS_TRACE_LEVEL_ERROR); + wdaContext->driverMode = pMacParams->driverType; + if(WDI_STATUS_SUCCESS != WDI_Init(devHandle, &wdaContext->pWdiContext, + &wdiDevCapability, pMacParams->driverType)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDI Init failed" ); + goto error; + } + else + { + pMacParams->maxStation = wdiDevCapability.ucMaxSTASupported ; + pMacParams->maxBssId = wdiDevCapability.ucMaxBSSSupported; + pMacParams->frameTransRequired = wdiDevCapability.bFrameXtlSupported; + /* update max STA in WDA used for BA */ + wdaContext->wdaMaxSta = pMacParams->maxStation; + /* store the frameTransRequired flag in wdaContext, to send this to HAL + * in WDA_Start + */ + wdaContext->frameTransRequired = wdiDevCapability.bFrameXtlSupported; + } + + wda_register_debug_callback(); + + return status; + +error: + vos_free_context(pVosContext, VOS_MODULE_ID_WDA, wdaContext); + return VOS_STATUS_E_FAILURE; +} + +/* + * FUNCTION: WDA_preStart + * Trigger DAL-AL to start CFG download + */ +VOS_STATUS WDA_preStart(v_PVOID_t pVosContext) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t wdaMsg = {0} ; + /* + * trigger CFG download in WDA by sending WDA_CFG_DNLD message + */ + wdaMsg.type = WNI_CFG_DNLD_REQ ; + wdaMsg.bodyptr = NULL; + wdaMsg.bodyval = 0; + /* post the message.. */ + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &wdaMsg ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vosStatus = VOS_STATUS_E_BADMSG; + } + return( vosStatus ); +} +/* + * FUNCTION: WDA_wdiStartCallback + * Once WDI_Start is finished, WDI start callback will be called by WDI + * to indicate completion of WDI_Start. + */ +void WDA_wdiStartCallback(WDI_StartRspParamsType *wdiRspParams, + void *pVosContext) +{ + tWDA_CbContext *wdaContext; + VOS_STATUS status; + if (NULL == pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: Invoked with invalid pVosContext", __func__ ); + return; + } + wdaContext = VOS_GET_WDA_CTXT(pVosContext); + if (NULL == wdaContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: Invoked with invalid wdaContext", __func__ ); + return; + } + if (WDI_STATUS_SUCCESS != wdiRspParams->wdiStatus) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: WDI_Start() failure reported", __func__ ); + } + else + { + wdaContext->wdaState = WDA_START_STATE; + } + /* extract and save version information from the Start Response */ + wdaContext->wcnssWlanCompiledVersion.major = + wdiRspParams->wlanCompiledVersion.major; + wdaContext->wcnssWlanCompiledVersion.minor = + wdiRspParams->wlanCompiledVersion.minor; + wdaContext->wcnssWlanCompiledVersion.version = + wdiRspParams->wlanCompiledVersion.version; + wdaContext->wcnssWlanCompiledVersion.revision = + wdiRspParams->wlanCompiledVersion.revision; + wdaContext->wcnssWlanReportedVersion.major = + wdiRspParams->wlanReportedVersion.major; + wdaContext->wcnssWlanReportedVersion.minor = + wdiRspParams->wlanReportedVersion.minor; + wdaContext->wcnssWlanReportedVersion.version = + wdiRspParams->wlanReportedVersion.version; + wdaContext->wcnssWlanReportedVersion.revision = + wdiRspParams->wlanReportedVersion.revision; + wpalMemoryCopy(wdaContext->wcnssSoftwareVersionString, + wdiRspParams->wcnssSoftwareVersion, + sizeof(wdaContext->wcnssSoftwareVersionString)); + wpalMemoryCopy(wdaContext->wcnssHardwareVersionString, + wdiRspParams->wcnssHardwareVersion, + sizeof(wdaContext->wcnssHardwareVersionString)); + /* Notify WDA_start that WDI_Start has completed */ + status = vos_event_set(&wdaContext->wdaWdiEvent); + if (VOS_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: Unable to unblock WDA_start", __func__ ); + } + return; +} + +/* + * FUNCTION: WDA_start + * Prepare TLV configuration and call WDI_Start. + */ +VOS_STATUS WDA_start(v_PVOID_t pVosContext) +{ + tWDA_CbContext *wdaContext; + VOS_STATUS status; + WDI_Status wdiStatus; + WDI_StartReqParamsType wdiStartParam; + if (NULL == pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid pVosContext", __func__ ); + return VOS_STATUS_E_FAILURE; + } + wdaContext = VOS_GET_WDA_CTXT(pVosContext); + if (NULL == wdaContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid wdaContext", __func__ ); + return VOS_STATUS_E_FAILURE; + } + /* Non-FTM mode, WDA status for START must be INIT + * FTM mode, WDA Status for START can be INIT or STOP */ + if ( (WDA_INIT_STATE != wdaContext->wdaState) && + (WDA_STOP_STATE != wdaContext->wdaState) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked from wrong state %d", + __func__, wdaContext->wdaState ); + return VOS_STATUS_E_FAILURE; + } + /* initialize the wdiStartParam. Note that we can create this on + the stack since we won't exit until WDI_Start() completes or + times out */ + vos_mem_set(&wdiStartParam, sizeof(wdiStartParam), 0); + wdiStartParam.wdiDriverType = wdaContext->driverMode; + /* prepare the config TLV for the WDI */ + status = WDA_prepareConfigTLV(pVosContext, &wdiStartParam); + if ( !VOS_IS_STATUS_SUCCESS(status) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to prepare Config TLV", __func__ ); + return VOS_STATUS_E_FAILURE; + } + /* note from here onwards if an error occurs we must + reclaim the config TLV buffer */ + wdiStartParam.wdiLowLevelIndCB = WDA_lowLevelIndCallback; + wdiStartParam.pIndUserData = (v_PVOID_t *)wdaContext; + wdiStartParam.wdiReqStatusCB = NULL; + /* initialize the WDA-WDI synchronization event */ + vos_event_reset(&wdaContext->wdaWdiEvent); + /* call WDI start */ + wdiStatus = WDI_Start(&wdiStartParam, + (WDI_StartRspCb)WDA_wdiStartCallback, + (v_VOID_t *)pVosContext); + if ( IS_WDI_STATUS_FAILURE(wdiStatus) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: WDI Start failed", __func__ ); + vos_mem_free(wdiStartParam.pConfigBuffer); + return VOS_STATUS_E_FAILURE; + } + /* wait for WDI start to invoke our callback */ + status = vos_wait_single_event( &wdaContext->wdaWdiEvent, + WDA_WDI_START_TIMEOUT ); + if ( !VOS_IS_STATUS_SUCCESS(status) ) + { + if ( VOS_STATUS_E_TIMEOUT == status ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred during WDI_Start", __func__ ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Error %d while waiting for WDI_Start", + __func__, status); + } + vos_mem_free(wdiStartParam.pConfigBuffer); + return status; + } + /* WDI_Start() has completed so we can resume our work */ + /* we no longer need the config TLV */ + vos_mem_free(wdiStartParam.pConfigBuffer); + /* if we are not in the START state then WDI_Start() failed */ + if (WDA_START_STATE != wdaContext->wdaState) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: WDI_Start() failure detected", __func__ ); + return VOS_STATUS_E_FAILURE; + } + /* FTM mode does not need to monitor BA activity */ + if ( eDRIVER_TYPE_MFG != wdaContext->driverMode ) + { + status = wdaCreateTimers(wdaContext) ; + if(VOS_STATUS_SUCCESS == status) + { + wdaContext->wdaTimersCreated = VOS_TRUE; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("wda create timers failed")); + } + } + else + { + vos_event_init(&wdaContext->ftmStopDoneEvent); + } + return status; +} + +/* + * FUNCTION: WDA_prepareConfigTLV + * Function to prepare CFG for DAL(WDA) + */ +VOS_STATUS WDA_prepareConfigTLV(v_PVOID_t pVosContext, + WDI_StartReqParamsType *wdiStartParams ) +{ + /* get pMac to acess CFG data base */ + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pVosContext); + tWDA_CbContext *wdaContext= (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + tHalCfg *tlvStruct = NULL ; + tANI_U8 *tlvStructStart = NULL ; + tANI_U32 strLength = WNI_CFG_STA_ID_LEN; + v_PVOID_t *configParam; + tANI_U32 configParamSize; + tANI_U32 *configDataValue; + WDI_WlanVersionType wcnssCompiledApiVersion; + tANI_U8 i; + + if ((NULL == pMac)||(NULL == wdaContext)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid wdaContext or pMac", __func__ ); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + configParamSize = (sizeof(tHalCfg) * QWLAN_HAL_CFG_MAX_PARAMS) + + WNI_CFG_STA_ID_LEN + + WNI_CFG_EDCA_WME_ACBK_LEN + + WNI_CFG_EDCA_WME_ACBE_LEN + + WNI_CFG_EDCA_WME_ACVI_LEN + + WNI_CFG_EDCA_WME_ACVO_LEN + + + (QWLAN_HAL_CFG_INTEGER_PARAM * sizeof(tANI_U32)); + /* malloc memory for all configs in one shot */ + configParam = vos_mem_malloc(configParamSize); + + if(NULL == configParam ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:configParam is NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(configParam, configParamSize, 0); + wdiStartParams->pConfigBuffer = configParam; + tlvStruct = (tHalCfg *)configParam; + tlvStructStart = (tANI_U8 *)configParam; + /* TODO: Remove Later */ + /* QWLAN_HAL_CFG_STA_ID */ + tlvStruct->type = QWLAN_HAL_CFG_STA_ID; + configDataValue = (tANI_U32*)((tANI_U8 *) tlvStruct + sizeof(tHalCfg)); + if(wlan_cfgGetStr(pMac, WNI_CFG_STA_ID, (tANI_U8*)configDataValue, &strLength) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_STA_ID"); + goto handle_failure; + } + tlvStruct->length = strLength ; + /* calculate the pad bytes to have the CFG in aligned format */ + tlvStruct->padBytes = ALIGNED_WORD_SIZE - + (tlvStruct->length & (ALIGNED_WORD_SIZE - 1)); + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length + tlvStruct->padBytes)) ; + /* QWLAN_HAL_CFG_CURRENT_TX_ANTENNA */ + tlvStruct->type = QWLAN_HAL_CFG_CURRENT_TX_ANTENNA; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_TX_ANTENNA, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_CURRENT_TX_ANTENNA"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_CURRENT_RX_ANTENNA */ + tlvStruct->type = QWLAN_HAL_CFG_CURRENT_RX_ANTENNA; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_RX_ANTENNA, configDataValue) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_CURRENT_RX_ANTENNA"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE */ + tlvStruct->type = QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_LOW_GAIN_OVERRIDE, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_LOW_GAIN_OVERRIDE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + + /* QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN */ + tlvStruct->type = QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_POWER_STATE_PER_CHAIN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_POWER_STATE_PER_CHAIN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_CAL_PERIOD */ + tlvStruct->type = QWLAN_HAL_CFG_CAL_PERIOD; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_CAL_PERIOD, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_CAL_PERIOD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_CAL_CONTROL */ + tlvStruct->type = QWLAN_HAL_CFG_CAL_CONTROL ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_CAL_CONTROL, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_CAL_CONTROL"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_PROXIMITY */ + tlvStruct->type = QWLAN_HAL_CFG_PROXIMITY ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_PROXIMITY, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_PROXIMITY"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_NETWORK_DENSITY */ + tlvStruct->type = QWLAN_HAL_CFG_NETWORK_DENSITY ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_NETWORK_DENSITY, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_NETWORK_DENSITY"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_MAX_MEDIUM_TIME */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_MEDIUM_TIME ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_MEDIUM_TIME, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_MEDIUM_TIME"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_MPDUS_IN_AMPDU, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_MPDUS_IN_AMPDU"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_RTS_THRESHOLD */ + tlvStruct->type = QWLAN_HAL_CFG_RTS_THRESHOLD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_RTS_THRESHOLD, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_RTS_THRESHOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_SHORT_RETRY_LIMIT */ + tlvStruct->type = QWLAN_HAL_CFG_SHORT_RETRY_LIMIT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_SHORT_RETRY_LIMIT, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_SHORT_RETRY_LIMIT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_LONG_RETRY_LIMIT */ + tlvStruct->type = QWLAN_HAL_CFG_LONG_RETRY_LIMIT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_LONG_RETRY_LIMIT, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_LONG_RETRY_LIMIT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD */ + tlvStruct->type = QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_FRAGMENTATION_THRESHOLD, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_FRAGMENTATION_THRESHOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO */ + tlvStruct->type = QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DYNAMIC_THRESHOLD_ZERO, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DYNAMIC_THRESHOLD_ZERO"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + + /* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE */ + tlvStruct->type = QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DYNAMIC_THRESHOLD_ONE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DYNAMIC_THRESHOLD_ONE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + /* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO */ + tlvStruct->type = QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DYNAMIC_THRESHOLD_TWO, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DYNAMIC_THRESHOLD_TWO"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + + /* QWLAN_HAL_CFG_FIXED_RATE */ + tlvStruct->type = QWLAN_HAL_CFG_FIXED_RATE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_FIXED_RATE, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_FIXED_RATE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + + /* QWLAN_HAL_CFG_RETRYRATE_POLICY */ + tlvStruct->type = QWLAN_HAL_CFG_RETRYRATE_POLICY ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_RETRYRATE_POLICY, configDataValue ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_RETRYRATE_POLICY"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + + /* QWLAN_HAL_CFG_RETRYRATE_SECONDARY */ + tlvStruct->type = QWLAN_HAL_CFG_RETRYRATE_SECONDARY ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_RETRYRATE_SECONDARY, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_RETRYRATE_SECONDARY"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_RETRYRATE_TERTIARY */ + tlvStruct->type = QWLAN_HAL_CFG_RETRYRATE_TERTIARY ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_RETRYRATE_TERTIARY, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_RETRYRATE_TERTIARY"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION */ + tlvStruct->type = QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_FORCE_POLICY_PROTECTION, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_FORCE_POLICY_PROTECTION"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ */ + tlvStruct->type = QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_FIXED_RATE_MULTICAST_24GHZ, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_FIXED_RATE_MULTICAST_24GHZ"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ */ + tlvStruct->type = QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_FIXED_RATE_MULTICAST_5GHZ, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_FIXED_RATE_MULTICAST_5GHZ"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + + /* QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ */ + tlvStruct->type = QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DEFAULT_RATE_INDEX_24GHZ, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DEFAULT_RATE_INDEX_24GHZ"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ */ + tlvStruct->type = QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DEFAULT_RATE_INDEX_5GHZ, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DEFAULT_RATE_INDEX_5GHZ"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_MAX_BA_SESSIONS */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_BA_SESSIONS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_BA_SESSIONS, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_BA_SESSIONS"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + + /* QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT */ + tlvStruct->type = QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER */ + tlvStruct->type = QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_PS_ENABLE_BCN_FILTER, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_PS_ENABLE_BCN_FILTER"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR */ + tlvStruct->type = QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_PS_ENABLE_RSSI_MONITOR, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_PS_ENABLE_RSSI_MONITOR"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE */ + tlvStruct->type = QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + + /* QWLAN_HAL_CFG_STATS_PERIOD */ + tlvStruct->type = QWLAN_HAL_CFG_STATS_PERIOD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_STATS_PERIOD, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_STATS_PERIOD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + /* QWLAN_HAL_CFG_CFP_MAX_DURATION */ + tlvStruct->type = QWLAN_HAL_CFG_CFP_MAX_DURATION ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, configDataValue ) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_CFP_MAX_DURATION"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_FRAME_TRANS_ENABLED */ + tlvStruct->type = QWLAN_HAL_CFG_FRAME_TRANS_ENABLED ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + vos_mem_copy(configDataValue, &wdaContext->frameTransRequired, + sizeof(tANI_U32)); + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_DTIM_PERIOD */ + tlvStruct->type = QWLAN_HAL_CFG_DTIM_PERIOD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DTIM_PERIOD, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DTIM_PERIOD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_EDCA_WMM_ACBK */ + tlvStruct->type = QWLAN_HAL_CFG_EDCA_WMM_ACBK ; + strLength = WNI_CFG_EDCA_WME_ACBK_LEN; + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetStr(pMac, WNI_CFG_EDCA_WME_ACBK, (tANI_U8 *)configDataValue, + &strLength) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_EDCA_WME_ACBK"); + goto handle_failure; + } + tlvStruct->length = strLength; + /* calculate the pad bytes to have the CFG in aligned format */ + tlvStruct->padBytes = ALIGNED_WORD_SIZE - + (tlvStruct->length & (ALIGNED_WORD_SIZE - 1)); + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length + tlvStruct->padBytes) ; + /* QWLAN_HAL_CFG_EDCA_WMM_ACBE */ + tlvStruct->type = QWLAN_HAL_CFG_EDCA_WMM_ACBE ; + strLength = WNI_CFG_EDCA_WME_ACBE_LEN; + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetStr(pMac, WNI_CFG_EDCA_WME_ACBE, (tANI_U8 *)configDataValue, + &strLength) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_EDCA_WME_ACBE"); + goto handle_failure; + } + tlvStruct->length = strLength; + /* calculate the pad bytes to have the CFG in aligned format */ + tlvStruct->padBytes = ALIGNED_WORD_SIZE - + (tlvStruct->length & (ALIGNED_WORD_SIZE - 1)); + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length + tlvStruct->padBytes) ; + /* QWLAN_HAL_CFG_EDCA_WMM_ACVI */ + tlvStruct->type = QWLAN_HAL_CFG_EDCA_WMM_ACVO ; + strLength = WNI_CFG_EDCA_WME_ACVI_LEN; + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetStr(pMac, WNI_CFG_EDCA_WME_ACVO, (tANI_U8 *)configDataValue, + &strLength) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_EDCA_WME_ACVI"); + goto handle_failure; + } + tlvStruct->length = strLength; + /* calculate the pad bytes to have the CFG in aligned format */ + tlvStruct->padBytes = ALIGNED_WORD_SIZE - + (tlvStruct->length & (ALIGNED_WORD_SIZE - 1)); + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length + tlvStruct->padBytes) ; + /* QWLAN_HAL_CFG_EDCA_WMM_ACVO */ + tlvStruct->type = QWLAN_HAL_CFG_EDCA_WMM_ACVI ; + strLength = WNI_CFG_EDCA_WME_ACVO_LEN; + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetStr(pMac, WNI_CFG_EDCA_WME_ACVI, (tANI_U8 *)configDataValue, + &strLength) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_EDCA_WME_ACVO"); + goto handle_failure; + } + tlvStruct->length = strLength; + /* calculate the pad bytes to have the CFG in aligned format */ + tlvStruct->padBytes = ALIGNED_WORD_SIZE - + (tlvStruct->length & (ALIGNED_WORD_SIZE - 1)); + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length + tlvStruct->padBytes) ; + /* QWLAN_HAL_CFG_BA_THRESHOLD_HIGH */ + tlvStruct->type = QWLAN_HAL_CFG_BA_THRESHOLD_HIGH ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_BA_THRESHOLD_HIGH, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BA_THRESHOLD_HIGH"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_MAX_BA_BUFFERS */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_BA_BUFFERS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_MAX_BA_BUFFERS, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_BA_BUFFERS"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE */ + tlvStruct->type = QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_DYNAMIC_PS_POLL_VALUE, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DYNAMIC_PS_POLL_VALUE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TELE_BCN_TRANS_LI */ + tlvStruct->type = QWLAN_HAL_CFG_TELE_BCN_TRANS_LI ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_TRANS_LI, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TELE_BCN_TRANS_LI"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS */ + tlvStruct->type = QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TELE_BCN_MAX_LI */ + tlvStruct->type = QWLAN_HAL_CFG_TELE_BCN_MAX_LI ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TELE_BCN_MAX_LI"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS */ + tlvStruct->type = QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN */ + tlvStruct->type = QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TELE_BCN_WAKEUP_EN, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TELE_BCN_WAKEUP_EN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD */ + tlvStruct->type = QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_INFRA_STA_KEEP_ALIVE_PERIOD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /*QWLAN_HAL_CFG_TX_PWR_CTRL_ENABLE*/ + tlvStruct->type = QWLAN_HAL_CFG_TX_PWR_CTRL_ENABLE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TX_PWR_CTRL_ENABLE, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TX_PWR_CTRL_ENABLE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_CLOSE_LOOP, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_CLOSE_LOOP"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* [COEX] strictly speaking, the Coex parameters are not part of the WLAN_CFG_FILE binary, + * but are from the WLAN_INI_FILE file. However, this is the only parameter download routine + * into FW, so the parameters are added here. + */ + /* [COEX] QWLAN_HAL_CFG_BTC_EXECUTION_MODE */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_EXECUTION_MODE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcExecutionMode; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* [COEX] QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcConsBtSlotsToBlockDuringDhcp; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* [COEX] QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcA2DPBtSubIntervalsDuringDhcp; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenInqBt; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenPageBt; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenConnBt; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenLeBt; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenInqWlan; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenPageWlan; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenConnWlan; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcStaticLenLeWlan; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcDynMaxLenBt; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcDynMaxLenWlan; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcMaxScoBlockPerc; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcDhcpProtOnA2dp; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.btcDhcpProtOnSco; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + for (i = 0; i < QWLAN_HAL_CFG_MWS_COEX_MAX_VICTIM; i++) + { + /* [COEX] QWLAN_HAL_CFG_MWS_COEX_VX_WAN_FREQ */ + tlvStruct->type = QWLAN_HAL_CFG_MWS_COEX_V1_WAN_FREQ + i*4; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.mwsCoexVictimWANFreq[i]; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_MWS_COEX_VX_WLAN_FREQ */ + tlvStruct->type = QWLAN_HAL_CFG_MWS_COEX_V1_WLAN_FREQ + i*4; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.mwsCoexVictimWLANFreq[i]; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_MWS_COEX_VX_CONFIG */ + tlvStruct->type = QWLAN_HAL_CFG_MWS_COEX_V1_CONFIG + i*4; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.mwsCoexVictimConfig[i]; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* [COEX] QWLAN_HAL_CFG_MWS_COEX_VX_CONFIG2 */ + tlvStruct->type = QWLAN_HAL_CFG_MWS_COEX_V1_CONFIG2 + i*4; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.mwsCoexVictimConfig2[i]; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + } + + /* [COEX] QWLAN_HAL_CFG_MWS_COEX_MODEM_BACKOFF */ + tlvStruct->type = QWLAN_HAL_CFG_MWS_COEX_MODEM_BACKOFF ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.mwsCoexModemBackoff; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + for (i = 0; i < QWLAN_HAL_CFG_MWS_COEX_MAX_CONFIG; i++) + { + /* [COEX] QWLAN_HAL_CFG_MWS_COEX_CONFIGX */ + tlvStruct->type = QWLAN_HAL_CFG_MWS_COEX_CONFIG1 + i; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.mwsCoexConfig[i]; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + } + + /* [COEX] QWLAN_HAL_CFG_SAR_POWER_BACKOFF */ + tlvStruct->type = QWLAN_HAL_CFG_SAR_POWER_BACKOFF ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = pMac->btc.btcConfig.SARPowerBackoff; + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_WCNSS_API_VERSION */ + tlvStruct->type = QWLAN_HAL_CFG_WCNSS_API_VERSION ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + WDI_GetWcnssCompiledApiVersion(&wcnssCompiledApiVersion); + *configDataValue = WLAN_HAL_CONSTRUCT_API_VERSION(wcnssCompiledApiVersion.major, + wcnssCompiledApiVersion.minor, + wcnssCompiledApiVersion.version, + wcnssCompiledApiVersion.revision); + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT */ + tlvStruct->type = QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_AP_KEEP_ALIVE_TIMEOUT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_AP_KEEP_ALIVE_TIMEOUT"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT */ + tlvStruct->type = QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_GO_KEEP_ALIVE_TIMEOUT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_GO_KEEP_ALIVE_TIMEOUT"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MC_ADDR_LIST, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_MC_ADDR_LIST"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_LPWR_IMG_TRANSITION, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_LPWR_IMG_TRANSITION"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + tlvStruct->type = QWLAN_HAL_CFG_MAX_ASSOC_LIMIT; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_STA_LIMIT, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ASSOC_STA_LIMIT"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; +#endif + + /* QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + +/* QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT */ + tlvStruct->type = QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_AP_LINK_MONITOR_TIMEOUT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_AP_LINK_MONITOR_TIMEOUT"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; +#ifdef FEATURE_WLAN_TDLS + /* QWLAN_HAL_CFG_TDLS_PUAPSD_MASK */ + tlvStruct->type = QWLAN_HAL_CFG_TDLS_PUAPSD_MASK; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TDLS_QOS_WMM_UAPSD_MASK"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE */ + tlvStruct->type = QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_BUF_STA_ENABLED, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TDLS_BUF_STA_ENABLED"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME */ + tlvStruct->type = QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_PUAPSD_INACT_TIME, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TDLS_PUAPSD_INACT_TIME"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP */ + tlvStruct->type = QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_RX_FRAME_THRESHOLD, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TDLS_RX_FRAME_THRESHOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE */ + tlvStruct->type = QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TDLS_OFF_CHANNEL_ENABLED, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TDLS_BUF_STA_ENABLED"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + +#endif + + /* QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_ADAPT_RX_DRAIN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_ADAPT_RX_DRAIN"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_FLEX_CONNECT_POWER_FACTOR */ + tlvStruct->type = QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_FLEX_CONNECT_POWER_FACTOR, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_FLEX_CONNECT_POWER_FACTOR"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)(((tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)); + + /* QWLAN_HAL_CFG_ANTENNA_DIVERSITY */ + tlvStruct->type = QWLAN_HAL_CFG_ANTENNA_DIVERSITY; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_ANTENNA_DIVESITY, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ANTENNA_DIVESITY"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT */ + tlvStruct->type = QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_GO_LINK_MONITOR_TIMEOUT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_GO_LINK_MONITOR_TIMEOUT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ATH_DISABLE */ + tlvStruct->type = QWLAN_HAL_CFG_ATH_DISABLE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ATH_DISABLE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ATH_DISABLE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_STATIC_OPP_BTC_ACTIVE_WLAN_LEN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_ACTIVE_WLAN_LEN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_ACTIVE_WLAN_LEN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_STATIC_OPP_BTC_ACTIVE_BT_LEN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_ACTIVE_BT_LEN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_ACTIVE_BT_LEN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_SAP_ACTIVE_WLAN_LEN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_BTC_ACTIVE_BT_LEN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_SAP_ACTIVE_BT_LEN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_SAP_ACTIVE_BT_LEN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ASD_PROBE_INTERVAL */ + tlvStruct->type = QWLAN_HAL_CFG_ASD_PROBE_INTERVAL ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ASD_PROBE_INTERVAL, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ASD_PROBE_INTERVAL"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD */ + tlvStruct->type = QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ASD_TRIGGER_THRESHOLD, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ASD_TRIGGER_THRESHOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD */ + tlvStruct->type = QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ASD_RTT_RSSI_HYST_THRESHOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_CTS2S_DURING_SCO, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_CTS2S_DURING_SCO"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_RA_FILTER_ENABLE */ + tlvStruct->type = QWLAN_HAL_CFG_RA_FILTER_ENABLE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_RA_FILTER_ENABLE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_RA_FILTER_ENABLE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_RA_RATE_LIMIT_INTERVAL */ + tlvStruct->type = QWLAN_HAL_CFG_RA_RATE_LIMIT_INTERVAL ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_RA_RATE_LIMIT_INTERVAL, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_RA_RATE_LIMIT_INTERVAL"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_UAPSD_CONSEC_SP, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_UAPSD_CONSEC_SP"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS */ + tlvStruct->type = QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_MAX_UAPSD_INACTIVITY_INTERVALS"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_DYNAMIC_WMMPS, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_DYNAMIC_WMMPS"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE */ + tlvStruct->type = QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BURST_MODE_BE_TXOP_VALUE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BURST_MODE_BE_TXOP_VALUE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_DYNAMIC_RA_START_RATE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_FAST_WLAN_CONN_PREF, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_FAST_WLAN_CONN_PREF"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT */ + tlvStruct->type = QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_RTSCTS_HTVHT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_RTSCTS_HTVHT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + + /* QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT */ + tlvStruct->type = QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_LINK_FAIL_TIMEOUT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_LINK_FAIL_TIMEOUT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_LINK_FAIL_TX_CNT */ + tlvStruct->type = QWLAN_HAL_CFG_LINK_FAIL_TX_CNT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_LINK_FAIL_TX_CNT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_LINK_FAIL_TX_CNT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES */ + tlvStruct->type = QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_TOGGLE_ARP_BDRATES, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_TOGGLE_ARP_BDRATES"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT */ + tlvStruct->type = QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if (wlan_cfgGetInt(pMac, WNI_CFG_OPTIMIZE_CA_EVENT, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_OPTIMIZE_CA_EVENT"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_EXT_SCAN_CONC_MODE */ + tlvStruct->type = QWLAN_HAL_CFG_EXT_SCAN_CONC_MODE ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_EXT_SCAN_CONC_MODE, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_EXT_SCAN_CONC_MODE"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE */ + tlvStruct->type = QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_BAR_WAKE_UP_HOST, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DISABLE_BAR_WAKE_UP_HOST"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_SAR_BOFFSET_CORRECTION_ENABLE */ + tlvStruct->type = QWLAN_HAL_CFG_SAR_BOFFSET_CORRECTION_ENABLE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_SAR_BOFFSET_SET_CORRECTION, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_SAR_BOFFSET_SET_CORRECTION"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + /* QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL */ + tlvStruct->type = QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + wdiStartParams->usConfigBufferLen = (tANI_U8 *)tlvStruct - tlvStructStart ; + + /* QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO */ + tlvStruct->type = QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO ; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + + if (wlan_cfgGetInt(pMac, WNI_CFG_DISABLE_SCAN_DURING_SCO, + configDataValue ) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_DISABLE_SCAN_DURING_SCO"); + goto handle_failure; + } + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length) ; + + /* QWLAN_HAL_CFG_CONS_BCNMISS_COUNT */ + tlvStruct->type = QWLAN_HAL_CFG_CONS_BCNMISS_COUNT; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_CONC_BMISS, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_CONC_BMISS"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + + /* QWLAN_HAL_CFG_UNITS_OF_BCN_WAIT_TIME */ + tlvStruct->type = QWLAN_HAL_CFG_UNITS_OF_BCN_WAIT_TIME; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_UNITS_BWAIT, configDataValue) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_ENABLE_UNITS_BWAIT"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); + + /* QWLAN_HAL_CFG_TRIGGER_NULLFRAME_BEFORE_HB */ + tlvStruct->type = QWLAN_HAL_CFG_TRIGGER_NULLFRAME_BEFORE_HB; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + if(wlan_cfgGetInt(pMac, WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB, + configDataValue) != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_TRIGGER_NULLFRAME_BEFORE_HB"); + goto handle_failure; + } + + tlvStruct = (tHalCfg *)( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length); +#ifdef WLAN_DEBUG + { + int i; + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "****** Dumping CFG TLV ***** "); + for (i=0; (i+7) < wdiStartParams->usConfigBufferLen; i+=8) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%02x %02x %02x %02x %02x %02x %02x %02x", + tlvStructStart[i], + tlvStructStart[i+1], + tlvStructStart[i+2], + tlvStructStart[i+3], + tlvStructStart[i+4], + tlvStructStart[i+5], + tlvStructStart[i+6], + tlvStructStart[i+7]); + } + /* Dump the bytes in the last line*/ + for (; i < wdiStartParams->usConfigBufferLen; i++) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%02x ",tlvStructStart[i]); + } + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "**************************** "); + } +#endif + return VOS_STATUS_SUCCESS ; +handle_failure: + vos_mem_free(configParam); + return VOS_STATUS_E_FAILURE; +} + +#ifdef DHCP_SERVER_OFFLOAD +/** + * wda_dhcp_server_offload_rsp_callback() - response to the dhcp server offload + * @wdi_rsp: pointer to the dhcp server offload response + * @user_data: pointer to user data + * + * Return: None + */ +void wda_dhcp_server_offload_rsp_callback(wdi_dhcp_server_offload_rsp_param_t* + wdi_rsp, + void* user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + sir_dhcp_srv_offload_info_t *dhcp_srv_offload_info; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return; + } + + dhcp_srv_offload_info = (sir_dhcp_srv_offload_info_t *) + wda_params->wdaMsgParam; + + if(dhcp_srv_offload_info->dhcp_offload_callback) + { + dhcp_srv_offload_info->dhcp_offload_callback( + dhcp_srv_offload_info->dhcp_server_offload_cb_context, + CONVERT_WDI2VOS_STATUS(wdi_rsp->status)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFWLoggingInitParams callback is NULL", __func__); + } + + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: DHCP server offload failed with status=%d", __func__, status); + VOS_ASSERT(0); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + return; +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * wda_mdns_enable_rsp_callback() - response to the mdns enable server offload + * @wdi_rsp: pointer to the mdns enable offload response + * @user_data: pointer to user data + * + * Return: None + */ +void wda_mdns_enable_rsp_callback(wdi_mdns_enable_offload_rsp_param_t* + wdi_rsp, + void* user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + sir_mdns_offload_info_t *mdns_offload_info; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return ; + } + + mdns_offload_info = (sir_mdns_offload_info_t *) + wda_params->wdaMsgParam; + + if(mdns_offload_info->mdns_enable_callback) + { + mdns_offload_info->mdns_enable_callback(mdns_offload_info-> + mdns_enable_cb_context, + CONVERT_WDI2VOS_STATUS(wdi_rsp-> + status)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: mdns_enable callback is NULL", __func__); + } + + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: MDNS offload failed with status=%d", __func__, status); + VOS_ASSERT(0); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + + return; +} + +/** + * wda_mdns_fqdn_rsp_callback() - response to the mdns fqdn offload + * @wdi_rsp: pointer to the mdns fqdn offload response + * @user_data: pointer to user data + * + * Return: None + */ +void wda_mdns_fqdn_rsp_callback(wdi_mdns_set_fqdn_rsp_param_t* + wdi_rsp, + void* user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + sir_mdns_fqdn_info_t *mdns_fqdn_info; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return ; + } + + mdns_fqdn_info = (sir_mdns_fqdn_info_t *) + wda_params->wdaMsgParam; + + if(mdns_fqdn_info->mdns_fqdn_callback) + { + mdns_fqdn_info->mdns_fqdn_callback(mdns_fqdn_info-> + mdns_fqdn_cb_context, + CONVERT_WDI2VOS_STATUS(wdi_rsp-> + status)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: mdns_fqdn callback is NULL", __func__); + } + + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: MDNS FQDN offload failed with status=%d", __func__, status); + VOS_ASSERT(0); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + + return; +} + +/** + * wda_mdns_resp_rsp_callback() - response to the mdns resp offload + * @wdi_rsp: pointer to the mdns fqdn offload response + * @user_data: pointer to user data + * + * Return: None + */ +void wda_mdns_resp_rsp_callback +( + wdi_mdns_set_rsp_param_t* + wdi_rsp, + void* user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + sir_mdns_resp_info_t *mdns_resp_info; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return ; + } + + mdns_resp_info = (sir_mdns_resp_info_t *) + wda_params->wdaMsgParam; + + if(mdns_resp_info->mdns_resp_callback) + { + mdns_resp_info->mdns_resp_callback(mdns_resp_info-> + mdns_resp_cb_context, + CONVERT_WDI2VOS_STATUS(wdi_rsp-> + status)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: mdns_fqdn callback is NULL", __func__); + } + + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: MDNS FQDN offload failed with status=%d", __func__, status); + VOS_ASSERT(0); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + + return; +} + +/** + * wda_get_stats_rsp_callback() - response to the mdns stats offload + * @wdi_rsp: pointer to the mdns fqdn offload response + * @user_data: pointer to user data + * + * Return: None + */ +void wda_get_stats_rsp_callback +( + wdi_mdns_stats_rsp_param_t* + wdi_rsp, + void* user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + sir_get_mdns_stats_info_t *mdns_stats_info; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return ; + } + + mdns_stats_info = (sir_get_mdns_stats_info_t *) + wda_params->wdaMsgParam; + + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: MDNS FQDN offload failed with status=%d", __func__, status); + VOS_ASSERT(0); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + + return; +} +#endif /* MDNS_OFFLOAD */ + +/* + * FUNCTION: WDA_wdiCompleteCB + * call the voss call back function + */ +void WDA_stopCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *wdaContext; + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + wdaContext = (tWDA_CbContext *)pWdaParams->pWdaContext; + + if (NULL == wdaContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid wdaContext", __func__ ); + return ; + } + + /* free the config structure */ + if(pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + if(WDI_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDI stop callback returned failure" ); + VOS_ASSERT(0) ; + } + else + { + wdaContext->wdaState = WDA_STOP_STATE; + } + + /* FTM Driver stop procedure should be synced. + * Stop and Close will happen on same context */ + if (eDRIVER_TYPE_MFG == wdaContext->driverMode) + { + if (VOS_STATUS_SUCCESS != vos_event_set(&wdaContext->ftmStopDoneEvent)) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: FTM Stop Event Set Fail", __func__); + VOS_ASSERT(0); + } + } + + /* Indicate VOSS about the start complete */ + vos_WDAComplete_cback(wdaContext->pVosContext); + + return ; +} +/* + * FUNCTION: WDA_stop + * call WDI_stop + */ +VOS_STATUS WDA_stop(v_PVOID_t pVosContext, tANI_U8 reason) +{ + WDI_Status wdiStatus; + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_StopReqParamsType *wdiStopReq; + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + tWDA_ReqParams *pWdaParams ; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid pWDA", __func__ ); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + if (pWDA->wdiFailed == true) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: WDI in failed state", __func__ ); + return VOS_STATUS_E_ALREADY; + } + + /* FTM mode stay START_STATE */ + if( (WDA_READY_STATE != pWDA->wdaState) && + (WDA_INIT_STATE != pWDA->wdaState) && + (WDA_START_STATE != pWDA->wdaState) ) + { + VOS_ASSERT(0); + } + wdiStopReq = (WDI_StopReqParamsType *) + vos_mem_malloc(sizeof(WDI_StopReqParamsType)); + if(NULL == wdiStopReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + wdiStopReq->wdiStopReason = reason; + wdiStopReq->wdiReqStatusCB = NULL; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiStopReq); + return VOS_STATUS_E_NOMEM; + } + + if ( (eDRIVER_TYPE_MFG != pWDA->driverMode) && + (VOS_TRUE == pWDA->wdaTimersCreated)) + { + wdaDestroyTimers(pWDA); + pWDA->wdaTimersCreated = VOS_FALSE; + } + + pWdaParams->wdaWdiApiMsgParam = (v_PVOID_t *)wdiStopReq; + pWdaParams->wdaMsgParam = NULL; + pWdaParams->pWdaContext = pWDA; + + /* call WDI stop */ + wdiStatus = WDI_Stop(wdiStopReq, + (WDI_StopRspCb)WDA_stopCallback, pWdaParams); + + if (IS_WDI_STATUS_FAILURE(wdiStatus) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "error in WDA Stop" ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + status = VOS_STATUS_E_FAILURE; + } + + /* FTM Driver stop procedure should be synced. + * Stop and Close will happen on same context */ + if (eDRIVER_TYPE_MFG == pWDA->driverMode) + { + status = vos_wait_single_event(&pWDA->ftmStopDoneEvent, + WDI_RESPONSE_TIMEOUT); + if (status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: FTM Stop Timepoout", __func__); + VOS_ASSERT(0); + } + vos_event_destroy(&pWDA->ftmStopDoneEvent); + } + return status; +} +/* + * FUNCTION: WDA_close + * call WDI_close and free the WDA context + */ +VOS_STATUS WDA_close(v_PVOID_t pVosContext) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + VOS_STATUS vstatus; + tWDA_CbContext *wdaContext= (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + if (NULL == wdaContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid wdaContext", __func__ ); + return VOS_STATUS_E_FAILURE; + } + if((WDA_INIT_STATE != wdaContext->wdaState) && + (WDA_STOP_STATE != wdaContext->wdaState)) + { + VOS_ASSERT(0); + } + /*call WDI close*/ + wstatus = WDI_Close(); + if ( wstatus != WDI_STATUS_SUCCESS ) + { + status = VOS_STATUS_E_FAILURE; + } + wdaContext->wdaState = WDA_CLOSE_STATE; + /* Destroy the events */ + vstatus = vos_event_destroy(&wdaContext->wdaWdiEvent); + if(!VOS_IS_STATUS_SUCCESS(vstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDI Sync Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + + vstatus = vos_event_destroy(&wdaContext->txFrameEvent); + if(!VOS_IS_STATUS_SUCCESS(vstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + vstatus = vos_event_destroy(&wdaContext->suspendDataTxEvent); + if(!VOS_IS_STATUS_SUCCESS(vstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + vstatus = vos_event_destroy(&wdaContext->waitOnWdiIndicationCallBack); + if(!VOS_IS_STATUS_SUCCESS(vstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + + vos_lock_destroy(&wdaContext->mgmt_pkt_lock); + + /* free WDA context */ + vstatus = vos_free_context(pVosContext, VOS_MODULE_ID_WDA, wdaContext); + if ( !VOS_IS_STATUS_SUCCESS(vstatus) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "error in WDA close " ); + status = VOS_STATUS_E_FAILURE; + } + + return status; +} +/* + * FUNCTION: WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual + * returns 1 if the compiled version is greater than or equal to the input version + */ + +uint8 WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tSirVersionType compiledVersion; + status = WDA_GetWcnssWlanCompiledVersion(vosContext, &compiledVersion); + if ((compiledVersion.major > major) || ((compiledVersion.major == major)&& (compiledVersion.minor > minor)) || + ((compiledVersion.major == major)&& (compiledVersion.minor == minor) &&(compiledVersion.version > version)) || + ((compiledVersion.major == major)&& (compiledVersion.minor == minor) &&(compiledVersion.version == version) && + (compiledVersion.revision >= revision))) + return 1; + else + return 0; +} +/* + * FUNCTION: WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual + * returns 1 if the compiled version is greater than or equal to the input version + */ +uint8 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + v_CONTEXT_t vosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tSirVersionType reportedVersion; + status = WDA_GetWcnssWlanReportedVersion(vosContext, &reportedVersion); + if ((reportedVersion.major > major) || ((reportedVersion.major == major)&& (reportedVersion.minor > minor)) || + ((reportedVersion.major == major)&& (reportedVersion.minor == minor) &&(reportedVersion.version > version)) || + ((reportedVersion.major == major)&& (reportedVersion.minor == minor) &&(reportedVersion.version == version) && + (reportedVersion.revision >= revision))) + return 1; + else + return 0; +} +/* + * FUNCTION: WDA_GetWcnssWlanCompiledVersion + * Returns the version of the WCNSS WLAN API with which the HOST + * device driver was compiled + */ +VOS_STATUS WDA_GetWcnssWlanCompiledVersion(v_PVOID_t pvosGCtx, + tSirVersionType *pVersion) +{ + tWDA_CbContext *pWDA = NULL; + if ((NULL == pvosGCtx) || (NULL == pVersion)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid parameter", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pvosGCtx); + if (NULL == pWDA ) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WDA context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + *pVersion = pWDA->wcnssWlanCompiledVersion; + return VOS_STATUS_SUCCESS; +} +/* + * FUNCTION: WDA_GetWcnssWlanReportedVersion + * Returns the version of the WCNSS WLAN API with which the WCNSS + * device driver was compiled + */ +VOS_STATUS WDA_GetWcnssWlanReportedVersion(v_PVOID_t pvosGCtx, + tSirVersionType *pVersion) +{ + tWDA_CbContext *pWDA = NULL; + if ((NULL == pvosGCtx) || (NULL == pVersion)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid parameter", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pvosGCtx); + if (NULL == pWDA ) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WDA context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + *pVersion = pWDA->wcnssWlanReportedVersion; + return VOS_STATUS_SUCCESS; +} +/* + * FUNCTION: WDA_GetWcnssSoftwareVersion + * Returns the WCNSS Software version string + */ +VOS_STATUS WDA_GetWcnssSoftwareVersion(v_PVOID_t pvosGCtx, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + tWDA_CbContext *pWDA = NULL; + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Entered", __func__); + if ((NULL == pvosGCtx) || (NULL == pVersion)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid parameter", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pvosGCtx); + if (NULL == pWDA ) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WDA context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + wpalMemoryCopy(pVersion, pWDA->wcnssSoftwareVersionString, versionBufferSize); + return VOS_STATUS_SUCCESS; +} +/* + * FUNCTION: WDA_GetWcnssHardwareVersion + * Returns the WCNSS Hardware version string + */ +VOS_STATUS WDA_GetWcnssHardwareVersion(v_PVOID_t pvosGCtx, + tANI_U8 *pVersion, + tANI_U32 versionBufferSize) +{ + tWDA_CbContext *pWDA = NULL; + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Entered", __func__); + if ((NULL == pvosGCtx) || (NULL == pVersion)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid parameter", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pvosGCtx); + if (NULL == pWDA ) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid WDA context", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + wpalMemoryCopy(pVersion, pWDA->wcnssHardwareVersionString, versionBufferSize); + return VOS_STATUS_SUCCESS; +} +/* + * FUNCTION: WDA_WniCfgDnld + * Trigger CFG Download + */ +VOS_STATUS WDA_WniCfgDnld(tWDA_CbContext *pWDA) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + + if (NULL == pMac ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid MAC context ", __func__ ); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + processCfgDownloadReq(pMac); + return vosStatus; +} +/* ----------------------------------------------------------------- + * WDI interface + * ----------------------------------------------------------------- + */ +/* + * FUNCTION: WDA_suspendDataTxCallback + * call back function called from TL after suspend Transmission + */ +VOS_STATUS WDA_SuspendDataTxCallback( v_PVOID_t pvosGCtx, + v_U8_t* ucSTAId, + VOS_STATUS vosStatus) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pvosGCtx); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Entered " ,__func__); + if (NULL == pWDA ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid WDA context ", __func__ ); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + if(VOS_IS_STATUS_SUCCESS(vosStatus)) + { + pWDA->txStatus = WDA_TL_TX_SUSPEND_SUCCESS; + } + else + { + pWDA->txStatus = WDA_TL_TX_SUSPEND_FAILURE; + } + /* Trigger the event to bring the WDA TL suspend function to come + * out of wait*/ + vosStatus = vos_event_set(&pWDA->suspendDataTxEvent); + if(!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "NEW VOS Event Set failed - status = %d", vosStatus); + } + /* If TL suspended had timedout before this callback was called, resume back + * TL.*/ + if (pWDA->txSuspendTimedOut) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Late TLSuspendCallback, resuming TL back again"); + WDA_ResumeDataTx(pWDA); + pWDA->txSuspendTimedOut = FALSE; + } + return VOS_STATUS_SUCCESS; +} +/* + * FUNCTION: WDA_suspendDataTx + * Update TL to suspend the data Transmission + */ +VOS_STATUS WDA_SuspendDataTx(tWDA_CbContext *pWDA) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tANI_U8 eventIdx = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Entered " ,__func__); + pWDA->txStatus = WDA_TL_TX_SUSPEND_FAILURE; + if (pWDA->txSuspendTimedOut) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "TL suspend timedout previously, CB not called yet"); + return status; + } + /* Reset the event to be not signalled */ + status = vos_event_reset(&pWDA->suspendDataTxEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event reset failed - status = %d",status); + return VOS_STATUS_E_FAILURE; + } + /*Indicate TL to suspend transmission for all Sta Id */ + status = WLANTL_SuspendDataTx(pWDA->pVosContext, NULL, + WDA_SuspendDataTxCallback); + if(status != VOS_STATUS_SUCCESS) + { + return status; + } + /* Wait for the event to be set by the TL, to get the response of + * suspending the TX queues, this event should be set by the Callback + * function called by TL*/ + status = vos_wait_events(&pWDA->suspendDataTxEvent, 1, + WDA_TL_SUSPEND_TIMEOUT, &eventIdx); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Status %d when waiting for Suspend Data TX Event", + __func__, status); + /* Set this flag to true when TL suspend times out, so that when TL + * suspend eventually happens and calls the callback, TL can be resumed + * right away by looking at this flag when true.*/ + pWDA->txSuspendTimedOut = TRUE; + } + else + { + pWDA->txSuspendTimedOut = FALSE; + } + if(WDA_TL_TX_SUSPEND_SUCCESS == pWDA->txStatus) + { + status = VOS_STATUS_SUCCESS; + } + return status; +} +/* + * FUNCTION: WDA_resumeDataTx + * Update TL to resume the data Transmission + */ +VOS_STATUS WDA_ResumeDataTx(tWDA_CbContext *pWDA) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Entered " ,__func__); + + status = WLANTL_ResumeDataTx(pWDA->pVosContext, NULL); + return status; +} +/* + * FUNCTION: WDA_InitScanReqCallback + * Trigger Init SCAN callback + */ +void WDA_InitScanReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tInitScanParams *pWDA_ScanParam ; + VOS_STATUS status; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pWDA_ScanParam = (tInitScanParams *)pWdaParams->wdaMsgParam; + if(NULL == pWDA_ScanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA_ScanParam received NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + if(WDI_STATUS_SUCCESS != wdiStatus) + { + status = WDA_ResumeDataTx(pWDA) ; + if(VOS_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s error in Resume Tx ", __func__ ); + } + } + /* free WDI command buffer */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + + /* assign status to scan params */ + /* without converting the Status to Failure or Success Just + pass the same status to lim */ + pWDA_ScanParam->status = wdiStatus ; + /* send SCAN RSP message back to PE */ + WDA_SendMsg(pWDA, WDA_INIT_SCAN_RSP, (void *)pWDA_ScanParam, 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessInitScanReq + * Trigger Init SCAN in DAL + */ +VOS_STATUS WDA_ProcessInitScanReq(tWDA_CbContext *pWDA, + tInitScanParams *initScanParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_InitScanReqParamsType *wdiInitScanParam = + (WDI_InitScanReqParamsType *)vos_mem_malloc( + sizeof(WDI_InitScanReqParamsType)) ; + tWDA_ReqParams *pWdaParams; + tANI_U8 i = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiInitScanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiInitScanParam); + return VOS_STATUS_E_NOMEM; + } + + /* Copy init Scan params to WDI structure */ + wdiInitScanParam->wdiReqInfo.wdiScanMode = initScanParams->scanMode ; + vos_mem_copy(wdiInitScanParam->wdiReqInfo.macBSSID, initScanParams->bssid, + sizeof(tSirMacAddr)) ; + wdiInitScanParam->wdiReqInfo.bNotifyBSS = initScanParams->notifyBss ; + wdiInitScanParam->wdiReqInfo.ucFrameType = initScanParams->frameType ; + wdiInitScanParam->wdiReqInfo.ucFrameLength = initScanParams->frameLength ; + wdiInitScanParam->wdiReqInfo.bUseNOA = initScanParams->useNoA; + wdiInitScanParam->wdiReqInfo.scanDuration = initScanParams->scanDuration; + wdiInitScanParam->wdiReqInfo.wdiScanEntry.activeBSScnt = + initScanParams->scanEntry.activeBSScnt ; + for (i=0; i < initScanParams->scanEntry.activeBSScnt; i++) + { + wdiInitScanParam->wdiReqInfo.wdiScanEntry.bssIdx[i] = + initScanParams->scanEntry.bssIdx[i] ; + } + + /* if Frame length, copy macMgmtHdr or WDI structure */ + if(0 != wdiInitScanParam->wdiReqInfo.ucFrameLength) + { + vos_mem_copy(&wdiInitScanParam->wdiReqInfo.wdiMACMgmtHdr, + &initScanParams->macMgmtHdr, sizeof(tSirMacMgmtHdr)) ; + } + wdiInitScanParam->wdiReqStatusCB = NULL ; + + /* Store Init Req pointer, as this will be used for response */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = initScanParams; + pWdaParams->wdaWdiApiMsgParam = wdiInitScanParam; + /* first try to suspend TX */ + status = WDA_SuspendDataTx(pWDA) ; + if(WDI_STATUS_SUCCESS != status) + { + goto handleWdiFailure; + } + /* call DAL API to pass init scan request to DAL */ + status = WDI_InitScanReq(wdiInitScanParam, + WDA_InitScanReqCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "error in WDA Init Scan, Resume Tx " ); + status = WDA_ResumeDataTx(pWDA) ; + VOS_ASSERT(0) ; + + goto handleWdiFailure; + } + return CONVERT_WDI2VOS_STATUS(status) ; +handleWdiFailure: + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDI Api, free all the memory " ); + /* free WDI command buffer */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* send Failure to PE */ + initScanParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_INIT_SCAN_RSP, (void *)initScanParams, 0) ; + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_StartScanReqCallback + * send Start SCAN RSP back to PE + */ +void WDA_StartScanReqCallback(WDI_StartScanRspParamsType *pScanRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tStartScanParams *pWDA_ScanParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pWDA_ScanParam = (tStartScanParams *)pWdaParams->wdaMsgParam; + if(NULL == pWDA_ScanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA_ScanParam received NULL", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pWdaParams); + return ; + } + if(NULL == pWdaParams->wdaWdiApiMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdaWdiApiMsgParam is NULL", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pWdaParams); + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + + /* assign status to scan params */ + pWDA_ScanParam->status = pScanRsp->wdiStatus ; + /* send SCAN RSP message back to PE */ + WDA_SendMsg(pWDA, WDA_START_SCAN_RSP, (void *)pWDA_ScanParam, 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessStartScanReq + * Trigger start SCAN in WDI + */ +VOS_STATUS WDA_ProcessStartScanReq(tWDA_CbContext *pWDA, + tStartScanParams *startScanParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_StartScanReqParamsType *wdiStartScanParams = + (WDI_StartScanReqParamsType *)vos_mem_malloc( + sizeof(WDI_StartScanReqParamsType)) ; + tWDA_ReqParams *pWdaParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiStartScanParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiStartScanParams); + return VOS_STATUS_E_NOMEM; + } + /* Copy init Scan params to WDI structure */ + wdiStartScanParams->ucChannel = startScanParams->scanChannel ; + wdiStartScanParams->wdiReqStatusCB = NULL ; + + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = startScanParams; + pWdaParams->wdaWdiApiMsgParam = wdiStartScanParams; + /* call DAL API to pass init scan request to DAL */ + status = WDI_StartScanReq(wdiStartScanParams, + WDA_StartScanReqCallback, pWdaParams) ; + /* failure returned by WDI API */ + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Start Scan WDI API, free all the memory " + "It should be due to previous abort scan." ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + startScanParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_START_SCAN_RSP, (void *)startScanParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_EndScanReqCallback + * END SCAN callback + */ +void WDA_EndScanReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tEndScanParams *endScanParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + endScanParam = (tEndScanParams *)pWdaParams->wdaMsgParam; + if(NULL == endScanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: endScanParam received NULL", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + + /* Free WDI command buffer */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* assign status to scan params */ + endScanParam->status = status ; + /* send response back to PE */ + WDA_SendMsg(pWDA, WDA_END_SCAN_RSP, (void *)endScanParam, 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessEndScanReq + * Trigger END SCAN in WDI + */ +VOS_STATUS WDA_ProcessEndScanReq(tWDA_CbContext *pWDA, + tEndScanParams *endScanParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_EndScanReqParamsType *wdiEndScanParams = + (WDI_EndScanReqParamsType *)vos_mem_malloc( + sizeof(WDI_EndScanReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiEndScanParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiEndScanParams); + return VOS_STATUS_E_NOMEM; + } + /* Copy init Scan params to WDI structure */ + wdiEndScanParams->ucChannel = endScanParams->scanChannel ; + wdiEndScanParams->wdiReqStatusCB = NULL ; + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = endScanParams; + pWdaParams->wdaWdiApiMsgParam = wdiEndScanParams; + /* call DAL API to pass init scan request to DAL */ + status = WDI_EndScanReq(wdiEndScanParams, + WDA_EndScanReqCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in End Scan WDI API, free all the memory " + "It should be due to previous abort scan." ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + endScanParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_END_SCAN_RSP, (void *)endScanParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_FinishScanReqCallback + * Trigger Finish SCAN callback + */ +void WDA_FinishScanReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tFinishScanParams *finishScanParam; + VOS_STATUS status; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + finishScanParam = (tFinishScanParams *)pWdaParams->wdaMsgParam; + if(NULL == finishScanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: finishScanParam is NULL", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* + * Now Resume TX, if we reached here means, TX is already suspended, we + * have to resume it unconditionaly + */ + status = WDA_ResumeDataTx(pWDA) ; + + if(VOS_STATUS_SUCCESS != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s error in Resume Tx ", __func__ ); + } + finishScanParam->status = wdiStatus ; + WDA_SendMsg(pWDA, WDA_FINISH_SCAN_RSP, (void *)finishScanParam, 0) ; + return ; +} +/* + * FUNCTION: WDA_ProcessFinshScanReq + * Trigger Finish SCAN in WDI + */ +VOS_STATUS WDA_ProcessFinishScanReq(tWDA_CbContext *pWDA, + tFinishScanParams *finishScanParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_FinishScanReqParamsType *wdiFinishScanParams = + (WDI_FinishScanReqParamsType *)vos_mem_malloc( + sizeof(WDI_FinishScanReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + tANI_U8 i = 0; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiFinishScanParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiFinishScanParams); + return VOS_STATUS_E_NOMEM; + } + /* Copy init Scan params to WDI structure */ + wdiFinishScanParams->wdiReqInfo.wdiScanMode = finishScanParams->scanMode ; + vos_mem_copy(wdiFinishScanParams->wdiReqInfo.macBSSID, + finishScanParams->bssid, sizeof(tSirMacAddr)) ; + wdiFinishScanParams->wdiReqInfo.bNotifyBSS = finishScanParams->notifyBss ; + wdiFinishScanParams->wdiReqInfo.ucFrameType = finishScanParams->frameType ; + wdiFinishScanParams->wdiReqInfo.ucFrameLength = + finishScanParams->frameLength ; + wdiFinishScanParams->wdiReqInfo.ucCurrentOperatingChannel = + finishScanParams->currentOperChannel ; + wdiFinishScanParams->wdiReqInfo.wdiCBState = finishScanParams->cbState ; + wdiFinishScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt = + finishScanParams->scanEntry.activeBSScnt ; + for (i = 0; i < finishScanParams->scanEntry.activeBSScnt; i++) + { + wdiFinishScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i] = + finishScanParams->scanEntry.bssIdx[i] ; + } + + + /* if Frame length, copy macMgmtHdr ro WDI structure */ + if(0 != wdiFinishScanParams->wdiReqInfo.ucFrameLength) + { + vos_mem_copy(&wdiFinishScanParams->wdiReqInfo.wdiMACMgmtHdr, + &finishScanParams->macMgmtHdr, + sizeof(WDI_MacMgmtHdr)) ; + } + wdiFinishScanParams->wdiReqStatusCB = NULL ; + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = finishScanParams; + pWdaParams->wdaWdiApiMsgParam = wdiFinishScanParams; + /* call DAL API to pass init scan request to DAL */ + status = WDI_FinishScanReq(wdiFinishScanParams, + WDA_FinishScanReqCallback, pWdaParams) ; + + + /* + * WDI API returns failure.. + */ + if(IS_WDI_STATUS_FAILURE( status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Finish Scan WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + finishScanParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_FINISH_SCAN_RSP, (void *)finishScanParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/*--------------------------------------------------------------------- + * ASSOC API's + *--------------------------------------------------------------------- + */ +/* + * FUNCTION: WDA_JoinRspCallback + * Trigger Init SCAN callback + */ +void WDA_JoinRspCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tSwitchChannelParams *joinReqParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + joinReqParam = (tSwitchChannelParams *)pWdaParams->wdaMsgParam; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams) ; + /* reset macBSSID */ + vos_mem_set(pWDA->macBSSID, sizeof(pWDA->macBSSID),0 ); + /* reset macSTASelf */ + vos_mem_set(pWDA->macSTASelf, sizeof(pWDA->macSTASelf),0 ); + joinReqParam->status = status ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, (void *)joinReqParam , 0) ; + return ; +} + +/* + * FUNCTION: WDA_JoinReqCallback + * Free memory and send SWITCH CHANNEL RSP back to PE. + * Invoked when Enter JOIN REQ failed in WDI and no RSP callback is generated. + */ +void WDA_JoinReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tSwitchChannelParams *joinReqParam; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + joinReqParam = (tSwitchChannelParams *)pWdaParams->wdaMsgParam; + joinReqParam->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + /* reset macBSSID */ + vos_mem_set(pWDA->macBSSID, sizeof(pWDA->macBSSID),0 ); + /* reset macSTASelf */ + vos_mem_set(pWDA->macSTASelf, sizeof(pWDA->macSTASelf),0 ); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, (void *)joinReqParam , 0) ; + } + + return; +} + +/* + * FUNCTION: WDA_ProcessJoinReq + * Trigger Join REQ in WDI + */ +VOS_STATUS WDA_ProcessJoinReq(tWDA_CbContext *pWDA, + tSwitchChannelParams* joinReqParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_JoinReqParamsType *wdiJoinReqParam = + (WDI_JoinReqParamsType *)vos_mem_malloc( + sizeof(WDI_JoinReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiJoinReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(joinReqParam); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiJoinReqParam); + vos_mem_free(joinReqParam); + return VOS_STATUS_E_NOMEM; + } + + /*if the BSSID or self STA in pWDA is NULL, join request can't be processed*/ + if(WDA_IS_NULL_MAC_ADDRESS(pWDA->macBSSID) || + WDA_IS_NULL_MAC_ADDRESS(pWDA->macSTASelf)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: received join request when BSSID or self-STA is NULL " + " BSSID:" WDA_MAC_ADDRESS_STR "Self-STA:" WDA_MAC_ADDRESS_STR, + __func__, WDA_MAC_ADDR_ARRAY(pWDA->macBSSID), + WDA_MAC_ADDR_ARRAY(pWDA->macSTASelf)); + VOS_ASSERT(0); + vos_mem_free(wdiJoinReqParam); + vos_mem_free(pWdaParams); + joinReqParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, (void *)joinReqParam, 0) ; + return VOS_STATUS_E_INVAL; + } + + /* copy the BSSID for pWDA */ + vos_mem_copy(wdiJoinReqParam->wdiReqInfo.macBSSID, pWDA->macBSSID, + sizeof(tSirMacAddr)) ; + vos_mem_copy(wdiJoinReqParam->wdiReqInfo.macSTASelf, + pWDA->macSTASelf, sizeof(tSirMacAddr)) ; + wdiJoinReqParam->wdiReqInfo.wdiChannelInfo.ucChannel = + joinReqParam->channelNumber ; +#ifdef WLAN_FEATURE_VOWIFI + wdiJoinReqParam->wdiReqInfo.wdiChannelInfo.cMaxTxPower = + joinReqParam->maxTxPower ; +#else + wdiJoinReqParam->wdiReqInfo.wdiChannelInfo.ucLocalPowerConstraint = + joinReqParam->localPowerConstraint ; +#endif + wdiJoinReqParam->wdiReqInfo.wdiChannelInfo.wdiSecondaryChannelOffset = + joinReqParam->secondaryChannelOffset ; + wdiJoinReqParam->wdiReqInfo.linkState = pWDA->linkState; + + wdiJoinReqParam->wdiReqStatusCB = WDA_JoinReqCallback; + wdiJoinReqParam->pUserData = pWdaParams; + + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = joinReqParam; + pWdaParams->wdaWdiApiMsgParam = wdiJoinReqParam; + status = WDI_JoinReq(wdiJoinReqParam, + (WDI_JoinRspCb )WDA_JoinRspCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Join WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + joinReqParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, (void *)joinReqParam, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_SwitchChannelReqCallback + * send Switch channel RSP back to PE + */ +void WDA_SwitchChannelReqCallback( + WDI_SwitchCHRspParamsType *wdiSwitchChanRsp, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + tWDA_CbContext *pWDA; + tSwitchChannelParams *pSwitchChanParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pSwitchChanParams = (tSwitchChannelParams *)pWdaParams->wdaMsgParam; + +#ifdef WLAN_FEATURE_VOWIFI + pSwitchChanParams->txMgmtPower = wdiSwitchChanRsp->ucTxMgmtPower; +#endif + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pSwitchChanParams->status = + wdiSwitchChanRsp->wdiStatus ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, (void *)pSwitchChanParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_ProcessChannelSwitchReq + * Request to WDI to switch channel REQ params. + */ +VOS_STATUS WDA_ProcessChannelSwitchReq(tWDA_CbContext *pWDA, + tSwitchChannelParams *pSwitchChanParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SwitchChReqParamsType *wdiSwitchChanParam = + (WDI_SwitchChReqParamsType *)vos_mem_malloc( + sizeof(WDI_SwitchChReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSwitchChanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSwitchChanParam); + return VOS_STATUS_E_NOMEM; + } + wdiSwitchChanParam->wdiChInfo.ucChannel = pSwitchChanParams->channelNumber; +#ifndef WLAN_FEATURE_VOWIFI + wdiSwitchChanParam->wdiChInfo.ucLocalPowerConstraint = + pSwitchChanParams->localPowerConstraint; +#endif + wdiSwitchChanParam->wdiChInfo.wdiSecondaryChannelOffset = + pSwitchChanParams->secondaryChannelOffset; + wdiSwitchChanParam->wdiReqStatusCB = NULL ; + /* Store req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pSwitchChanParams; + pWdaParams->wdaWdiApiMsgParam = wdiSwitchChanParam; +#ifdef WLAN_FEATURE_VOWIFI + wdiSwitchChanParam->wdiChInfo.cMaxTxPower + = pSwitchChanParams->maxTxPower; + vos_mem_copy(wdiSwitchChanParam->wdiChInfo.macSelfStaMacAddr, + pSwitchChanParams ->selfStaMacAddr, + sizeof(tSirMacAddr)); +#endif + vos_mem_copy(wdiSwitchChanParam->wdiChInfo.macBSSId, + pSwitchChanParams->bssId, + sizeof(tSirMacAddr)); + + status = WDI_SwitchChReq(wdiSwitchChanParam, + (WDI_SwitchChRspCb)WDA_SwitchChannelReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in process channel switch Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pSwitchChanParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, (void *)pSwitchChanParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_SwitchChannelReqCallback_V1 + * send Switch channel RSP back to PE + */ +void WDA_SwitchChannelReqCallback_V1( + WDI_SwitchChRspParamsType_V1 *wdiSwitchChanRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + tWDA_CbContext *pWDA; + tSwitchChannelParams *pSwitchChanParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pSwitchChanParams = + (tSwitchChannelParams *)pWdaParams->wdaMsgParam; + pSwitchChanParams->channelSwitchSrc = + wdiSwitchChanRsp->channelSwitchSrc; +#ifdef WLAN_FEATURE_VOWIFI + pSwitchChanParams->txMgmtPower = + wdiSwitchChanRsp->ucTxMgmtPower; +#endif + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pSwitchChanParams->status = + wdiSwitchChanRsp->wdiStatus ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, + (void *)pSwitchChanParams , 0); + return; +} + +/* + * FUNCTION: WDA_ProcessChannelSwitchReq_V1 + * Request to WDI to switch channel REQ params. + */ +VOS_STATUS WDA_ProcessChannelSwitchReq_V1(tWDA_CbContext *pWDA, + tSwitchChannelParams *pSwitchChanParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SwitchChReqParamsType_V1 *wdiSwitchChanParam = + (WDI_SwitchChReqParamsType_V1 *)vos_mem_malloc( + sizeof(WDI_SwitchChReqParamsType_V1)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if (NULL == wdiSwitchChanParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSwitchChanParam); + return VOS_STATUS_E_NOMEM; + } + wdiSwitchChanParam->wdiChInfo.channelSwitchSrc = + pSwitchChanParams->channelSwitchSrc; + + wdiSwitchChanParam->wdiChInfo.ucChannel = + pSwitchChanParams->channelNumber; +#ifndef WLAN_FEATURE_VOWIFI + wdiSwitchChanParam->wdiChInfo.ucLocalPowerConstraint = + pSwitchChanParams->localPowerConstraint; +#endif + wdiSwitchChanParam->wdiChInfo.wdiSecondaryChannelOffset = + pSwitchChanParams->secondaryChannelOffset; + wdiSwitchChanParam->wdiReqStatusCB = NULL ; + /* Store req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pSwitchChanParams; + pWdaParams->wdaWdiApiMsgParam = wdiSwitchChanParam; +#ifdef WLAN_FEATURE_VOWIFI + wdiSwitchChanParam->wdiChInfo.cMaxTxPower = + pSwitchChanParams->maxTxPower; + vos_mem_copy(wdiSwitchChanParam->wdiChInfo.macSelfStaMacAddr, + pSwitchChanParams ->selfStaMacAddr, + sizeof(tSirMacAddr)); +#endif + vos_mem_copy(wdiSwitchChanParam->wdiChInfo.macBSSId, + pSwitchChanParams->bssId, + sizeof(tSirMacAddr)); + + status = WDI_SwitchChReq_V1(wdiSwitchChanParam, + (WDI_SwitchChRspCb_V1)WDA_SwitchChannelReqCallback_V1, + pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in process channel switch Req WDI " + "API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pSwitchChanParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SWITCH_CHANNEL_RSP, + (void *)pSwitchChanParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_ConfigBssRspCallback + * config BSS Req Callback, called by WDI + */ +void WDA_ConfigBssRspCallback(WDI_ConfigBSSRspParamsType *wdiConfigBssRsp + ,void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddBssParams *configBssReqParam; + tAddStaParams *staConfigBssParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + configBssReqParam = (tAddBssParams *)pWdaParams->wdaMsgParam; + staConfigBssParam = &configBssReqParam->staContext ; + configBssReqParam->status = + wdiConfigBssRsp->wdiStatus; + if(WDI_STATUS_SUCCESS == wdiConfigBssRsp->wdiStatus) + { + vos_mem_copy(configBssReqParam->bssId, wdiConfigBssRsp->macBSSID, + sizeof(tSirMacAddr)); + configBssReqParam->bssIdx = wdiConfigBssRsp->ucBSSIdx; + configBssReqParam->bcastDpuSignature = wdiConfigBssRsp->ucBcastSig; + configBssReqParam->mgmtDpuSignature = wdiConfigBssRsp->ucUcastSig; + + if (configBssReqParam->operMode == BSS_OPERATIONAL_MODE_STA) + { + if(configBssReqParam->bssType == eSIR_IBSS_MODE) + { + pWDA->wdaGlobalSystemRole = eSYSTEM_STA_IN_IBSS_ROLE; + staConfigBssParam->staType = STA_ENTRY_BSSID; + } + else if ((configBssReqParam->bssType == eSIR_BTAMP_STA_MODE) && + (staConfigBssParam->staType == STA_ENTRY_SELF)) + { + /* This is the 1st add BSS Req for the BTAMP STA */ + pWDA->wdaGlobalSystemRole = eSYSTEM_BTAMP_STA_ROLE; + staConfigBssParam->staType = STA_ENTRY_BSSID; + } + else if ((configBssReqParam->bssType == eSIR_BTAMP_AP_MODE) && + (staConfigBssParam->staType == STA_ENTRY_PEER)) + { + /* This is the 2nd ADD BSS Request that is sent + * on the BTAMP STA side. The Sta type is + * set to STA_ENTRY_PEER here.*/ + pWDA->wdaGlobalSystemRole = eSYSTEM_BTAMP_STA_ROLE; + } + else if ((configBssReqParam->bssType == eSIR_BTAMP_AP_MODE) && + (staConfigBssParam->staType == STA_ENTRY_SELF)) + { + /* statype is already set by PE. + * Only 1 ADD BSS Req is sent on the BTAMP AP side.*/ + pWDA->wdaGlobalSystemRole = eSYSTEM_BTAMP_AP_ROLE; + staConfigBssParam->staType = STA_ENTRY_BSSID; + } + else + { + pWDA->wdaGlobalSystemRole = eSYSTEM_STA_ROLE; + staConfigBssParam->staType = STA_ENTRY_PEER; + } + } + else if (configBssReqParam->operMode == BSS_OPERATIONAL_MODE_AP) + { + pWDA->wdaGlobalSystemRole = eSYSTEM_AP_ROLE; + staConfigBssParam->staType = STA_ENTRY_SELF; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Invalid operation mode specified"); + VOS_ASSERT(0); + } + + staConfigBssParam->staIdx = wdiConfigBssRsp->ucSTAIdx; + staConfigBssParam->bssIdx = wdiConfigBssRsp->ucBSSIdx; + staConfigBssParam->ucUcastSig = wdiConfigBssRsp->ucUcastSig; + staConfigBssParam->ucBcastSig = wdiConfigBssRsp->ucBcastSig; + vos_mem_copy(staConfigBssParam->staMac, wdiConfigBssRsp->macSTA, + sizeof(tSirMacAddr)); + staConfigBssParam->txChannelWidthSet = + configBssReqParam->txChannelWidthSet; + if(staConfigBssParam->staType == STA_ENTRY_PEER && + staConfigBssParam->htCapable) + { + pWDA->wdaStaInfo[staConfigBssParam->staIdx].bssIdx = + wdiConfigBssRsp->ucBSSIdx; + pWDA->wdaStaInfo[staConfigBssParam->staIdx].ucValidStaIndex = + WDA_VALID_STA_INDEX ; + pWDA->wdaStaInfo[staConfigBssParam->staIdx].currentOperChan = + configBssReqParam->currentOperChannel; + } + if(WDI_DS_SetStaIdxPerBssIdx(pWDA->pWdiContext, + wdiConfigBssRsp->ucBSSIdx, + wdiConfigBssRsp->ucSTAIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: fail to set STA idx associated with BSS index", __func__); + VOS_ASSERT(0) ; + } + if(WDI_DS_AddSTAMemPool(pWDA->pWdiContext, wdiConfigBssRsp->ucSTAIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: add BSS into mempool fail", __func__); + VOS_ASSERT(0) ; + } +#ifdef WLAN_FEATURE_VOWIFI + configBssReqParam->txMgmtPower = wdiConfigBssRsp->ucTxMgmtPower; +#endif + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d", __func__, + wdiConfigBssRsp->wdiStatus); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + FALSE, TRUE); + } + vos_mem_zero(pWdaParams->wdaWdiApiMsgParam, + sizeof(WDI_ConfigBSSReqParamsType)); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + WDA_SendMsg(pWDA, WDA_ADD_BSS_RSP, (void *)configBssReqParam , 0) ; + return ; +} +/* + * FUNCTION: WDA_UpdateEdcaParamsForAC + * Update WDI EDCA params with PE edca params + */ +void WDA_UpdateEdcaParamsForAC(tWDA_CbContext *pWDA, + WDI_EdcaParamRecord *wdiEdcaParam, + tSirMacEdcaParamRecord *macEdcaParam) +{ + wdiEdcaParam->wdiACI.aifsn = macEdcaParam->aci.aifsn; + wdiEdcaParam->wdiACI.acm= macEdcaParam->aci.acm; + wdiEdcaParam->wdiACI.aci = macEdcaParam->aci.aci; + wdiEdcaParam->wdiCW.min = macEdcaParam->cw.min; + wdiEdcaParam->wdiCW.max = macEdcaParam->cw.max; + wdiEdcaParam->usTXOPLimit = macEdcaParam->txoplimit; +} +void WDA_ConfigBssReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddBssParams *addBssParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", + __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + addBssParams = (tAddBssParams *)pWdaParams->wdaMsgParam; + + addBssParams->status = wdiStatus; + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + FALSE, TRUE); + WDA_SendMsg(pWDA, WDA_ADD_BSS_RSP, (void *)addBssParams , 0); + } + + return ; +} + +/* + * FUNCTION: WDA_ProcessConfigBssReq + * Configure BSS before starting Assoc with AP + */ +VOS_STATUS WDA_ProcessConfigBssReq(tWDA_CbContext *pWDA, + tAddBssParams* configBssReqParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_ConfigBSSReqParamsType *wdiConfigBssReqParam; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if (NULL == configBssReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: configBssReqParam is NULL", __func__); + return VOS_STATUS_E_INVAL; + } + + wdiConfigBssReqParam = (WDI_ConfigBSSReqParamsType *)vos_mem_malloc( + sizeof(WDI_ConfigBSSReqParamsType)) ; + + if(NULL == wdiConfigBssReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiConfigBssReqParam); + return VOS_STATUS_E_NOMEM; + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: maxTxPower %d", __func__, configBssReqParam->maxTxPower); + vos_mem_set(wdiConfigBssReqParam, sizeof(WDI_ConfigBSSReqParamsType), 0); + WDA_UpdateBSSParams(pWDA, &wdiConfigBssReqParam->wdiReqInfo, + configBssReqParam) ; + wdiConfigBssReqParam->wdiReqStatusCB = WDA_ConfigBssReqCallback; + wdiConfigBssReqParam->pUserData = pWdaParams; + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = configBssReqParam; + pWdaParams->wdaWdiApiMsgParam = wdiConfigBssReqParam; + status = WDI_ConfigBSSReq(wdiConfigBssReqParam, + (WDI_ConfigBSSRspCb )WDA_ConfigBssRspCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Config BSS WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + configBssReqParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_ADD_BSS_RSP, (void *)configBssReqParam, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#ifdef ENABLE_HAL_COMBINED_MESSAGES +/* + * FUNCTION: WDA_PostAssocReqCallback + * Post ASSOC req callback, send RSP back to PE + */ +void WDA_PostAssocReqCallback(WDI_PostAssocRspParamsType *wdiPostAssocRsp, + void* pUserData) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)pUserData ; + tPostAssocParams *postAssocReqParam = + (tPostAssocParams *)pWDA->wdaMsgParam ; + /*STA context within the BSS Params*/ + tAddStaParams *staPostAssocParam = + &postAssocReqParam->addBssParams.staContext ; + /*STA Params for self STA*/ + tAddStaParams *selfStaPostAssocParam = + &postAssocReqParam->addStaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + postAssocReqParam->status = + wdiPostAssocRsp->wdiStatus ; + if(WDI_STATUS_SUCCESS == wdiPostAssocRsp->wdiStatus) + { + staPostAssocParam->staIdx = wdiPostAssocRsp->bssParams.ucSTAIdx ; + vos_mem_copy(staPostAssocParam->staMac, wdiPostAssocRsp->bssParams.macSTA, + sizeof(tSirMacAddr)) ; + staPostAssocParam->ucUcastSig = wdiPostAssocRsp->bssParams.ucUcastSig ; + staPostAssocParam->ucBcastSig = wdiPostAssocRsp->bssParams.ucBcastSig ; + staPostAssocParam->bssIdx = wdiPostAssocRsp->bssParams.ucBSSIdx; + selfStaPostAssocParam->staIdx = wdiPostAssocRsp->staParams.ucSTAIdx; + } + vos_mem_zero(pWDA->wdaWdiApiMsgParam, sizeof(WDI_PostAssocReqParamsType)); + vos_mem_free(pWDA->wdaWdiApiMsgParam) ; + pWDA->wdaWdiApiMsgParam = NULL; + pWDA->wdaMsgParam = NULL; + WDA_SendMsg(pWDA, WDA_POST_ASSOC_RSP, (void *)postAssocReqParam, 0) ; + return ; +} +/* + * FUNCTION: WDA_ProcessPostAssocReq + * Trigger POST ASSOC processing in WDI + */ +VOS_STATUS WDA_ProcessPostAssocReq(tWDA_CbContext *pWDA, + tPostAssocParams *postAssocReqParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + + WDI_PostAssocReqParamsType *wdiPostAssocReqParam = + (WDI_PostAssocReqParamsType *)vos_mem_malloc( + sizeof(WDI_PostAssocReqParamsType)) ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if(NULL == wdiPostAssocReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + if((NULL != pWDA->wdaMsgParam) || (NULL != pWDA->wdaWdiApiMsgParam)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdaMsgParam or wdaWdiApiMsgParam is not NULL", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* update BSS params into WDI structure */ + WDA_UpdateBSSParams(pWDA, &wdiPostAssocReqParam->wdiBSSParams, + &postAssocReqParam->addBssParams) ; + /* update STA params into WDI structure */ + WDA_UpdateSTAParams(pWDA, &wdiPostAssocReqParam->wdiSTAParams, + &postAssocReqParam->addStaParams) ; + + wdiPostAssocReqParam->wdiBSSParams.ucEDCAParamsValid = + postAssocReqParam->addBssParams.highPerformance; + WDA_UpdateEdcaParamsForAC(pWDA, + &wdiPostAssocReqParam->wdiBSSParams.wdiBEEDCAParams, + &postAssocReqParam->addBssParams.acbe); + WDA_UpdateEdcaParamsForAC(pWDA, + &wdiPostAssocReqParam->wdiBSSParams.wdiBKEDCAParams, + &postAssocReqParam->addBssParams.acbk); + WDA_UpdateEdcaParamsForAC(pWDA, + &wdiPostAssocReqParam->wdiBSSParams.wdiVIEDCAParams, + &postAssocReqParam->addBssParams.acvi); + WDA_UpdateEdcaParamsForAC(pWDA, + &wdiPostAssocReqParam->wdiBSSParams.wdiVOEDCAParams, + &postAssocReqParam->addBssParams.acvo); + /* Store Init Req pointer, as this will be used for response */ + pWDA->wdaMsgParam = (void *)postAssocReqParam ; + /* store Params pass it to WDI */ + pWDA->wdaWdiApiMsgParam = (void *)wdiPostAssocReqParam ; + status = WDI_PostAssocReq(wdiPostAssocReqParam, + (WDI_PostAssocRspCb )WDA_PostAssocReqCallback, pWDA) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Post Assoc WDI API, free all the memory " ); + vos_mem_free(pWDA->wdaWdiApiMsgParam) ; + pWDA->wdaWdiApiMsgParam = NULL; + pWDA->wdaMsgParam = NULL; + postAssocReqParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_POST_ASSOC_RSP, (void *)postAssocReqParam, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif +/* + * FUNCTION: WDA_AddStaRspCallback + * ADD STA req callback, send RSP back to PE + */ +void WDA_AddStaRspCallback(WDI_ConfigSTARspParamsType *wdiConfigStaRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddStaParams *addStaReqParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,"%s: pWdaParams is NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + addStaReqParam = (tAddStaParams *)pWdaParams->wdaMsgParam; + addStaReqParam->status = + wdiConfigStaRsp->wdiStatus ; + if(WDI_STATUS_SUCCESS == wdiConfigStaRsp->wdiStatus) + { + addStaReqParam->staIdx = wdiConfigStaRsp->ucSTAIdx; + /*TODO: UMAC structure doesn't have these fields*/ + /*addStaReqParam-> = wdiConfigStaRsp->ucDpuIndex; + addStaReqParam-> = wdiConfigStaRsp->ucBcastDpuIndex; + addStaReqParam-> = wdiConfigStaRsp->ucBcastMgmtDpuIdx; */ + addStaReqParam->ucUcastSig = wdiConfigStaRsp->ucUcastSig; + addStaReqParam->ucBcastSig = wdiConfigStaRsp->ucBcastSig; + /* update staIndex as valid index for BA if STA is HT capable*/ +#ifdef FEATURE_WLAN_TDLS + if( (addStaReqParam->staType == STA_ENTRY_PEER || + addStaReqParam->staType == STA_ENTRY_TDLS_PEER) && addStaReqParam->htCapable) +#else + if(addStaReqParam->staType == STA_ENTRY_PEER && addStaReqParam->htCapable) +#endif + { + pWDA->wdaStaInfo[addStaReqParam->staIdx].bssIdx = + wdiConfigStaRsp->ucBssIdx; + pWDA->wdaStaInfo[addStaReqParam->staIdx].ucValidStaIndex = + WDA_VALID_STA_INDEX ; + pWDA->wdaStaInfo[addStaReqParam->staIdx].currentOperChan = + addStaReqParam->currentOperChan; + } + if(WDI_DS_AddSTAMemPool(pWDA->pWdiContext, wdiConfigStaRsp->ucSTAIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: add STA into mempool fail", __func__); + VOS_ASSERT(0) ; + return ; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d", __func__, + wdiConfigStaRsp->wdiStatus); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + FALSE, TRUE); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams) ; + WDA_SendMsg(pWDA, WDA_ADD_STA_RSP, (void *)addStaReqParam, 0) ; + return ; +} +void WDA_AddStaReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddStaParams *addStaParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", + __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + addStaParams = (tAddStaParams *)pWdaParams->wdaMsgParam; + + addStaParams->status = wdiStatus; + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + FALSE, TRUE); + WDA_SendMsg(pWDA, WDA_ADD_STA_RSP, (void *)addStaParams , 0); + } + + return ; +} + +/* + * FUNCTION: WDA_ConfigStaReq + * Trigger Config STA processing in WDI + */ +VOS_STATUS WDA_ProcessAddStaReq(tWDA_CbContext *pWDA, + tAddStaParams *addStaReqParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_ConfigSTAReqParamsType *wdiConfigStaReqParam = + (WDI_ConfigSTAReqParamsType *)vos_mem_malloc( + sizeof(WDI_ConfigSTAReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiConfigStaReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiConfigStaReqParam); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(wdiConfigStaReqParam, sizeof(WDI_ConfigSTAReqParamsType), 0); + /* update STA params into WDI structure */ + WDA_UpdateSTAParams(pWDA, &wdiConfigStaReqParam->wdiReqInfo, + addStaReqParam) ; + wdiConfigStaReqParam->wdiReqStatusCB = WDA_AddStaReqCallback; + wdiConfigStaReqParam->pUserData = pWdaParams; + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = addStaReqParam; + pWdaParams->wdaWdiApiMsgParam = wdiConfigStaReqParam; + + status = WDI_ConfigSTAReq(wdiConfigStaReqParam, + (WDI_ConfigSTARspCb )WDA_AddStaRspCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Config STA WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + addStaReqParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_ADD_STA_RSP, (void *)addStaReqParam, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#ifdef SAP_AUTH_OFFLOAD + +/** + * WDA_ProcessSapAuthOffloadAddStaReq(): process add sta command. + * + * @pWDA: WDA Call back context + * @addStaReqParam: Add sta request params + * + * This function process sta params and store them to WDA layer. + * It will register station entry to mempool as well. + * As station is already in associated state in firmware this + * function doesnt send any request to firmware and wait for response, + * instead of that this function will send response from here. + * + * Return: Return VOS_STATUS + */ +VOS_STATUS WDA_ProcessSapAuthOffloadAddStaReq(tWDA_CbContext *pWDA, + tAddStaParams *addStaReqParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_AddStaParams wdiAddSTAParam = {0}; + WDI_ConfigSTAReqParamsType *wdiConfigStaReqParam = + (WDI_ConfigSTAReqParamsType *)vos_mem_malloc( + sizeof(WDI_ConfigSTAReqParamsType)) ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if (NULL == wdiConfigStaReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_set(wdiConfigStaReqParam, sizeof(WDI_ConfigSTAReqParamsType), 0); + /* update STA params into WDI structure */ + WDA_UpdateSTAParams(pWDA, &wdiConfigStaReqParam->wdiReqInfo, + addStaReqParam); + wdiAddSTAParam.ucSTAIdx = wdiConfigStaReqParam->wdiReqInfo.staIdx; + wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_PEER; + /* MAC Address of STA */ + wpalMemoryCopy(wdiAddSTAParam.staMacAddr, + wdiConfigStaReqParam->wdiReqInfo.macSTA, + WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(wdiAddSTAParam.macBSSID, + wdiConfigStaReqParam->wdiReqInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + wdiAddSTAParam.dpuIndex = addStaReqParam->dpuIndex; + wdiAddSTAParam.dpuSig = addStaReqParam->ucUcastSig; + wdiAddSTAParam.bcastDpuIndex = addStaReqParam->bcastDpuIndex; + wdiAddSTAParam.bcastDpuSignature = addStaReqParam->ucBcastSig; + wdiAddSTAParam.bcastMgmtDpuIndex = addStaReqParam->bcastMgmtDpuIdx; + wdiAddSTAParam.bcastMgmtDpuSignature = addStaReqParam->ucMgmtSig; + wdiAddSTAParam.ucWmmEnabled = addStaReqParam->wmmEnabled; + wdiAddSTAParam.ucRmfEnabled = addStaReqParam->rmfEnabled; + wdiAddSTAParam.ucBSSIdx = addStaReqParam->bssIdx; + wdiAddSTAParam.ucHTCapable = addStaReqParam->htCapable; + + + WDI_STATableAddSta(pWDA->pWdiContext, &wdiAddSTAParam); + pWDA->wdaStaInfo[wdiConfigStaReqParam->wdiReqInfo.staIdx].ucValidStaIndex = + WDA_VALID_STA_INDEX; + pWDA->wdaStaInfo[wdiConfigStaReqParam->wdiReqInfo.staIdx].currentOperChan = + addStaReqParam->currentOperChan; + + if (WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDA->pWdiContext, + wdiConfigStaReqParam->wdiReqInfo.macSTA, + (wpt_uint8 *)&wdiConfigStaReqParam->wdiReqInfo.staIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failed to get selfStaIdx!", __func__); + } + if (WDI_DS_AddSTAMemPool(pWDA->pWdiContext, + wdiConfigStaReqParam->wdiReqInfo.staIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: add STA into mempool fail", __func__); + VOS_ASSERT(0) ; + } + vos_mem_free(wdiConfigStaReqParam); + WDA_SendMsg(pWDA, WDA_ADD_STA_RSP, (void *)addStaReqParam, 0) ; + return status; +} +#endif +/* + * FUNCTION: WDA_DelBSSRspCallback + * Dens DEL BSS RSP back to PE + */ +void WDA_DelBSSRspCallback(WDI_DelBSSRspParamsType *wdiDelBssRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDeleteBssParams *delBssReqParam; + tANI_U8 staIdx,tid; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + delBssReqParam = (tDeleteBssParams *)pWdaParams->wdaMsgParam; + delBssReqParam->status = wdiDelBssRsp->wdiStatus ; + if(WDI_STATUS_SUCCESS == wdiDelBssRsp->wdiStatus) + { + vos_mem_copy(delBssReqParam->bssid, wdiDelBssRsp->macBSSID, + sizeof(tSirMacAddr)) ; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d", __func__, + wdiDelBssRsp->wdiStatus); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + FALSE, TRUE); + } + if(WDI_DS_GetStaIdxFromBssIdx(pWDA->pWdiContext, delBssReqParam->bssIdx, &staIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Get STA index from BSS index Fail", __func__); + VOS_ASSERT(0) ; + } + if(WDI_DS_DelSTAMemPool(pWDA->pWdiContext, staIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: DEL STA from MemPool Fail", __func__); + VOS_ASSERT(0) ; + } + if(WDI_DS_ClearStaIdxPerBssIdx(pWDA->pWdiContext, delBssReqParam->bssIdx, staIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Clear STA index form table Fail", __func__); + VOS_ASSERT(0) ; + } + + WLANTL_StartForwarding(staIdx,0,0); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* reset the the system role*/ + pWDA->wdaGlobalSystemRole = eSYSTEM_UNKNOWN_ROLE; + + /* Reset the BA related information */ + for(staIdx=0; staIdx < WDA_MAX_STA; staIdx++) + { + if( pWDA->wdaStaInfo[staIdx].bssIdx == wdiDelBssRsp->ucBssIdx ) + { + pWDA->wdaStaInfo[staIdx].ucValidStaIndex = WDA_INVALID_STA_INDEX; + pWDA->wdaStaInfo[staIdx].ucUseBaBitmap = 0; + pWDA->wdaStaInfo[staIdx].currentOperChan = 0; + /* Reset framesTxed counters here */ + for(tid = 0; tid < STACFG_MAX_TC; tid++) + { + pWDA->wdaStaInfo[staIdx].framesTxed[tid] = 0; + } + } + } + + WDA_SendMsg(pWDA, WDA_DELETE_BSS_RSP, (void *)delBssReqParam , 0) ; + return ; +} +void WDA_DelBSSReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDeleteBssParams *delbssParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", + __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + delbssParams = (tDeleteBssParams *)pWdaParams->wdaMsgParam; + + delbssParams->status = wdiStatus ; + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + FALSE, TRUE); + WDA_SendMsg(pWDA, WDA_DELETE_BSS_RSP, (void *)delbssParams , 0) ; + } + + return ; +} + +/* + * FUNCTION: WDA_ProcessDelBssReq + * Init DEL BSS req with WDI + */ +VOS_STATUS WDA_ProcessDelBssReq(tWDA_CbContext *pWDA, + tDeleteBssParams *delBssParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_DelBSSReqParamsType *wdiDelBssReqParam = + (WDI_DelBSSReqParamsType *)vos_mem_malloc( + sizeof(WDI_DelBSSReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiDelBssReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiDelBssReqParam); + return VOS_STATUS_E_NOMEM; + } + wdiDelBssReqParam->ucBssIdx = delBssParam->bssIdx; + wdiDelBssReqParam->wdiReqStatusCB = WDA_DelBSSReqCallback ; + wdiDelBssReqParam->pUserData = pWdaParams; + + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = delBssParam; + pWdaParams->wdaWdiApiMsgParam = wdiDelBssReqParam; + + status = WDI_DelBSSReq(wdiDelBssReqParam, + (WDI_DelBSSRspCb )WDA_DelBSSRspCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Del BSS WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + delBssParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_DELETE_BSS_RSP, (void *)delBssParam, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_DelSTARspCallback + * Dens DEL STA RSP back to PE + */ +void WDA_DelSTARspCallback(WDI_DelSTARspParamsType *wdiDelStaRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDeleteStaParams *delStaReqParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + delStaReqParam = (tDeleteStaParams *)pWdaParams->wdaMsgParam; + delStaReqParam->status = wdiDelStaRsp->wdiStatus ; + if(WDI_STATUS_SUCCESS == wdiDelStaRsp->wdiStatus) + { + if(WDI_DS_DelSTAMemPool(pWDA->pWdiContext, wdiDelStaRsp->ucSTAIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: DEL STA from MemPool Fail", __func__); + VOS_ASSERT(0) ; + } + delStaReqParam->staIdx = wdiDelStaRsp->ucSTAIdx ; + WLANTL_StartForwarding(delStaReqParam->staIdx,0,0); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d", __func__, + wdiDelStaRsp->wdiStatus); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + FALSE, TRUE); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /*Reset the BA information corresponding to this STAIdx */ + pWDA->wdaStaInfo[wdiDelStaRsp->ucSTAIdx].ucValidStaIndex = + WDA_INVALID_STA_INDEX; + pWDA->wdaStaInfo[wdiDelStaRsp->ucSTAIdx].ucUseBaBitmap = 0; + pWDA->wdaStaInfo[wdiDelStaRsp->ucSTAIdx].currentOperChan = 0; + WDA_SendMsg(pWDA, WDA_DELETE_STA_RSP, (void *)delStaReqParam , 0) ; + return ; +} +void WDA_DelSTAReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDeleteStaParams *delStaParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", + __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + delStaParams = (tDeleteStaParams *)pWdaParams->wdaMsgParam; + + delStaParams->status = wdiStatus ; + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + FALSE, TRUE); + WDA_SendMsg(pWDA, WDA_DELETE_STA_RSP, (void *)delStaParams , 0) ; + } + + return ; +} + +#ifdef SAP_AUTH_OFFLOAD +/** + * WDA_ProcessSapAuthOffloadDelStaReq(): process del sta command. + * + * @pWDA: WDA Call back context + * @delStaParam: Del sta request params + * + * This function process sta params and remove entry from WDA layer. + * It will unregister station entry from mempool as well. + * As station is already in disassociated state in firmware this + * function doesn't send any request to firmware and wait for response, + * instead of that this function will send response from here. + * + * Return: Return VOS_STATUS + */ +void WDA_ProcessSapAuthOffloadDelStaReq(tWDA_CbContext *pWDA, + tDeleteStaParams *delStaParam) + +{ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if (WDI_DS_DelSTAMemPool(pWDA->pWdiContext, delStaParam->staIdx)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: DEL STA from MemPool Fail", __func__); + // VOS_ASSERT(0) ; + } + WLANTL_StartForwarding(delStaParam->staIdx, 0, 0); + WDI_STATableDelSta(pWDA->pWdiContext, delStaParam->staIdx); + pWDA->wdaStaInfo[delStaParam->staIdx].ucValidStaIndex = + WDA_INVALID_STA_INDEX; + pWDA->wdaStaInfo[delStaParam->staIdx].currentOperChan = 0; + pWDA->wdaStaInfo[delStaParam->staIdx].ucUseBaBitmap = 0; + WDA_SendMsg(pWDA, WDA_DELETE_STA_RSP, (void *)delStaParam, 0); + return ; +} +#endif + +/* + * FUNCTION: WDA_ProcessDelStaReq + * Init DEL STA req with WDI + */ +VOS_STATUS WDA_ProcessDelStaReq(tWDA_CbContext *pWDA, + tDeleteStaParams *delStaParam) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_DelSTAReqParamsType *wdiDelStaReqParam = + (WDI_DelSTAReqParamsType *)vos_mem_malloc( + sizeof(WDI_DelSTAReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiDelStaReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiDelStaReqParam); + return VOS_STATUS_E_NOMEM; + } + wdiDelStaReqParam->ucSTAIdx = delStaParam->staIdx ; + wdiDelStaReqParam->wdiReqStatusCB = WDA_DelSTAReqCallback ; + wdiDelStaReqParam->pUserData = pWdaParams; + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = delStaParam; + pWdaParams->wdaWdiApiMsgParam = wdiDelStaReqParam; + + status = WDI_DelSTAReq(wdiDelStaReqParam, + (WDI_DelSTARspCb )WDA_DelSTARspCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Del STA WDI API, free all the memory status = %d", + status ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + delStaParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_DELETE_STA_RSP, (void *)delStaParam, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +void WDA_ProcessAddStaSelfRspCallback(WDI_AddSTASelfRspParamsType* pwdiAddSTASelfRsp, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddStaSelfParams *pAddStaSelfRsp = NULL; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pAddStaSelfRsp = (tAddStaSelfParams*)pWdaParams->wdaMsgParam; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pAddStaSelfRsp->status = CONVERT_WDI2SIR_STATUS(pwdiAddSTASelfRsp->wdiStatus); + vos_mem_copy(pAddStaSelfRsp->selfMacAddr, + pwdiAddSTASelfRsp->macSelfSta, + sizeof(pAddStaSelfRsp->selfMacAddr)); + pWDA->wdaAddSelfStaParams.ucSTASelfIdx = pwdiAddSTASelfRsp->ucSTASelfIdx; + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaRspCounter++; + if (pAddStaSelfRsp->status == eSIR_FAILURE) + { + pWDA->wdaAddSelfStaParams.wdaAddSelfStaFailReason = WDA_ADDSTA_RSP_WDI_FAIL; + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter++; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d failcnter %d", __func__, + pwdiAddSTASelfRsp->wdiStatus, + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + FALSE, TRUE); + } + WDA_SendMsg( pWDA, WDA_ADD_STA_SELF_RSP, (void *)pAddStaSelfRsp, 0) ; + return ; +} +void WDA_ProcessAddStaSelfReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddStaSelfParams *addStaSelfParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", + __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + addStaSelfParams = (tAddStaSelfParams *)pWdaParams->wdaMsgParam; + + addStaSelfParams->status = wdiStatus ; + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pWDA->wdaAddSelfStaParams.wdaAddSelfStaFailReason + = WDA_ADDSTA_REQ_WDI_FAIL; + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter++; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d failcnter %d", __func__, + wdiStatus, + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ADD_BSS_STA_FAIL, + FALSE, TRUE); + WDA_SendMsg(pWDA, WDA_ADD_STA_SELF_RSP, (void *)addStaSelfParams , 0); + } + + return ; +} + +/* + * FUNCTION: WDA_ProcessAddStaSelfReq + * + */ +VOS_STATUS WDA_ProcessAddStaSelfReq( tWDA_CbContext *pWDA, tpAddStaSelfParams pAddStaSelfReq) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_AddSTASelfReqParamsType *wdiAddStaSelfReq = + (WDI_AddSTASelfReqParamsType *)vos_mem_malloc( + sizeof(WDI_AddSTASelfReqParamsType)) ; + tWDA_ReqParams *pWdaParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaReqCounter++; + if( NULL == wdiAddStaSelfReq ) + { + VOS_ASSERT( 0 ); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate memory " ,__func__); + pWDA->wdaAddSelfStaParams.wdaAddSelfStaFailReason = WDA_ADDSTA_REQ_NO_MEM; + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter++; + return( VOS_STATUS_E_NOMEM ); + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if( NULL == pWdaParams ) + { + VOS_ASSERT( 0 ); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate memory " ,__func__); + pWDA->wdaAddSelfStaParams.wdaAddSelfStaFailReason = WDA_ADDSTA_REQ_NO_MEM; + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter++; + vos_mem_free(wdiAddStaSelfReq) ; + return( VOS_STATUS_E_NOMEM ); + } + wdiAddStaSelfReq->wdiReqStatusCB = WDA_ProcessAddStaSelfReqCallback; + wdiAddStaSelfReq->pUserData = pWdaParams; + vos_mem_copy( wdiAddStaSelfReq->wdiAddSTASelfInfo.selfMacAddr, pAddStaSelfReq->selfMacAddr, 6); + wdiAddStaSelfReq->wdiAddSTASelfInfo.currDeviceMode = pAddStaSelfReq->currDeviceMode; + /* Store Init Req pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pAddStaSelfReq; + pWdaParams->wdaWdiApiMsgParam = wdiAddStaSelfReq; + + wstatus = WDI_AddSTASelfReq( wdiAddStaSelfReq, + WDA_ProcessAddStaSelfRspCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Add Self Sta Request API, free all the memory status = %d", + wstatus ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pWDA->wdaAddSelfStaParams.wdaAddSelfStaFailReason = WDA_ADDSTA_REQ_WDI_FAIL; + pWDA->wdaAddSelfStaParams.wdiAddStaSelfStaFailCounter++; + pAddStaSelfReq->status = eSIR_FAILURE ; + WDA_SendMsg( pWDA, WDA_ADD_STA_SELF_RSP, (void *)pAddStaSelfReq, 0) ; + } + return status; +} +/* + * FUNCTION: WDA_DelSTASelfRespCallback + * + */ +void WDA_DelSTASelfRespCallback(WDI_DelSTASelfRspParamsType * + wdiDelStaSelfRspParams , void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDelStaSelfParams *delStaSelfParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + delStaSelfParams = (tDelStaSelfParams *)pWdaParams->wdaMsgParam; + delStaSelfParams->status = + wdiDelStaSelfRspParams->wdiStatus ; + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + if (WDI_STATUS_SUCCESS != delStaSelfParams->status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure with status %d", __func__, + wdiDelStaSelfRspParams->wdiStatus); + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + FALSE, TRUE); + } + WDA_SendMsg(pWDA, WDA_DEL_STA_SELF_RSP, (void *)delStaSelfParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_DelSTASelfReqCallback + * + */ +void WDA_DelSTASelfReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDelStaSelfParams *delStaSelfParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d pWdaParams: %p", + __func__, wdiStatus, pWdaParams); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + delStaSelfParams = (tDelStaSelfParams *)pWdaParams->wdaMsgParam; + + delStaSelfParams->status = wdiStatus ; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_DEL_BSS_STA_FAIL, + FALSE, TRUE); + WDA_SendMsg(pWDA, WDA_DEL_STA_SELF_RSP, (void *)delStaSelfParams , 0) ; + } + + return ; +} + +/* + * FUNCTION: WDA_DelSTASelfReq + * Trigger Config STA processing in WDI + */ +VOS_STATUS WDA_ProcessDelSTASelfReq(tWDA_CbContext *pWDA, + tDelStaSelfParams* pDelStaSelfReqParam) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + tWDA_ReqParams *pWdaParams = NULL; + WDI_DelSTASelfReqParamsType *wdiDelStaSelfReq = + (WDI_DelSTASelfReqParamsType *)vos_mem_malloc( + sizeof(WDI_DelSTASelfReqParamsType)) ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if( NULL == wdiDelStaSelfReq ) + { + VOS_ASSERT( 0 ); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate memory " ,__func__); + return( VOS_STATUS_E_NOMEM ); + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if( NULL == pWdaParams ) + { + VOS_ASSERT( 0 ); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate memory " ,__func__); + vos_mem_free(wdiDelStaSelfReq) ; + return( VOS_STATUS_E_NOMEM ); + } + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pDelStaSelfReqParam; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiDelStaSelfReq; + vos_mem_copy( wdiDelStaSelfReq->wdiDelStaSelfInfo.selfMacAddr, + pDelStaSelfReqParam->selfMacAddr, sizeof(tSirMacAddr)); + + wdiDelStaSelfReq->wdiReqStatusCB = WDA_DelSTASelfReqCallback; + wdiDelStaSelfReq->pUserData = pWdaParams; + + wstatus = WDI_DelSTASelfReq(wdiDelStaSelfReq, + (WDI_DelSTASelfRspCb)WDA_DelSTASelfRespCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "Failure in Del Sta Self REQ WDI API, free all the memory " ); + VOS_ASSERT(0); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pDelStaSelfReqParam->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_DEL_STA_SELF_RSP, (void *)pDelStaSelfReqParam, 0) ; + } + return status; +} + +/* + * FUNCTION: WDA_SendMsg + * Send Message back to PE + */ +void WDA_SendMsg(tWDA_CbContext *pWDA, tANI_U16 msgType, + void *pBodyptr, tANI_U32 bodyVal) +{ + tSirMsgQ msg = {0} ; + tANI_U32 status = VOS_STATUS_SUCCESS ; + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + msg.type = msgType; + msg.bodyval = bodyVal; + msg.bodyptr = pBodyptr; + status = limPostMsgApi(pMac, &msg); + if (VOS_STATUS_SUCCESS != status) + { + if(NULL != pBodyptr) + { + vos_mem_free(pBodyptr); + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: limPostMsgApi is failed " ,__func__); + VOS_ASSERT(0) ; + } + return ; +} +/* + * FUNCTION: WDA_UpdateBSSParams + * Translated WDA/PE BSS info into WDI BSS info.. + */ +void WDA_UpdateBSSParams(tWDA_CbContext *pWDA, + WDI_ConfigBSSReqInfoType *wdiBssParams, + tAddBssParams *wdaBssParams) +{ + v_U8_t keyIndex = 0; + v_U8_t i = 0; + + /* copy bssReq Params to WDI structure */ + vos_mem_copy(wdiBssParams->macBSSID, + wdaBssParams->bssId, sizeof(tSirMacAddr)) ; + vos_mem_copy(wdiBssParams->macSelfAddr, wdaBssParams->selfMacAddr, + sizeof(tSirMacAddr)) ; + wdiBssParams->wdiBSSType = wdaBssParams->bssType ; + wdiBssParams->ucOperMode = wdaBssParams->operMode ; + wdiBssParams->wdiNWType = wdaBssParams->nwType ; + wdiBssParams->ucShortSlotTimeSupported = + wdaBssParams->shortSlotTimeSupported ; + wdiBssParams->ucllaCoexist = wdaBssParams->llaCoexist ; + wdiBssParams->ucllbCoexist = wdaBssParams->llbCoexist ; + wdiBssParams->ucllgCoexist = wdaBssParams->llgCoexist ; + wdiBssParams->ucHT20Coexist = wdaBssParams->ht20Coexist ; + wdiBssParams->ucObssProtEnabled = wdaBssParams->obssProtEnabled ; + + wdiBssParams->ucllnNonGFCoexist = wdaBssParams->llnNonGFCoexist ; + wdiBssParams->ucTXOPProtectionFullSupport = + wdaBssParams->fLsigTXOPProtectionFullSupport ; + wdiBssParams->ucRIFSMode = wdaBssParams->fRIFSMode ; + wdiBssParams->usBeaconInterval = wdaBssParams->beaconInterval ; + wdiBssParams->ucDTIMPeriod = wdaBssParams->dtimPeriod ; + wdiBssParams->ucTXChannelWidthSet = wdaBssParams->txChannelWidthSet ; + wdiBssParams->ucCurrentOperChannel = wdaBssParams->currentOperChannel ; + wdiBssParams->ucCurrentExtChannel = wdaBssParams->currentExtChannel ; + wdiBssParams->bHiddenSSIDEn = wdaBssParams->bHiddenSSIDEn ; + + wdiBssParams->ucRMFEnabled = wdaBssParams->rmfEnabled; + + /* copy SSID into WDI structure */ + wdiBssParams->wdiSSID.ucLength = wdaBssParams->ssId.length ; + vos_mem_copy(wdiBssParams->wdiSSID.sSSID, + wdaBssParams->ssId.ssId, wdaBssParams->ssId.length) ; + WDA_UpdateSTAParams(pWDA, &wdiBssParams->wdiSTAContext, + &wdaBssParams->staContext) ; + wdiBssParams->wdiAction = wdaBssParams->updateBss; +#ifdef WLAN_FEATURE_VOWIFI + wdiBssParams->cMaxTxPower = wdaBssParams->maxTxPower; +#endif + wdiBssParams->ucPersona = wdaBssParams->halPersona; + wdiBssParams->bSpectrumMgtEn = wdaBssParams->bSpectrumMgtEnabled; +#ifdef WLAN_FEATURE_VOWIFI_11R + wdiBssParams->bExtSetStaKeyParamValid = wdaBssParams->extSetStaKeyParamValid; + if(wdiBssParams->bExtSetStaKeyParamValid) + { + /* copy set STA key params to WDI structure */ + wdiBssParams->wdiExtSetKeyParam.ucSTAIdx = + wdaBssParams->extSetStaKeyParam.staIdx; + wdiBssParams->wdiExtSetKeyParam.wdiEncType = + wdaBssParams->extSetStaKeyParam.encType; + wdiBssParams->wdiExtSetKeyParam.wdiWEPType = + wdaBssParams->extSetStaKeyParam.wepType; + wdiBssParams->wdiExtSetKeyParam.ucDefWEPIdx = + wdaBssParams->extSetStaKeyParam.defWEPIdx; + if(wdaBssParams->extSetStaKeyParam.encType != eSIR_ED_NONE) + { + if( (wdiBssParams->wdiExtSetKeyParam.wdiWEPType == WDI_WEP_STATIC) && + (WDA_INVALID_KEY_INDEX == wdaBssParams->extSetStaKeyParam.defWEPIdx) && + (eSYSTEM_AP_ROLE != pWDA->wdaGlobalSystemRole)) + { + WDA_GetWepKeysFromCfg( pWDA, + &wdiBssParams->wdiExtSetKeyParam.ucDefWEPIdx, + &wdiBssParams->wdiExtSetKeyParam.ucNumKeys, + wdiBssParams->wdiExtSetKeyParam.wdiKey ); + } + else + { + for( keyIndex=0; keyIndex < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + keyIndex++) + { + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].keyId = + wdaBssParams->extSetStaKeyParam.key[keyIndex].keyId; + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].unicast = + wdaBssParams->extSetStaKeyParam.key[keyIndex].unicast; + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].keyDirection = + wdaBssParams->extSetStaKeyParam.key[keyIndex].keyDirection; + + if(WDA_getHostWlanFeatCaps(DISA) && WDA_getFwWlanFeatCaps(DISA)) + { + for (i = 0; i < WLAN_MAX_KEY_RSC_LEN; i ++) + { + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].keyRsc[i] = + ~(wdaBssParams->extSetStaKeyParam.key[keyIndex].keyRsc[i]); + } + + for (i = 0; i < SIR_MAC_MAX_KEY_LENGTH; i++) + { + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].key[i] = + ~(wdaBssParams->extSetStaKeyParam.key[keyIndex].key[i]); + } + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("%s: Negated Keys"), __func__); + } + else + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("%s: No change in Keys "), __func__); + vos_mem_copy( + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].keyRsc, + wdaBssParams->extSetStaKeyParam.key[keyIndex].keyRsc, + WLAN_MAX_KEY_RSC_LEN); + vos_mem_copy( + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].key, + wdaBssParams->extSetStaKeyParam.key[keyIndex].key, + SIR_MAC_MAX_KEY_LENGTH); + } + + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].paeRole = + wdaBssParams->extSetStaKeyParam.key[keyIndex].paeRole; + wdiBssParams->wdiExtSetKeyParam.wdiKey[keyIndex].keyLength = + wdaBssParams->extSetStaKeyParam.key[keyIndex].keyLength; + } + wdiBssParams->wdiExtSetKeyParam.ucNumKeys = + SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + } + } + wdiBssParams->wdiExtSetKeyParam.ucSingleTidRc = wdaBssParams->extSetStaKeyParam.singleTidRc; + } + else /* wdaBssParams->bExtSetStaKeyParamValid is not valid */ + { + vos_mem_zero( &wdaBssParams->extSetStaKeyParam, + sizeof(wdaBssParams->extSetStaKeyParam) ); + } +#endif /*WLAN_FEATURE_VOWIFI_11R*/ +#ifdef WLAN_FEATURE_11AC + wdiBssParams->ucVhtCapableSta = wdaBssParams->vhtCapable; + wdiBssParams->ucVhtTxChannelWidthSet = wdaBssParams->vhtTxChannelWidthSet; +#endif + + return ; +} +/* + * FUNCTION: WDA_UpdateSTAParams + * Translated WDA/PE BSS info into WDI BSS info.. + */ +void WDA_UpdateSTAParams(tWDA_CbContext *pWDA, + WDI_ConfigStaReqInfoType *wdiStaParams, + tAddStaParams *wdaStaParams) +{ + tANI_U8 i = 0; + /* Update STA params */ + vos_mem_copy(wdiStaParams->macBSSID, wdaStaParams->bssId, + sizeof(tSirMacAddr)) ; + wdiStaParams->usAssocId = wdaStaParams->assocId; + wdiStaParams->wdiSTAType = wdaStaParams->staType; + wdiStaParams->staIdx = wdaStaParams->staIdx; + + wdiStaParams->ucShortPreambleSupported = + wdaStaParams->shortPreambleSupported; + vos_mem_copy(wdiStaParams->macSTA, wdaStaParams->staMac, + sizeof(tSirMacAddr)) ; + wdiStaParams->usListenInterval = wdaStaParams->listenInterval; + + wdiStaParams->ucWMMEnabled = wdaStaParams->wmmEnabled; + + wdiStaParams->ucHTCapable = wdaStaParams->htCapable; + wdiStaParams->ucTXChannelWidthSet = wdaStaParams->txChannelWidthSet; + wdiStaParams->ucRIFSMode = wdaStaParams->rifsMode; + wdiStaParams->ucLSIGTxopProtection = wdaStaParams->lsigTxopProtection; + wdiStaParams->ucMaxAmpduSize = wdaStaParams->maxAmpduSize; + wdiStaParams->ucMaxAmpduDensity = wdaStaParams->maxAmpduDensity; + wdiStaParams->ucMaxAmsduSize = wdaStaParams->maxAmsduSize; + + wdiStaParams->ucShortGI40Mhz = wdaStaParams->fShortGI40Mhz; + wdiStaParams->ucShortGI20Mhz = wdaStaParams->fShortGI20Mhz; + wdiStaParams->wdiSupportedRates.opRateMode = + wdaStaParams->supportedRates.opRateMode; + for(i = 0;i < WDI_NUM_11B_RATES;i++) + { + wdiStaParams->wdiSupportedRates.llbRates[i] = + wdaStaParams->supportedRates.llbRates[i]; + } + for(i = 0;i < WDI_NUM_11A_RATES;i++) + { + wdiStaParams->wdiSupportedRates.llaRates[i] = + wdaStaParams->supportedRates.llaRates[i]; + } + for(i = 0;i < SIR_NUM_POLARIS_RATES;i++) + { + wdiStaParams->wdiSupportedRates.aLegacyRates[i] = + wdaStaParams->supportedRates.aniLegacyRates[i]; + } + wdiStaParams->wdiSupportedRates.uEnhancedRateBitmap = + wdaStaParams->supportedRates.aniEnhancedRateBitmap; +#ifdef WLAN_FEATURE_11AC + wdiStaParams->wdiSupportedRates.vhtRxMCSMap = wdaStaParams->supportedRates.vhtRxMCSMap; + wdiStaParams->wdiSupportedRates.vhtRxHighestDataRate = wdaStaParams->supportedRates.vhtRxHighestDataRate; + wdiStaParams->wdiSupportedRates.vhtTxMCSMap = wdaStaParams->supportedRates.vhtTxMCSMap; + wdiStaParams->wdiSupportedRates.vhtTxHighestDataRate = wdaStaParams->supportedRates.vhtTxHighestDataRate; +#endif + for(i = 0;i wdiSupportedRates.aSupportedMCSSet[i] = + wdaStaParams->supportedRates.supportedMCSSet[i]; + } + wdiStaParams->wdiSupportedRates.aRxHighestDataRate = + wdaStaParams->supportedRates.rxHighestDataRate; + + wdiStaParams->ucRMFEnabled = wdaStaParams->rmfEnabled; + + wdiStaParams->wdiAction = wdaStaParams->updateSta; + + wdiStaParams->ucAPSD = wdaStaParams->uAPSD; + wdiStaParams->ucMaxSPLen = wdaStaParams->maxSPLen; + wdiStaParams->ucGreenFieldCapable = wdaStaParams->greenFieldCapable; + + wdiStaParams->ucDelayedBASupport = wdaStaParams->delBASupport; + wdiStaParams->us32MaxAmpduDuratio = wdaStaParams->us32MaxAmpduDuration; + wdiStaParams->ucDsssCckMode40Mhz = wdaStaParams->fDsssCckMode40Mhz; + wdiStaParams->ucEncryptType = wdaStaParams->encryptType; + wdiStaParams->ucP2pCapableSta = wdaStaParams->p2pCapableSta; +#ifdef WLAN_FEATURE_11AC + wdiStaParams->ucVhtCapableSta = wdaStaParams->vhtCapable; + wdiStaParams->ucVhtTxChannelWidthSet = wdaStaParams->vhtTxChannelWidthSet; + wdiStaParams->ucVhtTxBFEnabled = wdaStaParams->vhtTxBFCapable; + wdiStaParams->vhtTxMUBformeeCapable = wdaStaParams->vhtTxMUBformeeCapable; + /* When MU vhtTxMUBformeeCapable is set, SU ucVhtTxBFEnabled + * must be set by default */ + if ( wdiStaParams->vhtTxMUBformeeCapable ) + wdiStaParams->ucVhtTxBFEnabled = wdaStaParams->vhtTxMUBformeeCapable; +#endif + wdiStaParams->ucHtLdpcEnabled= wdaStaParams->htLdpcCapable; + wdiStaParams->ucVhtLdpcEnabled = wdaStaParams->vhtLdpcCapable; + return ; +} +/* + * ------------------------------------------------------------------------- + * CFG update to WDI + * ------------------------------------------------------------------------- + */ + + /* + * FUNCTION: WDA_ConvertWniCfgIdToHALCfgId + * Convert the WNI CFG ID to HAL CFG ID + */ +static inline tANI_U16 WDA_ConvertWniCfgIdToHALCfgId(v_U32_t wniCfgId) +{ + switch(wniCfgId) + { + case WNI_CFG_STA_ID: + return QWLAN_HAL_CFG_STA_ID; + case WNI_CFG_CURRENT_TX_ANTENNA: + return QWLAN_HAL_CFG_CURRENT_TX_ANTENNA; + case WNI_CFG_CURRENT_RX_ANTENNA: + return QWLAN_HAL_CFG_CURRENT_RX_ANTENNA; + case WNI_CFG_LOW_GAIN_OVERRIDE: + return QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE; + case WNI_CFG_POWER_STATE_PER_CHAIN: + return QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN; + case WNI_CFG_CAL_PERIOD: + return QWLAN_HAL_CFG_CAL_PERIOD; + case WNI_CFG_CAL_CONTROL: + return QWLAN_HAL_CFG_CAL_CONTROL; + case WNI_CFG_PROXIMITY: + return QWLAN_HAL_CFG_PROXIMITY; + case WNI_CFG_NETWORK_DENSITY: + return QWLAN_HAL_CFG_NETWORK_DENSITY; + case WNI_CFG_MAX_MEDIUM_TIME: + return QWLAN_HAL_CFG_MAX_MEDIUM_TIME; + case WNI_CFG_MAX_MPDUS_IN_AMPDU: + return QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU; + case WNI_CFG_RTS_THRESHOLD: + return QWLAN_HAL_CFG_RTS_THRESHOLD; + case WNI_CFG_SHORT_RETRY_LIMIT: + return QWLAN_HAL_CFG_SHORT_RETRY_LIMIT; + case WNI_CFG_LONG_RETRY_LIMIT: + return QWLAN_HAL_CFG_LONG_RETRY_LIMIT; + case WNI_CFG_FRAGMENTATION_THRESHOLD: + return QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD; + case WNI_CFG_DYNAMIC_THRESHOLD_ZERO: + return QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO; + case WNI_CFG_DYNAMIC_THRESHOLD_ONE: + return QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE; + case WNI_CFG_DYNAMIC_THRESHOLD_TWO: + return QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO; + case WNI_CFG_FIXED_RATE: + return QWLAN_HAL_CFG_FIXED_RATE; + case WNI_CFG_RETRYRATE_POLICY: + return QWLAN_HAL_CFG_RETRYRATE_POLICY; + case WNI_CFG_RETRYRATE_SECONDARY: + return QWLAN_HAL_CFG_RETRYRATE_SECONDARY; + case WNI_CFG_RETRYRATE_TERTIARY: + return QWLAN_HAL_CFG_RETRYRATE_TERTIARY; + case WNI_CFG_FORCE_POLICY_PROTECTION: + return QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION; + case WNI_CFG_FIXED_RATE_MULTICAST_24GHZ: + return QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ; + case WNI_CFG_FIXED_RATE_MULTICAST_5GHZ: + return QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ; + case WNI_CFG_DEFAULT_RATE_INDEX_24GHZ: + return QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ; + case WNI_CFG_DEFAULT_RATE_INDEX_5GHZ: + return QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ; + case WNI_CFG_MAX_BA_SESSIONS: + return QWLAN_HAL_CFG_MAX_BA_SESSIONS; + case WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT: + return QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT; + case WNI_CFG_PS_ENABLE_BCN_FILTER: + return QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER; + case WNI_CFG_PS_ENABLE_RSSI_MONITOR: + return QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR; + case WNI_CFG_NUM_BEACON_PER_RSSI_AVERAGE: + return QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE; + case WNI_CFG_STATS_PERIOD: + return QWLAN_HAL_CFG_STATS_PERIOD; + case WNI_CFG_CFP_MAX_DURATION: + return QWLAN_HAL_CFG_CFP_MAX_DURATION; +#if 0 /*This is not part of CFG*/ + case WNI_CFG_FRAME_TRANS_ENABLED: + return QWLAN_HAL_CFG_FRAME_TRANS_ENABLED; +#endif + case WNI_CFG_DTIM_PERIOD: + return QWLAN_HAL_CFG_DTIM_PERIOD; + case WNI_CFG_EDCA_WME_ACBK: + return QWLAN_HAL_CFG_EDCA_WMM_ACBK; + case WNI_CFG_EDCA_WME_ACBE: + return QWLAN_HAL_CFG_EDCA_WMM_ACBE; + case WNI_CFG_EDCA_WME_ACVI: + return QWLAN_HAL_CFG_EDCA_WMM_ACVI; + case WNI_CFG_EDCA_WME_ACVO: + return QWLAN_HAL_CFG_EDCA_WMM_ACVO; +#if 0 + case WNI_CFG_TELE_BCN_WAKEUP_EN: + return QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN; + case WNI_CFG_TELE_BCN_TRANS_LI: + return QWLAN_HAL_CFG_TELE_BCN_TRANS_LI; + case WNI_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS: + return QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS; + case WNI_CFG_TELE_BCN_MAX_LI: + return QWLAN_HAL_CFG_TELE_BCN_MAX_LI; + case WNI_CFG_TELE_BCN_MAX_LI_IDLE_BCNS: + return QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS; +#endif + case WNI_CFG_ENABLE_CLOSE_LOOP: + return QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP; + case WNI_CFG_ENABLE_LPWR_IMG_TRANSITION: + return QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION; + case WNI_CFG_ENABLE_CONC_BMISS: + return QWLAN_HAL_CFG_CONS_BCNMISS_COUNT; + case WNI_CFG_ENABLE_UNITS_BWAIT: + return QWLAN_HAL_CFG_UNITS_OF_BCN_WAIT_TIME; + case WNI_CFG_ENABLE_RTSCTS_HTVHT: + return QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT; + case WNI_CFG_ENABLE_MC_ADDR_LIST: + return QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST; + case WNI_CFG_HEART_BEAT_THRESHOLD: + return QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD; + + default: + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "There is no HAL CFG Id corresponding to WNI CFG Id: %d", + wniCfgId); + return QWLAN_HAL_CFG_MAX_PARAMS; + } + } +} +/* + * FUNCTION: WDA_UpdateCfgCallback + * + */ +void WDA_UpdateCfgCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)pUserData ; + WDI_UpdateCfgReqParamsType *wdiCfgParam = + (WDI_UpdateCfgReqParamsType *)pWDA->wdaWdiCfgApiMsgParam ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + /* + * currently there is no response message is expected between PE and + * WDA, Failure return from WDI is a ASSERT condition + */ + if(WDI_STATUS_SUCCESS != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: CFG (%d) config failure", __func__, + ((tHalCfg *)(wdiCfgParam->pConfigBuffer))->type); + } + + vos_mem_free(wdiCfgParam->pConfigBuffer) ; + vos_mem_free(pWDA->wdaWdiCfgApiMsgParam) ; + pWDA->wdaWdiCfgApiMsgParam = NULL; + return ; +} +/* + * FUNCTION: WDA_UpdateCfg + * + */ +VOS_STATUS WDA_UpdateCfg(tWDA_CbContext *pWDA, tSirMsgQ *cfgParam) +{ + + WDI_Status status = WDI_STATUS_SUCCESS ; + tANI_U32 val =0; + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext) ; + tHalCfg *configData; + WDI_UpdateCfgReqParamsType *wdiCfgReqParam = NULL ; + tANI_U8 *configDataValue; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if (NULL == pMac ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid MAC context ", __func__ ); + return VOS_STATUS_E_FAILURE; + } + if(WDA_START_STATE != pWDA->wdaState) + { + return VOS_STATUS_E_FAILURE; + } + if(NULL != pWDA->wdaWdiCfgApiMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:wdaWdiCfgApiMsgParam is not NULL", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + wdiCfgReqParam = (WDI_UpdateCfgReqParamsType *)vos_mem_malloc( + sizeof(WDI_UpdateCfgReqParamsType)) ; + if(NULL == wdiCfgReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + wdiCfgReqParam->pConfigBuffer = vos_mem_malloc(sizeof(tHalCfg) + + sizeof(tANI_U32)) ; + if(NULL == wdiCfgReqParam->pConfigBuffer) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(wdiCfgReqParam); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + /*convert the WNI CFG Id to HAL CFG Id*/ + ((tHalCfg *)wdiCfgReqParam->pConfigBuffer)->type = + WDA_ConvertWniCfgIdToHALCfgId(cfgParam->bodyval); + + /*TODO: revisit this for handling string parameters */ + if (wlan_cfgGetInt(pMac, (tANI_U16) cfgParam->bodyval, + &val) != eSIR_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to cfg get id %d", cfgParam->bodyval); + vos_mem_free(wdiCfgReqParam->pConfigBuffer); + vos_mem_free(wdiCfgReqParam); + return eSIR_FAILURE; + } + ((tHalCfg *)wdiCfgReqParam->pConfigBuffer)->length = sizeof(tANI_U32); + configData =((tHalCfg *)wdiCfgReqParam->pConfigBuffer) ; + configDataValue = ((tANI_U8 *)configData + sizeof(tHalCfg)); + vos_mem_copy( configDataValue, &val, sizeof(tANI_U32)); + wdiCfgReqParam->wdiReqStatusCB = NULL ; + + /* store Params pass it to WDI */ + pWDA->wdaWdiCfgApiMsgParam = (void *)wdiCfgReqParam ; +#ifdef FEATURE_HAL_SUPPORT_DYNAMIC_UPDATE_CFG + status = WDI_UpdateCfgReq(wdiCfgReqParam, + (WDI_UpdateCfgRspCb )WDA_UpdateCfgCallback, pWDA) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Update CFG WDI API, free all the memory " ); + vos_mem_free(wdiCfgReqParam->pConfigBuffer) ; + vos_mem_free(pWDA->wdaWdiCfgApiMsgParam) ; + pWDA->wdaWdiCfgApiMsgParam = NULL; + /* Failure is not expected */ + VOS_ASSERT(0) ; + } +#else + vos_mem_free(wdiCfgReqParam->pConfigBuffer) ; + vos_mem_free(pWDA->wdaWdiCfgApiMsgParam) ; + pWDA->wdaWdiCfgApiMsgParam = NULL; +#endif + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_UpdateCfgIntParamCb + * + */ +void WDA_UpdateCfgIntParamCb(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)pUserData ; + WDI_UpdateCfgReqParamsType *wdiCfgParam = + (WDI_UpdateCfgReqParamsType *)pWDA->wdaWdiCfgUpdateIntMsg ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + /* + * currently there is no response message is expected between PE and + * WDA, Failure return from WDI is a ASSERT condition + */ + if (WDI_STATUS_SUCCESS != wdiStatus) + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: CFG (%d) config failure", __func__, + ((tHalCfg *)(wdiCfgParam->pConfigBuffer))->type); + + if (wdiCfgParam && wdiCfgParam->pConfigBuffer) + { + vos_mem_free(wdiCfgParam->pConfigBuffer); + wdiCfgParam->pConfigBuffer = NULL; + } + + if (pWDA->wdaWdiCfgUpdateIntMsg) + { + vos_mem_free(pWDA->wdaWdiCfgUpdateIntMsg); + pWDA->wdaWdiCfgUpdateIntMsg = NULL; + } + + return ; +} + +/* + * FUNCTION: WDA_UpdateCfgIntParam + * + */ +VOS_STATUS WDA_UpdateCfgIntParam(tWDA_CbContext *pWDA, + tSirUpdateCfgIntParam *cfgParam) +{ + + WDI_Status status = WDI_STATUS_SUCCESS ; + tANI_U32 val =0; + tpAniSirGlobal pMac; + WDI_UpdateCfgReqParamsType *wdiCfgReqParam = NULL ; + tHalCfg *tlvStruct = NULL ; + tANI_U8 *tlvStructStart = NULL ; + v_PVOID_t *configParam; + tANI_U32 configParamSize; + tANI_U32 *configDataValue; + tANI_U32 cfgId; + tANI_U32 tlv_type = QWLAN_HAL_CFG_MAX_PARAMS; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + " ------> %s " ,__func__); + + if (cfgParam) + { + cfgId = cfgParam->cfgId; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Invoked with NULL cfgParam")); + return VOS_STATUS_E_FAILURE; + } + + if (!pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Invoked with invalid WDA context")); + return VOS_STATUS_E_FAILURE; + } + + if (NULL != pWDA->wdaWdiCfgUpdateIntMsg) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("wdaWdiCfgApiMsgParam is not NULL")); + + return VOS_STATUS_E_FAILURE; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext) ; + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Invoked with invalid MAC context ")); + return VOS_STATUS_E_FAILURE; + } + + if (wlan_cfgGetInt(pMac, (tANI_U16)cfgId , &val) != eSIR_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Fail to cfg get id %d"), cfgId); + return VOS_STATUS_E_FAILURE; + } + + /* Get TLV type */ + tlv_type = WDA_ConvertWniCfgIdToHALCfgId(cfgId); + if (tlv_type == QWLAN_HAL_CFG_MAX_PARAMS) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to Convert cfg to hal id %d", cfgId); + return VOS_STATUS_E_FAILURE; + } + + wdiCfgReqParam = (WDI_UpdateCfgReqParamsType *)vos_mem_malloc( + sizeof(WDI_UpdateCfgReqParamsType)) ; + if (NULL == wdiCfgReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + return VOS_STATUS_E_NOMEM; + } + + configParamSize = (sizeof(tHalCfg) + (sizeof(tANI_U32))) * 1; + configParam = vos_mem_malloc(configParamSize); + if (NULL == configParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(wdiCfgReqParam); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_set(configParam, configParamSize, 0); + wdiCfgReqParam->pConfigBuffer = configParam; + tlvStruct = (tHalCfg *)configParam; + tlvStructStart = (tANI_U8 *)configParam; + /* Set TLV type */ + tlvStruct->type = tlv_type; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)val; + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "cfg_id %d tlv_type %d tlv_value %d \n", + cfgId, tlvStruct->type, val); + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + wdiCfgReqParam->uConfigBufferLen = (tANI_U8 *)tlvStruct - tlvStructStart ; + wdiCfgReqParam->wdiReqStatusCB = NULL; + /* store Params pass it to WDI */ + pWDA->wdaWdiCfgUpdateIntMsg = (void *)wdiCfgReqParam ; + status = WDI_UpdateCfgReq(wdiCfgReqParam, + (WDI_UpdateCfgRspCb )WDA_UpdateCfgIntParamCb, pWDA) ; + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDA_UpdateCfgIntParam WDI API, free memory "); + vos_mem_free(wdiCfgReqParam->pConfigBuffer); + wdiCfgReqParam->pConfigBuffer = NULL; + vos_mem_free(pWDA->wdaWdiCfgUpdateIntMsg); + pWDA->wdaWdiCfgUpdateIntMsg = NULL; + } + + return CONVERT_WDI2VOS_STATUS(status); +} + +VOS_STATUS WDA_GetWepKeysFromCfg( tWDA_CbContext *pWDA, + v_U8_t *pDefaultKeyId, + v_U8_t *pNumKeys, + WDI_KeysType *pWdiKeys ) +{ + v_U32_t i, j, defKeyId = 0; + v_U32_t val = SIR_MAC_KEY_LENGTH; + VOS_STATUS status = WDI_STATUS_SUCCESS; + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext) ; + if (NULL == pMac ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid MAC context ", __func__ ); + return VOS_STATUS_E_FAILURE; + } + if( eSIR_SUCCESS != wlan_cfgGetInt( pMac, WNI_CFG_WEP_DEFAULT_KEYID, + &defKeyId )) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to retrieve defaultKeyId from CFG. Defaulting to 0..."); + } + + *pDefaultKeyId = (v_U8_t)defKeyId; + /* Need to extract ALL of the configured WEP Keys */ + for( i = 0, j = 0; i < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; i++ ) + { + val = SIR_MAC_KEY_LENGTH; + if( eSIR_SUCCESS != wlan_cfgGetStr( pMac, + (v_U16_t) (WNI_CFG_WEP_DEFAULT_KEY_1 + i), + pWdiKeys[j].key, + &val )) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WEP Key index [%d] may not configured in CFG",i); + } + else + { + pWdiKeys[j].keyId = (tANI_U8) i; + /* + * Actually, a DC (Don't Care) because + * this is determined (and set) by PE/MLME + */ + pWdiKeys[j].unicast = 0; + /* + * Another DC (Don't Care) + */ + pWdiKeys[j].keyDirection = eSIR_TX_RX; + /* Another DC (Don't Care). Unused for WEP */ + pWdiKeys[j].paeRole = 0; + /* Determined from wlan_cfgGetStr() above.*/ + pWdiKeys[j].keyLength = (tANI_U16) val; + j++; + *pNumKeys = (tANI_U8) j; + } + } + return status; +} +/* + * FUNCTION: WDA_SetBssKeyReqCallback + * send SET BSS key RSP back to PE + */ +void WDA_SetBssKeyReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tSetBssKeyParams *setBssKeyParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + setBssKeyParams = (tSetBssKeyParams *)pWdaParams->wdaMsgParam; + vos_mem_zero(pWdaParams->wdaWdiApiMsgParam, + sizeof(WDI_SetBSSKeyReqParamsType)); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + setBssKeyParams->status = status ; + WDA_SendMsg(pWDA, WDA_SET_BSSKEY_RSP, (void *)setBssKeyParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_ProcessSetBssKeyReq + * Request to WDI for programming the BSS key( key for + * broadcast/multicast frames Encryption) + */ +VOS_STATUS WDA_ProcessSetBssKeyReq(tWDA_CbContext *pWDA, + tSetBssKeyParams *setBssKeyParams ) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetBSSKeyReqParamsType *wdiSetBssKeyParam = + (WDI_SetBSSKeyReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetBSSKeyReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + v_U8_t keyIndex; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSetBssKeyParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetBssKeyParam); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(wdiSetBssKeyParam, sizeof(WDI_SetBSSKeyReqParamsType)); + /* copy set BSS params to WDI structure */ + wdiSetBssKeyParam->wdiBSSKeyInfo.ucBssIdx = setBssKeyParams->bssIdx; + wdiSetBssKeyParam->wdiBSSKeyInfo.wdiEncType = setBssKeyParams->encType; + wdiSetBssKeyParam->wdiBSSKeyInfo.ucNumKeys = setBssKeyParams->numKeys; + if(setBssKeyParams->encType != eSIR_ED_NONE) + { + if( setBssKeyParams->numKeys == 0 && + (( setBssKeyParams->encType == eSIR_ED_WEP40)|| + setBssKeyParams->encType == eSIR_ED_WEP104)) + { + tANI_U8 defaultKeyId = 0; + WDA_GetWepKeysFromCfg( pWDA, &defaultKeyId, + &wdiSetBssKeyParam->wdiBSSKeyInfo.ucNumKeys, + wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys ); + } + else + { + for( keyIndex=0; keyIndex < setBssKeyParams->numKeys; keyIndex++) + { + wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].keyId = + setBssKeyParams->key[keyIndex].keyId; + wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].unicast = + setBssKeyParams->key[keyIndex].unicast; + wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].keyDirection = + setBssKeyParams->key[keyIndex].keyDirection; + vos_mem_copy(wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].keyRsc, + setBssKeyParams->key[keyIndex].keyRsc, WLAN_MAX_KEY_RSC_LEN); + wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].paeRole = + setBssKeyParams->key[keyIndex].paeRole; + wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].keyLength = + setBssKeyParams->key[keyIndex].keyLength; + vos_mem_copy(wdiSetBssKeyParam->wdiBSSKeyInfo.aKeys[keyIndex].key, + setBssKeyParams->key[keyIndex].key, + SIR_MAC_MAX_KEY_LENGTH); + } + } + } + wdiSetBssKeyParam->wdiBSSKeyInfo.ucSingleTidRc = + setBssKeyParams->singleTidRc; + wdiSetBssKeyParam->wdiReqStatusCB = NULL ; + /* Store set key pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = setBssKeyParams; + pWdaParams->wdaWdiApiMsgParam = wdiSetBssKeyParam; + status = WDI_SetBSSKeyReq(wdiSetBssKeyParam, + (WDI_SetBSSKeyRspCb)WDA_SetBssKeyReqCallback ,pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set BSS Key Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + setBssKeyParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SET_BSSKEY_RSP, (void *)setBssKeyParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_RemoveBssKeyReqCallback + * send SET BSS key RSP back to PE + */ +void WDA_RemoveBssKeyReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tRemoveBssKeyParams *removeBssKeyParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + removeBssKeyParams = (tRemoveBssKeyParams *)pWdaParams->wdaMsgParam; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + removeBssKeyParams->status = status ; + WDA_SendMsg(pWDA, WDA_REMOVE_BSSKEY_RSP, (void *)removeBssKeyParams , 0) ; + return ; +} + +/* + * FUNCTION: WDA_GetFrameLogRspCallback + * recieves get frame log response from FW + */ +void WDA_GetFrameLogRspCallback(WDI_GetFrameLogRspParamType* wdiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tAniGetFrameLogReq *pGetFrameLogReqParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ Entering: %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + + pGetFrameLogReqParams = (tAniGetFrameLogReq *)pWdaParams->wdaMsgParam; + if(NULL == pGetFrameLogReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pGetFrameLogReqParams received NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return; + } + + if (wdiRsp->wdiStatus != WDI_STATUS_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:GetFrameLog with rsp status %d flag %d", __func__, + wdiRsp->wdiStatus,pGetFrameLogReqParams->getFrameLogCmdFlag); + } + + /* free WDI command buffer only */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return ; + +} + +/* + * FUNCTION: WDA_RssiMonitorStopRspCallback + * recieves Rssi Monitor stop response from FW + */ +void WDA_RssiMonitorStopRspCallback(WDI_RssiMonitorStopRspParamType *wdiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirRssiMonitorReq *pRssiMonitorReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == pWdaParams->wdaMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + pRssiMonitorReqParams = (tSirRssiMonitorReq *)pWdaParams->wdaMsgParam; + + if(pRssiMonitorReqParams->rssiMonitorCallback) + { + pRssiMonitorReqParams->rssiMonitorCallback( + pRssiMonitorReqParams->rssiMonitorCbContext, + CONVERT_WDI2VOS_STATUS(wdiRsp->status)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFWLoggingInitParams callback is NULL", __func__); + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; +} + +/* + * FUNCTION: WDA_RssiMonitorStartRspCallback + * recieves Rssi Monitor start response from FW + */ +void WDA_RssiMonitorStartRspCallback(WDI_RssiMonitorStartRspParamType* wdiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirRssiMonitorReq *pRssiMonitorReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == pWdaParams->wdaMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + pRssiMonitorReqParams = (tSirRssiMonitorReq *)pWdaParams->wdaMsgParam; + + if(pRssiMonitorReqParams->rssiMonitorCallback) + { + pRssiMonitorReqParams->rssiMonitorCallback( + pRssiMonitorReqParams->rssiMonitorCbContext, + CONVERT_WDI2VOS_STATUS(wdiRsp->status)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFWLoggingInitParams callback is NULL", __func__); + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; +} + +/* + * FUNCTION: WDA_FWLoggingInitRspCallback + * recieves Mgmt Logging init response from FW + */ +void WDA_FWLoggingInitRspCallback(WDI_FWLoggingInitRspParamType* wdiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirFWLoggingInitParam *pFWLoggingInitParams; + tAniLoggingInitRsp *pLoggingInitRsp; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == pWdaParams->wdaMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + pLoggingInitRsp = (tAniLoggingInitRsp *)vos_mem_malloc(sizeof(tAniLoggingInitRsp)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure for pLoggingInitRsp", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return; + } + + pFWLoggingInitParams = (tSirFWLoggingInitParam *)pWdaParams->wdaMsgParam; + vos_mem_copy(pLoggingInitRsp, wdiRsp, sizeof(tAniLoggingInitRsp)); + + if(pFWLoggingInitParams->fwlogInitCallback) + { + pFWLoggingInitParams->fwlogInitCallback( + pFWLoggingInitParams->fwlogInitCbContext, + pLoggingInitRsp); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFWLoggingInitParams callback is NULL", __func__); + } + + vos_mem_free(pLoggingInitRsp); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; +} + +/* + * FUNCTION: WDA_SpoofMacAddrRspCallback + * recieves spoof mac addr response from FW + */ +void WDA_SpoofMacAddrRspCallback(WDI_SpoofMacAddrRspParamType* wdiRsp, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + + if (wdiRsp->wdiStatus != WDI_STATUS_SUCCESS) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:Spoofing with rsp status %d", __func__, wdiRsp->wdiStatus); + } + WDA_SendMsg(pWDA, WDA_SPOOF_MAC_ADDR_RSP, NULL, + CONVERT_WDI2SIR_STATUS(wdiRsp->wdiStatus)); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; +} + +/* + * FUNCTION: WDA_ProcessRemoveBssKeyReq + * Request to WDI to remove the BSS key( key for broadcast/multicast + * frames Encryption) + */ +VOS_STATUS WDA_ProcessRemoveBssKeyReq(tWDA_CbContext *pWDA, + tRemoveBssKeyParams *removeBssKeyParams ) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_RemoveBSSKeyReqParamsType *wdiRemoveBssKeyParam = + (WDI_RemoveBSSKeyReqParamsType *)vos_mem_malloc( + sizeof(WDI_RemoveBSSKeyReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiRemoveBssKeyParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiRemoveBssKeyParam); + return VOS_STATUS_E_NOMEM; + } + /* copy Remove BSS key params to WDI structure*/ + wdiRemoveBssKeyParam->wdiKeyInfo.ucBssIdx = removeBssKeyParams->bssIdx; + wdiRemoveBssKeyParam->wdiKeyInfo.wdiEncType = removeBssKeyParams->encType; + wdiRemoveBssKeyParam->wdiKeyInfo.ucKeyId = removeBssKeyParams->keyId; + wdiRemoveBssKeyParam->wdiKeyInfo.wdiWEPType = removeBssKeyParams->wepType; + wdiRemoveBssKeyParam->wdiReqStatusCB = NULL ; + /* Store remove key pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = removeBssKeyParams; + pWdaParams->wdaWdiApiMsgParam = wdiRemoveBssKeyParam; + status = WDI_RemoveBSSKeyReq(wdiRemoveBssKeyParam, + (WDI_RemoveBSSKeyRspCb)WDA_RemoveBssKeyReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Remove BSS Key Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + removeBssKeyParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_REMOVE_BSSKEY_RSP, (void *)removeBssKeyParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_SetBssKeyReqCallback + * send SET BSS key RSP back to PE + */ +void WDA_SetStaKeyReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tSetStaKeyParams *setStaKeyParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR + ,"%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + setStaKeyParams = (tSetStaKeyParams *)pWdaParams->wdaMsgParam; + vos_mem_zero(pWdaParams->wdaWdiApiMsgParam, + sizeof(WDI_SetSTAKeyReqParamsType)); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + setStaKeyParams->status = status ; + WDA_SendMsg(pWDA, WDA_SET_STAKEY_RSP, (void *)setStaKeyParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_ProcessSetStaKeyReq + * Request to WDI for programming the STA key( key for Unicast frames + * Encryption) + */ +VOS_STATUS WDA_ProcessSetStaKeyReq(tWDA_CbContext *pWDA, + tSetStaKeyParams *setStaKeyParams ) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetSTAKeyReqParamsType *wdiSetStaKeyParam = + (WDI_SetSTAKeyReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetSTAKeyReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + v_U8_t keyIndex; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSetStaKeyParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetStaKeyParam); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(wdiSetStaKeyParam, sizeof(WDI_SetSTAKeyReqParamsType), 0); + vos_mem_zero(wdiSetStaKeyParam, sizeof(WDI_SetSTAKeyReqParamsType)); + /* copy set STA key params to WDI structure */ + wdiSetStaKeyParam->wdiKeyInfo.ucSTAIdx = setStaKeyParams->staIdx; + wdiSetStaKeyParam->wdiKeyInfo.wdiEncType = setStaKeyParams->encType; + wdiSetStaKeyParam->wdiKeyInfo.wdiWEPType = setStaKeyParams->wepType; + wdiSetStaKeyParam->wdiKeyInfo.ucDefWEPIdx = setStaKeyParams->defWEPIdx; + if(setStaKeyParams->encType != eSIR_ED_NONE) + { + if( (wdiSetStaKeyParam->wdiKeyInfo.wdiWEPType == WDI_WEP_STATIC) && + (WDA_INVALID_KEY_INDEX == setStaKeyParams->defWEPIdx) && + (eSYSTEM_AP_ROLE != pWDA->wdaGlobalSystemRole)) + { + WDA_GetWepKeysFromCfg( pWDA, + &wdiSetStaKeyParam->wdiKeyInfo.ucDefWEPIdx, + &wdiSetStaKeyParam->wdiKeyInfo.ucNumKeys, + wdiSetStaKeyParam->wdiKeyInfo.wdiKey ); + } + else + { + for( keyIndex=0; keyIndex < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + keyIndex++) + { + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyId = + setStaKeyParams->key[keyIndex].keyId; + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].unicast = + setStaKeyParams->key[keyIndex].unicast; + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyDirection = + setStaKeyParams->key[keyIndex].keyDirection; + vos_mem_copy(wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyRsc, + setStaKeyParams->key[keyIndex].keyRsc, WLAN_MAX_KEY_RSC_LEN); + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].paeRole = + setStaKeyParams->key[keyIndex].paeRole; + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyLength = + setStaKeyParams->key[keyIndex].keyLength; + vos_mem_copy(wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].key, + setStaKeyParams->key[keyIndex].key, SIR_MAC_MAX_KEY_LENGTH); + /* set default index to index which have key direction as WDI_TX_DEFAULT */ + if (WDI_TX_DEFAULT == wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyDirection) + { + wdiSetStaKeyParam->wdiKeyInfo.ucDefWEPIdx = keyIndex; + } + } + wdiSetStaKeyParam->wdiKeyInfo.ucNumKeys = + SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + } + } + wdiSetStaKeyParam->wdiKeyInfo.ucSingleTidRc = setStaKeyParams->singleTidRc; + wdiSetStaKeyParam->wdiReqStatusCB = NULL ; + /* Store set key pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = setStaKeyParams; + pWdaParams->wdaWdiApiMsgParam = wdiSetStaKeyParam; + status = WDI_SetSTAKeyReq(wdiSetStaKeyParam, + (WDI_SetSTAKeyRspCb)WDA_SetStaKeyReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in set STA Key Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + setStaKeyParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SET_STAKEY_RSP, (void *)setStaKeyParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_SetBcastStaKeyReqCallback + * send SET Bcast STA key RSP back to PE + */ +void WDA_SetBcastStaKeyReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tSetStaKeyParams *setStaKeyParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + setStaKeyParams = (tSetStaKeyParams *)pWdaParams->wdaMsgParam; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + setStaKeyParams->status = status ; + WDA_SendMsg(pWDA, WDA_SET_STA_BCASTKEY_RSP, (void *)setStaKeyParams , 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessSetBcastStaKeyReq + * Request to WDI for programming the Bcast STA key( key for Broadcast frames + * Encryption) + */ +VOS_STATUS WDA_ProcessSetBcastStaKeyReq(tWDA_CbContext *pWDA, + tSetStaKeyParams *setStaKeyParams ) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetSTAKeyReqParamsType *wdiSetStaKeyParam = + (WDI_SetSTAKeyReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetSTAKeyReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + v_U8_t keyIndex; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSetStaKeyParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetStaKeyParam); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(wdiSetStaKeyParam, sizeof(WDI_SetSTAKeyReqParamsType), 0); + vos_mem_zero(wdiSetStaKeyParam, sizeof(WDI_SetSTAKeyReqParamsType)); + /* copy set STA key params to WDI structure */ + wdiSetStaKeyParam->wdiKeyInfo.ucSTAIdx = setStaKeyParams->staIdx; + wdiSetStaKeyParam->wdiKeyInfo.wdiEncType = setStaKeyParams->encType; + wdiSetStaKeyParam->wdiKeyInfo.wdiWEPType = setStaKeyParams->wepType; + wdiSetStaKeyParam->wdiKeyInfo.ucDefWEPIdx = setStaKeyParams->defWEPIdx; + if(setStaKeyParams->encType != eSIR_ED_NONE) + { + for( keyIndex=0; keyIndex < SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + keyIndex++) + { + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyId = + setStaKeyParams->key[keyIndex].keyId; + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].unicast = + setStaKeyParams->key[keyIndex].unicast; + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyDirection = + setStaKeyParams->key[keyIndex].keyDirection; + vos_mem_copy(wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyRsc, + setStaKeyParams->key[keyIndex].keyRsc, WLAN_MAX_KEY_RSC_LEN); + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].paeRole = + setStaKeyParams->key[keyIndex].paeRole; + wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].keyLength = + setStaKeyParams->key[keyIndex].keyLength; + vos_mem_copy(wdiSetStaKeyParam->wdiKeyInfo.wdiKey[keyIndex].key, + setStaKeyParams->key[keyIndex].key, SIR_MAC_MAX_KEY_LENGTH); + } + wdiSetStaKeyParam->wdiKeyInfo.ucNumKeys = + SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + } + wdiSetStaKeyParam->wdiKeyInfo.ucSingleTidRc = setStaKeyParams->singleTidRc; + /* Store set key pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = setStaKeyParams; + pWdaParams->wdaWdiApiMsgParam = wdiSetStaKeyParam; + status = WDI_SetSTABcastKeyReq(wdiSetStaKeyParam, + (WDI_SetSTAKeyRspCb)WDA_SetBcastStaKeyReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in set BCAST STA Key Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + setStaKeyParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_SET_STA_BCASTKEY_RSP, (void *)setStaKeyParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_RemoveStaKeyReqCallback + * send SET BSS key RSP back to PE + */ +void WDA_RemoveStaKeyReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tRemoveStaKeyParams *removeStaKeyParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + removeStaKeyParams = (tRemoveStaKeyParams *)pWdaParams->wdaMsgParam; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + removeStaKeyParams->status = status ; + WDA_SendMsg(pWDA, WDA_REMOVE_STAKEY_RSP, (void *)removeStaKeyParams , 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessRemoveStaKeyReq + * Request to WDI to remove the STA key( key for Unicast frames Encryption) + */ +VOS_STATUS WDA_ProcessRemoveStaKeyReq(tWDA_CbContext *pWDA, + tRemoveStaKeyParams *removeStaKeyParams ) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_RemoveSTAKeyReqParamsType *wdiRemoveStaKeyParam = + (WDI_RemoveSTAKeyReqParamsType *)vos_mem_malloc( + sizeof(WDI_RemoveSTAKeyReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiRemoveStaKeyParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiRemoveStaKeyParam); + return VOS_STATUS_E_NOMEM; + } + /* copy remove STA key params to WDI structure*/ + wdiRemoveStaKeyParam->wdiKeyInfo.ucSTAIdx = removeStaKeyParams->staIdx; + wdiRemoveStaKeyParam->wdiKeyInfo.wdiEncType = removeStaKeyParams->encType; + wdiRemoveStaKeyParam->wdiKeyInfo.ucKeyId = removeStaKeyParams->keyId; + wdiRemoveStaKeyParam->wdiKeyInfo.ucUnicast = removeStaKeyParams->unicast; + wdiRemoveStaKeyParam->wdiReqStatusCB = NULL ; + /* Store remove key pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = removeStaKeyParams; + pWdaParams->wdaWdiApiMsgParam = wdiRemoveStaKeyParam; + status = WDI_RemoveSTAKeyReq(wdiRemoveStaKeyParam, + (WDI_RemoveSTAKeyRspCb)WDA_RemoveStaKeyReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in remove STA Key Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + removeStaKeyParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_REMOVE_STAKEY_RSP, (void *)removeStaKeyParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_IsHandleSetLinkStateReq + * Update the WDA state and return the status to handle this message or not + */ +WDA_processSetLinkStateStatus WDA_IsHandleSetLinkStateReq( + tWDA_CbContext *pWDA, + tLinkStateParams *linkStateParams) +{ + WDA_processSetLinkStateStatus status = WDA_PROCESS_SET_LINK_STATE; + switch(linkStateParams->state) + { + case eSIR_LINK_PREASSOC_STATE: + case eSIR_LINK_BTAMP_PREASSOC_STATE: + /* + * set the WDA state to PRE ASSOC + * copy the BSSID into pWDA to use it in join request and return, + * No need to handle these messages. + */ + if( !WDA_IS_NULL_MAC_ADDRESS(linkStateParams->bssid) ) + { + vos_mem_copy(pWDA->macBSSID,linkStateParams->bssid, + sizeof(tSirMacAddr)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: BSSID in set link state is NULL ", __func__); + VOS_ASSERT(0); + } + + if( !WDA_IS_NULL_MAC_ADDRESS(linkStateParams->selfMacAddr) ) + { + vos_mem_copy(pWDA->macSTASelf,linkStateParams->selfMacAddr, + sizeof(tSirMacAddr)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s: self mac address in set link state is NULL ", __func__); + VOS_ASSERT(0); + } + + /* UMAC is issuing the setlink state with PREASSOC twice (before set + *channel and after ) so reset the WDA state to ready when the second + * time UMAC issue the link state with PREASSOC + */ + if(WDA_PRE_ASSOC_STATE == pWDA->wdaState) + { + /* RESET WDA state back to WDA_READY_STATE */ + pWDA->wdaState = WDA_READY_STATE; + } + else + { + pWDA->wdaState = WDA_PRE_ASSOC_STATE; + } + //populate linkState info in WDACbCtxt + pWDA->linkState = linkStateParams->state; + break; + default: + if(pWDA->wdaState != WDA_READY_STATE) + { + /*If WDA_SET_LINK_STATE is recieved with any other link state apart + *from eSIR_LINK_PREASSOC_STATE and eSIR_LINK_BTAMP_PREASSOC_STATE when + *pWDA->wdaState is in WDA_PRE_ASSOC_STATE(This can happen only in + *error cases) so reset the WDA state to WDA_READY_STATE to avoid + *the ASSERT in WDA_Stop during module unload.*/ + if (pWDA->wdaState == WDA_PRE_ASSOC_STATE) + { + pWDA->wdaState = WDA_READY_STATE; + /* Don't ignore the set link in this case*/ + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Set link state called when WDA is not in READY STATE " ); + status = WDA_IGNORE_SET_LINK_STATE; + } + } + break; + } + + return status; +} +/* + * FUNCTION: WDA_SetLinkStateCallback + * call back function for set link state from WDI + */ +void WDA_SetLinkStateCallback(WDI_Status status, void* pUserData) +{ + tWDA_CbContext *pWDA = NULL; + tLinkStateParams *linkStateParams; + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + linkStateParams = (tLinkStateParams *)pWdaParams->wdaMsgParam ; + /* + * In STA mode start the BA activity check timer after association + * and in AP mode start BA activity check timer after BSS start */ + if( ((linkStateParams->state == eSIR_LINK_POSTASSOC_STATE) && + status == WDI_STATUS_SUCCESS) || ((status == WDI_STATUS_SUCCESS) && + (linkStateParams->state == eSIR_LINK_AP_STATE)) || + ((status == WDI_STATUS_SUCCESS) && + (linkStateParams->state == eSIR_LINK_IBSS_STATE))) + { + WDA_START_TIMER(&pWDA->wdaTimers.baActivityChkTmr); + } + WDA_SendMsg(pWDA, WDA_SET_LINK_STATE_RSP, (void *)linkStateParams , 0) ; + /* + * No respone required for WDA_SET_LINK_STATE so free the request + * param here + */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + + return ; +} +/* + * FUNCTION: WDA_ProcessSetLinkState + * Request to WDI to set the link status. + */ +VOS_STATUS WDA_ProcessSetLinkState(tWDA_CbContext *pWDA, + tLinkStateParams *linkStateParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetLinkReqParamsType *wdiSetLinkStateParam = + (WDI_SetLinkReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetLinkReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + tpAniSirGlobal pMac; + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + + if(NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetLinkStateParam); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSetLinkStateParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetLinkStateParam); + return VOS_STATUS_E_NOMEM; + } + if(WDA_IGNORE_SET_LINK_STATE == + WDA_IsHandleSetLinkStateReq(pWDA,linkStateParams)) + { + status = WDI_STATUS_E_FAILURE; + } + else + { + vos_mem_copy(wdiSetLinkStateParam->wdiLinkInfo.macBSSID, + linkStateParams->bssid, sizeof(tSirMacAddr)); + vos_mem_copy(wdiSetLinkStateParam->wdiLinkInfo.macSelfStaMacAddr, + linkStateParams->selfMacAddr, sizeof(tSirMacAddr)); + wdiSetLinkStateParam->wdiLinkInfo.wdiLinkState = linkStateParams->state; + wdiSetLinkStateParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + /* Store remove key pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)linkStateParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetLinkStateParam ; + /* Stop Timer only other than GO role and concurrent session */ + if( (linkStateParams->state == eSIR_LINK_IDLE_STATE) + && (0 == WDI_GetActiveSessionsCount(pWDA->pWdiContext, linkStateParams->bssid, TRUE)) && + (wdaGetGlobalSystemRole(pMac) != eSYSTEM_AP_ROLE) ) + { + WDA_STOP_TIMER(&pWDA->wdaTimers.baActivityChkTmr); + } + status = WDI_SetLinkStateReq(wdiSetLinkStateParam, + (WDI_SetLinkStateRspCb)WDA_SetLinkStateCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in set link state Req WDI API, free all the memory " ); + } + } + if(IS_WDI_STATUS_FAILURE(status)) + { + vos_mem_free(wdiSetLinkStateParam) ; + WDA_SendMsg(pWDA, WDA_SET_LINK_STATE_RSP, (void *)linkStateParams, 0); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_GetStatsReqParamsCallback + * send the response to PE with Stats received from WDI + */ +void WDA_GetStatsReqParamsCallback( + WDI_GetStatsRspParamsType *wdiGetStatsRsp, + void* pUserData) +{ + tAniGetPEStatsRsp *pGetPEStatsRspParams; + vos_msg_t vosMsg; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + pGetPEStatsRspParams = + (tAniGetPEStatsRsp *)vos_mem_malloc(sizeof(tAniGetPEStatsRsp) + + (wdiGetStatsRsp->usMsgLen - sizeof(WDI_GetStatsRspParamsType))); + + if(NULL == pGetPEStatsRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return; + } + vos_mem_set(pGetPEStatsRspParams, wdiGetStatsRsp->usMsgLen, 0); + pGetPEStatsRspParams->msgType = eWNI_SME_GET_STATISTICS_RSP; + pGetPEStatsRspParams->msgLen = sizeof(tAniGetPEStatsRsp) + + (wdiGetStatsRsp->usMsgLen - sizeof(WDI_GetStatsRspParamsType)); + + //Fill the Session Id Properly in PE + pGetPEStatsRspParams->sessionId = 0; + pGetPEStatsRspParams->rc = + wdiGetStatsRsp->wdiStatus; + pGetPEStatsRspParams->staId = wdiGetStatsRsp->ucSTAIdx; + pGetPEStatsRspParams->statsMask = wdiGetStatsRsp->uStatsMask; + vos_mem_copy( pGetPEStatsRspParams + 1, + wdiGetStatsRsp + 1, + wdiGetStatsRsp->usMsgLen - sizeof(WDI_GetStatsRspParamsType)); + + vosMsg.type = eWNI_SME_GET_STATISTICS_RSP; + vosMsg.bodyptr = (void *)pGetPEStatsRspParams; + vosMsg.bodyval = 0; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, + (vos_msg_t*)&vosMsg)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: fail to post eWNI_SME_GET_STATISTICS_RSP", __func__); + vos_mem_free(pGetPEStatsRspParams); + } + + return; +} + +/* + * FUNCTION: WDA_ProcessGetStatsReq + * Request to WDI to get the statistics + */ +VOS_STATUS WDA_ProcessGetStatsReq(tWDA_CbContext *pWDA, + tAniGetPEStatsReq *pGetStatsParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_GetStatsReqParamsType wdiGetStatsParam; + tAniGetPEStatsRsp *pGetPEStatsRspParams; + vos_msg_t vosMsg; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiGetStatsParam.wdiGetStatsParamsInfo.ucSTAIdx = + pGetStatsParams->staId; + wdiGetStatsParam.wdiGetStatsParamsInfo.uStatsMask = + pGetStatsParams->statsMask; + wdiGetStatsParam.wdiReqStatusCB = NULL ; + status = WDI_GetStatsReq(&wdiGetStatsParam, + (WDI_GetStatsRspCb)WDA_GetStatsReqParamsCallback, pWDA); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Get Stats Req WDI API, free all the memory " ); + pGetPEStatsRspParams = + (tAniGetPEStatsRsp *)vos_mem_malloc(sizeof(tAniGetPEStatsRsp)); + if(NULL == pGetPEStatsRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pGetStatsParams); + return VOS_STATUS_E_NOMEM; + } + pGetPEStatsRspParams->msgType = eWNI_SME_GET_STATISTICS_RSP; + pGetPEStatsRspParams->msgLen = sizeof(tAniGetPEStatsRsp); + pGetPEStatsRspParams->staId = pGetStatsParams->staId; + pGetPEStatsRspParams->rc = eSIR_FAILURE; + + vosMsg.type = eWNI_SME_GET_STATISTICS_RSP; + vosMsg.bodyptr = (void *)pGetPEStatsRspParams; + vosMsg.bodyval = 0; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, + (vos_msg_t*)&vosMsg)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: fail to post eWNI_SME_GET_STATISTICS_RSP", __func__); + vos_mem_free(pGetPEStatsRspParams); + } + } + /* Free the request message */ + vos_mem_free(pGetStatsParams); + return CONVERT_WDI2VOS_STATUS(status); +} + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/* + * FUNCTION: WDA_GetGetRssiReqRoamRssiReqParamsCallback + * send the response to PE with roam Rssi received from WDI + */ +void WDA_GetRoamRssiReqParamsCallback( + WDI_GetRoamRssiRspParamsType *wdiGetRoamRssiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tAniGetRoamRssiRsp *pGetRoamRssiRspParams = NULL; + tpAniGetRssiReq pGetRoamRssiReqParams = NULL; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pGetRoamRssiReqParams = (tAniGetRssiReq *)pWdaParams->wdaMsgParam; + + if(NULL == pGetRoamRssiReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pGetRoamRssiReqParams received NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + pGetRoamRssiRspParams = + (tAniGetRoamRssiRsp *)vos_mem_malloc(sizeof(tAniGetRoamRssiRsp)); + + if(NULL == pGetRoamRssiRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return; + } + vos_mem_set(pGetRoamRssiRspParams, sizeof(tAniGetRoamRssiRsp), 0); + pGetRoamRssiRspParams->rc = + wdiGetRoamRssiRsp->wdiStatus; + pGetRoamRssiRspParams->staId = wdiGetRoamRssiRsp->ucSTAIdx; + pGetRoamRssiRspParams->rssi = wdiGetRoamRssiRsp->rssi; + + /* Assign get roam rssi req (backup) in to the response */ + pGetRoamRssiRspParams->rssiReq = pGetRoamRssiReqParams; + + /* free WDI command buffer */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_GET_ROAM_RSSI_RSP, pGetRoamRssiRspParams , 0) ; + + return; +} + + + +/* + * FUNCTION: WDA_ProcessGetRoamRssiReq + * Request to WDI to get the statistics + */ +VOS_STATUS WDA_ProcessGetRoamRssiReq(tWDA_CbContext *pWDA, + tAniGetRssiReq *pGetRoamRssiParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_GetRoamRssiReqParamsType wdiGetRoamRssiParam; + tAniGetRoamRssiRsp *pGetRoamRssiRspParams = NULL; + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiGetRoamRssiParam.wdiGetRoamRssiParamsInfo.ucSTAIdx = + pGetRoamRssiParams->staId; + wdiGetRoamRssiParam.wdiReqStatusCB = NULL ; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pGetRoamRssiParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + /* Store Init Req pointer, as this will be used for response */ + pWdaParams->pWdaContext = pWDA; + + /* Take Get roam Rssi req backup as it stores the callback to be called after + receiving the response */ + pWdaParams->wdaMsgParam = pGetRoamRssiParams; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_GetRoamRssiReq(&wdiGetRoamRssiParam, + (WDI_GetRoamRssiRspCb)WDA_GetRoamRssiReqParamsCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Get RoamRssi Req WDI API, free all the memory status=%d", status ); + pGetRoamRssiRspParams = + (tAniGetRoamRssiRsp *)vos_mem_malloc(sizeof(tAniGetRoamRssiRsp)); + if(NULL == pGetRoamRssiRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pGetRoamRssiParams); + vos_mem_free(pWdaParams); + return VOS_STATUS_E_NOMEM; + } + pGetRoamRssiRspParams->staId = pGetRoamRssiParams->staId; + pGetRoamRssiRspParams->rc = eSIR_FAILURE; + pGetRoamRssiRspParams->rssi = 0; + pGetRoamRssiRspParams->rssiReq = pGetRoamRssiParams; + WDA_SendMsg(pWDA, WDA_GET_ROAM_RSSI_RSP, + (void *)pGetRoamRssiRspParams, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status); +} +#endif + + +/* + * FUNCTION: WDA_UpdateEDCAParamCallback + * call back function for Update EDCA params from WDI + */ +void WDA_UpdateEDCAParamCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tEdcaParams *pEdcaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pEdcaParams = (tEdcaParams *)pWdaParams->wdaMsgParam ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + vos_mem_free(pEdcaParams); + return ; +} +/* + * FUNCTION: WDA_ProcessUpdateEDCAParamReq + * Request to WDI to Update the EDCA params. + */ +VOS_STATUS WDA_ProcessUpdateEDCAParamReq(tWDA_CbContext *pWDA, + tEdcaParams *pEdcaParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_UpdateEDCAParamsType *wdiEdcaParam = + (WDI_UpdateEDCAParamsType *)vos_mem_malloc( + sizeof(WDI_UpdateEDCAParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiEdcaParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pEdcaParams); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiEdcaParam); + vos_mem_free(pEdcaParams); + return VOS_STATUS_E_NOMEM; + } + wdiEdcaParam->wdiEDCAInfo.ucBssIdx = pEdcaParams->bssIdx; + /* + Since firmware is not using highperformance flag, we have removed + this flag from wdiEDCAInfo structure to match sizeof the structure + between host and firmware.In future if we are planning to use + highperformance flag then Please define this flag in wdiEDCAInfo + structure, update it here and send it to firmware. i.e. + Following is the original line which we removed as part of the fix + wdiEdcaParam->wdiEDCAInfo.ucEDCAParamsValid = + pEdcaParams->highPerformance; + */ + WDA_UpdateEdcaParamsForAC(pWDA, &wdiEdcaParam->wdiEDCAInfo.wdiEdcaBEInfo, + &pEdcaParams->acbe); + WDA_UpdateEdcaParamsForAC(pWDA, &wdiEdcaParam->wdiEDCAInfo.wdiEdcaBKInfo, + &pEdcaParams->acbk); + WDA_UpdateEdcaParamsForAC(pWDA, &wdiEdcaParam->wdiEDCAInfo.wdiEdcaVIInfo, + &pEdcaParams->acvi); + WDA_UpdateEdcaParamsForAC(pWDA, &wdiEdcaParam->wdiEDCAInfo.wdiEdcaVOInfo, + &pEdcaParams->acvo); + wdiEdcaParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + /* Store remove key pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pEdcaParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiEdcaParam ; + status = WDI_UpdateEDCAParams(wdiEdcaParam, + (WDI_UpdateEDCAParamsRspCb)WDA_UpdateEDCAParamCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Update EDCA Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + vos_mem_free(pEdcaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_AddBAReqCallback + * send ADD BA RSP back to PE + */ +void WDA_AddBAReqCallback(WDI_AddBARspinfoType *pAddBARspParams, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tAddBAParams *pAddBAReqParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pAddBAReqParams = (tAddBAParams *)pWdaParams->wdaMsgParam; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + pAddBAReqParams->status = pAddBARspParams->wdiStatus ; + WDA_SendMsg(pWDA, WDA_ADDBA_RSP, (void *)pAddBAReqParams , 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessAddBAReq + * Request to WDI to Update the ADDBA REQ params. + */ +VOS_STATUS WDA_ProcessAddBAReq(tWDA_CbContext *pWDA, VOS_STATUS status, + tANI_U16 baSessionID, tANI_U8 staIdx, tANI_U8 ucWinSize, tAddBAParams *pAddBAReqParams) +{ + WDI_Status wstatus; + WDI_AddBAReqParamsType *wdiAddBAReqParam = + (WDI_AddBAReqParamsType *)vos_mem_malloc( + sizeof(WDI_AddBAReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiAddBAReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiAddBAReqParam); + return VOS_STATUS_E_NOMEM; + } + do + { + WDI_AddBAReqinfoType *wdiAddBaInfo = &wdiAddBAReqParam->wdiBAInfoType ; + wdiAddBaInfo->ucSTAIdx = staIdx ; + wdiAddBaInfo->ucBaSessionID = baSessionID ; + wdiAddBaInfo->ucWinSize = ucWinSize ; + } while(0) ; + wdiAddBAReqParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiAddBAReqParam ; + pWdaParams->wdaMsgParam = pAddBAReqParams; + wstatus = WDI_AddBAReq(wdiAddBAReqParam, + (WDI_AddBARspCb)WDA_AddBAReqCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in ADD BA REQ Params WDI API, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pAddBAReqParams->status = eSIR_FAILURE; + WDA_SendMsg(pWDA, WDA_ADDBA_RSP, (void *)pAddBAReqParams , 0) ; + } + return status; +} +/* + * FUNCTION: WDA_AddBASessionReqCallback + * send ADD BA SESSION RSP back to PE/(or TL) + */ +void WDA_AddBASessionReqCallback( + WDI_AddBASessionRspParamsType *wdiAddBaSession, void* pUserData) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS ; + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tAddBAParams *pAddBAReqParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + pAddBAReqParams = (tAddBAParams *)pWdaParams->wdaMsgParam; + if( NULL == pAddBAReqParams ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pAddBAReqParams received NULL " ,__func__); + VOS_ASSERT( 0 ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + /* + * if BA direction is for recipient, update TL with BA session params and send + * another request to HAL(/WDI) (ADD_BA_REQ) + */ + if((VOS_STATUS_SUCCESS == + CONVERT_WDI2VOS_STATUS(wdiAddBaSession->wdiStatus)) && + (eBA_RECIPIENT == pAddBAReqParams->baDirection)) + { + /* Update TL with BA info received from HAL/WDI */ + status = WDA_TL_BA_SESSION_ADD(pWDA->pVosContext, + wdiAddBaSession->usBaSessionID, + wdiAddBaSession->ucSTAIdx, + wdiAddBaSession->ucBaTID, + wdiAddBaSession->ucBaBufferSize, + wdiAddBaSession->ucWinSize, + wdiAddBaSession->usBaSSN ); + WDA_ProcessAddBAReq(pWDA, status, wdiAddBaSession->usBaSessionID, + wdiAddBaSession->ucSTAIdx, + wdiAddBaSession->ucWinSize, pAddBAReqParams) ; + } + else + { + pAddBAReqParams->status = + CONVERT_WDI2SIR_STATUS(wdiAddBaSession->wdiStatus) ; + + /* Setting Flag to indicate that Set BA is success */ + if(WDI_STATUS_SUCCESS == wdiAddBaSession->wdiStatus) + { + tANI_U16 curSta = wdiAddBaSession->ucSTAIdx; + tANI_U8 tid = wdiAddBaSession->ucBaTID; + WDA_SET_BA_TXFLAG(pWDA, curSta, tid) ; + } + WDA_SendMsg(pWDA, WDA_ADDBA_RSP, (void *)pAddBAReqParams , 0) ; + } + /*Reset the WDA state to READY */ + pWDA->wdaState = WDA_READY_STATE; + return ; +} + +/* + * FUNCTION: WDA_ProcessAddBASessionReq + * Request to WDI to Update the ADDBA REQ params. + */ +VOS_STATUS WDA_ProcessAddBASessionReq(tWDA_CbContext *pWDA, + tAddBAParams *pAddBAReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_AddBASessionReqParamsType *wdiAddBASessionReqParam = + (WDI_AddBASessionReqParamsType *)vos_mem_malloc( + sizeof(WDI_AddBASessionReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + WLANTL_STAStateType tlSTAState = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiAddBASessionReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiAddBASessionReqParam); + return VOS_STATUS_E_NOMEM; + } + /* + * Populate ADD BA parameters and pass these paarmeters to WDI. + * ADD BA SESSION REQ will update HAL with BA params, WDA, will changes + * the state to track if these is BA recipient case or BA initiator + * case. + */ + do + { + WDI_AddBASessionReqinfoType *wdiBAInfoType = + &wdiAddBASessionReqParam->wdiBASessionInfoType ; + /* vos_mem_copy(wdiBAInfoType->macBSSID, + pAddBAReqParams->bssId, sizeof(tSirMacAddr));*/ + wdiBAInfoType->ucSTAIdx = pAddBAReqParams->staIdx; + vos_mem_copy(wdiBAInfoType->macPeerAddr, + pAddBAReqParams->peerMacAddr, sizeof(tSirMacAddr)); + wdiBAInfoType->ucBaTID = pAddBAReqParams->baTID; + wdiBAInfoType->ucBaPolicy = pAddBAReqParams->baPolicy; + wdiBAInfoType->usBaBufferSize = pAddBAReqParams->baBufferSize; + wdiBAInfoType->usBaTimeout = pAddBAReqParams->baTimeout; + wdiBAInfoType->usBaSSN = pAddBAReqParams->baSSN; + wdiBAInfoType->ucBaDirection = pAddBAReqParams->baDirection; + + }while(0) ; + wdiAddBASessionReqParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + /* Store ADD BA pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pAddBAReqParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiAddBASessionReqParam ; + + /* In TDLS case, there is a possibility that TL hasn't registered peer yet, but + the peer thinks that we already setup TDLS link, and send us ADDBA request packet + */ + if((VOS_STATUS_SUCCESS != WDA_TL_GET_STA_STATE(pWDA->pVosContext, pAddBAReqParams->staIdx, &tlSTAState)) || + ((WLANTL_STA_CONNECTED != tlSTAState) && (WLANTL_STA_AUTHENTICATED != tlSTAState))) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "Peer staIdx %d hasn't established yet(%d). Send ADD BA failure to PE.", pAddBAReqParams->staIdx, tlSTAState ); + status = WDI_STATUS_E_NOT_ALLOWED; + pAddBAReqParams->status = + CONVERT_WDI2SIR_STATUS(status) ; + WDA_SendMsg(pWDA, WDA_ADDBA_RSP, (void *)pAddBAReqParams , 0) ; + /*Reset the WDA state to READY */ + pWDA->wdaState = WDA_READY_STATE; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + + return CONVERT_WDI2VOS_STATUS(status) ; + } + + status = WDI_AddBASessionReq(wdiAddBASessionReqParam, + (WDI_AddBASessionRspCb)WDA_AddBASessionReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in ADD BA Session REQ Params WDI API, free all the memory =%d", status); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Send ADD BA failure response to PE"); + pAddBAReqParams->status = + CONVERT_WDI2SIR_STATUS(status) ; + WDA_SendMsg(pWDA, WDA_ADDBA_RSP, (void *)pAddBAReqParams , 0) ; + /*Reset the WDA state to READY */ + pWDA->wdaState = WDA_READY_STATE; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_DelBANotifyTL + * send DEL BA IND to TL + */ +void WDA_DelBANotifyTL(tWDA_CbContext *pWDA, + tDelBAParams *pDelBAReqParams) +{ + tpDelBAInd pDelBAInd = (tpDelBAInd)vos_mem_malloc(sizeof( tDelBAInd )); + //tSirMsgQ msg; + vos_msg_t vosMsg; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + if(NULL == pDelBAInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0) ; + return; + } + pDelBAInd->mesgType = WDA_DELETEBA_IND; + pDelBAInd->staIdx = (tANI_U8) pDelBAReqParams->staIdx; + pDelBAInd->baTID = (tANI_U8) pDelBAReqParams->baTID; + pDelBAInd->mesgLen = sizeof( tDelBAInd ); + + + vosMsg.type = WDA_DELETEBA_IND; + vosMsg.bodyptr = pDelBAInd; + vosStatus = vos_mq_post_message(VOS_MQ_ID_TL, &vosMsg); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vosStatus = VOS_STATUS_E_BADMSG; + } +} +/* + * FUNCTION: WDA_DelBAReqCallback + * send DEL BA RSP back to PE + */ +void WDA_DelBAReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tDelBAParams *pDelBAReqParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + + pDelBAReqParams = (tDelBAParams *)pWdaParams->wdaMsgParam ; + /* Notify TL about DEL BA in case of recipinet */ + if((VOS_STATUS_SUCCESS == CONVERT_WDI2VOS_STATUS(status)) && + (eBA_RECIPIENT == pDelBAReqParams->baDirection)) + { + WDA_DelBANotifyTL(pWDA, pDelBAReqParams); + } + /* + * No respone required for WDA_DELBA_IND so just free the request + * param here + */ + vos_mem_free(pDelBAReqParams); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; +} + +/* + * FUNCTION: WDA_ProcessDelBAReq + * Request to WDI to Update the DELBA REQ params. + */ +VOS_STATUS WDA_ProcessDelBAReq(tWDA_CbContext *pWDA, + tDelBAParams *pDelBAReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_DelBAReqParamsType *wdiDelBAReqParam = + (WDI_DelBAReqParamsType *)vos_mem_malloc( + sizeof(WDI_DelBAReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + tANI_U16 staIdx = 0; + tANI_U8 tid = 0; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiDelBAReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiDelBAReqParam); + return VOS_STATUS_E_NOMEM; + } + wdiDelBAReqParam->wdiBAInfo.ucSTAIdx = pDelBAReqParams->staIdx; + wdiDelBAReqParam->wdiBAInfo.ucBaTID = pDelBAReqParams->baTID; + wdiDelBAReqParam->wdiBAInfo.ucBaDirection = pDelBAReqParams->baDirection; + wdiDelBAReqParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + /* Store DEL BA pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pDelBAReqParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiDelBAReqParam ; + /* if BA exchange over the air is failed, clear this tid in BaBitmap + * maintained in WDA, so that WDA can retry for another BA session + */ + staIdx = pDelBAReqParams->staIdx; + tid = pDelBAReqParams->baTID; + WDA_CLEAR_BA_TXFLAG(pWDA, staIdx, tid); + status = WDI_DelBAReq(wdiDelBAReqParam, + (WDI_DelBARspCb)WDA_DelBAReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in DEL BA REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_UpdateChReqCallback + * + */ +void WDA_UpdateChReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams; + WDI_UpdateChReqParamsType *pwdiUpdateChReqParam; + WDI_UpdateChannelReqType *pwdiUpdateChanReqType; + WDI_UpdateChannelReqinfoType *pChanInfoType; + tSirUpdateChanList *pChanList; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pUserData) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pUserData received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWdaParams = (tWDA_ReqParams *)pUserData; + pwdiUpdateChReqParam = + (WDI_UpdateChReqParamsType *)pWdaParams->wdaWdiApiMsgParam; + pwdiUpdateChanReqType = &pwdiUpdateChReqParam->wdiUpdateChanParams; + pChanInfoType = pwdiUpdateChanReqType->pchanParam; + pChanList = (tSirUpdateChanList *)pWdaParams->wdaMsgParam; + /* + * currently there is no response message is expected between PE and + * WDA, Failure return from WDI is a ASSERT condition + */ + vos_mem_free(pChanInfoType); + vos_mem_free(pChanList); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + return; +} + +/* + * FUNCTION: WDA_ProcessUpdateChannelList + * Request to WDI to Update the ChannelList params. + */ +VOS_STATUS WDA_ProcessUpdateChannelList(tWDA_CbContext *pWDA, + tSirUpdateChanList *pChanList) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_UpdateChReqParamsType *pwdiUpdateChReqParam; + WDI_UpdateChannelReqType *pwdiUpdateChanReqType; + WDI_UpdateChannelReqinfoType *pChanInfoType; + tWDA_ReqParams *pWdaParams; + wpt_uint8 i; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pChanList) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: NULL pChanList", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_INVAL; + } + + if(!WDA_getFwWlanFeatCaps(UPDATE_CHANNEL_LIST)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Update channel list capability Not Supported"); + vos_mem_free(pChanList); + return VOS_STATUS_E_INVAL; + } + + pwdiUpdateChReqParam = (WDI_UpdateChReqParamsType *)vos_mem_malloc( + sizeof(WDI_UpdateChReqParamsType)); + if(NULL == pwdiUpdateChReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failed for WDI_UpdateChReqParamsType", + __func__); + VOS_ASSERT(0); + vos_mem_free(pChanList); + return VOS_STATUS_E_NOMEM; + } + pwdiUpdateChanReqType = &pwdiUpdateChReqParam->wdiUpdateChanParams; + pChanInfoType = (WDI_UpdateChannelReqinfoType *) + vos_mem_malloc(sizeof(WDI_UpdateChannelReqinfoType) * + pChanList->numChan); + if(NULL == pChanInfoType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pChanList); + vos_mem_free(pwdiUpdateChReqParam); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(pChanInfoType, sizeof(WDI_UpdateChannelReqinfoType) + * pChanList->numChan); + pwdiUpdateChanReqType->pchanParam = pChanInfoType; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pChanList); + vos_mem_free(pChanInfoType); + vos_mem_free(pwdiUpdateChReqParam); + return VOS_STATUS_E_NOMEM; + } + pwdiUpdateChanReqType->numchan = pChanList->numChan; + + for(i = 0; i < pwdiUpdateChanReqType->numchan; i++) + { + pChanInfoType->mhz = + vos_chan_to_freq(pChanList->chanParam[i].chanId); + + pChanInfoType->band_center_freq1 = pChanInfoType->mhz; + pChanInfoType->band_center_freq2 = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "chan[%d] = %u", i, pChanInfoType->mhz); + if (pChanList->chanParam[i].dfsSet) + { + WDA_SET_CHANNEL_FLAG(pChanInfoType, WLAN_HAL_CHAN_FLAG_PASSIVE); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "chan[%d] DFS[%d]", pChanList->chanParam[i].chanId, + pChanList->chanParam[i].dfsSet); + } + + if (pChanInfoType->mhz < WDA_2_4_GHZ_MAX_FREQ) + { + WDA_SET_CHANNEL_MODE(pChanInfoType, MODE_11G); + } + else + { + WDA_SET_CHANNEL_MODE(pChanInfoType, MODE_11A); + WDA_SET_CHANNEL_FLAG(pChanInfoType, WLAN_HAL_CHAN_FLAG_ALLOW_HT); + WDA_SET_CHANNEL_FLAG(pChanInfoType, WLAN_HAL_CHAN_FLAG_ALLOW_VHT); + } + + WDA_SET_CHANNEL_MAX_POWER(pChanInfoType, pChanList->chanParam[i].pwr); + WDA_SET_CHANNEL_REG_POWER(pChanInfoType, pChanList->chanParam[i].pwr); + WDA_SET_CUURENT_REG_DOMAIN(pChanInfoType, pChanList->regId); + pChanInfoType++; + } + pwdiUpdateChReqParam->wdiReqStatusCB = NULL; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = (void *)pChanList; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiUpdateChReqParam; + status = WDI_UpdateChannelReq(pwdiUpdateChReqParam, + (WDI_UpdateChannelRspCb)WDA_UpdateChReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Update Channel REQ Params WDI API, free all the memory"); + vos_mem_free(pwdiUpdateChanReqType->pchanParam); + vos_mem_free(pwdiUpdateChReqParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/* + * FUNCTION: WDA_AddTSReqCallback + * send ADD TS RSP back to PE + */ +void WDA_AddTSReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tAddTsParams *pAddTsReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pAddTsReqParams = (tAddTsParams *)pWdaParams->wdaMsgParam ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + + pAddTsReqParams->status = status ; + WDA_SendMsg(pWDA, WDA_ADD_TS_RSP, (void *)pAddTsReqParams , 0) ; + return ; +} + +/* + * FUNCTION: WDA_ProcessAddTSReq + * Request to WDI to Update the ADD TS REQ params. + */ +VOS_STATUS WDA_ProcessAddTSReq(tWDA_CbContext *pWDA, + tAddTsParams *pAddTsReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_AddTSReqParamsType *wdiAddTSReqParam = + (WDI_AddTSReqParamsType *)vos_mem_malloc( + sizeof(WDI_AddTSReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiAddTSReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiAddTSReqParam); + return VOS_STATUS_E_NOMEM; + } + wdiAddTSReqParam->wdiTsInfo.ucSTAIdx = pAddTsReqParams->staIdx; + wdiAddTSReqParam->wdiTsInfo.ucTspecIdx = pAddTsReqParams->tspecIdx; + //TS IE + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.ucType = pAddTsReqParams->tspec.type; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.ucLength = + pAddTsReqParams->tspec.length; + + //TS IE : TS INFO : TRAFFIC + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.ackPolicy = + pAddTsReqParams->tspec.tsinfo.traffic.ackPolicy; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.userPrio = + pAddTsReqParams->tspec.tsinfo.traffic.userPrio; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.psb = + pAddTsReqParams->tspec.tsinfo.traffic.psb; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.aggregation = + pAddTsReqParams->tspec.tsinfo.traffic.aggregation; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.accessPolicy = + pAddTsReqParams->tspec.tsinfo.traffic.accessPolicy; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.direction = + pAddTsReqParams->tspec.tsinfo.traffic.direction; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.tsid = + pAddTsReqParams->tspec.tsinfo.traffic.tsid; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.trafficType = + pAddTsReqParams->tspec.tsinfo.traffic.trafficType; + + //TS IE : TS INFO : SCHEDULE + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiSchedule.schedule = + pAddTsReqParams->tspec.tsinfo.schedule.schedule; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiSchedule.rsvd = + pAddTsReqParams->tspec.tsinfo.schedule.rsvd; + //TS IE + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.usNomMsduSz = + pAddTsReqParams->tspec.nomMsduSz; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.usMaxMsduSz = + pAddTsReqParams->tspec.maxMsduSz; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uMinSvcInterval = + pAddTsReqParams->tspec.minSvcInterval; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uMaxSvcInterval = + pAddTsReqParams->tspec.maxSvcInterval; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uInactInterval = + pAddTsReqParams->tspec.inactInterval; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uSuspendInterval = + pAddTsReqParams->tspec.suspendInterval; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uSvcStartTime = + pAddTsReqParams->tspec.svcStartTime; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uMinDataRate = + pAddTsReqParams->tspec.minDataRate; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uMeanDataRate = + pAddTsReqParams->tspec.meanDataRate; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uPeakDataRate = + pAddTsReqParams->tspec.peakDataRate; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uMaxBurstSz = + pAddTsReqParams->tspec.maxBurstSz; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uDelayBound = + pAddTsReqParams->tspec.delayBound; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.uMinPhyRate = + pAddTsReqParams->tspec.minPhyRate; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.usSurplusBw = + pAddTsReqParams->tspec.surplusBw; + wdiAddTSReqParam->wdiTsInfo.wdiTspecIE.usMediumTime = + pAddTsReqParams->tspec.mediumTime; + /* TODO: tAddTsParams doesn't have the following fields */ +#if 0 + wdiAddTSReqParam->wdiTsInfo.ucUapsdFlags = + wdiAddTSReqParam->wdiTsInfo.ucServiceInterval = + wdiAddTSReqParam->wdiTsInfo.ucSuspendInterval = + wdiAddTSReqParam->wdiTsInfo.ucDelayedInterval = +#endif + wdiAddTSReqParam->wdiReqStatusCB = NULL ; + + pWdaParams->pWdaContext = pWDA; + /* Store ADD TS pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pAddTsReqParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiAddTSReqParam ; + status = WDI_AddTSReq(wdiAddTSReqParam, + (WDI_AddTsRspCb)WDA_AddTSReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in ADD TS REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + pAddTsReqParams->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_ADD_TS_RSP, (void *)pAddTsReqParams , 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_DelTSReqCallback + * send DEL TS RSP back to PE + */ +void WDA_DelTSReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams); + /* + * No respone required for WDA_DEL_TS_REQ so just free the request + * param here + */ + return ; +} + +/* + * FUNCTION: WDA_ProcessDelTSReq + * Request to WDI to Update the DELTS REQ params. + */ +VOS_STATUS WDA_ProcessDelTSReq(tWDA_CbContext *pWDA, + tDelTsParams *pDelTSReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_DelTSReqParamsType *wdiDelTSReqParam = + (WDI_DelTSReqParamsType *)vos_mem_malloc( + sizeof(WDI_DelTSReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiDelTSReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiDelTSReqParam); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(wdiDelTSReqParam->wdiDelTSInfo.macBSSID, + pDelTSReqParams->bssId, sizeof(tSirMacAddr)); + wdiDelTSReqParam->wdiDelTSInfo.ucSTAIdx = pDelTSReqParams->staIdx; + wdiDelTSReqParam->wdiDelTSInfo.ucTspecIdx = pDelTSReqParams->tspecIdx; + wdiDelTSReqParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + /* Store DEL TS pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pDelTSReqParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiDelTSReqParam ; + status = WDI_DelTSReq(wdiDelTSReqParam, + (WDI_DelTsRspCb)WDA_DelTSReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in DEL TS REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_UpdateBeaconParamsCallback + * Free the memory. No need to send any response to PE in this case + */ +void WDA_UpdateBeaconParamsCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams); + /* + * No respone required for WDA_UPDATE_BEACON_IND so just free the request + * param here + */ + return ; +} +/* + * FUNCTION: WDA_ProcessUpdateBeaconParams + * Request to WDI to send the beacon parameters to HAL to update the Hardware + */ +VOS_STATUS WDA_ProcessUpdateBeaconParams(tWDA_CbContext *pWDA, + tUpdateBeaconParams *pUpdateBeaconParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_UpdateBeaconParamsType *wdiUpdateBeaconParams = + (WDI_UpdateBeaconParamsType *)vos_mem_malloc( + sizeof(WDI_UpdateBeaconParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiUpdateBeaconParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiUpdateBeaconParams); + return VOS_STATUS_E_NOMEM; + } + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucBssIdx = + pUpdateBeaconParams->bssIdx; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfShortPreamble = + pUpdateBeaconParams->fShortPreamble; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfShortSlotTime = + pUpdateBeaconParams->fShortSlotTime; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.usBeaconInterval = + pUpdateBeaconParams->beaconInterval; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllaCoexist = + pUpdateBeaconParams->llaCoexist; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllbCoexist = + pUpdateBeaconParams->llbCoexist; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllgCoexist = + pUpdateBeaconParams->llgCoexist; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucHt20MhzCoexist= + pUpdateBeaconParams->ht20MhzCoexist; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllnNonGFCoexist = + pUpdateBeaconParams->llnNonGFCoexist; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfLsigTXOPProtectionFullSupport = + pUpdateBeaconParams->fLsigTXOPProtectionFullSupport; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfRIFSMode = + pUpdateBeaconParams->fRIFSMode; + wdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.usChangeBitmap = + pUpdateBeaconParams->paramChangeBitmap; + wdiUpdateBeaconParams->wdiReqStatusCB = NULL ; + + pWdaParams->pWdaContext = pWDA; + /* Store UpdateBeacon Req pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pUpdateBeaconParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiUpdateBeaconParams ; + status = WDI_UpdateBeaconParamsReq(wdiUpdateBeaconParams, + (WDI_UpdateBeaconParamsRspCb)WDA_UpdateBeaconParamsCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in UPDATE BEACON REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#ifdef FEATURE_WLAN_ESE +/* + * FUNCTION: WDA_TSMStatsReqCallback + * send TSM Stats RSP back to PE + */ +void WDA_TSMStatsReqCallback(WDI_TSMStatsRspParamsType *pwdiTSMStatsRspParams, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tpAniGetTsmStatsRsp pTsmRspParams = NULL; + tpAniGetTsmStatsReq pGetTsmStatsReqParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ Entering: %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pGetTsmStatsReqParams = (tAniGetTsmStatsReq *)pWdaParams->wdaMsgParam; + + if(NULL == pGetTsmStatsReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pGetTsmStatsReqParams received NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return; + } + + pTsmRspParams = + (tAniGetTsmStatsRsp *)vos_mem_malloc(sizeof(tAniGetTsmStatsRsp)); + if( NULL == pTsmRspParams ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pTsmRspParams received NULL " ,__func__); + VOS_ASSERT( 0 ); + return ; + } + vos_mem_set(pTsmRspParams, sizeof(tAniGetTsmStatsRsp), 0); + pTsmRspParams->rc = pwdiTSMStatsRspParams->wdiStatus; + pTsmRspParams->staId = pGetTsmStatsReqParams->staId; + + pTsmRspParams->tsmMetrics.UplinkPktQueueDly = pwdiTSMStatsRspParams->UplinkPktQueueDly; + vos_mem_copy(pTsmRspParams->tsmMetrics.UplinkPktQueueDlyHist, + pwdiTSMStatsRspParams->UplinkPktQueueDlyHist, + sizeof(pwdiTSMStatsRspParams->UplinkPktQueueDlyHist)/ + sizeof(pwdiTSMStatsRspParams->UplinkPktQueueDlyHist[0])); + pTsmRspParams->tsmMetrics.UplinkPktTxDly = pwdiTSMStatsRspParams->UplinkPktTxDly; + pTsmRspParams->tsmMetrics.UplinkPktLoss = pwdiTSMStatsRspParams->UplinkPktLoss; + pTsmRspParams->tsmMetrics.UplinkPktCount = pwdiTSMStatsRspParams->UplinkPktCount; + pTsmRspParams->tsmMetrics.RoamingCount = pwdiTSMStatsRspParams->RoamingCount; + pTsmRspParams->tsmMetrics.RoamingDly = pwdiTSMStatsRspParams->RoamingDly; + + /* Assign get tsm stats req req (backup) in to the response */ + pTsmRspParams->tsmStatsReq = pGetTsmStatsReqParams; + + /* free WDI command buffer */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + WDA_SendMsg(pWDA, WDA_TSM_STATS_RSP, (void *)pTsmRspParams , 0) ; + return ; +} + + +/* + * FUNCTION: WDA_ProcessTsmStatsReq + * Request to WDI to get the TSM Stats params. + */ +VOS_STATUS WDA_ProcessTsmStatsReq(tWDA_CbContext *pWDA, + tpAniGetTsmStatsReq pTsmStats) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_TSMStatsReqParamsType *wdiTSMReqParam = NULL; + tWDA_ReqParams *pWdaParams = NULL; + tAniGetTsmStatsRsp *pGetTsmStatsRspParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> Entering: %s " ,__func__); + wdiTSMReqParam = (WDI_TSMStatsReqParamsType *)vos_mem_malloc( + sizeof(WDI_TSMStatsReqParamsType)); + if(NULL == wdiTSMReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiTSMReqParam); + return VOS_STATUS_E_NOMEM; + } + wdiTSMReqParam->wdiTsmStatsParamsInfo.ucTid = pTsmStats->tid; + vos_mem_copy(wdiTSMReqParam->wdiTsmStatsParamsInfo.bssid, + pTsmStats->bssId, + sizeof(wpt_macAddr)); + wdiTSMReqParam->wdiReqStatusCB = NULL ; + + pWdaParams->pWdaContext = pWDA; + /* Store TSM Stats pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pTsmStats ; + pWdaParams->wdaWdiApiMsgParam = NULL ; + status = WDI_TSMStatsReq(wdiTSMReqParam, + (WDI_TsmRspCb)WDA_TSMStatsReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in TSM STATS REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams); + + pGetTsmStatsRspParams = + (tAniGetTsmStatsRsp *)vos_mem_malloc(sizeof(tAniGetTsmStatsRsp)); + if(NULL == pGetTsmStatsRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pTsmStats); + return VOS_STATUS_E_NOMEM; + } + pGetTsmStatsRspParams->staId = pTsmStats->staId; + pGetTsmStatsRspParams->rc = eSIR_FAILURE; + pGetTsmStatsRspParams->tsmStatsReq = pTsmStats; + + WDA_SendMsg(pWDA, WDA_TSM_STATS_RSP, (void *)pGetTsmStatsRspParams , 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif +/* + * FUNCTION: WDA_SendBeaconParamsCallback + * No need to send any response to PE in this case + */ +void WDA_SendBeaconParamsCallback(WDI_Status status, void* pUserData) +{ + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + return ; +} +/* + * FUNCTION: WDA_ProcessSendBeacon + * Request to WDI to send the beacon template to HAL to update the TPE memory and + * start beacon trasmission + */ +VOS_STATUS WDA_ProcessSendBeacon(tWDA_CbContext *pWDA, + tSendbeaconParams *pSendbeaconParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SendBeaconParamsType wdiSendBeaconReqParam; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + vos_mem_copy(wdiSendBeaconReqParam.wdiSendBeaconParamsInfo.macBSSID, + pSendbeaconParams->bssId, sizeof(tSirMacAddr)); + wdiSendBeaconReqParam.wdiSendBeaconParamsInfo.beaconLength = + pSendbeaconParams->beaconLength; + wdiSendBeaconReqParam.wdiSendBeaconParamsInfo.timIeOffset = + pSendbeaconParams->timIeOffset; + /* p2pIeOffset should be atleast greater than timIeOffset */ + if ((pSendbeaconParams->p2pIeOffset != 0) && + (pSendbeaconParams->p2pIeOffset < + pSendbeaconParams->timIeOffset)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Invalid p2pIeOffset = %hu ", pSendbeaconParams->p2pIeOffset); + vos_mem_free(pSendbeaconParams); + VOS_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + wdiSendBeaconReqParam.wdiSendBeaconParamsInfo.usP2PIeOffset = + pSendbeaconParams->p2pIeOffset; + /* Copy the beacon template to local buffer */ + vos_mem_copy(wdiSendBeaconReqParam.wdiSendBeaconParamsInfo.beacon, + pSendbeaconParams->beacon, pSendbeaconParams->beaconLength); + wdiSendBeaconReqParam.wdiReqStatusCB = NULL ; + + status = WDI_SendBeaconParamsReq(&wdiSendBeaconReqParam, + (WDI_SendBeaconParamsRspCb)WDA_SendBeaconParamsCallback, pWDA); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SEND BEACON REQ Params WDI API" ); + } + vos_mem_free(pSendbeaconParams); + return CONVERT_WDI2VOS_STATUS(status); +} +/* + * FUNCTION: WDA_UpdateProbeRspParamsCallback + * No need to send any response to PE in this case + */ +void WDA_UpdateProbeRspParamsCallback(WDI_Status status, void* pUserData) +{ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + return ; +} + +/* + * FUNCTION: WDA_ProcessUpdateProbeRspTemplate + * Request to WDI to send the probe response template to HAL to update the TPE memory and + * send probe response + */ +VOS_STATUS WDA_ProcessUpdateProbeRspTemplate(tWDA_CbContext *pWDA, + tSendProbeRespParams *pSendProbeRspParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_UpdateProbeRspTemplateParamsType *wdiSendProbeRspParam = + vos_mem_malloc(sizeof(WDI_UpdateProbeRspTemplateParamsType)); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if (!wdiSendProbeRspParam) + { + vos_mem_free(pSendProbeRspParams); + return CONVERT_WDI2VOS_STATUS(WDI_STATUS_MEM_FAILURE); + } + + /*Copy update probe response parameters*/ + vos_mem_copy(wdiSendProbeRspParam->wdiProbeRspTemplateInfo.macBSSID, + pSendProbeRspParams->bssId, sizeof(tSirMacAddr)); + wdiSendProbeRspParam->wdiProbeRspTemplateInfo.uProbeRespTemplateLen = + pSendProbeRspParams->probeRespTemplateLen; + vos_mem_copy( + wdiSendProbeRspParam->wdiProbeRspTemplateInfo.uaProxyProbeReqValidIEBmap, + pSendProbeRspParams->ucProxyProbeReqValidIEBmap, + WDI_PROBE_REQ_BITMAP_IE_LEN); + /* Copy the Probe Response template to local buffer */ + wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate = + vos_mem_malloc(wdiSendProbeRspParam->wdiProbeRspTemplateInfo. + uProbeRespTemplateLen); + if(!wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate) + { + status = WDI_STATUS_MEM_FAILURE; + goto free_mem; + } + + vos_mem_copy( + wdiSendProbeRspParam->wdiProbeRspTemplateInfo.pProbeRespTemplate, + pSendProbeRspParams->pProbeRespTemplate, + pSendProbeRspParams->probeRespTemplateLen); + + wdiSendProbeRspParam->wdiReqStatusCB = NULL ; + + status = WDI_UpdateProbeRspTemplateReq(wdiSendProbeRspParam, + (WDI_UpdateProbeRspTemplateRspCb)WDA_UpdateProbeRspParamsCallback, pWDA); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SEND Probe RSP Params WDI API" ); + vos_mem_free(wdiSendProbeRspParam->wdiProbeRspTemplateInfo. + pProbeRespTemplate); + } +free_mem: + vos_mem_free(pSendProbeRspParams); + vos_mem_free(wdiSendProbeRspParam); + return CONVERT_WDI2VOS_STATUS(status); +} +#if defined(WLAN_FEATURE_VOWIFI) || defined(FEATURE_WLAN_ESE) +/* + * FUNCTION: WDA_SetMaxTxPowerCallBack + * send the response to PE with power value received from WDI + */ +void WDA_SetMaxTxPowerCallBack(WDI_SetMaxTxPowerRspMsg * pwdiSetMaxTxPowerRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tMaxTxPowerParams *pMaxTxPowerParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + pMaxTxPowerParams = (tMaxTxPowerParams *)pWdaParams->wdaMsgParam ; + if( NULL == pMaxTxPowerParams ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pMaxTxPowerParams received NULL " ,__func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + + + /*need to free memory for the pointers used in the + WDA Process.Set Max Tx Power Req function*/ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + pMaxTxPowerParams->power = pwdiSetMaxTxPowerRsp->ucPower; + + + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_MAX_TX_POWER_RSP, pMaxTxPowerParams , 0) ; + + return; +} +/* + * FUNCTION: WDA_ProcessSetMaxTxPowerReq + * Request to WDI to send set Max Tx Power Request + */ + VOS_STATUS WDA_ProcessSetMaxTxPowerReq(tWDA_CbContext *pWDA, + tMaxTxPowerParams *MaxTxPowerParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_SetMaxTxPowerParamsType *wdiSetMaxTxPowerParams = NULL; + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + wdiSetMaxTxPowerParams = (WDI_SetMaxTxPowerParamsType *)vos_mem_malloc( + sizeof(WDI_SetMaxTxPowerParamsType)); + if(NULL == wdiSetMaxTxPowerParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(wdiSetMaxTxPowerParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + /* Copy.Max.Tx.Power Params to WDI structure */ + vos_mem_copy(wdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.macBSSId, + MaxTxPowerParams->bssId, + sizeof(tSirMacAddr)); + vos_mem_copy(wdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.macSelfStaMacAddr, + MaxTxPowerParams->selfStaMacAddr, + sizeof(tSirMacAddr)); + wdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.ucPower = + MaxTxPowerParams->power; + wdiSetMaxTxPowerParams->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = (void *)MaxTxPowerParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetMaxTxPowerParams ; + status = WDI_SetMaxTxPowerReq(wdiSetMaxTxPowerParams, + (WDA_SetMaxTxPowerRspCb)WDA_SetMaxTxPowerCallBack, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SET MAX TX Power REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_MAX_TX_POWER_RSP, MaxTxPowerParams , 0) ; + } + return CONVERT_WDI2VOS_STATUS(status); + +} +#endif + +/* + * FUNCTION: WDA_SetMaxTxPowerPerBandCallBack + * send the response to PE with power value received from WDI + */ +void WDA_SetMaxTxPowerPerBandCallBack(WDI_SetMaxTxPowerPerBandRspMsg + *pwdiSetMaxTxPowerPerBandRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tMaxTxPowerPerBandParams *pMxTxPwrPerBandParams = NULL; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s ", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + pMxTxPwrPerBandParams = (tMaxTxPowerPerBandParams*)pWdaParams->wdaMsgParam; + if ( NULL == pMxTxPwrPerBandParams ) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pMxTxPwrPerBandParams received NULL ", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return; + } + + /*need to free memory for the pointers used in the + WDA Process.Set Max Tx Power Req function*/ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pMxTxPwrPerBandParams->power = pwdiSetMaxTxPowerPerBandRsp->ucPower; + + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_MAX_TX_POWER_PER_BAND_RSP, + pMxTxPwrPerBandParams, 0); + + return; +} + +/* + * FUNCTION: WDA_ProcessSetMaxTxPowerPerBandReq + * Request to WDI to send set Max Tx Power Per band Request + */ + VOS_STATUS WDA_ProcessSetMaxTxPowerPerBandReq(tWDA_CbContext *pWDA, + tMaxTxPowerPerBandParams + *MaxTxPowerPerBandParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_SetMaxTxPowerPerBandParamsType *wdiSetMxTxPwrPerBandParams = NULL; + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s ", __func__); + + wdiSetMxTxPwrPerBandParams = vos_mem_malloc( + sizeof(WDI_SetMaxTxPowerPerBandParamsType)); + + if (NULL == wdiSetMxTxPwrPerBandParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(wdiSetMxTxPwrPerBandParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + /* Copy.Max.Tx.Power.Per.Band Params to WDI structure */ + wdiSetMxTxPwrPerBandParams->wdiMaxTxPowerPerBandInfo.bandInfo = \ + MaxTxPowerPerBandParams->bandInfo; + wdiSetMxTxPwrPerBandParams->wdiMaxTxPowerPerBandInfo.ucPower = \ + MaxTxPowerPerBandParams->power; + wdiSetMxTxPwrPerBandParams->wdiReqStatusCB = NULL; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = (void *)MaxTxPowerPerBandParams; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetMxTxPwrPerBandParams; + status = WDI_SetMaxTxPowerPerBandReq(wdiSetMxTxPwrPerBandParams, + WDA_SetMaxTxPowerPerBandCallBack, + pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SET MAX TX Power REQ Params WDI API," + " free all the memory"); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + /* send response to UMAC*/ + WDA_SendMsg(pWDA, + WDA_SET_MAX_TX_POWER_PER_BAND_RSP, + MaxTxPowerPerBandParams, 0); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/* + * FUNCTION: WDA_SetTxPowerCallBack + * send the response to PE with power value received from WDI + */ +void WDA_SetTxPowerCallBack(WDI_SetTxPowerRspMsg * pwdiSetMaxTxPowerRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tSirSetTxPowerReq *pTxPowerParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s ", __func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + pTxPowerParams = (tSirSetTxPowerReq *)pWdaParams->wdaMsgParam; + if(NULL == pTxPowerParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pTxPowerParams received NULL " ,__func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + + /*need to free memory for the pointers used in the + WDA Process.Set Max Tx Power Req function*/ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_TX_POWER_RSP, pTxPowerParams , 0) ; + return; +} + +/* + * FUNCTION: WDA_ProcessSetTxPowerReq + * Request to WDI to send set Tx Power Request + */ + VOS_STATUS WDA_ProcessSetTxPowerReq(tWDA_CbContext *pWDA, + tSirSetTxPowerReq *txPowerParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_SetTxPowerParamsType *wdiSetTxPowerParams = NULL; + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s ", __func__); + + wdiSetTxPowerParams = (WDI_SetTxPowerParamsType *)vos_mem_malloc( + sizeof(WDI_SetTxPowerParamsType)); + if(NULL == wdiSetTxPowerParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(wdiSetTxPowerParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + wdiSetTxPowerParams->wdiTxPowerInfo.bssIdx = + txPowerParams->bssIdx; + wdiSetTxPowerParams->wdiTxPowerInfo.ucPower = + txPowerParams->mwPower; + wdiSetTxPowerParams->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = (void *)txPowerParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetTxPowerParams ; + status = WDI_SetTxPowerReq(wdiSetTxPowerParams, + (WDA_SetTxPowerRspCb)WDA_SetTxPowerCallBack, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SET TX Power REQ Params WDI API, free all the memory "); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_TX_POWER_RSP, txPowerParams , 0) ; + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/* + * FUNCTION: WDA_SetP2PGONOAReqParamsCallback + * Free the memory. No need to send any response to PE in this case + */ +void WDA_SetP2PGONOAReqParamsCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams); + + /* + * No respone required for SIR_HAL_SET_P2P_GO_NOA_REQ + * so just free the request param here + */ + return ; +} + +/* + * FUNCTION: WDA_ProcessSetP2PGONOAReq + * Request to WDI to set the P2P Group Owner Notice of Absence Req + */ +VOS_STATUS WDA_ProcessSetP2PGONOAReq(tWDA_CbContext *pWDA, + tP2pPsParams *pP2pPsConfigParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetP2PGONOAReqParamsType *wdiSetP2PGONOAReqParam = + (WDI_SetP2PGONOAReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetP2PGONOAReqParamsType)) ; + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSetP2PGONOAReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pP2pPsConfigParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pP2pPsConfigParams); + vos_mem_free(wdiSetP2PGONOAReqParam); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.ucOpp_ps = + pP2pPsConfigParams->opp_ps; + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.uCtWindow = + pP2pPsConfigParams->ctWindow; + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.ucCount = + pP2pPsConfigParams->count; + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.uDuration = + pP2pPsConfigParams->duration; + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.uInterval = + pP2pPsConfigParams->interval; + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.uSingle_noa_duration = + pP2pPsConfigParams->single_noa_duration; + wdiSetP2PGONOAReqParam->wdiP2PGONOAInfo.ucPsSelection = + pP2pPsConfigParams->psSelection; + + wdiSetP2PGONOAReqParam->wdiReqStatusCB = NULL ; + /* Store msg pointer from PE, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pP2pPsConfigParams ; + + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetP2PGONOAReqParam ; + pWdaParams->pWdaContext = pWDA; + + status = WDI_SetP2PGONOAReq(wdiSetP2PGONOAReqParam, + (WDI_SetP2PGONOAReqParamsRspCb)WDA_SetP2PGONOAReqParamsCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set P2P GO NOA Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); + +} + +#ifdef FEATURE_WLAN_TDLS +/* + * FUNCTION: WDA_SetP2PGONOAReqParamsCallback + * Free the memory. No need to send any response to PE in this case + */ +void WDA_SetTDLSLinkEstablishReqParamsCallback(WDI_SetTdlsLinkEstablishReqResp *wdiSetTdlsLinkEstablishReqRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tTdlsLinkEstablishParams *pTdlsLinkEstablishParams; + + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + pTdlsLinkEstablishParams = (tTdlsLinkEstablishParams *)pWdaParams->wdaMsgParam ; + if( NULL == pTdlsLinkEstablishParams ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pTdlsLinkEstablishParams " + "received NULL " ,__func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + pTdlsLinkEstablishParams->status = CONVERT_WDI2SIR_STATUS( + wdiSetTdlsLinkEstablishReqRsp->wdiStatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_TDLS_LINK_ESTABLISH_REQ_RSP, pTdlsLinkEstablishParams, 0) ; + + return ; +} + +VOS_STATUS WDA_ProcessSetTdlsLinkEstablishReq(tWDA_CbContext *pWDA, + tTdlsLinkEstablishParams *pTdlsLinkEstablishParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetTDLSLinkEstablishReqParamsType *wdiSetTDLSLinkEstablishReqParam = + (WDI_SetTDLSLinkEstablishReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetTDLSLinkEstablishReqParamsType)) ; + tWDA_ReqParams *pWdaParams = NULL; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiSetTDLSLinkEstablishReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pTdlsLinkEstablishParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pTdlsLinkEstablishParams); + vos_mem_free(wdiSetTDLSLinkEstablishReqParam); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.uStaIdx = + pTdlsLinkEstablishParams->staIdx; + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.uIsResponder = + pTdlsLinkEstablishParams->isResponder; + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.uUapsdQueues = + pTdlsLinkEstablishParams->uapsdQueues; + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.uMaxSp = + pTdlsLinkEstablishParams->maxSp; + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.uIsBufSta = + pTdlsLinkEstablishParams->isBufsta; + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.uIsOffChannelSupported = + pTdlsLinkEstablishParams->isOffChannelSupported; + + vos_mem_copy(wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.validChannels, + pTdlsLinkEstablishParams->validChannels, + pTdlsLinkEstablishParams->validChannelsLen); + + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.validChannelsLen = + pTdlsLinkEstablishParams->validChannelsLen; + + vos_mem_copy(wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.validOperClasses, + pTdlsLinkEstablishParams->validOperClasses, + pTdlsLinkEstablishParams->validOperClassesLen); + wdiSetTDLSLinkEstablishReqParam->wdiTDLSLinkEstablishInfo.validOperClassesLen = + pTdlsLinkEstablishParams->validOperClassesLen; + + wdiSetTDLSLinkEstablishReqParam->wdiReqStatusCB = NULL ; + /* Store msg pointer from PE, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pTdlsLinkEstablishParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetTDLSLinkEstablishReqParam ; + pWdaParams->pWdaContext = pWDA; + + status = WDI_SetTDLSLinkEstablishReq(wdiSetTDLSLinkEstablishReqParam, + (WDI_SetTDLSLinkEstablishReqParamsRspCb) + WDA_SetTDLSLinkEstablishReqParamsCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set P2P GO NOA Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +// tdlsoffchan +void WDA_SetTDLSChanSwitchReqParamsCallback(WDI_SetTdlsChanSwitchReqResp *wdiSetTdlsChanSwitchReqRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tTdlsChanSwitchParams *pTdlsChanSwitchParams; + + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + pTdlsChanSwitchParams = (tTdlsChanSwitchParams *)pWdaParams->wdaMsgParam ; + if( NULL == pTdlsChanSwitchParams ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pTdlsChanSwitchParams " + "received NULL " ,__func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; + } + pTdlsChanSwitchParams->status = CONVERT_WDI2SIR_STATUS( + wdiSetTdlsChanSwitchReqRsp->wdiStatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + /* send response to UMAC*/ + WDA_SendMsg(pWDA, WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP, pTdlsChanSwitchParams, 0) ; + + return ; +} +VOS_STATUS WDA_ProcessSetTdlsChanSwitchReq(tWDA_CbContext *pWDA, + tTdlsChanSwitchParams *pTdlsChanSwitchParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_SetTDLSChanSwitchReqParamsType *wdiSetTDLSChanSwitchReqParam = + (WDI_SetTDLSChanSwitchReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetTDLSChanSwitchReqParamsType)); + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Enter: %s ",__func__); + if(NULL == wdiSetTDLSChanSwitchReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pTdlsChanSwitchParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pTdlsChanSwitchParams); + vos_mem_free(wdiSetTDLSChanSwitchReqParam); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.staIdx = + pTdlsChanSwitchParams->staIdx; + wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.isOffchannelInitiator = + pTdlsChanSwitchParams->tdlsSwMode; + wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.targetOperClass = + pTdlsChanSwitchParams->operClass; + wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.targetChannel = + pTdlsChanSwitchParams->tdlsOffCh; + wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.secondaryChannelOffset = + pTdlsChanSwitchParams->tdlsOffChBwOffset; + + + /* Store msg pointer from PE, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pTdlsChanSwitchParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetTDLSChanSwitchReqParam ; + pWdaParams->pWdaContext = pWDA; + status = WDI_SetTDLSChanSwitchReq(wdiSetTDLSChanSwitchReqParam, + (WDI_SetTDLSChanSwitchReqParamsRspCb) + WDA_SetTDLSChanSwitchReqParamsCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in TDLS Channel Switch Req WDI API, free all the memory" ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} +#endif /*FEATURE_WLAN_TDLS*/ + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/* + * FUNCTION: WDA_AggrAddTSReqCallback + * send ADD AGGREGATED TS RSP back to PE + */ +void WDA_AggrAddTSReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + tWDA_CbContext *pWDA = NULL; + tAggrAddTsParams *pAggrAddTsReqParams; + int i; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pAggrAddTsReqParams = (tAggrAddTsParams *)pWdaParams->wdaMsgParam ; + + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + pAggrAddTsReqParams->status[i] = (status) ; + } + WDA_SendMsg(pWDA, WDA_AGGR_QOS_RSP, (void *)pAggrAddTsReqParams , 0) ; + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + return ; +}/* WLAN_FEATURE_VOWIFI_11R */ +/* + * FUNCTION: WDA_ProcessAddTSReq + * Request to WDI to send an update with AGGREGATED ADD TS REQ params. + */ +VOS_STATUS WDA_ProcessAggrAddTSReq(tWDA_CbContext *pWDA, + tAggrAddTsParams *pAggrAddTsReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + int i; + WDI_AggrAddTSReqParamsType *wdiAggrAddTSReqParam; + tWDA_ReqParams *pWdaParams = NULL; + + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiAggrAddTSReqParam = (WDI_AggrAddTSReqParamsType *)vos_mem_malloc( + sizeof(WDI_AggrAddTSReqParamsType)) ; + if(NULL == wdiAggrAddTSReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pAggrAddTsReqParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pAggrAddTsReqParams); + vos_mem_free(wdiAggrAddTSReqParam); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + wdiAggrAddTSReqParam->wdiAggrTsInfo.ucSTAIdx = pAggrAddTsReqParams->staIdx; + wdiAggrAddTSReqParam->wdiAggrTsInfo.ucTspecIdx = + pAggrAddTsReqParams->tspecIdx; + for( i = 0; i < WDI_MAX_NO_AC; i++ ) + { + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].ucType = pAggrAddTsReqParams->tspec[i].type; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].ucLength = + pAggrAddTsReqParams->tspec[i].length; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.ackPolicy = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.ackPolicy; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.userPrio = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.userPrio; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.psb = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.psb; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.aggregation = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.aggregation; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.accessPolicy = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.accessPolicy; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.direction = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.direction; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.tsid = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.tsid; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic.trafficType = + pAggrAddTsReqParams->tspec[i].tsinfo.traffic.trafficType; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiSchedule.schedule = + pAggrAddTsReqParams->tspec[i].tsinfo.schedule.schedule; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].usNomMsduSz = + pAggrAddTsReqParams->tspec[i].nomMsduSz; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].usMaxMsduSz = + pAggrAddTsReqParams->tspec[i].maxMsduSz; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uMinSvcInterval = + pAggrAddTsReqParams->tspec[i].minSvcInterval; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uMaxSvcInterval = + pAggrAddTsReqParams->tspec[i].maxSvcInterval; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uInactInterval = + pAggrAddTsReqParams->tspec[i].inactInterval; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uSuspendInterval = + pAggrAddTsReqParams->tspec[i].suspendInterval; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uSvcStartTime = + pAggrAddTsReqParams->tspec[i].svcStartTime; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uMinDataRate = + pAggrAddTsReqParams->tspec[i].minDataRate; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uMeanDataRate = + pAggrAddTsReqParams->tspec[i].meanDataRate; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uPeakDataRate = + pAggrAddTsReqParams->tspec[i].peakDataRate; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uMaxBurstSz = + pAggrAddTsReqParams->tspec[i].maxBurstSz; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uDelayBound = + pAggrAddTsReqParams->tspec[i].delayBound; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].uMinPhyRate = + pAggrAddTsReqParams->tspec[i].minPhyRate; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].usSurplusBw = + pAggrAddTsReqParams->tspec[i].surplusBw; + wdiAggrAddTSReqParam->wdiAggrTsInfo.wdiTspecIE[i].usMediumTime = + pAggrAddTsReqParams->tspec[i].mediumTime; + } + + /* TODO: tAggrAddTsParams doesn't have the following fields */ +#if 0 + wdiAggrAddTSReqParam->wdiTsInfo.ucUapsdFlags = + wdiAggrAddTSReqParam->wdiTsInfo.ucServiceInterval = + wdiAggrAddTSReqParam->wdiTsInfo.ucSuspendInterval = + wdiAggrAddTSReqParam->wdiTsInfo.ucDelayedInterval = +#endif + wdiAggrAddTSReqParam->wdiReqStatusCB = NULL ; + + /* Store ADD TS pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pAggrAddTsReqParams ; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiAggrAddTSReqParam ; + + pWdaParams->pWdaContext = pWDA; + + status = WDI_AggrAddTSReq(wdiAggrAddTSReqParam, + (WDI_AggrAddTsRspCb)WDA_AggrAddTSReqCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in ADD TS REQ Params WDI API, free all the memory " ); + + /* send the failure response back to PE*/ + for( i = 0; i < HAL_QOS_NUM_AC_MAX; i++ ) + { + pAggrAddTsReqParams->status[i] = eHAL_STATUS_FAILURE ; + } + + WDA_SendMsg(pWdaParams->pWdaContext, WDA_AGGR_QOS_RSP, + (void *)pAggrAddTsReqParams , 0) ; + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif +/* + * FUNCTION: WDA_EnterImpsRspCallback + * send Enter IMPS RSP back to PE + */ +void WDA_EnterImpsRspCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s status=%d" ,__func__,status); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + if (WDI_STATUS_SUCCESS != status) + { + pWDA->failureCounts.enterImpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.enterImpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Status %d fail count %d", __func__, status, + pWDA->failureCounts.enterImpsFailureCount); + pWDA->failureCounts.enterImpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ENTER_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + } + else + { + pWDA->failureCounts.enterImpsFailureCount = 0; + } + WDA_SendMsg(pWDA, WDA_ENTER_IMPS_RSP, NULL , status) ; + return ; +} + + +/* + * FUNCTION: WDA_EnterImpsReqCallback + * Free memory and send Enter IMPS RSP back to PE. + * Invoked when Enter IMPS REQ failed in WDI and no RSP callback is generated. + */ +void WDA_EnterImpsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pWDA->failureCounts.enterImpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.enterImpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdiStatus %d fail count %d", __func__, wdiStatus, + pWDA->failureCounts.enterImpsFailureCount); + pWDA->failureCounts.enterImpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ENTER_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + WDA_SendMsg(pWDA, WDA_ENTER_IMPS_RSP, NULL, + CONVERT_WDI2SIR_STATUS(wdiStatus)); + } + + return; +} +/* + * FUNCTION: WDA_ProcessEnterImpsReq + * Request to WDI to Enter IMPS power state. + */ +VOS_STATUS WDA_ProcessEnterImpsReq(tWDA_CbContext *pWDA) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_EnterImpsReqParamsType *wdiEnterImpsReqParams; + tWDA_ReqParams *pWdaParams; + static int failcnt = 0; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + + wdiEnterImpsReqParams = vos_mem_malloc(sizeof(WDI_EnterImpsReqParamsType)); + if (NULL == wdiEnterImpsReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + WDA_SendMsg(pWDA, WDA_ENTER_IMPS_RSP, NULL, + CONVERT_WDI2SIR_STATUS(WDI_STATUS_MEM_FAILURE)) ; + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiEnterImpsReqParams); + WDA_SendMsg(pWDA, WDA_ENTER_IMPS_RSP, NULL , + CONVERT_WDI2SIR_STATUS(WDI_STATUS_MEM_FAILURE)) ; + return VOS_STATUS_E_NOMEM; + } + + wdiEnterImpsReqParams->wdiReqStatusCB = WDA_EnterImpsReqCallback; + wdiEnterImpsReqParams->pUserData = pWdaParams; + + pWdaParams->wdaWdiApiMsgParam = wdiEnterImpsReqParams; + pWdaParams->wdaMsgParam = NULL; + pWdaParams->pWdaContext = pWDA; + + status = WDI_EnterImpsReq(wdiEnterImpsReqParams, + (WDI_EnterImpsRspCb)WDA_EnterImpsRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + if (! (failcnt & 0xF)) + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Enter IMPS REQ WDI API, free all the memory " ); + failcnt++; + vos_mem_free(wdiEnterImpsReqParams); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_ENTER_IMPS_RSP, NULL , CONVERT_WDI2SIR_STATUS(status)) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_ExitImpsRespCallback + * send Exit IMPS RSP back to PE + */ +void WDA_ExitImpsRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + if (WDI_STATUS_SUCCESS != status) + { + pWDA->failureCounts.exitImpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.exitImpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Status %d fail count %d", __func__, + status, + pWDA->failureCounts.exitImpsFailureCount); + pWDA->failureCounts.exitImpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_EXIT_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + } + else + { + pWDA->failureCounts.exitImpsFailureCount = 0; + } + + WDA_SendMsg(pWDA, WDA_EXIT_IMPS_RSP, NULL , (status)); + return; +} + +/* + * FUNCTION: WDA_ExitImpsReqCallback + */ +void WDA_ExitImpsReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (IS_WDI_STATUS_FAILURE(status)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + pWDA->failureCounts.exitImpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.exitImpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdiStatus %d fail count %d", __func__, + status, + pWDA->failureCounts.exitImpsFailureCount); + pWDA->failureCounts.exitImpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_EXIT_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + if (WDI_STATUS_DEV_INTERNAL_FAILURE == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("reload wlan driver")); + wpalWlanReload(); + } + } + return; +} + +/* + * FUNCTION: WDA_ProcessExitImpsReq + * Request to WDI to Exit IMPS power state. + */ +VOS_STATUS WDA_ProcessExitImpsReq(tWDA_CbContext *pWDA) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + tWDA_ReqParams *pWdaParams; + WDI_ExitImpsReqParamsType *wdiExitImpsReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiExitImpsReqParams = (WDI_ExitImpsReqParamsType *)vos_mem_malloc( + sizeof(WDI_ExitImpsReqParamsType)); + if (NULL == wdiExitImpsReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiExitImpsReqParams); + return VOS_STATUS_E_NOMEM; + } + wdiExitImpsReqParams->wdiReqStatusCB = WDA_ExitImpsReqCallback; + wdiExitImpsReqParams->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiExitImpsReqParams; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdiExitImpsReqParams; + status = WDI_ExitImpsReq(wdiExitImpsReqParams, + (WDI_ExitImpsRspCb)WDA_ExitImpsRespCallback, + pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Exit IMPS REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_EXIT_IMPS_RSP, NULL , CONVERT_WDI2SIR_STATUS(status)) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_EnterBmpsRespCallback + * send Enter BMPS RSP back to PE + */ +void WDA_EnterBmpsRespCallback(WDI_EnterBmpsRspParamsType *pwdiEnterBmpsRsp, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tEnterBmpsParams *pEnterBmpsRspParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + + if(pWdaParams->wdaWdiApiMsgParam) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pEnterBmpsRspParams = (tEnterBmpsParams *)pWdaParams->wdaMsgParam; + + pEnterBmpsRspParams->bssIdx = pwdiEnterBmpsRsp->bssIdx; + pEnterBmpsRspParams->status = (pwdiEnterBmpsRsp->wdiStatus); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams) ; + if (eHAL_STATUS_SUCCESS != pEnterBmpsRspParams->status) + { + pWDA->failureCounts.enterBmpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.enterBmpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdiStatus %d fail count %d", __func__, + pwdiEnterBmpsRsp->wdiStatus, + pWDA->failureCounts.enterBmpsFailureCount); + pWDA->failureCounts.enterBmpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ENTER_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + } + else + { + pWDA->failureCounts.enterBmpsFailureCount = 0; + } + WDA_SendMsg(pWDA, WDA_ENTER_BMPS_RSP, (void *)pEnterBmpsRspParams , 0); + + return ; +} +/* + * FUNCTION: WDA_EnterBmpsReqCallback + * Free memory and send Enter BMPS RSP back to PE. + * Invoked when Enter BMPS REQ failed in WDI and no RSP callback is generated. + */ +void WDA_EnterBmpsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tEnterBmpsParams *pEnterBmpsRspParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pEnterBmpsRspParams = (tEnterBmpsParams *)pWdaParams->wdaMsgParam; + pEnterBmpsRspParams->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pWDA->failureCounts.enterBmpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.enterBmpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdiStatus %d fail count %d", __func__, + wdiStatus, + pWDA->failureCounts.enterBmpsFailureCount); + pWDA->failureCounts.enterBmpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_ENTER_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + WDA_SendMsg(pWDA, WDA_ENTER_BMPS_RSP, (void *)pEnterBmpsRspParams, 0); + } + + return; +} +/* + * FUNCTION: WDA_ProcessEnterBmpsReq + * Request to WDI to Enter BMPS power state. + */ +VOS_STATUS WDA_ProcessEnterBmpsReq(tWDA_CbContext *pWDA, + tEnterBmpsParams *pEnterBmpsReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_EnterBmpsReqParamsType *wdiEnterBmpsReqParams; + tWDA_ReqParams *pWdaParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if ((NULL == pWDA) || (NULL == pEnterBmpsReqParams)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: invalid param", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + wdiEnterBmpsReqParams = vos_mem_malloc(sizeof(WDI_EnterBmpsReqParamsType)); + if (NULL == wdiEnterBmpsReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + WDA_SendMsg(pWDA, WDA_ENTER_BMPS_RSP, NULL , + CONVERT_WDI2SIR_STATUS(WDI_STATUS_MEM_FAILURE)) ; + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiEnterBmpsReqParams); + WDA_SendMsg(pWDA, WDA_ENTER_BMPS_RSP, NULL , + CONVERT_WDI2SIR_STATUS(WDI_STATUS_MEM_FAILURE)) ; + return VOS_STATUS_E_NOMEM; + } + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucBssIdx = pEnterBmpsReqParams->bssIdx; + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucDtimCount = pEnterBmpsReqParams->dtimCount; + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucDtimPeriod = pEnterBmpsReqParams->dtimPeriod; + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.uTbtt = pEnterBmpsReqParams->tbtt; + // For ESE and 11R Roaming + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.rssiFilterPeriod = (wpt_uint32)pEnterBmpsReqParams->rssiFilterPeriod; + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.numBeaconPerRssiAverage = (wpt_uint32)pEnterBmpsReqParams->numBeaconPerRssiAverage; + wdiEnterBmpsReqParams->wdiEnterBmpsInfo.bRssiFilterEnable = (wpt_uint8)pEnterBmpsReqParams->bRssiFilterEnable; + wdiEnterBmpsReqParams->wdiReqStatusCB = WDA_EnterBmpsReqCallback; + wdiEnterBmpsReqParams->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiEnterBmpsReqParams; + pWdaParams->wdaMsgParam = pEnterBmpsReqParams; + pWdaParams->pWdaContext = pWDA; + status = WDI_EnterBmpsReq(wdiEnterBmpsReqParams, + (WDI_EnterBmpsRspCb)WDA_EnterBmpsRespCallback, pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Enter BMPS REQ WDI API, free all the memory" ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_ENTER_BMPS_RSP, NULL , CONVERT_WDI2SIR_STATUS(status)) ; + } + return CONVERT_WDI2VOS_STATUS(status); +} + + +static void WDA_SendExitBmpsRsp(tWDA_CbContext *pWDA, + WDI_Status wdiStatus, + tExitBmpsParams *pExitBmpsReqParams) +{ + pExitBmpsReqParams->status = CONVERT_WDI2SIR_STATUS(wdiStatus) ; + + WDA_SendMsg(pWDA, WDA_EXIT_BMPS_RSP, (void *)pExitBmpsReqParams , 0) ; +} + + +/* + * FUNCTION: WDA_ExitBmpsRespCallback + * send Exit BMPS RSP back to PE + */ +void WDA_ExitBmpsRespCallback(WDI_ExitBmpsRspParamsType *pwdiExitBmpsRsp, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tExitBmpsParams *pExitBmpsRspParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + + if(pWdaParams->wdaWdiApiMsgParam) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pExitBmpsRspParams = (tExitBmpsParams *)pWdaParams->wdaMsgParam; + + pExitBmpsRspParams->bssIdx = pwdiExitBmpsRsp->bssIdx; + pExitBmpsRspParams->status = (pwdiExitBmpsRsp->wdiStatus); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + if (WDI_STATUS_SUCCESS != pwdiExitBmpsRsp->wdiStatus) + { + pWDA->failureCounts.exitBmpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.exitBmpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Status %d fail count %d", __func__, + pExitBmpsRspParams->status, + pWDA->failureCounts.exitBmpsFailureCount); + pWDA->failureCounts.exitBmpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_EXIT_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + } + else + { + pWDA->failureCounts.exitBmpsFailureCount = 0; + } + + WDA_SendMsg(pWDA, WDA_EXIT_BMPS_RSP, (void *)pExitBmpsRspParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_ExitBmpsReqCallback + * Free memory and send Exit BMPS RSP back to PE. + * Invoked when Exit BMPS REQ failed in WDI and no RSP callback is generated. + */ +void WDA_ExitBmpsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tExitBmpsParams *pExitBmpsRspParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pExitBmpsRspParams = (tExitBmpsParams *)pWdaParams->wdaMsgParam; + pExitBmpsRspParams->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + pWDA->failureCounts.exitBmpsFailureCount++; + if (BMPS_IMPS_FAILURE_REPORT_THRESHOLD == + pWDA->failureCounts.exitBmpsFailureCount) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wdiStatus %d fail count %d", __func__, + wdiStatus, + pWDA->failureCounts.exitBmpsFailureCount); + pWDA->failureCounts.exitBmpsFailureCount = 0; + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_EXIT_IMPS_BMPS_FAIL, + FALSE, TRUE); + } + WDA_SendMsg(pWDA, WDA_EXIT_BMPS_RSP, (void *)pExitBmpsRspParams, 0); + } + + return; +} +/* + * FUNCTION: WDA_ProcessExitBmpsReq + * Request to WDI to Exit BMPS power state. + */ +VOS_STATUS WDA_ProcessExitBmpsReq(tWDA_CbContext *pWDA, + tExitBmpsParams *pExitBmpsReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_ExitBmpsReqParamsType *wdiExitBmpsReqParams = + (WDI_ExitBmpsReqParamsType *)vos_mem_malloc( + sizeof(WDI_ExitBmpsReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiExitBmpsReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + WDA_SendExitBmpsRsp(pWDA, WDI_STATUS_MEM_FAILURE, pExitBmpsReqParams); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiExitBmpsReqParams); + return VOS_STATUS_E_NOMEM; + } + wdiExitBmpsReqParams->wdiExitBmpsInfo.ucSendDataNull = pExitBmpsReqParams->sendDataNull; + + wdiExitBmpsReqParams->wdiExitBmpsInfo.bssIdx = pExitBmpsReqParams->bssIdx; + + wdiExitBmpsReqParams->wdiReqStatusCB = WDA_ExitBmpsReqCallback; + wdiExitBmpsReqParams->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiExitBmpsReqParams; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pExitBmpsReqParams; + status = WDI_ExitBmpsReq(wdiExitBmpsReqParams, + (WDI_ExitBmpsRspCb)WDA_ExitBmpsRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Exit BMPS REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + WDA_SendExitBmpsRsp(pWDA, status, pExitBmpsReqParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_EnterUapsdRespCallback + * send Enter UAPSD RSP back to PE + */ +void WDA_EnterUapsdRespCallback( WDI_EnterUapsdRspParamsType *pwdiEnterUapsdRspParams, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tUapsdParams *pEnterUapsdRsqParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + + if(pWdaParams->wdaWdiApiMsgParam) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pEnterUapsdRsqParams = (tUapsdParams *)pWdaParams->wdaMsgParam; + + pEnterUapsdRsqParams->bssIdx = pwdiEnterUapsdRspParams->bssIdx; + pEnterUapsdRsqParams->status = (pwdiEnterUapsdRspParams->wdiStatus); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + WDA_SendMsg(pWDA, WDA_ENTER_UAPSD_RSP, (void *)pEnterUapsdRsqParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_EnterUapsdReqCallback + * Free memory and send Enter UAPSD RSP back to PE. + * Invoked when Enter UAPSD REQ failed in WDI and no RSP callback is generated. + */ +void WDA_EnterUapsdReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tUapsdParams *pEnterUapsdRsqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pEnterUapsdRsqParams = (tUapsdParams *)pWdaParams->wdaMsgParam; + pEnterUapsdRsqParams->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_ENTER_UAPSD_RSP, (void *)pEnterUapsdRsqParams, 0); + } + + return; +} +/* + * FUNCTION: WDA_ProcessEnterUapsdReq + * Request to WDI to Enter UAPSD power state. + */ +VOS_STATUS WDA_ProcessEnterUapsdReq(tWDA_CbContext *pWDA, + tUapsdParams *pEnterUapsdReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_EnterUapsdReqParamsType *wdiEnterUapsdReqParams = + (WDI_EnterUapsdReqParamsType *)vos_mem_malloc( + sizeof(WDI_EnterUapsdReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiEnterUapsdReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiEnterUapsdReqParams); + return VOS_STATUS_E_NOMEM; + } + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBeDeliveryEnabled = + pEnterUapsdReqParams->beDeliveryEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBeTriggerEnabled = + pEnterUapsdReqParams->beTriggerEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBkDeliveryEnabled = + pEnterUapsdReqParams->bkDeliveryEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBkTriggerEnabled = + pEnterUapsdReqParams->bkTriggerEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucViDeliveryEnabled = + pEnterUapsdReqParams->viDeliveryEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucViTriggerEnabled = + pEnterUapsdReqParams->viTriggerEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucVoDeliveryEnabled = + pEnterUapsdReqParams->voDeliveryEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucVoTriggerEnabled = + pEnterUapsdReqParams->voTriggerEnabled; + wdiEnterUapsdReqParams->wdiEnterUapsdInfo.bssIdx = pEnterUapsdReqParams->bssIdx; + + wdiEnterUapsdReqParams->wdiReqStatusCB = WDA_EnterUapsdReqCallback; + wdiEnterUapsdReqParams->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiEnterUapsdReqParams; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pEnterUapsdReqParams; + status = WDI_EnterUapsdReq(wdiEnterUapsdReqParams, + (WDI_EnterUapsdRspCb)WDA_EnterUapsdRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Enter UAPSD REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_ExitUapsdRespCallback + * send Exit UAPSD RSP back to PE + */ +void WDA_ExitUapsdRespCallback(WDI_ExitUapsdRspParamsType *pwdiExitRspParam, void* pUserData) +{ + + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tExitUapsdParams *pExitUapsdRspParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + pExitUapsdRspParams = (tExitUapsdParams *)pWdaParams->wdaMsgParam; + + pExitUapsdRspParams->bssIdx = pwdiExitRspParam->bssIdx; + pExitUapsdRspParams->status = (pwdiExitRspParam->wdiStatus); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + WDA_SendMsg(pWDA, WDA_EXIT_UAPSD_RSP, (void *)pExitUapsdRspParams, 0) ; + return ; +} +/* + * FUNCTION: WDA_ExitUapsdReqCallback + * Free memory and send Exit UAPSD RSP back to PE. + * Invoked when Exit UAPSD REQ failed in WDI and no RSP callback is generated. + */ +void WDA_ExitUapsdReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tExitUapsdParams *pExitUapsdRspParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pExitUapsdRspParams = (tExitUapsdParams *)pWdaParams->wdaMsgParam; + pExitUapsdRspParams->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_EXIT_UAPSD_RSP, (void *)pExitUapsdRspParams, 0); + } + + return; +} +/* + * FUNCTION: WDA_ProcessExitUapsdReq + * Request to WDI to Exit UAPSD power state. + */ +VOS_STATUS WDA_ProcessExitUapsdReq(tWDA_CbContext *pWDA, + tExitUapsdParams *pExitUapsdParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + tWDA_ReqParams *pWdaParams ; + WDI_ExitUapsdReqParamsType *wdiExitUapsdReqParams = + (WDI_ExitUapsdReqParamsType *)vos_mem_malloc( + sizeof(WDI_ExitUapsdReqParamsType)) ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if(NULL == wdiExitUapsdReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiExitUapsdReqParams); + return VOS_STATUS_E_NOMEM; + } + + wdiExitUapsdReqParams->wdiExitUapsdInfo.bssIdx = pExitUapsdParams->bssIdx; + wdiExitUapsdReqParams->wdiReqStatusCB = WDA_ExitUapsdReqCallback; + wdiExitUapsdReqParams->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiExitUapsdReqParams; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pExitUapsdParams; + + status = WDI_ExitUapsdReq(wdiExitUapsdReqParams, (WDI_ExitUapsdRspCb)WDA_ExitUapsdRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Exit UAPSD REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_SetPwrSaveCfgReqCallback + * + */ +void WDA_SetPwrSaveCfgReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if( pWdaParams != NULL ) + { + if( pWdaParams->wdaWdiApiMsgParam != NULL ) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if( pWdaParams->wdaMsgParam != NULL ) + { + vos_mem_free(pWdaParams->wdaMsgParam) ; + } + vos_mem_free(pWdaParams) ; + } + return ; +} +/* + * FUNCTION: WDA_ProcessSetPwrSaveCfgReq + * Request to WDI to set the power save params at start. + */ +VOS_STATUS WDA_ProcessSetPwrSaveCfgReq(tWDA_CbContext *pWDA, + tSirPowerSaveCfg *pPowerSaveCfg) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + tHalCfg *tlvStruct = NULL ; + tANI_U8 *tlvStructStart = NULL ; + v_PVOID_t *configParam; + tANI_U32 configParamSize; + tANI_U32 *configDataValue; + WDI_UpdateCfgReqParamsType *wdiPowerSaveCfg; + tWDA_ReqParams *pWdaParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if ((NULL == pWDA) || (NULL == pPowerSaveCfg)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: invalid param", __func__); + VOS_ASSERT(0); + vos_mem_free(pPowerSaveCfg); + return VOS_STATUS_E_FAILURE; + } + wdiPowerSaveCfg = vos_mem_malloc(sizeof(WDI_UpdateCfgReqParamsType)); + if (NULL == wdiPowerSaveCfg) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pPowerSaveCfg); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiPowerSaveCfg); + vos_mem_free(pPowerSaveCfg); + return VOS_STATUS_E_NOMEM; + } + configParamSize = (sizeof(tHalCfg) + (sizeof(tANI_U32))) * WDA_NUM_PWR_SAVE_CFG; + configParam = vos_mem_malloc(configParamSize); + if(NULL == configParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + vos_mem_free(wdiPowerSaveCfg); + vos_mem_free(pPowerSaveCfg); + return VOS_STATUS_E_NOMEM; + } + vos_mem_set(configParam, configParamSize, 0); + wdiPowerSaveCfg->pConfigBuffer = configParam; + tlvStruct = (tHalCfg *)configParam; + tlvStructStart = (tANI_U8 *)configParam; + /* QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE */ + tlvStruct->type = QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->broadcastFrameFilter; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD */ + tlvStruct->type = QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->HeartBeatCount; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_IGNORE_DTIM */ + tlvStruct->type = QWLAN_HAL_CFG_PS_IGNORE_DTIM; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->ignoreDtim; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_LISTEN_INTERVAL */ + tlvStruct->type = QWLAN_HAL_CFG_PS_LISTEN_INTERVAL; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->listenInterval; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_MAX_PS_POLL */ + tlvStruct->type = QWLAN_HAL_CFG_PS_MAX_PS_POLL; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->maxPsPoll; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD */ + tlvStruct->type = QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->minRssiThreshold; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER */ + tlvStruct->type = QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->nthBeaconFilter; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM */ + tlvStruct->type = QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->fEnableBeaconEarlyTermination; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL */ + tlvStruct->type = QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->bcnEarlyTermWakeInterval; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE */ + tlvStruct->type = QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->numBeaconPerRssiAverage; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + /* QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD */ + tlvStruct->type = QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD; + tlvStruct->length = sizeof(tANI_U32); + configDataValue = (tANI_U32 *)(tlvStruct + 1); + *configDataValue = (tANI_U32)pPowerSaveCfg->rssiFilterPeriod; + tlvStruct = (tHalCfg *)(( (tANI_U8 *) tlvStruct + + sizeof(tHalCfg) + tlvStruct->length)) ; + wdiPowerSaveCfg->uConfigBufferLen = (tANI_U8 *)tlvStruct - tlvStructStart ; + wdiPowerSaveCfg->wdiReqStatusCB = NULL; + /* store Params pass it to WDI */ + pWdaParams->wdaMsgParam = configParam; + pWdaParams->wdaWdiApiMsgParam = wdiPowerSaveCfg; + pWdaParams->pWdaContext = pWDA; + status = WDI_SetPwrSaveCfgReq(wdiPowerSaveCfg, + (WDI_SetPwrSaveCfgCb)WDA_SetPwrSaveCfgReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set Pwr Save CFG REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + } + vos_mem_free(pPowerSaveCfg); + return CONVERT_WDI2VOS_STATUS(status); +} +/* + * FUNCTION: WDA_SetUapsdAcParamsRespCallback + * + */ +void WDA_SetUapsdAcParamsRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + return ; +} +/* + * FUNCTION: WDA_SetUapsdAcParamsReqCallback + * Free memory. + * Invoked when SetUAPSDACParams REQ failed in WDI and no RSP callback is generated. + */ +void WDA_SetUapsdAcParamsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_SetUapsdAcParamsReq + * Request to WDI to set the UAPSD params for an ac (sta mode). + */ +VOS_STATUS WDA_SetUapsdAcParamsReq(v_PVOID_t pVosContext, v_U8_t staIdx, + tUapsdInfo *pUapsdInfo) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_CbContext *pWDA = NULL ; + WDI_SetUapsdAcParamsReqParamsType *wdiUapsdParams = + (WDI_SetUapsdAcParamsReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetUapsdAcParamsReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiUapsdParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiUapsdParams); + return VOS_STATUS_E_NOMEM; + } + wdiUapsdParams->wdiUapsdInfo.ucAc = pUapsdInfo->ac; + wdiUapsdParams->wdiUapsdInfo.uDelayInterval = pUapsdInfo->delayInterval; + wdiUapsdParams->wdiUapsdInfo.uSrvInterval = pUapsdInfo->srvInterval; + wdiUapsdParams->wdiUapsdInfo.ucSTAIdx = pUapsdInfo->staidx; + wdiUapsdParams->wdiUapsdInfo.uSusInterval = pUapsdInfo->susInterval; + wdiUapsdParams->wdiUapsdInfo.ucUp = pUapsdInfo->up; + wdiUapsdParams->wdiReqStatusCB = WDA_SetUapsdAcParamsReqCallback; + wdiUapsdParams->pUserData = pWdaParams; + + pWDA = vos_get_context( VOS_MODULE_ID_WDA, pVosContext ); + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pUapsdInfo; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiUapsdParams; + status = WDI_SetUapsdAcParamsReq(wdiUapsdParams, + (WDI_SetUapsdAcParamsCb)WDA_SetUapsdAcParamsRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set UAPSD params REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + } + if((WDI_STATUS_SUCCESS == status) || (WDI_STATUS_PENDING == status)) + return VOS_STATUS_SUCCESS; + else + return VOS_STATUS_E_FAILURE; + +} +/* + * FUNCTION: WDA_ClearUapsdAcParamsReq + * Currently the WDA API is a NOP. It has been added for symmetry & Also it was + * decided that the if the UPASD parameters change, FW would get a exit UAPSD + * and again enter the UPASD with the modified params. Hence the disable + * function was kept empty. + * + */ +VOS_STATUS WDA_ClearUapsdAcParamsReq(v_PVOID_t pVosContext, v_U8_t staIdx, wpt_uint8 ac) +{ + /* do nothing */ + return VOS_STATUS_SUCCESS; +} +/* + * FUNCTION: WDA_UpdateUapsdParamsRespCallback + * + */ +void WDA_UpdateUapsdParamsRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_UpdateUapsdParamsRespCallback invoked " ); + return ; +} +/* + * FUNCTION: WDA_UpdateUapsdParamsReqCallback + * Free memory. + * Invoked when UpdateUAPSDParams REQ failed in WDI and no RSP callback is generated. + */ +void WDA_UpdateUapsdParamsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_UpdateUapsdParamsReq + * Request to WDI to update UAPSD params (in softAP mode) for a station. + */ +VOS_STATUS WDA_UpdateUapsdParamsReq(tWDA_CbContext *pWDA, + tUpdateUapsdParams* pUpdateUapsdInfo) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_UpdateUapsdReqParamsType *wdiUpdateUapsdParams = + (WDI_UpdateUapsdReqParamsType *)vos_mem_malloc( + sizeof(WDI_UpdateUapsdReqParamsType)) ; + tWDA_ReqParams *pWdaParams = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiUpdateUapsdParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + wdiUpdateUapsdParams->wdiUpdateUapsdInfo.uMaxSpLen = pUpdateUapsdInfo->maxSpLen; + wdiUpdateUapsdParams->wdiUpdateUapsdInfo.ucSTAIdx = pUpdateUapsdInfo->staIdx; + wdiUpdateUapsdParams->wdiUpdateUapsdInfo.ucUapsdACMask = pUpdateUapsdInfo->uapsdACMask; + wdiUpdateUapsdParams->wdiReqStatusCB = WDA_UpdateUapsdParamsReqCallback; + wdiUpdateUapsdParams->pUserData = pWdaParams; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pUpdateUapsdInfo); + vos_mem_free(wdiUpdateUapsdParams); + return VOS_STATUS_E_NOMEM; + } + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pUpdateUapsdInfo; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiUpdateUapsdParams; + pWdaParams->pWdaContext = pWDA; + + wstatus = WDI_UpdateUapsdParamsReq(wdiUpdateUapsdParams, + (WDI_UpdateUapsdParamsCb)WDA_UpdateUapsdParamsRespCallback, + pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set UAPSD params REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return status; +} +/* + * FUNCTION: WDA_ConfigureRxpFilterRespCallback + * + */ +void WDA_ConfigureRxpFilterRespCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(WDI_STATUS_SUCCESS != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: RXP config filter failure", __func__ ); + } + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + return ; +} +/* + * FUNCTION: WDA_ConfigureRxpFilterReqCallback + * Free memory. + * Invoked when ConfigureRXPFilter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_ConfigureRxpFilterReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessConfigureRxpFilterReq + * + */ +VOS_STATUS WDA_ProcessConfigureRxpFilterReq(tWDA_CbContext *pWDA, + tSirWlanSetRxpFilters *pWlanSuspendParam) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_ConfigureRxpFilterReqParamsType *wdiRxpFilterParams; + tWDA_ReqParams *pWdaParams ; + /* Sanity Check + * This is very unlikely and add assert to collect more info next time */ + if(NULL == pWlanSuspendParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWlanSuspendParam received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + wdiRxpFilterParams = (WDI_ConfigureRxpFilterReqParamsType *)vos_mem_malloc( + sizeof(WDI_ConfigureRxpFilterReqParamsType)) ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiRxpFilterParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pWlanSuspendParam); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiRxpFilterParams); + vos_mem_free(pWlanSuspendParam); + return VOS_STATUS_E_NOMEM; + } + wdiRxpFilterParams->wdiRxpFilterParam.ucSetMcstBcstFilter = + pWlanSuspendParam->setMcstBcstFilter; + wdiRxpFilterParams->wdiRxpFilterParam.ucSetMcstBcstFilterSetting = + pWlanSuspendParam->configuredMcstBcstFilterSetting; + + wdiRxpFilterParams->wdiReqStatusCB = WDA_ConfigureRxpFilterReqCallback; + wdiRxpFilterParams->pUserData = pWdaParams; + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pWlanSuspendParam; + pWdaParams->wdaWdiApiMsgParam = (void *)wdiRxpFilterParams; + wstatus = WDI_ConfigureRxpFilterReq(wdiRxpFilterParams, + (WDI_ConfigureRxpFilterCb)WDA_ConfigureRxpFilterRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in configure RXP filter REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return status; +} + +/* + * FUNCTION: WDA_ProcessGetFrameLogReq + * Request to WDI to get the Frame Log. + */ +VOS_STATUS WDA_ProcessGetFrameLogReq(tWDA_CbContext *pWDA, + tAniGetFrameLogReq *pGetFrameLog) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_GetFrameLogReqInfoType *wdiGetFrameLogInfo; + tWDA_ReqParams *pWdaParams ; + + /* Sanity Check*/ + if(NULL == pGetFrameLog) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFWLoggingInitParam received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiGetFrameLogInfo = (WDI_GetFrameLogReqInfoType *)vos_mem_malloc( + sizeof(WDI_GetFrameLogReqInfoType)); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if(NULL == wdiGetFrameLogInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pGetFrameLog); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiGetFrameLogInfo); + vos_mem_free(pGetFrameLog); + return VOS_STATUS_E_NOMEM; + } + + wdiGetFrameLogInfo->flags = pGetFrameLog->getFrameLogCmdFlag; + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pGetFrameLog; + pWdaParams->wdaWdiApiMsgParam = (void *)wdiGetFrameLogInfo; + + wstatus = WDI_GetFrameLogReq(wdiGetFrameLogInfo, + (WDI_GetFrameLogRspCb)WDA_GetFrameLogRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in get frame log REQ WDI API, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return status; +} + + +/* + * FUNCTION: WDA_FatalEventLogsRspCallback + * recieves Flush Logs response from FW + */ + +void WDA_FatalEventLogsRspCallback(WDI_FatalEventLogsRspParamType* wdiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s,wdiStatus:%d " , + __func__, wdiRsp->wdiStatus); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == pWdaParams->wdaMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + if(IS_WDI_STATUS_FAILURE(wdiRsp->wdiStatus)) + { + /* + * If it is failure, it means JOb is already posted by FW + * for logging, so for failure scenario also we will get the + * done indication + */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Fatal Event Rsp Failure,wdiStatus : %d ", + __func__, wdiRsp->wdiStatus); + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; + +} + +/* + * FUNCTION: WDA_ProcessFatalEventLogsReq + * Request to WDI to send the fatal Event Logs Req. + */ + +VOS_STATUS WDA_ProcessFatalEventLogsReq(tWDA_CbContext *pWDA, + tSirFatalEventLogsReqParam *pFatalEventLogsReqParam) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_FatalEventLogsReqInfoType *wdiFatalEventLogsReqInfo; + tWDA_ReqParams *pWdaParams ; + WDI_Status wstatus; + + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if (NULL == pFatalEventLogsReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pMgmtLoggingInitParam received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + wdiFatalEventLogsReqInfo = (WDI_FatalEventLogsReqInfoType *)vos_mem_malloc( + sizeof(WDI_FatalEventLogsReqInfoType)); + if(NULL == wdiFatalEventLogsReqInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pFatalEventLogsReqParam); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiFatalEventLogsReqInfo); + vos_mem_free(pFatalEventLogsReqParam); + return VOS_STATUS_E_NOMEM; + } + wdiFatalEventLogsReqInfo->reason_code = pFatalEventLogsReqParam->reason_code; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pFatalEventLogsReqParam; + pWdaParams->wdaWdiApiMsgParam = (void *)wdiFatalEventLogsReqInfo; + + wstatus = WDI_FatalEventLogsReq(wdiFatalEventLogsReqInfo, + (WDI_FatalEventLogsRspCb)WDA_FatalEventLogsRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Mgmt Logging init REQ WDI API, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return status; + +} + +/* + * FUNCTION: WDA_ProcessFWLoggingInitReq + * + */ +VOS_STATUS WDA_ProcessFWLoggingInitReq(tWDA_CbContext *pWDA, + tSirFWLoggingInitParam *pFWLoggingInitParam) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_FWLoggingInitReqInfoType *wdiFWLoggingInitInfo; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + /* Sanity Check*/ + if(NULL == pFWLoggingInitParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFWLoggingInitParam received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiFWLoggingInitInfo = (WDI_FWLoggingInitReqInfoType *)vos_mem_malloc( + sizeof(WDI_FWLoggingInitReqInfoType)); + if(NULL == wdiFWLoggingInitInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pFWLoggingInitParam); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiFWLoggingInitInfo); + vos_mem_free(pFWLoggingInitParam); + return VOS_STATUS_E_NOMEM; + } + + wdiFWLoggingInitInfo->enableFlag = pFWLoggingInitParam->enableFlag; + wdiFWLoggingInitInfo->frameType = pFWLoggingInitParam->frameType; + wdiFWLoggingInitInfo->frameSize = pFWLoggingInitParam->frameSize; + wdiFWLoggingInitInfo->bufferMode = pFWLoggingInitParam->bufferMode; + wdiFWLoggingInitInfo->continuousFrameLogging = + pFWLoggingInitParam->continuousFrameLogging; + wdiFWLoggingInitInfo->minLogBufferSize= + pFWLoggingInitParam->minLogBufferSize; + wdiFWLoggingInitInfo->maxLogBufferSize= + pFWLoggingInitParam->maxLogBufferSize; + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pFWLoggingInitParam; + pWdaParams->wdaWdiApiMsgParam = (void *)wdiFWLoggingInitInfo; + + wstatus = WDI_FWLoggingInitReq(wdiFWLoggingInitInfo, + (WDI_FWLoggingInitRspCb)WDA_FWLoggingInitRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Mgmt Logging init REQ WDI API, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return status; +} + +/* + * FUNCTION: WDA_ProcessStartRssiMonitorReq + * + */ +VOS_STATUS WDA_ProcessStartRssiMonitorReq(tWDA_CbContext *pWDA, + tSirRssiMonitorReq *pRssiMonitorReqParam) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_RssiMonitorReqInfoType *wdiRssiMonitorInfo; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + /* Sanity Check*/ + if(NULL == pRssiMonitorReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pRssiMonitorReqParam received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiRssiMonitorInfo = (WDI_RssiMonitorReqInfoType *)vos_mem_malloc( + sizeof(WDI_RssiMonitorReqInfoType)); + if(NULL == wdiRssiMonitorInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pRssiMonitorReqParam); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiRssiMonitorInfo); + vos_mem_free(pRssiMonitorReqParam); + return VOS_STATUS_E_NOMEM; + } + + wdiRssiMonitorInfo->requestId = pRssiMonitorReqParam->requestId; + wdiRssiMonitorInfo->minRssi = pRssiMonitorReqParam->minRssi; + wdiRssiMonitorInfo->maxRssi = pRssiMonitorReqParam->maxRssi; + vos_mem_copy(wdiRssiMonitorInfo->currentBssId, + &(pRssiMonitorReqParam->currentBssId), sizeof(tSirMacAddr)); + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pRssiMonitorReqParam; + pWdaParams->wdaWdiApiMsgParam = (void *)wdiRssiMonitorInfo; + + wstatus = WDI_StartRssiMonitorReq(wdiRssiMonitorInfo, + (WDI_RssiMonitorStartRspCb)WDA_RssiMonitorStartRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Mgmt Logging init REQ WDI API, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return status; +} + +/* + * FUNCTION: WDA_ProcessStopRssiMonitorReq + * + */ +VOS_STATUS WDA_ProcessStopRssiMonitorReq(tWDA_CbContext *pWDA, + tSirRssiMonitorReq *pRssiMonitorReqParam) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_RssiMonitorReqInfoType *wdiRssiMonitorInfo; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + /* Sanity Check*/ + if(NULL == pRssiMonitorReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pRssiMonitorReqParam received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiRssiMonitorInfo = (WDI_RssiMonitorReqInfoType *)vos_mem_malloc( + sizeof(WDI_RssiMonitorReqInfoType)); + if(NULL == wdiRssiMonitorInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pRssiMonitorReqParam); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiRssiMonitorInfo); + vos_mem_free(pRssiMonitorReqParam); + return VOS_STATUS_E_NOMEM; + } + + wdiRssiMonitorInfo->requestId = pRssiMonitorReqParam->requestId; + vos_mem_copy(wdiRssiMonitorInfo->currentBssId, + &(pRssiMonitorReqParam->currentBssId), sizeof(tSirMacAddr)); + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pRssiMonitorReqParam; + pWdaParams->wdaWdiApiMsgParam = (void *)wdiRssiMonitorInfo; + + wstatus = WDI_StopRssiMonitorReq(wdiRssiMonitorInfo, + (WDI_RssiMonitorStopRspCb)WDA_RssiMonitorStopRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Mgmt Logging init REQ WDI API, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return status; +} + + +/* + * FUNCTION: WDA_WdiIndicationCallback + * + */ +void WDA_WdiIndicationCallback( WDI_Status wdiStatus, + void* pUserData) +{ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); +} + +/** + * WDA_ProcessWlanSuspendIndCallback: callback API for WDA_ProcessWlanSuspendInd + * @wdiStatus: wdi status + * @pUserData: suspend params + * + * Return: None + */ +void WDA_ProcessWlanSuspendIndCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirWlanSuspendParam *pWlanSuspendParam; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + return; + } + + pWlanSuspendParam = (tSirWlanSuspendParam *)pWdaParams->wdaMsgParam; + if (pWlanSuspendParam == NULL) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: suspend params NULL", __func__); + vos_mem_free(pWdaParams); + return; + } + if (pWlanSuspendParam->wlan_sus_callback) + { + pWlanSuspendParam->wlan_sus_callback(pWlanSuspendParam->context, + CONVERT_WDI2VOS_STATUS(wdiStatus)); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wlan suspend callback is NULL", __func__); + } + if (pWdaParams->wdaMsgParam) { + vos_mem_free(pWdaParams->wdaMsgParam); + pWdaParams->wdaMsgParam = NULL; + } + vos_mem_free(pWdaParams); + return; +} + +/* + * FUNCTION: WDA_ProcessWlanSuspendInd + * + */ +VOS_STATUS WDA_ProcessWlanSuspendInd(tWDA_CbContext *pWDA, + tSirWlanSuspendParam *pWlanSuspendParam) +{ + WDI_Status wdiStatus; + WDI_SuspendParamsType wdiSuspendParams; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiSuspendParams.wdiSuspendParams.ucConfiguredMcstBcstFilterSetting = + pWlanSuspendParam->configuredMcstBcstFilterSetting; + wdiSuspendParams.wdiReqStatusCB = WDA_ProcessWlanSuspendIndCallback; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (!pWdaParams) + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s memory allocation failed" ,__func__); + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pWlanSuspendParam; + wdiSuspendParams.pUserData = pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, "%s: %d" ,__func__, pWlanSuspendParam->configuredMcstBcstFilterSetting); + wdiStatus = WDI_HostSuspendInd(&wdiSuspendParams); + if(WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if( WDI_STATUS_SUCCESS_SYNC != wdiStatus ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d ",__func__,__LINE__ ); + } + return CONVERT_WDI2VOS_STATUS(wdiStatus) ; +} + +#ifdef WLAN_FEATURE_11W +/* + * FUNCTION: WDA_ProcessExcludeUnecryptInd + * + */ +VOS_STATUS WDA_ProcessExcludeUnecryptInd(tWDA_CbContext *pWDA, + tSirWlanExcludeUnencryptParam *pExclUnencryptParam) +{ + WDI_Status wdiStatus; + WDI_ExcludeUnencryptIndType wdiExclUnencryptParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s ", __func__); + + wdiExclUnencryptParams.bExcludeUnencrypt = pExclUnencryptParam->excludeUnencrypt; + vos_mem_copy(wdiExclUnencryptParams.bssid, pExclUnencryptParam->bssId, + sizeof(tSirMacAddr)); + + wdiExclUnencryptParams.wdiReqStatusCB = NULL; + wdiExclUnencryptParams.pUserData = pWDA; + + wdiStatus = WDI_ExcludeUnencryptedInd(&wdiExclUnencryptParams); + if(WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ", __func__, __LINE__ ); + } + else if( WDI_STATUS_SUCCESS_SYNC != wdiStatus ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d ", __func__, __LINE__ ); + } + vos_mem_free(pExclUnencryptParam); + return CONVERT_WDI2VOS_STATUS(wdiStatus) ; +} +#endif + +/* + * FUNCTION: WDA_ProcessWlanResumeCallback + * + */ +void WDA_ProcessWlanResumeCallback( + WDI_SuspendResumeRspParamsType *resumeRspParams, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if(WDI_STATUS_SUCCESS != resumeRspParams->wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Process Wlan Resume failure", __func__ ); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + return ; +} +/* + * FUNCTION: WDA_ProcessWlanResumeReq + * + */ +VOS_STATUS WDA_ProcessWlanResumeReq(tWDA_CbContext *pWDA, + tSirWlanResumeParam *pWlanResumeParam) +{ + WDI_Status wdiStatus; + WDI_ResumeParamsType *wdiResumeParams = + (WDI_ResumeParamsType *)vos_mem_malloc( + sizeof(WDI_ResumeParamsType) ) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiResumeParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiResumeParams); + return VOS_STATUS_E_NOMEM; + } + wdiResumeParams->wdiResumeParams.ucConfiguredMcstBcstFilterSetting = + pWlanResumeParam->configuredMcstBcstFilterSetting; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, "%s: %d" ,__func__, pWlanResumeParam->configuredMcstBcstFilterSetting); + wdiResumeParams->wdiReqStatusCB = NULL; + pWdaParams->wdaMsgParam = pWlanResumeParam; + pWdaParams->wdaWdiApiMsgParam = wdiResumeParams; + pWdaParams->pWdaContext = pWDA; + wdiStatus = WDI_HostResumeReq(wdiResumeParams, + (WDI_HostResumeEventRspCb)WDA_ProcessWlanResumeCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Host Resume REQ WDI API, free all the memory " ); + VOS_ASSERT(0); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(wdiStatus) ; +} + +/* + * FUNCTION: WDA_SetBeaconFilterRespCallback + * + */ +void WDA_SetBeaconFilterRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* + * No respone required for SetBeaconFilter req so just free the request + * param here + */ + + return ; +} +/* + * FUNCTION: WDA_SetBeaconFilterReqCallback + * Free memory. + * Invoked when SetBeaconFilter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_SetBeaconFilterReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_SetBeaconFilterReq + * Request to WDI to send the beacon filtering related information. + */ +VOS_STATUS WDA_SetBeaconFilterReq(tWDA_CbContext *pWDA, + tBeaconFilterMsg* pBeaconFilterInfo) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tANI_U8 *dstPtr, *srcPtr; + tANI_U8 filterLength; + WDI_BeaconFilterReqParamsType *wdiBeaconFilterInfo = + (WDI_BeaconFilterReqParamsType *)vos_mem_malloc( + sizeof(WDI_BeaconFilterReqParamsType) ) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiBeaconFilterInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiBeaconFilterInfo); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(wdiBeaconFilterInfo, sizeof(WDI_BeaconFilterReqParamsType)); + wdiBeaconFilterInfo->wdiBeaconFilterInfo.usBeaconInterval = + pBeaconFilterInfo->beaconInterval; + wdiBeaconFilterInfo->wdiBeaconFilterInfo.usCapabilityInfo = + pBeaconFilterInfo->capabilityInfo; + wdiBeaconFilterInfo->wdiBeaconFilterInfo.usCapabilityMask = + pBeaconFilterInfo->capabilityMask; + wdiBeaconFilterInfo->wdiBeaconFilterInfo.usIeNum = pBeaconFilterInfo->ieNum; + + //Fill the BssIdx + wdiBeaconFilterInfo->wdiBeaconFilterInfo.bssIdx = pBeaconFilterInfo->bssIdx; + + //Fill structure with info contained in the beaconFilterTable + dstPtr = (tANI_U8 *)wdiBeaconFilterInfo + sizeof(WDI_BeaconFilterInfoType); + srcPtr = (tANI_U8 *)pBeaconFilterInfo + sizeof(tBeaconFilterMsg); + filterLength = wdiBeaconFilterInfo->wdiBeaconFilterInfo.usIeNum * sizeof(tBeaconFilterIe); + if(WDI_BEACON_FILTER_LEN < filterLength) + { + filterLength = WDI_BEACON_FILTER_LEN; + } + vos_mem_copy(dstPtr, srcPtr, filterLength); + wdiBeaconFilterInfo->wdiReqStatusCB = WDA_SetBeaconFilterReqCallback; + wdiBeaconFilterInfo->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiBeaconFilterInfo; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pBeaconFilterInfo; + + status = WDI_SetBeaconFilterReq(wdiBeaconFilterInfo, + (WDI_SetBeaconFilterCb)WDA_SetBeaconFilterRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set Beacon Filter REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_RemBeaconFilterRespCallback + * + */ +void WDA_RemBeaconFilterRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_RemBeaconFilterRespCallback invoked " ); + return ; +} +/* + * FUNCTION: WDA_RemBeaconFilterReqCallback + * Free memory. + * Invoked when RemBeaconFilter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_RemBeaconFilterReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} + // TODO: PE does not have this feature for now implemented, + // but the support for removing beacon filter exists between + // HAL and FW. This function can be called whenever PE defines + // a new message for beacon filter removal +/* + * FUNCTION: WDA_RemBeaconFilterReq + * Request to WDI to send the removal of beacon filtering related information. + */ +VOS_STATUS WDA_RemBeaconFilterReq(tWDA_CbContext *pWDA, + tRemBeaconFilterMsg* pBeaconFilterInfo) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_RemBeaconFilterReqParamsType *wdiBeaconFilterInfo = + (WDI_RemBeaconFilterReqParamsType *)vos_mem_malloc( + sizeof(WDI_RemBeaconFilterReqParamsType) + pBeaconFilterInfo->ucIeCount) ; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiBeaconFilterInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiBeaconFilterInfo); + vos_mem_free(pBeaconFilterInfo); + return VOS_STATUS_E_NOMEM; + } + + wdiBeaconFilterInfo->wdiBeaconFilterInfo.ucIeCount = + pBeaconFilterInfo->ucIeCount; + //Fill structure with info contained in the ucRemIeId + vos_mem_copy(wdiBeaconFilterInfo->wdiBeaconFilterInfo.ucRemIeId, + pBeaconFilterInfo->ucRemIeId, + wdiBeaconFilterInfo->wdiBeaconFilterInfo.ucIeCount); + wdiBeaconFilterInfo->wdiReqStatusCB = WDA_RemBeaconFilterReqCallback; + wdiBeaconFilterInfo->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pBeaconFilterInfo; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiBeaconFilterInfo; + + pWdaParams->pWdaContext = pWDA; + + wstatus = WDI_RemBeaconFilterReq(wdiBeaconFilterInfo, + (WDI_RemBeaconFilterCb)WDA_RemBeaconFilterRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Remove Beacon Filter REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return status; +} +/* + * FUNCTION: WDA_SetRSSIThresholdsRespCallback + * + */ +void WDA_SetRSSIThresholdsRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + return ; +} +/* + * FUNCTION: WDA_SetRSSIThresholdsReqCallback + * Free memory. + * Invoked when SetRSSIThresholds REQ failed in WDI and no RSP callback is generated. + */ +void WDA_SetRSSIThresholdsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_SetRSSIThresholdsReq + * Request to WDI to set the RSSI thresholds (sta mode). + */ +VOS_STATUS WDA_SetRSSIThresholdsReq(tpAniSirGlobal pMac, tSirRSSIThresholds *pBmpsThresholds) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + tWDA_CbContext *pWDA = NULL ; + v_PVOID_t pVosContext = NULL; + WDI_SetRSSIThresholdsReqParamsType *wdiRSSIThresholdsInfo = + (WDI_SetRSSIThresholdsReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetRSSIThresholdsReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiRSSIThresholdsInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiRSSIThresholdsInfo); + return VOS_STATUS_E_NOMEM; + } + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bReserved10 = pBmpsThresholds->bReserved10; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.ucRssiThreshold1 = pBmpsThresholds->ucRssiThreshold1; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.ucRssiThreshold2 = pBmpsThresholds->ucRssiThreshold2; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.ucRssiThreshold3 = pBmpsThresholds->ucRssiThreshold3; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bRssiThres1NegNotify = pBmpsThresholds->bRssiThres1NegNotify; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bRssiThres2NegNotify = pBmpsThresholds->bRssiThres2NegNotify; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bRssiThres3NegNotify = pBmpsThresholds->bRssiThres3NegNotify; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bRssiThres1PosNotify = pBmpsThresholds->bRssiThres1PosNotify; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bRssiThres2PosNotify = pBmpsThresholds->bRssiThres2PosNotify; + wdiRSSIThresholdsInfo->wdiRSSIThresholdsInfo.bRssiThres3PosNotify = pBmpsThresholds->bRssiThres3PosNotify; + wdiRSSIThresholdsInfo->wdiReqStatusCB = WDA_SetRSSIThresholdsReqCallback; + wdiRSSIThresholdsInfo->pUserData = pWdaParams; + pVosContext = vos_get_global_context(VOS_MODULE_ID_PE, (void *)pMac); + pWDA = vos_get_context( VOS_MODULE_ID_WDA, pVosContext ); + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiRSSIThresholdsInfo; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pBmpsThresholds; + wstatus = WDI_SetRSSIThresholdsReq(wdiRSSIThresholdsInfo, + (WDI_SetRSSIThresholdsCb)WDA_SetRSSIThresholdsRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set RSSI thresholds REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; + +}/*WDA_SetRSSIThresholdsReq*/ +/* + * FUNCTION: WDA_HostOffloadRespCallback + * + */ +void WDA_HostOffloadRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_HostOffloadRespCallback invoked " ); + return ; +} +/* + * FUNCTION: WDA_HostOffloadReqCallback + * Free memory. + * Invoked when HostOffload REQ failed in WDI and no RSP callback is generated. + */ +void WDA_HostOffloadReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessHostOffloadReq + * Request to WDI to set the filter to minimize unnecessary host wakeup due + * to broadcast traffic (sta mode). + */ +VOS_STATUS WDA_ProcessHostOffloadReq(tWDA_CbContext *pWDA, + tSirHostOffloadReq *pHostOffloadParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_HostOffloadReqParamsType *wdiHostOffloadInfo = + (WDI_HostOffloadReqParamsType *)vos_mem_malloc( + sizeof(WDI_HostOffloadReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s: offloadType=%x" ,__func__, pHostOffloadParams->offloadType); + + if(NULL == wdiHostOffloadInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiHostOffloadInfo); + vos_mem_free(pHostOffloadParams); + return VOS_STATUS_E_NOMEM; + } + + wdiHostOffloadInfo->wdiHostOffloadInfo.ucOffloadType = + pHostOffloadParams->offloadType; + wdiHostOffloadInfo->wdiHostOffloadInfo.ucEnableOrDisable = + pHostOffloadParams->enableOrDisable; + + vos_mem_copy(wdiHostOffloadInfo->wdiHostOffloadInfo.bssId, + pHostOffloadParams->bssId, sizeof(wpt_macAddr)); + + switch (wdiHostOffloadInfo->wdiHostOffloadInfo.ucOffloadType) + { + case SIR_IPV4_ARP_REPLY_OFFLOAD: + vos_mem_copy(wdiHostOffloadInfo->wdiHostOffloadInfo.params.aHostIpv4Addr, + pHostOffloadParams->params.hostIpv4Addr, + 4); + break; + case SIR_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD: + vos_mem_copy(wdiHostOffloadInfo->wdiHostOffloadInfo.params.aHostIpv6Addr, + pHostOffloadParams->params.hostIpv6Addr, + 16); + break; + case SIR_IPV6_NS_OFFLOAD: + vos_mem_copy(wdiHostOffloadInfo->wdiHostOffloadInfo.params.aHostIpv6Addr, + pHostOffloadParams->params.hostIpv6Addr, + 16); + +#ifdef WLAN_NS_OFFLOAD + if(pHostOffloadParams->nsOffloadInfo.srcIPv6AddrValid) + { + vos_mem_copy(wdiHostOffloadInfo->wdiNsOffloadParams.srcIPv6Addr, + pHostOffloadParams->nsOffloadInfo.srcIPv6Addr, + 16); + wdiHostOffloadInfo->wdiNsOffloadParams.srcIPv6AddrValid = 1; + } + else + { + wdiHostOffloadInfo->wdiNsOffloadParams.srcIPv6AddrValid = 0; + } + + vos_mem_copy(wdiHostOffloadInfo->wdiNsOffloadParams.selfIPv6Addr, + pHostOffloadParams->nsOffloadInfo.selfIPv6Addr, + 16); + vos_mem_copy(wdiHostOffloadInfo->wdiNsOffloadParams.selfMacAddr, + pHostOffloadParams->nsOffloadInfo.selfMacAddr, + 6); + + //Only two are supported so let's go through them without a loop + if(pHostOffloadParams->nsOffloadInfo.targetIPv6AddrValid[0]) + { + vos_mem_copy(wdiHostOffloadInfo->wdiNsOffloadParams.targetIPv6Addr1, + pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[0], + 16); + wdiHostOffloadInfo->wdiNsOffloadParams.targetIPv6Addr1Valid = 1; + } + else + { + wdiHostOffloadInfo->wdiNsOffloadParams.targetIPv6Addr1Valid = 0; + } + + if(pHostOffloadParams->nsOffloadInfo.targetIPv6AddrValid[1]) + { + vos_mem_copy(wdiHostOffloadInfo->wdiNsOffloadParams.targetIPv6Addr2, + pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[1], + 16); + wdiHostOffloadInfo->wdiNsOffloadParams.targetIPv6Addr2Valid = 1; + } + else + { + wdiHostOffloadInfo->wdiNsOffloadParams.targetIPv6Addr2Valid = 0; + } + wdiHostOffloadInfo->wdiNsOffloadParams.slotIdx = + pHostOffloadParams->nsOffloadInfo.slotIdx; + break; +#endif //WLAN_NS_OFFLOAD + default: + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "No Handling for Offload Type %x in WDA " + , wdiHostOffloadInfo->wdiHostOffloadInfo.ucOffloadType); + //WDA_VOS_ASSERT(0) ; + } + } + wdiHostOffloadInfo->wdiReqStatusCB = WDA_HostOffloadReqCallback; + wdiHostOffloadInfo->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pHostOffloadParams; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiHostOffloadInfo; + pWdaParams->pWdaContext = pWDA; + + + wstatus = WDI_HostOffloadReq(wdiHostOffloadInfo, + (WDI_HostOffloadCb)WDA_HostOffloadRespCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "Failure in host offload REQ WDI API, free all the memory %d", + wstatus); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; + +}/*WDA_HostOffloadReq*/ +/* + * FUNCTION: WDA_KeepAliveRespCallback + * + */ +void WDA_KeepAliveRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_KeepAliveRespCallback invoked " ); + return ; +} +/* + * FUNCTION: WDA_KeepAliveReqCallback + * Free memory. + * Invoked when KeepAlive REQ failed in WDI and no RSP callback is generated. + */ +void WDA_KeepAliveReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessKeepAliveReq + * Request to WDI to send Keep Alive packets to minimize unnecessary host + * wakeup due to broadcast traffic (sta mode). + */ +VOS_STATUS WDA_ProcessKeepAliveReq(tWDA_CbContext *pWDA, + tSirKeepAliveReq *pKeepAliveParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_KeepAliveReqParamsType *wdiKeepAliveInfo = + (WDI_KeepAliveReqParamsType *)vos_mem_malloc( + sizeof(WDI_KeepAliveReqParamsType)) ; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiKeepAliveInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pKeepAliveParams); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiKeepAliveInfo); + vos_mem_free(pKeepAliveParams); + return VOS_STATUS_E_NOMEM; + } + + wdiKeepAliveInfo->wdiKeepAliveInfo.ucPacketType = + pKeepAliveParams->packetType; + wdiKeepAliveInfo->wdiKeepAliveInfo.ucTimePeriod = + pKeepAliveParams->timePeriod; + + vos_mem_copy(&wdiKeepAliveInfo->wdiKeepAliveInfo.bssId, + pKeepAliveParams->bssId, + sizeof(wpt_macAddr)); + + if(pKeepAliveParams->packetType == SIR_KEEP_ALIVE_UNSOLICIT_ARP_RSP) + { + vos_mem_copy(&wdiKeepAliveInfo->wdiKeepAliveInfo.aHostIpv4Addr, + pKeepAliveParams->hostIpv4Addr, + SIR_IPV4_ADDR_LEN); + vos_mem_copy(&wdiKeepAliveInfo->wdiKeepAliveInfo.aDestIpv4Addr, + pKeepAliveParams->destIpv4Addr, + SIR_IPV4_ADDR_LEN); + vos_mem_copy(&wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr, + pKeepAliveParams->destMacAddr, + SIR_MAC_ADDR_LEN); + } + else if(pKeepAliveParams->packetType == SIR_KEEP_ALIVE_NULL_PKT) + { + vos_mem_set(&wdiKeepAliveInfo->wdiKeepAliveInfo.aHostIpv4Addr, + SIR_IPV4_ADDR_LEN, + 0); + vos_mem_set(&wdiKeepAliveInfo->wdiKeepAliveInfo.aDestIpv4Addr, + SIR_IPV4_ADDR_LEN, + 0); + vos_mem_set(&wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr, + SIR_MAC_ADDR_LEN, + 0); + } + wdiKeepAliveInfo->wdiReqStatusCB = WDA_KeepAliveReqCallback; + wdiKeepAliveInfo->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pKeepAliveParams; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiKeepAliveInfo; + pWdaParams->pWdaContext = pWDA; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,"WDA HIP : %d.%d.%d.%d", + wdiKeepAliveInfo->wdiKeepAliveInfo.aHostIpv4Addr[0], + wdiKeepAliveInfo->wdiKeepAliveInfo.aHostIpv4Addr[1], + wdiKeepAliveInfo->wdiKeepAliveInfo.aHostIpv4Addr[2], + wdiKeepAliveInfo->wdiKeepAliveInfo.aHostIpv4Addr[3]); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,"WDA DIP : %d.%d.%d.%d", + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestIpv4Addr[0], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestIpv4Addr[1], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestIpv4Addr[2], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestIpv4Addr[3]); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA DMAC : %d:%d:%d:%d:%d:%d", + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr[0], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr[1], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr[2], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr[3], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr[4], + wdiKeepAliveInfo->wdiKeepAliveInfo.aDestMacAddr[5]); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "TimePeriod %d PacketType %d", + wdiKeepAliveInfo->wdiKeepAliveInfo.ucTimePeriod, + wdiKeepAliveInfo->wdiKeepAliveInfo.ucPacketType); + wstatus = WDI_KeepAliveReq(wdiKeepAliveInfo, + (WDI_KeepAliveCb)WDA_KeepAliveRespCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Keep Alive REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return status; + +}/*WDA_KeepAliveReq*/ +/* + * FUNCTION: WDA_WowlAddBcPtrnRespCallback + * + */ +void WDA_WowlAddBcPtrnRespCallback( + WDI_WowlAddBcPtrnRspParamsType *pWdiWowlAddBcstPtrRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + return ; +} +/* + * FUNCTION: WDA_WowlAddBcPtrnReqCallback + * Free memory. + * Invoked when WOWLAddBCPTRN REQ failed in WDI and no RSP callback is generated. + */ +void WDA_WowlAddBcPtrnReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} + +/* + * FUNCTION: WDA_ProcessWowlAddBcPtrnReq + * Request to WDI to add WOWL Bcast pattern + */ +VOS_STATUS WDA_ProcessWowlAddBcPtrnReq(tWDA_CbContext *pWDA, + tSirWowlAddBcastPtrn *pWowlAddBcPtrnParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_WowlAddBcPtrnReqParamsType *wdiWowlAddBcPtrnInfo = + (WDI_WowlAddBcPtrnReqParamsType *)vos_mem_malloc( + sizeof(WDI_WowlAddBcPtrnReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiWowlAddBcPtrnInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiWowlAddBcPtrnInfo); + return VOS_STATUS_E_NOMEM; + } + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternId = + pWowlAddBcPtrnParams->ucPatternId; + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternByteOffset = + pWowlAddBcPtrnParams->ucPatternByteOffset; + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternMaskSize = + pWowlAddBcPtrnParams->ucPatternMaskSize; + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternSize = + pWowlAddBcPtrnParams->ucPatternSize; + if (wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternSize <= WDI_WOWL_BCAST_PATTERN_MAX_SIZE) + { + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPattern, + pWowlAddBcPtrnParams->ucPattern, + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternSize); + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternMask, + pWowlAddBcPtrnParams->ucPatternMask, + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternMaskSize); + } + else + { + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPattern, + pWowlAddBcPtrnParams->ucPattern, + WDI_WOWL_BCAST_PATTERN_MAX_SIZE); + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternMask, + pWowlAddBcPtrnParams->ucPatternMask, + WDI_WOWL_BCAST_PATTERN_MAX_SIZE); + + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternExt, + pWowlAddBcPtrnParams->ucPatternExt, + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternSize - WDI_WOWL_BCAST_PATTERN_MAX_SIZE); + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternMaskExt, + pWowlAddBcPtrnParams->ucPatternMaskExt, + wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.ucPatternMaskSize - WDI_WOWL_BCAST_PATTERN_MAX_SIZE); + } + + vos_mem_copy(wdiWowlAddBcPtrnInfo->wdiWowlAddBcPtrnInfo.bssId, + pWowlAddBcPtrnParams->bssId, sizeof(wpt_macAddr)); + + wdiWowlAddBcPtrnInfo->wdiReqStatusCB = WDA_WowlAddBcPtrnReqCallback; + wdiWowlAddBcPtrnInfo->pUserData = pWdaParams; + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiWowlAddBcPtrnInfo; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pWowlAddBcPtrnParams; + wstatus = WDI_WowlAddBcPtrnReq(wdiWowlAddBcPtrnInfo, + (WDI_WowlAddBcPtrnCb)WDA_WowlAddBcPtrnRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Wowl add Bcast ptrn REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; + +}/*WDA_ProcessWowlAddBcPtrnReq*/ +/* + * FUNCTION: WDA_WowlDelBcPtrnRespCallback + * + */ +void WDA_WowlDelBcPtrnRespCallback( + WDI_WowlDelBcPtrnRspParamsType *pWdiWowlDelBcstPtrRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + return ; +} +/* + * FUNCTION: WDA_WowlDelBcPtrnReqCallback + * Free memory. + * Invoked when WOWLDelBCPTRN REQ failed in WDI and no RSP callback is generated. + */ +void WDA_WowlDelBcPtrnReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessWowlDelBcPtrnReq + * Request to WDI to delete WOWL Bcast pattern + */ +VOS_STATUS WDA_ProcessWowlDelBcPtrnReq(tWDA_CbContext *pWDA, + tSirWowlDelBcastPtrn *pWowlDelBcPtrnParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_WowlDelBcPtrnReqParamsType *wdiWowlDelBcPtrnInfo = + (WDI_WowlDelBcPtrnReqParamsType *)vos_mem_malloc( + sizeof(WDI_WowlDelBcPtrnReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiWowlDelBcPtrnInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiWowlDelBcPtrnInfo); + return VOS_STATUS_E_NOMEM; + } + wdiWowlDelBcPtrnInfo->wdiWowlDelBcPtrnInfo.ucPatternId = + pWowlDelBcPtrnParams->ucPatternId; + + vos_mem_copy(wdiWowlDelBcPtrnInfo->wdiWowlDelBcPtrnInfo.bssId, + pWowlDelBcPtrnParams->bssId, sizeof(wpt_macAddr)); + + wdiWowlDelBcPtrnInfo->wdiReqStatusCB = WDA_WowlDelBcPtrnReqCallback; + wdiWowlDelBcPtrnInfo->pUserData = pWdaParams; + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiWowlDelBcPtrnInfo; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pWowlDelBcPtrnParams; + wstatus = WDI_WowlDelBcPtrnReq(wdiWowlDelBcPtrnInfo, + (WDI_WowlDelBcPtrnCb)WDA_WowlDelBcPtrnRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Wowl delete Bcast ptrn REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; + +}/*WDA_ProcessWowlDelBcPtrnReq*/ +/* + * FUNCTION: WDA_WowlEnterRespCallback + * + */ +void WDA_WowlEnterRespCallback(WDI_WowlEnterRspParamsType *pwdiWowlEnterRspParam, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tSirHalWowlEnterParams *pWowlEnterParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext ; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + + if(pWdaParams->wdaWdiApiMsgParam) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pWowlEnterParams = (tSirHalWowlEnterParams *)pWdaParams->wdaMsgParam ; + + pWowlEnterParams->bssIdx = pwdiWowlEnterRspParam->bssIdx; + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + pWowlEnterParams->status = + (pwdiWowlEnterRspParam->status); + WDA_SendMsg(pWDA, WDA_WOWL_ENTER_RSP, (void *)pWowlEnterParams , 0) ; + return ; +} +/* + * FUNCTION: WDA_WowlEnterReqCallback + * Free memory and send WOWL Enter RSP back to PE. + * Invoked when WOWL Enter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_WowlEnterReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tSirHalWowlEnterParams *pWowlEnterParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pWowlEnterParams = (tSirHalWowlEnterParams *)pWdaParams->wdaMsgParam; + pWowlEnterParams->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_WOWL_ENTER_RSP, (void *)pWowlEnterParams , 0); + } + + return; +} +/* + * FUNCTION: WDA_ProcessWowlEnterReq + * Request to WDI to enter WOWL + */ +VOS_STATUS WDA_ProcessWowlEnterReq(tWDA_CbContext *pWDA, + tSirHalWowlEnterParams *pWowlEnterParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_WowlEnterReqParamsType *wdiWowlEnterInfo = + (WDI_WowlEnterReqParamsType *)vos_mem_malloc( + sizeof(WDI_WowlEnterReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiWowlEnterInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiWowlEnterInfo); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(pWdaParams, sizeof(tWDA_ReqParams)); + + vos_mem_copy(wdiWowlEnterInfo->wdiWowlEnterInfo.magicPtrn, + pWowlEnterParams->magicPtrn, + sizeof(tSirMacAddr)); + wdiWowlEnterInfo->wdiWowlEnterInfo.ucMagicPktEnable = + pWowlEnterParams->ucMagicPktEnable; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucPatternFilteringEnable = + pWowlEnterParams->ucPatternFilteringEnable; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucUcastPatternFilteringEnable = + pWowlEnterParams->ucUcastPatternFilteringEnable; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowChnlSwitchRcv = + pWowlEnterParams->ucWowChnlSwitchRcv; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowDeauthRcv = + pWowlEnterParams->ucWowDeauthRcv; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowDisassocRcv = + pWowlEnterParams->ucWowDisassocRcv; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowMaxMissedBeacons = + pWowlEnterParams->ucWowMaxMissedBeacons; + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowMaxSleepUsec = + pWowlEnterParams->ucWowMaxSleepUsec; +#ifdef WLAN_WAKEUP_EVENTS + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWoWEAPIDRequestEnable = + pWowlEnterParams->ucWoWEAPIDRequestEnable; + + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWoWEAPOL4WayEnable = + pWowlEnterParams->ucWoWEAPOL4WayEnable; + + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowNetScanOffloadMatch = + pWowlEnterParams->ucWowNetScanOffloadMatch; + + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWowGTKRekeyError = + pWowlEnterParams->ucWowGTKRekeyError; + + wdiWowlEnterInfo->wdiWowlEnterInfo.ucWoWBSSConnLoss = + pWowlEnterParams->ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + wdiWowlEnterInfo->wdiWowlEnterInfo.bssIdx = + pWowlEnterParams->bssIdx; + + wdiWowlEnterInfo->wdiReqStatusCB = WDA_WowlEnterReqCallback; + wdiWowlEnterInfo->pUserData = pWdaParams; + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiWowlEnterInfo; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pWowlEnterParams; + wstatus = WDI_WowlEnterReq(wdiWowlEnterInfo, + (WDI_WowlEnterReqCb)WDA_WowlEnterRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Wowl enter REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; + +}/*WDA_ProcessWowlEnterReq*/ +/* + * FUNCTION: WDA_WowlExitRespCallback + * + */ +void WDA_WowlExitRespCallback( WDI_WowlExitRspParamsType *pwdiWowlExitRsp, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tSirHalWowlExitParams *pWowlExitParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext ; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + + if(pWdaParams->wdaWdiApiMsgParam) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + pWowlExitParams = (tSirHalWowlExitParams *)pWdaParams->wdaMsgParam ; + + pWowlExitParams->bssIdx = pwdiWowlExitRsp->bssIdx; + pWowlExitParams->status = (pwdiWowlExitRsp->status); + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + WDA_SendMsg(pWDA, WDA_WOWL_EXIT_RSP, (void *)pWowlExitParams, 0) ; + return ; +} +/* + * FUNCTION: WDA_WowlExitReqCallback + * Free memory and send WOWL Exit RSP back to PE. + * Invoked when WOWL Exit REQ failed in WDI and no RSP callback is generated. + */ +void WDA_WowlExitReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tSirHalWowlExitParams *pWowlExitParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + pWowlExitParams = (tSirHalWowlExitParams *)pWdaParams->wdaMsgParam; + pWowlExitParams->status = wdiStatus; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + WDA_SendMsg(pWDA, WDA_WOWL_EXIT_RSP, (void *)pWowlExitParams, 0); + } + + return; +} +/* + * FUNCTION: WDA_ProcessWowlExitReq + * Request to WDI to add WOWL Bcast pattern + */ +VOS_STATUS WDA_ProcessWowlExitReq(tWDA_CbContext *pWDA, + tSirHalWowlExitParams *pWowlExitParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_WowlExitReqParamsType *wdiWowlExitInfo = + (WDI_WowlExitReqParamsType *)vos_mem_malloc( + sizeof(WDI_WowlExitReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiWowlExitInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiWowlExitInfo); + return VOS_STATUS_E_NOMEM; + } + + wdiWowlExitInfo->wdiWowlExitInfo.bssIdx = + pWowlExitParams->bssIdx; + + wdiWowlExitInfo->wdiReqStatusCB = WDA_WowlExitReqCallback; + wdiWowlExitInfo->pUserData = pWdaParams; + + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiWowlExitInfo; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pWowlExitParams; + + wstatus = WDI_WowlExitReq(wdiWowlExitInfo, + (WDI_WowlExitReqCb)WDA_WowlExitRespCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Wowl exit REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; +}/*WDA_ProcessWowlExitReq*/ +/* + * FUNCTION: WDA_IsHwFrameTxTranslationCapable + * Request to WDI to determine whether a given station is capable of + * using HW-based frame translation + */ +v_BOOL_t WDA_IsHwFrameTxTranslationCapable(v_PVOID_t pVosGCtx, + tANI_U8 staIdx) +{ + return WDI_IsHwFrameTxTranslationCapable(staIdx); +} + +/* + * FUNCTION: WDA_IsSelfSTA + * Request to WDI to determine whether a given STAID is self station + * index. + */ +v_BOOL_t WDA_IsSelfSTA(v_PVOID_t pVosContext, tANI_U8 ucSTAIdx) +{ + + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + + if (NULL != pWDA) + return WDI_IsSelfSTA(pWDA->pWdiContext,ucSTAIdx); + else + return VOS_TRUE; +} +/* + * FUNCTION: WDA_NvDownloadReqCallback + * send NV Download RSP back to PE + */ +void WDA_NvDownloadReqCallback(WDI_NvDownloadRspInfoType *pNvDownloadRspParams, + void* pUserData) +{ + + tWDA_ReqParams *pWdaParams= ( tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pWDA = pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + + if(pWdaParams->wdaWdiApiMsgParam) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return ; + } + + /*Cleaning */ + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + + vos_WDAComplete_cback(pWDA->pVosContext); + return ; +} +/* + * FUNCTION: WDA_ProcessNvDownloadReq + * Read the NV blob to a buffer and send a request to WDI to download the blob to NV memory. + */ +VOS_STATUS WDA_NVDownload_Start(v_PVOID_t pVosContext) +{ + /* Initialize the local Variables*/ + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + v_VOID_t *pNvBuffer=NULL; + v_SIZE_t bufferSize = 0; + WDI_Status status = WDI_STATUS_E_FAILURE; + WDI_NvDownloadReqParamsType * wdiNvDownloadReqParam =NULL; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* Get the NV structure base address and size from VOS */ + vos_nv_getNVEncodedBuffer(&pNvBuffer,&bufferSize); + + wdiNvDownloadReqParam = (WDI_NvDownloadReqParamsType *)vos_mem_malloc( + sizeof(WDI_NvDownloadReqParamsType)) ; + if(NULL == wdiNvDownloadReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + /* Copy Params to wdiNvDownloadReqParam*/ + wdiNvDownloadReqParam->wdiBlobInfo.pBlobAddress = pNvBuffer; + wdiNvDownloadReqParam->wdiBlobInfo.uBlobSize = bufferSize; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiNvDownloadReqParam); + return VOS_STATUS_E_NOMEM; + } + + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiNvDownloadReqParam ; + pWdaParams->wdaMsgParam = NULL; + pWdaParams->pWdaContext = pWDA; + + + wdiNvDownloadReqParam->wdiReqStatusCB = NULL ; + + status = WDI_NvDownloadReq(wdiNvDownloadReqParam, + (WDI_NvDownloadRspCb)WDA_NvDownloadReqCallback,(void *)pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in NV Download REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_FlushAcReqCallback + * send Flush AC RSP back to TL + */ +void WDA_FlushAcReqCallback(WDI_Status status, void* pUserData) +{ + vos_msg_t wdaMsg = {0} ; + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tFlushACReq *pFlushACReqParams; + tFlushACRsp *pFlushACRspParams; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pFlushACReqParams = (tFlushACReq *)pWdaParams->wdaMsgParam; + pFlushACRspParams = vos_mem_malloc(sizeof(tFlushACRsp)); + if(NULL == pFlushACRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + vos_mem_zero(pFlushACRspParams,sizeof(tFlushACRsp)); + pFlushACRspParams->mesgLen = sizeof(tFlushACRsp); + pFlushACRspParams->mesgType = WDA_TL_FLUSH_AC_RSP; + pFlushACRspParams->ucSTAId = pFlushACReqParams->ucSTAId; + pFlushACRspParams->ucTid = pFlushACReqParams->ucTid; + pFlushACRspParams->status = (status) ; + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + wdaMsg.type = WDA_TL_FLUSH_AC_RSP ; + wdaMsg.bodyptr = (void *)pFlushACRspParams; + // POST message to TL + vos_mq_post_message(VOS_MQ_ID_TL, (vos_msg_t *) &wdaMsg); + + return ; +} +/* + * FUNCTION: WDA_ProcessFlushAcReq + * Request to WDI to Update the DELBA REQ params. + */ +VOS_STATUS WDA_ProcessFlushAcReq(tWDA_CbContext *pWDA, + tFlushACReq *pFlushAcReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_FlushAcReqParamsType *wdiFlushAcReqParam = + (WDI_FlushAcReqParamsType *)vos_mem_malloc( + sizeof(WDI_FlushAcReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + if(NULL == wdiFlushAcReqParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiFlushAcReqParam); + return VOS_STATUS_E_NOMEM; + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiFlushAcReqParam->wdiFlushAcInfo.ucSTAId = pFlushAcReqParams->ucSTAId; + wdiFlushAcReqParam->wdiFlushAcInfo.ucTid = pFlushAcReqParams->ucTid; + wdiFlushAcReqParam->wdiFlushAcInfo.usMesgLen = pFlushAcReqParams->mesgLen; + wdiFlushAcReqParam->wdiFlushAcInfo.usMesgType = pFlushAcReqParams->mesgType; + /* Store Flush AC pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pFlushAcReqParams; + pWdaParams->wdaWdiApiMsgParam = wdiFlushAcReqParam; + status = WDI_FlushAcReq(wdiFlushAcReqParam, + (WDI_FlushAcRspCb)WDA_FlushAcReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Flush AC REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + //TODO: respond to TL with failure + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_BtAmpEventRespCallback + * + */ +void WDA_BtAmpEventRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + WDI_BtAmpEventParamsType *wdiBtAmpEventParam; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + VOS_ASSERT(0); + return ; + } + + wdiBtAmpEventParam = (WDI_BtAmpEventParamsType *)pWdaParams->wdaWdiApiMsgParam; + if(BTAMP_EVENT_CONNECTION_TERMINATED == + wdiBtAmpEventParam->wdiBtAmpEventInfo.ucBtAmpEventType) + { + pWDA->wdaAmpSessionOn = VOS_FALSE; + } + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* + * No respone required for WDA_SIGNAL_BTAMP_EVENT so just free the request + * param here + */ + return ; +} +/* + * FUNCTION: WDA_BtAmpEventReqCallback + * Free memory. + * Invoked when BTAMPEvent REQ failed in WDI and no RSP callback is generated. + */ +void WDA_BtAmpEventReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + WDI_BtAmpEventParamsType *wdiBtAmpEventParam; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + wdiBtAmpEventParam = (WDI_BtAmpEventParamsType *)pWdaParams->wdaWdiApiMsgParam; + + if(BTAMP_EVENT_CONNECTION_TERMINATED == + wdiBtAmpEventParam->wdiBtAmpEventInfo.ucBtAmpEventType) + { + pWDA->wdaAmpSessionOn = VOS_FALSE; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessBtAmpEventReq + * Request to WDI to Update with BT AMP events. + */ +VOS_STATUS WDA_ProcessBtAmpEventReq(tWDA_CbContext *pWDA, + tSmeBtAmpEvent *pBtAmpEventParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_BtAmpEventParamsType *wdiBtAmpEventParam = + (WDI_BtAmpEventParamsType *)vos_mem_malloc( + sizeof(WDI_BtAmpEventParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiBtAmpEventParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiBtAmpEventParam); + return VOS_STATUS_E_NOMEM; + } + wdiBtAmpEventParam->wdiBtAmpEventInfo.ucBtAmpEventType = + pBtAmpEventParams->btAmpEventType; + wdiBtAmpEventParam->wdiReqStatusCB = WDA_BtAmpEventReqCallback; + wdiBtAmpEventParam->pUserData = pWdaParams; + /* Store BT AMP event pointer, as this will be used for response */ + /* store Params pass it to WDI */ + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pBtAmpEventParams; + pWdaParams->wdaWdiApiMsgParam = wdiBtAmpEventParam; + status = WDI_BtAmpEventReq(wdiBtAmpEventParam, + (WDI_BtAmpEventRspCb)WDA_BtAmpEventRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in BT AMP event REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + if(BTAMP_EVENT_CONNECTION_START == wdiBtAmpEventParam->wdiBtAmpEventInfo.ucBtAmpEventType) + { + pWDA->wdaAmpSessionOn = VOS_TRUE; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_FTMCommandReqCallback + * Handle FTM CMD response came from HAL + * Route responce to HDD FTM + */ +void WDA_FTMCommandReqCallback(void *ftmCmdRspData, + void *usrData) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)usrData ; + if((NULL == pWDA) || (NULL == ftmCmdRspData)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s, invalid input %p, %p",__func__, pWDA, ftmCmdRspData); + return; + } + /* Release Current FTM Command Request */ + vos_mem_free(pWDA->wdaFTMCmdReq); + pWDA->wdaFTMCmdReq = NULL; + /* Post FTM Responce to HDD FTM */ + wlan_sys_ftm(ftmCmdRspData); + return; +} +/* + * FUNCTION: WDA_ProcessFTMCommand + * Send FTM command to WDI + */ +VOS_STATUS WDA_ProcessFTMCommand(tWDA_CbContext *pWDA, + tPttMsgbuffer *pPTTFtmCmd) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_FTMCommandReqType *ftmCMDReq = NULL; + ftmCMDReq = (WDI_FTMCommandReqType *) + vos_mem_malloc(sizeof(WDI_FTMCommandReqType)); + if(NULL == ftmCMDReq) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA FTM Command buffer alloc fail"); + return VOS_STATUS_E_NOMEM; + } + ftmCMDReq->bodyLength = pPTTFtmCmd->msgBodyLength; + ftmCMDReq->FTMCommandBody = (void *)pPTTFtmCmd; + pWDA->wdaFTMCmdReq = (void *)ftmCMDReq; + /* Send command to WDI */ + status = WDI_FTMCommandReq(ftmCMDReq, WDA_FTMCommandReqCallback, pWDA); + return status; +} +#ifdef FEATURE_OEM_DATA_SUPPORT +/* + * FUNCTION: WDA_StartOemDataReqCallback + * + */ +void WDA_StartOemDataReqCallback( + WDI_oemDataRspParamsType *wdiOemDataRspParams, + void* pUserData) +{ + VOS_STATUS status = VOS_STATUS_E_FAILURE; + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tStartOemDataRsp *pOemDataRspParams = NULL ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + /* + * Allocate memory for response params sent to PE + */ + pOemDataRspParams = vos_mem_malloc(sizeof(tStartOemDataRsp)); + + // Check if memory is allocated for OemdataMeasRsp Params. + if(NULL == pOemDataRspParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "OEM DATA WDA callback alloc fail"); + VOS_ASSERT(0) ; + return; + } + + // Free the memory allocated during request. + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + + /* + * Now go ahead and copy other stuff for PE in incase of success only + * Also, here success always means that we have atleast one BSSID. + */ + vos_mem_copy(pOemDataRspParams->oemDataRsp, wdiOemDataRspParams->oemDataRsp, OEM_DATA_RSP_SIZE); + + //enable Tx + status = WDA_ResumeDataTx(pWDA); + if(status != VOS_STATUS_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, "WDA Resume Data Tx fail"); + } + WDA_SendMsg(pWDA, WDA_START_OEM_DATA_RSP, (void *)pOemDataRspParams, 0) ; + return ; +} +/* + * FUNCTION: WDA_ProcessStartOemDataReq + * Send Start Oem Data Req to WDI + */ +VOS_STATUS WDA_ProcessStartOemDataReq(tWDA_CbContext *pWDA, + tStartOemDataReq *pOemDataReqParams) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_oemDataReqParamsType *wdiOemDataReqParams = NULL; + tWDA_ReqParams *pWdaParams ; + + wdiOemDataReqParams = (WDI_oemDataReqParamsType*)vos_mem_malloc(sizeof(WDI_oemDataReqParamsType)) ; + + if(NULL == wdiOemDataReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(wdiOemDataReqParams->wdiOemDataReqInfo.selfMacAddr, + pOemDataReqParams->selfMacAddr, sizeof(tSirMacAddr)); + vos_mem_copy(wdiOemDataReqParams->wdiOemDataReqInfo.oemDataReq, + pOemDataReqParams->oemDataReq, OEM_DATA_REQ_SIZE); + + wdiOemDataReqParams->wdiReqStatusCB = NULL; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(wdiOemDataReqParams); + vos_mem_free(pOemDataReqParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams->pWdaContext = (void*)pWDA; + pWdaParams->wdaMsgParam = (void*)pOemDataReqParams; + pWdaParams->wdaWdiApiMsgParam = (void*)wdiOemDataReqParams; + + status = WDI_StartOemDataReq(wdiOemDataReqParams, + (WDI_oemDataRspCb)WDA_StartOemDataReqCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Start OEM DATA REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif /* FEATURE_OEM_DATA_SUPPORT */ +/* + * FUNCTION: WDA_SetTxPerTrackingRespCallback + * + */ +void WDA_SetTxPerTrackingRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return ; +} +/* + * FUNCTION: WDA_SetTxPerTrackingReqCallback + * Free memory. + * Invoked when SetTXPerTracking REQ failed in WDI and no RSP callback is generated. + */ +void WDA_SetTxPerTrackingReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* + * FUNCTION: WDA_GTKOffloadRespCallback + * + */ +void WDA_GTKOffloadRespCallback( WDI_GtkOffloadRspParams *pwdiGtkOffloadRsparams, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_GTKOffloadRespCallback invoked " ); + + return ; +} +/* + * FUNCTION: WDA_GTKOffloadReqCallback + * Free memory. + * Invoked when GTKOffload REQ failed in WDI and no RSP callback is generated. + */ +void WDA_GTKOffloadReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_zero(pWdaParams->wdaWdiApiMsgParam, + sizeof(WDI_GtkOffloadReqMsg)); + vos_mem_zero(pWdaParams->wdaMsgParam, + sizeof(tSirGtkOffloadParams)); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessGTKOffloadReq + * Request to WDI to set the filter to minimize unnecessary host wakeup due + * to broadcast traffic (sta mode). + */ +VOS_STATUS WDA_ProcessGTKOffloadReq(tWDA_CbContext *pWDA, + tpSirGtkOffloadParams pGtkOffloadParams) +{ + WDI_Status status = WDI_STATUS_E_FAILURE; + WDI_GtkOffloadReqMsg *wdiGtkOffloadReqMsg = + (WDI_GtkOffloadReqMsg *)vos_mem_malloc( + sizeof(WDI_GtkOffloadReqMsg)) ; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if(NULL == wdiGtkOffloadReqMsg) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiGtkOffloadReqMsg); + return VOS_STATUS_E_NOMEM; + } + + // + // Fill wdiGtkOffloadInfo from pGtkOffloadParams + // + + vos_mem_copy(wdiGtkOffloadReqMsg->gtkOffloadReqParams.bssId, + pGtkOffloadParams->bssId, sizeof (wpt_macAddr)); + + wdiGtkOffloadReqMsg->gtkOffloadReqParams.ulFlags = pGtkOffloadParams->ulFlags; + // Copy KCK + vos_mem_copy(&(wdiGtkOffloadReqMsg->gtkOffloadReqParams.aKCK[0]), &(pGtkOffloadParams->aKCK[0]), 16); + // Copy KEK + vos_mem_copy(&(wdiGtkOffloadReqMsg->gtkOffloadReqParams.aKEK[0]), &(pGtkOffloadParams->aKEK[0]), 16); + // Copy KeyReplayCounter + vos_mem_copy(&(wdiGtkOffloadReqMsg->gtkOffloadReqParams.ullKeyReplayCounter), + &(pGtkOffloadParams->ullKeyReplayCounter), sizeof(v_U64_t)); + + wdiGtkOffloadReqMsg->wdiReqStatusCB = WDA_GTKOffloadReqCallback; + wdiGtkOffloadReqMsg->pUserData = pWdaParams; + + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiGtkOffloadReqMsg; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pGtkOffloadParams; + + status = WDI_GTKOffloadReq(wdiGtkOffloadReqMsg, (WDI_GtkOffloadCb)WDA_GTKOffloadRespCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDA_ProcessGTKOffloadReq(), free all the memory " ); + vos_mem_zero(wdiGtkOffloadReqMsg, sizeof(WDI_GtkOffloadReqMsg)); + vos_mem_zero(pGtkOffloadParams, sizeof(tSirGtkOffloadParams)); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_GtkOffloadGetInfoRespCallback + * + */ +void WDA_GtkOffloadGetInfoRespCallback( WDI_GtkOffloadGetInfoRspParams *pwdiGtkOffloadGetInfoRsparams, + void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoReq; + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp; + vos_msg_t vosMsg; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pGtkOffloadGetInfoRsp = vos_mem_malloc(sizeof(tSirGtkOffloadGetInfoRspParams)); + if(NULL == pGtkOffloadGetInfoRsp) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: vos_mem_malloc failed ", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext ; + pGtkOffloadGetInfoReq = (tpSirGtkOffloadGetInfoRspParams)pWdaParams->wdaMsgParam; + + // Fill pGtkOffloadGetInfoRsp from tSirGtkOffloadGetInfoRspParams + vos_mem_zero(pGtkOffloadGetInfoRsp, sizeof(tSirGtkOffloadGetInfoRspParams)); + + /* Message Header */ + pGtkOffloadGetInfoRsp->mesgType = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP; + pGtkOffloadGetInfoRsp->mesgLen = sizeof(tSirGtkOffloadGetInfoRspParams); + + pGtkOffloadGetInfoRsp->ulStatus = pwdiGtkOffloadGetInfoRsparams->ulStatus; + pGtkOffloadGetInfoRsp->ullKeyReplayCounter = pwdiGtkOffloadGetInfoRsparams->ullKeyReplayCounter; + pGtkOffloadGetInfoRsp->ulTotalRekeyCount = pwdiGtkOffloadGetInfoRsparams->ulTotalRekeyCount; + pGtkOffloadGetInfoRsp->ulGTKRekeyCount = pwdiGtkOffloadGetInfoRsparams->ulGTKRekeyCount; + pGtkOffloadGetInfoRsp->ulIGTKRekeyCount = pwdiGtkOffloadGetInfoRsparams->ulIGTKRekeyCount; + + vos_mem_copy( pGtkOffloadGetInfoRsp->bssId, + pwdiGtkOffloadGetInfoRsparams->bssId, + sizeof (wpt_macAddr)); + /* VOS message wrapper */ + vosMsg.type = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP; + vosMsg.bodyptr = (void *)pGtkOffloadGetInfoRsp; + vosMsg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + vos_mem_zero(pGtkOffloadGetInfoRsp, + sizeof(tSirGtkOffloadGetInfoRspParams)); + vos_mem_free((v_VOID_t *) pGtkOffloadGetInfoRsp); + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + return; +} +/* + * FUNCTION: WDA_GtkOffloadGetInfoReqCallback + * Free memory and send RSP back to SME. + * Invoked when GTKOffloadGetInfo REQ failed in WDI and no RSP callback is generated. + */ +void WDA_GtkOffloadGetInfoReqCallback(WDI_Status wdiStatus, void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + vos_msg_t vosMsg; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + /* VOS message wrapper */ + vosMsg.type = eWNI_PMC_GTK_OFFLOAD_GETINFO_RSP; + vosMsg.bodyptr = NULL; + vosMsg.bodyval = 0; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg); + } + + return; +} +#endif + +/* + * FUNCTION: WDA_ProcessSetTxPerTrackingReq + * Request to WDI to set Tx Per Tracking configurations + */ +VOS_STATUS WDA_ProcessSetTxPerTrackingReq(tWDA_CbContext *pWDA, tSirTxPerTrackingParam *pTxPerTrackingParams) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_SetTxPerTrackingReqParamsType *pwdiSetTxPerTrackingReqParams = + (WDI_SetTxPerTrackingReqParamsType *)vos_mem_malloc( + sizeof(WDI_SetTxPerTrackingReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiSetTxPerTrackingReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pTxPerTrackingParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pwdiSetTxPerTrackingReqParams); + vos_mem_free(pTxPerTrackingParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingEnable = + pTxPerTrackingParams->ucTxPerTrackingEnable; + pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingPeriod = + pTxPerTrackingParams->ucTxPerTrackingPeriod; + pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingRatio = + pTxPerTrackingParams->ucTxPerTrackingRatio; + pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.uTxPerTrackingWatermark = + pTxPerTrackingParams->uTxPerTrackingWatermark; + pwdiSetTxPerTrackingReqParams->wdiReqStatusCB = WDA_SetTxPerTrackingReqCallback; + pwdiSetTxPerTrackingReqParams->pUserData = pWdaParams; + /* Store param pointer as passed in by caller */ + /* store Params pass it to WDI + Ideally, the memory allocated here will be free at WDA_SetTxPerTrackingReqCallback */ + pWdaParams->wdaWdiApiMsgParam = pwdiSetTxPerTrackingReqParams; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pTxPerTrackingParams; + wstatus = WDI_SetTxPerTrackingReq(pwdiSetTxPerTrackingReqParams, + (WDI_SetTxPerTrackingRspCb)WDA_SetTxPerTrackingRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set Tx PER REQ WDI API, free all the memory " ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + return status; + +}/*WDA_ProcessSetTxPerTrackingReq*/ +/* + * FUNCTION: WDA_HALDumpCmdCallback + * Send the VOS complete . + */ +void WDA_HALDumpCmdCallback(WDI_HALDumpCmdRspParamsType *wdiRspParams, + void* pUserData) +{ + tANI_U8 *buffer = NULL; + tWDA_CbContext *pWDA = NULL; + tWDA_HalDumpReqParams *pWdaParams = (tWDA_HalDumpReqParams *)pUserData; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: WDA HAL DUMP Resp Received",__func__); + + pWDA = pWdaParams->pWdaContext; + buffer = (tANI_U8 *)pWdaParams->wdaMsgParam; + if(wdiRspParams->usBufferLen > 0) + { + /*Copy the Resp data to UMAC supplied buffer*/ + vos_mem_copy(buffer, wdiRspParams->pBuffer, wdiRspParams->usBufferLen); + } + + if (!pWdaParams->wdaHALDumpAsync) + {/* Indicate VOSS about the start complete */ + vos_WDAComplete_cback(pWDA->pVosContext); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + return ; +} + +/* + * FUNCTION: WDA_ProcessHALDumpCmdReq + * Send Dump command to WDI + */ +VOS_STATUS WDA_HALDumpCmdReq(tpAniSirGlobal pMac, tANI_U32 cmd, + tANI_U32 arg1, tANI_U32 arg2, tANI_U32 arg3, + tANI_U32 arg4, tANI_U8 *pBuffer, wpt_boolean async) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_HALDumpCmdReqParamsType *wdiHALDumpCmdReqParam = NULL; + WDI_HALDumpCmdReqInfoType *wdiHalDumpCmdInfo = NULL ; + tWDA_HalDumpReqParams *pWdaParams ; + + pVosContextType pVosContext = NULL; + VOS_STATUS vStatus; + pVosContext = (pVosContextType)vos_get_global_context(VOS_MODULE_ID_PE, + (void *)pMac); + if(pVosContext) + { + if (pVosContext->isLogpInProgress) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_FATAL, + "%s:LOGP in Progress. Ignore!!!", __func__); + return VOS_STATUS_E_BUSY; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS Context Null", __func__); + return VOS_STATUS_E_RESOURCES; + } + + if (NULL == pVosContext->pWDAContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: WDA Context Null", __func__); + return VOS_STATUS_E_RESOURCES; + } + pWdaParams = (tWDA_HalDumpReqParams *)vos_mem_malloc(sizeof(tWDA_HalDumpReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + return VOS_STATUS_E_NOMEM; + } + /* Allocate memory WDI request structure*/ + wdiHALDumpCmdReqParam = (WDI_HALDumpCmdReqParamsType *) + vos_mem_malloc(sizeof(WDI_HALDumpCmdReqParamsType)); + if(NULL == wdiHALDumpCmdReqParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA HAL DUMP Command buffer alloc fail"); + vos_mem_free(pWdaParams); + return WDI_STATUS_E_FAILURE; + } + wdiHalDumpCmdInfo = &wdiHALDumpCmdReqParam->wdiHALDumpCmdInfoType; + /* Extract the arguments */ + wdiHalDumpCmdInfo->command = cmd; + wdiHalDumpCmdInfo->argument1 = arg1; + wdiHalDumpCmdInfo->argument2 = arg2; + wdiHalDumpCmdInfo->argument3 = arg3; + wdiHalDumpCmdInfo->argument4 = arg4; + wdiHALDumpCmdReqParam->wdiReqStatusCB = NULL ; + pWdaParams->pWdaContext = pVosContext->pWDAContext; + pWdaParams->wdaHALDumpAsync = async; + + /* Response message will be passed through the buffer */ + pWdaParams->wdaMsgParam = (void *)pBuffer; + + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiHALDumpCmdReqParam ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: WDA HAL DUMP Command sent",__func__); + + /* Send command to WDI */ + status = WDI_HALDumpCmdReq(wdiHALDumpCmdReqParam, WDA_HALDumpCmdCallback, + pWdaParams); + /* For Sync event only wait for rsp until completion of wdaCompleteEvent*/ + if (!async) + { + vStatus = vos_wait_single_event( &(pVosContext->wdaCompleteEvent), + WDA_DUMPCMD_WAIT_TIMEOUT ); + if ( vStatus != VOS_STATUS_SUCCESS ) + { + if ( vStatus == VOS_STATUS_E_TIMEOUT ) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Timeout occurred before WDA_HALDUMP complete",__func__); + } + else + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: WDA_HALDUMP reporting other error",__func__); + } + if (!(vos_isLoadUnloadInProgress() || + vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL))) + VOS_BUG(0); + } + } + return status; +} +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/* + * FUNCTION: WDA_ProcessGTKOffloadgetInfoReq + * Request to WDI to get GTK Offload Information + */ +VOS_STATUS WDA_ProcessGTKOffloadGetInfoReq(tWDA_CbContext *pWDA, + tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) +{ + WDI_Status status = WDI_STATUS_E_FAILURE; + WDI_GtkOffloadGetInfoReqMsg *pwdiGtkOffloadGetInfoReqMsg = + (WDI_GtkOffloadGetInfoReqMsg *)vos_mem_malloc(sizeof(WDI_GtkOffloadGetInfoReqMsg)); + tWDA_ReqParams *pWdaParams ; + + if(NULL == pwdiGtkOffloadGetInfoReqMsg) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiGtkOffloadGetInfoReqMsg); + return VOS_STATUS_E_NOMEM; + } + + pwdiGtkOffloadGetInfoReqMsg->wdiReqStatusCB = WDA_GtkOffloadGetInfoReqCallback; + pwdiGtkOffloadGetInfoReqMsg->pUserData = pWdaParams; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiGtkOffloadGetInfoReqMsg; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pGtkOffloadGetInfoRsp; + + vos_mem_copy(pwdiGtkOffloadGetInfoReqMsg->WDI_GtkOffloadGetInfoReqParams.bssId, + pGtkOffloadGetInfoRsp->bssId, sizeof (wpt_macAddr)); + + status = WDI_GTKOffloadGetInfoReq(pwdiGtkOffloadGetInfoReqMsg, (WDI_GtkOffloadGetInfoCb)WDA_GtkOffloadGetInfoRespCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + /* failure returned by WDI API */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDA_ProcessGTKOffloadGetInfoReq(), free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pGtkOffloadGetInfoRsp->ulStatus = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_GTK_OFFLOAD_GETINFO_RSP, (void *)pGtkOffloadGetInfoRsp, 0) ; + } + + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/* + * FUNCTION: WDA_ProcessAddPeriodicTxPtrnInd + * + */ +VOS_STATUS WDA_ProcessAddPeriodicTxPtrnInd(tWDA_CbContext *pWDA, + tSirAddPeriodicTxPtrn *pAddPeriodicTxPtrnParams) +{ + WDI_Status wdiStatus; + WDI_AddPeriodicTxPtrnParamsType *addPeriodicTxPtrnParams; + + addPeriodicTxPtrnParams = + vos_mem_malloc(sizeof(WDI_AddPeriodicTxPtrnParamsType)); + + if (NULL == addPeriodicTxPtrnParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for addPeriodicTxPtrnParams!", + __func__); + + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(&(addPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams), + pAddPeriodicTxPtrnParams, sizeof(tSirAddPeriodicTxPtrn)); + + addPeriodicTxPtrnParams->wdiReqStatusCB = WDA_WdiIndicationCallback; + addPeriodicTxPtrnParams->pUserData = pWDA; + + wdiStatus = WDI_AddPeriodicTxPtrnInd(addPeriodicTxPtrnParams); + + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d", __func__, __LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d", __func__, __LINE__ ); + } + + vos_mem_free(addPeriodicTxPtrnParams); + + return CONVERT_WDI2VOS_STATUS(wdiStatus); +} + +/* + * FUNCTION: WDA_ProcessDelPeriodicTxPtrnInd + * + */ +VOS_STATUS WDA_ProcessDelPeriodicTxPtrnInd(tWDA_CbContext *pWDA, + tSirDelPeriodicTxPtrn *pDelPeriodicTxPtrnParams) +{ + WDI_Status wdiStatus; + WDI_DelPeriodicTxPtrnParamsType *delPeriodicTxPtrnParams; + + delPeriodicTxPtrnParams = + vos_mem_malloc(sizeof(WDI_DelPeriodicTxPtrnParamsType)); + + if (NULL == delPeriodicTxPtrnParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for delPeriodicTxPtrnParams!", + __func__); + + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(&(delPeriodicTxPtrnParams->wdiDelPeriodicTxPtrnParams), + pDelPeriodicTxPtrnParams, sizeof(tSirDelPeriodicTxPtrn)); + + delPeriodicTxPtrnParams->wdiReqStatusCB = WDA_WdiIndicationCallback; + delPeriodicTxPtrnParams->pUserData = pWDA; + + wdiStatus = WDI_DelPeriodicTxPtrnInd(delPeriodicTxPtrnParams); + + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d", __func__, __LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d", __func__, __LINE__ ); + } + + vos_mem_free(delPeriodicTxPtrnParams); + + return CONVERT_WDI2VOS_STATUS(wdiStatus); +} + +/* + * FUNCTION: WDA_ProcessRateUpdateInd + * + */ +VOS_STATUS WDA_ProcessRateUpdateInd(tWDA_CbContext *pWDA, + tSirRateUpdateInd *pRateUpdateParams) +{ + WDI_Status wdiStatus; + WDI_RateUpdateIndParams rateUpdateParams; + + vos_mem_copy(rateUpdateParams.bssid, + pRateUpdateParams->bssid, sizeof(tSirMacAddr)); + + rateUpdateParams.ucastDataRateTxFlag = + pRateUpdateParams->ucastDataRateTxFlag; + rateUpdateParams.rmcDataRateTxFlag = + pRateUpdateParams->rmcDataRateTxFlag; + rateUpdateParams.mcastDataRate24GHzTxFlag = + pRateUpdateParams->mcastDataRate24GHzTxFlag; + rateUpdateParams.mcastDataRate5GHzTxFlag = + pRateUpdateParams->mcastDataRate5GHzTxFlag; + + rateUpdateParams.ucastDataRate = pRateUpdateParams->ucastDataRate; + rateUpdateParams.rmcDataRate = + pRateUpdateParams->rmcDataRate; + rateUpdateParams.mcastDataRate24GHz = pRateUpdateParams->mcastDataRate24GHz; + rateUpdateParams.mcastDataRate5GHz = pRateUpdateParams->mcastDataRate5GHz; + + rateUpdateParams.wdiReqStatusCB = WDA_WdiIndicationCallback; + rateUpdateParams.pUserData = pWDA; + + wdiStatus = WDI_RateUpdateInd(&rateUpdateParams); + + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d", __func__, __LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d", __func__, __LINE__ ); + } + + vos_mem_free(pRateUpdateParams); + + return CONVERT_WDI2VOS_STATUS(wdiStatus); +} + + +#ifdef FEATURE_WLAN_BATCH_SCAN +/* + * FUNCTION: WDA_ProcessStopBatchScanInd + * + * DESCRIPTION: This function sends stop batch scan inidcation message to WDI + * + * PARAM: + * pWDA: pointer to WDA context + * pReq: pointer to stop batch scan request + */ +VOS_STATUS WDA_ProcessStopBatchScanInd(tWDA_CbContext *pWDA, + tSirStopBatchScanInd *pReq) +{ + WDI_Status wdiStatus; + WDI_StopBatchScanIndType wdiReq; + + wdiReq.param = pReq->param; + + wdiStatus = WDI_StopBatchScanInd(&wdiReq); + + if (WDI_STATUS_SUCCESS_SYNC != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Stop batch scan ind failed %s:%d", __func__, wdiStatus); + } + + vos_mem_free(pReq); + + return CONVERT_WDI2VOS_STATUS(wdiStatus); +} +/*========================================================================== + FUNCTION WDA_ProcessTriggerBatchScanResultInd + + DESCRIPTION + API to pull batch scan result from FW + + PARAMETERS + pWDA: Pointer to WDA context + pGetBatchScanReq: Pointer to get batch scan result indication + + RETURN VALUE + NONE + +===========================================================================*/ +VOS_STATUS WDA_ProcessTriggerBatchScanResultInd(tWDA_CbContext *pWDA, + tSirTriggerBatchScanResultInd *pReq) +{ + WDI_Status wdiStatus; + WDI_TriggerBatchScanResultIndType wdiReq; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "------> %s " ,__func__); + + wdiReq.param = pReq->param; + + wdiStatus = WDI_TriggerBatchScanResultInd(&wdiReq); + + if (WDI_STATUS_SUCCESS_SYNC != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Trigger batch scan result ind failed %s:%d", + __func__, wdiStatus); + } + + vos_mem_free(pReq); + + return CONVERT_WDI2VOS_STATUS(wdiStatus); +} + +/*========================================================================== + FUNCTION WDA_SetBatchScanRespCallback + + DESCRIPTION + API to process set batch scan response from FW + + PARAMETERS + pRsp: Pointer to set batch scan response + pUserData: Pointer to user data + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_SetBatchScanRespCallback +( + WDI_SetBatchScanRspType *pRsp, + void* pUserData +) +{ + tSirSetBatchScanRsp *pHddSetBatchScanRsp; + tpAniSirGlobal pMac; + void *pCallbackContext; + tWDA_CbContext *pWDA = NULL ; + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + /*extract WDA context*/ + pWDA = pWdaParams->pWdaContext; + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL can't invole HDD callback", + __func__); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + VOS_ASSERT(0); + return; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + return; + } + + pHddSetBatchScanRsp = + (tSirSetBatchScanRsp *)vos_mem_malloc(sizeof(tSirSetBatchScanRsp)); + if (NULL == pHddSetBatchScanRsp) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure can't invoke HDD callback", __func__); + VOS_ASSERT(0); + return; + } + + pHddSetBatchScanRsp->nScansToBatch = pRsp->nScansToBatch; + + pCallbackContext = pMac->pmc.setBatchScanReqCallbackContext; + /*call hdd callback with set batch scan response data*/ + if(pMac->pmc.setBatchScanReqCallback) + { + pMac->pmc.setBatchScanReqCallback(pCallbackContext, pHddSetBatchScanRsp); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + + vos_mem_free(pHddSetBatchScanRsp); + return ; +} + +/*========================================================================== + FUNCTION WDA_ProcessSetBatchScanReq + + DESCRIPTION + API to send set batch scan request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + pSetBatchScanReq: Pointer to set batch scan req + + RETURN VALUE + NONE + +===========================================================================*/ +VOS_STATUS WDA_ProcessSetBatchScanReq(tWDA_CbContext *pWDA, + tSirSetBatchScanReq *pSetBatchScanReq) +{ + WDI_Status status; + tWDA_ReqParams *pWdaParams ; + WDI_SetBatchScanReqType *pWdiSetBatchScanReq; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "------> %s " ,__func__); + + pWdiSetBatchScanReq = + (WDI_SetBatchScanReqType *)vos_mem_malloc(sizeof(WDI_SetBatchScanReqType)); + if (NULL == pWdiSetBatchScanReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pSetBatchScanReq); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pSetBatchScanReq); + vos_mem_free(pWdiSetBatchScanReq); + return VOS_STATUS_E_NOMEM; + } + + pWdiSetBatchScanReq->scanFrequency = pSetBatchScanReq->scanFrequency; + pWdiSetBatchScanReq->numberOfScansToBatch = + pSetBatchScanReq->numberOfScansToBatch; + pWdiSetBatchScanReq->bestNetwork = pSetBatchScanReq->bestNetwork; + pWdiSetBatchScanReq->rfBand = pSetBatchScanReq->rfBand; + pWdiSetBatchScanReq->rtt = pSetBatchScanReq->rtt; + + pWdaParams->wdaWdiApiMsgParam = pWdiSetBatchScanReq; + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pSetBatchScanReq; + + status = WDI_SetBatchScanReq(pWdiSetBatchScanReq, pWdaParams, + (WDI_SetBatchScanCb)WDA_SetBatchScanRespCallback); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set Batch Scan REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +#endif +/* + * FUNCTION: WDA_ProcessHT40OBSSScanInd + * + * DESCRIPTION: This function sends start/update OBSS scan + * inidcation message to WDI + * + * PARAM: + * pWDA: pointer to WDA context + * pReq: pointer to start OBSS scan request + */ +VOS_STATUS WDA_ProcessHT40OBSSScanInd(tWDA_CbContext *pWDA, + tSirHT40OBSSScanInd *pReq) +{ + WDI_Status status; + WDI_HT40ObssScanParamsType wdiOBSSScanParams; + WDI_HT40ObssScanIndType *pWdiOBSSScanInd; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + wdiOBSSScanParams.wdiReqStatusCB = WDA_WdiIndicationCallback; + wdiOBSSScanParams.pUserData = pWDA; + + pWdiOBSSScanInd = &(wdiOBSSScanParams.wdiHT40ObssScanParam); + pWdiOBSSScanInd->cmdType = pReq->cmdType; + pWdiOBSSScanInd->scanType = pReq->scanType; + pWdiOBSSScanInd->OBSSScanActiveDwellTime = + pReq->OBSSScanActiveDwellTime; + pWdiOBSSScanInd->OBSSScanPassiveDwellTime = + pReq->OBSSScanPassiveDwellTime; + pWdiOBSSScanInd->BSSChannelWidthTriggerScanInterval = + pReq->BSSChannelWidthTriggerScanInterval; + pWdiOBSSScanInd->BSSWidthChannelTransitionDelayFactor = + pReq->BSSWidthChannelTransitionDelayFactor; + pWdiOBSSScanInd->OBSSScanActiveTotalPerChannel = + pReq->OBSSScanActiveTotalPerChannel; + pWdiOBSSScanInd->OBSSScanPassiveTotalPerChannel = + pReq->OBSSScanPassiveTotalPerChannel; + pWdiOBSSScanInd->OBSSScanActivityThreshold = + pReq->OBSSScanActivityThreshold; + pWdiOBSSScanInd->channelCount = pReq->channelCount; + vos_mem_copy(pWdiOBSSScanInd->channels, + pReq->channels, + pReq->channelCount); + pWdiOBSSScanInd->selfStaIdx = pReq->selfStaIdx; + pWdiOBSSScanInd->fortyMHZIntolerent = pReq->fortyMHZIntolerent; + pWdiOBSSScanInd->bssIdx = pReq->bssIdx; + pWdiOBSSScanInd->currentOperatingClass = pReq->currentOperatingClass; + pWdiOBSSScanInd->ieFieldLen = pReq->ieFieldLen; + + vos_mem_copy(pWdiOBSSScanInd->ieField, + pReq->ieField, + pReq->ieFieldLen); + + status = WDI_HT40OBSSScanInd(&wdiOBSSScanParams); + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d ",__func__,__LINE__ ); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_ProcessHT40OBSSStopScanInd + * + * DESCRIPTION: This function sends stop OBSS scan inidcation message to WDI + * + * PARAM: + * pWDA: pointer to WDA context + * pReq: pointer to stop batch scan request + */ +VOS_STATUS WDA_ProcessHT40OBSSStopScanInd(tWDA_CbContext *pWDA, + tANI_U8 *bssIdx) +{ + WDI_Status status; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + status = WDI_HT40OBSSStopScanInd(*bssIdx); + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d ",__func__,__LINE__ ); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * ------------------------------------------------------------------------- + * DATA interface with WDI for Mgmt Frames + * ------------------------------------------------------------------------- + */ +/* + * FUNCTION: WDA_TxComplete + * Callback function for the WDA_TxPacket + */ +VOS_STATUS WDA_TxComplete( v_PVOID_t pVosContext, vos_pkt_t *pData, + VOS_STATUS status ) +{ + + tWDA_CbContext *wdaContext= (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + tpAniSirGlobal pMac = (tpAniSirGlobal)VOS_GET_MAC_CTXT((void *)pVosContext) ; + uintptr_t uUserData; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, "Enter:%s", __func__); + + if(NULL == wdaContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", + __func__); + VOS_ASSERT(0); + vos_pkt_return_packet(pData); + return VOS_STATUS_E_FAILURE; + } + + vos_lock_acquire(&wdaContext->mgmt_pkt_lock); + /*Check if frame was timed out or not*/ + vos_pkt_get_user_data_ptr( pData, VOS_PKT_USER_DATA_ID_WDA, + (v_PVOID_t)&uUserData); + + if ( WDA_TL_TX_MGMT_TIMED_OUT == uUserData ) + { + /*Discard frame - no further processing is needed*/ + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "%s: MGMT Frame Tx timed out", + __func__); + vos_pkt_return_packet(pData); + vos_lock_release(&wdaContext->mgmt_pkt_lock); + return VOS_STATUS_SUCCESS; + } + + /*check whether the callback is null or not,made null during WDA_TL_TX_FRAME_TIMEOUT timeout*/ + if( NULL!=wdaContext->pTxCbFunc) + { + /*check if packet is freed already*/ + if(vos_atomic_set((uintptr_t*)&wdaContext->VosPacketToFree, (uintptr_t)WDA_TX_PACKET_FREED) == (uintptr_t)pData) + { + wdaContext->pTxCbFunc(pMac, pData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "%s:packet (%p) is already freed", + __func__, pData); + //Return from here since we reaching here because the packet already timeout + vos_lock_release(&wdaContext->mgmt_pkt_lock); + return status; + } + } + else { + wdaContext->mgmt_pktfree_fail++; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:packet (%p) userData (%lx) is not freed", + __func__, pData, uUserData); + } + vos_lock_release(&wdaContext->mgmt_pkt_lock); + + /* + * Trigger the event to bring the HAL TL Tx complete function to come + * out of wait + * Let the coe above to complete the packet first. When this event is set, + * the thread waiting for the event may run and set Vospacket_freed causing the original + * packet not being freed. + */ + status = vos_event_set(&wdaContext->txFrameEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "NEW VOS Event Set failed - status = %d", status); + } + return status; +} +/* + * FUNCTION: WDA_TxPacket + * Forward TX management frame to WDI + */ +VOS_STATUS WDA_TxPacket(tWDA_CbContext *pWDA, + void *pFrmBuf, + tANI_U16 frmLen, + eFrameType frmType, + eFrameTxDir txDir, + tANI_U8 tid, + pWDATxRxCompFunc pCompFunc, + void *pData, + pWDAAckFnTxComp pAckTxComp, + tANI_U32 txFlag, + tANI_U32 txBdToken + ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS ; + tpSirMacFrameCtl pFc = (tpSirMacFrameCtl ) pData; + tANI_U8 ucTypeSubType = pFc->type <<4 | pFc->subType; + tANI_U8 eventIdx = 0; + tBssSystemRole systemRole = eSYSTEM_UNKNOWN_ROLE; + tpAniSirGlobal pMac; + tpSirTxBdStatus txBdStatus = {0}; + v_TIME_t time_snapshot; + + if((NULL == pWDA)||(NULL == pFrmBuf)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA %p or pFrmBuf %p is NULL", + __func__,pWDA,pFrmBuf); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "Tx Mgmt Frame Subtype: %d alloc(%p) txBdToken = %u", + pFc->subType, pFrmBuf, txBdToken); + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if(NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + /* store the call back function in WDA context */ + pWDA->pTxCbFunc = pCompFunc; + /* store the call back for the function of ackTxComplete */ + if( pAckTxComp ) + { + if( NULL != pWDA->pAckTxCbFunc ) + { + /* Already TxComp is active no need to active again */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "There is already one request pending for tx complete"); + pWDA->pAckTxCbFunc( pMac, &txBdStatus); + pWDA->pAckTxCbFunc = NULL; + + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.TxCompleteTimer)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Tx Complete timeout Timer Stop Failed "); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Tx Complete timeout Timer Stop Success "); + } + } + + txFlag |= HAL_TXCOMP_REQUESTED_MASK; + pWDA->pAckTxCbFunc = pAckTxComp; + if( VOS_STATUS_SUCCESS != + WDA_START_TIMER(&pWDA->wdaTimers.TxCompleteTimer) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Tx Complete Timer Start Failed "); + pWDA->pAckTxCbFunc = NULL; + return eHAL_STATUS_FAILURE; + } + } + /* Reset the event to be not signalled */ + status = vos_event_reset(&pWDA->txFrameEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event reset failed - status = %d",status); + pCompFunc(pWDA->pVosContext, (vos_pkt_t *)pFrmBuf); + if( pAckTxComp ) + { + pWDA->pAckTxCbFunc = NULL; + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.TxCompleteTimer)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Tx Complete timeout Timer Stop Failed "); + } + } + return VOS_STATUS_E_FAILURE; + } + + /* If Peer Sta mask is set don't overwrite to self sta */ + if(txFlag & HAL_USE_PEER_STA_REQUESTED_MASK) + { + txFlag &= ~HAL_USE_PEER_STA_REQUESTED_MASK; + } + else + { + /* Get system role, use the self station if in unknown role or STA role */ + systemRole = wdaGetGlobalSystemRole(pMac); + if (( eSYSTEM_UNKNOWN_ROLE == systemRole ) || + (( eSYSTEM_STA_ROLE == systemRole ) +#if defined FEATURE_WLAN_ESE || defined FEATURE_WLAN_TDLS + && frmType == HAL_TXRX_FRM_802_11_MGMT +#endif + )) + { + txFlag |= HAL_USE_SELF_STA_REQUESTED_MASK; + } + } + + /* Divert Disassoc/Deauth frames thru self station, as by the time unicast + disassoc frame reaches the HW, HAL has already deleted the peer station */ + if ((pFc->type == SIR_MAC_MGMT_FRAME)) + { + if ((pFc->subType == SIR_MAC_MGMT_REASSOC_RSP) || + (pFc->subType == SIR_MAC_MGMT_PROBE_REQ)) + { + /*Send Probe request frames on self sta idx*/ + txFlag |= HAL_USE_SELF_STA_REQUESTED_MASK; + } + /* Since we donot want probe responses to be retried, send probe responses + through the NO_ACK queues */ + if (pFc->subType == SIR_MAC_MGMT_PROBE_RSP) + { + //probe response is sent out using self station and no retries options. + txFlag |= (HAL_USE_NO_ACK_REQUESTED_MASK | HAL_USE_SELF_STA_REQUESTED_MASK); + } + if(VOS_TRUE == pWDA->wdaAmpSessionOn) + { + txFlag |= HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME; + } + } +#ifdef FEATURE_WLAN_TDLS + /* TDLS Management frames are sent using Peer Sta mask */ + else if ((pFc->type == SIR_MAC_DATA_FRAME) && + (txFlag & HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) + { + txFlag |= HAL_USE_PEER_STA_REQUESTED_MASK; + + } +#endif + vos_atomic_set((uintptr_t*)&pWDA->VosPacketToFree, (uintptr_t)pFrmBuf);/*set VosPacket_freed to pFrmBuf*/ + + /*Set frame tag to 0 + We will use the WDA user data in order to tag a frame as expired*/ + vos_pkt_set_user_data_ptr( (vos_pkt_t *)pFrmBuf, VOS_PKT_USER_DATA_ID_WDA, + (v_PVOID_t)0); + + + if((status = WLANTL_TxMgmtFrm(pWDA->pVosContext, (vos_pkt_t *)pFrmBuf, + frmLen, ucTypeSubType, tid, WDA_TxComplete, NULL, txFlag, + txBdToken))!= VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Sending Mgmt Frame failed - status = %d", status); + pCompFunc(VOS_GET_MAC_CTXT(pWDA->pVosContext), (vos_pkt_t *)pFrmBuf); + vos_atomic_set((uintptr_t*)&pWDA->VosPacketToFree, (v_U32_t)WDA_TX_PACKET_FREED);/*reset the VosPacket_freed*/ + if( pAckTxComp ) + { + pWDA->pAckTxCbFunc = NULL; + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.TxCompleteTimer)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Tx Complete timeout Timer Stop Failed "); + } + } + return VOS_STATUS_E_FAILURE; + } + time_snapshot = vos_timer_get_system_time(); + /* + * Wait for the event to be set by the TL, to get the response of TX + * complete, this event should be set by the Callback function called by TL + */ + status = vos_wait_events(&pWDA->txFrameEvent, 1, WDA_TL_TX_FRAME_TIMEOUT, + &eventIdx); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Status %d when waiting for TX Frame Event", + __func__, status); + vos_lock_acquire(&pWDA->mgmt_pkt_lock); + /*Tag Frame as timed out for later deletion*/ + vos_pkt_set_user_data_ptr( (vos_pkt_t *)pFrmBuf, VOS_PKT_USER_DATA_ID_WDA, + (v_PVOID_t)WDA_TL_TX_MGMT_TIMED_OUT); + pWDA->pTxCbFunc = NULL; /*To stop the limTxComplete being called again , + after the packet gets completed(packet freed once)*/ + + vos_atomic_set((uintptr_t*)&pWDA->VosPacketToFree, (uintptr_t)WDA_TX_PACKET_FREED); + + /* + * Memory barrier to ensure pFrmBuf is set before TX thread access it in + * TX completion call back + */ + VOS_SMP_MB; + vos_lock_release(&pWDA->mgmt_pkt_lock); + + /* TX MGMT fail with COMP timeout, try to detect DXE stall */ + WDA_TransportChannelDebug(pMac, 1, 0); + + if (vos_isFatalEventEnabled()) + vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_REASON_MGMT_FRAME_TIMEOUT, + FALSE, TRUE); + + if( pAckTxComp ) + { + pWDA->pAckTxCbFunc = NULL; + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.TxCompleteTimer)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Tx Complete timeout Timer Stop Failed "); + } + } + pWDA->mgmtTxfailureCnt++; + + /* Request firmware recovery */ + if (WDA_TX_FW_RECOVERY_THRESHOLD == + pWDA->mgmtTxfailureCnt) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Request firmware for recovery", __func__); + WLANTL_TLDebugMessage(WLANTL_DEBUG_FW_CLEANUP); + } + + /* SSR if timeout continously for + * WDA_TX_FAILURE_RECOVERY_THRESHOLD times. + */ + if (WDA_TX_FAILURE_RECOVERY_THRESHOLD == + pWDA->mgmtTxfailureCnt) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Request system recovery", __func__); + vos_wlanRestart(); + } + status = VOS_STATUS_E_FAILURE; + } + +#ifdef WLAN_DUMP_MGMTFRAMES + if (VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s() TX packet : SubType %d", __func__,pFc->subType); + VOS_TRACE_HEX_DUMP( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + pData, frmLen); + } +#endif + + if (VOS_IS_STATUS_SUCCESS(status)) + { + pWDA->mgmtTxfailureCnt = 0; + if ((vos_timer_get_system_time() - time_snapshot) >= + WDA_TX_TIME_THRESHOLD) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Tx Complete took %lu ms", + vos_timer_get_system_time() - time_snapshot); + } + + if (pMac->fEnableDebugLog & 0x1) + { + if ((pFc->type == SIR_MAC_MGMT_FRAME) && + (pFc->subType != SIR_MAC_MGMT_PROBE_REQ) && + (pFc->subType != SIR_MAC_MGMT_PROBE_RSP)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, "TX MGMT - Type %hu, SubType %hu", + pFc->type, pFc->subType); + } + } + } + + + return status; +} +/* + * FUNCTION: WDA_ProcessDHCPStartInd + * Forward DHCP Start to WDI + */ +static VOS_STATUS WDA_ProcessDHCPStartInd (tWDA_CbContext *pWDA, + tAniDHCPInd *dhcpStartInd) +{ + WDI_Status status; + WDI_DHCPInd wdiDHCPInd; + + wdiDHCPInd.device_mode = dhcpStartInd->device_mode; + vos_mem_copy(wdiDHCPInd.macAddr, dhcpStartInd->macAddr, + sizeof(tSirMacAddr)); + + status = WDI_dhcpStartInd(&wdiDHCPInd); + + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure status: %d in %s:%d ", status, __func__, __LINE__); + } + + vos_mem_free(dhcpStartInd); + return CONVERT_WDI2VOS_STATUS(status) ; +} + + /* + * FUNCTION: WDA_ProcessDHCPStopInd + * Forward DHCP Stop to WDI + */ + static VOS_STATUS WDA_ProcessDHCPStopInd (tWDA_CbContext *pWDA, + tAniDHCPInd *dhcpStopInd) + { + WDI_Status status; + WDI_DHCPInd wdiDHCPInd; + + wdiDHCPInd.device_mode = dhcpStopInd->device_mode; + vos_mem_copy(wdiDHCPInd.macAddr, dhcpStopInd->macAddr, sizeof(tSirMacAddr)); + + status = WDI_dhcpStopInd(&wdiDHCPInd); + + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure status: %d in %s:%d ", status, __func__, __LINE__); + } + + vos_mem_free(dhcpStopInd); + + return CONVERT_WDI2VOS_STATUS(status) ; + } + +#ifdef WLAN_FEATURE_RMC + +void +WDA_RMCRulerRspCallback(WDI_RmcRspParamsType *wdiRmcResponse, void *pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = pWdaParams->pWdaContext; + + switch (wdiRmcResponse->cmd) + { + case eWDI_BECOME_RULER_CMD : + { + tSirRmcBecomeRulerInd *pRmcBecomeRulerInd; + + pRmcBecomeRulerInd = (tSirRmcBecomeRulerInd *) + vos_mem_malloc(sizeof(*pRmcBecomeRulerInd)); + + if (NULL == pRmcBecomeRulerInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: unable to allocate pRmcBecomeRulerInd", __func__); + break; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received eWDI_BECOME_RULER_CMD from WDI"); + + pRmcBecomeRulerInd->status = wdiRmcResponse->status; + + vos_mem_copy(pRmcBecomeRulerInd->mcastTransmitter, + wdiRmcResponse->mcastTransmitter, + sizeof(tSirMacAddr)); + vos_mem_copy(pRmcBecomeRulerInd->mcastGroup, + wdiRmcResponse->mcastGroup, + sizeof(tSirMacAddr)); + + WDA_SendMsg(pWDA, WDA_RMC_BECOME_RULER, + (void *)pRmcBecomeRulerInd, 0) ; + break; + } + case eWDI_SUGGEST_RULER_CMD : + { + tSirRmcRulerSelectInd *pRmcRulerSelectInd; + + pRmcRulerSelectInd = (tSirRmcRulerSelectInd *) + vos_mem_malloc(sizeof(tSirRmcRulerSelectInd)); + + if (NULL == pRmcRulerSelectInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: unable to allocate pRmcRulerSelectInd", __func__); + break; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received eWDI_SUGGEST_RULER_CMD from WDI"); + + pRmcRulerSelectInd->status = wdiRmcResponse->status; + + vos_mem_copy(pRmcRulerSelectInd->mcastTransmitter, + wdiRmcResponse->mcastTransmitter, + sizeof(tSirMacAddr)); + vos_mem_copy(pRmcRulerSelectInd->mcastGroup, + wdiRmcResponse->mcastGroup, + sizeof(tSirMacAddr)); + vos_mem_copy(pRmcRulerSelectInd->ruler, + wdiRmcResponse->ruler, + sizeof(pRmcRulerSelectInd->ruler)); + + WDA_SendMsg(pWDA, WDA_RMC_RULER_SELECT_RESP, + (void *)pRmcRulerSelectInd, 0) ; + break; + } + } + + /* free the config structure */ + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + +} + +void WDA_RMCRulerReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} + +static VOS_STATUS +WDA_ProcessRMCRulerReq(tWDA_CbContext *pWDA, + tSirRmcRulerReq *rmcRulerReq) +{ + WDI_Status status; + WDI_RmcRulerReqParams *wdiRulerReq; + tWDA_ReqParams *pWdaParams; + + wdiRulerReq = (WDI_RmcRulerReqParams *) + vos_mem_malloc(sizeof(*wdiRulerReq)); + + if (NULL == wdiRulerReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(rmcRulerReq); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(rmcRulerReq); + vos_mem_free(wdiRulerReq); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams->wdaWdiApiMsgParam = (v_PVOID_t *)wdiRulerReq; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = rmcRulerReq; + pWdaParams->pWdaContext = pWDA; + + wdiRulerReq->cmd = rmcRulerReq->cmd; + + vos_mem_copy(wdiRulerReq->mcastTransmitter, + rmcRulerReq->mcastTransmitter, sizeof(tSirMacAddr)); + vos_mem_copy(wdiRulerReq->mcastGroup, + rmcRulerReq->mcastGroup, sizeof(tSirMacAddr)); + vos_mem_copy(wdiRulerReq->blacklist, + rmcRulerReq->blacklist, sizeof(wdiRulerReq->blacklist)); + + wdiRulerReq->wdiReqStatusCB = WDA_RMCRulerReqCallback; + + status = WDI_RmcRulerReq(wdiRulerReq, + (WDI_RmcRulerRspCb)WDA_RMCRulerRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Ruler Request failed"); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_ProcessRMCUpdateInd + * Forward Update Indication to WDI +*/ +static VOS_STATUS +WDA_ProcessRMCUpdateInd(tWDA_CbContext *pWDA, + tSirRmcUpdateInd *rmcUpdateInd) +{ + WDI_Status status; + WDI_RmcUpdateIndParams wdiUpdateInd; + + /* Copy the paramters for Update_Ind */ + + wdiUpdateInd.indication = rmcUpdateInd->indication; + wdiUpdateInd.role = rmcUpdateInd->role; + + vos_mem_copy(wdiUpdateInd.mcastTransmitter, + rmcUpdateInd->mcastTransmitter, sizeof(tSirMacAddr)); + + vos_mem_copy(wdiUpdateInd.mcastGroup, + rmcUpdateInd->mcastGroup, sizeof(tSirMacAddr)); + + vos_mem_copy(wdiUpdateInd.mcastRuler, + rmcUpdateInd->mcastRuler, sizeof(tSirMacAddr)); + + wdiUpdateInd.wdiReqStatusCB = WDA_WdiIndicationCallback; + wdiUpdateInd.pUserData = pWDA; + status = WDI_RmcUpdateInd(&wdiUpdateInd); + + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d ",__func__,__LINE__ ); + } + + vos_mem_free(rmcUpdateInd); + + return CONVERT_WDI2VOS_STATUS(status) ; +} + +void WDA_GetIbssPeerInfoRspCallback(WDI_IbssPeerInfoRspParams *peerInfoRspParams + ,void* pUserData) +{ + + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + WDI_IbssPeerInfoParams *pIbssPeerInfoParams; + tWDA_CbContext *pWDA; + tpSirIbssGetPeerInfoRspParams pIbssGetPeerInfoRsp; + vos_msg_t vosMsg; + v_U32_t wdaCnt = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if (NULL == peerInfoRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: peerInfoRspParams received NULL", __func__); + if(pWdaParams->wdaMsgParam) + vos_mem_free(pWdaParams->wdaMsgParam); + if(pWdaParams->wdaWdiApiMsgParam) + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + VOS_ASSERT(0); + return; + } + + pIbssPeerInfoParams = + (WDI_IbssPeerInfoParams *)peerInfoRspParams->wdiPeerInfoParams; + + pIbssGetPeerInfoRsp = + vos_mem_malloc(sizeof(tSirIbssGetPeerInfoRspParams)); + + if(NULL == pIbssGetPeerInfoRsp) + { + if(pWdaParams->wdaMsgParam) + vos_mem_free(pWdaParams->wdaMsgParam); + if(pWdaParams->wdaWdiApiMsgParam) + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Memory allocation failed for pIbssGetPeerInfoRsp", + __func__); + VOS_ASSERT(0); + return; + + } + + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext ; + + + if (peerInfoRspParams->wdiNumPeers > 32) + { + pr_info("%s] Number of peers is more than 32, returning\n", __func__); + /* free the mem and return */ + vos_mem_free((v_VOID_t *) pIbssGetPeerInfoRsp); + if(pWdaParams->wdaMsgParam) + vos_mem_free(pWdaParams->wdaMsgParam); + if(pWdaParams->wdaWdiApiMsgParam) + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + + return; + } + + /* Message Header */ + pIbssGetPeerInfoRsp->mesgType = eWNI_SME_IBSS_PEER_INFO_RSP; + pIbssGetPeerInfoRsp->mesgLen = sizeof(tSirIbssGetPeerInfoRspParams); + pIbssGetPeerInfoRsp->ibssPeerInfoRspParams.status = peerInfoRspParams->wdiStatus; + pIbssGetPeerInfoRsp->ibssPeerInfoRspParams.numPeers = peerInfoRspParams->wdiNumPeers; + + for (wdaCnt = 0; wdaCnt < peerInfoRspParams->wdiNumPeers; wdaCnt++) + { + WDI_IbssPeerInfoParams *pWdiTmp = &pIbssPeerInfoParams[wdaCnt]; + tSirIbssPeerInfoParams *pSmeTmp = + &pIbssGetPeerInfoRsp->ibssPeerInfoRspParams.peerInfoParams[wdaCnt]; + + pSmeTmp->staIdx = pWdiTmp->wdiStaIdx; + pSmeTmp->mcsIndex = pWdiTmp->wdiMcsIndex; + pSmeTmp->rssi = pWdiTmp->wdiRssi; + pSmeTmp->txRate = pWdiTmp->wdiTxRate; + pSmeTmp->txRateFlags = pWdiTmp->wdiTxRateFlags; + } + + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_IBSS_PEER_INFO_RSP; + vosMsg.bodyptr = (void *)pIbssGetPeerInfoRsp; + vosMsg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + vos_mem_free((v_VOID_t *) pIbssGetPeerInfoRsp); + } + + if(NULL != pWdaParams) + { + if(pWdaParams->wdaMsgParam) + vos_mem_free(pWdaParams->wdaMsgParam); + if(pWdaParams->wdaWdiApiMsgParam) + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} + +static VOS_STATUS +WDA_ProcessIbssPeerInfoReq(tWDA_CbContext *pWDA, + tSirIbssGetPeerInfoReqParams *ibssPeerInfoReqParams) +{ + WDI_Status status; + WDI_IbssPeerInfoReqType *wdiPeerInfoReq; + tWDA_ReqParams *pWdaParams; + + wdiPeerInfoReq = (WDI_IbssPeerInfoReqType *) + vos_mem_malloc(sizeof(WDI_IbssPeerInfoReqType)); + if (NULL == wdiPeerInfoReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(ibssPeerInfoReqParams); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiPeerInfoReq); + vos_mem_free(ibssPeerInfoReqParams); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams->wdaWdiApiMsgParam = (v_PVOID_t *)wdiPeerInfoReq; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = ibssPeerInfoReqParams; + pWdaParams->pWdaContext = pWDA; + + wdiPeerInfoReq->wdiAllPeerInfoReqd = + ibssPeerInfoReqParams->allPeerInfoReqd; + wdiPeerInfoReq->wdiStaIdx = + ibssPeerInfoReqParams->staIdx; + + status = WDI_IbssPeerInfoReq(wdiPeerInfoReq, + (WDI_IbssPeerInfoReqCb)WDA_GetIbssPeerInfoRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams) ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "IBSS Peer Info Request failed"); + } + return CONVERT_WDI2VOS_STATUS(status) ; + +} + +#ifdef WLAN_FEATURE_APFIND +/* + * FUNCTION: WDA_Process_apfind_set_cmd + * Forward AP find config request to WDI + */ +VOS_STATUS WDA_Process_apfind_set_cmd(tWDA_CbContext *pWDA, + struct hal_apfind_request *ap_find_req) +{ + WDI_Status status; + struct WDI_APFind_cmd *wdi_ap_find_cmd; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "------> %s " ,__func__); + if (NULL == ap_find_req) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: apfind_req info received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdi_ap_find_cmd = (struct WDI_APFind_cmd *)vos_mem_malloc( + sizeof(struct hal_apfind_request) + ap_find_req->request_data_len); + + wdi_ap_find_cmd->data_len = ap_find_req->request_data_len; + vos_mem_copy(wdi_ap_find_cmd->data, ap_find_req->request_data, + ap_find_req->request_data_len); + + status = WDI_process_ap_find_cmd(wdi_ap_find_cmd); + if (WDI_STATUS_PENDING == status) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received")); + } else if (WDI_STATUS_SUCCESS_SYNC != status && + (WDI_STATUS_SUCCESS != status)) { + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure in process_sap_auth_offload API %d"), status); + + } + vos_mem_free(wdi_ap_find_cmd); + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif + +/* + * FUNCTION: WDA_ProcessTXFailMonitorInd + * Forward TX Fail Monitor to WDI + */ +static VOS_STATUS WDA_ProcessTXFailMonitorInd( + tWDA_CbContext *pWDA, + tAniTXFailMonitorInd *txFailMonitorInd) +{ + WDI_Status status; + WDI_TXFailMonitorInd *wdiTXFailMonitorInd = + (WDI_TXFailMonitorInd *)vos_mem_malloc(sizeof(WDI_TXFailMonitorInd)); + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if (NULL == wdiTXFailMonitorInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(txFailMonitorInd); + return VOS_STATUS_E_NOMEM; + } + + wdiTXFailMonitorInd->tx_fail_count = txFailMonitorInd->tx_fail_count; + + wdiTXFailMonitorInd->wdiReqStatusCB = WDA_WdiIndicationCallback; + wdiTXFailMonitorInd->pUserData = pWDA; + + status = WDI_TXFailMonitorStartStopInd(wdiTXFailMonitorInd); + + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "TX Fail Monitor Indication Pending"); + } + else if (WDI_STATUS_SUCCESS_SYNC == status) + { + if (0 == txFailMonitorInd->tx_fail_count) + pWDA->txFailIndCallback = NULL; + else + pWDA->txFailIndCallback = txFailMonitorInd->txFailIndCallback; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "TX Fail Monitor Indication Failed"); + } + + vos_mem_free(wdiTXFailMonitorInd); + vos_mem_free(txFailMonitorInd); + + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +VOS_STATUS WDA_ProcessPERRoamScanTriggerReq(tWDA_CbContext *pWDA, + tPERRoamScanStart *pPERRoamTriggerScanReqParams) +{ + WDI_Status status; + tWDA_ReqParams *pWdaParams ; + WDI_PERRoamTriggerScanInfo *pwdiPERRoamTriggerScanInfo = + (WDI_PERRoamTriggerScanInfo *)vos_mem_malloc( + sizeof(WDI_PERRoamTriggerScanInfo)); + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if (NULL == pwdiPERRoamTriggerScanInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiPERRoamTriggerScanInfo); + return VOS_STATUS_E_NOMEM; + } + + pwdiPERRoamTriggerScanInfo->roamScanReq = + pPERRoamTriggerScanReqParams->start; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiPERRoamTriggerScanInfo; + pWdaParams->pWdaContext = pWDA; + + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pPERRoamTriggerScanReqParams; + status = WDI_PERRoamScanTriggerReq(pwdiPERRoamTriggerScanInfo, + (WDI_PERRoamTriggerScanCb)WDA_PERRoamTriggerScanReqCallback, + pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Start Roam Candidate trigger Req WDI API" ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + pWdaParams->wdaWdiApiMsgParam = NULL; + pWdaParams->wdaMsgParam = NULL; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif + +/* + * FUNCTION: WDA_ProcessSetSpoofMacAddrReq + * + * DESCRIPTION: This function sends Spoof Mac Addr Req to WDI + * + * PARAM: + * pWDA: pointer to WDA context + * pReq: pointer to stop batch scan request + */ +VOS_STATUS WDA_ProcessSetSpoofMacAddrReq(tWDA_CbContext *pWDA, + tpSpoofMacAddrReqParams pReq) +{ + WDI_Status wdiStatus; + WDI_SpoofMacAddrInfoType *WDI_SpoofMacAddrInfoParams; + tWDA_ReqParams *pWdaParams; + + WDI_SpoofMacAddrInfoParams = (WDI_SpoofMacAddrInfoType *)vos_mem_malloc( + sizeof(WDI_SpoofMacAddrInfoType)); + if(NULL == WDI_SpoofMacAddrInfoParams) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure in Spoof Req", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(WDI_SpoofMacAddrInfoParams); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(WDI_SpoofMacAddrInfoParams->macAddr, + pReq->macAddr, VOS_MAC_ADDRESS_LEN); + + pWdaParams->pWdaContext = pWDA; + /* Store Upper layer req pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pReq; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, WDA_MAC_ADDRESS_STR, + WDA_MAC_ADDR_ARRAY(WDI_SpoofMacAddrInfoParams->macAddr)); + + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)WDI_SpoofMacAddrInfoParams ; + + wdiStatus = WDI_SetSpoofMacAddrReq(WDI_SpoofMacAddrInfoParams, + (WDI_SetSpoofMacAddrRspCb) WDA_SpoofMacAddrRspCallback, + pWdaParams ); + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SetSpoofMacAddrReq Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return CONVERT_WDI2VOS_STATUS(wdiStatus) ; +} + + +/* + * FUNCTION: WDA_FwrMemDumpRespCallback + * recieves Mgmt Logging init response from FW + */ + void WDA_FwrMemDumpRespCallback(WDI_FwrMemDumpRsp* wdiRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tAniFwrDumpReq *pFwrMemDumpReq; + tAniFwrDumpRsp *pFwrMemDumpRsp; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == pWdaParams->wdaMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + pFwrMemDumpRsp = (tAniFwrDumpRsp *)vos_mem_malloc(sizeof(tAniFwrDumpRsp)); + if(pFwrMemDumpRsp == NULL) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFwrMemDumpRsp is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + pFwrMemDumpRsp->dump_status = wdiRsp->dump_status; + pFwrMemDumpReq = (tAniFwrDumpReq *)pWdaParams->wdaMsgParam; + + if(pFwrMemDumpReq->fwMemDumpReqCallback) + { + pFwrMemDumpReq->fwMemDumpReqCallback( + pFwrMemDumpReq->fwMemDumpReqContext, + pFwrMemDumpRsp); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: FwrMemDump callback is NULL", __func__); + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + vos_mem_free(pFwrMemDumpRsp); + + return ; +} + +VOS_STATUS WDA_ProcessFwrMemDumpReq(tWDA_CbContext * pWDA, + tAniFwrDumpReq* pFwrMemDumpReq) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_FwrMemDumpReqType * pWdiFwrMemDumpReq; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + /* Sanity Check*/ + if(NULL == pFwrMemDumpReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pFwrMemDumpReq received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + pWdiFwrMemDumpReq = (WDI_FwrMemDumpReqType *)vos_mem_malloc(sizeof(WDI_FwrMemDumpReqType)); + if(NULL == pWdiFwrMemDumpReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdiFwrMemDumpReq Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdiFwrMemDumpReq); + return VOS_STATUS_E_NOMEM; + } + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pWdiFwrMemDumpReq; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pFwrMemDumpReq; + + status = WDI_FwrMemDumpReq(pWdiFwrMemDumpReq, + (WDI_FwrMemDumpCb)WDA_FwrMemDumpRespCallback, + pWdaParams); + + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Fwr Mem Dump Req failed, free all the memory")); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + pWdaParams->wdaWdiApiMsgParam = NULL; + vos_mem_free(pWdaParams->wdaMsgParam); + pWdaParams->wdaMsgParam = NULL; + vos_mem_free(pWdaParams); + } + + return status; + +} + +/** + * wda_process_set_allowed_action_frames_ind() - Set allowed action frames to FW + * + * @pWDA: WDA Call back context + * @allowed_action_frames: Pointer to struct sir_allowed_action_frames + * that holds allowed action frames bitmask + * + * This function sets the allowed action frames that the FW needs to + * handover to host.The Action frames other than the requested ones + * can be dropped in FW + * + * Return: VOS_STATUS enumeration + */ +VOS_STATUS wda_process_set_allowed_action_frames_ind(tWDA_CbContext *pWDA, + struct sir_allowed_action_frames *allowed_action_frames) +{ + WDI_Status status; + struct WDI_AllowedActionFramesInd *wdi_allowed_action_frames; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + wdi_allowed_action_frames = (struct WDI_AllowedActionFramesInd*) + vos_mem_malloc(sizeof + (*wdi_allowed_action_frames)); + if (!wdi_allowed_action_frames) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(allowed_action_frames); + return VOS_STATUS_E_NOMEM; + } + + wdi_allowed_action_frames->bitmask = allowed_action_frames->bitmask; + wdi_allowed_action_frames->reserved = allowed_action_frames->reserved; + + status = WDI_SetAllowedActionFramesInd(wdi_allowed_action_frames); + if (WDI_STATUS_PENDING == status) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received")); + } else if (WDI_STATUS_SUCCESS_SYNC != status && + (WDI_STATUS_SUCCESS != status)) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure in allowed_action_frames API %d"), status); + } + + vos_mem_free(wdi_allowed_action_frames); + vos_mem_free(allowed_action_frames); + return CONVERT_WDI2VOS_STATUS(status) ; +} + +#ifdef SAP_AUTH_OFFLOAD +VOS_STATUS wda_process_sap_auth_offload(tWDA_CbContext *pWDA, + struct tSirSapOffloadInfo *sap_auth_offload_info) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + struct WDI_sap_ofl_enable_params *sap_ofl_enable_cmd; + v_U16_t psk_len, psk_len_padded; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if(NULL == sap_auth_offload_info) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: sap_auth_offload_info received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + psk_len = sap_auth_offload_info->key_len; + psk_len_padded = roundup(psk_len, sizeof(v_U32_t)); + + sap_ofl_enable_cmd = (struct WDI_sap_ofl_enable_params*) + vos_mem_malloc(sizeof + (*sap_ofl_enable_cmd)); + if (!sap_ofl_enable_cmd) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(sap_auth_offload_info); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(sap_ofl_enable_cmd, sizeof(*sap_ofl_enable_cmd)); + vos_mem_copy(sap_ofl_enable_cmd->macAddr, + sap_auth_offload_info->macAddr, VOS_MAC_ADDRESS_LEN); + + sap_ofl_enable_cmd->enable = sap_auth_offload_info->sap_auth_offload_enable; + sap_ofl_enable_cmd->psk_len = psk_len; + switch (sap_auth_offload_info->sap_auth_offload_sec_type) { + case eSIR_OFFLOAD_WPA2PSK_CCMP: + sap_ofl_enable_cmd->rsn_authmode = WDI_AUTH_TYPE_RSN_PSK; + sap_ofl_enable_cmd->rsn_mcastcipherset = WDI_ED_CCMP; + sap_ofl_enable_cmd->rsn_ucastcipherset = WDI_ED_CCMP; + break; + case eSIR_OFFLOAD_NONE: + default: + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Set SAP AP Auth offload with none support security type\n"); + break; + } + vos_mem_copy(sap_ofl_enable_cmd->key, sap_auth_offload_info->key, psk_len); + + status = WDI_process_sap_auth_offload(sap_ofl_enable_cmd); + + if (WDI_STATUS_PENDING == status) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received")); + } else if (WDI_STATUS_SUCCESS_SYNC != status && + (WDI_STATUS_SUCCESS != status)) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure in process_sap_auth_offload API %d"), status); + } + + vos_mem_free(sap_ofl_enable_cmd); + vos_mem_free(sap_auth_offload_info); + return CONVERT_WDI2VOS_STATUS(status) ; + +} +#endif + +/* + * FUNCTION: WDA_ProcessBcnMissPenaltyCount + * Request to WDI. + */ +VOS_STATUS WDA_ProcessTLPauseInd(tWDA_CbContext *pWDA, v_U32_t params) +{ + v_U8_t staId; + WLANTL_CbType* pTLCb = NULL; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, FL("---> %s"), __func__); + + staId = (v_U8_t)params; + + pTLCb = VOS_GET_TL_CB(pWDA->pVosContext); + if ( NULL == pTLCb ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid TL pointer from pvosGCtx on WLANTL_SuspendDataTx"); + return VOS_STATUS_E_FAULT; + } + + + pTLCb->atlSTAClients[staId]->disassoc_progress = VOS_TRUE; + /* Pause TL for Sta ID */ + return WLANTL_SuspendDataTx(pWDA->pVosContext, &staId, NULL); +} + +/** + * WDA_SetARPStatsParamsRspCallback() - WDA callback api to set/reset arp stats + * @wdiSetStatsRsp: pointer to set stats response + * @user_data: user data + * + * Return: None + */ +void WDA_SetARPStatsParamsRspCallback( + WDI_SetARPStatsRspParamsType *wdiSetStatsRsp, + void *user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + setArpStatsParams *arpStatsParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "ENTER <------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wda_params received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wda_params->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return; + } + + arpStatsParams = (setArpStatsParams *)wda_params->wdaMsgParam; + if(arpStatsParams->rsp_cb_fn) + { + arpStatsParams->rsp_cb_fn(arpStatsParams->data_ctx, + CONVERT_WDI2VOS_STATUS(wdiSetStatsRsp->status)); + } + else + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: ARP stats callback is NULL", __func__); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "EXIT <------ %s " ,__func__); + return; +} + +/** + * WDA_GetARPStatsParamsRspCallback() - WDA callback api to get arp stats + * @wdiGetStatsRsp: pointer to get stats response + * @user_data: user data + * + * Return: None + */ +void WDA_GetARPStatsParamsRspCallback( + WDI_GetARPStatsRspParamsType *wdiGetStatsRsp, + void *user_data) +{ + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + getArpStatsParams *arpStatsParams; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "ENTER <------ %s " ,__func__); + + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wda_params received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(NULL == wda_params->wdaMsgParam) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: wda_params->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return; + } + + arpStatsParams = (getArpStatsParams *)wda_params->wdaMsgParam; + if(arpStatsParams->get_rsp_cb_fn) + { + arpStatsParams->get_rsp_cb_fn(arpStatsParams->data_ctx, + (rsp_stats *)wdiGetStatsRsp); + } + else + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: ARP stats callback is NULL", __func__); + } + + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "EXIT <------ %s " ,__func__); + return; +} + +/** + * WDA_ProcessSetARPStatsReq() - WDA api to process set arp stats command + * @pWDA: wda handle + * @pSetStatsParams: pointer to set arp stats + * + * Return: VOS_STATUS + * 0 Success else failure + */ +VOS_STATUS WDA_ProcessSetARPStatsReq(tWDA_CbContext *pWDA, + setArpStatsParams *pSetStatsParams) +{ + WDI_SetARPStatsParamsInfoType *wdiSetStatsParam; + tWDA_ReqParams *wda_params; + WDI_Status wdi_status = WDI_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == pSetStatsParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pSetStatsParams received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiSetStatsParam = (WDI_SetARPStatsParamsInfoType *) + vos_mem_malloc(sizeof(*wdiSetStatsParam)); + if (!wdiSetStatsParam) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "set_dhcp_server_offload cmd"); + vos_mem_free(pSetStatsParams); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(wdiSetStatsParam, sizeof(*wdiSetStatsParam)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetStatsParam); + vos_mem_free(pSetStatsParams); + return VOS_STATUS_E_NOMEM; + } + + wdiSetStatsParam->flag = pSetStatsParams->flag; + wdiSetStatsParam->pkt_type = pSetStatsParams->pkt_type; + wdiSetStatsParam->ip_addr = pSetStatsParams->ip_addr; + + /* Store Params pass it to WDI */ + wda_params->wdaWdiApiMsgParam = (void *)wdiSetStatsParam; + wda_params->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + wda_params->wdaMsgParam = pSetStatsParams; + + wdi_status = WDI_SetARPStatsReq(wdiSetStatsParam, + (WDI_SetARPStatsRspCb)WDA_SetARPStatsParamsRspCallback, + wda_params); + + if(IS_WDI_STATUS_FAILURE(wdi_status)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure, free all the memory", __func__); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + return wdi_status; +} + +/** + * WDA_ProcessGetARPStatsReq() - WDA api to process get arp stats command + * @pWDA: wda handle + * @pGetStatsParams: pointer to get arp stats + * + * Return: VOS_STATUS + * 0 Success else failure + */ +VOS_STATUS WDA_ProcessGetARPStatsReq(tWDA_CbContext *pWDA, + getArpStatsParams *pGetStatsParams) +{ + WDI_GetARPStatsParamsInfoType *wdiGetStatsParam; + tWDA_ReqParams *wda_params; + WDI_Status wdi_status = WDI_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == pGetStatsParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pGetStatsParams received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiGetStatsParam = (WDI_GetARPStatsParamsInfoType *) + vos_mem_malloc(sizeof(*wdiGetStatsParam)); + if (!wdiGetStatsParam) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "set_dhcp_server_offload cmd"); + vos_mem_free(pGetStatsParams); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(wdiGetStatsParam, sizeof(*wdiGetStatsParam)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiGetStatsParam); + vos_mem_free(pGetStatsParams); + return VOS_STATUS_E_NOMEM; + } + + wdiGetStatsParam->pkt_type = pGetStatsParams->pkt_type; + + /* Store Params pass it to WDI */ + wda_params->wdaWdiApiMsgParam = (void *)wdiGetStatsParam; + wda_params->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + wda_params->wdaMsgParam = pGetStatsParams; + + wdi_status = WDI_GetARPStatsReq(wdiGetStatsParam, + (WDI_GetARPStatsRspCb)WDA_GetARPStatsParamsRspCallback, + wda_params); + + if(IS_WDI_STATUS_FAILURE(wdi_status)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Failure, free all the memory", __func__); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + return wdi_status; +} + + +#ifdef DHCP_SERVER_OFFLOAD +/** + * wda_process_dhcpserver_offload_req() - wda api to set dhcp server offload + * @wda_handle: pointer to wda handle + * @dhcp_server_offload_info: dhcp server offload info + * + * Return: status + * 0 - success or else failure + */ +static int wda_process_dhcpserver_offload_req(tWDA_CbContext *wda_handle, + sir_dhcp_srv_offload_info_t + *dhcp_server_offload_info) +{ + wdi_set_dhcp_server_offload_t *dhcp_info; + tWDA_ReqParams *wda_params; + WDI_Status wstatus; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == dhcp_server_offload_info) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: dhcp_server_offload_info received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + dhcp_info = (wdi_set_dhcp_server_offload_t *) + vos_mem_malloc(sizeof(*dhcp_info)); + if (!dhcp_info) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "set_dhcp_server_offload cmd"); + vos_mem_free(dhcp_server_offload_info); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(dhcp_info, sizeof(*dhcp_info)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(dhcp_info); + vos_mem_free(dhcp_server_offload_info); + return VOS_STATUS_E_NOMEM; + } + + dhcp_info->bssidx = dhcp_server_offload_info->bssidx; + dhcp_info->enable = dhcp_server_offload_info->dhcp_srv_offload_enabled; + dhcp_info->num_client = dhcp_server_offload_info->dhcp_client_num; + dhcp_info->srv_ipv4 = dhcp_server_offload_info->dhcp_srv_ip; + dhcp_info->start_lsb = dhcp_server_offload_info->start_lsb; + + wda_params->pWdaContext = wda_handle; + wda_params->wdaMsgParam = dhcp_server_offload_info; + wda_params->wdaWdiApiMsgParam = (void *)dhcp_info; + + wstatus = wdi_process_dhcpserver_offload_req(dhcp_info, + (wdi_dhcp_srv_offload_rsp_cb) + wda_dhcp_server_offload_rsp_callback, + wda_params); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to send set_dhcp_server_offload cmd" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Set dhcp server offload"); + return status; +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * wda_set_mdns_offload_req() - wda api to set mdns offload + * @wda_handle: wda handle + * @mdns_offload_info: mdns offload info + * + * Return - 0 for success or else failure + */ +static int +wda_set_mdns_offload_req(tWDA_CbContext *wda_handle, + sir_mdns_offload_info_t *mdns_offload_info) +{ + wdi_mdns_enable_offload_cmd_req *mdns_info; + tWDA_ReqParams *wda_params; + WDI_Status wstatus; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == mdns_offload_info) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: set_mdns_offload received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + mdns_info = (wdi_mdns_enable_offload_cmd_req *) + vos_mem_malloc(sizeof(*mdns_info)); + if (!mdns_info) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "set_mdns_offload cmd"); + vos_mem_free(mdns_offload_info); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(mdns_info, sizeof(*mdns_info)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(mdns_info); + vos_mem_free(mdns_offload_info); + return VOS_STATUS_E_NOMEM; + } + + mdns_info->bss_idx = mdns_offload_info->bss_idx; + mdns_info->enable = mdns_offload_info->enable; + + wda_params->pWdaContext = wda_handle; + wda_params->wdaMsgParam = mdns_offload_info; + wda_params->wdaWdiApiMsgParam = (void *)mdns_info; + + wstatus = wdi_set_mdns_offload_req(mdns_info, + (wdi_mdns_enable_rsp_cb) + wda_mdns_enable_rsp_callback, + wda_params); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to send wdi_set_mdns_offload_req cmd" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "mdns enabled!"); + return status; + +} + +/** + * wda_set_mdns_fqdn_req() - wda api to set mdns fqdn offload + * @wda_handle: wda handle + * @mdns_fqdn_info: mdns fqdn offload info + * + * Return - 0 for success or else failure + */ +static int +wda_set_mdns_fqdn_req(tWDA_CbContext *wda_handle, + sir_mdns_fqdn_info_t *mdns_fqdn_info) +{ + wdi_mdns_set_fqdn_cmd_req *fqdn_info; + tWDA_ReqParams *wda_params; + WDI_Status wstatus; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == mdns_fqdn_info) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: set_mdns_fqdn received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + fqdn_info = (wdi_mdns_set_fqdn_cmd_req *) + vos_mem_malloc(sizeof(*fqdn_info)); + if (!fqdn_info) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "set_mdns_fqdn cmd"); + vos_mem_free(mdns_fqdn_info); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(fqdn_info, sizeof(*fqdn_info)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(fqdn_info); + vos_mem_free(mdns_fqdn_info); + return VOS_STATUS_E_NOMEM; + } + + fqdn_info->bss_idx = mdns_fqdn_info->bss_idx; + fqdn_info->type = mdns_fqdn_info->fqdn_type; + fqdn_info->fqdn_len = mdns_fqdn_info->fqdn_len; + vos_mem_copy(fqdn_info->fqdn_data, mdns_fqdn_info->fqdn_data, + mdns_fqdn_info->fqdn_len); + fqdn_info->fqdn_data[mdns_fqdn_info->fqdn_len] = '\0'; + + wda_params->pWdaContext = wda_handle; + wda_params->wdaMsgParam = mdns_fqdn_info; + wda_params->wdaWdiApiMsgParam = (void *)fqdn_info; + + wstatus = wdi_set_mdns_fqdn_req(fqdn_info, + (wdi_mdns_fqdn_rsp_cb) + wda_mdns_fqdn_rsp_callback, + wda_params); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to send wdi_set_mdns_fqdn_req cmd" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "mDNS FQDN set"); + return status; +} + +/** + * wda_set_mdns_response_req() - wda api to set mdns resp offload + * @wda_handle: wda handle + * @mdns_rsp_info: mdns resp offload info + * + * Return - 0 for success or else failure + */ +static int +wda_set_mdns_response_req(tWDA_CbContext *wda_handle, + sir_mdns_resp_info_t *mdns_rsp_info) +{ + wdi_mdns_set_resp_req *rsp_info; + tWDA_ReqParams *wda_params; + WDI_Status wstatus; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == mdns_rsp_info) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: dhcp_server_offload_info received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + rsp_info = (wdi_mdns_set_resp_req *) + vos_mem_malloc(sizeof(*rsp_info)); + if (!rsp_info) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "wdi_set_mdns_response_req cmd"); + vos_mem_free(mdns_rsp_info); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(rsp_info, sizeof(*rsp_info)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(rsp_info); + vos_mem_free(mdns_rsp_info); + return VOS_STATUS_E_NOMEM; + } + + rsp_info->bss_idx = mdns_rsp_info->bss_idx; + rsp_info->ar_count = mdns_rsp_info->resourceRecord_count; + rsp_info->resp_len = mdns_rsp_info->resp_len; + vos_mem_copy(rsp_info->resp_data, mdns_rsp_info->resp_data, + mdns_rsp_info->resp_len); + rsp_info->resp_data[mdns_rsp_info->resp_len] = '\0'; + + wda_params->pWdaContext = wda_handle; + wda_params->wdaMsgParam = mdns_rsp_info; + wda_params->wdaWdiApiMsgParam = (void *)rsp_info; + + wstatus = wdi_set_mdns_response_req(rsp_info, + (wdi_mdns_resp_rsp_cb) + wda_mdns_resp_rsp_callback, + wda_params); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to send wdi_set_mdns_response_req cmd" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "mDNS Response set!"); + return status; +} + +/** + * wda_get_mdns_stats_req() - wda api to get mdns stats + * @wda_handle: wda handle + * @mdns_info: mdns info + * + * Return - 0 for success or else failure + */ +static int +wda_get_mdns_stats_req(tWDA_CbContext *wda_handle, + sir_get_mdns_stats_info_t *mdns_info) +{ + wdi_mdns_get_stats_req *status_info; + tWDA_ReqParams *wda_params; + WDI_Status wstatus; + + VOS_STATUS status = VOS_STATUS_SUCCESS; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if(NULL == mdns_info) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: dhcp_server_offload_info received NULL", + __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + status_info = (wdi_mdns_get_stats_req *) + vos_mem_malloc(sizeof(*status_info)); + if (!status_info) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to allocate buffer to send " + "wdi_set_mdns_response_req cmd"); + vos_mem_free(mdns_info); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_zero(status_info, sizeof(*status_info)); + + wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == wda_params) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(status_info); + vos_mem_free(mdns_info); + return VOS_STATUS_E_NOMEM; + } + + status_info->bss_idx = mdns_info->bss_idx; + + wda_params->pWdaContext = wda_handle; + wda_params->wdaMsgParam = mdns_info; + wda_params->wdaWdiApiMsgParam = (void *)status_info; + + wstatus = wdi_get_mdns_stats_req(status_info, + (wdi_get_stats_rsp_cb) + wda_get_stats_rsp_callback, + wda_params); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to send wdi_set_mdns_response_req cmd" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(wda_params->wdaWdiApiMsgParam) ; + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + } + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Get mDNS stats"); + return status; +} +#endif /* MDNS_OFFLOAD */ + +/* + * FUNCTION: WDA_McProcessMsg + * Trigger DAL-AL to start CFG download + */ +VOS_STATUS WDA_McProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg ) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + tWDA_CbContext *pWDA = NULL ; + if(NULL == pMsg) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMsg is NULL", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_LOW, + "=========> %s msgType: %x " ,__func__, pMsg->type); + + pWDA = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, pVosContext ); + if(NULL == pWDA ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pMsg->bodyptr); + return VOS_STATUS_E_FAILURE; + } + /* Process all the WDA messages.. */ + switch( pMsg->type ) + { + case WNI_CFG_DNLD_REQ: + { + status = WDA_WniCfgDnld(pWDA); + /* call WDA complete event if config download success */ + if( VOS_IS_STATUS_SUCCESS(status) ) + { + vos_WDAComplete_cback(pVosContext); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA Config Download failure" ); + } + break ; + } + /* + * Init SCAN request from PE, convert it into DAL format + * and send it to DAL + */ + case WDA_INIT_SCAN_REQ: + { + WDA_ProcessInitScanReq(pWDA, (tInitScanParams *)pMsg->bodyptr) ; + break ; + } + /* start SCAN request from PE */ + case WDA_START_SCAN_REQ: + { + WDA_ProcessStartScanReq(pWDA, (tStartScanParams *)pMsg->bodyptr) ; + break ; + } + /* end SCAN request from PE */ + case WDA_END_SCAN_REQ: + { + WDA_ProcessEndScanReq(pWDA, (tEndScanParams *)pMsg->bodyptr) ; + break ; + } + /* end SCAN request from PE */ + case WDA_FINISH_SCAN_REQ: + { + WDA_ProcessFinishScanReq(pWDA, (tFinishScanParams *)pMsg->bodyptr) ; + break ; + } + /* join request from PE */ + case WDA_CHNL_SWITCH_REQ: + { + if(WDA_PRE_ASSOC_STATE == pWDA->wdaState) + { + WDA_ProcessJoinReq(pWDA, (tSwitchChannelParams *)pMsg->bodyptr) ; + } + else + { + if (IS_FEATURE_SUPPORTED_BY_FW(CH_SWITCH_V1) && + eHAL_CHANNEL_SWITCH_SOURCE_CSA == + ((tSwitchChannelParams*)pMsg->bodyptr)->channelSwitchSrc ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "call ProcessChannelSwitchReq_V1" ); + WDA_ProcessChannelSwitchReq_V1(pWDA, + (tSwitchChannelParams*)pMsg->bodyptr) ; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "call ProcessChannelSwitchReq" ); + WDA_ProcessChannelSwitchReq(pWDA, + (tSwitchChannelParams*)pMsg->bodyptr) ; + } + } + break ; + } + /* ADD BSS request from PE */ + case WDA_ADD_BSS_REQ: + { + WDA_ProcessConfigBssReq(pWDA, (tAddBssParams*)pMsg->bodyptr) ; + break ; + } + case WDA_ADD_STA_REQ: + { + WDA_ProcessAddStaReq(pWDA, (tAddStaParams *)pMsg->bodyptr) ; + break ; + } + case WDA_DELETE_BSS_REQ: + { + WDA_ProcessDelBssReq(pWDA, (tDeleteBssParams *)pMsg->bodyptr) ; + break ; + } + case WDA_DELETE_STA_REQ: + { + WDA_ProcessDelStaReq(pWDA, (tDeleteStaParams *)pMsg->bodyptr) ; + break ; + } + case WDA_CONFIG_PARAM_UPDATE_REQ: + { + WDA_UpdateCfg(pWDA, (tSirMsgQ *)pMsg) ; + break ; + } + case WDA_SET_BSSKEY_REQ: + { + WDA_ProcessSetBssKeyReq(pWDA, (tSetBssKeyParams *)pMsg->bodyptr); + break ; + } + case WDA_SET_STAKEY_REQ: + { + WDA_ProcessSetStaKeyReq(pWDA, (tSetStaKeyParams *)pMsg->bodyptr); + break ; + } + case WDA_SET_STA_BCASTKEY_REQ: + { + WDA_ProcessSetBcastStaKeyReq(pWDA, (tSetStaKeyParams *)pMsg->bodyptr); + break ; + } + case WDA_REMOVE_BSSKEY_REQ: + { + WDA_ProcessRemoveBssKeyReq(pWDA, + (tRemoveBssKeyParams *)pMsg->bodyptr); + break ; + } + case WDA_REMOVE_STAKEY_REQ: + { + WDA_ProcessRemoveStaKeyReq(pWDA, + (tRemoveStaKeyParams *)pMsg->bodyptr); + break ; + } + case WDA_REMOVE_STA_BCASTKEY_REQ: + { + /* TODO: currently UMAC is not sending this request, Add the code for + handling this request when UMAC supports */ + break; + } +#ifdef FEATURE_WLAN_ESE + case WDA_TSM_STATS_REQ: + { + WDA_ProcessTsmStatsReq(pWDA, (tpAniGetTsmStatsReq)pMsg->bodyptr); + break; + } +#endif + case WDA_UPDATE_EDCA_PROFILE_IND: + { + WDA_ProcessUpdateEDCAParamReq(pWDA, (tEdcaParams *)pMsg->bodyptr); + break; + } + case WDA_ADD_TS_REQ: + { + WDA_ProcessAddTSReq(pWDA, (tAddTsParams *)pMsg->bodyptr); + break; + } + case WDA_DEL_TS_REQ: + { + WDA_ProcessDelTSReq(pWDA, (tDelTsParams *)pMsg->bodyptr); + break; + } + case WDA_ADDBA_REQ: + { + WDA_ProcessAddBASessionReq(pWDA, (tAddBAParams *)pMsg->bodyptr); + break; + } + case WDA_DELBA_IND: + { + WDA_ProcessDelBAReq(pWDA, (tDelBAParams *)pMsg->bodyptr); + break; + } + case WDA_UPDATE_CHAN_LIST_REQ: + { + WDA_ProcessUpdateChannelList(pWDA, + (tSirUpdateChanList *)pMsg->bodyptr); + break; + } + case WDA_SET_LINK_STATE: + { + WDA_ProcessSetLinkState(pWDA, (tLinkStateParams *)pMsg->bodyptr); + break; + } + case WDA_GET_STATISTICS_REQ: + { + WDA_ProcessGetStatsReq(pWDA, (tAniGetPEStatsReq *)pMsg->bodyptr); + break; + } +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WDA_GET_ROAM_RSSI_REQ: + { + WDA_ProcessGetRoamRssiReq(pWDA, (tAniGetRssiReq *)pMsg->bodyptr); + break; + } +#endif + case WDA_PWR_SAVE_CFG: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessSetPwrSaveCfgReq(pWDA, (tSirPowerSaveCfg *)pMsg->bodyptr); + } + else + { + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_PWR_SAVE_CFG req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_UPDATE_CFG_INT_PARAM: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_UpdateCfgIntParam(pWDA, (tSirUpdateCfgIntParam *)pMsg->bodyptr); + vos_mem_free(pMsg->bodyptr); + } + else + { + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + " WDA_UPDATE_CFG_INT_PARAM req in wrong state %d", + pWDA->wdaState ); + } + break; + } + case WDA_ENTER_IMPS_REQ: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessEnterImpsReq(pWDA); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_ENTER_IMPS_REQ req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_EXIT_IMPS_REQ: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessExitImpsReq(pWDA); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_EXIT_IMPS_REQ req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_ENTER_BMPS_REQ: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessEnterBmpsReq(pWDA, (tEnterBmpsParams *)pMsg->bodyptr); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_ENTER_BMPS_REQ req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_EXIT_BMPS_REQ: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessExitBmpsReq(pWDA, (tExitBmpsParams *)pMsg->bodyptr); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_EXIT_BMPS_REQ req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_ENTER_UAPSD_REQ: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessEnterUapsdReq(pWDA, (tUapsdParams *)pMsg->bodyptr); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_ENTER_UAPSD_REQ req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_EXIT_UAPSD_REQ: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_ProcessExitUapsdReq(pWDA, (tExitUapsdParams *)pMsg->bodyptr); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_EXIT_UAPSD_REQ req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_UPDATE_UAPSD_IND: + { + if(pWDA->wdaState == WDA_READY_STATE) + { + WDA_UpdateUapsdParamsReq(pWDA, (tUpdateUapsdParams *)pMsg->bodyptr); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_UPDATE_UAPSD_IND req in wrong state %d", pWDA->wdaState ); + } + break; + } + case WDA_REGISTER_PE_CALLBACK : + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "Handling msg type WDA_REGISTER_PE_CALLBACK " ); + /*TODO: store the PE callback */ + /* Do Nothing? MSG Body should be freed at here */ + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + break; + } + case WDA_SYS_READY_IND : + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "Handling msg type WDA_SYS_READY_IND " ); + pWDA->wdaState = WDA_READY_STATE; + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + break; + } + case WDA_BEACON_FILTER_IND : + { + WDA_SetBeaconFilterReq(pWDA, (tBeaconFilterMsg *)pMsg->bodyptr); + break; + } + case WDA_BTC_SET_CFG: + { + /*TODO: handle this while dealing with BTC */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "Handling msg type WDA_BTC_SET_CFG " ); + /* Do Nothing? MSG Body should be freed at here */ + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + break; + } + case WDA_SIGNAL_BT_EVENT: + { + /*TODO: handle this while dealing with BTC */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "Handling msg type WDA_SIGNAL_BT_EVENT " ); + /* Do Nothing? MSG Body should be freed at here */ + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + break; + } + case WDA_CFG_RXP_FILTER_REQ: + { + WDA_ProcessConfigureRxpFilterReq(pWDA, + (tSirWlanSetRxpFilters *)pMsg->bodyptr); + break; + } + case WDA_MGMT_LOGGING_INIT_REQ: + { + WDA_ProcessFWLoggingInitReq(pWDA, + (tSirFWLoggingInitParam *)pMsg->bodyptr); + break; + } + case WDA_GET_FRAME_LOG_REQ: + { + WDA_ProcessGetFrameLogReq(pWDA, + (tAniGetFrameLogReq *)pMsg->bodyptr); + break; + } + case WDA_START_RSSI_MONITOR_REQ: + { + WDA_ProcessStartRssiMonitorReq(pWDA,(tSirRssiMonitorReq *)pMsg->bodyptr); + break; + } + case WDA_STOP_RSSI_MONITOR_REQ: + { + WDA_ProcessStopRssiMonitorReq(pWDA,(tSirRssiMonitorReq *)pMsg->bodyptr); + break; + } + case WDA_SEND_LOG_DONE_IND: + { + WDA_FWLoggingDXEdoneInd(pMsg->bodyval); + break; + } + case WDA_FATAL_EVENT_LOGS_REQ: + { + WDA_ProcessFatalEventLogsReq(pWDA, + (tSirFatalEventLogsReqParam *)pMsg->bodyptr); + break; + } + case WDA_SET_HOST_OFFLOAD: + { + WDA_ProcessHostOffloadReq(pWDA, (tSirHostOffloadReq *)pMsg->bodyptr); + break; + } + case WDA_SET_KEEP_ALIVE: + { + WDA_ProcessKeepAliveReq(pWDA, (tSirKeepAliveReq *)pMsg->bodyptr); + break; + } +#ifdef WLAN_NS_OFFLOAD + case WDA_SET_NS_OFFLOAD: + { + WDA_ProcessHostOffloadReq(pWDA, (tSirHostOffloadReq *)pMsg->bodyptr); + break; + } +#endif //WLAN_NS_OFFLOAD + case WDA_ADD_STA_SELF_REQ: + { + WDA_ProcessAddStaSelfReq(pWDA, (tAddStaSelfParams *)pMsg->bodyptr); + break; + } + case WDA_DEL_STA_SELF_REQ: + { + WDA_ProcessDelSTASelfReq(pWDA, (tDelStaSelfParams *)pMsg->bodyptr); + break; + } + case WDA_WOWL_ADD_BCAST_PTRN: + { + WDA_ProcessWowlAddBcPtrnReq(pWDA, (tSirWowlAddBcastPtrn *)pMsg->bodyptr); + break; + } + case WDA_WOWL_DEL_BCAST_PTRN: + { + WDA_ProcessWowlDelBcPtrnReq(pWDA, (tSirWowlDelBcastPtrn *)pMsg->bodyptr); + break; + } + case WDA_WOWL_ENTER_REQ: + { + WDA_ProcessWowlEnterReq(pWDA, (tSirHalWowlEnterParams *)pMsg->bodyptr); + break; + } + case WDA_WOWL_EXIT_REQ: + { + WDA_ProcessWowlExitReq(pWDA, (tSirHalWowlExitParams *)pMsg->bodyptr); + break; + } + case WDA_TL_FLUSH_AC_REQ: + { + WDA_ProcessFlushAcReq(pWDA, (tFlushACReq *)pMsg->bodyptr); + break; + } + case WDA_SIGNAL_BTAMP_EVENT: + { + WDA_ProcessBtAmpEventReq(pWDA, (tSmeBtAmpEvent *)pMsg->bodyptr); + break; + } + case WDA_FW_STATS_GET_REQ: + { + WDA_ProcessFWStatsGetReq(pWDA, + (tSirFWStatsGetReq *)pMsg->bodyptr); + break; + } +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case WDA_LINK_LAYER_STATS_SET_REQ: + { + WDA_ProcessLLStatsSetReq(pWDA, (tSirLLStatsSetReq *)pMsg->bodyptr); + break; + } + case WDA_LINK_LAYER_STATS_GET_REQ: + { + WDA_ProcessLLStatsGetReq(pWDA, (tSirLLStatsGetReq *)pMsg->bodyptr); + break; + } + case WDA_LINK_LAYER_STATS_CLEAR_REQ: + { + WDA_ProcessLLStatsClearReq(pWDA, (tSirLLStatsClearReq *)pMsg->bodyptr); + break; + } +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ +#ifdef WLAN_FEATURE_EXTSCAN + case WDA_EXTSCAN_GET_CAPABILITIES_REQ: + { + WDA_ProcessEXTScanGetCapabilitiesReq(pWDA, + (tSirGetEXTScanCapabilitiesReqParams *)pMsg->bodyptr); + break; + } + case WDA_EXTSCAN_START_REQ: + { + WDA_ProcessEXTScanStartReq(pWDA, + (tSirEXTScanStartReqParams *)pMsg->bodyptr); + break; + } + case WDA_EXTSCAN_STOP_REQ: + { + WDA_ProcessEXTScanStopReq(pWDA, + (tSirEXTScanStopReqParams *)pMsg->bodyptr); + break; + } + case WDA_EXTSCAN_GET_CACHED_RESULTS_REQ: + { + WDA_ProcessEXTScanGetCachedResultsReq(pWDA, + (tSirEXTScanGetCachedResultsReqParams *)pMsg->bodyptr); + break; + } + case WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ: + { + WDA_ProcessEXTScanSetBSSIDHotlistReq(pWDA, + (tSirEXTScanSetBssidHotListReqParams *)pMsg->bodyptr); + break; + } + case WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ: + { + WDA_ProcessEXTScanResetBSSIDHotlistReq(pWDA, + (tSirEXTScanResetBssidHotlistReqParams *)pMsg->bodyptr); + break; + } + case WDA_HIGH_PRIORITY_DATA_INFO_IND: + { + WDA_ProcessHighPriorityDataInfoInd(pWDA, + (tSirHighPriorityDataInfoInd *)pMsg->bodyptr); + break; + } +#endif /* WLAN_FEATURE_EXTSCAN */ +#ifdef WDA_UT + case WDA_WDI_EVENT_MSG: + { + WDI_processEvent(pMsg->bodyptr,(void *)pMsg->bodyval); + break ; + } +#endif + case WDA_UPDATE_BEACON_IND: + { + WDA_ProcessUpdateBeaconParams(pWDA, + (tUpdateBeaconParams *)pMsg->bodyptr); + break; + } + case WDA_SEND_BEACON_REQ: + { + WDA_ProcessSendBeacon(pWDA, (tSendbeaconParams *)pMsg->bodyptr); + break; + } + case WDA_UPDATE_PROBE_RSP_TEMPLATE_IND: + { + WDA_ProcessUpdateProbeRspTemplate(pWDA, + (tSendProbeRespParams *)pMsg->bodyptr); + break; + } +#if defined(WLAN_FEATURE_VOWIFI) || defined(FEATURE_WLAN_ESE) + case WDA_SET_MAX_TX_POWER_REQ: + { + WDA_ProcessSetMaxTxPowerReq(pWDA, + (tMaxTxPowerParams *)pMsg->bodyptr); + break; + } +#endif + case WDA_SET_MAX_TX_POWER_PER_BAND_REQ: + { + WDA_ProcessSetMaxTxPowerPerBandReq(pWDA, (tMaxTxPowerPerBandParams *) + pMsg->bodyptr); + break; + } + case WDA_SET_TX_POWER_REQ: + { + WDA_ProcessSetTxPowerReq(pWDA, + (tSirSetTxPowerReq *)pMsg->bodyptr); + break; + } + case WDA_SET_P2P_GO_NOA_REQ: + { + WDA_ProcessSetP2PGONOAReq(pWDA, + (tP2pPsParams *)pMsg->bodyptr); + break; + } + /* timer related messages */ + case WDA_TIMER_BA_ACTIVITY_REQ: + { + WDA_BaCheckActivity(pWDA) ; + break ; + } + + /* timer related messages */ + case WDA_TIMER_TRAFFIC_STATS_IND: + { + WDA_TimerTrafficStatsInd(pWDA); + break; + } +#ifdef WLAN_FEATURE_VOWIFI_11R + case WDA_AGGR_QOS_REQ: + { + WDA_ProcessAggrAddTSReq(pWDA, (tAggrAddTsParams *)pMsg->bodyptr); + break; + } +#endif /* WLAN_FEATURE_VOWIFI_11R */ + case WDA_FTM_CMD_REQ: + { + WDA_ProcessFTMCommand(pWDA, (tPttMsgbuffer *)pMsg->bodyptr) ; + break ; + } +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDA_START_OEM_DATA_REQ: + { + WDA_ProcessStartOemDataReq(pWDA, (tStartOemDataReq *)pMsg->bodyptr) ; + break; + } +#endif /* FEATURE_OEM_DATA_SUPPORT */ + /* Tx Complete Time out Indication */ + case WDA_TX_COMPLETE_TIMEOUT_IND: + { + WDA_ProcessTxCompleteTimeOutInd(pWDA); + break; + } + case WDA_WLAN_SUSPEND_IND: + { + WDA_ProcessWlanSuspendInd(pWDA, + (tSirWlanSuspendParam *)pMsg->bodyptr) ; + break; + } + case WDA_WLAN_RESUME_REQ: + { + WDA_ProcessWlanResumeReq(pWDA, + (tSirWlanResumeParam *)pMsg->bodyptr) ; + break; + } + + case WDA_UPDATE_CF_IND: + { + vos_mem_free((v_VOID_t*)pMsg->bodyptr); + pMsg->bodyptr = NULL; + break; + } +#ifdef FEATURE_WLAN_SCAN_PNO + case WDA_SET_PNO_REQ: + { + WDA_ProcessSetPrefNetworkReq(pWDA, (tSirPNOScanReq *)pMsg->bodyptr); + break; + } + case WDA_UPDATE_SCAN_PARAMS_REQ: + { + WDA_ProcessUpdateScanParams(pWDA, (tSirUpdateScanParams *)pMsg->bodyptr); + break; + } + case WDA_SET_RSSI_FILTER_REQ: + { + WDA_ProcessSetRssiFilterReq(pWDA, (tSirSetRSSIFilterReq *)pMsg->bodyptr); + break; + } +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case WDA_ROAM_SCAN_OFFLOAD_REQ: + { + WDA_ProcessRoamScanOffloadReq(pWDA, (tSirRoamOffloadScanReq *)pMsg->bodyptr); + break; + } + case WDA_PER_ROAM_SCAN_OFFLOAD_REQ: + { + WDA_ProcessPERRoamScanOffloadReq(pWDA, (tSirPERRoamOffloadScanReq *)pMsg->bodyptr); + break; + } +#endif + case WDA_SET_TX_PER_TRACKING_REQ: + { + WDA_ProcessSetTxPerTrackingReq(pWDA, (tSirTxPerTrackingParam *)pMsg->bodyptr); + break; + } + +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WDA_8023_MULTICAST_LIST_REQ: + { + WDA_Process8023MulticastListReq(pWDA, (tSirRcvFltMcAddrList *)pMsg->bodyptr); + break; + } + case WDA_RECEIVE_FILTER_SET_FILTER_REQ: + { + WDA_ProcessReceiveFilterSetFilterReq(pWDA, (tSirRcvPktFilterCfgType *)pMsg->bodyptr); + break; + } + case WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ: + { + WDA_ProcessPacketFilterMatchCountReq(pWDA, (tpSirRcvFltPktMatchRsp)pMsg->bodyptr); + break; + } + case WDA_RECEIVE_FILTER_CLEAR_FILTER_REQ: + { + WDA_ProcessReceiveFilterClearFilterReq(pWDA, (tSirRcvFltPktClearParam *)pMsg->bodyptr); + break; + } +#endif // WLAN_FEATURE_PACKET_FILTERING + + + case WDA_TRANSMISSION_CONTROL_IND: + { + WDA_ProcessTxControlInd(pWDA, (tpTxControlParams)pMsg->bodyptr); + break; + } + case WDA_SET_POWER_PARAMS_REQ: + { + WDA_ProcessSetPowerParamsReq(pWDA, (tSirSetPowerParamsReq *)pMsg->bodyptr); + break; + } + case WDA_FW_MEM_DUMP_REQ: + { + WDA_ProcessFwrMemDumpReq(pWDA, (tAniFwrDumpReq*)pMsg->bodyptr); + break; + } + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDA_GTK_OFFLOAD_REQ: + { + WDA_ProcessGTKOffloadReq(pWDA, (tpSirGtkOffloadParams)pMsg->bodyptr); + break; + } + + case WDA_GTK_OFFLOAD_GETINFO_REQ: + { + WDA_ProcessGTKOffloadGetInfoReq(pWDA, (tpSirGtkOffloadGetInfoRspParams)pMsg->bodyptr); + break; + } +#endif //WLAN_FEATURE_GTK_OFFLOAD + + case WDA_SET_TM_LEVEL_REQ: + { + WDA_ProcessSetTmLevelReq(pWDA, (tAniSetTmLevelReq *)pMsg->bodyptr); + break; + } + + case WDA_UPDATE_OP_MODE: + { + if(WDA_getHostWlanFeatCaps(HT40_OBSS_SCAN) && + WDA_getFwWlanFeatCaps(HT40_OBSS_SCAN)) + { + WDA_ProcessUpdateOpMode(pWDA, (tUpdateVHTOpMode *)pMsg->bodyptr); + } + else if(WDA_getHostWlanFeatCaps(DOT11AC) && WDA_getFwWlanFeatCaps(DOT11AC)) + { + if(WDA_getHostWlanFeatCaps(DOT11AC_OPMODE) && WDA_getFwWlanFeatCaps(DOT11AC_OPMODE)) + WDA_ProcessUpdateOpMode(pWDA, (tUpdateVHTOpMode *)pMsg->bodyptr); + else + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + " VHT OpMode Feature is Not Supported"); + } + else + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + " 11AC Feature is Not Supported"); + break; + } +#ifdef WLAN_FEATURE_11W + case WDA_EXCLUDE_UNENCRYPTED_IND: + { + WDA_ProcessExcludeUnecryptInd(pWDA, (tSirWlanExcludeUnencryptParam *)pMsg->bodyptr); + break; + } +#endif +#ifdef FEATURE_WLAN_TDLS + case WDA_SET_TDLS_LINK_ESTABLISH_REQ: + { + WDA_ProcessSetTdlsLinkEstablishReq(pWDA, (tTdlsLinkEstablishParams *)pMsg->bodyptr); + break; + } +#endif + case WDA_DHCP_START_IND: + { + WDA_ProcessDHCPStartInd(pWDA, (tAniDHCPInd *)pMsg->bodyptr); + break; + } + case WDA_DHCP_STOP_IND: + { + WDA_ProcessDHCPStopInd(pWDA, (tAniDHCPInd *)pMsg->bodyptr); + break; + } +#ifdef FEATURE_WLAN_LPHB + case WDA_LPHB_CONF_REQ: + { + WDA_ProcessLPHBConfReq(pWDA, (tSirLPHBReq *)pMsg->bodyptr); + break; + } +#endif + case WDA_ADD_PERIODIC_TX_PTRN_IND: + { + WDA_ProcessAddPeriodicTxPtrnInd(pWDA, + (tSirAddPeriodicTxPtrn *)pMsg->bodyptr); + break; + } + case WDA_DEL_PERIODIC_TX_PTRN_IND: + { + WDA_ProcessDelPeriodicTxPtrnInd(pWDA, + (tSirDelPeriodicTxPtrn *)pMsg->bodyptr); + break; + } + case WDA_RATE_UPDATE_IND: + { + WDA_ProcessRateUpdateInd(pWDA, (tSirRateUpdateInd *)pMsg->bodyptr); + break; + } +#ifdef WLAN_FEATURE_RMC + case WDA_RMC_RULER_REQ: + { + WDA_ProcessRMCRulerReq(pWDA, (tSirRmcRulerReq *)pMsg->bodyptr); + break; + } + case WDA_RMC_UPDATE_IND: + { + WDA_ProcessRMCUpdateInd(pWDA, (tSirRmcUpdateInd *)pMsg->bodyptr); + break; + } + case WDA_GET_IBSS_PEER_INFO_REQ: + { + WDA_ProcessIbssPeerInfoReq(pWDA, + (tSirIbssGetPeerInfoReqParams *)pMsg->bodyptr); + break; + } + case WDA_TX_FAIL_MONITOR_IND: + { + WDA_ProcessTXFailMonitorInd(pWDA, (tAniTXFailMonitorInd *)pMsg->bodyptr); + break; + } +#endif /* WLAN_FEATURE_RMC */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case WDA_PER_ROAM_SCAN_TRIGGER_REQ: + { + WDA_ProcessPERRoamScanTriggerReq(pWDA, + (tPERRoamScanStart *)pMsg->bodyptr); + break; + } +#endif +#ifdef FEATURE_WLAN_BATCH_SCAN + case WDA_SET_BATCH_SCAN_REQ: + { + WDA_ProcessSetBatchScanReq(pWDA, + (tSirSetBatchScanReq *)pMsg->bodyptr); + break; + } + case WDA_TRIGGER_BATCH_SCAN_RESULT_IND: + { + WDA_ProcessTriggerBatchScanResultInd(pWDA, + (tSirTriggerBatchScanResultInd *)pMsg->bodyptr); + break; + } + case WDA_STOP_BATCH_SCAN_IND: + { + WDA_ProcessStopBatchScanInd(pWDA, + (tSirStopBatchScanInd *)pMsg->bodyptr); + break; + } + case WDA_GET_BCN_MISS_RATE_REQ: + WDA_ProcessGetBcnMissRateReq(pWDA, + (tSirBcnMissRateReq *)pMsg->bodyptr); + break; +#endif + + case WDA_HT40_OBSS_SCAN_IND: + { + WDA_ProcessHT40OBSSScanInd(pWDA, + (tSirHT40OBSSScanInd *)pMsg->bodyptr); + break; + } + case WDA_HT40_OBSS_STOP_SCAN_IND: + { + WDA_ProcessHT40OBSSStopScanInd(pWDA, + (tANI_U8*)pMsg->bodyptr); + break; + } +// tdlsoffchan +#ifdef FEATURE_WLAN_TDLS + case WDA_SET_TDLS_CHAN_SWITCH_REQ: + { + WDA_ProcessSetTdlsChanSwitchReq(pWDA, (tTdlsChanSwitchParams *)pMsg->bodyptr); + break; + } +#endif + case WDA_SPOOF_MAC_ADDR_REQ: + { + WDA_ProcessSetSpoofMacAddrReq(pWDA, (tpSpoofMacAddrReqParams)pMsg->bodyptr); + break; + } + case WDA_ENCRYPT_MSG_REQ: + { + WDA_ProcessEncryptMsgReq(pWDA, (u8 *)pMsg->bodyptr); + break; + } +#ifdef DHCP_SERVER_OFFLOAD + case WDA_SET_DHCP_SERVER_OFFLOAD_REQ: + { + wda_process_dhcpserver_offload_req(pWDA, + (sir_dhcp_srv_offload_info_t *)pMsg->bodyptr); + break; + } +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + case WDA_SET_MDNS_OFFLOAD_CMD: + wda_set_mdns_offload_req(pWDA, + (sir_mdns_offload_info_t *)pMsg->bodyptr); + break; + case WDA_SET_MDNS_FQDN_CMD: + wda_set_mdns_fqdn_req(pWDA, + (sir_mdns_fqdn_info_t *)pMsg->bodyptr); + break; + case WDA_SET_MDNS_RESPONSE_CMD: + wda_set_mdns_response_req(pWDA, + (sir_mdns_resp_info_t *)pMsg->bodyptr); + break; + case WDA_GET_MDNS_STATUS_CMD: + wda_get_mdns_stats_req(pWDA, + (sir_get_mdns_stats_info_t *) pMsg->bodyptr); + break; +#endif /* MDNS_OFFLOAD */ + case WDA_NAN_REQUEST: + { + WDA_ProcessNanRequest( pWDA, (tNanRequest *)pMsg->bodyptr); + break; + } + case WDA_SET_RTS_CTS_HTVHT: + { + WDA_ProcessSetRtsCtsHTVhtInd( pWDA, pMsg->bodyval); + break; + } + + case WDA_MON_START_REQ: + { + WDA_ProcessMonStartReq(pWDA,(v_PVOID_t)pMsg->bodyptr); + break; + } + case WDA_MON_STOP_REQ: + { + WDA_ProcessMonStopReq(pWDA, (v_PVOID_t)pMsg->bodyptr); + break; + } + case WDA_SEND_FREQ_RANGE_CONTROL_IND: + { + WDA_ProcessEnableDisableCAEventInd(pWDA, pMsg->bodyval); + break; + } + case WDA_WIFI_CONFIG_REQ: + { + WDA_ProcessWifiConfigReq(pWDA,(tSetWifiConfigParams *)pMsg->bodyptr); + break; + } +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDA_START_OEM_DATA_REQ_IND_NEW: + { + WDA_ProcessStartOemDataReqIndNew(pWDA, + (tOemDataReqNewConfig *)pMsg->bodyptr); + break; + } +#endif + case WDA_ANTENNA_DIVERSITY_SELECTION_REQ: + { + WDA_ProcessAntennaDiversitySelectionReq(pWDA, + (tSirAntennaDiversitySelectionReq *)pMsg->bodyptr); + break; + } + case WDA_MODIFY_ROAM_PARAMS_IND: + { + WDA_ProcessBcnMissPenaltyCount(pWDA, + (tModifyRoamParamsReqParams *)pMsg->bodyptr); + break; + } + + case WDA_SET_ALLOWED_ACTION_FRAMES_IND: + wda_process_set_allowed_action_frames_ind(pWDA, + (struct sir_allowed_action_frames*)pMsg->bodyptr); + break; + + case WDA_PAUSE_TL_IND: + { + WDA_ProcessTLPauseInd(pWDA, pMsg->bodyval); + break; + } +#ifdef WLAN_FEATURE_APFIND + case WDA_APFIND_SET_CMD: + { + WDA_Process_apfind_set_cmd(pWDA, + (struct hal_apfind_request *)pMsg->bodyptr); + } +#endif +#ifdef SAP_AUTH_OFFLOAD + case WDA_SET_SAP_AUTH_OFL: + { + wda_process_sap_auth_offload(pWDA, + (struct tSirSapOffloadInfo*)pMsg->bodyptr); + break; + } + case WDA_SAP_OFL_ADD_STA: + { + WDA_ProcessSapAuthOffloadAddStaReq(pWDA, + (tAddStaParams *)pMsg->bodyptr); + break; + } + case WDA_SAP_OFL_DEL_STA: + { + WDA_ProcessSapAuthOffloadDelStaReq(pWDA, + (tDeleteStaParams *)pMsg->bodyptr); + break; + } +#endif + case WDA_CAP_TSF_REQ: + { + WDA_ProcessCapTsfReq(pWDA, (tSirCapTsfParams *) + pMsg->bodyptr); + break; + } + case WDA_GET_TSF_REQ: + { + WDA_ProcessGetTsfReq(pWDA, (tSirCapTsfParams *)pMsg->bodyptr); + break; + } + case WDA_SET_ARP_STATS_REQ: + { + WDA_ProcessSetARPStatsReq(pWDA, (setArpStatsParams *)pMsg->bodyptr); + break; + } + case WDA_GET_ARP_STATS_REQ: + { + WDA_ProcessGetARPStatsReq(pWDA, (getArpStatsParams *)pMsg->bodyptr); + break; + } + default: + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "No Handling for msg type %x in WDA " + ,pMsg->type); + /* Do Nothing? MSG Body should be freed at here */ + if(NULL != pMsg->bodyptr) + { + vos_mem_free(pMsg->bodyptr); + } + //WDA_VOS_ASSERT(0) ; + } + } + return status ; +} + +/* + * FUNCTION: WDA_LowLevelIndCallback + * IND API callback from WDI, send Ind to PE + */ +void WDA_lowLevelIndCallback(WDI_LowLevelIndType *wdiLowLevelInd, + void* pUserData ) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)pUserData; +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + tSirRSSINotification rssiNotification; +#endif + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + + switch(wdiLowLevelInd->wdiIndicationType) + { + case WDI_RSSI_NOTIFICATION_IND: + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_HAL_RSSI_NOTIFICATION_IND from WDI "); +#if defined WLAN_FEATURE_NEIGHBOR_ROAMING + rssiNotification.bReserved = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bReserved; + rssiNotification.bRssiThres1NegCross = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bRssiThres1NegCross; + rssiNotification.bRssiThres1PosCross = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bRssiThres1PosCross; + rssiNotification.bRssiThres2NegCross = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bRssiThres2NegCross; + rssiNotification.bRssiThres2PosCross = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bRssiThres2PosCross; + rssiNotification.bRssiThres3NegCross = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bRssiThres3NegCross; + rssiNotification.bRssiThres3PosCross = + wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.bRssiThres3PosCross; + rssiNotification.avgRssi = (v_S7_t) + ((-1)*wdiLowLevelInd->wdiIndicationData.wdiLowRSSIInfo.avgRssi); + WLANTL_BMPSRSSIRegionChangedNotification( + pWDA->pVosContext, + &rssiNotification); +#endif + break ; + } + case WDI_MISSED_BEACON_IND: + { + tpSirSmeMissedBeaconInd pMissBeacInd = + (tpSirSmeMissedBeaconInd)vos_mem_malloc(sizeof(tSirSmeMissedBeaconInd)); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_MISSED_BEACON_IND from WDI "); + /* send IND to PE */ + if(NULL == pMissBeacInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + break; + } + pMissBeacInd->messageType = WDA_MISSED_BEACON_IND; + pMissBeacInd->length = sizeof(tSirSmeMissedBeaconInd); + pMissBeacInd->bssIdx = + wdiLowLevelInd->wdiIndicationData.wdiMissedBeaconInd.bssIdx; + WDA_SendMsg(pWDA, WDA_MISSED_BEACON_IND, (void *)pMissBeacInd , 0) ; + break ; + } +#ifdef WLAN_FEATURE_APFIND + case WDI_AP_FOUND_IND: + { + WDA_SendMsg(pWDA, WDA_AP_FIND_IND, NULL, 0) ; + break ; + } +#endif + case WDI_UNKNOWN_ADDR2_FRAME_RX_IND: + { + /* TODO: Decode Ind and send Ind to PE */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_UNKNOWN_ADDR2_FRAME_RX_IND from WDI "); + break ; + } + + case WDI_MIC_FAILURE_IND: + { + tpSirSmeMicFailureInd pMicInd = + (tpSirSmeMicFailureInd)vos_mem_malloc(sizeof(tSirSmeMicFailureInd)); + + if(NULL == pMicInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + break; + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_MIC_FAILURE_IND from WDI "); + pMicInd->messageType = eWNI_SME_MIC_FAILURE_IND; + pMicInd->length = sizeof(tSirSmeMicFailureInd); + vos_mem_copy(pMicInd->bssId, + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.bssId, + sizeof(tSirMacAddr)); + vos_mem_copy(pMicInd->info.srcMacAddr, + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.macSrcAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pMicInd->info.taMacAddr, + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.macTaAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pMicInd->info.dstMacAddr, + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.macDstAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pMicInd->info.rxMacAddr, + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.macRxAddr, + sizeof(tSirMacAddr)); + pMicInd->info.multicast = + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.ucMulticast; + pMicInd->info.keyId= + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.keyId; + pMicInd->info.IV1= + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.ucIV1; + vos_mem_copy(pMicInd->info.TSC, + wdiLowLevelInd->wdiIndicationData.wdiMICFailureInfo.TSC,SIR_CIPHER_SEQ_CTR_SIZE); + WDA_SendMsg(pWDA, SIR_HAL_MIC_FAILURE_IND, + (void *)pMicInd , 0) ; + break ; + } + case WDI_FATAL_ERROR_IND: + { + pWDA->wdiFailed = true; + /* TODO: Decode Ind and send Ind to PE */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_FATAL_ERROR_IND from WDI "); + break ; + } + case WDI_DEL_STA_IND: + { + tpDeleteStaContext pDelSTACtx = + (tpDeleteStaContext)vos_mem_malloc(sizeof(tDeleteStaContext)); + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_DEL_STA_IND from WDI "); + if(NULL == pDelSTACtx) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + break; + } + vos_mem_copy(pDelSTACtx->addr2, + wdiLowLevelInd->wdiIndicationData.wdiDeleteSTAIndType.macADDR2, + sizeof(tSirMacAddr)); + vos_mem_copy(pDelSTACtx->bssId, + wdiLowLevelInd->wdiIndicationData.wdiDeleteSTAIndType.macBSSID, + sizeof(tSirMacAddr)); + pDelSTACtx->assocId = + wdiLowLevelInd->wdiIndicationData.wdiDeleteSTAIndType.usAssocId; + pDelSTACtx->reasonCode = + wdiLowLevelInd->wdiIndicationData.wdiDeleteSTAIndType.wptReasonCode; + pDelSTACtx->staId = + wdiLowLevelInd->wdiIndicationData.wdiDeleteSTAIndType.ucSTAIdx; + WDA_SendMsg(pWDA, SIR_LIM_DELETE_STA_CONTEXT_IND, + (void *)pDelSTACtx , 0) ; + break ; + } + case WDI_COEX_IND: + { + tANI_U32 index; + vos_msg_t vosMsg; + tSirSmeCoexInd *pSmeCoexInd; + + if (SIR_COEX_IND_TYPE_CXM_FEATURES_NOTIFICATION == + wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndType) + { + if(wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndData) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Coex state: 0x%x coex feature: 0x%x"), + wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndData[0], + wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndData[1]); + + if (wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndData[2] << 16) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, FL("power limit: 0x%x"), + (tANI_U16)(wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndData[2])); + } + } + break; + } + + pSmeCoexInd = (tSirSmeCoexInd *)vos_mem_malloc(sizeof(tSirSmeCoexInd)); + if(NULL == pSmeCoexInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure-pSmeCoexInd", __func__); + break; + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_COEX_IND from WDI "); + /* Message Header */ + pSmeCoexInd->mesgType = eWNI_SME_COEX_IND; + pSmeCoexInd->mesgLen = sizeof(tSirSmeCoexInd); + /* Info from WDI Indication */ + pSmeCoexInd->coexIndType = wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndType; + for (index = 0; index < SIR_COEX_IND_DATA_SIZE; index++) + { + pSmeCoexInd->coexIndData[index] = wdiLowLevelInd->wdiIndicationData.wdiCoexInfo.coexIndData[index]; + } + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_COEX_IND; + vosMsg.bodyptr = (void *)pSmeCoexInd; + vosMsg.bodyval = 0; + /* Send message to SME */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + vos_mem_free((v_VOID_t *)pSmeCoexInd); + } + else + { + /* DEBUG */ + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "[COEX WDA] Coex Ind Type (%x) data (%x %x %x %x)", + pSmeCoexInd->coexIndType, + pSmeCoexInd->coexIndData[0], + pSmeCoexInd->coexIndData[1], + pSmeCoexInd->coexIndData[2], + pSmeCoexInd->coexIndData[3]); + } + break; + } + case WDI_TX_COMPLETE_IND: + { + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext) ; + /* Calling TxCompleteAck Indication from wda context*/ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Complete Indication received from HAL"); + if( pWDA->pAckTxCbFunc ) + { + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.TxCompleteTimer)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Tx Complete timeout Timer Stop Failed "); + } + if (!IS_FEATURE_SUPPORTED_BY_FW(ENHANCED_TXBD_COMPLETION)) + pWDA->pAckTxCbFunc( pMac, &wdiLowLevelInd->wdiIndicationData.tx_complete_status); + else + pWDA->pAckTxCbFunc( pMac, &wdiLowLevelInd->wdiIndicationData.wdiTxBdInd); + pWDA->pAckTxCbFunc = NULL; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Tx Complete Indication is received after timeout "); + } + break; + } + case WDI_P2P_NOA_START_IND : + { + tSirP2PNoaStart *pP2pNoaStart = + (tSirP2PNoaStart *)vos_mem_malloc(sizeof(tSirP2PNoaStart)); + + if (NULL == pP2pNoaStart) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_P2P_NOA_START_IND not forwarded"); + break; + } + pP2pNoaStart->status = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaStartInfo.status; + pP2pNoaStart->bssIdx = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaStartInfo.bssIdx; + WDA_SendMsg(pWDA, SIR_HAL_P2P_NOA_START_IND, + (void *)pP2pNoaStart , 0) ; + break; + } + +#ifdef FEATURE_WLAN_TDLS + case WDI_TDLS_IND : + { + tSirTdlsInd *pTdlsInd = + (tSirTdlsInd *)vos_mem_malloc(sizeof(tSirTdlsInd)); + + if (NULL == pTdlsInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_TDLS_IND not forwarded"); + break; + } + pTdlsInd->status = + wdiLowLevelInd->wdiIndicationData.wdiTdlsIndInfo.status; + pTdlsInd->assocId = + wdiLowLevelInd->wdiIndicationData.wdiTdlsIndInfo.assocId; + pTdlsInd->staIdx = + wdiLowLevelInd->wdiIndicationData.wdiTdlsIndInfo.staIdx; + pTdlsInd->reasonCode = + wdiLowLevelInd->wdiIndicationData.wdiTdlsIndInfo.reasonCode; + WDA_SendMsg(pWDA, SIR_HAL_TDLS_IND, + (void *)pTdlsInd , 0) ; + break; + } +#endif + case WDI_P2P_NOA_ATTR_IND : + { + tSirP2PNoaAttr *pP2pNoaAttr = + (tSirP2PNoaAttr *)vos_mem_malloc(sizeof(tSirP2PNoaAttr)); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_P2P_NOA_ATTR_IND from WDI"); + if (NULL == pP2pNoaAttr) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_P2P_NOA_ATTR_IND not forwarded"); + break; + } + pP2pNoaAttr->index = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.ucIndex; + pP2pNoaAttr->oppPsFlag = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.ucOppPsFlag; + pP2pNoaAttr->ctWin = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.usCtWin; + + pP2pNoaAttr->uNoa1IntervalCnt = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.usNoa1IntervalCnt; + pP2pNoaAttr->uNoa1Duration = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1Duration; + pP2pNoaAttr->uNoa1Interval = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1Interval; + pP2pNoaAttr->uNoa1StartTime = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1StartTime; + pP2pNoaAttr->uNoa2IntervalCnt = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.usNoa2IntervalCnt; + pP2pNoaAttr->uNoa2Duration = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2Duration; + pP2pNoaAttr->uNoa2Interval = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2Interval; + pP2pNoaAttr->uNoa2StartTime = + wdiLowLevelInd->wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2StartTime; + WDA_SendMsg(pWDA, SIR_HAL_P2P_NOA_ATTR_IND, + (void *)pP2pNoaAttr , 0) ; + break; + } +#ifdef FEATURE_WLAN_SCAN_PNO + case WDI_PREF_NETWORK_FOUND_IND: + { + vos_msg_t vosMsg; + v_U32_t size = sizeof(tSirPrefNetworkFoundInd) + + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.frameLength; + tSirPrefNetworkFoundInd *pPrefNetworkFoundInd = + (tSirPrefNetworkFoundInd *)vos_mem_malloc(size); + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_PREF_NETWORK_FOUND_IND from WDI"); + if (NULL == pPrefNetworkFoundInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_PREF_NETWORK_FOUND_IND not forwarded"); + if (NULL != + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData) + { + wpalMemoryFree( + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData + ); + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData = NULL; + } + break; + } + /* Message Header */ + pPrefNetworkFoundInd->mesgType = eWNI_SME_PREF_NETWORK_FOUND_IND; + pPrefNetworkFoundInd->mesgLen = size; + + /* Info from WDI Indication */ + pPrefNetworkFoundInd->ssId.length = + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength; + vos_mem_set( pPrefNetworkFoundInd->ssId.ssId, 32, 0); + vos_mem_copy( pPrefNetworkFoundInd->ssId.ssId, + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.ssId.sSSID, + pPrefNetworkFoundInd->ssId.length); + if (NULL != + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData) + { + pPrefNetworkFoundInd->frameLength = + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.frameLength; + vos_mem_copy( pPrefNetworkFoundInd->data, + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData, + pPrefNetworkFoundInd->frameLength); + wpalMemoryFree(wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData); + wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.pData = NULL; + } + else + { + pPrefNetworkFoundInd->frameLength = 0; + } + pPrefNetworkFoundInd ->rssi = wdiLowLevelInd->wdiIndicationData.wdiPrefNetworkFoundInd.rssi; + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_PREF_NETWORK_FOUND_IND; + vosMsg.bodyptr = (void *) pPrefNetworkFoundInd; + vosMsg.bodyval = 0; + /* Send message to SME */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + vos_mem_free((v_VOID_t *) pPrefNetworkFoundInd); + } + break; + } +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_WAKEUP_EVENTS + case WDI_WAKE_REASON_IND: + { + vos_msg_t vosMsg; + tANI_U32 allocSize = sizeof(tSirWakeReasonInd) + + (wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulStoredDataLen - 1); + tSirWakeReasonInd *pWakeReasonInd = (tSirWakeReasonInd *)vos_mem_malloc(allocSize); + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "[WAKE_REASON WDI] WAKE_REASON_IND Type (%d) data (ulReason=0x%x, ulReasonArg=0x%x, ulStoredDataLen=0x%x)", + wdiLowLevelInd->wdiIndicationType, + wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulReason, + wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulReasonArg, + wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulStoredDataLen); + + if (NULL == pWakeReasonInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_WAKE_REASON_IND not forwarded"); + break; + } + + vos_mem_zero(pWakeReasonInd, allocSize); + + /* Message Header */ + pWakeReasonInd->mesgType = eWNI_SME_WAKE_REASON_IND; + pWakeReasonInd->mesgLen = allocSize; + + /* Info from WDI Indication */ + // Fill pWakeReasonInd structure from wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd + pWakeReasonInd->ulReason = wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulReason; + pWakeReasonInd->ulReasonArg = wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulReasonArg; + pWakeReasonInd->ulStoredDataLen = wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulStoredDataLen; + pWakeReasonInd->ulActualDataLen = wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulActualDataLen; + vos_mem_copy( (void *)&(pWakeReasonInd->aDataStart[0]), + &(wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.aDataStart[0]), + wdiLowLevelInd->wdiIndicationData.wdiWakeReasonInd.ulStoredDataLen); + + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_WAKE_REASON_IND; + vosMsg.bodyptr = (void *) pWakeReasonInd; + vosMsg.bodyval = 0; + + /* Send message to SME */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + vos_mem_free((v_VOID_t *) pWakeReasonInd); + } + + break; + } +#endif // WLAN_WAKEUP_EVENTS + + case WDI_TX_PER_HIT_IND: + { + vos_msg_t vosMsg; + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, "Get WDI_TX_PER_HIT_IND"); + /* send IND to PE eWNI_SME_TX_PER_HIT_IND*/ + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_TX_PER_HIT_IND; + vosMsg.bodyptr = NULL; + vosMsg.bodyval = 0; + /* Send message to SME */ + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, "post eWNI_SME_TX_PER_HIT_IND to SME Failed"); + } + break; + } +#ifdef WLAN_FEATURE_RMC + case WDI_TX_FAIL_IND: + { + if (pWDA->txFailIndCallback) + { + pWDA->txFailIndCallback( + wdiLowLevelInd->wdiIndicationData.wdiTXFailInd.macAddr, + wdiLowLevelInd->wdiIndicationData.wdiTXFailInd.seqNo); + } + break; + } +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_LPHB + case WDI_LPHB_IND: + { + vos_msg_t vosMsg; + tSirLPHBInd *lphbInd; + + lphbInd = + (tSirLPHBInd *)vos_mem_malloc(sizeof(tSirLPHBInd)); + if (NULL == lphbInd) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: LPHB IND buffer alloc Fail", __func__); + return ; + } + + lphbInd->sessionIdx = + wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.sessionIdx; + lphbInd->protocolType = + wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.protocolType; + lphbInd->eventReason = + wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.eventReason; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Get WDI_LPHB_IND bssIdx %d", + wdiLowLevelInd->wdiIndicationData.wdiLPHBTimeoutInd.bssIdx); + + vosMsg.type = eWNI_SME_LPHB_IND; + vosMsg.bodyptr = lphbInd; + vosMsg.bodyval = 0; + /* Send message to SME */ + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "post WDI_LPHB_WAIT_TIMEOUT_IND to SME Failed"); + vos_mem_free(lphbInd); + } + break; + } +#endif /* FEATURE_WLAN_LPHB */ + case WDI_PERIODIC_TX_PTRN_FW_IND: + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: WDI_PERIODIC_TX_PTRN_FW_IND received, bssIdx: %d, " + "selfStaIdx: %d, status: %d, patternIdBitmap: %d", __func__, + (int)wdiLowLevelInd->wdiIndicationData.wdiPeriodicTxPtrnFwInd.bssIdx, + (int)wdiLowLevelInd->wdiIndicationData.wdiPeriodicTxPtrnFwInd.selfStaIdx, + (int)wdiLowLevelInd->wdiIndicationData.wdiPeriodicTxPtrnFwInd.status, + (int)wdiLowLevelInd->wdiIndicationData.wdiPeriodicTxPtrnFwInd.patternIdBitmap); + + break; + } + + case WDI_IBSS_PEER_INACTIVITY_IND: + { + tSirIbssPeerInactivityInd *pIbssInd = + (tSirIbssPeerInactivityInd *) + vos_mem_malloc(sizeof(tSirIbssPeerInactivityInd)); + + if (NULL == pIbssInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_IBSS_PEER_INACTIVITY_IND not forwarded"); + break; + } + + pIbssInd->bssIdx = + wdiLowLevelInd->wdiIndicationData.wdiIbssPeerInactivityInd.bssIdx; + pIbssInd->staIdx = + wdiLowLevelInd->wdiIndicationData.wdiIbssPeerInactivityInd.staIdx; + vos_mem_copy(pIbssInd->peerAddr, + wdiLowLevelInd->wdiIndicationData.wdiIbssPeerInactivityInd.staMacAddr, + sizeof(tSirMacAddr)); + WDA_SendMsg(pWDA, WDA_IBSS_PEER_INACTIVITY_IND, (void *)pIbssInd, 0) ; + break; + } + +#ifdef WLAN_FEATURE_RMC + case WDI_RMC_RULER_PICK_NEW : + { + tSirRmcUpdateInd *pRmcUpdateInd = + (tSirRmcUpdateInd *)vos_mem_malloc(sizeof(tSirRmcUpdateInd)); + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_RMC_UPDATE_IND from WDI"); + if (NULL == pRmcUpdateInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Memory allocation failure, " + "WDI_RMC_UPDATE_IND not forwarded"); + break; + } + + pRmcUpdateInd->indication = + wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.indication; + pRmcUpdateInd->role = + wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.role; + + /* Copy the mcast transmitter which should be us */ + vos_mem_copy(pRmcUpdateInd->mcastTransmitter, + wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd. \ + mcastTransmitter, + sizeof(tSirMacAddr)); + /* Copy the mcast group address */ + vos_mem_copy(pRmcUpdateInd->mcastGroup, + wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.mcastGroup, + sizeof(tSirMacAddr)); + vos_mem_copy(pRmcUpdateInd->mcastRuler, + wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.mcastRuler, + sizeof(tSirMacAddr)); + vos_mem_copy(pRmcUpdateInd->ruler, + wdiLowLevelInd->wdiIndicationData.wdiRmcPickNewRulerInd.ruler, + sizeof(pRmcUpdateInd->ruler)); + + WDA_SendMsg(pWDA, WDA_RMC_UPDATE_IND, (void *)pRmcUpdateInd, 0) ; + break; + } +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + case WDI_BATCH_SCAN_RESULT_IND: + { + void *pBatchScanResult; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_HIGH, + "Received WDI_BATCHSCAN_RESULT_IND from FW"); + + /*sanity check*/ + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return; + } + + pBatchScanResult = + (void *)wdiLowLevelInd->wdiIndicationData.pBatchScanResult; + if (NULL == pBatchScanResult) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:Batch scan result from FW is null can't invoke HDD callback", + __func__); + VOS_ASSERT(0); + return; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + return; + } + + pCallbackContext = pMac->pmc.batchScanResultCallbackContext; + /*call hdd callback with set batch scan response data*/ + if(pMac->pmc.batchScanResultCallback) + { + pMac->pmc.batchScanResultCallback(pCallbackContext, + pBatchScanResult); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + break; + } +#endif + +#ifdef FEATURE_WLAN_CH_AVOID + case WDI_CH_AVOID_IND: + { + vos_msg_t vosMsg; + tSirChAvoidIndType *chAvoidInd; + + chAvoidInd = + (tSirChAvoidIndType *)vos_mem_malloc(sizeof(tSirChAvoidIndType)); + if (NULL == chAvoidInd) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: CH_AVOID IND buffer alloc Fail", __func__); + return ; + } + + chAvoidInd->avoidRangeCount = + wdiLowLevelInd->wdiIndicationData.wdiChAvoidInd.avoidRangeCount; + wpalMemoryCopy((void *)chAvoidInd->avoidFreqRange, + (void *)wdiLowLevelInd->wdiIndicationData.wdiChAvoidInd.avoidFreqRange, + chAvoidInd->avoidRangeCount * sizeof(tSirChAvoidFreqType)); + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s : WDA CH avoid notification", __func__); + + vosMsg.type = eWNI_SME_CH_AVOID_IND; + vosMsg.bodyptr = chAvoidInd; + vosMsg.bodyval = 0; + /* Send message to SME */ + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "post eWNI_SME_CH_AVOID_IND to SME Failed"); + vos_mem_free(chAvoidInd); + } + break; + } +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case WDI_LL_STATS_RESULTS_IND: + { + void *pLinkLayerStatsInd; + tpAniSirGlobal pMac; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_LL_STATS_RESULTS_IND from FW"); + + /*sanity check*/ + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return; + } + + pLinkLayerStatsInd = + (void *)wdiLowLevelInd-> + wdiIndicationData.wdiLinkLayerStatsResults.pLinkLayerStatsResults; + if (NULL == pLinkLayerStatsInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:Link Layer Statistics from FW is null can't invoke HDD callback", + __func__); + VOS_ASSERT(0); + return; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + return; + } + + /* call hdd callback with Link Layer Statistics. + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + if (pMac->sme.pLinkLayerStatsIndCallback) + { + pMac->sme.pLinkLayerStatsIndCallback(pMac->pAdapter, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + pLinkLayerStatsInd, + wdiLowLevelInd-> + wdiIndicationData.wdiLinkLayerStatsResults.macAddr); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + } + break; + } +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +#ifdef WLAN_FEATURE_EXTSCAN + case WDI_EXTSCAN_PROGRESS_IND: + case WDI_EXTSCAN_SCAN_AVAILABLE_IND: + case WDI_EXTSCAN_SCAN_RESULT_IND: + case WDI_EXTSCAN_BSSID_HOTLIST_RESULT_IND: + { + void *pEXTScanData; + void *pCallbackContext; + tpAniSirGlobal pMac; + tANI_U16 indType; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_EXTSCAN Indications from FW"); + /*sanity check*/ + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return; + } + if (wdiLowLevelInd->wdiIndicationType == WDI_EXTSCAN_PROGRESS_IND) + { + indType = WDA_EXTSCAN_PROGRESS_IND; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDI_EXTSCAN Indication is WDI_EXTSCAN_PROGRESS_IND"); + } + if (wdiLowLevelInd->wdiIndicationType == + WDI_EXTSCAN_SCAN_AVAILABLE_IND) + { + indType = WDA_EXTSCAN_SCAN_AVAILABLE_IND; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDI_EXTSCAN Indication is WDI_EXTSCAN_SCAN_AVAILABLE_IND"); + } + if (wdiLowLevelInd->wdiIndicationType == WDI_EXTSCAN_SCAN_RESULT_IND) + { + indType = WDA_EXTSCAN_SCAN_RESULT_IND; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDI_EXTSCAN Indication is WDI_EXTSCAN_SCAN_RESULT_IND"); + } + if (wdiLowLevelInd->wdiIndicationType == + WDI_EXTSCAN_BSSID_HOTLIST_RESULT_IND) + { + indType = WDA_EXTSCAN_BSSID_HOTLIST_RESULT_IND; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDI_EXTSCAN Indication is WDI_EXTSCAN_BSSID_HOTLIST_RESULT_IND"); + } + + pEXTScanData = + (void *)wdiLowLevelInd->wdiIndicationData.pEXTScanIndData; + if (NULL == pEXTScanData) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: EXTSCAN Indication Data is null, can't invoke HDD callback", + __func__); + VOS_ASSERT(0); + return; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + return; + } + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if(pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, + indType, + pEXTScanData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + } + break; + } +#endif /* WLAN_FEATURE_EXTSCAN */ + case WDI_DEL_BA_IND: + { + tpBADeleteParams pDelBAInd = + (tpBADeleteParams)vos_mem_malloc(sizeof(*pDelBAInd)); + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Received WDI_DEL_BA_IND from WDI "); + if(NULL == pDelBAInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + break; + } + vos_mem_copy(pDelBAInd->peerMacAddr, + wdiLowLevelInd->wdiIndicationData.wdiDeleteBAInd.peerMacAddr, + sizeof(tSirMacAddr)); + vos_mem_copy(pDelBAInd->bssId, + wdiLowLevelInd->wdiIndicationData.wdiDeleteBAInd.bssId, + sizeof(tSirMacAddr)); + pDelBAInd->staIdx = + wdiLowLevelInd->wdiIndicationData.wdiDeleteBAInd.staIdx; + pDelBAInd->baTID = + wdiLowLevelInd->wdiIndicationData.wdiDeleteBAInd.baTID; + pDelBAInd->baDirection = + wdiLowLevelInd->wdiIndicationData.wdiDeleteBAInd.baDirection; + pDelBAInd->reasonCode = + wdiLowLevelInd->wdiIndicationData.wdiDeleteBAInd.reasonCode; + + WDA_SendMsg(pWDA, SIR_LIM_DEL_BA_IND, + (void *)pDelBAInd , 0) ; + break; + } + case WDI_NAN_EVENT_IND: + { + vos_msg_t vosMsg; + tpSirNanEvent pSirNanEvent = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_NAN_EVENT"); + + pSirNanEvent = (tpSirNanEvent)vos_mem_malloc( sizeof( tSirNanEvent ) + - sizeof( pSirNanEvent->event_data) + + wdiLowLevelInd->wdiIndicationData.wdiNanEvent.event_data_len); + + if (NULL == pSirNanEvent) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0) ; + break; + } + + pSirNanEvent->event_data_len = + wdiLowLevelInd->wdiIndicationData.wdiNanEvent.event_data_len; + + if (wdiLowLevelInd->wdiIndicationData.wdiNanEvent.event_data_len) + { + vos_mem_copy( pSirNanEvent->event_data, + wdiLowLevelInd->wdiIndicationData.wdiNanEvent.event_data, + wdiLowLevelInd->wdiIndicationData.wdiNanEvent.event_data_len); + } + + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_NAN_EVENT; + vosMsg.bodyptr = pSirNanEvent; + vosMsg.bodyval = 0; + + /* Send message to SME */ + if (VOS_STATUS_SUCCESS + != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "post eWNI_SME_NAN_EVENT to SME Failed"); + vos_mem_free(pSirNanEvent); + } + break; + } + case WDI_LOST_LINK_PARAMS_IND: + { + tpSirSmeLostLinkParamsInd pLostLinkParamInd = + (tpSirSmeLostLinkParamsInd)vos_mem_malloc(sizeof(tSirSmeLostLinkParamsInd)); + + if (NULL == pLostLinkParamInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + break; + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_LOST_LINK_PARAMS_IND from WDI "); + + pLostLinkParamInd->messageType = eWNI_SME_LOST_LINK_PARAMS_IND; + pLostLinkParamInd->length = sizeof(tSirSmeMicFailureInd); + pLostLinkParamInd->info.bssIdx = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.bssIdx; + pLostLinkParamInd->info.rssi = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.rssi; + vos_mem_copy(pLostLinkParamInd->info.selfMacAddr, + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.selfMacAddr, + sizeof(tSirMacAddr)); + pLostLinkParamInd->info.linkFlCnt = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.linkFlCnt; + pLostLinkParamInd->info.linkFlTx = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.linkFlTx; + pLostLinkParamInd->info.lastDataRate = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.lastDataRate; + pLostLinkParamInd->info.rsvd1 = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.rsvd1; + pLostLinkParamInd->info.rsvd2 = + wdiLowLevelInd->wdiIndicationData.wdiLostLinkParamsInd.rsvd2; + WDA_SendMsg(pWDA, SIR_HAL_LOST_LINK_PARAMS_IND, + (void *)pLostLinkParamInd , 0) ; + break; + } + case WDI_RSSI_BREACHED_IND: + { + WDI_RssiBreachedIndType *pRssiBreachedInd; + tpAniSirGlobal pMac; + + pRssiBreachedInd = + (WDI_RssiBreachedIndType *)vos_mem_malloc(sizeof(WDI_RssiBreachedIndType)); + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_RSSI_BREACHED_IND from FW"); + + vos_mem_copy(pRssiBreachedInd, + &wdiLowLevelInd->wdiIndicationData.wdiRssiBreachedInd, + sizeof(WDI_RssiBreachedIndType)); + + /*sanity check*/ + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + vos_mem_free(pRssiBreachedInd); + VOS_ASSERT(0); + return; + } + + if (NULL == pRssiBreachedInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:Breach indication from FW is null can't invoke HDD callback", + __func__); + VOS_ASSERT(0); + return; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pRssiBreachedInd); + return; + } + + if (pMac->sme.rssiThresholdBreachedCb) + { + pMac->sme.rssiThresholdBreachedCb(pMac->pAdapter, (void *)pRssiBreachedInd); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + } + vos_mem_free(pRssiBreachedInd); + break; + } +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDI_START_OEM_DATA_RSP_IND_NEW: + { + void *pCallbackContext; + tpAniSirGlobal pMac; + tANI_U16 indType; + void *pOemRspNewIndData; + tANI_U32 OemRspNewLen; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Received WDI_START_OEM_DATA_RSP_IND_NEW Indications from FW"); + + /*sanity check*/ + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return; + } + + indType = WDA_START_OEM_DATA_RSP_IND_NEW; + pOemRspNewIndData = + (void *)wdiLowLevelInd->wdiIndicationData.wdiOemDataRspNew. + pOemRspNewIndData; + if (NULL == pOemRspNewIndData) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: OEM_DATA_RSP_IND_NEW Indication Data is null, can't invoke HDD callback", + __func__); + VOS_ASSERT(0); + return; + } + + OemRspNewLen = wdiLowLevelInd->wdiIndicationData.wdiOemDataRspNew. + OemRspNewLen; + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + return; + } + + pCallbackContext = pMac->sme.pOemDataCallbackContext; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: OemRspNewLen: %d", __func__, OemRspNewLen); + + if(pMac->sme.pOemDataIndCb) + { + pMac->sme.pOemDataIndCb(pCallbackContext, + indType, + pOemRspNewIndData, + OemRspNewLen); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + } + break; + } +#endif /* FEATURE_OEM_DATA_SUPPORT */ + + default: + { + /* TODO error */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Received UNKNOWN Indication from WDI "); + } + } + return ; +} + +/* + * BA related processing in WDA. + */ +void WDA_TriggerBaReqCallback(WDI_TriggerBARspParamsType *wdiTriggerBaRsp, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext; + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(WDI_STATUS_SUCCESS == wdiTriggerBaRsp->wdiStatus) + { + tANI_U8 i = 0 ; + tBaActivityInd *baActivityInd = NULL ; + tANI_U8 baCandidateCount = wdiTriggerBaRsp->usBaCandidateCnt ; + tANI_U8 allocSize = sizeof(tBaActivityInd) + + sizeof(tAddBaCandidate) * (baCandidateCount) ; + WDI_TriggerBARspCandidateType *wdiBaCandidate = NULL ; + tAddBaCandidate *baCandidate = NULL ; + baActivityInd = (tBaActivityInd *)vos_mem_malloc(allocSize) ; + if(NULL == baActivityInd) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0) ; + return; + } + vos_mem_copy(baActivityInd->bssId, wdiTriggerBaRsp->macBSSID, + sizeof(tSirMacAddr)) ; + baActivityInd->baCandidateCnt = baCandidateCount ; + + wdiBaCandidate = (WDI_TriggerBARspCandidateType*)(wdiTriggerBaRsp + 1) ; + baCandidate = (tAddBaCandidate*)(baActivityInd + 1) ; + + for(i = 0 ; i < baCandidateCount ; i++) + { + tANI_U8 tid = 0 ; + vos_mem_copy(baCandidate->staAddr, wdiBaCandidate->macSTA, + sizeof(tSirMacAddr)) ; + for(tid = 0 ; tid < STACFG_MAX_TC; tid++) + { + baCandidate->baInfo[tid].fBaEnable = + wdiBaCandidate->wdiBAInfo[tid].fBaEnable ; + baCandidate->baInfo[tid].startingSeqNum = + wdiBaCandidate->wdiBAInfo[tid].startingSeqNum ; + } + wdiBaCandidate++ ; + baCandidate++ ; + } + WDA_SendMsg(pWDA, SIR_LIM_ADD_BA_IND, (void *)baActivityInd , 0) ; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "BA Trigger RSP with Failure received "); + } + return ; +} + + +/* + * API to activate/deactivate Traffic Stats timer. Traffic stats timer is only needed + * during MCC + */ +void WDA_TrafficStatsTimerActivate(wpt_boolean activate) +{ + wpt_uint32 enabled; + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tWDA_CbContext *pWDA = vos_get_context(VOS_MODULE_ID_WDA, pVosContext); + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pVosContext); + + if (NULL == pMac ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid MAC context ", __func__ ); + VOS_ASSERT(0); + return; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, &enabled) + != eSIR_SUCCESS) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED"); + return; + } + + if(!enabled) + { + return; + } + + if(NULL == pWDA) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:WDA context is NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(activate) + { + if( VOS_STATUS_SUCCESS != + WDA_START_TIMER(&pWDA->wdaTimers.trafficStatsTimer)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Traffic Stats Timer Start Failed "); + return; + } + WDI_DS_ActivateTrafficStats(); + } + else + { + WDI_DS_DeactivateTrafficStats(); + WDI_DS_ClearTrafficStats(); + + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.trafficStatsTimer)) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Traffic Stats Timer Stop Failed "); + return; + } + } +} + +/* + * Traffic Stats Timer handler + */ +void WDA_TimerTrafficStatsInd(tWDA_CbContext *pWDA) +{ + WDI_Status wdiStatus; + WDI_TrafficStatsType *pWdiTrafficStats = NULL; + WDI_TrafficStatsIndType trafficStatsIndParams; + wpt_uint32 length, enabled; + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + + if (NULL == pMac ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid MAC context ", __func__ ); + VOS_ASSERT(0); + return; + } + + if(wlan_cfgGetInt(pMac, WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED, &enabled) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED"); + return; + } + + if(!enabled) + { + WDI_DS_DeactivateTrafficStats(); + return; + } + + WDI_DS_GetTrafficStats(&pWdiTrafficStats, &length); + + if(pWdiTrafficStats != NULL) + { + trafficStatsIndParams.pTrafficStats = pWdiTrafficStats; + trafficStatsIndParams.length = length; + trafficStatsIndParams.duration = + pWDA->wdaTimers.trafficStatsTimer.initScheduleTimeInMsecs; + trafficStatsIndParams.wdiReqStatusCB = WDA_WdiIndicationCallback; + trafficStatsIndParams.pUserData = pWDA; + + wdiStatus = WDI_TrafficStatsInd(&trafficStatsIndParams); + + if(WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ",__func__,__LINE__ ); + } + else if( WDI_STATUS_SUCCESS_SYNC != wdiStatus ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d ",__func__,__LINE__ ); + } + + WDI_DS_ClearTrafficStats(); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "pWdiTrafficStats is Null"); + } + + if( VOS_STATUS_SUCCESS != + WDA_START_TIMER(&pWDA->wdaTimers.trafficStatsTimer)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_WARN, + "Traffic Stats Timer Start Failed "); + return; + } +} + +bool WDA_AllowAddBA(tpAniSirGlobal pMac, tANI_U8 staId, tANI_U8 tid) +{ + if (!pMac->lim.staBaInfo[staId].failed_count[tid]) + return true; + if ((WDA_BA_MAX_RETRY_THRESHOLD <= + pMac->lim.staBaInfo[staId].failed_count[tid]) || + ((pMac->lim.staBaInfo[staId].failed_timestamp[tid] + + (pMac->lim.staBaInfo[staId].failed_count[tid] * WDA_BA_RETRY_TIME)) >= + jiffies_to_msecs(jiffies))) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: AP/STA has declined ADDBA req for tid %d, declined %d times", + __func__, tid, pMac->lim.staBaInfo[staId].failed_count[tid]); + return false; + } + return true; +} + +/* + * BA Activity check timer handler + */ +void WDA_BaCheckActivity(tWDA_CbContext *pWDA) +{ + tANI_U8 curSta = 0 ; + tANI_U8 tid = 0 ; + tANI_U8 size = 0 ; + tANI_U8 baCandidateCount = 0 ; + tANI_U8 newBaCandidate = 0 ; + tANI_U32 val, val1; + WDI_TriggerBAReqCandidateType baCandidate[WDA_MAX_STA] = {{0}} ; + tpAniSirGlobal pMac; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pWDA is NULL", __func__); + VOS_ASSERT(0); + return ; + } + if(WDA_MAX_STA < pWDA->wdaMaxSta) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Inconsistent STA entries in WDA"); + VOS_ASSERT(0) ; + } + if(NULL == pWDA->pVosContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pVosContext is NULL",__func__); + VOS_ASSERT(0); + return ; + } + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if(NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pMac is NULL",__func__); + VOS_ASSERT(0); + return ; + } + + if (wlan_cfgGetInt(pMac, + WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, &val) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to get WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC"); + val = 0; + } + + if (wlan_cfgGetInt(pMac, + WNI_CFG_ENABLE_TX_RX_AGGREGATION, &val1) != + eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to get WNI_CFG_ENABLE_TX_RX_AGGREGATION"); + val1 = 1; + } + /* walk through all STA entries and find out TX packet count */ + for(curSta = 0 ; curSta < pWDA->wdaMaxSta ; curSta++) + { + tANI_U32 currentOperChan = pWDA->wdaStaInfo[curSta].currentOperChan; +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // We can only do BA on "hard" STAs. + if (!(IS_HWSTA_IDX(curSta))) + { + continue; + } +#endif //WLAN_SOFTAP_VSTA_FEATURE + for(tid = 0 ; tid < STACFG_MAX_TC ; tid++) + { + WLANTL_STAStateType tlSTAState ; + tANI_U32 txPktCount = 0 ; + tANI_U8 validStaIndex = pWDA->wdaStaInfo[curSta].ucValidStaIndex ; + if((WDA_VALID_STA_INDEX == validStaIndex) && + (VOS_STATUS_SUCCESS == WDA_TL_GET_STA_STATE( pWDA->pVosContext, + curSta, &tlSTAState)) && + (VOS_STATUS_SUCCESS == WDA_TL_GET_TX_PKTCOUNT( pWDA->pVosContext, + curSta, tid, &txPktCount))) + { +#if 0 + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_LOW, + "************* %d:%d, %d ",curSta, txPktCount, + pWDA->wdaStaInfo[curSta].framesTxed[tid]); +#endif + if(val && ( (currentOperChan >= SIR_11B_CHANNEL_BEGIN) && + (currentOperChan <= SIR_11B_CHANNEL_END))) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: BTC disabled aggregation - dont start " + "TX ADDBA req",__func__); + } + else if (!val1) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: aggregation disabled- dont start " + "TX ADDBA req",__func__); + } + else if(!WDA_GET_BA_TXFLAG(pWDA, curSta, tid) + && (WLANTL_STA_AUTHENTICATED == tlSTAState) + && WDA_AllowAddBA(pMac, curSta, tid) + && (((eSYSTEM_STA_IN_IBSS_ROLE == + pWDA->wdaGlobalSystemRole) && txPktCount ) + || (txPktCount >= WDA_LAST_POLLED_THRESHOLD(pWDA, + curSta, tid)))) + { + /* get prepare for sending message to HAL */ + //baCandidate[baCandidateCount].staIdx = curSta ; + baCandidate[baCandidateCount].ucTidBitmap |= 1 << tid ; + newBaCandidate = WDA_ENABLE_BA ; + } + pWDA->wdaStaInfo[curSta].framesTxed[tid] = txPktCount ; + } + } + /* fill the entry for all the sta with given TID's */ + if(WDA_ENABLE_BA == newBaCandidate) + { + /* move to next BA candidate */ + baCandidate[baCandidateCount].ucSTAIdx = curSta ; + size += sizeof(WDI_TriggerBAReqCandidateType) ; + baCandidateCount++ ; + newBaCandidate = WDA_DISABLE_BA ; + } + } + /* prepare and send message to hal */ + if( 0 < baCandidateCount) + { + WDI_Status status = WDI_STATUS_SUCCESS ; + WDI_TriggerBAReqParamsType *wdiTriggerBaReq; + tWDA_ReqParams *pWdaParams = + (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0) ; + return; + } + wdiTriggerBaReq = (WDI_TriggerBAReqParamsType *) + vos_mem_malloc(sizeof(WDI_TriggerBAReqParamsType) + size) ; + if(NULL == wdiTriggerBaReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pWdaParams); + return; + } + do + { + WDI_TriggerBAReqinfoType *triggerBaInfo = + &wdiTriggerBaReq->wdiTriggerBAInfoType ; + triggerBaInfo->usBACandidateCnt = baCandidateCount ; + /* TEMP_FIX: Need to see if WDI need check for assoc session for + * for each request */ + triggerBaInfo->ucSTAIdx = baCandidate[0].ucSTAIdx ; + triggerBaInfo->ucBASessionID = 0; + vos_mem_copy((wdiTriggerBaReq + 1), baCandidate, size) ; + } while(0) ; + wdiTriggerBaReq->wdiReqStatusCB = NULL ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaWdiApiMsgParam = wdiTriggerBaReq ; + pWdaParams->wdaMsgParam = NULL; + status = WDI_TriggerBAReq(wdiTriggerBaReq, size, + WDA_TriggerBaReqCallback, pWdaParams) ; + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Trigger BA REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO_LOW, + "There is no TID for initiating BA"); + } + if( VOS_STATUS_SUCCESS != + WDA_STOP_TIMER(&pWDA->wdaTimers.baActivityChkTmr)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "BA Activity Timer Stop Failed "); + return ; + } + if( VOS_STATUS_SUCCESS != + WDA_START_TIMER(&pWDA->wdaTimers.baActivityChkTmr)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "BA Activity Timer Start Failed "); + return; + } + return ; +} +/* + * WDA common routine to create timer used by WDA. + */ +static VOS_STATUS wdaCreateTimers(tWDA_CbContext *pWDA) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS ; + tANI_U32 val = 0 ; + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + + if(NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:MAC context is NULL", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + if(wlan_cfgGetInt(pMac, WNI_CFG_BA_ACTIVITY_CHECK_TIMEOUT, &val ) + != eSIR_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failed to get value for WNI_CFG_CURRENT_TX_ANTENNA"); + return VOS_STATUS_E_FAILURE; + } + val = SYS_MS_TO_TICKS(val) ; + + /* BA activity check timer */ + status = WDA_CREATE_TIMER(&pWDA->wdaTimers.baActivityChkTmr, + "BA Activity Check timer", WDA_TimerHandler, + WDA_TIMER_BA_ACTIVITY_REQ, val, val, TX_NO_ACTIVATE) ; + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to create BA activity timer"); + return VOS_STATUS_E_FAILURE ; + } + val = SYS_MS_TO_TICKS( WDA_TX_COMPLETE_TIME_OUT_VALUE ) ; + /* Tx Complete Timeout timer */ + status = WDA_CREATE_TIMER(&pWDA->wdaTimers.TxCompleteTimer, + "Tx Complete Check timer", WDA_TimerHandler, + WDA_TX_COMPLETE_TIMEOUT_IND, val, val, TX_NO_ACTIVATE) ; + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to create Tx Complete Timeout timer"); + /* Destroy timer of BA activity check timer */ + status = WDA_DESTROY_TIMER(&pWDA->wdaTimers.baActivityChkTmr); + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to Destroy BA activity timer"); + return VOS_STATUS_E_FAILURE ; + } + return VOS_STATUS_E_FAILURE ; + } + + val = SYS_MS_TO_TICKS( WDA_TRAFFIC_STATS_TIME_OUT_VALUE ); + + /* Traffic Stats timer */ + status = WDA_CREATE_TIMER(&pWDA->wdaTimers.trafficStatsTimer, + "Traffic Stats timer", WDA_TimerHandler, + WDA_TIMER_TRAFFIC_STATS_IND, val, val, TX_NO_ACTIVATE) ; + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to create traffic stats timer"); + /* Destroy timer of BA activity check timer */ + status = WDA_DESTROY_TIMER(&pWDA->wdaTimers.baActivityChkTmr); + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to Destroy BA activity timer"); + } + /* Destroy timer of tx complete timer */ + status = WDA_DESTROY_TIMER(&pWDA->wdaTimers.TxCompleteTimer); + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to Tx complete timer"); + } + return VOS_STATUS_E_FAILURE ; + } + return VOS_STATUS_SUCCESS ; +} +/* + * WDA common routine to destroy timer used by WDA. + */ +static VOS_STATUS wdaDestroyTimers(tWDA_CbContext *pWDA) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS ; + status = WDA_DESTROY_TIMER(&pWDA->wdaTimers.TxCompleteTimer); + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to Destroy Tx Complete Timeout timer"); + return eSIR_FAILURE ; + } + status = WDA_DESTROY_TIMER(&pWDA->wdaTimers.baActivityChkTmr); + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to Destroy BA activity timer"); + return eSIR_FAILURE ; + } + status = WDA_DESTROY_TIMER(&pWDA->wdaTimers.trafficStatsTimer); + if(status != TX_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Unable to Destroy traffic stats timer"); + return eSIR_FAILURE ; + } + return eSIR_SUCCESS ; +} +/* + * WDA timer handler. + */ +void WDA_TimerHandler(v_VOID_t* pContext, tANI_U32 timerInfo) +{ + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + vos_msg_t wdaMsg = {0} ; + /* + * trigger CFG download in WDA by sending WDA_CFG_DNLD message + */ + wdaMsg.type = timerInfo ; + wdaMsg.bodyptr = NULL; + wdaMsg.bodyval = 0; + /* post the message.. */ + vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &wdaMsg ); + if ( !VOS_IS_STATUS_SUCCESS(vosStatus) ) + { + vosStatus = VOS_STATUS_E_BADMSG; + } +} +/* + * WDA Tx Complete timeout Indication. + */ +void WDA_ProcessTxCompleteTimeOutInd(tWDA_CbContext* pWDA) +{ + tpAniSirGlobal pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext) ; + tpSirTxBdStatus txBdStatus = {0}; + + if( pWDA->pAckTxCbFunc ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "TxComplete timer expired"); + /*Indicate failure*/ + pWDA->pAckTxCbFunc( pMac, &txBdStatus); + pWDA->pAckTxCbFunc = NULL; + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "There is no request pending for TxComplete and wait timer expired"); + } +} +/* + * WDA Set REG Domain to VOS NV + */ +eHalStatus WDA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId, + tAniBool sendRegHint) +{ + if(VOS_STATUS_SUCCESS != vos_nv_setRegDomain(clientCtxt, regId, sendRegHint)) + { + return eHAL_STATUS_INVALID_PARAMETER; + } + return eHAL_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_SCAN_PNO +/* + * FUNCTION: WDA_PNOScanRespCallback + * + */ +void WDA_PNOScanRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirPNOScanReq *pPNOScanReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d",__func__, status); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pPNOScanReqParams = (tSirPNOScanReq *)pWdaParams->wdaMsgParam; + if(pPNOScanReqParams->statusCallback) + { + pPNOScanReqParams->statusCallback(pPNOScanReqParams->callbackContext, + (status == WDI_STATUS_SUCCESS) ? + VOS_STATUS_SUCCESS : VOS_STATUS_E_FAILURE); + } + + if (pPNOScanReqParams->enable == 1) + { + if (pPNOScanReqParams->aNetworks) + vos_mem_free(pPNOScanReqParams->aNetworks); + if (pPNOScanReqParams->p24GProbeTemplate) + vos_mem_free(pPNOScanReqParams->p24GProbeTemplate); + if (pPNOScanReqParams->p5GProbeTemplate) + vos_mem_free(pPNOScanReqParams->p5GProbeTemplate); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return ; +} +/* + * FUNCTION: WDA_PNOScanReqCallback + * Free memory. + * Invoked when PNOScan REQ failed in WDI and no RSP callback is generated. + */ +void WDA_PNOScanReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirPNOScanReq *pPNOScanReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + pPNOScanReqParams = (tSirPNOScanReq *)pWdaParams->wdaMsgParam; + if(pPNOScanReqParams->statusCallback) + { + pPNOScanReqParams->statusCallback(pPNOScanReqParams->callbackContext, + VOS_STATUS_E_FAILURE); + } + + if (pPNOScanReqParams->enable == 1) + { + if (pPNOScanReqParams->aNetworks) + vos_mem_free(pPNOScanReqParams->aNetworks); + if (pPNOScanReqParams->p24GProbeTemplate) + vos_mem_free(pPNOScanReqParams->p24GProbeTemplate); + if (pPNOScanReqParams->p5GProbeTemplate) + vos_mem_free(pPNOScanReqParams->p5GProbeTemplate); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_UpdateScanParamsRespCallback + * + */ +void WDA_UpdateScanParamsRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return ; +} +/* + * FUNCTION: WDA_UpdateScanParamsReqCallback + * Free memory. + * Invoked when UpdateScanParams REQ failed in WDI and no RSP callback is generated. + */ +void WDA_UpdateScanParamsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessSetPreferredNetworkList + * Request to WDI to set Preferred Network List.Offload + */ +VOS_STATUS WDA_ProcessSetPrefNetworkReq(tWDA_CbContext *pWDA, + tSirPNOScanReq *pPNOScanReqParams) +{ + WDI_Status status; + WDI_PNOScanReqParamsType *pwdiPNOScanReqInfo = + (WDI_PNOScanReqParamsType *)vos_mem_malloc(sizeof(WDI_PNOScanReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + v_U8_t i; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiPNOScanReqInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiPNOScanReqInfo); + return VOS_STATUS_E_NOMEM; + } + // + // Fill wdiPNOScanReqInfo->wdiPNOScanInfo from pPNOScanReqParams + // + pwdiPNOScanReqInfo->wdiPNOScanInfo.bEnable = pPNOScanReqParams->enable; + pwdiPNOScanReqInfo->wdiPNOScanInfo.wdiModePNO = pPNOScanReqParams->modePNO; + pwdiPNOScanReqInfo->wdiPNOScanInfo.ucNetworksCount = + ( pPNOScanReqParams->ucNetworksCount < WDI_PNO_MAX_SUPP_NETWORKS )? + pPNOScanReqParams->ucNetworksCount : WDI_PNO_MAX_SUPP_NETWORKS ; + for ( i = 0; i < pwdiPNOScanReqInfo->wdiPNOScanInfo.ucNetworksCount ; i++) + { + vos_mem_copy(&pwdiPNOScanReqInfo->wdiPNOScanInfo.aNetworks[i], + &pPNOScanReqParams->aNetworks[i], + sizeof(pwdiPNOScanReqInfo->wdiPNOScanInfo.aNetworks[i])); + } + /*Scan timer intervals*/ + vos_mem_copy(&pwdiPNOScanReqInfo->wdiPNOScanInfo.scanTimers, + &pPNOScanReqParams->scanTimers, + sizeof(pwdiPNOScanReqInfo->wdiPNOScanInfo.scanTimers)); + /*Probe template for 2.4GHz band*/ + pwdiPNOScanReqInfo->wdiPNOScanInfo.us24GProbeSize = + (pPNOScanReqParams->us24GProbeTemplateLenus24GProbeTemplateLen:WDI_PNO_MAX_PROBE_SIZE; + vos_mem_copy( &pwdiPNOScanReqInfo->wdiPNOScanInfo.a24GProbeTemplate, + pPNOScanReqParams->p24GProbeTemplate, + pwdiPNOScanReqInfo->wdiPNOScanInfo.us24GProbeSize); + /*Probe template for 5GHz band*/ + pwdiPNOScanReqInfo->wdiPNOScanInfo.us5GProbeSize = + (pPNOScanReqParams->us5GProbeTemplateLenus5GProbeTemplateLen:WDI_PNO_MAX_PROBE_SIZE; + vos_mem_copy( &pwdiPNOScanReqInfo->wdiPNOScanInfo.a5GProbeTemplate, + pPNOScanReqParams->p5GProbeTemplate, + pwdiPNOScanReqInfo->wdiPNOScanInfo.us5GProbeSize); + pwdiPNOScanReqInfo->wdiReqStatusCB = WDA_PNOScanReqCallback; + pwdiPNOScanReqInfo->pUserData = pWdaParams; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiPNOScanReqInfo; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pPNOScanReqParams; + status = WDI_SetPreferredNetworkReq(pwdiPNOScanReqInfo, + (WDI_PNOScanCb)WDA_PNOScanRespCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set PNO REQ WDI API, free all the memory " ); + if(pPNOScanReqParams->statusCallback) + { + pPNOScanReqParams->statusCallback(pPNOScanReqParams->callbackContext, + VOS_STATUS_E_FAILURE); + } + if (pPNOScanReqParams->enable == 1) + { + if (pPNOScanReqParams->aNetworks) + vos_mem_free(pPNOScanReqParams->aNetworks); + if (pPNOScanReqParams->p24GProbeTemplate) + vos_mem_free(pPNOScanReqParams->p24GProbeTemplate); + if (pPNOScanReqParams->p5GProbeTemplate) + vos_mem_free(pPNOScanReqParams->p5GProbeTemplate); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + + pWdaParams->wdaWdiApiMsgParam = NULL; + pWdaParams->wdaMsgParam = NULL; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +void WDA_ConvertSirAuthToWDIAuth(WDI_AuthType *AuthType, v_U8_t csrAuthType) +{ + /*Convert the CSR Auth types to WDI Auth types */ + switch (csrAuthType) + { + case eCSR_AUTH_TYPE_OPEN_SYSTEM: + *AuthType = eWDA_AUTH_TYPE_OPEN_SYSTEM; + break; +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_WPA: + *AuthType = eWDA_AUTH_TYPE_CCKM_WPA; + break; +#endif + case eCSR_AUTH_TYPE_WPA: + *AuthType = eWDA_AUTH_TYPE_WPA; + break; + case eCSR_AUTH_TYPE_WPA_PSK: + *AuthType = eWDA_AUTH_TYPE_WPA_PSK; + break; +#ifdef FEATURE_WLAN_ESE + case eCSR_AUTH_TYPE_CCKM_RSN: + *AuthType = eWDA_AUTH_TYPE_CCKM_RSN; + break; +#endif + case eCSR_AUTH_TYPE_RSN: + *AuthType = eWDA_AUTH_TYPE_RSN; + break; + case eCSR_AUTH_TYPE_RSN_PSK: + *AuthType = eWDA_AUTH_TYPE_RSN_PSK; + break; +#if defined WLAN_FEATURE_VOWIFI_11R + case eCSR_AUTH_TYPE_FT_RSN: + *AuthType = eWDA_AUTH_TYPE_FT_RSN; + break; + case eCSR_AUTH_TYPE_FT_RSN_PSK: + *AuthType = eWDA_AUTH_TYPE_FT_RSN_PSK; + break; +#endif +#ifdef FEATURE_WLAN_WAPI + case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE: + *AuthType = eWDA_AUTH_TYPE_WAPI_WAI_CERTIFICATE; + break; + case eCSR_AUTH_TYPE_WAPI_WAI_PSK: + *AuthType = eWDA_AUTH_TYPE_WAPI_WAI_PSK; + break; +#endif /* FEATURE_WLAN_WAPI */ + case eCSR_AUTH_TYPE_SHARED_KEY: + case eCSR_AUTH_TYPE_AUTOSWITCH: + *AuthType = eWDA_AUTH_TYPE_OPEN_SYSTEM; + break; +#ifdef WLAN_FEATURE_11W + case eCSR_AUTH_TYPE_RSN_PSK_SHA256: + *AuthType = eWDA_AUTH_TYPE_RSN_PSK_SHA256; + break; + case eCSR_AUTH_TYPE_RSN_8021X_SHA256: + *AuthType = eWDA_AUTH_TYPE_RSN_8021X_SHA256; + break; +#endif + default: + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Unknown Auth Type", __func__); + break; + } +} +void WDA_ConvertSirEncToWDIEnc(WDI_EdType *EncrType, v_U8_t csrEncrType) +{ + switch (csrEncrType) + { + case eCSR_ENCRYPT_TYPE_NONE: + *EncrType = WDI_ED_NONE; + break; + case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY: + case eCSR_ENCRYPT_TYPE_WEP40: + *EncrType = WDI_ED_WEP40; + break; + case eCSR_ENCRYPT_TYPE_WEP104: + case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY: + *EncrType = WDI_ED_WEP104; + break; + case eCSR_ENCRYPT_TYPE_TKIP: + *EncrType = WDI_ED_TKIP; + break; + case eCSR_ENCRYPT_TYPE_AES: + *EncrType = WDI_ED_CCMP; + break; +#ifdef WLAN_FEATURE_11W + case eCSR_ENCRYPT_TYPE_AES_CMAC: + *EncrType = WDI_ED_AES_128_CMAC; + break; +#endif +#ifdef FEATURE_WLAN_WAPI + case eCSR_ENCRYPT_TYPE_WPI: + *EncrType = WDI_ED_WPI; + break; +#endif + case eCSR_ENCRYPT_TYPE_ANY: + *EncrType = WDI_ED_ANY; + break; + + default: + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unknown Encryption Type", __func__); + break; + } +} + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +VOS_STATUS WDA_ProcessPERRoamScanOffloadReq(tWDA_CbContext *pWDA, + tSirPERRoamOffloadScanReq *pPERRoamOffloadScanReqParams) +{ + WDI_Status status; + tWDA_ReqParams *pWdaParams ; + WDI_PERRoamOffloadScanInfo *pwdiPERRoamOffloadScanInfo; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + pwdiPERRoamOffloadScanInfo = (WDI_PERRoamOffloadScanInfo *) + vos_mem_malloc(sizeof(WDI_PERRoamOffloadScanInfo)); + if (NULL == pwdiPERRoamOffloadScanInfo) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if (NULL == pWdaParams) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiPERRoamOffloadScanInfo); + return VOS_STATUS_E_NOMEM; + } + + pwdiPERRoamOffloadScanInfo->rateUpThreshold = + pPERRoamOffloadScanReqParams->rateUpThreshold; + pwdiPERRoamOffloadScanInfo->rateDownThreshold = + pPERRoamOffloadScanReqParams->rateDownThreshold; + pwdiPERRoamOffloadScanInfo->waitPeriodForNextPERScan = + pPERRoamOffloadScanReqParams->waitPeriodForNextPERScan; + pwdiPERRoamOffloadScanInfo->PERtimerThreshold = + pPERRoamOffloadScanReqParams->PERtimerThreshold; + pwdiPERRoamOffloadScanInfo->isPERRoamCCAEnabled = + pPERRoamOffloadScanReqParams->isPERRoamCCAEnabled; + pwdiPERRoamOffloadScanInfo->PERRoamFullScanThreshold = + pPERRoamOffloadScanReqParams->PERRoamFullScanThreshold; + pwdiPERRoamOffloadScanInfo->PERroamTriggerPercent = + pPERRoamOffloadScanReqParams->PERroamTriggerPercent; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiPERRoamOffloadScanInfo; + pWdaParams->pWdaContext = pWDA; + + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pPERRoamOffloadScanReqParams; + status = WDI_PERRoamScanOffloadReq(pwdiPERRoamOffloadScanInfo, + (WDI_PERRoamOffloadScanCb)WDA_PERRoamOffloadScanReqCallback, + pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Send config PER roam params"); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif + +/* + * FUNCTION: WDA_ProcessRoamScanOffloadReq + * Request to WDI to set Roam Offload Scan + */ +VOS_STATUS WDA_ProcessRoamScanOffloadReq(tWDA_CbContext *pWDA, + tSirRoamOffloadScanReq *pRoamOffloadScanReqParams) +{ + WDI_Status status; + WDI_RoamScanOffloadReqParamsType *pwdiRoamScanOffloadReqParams = + (WDI_RoamScanOffloadReqParamsType *)vos_mem_malloc(sizeof(WDI_RoamScanOffloadReqParamsType)); + tWDA_ReqParams *pWdaParams ; + v_U8_t csrAuthType; + WDI_RoamNetworkType *pwdiRoamNetworkType; + WDI_RoamOffloadScanInfo *pwdiRoamOffloadScanInfo; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if (NULL == pwdiRoamScanOffloadReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiRoamScanOffloadReqParams); + return VOS_STATUS_E_NOMEM; + } + + pwdiRoamNetworkType = + &pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork; + pwdiRoamOffloadScanInfo = + &pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo; + vos_mem_zero (pwdiRoamScanOffloadReqParams,sizeof(WDI_RoamScanOffloadReqParamsType)); + csrAuthType = pRoamOffloadScanReqParams->ConnectedNetwork.authentication; + pwdiRoamOffloadScanInfo->RoamScanOffloadEnabled = + pRoamOffloadScanReqParams->RoamScanOffloadEnabled; + vos_mem_copy(pwdiRoamNetworkType->currAPbssid, + pRoamOffloadScanReqParams->ConnectedNetwork.currAPbssid, + sizeof(pwdiRoamNetworkType->currAPbssid)); + WDA_ConvertSirAuthToWDIAuth(&pwdiRoamNetworkType->authentication, + csrAuthType); + WDA_ConvertSirEncToWDIEnc(&pwdiRoamNetworkType->encryption, + pRoamOffloadScanReqParams->ConnectedNetwork.encryption); + WDA_ConvertSirEncToWDIEnc(&pwdiRoamNetworkType->mcencryption, + pRoamOffloadScanReqParams->ConnectedNetwork.mcencryption); + pwdiRoamOffloadScanInfo->LookupThreshold = + pRoamOffloadScanReqParams->LookupThreshold ; + pwdiRoamOffloadScanInfo->RxSensitivityThreshold = + pRoamOffloadScanReqParams->RxSensitivityThreshold; + pwdiRoamOffloadScanInfo->RoamRssiDiff = + pRoamOffloadScanReqParams->RoamRssiDiff ; + pwdiRoamOffloadScanInfo->MAWCEnabled = + pRoamOffloadScanReqParams->MAWCEnabled ; + pwdiRoamOffloadScanInfo->Command = + pRoamOffloadScanReqParams->Command ; + pwdiRoamOffloadScanInfo->StartScanReason = + pRoamOffloadScanReqParams->StartScanReason ; + pwdiRoamOffloadScanInfo->NeighborScanTimerPeriod = + pRoamOffloadScanReqParams->NeighborScanTimerPeriod ; + pwdiRoamOffloadScanInfo->NeighborRoamScanRefreshPeriod = + pRoamOffloadScanReqParams->NeighborRoamScanRefreshPeriod ; + pwdiRoamOffloadScanInfo->NeighborScanChannelMinTime = + pRoamOffloadScanReqParams->NeighborScanChannelMinTime ; + pwdiRoamOffloadScanInfo->NeighborScanChannelMaxTime = + pRoamOffloadScanReqParams->NeighborScanChannelMaxTime ; + pwdiRoamOffloadScanInfo->EmptyRefreshScanPeriod = + pRoamOffloadScanReqParams->EmptyRefreshScanPeriod ; + pwdiRoamOffloadScanInfo->IsESEEnabled = + pRoamOffloadScanReqParams->IsESEEnabled ; + vos_mem_copy(&pwdiRoamNetworkType->ssId.sSSID, + &pRoamOffloadScanReqParams->ConnectedNetwork.ssId.ssId, + pRoamOffloadScanReqParams->ConnectedNetwork.ssId.length); + pwdiRoamNetworkType->ssId.ucLength = + pRoamOffloadScanReqParams->ConnectedNetwork.ssId.length; + vos_mem_copy(pwdiRoamNetworkType->ChannelCache, + pRoamOffloadScanReqParams->ConnectedNetwork.ChannelCache, + pRoamOffloadScanReqParams->ConnectedNetwork.ChannelCount); + pwdiRoamNetworkType->ChannelCount = + pRoamOffloadScanReqParams->ConnectedNetwork.ChannelCount; + pwdiRoamOffloadScanInfo->ChannelCacheType = + pRoamOffloadScanReqParams->ChannelCacheType; + vos_mem_copy(pwdiRoamOffloadScanInfo->ValidChannelList, + pRoamOffloadScanReqParams->ValidChannelList, + pRoamOffloadScanReqParams->ValidChannelCount); + pwdiRoamOffloadScanInfo->ValidChannelCount = + pRoamOffloadScanReqParams->ValidChannelCount; + pwdiRoamOffloadScanInfo->us24GProbeSize = + (pRoamOffloadScanReqParams->us24GProbeTemplateLenus24GProbeTemplateLen:WDI_PNO_MAX_PROBE_SIZE; + vos_mem_copy(&pwdiRoamOffloadScanInfo->a24GProbeTemplate, + pRoamOffloadScanReqParams->p24GProbeTemplate, + pwdiRoamOffloadScanInfo->us24GProbeSize); + pwdiRoamOffloadScanInfo->us5GProbeSize = + (pRoamOffloadScanReqParams->us5GProbeTemplateLenus5GProbeTemplateLen:WDI_PNO_MAX_PROBE_SIZE; + vos_mem_copy(&pwdiRoamOffloadScanInfo->a5GProbeTemplate, + pRoamOffloadScanReqParams->p5GProbeTemplate, + pwdiRoamOffloadScanInfo->us5GProbeSize); + pwdiRoamOffloadScanInfo->MDID.mdiePresent = + pRoamOffloadScanReqParams->MDID.mdiePresent; + pwdiRoamOffloadScanInfo->MDID.mobilityDomain = + pRoamOffloadScanReqParams->MDID.mobilityDomain; + pwdiRoamOffloadScanInfo->nProbes = + pRoamOffloadScanReqParams->nProbes; + pwdiRoamOffloadScanInfo->HomeAwayTime = + pRoamOffloadScanReqParams->HomeAwayTime; + pwdiRoamOffloadScanInfo->WeakZoneRssiThresholdForRoam = + pRoamOffloadScanReqParams->WeakZoneRssiThresholdForRoam; + pwdiRoamScanOffloadReqParams->wdiReqStatusCB = NULL; + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiRoamScanOffloadReqParams; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pRoamOffloadScanReqParams; + status = WDI_RoamScanOffloadReq(pwdiRoamScanOffloadReqParams, + (WDI_RoamOffloadScanCb)WDA_RoamOffloadScanReqCallback, pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Start Roam Candidate Lookup Req WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + pWdaParams->wdaWdiApiMsgParam = NULL; + pWdaParams->wdaMsgParam = NULL; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif + +/* + * FUNCTION: WDA_RssiFilterRespCallback + * + */ +void WDA_RssiFilterRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + return ; +} +/* + * FUNCTION: WDA_RssiFilterReqCallback + * Free memory. + * Invoked when RSSIFilter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_RssiFilterReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessSetRssiFilterReq + * Request to WDI to set Preferred Network List.Offload + */ +VOS_STATUS WDA_ProcessSetRssiFilterReq(tWDA_CbContext *pWDA, + tSirSetRSSIFilterReq* pRssiFilterParams) +{ + WDI_Status status; + WDI_SetRssiFilterReqParamsType *pwdiSetRssiFilterReqInfo = + (WDI_SetRssiFilterReqParamsType *)vos_mem_malloc(sizeof(WDI_SetRssiFilterReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiSetRssiFilterReqInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiSetRssiFilterReqInfo); + return VOS_STATUS_E_NOMEM; + } + pwdiSetRssiFilterReqInfo->rssiThreshold = pRssiFilterParams->rssiThreshold; + pwdiSetRssiFilterReqInfo->wdiReqStatusCB = WDA_RssiFilterReqCallback; + pwdiSetRssiFilterReqInfo->pUserData = pWdaParams; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiSetRssiFilterReqInfo; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pRssiFilterParams; + status = WDI_SetRssiFilterReq( pwdiSetRssiFilterReqInfo, + (WDI_PNOScanCb)WDA_RssiFilterRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set RSSI Filter REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + pWdaParams->wdaWdiApiMsgParam = NULL; + pWdaParams->wdaMsgParam = NULL; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_ProcessUpdateScanParams + * Request to WDI to update Scan Parameters + */ +VOS_STATUS WDA_ProcessUpdateScanParams(tWDA_CbContext *pWDA, + tSirUpdateScanParams *pUpdateScanParams) +{ + WDI_Status status; + WDI_UpdateScanParamsInfoType *wdiUpdateScanParamsInfoType = + (WDI_UpdateScanParamsInfoType *)vos_mem_malloc( + sizeof(WDI_UpdateScanParamsInfoType)) ; + tWDA_ReqParams *pWdaParams ; + v_U8_t i; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == wdiUpdateScanParamsInfoType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if ( NULL == pWdaParams ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiUpdateScanParamsInfoType); + return VOS_STATUS_E_NOMEM; + } + // + // Fill wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo from pUpdateScanParams + // + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Update Scan Parameters b11dEnabled %d b11dResolved %d " + "ucChannelCount %d usPassiveMinChTime %d usPassiveMaxChTime" + " %d usActiveMinChTime %d usActiveMaxChTime %d sizeof " + "sir struct %zu wdi struct %zu", + pUpdateScanParams->b11dEnabled, + pUpdateScanParams->b11dResolved, + pUpdateScanParams->ucChannelCount, + pUpdateScanParams->usPassiveMinChTime, + pUpdateScanParams->usPassiveMaxChTime, + pUpdateScanParams->usActiveMinChTime, + pUpdateScanParams->usActiveMaxChTime, + sizeof(tSirUpdateScanParams), + sizeof(wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo) ); + + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.b11dEnabled = + pUpdateScanParams->b11dEnabled; + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.b11dResolved = + pUpdateScanParams->b11dResolved; + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.cbState = + pUpdateScanParams->ucCBState; + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.usActiveMaxChTime = + pUpdateScanParams->usActiveMaxChTime; + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.usActiveMinChTime = + pUpdateScanParams->usActiveMinChTime; + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.usPassiveMaxChTime = + pUpdateScanParams->usPassiveMaxChTime; + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.usPassiveMinChTime = + pUpdateScanParams->usPassiveMinChTime; + + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.ucChannelCount = + (pUpdateScanParams->ucChannelCount < WDI_PNO_MAX_NETW_CHANNELS_EX)? + pUpdateScanParams->ucChannelCount:WDI_PNO_MAX_NETW_CHANNELS_EX; + + for ( i = 0; i < + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.ucChannelCount ; + i++) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Update Scan Parameters channel: %d", + pUpdateScanParams->aChannels[i]); + + wdiUpdateScanParamsInfoType->wdiUpdateScanParamsInfo.aChannels[i] = + pUpdateScanParams->aChannels[i]; + } + + wdiUpdateScanParamsInfoType->wdiReqStatusCB = WDA_UpdateScanParamsReqCallback; + wdiUpdateScanParamsInfoType->pUserData = pWdaParams; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = wdiUpdateScanParamsInfoType; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pUpdateScanParams; + + + + status = WDI_UpdateScanParamsReq(wdiUpdateScanParamsInfoType, + (WDI_UpdateScanParamsCb)WDA_UpdateScanParamsRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Update Scan Params EQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/* + * FUNCTION: WDA_RoamOffloadScanReqCallback + * + */ +void WDA_RoamOffloadScanReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + vos_msg_t vosMsg; + wpt_uint8 reason = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if ( pWdaParams != NULL ) + { + if ( pWdaParams->wdaWdiApiMsgParam != NULL ) + { + reason = ((WDI_RoamScanOffloadReqParamsType *)pWdaParams->wdaWdiApiMsgParam)->wdiRoamOffloadScanInfo.StartScanReason; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if ( pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + + vos_mem_free(pWdaParams) ; + } + vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP; + vosMsg.bodyptr = NULL; + if (WDI_STATUS_SUCCESS != status) + { + reason = 0; + } + vosMsg.bodyval = reason; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Failed to post the rsp to UMAC", __func__); + } + + return ; +} + +void WDA_PERRoamTriggerScanReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + vos_msg_t vosMsg; + wpt_uint8 reason = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if ( pWdaParams->wdaMsgParam != NULL) + vos_mem_free(pWdaParams->wdaMsgParam); + + vos_mem_free(pWdaParams) ; + vosMsg.type = eWNI_SME_ROAM_SCAN_TRIGGER_RSP; + vosMsg.bodyptr = NULL; + if (WDI_STATUS_SUCCESS != status) + reason = 0; + + vosMsg.bodyval = reason; + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) { + /* free the mem and return */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Failed to post the rsp to UMAC", __func__); + } + + return ; +} + + +void WDA_PERRoamOffloadScanReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + vos_msg_t vosMsg; + wpt_uint8 reason = 0; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if ( pWdaParams->wdaMsgParam != NULL) + vos_mem_free(pWdaParams->wdaMsgParam); + + vos_mem_free(pWdaParams) ; + vosMsg.type = eWNI_SME_ROAM_SCAN_OFFLOAD_RSP; + vosMsg.bodyptr = NULL; + if (WDI_STATUS_SUCCESS != status) + reason = 0; + + vosMsg.bodyval = reason; + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) { + /* free the mem and return */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: Failed to post the rsp to UMAC", __func__); + } + + return ; +} +#endif + +/* + * FUNCTION: WDA_SetPowerParamsRespCallback + * + */ +void WDA_SetPowerParamsRespCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; +} +/* + * FUNCTION: WDA_SetPowerParamsReqCallback + * Free memory. + * Invoked when SetPowerParams REQ failed in WDI and no RSP callback is generated. + */ +void WDA_SetPowerParamsReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/* + * FUNCTION: WDA_8023MulticastListRespCallback + * + */ +void WDA_8023MulticastListRespCallback( + WDI_RcvFltPktSetMcListRspParamsType *pwdiRcvFltPktSetMcListRspInfo, + void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_8023MulticastListRespCallback invoked " ); + return ; +} +/* + * FUNCTION: WDA_8023MulticastListReqCallback + * Free memory. + * Invoked when 8023MulticastList REQ failed in WDI and no RSP callback is generated. + */ +void WDA_8023MulticastListReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_Process8023MulticastListReq + * Request to WDI to add 8023 Multicast List + */ +VOS_STATUS WDA_Process8023MulticastListReq (tWDA_CbContext *pWDA, + tSirRcvFltMcAddrList *pRcvFltMcAddrList) +{ + WDI_Status status; + WDI_RcvFltPktSetMcListReqParamsType *pwdiFltPktSetMcListReqParamsType = NULL; + tWDA_ReqParams *pWdaParams ; + tANI_U8 i; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + pwdiFltPktSetMcListReqParamsType = + (WDI_RcvFltPktSetMcListReqParamsType *)vos_mem_malloc( + sizeof(WDI_RcvFltPktSetMcListReqParamsType) + ) ; + if(NULL == pwdiFltPktSetMcListReqParamsType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + vos_mem_free(pwdiFltPktSetMcListReqParamsType); + return VOS_STATUS_E_NOMEM; + } + + // + // Fill pwdiFltPktSetMcListReqParamsType from pRcvFltMcAddrList + // + pwdiFltPktSetMcListReqParamsType->mcAddrList.ulMulticastAddrCnt = + pRcvFltMcAddrList->ulMulticastAddrCnt; + + vos_mem_copy(pwdiFltPktSetMcListReqParamsType->mcAddrList.selfMacAddr, + pRcvFltMcAddrList->selfMacAddr, sizeof(tSirMacAddr)); + vos_mem_copy(pwdiFltPktSetMcListReqParamsType->mcAddrList.bssId, + pRcvFltMcAddrList->bssId, sizeof(tSirMacAddr)); + + for( i = 0; i < pRcvFltMcAddrList->ulMulticastAddrCnt; i++ ) + { + vos_mem_copy(&(pwdiFltPktSetMcListReqParamsType->mcAddrList.multicastAddr[i]), + &(pRcvFltMcAddrList->multicastAddr[i]), + sizeof(tSirMacAddr)); + } + pwdiFltPktSetMcListReqParamsType->wdiReqStatusCB = WDA_8023MulticastListReqCallback; + pwdiFltPktSetMcListReqParamsType->pUserData = pWdaParams; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiFltPktSetMcListReqParamsType; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pRcvFltMcAddrList; + status = WDI_8023MulticastListReq( + pwdiFltPktSetMcListReqParamsType, + (WDI_8023MulticastListCb)WDA_8023MulticastListRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDA_Process8023MulticastListReq(), free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_ReceiveFilterSetFilterRespCallback + * + */ +void WDA_ReceiveFilterSetFilterRespCallback( + WDI_SetRcvPktFilterRspParamsType *pwdiSetRcvPktFilterRspInfo, + void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + /*WDA_VOS_ASSERT(NULL != pWdaParams);*/ + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_ReceiveFilterSetFilterRespCallback invoked " ); + return ; +} + +/* + * FUNCTION: WDA_ReceiveFilterSetFilterReqCallback + * Free memory. + * Invoked when ReceiveFilterSetFilter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_ReceiveFilterSetFilterReqCallback(WDI_Status wdiStatus, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", + __func__, wdiStatus); + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + if (IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} + +/* + * FUNCTION: WDA_ProcessReceiveFilterSetFilterReq + * Request to WDI to set Receive Filters + */ +VOS_STATUS WDA_ProcessReceiveFilterSetFilterReq (tWDA_CbContext *pWDA, + tSirRcvPktFilterCfgType *pRcvPktFilterCfg) +{ + WDI_Status status; + v_SIZE_t allocSize = sizeof(WDI_SetRcvPktFilterReqParamsType) + + ((pRcvPktFilterCfg->numFieldParams - 1) * sizeof(tSirRcvPktFilterFieldParams)); + WDI_SetRcvPktFilterReqParamsType *pwdiSetRcvPktFilterReqParamsType = + (WDI_SetRcvPktFilterReqParamsType *)vos_mem_malloc(allocSize) ; + tWDA_ReqParams *pWdaParams ; + tANI_U8 i; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiSetRcvPktFilterReqParamsType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiSetRcvPktFilterReqParamsType); + return VOS_STATUS_E_NOMEM; + } + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.filterId = pRcvPktFilterCfg->filterId; + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.filterType = pRcvPktFilterCfg->filterType; + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.numFieldParams = pRcvPktFilterCfg->numFieldParams; + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.coalesceTime = pRcvPktFilterCfg->coalesceTime; + vos_mem_copy(pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.selfMacAddr, + pRcvPktFilterCfg->selfMacAddr, sizeof(wpt_macAddr)); + + vos_mem_copy(pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.bssId, + pRcvPktFilterCfg->bssId, sizeof(wpt_macAddr)); + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "FID %d FT %d NParams %d CT %d", + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.filterId, + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.filterType, + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.numFieldParams, + pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.coalesceTime); + for ( i = 0; i < pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.numFieldParams; i++ ) + { + wpalMemoryCopy(&pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.paramsData[i], + &pRcvPktFilterCfg->paramsData[i], + sizeof(pwdiSetRcvPktFilterReqParamsType->wdiPktFilterCfg.paramsData[i])); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Proto %d Comp Flag %d", + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].protocolLayer, + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].cmpFlag); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Data Offset %d Data Len %d", + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataOffset, + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataLength); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "CData: %d:%d:%d:%d:%d:%d", + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].compareData[0], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].compareData[1], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].compareData[2], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].compareData[3], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].compareData[4], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].compareData[5]); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "MData: %d:%d:%d:%d:%d:%d", + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataMask[0], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataMask[1], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataMask[2], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataMask[3], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataMask[4], + pwdiSetRcvPktFilterReqParamsType-> + wdiPktFilterCfg.paramsData[i].dataMask[5]); + } + pwdiSetRcvPktFilterReqParamsType->wdiReqStatusCB = WDA_ReceiveFilterSetFilterReqCallback; + pwdiSetRcvPktFilterReqParamsType->pUserData = pWdaParams; + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiSetRcvPktFilterReqParamsType; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pRcvPktFilterCfg; + status = WDI_ReceiveFilterSetFilterReq(pwdiSetRcvPktFilterReqParamsType, + (WDI_ReceiveFilterSetFilterCb)WDA_ReceiveFilterSetFilterRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in SetFilter(),free all the memory,status %d ",status); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_FilterMatchCountRespCallback + * + */ +void WDA_FilterMatchCountRespCallback( + WDI_RcvFltPktMatchCntRspParamsType *pwdiRcvFltPktMatchRspParams, + void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA; + tpSirRcvFltPktMatchRsp pRcvFltPktMatchCntReq; + tpSirRcvFltPktMatchRsp pRcvFltPktMatchCntRsp = + vos_mem_malloc(sizeof(tSirRcvFltPktMatchRsp)); + tANI_U8 i; + vos_msg_t vosMsg; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + /*WDA_VOS_ASSERT(NULL != pWdaParams);*/ + + if(NULL == pRcvFltPktMatchCntRsp) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pRcvFltPktMatchCntRsp is NULL", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pWdaParams); + return ; + } + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + vos_mem_free(pRcvFltPktMatchCntRsp); + return ; + } + pWDA = (tWDA_CbContext *)pWdaParams->pWdaContext ; + pRcvFltPktMatchCntReq = (tpSirRcvFltPktMatchRsp)pWdaParams->wdaMsgParam; + // Fill pRcvFltPktMatchCntRsp from pRcvFltPktMatchCntReq + vos_mem_zero(pRcvFltPktMatchCntRsp,sizeof(tSirRcvFltPktMatchRsp)); + + /* Message Header */ + pRcvFltPktMatchCntRsp->mesgType = eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP; + pRcvFltPktMatchCntRsp->mesgLen = sizeof(tSirRcvFltPktMatchRsp); + + pRcvFltPktMatchCntRsp->status = pwdiRcvFltPktMatchRspParams->wdiStatus; + + for (i = 0; i < SIR_MAX_NUM_FILTERS; i++) + { + pRcvFltPktMatchCntRsp->filterMatchCnt[i].filterId = pRcvFltPktMatchCntReq->filterMatchCnt[i].filterId; + pRcvFltPktMatchCntRsp->filterMatchCnt[i].matchCnt = pRcvFltPktMatchCntReq->filterMatchCnt[i].matchCnt; + } + /* VOS message wrapper */ + vosMsg.type = eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP; + vosMsg.bodyptr = (void *)pRcvFltPktMatchCntRsp; + vosMsg.bodyval = 0; + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem and return */ + vos_mem_free((v_VOID_t *)pRcvFltPktMatchCntRsp); + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + + return; +} +/* + * FUNCTION: WDA_FilterMatchCountReqCallback + * Free memory and send RSP back to SME. + * Invoked when FilterMatchCount REQ failed in WDI and no RSP callback is generated. + */ +void WDA_FilterMatchCountReqCallback(WDI_Status wdiStatus, void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + vos_msg_t vosMsg; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + /* VOS message wrapper */ + vosMsg.type = eWNI_PMC_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP; + vosMsg.bodyptr = NULL; + vosMsg.bodyval = 0; + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg); + } + + return; +} +/* + * FUNCTION: WDA_ProcessPacketFilterMatchCountReq + * Request to WDI to get PC Filter Match Count + */ +VOS_STATUS WDA_ProcessPacketFilterMatchCountReq (tWDA_CbContext *pWDA, tpSirRcvFltPktMatchRsp pRcvFltPktMatchRsp) +{ + WDI_Status status; + WDI_RcvFltPktMatchCntReqParamsType *pwdiRcvFltPktMatchCntReqParamsType = + (WDI_RcvFltPktMatchCntReqParamsType *)vos_mem_malloc(sizeof(WDI_RcvFltPktMatchCntReqParamsType)); + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiRcvFltPktMatchCntReqParamsType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiRcvFltPktMatchCntReqParamsType); + return VOS_STATUS_E_NOMEM; + } + + pwdiRcvFltPktMatchCntReqParamsType->wdiReqStatusCB = WDA_FilterMatchCountReqCallback; + pwdiRcvFltPktMatchCntReqParamsType->pUserData = pWdaParams; + + vos_mem_copy( pwdiRcvFltPktMatchCntReqParamsType->bssId, + pRcvFltPktMatchRsp->bssId, + sizeof(wpt_macAddr)); + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiRcvFltPktMatchCntReqParamsType; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pRcvFltPktMatchRsp; + status = WDI_FilterMatchCountReq(pwdiRcvFltPktMatchCntReqParamsType, + (WDI_FilterMatchCountCb)WDA_FilterMatchCountRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + /* failure returned by WDI API */ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDI_FilterMatchCountReq(), free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + pRcvFltPktMatchRsp->status = eSIR_FAILURE ; + WDA_SendMsg(pWDA, WDA_PACKET_COALESCING_FILTER_MATCH_COUNT_RSP, (void *)pRcvFltPktMatchRsp, 0) ; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +/* + * FUNCTION: WDA_ReceiveFilterClearFilterRespCallback + * + */ +void WDA_ReceiveFilterClearFilterRespCallback( + WDI_RcvFltPktClearRspParamsType *pwdiRcvFltPktClearRspParamsType, + void * pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirRcvFltPktClearParam *pktClearParam; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); +/* WDA_VOS_ASSERT(NULL != pWdaParams); */ + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + pktClearParam = (tSirRcvFltPktClearParam *)pWdaParams->wdaMsgParam; + if(pktClearParam->pktFilterCallback) + { + pktClearParam->pktFilterCallback( + pktClearParam->cbCtx, + CONVERT_WDI2SIR_STATUS(pwdiRcvFltPktClearRspParamsType->wdiStatus)); + } + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + //print a msg, nothing else to do + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "WDA_ReceiveFilterClearFilterRespCallback invoked " ); + return ; +} +/* + * FUNCTION: WDA_ReceiveFilterClearFilterReqCallback + * Free memory. + * Invoked when ReceiveFilterClearFilter REQ failed in WDI and no RSP callback is generated. + */ +void WDA_ReceiveFilterClearFilterReqCallback(WDI_Status wdiStatus, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirRcvFltPktClearParam *pktClearParam; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s, wdiStatus: %d", __func__, wdiStatus); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid pWdaParams pointer", __func__); + VOS_ASSERT(0); + return; + } + + if(IS_WDI_STATUS_FAILURE(wdiStatus)) + { + pktClearParam = (tSirRcvFltPktClearParam *)pWdaParams->wdaMsgParam; + if(pktClearParam->pktFilterCallback) + { + pktClearParam->pktFilterCallback( + pktClearParam->cbCtx, + CONVERT_WDI2SIR_STATUS(wdiStatus)); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return; +} +/* + * FUNCTION: WDA_ProcessReceiveFilterClearFilterReq + * Request to WDI to clear Receive Filters + */ +VOS_STATUS WDA_ProcessReceiveFilterClearFilterReq (tWDA_CbContext *pWDA, + tSirRcvFltPktClearParam *pRcvFltPktClearParam) +{ + WDI_Status status; + WDI_RcvFltPktClearReqParamsType *pwdiRcvFltPktClearReqParamsType = + (WDI_RcvFltPktClearReqParamsType *)vos_mem_malloc(sizeof(WDI_RcvFltPktClearReqParamsType)); + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiRcvFltPktClearReqParamsType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiRcvFltPktClearReqParamsType); + return VOS_STATUS_E_NOMEM; + } + pwdiRcvFltPktClearReqParamsType->filterClearParam.status = pRcvFltPktClearParam->status; + pwdiRcvFltPktClearReqParamsType->filterClearParam.filterId = pRcvFltPktClearParam->filterId; + vos_mem_copy(pwdiRcvFltPktClearReqParamsType->filterClearParam.selfMacAddr, + pRcvFltPktClearParam->selfMacAddr, sizeof(wpt_macAddr)); + vos_mem_copy(pwdiRcvFltPktClearReqParamsType->filterClearParam.bssId, + pRcvFltPktClearParam->bssId, sizeof(wpt_macAddr)); + + pwdiRcvFltPktClearReqParamsType->wdiReqStatusCB = WDA_ReceiveFilterClearFilterReqCallback; + pwdiRcvFltPktClearReqParamsType->pUserData = pWdaParams; + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiRcvFltPktClearReqParamsType; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pRcvFltPktClearParam; + status = WDI_ReceiveFilterClearFilterReq(pwdiRcvFltPktClearReqParamsType, + (WDI_ReceiveFilterClearFilterCb)WDA_ReceiveFilterClearFilterRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in WDA_ProcessReceiveFilterClearFilterReq(), free all the memory " ); + if(pRcvFltPktClearParam->pktFilterCallback) + { + pRcvFltPktClearParam->pktFilterCallback( + pRcvFltPktClearParam->cbCtx, + CONVERT_WDI2SIR_STATUS(status)); + } + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +/* + * FUNCTION: WDA_ProcessSetPowerParamsReq + * Request to WDI to set power params + */ +VOS_STATUS WDA_ProcessSetPowerParamsReq(tWDA_CbContext *pWDA, + tSirSetPowerParamsReq *pPowerParams) +{ + WDI_Status status; + WDI_SetPowerParamsReqParamsType *pwdiSetPowerParamsReqInfo = + (WDI_SetPowerParamsReqParamsType *)vos_mem_malloc(sizeof(WDI_SetPowerParamsReqParamsType)) ; + tWDA_ReqParams *pWdaParams ; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if(NULL == pwdiSetPowerParamsReqInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiSetPowerParamsReqInfo); + return VOS_STATUS_E_NOMEM; + } + + + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uIgnoreDTIM = + pPowerParams->uIgnoreDTIM; + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uDTIMPeriod = + pPowerParams->uDTIMPeriod; + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uListenInterval = + pPowerParams->uListenInterval; + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uBcastMcastFilter = + pPowerParams->uBcastMcastFilter; + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uEnableBET = + pPowerParams->uEnableBET; + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uBETInterval = + pPowerParams->uBETInterval; + pwdiSetPowerParamsReqInfo->wdiSetPowerParamsInfo.uMaxLIModulatedDTIM = + pPowerParams->uMaxLIModulatedDTIM; + pwdiSetPowerParamsReqInfo->wdiReqStatusCB = WDA_SetPowerParamsReqCallback; + pwdiSetPowerParamsReqInfo->pUserData = pWdaParams; + + /* Store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiSetPowerParamsReqInfo; + pWdaParams->pWdaContext = pWDA; + /* Store param pointer as passed in by caller */ + pWdaParams->wdaMsgParam = pPowerParams; + status = WDI_SetPowerParamsReq( pwdiSetPowerParamsReqInfo, + (WDI_SetPowerParamsCb)WDA_SetPowerParamsRespCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in Set power params REQ WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + pWdaParams->wdaWdiApiMsgParam = NULL; + pWdaParams->wdaMsgParam = NULL; + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_SetTmLevelRspCallback + * Set TM Level response + */ +void WDA_SetTmLevelRspCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + /* Dose not need to send notification to upper layer + * Just free allocated resources */ + if( pWdaParams != NULL ) + { + if( pWdaParams->wdaWdiApiMsgParam != NULL ) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams) ; + } +} + +/* + * FUNCTION: WDA_ProcessSetTmLevelReq + * Set TM Level request + */ +VOS_STATUS WDA_ProcessSetTmLevelReq(tWDA_CbContext *pWDA, + tAniSetTmLevelReq *setTmLevelReq) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + tWDA_ReqParams *pWdaParams ; + WDI_SetTmLevelReqType *wdiSetTmLevelReq = + (WDI_SetTmLevelReqType *)vos_mem_malloc( + sizeof(WDI_SetTmLevelReqType)) ; + if(NULL == wdiSetTmLevelReq) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiSetTmLevelReq); + return VOS_STATUS_E_NOMEM; + } + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + wdiSetTmLevelReq->tmMode = setTmLevelReq->tmMode; + wdiSetTmLevelReq->tmLevel = setTmLevelReq->newTmLevel; + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = setTmLevelReq; + pWdaParams->wdaWdiApiMsgParam = wdiSetTmLevelReq; + + status = WDI_SetTmLevelReq(wdiSetTmLevelReq, + (WDI_SetTmLevelCb)WDA_SetTmLevelRspCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure setting thermal mitigation level, freeing memory" ); + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + } + + return CONVERT_WDI2VOS_STATUS(status) ; +} + +VOS_STATUS WDA_ProcessTxControlInd(tWDA_CbContext *pWDA, + tpTxControlParams pTxCtrlParam) +{ + VOS_STATUS wdaStatus; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + if( pTxCtrlParam == NULL ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Input tpTxControlParams is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + if( pTxCtrlParam->stopTx == eANI_BOOLEAN_TRUE ) + { + wdaStatus = WDA_SuspendDataTx(pWDA); + } + else /* pTxCtrlParam->stopTx == eANI_BOOLEAN_FALSE */ + { + wdaStatus = WDA_ResumeDataTx(pWDA); + } + return wdaStatus; +} + +void WDA_FWLoggingDXEdoneInd(v_U32_t logType) +{ + WDI_Status status; + status = WDI_FWLoggingDXEdoneInd(logType); + + if (!(WDI_STATUS_SUCCESS_SYNC == status || WDI_STATUS_PENDING == status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure status %d"), status); + } +} + + /* FUNCTION WDA_featureCapsExchange + * WDA API to invoke capability exchange between host and FW. + */ +void WDA_featureCapsExchange(v_PVOID_t pVosContext) +{ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:enter", __func__ ); + WDI_featureCapsExchangeReq( NULL, pVosContext); +} + +/* FUNCTION WDA_disableCapablityFeature + * WDA API to diable Active mode offload in host. + */ +void WDA_disableCapablityFeature(tANI_U8 feature_index) +{ + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:enter", __func__ ); + WDI_disableCapablityFeature(feature_index); +} + + /* FUNCTION WDA_getHostWlanFeatCaps + * Wrapper for WDI API, that will return if the feature (enum value).passed + * to this API is supported or not in Host + * return value + * 0 - implies feature is NOT Supported + * any non zero value - implies feature is SUPPORTED + */ +tANI_U8 WDA_getHostWlanFeatCaps(tANI_U8 featEnumValue) +{ + return WDI_getHostWlanFeatCaps(featEnumValue); +} + + /* FUNCTION WDA_getFwWlanFeatCaps + * Wrapper for WDI API, that will return if the feature (enum value).passed + * to this API is supported or not in FW + * return value + * 0 - implies feature is NOT Supported + * any non zero value - implies feature is SUPPORTED + */ +tANI_U8 WDA_getFwWlanFeatCaps(tANI_U8 featEnumValue) +{ + return WDI_getFwWlanFeatCaps(featEnumValue); +} + + +/* + * FUNCTION: WDA_shutdown + * Shutdown WDA/WDI without handshaking with Riva. + * Synchronous function. + */ +VOS_STATUS WDA_shutdown(v_PVOID_t pVosContext, wpt_boolean closeTransport) +{ + WDI_Status wdiStatus; + //tANI_U8 eventIdx = 0; + VOS_STATUS status = VOS_STATUS_SUCCESS; + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Invoked with invalid pWDA", __func__ ); + VOS_ASSERT(0); + return VOS_STATUS_E_FAILURE; + } + /* FTM mode stay START_STATE */ + if( (WDA_READY_STATE != pWDA->wdaState) && + (WDA_INIT_STATE != pWDA->wdaState) && + (WDA_START_STATE != pWDA->wdaState) ) + { + VOS_ASSERT(0); + } + + if (eDRIVER_TYPE_MFG != pWDA->driverMode) + { + if(VOS_TRUE == pWDA->wdaTimersCreated) + { + wdaDestroyTimers(pWDA); + pWDA->wdaTimersCreated = VOS_FALSE; + } + } + else + { + vos_event_destroy(&pWDA->ftmStopDoneEvent); + } + + /* call WDI shutdown */ + wdiStatus = WDI_Shutdown(closeTransport); + if (IS_WDI_STATUS_FAILURE(wdiStatus) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "error in WDA Stop" ); + status = VOS_STATUS_E_FAILURE; + } + /* WDI stop is synchrnous, shutdown is complete when it returns */ + pWDA->wdaState = WDA_STOP_STATE; + + /* shutdown should perform the stop & close actions. */ + /* Destroy the event */ + status = vos_event_destroy(&pWDA->txFrameEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + status = vos_event_destroy(&pWDA->suspendDataTxEvent); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + status = vos_event_destroy(&pWDA->waitOnWdiIndicationCallBack); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "VOS Event destroy failed - status = %d", status); + status = VOS_STATUS_E_FAILURE; + } + /* free WDA context */ + status = vos_free_context(pVosContext,VOS_MODULE_ID_WDA,pWDA); + if ( !VOS_IS_STATUS_SUCCESS(status) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "error in WDA close " ); + status = VOS_STATUS_E_FAILURE; + } + return status; +} + +/* + * FUNCTION: WDA_setNeedShutdown + * WDA stop failed or WDA NVDownload failed + */ + +void WDA_setNeedShutdown(v_PVOID_t pVosContext) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + if(pWDA == NULL) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Could not get the WDA Context pointer" ); + return; + } + pWDA->needShutdown = TRUE; +} +/* + * FUNCTION: WDA_needShutdown + * WDA needs a shutdown + */ + +v_BOOL_t WDA_needShutdown(v_PVOID_t pVosContext) +{ + tWDA_CbContext *pWDA = (tWDA_CbContext *)VOS_GET_WDA_CTXT(pVosContext); + if(pWDA == NULL) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Could not get the WDA Context pointer" ); + return 0; + } + return pWDA->needShutdown; +} + +#ifdef WLAN_FEATURE_11AC +/* + * FUNCTION: WDA_SetBeaconFilterReqCallback + * + */ +void WDA_SetUpdateOpModeReqCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams) ; + /* + * No respone required for SetBeaconFilter req so just free the request + * param here + */ + + return ; +} + +VOS_STATUS WDA_ProcessUpdateOpMode(tWDA_CbContext *pWDA, + tUpdateVHTOpMode *pData) +{ + WDI_Status status = WDI_STATUS_SUCCESS ; + tWDA_ReqParams *pWdaParams ; + WDI_UpdateVHTOpMode *wdiTemp = (WDI_UpdateVHTOpMode *)vos_mem_malloc( + sizeof(WDI_UpdateVHTOpMode)) ; + if(NULL == wdiTemp) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(wdiTemp); + return VOS_STATUS_E_NOMEM; + } + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s Opmode = %d and staid = %d" , + __func__, pData->opMode, pData->staId); + wdiTemp->opMode = pData->opMode; + wdiTemp->staId = pData->staId; + + pWdaParams->pWdaContext = pWDA; + /* Store Req pointer, as this will be used for response */ + pWdaParams->wdaMsgParam = (void *)pData; + /* store Params pass it to WDI */ + pWdaParams->wdaWdiApiMsgParam = (void *)wdiTemp ; + + status = WDI_UpdateVHTOpModeReq( wdiTemp, (WDI_UpdateVHTOpModeCb) WDA_SetUpdateOpModeReqCallback, pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in UPDATE VHT OP_MODE REQ Params WDI API, free all the memory " ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif + +/*========================================================================== + FUNCTION WDA_TransportChannelDebug + + DESCRIPTION + Display Transport Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + PARAMETERS + pMac : upper MAC context pointer + displaySnapshot : Display DXE snapshot option + debugFlags : Enable stall detect features + defined by WPAL_DeviceDebugFlags + These features may effect + data performance. + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_TransportChannelDebug +( + tpAniSirGlobal pMac, + v_BOOL_t displaySnapshot, + v_U8_t debugFlags +) +{ + WDI_TransportChannelDebug(displaySnapshot, debugFlags); + return; +} + +/*========================================================================== + FUNCTION WDA_TransportKickDxe + + DESCRIPTION + Request Kick Dxe when first hdd TX time out + happens + + PARAMETERS + NONE + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_TransportKickDxe() +{ + WDI_TransportKickDxe(); + return; +} + + +/*========================================================================== + FUNCTION WDA_SetEnableSSR + + DESCRIPTION + API to enable/disable SSR on WDI timeout + + PARAMETERS + enableSSR : enable/disable SSR + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_SetEnableSSR(v_BOOL_t enableSSR) +{ + WDI_SetEnableSSR(enableSSR); +} + +/** + * WDA_SetMgmtPktViaWQ5() - Set INI params sendMgmtPktViaWQ5 to WDI. + * @sendMgmtPktViaWQ5: INI params to enable/disable sending mgmt pkt via WQ5. + * + * Return: void + */ +void WDA_SetMgmtPktViaWQ5(v_BOOL_t sendMgmtPktViaWQ5) +{ + WDI_SetMgmtPktViaWQ5(sendMgmtPktViaWQ5); +} + +#ifdef FEATURE_WLAN_LPHB +/* + * FUNCTION: WDA_LPHBconfRspCallback + * + */ +void WDA_LPHBconfRspCallback(WDI_Status status, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + /* Do not need to send notification to upper layer + * Just free allocated resources */ + if (pWdaParams != NULL) + { + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + vos_mem_free(pWdaParams->wdaMsgParam) ; + vos_mem_free(pWdaParams) ; + } + + return; +} + +/* + * FUNCTION: WDA_ProcessLPHBConfReq + * + */ +VOS_STATUS WDA_ProcessLPHBConfReq(tWDA_CbContext *pWDA, + tSirLPHBReq *pData) +{ + WDI_Status wdiStatus; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " , __func__); + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if (NULL == pWdaParams) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pData); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = (void *)pData; + pWdaParams->wdaWdiApiMsgParam = NULL; + + wdiStatus = WDI_LPHBConfReq(pData, pWdaParams, WDA_LPHBconfRspCallback); + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ", __func__, __LINE__); + } + else if (WDI_STATUS_SUCCESS != wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in %s:%d s %d", __func__, __LINE__, wdiStatus); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return CONVERT_WDI2VOS_STATUS(wdiStatus); +} +#endif /* FEATURE_WLAN_LPHB */ + +void WDA_GetBcnMissRateCallback(tANI_U8 status, tANI_U32 bcnMissRate, + void* pUserData) +{ + tSirBcnMissRateInfo *pBcnMissRateInfo = (tSirBcnMissRateInfo *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pBcnMissRateInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if (pBcnMissRateInfo->callback) + { + pBcnMissRateInfo->callback(status, bcnMissRate, + pBcnMissRateInfo->data); + } + vos_mem_free(pUserData); + + return; +} + +v_VOID_t WDA_ProcessGetBcnMissRateReq(tWDA_CbContext *pWDA, + tSirBcnMissRateReq *pData) +{ + WDI_Status wdiStatus; + tSirBcnMissRateInfo *pBcnMissRateInfo; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " , __func__); + + pBcnMissRateInfo = + (tSirBcnMissRateInfo *)vos_mem_malloc(sizeof(tSirBcnMissRateInfo)); + if (NULL == pBcnMissRateInfo) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pData); + return; + } + + pBcnMissRateInfo->callback = (pGetBcnMissRateCB)(pData->callback); + pBcnMissRateInfo->data = pData->data; + + wdiStatus = WDI_GetBcnMissRate(pBcnMissRateInfo, + WDA_GetBcnMissRateCallback, + pData->bssid); + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ", __func__, __LINE__); + } + else if (WDI_STATUS_SUCCESS != wdiStatus) + { + if (pBcnMissRateInfo->callback) + { + pBcnMissRateInfo->callback(VOS_STATUS_E_FAILURE, + -1, pBcnMissRateInfo->data); + } + } + vos_mem_free(pData); +} + +#ifdef WLAN_FEATURE_EXTSCAN + +/*========================================================================== + FUNCTION WDA_EXTScanStartRspCallback + + DESCRIPTION + API to send EXTScan Start Response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: +===========================================================================*/ +void WDA_EXTScanStartRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA received NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if (pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, WDA_EXTSCAN_START_RSP, + pEventData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_EXTScanStopRspCallback + + DESCRIPTION + API to send EXTScan Stop Response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: +===========================================================================*/ +void WDA_EXTScanStopRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA received NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + goto error; + } + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if (pMac->sme.pEXTScanIndCb) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD call back function called", __func__); + pMac->sme.pEXTScanIndCb(pCallbackContext, WDA_EXTSCAN_STOP_RSP, + pEventData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + + return; +} + +/*========================================================================== + FUNCTION WDA_EXTScanGetCachedResultsRspCallback + + DESCRIPTION + API to send EXTScan Get Cached Results Response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: +===========================================================================*/ +void WDA_EXTScanGetCachedResultsRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA received NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if (pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, + WDA_EXTSCAN_GET_CACHED_RESULTS_RSP, + pEventData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_EXTScanGetCapabilitiesRspCallback + + DESCRIPTION + API to send EXTScan Get Capabilities Response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: +===========================================================================*/ +void WDA_EXTScanGetCapabilitiesRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA received NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if (pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, + WDA_EXTSCAN_GET_CAPABILITIES_RSP, + pEventData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_EXTScanSetBSSIDHotlistRspCallback + + DESCRIPTION + API to send EXTScan Set BSSID Hotlist Response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: +===========================================================================*/ +void WDA_EXTScanSetBSSIDHotlistRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA received NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if (pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, + WDA_EXTSCAN_SET_BSSID_HOTLIST_RSP, + pEventData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_EXTScanResetBSSIDHotlistRspCallback + + DESCRIPTION + API to send EXTScan ReSet BSSID Hotlist Response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: +===========================================================================*/ +void WDA_EXTScanResetBSSIDHotlistRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + void *pCallbackContext; + tpAniSirGlobal pMac; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWDA received NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:pMac is NULL", __func__); + VOS_ASSERT(0); + goto error; + } + + pCallbackContext = pMac->sme.pEXTScanCallbackContext; + + if (pMac->sme.pEXTScanIndCb) + { + pMac->sme.pEXTScanIndCb(pCallbackContext, + WDA_EXTSCAN_RESET_BSSID_HOTLIST_RSP, + pEventData); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:HDD callback is null", __func__); + VOS_ASSERT(0); + } + + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_ProcessEXTScanStartReq + + DESCRIPTION + API to send EXTScan Start Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEXTScanStartReq(tWDA_CbContext *pWDA, + tSirEXTScanStartReqParams *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EXTScanStartReq((void *)wdaRequest, + (WDI_EXTScanStartRspCb)WDA_EXTScanStartRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_ProcessEXTScanStopReq + + DESCRIPTION + API to send EXTScan Start Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEXTScanStopReq(tWDA_CbContext *pWDA, + tSirEXTScanStopReqParams *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EXTScanStopReq((void *)wdaRequest, + (WDI_EXTScanStopRspCb)WDA_EXTScanStopRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_ProcessEXTScanGetCachedResultsReq + + DESCRIPTION + API to send EXTScan Get Cached Results Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEXTScanGetCachedResultsReq(tWDA_CbContext *pWDA, + tSirEXTScanGetCachedResultsReqParams *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EXTScanGetCachedResultsReq((void *)wdaRequest, + (WDI_EXTScanGetCachedResultsRspCb)WDA_EXTScanGetCachedResultsRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_ProcessEXTScanGetCapabilitiesReq + + DESCRIPTION + API to send EXTScan Get Capabilities Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEXTScanGetCapabilitiesReq(tWDA_CbContext *pWDA, + tSirGetEXTScanCapabilitiesReqParams *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EXTScanGetCapabilitiesReq((void *)wdaRequest, + (WDI_EXTScanGetCapabilitiesRspCb)WDA_EXTScanGetCapabilitiesRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_ProcessEXTScanSetBSSIDHotlistReq + + DESCRIPTION + API to send Set BSSID Hotlist Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEXTScanSetBSSIDHotlistReq(tWDA_CbContext *pWDA, + tSirEXTScanSetBssidHotListReqParams *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EXTScanSetBSSIDHotlistReq((void *)wdaRequest, + (WDI_EXTScanSetBSSIDHotlistRspCb)WDA_EXTScanSetBSSIDHotlistRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_ProcessEXTScanReSetBSSIDHotlistReq + + DESCRIPTION + API to send Reset BSSID Hotlist Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEXTScanResetBSSIDHotlistReq(tWDA_CbContext *pWDA, + tSirEXTScanResetBssidHotlistReqParams *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EXTScanResetBSSIDHotlistReq((void *)wdaRequest, + (WDI_EXTScanResetBSSIDHotlistRspCb)WDA_EXTScanResetBSSIDHotlistRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_ProcessHighPriorityDataInfoInd + + DESCRIPTION + API to send Reset SSID Hotlist Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to EXTScan req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessHighPriorityDataInfoInd(tWDA_CbContext *pWDA, + tSirHighPriorityDataInfoInd *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "%s:", __func__); + + status = WDI_HighPriorityDataInfoInd((void *)wdaRequest); + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received ")); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure status %d"), status); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/*========================================================================== + FUNCTION WDA_LLStatsSetRspCallback + + DESCRIPTION + API to process set link layer statistics response from FW + + PARAMETERS + pRsp: Pointer to set link layer statistics response + pUserData: Pointer to user data + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_LLStatsSetRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + /* Do not need to send notification to upper layer + * Just free allocated resources */ + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_ProcessLLStatsSetReq + + DESCRIPTION + API to send Set Link Layer Stats request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to set Link Layer Stats req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessLLStatsSetReq(tWDA_CbContext *pWDA, + tSirLLStatsSetReq *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_LLStatsSetReq((void *)wdaRequest, + (WDI_LLStatsSetRspCb)WDA_LLStatsSetRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_LLStatsGetRspCallback + + DESCRIPTION + API to process get link layer statistics response from FW + + PARAMETERS + pRsp: Pointer to get link layer statistics response + pUserData: Pointer to user data + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_LLStatsGetRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + /* Do not need to send notification to upper layer + * Just free allocated resources */ + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +/*========================================================================== + FUNCTION WDA_ProcessLLStatsGetReq + + DESCRIPTION + API to send Get Link Layer Stats request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to get Link Layer Stats req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessLLStatsGetReq(tWDA_CbContext *pWDA, + tSirLLStatsGetReq *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_LLStatsGetReq((void *) wdaRequest, + (WDI_LLStatsGetRspCb)WDA_LLStatsGetRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +/*========================================================================== + FUNCTION WDA_LLStatsClearRspCallback + + DESCRIPTION + API to process clear link layer statistics response from FW + + PARAMETERS + pRsp: Pointer to clear link layer statistics response + pUserData: Pointer to user data + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_LLStatsClearRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + /* Do not need to send notification to upper layer + * Just free allocated resources */ + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + return; +} + +/*========================================================================== + FUNCTION WDA_ProcessLLStatsClearReq + + DESCRIPTION + API to send Clear Link Layer Stats request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to earLink Layer Stats req +===========================================================================*/ +VOS_STATUS WDA_ProcessLLStatsClearReq(tWDA_CbContext *pWDA, + tSirLLStatsClearReq *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_LLStatsClearReq((void *) wdaRequest, + (WDI_LLStatsClearRspCb)WDA_LLStatsClearRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +void WDA_FWStatsGetRspCallback(WDI_Status status,void *fwStatsResp,void *pUserData) +{ + tSirFWStatsInfo *fwStatsinfo = (tSirFWStatsInfo *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == fwStatsinfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if(fwStatsinfo->callback) + fwStatsinfo->callback(status, fwStatsResp, fwStatsinfo->data); + + vos_mem_free(pUserData); + return; +} + + +v_VOID_t WDA_ProcessFWStatsGetReq(tWDA_CbContext *pWDA, + tSirFWStatsGetReq *pData) +{ + + WDI_Status wdiStatus; + tSirFWStatsInfo *fwStatsinfo; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s" , __func__); + + fwStatsinfo = + (tSirFWStatsInfo *)vos_mem_malloc(sizeof(tSirFWStatsInfo)); + if (NULL == fwStatsinfo) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pData); + return; + } + + fwStatsinfo->callback = (tSirFWStatsCallback)(pData->callback); + fwStatsinfo->data = pData->data; + + wdiStatus = WDI_FWStatsGetReq(fwStatsinfo, + WDA_FWStatsGetRspCallback, + pData->stats); + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ", __func__, __LINE__); + } + else if (WDI_STATUS_SUCCESS != wdiStatus) + { + if (fwStatsinfo->callback) + { + fwStatsinfo->callback(WDI_STATUS_E_FAILURE, NULL ,fwStatsinfo->data); + } + vos_mem_free(fwStatsinfo); + } + vos_mem_free(pData); +} + +/*========================================================================== + FUNCTION WDA_EncryptMsgRspCallback + + DESCRIPTION + API to send Encrypt message response to HDD + + PARAMETERS + pEventData: Response from FW + pUserData: Data sent to firmware as part of request +===========================================================================*/ +void WDA_EncryptMsgRspCallback(WDI_Status status, void *pEventData, + void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tWDA_CbContext *pWDA = NULL; + tpAniSirGlobal pMac; + vos_msg_t vosMsg; + tpSirEncryptedDataRspParams pEncRspParams; + tpSetEncryptedDataRspParams pEncryptedDataRsp; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("%s:"), __func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s: pWdaParams received NULL"), __func__); + VOS_ASSERT(0); + return; + } + + pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext; + + if (NULL == pWDA) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s: pWDA received NULL"), __func__); + VOS_ASSERT(0); + goto error; + } + + pMac = (tpAniSirGlobal )VOS_GET_MAC_CTXT(pWDA->pVosContext); + if (NULL == pMac) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s:pMac is NULL"), __func__); + VOS_ASSERT(0); + goto error; + } + + pEncryptedDataRsp = (tpSetEncryptedDataRspParams) pEventData; + + pEncRspParams = vos_mem_malloc(sizeof(tSirEncryptedDataRspParams)); + if (NULL == pEncRspParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s: VOS MEM Alloc Failure"), __func__); + VOS_ASSERT(0); + goto error; + } + + /* Message Header */ + pEncRspParams->mesgType = eWNI_SME_ENCRYPT_MSG_RSP; + pEncRspParams->mesgLen = sizeof(tSirEncryptedDataRspParams); + pEncRspParams->encryptedDataRsp.encryptedPayload.length = + pEncryptedDataRsp->encryptedPayload.length; + vos_mem_copy(pEncRspParams->encryptedDataRsp.encryptedPayload.data, + pEncryptedDataRsp->encryptedPayload.data, + pEncryptedDataRsp->encryptedPayload.length); + + /* VOS message wrapper */ + vosMsg.type = eWNI_SME_ENCRYPT_MSG_RSP; + vosMsg.bodyptr = (void *)pEncRspParams; + vosMsg.bodyval = 0; + + if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, (vos_msg_t*)&vosMsg)) + { + /* free the mem */ + vos_mem_free((v_VOID_t *) pEncRspParams); + } + +error: + + if (pWdaParams->wdaWdiApiMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + } + if (pWdaParams->wdaMsgParam != NULL) + { + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} +/*========================================================================== + FUNCTION WDA_ProcessEncryptMsgReq + + DESCRIPTION + API to send Encrypt message Request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to Encrypt_msg req parameters +===========================================================================*/ +VOS_STATUS WDA_ProcessEncryptMsgReq(tWDA_CbContext *pWDA, + u8 *wdaRequest) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("%s: "), __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s: VOS MEM Alloc Failure"), __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_EncryptMsgReq((void *)wdaRequest, + (WDI_EncryptMsgRspCb)WDA_EncryptMsgRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure to request. Free all the memory " )); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} +/*========================================================================== + FUNCTION WDA_ProcessSetRtsCtsHTVhtInd + + DESCRIPTION + API to enable/disable RTS/CTS for different modes. + + PARAMETERS + pWDA: Pointer to WDA context + rtsCtsVal : Bit mask value to enable RTS/CTS for different modes +===========================================================================*/ + +VOS_STATUS +WDA_ProcessSetRtsCtsHTVhtInd(tWDA_CbContext *pWDA, + tANI_U32 rtsCtsVal) +{ + WDI_Status status; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + status = WDI_SetRtsCtsHTVhtInd(rtsCtsVal); + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received ")); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure status %d"), status); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +void WDA_MonModeRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + tSirMonModeReq *pData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + pData = (tSirMonModeReq *)pWdaParams->wdaMsgParam; + if (pData != NULL) { + pData->callback(pData->magic, pData->cmpVar); + vos_mem_free(pWdaParams->wdaMsgParam); + } + vos_mem_free(pWdaParams) ; + + return; +} + +VOS_STATUS WDA_ProcessMonStartReq( tWDA_CbContext *pWDA, void *wdaRequest) +{ + + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + tSirMonModeReq *pMonModeData = (tSirMonModeReq *)wdaRequest; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("%s: "), __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s: VOS MEM Alloc Failure"), __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + status = WDI_MonStartReq(pMonModeData->data, + (WDI_MonModeRspCb)WDA_MonModeRspCallback, + (void *)pWdaParams); + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +VOS_STATUS WDA_ProcessMonStopReq( tWDA_CbContext *pWDA, void* wdaRequest) +{ + + WDI_Status status = WDI_STATUS_SUCCESS; + tWDA_ReqParams *pWdaParams; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("%s: "), __func__); + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)); + if (NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("%s: VOS MEM Alloc Failure"), __func__); + VOS_ASSERT(0); + return VOS_STATUS_E_NOMEM; + } + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = wdaRequest; + pWdaParams->wdaWdiApiMsgParam = NULL; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Processing Mon stop request", __func__); + status = WDI_MonStopReq((WDI_MonModeRspCb)WDA_MonModeRspCallback, + (void *)pWdaParams); + + if (IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure to request. Free all the memory " ); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + return CONVERT_WDI2VOS_STATUS(status); +} + +VOS_STATUS WDA_ProcessEnableDisableCAEventInd(tWDA_CbContext *pWDA, tANI_U8 val) +{ + WDI_Status status; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + status = WDI_EnableDisableCAEventInd(val); + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received ")); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure status %d"), status); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/*========================================================================== + FUNCTION WDA_WifiConfigSetRspCallback + + DESCRIPTION + API to process set WifiConfig response from FW + + PARAMETERS + pRsp: Pointer to set WifiConfig response + pUserData: Pointer to user data + + RETURN VALUE + NONE + +===========================================================================*/ +void WDA_WifiConfigSetRspCallback(void *pEventData, void* pUserData) +{ + tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return ; + } + + if(NULL == pWdaParams->wdaMsgParam) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(pWdaParams); + return ; + } + + vos_mem_free(pWdaParams->wdaWdiApiMsgParam); + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + + return; +} + +/*========================================================================== + FUNCTION WDA_ProcessWifiConfigReq + + DESCRIPTION + API to send Set WifiConfig params request to WDI + + PARAMETERS + pWDA: Pointer to WDA context + wdaRequest: Pointer to set WifiConfig req parameters +===========================================================================*/ + +VOS_STATUS WDA_ProcessWifiConfigReq(tWDA_CbContext *pWDA, + tSetWifiConfigParams *pwdaWificonfig) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_WifiConfigSetReqType *pwdiWifConfigSetReqParams; + tWDA_ReqParams *pWdaParams ; + WDI_Status wstatus; + + /* Sanity Check*/ + if(NULL == pwdaWificonfig) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: tSetWifiConfigParams received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + pwdiWifConfigSetReqParams = (WDI_WifiConfigSetReqType *)vos_mem_malloc( + sizeof(WDI_WifiConfigSetReqType)); + if(NULL == pwdiWifConfigSetReqParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdaWificonfig); + return VOS_STATUS_E_NOMEM; + } + + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pwdiWifConfigSetReqParams); + vos_mem_free(pwdaWificonfig); + return VOS_STATUS_E_NOMEM; + } + pwdiWifConfigSetReqParams->paramType = pwdaWificonfig->paramType; + pwdiWifConfigSetReqParams->paramValue = pwdaWificonfig->paramValue; + vos_mem_copy(pwdiWifConfigSetReqParams->bssId, + &(pwdaWificonfig->bssId), sizeof(tSirMacAddr)); + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = pwdaWificonfig; + pWdaParams->wdaWdiApiMsgParam = (void *)pwdiWifConfigSetReqParams; + + wstatus = WDI_WifiConfigSetReq(pwdiWifConfigSetReqParams, + (WDI_WifiConfigSetRspCb)WDA_WifiConfigSetRspCallback, + pWdaParams); + if(IS_WDI_STATUS_FAILURE(wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in sendind WifiConfigReq, free all the memory" ); + status = CONVERT_WDI2VOS_STATUS(wstatus); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + } + + return status; + +} + +#ifdef FEATURE_OEM_DATA_SUPPORT +/* + * FUNCTION: WDA_ProcessStartOemDataReqIndNew + * Request to WDI. + */ +VOS_STATUS WDA_ProcessStartOemDataReqIndNew(tWDA_CbContext *pWDA, + tOemDataReqNewConfig *pOemDataReqNewConfig) +{ + VOS_STATUS status = VOS_STATUS_SUCCESS; + WDI_Status wstatus; + WDI_OemDataReqNewConfig *wdiOemDataReqNewConfig; + + /* Sanity Check*/ + if(NULL == pOemDataReqNewConfig) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pOemDataReqNewConfig received NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_FAULT; + } + + wdiOemDataReqNewConfig = (WDI_OemDataReqNewConfig *)vos_mem_malloc( + sizeof(WDI_OemDataReqNewConfig)); + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " ,__func__); + + if(NULL == wdiOemDataReqNewConfig) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pOemDataReqNewConfig); + return VOS_STATUS_E_NOMEM; + } + + vos_mem_copy(wdiOemDataReqNewConfig, pOemDataReqNewConfig, + sizeof(WDI_OemDataReqNewConfig)); + + wstatus = WDI_StartOemDataReqIndNew(wdiOemDataReqNewConfig); + + if (WDI_STATUS_PENDING == wstatus) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received ")); + } + else if ((WDI_STATUS_SUCCESS_SYNC != wstatus) && (WDI_STATUS_SUCCESS != wstatus)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure in OemDataReqIndNew WDI API, free all memory %d"), wstatus); + } + + vos_mem_free(wdiOemDataReqNewConfig); + vos_mem_free(pOemDataReqNewConfig); + + return status; +} + +void WDA_GetCurrentAntennaIndexCallback(WDI_Status status, void *params, + void *pUserData) +{ + tSirAntennaDiversitySelectionInfo *pAntennaDivSelInfo = + (tSirAntennaDiversitySelectionInfo *)pUserData; + + tSirAntennaDivSelRsp *resParams = (tSirAntennaDivSelRsp *)params; + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if (NULL == pAntennaDivSelInfo) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + if (NULL == resParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: resParams received NULL", __func__); + VOS_ASSERT(0) ; + return ; + } + + if (pAntennaDivSelInfo->callback) + { + if (WDI_STATUS_SUCCESS == status) + { + pAntennaDivSelInfo->callback(resParams->selectedAntennaId, + pAntennaDivSelInfo->data); + } + else + { + pAntennaDivSelInfo->callback(-1, + pAntennaDivSelInfo->data); + } + } + + vos_mem_free(pUserData); + return; +} + +/* + * FUNCTION: WDA_ProcessAntennaDiversitySelectionReq + * Request to WDI. + */ +v_VOID_t WDA_ProcessAntennaDiversitySelectionReq(tWDA_CbContext *pWDA, + tSirAntennaDiversitySelectionReq *pData) +{ + WDI_Status wdiStatus; + tSirAntennaDiversitySelectionInfo *pAntennaDivSelInfo; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "------> %s " , __func__); + + pAntennaDivSelInfo = (tSirAntennaDiversitySelectionInfo *) + vos_mem_malloc(sizeof(tSirAntennaDiversitySelectionInfo)); + if (NULL == pAntennaDivSelInfo) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pData); + return; + } + + pAntennaDivSelInfo->callback = (tAntennaDivSelCB)(pData->callback); + pAntennaDivSelInfo->data = pData->data; + + wdiStatus = WDI_GetCurrentAntennaIndex(pAntennaDivSelInfo, + WDA_GetCurrentAntennaIndexCallback, pData->reserved); + + if (WDI_STATUS_PENDING == wdiStatus) + { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "Pending received for %s:%d ", __func__, __LINE__); + } + else if (WDI_STATUS_SUCCESS != wdiStatus) + { + if (pAntennaDivSelInfo->callback) + { + pAntennaDivSelInfo->callback(-1, pAntennaDivSelInfo->data); + } + } + + vos_mem_free(pData); + return; +} + +/* + * FUNCTION: WDA_ProcessBcnMissPenaltyCount + * Request to WDI. + */ +VOS_STATUS WDA_ProcessBcnMissPenaltyCount(tWDA_CbContext *pWDA, + tModifyRoamParamsReqParams *params) +{ + WDI_Status status; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("---> %s"), __func__); + + if (NULL == params) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("tModifyRoamParamsReqParams is received NULL")); + return VOS_STATUS_E_NOMEM; + } + + status = WDI_SetBcnMissPenaltyCount((WDI_ModifyRoamParamsReqType *)params); + if (WDI_STATUS_PENDING == status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + FL("pending status received ")); + } + else if (WDI_STATUS_SUCCESS_SYNC != status) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + FL("Failure status %d"), status); + } + vos_mem_free(params); + return CONVERT_WDI2VOS_STATUS(status) ; +} +#endif +/* + * WDA_CapTsfRspCb : handle response for tsf requests + * @wdi_rsp : Response from WDI for tsf requests + * @user_data: pointer to user data + * Returns: None + */ +void WDA_CapTsfRspCb (wdi_cap_tsf_rsp_t *wdi_rsp, void *user_data) +{ + + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + tSirCapTsfParams *cap_tsf_params; + struct stsf *stsf_temp; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if (NULL == wda_params) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if (NULL == wda_params->wdaMsgParam) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return; + } + + stsf_temp = (struct stsf *)vos_mem_malloc(sizeof(*stsf_temp)); + if (NULL == stsf_temp) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate tsf struct", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + return; + } + cap_tsf_params = (tSirCapTsfParams *)wda_params->wdaMsgParam; + stsf_temp->session_id = cap_tsf_params->bss_idx; + stsf_temp->set_tsf_req = true; + stsf_temp->tsf_req_status = wdi_rsp->status; + + if (cap_tsf_params->tsf_rsp_cb_func) { + cap_tsf_params->tsf_rsp_cb_func ( + cap_tsf_params->tsf_rsp_cb_ctx, stsf_temp); + } + else { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: tsf callback is NULL", __func__); + vos_mem_free(stsf_temp); + } + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Capture TSF failed with status=%d", __func__, + status); + VOS_ASSERT(0); + } + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + return; +} + +/* + * WDA_GetTsfRspCb : handle response for get tsf request + * @wdi_rsp : Response from WDI for tsf requests + * @user_data: pointer to user data + * Returns: None + */ +void WDA_GetTsfRspCb (wdi_cap_tsf_rsp_t *wdi_rsp, void *user_data) +{ + + tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data; + tSirCapTsfParams *cap_tsf_params; + struct stsf *stsf_temp; + VOS_STATUS status; + + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + + if (NULL == wda_params) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams received NULL", __func__); + VOS_ASSERT(0); + return; + } + + if (NULL == wda_params->wdaMsgParam) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: pWdaParams->wdaMsgParam is NULL", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params); + return; + } + + stsf_temp = (struct stsf *)vos_mem_malloc(sizeof(*stsf_temp)); + if (NULL == stsf_temp) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Unable to allocate tsf struct", __func__); + VOS_ASSERT(0); + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + return; + } + cap_tsf_params = (tSirCapTsfParams *)wda_params->wdaMsgParam; + stsf_temp->session_id = cap_tsf_params->bss_idx; + /* Indicate to upper layer that this is a get request */ + stsf_temp->set_tsf_req = false; + stsf_temp->tsf_low = wdi_rsp->tsf_lo; + stsf_temp->tsf_high = wdi_rsp->tsf_hi; + stsf_temp->tsf_req_status = wdi_rsp->status; + + if (cap_tsf_params->tsf_rsp_cb_func) { + cap_tsf_params->tsf_rsp_cb_func ( + cap_tsf_params->tsf_rsp_cb_ctx, stsf_temp); + } + else { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: tsf callback is NULL", __func__); + vos_mem_free(stsf_temp); + } + status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status); + if (status) { + VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: Capture TSF failed with status=%d", __func__, + status); + VOS_ASSERT(0); + } + vos_mem_free(wda_params->wdaWdiApiMsgParam); + vos_mem_free(wda_params->wdaMsgParam); + vos_mem_free(wda_params); + return; +} +/* + * FUNCTION: WDA_ProcessCapTsfReq + * Send capture tsf request to FW. + */ +VOS_STATUS WDA_ProcessCapTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + wdi_cap_tsf_params_t *pWDICapTsfReqType; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == params) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: cap tsf params NULL", __func__); + VOS_ASSERT(0) ; + return -EINVAL; + } + + pWDICapTsfReqType = (wdi_cap_tsf_params_t *)vos_mem_malloc( + sizeof(*pWDICapTsfReqType)); + if(NULL == pWDICapTsfReqType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(params); + return VOS_STATUS_E_NOMEM; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(*pWdaParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pWDICapTsfReqType); + vos_mem_free(params); + return VOS_STATUS_E_NOMEM; + } + + pWDICapTsfReqType->bss_idx = params->bss_idx; + pWDICapTsfReqType->capTSFget = CAP_TSF_REQUEST; + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = params; + pWdaParams->wdaWdiApiMsgParam = (void *)pWDICapTsfReqType; + + status = wdi_process_cap_tsf_req(pWDICapTsfReqType, + (wdi_tsf_rsp_cb)WDA_CapTsfRspCb, + pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in sendind WifiConfigReq, free all the memory" ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + vos_mem_free(params); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} + +/* + * FUNCTION: WDA_ProcessGetTsfReq + * Send capture tsf request to FW. + */ +VOS_STATUS WDA_ProcessGetTsfReq(tWDA_CbContext *pWDA, tSirCapTsfParams *params) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + wdi_cap_tsf_params_t *pWDIGetTsfReqType; + tWDA_ReqParams *pWdaParams ; + + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO, + "<------ %s " ,__func__); + if(NULL == params) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: cap tsf params NULL", __func__); + VOS_ASSERT(0) ; + return VOS_STATUS_E_INVAL; + } + + pWDIGetTsfReqType = (wdi_cap_tsf_params_t *)vos_mem_malloc( + sizeof(wdi_cap_tsf_params_t)); + if(NULL == pWDIGetTsfReqType) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(params); + return VOS_STATUS_E_INVAL; + } + pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ; + if(NULL == pWdaParams) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s: VOS MEM Alloc Failure", __func__); + VOS_ASSERT(0); + vos_mem_free(pWDIGetTsfReqType); + vos_mem_free(params); + return VOS_STATUS_E_NOMEM; + } + + pWDIGetTsfReqType->bss_idx = params->bss_idx; + /* Indicate that this is a get request */ + pWDIGetTsfReqType->capTSFget = GET_TSF_REQUEST; + + pWdaParams->pWdaContext = pWDA; + pWdaParams->wdaMsgParam = params; + pWdaParams->wdaWdiApiMsgParam = (void *)pWDIGetTsfReqType; + + status = wdi_process_get_tsf_req(pWDIGetTsfReqType, + (wdi_tsf_rsp_cb)WDA_GetTsfRspCb, + pWdaParams); + + if(IS_WDI_STATUS_FAILURE(status)) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "Failure in sendind WifiConfigReq, free all the memory" ); + vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ; + vos_mem_free(pWdaParams->wdaMsgParam); + vos_mem_free(pWdaParams); + vos_mem_free(params); + } + return CONVERT_WDI2VOS_STATUS(status) ; +} diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.c b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.c new file mode 100644 index 000000000000..5f3cabc5c22c --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + wlan_qct_wda_debug.c + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Adaptation + Layer for debugging APIs. + + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + + +#include "palTypes.h" +#include "wlan_qct_wda_debug.h" + +void wdaLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...) { + va_list marker; + + if(loglevel > pMac->utils.gLogDbgLevel[WDA_DEBUG_LOGIDX]) + return; + + va_start( marker, pString ); /* Initialize variable arguments. */ + + logDebug(pMac, SIR_WDA_MODULE_ID, loglevel, pString, marker); + + va_end( marker ); /* Reset variable arguments. */ +} + diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.h b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.h new file mode 100644 index 000000000000..b0958cdb64c4 --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_debug.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WDA_DEBUG_H__ +#define __WDA_DEBUG_H__ +#if !defined (ANI_OS_TYPE_ANDROID) +#include +#endif +#include + +#include "utilsApi.h" +#include "sirDebug.h" +#include "sirParams.h" +#define WDA_DEBUG_LOGIDX ( LOG_INDEX_FOR_MODULE(SIR_WDA_MODULE_ID) ) + + + +#ifdef WLAN_DEBUG + +#define WDALOGP(x0) x0 +#define WDALOGE(x0) x0 +#define WDALOGW(x0) x0 +#define WDALOG1(x0) x0 + +#ifdef HAL_DEBUG_LOG2 +#define WDALOG2(x0) x0 +#else + #define WDALOG2(x0) +#endif + +#ifdef HAL_DEBUG_LOG3 +#define WDALOG3(x0) x0 +#else + #define WDALOG3(x0) +#endif + +#ifdef HAL_DEBUG_LOG4 +#define WDALOG4(x0) x0 +#else + #define WDALOG4(x0) +#endif + +#define STR(x) x + +#else + +#define WDALOGP(x) x +#define WDALOGE(x) {} +#define WDALOGW(x) {} +#define WDALOG1(x) {} +#define WDALOG2(x) {} +#define WDALOG3(x) {} +#define WDALOG4(x) {} +#define STR(x) "" +#endif + +void wdaLog(tpAniSirGlobal pMac, tANI_U32 loglevel, const char *pString,...); + +#endif // __WDA_DEBUG_H__ + diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_ds.c b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_ds.c new file mode 100644 index 000000000000..b4a9bbba7e3f --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_ds.c @@ -0,0 +1,1282 @@ +/* + * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*=========================================================================== + + + W L A N _ Q C T _ WDA _ DS . C + + OVERVIEW: + + This software unit holds the implementation of WLAN Data Abtraction APIs + for the WLAN Transport Layer. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------- +12/08/2010 seokyoun Created. Move down HAL interfaces from TL to WDA + for UMAC convergence btween Volans/Libra and Prima +=========================================================================== */ + +#include "wlan_qct_wda.h" +#include "wlan_qct_tl.h" +#include "wlan_qct_tli.h" +#include "tlDebug.h" + +#define WDA_DS_DXE_RES_COUNT (WDA_TLI_MIN_RES_DATA + 20) + +/* macro's for acessing TL API/data structures */ +#define WDA_TL_SET_TX_XMIT_PENDING(a) WLANTL_SetTxXmitPending(a) +#define WDA_TL_IS_TX_XMIT_PENDING(a) WLANTL_IsTxXmitPending(a) +#define WDA_TL_CLEAR_TX_XMIT_PENDING(a) WLANTL_ClearTxXmitPending(a) + +#define WDA_HI_FLOW_MASK 0xF0 +#define WDA_LO_FLOW_MASK 0x0F + +static v_VOID_t +WDA_DS_TxCompleteCB +( + v_PVOID_t pvosGCtx, + v_PVOID_t pFrameDataBuff +); + + +#ifdef WLAN_PERF +/*========================================================================== + FUNCTION WDA_TLI_FastHwFwdDataFrame + + DESCRIPTION + For NON integrated SOC, this function is called by TL. + + Fast path function to quickly forward a data frame if HAL determines BD + signature computed here matches the signature inside current VOSS packet. + If there is a match, HAL and TL fills in the swapped packet length into + BD header and DxE header, respectively. Otherwise, packet goes back to + normal (slow) path and a new BD signature would be tagged into BD in this + VOSS packet later by the WLANHAL_FillTxBd() function. + + TODO For integrated SOC, this function does nothing yet. Pima SLM/HAL + should provide the equivelant functionality. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff Ptr to VOSS packet + pMetaInfo For getting frame's TID + pStaInfo For checking STA type + + OUT + pvosStatus returned status + puFastFwdOK Flag to indicate whether frame could be fast forwarded + + RETURN VALUE + No return. + + SIDE EFFECTS + +============================================================================*/ +void WDA_TLI_FastHwFwdDataFrame +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + VOS_STATUS* pvosStatus, + v_U32_t* puFastFwdOK, + WLANTL_MetaInfoType* pMetaInfo, + WLAN_STADescType* pStaInfo +) +{ + /* FIXME WDI/WDA should support this function + once HAL supports it + */ +} +#endif /*WLAN_PERF*/ + +void WDA_DS_RxLogCallback(v_U8_t logType) +{ + vos_msg_t vosMessage; + + vosMessage.bodyval = (v_U32_t)logType; + vosMessage.reserved = 0; + vosMessage.type = WDA_SEND_LOG_DONE_IND; + if (VOS_STATUS_SUCCESS != vos_mq_post_message( VOS_MQ_ID_WDA, &vosMessage )) { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WLAN WDA:Posting DXE logging done indication failed" ); + } + return; +} + +/*========================================================================== + FUNCTION WDA_DS_Register + + DESCRIPTION + Register TL client to WDA. This function registers TL RX/TX functions + to WDI by calling WDI_DS_Register. + + + For NON integrated SOC, this function calls WLANBAL_RegTlCbFunctions + to register TL's RX/TX functions to BAL + + TODO + For Prima, pfnResourceCB gets called in WDTS_OOResourceNotification. + The uCount parameter is AC mask. It should be redefined to use the + same resource callback function. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + pfnTxCompleteCallback TX complete callback upon TX completion + pfnRxPacketCallback RX callback + pfnTxPacketCallback TX callback + pfnResourceCB gets called when updating TX PDU number + uResTheshold minimum TX PDU size for a packet + pCallbackContext WDI calls callback function with it + VOS global context pointer + OUT + uAvailableTxBuf available TX PDU numbder. + BAL returns it for NON integrated SOC + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS WDA_DS_Register +( + v_PVOID_t pvosGCtx, + WDA_DS_TxCompleteCallback pfnTxCompleteCallback, + WDA_DS_RxPacketCallback pfnRxPacketCallback, + WDA_DS_TxPacketCallback pfnTxPacketCallback, + WDA_DS_ResourceCB pfnResourceCB, + v_U32_t uResTheshold, + v_PVOID_t pCallbackContext, + v_U32_t *uAvailableTxBuf +) +{ + tWDA_CbContext *wdaContext = NULL; + WDI_Status wdiStatus; + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "WLAN WDA: WDA_DS_Register" ); + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( ( NULL == pvosGCtx ) || + ( NULL == pfnTxPacketCallback ) || + ( NULL == pfnTxCompleteCallback ) || + ( NULL == pfnRxPacketCallback ) || + ( NULL == pfnResourceCB) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WLAN WDA:Invalid pointers on WDA_DS_Register" ); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Extract WDA context + ------------------------------------------------------------------------*/ + wdaContext = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, pvosGCtx ); + if ( NULL == wdaContext ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WLAN WDA:Invalid wda context pointer " + "from pvosGCtx on WDA_DS_Register" ); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------ + Register with WDI as transport layer client + ------------------------------------------------------------------------*/ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, "WDA: WDA_DS_Register"); + + wdaContext->pfnTxResourceCB = pfnResourceCB; + wdaContext->pfnTxCompleteCallback = pfnTxCompleteCallback; + + wdiStatus = WDI_DS_Register( wdaContext->pWdiContext, + (WDI_DS_TxCompleteCallback)WDA_DS_TxCompleteCB, + (WDI_DS_RxPacketCallback)pfnRxPacketCallback, + WDA_DS_TxFlowControlCallback, + WDA_DS_RxLogCallback, + pvosGCtx ); + + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:TL failed to register with DAL, Err: %d", wdiStatus ); + return VOS_STATUS_E_FAILURE; + } + + /* TODO Out-of-resource condition if PDU size is less than WLANTL_MIN_RES_MF + Put hardcoded value not to put TL into OOR. Revisit it */ + *uAvailableTxBuf = WDA_DS_DXE_RES_COUNT; + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WDA_DS_StartXmit + + DESCRIPTION + Serialize TX transmit reques to TX thread. + + TODO This sends TX transmit request to TL. It should send to WDI for + abstraction. + + For NON integrated SOC, this function calls WLANBAL_StartXmit + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_StartXmit +( + v_PVOID_t pvosGCtx +) +{ + vos_msg_t sMessage; + VOS_STATUS status; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ( NULL == pvosGCtx ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN WDA:Invalid pointers on WDA_DS_StartXmit" ); + return VOS_STATUS_E_FAULT; + } + + if(WDA_TL_IS_TX_XMIT_PENDING( pvosGCtx )) + { + /*Already WDA_DS_TX_START_XMIT msg is pending in TL msg queue */ + return VOS_STATUS_SUCCESS; + } + /* Serialize our event */ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Serializing WDA TX Start Xmit event" ); + + vos_mem_zero( &sMessage, sizeof(vos_msg_t) ); + + sMessage.bodyptr = NULL; + sMessage.type = WDA_DS_TX_START_XMIT; + + WDA_TL_SET_TX_XMIT_PENDING(pvosGCtx); + + status = vos_tx_mq_serialize(VOS_MQ_ID_TL, &sMessage); + + if(status != VOS_STATUS_SUCCESS) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, + "Serializing WDA TX Start Xmit event FAILED" ); + WDA_TL_CLEAR_TX_XMIT_PENDING(pvosGCtx); + } + return status; +} + + +/*========================================================================== + FUNCTION WDA_DS_FinishULA + + DESCRIPTION + Serialize Finish Upper Level Authentication reques to TX thread. + + DEPENDENCIES + + PARAMETERS + + IN + callbackRoutine routine to be called in TX thread + callbackContext user data for the above routine + + RETURN VALUE + please see vos_tx_mq_serialize + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_FinishULA +( + void (*callbackRoutine) (void *callbackContext), + void *callbackContext +) +{ + vos_msg_t sMessage; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /* Serialize our event */ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_HIGH, + "Serializing WDA_DS_FinishULA event" ); + + vos_mem_zero( &sMessage, sizeof(vos_msg_t) ); + sMessage.bodyptr = callbackContext; + sMessage.callback = callbackRoutine; + sMessage.bodyval = 0; + sMessage.type = WDA_DS_FINISH_ULA; + + return vos_tx_mq_serialize(VOS_MQ_ID_TL, &sMessage); +}/*WDA_DS_FinishULA*/ + +/*========================================================================== + FUNCTION WDA_DS_BuildTxPacketInfo + + DESCRIPTION + Build TX meta info for integrated SOC. + + Same function calls HAL for reserve BD header space into VOS packet and + HAL function to fill it. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff vos data buffer + pvDestMacAddr destination MAC address ponter + ucDisableFrmXtl Is frame xtl disabled? + ucQosEnabled Is QoS enabled? + ucWDSEnabled Is WDS enabled? + extraHeadSpace Extra head bytes. If it's not 0 due to 4 bytes align + of BD header. + typeSubtype typeSubtype from MAC header or TX metainfo/BD + pAddr2 address 2 + uTid tid + txFlag + timeStamp + ucIsEapol + ucUP + + OUT + *pusPktLen Packet length + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_BuildTxPacketInfo +( + v_PVOID_t pvosGCtx, + vos_pkt_t* vosDataBuff, + v_MACADDR_t* pvDestMacAddr, + v_U8_t ucDisableFrmXtl, + v_U16_t* pusPktLen, + v_U8_t ucQosEnabled, + v_U8_t ucWDSEnabled, + v_U8_t extraHeadSpace, + v_U8_t typeSubtype, + v_PVOID_t pAddr2, + v_U8_t uTid, + v_U32_t txFlag, + v_U32_t timeStamp, + v_U8_t ucIsEapol, + v_U8_t ucIsArp, + v_U8_t ucUP, + v_U32_t ucTxBdToken +) +{ + VOS_STATUS vosStatus; + WDI_DS_TxMetaInfoType* pTxMetaInfo = NULL; + v_SIZE_t usMacAddrSize; + wpt_FrameCtrl *pFrameControl; +#ifdef WLAN_FEATURE_RMC + WLANTL_CbType* pTLCb; + WLANTL_RMC_SESSION* pRMCSession; +#endif + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + Extract TL control block + ------------------------------------------------------------------------*/ + if ( ( NULL == pvosGCtx ) || ( NULL == vosDataBuff ) || ( NULL == pvDestMacAddr ) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA:Invalid parameter sent on WDA_DS_BuildTxPacketInfo" ); + return VOS_STATUS_E_FAULT; + } + +#ifdef WLAN_FEATURE_RMC +/*---------------------------------------------------------------- + Extract TL control block + --------------------------------------------------------------*/ + pTLCb = VOS_GET_TL_CB(pvosGCtx); + if ( NULL == pTLCb ) + { + TLLOGE(VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL %s: pTLCb is NULL", __func__)); + + return VOS_STATUS_E_FAILURE; + } +#endif + + /*------------------------------------------------------------------------ + Extract TX Meta Info pointer from PAL packet + ------------------------------------------------------------------------*/ + pTxMetaInfo = WDI_DS_ExtractTxMetaData( VOS_TO_WPAL_PKT(vosDataBuff) ); + if ( NULL == pTxMetaInfo ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WLAN TL:Invalid RxMetaInfo pointer from PAL packet on WLANTL_RxFrames"); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAULT; + } + + /* Zero out memeory */ + vos_mem_zero( pTxMetaInfo, sizeof( WDI_DS_TxMetaInfoType ) ); + + /* Fill the TX Meta info */ + pTxMetaInfo->txFlags = txFlag; + pTxMetaInfo->qosEnabled = ucQosEnabled; + pTxMetaInfo->fenableWDS = ucWDSEnabled; + pTxMetaInfo->ac = ucUP; + pTxMetaInfo->fUP = uTid; + pTxMetaInfo->isEapol = ucIsEapol; + pTxMetaInfo->isArp = ucIsArp; + pTxMetaInfo->fdisableFrmXlt = ucDisableFrmXtl; + pTxMetaInfo->frmType = ( ( typeSubtype & 0x30 ) >> 4 ); + pTxMetaInfo->typeSubtype = typeSubtype; + pTxMetaInfo->txBdToken = ucTxBdToken; + /* Length = MAC header + payload */ + vos_pkt_get_packet_length( vosDataBuff, pusPktLen); + pTxMetaInfo->fPktlen = *pusPktLen; + + /* For management frames, peek into Frame Control + field to get value of Protected Frame bit */ + pTxMetaInfo->fProtMgmtFrame = 0; + if ( WDA_TLI_MGMT_FRAME_TYPE == pTxMetaInfo->frmType ) + { + if ( 1 == ucDisableFrmXtl ) /* should be 802.11, but check */ + { + vosStatus = vos_pkt_peek_data( vosDataBuff, 0, (v_PVOID_t)&pFrameControl, + sizeof( wpt_FrameCtrl )); + if ( VOS_STATUS_SUCCESS != vosStatus ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WDA: Failed while attempting to extract Protect Bit in " + "Frame Control, status %d", vosStatus ); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAULT; + } + pTxMetaInfo->fProtMgmtFrame = pFrameControl->wep; + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL: fProtMgmtFrame:%d", pTxMetaInfo->fProtMgmtFrame ); + } + } + + // Dst address + usMacAddrSize = VOS_MAC_ADDR_SIZE; + vosStatus = vos_pkt_extract_data( vosDataBuff, + WLANTL_MAC_ADDR_ALIGN( ucDisableFrmXtl ), + (v_PVOID_t)pvDestMacAddr, + &usMacAddrSize ); + if ((VOS_STATUS_SUCCESS != vosStatus) || + (usMacAddrSize != VOS_MAC_ADDR_SIZE)) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WDA:Failed while attempting to extract MAC Addr %d", + vosStatus ); + VOS_ASSERT( 0 ); + return VOS_STATUS_E_FAULT; + } + + vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->fSTAMACAddress, pvDestMacAddr ); + + // ADDR2 + vos_copy_macaddr( (v_MACADDR_t*)pTxMetaInfo->addr2MACAddress, pAddr2 ); + +#ifdef WLAN_FEATURE_RMC + if (pTLCb->rmcDataPathEnabled) + { + /*look up for mcast transmitter MAC address in TL's active rmc list*/ + if (((WDA_TLI_DATA_FRAME_TYPE >> 4) == pTxMetaInfo->frmType) && + (vos_is_macaddr_group(pvDestMacAddr))) + { + pRMCSession = + WLANTL_RmcLookUpRmcSession(pTLCb->rmcSession, + (v_MACADDR_t*)pTxMetaInfo->addr2MACAddress); + + if (pRMCSession) + { + if (0xFF == pvDestMacAddr->bytes[0]) + { + pTxMetaInfo->txFlags |= (HAL_USE_BD_RATE_1_MASK); + } + else + { + pTxMetaInfo->txFlags |= (HAL_RMC_REQUESTED_MASK); + + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "RMC active for " MAC_ADDRESS_STR " RMC session", + MAC_ADDR_ARRAY(pRMCSession->rmcAddr.bytes)); + } + } + else + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO, + "RMC disabled for " MAC_ADDRESS_STR " RMC session", + MAC_ADDR_ARRAY(pTxMetaInfo->addr2MACAddress)); + } + } + } +#endif /*WLAN_FEATURE_RMC*/ + + /* Dump TX meta infro for debugging */ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_INFO_LOW, + "WLAN TL: Dump TX meta info: " + "txFlags:%d, qosEnabled:%d, ac:%d, " + "isEapol:%d, fdisableFrmXlt:%d, frmType:%d", + pTxMetaInfo->txFlags, ucQosEnabled, pTxMetaInfo->ac, + pTxMetaInfo->isEapol, pTxMetaInfo->fdisableFrmXlt, + pTxMetaInfo->frmType ); + + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION WDS_DS_TrimRxPacketInfo + + DESCRIPTION + Trim/Remove RX BD header for NON integrated SOC. + It does nothing for integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_TrimRxPacketInfo +( + vos_pkt_t *vosDataBuff +) +{ + /* Nothing to trim + * Do Nothing */ + + return VOS_STATUS_SUCCESS; +} + + + +/*========================================================================== + FUNCTION WDA_DS_PeekRxPacketInfo + + DESCRIPTION + Return RX metainfo pointer for for integrated SOC. + + Same function will return BD header pointer. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + pvDestMacAddr destination MAC address ponter + bSwap Want to swap BD header? For backward compatability + It does nothing for integrated SOC + OUT + *ppRxHeader RX metainfo pointer + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_PeekRxPacketInfo +( + vos_pkt_t *vosDataBuff, + v_PVOID_t *ppRxHeader, + v_BOOL_t bSwap +) +{ + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == vosDataBuff ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA:Invalid parameter sent on WDA_DS_PeekRxPacketInfo" ); + return VOS_STATUS_E_FAULT; + } + + *ppRxHeader = WDI_DS_ExtractRxMetaData( (wpt_packet*)vosDataBuff ); + + if ( NULL == *ppRxHeader ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA:Failed to get RX meta data from WDI" ); + return VOS_STATUS_E_FAILURE; + } + + return VOS_STATUS_SUCCESS; +} + + + +/*========================================================================== + FUNCTION WDA_DS_GetFrameTypeSubType + + DESCRIPTION + Get typeSubtype from the packet. The BD header should have this. + But some reason, Libra/Volans read it from 802.11 header and save it + back to BD header. So for NON integrated SOC, this function does + the same. + + For integrated SOC, WDI does the same, not TL. + It does return typeSubtype from RX meta info for integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + vosDataBuff vos data buffer + pRxHeader RX meta info or BD header pointer + + OUT + ucTypeSubtype typeSubtype + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetFrameTypeSubType +( + v_PVOID_t pvosGCtx, + vos_pkt_t *vosDataBuff, + v_PVOID_t pRxHeader, + v_U8_t *ucTypeSubtype +) +{ + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pRxHeader ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA:Invalid parameter sent on WDA_DS_GetFrameTypeSubType" ); + return VOS_STATUS_E_FAULT; + } + + *ucTypeSubtype = ( WDA_GET_RX_TYPE( pRxHeader ) << 4 ) | WDA_GET_RX_SUBTYPE( pRxHeader ); + + return VOS_STATUS_SUCCESS; +} + + +/*========================================================================== + FUNCTION WDA_DS_RxAmsduBdFix + + DESCRIPTION + For backward compatability with Libra/Volans. Need to call HAL function + for HW BD bug fix + + It does nothing for integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + pvBDHeader BD header pointer + + OUT + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_RxAmsduBdFix +( + v_PVOID_t pvosGCtx, + v_PVOID_t pvBDHeader +) +{ + /* Do nothing for Prima */ + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WDA_DS_GetRssi + + DESCRIPTION + Get RSSI + + TODO It returns hardcoded value in the meantime since WDA/WDI does nothing + support it yet for Prima. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + OUT + puRssi RSSI + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetRssi +( + v_PVOID_t pvosGCtx, + v_S7_t* puRssi +) +{ + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WDA:halPS_GetRssi no longer supported. Need replacement"); + + *puRssi = -30; + + return VOS_STATUS_SUCCESS; +} + +/*========================================================================== + FUNCTION WDA_DS_GetTxResources + + DESCRIPTION + It does return hardcoded value. It should bigger number than 0. + Returning 0 will put TL in out-of-resource condition for TX. + + Return current PDU resources from BAL for NON integrated SOC. + + DEPENDENCIES + + PARAMETERS + + IN + vosDataBuff vos data buffer + + OUT + puResCount available PDU number for TX + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetTxResources +( + v_PVOID_t pvosGCtx, + v_U32_t* puResCount +) +{ + /* Return minimum necessary number of packet(DXE descriptor) for data */ + /* TODO Need to get this from DXE??? */ + *puResCount = WDA_TLI_BD_PDU_RESERVE_THRESHOLD + 50; + return VOS_STATUS_SUCCESS; +} + + + +/*========================================================================== + FUNCTION WDA_DS_GetReplayCounter + + DESCRIPTION + Return replay counter from BD header or RX meta info + + DEPENDENCIES + + PARAMETERS + + IN + pRxHeader RX meta info or BD header pointer + + OUT + + RETURN VALUE + Replay Counter + + SIDE EFFECTS + +============================================================================*/ +v_U64_t +WDA_DS_GetReplayCounter +( + v_PVOID_t pRxHeader +) +{ + return WDA_GET_RX_REPLAY_COUNT( pRxHeader ); +} + +/*========================================================================== + FUNCTION WDA_DS_TxFrames + + DESCRIPTION + Pull packets from TL and push them to WDI. It gets invoked upon + WDA_DS_TX_START_XMIT. + + This function is equivelant of WLANSSC_Transmit in Libra/Volans. + + TODO + This function should be implemented and moved in WDI. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + + OUT + + RETURN VALUE + VOS_STATUS_E_FAULT: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ + +VOS_STATUS +WDA_DS_TxFrames +( + v_PVOID_t pvosGCtx +) +{ + VOS_STATUS vosStatus; + vos_pkt_t *pTxMgmtChain = NULL; + vos_pkt_t *pTxDataChain = NULL; + vos_pkt_t *pTxPacket = NULL; + v_BOOL_t bUrgent; + wpt_uint32 ucTxResReq; + WDI_Status wdiStatus; + tWDA_CbContext *wdaContext = NULL; + v_U32_t uMgmtAvailRes; + v_U32_t uDataAvailRes; + WLANTL_TxCompCBType pfnTxComp = NULL; + v_U32_t uTxFailCount = 0; + + wdaContext = (tWDA_CbContext *)vos_get_context(VOS_MODULE_ID_WDA, pvosGCtx); + if ( NULL == wdaContext ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA:Invalid wda context pointer from pvosGCtx on WDA_DS_TxFrames" ); + return VOS_STATUS_E_FAULT; + } + + /*------------------------------------------------------------------------- + Need to fetch separatelly for Mgmt and Data frames because TL is not + aware of separate resource management at the lower levels + -------------------------------------------------------------------------*/ + /*Mgmt tx*/ + uMgmtAvailRes = WDI_GetAvailableResCount(wdaContext->pWdiContext, + WDI_MGMT_POOL_ID); + + ucTxResReq = WLANTL_GetFrames( pvosGCtx, + &pTxMgmtChain, + uMgmtAvailRes, + (wdaContext->uTxFlowMask & WDA_HI_FLOW_MASK), + &bUrgent ); + + // We need to initialize vsoStatus in case we don't enter the "while" + // loop. If we don't enter the loop, it means that there are no packets, + // available, and that is considered success. If we enter the loop, + // vosStatus will be set appropriately inside the loop + vosStatus = VOS_STATUS_SUCCESS; + + while ( NULL != pTxMgmtChain ) + { + /* Walk the chain and unchain the packet */ + pTxPacket = pTxMgmtChain; + vosStatus = vos_pkt_walk_packet_chain( pTxMgmtChain, &pTxMgmtChain, VOS_TRUE ); + + if( (VOS_STATUS_SUCCESS != vosStatus) && + (VOS_STATUS_E_EMPTY != vosStatus) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA Walking packet chain returned status : %d", vosStatus ); + VOS_ASSERT( 0 ); + vosStatus = VOS_STATUS_E_FAILURE; + break; + } + + if ( VOS_STATUS_E_EMPTY == vosStatus ) + { + vosStatus = VOS_STATUS_SUCCESS; + } + + wdiStatus = WDI_DS_TxPacket( wdaContext->pWdiContext, + (wpt_packet*)pTxPacket, + 0 /* more */ ); + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WDA : Pushing a packet to WDI failed." ); + if ( WDI_STATUS_E_NOT_ALLOWED != wdiStatus ) + { + uTxFailCount++; + } + VOS_ASSERT( wdiStatus == WDI_STATUS_E_NOT_ALLOWED ); + //We need to free the packet here + vos_pkt_get_user_data_ptr(pTxPacket, VOS_PKT_USER_DATA_ID_TL, (void **)&pfnTxComp); + if(pfnTxComp) + { + pfnTxComp(pvosGCtx, pTxPacket, VOS_STATUS_E_FAILURE); + } + } + + }; + + if ( uTxFailCount ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WDA : Tx fail count for mgmt pkts: %d.", uTxFailCount); + uTxFailCount = 0; + } + + /*Data tx*/ + uDataAvailRes = WDI_GetAvailableResCount(wdaContext->pWdiContext, + WDI_DATA_POOL_ID); + + ucTxResReq = WLANTL_GetFrames( pvosGCtx, + &pTxDataChain, + /*WDA_DS_DXE_RES_COUNT*/ uDataAvailRes, + (wdaContext->uTxFlowMask & WDA_LO_FLOW_MASK), + &bUrgent ); + + // We need to initialize vsoStatus in case we don't enter the "while" + // loop. If we don't enter the loop, it means that there are no packets, + // available, and that is considered success. If we enter the loop, + // vosStatus will be set appropriately inside the loop + vosStatus = VOS_STATUS_SUCCESS; + + while ( NULL != pTxDataChain ) + { + /* Walk the chain and unchain the packet */ + pTxPacket = pTxDataChain; + vosStatus = vos_pkt_walk_packet_chain( pTxDataChain, &pTxDataChain, VOS_TRUE ); + + if( (VOS_STATUS_SUCCESS != vosStatus) && + (VOS_STATUS_E_EMPTY != vosStatus) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA Walking packet chain returned status : %d", vosStatus ); + VOS_ASSERT( 0 ); + vosStatus = VOS_STATUS_E_FAILURE; + break; + } + + if ( VOS_STATUS_E_EMPTY == vosStatus ) + { + vosStatus = VOS_STATUS_SUCCESS; + } + + wdiStatus = WDI_DS_TxPacket( wdaContext->pWdiContext, + (wpt_packet*)pTxPacket, + 0 /* more */ ); + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_WARN, + "WDA : Pushing a packet to WDI failed." ); + if ( WDI_STATUS_E_NOT_ALLOWED != wdiStatus ) + { + uTxFailCount++; + } + VOS_ASSERT( wdiStatus == WDI_STATUS_E_NOT_ALLOWED ); + //We need to free the packet here + vos_pkt_get_user_data_ptr(pTxPacket, VOS_PKT_USER_DATA_ID_TL, (void **)&pfnTxComp); + if(pfnTxComp) + { + pfnTxComp(pvosGCtx, pTxPacket, VOS_STATUS_E_FAILURE); + } + } + + }; + + if ( uTxFailCount ) + { + VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, + "WDA : Tx fail count for data pkts: %d.", uTxFailCount); + } + + + WDI_DS_TxComplete(wdaContext->pWdiContext, ucTxResReq); + + return vosStatus; +} + +/*========================================================================== + FUNCTION WDA_DS_TxFlowControlCallback + + DESCRIPTION + Invoked by WDI to control TX flow. + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + uFlowMask TX channel mask for flow control + Defined in WDA_TXFlowEnumType + + OUT + + RETURN VALUE + + SIDE EFFECTS + +============================================================================*/ +v_VOID_t +WDA_DS_TxFlowControlCallback +( + v_PVOID_t pvosGCtx, + v_U8_t ucFlowMask +) +{ + tWDA_CbContext* wdaContext = NULL; + v_U8_t ucOldFlowMask; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pvosGCtx ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA: Invalid parameter sent on WDA_DS_TxFlowControlCallback" ); + return; + } + + wdaContext = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, pvosGCtx ); + if ( NULL == wdaContext ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA: Invalid context on WDA_DS_TxFlowControlCallback" ); + return; + } + + /* two physical DXE channels + 1) data packets(all four AC) and BAP for the low priority channel(lower 4 bits) + 2) management packets for high priority channel(5th bit) + */ + + + /*Save and reset */ + ucOldFlowMask = wdaContext->uTxFlowMask; + wdaContext->uTxFlowMask = ucFlowMask; + + /*If the AC is being enabled - resume data xfer + + Assume previous value of wdaContext->uTxFlowMask: + + DATA\MGM | ON | OFF + ---------------------- + ON | 1F | 0F * + ---------------------- + OFF | 10 *| 00 * + + * - states in which a channel can be enabled + + ucFlowMask will tell which channel must be enabled + to enable a channel a new bit must be turned on => + ucFlowMask > wdaContext->uTxFlowMask when enable happens + */ + + if ( ucFlowMask > ucOldFlowMask ) + { + WDA_DS_StartXmit(pvosGCtx); + } + +} + +/*========================================================================== + FUNCTION WDA_DS_GetTxFlowMask + + DESCRIPTION + return TX flow mask control value + + DEPENDENCIES + + PARAMETERS + + IN + pvosGCtx VOS context + + OUT + uFlowMask TX channel mask for flow control + Defined in WDA_TXFlowEnumType + + RETURN VALUE + VOS_STATUS_E_INVAL: pointer is NULL and other errors + VOS_STATUS_SUCCESS: Everything is good :) + + SIDE EFFECTS + +============================================================================*/ +VOS_STATUS +WDA_DS_GetTxFlowMask +( + v_PVOID_t pvosGCtx, + v_U8_t* puFlowMask +) +{ + tWDA_CbContext* wdaContext = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( ( NULL == pvosGCtx ) || ( NULL == puFlowMask ) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA: Invalid parameter sent on WDA_DS_GetTxFlowMask" ); + return VOS_STATUS_E_INVAL; + } + + wdaContext = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, pvosGCtx ); + if ( NULL == wdaContext ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA: Invalid context on WDA_DS_GetTxFlowMask" ); + return VOS_STATUS_E_INVAL; + } + + *puFlowMask = wdaContext->uTxFlowMask; + + return VOS_STATUS_SUCCESS; +} + +v_VOID_t +WDA_DS_TxCompleteCB +( + v_PVOID_t pvosGCtx, + v_PVOID_t pFrameDataBuff +) +{ + tWDA_CbContext* wdaContext = NULL; + WDI_DS_TxMetaInfoType* pTxMetadata; + VOS_STATUS vosStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + + if ( ( NULL == pvosGCtx ) || ( NULL == pFrameDataBuff ) ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA: Invalid parameter sent on WDA_DS_TxCompleteCB" ); + return; + } + + wdaContext = (tWDA_CbContext *)vos_get_context( VOS_MODULE_ID_WDA, pvosGCtx ); + if ( NULL == wdaContext ) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "WDA: Invalid context on WDA_DS_TxCompleteCB" ); + return; + } + + // extract metadata from PAL packet + pTxMetadata = WDI_DS_ExtractTxMetaData( (wpt_packet*)pFrameDataBuff ); + + if ( eWLAN_PAL_STATUS_SUCCESS == pTxMetadata->txCompleteStatus ) + vosStatus = VOS_STATUS_SUCCESS; + else + vosStatus = VOS_STATUS_E_FAILURE; + + wdaContext->pfnTxCompleteCallback( pvosGCtx, pFrameDataBuff, vosStatus ); +} diff --git a/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_legacy.c b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_legacy.c new file mode 100644 index 000000000000..176aabf90e98 --- /dev/null +++ b/drivers/staging/prima/CORE/WDA/src/wlan_qct_wda_legacy.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + wlan_qct_wda_legacy.c + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Adaptation + Layer for the legacy functionalities that were part of the old HAL. + + The functions externalized by this module are to be called ONLY by other + WLAN modules that properly register with the Transport Layer initially. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/* Standard include files */ +/* Application Specific include files */ +#include "limApi.h" +#include "pmmApi.h" +#include "cfgApi.h" +#include "wlan_qct_wda_debug.h" + +/* Locally used Defines */ + +#define HAL_MMH_MB_MSG_TYPE_MASK 0xFF00 + +// ------------------------------------------------------------- +/** + * wdaPostCtrlMsg + * + * FUNCTION: + * Posts WDA messages to MC thread + * + * LOGIC: + * + * ASSUMPTIONS:pl + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param pMsg pointer with message + * @return Success or Failure + */ + +tSirRetStatus +wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, (vos_msg_t *) pMsg)) + return eSIR_FAILURE; + else + return eSIR_SUCCESS; +} // halPostMsg() + +/** + * wdaPostCfgMsg + * + * FUNCTION: + * Posts MNT messages to gSirMntMsgQ + * + * LOGIC: + * + * ASSUMPTIONS: + * + * + * NOTE: + * + * @param tpAniSirGlobal MAC parameters structure + * @param pMsg A pointer to the msg + * @return Success or Failure + */ + +tSirRetStatus +wdaPostCfgMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg) +{ + tSirRetStatus rc = eSIR_SUCCESS; + + do + { + // For Windows based MAC, instead of posting message to different + // queues we will call the handler routines directly + + cfgProcessMbMsg(pMac, (tSirMbMsg*)pMsg->bodyptr); + rc = eSIR_SUCCESS; + } while (0); + + return rc; +} // halMntPostMsg() + + +// ------------------------------------------------------------- +/** + * uMacPostCtrlMsg + * + * FUNCTION: + * Forwards the completely received message to the respective + * modules for further processing. + * + * LOGIC: + * + * ASSUMPTIONS: + * Freeing up of the message buffer is left to the destination module. + * + * NOTE: + * This function has been moved to the API file because for MAC running + * on Windows host, the host module will call this routine directly to + * send any mailbox messages. Making this function an API makes sure that + * outside world (any module outside MMH) only calls APIs to use MMH + * services and not an internal function. + * + * @param pMb A pointer to the maibox message + * @return NONE + */ + +tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb) +{ + tSirMsgQ msg; + tpAniSirGlobal pMac = (tpAniSirGlobal)pSirGlobal; + + + tSirMbMsg* pMbLocal; + msg.type = pMb->type; + msg.bodyval = 0; + + WDALOG3(wdaLog(pMac, LOG3, FL("msgType %d, msgLen %d" ), + pMb->type, pMb->msgLen)); + + // copy the message from host buffer to firmware buffer + // this will make sure that firmware allocates, uses and frees + // it's own buffers for mailbox message instead of working on + // host buffer + + // second parameter, 'wait option', to palAllocateMemory is ignored on Windows + pMbLocal = vos_mem_malloc(pMb->msgLen); + if ( NULL == pMbLocal ) + { + WDALOGE( wdaLog(pMac, LOGE, FL("Buffer Allocation failed!"))); + return eSIR_FAILURE; + } + + vos_mem_copy((void *)pMbLocal, (void *)pMb, pMb->msgLen); + msg.bodyptr = pMbLocal; + + switch (msg.type & HAL_MMH_MB_MSG_TYPE_MASK) + { + case WDA_MSG_TYPES_BEGIN: // Posts a message to the HAL MsgQ + case WDA_EXT_MSG_TYPES_BEGIN: + wdaPostCtrlMsg(pMac, &msg); + break; + + case SIR_LIM_MSG_TYPES_BEGIN: // Posts a message to the LIM MsgQ + limPostMsgApi(pMac, &msg); + break; + + case SIR_CFG_MSG_TYPES_BEGIN: // Posts a message to the CFG MsgQ + wdaPostCfgMsg(pMac, &msg); + break; + + case SIR_PMM_MSG_TYPES_BEGIN: // Posts a message to the PMM MsgQ + pmmPostMessage(pMac, &msg); + break; + + case SIR_PTT_MSG_TYPES_BEGIN: + WDALOGW( wdaLog(pMac, LOGW, FL("%s:%d: message type = 0x%X"), + __func__, __LINE__, msg.type)); + vos_mem_free(msg.bodyptr); + break; + + + default: + WDALOGW( wdaLog(pMac, LOGW, FL("Unknown message type = " + "0x%X"), + msg.type)); + + // Release the memory. + vos_mem_free(msg.bodyptr); + break; + } + + return eSIR_SUCCESS; + +} // uMacPostCtrlMsg() + + +/* --------------------------------------------------------- + * FUNCTION: wdaGetGlobalSystemRole() + * + * Get the global HAL system role. + * --------------------------------------------------------- + */ +tBssSystemRole wdaGetGlobalSystemRole(tpAniSirGlobal pMac) +{ + v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); + tWDA_CbContext *wdaContext = + vos_get_context(VOS_MODULE_ID_WDA, pVosContext); + if(NULL == wdaContext) + { + VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR, + "%s:WDA context is NULL", __func__); + VOS_ASSERT(0); + return eSYSTEM_UNKNOWN_ROLE; + } + return wdaContext->wdaGlobalSystemRole; +} + diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/qwlanfw_defs.h b/drivers/staging/prima/CORE/WDI/CP/inc/qwlanfw_defs.h new file mode 100644 index 000000000000..3936a7184ac1 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/qwlanfw_defs.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + * + * @file: wlan_defs.h + * + * @brief: This file defines the common typedefs + * + * @author: Gagan Jain + * + * Copyright (C) 2010, Qualcomm, Inc. + * All rights reserved. + * + *=========================================================================*/ + +#ifndef __WLAN_DEFS_H__ +#define __WLAN_DEFS_H__ + +/*------------------------------------------------------------------------- + Include Files +-------------------------------------------------------------------------*/ +#include "wlan_qct_pal_type.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +typedef wpt_uint32 uint32; /* Unsigned 32 bit value */ + +typedef wpt_uint16 uint16; /* Unsigned 16 bit value */ + +typedef wpt_uint8 uint8; /* Unsigned 8 bit value */ + +typedef wpt_int32 int32; /* Signed 32 bit value */ + +typedef wpt_int16 int16; /* Signed 16 bit value */ + +typedef wpt_int8 int8; /* Signed 8 bit value */ + +typedef wpt_int64 int64; /* Signed 64 bit value */ + +typedef wpt_uint64 uint64; /* Unsigned 64 bit value */ + +typedef wpt_byte byte; /* byte type */ + +typedef wpt_boolean boolean; /* Boolean Type */ + +#endif //__WLAN_DEFS_H__ diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h new file mode 100644 index 000000000000..297fba64905c --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi.h @@ -0,0 +1,12510 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_WDI_H +#define WLAN_QCT_WDI_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan transport layer + module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/05/11 hap Adding support for Keep Alive +08/04/10 lti Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pack_align.h" +#include "wlan_qct_wdi_cfg.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ +#ifdef __cplusplus + extern "C" { +#endif + +/* MAC ADDRESS LENGTH - per spec*/ +#define WDI_MAC_ADDR_LEN 6 + +/* Max number of 11b rates -> 1,2,5.5,11 */ +#define WDI_NUM_11B_RATES 4 + +/* Max number of 11g rates -> 6,9,12,18,24,36,48,54*/ +#define WDI_NUM_11A_RATES 8 + +/* Max number of legacy rates -> 72, 96, 108*/ +#define WDI_NUM_POLARIS_RATES 3 + +/* Max supported MCS set*/ +#define WDI_MAC_MAX_SUPPORTED_MCS_SET 16 + +/*Max number of Access Categories for QoS - per spec */ +#define WDI_MAX_NO_AC 4 + +/*Max. size for reserving the Beacon Template */ +#define WDI_BEACON_TEMPLATE_SIZE 0x180 + +#define WDI_WOWL_BCAST_PATTERN_MAX_SIZE 128 + +#define WDI_WOWL_BCAST_MAX_NUM_PATTERNS 16 + +#define WDI_MAX_SSID_SIZE 32 + +/* The shared memory between WDI and HAL is 4K so maximum data can be transferred +from WDI to HAL is 4K.This 4K should also include the Message header so sending 4K +of NV fragment is nt possbile.The next multiple of 1Kb is 3K */ + +#define FRAGMENT_SIZE 3072 + +/* Macro to find the total number fragments of the NV Image*/ +#define TOTALFRAGMENTS(x) (((x % FRAGMENT_SIZE) == 0) ? (x / FRAGMENT_SIZE):((x / FRAGMENT_SIZE) + 1)) + +/* Beacon Filter Length*/ +#define WDI_BEACON_FILTER_LEN 90 + +/* Coex Indication data size - should match WLAN_COEX_IND_DATA_SIZE */ +#define WDI_COEX_IND_DATA_SIZE (4) + +#define WDI_CIPHER_SEQ_CTR_SIZE 6 + +#define WDI_NUM_BSSID 2 + +/*Version string max length (including NUL) */ +#define WDI_VERSION_LENGTH 64 + + +/*WDI Response timeout - how long will WDI wait for a response from the device + - it should be large enough to allow any other failure mechanism to kick + in before we get to a timeout (ms units)*/ +#define WDI_RESPONSE_TIMEOUT 10000 + +/* SSR timeout - If Riva initiated SSR doesn't happen during this time, then the + * Apps initiated SSR will be performed */ +#define WDI_SSR_TIMEOUT 5000 + +#define WDI_SET_POWER_STATE_TIMEOUT 10000 /* in msec a very high upper limit */ + +/* Periodic Tx pattern offload feature */ +#define PERIODIC_TX_PTRN_MAX_SIZE 1536 +#define MAXNUM_PERIODIC_TX_PTRNS 6 +#define WDI_DISA_MAX_PAYLOAD_SIZE 1600 +#define MAX_NUM_OF_BUFFER 3 +#define VALID_FW_LOG_TYPES 2 +#define MAX_LOG_BUFFER_LENGTH 128 * 1024 + +/*============================================================================ + * GENERIC STRUCTURES + +============================================================================*/ + +/*--------------------------------------------------------------------------- + WDI Version Information +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 revision; + wpt_uint8 version; + wpt_uint8 minor; + wpt_uint8 major; +} WDI_WlanVersionType; + +/*--------------------------------------------------------------------------- + WDI Device Capability +---------------------------------------------------------------------------*/ +typedef struct +{ + /*If this flag is true it means that the device can support 802.3/ETH2 to + 802.11 translation*/ + wpt_boolean bFrameXtlSupported; + + /*Maximum number of BSSes supported by the Device */ + wpt_uint8 ucMaxBSSSupported; + + /*Maximum number of stations supported by the Device */ + wpt_uint8 ucMaxSTASupported; +}WDI_DeviceCapabilityType; + +/*--------------------------------------------------------------------------- + WDI Channel Offset +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_SECONDARY_CHANNEL_OFFSET_NONE = 0, + WDI_SECONDARY_CHANNEL_OFFSET_UP = 1, + WDI_SECONDARY_CHANNEL_OFFSET_DOWN = 3, +#ifdef WLAN_FEATURE_11AC + WDI_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + WDI_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + WDI_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + WDI_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + WDI_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + WDI_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + WDI_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + WDI_SECONDARY_CHANNEL_OFFSET_MAX +}WDI_HTSecondaryChannelOffset; + +/*--------------------------------------------------------------------------- + WDI_MacFrameCtl + Frame control field format (2 bytes) +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 protVer :2; + wpt_uint8 type :2; + wpt_uint8 subType :4; + + wpt_uint8 toDS :1; + wpt_uint8 fromDS :1; + wpt_uint8 moreFrag :1; + wpt_uint8 retry :1; + wpt_uint8 powerMgmt :1; + wpt_uint8 moreData :1; + wpt_uint8 wep :1; + wpt_uint8 order :1; + +} WDI_MacFrameCtl; + +/*--------------------------------------------------------------------------- + WDI Sequence control field +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 fragNum : 4; + wpt_uint8 seqNumLo : 4; + wpt_uint8 seqNumHi : 8; +} WDI_MacSeqCtl; + +/*--------------------------------------------------------------------------- + Management header format +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_MacFrameCtl fc; + wpt_uint8 durationLo; + wpt_uint8 durationHi; + wpt_uint8 da[WDI_MAC_ADDR_LEN]; + wpt_uint8 sa[WDI_MAC_ADDR_LEN]; + wpt_macAddr bssId; + WDI_MacSeqCtl seqControl; +} WDI_MacMgmtHdr; + +/*--------------------------------------------------------------------------- + NV Blob management sturcture + ---------------------------------------------------------------------------*/ + +typedef struct +{ + /* NV image fragments count */ + wpt_uint16 usTotalFragment; + + /* NV fragment size */ + wpt_uint16 usFragmentSize; + + /* current fragment to be sent */ + wpt_uint16 usCurrentFragment; + +} WDI_NvBlobInfoParams; + + +/*--------------------------------------------------------------------------- + Data path enums memory pool resource + ---------------------------------------------------------------------------*/ + +typedef enum +{ + /* managment resource pool ID */ + WDI_MGMT_POOL_ID = 0, + /* Data resource pool ID */ + WDI_DATA_POOL_ID = 1 +}WDI_ResPoolType; + +/*============================================================================ + * GENERIC STRUCTURES - END + ============================================================================*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + WDI Status +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_STATUS_SUCCESS, /* Operation has completed successfully*/ + WDI_STATUS_SUCCESS_SYNC, /* Operation has completed successfully in a + synchronous way - no rsp will be generated*/ + WDI_STATUS_PENDING, /* Operation result is pending and will be + provided asynchronously through the Req Status + Callback */ + WDI_STATUS_E_FAILURE, /* Operation has ended in a generic failure*/ + WDI_STATUS_RES_FAILURE, /* Operation has ended in a resource failure*/ + WDI_STATUS_MEM_FAILURE, /* Operation has ended in a memory allocation + failure*/ + WDI_STATUS_E_NOT_ALLOWED, /* Operation is not allowed in the current state + of the driver*/ + WDI_STATUS_E_NOT_IMPLEMENT, /* Operation is not yet implemented*/ + + WDI_STATUS_DEV_INTERNAL_FAILURE, /*An internal error has occurred in the device*/ + WDI_STATUS_MAX + +}WDI_Status; + + +/*--------------------------------------------------------------------------- + WDI_ReqStatusCb + + DESCRIPTION + + This callback is invoked by DAL to deliver to UMAC the result of posting + a previous request for which the return status was PENDING. + + PARAMETERS + + IN + wdiStatus: response status received from the Control Transport + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ReqStatusCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_LowLevelIndEnumType + Types of indication that can be posted to UMAC by DAL +---------------------------------------------------------------------------*/ +typedef enum +{ + /*When RSSI monitoring is enabled of the Lower MAC and a threshold has been + passed. */ + WDI_RSSI_NOTIFICATION_IND, + + /*Link loss in the low MAC */ + WDI_MISSED_BEACON_IND, + + /*when hardware has signaled an unknown addr2 frames. The indication will + contain info from frames to be passed to the UMAC, this may use this info to + deauth the STA*/ + WDI_UNKNOWN_ADDR2_FRAME_RX_IND, + + /*MIC Failure detected by HW*/ + WDI_MIC_FAILURE_IND, + + /*Fatal Error Ind*/ + WDI_FATAL_ERROR_IND, + + /*Delete Station Ind*/ + WDI_DEL_STA_IND, + + /*Indication from Coex*/ + WDI_COEX_IND, + + /* Indication for Tx Complete */ + WDI_TX_COMPLETE_IND, + + /*.P2P_NOA_Attr_Indication */ + WDI_P2P_NOA_ATTR_IND, + + /* Preferred Network Found Indication */ + WDI_PREF_NETWORK_FOUND_IND, + + WDI_WAKE_REASON_IND, + + /* Tx PER Tracking Indication */ + WDI_TX_PER_HIT_IND, + + /* P2P_NOA_Start_Indication */ + WDI_P2P_NOA_START_IND, + + /* TDLS_Indication */ + WDI_TDLS_IND, + + /* LPHB Indication from FW to umac */ + WDI_LPHB_IND, + + /* IBSS Peer Inactivity Indication */ + WDI_IBSS_PEER_INACTIVITY_IND, + + /* Periodic Tx Pattern FW Indication */ + WDI_PERIODIC_TX_PTRN_FW_IND, +#ifdef WLAN_FEATURE_RMC + /* RMC_Ruler_Pick_New Indication */ + WDI_RMC_RULER_PICK_NEW, +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*Batch scan result indication from FW*/ + WDI_BATCH_SCAN_RESULT_IND, +#endif + +#ifdef WLAN_FEATURE_RMC + WDI_TX_FAIL_IND, +#endif + +#ifdef FEATURE_WLAN_CH_AVOID + WDI_CH_AVOID_IND, +#endif /* FEATURE_WLAN_CH_AVOID */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_LL_STATS_RESULTS_IND, +#endif +#ifdef WLAN_FEATURE_EXTSCAN + WDI_EXTSCAN_PROGRESS_IND, + WDI_EXTSCAN_SCAN_AVAILABLE_IND, + WDI_EXTSCAN_SCAN_RESULT_IND, + WDI_EXTSCAN_GET_CAPABILITIES_IND, + WDI_EXTSCAN_BSSID_HOTLIST_RESULT_IND, +#endif + /*Delete BA Ind*/ + WDI_DEL_BA_IND, + WDI_NAN_EVENT_IND, + WDI_LOST_LINK_PARAMS_IND, + WDI_RSSI_BREACHED_IND, +#ifdef FEATURE_OEM_DATA_SUPPORT + WDI_START_OEM_DATA_RSP_IND_NEW, +#endif +#ifdef WLAN_FEATURE_APFIND + WDI_AP_FOUND_IND, +#endif + WDI_MAX_IND +}WDI_LowLevelIndEnumType; + + +/*--------------------------------------------------------------------------- + WDI_LowRSSIThIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Positive crossing of Rssi Thresh1*/ + wpt_uint32 bRssiThres1PosCross : 1; + /*Negative crossing of Rssi Thresh1*/ + wpt_uint32 bRssiThres1NegCross : 1; + /*Positive crossing of Rssi Thresh2*/ + wpt_uint32 bRssiThres2PosCross : 1; + /*Negative crossing of Rssi Thresh2*/ + wpt_uint32 bRssiThres2NegCross : 1; + /*Positive crossing of Rssi Thresh3*/ + wpt_uint32 bRssiThres3PosCross : 1; + /*Negative crossing of Rssi Thresh3*/ + wpt_uint32 bRssiThres3NegCross : 1; + + wpt_uint32 avgRssi : 8; + wpt_uint32 bReserved : 18; + +}WDI_LowRSSIThIndType; + + +/*--------------------------------------------------------------------------- + WDI_UnkAddr2FrmRxIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Rx Bd data of the unknown received addr2 frame.*/ + void* bufRxBd; + + /*Buffer Length*/ + wpt_uint16 usBufLen; +}WDI_UnkAddr2FrmRxIndType; + +/*--------------------------------------------------------------------------- + WDI_DeleteSTAIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*ASSOC ID, as assigned by UMAC*/ + wpt_uint16 usAssocId; + + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ + wpt_uint8 ucSTAIdx; + + /*BSSID of STA*/ + wpt_macAddr macBSSID; + + /*MAC ADDR of STA*/ + wpt_macAddr macADDR2; + + /* To unify the keepalive / unknown A2 / tim-based disa*/ + wpt_uint16 wptReasonCode; + +}WDI_DeleteSTAIndType; + +/*--------------------------------------------------------------------------- + WDI_MicFailureIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*current BSSID*/ + wpt_macAddr bssId; + + /*Source mac address*/ + wpt_macAddr macSrcAddr; + + /*Transmitter mac address*/ + wpt_macAddr macTaAddr; + + /*Destination mac address*/ + wpt_macAddr macDstAddr; + + /*Multicast flag*/ + wpt_uint8 ucMulticast; + + /*First byte of IV*/ + wpt_uint8 ucIV1; + + /*Key Id*/ + wpt_uint8 keyId; + + /*Sequence Number*/ + wpt_uint8 TSC[WDI_CIPHER_SEQ_CTR_SIZE]; + + /*receive address */ + wpt_macAddr macRxAddr; +}WDI_MicFailureIndType; + +/*--------------------------------------------------------------------------- + WDI_CoexIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 coexIndType; + wpt_uint32 coexIndData[WDI_COEX_IND_DATA_SIZE]; +} WDI_CoexIndType; + +/*--------------------------------------------------------------------------- + WDI_DHCPInd +---------------------------------------------------------------------------*/ + +typedef struct +{ + wpt_uint8 device_mode; + wpt_uint8 macAddr[WDI_MAC_ADDR_LEN]; +}WDI_DHCPInd; + +#ifdef WLAN_FEATURE_RMC +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + wpt_uint8 tx_fail_count; +}WDI_TXFailMonitorInd; +#endif /* WLAN_FEATURE_RMC */ + +/*--------------------------------------------------------------------------- + + WDI_MacSSid +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucLength; + wpt_uint8 sSSID[WDI_MAX_SSID_SIZE]; +} WDI_MacSSid; + +#ifdef FEATURE_WLAN_SCAN_PNO +/*--------------------------------------------------------------------------- + WDI_PrefNetworkFoundInd +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Network that was found with the highest RSSI*/ + WDI_MacSSid ssId; + /* Indicates the RSSI */ + wpt_uint8 rssi; + wpt_uint16 frameLength; + wpt_uint8 *pData; +} WDI_PrefNetworkFoundInd; +#endif // FEATURE_WLAN_SCAN_PNO + +/*--------------------------------------------------------------------------- + *WDI_P2pNoaAttrIndType + *-------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucIndex ; + wpt_uint8 ucOppPsFlag ; + wpt_uint16 usCtWin ; + + wpt_uint16 usNoa1IntervalCnt; + wpt_uint16 usRsvd1 ; + wpt_uint32 uslNoa1Duration; + wpt_uint32 uslNoa1Interval; + wpt_uint32 uslNoa1StartTime; + + wpt_uint16 usNoa2IntervalCnt; + wpt_uint16 usRsvd2; + wpt_uint32 uslNoa2Duration; + wpt_uint32 uslNoa2Interval; + wpt_uint32 uslNoa2StartTime; + + wpt_uint32 status; +}WDI_P2pNoaAttrIndType; + +/*--------------------------------------------------------------------------- + *WDI_P2pNoaStartIndType + *-------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 status; + wpt_uint32 bssIdx; +}WDI_P2pNoaStartIndType; + +/*--------------------------------------------------------------------------- + *WDI_TdlsIndType + *-------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 status; + wpt_uint16 assocId; + wpt_uint16 staIdx; + wpt_uint16 reasonCode; +}WDI_TdlsIndType; + +#ifdef WLAN_WAKEUP_EVENTS +/*--------------------------------------------------------------------------- + WDI_WakeReasonIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 ulReason; /* see tWakeReasonType */ + wpt_uint32 ulReasonArg; /* argument specific to the reason type */ + wpt_uint32 ulStoredDataLen; /* length of optional data stored in this message, in case + HAL truncates the data (i.e. data packets) this length + will be less than the actual length */ + wpt_uint32 ulActualDataLen; /* actual length of data */ + wpt_uint8 aDataStart[1]; /* variable length start of data (length == storedDataLen) + see specific wake type */ +} WDI_WakeReasonIndType; +#endif // WLAN_WAKEUP_EVENTS + +typedef struct +{ + wpt_uint16 event_data_len; + wpt_uint8* event_data; +} WDI_NanEventType; + + +/*--------------------------------------------------------------------------- + WDI_MissedBeaconIndType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; /*bssidx on which beacon is missed*/ +} WDI_MissedBeaconIndType; + +#ifdef FEATURE_WLAN_LPHB +/*--------------------------------------------------------------------------- + WDI_LPHBTimeoutIndData +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint8 sessionIdx; + wpt_uint8 protocolType; /*TCP or UDP*/ + wpt_uint8 eventReason; +} WDI_LPHBTimeoutIndData; +#endif /* FEATURE_WLAN_LPHB */ + +/*----------------------------------------------------------------------------- +WDI_PeriodicTxPtrnFwIndType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint32 selfStaIdx; + wpt_uint32 status; + wpt_uint32 patternIdBitmap; +} WDI_PeriodicTxPtrnFwIndType; + +#ifdef FEATURE_WLAN_BATCH_SCAN +/*--------------------------------------------------------------------------- + WDI_SetBatchScanReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 scanFrequency; /* how frequent to do scan default 30Sec*/ + wpt_uint32 numberOfScansToBatch; /* number of scans to batch */ + wpt_uint32 bestNetwork; /* best networks in terms of rssi */ + wpt_uint8 rfBand; /* band to scan : + 0 ->both Band, 1->2.4Ghz Only + and 2-> 5GHz Only */ + wpt_uint32 rtt; /* set if required to do RTT it is not + supported in current version */ +}WDI_SetBatchScanReqType; + +/*--------------------------------------------------------------------------- + WDI_SetBatchScanRspType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*max number of scans which FW can cache*/ + wpt_uint32 nScansToBatch; +}WDI_SetBatchScanRspType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBatchScanResultIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 param; +}WDI_TriggerBatchScanResultIndType; + +/*--------------------------------------------------------------------------- + WDI_StopBatchScanIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*max number of scans which FW can cache*/ + wpt_uint32 param; +}WDI_StopBatchScanIndType; + + +/*--------------------------------------------------------------------------- + * WDI_BatchScanResultIndType + *--------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 bssid[6]; /* BSSID */ + wpt_uint32 ssid[32]; /* SSID */ + wpt_uint32 ch; /* Channel */ + wpt_uint32 rssi; /* RSSI or Level */ + /* Timestamp when Network was found. Used to calculate age based on + timestamp in GET_RSP msg header */ + wpt_uint32 timestamp; +} tWDIBatchScanNetworkInfo, *tpWDIBatchScanNetworkInfo; + +typedef struct +{ + wpt_uint32 scanId; /*Scan List ID*/ + /*No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg*/ + wpt_uint32 numNetworksInScanList; + /*Variable data ptr: Number of AP in Scan List*/ + wpt_uint32 scanList[1]; +} tWDIBatchScanList, *tpWDIBatchScanList; + +typedef struct +{ + wpt_uint32 timestamp; + wpt_uint32 numScanLists; + wpt_boolean isLastResult; + /* Variable Data ptr: Number of Scan Lists*/ + wpt_uint32 scanResults[1]; +} tWDIBatchScanResultParam, *tpWDIBatchScanResultParam; + +#endif + +#ifdef WLAN_FEATURE_RMC +typedef struct +{ + wpt_uint8 seqNo; + wpt_uint8 macAddr[WDI_MAC_ADDR_LEN]; +} WDI_TXFailIndType; +#endif /* WLAN_FEATURE_RMC */ + +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint8 rssi; + wpt_uint8 selfMacAddr[WDI_MAC_ADDR_LEN]; + wpt_uint32 linkFlCnt; + wpt_uint32 linkFlTx; + wpt_uint32 lastDataRate; + wpt_uint32 rsvd1; + wpt_uint32 rsvd2; + +}WDI_LostLinkParamsIndType; + +typedef struct +{ + wpt_uint32 request_id; + wpt_uint8 bssId[WDI_MAC_ADDR_LEN]; + wpt_int8 rssi; +}WDI_RssiBreachedIndType; + +/*--------------------------------------------------------------------------- + WDI_IbssPeerInactivityIndType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; + wpt_uint8 staIdx; + wpt_macAddr staMacAddr; +}WDI_IbssPeerInactivityIndType; + +#ifdef WLAN_FEATURE_RMC +/*--------------------------------------------------------------------------- + WDI_RmcRulerReqParams +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 cmd; + + /* MAC address of MCAST Transmitter (source) */ + wpt_macAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + wpt_macAddr mcastGroup; + + /* List of candidates for cmd = WLAN_HAL_SUGGEST_RULER*/ + wpt_macAddr blacklist[8]; /* HAL_NUM_MAX_RULERS */ + + /* + * Request status callback offered by UMAC - it is called if the current + * req has returned PENDING as status; it delivers the status of sending + * the message over the BUS + */ + WDI_ReqStatusCb wdiReqStatusCB; + +} WDI_RmcRulerReqParams; + +/*--------------------------------------------------------------------------- + WDI_RmcUpdateIndParams +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 indication; /* tRmcUpdateIndType */ + + wpt_uint8 role; + + /* MAC address of MCAST Transmitter (source) */ + wpt_macAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + wpt_macAddr mcastGroup; + + wpt_macAddr mcastRuler; + + wpt_macAddr ruler[16]; + + /* + * Request status callback offered by UMAC - it is called if the current + * req has returned PENDING as status; it delivers the status of sending + * the message over the BUS + */ + WDI_ReqStatusCb wdiReqStatusCB; + + /* + * The user data passed in by UMAC, it will be sent back when the above + * function pointer will be called + */ + void *pUserData; + +} WDI_RmcUpdateIndParams; + +typedef enum +{ + eWDI_SUGGEST_RULER_CMD = 0, + eWDI_BECOME_RULER_CMD = 1, +} eWDI_RulerRspCmdType; + +/*--------------------------------------------------------------------------- + WDI_RmcRspParamsType +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 status; /* success or failure */ + + /* Command Type */ + eWDI_RulerRspCmdType cmd; + + /* MAC address of MCAST Transmitter (source) */ + wpt_macAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + wpt_macAddr mcastGroup; + + wpt_macAddr ruler[8]; +} WDI_RmcRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_RmcPickNewRuler +-----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 indication; /* pick_new */ + + wpt_uint8 role; + + /* MAC address of MCAST Transmitter (source) */ + wpt_macAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + wpt_macAddr mcastGroup; + + wpt_macAddr mcastRuler; + + wpt_macAddr ruler[16]; +} WDI_RmcPickNewRuler; +#endif + +/*--------------------------------------------------------------------------- + WDI_TxRateFlags +-----------------------------------------------------------------------------*/ +typedef enum +{ + WDI_TX_RATE_LEGACY = 0x1, /* Legacy rates */ + WDI_TX_RATE_HT20 = 0x2, /* HT20 rates */ + WDI_TX_RATE_HT40 = 0x4, /* HT40 rates */ + WDI_TX_RATE_SGI = 0x8, /* Rate with Short guard interval */ + WDI_TX_RATE_LGI = 0x10, /* Rate with Long guard interval */ + WDI_TX_RATE_VHT20 = 0x20, /* VHT 20 rates */ + WDI_TX_RATE_VHT40 = 0x40, /* VHT 20 rates */ + WDI_TX_RATE_VHT80 = 0x80, /* VHT 20 rates */ + WDI_TX_RATE_VIRT = 0x100, /* Virtual Rate */ +} WDI_TxRateFlags; + +/*--------------------------------------------------------------------------- + WDI_RateUpdateIndParams +-----------------------------------------------------------------------------*/ +typedef struct +{ + /* 0 implies RA, positive value implies fixed rate, -1 implies ignore this + * param ucastDataRate can be used to control RA behavior of unicast data to + */ + wpt_int32 ucastDataRate; + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags ucastDataRateTxFlag; + + /* BSSID - Optional. 00-00-00-00-00-00 implies apply to all BCAST STAs */ + wpt_macAddr bssid; + + /* + * 0 implies MCAST RA, positive value implies fixed rate, + * -1 implies ignore this param + */ + wpt_int32 rmcDataRate; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags rmcDataRateTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 2.4 GHz, unit Mbpsx10, + * 0 implies ignore + */ + wpt_uint32 mcastDataRate24GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags mcastDataRate24GHzTxFlag; + + /* + * MCAST(or BCAST) fixed data rate in 5 GHz, + * unit Mbpsx10, 0 implies ignore + */ + wpt_uint32 mcastDataRate5GHz; + + /* TX flag to differentiate between HT20, HT40 etc */ + WDI_TxRateFlags mcastDataRate5GHzTxFlag; + + /* + * Request status callback offered by UMAC - it is called if the current + * req has returned PENDING as status; it delivers the status of sending + * the message over the BUS + */ + WDI_ReqStatusCb wdiReqStatusCB; + + /* + * The user data passed in by UMAC, it will be sent back when the above + * function pointer will be called + */ + void *pUserData; + +} WDI_RateUpdateIndParams; + +typedef struct +{ + wpt_uint32 ubsp_enter_cnt; + wpt_uint32 ubsp_jump_ddr_cnt; +}ubspFwStats; + +typedef struct +{ + wpt_uint32 type; + /*data*/ + union{ + ubspFwStats ubspStats; + }wdiFwStatsData; +} WDI_FWStatsResults; + +#ifdef FEATURE_WLAN_CH_AVOID +#define WDI_CH_AVOID_MAX_RANGE 15 + +typedef struct +{ + wpt_uint32 startFreq; + wpt_uint32 endFreq; +} WDI_ChAvoidFreqType; + +typedef struct +{ + wpt_uint32 avoidRangeCount; + WDI_ChAvoidFreqType avoidFreqRange[WDI_CH_AVOID_MAX_RANGE]; +} WDI_ChAvoidIndType; +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +typedef struct +{ + void *pLinkLayerStatsResults; + wpt_macAddr macAddr; +} WDI_LinkLayerStatsResults; + +#endif + +typedef struct +{ + /*STA Index*/ + wpt_uint16 staIdx; + + /*Peer MAC*/ + wpt_macAddr peerMacAddr; + + // TID for which a BA session timeout is being triggered + wpt_uint8 baTID; + // DELBA direction + // 1 - Originator + // 0 - Recipient + wpt_uint8 baDirection; + wpt_uint32 reasonCode; + /*MAC ADDR of STA*/ + wpt_macAddr bssId; // TO SUPPORT BT-AMP +} WDI_DeleteBAIndType; + +typedef struct +{ + wpt_uint32 tx_complete_status; + wpt_uint32 tx_bd_token; +} WDI_TxBDStatus; + +#ifdef FEATURE_OEM_DATA_SUPPORT +/*---------------------------------------------------------------------------- + OEM DATA RESPONSE - DATA STRUCTURES +----------------------------------------------------------------------------*/ +typedef struct +{ + void *pOemRspNewIndData; + /* Max OemRspNewLen possible is NEW_OEM_DATA_RSP_SIZE*/ + wpt_uint32 OemRspNewLen; +} WDI_OemDataRspNew; +#endif + +/*--------------------------------------------------------------------------- + WDI_LowLevelIndType + Inidcation type and information about the indication being carried + over +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Inidcation type*/ + WDI_LowLevelIndEnumType wdiIndicationType; + + /*Indication data*/ + union + { + /*RSSI Threshold Info for WDI_LOW_RSSI_IND*/ + WDI_LowRSSIThIndType wdiLowRSSIInfo; + + /*Addr2 Frame Info for WDI_UNKNOWN_ADDR2_FRAME_RX_IND*/ + WDI_UnkAddr2FrmRxIndType wdiUnkAddr2FrmInfo; + + /*MIC Failure info for WDI_MIC_FAILURE_IND*/ + WDI_MicFailureIndType wdiMICFailureInfo; + + /*Error code for WDI_FATAL_ERROR_IND*/ + wpt_uint16 usErrorCode; + + /*Delete STA Indication*/ + WDI_DeleteSTAIndType wdiDeleteSTAIndType; + + /*Coex Indication*/ + WDI_CoexIndType wdiCoexInfo; + + /* Tx Complete Indication */ + wpt_uint32 tx_complete_status; + + /* P2P NOA ATTR Indication */ + WDI_P2pNoaAttrIndType wdiP2pNoaAttrInfo; + WDI_P2pNoaStartIndType wdiP2pNoaStartInfo; + /* TDLS Indications */ + WDI_TdlsIndType wdiTdlsIndInfo; + + +#ifdef FEATURE_WLAN_SCAN_PNO + WDI_PrefNetworkFoundInd wdiPrefNetworkFoundInd; +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_WAKEUP_EVENTS + WDI_WakeReasonIndType wdiWakeReasonInd; +#endif // WLAN_WAKEUP_EVENTS + WDI_MissedBeaconIndType wdiMissedBeaconInd; + +#ifdef FEATURE_WLAN_LPHB + WDI_LPHBTimeoutIndData wdiLPHBTimeoutInd; +#endif /* FEATURE_WLAN_LPHB */ + + /* IBSS Peer Inactivity Indication */ + WDI_IbssPeerInactivityIndType wdiIbssPeerInactivityInd; + + /* Periodic TX Pattern FW Indication */ + WDI_PeriodicTxPtrnFwIndType wdiPeriodicTxPtrnFwInd; + +#ifdef WLAN_FEATURE_RMC + WDI_RmcPickNewRuler wdiRmcPickNewRulerInd; +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + /*batch scan result indication from FW*/ + void *pBatchScanResult; +#endif + +#ifdef WLAN_FEATURE_RMC + WDI_TXFailIndType wdiTXFailInd; +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_CH_AVOID + WDI_ChAvoidIndType wdiChAvoidInd; +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + /*Link Layer Statistics from FW*/ + WDI_LinkLayerStatsResults wdiLinkLayerStatsResults; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + /*EXTSCAN Results from FW*/ + void *pEXTScanIndData; +#endif + WDI_DeleteBAIndType wdiDeleteBAInd; + + WDI_NanEventType wdiNanEvent; + + WDI_TxBDStatus wdiTxBdInd; + WDI_LostLinkParamsIndType wdiLostLinkParamsInd; + WDI_RssiBreachedIndType wdiRssiBreachedInd; +#ifdef FEATURE_OEM_DATA_SUPPORT +/*OEM Data Rsp New Results from FW*/ + WDI_OemDataRspNew wdiOemDataRspNew; +#endif + } wdiIndicationData; +}WDI_LowLevelIndType; + +/*--------------------------------------------------------------------------- + WDI_LowLevelIndCBType + + DESCRIPTION + + This callback is invoked by DAL to deliver to UMAC certain indications + that has either received from the lower device or has generated itself. + + PARAMETERS + + IN + pwdiInd: information about the indication sent over + pUserData: user data provided by UMAC during registration + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_LowLevelIndCBType)(WDI_LowLevelIndType* pwdiInd, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_DriverType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_DRIVER_TYPE_PRODUCTION = 0, + WDI_DRIVER_TYPE_MFG = 1, + WDI_DRIVER_TYPE_DVT = 2 +} WDI_DriverType; + +/*--------------------------------------------------------------------------- + WDI_StartReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*This is a TLV formatted buffer containing all config values that can + be set through the DAL Interface + + The TLV is expected to be formatted like this: + + 0 7 15 31 .... + | CONFIG ID | CFG LEN | RESERVED | CFG BODY | + + Or from a C construct point of VU it would look like this: + + typedef struct WPT_PACK_POST + { + #ifdef WPT_BIG_ENDIAN + wpt_uint32 ucCfgId:8; + wpt_uint32 ucCfgLen:8; + wpt_uint32 usReserved:16; + #else + wpt_uint32 usReserved:16; + wpt_uint32 ucCfgLen:8; + wpt_uint32 ucCfgId:8; + #endif + + wpt_uint8 ucCfgBody[ucCfgLen]; + }WDI_ConfigType; + + Multiple such tuplets are to be placed in the config buffer. One for + each required configuration item: + + | TLV 1 | TLV2 | .... + + The buffer is expected to be a flat area of memory that can be manipulated + with standard memory routines. + + For more info please check paragraph 2.3.1 Config Structure from the + HAL LLD. + + For a list of accepted configuration list and IDs please look up + wlan_qct_dal_cfg.h + + */ + void* pConfigBuffer; + + /*Length of the config buffer above*/ + wpt_uint16 usConfigBufferLen; + + /*Production or FTM driver*/ + WDI_DriverType wdiDriverType; + + /*Should device enable frame translation */ + wpt_uint8 bFrameTransEnabled; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + /*Indication callback given by UMAC to be called by the WLAN DAL when it + wishes to send something back independent of a request*/ + WDI_LowLevelIndCBType wdiLowLevelIndCB; + + /*The user data passed in by UMAC, it will be sent back when the indication + function pointer will be called */ + void* pIndUserData; +}WDI_StartReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_StartRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Max number of STA supported by the device*/ + wpt_uint8 ucMaxStations; + + /*Max number of BSS supported by the device*/ + wpt_uint8 ucMaxBssids; + + /*Version of the WLAN HAL API with which we were compiled*/ + WDI_WlanVersionType wlanCompiledVersion; + + /*Version of the WLAN HAL API that was reported*/ + WDI_WlanVersionType wlanReportedVersion; + + /*WCNSS Software version string*/ + wpt_uint8 wcnssSoftwareVersion[WDI_VERSION_LENGTH]; + + /*WCNSS Hardware version string*/ + wpt_uint8 wcnssHardwareVersion[WDI_VERSION_LENGTH]; +}WDI_StartRspParamsType; + + +/*--------------------------------------------------------------------------- + WDI_StopType +---------------------------------------------------------------------------*/ +typedef enum +{ + /*Device is being stopped due to a reset*/ + WDI_STOP_TYPE_SYS_RESET, + + /*Device is being stopped due to entering deep sleep*/ + WDI_STOP_TYPE_SYS_DEEP_SLEEP, + + /*Device is being stopped because the RF needs to shut off + (e.g.:Airplane mode)*/ + WDI_STOP_TYPE_RF_KILL +}WDI_StopType; + +/*--------------------------------------------------------------------------- + WDI_StopReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + + /*The reason for which the device is being stopped*/ + WDI_StopType wdiStopReason; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_StopReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_ScanMode +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_SCAN_MODE_NORMAL = 0, + WDI_SCAN_MODE_LEARN, + WDI_SCAN_MODE_SCAN, + WDI_SCAN_MODE_PROMISC, + WDI_SCAN_MODE_SUSPEND_LINK, + WDI_SCAN_MODE_ROAM_SCAN, + WDI_SCAN_MODE_ROAM_SUSPEND_LINK, + +} WDI_ScanMode; + +/*--------------------------------------------------------------------------- + WDI_ScanEntry +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx[WDI_NUM_BSSID]; + wpt_uint8 activeBSScnt; +}WDI_ScanEntry; + +/*--------------------------------------------------------------------------- + WDI_InitScanReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*LEARN - AP Role + SCAN - STA Role*/ + WDI_ScanMode wdiScanMode; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Whether BSS needs to be notified*/ + wpt_boolean bNotifyBSS; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + wpt_uint8 ucFrameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + wpt_uint8 ucFrameLength; + + /*Pointer to the MAC frame buffer. Used only if ucFrameLength is non-zero.*/ + WDI_MacMgmtHdr wdiMACMgmtHdr; + + /*Entry to hold number of active BSS to send NULL frames before + * initiating SCAN*/ + WDI_ScanEntry wdiScanEntry; + + /* Flag to enable/disable Single NOA*/ + wpt_boolean bUseNOA; + + /* Indicates the scan duration (in ms) */ + wpt_uint16 scanDuration; + +}WDI_InitScanReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_InitScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The info associated with the request that needs to be sent over to the + device*/ + WDI_InitScanReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_InitScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_StartScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to scan*/ + wpt_uint8 ucChannel; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_StartScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_StartScanRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the status of the operation */ + WDI_Status wdiStatus; + +#if defined WLAN_FEATURE_VOWIFI + wpt_uint32 aStartTSF[2]; + wpt_int8 ucTxMgmtPower; +#endif +}WDI_StartScanRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EndScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to stop scanning. Not used really. But retained + for symmetry with "start Scan" message. It can also help in error + check if needed.*/ + wpt_uint8 ucChannel; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EndScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_PhyChanBondState +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_PHY_SINGLE_CHANNEL_CENTERED = 0, + WDI_PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, + WDI_PHY_DOUBLE_CHANNEL_CENTERED = 2, + WDI_PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, +#ifdef WLAN_FEATURE_11AC + WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + WDI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + WDI_MAX_CB_STATE +} WDI_PhyChanBondState; + +/*--------------------------------------------------------------------------- + WDI_FinishScanReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*LEARN - AP Role + SCAN - STA Role*/ + WDI_ScanMode wdiScanMode; + + /*Operating channel to tune to.*/ + wpt_uint8 ucCurrentOperatingChannel; + + /*Channel Bonding state If 20/40 MHz is operational, this will indicate the + 40 MHz extension channel in combination with the control channel*/ + WDI_PhyChanBondState wdiCBState; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Whether BSS needs to be notified*/ + wpt_boolean bNotifyBSS; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + wpt_uint8 ucFrameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + wpt_uint8 ucFrameLength; + + /*Pointer to the MAC frame buffer. Used only if ucFrameLength is non-zero.*/ + WDI_MacMgmtHdr wdiMACMgmtHdr; + + /*Entry to hold number of active BSS to send NULL frames after SCAN*/ + WDI_ScanEntry wdiScanEntry; + +}WDI_FinishScanReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SwitchChReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to switch to.*/ + wpt_uint8 ucChannel; + + /*Local power constraint*/ + wpt_uint8 ucLocalPowerConstraint; + + /*Secondary channel offset */ + WDI_HTSecondaryChannelOffset wdiSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_VOWIFI + wpt_int8 cMaxTxPower; + + /*Self STA Mac address*/ + wpt_macAddr macSelfStaMacAddr; +#endif + /* VO Wifi comment: BSSID is needed to identify which session issued this request. As the + request has power constraints, this should be applied only to that session */ + /* V IMP: Keep bssId field at the end of this msg. It is used to mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since it is at the end of this struct + */ + wpt_macAddr macBSSId; + +}WDI_SwitchChReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SwitchChReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Channel Info*/ + WDI_SwitchChReqInfoType wdiChInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SwitchChReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_FinishScanReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Finish Scan request that will be sent down to the device*/ + WDI_FinishScanReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_FinishScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_JoinReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the BSSID to which STA is going to associate*/ + wpt_macAddr macBSSID; + + /*Indicates the MAC Address of the current Self STA*/ + wpt_macAddr macSTASelf; + + /*Indicates the link State determining the entity Type e.g. BTAMP-STA, STA etc.*/ + wpt_uint32 linkState; + + /*Indicates the channel to switch to.*/ + WDI_SwitchChReqInfoType wdiChannelInfo; + +}WDI_JoinReqInfoType; + +typedef enum +{ + eWDI_CHANNEL_SWITCH_SOURCE_SCAN, + eWDI_CHANNEL_SWITCH_SOURCE_LISTEN, + eWDI_CHANNEL_SWITCH_SOURCE_MCC, + eWDI_CHANNEL_SWITCH_SOURCE_CSA, + eWDI_CHANNEL_SWITCH_SOURCE_MAX = 0x7FFFFFFF +} WDI_ChanSwitchSource; + +/*--------------------------------------------------------------------------- + WDI_SwitchChReqInfoType_V1 +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the channel to switch to.*/ + wpt_uint8 ucChannel; + + /*Local power constraint*/ + wpt_uint8 ucLocalPowerConstraint; + + /*Secondary channel offset */ + WDI_HTSecondaryChannelOffset wdiSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_VOWIFI + wpt_int8 cMaxTxPower; + /*Self STA Mac address*/ + wpt_macAddr macSelfStaMacAddr; +#endif + /* VO Wifi comment: BSSID is needed to identify which session + issued this request. As the request has power constraints, this + should be applied only to that session + */ + /* V IMP: Keep bssId field at the end of this msg. It is used to + maintain backward compatibility by way of ignoring if using new + host/old FW or old host/new FW since it is at the end of this struct + */ + wpt_macAddr macBSSId; + /* Source of Channel Switch */ + WDI_ChanSwitchSource channelSwitchSrc; +}WDI_SwitchChReqInfoType_V1; + +/*-------------------------------------------------------------------- + WDI_SwitchChReqParamsType_V1 +----------------------------------------------------------------------*/ +typedef struct +{ + /*Channel Info*/ + WDI_SwitchChReqInfoType_V1 wdiChInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SwitchChReqParamsType_V1; + +/*--------------------------------------------------------------------------- + WDI_JoinReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Join request that will be sent down to the device*/ + WDI_JoinReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_JoinReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_BssType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_INFRASTRUCTURE_MODE, + WDI_INFRA_AP_MODE, //Added for softAP support + WDI_IBSS_MODE, + WDI_BTAMP_STA_MODE, + WDI_BTAMP_AP_MODE, + WDI_BSS_AUTO_MODE, +}WDI_BssType; + +/*--------------------------------------------------------------------------- + WDI_NwType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_11A_NW_TYPE, + WDI_11B_NW_TYPE, + WDI_11G_NW_TYPE, + WDI_11N_NW_TYPE, +} WDI_NwType; + +/*--------------------------------------------------------------------------- + WDI_ConfigAction +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ADD_BSS, + WDI_UPDATE_BSS +} WDI_ConfigAction; + +/*--------------------------------------------------------------------------- + WDI_HTOperatingMode +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_HT_OP_MODE_PURE, + WDI_HT_OP_MODE_OVERLAP_LEGACY, + WDI_HT_OP_MODE_NO_LEGACY_20MHZ_HT, + WDI_HT_OP_MODE_MIXED + +} WDI_HTOperatingMode; + + +/*--------------------------------------------------------------------------- + WDI_STAEntryType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_STA_ENTRY_SELF, + WDI_STA_ENTRY_PEER, + WDI_STA_ENTRY_BSSID, + WDI_STA_ENTRY_BCAST, +#ifdef FEATURE_WLAN_TDLS + WDI_STA_ENTRY_TDLS_PEER, +#endif +}WDI_STAEntryType; + +/*--------------------------------------------------------------------------- + WDI_ConfigActionType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ADD_STA, + WDI_UPDATE_STA +} WDI_ConfigActionType; + +/*---------------------------------------------------------------------------- + Each station added has a rate mode which specifies the sta attributes + ----------------------------------------------------------------------------*/ +typedef enum +{ + WDI_RESERVED_1 = 0, + WDI_RESERVED_2, + WDI_RESERVED_3, + WDI_11b, + WDI_11bg, + WDI_11a, + WDI_11n, +} WDI_RateModeType; + +/*--------------------------------------------------------------------------- + WDI_SupportedRatesType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + WDI_RateModeType opRateMode; + + /* 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps */ + wpt_uint16 llbRates[WDI_NUM_11B_RATES]; + wpt_uint16 llaRates[WDI_NUM_11A_RATES]; + wpt_uint16 aLegacyRates[WDI_NUM_POLARIS_RATES]; + + /*Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + First 26 bits are reserved for those Titan rates and + the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved.*/ + wpt_uint32 uEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + wpt_uint8 aSupportedMCSSet[WDI_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + wpt_uint16 aRxHighestDataRate; + + +#ifdef WLAN_FEATURE_11AC + /*Indicates the Maximum MCS that can be received for each number + of spacial streams */ + wpt_uint16 vhtRxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to receive*/ + wpt_uint16 vhtRxHighestDataRate; + /*Indicates the Maximum MCS that can be transmitted for each number + of spacial streams */ + wpt_uint16 vhtTxMCSMap; + /*Indicate the highest VHT data rate that the STA is able to transmit*/ + wpt_uint16 vhtTxHighestDataRate; +#endif + +} WDI_SupportedRates; + +/*-------------------------------------------------------------------------- + WDI_HTMIMOPowerSaveState + Spatial Multiplexing(SM) Power Save mode + --------------------------------------------------------------------------*/ +typedef enum +{ + WDI_HT_MIMO_PS_STATIC = 0, // Static SM Power Save mode + WDI_HT_MIMO_PS_DYNAMIC = 1, // Dynamic SM Power Save mode + WDI_HT_MIMO_PS_NA = 2, // reserved + WDI_HT_MIMO_PS_NO_LIMIT = 3, // SM Power Save disabled +} WDI_HTMIMOPowerSaveState; + +/*--------------------------------------------------------------------------- + WDI_ConfigStaReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSSID of STA*/ + wpt_macAddr macBSSID; + + /*ASSOC ID, as assigned by UMAC*/ + wpt_uint16 usAssocId; + + /*Used for configuration of different HW modules.*/ + WDI_STAEntryType wdiSTAType; + + /*STA Index */ + wpt_uint8 staIdx; + + /*Short Preamble Supported.*/ + wpt_uint8 ucShortPreambleSupported; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /*Listen interval of the STA*/ + wpt_uint16 usListenInterval; + + /*Support for 11e/WMM*/ + wpt_uint8 ucWMMEnabled; + + /*11n HT capable STA*/ + wpt_uint8 ucHTCapable; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + wpt_uint8 ucTXChannelWidthSet; + + /*RIFS mode 0 - NA, 1 - Allowed*/ + wpt_uint8 ucRIFSMode; + + /*L-SIG TXOP Protection mechanism + 0 - No Support, 1 - Supported + SG - there is global field*/ + wpt_uint8 ucLSIGTxopProtection; + + /*Max Ampdu Size supported by STA. Device programming. + 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ + wpt_uint8 ucMaxAmpduSize; + + /*Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4)*/ + wpt_uint8 ucMaxAmpduDensity; + + /*Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes*/ + wpt_uint8 ucMaxAmsduSize; + + /*Short GI support for 40Mhz packets*/ + wpt_uint8 ucShortGI40Mhz; + + /*Short GI support for 20Mhz packets*/ + wpt_uint8 ucShortGI20Mhz; + + /*These rates are the intersection of peer and self capabilities.*/ + WDI_SupportedRates wdiSupportedRates; + + /*Robust Management Frame (RMF) enabled/disabled*/ + wpt_uint8 ucRMFEnabled; + + /* The unicast encryption type in the association */ + wpt_uint32 ucEncryptType; + + /*HAL should update the existing STA entry, if this flag is set. UMAC + will set this flag in case of RE-ASSOC, where we want to reuse the old + STA ID.*/ + WDI_ConfigActionType wdiAction; + + /*U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO + */ + wpt_uint8 ucAPSD; + + /*Max SP Length*/ + wpt_uint8 ucMaxSPLen; + + /*11n Green Field preamble support*/ + wpt_uint8 ucGreenFieldCapable; + + /*MIMO Power Save mode*/ + WDI_HTMIMOPowerSaveState wdiMIMOPS; + + /*Delayed BA Support*/ + wpt_uint8 ucDelayedBASupport; + + /*Max AMPDU duration in 32us*/ + wpt_uint8 us32MaxAmpduDuratio; + + /*HT STA should set it to 1 if it is enabled in BSS + HT STA should set it to 0 if AP does not support it. This indication is + sent to HAL and HAL uses this flag to pickup up appropriate 40Mhz rates. + */ + wpt_uint8 ucDsssCckMode40Mhz; + + wpt_uint8 ucP2pCapableSta; +#ifdef WLAN_FEATURE_11AC + wpt_uint8 ucVhtCapableSta; + wpt_uint8 ucVhtTxChannelWidthSet; + wpt_uint8 ucVhtTxBFEnabled; + wpt_uint8 vhtTxMUBformeeCapable; +#endif + + wpt_uint8 ucHtLdpcEnabled; + wpt_uint8 ucVhtLdpcEnabled; +}WDI_ConfigStaReqInfoType; + + +/*--------------------------------------------------------------------------- + WDI_RateSet + + 12 Bytes long because this structure can be used to represent rate + and extended rate set IEs + The parser assume this to be at least 12 +---------------------------------------------------------------------------*/ +#define WDI_RATESET_EID_MAX 12 + +typedef struct +{ + wpt_uint8 ucNumRates; + wpt_uint8 aRates[WDI_RATESET_EID_MAX]; +} WDI_RateSet; + +/*--------------------------------------------------------------------------- + WDI_AciAifsnType + access category record +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 rsvd : 1; + wpt_uint8 aci : 2; + wpt_uint8 acm : 1; + wpt_uint8 aifsn : 4; +} WDI_AciAifsnType; + +/*--------------------------------------------------------------------------- + WDI_CWType + contention window size +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 max : 4; + wpt_uint8 min : 4; +} WDI_CWType; + +/*--------------------------------------------------------------------------- + WDI_EdcaParamRecord +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Access Category Record*/ + WDI_AciAifsnType wdiACI; + + /*Contention WIndow Size*/ + WDI_CWType wdiCW; + + /*TX Oportunity Limit*/ + wpt_uint16 usTXOPLimit; +} WDI_EdcaParamRecord; + +/*--------------------------------------------------------------------------- + WDI_EDCAParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index*/ + wpt_uint8 ucBSSIdx; + + /*?*/ + wpt_boolean bHighPerformance; + + /*Best Effort*/ + WDI_EdcaParamRecord wdiACBE; + + /*Background*/ + WDI_EdcaParamRecord wdiACBK; + + /*Video*/ + WDI_EdcaParamRecord wdiACVI; + + /*Voice*/ + WDI_EdcaParamRecord acvo; // voice +} WDI_EDCAParamsType; + +/* operMode in ADD BSS message */ +#define WDI_BSS_OPERATIONAL_MODE_AP 0 +#define WDI_BSS_OPERATIONAL_MODE_STA 1 + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*BSS Index*/ + wpt_uint8 ucBSSIdx; + + /*Unicast DPU signature*/ + wpt_uint8 ucUcastSig; + + /*Broadcast DPU Signature*/ + wpt_uint8 ucBcastSig; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /*BSS STA ID*/ + wpt_uint8 ucSTAIdx; + +#ifdef WLAN_FEATURE_VOWIFI + /*HAL fills in the tx power used for mgmt frames in this field */ + wpt_int8 ucTxMgmtPower; +#endif + +}WDI_ConfigBSSRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelBSSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelBSSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelBSSRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + wpt_uint8 ucBssIdx; + +}WDI_DelBSSRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigSTARspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Idx allocated by HAL*/ + wpt_uint8 ucSTAIdx; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /* BSSID Index of BSS to which the station is associated */ + wpt_uint8 ucBssIdx; + + /* DPU Index - PTK */ + wpt_uint8 ucDpuIndex; + + /* Bcast DPU Index - GTK */ + wpt_uint8 ucBcastDpuIndex; + + /* Management DPU Index - IGTK - Why is it called bcastMgmtDpuIdx? */ + wpt_uint8 ucBcastMgmtDpuIdx; + + /*Unicast DPU signature*/ + wpt_uint8 ucUcastSig; + + /*Broadcast DPU Signature*/ + wpt_uint8 ucBcastSig; + + /* IGTK DPU signature*/ + wpt_uint8 ucMgmtSig; + +}WDI_ConfigSTARspParamsType; + +/*--------------------------------------------------------------------------- + WDI_PostAssocRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Parameters related to the BSS*/ + WDI_ConfigBSSRspParamsType bssParams; + + /*Parameters related to the self STA*/ + WDI_ConfigSTARspParamsType staParams; + +}WDI_PostAssocRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ + wpt_uint8 ucSTAIdx; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelSTAReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTARspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ + wpt_uint8 ucSTAIdx; +}WDI_DelSTARspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EncryptType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ENCR_NONE, + WDI_ENCR_WEP40, + WDI_ENCR_WEP104, + WDI_ENCR_TKIP, + WDI_ENCR_CCMP, +#if defined(FEATURE_WLAN_WAPI) + WDI_ENCR_WPI, +#endif + WDI_ENCR_AES_128_CMAC +} WDI_EncryptType; + +/*--------------------------------------------------------------------------- + WDI_KeyDirectionType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_TX_ONLY, + WDI_RX_ONLY, + WDI_TX_RX, + WDI_TX_DEFAULT, + WDI_DONOT_USE_KEY_DIRECTION +} WDI_KeyDirectionType; + +#define WDI_MAX_ENCR_KEYS 4 +#define WDI_MAX_KEY_LENGTH 32 +#if defined(FEATURE_WLAN_WAPI) +#define WDI_MAX_KEY_RSC_LEN 16 +#define WDI_WAPI_KEY_RSC_LEN 16 +#else +#define WDI_MAX_KEY_RSC_LEN 8 +#endif + +typedef struct +{ + /* Key ID */ + wpt_uint8 keyId; + /* 0 for multicast */ + wpt_uint8 unicast; + /* Key Direction */ + WDI_KeyDirectionType keyDirection; + /* Usage is unknown */ + wpt_uint8 keyRsc[WDI_MAX_KEY_RSC_LEN]; + /* =1 for authenticator, =0 for supplicant */ + wpt_uint8 paeRole; + wpt_uint16 keyLength; + wpt_uint8 key[WDI_MAX_KEY_LENGTH]; + +}WDI_KeysType; + +/*--------------------------------------------------------------------------- + WDI_SetBSSKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*Number of keys*/ + wpt_uint8 ucNumKeys; + + /*Array of keys.*/ + WDI_KeysType aKeys[WDI_MAX_ENCR_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + wpt_uint8 ucSingleTidRc; +}WDI_SetBSSKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetBSSKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info */ + WDI_SetBSSKeyReqInfoType wdiBSSKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetBSSKeyReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WepType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_WEP_STATIC, + WDI_WEP_DYNAMIC + +} WDI_WepType; + +/*--------------------------------------------------------------------------- + WDI_RemoveBSSKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*Key Id*/ + wpt_uint8 ucKeyId; + + /*STATIC/DYNAMIC. Used in Nullifying in Key Descriptors for Static/Dynamic + keys*/ + WDI_WepType wdiWEPType; +}WDI_RemoveBSSKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_RemoveBSSKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info */ + WDI_RemoveBSSKeyReqInfoType wdiKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_RemoveBSSKeyReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetSTAKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*STATIC/DYNAMIC*/ + WDI_WepType wdiWEPType; + + /*Default WEP key, valid only for static WEP, must between 0 and 3.*/ + wpt_uint8 ucDefWEPIdx; + + /*Number of keys*/ + wpt_uint8 ucNumKeys; + + /*Array of keys.*/ + WDI_KeysType wdiKey[WDI_MAX_ENCR_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + wpt_uint8 ucSingleTidRc; +}WDI_SetSTAKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Peer BSSID*/ + wpt_macAddr macBSSID; + + /*Self MAC Address*/ + wpt_macAddr macSelfAddr; + + /*BSS Type*/ + WDI_BssType wdiBSSType; + + /*Operational Mode: AP =0, STA = 1*/ + wpt_uint8 ucOperMode; + + /*Network Type*/ + WDI_NwType wdiNWType; + + /*Used to classify PURE_11G/11G_MIXED to program MTU*/ + wpt_uint8 ucShortSlotTimeSupported; + + /*Co-exist with 11a STA*/ + wpt_uint8 ucllaCoexist; + + /*Co-exist with 11b STA*/ + wpt_uint8 ucllbCoexist; + + /*Co-exist with 11g STA*/ + wpt_uint8 ucllgCoexist; + + /*Coexistence with 11n STA*/ + wpt_uint8 ucHT20Coexist; + + /*Non GF coexist flag*/ + wpt_uint8 ucllnNonGFCoexist; + + /*TXOP protection support*/ + wpt_uint8 ucTXOPProtectionFullSupport; + + /*RIFS mode*/ + wpt_uint8 ucRIFSMode; + + /*Beacon Interval in TU*/ + wpt_uint16 usBeaconInterval; + + /*DTIM period*/ + wpt_uint8 ucDTIMPeriod; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + wpt_uint8 ucTXChannelWidthSet; + + /*Operating channel*/ + wpt_uint8 ucCurrentOperChannel; + + /*Extension channel for channel bonding*/ + wpt_uint8 ucCurrentExtChannel; + + /*Context of the station being added in HW.*/ + WDI_ConfigStaReqInfoType wdiSTAContext; + + /*SSID of the BSS*/ + WDI_MacSSid wdiSSID; + + /*HAL should update the existing BSS entry, if this flag is set. UMAC will + set this flag in case of RE-ASSOC, where we want to reuse the old BSSID*/ + WDI_ConfigAction wdiAction; + + /*Basic Rate Set*/ + WDI_RateSet wdiRateSet; + + /*Enable/Disable HT capabilities of the BSS*/ + wpt_uint8 ucHTCapable; + + /* Enable/Disable OBSS protection */ + wpt_uint8 ucObssProtEnabled; + + /*RMF enabled/disabled*/ + wpt_uint8 ucRMFEnabled; + + /*Determines the current HT Operating Mode operating mode of the + 802.11n STA*/ + WDI_HTOperatingMode wdiHTOperMod; + + /*Dual CTS Protection: 0 - Unused, 1 - Used*/ + wpt_uint8 ucDualCTSProtection; + + /* Probe Response Max retries */ + wpt_uint8 ucMaxProbeRespRetryLimit; + + /* To Enable Hidden ssid */ + wpt_uint8 bHiddenSSIDEn; + + /* To Enable Disable FW Proxy Probe Resp */ + wpt_uint8 bProxyProbeRespEn; + + /* Boolean to indicate if EDCA params are valid. UMAC might not have valid + EDCA params or might not desire to apply EDCA params during config BSS. + 0 implies Not Valid ; Non-Zero implies valid*/ + wpt_uint8 ucEDCAParamsValid; + + /*EDCA Parameters for BK*/ + WDI_EdcaParamRecord wdiBKEDCAParams; + + /*EDCA Parameters for BE*/ + WDI_EdcaParamRecord wdiBEEDCAParams; + + /*EDCA Parameters for VI*/ + WDI_EdcaParamRecord wdiVIEDCAParams; + + /*EDCA Parameters for VO*/ + WDI_EdcaParamRecord wdiVOEDCAParams; + +#ifdef WLAN_FEATURE_VOWIFI + /*max power to be used after applying the power constraint, if any */ + wpt_int8 cMaxTxPower; +#endif + + /* Persona for the BSS can be STA,AP,GO,CLIENT, same as Connection Mode */ + wpt_uint8 ucPersona; + + /* Spectrum Mangement Indicator */ + wpt_uint8 bSpectrumMgtEn; + +#ifdef WLAN_FEATURE_VOWIFI_11R + wpt_uint8 bExtSetStaKeyParamValid; + WDI_SetSTAKeyReqInfoType wdiExtSetKeyParam; +#endif + +#ifdef WLAN_FEATURE_11AC + wpt_uint8 ucVhtCapableSta; + wpt_uint8 ucVhtTxChannelWidthSet; +#endif + +}WDI_ConfigBSSReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_PostAssocReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Config STA arguments.*/ + WDI_ConfigStaReqInfoType wdiSTAParams; + + /*Config BSS Arguments*/ + WDI_ConfigBSSReqInfoType wdiBSSParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_PostAssocReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Join request that will be sent down to the device*/ + WDI_ConfigBSSReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigBSSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetSTAKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info*/ + WDI_SetSTAKeyReqInfoType wdiKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetSTAKeyReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_RemoveSTAKeyReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Encryption Type used with peer*/ + WDI_EncryptType wdiEncType; + + /*Key Id*/ + wpt_uint8 ucKeyId; + + /*Whether to invalidate the Broadcast key or Unicast key. In case of WEP, + the same key is used for both broadcast and unicast.*/ + wpt_uint8 ucUnicast; +}WDI_RemoveSTAKeyReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_RemoveSTAKeyReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Key Info */ + WDI_RemoveSTAKeyReqInfoType wdiKeyInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_RemoveSTAKeyReqParamsType; + +/*--------------------------------------------------------------------------- + QOS Parameters +---------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + WDI_TSInfoTfc +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 ackPolicy:2; + wpt_uint16 userPrio:3; + wpt_uint16 psb:1; + wpt_uint16 aggregation : 1; + wpt_uint16 accessPolicy : 2; + wpt_uint16 direction : 2; + wpt_uint16 tsid : 4; + wpt_uint16 trafficType : 1; +} WDI_TSInfoTfc; + +/*--------------------------------------------------------------------------- + WDI_TSInfoSch +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 rsvd : 7; + wpt_uint8 schedule : 1; +} WDI_TSInfoSch; + +/*--------------------------------------------------------------------------- + WDI_TSInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_TSInfoTfc wdiTraffic; + WDI_TSInfoSch wdiSchedule; +} WDI_TSInfoType; + +/*--------------------------------------------------------------------------- + WDI_TspecIEType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucType; + wpt_uint8 ucLength; + WDI_TSInfoType wdiTSinfo; + wpt_uint16 usNomMsduSz; + wpt_uint16 usMaxMsduSz; + wpt_uint32 uMinSvcInterval; + wpt_uint32 uMaxSvcInterval; + wpt_uint32 uInactInterval; + wpt_uint32 uSuspendInterval; + wpt_uint32 uSvcStartTime; + wpt_uint32 uMinDataRate; + wpt_uint32 uMeanDataRate; + wpt_uint32 uPeakDataRate; + wpt_uint32 uMaxBurstSz; + wpt_uint32 uDelayBound; + wpt_uint32 uMinPhyRate; + wpt_uint16 usSurplusBw; + wpt_uint16 usMediumTime; +}WDI_TspecIEType; + +/*--------------------------------------------------------------------------- + WDI_AddTSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Identifier for TSpec*/ + wpt_uint16 ucTspecIdx; + + /*Tspec IE negotiated OTA*/ + WDI_TspecIEType wdiTspecIE; + + /*UAPSD delivery and trigger enabled flags */ + wpt_uint8 ucUapsdFlags; + + /*SI for each AC*/ + wpt_uint8 ucServiceInterval[WDI_MAX_NO_AC]; + + /*Suspend Interval for each AC*/ + wpt_uint8 ucSuspendInterval[WDI_MAX_NO_AC]; + + /*DI for each AC*/ + wpt_uint8 ucDelayedInterval[WDI_MAX_NO_AC]; + +}WDI_AddTSReqInfoType; + + +/*--------------------------------------------------------------------------- + WDI_AddTSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*TSpec Info */ + WDI_AddTSReqInfoType wdiTsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddTSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelTSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Identifier for TSpec*/ + wpt_uint16 ucTspecIdx; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; +}WDI_DelTSReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_DelTSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Del TSpec Info*/ + WDI_DelTSReqInfoType wdiDelTSInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelTSReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateEDCAInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint16 ucBssIdx; + + /*EDCA params for BE*/ + WDI_EdcaParamRecord wdiEdcaBEInfo; + + /*EDCA params for BK*/ + WDI_EdcaParamRecord wdiEdcaBKInfo; + + /*EDCA params for VI*/ + WDI_EdcaParamRecord wdiEdcaVIInfo; + + /*EDCA params for VO*/ + WDI_EdcaParamRecord wdiEdcaVOInfo; + +}WDI_UpdateEDCAInfoType; + +/*--------------------------------------------------------------------------- + WDI_UpdateEDCAParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*EDCA Info */ + WDI_UpdateEDCAInfoType wdiEDCAInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateEDCAParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBASessionReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /*The peer mac address*/ + wpt_macAddr macPeerAddr; + + /*TID for which BA was negotiated*/ + wpt_uint8 ucBaTID; + + /*Delayed or imediate */ + wpt_uint8 ucBaPolicy; + + /*The number of buffers for this TID (baTID)*/ + wpt_uint16 usBaBufferSize; + + /*BA timeout in TU's*/ + wpt_uint16 usBaTimeout; + + /*b0..b3 - Fragment Number - Always set to 0 + b4..b15 - Starting Sequence Number of first MSDU for which this BA is setup*/ + wpt_uint16 usBaSSN; + + /*Originator/Recipient*/ + wpt_uint8 ucBaDirection; + +}WDI_AddBASessionReqinfoType; + + +/*--------------------------------------------------------------------------- + WDI_AddBASessionReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Session Info Type*/ + WDI_AddBASessionReqinfoType wdiBASessionInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddBASessionReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBASessionRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /* Dialog token */ + wpt_uint8 ucBaDialogToken; + + /* TID for which the BA session has been setup */ + wpt_uint8 ucBaTID; + + /* BA Buffer Size allocated for the current BA session */ + wpt_uint8 ucBaBufferSize; + + /* BA session ID */ + wpt_uint16 usBaSessionID; + + /* Reordering Window buffer */ + wpt_uint8 ucWinSize; + + /*Station Index to id the sta */ + wpt_uint8 ucSTAIdx; + + /* Starting Sequence Number */ + wpt_uint16 usBaSSN; + +}WDI_AddBASessionRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_SpoofMacAddrRspParamType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* wdi status */ + wpt_uint32 wdiStatus; + + /* Reserved Field */ + wpt_uint32 reserved; + +}WDI_SpoofMacAddrRspParamType; +/*--------------------------------------------------------------------------- + WDI_GetFrameLogRspParamType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* wdi status */ + wpt_uint32 wdiStatus; +}WDI_GetFrameLogRspParamType; +/*--------------------------------------------------------------------------- + WDI_FWLoggingInitRspParamType +---------------------------------------------------------------------------*/ +typedef struct +{ + //FW mail box address + wpt_uint64 logMailBoxAddr; + wpt_uint32 status; + //Logging mail box version + wpt_uint8 logMailBoxVer; + //Qshrink is enabled + wpt_boolean logCompressEnabled; + /* store the size of fw mem dump */ + wpt_uint32 fw_mem_dump_max_size; + //Reserved for future purpose + wpt_uint32 reserved1; + wpt_uint32 reserved2; +}WDI_FWLoggingInitRspParamType; + +typedef struct +{ + /* wdi status */ + wpt_uint32 status; +}WDI_RssiMonitorStartRspParamType; + +typedef struct +{ + /* wdi status */ + wpt_uint32 status; +}WDI_RssiMonitorStopRspParamType; +/*--------------------------------------------------------------------------- + WDI_FatalEventLogsRspParamType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* wdi status */ + wpt_uint32 wdiStatus; +}WDI_FatalEventLogsRspParamType; + +/*--------------------------------------------------------------------------- + WDI_AddBAReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /* Session Id */ + wpt_uint8 ucBaSessionID; + + /* Reorder Window Size */ + wpt_uint8 ucWinSize; + +#ifdef FEATURE_ON_CHIP_REORDERING + wpt_boolean bIsReorderingDoneOnChip; +#endif + +}WDI_AddBAReqinfoType; + + +/*--------------------------------------------------------------------------- + WDI_AddBAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Info Type*/ + WDI_AddBAReqinfoType wdiBAInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddBAReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_AddBARspinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /* Dialog token */ + wpt_uint8 ucBaDialogToken; + +}WDI_AddBARspinfoType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBAReqCandidateType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* STA index */ + wpt_uint8 ucSTAIdx; + + /* TID bit map for the STA's*/ + wpt_uint8 ucTidBitmap; + +}WDI_TriggerBAReqCandidateType; + + +/*--------------------------------------------------------------------------- + WDI_TriggerBAReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /* Session Id */ + wpt_uint8 ucBASessionID; + + /* Trigger BA Request candidate count */ + wpt_uint16 usBACandidateCnt; + + /* WDI_TriggerBAReqCandidateType followed by this*/ + +}WDI_TriggerBAReqinfoType; + + +/*--------------------------------------------------------------------------- + WDI_TriggerBAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Trigger Info Type*/ + WDI_TriggerBAReqinfoType wdiTriggerBAInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_TriggerBAReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_AddBAInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 fBaEnable : 1; + wpt_uint16 startingSeqNum: 12; + wpt_uint16 reserved : 3; +}WDI_AddBAInfoType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBARspCandidateType +---------------------------------------------------------------------------*/ +#define STA_MAX_TC 8 + +typedef struct +{ + /* STA index */ + wpt_macAddr macSTA; + + /* BA Info */ + WDI_AddBAInfoType wdiBAInfo[STA_MAX_TC]; +}WDI_TriggerBARspCandidateType; + +/*--------------------------------------------------------------------------- + WDI_TriggerBARspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /* Trigger BA response candidate count */ + wpt_uint16 usBaCandidateCnt; + + /* WDI_TriggerBARspCandidateType followed by this*/ + +}WDI_TriggerBARspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelBAReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which BA is added..*/ + wpt_uint8 ucSTAIdx; + + /*TID for which BA was negotiated*/ + wpt_uint8 ucBaTID; + + /*Originator/Recipient*/ + wpt_uint8 ucBaDirection; + +}WDI_DelBAReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_DelBAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Info */ + WDI_DelBAReqinfoType wdiBAInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelBAReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateChannelReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /** primary 20 MHz channel frequency in mhz */ + wpt_uint32 mhz; + /** Center frequency 1 in MHz*/ + wpt_uint32 band_center_freq1; + /** Center frequency 2 in MHz - valid only for 11acvht 80plus80 mode*/ + wpt_uint32 band_center_freq2; + /* The first 26 bits are a bit mask to indicate any channel flags, + (see WLAN_HAL_CHAN_FLAG*) + The last 6 bits indicate the mode (see tChannelPhyModeType)*/ + wpt_uint32 channel_info; + /** contains min power, max power, reg power and reg class id. */ + wpt_uint32 reg_info_1; + /** contains antennamax */ + wpt_uint32 reg_info_2; +}WDI_UpdateChannelReqinfoType; + +typedef struct +{ + wpt_uint8 numchan; + WDI_UpdateChannelReqinfoType *pchanParam; +}WDI_UpdateChannelReqType; +/*--------------------------------------------------------------------------- + WDI_UpdateChReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BA Info */ + WDI_UpdateChannelReqType wdiUpdateChanParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateChReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SwitchCHRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Indicates the channel that WLAN is on*/ + wpt_uint8 ucChannel; + +#ifdef WLAN_FEATURE_VOWIFI + /*HAL fills in the tx power used for mgmt frames in this field.*/ + wpt_int8 ucTxMgmtPower; +#endif + +}WDI_SwitchCHRspParamsType; + +/*-------------------------------------------------------------------- + WDI_SwitchChRspParamsType_V1 +--------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*Indicates the channel that WLAN is on*/ + wpt_uint8 ucChannel; + +#ifdef WLAN_FEATURE_VOWIFI + /*HAL fills in the tx power used for mgmt frames in this field.*/ + wpt_int8 ucTxMgmtPower; +#endif + + /* Source of Channel Switch */ + WDI_ChanSwitchSource channelSwitchSrc; +}WDI_SwitchChRspParamsType_V1; + +/*--------------------------------------------------------------------------- + WDI_ConfigSTAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Info for the Join request that will be sent down to the device*/ + WDI_ConfigStaReqInfoType wdiReqInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigSTAReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_UpdateBeaconParamsInfoType +---------------------------------------------------------------------------*/ + +typedef struct +{ + /*BSS Index of the BSS*/ + wpt_uint8 ucBssIdx; + + /*shortPreamble mode. HAL should update all the STA rates when it + receives this message*/ + wpt_uint8 ucfShortPreamble; + /* short Slot time.*/ + wpt_uint8 ucfShortSlotTime; + /* Beacon Interval */ + wpt_uint16 usBeaconInterval; + /*Protection related */ + wpt_uint8 ucllaCoexist; + wpt_uint8 ucllbCoexist; + wpt_uint8 ucllgCoexist; + wpt_uint8 ucHt20MhzCoexist; + wpt_uint8 ucllnNonGFCoexist; + wpt_uint8 ucfLsigTXOPProtectionFullSupport; + wpt_uint8 ucfRIFSMode; + + wpt_uint16 usChangeBitmap; +}WDI_UpdateBeaconParamsInfoType; + +#ifdef WLAN_FEATURE_11AC +typedef struct +{ + wpt_uint16 opMode; + wpt_uint16 staId; +}WDI_UpdateVHTOpMode; +#endif + +/*--------------------------------------------------------------------------- + WDI_UpdateBeaconParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Update Beacon Params Info*/ + WDI_UpdateBeaconParamsInfoType wdiUpdateBeaconParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateBeaconParamsType; + +/*--------------------------------------------------------------------------- + WDI_SendBeaconParamsInfoType +---------------------------------------------------------------------------*/ + +typedef struct { + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /* Beacon data */ + wpt_uint8 beacon[WDI_BEACON_TEMPLATE_SIZE]; + + /* length of the template */ + wpt_uint32 beaconLength; + + /* TIM IE offset from the beginning of the template.*/ + wpt_uint32 timIeOffset; + + /* P2P IE offset from the beginning of the template */ + wpt_uint16 usP2PIeOffset; +} WDI_SendBeaconParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_SendBeaconParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Send Beacon Params Info*/ + WDI_SendBeaconParamsInfoType wdiSendBeaconParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SendBeaconParamsType; + +/*--------------------------------------------------------------------------- + WDI_LinkStateType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_LINK_IDLE_STATE = 0, + WDI_LINK_PREASSOC_STATE = 1, + WDI_LINK_POSTASSOC_STATE = 2, + WDI_LINK_AP_STATE = 3, + WDI_LINK_IBSS_STATE = 4, + + // BT-AMP Case + WDI_LINK_BTAMP_PREASSOC_STATE = 5, + WDI_LINK_BTAMP_POSTASSOC_STATE = 6, + WDI_LINK_BTAMP_AP_STATE = 7, + WDI_LINK_BTAMP_STA_STATE = 8, + + // Reserved for HAL internal use + WDI_LINK_LEARN_STATE = 9, + WDI_LINK_SCAN_STATE = 10, + WDI_LINK_FINISH_SCAN_STATE = 11, + WDI_LINK_INIT_CAL_STATE = 12, + WDI_LINK_FINISH_CAL_STATE = 13, + WDI_LINK_LISTEN_STATE = 14, + WDI_LINK_SEND_ACTION_STATE = 15, +#ifdef WLAN_FEATURE_LFR_MBB + WDI_LINK_PRE_AUTH_REASSOC_STATE = 17, +#endif + WDI_LINK_MAX = 0x7FFFFFFF +} WDI_LinkStateType; + +/*--------------------------------------------------------------------------- + WDI_SetLinkReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Link state*/ + WDI_LinkStateType wdiLinkState; + + /*BSSID of the BSS*/ + wpt_macAddr macSelfStaMacAddr; +}WDI_SetLinkReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetLinkReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_SetLinkReqInfoType wdiLinkInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetLinkReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_GetStatsParamsInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* categories of stats requested */ + wpt_uint32 uStatsMask; +}WDI_GetStatsParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_GetStatsReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Get Stats Params Info*/ + WDI_GetStatsParamsInfoType wdiGetStatsParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_GetStatsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_GetStatsRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*message type is same as the request type*/ + wpt_uint16 usMsgType; + + /* length of the entire request, includes the pStatsBuf length too*/ + wpt_uint16 usMsgLen; + + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* categories of stats requested */ + wpt_uint32 uStatsMask; + + /* The Stats buffer starts here and can be an aggregate of more than one statistics + * structure depending on statsMask.*/ +}WDI_GetStatsRspParamsType; + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiParamsInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* categories of stats requested */ + wpt_uint32 uStatsMask; +}WDI_GetRoamRssiParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Get Roam Rssi Params Info*/ + WDI_GetRoamRssiParamsInfoType wdiGetRoamRssiParamsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_GetRoamRssiReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucSTAIdx; + + /* roam rssi requested */ + wpt_int8 rssi; + + /* The Stats buffer starts here and can be an aggregate of more than one statistics + * structure depending on statsMask.*/ +}WDI_GetRoamRssiRspParamsType; +#endif + +#ifdef FEATURE_WLAN_ESE +/*--------------------------------------------------------------------------- + WDI_TSMStatsParamsInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the station for which Get Stats are requested..*/ + wpt_uint8 ucTid; + + wpt_macAddr bssid; +}WDI_TSMStatsParamsInfoType; + +/*--------------------------------------------------------------------------- + WDI_TSMStatsReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Get TSM Stats Params Info*/ + WDI_TSMStatsParamsInfoType wdiTsmStatsParamsInfo; + + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_TSMStatsReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_TSMStatsRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Indicates the status of the operation */ + WDI_Status wdiStatus; + + wpt_uint16 UplinkPktQueueDly; + wpt_uint16 UplinkPktQueueDlyHist[4]; + wpt_uint32 UplinkPktTxDly; + wpt_uint16 UplinkPktLoss; + wpt_uint16 UplinkPktCount; + wpt_uint8 RoamingCount; + wpt_uint16 RoamingDly; +}WDI_TSMStatsRspParamsType; + + +#endif +/*--------------------------------------------------------------------------- + WDI_UpdateCfgReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*This is a TLV formatted buffer containing all config values that can + be set through the DAL Interface + + The TLV is expected to be formatted like this: + + 0 7 15 31 .... + | CONFIG ID | CFG LEN | RESERVED | CFG BODY | + + Or from a C construct point of VU it would look like this: + + typedef struct WPT_PACK_POST + { + #ifdef WPT_BIG_ENDIAN + wpt_uint32 ucCfgId:8; + wpt_uint32 ucCfgLen:8; + wpt_uint32 usReserved:16; + #else + wpt_uint32 usReserved:16; + wpt_uint32 ucCfgLen:8; + wpt_uint32 ucCfgId:8; + #endif + + wpt_uint8 ucCfgBody[ucCfgLen]; + }WDI_ConfigType; + + Multiple such tuplets are to be placed in the config buffer. One for + each required configuration item: + + | TLV 1 | TLV2 | .... + + The buffer is expected to be a flat area of memory that can be manipulated + with standard memory routines. + + For more info please check paragraph 2.3.1 Config Structure from the + HAL LLD. + + For a list of accepted configuration list and IDs please look up + wlan_qct_dal_cfg.h + */ + void* pConfigBuffer; + + /*Length of the config buffer above*/ + wpt_uint32 uConfigBufferLen; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateCfgReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateProbeRspTemplateInfoType +---------------------------------------------------------------------------*/ +//Default Beacon template size +#define WDI_PROBE_RSP_TEMPLATE_SIZE 0x180 + +#define WDI_PROBE_REQ_BITMAP_IE_LEN 8 + +typedef struct +{ + /*BSSID for which the Probe Template is to be used*/ + wpt_macAddr macBSSID; + + /*Template Len*/ + wpt_uint32 uProbeRespTemplateLen; + + /*Bitmap for the IEs that are to be handled at SLM level*/ + wpt_uint32 uaProxyProbeReqValidIEBmap[WDI_PROBE_REQ_BITMAP_IE_LEN]; + + /*Probe response template*/ + wpt_uint8 *pProbeRespTemplate; + +}WDI_UpdateProbeRspTemplateInfoType; + +/*--------------------------------------------------------------------------- + WDI_UpdateProbeRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_UpdateProbeRspTemplateInfoType wdiProbeRspTemplateInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateProbeRspTemplateParamsType; + +/*--------------------------------------------------------------------------- + WDI_NvDownloadReqBlobInfo +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* Blob starting address*/ + void *pBlobAddress; + + /* Blob size */ + wpt_uint32 uBlobSize; + +}WDI_NvDownloadReqBlobInfo; + +/*--------------------------------------------------------------------------- + WDI_NvDownloadReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*NV Blob Info*/ + WDI_NvDownloadReqBlobInfo wdiBlobInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_NvDownloadReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_NvDownloadRspInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + +}WDI_NvDownloadRspInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerInfoType +---------------------------------------------------------------------------*/ + +typedef struct +{ + /*BSSID is needed to identify which session issued this request. As the request has + power constraints, this should be applied only to that session*/ + wpt_macAddr macBSSId; + + + wpt_macAddr macSelfStaMacAddr; + + /* In request power == MaxTxpower to be used.*/ + wpt_int8 ucPower; + +}WDI_SetMaxTxPowerInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPowerInfoType +---------------------------------------------------------------------------*/ + +typedef struct +{ + wpt_uint8 bssIdx; + /* In request power == MaxTxpower to be used.*/ + wpt_uint8 ucPower; + +}WDI_SetTxPowerInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_SetMaxTxPowerInfoType wdiMaxTxPowerInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetMaxTxPowerParamsType; + +/*--------------------------------------------------------------------------- + WDI_Band +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_BAND_ALL, + WDI_BAND_24, + WDI_BAND_5G, + WDI_BAND_MAX, +}eWDIBand; + +/*--------------------------------------------------------------------------- + WDI_MaxTxPowerPerBandInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + eWDIBand bandInfo; + /* In request power == MaxTxpower to be used.*/ + wpt_uint8 ucPower; +}WDI_MaxTxPowerPerBandInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerPerBandParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_MaxTxPowerPerBandInfoType wdiMaxTxPowerPerBandInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetMaxTxPowerPerBandParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPowerParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Link Info*/ + WDI_SetTxPowerInfoType wdiTxPowerInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetTxPowerParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerRspMsg +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* In response, power==tx power used for management frames*/ + wpt_int8 ucPower; + + /*Result of the operation*/ + WDI_Status wdiStatus; + +}WDI_SetMaxTxPowerRspMsg; + +/*--------------------------------------------------------------------------- + WDI_SetMaxTxPowerPerBandRspMsg +---------------------------------------------------------------------------*/ +typedef struct +{ + /* In response, power==tx power used for management frames*/ + wpt_int8 ucPower; + + /*Result of the operation*/ + WDI_Status wdiStatus; + +}WDI_SetMaxTxPowerPerBandRspMsg; + +/*--------------------------------------------------------------------------- + WDI_SetTxPowerRspMsg +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* In response, power==tx power used for management frames*/ + wpt_int8 ucPower; + + /*Result of the operation*/ + WDI_Status wdiStatus; + +}WDI_SetTxPowerRspMsg; + +typedef struct +{ + wpt_uint8 ucOpp_ps; + wpt_uint32 uCtWindow; + wpt_uint8 ucCount; + wpt_uint32 uDuration; + wpt_uint32 uInterval; + wpt_uint32 uSingle_noa_duration; + wpt_uint8 ucPsSelection; +}WDI_SetP2PGONOAReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetP2PGONOAReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*P2P GO NOA Req*/ + WDI_SetP2PGONOAReqInfoType wdiP2PGONOAInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetP2PGONOAReqParamsType; + +#define WDI_MAX_SUPP_CHANNELS 128 +#define WDI_MAX_SUPP_OPER_CLASSES 32 + +typedef struct +{ + wpt_uint16 uStaIdx; + wpt_uint8 uIsResponder; + wpt_uint8 uUapsdQueues; + wpt_uint8 uMaxSp; + wpt_uint8 uIsBufSta; + wpt_uint8 uIsOffChannelSupported; + wpt_uint8 peerCurrOperClass; + wpt_uint8 selfCurrOperClass; + wpt_uint8 validChannelsLen; + wpt_uint8 validChannels[WDI_MAX_SUPP_CHANNELS]; + wpt_uint8 validOperClassesLen; + wpt_uint8 validOperClasses[WDI_MAX_SUPP_OPER_CLASSES]; +}WDI_SetTDLSLinkEstablishReqInfoType; +/*--------------------------------------------------------------------------- + WDI_SetTDLSLinkEstablishReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*TDLS Link Establish Req*/ + WDI_SetTDLSLinkEstablishReqInfoType wdiTDLSLinkEstablishInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetTDLSLinkEstablishReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*STA Idx*/ + wpt_uint16 uStaIdx; +}WDI_SetTdlsLinkEstablishReqResp; + + + +typedef struct +{ + /*STA Index*/ + wpt_uint8 staIdx; + /* if this is 1, self is initiator otherwise responder only*/ + wpt_uint8 isOffchannelInitiator; + /*TDLS off channel related params */ + wpt_uint8 targetOperClass; + wpt_uint8 targetChannel; + wpt_uint8 secondaryChannelOffset; + wpt_uint8 reserved[64]; +}WDI_SetTDLSChanSwitchReqInfoType; + +typedef struct +{ + WDI_SetTDLSChanSwitchReqInfoType wdiTDLSChanSwitchReqInfo; + WDI_ReqStatusCb wdiReqStatusCB; + void* pUserData; +}WDI_SetTDLSChanSwitchReqParamsType; + + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /*STA Idx*/ + wpt_uint16 uStaIdx; +}WDI_SetTdlsChanSwitchReqResp; +/*--------------------------------------------------------------------------- + WDI_SetAddSTASelfParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Self Station MAC address*/ + wpt_macAddr selfMacAddr; + + /*Self STA device mode*/ + wpt_uint32 currDeviceMode; + + /*Status of the operation*/ + wpt_uint32 uStatus; +}WDI_AddSTASelfInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetAddSTASelfParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Add Sta Self Req */ + WDI_AddSTASelfInfoType wdiAddSTASelfInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AddSTASelfReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_AddSTASelfRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Idx allocated by HAL*/ + wpt_uint8 ucSTASelfIdx; + + /* DPU Index (IGTK, PTK, GTK all same) */ + wpt_uint8 dpuIdx; + + /* DPU Signature */ + wpt_uint8 dpuSignature; + + /*Self STA Mac*/ + wpt_macAddr macSelfSta; + +}WDI_AddSTASelfRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfReqParamsType + Del Sta Self info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_macAddr selfMacAddr; + +}WDI_DelSTASelfInfoType; + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfReqParamsType + Del Sta Self info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Del Sta Self Info Type */ + WDI_DelSTASelfInfoType wdiDelStaSelfInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_DelSTASelfReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*STA Index returned during DAL_PostAssocReq or DAL_ConfigStaReq*/ +// wpt_uint8 ucSTAIdx; +}WDI_DelSTASelfRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_UapsdInfoType + UAPSD parameters passed per AC to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSTAIdx; // STA index + wpt_uint8 ucAc; // Access Category + wpt_uint8 ucUp; // User Priority + wpt_uint32 uSrvInterval; // Service Interval + wpt_uint32 uSusInterval; // Suspend Interval + wpt_uint32 uDelayInterval; // Delay Interval +} WDI_UapsdInfoType; + +/*--------------------------------------------------------------------------- + WDI_SetUapsdAcParamsReqParamsType + UAPSD parameters passed per AC to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enter BMPS Info Type, same as tEnterBmpsParams */ + WDI_UapsdInfoType wdiUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetUapsdAcParamsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsReqinfoType + Enter BMPS parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + //TBTT value derived from the last beacon + wpt_uint8 ucBssIdx; + wpt_uint64 uTbtt; + wpt_uint8 ucDtimCount; + //DTIM period given to HAL during association may not be valid, + //if association is based on ProbeRsp instead of beacon. + wpt_uint8 ucDtimPeriod; + /* DXE physical addr to be passed down to RIVA. RIVA HAL will use it to program + DXE when DXE wakes up from power save*/ + unsigned int dxePhyAddr; + + // For ESE and 11R Roaming + wpt_uint32 rssiFilterPeriod; + wpt_uint32 numBeaconPerRssiAverage; + wpt_uint8 bRssiFilterEnable; +}WDI_EnterBmpsReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsReqParamsType + Enter BMPS parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enter BMPS Info Type, same as tEnterBmpsParams */ + WDI_EnterBmpsReqinfoType wdiEnterBmpsInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EnterBmpsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterImpsReqParamsType + Enter IMPS parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EnterImpsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitImpsReqParamsType + Exit IMPS parameters passed to WDI from WDA +----------------------------------------------------------------------------*/ +typedef struct +{ + /*Request status callback offered by UMAC */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_ExitImpsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsReqParamsType + Enter BMPS parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_EnterBmpsRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsReqinfoType + Exit BMPS parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSendDataNull; + wpt_uint8 bssIdx; +}WDI_ExitBmpsReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsReqParamsType + Exit BMPS parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Exit BMPS Info Type, same as tExitBmpsParams */ + WDI_ExitBmpsReqinfoType wdiExitBmpsInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ExitBmpsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsReqParamsType + Exit BMPS parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_ExitBmpsRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdReqinfoType + Enter UAPSD parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucBkDeliveryEnabled:1; + wpt_uint8 ucBeDeliveryEnabled:1; + wpt_uint8 ucViDeliveryEnabled:1; + wpt_uint8 ucVoDeliveryEnabled:1; + wpt_uint8 ucBkTriggerEnabled:1; + wpt_uint8 ucBeTriggerEnabled:1; + wpt_uint8 ucViTriggerEnabled:1; + wpt_uint8 ucVoTriggerEnabled:1; + wpt_uint8 bssIdx; +}WDI_EnterUapsdReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdRspParamsType + Enter UAPSD parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_EnterUapsdRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdReqinfoType + Enter UAPSD parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enter UAPSD Info Type, same as tUapsdParams */ + WDI_EnterUapsdReqinfoType wdiEnterUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_EnterUapsdReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateUapsdReqinfoType + Update UAPSD parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSTAIdx; + wpt_uint8 ucUapsdACMask; + wpt_uint32 uMaxSpLen; +}WDI_UpdateUapsdReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdReqinfoType + Exit UAPSD parameters passed to WDA from UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 bssIdx; +}WDI_ExitUapsdReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdReqParamsType + Exit UAPSD parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Exit UAPSD Info Type, same as tUapsdParams */ + WDI_ExitUapsdReqinfoType wdiExitUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ExitUapsdReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdRspParamsType + Exit UAPSD parameters passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_ExitUapsdRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateUapsdReqParamsType + Update UAPSD parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Update UAPSD Info Type, same as tUpdateUapsdParams */ + WDI_UpdateUapsdReqinfoType wdiUpdateUapsdInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_UpdateUapsdReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigureRxpFilterReqParamsType + RXP filter parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Mode of Mcast and Bcast filters configured */ + wpt_uint8 ucSetMcstBcstFilterSetting; + + /* Mcast Bcast Filters enable/disable*/ + wpt_uint8 ucSetMcstBcstFilter; +}WDI_RxpFilterReqParamsType; + +typedef struct +{ + /* Rxp Filter */ + WDI_RxpFilterReqParamsType wdiRxpFilterParam; + + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigureRxpFilterReqParamsType; + +typedef struct +{ + wpt_uint8 enableFlag; + wpt_uint8 frameType; + wpt_uint8 frameSize; + wpt_uint8 bufferMode; + wpt_uint8 continuousFrameLogging; + wpt_uint8 minLogBufferSize; + wpt_uint8 maxLogBufferSize; +}WDI_FWLoggingInitReqInfoType; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint8 minRssi; + wpt_uint8 maxRssi; + wpt_macAddr currentBssId; +}WDI_RssiMonitorReqInfoType; + +typedef struct +{ + wpt_uint32 reason_code; +}WDI_FatalEventLogsReqInfoType; + + +typedef struct +{ + wpt_uint8 flags; +}WDI_GetFrameLogReqInfoType; + +typedef struct +{ + wpt_uint16 status; + wpt_uint16 doneIndicationForSource; + wpt_uint64 logBuffAddress[MAX_NUM_OF_BUFFER]; + wpt_uint32 logBuffLength[MAX_NUM_OF_BUFFER]; +}WDI_FWLoggingDXEdoneIndInfoType; + +/*--------------------------------------------------------------------------- + WDI_BeaconFilterInfoType + Beacon Filtering data structures passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 usCapabilityInfo; + wpt_uint16 usCapabilityMask; + wpt_uint16 usBeaconInterval; + wpt_uint16 usIeNum; + wpt_uint8 bssIdx; + wpt_uint8 reserved; +}WDI_BeaconFilterInfoType; + +/*--------------------------------------------------------------------------- + WDI_BeaconFilterReqParamsType + Beacon Filtering parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Beacon Filtering Info Type, same as tBeaconFilterMsg */ + WDI_BeaconFilterInfoType wdiBeaconFilterInfo; + /*Beacon Filter(s) follow the "usIeNum" field, hence the array to ease the + copy of params from WDA to WDI */ + wpt_uint8 aFilters[WDI_BEACON_FILTER_LEN]; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_BeaconFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_RemBeaconFilterInfoType + Beacon Filtering data structures (to be reomoved) passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucIeCount; + wpt_uint8 ucRemIeId[1]; +}WDI_RemBeaconFilterInfoType; + +/*--------------------------------------------------------------------------- + WDI_RemBeaconFilterReqParamsType + Beacon Filtering parameters (to be reomoved)passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Beacon Filtering Info Type, same as tBeaconFilterMsg */ + WDI_RemBeaconFilterInfoType wdiBeaconFilterInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_RemBeaconFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_RSSIThresholdsType + RSSI thresholds data structures (to be reomoved) passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_int8 ucRssiThreshold1 : 8; + wpt_int8 ucRssiThreshold2 : 8; + wpt_int8 ucRssiThreshold3 : 8; + wpt_uint8 bRssiThres1PosNotify : 1; + wpt_uint8 bRssiThres1NegNotify : 1; + wpt_uint8 bRssiThres2PosNotify : 1; + wpt_uint8 bRssiThres2NegNotify : 1; + wpt_uint8 bRssiThres3PosNotify : 1; + wpt_uint8 bRssiThres3NegNotify : 1; + wpt_uint8 bReserved10 : 2; +} WDI_RSSIThresholdsType; + +/*--------------------------------------------------------------------------- + WDI_SetRSSIThresholdsReqParamsType + RSSI thresholds parameters (to be reomoved)passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*RSSI thresholds Info Type, same as WDI_RSSIThresholds */ + WDI_RSSIThresholdsType wdiRSSIThresholdsInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetRSSIThresholdsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_HostOffloadReqType + host offload info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +#ifdef WLAN_NS_OFFLOAD +typedef struct +{ + wpt_uint8 srcIPv6Addr[16]; + wpt_uint8 selfIPv6Addr[16]; + //Only support 2 possible Network Advertisement IPv6 address + wpt_uint8 targetIPv6Addr1[16]; + wpt_uint8 targetIPv6Addr2[16]; + wpt_uint8 selfMacAddr[6]; + wpt_uint8 srcIPv6AddrValid : 1; + wpt_uint8 targetIPv6Addr1Valid : 1; + wpt_uint8 targetIPv6Addr2Valid : 1; + wpt_uint8 slotIdx; +} WDI_NSOffloadParams; +#endif //WLAN_NS_OFFLOAD + +typedef struct +{ + wpt_uint8 ucOffloadType; + wpt_uint8 ucEnableOrDisable; + wpt_macAddr bssId; + union + { + wpt_uint8 aHostIpv4Addr [4]; + wpt_uint8 aHostIpv6Addr [16]; + } params; +} WDI_HostOffloadReqType; + +/*--------------------------------------------------------------------------- + WDI_HostOffloadReqParamsType + host offload info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Host offload Info Type, same as tHalHostOffloadReq */ + WDI_HostOffloadReqType wdiHostOffloadInfo; +#ifdef WLAN_NS_OFFLOAD + WDI_NSOffloadParams wdiNsOffloadParams; +#endif //WLAN_NS_OFFLOAD + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_HostOffloadReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_KeepAliveReqType + Keep Alive info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucPacketType; + wpt_uint32 ucTimePeriod; + wpt_uint8 aHostIpv4Addr[4]; + wpt_uint8 aDestIpv4Addr[4]; + wpt_uint8 aDestMacAddr[6]; + wpt_macAddr bssId; +} WDI_KeepAliveReqType; + +/*--------------------------------------------------------------------------- + WDI_KeepAliveReqParamsType + Keep Alive passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Keep Alive Info Type, same as tHalKeepAliveReq */ + WDI_KeepAliveReqType wdiKeepAliveInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_KeepAliveReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnInfoType + Wowl add ptrn info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucPatternId; // Pattern ID + // Pattern byte offset from beginning of the 802.11 packet to start of the + // wake-up pattern + wpt_uint8 ucPatternByteOffset; + wpt_uint8 ucPatternSize; // Non-Zero Pattern size + wpt_uint8 ucPattern[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern + wpt_uint8 ucPatternMaskSize; // Non-zero pattern mask size + wpt_uint8 ucPatternMask[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern mask + wpt_uint8 ucPatternExt[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern + wpt_uint8 ucPatternMaskExt[WDI_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern mask + wpt_macAddr bssId; +} WDI_WowlAddBcPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnReqParamsType + Wowl add ptrn info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl add ptrn Info Type, same as tpSirWowlAddBcastPtrn */ + WDI_WowlAddBcPtrnInfoType wdiWowlAddBcPtrnInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlAddBcPtrnReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnRspParamsType + Wowl add ptrn info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_WowlAddBcPtrnRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnInfoType + Wowl add ptrn info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Pattern ID of the wakeup pattern to be deleted */ + wpt_uint8 ucPatternId; + wpt_macAddr bssId; +} WDI_WowlDelBcPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnReqParamsType + Wowl add ptrn info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl delete ptrn Info Type, same as WDI_WowlDelBcastPtrn */ + WDI_WowlDelBcPtrnInfoType wdiWowlDelBcPtrnInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlDelBcPtrnReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnRspParamsType + Wowl Del ptrn info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; + /*BssIDX of the session*/ + wpt_uint8 bssIdx; +}WDI_WowlDelBcPtrnRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlEnterInfoType + Wowl enter info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Enables/disables magic packet filtering */ + wpt_uint8 ucMagicPktEnable; + + /* Magic pattern */ + wpt_macAddr magicPtrn; + + /* Enables/disables packet pattern filtering in firmware. + Enabling this flag enables broadcast pattern matching + in Firmware. If unicast pattern matching is also desired, + ucUcastPatternFilteringEnable flag must be set tot true + as well + */ + wpt_uint8 ucPatternFilteringEnable; + + /* Enables/disables unicast packet pattern filtering. + This flag specifies whether we want to do pattern match + on unicast packets as well and not just broadcast packets. + This flag has no effect if the ucPatternFilteringEnable + (main controlling flag) is set to false + */ + wpt_uint8 ucUcastPatternFilteringEnable; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Channel Switch Action Frame. + */ + wpt_uint8 ucWowChnlSwitchRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Deauthentication Frame. + */ + wpt_uint8 ucWowDeauthRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Disassociation Frame. + */ + wpt_uint8 ucWowDisassocRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it has missed + * consecutive beacons. This is a hardware register + * configuration (NOT a firmware configuration). + */ + wpt_uint8 ucWowMaxMissedBeacons; + + /* This configuration is valid only when magicPktEnable=1. + * This is a timeout value in units of microsec. It requests + * hardware to unconditionally wake up after it has stayed + * in WoWLAN mode for some time. Set 0 to disable this feature. + */ + wpt_uint8 ucWowMaxSleepUsec; + +#ifdef WLAN_WAKEUP_EVENTS + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + wpt_uint8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + wpt_uint8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + wpt_uint8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + wpt_uint8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + wpt_uint8 ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +} WDI_WowlEnterInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlEnterReqParamsType + Wowl enter info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl delete ptrn Info Type, same as WDI_SmeWowlEnterParams */ + WDI_WowlEnterInfoType wdiWowlEnterInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlEnterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlEnterRsqParamsType + Wowl enter info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response message*/ + WDI_Status status; + + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +}WDI_WowlEnterRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlExitInfoType + Wowl exit info passed to WDA form UMAC + ---------------------------------------------------------------------------*/ +typedef struct +{ + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +} WDI_WowlExitInfoType; + +/*--------------------------------------------------------------------------- + WDI_WowlExitReqParamsType + Wowl exit info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Wowl delete ptrn Info Type, same as WDI_SmeWowlEnterParams */ + WDI_WowlExitInfoType wdiWowlExitInfo; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_WowlExitReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_WowlExitRspParamsType + Wowl exit info passed from WDI to WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response message*/ + WDI_Status status; + + /* BSSIDX used to find the current session + */ + wpt_uint8 bssIdx; +}WDI_WowlExitRspParamsType; + +/*--------------------------------------------------------------------------- + WDI_ConfigureAppsCpuWakeupStateReqParamsType + Apps Cpu Wakeup State parameters passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Depicts the state of the Apps CPU */ + wpt_boolean bIsAppsAwake; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ConfigureAppsCpuWakeupStateReqParamsType; +/*--------------------------------------------------------------------------- + WDI_FlushAcReqinfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + // Message Type + wpt_uint16 usMesgType; + + // Message Length + wpt_uint16 usMesgLen; + + // Station Index. originates from HAL + wpt_uint8 ucSTAId; + + // TID for which the transmit queue is being flushed + wpt_uint8 ucTid; + +}WDI_FlushAcReqinfoType; + +/*--------------------------------------------------------------------------- + WDI_FlushAcReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*AC Info */ + WDI_FlushAcReqinfoType wdiFlushAcInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_FlushAcReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_BtAmpEventinfoType + BT-AMP Event Structure +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucBtAmpEventType; + +} WDI_BtAmpEventinfoType; + +/*--------------------------------------------------------------------------- + WDI_BtAmpEventParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*BT AMP event Info */ + WDI_BtAmpEventinfoType wdiBtAmpEventInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_BtAmpEventParamsType; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +#ifndef NEW_OEM_DATA_REQ_SIZE +#define NEW_OEM_DATA_REQ_SIZE 292 +#endif + +#ifndef NEW_OEM_DATA_RSP_SIZE +#define NEW_OEM_DATA_RSP_SIZE 2100 +#endif + +/*---------------------------------------------------------------------------- + WDI_oemDataReqInfoType +----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_macAddr selfMacAddr; + wpt_uint8 oemDataReq[OEM_DATA_REQ_SIZE]; +}WDI_oemDataReqInfoType; + +/*---------------------------------------------------------------------------- + WDI_oemDataReqParamsType +----------------------------------------------------------------------------*/ +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + /*OEM DATA REQ Info */ + WDI_oemDataReqInfoType wdiOemDataReqInfo; + +}WDI_oemDataReqParamsType; + +/*---------------------------------------------------------------------------- + WDI_oemDataRspParamsType +----------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 oemDataRsp[OEM_DATA_RSP_SIZE]; +}WDI_oemDataRspParamsType; + +/*---------------------------------------------------------------------------- + OEM DATA REQ NEW/OEM DATA RSP NEW - DATA STRUCTURES +----------------------------------------------------------------------------*/ +/* Structure for defining req sent to the PE */ +typedef struct +{ + wpt_macAddr selfMacAddr; + wpt_uint8 reserved[2]; + wpt_uint8 oemDataReqNew[NEW_OEM_DATA_REQ_SIZE]; +} WDI_OemDataReqNew, WDI_OemDataReqNewConfig; + +/*************************************************************************************************************/ + +#endif /* FEATURE_OEM_DATA_SUPPORT */ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*--------------------------------------------------------------------------- + WDI_AggrAddTSReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*STA Index*/ + wpt_uint8 ucSTAIdx; + + /*Identifier for TSpec*/ + wpt_uint8 ucTspecIdx; + + /*Tspec IE negotiated OTA*/ + WDI_TspecIEType wdiTspecIE[WDI_MAX_NO_AC]; + + /*UAPSD delivery and trigger enabled flags */ + wpt_uint8 ucUapsdFlags; + + /*SI for each AC*/ + wpt_uint8 ucServiceInterval[WDI_MAX_NO_AC]; + + /*Suspend Interval for each AC*/ + wpt_uint8 ucSuspendInterval[WDI_MAX_NO_AC]; + + /*DI for each AC*/ + wpt_uint8 ucDelayedInterval[WDI_MAX_NO_AC]; + +}WDI_AggrAddTSReqInfoType; + + +/*--------------------------------------------------------------------------- + WDI_AggrAddTSReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*TSpec Info */ + WDI_AggrAddTSReqInfoType wdiAggrTsInfo; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_AggrAddTSReqParamsType; + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/*--------------------------------------------------------------------------- + WDI_FTMCommandReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* FTM Command Body length */ + wpt_uint32 bodyLength; + /* Actual FTM Command body */ + void *FTMCommandBody; +}WDI_FTMCommandReqType; + +/*--------------------------------------------------------------------------- + WDI_WlanSuspendInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Mode of Mcast and Bcast filters configured */ + wpt_uint8 ucConfiguredMcstBcstFilterSetting; +}WDI_WlanSuspendInfoType; + +/*--------------------------------------------------------------------------- + WDI_SuspendParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_WlanSuspendInfoType wdiSuspendParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_SuspendParamsType; + +/*--------------------------------------------------------------------------- + WDI_TrafficStatsType - This is collected for each STA +---------------------------------------------------------------------------*/ + +typedef struct +{ + /* TX stats */ + wpt_uint32 txBytesPushed; + wpt_uint32 txPacketsPushed; + + /* RX stats */ + wpt_uint32 rxBytesRcvd; + wpt_uint32 rxPacketsRcvd; + wpt_uint32 rxTimeTotal; +}WDI_TrafficStatsType; + +typedef struct +{ + WDI_TrafficStatsType *pTrafficStats; + wpt_uint32 length; + wpt_uint32 duration; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_TrafficStatsIndType; + +#ifdef WLAN_FEATURE_11W +typedef struct +{ + + wpt_boolean bExcludeUnencrypt; + wpt_macAddr bssid; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_ExcludeUnencryptIndType; +#endif + +/*--------------------------------------------------------------------------- + WDI_WlanResumeInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Mode of Mcast and Bcast filters configured */ + wpt_uint8 ucConfiguredMcstBcstFilterSetting; +}WDI_WlanResumeInfoType; + +/*--------------------------------------------------------------------------- + WDI_ResumeParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_WlanResumeInfoType wdiResumeParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_ResumeParamsType; + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/*--------------------------------------------------------------------------- + * WDI_GTK_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ + +typedef struct +{ + wpt_uint32 ulFlags; /* optional flags */ + wpt_uint8 aKCK[16]; /* Key confirmation key */ + wpt_uint8 aKEK[16]; /* key encryption key */ + wpt_uint64 ullKeyReplayCounter; /* replay counter */ + wpt_macAddr bssId; +} WDI_GtkOffloadReqParams; + +typedef struct +{ + WDI_GtkOffloadReqParams gtkOffloadReqParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadReqMsg; + +/*--------------------------------------------------------------------------- + * WDI_GTK_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef struct +{ + /* success or failure */ + wpt_uint32 ulStatus; + /*BssIdx of the response */ + wpt_uint8 bssIdx; +} WDI_GtkOffloadRspParams; + +typedef struct +{ + WDI_GtkOffloadRspParams gtkOffloadRspParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadRspMsg; + + +/*--------------------------------------------------------------------------- +* WDI_GTK_OFFLOAD_GETINFO_REQ +*--------------------------------------------------------------------------*/ +typedef struct +{ + /*BssIdx of the response */ + wpt_macAddr bssId; +} WDI_GtkOffloadGetInfoReqParams; + +typedef struct +{ + + WDI_GtkOffloadGetInfoReqParams WDI_GtkOffloadGetInfoReqParams; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadGetInfoReqMsg; + +/*--------------------------------------------------------------------------- +* WDI_GTK_OFFLOAD_GETINFO_RSP +*--------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 ulStatus; /* success or failure */ + wpt_uint64 ullKeyReplayCounter; /* current replay counter value */ + wpt_uint32 ulTotalRekeyCount; /* total rekey attempts */ + wpt_uint32 ulGTKRekeyCount; /* successful GTK rekeys */ + wpt_uint32 ulIGTKRekeyCount; /* successful iGTK rekeys */ + wpt_macAddr bssId; +} WDI_GtkOffloadGetInfoRspParams; + +typedef struct +{ + WDI_GtkOffloadGetInfoRspParams gtkOffloadGetInfoRspParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_GtkOffloadGetInfoRspMsg; +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/*--------------------------------------------------------------------------- + WDI_SuspendResumeRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Status of the response*/ + WDI_Status wdiStatus; +}WDI_SuspendResumeRspParamsType; + +#ifdef FEATURE_WLAN_LPHB +/*--------------------------------------------------------------------------- + WDI Low Power Heart Beat Config request + Copy from sirApi.h to avoid compile error +---------------------------------------------------------------------------*/ +#define WDI_LPHB_FILTER_LEN 64 + +typedef enum +{ + WDI_LPHB_SET_EN_PARAMS_INDID = 0x0001, + WDI_LPHB_SET_TCP_PARAMS_INDID, + WDI_LPHB_SET_TCP_PKT_FILTER_INDID, + WDI_LPHB_SET_UDP_PARAMS_INDID, + WDI_LPHB_SET_UDP_PKT_FILTER_INDID, + WDI_LPHB_SET_NETWORK_INFO_INDID, +} WDI_LPHBIndType; + +typedef struct +{ + wpt_uint8 enable; + wpt_uint8 item; + wpt_uint8 session; +} WDI_LPHBEnableStruct; + +typedef struct +{ + wpt_uint32 srv_ip; + wpt_uint32 dev_ip; + wpt_uint16 src_port; + wpt_uint16 dst_port; + wpt_uint16 timeout; + wpt_uint8 session; + wpt_uint8 gateway_mac[WDI_MAC_ADDR_LEN]; + wpt_uint16 timePeriodSec; // in seconds + wpt_uint32 tcpSn; +} WDI_LPHBTcpParamStruct; + +typedef struct +{ + wpt_uint16 length; + wpt_uint8 offset; + wpt_uint8 session; + wpt_uint8 filter[WDI_LPHB_FILTER_LEN]; +} WDI_LPHBTcpFilterStruct; + +typedef struct +{ + wpt_uint32 srv_ip; + wpt_uint32 dev_ip; + wpt_uint16 src_port; + wpt_uint16 dst_port; + wpt_uint16 interval; + wpt_uint16 timeout; + wpt_uint8 session; + wpt_uint8 gateway_mac[WDI_MAC_ADDR_LEN]; +} WDI_LPHBUdpParamStruct; + +typedef struct +{ + wpt_uint16 length; + wpt_uint8 offset; + wpt_uint8 session; + wpt_uint8 filter[WDI_LPHB_FILTER_LEN]; +} WDI_LPHBUdpFilterStruct; + +typedef struct +{ + wpt_uint16 cmd; + wpt_uint16 dummy; + union + { + WDI_LPHBEnableStruct lphbEnableReq; + WDI_LPHBTcpParamStruct lphbTcpParamReq; + WDI_LPHBTcpFilterStruct lphbTcpFilterReq; + WDI_LPHBUdpParamStruct lphbUdpParamReq; + WDI_LPHBUdpFilterStruct lphbUdpFilterReq; + } params; +} WDI_LPHBReq; +#endif /* FEATURE_WLAN_LPHB */ + +/*--------------------------------------------------------------------------- + WDI_AuthType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_AUTH_TYPE_ANY = 0, + + WDI_AUTH_TYPE_NONE, + WDI_AUTH_TYPE_OPEN_SYSTEM, + WDI_AUTH_TYPE_SHARED_KEY, + + WDI_AUTH_TYPE_WPA, + WDI_AUTH_TYPE_WPA_PSK, + WDI_AUTH_TYPE_WPA_NONE, + + WDI_AUTH_TYPE_RSN, + WDI_AUTH_TYPE_RSN_PSK, + WDI_AUTH_TYPE_FT_RSN, + WDI_AUTH_TYPE_FT_RSN_PSK, + WDI_AUTH_TYPE_WAPI_WAI_CERTIFICATE, + WDI_AUTH_TYPE_WAPI_WAI_PSK, + WDI_AUTH_TYPE_MAX = 0xFFFFFFFF /*expanding the type to UINT32*/ + +}WDI_AuthType; + +/*--------------------------------------------------------------------------- + WDI_EdType +---------------------------------------------------------------------------*/ +typedef enum +{ + WDI_ED_ANY = 0, + WDI_ED_NONE, + WDI_ED_WEP40, + WDI_ED_WEP104, + WDI_ED_TKIP, + WDI_ED_CCMP, + WDI_ED_WPI, + WDI_ED_AES_128_CMAC, + WDI_ED_MAX = 0xFFFFFFFF /*expanding the type to UINT32*/ +} WDI_EdType; + +#ifdef FEATURE_WLAN_SCAN_PNO + +/*Max number of channels for a given network supported by PNO*/ +#define WDI_PNO_MAX_NETW_CHANNELS 26 + +/*Max number of channels for a given network supported by PNO*/ +#define WDI_PNO_MAX_NETW_CHANNELS_EX 60 + +/*The max number of programable networks for PNO*/ +#define WDI_PNO_MAX_SUPP_NETWORKS 16 + +/*The max number of scan timers programable in Riva*/ +#define WDI_PNO_MAX_SCAN_TIMERS 10 + +#define WDI_PNO_MAX_PROBE_SIZE 450 + +/*--------------------------------------------------------------------------- + WDI_PNOMode +---------------------------------------------------------------------------*/ +typedef enum +{ + /*Network offload is to start immediately*/ + WDI_PNO_MODE_IMMEDIATE, + + /*Network offload is to start on host suspend*/ + WDI_PNO_MODE_ON_SUSPEND, + + /*Network offload is to start on host resume*/ + WDI_PNO_MODE_ON_RESUME, + WDI_PNO_MODE_MAX = 0xFFFFFFFF +} WDI_PNOMode; + +/* SSID broadcast type */ +typedef enum +{ + WDI_BCAST_UNKNOWN = 0, + WDI_BCAST_NORMAL = 1, + WDI_BCAST_HIDDEN = 2, + + WDI_BCAST_TYPE_MAX = 0xFFFFFFFF +} WDI_SSIDBcastType; + +/*--------------------------------------------------------------------------- + WDI_NetworkType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The SSID of the preferred network*/ + WDI_MacSSid ssId; + + /*The authentication method of the preferred network*/ + WDI_AuthType wdiAuth; + + /*The encryption method of the preferred network*/ + WDI_EdType wdiEncryption; + + /*SSID broadcast type, normal, hidden or unknown*/ + WDI_SSIDBcastType wdiBcastNetworkType; + + /*channel count - 0 for all channels*/ + wpt_uint8 ucChannelCount; + + /*the actual channels*/ + wpt_uint8 aChannels[WDI_PNO_MAX_NETW_CHANNELS_EX]; + + /*rssi threshold that a network must meet to be considered, 0 - for any*/ + wpt_uint8 rssiThreshold; +} WDI_NetworkType; + + +/*--------------------------------------------------------------------------- + WDI_ScanTimer +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The timer value*/ + wpt_uint32 uTimerValue; + + /*The amount of time we should be repeating the interval*/ + wpt_uint32 uTimerRepeat; +} WDI_ScanTimer; + +/*--------------------------------------------------------------------------- + WDI_ScanTimersType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*The number of value pair intervals present in the array*/ + wpt_uint8 ucScanTimersCount; + + /*The time-repeat value pairs*/ + WDI_ScanTimer aTimerValues[WDI_PNO_MAX_SCAN_TIMERS]; +} WDI_ScanTimersType; + +/*--------------------------------------------------------------------------- + WDI_PNOScanReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Enable or disable PNO feature*/ + wpt_uint8 bEnable; + + /*PNO mode requested*/ + WDI_PNOMode wdiModePNO; + + /*Network count*/ + wpt_uint8 ucNetworksCount; + + /*The networks to look for*/ + WDI_NetworkType aNetworks[WDI_PNO_MAX_SUPP_NETWORKS]; + + /*Scan timer intervals*/ + WDI_ScanTimersType scanTimers; + + /*Probe template for 2.4GHz band*/ + wpt_uint16 us24GProbeSize; + wpt_uint8 a24GProbeTemplate[WDI_PNO_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + wpt_uint16 us5GProbeSize; + wpt_uint8 a5GProbeTemplate[WDI_PNO_MAX_PROBE_SIZE]; +} WDI_PNOScanReqType; + +/*--------------------------------------------------------------------------- + WDI_PNOScanReqParamsType + PNO info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* PNO Info Type, same as tPrefNetwListParams */ + WDI_PNOScanReqType wdiPNOScanInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_PNOScanReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetRssiFilterReqParamsType + PNO info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* RSSI Threshold */ + wpt_uint8 rssiThreshold; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_SetRssiFilterReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfo +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Is 11d enabled*/ + wpt_uint8 b11dEnabled; + + /*Was UMAc able to find the regulatory domain*/ + wpt_uint8 b11dResolved; + + /*Number of channel allowed in the regulatory domain*/ + wpt_uint8 ucChannelCount; + + /*The actual channels allowed in the regulatory domain*/ + wpt_uint8 aChannels[WDI_PNO_MAX_NETW_CHANNELS_EX]; + + /*Passive min channel time*/ + wpt_uint16 usPassiveMinChTime; + + /*Passive max channel time*/ + wpt_uint16 usPassiveMaxChTime; + + /*Active min channel time*/ + wpt_uint16 usActiveMinChTime; + + /*Active max channel time*/ + wpt_uint16 usActiveMaxChTime; + + /*channel bonding info*/ + wpt_uint8 cbState; +} WDI_UpdateScanParamsInfo; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfoType + UpdateScanParams info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* PNO Info Type, same as tUpdateScanParams */ + WDI_UpdateScanParamsInfo wdiUpdateScanParamsInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_UpdateScanParamsInfoType; +#endif //FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#define WDI_ROAM_SCAN_MAX_CHANNELS 80 +#define WDI_ROAM_SCAN_MAX_PROBE_SIZE 450 + +typedef struct +{ + /*The SSID of the preferred network*/ + WDI_MacSSid ssId; + wpt_uint8 currAPbssid[WDI_MAC_ADDR_LEN]; + + /*The authentication method of the preferred network*/ + WDI_AuthType authentication; + + /*The encryption method of the preferred network*/ + WDI_EdType encryption; + WDI_EdType mcencryption; + + /*SSID broadcast type, normal, hidden or unknown*/ + //WDI_SSIDBcastType wdiBcastNetworkType; + + /*channel count - 0 for all channels*/ + wpt_uint8 ChannelCount; + + /*the actual channels*/ + wpt_uint8 ChannelCache[WDI_ROAM_SCAN_MAX_CHANNELS]; + +} WDI_RoamNetworkType; + +typedef struct WDIMobilityDomainInfo +{ + wpt_uint8 mdiePresent; + wpt_uint16 mobilityDomain; +} WDI_MobilityDomainInfo; + +/*--------------------------------------------------------------------------- + WDI_RoamOffloadScanInfo +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_boolean RoamScanOffloadEnabled; + wpt_boolean MAWCEnabled; + wpt_uint8 LookupThreshold; + wpt_uint8 RxSensitivityThreshold; + wpt_uint8 RoamRssiDiff; + wpt_uint8 ChannelCacheType; + wpt_uint8 Command; + wpt_uint8 StartScanReason; + wpt_uint16 NeighborScanTimerPeriod; + wpt_uint16 NeighborRoamScanRefreshPeriod; + wpt_uint16 NeighborScanChannelMinTime; + wpt_uint16 NeighborScanChannelMaxTime; + wpt_uint16 EmptyRefreshScanPeriod; + wpt_uint8 ValidChannelCount; + wpt_uint8 ValidChannelList[WDI_ROAM_SCAN_MAX_CHANNELS]; + wpt_boolean IsESEEnabled; + /*Probe template for 2.4GHz band*/ + wpt_uint16 us24GProbeSize; + wpt_uint8 a24GProbeTemplate[WDI_ROAM_SCAN_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + wpt_uint16 us5GProbeSize; + wpt_uint8 a5GProbeTemplate[WDI_ROAM_SCAN_MAX_PROBE_SIZE]; + /*LFR BG Scan will currently look for only one network to which it is initially connected. + * As per requirement, later, the following structure can be used as an array of networks.*/ + WDI_RoamNetworkType ConnectedNetwork; + WDI_MobilityDomainInfo MDID; + wpt_uint8 nProbes; + wpt_uint16 HomeAwayTime; + wpt_uint8 WeakZoneRssiThresholdForRoam; +} WDI_RoamOffloadScanInfo; + +typedef struct +{ + /* Start Roam Candidate Lookup Offload Back Ground Info Type */ + WDI_RoamOffloadScanInfo wdiRoamOffloadScanInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_RoamScanOffloadReqParamsType; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint32 rateUpThreshold; + wpt_uint32 rateDownThreshold; + wpt_uint32 isPERRoamCCAEnabled; + wpt_uint32 waitPeriodForNextPERScan; + wpt_uint32 PERtimerThreshold; + wpt_uint32 PERroamTriggerPercent; + wpt_int16 PERRoamFullScanThreshold; +} WDI_PERRoamOffloadScanInfo; + +typedef struct +{ + wpt_boolean roamScanReq; // Request info for all peers +} WDI_PERRoamTriggerScanInfo; +#endif //WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +/*--------------------------------------------------------------------------- + WDI_HT40ObssScanIndType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 cmdType; + wpt_uint8 scanType; + wpt_uint16 OBSSScanPassiveDwellTime; // In TUs + wpt_uint16 OBSSScanActiveDwellTime; // In TUs + wpt_uint16 BSSChannelWidthTriggerScanInterval; // In seconds + wpt_uint16 OBSSScanPassiveTotalPerChannel; // In TUs + wpt_uint16 OBSSScanActiveTotalPerChannel; // In TUs + wpt_uint16 BSSWidthChannelTransitionDelayFactor; + wpt_uint16 OBSSScanActivityThreshold; + wpt_uint8 selfStaIdx; + wpt_uint8 bssIdx; + wpt_uint8 fortyMHZIntolerent; + wpt_uint8 channelCount; + wpt_uint8 channels[WDI_ROAM_SCAN_MAX_CHANNELS]; + wpt_uint8 currentOperatingClass; + wpt_uint16 ieFieldLen; + wpt_uint8 ieField[WDI_ROAM_SCAN_MAX_PROBE_SIZE]; +} WDI_HT40ObssScanIndType; + + +/*--------------------------------------------------------------------------- + WDI_OBSSScanIndParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_HT40ObssScanIndType wdiHT40ObssScanParam; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_HT40ObssScanParamsType; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfo +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Ignore DTIM */ + wpt_uint32 uIgnoreDTIM; + + /*DTIM Period*/ + wpt_uint32 uDTIMPeriod; + + /* Listen Interval */ + wpt_uint32 uListenInterval; + + /* Broadcast Multicas Filter */ + wpt_uint32 uBcastMcastFilter; + + /* Beacon Early Termination */ + wpt_uint32 uEnableBET; + + /* Beacon Early Termination Interval */ + wpt_uint32 uBETInterval; + + /* MAX LI for modulated DTIM */ + wpt_uint32 uMaxLIModulatedDTIM; + +} WDI_SetPowerParamsInfo; + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsInfoType + UpdateScanParams info passed to WDI form WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Power params Info Type, same as tSetPowerParamsReq */ + WDI_SetPowerParamsInfo wdiSetPowerParamsInfo; + /* Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /* The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetPowerParamsReqParamsType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPerTrackingConfType + Wowl add ptrn info passed to WDA form UMAC +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucTxPerTrackingEnable; /* 0: disable, 1:enable */ + wpt_uint8 ucTxPerTrackingPeriod; /* Check period, unit is sec. */ + wpt_uint8 ucTxPerTrackingRatio; /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. */ + wpt_uint32 uTxPerTrackingWatermark; /* A watermark of check number, once the tx packet exceed this number, we do the check, default is 5 */ +} WDI_TxPerTrackingParamType; + +/*--------------------------------------------------------------------------- + WDI_SetTxPerTrackingReqParamsType + Tx PER Tracking parameters passed to WDI from WDA +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Configurations for Tx PER Tracking */ + WDI_TxPerTrackingParamType wdiTxPerTrackingParam; + /*Request status callback offered by UMAC - it is called if the current req + has returned PENDING as status; it delivers the status of sending the message + over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_SetTxPerTrackingReqParamsType; + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/*--------------------------------------------------------------------------- + Packet Filtering Parameters +---------------------------------------------------------------------------*/ + +#define WDI_IPV4_ADDR_LEN 4 +#define WDI_MAC_ADDR_LEN 6 +#define WDI_MAX_FILTER_TEST_DATA_LEN 8 +#define WDI_MAX_NUM_MULTICAST_ADDRESS 240 +#define WDI_MAX_NUM_FILTERS 20 +#define WDI_MAX_NUM_TESTS_PER_FILTER 10 + +// +// Receive Filter Parameters +// +typedef enum +{ + WDI_RCV_FILTER_TYPE_INVALID, + WDI_RCV_FILTER_TYPE_FILTER_PKT, + WDI_RCV_FILTER_TYPE_BUFFER_PKT, + WDI_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}WDI_ReceivePacketFilterType; + +typedef enum +{ + WDI_FILTER_HDR_TYPE_INVALID, + WDI_FILTER_HDR_TYPE_MAC, + WDI_FILTER_HDR_TYPE_ARP, + WDI_FILTER_HDR_TYPE_IPV4, + WDI_FILTER_HDR_TYPE_IPV6, + WDI_FILTER_HDR_TYPE_UDP, + WDI_FILTER_HDR_TYPE_MAX +}WDI_RcvPktFltProtocolType; + +typedef enum +{ + WDI_FILTER_CMP_TYPE_INVALID, + WDI_FILTER_CMP_TYPE_EQUAL, + WDI_FILTER_CMP_TYPE_MASK_EQUAL, + WDI_FILTER_CMP_TYPE_NOT_EQUAL, + WDI_FILTER_CMP_TYPE_MASK_NOT_EQUAL, + WDI_FILTER_CMP_TYPE_MAX +}WDI_RcvPktFltCmpFlagType; + +typedef struct +{ + WDI_RcvPktFltProtocolType protocolLayer; + WDI_RcvPktFltCmpFlagType cmpFlag; +/* Length of the data to compare */ + wpt_uint16 dataLength; +/* from start of the respective frame header */ + wpt_uint8 dataOffset; + wpt_uint8 reserved; /* Reserved field */ +/* Data to compare */ + wpt_uint8 compareData[WDI_MAX_FILTER_TEST_DATA_LEN]; +/* Mask to be applied on the received packet data before compare */ + wpt_uint8 dataMask[WDI_MAX_FILTER_TEST_DATA_LEN]; +}WDI_RcvPktFilterFieldParams; + +typedef struct +{ + wpt_uint8 filterId; + wpt_uint8 filterType; + wpt_uint32 numFieldParams; + wpt_uint32 coalesceTime; + wpt_macAddr selfMacAddr; + wpt_macAddr bssId; + WDI_RcvPktFilterFieldParams paramsData[1]; + +}WDI_RcvPktFilterCfgType; + +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + // Variable length packet filter field params + WDI_RcvPktFilterCfgType wdiPktFilterCfg; +} WDI_SetRcvPktFilterReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + /* BSSIDX of the Set Receive Filter + */ + wpt_uint8 bssIdx; +} WDI_SetRcvPktFilterRspParamsType; + +// +// Filter Packet Match Count Parameters +// +typedef struct +{ + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + + /* BSSID of the Match count + */ + wpt_macAddr bssId; +} WDI_RcvFltPktMatchCntReqParamsType; + +typedef struct +{ + wpt_uint8 filterId; + wpt_uint32 matchCnt; +} WDI_RcvFltPktMatchCnt; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /* BSSIDX of the Match count response + */ + wpt_uint8 bssIdx; + +} WDI_RcvFltPktMatchCntRspParamsType; + +// +// Receive Filter Clear Parameters +// +typedef struct +{ + wpt_uint32 status; /* only valid for response message */ + wpt_uint8 filterId; + wpt_macAddr selfMacAddr; + wpt_macAddr bssId; +}WDI_RcvFltPktClearParam; + +typedef struct +{ + WDI_RcvFltPktClearParam filterClearParam; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_RcvFltPktClearReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + /* BSSIDX of the Match count response + */ + wpt_uint8 bssIdx; + +} WDI_RcvFltPktClearRspParamsType; + +// +// Multicast Address List Parameters +// +typedef struct +{ + wpt_uint32 ulMulticastAddrCnt; + wpt_macAddr multicastAddr[WDI_MAX_NUM_MULTICAST_ADDRESS]; + wpt_macAddr selfMacAddr; + wpt_macAddr bssId; +} WDI_RcvFltMcAddrListType; + +typedef struct +{ + WDI_RcvFltMcAddrListType mcAddrList; + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_RcvFltPktSetMcListReqParamsType; + +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + /* BSSIDX of the Match count response + */ + wpt_uint8 bssIdx; +} WDI_RcvFltPktSetMcListRspParamsType; + +#endif // WLAN_FEATURE_PACKET_FILTERING + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdReqInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*command*/ + wpt_uint32 command; + + /*Arguments*/ + wpt_uint32 argument1; + wpt_uint32 argument2; + wpt_uint32 argument3; + wpt_uint32 argument4; + +}WDI_HALDumpCmdReqInfoType; + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdReqParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*NV Blob Info*/ + WDI_HALDumpCmdReqInfoType wdiHALDumpCmdInfoType; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; + +}WDI_HALDumpCmdReqParamsType; + + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdRspParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + /*Result of the operation*/ + WDI_Status wdiStatus; + + /* length of the buffer */ + wpt_uint16 usBufferLen; + + /* Buffer */ + wpt_uint8 *pBuffer; +}WDI_HALDumpCmdRspParamsType; + + +/*--------------------------------------------------------------------------- + WDI_SetTmLevelReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 tmMode; + wpt_uint16 tmLevel; + void* pUserData; +}WDI_SetTmLevelReqType; + +/*--------------------------------------------------------------------------- + WDI_SetTmLevelRspType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_Status wdiStatus; + void* pUserData; +}WDI_SetTmLevelRspType; + +#ifdef FEATURE_WLAN_LPHB +/*--------------------------------------------------------------------------- + WDI_LPHBConfigParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + void* pLphsConfIndData; +}WDI_LPHBConfigParamsType; +#endif /* FEATURE_WLAN_LPHB */ + +/*--------------------------------------------------------------------------- + WDI_AddPeriodicTxPtrnInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* MAC Address for the adapter */ + wpt_macAddr macAddr; + + wpt_uint8 ucPtrnId; // Pattern ID + wpt_uint16 ucPtrnSize; // Pattern size + wpt_uint32 usPtrnIntervalMs; // In msec + wpt_uint8 ucPattern[PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer +} WDI_AddPeriodicTxPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_DelPeriodicTxPtrnInfoType +---------------------------------------------------------------------------*/ +typedef struct +{ + /* MAC Address for the adapter */ + wpt_macAddr macAddr; + + /* Bitmap of pattern IDs that needs to be deleted */ + wpt_uint32 ucPatternIdBitmap; +} WDI_DelPeriodicTxPtrnInfoType; + +/*--------------------------------------------------------------------------- + WDI_AddPeriodicTxPtrnParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_AddPeriodicTxPtrnInfoType wdiAddPeriodicTxPtrnParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_AddPeriodicTxPtrnParamsType; + +/*--------------------------------------------------------------------------- + WDI_NanRequestType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint16 request_data_len; + wpt_uint8 request_data[1]; +} WDI_NanRequestType; + + +/*--------------------------------------------------------------------------- + WDI_DelPeriodicTxPtrnParamsType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_DelPeriodicTxPtrnInfoType wdiDelPeriodicTxPtrnParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +} WDI_DelPeriodicTxPtrnParamsType; + +#ifdef WLAN_FEATURE_RMC +/*--------------------------------------------------------------------------- + WDI_IbssPeerInfoParams +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 wdiStaIdx; //StaIdx + wpt_uint32 wdiTxRate; //Tx Rate + wpt_uint32 wdiMcsIndex; //MCS Index + wpt_uint32 wdiTxRateFlags; //TxRate Flags + wpt_int8 wdiRssi; //RSSI +}WDI_IbssPeerInfoParams; + +/*--------------------------------------------------------------------------- + WDI_IbssPeerInfoRspParams +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint32 wdiStatus; // Return status + wpt_uint8 wdiNumPeers; // Number of peers + WDI_IbssPeerInfoParams *wdiPeerInfoParams; // Peer Info parameters +}WDI_IbssPeerInfoRspParams; + +/*--------------------------------------------------------------------------- + WDI_GetIbssPeerInfoRspType +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_IbssPeerInfoRspParams wdiPeerInfoRspParams; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pUserData; +}WDI_GetIbssPeerInfoRspType; + +/*--------------------------------------------------------------------------- + WDI_IbssPeerInfoReqType +---------------------------------------------------------------------------*/ +typedef struct +{ + wpt_boolean wdiAllPeerInfoReqd; // Request info for all peers + wpt_uint8 wdiStaIdx; // STA Index + wpt_uint8 wdiBssIdx; // BSS Index +}WDI_IbssPeerInfoReqType; + +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_EXTSCAN + +#define WDI_WLAN_EXTSCAN_MAX_CHANNELS 16 +#define WDI_WLAN_EXTSCAN_MAX_BUCKETS 16 +#define WDI_WLAN_EXTSCAN_MAX_HOTLIST_APS 128 + +typedef enum +{ + WDI_WIFI_BAND_UNSPECIFIED, + WDI_WIFI_BAND_BG = 1, // 2.4 GHz + WDI_WIFI_BAND_A = 2, // 5 GHz without DFS + WDI_WIFI_BAND_ABG = 3, // 2.4 GHz + 5 GHz; no DFS + WDI_WIFI_BAND_A_DFS = 4, // 5 GHz DFS only + WDI_WIFI_BAND_A_WITH_DFS = 6, // 5 GHz with DFS + WDI_WIFI_BAND_ABG_WITH_DFS = 7, // 2.4 GHz + 5 GHz with DFS + + /* Keep it last */ + WDI_WIFI_BAND_MAX +} WDI_WifiBand; + +typedef struct +{ + wpt_uint32 channel; // frequency + wpt_uint32 dwellTimeMs; // dwell time hint + wpt_uint8 passive; // 0 => active, + // 1 => passive scan; ignored for DFS + wpt_uint8 chnlClass; +} WDI_WifiScanChannelSpec; + +typedef struct +{ + wpt_uint8 bucket; // bucket index, 0 based + WDI_WifiBand band; // when UNSPECIFIED, use channel list + + /* + * desired period, in millisecond; if this is too + * low, the firmware should choose to generate results as fast as + * it can instead of failing the command byte + */ + wpt_uint32 period; + + /* + * 0 => normal reporting (reporting rssi history + * only, when rssi history buffer is % full) + * 1 => same as 0 + report a scan completion event after scanning + * this bucket + * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) + * in real time to HAL + */ + wpt_uint8 reportEvents; + + wpt_uint32 max_period; + wpt_uint32 exponent; + wpt_uint32 step_count; + + wpt_uint8 numChannels; + + /* + * channels to scan; these may include DFS channels + */ + WDI_WifiScanChannelSpec channels[WDI_WLAN_EXTSCAN_MAX_CHANNELS]; +} WDI_WifiScanBucketSpec; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint8 sessionId; + wpt_uint32 basePeriod; // base timer period + wpt_uint32 maxAPperScan; + + /* in %, when buffer is this much full, wake up host */ + wpt_uint32 reportThresholdPercent; + wpt_uint32 reportThresholdNumScans; + + wpt_uint32 homeAwayTime; //in units of milliseconds + wpt_uint8 numBuckets; + WDI_WifiScanBucketSpec buckets[WDI_WLAN_EXTSCAN_MAX_BUCKETS]; +} WDI_EXTScanStartReqParams; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint8 sessionId; +} WDI_EXTScanStopReqParams; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint8 sessionId; + + /* + * 1 return cached results and flush it + * 0 return cached results and do not flush + */ + wpt_boolean flush; +} WDI_EXTScanGetCachedResultsReqParams; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint8 sessionId; +} WDI_EXTScanGetCapabilitiesReqParams; + +typedef struct +{ + wpt_uint8 bssid[6]; /* BSSID */ + wpt_int32 low; // low threshold + wpt_int32 high; // high threshold +} WDI_APThresholdParam; + +typedef struct +{ + wpt_int32 requestId; + wpt_int8 sessionId; // session Id mapped to vdev_id + wpt_uint32 lostBssidSampleSize; + wpt_int32 numBssid; // number of hotlist APs + WDI_APThresholdParam ap[WDI_WLAN_EXTSCAN_MAX_HOTLIST_APS]; // hotlist APs +} WDI_EXTScanSetBSSIDHotlistReqParams; + +typedef struct +{ + wpt_uint32 requestId; + wpt_uint8 sessionId; +} WDI_EXTScanResetBSSIDHotlistReqParams; + +typedef struct +{ + wpt_boolean pause; + wpt_uint32 reserved; +} WDI_HighPriorityDataInfoIndParams; + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +typedef struct +{ + wpt_uint32 reqId; + wpt_macAddr macAddr; + wpt_uint32 mpduSizeThreshold; + wpt_uint32 aggressiveStatisticsGathering; +}WDI_LLStatsSetReqType; + +typedef struct +{ + wpt_uint32 reqId; + wpt_macAddr macAddr; + wpt_uint32 paramIdMask; +}WDI_LLStatsGetReqType; + +typedef struct +{ + wpt_uint32 reqId; + wpt_macAddr macAddr; + wpt_uint32 statsClearReqMask; + wpt_uint8 stopReq; +}WDI_LLStatsClearReqType; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/*--------------------------------------------------------------------------- + WDI_SPOOF_MAC_ADDR_REQ +---------------------------------------------------------------------------*/ +typedef struct +{ + /* Spoof MAC Address for FW */ + wpt_macAddr macAddr; + + /* Reserved Params/fields */ + wpt_uint32 params; + wpt_uint32 reserved; +} WDI_SpoofMacAddrInfoType; + +//This is to force compiler to use the maximum of an int for enum +#define SIR_MAX_ENUM_SIZE 0x7FFFFFFF +// Enum to specify whether key is used +// for TX only, RX only or both +typedef enum +{ + eWDI_TX_ONLY, + eWDI_RX_ONLY, + eWDI_TX_RX, + eWDI_TX_DEFAULT, + eWDI_DONOT_USE_KEY_DIRECTION = SIR_MAX_ENUM_SIZE +} tWDIKeyDirection; + +// MAX key length when ULA is used +#define SIR_MAC_MAX_KEY_LENGTH 32 +/* Max key size including the WAPI and TKIP */ +#define WLAN_MAX_KEY_RSC_LEN 16 +// Definition for Encryption Keys +//typedef struct sSirKeys +typedef struct +{ + wpt_uint8 keyId; + wpt_uint8 unicast; // 0 for multicast + tWDIKeyDirection keyDirection; + wpt_uint8 keyRsc[WLAN_MAX_KEY_RSC_LEN]; // Usage is unknown + wpt_uint8 paeRole; // =1 for authenticator, + // =0 for supplicant + wpt_uint16 keyLength; + wpt_uint8 key[SIR_MAC_MAX_KEY_LENGTH]; +} tWDIKeys, *tpWDIKeys; + +typedef enum +{ + eWDI_WEP_STATIC, + eWDI_WEP_DYNAMIC, +} tWDIWepType; + +// Encryption type enum used with peer +typedef enum +{ + eWDI_ED_NONE, + eWDI_ED_WEP40, + eWDI_ED_WEP104, + eWDI_ED_TKIP, + eWDI_ED_CCMP, +#if defined(FEATURE_WLAN_WAPI) + eWDI_ED_WPI, +#endif + /* DPU HW treats encryption mode 4 plus RMF bit set in TX BD as BIP. + * Thus while setting BIP encryption mode in corresponding DPU Desc + * eSIR_ED_AES_128_CMAC should be set to eSIR_ED_CCMP + */ + eWDI_ED_AES_128_CMAC, + eWDI_ED_NOT_IMPLEMENTED = SIR_MAX_ENUM_SIZE +} tWDIEdType; +#define SIR_WDI_MAX_NUM_OF_DEFAULT_KEYS 4 +/* + * This is used by PE to configure the key information on a given station. + * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate + * a preconfigured key from a BSS the station assoicated with; otherwise + * a new key descriptor is created based on the key field. + */ +typedef struct +{ + wpt_uint16 staIdx; + tWDIEdType encType; // Encryption/Decryption type + tWDIWepType wepType; // valid only for WEP + wpt_uint8 defWEPIdx; // Default WEP key, valid only for static WEP, must between 0 and 3 + tWDIKeys key[SIR_WDI_MAX_NUM_OF_DEFAULT_KEYS]; // valid only for non-static WEP encyrptions + wpt_uint8 singleTidRc; // 1=Single TID based Replay Count, 0=Per TID based RC + wpt_uint8 sessionId; // PE session id for PE<->HAL interface +} tWDISetStaKeyParams, *tpWDISetStaKeyParams; + +typedef struct +{ + tWDISetStaKeyParams keyParams; + wpt_uint8 pn[6]; +}wpt_encConfigParams; + +typedef struct +{ + wpt_uint16 length; + wpt_uint8 data[WDI_DISA_MAX_PAYLOAD_SIZE]; +}wpt_payload; + +typedef struct +{ + wpt_80211Header macHeader; + wpt_encConfigParams encParams; + wpt_payload data; +}wpt_pkt80211; + +#define NUM_FILTERS_SUPPORTED 1 +typedef struct +{ + wpt_macAddr macAddr; + wpt_uint8 isA1filter; + wpt_uint8 isA2filter; + wpt_uint8 isA3filter; +}WDI_filter; + +typedef struct +{ + /* start or stop */ + wpt_uint8 state; + /*Conversion of packet required or not*/ + wpt_uint8 is80211to803ConReq; + wpt_uint32 ChannelNo; + wpt_uint32 ChannelBW; + wpt_uint8 crcCheckEnabled; + wpt_uint8 numOfMacFilters; + WDI_filter mmFilters[NUM_FILTERS_SUPPORTED]; + wpt_uint64 typeSubtypeBitmap; + wpt_uint64 rsvd; + +}WDI_MonStartReqType; + +typedef struct +{ + wpt_uint8 paramType; + wpt_uint32 paramValue; + wpt_macAddr bssId; +}WDI_WifiConfigSetReqType; + +#ifdef DHCP_SERVER_OFFLOAD +/** + * wdi_set_dhcp_server_offload_t - dhcp server offload info + * @bssidx: bss index + * @enable: enable od disable + * @srv_ipv4: server ip address + * @start_lsb: starting lsb addredd of pool + * @num_client: number of clients supported + */ +typedef struct { + wpt_uint8 bssidx; + wpt_uint32 enable; + wpt_uint32 srv_ipv4; /* server IP */ + wpt_uint32 start_lsb; /* starting address assigned to client */ + wpt_uint32 num_client; /* number of clients we support */ +} wdi_set_dhcp_server_offload_t; + +/** + * wdi_dhcp_server_offload_rsp_param_t - dhcp server offload response + * @status: status for the command success or failure + */ +typedef struct +{ + /* wdi status */ + wpt_uint32 status; +} wdi_dhcp_server_offload_rsp_param_t; +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * The purpose of the multicast Domain Name System (mDNS) is to resolve host + * names to IP addresses within small networks that do not include a local + * name server. It utilizes essentially the same programming interfaces, packet + * formats and operating semantics as the unicast DNS, and the advantage is + * zero configuration service while no need for central or global server. + * Based on mDNS, the DNS-SD (Service Discovery) allows clients to discover a + * named list of services by type in a specified domain using standard + * DNS queries. Here, we provide the ability to advertise the available + * services by responding to mDNS queries. + */ + +/** + * wdi_mdns_enable_offload_cmd_req - mdns enable request + * @bss_idx: bss index + * @enable: enable + */ +typedef struct { + wpt_uint8 bss_idx; + wpt_uint32 enable; +} wdi_mdns_enable_offload_cmd_req; + +/** + * wdi_mdns_enable_offload_rsp_param_t - mDNS enable offload response + * @status: status for the command success or failure + */ +typedef struct +{ + wpt_uint32 status; +} wdi_mdns_enable_offload_rsp_param_t; + +#define WMI_MAX_MDNS_FQDN_LEN 64 +#define WMI_MAX_MDNS_RESP_LEN 512 +#define WMI_MDNS_FQDN_TYPE_GENERAL 0 +#define WMI_MDNS_FQDN_TYPE_UNIQUE 1 + +/** + * wdi_mdns_set_fqdn_cmd_req - set fqdn request + * @bss_idx: bss index + * @type: type of fqdn, general or unique + * @fqdn_len: length of fqdn + * @fqdn_data: TLV byte stream of fqdn data of length fqdn_len fully-qualified + * domain name to check if match with the received queries + */ +typedef struct { + wpt_uint8 bss_idx; + wpt_uint32 type; + wpt_uint32 fqdn_len; + wpt_uint8 fqdn_data[WMI_MAX_MDNS_FQDN_LEN]; +} wdi_mdns_set_fqdn_cmd_req; + +/** + * wdi_mdns_set_fqdn_rsp_param_t - mDNS set fqdn response + * @status: status for the command success or failure + */ +typedef struct +{ + wpt_uint32 status; +} wdi_mdns_set_fqdn_rsp_param_t; + +/** + * wdi_mdns_set_resp_req - mDNS response request + * @bss_idx: bss index + * @ar_count: Answer Resource Record count + * @resp_len: length of response + * @resp_data: TLV byte stream of resp data of length resp_len responses consisits of Resource Records + */ +typedef struct { + wpt_uint8 bss_idx; + wpt_uint32 ar_count; + wpt_uint32 resp_len; + wpt_uint8 resp_data[WMI_MAX_MDNS_RESP_LEN]; +} wdi_mdns_set_resp_req; + +/** + * wdi_mdns_set_rsp_param_t - mDNS set response rsp + * @status: status for the command success or failure + */ +typedef struct +{ + wpt_uint32 status; +} wdi_mdns_set_rsp_param_t; + +/** + * wdi_mdns_get_stats_req - get mdns stats request + * @bss_idx: bss index + */ +typedef struct { + wpt_uint8 bss_idx; +} wdi_mdns_get_stats_req; + +/** + * wdi_mdns_stats_rsp_t - mdns stats + * @bss_idx: bss index + * @current_ts: curTimestamp in milliseconds + * @last_querry_ts: last received Query in milliseconds + * @last_resp_ts: last sent Response in milliseconds + * @tot_queries: stats of received queries + * @tot_matches: stats of macth queries + * @tot_rsp: stats of responses + * @status: indicate the current status of mDNS offload + */ +typedef struct { + wpt_uint8 bss_idx; + wpt_uint32 current_ts; + wpt_uint32 last_querry_ts; + wpt_uint32 last_resp_ts; + wpt_uint32 tot_queries; + wpt_uint32 tot_matches; + wpt_uint32 tot_rsp; + wpt_uint32 status; +} wdi_mdns_stats_rsp_param_t; +#endif /* MDNS_OFFLOAD */ + +#ifdef WLAN_FEATURE_APFIND +struct WDI_APFind_cmd +{ + wpt_uint32 data_len; + wpt_uint8 data[]; +}; +#endif + +/** + * struct WDI_FwrMemDumpReqType - firmware memory dump request details. +.*.@FWMemDumpReqCb - Associated Callback + *.@fwMemDumpReqContext - Callback context + * @reserved - reserved field 1. + * + * This structure carries information about the firmware + * memory dump request. + */ +typedef struct +{ + wpt_uint32 reserved1; +}WDI_FwrMemDumpReqType; + +/** + * struct WDI_FwrMemDumpRsp - firmware dump response details. + * + * This structure is used to store the firmware dump + * response from the firmware. + */ +typedef struct +{ + wpt_uint32 dump_status; +}WDI_FwrMemDumpRsp; + +typedef struct +{ + wpt_uint32 wificonfigset_status; +}WDI_WifconfigSetRsp; + +/** + * struct WDI_ModifyRoamParamsReqType - Modified roam parameter details. + * + */ + +typedef struct { + wpt_uint8 param; + wpt_uint32 value; +}WDI_ModifyRoamParamsReqType; + +/** + * struct WDI_AllowedActionFramesInd - Allowed Action frames details + * + */ +struct WDI_AllowedActionFramesInd { + wpt_uint32 bitmask; + wpt_uint32 reserved; +}; + +struct WDI_sap_ofl_enable_params{ + + wpt_macAddr macAddr; + /** enable/disable sap auth offload */ + wpt_uint32 enable; + /** authentication mode (defined above) */ + wpt_uint32 rsn_authmode; + /** unicast cipher set */ + wpt_uint32 rsn_ucastcipherset; + /** mcast/group cipher set */ + wpt_uint32 rsn_mcastcipherset; + /** mcast/group management frames cipher set */ + wpt_uint32 rsn_mcastmgmtcipherset; + /** sap channel */ + wpt_uint32 channel; + /** length of psk */ + wpt_uint32 psk_len; + wpt_uint8 key[64]; +}; + +/** + * wdi_cap_tsf_params_t - wdi capture tsf params + * @bssidx: bss index + * @capTSFget: whether get/set request + * + */ + typedef struct { + wpt_uint8 bss_idx; + wpt_uint8 capTSFget; +} wdi_cap_tsf_params_t; + +/** + * wdi_cap_tsf_rsp_t - capture tsf response + * @bssidx: bss index + * @capTSFget: whether get/set request + * + */ + typedef struct { + wpt_uint32 status; + wpt_uint32 tsf_lo; + wpt_uint32 tsf_hi; +} wdi_cap_tsf_rsp_t; + +/*---------------------------------------------------------------------------- + * WDI callback types + *--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Start response from + the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_StartRspCb)(WDI_StartRspParamsType* pwdiRspParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Stop response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_StopRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received an Init Scan response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_InitScanRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a StartScan response + from the underlying device. + + PARAMETERS + + IN + wdiParams: response params received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_StartScanRspCb)(WDI_StartScanRspParamsType* wdiParams, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a End Scan response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EndScanRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Finish Scan response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_FinishScanRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Join response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_JoinRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Config BSS response + from the underlying device. + + PARAMETERS + + IN + wdiConfigBSSRsp: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigBSSRspCb)( + WDI_ConfigBSSRspParamsType* pwdiConfigBSSRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del BSS response from + the underlying device. + + PARAMETERS + + IN + wdiDelBSSRsp: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelBSSRspCb)(WDI_DelBSSRspParamsType* pwdiDelBSSRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Post Assoc response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_PostAssocRspCb)( + WDI_PostAssocRspParamsType* pwdiPostAssocRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del STA response from + the underlying device. + + PARAMETERS + + IN + wdiDelSTARsp: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelSTARspCb)(WDI_DelSTARspParamsType* pwdiDelSTARsp, + void* pUserData); + + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set BSS Key response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetBSSKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Remove BSS Key + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RemoveBSSKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set STA Key response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetSTAKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Remove STA Key + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RemoveSTAKeyRspCb)(WDI_Status wdiStatus, + void* pUserData); + + +#ifdef FEATURE_WLAN_ESE +/*--------------------------------------------------------------------------- + WDI_TsmRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a TSM Stats response from the underlying device. + + PARAMETERS + + IN + pTSMStats: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_TsmRspCb)(WDI_TSMStatsRspParamsType *pTSMStats, + void* pUserData); +#endif + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Add TS response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddTsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del TS response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelTsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received an Update EDCA Params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateEDCAParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Add BA response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddBASessionRspCb)( + WDI_AddBASessionRspParamsType* wdiAddBASessionRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Del BA response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelBARspCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Switch Ch response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SwitchChRspCb)(WDI_SwitchCHRspParamsType* pwdiSwitchChRsp, + void* pUserData); + +typedef void (*WDI_SwitchChRspCb_V1)(WDI_SwitchChRspParamsType_V1* pwdiSwitchChRsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Config STA response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigSTARspCb)( + WDI_ConfigSTARspParamsType* pwdiConfigSTARsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set Link State + response from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetLinkStateRspCb)( WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Get Stats response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GetStatsRspCb)(WDI_GetStatsRspParamsType* pwdiGetStatsRsp, + void* pUserData); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/*--------------------------------------------------------------------------- + WDI_GetRoamRssiRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Get Roam Rssi response + from the underlying device. + + PARAMETERS + + IN + wdiRspParams: response parameters received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GetRoamRssiRspCb)(WDI_GetRoamRssiRspParamsType* pwdiGetRoamRssiRsp, + void* pUserData); +#endif + + +/*--------------------------------------------------------------------------- + WDI_StartRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Update Cfg response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateCfgRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_AddBARspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a ADD BA response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddBARspCb)(WDI_AddBARspinfoType* wdiAddBARsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_TriggerBARspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a ADD BA response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_TriggerBARspCb)(WDI_TriggerBARspParamsType* wdiTriggerBARsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_UpdateBeaconParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Update Beacon Params response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateBeaconParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SendBeaconParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Send Beacon Params response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SendBeaconParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDA_SetMaxTxPowerRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set max Tx Power response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDA_SetMaxTxPowerRspCb)(WDI_SetMaxTxPowerRspMsg *wdiSetMaxTxPowerRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDA_SetMaxTxPowerPerBandRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a + set max Tx Power Per Band response from the underlying device. + + PARAMETERS + + IN + wdiSetMaxTxPowerPerBandRsp: response status received from HAL + pUserData: user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDA_SetMaxTxPowerPerBandRspCb)(WDI_SetMaxTxPowerPerBandRspMsg + *wdiSetMaxTxPowerPerBandRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDA_SetTxPowerRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set max Tx Power response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDA_SetTxPowerRspCb)(WDI_SetTxPowerRspMsg *wdiSetTxPowerRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_UpdateProbeRspTemplateRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Probe RSP Template + Update response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateProbeRspTemplateRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetP2PGONOAReqParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a P2P GO NOA Params response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetP2PGONOAReqParamsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetTDLSLinkEstablishReqParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a TDLS Link Establish Req response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTDLSLinkEstablishReqParamsRspCb)(WDI_SetTdlsLinkEstablishReqResp * + wdiSetTdlsLinkEstablishReqRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetTDLSChanSwitchReqParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a TDLS Link Establish Req response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTDLSChanSwitchReqParamsRspCb)(WDI_SetTdlsChanSwitchReqResp * + wdiSetTdlsChanSwitchReqRsp, + void* pUserData); +/*--------------------------------------------------------------------------- + WDI_SetPwrSaveCfgCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set Power Save CFG + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetPwrSaveCfgCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetUapsdAcParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set UAPSD params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetUapsdAcParamsCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_EnterImpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Enter IMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EnterImpsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ExitImpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Exit IMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ExitImpsRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_EnterBmpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a enter BMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EnterBmpsRspCb)(WDI_EnterBmpsRspParamsType *pwdiEnterBmpsRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ExitBmpsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a exit BMPS response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ExitBmpsRspCb)( WDI_ExitBmpsRspParamsType *pwdiExitBmpsRspParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_EnterUapsdRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a enter UAPSD response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_EnterUapsdRspCb)( WDI_EnterUapsdRspParamsType *pwdiEnterUapsdRspParam, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ExitUapsdRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a exit UAPSD response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ExitUapsdRspCb)(WDI_ExitUapsdRspParamsType *pwidExitUapsdRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_UpdateUapsdParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a update UAPSD params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateUapsdParamsCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ConfigureRxpFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a config RXP filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigureRxpFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetBeaconFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set beacon filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetBeaconFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_RemBeaconFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a remove beacon filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RemBeaconFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetRSSIThresholdsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a set RSSI thresholds + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetRSSIThresholdsCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_HostOffloadCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a host offload + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_HostOffloadCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_KeepAliveCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Keep Alive + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_KeepAliveCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlAddBcPtrnCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl add Bcast ptrn + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlAddBcPtrnCb)( WDI_WowlAddBcPtrnRspParamsType *pwdiWowlAddBcPtrnParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlDelBcPtrnCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl delete Bcast ptrn + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlDelBcPtrnCb)( WDI_WowlDelBcPtrnRspParamsType *pwdiWowlDelBcstPtrRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlEnterReqCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl enter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlEnterReqCb)( WDI_WowlEnterRspParamsType *pwdiwowlEnterRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_WowlExitReqCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Wowl exit + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_WowlExitReqCb)( WDI_WowlExitRspParamsType *pwdiWowlExitRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ConfigureAppsCpuWakeupStateCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a config Apps Cpu Wakeup + State response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ConfigureAppsCpuWakeupStateCb)(WDI_Status wdiStatus, + void* pUserData); +/*--------------------------------------------------------------------------- + WDI_NvDownloadRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a NV Download response + from the underlying device. + + PARAMETERS + + IN + wdiStatus:response status received from HAL + pUserData:user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_NvDownloadRspCb)(WDI_NvDownloadRspInfoType* wdiNvDownloadRsp, + void* pUserData); +/*--------------------------------------------------------------------------- + WDI_FlushAcRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Flush AC response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_FlushAcRspCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_BtAmpEventRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Bt AMP event response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_BtAmpEventRspCb)(WDI_Status wdiStatus, + void* pUserData); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/*--------------------------------------------------------------------------- + WDI_oemDataRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Start oem data response from + the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_oemDataRspCb)(WDI_oemDataRspParamsType* wdiOemDataRspParams, + void* pUserData); + +#endif + +/*--------------------------------------------------------------------------- + WDI_HostResumeEventRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Bt AMP event response + from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_HostResumeEventRspCb)( + WDI_SuspendResumeRspParamsType *resumeRspParams, + void* pUserData); + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/*--------------------------------------------------------------------------- + WDI_AggrAddTsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Aggregated Add TS + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AggrAddTsRspCb)(WDI_Status wdiStatus, + void* pUserData); +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/*--------------------------------------------------------------------------- + WDI_FTMCommandRspCb + + DESCRIPTION + + FTM Command response CB + + PARAMETERS + + IN + ftmCMDRspdata: FTM response data from HAL + pUserData: user data + + + RETURN VALUE + NONE +---------------------------------------------------------------------------*/ +typedef void (*WDI_FTMCommandRspCb)(void *ftmCMDRspdata, + void *pUserData); + +/*--------------------------------------------------------------------------- + WDI_AddSTASelfParamsRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Add Sta Self Params + response from the underlying device. + + PARAMETERS + + IN + wdiAddSelfSTARsp: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_AddSTASelfParamsRspCb)( + WDI_AddSTASelfRspParamsType* pwdiAddSelfSTARsp, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDI_DelSTASelfRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a host offload + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_DelSTASelfRspCb) +( +WDI_DelSTASelfRspParamsType* wdiDelStaSelfRspParams, +void* pUserData +); + +#ifdef FEATURE_WLAN_SCAN_PNO +/*--------------------------------------------------------------------------- + WDI_PNOScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set PNO + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_PNOScanCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_PNOScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set PNO + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RssiFilterCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_UpdateScanParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Update Scan Params + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_UpdateScanParamsCb)(WDI_Status wdiStatus, + void* pUserData); +#endif // FEATURE_WLAN_SCAN_PNO + +typedef void (*WDI_UpdateChannelRspCb)(WDI_Status wdiStatus, + void* pUserData); + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/*--------------------------------------------------------------------------- + WDI_RoamOffloadScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Start Roam Candidate Lookup Req + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_RoamOffloadScanCb)(WDI_Status wdiStatus, + void* pUserData); + +typedef void (*WDI_PERRoamOffloadScanCb)(WDI_Status wdiStatus, void *pUserData); +typedef void (*WDI_PERRoamTriggerScanCb)(WDI_Status wdiStatus, void *pUserData); +#endif +/*--------------------------------------------------------------------------- + WDI_SetTxPerTrackingRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Tx PER Tracking + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTxPerTrackingRspCb)(WDI_Status wdiStatus, + void* pUserData); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/*--------------------------------------------------------------------------- + WDI_8023MulticastListCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a 8023 Multicast List + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_8023MulticastListCb)( + WDI_RcvFltPktSetMcListRspParamsType *pwdiRcvFltPktSetMcListRspInfo, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ReceiveFilterSetFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Receive Filter Set Filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ReceiveFilterSetFilterCb)( + WDI_SetRcvPktFilterRspParamsType *pwdiSetRcvPktFilterRspInfo, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_FilterMatchCountCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Do PC Filter Match Count + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_FilterMatchCountCb)( + WDI_RcvFltPktMatchCntRspParamsType *pwdiRcvFltPktMatchRspParams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_ReceiveFilterClearFilterCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Receive Filter Clear Filter + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_ReceiveFilterClearFilterCb)( + WDI_RcvFltPktClearRspParamsType *pwdiRcvFltPktClearRspParamsType, + void* pUserData); +#endif // WLAN_FEATURE_PACKET_FILTERING + +/*--------------------------------------------------------------------------- + WDI_HALDumpCmdRspCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a HAL DUMP Command +response from + the HAL layer. + + PARAMETERS + + IN + wdiHalDumpCmdRsp: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_HALDumpCmdRspCb)(WDI_HALDumpCmdRspParamsType* wdiHalDumpCmdRsp, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_SetPowerParamsCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set Power Param + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetPowerParamsCb)(WDI_Status wdiStatus, + void* pUserData); + + +/*--------------------------------------------------------------------------- + WDA_FwrMemDumpRespCallback + + DESCRIPTION + + This callback is invoked by DAL when it has received a Fwr Mem dump + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + ---------------------------------------------------------------------------*/ +typedef void (* WDI_FwrMemDumpCb) (WDI_FwrMemDumpRsp* wdiRsp, + void* pUserData); + + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/*--------------------------------------------------------------------------- + WDI_GtkOffloadCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a GTK offload + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GtkOffloadCb)( WDI_GtkOffloadRspParams *pwdiGtkOffloadRsparams, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_GtkOffloadGetInfoCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a GTK offload + information response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_GtkOffloadGetInfoCb)( WDI_GtkOffloadGetInfoRspParams *pwdiGtkOffloadGetInfoRsparams, + void* pUserData); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/*--------------------------------------------------------------------------- + WDI_SetTmLevelCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a Set New TM Level + done response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetTmLevelCb)(WDI_Status wdiStatus, + void* pUserData); + +/*--------------------------------------------------------------------------- + WDI_featureCapsExchangeCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a HAL Feature Capbility + Exchange Response the HAL layer. This callback is put to mantain code + similarity and is not being used right now. + + PARAMETERS + + IN + wdiFeatCapRspParams: response parameters received from HAL + pUserData: user data + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_featureCapsExchangeCb)(void* wdiFeatCapRspParams, + void* pUserData); + +#ifdef WLAN_FEATURE_11AC +typedef void (*WDI_UpdateVHTOpModeCb)(WDI_Status wdiStatus, + void* pUserData); +#endif + +#ifdef FEATURE_WLAN_LPHB +typedef void (*WDI_LphbCfgCb)(WDI_Status wdiStatus, + void* pUserData); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef WLAN_FEATURE_RMC +typedef void (*WDI_RmcRulerRspCb)(WDI_RmcRspParamsType *wdiRmcResponse, + void* pUserData); + +typedef void (*WDI_IbssPeerInfoReqCb)(WDI_IbssPeerInfoRspParams *pInfoRspParams, + void* pUserData); + +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +/*--------------------------------------------------------------------------- + WDI_SetBatchScanCb + + DESCRIPTION + + This callback is invoked by DAL when it has received a get batch scan + response from the underlying device. + + PARAMETERS + + IN + wdiStatus: response status received from HAL + pUserData: user data + + + + RETURN VALUE + The result code associated with performing the operation +---------------------------------------------------------------------------*/ +typedef void (*WDI_SetBatchScanCb)(void *pData, WDI_SetBatchScanRspType *pRsp); + +#endif + +typedef void (*WDI_GetBcnMissRateCb)(wpt_uint8 status, wpt_uint32 bcnMissRate, + void* pUserData); + +#ifdef WLAN_FEATURE_EXTSCAN +typedef void (*WDI_EXTScanStartRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_EXTScanStopRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_EXTScanGetCachedResultsRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_EXTScanGetCapabilitiesRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_EXTScanSetBSSIDHotlistRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_EXTScanResetBSSIDHotlistRspCb)(void *pEventData, + void *pUserData); + + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +typedef void (*WDI_LLStatsSetRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_LLStatsGetRspCb)(void *pEventData, + void *pUserData); +typedef void (*WDI_LLStatsClearRspCb)(void *pEventData, + void *pUserData); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +typedef void (*WDI_SetSpoofMacAddrRspCb)( + WDI_SpoofMacAddrRspParamType* wdiRsp, void *pUserData); + +typedef void (*WDI_FWStatsGetRspCb)(WDI_Status status,void *fwStatsResp, + void *pUserData); + +typedef void (*WDI_EncryptMsgRspCb)(wpt_uint8 status, void *pEventData, void* pUserData); +typedef void (*WDI_FWLoggingInitRspCb)( + WDI_FWLoggingInitRspParamType *wdiRsp, void *pUserData); +typedef void (*WDI_GetFrameLogRspCb)( + WDI_GetFrameLogRspParamType *wdiRsp, void *pUserData); +typedef void (*WDI_FatalEventLogsRspCb)( + WDI_FatalEventLogsRspParamType *wdiRsp, void *pUserData); + +typedef void (*WDI_MonModeRspCb)(void *pEventData,void *pUserData); +typedef void (*WDI_RssiMonitorStartRspCb)(void *pEventData,void *pUserData); +typedef void (*WDI_RssiMonitorStopRspCb)(void *pEventData,void *pUserData); + +typedef void (*WDI_FwrMemDumpRspCb)(WDI_FwrMemDumpRsp *wdiRsp, void *pUserData); + +typedef void (*WDI_WifiConfigSetRspCb) (WDI_WifconfigSetRsp *wdiRsp, void *pUserData); + +typedef void (*WDI_AntennaDivSelRspCb)(WDI_Status status, + void *resp, void *pUserData); + +typedef void (*wdi_nud_set_arp_rsp_cb)(void *event_data,void *user_data); +typedef void (*wdi_nud_get_arp_rsp_cb)(void *event_data,void *user_data); + +#ifdef DHCP_SERVER_OFFLOAD +typedef void (*wdi_dhcp_srv_offload_rsp_cb)(void *event_data,void *user_data); +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD +typedef void (*wdi_mdns_enable_rsp_cb)(void *event_data,void *user_data); +typedef void (*wdi_mdns_fqdn_rsp_cb)(void *event_data,void *user_data); +typedef void (*wdi_mdns_resp_rsp_cb)(void *event_data,void *user_data); +typedef void (*wdi_get_stats_rsp_cb)(void *event_data,void *user_data); +#endif /* MDNS_OFFLOAD */ + +typedef void (*wdi_tsf_rsp_cb)(void *event_data,void *user_data); + + +/*======================================================================== + * Function Declarations and Documentation + ==========================================================================*/ + +/*======================================================================== + + INITIALIZATION APIs + +==========================================================================*/ + +/** + @brief WDI_Init is used to initialize the DAL. + + DAL will allocate all the resources it needs. It will open PAL, it will also + open both the data and the control transport which in their turn will open + DXE/SMD or any other drivers that they need. + + @param devHandle: pointer to the OS specific device handle + ppWDIGlobalCtx: output pointer of Global Context + pWdiDevCapability: output pointer of device capability + + @return Result of the function call +*/ +WDI_Status +WDI_Init +( + void* devHandle, + void** ppWDIGlobalCtx, + WDI_DeviceCapabilityType* pWdiDevCapability, + unsigned int driverType +); + +/** + @brief WDI_Start will be called when the upper MAC is ready to + commence operation with the WLAN Device. Upon the call + of this API the WLAN DAL will pack and send a HAL Start + message to the lower RIVA sub-system if the SMD channel + has been fully opened and the RIVA subsystem is up. + + If the RIVA sub-system is not yet up and running DAL + will queue the request for Open and will wait for the + SMD notification before attempting to send down the + message to HAL. + + WDI_Init must have been called. + + @param wdiStartParams: the start parameters as specified by + the Device Interface + + wdiStartRspCb: callback for passing back the response of + the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_Start +( + WDI_StartReqParamsType* pwdiStartParams, + WDI_StartRspCb wdiStartRspCb, + void* pUserData +); + + +/** + @brief WDI_Stop will be called when the upper MAC is ready to + stop any operation with the WLAN Device. Upon the call + of this API the WLAN DAL will pack and send a HAL Stop + message to the lower RIVA sub-system if the DAL Core is + in started state. + + In state BUSY this request will be queued. + + Request will not be accepted in any other state. + + WDI_Start must have been called. + + @param wdiStopParams: the stop parameters as specified by + the Device Interface + + wdiStopRspCb: callback for passing back the response of + the stop operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_Stop +( + WDI_StopReqParamsType* pwdiStopParams, + WDI_StopRspCb wdiStopRspCb, + void* pUserData +); + +/** + @brief WDI_Close will be called when the upper MAC no longer + needs to interract with DAL. DAL will free its control + block. + + It is only accepted in state STOPPED. + + WDI_Stop must have been called. + + @param none + + @see WDI_Stop + @return Result of the function call +*/ +WDI_Status +WDI_Close +( + void +); + + +/** + @brief WDI_Shutdown will be called during 'SSR shutdown' operation. + This will do most of the WDI stop & close + operations without doing any handshake with Riva + + This will also make sure that the control transport + will NOT be closed. + + This request will not be queued. + + + WDI_Start must have been called. + + @param closeTransport: Close control channel if this is set + + @return Result of the function call +*/ +WDI_Status +WDI_Shutdown +( + wpt_boolean closeTransport +); + +/*======================================================================== + + SCAN APIs + +==========================================================================*/ + +/** + @brief WDI_InitScanReq will be called when the upper MAC wants + the WLAN Device to get ready for a scan procedure. Upon + the call of this API the WLAN DAL will pack and send a + HAL Init Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiInitScanParams: the init scan parameters as specified + by the Device Interface + + wdiInitScanRspCb: callback for passing back the response + of the init scan operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_InitScanReq +( + WDI_InitScanReqParamsType* pwdiInitScanParams, + WDI_InitScanRspCb wdiInitScanRspCb, + void* pUserData +); + +/** + @brief WDI_StartScanReq will be called when the upper MAC + wishes to change the Scan channel on the WLAN Device. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_InitScanReq must have been called. + + @param wdiStartScanParams: the start scan parameters as + specified by the Device Interface + + wdiStartScanRspCb: callback for passing back the + response of the start scan operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_InitScanReq + @return Result of the function call +*/ +WDI_Status +WDI_StartScanReq +( + WDI_StartScanReqParamsType* pwdiStartScanParams, + WDI_StartScanRspCb wdiStartScanRspCb, + void* pUserData +); + + +/** + @brief WDI_EndScanReq will be called when the upper MAC is + wants to end scanning for a particular channel that it + had set before by calling Scan Start on the WLAN Device. + Upon the call of this API the WLAN DAL will pack and + send a HAL End Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_StartScanReq must have been called. + + @param wdiEndScanParams: the end scan parameters as specified + by the Device Interface + + wdiEndScanRspCb: callback for passing back the response + of the end scan operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_StartScanReq + @return Result of the function call +*/ +WDI_Status +WDI_EndScanReq +( + WDI_EndScanReqParamsType* pwdiEndScanParams, + WDI_EndScanRspCb wdiEndScanRspCb, + void* pUserData +); + + +/** + @brief WDI_FinishScanReq will be called when the upper MAC has + completed the scan process on the WLAN Device. Upon the + call of this API the WLAN DAL will pack and send a HAL + Finish Scan Request request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_InitScanReq must have been called. + + @param wdiFinishScanParams: the finish scan parameters as + specified by the Device Interface + + wdiFinishScanRspCb: callback for passing back the + response of the finish scan operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_InitScanReq + @return Result of the function call +*/ +WDI_Status +WDI_FinishScanReq +( + WDI_FinishScanReqParamsType* pwdiFinishScanParams, + WDI_FinishScanRspCb wdiFinishScanRspCb, + void* pUserData +); + +/*======================================================================== + + ASSOCIATION APIs + +==========================================================================*/ + +/** + @brief WDI_JoinReq will be called when the upper MAC is ready + to start an association procedure to a BSS. Upon the + call of this API the WLAN DAL will pack and send a HAL + Join request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiJoinParams: the join parameters as specified by + the Device Interface + + wdiJoinRspCb: callback for passing back the response of + the join operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_JoinReq +( + WDI_JoinReqParamsType* pwdiJoinParams, + WDI_JoinRspCb wdiJoinRspCb, + void* pUserData +); + +/** + @brief WDI_ConfigBSSReq will be called when the upper MAC + wishes to configure the newly acquired or in process of + being acquired BSS to the HW . Upon the call of this API + the WLAN DAL will pack and send a HAL Config BSS request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiConfigBSSParams: the config BSS parameters as + specified by the Device Interface + + wdiConfigBSSRspCb: callback for passing back the + response of the config BSS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinReq + @return Result of the function call +*/ +WDI_Status +WDI_ConfigBSSReq +( + WDI_ConfigBSSReqParamsType* pwdiConfigBSSParams, + WDI_ConfigBSSRspCb wdiConfigBSSRspCb, + void* pUserData +); + +/** + @brief WDI_DelBSSReq will be called when the upper MAC is + dissasociating from the BSS and wishes to notify HW. + Upon the call of this API the WLAN DAL will pack and + send a HAL Del BSS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_ConfigBSSReq or WDI_PostAssocReq must have been called. + + @param wdiDelBSSParams: the del BSS parameters as specified by + the Device Interface + + wdiDelBSSRspCb: callback for passing back the response + of the del bss operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_ConfigBSSReq, WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelBSSReq +( + WDI_DelBSSReqParamsType* pwdiDelBSSParams, + WDI_DelBSSRspCb wdiDelBSSRspCb, + void* pUserData +); + +/** + @brief WDI_PostAssocReq will be called when the upper MAC has + associated to a BSS and wishes to configure HW for + associated state. Upon the call of this API the WLAN DAL + will pack and send a HAL Post Assoc request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiPostAssocReqParams: the assoc parameters as specified + by the Device Interface + + wdiPostAssocRspCb: callback for passing back the + response of the post assoc operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinReq + @return Result of the function call +*/ +WDI_Status +WDI_PostAssocReq +( + WDI_PostAssocReqParamsType* pwdiPostAssocReqParams, + WDI_PostAssocRspCb wdiPostAssocRspCb, + void* pUserData +); + +/** + @brief WDI_DelSTAReq will be called when the upper MAC when an + association with another STA has ended and the station + must be deleted from HW. Upon the call of this API the + WLAN DAL will pack and send a HAL Del STA request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiDelSTAParams: the Del STA parameters as specified by + the Device Interface + + wdiDelSTARspCb: callback for passing back the response + of the del STA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelSTAReq +( + WDI_DelSTAReqParamsType* pwdiDelSTAParams, + WDI_DelSTARspCb wdiDelSTARspCb, + void* pUserData +); + +/*======================================================================== + + SECURITY APIs + +==========================================================================*/ + +/** + @brief WDI_SetBSSKeyReq will be called when the upper MAC ito + install a BSS encryption key on the HW. Upon the call of + this API the WLAN DAL will pack and send a HAL Start + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSetBSSKeyParams: the BSS Key set parameters as + specified by the Device Interface + + wdiSetBSSKeyRspCb: callback for passing back the + response of the set BSS Key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetBSSKeyReq +( + WDI_SetBSSKeyReqParamsType* pwdiSetBSSKeyParams, + WDI_SetBSSKeyRspCb wdiSetBSSKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_RemoveBSSKeyReq will be called when the upper MAC to + uninstall a BSS key from HW. Upon the call of this API + the WLAN DAL will pack and send a HAL Remove BSS Key + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetBSSKeyReq must have been called. + + @param wdiRemoveBSSKeyParams: the remove BSS key parameters as + specified by the Device Interface + + wdiRemoveBSSKeyRspCb: callback for passing back the + response of the remove BSS key operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetBSSKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveBSSKeyReq +( + WDI_RemoveBSSKeyReqParamsType* pwdiRemoveBSSKeyParams, + WDI_RemoveBSSKeyRspCb wdiRemoveBSSKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_SetSTAKeyReq will be called when the upper MAC is + ready to install a STA(ast) encryption key in HW. Upon + the call of this API the WLAN DAL will pack and send a + HAL Set STA Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSetSTAKeyParams: the set STA key parameters as + specified by the Device Interface + + wdiSetSTAKeyRspCb: callback for passing back the + response of the set STA key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetSTAKeyReq +( + WDI_SetSTAKeyReqParamsType* pwdiSetSTAKeyParams, + WDI_SetSTAKeyRspCb wdiSetSTAKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_RemoveSTAKeyReq will be called when the upper MAC + wants to unistall a previously set STA key in HW. Upon + the call of this API the WLAN DAL will pack and send a + HAL Remove STA Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTAKeyReq must have been called. + + @param wdiRemoveSTAKeyParams: the remove STA key parameters as + specified by the Device Interface + + wdiRemoveSTAKeyRspCb: callback for passing back the + response of the remove STA key operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetSTAKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveSTAKeyReq +( + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTAKeyParams, + WDI_RemoveSTAKeyRspCb wdiRemoveSTAKeyRspCb, + void* pUserData +); + +/** + @brief WDI_SetSTABcastKeyReq will be called when the upper MAC + wants to install a STA Bcast encryption key on the HW. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiSetSTABcastKeyParams: the BSS Key set parameters as + specified by the Device Interface + + wdiSetSTABcastKeyRspCb: callback for passing back the + response of the set BSS Key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetSTABcastKeyReq +( + WDI_SetSTAKeyReqParamsType* pwdiSetSTABcastKeyParams, + WDI_SetSTAKeyRspCb wdiSetSTABcastKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_RemoveSTABcastKeyReq will be called when the upper + MAC to uninstall a STA Bcast key from HW. Upon the call + of this API the WLAN DAL will pack and send a HAL Remove + STA Bcast Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTABcastKeyReq must have been called. + + @param pwdiRemoveSTABcastKeyParams: the remove BSS key + parameters as specified by the Device + Interface + + wdiRemoveSTABcastKeyRspCb: callback for passing back the + response of the remove STA Bcast key operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetSTABcastKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveSTABcastKeyReq +( + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTABcastKeyParams, + WDI_RemoveSTAKeyRspCb wdiRemoveSTABcastKeyRspCb, + void* pUserData +); + + +/** + @brief WDI_SetTxPowerReq will be called when the upper + MAC wants to set Tx Power to HW. + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiSetTxPowerParams: set TS Power parameters + BSSID and target TX Power with dbm included + + wdiReqStatusCb: callback for passing back the response + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTxPowerReq +( + WDI_SetTxPowerParamsType* pwdiSetTxPowerParams, + WDA_SetTxPowerRspCb wdiReqStatusCb, + void* pUserData +); + +/** + @brief WDI_SetMaxTxPowerReq will be called when the upper + MAC wants to set Max Tx Power to HW. Upon the + call of this API the WLAN DAL will pack and send a HAL + Remove STA Bcast Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTABcastKeyReq must have been called. + + @param pwdiRemoveSTABcastKeyParams: the remove BSS key + parameters as specified by the Device + Interface + + wdiRemoveSTABcastKeyRspCb: callback for passing back the + response of the remove STA Bcast key operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetMaxTxPowerReq + @return Result of the function call +*/ +WDI_Status +WDI_SetMaxTxPowerReq +( + WDI_SetMaxTxPowerParamsType* pwdiSetMaxTxPowerParams, + WDA_SetMaxTxPowerRspCb wdiReqStatusCb, + void* pUserData +); + +/** + @brief WDI_SetMaxTxPowerPerBandReq will be called when the upper + MAC wants to set Max Tx Power to HW for specific band. Upon the + call of this API the WLAN DAL will pack and send a HAL + Set Max Tx Power Per Band request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param WDI_SetMaxTxPowerPerBandParamsType: Max Tx Per Band Info + + WDA_SetMaxTxPowerPerBandRspCb: This callback is invoked by DAL + when it has received a set max Tx Power Per Band response from + the underlying device. + + pUserData: user data will be passed back with the + callback + + @see WDI_SetMaxTxPowerPerBandReq + @return Result of the function call +*/ +WDI_Status +WDI_SetMaxTxPowerPerBandReq +( + WDI_SetMaxTxPowerPerBandParamsType* pwdiSetMaxTxPowerPerBandParams, + WDA_SetMaxTxPowerPerBandRspCb wdiReqStatusCb, + void* pUserData +); + +#ifdef FEATURE_WLAN_ESE +/** + @brief WDI_TSMStatsReq will be called by the upper MAC to fetch + Traffic Stream metrics. + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + @param wdiAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_TSMStatsReq +( + WDI_TSMStatsReqParamsType* pwdiTsmStatsReqParams, + WDI_TsmRspCb wdiTsmStatsRspCb, + void* pUserData +); + + +#endif + +/*======================================================================== + + QoS and BA APIs + +==========================================================================*/ + +/** + @brief WDI_AddTSReq will be called when the upper MAC to inform + the device of a successful add TSpec negotiation. HW + needs to receive the TSpec Info from the UMAC in order + to configure properly the QoS data traffic. Upon the + call of this API the WLAN DAL will pack and send a HAL + Add TS request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddTSReq +( + WDI_AddTSReqParamsType* pwdiAddTsReqParams, + WDI_AddTsRspCb wdiAddTsRspCb, + void* pUserData +); + + + +/** + @brief WDI_DelTSReq will be called when the upper MAC has ended + admission on a specific AC. This is to inform HW that + QoS traffic parameters must be rest. Upon the call of + this API the WLAN DAL will pack and send a HAL Del TS + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddTSReq must have been called. + + @param wdiDelTsReqParams: the del TS parameters as specified by + the Device Interface + + wdiDelTsRspCb: callback for passing back the response of + the del TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddTSReq + @return Result of the function call +*/ +WDI_Status +WDI_DelTSReq +( + WDI_DelTSReqParamsType* pwdiDelTsReqParams, + WDI_DelTsRspCb wdiDelTsRspCb, + void* pUserData +); + + + +/** + @brief WDI_UpdateEDCAParams will be called when the upper MAC + wishes to update the EDCA parameters used by HW for QoS + data traffic. Upon the call of this API the WLAN DAL + will pack and send a HAL Update EDCA Params request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiUpdateEDCAParams: the start parameters as specified + by the Device Interface + + wdiUpdateEDCAParamsRspCb: callback for passing back the + response of the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateEDCAParams +( + WDI_UpdateEDCAParamsType* pwdiUpdateEDCAParams, + WDI_UpdateEDCAParamsRspCb wdiUpdateEDCAParamsRspCb, + void* pUserData +); + + + +/** + @brief WDI_AddBASessionReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddBASessionReq +( + WDI_AddBASessionReqParamsType* pwdiAddBASessionReqParams, + WDI_AddBASessionRspCb wdiAddBASessionRspCb, + void* pUserData +); + + +/** + @brief WDI_DelBAReq will be called when the upper MAC wants to + inform HW that it has deleted a previously created BA + session. Upon the call of this API the WLAN DAL will + pack and send a HAL Del BA request message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddBAReq must have been called. + + @param wdiDelBAReqParams: the del BA parameters as specified by + the Device Interface + + wdiDelBARspCb: callback for passing back the response of + the del BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_DelBAReq +( + WDI_DelBAReqParamsType* pwdiDelBAReqParams, + WDI_DelBARspCb wdiDelBARspCb, + void* pUserData +); + +/** + @brief WDI_UpdateBeaconParamsReq will be called when the upper MAC wants to + inform HW that there is a change in the beacon parameters + Upon the call of this API the WLAN DAL will + pack and send a UpdateBeacon Params message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_UpdateBeaconParamsReq must have been called. + + @param WDI_UpdateBeaconParamsType: the Update Beacon parameters as specified by + the Device Interface + + WDI_UpdateBeaconParamsRspCb: callback for passing back the response of + the Update Beacon Params operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_UpdateBeaconParamsReq +( + WDI_UpdateBeaconParamsType * pwdiUpdateBeaconParams, + WDI_UpdateBeaconParamsRspCb wdiUpdateBeaconParamsRspCb, + void* pUserData +); + + +/** + @brief WDI_SendBeaconParamsReq will be called when the upper MAC wants to + update the beacon template to be transmitted as BT MAP STA/IBSS/Soft AP + Upon the call of this API the WLAN DAL will + pack and send the beacon Template message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SendBeaconParamsReq must have been called. + + @param WDI_SendBeaconParamsType: the Update Beacon parameters as specified by + the Device Interface + + WDI_SendBeaconParamsRspCb: callback for passing back the response of + the Send Beacon Params operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_SendBeaconParamsReq +( + WDI_SendBeaconParamsType* pwdiSendBeaconParams, + WDI_SendBeaconParamsRspCb wdiSendBeaconParamsRspCb, + void* pUserData +); + + +/** + @brief WDI_UpdateProbeRspTemplateReq will be called when the + upper MAC wants to update the probe response template to + be transmitted as Soft AP + Upon the call of this API the WLAN DAL will + pack and send the probe rsp template message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiUpdateProbeRspParams: the Update Beacon parameters as + specified by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the Send Beacon Params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_UpdateProbeRspTemplateReq +( + WDI_UpdateProbeRspTemplateParamsType* pwdiUpdateProbeRspParams, + WDI_UpdateProbeRspTemplateRspCb wdiSendBeaconParamsRspCb, + void* pUserData +); + +/** + @brief WDI_SetP2PGONOAReq will be called when the + upper MAC wants to send Notice of Absence + Upon the call of this API the WLAN DAL will + pack and send the probe rsp template message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiUpdateProbeRspParams: the Update Beacon parameters as + specified by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the Send Beacon Params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_SetP2PGONOAReq +( + WDI_SetP2PGONOAReqParamsType* pwdiP2PGONOAReqParams, + WDI_SetP2PGONOAReqParamsRspCb wdiP2PGONOAReqParamsRspCb, + void* pUserData +); + +/** + @brief WDI_SetTDLSLinkEstablishReq will be called when the + upper MAC wants to send TDLS Link Establish Request Parameters + Upon the call of this API the WLAN DAL will + pack and send the TDLS Link Establish Request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiTDLSLinkEstablishReqParams: TDLS Peer Parameters + for Link Establishment (Used for PUAPSD , TDLS Off Channel ...) + + wdiTDLSLinkEstablishReqRspCb: callback for passing back the + response of the TDLS Link Establish request received + from the device + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SetTDLSLinkEstablishReq +( + WDI_SetTDLSLinkEstablishReqParamsType* pwdiTDLSLinkEstablishReqParams, + WDI_SetTDLSLinkEstablishReqParamsRspCb wdiTDLSLinkEstablishReqRspCb, + void* pUserData +); + +WDI_Status +WDI_SetTDLSChanSwitchReq +( + WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams, + WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchRReqRspCb, + void* pUserData +); +/*======================================================================== + + Power Save APIs + +==========================================================================*/ + +/** + @brief WDI_SetPwrSaveCfgReq will be called when the upper MAC + wants to set the power save related configurations of + the WLAN Device. Upon the call of this API the WLAN DAL + will pack and send a HAL Update CFG request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param pwdiPowerSaveCfg: the power save cfg parameters as + specified by the Device Interface + + wdiSetPwrSaveCfgCb: callback for passing back the + response of the set power save cfg operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SetPwrSaveCfgReq +( + WDI_UpdateCfgReqParamsType* pwdiPowerSaveCfg, + WDI_SetPwrSaveCfgCb wdiSetPwrSaveCfgCb, + void* pUserData +); + +/** + @brief WDI_EnterImpsReq will be called when the upper MAC to + request the device to get into IMPS power state. Upon + the call of this API the WLAN DAL will send a HAL Enter + IMPS request message to the lower RIVA sub-system if DAL + is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiEnterImpsRspCb: callback for passing back the + response of the Enter IMPS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_EnterImpsReq +( + WDI_EnterImpsReqParamsType *pwdiEnterImpsReqParams, + WDI_EnterImpsRspCb wdiEnterImpsRspCb, + void* pUserData +); + +/** + @brief WDI_ExitImpsReq will be called when the upper MAC to + request the device to get out of IMPS power state. Upon + the call of this API the WLAN DAL will send a HAL Exit + IMPS request message to the lower RIVA sub-system if DAL + is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + + @param wdiExitImpsRspCb: callback for passing back the response + of the Exit IMPS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_ExitImpsReq +( + WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams, + WDI_ExitImpsRspCb wdiExitImpsRspCb, + void* pUserData +); + +/** + @brief WDI_EnterBmpsReq will be called when the upper MAC to + request the device to get into BMPS power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Enter BMPS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiEnterBmpsReqParams: the Enter BMPS parameters as + specified by the Device Interface + + wdiEnterBmpsRspCb: callback for passing back the + response of the Enter BMPS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_EnterBmpsReq +( + WDI_EnterBmpsReqParamsType *pwdiEnterBmpsReqParams, + WDI_EnterBmpsRspCb wdiEnterBmpsRspCb, + void* pUserData +); + +/** + @brief WDI_ExitBmpsReq will be called when the upper MAC to + request the device to get out of BMPS power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Exit BMPS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiExitBmpsReqParams: the Exit BMPS parameters as + specified by the Device Interface + + wdiExitBmpsRspCb: callback for passing back the response + of the Exit BMPS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ExitBmpsReq +( + WDI_ExitBmpsReqParamsType *pwdiExitBmpsReqParams, + WDI_ExitBmpsRspCb wdiExitBmpsRspCb, + void* pUserData +); + +/** + @brief WDI_EnterUapsdReq will be called when the upper MAC to + request the device to get into UAPSD power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Enter UAPSD request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + WDI_SetUapsdAcParamsReq must have been called. + + @param pwdiEnterUapsdReqParams: the Enter UAPSD parameters as + specified by the Device Interface + + wdiEnterUapsdRspCb: callback for passing back the + response of the Enter UAPSD operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq, WDI_SetUapsdAcParamsReq + @return Result of the function call +*/ +WDI_Status +WDI_EnterUapsdReq +( + WDI_EnterUapsdReqParamsType *pwdiEnterUapsdReqParams, + WDI_EnterUapsdRspCb wdiEnterUapsdRspCb, + void* pUserData +); + +/** + @brief WDI_ExitUapsdReq will be called when the upper MAC to + request the device to get out of UAPSD power state. Upon + the call of this API the WLAN DAL will send a HAL Exit + UAPSD request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiExitUapsdRspCb: callback for passing back the + response of the Exit UAPSD operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ExitUapsdReq +( + WDI_ExitUapsdReqParamsType *pwdiExitUapsdReqParams, + WDI_ExitUapsdRspCb wdiExitUapsdRspCb, + void* pUserData +); + +/** + @brief WDI_UpdateUapsdParamsReq will be called when the upper + MAC wants to set the UAPSD related configurations + of an associated STA (while acting as an AP) to the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Update UAPSD params request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_ConfigBSSReq must have been called. + + @param pwdiUpdateUapsdReqParams: the UAPSD parameters + as specified by the Device Interface + + wdiUpdateUapsdParamsCb: callback for passing back the + response of the update UAPSD params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_ConfigBSSReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateUapsdParamsReq +( + WDI_UpdateUapsdReqParamsType *pwdiUpdateUapsdReqParams, + WDI_UpdateUapsdParamsCb wdiUpdateUapsdParamsCb, + void* pUserData +); + +/** + @brief WDI_SetUapsdAcParamsReq will be called when the upper + MAC wants to set the UAPSD related configurations before + requesting for enter UAPSD power state to the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Set UAPSD params request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiUapsdInfo: the UAPSD parameters as specified by + the Device Interface + + wdiSetUapsdAcParamsCb: callback for passing back the + response of the set UAPSD params operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetUapsdAcParamsReq +( + WDI_SetUapsdAcParamsReqParamsType* pwdiPowerSaveCfg, + WDI_SetUapsdAcParamsCb wdiSetUapsdAcParamsCb, + void* pUserData +); + + +/** + @brief WDI_FatalEventLogsReq will be called when the upper + MAC wants to send the fatal event req. Upon the call of + this API the WLAN DAL will pack and send a HAL + Fatal event request message to the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiFatalEventLogsReqInfo: the Fatal event logs params + as specified by the Device Interface + + wdiFatalEventLogsRspCb: callback for passing back the + response of the fatal event operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ + +WDI_Status +WDI_FatalEventLogsReq +( + WDI_FatalEventLogsReqInfoType *pwdiFatalEventLogsReqInfo, + WDI_FatalEventLogsRspCb wdiFatalEventLogsRspCb, + void* pUserData +); + +/** + @brief WDI_GetFrameLogReq will be called when the upper + MAC wants to initialize frame logging. Upon the call of + this API the WLAN DAL will pack and send a HAL + Frame logging init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiGetFrameLogReqInfo: the Frame Logging params + as specified by the Device Interface + + wdiGetFrameLogReqCb: callback for passing back the + response of the frame logging init operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_GetFrameLogReq +( + WDI_GetFrameLogReqInfoType *pwdiGetFrameLogReqInfo, + WDI_GetFrameLogRspCb wdiGetFrameLogReqCb, + void* pUserData +); + +/** + @brief WDI_FWLoggingInitReq will be called when the upper + MAC wants to initialize frame logging. Upon the call of + this API the WLAN DAL will pack and send a HAL + Frame logging init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiFWLoggingInitReqParams: the Frame Logging params + as specified by the Device Interface + + wdiFWLoggingInitReqCb: callback for passing back the + response of the frame logging init operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_FWLoggingInitReq +( + WDI_FWLoggingInitReqInfoType *pwdiFWLoggingInitReqInfo, + WDI_FWLoggingInitRspCb wdiFWLoggingInitReqCb, + void* pUserData +); + +/** + @brief WDI_StartRssiMonitorReq will be called when the upper + MAC wants to initialize Rssi Monitor on a bssid. + Upon the call of this API the WLAN DAL will pack and + send a HAL Rssi Monitor init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiRssiMonitorInfo: the Rssi Monitor params + as specified by the Device Interface + + wdiRssiMonitorStartRspCb: callback for passing back the + response of the rssi monitor operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StartRssiMonitorReq +( + WDI_RssiMonitorReqInfoType *pwdiRssiMonitorInfo, + WDI_RssiMonitorStartRspCb wdiRssiMonitorStartRspCb, + void* pUserData +); + + +/** + @brief WDI_StopRssiMonitorReq will be called when the upper + MAC wants to stop Rssi Monitor on a bssid. + Upon the call of this API the WLAN DAL will pack and + send a HAL Rssi Monitor stop request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiRssiMonitorInfo: the Rssi Monitor params + as specified by the Device Interface + + wdiRssiMonitorStopRspCb: callback for passing back the + response of the rssi monitor operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StopRssiMonitorReq +( + WDI_RssiMonitorReqInfoType *pwdiRssiMonitorInfo, + WDI_RssiMonitorStopRspCb wdiRssiMonitorStopRspCb, + void* pUserData +); + +/** + @brief WDI_ConfigureRxpFilterReq will be called when the upper + MAC wants to set/reset the RXP filters for received pkts + (MC, BC etc.). Upon the call of this API the WLAN DAL will pack + and send a HAL configure RXP filter request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiConfigureRxpFilterReqParams: the RXP + filter as specified by the Device + Interface + + wdiConfigureRxpFilterCb: callback for passing back the + response of the configure RXP filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_ConfigureRxpFilterReq +( + WDI_ConfigureRxpFilterReqParamsType *pwdiConfigureRxpFilterReqParams, + WDI_ConfigureRxpFilterCb wdiConfigureRxpFilterCb, + void* pUserData +); + +/** + @brief WDI_SetBeaconFilterReq will be called when the upper MAC + wants to set the beacon filters while in power save. + Upon the call of this API the WLAN DAL will pack and + send a Beacon filter request message to the + lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiBeaconFilterReqParams: the beacon + filter as specified by the Device + Interface + + wdiBeaconFilterCb: callback for passing back the + response of the set beacon filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetBeaconFilterReq +( + WDI_BeaconFilterReqParamsType *pwdiBeaconFilterReqParams, + WDI_SetBeaconFilterCb wdiBeaconFilterCb, + void* pUserData +); + +/** + @brief WDI_RemBeaconFilterReq will be called when the upper MAC + wants to remove the beacon filter for perticular IE + while in power save. Upon the call of this API the WLAN + DAL will pack and send a remove Beacon filter request + message to the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiBeaconFilterReqParams: the beacon + filter as specified by the Device + Interface + + wdiBeaconFilterCb: callback for passing back the + response of the remove beacon filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_RemBeaconFilterReq +( + WDI_RemBeaconFilterReqParamsType *pwdiBeaconFilterReqParams, + WDI_RemBeaconFilterCb wdiBeaconFilterCb, + void* pUserData +); + +/** + @brief WDI_SetRSSIThresholdsReq will be called when the upper + MAC wants to set the RSSI thresholds related + configurations while in power save. Upon the call of + this API the WLAN DAL will pack and send a HAL Set RSSI + thresholds request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiUapsdInfo: the UAPSD parameters as specified by + the Device Interface + + wdiSetUapsdAcParamsCb: callback for passing back the + response of the set UAPSD params operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetRSSIThresholdsReq +( + WDI_SetRSSIThresholdsReqParamsType* pwdiRSSIThresholdsParams, + WDI_SetRSSIThresholdsCb wdiSetRSSIThresholdsCb, + void* pUserData +); + +/** + @brief WDI_HostOffloadReq will be called when the upper MAC + wants to set the filter to minimize unnecessary host + wakeup due to broadcast traffic while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL host offload request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiHostOffloadParams: the host offload as specified + by the Device Interface + + wdiHostOffloadCb: callback for passing back the response + of the host offload operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_HostOffloadReq +( + WDI_HostOffloadReqParamsType* pwdiHostOffloadParams, + WDI_HostOffloadCb wdiHostOffloadCb, + void* pUserData +); + +/** + @brief WDI_KeepAliveReq will be called when the upper MAC + wants to set the filter to send NULL or unsolicited ARP responses + and minimize unnecessary host wakeups due to while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL Keep Alive request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiKeepAliveParams: the Keep Alive as specified + by the Device Interface + + wdiKeepAliveCb: callback for passing back the response + of the Keep Alive operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_KeepAliveReq +( + WDI_KeepAliveReqParamsType* pwdiKeepAliveParams, + WDI_KeepAliveCb wdiKeepAliveCb, + void* pUserData +); + +/** + @brief WDI_WowlAddBcPtrnReq will be called when the upper MAC + wants to set the Wowl Bcast ptrn to minimize unnecessary + host wakeup due to broadcast traffic while in power + save. Upon the call of this API the WLAN DAL will pack + and send a HAL Wowl Bcast ptrn request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiWowlAddBcPtrnParams: the Wowl bcast ptrn as + specified by the Device Interface + + wdiWowlAddBcPtrnCb: callback for passing back the + response of the add Wowl bcast ptrn operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlAddBcPtrnReq +( + WDI_WowlAddBcPtrnReqParamsType* pwdiWowlAddBcPtrnParams, + WDI_WowlAddBcPtrnCb wdiWowlAddBcPtrnCb, + void* pUserData +); + +/** + @brief WDI_WowlDelBcPtrnReq will be called when the upper MAC + wants to clear the Wowl Bcast ptrn. Upon the call of + this API the WLAN DAL will pack and send a HAL delete + Wowl Bcast ptrn request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_WowlAddBcPtrnReq must have been called. + + @param pwdiWowlDelBcPtrnParams: the Wowl bcast ptrn as + specified by the Device Interface + + wdiWowlDelBcPtrnCb: callback for passing back the + response of the del Wowl bcast ptrn operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_WowlAddBcPtrnReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlDelBcPtrnReq +( + WDI_WowlDelBcPtrnReqParamsType* pwdiWowlDelBcPtrnParams, + WDI_WowlDelBcPtrnCb wdiWowlDelBcPtrnCb, + void* pUserData +); + +/** + @brief WDI_WowlEnterReq will be called when the upper MAC + wants to enter the Wowl state to minimize unnecessary + host wakeup while in power save. Upon the call of this + API the WLAN DAL will pack and send a HAL Wowl enter + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiWowlEnterReqParams: the Wowl enter info as + specified by the Device Interface + + wdiWowlEnterReqCb: callback for passing back the + response of the enter Wowl operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlEnterReq +( + WDI_WowlEnterReqParamsType* pwdiWowlEnterParams, + WDI_WowlEnterReqCb wdiWowlEnterCb, + void* pUserData +); + +/** + @brief WDI_WowlExitReq will be called when the upper MAC + wants to exit the Wowl state. Upon the call of this API + the WLAN DAL will pack and send a HAL Wowl exit request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_WowlEnterReq must have been called. + + @param pwdiWowlExitReqParams: the Wowl exit info as + specified by the Device Interface + + wdiWowlExitReqCb: callback for passing back the response + of the exit Wowl operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_WowlEnterReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlExitReq +( + WDI_WowlExitReqParamsType* pwdiWowlExitParams, + WDI_WowlExitReqCb wdiWowlExitCb, + void* pUserData +); + +/** + @brief WDI_ConfigureAppsCpuWakeupStateReq will be called when + the upper MAC wants to dynamically adjusts the listen + interval based on the WLAN/MSM activity. Upon the call + of this API the WLAN DAL will pack and send a HAL + configure Apps Cpu Wakeup State request message to the + lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiConfigureAppsCpuWakeupStateReqParams: the + Apps Cpu Wakeup State as specified by the + Device Interface + + wdiConfigureAppsCpuWakeupStateCb: callback for passing + back the response of the configure Apps Cpu Wakeup State + operation received from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_ConfigureAppsCpuWakeupStateReq +( + WDI_ConfigureAppsCpuWakeupStateReqParamsType *pwdiConfigureAppsCpuWakeupStateReqParams, + WDI_ConfigureAppsCpuWakeupStateCb wdiConfigureAppsCpuWakeupStateCb, + void* pUserData +); +/** + @brief WDI_FlushAcReq will be called when the upper MAC wants + to to perform a flush operation on a given AC. Upon the + call of this API the WLAN DAL will pack and send a HAL + Flush AC request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiFlushAcReqParams: the Flush AC parameters as + specified by the Device Interface + + wdiFlushAcRspCb: callback for passing back the response + of the Flush AC operation received from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_FlushAcReq +( + WDI_FlushAcReqParamsType* pwdiFlushAcReqParams, + WDI_FlushAcRspCb wdiFlushAcRspCb, + void* pUserData +); + +/** + @brief WDI_BtAmpEventReq will be called when the upper MAC + wants to notify the lower mac on a BT AMP event. This is + to inform BTC-SLM that some BT AMP event occurred. Upon + the call of this API the WLAN DAL will pack and send a + HAL BT AMP event request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiBtAmpEventReqParams: the BT AMP event parameters as + specified by the Device Interface + + wdiBtAmpEventRspCb: callback for passing back the + response of the BT AMP event operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_BtAmpEventReq +( + WDI_BtAmpEventParamsType* pwdiBtAmpEventReqParams, + WDI_BtAmpEventRspCb wdiBtAmpEventRspCb, + void* pUserData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief WDI_Start oem data Req will be called when the upper MAC + wants to notify the lower mac on a oem data Req event.Upon + the call of this API the WLAN DAL will pack and send a + HAL OEM Data Req event request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pWdiOemDataReqParams: the oem data req parameters as + specified by the Device Interface + + wdiStartOemDataRspCb: callback for passing back the + response of the Oem Data Req received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StartOemDataReq +( + WDI_oemDataReqParamsType* pWdiOemDataReqParams, + WDI_oemDataRspCb wdiOemDataRspCb, + void* pUserData +); +#endif + +/*======================================================================== + + CONTROL APIs + +==========================================================================*/ +/** + @brief WDI_SwitchChReq will be called when the upper MAC wants + the WLAN HW to change the current channel of operation. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiSwitchChReqParams: the switch ch parameters as + specified by the Device Interface + + wdiSwitchChRspCb: callback for passing back the response + of the switch ch operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SwitchChReq +( + WDI_SwitchChReqParamsType* pwdiSwitchChReqParams, + WDI_SwitchChRspCb wdiSwitchChRspCb, + void* pUserData +); + +/** + @brief WDI_SwitchChReq_V1 is similar to WDI_SwitchChReq except + it also send type source for the channel change. + WDI_Start must have been called. + + @param wdiSwitchChReqParams: the switch ch parameters as + specified by the Device Interface + + wdiSwitchChRspCb: callback for passing back the response + of the switch ch operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ + +WDI_Status +WDI_SwitchChReq_V1 +( + WDI_SwitchChReqParamsType_V1* pwdiSwitchChReqParams, + WDI_SwitchChRspCb_V1 wdiSwitchChRspCb, + void* pUserData +); + +/** + @brief WDI_UpdateChannelReq will be called when the upper MAC + wants to update the channel list on change in country code. + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_UpdateChannelReq must have been called. + + @param wdiUpdateChannelReqParams: the updated channel parameters + as specified by the Device Interface + + wdiUpdateChannelRspCb: callback for passing back the + response of the update channel operation received from + the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_UpdateChannelReq +( + WDI_UpdateChReqParamsType *pwdiUpdateChannelReqParams, + WDI_UpdateChannelRspCb wdiUpdateChannelRspCb, + void* pUserData +); + +/** + @brief WDI_ConfigSTAReq will be called when the upper MAC + wishes to add or update a STA in HW. Upon the call of + this API the WLAN DAL will pack and send a HAL Start + message request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiConfigSTAReqParams: the config STA parameters as + specified by the Device Interface + + wdiConfigSTARspCb: callback for passing back the + response of the config STA operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_ConfigSTAReq +( + WDI_ConfigSTAReqParamsType* pwdiConfigSTAReqParams, + WDI_ConfigSTARspCb wdiConfigSTARspCb, + void* pUserData +); + +/** + @brief WDI_SetLinkStateReq will be called when the upper MAC + wants to change the state of an ongoing link. Upon the + call of this API the WLAN DAL will pack and send a HAL + Start message request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiSetLinkStateReqParams: the set link state parameters + as specified by the Device Interface + + wdiSetLinkStateRspCb: callback for passing back the + response of the set link state operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinStartReq + @return Result of the function call +*/ +WDI_Status +WDI_SetLinkStateReq +( + WDI_SetLinkReqParamsType* pwdiSetLinkStateReqParams, + WDI_SetLinkStateRspCb wdiSetLinkStateRspCb, + void* pUserData +); + + +/** + @brief WDI_GetStatsReq will be called when the upper MAC wants + to get statistics (MIB counters) from the device. Upon + the call of this API the WLAN DAL will pack and send a + HAL Start request message to the lower RIVA sub-system + if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiGetStatsReqParams: the stats parameters to get as + specified by the Device Interface + + wdiGetStatsRspCb: callback for passing back the response + of the get stats operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_GetStatsReq +( + WDI_GetStatsReqParamsType* pwdiGetStatsReqParams, + WDI_GetStatsRspCb wdiGetStatsRspCb, + void* pUserData +); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief WDI_GetRoamRssiReq will be called when the upper MAC wants + to get roam rssi from the device. Upon + the call of this API the WLAN DAL will pack and send a + HAL Start request message to the lower RIVA sub-system + if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiGetRoamRssiReqParams: the stats parameters to get as + specified by the Device Interface + + wdiGetRoamRssispCb: callback for passing back the response + of the get stats operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_GetRoamRssiReq +( + WDI_GetRoamRssiReqParamsType* pwdiGetRoamRssiReqParams, + WDI_GetRoamRssiRspCb wdiGetRoamRssiRspCb, + void* pUserData +); +#endif + +/** + @brief WDI_UpdateCfgReq will be called when the upper MAC when + it wishes to change the configuration of the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Update CFG request message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiUpdateCfgReqParams: the update cfg parameters as + specified by the Device Interface + + wdiUpdateCfgsRspCb: callback for passing back the + response of the update cfg operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_UpdateCfgReq +( + WDI_UpdateCfgReqParamsType* pwdiUpdateCfgReqParams, + WDI_UpdateCfgRspCb wdiUpdateCfgsRspCb, + void* pUserData +); + +/** + @brief WDI_NvDownloadReq will be called by the UMAC to dowload the NV blob + to the NV memory. + + @param wdiNvDownloadReqParams: the NV Download parameters as specified by + the Device Interface + + wdiNvDownloadRspCb: callback for passing back the response of + the NV Download operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_NvDownloadReq +( + WDI_NvDownloadReqParamsType* pwdiNvDownloadReqParams, + WDI_NvDownloadRspCb wdiNvDownloadRspCb, + void* pUserData +); +/** + @brief WDI_AddBAReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddBAReq +( + WDI_AddBAReqParamsType* pwdiAddBAReqParams, + WDI_AddBARspCb wdiAddBARspCb, + void* pUserData +); + +/** + @brief WDI_TriggerBAReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + baReqParamUserDataSize: user data size of wdiAddBAReqParams + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_TriggerBAReq +( + WDI_TriggerBAReqParamsType* pwdiTriggerBAReqParams, + wpt_uint8 baReqParamUserDataSize, + WDI_TriggerBARspCb wdiTriggerBARspCb, + void* pUserData +); + + +/** + @brief WDI_IsHwFrameTxTranslationCapable checks to see if HW + frame xtl is enabled for a particular STA. + + WDI_PostAssocReq must have been called. + + @param uSTAIdx: STA index + + @see WDI_PostAssocReq + @return Result of the function call +*/ +wpt_boolean WDI_IsHwFrameTxTranslationCapable +( + wpt_uint8 uSTAIdx +); + + +/** + @brief WDI_IsSelfSTA - check if staid is self sta index + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + + @return Result of the function call +*/ + +wpt_boolean +WDI_IsSelfSTA +( + void* pWDICtx, + wpt_uint8 ucSTAIdx +); + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief WDI_AggrAddTSReq will be called when the upper MAC to inform + the device of a successful add TSpec negotiation for 11r. HW + needs to receive the TSpec Info from the UMAC in order + to configure properly the QoS data traffic. Upon the + call of this API the WLAN DAL will pack and send a HAL + Aggregated Add TS request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAggrAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAggrAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AggrAddTSReq +( + WDI_AggrAddTSReqParamsType* pwdiAddTsReqParams, + WDI_AggrAddTsRspCb wdiAggrAddTsRspCb, + void* pUserData +); +#endif /* WLAN_FEATURE_VOWIFI_11R */ +/** + @brief WDI_STATableInit - Initializes the STA tables. + Allocates the necesary memory. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ + +WDI_Status WDI_StubRunTest +( + wpt_uint8 ucTestNo +); + +/** + @brief WDI_FTMCommandReq - + Route FTMRequest Command to HAL + + @param ftmCommandReq: FTM request command body + @param ftmCommandRspCb: Response CB + @param pUserData: User data will be included with CB + + @return Result of the function call +*/ +WDI_Status WDI_FTMCommandReq +( + WDI_FTMCommandReqType *ftmCommandReq, + WDI_FTMCommandRspCb ftmCommandRspCb, + void *pUserData +); + +/** + @brief WDI_HostResumeReq will be called + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiResumeReqParams: as specified by + the Device Interface + + wdiResumeReqRspCb: callback for passing back the response of + the Resume Req received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_HostResumeReq +( + WDI_ResumeParamsType* pwdiResumeReqParams, + WDI_HostResumeEventRspCb wdiResumeReqRspCb, + void* pUserData +); + +/** + @brief WDI_GetAvailableResCount - Function to get the available resource + for data and managemnt frames. + + @param pContext: pointer to the WDI context + @param wdiResPool: type of resource pool requesting + @see + @return Result of the function call +*/ + +wpt_uint32 WDI_GetAvailableResCount +( + void *pContext, + WDI_ResPoolType wdiResPool +); + +/** + @brief WDI_SetAddSTASelfReq will be called when the + UMAC wanted to add self STA while opening any new session + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiAddSTASelfParams: the add self sta parameters as + specified by the Device Interface + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_AddSTASelfReq +( + WDI_AddSTASelfReqParamsType* pwdiAddSTASelfReqParams, + WDI_AddSTASelfParamsRspCb wdiAddSTASelfReqParamsRspCb, + void* pUserData +); + + +/** + @brief WDI_DelSTASelfReq will be called . + + @param WDI_DelSTASelfReqParamsType + + WDI_DelSTASelfRspCb: callback for passing back the + response of the del sta self operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelSTASelfReq +( + WDI_DelSTASelfReqParamsType* pwdiDelStaSelfParams, + WDI_DelSTASelfRspCb wdiDelStaSelfRspCb, + void* pUserData +); + +/** + @brief WDI_HostSuspendInd + + Suspend Indication from the upper layer will be sent + down to HAL + + @param WDI_SuspendParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_HostSuspendInd +( + WDI_SuspendParamsType* pwdiSuspendIndParams +); + +/** + @brief WDI_TrafficStatsInd + + Traffic Stats from the upper layer will be sent + down to HAL + + @param WDI_TrafficStatsIndType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_TrafficStatsInd +( + WDI_TrafficStatsIndType *pWdiTrafficStatsIndParams +); + +#ifdef WLAN_FEATURE_11W +/** + @brief WDI_ExcludeUnencryptedInd + Register with HAL to receive/drop unencrypted frames + + @param WDI_ExcludeUnencryptIndType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_ExcludeUnencryptedInd +( + WDI_ExcludeUnencryptIndType *pWdiExcUnencParams +); +#endif + +/** + @brief WDI_AddPeriodicTxPtrnInd + + @param WDI_AddPeriodicTxPtrnParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_AddPeriodicTxPtrnInd +( + WDI_AddPeriodicTxPtrnParamsType *addPeriodicTxPtrnParams +); + +/** + @brief WDI_DelPeriodicTxPtrnInd + + @param WDI_DelPeriodicTxPtrnParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_DelPeriodicTxPtrnInd +( + WDI_DelPeriodicTxPtrnParamsType *delPeriodicTxPtrnParams +); + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + @brief WDI_SetPreferredNetworkList + + @param pwdiPNOScanReqParams: the Set PNO as specified + by the Device Interface + + wdiPNOScanCb: callback for passing back the response + of the Set PNO operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetPreferredNetworkReq +( + WDI_PNOScanReqParamsType* pwdiPNOScanReqParams, + WDI_PNOScanCb wdiPNOScanCb, + void* pUserData +); + +/** + @brief WDI_SetRssiFilterReq + + @param pwdiRssiFilterReqParams: the Set RSSI Filter as + specified by the Device Interface + + wdiRssiFilterCb: callback for passing back the response + of the Set RSSI Filter operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetRssiFilterReq +( + WDI_SetRssiFilterReqParamsType* pwdiRssiFilterReqParams, + WDI_RssiFilterCb wdiRssiFilterCb, + void* pUserData +); + +/** + @brief WDI_UpdateScanParams + + @param pwdiUpdateScanParamsInfoType: the Update Scan Params as specified + by the Device Interface + + wdiUpdateScanParamsCb: callback for passing back the response + of the Set PNO operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateScanParamsReq +( + WDI_UpdateScanParamsInfoType* pwdiUpdateScanParamsInfoType, + WDI_UpdateScanParamsCb wdiUpdateScanParamsCb, + void* pUserData +); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + @brief WDI_RoamScanOffloadReq + + @param pwdiRoamScanOffloadReqParams: Start Roam Candidate Lookup Req as specified + by the Device Interface + + wdiRoamOffloadScanCb: callback for passing back the response + of the Start Roam Candidate Lookup operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_RoamScanOffloadReq +( + WDI_RoamScanOffloadReqParamsType *pwdiRoamScanOffloadReqParams, + WDI_RoamOffloadScanCb wdiRoamOffloadScancb, + void* pUserData +); + +WDI_Status +WDI_PERRoamScanOffloadReq +( + WDI_PERRoamOffloadScanInfo *pwdiRoamScanOffloadReqParams, + WDI_PERRoamOffloadScanCb wdiRoamOffloadScancb, + void* pUserData +); + +WDI_Status +WDI_PERRoamScanTriggerReq +( + WDI_PERRoamTriggerScanInfo *pwdiRoamScanTriggerReqParams, + WDI_PERRoamTriggerScanCb wdiRoamTriggerScancb, + void* pUserData +); +#endif + +/** + @brief WDI_SetTxPerTrackingReq will be called when the upper MAC + wants to set the Tx Per Tracking configurations. + Upon the call of this API the WLAN DAL will pack + and send a HAL Set Tx Per Tracking request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + @param wdiSetTxPerTrackingConf: the Set Tx PER Tracking configurations as + specified by the Device Interface + + wdiSetTxPerTrackingCb: callback for passing back the + response of the set Tx PER Tracking configurations operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTxPerTrackingReq +( + WDI_SetTxPerTrackingReqParamsType* pwdiSetTxPerTrackingReqParams, + WDI_SetTxPerTrackingRspCb pwdiSetTxPerTrackingRspCb, + void* pUserData +); + +/** + @brief WDI_SetTmLevelReq + If HW Thermal condition changed, driver should react based on new + HW thermal condition. + + @param pwdiSetTmLevelReq: New thermal condition information + + pwdiSetTmLevelRspCb: callback + + usrData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTmLevelReq +( + WDI_SetTmLevelReqType *pwdiSetTmLevelReq, + WDI_SetTmLevelCb pwdiSetTmLevelRspCb, + void *usrData +); + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/** + @brief WDI_8023MulticastListReq + + @param pwdiRcvFltPktSetMcListReqInfo: the Set 8023 Multicast + List as specified by the Device Interface + + wdi8023MulticastListCallback: callback for passing back + the response of the Set 8023 Multicast List operation + received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_8023MulticastListReq +( + WDI_RcvFltPktSetMcListReqParamsType* pwdiRcvFltPktSetMcListReqInfo, + WDI_8023MulticastListCb wdi8023MulticastListCallback, + void* pUserData +); + +/** + @brief WDI_ReceiveFilterSetFilterReq + + @param pwdiSetRcvPktFilterReqInfo: the Set Receive Filter as + specified by the Device Interface + + wdiReceiveFilterSetFilterReqCallback: callback for + passing back the response of the Set Receive Filter + operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ReceiveFilterSetFilterReq +( + WDI_SetRcvPktFilterReqParamsType* pwdiSetRcvPktFilterReqInfo, + WDI_ReceiveFilterSetFilterCb wdiReceiveFilterSetFilterReqCallback, + void* pUserData +); + +/** + @brief WDI_PCFilterMatchCountReq + + @param pwdiRcvFltPktMatchCntReqInfo: get D0 PC Filter Match + Count + + wdiPCFilterMatchCountCallback: callback for passing back + the response of the D0 PC Filter Match Count operation + received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_FilterMatchCountReq +( + WDI_RcvFltPktMatchCntReqParamsType* pwdiRcvFltPktMatchCntReqInfo, + WDI_FilterMatchCountCb wdiFilterMatchCountCallback, + void* pUserData +); + +/** + @brief WDI_ReceiveFilterClearFilterReq + + @param pwdiRcvFltPktClearReqInfo: the Clear Filter as + specified by the Device Interface + + wdiReceiveFilterClearFilterCallback: callback for + passing back the response of the Clear Filter + operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ReceiveFilterClearFilterReq +( + WDI_RcvFltPktClearReqParamsType* pwdiRcvFltPktClearReqInfo, + WDI_ReceiveFilterClearFilterCb wdiReceiveFilterClearFilterCallback, + void* pUserData +); +#endif // WLAN_FEATURE_PACKET_FILTERING + +/** + @brief WDI_HALDumpCmdReq + Post HAL DUMP Command Event + + @param halDumpCmdReqParams: Hal Dump Command Body + @param halDumpCmdRspCb: callback for passing back the + response + @param pUserData: Client Data + + @see + @return Result of the function call +*/ +WDI_Status WDI_HALDumpCmdReq( + WDI_HALDumpCmdReqParamsType *halDumpCmdReqParams, + WDI_HALDumpCmdRspCb halDumpCmdRspCb, + void *pUserData +); + + +/** + @brief WDI_SetPowerParamsReq + + @param pwdiPowerParamsReqParams: the Set Power Params as + specified by the Device Interface + + wdiPowerParamsCb: callback for passing back the response + of the Set Power Params operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetPowerParamsReq +( + WDI_SetPowerParamsReqParamsType* pwdiPowerParamsReqParams, + WDI_SetPowerParamsCb wdiPowerParamsCb, + void* pUserData +); +/** + @brief WDI_dhcpStartInd + Forward the DHCP Start event + + @param + + wdiDHCPInd: device mode and MAC address is passed + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_dhcpStartInd +( + WDI_DHCPInd *wdiDHCPInd +); +/** + @brief WDI_dhcpStopReq + Forward the DHCP Stop event + + @param + + wdiDHCPInd: device mode and MAC address is passed + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_dhcpStopInd +( + WDI_DHCPInd *wdiDHCPInd +); + +#ifdef WLAN_FEATURE_RMC +WDI_Status +WDI_RmcRulerReq +( + WDI_RmcRulerReqParams *wdiRmcRulerReqParams, + WDI_RmcRulerRspCb rmcRulerRspCb, + void *usrData +); + +WDI_Status +WDI_RmcUpdateInd +( + WDI_RmcUpdateIndParams *wdiRmcUpdateIndParams +); +#endif /* WLAN_FEATURE_RMC */ + +/** + @brief WDI_RateUpdateInd will be called when the upper MAC + requests the device to update rates. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiRateUpdateIndParams + + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_RateUpdateInd +( + WDI_RateUpdateIndParams *wdiRateUpdateIndParams +); + +#ifdef WLAN_FEATURE_RMC +/** + @brief WDI_TXFailMonitorStartStopInd + Forward TX monitor start/stop event + + @param + + WDI_TXFailMonitorInd + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_TXFailMonitorStartStopInd +( + WDI_TXFailMonitorInd *wdiTXFailMonitorInd +); +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/** + @brief WDI_GTKOffloadReq will be called when the upper MAC + wants to set GTK Rekey Counter while in power save. Upon + the call of this API the WLAN DAL will pack and send a + HAL GTK offload request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiGtkOffloadParams: the GTK offload as specified + by the Device Interface + + wdiGtkOffloadCb: callback for passing back the response + of the GTK offload operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_GTKOffloadReq +( + WDI_GtkOffloadReqMsg* pwdiGtkOffloadReqMsg, + WDI_GtkOffloadCb wdiGtkOffloadCb, + void* pUserData +); + +/** + @brief WDI_GTKOffloadGetInfoReq will be called when the upper + MAC wants to get GTK Rekey Counter while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL GTK offload request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiGtkOffloadGetInfoReqMsg: the GTK Offload + Information Message as specified by the + Device Interface + + wdiGtkOffloadGetInfoCb: callback for passing back the + response of the GTK offload operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_GTKOffloadGetInfoReq +( + WDI_GtkOffloadGetInfoReqMsg* pwdiGtkOffloadGetInfoReqMsg, + WDI_GtkOffloadGetInfoCb wdiGtkOffloadGetInfoCb, + void* pUserData +); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +/** + @brief WDI_featureCapsExchangeReq + Post feature capability bitmap exchange event. + Host will send its own capability to FW in this req and + expect FW to send its capability back as a bitmap in Response + + @param + + wdiFeatCapsExcRspCb: callback called on getting the response. + It is kept to mantain similarity between WDI reqs and if needed, can + be used in future. Currently, It is set to NULL + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_featureCapsExchangeReq +( + WDI_featureCapsExchangeCb wdiFeatureCapsExchangeCb, + void* pUserData +); + +/** + @brief Disable Active mode offload in Host + + @param void + @see + @return void +*/ +void +WDI_disableCapablityFeature(wpt_uint8 feature_index); + + +/** + @brief WDI_getHostWlanFeatCaps + WDI API that returns whether the feature passed to it as enum value in + "placeHolderInCapBitmap" is supported by Host or not. It uses WDI global + variable storing host capability bitmap to find this. This can be used by + other moduels to decide certain things like call different APIs based on + whether a particular feature is supported. + + @param + + feat_enum_value: enum value for the feature as in placeHolderInCapBitmap in wlan_hal_msg.h. + + @see + @return + 0 - if the feature is NOT supported in host + any non-zero value - if the feature is SUPPORTED in host. +*/ +wpt_uint8 WDI_getHostWlanFeatCaps(wpt_uint8 feat_enum_value); + +/** + @brief WDI_getFwWlanFeatCaps + WDI API that returns whether the feature passed to it as enum value in + "placeHolderInCapBitmap" is supported by FW or not. It uses WDI global + variable storing host capability bitmap to find this. This can be used by + other moduels to decide certain things like call different APIs based on + whether a particular feature is supported. + + @param + + feat_enum_value: enum value for the feature as in placeHolderInCapBitmap + in wlan_hal_msg.h. + + @see + @return + 0 - if the feature is NOT supported in FW + any non-zero value - if the feature is SUPPORTED in FW. +*/ +wpt_uint8 WDI_getFwWlanFeatCaps(wpt_uint8 feat_enum_value); + +/** + @brief WDI_GetWcnssCompiledApiVersion - Function to get wcnss compiled + api version + + @param WDI_WlanVersionType: Wlan version structure + @see + @return none +*/ + +void WDI_GetWcnssCompiledApiVersion +( + WDI_WlanVersionType *pWcnssApiVersion +); + +#ifdef WLAN_FEATURE_11AC +WDI_Status +WDI_UpdateVHTOpModeReq +( + WDI_UpdateVHTOpMode *pData, + WDI_UpdateVHTOpModeCb wdiUpdateVHTOpModeCb, + void* pUserData +); + +#endif + +/** + @brief WDI_TransportChannelDebug - + Display DXE Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + @param displaySnapshot : Display DXE snapshot option + @param debugFlags : Enable stall detect features + defined by WPAL_DeviceDebugFlags + These features may effect + data performance. + @see + @return none +*/ +void WDI_TransportChannelDebug +( + wpt_boolean displaySnapshot, + wpt_uint8 debugFlags +); + +/** + @brief WDI_TransportKickDxe - + Request Kick DXE when first HDD TX time out + happens + @param none + @see + @return none +*/ +void WDI_TransportKickDxe(void); + +/** + @brief WDI_SsrTimerCB + Callback function for SSR timer, if this is called then the graceful + shutdown for Riva did not happen. + + @param pUserData : user data to timer + + @see + @return none +*/ +void +WDI_SsrTimerCB +( + void *pUserData +); + +/** + @brief WDI_SetEnableSSR - + This API is called to enable/disable SSR on WDI timeout. + + @param enableSSR : enable/disable SSR + + @see + @return none +*/ +void WDI_SetEnableSSR(wpt_boolean enableSSR); + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_LPHBConfReq + This API is called to config FW LPHB rule + + @param lphbconfParam : LPHB rule should config to FW + usrData : Client context + lphbCfgCb : Configuration status callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_LPHBConfReq +( + void *lphbconfParam, + void *usrData, + WDI_LphbCfgCb lphbCfgCb +); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef WLAN_FEATURE_EXTSCAN +/** + @brief WDI_EXTScanStartReq + This API is called to send EXTScan start request to FW + + @param pwdiEXTScanStartReqParams : pointer to the request params. + wdiEXTScanStartRspCb : callback on getting the response. + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_EXTScanStartReq +( + WDI_EXTScanStartReqParams* pwdiEXTScanStartReqParams, + WDI_EXTScanStartRspCb wdiEXTScanStartRspCb, + void* pUserData +); + +/** + @brief WDI_EXTScanStopReq + This API is called to stop the EXTScan operations in the FW + + @param pwdiEXTScanStopReqParams : pointer to the request params. + wdiEXTScanStopRspCb : callback on getting the response. + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_EXTScanStopReq +( + WDI_EXTScanStopReqParams* pwdiEXTScanStopReqParams, + WDI_EXTScanStopRspCb wdiEXTScanStopRspCb, + void* pUserData +); + +/** + @brief WDI_EXTScanGetCachedResultsReq + This API is called to send get link layer stats request in FW + + @param pwdiEXTScanGetCachedResultsReqParams : pointer to the request params. + wdiEXTScanGetCachedResultsRspCb : callback on getting the response. + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_EXTScanGetCachedResultsReq +( + WDI_EXTScanGetCachedResultsReqParams* pwdiEXTScanGetCachedResultsReqParams, + WDI_EXTScanGetCachedResultsRspCb wdiEXTScanGetCachedResultsRspCb, + void* pUserData +); + +/** + @brief WDI_EXTScanGetCapabilitiesReq + This API is called to send get EXTScan capabilities from FW + + @param pwdiEXTScanGetCachedResultsReqParams : pointer to the request params. + wdiEXTScanGetCachedResultsRspCb : callback on getting the response. + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_EXTScanGetCapabilitiesReq +( + WDI_EXTScanGetCapabilitiesReqParams* pwdiEXTScanGetCapabilitiesReqParams, + WDI_EXTScanGetCapabilitiesRspCb wdiEXTScanGetCapabilitiesRspCb, + void* pUserData +); + +/** + @brief WDI_EXTScanSetBSSIDHotlistReq + This API is called to send Set BSSID Hotlist Request FW + + @param pwdiEXTScanSetBssidHotlistReqParams : pointer to the request params. + wdiEXTScanSetBSSIDHotlistRspCb : callback on getting the response. + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_EXTScanSetBSSIDHotlistReq +( + WDI_EXTScanSetBSSIDHotlistReqParams* pwdiEXTScanSetBSSIDHotlistReqParams, + WDI_EXTScanSetBSSIDHotlistRspCb wdiEXTScanSetBSSIDHotlistRspCb, + void* pUserData +); + +/** + @brief WDI_EXTScanResetBSSIDHotlistReq + This API is called to send Reset BSSID Hotlist Request FW + + @param pwdiEXTScanResetBssidHotlistReqParams : pointer to the request params. + wdiEXTScanGetCachedResultsRspCb : callback on getting the response. + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_EXTScanResetBSSIDHotlistReq +( + WDI_EXTScanResetBSSIDHotlistReqParams* pwdiEXTScanResetBSSIDHotlistReqParams, + WDI_EXTScanResetBSSIDHotlistRspCb wdiEXTScanResetBSSIDHotlistRspCb, + void* pUserData +); + +/** + @brief WDI_HighPriorityDataInfoInd + + @param pHighPriorityDataInfoIndParams: Req parameter for the FW + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_HighPriorityDataInfoInd +( + WDI_HighPriorityDataInfoIndParams* pHighPriorityDataInfoIndParams +); + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/** + @brief WDI_LLStatsSetReq + This API is called to send set link layer stats request to FW + + @param pwdiLLStatsSetReqParams : pointer to set link layer stats params + wdiLLStatsSetRspCb : set link layer stats response callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_LLStatsSetReq +( + WDI_LLStatsSetReqType* pwdiLLStatsSetReqParams, + WDI_LLStatsSetRspCb wdiLLStatsSetRspCb, + void* pUserData +); + +/** + @brief WDI_LLStatsGetReq + This API is called to send get link layer stats request in FW + + @param pwdiLLStatsGetParams : pointer to get link layer stats params + wdiLLStatsGetRspCb : get link layer stats response callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_LLStatsGetReq +( + WDI_LLStatsGetReqType* pwdiLLStatsGetReqParams, + WDI_LLStatsGetRspCb wdiLLStatsGetRspCb, + void* pUserData +); + +/** + @brief WDI_LLStatsClearReq + This API is called to set clear link layer stats request in FW + + @param pwdiLLStatsClearReqParams : pointer to clear link layer stats params + iwdiLLStatsClearRspCb : clear link layer stats response callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_LLStatsClearReq +( + WDI_LLStatsClearReqType* pwdiLLStatsClearReqParams, + WDI_LLStatsClearRspCb wdiLLStatsClearRspCb, + void* pUserData +); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +WDI_Status WDI_FWStatsGetReq +( + void* pwdiFWStatsGetReqParams, + WDI_FWStatsGetRspCb wdiFWStatsGetRspCb, + wpt_uint32 pUserData +); + +WDI_Status WDI_MonStartReq +( + WDI_MonStartReqType* pwdiMonStartReqParams, + WDI_MonModeRspCb wdiMonModeRspCb, + void* pUserData +); + +WDI_Status WDI_MonStopReq +( + WDI_MonModeRspCb wdiMonModeRspCb, + void* pUserData +); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief WDI_SetBatchScanReq + This API is called to set batch scan request in FW + + @param pBatchScanReqParam : pointer to set batch scan re param + usrData : Client context + setBatchScanRspCb : set batch scan resp callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_SetBatchScanReq +( + void *pBatchScanReqParam, + void *usrData, + WDI_SetBatchScanCb setBatchScanRspCb +); + +/** + @brief WDI_StopBatchScanInd + + @param none + + @see + + @return Status of the request +*/ +WDI_Status +WDI_StopBatchScanInd(WDI_StopBatchScanIndType *pWdiReq); + +/** + @brief WDI_TriggerBatchScanResultInd + This API is called to pull batch scan result from FW + + @param pBatchScanReqParam : pointer to trigger batch scan ind param + usrData : Client context + setBatchScanRspCb : get batch scan resp callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_TriggerBatchScanResultInd(WDI_TriggerBatchScanResultIndType *pWdiReq); + + +#endif /*FEATURE_WLAN_BATCH_SCAN*/ + +#ifdef WLAN_FEATURE_RMC +/** + @brief Process peer info req + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_IbssPeerInfoReq +( + WDI_IbssPeerInfoReqType* wdiPeerInfoReqParams, + WDI_IbssPeerInfoReqCb wdiIbssPeerInfoReqCb, + void* pUserData +); +#endif /* WLAN_FEATURE_RMC */ + +/** + @brief wdi_HT40OBSSScanInd + This API is called to start OBSS scan + + @param pWdiReq : pointer to get ind param + @see + @return SUCCESS or FAIL +*/ + +WDI_Status WDI_HT40OBSSScanInd(WDI_HT40ObssScanParamsType *pWdiReq); + +/** + @brief wdi_HT40OBSSStopScanInd + This API is called to stop OBSS scan + + @param bssIdx : bssIdx to stop + @see + @return SUCCESS or FAIL +*/ + +WDI_Status WDI_HT40OBSSStopScanInd(wpt_uint8 bssIdx); + + +WDI_Status WDI_GetBcnMissRate( void *pUserData, + WDI_GetBcnMissRateCb wdiGetBcnMissRateCb, + wpt_uint8 *bssid + ); +WDI_Status +WDI_SetSpoofMacAddrReq +( +WDI_SpoofMacAddrInfoType *pWdiReq, + WDI_SetSpoofMacAddrRspCb setSpoofMacAddrRspCb, + void* pUserData +); + +WDI_Status +WDI_EncryptMsgReq(void* pwdiEncryptMsgParams, + WDI_EncryptMsgRspCb wdiEncryptMsgCbRsp, + void* pUserData + ); + +WDI_Status +WDI_FwrMemDumpReq + +( + WDI_FwrMemDumpReqType *pwdiFwrMemDumpReqInfo, + WDI_FwrMemDumpCb wdiFwrMemDumpRspCb, + void* pUserData +); + + +/** + @brief WDI_NanRequest + NAN request + + @param pwdiNanRequest: data + + pwdiNanCb: callback + + usrData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_NanRequest +( + WDI_NanRequestType *pwdiNanRequest, + void *usrData +); + +/** + @brief WDI_SetRtsCtsHTVhtInd + Set RTS/CTS indication for diff modes. + + @param rtsCtsVal: Bit mask value to enable RTS/CTS for different modes + + @return Result of the function call +*/ + +WDI_Status +WDI_SetRtsCtsHTVhtInd +( + wpt_uint32 rtsCtsVal +); + +WDI_Status +WDI_FWLoggingDXEdoneInd +( + wpt_uint32 logType +); + +/** + @brief WDI_EnableDisableCAEventInd + Enable/Disable Chan Avoidance indication + + @param val: Enable/Disable Chan Avoidance indication + + @return Result of the function call +*/ + +WDI_Status +WDI_EnableDisableCAEventInd +( +wpt_uint32 val +); + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** + @brief WDI_HighPriorityDataInfoInd + + @param pHighPriorityDataInfoIndParams: Req parameter for the FW + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_StartOemDataReqIndNew +( + WDI_OemDataReqNewConfig *pOemDataReqNewConfig +); +#endif + +#ifdef __cplusplus + } +#endif + +/** + @brief WDI_WifiConfigSetReq + This API is called to send WifiConfig request to FW + + @param pwdiWifConfigSetReqParams : pointer to wificonfig params + wdiLLStatsSetRspCb : set wificonfig response callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_WifiConfigSetReq + (WDI_WifiConfigSetReqType* pwdiWifConfigSetReqParams, + WDI_WifiConfigSetRspCb wdiWifiConfigSetRspCb, + void* pUserData); + +/** + @brief WDI_GetCurrentAntennaIndex + This API is called to send getCurretAntennaIndex request to FW + + @param pUserData: pointer to request params + wdiLLStatsSetRspCb : set wificonfig response callback + reserved: request parameter + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_GetCurrentAntennaIndex +( + void *pUserData, + WDI_AntennaDivSelRspCb wdiAntennaDivSelRspCb, + wpt_uint32 reserved +); + +/** + @brief WDI_SetBcnMissPenaltyCount + This API is called to send modified roam parameters to FW + + @param params: pointer to request params + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_SetBcnMissPenaltyCount +( + WDI_ModifyRoamParamsReqType *params +); + +/** + * WDI_SetAllowedActionFramesInd - This API is called to send Allowed + * Action frame details to FW + * @allowed_action_frames: Pointer to WDI_AllowedActionFramesInd structure + * which holds bitmask of allowed action frames + * + */ +WDI_Status +WDI_SetAllowedActionFramesInd( + struct WDI_AllowedActionFramesInd *allowed_action_frames +); + +void WDI_SetMgmtPktViaWQ5(wpt_boolean sendMgmtPktViaWQ5); + +/* ARP DEBUG STATS */ +typedef struct +{ + wpt_uint8 flag; + wpt_uint8 pkt_type; + wpt_uint32 ip_addr; +} WDI_SetARPStatsParamsInfoType; + +typedef struct +{ + wpt_uint32 status; +} WDI_SetARPStatsRspParamsType; + +typedef void (*WDI_SetARPStatsRspCb)(WDI_SetARPStatsRspParamsType* StatsRsp, + void* pUserData); + +WDI_Status +WDI_SetARPStatsReq +( + WDI_SetARPStatsParamsInfoType *pwdiSetStatsReqParams, + WDI_SetARPStatsRspCb wdiSetARPStatsRspCb, + void* pUserData +); + +/* ARP DEBUG STATS */ +typedef struct +{ + wpt_uint8 pkt_type; +} WDI_GetARPStatsParamsInfoType; + +typedef struct +{ + wpt_uint32 status; + wpt_uint16 dad; + wpt_uint16 tx_fw_cnt; + wpt_uint16 rx_fw_cnt; + wpt_uint16 tx_ack_cnt; +} WDI_GetARPStatsRspParamsType; + +typedef void (*WDI_GetARPStatsRspCb)(WDI_GetARPStatsRspParamsType* StatsRsp, + void* pUserData); + +WDI_Status +WDI_GetARPStatsReq +( + WDI_GetARPStatsParamsInfoType *pwdiGetStatsReqParams, + WDI_GetARPStatsRspCb wdiGetARPStatsRspCb, + void* pUserData +); + +WDI_Status +WDI_process_sap_auth_offload( + struct WDI_sap_ofl_enable_params *sap_ofl_enable_cmd +); +#ifdef WLAN_FEATURE_APFIND +WDI_Status WDI_process_ap_find_cmd(struct WDI_APFind_cmd *params); +#endif +#ifdef DHCP_SERVER_OFFLOAD +WDI_Status +wdi_process_dhcpserver_offload_req +( + wdi_set_dhcp_server_offload_t *dhcp_info, + wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback, + void *user_data +); +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +WDI_Status +wdi_set_mdns_offload_req +( + wdi_mdns_enable_offload_cmd_req *mdns_info, + wdi_mdns_enable_rsp_cb wdi_mdns_enable_rsp_callback, + void *user_data +); + +WDI_Status +wdi_set_mdns_fqdn_req +( + wdi_mdns_set_fqdn_cmd_req *mdns_info, + wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_rsp_callback, + void *user_data +); + +WDI_Status +wdi_set_mdns_response_req +( + wdi_mdns_set_resp_req *mdns_info, + wdi_mdns_resp_rsp_cb wdi_mdns_resp_rsp_callback, + void *user_data +); + +WDI_Status +wdi_get_mdns_stats_req +( + wdi_mdns_get_stats_req *mdns_info, + wdi_get_stats_rsp_cb wdi_get_stats_rsp_callback, + void *user_data +); +#endif /* MDNS_OFFLOAD */ + +WDI_Status +wdi_process_cap_tsf_req (wdi_cap_tsf_params_t *wdi_cap_tsf_req, + wdi_tsf_rsp_cb wdi_tsf_rsp_callback, + void *user_data); + +WDI_Status +wdi_process_get_tsf_req (wdi_cap_tsf_params_t *wdi_get_tsf_req, + wdi_tsf_rsp_cb wdi_tsf_rsp_callback, + void *user_data); + + +#endif /* #ifndef WLAN_QCT_WDI_H */ diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h new file mode 100644 index 000000000000..4ca3a6564723 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_bd.h @@ -0,0 +1,1322 @@ +/* + * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WDI_BD_H +#define WLAN_QCT_WDI_BD_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + B D H E A D E R D E F I N I T I O N + + +DESCRIPTION + This file contains the internal BD definition exposed by the DAL Control + Path Core module to be used by the DAL Data Path Core. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" + + +/*========================================================================= + BD STRUCTURE Defines + =========================================================================*/ +/*--------------------------------------------------------------------------- + WDI_RxBdType - The format of the RX BD +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + This routing flag indicates the WQ number to which the DPU will push the + frame after it finished processing it. */ + wpt_uint32 dpuRF:8; + + /** This is DPU sig inserted by RXP. Signature on RA's DPU descriptor */ + wpt_uint32 dpuSignature:3; + + /** When set Sta is authenticated. SW needs to set bit + addr2_auth_extract_enable in rxp_config2 register. Then RXP will use bit 3 + in DPU sig to say whether STA is authenticated or not. In this case only + lower 2bits of DPU Sig is valid */ + wpt_uint32 stAuF:1; + + /** When set address2 is not valid */ + wpt_uint32 A2HF:1; + + /** When set it indicates TPE has sent the Beacon frame */ + wpt_uint32 bsf:1; + + /** This bit filled by rxp when set indicates if the current tsf is smaller + than received tsf */ + wpt_uint32 rtsf:1; + +#ifdef WCN_PRONTO_CSU + /** No valid header found during parsing. Therefore no checksum was validated */ + wpt_uint32 csuNoValHd:1; + + /** 0 = CSU did not verify TCP/UDP (Transport Layer TL) checksum; 1 = CSU verified TCP/UDP checksum */ + wpt_uint32 csuVerifiedTLChksum:1; + + /** 0 = CSU did not verify IP checksum; 1 = CSU verified IP checksum */ + wpt_uint32 csuVerifiedIPChksum:1; + + /** 0 = BD field checksum is not valid; 1 = BD field checksum is valid */ + wpt_uint32 csuChksumValid:1; + + /** 0 = No TCP/UDP checksum error; 1 = Has TCP/UDP checksum error */ + wpt_uint32 csuTLChksumError:1; + + /** 0 = No IPv4/IPv6 checksum error; 1 = Has IPv4/IPv6 checksum error */ + wpt_uint32 csuIPChksumError:1; +#else /*WCN_PRONTO*/ + /** These two fields are used by SW to carry the Rx Channel number and SCAN bit in RxBD*/ + wpt_uint32 rxChannel:4; + wpt_uint32 scanLearn:1; + wpt_uint32 reserved0:1; +#endif /*WCN_PRONTO*/ + + /** LLC Removed + This bit is only used in Libra rsvd for Virgo1.0/Virgo2.0 + Filled by ADU when it is set LLC is removed from packet */ + wpt_uint32 llcr:1; + + wpt_uint32 umaByPass:1; + + /** This bit is only available in Virgo2.0/libra it is reserved in Virgo1.0 + Robust Management frame. This bit indicates to DPU that the packet is a + robust management frame which requires decryption(this bit is only valid for + management unicast encrypted frames) + 1 - Needs decryption + 0 - No decryption required */ + wpt_uint32 rmf:1; + + /** + This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is only valid when RMF bit is 1 */ + wpt_uint32 ub:1; + + /** This is the KEY ID extracted from WEP packets and is used for determine + the RX Key Index to use in the DPU Descriptror. + This field is 2bits for virgo 1.0 + And 3 bits in virgo2.0 and Libra + In virgo2.0/libra it is 3bits for the BC/MC packets */ + wpt_uint32 rxKeyId:3; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + wpt_uint32 dpuNE:1; + + /** + This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit is filled by RXP and modified by ADU + This bit indicates to ADU/UMA module that the packet requires 802.11n to + 802.3 frame translation. Once ADU/UMA is done with translation they + overwrite it with 1'b0/1'b1 depending on how the translation resulted + When used by ADU + 0 - No frame translation required + 1 - Frame Translation required + When used by SW + 0 - Frame translation not done, MPDU header offset points to 802.11 header.. + 1 - Frame translation done ; hence MPDU header offset will point to a + 802.3 header */ + wpt_uint32 ft:1; + + /** (Only used by the DPU) + BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + wpt_uint32 bdt:2; + +#else + wpt_uint32 bdt:2; + wpt_uint32 ft:1; + wpt_uint32 dpuNE:1; + wpt_uint32 rxKeyId:3; + wpt_uint32 ub:1; + wpt_uint32 rmf:1; + wpt_uint32 umaByPass:1; + wpt_uint32 llcr:1; + +#ifdef WCN_PRONTO_CSU + wpt_uint32 csuIPChksumError:1; + wpt_uint32 csuTLChksumError:1; + wpt_uint32 csuChksumValid:1; + wpt_uint32 csuVerifiedIPChksum:1; + wpt_uint32 csuVerifiedTLChksum:1; + wpt_uint32 csuNoValHd:1; +#else /*WCN_PRONTO*/ + wpt_uint32 reserved0:1; + wpt_uint32 scanLearn:1; + wpt_uint32 rxChannel:4; +#endif /*WCN_PRONTO*/ + + wpt_uint32 rtsf:1; + wpt_uint32 bsf:1; + wpt_uint32 A2HF:1; + wpt_uint32 stAuF:1; + wpt_uint32 dpuSignature:3; + wpt_uint32 dpuRF:8; +#endif + + /* 0x04 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is used for AMSDU this is the PDU index of the PDU which is the + one before last PDU; for all non AMSDU frames, this field SHALL be 0. + Used in ADU (for AMSDU deaggregation) */ + wpt_uint32 penultimatePduIdx:16; + +#ifdef WCN_PRONTO + wpt_uint32 aduFeedback:7; + wpt_uint32 dpuMagicPacket: 1; +#else + wpt_uint32 aduFeedback:8; +#endif //WCN_PRONTO + + /** DPU feedback */ + wpt_uint32 dpuFeedback:8; + +#else + wpt_uint32 dpuFeedback:8; +#ifdef WCN_PRONTO + wpt_uint32 dpuMagicPacket: 1; + wpt_uint32 aduFeedback:7; +#else + wpt_uint32 aduFeedback:8; +#endif //WCN_PRONTO + wpt_uint32 penultimatePduIdx:16; +#endif + + /* 0x08 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** In case PDUs are linked to the BD, this field indicates the index of + the first PDU linked to the BD. When PDU count is zero, this field has an + undefined value. */ + wpt_uint32 headPduIdx:16; + + /** In case PDUs are linked to the BD, this field indicates the index of + the last PDU. When PDU count is zero, this field has an undefined value.*/ + wpt_uint32 tailPduIdx:16; + +#else + wpt_uint32 tailPduIdx:16; + wpt_uint32 headPduIdx:16; +#endif + + /* 0x0c */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + wpt_uint32 mpduHeaderLength:8; + + /** The start byte number of the MPDU header. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. */ + wpt_uint32 mpduHeaderOffset:8; + + /** The start byte number of the MPDU data. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. Note that this offset can point all the way into the first + linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + wpt_uint32 mpduDataOffset:9; + + /** The number of PDUs linked to the BD. + This field should always indicate the correct amount. */ + wpt_uint32 pduCount:7; +#else + + wpt_uint32 pduCount:7; + wpt_uint32 mpduDataOffset:9; + wpt_uint32 mpduHeaderOffset:8; + wpt_uint32 mpduHeaderLength:8; +#endif + + /* 0x10 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is the length (in number of bytes) of the entire MPDU + (header and data). Note that the length does not include FCS field. */ + wpt_uint32 mpduLength:16; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + wpt_uint32 offloadScanLearn:1; + wpt_uint32 roamCandidateInd:1; +#else + wpt_uint32 reserved22:2; +#endif + +#ifdef WCN_PRONTO +#ifdef WLAN_FEATURE_EXTSCAN + wpt_uint32 extscanBuffer:1; +#else + wpt_uint32 reserved3: 1; +#endif + wpt_uint32 rxDXEPriorityRouting:1; +#else +#ifdef WLAN_FEATURE_EXTSCAN + wpt_uint32 extscanBuffer:1; + wpt_uint32 reserved3: 1; +#else + wpt_uint32 reserved3: 2; +#endif +#endif //WCN_PRONTO + + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, + this field is set to zero. */ + wpt_uint32 tid:4; + + wpt_uint32 indType:2; + wpt_uint32 reserved4:4; + wpt_uint32 htt_t2h_msg:1; + wpt_uint32 fc:1; + +#else + wpt_uint32 fc:1; + wpt_uint32 htt_t2h_msg:1; + wpt_uint32 reserved4:4; + wpt_uint32 indType:2; + wpt_uint32 tid:4; +#ifdef WCN_PRONTO + wpt_uint32 rxDXEPriorityRouting:1; +#ifdef WLAN_FEATURE_EXTSCAN + wpt_uint32 extscanBuffer:1; +#else + wpt_uint32 reserved3: 1; +#endif +#else +#ifdef WLAN_FEATURE_EXTSCAN + wpt_uint32 reserved3: 1; + wpt_uint32 extscanBuffer:1; +#else + wpt_uint32 reserved3: 2; +#endif +#endif //WCN_PRONTO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + wpt_uint32 roamCandidateInd:1; + wpt_uint32 offloadScanLearn:1; +#else + wpt_uint32 reserved22:2; +#endif + + wpt_uint32 mpduLength:16; +#endif + + /* 0x14 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + The DPU descriptor index is used to calculate where in memory the DPU can + find the DPU descriptor related to this frame. The DPU calculates the + address by multiplying this index with the DPU descriptor size and adding + the DPU descriptors base address. The DPU descriptor contains information + specifying the encryption and compression type and contains references to + where encryption keys can be found. */ + wpt_uint32 dpuDescIdx:8; + + /** The result from the binary address search on the ADDR1 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr1Index:8; + + /** The result from the binary address search on the ADDR2 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr2Index:8; + + /** The result from the binary address search on the ADDR3 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr3Index:8; +#else + wpt_uint32 addr3Index:8; + wpt_uint32 addr2Index:8; + wpt_uint32 addr1Index:8; + wpt_uint32 dpuDescIdx:8; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + + /** Indicates Rate Index of packet received */ + wpt_uint32 rateIndex:9; + + /** An overview of RXP status information related to receiving the frame.*/ + wpt_uint32 rxpFlags:23; + +#else + + wpt_uint32 rxpFlags:23; /* RxP flags*/ + wpt_uint32 rateIndex:9; + +#endif + /* 0x1c, 20 */ + /** The PHY can be programmed to put all the PHY STATS received from the + PHY when receiving a frame in the BD. */ + wpt_uint32 phyStats0; /* PHY status word 0*/ + wpt_uint32 phyStats1; /* PHY status word 1*/ + + /* 0x24 */ + /** The value of the TSF[31:0] bits at the moment that the RXP start + receiving a frame from the PHY RX. */ + wpt_uint32 mclkRxTimestamp; /* Rx timestamp, microsecond based*/ + + /* 0x28~0x38 */ + /** The bits from the PMI command as received from the PHY RX. */ + wpt_uint32 pmiCmd4to23[5]; /* PMI cmd rcvd from RxP */ + + /* 0x3c */ +#ifdef WCN_PRONTO +#ifdef WPT_BIG_BYTE_ENDIAN + /** The bits from the PMI command as received from the PHY RX. */ + wpt_uint32 pmiCmd24to25:16; + + /* 16-bit CSU Checksum value for the fragmented receive frames */ + wpt_uint32 csuChecksum:16; +#else + wpt_uint32 csuChecksum:16; + wpt_uint32 pmiCmd24to25:16; +#endif +#else /*WCN_PRONTO*/ + /** The bits from the PMI command as received from the PHY RX. */ + wpt_uint32 pmiCmd24to25; +#endif /*WCN_PRONTO*/ + + /* 0x40 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** Gives commands to software upon which host will perform some commands. + Please refer to following RPE document for description of all different + values for this field. */ + wpt_uint32 reorderOpcode:4; + + wpt_uint32 reserved6:12; + + /** Filled by RPE to Indicate to the host up to which slot the host needs + to forward the packets to upper Mac layer. This field mostly used for AMDPU + packets */ + wpt_uint32 reorderFwdIdx:6; + + /** Filled by RPE which indicates to the host which one of slots in the + available 64 slots should the host Queue the packet. This field only + applied to AMPDU packets. */ + wpt_uint32 reorderSlotIdx:6; + +#ifdef WCN_PRONTO + wpt_uint32 reserved7: 1; + wpt_uint32 perRoamCndInd:1; + wpt_uint32 outOfOrderForward: 1; + wpt_uint32 reorderEnable: 1; +#else + wpt_uint32 reserved7:4; +#endif //WCN_PRONTO + +#else + +#ifdef WCN_PRONTO + wpt_uint32 reorderEnable: 1; + wpt_uint32 outOfOrderForward: 1; + wpt_uint32 perRoamCndInd:1; + wpt_uint32 reserved7: 1; +#else + wpt_uint32 reserved7:4; +#endif //WCN_PRONTO + wpt_uint32 reorderSlotIdx:6; + wpt_uint32 reorderFwdIdx:6; + wpt_uint32 reserved6:12; + wpt_uint32 reorderOpcode:4; +#endif + + /* 0x44 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** reserved8 from a hardware perspective. + Used by SW to propogate frame type/subtype information */ + wpt_uint32 frameTypeSubtype:6; + wpt_uint32 rfBand:2; + + /** Filled RPE gives the current sequence number in bitmap */ + wpt_uint32 currentPktSeqNo:12; + + /** Filled by RPE which gives the sequence number of next expected packet + in bitmap */ + wpt_uint32 expectedPktSeqNo:12; +#else + wpt_uint32 expectedPktSeqNo:12; + wpt_uint32 currentPktSeqNo:12; + wpt_uint32 rfBand:2; + wpt_uint32 frameTypeSubtype:6; +#endif + + /* 0x48 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** When set it is the AMSDU subframe */ + wpt_uint32 asf:1; + + /** When set it is the First subframe of the AMSDU packet */ + wpt_uint32 esf:1; + + /** When set it is the last subframe of the AMSDU packet */ + wpt_uint32 lsf:1; + + /** When set it indicates an Errored AMSDU packet */ + wpt_uint32 aef:1; + + wpt_uint32 reserved9:4; + + /** It gives the order in which the AMSDU packet is processed + Basically this is a number which increments by one for every AMSDU frame + received. Mainly for debugging purpose. */ + wpt_uint32 processOrder:4; + + /** It is the order of the subframe of AMSDU that is processed by ADU. + This is reset to 0 when ADU deaggregates the first subframe from a new + AMSDU and increments by 1 for every new subframe deaggregated within the + AMSDU, after it reaches 4'hf it stops incrementing. That means host should + not rely on this field as index for subframe queuing. Theoretically there + can be way more than 16 subframes in an AMSDU. This is only used for debug + purpose, SW should use LSF and FSF bits to determine first and last + subframes. */ + wpt_uint32 sybFrameIdx:4; + + /** Filled by ADU this is the total AMSDU size */ + wpt_uint32 totalMsduSize:16; +#else + wpt_uint32 totalMsduSize:16; + wpt_uint32 sybFrameIdx:4; + wpt_uint32 processOrder:4; + wpt_uint32 reserved9:4; + wpt_uint32 aef:1; + wpt_uint32 lsf:1; + wpt_uint32 esf:1; + wpt_uint32 asf:1; +#endif + +} WDI_RxBdType; + +/*--------------------------------------------------------------------------- + WDI_RxFcBdType - The format of the RX special flow control BD +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + This routing flag indicates the WQ number to which the DPU will push the + frame after it finished processing it. */ + wpt_uint32 dpuRF:8; + + /** This is DPU sig inserted by RXP. Signature on RA's DPU descriptor */ + wpt_uint32 dpuSignature:3; + + /** When set Sta is authenticated. SW needs to set bit + addr2_auth_extract_enable in rxp_config2 register. Then RXP will use bit 3 + in DPU sig to say whether STA is authenticated or not. In this case only + lower 2bits of DPU Sig is valid */ + wpt_uint32 stAuF:1; + + /** When set address2 is not valid */ + wpt_uint32 A2HF:1; + + /** When set it indicates TPE has sent the Beacon frame */ + wpt_uint32 bsf:1; + + /** This bit filled by rxp when set indicates if the current tsf is smaller + than received tsf */ + wpt_uint32 rtsf:1; + + /** These two fields are used by SW to carry the Rx Channel number and SCAN bit in RxBD*/ + wpt_uint32 rxChannel:4; + wpt_uint32 scanLearn:1; + + wpt_uint32 reserved0:1; + + /** LLC Removed + This bit is only used in Libra rsvd for Virgo1.0/Virgo2.0 + Filled by ADU when it is set LLC is removed from packet */ + wpt_uint32 llcr:1; + + wpt_uint32 umaByPass:1; + + /** This bit is only available in Virgo2.0/libra it is reserved in Virgo1.0 + Robust Management frame. This bit indicates to DPU that the packet is a + robust management frame which requires decryption(this bit is only valid for + management unicast encrypted frames) + 1 - Needs decryption + 0 - No decryption required */ + wpt_uint32 rmf:1; + + /** + This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is only valid when RMF bit is 1 */ + wpt_uint32 ub:1; + + /** This is the KEY ID extracted from WEP packets and is used for determine + the RX Key Index to use in the DPU Descriptror. + This field is 2bits for virgo 1.0 + And 3 bits in virgo2.0 and Libra + In virgo2.0/libra it is 3bits for the BC/MC packets */ + wpt_uint32 rxKeyId:3; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + wpt_uint32 dpuNE:1; + + /** + This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit is filled by RXP and modified by ADU + This bit indicates to ADU/UMA module that the packet requires 802.11n to + 802.3 frame translation. Once ADU/UMA is done with translation they + overwrite it with 1'b0/1'b1 depending on how the translation resulted + When used by ADU + 0 - No frame translation required + 1 - Frame Translation required + When used by SW + 0 - Frame translation not done, MPDU header offset points to 802.11 header.. + 1 - Frame translation done ; hence MPDU header offset will point to a + 802.3 header */ + wpt_uint32 ft:1; + + /** (Only used by the DPU) + BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + wpt_uint32 bdt:2; + +#else + wpt_uint32 bdt:2; + wpt_uint32 ft:1; + wpt_uint32 dpuNE:1; + wpt_uint32 rxKeyId:3; + wpt_uint32 ub:1; + wpt_uint32 rmf:1; + wpt_uint32 reserved1:1; + wpt_uint32 llc:1; + wpt_uint32 reserved0:1; + wpt_uint32 scanLearn:1; + wpt_uint32 rxChannel:4; + wpt_uint32 rtsf:1; + wpt_uint32 bsf:1; + wpt_uint32 A2HF:1; + wpt_uint32 stAuF:1; + wpt_uint32 dpuSignature:3; + wpt_uint32 dpuRF:8; +#endif + + /* 0x04 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is used for AMSDU this is the PDU index of the PDU which is the + one before last PDU; for all non AMSDU frames, this field SHALL be 0. + Used in ADU (for AMSDU deaggregation) */ + wpt_uint32 penultimatePduIdx:16; + + wpt_uint32 aduFeedback:8; + + /** DPU feedback */ + wpt_uint32 dpuFeedback:8; + +#else + wpt_uint32 dpuFeedback:8; + wpt_uint32 aduFeedback:8; + wpt_uint32 penultimatePduIdx:16; +#endif + + /* 0x08 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** In case PDUs are linked to the BD, this field indicates the index of + the first PDU linked to the BD. When PDU count is zero, this field has an + undefined value. */ + wpt_uint32 headPduIdx:16; + + /** In case PDUs are linked to the BD, this field indicates the index of + the last PDU. When PDU count is zero, this field has an undefined value.*/ + wpt_uint32 tailPduIdx:16; + +#else + wpt_uint32 tailPduIdx:16; + wpt_uint32 headPduIdx:16; +#endif + + /* 0x0c */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + wpt_uint32 mpduHeaderLength:8; + + /** The start byte number of the MPDU header. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. */ + wpt_uint32 mpduHeaderOffset:8; + + /** The start byte number of the MPDU data. + The byte numbering is done in the BE format. Word 0x0, bits [31:24] has + byte index 0. Note that this offset can point all the way into the first + linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + wpt_uint32 mpduDataOffset:9; + + /** The number of PDUs linked to the BD. + This field should always indicate the correct amount. */ + wpt_uint32 pduCount:7; +#else + + wpt_uint32 pduCount:7; + wpt_uint32 mpduDataOffset:9; + wpt_uint32 mpduHeaderOffset:8; + wpt_uint32 mpduHeaderLength:8; +#endif + + /* 0x10 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** This is the length (in number of bytes) of the entire MPDU + (header and data). Note that the length does not include FCS field. */ + wpt_uint32 mpduLength:16; + + wpt_uint32 reserved3:4; + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, + this field is set to zero. */ + wpt_uint32 tid:4; + + wpt_uint32 reserved4:7; + wpt_uint32 fc:1; //if set then its special flow control BD. +#else + wpt_uint32 fc:1; //if set then its special flow control BD. + wpt_uint32 reserved4:7; + wpt_uint32 tid:4; + wpt_uint32 reserved3:4; + wpt_uint32 mpduLength:16; +#endif + + /* 0x14 */ +#ifdef WPT_BIG_BYTE_ENDIAN + + /** (Only used by the DPU) + The DPU descriptor index is used to calculate where in memory the DPU can + find the DPU descriptor related to this frame. The DPU calculates the + address by multiplying this index with the DPU descriptor size and adding + the DPU descriptors base address. The DPU descriptor contains information + specifying the encryption and compression type and contains references to + where encryption keys can be found. */ + wpt_uint32 dpuDescIdx:8; + + /** The result from the binary address search on the ADDR1 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr1Index:8; + + /** The result from the binary address search on the ADDR2 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr2Index:8; + + /** The result from the binary address search on the ADDR3 of the incoming + frame. See chapter: RXP filter for encoding of this field. */ + wpt_uint32 addr3Index:8; +#else + wpt_uint32 addr3Index:8; + wpt_uint32 addr2Index:8; + wpt_uint32 addr1Index:8; + wpt_uint32 dpuDescIdx:8; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + + /** Indicates Rate Index of packet received */ + wpt_uint32 rateIndex:9; + + /** An overview of RXP status information related to receiving the frame.*/ + wpt_uint32 rxpFlags:23; + +#else + + wpt_uint32 rxpFlags:23; /* RxP flags*/ + wpt_uint32 rateIndex:9; + +#endif + /* 0x1c, 20 */ + /** The PHY can be programmed to put all the PHY STATS received from the + PHY when receiving a frame in the BD. */ + wpt_uint32 phyStats0; /* PHY status word 0*/ + wpt_uint32 phyStats1; /* PHY status word 1*/ + + /* 0x24 */ + /** The value of the TSF[31:0] bits at the moment that the RXP start + receiving a frame from the PHY RX. */ + wpt_uint32 mclkRxTimestamp; /* Rx timestamp, microsecond based*/ + + /* 0x28 - 0x2c*/ +#ifdef WPT_BIG_BYTE_ENDIAN + /** One bit per STA. Bit X for STA id X, X=0~7. When set, corresponding STA is valid in FW's STA table.*/ + wpt_uint32 fcSTAValidMask:16; + /** One bit per STA. Bit X for STA id X, X=0~7. Valid only when corresponding bit in fcSTAValisMask is set.*/ + wpt_uint32 fcSTAPwrSaveStateMask:16; + /** One bit per STA. Bit X for STA id X, X=0~7. Valid only when corresponding bit in fcSTAValisMask is set. + When set, corresponding fcSTAThreshEnableMask bit in previous flow control request packet frame was enabled + AND the STA TxQ length is lower than configured fcSTAThresh value. */ + wpt_uint32 fcSTAThreshIndMask:16; + /** Bit 0 unit: 1=BD count(Libra SoftAP project default). 0=packet count. Bit 7-1: Reserved */ + wpt_uint32 fcSTATxQStatus:16; +#else + wpt_uint32 fcSTATxQStatus:16; + wpt_uint32 fcSTAThreshIndMask:16; + wpt_uint32 fcSTAPwrSaveStateMask:16; + wpt_uint32 fcSTAValidMask:16; +#endif + /* 0x30 */ +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 fcStaTxDisabledBitmap:16; + wpt_uint32 reserved5:16; +#else + wpt_uint32 reserved5:16; + wpt_uint32 fcStaTxDisabledBitmap:16; +#endif + + // with HAL_NUM_STA as 12 + /* 0x34 to 0x3A*/ + wpt_uint32 fcSTATxQLen[12]; // one byte per STA. + wpt_uint32 fcSTACurTxRate[12]; // current Tx rate for each sta. + +} WDI_FcRxBdType; //flow control BD + +/*--------------------------------------------------------------------------- + WDI_TxBdType - The format of the TX BD +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** (Only used by the DPU) This routing flag indicates the WQ number to + which the DPU will push the frame after it finished processing it. */ + wpt_uint32 dpuRF:8; + + /** DPU signature. Filled by Host in Virgo 1.0 but by ADU in Virgo 2.0 */ + wpt_uint32 dpuSignature:3; + +#ifdef WCN_PRONTO + /** Reserved */ + wpt_uint32 reserved0:2; + + /** Set to '1' to terminate the current AMPDU session. Added based on the + request for WiFi Display */ + wpt_uint32 terminateAMPDU:1; + + /** Bssid index to indicate ADU to use which of the 4 default MAC address + to use while 802.3 to 802.11 translation in case search in ADU UMA table + fails. The default MAC address should be appropriately programmed in the + uma_tx_default_wmacaddr_u(_1,_2,_3) and uma_tx_default_wmacaddr_l(_1,_2,_3) + registers */ + wpt_uint32 umaBssidIdx:2; + + /** Set to 1 to enable uma filling the BD when FT is not enabled. + Ignored when FT is enabled. */ + wpt_uint32 umaBDEnable:1; + + /** (Only used by the CSU) + 0: No action + 1: Host will indicate TCP/UPD header start location and provide pseudo header value in BD. + */ + wpt_uint32 csuSWMode:1; + + /** Enable/Disable CSU on TX direction. + 0: Disable Checksum Unit (CSU) for Transmit. + 1: Enable + */ + wpt_uint32 csuTXEnable:1; + + /** Enable/Disable Transport layer Checksum in CSU + 0: Disable TCP UDP checksum generation for TX. + 1: Enable TCP UDP checksum generation for TX. + */ + wpt_uint32 csuEnableTLCksum:1; + + /** Enable/Disable IP layer Checksum in CSU + 0: Disable IPv4/IPv6 checksum generation for TX + 1: Enable IPv4/IPv6 checksum generation for TX + */ + wpt_uint32 csuEnableIPCksum:1; + + /** Filled by CSU to indicate whether transport layer Checksum is generated by CSU or not + 0: TCP/UDP checksum is being generated for TX. + 1: TCP/UDP checksum is NOT being generated for TX. + */ + wpt_uint32 csuTLCksumGenerated:1; + + /** Filled by CSU in error scenario + 1: No valid header found during parsing. Therefore no checksum was validated. + 0: Valid header found + */ + wpt_uint32 csuNoValidHeader:1; +#else /*WCN_PRONTO*/ + wpt_uint32 reserved0:12; +#endif /*WCN_PRONTO*/ + + /** Only available in Virgo 2.0 and reserved in Virgo 1.0. + This bit indicates to DPU that the packet is a robust management frame + which requires encryption(this bit is only valid for certain management + frames) + 1 - Needs encryption + 0 - No encrytion required + It is only set when Privacy bit=1 AND type/subtype=Deauth, Action, + Disassoc. Otherwise it should always be 0. */ + wpt_uint32 rmf:1; + + /** This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This 1-bit field indicates to DPU Unicast/BC/MC packet + 0 - Unicast packet + 1 - Broadcast/Multicast packet + This bit is valid only if RMF bit is set */ + wpt_uint32 ub:1; + + wpt_uint32 reserved1:1; + + /** This bit is only in Virgo2.0/libra it is reserved in Virgo 1.0 + This bit indicates TPE has to assert the TX complete interrupt. + 0 - no interrupt + 1 - generate interrupt */ + wpt_uint32 txComplete1:1; + wpt_uint32 fwTxComplete0:1; + + /** (Only used by the DPU) + No encryption/decryption + 0: No action + 1: DPU will not encrypt/decrypt the frame, and discard any encryption + related settings in the PDU descriptor. */ + wpt_uint32 dpuNE:1; + + + /** This is only available in libra/virgo2.0 it is reserved for virgo1.0 + This bit indicates to ADU/UMA module that the packet requires 802.11n + to 802.3 frame translation. When used by ADU + 0 - No frame translation required + 1 - Frame Translation required */ + wpt_uint32 ft:1; + + /** BD Type + 00: 'Generic BD', as indicted above + 01: De-fragmentation format + 10-11: Reserved for future use. */ + wpt_uint32 bdt:2; +#else + wpt_uint32 bdt:2; + wpt_uint32 ft:1; + wpt_uint32 dpuNE:1; + wpt_uint32 fwTxComplete0:1; + wpt_uint32 txComplete1:1; + wpt_uint32 reserved1:1; + wpt_uint32 ub:1; + wpt_uint32 rmf:1; +#ifdef WCN_PRONTO + wpt_uint32 csuNoValidHeader:1; + wpt_uint32 csuTLCksumGenerated:1; + wpt_uint32 csuEnableIPCksum:1; + wpt_uint32 csuEnableTLCksum:1; + wpt_uint32 csuTXEnable:1; + wpt_uint32 csuSWMode:1; + wpt_uint32 umaBDEnable:1; + wpt_uint32 umaBssidIdx:2; + wpt_uint32 terminateAMPDU:1; + wpt_uint32 reserved0:2; +#else /*WCN_PRONTO*/ + wpt_uint32 reserved0:12; +#endif /*WCN_PRONTO*/ + wpt_uint32 dpuSignature:3; + wpt_uint32 dpuRF:8; +#endif + + /* 0x04 */ +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved2:16; /* MUST BE 0 otherwise triggers BMU error*/ + wpt_uint32 aduFeedback:8; + + /* DPU feedback in Tx path.*/ + wpt_uint32 dpuFeedback:8; + +#else + wpt_uint32 dpuFeedback:8; + wpt_uint32 aduFeedback:8; + wpt_uint32 reserved2:16; +#endif + + /* 0x08 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** It is initially filled by DXE then if encryption is on, then DPU will + overwrite these fields. In case PDUs are linked to the BD, this field + indicates the index of the first PDU linked to the BD. When PDU count is + zero, this field has an undefined value. */ + wpt_uint32 headPduIdx:16; + + /** It is initially filled by DXE then if encryption is on, then DPU will + overwrite these fields.In case PDUs are linked to the BD, this field + indicates the index of the last PDU. When PDU count is zero, this field + has an undefined value. */ + wpt_uint32 tailPduIdx:16; +#else + wpt_uint32 tailPduIdx:16; + wpt_uint32 headPduIdx:16; +#endif + + /* 0x0c */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/Libra. The length (in number of bytes) of the MPDU header. + Limitation: The MPDU header offset + MPDU header length can never go beyond + the end of the first PDU */ + wpt_uint32 mpduHeaderLength:8; + + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/Libra. The start byte number of the MPDU header. The byte numbering + is done in the BE format. Word 0x0, bits [31:24] has byte index 0. */ + wpt_uint32 mpduHeaderOffset:8; + + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/Libra. The start byte number of the MPDU data. The byte numbering + is done in the BE format. Word 0x0, bits [31:24] has byte index 0. + Note that this offset can point all the way into the first linked PDU. + Limitation: MPDU DATA OFFSET can not point into the 2nd linked PDU */ + wpt_uint32 mpduDataOffset:9; + + /** It is initially filled by DXE then if encryption is on, then DPU will + overwrite these fields. The number of PDUs linked to the BD. This field + should always indicate the correct amount. */ + wpt_uint32 pduCount:7; +#else + wpt_uint32 pduCount:7; + wpt_uint32 mpduDataOffset:9; + wpt_uint32 mpduHeaderOffset:8; + wpt_uint32 mpduHeaderLength:8; +#endif + + /* 0x10 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** This is filled by Host in Virgo 1.0 but it gets changed by ADU in + Virgo2.0/LibraMPDU length.This covers MPDU header length + MPDU data length. + This does not include FCS. For single frame transmission, PSDU size is + mpduLength + 4.*/ + wpt_uint32 mpduLength:16; + + wpt_uint32 reserved3:2; + /** Sequence number insertion by DPU + 00: Leave sequence number as is, as filled by host + 01: DPU to insert non TID based sequence number (If it is not TID based, + then how does DPU know what seq to fill? Is this the non-Qos/Mgmt sequence + number? + 10: DPU to insert a sequence number based on TID. + 11: Reserved */ + wpt_uint32 bd_ssn:2; + + /** Traffic Identifier + Indicates the traffic class the frame belongs to. For non QoS frames, this + field is set to zero. */ + wpt_uint32 tid:4; + + wpt_uint32 reserved4:8; + +#else + wpt_uint32 reserved4:8; + wpt_uint32 tid:4; + wpt_uint32 bd_ssn:2; + wpt_uint32 reserved3:2; + wpt_uint32 mpduLength:16; +#endif + + /* 0x14 */ +#ifdef WPT_BIG_BYTE_ENDIAN + /** (Only used by the DPU) + This is filled by Host in Virgo 1.0 but it gets filled by ADU in + Virgo2.0/Libra. The DPU descriptor index is used to calculate where in + memory the DPU can find the DPU descriptor related to this frame. The DPU + calculates the address by multiplying this index with the DPU descriptor + size and adding the DPU descriptors base address. The DPU descriptor + contains information specifying the encryption and compression type and + contains references to where encryption keys can be found. */ + wpt_uint32 dpuDescIdx:8; + + /** This is filled by Host in Virgo 1.0 but it gets filled by ADU in + Virgo2.0/Libra. The STAid of the RA address */ + wpt_uint32 staIndex:8; + + /** A field passed on to TPE which influences the ACK policy to be used for + this frame + 00 - Iack + 01,10,11 - No Ack */ + wpt_uint32 ap:2; + + /** Overwrite option for the transmit rate + 00: Use rate programmed in the TPE STA descriptor + 01: Use TPE BD rate 1 + 10: Use TPE BD rate 2 + 11: Delayed Use TPE BD rate 3 */ + wpt_uint32 bdRate:2; + + /** + This is filled by Host in Virgo 1.0 but it gets filled by ADU in + Virgo2.0/Libra. Queue ID */ + wpt_uint32 queueId:5; + + wpt_uint32 isArp:1; + + wpt_uint32 reserved5:6; +#else + wpt_uint32 reserved5:6; + wpt_uint32 isArp:1; + wpt_uint32 queueId:5; + wpt_uint32 bdRate:2; + wpt_uint32 ap:2; + wpt_uint32 staIndex:8; + wpt_uint32 dpuDescIdx:8; +#endif + + wpt_uint32 txBdSignature; + + /* 0x1C */ + wpt_uint32 reserved6; + /* 0x20 */ + /* Timestamp filled by DXE. Timestamp for current transfer */ + wpt_uint32 dxeH2BStartTimestamp; + + /* 0x24 */ + /* Timestamp filled by DXE. Timestamp for previous transfer */ + wpt_uint32 dxeH2BEndTimestamp; + +#ifdef WCN_PRONTO +#ifdef WPT_BIG_BYTE_ENDIAN + /** 10 bit value to indicate the start of TCP UDP frame relative to + * the first IP frame header */ + wpt_uint32 csuTcpUdpStartOffset:10; + + /** 16 bit pseudo header for TCP UDP used by CSU to generate TCP/UDP + * frame checksum */ + wpt_uint32 csuPseudoHeaderCksum:16; + + wpt_uint32 reserved7:6; +#else + wpt_uint32 reserved7:6; + wpt_uint32 csuPseudoHeaderCksum:16; + wpt_uint32 csuTcpUdpStartOffset:10; +#endif +#endif /*WCN_PRONTO*/ + wpt_uint32 txBdToken; + +} WDI_TxBdType; + +/*--------------------------------------------------------------------------- + WDI_RxDeFragBdType - The format of the RX BD Defragmented +---------------------------------------------------------------------------*/ +typedef struct +{ + /* 0x00 */ +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved1:30; + wpt_uint32 bdt:2; +#else + wpt_uint32 bdt:2; + wpt_uint32 reserved1:30; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved2:24; + wpt_uint32 dpuFeedBack:8; +#else + wpt_uint32 dpuFeedBack:8; + wpt_uint32 reserved2:24; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved3:16; + wpt_uint32 frag0BdIdx:16; +#else + wpt_uint32 frag0BdIdx:16; + wpt_uint32 reserved3:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved4:16; + wpt_uint32 frag1BdIdx:16; +#else + wpt_uint32 frag1BdIdx:16; + wpt_uint32 reserved4:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 frag2BdIdx:16; + wpt_uint32 reserved5:16; +#else + wpt_uint32 frag2BdIdx:16; + wpt_uint32 reserved5:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved6:16; + wpt_uint32 frag3BdIdx:16; +#else + wpt_uint32 frag3BdIdx:16; + wpt_uint32 reserved6:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved7:16; + wpt_uint32 frag4BdIdx:16; +#else + wpt_uint32 frag4BdIdx:16; + wpt_uint32 reserved7:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved8:16; + wpt_uint32 frag5BdIdx:16; +#else + wpt_uint32 frag5BdIdx:16; + wpt_uint32 reserved8:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved9:16; + wpt_uint32 frag6BdIdx:16; +#else + wpt_uint32 frag6BdIdx:16; + wpt_uint32 reserved9:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved10:16; + wpt_uint32 frag7BdIdx:16; +#else + wpt_uint32 frag7BdIdx:16; + wpt_uint32 reserved10:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved11:16; + wpt_uint32 frag8BdIdx:16; +#else + wpt_uint32 frag8BdIdx:16; + wpt_uint32 reserved11:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved12:16; + wpt_uint32 frag9BdIdx:16; +#else + wpt_uint32 frag9BdIdx:16; + wpt_uint32 reserved12:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved13:16; + wpt_uint32 frag10BdIdx:16; +#else + wpt_uint32 frag10BdIdx:16; + wpt_uint32 reserved13:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved14:16; + wpt_uint32 frag11BdIdx:16; +#else + wpt_uint32 frag11BdIdx:16; + wpt_uint32 reserved14:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved15:16; + wpt_uint32 frag12BdIdx:16; +#else + wpt_uint32 frag12BdIdx:16; + wpt_uint32 reserved15:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 reserved16:16; + wpt_uint32 frag13BdIdx:16; +#else + wpt_uint32 frag13BdIdx:16; + wpt_uint32 reserved16:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 frag14BdIdx:16; + wpt_uint32 reserved17:16; +#else + wpt_uint32 frag14BdIdx:16; + wpt_uint32 reserved17:16; +#endif + +#ifdef WPT_BIG_BYTE_ENDIAN + wpt_uint32 frag15BdIdx:16; + wpt_uint32 reserved18:16; +#else + wpt_uint32 frag15BdIdx:16; + wpt_uint32 reserved18:16; +#endif + +} WDI_RxDeFragBdType; + +#endif /*WLAN_QCT_WDI_BD_H*/ diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h new file mode 100644 index 000000000000..90e7bce6712d --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_cfg.h @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WDI_CFG_H +#define WLAN_QCT_WDI_CFG_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + C O N F I G U R A T I O N D E F I N E S + E X T E R N A L A P I + +DESCRIPTION + This file contains the configuration defines to be used by the UMAC for + setting up the config parameters in DAL. + + !! The values in here should be an identical match of the HAL defines + by the same name !! + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +/*------------------------------------------------------------------------- + Preprocessor definitions and constants +-------------------------------------------------------------------------*/ +#define WDI_MAX_CFG_LENGTH 0x06 + +/*------------------------------------------------------------------------- + Configuration Parameter IDs +-------------------------------------------------------------------------*/ +#define WDI_CFG_STA_ID 0 +#define WDI_CFG_CURRENT_TX_ANTENNA 1 +#define WDI_CFG_CURRENT_RX_ANTENNA 2 +#define WDI_CFG_LOW_GAIN_OVERRIDE 3 +#define WDI_CFG_POWER_STATE_PER_CHAIN 4 +#define WDI_CFG_CAL_PERIOD 5 +#define WDI_CFG_CAL_CONTROL 6 +#define WDI_CFG_PROXIMITY 7 +#define WDI_CFG_NETWORK_DENSITY 8 +#define WDI_CFG_MAX_MEDIUM_TIME 9 +#define WDI_CFG_MAX_MPDUS_IN_AMPDU 10 +#define WDI_CFG_RTS_THRESHOLD 11 +#define WDI_CFG_SHORT_RETRY_LIMIT 12 +#define WDI_CFG_LONG_RETRY_LIMIT 13 +#define WDI_CFG_FRAGMENTATION_THRESHOLD 14 +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO 15 +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE 16 +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO 17 +#define WDI_CFG_FIXED_RATE 18 +#define WDI_CFG_RETRYRATE_POLICY 19 +#define WDI_CFG_RETRYRATE_SECONDARY 20 +#define WDI_CFG_RETRYRATE_TERTIARY 21 +#define WDI_CFG_FORCE_POLICY_PROTECTION 22 +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ 23 +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ 24 +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ 25 +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ 26 +#define WDI_CFG_MAX_BA_SESSIONS 27 +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT 28 +#define WDI_CFG_PS_ENABLE_BCN_FILTER 29 +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR 30 +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE 31 +#define WDI_CFG_STATS_PERIOD 32 +#define WDI_CFG_CFP_MAX_DURATION 33 + +/*------------------------------------------------------------------------- + Configuration Parameter min, max, defaults +-------------------------------------------------------------------------*/ + +/* WDI_CFG_CURRENT_TX_ANTENNA */ +#define WDI_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define WDI_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define WDI_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +/* WDI_CFG_CURRENT_RX_ANTENNA */ +#define WDI_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define WDI_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define WDI_CFG_CURRENT_RX_ANTENNA_STADEF 1 + +/* WDI_CFG_LOW_GAIN_OVERRIDE */ +#define WDI_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define WDI_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define WDI_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +/* WDI_CFG_POWER_STATE_PER_CHAIN */ +#define WDI_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define WDI_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define WDI_CFG_POWER_STATE_PER_CHAIN_STADEF 785 +#define WDI_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define WDI_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define WDI_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define WDI_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define WDI_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define WDI_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define WDI_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define WDI_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +/* WDI_CFG_CAL_PERIOD */ +#define WDI_CFG_CAL_PERIOD_STAMIN 2 +#define WDI_CFG_CAL_PERIOD_STAMAX 10 +#define WDI_CFG_CAL_PERIOD_STADEF 5 + +/* WDI_CFG_CAL_CONTROL */ +#define WDI_CFG_CAL_CONTROL_STAMIN 0 +#define WDI_CFG_CAL_CONTROL_STAMAX 1 +#define WDI_CFG_CAL_CONTROL_STADEF 0 + +/* WDI_CFG_PROXIMITY */ +#define WDI_CFG_PROXIMITY_STAMIN 0 +#define WDI_CFG_PROXIMITY_STAMAX 1 +#define WDI_CFG_PROXIMITY_STADEF 0 +#define WDI_CFG_PROXIMITY_OFF 0 +#define WDI_CFG_PROXIMITY_ON 1 + +/* WDI_CFG_NETWORK_DENSITY */ +#define WDI_CFG_NETWORK_DENSITY_STAMIN 0 +#define WDI_CFG_NETWORK_DENSITY_STAMAX 3 +#define WDI_CFG_NETWORK_DENSITY_STADEF 3 +#define WDI_CFG_NETWORK_DENSITY_LOW 0 +#define WDI_CFG_NETWORK_DENSITY_MEDIUM 1 +#define WDI_CFG_NETWORK_DENSITY_HIGH 2 +#define WDI_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +/* WDI_CFG_MAX_MEDIUM_TIME */ +#define WDI_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define WDI_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define WDI_CFG_MAX_MEDIUM_TIME_STADEF 1024 + +/* WDI_CFG_MAX_MPDUS_IN_AMPDU */ +#define WDI_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define WDI_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define WDI_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +/* WDI_CFG_RTS_THRESHOLD */ +#define WDI_CFG_RTS_THRESHOLD_STAMIN 0 +#define WDI_CFG_RTS_THRESHOLD_STAMAX 2347 +#define WDI_CFG_RTS_THRESHOLD_STADEF 2347 + +/* WDI_CFG_SHORT_RETRY_LIMIT */ +#define WDI_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define WDI_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define WDI_CFG_SHORT_RETRY_LIMIT_STADEF 6 + +/* WDI_CFG_LONG_RETRY_LIMIT */ +#define WDI_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define WDI_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define WDI_CFG_LONG_RETRY_LIMIT_STADEF 6 + +/* WDI_CFG_FRAGMENTATION_THRESHOLD */ +#define WDI_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define WDI_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define WDI_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +/* WDI_CFG_DYNAMIC_THRESHOLD_ZERO */ +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define WDI_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 2 + +/* WDI_CFG_DYNAMIC_THRESHOLD_ONE */ +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define WDI_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 4 + +/* WDI_CFG_DYNAMIC_THRESHOLD_TWO */ +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define WDI_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 6 + +/* WDI_CFG_FIXED_RATE */ +#define WDI_CFG_FIXED_RATE_STAMIN 0 +#define WDI_CFG_FIXED_RATE_STAMAX 31 +#define WDI_CFG_FIXED_RATE_STADEF 0 +#define WDI_CFG_FIXED_RATE_AUTO 0 +#define WDI_CFG_FIXED_RATE_1MBPS 1 +#define WDI_CFG_FIXED_RATE_2MBPS 2 +#define WDI_CFG_FIXED_RATE_5_5MBPS 3 +#define WDI_CFG_FIXED_RATE_11MBPS 4 +#define WDI_CFG_FIXED_RATE_6MBPS 5 +#define WDI_CFG_FIXED_RATE_9MBPS 6 +#define WDI_CFG_FIXED_RATE_12MBPS 7 +#define WDI_CFG_FIXED_RATE_18MBPS 8 +#define WDI_CFG_FIXED_RATE_24MBPS 9 +#define WDI_CFG_FIXED_RATE_36MBPS 10 +#define WDI_CFG_FIXED_RATE_48MBPS 11 +#define WDI_CFG_FIXED_RATE_54MBPS 12 +#define WDI_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define WDI_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define WDI_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define WDI_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define WDI_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define WDI_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define WDI_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define WDI_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define WDI_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define WDI_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define WDI_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define WDI_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define WDI_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define WDI_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define WDI_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define WDI_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define WDI_CFG_FIXED_RATE_0_25MBPS_SLR_20MHZ_SIMO 29 +#define WDI_CFG_FIXED_RATE_0_5MBPS_SLR_20MHZ_SIMO 30 +#define WDI_CFG_FIXED_RATE_68_25MBPS_QC_PROP_20MHZ_SIMO 31 + +/* WDI_CFG_RETRYRATE_POLICY */ +#define WDI_CFG_RETRYRATE_POLICY_STAMIN 0 +#define WDI_CFG_RETRYRATE_POLICY_STAMAX 255 +#define WDI_CFG_RETRYRATE_POLICY_STADEF 4 +#define WDI_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define WDI_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define WDI_CFG_RETRYRATE_POLICY_RESERVED 2 +#define WDI_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define WDI_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define WDI_CFG_RETRYRATE_POLICY_MAX 5 + +/* WDI_CFG_RETRYRATE_SECONDARY */ +#define WDI_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define WDI_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define WDI_CFG_RETRYRATE_SECONDARY_STADEF 0 + +/* WDI_CFG_RETRYRATE_TERTIARY */ +#define WDI_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define WDI_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define WDI_CFG_RETRYRATE_TERTIARY_STADEF 0 + +/* WDI_CFG_FORCE_POLICY_PROTECTION */ +#define WDI_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define WDI_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define WDI_CFG_FORCE_POLICY_PROTECTION_STADEF 5 +#define WDI_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define WDI_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define WDI_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define WDI_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define WDI_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define WDI_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +/* WDI_CFG_FIXED_RATE_MULTICAST_24GHZ */ +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX 31 +#define WDI_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF 1 + +/* WDI_CFG_FIXED_RATE_MULTICAST_5GHZ */ +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX 31 +#define WDI_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF 5 + +/* WDI_CFG_DEFAULT_RATE_INDEX_24GHZ */ +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX 31 +#define WDI_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF 1 + +/* WDI_CFG_DEFAULT_RATE_INDEX_5GHZ */ +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX 11 +#define WDI_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF 5 + +/* WDI_CFG_MAX_BA_SESSIONS */ +#define WDI_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define WDI_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define WDI_CFG_MAX_BA_SESSIONS_STADEF 16 + +/* WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT */ +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define WDI_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +/* WDI_CFG_PS_ENABLE_BCN_FILTER */ +#define WDI_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define WDI_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define WDI_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +/* WDI_CFG_PS_ENABLE_RSSI_MONITOR */ +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define WDI_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 1 + +/* WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE */ +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define WDI_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +/* WDI_CFG_STATS_PERIOD */ +#define WDI_CFG_STATS_PERIOD_STAMIN 1 +#define WDI_CFG_STATS_PERIOD_STAMAX 10 +#define WDI_CFG_STATS_PERIOD_STADEF 10 + +/* WDI_CFG_CFP_MAX_DURATION */ +#define WDI_CFG_CFP_PERIOD_STAMIN 0 +#define WDI_CFG_CFP_PERIOD_STAMAX 255 +#define WDI_CFG_CFP_PERIOD_STADEF 1 + +#endif /*WLAN_QCT_WDI_CFG_H*/ diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h new file mode 100644 index 000000000000..ca1b403af0f4 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_WDI_DP_H +#define WLAN_QCT_WDI_DP_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + D A T A P A T H + + +DESCRIPTION + This file contains the internal API exposed by the DAL Control Path Core + module to be used by the DAL Data Path Core. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_wdi_i.h" +#include "wlan_qct_wdi_bd.h" + +/*========================================================================= + BD Macro Defines +=========================================================================*/ + +/*-------------------------------------------------------------------------- + BD Definitions used by the DAL data path +--------------------------------------------------------------------------*/ +#define WDI_TXBD_BDRATE_DEFAULT 0 +#define WDI_TXBD_BDRATE_FIRST 1 +#define WDI_TXBD_BDRATE_SECOND 2 +#define WDI_TXBD_BDRATE_THIRD 3 + +#define WDI_FRAME_TYPE_MASK 0x30 +#define WDI_FRAME_TYPE_OFFSET 0x4 +#define WDI_FRAME_SUBTYPE_MASK 0x0F + +#define WDI_TXBD_BD_SSN_FILL_HOST 0 +#define WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS 1 +#define WDI_TXBD_BD_SSN_FILL_DPU_QOS 2 + +#define WDI_ACKPOLICY_ACK_REQUIRED 0 +#define WDI_ACKPOLICY_ACK_NOTREQUIRED 1 + +#define WDI_BDRATE_BCDATA_FRAME 1 +#define WDI_BDRATE_BCMGMT_FRAME 2 +#define WDI_BDRATE_CTRL_FRAME 3 + +/* Default values for FillTx BD */ +#define WDI_DEFAULT_UNICAST_ENABLED 1 +#define WDI_RMF_DISABLED 0 +#define WDI_RMF_ENABLED 1 +#define WDI_NO_ENCRYPTION_DISABLED 0 +#define WDI_NO_ENCRYPTION_ENABLED 1 + +#define WDI_RX_BD_ADDR3_SELF_IDX 0 + +#define WDI_TXCOMP_REQUESTED_MASK 0x1 //bit 0 for TxComp intr requested. +#define WDI_USE_SELF_STA_REQUESTED_MASK 0x2 //bit 1 for STA overwrite with selfSta Requested. +#define WDI_TX_NO_ENCRYPTION_MASK 0x4 //bit 2. If set, the frame is not to be encrypted +#if defined(LIBRA_WAPI_SUPPORT) +#define WDI_WAPI_STA_MASK 0x8 //bit 3. If set, this frame is for WAPI station +#endif + +#define WDI_TRIGGER_ENABLED_AC_MASK 0x10 //bit 4 for data frames belonging to trigger enabled AC +#define WDI_USE_NO_ACK_REQUESTED_MASK 0x20 + +#define WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames + +#ifdef FEATURE_WLAN_TDLS +#define HAL_TDLS_PEER_STA_MASK 0x80 //bit 7 set for TDLS peer station +#endif + +#ifdef WLAN_FEATURE_RMC +#define WDI_RMC_REQUESTED_MASK 0x100 +#endif + +#define WDI_USE_BD_RATE_1_MASK 0x1000 +#define WDI_USE_BD_RATE_2_MASK 0x2000 +#define WDI_USE_BD_RATE_3_MASK 0x4000 +#define WDI_USE_FW_IN_TX_PATH 0x200 //bit 9 used to route the frames to Work Queue 5 + +/*Macro for getting the size of the TX BD*/ +#define WDI_TX_BD_HEADER_SIZE sizeof(WDI_TxBdType) + +/*Macro for getting the size of the RX BD*/ +#define WDI_RX_BD_HEADER_SIZE sizeof(WDI_RxBdType) + +#define WDI_RX_BD_HEADER_OFFSET 0 + +#define WDI_DPU_FEEDBACK_OFFSET 1 + +#define WDI_MAC_LLC_HEADER_SIZE 8 + + +// Frame Type definitions + +#define WDI_MAC_MGMT_FRAME 0x0 +#define WDI_MAC_CTRL_FRAME 0x1 +#define WDI_MAC_DATA_FRAME 0x2 + +// Data frame subtype definitions +#define WDI_MAC_DATA_DATA 0 +#define WDI_MAC_DATA_DATA_ACK 1 +#define WDI_MAC_DATA_DATA_POLL 2 +#define WDI_MAC_DATA_DATA_ACK_POLL 3 +#define WDI_MAC_DATA_NULL 4 +#define WDI_MAC_DATA_NULL_ACK 5 +#define WDI_MAC_DATA_NULL_POLL 6 +#define WDI_MAC_DATA_NULL_ACK_POLL 7 +#define WDI_MAC_DATA_QOS_DATA 8 +#define WDI_MAC_DATA_QOS_DATA_ACK 9 +#define WDI_MAC_DATA_QOS_DATA_POLL 10 +#define WDI_MAC_DATA_QOS_DATA_ACK_POLL 11 +#define WDI_MAC_DATA_QOS_NULL 12 +#define WDI_MAC_DATA_QOS_NULL_ACK 13 +#define WDI_MAC_DATA_QOS_NULL_POLL 14 +#define WDI_MAC_DATA_QOS_NULL_ACK_POLL 15 + +#define WDI_MAC_FRAME_SUBTYPE_START 0 +#define WDI_MAC_FRAME_SUBTYPE_END 16 + +#define WDI_MAC_DATA_QOS_MASK 8 +#define WDI_MAC_DATA_NULL_MASK 4 +#define WDI_MAC_DATA_POLL_MASK 2 +#define WDI_MAC_DATA_ACK_MASK 1 + +// Management frame subtype definitions + +#define WDI_MAC_MGMT_ASSOC_REQ 0x0 +#define WDI_MAC_MGMT_ASSOC_RSP 0x1 +#define WDI_MAC_MGMT_REASSOC_REQ 0x2 +#define WDI_MAC_MGMT_REASSOC_RSP 0x3 +#define WDI_MAC_MGMT_PROBE_REQ 0x4 +#define WDI_MAC_MGMT_PROBE_RSP 0x5 +#define WDI_MAC_MGMT_BEACON 0x8 +#define WDI_MAC_MGMT_ATIM 0x9 +#define WDI_MAC_MGMT_DISASSOC 0xA +#define WDI_MAC_MGMT_AUTH 0xB +#define WDI_MAC_MGMT_DEAUTH 0xC +#define WDI_MAC_MGMT_ACTION 0xD +#define WDI_MAC_MGMT_RESERVED15 0xF + +// Action frame categories + +#define WDI_MAC_ACTION_SPECTRUM_MGMT 0 +#define WDI_MAC_ACTION_QOS_MGMT 1 +#define WDI_MAC_ACTION_DLP 2 +#define WDI_MAC_ACTION_BLKACK 3 +#define WDI_MAC_ACTION_HT 7 +#define WDI_MAC_ACTION_WME 17 + +// QoS management action codes + +#define WDI_MAC_QOS_ADD_TS_REQ 0 +#define WDI_MAC_QOS_ADD_TS_RSP 1 +#define WDI_MAC_QOS_DEL_TS_REQ 2 +#define WDI_MAC_QOS_SCHEDULE 3 +// and these are proprietary +#define WDI_MAC_QOS_DEF_BA_REQ 4 +#define WDI_MAC_QOS_DEF_BA_RSP 5 +#define WDI_MAC_QOS_DEL_BA_REQ 6 +#define WDI_MAC_QOS_DEL_BA_RSP 7 + +#ifdef WLAN_PERF +/* TxBD signature fields + * serial(8): a monotonically increasing serial # whenever there is a Add/Del STA or Add/Del Key event + * macHash(16): Hash value of DA + * tid(4): TID + * ucast(1): Unicast or Broadcast data frame + */ +#define WDI_TXBD_SIG_SERIAL_OFFSET 0 +#define WDI_TXBD_SIG_TID_OFFSET 8 +#define WDI_TXBD_SIG_UCAST_DATA_OFFSET 9 +#define WDI_TXBD_SIG_MACADDR_HASH_OFFSET 16 +#define WDI_TXBD_SIG_MGMT_MAGIC 0xbdbdbdbd + +#endif + +#define WDI_RXBD_MLME_STA_STATUS 0x1 +#define WDI_RXBD_SAP_TX_STATS 0x2 +/*-------------------------------------------------------------------------- + BD header macros - used by the data path to get or set various values + inside the packet BD +--------------------------------------------------------------------------*/ +#define WDI_RX_BD_GET_MPDU_H_OFFSET( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduHeaderOffset) + +#define WDI_RX_BD_GET_MPDU_D_OFFSET( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduDataOffset) + +#define WDI_RX_BD_GET_MPDU_LEN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduLength) + +#define WDI_RX_BD_GET_MPDU_H_LEN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mpduHeaderLength) + +#define WDI_RX_BD_GET_FT( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->ft) + +#define WDI_RX_BD_GET_DPU_FEEDBACK( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuFeedback) + +#define WDI_RX_BD_GET_RX_CHANNEL( _pvBDHeader ) \ + (( (((WDI_RxBdType*)_pvBDHeader)->reserved0) << 4) | (((WDI_RxBdType*)_pvBDHeader)->rxChannel)) + +#define WDI_FRAME_TYPE_MASK 0x30 +#define WDI_FRAME_TYPE_OFFSET 0x4 +#define WDI_FRAME_SUBTYPE_MASK 0x0F + +#define WDI_RX_BD_GET_SUBTYPE( _pvBDHeader ) ((((WDI_RxBdType*)_pvBDHeader)->frameTypeSubtype) & WDI_FRAME_SUBTYPE_MASK) + +#define WDI_RX_BD_GET_TYPE( _pvBDHeader ) (((((WDI_RxBdType*)_pvBDHeader)->frameTypeSubtype) & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET) + +#define WDI_RX_BD_GET_RTSF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rtsf) + +#define WDI_RX_BD_GET_BSF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->bsf) + +#define WDI_RX_BD_GET_SCAN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->scanLearn) + +#define WDI_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuSignature) + +#define WDI_RX_BD_GET_NE( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuNE) + +#define WDI_RX_BD_GET_LLCR( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->llcr) + +#define WDI_RX_BD_GET_TIMESTAMP( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->mclkRxTimestamp) + +#define WDI_RX_BD_GET_RXPFLAGS( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rxpFlags) + +#define WDI_RX_BD_GET_RATEINDEX( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rateIndex) + +#define WDI_RX_BD_GET_AMSDU_SIZE( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->totalMsduSize) + +#define WDI_RX_BD_GET_LLC( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->llc) + +#define WDI_RX_BD_GET_TID( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->tid) + +#define WDI_RX_BD_GET_RFBAND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rfBand) + +#define WDI_RX_BD_GET_ASF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->asf) + +#define WDI_RX_BD_GET_AEF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->aef) + +#define WDI_RX_BD_GET_LSF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->lsf) + +#define WDI_RX_BD_GET_ESF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->esf) + +#define WDI_RX_BD_GET_STA_ID( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->addr2Index) +#define WDI_RX_BD_GET_UB( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->ub) +#define WDI_RX_BD_GET_ADDR3_IDX( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->addr3Index) +#define WDI_RX_BD_GET_ADDR1_IDX( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->addr1Index) + +#define WDI_TX_BD_GET_TID( _pvBDHeader ) (((WDI_TxBdType*)_pvBDHeader)->tid) +#define WDI_TX_BD_GET_STA_ID( _pvBDHeader ) (((WDI_TxBdType*)_pvBDHeader)->staIndex) + +#define WDI_RX_BD_GET_DPU_SIG( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->dpuSignature) + +//flow control related. +#define WDI_RX_FC_BD_GET_STA_TX_DISABLED_BITMAP( _pvBDHeader ) (((WDI_FcRxBdType*)_pvBDHeader)->fcStaTxDisabledBitmap) +#define WDI_RX_FC_BD_GET_FC( _pvBDHeader ) (((WDI_FcRxBdType*)_pvBDHeader)->fc) +#define WDI_RX_FC_BD_GET_STA_VALID_MASK( _pvBDHeader ) (((WDI_FcRxBdType*)_pvBDHeader)->fcSTAValidMask) + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +//LFR scan related +#define WDI_RX_BD_GET_OFFLOADSCANLEARN( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->offloadScanLearn) +#define WDI_RX_BD_GET_ROAMCANDIDATEIND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->roamCandidateInd) +#define WDI_RX_BD_GET_PER_ROAMCANDIDATEIND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->perRoamCndInd) +#endif +#ifdef WLAN_FEATURE_EXTSCAN +#define WDI_RX_BD_GET_EXTSCANFULLSCANRESIND( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->extscanBuffer) +#endif + +#define WDI_RX_BD_GET_PER_SAPOFFLOAD( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->indType) + +/*------------ RSSI and SNR Information extraction -------------*/ +#define WDI_RX_BD_GET_RSSI0( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 24) & 0xff) +#define WDI_RX_BD_GET_RSSI1( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 16) & 0xff) +#define WDI_RX_BD_GET_RSSI2( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats0) >> 0) & 0xff) +#define WDI_RX_BD_GET_RSSI3( _pvBDHeader ) \ + ((((WDI_RxBdType*)_pvBDHeader)->phyStats0) & 0xff) + +// Get the average of the 4 values. +#define WDI_GET_RSSI_AVERAGE( _pvBDHeader ) \ + (((WDI_RX_BD_GET_RSSI0(_pvBDHeader)) + \ + (WDI_RX_BD_GET_RSSI1(_pvBDHeader)) + \ + (WDI_RX_BD_GET_RSSI2(_pvBDHeader)) + \ + (WDI_RX_BD_GET_RSSI3(_pvBDHeader))) / 4) + +// Get the SNR value from PHY Stats +#define WDI_RX_BD_GET_SNR( _pvBDHeader ) \ + (((((WDI_RxBdType*)_pvBDHeader)->phyStats1) >> 24) & 0xff) +/*-----------------------------------------------------------------*/ + +#define WDI_TX_BD_SET_MPDU_DATA_OFFSET( _bd, _off ) (((WDI_TxBdType*)_bd)->mpduDataOffset = _off) + +#define WDI_TX_BD_SET_MPDU_HEADER_OFFSET( _bd, _off ) (((WDI_TxBdType*)_bd)->mpduHeaderOffset = _off) + +#define WDI_TX_BD_SET_MPDU_HEADER_LEN( _bd, _len ) (((WDI_TxBdType*)_bd)->mpduHeaderLength = _len) + +#define WDI_TX_BD_GET_MPDU_HEADER_LEN( _bd ) (((WDI_TxBdType*)_bd)->mpduHeaderLength) + + +#define WDI_TX_BD_SET_MPDU_LEN( _bd, _len ) (((WDI_TxBdType*)_bd)->mpduLength = _len) + +#define WDI_RX_BD_GET_BA_OPCODE(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->reorderOpcode) + +#define WDI_RX_BD_GET_BA_FI(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->reorderFwdIdx) + +#define WDI_RX_BD_GET_BA_SI(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->reorderSlotIdx) + +#define WDI_RX_BD_GET_BA_CSN(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->currentPktSeqNo) + +#define WDI_RX_BD_GET_BA_ESN(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->expectedPktSeqNo) + +#define WDI_RX_BD_GET_RXP_FLAGS(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->rxpFlags) + +#define WDI_RX_BD_GET_PMICMD_20TO23(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->pmiCmd4to23[4]) + +#define WDI_RX_BD_GET_PMICMD_24TO25(_pvBDHeader) (((WDI_RxBdType*)_pvBDHeader)->pmiCmd24to25) + +#ifdef WLAN_FEATURE_11W +#define WDI_RX_BD_GET_RMF( _pvBDHeader ) (((WDI_RxBdType*)_pvBDHeader)->rmf) +#endif + +#define WDI_RX_BD_ASF_SET 1 /*The value of the field when set and pkt is AMSDU*/ + +#define WDI_RX_BD_FSF_SET 1 + +#define WDI_RX_BD_LSF_SET 1 + +#define WDI_RX_BD_AEF_SET 1 + + +#define WDI_RX_BD_LLC_PRESENT 0 /*The value of the field when LLC is present*/ + +#define WDI_RX_BD_FT_DONE 1 /* The value of the field when frame xtl was done*/ + +/*========================================================================= + API Definition +=========================================================================*/ + + +/** + @brief WDI_RxBD_GetFrameTypeSubType - Called by the data path + to retrieve the type/subtype of the received frame. + + @param pvBDHeader: Void pointer to the RxBD buffer. + usFrmCtrl: the frame ctrl of the 802.11 header + + @return A byte which contains both type and subtype info. LSB four bytes + (b0 to b3)is subtype and b5-b6 is type info. +*/ + +wpt_uint8 +WDI_RxBD_GetFrameTypeSubType +( + void* _pvBDHeader, + wpt_uint16 usFrmCtrl +); + + +/** + @brief WDI_FillTxBd - Called by the data path to fill the TX BD + + @param pWDICtx: Context to the WDI + ucTypeSubtype: of the frame + pDestMacAddr: destination MAC address + pTid: pointer to the TID (in/out value in case DAL Ctrl causes + a TID downgrade - not done for now) + ucDisableFrmXtl: set to 1 if this frame is not to be translated by HW + pTxBd: pointer to the TX BD + ucTxFlag: can have appropriate bit setting as required + ucProtMgmtFrame: for management frames, whether the frame is + protected (protect bit is set in FC) + uTimestamp: pkt timestamp + + + @return success or not +*/ + +WDI_Status +WDI_FillTxBd +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucTypeSubtype, + void* pDestMacAddr, + void* pAddr2, + wpt_uint8* pTid, + wpt_uint8 ucDisableFrmXtl, + void* pTxBd, + wpt_uint32 ucTxFlag, + wpt_uint8 ucProtMgmtFrame, + wpt_uint32 uTimeStamp, + wpt_uint8 isEapol, + wpt_uint8 isArp, + wpt_uint8* staIndex, + wpt_uint32 txBdToken +); + +/** + @brief WDI_SwapRxBd swaps the RX BD. + + + @param pBd - pointer to the BD (in/out) + + @return None +*/ +void +WDI_SwapRxBd +( + wpt_uint8 *pBd +); + +/** + @brief WDI_SwapTxBd - Swaps the TX BD + + @param pBd - pointer to the BD (in/out) + + @return none +*/ +void +WDI_SwapTxBd +( + wpt_uint8 *pBd +); + +/** + @brief WDI_RxAmsduBdFix - fix for HW issue for AMSDU + + + @param pWDICtx: Context to the WDI + pBDHeader - pointer to the BD header + + @return None +*/ +void +WDI_RxAmsduBdFix +( + WDI_ControlBlockType* pWDICtx, + void* pBDHeader +); + +#ifdef WLAN_PERF +/** + @brief WDI_TxBdFastFwd - evaluates if a frame can be fast + forwarded + + @param pWDICtx: Context to the WDI + pDestMac: Destination MAC + ucTid: packet TID pBDHeader + ucUnicastDst: is packet unicast + pTxBd: pointer to the BD header + usMpduLength: len + + @return 1 - if the frame can be fast fwd-ed ; 0 if not +*/ +wpt_uint32 +WDI_TxBdFastFwd +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pDestMac, + wpt_uint8 ucTid, + wpt_uint8 ucUnicastDst, + void* pTxBd, + wpt_uint16 usMpduLength); +#endif /*WLAN_PERF*/ + +/** + @brief WDI_DP_UtilsInit - Intializes the parameters required to + interact with the data path + + @param pWDICtx: pointer to the main WDI Ctrl Block + + @return success always +*/ +WDI_Status +WDI_DP_UtilsInit +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_DP_UtilsExit - Clears the parameters required to + interact with the data path + + @param pWDICtx: pointer to the main WDI Ctrl Block + + @return success always +*/ +WDI_Status +WDI_DP_UtilsExit +( + WDI_ControlBlockType* pWDICtx +); + +#endif /*WLAN_QCT_WDI_DP_H*/ + diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h new file mode 100644 index 000000000000..5fb24ba07222 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_i.h @@ -0,0 +1,6833 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +#ifndef WLAN_QCT_WDI_I_H +#define WLAN_QCT_WDI_I_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + D A T A P A T H + + +DESCRIPTION + This file contains the internal API exposed by the DAL Control Path Core + module to be used by the DAL Data Path Core. +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +10/05/11 hap Adding support for Keep Alive +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_list.h" +#include "wlan_qct_pal_sync.h" +#include "wlan_qct_pal_timer.h" +#include "wlan_qct_wdi_cts.h" +#include "wlan_qct_wdi_bd.h" + +#include "wlan_hal_msg.h" +#include "wlan_status_code.h" +#include "wlan_qct_dev_defs.h" +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*Assert macro - redefined for WDI so it is more flexible in disabling*/ +#define WDI_ASSERT(_cond) WPAL_ASSERT(_cond) + +/*Error codes that can be returned by WDI - the HAL Error codes are not + propagated outside WDI because they are too explicit when refering to RIVA + HW errors - they are masked under dev internal failure*/ +#define WDI_ERR_BASIC_OP_FAILURE 0 +#define WDI_ERR_TRANSPORT_FAILURE 1 +#define WDI_ERR_INVALID_RSP_FMT 2 +#define WDI_ERR_RSP_TIMEOUT 3 +#define WDI_ERR_DEV_INTERNAL_FAILURE 4 + +/*In prima 12 HW stations are supported including BCAST STA(staId 0) + and SELF STA(staId 1) so total ASSOC stations which can connect to Prima + SoftAP = 12 - 1(Self STa) - 1(Bcast Sta) = 10 Stations. */ + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WDI_MAX_SUPPORTED_STAS 41 +#define WDI_MAX_IBSS_PEER_SUPPORED_STAS 32 +#else +#define WDI_MAX_SUPPORTED_STAS 12 +#define WDI_MAX_IBSS_PEER_SUPPORED_STAS 11 +#endif +#define WDI_MAX_SUPPORTED_BSS 5 + +/* Control transport channel size*/ +#define WDI_CT_CHANNEL_SIZE 4096 + +/*Invalid BSS index ! TO DO: Must come from the HAL header file*/ +#define WDI_BSS_INVALID_IDX 0xFF + +#define WDI_FTM_MAX_RECEIVE_BUFFER 6500 + +/*--------------------------------------------------------------------------- + DAL Control Path Main States +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Transition in this state made upon creation and when a close request is + received*/ + WDI_INIT_ST = 0, + + /* Transition happens after a Start response was received from HAL (as a + result of a previously sent HAL Request)*/ + WDI_STARTED_ST, + + /* Transition happens when a Stop request was received */ + WDI_STOPPED_ST, + + /* Transition happens when a request is being sent down to HAL and we are + waiting for the response */ + WDI_BUSY_ST, + + /* Transition happens when 'SSR' shutdown request is recieved.*/ + WDI_SHUTDOWN_ST, + + WDI_MAX_ST +}WDI_MainStateType; + + +/*--------------------------------------------------------------------------- + DAL Control Path Scan States +---------------------------------------------------------------------------*/ +typedef enum +{ + /*The flag will be set to this state when init is called. Once the flag has + this value the only two scanning API calls allowed are Scan Start and + Scan Finished*/ + WDI_SCAN_INITIALIZED_ST = 0, + + /*The flag will be set to this value once the Start Scan API is called. + When the flag has this value only Scan End API will be allowed. */ + WDI_SCAN_STARTED_ST = 1, + + /*The flag will be set to this value when End Scan API is called. When the + flag is set to this value the only two Scan APIs allowed are Start and + Finish. */ + WDI_SCAN_ENDED_ST = 2, + + /*The flag will be set to this value in the beginning before init is called + and after the Finish API is called. No other scan APIs will be allowed + in this state until Scan Init is called again. */ + WDI_SCAN_FINISHED_ST = 3, + + WDI_SCAN_MAX_ST +}WDI_ScanStateType; + +/*--------------------------------------------------------------------------- + WLAN DAL BSS Session Type - used to allow simulatneous association + and keep track of each associated session + ---------------------------------------------------------------------------*/ +#define WDI_MAX_BSS_SESSIONS 10 + +typedef enum +{ + /*Init state*/ + WDI_ASSOC_INIT_ST, + + /*Joining State*/ + WDI_ASSOC_JOINING_ST, + + /*Associated state*/ + WDI_ASSOC_POST_ST, + + WDI_ASSOC_MAX_ST +}WDI_AssocStateType; + +/*--------------------------------------------------------------------------- + WLAN DAL Supported Request Types + ---------------------------------------------------------------------------*/ +typedef enum +{ + /*WLAN DAL START Request*/ + WDI_START_REQ = 0, + + /*WLAN DAL STOP Request*/ + WDI_STOP_REQ = 1, + + /*WLAN DAL STOP Request*/ + WDI_CLOSE_REQ = 2, + + + /*SCAN*/ + /*WLAN DAL Init Scan Request*/ + WDI_INIT_SCAN_REQ = 3, + + /*WLAN DAL Start Scan Request*/ + WDI_START_SCAN_REQ = 4, + + /*WLAN DAL End Scan Request*/ + WDI_END_SCAN_REQ = 5, + + /*WLAN DAL Finish Scan Request*/ + WDI_FINISH_SCAN_REQ = 6, + + + /*ASSOCIATION*/ + /*WLAN DAL Join Request*/ + WDI_JOIN_REQ = 7, + + /*WLAN DAL Config BSS Request*/ + WDI_CONFIG_BSS_REQ = 8, + + /*WLAN DAL Del BSS Request*/ + WDI_DEL_BSS_REQ = 9, + + /*WLAN DAL Post Assoc Request*/ + WDI_POST_ASSOC_REQ = 10, + + /*WLAN DAL Del STA Request*/ + WDI_DEL_STA_REQ = 11, + + /*Security*/ + /*WLAN DAL Set BSS Key Request*/ + WDI_SET_BSS_KEY_REQ = 12, + + /*WLAN DAL Remove BSS Key Request*/ + WDI_RMV_BSS_KEY_REQ = 13, + + /*WLAN DAL Set STA Key Request*/ + WDI_SET_STA_KEY_REQ = 14, + + /*WLAN DAL Remove STA Key Request*/ + WDI_RMV_STA_KEY_REQ = 15, + + /*QOS and BA*/ + /*WLAN DAL Add TSpec Request*/ + WDI_ADD_TS_REQ = 16, + + /*WLAN DAL Delete TSpec Request*/ + WDI_DEL_TS_REQ = 17, + + /*WLAN DAL Update EDCA Params Request*/ + WDI_UPD_EDCA_PRMS_REQ = 18, + + /*WLAN DAL Add BA Session Request*/ + WDI_ADD_BA_SESSION_REQ = 19, + + /*WLAN DAL Delete BA Request*/ + WDI_DEL_BA_REQ = 20, + + /* Miscellaneous Control */ + /*WLAN DAL Channel Switch Request*/ + WDI_CH_SWITCH_REQ = 21, + + /*WLAN DAL Config STA Request*/ + WDI_CONFIG_STA_REQ = 22, + + /*WLAN DAL Set Link State Request*/ + WDI_SET_LINK_ST_REQ = 23, + + /*WLAN DAL Get Stats Request*/ + WDI_GET_STATS_REQ = 24, + + /*WLAN DAL Update Config Request*/ + WDI_UPDATE_CFG_REQ = 25, + + /* WDI ADD BA Request */ + WDI_ADD_BA_REQ = 26, + + /* WDI Trigger BA Request */ + WDI_TRIGGER_BA_REQ = 27, + + /*WLAN DAL Update Beacon Params Request*/ + WDI_UPD_BCON_PRMS_REQ = 28, + + /*WLAN DAL Send Beacon template Request*/ + WDI_SND_BCON_REQ = 29, + + /*WLAN DAL Send Probe Response Template Request*/ + WDI_UPD_PROBE_RSP_TEMPLATE_REQ = 30, + + /*WLAN DAL Set STA Bcast Key Request*/ + WDI_SET_STA_BCAST_KEY_REQ = 31, + + /*WLAN DAL Remove STA Bcast Key Request*/ + WDI_RMV_STA_BCAST_KEY_REQ = 32, + + /*WLAN DAL Set Max Tx Power Request*/ + WDI_SET_MAX_TX_POWER_REQ = 33, + + /* WLAN DAL P2P GO Notice Of Absence Request */ + WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ = 34, + + /*WLAN DAL Enter IMPS Request*/ + WDI_ENTER_IMPS_REQ = 35, + + /*WLAN DAL Exit IMPS Request*/ + WDI_EXIT_IMPS_REQ = 36, + + /*WLAN DAL Enter BMPS Request*/ + WDI_ENTER_BMPS_REQ = 37, + + /*WLAN DAL Exit BMPS Request*/ + WDI_EXIT_BMPS_REQ = 38, + + /*WLAN DAL Enter UAPSD Request*/ + WDI_ENTER_UAPSD_REQ = 39, + + /*WLAN DAL Exit UAPSD Request*/ + WDI_EXIT_UAPSD_REQ = 40, + + /*WLAN DAL Set UAPSD Param Request*/ + WDI_SET_UAPSD_PARAM_REQ = 41, + + /*WLAN DAL Update UAPSD Param (SoftAP mode) Request*/ + WDI_UPDATE_UAPSD_PARAM_REQ = 42, + + /*WLAN DAL Configure RXP filter Request*/ + WDI_CONFIGURE_RXP_FILTER_REQ = 43, + + /*WLAN DAL Configure Beacon filter Request*/ + WDI_SET_BEACON_FILTER_REQ = 44, + + /*WLAN DAL Remove Beacon filter Request*/ + WDI_REM_BEACON_FILTER_REQ = 45, + + /*WLAN DAL Set RSSI thresholds Request*/ + WDI_SET_RSSI_THRESHOLDS_REQ = 46, + + /*WLAN DAL host offload Request*/ + WDI_HOST_OFFLOAD_REQ = 47, + + /*WLAN DAL add wowl bc ptrn Request*/ + WDI_WOWL_ADD_BC_PTRN_REQ = 48, + + /*WLAN DAL delete wowl bc ptrn Request*/ + WDI_WOWL_DEL_BC_PTRN_REQ = 49, + + /*WLAN DAL enter wowl Request*/ + WDI_WOWL_ENTER_REQ = 50, + + /*WLAN DAL exit wowl Request*/ + WDI_WOWL_EXIT_REQ = 51, + + /*WLAN DAL Configure Apps CPU Wakeup state Request*/ + WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ = 52, + + /* WLAN NV Download Request */ + WDI_NV_DOWNLOAD_REQ = 53, + /*WLAN DAL Flush AC Request*/ + WDI_FLUSH_AC_REQ = 54, + + /*WLAN DAL BT AMP event Request*/ + WDI_BTAMP_EVENT_REQ = 55, + /*WLAN DAL Aggregated Add TSpec Request*/ + WDI_AGGR_ADD_TS_REQ = 56, + + WDI_ADD_STA_SELF_REQ = 57, + + WDI_DEL_STA_SELF_REQ = 58, + + /* WLAN FTM Command request */ + WDI_FTM_CMD_REQ = 59, + + /*WLAN START OEM_DATA MEAS Request*/ + WDI_START_OEM_DATA_REQ = 60, + /* WLAN host resume request */ + WDI_HOST_RESUME_REQ = 61, + + WDI_KEEP_ALIVE_REQ = 62, + + /* Set PNO */ + WDI_SET_PREF_NETWORK_REQ = 63, + + /*RSSI Filter Request*/ + WDI_SET_RSSI_FILTER_REQ = 64, + + /* Update Scan Parameters*/ + WDI_UPDATE_SCAN_PARAMS_REQ = 65, + + WDI_SET_TX_PER_TRACKING_REQ = 66, + + WDI_8023_MULTICAST_LIST_REQ = 67, + WDI_RECEIVE_FILTER_SET_FILTER_REQ = 68, + WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ = 69, + WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ = 70, + + /*This is temp fix. Should be removed once + * Host and Riva code is in sync*/ + WDI_INIT_SCAN_CON_REQ = 71, + + /* WLAN HAL DUMP Command request */ + WDI_HAL_DUMP_CMD_REQ = 72, + + /* WLAN DAL Shutdown Request */ + WDI_SHUTDOWN_REQ = 73, + + /*Set power parameters on the device*/ + WDI_SET_POWER_PARAMS_REQ = 74, + + /* Traffic Stream Metrics statistic request */ + WDI_TSM_STATS_REQ = 75, + /* GTK Rekey Offload */ + WDI_GTK_OFFLOAD_REQ = 76, + WDI_GTK_OFFLOAD_GETINFO_REQ = 77, + + /*Set Thermal Migration level to RIVA*/ + WDI_SET_TM_LEVEL_REQ = 78, + + /* Send a capability exchange message to HAL */ + WDI_FEATURE_CAPS_EXCHANGE_REQ = 79, + +#ifdef WLAN_FEATURE_11AC + /* Send a capability exchange message to HAL */ + WDI_UPDATE_VHT_OP_MODE_REQ = 80, +#endif + + /*WLAN DAL Get Roam Rssi Request*/ + WDI_GET_ROAM_RSSI_REQ = 81, + + /*WLAN DAL Set Tx Power Request*/ + WDI_SET_TX_POWER_REQ = 82, + WDI_ROAM_SCAN_OFFLOAD_REQ = 83, + + WDI_TDLS_LINK_ESTABLISH_REQ = 84, + + /* WLAN FW LPHB config request */ + WDI_LPHB_CFG_REQ = 85, +#ifdef WLAN_FEATURE_RMC + WDI_RMC_RULER_REQ = 86, + WDI_HAL_IBSS_PEER_INFO_REQ = 87, +#endif /* WLAN_FEATURE_RMC */ + + /* WLAN FW set batch scan request */ + WDI_SET_BATCH_SCAN_REQ = 88, + + /*WLAN DAL Set Max Tx Power Per band Request*/ + WDI_SET_MAX_TX_POWER_PER_BAND_REQ = 89, + + WDI_UPDATE_CHAN_REQ = 90, + + WDI_GET_BCN_MISS_RATE_REQ = 91, + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_LL_STATS_SET_REQ = 92, + WDI_LL_STATS_GET_REQ = 93, + WDI_LL_STATS_CLEAR_REQ = 94, +#endif + +#ifdef WLAN_FEATURE_EXTSCAN + WDI_EXTSCAN_START_REQ = 95, + WDI_EXTSCAN_STOP_REQ = 96, + WDI_EXTSCAN_GET_CACHED_RESULTS_REQ = 97, + WDI_EXTSCAN_GET_CAPABILITIES_REQ = 98, + WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ = 99, + WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ = 100, +#endif + + WDI_SPOOF_MAC_ADDR_REQ = 103, + + WDI_GET_FW_STATS_REQ = 104, + + /* Send command to encrypt the given message */ + WDI_ENCRYPT_MSG_REQ = 105, + + WDI_FW_LOGGING_INIT_REQ = 106, + WDI_GET_FRAME_LOG_REQ = 107, + /* NAN Request */ + WDI_NAN_REQUEST = 108, + + WDI_MON_START_REQ = 109, + WDI_MON_STOP_REQ = 110, + WDI_FATAL_EVENT_LOGGING_REQ = 111, + WDI_FWR_MEM_DUMP_REQ = 112, + WDI_START_RSSI_MONITOR_REQ = 113, + WDI_STOP_RSSI_MONITOR_REQ = 114, + WDI_WIFI_CONFIG_SET_REQ = 115, + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WDI_PER_ROAM_SCAN_OFFLOAD_REQ = 116, + WDI_PER_ROAM_SCAN_TRIGGER_REQ = 117, +#endif + + WDI_DHCP_SERVER_OFFLOAD_REQ = 118, + WDI_MDNS_ENABLE_OFFLOAD_REQ = 119, + WDI_MDNS_FQDN_OFFLOAD_REQ = 120, + WDI_MDNS_RESP_OFFLOAD_REQ = 121, + WDI_MDNS_STATS_OFFLOAD_REQ = 122, + + WDI_CAP_TSF_REQ = 123, + WDI_GET_TSF_REQ = 124, + + /* ARP DEBUG STATS */ + WDI_FW_ARP_STATS_REQ = 125, + WDI_FW_GET_ARP_STATS_REQ = 126, + + WDI_MAX_REQ, + + /*Send a suspend Indication down to HAL*/ + WDI_HOST_SUSPEND_IND = WDI_MAX_REQ, + + /* Send a traffic stats indication to HAL */ + WDI_TRAFFIC_STATS_IND = WDI_MAX_REQ + 1, + + /* DHCP Start Indication */ + WDI_DHCP_START_IND = WDI_MAX_REQ + 2, + + /* DHCP Stop Indication */ + WDI_DHCP_STOP_IND = WDI_MAX_REQ + 3, + + /* Drop/Receive unencrypted frames indication to HAL */ + WDI_EXCLUDE_UNENCRYPTED_IND = WDI_MAX_REQ + 4, + + /* Send an add periodic Tx pattern indication to HAL */ + WDI_ADD_PERIODIC_TX_PATTERN_IND = WDI_MAX_REQ + 5, + + /* Send a delete periodic Tx pattern indicationto HAL */ + WDI_DEL_PERIODIC_TX_PATTERN_IND = WDI_MAX_REQ + 6, + +#ifdef WLAN_FEATURE_RMC + /* Send RMC Update Indication */ + WDI_RMC_UPDATE_IND = WDI_MAX_REQ + 7, +#endif + /* Send Rate Update Indication */ + WDI_RATE_UPDATE_IND = WDI_MAX_REQ + 8, + + /*Send stop batch scan indication to FW*/ + WDI_STOP_BATCH_SCAN_IND = WDI_MAX_REQ + 9, + + /*Send stop batch scan indication to FW*/ + WDI_TRIGGER_BATCH_SCAN_RESULT_IND = WDI_MAX_REQ + 10, + +#ifdef WLAN_FEATURE_RMC + /* TX Monitor start/stop indication */ + WDI_TX_FAIL_MONITOR_IND = WDI_MAX_REQ + 11, +#endif + WDI_START_HT40_OBSS_SCAN_IND = WDI_MAX_REQ +12, + WDI_STOP_HT40_OBSS_SCAN_IND = WDI_MAX_REQ +13, + + /* csa channel switch req*/ + WDI_CH_SWITCH_REQ_V1 = WDI_MAX_REQ + 14, + WDI_TDLS_CHAN_SWITCH_REQ = WDI_MAX_REQ + 15, + WDI_SET_RTS_CTS_HTVHT_IND = WDI_MAX_REQ + 16, + WDI_FW_LOGGING_DXE_DONE_IND = WDI_MAX_REQ + 17, + WDI_SEND_FREQ_RANGE_CONTROL_IND = WDI_MAX_REQ + 18, + +#ifdef WLAN_FEATURE_EXTSCAN + WDI_HIGH_PRIORITY_DATA_INFO_IND = WDI_MAX_REQ + 19, +#endif + +#ifdef FEATURE_OEM_DATA_SUPPORT + WDI_START_OEM_DATA_REQ_IND_NEW = WDI_MAX_REQ + 20, +#endif + + /*Keep adding the indications to the max request + such that we keep them separate */ + WDI_ANTENNA_DIVERSITY_SELECTION_REQ = WDI_MAX_REQ + 21, + WDI_MODIFY_ROAM_PARAMS_IND = WDI_MAX_REQ + 22, + WDI_SET_ALLOWED_ACTION_FRAMES_IND = WDI_MAX_REQ + 23, +#ifdef SAP_AUTH_OFFLOAD + WDI_PROCESS_SAP_AUTH_OFFLOAD_IND = WDI_MAX_REQ +24, +#endif + + WDI_SET_AP_FIND_IND = WDI_MAX_REQ + 25, + WDI_MAX_UMAC_IND = WDI_MAX_REQ + 26 + +}WDI_RequestEnumType; + +/*--------------------------------------------------------------------------- + WLAN DAL Supported Response Types + ---------------------------------------------------------------------------*/ +typedef enum +{ + /*WLAN DAL START Response*/ + WDI_START_RESP = 0, + + /*WLAN DAL STOP Response*/ + WDI_STOP_RESP = 1, + + /*WLAN DAL STOP Response*/ + WDI_CLOSE_RESP = 2, + + /*SCAN*/ + /*WLAN DAL Init Scan Response*/ + WDI_INIT_SCAN_RESP = 3, + + /*WLAN DAL Start Scan Response*/ + WDI_START_SCAN_RESP = 4, + + /*WLAN DAL End Scan Response*/ + WDI_END_SCAN_RESP = 5, + + /*WLAN DAL Finish Scan Response*/ + WDI_FINISH_SCAN_RESP = 6, + + + /*ASSOCIATION*/ + /*WLAN DAL Join Response*/ + WDI_JOIN_RESP = 7, + + /*WLAN DAL Config BSS Response*/ + WDI_CONFIG_BSS_RESP = 8, + + /*WLAN DAL Del BSS Response*/ + WDI_DEL_BSS_RESP = 9, + + /*WLAN DAL Post Assoc Response*/ + WDI_POST_ASSOC_RESP = 10, + + /*WLAN DAL Del STA Response*/ + WDI_DEL_STA_RESP = 11, + + /*WLAN DAL Set BSS Key Response*/ + WDI_SET_BSS_KEY_RESP = 12, + + /*WLAN DAL Remove BSS Key Response*/ + WDI_RMV_BSS_KEY_RESP = 13, + + /*WLAN DAL Set STA Key Response*/ + WDI_SET_STA_KEY_RESP = 14, + + /*WLAN DAL Remove STA Key Response*/ + WDI_RMV_STA_KEY_RESP = 15, + + /*WLAN DAL Add TSpec Response*/ + WDI_ADD_TS_RESP = 16, + + /*WLAN DAL Delete TSpec Response*/ + WDI_DEL_TS_RESP = 17, + + /*WLAN DAL Update EDCA Params Response*/ + WDI_UPD_EDCA_PRMS_RESP = 18, + + /*WLAN DAL Add BA Session Response*/ + WDI_ADD_BA_SESSION_RESP = 19, + + /*WLAN DAL Delete BA Response*/ + WDI_DEL_BA_RESP = 20, + + /*WLAN DAL Channel Switch Response*/ + WDI_CH_SWITCH_RESP = 21, + + /*WLAN DAL Config STA Response*/ + WDI_CONFIG_STA_RESP = 22, + + /*WLAN DAL Set Link State Response*/ + WDI_SET_LINK_ST_RESP = 23, + + /*WLAN DAL Get Stats Response*/ + WDI_GET_STATS_RESP = 24, + + /*WLAN DAL Update Config Response*/ + WDI_UPDATE_CFG_RESP = 25, + + /* WDI ADD BA Response */ + WDI_ADD_BA_RESP = 26, + + /* WDI Trigger BA Response */ + WDI_TRIGGER_BA_RESP = 27, + + /*WLAN DAL Update beacon params Response*/ + WDI_UPD_BCON_PRMS_RESP = 28, + + /*WLAN DAL Send beacon template Response*/ + WDI_SND_BCON_RESP = 29, + + /*WLAN DAL Update Probe Response Template Response*/ + WDI_UPD_PROBE_RSP_TEMPLATE_RESP = 30, + + /*WLAN DAL Set STA Key Response*/ + WDI_SET_STA_BCAST_KEY_RESP = 31, + + /*WLAN DAL Remove STA Key Response*/ + WDI_RMV_STA_BCAST_KEY_RESP = 32, + + /*WLAN DAL Set Max Tx Power Response*/ + WDI_SET_MAX_TX_POWER_RESP = 33, + + /*WLAN DAL Enter IMPS Response*/ + WDI_ENTER_IMPS_RESP = 34, + + /*WLAN DAL Exit IMPS Response*/ + WDI_EXIT_IMPS_RESP = 35, + + /*WLAN DAL Enter BMPS Response*/ + WDI_ENTER_BMPS_RESP = 36, + + /*WLAN DAL Exit BMPS Response*/ + WDI_EXIT_BMPS_RESP = 37, + + /*WLAN DAL Enter UAPSD Response*/ + WDI_ENTER_UAPSD_RESP = 38, + + /*WLAN DAL Exit UAPSD Response*/ + WDI_EXIT_UAPSD_RESP = 39, + + /*WLAN DAL Set UAPSD Param Response*/ + WDI_SET_UAPSD_PARAM_RESP = 40, + + /*WLAN DAL Update UAPSD Param (SoftAP mode) Response*/ + WDI_UPDATE_UAPSD_PARAM_RESP = 41, + + /*WLAN DAL Configure RXP filter Response*/ + WDI_CONFIGURE_RXP_FILTER_RESP = 42, + + /*WLAN DAL Set Beacon filter Response*/ + WDI_SET_BEACON_FILTER_RESP = 43, + + /*WLAN DAL Remove Beacon filter Response*/ + WDI_REM_BEACON_FILTER_RESP = 44, + + /*WLAN DAL Set RSSI thresholds Response*/ + WDI_SET_RSSI_THRESHOLDS_RESP = 45, + + /*WLAN DAL Set RSSI thresholds Response*/ + WDI_HOST_OFFLOAD_RESP = 46, + + /*WLAN DAL add wowl bc ptrn Response*/ + WDI_WOWL_ADD_BC_PTRN_RESP = 47, + + /*WLAN DAL delete wowl bc ptrn Response*/ + WDI_WOWL_DEL_BC_PTRN_RESP = 48, + + /*WLAN DAL enter wowl Response*/ + WDI_WOWL_ENTER_RESP = 49, + + /*WLAN DAL exit wowl Response*/ + WDI_WOWL_EXIT_RESP = 50, + + /*WLAN DAL Configure Apps CPU Wakeup state Response*/ + WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP = 51, + + /* WLAN NV Download responce */ + WDI_NV_DOWNLOAD_RESP = 52, + + /*WLAN DAL Flush AC Response*/ + WDI_FLUSH_AC_RESP = 53, + + /*WLAN DAL Flush AC Response*/ + WDI_BTAMP_EVENT_RESP = 54, + + /*WLAN DAL Add Aggregated TSpec Response*/ + WDI_AGGR_ADD_TS_RESP = 55, + + /*Add Self STA Response*/ + WDI_ADD_STA_SELF_RESP = 56, + + /*Delete Self STA Response*/ + WDI_DEL_STA_SELF_RESP = 57, + + /*WLAN START OEM_DATA Response*/ + WDI_START_OEM_DATA_RESP = 58, + + /* WLAN host resume request */ + WDI_HOST_RESUME_RESP = 59, + + /* WLAN DAL P2P GO Notice Of Absence Response */ + WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP = 60, + + /* FTM Response from HAL */ + WDI_FTM_CMD_RESP = 61, + + /*Keep alive response */ + WDI_KEEP_ALIVE_RESP = 62, + + /* Set PNO Response */ + WDI_SET_PREF_NETWORK_RESP = 63, + + /* Set RSSI Filter Response */ + WDI_SET_RSSI_FILTER_RESP = 64, + + /* Update Scan Parameters Resp */ + WDI_UPDATE_SCAN_PARAMS_RESP = 65, + + //Tx PER Tracking + WDI_SET_TX_PER_TRACKING_RESP = 66, + + + + /* Packet Filtering Response */ + WDI_8023_MULTICAST_LIST_RESP = 67, + + WDI_RECEIVE_FILTER_SET_FILTER_RESP = 68, + + WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP = 69, + + WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP = 70, + + + /* WLAN HAL DUMP Command Response */ + WDI_HAL_DUMP_CMD_RESP = 71, + + /* WLAN Shutdown Response */ + WDI_SHUTDOWN_RESP = 72, + + /*Set power parameters response */ + WDI_SET_POWER_PARAMS_RESP = 73, + + WDI_TSM_STATS_RESP = 74, + /* GTK Rekey Offload */ + WDI_GTK_OFFLOAD_RESP = 75, + WDI_GTK_OFFLOAD_GETINFO_RESP = 76, + + WDI_SET_TM_LEVEL_RESP = 77, + + /* FW sends its capability bitmap as a response */ + WDI_FEATURE_CAPS_EXCHANGE_RESP = 78, + +#ifdef WLAN_FEATURE_11AC + WDI_UPDATE_VHT_OP_MODE_RESP = 79, +#endif + + /* WLAN DAL Get Roam Rssi Response*/ + WDI_GET_ROAM_RSSI_RESP = 80, + + WDI_SET_TX_POWER_RESP = 81, + WDI_ROAM_SCAN_OFFLOAD_RESP = 82, + + WDI_TDLS_LINK_ESTABLISH_REQ_RESP = 83, + + /* WLAN FW LPHB Config response */ + WDI_LPHB_CFG_RESP = 84, + +#ifdef WLAN_FEATURE_RMC + WDI_RMC_RULER_RESP = 85, + WDI_HAL_IBSS_PEER_INFO_RSP = 86, +#endif /* WLAN_FEATURE_RMC */ + + WDI_SET_BATCH_SCAN_RESP = 87, + + WDI_SET_MAX_TX_POWER_PER_BAND_RSP = 88, + + WDI_UPDATE_CHAN_RESP = 89, + /* channel switch resp v1*/ + WDI_CH_SWITCH_RESP_V1 = 90, + + WDI_GET_BCN_MISS_RATE_RSP = 91, +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_LL_STATS_SET_RSP = 92, + WDI_LL_STATS_GET_RSP = 93, + WDI_LL_STATS_CLEAR_RSP = 94, +#endif + +#ifdef WLAN_FEATURE_EXTSCAN + WDI_EXTSCAN_START_RSP = 95, + WDI_EXTSCAN_STOP_RSP = 96, + WDI_EXTSCAN_GET_CACHED_RESULTS_RSP = 97, + WDI_EXTSCAN_GET_CAPABILITIES_RSP = 98, + WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP = 99, + WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP = 100, +#endif + WDI_SPOOF_MAC_ADDR_RSP = 103, + WDI_GET_FW_STATS_RSP = 104, + + /* Send command to encrypt the given message */ + WDI_ENCRYPT_MSG_RSP = 105, + + WDI_FW_LOGGING_INIT_RSP = 106, + WDI_GET_FRAME_LOG_RSP = 107, + + WDI_NAN_RESPONSE = 108, + + WDI_MON_START_RSP = 109, + WDI_MON_STOP_RSP = 110, + WDI_FATAL_EVENT_LOGGING_RSP = 111, + WDI_FWR_MEM_DUMP_RSP = 112, + WDI_START_RSSI_MONITOR_RSP = 113, + WDI_STOP_RSSI_MONITOR_RSP = 114, + + WDI_WIFI_CONFIG_SET_RSP = 115, +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WDI_PER_ROAM_SCAN_OFFLOAD_RSP = 116, + WDI_PER_ROAM_SCAN_TRIGGER_RSP = 117, +#endif + WDI_DHCP_SERVER_OFFLOAD_RSP = 118, + WDI_MDNS_ENABLE_OFFLOAD_RSP = 119, + WDI_MDNS_FQDN_OFFLOAD_RSP = 120, + WDI_MDNS_RESP_OFFLOAD_RSP = 121, + WDI_MDNS_STATS_OFFLOAD_RSP = 122, + WDI_CAPTURE_GET_TSF_TSTAMP_RSP = 123, + WDI_FW_ARP_STATS_RSP = 124, + WDI_FW_GET_ARP_STATS_RSP = 125, + + + /*------------------------------------------------------------------------- + Indications + !! Keep these last in the enum if possible + -------------------------------------------------------------------------*/ + WDI_HAL_IND_MIN , + /*When RSSI monitoring is enabled of the Lower MAC and a threshold has been + passed. */ + WDI_HAL_RSSI_NOTIFICATION_IND = WDI_HAL_IND_MIN, + + /*Link loss in the low MAC */ + WDI_HAL_MISSED_BEACON_IND = WDI_HAL_IND_MIN + 1, + + /*When hardware has signaled an unknown addr2 frames. The indication will + contain info from frames to be passed to the UMAC, this may use this info to + deauth the STA*/ + WDI_HAL_UNKNOWN_ADDR2_FRAME_RX_IND = WDI_HAL_IND_MIN + 2, + + /*MIC Failure detected by HW*/ + WDI_HAL_MIC_FAILURE_IND = WDI_HAL_IND_MIN + 3, + + /*Fatal Error Ind*/ + WDI_HAL_FATAL_ERROR_IND = WDI_HAL_IND_MIN + 4, + + /*Received when the RIVA SW decides to autonomously delete an associate + station (e.g. Soft AP TIM based dissassoc) */ + WDI_HAL_DEL_STA_IND = WDI_HAL_IND_MIN + 5, + + /*Coex indication*/ + WDI_HAL_COEX_IND = WDI_HAL_IND_MIN + 6, + + /* Tx Complete Indication */ + WDI_HAL_TX_COMPLETE_IND = WDI_HAL_IND_MIN + 7, + + WDI_HAL_P2P_NOA_ATTR_IND = WDI_HAL_IND_MIN + 8, + + /* Preferred Network Found Indication */ + WDI_HAL_PREF_NETWORK_FOUND_IND = WDI_HAL_IND_MIN + 9, + + /* Wakeup Reason Indication */ + WDI_HAL_WAKE_REASON_IND = WDI_HAL_IND_MIN + 10, + + /* Tx PER Hit Indication */ + WDI_HAL_TX_PER_HIT_IND = WDI_HAL_IND_MIN + 11, + + /* NOA Start Indication from FW to Host */ + WDI_HAL_P2P_NOA_START_IND = WDI_HAL_IND_MIN + 12, + + /* TDLS Indication from FW to Host */ + WDI_HAL_TDLS_IND = WDI_HAL_IND_MIN + 13, + + /* LPHB timeout indication */ + WDI_HAL_LPHB_IND = WDI_HAL_IND_MIN + 14, + + /* IBSS Peer Inactivity Indication from FW to Host */ + WDI_HAL_IBSS_PEER_INACTIVITY_IND = WDI_HAL_IND_MIN + 15, + + /* Periodic Tx Pattern Indication from FW to Host */ + WDI_HAL_PERIODIC_TX_PTRN_FW_IND = WDI_HAL_IND_MIN + 16, + +#ifdef WLAN_FEATURE_RMC + /* Update Indication from FW to Host */ + WDI_RMC_UPDATE_IND_TO_HOST = WDI_HAL_IND_MIN + 17, +#endif + + WDI_BATCHSCAN_RESULT_IND = WDI_HAL_IND_MIN + 18, + +#ifdef WLAN_FEATURE_RMC + WDI_HAL_TX_FAIL_IND = WDI_HAL_IND_MIN + 19, +#endif + + WDI_HAL_CH_AVOID_IND = WDI_HAL_IND_MIN + 20, + + /* print register values indication from FW to Host */ + WDI_PRINT_REG_INFO_IND = WDI_HAL_IND_MIN + 21, +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_HAL_LL_STATS_RESULTS_IND = WDI_HAL_IND_MIN + 22, +#endif +#ifdef WLAN_FEATURE_EXTSCAN + WDI_HAL_EXTSCAN_PROGRESS_IND = WDI_HAL_IND_MIN + 23, + WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND = WDI_HAL_IND_MIN + 24, + WDI_HAL_EXTSCAN_RESULT_IND = WDI_HAL_IND_MIN + 25, + WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND = WDI_HAL_IND_MIN + 26, +#endif + WDI_TDLS_CHAN_SWITCH_REQ_RESP = WDI_HAL_IND_MIN + 28, + WDI_HAL_DEL_BA_IND = WDI_HAL_IND_MIN + 29, + WDI_HAL_NAN_EVENT = WDI_HAL_IND_MIN + 30, + WDI_HAL_LOST_LINK_PARAMS_IND = WDI_HAL_IND_MIN + 31, + WDI_HAL_RSSI_BREACHED_IND = WDI_HAL_IND_MIN + 32, + WDI_HAL_START_OEM_DATA_RSP_IND_NEW = WDI_HAL_IND_MIN + 33, + WDI_ANTENNA_DIVERSITY_SELECTION_RSP = WDI_HAL_IND_MIN + 34, +#ifdef WLAN_FEATURE_APFIND + WDI_HAL_QRF_PREF_NETWORK_FOUND_IND = WDI_HAL_IND_MIN + 35, +#endif + WDI_MAX_RESP +}WDI_ResponseEnumType; + +typedef struct +{ + /*Flag that marks a session as being in use*/ + wpt_boolean bInUse; + + /*Flag that keeps track if a series of assoc requests for this BSS are + currently pending in the queue or processed + - the flag is set to true when the Join request ends up being queued + - and reset to false when the Pending queue is empty */ + wpt_boolean bAssocReqQueued; + + /*BSSID of the session*/ + wpt_macAddr macBSSID; + + /*BSS Index associated with this BSSID*/ + wpt_uint8 ucBSSIdx; + + /*Associated state of the current BSS*/ + WDI_AssocStateType wdiAssocState; + + /*WDI Pending Request Queue*/ + wpt_list wptPendingQueue; + + /*DPU Information for this BSS*/ + wpt_uint8 bcastDpuIndex; + wpt_uint8 bcastDpuSignature; + wpt_uint8 bcastMgmtDpuIndex; + wpt_uint8 bcastMgmtDpuSignature; + + /*RMF enabled/disabled*/ + wpt_uint8 ucRmfEnabled; + + /*Bcast STA ID associated with this BSS session */ + wpt_uint8 bcastStaIdx; + + /*The type of the BSS in the session */ + WDI_BssType wdiBssType; +}WDI_BSSSessionType; + +/*--------------------------------------------------------------------------- + WDI_ConfigBSSRspInfoType +---------------------------------------------------------------------------*/ +typedef WPT_PACK_PRE struct +{ + /*BSS index allocated by HAL*/ + wpt_uint8 ucBSSIdx; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*Broadcast DPU descriptor index allocated by HAL and used for + broadcast/multicast packets.*/ + wpt_uint8 ucBcastDpuDescIndx; + + /*DPU signature to be used for broadcast/multicast packets*/ + wpt_uint8 ucBcastDpuSignature; + + /*DPU descriptor index allocated by HAL, used for bcast/mcast management + packets*/ + wpt_uint8 ucMgmtDpuDescIndx; + + /*DPU signature to be used for bcast/mcast management packets*/ + wpt_uint8 ucMgmtDpuSignature; + + /*Status of the request received from HAL */ + eHalStatus halStatus; +}WPT_PACK_POST WDI_ConfigBSSRspInfoType; + + +/*--------------------------------------------------------------------------- + WDI_PostAssocRspInfoType +---------------------------------------------------------------------------*/ +typedef WPT_PACK_PRE struct +{ + /*STA Index allocated by HAL.*/ + wpt_uint16 usSTAIdx; + + /*MAC Address of STA*/ + wpt_macAddr macSTA; + + /*Unicast DPU signature*/ + wpt_uint8 ucUcastSig; + + /*Broadcast DPU Signature*/ + wpt_uint8 ucBcastSig; + + /*BSSID of the BSS*/ + wpt_macAddr macBSSID; + + /*HAL Status */ + eHalStatus halStatus; +}WPT_PACK_POST WDI_PostAssocRspInfoType; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/*--------------------------------------------------------------------------- + WDI_LLStatsResultsType +---------------------------------------------------------------------------*/ +typedef WPT_PACK_PRE struct +{ + wpt_uint32 param_id; + wpt_uint8 iface_id; + wpt_uint32 resp_id; + wpt_uint32 more_result_to_follow; + wpt_uint8 result[1]; +}WPT_PACK_POST WDI_LLstatsResultsType; + +#endif + +/*--------------------------------------------------------------------------- + WLAN DAL FSM Event Info Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*Events can be linked in a list - put a node in front for that, it will be + used by wpt to link them*/ + wpt_list_node wptListNode; + + /*Request Received */ + WDI_RequestEnumType wdiRequest; + + /*Response Received */ + WDI_ResponseEnumType wdiResponse; + + /*Data associated with the request */ + void* pEventData; + + /*Data Size*/ + wpt_uint32 uEventDataSize; + + /*Callback function for receiving the response to the event*/ + void* pCBfnc; + + /*User data to be sent along with the CB function call*/ + void* pUserData; +}WDI_EventInfoType; + +/*--------------------------------------------------------------------------- + WLAN DAL Session Index Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*Events can be linked in a list - put a node in front for that, it will be + used by wpt to link them*/ + wpt_list_node wptListNode; + + /*Session id for the new association to be processed*/ + wpt_uint8 ucIndex; + +}WDI_NextSessionIdType; + +#define WDI_CONTROL_BLOCK_MAGIC 0x67736887 /* WDIC in little endian */ +/*--------------------------------------------------------------------------- + WLAN DAL Control Block Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*magic number so callbacks can validate their context pointers*/ + wpt_uint32 magic; + + /*Ptr to the OS Context received from the UMAC*/ + void* pOSContext; + + /*Ptr to the PAL Context received from PAL*/ + void* pPALContext; + + /*Ptr to the Datapath Context received from PAL*/ + void* pDPContext; + + /*Ptr to the Datapath Transport Driver Context received from PAL*/ + void* pDTDriverContext; + + /*Hanlde to the control transport service*/ + WCTS_HandleType wctsHandle; + + /*Flag that keeps track if CT is Opened or not*/ + wpt_boolean bCTOpened; + + /*The global state of the DAL Control Path*/ + WDI_MainStateType uGlobalState; + + /*Flag to keep track of the expected state transition after processing + of a response */ + WDI_MainStateType ucExpectedStateTransition; + + /*Main Synchronization Object for the WDI CB*/ + wpt_mutex wptMutex; + + /*WDI response timer*/ + wpt_timer wptResponseTimer; + + /*WDI Pending Request Queue*/ + wpt_list wptPendingQueue; +#if 0 + /*The state of the DAL during a scanning procedure*/ + WDI_ScanStateType uScanState; + + /*Flag that keeps track if a Scan is currently in progress*/ + wpt_boolean bScanInProgress; +#endif + /*Flag that keeps track if an Association is currently in progress*/ + wpt_boolean bAssociationInProgress; + + /*Array of simultaneous BSS Sessions*/ + WDI_BSSSessionType aBSSSessions[WDI_MAX_BSS_SESSIONS]; + + /*WDI Pending Association Session Id Queue - it keeps track of the + order in which queued assoc requests came in*/ + wpt_list wptPendingAssocSessionIdQueue; + + /*! TO DO : - group these in a union, only one cached req can exist at a + time */ + + /*Cached post assoc request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save a station if needed */ + WDI_PostAssocReqParamsType wdiCachedPostAssocReq; + + /*Cached config sta request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save a station if needed */ + WDI_ConfigSTAReqParamsType wdiCachedConfigStaReq; + + /*Cached config sta request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save a BSS if needed */ + WDI_ConfigBSSReqParamsType wdiCachedConfigBssReq; + + /*Cached set link state request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to delete a BSS if needed */ + WDI_SetLinkReqParamsType wdiCacheSetLinkStReq; + + /*Cached add STA self request - there can only be one in the system as + only one request goes down to hal up until a response is received + The values cached are used on response to save the self STA in the table */ + WDI_AddSTASelfReqParamsType wdiCacheAddSTASelfReq; + + /*Current session being handled*/ + wpt_uint8 ucCurrentBSSSesIdx; + + /*Pointer to the response CB of the pending request*/ + void* pfncRspCB; + + /*Pointer to the user data to be sent along with the response CB*/ + void* pRspCBUserData; + + /*The expected response from HAL*/ + WDI_ResponseEnumType wdiExpectedResponse; + + /*Request status callback offered by UMAC - it is called if the current + req has returned PENDING as status; it delivers the status of sending + the message over the BUS */ + WDI_ReqStatusCb wdiReqStatusCB; + + /*The user data passed in by UMAC, it will be sent back when the above + function pointer will be called */ + void* pReqStatusUserData; + + /*Indication callback given by UMAC to be called by the WLAN DAL when it + wishes to send something back independent of a request*/ + WDI_LowLevelIndCBType wdiLowLevelIndCB; + + /*The user data passed in by UMAC, it will be sent back when the indication + function pointer will be called */ + void* pIndUserData; + + /*Cached start response parameters*/ + WDI_StartRspParamsType wdiCachedStartRspParams; + + /* Information related to NV Image*/ + WDI_NvBlobInfoParams wdiNvBlobInfo; + + /*STA Table Information*/ + /*Max number of stations allowed by device */ + wpt_uint8 ucMaxStations; + + /*Max number of BSSes allowed by device */ + wpt_uint8 ucMaxBssids; + + /* Global BSS and STA table - Memory is allocated when needed.*/ + void* staTable; + +#ifndef HAL_SELF_STA_PER_BSS + /*Index of the Self STA */ + wpt_uint8 ucSelfStaId; + + /* Self STA DPU Index */ + wpt_uint16 usSelfStaDpuId; + + /*Self STA Mac*/ + wpt_macAddr macSelfSta; +#endif + + /*Is frame translation enabled */ + wpt_uint8 bFrameTransEnabled; + + /*AMSDU BD Fix Mask - used by the Fixing routine for Data Path */ + WDI_RxBdType wdiRxAmsduBdFixMask; + + /*First AMSDU BD - used by the Fixing routine for Data Path */ + WDI_RxBdType wdiRxAmsduFirstBdCache; + + /*This must be incremented on sta change */ + wpt_uint32 uBdSigSerialNum; + + /* dpu routing flag + ! TO DO: - must be set/reset when PS is enabled for UAPSD */ + wpt_uint8 ucDpuRF; + /* Event to wait for when WCTS is told to perform an action */ + wpt_event wctsActionEvent; + /* Event to wait for ACK from DXE after the power state is set */ + wpt_event setPowerStateEvent; + /* DXE physical addr to be passed down to RIVA. RIVA HAL will use it to program + DXE when DXE wakes up from power save*/ + unsigned int dxePhyAddr; + + wpt_boolean dxeRingsEmpty; + + /*NV download request parameters */ + WDI_NvDownloadReqParamsType wdiCachedNvDownloadReq; + + /* Driver Type */ + tDriverType driverMode; + + /* Statically allocated FTM Response Buffer */ + wpt_uint8 ucFTMCommandRspBuffer[WDI_FTM_MAX_RECEIVE_BUFFER]; + + /*Driver in BMPS state*/ + wpt_boolean bInBmps; + + /*version of the PNO implementation in RIVA*/ + wpt_uint8 wdiPNOVersion; + + /*SSR timer*/ + wpt_timer ssrTimer; + + /*Version of the WLAN HAL API received on start resp*/ + WDI_WlanVersionType wlanVersion; + + /*timestamp when we start response timer*/ + wpt_uint32 uTimeStampRspTmrStart; + + /*timestamp when we get response timer event*/ + wpt_uint32 uTimeStampRspTmrExp; + + /* enable/disable SSR on WDI timeout */ + wpt_boolean bEnableSSR; + + /* timestamp derived from msm arch counter. */ + /*timestamp when we start response timer*/ + wpt_uint64 uArchTimeStampRspTmrStart; + + /*timestamp when we get response timer event*/ + wpt_uint64 uArchTimeStampRspTmrExp; + + /* reason for WDI_DetectedDeviceError */ + void * DeviceErrorReason; + + /* Roam delay statistic enabled in ini*/ + wpt_uint8 roamDelayStatsEnabled; + /* enable/disable sendMgmtPktViaWQ5 params in ini */ + wpt_boolean sendMgmtPktViaWQ5; + /* Wake lock for keep device in awake once host gets a find AP indication */ + vos_wake_lock_t find_ap_lock; + +}WDI_ControlBlockType; + + + + +/*--------------------------------------------------------------------------- + + DESCRIPTION + WLAN DAL Request Processing function definition. + + PARAMETERS + + IN + pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef WDI_Status (*WDI_ReqProcFuncType)( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData); + + +/*--------------------------------------------------------------------------- + + DESCRIPTION + WLAN DAL Response Processing function definition. + + PARAMETERS + + IN + pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef WDI_Status (*WDI_RspProcFuncType)( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData); + + + + +/*========================================================================== + MAIN DAL FSM Definitions and Declarations +==========================================================================*/ + +/*--------------------------------------------------------------------------- + DAL Control Path Main FSM + ---------------------------------------------------------------------------*/ +#define WDI_STATE_TRANSITION(_pctx, _st) (_pctx->uGlobalState = _st) + + + +/*--------------------------------------------------------------------------- + DAL Main Event type +---------------------------------------------------------------------------*/ +typedef enum +{ + /* Start request received from UMAC */ + WDI_START_EVENT = 0, + + /* Stop request received from UMAC */ + WDI_STOP_EVENT = 1, + + /* HAL request received from UMAC*/ + WDI_REQUEST_EVENT = 2, + + /* HAL Response received from device */ + WDI_RESPONSE_EVENT = 3, + + /* Close request received from UMAC */ + WDI_CLOSE_EVENT = 4, + + /* Shutdown request received from UMAC */ + WDI_SHUTDOWN_EVENT = 5, + + WDI_MAX_EVENT + +}WDI_MainEventType; + +/*--------------------------------------------------------------------------- + + DESCRIPTION + Main DAL state machine function definition. + + PARAMETERS + + IN + pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + RETURN VALUE + The result code associated with performing the operation + +---------------------------------------------------------------------------*/ +typedef WDI_Status (*WDI_MainFuncType)( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData); + +/*--------------------------------------------------------------------------- + MAIN DAL FSM Entry type +---------------------------------------------------------------------------*/ +typedef struct +{ + WDI_MainFuncType pfnMainTbl[WDI_MAX_EVENT]; +} WDI_MainFsmEntryType; + +/*Macro to check for valid session id*/ +#define WDI_VALID_SESSION_IDX(_idx) ( _idx < WDI_MAX_BSS_SESSIONS ) + +/*========================================================================== + + DAL INTERNAL FUNCTION DECLARATION + +==========================================================================*/ + +/** + @brief Helper routine for retrieving the PAL Context from WDI - + can be used by CTS, DTS, DXE and othe DAL internals + + @param None + + @see + @return pointer to the context +*/ +void* WDI_GET_PAL_CTX( void ); + +/*--------------------------------------------------------------------------- + MAIN DAL FSM Function Declarations +---------------------------------------------------------------------------*/ +/** + @brief WDI_PostMainEvent - Posts an event to the Main FSM + + + @param pWDICtx: pointer to the WLAN DAL context + wdiEV: event posted to the main DAL FSM + pEventData: pointer to the event information + structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_PostMainEvent +( + WDI_ControlBlockType* pWDICtx, + WDI_MainEventType wdiEV, + WDI_EventInfoType* pEventData + +); + +/*-------------------------------------------------------------------------- + INIT State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStart +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Response function for state INIT + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainRspInit +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Close function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainClose +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*-------------------------------------------------------------------------- + STARTED State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for state STARTED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStartStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Stop function for state STARTED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + uEventDataSize: size of the data sent in event + pCBfnc: cb function for event response + pUserData: user data + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Request function for state started + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainReqStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Response function for all states except INIT + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*-------------------------------------------------------------------------- + STOPPED State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Stop function for state STOPPED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopStopped +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); + +/*-------------------------------------------------------------------------- + BUSY State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStartBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Stop function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Request function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainReqBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Close function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainCloseBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Shutdown function for INIT & STARTED states + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainShutdown +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Main FSM Shutdown function for BUSY state + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainShutdownBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*======================================================================== + Main DAL Control Path Request Processing API +========================================================================*/ + +/** + @brief Process Start Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Stop Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Close Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCloseReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Shutdown Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessShutdownReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Init Scan Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessInitScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Start Scan Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process End Scan Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEndScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Finish Scan Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFinishScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Join Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessJoinReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Config BSS Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigBSSReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del BSS Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBSSReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Post Assoc Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPostAssocReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del STA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set BSS Key Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBssKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove BSS Key Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveBssKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set STA KeyRequest function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Key Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set STA KeyRequest function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaBcastKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Key Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaBcastKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update EDCA Params Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateEDCAParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBASessionReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_ESE +/** + @brief Process TSM Stats Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTSMStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Channel Switch Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Channel Switch Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ + +WDI_Status WDI_ProcessChannelSwitchReq_V1 +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Config STA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigStaReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set Link State Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetLinkStateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Get Stats Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief Process Get Roam rssi Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetRoamRssiReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Get Roam Rssi Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetRoamRssiRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif + + +/** + @brief Process Update Cfg Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateCfgReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Trigger BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon Params Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateBeaconParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon template Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSendBeaconParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon Params Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateProbeRspTemplateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief Process NV blob download function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNvDownloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Max Tx Power Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetMaxTxPowerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Max Tx Power Per Band Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetMaxTxPowerPerBandReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Tx Power Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetTxPowerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process P2P Notice Of Absence Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2PGONOAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process TDLS Link Establish Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsLinkEstablishReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process tdls channel switch request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsChanSwitchReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief Process Enter IMPS Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterImpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit IMPS Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitImpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter BMPS Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterBmpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit BMPS Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitBmpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter UAPSD Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterUapsdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit UAPSD Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitUapsdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set UAPSD params Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetUapsdAcParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process update UAPSD params Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateUapsdParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure RXP filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureRxpFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set beacon filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBeaconFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process remove beacon filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemBeaconFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set RSSI thresholds Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRSSIThresholdsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set RSSI thresholds Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Keep Alive Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessKeepAliveReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Wowl add bc ptrn Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlAddBcPtrnReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Wowl delete bc ptrn Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlDelBcPtrnReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Wowl enter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlEnterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Wowl exit Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlExitReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure Apps Cpu Wakeup State Request function + (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureAppsCpuWakeupStateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Flush AC Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFlushAcReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief Process Start Oem Data Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Host Resume Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostResumeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process BT AMP event Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBtAmpEventReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add STA self Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddSTASelfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del Sta Self Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTASelfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set Tx Per Tracking configurations Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPerTrackingReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Power Params Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPowerParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Thermal Mitigation level Changed request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTmLevelReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLPHBConfReq - + LPHB configuration request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return esult of the function call +*/ +WDI_Status WDI_ProcessLPHBConfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_LPHB */ + +/** + @brief WDI_ProcessUpdateChannelParamsReq - + Send update channel request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return success or failure +*/ +WDI_Status WDI_ProcessUpdateChannelParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief WDI_ProcessSetBatchScanReq - + Send set batch scan configuration request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return success or failure +*/ +WDI_Status WDI_ProcessSetBatchScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessGetBatchScanReq - + Send get batch scan request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return success or failure +*/ +WDI_Status WDI_ProcessGetBatchScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_BATCH_SCAN */ + + +/*========================================================================= + Indications +=========================================================================*/ + +/** + @brief Process Suspend Indications function (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostSuspendInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief DHCP Start Event Indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDHCPStartInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief DHCP Stop Event Indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDHCPStopInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Traffic Stats Indications function (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTrafficStatsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_11W +/** + @brief Process Exclude Unencrypted Indications function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExcludeUnencryptInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Add Periodic Tx Pattern Indication function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddPeriodicTxPtrnInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Delete Periodic Tx Pattern Indication function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelPeriodicTxPtrnInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief Process stop batch scan indications function + It is called when Main FSM allows it + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call + */ + WDI_Status + WDI_ProcessStopBatchScanInd + ( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); + +/** + @brief This API is called to trigger batch scan results from FW + It is called when Main FSM allows it + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call + */ + WDI_Status + WDI_ProcessTriggerBatchScanResultInd + ( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); + +#endif +#ifdef WLAN_FEATURE_RMC +/** + @brief Process TX Fail monitor indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTXFailMonitor +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* WLAN_FEATURE_RMC */ +/** + @brief Process start OBSS scan request from Host + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHT40OBSSScanInd( + WDI_ControlBlockType* pWDICtx, WDI_EventInfoType* pEventData ); + + +/** + @brief Process stop OBSS scan request from Host + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHT40OBSSStopScanInd( + WDI_ControlBlockType* pWDICtx, WDI_EventInfoType* pEventData ); + +/*======================================================================== + Main DAL Control Path Response Processing API +========================================================================*/ + + +/** + @brief Process Start Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Stop Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Close Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCloseRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Shutdown Rsp function + There is no shutdown response comming from HAL + - function just kept for simmetry + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessShutdownRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Init Scan Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessInitScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Start Scan Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process End Scan Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEndScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Finish Scan Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFinishScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Join Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessJoinRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Config BSS Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigBSSRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del BSS Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBSSRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Post Assoc Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPostAssocRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Del STA Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set BSS Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBssKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove BSS Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveBssKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set STA Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set STA Bcast Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaBcastKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Remove STA Bcast Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaBcastKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update EDCA Parameters Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateEDCAParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBASessionRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Del BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_ESE +/** + @brief Process TSM stats Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTsmStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif + + +/** + @brief Process Channel Switch Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Channel Switch Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchRsp_V1 +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Config STA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigStaRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Set Link State Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetLinkStateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Channel Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateChanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Get Stats Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Update Cfg Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateCfgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Beacon Params Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateBeaconParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Send Beacon template Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSendBeaconParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Probe Resp Template Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateProbeRspTemplateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + /** + @brief Process Set Max Tx Power Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetMaxTxPowerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set Max Tx Power Per Band Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetMaxTxPowerPerBandRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + /** + @brief Process Set Tx Power Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPowerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + /** + @brief Process TDLS Link Establish Req Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLinkEstablishReqRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + + /** + @brief Process TDLS Chan Switch Req Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChanSwitchReqRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Nv download(called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNvDownloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process P2P Group Owner Notice Of Absense Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2PGONOARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter IMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterImpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit IMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitImpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter BMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterBmpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit BMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitBmpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Enter UAPSD Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterUapsdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Exit UAPSD Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitUapsdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set UAPSD params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetUapsdAcParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process update UAPSD params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateUapsdParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure RXP filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureRxpFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set beacon filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBeaconFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process remove beacon filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemBeaconFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set RSSI thresholds Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRSSIThresoldsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process host offload Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Keep Alive Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessKeepAliveRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process wowl add ptrn Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlAddBcPtrnRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process wowl delete ptrn Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlDelBcPtrnRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process wowl enter Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlEnterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process wowl exit Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlExitRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Configure Apps CPU wakeup State Rsp function + (called when a response is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureAppsCpuWakeupStateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief Process Flush AC Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFlushAcRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process BT AMP event Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBtAmpEventRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process ADD SELF STA Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddSTASelfRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + /** + @brief WDI_ProcessDelSTASelfRsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTASelfRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief Start Oem Data Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + + /** + @brief WDI_ProcessHostResumeRsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostResumeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set tx per tracking Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPerTrackingRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Power Params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPowerParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set TM Level Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTmLevelRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/*========================================================================== + Indications from HAL + ==========================================================================*/ +/** + @brief Process Low RSSI Indication function (called when an + indication of this kind is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLowRSSIInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Missed Beacon Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessMissedBeaconInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process Unk Addr Frame Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUnkAddrFrameInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief Process MIC Failure Indication function (called when an + indication of this kind is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessMicFailureInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Fatal Failure Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFatalErrorInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Delete STA Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTAInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Coex Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCoexInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Tx Complete Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTxCompleteInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Tdls Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_RMC +/** +*@brief Process Tx Fail Indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTXFailInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* WLAN_FEATURE_RMC */ + +/** +*@brief Process Noa Start Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2pNoaStartInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Noa Attr Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2pNoaAttrInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process Tx Per Hit Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTxPerHitInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLphbInd - + This function will be invoked when FW detects low power + heart beat failure + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLphbInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_LPHB */ + +/** + @brief Process Periodic Tx Pattern Fw Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPeriodicTxPtrnFwInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief Process Aggrgated Add TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAggrAddTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Add TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAggrAddTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + @brief WDI_ProcessFTMCommandReq + Process FTM Command, simply route to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFTMCommandReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessFTMCommandRsp + Process FTM Command Response from HAL, simply route to HDD FTM + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFTMCommandRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +/** + @brief WDI_ProcessHALDumpCmdReq + Process Hal Dump Command, simply route to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHALDumpCmdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessHALDumpCmdRsp + Process Hal Dump Command Response from HAL, simply route to HDD FTM + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHALDumpCmdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief WDI_ProcessIbssPeerInactivityInd + Process peer inactivity indication coming from HAL. + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInactivityInd + +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/*======================================================================== + Internal Helper Routines +========================================================================*/ + +/** + @brief WDI_CleanCB - internal helper routine used to clean the + WDI Main Control Block + + @param pWDICtx - pointer to the control block + + @return Result of the function call +*/ +WDI_Status +WDI_CleanCB +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Main FSM Close function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Get message helper function - it allocates memory for a + message that is to be sent to HAL accross the bus and + prefixes it with a send message header + + @param pWDICtx: pointer to the WLAN DAL context + wdiReqType: type of the request being sent + uBufferLen: message buffer len + pMsgBuffer: resulting allocated buffer + puDataOffset: offset in the buffer where the caller + can start copying its message data + puBufferSize: the resulting buffer size (offset+buff + len) + + @see + @return Result of the function call +*/ +WDI_Status +WDI_GetMessageBuffer +( + WDI_ControlBlockType* pWDICtx, + WDI_RequestEnumType wdiReqType, + wpt_uint16 usBufferLen, + wpt_uint8** pMsgBuffer, + wpt_uint16* pusDataOffset, + wpt_uint16* pusBufferSize +); + +/** + @brief WDI_DetectedDeviceError - called internally by DAL when + it has detected a failure in the device + + @param pWDICtx: pointer to the WLAN DAL context + usErrorCode: error code detected by WDI or received + from HAL + + @see + @return None +*/ +void +WDI_DetectedDeviceError +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usErrorCode +); + +/*========================================================================= + QUEUE SUPPORT UTILITY FUNCTIONS +=========================================================================*/ + +/** + @brief Utility function used by the DAL Core to help queue a + request that cannot be processed right away. + @param + + pWDICtx: - pointer to the WDI control block + pEventData: - pointer to the evnt info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueuePendingReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Utility function used by the DAL Core to clear any + pending requests - all req cb will be called with + failure and the queue will be emptied. + @param + + pWDICtx: - pointer to the WDI control block + + @see + @return Result of the operation +*/ +WDI_Status +WDI_ClearPendingRequests +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief This callback is invoked by the wpt when a timer that + we started on send message has expire - this should + never happen - it means device is stuck and cannot + reply - trigger catastrophic failure + @param + + pUserData: the callback data of the user (ptr to WDI CB) + + @see + @return None +*/ +void +WDI_ResponseTimerCB +( + void *pUserData +); + +/*========================================================================== + CONTRL TRANSPORT INTERACTION + + Callback function registered with the control transport - for receiving + notifications and packets +==========================================================================*/ +/** + @brief This callback is invoked by the control transport + when it wishes to send up a notification like the ones + mentioned above. + + @param + + wctsHandle: handle to the control transport service + wctsEvent: the event being notified + wctsNotifyCBData: the callback data of the user + + @see WCTS_OpenTransport + + @return None +*/ +void +WDI_NotifyMsgCTSCB +( + WCTS_HandleType wctsHandle, + WCTS_NotifyEventType wctsEvent, + void* wctsNotifyCBData +); + +/** + @brief This callback is invoked by the control transport + when it wishes to send up a packet received over the + bus. + + @param + + wctsHandle: handle to the control transport service + pMsg: the packet + uLen: the packet length + wctsRxMsgCBData: the callback data of the user + + @see WCTS_OpenTransport + + @return None +*/ +void +WDI_RXMsgCTSCB +( + WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen, + void* wctsRxMsgCBData +); + +/** + @brief Process response helper function + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessResponse +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Send message helper function - sends a message over the + bus using the control tranport and saves some info in + the CB + + @param pWDICtx: pointer to the WLAN DAL context + pSendBuffer: buffer to be sent + + uSendSize size of the buffer to be sent + pRspCb: response callback - save in the WDI + CB + pUserData: user data associated with the + callback + wdiExpectedResponse: the code of the response that is + expected to be rx-ed for this request + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SendMsg +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pSendBuffer, + wpt_uint32 uSendSize, + void* pRspCb, + void* pUserData, + WDI_ResponseEnumType wdiExpectedResponse +); + + +/** + @brief Send indication helper function - sends a message over + the bus using the control transport and saves some info + in the CB + + @param pWDICtx: pointer to the WLAN DAL context + pSendBuffer: buffer to be sent + usSendSize: size of the buffer to be sent + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SendIndication +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pSendBuffer, + wpt_uint32 usSendSize +); + +/** + @brief Utility function used by the DAL Core to help dequeue + and schedule for execution a pending request + @param + + pWDICtx: - pointer to the WDI control block + pEventData: - pointer to the evnt info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_DequeuePendingReq +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Utility function used by the DAL Core to help queue + an association request that cannot be processed right + away.- The assoc requests will be queued by BSSID + @param + + pWDICtx: - pointer to the WDI control block + pEventData: pointer to the evnt info that needs to be queued + macBSSID: bssid + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueueNewAssocRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData, + wpt_macAddr macBSSID +); + +/** + @brief Utility function used by the DAL Core to help queue + an association request that cannot be processed right + away.- The assoc requests will be queued by BSSID + @param + + pWDICtx: - pointer to the WDI control block + pSession: - session in which to queue + pEventData: pointer to the event info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueueAssocRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType* pSession, + WDI_EventInfoType* pEventData +); + +/** + @brief Utility function used by the DAL Core to help dequeue + an association request that was pending + The request will be queued up in front of the main + pending queue for immediate processing + @param + + pWDICtx: - pointer to the WDI control block + + + @see + @return Result of the operation +*/ +WDI_Status +WDI_DequeueAssocRequest +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Helper routine used to init the BSS Sessions in the WDI control block + + + @param pWDICtx: pointer to the WLAN DAL context + + @see +*/ +void +WDI_ResetAssocSessions +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief Helper routine used to find an empty session in the WDI + CB + + + @param pWDICtx: pointer to the WLAN DAL context + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindEmptySession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType** ppSession +); + +/** + @brief Helper routine used to get the total count of active + sessions + + + @param pWDICtx: pointer to the WLAN DAL context + macBSSID: pointer to BSSID. If NULL, get all the session. + If not NULL, count ActiveSession by excluding (TRUE) or including (FALSE) skipBSSID. + skipBSSID: if TRUE, get all the sessions except matching to macBSSID. If FALSE, get all session. + This argument is ignored if macBSSID is NULL. + @see + @return Number of sessions in use +*/ +wpt_uint8 +WDI_GetActiveSessionsCount +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr macBSSID, + wpt_boolean skipBSSID +); + +/** + @brief Helper routine used to delete session in the WDI + CB + + + @param pWDICtx: pointer to the WLAN DAL context + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +void +WDI_DeleteSession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType* ppSession +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + macBSSID: BSSID of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSession +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr macBSSID, + WDI_BSSSessionType** ppSession +); + + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + usBssIdx: BSS Index of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSessionByBSSIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usBssIdx, + WDI_BSSSessionType** ppSession +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + usBssIdx: BSS Index of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSessionByIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usBssIdx, + WDI_BSSSessionType** ppSession +); + +/** + @brief Helper routine used to find a session based on the BSSID + @param pContext: pointer to the WLAN DAL context + @param pDPContext: pointer to the Datapath context + + @see + @return +*/ +void +WDI_DS_AssignDatapathContext +( + void *pContext, + void *pDPContext +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pContext: pointer to the WLAN DAL context + + @see + @return pointer to Datapath context +*/ +void * +WDI_DS_GetDatapathContext +( + void *pContext +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pContext: pointer to the WLAN DAL context + @param pDTDriverContext: pointer to the Transport Driver context + + @see + @return void +*/ +void +WDT_AssignTransportDriverContext +( + void *pContext, + void *pDTDriverContext +); + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return pointer to datapath context +*/ +void * +WDT_GetTransportDriverContext +( + void *pContext +); + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + @brief Process Set Preferred Network List Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPreferredNetworkReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Set RSSI Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRssiFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Scan Params function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateScanParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Preferred Network Found Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPrefNetworkFoundInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process PNO Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPreferredNetworkRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process RSSI Filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRssiFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Update Scan Params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateScanParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + @brief Process Start Roam Candidate Lookup Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRoamScanOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessPERRoamScanOffloadReq(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData); + +WDI_Status +WDI_ProcessPERRoamScanTriggerReq(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData); +/** + @brief Process Start Roam Candidate Lookup Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRoamScanOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessPERRoamScanOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessPERRoamScanTriggerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +#ifdef WLAN_FEATURE_PACKET_FILTERING +/** + @brief Process 8023 Multicast List Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_Process8023MulticastListReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Set Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterSetFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process D0 PC Filter Match Count Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFilterMatchCountReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Clear Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterClearFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process 8023 Multicast List Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_Process8023MulticastListRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Set Filter Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterSetFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process D0 PC Filter Match Count Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFilterMatchCountRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Receive Filter Clear Filter Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterClearFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // WLAN_FEATURE_PACKET_FILTERING + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/** + @brief Process set GTK Offload Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process GTK Offload Get Information Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadGetInfoReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process host offload Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGtkOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process GTK Offload Get Information Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadGetInfoRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +WDI_Status +WDI_ProcessWakeReasonInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif // WLAN_WAKEUP_EVENTS + +/** + @brief Process Host-FW Capability Exchange Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFeatureCapsExchangeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process Host-FW Capability Exchange Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFeatureCapsExchangeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_11AC +WDI_Status +WDI_ProcessUpdateVHTOpModeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessUpdateVHTOpModeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + * @brief WDI_wdiEdTypeEncToEdTypeEnc - + * The firmware expects the Encryption type to be in EdType. + * This function converts the WdiEdType encryption to EdType. + * @param tEdType : EdType to which the encryption needs to be converted. + * @param WDI_EdType : wdiEdType passed from the upper layer. + * @see + * @return none + * */ +void +WDI_wdiEdTypeEncToEdTypeEnc +( + tEdType *EdType, + WDI_EdType wdiEdType +); +#endif + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLphbCfgRsp - + LPHB configuration response from FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessLphbCfgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_LPHB */ + +#ifdef WLAN_FEATURE_APFIND +WDI_Status +WDI_ProcessQRFPrefNetworkFoundInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process Rate Update Indication and post it to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRateUpdateInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_RMC +WDI_Status +WDI_ProcessRMCRulerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRMCRulerResp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRMCUpdateInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_RmcUpdateInd +( + WDI_RmcUpdateIndParams *wdiRmcUpdateIndParams +); + +WDI_Status +WDI_ProcessRMCRulerResp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRMCUpdateIndToHost +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process peer info req + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInfoReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process peer info resp + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInfoRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN +/** + @brief WDI_ProcessSetBatchScanRsp - + Process set batch scan response from FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetBatchScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessGetBcnMissRateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessGetBcnMissRateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process batch scan response from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBatchScanResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* FEATURE_WLAN_BATCH_SCAN */ + +WDI_Status +WDI_ProcessGetFwStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessGetFwStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_WLAN_CH_AVOID +/** + @brief v - + + + @param pWDICtx : wdi context + pEventData : indication data + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChAvoidInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif /* FEATURE_WLAN_CH_AVOID */ + +/** + @brief v - + + + @param pWDICtx : wdi context + pEventData : indication data + @see + @return Result of the function call +*/ +WDI_Status +WDI_printRegInfo +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef WLAN_FEATURE_EXTSCAN +WDI_Status +WDI_ProcessEXTScanStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +WDI_Status +WDI_ProcessEXTScanStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +WDI_Status +WDI_ProcessEXTScanStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +WDI_Status +WDI_ProcessEXTScanStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanGetCachedResultsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +WDI_Status +WDI_ProcessEXTScanGetCachedResultsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanProgressInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanGetCapabilitiesReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanGetCapabilitiesRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanSetBSSIDHotlistReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanSetHotlistBSSIDRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanResetBSSIDHotlistReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanResetHotlistBSSIDRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessHighPriorityDataInfoInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanScanAvailableInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEXTScanBssidHotListResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +WDI_Status +WDI_ProcessLLStatsSetRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessLLStatsSetReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessLLStatsGetRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessLLStatsGetReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessLLStatsClearRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessLLStatsClearReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessLinkLayerStatsResultsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +WDI_Status +WDI_delBaInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessSpoofMacAddrReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +WDI_Status +WDI_ProcessSpoofMacAddrRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessGetFrameLogRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +WDI_Status +WDI_ProcessGetFrameLogReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessFWLoggingDXEdoneInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessFatalEventLogsReq + +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessFatalEventLogsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessFWLoggingInitReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessFWFrameLoggingInitRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRssiMonitorStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRssiMonitorStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRssiMonitorStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessRssiMonitorStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEncryptMsgReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEncryptMsgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process NAN Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNanRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process NAN Response + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNanResponse +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** +*@brief Process NAN Event function (called when + an indication is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNanEvent +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** +*@brief Process Lost Link param function (called when + an indication is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_Process_LostLinkParamInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_Process_RssiBreachedInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + + +/** + @brief WDI_ProcessSetRtsCtsHtvhtInd + Set RTS/CTS indication for diff modes. + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @return Result of the function call +*/ + + +WDI_Status +WDI_ProcessSetRtsCtsHtvhtInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessMonStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessMonStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessMonStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessMonStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessEnableDisableCAEventInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessFwrMemDumpReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status + WDI_ProcessFwrMemDumpRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessWifiConfigReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessWificonfigSetRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief WDI_ProcessStartOemDataReqIndNew - + Send OEM Data request new indication to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessStartOemDataReqIndNew +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process OemDataRsp New Indication indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataRspIndNew +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +/** + @brief Process get current antenna index command + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetCurrentAntennaIndex +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process get current antenna index response from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetCurrentAntennaIndexRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + @brief Process set modified roam params command + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBcnMissPenaltyCount +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +/** + * WDI_ProcessSetAllowedActionFramesInd - Process Set allowed action + * frames command + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + */ +WDI_Status +WDI_ProcessSetAllowedActionFramesInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#ifdef SAP_AUTH_OFFLOAD +/** + * WDI_ProcessSapAuthOffloadInd - Process Set sap offload enable + * command + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + */ +WDI_Status +WDI_ProcessSapAuthOffloadInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ); +#endif + +#ifdef DHCP_SERVER_OFFLOAD +WDI_Status +wdi_dhcp_server_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_dhcp_server_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +WDI_Status +wdi_mdns_enable_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_mdns_enable_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_mdns_fqdn_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_mdns_fqdn_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_mdns_resp_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_mdns_resp_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_get_mdns_stats_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_get_mdns_stats_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); +#endif /* MDNS_OFFLOAD */ +#ifdef WLAN_FEATURE_APFIND +/** + * WDI_ProcessApFindInd - Process AP find command command + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + */ +WDI_Status +WDI_ProcessApFindInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); +#endif + +WDI_Status +wdi_cap_tsf_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +wdi_get_tsf_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); +WDI_Status +wdi_get_tsf_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +); + +WDI_Status +WDI_ProcessSetArpStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessSetArpStatsResp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessGetArpStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +WDI_Status +WDI_ProcessGetArpStatsResp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +#endif /*WLAN_QCT_WDI_I_H*/ + diff --git a/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h new file mode 100644 index 000000000000..f62bbff6b80f --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/inc/wlan_qct_wdi_sta.h @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_DAL_STA_H +#define WLAN_QCT_DAL_STA_H + +/*=========================================================================== + + W L A N D E V I C E A B S T R A C T I O N L A Y E R + I N T E R N A L A P I F O R T H E + S T A T I O N M G M T + + +DESCRIPTION + This file contains the internal API exposed by the STA Management entity to + be used by the DAL Control Path Core . + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/19/10 lti Created module. + +===========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_api.h" + +/*---------------------------------------------------------------------------- + Preprocesor definitions and macros + -------------------------------------------------------------------------*/ +/*Invalid station index */ +#define WDI_STA_INVALID_IDX 0xFF + +/*---------------------------------------------------------------------------- + WDI_StaStruct + -------------------------------------------------------------------------*/ +typedef struct +{ + wpt_macAddr staAddr; // Sta Addr + + wpt_uint8 valid:1; // Used/free flag + wpt_uint8 rmfEnabled:1; + wpt_uint8 htEnabled:1; + + /* 11e or WMM enabled, flag used for header length*/ + wpt_uint8 qosEnabled:1; + + wpt_uint8 bssIdx; // BSS Index + wpt_uint8 staId; + + wpt_macAddr macBSSID; + // Field to indicate if this is sta entry for itself STA adding entry for itself + // or remote (AP adding STA after successful association. + // This may or may not be required in production driver. + // 0 - Self, 1 other/remote, 2 - bssid + wpt_uint8 ucStaType; + + + /*DPU Information*/ + wpt_uint8 dpuIndex; // DPU table index + wpt_uint8 dpuSig; // DPU signature + wpt_uint8 bcastDpuIndex; + wpt_uint8 bcastDpuSignature; + wpt_uint8 bcastMgmtDpuIndex; + wpt_uint8 bcastMgmtDpuSignature; + +} WDI_StaStruct; + +/** + @brief WDI_STATableInit - Initializes the STA tables. + Allocates the necesary memory. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status WDI_STATableInit +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableStart - resets the max and number values of + STAtions + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableStart +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableStop - clears the sta table + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableStop +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableClose - frees the resources used by the STA + table. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableClose +( + WDI_ControlBlockType* pWDICtx +); + +/** + @brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS + + + @param pWDICtx: pointer to the WLAN DAL context + bssIdx: BSS index + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableBSSDelSta +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucBssIdx +); + +/** + @brief WDI_STATableGetStaBSSIDAddr - Gets the BSSID associated + with this station + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + pmacBSSID: out BSSID for this STA + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaBSSIDAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr* pmacBSSID +); +/** + @brief WDI_STATableGetStaQosEnabled - Gets is qos is enabled + for a sta + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + qosEnabled: out qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaQosEnabled +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8* qosEnabled +); + +/** + @brief WDI_STATableSetStaQosEnabled - set qos mode for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + qosEnabled: qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaQosEnabled +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 qosEnabled +); + +/** + @brief WDI_STATableGetStaType - get sta type for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + pStaType: qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaType +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8* pStaType +); + +/** + @brief WDI_STATableSetStaType - sets sta type for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + staType: sta type + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaType +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 staType +); + + +/** + @brief WDI_STATableGetStaAddr - get station address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8** pStaAddr +); + +/** + @brief WDI_STATableGetStaMacAddr - get station MAC address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station MAC address + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_STATableGetStaMacAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr* staMacAddr +); + +/** + @brief WDI_STATableSetStaAddr - set station address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr staAddr +); + +/** + @brief WDI_STATableSetBSSID - set station corresponding BSSID + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetBSSID +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr macBSSID +); + +/** + @brief WDI_STATableSetBSSIdx - set station corresponding BSS index + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + bssIdx: BSS index + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetBSSIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 ucBSSIdx +); + +#endif /*WLAN_QCT_WDI_STA_H*/ + diff --git a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c new file mode 100644 index 000000000000..4aed25df7450 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi.c @@ -0,0 +1,39610 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*=========================================================================== + + W L A N _ Q C T _ W D I. C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Abstraction + Layer Interface. + + The functions externalized by this module are to be called by any upper + MAC implementation that wishes to use the WLAN Device. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +10/05/11 hap Adding support for Keep Alive +2010-08-09 lti Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_i.h" +#include "wlan_qct_wdi_sta.h" +#include "wlan_qct_wdi_dp.h" + +#include "wlan_qct_wdi_cts.h" + +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_sync.h" +#include "wlan_qct_pal_msg.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_pal_packet.h" + +#include "wlan_qct_wdi_dts.h" + +#include "wlan_hal_msg.h" + +#include "pttMsgApi.h" +#include "vos_trace.h" +#include "vos_diag_core_event.h" + +#include "vos_api.h" + +/*=========================================================================== + WLAN DAL Control Path Internal Data Definitions and Declarations + ===========================================================================*/ +#define WDI_WCTS_ACTION_TIMEOUT 2000 /* in msec a very high upper limit */ + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" + +#define FEATURE_NOT_SUPPORTED 127 +#define MAX_FW_HOST_CAP_SIZE 1024 +#ifdef FEATURE_WLAN_SCAN_PNO +#define WDI_PNO_VERSION_MASK 0x8000 +#endif + +/* host capability bitmap global */ +static tWlanFeatCaps *gpHostWlanFeatCaps; +/* FW capability bitmap global */ +static tWlanFeatCaps *gpFwWlanFeatCaps; +/* array of features supported. Need to add a new feature + * and other two places - wlan_hal_msg.h and halMsg.c (FW file) + */ +static placeHolderInCapBitmap supportEnabledFeatures[] = + {MCC, P2P, DOT11AC, SLM_SESSIONIZATION, DOT11AC_OPMODE +#ifdef WLAN_SOFTAP_VSTA_FEATURE + ,SAP32STA //5 +#else + ,FEATURE_NOT_SUPPORTED +#endif +#ifdef FEATURE_WLAN_TDLS + ,TDLS //6 +#else + ,FEATURE_NOT_SUPPORTED +#endif + ,P2P_GO_NOA_DECOUPLE_INIT_SCAN //7 +#ifdef WLAN_ACTIVEMODE_OFFLOAD_FEATURE + ,WLANACTIVE_OFFLOAD //8 +#else + ,FEATURE_NOT_SUPPORTED +#endif + ,FEATURE_NOT_SUPPORTED //9 + ,FEATURE_NOT_SUPPORTED //10 + ,FEATURE_NOT_SUPPORTED //11 + ,FEATURE_NOT_SUPPORTED //12 + ,FEATURE_NOT_SUPPORTED //13 + ,FEATURE_NOT_SUPPORTED //14 + ,FEATURE_NOT_SUPPORTED //15 + ,FEATURE_NOT_SUPPORTED //16 + ,FEATURE_NOT_SUPPORTED //17 + ,FEATURE_NOT_SUPPORTED //18 + ,FEATURE_NOT_SUPPORTED //19 + ,FEATURE_NOT_SUPPORTED //20 + ,FEATURE_NOT_SUPPORTED //21 + ,WOW //22 +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + ,WLAN_ROAM_SCAN_OFFLOAD //23 +#else + ,FEATURE_NOT_SUPPORTED +#endif + ,FEATURE_NOT_SUPPORTED //24 + ,FEATURE_NOT_SUPPORTED //25 + ,IBSS_HEARTBEAT_OFFLOAD //26 + ,FEATURE_NOT_SUPPORTED //27 + ,WLAN_PERIODIC_TX_PTRN //28 +#ifdef FEATURE_WLAN_TDLS + ,ADVANCE_TDLS //29 +#else + ,FEATURE_NOT_SUPPORTED //29 +#endif + ,FEATURE_NOT_SUPPORTED //30 + ,FW_IN_TX_PATH //31 + ,EXTENDED_NSOFFLOAD_SLOT //32 + ,CH_SWITCH_V1 //33 + ,HT40_OBSS_SCAN //34 + ,UPDATE_CHANNEL_LIST //35 + ,FEATURE_NOT_SUPPORTED //36 + ,FEATURE_NOT_SUPPORTED //37 + ,FEATURE_NOT_SUPPORTED //38 +#ifdef FEATURE_WLAN_TDLS + ,TDLS_SCAN_COEXISTENCE //39 +#else + ,FEATURE_NOT_SUPPORTED //39 +#endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + ,LINK_LAYER_STATS_MEAS //40 +#else + ,FEATURE_NOT_SUPPORTED //40 +#endif + ,MU_MIMO //41 +#ifdef WLAN_FEATURE_EXTSCAN + ,EXTENDED_SCAN //42 +#else + ,FEATURE_NOT_SUPPORTED //42 +#endif + ,DYNAMIC_WMM_PS //43 + + ,MAC_SPOOFED_SCAN //44 + ,BMU_ERROR_GENERIC_RECOVERY //45 + ,DISA //46 + ,FW_STATS //47 + ,WPS_PRBRSP_TMPL //48 + ,BCN_IE_FLT_DELTA //49 + ,FEATURE_NOT_SUPPORTED //50 +#ifdef FEATURE_WLAN_TDLS + ,TDLS_OFF_CHANNEL //51 +#else + ,FEATURE_NOT_SUPPORTED //51 +#endif + ,RTT3 //52 + ,MGMT_FRAME_LOGGING //53 + ,ENHANCED_TXBD_COMPLETION //54 + ,LOGGING_ENHANCEMENT //55 +#ifdef WLAN_FEATURE_EXTSCAN + ,EXT_SCAN_ENHANCED //56 +#else + ,FEATURE_NOT_SUPPORTED //56 +#endif + ,MEMORY_DUMP_SUPPORTED //57 + ,PER_PKT_STATS_SUPPORTED //58 + ,FEATURE_NOT_SUPPORTED //59 +#ifdef FEATURE_EXT_LL_STAT + ,EXT_LL_STAT //60 +#else + ,FEATURE_NOT_SUPPORTED +#endif + ,WIFI_CONFIG //61 + ,ANTENNA_DIVERSITY_SELECTION //62 + ,PER_BASED_ROAMING //63 + ,SAP_MODE_WOW //64 + ,SAP_OFFLOADS //65 + ,SAP_BUFF_ALLOC //66 + ,MAKE_BEFORE_BREAK //67 + ,NUD_DEBUG //68 + ,FEATURE_NOT_SUPPORTED //69 reserved for FATAL_EVENT_LOGGING + ,FEATURE_NOT_SUPPORTED //70 reserved for WIFI_DUAL_BAND_ENABLE + ,PROBE_RSP_TEMPLATE_VER1 //71 +}; + +/*-------------------------------------------------------------------------- + WLAN DAL State Machine + --------------------------------------------------------------------------*/ +WPT_STATIC const WDI_MainFsmEntryType wdiMainFSM[WDI_MAX_ST] = +{ + /*WDI_INIT_ST*/ + {{ + WDI_MainStart, /*WDI_START_EVENT*/ + NULL, /*WDI_STOP_EVENT*/ + WDI_MainReqBusy, /*WDI_REQUEST_EVENT*/ + WDI_MainRspInit, /*WDI_RESPONSE_EVENT*/ + WDI_MainClose, /*WDI_CLOSE_EVENT*/ + WDI_MainShutdown /*WDI_SHUTDOWN_EVENT*/ + }}, + + /*WDI_STARTED_ST*/ + {{ + WDI_MainStartStarted, /*WDI_START_EVENT*/ + WDI_MainStopStarted, /*WDI_STOP_EVENT*/ + WDI_MainReqStarted, /*WDI_REQUEST_EVENT*/ + WDI_MainRsp, /*WDI_RESPONSE_EVENT*/ + NULL, /*WDI_CLOSE_EVENT*/ + WDI_MainShutdown /*WDI_SHUTDOWN_EVENT*/ + }}, + + /*WDI_STOPPED_ST*/ + {{ + WDI_MainStart, /*WDI_START_EVENT*/ + WDI_MainStopStopped, /*WDI_STOP_EVENT*/ + NULL, /*WDI_REQUEST_EVENT*/ + WDI_MainRsp, /*WDI_RESPONSE_EVENT*/ + WDI_MainClose, /*WDI_CLOSE_EVENT*/ + WDI_MainShutdown /*WDI_SHUTDOWN_EVENT*/ + }}, + + /*WDI_BUSY_ST*/ + {{ + WDI_MainStartBusy, /*WDI_START_EVENT*/ + WDI_MainStopBusy, /*WDI_STOP_EVENT*/ + WDI_MainReqBusy, /*WDI_REQUEST_EVENT*/ + WDI_MainRsp, /*WDI_RESPONSE_EVENT*/ + WDI_MainCloseBusy, /*WDI_CLOSE_EVENT*/ + WDI_MainShutdownBusy /*WDI_SHUTDOWN_EVENT*/ + }} +}; + +/*--------------------------------------------------------------------------- + DAL Request Processing Array - the functions in this table will only be + called when the processing of the specific request is allowed by the + Main FSM + ---------------------------------------------------------------------------*/ +WDI_ReqProcFuncType pfnReqProcTbl[WDI_MAX_UMAC_IND] = +{ + /*INIT*/ + WDI_ProcessStartReq, /* WDI_START_REQ */ + WDI_ProcessStopReq, /* WDI_STOP_REQ */ + WDI_ProcessCloseReq, /* WDI_CLOSE_REQ */ + + /*SCAN*/ + WDI_ProcessInitScanReq, /* WDI_INIT_SCAN_REQ */ + WDI_ProcessStartScanReq, /* WDI_START_SCAN_REQ */ + WDI_ProcessEndScanReq, /* WDI_END_SCAN_REQ */ + WDI_ProcessFinishScanReq, /* WDI_FINISH_SCAN_REQ */ + + /*ASSOCIATION*/ + WDI_ProcessJoinReq, /* WDI_JOIN_REQ */ + WDI_ProcessConfigBSSReq, /* WDI_CONFIG_BSS_REQ */ + WDI_ProcessDelBSSReq, /* WDI_DEL_BSS_REQ */ + WDI_ProcessPostAssocReq, /* WDI_POST_ASSOC_REQ */ + WDI_ProcessDelSTAReq, /* WDI_DEL_STA_REQ */ + + /* Security */ + WDI_ProcessSetBssKeyReq, /* WDI_SET_BSS_KEY_REQ */ + WDI_ProcessRemoveBssKeyReq, /* WDI_RMV_BSS_KEY_REQ */ + WDI_ProcessSetStaKeyReq, /* WDI_SET_STA_KEY_REQ */ + WDI_ProcessRemoveStaKeyReq, /* WDI_RMV_BSS_KEY_REQ */ + + /* QoS and BA APIs */ + WDI_ProcessAddTSpecReq, /* WDI_ADD_TS_REQ */ + WDI_ProcessDelTSpecReq, /* WDI_DEL_TS_REQ */ + WDI_ProcessUpdateEDCAParamsReq, /* WDI_UPD_EDCA_PRMS_REQ */ + WDI_ProcessAddBASessionReq, /* WDI_ADD_BA_SESSION_REQ */ + WDI_ProcessDelBAReq, /* WDI_DEL_BA_REQ */ + + /* Miscellaneous Control APIs */ + WDI_ProcessChannelSwitchReq, /* WDI_CH_SWITCH_REQ */ + WDI_ProcessConfigStaReq, /* WDI_CONFIG_STA_REQ */ + WDI_ProcessSetLinkStateReq, /* WDI_SET_LINK_ST_REQ */ + WDI_ProcessGetStatsReq, /* WDI_GET_STATS_REQ */ + WDI_ProcessUpdateCfgReq, /* WDI_UPDATE_CFG_REQ */ + + /*BA APIs*/ + WDI_ProcessAddBAReq, /* WDI_ADD_BA_REQ */ + WDI_ProcessTriggerBAReq, /* WDI_TRIGGER_BA_REQ */ + + /*Beacon processing APIs*/ + WDI_ProcessUpdateBeaconParamsReq, /* WDI_UPD_BCON_PRMS_REQ */ + WDI_ProcessSendBeaconParamsReq, /* WDI_SND_BCON_REQ */ + + WDI_ProcessUpdateProbeRspTemplateReq, /* WDI_UPD_PROBE_RSP_TEMPLATE_REQ */ + WDI_ProcessSetStaBcastKeyReq, /* WDI_SET_STA_BCAST_KEY_REQ */ + WDI_ProcessRemoveStaBcastKeyReq, /* WDI_RMV_STA_BCAST_KEY_REQ */ + WDI_ProcessSetMaxTxPowerReq, /*WDI_SET_MAX_TX_POWER_REQ*/ + WDI_ProcessP2PGONOAReq, /* WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ */ + /* PowerSave APIs */ + WDI_ProcessEnterImpsReq, /* WDI_ENTER_IMPS_REQ */ + WDI_ProcessExitImpsReq, /* WDI_EXIT_IMPS_REQ */ + WDI_ProcessEnterBmpsReq, /* WDI_ENTER_BMPS_REQ */ + WDI_ProcessExitBmpsReq, /* WDI_EXIT_BMPS_REQ */ + WDI_ProcessEnterUapsdReq, /* WDI_ENTER_UAPSD_REQ */ + WDI_ProcessExitUapsdReq, /* WDI_EXIT_UAPSD_REQ */ + WDI_ProcessSetUapsdAcParamsReq, /* WDI_SET_UAPSD_PARAM_REQ */ + WDI_ProcessUpdateUapsdParamsReq, /* WDI_UPDATE_UAPSD_PARAM_REQ */ + WDI_ProcessConfigureRxpFilterReq, /* WDI_CONFIGURE_RXP_FILTER_REQ */ + WDI_ProcessSetBeaconFilterReq, /* WDI_SET_BEACON_FILTER_REQ */ + WDI_ProcessRemBeaconFilterReq, /* WDI_REM_BEACON_FILTER_REQ */ + WDI_ProcessSetRSSIThresholdsReq, /* WDI_SET_RSSI_THRESHOLDS_REQ */ + WDI_ProcessHostOffloadReq, /* WDI_HOST_OFFLOAD_REQ */ + WDI_ProcessWowlAddBcPtrnReq, /* WDI_WOWL_ADD_BC_PTRN_REQ */ + WDI_ProcessWowlDelBcPtrnReq, /* WDI_WOWL_DEL_BC_PTRN_REQ */ + WDI_ProcessWowlEnterReq, /* WDI_WOWL_ENTER_REQ */ + WDI_ProcessWowlExitReq, /* WDI_WOWL_EXIT_REQ */ + WDI_ProcessConfigureAppsCpuWakeupStateReq, /* WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ */ + /*NV Download APIs*/ + WDI_ProcessNvDownloadReq, /* WDI_NV_DOWNLOAD_REQ*/ + WDI_ProcessFlushAcReq, /* WDI_FLUSH_AC_REQ */ + WDI_ProcessBtAmpEventReq, /* WDI_BTAMP_EVENT_REQ */ +#ifdef WLAN_FEATURE_VOWIFI_11R + WDI_ProcessAggrAddTSpecReq, /* WDI_AGGR_ADD_TS_REQ */ +#else + NULL, +#endif /* WLAN_FEATURE_VOWIFI_11R */ + WDI_ProcessAddSTASelfReq, /* WDI_ADD_STA_SELF_REQ */ + WDI_ProcessDelSTASelfReq, /* WDI DEL STA SELF REQ */ + WDI_ProcessFTMCommandReq, /* WDI_FTM_CMD_REQ */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + WDI_ProcessStartOemDataReq, /*WDI_START_OEM_DATA_REQ*/ +#else + NULL, +#endif /*FEATURE_OEM_DATA_SUPPORT*/ + WDI_ProcessHostResumeReq, /*WDI_HOST_RESUME_REQ*/ + + WDI_ProcessKeepAliveReq, /* WDI_KEEP_ALIVE_REQ */ + +#ifdef FEATURE_WLAN_SCAN_PNO + WDI_ProcessSetPreferredNetworkReq, /* WDI_SET_PREF_NETWORK_REQ */ + WDI_ProcessSetRssiFilterReq, /* WDI_SET_RSSI_FILTER_REQ */ + WDI_ProcessUpdateScanParamsReq, /* WDI_UPDATE_SCAN_PARAMS_REQ */ +#else + NULL, + NULL, + NULL, +#endif /* FEATURE_WLAN_SCAN_PNO */ + + WDI_ProcessSetTxPerTrackingReq, /* WDI_SET_TX_PER_TRACKING_REQ */ + +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* WDI_8023_MULTICAST_LIST_REQ */ + WDI_Process8023MulticastListReq, + /* WDI_RECEIVE_FILTER_SET_FILTER_REQ */ + WDI_ProcessReceiveFilterSetFilterReq, + /* WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ */ + WDI_ProcessFilterMatchCountReq, + /* WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ */ + WDI_ProcessReceiveFilterClearFilterReq, +#else + NULL, + NULL, + NULL, + NULL, +#endif // WLAN_FEATURE_PACKET_FILTERING + WDI_ProcessInitScanReq, /* WDI_INIT_SCAN_CON_REQ */ + WDI_ProcessHALDumpCmdReq, /*WDI_HAL_DUMP_CMD_REQ */ + WDI_ProcessShutdownReq, /* WDI_SHUTDOWN_REQ */ + + WDI_ProcessSetPowerParamsReq, /*WDI_SET_POWER_PARAMS_REQ*/ +#ifdef FEATURE_WLAN_ESE + WDI_ProcessTSMStatsReq, /* WDI_TSM_STATS_REQ */ +#else + NULL, +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + WDI_ProcessGTKOffloadReq, /* WDI_GTK_OFFLOAD_REQ */ + WDI_ProcessGTKOffloadGetInfoReq, /* WDI_GTK_OFFLOAD_GETINFO_REQ */ +#else + NULL, + NULL, +#endif // WLAN_FEATURE_GTK_OFFLOAD + + WDI_ProcessSetTmLevelReq, /*WDI_SET_TM_LEVEL_REQ*/ + WDI_ProcessFeatureCapsExchangeReq, /* WDI_FEATURE_CAPS_EXCHANGE_REQ */ +#ifdef WLAN_FEATURE_11AC + WDI_ProcessUpdateVHTOpModeReq, /* WDI_UPDATE_VHT_OP_MODE_REQ */ +#else + NULL, +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + WDI_ProcessGetRoamRssiReq, /* WDI_GET_ROAM_RSSI_REQ */ +#else + NULL, +#endif + WDI_ProcessSetTxPowerReq, /* WDI_SET_TX_POWER_REQ*/ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WDI_ProcessRoamScanOffloadReq, /* WDI_ROAM_SCAN_OFFLOAD_REQ */ +#else + NULL, +#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */ +#ifdef FEATURE_WLAN_TDLS + WDI_ProcessTdlsLinkEstablishReq, /* WDI_TDLS_LINK_ESTABLISH_REQ */ +#else + NULL, +#endif +#ifdef FEATURE_WLAN_LPHB + WDI_ProcessLPHBConfReq, /* WDI_LPHB_CFG_REQ */ +#else + NULL, +#endif /* FEATURE_WLAN_LPHB */ +#ifdef WLAN_FEATURE_RMC + WDI_ProcessRMCRulerReq, /* WDI_LBP_RULER_REQ */ + WDI_ProcessIbssPeerInfoReq, /* WDI_HAL_IBSS_PEER_INFO_REQ */ +#else + NULL, + NULL, +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + WDI_ProcessSetBatchScanReq, /* WDI_SET_BATCH_SCAN_REQ */ +#else + NULL, +#endif /* FEATURE_WLAN_BATCH_SCAN */ + + WDI_ProcessSetMaxTxPowerPerBandReq, /* WDI_SET_MAX_TX_POWER_PER_BAND_REQ*/ + + WDI_ProcessUpdateChannelParamsReq, /* WDI_UPDATE_CHAN_REQ */ + + WDI_ProcessGetBcnMissRateReq, /* WDI_GET_BCN_MISS_RATE_REQ */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_ProcessLLStatsSetReq, /* WDI_LL_STATS_SET_REQ */ + WDI_ProcessLLStatsGetReq, /* WDI_LL_STATS_GET_REQ */ + WDI_ProcessLLStatsClearReq, /* WDI_LL_STATS_CLEAR_REQ */ +#else + NULL, + NULL, + NULL, +#endif +#ifdef WLAN_FEATURE_EXTSCAN + WDI_ProcessEXTScanStartReq, /* WDI_EXTSCAN_START_REQ */ + WDI_ProcessEXTScanStopReq, /* WDI_EXTSCAN_STOP_REQ */ + WDI_ProcessEXTScanGetCachedResultsReq, /* WDI_EXTSCAN_GET_CACHED_RESULTS_REQ */ + WDI_ProcessEXTScanGetCapabilitiesReq, /* WDI_EXTSCAN_GET_CAPABILITIES_REQ */ + WDI_ProcessEXTScanSetBSSIDHotlistReq, /* WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ */ + WDI_ProcessEXTScanResetBSSIDHotlistReq, /* WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ */ + NULL, /* maintain synchronization though SSID_HOTLIST is deprecated */ + NULL, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif /* WLAN_FEATURE_EXTSCAN */ + WDI_ProcessSpoofMacAddrReq, /* WDI_SPOOF_MAC_ADDR_REQ */ + + WDI_ProcessGetFwStatsReq, /*WDI_GET_FW_STATS_REQ*/ + + WDI_ProcessEncryptMsgReq, /* WDI_ENCRYPT_MSG_REQ*/ + + WDI_ProcessFWLoggingInitReq, /* WDI_FW_LOGGING_INIT_REQ*/ + WDI_ProcessGetFrameLogReq, /* WDI_GET_FRAME_LOG_REQ*/ + + WDI_ProcessNanRequest, /* WDI_NAN_REQUEST*/ + + WDI_ProcessMonStartReq, /* WDI_MON_START_REQ */ + WDI_ProcessMonStopReq, /* WDI_MON_STOP_REQ */ + WDI_ProcessFatalEventLogsReq, /*WDI_FATAL_EVENT_LOGGING_REQ*/ + WDI_ProcessFwrMemDumpReq, /* WDI_FWR_MEM_DUMP_REQ*/ + + WDI_ProcessRssiMonitorStartReq, /* WDI_START_RSSI_MONITOR_REQ */ + WDI_ProcessRssiMonitorStopReq, /* WDI_STOP_RSSI_MONITOR_REQ */ + + WDI_ProcessWifiConfigReq, /*WDI_WIFI_CONFIG_SET_REQ*/ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WDI_ProcessPERRoamScanOffloadReq, /* WDI_PER_ROAM_SCAN_OFFLOAD_REQ */ + WDI_ProcessPERRoamScanTriggerReq, /* WDI_PER_ROAM_SCAN_TRIGGER_REQ */ +#else + NULL, + NULL, +#endif /* WLAN_FEATURE_ROAM_SCAN_OFFLOAD */ +#ifdef DHCP_SERVER_OFFLOAD + wdi_dhcp_server_offload_req, /* WDI_DHCP_SERVER_OFFLOAD_REQ */ +#else + NULL, +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + wdi_mdns_enable_offload_req, /* WDI_MDNS_ENABLE_OFFLOAD_REQ */ + wdi_mdns_fqdn_offload_req, /* WDI_MDNS_FQDN_OFFLOAD_REQ */ + wdi_mdns_resp_offload_req, /* WDI_MDNS_RESP_OFFLOAD_REQ */ + wdi_get_mdns_stats_offload_req, /* WDI_GET_MDNS_STATS_OFFLOAD_REQ */ +#else + NULL, + NULL, + NULL, + NULL, +#endif /* MDNS_OFFLOAD */ + wdi_cap_tsf_req, /* WDI_CAP_TSF_REQ */ + wdi_get_tsf_req, /* WDI_GET_TSF_REQ */ + + WDI_ProcessSetArpStatsReq, /* WDI_FW_ARP_STATS_REQ */ + WDI_ProcessGetArpStatsReq, /* WDI_FW_GET_ARP_STATS_REQ */ + + /*------------------------------------------------------------------------- + Indications + -------------------------------------------------------------------------*/ + WDI_ProcessHostSuspendInd, /* WDI_HOST_SUSPEND_IND*/ + WDI_ProcessTrafficStatsInd, /* WDI_TRAFFIC_STATS_IND*/ + WDI_ProcessDHCPStartInd, /* WDI_DHCP_START_IND*/ + WDI_ProcessDHCPStopInd, /* WDI_DHCP_STOP_IND*/ +#ifdef WLAN_FEATURE_11W + WDI_ProcessExcludeUnencryptInd, /* WDI_EXCLUDE_UNENCRYPTED_IND */ +#else + NULL, +#endif + WDI_ProcessAddPeriodicTxPtrnInd, /* WDI_ADD_PERIODIC_TX_PATTERN_IND */ + WDI_ProcessDelPeriodicTxPtrnInd, /* WDI_DEL_PERIODIC_TX_PATTERN_IND */ +#ifdef WLAN_FEATURE_RMC + WDI_ProcessRMCUpdateInd, /* WDI_RMC_UPDATE_IND */ +#else + NULL, +#endif /* WLAN_FEATURE_RMC */ + WDI_ProcessRateUpdateInd, /* WDI_RATE_UPDATE_IND */ +#ifdef FEATURE_WLAN_BATCH_SCAN + WDI_ProcessStopBatchScanInd, /* WDI_STOP_BATCH_SCAN_IND */ + WDI_ProcessTriggerBatchScanResultInd, /* WDI_TRIGGER_BATCH_SCAN_RESULT_IND */ +#else + NULL, + NULL, +#endif /* FEATURE_WLAN_BATCH_SCAN */ +#ifdef WLAN_FEATURE_RMC + WDI_ProcessTXFailMonitor, +#else + NULL, +#endif + + WDI_ProcessHT40OBSSScanInd, /*WDI_START_HT40_OBSS_SCAN_IND */ + WDI_ProcessHT40OBSSStopScanInd, /*WDI_STOP_HT40_OBSS_SCAN_IND */ + + WDI_ProcessChannelSwitchReq_V1, /* WDI_CH_SWITCH_REQ_V1*/ +#ifdef FEATURE_WLAN_TDLS + WDI_ProcessTdlsChanSwitchReq, /* WDI_TDLS_CHAN_SWITCH_REQ */ +#else + NULL, +#endif + WDI_ProcessSetRtsCtsHtvhtInd, /* WDI_SET_RTS_CTS_HTVHT_IND */ + WDI_ProcessFWLoggingDXEdoneInd, /* WDI_FW_LOGGING_DXE_DONE_IND */ + WDI_ProcessEnableDisableCAEventInd, /* WDI_SEND_FREQ_RANGE_CONTROL_IND */ + +#ifdef WLAN_FEATURE_EXTSCAN + WDI_ProcessHighPriorityDataInfoInd, /* WDI_HIGH_PRIORITY_DATA_INFO_IND */ +#else + NULL, +#endif /* WLAN_FEATURE_EXTSCAN */ + +#ifdef FEATURE_OEM_DATA_SUPPORT + WDI_ProcessStartOemDataReqIndNew, /* WDI_START_OEM_DATA_REQ_IND_NEW */ +#else + NULL, +#endif /* FEATURE_OEM_DATA_SUPPORT */ + WDI_ProcessGetCurrentAntennaIndex, /* WDI_ANTENNA_DIVERSITY_SELECTION_REQ */ + WDI_ProcessBcnMissPenaltyCount, /* WDI_MODIFY_ROAM_PARAMS_IND */ + WDI_ProcessSetAllowedActionFramesInd, /* WDI_SET_ALLOWED_ACTION_FRAMES_IND */ +#ifdef SAP_AUTH_OFFLOAD + WDI_ProcessSapAuthOffloadInd, /* WDI_PROCESS_SAP_AUTH_OFFLOAD_IND */ +#endif +#ifdef WLAN_FEATURE_APFIND + WDI_ProcessApFindInd, /* WDI_SET_AP_FIND_IND */ +#endif +}; + + +/*--------------------------------------------------------------------------- + DAL Request Processing Array - the functions in this table will only be + called when the processing of the specific request is allowed by the + Main FSM + ---------------------------------------------------------------------------*/ +WDI_RspProcFuncType pfnRspProcTbl[WDI_MAX_RESP] = +{ + /*INIT*/ + WDI_ProcessStartRsp, /* WDI_START_RESP */ + WDI_ProcessStopRsp, /* WDI_STOP_RESP */ + WDI_ProcessCloseRsp, /* WDI_CLOSE_RESP */ + + /*SCAN*/ + WDI_ProcessInitScanRsp, /* WDI_INIT_SCAN_RESP */ + WDI_ProcessStartScanRsp, /* WDI_START_SCAN_RESP */ + WDI_ProcessEndScanRsp, /* WDI_END_SCAN_RESP */ + WDI_ProcessFinishScanRsp, /* WDI_FINISH_SCAN_RESP */ + + /* ASSOCIATION*/ + WDI_ProcessJoinRsp, /* WDI_JOIN_RESP */ + WDI_ProcessConfigBSSRsp, /* WDI_CONFIG_BSS_RESP */ + WDI_ProcessDelBSSRsp, /* WDI_DEL_BSS_RESP */ + WDI_ProcessPostAssocRsp, /* WDI_POST_ASSOC_RESP */ + WDI_ProcessDelSTARsp, /* WDI_DEL_STA_RESP */ + + /* Security */ + WDI_ProcessSetBssKeyRsp, /* WDI_SET_BSS_KEY_RESP */ + WDI_ProcessRemoveBssKeyRsp, /* WDI_RMV_BSS_KEY_RESP */ + WDI_ProcessSetStaKeyRsp, /* WDI_SET_STA_KEY_RESP */ + WDI_ProcessRemoveStaKeyRsp, /* WDI_RMV_BSS_KEY_RESP */ + + /* QoS and BA APIs */ + WDI_ProcessAddTSpecRsp, /* WDI_ADD_TS_RESP */ + WDI_ProcessDelTSpecRsp, /* WDI_DEL_TS_RESP */ + WDI_ProcessUpdateEDCAParamsRsp, /* WDI_UPD_EDCA_PRMS_RESP */ + WDI_ProcessAddBASessionRsp, /* WDI_ADD_BA_SESSION_RESP */ + WDI_ProcessDelBARsp, /* WDI_DEL_BA_RESP */ + + /* Miscellaneous Control APIs */ + WDI_ProcessChannelSwitchRsp, /* WDI_CH_SWITCH_RESP */ + WDI_ProcessConfigStaRsp, /* WDI_CONFIG_STA_RESP */ + WDI_ProcessSetLinkStateRsp, /* WDI_SET_LINK_ST_RESP */ + WDI_ProcessGetStatsRsp, /* WDI_GET_STATS_RESP */ + WDI_ProcessUpdateCfgRsp, /* WDI_UPDATE_CFG_RESP */ + + /* BA APIs*/ + WDI_ProcessAddBARsp, /* WDI_ADD_BA_RESP */ + WDI_ProcessTriggerBARsp, /* WDI_TRIGGER_BA_RESP */ + + /* IBSS APIs*/ + WDI_ProcessUpdateBeaconParamsRsp, /* WDI_UPD_BCON_PRMS_RSP */ + WDI_ProcessSendBeaconParamsRsp, /* WDI_SND_BCON_RSP */ + + /*Soft AP APIs*/ + WDI_ProcessUpdateProbeRspTemplateRsp,/*WDI_UPD_PROBE_RSP_TEMPLATE_RESP */ + WDI_ProcessSetStaBcastKeyRsp, /*WDI_SET_STA_BCAST_KEY_RESP */ + WDI_ProcessRemoveStaBcastKeyRsp, /*WDI_RMV_STA_BCAST_KEY_RESP */ + WDI_ProcessSetMaxTxPowerRsp, /*WDI_SET_MAX_TX_POWER_RESP */ + + /* PowerSave APIs */ + WDI_ProcessEnterImpsRsp, /* WDI_ENTER_IMPS_RESP */ + WDI_ProcessExitImpsRsp, /* WDI_EXIT_IMPS_RESP */ + WDI_ProcessEnterBmpsRsp, /* WDI_ENTER_BMPS_RESP */ + WDI_ProcessExitBmpsRsp, /* WDI_EXIT_BMPS_RESP */ + WDI_ProcessEnterUapsdRsp, /* WDI_ENTER_UAPSD_RESP */ + WDI_ProcessExitUapsdRsp, /* WDI_EXIT_UAPSD_RESP */ + WDI_ProcessSetUapsdAcParamsRsp, /* WDI_SET_UAPSD_PARAM_RESP */ + WDI_ProcessUpdateUapsdParamsRsp, /* WDI_UPDATE_UAPSD_PARAM_RESP */ + WDI_ProcessConfigureRxpFilterRsp,/* WDI_CONFIGURE_RXP_FILTER_RESP */ + WDI_ProcessSetBeaconFilterRsp, /* WDI_SET_BEACON_FILTER_RESP */ + WDI_ProcessRemBeaconFilterRsp, /* WDI_REM_BEACON_FILTER_RESP */ + WDI_ProcessSetRSSIThresoldsRsp, /* WDI_SET_RSSI_THRESHOLDS_RESP */ + WDI_ProcessHostOffloadRsp, /* WDI_HOST_OFFLOAD_RESP */ + WDI_ProcessWowlAddBcPtrnRsp, /* WDI_WOWL_ADD_BC_PTRN_RESP */ + WDI_ProcessWowlDelBcPtrnRsp, /* WDI_WOWL_DEL_BC_PTRN_RESP */ + WDI_ProcessWowlEnterRsp, /* WDI_WOWL_ENTER_RESP */ + WDI_ProcessWowlExitRsp, /* WDI_WOWL_EXIT_RESP */ + WDI_ProcessConfigureAppsCpuWakeupStateRsp, /* WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP */ + + + WDI_ProcessNvDownloadRsp, /* WDI_NV_DOWNLOAD_RESP*/ + + WDI_ProcessFlushAcRsp, /* WDI_FLUSH_AC_RESP */ + WDI_ProcessBtAmpEventRsp, /* WDI_BTAMP_EVENT_RESP */ +#ifdef WLAN_FEATURE_VOWIFI_11R + WDI_ProcessAggrAddTSpecRsp, /* WDI_AGGR_ADD_TS_RESP */ +#else + NULL, +#endif /* WLAN_FEATURE_VOWIFI_11R */ + WDI_ProcessAddSTASelfRsp, /* WDI_ADD_STA_SELF_RESP */ + WDI_ProcessDelSTASelfRsp, /* WDI_DEL_STA_SELF_RESP */ +#ifdef FEATURE_OEM_DATA_SUPPORT + WDI_ProcessStartOemDataRsp, /*WDI_START_OEM_DATA_RESP*/ +#else + NULL, +#endif /*FEATURE_OEM_DATA_SUPPORT*/ + WDI_ProcessHostResumeRsp, /*WDI_HOST_RESUME_RESP*/ + + WDI_ProcessP2PGONOARsp, /*WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP */ + + WDI_ProcessFTMCommandRsp, /* WDI_FTM_CMD_RESP */ + + WDI_ProcessKeepAliveRsp, /* WDI_KEEP_ALIVE_RESP */ + +#ifdef FEATURE_WLAN_SCAN_PNO + WDI_ProcessSetPreferredNetworkRsp, /* WDI_SET_PREF_NETWORK_RESP */ + WDI_ProcessSetRssiFilterRsp, /* WDI_SET_RSSI_FILTER_RESP */ + WDI_ProcessUpdateScanParamsRsp, /* WDI_UPDATE_SCAN_PARAMS_RESP */ +#else + NULL, + NULL, + NULL, +#endif // FEATURE_WLAN_SCAN_PNO + + WDI_ProcessSetTxPerTrackingRsp, /* WDI_SET_TX_PER_TRACKING_RESP */ + /*--------------------------------------------------------------------- + Indications + ---------------------------------------------------------------------*/ +#ifdef WLAN_FEATURE_PACKET_FILTERING + /* WDI_8023_MULTICAST_LIST_RESP */ + WDI_Process8023MulticastListRsp, + /* WDI_RECEIVE_FILTER_SET_FILTER_RESP */ + WDI_ProcessReceiveFilterSetFilterRsp, + /* WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP */ + WDI_ProcessFilterMatchCountRsp, + /* WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP */ + WDI_ProcessReceiveFilterClearFilterRsp, +#else + NULL, + NULL, + NULL, + NULL, +#endif // WLAN_FEATURE_PACKET_FILTERING + + WDI_ProcessHALDumpCmdRsp, /* WDI_HAL_DUMP_CMD_RESP */ + WDI_ProcessShutdownRsp, /* WDI_SHUTDOWN_RESP */ + + WDI_ProcessSetPowerParamsRsp, /*WDI_SET_POWER_PARAMS_RESP*/ +#ifdef FEATURE_WLAN_ESE + WDI_ProcessTsmStatsRsp, /* WDI_TSM_STATS_RESP */ +#else + NULL, +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + WDI_ProcessGtkOffloadRsp, /* WDI_GTK_OFFLOAD_RESP */ + WDI_ProcessGTKOffloadGetInfoRsp, /* WDI_GTK_OFFLOAD_GETINFO_RESP */ +#else + NULL, + NULL, +#endif // WLAN_FEATURE_GTK_OFFLOAD + WDI_ProcessSetTmLevelRsp, /* WDI_SET_TM_LEVEL_RESP */ + WDI_ProcessFeatureCapsExchangeRsp, /* WDI_FEATURE_CAPS_EXCHANGE_RESP */ +#ifdef WLAN_FEATURE_11AC + WDI_ProcessUpdateVHTOpModeRsp, /* WDI_UPDATE_VHT_OP_MODE_RESP */ +#else + NULL, +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + WDI_ProcessGetRoamRssiRsp, /* WDI_GET_ROAM_RSSI_RESP */ +#else + NULL, +#endif + WDI_ProcessSetTxPowerRsp, /* WDI_SET_TX_POWER_RESP */ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WDI_ProcessRoamScanOffloadRsp, /* WDI_ROAM_SCAN_OFFLOAD_RESP */ +#else + NULL, +#endif +#ifdef FEATURE_WLAN_TDLS + WDI_ProcessLinkEstablishReqRsp, /*WDI_TDLS_LINK_ESTABLISH_REQ_RESP*/ +#else + NULL, +#endif +#ifdef FEATURE_WLAN_LPHB + WDI_ProcessLphbCfgRsp, /* WDI_LPHB_CFG_RESP */ +#else + NULL, +#endif /* FEATURE_WLAN_LPHB */ +#ifdef WLAN_FEATURE_RMC + WDI_ProcessRMCRulerResp, /* WDI_RMC_RULER_RESP */ +#else + NULL, +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_RMC + WDI_ProcessIbssPeerInfoRsp, /* WDI_HAL_GET_IBSS_PEER_INFO_RSP */ +#else + NULL, +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + WDI_ProcessSetBatchScanRsp, /* WDI_SET_BATCH_SCAN_RESP */ +#else + NULL, +#endif /*FEATURE_WLAN_BATCH_SCAN*/ + WDI_ProcessSetMaxTxPowerPerBandRsp, /* WDI_SET_MAX_TX_POWER_PER_BAND_RSP */ + + WDI_ProcessUpdateChanRsp, /* WDI_UPDATE_CHAN_RESP */ + + WDI_ProcessChannelSwitchRsp_V1, /* WDI_CH_SWITCH_RESP_V1 */ + + WDI_ProcessGetBcnMissRateRsp, /*WDI_GET_BCN_MISS_RATE_RSP*/ + + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_ProcessLLStatsSetRsp, /* WDI_LL_STATS_SET_RSP */ + WDI_ProcessLLStatsGetRsp, /* WDI_LL_STATS_GET_RSP */ + WDI_ProcessLLStatsClearRsp, /* WDI_LL_STATS_CLEAR_RSP */ +#else + NULL, + NULL, + NULL, +#endif +#ifdef WLAN_FEATURE_EXTSCAN + WDI_ProcessEXTScanStartRsp, /* WDI_EXTSCAN_START_RSP */ + WDI_ProcessEXTScanStopRsp, /* WDI_EXTSCAN_STOP_RSP */ + WDI_ProcessEXTScanGetCachedResultsRsp, /* WDI_EXTSCAN_GET_CACHED_RESULTS_RSP */ + WDI_ProcessEXTScanGetCapabilitiesRsp, /* WDI_EXTSCAN_GET_CAPABILITIES_RSP */ + WDI_ProcessEXTScanSetHotlistBSSIDRsp, /* WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP */ + WDI_ProcessEXTScanResetHotlistBSSIDRsp, /* WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP */ + NULL, /* maintain synchronization though SSID_HOTLIST is deprecated */ + NULL, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif /* WLAN_FEATURE_EXTSCAN */ + WDI_ProcessSpoofMacAddrRsp, /* WDI_SPOOF_MAC_ADDR_RSP */ + + WDI_ProcessGetFwStatsRsp, /*WDI_GET_FW_STATS_RSP*/ + + WDI_ProcessEncryptMsgRsp, /* WDI_ENCRYPT_MSG_RSP*/ + WDI_ProcessFWFrameLoggingInitRsp, /* WDI_FW_LOGGING_INIT_RSP*/ + WDI_ProcessGetFrameLogRsp, /* WDI_GET_FRAME_LOG_RSP*/ + + WDI_ProcessNanResponse, /* WDI_NAN_RESPONSE */ + + WDI_ProcessMonStartRsp, /* WDI_MON_START_RSP*/ + WDI_ProcessMonStopRsp, /* WDI_MON_STOP_RSP*/ + WDI_ProcessFatalEventLogsRsp, /*WDI_FATAL_EVENT_LOGGING_RSP*/ + WDI_ProcessFwrMemDumpRsp, /* WDI_FWR_MEM_DUMP_RSP */ + WDI_ProcessRssiMonitorStartRsp, /* WDI_START_RSSI_MONITOR_RSP*/ + WDI_ProcessRssiMonitorStopRsp, /* WDI_STOP_RSSI_MONITOR_RSP*/ + + WDI_ProcessWificonfigSetRsp, /* /WDI_WIFI_CONFIG_SET_RSP*/ +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + WDI_ProcessPERRoamScanOffloadRsp, /* WDI_PER_ROAM_SCAN_OFFLOAD_RSP */ + WDI_ProcessPERRoamScanTriggerRsp, /* WDI_PER_ROAM_SCAN_TRIGGER_RSP */ +#else + NULL, + NULL, +#endif +#ifdef DHCP_SERVER_OFFLOAD + wdi_dhcp_server_offload_rsp, /* WDI_DHCP_SERVER_OFFLOAD_RSP */ +#else + NULL, +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + wdi_mdns_enable_offload_rsp, /* WDI_MDNS_ENABLE_OFFLOAD_RSP */ + wdi_mdns_fqdn_offload_rsp, /* WDI_MDNS_FQDN_OFFLOAD_RSP */ + wdi_mdns_resp_offload_rsp, /* WDI_MDNS_RESP_OFFLOAD_RSP */ + wdi_get_mdns_stats_offload_rsp, /* WDI_MDNS_STATS_OFFLOAD_RSP */ +#else + NULL, + NULL, + NULL, + NULL, +#endif /* MDNS_OFFLOAD */ + wdi_get_tsf_rsp, /* WDI_CAPTURE_GET_TSF_TSTAMP_RSP */ + + /* ARP Debug Stats*/ + WDI_ProcessSetArpStatsResp, /* WDI_FW_ARP_STATS_RSP */ + WDI_ProcessGetArpStatsResp, /* WDI_FW_GET_ARP_STATS_RSP */ + + /*--------------------------------------------------------------------- + Indications + ---------------------------------------------------------------------*/ + WDI_ProcessLowRSSIInd, /* Just threshold crossing not really low WDI_HAL_RSSI_NOTIFICATION_IND */ + WDI_ProcessMissedBeaconInd, /* WDI_HAL_MISSED_BEACON_IND */ + WDI_ProcessUnkAddrFrameInd, /* WDI_HAL_UNKNOWN_ADDR2_FRAME_RX_IND */ + WDI_ProcessMicFailureInd, /* WDI_HAL_MIC_FAILURE_IND */ + WDI_ProcessFatalErrorInd, /* WDI_HAL_FATAL_ERROR_IND */ + WDI_ProcessDelSTAInd, /* WDI_HAL_DEL_STA_IND */ + + WDI_ProcessCoexInd, /* WDI_HAL_COEX_IND */ + + WDI_ProcessTxCompleteInd, /* WDI_HAL_TX_COMPLETE_IND */ + + WDI_ProcessP2pNoaAttrInd, /*WDI_HOST_NOA_ATTR_IND*/ + +#ifdef FEATURE_WLAN_SCAN_PNO + WDI_ProcessPrefNetworkFoundInd, /* WDI_HAL_PREF_NETWORK_FOUND_IND */ +#else + NULL, +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_WAKEUP_EVENTS + WDI_ProcessWakeReasonInd, /* WDI_WAKE_REASON_IND */ +#else // WLAN_WAKEUP_EVENTS + NULL, +#endif // WLAN_WAKEUP_EVENTS + + WDI_ProcessTxPerHitInd, /* WDI_HAL_TX_PER_HIT_IND */ + + WDI_ProcessP2pNoaStartInd, /* WDI_NOA_START_IND */ +#ifdef FEATURE_WLAN_TDLS + WDI_ProcessTdlsInd, /* WDI_HAL_TDLS_IND */ +#else + NULL, +#endif + +#ifdef FEATURE_WLAN_LPHB + WDI_ProcessLphbInd, /* WDI_HAL_LPHB_IND */ +#else + NULL, +#endif /* FEATURE_WLAN_LPHB */ + + WDI_ProcessIbssPeerInactivityInd, /* WDI_HAL_IBSS_PEER_INACTIVITY_IND */ + + WDI_ProcessPeriodicTxPtrnFwInd, /* WDI_HAL_PERIODIC_TX_PTRN_FW_IND */ + +#ifdef WLAN_FEATURE_RMC + WDI_ProcessRMCUpdateIndToHost, /* WDI_RMC_UPDATE_IND_TO_HOST */ +#else + NULL, +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + WDI_ProcessBatchScanResultInd, /* WDI_BATCHSCAN_RESULT_IND */ +#else + NULL, +#endif + +#ifdef WLAN_FEATURE_RMC + WDI_ProcessTXFailInd, /*WDI_HAL_TX_FAIL_IND*/ +#else + NULL, +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_CH_AVOID + WDI_ProcessChAvoidInd, /* WDI_HAL_CH_AVOID_IND */ +#else + NULL, +#endif /* FEATURE_WLAN_CH_AVOID */ + + WDI_printRegInfo, /* WDI_PRINT_REG_INFO_IND */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + WDI_ProcessLinkLayerStatsResultsInd, /* WDI_HAL_LL_STATS_RESULTS_IND */ +#else + NULL, +#endif +#ifdef WLAN_FEATURE_EXTSCAN + WDI_ProcessEXTScanProgressInd, /* WDI_HAL_EXTSCAN_PROGRESS_IND */ + WDI_ProcessEXTScanScanAvailableInd, /* WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND */ + WDI_ProcessEXTScanResultInd, /* WDI_HAL_EXTSCAN_RESULT_IND */ + WDI_ProcessEXTScanBssidHotListResultInd, /* WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND */ + NULL, /* maintain synchronization though SSID_HOTLIST is deprecated */ +#else + NULL, + NULL, + NULL, + NULL, + NULL, +#endif /* WLAN_FEATURE_EXTSCAN */ +#ifdef FEATURE_WLAN_TDLS + WDI_ProcessChanSwitchReqRsp, /*WDI_TDLS_CHAN_SWITCH_REQ_RESP*/ +#else + NULL, +#endif + WDI_delBaInd, /* WDI_HAL_DEL_BA_IND*/ + WDI_ProcessNanEvent, /* WDI_HAL_NAN_EVENT */ + WDI_Process_LostLinkParamInd, /* WDI_HAL_LOST_LINK_PARAMS_IND*/ + WDI_Process_RssiBreachedInd, /* WDI_HAL_RSSI_BREACHED_IND */ +#ifdef FEATURE_OEM_DATA_SUPPORT + WDI_ProcessStartOemDataRspIndNew, /* WDI_HAL_START_OEM_DATA_RSP_IND_NEW */ +#else + NULL, +#endif + WDI_ProcessGetCurrentAntennaIndexRsp, /* WDI_ANTENNA_DIVERSITY_SELECTION_RSP */ +#ifdef WLAN_FEATURE_APFIND + WDI_ProcessQRFPrefNetworkFoundInd, /* WDI_HAL_QRF_PREF_NETWORK_FOUND_IND */ +#else + NULL, +#endif +}; + + +/*--------------------------------------------------------------------------- + WLAN DAL Global Control Block + ---------------------------------------------------------------------------*/ +WDI_ControlBlockType gWDICb; +static wpt_uint8 gWDIInitialized = eWLAN_PAL_FALSE; + +const wpt_uint8 szTransportChName[] = "WLAN_CTRL"; + +/*Helper routine for retrieving the PAL Context from WDI*/ +WPT_INLINE +void* WDI_GET_PAL_CTX( void ) +{ + return gWDICb.pPALContext; +}/*WDI_GET_PAL_CTX*/ + +/*============================================================================ + Helper inline converters + ============================================================================*/ +/*Convert WDI driver type into HAL driver type*/ +WPT_STATIC WPT_INLINE WDI_Status +WDI_HAL_2_WDI_STATUS +( + eHalStatus halStatus +); + +/*Convert WDI request type into HAL request type*/ +WPT_STATIC WPT_INLINE tHalHostMsgType +WDI_2_HAL_REQ_TYPE +( + WDI_RequestEnumType wdiReqType +); + +/*Convert WDI response type into HAL response type*/ +WPT_STATIC WPT_INLINE WDI_ResponseEnumType +HAL_2_WDI_RSP_TYPE +( + tHalHostMsgType halMsg +); + +/*Convert WDI driver type into HAL driver type*/ +WPT_STATIC WPT_INLINE tDriverType +WDI_2_HAL_DRV_TYPE +( + WDI_DriverType wdiDriverType +); + +/*Convert WDI stop reason into HAL stop reason*/ +WPT_STATIC WPT_INLINE tHalStopType +WDI_2_HAL_STOP_REASON +( + WDI_StopType wdiStopType +); + +/*Convert WDI scan mode type into HAL scan mode type*/ +WPT_STATIC WPT_INLINE eHalSysMode +WDI_2_HAL_SCAN_MODE +( + WDI_ScanMode wdiScanMode +); + +/*Convert WDI sec ch offset into HAL sec ch offset type*/ +WPT_STATIC WPT_INLINE ePhyChanBondState +WDI_2_HAL_SEC_CH_OFFSET +( + WDI_HTSecondaryChannelOffset wdiSecChOffset +); + +/*Convert WDI BSS type into HAL BSS type*/ +WPT_STATIC WPT_INLINE tSirBssType +WDI_2_HAL_BSS_TYPE +( + WDI_BssType wdiBSSType +); + +/*Convert WDI NW type into HAL NW type*/ +WPT_STATIC WPT_INLINE tSirNwType +WDI_2_HAL_NW_TYPE +( + WDI_NwType wdiNWType +); + +/*Convert WDI chanel bonding type into HAL cb type*/ +WPT_STATIC WPT_INLINE ePhyChanBondState +WDI_2_HAL_CB_STATE +( + WDI_PhyChanBondState wdiCbState +); + +/*Convert WDI chanel bonding type into HAL cb type*/ +WPT_STATIC WPT_INLINE tSirMacHTOperatingMode +WDI_2_HAL_HT_OPER_MODE +( + WDI_HTOperatingMode wdiHTOperMode +); + +/*Convert WDI mimo PS type into HAL mimo PS type*/ +WPT_STATIC WPT_INLINE tSirMacHTMIMOPowerSaveState +WDI_2_HAL_MIMO_PS +( + WDI_HTMIMOPowerSaveState wdiHTOperMode +); + +/*Convert WDI ENC type into HAL ENC type*/ +WPT_STATIC WPT_INLINE tAniEdType +WDI_2_HAL_ENC_TYPE +( + WDI_EncryptType wdiEncType +); + +/*Convert WDI WEP type into HAL WEP type*/ +WPT_STATIC WPT_INLINE tAniWepType +WDI_2_HAL_WEP_TYPE +( + WDI_WepType wdiWEPType +); + +/*Convert WDI Link State into HAL Link State*/ +WPT_STATIC WPT_INLINE tSirLinkState +WDI_2_HAL_LINK_STATE +( + WDI_LinkStateType wdiLinkState +); + +/*Translate a STA Context from WDI into HAL*/ +WPT_STATIC WPT_INLINE +void +WDI_CopyWDIStaCtxToHALStaCtx +( + tConfigStaParams* phalConfigSta, + WDI_ConfigStaReqInfoType* pwdiConfigSta +); + +/*Translate a Rate set info from WDI into HAL*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIRateSetToHALRateSet +( + tSirMacRateSet* pHalRateSet, + WDI_RateSet* pwdiRateSet +); + +/*Translate an EDCA Parameter Record from WDI into HAL*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIEDCAParamsToHALEDCAParams +( + tSirMacEdcaParamRecord* phalEdcaParam, + WDI_EdcaParamRecord* pWDIEdcaParam +); + +/*Copy a management frame header from WDI fmt into HAL fmt*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr +( + tSirMacMgmtHdr* pmacMgmtHdr, + WDI_MacMgmtHdr* pwdiMacMgmtHdr +); + +/*Copy config bss parameters from WDI fmt into HAL fmt*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIConfigBSSToHALConfigBSS +( + tConfigBssParams* phalConfigBSS, + WDI_ConfigBSSReqInfoType* pwdiConfigBSS +); + +/*Extract the request CB function and user data from a request structure + pointed to by user data */ +WPT_STATIC WPT_INLINE void +WDI_ExtractRequestCBFromEvent +( + WDI_EventInfoType* pEvent, + WDI_ReqStatusCb* ppfnReqCB, + void** ppUserData +); + +wpt_uint8 +WDI_FindEmptySession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType** ppSession +); + +void +WDI_AddBcastSTAtoSTATable +( + WDI_ControlBlockType* pWDICtx, + WDI_AddStaParams * staParams, + wpt_uint16 usBcastStaIdx +); + +WDI_Status WDI_SendNvBlobReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +); + +void +WDI_SetPowerStateCb +( + wpt_status status, + unsigned int dxePhyAddr, + void *pContext +); + +/** + @brief WDI_getReqMsgString prints the WDI request message in string. + + @param wdiReqMsgId: WDI Message request Id + + @see + @return Result of the function call +*/ +static char *WDI_getReqMsgString(wpt_uint16 wdiReqMsgId) +{ + switch (wdiReqMsgId) + { + CASE_RETURN_STRING( WDI_START_REQ ); + CASE_RETURN_STRING( WDI_STOP_REQ ); + CASE_RETURN_STRING( WDI_CLOSE_REQ ); + CASE_RETURN_STRING( WDI_INIT_SCAN_REQ ); + CASE_RETURN_STRING( WDI_START_SCAN_REQ ); + CASE_RETURN_STRING( WDI_END_SCAN_REQ ); + CASE_RETURN_STRING( WDI_FINISH_SCAN_REQ ); + CASE_RETURN_STRING( WDI_JOIN_REQ ); + CASE_RETURN_STRING( WDI_CONFIG_BSS_REQ ); + CASE_RETURN_STRING( WDI_DEL_BSS_REQ ); + CASE_RETURN_STRING( WDI_POST_ASSOC_REQ ); + CASE_RETURN_STRING( WDI_DEL_STA_REQ ); + CASE_RETURN_STRING( WDI_SET_BSS_KEY_REQ ); + CASE_RETURN_STRING( WDI_RMV_BSS_KEY_REQ ); + CASE_RETURN_STRING( WDI_SET_STA_KEY_REQ ); + CASE_RETURN_STRING( WDI_RMV_STA_KEY_REQ ); + CASE_RETURN_STRING( WDI_ADD_TS_REQ ); + CASE_RETURN_STRING( WDI_DEL_TS_REQ ); + CASE_RETURN_STRING( WDI_UPD_EDCA_PRMS_REQ ); + CASE_RETURN_STRING( WDI_ADD_BA_SESSION_REQ ); + CASE_RETURN_STRING( WDI_DEL_BA_REQ ); + CASE_RETURN_STRING( WDI_CH_SWITCH_REQ ); + CASE_RETURN_STRING( WDI_CH_SWITCH_REQ_V1); + CASE_RETURN_STRING( WDI_CONFIG_STA_REQ ); + CASE_RETURN_STRING( WDI_SET_LINK_ST_REQ ); + CASE_RETURN_STRING( WDI_GET_STATS_REQ ); + CASE_RETURN_STRING( WDI_UPDATE_CFG_REQ ); + CASE_RETURN_STRING( WDI_ADD_BA_REQ ); + CASE_RETURN_STRING( WDI_TRIGGER_BA_REQ ); + CASE_RETURN_STRING( WDI_UPD_BCON_PRMS_REQ ); + CASE_RETURN_STRING( WDI_SND_BCON_REQ ); + CASE_RETURN_STRING( WDI_UPD_PROBE_RSP_TEMPLATE_REQ ); + CASE_RETURN_STRING( WDI_SET_STA_BCAST_KEY_REQ ); + CASE_RETURN_STRING( WDI_RMV_STA_BCAST_KEY_REQ ); + CASE_RETURN_STRING( WDI_SET_MAX_TX_POWER_REQ ); + CASE_RETURN_STRING( WDI_SET_MAX_TX_POWER_PER_BAND_REQ ); + CASE_RETURN_STRING( WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ ); +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING( WDI_TDLS_LINK_ESTABLISH_REQ ); + CASE_RETURN_STRING( WDI_TDLS_CHAN_SWITCH_REQ ); +#endif + CASE_RETURN_STRING( WDI_ENTER_IMPS_REQ ); + CASE_RETURN_STRING( WDI_EXIT_IMPS_REQ ); + CASE_RETURN_STRING( WDI_ENTER_BMPS_REQ ); + CASE_RETURN_STRING( WDI_EXIT_BMPS_REQ ); + CASE_RETURN_STRING( WDI_ENTER_UAPSD_REQ ); + CASE_RETURN_STRING( WDI_EXIT_UAPSD_REQ ); + CASE_RETURN_STRING( WDI_SET_UAPSD_PARAM_REQ ); + CASE_RETURN_STRING( WDI_UPDATE_UAPSD_PARAM_REQ ); + CASE_RETURN_STRING( WDI_CONFIGURE_RXP_FILTER_REQ ); + CASE_RETURN_STRING( WDI_SET_BEACON_FILTER_REQ); + CASE_RETURN_STRING( WDI_REM_BEACON_FILTER_REQ ); + CASE_RETURN_STRING( WDI_SET_RSSI_THRESHOLDS_REQ ); + CASE_RETURN_STRING( WDI_HOST_OFFLOAD_REQ ); + CASE_RETURN_STRING( WDI_WOWL_ADD_BC_PTRN_REQ ); + CASE_RETURN_STRING( WDI_WOWL_DEL_BC_PTRN_REQ ); + CASE_RETURN_STRING( WDI_WOWL_ENTER_REQ ); + CASE_RETURN_STRING( WDI_WOWL_EXIT_REQ ); + CASE_RETURN_STRING( WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ ); + CASE_RETURN_STRING( WDI_NV_DOWNLOAD_REQ ); + CASE_RETURN_STRING( WDI_FLUSH_AC_REQ ); + CASE_RETURN_STRING( WDI_BTAMP_EVENT_REQ ); + CASE_RETURN_STRING( WDI_AGGR_ADD_TS_REQ ); + CASE_RETURN_STRING( WDI_ADD_STA_SELF_REQ ); + CASE_RETURN_STRING( WDI_DEL_STA_SELF_REQ ); + CASE_RETURN_STRING( WDI_FTM_CMD_REQ ); + CASE_RETURN_STRING( WDI_START_OEM_DATA_REQ ); + CASE_RETURN_STRING( WDI_HOST_RESUME_REQ ); + CASE_RETURN_STRING( WDI_KEEP_ALIVE_REQ); + #ifdef FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING( WDI_SET_PREF_NETWORK_REQ ); + CASE_RETURN_STRING( WDI_SET_RSSI_FILTER_REQ ); + CASE_RETURN_STRING( WDI_UPDATE_SCAN_PARAMS_REQ ); + #endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + CASE_RETURN_STRING( WDI_ROAM_SCAN_OFFLOAD_REQ ); +#endif + CASE_RETURN_STRING( WDI_SET_TX_PER_TRACKING_REQ ); + CASE_RETURN_STRING( WDI_8023_MULTICAST_LIST_REQ ); + CASE_RETURN_STRING( WDI_RECEIVE_FILTER_SET_FILTER_REQ ); + CASE_RETURN_STRING( WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ ); + CASE_RETURN_STRING( WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ ); + CASE_RETURN_STRING( WDI_INIT_SCAN_CON_REQ ); + CASE_RETURN_STRING( WDI_HAL_DUMP_CMD_REQ ); + CASE_RETURN_STRING( WDI_SHUTDOWN_REQ ); + CASE_RETURN_STRING( WDI_SET_POWER_PARAMS_REQ ); + CASE_RETURN_STRING( WDI_GET_BCN_MISS_RATE_REQ ); + CASE_RETURN_STRING( WDI_TRAFFIC_STATS_IND ); + CASE_RETURN_STRING( WDI_GET_ROAM_RSSI_REQ ); +#ifdef WLAN_FEATURE_11W + CASE_RETURN_STRING( WDI_EXCLUDE_UNENCRYPTED_IND ); +#endif +#ifdef FEATURE_WLAN_BATCH_SCAN + CASE_RETURN_STRING( WDI_SET_BATCH_SCAN_REQ); + CASE_RETURN_STRING( WDI_STOP_BATCH_SCAN_IND ); + CASE_RETURN_STRING( WDI_TRIGGER_BATCH_SCAN_RESULT_IND); +#endif +#ifdef WLAN_FEATURE_RMC + CASE_RETURN_STRING( WDI_TX_FAIL_MONITOR_IND ); +#endif /* WLAN_FEATURE_RMC */ + CASE_RETURN_STRING(WDI_START_HT40_OBSS_SCAN_IND); + CASE_RETURN_STRING(WDI_STOP_HT40_OBSS_SCAN_IND); + CASE_RETURN_STRING(WDI_UPDATE_CHAN_REQ); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + CASE_RETURN_STRING( WDI_LL_STATS_SET_REQ); + CASE_RETURN_STRING( WDI_LL_STATS_GET_REQ); + CASE_RETURN_STRING( WDI_LL_STATS_CLEAR_REQ); +#endif +#ifdef WLAN_FEATURE_EXTSCAN + CASE_RETURN_STRING( WDI_EXTSCAN_START_REQ); + CASE_RETURN_STRING( WDI_EXTSCAN_STOP_REQ); + CASE_RETURN_STRING( WDI_EXTSCAN_GET_CACHED_RESULTS_REQ); + CASE_RETURN_STRING( WDI_EXTSCAN_GET_CAPABILITIES_REQ); + CASE_RETURN_STRING( WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ); + CASE_RETURN_STRING( WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ); + CASE_RETURN_STRING( WDI_HIGH_PRIORITY_DATA_INFO_IND); +#endif /* WLAN_FEATURE_EXTSCAN */ + CASE_RETURN_STRING( WDI_SPOOF_MAC_ADDR_REQ); + CASE_RETURN_STRING( WDI_GET_FW_STATS_REQ); + CASE_RETURN_STRING( WDI_ENCRYPT_MSG_REQ); + CASE_RETURN_STRING( WDI_FW_LOGGING_INIT_REQ); + CASE_RETURN_STRING( WDI_GET_FRAME_LOG_REQ); + CASE_RETURN_STRING( WDI_NAN_REQUEST ); + CASE_RETURN_STRING( WDI_SET_RTS_CTS_HTVHT_IND ); + CASE_RETURN_STRING( WDI_MON_START_REQ ); + CASE_RETURN_STRING( WDI_MON_STOP_REQ ); + CASE_RETURN_STRING( WDI_FATAL_EVENT_LOGGING_REQ ); + CASE_RETURN_STRING( WDI_SEND_FREQ_RANGE_CONTROL_IND ); + CASE_RETURN_STRING( WDI_FWR_MEM_DUMP_REQ); + CASE_RETURN_STRING( WDI_START_RSSI_MONITOR_REQ ); + CASE_RETURN_STRING( WDI_STOP_RSSI_MONITOR_REQ ); + CASE_RETURN_STRING( WDI_START_OEM_DATA_REQ_IND_NEW ); + CASE_RETURN_STRING( WDI_ANTENNA_DIVERSITY_SELECTION_REQ ); + CASE_RETURN_STRING( WDI_MODIFY_ROAM_PARAMS_IND ); + CASE_RETURN_STRING( WDI_SET_ALLOWED_ACTION_FRAMES_IND ); +#ifdef SAP_AUTH_OFFLOAD + CASE_RETURN_STRING( WDI_PROCESS_SAP_AUTH_OFFLOAD_IND); +#endif +#ifdef DHCP_SERVER_OFFLOAD + CASE_RETURN_STRING( WDI_DHCP_SERVER_OFFLOAD_REQ ); +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + CASE_RETURN_STRING( WDI_MDNS_ENABLE_OFFLOAD_REQ ); + CASE_RETURN_STRING( WDI_MDNS_FQDN_OFFLOAD_REQ ); + CASE_RETURN_STRING( WDI_MDNS_RESP_OFFLOAD_REQ ); + CASE_RETURN_STRING( WDI_MDNS_STATS_OFFLOAD_REQ ); +#endif /* MDNS_OFFLOAD */ +#ifdef WLAN_FEATURE_APFIND + CASE_RETURN_STRING( WDI_SET_AP_FIND_IND ); +#endif + CASE_RETURN_STRING( WDI_FW_ARP_STATS_REQ ); + CASE_RETURN_STRING( WDI_FW_GET_ARP_STATS_REQ ); + + default: + return "Unknown WDI MessageId"; + } +} + +#ifdef DHCP_SERVER_OFFLOAD +/** + * wdi_process_dhcpserver_offload_req() - wdi api to set dhcp server offload + * @dhcp_info: pointer to dhcp server offload + * @wdi_dhcp_srv_offload_rsp_callback: response callback + * @user_data: pointer to user data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_process_dhcpserver_offload_req +( + wdi_set_dhcp_server_offload_t *dhcp_info, + wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback, + void *user_data +) +{ + WDI_EventInfoType wdi_event_data; + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + -----------------------------------------------------------------*/ + wdi_event_data.wdiRequest = WDI_DHCP_SERVER_OFFLOAD_REQ; + wdi_event_data.pEventData = dhcp_info; + wdi_event_data.uEventDataSize = sizeof(*dhcp_info); + wdi_event_data.pCBfnc = wdi_dhcp_srv_offload_rsp_callback; + wdi_event_data.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data); +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * wdi_set_mdns_offload_req() - wdi api to set mdns enable offload + * @mdns_info: pointer to dhcp server offload + * @wdi_mdns_enable_offload_rsp_callback: response callback + * @user_data: pointer to user data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_set_mdns_offload_req + +( + wdi_mdns_enable_offload_cmd_req *mdns_info, + wdi_mdns_enable_rsp_cb wdi_mdns_enable_offload_rsp_callback, + void *user_data +) +{ + WDI_EventInfoType wdi_event_data; + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + -----------------------------------------------------------------*/ + wdi_event_data.wdiRequest = WDI_MDNS_ENABLE_OFFLOAD_REQ; + wdi_event_data.pEventData = mdns_info; + wdi_event_data.uEventDataSize = sizeof(*mdns_info); + wdi_event_data.pCBfnc = wdi_mdns_enable_offload_rsp_callback; + wdi_event_data.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data); +} + +/** + * wdi_set_mdns_fqdn_req() - wdi api to set mdns fqdn request + * @fqdn_info: pointer to dhcp server offload + * @wdi_mdns_fqdn_offload_rsp_callback: response callback + * @user_data: pointer to user data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_set_mdns_fqdn_req + +( + wdi_mdns_set_fqdn_cmd_req *fqdn_info, + wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_offload_rsp_callback, + void *user_data +) +{ + WDI_EventInfoType wdi_event_data; + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + -----------------------------------------------------------------*/ + wdi_event_data.wdiRequest = WDI_MDNS_FQDN_OFFLOAD_REQ; + wdi_event_data.pEventData = fqdn_info; + wdi_event_data.uEventDataSize = sizeof(*fqdn_info); + wdi_event_data.pCBfnc = wdi_mdns_fqdn_offload_rsp_callback; + wdi_event_data.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data); +} + +/** + * wdi_set_mdns_response_req() - wdi api to mdns response + * @resp_info: pointer to mdns response + * @wdi_mdns_resp_offload_rsp_callback: response callback + * @user_data: pointer to user data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_set_mdns_response_req + +( + wdi_mdns_set_resp_req *resp_info, + wdi_mdns_resp_rsp_cb wdi_mdns_resp_offload_rsp_callback, + void *user_data +) +{ + WDI_EventInfoType wdi_event_data; + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + -----------------------------------------------------------------*/ + wdi_event_data.wdiRequest = WDI_MDNS_RESP_OFFLOAD_REQ; + wdi_event_data.pEventData = resp_info; + wdi_event_data.uEventDataSize = sizeof(*resp_info); + wdi_event_data.pCBfnc = wdi_mdns_resp_offload_rsp_callback; + wdi_event_data.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data); +} + +/** + * wdi_get_mdns_stats_req() - wdi api to get mdns stats + * @stats_info: pointer to mdns stats info + * @wdi_get_stats_offload_rsp_callback: response callback + * @user_data: pointer to user data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_get_mdns_stats_req +( + wdi_mdns_get_stats_req *stats_info, + wdi_get_stats_rsp_cb wdi_get_stats_offload_rsp_callback, + void *user_data +) +{ + WDI_EventInfoType wdi_event_data; + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + -----------------------------------------------------------------*/ + wdi_event_data.wdiRequest = WDI_MDNS_STATS_OFFLOAD_REQ; + wdi_event_data.pEventData = stats_info; + wdi_event_data.uEventDataSize = sizeof(*stats_info); + wdi_event_data.pCBfnc = wdi_get_stats_offload_rsp_callback; + wdi_event_data.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data); +} +#endif /* MDNS_OFFLOAD */ + +/** + * WDI_ProcessSetArpStatsResp() - WDI api to process set arp stats response + * @wdi_ctx: wdi context + * @event_data: event data + * + * Return: WDI_Status + */ +WDI_Status +WDI_ProcessSetArpStatsResp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_nud_set_arp_rsp_cb nud_set_arp_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + nud_set_arp_rsp_callback = + (wdi_nud_set_arp_rsp_cb)wdi_ctx->pfncRspCB; + + nud_set_arp_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + * WDI_ProcessGetArpStatsResp() - WDI api to process get arp stats response + * @wdi_ctx: wdi context + * @event_data: event data + * + * Return: WDI_Status + */ +WDI_Status +WDI_ProcessGetArpStatsResp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_nud_get_arp_rsp_cb nud_get_arp_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + nud_get_arp_rsp_callback = + (wdi_nud_get_arp_rsp_cb)wdi_ctx->pfncRspCB; + + nud_get_arp_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + + +/** + @brief WDI_getRespMsgString prints the WDI resonse message in string. + + @param wdiRespMsgId: WDI Message response Id + + @see + @return Result of the function call +*/ +static char *WDI_getRespMsgString(wpt_uint16 wdiRespMsgId) +{ + switch (wdiRespMsgId) + { + CASE_RETURN_STRING( WDI_START_RESP ); + CASE_RETURN_STRING( WDI_STOP_RESP ); + CASE_RETURN_STRING( WDI_CLOSE_RESP ); + CASE_RETURN_STRING( WDI_INIT_SCAN_RESP ); + CASE_RETURN_STRING( WDI_START_SCAN_RESP ); + CASE_RETURN_STRING( WDI_END_SCAN_RESP ); + CASE_RETURN_STRING( WDI_FINISH_SCAN_RESP ); + CASE_RETURN_STRING( WDI_JOIN_RESP ); + CASE_RETURN_STRING( WDI_CONFIG_BSS_RESP ); + CASE_RETURN_STRING( WDI_DEL_BSS_RESP ); + CASE_RETURN_STRING( WDI_POST_ASSOC_RESP ); + CASE_RETURN_STRING( WDI_DEL_STA_RESP ); + CASE_RETURN_STRING( WDI_SET_BSS_KEY_RESP ); + CASE_RETURN_STRING( WDI_RMV_BSS_KEY_RESP ); + CASE_RETURN_STRING( WDI_SET_STA_KEY_RESP ); + CASE_RETURN_STRING( WDI_RMV_STA_KEY_RESP ); + CASE_RETURN_STRING( WDI_ADD_TS_RESP ); + CASE_RETURN_STRING( WDI_DEL_TS_RESP ); + CASE_RETURN_STRING( WDI_UPD_EDCA_PRMS_RESP ); + CASE_RETURN_STRING( WDI_ADD_BA_SESSION_RESP ); + CASE_RETURN_STRING( WDI_DEL_BA_RESP ); + CASE_RETURN_STRING( WDI_CH_SWITCH_RESP ); + CASE_RETURN_STRING( WDI_CONFIG_STA_RESP ); + CASE_RETURN_STRING( WDI_SET_LINK_ST_RESP ); + CASE_RETURN_STRING( WDI_GET_STATS_RESP ); + CASE_RETURN_STRING( WDI_UPDATE_CFG_RESP ); + CASE_RETURN_STRING( WDI_ADD_BA_RESP ); + CASE_RETURN_STRING( WDI_TRIGGER_BA_RESP ); + CASE_RETURN_STRING( WDI_UPD_BCON_PRMS_RESP ); + CASE_RETURN_STRING( WDI_SND_BCON_RESP ); + CASE_RETURN_STRING( WDI_UPD_PROBE_RSP_TEMPLATE_RESP ); + CASE_RETURN_STRING( WDI_SET_STA_BCAST_KEY_RESP ); + CASE_RETURN_STRING( WDI_RMV_STA_BCAST_KEY_RESP ); + CASE_RETURN_STRING( WDI_SET_MAX_TX_POWER_RESP ); + CASE_RETURN_STRING( WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP ); +#ifdef FEATURE_WLAN_TDLS + CASE_RETURN_STRING( WDI_TDLS_LINK_ESTABLISH_REQ_RESP ); + CASE_RETURN_STRING( WDI_TDLS_CHAN_SWITCH_REQ_RESP); + CASE_RETURN_STRING( WDI_HAL_TDLS_IND ); +#endif + CASE_RETURN_STRING( WDI_ENTER_IMPS_RESP ); + CASE_RETURN_STRING( WDI_EXIT_IMPS_RESP ); + CASE_RETURN_STRING( WDI_ENTER_BMPS_RESP ); + CASE_RETURN_STRING( WDI_EXIT_BMPS_RESP ); + CASE_RETURN_STRING( WDI_ENTER_UAPSD_RESP ); + CASE_RETURN_STRING( WDI_EXIT_UAPSD_RESP ); + CASE_RETURN_STRING( WDI_SET_UAPSD_PARAM_RESP ); + CASE_RETURN_STRING( WDI_UPDATE_UAPSD_PARAM_RESP ); + CASE_RETURN_STRING( WDI_CONFIGURE_RXP_FILTER_RESP ); + CASE_RETURN_STRING( WDI_SET_BEACON_FILTER_RESP); + CASE_RETURN_STRING( WDI_REM_BEACON_FILTER_RESP ); + CASE_RETURN_STRING( WDI_SET_RSSI_THRESHOLDS_RESP ); + CASE_RETURN_STRING( WDI_HOST_OFFLOAD_RESP ); + CASE_RETURN_STRING( WDI_WOWL_ADD_BC_PTRN_RESP ); + CASE_RETURN_STRING( WDI_WOWL_DEL_BC_PTRN_RESP ); + CASE_RETURN_STRING( WDI_WOWL_ENTER_RESP ); + CASE_RETURN_STRING( WDI_WOWL_EXIT_RESP ); + CASE_RETURN_STRING( WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP ); + CASE_RETURN_STRING( WDI_NV_DOWNLOAD_RESP ); + CASE_RETURN_STRING( WDI_FLUSH_AC_RESP ); + CASE_RETURN_STRING( WDI_BTAMP_EVENT_RESP ); + CASE_RETURN_STRING( WDI_AGGR_ADD_TS_RESP ); + CASE_RETURN_STRING( WDI_ADD_STA_SELF_RESP ); + CASE_RETURN_STRING( WDI_DEL_STA_SELF_RESP ); + CASE_RETURN_STRING( WDI_FTM_CMD_RESP ); + CASE_RETURN_STRING( WDI_START_OEM_DATA_RESP ); + CASE_RETURN_STRING( WDI_HOST_RESUME_RESP ); + CASE_RETURN_STRING( WDI_KEEP_ALIVE_RESP); + #ifdef FEATURE_WLAN_SCAN_PNO + CASE_RETURN_STRING( WDI_SET_PREF_NETWORK_RESP ); + CASE_RETURN_STRING( WDI_SET_RSSI_FILTER_RESP ); + CASE_RETURN_STRING( WDI_UPDATE_SCAN_PARAMS_RESP ); + #endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + CASE_RETURN_STRING( WDI_ROAM_SCAN_OFFLOAD_RESP ); +#endif + CASE_RETURN_STRING( WDI_SET_TX_PER_TRACKING_RESP ); + CASE_RETURN_STRING( WDI_8023_MULTICAST_LIST_RESP ); + CASE_RETURN_STRING( WDI_RECEIVE_FILTER_SET_FILTER_RESP ); + CASE_RETURN_STRING( WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP ); + CASE_RETURN_STRING( WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP ); + CASE_RETURN_STRING( WDI_HAL_DUMP_CMD_RESP ); + CASE_RETURN_STRING( WDI_SHUTDOWN_RESP ); + CASE_RETURN_STRING( WDI_SET_POWER_PARAMS_RESP ); + CASE_RETURN_STRING( WDI_GET_ROAM_RSSI_RESP ); +#ifdef WLAN_FEATURE_RMC + CASE_RETURN_STRING( WDI_RMC_RULER_RESP ); + CASE_RETURN_STRING( WDI_RMC_UPDATE_IND_TO_HOST ); + + CASE_RETURN_STRING( WDI_HAL_IBSS_PEER_INFO_RSP ); +#endif /* WLAN_FEATURE_RMC */ +#ifdef FEATURE_WLAN_BATCH_SCAN + CASE_RETURN_STRING( WDI_SET_BATCH_SCAN_RESP); +#endif + CASE_RETURN_STRING( WDI_UPDATE_CHAN_RESP); + CASE_RETURN_STRING( WDI_CH_SWITCH_RESP_V1 ); + CASE_RETURN_STRING( WDI_GET_BCN_MISS_RATE_RSP ); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + CASE_RETURN_STRING( WDI_LL_STATS_SET_RSP); + CASE_RETURN_STRING( WDI_LL_STATS_GET_RSP); + CASE_RETURN_STRING( WDI_LL_STATS_CLEAR_RSP); +#endif +#ifdef WLAN_FEATURE_EXTSCAN + CASE_RETURN_STRING( WDI_EXTSCAN_START_RSP); + CASE_RETURN_STRING( WDI_EXTSCAN_STOP_RSP); + CASE_RETURN_STRING( WDI_EXTSCAN_GET_CACHED_RESULTS_RSP); + CASE_RETURN_STRING( WDI_EXTSCAN_GET_CAPABILITIES_RSP); + CASE_RETURN_STRING( WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP); + CASE_RETURN_STRING( WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP); + CASE_RETURN_STRING( WDI_HAL_EXTSCAN_PROGRESS_IND); + CASE_RETURN_STRING( WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND); + CASE_RETURN_STRING( WDI_HAL_EXTSCAN_RESULT_IND); + CASE_RETURN_STRING( WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND); +#endif /* WLAN_FEATURE_EXTSCAN */ + CASE_RETURN_STRING( WDI_GET_FW_STATS_RSP); + CASE_RETURN_STRING( WDI_ENCRYPT_MSG_RSP); + CASE_RETURN_STRING( WDI_FW_LOGGING_INIT_RSP); + CASE_RETURN_STRING( WDI_GET_FRAME_LOG_RSP); + CASE_RETURN_STRING (WDI_FATAL_EVENT_LOGGING_RSP); + CASE_RETURN_STRING( WDI_FWR_MEM_DUMP_RSP); + CASE_RETURN_STRING (WDI_START_RSSI_MONITOR_RSP); + CASE_RETURN_STRING (WDI_STOP_RSSI_MONITOR_RSP); + CASE_RETURN_STRING( WDI_WIFI_CONFIG_SET_RSP); +#ifdef FEATURE_OEM_DATA_SUPPORT + CASE_RETURN_STRING (WDI_HAL_START_OEM_DATA_RSP_IND_NEW); +#endif + CASE_RETURN_STRING (WDI_ANTENNA_DIVERSITY_SELECTION_RSP); +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + CASE_RETURN_STRING (WDI_PER_ROAM_SCAN_OFFLOAD_RSP); + CASE_RETURN_STRING (WDI_PER_ROAM_SCAN_TRIGGER_RSP); +#endif +#ifdef DHCP_SERVER_OFFLOAD + CASE_RETURN_STRING (WDI_DHCP_SERVER_OFFLOAD_RSP); +#endif /* DHCP_SERVER_OFFLOAD */ + CASE_RETURN_STRING (WDI_CAPTURE_GET_TSF_TSTAMP_RSP); + default: + return "Unknown WDI MessageId"; + } +} + +/** + @brief WDI_TraceHostFWCapabilities - Parses both host and Firmware + Capability bitmap array. + @param capabilityBitmap - Base address of a 4 element Bitmap array + of type tANI_U32. + @see + @returns None + */ +void WDI_TraceHostFWCapabilities(tANI_U32 *capabilityBitmap) +{ + int i,j; + char *pTempCapStr = NULL; + char *pCapStr = NULL; + pTempCapStr = vos_mem_malloc(MAX_FW_HOST_CAP_SIZE); + if (NULL == pTempCapStr) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Memory allocation failed for CapStr"); + return; + } + + pCapStr = pTempCapStr; + for (j = 0; j < 4; j++) { + for (i = 0; i < 32; i++) { + if ((*(capabilityBitmap + j) & (1 << i))) { + switch(i + (j * 32)) { + case MCC: snprintf(pCapStr, sizeof("MCC"), "%s", "MCC"); + pCapStr += strlen("MCC"); + break; + case P2P: snprintf(pCapStr, sizeof("P2P"), "%s", "P2P"); + pCapStr += strlen("P2P"); + break; + case DOT11AC: snprintf(pCapStr, sizeof("DOT11AC") , "%s", "DOT11AC"); + pCapStr += strlen("DOT11AC"); + break; + case SLM_SESSIONIZATION: snprintf(pCapStr, sizeof("SLM_SESSIONIZATION"), "%s", "SLM_SESSIONIZATION"); + pCapStr += strlen("SLM_SESSIONIZATION"); + break; + case DOT11AC_OPMODE: snprintf(pCapStr, sizeof("DOT11AC_OPMODE"), "%s", "DOT11AC_OPMODE"); + pCapStr += strlen("DOT11AC_OPMODE"); + break; + case SAP32STA: snprintf(pCapStr, sizeof("SAP32STA"), "%s", "SAP32STA"); + pCapStr += strlen("SAP32STA"); + break; + case TDLS: snprintf(pCapStr, sizeof("TDLS"), "%s", "TDLS"); + pCapStr += strlen("TDLS"); + break; + case P2P_GO_NOA_DECOUPLE_INIT_SCAN: snprintf(pCapStr, sizeof("P2P_GO_NOA_DECOUPLE_INIT_SCAN"), "%s", "P2P_GO_NOA_DECOUPLE_INIT_SCAN"); + pCapStr += strlen("P2P_GO_NOA_DECOUPLE_INIT_SCAN"); + break; + case WLANACTIVE_OFFLOAD: snprintf(pCapStr, sizeof("WLANACTIVE_OFFLOAD"), "%s", "WLANACTIVE_OFFLOAD"); + pCapStr += strlen("WLANACTIVE_OFFLOAD"); + break; + case BEACON_OFFLOAD: snprintf(pCapStr, sizeof("BEACON_OFFLOAD"), "%s","BEACON_OFFLOAD"); + pCapStr += strlen("BEACON_OFFLOAD"); + break; + case SCAN_OFFLOAD: snprintf(pCapStr, sizeof("SCAN_OFFLOAD"), "%s", "SCAN_OFFLOAD"); + pCapStr += strlen("SCAN_OFFLOAD"); + break; + case ROAM_OFFLOAD: snprintf(pCapStr, sizeof("ROAM_OFFLOAD"), "%s", "ROAM_OFFLOAD"); + pCapStr += strlen("ROAM_OFFLOAD"); + break; + case BCN_MISS_OFFLOAD: snprintf(pCapStr, sizeof("BCN_MISS_OFFLOAD"), "%s", "BCN_MISS_OFFLOAD"); + pCapStr += strlen("BCN_MISS_OFFLOAD"); + break; + case STA_POWERSAVE: snprintf(pCapStr, sizeof("STA_POWERSAVE"), "%s", "STA_POWERSAVE"); + pCapStr += strlen("STA_POWERSAVE"); + break; + case AP_UAPSD: snprintf(pCapStr, sizeof("AP_UAPSD"), "%s", "AP_UAPSD"); + pCapStr += strlen("AP_UAPSD"); + break; + case AP_DFS: snprintf(pCapStr, sizeof("AP_DFS"), "%s", "AP_DFS"); + pCapStr += strlen("AP_DFS"); + break; + case BLOCKACK: snprintf(pCapStr, sizeof("BLOCKACK"), "%s", "BLOCKACK"); + pCapStr += strlen("BLOCKACK"); + break; + case PHY_ERR: snprintf(pCapStr, sizeof("PHY_ERR"), "%s", "PHY_ERR"); + pCapStr += strlen("PHY_ERR"); + break; + case BCN_FILTER: snprintf(pCapStr, sizeof("BCN_FILTER"), "%s", "BCN_FILTER"); + pCapStr += strlen("BCN_FILTER"); + break; + case RTT: snprintf(pCapStr, sizeof("RTT"), "%s", "RTT"); + pCapStr += strlen("RTT"); + break; + case RATECTRL: snprintf(pCapStr, sizeof("RATECTRL"), "%s", "RATECTRL"); + pCapStr += strlen("RATECTRL"); + break; + case WOW: snprintf(pCapStr, sizeof("WOW"), "%s", "WOW"); + pCapStr += strlen("WOW"); + break; + case WLAN_ROAM_SCAN_OFFLOAD: snprintf(pCapStr, sizeof("WLAN_ROAM_SCAN_OFFLOAD"), "%s", "WLAN_ROAM_SCAN_OFFLOAD"); + pCapStr += strlen("WLAN_ROAM_SCAN_OFFLOAD"); + break; + case FW_IN_TX_PATH: snprintf(pCapStr, sizeof("FW_IN_TX_PATH"), "%s", "FW_IN_TX_PATH"); + pCapStr += strlen("FW_IN_TX_PATH"); + break; + case HT40_OBSS_SCAN: + snprintf(pCapStr, sizeof("HT40_OBSS_SCAN"), + "%s", "HT40_OBSS_SCAN"); + pCapStr += strlen("HT40_OBSS_SCAN"); + break; + case EXTENDED_NSOFFLOAD_SLOT: snprintf(pCapStr, + sizeof("EXTENDED_NSOFFLOAD_SLOT"), + "%s", "EXTENDED_NSOFFLOAD_SLOT"); + pCapStr += strlen("EXTENDED_NSOFFLOAD_SLOT"); + break; + case TDLS_SCAN_COEXISTENCE: snprintf(pCapStr, sizeof("TDLS_SCAN_COEXISTENCE"), "%s", "TDLS_SCAN_COEXISTENCE"); + pCapStr += strlen("TDLS_SCAN_COEXISTENCE"); + break; + case CH_SWITCH_V1: snprintf(pCapStr, sizeof("CH_SWITCH_V1"), "%s", "CH_SWITCH_V1"); + pCapStr += strlen("CH_SWITCH_V1"); + break; +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case LINK_LAYER_STATS_MEAS: snprintf(pCapStr, sizeof("LINK_LAYER_STATS_MEAS"), "%s", "LINK_LAYER_STATS_MEAS"); + pCapStr += strlen("LINK_LAYER_STATS_MEAS"); + break; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + case EXTENDED_SCAN: snprintf(pCapStr, sizeof("EXTENDED_SCAN"), "%s", "EXTENDED_SCAN"); + pCapStr += strlen("EXTENDED_SCAN"); + break; + case EXT_SCAN_ENHANCED: snprintf(pCapStr, sizeof("EXT_SCAN_ENHANCED"), "%s", "EXT_SCAN_ENHANCED"); + pCapStr += strlen("EXT_SCAN_ENHANCED"); + break; +#endif + case MU_MIMO: snprintf(pCapStr, sizeof("MU_MIMO"), "%s", "MU_MIMO"); + pCapStr += strlen("MU_MIMO"); + break; + + case DYNAMIC_WMM_PS: snprintf(pCapStr, sizeof("DYNAMIC_WMM_PS"), "%s", "DYNAMIC_WMM_PS"); + pCapStr += strlen("DYNAMIC_WMM_PS"); + break; + case FW_STATS: snprintf(pCapStr, sizeof("FW_STATS"), "%s", "FW_STATS"); + pCapStr += strlen("FW_STATS"); + break; + case MAC_SPOOFED_SCAN: snprintf(pCapStr, sizeof("MAC_SPOOFED_SCAN"), "%s", "MAC_SPOOFED_SCAN"); + pCapStr += strlen("MAC_SPOOFED_SCAN"); + break; + case WPS_PRBRSP_TMPL: snprintf(pCapStr, sizeof("WPS_PRBRSP_TMPL"), "%s", "WPS_PRBRSP_TMPL"); + pCapStr += strlen("WPS_PRBRSP_TMPL"); + break; + case BCN_IE_FLT_DELTA: snprintf(pCapStr, sizeof("BCN_IE_FLT_DELTA"), "%s", "BCN_IE_FLT_DELTA"); + pCapStr += strlen("BCN_IE_FLT_DELTA"); + break; + case MGMT_FRAME_LOGGING: snprintf(pCapStr, sizeof("MGMT_FRAME_LOGGING"), "%s", "MGMT_FRAME_LOGGING"); + pCapStr += strlen("MGMT_FRAME_LOGGING"); + break; + case BMU_ERROR_GENERIC_RECOVERY: snprintf(pCapStr, sizeof("BMU_ERROR_GENERIC_RECOVERY"), "%s", "BMU_ERROR_GENERIC_RECOVERY"); + pCapStr += strlen("BMU_ERROR_GENERIC_RECOVERY"); + break; + + case DISA: snprintf(pCapStr, sizeof("DISA"), "%s", "DISA"); + pCapStr += strlen("DISA"); + break; + + case TDLS_OFF_CHANNEL: snprintf(pCapStr, sizeof("TDLS_OFF_CHANNEL"), "%s", "TDLS_OFF_CHANNEL"); + pCapStr += strlen("TDLS_OFF_CHANNEL"); + break; + case LOGGING_ENHANCEMENT: snprintf(pCapStr, sizeof("LOGGING_ENHANCEMENT"), "%s", "LOGGING_ENHANCEMENT"); + pCapStr += strlen("LOGGING_ENHANCEMENT"); + break; + case MEMORY_DUMP_SUPPORTED:snprintf(pCapStr, sizeof("FW_MEM_DUMP_LOGGING"), "%s", "FW_MEM_DUMP_LOGGING"); + pCapStr += strlen("FW_MEM_DUMP_LOGGING"); + break; + case PER_PKT_STATS_SUPPORTED: snprintf(pCapStr, sizeof("PER_PKT_STATS_SUPPORTED"), "%s", "PER_PKT_STATS_SUPPORTED"); + pCapStr += strlen("PER_PKT_STATS_SUPPORTED"); + break; + case EXT_LL_STAT: snprintf(pCapStr, sizeof("EXT_LL_STAT"), "%s", "EXT_LL_STAT"); + pCapStr += strlen("EXT_LL_STAT"); + break; + case RTT3: snprintf(pCapStr, sizeof("RTT3"), "%s", "RTT3"); + pCapStr += strlen("RTT3"); + break; + case ANTENNA_DIVERSITY_SELECTION: + snprintf(pCapStr, + sizeof("ANTENNA_DIVERSITY_SELECTION"), "%s", + "ANTENNA_DIVERSITY_SELECTION"); + pCapStr += strlen("ANTENNA_DIVERSITY_SELECTION"); + break; + case PER_BASED_ROAMING: + snprintf(pCapStr, sizeof("PER_BASED_ROAMING"), + "%s", "PER_BASED_ROAMING"); + pCapStr += strlen("PER_BASED_ROAMING"); + break; + case SAP_MODE_WOW: + snprintf(pCapStr, sizeof("SAP_MODE_WOW"), + "%s", "SAP_MODE_WOW"); + pCapStr += strlen("SAP_MODE_WOW"); + break; + case SAP_OFFLOADS: + snprintf(pCapStr, sizeof("SAP_OFFLOADS"), + "%s", "SAP_OFFLOADS"); + pCapStr += strlen("SAP_OFFLOADS"); + break; + + case SAP_BUFF_ALLOC: + snprintf(pCapStr, sizeof("SAP_BUFF_ALLOC"), + "%s", "SAP_BUFF_ALLOC"); + pCapStr += strlen("SAP_BUFF_ALLOC"); + break; + + case MAKE_BEFORE_BREAK: + snprintf(pCapStr, sizeof("MAKE_BEFORE_BREAK"), + "%s", "MAKE_BEFORE_BREAK"); + pCapStr += strlen("MAKE_BEFORE_BREAK"); + break; + + case NUD_DEBUG: + snprintf(pCapStr, sizeof("NUD_DEBUG"), + "%s", "NUD_DEBUG"); + pCapStr += strlen("NUD_DEEBUG"); + break; + case PROBE_RSP_TEMPLATE_VER1: + snprintf(pCapStr, sizeof("PROBE_RSP_TEMPLATE_VER1"), + "%s", "PROBE_RSP_TEMPLATE_VER1"); + pCapStr += strlen("PROBE_RSP_TEMPLATE_VER1"); + break; + } + *pCapStr++ = ','; + *pCapStr++ = ' '; + } + } + } + pCapStr -= 2; + *pCapStr = '\0'; + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "\t\t%s", pTempCapStr); + if (pTempCapStr) + { + vos_mem_free(pTempCapStr); + pTempCapStr = NULL; + } +} + +/** + @brief WDI_getHALStatusMsgString prints the HAL status in string. + + @param halStatusId: HAL status Id + + @see + @return Result of the function call +*/ +static char *WDI_getHALStatusMsgString(wpt_uint16 halStatusId) +{ + switch (halStatusId) + { + CASE_RETURN_STRING( eHAL_STATUS_SUCCESS ); + CASE_RETURN_STRING( PAL_STATUS_INVAL ); + CASE_RETURN_STRING( PAL_STATUS_ALREADY ); + CASE_RETURN_STRING( PAL_STATUS_EMPTY ); + CASE_RETURN_STRING( PAL_STATUS_FAILURE ); + CASE_RETURN_STRING( eHAL_STATUS_FAILURE ); + CASE_RETURN_STRING( eHAL_STATUS_INVALID_PARAMETER ); + CASE_RETURN_STRING( eHAL_STATUS_INVALID_STAIDX ); + CASE_RETURN_STRING( eHAL_STATUS_DPU_DESCRIPTOR_TABLE_FULL ); + CASE_RETURN_STRING( eHAL_STATUS_NO_INTERRUPTS ); + CASE_RETURN_STRING( eHAL_STATUS_INTERRUPT_PRESENT ); + CASE_RETURN_STRING( eHAL_STATUS_STA_TABLE_FULL ); + CASE_RETURN_STRING( eHAL_STATUS_DUPLICATE_STA ); + CASE_RETURN_STRING( eHAL_STATUS_BSSID_INVALID ); + CASE_RETURN_STRING( eHAL_STATUS_STA_INVALID ); + CASE_RETURN_STRING( eHAL_STATUS_DUPLICATE_BSSID ); + CASE_RETURN_STRING( eHAL_STATUS_INVALID_BSSIDX ); + CASE_RETURN_STRING( eHAL_STATUS_BSSID_TABLE_FULL ); + CASE_RETURN_STRING( eHAL_STATUS_INVALID_SIGNATURE ); + CASE_RETURN_STRING( eHAL_STATUS_INVALID_KEYID ); + CASE_RETURN_STRING( eHAL_STATUS_SET_CHAN_ALREADY_ON_REQUESTED_CHAN ); + CASE_RETURN_STRING( eHAL_STATUS_UMA_DESCRIPTOR_TABLE_FULL ); + CASE_RETURN_STRING( eHAL_STATUS_DPU_MICKEY_TABLE_FULL ); + CASE_RETURN_STRING( eHAL_STATUS_BA_RX_BUFFERS_FULL ); + CASE_RETURN_STRING( eHAL_STATUS_BA_RX_MAX_SESSIONS_REACHED ); + CASE_RETURN_STRING( eHAL_STATUS_BA_RX_INVALID_SESSION_ID ); + CASE_RETURN_STRING( eHAL_STATUS_TIMER_START_FAILED ); + CASE_RETURN_STRING( eHAL_STATUS_TIMER_STOP_FAILED ); + CASE_RETURN_STRING( eHAL_STATUS_FAILED_ALLOC ); + CASE_RETURN_STRING( eHAL_STATUS_NOTIFY_BSS_FAIL ); + CASE_RETURN_STRING( eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO ); + CASE_RETURN_STRING( eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO ); + CASE_RETURN_STRING( eHAL_STATUS_FW_SEND_MSG_FAILED ); + default: + return "Unknown HAL status"; + } +} + +/** + * wdi_state_info_dump() - prints state information of wdi layer + */ +static void wdi_state_info_dump(void) +{ + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s pending commands: %d", __func__, + gWDICb.wptPendingQueue.count); + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "uGlobalState %d wdiExpectedResponse: %d", + gWDICb.uGlobalState, gWDICb.wdiExpectedResponse); +} + + +/** + * wdi_register_debug_callback() - registration function for wdi layer + * to print WDI state information + */ +static void wdi_register_debug_callback(void) +{ + vos_register_debug_callback(VOS_MODULE_ID_WDI, &wdi_state_info_dump); +} + + +/*======================================================================== + + INITIALIZATION APIs + +==========================================================================*/ + +/** + @brief WDI_Init is used to initialize the DAL. + + DAL will allocate all the resources it needs. It will open PAL, it will also + open both the data and the control transport which in their turn will open + DXE/SMD or any other drivers that they need. + + @param devHandle: pointer to the OS specific device handle + ppWDIGlobalCtx: output pointer of Global Context + pWdiDevCapability: output pointer of device capability + + @return Result of the function call +*/ +WDI_Status +WDI_Init +( + void* devHandle, + void** ppWDIGlobalCtx, + WDI_DeviceCapabilityType* pWdiDevCapability, + unsigned int driverType +) +{ + wpt_uint8 i; + wpt_status wptStatus; + WDI_Status wdiStatus; + WCTS_TransportCBsType wctsCBs; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*--------------------------------------------------------------------- + Sanity check + ---------------------------------------------------------------------*/ + if (( NULL == ppWDIGlobalCtx ) || ( NULL == pWdiDevCapability )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid input parameters in WDI_Init"); + + return WDI_STATUS_E_FAILURE; + } + + /*--------------------------------------------------------------------- + Check to see if the module has already been initialized or not + ---------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE != gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI module already initialized - return"); + + return WDI_STATUS_SUCCESS; + } + + /*Module is now initialized - this flag is to ensure the fact that multiple + init will not happen on WDI + !! - potential race does exist because read and set are not atomic, + however an atomic operation would be closely here - reanalyze if necessary*/ + gWDIInitialized = eWLAN_PAL_TRUE; + + /*Setup the control block */ + WDI_CleanCB(&gWDICb); + gWDICb.pOSContext = devHandle ; + + /*Setup the STA Table*/ + wdiStatus = WDI_STATableInit(&gWDICb); + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failure while initializing STA Table, status %d", + __func__, wdiStatus); + goto fail_STATableInit; + } + + /*------------------------------------------------------------------------ + Open the PAL + ------------------------------------------------------------------------*/ + wptStatus = wpalOpen(&gWDICb.pPALContext, devHandle); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to open PAL, status %d", + __func__, wptStatus); + goto fail_wpalOpen; + } + + /*Initialize main synchro mutex - it will be used to ensure integrity of + the main WDI Control Block*/ + wptStatus = wpalMutexInit(&gWDICb.wptMutex); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to init mutex, status %d", + __func__, wptStatus); + goto fail_mutex; + } + + /*Initialize the response timer - it will be used to time all messages + expected as response from device*/ + wptStatus = wpalTimerInit( &gWDICb.wptResponseTimer, + WDI_ResponseTimerCB, + &gWDICb); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to init response timer, status %d", + __func__, wptStatus); + goto fail_timer; + } + + wptStatus = wpalTimerInit( &gWDICb.ssrTimer, + WDI_SsrTimerCB, + &gWDICb); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to init SSR timer, status %d", + __func__, wptStatus); + goto fail_timer2; + } + /* Initialize the WDI Pending Request Queue*/ + wptStatus = wpal_list_init(&(gWDICb.wptPendingQueue)); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to init pending request queue, status %d", + __func__, wptStatus); + goto fail_pend_queue; + } + + /*Init WDI Pending Assoc Id Queue */ + wptStatus = wpal_list_init(&(gWDICb.wptPendingAssocSessionIdQueue)); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to init assoc session queue, status %d", + __func__, wptStatus); + goto fail_assoc_queue; + } + + /*Initialize the BSS sessions pending Queue */ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + wptStatus = wpal_list_init(&(gWDICb.aBSSSessions[i].wptPendingQueue)); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to init BSS %d pending queue, status %d", + __func__, i, wptStatus); + goto fail_bss_queue; + } + } + + /*Indicate the control block is sufficiently initialized for callbacks*/ + gWDICb.magic = WDI_CONTROL_BLOCK_MAGIC; + + /*------------------------------------------------------------------------ + Initialize the Data Path Utility Module + ------------------------------------------------------------------------*/ + wdiStatus = WDI_DP_UtilsInit(&gWDICb); + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to initialize the DP Util Module, status %d", + __func__, wdiStatus); + goto fail_dp_util_init; + } + + /* Init Set power state event */ + wptStatus = wpalEventInit(&gWDICb.setPowerStateEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to initialize power state event, status %d", + __func__, wptStatus); + goto fail_power_event; + } + + /* Init WCTS action event */ + wptStatus = wpalEventInit(&gWDICb.wctsActionEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to initialize WCTS action event, status %d", + __func__, wptStatus); + goto fail_wcts_event; + } + + /*------------------------------------------------------------------------ + Open the Transport Services for Control and Data + ------------------------------------------------------------------------*/ + wctsCBs.wctsNotifyCB = WDI_NotifyMsgCTSCB; + wctsCBs.wctsNotifyCBData = &gWDICb; + wctsCBs.wctsRxMsgCB = WDI_RXMsgCTSCB; + wctsCBs.wctsRxMsgCBData = &gWDICb; + + gWDICb.bCTOpened = eWLAN_PAL_FALSE; + gWDICb.wctsHandle = WCTS_OpenTransport( szTransportChName , + WDI_CT_CHANNEL_SIZE, + &wctsCBs ); + + if ( NULL == gWDICb.wctsHandle ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to open WCTS transport", __func__); + goto fail_wcts_open; + } + + gWDICb.driverMode = (tDriverType)driverType; + /* FTM mode not need to open Transport Driver */ + if(eDRIVER_TYPE_MFG != (tDriverType)driverType) + { + /*------------------------------------------------------------------------ + Open the Data Transport + ------------------------------------------------------------------------*/ + if(eWLAN_PAL_STATUS_SUCCESS != WDTS_openTransport(&gWDICb)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to open the DT Transport", __func__); + goto fail_wdts_open; + } + } + /*The WDI is initialized - set state to init */ + gWDICb.uGlobalState = WDI_INIT_ST; + gWDICb.roamDelayStatsEnabled = vos_get_roam_delay_stats_enabled(); + /*Send the context as a ptr to the global WDI Control Block*/ + *ppWDIGlobalCtx = &gWDICb; + + /*Fill in the device capabilities*/ + pWdiDevCapability->bFrameXtlSupported = eWLAN_PAL_FALSE; + pWdiDevCapability->ucMaxSTASupported = gWDICb.ucMaxStations; + pWdiDevCapability->ucMaxBSSSupported = gWDICb.ucMaxBssids; + + wdi_register_debug_callback(); + + vos_wake_lock_init(&gWDICb.find_ap_lock, "find_ap_lock"); + + return WDI_STATUS_SUCCESS; + + /* ERROR handlers + Undo everything that completed successfully */ + + fail_wdts_open: + { + wpt_status eventStatus; + + /* Closing WCTS in this scenario is tricky since it has to close + the SMD channel and then we get notified asynchronously when + the channel has been closed. So we take some of the logic from + the "normal" close procedure in WDI_Close() + */ + + eventStatus = wpalEventReset(&gWDICb.wctsActionEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to reset WCTS action event", __func__); + } + + WCTS_CloseTransport(gWDICb.wctsHandle); + + /* Wait for WCTS to close the control transport. If we were able + to reset the event flag, then we'll wait for the event, + otherwise we'll wait for a maximum amount of time required for + the channel to be closed */ + if ( eWLAN_PAL_STATUS_SUCCESS == eventStatus ) + { + eventStatus = wpalEventWait(&gWDICb.wctsActionEvent, + WDI_WCTS_ACTION_TIMEOUT); + if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to wait on WCTS action event", __func__); + } + } + else + { + wpalSleep(WDI_WCTS_ACTION_TIMEOUT); + } + } + fail_wcts_open: + wpalEventDelete(&gWDICb.wctsActionEvent); + fail_wcts_event: + wpalEventDelete(&gWDICb.setPowerStateEvent); + fail_power_event: + WDI_DP_UtilsExit(&gWDICb); + fail_dp_util_init: + gWDICb.magic = 0; + fail_bss_queue: + /* entries 0 thru i-1 were successfully initialized */ + while (0 < i) + { + i--; + wpal_list_destroy(&(gWDICb.aBSSSessions[i].wptPendingQueue)); + } + wpal_list_destroy(&(gWDICb.wptPendingAssocSessionIdQueue)); + fail_assoc_queue: + wpal_list_destroy(&(gWDICb.wptPendingQueue)); + fail_pend_queue: + wpalTimerDelete(&gWDICb.ssrTimer); + fail_timer2: + wpalTimerDelete(&gWDICb.wptResponseTimer); + fail_timer: + wpalMutexDelete(&gWDICb.wptMutex); + fail_mutex: + wpalClose(gWDICb.pPALContext); + fail_wpalOpen: + WDI_STATableClose(&gWDICb); + fail_STATableInit: + gWDIInitialized = eWLAN_PAL_FALSE; + + return WDI_STATUS_E_FAILURE; + +}/*WDI_Init*/; + +/** + @brief WDI_Start will be called when the upper MAC is ready to + commence operation with the WLAN Device. Upon the call + of this API the WLAN DAL will pack and send a HAL Start + message to the lower RIVA sub-system if the SMD channel + has been fully opened and the RIVA subsystem is up. + + If the RIVA sub-system is not yet up and running DAL + will queue the request for Open and will wait for the + SMD notification before attempting to send down the + message to HAL. + + WDI_Init must have been called. + + @param wdiStartParams: the start parameters as specified by + the Device Interface + + wdiStartRspCb: callback for passing back the response of + the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_Start +( + WDI_StartReqParamsType* pwdiStartParams, + WDI_StartRspCb wdiStartRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_START_REQ; + wdiEventData.pEventData = pwdiStartParams; + wdiEventData.uEventDataSize = sizeof(*pwdiStartParams); + wdiEventData.pCBfnc = wdiStartRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_Start*/ + +/** + @brief WDI_Stop will be called when the upper MAC is ready to + stop any operation with the WLAN Device. Upon the call + of this API the WLAN DAL will pack and send a HAL Stop + message to the lower RIVA sub-system if the DAL Core is + in started state. + + In state BUSY this request will be queued. + + Request will not be accepted in any other state. + + WDI_Start must have been called. + + @param wdiStopParams: the stop parameters as specified by + the Device Interface + + wdiStopRspCb: callback for passing back the response of + the stop operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_Stop +( + WDI_StopReqParamsType* pwdiStopParams, + WDI_StopRspCb wdiStopRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + WDI_ControlBlockType* pWDICtx = &gWDICb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*Access to the global state must be locked before cleaning */ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*Clear all pending request*/ + WDI_ClearPendingRequests(pWDICtx); + + /*We have completed cleaning unlock now*/ + wpalMutexRelease(&pWDICtx->wptMutex); + + /* Free the global variables */ + wpalMemoryFree(gpHostWlanFeatCaps); + wpalMemoryFree(gpFwWlanFeatCaps); + gpHostWlanFeatCaps = NULL; + gpFwWlanFeatCaps = NULL; + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_STOP_REQ; + wdiEventData.pEventData = pwdiStopParams; + wdiEventData.uEventDataSize = sizeof(*pwdiStopParams); + wdiEventData.pCBfnc = wdiStopRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_STOP_EVENT, &wdiEventData); + +}/*WDI_Stop*/ + + + +/** + @brief WDI_Close will be called when the upper MAC no longer + needs to interact with DAL. DAL will free its control + block. + + It is only accepted in state STOPPED. + + WDI_Stop must have been called. + + @param none + + @see WDI_Stop + @return Result of the function call +*/ +WDI_Status +WDI_Close +( + void +) +{ + wpt_uint8 i; + WDI_EventInfoType wdiEventData; + wpt_status wptStatus; + wpt_status eventStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*Reset WCTS action event prior to posting the WDI_CLOSE_REQ + (the control transport will be closed by the FSM and we'll want + to wait until that completes)*/ + eventStatus = wpalEventReset(&gWDICb.wctsActionEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to reset WCTS action event", __func__); + /* fall through and try to finish closing via the FSM */ + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CLOSE_REQ; + wdiEventData.pEventData = NULL; + wdiEventData.uEventDataSize = 0; + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + gWDIInitialized = eWLAN_PAL_FALSE; + + wptStatus = WDI_PostMainEvent(&gWDICb, WDI_CLOSE_EVENT, &wdiEventData); + + /*Wait for WCTS to close the control transport + (but only if we were able to reset the event flag*/ + if ( eWLAN_PAL_STATUS_SUCCESS == eventStatus ) + { + eventStatus = wpalEventWait(&gWDICb.wctsActionEvent, + WDI_WCTS_ACTION_TIMEOUT); + if ( eWLAN_PAL_STATUS_SUCCESS != eventStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to wait on WCTS action event", __func__); + } + } + + /* Destroy the WCTS action event */ + wptStatus = wpalEventDelete(&gWDICb.wctsActionEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Close failed to destroy an event"); + WDI_ASSERT(0); + } + + /* Destroy the Set Power State event */ + wptStatus = wpalEventDelete(&gWDICb.setPowerStateEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Close failed to destroy an event"); + + WDI_ASSERT(0); + } + + /*------------------------------------------------------------------------ + Closes the Data Path Utility Module + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_DP_UtilsExit(&gWDICb)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to close the DP Util Module"); + + WDI_ASSERT(0); + } + + /*destroy the BSS sessions pending Queue */ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + wpal_list_destroy(&(gWDICb.aBSSSessions[i].wptPendingQueue)); + } + + /* destroy the WDI Pending Assoc Id Request Queue*/ + wpal_list_destroy(&(gWDICb.wptPendingAssocSessionIdQueue)); + + /* destroy the WDI Pending Request Queue*/ + wpal_list_destroy(&(gWDICb.wptPendingQueue)); + + /*destroy the response timer */ + wptStatus = wpalTimerDelete( &gWDICb.wptResponseTimer); + + /*destroy the SSR timer */ + wptStatus = wpalTimerDelete( &gWDICb.ssrTimer); + + /*invalidate the main synchro mutex */ + wptStatus = wpalMutexDelete(&gWDICb.wptMutex); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to delete mutex %d", wptStatus); + WDI_ASSERT(0); + } + vos_wake_lock_destroy(&gWDICb.find_ap_lock); + /*Clear control block. note that this will clear the "magic" + which will inhibit all asynchronous callbacks*/ + WDI_CleanCB(&gWDICb); + + return wptStatus; + +}/*WDI_Close*/ + +/** + @brief WDI_Shutdown will be called during 'SSR shutdown' operation. + This will do most of the WDI stop & close + operations without doing any handshake with Riva + + This will also make sure that the control transport + will NOT be closed. + + This request will not be queued. + + + WDI_Start must have been called. + + @param closeTransport: Close control channel if this is set + + @return Result of the function call +*/ +WDI_Status +WDI_Shutdown +( + wpt_boolean closeTransport +) +{ + WDI_EventInfoType wdiEventData; + wpt_status wptStatus; + int i = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SHUTDOWN_REQ; + wdiEventData.pEventData = NULL; + wdiEventData.uEventDataSize = 0; + + /* Shutdown will not be queued, if the state is busy timer will be + * stopped & this message will be processed.*/ + wptStatus = WDI_PostMainEvent(&gWDICb, WDI_SHUTDOWN_EVENT, &wdiEventData); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Failed to process shutdown event", __func__); + } + /* Destroy the Set Power State event */ + wptStatus = wpalEventDelete(&gWDICb.setPowerStateEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Close failed to destroy an event"); + + WDI_ASSERT(0); + } + /*------------------------------------------------------------------------ + Closes the Data Path Utility Module + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_DP_UtilsExit(&gWDICb)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to close the DP Util Module"); + + WDI_ASSERT(0); + } + if ( closeTransport ) + { + /* Close control transport, called from module unload */ + WCTS_CloseTransport(gWDICb.wctsHandle); + } + else + { + /* Riva is crashed then SMD is already closed so cleaning all + the pending messages in the transport queue */ + WCTS_ClearPendingQueue(gWDICb.wctsHandle); + } + /*destroy the BSS sessions pending Queue */ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + wpal_list_destroy(&(gWDICb.aBSSSessions[i].wptPendingQueue)); + } + + /* destroy the WDI Pending Assoc Id Request Queue*/ + wpal_list_destroy(&(gWDICb.wptPendingAssocSessionIdQueue)); + /* destroy the WDI Pending Request Queue*/ + wpal_list_destroy(&(gWDICb.wptPendingQueue)); + /*destroy the response timer */ + wptStatus = wpalTimerDelete( &gWDICb.wptResponseTimer); + /*destroy the SSR timer */ + wptStatus = wpalTimerDelete( &gWDICb.ssrTimer); + + /*invalidate the main synchro mutex */ + wptStatus = wpalMutexDelete(&gWDICb.wptMutex); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Failed to delete mutex %d", __func__, wptStatus); + WDI_ASSERT(0); + } + vos_wake_lock_destroy(&gWDICb.find_ap_lock); + /* Free the global variables */ + wpalMemoryFree(gpHostWlanFeatCaps); + wpalMemoryFree(gpFwWlanFeatCaps); + gpHostWlanFeatCaps = NULL; + gpFwWlanFeatCaps = NULL; + /*Clear control block. note that this will clear the "magic" + which will inhibit all asynchronous callbacks*/ + WDI_CleanCB(&gWDICb); + return wptStatus; + +}/*WDI_Shutdown*/ + + +/*======================================================================== + + SCAN APIs + +==========================================================================*/ + +/** + @brief WDI_InitScanReq will be called when the upper MAC wants + the WLAN Device to get ready for a scan procedure. Upon + the call of this API the WLAN DAL will pack and send a + HAL Init Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiInitScanParams: the init scan parameters as specified + by the Device Interface + + wdiInitScanRspCb: callback for passing back the response + of the init scan operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_InitScanReq +( + WDI_InitScanReqParamsType* pwdiInitScanParams, + WDI_InitScanRspCb wdiInitScanRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_INIT_SCAN_REQ; + wdiEventData.pEventData = pwdiInitScanParams; + wdiEventData.uEventDataSize = sizeof(*pwdiInitScanParams); + wdiEventData.pCBfnc = wdiInitScanRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_InitScanReq*/ + +/** + @brief WDI_StartScanReq will be called when the upper MAC + wishes to change the Scan channel on the WLAN Device. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_InitScanReq must have been called. + + @param wdiStartScanParams: the start scan parameters as + specified by the Device Interface + + wdiStartScanRspCb: callback for passing back the + response of the start scan operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_InitScanReq + @return Result of the function call +*/ +WDI_Status +WDI_StartScanReq +( + WDI_StartScanReqParamsType* pwdiStartScanParams, + WDI_StartScanRspCb wdiStartScanRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_START_SCAN_REQ; + wdiEventData.pEventData = pwdiStartScanParams; + wdiEventData.uEventDataSize = sizeof(*pwdiStartScanParams); + wdiEventData.pCBfnc = wdiStartScanRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_StartScanReq*/ + + +/** + @brief WDI_EndScanReq will be called when the upper MAC is + wants to end scanning for a particular channel that it + had set before by calling Scan Start on the WLAN Device. + Upon the call of this API the WLAN DAL will pack and + send a HAL End Scan request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_StartScanReq must have been called. + + @param wdiEndScanParams: the end scan parameters as specified + by the Device Interface + + wdiEndScanRspCb: callback for passing back the response + of the end scan operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_StartScanReq + @return Result of the function call +*/ +WDI_Status +WDI_EndScanReq +( + WDI_EndScanReqParamsType* pwdiEndScanParams, + WDI_EndScanRspCb wdiEndScanRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_END_SCAN_REQ; + wdiEventData.pEventData = pwdiEndScanParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEndScanParams); + wdiEventData.pCBfnc = wdiEndScanRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_EndScanReq*/ + + +/** + @brief WDI_FinishScanReq will be called when the upper MAC has + completed the scan process on the WLAN Device. Upon the + call of this API the WLAN DAL will pack and send a HAL + Finish Scan Request request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_InitScanReq must have been called. + + @param wdiFinishScanParams: the finish scan parameters as + specified by the Device Interface + + wdiFinishScanRspCb: callback for passing back the + response of the finish scan operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_InitScanReq + @return Result of the function call +*/ +WDI_Status +WDI_FinishScanReq +( + WDI_FinishScanReqParamsType* pwdiFinishScanParams, + WDI_FinishScanRspCb wdiFinishScanRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FINISH_SCAN_REQ; + wdiEventData.pEventData = pwdiFinishScanParams; + wdiEventData.uEventDataSize = sizeof(*pwdiFinishScanParams); + wdiEventData.pCBfnc = wdiFinishScanRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_FinishScanReq*/ + +/*======================================================================== + + ASSOCIATION APIs + +==========================================================================*/ + +/** + @brief WDI_JoinReq will be called when the upper MAC is ready + to start an association procedure to a BSS. Upon the + call of this API the WLAN DAL will pack and send a HAL + Join request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiJoinParams: the join parameters as specified by + the Device Interface + + wdiJoinRspCb: callback for passing back the response of + the join operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_JoinReq +( + WDI_JoinReqParamsType* pwdiJoinParams, + WDI_JoinRspCb wdiJoinRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_JOIN_REQ; + wdiEventData.pEventData = pwdiJoinParams; + wdiEventData.uEventDataSize = sizeof(*pwdiJoinParams); + wdiEventData.pCBfnc = wdiJoinRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_JoinReq*/ + +/** + @brief WDI_ConfigBSSReq will be called when the upper MAC + wishes to configure the newly acquired or in process of + being acquired BSS to the HW . Upon the call of this API + the WLAN DAL will pack and send a HAL Config BSS request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiConfigBSSParams: the config BSS parameters as + specified by the Device Interface + + wdiConfigBSSRspCb: callback for passing back the + response of the config BSS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinReq + @return Result of the function call +*/ +WDI_Status +WDI_ConfigBSSReq +( + WDI_ConfigBSSReqParamsType* pwdiConfigBSSParams, + WDI_ConfigBSSRspCb wdiConfigBSSRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CONFIG_BSS_REQ; + wdiEventData.pEventData = pwdiConfigBSSParams; + wdiEventData.uEventDataSize = sizeof(*pwdiConfigBSSParams); + wdiEventData.pCBfnc = wdiConfigBSSRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_ConfigBSSReq*/ + +/** + @brief WDI_DelBSSReq will be called when the upper MAC is + disassociating from the BSS and wishes to notify HW. + Upon the call of this API the WLAN DAL will pack and + send a HAL Del BSS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_ConfigBSSReq or WDI_PostAssocReq must have been called. + + @param wdiDelBSSParams: the del BSS parameters as specified by + the Device Interface + + wdiDelBSSRspCb: callback for passing back the response + of the del bss operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_ConfigBSSReq, WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelBSSReq +( + WDI_DelBSSReqParamsType* pwdiDelBSSParams, + WDI_DelBSSRspCb wdiDelBSSRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_DEL_BSS_REQ; + wdiEventData.pEventData = pwdiDelBSSParams; + wdiEventData.uEventDataSize = sizeof(*pwdiDelBSSParams); + wdiEventData.pCBfnc = wdiDelBSSRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_DelBSSReq*/ + +/** + @brief WDI_PostAssocReq will be called when the upper MAC has + associated to a BSS and wishes to configure HW for + associated state. Upon the call of this API the WLAN DAL + will pack and send a HAL Post Assoc request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinReq must have been called. + + @param wdiPostAssocReqParams: the assoc parameters as specified + by the Device Interface + + wdiPostAssocRspCb: callback for passing back the + response of the post assoc operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinReq + @return Result of the function call +*/ +WDI_Status +WDI_PostAssocReq +( + WDI_PostAssocReqParamsType* pwdiPostAssocReqParams, + WDI_PostAssocRspCb wdiPostAssocRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_POST_ASSOC_REQ; + wdiEventData.pEventData = pwdiPostAssocReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiPostAssocReqParams); + wdiEventData.pCBfnc = wdiPostAssocRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_PostAssocReq*/ + +/** + @brief WDI_DelSTAReq will be called when the upper MAC when an + association with another STA has ended and the station + must be deleted from HW. Upon the call of this API the + WLAN DAL will pack and send a HAL Del STA request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiDelSTAParams: the Del STA parameters as specified by + the Device Interface + + wdiDelSTARspCb: callback for passing back the response + of the del STA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelSTAReq +( + WDI_DelSTAReqParamsType* pwdiDelSTAParams, + WDI_DelSTARspCb wdiDelSTARspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_DEL_STA_REQ; + wdiEventData.pEventData = pwdiDelSTAParams; + wdiEventData.uEventDataSize = sizeof(*pwdiDelSTAParams); + wdiEventData.pCBfnc = wdiDelSTARspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_DelSTAReq*/ + +/*======================================================================== + + SECURITY APIs + +==========================================================================*/ + +/** + @brief WDI_SetBSSKeyReq will be called when the upper MAC wants to + install a BSS encryption key on the HW. Upon the call of this + API the WLAN DAL will pack and send a Set BSS Key request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSetBSSKeyParams: the BSS Key set parameters as + specified by the Device Interface + + wdiSetBSSKeyRspCb: callback for passing back the + response of the set BSS Key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetBSSKeyReq +( + WDI_SetBSSKeyReqParamsType* pwdiSetBSSKeyParams, + WDI_SetBSSKeyRspCb wdiSetBSSKeyRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_BSS_KEY_REQ; + wdiEventData.pEventData = pwdiSetBSSKeyParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetBSSKeyParams); + wdiEventData.pCBfnc = wdiSetBSSKeyRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetBSSKeyReq*/ + +/** + @brief WDI_RemoveBSSKeyReq will be called when the upper MAC wants to + uninstall a BSS key from HW. Upon the call of this API the + WLAN DAL will pack and send a HAL Remove BSS Key request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetBSSKeyReq must have been called. + + @param wdiRemoveBSSKeyParams: the remove BSS key parameters as + specified by the Device Interface + + wdiRemoveBSSKeyRspCb: callback for passing back the + response of the remove BSS key operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetBSSKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveBSSKeyReq +( + WDI_RemoveBSSKeyReqParamsType* pwdiRemoveBSSKeyParams, + WDI_RemoveBSSKeyRspCb wdiRemoveBSSKeyRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RMV_BSS_KEY_REQ; + wdiEventData.pEventData = pwdiRemoveBSSKeyParams; + wdiEventData.uEventDataSize = sizeof(*pwdiRemoveBSSKeyParams); + wdiEventData.pCBfnc = wdiRemoveBSSKeyRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_RemoveBSSKeyReq*/ + + +/** + @brief WDI_SetSTAKeyReq will be called when the upper MAC is + ready to install a STA(ast) encryption key in HW. Upon + the call of this API the WLAN DAL will pack and send a + HAL Set STA Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSetSTAKeyParams: the set STA key parameters as + specified by the Device Interface + + wdiSetSTAKeyRspCb: callback for passing back the + response of the set STA key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetSTAKeyReq +( + WDI_SetSTAKeyReqParamsType* pwdiSetSTAKeyParams, + WDI_SetSTAKeyRspCb wdiSetSTAKeyRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_STA_KEY_REQ; + wdiEventData.pEventData = pwdiSetSTAKeyParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetSTAKeyParams); + wdiEventData.pCBfnc = wdiSetSTAKeyRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetSTAKeyReq*/ + + +/** + @brief WDI_RemoveSTAKeyReq will be called when the upper MAC + wants to uninstall a previously set STA key in HW. Upon + the call of this API the WLAN DAL will pack and send a + HAL Remove STA Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTAKeyReq must have been called. + + @param wdiRemoveSTAKeyParams: the remove STA key parameters as + specified by the Device Interface + + wdiRemoveSTAKeyRspCb: callback for passing back the + response of the remove STA key operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetSTAKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveSTAKeyReq +( + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTAKeyParams, + WDI_RemoveSTAKeyRspCb wdiRemoveSTAKeyRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RMV_STA_KEY_REQ; + wdiEventData.pEventData = pwdiRemoveSTAKeyParams; + wdiEventData.uEventDataSize = sizeof(*pwdiRemoveSTAKeyParams); + wdiEventData.pCBfnc = wdiRemoveSTAKeyRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_RemoveSTAKeyReq*/ + + +/** + @brief WDI_SetSTABcastKeyReq will be called when the upper MAC + wants to install a STA Bcast encryption key on the HW. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiSetSTABcastKeyParams: the BSS Key set parameters as + specified by the Device Interface + + wdiSetSTABcastKeyRspCb: callback for passing back the + response of the set BSS Key operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetSTABcastKeyReq +( + WDI_SetSTAKeyReqParamsType* pwdiSetSTABcastKeyParams, + WDI_SetSTAKeyRspCb wdiSetSTABcastKeyRspCb, + void* pUserData +) + +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_STA_BCAST_KEY_REQ; + wdiEventData.pEventData = pwdiSetSTABcastKeyParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetSTABcastKeyParams); + wdiEventData.pCBfnc = wdiSetSTABcastKeyRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetSTABcastKeyReq*/ + +/** + @brief WDI_RemoveSTABcastKeyReq will be called when the upper + MAC wants to uninstall a STA Bcast key from HW. Upon the + call of this API the WLAN DAL will pack and send a HAL + Remove STA Bcast Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTABcastKeyReq must have been called. + + @param pwdiRemoveSTABcastKeyParams: the remove BSS key + parameters as specified by the Device + Interface + + wdiRemoveSTABcastKeyRspCb: callback for passing back the + response of the remove STA Bcast key operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetSTABcastKeyReq + @return Result of the function call +*/ +WDI_Status +WDI_RemoveSTABcastKeyReq +( + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTABcastKeyParams, + WDI_RemoveSTAKeyRspCb wdiRemoveSTABcastKeyRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RMV_STA_BCAST_KEY_REQ; + wdiEventData.pEventData = pwdiRemoveSTABcastKeyParams; + wdiEventData.uEventDataSize = sizeof(*pwdiRemoveSTABcastKeyParams); + wdiEventData.pCBfnc = wdiRemoveSTABcastKeyRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_RemoveSTABcastKeyReq*/ + +/** + @brief WDI_SetMaxTxPowerReq will be called when the upper + MAC wants to set Max Tx Power to HW. Upon the + call of this API the WLAN DAL will pack and send a HAL + Remove STA Bcast Key request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_SetSTABcastKeyReq must have been called. + + @param pwdiRemoveSTABcastKeyParams: the remove BSS key + parameters as specified by the Device + Interface + + wdiRemoveSTABcastKeyRspCb: callback for passing back the + response of the remove STA Bcast key operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetMaxTxPowerReq + @return Result of the function call +*/ +WDI_Status +WDI_SetMaxTxPowerReq +( + WDI_SetMaxTxPowerParamsType* pwdiSetMaxTxPowerParams, + WDA_SetMaxTxPowerRspCb wdiReqStatusCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_MAX_TX_POWER_REQ; + wdiEventData.pEventData = pwdiSetMaxTxPowerParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetMaxTxPowerParams); + wdiEventData.pCBfnc = wdiReqStatusCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_SetMaxTxPowerPerBandReq will be called when the upper + MAC wants to set Max Tx Power to HW for specific band. + + @param pwdiSetMaxTxPowerPerBandParams: Tx Power Information + + wdiReqStatusCb: callback for passing back the + response msg from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_SetMaxTxPowerPerBandReq + @return Result of the function call +*/ +WDI_Status +WDI_SetMaxTxPowerPerBandReq +( + WDI_SetMaxTxPowerPerBandParamsType* pwdiSetMaxTxPowerPerBandParams, + WDA_SetMaxTxPowerPerBandRspCb wdiReqStatusCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_MAX_TX_POWER_PER_BAND_REQ; + wdiEventData.pEventData = pwdiSetMaxTxPowerPerBandParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetMaxTxPowerPerBandParams); + wdiEventData.pCBfnc = wdiReqStatusCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_SetTxPowerReq will be called when the upper + MAC wants to set Tx Power to HW. + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiSetTxPowerParams: set TS Power parameters + BSSID and target TX Power with dbm included + + wdiReqStatusCb: callback for passing back the response + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTxPowerReq +( + WDI_SetTxPowerParamsType* pwdiSetTxPowerParams, + WDA_SetTxPowerRspCb wdiReqStatusCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_TX_POWER_REQ; + wdiEventData.pEventData = pwdiSetTxPowerParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetTxPowerParams); + wdiEventData.pCBfnc = wdiReqStatusCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +#ifdef FEATURE_WLAN_ESE +WDI_Status +WDI_TSMStatsReq +( + WDI_TSMStatsReqParamsType* pwdiTsmReqParams, + WDI_TsmRspCb wdiReqStatusCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_TSM_STATS_REQ; + wdiEventData.pEventData = pwdiTsmReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiTsmReqParams); + wdiEventData.pCBfnc = wdiReqStatusCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} +#endif + +/*======================================================================== + + QoS and BA APIs + +==========================================================================*/ + +/** + @brief WDI_AddTSReq will be called when the upper MAC to inform + the device of a successful add TSpec negotiation. HW + needs to receive the TSpec Info from the UMAC in order + to configure properly the QoS data traffic. Upon the + call of this API the WLAN DAL will pack and send a HAL + Add TS request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddTSReq +( + WDI_AddTSReqParamsType* pwdiAddTsReqParams, + WDI_AddTsRspCb wdiAddTsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ADD_TS_REQ; + wdiEventData.pEventData = pwdiAddTsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiAddTsReqParams); + wdiEventData.pCBfnc = wdiAddTsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AddTSReq*/ + + + +/** + @brief WDI_DelTSReq will be called when the upper MAC has ended + admission on a specific AC. This is to inform HW that + QoS traffic parameters must be rest. Upon the call of + this API the WLAN DAL will pack and send a HAL Del TS + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddTSReq must have been called. + + @param wdiDelTsReqParams: the del TS parameters as specified by + the Device Interface + + wdiDelTsRspCb: callback for passing back the response of + the del TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddTSReq + @return Result of the function call +*/ +WDI_Status +WDI_DelTSReq +( + WDI_DelTSReqParamsType* pwdiDelTsReqParams, + WDI_DelTsRspCb wdiDelTsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_DEL_TS_REQ; + wdiEventData.pEventData = pwdiDelTsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiDelTsReqParams); + wdiEventData.pCBfnc = wdiDelTsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_DelTSReq*/ + + + +/** + @brief WDI_UpdateEDCAParams will be called when the upper MAC + wishes to update the EDCA parameters used by HW for QoS + data traffic. Upon the call of this API the WLAN DAL + will pack and send a HAL Update EDCA Params request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiUpdateEDCAParams: the start parameters as specified + by the Device Interface + + wdiUpdateEDCAParamsRspCb: callback for passing back the + response of the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateEDCAParams +( + WDI_UpdateEDCAParamsType* pwdiUpdateEDCAParams, + WDI_UpdateEDCAParamsRspCb wdiUpdateEDCAParamsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPD_EDCA_PRMS_REQ; + wdiEventData.pEventData = pwdiUpdateEDCAParams; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateEDCAParams); + wdiEventData.pCBfnc = wdiUpdateEDCAParamsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_UpdateEDCAParams*/ + + +/** + @brief WDI_AddBASessionReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddBASessionReq +( + WDI_AddBASessionReqParamsType* pwdiAddBASessionReqParams, + WDI_AddBASessionRspCb wdiAddBASessionRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ADD_BA_SESSION_REQ; + wdiEventData.pEventData = pwdiAddBASessionReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiAddBASessionReqParams); + wdiEventData.pCBfnc = wdiAddBASessionRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AddBASessionReq*/ + +/** + @brief WDI_DelBAReq will be called when the upper MAC wants to + inform HW that it has deleted a previously created BA + session. Upon the call of this API the WLAN DAL will + pack and send a HAL Del BA request message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddBAReq must have been called. + + @param wdiDelBAReqParams: the del BA parameters as specified by + the Device Interface + + wdiDelBARspCb: callback for passing back the response of + the del BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_DelBAReq +( + WDI_DelBAReqParamsType* pwdiDelBAReqParams, + WDI_DelBARspCb wdiDelBARspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_DEL_BA_REQ; + wdiEventData.pEventData = pwdiDelBAReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiDelBAReqParams); + wdiEventData.pCBfnc = wdiDelBARspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_DelBAReq*/ + +/*======================================================================== + + Power Save APIs + +==========================================================================*/ + +/** + @brief WDI_SetPwrSaveCfgReq will be called when the upper MAC + wants to set the power save related configurations of + the WLAN Device. Upon the call of this API the WLAN DAL + will pack and send a HAL Update CFG request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param pwdiPowerSaveCfg: the power save cfg parameters as + specified by the Device Interface + + wdiSetPwrSaveCfgCb: callback for passing back the + response of the set power save cfg operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SetPwrSaveCfgReq +( + WDI_UpdateCfgReqParamsType* pwdiPowerSaveCfg, + WDI_SetPwrSaveCfgCb wdiSetPwrSaveCfgCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPDATE_CFG_REQ; + wdiEventData.pEventData = pwdiPowerSaveCfg; + wdiEventData.uEventDataSize = sizeof(*pwdiPowerSaveCfg); + wdiEventData.pCBfnc = wdiSetPwrSaveCfgCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetPwrSaveCfgReq*/ + +/** + @brief WDI_EnterImpsReq will be called when the upper MAC to + request the device to get into IMPS power state. Upon + the call of this API the WLAN DAL will send a HAL Enter + IMPS request message to the lower RIVA sub-system if DAL + is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiEnterImpsRspCb: callback for passing back the + response of the Enter IMPS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_EnterImpsReq +( + WDI_EnterImpsReqParamsType *pwdiEnterImpsReqParams, + WDI_EnterImpsRspCb wdiEnterImpsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ENTER_IMPS_REQ; + wdiEventData.pEventData = pwdiEnterImpsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEnterImpsReqParams); + wdiEventData.pCBfnc = wdiEnterImpsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_EnterImpsReq*/ + +/** + @brief WDI_ExitImpsReq will be called when the upper MAC to + request the device to get out of IMPS power state. Upon + the call of this API the WLAN DAL will send a HAL Exit + IMPS request message to the lower RIVA sub-system if DAL + is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + + @param wdiExitImpsRspCb: callback for passing back the response + of the Exit IMPS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_ExitImpsReq +( + WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams, + WDI_ExitImpsRspCb wdiExitImpsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_EXIT_IMPS_REQ; + wdiEventData.pEventData = pwdiExitImpsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiExitImpsReqParams); + wdiEventData.pCBfnc = wdiExitImpsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_ExitImpsReq*/ + +/** + @brief WDI_EnterBmpsReq will be called when the upper MAC to + request the device to get into BMPS power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Enter BMPS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiEnterBmpsReqParams: the Enter BMPS parameters as + specified by the Device Interface + + wdiEnterBmpsRspCb: callback for passing back the + response of the Enter BMPS operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_EnterBmpsReq +( + WDI_EnterBmpsReqParamsType *pwdiEnterBmpsReqParams, + WDI_EnterBmpsRspCb wdiEnterBmpsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ENTER_BMPS_REQ; + wdiEventData.pEventData = pwdiEnterBmpsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEnterBmpsReqParams); + wdiEventData.pCBfnc = wdiEnterBmpsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_EnterBmpsReq*/ + +/** + @brief WDI_ExitBmpsReq will be called when the upper MAC to + request the device to get out of BMPS power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Exit BMPS request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiExitBmpsReqParams: the Exit BMPS parameters as + specified by the Device Interface + + wdiExitBmpsRspCb: callback for passing back the response + of the Exit BMPS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ExitBmpsReq +( + WDI_ExitBmpsReqParamsType *pwdiExitBmpsReqParams, + WDI_ExitBmpsRspCb wdiExitBmpsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_EXIT_BMPS_REQ; + wdiEventData.pEventData = pwdiExitBmpsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiExitBmpsReqParams); + wdiEventData.pCBfnc = wdiExitBmpsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_ExitBmpsReq*/ + +/** + @brief WDI_EnterUapsdReq will be called when the upper MAC to + request the device to get into UAPSD power state. Upon + the call of this API the WLAN DAL will pack and send a + HAL Enter UAPSD request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + WDI_SetUapsdAcParamsReq must have been called. + + @param pwdiEnterUapsdReqParams: the Enter UAPSD parameters as + specified by the Device Interface + + wdiEnterUapsdRspCb: callback for passing back the + response of the Enter UAPSD operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq, WDI_SetUapsdAcParamsReq + @return Result of the function call +*/ +WDI_Status +WDI_EnterUapsdReq +( + WDI_EnterUapsdReqParamsType *pwdiEnterUapsdReqParams, + WDI_EnterUapsdRspCb wdiEnterUapsdRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ENTER_UAPSD_REQ; + wdiEventData.pEventData = pwdiEnterUapsdReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEnterUapsdReqParams); + wdiEventData.pCBfnc = wdiEnterUapsdRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_EnterUapsdReq*/ + +/** + @brief WDI_ExitUapsdReq will be called when the upper MAC to + request the device to get out of UAPSD power state. Upon + the call of this API the WLAN DAL will send a HAL Exit + UAPSD request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiExitUapsdRspCb: callback for passing back the + response of the Exit UAPSD operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_ExitUapsdReq +( + WDI_ExitUapsdReqParamsType *pwdiExitUapsdReqParams, + WDI_ExitUapsdRspCb wdiExitUapsdRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_EXIT_UAPSD_REQ; + wdiEventData.pEventData = pwdiExitUapsdReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiExitUapsdReqParams); + wdiEventData.pCBfnc = wdiExitUapsdRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_ExitUapsdReq*/ + +/** + @brief WDI_UpdateUapsdParamsReq will be called when the upper + MAC wants to set the UAPSD related configurations + of an associated STA (while acting as an AP) to the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Update UAPSD params request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_ConfigBSSReq must have been called. + + @param pwdiUpdateUapsdReqParams: the UAPSD parameters + as specified by the Device Interface + + wdiUpdateUapsdParamsCb: callback for passing back the + response of the update UAPSD params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_ConfigBSSReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateUapsdParamsReq +( + WDI_UpdateUapsdReqParamsType *pwdiUpdateUapsdReqParams, + WDI_UpdateUapsdParamsCb wdiUpdateUapsdParamsCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPDATE_UAPSD_PARAM_REQ; + wdiEventData.pEventData = pwdiUpdateUapsdReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateUapsdReqParams); + wdiEventData.pCBfnc = wdiUpdateUapsdParamsCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_UpdateUapsdParamsReq*/ + +/** + @brief WDI_SetUapsdAcParamsReq will be called when the upper + MAC wants to set the UAPSD related configurations before + requesting for enter UAPSD power state to the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Set UAPSD params request message to + the lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiUapsdInfo: the UAPSD parameters as specified by + the Device Interface + + wdiSetUapsdAcParamsCb: callback for passing back the + response of the set UAPSD params operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetUapsdAcParamsReq +( + WDI_SetUapsdAcParamsReqParamsType* pwdiUapsdInfo, + WDI_SetUapsdAcParamsCb wdiSetUapsdAcParamsCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_UAPSD_PARAM_REQ; + wdiEventData.pEventData = pwdiUapsdInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiUapsdInfo); + wdiEventData.pCBfnc = wdiSetUapsdAcParamsCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetUapsdAcParamsReq*/ + +/** + @brief WDI_FWLoggingDXEdoneInd + + FW Logging DXE done Indication from the upper layer will be sent + down to HAL + + @param WDI_FWLoggingDXEdoneIndInfoType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_FWLoggingDXEdoneInd +( + wpt_uint32 data +) +{ + + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FW_LOGGING_DXE_DONE_IND; + wdiEventData.pEventData = (void *)&data; + wdiEventData.uEventDataSize = sizeof(wpt_uint32); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_FWLoggingDXEdoneInd*/ + +/** + @brief WDI_GetFrameLogReq will be called when the upper + MAC wants to initialize frame logging. Upon the call of + this API the WLAN DAL will pack and send a HAL + Frame logging init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiGetFrameLogReqInfo: the Frame Logging params + as specified by the Device Interface + + wdiGetFrameLogRspCb: callback for passing back the + response of the frame logging init operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_GetFrameLogReq +( + WDI_GetFrameLogReqInfoType *pwdiGetFrameLogReqInfo, + WDI_GetFrameLogRspCb wdiGetFrameLogRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GET_FRAME_LOG_REQ; + wdiEventData.pEventData = pwdiGetFrameLogReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiGetFrameLogReqInfo); + wdiEventData.pCBfnc = wdiGetFrameLogRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief WDI_FatalEventLogsReq will be called when the upper + MAC wants to send the flush command. Upon the call of + this API the WLAN DAL will pack and send a HAL + Fatal Event Req message to the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiFlushLogsReqInfo: the Flush Logs params + as specified by the Device Interface + + wdiFlushLogsRspCb: callback for passing back the + response of the Flush Logs operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ + +WDI_Status +WDI_FatalEventLogsReq +( + WDI_FatalEventLogsReqInfoType *pwdiFatalEventLogsReqInfo, + WDI_FatalEventLogsRspCb wdiFatalEventLogsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FATAL_EVENT_LOGGING_REQ; + wdiEventData.pEventData = pwdiFatalEventLogsReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiFatalEventLogsReqInfo); + wdiEventData.pCBfnc = wdiFatalEventLogsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} + + +/** + @brief WDI_FWLoggingInitReq will be called when the upper + MAC wants to initialize frame logging. Upon the call of + this API the WLAN DAL will pack and send a HAL + Frame logging init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiFWLoggingInitReqParams: the Frame Logging params + as specified by the Device Interface + + wdiFWLoggingInitReqCb: callback for passing back the + response of the frame logging init operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_FWLoggingInitReq +( + WDI_FWLoggingInitReqInfoType *pwdiFWLoggingInitReqInfo, + WDI_FWLoggingInitRspCb wdiFWLoggingInitRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FW_LOGGING_INIT_REQ; + wdiEventData.pEventData = pwdiFWLoggingInitReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiFWLoggingInitReqInfo); + wdiEventData.pCBfnc = wdiFWLoggingInitRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief WDI_FwrMemDumpReq will be called when the upper + MAC wants to get fwr mem dump. Upon the call of + this API the WLAN DAL will pack and send a HAL + Frame logging init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pWdiFwrMemDumpReq: the fwr mem dump req params + as specified by the Device Interface + + wdiFWLoggingInitReqCb: callback for passing back the + response of the frame logging init operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ + +WDI_Status +WDI_FwrMemDumpReq + +( + WDI_FwrMemDumpReqType *pwdiFwrMemDumpReqInfo, + WDI_FwrMemDumpCb wdiFwrMemDumpRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FWR_MEM_DUMP_REQ; + wdiEventData.pEventData = pwdiFwrMemDumpReqInfo; + wdiEventData.uEventDataSize = sizeof(WDI_FwrMemDumpReqType); + wdiEventData.pCBfnc = wdiFwrMemDumpRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + + +/** + @brief WDI_StartRssiMonitorReq will be called when the upper + MAC wants to initialize Rssi Monitor on a bssid. + Upon the call of this API the WLAN DAL will pack and + send a HAL Rssi Monitor init request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiRssiMonitorInfo: the Rssi Monitor params + as specified by the Device Interface + + wdiRssiMonitorStartRspCb: callback for passing back the + response of the rssi monitor operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StartRssiMonitorReq +( + WDI_RssiMonitorReqInfoType *pwdiRssiMonitorInfo, + WDI_RssiMonitorStartRspCb wdiRssiMonitorStartRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_START_RSSI_MONITOR_REQ; + wdiEventData.pEventData = pwdiRssiMonitorInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiRssiMonitorInfo); + wdiEventData.pCBfnc = wdiRssiMonitorStartRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_StopRssiMonitorReq will be called when the upper + MAC wants to stop Rssi Monitor on a bssid. + Upon the call of this API the WLAN DAL will pack and + send a HAL Rssi Monitor stop request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiRssiMonitorInfo: the Rssi Monitor params + as specified by the Device Interface + + wdiRssiMonitorStopRspCb: callback for passing back the + response of the rssi monitor operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StopRssiMonitorReq +( + WDI_RssiMonitorReqInfoType *pwdiRssiMonitorInfo, + WDI_RssiMonitorStopRspCb wdiRssiMonitorStopRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_STOP_RSSI_MONITOR_REQ; + wdiEventData.pEventData = pwdiRssiMonitorInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiRssiMonitorInfo); + wdiEventData.pCBfnc = wdiRssiMonitorStopRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief WDI_ConfigureRxpFilterReq will be called when the upper + MAC wants to set/reset the RXP filters for received pkts + (MC, BC etc.). Upon the call of this API the WLAN DAL will pack + and send a HAL configure RXP filter request message to + the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiConfigureRxpFilterReqParams: the RXP + filter as specified by the Device + Interface + + wdiConfigureRxpFilterCb: callback for passing back the + response of the configure RXP filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_ConfigureRxpFilterReq +( + WDI_ConfigureRxpFilterReqParamsType *pwdiConfigureRxpFilterReqParams, + WDI_ConfigureRxpFilterCb wdiConfigureRxpFilterCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CONFIGURE_RXP_FILTER_REQ; + wdiEventData.pEventData = pwdiConfigureRxpFilterReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiConfigureRxpFilterReqParams); + wdiEventData.pCBfnc = wdiConfigureRxpFilterCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_ConfigureRxpFilterReq*/ + +/** + @brief WDI_SetBeaconFilterReq will be called when the upper MAC + wants to set the beacon filters while in power save. + Upon the call of this API the WLAN DAL will pack and + send a Beacon filter request message to the + lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiBeaconFilterReqParams: the beacon + filter as specified by the Device + Interface + + wdiBeaconFilterCb: callback for passing back the + response of the set beacon filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetBeaconFilterReq +( + WDI_BeaconFilterReqParamsType *pwdiBeaconFilterReqParams, + WDI_SetBeaconFilterCb wdiBeaconFilterCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_BEACON_FILTER_REQ; + wdiEventData.pEventData = pwdiBeaconFilterReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiBeaconFilterReqParams); + wdiEventData.pCBfnc = wdiBeaconFilterCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_SetBeaconFilterReq*/ + +/** + @brief WDI_RemBeaconFilterReq will be called when the upper MAC + wants to remove the beacon filter for particular IE + while in power save. Upon the call of this API the WLAN + DAL will pack and send a remove Beacon filter request + message to the lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiBeaconFilterReqParams: the beacon + filter as specified by the Device + Interface + + wdiBeaconFilterCb: callback for passing back the + response of the remove beacon filter operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_RemBeaconFilterReq +( + WDI_RemBeaconFilterReqParamsType *pwdiBeaconFilterReqParams, + WDI_RemBeaconFilterCb wdiBeaconFilterCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_REM_BEACON_FILTER_REQ; + wdiEventData.pEventData = pwdiBeaconFilterReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiBeaconFilterReqParams); + wdiEventData.pCBfnc = wdiBeaconFilterCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_RemBeaconFilterReq*/ + +/** + @brief WDI_SetRSSIThresholdsReq will be called when the upper + MAC wants to set the RSSI thresholds related + configurations while in power save. Upon the call of + this API the WLAN DAL will pack and send a HAL Set RSSI + thresholds request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiUapsdInfo: the UAPSD parameters as specified by + the Device Interface + + wdiSetUapsdAcParamsCb: callback for passing back the + response of the set UAPSD params operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SetRSSIThresholdsReq +( + WDI_SetRSSIThresholdsReqParamsType* pwdiRSSIThresholdsParams, + WDI_SetRSSIThresholdsCb wdiSetRSSIThresholdsCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_RSSI_THRESHOLDS_REQ; + wdiEventData.pEventData = pwdiRSSIThresholdsParams; + wdiEventData.uEventDataSize = sizeof(*pwdiRSSIThresholdsParams); + wdiEventData.pCBfnc = wdiSetRSSIThresholdsCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/* WDI_SetRSSIThresholdsReq*/ + +/** + @brief WDI_HostOffloadReq will be called when the upper MAC + wants to set the filter to minimize unnecessary host + wakeup due to broadcast traffic while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL host offload request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiHostOffloadParams: the host offload as specified + by the Device Interface + + wdiHostOffloadCb: callback for passing back the response + of the host offload operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_HostOffloadReq +( + WDI_HostOffloadReqParamsType* pwdiHostOffloadParams, + WDI_HostOffloadCb wdiHostOffloadCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_HOST_OFFLOAD_REQ; + wdiEventData.pEventData = pwdiHostOffloadParams; + wdiEventData.uEventDataSize = sizeof(*pwdiHostOffloadParams); + wdiEventData.pCBfnc = wdiHostOffloadCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_HostOffloadReq*/ + +/** + @brief WDI_KeepAliveReq will be called when the upper MAC + wants to set the filter to send NULL or unsolicited ARP responses + and minimize unnecessary host wakeups due to while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL Keep Alive request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiKeepAliveParams: the Keep Alive as specified + by the Device Interface + + wdiKeepAliveCb: callback for passing back the response + of the Keep Alive operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_KeepAliveReq +( + WDI_KeepAliveReqParamsType* pwdiKeepAliveParams, + WDI_KeepAliveCb wdiKeepAliveCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI_KeepAliveReq: WDI API call before module " + "is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_KEEP_ALIVE_REQ; + wdiEventData.pEventData = pwdiKeepAliveParams; + wdiEventData.uEventDataSize = sizeof(*pwdiKeepAliveParams); + wdiEventData.pCBfnc = wdiKeepAliveCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_KeepAliveReq*/ + +/** + @brief WDI_WowlAddBcPtrnReq will be called when the upper MAC + wants to set the Wowl Bcast ptrn to minimize unnecessary + host wakeup due to broadcast traffic while in power + save. Upon the call of this API the WLAN DAL will pack + and send a HAL Wowl Bcast ptrn request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiWowlAddBcPtrnParams: the Wowl bcast ptrn as + specified by the Device Interface + + wdiWowlAddBcPtrnCb: callback for passing back the + response of the add Wowl bcast ptrn operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlAddBcPtrnReq +( + WDI_WowlAddBcPtrnReqParamsType* pwdiWowlAddBcPtrnParams, + WDI_WowlAddBcPtrnCb wdiWowlAddBcPtrnCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_WOWL_ADD_BC_PTRN_REQ; + wdiEventData.pEventData = pwdiWowlAddBcPtrnParams; + wdiEventData.uEventDataSize = sizeof(*pwdiWowlAddBcPtrnParams); + wdiEventData.pCBfnc = wdiWowlAddBcPtrnCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_WowlAddBcPtrnReq*/ + +/** + @brief WDI_WowlDelBcPtrnReq will be called when the upper MAC + wants to clear the Wowl Bcast ptrn. Upon the call of + this API the WLAN DAL will pack and send a HAL delete + Wowl Bcast ptrn request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_WowlAddBcPtrnReq must have been called. + + @param pwdiWowlDelBcPtrnParams: the Wowl bcast ptrn as + specified by the Device Interface + + wdiWowlDelBcPtrnCb: callback for passing back the + response of the del Wowl bcast ptrn operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_WowlAddBcPtrnReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlDelBcPtrnReq +( + WDI_WowlDelBcPtrnReqParamsType* pwdiWowlDelBcPtrnParams, + WDI_WowlDelBcPtrnCb wdiWowlDelBcPtrnCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_WOWL_DEL_BC_PTRN_REQ; + wdiEventData.pEventData = pwdiWowlDelBcPtrnParams; + wdiEventData.uEventDataSize = sizeof(*pwdiWowlDelBcPtrnParams); + wdiEventData.pCBfnc = wdiWowlDelBcPtrnCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_WowlDelBcPtrnReq*/ + +/** + @brief WDI_WowlEnterReq will be called when the upper MAC + wants to enter the Wowl state to minimize unnecessary + host wakeup while in power save. Upon the call of this + API the WLAN DAL will pack and send a HAL Wowl enter + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiWowlEnterReqParams: the Wowl enter info as + specified by the Device Interface + + wdiWowlEnterReqCb: callback for passing back the + response of the enter Wowl operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlEnterReq +( + WDI_WowlEnterReqParamsType* pwdiWowlEnterParams, + WDI_WowlEnterReqCb wdiWowlEnterCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_WOWL_ENTER_REQ; + wdiEventData.pEventData = pwdiWowlEnterParams; + wdiEventData.uEventDataSize = sizeof(*pwdiWowlEnterParams); + wdiEventData.pCBfnc = wdiWowlEnterCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_WowlEnterReq*/ + +/** + @brief WDI_WowlExitReq will be called when the upper MAC + wants to exit the Wowl state. Upon the call of this API + the WLAN DAL will pack and send a HAL Wowl exit request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_WowlEnterReq must have been called. + + @param pwdiWowlExitReqParams: the Wowl exit info as + specified by the Device Interface + + wdiWowlExitReqCb: callback for passing back the response + of the exit Wowl operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_WowlEnterReq + @return Result of the function call +*/ +WDI_Status +WDI_WowlExitReq +( + WDI_WowlExitReqParamsType* pwdiWowlExitParams, + WDI_WowlExitReqCb wdiWowlExitCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_WOWL_EXIT_REQ; + wdiEventData.pEventData = pwdiWowlExitParams; + wdiEventData.uEventDataSize = sizeof(*pwdiWowlExitParams); + wdiEventData.pCBfnc = wdiWowlExitCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_WowlExitReq*/ + +/** + @brief WDI_ConfigureAppsCpuWakeupStateReq will be called when + the upper MAC wants to dynamically adjusts the listen + interval based on the WLAN/MSM activity. Upon the call + of this API the WLAN DAL will pack and send a HAL + configure Apps Cpu Wakeup State request message to the + lower RIVA sub-system. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiConfigureAppsCpuWakeupStateReqParams: the + Apps Cpu Wakeup State as specified by the + Device Interface + + wdiConfigureAppsCpuWakeupStateCb: callback for passing + back the response of the configure Apps Cpu Wakeup State + operation received from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_ConfigureAppsCpuWakeupStateReq +( + WDI_ConfigureAppsCpuWakeupStateReqParamsType *pwdiConfigureAppsCpuWakeupStateReqParams, + WDI_ConfigureAppsCpuWakeupStateCb wdiConfigureAppsCpuWakeupStateCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ; + wdiEventData.pEventData = pwdiConfigureAppsCpuWakeupStateReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiConfigureAppsCpuWakeupStateReqParams); + wdiEventData.pCBfnc = wdiConfigureAppsCpuWakeupStateCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_ConfigureAppsCpuWakeupStateReq*/ +/** + @brief WDI_FlushAcReq will be called when the upper MAC wants + to to perform a flush operation on a given AC. Upon the + call of this API the WLAN DAL will pack and send a HAL + Flush AC request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_AddBAReq must have been called. + + @param pwdiFlushAcReqParams: the Flush AC parameters as + specified by the Device Interface + + wdiFlushAcRspCb: callback for passing back the response + of the Flush AC operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_FlushAcReq +( + WDI_FlushAcReqParamsType* pwdiFlushAcReqParams, + WDI_FlushAcRspCb wdiFlushAcRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FLUSH_AC_REQ; + wdiEventData.pEventData = pwdiFlushAcReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiFlushAcReqParams); + wdiEventData.pCBfnc = wdiFlushAcRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_FlushAcReq*/ + +/** + @brief WDI_BtAmpEventReq will be called when the upper MAC + wants to notify the lower mac on a BT AMP event. This is + to inform BTC-SLM that some BT AMP event occurred. Upon + the call of this API the WLAN DAL will pack and send a + HAL BT AMP event request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param wdiBtAmpEventReqParams: the BT AMP event parameters as + specified by the Device Interface + + wdiBtAmpEventRspCb: callback for passing back the + response of the BT AMP event operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_BtAmpEventReq +( + WDI_BtAmpEventParamsType* pwdiBtAmpEventReqParams, + WDI_BtAmpEventRspCb wdiBtAmpEventRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_BTAMP_EVENT_REQ; + wdiEventData.pEventData = pwdiBtAmpEventReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiBtAmpEventReqParams); + wdiEventData.pCBfnc = wdiBtAmpEventRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_BtAmpEventReq*/ + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief WDI_Start Oem Data Req will be called when the upper MAC + wants to notify the lower mac on a oem data Req event.Upon + the call of this API the WLAN DAL will pack and send a + HAL OEM Data Req event request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + + @param pwdiOemDataReqParams: the Oem Data Req as + specified by the Device Interface + + wdiStartOemDataRspCb: callback for passing back the + response of the Oem Data Req received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_StartOemDataReq +( + WDI_oemDataReqParamsType* pwdiOemDataReqParams, + WDI_oemDataRspCb wdiOemDataRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_START_OEM_DATA_REQ; + wdiEventData.pEventData = pwdiOemDataReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiOemDataReqParams); + wdiEventData.pCBfnc = wdiOemDataRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + + +} + +#endif + + +/*======================================================================== + + CONTROL APIs + +==========================================================================*/ +/** + @brief WDI_SwitchChReq will be called when the upper MAC wants + the WLAN HW to change the current channel of operation. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiSwitchChReqParams: the switch ch parameters as + specified by the Device Interface + + wdiSwitchChRspCb: callback for passing back the response + of the switch ch operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SwitchChReq +( + WDI_SwitchChReqParamsType* pwdiSwitchChReqParams, + WDI_SwitchChRspCb wdiSwitchChRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CH_SWITCH_REQ; + wdiEventData.pEventData = pwdiSwitchChReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSwitchChReqParams); + wdiEventData.pCBfnc = wdiSwitchChRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SwitchChReq*/ + +/** + @brief WDI_SwitchChReq_V1 will be called when the upper MAC wants + the WLAN HW to change the current channel of operation. + Upon the call of this API the WLAN DAL will pack and + send a HAL Start request message to the lower RIVA + sub-system if DAL is in state STARTED. + This request message also includes source of channel switch, + like CSA, + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiSwitchChReqParams: the switch ch parameters as + specified by the Device Interface + + wdiSwitchChRspCb: callback for passing back the response + of the switch ch operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_SwitchChReq_V1 +( + WDI_SwitchChReqParamsType_V1* pwdiSwitchChReqParams, + WDI_SwitchChRspCb_V1 wdiSwitchChRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI API call WDI_SwitchChReq_V1"); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CH_SWITCH_REQ_V1; + wdiEventData.pEventData = pwdiSwitchChReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSwitchChReqParams); + wdiEventData.pCBfnc = wdiSwitchChRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SwitchChReq_V1*/ + + +/** + @brief WDI_ConfigSTAReq will be called when the upper MAC + wishes to add or update a STA in HW. Upon the call of + this API the WLAN DAL will pack and send a HAL Start + message request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiConfigSTAReqParams: the config STA parameters as + specified by the Device Interface + + wdiConfigSTARspCb: callback for passing back the + response of the config STA operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_ConfigSTAReq +( + WDI_ConfigSTAReqParamsType* pwdiConfigSTAReqParams, + WDI_ConfigSTARspCb wdiConfigSTARspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_CONFIG_STA_REQ; + wdiEventData.pEventData = pwdiConfigSTAReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiConfigSTAReqParams); + wdiEventData.pCBfnc = wdiConfigSTARspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_ConfigSTAReq*/ + + /** + @brief WDI_UpdateChannelReq will be called when the upper MAC + wants to update the channel list on change in country code. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_UpdateChannelReq must have been called. + + @param wdiUpdateChannelReqParams: the updated channel parameters + as specified by the Device Interface + + wdiUpdateChannelRspCb: callback for passing back the + response of the update channel operation received from + the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_UpdateChannelReq +( + WDI_UpdateChReqParamsType *pwdiUpdateChannelReqParams, + WDI_UpdateChannelRspCb wdiUpdateChannelRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPDATE_CHAN_REQ; + wdiEventData.pEventData = pwdiUpdateChannelReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateChannelReqParams); + wdiEventData.pCBfnc = wdiUpdateChannelRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_UpdateChannelReq*/ + +/** + @brief WDI_SetLinkStateReq will be called when the upper MAC + wants to change the state of an ongoing link. Upon the + call of this API the WLAN DAL will pack and send a HAL + Start message request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_JoinStartReq must have been called. + + @param wdiSetLinkStateReqParams: the set link state parameters + as specified by the Device Interface + + wdiSetLinkStateRspCb: callback for passing back the + response of the set link state operation received from + the device + + pUserData: user data will be passed back with the + callback + + @see WDI_JoinStartReq + @return Result of the function call +*/ +WDI_Status +WDI_SetLinkStateReq +( + WDI_SetLinkReqParamsType* pwdiSetLinkStateReqParams, + WDI_SetLinkStateRspCb wdiSetLinkStateRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_LINK_ST_REQ; + wdiEventData.pEventData = pwdiSetLinkStateReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetLinkStateReqParams); + wdiEventData.pCBfnc = wdiSetLinkStateRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetLinkStateReq*/ + + +/** + @brief WDI_GetStatsReq will be called when the upper MAC wants + to get statistics (MIB counters) from the device. Upon + the call of this API the WLAN DAL will pack and send a + HAL Start request message to the lower RIVA sub-system + if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiGetStatsReqParams: the stats parameters to get as + specified by the Device Interface + + wdiGetStatsRspCb: callback for passing back the response + of the get stats operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_GetStatsReq +( + WDI_GetStatsReqParamsType* pwdiGetStatsReqParams, + WDI_GetStatsRspCb wdiGetStatsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GET_STATS_REQ; + wdiEventData.pEventData = pwdiGetStatsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiGetStatsReqParams); + wdiEventData.pCBfnc = wdiGetStatsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_GetStatsReq*/ + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief WDI_GetRoamRssiReq will be called when the upper MAC wants + to get roam rssi from the device. Upon + the call of this API the WLAN DAL will pack and send a + HAL Start request message to the lower RIVA sub-system + if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiGetRoamRssiReqParams: the stats parameters to get as + specified by the Device Interface + + wdiGetRoamRssiRspCb: callback for passing back the response + of the get stats operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_GetRoamRssiReq +( + WDI_GetRoamRssiReqParamsType* pwdiGetRoamRssiReqParams, + WDI_GetRoamRssiRspCb wdiGetRoamRssiRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GET_ROAM_RSSI_REQ; + wdiEventData.pEventData = pwdiGetRoamRssiReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiGetRoamRssiReqParams); + wdiEventData.pCBfnc = wdiGetRoamRssiRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_GetRoamRssiReq*/ +#endif + + +/** + @brief WDI_UpdateCfgReq will be called when the upper MAC when + it wishes to change the configuration of the WLAN + Device. Upon the call of this API the WLAN DAL will pack + and send a HAL Update CFG request message to the lower + RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_Start must have been called. + + @param wdiUpdateCfgReqParams: the update cfg parameters as + specified by the Device Interface + + wdiUpdateCfgsRspCb: callback for passing back the + response of the update cfg operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_Start + @return Result of the function call +*/ +WDI_Status +WDI_UpdateCfgReq +( + WDI_UpdateCfgReqParamsType* pwdiUpdateCfgReqParams, + WDI_UpdateCfgRspCb wdiUpdateCfgsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPDATE_CFG_REQ; + wdiEventData.pEventData = pwdiUpdateCfgReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateCfgReqParams); + wdiEventData.pCBfnc = wdiUpdateCfgsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_UpdateCfgReq*/ + + + +/** + @brief WDI_AddBAReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AddBAReq +( + WDI_AddBAReqParamsType* pwdiAddBAReqParams, + WDI_AddBARspCb wdiAddBARspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ADD_BA_REQ; + wdiEventData.pEventData = pwdiAddBAReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiAddBAReqParams); + wdiEventData.pCBfnc = wdiAddBARspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AddBAReq*/ + + +/** + @brief WDI_TriggerBAReq will be called when the upper MAC has setup + successfully a BA session and needs to notify the HW for + the appropriate settings to take place. Upon the call of + this API the WLAN DAL will pack and send a HAL Add BA + request message to the lower RIVA sub-system if DAL is + in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddBAReqParams: the add BA parameters as specified by + the Device Interface + + baReqParamUserDataSize: user data size of wdiAddBAReqParams + wdiAddBARspCb: callback for passing back the response of + the add BA operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_TriggerBAReq +( + WDI_TriggerBAReqParamsType* pwdiTriggerBAReqParams, + wpt_uint8 baReqParamUserDataSize, + WDI_TriggerBARspCb wdiTriggerBARspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_TRIGGER_BA_REQ; + wdiEventData.pEventData = pwdiTriggerBAReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiTriggerBAReqParams) + + baReqParamUserDataSize; + wdiEventData.pCBfnc = wdiTriggerBARspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AddBAReq*/ + +/** + @brief WDI_UpdateBeaconParamsReq will be called when the upper MAC + wishes to update any of the Beacon parameters used by HW. + Upon the call of this API the WLAN DAL will pack and send a HAL Update Beacon Params request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiUpdateBeaconParams: the Beacon parameters as specified + by the Device Interface + + wdiUpdateBeaconParamsRspCb: callback for passing back the + response of the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_UpdateBeaconParamsReq +( + WDI_UpdateBeaconParamsType* pwdiUpdateBeaconParams, + WDI_UpdateBeaconParamsRspCb wdiUpdateBeaconParamsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPD_BCON_PRMS_REQ; + wdiEventData.pEventData = pwdiUpdateBeaconParams; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateBeaconParams); + wdiEventData.pCBfnc = wdiUpdateBeaconParamsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_UpdateBeaconParamsReq*/ + +/** + @brief WDI_SendBeaconParamsReq will be called when the upper MAC + wishes to update the Beacon template used by HW. + Upon the call of this API the WLAN DAL will pack and send a HAL Update Beacon template request + message to the lower RIVA sub-system if DAL is in state + STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiSendBeaconParams: the Beacon parameters as specified + by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the start operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_SendBeaconParamsReq +( + WDI_SendBeaconParamsType* pwdiSendBeaconParams, + WDI_SendBeaconParamsRspCb wdiSendBeaconParamsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SND_BCON_REQ; + wdiEventData.pEventData = pwdiSendBeaconParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSendBeaconParams); + wdiEventData.pCBfnc = wdiSendBeaconParamsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SendBeaconParamsReq*/ + +/** + @brief WDI_UpdateProbeRspTemplateReq will be called when the + upper MAC wants to update the probe response template to + be transmitted as Soft AP + Upon the call of this API the WLAN DAL will + pack and send the probe rsp template message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiUpdateProbeRspParams: the Update Beacon parameters as + specified by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the Send Beacon Params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ + +WDI_Status +WDI_UpdateProbeRspTemplateReq +( + WDI_UpdateProbeRspTemplateParamsType* pwdiUpdateProbeRspParams, + WDI_UpdateProbeRspTemplateRspCb wdiUpdateProbeRspParamsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPD_PROBE_RSP_TEMPLATE_REQ; + wdiEventData.pEventData = pwdiUpdateProbeRspParams; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateProbeRspParams); + wdiEventData.pCBfnc = wdiUpdateProbeRspParamsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_UpdateProbeRspTemplateReq*/ + +/** + @brief WDI_NvDownloadReq will be called by the UMAC to download the NV blob + to the NV memory. + + + @param wdiNvDownloadReqParams: the NV Download parameters as specified by + the Device Interface + + wdiNvDownloadRspCb: callback for passing back the response of + the NV Download operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_NvDownloadReq +( + WDI_NvDownloadReqParamsType* pwdiNvDownloadReqParams, + WDI_NvDownloadRspCb wdiNvDownloadRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_NV_DOWNLOAD_REQ; + wdiEventData.pEventData = (void *)pwdiNvDownloadReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiNvDownloadReqParams); + wdiEventData.pCBfnc = wdiNvDownloadRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_START_EVENT, &wdiEventData); + +}/*WDI_NVDownloadReq*/ + +/** + @brief WDI_SetP2PGONOAReq will be called when the + upper MAC wants to send Notice of Absence + Upon the call of this API the WLAN DAL will + pack and send the probe rsp template message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiUpdateProbeRspParams: the Update Beacon parameters as + specified by the Device Interface + + wdiSendBeaconParamsRspCb: callback for passing back the + response of the Send Beacon Params operation received + from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_AddBAReq + @return Result of the function call +*/ +WDI_Status +WDI_SetP2PGONOAReq +( + WDI_SetP2PGONOAReqParamsType* pwdiP2PGONOAReqParams, + WDI_SetP2PGONOAReqParamsRspCb wdiP2PGONOAReqParamsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ; + wdiEventData.pEventData = pwdiP2PGONOAReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiP2PGONOAReqParams); + wdiEventData.pCBfnc = wdiP2PGONOAReqParamsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetP2PGONOAReq*/ + +#ifdef FEATURE_WLAN_TDLS +/** + @brief WDI_SetTDLSLinkEstablishReq will be called when the + upper MAC wants to send TDLS Link Establish Request Parameters + Upon the call of this API the WLAN DAL will + pack and send the TDLS Link Establish Request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiTDLSLinkEstablishReqParams: TDLS Peer Parameters + for Link Establishment (Used for PUAPSD , TDLS Off Channel ...) + + wdiTDLSLinkEstablishReqRspCb: callback for passing back the + response of the TDLS Link Establish request received + from the device + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SetTDLSLinkEstablishReq +( + WDI_SetTDLSLinkEstablishReqParamsType* pwdiTDLSLinkEstablishReqParams, + WDI_SetTDLSLinkEstablishReqParamsRspCb wdiTDLSLinkEstablishReqRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_TDLS_LINK_ESTABLISH_REQ; + wdiEventData.pEventData = pwdiTDLSLinkEstablishReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiTDLSLinkEstablishReqParams); + wdiEventData.pCBfnc = wdiTDLSLinkEstablishReqRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetTDLSLinkEstablishReq*/ + +//tdlsoffchan +/** + @brief WDI_SetTDLSChanSwitchReq will be called when the + upper MAC wants to send TDLS Chan Switch Request Parameters + Upon the call of this API the WLAN DAL will + pack and send the TDLS Link Establish Request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiTDLSChanSwitchReqParams: TDLS Peer Parameters + for Link Establishment (Used for TDLS Off Channel ...) + + wdiTDLSChanSwitchReqRspCb: callback for passing back the + response of the TDLS Chan Switch request received + from the device + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SetTDLSChanSwitchReq +( + WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams, + WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchRReqRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_TDLS_CHAN_SWITCH_REQ; + wdiEventData.pEventData = pwdiTDLSChanSwitchReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiTDLSChanSwitchReqParams); + wdiEventData.pCBfnc = wdiTDLSChanSwitchRReqRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetTDLSChanSwitchReq*/ + +#endif + +/** + @brief WDI_AddSTASelfReq will be called when the + UMAC wanted to add STA self while opening any new session + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiAddSTASelfParams: the add sta self parameters as + specified by the Device Interface + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_AddSTASelfReq +( + WDI_AddSTASelfReqParamsType* pwdiAddSTASelfReqParams, + WDI_AddSTASelfParamsRspCb wdiAddSTASelfReqParamsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ADD_STA_SELF_REQ; + wdiEventData.pEventData = pwdiAddSTASelfReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiAddSTASelfReqParams); + wdiEventData.pCBfnc = wdiAddSTASelfReqParamsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AddSTASelfReq*/ + + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief WDI_AggrAddTSReq will be called when the upper MAC to inform + the device of a successful add TSpec negotiation. HW + needs to receive the TSpec Info from the UMAC in order + to configure properly the QoS data traffic. Upon the + call of this API the WLAN DAL will pack and send a HAL + Add TS request message to the lower RIVA sub-system if + DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param wdiAddTsReqParams: the add TS parameters as specified by + the Device Interface + + wdiAddTsRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_AggrAddTSReq +( + WDI_AggrAddTSReqParamsType* pwdiAggrAddTsReqParams, + WDI_AggrAddTsRspCb wdiAggrAddTsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_AGGR_ADD_TS_REQ; + wdiEventData.pEventData = pwdiAggrAddTsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiAggrAddTsReqParams); + wdiEventData.pCBfnc = wdiAggrAddTsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AggrAddTSReq*/ + +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + @brief WDI_FTMCommandReq + Post FTM Command Event + + @param ftmCommandReq: FTM Command Body + @param ftmCommandRspCb: FTM Response from HAL CB + @param pUserData: Client Data + + @see + @return Result of the function call +*/ +WDI_Status +WDI_FTMCommandReq +( + WDI_FTMCommandReqType *ftmCommandReq, + WDI_FTMCommandRspCb ftmCommandRspCb, + void *pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_FTM_CMD_REQ; + wdiEventData.pEventData = (void *)ftmCommandReq; + wdiEventData.uEventDataSize = ftmCommandReq->bodyLength + sizeof(wpt_uint32); + wdiEventData.pCBfnc = ftmCommandRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} +/** + @brief WDI_HostResumeReq will be called + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiResumeReqParams: as specified by + the Device Interface + + wdiResumeReqRspCb: callback for passing back the response of + the Resume Req received from the device + + pUserData: user data will be passed back with the + callback + + @see + @return Result of the function call +*/ +WDI_Status +WDI_HostResumeReq +( + WDI_ResumeParamsType* pwdiResumeReqParams, + WDI_HostResumeEventRspCb wdiResumeReqRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_HOST_RESUME_REQ; + wdiEventData.pEventData = pwdiResumeReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiResumeReqParams); + wdiEventData.pCBfnc = wdiResumeReqRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_HostResumeReq*/ + +/** + @brief WDI_DelSTASelfReq will be called + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + + @param pwdiDelStaSelfReqParams: as specified by + the Device Interface + + wdiDelStaSelfRspCb: callback for passing back the response of + the add TS operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_DelSTASelfReq +( + WDI_DelSTASelfReqParamsType* pwdiDelStaSelfReqParams, + WDI_DelSTASelfRspCb wdiDelStaSelfRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_DEL_STA_SELF_REQ; + wdiEventData.pEventData = pwdiDelStaSelfReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiDelStaSelfReqParams); + wdiEventData.pCBfnc = wdiDelStaSelfRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_AggrAddTSReq*/ + +/** + @brief WDI_SetTxPerTrackingReq will be called when the upper MAC + wants to set the Tx Per Tracking configurations. + Upon the call of this API the WLAN DAL will pack + and send a HAL Set Tx Per Tracking request message to the + lower RIVA sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + @param pwdiSetTxPerTrackingReqParams: the Set Tx PER Tracking configurations as + specified by the Device Interface + + pwdiSetTxPerTrackingRspCb: callback for passing back the + response of the set Tx PER Tracking configurations operation received + from the device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTxPerTrackingReq +( + WDI_SetTxPerTrackingReqParamsType* pwdiSetTxPerTrackingReqParams, + WDI_SetTxPerTrackingRspCb pwdiSetTxPerTrackingRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_TX_PER_TRACKING_REQ; + wdiEventData.pEventData = pwdiSetTxPerTrackingReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetTxPerTrackingReqParams); + wdiEventData.pCBfnc = pwdiSetTxPerTrackingRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_SetTxPerTrackingReq*/ + +/** + @brief WDI_SetTmLevelReq + If HW Thermal condition changed, driver should react based on new + HW thermal condition. + + @param pwdiSetTmLevelReq: New thermal condition information + + pwdiSetTmLevelRspCb: callback + + usrData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetTmLevelReq +( + WDI_SetTmLevelReqType *pwdiSetTmLevelReq, + WDI_SetTmLevelCb pwdiSetTmLevelRspCb, + void *usrData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_TM_LEVEL_REQ; + wdiEventData.pEventData = pwdiSetTmLevelReq; + wdiEventData.uEventDataSize = sizeof(*pwdiSetTmLevelReq); + wdiEventData.pCBfnc = pwdiSetTmLevelRspCb; + wdiEventData.pUserData = usrData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_HostSuspendInd + + Suspend Indication from the upper layer will be sent + down to HAL + + @param WDI_SuspendResumeIndParamsType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_HostSuspendInd +( + WDI_SuspendParamsType* pwdiSuspendIndParams +) +{ + + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_HOST_SUSPEND_IND; + wdiEventData.pEventData = pwdiSuspendIndParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSuspendIndParams); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_HostSuspendInd*/ + +/** + @brief WDI_TrafficStatsInd + Traffic Stats from the upper layer will be sent + down to HAL + + @param WDI_TrafficStatsIndType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_TrafficStatsInd +( + WDI_TrafficStatsIndType *pWdiTrafficStatsIndParams +) +{ + + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_TRAFFIC_STATS_IND; + wdiEventData.pEventData = pWdiTrafficStatsIndParams; + wdiEventData.uEventDataSize = sizeof(*pWdiTrafficStatsIndParams); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_TrafficStatsInd*/ + +#ifdef WLAN_FEATURE_11W +/** + @brief WDI_ExcludeUnencryptedInd + Register with HAL to receive/drop unencrypted frames + + @param WDI_ExcludeUnencryptIndType + + @see + + @return Status of the request +*/ +WDI_Status +WDI_ExcludeUnencryptedInd +( + WDI_ExcludeUnencryptIndType *pWdiExcUnencParams +) +{ + + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_EXCLUDE_UNENCRYPTED_IND; + wdiEventData.pEventData = pWdiExcUnencParams; + wdiEventData.uEventDataSize = sizeof(*pWdiExcUnencParams); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_TrafficStatsInd*/ +#endif + +/** + @brief WDI_AddPeriodicTxPtrnInd: Add Periodic TX Pattern Indication to FW + + @param addPeriodicTxPtrnParams: Add Pattern parameters + + @see + + @return Status of the request +*/ +WDI_Status +WDI_AddPeriodicTxPtrnInd +( + WDI_AddPeriodicTxPtrnParamsType* addPeriodicTxPtrnParams +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ADD_PERIODIC_TX_PATTERN_IND; + wdiEventData.pEventData = addPeriodicTxPtrnParams; + wdiEventData.uEventDataSize = sizeof(WDI_AddPeriodicTxPtrnParamsType); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_DelPeriodicTxPtrnInd: Delete Periodic TX Pattern Indication to FW + + @param delPeriodicTxPtrnParams: Delete Pattern parameters + + @see + + @return Status of the request +*/ +WDI_Status +WDI_DelPeriodicTxPtrnInd +( + WDI_DelPeriodicTxPtrnParamsType* delPeriodicTxPtrnParams +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_DEL_PERIODIC_TX_PATTERN_IND; + wdiEventData.pEventData = delPeriodicTxPtrnParams; + wdiEventData.uEventDataSize = sizeof(WDI_DelPeriodicTxPtrnParamsType); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_HALDumpCmdReq + Post HAL DUMP Command Event + + @param halDumpCmdReqParams: Hal Dump Command Body + @param halDumpCmdRspCb: HAL DUMP Response from HAL CB + @param pUserData: Client Data + + @see + @return Result of the function call +*/ +WDI_Status WDI_HALDumpCmdReq +( + WDI_HALDumpCmdReqParamsType *halDumpCmdReqParams, + WDI_HALDumpCmdRspCb halDumpCmdRspCb, + void *pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_HAL_DUMP_CMD_REQ; + wdiEventData.pEventData = (void *)halDumpCmdReqParams; + wdiEventData.uEventDataSize = sizeof(WDI_HALDumpCmdReqParamsType); + wdiEventData.pCBfnc = halDumpCmdRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/*============================================================================ + + DAL Control Path Main FSM Function Implementation + + ============================================================================*/ + +/** + @brief Main FSM Start function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + wdiEV: event posted to the main DAL FSM + pEventData: pointer to the event information + structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_PostMainEvent +( + WDI_ControlBlockType* pWDICtx, + WDI_MainEventType wdiEV, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + WDI_MainFuncType pfnWDIMainEvHdlr; + WDI_MainStateType wdiOldState; + static int failCnt = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( pWDICtx->uGlobalState >= WDI_MAX_ST ) || + ( wdiEV >= WDI_MAX_EVENT )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid state or event in Post Main Ev function ST: %d EV: %d", + pWDICtx->uGlobalState, wdiEV); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*Access to the global state must be locked */ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*Fetch event handler for state*/ + pfnWDIMainEvHdlr = wdiMainFSM[pWDICtx->uGlobalState].pfnMainTbl[wdiEV]; + + wdiOldState = pWDICtx->uGlobalState; + + /* + --Incase of WDI event is WDI_RESPONSE_EVENT and this is called when a + response comes from CCPU for the request sent by host: + the WDI global state will be in WDI_BUSY_ST already, so do not set it to BUSY again. + This state will be set to WDI_STARTED_ST in WDI_MainRsp, if it is a expected response. + --Incase of WDI event is WDI_RESPONSE_EVENT and it is an indication from the + CCPU: + don't change the state */ + if ( WDI_RESPONSE_EVENT != wdiEV) + { + /*Transition to BUSY State - the request is now being processed by the FSM, + if the request fails we shall transition back to the old state, if not + the request will manage its own state transition*/ + WDI_STATE_TRANSITION( pWDICtx, WDI_BUSY_ST); + } + /* If the state function associated with the EV is NULL it means that this + event is not allowed in this state*/ + if ( NULL != pfnWDIMainEvHdlr ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Posting event %d in state: %d to the Main FSM", + wdiEV, wdiOldState); + wdiStatus = pfnWDIMainEvHdlr( pWDICtx, pEventData); + } + else + { + if (!(failCnt & 0xF)) + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unexpected event %d in state: %d", + wdiEV, wdiOldState); + failCnt++; + wdiStatus = WDI_STATUS_E_NOT_ALLOWED; + } + + /* If a request handles itself well it will end up in a success or in a + pending + Success - means that the request was processed and the proper state + transition already occurred or will occur when the resp is received + - NO other state transition or dequeueing is required + + Pending - means the request could not be processed at this moment in time + because the FSM was already busy so no state transition or dequeueing + is necessary anymore + + Success for synchronous case means that the transition may occur and + processing of pending requests may continue - so it should go through + and restores the state and continue processing queued requests*/ + if (( WDI_STATUS_SUCCESS != wdiStatus )&& + ( WDI_STATUS_PENDING != wdiStatus )) + { + if ( WDI_RESPONSE_EVENT != wdiEV) + { + /*The request has failed or could not be processed - transition back to + the old state - check to see if anything was queued and try to execute + The dequeue logic should post a message to a thread and return - no + actual processing can occur */ + WDI_STATE_TRANSITION( pWDICtx, wdiOldState); + } + WDI_DequeuePendingReq(pWDICtx); + + } + + /* we have completed processing the event */ + wpalMutexRelease(&pWDICtx->wptMutex); + + return wdiStatus; + +}/*WDI_PostMainEvent*/ + + +/*-------------------------------------------------------------------------- + INIT State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStart +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Start Started %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*-------------------------------------------------------------------- + Check if the Control Transport has been opened + ----------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == pWDICtx->bCTOpened ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Control Transport not yet Open - queueing the request"); + + WDI_STATE_TRANSITION( pWDICtx, WDI_INIT_ST); + WDI_QueuePendingReq( pWDICtx, pEventData); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_PENDING; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Return Success*/ + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainStart*/ + +/** + @brief Main FSM Response function for state INIT + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainRspInit +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*------------------------------------------------------------------------ + Not expecting a response from the device before it is started + ------------------------------------------------------------------------*/ + WDI_ASSERT(0); + + /*Return Success*/ + return WDI_STATUS_E_NOT_ALLOWED; +}/* WDI_MainRspInit */ + +/** + @brief Main FSM Close function for all states except BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainClose +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Close %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*Return Success*/ + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainClose*/ +/*-------------------------------------------------------------------------- + STARTED State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for state STARTED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStartStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_StartRspCb wdiStartRspCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Start %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*-------------------------------------------------------------------- + Nothing to do transport was already started + ----------------------------------------------------------------------*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Received start while transport was already started - nothing to do"); + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*Transition back to started because the post function transitioned us to + busy*/ + WDI_STATE_TRANSITION( pWDICtx, WDI_STARTED_ST); + + /*Check to see if any request is pending*/ + WDI_DequeuePendingReq(pWDICtx); + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Tell UMAC Success*/ + wdiStartRspCb = (WDI_StartRspCb)pEventData->pCBfnc; + + /*Notify UMAC*/ + wdiStartRspCb( &pWDICtx->wdiCachedStartRspParams, pEventData->pUserData); + + /*Return Success*/ + return WDI_STATUS_SUCCESS; + +}/*WDI_MainStartStarted*/ + +/** + @brief Main FSM Stop function for state STARTED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid parameters on Main Stop Started %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*State at this point is BUSY - because we enter this state before posting + an event to the FSM in order to prevent potential race conditions*/ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Processing stop request in FSM"); + + /*Return Success*/ + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainStopStarted*/ +/** + @brief Main FSM Request function for state started + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainReqStarted +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Req Started %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*State at this point is BUSY - because we enter this state before posting + an event to the FSM in order to prevent potential race conditions*/ + + /*Return Success*/ + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainReqStarted*/ + +/** + @brief Main FSM Response function for all states except INIT + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + wpt_boolean expectedResponse; + + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Response %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + if ( pEventData->wdiResponse == pWDICtx->wdiExpectedResponse ) + { + /* we received an expected response */ + expectedResponse = eWLAN_PAL_TRUE; + + /*We expect that we will transition to started after this processing*/ + pWDICtx->ucExpectedStateTransition = WDI_STARTED_ST; + + /* we are no longer expecting a response */ + pWDICtx->wdiExpectedResponse = WDI_MAX_RESP; + } + else + { + /* we received an indication or unexpected response */ + expectedResponse = eWLAN_PAL_FALSE; + /* for indications no need to update state from what it is right + now, unless it explicitly does it in the indication handler (say + for device failure ind) */ + pWDICtx->ucExpectedStateTransition = pWDICtx->uGlobalState; + } + + /*Process the response and indication */ + wdiStatus = WDI_ProcessResponse( pWDICtx, pEventData ); + + /*Lock the CB as we are about to do a state transition*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*Transition to the expected state after the response processing + - this should always be started state with the following exceptions: + 1. processing of a failed start response + 2. device failure detected while processing response + 3. stop response received*/ + WDI_STATE_TRANSITION( pWDICtx, pWDICtx->ucExpectedStateTransition); + + /*Dequeue request that may have been queued while we were waiting for the + response */ + if ( expectedResponse ) + { + WDI_DequeuePendingReq(pWDICtx); + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Return Success - always */ + return WDI_STATUS_SUCCESS; + +}/*WDI_MainRsp*/ + +/*-------------------------------------------------------------------------- + STOPPED State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Stop function for state STOPPED + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopStopped +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid parameters on Main Stop Stopped %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*We should normally not get a STOP request if we are already stopped + since we should normally be stopped by the UMAC. However in some + error situations we put ourselves in the stopped state without the + UMAC knowing, so when we get a STOP request in this state we still + process it since we need to clean up the underlying state */ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Processing stop request while stopped in FSM"); + + /*Return Success*/ + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainStopStopped*/ + +/*-------------------------------------------------------------------------- + BUSY State Functions +--------------------------------------------------------------------------*/ +/** + @brief Main FSM Start function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStartBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Start in BUSY %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*-------------------------------------------------------------------- + Check if the Control Transport has been opened + ----------------------------------------------------------------------*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Busy state - queue start request"); + + /*Queue the start request*/ + WDI_QueuePendingReq( pWDICtx, pEventData); + + /*Return Success*/ + return WDI_STATUS_PENDING; +}/*WDI_MainStartBusy*/ + +/** + @brief Main FSM Stop function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainStopBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Stop in BUSY %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*-------------------------------------------------------------------- + Check if the Control Transport has been opened + ----------------------------------------------------------------------*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Busy state - queue stop request"); + + WDI_QueuePendingReq( pWDICtx, pEventData); + return WDI_STATUS_PENDING; + +}/*WDI_MainStopBusy*/ + +/** + @brief Main FSM Request function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainReqBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Request in BUSY %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*-------------------------------------------------------------------- + Check if the Control Transport has been opened + ----------------------------------------------------------------------*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Busy state - queue request %d because waiting for response %d", + pEventData->wdiRequest, pWDICtx->wdiExpectedResponse); + + WDI_QueuePendingReq( pWDICtx, pEventData); + return WDI_STATUS_PENDING; + +}/*WDI_MainReqBusy*/ +/** + @brief Main FSM Close function for state BUSY + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainCloseBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid parameters on Main Close in BUSY %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*-------------------------------------------------------------------- + Check if the Control Transport has been opened + ----------------------------------------------------------------------*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Busy state - queue close request"); + + WDI_QueuePendingReq( pWDICtx, pEventData); + return WDI_STATUS_PENDING; + +}/*WDI_MainCloseBusy*/ + +/** + @brief Main FSM Shutdown function for INIT & STARTED states + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainShutdown +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid parameters on Main Start %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /*State at this point is BUSY - because we enter this state before posting + an event to the FSM in order to prevent potential race conditions*/ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Processing shutdown request in FSM"); + + /*Return Success*/ + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainShutdown*/ + +/** + @brief Main FSM Shutdown function for BUSY state + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_MainShutdownBusy +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*-------------------------------------------------------------------- + Sanity Check + ----------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid parameters on Main Start %p %p", + pWDICtx, pEventData); + return WDI_STATUS_E_FAILURE; + } + + /* If you are waiting for a HAL response at this stage, you are not + * going to get it. Riva is already shutdown/crashed. + */ + wpalTimerStop(&gWDICb.wptResponseTimer); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Processing shutdown request in FSM: Busy state "); + + return WDI_ProcessRequest( pWDICtx, pEventData ); + +}/*WDI_MainShutdownBusy*/ + + +/*======================================================================= + + WLAN DAL Control Path Main Processing Functions + +*=======================================================================*/ + +/*======================================================================== + Main DAL Control Path Request Processing API +========================================================================*/ +/** + @brief Process Start Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_StartReqParamsType* pwdiStartParams = NULL; + WDI_StartRspCb wdiStartRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + tHalMacStartReqMsg halStartReq; + wpt_uint16 usLen = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiStartParams = (WDI_StartReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiStartRspCb = (WDI_StartRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + usLen = sizeof(halStartReq.startReqParams) + + pwdiStartParams->usConfigBufferLen; + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_START_REQ, + usLen, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in start req %p %p %p", + pEventData, pwdiStartParams, wdiStartRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Fill in the message + -----------------------------------------------------------------------*/ + halStartReq.startReqParams.driverType = + WDI_2_HAL_DRV_TYPE(pwdiStartParams->wdiDriverType); + + halStartReq.startReqParams.uConfigBufferLen = + pwdiStartParams->usConfigBufferLen; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halStartReq.startReqParams, + sizeof(halStartReq.startReqParams)); + + usDataOffset += sizeof(halStartReq.startReqParams); + wpalMemoryCopy( pSendBuffer+usDataOffset, + pwdiStartParams->pConfigBuffer, + pwdiStartParams->usConfigBufferLen); + + pWDICtx->wdiReqStatusCB = pwdiStartParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiStartParams->pUserData; + + /*Save Low Level Ind CB and associated user data - it will be used further + on when an indication is coming from the lower MAC*/ + pWDICtx->wdiLowLevelIndCB = pwdiStartParams->wdiLowLevelIndCB; + pWDICtx->pIndUserData = pwdiStartParams->pIndUserData; + + pWDICtx->bFrameTransEnabled = pwdiStartParams->bFrameTransEnabled; + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiStartRspCb, pEventData->pUserData, WDI_START_RESP); + + +}/*WDI_ProcessStartReq*/ + +/** + @brief Process Stop Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_StopReqParamsType* pwdiStopParams = NULL; + WDI_StopRspCb wdiStopRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_status status; + tHalMacStopReqMsg halStopReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiStopParams = (WDI_StopReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiStopRspCb = (WDI_StopRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_STOP_REQ, + sizeof(halStopReq.stopReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halStopReq.stopReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in stop req %p %p %p", + pEventData, pwdiStopParams, wdiStopRspCb); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Fill in the message + -----------------------------------------------------------------------*/ + halStopReq.stopReqParams.reason = WDI_2_HAL_STOP_REASON( + pwdiStopParams->wdiStopReason); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halStopReq.stopReqParams, + sizeof(halStopReq.stopReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiStopParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiStopParams->pUserData; + + /*! TO DO: stop the data services */ + if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode ) + { + /*Stop the STA Table !UT- check this logic again + It is safer to do it here than on the response - because a stop is imminent*/ + WDI_STATableStop(pWDICtx); + + /* Reset the event to be not signalled */ + status = wpalEventReset(&pWDICtx->setPowerStateEvent); + if (eWLAN_PAL_STATUS_SUCCESS != status) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to reset power state event"); + + WDI_ASSERT(0); + goto fail; + } + /* Stop Transport Driver, DXE */ + status = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_DOWN, WDI_SetPowerStateCb); + if( eWLAN_PAL_STATUS_SUCCESS != status ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Power Down state", status); + WDI_ASSERT(0); + goto fail; + } + /* + * Wait for the event to be set once the ACK comes back from DXE + */ + status = wpalEventWait(&pWDICtx->setPowerStateEvent, + WDI_SET_POWER_STATE_TIMEOUT); + if (eWLAN_PAL_STATUS_SUCCESS != status) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to wait on an event"); + + WDI_ASSERT(0); + goto fail; + } + } + + /*------------------------------------------------------------------------- + Send Stop Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiStopRspCb, pEventData->pUserData, WDI_STOP_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; + +}/*WDI_ProcessStopReq*/ + +/** + @brief Process Close Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCloseReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_status wptStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*Lock control block for cleanup*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*Clear all pending request*/ + WDI_ClearPendingRequests(pWDICtx); + + /* Close Control transport*/ + WCTS_CloseTransport(pWDICtx->wctsHandle); + + /* Close Data transport*/ + /* FTM mode does not open Data Path */ + if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode ) + { + WDTS_Close(pWDICtx); + } + + /*Close the STA Table !UT- check this logic again*/ + WDI_STATableClose(pWDICtx); + + /*close the PAL */ + wptStatus = wpalClose(pWDICtx->pPALContext); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to wpal Close %d", wptStatus); + WDI_ASSERT(0); + } + + /*Transition back to init state*/ + WDI_STATE_TRANSITION( pWDICtx, WDI_INIT_ST); + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Make sure the expected state is properly defaulted to Init*/ + pWDICtx->ucExpectedStateTransition = WDI_INIT_ST; + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessCloseReq*/ + + +/*=========================================================================== + SCANING REQUEST PROCESSING API +===========================================================================*/ + +/** + @brief Process Init Scan Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessInitScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_InitScanReqParamsType* pwdiInitScanParams = NULL; + WDI_InitScanRspCb wdiInitScanRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 i = 0; + + tHalInitScanReqMsg halInitScanReqMsg; + + /*This is temporary fix. + * It shold be removed once host and riva changes are in sync*/ + tHalInitScanConReqMsg halInitScanConReqMsg; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiInitScanParams = (WDI_InitScanReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiInitScanRspCb = (WDI_InitScanRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + +#if 0 + wpalMutexAcquire(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Check to see if SCAN is already in progress - if so reject the req + We only allow one scan at a time + ! TO DO: - revisit this constraint + -----------------------------------------------------------------------*/ + if ( pWDICtx->bScanInProgress ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Scan is already in progress - subsequent scan is not allowed" + " until the first scan completes"); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + pWDICtx->bScanInProgress = eWLAN_PAL_TRUE; + pWDICtx->uScanState = WDI_SCAN_INITIALIZED_ST; + + wpalMutexRelease(&pWDICtx->wptMutex); +#endif + if ((pwdiInitScanParams->wdiReqInfo.bUseNOA) && (!WDI_getFwWlanFeatCaps(P2P_GO_NOA_DECOUPLE_INIT_SCAN))) + { + /*This is temporary fix. + * It shold be removed once host and riva changes are in sync*/ + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_INIT_SCAN_CON_REQ, + sizeof(halInitScanConReqMsg.initScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halInitScanConReqMsg.initScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in init scan req %p %p %p", + pEventData, pwdiInitScanParams, wdiInitScanRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + /*----------------------------------------------------------------------- + Fill in the message + -----------------------------------------------------------------------*/ + halInitScanConReqMsg.initScanParams.scanMode = + WDI_2_HAL_SCAN_MODE(pwdiInitScanParams->wdiReqInfo.wdiScanMode); + + wpalMemoryCopy(halInitScanConReqMsg.initScanParams.bssid, + pwdiInitScanParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN); + + halInitScanConReqMsg.initScanParams.notifyBss = + pwdiInitScanParams->wdiReqInfo.bNotifyBSS; + halInitScanConReqMsg.initScanParams.frameType = + pwdiInitScanParams->wdiReqInfo.ucFrameType; + halInitScanConReqMsg.initScanParams.frameLength = + pwdiInitScanParams->wdiReqInfo.ucFrameLength; + + WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr( &halInitScanConReqMsg.initScanParams.macMgmtHdr, + &pwdiInitScanParams->wdiReqInfo.wdiMACMgmtHdr); + + halInitScanConReqMsg.initScanParams.useNoA = pwdiInitScanParams->wdiReqInfo.bUseNOA; + halInitScanConReqMsg.initScanParams.scanDuration = pwdiInitScanParams->wdiReqInfo.scanDuration; + + halInitScanConReqMsg.initScanParams.scanEntry.activeBSScnt = + pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; + + for (i=0; i < pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; i++) + { + halInitScanConReqMsg.initScanParams.scanEntry.bssIdx[i] = + pwdiInitScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i]; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halInitScanConReqMsg.initScanParams, + sizeof(halInitScanConReqMsg.initScanParams)); + } + else + { + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_INIT_SCAN_REQ, + sizeof(halInitScanReqMsg.initScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halInitScanReqMsg.initScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in init scan req %p %p %p", + pEventData, pwdiInitScanParams, wdiInitScanRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + /*----------------------------------------------------------------------- + Fill in the message + -----------------------------------------------------------------------*/ + halInitScanReqMsg.initScanParams.scanMode = + WDI_2_HAL_SCAN_MODE(pwdiInitScanParams->wdiReqInfo.wdiScanMode); + + wpalMemoryCopy(halInitScanReqMsg.initScanParams.bssid, + pwdiInitScanParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN); + + halInitScanReqMsg.initScanParams.notifyBss = + pwdiInitScanParams->wdiReqInfo.bNotifyBSS; + halInitScanReqMsg.initScanParams.frameType = + pwdiInitScanParams->wdiReqInfo.ucFrameType; + halInitScanReqMsg.initScanParams.frameLength = + pwdiInitScanParams->wdiReqInfo.ucFrameLength; + + WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr( &halInitScanReqMsg.initScanParams.macMgmtHdr, + &pwdiInitScanParams->wdiReqInfo.wdiMACMgmtHdr); + + halInitScanReqMsg.initScanParams.scanEntry.activeBSScnt = + pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; + + for (i=0; i < pwdiInitScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; i++) + { + halInitScanReqMsg.initScanParams.scanEntry.bssIdx[i] = + pwdiInitScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i]; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halInitScanReqMsg.initScanParams, + sizeof(halInitScanReqMsg.initScanParams)); + } + + pWDICtx->wdiReqStatusCB = pwdiInitScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiInitScanParams->pUserData; + + /*------------------------------------------------------------------------- + Send Init Scan Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiInitScanRspCb, pEventData->pUserData, WDI_INIT_SCAN_RESP); + +}/*WDI_ProcessInitScanReq*/ + +/** + @brief Process Start Scan Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_StartScanReqParamsType* pwdiStartScanParams = NULL; + WDI_StartScanRspCb wdiStartScanRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + tHalStartScanReqMsg halStartScanReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiStartScanParams = (WDI_StartScanReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiStartScanRspCb = (WDI_StartScanRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + +#if 0 + wpalMutexAcquire(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Check to see if SCAN is already in progress - start scan is only + allowed when a scan is ongoing and the state of the scan procedure + is either init or end + -----------------------------------------------------------------------*/ + if (( !pWDICtx->bScanInProgress ) || + (( WDI_SCAN_INITIALIZED_ST != pWDICtx->uScanState ) && + ( WDI_SCAN_ENDED_ST != pWDICtx->uScanState ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Scan start not allowed in this state %d %d", + pWDICtx->bScanInProgress, pWDICtx->uScanState); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + pWDICtx->uScanState = WDI_SCAN_STARTED_ST; + + wpalMutexRelease(&pWDICtx->wptMutex); +#endif + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_START_SCAN_REQ, + sizeof(halStartScanReqMsg.startScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halStartScanReqMsg.startScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in start scan req %p %p %p", + pEventData, pwdiStartScanParams, wdiStartScanRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halStartScanReqMsg.startScanParams.scanChannel = + pwdiStartScanParams->ucChannel; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halStartScanReqMsg.startScanParams, + sizeof(halStartScanReqMsg.startScanParams)); + + pWDICtx->wdiReqStatusCB = pwdiStartScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiStartScanParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Scan Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiStartScanRspCb, pEventData->pUserData, WDI_START_SCAN_RESP); +}/*WDI_ProcessStartScanReq*/ + + +/** + @brief Process End Scan Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEndScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EndScanReqParamsType* pwdiEndScanParams = NULL; + WDI_EndScanRspCb wdiEndScanRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + tHalEndScanReqMsg halEndScanReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiEndScanParams = (WDI_EndScanReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiEndScanRspCb = (WDI_EndScanRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* commenting this check as UMAC is sending END_SCAN_REQ after FINISH_SCAN + * sometimes because of this check the scan request is not being + * forwarded to HAL and result in hang*/ +#if 0 + wpalMutexAcquire(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Check to see if SCAN is already in progress - end scan is only + allowed when a scan is ongoing and the state of the scan procedure + is started + -----------------------------------------------------------------------*/ + if (( !pWDICtx->bScanInProgress ) || + ( WDI_SCAN_STARTED_ST != pWDICtx->uScanState )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "End start not allowed in this state %d %d", + pWDICtx->bScanInProgress, pWDICtx->uScanState); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + pWDICtx->uScanState = WDI_SCAN_ENDED_ST; + + wpalMutexRelease(&pWDICtx->wptMutex); +#endif + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_END_SCAN_REQ, + sizeof(halEndScanReqMsg.endScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halEndScanReqMsg.endScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in start scan req %p %p %p", + pEventData, pwdiEndScanParams, wdiEndScanRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halEndScanReqMsg.endScanParams.scanChannel = pwdiEndScanParams->ucChannel; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halEndScanReqMsg.endScanParams, + sizeof(halEndScanReqMsg.endScanParams)); + + pWDICtx->wdiReqStatusCB = pwdiEndScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiEndScanParams->pUserData; + + /*------------------------------------------------------------------------- + Send End Scan Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEndScanRspCb, pEventData->pUserData, WDI_END_SCAN_RESP); +}/*WDI_ProcessEndScanReq*/ + + +/** + @brief Process Finish Scan Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFinishScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FinishScanReqParamsType* pwdiFinishScanParams; + WDI_FinishScanRspCb wdiFinishScanRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 i = 0; + wpt_status wptStatus; + tHalFinishScanReqMsg halFinishScanReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiFinishScanParams = (WDI_FinishScanReqParamsType*)pEventData->pEventData; + wdiFinishScanRspCb = (WDI_FinishScanRspCb)pEventData->pCBfnc; + /* commenting this check as UMAC is sending END_SCAN_REQ after FINISH_SCAN + * sometimes because of this check the scan request is not being + * forwarded to HAL and result in hang*/ +#if 0 + wpalMutexAcquire(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Check to see if SCAN is already in progress + Finish scan gets invoked any scan states. ie. abort scan + It should be allowed in any states. + -----------------------------------------------------------------------*/ + if ( !pWDICtx->bScanInProgress ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Finish start not allowed in this state %d", + pWDICtx->bScanInProgress ); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*----------------------------------------------------------------------- + It is safe to reset the scan flags here because until the response comes + back all subsequent requests will be blocked at BUSY state + -----------------------------------------------------------------------*/ + pWDICtx->uScanState = WDI_SCAN_FINISHED_ST; + pWDICtx->bScanInProgress = eWLAN_PAL_FALSE; + wpalMutexRelease(&pWDICtx->wptMutex); +#endif + + if ( pWDICtx->bInBmps ) + { + // notify DTS that we are entering BMPS + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_BMPS, NULL); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering BMPS", wptStatus); + WDI_ASSERT(0); + } + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_FINISH_SCAN_REQ, + sizeof(halFinishScanReqMsg.finishScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halFinishScanReqMsg.finishScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in start scan req %p %p %p", + pEventData, pwdiFinishScanParams, wdiFinishScanRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halFinishScanReqMsg.finishScanParams.scanMode = + WDI_2_HAL_SCAN_MODE(pwdiFinishScanParams->wdiReqInfo.wdiScanMode); + + halFinishScanReqMsg.finishScanParams.currentOperChannel = + pwdiFinishScanParams->wdiReqInfo.ucCurrentOperatingChannel; + + halFinishScanReqMsg.finishScanParams.cbState = + WDI_2_HAL_CB_STATE(pwdiFinishScanParams->wdiReqInfo.wdiCBState); + + wpalMemoryCopy(halFinishScanReqMsg.finishScanParams.bssid, + pwdiFinishScanParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN); + + halFinishScanReqMsg.finishScanParams.notifyBss = + pwdiFinishScanParams->wdiReqInfo.bNotifyBSS ; + halFinishScanReqMsg.finishScanParams.frameType = + pwdiFinishScanParams->wdiReqInfo.ucFrameType ; + halFinishScanReqMsg.finishScanParams.frameLength = + pwdiFinishScanParams->wdiReqInfo.ucFrameLength ; + + halFinishScanReqMsg.finishScanParams.scanEntry.activeBSScnt = + pwdiFinishScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt ; + + for (i = 0; i < pwdiFinishScanParams->wdiReqInfo.wdiScanEntry.activeBSScnt; i++) + { + halFinishScanReqMsg.finishScanParams.scanEntry.bssIdx[i] = + pwdiFinishScanParams->wdiReqInfo.wdiScanEntry.bssIdx[i] ; + } + + WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr( &halFinishScanReqMsg.finishScanParams.macMgmtHdr, + &pwdiFinishScanParams->wdiReqInfo.wdiMACMgmtHdr); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halFinishScanReqMsg.finishScanParams, + sizeof(halFinishScanReqMsg.finishScanParams)); + + pWDICtx->wdiReqStatusCB = pwdiFinishScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiFinishScanParams->pUserData; + + /*------------------------------------------------------------------------- + Send Finish Scan Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiFinishScanRspCb, pEventData->pUserData, WDI_FINISH_SCAN_RESP); +}/*WDI_ProcessFinishScanReq*/ + + +/*========================================================================== + ASSOCIATION REQUEST API +==========================================================================*/ +/** + @brief Process BSS Join for a given Session + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBSSSessionJoinReq +( + WDI_ControlBlockType* pWDICtx, + WDI_JoinReqParamsType* pwdiJoinParams, + WDI_JoinRspCb wdiJoinRspCb, + void* pUserData +) +{ + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 ucCurrentBSSSesIdx = 0; + + tHalJoinReqMsg halJoinReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Check to see if we have any session with this BSSID already stored, we + should not + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiJoinParams->wdiReqInfo.macBSSID, + &pBSSSes); + + if ( NULL != pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association for this BSSID: " MAC_ADDRESS_STR " is already in place", + MAC_ADDR_ARRAY(pwdiJoinParams->wdiReqInfo.macBSSID)); + + /*reset the bAssociationInProgress otherwise the next + *join request will be queued*/ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fetch an empty session block + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindEmptySession( pWDICtx, &pBSSSes); + if ( NULL == pBSSSes ) + { + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "DAL has no free sessions - cannot run another join"); + + /*reset the bAssociationInProgress otherwise the next + *join request will be queued*/ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_RES_FAILURE; + } + + /*Save BSS Session Info*/ + pBSSSes->bInUse = eWLAN_PAL_TRUE; + wpalMemoryCopy( pBSSSes->macBSSID, pwdiJoinParams->wdiReqInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + /*Transition to state Joining*/ + pBSSSes->wdiAssocState = WDI_ASSOC_JOINING_ST; + pWDICtx->ucCurrentBSSSesIdx = ucCurrentBSSSesIdx; + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_JOIN_REQ, + sizeof(halJoinReqMsg.joinReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halJoinReqMsg.joinReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in join req %p %p %p", + pUserData, pwdiJoinParams, wdiJoinRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(halJoinReqMsg.joinReqParams.bssId, + pwdiJoinParams->wdiReqInfo.macBSSID, WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(halJoinReqMsg.joinReqParams.selfStaMacAddr, + pwdiJoinParams->wdiReqInfo.macSTASelf, + WDI_MAC_ADDR_LEN); + + halJoinReqMsg.joinReqParams.ucChannel = + pwdiJoinParams->wdiReqInfo.wdiChannelInfo.ucChannel; + + halJoinReqMsg.joinReqParams.linkState = pwdiJoinParams->wdiReqInfo.linkState; + +#ifdef WLAN_FEATURE_VOWIFI + halJoinReqMsg.joinReqParams.maxTxPower = + pwdiJoinParams->wdiReqInfo.wdiChannelInfo.cMaxTxPower; +#else + halJoinReqMsg.joinReqParams.ucLocalPowerConstraint = + pwdiJoinParams->wdiReqInfo.wdiChannelInfo.ucLocalPowerConstraint; +#endif + + halJoinReqMsg.joinReqParams.secondaryChannelOffset = + WDI_2_HAL_SEC_CH_OFFSET(pwdiJoinParams->wdiReqInfo.wdiChannelInfo. + wdiSecondaryChannelOffset); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halJoinReqMsg.joinReqParams, + sizeof(halJoinReqMsg.joinReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiJoinParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiJoinParams->pUserData; + + /*------------------------------------------------------------------------- + Send Join Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiJoinRspCb, pUserData, WDI_JOIN_RESP); + +}/*WDI_ProcessBSSSessionJoinReq*/ + +/** + @brief Process Join Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessJoinReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + WDI_JoinReqParamsType* pwdiJoinParams = NULL; + WDI_JoinRspCb wdiJoinRspCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiJoinParams = (WDI_JoinReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiJoinRspCb = (WDI_JoinRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + if ( eWLAN_PAL_FALSE != pWDICtx->bAssociationInProgress ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Association is currently in progress, queueing new join req"); + + /*Association is in progress - queue current one*/ + wdiStatus = WDI_QueueNewAssocRequest(pWDICtx, pEventData, + pwdiJoinParams->wdiReqInfo.macBSSID); + + wpalMutexRelease(&pWDICtx->wptMutex); + + return wdiStatus; + } + + /*Starting a new association */ + pWDICtx->bAssociationInProgress = eWLAN_PAL_TRUE; + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Process the Join Request*/ + return WDI_ProcessBSSSessionJoinReq( pWDICtx, pwdiJoinParams, + wdiJoinRspCb,pEventData->pUserData); + +}/*WDI_ProcessJoinReq*/ + + +/** + @brief Process Config BSS Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigBSSReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ConfigBSSReqParamsType* pwdiConfigBSSParams; + WDI_ConfigBSSRspCb wdiConfigBSSRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint16 uMsgSize = 0; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + tConfigBssReqMsg halConfigBssReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(&halConfigBssReqMsg, sizeof(tConfigBssReqMsg)); + pwdiConfigBSSParams = (WDI_ConfigBSSReqParamsType*)pEventData->pEventData; + wdiConfigBSSRspCb = (WDI_ConfigBSSRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiConfigBSSParams->wdiReqInfo.macBSSID, + &pBSSSes); + + if ( NULL == pBSSSes ) + { +#ifdef WLAN_FEATURE_VOWIFI_11R + /*------------------------------------------------------------------------ + Fetch an empty session block + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindEmptySession( pWDICtx, &pBSSSes); + if ( NULL == pBSSSes ) + { + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "DAL has no free sessions - cannot run another join"); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_RES_FAILURE; + } + + /*Save BSS Session Info*/ + pBSSSes->bInUse = eWLAN_PAL_TRUE; + wpalMemoryCopy( pBSSSes->macBSSID, pwdiConfigBSSParams->wdiReqInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + /*Transition to state Joining*/ + pBSSSes->wdiAssocState = WDI_ASSOC_JOINING_ST; + pWDICtx->ucCurrentBSSSesIdx = ucCurrentBSSSesIdx; +#else + /* If the BSS type is IBSS create the session here as there is no Join + * Request in case of IBSS*/ + if((pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_IBSS_MODE) || + (pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_INFRA_AP_MODE) || + (pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_BTAMP_AP_MODE) || + (pwdiConfigBSSParams->wdiReqInfo.wdiBSSType == WDI_BTAMP_STA_MODE)) + { + /*------------------------------------------------------------------------ + Fetch an empty session block + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindEmptySession( pWDICtx, &pBSSSes); + if ( NULL == pBSSSes ) + { + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "DAL has no free sessions - cannot run another join"); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_RES_FAILURE; + } + + /*Save BSS Session Info*/ + pBSSSes->bInUse = eWLAN_PAL_TRUE; + wpalMemoryCopy( pBSSSes->macBSSID, pwdiConfigBSSParams->wdiReqInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + /*Transition to state Joining*/ + pBSSSes->wdiAssocState = WDI_ASSOC_JOINING_ST; + pWDICtx->ucCurrentBSSSesIdx = ucCurrentBSSSesIdx; + } + else + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist." MAC_ADDRESS_STR "wdiBssType %d", + __func__, MAC_ADDR_ARRAY(pwdiConfigBSSParams->wdiReqInfo.macBSSID), + pwdiConfigBSSParams->wdiReqInfo.wdiBSSType); + + /* for IBSS testing */ + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } +#endif + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. " MAC_ADDRESS_STR " bssIdx %d", + __func__, MAC_ADDR_ARRAY(pwdiConfigBSSParams->wdiReqInfo.macBSSID), + ucCurrentBSSSesIdx); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + + wpalMutexRelease(&pWDICtx->wptMutex); + + return wdiStatus; + } + + /* Cache the request for response processing */ + wpalMemoryCopy(&pWDICtx->wdiCachedConfigBssReq, + pwdiConfigBSSParams, + sizeof(pWDICtx->wdiCachedConfigBssReq)); + + wpalMutexRelease(&pWDICtx->wptMutex); + + /* Allocation of BssReqMsg Memory Based on Firmware Capabilities */ +#ifdef WLAN_FEATURE_11AC + if (WDI_getFwWlanFeatCaps(DOT11AC)) + uMsgSize = sizeof(halConfigBssReqMsg.uBssParams.configBssParams_V1); // Version - 1 For 11AC + else +#endif + uMsgSize = sizeof(halConfigBssReqMsg.uBssParams.configBssParams); // default Version - 0 Structure + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIG_BSS_REQ, + uMsgSize, &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + uMsgSize ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in config bss req %p %p %p", + pEventData, pwdiConfigBSSParams, wdiConfigBSSRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*Copy the BSS request */ +#ifdef WLAN_FEATURE_11AC + if (WDI_getFwWlanFeatCaps(DOT11AC)) + WDI_CopyWDIConfigBSSToHALConfigBSS( (tConfigBssParams*)&halConfigBssReqMsg.uBssParams.configBssParams_V1, + &pwdiConfigBSSParams->wdiReqInfo); + else +#endif + WDI_CopyWDIConfigBSSToHALConfigBSS( &halConfigBssReqMsg.uBssParams.configBssParams, + &pwdiConfigBSSParams->wdiReqInfo); + + /* Need to fill in the STA Index to invalid, since at this point we have not + yet received it from HAL */ + halConfigBssReqMsg.uBssParams.configBssParams.staContext.staIdx = WDI_STA_INVALID_IDX; + + /* Need to fill in the BSS index */ + halConfigBssReqMsg.uBssParams.configBssParams.staContext.bssIdx = pBSSSes->ucBSSIdx; + +#ifdef WLAN_FEATURE_11AC + if (WDI_getFwWlanFeatCaps(DOT11AC)){ + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halConfigBssReqMsg.uBssParams.configBssParams_V1, + uMsgSize); + }else +#endif + { + if ( uMsgSize <= sizeof(tConfigBssParams) ) + { + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halConfigBssReqMsg.uBssParams.configBssParams, + uMsgSize); + } + else + { + return WDI_STATUS_E_FAILURE; + } + } + + pWDICtx->wdiReqStatusCB = pwdiConfigBSSParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiConfigBSSParams->pUserData; + wpalMemoryZero(&halConfigBssReqMsg, sizeof(halConfigBssReqMsg)); + /*------------------------------------------------------------------------- + Send Config BSS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiConfigBSSRspCb, pEventData->pUserData, + WDI_CONFIG_BSS_RESP); + +}/*WDI_ProcessConfigBSSReq*/ + + +/** + @brief Process Del BSS Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBSSReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelBSSReqParamsType* pwdiDelBSSParams = NULL; + WDI_DelBSSRspCb wdiDelBSSRspCb = NULL; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + tDeleteBssReqMsg halBssReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiDelBSSParams = (WDI_DelBSSReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiDelBSSRspCb = (WDI_DelBSSRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx, + pwdiDelBSSParams->ucBssIdx, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: BSS does not yet exist. ucBssIdx %d", + __func__, pwdiDelBSSParams->ucBssIdx); + + wpalMutexRelease(&pWDICtx->wptMutex); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d", + __func__, pwdiDelBSSParams->ucBssIdx); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + + wpalMutexRelease(&pWDICtx->wptMutex); + + return wdiStatus; + } + + /*----------------------------------------------------------------------- + If we receive a Del BSS request for an association that is already in + progress, it indicates that the assoc has failed => we no longer have + an association in progress => we must check for pending associations + that were queued and start as soon as the Del BSS response is received + -----------------------------------------------------------------------*/ + if ( ucCurrentBSSSesIdx == pWDICtx->ucCurrentBSSSesIdx ) + { + /*We can switch to false here because even if a subsequent Join comes in + it will only be processed when DAL transitions out of BUSY state which + happens when the Del BSS request comes */ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + + /*Former association is complete - prepare next pending assoc for + processing */ + WDI_DequeueAssocRequest(pWDICtx); + } + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_BSS_REQ, + sizeof(halBssReqMsg.deleteBssParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halBssReqMsg.deleteBssParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in start req %p %p %p", + pEventData, pwdiDelBSSParams, wdiDelBSSRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*Fill in the message request structure*/ + + /*BSS Index is saved on config BSS response and Post Assoc Response */ + halBssReqMsg.deleteBssParams.bssIdx = pBSSSes->ucBSSIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halBssReqMsg.deleteBssParams, + sizeof(halBssReqMsg.deleteBssParams)); + + pWDICtx->wdiReqStatusCB = pwdiDelBSSParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiDelBSSParams->pUserData; + + + /*------------------------------------------------------------------------- + Send Del BSS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiDelBSSRspCb, pEventData->pUserData, WDI_DEL_BSS_RESP); + + +}/*WDI_ProcessDelBSSReq*/ + +/** + @brief Process Post Assoc Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPostAssocReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_PostAssocReqParamsType* pwdiPostAssocParams = NULL; + WDI_PostAssocRspCb wdiPostAssocRspCb = NULL; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 uMsgSize = 0; + wpt_uint16 uOffset = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + tPostAssocReqMsg halPostAssocReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiPostAssocParams = (WDI_PostAssocReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiPostAssocRspCb = (WDI_PostAssocRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiPostAssocParams->wdiBSSParams.macBSSID, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist - " + "operation not allowed. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiBSSParams.macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiBSSParams.macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + + wpalMutexRelease(&pWDICtx->wptMutex); + + return wdiStatus; + } + + /*----------------------------------------------------------------------- + If Post Assoc was not yet received - the current association must + be in progress + -----------------------------------------------------------------------*/ + if (( ucCurrentBSSSesIdx != pWDICtx->ucCurrentBSSSesIdx ) || + ( eWLAN_PAL_FALSE == pWDICtx->bAssociationInProgress )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association sequence for this BSS association no longer in " + "progress - not allowed"); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*----------------------------------------------------------------------- + Post Assoc Request is only allowed in Joining state + -----------------------------------------------------------------------*/ + if ( WDI_ASSOC_JOINING_ST != pBSSSes->wdiAssocState) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Post Assoc not allowed before JOIN - failing request"); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + uMsgSize = sizeof(halPostAssocReqMsg.postAssocReqParams.configStaParams) + + sizeof(halPostAssocReqMsg.postAssocReqParams.configBssParams) ; + /*----------------------------------------------------------------------- + Fill message for tx over the bus + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_POST_ASSOC_REQ, + uMsgSize,&pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + uMsgSize ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in start req %p %p %p", + pEventData, pwdiPostAssocParams, wdiPostAssocRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*Copy the STA parameters */ + WDI_CopyWDIStaCtxToHALStaCtx(&halPostAssocReqMsg.postAssocReqParams.configStaParams, + &pwdiPostAssocParams->wdiSTAParams ); + + /* Need to fill in the self STA Index */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDICtx, + pwdiPostAssocParams->wdiSTAParams.macSTA, + (wpt_uint8*)&halPostAssocReqMsg.postAssocReqParams.configStaParams.staIdx )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + MAC_ADDRESS_STR + ": This station does not exist in the WDI Station Table", + MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiSTAParams.macSTA)); + wpalMutexRelease(&pWDICtx->wptMutex); + wpalMemoryFree(pSendBuffer); + return WDI_STATUS_E_FAILURE; + } + + /* Need to fill in the BSS index */ + halPostAssocReqMsg.postAssocReqParams.configStaParams.bssIdx = + pBSSSes->ucBSSIdx; + + /*Copy the BSS parameters */ + WDI_CopyWDIConfigBSSToHALConfigBSS( &halPostAssocReqMsg.postAssocReqParams.configBssParams, + &pwdiPostAssocParams->wdiBSSParams); + + /* Need to fill in the STA index of the peer */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDICtx, + pwdiPostAssocParams->wdiBSSParams.wdiSTAContext.macSTA, + (wpt_uint8*)&halPostAssocReqMsg.postAssocReqParams.configBssParams.staContext.staIdx)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + MAC_ADDRESS_STR + ": This station does not exist in the WDI Station Table", + MAC_ADDR_ARRAY(pwdiPostAssocParams->wdiBSSParams.wdiSTAContext.macSTA)); + wpalMutexRelease(&pWDICtx->wptMutex); + wpalMemoryFree(pSendBuffer); + return WDI_STATUS_E_FAILURE; + } + + /* Need to fill in the BSS index */ + halPostAssocReqMsg.postAssocReqParams.configStaParams.bssIdx = + pBSSSes->ucBSSIdx; + + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halPostAssocReqMsg.postAssocReqParams.configStaParams, + sizeof(halPostAssocReqMsg.postAssocReqParams.configStaParams)); + + uOffset = sizeof(halPostAssocReqMsg.postAssocReqParams.configStaParams); + + wpalMemoryCopy( pSendBuffer+usDataOffset + uOffset, + &halPostAssocReqMsg.postAssocReqParams.configBssParams, + sizeof(halPostAssocReqMsg.postAssocReqParams.configBssParams)); + + + pWDICtx->wdiReqStatusCB = pwdiPostAssocParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiPostAssocParams->pUserData; + + + wpalMemoryCopy( &pWDICtx->wdiCachedPostAssocReq, + pwdiPostAssocParams, + sizeof(pWDICtx->wdiCachedPostAssocReq)); + + wpalMemoryZero(&halPostAssocReqMsg, sizeof(halPostAssocReqMsg)); + /*------------------------------------------------------------------------- + Send Post Assoc Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiPostAssocRspCb, pEventData->pUserData, WDI_POST_ASSOC_RESP); + + +}/*WDI_ProcessPostAssocReq*/ + +/** + @brief Process Del STA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelSTAReqParamsType* pwdiDelSTAParams; + WDI_DelSTARspCb wdiDelSTARspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_macAddr macBSSID; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + tDeleteStaReqMsg halDelStaReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiDelSTAParams = (WDI_DelSTAReqParamsType*)pEventData->pEventData; + wdiDelSTARspCb = (WDI_DelSTARspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiDelSTAParams->ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiDelSTAParams->ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_STA_REQ, + sizeof(halDelStaReqMsg.delStaParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halDelStaReqMsg.delStaParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in start req %p %p %p", + pEventData, pwdiDelSTAParams, wdiDelSTARspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halDelStaReqMsg.delStaParams.staIdx = pwdiDelSTAParams->ucSTAIdx; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halDelStaReqMsg.delStaParams, + sizeof(halDelStaReqMsg.delStaParams)); + + pWDICtx->wdiReqStatusCB = pwdiDelSTAParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiDelSTAParams->pUserData; + + /*------------------------------------------------------------------------- + Send Del STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiDelSTARspCb, pEventData->pUserData, WDI_DEL_STA_RESP); + +}/*WDI_ProcessDelSTAReq*/ + + +/*========================================================================== + SECURITY REQUEST PROCESSING API +==========================================================================*/ +/** + @brief Process Set BSS Key Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBssKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetBSSKeyReqParamsType* pwdiSetBSSKeyParams; + WDI_SetBSSKeyRspCb wdiSetBSSKeyRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + tSetBssKeyReqMsg halSetBssKeyReqMsg = {{0}}; + wpt_uint8 keyIndex = 0; + wpt_uint8 i; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetBSSKeyParams = (WDI_SetBSSKeyReqParamsType*)pEventData->pEventData; + wdiSetBSSKeyRspCb = (WDI_SetBSSKeyRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx, + pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucBssIdx, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. ucBssIdx %d", + __func__, pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucBssIdx); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d", + __func__, pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucBssIdx); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_BSS_KEY_REQ, + sizeof(halSetBssKeyReqMsg.setBssKeyParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetBssKeyReqMsg.setBssKeyParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiSetBSSKeyParams, wdiSetBSSKeyRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Copy the Key parameters into the HAL message + -----------------------------------------------------------------------*/ + + halSetBssKeyReqMsg.setBssKeyParams.bssIdx = ucCurrentBSSSesIdx; + + halSetBssKeyReqMsg.setBssKeyParams.encType = + WDI_2_HAL_ENC_TYPE (pwdiSetBSSKeyParams->wdiBSSKeyInfo.wdiEncType); + + halSetBssKeyReqMsg.setBssKeyParams.numKeys = + pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucNumKeys; + + for(keyIndex = 0; keyIndex < pwdiSetBSSKeyParams->wdiBSSKeyInfo.ucNumKeys ; + keyIndex++) + { + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyId = + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyId; + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].unicast = + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].unicast; + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyDirection = + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyDirection; + + if(WDI_getHostWlanFeatCaps(DISA) && WDI_getFwWlanFeatCaps(DISA)) + { + for (i = 0; i < WDI_MAX_KEY_RSC_LEN; i++) + { + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyRsc[i] = + ~(pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyRsc[i]); + } + + for (i = 0; i < WDI_MAX_KEY_LENGTH; i++) + { + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].key[i] = + ~(pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].key[i]); + } + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Negated Keys", __func__); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: No change in Keys", __func__); + wpalMemoryCopy(halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyRsc, + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyRsc, + WDI_MAX_KEY_RSC_LEN); + wpalMemoryCopy(halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].key, + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].key, + WDI_MAX_KEY_LENGTH); + } + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].paeRole = + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].paeRole; + halSetBssKeyReqMsg.setBssKeyParams.key[keyIndex].keyLength = + pwdiSetBSSKeyParams->wdiBSSKeyInfo.aKeys[keyIndex].keyLength; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetBssKeyReqMsg.setBssKeyParams, + sizeof(halSetBssKeyReqMsg.setBssKeyParams)); + + pWDICtx->wdiReqStatusCB = pwdiSetBSSKeyParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetBSSKeyParams->pUserData; + + /*------------------------------------------------------------------------- + Send Set BSS Key Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetBSSKeyRspCb, pEventData->pUserData, + WDI_SET_BSS_KEY_RESP); + +}/*WDI_ProcessSetBssKeyReq*/ + +/** + @brief Process Remove BSS Key Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveBssKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RemoveBSSKeyReqParamsType* pwdiRemoveBSSKeyParams; + WDI_RemoveBSSKeyRspCb wdiRemoveBSSKeyRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + tRemoveBssKeyReqMsg halRemoveBssKeyReqMsg = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiRemoveBSSKeyParams = (WDI_RemoveBSSKeyReqParamsType*)pEventData->pEventData; + wdiRemoveBSSKeyRspCb = (WDI_RemoveBSSKeyRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx, + pwdiRemoveBSSKeyParams->wdiKeyInfo.ucBssIdx, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. ucBssIdx %d", + __func__, pwdiRemoveBSSKeyParams->wdiKeyInfo.ucBssIdx); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d", + __func__, pwdiRemoveBSSKeyParams->wdiKeyInfo.ucBssIdx); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RMV_BSS_KEY_REQ, + sizeof(halRemoveBssKeyReqMsg.removeBssKeyParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halRemoveBssKeyReqMsg.removeBssKeyParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiRemoveBSSKeyParams, wdiRemoveBSSKeyRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /*----------------------------------------------------------------------- + Copy the Key parameters into the HAL message + -----------------------------------------------------------------------*/ + halRemoveBssKeyReqMsg.removeBssKeyParams.bssIdx = ucCurrentBSSSesIdx; + + halRemoveBssKeyReqMsg.removeBssKeyParams.encType = + WDI_2_HAL_ENC_TYPE (pwdiRemoveBSSKeyParams->wdiKeyInfo.wdiEncType); + + halRemoveBssKeyReqMsg.removeBssKeyParams.keyId = pwdiRemoveBSSKeyParams->wdiKeyInfo.ucKeyId; + + halRemoveBssKeyReqMsg.removeBssKeyParams.wepType = + WDI_2_HAL_WEP_TYPE(pwdiRemoveBSSKeyParams->wdiKeyInfo.wdiWEPType); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halRemoveBssKeyReqMsg.removeBssKeyParams, + sizeof(halRemoveBssKeyReqMsg.removeBssKeyParams)); + + pWDICtx->wdiReqStatusCB = pwdiRemoveBSSKeyParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRemoveBSSKeyParams->pUserData; + + /*------------------------------------------------------------------------- + Send Remove BSS Key Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRemoveBSSKeyRspCb, pEventData->pUserData, + WDI_RMV_BSS_KEY_RESP); +}/*WDI_ProcessRemoveBssKeyReq*/ + +/** + @brief Process Set STA KeyRequest function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetSTAKeyReqParamsType* pwdiSetSTAKeyParams; + WDI_SetSTAKeyRspCb wdiSetSTAKeyRspCb; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + wpt_uint8 ucCurrentBSSSesIdx; + tSetStaKeyReqMsg halSetStaKeyReqMsg = {{0}}; + wpt_uint8 keyIndex = 0; + wpt_uint8 i; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetSTAKeyParams = (WDI_SetSTAKeyReqParamsType*)pEventData->pEventData; + wdiSetSTAKeyRspCb = (WDI_SetSTAKeyRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_STA_KEY_REQ, + sizeof(halSetStaKeyReqMsg.setStaKeyParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetStaKeyReqMsg.setStaKeyParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiSetSTAKeyParams, wdiSetSTAKeyRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /*----------------------------------------------------------------------- + Copy the STA Key parameters into the HAL message + -----------------------------------------------------------------------*/ + halSetStaKeyReqMsg.setStaKeyParams.encType = + WDI_2_HAL_ENC_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiEncType); + + halSetStaKeyReqMsg.setStaKeyParams.wepType = + WDI_2_HAL_WEP_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiWEPType ); + + halSetStaKeyReqMsg.setStaKeyParams.staIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx; + + halSetStaKeyReqMsg.setStaKeyParams.defWEPIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucDefWEPIdx; + + halSetStaKeyReqMsg.setStaKeyParams.singleTidRc = pwdiSetSTAKeyParams->wdiKeyInfo.ucSingleTidRc; + + for(keyIndex = 0; keyIndex < pwdiSetSTAKeyParams->wdiKeyInfo.ucNumKeys ; + keyIndex++) + { + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyId = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyId; + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].unicast = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].unicast; + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyDirection = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyDirection; + + if(WDI_getHostWlanFeatCaps(DISA) && WDI_getFwWlanFeatCaps(DISA)) + { + for (i = 0; i < WDI_MAX_KEY_RSC_LEN; i++) + { + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc[i] = + ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc[i]); + } + + for (i = 0; i< WDI_MAX_KEY_LENGTH; i++) + { + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key[i] = + ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key[i]); + } + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Negated Keys", __func__); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: No change in Keys", __func__); + wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc, + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc, + WDI_MAX_KEY_RSC_LEN); + wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key, + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key, + WDI_MAX_KEY_LENGTH); + } + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].paeRole = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].paeRole; + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyLength = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyLength; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetStaKeyReqMsg.setStaKeyParams, + sizeof(halSetStaKeyReqMsg.setStaKeyParams)); + + pWDICtx->wdiReqStatusCB = pwdiSetSTAKeyParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetSTAKeyParams->pUserData; + wpalMemoryZero(&halSetStaKeyReqMsg, sizeof(halSetStaKeyReqMsg)); + /*------------------------------------------------------------------------- + Send Set STA Key Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetSTAKeyRspCb, pEventData->pUserData, + WDI_SET_STA_KEY_RESP); + +}/*WDI_ProcessSetSTAKeyReq*/ + +/** + @brief Process Remove STA Key Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTAKeyParams; + WDI_RemoveSTAKeyRspCb wdiRemoveSTAKeyRspCb; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + wpt_uint8 ucCurrentBSSSesIdx; + tRemoveStaKeyReqMsg halRemoveStaKeyReqMsg = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiRemoveSTAKeyParams = (WDI_RemoveSTAKeyReqParamsType*)pEventData->pEventData; + wdiRemoveSTAKeyRspCb = (WDI_RemoveSTAKeyRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiRemoveSTAKeyParams->wdiKeyInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiRemoveSTAKeyParams->wdiKeyInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RMV_STA_KEY_REQ, + sizeof(halRemoveStaKeyReqMsg.removeStaKeyParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halRemoveStaKeyReqMsg.removeStaKeyParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiRemoveSTAKeyParams, wdiRemoveSTAKeyRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Copy the Key parameters into the HAL message + -----------------------------------------------------------------------*/ + + halRemoveStaKeyReqMsg.removeStaKeyParams.staIdx = + pwdiRemoveSTAKeyParams->wdiKeyInfo.ucSTAIdx; + + halRemoveStaKeyReqMsg.removeStaKeyParams.encType = + WDI_2_HAL_ENC_TYPE (pwdiRemoveSTAKeyParams->wdiKeyInfo.wdiEncType); + + halRemoveStaKeyReqMsg.removeStaKeyParams.keyId = + pwdiRemoveSTAKeyParams->wdiKeyInfo.ucKeyId; + + halRemoveStaKeyReqMsg.removeStaKeyParams.unicast = + pwdiRemoveSTAKeyParams->wdiKeyInfo.ucUnicast; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halRemoveStaKeyReqMsg.removeStaKeyParams, + sizeof(halRemoveStaKeyReqMsg.removeStaKeyParams)); + + pWDICtx->wdiReqStatusCB = pwdiRemoveSTAKeyParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRemoveSTAKeyParams->pUserData; + + /*------------------------------------------------------------------------- + Send Remove STA Key Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRemoveSTAKeyRspCb, pEventData->pUserData, + WDI_RMV_STA_KEY_RESP); + +}/*WDI_ProcessRemoveSTAKeyReq*/ + +/** + @brief Process Set STA KeyRequest function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaBcastKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetSTAKeyReqParamsType* pwdiSetSTAKeyParams; + WDI_SetSTAKeyRspCb wdiSetSTAKeyRspCb; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + wpt_uint8 ucCurrentBSSSesIdx; + tSetStaKeyReqMsg halSetStaKeyReqMsg = {{0}}; + wpt_uint8 keyIndex = 0; + wpt_uint8 i; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetSTAKeyParams = (WDI_SetSTAKeyReqParamsType*)pEventData->pEventData; + wdiSetSTAKeyRspCb = (WDI_SetSTAKeyRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_STA_KEY_REQ, + sizeof(halSetStaKeyReqMsg.setStaKeyParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetStaKeyReqMsg.setStaKeyParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiSetSTAKeyParams, wdiSetSTAKeyRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /*----------------------------------------------------------------------- + Copy the STA Key parameters into the HAL message + -----------------------------------------------------------------------*/ + halSetStaKeyReqMsg.setStaKeyParams.encType = + WDI_2_HAL_ENC_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiEncType); + + halSetStaKeyReqMsg.setStaKeyParams.wepType = + WDI_2_HAL_WEP_TYPE (pwdiSetSTAKeyParams->wdiKeyInfo.wdiWEPType ); + + halSetStaKeyReqMsg.setStaKeyParams.staIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucSTAIdx; + + halSetStaKeyReqMsg.setStaKeyParams.defWEPIdx = pwdiSetSTAKeyParams->wdiKeyInfo.ucDefWEPIdx; + + halSetStaKeyReqMsg.setStaKeyParams.singleTidRc = pwdiSetSTAKeyParams->wdiKeyInfo.ucSingleTidRc; + + for(keyIndex = 0; keyIndex < pwdiSetSTAKeyParams->wdiKeyInfo.ucNumKeys ; + keyIndex++) + { + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyId = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyId; + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].unicast = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].unicast; + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyDirection = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyDirection; + + if(WDI_getHostWlanFeatCaps(DISA) && WDI_getFwWlanFeatCaps(DISA)) + { + for (i = 0; i < WDI_MAX_KEY_RSC_LEN; i++) + { + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc[i] = + ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc[i]); + } + + for (i = 0; i< WDI_MAX_KEY_LENGTH; i++) + { + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key[i] = + ~(pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key[i]); + } + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Negated Keys", __func__); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: No change in Keys", __func__); + wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyRsc, + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyRsc, + WDI_MAX_KEY_RSC_LEN); + wpalMemoryCopy(halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].key, + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].key, + WDI_MAX_KEY_LENGTH); + } + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].paeRole = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].paeRole; + halSetStaKeyReqMsg.setStaKeyParams.key[keyIndex].keyLength = + pwdiSetSTAKeyParams->wdiKeyInfo.wdiKey[keyIndex].keyLength; + } + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetStaKeyReqMsg.setStaKeyParams, + sizeof(halSetStaKeyReqMsg.setStaKeyParams)); + + pWDICtx->wdiReqStatusCB = pwdiSetSTAKeyParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetSTAKeyParams->pUserData; + + /*------------------------------------------------------------------------- + Send Set STA Key Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetSTAKeyRspCb, pEventData->pUserData, + WDI_SET_STA_KEY_RESP); + +}/*WDI_ProcessSetSTABcastKeyReq*/ + +/** + @brief Process Remove STA Key Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaBcastKeyReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RemoveSTAKeyReqParamsType* pwdiRemoveSTABcastKeyParams; + WDI_RemoveSTAKeyRspCb wdiRemoveSTAKeyRspCb; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + wpt_uint8 ucCurrentBSSSesIdx; + tRemoveStaKeyReqMsg halRemoveStaBcastKeyReqMsg = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiRemoveSTABcastKeyParams = (WDI_RemoveSTAKeyReqParamsType*)pEventData->pEventData; + wdiRemoveSTAKeyRspCb = (WDI_RemoveSTAKeyRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RMV_STA_BCAST_KEY_REQ, + sizeof(halRemoveStaBcastKeyReqMsg.removeStaKeyParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halRemoveStaBcastKeyReqMsg.removeStaKeyParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiRemoveSTABcastKeyParams, wdiRemoveSTAKeyRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Copy the Key parameters into the HAL message + -----------------------------------------------------------------------*/ + + halRemoveStaBcastKeyReqMsg.removeStaKeyParams.staIdx = + pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucSTAIdx; + + halRemoveStaBcastKeyReqMsg.removeStaKeyParams.encType = + WDI_2_HAL_ENC_TYPE (pwdiRemoveSTABcastKeyParams->wdiKeyInfo.wdiEncType); + + halRemoveStaBcastKeyReqMsg.removeStaKeyParams.keyId = + pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucKeyId; + + halRemoveStaBcastKeyReqMsg.removeStaKeyParams.unicast = + pwdiRemoveSTABcastKeyParams->wdiKeyInfo.ucUnicast; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halRemoveStaBcastKeyReqMsg.removeStaKeyParams, + sizeof(halRemoveStaBcastKeyReqMsg.removeStaKeyParams)); + + pWDICtx->wdiReqStatusCB = pwdiRemoveSTABcastKeyParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRemoveSTABcastKeyParams->pUserData; + + /*------------------------------------------------------------------------- + Send Remove STA Key Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRemoveSTAKeyRspCb, pEventData->pUserData, + WDI_RMV_STA_KEY_RESP); + +}/*WDI_ProcessRemoveSTABcastKeyReq*/ + +/*========================================================================== + QOS and BA PROCESSING REQUEST API +==========================================================================*/ +/** + @brief Process Add TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddTSReqParamsType* pwdiAddTSParams; + WDI_AddTsRspCb wdiAddTSRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + tAddTsParams halAddTsParams = {0}; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiAddTSParams = (WDI_AddTSReqParamsType*)pEventData->pEventData; + wdiAddTSRspCb = (WDI_AddTsRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiAddTSParams->wdiTsInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiAddTSParams->wdiTsInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ADD_TS_REQ, + sizeof(halAddTsParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halAddTsParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiAddTSParams, wdiAddTSRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halAddTsParams.staIdx = pwdiAddTSParams->wdiTsInfo.ucSTAIdx; + halAddTsParams.tspecIdx = pwdiAddTSParams->wdiTsInfo.ucTspecIdx; + + //TSPEC IE + halAddTsParams.tspec.type = pwdiAddTSParams->wdiTsInfo.wdiTspecIE.ucType; + halAddTsParams.tspec.length = pwdiAddTSParams->wdiTsInfo.wdiTspecIE.ucLength; + halAddTsParams.tspec.nomMsduSz = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usNomMsduSz; + halAddTsParams.tspec.maxMsduSz = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usMaxMsduSz; + halAddTsParams.tspec.minSvcInterval = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMinSvcInterval; + halAddTsParams.tspec.maxSvcInterval = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMaxSvcInterval; + halAddTsParams.tspec.inactInterval = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uInactInterval; + halAddTsParams.tspec.suspendInterval = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uSuspendInterval; + halAddTsParams.tspec.svcStartTime = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uSvcStartTime; + halAddTsParams.tspec.minDataRate = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMinDataRate; + halAddTsParams.tspec.meanDataRate = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMeanDataRate; + halAddTsParams.tspec.peakDataRate = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uPeakDataRate; + halAddTsParams.tspec.maxBurstSz = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMaxBurstSz; + halAddTsParams.tspec.delayBound = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uDelayBound; + halAddTsParams.tspec.minPhyRate = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.uMinPhyRate; + halAddTsParams.tspec.surplusBw = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usSurplusBw; + halAddTsParams.tspec.mediumTime = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.usMediumTime; + + //TSPEC IE : TS INFO : TRAFFIC + halAddTsParams.tspec.tsinfo.traffic.ackPolicy = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.accessPolicy; + halAddTsParams.tspec.tsinfo.traffic.userPrio = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.userPrio; + halAddTsParams.tspec.tsinfo.traffic.psb = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.psb; + halAddTsParams.tspec.tsinfo.traffic.aggregation = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.aggregation; + halAddTsParams.tspec.tsinfo.traffic.direction = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.direction; + halAddTsParams.tspec.tsinfo.traffic.tsid = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.tsid; + halAddTsParams.tspec.tsinfo.traffic.trafficType = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiTraffic.trafficType; + + //TSPEC IE : TS INFO : SCHEDULE + halAddTsParams.tspec.tsinfo.schedule.rsvd = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiSchedule.rsvd; + halAddTsParams.tspec.tsinfo.schedule.schedule = + pwdiAddTSParams->wdiTsInfo.wdiTspecIE.wdiTSinfo.wdiSchedule.schedule; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halAddTsParams, + sizeof(halAddTsParams)); + + pWDICtx->wdiReqStatusCB = pwdiAddTSParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiAddTSParams->pUserData; + + /*------------------------------------------------------------------------- + Send Add TS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiAddTSRspCb, pEventData->pUserData, + WDI_ADD_TS_RESP); +}/*WDI_ProcessAddTSpecReq*/ + + +/** + @brief Process Del TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelTSReqParamsType* pwdiDelTSParams; + WDI_DelTsRspCb wdiDelTSRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiDelTSParams = (WDI_DelTSReqParamsType*)pEventData->pEventData; + wdiDelTSRspCb = (WDI_DelTsRspCb)pEventData->pCBfnc; + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiDelTSParams->wdiDelTSInfo.macBSSID, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiDelTSParams->wdiDelTSInfo.macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiDelTSParams->wdiDelTSInfo.macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_TS_REQ, + sizeof(pwdiDelTSParams->wdiDelTSInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiDelTSParams->wdiDelTSInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiDelTSParams, wdiDelTSRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiDelTSParams->wdiDelTSInfo, + sizeof(pwdiDelTSParams->wdiDelTSInfo)); + + pWDICtx->wdiReqStatusCB = pwdiDelTSParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiDelTSParams->pUserData; + + /*------------------------------------------------------------------------- + Send Del TS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiDelTSRspCb, pEventData->pUserData, WDI_DEL_TS_RESP); +}/*WDI_ProcessDelTSpecReq*/ + +/** + @brief Process Update EDCA Params Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateEDCAParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateEDCAParamsType* pwdiUpdateEDCAParams; + WDI_UpdateEDCAParamsRspCb wdiUpdateEDCARspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiUpdateEDCAParams = (WDI_UpdateEDCAParamsType*)pEventData->pEventData; + wdiUpdateEDCARspCb = (WDI_UpdateEDCAParamsRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx, + pwdiUpdateEDCAParams->wdiEDCAInfo.ucBssIdx, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. ucBssIdx %d", + __func__, pwdiUpdateEDCAParams->wdiEDCAInfo.ucBssIdx); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. ucBssIdx %d", + __func__, pwdiUpdateEDCAParams->wdiEDCAInfo.ucBssIdx); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_EDCA_PRMS_REQ, + sizeof(pwdiUpdateEDCAParams->wdiEDCAInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiUpdateEDCAParams->wdiEDCAInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiUpdateEDCAParams, wdiUpdateEDCARspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiUpdateEDCAParams->wdiEDCAInfo, + sizeof(pwdiUpdateEDCAParams->wdiEDCAInfo)); + + pWDICtx->wdiReqStatusCB = pwdiUpdateEDCAParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateEDCAParams->pUserData; + + /*------------------------------------------------------------------------- + Send Update EDCA Params Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiUpdateEDCARspCb, pEventData->pUserData, + WDI_UPD_EDCA_PRMS_RESP); +}/*WDI_ProcessUpdateEDCAParamsReq*/ + +/** + @brief Process Add BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBASessionReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddBASessionReqParamsType* pwdiAddBASessionParams; + WDI_AddBASessionRspCb wdiAddBASessionRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + + tAddBASessionReqMsg halAddBASessionReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiAddBASessionParams = + (WDI_AddBASessionReqParamsType*)pEventData->pEventData; + wdiAddBASessionRspCb = + (WDI_AddBASessionRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiAddBASessionParams->wdiBASessionInfoType.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiAddBASessionParams->wdiBASessionInfoType.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_ADD_BA_SESSION_REQ, + sizeof(halAddBASessionReq.addBASessionParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < + (usDataOffset + sizeof(halAddBASessionReq.addBASessionParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Add BA session req %p %p %p", + pEventData, pwdiAddBASessionParams, wdiAddBASessionRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halAddBASessionReq.addBASessionParams.staIdx = + pwdiAddBASessionParams->wdiBASessionInfoType.ucSTAIdx; + wpalMemoryCopy(halAddBASessionReq.addBASessionParams.peerMacAddr, + pwdiAddBASessionParams->wdiBASessionInfoType.macPeerAddr, + WDI_MAC_ADDR_LEN); + halAddBASessionReq.addBASessionParams.baTID = + pwdiAddBASessionParams->wdiBASessionInfoType.ucBaTID; + halAddBASessionReq.addBASessionParams.baPolicy = + pwdiAddBASessionParams->wdiBASessionInfoType.ucBaPolicy; + halAddBASessionReq.addBASessionParams.baBufferSize = + pwdiAddBASessionParams->wdiBASessionInfoType.usBaBufferSize; + halAddBASessionReq.addBASessionParams.baTimeout = + pwdiAddBASessionParams->wdiBASessionInfoType.usBaTimeout; + halAddBASessionReq.addBASessionParams.baSSN = + pwdiAddBASessionParams->wdiBASessionInfoType.usBaSSN; + halAddBASessionReq.addBASessionParams.baDirection = + pwdiAddBASessionParams->wdiBASessionInfoType.ucBaDirection; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halAddBASessionReq.addBASessionParams, + sizeof(halAddBASessionReq.addBASessionParams)); + + pWDICtx->wdiReqStatusCB = pwdiAddBASessionParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiAddBASessionParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiAddBASessionRspCb, pEventData->pUserData, + WDI_ADD_BA_SESSION_RESP); +}/*WDI_ProcessAddBASessionReq*/ + +/** + @brief Process Del BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelBAReqParamsType* pwdiDelBAParams; + WDI_DelBARspCb wdiDelBARspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + tDelBAParams halDelBAparam; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiDelBAParams = (WDI_DelBAReqParamsType*)pEventData->pEventData; + wdiDelBARspCb = (WDI_DelBARspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiDelBAParams->wdiBAInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiDelBAParams->wdiBAInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_BA_REQ, + sizeof(halDelBAparam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halDelBAparam) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer for DEL BA req %p %p %p", + pEventData, pwdiDelBAParams, wdiDelBARspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halDelBAparam.staIdx = pwdiDelBAParams->wdiBAInfo.ucSTAIdx; + halDelBAparam.baTID = pwdiDelBAParams->wdiBAInfo.ucBaTID; + halDelBAparam.baDirection = pwdiDelBAParams->wdiBAInfo.ucBaDirection; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halDelBAparam, + sizeof(halDelBAparam)); + + pWDICtx->wdiReqStatusCB = pwdiDelBAParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiDelBAParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiDelBARspCb, pEventData->pUserData, WDI_DEL_BA_RESP); +}/*WDI_ProcessDelBAReq*/ + +#ifdef FEATURE_WLAN_ESE + +WDI_Status +WDI_ProcessTSMStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_TSMStatsReqParamsType* pwdiTSMParams; + WDI_TsmRspCb wdiTSMRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + tTsmStatsParams halTsmStatsReqParams = {0}; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiTSMParams = (WDI_TSMStatsReqParamsType*)pEventData->pEventData; + wdiTSMRspCb = (WDI_TsmRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, pwdiTSMParams->wdiTsmStatsParamsInfo.bssid, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiTSMParams->wdiTsmStatsParamsInfo.bssid)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiTSMParams->wdiTsmStatsParamsInfo.bssid)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_TSM_STATS_REQ, + sizeof(halTsmStatsReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halTsmStatsReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiTSMParams, wdiTSMRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halTsmStatsReqParams.tsmTID = pwdiTSMParams->wdiTsmStatsParamsInfo.ucTid; + wpalMemoryCopy(halTsmStatsReqParams.bssId, + pwdiTSMParams->wdiTsmStatsParamsInfo.bssid, + WDI_MAC_ADDR_LEN); + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halTsmStatsReqParams, + sizeof(halTsmStatsReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiTSMParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiTSMParams->pUserData; + + /*------------------------------------------------------------------------- + Send TSM Stats Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiTSMRspCb, pEventData->pUserData, + WDI_TSM_STATS_RESP); +}/*WDI_ProcessTSMStatsReq*/ + +#endif + + +/** + @brief Process Flush AC Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFlushAcReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FlushAcReqParamsType* pwdiFlushAcParams = NULL; + WDI_FlushAcRspCb wdiFlushAcRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiFlushAcParams = (WDI_FlushAcReqParamsType*)pEventData->pEventData; + wdiFlushAcRspCb = (WDI_FlushAcRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_FLUSH_AC_REQ, + sizeof(pwdiFlushAcParams->wdiFlushAcInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiFlushAcParams->wdiFlushAcInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiFlushAcParams, wdiFlushAcRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiFlushAcParams->wdiFlushAcInfo, + sizeof(pwdiFlushAcParams->wdiFlushAcInfo)); + + pWDICtx->wdiReqStatusCB = pwdiFlushAcParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiFlushAcParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiFlushAcRspCb, pEventData->pUserData, WDI_FLUSH_AC_RESP); +}/*WDI_ProcessFlushAcReq*/ + +/** + @brief Process BT AMP event Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBtAmpEventReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_BtAmpEventParamsType* pwdiBtAmpEventParams = NULL; + WDI_BtAmpEventRspCb wdiBtAmpEventRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + tBtAmpEventMsg haltBtAmpEventMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiBtAmpEventParams = (WDI_BtAmpEventParamsType*)pEventData->pEventData; + wdiBtAmpEventRspCb = (WDI_BtAmpEventRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_BTAMP_EVENT_REQ, + sizeof(haltBtAmpEventMsg.btAmpEventParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(haltBtAmpEventMsg.btAmpEventParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in BT AMP event req %p %p %p", + pEventData, pwdiBtAmpEventParams, wdiBtAmpEventRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + haltBtAmpEventMsg.btAmpEventParams.btAmpEventType = + pwdiBtAmpEventParams->wdiBtAmpEventInfo.ucBtAmpEventType; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &haltBtAmpEventMsg.btAmpEventParams, + sizeof(haltBtAmpEventMsg.btAmpEventParams)); + + pWDICtx->wdiReqStatusCB = pwdiBtAmpEventParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiBtAmpEventParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiBtAmpEventRspCb, pEventData->pUserData, WDI_BTAMP_EVENT_RESP); +}/*WDI_ProcessBtAmpEventReq*/ + +/** + @brief Process Add STA self Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddSTASelfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddSTASelfReqParamsType* pwdiAddSTASelfReqParams; + WDI_AddSTASelfParamsRspCb wdiAddSTASelfReqRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tAddStaSelfParams_V1 halAddSTASelfParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiAddSTASelfReqParams = + (WDI_AddSTASelfReqParamsType*)pEventData->pEventData; + wdiAddSTASelfReqRspCb = + (WDI_AddSTASelfParamsRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_ADD_STA_SELF_REQ, + sizeof(tAddStaSelfParams_V1), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tAddStaSelfParams_V1) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in ADD STA SELF REQ %p %p %p", + pEventData, pwdiAddSTASelfReqParams, wdiAddSTASelfReqRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Cache the request for response processing */ + wpalMemoryCopy(&pWDICtx->wdiCacheAddSTASelfReq, pwdiAddSTASelfReqParams, + sizeof(pWDICtx->wdiCacheAddSTASelfReq)); + + wpalMemoryCopy(halAddSTASelfParams.selfMacAddr, + pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.selfMacAddr, 6); + halAddSTASelfParams.iface_persona = HAL_IFACE_UNKNOWN; + if (pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.currDeviceMode == VOS_STA_MODE) + { + halAddSTASelfParams.iface_persona = HAL_IFACE_STA_MODE; + } + else if ((pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.currDeviceMode == + VOS_P2P_CLIENT_MODE) || + (pwdiAddSTASelfReqParams->wdiAddSTASelfInfo.currDeviceMode == + VOS_P2P_DEVICE)) + { + halAddSTASelfParams.iface_persona = HAL_IFACE_P2P_MODE; + } + wpalMemoryCopy( pSendBuffer+usDataOffset, &halAddSTASelfParams, + sizeof(tAddStaSelfParams_V1)); + + pWDICtx->wdiReqStatusCB = pwdiAddSTASelfReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiAddSTASelfReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Update Probe Resp Template Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiAddSTASelfReqRspCb, pEventData->pUserData, + WDI_ADD_STA_SELF_RESP); +}/*WDI_ProcessAddSTASelfReq*/ + + + +/** + @brief Process Del Sta Self Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTASelfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelSTASelfReqParamsType* pwdiDelStaSelfReqParams; + WDI_DelSTASelfRspCb wdiDelStaSelfRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tDelStaSelfParams halSetDelSelfSTAParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiDelStaSelfReqParams = + (WDI_DelSTASelfReqParamsType*)pEventData->pEventData; + wdiDelStaSelfRspCb = (WDI_DelSTASelfRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_DEL_STA_SELF_REQ, + sizeof(pwdiDelStaSelfReqParams->wdiDelStaSelfInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < + (usDataOffset + sizeof(pwdiDelStaSelfReqParams->wdiDelStaSelfInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Del Sta Self req %p %p %p", + pEventData, pwdiDelStaSelfReqParams, wdiDelStaSelfRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(halSetDelSelfSTAParams.selfMacAddr, + pwdiDelStaSelfReqParams->wdiDelStaSelfInfo.selfMacAddr, 6) ; + + wpalMemoryCopy( pSendBuffer+usDataOffset, &halSetDelSelfSTAParams, + sizeof(tDelStaSelfParams)); + + pWDICtx->wdiReqStatusCB = pwdiDelStaSelfReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiDelStaSelfReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiDelStaSelfRspCb, pEventData->pUserData, + WDI_DEL_STA_SELF_RESP); + +} + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief Process Start Oem Data Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_oemDataReqParamsType* pwdiOemDataReqParams = NULL; + WDI_oemDataRspCb wdiOemDataRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 reqLen; + tStartOemDataReqParams* halStartOemDataReqParams; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiOemDataReqParams = (WDI_oemDataReqParamsType*)pEventData->pEventData; + wdiOemDataRspCb = (WDI_oemDataRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + reqLen = sizeof(tStartOemDataReqParams); + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_START_OEM_DATA_REQ, reqLen, + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + reqLen))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Start Oem Data req %p %p %p", + pEventData, pwdiOemDataReqParams, wdiOemDataRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + //copying WDI OEM DATA REQ PARAMS to shared memory + halStartOemDataReqParams = (tStartOemDataReqParams *)(pSendBuffer + usDataOffset ); + + wpalMemoryCopy(&halStartOemDataReqParams->selfMacAddr, &pwdiOemDataReqParams->wdiOemDataReqInfo.selfMacAddr, sizeof(wpt_macAddr)); + wpalMemoryCopy(&halStartOemDataReqParams->oemDataReq, &pwdiOemDataReqParams->wdiOemDataReqInfo.oemDataReq, OEM_DATA_REQ_SIZE); + + pWDICtx->wdiReqStatusCB = pwdiOemDataReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiOemDataReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiOemDataRspCb, pEventData->pUserData, + WDI_START_OEM_DATA_RESP); +}/*WDI_ProcessStartOemDataReq*/ +#endif + +/** + @brief Process Host Resume Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostResumeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ResumeParamsType* pwdiHostResumeParams = NULL; + WDI_HostResumeEventRspCb wdiHostResumeRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalWlanHostResumeReqParam halResumeReqParams; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters ",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiHostResumeParams = (WDI_ResumeParamsType*)pEventData->pEventData; + wdiHostResumeRspCb = (WDI_HostResumeEventRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_HOST_RESUME_REQ, sizeof(halResumeReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(halResumeReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Start Oem Data req %p %p %p", + pEventData, pwdiHostResumeParams, wdiHostResumeRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halResumeReqParams.configuredMcstBcstFilterSetting = + pwdiHostResumeParams->wdiResumeParams.ucConfiguredMcstBcstFilterSetting; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halResumeReqParams, + sizeof(halResumeReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiHostResumeParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiHostResumeParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiHostResumeRspCb, pEventData->pUserData, + WDI_HOST_RESUME_RESP); +}/*WDI_ProcessHostResumeReq*/ + +/** + @brief Process set Tx Per Tracking Parameters Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPerTrackingReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetTxPerTrackingReqParamsType* pwdiSetTxPerTrackingReqParams = NULL; + WDI_SetTxPerTrackingRspCb pwdiSetTxPerTrackingRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalTxPerTrackingReqParam halTxPerTrackingReqParam; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters ",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetTxPerTrackingReqParams = (WDI_SetTxPerTrackingReqParamsType*)pEventData->pEventData; + pwdiSetTxPerTrackingRspCb = (WDI_SetTxPerTrackingRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_TX_PER_TRACKING_REQ, + sizeof(halTxPerTrackingReqParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halTxPerTrackingReqParam) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set tx per tracking req %p %p %p", + pEventData, pwdiSetTxPerTrackingReqParams, pwdiSetTxPerTrackingRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halTxPerTrackingReqParam.ucTxPerTrackingEnable = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingEnable; + halTxPerTrackingReqParam.ucTxPerTrackingPeriod = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingPeriod; + halTxPerTrackingReqParam.ucTxPerTrackingRatio = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.ucTxPerTrackingRatio; + halTxPerTrackingReqParam.uTxPerTrackingWatermark = pwdiSetTxPerTrackingReqParams->wdiTxPerTrackingParam.uTxPerTrackingWatermark; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halTxPerTrackingReqParam, + sizeof(halTxPerTrackingReqParam)); + + pWDICtx->wdiReqStatusCB = pwdiSetTxPerTrackingReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetTxPerTrackingReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + pwdiSetTxPerTrackingRspCb, pEventData->pUserData, WDI_SET_TX_PER_TRACKING_RESP); +}/*WDI_ProcessSetTxPerTrackingReq*/ + +/*========================================================================= + Indications +=========================================================================*/ + +/** + @brief Process Suspend Indications function (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostSuspendInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SuspendParamsType *pSuspendIndParams; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalWlanHostSuspendIndParam halWlanSuspendIndparams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in Suspend ind",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pSuspendIndParams = (WDI_SuspendParamsType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_HOST_SUSPEND_IND, + sizeof(halWlanSuspendIndparams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(halWlanSuspendIndparams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Suspend Ind "); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halWlanSuspendIndparams.configuredMcstBcstFilterSetting = + pSuspendIndParams->wdiSuspendParams.ucConfiguredMcstBcstFilterSetting; + + halWlanSuspendIndparams.activeSessionCount = + WDI_GetActiveSessionsCount(pWDICtx, NULL, eWLAN_PAL_TRUE); + + wpalMemoryCopy( pSendBuffer+usDataOffset, &halWlanSuspendIndparams, + sizeof(tHalWlanHostSuspendIndParam)); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pSuspendIndParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pSuspendIndParams->pUserData; + + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return ( wdiStatus != WDI_STATUS_SUCCESS )?wdiStatus:WDI_STATUS_SUCCESS_SYNC; +}/*WDI_ProcessHostSuspendInd*/ + + + +/** + @brief Process Traffic Stats Indications function (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTrafficStatsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_TrafficStatsIndType* pTrafficStatsIndParams; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tStatsClassBIndParams* pStatsClassBIndParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in Traffic Stats ind",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pTrafficStatsIndParams = (WDI_TrafficStatsIndType *)pEventData->pEventData; + + if(pTrafficStatsIndParams->length != sizeof(tStaStatsClassB)*(HAL_NUM_STA)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in Traffic Stats ind",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_TRAFFIC_STATS_IND, + sizeof(tStatsClassBIndParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(tStatsClassBIndParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Traffic Stats Ind "); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pStatsClassBIndParams = (tStatsClassBIndParams*)(pSendBuffer+usDataOffset); + + pStatsClassBIndParams->duration = pTrafficStatsIndParams->duration; + + wpalMemoryCopy(pStatsClassBIndParams->staStatsClassB, + pTrafficStatsIndParams->pTrafficStats, + pTrafficStatsIndParams->length); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pTrafficStatsIndParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pTrafficStatsIndParams->pUserData; + + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return ( wdiStatus != WDI_STATUS_SUCCESS )?wdiStatus:WDI_STATUS_SUCCESS_SYNC; +}/*WDI_ProcessTrafficStatsInd*/ + +#ifdef WLAN_FEATURE_11W +/** + @brief Process Exclude Unencrypted Indications function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExcludeUnencryptInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ExcludeUnencryptIndType* pWDIExcUnencIndParams; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalWlanExcludeUnEncryptedIndParam* pHalExcUnencIndParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in Exclude Unencrypted ind",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pWDIExcUnencIndParams = (WDI_ExcludeUnencryptIndType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_EXCLUDE_UNENCRYPTED_IND, + sizeof(tHalWlanExcludeUnEncryptedIndParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(tHalWlanExcludeUnEncryptedIndParam)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Exclude Unencrypted Ind "); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalExcUnencIndParams = (tHalWlanExcludeUnEncryptedIndParam*)(pSendBuffer+usDataOffset); + + pHalExcUnencIndParams->bDot11ExcludeUnencrypted = pWDIExcUnencIndParams->bExcludeUnencrypt; + + wpalMemoryCopy(pHalExcUnencIndParams->bssId, + pWDIExcUnencIndParams->bssid, WDI_MAC_ADDR_LEN); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pWDIExcUnencIndParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pWDIExcUnencIndParams->pUserData; + + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return ( wdiStatus != WDI_STATUS_SUCCESS )?wdiStatus:WDI_STATUS_SUCCESS_SYNC; +}/*WDI_ProcessExcludeUnencryptInd*/ +#endif + +/** + @brief Process Add Periodic Tx Pattern Indication function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddPeriodicTxPtrnInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddPeriodicTxPtrnParamsType *pAddPeriodicTxPtrnParams; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalAddPeriodicTxPtrn *halAddPeriodicTxPtrn; + wpt_uint8 selfStaIdx = 0; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pEventData) || (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in AddPeriodicTxPtrnInd!", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pAddPeriodicTxPtrnParams = + (WDI_AddPeriodicTxPtrnParamsType *)pEventData->pEventData; + + /*------------------------------------------------------------------------ + Get message buffer + ------------------------------------------------------------------------*/ + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_ADD_PERIODIC_TX_PATTERN_IND, sizeof(tHalAddPeriodicTxPtrn), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(tHalAddPeriodicTxPtrn)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Unable to get send buffer in AddPeriodicTxPtrnInd!", + __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halAddPeriodicTxPtrn = (tHalAddPeriodicTxPtrn *)(pSendBuffer + usDataOffset); + + if (WDI_STATUS_SUCCESS != WDI_STATableFindStaidByAddr(pWDICtx, + pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.macAddr, + &selfStaIdx)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Failed to get selfStaIdx!", __func__); + wpalMemoryFree(pSendBuffer); + + return WDI_STATUS_E_FAILURE; + } + + halAddPeriodicTxPtrn->selfStaIdx = selfStaIdx; + halAddPeriodicTxPtrn->ucPtrnId = + pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPtrnId; + halAddPeriodicTxPtrn->usPtrnSize = + pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPtrnSize; + halAddPeriodicTxPtrn->uPtrnIntervalMs = + pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.usPtrnIntervalMs; + + wpalMemoryCopy(halAddPeriodicTxPtrn->ucPattern, + pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPattern, + pAddPeriodicTxPtrnParams->wdiAddPeriodicTxPtrnParams.ucPtrnSize); + + /*------------------------------------------------------------------------- + Send Indication to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pAddPeriodicTxPtrnParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pAddPeriodicTxPtrnParams->pUserData; + + wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Sent WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND to HAL.", __func__); + + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus : WDI_STATUS_SUCCESS_SYNC; +} /* WDI_ProcessAddPeriodicTxPtrnInd */ + +/** + @brief Process Delete Periodic Tx Pattern Indication function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelPeriodicTxPtrnInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelPeriodicTxPtrnParamsType *pDelPeriodicTxPtrnParams; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalDelPeriodicTxPtrn *halDelPeriodicTxPtrn; + wpt_uint8 selfStaIdx = 0; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pEventData) || (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in DelPeriodicTxPtrnInd!", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pDelPeriodicTxPtrnParams = + (WDI_DelPeriodicTxPtrnParamsType *)pEventData->pEventData; + + /*------------------------------------------------------------------------ + Get message buffer + ------------------------------------------------------------------------*/ + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_DEL_PERIODIC_TX_PATTERN_IND, sizeof(tHalDelPeriodicTxPtrn), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(tHalDelPeriodicTxPtrn)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Unable to get send buffer in DelPeriodicTxPtrnInd!", + __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halDelPeriodicTxPtrn = (tHalDelPeriodicTxPtrn *)(pSendBuffer + usDataOffset); + + if (WDI_STATUS_SUCCESS != WDI_STATableFindStaidByAddr(pWDICtx, + pDelPeriodicTxPtrnParams->wdiDelPeriodicTxPtrnParams.macAddr, + &selfStaIdx)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Failed to get selfStaIdx!", __func__); + wpalMemoryFree(pSendBuffer); + + return WDI_STATUS_E_FAILURE; + } + + halDelPeriodicTxPtrn->selfStaIdx = selfStaIdx; + halDelPeriodicTxPtrn->uPatternIdBitmap = + pDelPeriodicTxPtrnParams->wdiDelPeriodicTxPtrnParams.ucPatternIdBitmap; + + /*------------------------------------------------------------------------- + Send Indication to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pDelPeriodicTxPtrnParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pDelPeriodicTxPtrnParams->pUserData; + + wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Sent WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND to HAL.", __func__); + + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus : WDI_STATUS_SUCCESS_SYNC; +} /* WDI_ProcessDelPeriodicTxPtrnInd */ + +/*========================================================================== + MISC CONTROL PROCESSING REQUEST API +==========================================================================*/ +/** + @brief Process Channel Switch Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SwitchChReqParamsType* pwdiSwitchChParams; + WDI_SwitchChRspCb wdiSwitchChRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSwitchChannelReqMsg halSwitchChannelReq = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSwitchChParams = (WDI_SwitchChReqParamsType*)pEventData->pEventData; + wdiSwitchChRspCb = (WDI_SwitchChRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CH_SWITCH_REQ, + sizeof(halSwitchChannelReq.switchChannelParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSwitchChannelReq.switchChannelParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in channel switch req %p %p %p", + pEventData, pwdiSwitchChParams, wdiSwitchChRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSwitchChannelReq.switchChannelParams.channelNumber = + pwdiSwitchChParams->wdiChInfo.ucChannel; +#ifndef WLAN_FEATURE_VOWIFI + halSwitchChannelReq.switchChannelParams.localPowerConstraint = + pwdiSwitchChParams->wdiChInfo.ucLocalPowerConstraint; +#endif + halSwitchChannelReq.switchChannelParams.secondaryChannelOffset = + pwdiSwitchChParams->wdiChInfo.wdiSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_VOWIFI + halSwitchChannelReq.switchChannelParams.maxTxPower + = pwdiSwitchChParams->wdiChInfo.cMaxTxPower; + wpalMemoryCopy(halSwitchChannelReq.switchChannelParams.selfStaMacAddr, + pwdiSwitchChParams->wdiChInfo.macSelfStaMacAddr, + WDI_MAC_ADDR_LEN); + wpalMemoryCopy(halSwitchChannelReq.switchChannelParams.bssId, + pwdiSwitchChParams->wdiChInfo.macBSSId, + WDI_MAC_ADDR_LEN); +#endif + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSwitchChannelReq.switchChannelParams, + sizeof(halSwitchChannelReq.switchChannelParams)); + + pWDICtx->wdiReqStatusCB = pwdiSwitchChParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSwitchChParams->pUserData; + + /*------------------------------------------------------------------------- + Send Switch Channel Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSwitchChRspCb, pEventData->pUserData, WDI_CH_SWITCH_RESP); +}/*WDI_ProcessChannelSwitchReq*/ + +/** + @brief Process Channel Switch Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessChannelSwitchReq_V1 +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SwitchChReqParamsType_V1* pwdiSwitchChParams; + WDI_SwitchChRspCb_V1 wdiSwitchChRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSwitchChannelReqMsg_V1 halSwitchChannelReq = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSwitchChParams = (WDI_SwitchChReqParamsType_V1*)pEventData->pEventData; + wdiSwitchChRspCb = (WDI_SwitchChRspCb_V1)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_CH_SWITCH_REQ_V1, + sizeof(halSwitchChannelReq.switchChannelParams_V1), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(halSwitchChannelReq.switchChannelParams_V1) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in channel switch req %p %p %p", + pEventData, pwdiSwitchChParams, wdiSwitchChRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSwitchChannelReq.switchChannelParams_V1.channelSwitchSrc = + pwdiSwitchChParams->wdiChInfo.channelSwitchSrc; + + halSwitchChannelReq.switchChannelParams_V1.channelNumber = + pwdiSwitchChParams->wdiChInfo.ucChannel; +#ifndef WLAN_FEATURE_VOWIFI + halSwitchChannelReq.switchChannelParams_V1.localPowerConstraint = + pwdiSwitchChParams->wdiChInfo.ucLocalPowerConstraint; +#endif + halSwitchChannelReq.switchChannelParams_V1.secondaryChannelOffset = + pwdiSwitchChParams->wdiChInfo.wdiSecondaryChannelOffset; + +#ifdef WLAN_FEATURE_VOWIFI + halSwitchChannelReq.switchChannelParams_V1.maxTxPower + = pwdiSwitchChParams->wdiChInfo.cMaxTxPower; + wpalMemoryCopy(halSwitchChannelReq.switchChannelParams_V1.selfStaMacAddr, + pwdiSwitchChParams->wdiChInfo.macSelfStaMacAddr, + WDI_MAC_ADDR_LEN); + wpalMemoryCopy(halSwitchChannelReq.switchChannelParams_V1.bssId, + pwdiSwitchChParams->wdiChInfo.macBSSId, + WDI_MAC_ADDR_LEN); +#endif + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSwitchChannelReq.switchChannelParams_V1, + sizeof(halSwitchChannelReq.switchChannelParams_V1)); + + pWDICtx->wdiReqStatusCB = pwdiSwitchChParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSwitchChParams->pUserData; + + /*------------------------------------------------------------------------- + Send Switch Channel Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSwitchChRspCb, pEventData->pUserData, + WDI_CH_SWITCH_RESP_V1); +}/*WDI_ProcessChannelSwitchReq_V1*/ + +/** + @brief Process Config STA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigStaReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ConfigSTAReqParamsType* pwdiConfigSTAParams; + WDI_ConfigSTARspCb wdiConfigSTARspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + tConfigStaReqMsg halConfigStaReqMsg; + wpt_uint16 uMsgSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(&halConfigStaReqMsg, sizeof(tConfigStaReqMsg)); + pwdiConfigSTAParams = (WDI_ConfigSTAReqParamsType*)pEventData->pEventData; + wdiConfigSTARspCb = (WDI_ConfigSTARspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiConfigSTAParams->wdiReqInfo.macBSSID, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiConfigSTAParams->wdiReqInfo.macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiConfigSTAParams->wdiReqInfo.macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + /* Allocation of StaReqMsg Memory Based on Firmware Capabilities */ +#ifdef WLAN_FEATURE_11AC + if (WDI_getFwWlanFeatCaps(DOT11AC)) + uMsgSize = sizeof(halConfigStaReqMsg.uStaParams.configStaParams_V1); // Version-1 For 11AC + else +#endif + uMsgSize = sizeof(halConfigStaReqMsg.uStaParams.configStaParams); // Version-0 Default + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIG_STA_REQ, + uMsgSize, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + uMsgSize ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in config sta req %p %p %p", + pEventData, pwdiConfigSTAParams, wdiConfigSTARspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*Copy the station context*/ + WDI_CopyWDIStaCtxToHALStaCtx( &halConfigStaReqMsg.uStaParams.configStaParams, + &pwdiConfigSTAParams->wdiReqInfo); + + if(pwdiConfigSTAParams->wdiReqInfo.wdiSTAType == WDI_STA_ENTRY_SELF) + { + /* Need to fill in the self STA Index */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDICtx, + pwdiConfigSTAParams->wdiReqInfo.macSTA, + (wpt_uint8*)&halConfigStaReqMsg.uStaParams.configStaParams.staIdx )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + MAC_ADDRESS_STR + ": This station does not exist in the WDI Station Table", + MAC_ADDR_ARRAY(pwdiConfigSTAParams->wdiReqInfo.macSTA)); + wpalMutexRelease(&pWDICtx->wptMutex); + wpalMemoryFree(pSendBuffer); + return WDI_STATUS_E_FAILURE; + } + } + else + { + /* Need to fill in the STA Index to invalid, since at this point we have not + yet received it from HAL */ + halConfigStaReqMsg.uStaParams.configStaParams.staIdx = pwdiConfigSTAParams->wdiReqInfo.staIdx; + } + + /* Need to fill in the BSS index */ + halConfigStaReqMsg.uStaParams.configStaParams.bssIdx = pBSSSes->ucBSSIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halConfigStaReqMsg.uStaParams, + uMsgSize); + + pWDICtx->wdiReqStatusCB = pwdiConfigSTAParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiConfigSTAParams->pUserData; + + wpalMemoryCopy( &pWDICtx->wdiCachedConfigStaReq, + pwdiConfigSTAParams, + sizeof(pWDICtx->wdiCachedConfigStaReq)); + + /*------------------------------------------------------------------------- + Send Config STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiConfigSTARspCb, pEventData->pUserData, WDI_CONFIG_STA_RESP); +}/*WDI_ProcessConfigStaReq*/ + + +/** + @brief Process Set Link State Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetLinkStateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetLinkReqParamsType* pwdiSetLinkParams; + WDI_SetLinkStateRspCb wdiSetLinkRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + tLinkStateParams halLinkStateReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetLinkParams = (WDI_SetLinkReqParamsType*)pEventData->pEventData; + wdiSetLinkRspCb = (WDI_SetLinkStateRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiSetLinkParams->wdiLinkInfo.macBSSID, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Set link request received outside association session. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiSetLinkParams->wdiLinkInfo.macBSSID)); + } + else + { + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiSetLinkParams->wdiLinkInfo.macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + } + /* If the link is set to enter IDLE - the Session allocated for this BSS + will be deleted on the Set Link State response coming from HAL + - cache the request for response processing */ + wpalMemoryCopy(&pWDICtx->wdiCacheSetLinkStReq, pwdiSetLinkParams, + sizeof(pWDICtx->wdiCacheSetLinkStReq)); + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_LINK_ST_REQ, + sizeof(halLinkStateReqMsg), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halLinkStateReqMsg) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiSetLinkParams, wdiSetLinkRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(halLinkStateReqMsg.bssid, + pwdiSetLinkParams->wdiLinkInfo.macBSSID, WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(halLinkStateReqMsg.selfMacAddr, + pwdiSetLinkParams->wdiLinkInfo.macSelfStaMacAddr, WDI_MAC_ADDR_LEN); + + halLinkStateReqMsg.state = + WDI_2_HAL_LINK_STATE(pwdiSetLinkParams->wdiLinkInfo.wdiLinkState); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halLinkStateReqMsg, + sizeof(halLinkStateReqMsg)); + + pWDICtx->wdiReqStatusCB = pwdiSetLinkParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetLinkParams->pUserData; + + /*------------------------------------------------------------------------- + Send Set Link State Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetLinkRspCb, pEventData->pUserData, WDI_SET_LINK_ST_RESP); +}/*WDI_ProcessSetLinkStateReq*/ + + +/** + @brief Process Get Stats Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetStatsReqParamsType* pwdiGetStatsParams; + WDI_GetStatsRspCb wdiGetStatsRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_macAddr macBSSID; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + tHalStatsReqMsg halStatsReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiGetStatsParams = (WDI_GetStatsReqParamsType*)pEventData->pEventData; + wdiGetStatsRspCb = (WDI_GetStatsRspCb)pEventData->pCBfnc; + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiGetStatsParams->wdiGetStatsParamsInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiGetStatsParams->wdiGetStatsParamsInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GET_STATS_REQ, + sizeof(halStatsReqMsg.statsReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halStatsReqMsg.statsReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiGetStatsParams, wdiGetStatsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halStatsReqMsg.statsReqParams.staId = + pwdiGetStatsParams->wdiGetStatsParamsInfo.ucSTAIdx; + halStatsReqMsg.statsReqParams.statsMask = + pwdiGetStatsParams->wdiGetStatsParamsInfo.uStatsMask; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halStatsReqMsg.statsReqParams, + sizeof(halStatsReqMsg.statsReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiGetStatsParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiGetStatsParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiGetStatsRspCb, pEventData->pUserData, WDI_GET_STATS_RESP); +}/*WDI_ProcessGetStatsReq*/ + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief Process Get Roam Rssi Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetRoamRssiReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetRoamRssiReqParamsType* pwdiGetRoamRssiParams; + WDI_GetStatsRspCb wdiGetStatsRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_macAddr macBSSID; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + tHalGetRoamRssiReqMsg halRssiRoamReqMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiGetRoamRssiParams = (WDI_GetRoamRssiReqParamsType*)pEventData->pEventData; + wdiGetStatsRspCb = (WDI_GetStatsRspCb)pEventData->pCBfnc; + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiGetRoamRssiParams->wdiGetRoamRssiParamsInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiGetRoamRssiParams->wdiGetRoamRssiParamsInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GET_ROAM_RSSI_REQ, + sizeof(halRssiRoamReqMsg.roamRssiReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halRssiRoamReqMsg.roamRssiReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiGetRoamRssiParams, wdiGetStatsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halRssiRoamReqMsg.roamRssiReqParams.staId = + pwdiGetRoamRssiParams->wdiGetRoamRssiParamsInfo.ucSTAIdx; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halRssiRoamReqMsg.roamRssiReqParams, + sizeof(halRssiRoamReqMsg.roamRssiReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiGetRoamRssiParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiGetRoamRssiParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiGetStatsRspCb, pEventData->pUserData, WDI_GET_ROAM_RSSI_RESP); +}/*WDI_ProcessGetRoamRssiReq*/ +#endif + +/** + @brief Process Update Cfg Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateCfgReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateCfgReqParamsType* pwdiUpdateCfgParams = NULL; + WDI_UpdateCfgRspCb wdiUpdateCfgRspCb = NULL; + + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiUpdateCfgParams = (WDI_UpdateCfgReqParamsType*)pEventData->pEventData; + wdiUpdateCfgRspCb = (WDI_UpdateCfgRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_CFG_REQ, + pwdiUpdateCfgParams->uConfigBufferLen + sizeof(wpt_uint32), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + pwdiUpdateCfgParams->uConfigBufferLen))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiUpdateCfgParams, wdiUpdateCfgRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiUpdateCfgParams->uConfigBufferLen, + sizeof(wpt_uint32)); + wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(wpt_uint32), + pwdiUpdateCfgParams->pConfigBuffer, + pwdiUpdateCfgParams->uConfigBufferLen); + + pWDICtx->wdiReqStatusCB = pwdiUpdateCfgParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateCfgParams->pUserData; + + /*------------------------------------------------------------------------- + Send Update Cfg Request to HAL + -------------------------------------------------------------------------*/ + + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiUpdateCfgRspCb, pEventData->pUserData, WDI_UPDATE_CFG_RESP); + +}/*WDI_ProcessUpdateCfgReq*/ + + +/** + @brief Process Add BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddBAReqParamsType* pwdiAddBAParams; + WDI_AddBARspCb wdiAddBARspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + + tAddBAReqMsg halAddBAReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiAddBAParams = (WDI_AddBAReqParamsType*)pEventData->pEventData; + wdiAddBARspCb = (WDI_AddBARspCb)pEventData->pCBfnc; + + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiAddBAParams->wdiBAInfoType.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiAddBAParams->wdiBAInfoType.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ADD_BA_REQ, + sizeof(halAddBAReq.addBAParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < + (usDataOffset + sizeof(halAddBAReq.addBAParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Add BA req %p %p %p", + pEventData, pwdiAddBAParams, wdiAddBARspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halAddBAReq.addBAParams.baSessionID = + pwdiAddBAParams->wdiBAInfoType.ucBaSessionID; + halAddBAReq.addBAParams.winSize = pwdiAddBAParams->wdiBAInfoType.ucWinSize; +#ifdef FEATURE_ON_CHIP_REORDERING + halAddBAReq.addBAParams.isReorderingDoneOnChip = + pwdiAddBAParams->wdiBAInfoType.bIsReorderingDoneOnChip; +#endif + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halAddBAReq.addBAParams, + sizeof(halAddBAReq.addBAParams)); + + pWDICtx->wdiReqStatusCB = pwdiAddBAParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiAddBAParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiAddBARspCb, pEventData->pUserData, + WDI_ADD_BA_RESP); +}/*WDI_ProcessAddBAReq*/ + + + +/** + @brief Process Trigger BA Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_TriggerBAReqParamsType* pwdiTriggerBAParams; + WDI_TriggerBARspCb wdiTriggerBARspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_uint16 index; + wpt_macAddr macBSSID; + + tTriggerBAReqMsg halTriggerBAReq; + tTriggerBaReqCandidate* halTriggerBACandidate; + WDI_TriggerBAReqCandidateType* wdiTriggerBACandidate; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiTriggerBAParams = (WDI_TriggerBAReqParamsType*)pEventData->pEventData; + wdiTriggerBARspCb = (WDI_TriggerBARspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiTriggerBAParams->wdiTriggerBAInfoType.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiTriggerBAParams->wdiTriggerBAInfoType.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_TRIGGER_BA_REQ, + sizeof(halTriggerBAReq.triggerBAParams) + + (sizeof(tTriggerBaReqCandidate) * + pwdiTriggerBAParams->wdiTriggerBAInfoType.usBACandidateCnt), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < + (usDataOffset + sizeof(halTriggerBAReq.triggerBAParams)+ + (sizeof(tTriggerBaReqCandidate) * + pwdiTriggerBAParams->wdiTriggerBAInfoType.usBACandidateCnt) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Trigger BA req %p %p %p", + pEventData, pwdiTriggerBAParams, wdiTriggerBARspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halTriggerBAReq.triggerBAParams.baSessionID = + pwdiTriggerBAParams->wdiTriggerBAInfoType.ucBASessionID; + halTriggerBAReq.triggerBAParams.baCandidateCnt = + pwdiTriggerBAParams->wdiTriggerBAInfoType.usBACandidateCnt; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halTriggerBAReq.triggerBAParams, + sizeof(halTriggerBAReq.triggerBAParams)); + + wdiTriggerBACandidate = + (WDI_TriggerBAReqCandidateType*)(pwdiTriggerBAParams + 1); + halTriggerBACandidate = (tTriggerBaReqCandidate*)(pSendBuffer+usDataOffset+ + sizeof(halTriggerBAReq.triggerBAParams)); + + for(index = 0 ; index < halTriggerBAReq.triggerBAParams.baCandidateCnt ; + index++) + { + halTriggerBACandidate->staIdx = wdiTriggerBACandidate->ucSTAIdx; + halTriggerBACandidate->tidBitmap = wdiTriggerBACandidate->ucTidBitmap; + halTriggerBACandidate++; + wdiTriggerBACandidate++; + } + + pWDICtx->wdiReqStatusCB = pwdiTriggerBAParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiTriggerBAParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiTriggerBARspCb, pEventData->pUserData, + WDI_TRIGGER_BA_RESP); +}/*WDI_ProcessTriggerBAReq*/ + + + +/** + @brief Process Update Beacon Params Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateBeaconParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateBeaconParamsType* pwdiUpdateBeaconParams; + WDI_UpdateBeaconParamsRspCb wdiUpdateBeaconParamsRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tUpdateBeaconParams halUpdateBeaconParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiUpdateBeaconParams = (WDI_UpdateBeaconParamsType*)pEventData->pEventData; + wdiUpdateBeaconParamsRspCb = (WDI_UpdateBeaconParamsRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_BCON_PRMS_REQ, + sizeof(halUpdateBeaconParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halUpdateBeaconParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiUpdateBeaconParams, wdiUpdateBeaconParamsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*BSS Index of the BSS*/ + halUpdateBeaconParams.bssIdx = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucBssIdx; + /*shortPreamble mode. HAL should update all the STA rates when it + receives this message*/ + halUpdateBeaconParams.fShortPreamble = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfShortPreamble; + /* short Slot time.*/ + halUpdateBeaconParams.fShortSlotTime = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfShortSlotTime; + /* Beacon Interval */ + halUpdateBeaconParams.beaconInterval = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.usBeaconInterval; + + /*Protection related */ + halUpdateBeaconParams.llaCoexist = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllaCoexist; + halUpdateBeaconParams.llbCoexist = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllbCoexist; + halUpdateBeaconParams.llgCoexist = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllgCoexist; + halUpdateBeaconParams.ht20MhzCoexist = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucHt20MhzCoexist; + halUpdateBeaconParams.llnNonGFCoexist = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucllnNonGFCoexist; + halUpdateBeaconParams.fLsigTXOPProtectionFullSupport = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfLsigTXOPProtectionFullSupport; + halUpdateBeaconParams.fRIFSMode = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.ucfRIFSMode; + halUpdateBeaconParams.paramChangeBitmap = + pwdiUpdateBeaconParams->wdiUpdateBeaconParamsInfo.usChangeBitmap; + + wpalMemoryCopy( pSendBuffer+usDataOffset, &halUpdateBeaconParams, + sizeof(halUpdateBeaconParams)); + + pWDICtx->wdiReqStatusCB = pwdiUpdateBeaconParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateBeaconParams->pUserData; + + /*------------------------------------------------------------------------- + Send Del TS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiUpdateBeaconParamsRspCb, pEventData->pUserData, WDI_UPD_BCON_PRMS_RESP); +}/*WDI_ProcessUpdateBeaconParamsReq*/ + + + +/** + @brief Process Send Beacon template Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSendBeaconParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SendBeaconParamsType* pwdiSendBeaconParams; + WDI_SendBeaconParamsRspCb wdiSendBeaconParamsRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + tSendBeaconReqMsg halSendBeaconReq; + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSendBeaconParams = (WDI_SendBeaconParamsType*)pEventData->pEventData; + wdiSendBeaconParamsRspCb = (WDI_SendBeaconParamsRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SND_BCON_REQ, + sizeof(halSendBeaconReq.sendBeaconParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSendBeaconReq.sendBeaconParam) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in send beacon req %p %p %p", + pEventData, pwdiSendBeaconParams, wdiSendBeaconParamsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(halSendBeaconReq.sendBeaconParam.bssId, + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.macBSSID, + WDI_MAC_ADDR_LEN); + halSendBeaconReq.sendBeaconParam.beaconLength = + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.beaconLength; + wpalMemoryCopy(halSendBeaconReq.sendBeaconParam.beacon, + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.beacon, + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.beaconLength); + halSendBeaconReq.sendBeaconParam.timIeOffset = + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.timIeOffset; + /* usP2PIeOffset should be atleast greater than timIeOffset */ + if ((pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset != 0 ) && + (pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset < + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.timIeOffset)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid usP2PIeOffset %hu", + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSendBeaconReq.sendBeaconParam.p2pIeOffset = + pwdiSendBeaconParams->wdiSendBeaconParamsInfo.usP2PIeOffset; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSendBeaconReq.sendBeaconParam, + sizeof(halSendBeaconReq.sendBeaconParam)); + + pWDICtx->wdiReqStatusCB = pwdiSendBeaconParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSendBeaconParams->pUserData; + + /*------------------------------------------------------------------------- + Send Del TS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSendBeaconParamsRspCb, pEventData->pUserData, WDI_SND_BCON_RESP); +}/*WDI_ProcessSendBeaconParamsReq*/ + +/** + @brief Process Update Beacon Params Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateProbeRspTemplateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateProbeRspTemplateParamsType* pwdiUpdateProbeRespTmplParams; + WDI_UpdateProbeRspTemplateRspCb wdiUpdateProbeRespTmplRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 uMsgSize = 0; + tSendProbeRespReqParams *halProbeRespTmplParams = NULL; + tSendProbeRespReqParams_V1 *halProbeRespTmplParams_V1 = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiUpdateProbeRespTmplParams = + (WDI_UpdateProbeRspTemplateParamsType*)pEventData->pEventData; + wdiUpdateProbeRespTmplRspCb = + (WDI_UpdateProbeRspTemplateRspCb)pEventData->pCBfnc; + + if (WDI_getFwWlanFeatCaps(PROBE_RSP_TEMPLATE_VER1)) + uMsgSize = sizeof(tSendProbeRespReqParams_V1) + + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + uProbeRespTemplateLen - + sizeof(halProbeRespTmplParams_V1->pProbeRespTemplate); + else + uMsgSize = sizeof(tSendProbeRespReqParams); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPD_PROBE_RSP_TEMPLATE_REQ, + uMsgSize, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + uMsgSize))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiUpdateProbeRespTmplParams, wdiUpdateProbeRespTmplRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + if (WDI_getFwWlanFeatCaps(PROBE_RSP_TEMPLATE_VER1)) + { + halProbeRespTmplParams_V1 = + (tSendProbeRespReqParams_V1 *)(pSendBuffer + usDataOffset); + + wpalMemoryCopy(halProbeRespTmplParams_V1->bssId, + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + halProbeRespTmplParams_V1->probeRespTemplateLen = + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + uProbeRespTemplateLen; + + wpalMemoryCopy(halProbeRespTmplParams_V1->ucProxyProbeReqValidIEBmap, + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + uaProxyProbeReqValidIEBmap, + WDI_PROBE_REQ_BITMAP_IE_LEN); + + wpalMemoryCopy(halProbeRespTmplParams_V1->pProbeRespTemplate, + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + pProbeRespTemplate, + halProbeRespTmplParams_V1->probeRespTemplateLen); + } + else + { + halProbeRespTmplParams = + (tSendProbeRespReqParams *)(pSendBuffer + usDataOffset); + + wpalMemoryCopy(halProbeRespTmplParams->bssId, + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + if (BEACON_TEMPLATE_SIZE < + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + uProbeRespTemplateLen) + halProbeRespTmplParams->probeRespTemplateLen = BEACON_TEMPLATE_SIZE; + else + halProbeRespTmplParams->probeRespTemplateLen = + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + uProbeRespTemplateLen; + + wpalMemoryCopy(halProbeRespTmplParams->ucProxyProbeReqValidIEBmap, + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + uaProxyProbeReqValidIEBmap, + WDI_PROBE_REQ_BITMAP_IE_LEN); + wpalMemoryCopy(halProbeRespTmplParams->pProbeRespTemplate, + pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + pProbeRespTemplate, + BEACON_TEMPLATE_SIZE); + } + + pWDICtx->wdiReqStatusCB = pwdiUpdateProbeRespTmplParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateProbeRespTmplParams->pUserData; + + vos_mem_free(pwdiUpdateProbeRespTmplParams->wdiProbeRspTemplateInfo. + pProbeRespTemplate); + /*------------------------------------------------------------------------- + Send Update Probe Resp Template Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiUpdateProbeRespTmplRspCb, pEventData->pUserData, + WDI_UPD_PROBE_RSP_TEMPLATE_RESP); +}/*WDI_ProcessUpdateProbeRspTemplateReq*/ + +/** + @brief Process NV blob download function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNvDownloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + + WDI_NvDownloadReqParamsType* pwdiNvDownloadReqParams = NULL; + WDI_NvDownloadRspCb wdiNvDownloadRspCb = NULL; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiNvDownloadReqParams = + (WDI_NvDownloadReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiNvDownloadRspCb = + (WDI_NvDownloadRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*Intialize the Nv Blob Info */ + pWDICtx->wdiNvBlobInfo.usTotalFragment = + TOTALFRAGMENTS(pwdiNvDownloadReqParams->wdiBlobInfo.uBlobSize); + + /*cache the wdi nv request message here if the the first fragment + * To issue the request to HAL for the next fragment */ + if( 0 == pWDICtx->wdiNvBlobInfo.usCurrentFragment) + { + wpalMemoryCopy(&pWDICtx->wdiCachedNvDownloadReq, + pwdiNvDownloadReqParams, + sizeof(pWDICtx->wdiCachedNvDownloadReq)); + + pWDICtx->pfncRspCB = pEventData->pCBfnc; + pWDICtx->pRspCBUserData = pEventData->pUserData; + } + + return WDI_SendNvBlobReq(pWDICtx,pEventData); +} + +/** + @brief Process Set Max Tx Power Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetMaxTxPowerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetMaxTxPowerParamsType* pwdiSetMaxTxPowerParams = NULL; + WDA_SetMaxTxPowerRspCb wdiSetMaxTxPowerRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSetMaxTxPwrReq halSetMaxTxPower; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiSetMaxTxPowerParams = + (WDI_SetMaxTxPowerParamsType*)pEventData->pEventData; + wdiSetMaxTxPowerRspCb = + (WDA_SetMaxTxPowerRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ +if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_MAX_TX_POWER_REQ, + sizeof(halSetMaxTxPower.setMaxTxPwrParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetMaxTxPower.setMaxTxPwrParams) +))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to get Set Max Tx Power req %p %p %p", + pEventData, pwdiSetMaxTxPowerParams, wdiSetMaxTxPowerRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(halSetMaxTxPower.setMaxTxPwrParams.bssId, + pwdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.macBSSId, + WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(halSetMaxTxPower.setMaxTxPwrParams.selfStaMacAddr, + pwdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.macSelfStaMacAddr, + WDI_MAC_ADDR_LEN); + halSetMaxTxPower.setMaxTxPwrParams.power = + pwdiSetMaxTxPowerParams->wdiMaxTxPowerInfo.ucPower; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetMaxTxPower.setMaxTxPwrParams, + sizeof(halSetMaxTxPower.setMaxTxPwrParams)); + + pWDICtx->wdiReqStatusCB = pwdiSetMaxTxPowerParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetMaxTxPowerParams->pUserData; + + /*------------------------------------------------------------------------- + Send Del TS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetMaxTxPowerRspCb, pEventData->pUserData, + WDI_SET_MAX_TX_POWER_RESP); + +} + +/* + @brief Process Set Max Tx Power Per Band Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetMaxTxPowerPerBandReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetMaxTxPowerPerBandParamsType* pwdiSetMaxTxPowerPerBandParams = NULL; + WDA_SetMaxTxPowerPerBandRspCb wdiSetMaxTxPowerPerBandRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tpSetMaxTxPwrPerBandParams phalSetMxTxPwrPerBand = NULL; + WDI_Status rValue = WDI_STATUS_SUCCESS; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiSetMaxTxPowerPerBandParams = \ + (WDI_SetMaxTxPowerPerBandParamsType*)pEventData->pEventData; + + wdiSetMaxTxPowerPerBandRspCb = \ + (WDA_SetMaxTxPowerPerBandRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + rValue = WDI_GetMessageBuffer(pWDICtx, + WDI_SET_MAX_TX_POWER_PER_BAND_REQ, + sizeof(tSetMaxTxPwrPerBandParams), + &pSendBuffer, &usDataOffset, &usSendSize); + + if ((WDI_STATUS_SUCCESS != rValue)|| (usSendSize < + (usDataOffset + sizeof(tSetMaxTxPwrPerBandParams)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to get Set Max Tx Power Per Band req %p %p %p", + pEventData, pwdiSetMaxTxPowerPerBandParams, + wdiSetMaxTxPowerPerBandRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + phalSetMxTxPwrPerBand = (tpSetMaxTxPwrPerBandParams)(pSendBuffer + usDataOffset); + phalSetMxTxPwrPerBand->bandInfo = \ + pwdiSetMaxTxPowerPerBandParams->wdiMaxTxPowerPerBandInfo.bandInfo; + + phalSetMxTxPwrPerBand->power = \ + pwdiSetMaxTxPowerPerBandParams->wdiMaxTxPowerPerBandInfo.ucPower; + + pWDICtx->wdiReqStatusCB = pwdiSetMaxTxPowerPerBandParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetMaxTxPowerPerBandParams->pUserData; + + /*------------------------------------------------------------------------- + Send Set Max Tx Power Per Band Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize, + wdiSetMaxTxPowerPerBandRspCb, pEventData->pUserData, + WDI_SET_MAX_TX_POWER_PER_BAND_RSP); +} + +/** + @brief Process Set Tx Power Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessSetTxPowerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetTxPowerParamsType* pwdiSetTxPowerParams = NULL; + WDA_SetTxPowerRspCb wdiSetTxPowerRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSetTxPwrReqParams *halSetTxPower = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetTxPowerParams = + (WDI_SetTxPowerParamsType*)pEventData->pEventData; + wdiSetTxPowerRspCb = + (WDA_SetTxPowerRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_TX_POWER_REQ, + sizeof(tSetTxPwrReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tSetTxPwrReqParams) + ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to get Set Max Tx Power req %p %p %p", + pEventData, pwdiSetTxPowerParams, wdiSetTxPowerRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSetTxPower = (tSetTxPwrReqParams *)(pSendBuffer + usDataOffset); + halSetTxPower->txPower = pwdiSetTxPowerParams->wdiTxPowerInfo.ucPower; + halSetTxPower->bssIdx = pwdiSetTxPowerParams->wdiTxPowerInfo.bssIdx; + + pWDICtx->wdiReqStatusCB = pwdiSetTxPowerParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetTxPowerParams->pUserData; + + /*------------------------------------------------------------------------- + Send Set Tx Power Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetTxPowerRspCb, pEventData->pUserData, + WDI_SET_TX_POWER_RESP); +} + +/** + @brief Process P2P Notice Of Absence Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2PGONOAReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetP2PGONOAReqParamsType* pwdiP2PGONOAReqParams; + WDI_SetP2PGONOAReqParamsRspCb wdiP2PGONOAReqRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSetP2PGONOAParams halSetP2PGONOAParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiP2PGONOAReqParams = + (WDI_SetP2PGONOAReqParamsType*)pEventData->pEventData; + wdiP2PGONOAReqRspCb = + (WDI_SetP2PGONOAReqParamsRspCb)pEventData->pCBfnc; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ, + sizeof(halSetP2PGONOAParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetP2PGONOAParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set P2P GO NOA REQ %p %p %p", + pEventData, pwdiP2PGONOAReqParams, wdiP2PGONOAReqRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSetP2PGONOAParams.opp_ps = + pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.ucOpp_ps; + halSetP2PGONOAParams.ctWindow = + pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uCtWindow; + halSetP2PGONOAParams.count = pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.ucCount; + halSetP2PGONOAParams.duration = + pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uDuration; + halSetP2PGONOAParams.interval = + pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uInterval; + halSetP2PGONOAParams.single_noa_duration = + pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.uSingle_noa_duration; + halSetP2PGONOAParams.psSelection = + pwdiP2PGONOAReqParams->wdiP2PGONOAInfo.ucPsSelection; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetP2PGONOAParams, + sizeof(halSetP2PGONOAParams)); + + pWDICtx->wdiReqStatusCB = pwdiP2PGONOAReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiP2PGONOAReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Update Probe Resp Template Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiP2PGONOAReqRspCb, pEventData->pUserData, + WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP); +}/*WDI_ProcessP2PGONOAReq*/ + +#ifdef FEATURE_WLAN_TDLS + +/** + @brief Process P2P Notice Of Absence Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsLinkEstablishReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetTDLSLinkEstablishReqParamsType* pwdiTDLSLinkEstablishReqParams; + WDI_SetTDLSLinkEstablishReqParamsRspCb wdiTDLSLinkEstablishReqRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + tTDLSLinkEstablishedType halSetTDLSLinkEstablishParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiTDLSLinkEstablishReqParams = + (WDI_SetTDLSLinkEstablishReqParamsType*)pEventData->pEventData; + wdiTDLSLinkEstablishReqRspCb = + (WDI_SetTDLSLinkEstablishReqParamsRspCb)pEventData->pCBfnc; + + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_TDLS_LINK_ESTABLISH_REQ, + sizeof(halSetTDLSLinkEstablishParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetTDLSLinkEstablishParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set P2P GO NOA REQ %p %p %p", + pEventData, pwdiTDLSLinkEstablishReqParams, wdiTDLSLinkEstablishReqRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSetTDLSLinkEstablishParams.staIdx = + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uStaIdx; + halSetTDLSLinkEstablishParams.bIsResponder = + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uIsResponder; + halSetTDLSLinkEstablishParams.acVOUAPSDFlag = + (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x08) >> 3; + halSetTDLSLinkEstablishParams.acVIUAPSDFlag = + (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x04) >> 2; + halSetTDLSLinkEstablishParams.acBKUAPSDFlag = + (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x02) >> 1; + halSetTDLSLinkEstablishParams.acBEUAPSDFlag = + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uUapsdQueues & 0x01; + halSetTDLSLinkEstablishParams.aAck = 0; + halSetTDLSLinkEstablishParams.maxServicePeriodLength = (pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uMaxSp & 0x03); + halSetTDLSLinkEstablishParams.moreDataAck = 0; + halSetTDLSLinkEstablishParams.TPUBufferStaSupport = pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uIsBufSta; + halSetTDLSLinkEstablishParams.tdlsOffChannelSupport = + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.uIsOffChannelSupported; + + wpalMemoryCopy( halSetTDLSLinkEstablishParams.validChannels, + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validChannels, + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validChannelsLen); + halSetTDLSLinkEstablishParams.validChannelsLen = + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validChannelsLen; + + wpalMemoryCopy( halSetTDLSLinkEstablishParams.validOperClasses, + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validOperClasses, + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validOperClassesLen); + halSetTDLSLinkEstablishParams.validOperClassesLen = + pwdiTDLSLinkEstablishReqParams->wdiTDLSLinkEstablishInfo.validOperClassesLen; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetTDLSLinkEstablishParams, + sizeof(halSetTDLSLinkEstablishParams)); + + pWDICtx->wdiReqStatusCB = pwdiTDLSLinkEstablishReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiTDLSLinkEstablishReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Update Probe Resp Template Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiTDLSLinkEstablishReqRspCb, pEventData->pUserData, + WDI_TDLS_LINK_ESTABLISH_REQ_RESP); + return 0; +}/*WDI_ProcessTdlsLinkEstablishReq*/ + + +/** + @brief sends the channel switch command to f/w (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsChanSwitchReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams; + WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchReqRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + //WDI_Status wdiStatus; + tTDLSChanSwitchReqType halSetTDLSChanSwitchParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiTDLSChanSwitchReqParams = + (WDI_SetTDLSChanSwitchReqParamsType*)pEventData->pEventData; + wdiTDLSChanSwitchReqRspCb = + (WDI_SetTDLSChanSwitchReqParamsRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_TDLS_CHAN_SWITCH_REQ, + sizeof(halSetTDLSChanSwitchParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halSetTDLSChanSwitchParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Channel Switch REQ %p %p %p", + pEventData, pwdiTDLSChanSwitchReqParams, wdiTDLSChanSwitchReqRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halSetTDLSChanSwitchParams.staIdx = + pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.staIdx; + halSetTDLSChanSwitchParams.isOffchannelInitiator = + pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.isOffchannelInitiator; + halSetTDLSChanSwitchParams.targetOperClass = + pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.targetOperClass; + halSetTDLSChanSwitchParams.targetChannel = + pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.targetChannel; + halSetTDLSChanSwitchParams.secondaryChannelOffset = + pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.secondaryChannelOffset; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halSetTDLSChanSwitchParams, + sizeof(halSetTDLSChanSwitchParams)); + + pWDICtx->wdiReqStatusCB = NULL; + pWDICtx->pReqStatusUserData = NULL; + + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiTDLSChanSwitchReqRspCb, pEventData->pUserData, + WDI_TDLS_CHAN_SWITCH_REQ_RESP); +}/*WDI_ProcessTdlsChanSwitchReq*/ + +#endif /*FEATURE_WLAN_TDLS*/ + + + +/** + @brief Function to handle the ack from DXE once the power + state is set. + @param None + + @see + @return void +*/ +void +WDI_SetPowerStateCb +( + wpt_status status, + unsigned int dxePhyAddr, + void *pContext +) +{ + wpt_status wptStatus; + WDI_ControlBlockType *pCB = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /* + * Trigger the event to bring the Enter BMPS req function to come + * out of wait +*/ + if( NULL != pContext ) + { + pCB = (WDI_ControlBlockType *)pContext; + } + else + { + //put an error msg + pCB = &gWDICb; + } + + if(eWLAN_PAL_STATUS_SUCCESS == status ) + { + pCB->dxeRingsEmpty = eWLAN_PAL_TRUE; + } + else + { + pCB->dxeRingsEmpty = eWLAN_PAL_FALSE; + } + pCB->dxePhyAddr = dxePhyAddr; + wptStatus = wpalEventSet(&pCB->setPowerStateEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Failed to set an event"); + + WDI_ASSERT(0); + } + return; +} + + +/** + @brief Process Enter IMPS Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterImpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_status wptStatus; + WDI_EnterImpsRspCb wdiEnterImpsRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_EnterImpsReqParamsType* pwdiEnterImpsReqParams = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pEventData ) || + (NULL == (wdiEnterImpsRspCb = (WDI_EnterImpsRspCb)pEventData->pCBfnc)) || + (NULL == (pwdiEnterImpsReqParams = + (WDI_EnterImpsReqParamsType*)pEventData->pEventData))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ENTER_IMPS_REQ, + 0, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Enter IMPS req %p %p", + pEventData, wdiEnterImpsRspCb); + WDI_ASSERT(0); + goto failRequest; + } + + /* Reset the event to be not signalled */ + wptStatus = wpalEventReset(&pWDICtx->setPowerStateEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to reset an event"); + + WDI_ASSERT(0); + goto fail; + } + + // notify DTS that we are entering IMPS + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_IMPS, WDI_SetPowerStateCb); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering IMPS", wptStatus); + WDI_ASSERT(0); + goto fail; + } + + /* + * Wait for the event to be set once the ACK comes back from DXE + */ + wptStatus = wpalEventWait(&pWDICtx->setPowerStateEvent, + WDI_SET_POWER_STATE_TIMEOUT); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to wait on an event"); + + WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + WDI_ASSERT(0); + goto fail; + } + + if (pWDICtx->dxeRingsEmpty == eWLAN_PAL_FALSE) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: DXE Rings not empty, cannot enter IMPS",__func__); + + goto fail; + } + + pWDICtx->wdiReqStatusCB = pwdiEnterImpsReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiEnterImpsReqParams->pUserData; + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEnterImpsRspCb, pEventData->pUserData, WDI_ENTER_IMPS_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +}/*WDI_ProcessEnterImpsReq*/ + +/** + @brief Process Exit IMPS Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitImpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ExitImpsRspCb wdiExitImpsRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_ExitImpsReqParamsType *pwdiExitImpsReqParams = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (wdiExitImpsRspCb = (WDI_ExitImpsRspCb)pEventData->pCBfnc)) || + (NULL == (pwdiExitImpsReqParams = + (WDI_ExitImpsReqParamsType*)pEventData->pEventData))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_EXIT_IMPS_REQ, + 0, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Exit IMPS req %p %p", + pEventData, wdiExitImpsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pWDICtx->wdiReqStatusCB = pwdiExitImpsReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiExitImpsReqParams->pUserData; + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiExitImpsRspCb, pEventData->pUserData, WDI_EXIT_IMPS_RESP); +}/*WDI_ProcessExitImpsReq*/ + +/** + @brief Process Enter BMPS Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterBmpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EnterBmpsReqParamsType* pwdiEnterBmpsReqParams = NULL; + WDI_EnterBmpsRspCb wdiEnterBmpsRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalEnterBmpsReqParams enterBmpsReq; + wpt_status wptStatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiEnterBmpsReqParams = (WDI_EnterBmpsReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiEnterBmpsRspCb = (WDI_EnterBmpsRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ENTER_BMPS_REQ, + sizeof(enterBmpsReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(enterBmpsReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Enter BMPS req %p %p %p", + pEventData, pwdiEnterBmpsReqParams, wdiEnterBmpsRspCb); + WDI_ASSERT(0); + goto failRequest; + } + + /* Reset the event to be not signalled */ + wptStatus = wpalEventReset(&pWDICtx->setPowerStateEvent); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to reset an event"); + + WDI_ASSERT(0); + goto fail; + } + + // notify DTS that we are entering BMPS + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_BMPS, WDI_SetPowerStateCb); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that we are entering BMPS", wptStatus); + WDI_ASSERT(0); + goto fail; + } + +/* + * Wait for the event to be set once the ACK comes back from DXE + */ + wptStatus = wpalEventWait(&pWDICtx->setPowerStateEvent, + WDI_SET_POWER_STATE_TIMEOUT); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "WDI Init failed to wait on an event"); + + WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + WDI_ASSERT(0); + goto fail; + } + + pWDICtx->bInBmps = eWLAN_PAL_TRUE; + + enterBmpsReq.bssIdx = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucBssIdx; + enterBmpsReq.tbtt = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.uTbtt; + enterBmpsReq.dtimCount = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucDtimCount; + enterBmpsReq.dtimPeriod = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.ucDtimPeriod; + + // For ESE and 11R Roaming + enterBmpsReq.rssiFilterPeriod = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.rssiFilterPeriod; + enterBmpsReq.numBeaconPerRssiAverage = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.numBeaconPerRssiAverage; + enterBmpsReq.bRssiFilterEnable = pwdiEnterBmpsReqParams->wdiEnterBmpsInfo.bRssiFilterEnable; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &enterBmpsReq, + sizeof(enterBmpsReq)); + + pWDICtx->wdiReqStatusCB = pwdiEnterBmpsReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiEnterBmpsReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEnterBmpsRspCb, pEventData->pUserData, WDI_ENTER_BMPS_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +}/*WDI_ProcessEnterBmpsReq*/ + +/** + @brief Process Exit BMPS Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitBmpsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ExitBmpsReqParamsType* pwdiExitBmpsReqParams = NULL; + WDI_ExitBmpsRspCb wdiExitBmpsRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalExitBmpsReqParams exitBmpsReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiExitBmpsReqParams = (WDI_ExitBmpsReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiExitBmpsRspCb = (WDI_ExitBmpsRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_EXIT_BMPS_REQ, + sizeof(exitBmpsReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(exitBmpsReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Exit BMPS req %p %p %p", + pEventData, pwdiExitBmpsReqParams, wdiExitBmpsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + exitBmpsReq.sendDataNull = pwdiExitBmpsReqParams->wdiExitBmpsInfo.ucSendDataNull; + + exitBmpsReq.bssIdx = pwdiExitBmpsReqParams->wdiExitBmpsInfo.bssIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &exitBmpsReq, + sizeof(exitBmpsReq)); + + pWDICtx->wdiReqStatusCB = pwdiExitBmpsReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiExitBmpsReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiExitBmpsRspCb, pEventData->pUserData, WDI_EXIT_BMPS_RESP); +}/*WDI_ProcessExitBmpsReq*/ + +/** + @brief Process Enter UAPSD Request function (called when Main + FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterUapsdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EnterUapsdReqParamsType* pwdiEnterUapsdReqParams = NULL; + WDI_EnterUapsdRspCb wdiEnterUapsdRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tUapsdReqParams enterUapsdReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiEnterUapsdReqParams = (WDI_EnterUapsdReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiEnterUapsdRspCb = (WDI_EnterUapsdRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ENTER_UAPSD_REQ, + sizeof(enterUapsdReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(enterUapsdReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Enter UAPSD req %p %p %p", + pEventData, pwdiEnterUapsdReqParams, wdiEnterUapsdRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + enterUapsdReq.beDeliveryEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBeDeliveryEnabled; + enterUapsdReq.beTriggerEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBeTriggerEnabled; + enterUapsdReq.bkDeliveryEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBkDeliveryEnabled; + enterUapsdReq.bkTriggerEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucBkTriggerEnabled; + enterUapsdReq.viDeliveryEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucViDeliveryEnabled; + enterUapsdReq.viTriggerEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucViTriggerEnabled; + enterUapsdReq.voDeliveryEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucVoDeliveryEnabled; + enterUapsdReq.voTriggerEnabled = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.ucVoTriggerEnabled; + enterUapsdReq.bssIdx = pwdiEnterUapsdReqParams->wdiEnterUapsdInfo.bssIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &enterUapsdReq, + sizeof(enterUapsdReq)); + + pWDICtx->wdiReqStatusCB = pwdiEnterUapsdReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiEnterUapsdReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEnterUapsdRspCb, pEventData->pUserData, WDI_ENTER_UAPSD_RESP); +}/*WDI_ProcessEnterUapsdReq*/ + +/** + @brief Process Exit UAPSD Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitUapsdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ExitUapsdRspCb wdiExitUapsdRspCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_ExitUapsdReqParamsType *pExitUapsdparams; + wpt_uint8 bssIdx = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pExitUapsdparams = (WDI_ExitUapsdReqParamsType *)pEventData->pEventData)) || + ( NULL == (wdiExitUapsdRspCb = (WDI_ExitUapsdRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_EXIT_UAPSD_REQ, + sizeof(wpt_uint8), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(wpt_uint8)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Exit UAPSD req %p %p", + pEventData, wdiExitUapsdRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + bssIdx = pExitUapsdparams->wdiExitUapsdInfo.bssIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &bssIdx, + sizeof(wpt_uint8)); + + pWDICtx->wdiReqStatusCB = pExitUapsdparams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pExitUapsdparams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiExitUapsdRspCb, pEventData->pUserData, WDI_EXIT_UAPSD_RESP); +}/*WDI_ProcessExitUapsdReq*/ + +/** + @brief Process Set UAPSD params Request function (called when + Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetUapsdAcParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetUapsdAcParamsReqParamsType* pwdiSetUapsdAcParams = NULL; + WDI_SetUapsdAcParamsCb wdiSetUapsdAcParamsCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tUapsdInfo uapsdAcParamsReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiSetUapsdAcParams = (WDI_SetUapsdAcParamsReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiSetUapsdAcParamsCb = (WDI_SetUapsdAcParamsCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_UAPSD_PARAM_REQ, + sizeof(uapsdAcParamsReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(uapsdAcParamsReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set UAPSD params req %p %p %p", + pEventData, pwdiSetUapsdAcParams, wdiSetUapsdAcParamsCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + uapsdAcParamsReq.ac = pwdiSetUapsdAcParams->wdiUapsdInfo.ucAc; + uapsdAcParamsReq.staidx = pwdiSetUapsdAcParams->wdiUapsdInfo.ucSTAIdx; + uapsdAcParamsReq.up = pwdiSetUapsdAcParams->wdiUapsdInfo.ucUp; + uapsdAcParamsReq.delayInterval = pwdiSetUapsdAcParams->wdiUapsdInfo.uDelayInterval; + uapsdAcParamsReq.srvInterval = pwdiSetUapsdAcParams->wdiUapsdInfo.uSrvInterval; + uapsdAcParamsReq.susInterval = pwdiSetUapsdAcParams->wdiUapsdInfo.uSusInterval; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &uapsdAcParamsReq, + sizeof(uapsdAcParamsReq)); + + pWDICtx->wdiReqStatusCB = pwdiSetUapsdAcParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetUapsdAcParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetUapsdAcParamsCb, pEventData->pUserData, WDI_SET_UAPSD_PARAM_RESP); +}/*WDI_ProcessSetUapsdAcParamsReq*/ + +/** + @brief Process update UAPSD params Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateUapsdParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateUapsdReqParamsType* pwdiUpdateUapsdReqParams = NULL; + WDI_UpdateUapsdParamsCb wdiUpdateUapsdParamsCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiUpdateUapsdReqParams = (WDI_UpdateUapsdReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiUpdateUapsdParamsCb = (WDI_UpdateUapsdParamsCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_UAPSD_PARAM_REQ, + sizeof(pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Update UAPSD params req %p %p %p", + pEventData, pwdiUpdateUapsdReqParams, wdiUpdateUapsdParamsCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo, + sizeof(pwdiUpdateUapsdReqParams->wdiUpdateUapsdInfo)); + + pWDICtx->wdiReqStatusCB = pwdiUpdateUapsdReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateUapsdReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiUpdateUapsdParamsCb, pEventData->pUserData, WDI_UPDATE_UAPSD_PARAM_RESP); +}/*WDI_ProcessUpdateUapsdParamsReq*/ + +/** + @brief Process Configure RXP filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureRxpFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ConfigureRxpFilterReqParamsType* pwdiRxpFilterParams = NULL; + WDI_ConfigureRxpFilterCb wdiConfigureRxpFilterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalConfigureRxpFilterReqParams halRxpFilterParams; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiRxpFilterParams = (WDI_ConfigureRxpFilterReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiConfigureRxpFilterCb = (WDI_ConfigureRxpFilterCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIGURE_RXP_FILTER_REQ, + sizeof(halRxpFilterParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halRxpFilterParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set UAPSD params req %p %p %p", + pEventData, pwdiRxpFilterParams, wdiConfigureRxpFilterCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halRxpFilterParams.setMcstBcstFilterSetting = + pwdiRxpFilterParams->wdiRxpFilterParam.ucSetMcstBcstFilterSetting; + halRxpFilterParams.setMcstBcstFilter = + pwdiRxpFilterParams->wdiRxpFilterParam.ucSetMcstBcstFilter; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halRxpFilterParams, + sizeof(halRxpFilterParams)); + + pWDICtx->wdiReqStatusCB = pwdiRxpFilterParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRxpFilterParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiConfigureRxpFilterCb, pEventData->pUserData, WDI_CONFIGURE_RXP_FILTER_RESP); +}/*WDI_ProcessConfigureRxpFilterReq*/ + +/** + @brief Process set beacon filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBeaconFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_BeaconFilterReqParamsType* pwdiBeaconFilterParams = NULL; + WDI_SetBeaconFilterCb wdiBeaconFilterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiBeaconFilterParams = (WDI_BeaconFilterReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiBeaconFilterCb = (WDI_SetBeaconFilterCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_BEACON_FILTER_REQ, + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo) + pwdiBeaconFilterParams->wdiBeaconFilterInfo.usIeNum * sizeof(tBeaconFilterIe), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set beacon filter req %p %p %p", + pEventData, pwdiBeaconFilterParams, wdiBeaconFilterCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiBeaconFilterParams->wdiBeaconFilterInfo, + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo)); + wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo), + &pwdiBeaconFilterParams->aFilters[0], + pwdiBeaconFilterParams->wdiBeaconFilterInfo.usIeNum * sizeof(tBeaconFilterIe)); + + pWDICtx->wdiReqStatusCB = pwdiBeaconFilterParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiBeaconFilterParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiBeaconFilterCb, pEventData->pUserData, WDI_SET_BEACON_FILTER_RESP); +}/*WDI_ProcessSetBeaconFilterReq*/ + +/** + @brief Process remove beacon filter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemBeaconFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RemBeaconFilterReqParamsType* pwdiBeaconFilterParams = NULL; + WDI_RemBeaconFilterCb wdiBeaconFilterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiBeaconFilterParams = (WDI_RemBeaconFilterReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiBeaconFilterCb = (WDI_RemBeaconFilterCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_REM_BEACON_FILTER_REQ, + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in remove beacon filter req %p %p %p", + pEventData, pwdiBeaconFilterParams, wdiBeaconFilterCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &pwdiBeaconFilterParams->wdiBeaconFilterInfo, + sizeof(pwdiBeaconFilterParams->wdiBeaconFilterInfo)); + + pWDICtx->wdiReqStatusCB = pwdiBeaconFilterParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiBeaconFilterParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiBeaconFilterCb, pEventData->pUserData, WDI_REM_BEACON_FILTER_RESP); +} + +/** + @brief Process set RSSI thresholds Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRSSIThresholdsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetRSSIThresholdsReqParamsType* pwdiRSSIThresholdsParams = NULL; + WDI_SetRSSIThresholdsCb wdiRSSIThresholdsCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalRSSIThresholds rssiThresholdsReq; + WDI_Status ret_status = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiRSSIThresholdsParams = (WDI_SetRSSIThresholdsReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiRSSIThresholdsCb = (WDI_SetRSSIThresholdsCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_RSSI_THRESHOLDS_REQ, + sizeof(rssiThresholdsReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(rssiThresholdsReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in remove beacon filter req %p %p %p", + pEventData, pwdiRSSIThresholdsParams, wdiRSSIThresholdsCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + rssiThresholdsReq.bReserved10 = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bReserved10; + rssiThresholdsReq.bRssiThres1NegNotify = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres1NegNotify; + rssiThresholdsReq.bRssiThres1PosNotify = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres1PosNotify; + rssiThresholdsReq.bRssiThres2NegNotify = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres2NegNotify; + rssiThresholdsReq.bRssiThres2PosNotify = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres2PosNotify; + rssiThresholdsReq.bRssiThres3NegNotify = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres3NegNotify; + rssiThresholdsReq.bRssiThres3PosNotify = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.bRssiThres3PosNotify; + rssiThresholdsReq.ucRssiThreshold1 = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.ucRssiThreshold1; + rssiThresholdsReq.ucRssiThreshold2 = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.ucRssiThreshold2; + rssiThresholdsReq.ucRssiThreshold3 = + pwdiRSSIThresholdsParams->wdiRSSIThresholdsInfo.ucRssiThreshold3; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &rssiThresholdsReq, + sizeof(rssiThresholdsReq)); + + pWDICtx->wdiReqStatusCB = pwdiRSSIThresholdsParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRSSIThresholdsParams->pUserData; + + /*------------------------------------------------------------------------- + Send Set threshold req to HAL + -------------------------------------------------------------------------*/ + if ((ret_status = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRSSIThresholdsCb, pEventData->pUserData, WDI_SET_RSSI_THRESHOLDS_RESP)) == WDI_STATUS_SUCCESS) + { + // When we are in idle state WDI_STARTED_ST and we receive indication for threshold + // req. Then as a result of processing the threshold cross ind, we trigger + // a Set threshold req, then we need to indicate to WDI that it needs to + // go to busy state as a result of the indication as we sent a req in the + // same WDI context. + // Hence expected state transition is to busy. + pWDICtx->ucExpectedStateTransition = WDI_BUSY_ST; + } + + return ret_status; +} + +/** + @brief Process set RSSI thresholds Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_HostOffloadReqParamsType* pwdiHostOffloadParams = NULL; + WDI_HostOffloadCb wdiHostOffloadCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalHostOffloadReq hostOffloadParams; + tHalNSOffloadParams nsOffloadParams; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiHostOffloadParams = (WDI_HostOffloadReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiHostOffloadCb = (WDI_HostOffloadCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_HOST_OFFLOAD_REQ, + sizeof(hostOffloadParams)+sizeof(nsOffloadParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(hostOffloadParams) + sizeof(nsOffloadParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in host offload req %p %p %p", + pEventData, pwdiHostOffloadParams, wdiHostOffloadCb); + WDI_ASSERT(0); + goto failRequest; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiHostOffloadParams->wdiHostOffloadInfo.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + " %s : Association for this BSSID does not exist " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pwdiHostOffloadParams->wdiHostOffloadInfo.bssId)); + goto fail; + } + + hostOffloadParams.offloadType = pwdiHostOffloadParams->wdiHostOffloadInfo.ucOffloadType; + hostOffloadParams.enableOrDisable = pwdiHostOffloadParams->wdiHostOffloadInfo.ucEnableOrDisable; + + if( HAL_IPV4_ARP_REPLY_OFFLOAD == hostOffloadParams.offloadType ) + { + // ARP Offload + wpalMemoryCopy(hostOffloadParams.params.hostIpv4Addr, + pwdiHostOffloadParams->wdiHostOffloadInfo.params.aHostIpv4Addr, + 4); + } + else + { + // NS Offload + wpalMemoryCopy(hostOffloadParams.params.hostIpv6Addr, + pwdiHostOffloadParams->wdiHostOffloadInfo.params.aHostIpv6Addr, + 16); + +#ifdef WLAN_NS_OFFLOAD + // copy pwdiHostOffloadParams->wdiNsOffloadParams into nsOffloadParams + wpalMemoryCopy(nsOffloadParams.srcIPv6Addr, + pwdiHostOffloadParams->wdiNsOffloadParams.srcIPv6Addr, + 16); + wpalMemoryCopy(nsOffloadParams.selfIPv6Addr, + pwdiHostOffloadParams->wdiNsOffloadParams.selfIPv6Addr, + 16); + wpalMemoryCopy(nsOffloadParams.targetIPv6Addr1, + pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr1, + 16); + wpalMemoryCopy(nsOffloadParams.targetIPv6Addr2, + pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr2, + 16); + wpalMemoryCopy(nsOffloadParams.selfMacAddr, + pwdiHostOffloadParams->wdiNsOffloadParams.selfMacAddr, + 6); + nsOffloadParams.srcIPv6AddrValid = + pwdiHostOffloadParams->wdiNsOffloadParams.srcIPv6AddrValid; + + nsOffloadParams.targetIPv6Addr1Valid = + pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr1Valid; + + nsOffloadParams.targetIPv6Addr2Valid = + pwdiHostOffloadParams->wdiNsOffloadParams.targetIPv6Addr2Valid; + + nsOffloadParams.slotIndex = + pwdiHostOffloadParams->wdiNsOffloadParams.slotIdx; + +#endif // WLAN_NS_OFFLOAD + } + + nsOffloadParams.bssIdx = pBSSSes->ucBSSIdx; + + // copy hostOffloadParams into pSendBuffer + wpalMemoryCopy( pSendBuffer+usDataOffset, + &hostOffloadParams, + sizeof(hostOffloadParams)); + + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION) ) + { + // copy nsOffloadParams into pSendBuffer + wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(hostOffloadParams), + &nsOffloadParams, + sizeof(nsOffloadParams)); + } + else + { +#ifdef WLAN_NS_OFFLOAD + if( HAL_IPV6_NS_OFFLOAD == hostOffloadParams.offloadType ) + { + // copy nsOffloadParams into pSendBuffer + wpalMemoryCopy( pSendBuffer+usDataOffset+sizeof(hostOffloadParams), + &nsOffloadParams, + sizeof(nsOffloadParams)); + } +#endif + } + + pWDICtx->wdiReqStatusCB = pwdiHostOffloadParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiHostOffloadParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiHostOffloadCb, pEventData->pUserData, WDI_HOST_OFFLOAD_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +}/*WDI_ProcessHostOffloadReq*/ + +/** + @brief Process Keep Alive Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessKeepAliveReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_KeepAliveReqParamsType* pwdiKeepAliveParams = NULL; + WDI_KeepAliveCb wdiKeepAliveCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalKeepAliveReq keepAliveReq; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiKeepAliveParams = (WDI_KeepAliveReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiKeepAliveCb = (WDI_KeepAliveCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid parameters in Keep Alive req"); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_KEEP_ALIVE_REQ, + sizeof(keepAliveReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(keepAliveReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to get send buffer in keep alive req %p %p %p", + pEventData, pwdiKeepAliveParams, wdiKeepAliveCb); + WDI_ASSERT(0); + goto failRequest; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiKeepAliveParams->wdiKeepAliveInfo.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + goto fail; + } + + keepAliveReq.packetType = pwdiKeepAliveParams->wdiKeepAliveInfo.ucPacketType; + keepAliveReq.timePeriod = pwdiKeepAliveParams->wdiKeepAliveInfo.ucTimePeriod; + + keepAliveReq.bssIdx = pBSSSes->ucBSSIdx; + + if(pwdiKeepAliveParams->wdiKeepAliveInfo.ucPacketType == 2) + { + wpalMemoryCopy(keepAliveReq.hostIpv4Addr, + pwdiKeepAliveParams->wdiKeepAliveInfo.aHostIpv4Addr, + HAL_IPV4_ADDR_LEN); + wpalMemoryCopy(keepAliveReq.destIpv4Addr, + pwdiKeepAliveParams->wdiKeepAliveInfo.aDestIpv4Addr, + HAL_IPV4_ADDR_LEN); + wpalMemoryCopy(keepAliveReq.destMacAddr, + pwdiKeepAliveParams->wdiKeepAliveInfo.aDestMacAddr, + HAL_MAC_ADDR_LEN); + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &keepAliveReq, + sizeof(keepAliveReq)); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Process keep alive req %zu", sizeof(keepAliveReq)); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Process keep alive req time period %d", + keepAliveReq.timePeriod); + + pWDICtx->wdiReqStatusCB = pwdiKeepAliveParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiKeepAliveParams->pUserData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Sending keep alive req to HAL"); + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiKeepAliveCb, pEventData->pUserData, WDI_KEEP_ALIVE_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +}/*WDI_ProcessKeepAliveReq*/ + + +/** + @brief Process Wowl add bc ptrn Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlAddBcPtrnReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_WowlAddBcPtrnReqParamsType* pwdiWowlAddBcPtrnParams = NULL; + WDI_WowlAddBcPtrnCb wdiWowlAddBcPtrnCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalWowlAddBcastPtrn wowlAddBcPtrnReq; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiWowlAddBcPtrnParams = (WDI_WowlAddBcPtrnReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiWowlAddBcPtrnCb = (WDI_WowlAddBcPtrnCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_ADD_BC_PTRN_REQ, + sizeof(wowlAddBcPtrnReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(wowlAddBcPtrnReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Wowl add bc ptrn req %p %p %p", + pEventData, pwdiWowlAddBcPtrnParams, wdiWowlAddBcPtrnCb); + WDI_ASSERT(0); + goto failRequest; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + goto fail; + } + + wowlAddBcPtrnReq.ucPatternId = + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternId; + wowlAddBcPtrnReq.ucPatternByteOffset = + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternByteOffset; + wowlAddBcPtrnReq.ucPatternMaskSize = + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize; + wowlAddBcPtrnReq.ucPatternSize = + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternSize; + + if (pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternSize <= HAL_WOWL_BCAST_PATTERN_MAX_SIZE) + { + wpalMemoryCopy(wowlAddBcPtrnReq.ucPattern, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPattern, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternSize); + wpalMemoryCopy(wowlAddBcPtrnReq.ucPatternMask, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMask, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize); + } + else + { + wpalMemoryCopy(wowlAddBcPtrnReq.ucPattern, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPattern, + HAL_WOWL_BCAST_PATTERN_MAX_SIZE); + wpalMemoryCopy(wowlAddBcPtrnReq.ucPatternMask, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMask, + HAL_WOWL_BCAST_PATTERN_MAX_SIZE); + + wpalMemoryCopy(wowlAddBcPtrnReq.ucPattern, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPattern, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize - HAL_WOWL_BCAST_PATTERN_MAX_SIZE); + wpalMemoryCopy(wowlAddBcPtrnReq.ucPatternMask, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMask, + pwdiWowlAddBcPtrnParams->wdiWowlAddBcPtrnInfo.ucPatternMaskSize - HAL_WOWL_BCAST_PATTERN_MAX_SIZE); + } + + wowlAddBcPtrnReq.bssIdx = pBSSSes->ucBSSIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &wowlAddBcPtrnReq, + sizeof(wowlAddBcPtrnReq)); + + pWDICtx->wdiReqStatusCB = pwdiWowlAddBcPtrnParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiWowlAddBcPtrnParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiWowlAddBcPtrnCb, pEventData->pUserData, WDI_WOWL_ADD_BC_PTRN_RESP); +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +}/*WDI_ProcessWowlAddBcPtrnReq*/ + +/** + @brief Process Wowl delete bc ptrn Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlDelBcPtrnReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_WowlDelBcPtrnReqParamsType* pwdiWowlDelBcPtrnParams = NULL; + WDI_WowlDelBcPtrnCb wdiWowlDelBcPtrnCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalWowlDelBcastPtrn wowlDelBcPtrnReq; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiWowlDelBcPtrnParams = (WDI_WowlDelBcPtrnReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiWowlDelBcPtrnCb = (WDI_WowlDelBcPtrnCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_DEL_BC_PTRN_REQ, + sizeof(wowlDelBcPtrnReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(wowlDelBcPtrnReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Wowl del bc ptrn req %p %p %p", + pEventData, pwdiWowlDelBcPtrnParams, wdiWowlDelBcPtrnCb); + WDI_ASSERT(0); + goto failRequest; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiWowlDelBcPtrnParams->wdiWowlDelBcPtrnInfo.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + goto fail; + } + + wowlDelBcPtrnReq.ucPatternId = + pwdiWowlDelBcPtrnParams->wdiWowlDelBcPtrnInfo.ucPatternId; + + wowlDelBcPtrnReq.bssIdx = pBSSSes->ucBSSIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &wowlDelBcPtrnReq, + sizeof(wowlDelBcPtrnReq)); + + pWDICtx->wdiReqStatusCB = pwdiWowlDelBcPtrnParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiWowlDelBcPtrnParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiWowlDelBcPtrnCb, pEventData->pUserData, WDI_WOWL_DEL_BC_PTRN_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +}/*WDI_ProcessWowlDelBcPtrnReq*/ + +/** + @brief Process Wowl enter Request function (called + when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlEnterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_WowlEnterReqParamsType* pwdiWowlEnterParams = NULL; + WDI_WowlEnterReqCb wdiWowlEnterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalWowlEnterParams wowlEnterReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiWowlEnterParams = (WDI_WowlEnterReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiWowlEnterCb = (WDI_WowlEnterReqCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_ENTER_REQ, + sizeof(wowlEnterReq), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(wowlEnterReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Wowl enter req %p %p %p", + pEventData, pwdiWowlEnterParams, wdiWowlEnterCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(&wowlEnterReq, sizeof(tHalWowlEnterParams)); + + wowlEnterReq.ucMagicPktEnable = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucMagicPktEnable; + wowlEnterReq.ucPatternFilteringEnable = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucPatternFilteringEnable; + wowlEnterReq.ucUcastPatternFilteringEnable = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucUcastPatternFilteringEnable; + wowlEnterReq.ucWowChnlSwitchRcv = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowChnlSwitchRcv; + wowlEnterReq.ucWowDeauthRcv = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowDeauthRcv; + wowlEnterReq.ucWowDisassocRcv = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowDisassocRcv; + wowlEnterReq.ucWowMaxMissedBeacons = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowMaxMissedBeacons; + wowlEnterReq.ucWowMaxSleepUsec = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowMaxSleepUsec; + +#ifdef WLAN_WAKEUP_EVENTS + wowlEnterReq.ucWoWEAPIDRequestEnable = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWoWEAPIDRequestEnable; + + wowlEnterReq.ucWoWEAPOL4WayEnable = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWoWEAPOL4WayEnable; + + wowlEnterReq.ucWowNetScanOffloadMatch = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowNetScanOffloadMatch; + + wowlEnterReq.ucWowGTKRekeyError = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWowGTKRekeyError; + + wowlEnterReq.ucWoWBSSConnLoss = + pwdiWowlEnterParams->wdiWowlEnterInfo.ucWoWBSSConnLoss; +#endif // WLAN_WAKEUP_EVENTS + + wowlEnterReq.bssIdx = pwdiWowlEnterParams->wdiWowlEnterInfo.bssIdx; + + wpalMemoryCopy(wowlEnterReq.magicPtrn, + pwdiWowlEnterParams->wdiWowlEnterInfo.magicPtrn, + sizeof(tSirMacAddr)); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &wowlEnterReq, + sizeof(wowlEnterReq)); + + pWDICtx->wdiReqStatusCB = pwdiWowlEnterParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiWowlEnterParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiWowlEnterCb, pEventData->pUserData, WDI_WOWL_ENTER_RESP); +}/*WDI_ProcessWowlEnterReq*/ + +/** + @brief Process Wowl exit Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlExitReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_WowlExitReqCb wdiWowlExitCb = NULL; + WDI_WowlExitReqParamsType* pwdiWowlExitParams = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalWowlExitParams wowlExitparams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiWowlExitParams = (WDI_WowlExitReqParamsType *)pEventData->pEventData)) || + ( NULL == (wdiWowlExitCb = (WDI_WowlExitReqCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_WOWL_EXIT_REQ, + sizeof(wowlExitparams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(wowlExitparams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Wowl Exit req %p %p", + pEventData, wdiWowlExitCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wowlExitparams.bssIdx = pwdiWowlExitParams->wdiWowlExitInfo.bssIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &wowlExitparams, + sizeof(wowlExitparams)); + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiWowlExitCb, pEventData->pUserData, WDI_WOWL_EXIT_RESP); +}/*WDI_ProcessWowlExitReq*/ + +/** + @brief Process Configure Apps Cpu Wakeup State Request function + (called when Main FSM allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureAppsCpuWakeupStateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ConfigureAppsCpuWakeupStateReqParamsType* pwdiAppsCpuWakeupStateParams = NULL; + WDI_ConfigureAppsCpuWakeupStateCb wdiConfigureAppsCpuWakeupStateCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalConfigureAppsCpuWakeupStateReqParams halCfgAppsCpuWakeupStateReqParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiAppsCpuWakeupStateParams = (WDI_ConfigureAppsCpuWakeupStateReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiConfigureAppsCpuWakeupStateCb = (WDI_ConfigureAppsCpuWakeupStateCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ, + sizeof(halCfgAppsCpuWakeupStateReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(pwdiAppsCpuWakeupStateParams->bIsAppsAwake) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Apps CPU Wakeup State req %p %p %p", + pEventData, pwdiAppsCpuWakeupStateParams, wdiConfigureAppsCpuWakeupStateCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halCfgAppsCpuWakeupStateReqParams.isAppsCpuAwake = + pwdiAppsCpuWakeupStateParams->bIsAppsAwake; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halCfgAppsCpuWakeupStateReqParams, + sizeof(halCfgAppsCpuWakeupStateReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiAppsCpuWakeupStateParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiAppsCpuWakeupStateParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiConfigureAppsCpuWakeupStateCb, pEventData->pUserData, + WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP); +}/*WDI_ProcessConfigureAppsCpuWakeupStateReq*/ + +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief Process Aggregated Add TSpec Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAggrAddTSpecReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AggrAddTSReqParamsType* pwdiAggrAddTSParams; + WDI_AggrAddTsRspCb wdiAggrAddTSRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_macAddr macBSSID; + tAggrAddTsReq halAggrAddTsReq; + int i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wpalMemoryFill( &halAggrAddTsReq, sizeof(tAggrAddTsReq), 0 ); + pwdiAggrAddTSParams = (WDI_AggrAddTSReqParamsType*)pEventData->pEventData; + wdiAggrAddTSRspCb = (WDI_AggrAddTsRspCb)pEventData->pCBfnc; + /*------------------------------------------------------------------------- + Check to see if we are in the middle of an association, if so queue, if + not it means it is free to process request + -------------------------------------------------------------------------*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made and identify WDI session + ------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != WDI_STATableGetStaBSSIDAddr(pWDICtx, + pwdiAggrAddTSParams->wdiAggrTsInfo.ucSTAIdx, + &macBSSID)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "This station does not exist in the WDI Station Table %d", + pwdiAggrAddTSParams->wdiAggrTsInfo.ucSTAIdx); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, macBSSID, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Check if this BSS is being currently processed or queued, + if queued - queue the new request as well + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_TRUE == pBSSSes->bAssocReqQueued ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Association sequence for this BSS exists but currently queued. macBSSID " MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(macBSSID)); + + wdiStatus = WDI_QueueAssocRequest( pWDICtx, pBSSSes, pEventData); + wpalMutexRelease(&pWDICtx->wptMutex); + return wdiStatus; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_AGGR_ADD_TS_REQ, + sizeof(tAggrAddTsParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tAggrAddTsParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pwdiAggrAddTSParams, wdiAggrAddTSRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halAggrAddTsReq.aggrAddTsParam.staIdx = + pwdiAggrAddTSParams->wdiAggrTsInfo.ucSTAIdx; + halAggrAddTsReq.aggrAddTsParam.tspecIdx = + pwdiAggrAddTSParams->wdiAggrTsInfo.ucTspecIdx; + + for( i = 0; i < WLAN_HAL_MAX_AC; i++ ) + { + halAggrAddTsReq.aggrAddTsParam.tspec[i].type = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].ucType; + halAggrAddTsReq.aggrAddTsParam.tspec[i].length = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].ucLength; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.ackPolicy = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + ackPolicy; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.accessPolicy = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + accessPolicy; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.userPrio = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + userPrio; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.psb = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + psb; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.aggregation = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + aggregation; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.direction = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + direction; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.tsid = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + trafficType; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.traffic.tsid = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiTraffic. + trafficType; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.schedule.rsvd = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiSchedule.rsvd; + halAggrAddTsReq.aggrAddTsParam.tspec[i].tsinfo.schedule.schedule = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].wdiTSinfo.wdiSchedule.schedule; + + + halAggrAddTsReq.aggrAddTsParam.tspec[i].nomMsduSz = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usNomMsduSz; + halAggrAddTsReq.aggrAddTsParam.tspec[i].maxMsduSz = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usMaxMsduSz; + halAggrAddTsReq.aggrAddTsParam.tspec[i].minSvcInterval = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMinSvcInterval; + halAggrAddTsReq.aggrAddTsParam.tspec[i].maxSvcInterval = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMaxSvcInterval; + halAggrAddTsReq.aggrAddTsParam.tspec[i].inactInterval = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uInactInterval; + halAggrAddTsReq.aggrAddTsParam.tspec[i].suspendInterval = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uSuspendInterval; + halAggrAddTsReq.aggrAddTsParam.tspec[i].svcStartTime = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uSvcStartTime; + halAggrAddTsReq.aggrAddTsParam.tspec[i].minDataRate = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMinDataRate; + halAggrAddTsReq.aggrAddTsParam.tspec[i].meanDataRate = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMeanDataRate; + halAggrAddTsReq.aggrAddTsParam.tspec[i].peakDataRate = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uPeakDataRate; + halAggrAddTsReq.aggrAddTsParam.tspec[i].maxBurstSz = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMaxBurstSz; + halAggrAddTsReq.aggrAddTsParam.tspec[i].delayBound = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uDelayBound; + halAggrAddTsReq.aggrAddTsParam.tspec[i].minPhyRate = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].uMinPhyRate; + halAggrAddTsReq.aggrAddTsParam.tspec[i].surplusBw = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usSurplusBw; + halAggrAddTsReq.aggrAddTsParam.tspec[i].mediumTime = + pwdiAggrAddTSParams->wdiAggrTsInfo.wdiTspecIE[i].usMediumTime; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halAggrAddTsReq, + sizeof(halAggrAddTsReq)); + + pWDICtx->wdiReqStatusCB = pwdiAggrAddTSParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiAggrAddTSParams->pUserData; + + /*------------------------------------------------------------------------- + Send Add TS Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiAggrAddTSRspCb, pEventData->pUserData, + WDI_AGGR_ADD_TS_RESP); +}/*WDI_ProcessAggrAddTSpecReq*/ +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + @brief Process Shutdown Request function (called when Main FSM + allows it) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessShutdownReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ) +{ + wpt_status wptStatus; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == pEventData ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMutexAcquire(&pWDICtx->wptMutex); + + + gWDIInitialized = eWLAN_PAL_FALSE; + /*! TO DO: stop the data services */ + if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode ) + { + /*Stop the STA Table !UT- check this logic again + It is safer to do it here than on the response - because a stop is imminent*/ + WDI_STATableStop(pWDICtx); + + /* Stop Transport Driver, DXE */ + WDTS_Stop(pWDICtx); + } + + /*Clear all pending request*/ + WDI_ClearPendingRequests(pWDICtx); + /* Close Data transport*/ + /* FTM mode does not open Data Path */ + if ( eDRIVER_TYPE_MFG != pWDICtx->driverMode ) + { + WDTS_Close(pWDICtx); + } + /*Close the STA Table !UT- check this logic again*/ + WDI_STATableClose(pWDICtx); + /*close the PAL */ + wptStatus = wpalClose(pWDICtx->pPALContext); + if ( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to wpal Close %d", wptStatus); + WDI_ASSERT(0); + } + + /*Transition back to init state*/ + WDI_STATE_TRANSITION( pWDICtx, WDI_INIT_ST); + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Make sure the expected state is properly defaulted to Init*/ + pWDICtx->ucExpectedStateTransition = WDI_INIT_ST; + + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessShutdownReq*/ + +/*======================================================================== + Main DAL Control Path Response Processing API +========================================================================*/ + +/** + @brief Process Start Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_StartRspParamsType wdiRspParams; + WDI_StartRspCb wdiStartRspCb = NULL; + + tHalMacStartRspParams* startRspParams; + +#ifndef HAL_SELF_STA_PER_BSS + WDI_AddStaParams wdiAddSTAParam = {0}; +#endif + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + wdiStartRspCb = (WDI_StartRspCb)pWDICtx->pfncRspCB; + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == wdiStartRspCb )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if ( sizeof(tHalMacStartRspParams) > pEventData->uEventDataSize ) + { + // not enough data was received + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Invalid response length in Start Resp Expect %zx Rcvd %x", + sizeof(tHalMacStartRspParams), pEventData->uEventDataSize); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Unpack HAL Response Message - the header was already extracted by the + main Response Handling procedure + -------------------------------------------------------------------------*/ + startRspParams = (tHalMacStartRspParams *) pEventData->pEventData; + + wdiRspParams.ucMaxBssids = startRspParams->ucMaxBssids; + wdiRspParams.ucMaxStations = startRspParams->ucMaxStations; + wdiRspParams.wlanCompiledVersion.major = WLAN_HAL_VER_MAJOR; + wdiRspParams.wlanCompiledVersion.minor = WLAN_HAL_VER_MINOR; + wdiRspParams.wlanCompiledVersion.version = WLAN_HAL_VER_VERSION; + wdiRspParams.wlanCompiledVersion.revision = WLAN_HAL_VER_REVISION; + wdiRspParams.wlanReportedVersion.major = + startRspParams->wcnssWlanVersion.major; + wdiRspParams.wlanReportedVersion.minor = + startRspParams->wcnssWlanVersion.minor; + wdiRspParams.wlanReportedVersion.version = + startRspParams->wcnssWlanVersion.version; + wdiRspParams.wlanReportedVersion.revision = + startRspParams->wcnssWlanVersion.revision; + wpalMemoryCopy(wdiRspParams.wcnssSoftwareVersion, + startRspParams->wcnssCrmVersionString, + sizeof(wdiRspParams.wcnssSoftwareVersion)); + wpalMemoryCopy(wdiRspParams.wcnssHardwareVersion, + startRspParams->wcnssWlanVersionString, + sizeof(wdiRspParams.wcnssHardwareVersion)); + wdiRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(startRspParams->status); + + /*Save the HAL Version*/ + pWDICtx->wlanVersion = wdiRspParams.wlanReportedVersion; + + wpalMutexAcquire(&pWDICtx->wptMutex); + if ( WDI_STATUS_SUCCESS == wdiRspParams.wdiStatus ) + { + pWDICtx->ucExpectedStateTransition = WDI_STARTED_ST; + + /*Cache the start response for further use*/ + wpalMemoryCopy( &pWDICtx->wdiCachedStartRspParams , + &wdiRspParams, + sizeof(pWDICtx->wdiCachedStartRspParams)); + + } + else + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to start device with status %s(%d)", + WDI_getHALStatusMsgString(startRspParams->status), + startRspParams->status); + + /*Set the expected state transition to stopped - because the start has + failed*/ + pWDICtx->ucExpectedStateTransition = WDI_STOPPED_ST; + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Notify UMAC*/ + wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData); + + WDI_DetectedDeviceError(pWDICtx, wdiRspParams.wdiStatus); + wpalWlanReload(); + + /*Although the response is an error - it was processed by our function + so as far as the caller is concerned this is a succesful reponse processing*/ + return WDI_STATUS_SUCCESS; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + if(eDRIVER_TYPE_MFG == pWDICtx->driverMode) + { + /* FTM mode does not need to execute below */ + /* Notify UMAC */ + wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData); + return WDI_STATUS_SUCCESS; + } + + /* START the Data transport */ + WDTS_startTransport(pWDICtx); + + /*Start the STA Table !- check this logic again*/ + WDI_STATableStart(pWDICtx); + +#ifndef HAL_SELF_STA_PER_BSS + /* Store the Self STA Index */ + pWDICtx->ucSelfStaId = halStartRspMsg.startRspParams.selfStaIdx; + + pWDICtx->usSelfStaDpuId = wdiRspParams.usSelfStaDpuId; + wpalMemoryCopy(pWDICtx->macSelfSta, wdiRspParams.macSelfSta, + WDI_MAC_ADDR_LEN); + + /* At this point add the self-STA */ + + /*! TO DO: wdiAddSTAParam.bcastMgmtDpuSignature */ + /* !TO DO: wdiAddSTAParam.bcastDpuSignature */ + /*! TO DO: wdiAddSTAParam.dpuSig */ + /*! TO DO: wdiAddSTAParam.ucWmmEnabled */ + /*! TO DO: wdiAddSTAParam.ucHTCapable */ + /*! TO DO: wdiAddSTAParam.ucRmfEnabled */ + + //all DPU indices are the same for self STA + wdiAddSTAParam.bcastDpuIndex = wdiRspParams.usSelfStaDpuId; + wdiAddSTAParam.bcastMgmtDpuIndex = wdiRspParams.usSelfStaDpuId; + wdiAddSTAParam.dpuIndex = wdiRspParams.usSelfStaDpuId; + wpalMemoryCopy(wdiAddSTAParam.staMacAddr, wdiRspParams.macSelfSta, + WDI_MAC_ADDR_LEN); + wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_SELF; /* 0 - self */ + wdiAddSTAParam.ucSTAIdx = halStartRspMsg.startRspParams.selfStaIdx; + + /* Note: Since we don't get an explicit config STA request for self STA, we + add the self STA upon receiving the Start response message. But the + self STA entry in the table is deleted when WDI gets an explicit delete STA + request */ + (void)WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam); +#endif + + /*Notify UMAC*/ + wdiStartRspCb( &wdiRspParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessStartRsp*/ + + +/** + @brief Process Stop Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + WDI_StopRspCb wdiStopRspCb = NULL; + + tHalMacStopRspMsg halMacStopRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + wdiStopRspCb = (WDI_StopRspCb)pWDICtx->pfncRspCB; + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == wdiStopRspCb )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if ( sizeof(halMacStopRspMsg) < pEventData->uEventDataSize ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Invalid response length in Stop Resp %u", + pEventData->uEventDataSize); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Unpack HAL Response Message - the header was already extracted by the + main Response Handling procedure + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halMacStopRspMsg.stopRspParams, + pEventData->pEventData, + sizeof(halMacStopRspMsg.stopRspParams)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halMacStopRspMsg.stopRspParams.status); + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*-------------------------------------------------------------------------- + Check to see if the stop went OK + --------------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to stop the device with status %s (%d)", + WDI_getHALStatusMsgString(halMacStopRspMsg.stopRspParams.status), + halMacStopRspMsg.stopRspParams.status); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + wpalWlanReload(); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_FAILURE; + } + + pWDICtx->ucExpectedStateTransition = WDI_STOPPED_ST; + + /*Transition now as WDI may get preempted imediately after it sends + up the Stop Response and it will not get to process the state transition + from Main Rsp function*/ + WDI_STATE_TRANSITION( pWDICtx, pWDICtx->ucExpectedStateTransition); + wpalMutexRelease(&pWDICtx->wptMutex); + + /*! TO DO: - STOP the Data transport */ + + /*Notify UMAC*/ + wdiStopRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessStopRsp*/ + +/** + @brief Process Close Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCloseRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*There is no close response comming from HAL - function just kept for + simmetry */ + WDI_ASSERT(0); + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessCloseRsp*/ + + +/*============================================================================ + SCAN RESPONSE PROCESSING API +============================================================================*/ + +/** + @brief Process Init Scan Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessInitScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + WDI_InitScanRspCb wdiInitScanRspCb; + tHalInitScanRspMsg halInitScanRspMsg; + wpt_status wptStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiInitScanRspCb = (WDI_InitScanRspCb)pWDICtx->pfncRspCB; + if( NULL == wdiInitScanRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: call back function is NULL", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Unpack HAL Response Message - the header was already extracted by the + main Response Handling procedure + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halInitScanRspMsg.initScanRspParams, + pEventData->pEventData, + sizeof(halInitScanRspMsg.initScanRspParams)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halInitScanRspMsg.initScanRspParams.status); + + if (pWDICtx->bInBmps && (WDI_STATUS_SUCCESS == wdiStatus)) + { + // notify DTS that we are entering Full power + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus); + WDI_ASSERT(0); + } + } + else if (WDI_STATUS_SUCCESS != wdiStatus) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Error returned WDI_ProcessInitScanRspi:%d BMPS%d", + wdiStatus, pWDICtx->bInBmps); + } + + /*Notify UMAC*/ + wdiInitScanRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessInitScanRsp*/ + + +/** + @brief Process Start Scan Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_StartScanRspParamsType wdiStartScanParams; + WDI_StartScanRspCb wdiStartScanRspCb; + + tHalStartScanRspMsg halStartScanRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiStartScanRspCb = (WDI_StartScanRspCb)pWDICtx->pfncRspCB; + if( NULL == wdiStartScanRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: call back function is NULL", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStartScanRspMsg.startScanRspParams, + pEventData->pEventData, + sizeof(halStartScanRspMsg.startScanRspParams)); + + wdiStartScanParams.wdiStatus = WDI_HAL_2_WDI_STATUS( + halStartScanRspMsg.startScanRspParams.status); +#ifdef WLAN_FEATURE_VOWIFI + wdiStartScanParams.ucTxMgmtPower = + halStartScanRspMsg.startScanRspParams.txMgmtPower; + wpalMemoryCopy( wdiStartScanParams.aStartTSF, + halStartScanRspMsg.startScanRspParams.startTSF, + 2); +#endif + + if ( eHAL_STATUS_SUCCESS != halStartScanRspMsg.startScanRspParams.status ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Start scan failed with status %s (%d)", + WDI_getHALStatusMsgString(halStartScanRspMsg.startScanRspParams.status), + halStartScanRspMsg.startScanRspParams.status); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiStartScanRspCb( &wdiStartScanParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; + +}/*WDI_ProcessStartScanRsp*/ + + +/** + @brief Process End Scan Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEndScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + tHalEndScanRspMsg halEndScanRspMsg; + WDI_EndScanRspCb wdiEndScanRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEndScanRspCb = (WDI_EndScanRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halEndScanRspMsg.endScanRspParams, + pEventData->pEventData, + sizeof(halEndScanRspMsg.endScanRspParams)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halEndScanRspMsg.endScanRspParams.status); + + if ( eHAL_STATUS_SUCCESS != halEndScanRspMsg.endScanRspParams.status ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "End Scan failed with status %s (%d )", + WDI_getHALStatusMsgString(halEndScanRspMsg.endScanRspParams.status), + halEndScanRspMsg.endScanRspParams.status); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiEndScanRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessEndScanRsp*/ + + +/** + @brief Process Finish Scan Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFinishScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + WDI_FinishScanRspCb wdiFinishScanRspCb; + + tHalFinishScanRspMsg halFinishScanRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiFinishScanRspCb = (WDI_FinishScanRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( (void *)&halFinishScanRspMsg.finishScanRspParams.status, + pEventData->pEventData, + sizeof(halFinishScanRspMsg.finishScanRspParams.status)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halFinishScanRspMsg.finishScanRspParams.status); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + "Finish scan response reported status: %d", + halFinishScanRspMsg.finishScanRspParams.status); + + if (( eHAL_STATUS_SUCCESS != halFinishScanRspMsg.finishScanRspParams.status )&& + ( eHAL_STATUS_NOTIFY_BSS_FAIL != halFinishScanRspMsg.finishScanRspParams.status )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Finish Scan failed with status %s (%d)", + WDI_getHALStatusMsgString(halFinishScanRspMsg.finishScanRspParams.status), + halFinishScanRspMsg.finishScanRspParams.status); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiFinishScanRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessFinishScanRsp*/ + +/** + @brief Process Join Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessJoinRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + WDI_JoinRspCb wdiJoinRspCb; + WDI_BSSSessionType* pBSSSes = NULL; + + tHalJoinRspMsg halJoinRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || + ( NULL == pWDICtx->pfncRspCB ) || + ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiJoinRspCb = (WDI_JoinRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halJoinRspMsg.joinRspParams, + pEventData->pEventData, + sizeof(halJoinRspMsg.joinRspParams)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halJoinRspMsg.joinRspParams.status); + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Join response can only be received for an existing assoc that + is current and in progress + -----------------------------------------------------------------------*/ + if (( !WDI_VALID_SESSION_IDX(pWDICtx->ucCurrentBSSSesIdx )) || + ( eWLAN_PAL_FALSE == pWDICtx->bAssociationInProgress )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist (bssIdx %d) or " + "association no longer in progress %d - mysterious HAL response", + __func__, pWDICtx->ucCurrentBSSSesIdx, pWDICtx->bAssociationInProgress); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + pBSSSes = &pWDICtx->aBSSSessions[pWDICtx->ucCurrentBSSSesIdx]; + + /*----------------------------------------------------------------------- + Join Response is only allowed in init state + -----------------------------------------------------------------------*/ + if ( WDI_ASSOC_JOINING_ST != pBSSSes->wdiAssocState) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Join only allowed in Joining state - failure state is %d " + "strange HAL response", pBSSSes->wdiAssocState); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + + /*----------------------------------------------------------------------- + If assoc has failed the current session will be deleted + -----------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != wdiStatus ) + { + /*Association was failed by HAL - remove session*/ + WDI_DeleteSession(pWDICtx, pBSSSes); + + /*Association no longer in progress */ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + + /*Association no longer in progress - prepare pending assoc for processing*/ + WDI_DequeueAssocRequest(pWDICtx); + + } + else + { + /*Transition to state Joining - this may be redundant as we are supposed + to be in this state already - but just to be safe*/ + pBSSSes->wdiAssocState = WDI_ASSOC_JOINING_ST; + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Notify UMAC*/ + wdiJoinRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessJoinRsp*/ + + +/** + @brief Process Config BSS Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigBSSRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ConfigBSSRspParamsType wdiConfigBSSParams; + WDI_ConfigBSSRspCb wdiConfigBSSRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + tConfigBssRspMsg halConfigBssRspMsg; + WDI_AddStaParams wdiBcastAddSTAParam = {0}; + WDI_AddStaParams wdiAddSTAParam = {0}; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiConfigBSSRspCb = (WDI_ConfigBSSRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halConfigBssRspMsg.configBssRspParams, + pEventData->pEventData, + sizeof(halConfigBssRspMsg.configBssRspParams)); + + wdiConfigBSSParams.wdiStatus = WDI_HAL_2_WDI_STATUS( + halConfigBssRspMsg.configBssRspParams.status); + if(WDI_STATUS_SUCCESS == wdiConfigBSSParams.wdiStatus) + { + wpalMemoryCopy( wdiConfigBSSParams.macBSSID, + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.macBSSID, + WDI_MAC_ADDR_LEN); + + wdiConfigBSSParams.ucBSSIdx = halConfigBssRspMsg.configBssRspParams.bssIdx; + + wdiConfigBSSParams.ucBcastSig = + halConfigBssRspMsg.configBssRspParams.bcastDpuSignature; + + wdiConfigBSSParams.ucUcastSig = + halConfigBssRspMsg.configBssRspParams.ucastDpuSignature; + + wdiConfigBSSParams.ucSTAIdx = halConfigBssRspMsg.configBssRspParams.bssStaIdx; + + #ifdef WLAN_FEATURE_VOWIFI + wdiConfigBSSParams.ucTxMgmtPower = + halConfigBssRspMsg.configBssRspParams.txMgmtPower; + #endif + wpalMemoryCopy( wdiConfigBSSParams.macSTA, + halConfigBssRspMsg.configBssRspParams.staMac, + WDI_MAC_ADDR_LEN ); + + wpalMutexAcquire(&pWDICtx->wptMutex); + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + wdiConfigBSSParams.macBSSID, + &pBSSSes); + + /*----------------------------------------------------------------------- + Config BSS response can only be received for an existing assoc that + is current and in progress + -----------------------------------------------------------------------*/ + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association sequence for this BSS does not yet exist " + "- mysterious HAL response"); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*Save data for this BSS*/ + pBSSSes->wdiBssType = pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiBSSType; + pBSSSes->ucBSSIdx = halConfigBssRspMsg.configBssRspParams.bssIdx; + pBSSSes->bcastDpuIndex = + halConfigBssRspMsg.configBssRspParams.bcastDpuDescIndx; + pBSSSes->bcastDpuSignature = + halConfigBssRspMsg.configBssRspParams.bcastDpuSignature; + pBSSSes->bcastMgmtDpuIndex = + halConfigBssRspMsg.configBssRspParams.mgmtDpuDescIndx; + pBSSSes->bcastMgmtDpuSignature = + halConfigBssRspMsg.configBssRspParams.mgmtDpuSignature; + pBSSSes->ucRmfEnabled = + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.ucRMFEnabled; + pBSSSes->bcastStaIdx = + halConfigBssRspMsg.configBssRspParams.bssBcastStaIdx; + + /* !TO DO: Shuould we be updating the RMF Capability of self STA here? */ + + /*------------------------------------------------------------------------- + Add Peer STA + -------------------------------------------------------------------------*/ + wdiAddSTAParam.ucSTAIdx = halConfigBssRspMsg.configBssRspParams.bssStaIdx; + wdiAddSTAParam.dpuIndex = halConfigBssRspMsg.configBssRspParams.dpuDescIndx; + wdiAddSTAParam.dpuSig = halConfigBssRspMsg.configBssRspParams.ucastDpuSignature; + + /*This info can be retrieved from the cached initial request*/ + wdiAddSTAParam.ucWmmEnabled = + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.ucWMMEnabled; + wdiAddSTAParam.ucHTCapable = + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.ucHTCapable; + wdiAddSTAParam.ucStaType = + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.wdiSTAType; + + /* MAC Address of STA */ + wpalMemoryCopy(wdiAddSTAParam.staMacAddr, + halConfigBssRspMsg.configBssRspParams.staMac, + WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(wdiAddSTAParam.macBSSID, + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.wdiSTAContext.macBSSID , + WDI_MAC_ADDR_LEN); + + /*Add BSS specific parameters*/ + wdiAddSTAParam.bcastMgmtDpuIndex = + halConfigBssRspMsg.configBssRspParams.mgmtDpuDescIndx; + wdiAddSTAParam.bcastMgmtDpuSignature = + halConfigBssRspMsg.configBssRspParams.mgmtDpuSignature; + wdiAddSTAParam.bcastDpuIndex = + halConfigBssRspMsg.configBssRspParams.bcastDpuDescIndx; + wdiAddSTAParam.bcastDpuSignature = + halConfigBssRspMsg.configBssRspParams.bcastDpuSignature; + wdiAddSTAParam.ucRmfEnabled = + pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.ucRMFEnabled; + wdiAddSTAParam.ucBSSIdx = + halConfigBssRspMsg.configBssRspParams.bssIdx; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Add STA to the table index: %d", wdiAddSTAParam.ucSTAIdx ); + + WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam); + /*------------------------------------------------------------------------- + Add Broadcast STA only in AP mode + -------------------------------------------------------------------------*/ + if( pWDICtx->wdiCachedConfigBssReq.wdiReqInfo.ucOperMode == + WDI_BSS_OPERATIONAL_MODE_AP || pBSSSes->wdiBssType == WDI_IBSS_MODE) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Add BCAST STA to table for index: %d", + halConfigBssRspMsg.configBssRspParams.bssBcastStaIdx ); + + wpalMemoryCopy( &wdiBcastAddSTAParam, &wdiAddSTAParam, + sizeof(WDI_AddStaParams) ); + + WDI_AddBcastSTAtoSTATable( pWDICtx, &wdiBcastAddSTAParam, + halConfigBssRspMsg.configBssRspParams.bssBcastStaIdx ); + } + wpalMutexRelease(&pWDICtx->wptMutex); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Config BSS RSP failed with status : %s(%d)", + WDI_getHALStatusMsgString( + halConfigBssRspMsg.configBssRspParams.status), + halConfigBssRspMsg.configBssRspParams.status); + + + /*Association was failed by HAL - remove session*/ + WDI_DeleteSession(pWDICtx, pBSSSes); + + /*Association no longer in progress */ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + + /*Association no longer in progress - prepare pending assoc for processing*/ + WDI_DequeueAssocRequest(pWDICtx); + + } + + /*Notify UMAC*/ + wdiConfigBSSRspCb( &wdiConfigBSSParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessConfigBSSRsp*/ + + +/** + @brief Process Del BSS Response function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBSSRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelBSSRspParamsType wdiDelBSSParams; + WDI_DelBSSRspCb wdiDelBSSRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + tDeleteBssRspMsg halDelBssRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiDelBSSRspCb = (WDI_DelBSSRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halDelBssRspMsg.deleteBssRspParams, + pEventData->pEventData, + sizeof(halDelBssRspMsg.deleteBssRspParams)); + + + wdiDelBSSParams.wdiStatus = WDI_HAL_2_WDI_STATUS( + halDelBssRspMsg.deleteBssRspParams.status); + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx, + halDelBssRspMsg.deleteBssRspParams.bssIdx, + &pBSSSes); + + /*----------------------------------------------------------------------- + Del BSS response can only be received for an existing assoc that + is current and in progress + -----------------------------------------------------------------------*/ + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association sequence for this BSS does not yet exist or " + "association no longer in progress - mysterious HAL response"); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*Extract BSSID for the response to UMAC*/ + wpalMemoryCopy(wdiDelBSSParams.macBSSID, + pBSSSes->macBSSID, WDI_MAC_ADDR_LEN); + + wdiDelBSSParams.ucBssIdx = halDelBssRspMsg.deleteBssRspParams.bssIdx; + + /*----------------------------------------------------------------------- + The current session will be deleted + -----------------------------------------------------------------------*/ + WDI_DeleteSession(pWDICtx, pBSSSes); + + + /* Delete the BCAST STA entry from the STA table if SAP/GO session is deleted */ + if(WDI_INFRA_AP_MODE == pBSSSes->wdiBssType || + pBSSSes->wdiBssType == WDI_IBSS_MODE) + { + (void)WDI_STATableDelSta( pWDICtx, pBSSSes->bcastStaIdx ); + } + + /* Delete the STA's in this BSS */ + WDI_STATableBSSDelSta(pWDICtx, halDelBssRspMsg.deleteBssRspParams.bssIdx); + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Notify UMAC*/ + wdiDelBSSRspCb( &wdiDelBSSParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessDelBSSRsp*/ + +/** + @brief Process Post Assoc Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPostAssocRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_PostAssocRspParamsType wdiPostAssocParams; + WDI_PostAssocRspCb wdiPostAssocRspCb; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + tPostAssocRspMsg halPostAssocRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiPostAssocRspCb = (WDI_PostAssocRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halPostAssocRspMsg.postAssocRspParams, + pEventData->pEventData, + sizeof(halPostAssocRspMsg.postAssocRspParams)); + + /*Extract the Post Assoc STA Params */ + + wdiPostAssocParams.staParams.ucSTAIdx = + halPostAssocRspMsg.postAssocRspParams.configStaRspParams.staIdx; + wdiPostAssocParams.staParams.ucUcastSig = + halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucUcastSig; + wdiPostAssocParams.staParams.ucBcastSig = + halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucBcastSig; + + wdiPostAssocParams.wdiStatus = + WDI_HAL_2_WDI_STATUS(halPostAssocRspMsg.postAssocRspParams.configStaRspParams.status); + + /*Copy the MAC addresses from the cached storage in the WDI CB as they are not + included in the response */ + wpalMemoryCopy( wdiPostAssocParams.staParams.macSTA, + pWDICtx->wdiCachedPostAssocReq.wdiSTAParams.macSTA, + WDI_MAC_ADDR_LEN); + + /* Extract Post Assoc BSS Params */ + + wpalMemoryCopy( wdiPostAssocParams.bssParams.macBSSID, + pWDICtx->wdiCachedPostAssocReq.wdiBSSParams.macBSSID, + WDI_MAC_ADDR_LEN); + + /*Copy the MAC addresses from the cached storage in the WDI CB as they are not + included in the response */ + wpalMemoryCopy( wdiPostAssocParams.bssParams.macSTA, + pWDICtx->wdiCachedPostAssocReq.wdiBSSParams.wdiSTAContext + .macSTA, WDI_MAC_ADDR_LEN); + + wdiPostAssocParams.bssParams.ucBcastSig = + halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucBcastSig; + + wdiPostAssocParams.bssParams.ucUcastSig = + halPostAssocRspMsg.postAssocRspParams.configStaRspParams.ucUcastSig; + + wdiPostAssocParams.bssParams.ucBSSIdx = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bssIdx; + + wdiPostAssocParams.bssParams.ucSTAIdx = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bssStaIdx; + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + wdiPostAssocParams.bssParams. + macBSSID, &pBSSSes); + + /*----------------------------------------------------------------------- + Post assoc response can only be received for an existing assoc that + is current and in progress + -----------------------------------------------------------------------*/ + if (( NULL == pBSSSes ) || + ( ucCurrentBSSSesIdx != pWDICtx->ucCurrentBSSSesIdx ) || + ( eWLAN_PAL_FALSE == pWDICtx->bAssociationInProgress )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association sequence for this BSS does not yet exist or " + "association no longer in progress - mysterious HAL response"); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*----------------------------------------------------------------------- + Post Assoc Request is only allowed in Joining state + -----------------------------------------------------------------------*/ + if ( WDI_ASSOC_JOINING_ST != pBSSSes->wdiAssocState) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Post Assoc not allowed before JOIN - failing request " + "strange HAL response"); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*----------------------------------------------------------------------- + If assoc has failed the current session will be deleted + -----------------------------------------------------------------------*/ + if ( WDI_STATUS_SUCCESS != wdiPostAssocParams.wdiStatus ) + { + /*Association was failed by HAL - remove session*/ + WDI_DeleteSession(pWDICtx, pBSSSes); + } + else + { + /*Transition to state POST Assoc*/ + pBSSSes->wdiAssocState = WDI_ASSOC_POST_ST; + + /*Save DPU Info*/ + pBSSSes->bcastMgmtDpuIndex = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.mgmtDpuDescIndx; + pBSSSes->bcastMgmtDpuSignature = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.mgmtDpuSignature; + pBSSSes->bcastDpuIndex = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bcastDpuDescIndx; + pBSSSes->bcastDpuSignature = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bcastDpuSignature; + + pBSSSes->ucBSSIdx = + halPostAssocRspMsg.postAssocRspParams.configBssRspParams.bssIdx; + } + + /*Association no longer in progress */ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + + /*Association no longer in progress - prepare pending assoc for processing*/ + WDI_DequeueAssocRequest(pWDICtx); + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Notify UMAC*/ + wdiPostAssocRspCb( &wdiPostAssocParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessPostAssocRsp*/ + +/** + @brief Process Del STA Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelSTARspParamsType wdiDelSTARsp; + WDI_DelSTARspCb wdiDelSTARspCb; + wpt_uint8 staType; + tDeleteStaRspMsg halDelStaRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiDelSTARspCb = (WDI_DelSTARspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halDelStaRspMsg.delStaRspParams, + pEventData->pEventData, + sizeof(halDelStaRspMsg.delStaRspParams)); + + wdiDelSTARsp.ucSTAIdx = halDelStaRspMsg.delStaRspParams.staId; + wdiDelSTARsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halDelStaRspMsg.delStaRspParams.status); + + WDI_STATableGetStaType(pWDICtx, wdiDelSTARsp.ucSTAIdx, &staType); + + /* If the DEL STA request is for self STA do not delete it - Really weird!!What happens in concurrency */ + if(staType == WDI_STA_ENTRY_SELF) + { + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + + /* At this point add the self-STA */ + + /*! TO DO: wdiAddSTAParam.ucWmmEnabled */ + /*! TO DO: wdiAddSTAParam.ucHTCapable */ + /*! TO DO: wdiAddSTAParam.ucRmfEnabled */ + +#define WDI_DPU_SELF_STA_DEFAULT_IDX 0 +#define WDI_DPU_SELF_STA_DEFAULT_SIG 0 + + //all DPU indices are the same for self STA + pSTATable[wdiDelSTARsp.ucSTAIdx].dpuIndex = WDI_DPU_SELF_STA_DEFAULT_IDX; + pSTATable[wdiDelSTARsp.ucSTAIdx].bcastDpuIndex = WDI_DPU_SELF_STA_DEFAULT_IDX; + pSTATable[wdiDelSTARsp.ucSTAIdx].bcastMgmtDpuIndex = WDI_DPU_SELF_STA_DEFAULT_IDX; + pSTATable[wdiDelSTARsp.ucSTAIdx].bcastDpuSignature = WDI_DPU_SELF_STA_DEFAULT_SIG; + pSTATable[wdiDelSTARsp.ucSTAIdx].bcastMgmtDpuSignature = WDI_DPU_SELF_STA_DEFAULT_SIG; + pSTATable[wdiDelSTARsp.ucSTAIdx].dpuSig = WDI_DPU_SELF_STA_DEFAULT_SIG; + + pSTATable[wdiDelSTARsp.ucSTAIdx].bssIdx = WDI_BSS_INVALID_IDX; + } + else + { + //Delete the station in the table + WDI_STATableDelSta( pWDICtx, wdiDelSTARsp.ucSTAIdx); + } + + /*Notify UMAC*/ + wdiDelSTARspCb( &wdiDelSTARsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessDelSTARsp*/ + + +/*========================================================================== + Security Response Processing Functions +==========================================================================*/ + +/** + @brief Process Set BSS Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBssKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetBSSKeyRspCb wdiSetBSSKeyRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetBSSKeyRspCb = (WDI_SetBSSKeyRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS != halStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Set BSS Key failed with status %s (%d)", + WDI_getHALStatusMsgString(halStatus), + halStatus); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiSetBSSKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetBssKeyRsp*/ + +/** + @brief Process Remove BSS Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveBssKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_RemoveBSSKeyRspCb wdiRemoveBSSKeyRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRemoveBSSKeyRspCb = (WDI_RemoveBSSKeyRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS != halStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Remove BSS Key failed with status %s (%d )", + WDI_getHALStatusMsgString(halStatus), + halStatus); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiRemoveBSSKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetBssKeyRsp*/ + + +/** + @brief Process Set STA Key Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetSTAKeyRspCb wdiSetSTAKeyRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetSTAKeyRspCb = (WDI_SetSTAKeyRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS != halStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Set STA Key failed with status %s (%d)", + WDI_getHALStatusMsgString(halStatus), + halStatus); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiSetSTAKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetSTAKeyRsp*/ + +/** + @brief Process Remove STA Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_RemoveSTAKeyRspCb wdiRemoveSTAKeyRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRemoveSTAKeyRspCb = (WDI_RemoveSTAKeyRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS != halStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Remove STA Key failed with status %s (%d)", + WDI_getHALStatusMsgString(halStatus), + halStatus); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiRemoveSTAKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessRemoveStaKeyRsp*/ + +/** + @brief Process Set STA Bcast Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetStaBcastKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetSTAKeyRspCb wdiSetSTABcastKeyRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetSTABcastKeyRspCb = (WDI_SetSTAKeyRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS != halStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Set STA Key failed with status %s (%d)", + WDI_getHALStatusMsgString(halStatus), + halStatus); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiSetSTABcastKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetSTABcastKeyRsp*/ + +/** + @brief Process Remove STA Bcast Key Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemoveStaBcastKeyRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_RemoveSTAKeyRspCb wdiRemoveSTABcastKeyRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRemoveSTABcastKeyRspCb = (WDI_RemoveSTAKeyRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS != halStatus ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Remove STA Key failed with status %s (%d)", + WDI_getHALStatusMsgString(halStatus), + halStatus); + /* send the status to UMAC, don't return from here*/ + } + + /*Notify UMAC*/ + wdiRemoveSTABcastKeyRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessRemoveStaBcastKeyRsp*/ + + +/*========================================================================== + QoS and BA Response Processing Functions +==========================================================================*/ + +/** + @brief Process Add TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_AddTsRspCb wdiAddTsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiAddTsRspCb = (WDI_AddTsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiAddTsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessAddTSpecRsp*/ + + + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +WDI_Status +WDI_ProcessLLStatsSetRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LLStatsSetRspCb wdiLLStatsSetRspCb; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiLLStatsSetRspCb = (WDI_LLStatsSetRspCb)pWDICtx->pfncRspCB; + + wdiLLStatsSetRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_ProcessLLStatsGetRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LLStatsGetRspCb wdiLLStatsGetRspCb; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + + wdiLLStatsGetRspCb = (WDI_LLStatsGetRspCb)pWDICtx->pfncRspCB; + + wdiLLStatsGetRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_ProcessLLStatsClearRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LLStatsClearRspCb wdiLLStatsClearRspCb; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: CLEAR RESPONSE CALL BACK", __func__); + wdiLLStatsClearRspCb = (WDI_LLStatsClearRspCb)pWDICtx->pfncRspCB; + + wdiLLStatsClearRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/** + @brief Process Del TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_DelTsRspCb wdiDelTsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiDelTsRspCb = (WDI_DelTsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiDelTsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessDelTSpecRsp*/ + +/** + @brief Process Update EDCA Parameters Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateEDCAParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_UpdateEDCAParamsRspCb wdiUpdateEDCAParamsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiUpdateEDCAParamsRspCb = (WDI_UpdateEDCAParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiUpdateEDCAParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUpdateEDCAParamsRsp*/ + + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBASessionRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddBASessionRspCb wdiAddBASessionRspCb; + + tAddBASessionRspParams halBASessionRsp; + WDI_AddBASessionRspParamsType wdiBASessionRsp; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiAddBASessionRspCb = (WDI_AddBASessionRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halBASessionRsp, + pEventData->pEventData, + sizeof(halBASessionRsp)); + + wdiBASessionRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halBASessionRsp.status); + + if ( WDI_STATUS_SUCCESS == wdiBASessionRsp.wdiStatus ) + { + wdiBASessionRsp.ucBaDialogToken = halBASessionRsp.baDialogToken; + wdiBASessionRsp.ucBaTID = halBASessionRsp.baTID; + wdiBASessionRsp.ucBaBufferSize = halBASessionRsp.baBufferSize; + wdiBASessionRsp.usBaSessionID = halBASessionRsp.baSessionID; + wdiBASessionRsp.ucWinSize = halBASessionRsp.winSize; + wdiBASessionRsp.ucSTAIdx = halBASessionRsp.STAID; + wdiBASessionRsp.usBaSSN = halBASessionRsp.SSN; + } + + /*Notify UMAC*/ + wdiAddBASessionRspCb( &wdiBASessionRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessAddSessionBARsp*/ + + +/** + @brief Process Del BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_DelBARspCb wdiDelBARspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiDelBARspCb = (WDI_DelBARspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if ( eHAL_STATUS_SUCCESS == halStatus ) + { + /*! TO DO: I should notify the DAL Data Path that the BA was deleted*/ + } + + /*Notify UMAC*/ + wdiDelBARspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessDelBARsp*/ + +#ifdef FEATURE_WLAN_ESE +/** + @brief Process TSM Stats Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTsmStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_TsmRspCb wdiTsmStatsRspCb; + tTsmStatsRspMsg halTsmStatsRspMsg; + WDI_TSMStatsRspParamsType wdiTsmStatsRspParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiTsmStatsRspCb = (WDI_TsmRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Unpack HAL Response Message - the header was already extracted by the + main Response Handling procedure + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTsmStatsRspMsg.tsmStatsRspParams, + pEventData->pEventData, + sizeof(halTsmStatsRspMsg.tsmStatsRspParams)); + + wdiTsmStatsRspParams.UplinkPktQueueDly = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDly; + wpalMemoryCopy( wdiTsmStatsRspParams.UplinkPktQueueDlyHist, + halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDlyHist, + sizeof(halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDlyHist)/ + sizeof(halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktQueueDlyHist[0])); + wdiTsmStatsRspParams.UplinkPktTxDly = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktTxDly; + wdiTsmStatsRspParams.UplinkPktLoss = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktLoss; + wdiTsmStatsRspParams.UplinkPktCount = halTsmStatsRspMsg.tsmStatsRspParams.UplinkPktCount; + wdiTsmStatsRspParams.RoamingCount = halTsmStatsRspMsg.tsmStatsRspParams.RoamingCount; + wdiTsmStatsRspParams.RoamingDly = halTsmStatsRspMsg.tsmStatsRspParams.RoamingDly; + wdiTsmStatsRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS( + halTsmStatsRspMsg.tsmStatsRspParams.status); + + /*Notify UMAC*/ + wdiTsmStatsRspCb( &wdiTsmStatsRspParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessTsmStatsRsp*/ + +#endif + + + +/** + @brief Process Flush AC Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFlushAcRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_FlushAcRspCb wdiFlushAcRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiFlushAcRspCb = (WDI_FlushAcRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiFlushAcRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessFlushAcRsp*/ + +/** + @brief Process BT AMP event Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBtAmpEventRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_BtAmpEventRspCb wdiBtAmpEventRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiBtAmpEventRspCb = (WDI_BtAmpEventRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiBtAmpEventRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessBtAmpEventRsp*/ + + +/** + @brief Process ADD STA SELF Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddSTASelfRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddSTASelfRspParamsType wdiAddSTASelfParams; + WDI_AddSTASelfParamsRspCb wdiAddSTASelfReqParamsRspCb; + tAddStaSelfRspMsg halAddStaSelfRsp; + WDI_AddStaParams wdiAddSTAParam = {0}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiAddSTASelfReqParamsRspCb = + (WDI_AddSTASelfParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halAddStaSelfRsp.addStaSelfRspParams, + pEventData->pEventData, + sizeof(halAddStaSelfRsp.addStaSelfRspParams)); + + + wdiAddSTASelfParams.wdiStatus = + WDI_HAL_2_WDI_STATUS(halAddStaSelfRsp.addStaSelfRspParams.status); + + wdiAddSTASelfParams.ucSTASelfIdx = + halAddStaSelfRsp.addStaSelfRspParams.selfStaIdx; + wdiAddSTASelfParams.dpuIdx = + halAddStaSelfRsp.addStaSelfRspParams.dpuIdx; + wdiAddSTASelfParams.dpuSignature = + halAddStaSelfRsp.addStaSelfRspParams.dpuSignature; + + wpalMemoryCopy(wdiAddSTASelfParams.macSelfSta, + pWDICtx->wdiCacheAddSTASelfReq.wdiAddSTASelfInfo.selfMacAddr, + WDI_MAC_ADDR_LEN); + + +#ifdef HAL_SELF_STA_PER_BSS + + /* At this point add the self-STA */ + + /*! TO DO: wdiAddSTAParam.ucWmmEnabled */ + /*! TO DO: wdiAddSTAParam.ucHTCapable */ + /*! TO DO: wdiAddSTAParam.ucRmfEnabled */ + + //all DPU indices are the same for self STA + + /*DPU Information*/ + wdiAddSTAParam.dpuIndex = wdiAddSTASelfParams.dpuIdx; + wdiAddSTAParam.dpuSig = wdiAddSTASelfParams.dpuSignature; + wdiAddSTAParam.bcastDpuSignature = wdiAddSTASelfParams.dpuSignature; + wdiAddSTAParam.bcastMgmtDpuSignature = wdiAddSTASelfParams.dpuSignature; + wdiAddSTAParam.bcastDpuIndex = wdiAddSTASelfParams.dpuIdx; + wdiAddSTAParam.bcastMgmtDpuIndex = wdiAddSTASelfParams.dpuIdx; + + wpalMemoryCopy(wdiAddSTAParam.staMacAddr, wdiAddSTASelfParams.macSelfSta, + WDI_MAC_ADDR_LEN); + + wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_SELF; /* 0 - self */ + wdiAddSTAParam.ucSTAIdx = wdiAddSTASelfParams.ucSTASelfIdx; + + if(halAddStaSelfRsp.addStaSelfRspParams.status + != eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO) + { + (void)WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam); + } +#endif + + /*Notify UMAC*/ + wdiAddSTASelfReqParamsRspCb( &wdiAddSTASelfParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessAddSTASelfRsp*/ + + + +/** + @brief WDI_ProcessDelSTASelfRsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTASelfRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_DelSTASelfRspParamsType wdiDelStaSelfRspParams; + WDI_DelSTASelfRspCb wdiDelStaSelfRspCb; + tDelStaSelfRspParams delStaSelfRspParams; + wpt_uint8 ucStaIdx; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiDelStaSelfRspCb = (WDI_DelSTASelfRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + + wpalMemoryCopy( &delStaSelfRspParams, + (wpt_uint8*)pEventData->pEventData, + sizeof(tDelStaSelfRspParams)); + + wdiDelStaSelfRspParams.wdiStatus = + WDI_HAL_2_WDI_STATUS(delStaSelfRspParams.status); + + /* delStaSelfRspParams.status is not + eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO*/ + if( eHAL_STATUS_SUCCESS == delStaSelfRspParams.status ) + { + WDI_Status wdiStatus; + wdiStatus = WDI_STATableFindStaidByAddr(pWDICtx, + delStaSelfRspParams.selfMacAddr, + &ucStaIdx); + if(WDI_STATUS_E_FAILURE == wdiStatus) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Unable to extract the STA Idx ", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + WDI_STATableDelSta(pWDICtx, ucStaIdx); + } + + /*Notify UMAC*/ + wdiDelStaSelfRspCb(&wdiDelStaSelfRspParams, (void*) pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +#ifdef FEATURE_OEM_DATA_SUPPORT +/** + @brief Start Oem Data Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_ProcessStartOemDataRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_oemDataRspCb wdiOemDataRspCb; + WDI_oemDataRspParamsType* wdiOemDataRspParams; + tStartOemDataRspParams* halStartOemDataRspParams; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiOemDataRspCb = (WDI_oemDataRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStartOemDataRspParams = (tStartOemDataRspParams *)pEventData->pEventData; + + + //It is the responsibility of the application code to check for failure + //conditions! + + //Allocate memory for WDI OEM DATA RSP structure + wdiOemDataRspParams = wpalMemoryAllocate(sizeof(WDI_oemDataRspParamsType)) ; + + if(NULL == wdiOemDataRspParams) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Failed to allocate memory in OEM DATA Response %p %p %p ", + pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(wdiOemDataRspParams->oemDataRsp, OEM_DATA_RSP_SIZE); + + /* Populate WDI structure members */ + wpalMemoryCopy(wdiOemDataRspParams->oemDataRsp, + halStartOemDataRspParams->oemDataRsp, + pEventData->uEventDataSize); + + /*Notify UMAC*/ + wdiOemDataRspCb(wdiOemDataRspParams, pWDICtx->pRspCBUserData); + + //Free memory allocated for WDI OEM_DATA MEAS RSP structure + wpalMemoryFree(wdiOemDataRspParams); + + return WDI_STATUS_SUCCESS; +}/*WDI_PrcoessStartOemDataRsp*/ +#endif + +/*=========================================================================== + Miscellaneous Control Response Processing API +===========================================================================*/ + +/** + @brief Process Channel Switch Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChannelSwitchRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SwitchCHRspParamsType wdiSwitchChRsp; + WDI_SwitchChRspCb wdiChSwitchRspCb; + tSwitchChannelRspParams halSwitchChannelRsp; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiChSwitchRspCb = (WDI_SwitchChRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halSwitchChannelRsp, + (wpt_uint8*)pEventData->pEventData, + sizeof(halSwitchChannelRsp)); + + wdiSwitchChRsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halSwitchChannelRsp.status); + wdiSwitchChRsp.ucChannel = halSwitchChannelRsp.channelNumber; + +#ifdef WLAN_FEATURE_VOWIFI + wdiSwitchChRsp.ucTxMgmtPower = halSwitchChannelRsp.txMgmtPower; +#endif + + /*Notify UMAC*/ + wdiChSwitchRspCb( &wdiSwitchChRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessChannelSwitchRsp*/ + +/** + @brief Process Channel Switch Rsp function (called when a response + is being received over the bus from HAL against + WDI_ProcessChannelSwitchReq_V1) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_ProcessChannelSwitchRsp_V1 +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SwitchChRspParamsType_V1 wdiSwitchChRsp; + WDI_SwitchChRspCb_V1 wdiChSwitchRspCb; + tSwitchChannelRspParams_V1 halSwitchChannelRsp; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiChSwitchRspCb = (WDI_SwitchChRspCb_V1)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halSwitchChannelRsp, + (wpt_uint8*)pEventData->pEventData, + sizeof(halSwitchChannelRsp)); + + wdiSwitchChRsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halSwitchChannelRsp.status); + wdiSwitchChRsp.ucChannel = halSwitchChannelRsp.channelNumber; + +#ifdef WLAN_FEATURE_VOWIFI + wdiSwitchChRsp.ucTxMgmtPower = halSwitchChannelRsp.txMgmtPower; +#endif + + wdiSwitchChRsp.channelSwitchSrc = halSwitchChannelRsp.channelSwitchSrc; + if (( NULL == wdiChSwitchRspCb ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: ### Call back function is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /*Notify UMAC*/ + wdiChSwitchRspCb( &wdiSwitchChRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessChannelSwitchRsp_V1*/ + +/** + @brief Process Config STA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigStaRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_ConfigSTARspParamsType wdiCfgSTAParams; + WDI_ConfigSTARspCb wdiConfigSTARspCb; + WDI_AddStaParams wdiAddSTAParam; + + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8 ucCurrentBSSSesIdx = 0; + + tConfigStaRspMsg halConfigStaRsp; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiConfigSTARspCb = (WDI_ConfigSTARspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halConfigStaRsp.configStaRspParams, + pEventData->pEventData, + sizeof(halConfigStaRsp.configStaRspParams)); + + + wdiCfgSTAParams.ucSTAIdx = halConfigStaRsp.configStaRspParams.staIdx; + wdiCfgSTAParams.ucBssIdx = halConfigStaRsp.configStaRspParams.bssIdx; + wdiCfgSTAParams.ucUcastSig = halConfigStaRsp.configStaRspParams.ucUcastSig; + wdiCfgSTAParams.ucBcastSig = halConfigStaRsp.configStaRspParams.ucBcastSig; + wdiCfgSTAParams.ucMgmtSig = halConfigStaRsp.configStaRspParams.ucMgmtSig; + + /* MAC Address of STA - take from cache as it does not come back in the + response*/ + wpalMemoryCopy( wdiCfgSTAParams.macSTA, + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macSTA, + WDI_MAC_ADDR_LEN); + + wdiCfgSTAParams.wdiStatus = + WDI_HAL_2_WDI_STATUS(halConfigStaRsp.configStaRspParams.status); + + wdiCfgSTAParams.ucDpuIndex = halConfigStaRsp.configStaRspParams.dpuIndex; + wdiCfgSTAParams.ucBcastDpuIndex = halConfigStaRsp.configStaRspParams.bcastDpuIndex; + wdiCfgSTAParams.ucBcastMgmtDpuIdx = halConfigStaRsp.configStaRspParams.bcastMgmtDpuIdx; + + if ( WDI_STATUS_SUCCESS == wdiCfgSTAParams.wdiStatus ) + { + if ( WDI_ADD_STA == pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.wdiAction ) + { + /* ADD STA to table */ + wdiAddSTAParam.ucSTAIdx = halConfigStaRsp.configStaRspParams.staIdx; + wdiAddSTAParam.dpuSig = halConfigStaRsp.configStaRspParams.ucUcastSig; + wdiAddSTAParam.dpuIndex = halConfigStaRsp.configStaRspParams.dpuIndex; + + /*This info can be retrieved from the cached initial request*/ + wdiAddSTAParam.ucWmmEnabled = + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.ucWMMEnabled; + wdiAddSTAParam.ucHTCapable = + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.ucHTCapable; + wdiAddSTAParam.ucStaType = + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.wdiSTAType; + wdiAddSTAParam.ucRmfEnabled = + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.ucRMFEnabled; + + /* MAC Address of STA */ + wpalMemoryCopy(wdiAddSTAParam.staMacAddr, + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macSTA, + WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(wdiAddSTAParam.macBSSID, + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macBSSID , + WDI_MAC_ADDR_LEN); + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.macBSSID, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association for this BSSID is not in place"); + + WDI_ASSERT(0); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*Add BSS specific parameters*/ + wdiAddSTAParam.bcastMgmtDpuIndex = + halConfigStaRsp.configStaRspParams.bcastMgmtDpuIdx; + wdiAddSTAParam.bcastMgmtDpuSignature = + halConfigStaRsp.configStaRspParams.ucMgmtSig; + wdiAddSTAParam.bcastDpuIndex = + halConfigStaRsp.configStaRspParams.bcastDpuIndex; + wdiAddSTAParam.bcastDpuSignature = + halConfigStaRsp.configStaRspParams.ucBcastSig; + wdiAddSTAParam.ucBSSIdx = ucCurrentBSSSesIdx; + + WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam); + } + if( WDI_UPDATE_STA == pWDICtx->wdiCachedConfigStaReq.wdiReqInfo.wdiAction ) + { + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastDpuIndex = + halConfigStaRsp.configStaRspParams.bcastDpuIndex; + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastDpuSignature = + halConfigStaRsp.configStaRspParams.ucBcastSig; + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastMgmtDpuIndex = + halConfigStaRsp.configStaRspParams.bcastMgmtDpuIdx; + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bcastMgmtDpuSignature = + halConfigStaRsp.configStaRspParams.ucMgmtSig; + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].bssIdx = + halConfigStaRsp.configStaRspParams.bssIdx; + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].dpuIndex = + halConfigStaRsp.configStaRspParams.dpuIndex; + pSTATable[halConfigStaRsp.configStaRspParams.staIdx].dpuSig = + halConfigStaRsp.configStaRspParams.ucUcastSig; + } + } + + /*Notify UMAC*/ + wdiConfigSTARspCb( &wdiCfgSTAParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessConfigStaRsp*/ + + +/** + @brief Process Set Link State Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetLinkStateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetLinkStateRspCb wdiSetLinkStateRspCb; + + WDI_BSSSessionType* pBSSSes = NULL; + wpt_uint8 ucCurrentBSSSesIdx = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetLinkStateRspCb = (WDI_SetLinkStateRspCb)pWDICtx->pfncRspCB; + + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*If the link is being transitioned to idle - the BSS is to be deleted + - this type of ending a session is possible when UMAC has failed an + - association session during Join*/ + if ( WDI_LINK_IDLE_STATE == + pWDICtx->wdiCacheSetLinkStReq.wdiLinkInfo.wdiLinkState ) + { + /*------------------------------------------------------------------------ + Find the BSS for which the request is made + ------------------------------------------------------------------------*/ + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pWDICtx->wdiCacheSetLinkStReq.wdiLinkInfo.macBSSID, + &pBSSSes); + + /*----------------------------------------------------------------------- + Del BSS response can only be received for an existing assoc that + is current and in progress + -----------------------------------------------------------------------*/ + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Set link response received outside association session"); + } + else + { + /* For BT AMP roles no need to delete the sessions if assoc fails. There + will be del BSS coming after this to stop the beaconing & cleaning up the + sessions*/ + if(( WDI_BTAMP_STA_MODE != pBSSSes->wdiBssType )&& + ( WDI_BTAMP_AP_MODE != pBSSSes->wdiBssType )) + { + /*----------------------------------------------------------------------- + The current session will be deleted + -----------------------------------------------------------------------*/ + WDI_DeleteSession(pWDICtx, pBSSSes); + + /*----------------------------------------------------------------------- + Check to see if this association is in progress - if so disable the + flag as this has ended + -----------------------------------------------------------------------*/ + if ( ucCurrentBSSSesIdx == pWDICtx->ucCurrentBSSSesIdx ) + { + /*Association no longer in progress */ + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + /*Association no longer in progress - prepare pending assoc for processing*/ + WDI_DequeueAssocRequest(pWDICtx); + } + } + } + } + /* If the link state has been set to POST ASSOC, reset the "association in + progress" flag */ + if ( WDI_LINK_POSTASSOC_STATE == + pWDICtx->wdiCacheSetLinkStReq.wdiLinkInfo.wdiLinkState ) + { + pWDICtx->bAssociationInProgress = eWLAN_PAL_FALSE; + WDI_DequeueAssocRequest(pWDICtx); + } + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiSetLinkStateRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetLinkStateRsp*/ + +/** + @brief Process Get Stats Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetStatsRspParamsType *wdiGetStatsRsp; + WDI_GetStatsRspCb wdiGetStatsRspCb; + tHalStatsRspParams* pHalStatsRspParams; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + pHalStatsRspParams = (tHalStatsRspParams *)pEventData->pEventData; + + /*allocate the stats response buffer */ + wdiGetStatsRsp = (WDI_GetStatsRspParamsType *)wpalMemoryAllocate( + pHalStatsRspParams->msgLen - sizeof(tHalStatsRspParams) + + sizeof(WDI_GetStatsRspParamsType)); + + if(NULL == wdiGetStatsRsp) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to allocate memory in Get Stats Response %p %p %p ", + pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGetStatsRspCb = (WDI_GetStatsRspCb)pWDICtx->pfncRspCB; + + wpalMemoryZero(wdiGetStatsRsp, pHalStatsRspParams->msgLen); + wdiGetStatsRsp->usMsgType = pHalStatsRspParams->msgType; + wdiGetStatsRsp->usMsgLen = pHalStatsRspParams->msgLen; + wdiGetStatsRsp->wdiStatus = WDI_HAL_2_WDI_STATUS(pHalStatsRspParams->status); + wdiGetStatsRsp->ucSTAIdx = pHalStatsRspParams->staId; + wdiGetStatsRsp->uStatsMask = pHalStatsRspParams->statsMask; + + /* copy the stats from buffer at the end of the tHalStatsRspParams message */ + wpalMemoryCopy(wdiGetStatsRsp + 1, + (wpt_uint8*)pEventData->pEventData + sizeof(tHalStatsRspParams), + pHalStatsRspParams->msgLen - sizeof(tHalStatsRspParams)); + + /*Notify UMAC*/ + wdiGetStatsRspCb( wdiGetStatsRsp, pWDICtx->pRspCBUserData); + + wpalMemoryFree(wdiGetStatsRsp); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessGetStatsRsp*/ + +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) +/** + @brief Process Get Roam Rssi Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetRoamRssiRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetRoamRssiRspParamsType wdiGetRoamRssiRsp; + WDI_GetRoamRssiRspCb wdiGetRoamRssiRspCb; + tHalGetRoamRssiRspMsg halRoamRssiRspParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGetRoamRssiRspCb = (WDI_GetRoamRssiRspCb)pWDICtx->pfncRspCB; + if(NULL == wdiGetRoamRssiRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: call back function is NULL", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRoamRssiRspParams.roamRssiRspParams, + pEventData->pEventData, + sizeof(halRoamRssiRspParams.roamRssiRspParams)); + + wdiGetRoamRssiRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRoamRssiRspParams.roamRssiRspParams.status); + wdiGetRoamRssiRsp.ucSTAIdx = halRoamRssiRspParams.roamRssiRspParams.staId; + wdiGetRoamRssiRsp.rssi = halRoamRssiRspParams.roamRssiRspParams.rssi; + + /*Notify UMAC*/ + wdiGetRoamRssiRspCb( &wdiGetRoamRssiRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessGetRoamRssiRsp*/ +#endif + + +/** + @brief Process Update Cfg Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateCfgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_UpdateCfgRspCb wdiUpdateCfgRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiUpdateCfgRspCb = (WDI_UpdateCfgRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiUpdateCfgRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUpdateCfgRsp*/ + + + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAddBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AddBARspCb wdiAddBARspCb; + + tAddBARspParams halAddBARsp; + WDI_AddBARspinfoType wdiAddBARsp; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiAddBARspCb = (WDI_AddBARspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halAddBARsp, + pEventData->pEventData, + sizeof(halAddBARsp)); + + wdiAddBARsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halAddBARsp.status); + + if ( WDI_STATUS_SUCCESS == wdiAddBARsp.wdiStatus ) + { + wdiAddBARsp.ucBaDialogToken = halAddBARsp.baDialogToken; + } + + /*Notify UMAC*/ + wdiAddBARspCb( &wdiAddBARsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessAddSessionBARsp*/ + +/** + @brief Process Add BA Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_TriggerBARspCb wdiTriggerBARspCb; + + tTriggerBARspParams* halTriggerBARsp; + tTriggerBaRspCandidate* halBaCandidate; + WDI_TriggerBARspParamsType* wdiTriggerBARsp; + WDI_TriggerBARspCandidateType* wdiTriggerBARspCandidate; + wpt_uint16 index; + wpt_uint16 TidIndex; + WDI_Status halTriggerBARspStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiTriggerBARspCb = (WDI_TriggerBARspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halTriggerBARsp = (tTriggerBARspParams *)pEventData->pEventData; + + halTriggerBARspStatus = WDI_HAL_2_WDI_STATUS(halTriggerBARsp->status); + + if ( WDI_STATUS_SUCCESS == halTriggerBARspStatus) + { + wdiTriggerBARsp = wpalMemoryAllocate(sizeof(WDI_TriggerBARspParamsType) + + halTriggerBARsp->baCandidateCnt * + sizeof(WDI_TriggerBARspCandidateType)); + + if(NULL == wdiTriggerBARsp) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Failed to allocate memory in Trigger BA Response %p %p %p ", + pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiTriggerBARsp->wdiStatus = halTriggerBARspStatus; + + wdiTriggerBARsp->usBaCandidateCnt = halTriggerBARsp->baCandidateCnt; + wpalMemoryCopy(wdiTriggerBARsp->macBSSID, + halTriggerBARsp->bssId , WDI_MAC_ADDR_LEN); + + wdiTriggerBARspCandidate = (WDI_TriggerBARspCandidateType*)(wdiTriggerBARsp + 1); + halBaCandidate = (tTriggerBaRspCandidate*)(halTriggerBARsp + 1); + + for(index = 0; index < wdiTriggerBARsp->usBaCandidateCnt; index++) + { + wpalMemoryCopy(wdiTriggerBARspCandidate->macSTA, + halBaCandidate->staAddr, WDI_MAC_ADDR_LEN); + for(TidIndex = 0; TidIndex < STA_MAX_TC; TidIndex++) + { + wdiTriggerBARspCandidate->wdiBAInfo[TidIndex].fBaEnable = + halBaCandidate->baInfo[TidIndex].fBaEnable; + wdiTriggerBARspCandidate->wdiBAInfo[TidIndex].startingSeqNum = + halBaCandidate->baInfo[TidIndex].startingSeqNum; + } + wdiTriggerBARspCandidate++; + halBaCandidate++; + } + } + else + { + wdiTriggerBARsp = wpalMemoryAllocate(sizeof(WDI_TriggerBARspParamsType)); + + if(NULL == wdiTriggerBARsp) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Failed to allocate memory in Trigger BA Response %p %p %p ", + pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiTriggerBARsp->wdiStatus = halTriggerBARspStatus; + + } + + /*Notify UMAC*/ + wdiTriggerBARspCb( wdiTriggerBARsp, pWDICtx->pRspCBUserData); + + wpalMemoryFree(wdiTriggerBARsp); + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessAddSessionBARsp*/ + +/** + @brief Process Update Beacon Params Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateBeaconParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_UpdateBeaconParamsRspCb wdiUpdateBeaconParamsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiUpdateBeaconParamsRspCb = (WDI_UpdateBeaconParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiUpdateBeaconParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUpdateBeaconParamsRsp*/ + +/** + @brief Process Send Beacon template Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSendBeaconParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SendBeaconParamsRspCb wdiSendBeaconParamsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSendBeaconParamsRspCb = (WDI_SendBeaconParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiSendBeaconParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSendBeaconParamsRsp*/ + + +/** + @brief Process Update Probe Resp Template Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateProbeRspTemplateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_UpdateProbeRspTemplateRspCb wdiUpdProbeRspTemplRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiUpdProbeRspTemplRspCb = (WDI_UpdateProbeRspTemplateRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiUpdProbeRspTemplRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUpdateProbeRspTemplateRsp*/ + + /** + @brief Process Set Max Tx Power Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetMaxTxPowerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tSetMaxTxPwrRspMsg halTxpowerrsp; + + WDI_SetMaxTxPowerRspMsg wdiSetMaxTxPowerRspMsg; + + WDA_SetMaxTxPowerRspCb wdiReqStatusCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiReqStatusCb = (WDA_SetMaxTxPowerRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTxpowerrsp.setMaxTxPwrRspParams, + pEventData->pEventData, + sizeof(halTxpowerrsp.setMaxTxPwrRspParams)); + + if ( eHAL_STATUS_SUCCESS != halTxpowerrsp.setMaxTxPwrRspParams.status ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Error status returned in Set Max Tx Power Response "); + return WDI_STATUS_E_FAILURE; + } + + wdiSetMaxTxPowerRspMsg.wdiStatus = + WDI_HAL_2_WDI_STATUS(halTxpowerrsp.setMaxTxPwrRspParams.status); + wdiSetMaxTxPowerRspMsg.ucPower = halTxpowerrsp.setMaxTxPwrRspParams.power; + + /*Notify UMAC*/ + wdiReqStatusCb( &wdiSetMaxTxPowerRspMsg, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + + /** + @brief Process Set Tx Power Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPowerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tSetTxPwrRspMsg halTxpowerrsp; + WDI_SetTxPowerRspMsg wdiSetTxPowerRspMsg; + WDA_SetTxPowerRspCb wdiReqStatusCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiReqStatusCb = (WDA_SetTxPowerRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy(&halTxpowerrsp.setTxPwrRspParams, + pEventData->pEventData, + sizeof(halTxpowerrsp.setTxPwrRspParams)); + + if (eHAL_STATUS_SUCCESS != halTxpowerrsp.setTxPwrRspParams.status) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Error status returned in Set Tx Power Response "); + WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + return WDI_STATUS_E_FAILURE; + } + + wdiSetTxPowerRspMsg.wdiStatus = + WDI_HAL_2_WDI_STATUS(halTxpowerrsp.setTxPwrRspParams.status); + + /*Notify UMAC*/ + wdiReqStatusCb(&wdiSetTxPowerRspMsg, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Set Max Tx Power Per Band Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetMaxTxPowerPerBandRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tSetMaxTxPwrPerBandRspMsg halMaxTxPowerPerBandRsp; + WDI_SetMaxTxPowerPerBandRspMsg wdiSetTxPowerPerBandRspMsg; + WDA_SetMaxTxPowerPerBandRspCb wdiReqStatusCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiReqStatusCb = (WDA_SetMaxTxPowerPerBandRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy(&halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams, + pEventData->pEventData, + sizeof(halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams)); + + if (eHAL_STATUS_SUCCESS != + halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams.status) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Error status returned in Set Max Tx Power Per Band Response"); + return WDI_STATUS_E_FAILURE; + } + + wdiSetTxPowerPerBandRspMsg.wdiStatus = + WDI_HAL_2_WDI_STATUS( + halMaxTxPowerPerBandRsp.setMaxTxPwrPerBandRspParams.status); + + /* Notify UMAC */ + wdiReqStatusCb(&wdiSetTxPowerPerBandRspMsg, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_TDLS +/** + @brief Process TDLS Link Establish Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLinkEstablishReqRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_SetTDLSLinkEstablishReqParamsRspCb wdiTDLSLinkEstablishReqParamsRspCb; + tTDLSLinkEstablishedRespMsg halTdlsLinkEstablishedRespMsg; + WDI_SetTdlsLinkEstablishReqResp wdiSetTdlsLinkEstablishReqResp; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTdlsLinkEstablishedRespMsg.TDLSLinkEstablishedRespParams, + pEventData->pEventData, + sizeof(halTdlsLinkEstablishedRespMsg.TDLSLinkEstablishedRespParams) ); + + wdiTDLSLinkEstablishReqParamsRspCb = (WDI_SetTDLSLinkEstablishReqParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiSetTdlsLinkEstablishReqResp.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + wdiSetTdlsLinkEstablishReqResp.uStaIdx = halTdlsLinkEstablishedRespMsg.TDLSLinkEstablishedRespParams.staIdx; + + /*Notify UMAC*/ + wdiTDLSLinkEstablishReqParamsRspCb( &wdiSetTdlsLinkEstablishReqResp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessLinkEstablishReqRsp*/ + + + +/** + @brief Process TDLS Chan switch Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChanSwitchReqRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchReqParamsRspCb; + tTDLSChanSwitchRespMsg halTdlsChanSwitchRespMsg; + WDI_SetTdlsChanSwitchReqResp wdiSetTdlsChanSwitchReqResp; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams, + pEventData->pEventData, + sizeof(halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams) ); + + wdiTDLSChanSwitchReqParamsRspCb = (WDI_SetTDLSChanSwitchReqParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiSetTdlsChanSwitchReqResp.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + wdiSetTdlsChanSwitchReqResp.uStaIdx = halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams.staIdx; + + /*Notify UMAC*/ + wdiTDLSChanSwitchReqParamsRspCb( &wdiSetTdlsChanSwitchReqResp, pWDICtx->pRspCBUserData ); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessChanSwitchReqRsp*/ + + + +#endif + +/** + @brief Process P2P Group Owner Notice Of Absense Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2PGONOARsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetP2PGONOAReqParamsRspCb wdiP2PGONOAReqParamsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiP2PGONOAReqParamsRspCb = (WDI_SetP2PGONOAReqParamsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halStatus, + pEventData->pEventData, + sizeof(halStatus)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiP2PGONOAReqParamsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessP2PGONOARsp*/ +/** + @brief Process Enter IMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterImpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_EnterImpsRspCb wdiEnterImpsRspCb; + wpt_status wptStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEnterImpsRspCb = (WDI_EnterImpsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /* If IMPS req failed, riva is not power collapsed Put the DXE in FULL state. + * Other module states are taken care by PMC. + * TODO: How do we take care of the case where IMPS is success, but riva power collapse fails?? + */ + if (wdiStatus != WDI_STATUS_SUCCESS) { + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDI Process Enter IMPS RSP failed With HAL Status Code: %d", + halStatus); + /* Call Back is not required as we are putting the DXE in FULL + * and riva is already in full (IMPS RSP Failed)*/ + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus); + WDI_ASSERT(0); + } + } + /*Notify UMAC*/ + wdiEnterImpsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessEnterImpsRsp*/ + +/** + @brief Process Exit IMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitImpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_ExitImpsRspCb wdiExitImpsRspCb; + wpt_status wptStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiExitImpsRspCb = (WDI_ExitImpsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + if (halStatus != eHAL_STATUS_SUCCESS) + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Exit IMPS response is a failure with halStatus %d", __func__, halStatus); + + // notify DTS that we are entering Full power + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus); + WDI_ASSERT(0); + } + /*Notify UMAC*/ + wdiExitImpsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessExitImpsRsp*/ + +/** + @brief Process Enter BMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterBmpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus = eHAL_STATUS_FAILURE; + tHalEnterBmpsRspParams halEnterBmpsRsp; + WDI_EnterBmpsRspCb wdiEnterBmpsRspCb; + WDI_EnterBmpsRspParamsType wdiEnterBmpsRspparams; + wpt_status wptStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halEnterBmpsRsp, + pEventData->pEventData, + sizeof(halEnterBmpsRsp)); + + //Used to print debug message + halStatus = halEnterBmpsRsp.status; + wdiEnterBmpsRspparams.wdiStatus = WDI_HAL_2_WDI_STATUS(halEnterBmpsRsp.status); + wdiEnterBmpsRspparams.bssIdx = halEnterBmpsRsp.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiEnterBmpsRspparams.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + wdiEnterBmpsRspCb = (WDI_EnterBmpsRspCb)pWDICtx->pfncRspCB; + + /* If BMPS req failed, riva is not power collapsed put the DXE in FULL state. + * Other module states are taken care by PMC. + * TODO: How do we take care of the case where BMPS is success, but riva power collapse fails?? + */ + if (wdiEnterBmpsRspparams.wdiStatus != WDI_STATUS_SUCCESS) + { + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDI Process Enter BMPS RSP failed With HAL Status Code: %d", + halStatus); + /* Call Back is not required as we are putting the DXE in FULL + * and riva is already in FULL (BMPS RSP Failed)*/ + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus); + WDI_ASSERT(0); + } + pWDICtx->bInBmps = eWLAN_PAL_FALSE; + } + + /*Notify UMAC*/ + wdiEnterBmpsRspCb( &wdiEnterBmpsRspparams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessEnterBmpsRsp*/ + +/** + @brief Process Exit BMPS Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitBmpsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_ExitBmpsRspCb wdiExitBmpsRspCb; + tHalExitBmpsRspParams halExitBmpsRsp; + WDI_ExitBmpsRspParamsType wdiExitBmpsRspParams; + wpt_status wptStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiExitBmpsRspCb = (WDI_ExitBmpsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halExitBmpsRsp, + pEventData->pEventData, + sizeof(halExitBmpsRsp)); + + wdiExitBmpsRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halExitBmpsRsp.status); + wdiExitBmpsRspParams.bssIdx = halExitBmpsRsp.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiExitBmpsRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + // notify DTS that we are entering Full power + wptStatus = WDTS_SetPowerState(pWDICtx, WDTS_POWER_STATE_FULL, NULL); + if( eWLAN_PAL_STATUS_SUCCESS != wptStatus ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDTS_SetPowerState returned with status %d when trying to notify DTS that host is entering Full Power state", wptStatus); + WDI_ASSERT(0); + } + pWDICtx->bInBmps = eWLAN_PAL_FALSE; + + /*Notify UMAC*/ + wdiExitBmpsRspCb( &wdiExitBmpsRspParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessExitBmpsRsp*/ + +/** + @brief Process Enter UAPSD Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEnterUapsdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + tUapsdRspParams halEnterUapsdRsp; + WDI_EnterUapsdRspCb wdiEnterUapsdRspCb; + WDI_EnterUapsdRspParamsType wdiEnterUapsdRspParams; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEnterUapsdRspCb = (WDI_EnterUapsdRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halEnterUapsdRsp, + pEventData->pEventData, + sizeof(halEnterUapsdRsp)); + + wdiEnterUapsdRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halEnterUapsdRsp.status); + wdiEnterUapsdRspParams.bssIdx = halEnterUapsdRsp.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiEnterUapsdRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + if(WDI_STATUS_SUCCESS == wdiEnterUapsdRspParams.wdiStatus) + { + // Set the DPU routing flag to the FW WQ, all the TX frames would be now pushed + // from DPU to the FW-WQ (5) in UAPSD. FW would be in data path, monitoring + // the traffic to decide when to suspend the trigger frames when there is no traffic + // activity on the trigger enabled ACs + pWDICtx->ucDpuRF = BMUWQ_FW_DPU_TX; + +#ifdef WLAN_PERF + // Increment the BD signature to refresh the fast path BD utilization + pWDICtx->uBdSigSerialNum++; +#endif + } + + /*Notify UMAC*/ + wdiEnterUapsdRspCb( &wdiEnterUapsdRspParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessEnterUapsdRsp*/ + +/** + @brief Process Exit UAPSD Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessExitUapsdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_ExitUapsdRspCb wdiExitUapsdRspCb; + tHalExitUapsdRspParams halExitUapsdRsp; + WDI_ExitUapsdRspParamsType wdiExitUapsdRspParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiExitUapsdRspCb = (WDI_ExitUapsdRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halExitUapsdRsp, + pEventData->pEventData, + sizeof(halExitUapsdRsp)); + + wdiExitUapsdRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halExitUapsdRsp.status); + wdiExitUapsdRspParams.bssIdx = halExitUapsdRsp.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiExitUapsdRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + // Restore back the DPU routing flag in the TxBD, for DPU to push the TxBDs to BTQM + // directly instead of the FW WQ. + pWDICtx->ucDpuRF = BMUWQ_BTQM_TX_MGMT; + +#ifdef WLAN_PERF + // Increment the BD signature to refresh the fast path BD utilization + pWDICtx->uBdSigSerialNum++; +#endif + + /*Notify UMAC*/ + wdiExitUapsdRspCb( &wdiExitUapsdRspParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessExitUapsdRsp*/ + +/** + @brief Process set UAPSD params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetUapsdAcParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetUapsdAcParamsCb wdiSetUapsdAcParamsCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetUapsdAcParamsCb = (WDI_SetUapsdAcParamsCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiSetUapsdAcParamsCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetUapsdAcParamsRsp*/ + +/** + @brief Process update UAPSD params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateUapsdParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_UpdateUapsdParamsCb wdiUpdateUapsdParamsCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiUpdateUapsdParamsCb = (WDI_UpdateUapsdParamsCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiUpdateUapsdParamsCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUpdateUapsdParamsRsp*/ + +/** + @brief Process Configure RXP filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureRxpFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_ConfigureRxpFilterCb wdiConfigureRxpFilterCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiConfigureRxpFilterCb = (WDI_ConfigureRxpFilterCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiConfigureRxpFilterCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessConfigureRxpFilterRsp*/ + +/** + @brief Process Set beacon filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBeaconFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetBeaconFilterCb wdiBeaconFilterCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiBeaconFilterCb = (WDI_SetBeaconFilterCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiBeaconFilterCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetBeaconFilterRsp*/ + +/** + @brief Process remove beacon filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRemBeaconFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_RemBeaconFilterCb wdiBeaconFilterCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiBeaconFilterCb = (WDI_RemBeaconFilterCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiBeaconFilterCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessRemBeaconFilterRsp*/ + +/** + @brief Process set RSSI thresholds Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRSSIThresoldsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetRSSIThresholdsCb wdiRSSIThresholdsCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRSSIThresholdsCb = (WDI_SetRSSIThresholdsCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiRSSIThresholdsCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetRSSIThresoldsRsp*/ + +/** + @brief Process host offload Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_HostOffloadCb wdiHostOffloadCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiHostOffloadCb = (WDI_HostOffloadCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiHostOffloadCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessHostOffloadRsp*/ + +/** + @brief Process keep alive Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessKeepAliveRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_KeepAliveCb wdiKeepAliveCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Received WDI_ProcessKeepAliveRsp Callback from HAL"); + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiKeepAliveCb = (WDI_KeepAliveCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiKeepAliveCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessKeepAliveRsp*/ + +/** + @brief Process wowl add ptrn Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlAddBcPtrnRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_WowlAddBcPtrnCb wdiWowlAddBcPtrnCb; + tHalAddWowlBcastPtrnRspParams halAddWowlBcastPtrRsp; + WDI_WowlAddBcPtrnRspParamsType wdiWowlAddBcPtrRsp; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiWowlAddBcPtrnCb = (WDI_WowlAddBcPtrnCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halAddWowlBcastPtrRsp, + pEventData->pEventData, + sizeof(halAddWowlBcastPtrRsp)); + + wdiWowlAddBcPtrRsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halAddWowlBcastPtrRsp.status); + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiWowlAddBcPtrRsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halStatus); + } + + /*Notify UMAC*/ + wdiWowlAddBcPtrnCb( &wdiWowlAddBcPtrRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessWowlAddBcPtrnRsp*/ + +/** + @brief Process wowl delete ptrn Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlDelBcPtrnRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_WowlDelBcPtrnCb wdiWowlDelBcPtrnCb; + tHalDelWowlBcastPtrnRspParams halDelWowlBcastPtrRsp; + WDI_WowlDelBcPtrnRspParamsType wdiWowlDelBcstPtrRsp; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiWowlDelBcPtrnCb = (WDI_WowlDelBcPtrnCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halDelWowlBcastPtrRsp, + pEventData->pEventData, + sizeof(halDelWowlBcastPtrRsp)); + + wdiWowlDelBcstPtrRsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halDelWowlBcastPtrRsp.status); + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiWowlDelBcstPtrRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + /*Notify UMAC*/ + wdiWowlDelBcPtrnCb( &wdiWowlDelBcstPtrRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessWowlDelBcPtrnRsp*/ + +/** + @brief Process wowl enter Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlEnterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_WowlEnterReqCb wdiWowlEnterCb; + WDI_WowlEnterRspParamsType wdiwowlEnterRsp; + tHalEnterWowlRspParams halEnterWowlRspParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiWowlEnterCb = (WDI_WowlEnterReqCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halEnterWowlRspParams, + (wpt_uint8*)pEventData->pEventData, + sizeof(halEnterWowlRspParams)); + + wdiwowlEnterRsp.bssIdx = halEnterWowlRspParams.bssIdx; + wdiwowlEnterRsp.status = + WDI_HAL_2_WDI_STATUS(halEnterWowlRspParams.status); + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiwowlEnterRsp.status = WDI_HAL_2_WDI_STATUS(halStatus); + } + /*Notify UMAC*/ + wdiWowlEnterCb( &wdiwowlEnterRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessWowlEnterRsp*/ + +/** + @brief Process wowl exit Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessWowlExitRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_WowlExitReqCb wdiWowlExitCb; + tHalExitWowlRspParams halExitWowlRspParams; + WDI_WowlExitRspParamsType wdiWowlExitRsp; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiWowlExitCb = (WDI_WowlExitReqCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halExitWowlRspParams, + pEventData->pEventData, + sizeof(halExitWowlRspParams)); + + wdiWowlExitRsp.status = WDI_HAL_2_WDI_STATUS(halExitWowlRspParams.status); + wdiWowlExitRsp.bssIdx = halExitWowlRspParams.bssIdx; + + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiWowlExitRsp.status = WDI_HAL_2_WDI_STATUS(halStatus); + } + /*Notify UMAC*/ + wdiWowlExitCb( &wdiWowlExitRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessWowlExitRsp*/ + +/** + @brief Process Configure Apps CPU wakeup State Rsp function + (called when a response is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessConfigureAppsCpuWakeupStateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_ConfigureAppsCpuWakeupStateCb wdiConfigureAppsCpuWakeupStateCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiConfigureAppsCpuWakeupStateCb = (WDI_ConfigureAppsCpuWakeupStateCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiConfigureAppsCpuWakeupStateCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessConfigureAppsCpuWakeupStateRsp*/ + + +/** + @brief Process Nv download(called when a response + is being received over the bus from HAL,will check if the responce is ) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNvDownloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + + WDI_NvDownloadRspCb wdiNvDownloadRspCb; + tHalNvImgDownloadRspParams halNvDownloadRsp; + WDI_NvDownloadRspInfoType wdiNvDownloadRsp; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halNvDownloadRsp, + pEventData->pEventData, + sizeof(halNvDownloadRsp)); + + wdiNvDownloadRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halNvDownloadRsp.status); + + if((wdiNvDownloadRsp.wdiStatus == WDI_STATUS_SUCCESS) && + (pWDICtx->wdiNvBlobInfo.usCurrentFragment != + pWDICtx->wdiNvBlobInfo.usTotalFragment )) + { + WDI_NvDownloadReq(&pWDICtx->wdiCachedNvDownloadReq, + (WDI_NvDownloadRspCb)pWDICtx->pfncRspCB, pWDICtx->pRspCBUserData); + } + else + { + /*Reset the Nv related global information in WDI context information */ + pWDICtx->wdiNvBlobInfo.usTotalFragment = 0; + pWDICtx->wdiNvBlobInfo.usFragmentSize = 0; + pWDICtx->wdiNvBlobInfo.usCurrentFragment = 0; + /*call WDA callback function for last fragment */ + wdiNvDownloadRspCb = (WDI_NvDownloadRspCb)pWDICtx->pfncRspCB; + wdiNvDownloadRspCb( &wdiNvDownloadRsp, pWDICtx->pRspCBUserData); + } + + return WDI_STATUS_SUCCESS; +} +#ifdef WLAN_FEATURE_VOWIFI_11R +/** + @brief Process Add TSpec Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessAggrAddTSpecRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + tAggrAddTsRspParams aggrAddTsRsp; + WDI_AggrAddTsRspCb wdiAggrAddTsRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiAggrAddTsRspCb = (WDI_AddTsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &aggrAddTsRsp, + pEventData->pEventData, + sizeof(aggrAddTsRsp)); + + /* What is the difference between status0 and status1? */ + wdiStatus = WDI_HAL_2_WDI_STATUS(aggrAddTsRsp.status0); + + /*Notify UMAC*/ + wdiAggrAddTsRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessAddTSpecRsp*/ +#endif /* WLAN_FEATURE_VOWIFI_11R */ + +/** + @brief WDI_ProcessHostResumeRsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHostResumeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SuspendResumeRspParamsType wdiResumeRspParams; + WDI_HostResumeEventRspCb wdiHostResumeRspCb; + tHalHostResumeRspParams hostResumeRspMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiHostResumeRspCb = (WDI_HostResumeEventRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + + wpalMemoryCopy( &hostResumeRspMsg, + (wpt_uint8*)pEventData->pEventData, + sizeof(hostResumeRspMsg)); + + wdiResumeRspParams.wdiStatus = + WDI_HAL_2_WDI_STATUS(hostResumeRspMsg.status); + + /*Notify UMAC*/ + wdiHostResumeRspCb(&wdiResumeRspParams, (void*) pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Set Tx PER Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTxPerTrackingRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetTxPerTrackingRspCb pwdiSetTxPerTrackingRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiSetTxPerTrackingRspCb = (WDI_SetTxPerTrackingRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + pwdiSetTxPerTrackingRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetTxPerTrackingRsp*/ + +/*========================================================================== + Indications from HAL + ==========================================================================*/ +/** + @brief Process Low RSSI Indication function (called when an + indication of this kind is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLowRSSIInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalRSSINotificationIndMsg halRSSINotificationIndMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( (void *)&halRSSINotificationIndMsg.rssiNotificationParams, + pEventData->pEventData, + sizeof(tHalRSSINotification)); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_RSSI_NOTIFICATION_IND; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres1PosCross = + halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres1PosCross; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres1NegCross = + halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres1NegCross; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres2PosCross = + halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres2PosCross; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres2NegCross = + halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres2NegCross; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres3PosCross = + halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres3PosCross; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.bRssiThres3NegCross = + halRSSINotificationIndMsg.rssiNotificationParams.bRssiThres3NegCross; + wdiInd.wdiIndicationData.wdiLowRSSIInfo.avgRssi = + halRSSINotificationIndMsg.rssiNotificationParams.avgRssi; + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC of indication*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessLowRSSIInd*/ + + +/** + @brief Process Missed Beacon Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessMissedBeaconInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_LowLevelIndType wdiInd; + tpHalMissedBeaconIndParams halMissedBeaconIndParams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + halMissedBeaconIndParams = (tpHalMissedBeaconIndParams)pEventData->pEventData; + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + /*! TO DO: Parameters need to be unpacked according to HAL struct*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_MISSED_BEACON_IND; + wdiInd.wdiIndicationData.wdiMissedBeaconInd.bssIdx = + halMissedBeaconIndParams->bssIdx; + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessMissedBeaconInd*/ + + +/** + @brief Process Unk Addr Frame Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUnkAddrFrameInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + /*! TO DO: Parameters need to be unpacked according to HAL struct*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_UNKNOWN_ADDR2_FRAME_RX_IND; + /* ! TO DO - fill in from HAL struct: + wdiInd.wdiIndicationData.wdiUnkAddr2FrmInfo*/ + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUnkAddrFrameInd*/ + + +/** + @brief Process MIC Failure Indication function (called when an + indication of this kind is being received over the bus + from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessMicFailureInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tpSirMicFailureInd pHalMicFailureInd; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalMicFailureInd = (tpSirMicFailureInd)pEventData->pEventData; + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_MIC_FAILURE_IND; + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.bssId, + pHalMicFailureInd->bssId, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macSrcAddr, + pHalMicFailureInd->info.srcMacAddr, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macTaAddr, + pHalMicFailureInd->info.taMacAddr, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macDstAddr, + pHalMicFailureInd->info.dstMacAddr, WDI_MAC_ADDR_LEN); + wdiInd.wdiIndicationData.wdiMICFailureInfo.ucMulticast = + pHalMicFailureInd->info.multicast; + wdiInd.wdiIndicationData.wdiMICFailureInfo.ucIV1 = + pHalMicFailureInd->info.IV1; + wdiInd.wdiIndicationData.wdiMICFailureInfo.keyId= + pHalMicFailureInd->info.keyId; + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.TSC, + pHalMicFailureInd->info.TSC,WDI_CIPHER_SEQ_CTR_SIZE); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiMICFailureInfo.macRxAddr, + pHalMicFailureInd->info.rxMacAddr, WDI_MAC_ADDR_LEN); + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessMicFailureInd*/ + + +/** + @brief Process Fatal Failure Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFatalErrorInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + + /*! TO DO: Parameters need to be unpacked according to HAL struct*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Fatal failure received from device %d ", halStatus ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_FATAL_ERROR_IND; + wdiInd.wdiIndicationData.usErrorCode = WDI_ERR_DEV_INTERNAL_FAILURE; + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessFatalErrorInd*/ + +/** + @brief Process Delete STA Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDelSTAInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tDeleteStaContextParams halDelSTACtx; + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + + /* Parameters need to be unpacked according to HAL struct*/ + wpalMemoryCopy( &halDelSTACtx, + pEventData->pEventData, + sizeof(halDelSTACtx)); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_DEL_STA_IND; + + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteSTAIndType.macADDR2, + halDelSTACtx.addr2, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteSTAIndType.macBSSID, + halDelSTACtx.bssId, WDI_MAC_ADDR_LEN); + + wdiInd.wdiIndicationData.wdiDeleteSTAIndType.usAssocId = + halDelSTACtx.assocId; + wdiInd.wdiIndicationData.wdiDeleteSTAIndType.ucSTAIdx = + halDelSTACtx.staId; + wdiInd.wdiIndicationData.wdiDeleteSTAIndType.wptReasonCode = + halDelSTACtx.reasonCode; + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessDelSTAInd*/ + +/** +*@brief Process Coex Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessCoexInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tCoexIndMsg halCoexIndMsg; + wpt_uint32 index; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halCoexIndMsg.coexIndParams, + pEventData->pEventData, + sizeof(halCoexIndMsg.coexIndParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_COEX_IND; + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndType = halCoexIndMsg.coexIndParams.coexIndType; + for (index = 0; index < WDI_COEX_IND_DATA_SIZE; index++) + { + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[index] = halCoexIndMsg.coexIndParams.coexIndData[index]; + } + + // DEBUG + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "[COEX WDI] Coex Ind Type (%x) data (%x %x %x %x)", + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndType, + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[0], + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[1], + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[2], + wdiInd.wdiIndicationData.wdiCoexInfo.coexIndData[3] ); + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessCoexInd*/ + +/** +*@brief Process Tx Complete Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTxCompleteInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tTxComplIndMsg halTxComplIndMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTxComplIndMsg.txComplParams, + pEventData->pEventData, + sizeof(halTxComplIndMsg.txComplParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_TX_COMPLETE_IND; + + wpalMemoryCopy( &wdiInd.wdiIndicationData, + &halTxComplIndMsg.txComplParams, + sizeof(WDI_TxBDStatus) ); + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessTxCompleteInd*/ +#ifdef FEATURE_WLAN_TDLS +/** +*@brief Process TDLS Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTdlsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tTdlsIndMsg halTdlsIndMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTdlsIndMsg.tdlsIndParams, + pEventData->pEventData, + sizeof(halTdlsIndMsg.tdlsIndParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_TDLS_IND; + + wdiInd.wdiIndicationData.wdiTdlsIndInfo.status + = halTdlsIndMsg.tdlsIndParams.status; + + wdiInd.wdiIndicationData.wdiTdlsIndInfo.staIdx + = halTdlsIndMsg.tdlsIndParams.staIdx; + + wdiInd.wdiIndicationData.wdiTdlsIndInfo.reasonCode + = halTdlsIndMsg.tdlsIndParams.reasonCode; + + wdiInd.wdiIndicationData.wdiTdlsIndInfo.assocId + = halTdlsIndMsg.tdlsIndParams.assocId; + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessTdlsInd*/ +#endif + +#ifdef WLAN_FEATURE_RMC +/** +*@brief Process Tx Fail Indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTXFailInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalTXFailIndMsg halTXFailIndMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halTXFailIndMsg.txFailIndParams, + pEventData->pEventData, + sizeof(halTXFailIndMsg.txFailIndParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_TX_FAIL_IND; + + wdiInd.wdiIndicationData.wdiTXFailInd.seqNo + = halTXFailIndMsg.txFailIndParams.seqNo; + + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiTXFailInd.macAddr, + halTXFailIndMsg.txFailIndParams.macAddr, + sizeof(wdiInd.wdiIndicationData.wdiTXFailInd.macAddr)); + + /*Notify UMAC*/ + if (pWDICtx->wdiLowLevelIndCB) + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + + return WDI_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_RMC */ + +/** +*@brief Process Noa Start Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2pNoaStartInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tNoaStartIndMsg halNoaStartIndMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halNoaStartIndMsg.noaStartIndParams, + pEventData->pEventData, + sizeof(halNoaStartIndMsg.noaStartIndParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_P2P_NOA_START_IND; + + wdiInd.wdiIndicationData.wdiP2pNoaStartInfo.status + = halNoaStartIndMsg.noaStartIndParams.status; + + wdiInd.wdiIndicationData.wdiP2pNoaStartInfo.bssIdx + = halNoaStartIndMsg.noaStartIndParams.bssIdx; + + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessNoaAttrInd*/ + +/** +*@brief Process Noa Attr Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessP2pNoaAttrInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tNoaAttrIndMsg halNoaAttrIndMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halNoaAttrIndMsg.noaAttrIndParams, + pEventData->pEventData, + sizeof(halNoaAttrIndMsg.noaAttrIndParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_P2P_NOA_ATTR_IND; + + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.status + = halNoaAttrIndMsg.noaAttrIndParams.status; + + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.ucIndex + = halNoaAttrIndMsg.noaAttrIndParams.index; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.ucOppPsFlag + = halNoaAttrIndMsg.noaAttrIndParams.oppPsFlag; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.usCtWin + = halNoaAttrIndMsg.noaAttrIndParams.ctWin; + + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.usNoa1IntervalCnt + = halNoaAttrIndMsg.noaAttrIndParams.uNoa1IntervalCnt; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1Duration + = halNoaAttrIndMsg.noaAttrIndParams.uNoa1Duration; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1Interval + = halNoaAttrIndMsg.noaAttrIndParams.uNoa1Interval; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa1StartTime + = halNoaAttrIndMsg.noaAttrIndParams.uNoa1StartTime; + + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.usNoa2IntervalCnt + = halNoaAttrIndMsg.noaAttrIndParams.uNoa2IntervalCnt; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2Duration + = halNoaAttrIndMsg.noaAttrIndParams.uNoa2Duration; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2Interval + = halNoaAttrIndMsg.noaAttrIndParams.uNoa2Interval; + wdiInd.wdiIndicationData.wdiP2pNoaAttrInfo.uslNoa2StartTime + = halNoaAttrIndMsg.noaAttrIndParams.uNoa2StartTime; + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessNoaAttrInd*/ + +/** + @brief Process Tx PER Hit Indication function (called when + an indication of this kind is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTxPerHitInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_TX_PER_HIT_IND; + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessTxPerHitInd*/ + +/** + @brief Process Periodic Tx Pattern Fw Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPeriodicTxPtrnFwInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pWDICtx) || (NULL == pEventData) || + (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy(&(wdiInd.wdiIndicationData.wdiPeriodicTxPtrnFwInd), + (tHalPeriodicTxPtrnFwInd *)pEventData->pEventData, + sizeof(tHalPeriodicTxPtrnFwInd)); + + if (pWDICtx->wdiLowLevelIndCB) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData); + } + + return WDI_STATUS_SUCCESS; +} + +/** + @brief WDI_ProcessFTMCommandReq + Process FTM Command, simply route to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFTMCommandReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FTMCommandReqType *ftmCommandReq = NULL; + wpt_uint8 *ftmCommandBuffer = NULL; + wpt_uint16 dataOffset; + wpt_uint16 bufferSize; + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ftmCommandReq = (WDI_FTMCommandReqType *)pEventData->pEventData; + + /* Get MSG Buffer */ + WDI_GetMessageBuffer(pWDICtx, + WDI_FTM_CMD_REQ, + ftmCommandReq->bodyLength, + &ftmCommandBuffer, + &dataOffset, + &bufferSize); + + wpalMemoryCopy(ftmCommandBuffer + dataOffset, + ftmCommandReq->FTMCommandBody, + ftmCommandReq->bodyLength); + + /* Send MSG */ + return WDI_SendMsg(pWDICtx, + ftmCommandBuffer, + bufferSize, + pEventData->pCBfnc, + pEventData->pUserData, + WDI_FTM_CMD_RESP); +} + +/** + @brief WDI_ProcessFTMCommandRsp + Process FTM Command Response from HAL, simply route to HDD FTM + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFTMCommandRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FTMCommandRspCb ftmCMDRspCb; + tProcessPttRspParams *ftmCMDRspData = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ftmCMDRspCb = (WDI_FTMCommandRspCb)pWDICtx->pfncRspCB; + + ftmCMDRspData = (tProcessPttRspParams *)pEventData->pEventData; + + wpalMemoryCopy((void *)pWDICtx->ucFTMCommandRspBuffer, + (void *)&ftmCMDRspData->pttMsgBuffer, + ftmCMDRspData->pttMsgBuffer.msgBodyLength); + + /*Notify UMAC*/ + ftmCMDRspCb((void *)pWDICtx->ucFTMCommandRspBuffer, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +/** + @brief WDI_ProcessHalDumpCmdReq + Process hal dump Command, simply route to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHALDumpCmdReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_HALDumpCmdReqParamsType* pwdiHALDumpCmdParams = NULL; + WDI_HALDumpCmdRspCb wdiHALDumpCmdRspCb = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalDumpCmdReqMsg halDumpCmdReqMsg; + wpt_uint8* pSendBuffer = NULL; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiHALDumpCmdParams = (WDI_HALDumpCmdReqParamsType*)pEventData->pEventData; + wdiHALDumpCmdRspCb = (WDI_HALDumpCmdRspCb)pEventData->pCBfnc; + + /* Copying the HAL DUMP Command Information HAL Structure*/ + halDumpCmdReqMsg.dumpCmdReqParams.argument1 = + pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.command; + halDumpCmdReqMsg.dumpCmdReqParams.argument2 = + pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument1; + halDumpCmdReqMsg.dumpCmdReqParams.argument3 = + pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument2; + halDumpCmdReqMsg.dumpCmdReqParams.argument4 = + pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument3; + halDumpCmdReqMsg.dumpCmdReqParams.argument5 = + pwdiHALDumpCmdParams->wdiHALDumpCmdInfoType.argument4; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_HAL_DUMP_CMD_REQ, + sizeof(halDumpCmdReqMsg.dumpCmdReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < + (usDataOffset + sizeof(halDumpCmdReqMsg.dumpCmdReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in HAL Dump Command req %p %p %p", + pEventData, pwdiHALDumpCmdParams, wdiHALDumpCmdRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halDumpCmdReqMsg.dumpCmdReqParams, + sizeof(halDumpCmdReqMsg.dumpCmdReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiHALDumpCmdParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiHALDumpCmdParams->pUserData; + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiHALDumpCmdRspCb, pEventData->pUserData, + WDI_HAL_DUMP_CMD_RESP); +} + +/** + @brief WDI_ProcessHalDumpCmdRsp + Process hal Dump Command Response from HAL, simply route to HDD + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHALDumpCmdRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_HALDumpCmdRspCb wdiHALDumpCmdRspCb; + tHalDumpCmdRspParams halDumpCmdRspParams; + WDI_HALDumpCmdRspParamsType wdiHALDumpCmdRsp; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiHALDumpCmdRspCb = (WDI_HALDumpCmdRspCb)pWDICtx->pfncRspCB; + + /*Initialize the WDI Response structure */ + wdiHALDumpCmdRsp.usBufferLen = 0; + wdiHALDumpCmdRsp.pBuffer = NULL; + + wpalMemoryCopy( &halDumpCmdRspParams, + pEventData->pEventData, + sizeof(tHalDumpCmdRspParams)); + + wdiHALDumpCmdRsp.wdiStatus = + WDI_HAL_2_WDI_STATUS(halDumpCmdRspParams.status); + + if (( wdiHALDumpCmdRsp.wdiStatus == WDI_STATUS_SUCCESS) && + (halDumpCmdRspParams.rspLength != 0)) + { + /* Copy the response data */ + wdiHALDumpCmdRsp.usBufferLen = halDumpCmdRspParams.rspLength; + wdiHALDumpCmdRsp.pBuffer = wpalMemoryAllocate(halDumpCmdRspParams.rspLength); + + wpalMemoryCopy( wdiHALDumpCmdRsp.pBuffer, + &halDumpCmdRspParams.rspBuffer, + halDumpCmdRspParams.rspLength); + } + + /*Notify UMAC*/ + wdiHALDumpCmdRspCb(&wdiHALDumpCmdRsp, pWDICtx->pRspCBUserData); + + if(wdiHALDumpCmdRsp.pBuffer != NULL) + { + /* Free the allocated buffer */ + wpalMemoryFree(wdiHALDumpCmdRsp.pBuffer); + } + return WDI_STATUS_SUCCESS; +} + +/*========================================================================== + CONTRL TRANSPORT INTERACTION + + Callback function registered with the control transport - for receiving + notifications and packets +==========================================================================*/ +/** + @brief This callback is invoked by the control transport + when it wishes to send up a notification like the ones + mentioned above. + + @param + + wctsHandle: handle to the control transport service + wctsEvent: the event being notified + wctsNotifyCBData: the callback data of the user + + @see WCTS_OpenTransport + + @return None +*/ +void +WDI_NotifyMsgCTSCB +( + WCTS_HandleType wctsHandle, + WCTS_NotifyEventType wctsEvent, + void* wctsNotifyCBData +) +{ + WDI_ControlBlockType* pWDICtx = (WDI_ControlBlockType*)wctsNotifyCBData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if (NULL == pWDICtx ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return; + } + + if (WDI_CONTROL_BLOCK_MAGIC != pWDICtx->magic) + { + /* callback presumably occurred after close */ + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid control block", __func__); + return; + } + + if ( WCTS_EVENT_OPEN == wctsEvent ) + { + /*Flag must be set atomically as it is checked from incoming request + functions*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + pWDICtx->bCTOpened = eWLAN_PAL_TRUE; + + /*Nothing to do - so try to dequeue any pending request that may have + occurred while we were trying to establish this*/ + WDI_DequeuePendingReq(pWDICtx); + wpalMutexRelease(&pWDICtx->wptMutex); + } + else if ( WCTS_EVENT_CLOSE == wctsEvent ) + { + /*Flag must be set atomically as it is checked from incoming request + functions*/ + wpalMutexAcquire(&pWDICtx->wptMutex); + pWDICtx->bCTOpened = eWLAN_PAL_FALSE; + + /*No other request will be processed from now on - fail all*/ + WDI_ClearPendingRequests(pWDICtx); + wpalMutexRelease(&pWDICtx->wptMutex); + + /*Notify that the Control Channel is closed */ + wpalEventSet(&pWDICtx->wctsActionEvent); + } + +}/*WDI_NotifyMsgCTSCB*/ + + +/** + @brief This callback is invoked by the control transport + when it wishes to send up a packet received over the + bus. + + @param + + wctsHandle: handle to the control transport service + pMsg: the packet + uLen: the packet length + wctsRxMsgCBData: the callback data of the user + + @see WCTS_OpenTransport + + @return None +*/ +void +WDI_RXMsgCTSCB +( + WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen, + void* wctsRxMsgCBData +) +{ + tHalMsgHeader *pHalMsgHeader; + WDI_EventInfoType wdiEventData; + WDI_ControlBlockType* pWDICtx = (WDI_ControlBlockType*)wctsRxMsgCBData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ((NULL == pWDICtx ) || ( NULL == pMsg ) || + ( uLen < sizeof(tHalMsgHeader))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return; + } + + if (WDI_CONTROL_BLOCK_MAGIC != pWDICtx->magic) + { + /* callback presumably occurred after close */ + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid control block", __func__); + return; + } + + /*The RX Callback is expected to be serialized in the proper control thread + context - so no serialization is necessary here + ! - revisit this assumption */ + + pHalMsgHeader = (tHalMsgHeader *)pMsg; + + if ( uLen != pHalMsgHeader->msgLen ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid packet received from HAL - catastrophic failure"); + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_INVALID_RSP_FMT); + wpalWlanReload(); + + return; + } + + wdiEventData.wdiResponse = HAL_2_WDI_RSP_TYPE( pHalMsgHeader->msgType ); + vos_log_wdi_event(wdiEventData.wdiResponse, VOS_WDI_READ); + + /*The message itself starts after the header*/ + wdiEventData.pEventData = (wpt_uint8*)pMsg + sizeof(tHalMsgHeader); + wdiEventData.uEventDataSize = pHalMsgHeader->msgLen - sizeof(tHalMsgHeader); + wdiEventData.pCBfnc = gWDICb.pfncRspCB; + wdiEventData.pUserData = gWDICb.pRspCBUserData; + + + if ( wdiEventData.wdiResponse == pWDICtx->wdiExpectedResponse ) + { + /*Stop the timer as the response was received */ + /*!UT - check for potential race conditions between stop and response */ + wpalTimerStop(&pWDICtx->wptResponseTimer); + } + /* Check if we receive a response message which is not expected */ + else if ( wdiEventData.wdiResponse < WDI_HAL_IND_MIN ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Received response %s (%d) when expecting %s (%d) - catastrophic failure", + WDI_getRespMsgString(wdiEventData.wdiResponse), + wdiEventData.wdiResponse, + WDI_getRespMsgString(pWDICtx->wdiExpectedResponse), + pWDICtx->wdiExpectedResponse); + + if (gWDICb.bEnableSSR == false) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "SSR is not enabled on WDI timeout"); + WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + return; + } + wpalWcnssResetIntr(); + /* if this timer fires, it means Riva did not receive the FIQ */ + wpalTimerStart(&pWDICtx->ssrTimer, WDI_SSR_TIMEOUT); + + return; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Rx smth from HAL: %d", wdiEventData.wdiResponse); + + /*Post response event to the state machine*/ + WDI_PostMainEvent(pWDICtx, WDI_RESPONSE_EVENT, &wdiEventData); + +}/*WDI_RXMsgCTSCB*/ + + +/*======================================================================== + Internal Helper Routines +========================================================================*/ + +/** + @brief WDI_CleanCB - internal helper routine used to clean the + WDI Main Control Block + + @param pWDICtx - pointer to the control block + + @return Result of the function call +*/ +WPT_INLINE WDI_Status +WDI_CleanCB +( + WDI_ControlBlockType* pWDICtx +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*Clean the WDI Control Block*/ + wpalMemoryZero( pWDICtx, sizeof(*pWDICtx)); + + pWDICtx->uGlobalState = WDI_MAX_ST; + pWDICtx->ucMaxBssids = WDI_MAX_SUPPORTED_BSS; + pWDICtx->ucMaxStations = WDI_MAX_SUPPORTED_STAS; + + WDI_ResetAssocSessions( pWDICtx ); + + return WDI_STATUS_SUCCESS; +}/*WDI_CleanCB*/ + + +/** + @brief Process request helper function + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WPT_INLINE WDI_Status +WDI_ProcessRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*!! Skip sanity check as this is called from the FSM functionss which + already checked these pointers*/ + + if (( pEventData->wdiRequest < WDI_MAX_UMAC_IND ) && + ( NULL != pfnReqProcTbl[pEventData->wdiRequest] )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Calling request processing function for req %s (%d) %p", + WDI_getReqMsgString(pEventData->wdiRequest), + pEventData->wdiRequest, pfnReqProcTbl[pEventData->wdiRequest]); + return pfnReqProcTbl[pEventData->wdiRequest](pWDICtx, pEventData); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Operation %d is not yet implemented ", + pEventData->wdiRequest); + return WDI_STATUS_E_NOT_IMPLEMENT; + } +}/*WDI_ProcessRequest*/ + + +/** + @brief Get message helper function - it allocates memory for a + message that is to be sent to HAL accross the bus and + prefixes it with a send message header + + @param pWDICtx: pointer to the WLAN DAL context + wdiReqType: type of the request being sent + uBufferLen: message buffer len + pMsgBuffer: resulting allocated buffer + pusDataOffset: offset in the buffer where the caller + can start copying its message data + puBufferSize: the resulting buffer size (offset+buff + len) + + @see + @return Result of the function call +*/ +WDI_Status +WDI_GetMessageBuffer +( + WDI_ControlBlockType* pWDICtx, + WDI_RequestEnumType wdiReqType, + wpt_uint16 usBufferLen, + wpt_uint8** pMsgBuffer, + wpt_uint16* pusDataOffset, + wpt_uint16* pusBufferSize +) +{ + tHalMsgHeader halMsgHeader; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*!! No sanity check here as we trust the called - ! check this assumption + again*/ + + /*------------------------------------------------------------------------- + Try to allocate message buffer from PAL + -------------------------------------------------------------------------*/ + *pusBufferSize = sizeof(halMsgHeader) + usBufferLen; + *pMsgBuffer = (wpt_uint8*)wpalMemoryAllocate(*pusBufferSize); + if ( NULL == *pMsgBuffer ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to allocate message buffer for req %s (%d)", + WDI_getReqMsgString(wdiReqType), + wdiReqType); + WDI_ASSERT(0); + return WDI_STATUS_MEM_FAILURE; + } + + /*------------------------------------------------------------------------- + Fill in the message header + -------------------------------------------------------------------------*/ + halMsgHeader.msgType = WDI_2_HAL_REQ_TYPE(wdiReqType); + /* Fill msgVersion */ +#ifdef WLAN_FEATURE_11AC + if (WDI_getFwWlanFeatCaps(DOT11AC)) + halMsgHeader.msgVersion = WLAN_HAL_MSG_VERSION1; + else +#endif + halMsgHeader.msgVersion = WLAN_HAL_MSG_VERSION0; + + halMsgHeader.msgLen = sizeof(halMsgHeader) + usBufferLen; + *pusDataOffset = sizeof(halMsgHeader); + + wpalMemoryCopy(*pMsgBuffer, &halMsgHeader, sizeof(halMsgHeader)); + + return WDI_STATUS_SUCCESS; +}/*WDI_GetMessageBuffer*/ + + +/** + @brief Send message helper function - sends a message over the + bus using the control tranport and saves some info in + the CB + + @param pWDICtx: pointer to the WLAN DAL context + pSendBuffer: buffer to be sent + + usSendSize size of the buffer to be sent + pRspCb: response callback - save in the WDI + CB + pUserData: user data associated with the + callback + wdiExpectedResponse: the code of the response that is + expected to be rx-ed for this request + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SendMsg +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pSendBuffer, + wpt_uint32 usSendSize, + void* pRspCb, + void* pUserData, + WDI_ResponseEnumType wdiExpectedResponse +) +{ + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_uint32 ret; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Save needed info in the CB + ------------------------------------------------------------------------*/ + pWDICtx->pRspCBUserData = pUserData; + pWDICtx->pfncRspCB = pRspCb; + pWDICtx->wdiExpectedResponse = wdiExpectedResponse; + + /*----------------------------------------------------------------------- + Call the CTS to send this message over - free message afterwards + - notify transport failure + Note: CTS is reponsible for freeing the message buffer. + -----------------------------------------------------------------------*/ + ret = WCTS_SendMessage(pWDICtx->wctsHandle, (void*)pSendBuffer, usSendSize); + if ((eWLAN_PAL_STATUS_SUCCESS != ret) && + (eWLAN_PAL_STATUS_E_RESOURCES != ret)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Failed to send message with expected response %s (%d)" + " over the bus - catastrophic failure", + WDI_getRespMsgString(pWDICtx->wdiExpectedResponse), + pWDICtx->wdiExpectedResponse); + + wdiStatus = (ret == eWLAN_PAL_STATUS_E_FAILURE) ? + WDI_STATUS_DEV_INTERNAL_FAILURE : WDI_STATUS_E_FAILURE; + } + else + { + /* even when message was placed in CTS deferred Q, we will treat it + success but log this info + */ + if (eWLAN_PAL_STATUS_E_RESOURCES == ret) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDI_SendMsg: message placed in CTS deferred Q, expected " + "response %s (%d)", + WDI_getRespMsgString(pWDICtx->wdiExpectedResponse), + pWDICtx->wdiExpectedResponse); + WDI_ASSERT(0); + } + } + + /*Check if originator provided a request status callback*/ + if ( NULL != pWDICtx->wdiReqStatusCB ) + { + /*Inform originator whether request went through or not*/ + WDI_ReqStatusCb callback = pWDICtx->wdiReqStatusCB; + void *callbackContext = pWDICtx->pReqStatusUserData; + pWDICtx->wdiReqStatusCB = NULL; + pWDICtx->pReqStatusUserData = NULL; + callback(wdiStatus, callbackContext); + + /*For WDI requests which have registered a request callback, + inform the WDA caller of the same via setting the return value + (wdiStatus) to WDI_STATUS_PENDING. This makes sure that WDA doesnt + end up repeating the functonality in the req callback for the + WDI_STATUS_E_FAILURE case*/ + if (wdiStatus != WDI_STATUS_SUCCESS) + { + wdiStatus = WDI_STATUS_PENDING; + } + } + + if ( wdiStatus == WDI_STATUS_SUCCESS ) + { + /*Start timer for the expected response */ + wpalTimerStart(&pWDICtx->wptResponseTimer, WDI_RESPONSE_TIMEOUT); + + /*cache current timestamp for debugging */ + pWDICtx->uTimeStampRspTmrStart = wpalGetSystemTime(); + pWDICtx->uArchTimeStampRspTmrStart = wpalGetArchCounterTime(); + } + else + { + /*Inform upper stack layers that a transport fatal error occurred*/ + WDI_DetectedDeviceError(pWDICtx, WDI_ERR_TRANSPORT_FAILURE); + } + + return wdiStatus; + +}/*WDI_SendMsg*/ + + + +/** + @brief Send indication helper function - sends a message over + the bus using the control transport and saves some info + in the CB + + @param pWDICtx: pointer to the WLAN DAL context + pSendBuffer: buffer to be sent + usSendSize: size of the buffer to be sent + + @see + @return Result of the function call +*/ +WDI_Status +WDI_SendIndication +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pSendBuffer, + wpt_uint32 usSendSize +) +{ + wpt_uint32 uStatus ; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*----------------------------------------------------------------------- + Call the CTS to send this message over + Note: CTS is reponsible for freeing the message buffer. + -----------------------------------------------------------------------*/ + uStatus = WCTS_SendMessage( pWDICtx->wctsHandle, + (void*)pSendBuffer, usSendSize ); + + /*Inform Upper MAC about the outcome of the request*/ + if ( NULL != pWDICtx->wdiReqStatusCB ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Send indication status : %d", uStatus); + + /* even if CTS placed indication into its deferred Q, we treat it + * as success and let CTS drain its queue as per smd interrupt to CTS + */ + pWDICtx->wdiReqStatusCB( ((uStatus != eWLAN_PAL_STATUS_SUCCESS) && (uStatus != eWLAN_PAL_STATUS_E_RESOURCES)) ? WDI_STATUS_E_FAILURE: WDI_STATUS_SUCCESS, + pWDICtx->pReqStatusUserData); + pWDICtx->wdiReqStatusCB = NULL; + } + + /*If sending of the message failed - it is considered catastrophic and + indicates an error with the device*/ + if (( eWLAN_PAL_STATUS_SUCCESS != uStatus) && + ( eWLAN_PAL_STATUS_E_RESOURCES != uStatus)) + + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Failed to send indication over the bus - catastrophic failure"); + + WDI_DetectedDeviceError( pWDICtx, WDI_ERR_TRANSPORT_FAILURE); + return WDI_STATUS_E_FAILURE; + } + + return WDI_STATUS_SUCCESS; +}/*WDI_SendIndication*/ + + +/** + @brief WDI_DetectedDeviceError - called internally by DAL when + it has detected a failure in the device + + @param pWDICtx: pointer to the WLAN DAL context + usErrorCode: error code detected by WDI or received + from HAL + + @see + @return None +*/ +void +WDI_DetectedDeviceError +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usErrorCode +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Device Error detected code: %d - transitioning to stopped state", + usErrorCode); + + pWDICtx->DeviceErrorReason = VOS_RETURN_ADDRESS; + + wpalMutexAcquire(&pWDICtx->wptMutex); + + WDI_STATableStop(pWDICtx); + + WDI_ResetAssocSessions(pWDICtx); + + /*Set the expected state transition to stopped - because the device + experienced a failure*/ + pWDICtx->ucExpectedStateTransition = WDI_STOPPED_ST; + + /*Transition to stopped to fail all incomming requests from this point on*/ + WDI_STATE_TRANSITION( pWDICtx, WDI_STOPPED_ST); + + WDI_ClearPendingRequests(pWDICtx); + + /*TO DO: - there should be an attempt to reset the device here*/ + + wpalMutexRelease(&pWDICtx->wptMutex); + + /*------------------------------------------------------------------------ + Notify UMAC if a handler is registered + ------------------------------------------------------------------------*/ + if (pWDICtx->wdiLowLevelIndCB) + { + wdiInd.wdiIndicationType = WDI_FATAL_ERROR_IND; + wdiInd.wdiIndicationData.usErrorCode = usErrorCode; + + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData); + } +}/*WDI_DetectedDeviceError*/ + +/** + @brief This callback is invoked by the wpt when a timer that + we started on send message has expire - this should + never happen - it means device is stuck and cannot + reply - trigger catastrophic failure + @param + + pUserData: the callback data of the user (ptr to WDI CB) + + @see + @return None +*/ +void +WDI_ResponseTimerCB +( + void *pUserData +) +{ + WDI_ControlBlockType* pWDICtx = (WDI_ControlBlockType*)pUserData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if (NULL == pWDICtx) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return; + } + + /*cache current timestamp for debugging */ + pWDICtx->uTimeStampRspTmrExp = wpalGetSystemTime(); + pWDICtx->uArchTimeStampRspTmrExp = wpalGetArchCounterTime(); + + /* If response timer is running at this time that means this timer + * event is not for the last request but rather last-to-last request and + * this timer event has come after we recevied respone for last-to-last + * message + */ + if (VOS_TIMER_STATE_RUNNING == wpalTimerGetCurStatus(&pWDICtx->wptResponseTimer)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WDI_ResponseTimerCB: timer in running state on timer event, " + "ignore tmr event, timeStampTmrStart: %u, timeStampTmrExp: %u", + pWDICtx->uTimeStampRspTmrStart, pWDICtx->uTimeStampRspTmrExp); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "uArchTimeStampTmrStart: %llu seconds, " + "uArchTimeStampTmrExp: %llu seconds", + pWDICtx->uArchTimeStampRspTmrStart, + pWDICtx->uArchTimeStampRspTmrExp); + + return; + } + + if (WDI_MAX_RESP != pWDICtx->wdiExpectedResponse) + { + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Timeout occurred while waiting for %s (%d) message from device " + " - catastrophic failure, timeStampTmrStart: %u, timeStampTmrExp: %u", + WDI_getRespMsgString(pWDICtx->wdiExpectedResponse), + pWDICtx->wdiExpectedResponse, pWDICtx->uTimeStampRspTmrStart, + pWDICtx->uTimeStampRspTmrExp); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "uArchTimeStampTmrStart: %llu seconds, " + "uArchTimeStampTmrExp: %llu seconds", + pWDICtx->uArchTimeStampRspTmrStart, + pWDICtx->uArchTimeStampRspTmrExp); + + /* WDI timeout means Riva is not responding or SMD communication to Riva + * is not happening. The only possible way to recover from this error + * is to initiate SSR from APPS. + * There is also an option to re-enable wifi, which will eventually + * trigger SSR + */ + if (gWDICb.bEnableSSR == false) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "SSR is not enabled on WDI timeout"); + WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + return; + } +#ifndef WDI_RE_ENABLE_WIFI_ON_WDI_TIMEOUT + wpalWcnssResetIntr(); + if(wpalIslogPInProgress()) + { + if(wpalIsSsrPanicOnFailure()) + wpalDevicePanic(); + } else { + /* if this timer fires, it means Riva did not receive the FIQ */ + wpalTimerStart(&pWDICtx->ssrTimer, WDI_SSR_TIMEOUT); + } +#else + WDI_DetectedDeviceError(pWDICtx, WDI_ERR_BASIC_OP_FAILURE); + wpalWlanReload(); +#endif + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Timeout occurred but not waiting for any response %d " + "timeStampTmrStart: %u, timeStampTmrExp: %u", + pWDICtx->wdiExpectedResponse, pWDICtx->uTimeStampRspTmrStart, + pWDICtx->uTimeStampRspTmrExp); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "uArchTimeStampTmrStart: %llu seconds, " + "uArchTimeStampTmrExp: %llu seconds", + pWDICtx->uArchTimeStampRspTmrStart, + pWDICtx->uArchTimeStampRspTmrExp); + + } + + return; + +}/*WDI_ResponseTimerCB*/ + + +/** + @brief Process response helper function + + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WPT_INLINE WDI_Status +WDI_ProcessResponse +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /* Skip sanity check as this is called from the FSM functions which + already checked these pointers + ! - revisit this assumption */ + if (( pEventData->wdiResponse < WDI_MAX_RESP ) && + ( NULL != pfnRspProcTbl[pEventData->wdiResponse] )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Calling response processing function for resp %s (%d) %p", + WDI_getRespMsgString(pEventData->wdiResponse), + pEventData->wdiResponse, pfnRspProcTbl[pEventData->wdiResponse]); + return pfnRspProcTbl[pEventData->wdiResponse](pWDICtx, pEventData); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Operation %d is not yet implemented ", + pEventData->wdiResponse); + return WDI_STATUS_E_NOT_IMPLEMENT; + } +}/*WDI_ProcessResponse*/ + + +/*========================================================================= + QUEUE SUPPORT UTILITY FUNCTIONS +=========================================================================*/ + +/** + @brief Utility function used by the DAL Core to help queue a + request that cannot be processed right away. + @param + + pWDICtx: - pointer to the WDI control block + pEventData: - pointer to the evnt info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueuePendingReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_list_node* pNode; + WDI_EventInfoType* pEventDataQueue = wpalMemoryAllocate(sizeof(*pEventData)); + void* pEventInfo = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ( NULL == pEventDataQueue ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Cannot allocate memory for queueing"); + WDI_ASSERT(0); + return WDI_STATUS_MEM_FAILURE; + } + + pEventDataQueue->pCBfnc = pEventData->pCBfnc; + pEventDataQueue->pUserData = pEventData->pUserData; + pEventDataQueue->uEventDataSize = pEventData->uEventDataSize; + pEventDataQueue->wdiRequest = pEventData->wdiRequest; + pEventDataQueue->wdiResponse = pEventData->wdiResponse; + + if( pEventData->uEventDataSize != 0 && pEventData->pEventData != NULL ) + { + pEventInfo = wpalMemoryAllocate(pEventData->uEventDataSize); + + if ( NULL == pEventInfo ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Cannot allocate memory for queueing event data info"); + WDI_ASSERT(0); + wpalMemoryFree(pEventDataQueue); + return WDI_STATUS_MEM_FAILURE; + } + + wpalMemoryCopy(pEventInfo, pEventData->pEventData, pEventData->uEventDataSize); + + } + pEventDataQueue->pEventData = pEventInfo; + + /*Send wpt a pointer to the node (this is the 1st element in the event data)*/ + pNode = (wpt_list_node*)pEventDataQueue; + + if (eWLAN_PAL_STATUS_E_FAILURE == + wpal_list_insert_back(&(pWDICtx->wptPendingQueue), pNode)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "pEventDataQueue wpal_list_insert_back failed"); + WDI_ASSERT(0); + wpalMemoryFree(pEventDataQueue); + wpalMemoryFree(pEventInfo); + return WDI_STATUS_MEM_FAILURE; + } + + return WDI_STATUS_SUCCESS; +}/*WDI_QueuePendingReq*/ + +/** + @brief Callback function for serializing queued message + processing in the control context + @param + + pMsg - pointer to the message + + @see + @return Result of the operation +*/ +void +WDI_PALCtrlMsgCB +( + wpt_msg *pMsg +) +{ + WDI_EventInfoType* pEventData = NULL; + WDI_ControlBlockType* pWDICtx = NULL; + WDI_Status wdiStatus; + WDI_ReqStatusCb pfnReqStatusCB; + void* pUserData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if (( NULL == pMsg )|| + ( NULL == (pEventData = (WDI_EventInfoType*)pMsg->ptr)) || + ( NULL == (pWDICtx = (WDI_ControlBlockType*)pMsg->pContext ))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid message received on serialize ctrl context API"); + WDI_ASSERT(0); + return; + } + + /*Access to the global state must be locked */ + wpalMutexAcquire(&pWDICtx->wptMutex); + + /*Transition back to the state that we had before serialization + - serialization transitions us to BUSY to stop any incomming requests + */ + WDI_STATE_TRANSITION( pWDICtx, pMsg->val); + wpalMutexRelease(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Check to see what type of event we are serializing + - responses are never expected to come through here + -----------------------------------------------------------------------*/ + switch ( pEventData->wdiRequest ) + { + + case WDI_STOP_REQ: + wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_STOP_EVENT, pEventData); + break; + + case WDI_NV_DOWNLOAD_REQ: + // When WDI State is WDI_STARTED_ST, send WDI request message with event type WDI_REQUEST_EVENT. + // In this case, because this request is called from response process, we could call WDI_ProcessRequest() directly. + if (pWDICtx->uGlobalState == WDI_STARTED_ST) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: WDI_NV_DOWNLOAD_REQ called in WDI_STARTED_ST - send with WDI_REQUEST_EVENT", __func__); + wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, pEventData); + } + else + { + wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_START_EVENT, pEventData); + } + + break; + + default: + wdiStatus = WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, pEventData); + break; + }/*switch ( pEventData->wdiRequest )*/ + + if (!(WDI_STATUS_SUCCESS == wdiStatus || WDI_STATUS_PENDING == wdiStatus + || WDI_STATUS_SUCCESS_SYNC == wdiStatus)) + { + WDI_ExtractRequestCBFromEvent(pEventData, &pfnReqStatusCB, &pUserData); + + if ( NULL != pfnReqStatusCB ) + { + /*Fail the request*/ + pfnReqStatusCB( wdiStatus, pUserData); + } + } + + /* Free data - that was allocated when queueing*/ + if( pEventData != NULL ) + { + if( pEventData->pEventData != NULL ) + { + wpalMemoryFree(pEventData->pEventData); + } + wpalMemoryFree(pEventData); + } + + if( pMsg != NULL ) + { + wpalMemoryFree(pMsg); + } + +}/*WDI_PALCtrlMsgCB*/ + +/** + @brief Utility function used by the DAL Core to help dequeue + and schedule for execution a pending request + @param + + pWDICtx: - pointer to the WDI control block + pEventData: - pointer to the evnt info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_DequeuePendingReq +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_list_node* pNode = NULL; + WDI_EventInfoType* pEventData; + wpt_msg* palMsg; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + wpal_list_remove_front(&(pWDICtx->wptPendingQueue), &pNode); + + if ( NULL == pNode ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "List is empty - return"); + return WDI_STATUS_SUCCESS; + } + + /*The node actually points to the 1st element inside the Event Data struct - + just cast it back to the struct*/ + pEventData = (WDI_EventInfoType*)pNode; + + /*Serialize processing in the control thread + !TO DO: - check to see if these are all the messages params that need + to be filled in*/ + palMsg = wpalMemoryAllocate(sizeof(wpt_msg)); + + if ( NULL == palMsg ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI_DequeuePendingReq: Cannot allocate memory for palMsg."); + WDI_ASSERT(0); + return WDI_STATUS_MEM_FAILURE; + } + palMsg->pContext = pWDICtx; + palMsg->callback = WDI_PALCtrlMsgCB; + palMsg->ptr = pEventData; + + /*Save the global state as we need it on the other side*/ + palMsg->val = pWDICtx->uGlobalState; + palMsg->type = 0; + + /*Transition back to BUSY as we need to handle a queued request*/ + WDI_STATE_TRANSITION( pWDICtx, WDI_BUSY_ST); + + wpalPostCtrlMsg(pWDICtx->pPALContext, palMsg); + + return WDI_STATUS_PENDING; +}/*WDI_DequeuePendingReq*/ + + +/** + @brief Utility function used by the DAL Core to help queue + an association request that cannot be processed right + away.- The assoc requests will be queued by BSSID + @param + + pWDICtx: - pointer to the WDI control block + pEventData: pointer to the evnt info that needs to be queued + macBSSID: bssid + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueueNewAssocRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData, + wpt_macAddr macBSSID +) +{ + wpt_uint8 i; + WDI_BSSSessionType* pSession = NULL; + wpt_list_node* pNode; + WDI_EventInfoType* pEventDataQueue; + void* pEventInfo; + WDI_NextSessionIdType* pSessionIdElement; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + + /*------------------------------------------------------------------------ + Search for a session that matches the BSSID + ------------------------------------------------------------------------*/ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + if ( eWLAN_PAL_FALSE == pWDICtx->aBSSSessions[i].bInUse ) + { + /*Found an empty session*/ + pSession = &pWDICtx->aBSSSessions[i]; + break; + } + } + + if ( i >= WDI_MAX_BSS_SESSIONS ) + { + /*Cannot find any empty sessions*/ + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Fill in the BSSID for this session and set the usage flag + ------------------------------------------------------------------------*/ + wpalMemoryCopy(pWDICtx->aBSSSessions[i].macBSSID, macBSSID, WDI_MAC_ADDR_LEN); + pWDICtx->aBSSSessions[i].bInUse = eWLAN_PAL_TRUE; + + /*------------------------------------------------------------------------ + Allocate memory for this and place it in the queue + ------------------------------------------------------------------------*/ + pEventDataQueue = (WDI_EventInfoType*)wpalMemoryAllocate(sizeof(WDI_EventInfoType)); + if ( NULL == pEventDataQueue ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Cannot allocate memory for queue node", __func__); + WDI_ASSERT(0); + return WDI_STATUS_MEM_FAILURE; + } + + pSessionIdElement = (WDI_NextSessionIdType*)wpalMemoryAllocate(sizeof(WDI_NextSessionIdType)); + if ( NULL == pSessionIdElement ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Cannot allocate memory for session ID", __func__); + WDI_ASSERT(0); + wpalMemoryFree(pEventDataQueue); + return WDI_STATUS_MEM_FAILURE; + } + + pEventInfo = wpalMemoryAllocate(pEventData->uEventDataSize); + if ( NULL == pEventInfo ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Cannot allocate memory for event data info", __func__); + WDI_ASSERT(0); + wpalMemoryFree(pSessionIdElement); + wpalMemoryFree(pEventDataQueue); + return WDI_STATUS_MEM_FAILURE; + } + + pEventDataQueue->pCBfnc = pEventData->pCBfnc; + pEventDataQueue->pUserData = pEventData->pUserData; + pEventDataQueue->uEventDataSize = pEventData->uEventDataSize; + pEventDataQueue->wdiRequest = pEventData->wdiRequest; + pEventDataQueue->wdiResponse = pEventData->wdiResponse; + + wpalMemoryCopy(pEventInfo, pEventData->pEventData, pEventData->uEventDataSize); + pEventDataQueue->pEventData = pEventInfo; + + /*Send wpt a pointer to the node (this is the 1st element in the event data)*/ + pNode = (wpt_list_node*)pEventDataQueue; + + /*This association is currently being queued*/ + pSession->bAssocReqQueued = eWLAN_PAL_TRUE; + + if (eWLAN_PAL_STATUS_E_FAILURE == + wpal_list_insert_back(&(pSession->wptPendingQueue), pNode)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: pEventDataQueue wpal_list_insert_back failed", __func__); + WDI_ASSERT(0); + wpalMemoryFree(pSessionIdElement); + wpalMemoryFree(pEventDataQueue); + wpalMemoryFree(pEventInfo); + return WDI_STATUS_MEM_FAILURE; + } + + /*We need to maintain a separate list that keeps track of the order in which + the new assoc requests are being queued such that we can start processing + them in the order that they had arrived*/ + pSessionIdElement->ucIndex = i; + pNode = (wpt_list_node*)pSessionIdElement; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Queueing up new assoc session : %d ", pSessionIdElement->ucIndex); + if (eWLAN_PAL_STATUS_E_FAILURE == + wpal_list_insert_back(&pWDICtx->wptPendingAssocSessionIdQueue, pNode)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: pSessionIdElement wpal_list_insert_back failed", __func__); + WDI_ASSERT(0); + wpalMemoryFree(pSessionIdElement); + wpalMemoryFree(pEventDataQueue); + wpalMemoryFree(pEventInfo); + return WDI_STATUS_MEM_FAILURE; + } + + /*Return pending as this is what the status of the request is since it has + been queued*/ + return WDI_STATUS_PENDING; +}/*WDI_QueueNewAssocRequest*/ + +/** + @brief Utility function used by the DAL Core to help queue + an association request that cannot be processed right + away.- The assoc requests will be queued by BSSID + @param + + pWDICtx: - pointer to the WDI control block + pSession: - session in which to queue + pEventData: pointer to the event info that needs to be + queued + + @see + @return Result of the operation +*/ +WDI_Status +WDI_QueueAssocRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType* pSession, + WDI_EventInfoType* pEventData +) +{ + wpt_list_node* pNode; + WDI_EventInfoType* pEventDataQueue; + void* pEventInfo; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pSession ) || ( NULL == pWDICtx )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + Allocate memory for this and place it in the queue + ------------------------------------------------------------------------*/ + pEventDataQueue = (WDI_EventInfoType*)wpalMemoryAllocate(sizeof(WDI_EventInfoType)); + if ( NULL == pEventDataQueue ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Cannot allocate memory for queueing", __func__); + WDI_ASSERT(0); + return WDI_STATUS_MEM_FAILURE; + } + + pEventInfo = wpalMemoryAllocate(pEventData->uEventDataSize); + if ( NULL == pEventInfo ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Cannot allocate memory for queueing event data info", + __func__); + WDI_ASSERT(0); + wpalMemoryFree(pEventDataQueue); + return WDI_STATUS_MEM_FAILURE; + } + + pEventDataQueue->pCBfnc = pEventData->pCBfnc; + pEventDataQueue->pUserData = pEventData->pUserData; + pEventDataQueue->uEventDataSize = pEventData->uEventDataSize; + pEventDataQueue->wdiRequest = pEventData->wdiRequest; + pEventDataQueue->wdiResponse = pEventData->wdiResponse; + pEventDataQueue->pEventData = pEventInfo; + + wpalMemoryCopy(pEventInfo, pEventData->pEventData, pEventData->uEventDataSize); + + /*Send wpt a pointer to the node (this is the 1st element in the event data)*/ + pNode = (wpt_list_node*)pEventDataQueue; + + /*This association is currently being queued*/ + pSession->bAssocReqQueued = eWLAN_PAL_TRUE; + + if (eWLAN_PAL_STATUS_E_FAILURE == + wpal_list_insert_back(&(pSession->wptPendingQueue), pNode)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Cannot allocate memory for queueing event data info", + __func__); + WDI_ASSERT(0); + wpalMemoryFree(pEventDataQueue); + wpalMemoryFree(pEventInfo); + return WDI_STATUS_MEM_FAILURE; + } + + /*The result of this operation is pending because the request has been + queued and it will be processed at a later moment in time */ + return WDI_STATUS_PENDING; +}/*WDI_QueueAssocRequest*/ + +/** + @brief Utility function used by the DAL Core to help dequeue + an association request that was pending + The request will be queued up in front of the main + pending queue for imediate processing + @param + + pWDICtx: - pointer to the WDI control block + + + @see + @return Result of the operation +*/ +WDI_Status +WDI_DequeueAssocRequest +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_list_node* pNode = NULL; + WDI_NextSessionIdType* pSessionIdElement; + WDI_BSSSessionType* pSession; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------------*/ + if ( NULL == pWDICtx ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------ + An association has been completed => a new association can occur + Check to see if there are any pending associations -> + If so , transfer all the pending requests into the busy queue for + processing + These requests have arrived prior to the requests in the busy queue + (bc they needed to be processed in order to be placed in this queue) + => they will be placed at the front of the busy queue + ------------------------------------------------------------------------*/ + wpal_list_remove_front(&(pWDICtx->wptPendingAssocSessionIdQueue), &pNode); + + if ( NULL == pNode ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "List is empty - return"); + return WDI_STATUS_SUCCESS; + } + + /*The node actually points to the 1st element inside the Session Id struct - + just cast it back to the struct*/ + pSessionIdElement = (WDI_NextSessionIdType*)pNode; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Dequeueing new assoc session : %d ", pSessionIdElement->ucIndex); + + if ( pSessionIdElement->ucIndex < WDI_MAX_BSS_SESSIONS ) + { + pSession = &pWDICtx->aBSSSessions[pSessionIdElement->ucIndex]; + + /*Transfer all the pending requests in this assoc queue to + the front of the main waiting queue for subsequent execution*/ + wpal_list_remove_back(&(pSession->wptPendingQueue), &pNode); + while ( NULL != pNode ) + { + /*Place it in front of the main pending list*/ + wpal_list_insert_front( &(pWDICtx->wptPendingQueue), &pNode); + wpal_list_remove_back(&(pSession->wptPendingQueue), &pNode); + } + pSession->bAssocReqQueued = eWLAN_PAL_FALSE; + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Invalid session id queued up for assoc"); + WPAL_ASSERT(0); + wpalMemoryFree(pSessionIdElement); + return WDI_STATUS_E_FAILURE; + } + + /*Clean this up as it is no longer needed in order to prevent memory leak*/ + wpalMemoryFree(pSessionIdElement); + return WDI_STATUS_SUCCESS; +}/*WDI_DequeueAssocRequest*/ + +/** + @brief Utility function used by the DAL Core to clear any + pending requests - all req cb will be called with + failure and the queue will be emptied. + @param + + pWDICtx: - pointer to the WDI control block + + @see + @return Result of the operation +*/ +WDI_Status +WDI_ClearPendingRequests +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_list_node* pNode = NULL; + WDI_EventInfoType* pEventDataQueue = NULL; + WDI_ReqStatusCb pfnReqStatusCB; + void* pUserData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + wpal_list_remove_front(&(pWDICtx->wptPendingQueue), &pNode); + + /*------------------------------------------------------------------------ + Go through all the requests and fail them - this will only be called + when device is being stopped or an error was detected - either case the + pending requests can no longer be sent down to HAL + ------------------------------------------------------------------------*/ + while( pNode ) + { + /*The node actually points to the 1st element inside the Event Data struct - + just cast it back to the struct*/ + pEventDataQueue = (WDI_EventInfoType*)pNode; + + WDI_ExtractRequestCBFromEvent(pEventDataQueue, &pfnReqStatusCB, &pUserData); + if ( NULL != pfnReqStatusCB ) + { + /*Fail the request*/ + pfnReqStatusCB( WDI_STATUS_E_FAILURE, pUserData); + } + /* Free data - that was allocated when queueing */ + if ( pEventDataQueue->pEventData != NULL ) + { + wpalMemoryFree(pEventDataQueue->pEventData); + } + wpalMemoryFree(pEventDataQueue); + + if (wpal_list_remove_front(&(pWDICtx->wptPendingQueue), &pNode) != eWLAN_PAL_STATUS_SUCCESS) + { + break; + } + } + + return WDI_STATUS_SUCCESS; +}/*WDI_ClearPendingRequests*/ + +/** + @brief Helper routine used to init the BSS Sessions in the WDI control block + + + @param pWDICtx: pointer to the WLAN DAL context + + @see +*/ +void +WDI_ResetAssocSessions +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_uint8 i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + No Sanity check + -------------------------------------------------------------------------*/ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + wpalMemoryZero( &pWDICtx->aBSSSessions[i], sizeof(WDI_BSSSessionType) ); + pWDICtx->aBSSSessions[i].wdiAssocState = WDI_ASSOC_INIT_ST; + pWDICtx->aBSSSessions[i].bcastStaIdx = WDI_STA_INVALID_IDX; + pWDICtx->aBSSSessions[i].ucBSSIdx = WDI_BSS_INVALID_IDX; + } +}/*WDI_ResetAssocSessions*/ + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + macBSSID: BSSID of the session + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSession +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr macBSSID, + WDI_BSSSessionType** ppSession +) +{ + wpt_uint8 i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == ppSession ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + return WDI_MAX_BSS_SESSIONS; + } + + *ppSession = NULL; + + /*------------------------------------------------------------------------ + Search for a session that matches the BSSID + ------------------------------------------------------------------------*/ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + if ( (pWDICtx->aBSSSessions[i].bInUse == eWLAN_PAL_TRUE) && + (eWLAN_PAL_TRUE == + wpalMemoryCompare(pWDICtx->aBSSSessions[i].macBSSID, macBSSID, + WDI_MAC_ADDR_LEN)) ) + { + /*Found the session*/ + *ppSession = &pWDICtx->aBSSSessions[i]; + return i; + } + } + + return i; +}/*WDI_FindAssocSession*/ + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + ucBSSIdx: BSS Index of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSessionByBSSIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 ucBSSIdx, + WDI_BSSSessionType** ppSession +) +{ + wpt_uint8 i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == ppSession ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + return WDI_MAX_BSS_SESSIONS; + } + + *ppSession = NULL; + + /*------------------------------------------------------------------------ + Search for a session that matches the BSSID + ------------------------------------------------------------------------*/ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + if ( ucBSSIdx == pWDICtx->aBSSSessions[i].ucBSSIdx ) + { + /*Found the session*/ + *ppSession = &pWDICtx->aBSSSessions[i]; + return i; + } + } + + return i; +}/*WDI_FindAssocSessionByBSSIdx*/ + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + ucBSSIdx: BSS Index of the session + ppSession: out pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindAssocSessionByIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint16 usIdx, + WDI_BSSSessionType** ppSession +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == ppSession || usIdx >= WDI_MAX_BSS_SESSIONS ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + return WDI_MAX_BSS_SESSIONS; + } + + /*Found the session*/ + *ppSession = &pWDICtx->aBSSSessions[usIdx]; + + return usIdx; + +}/*WDI_FindAssocSessionByBSSIdx*/ + +/** + @brief Helper routine used to find an empty session in the WDI + CB + + + @param pWDICtx: pointer to the WLAN DAL context + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +wpt_uint8 +WDI_FindEmptySession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType** ppSession +) +{ + wpt_uint8 i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == ppSession ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + return WDI_MAX_BSS_SESSIONS; + } + + *ppSession = NULL; + + /*------------------------------------------------------------------------ + Search for a session that it is not in use + ------------------------------------------------------------------------*/ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + if ( ! pWDICtx->aBSSSessions[i].bInUse ) + { + /*Found a session*/ + *ppSession = &pWDICtx->aBSSSessions[i]; + return i; + } + } + + return i; +}/*WDI_FindEmptySession*/ + + +/** + @brief Helper routine used to get the total count of active + sessions + + + @param pWDICtx: pointer to the WLAN DAL context + macBSSID: pointer to BSSID. If NULL, get all the session. + If not NULL, count ActiveSession by excluding (TRUE) or including (FALSE) skipBSSID. + skipBSSID: if TRUE, get all the sessions except matching to macBSSID. If FALSE, get all session. + This argument is ignored if macBSSID is NULL. + @see + @return Number of sessions in use +*/ +wpt_uint8 +WDI_GetActiveSessionsCount +( + WDI_ControlBlockType* pWDICtx, + wpt_macAddr macBSSID, + wpt_boolean skipBSSID +) +{ + wpt_uint8 i, ucCount = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Count all sessions in use + ------------------------------------------------------------------------*/ + for ( i = 0; i < WDI_MAX_BSS_SESSIONS; i++ ) + { + if ( macBSSID && skipBSSID && + (eWLAN_PAL_TRUE == + wpalMemoryCompare(pWDICtx->aBSSSessions[i].macBSSID, macBSSID, + WDI_MAC_ADDR_LEN))) + { + continue; + } + else if ( pWDICtx->aBSSSessions[i].bInUse ) + { + ucCount++; + } + } + + return ucCount; +}/*WDI_GetActiveSessionsCount*/ + +/** + @brief Helper routine used to delete session in the WDI + CB + + + @param pWDICtx: pointer to the WLAN DAL context + pSession: pointer to the session (if found) + + @see + @return Index of the session in the array +*/ +void +WDI_DeleteSession +( + WDI_ControlBlockType* pWDICtx, + WDI_BSSSessionType* ppSession +) +{ + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ( NULL == ppSession ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + return ; + } + + /*------------------------------------------------------------------------ + Reset the entries int session + ------------------------------------------------------------------------*/ + wpal_list_destroy(&ppSession->wptPendingQueue); + wpalMemoryZero(ppSession, sizeof(*ppSession)); + ppSession->wdiAssocState = WDI_ASSOC_INIT_ST; + ppSession->bInUse = eWLAN_PAL_FALSE; + ppSession->wdiBssType = WDI_INFRASTRUCTURE_MODE; + wpal_list_init(&ppSession->wptPendingQueue); + +}/*WDI_DeleteSession*/ + +/** + @brief Utility function to add the broadcast STA to the the STA table. + The bcast STA ID is assigned by HAL and must be valid. + @param + + WDI_AddStaParams: - pointer to the WDI Add STA params + usBcastStaIdx: - Broadcast STA index passed by HAL + + @see + @return void +*/ +void +WDI_AddBcastSTAtoSTATable +( + WDI_ControlBlockType* pWDICtx, + WDI_AddStaParams * staParams, + wpt_uint16 usBcastStaIdx +) +{ + WDI_AddStaParams wdiAddSTAParam = {0}; + wpt_macAddr bcastMacAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*--------------------------------------------------------------------- + Sanity check + ---------------------------------------------------------------------*/ + if ( NULL == staParams ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + + return; + } + + wdiAddSTAParam.bcastDpuIndex = staParams->bcastDpuIndex; + wdiAddSTAParam.bcastDpuSignature = staParams->bcastDpuSignature; + wdiAddSTAParam.bcastMgmtDpuIndex = staParams->bcastMgmtDpuIndex; + wdiAddSTAParam.bcastMgmtDpuSignature = staParams->bcastMgmtDpuSignature; + wdiAddSTAParam.dpuIndex = staParams->dpuIndex; + wdiAddSTAParam.dpuSig = staParams->dpuSig; + wpalMemoryCopy( wdiAddSTAParam.macBSSID, staParams->macBSSID, + WDI_MAC_ADDR_LEN ); + wpalMemoryCopy( wdiAddSTAParam.staMacAddr, bcastMacAddr, WDI_MAC_ADDR_LEN ); + wdiAddSTAParam.ucBSSIdx = staParams->ucBSSIdx; + wdiAddSTAParam.ucHTCapable = staParams->ucHTCapable; + wdiAddSTAParam.ucRmfEnabled = staParams->ucRmfEnabled; + wdiAddSTAParam.ucStaType = WDI_STA_ENTRY_BCAST; + wdiAddSTAParam.ucWmmEnabled = staParams->ucWmmEnabled; + wdiAddSTAParam.ucSTAIdx = usBcastStaIdx; + + (void)WDI_STATableAddSta(pWDICtx,&wdiAddSTAParam); +} + +/** + @brief NV blob will be divided into fragments of size 4kb and + Sent to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call + */ + +WDI_Status WDI_SendNvBlobReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + + tHalNvImgDownloadReqMsg halNvImgDownloadParam; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usCurrentFragmentSize =0; + wpt_uint8* pSrcBuffer = NULL; + WDI_NvDownloadReqParamsType* pwdiNvDownloadReqParams =NULL ; + WDI_NvDownloadRspCb wdiNvDownloadRspCb; + + wdiNvDownloadRspCb = (WDI_NvDownloadRspCb)pEventData->pCBfnc; + WDI_ASSERT(NULL != wdiNvDownloadRspCb); + pwdiNvDownloadReqParams = (WDI_NvDownloadReqParamsType*)pEventData->pEventData; + + /* Sanity Check is done by the caller */ + pSrcBuffer =(wpt_uint8 *) pwdiNvDownloadReqParams->wdiBlobInfo.pBlobAddress; + + /* Update the current Fragment Number */ + pWDICtx->wdiNvBlobInfo.usCurrentFragment += 1; + + /*Update the HAL REQ structure */ + /*HAL maintaining the fragment count as 0,1,2...n where at WDI it is represented as 1,2,3.. n*/ + halNvImgDownloadParam.nvImageReqParams.fragNumber = + pWDICtx->wdiNvBlobInfo.usCurrentFragment-1; + + /* Divide the NV Image to size of 'FRAGMENT_SIZE' fragments and send it to HAL. + If the size of the Image is less than 'FRAGMENT_SIZE' then in one iteration total + image will be sent to HAL*/ + + if(pWDICtx->wdiNvBlobInfo.usTotalFragment + == pWDICtx->wdiNvBlobInfo.usCurrentFragment) + { + /* Taking care of boundry condition */ + if( !(usCurrentFragmentSize = + pwdiNvDownloadReqParams->wdiBlobInfo.uBlobSize%FRAGMENT_SIZE )) + usCurrentFragmentSize = FRAGMENT_SIZE; + + /*Update the HAL REQ structure */ + halNvImgDownloadParam.nvImageReqParams.isLastFragment = 1; + halNvImgDownloadParam.nvImageReqParams.nvImgBufferSize= usCurrentFragmentSize; + + } + else + { + usCurrentFragmentSize = FRAGMENT_SIZE; + + /*Update the HAL REQ structure */ + halNvImgDownloadParam.nvImageReqParams.isLastFragment =0; + halNvImgDownloadParam.nvImageReqParams.nvImgBufferSize = usCurrentFragmentSize; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,WDI_NV_DOWNLOAD_REQ, + sizeof(halNvImgDownloadParam.nvImageReqParams)+ usCurrentFragmentSize, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < + (usDataOffset + sizeof(halNvImgDownloadParam.nvImageReqParams) + usCurrentFragmentSize ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in NV Download req %p %p ", + pEventData, pwdiNvDownloadReqParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Copying the Hal NV download REQ structure */ + wpalMemoryCopy(pSendBuffer + usDataOffset , + &halNvImgDownloadParam.nvImageReqParams ,sizeof(tHalNvImgDownloadReqParams)); + + /* Appending the NV image fragment */ + wpalMemoryCopy(pSendBuffer + usDataOffset + sizeof(tHalNvImgDownloadReqParams), + (void *)(pSrcBuffer + halNvImgDownloadParam.nvImageReqParams.fragNumber * FRAGMENT_SIZE), + usCurrentFragmentSize); + + pWDICtx->wdiReqStatusCB = pwdiNvDownloadReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiNvDownloadReqParams->pUserData; + + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiNvDownloadRspCb, pEventData->pUserData, + WDI_NV_DOWNLOAD_RESP); + +} +/*============================================================================ + Helper inline functions for + ============================================================================*/ +/** + @brief Helper routine used to find a session based on the BSSID + @param pContext: pointer to the WLAN DAL context + @param pDPContext: pointer to the Datapath context + + @see + @return +*/ +WPT_INLINE void +WDI_DS_AssignDatapathContext (void *pContext, void *pDPContext) +{ + WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext; + + pCB->pDPContext = pDPContext; + return; +} + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pContext: pointer to the WLAN DAL context + + @see + @return pointer to Datapath context +*/ +WPT_INLINE void * +WDI_DS_GetDatapathContext (void *pContext) +{ + WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext; + return pCB->pDPContext; +} +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pContext: pointer to the WLAN DAL context + @param pDTDriverContext: pointer to the Transport Driver context + + @see + @return void +*/ +WPT_INLINE void +WDT_AssignTransportDriverContext (void *pContext, void *pDTDriverContext) +{ + WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext; + + pCB->pDTDriverContext = pDTDriverContext; + return; +} + +/** + @brief Helper routine used to find a session based on the BSSID + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return pointer to datapath context +*/ +WPT_INLINE void * +WDT_GetTransportDriverContext (void *pContext) +{ + WDI_ControlBlockType *pCB = (WDI_ControlBlockType *)pContext; + return(pCB->pDTDriverContext); +} + +/*============================================================================ + Helper inline converters + ============================================================================*/ +/*Convert WDI driver type into HAL driver type*/ +WPT_STATIC WPT_INLINE WDI_Status +WDI_HAL_2_WDI_STATUS +( + eHalStatus halStatus +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( halStatus ) + { + case eHAL_STATUS_SUCCESS: + case eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO: + case eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO: + return WDI_STATUS_SUCCESS; + case eHAL_STATUS_FAILURE: + return WDI_STATUS_E_FAILURE; + case eHAL_STATUS_FAILED_ALLOC: + return WDI_STATUS_MEM_FAILURE; + /*The rest of the HAL error codes must be kept hidden from the UMAC as + they refer to specific internal modules of our device*/ + default: + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Fwr halStatus:%d", halStatus); + return WDI_STATUS_DEV_INTERNAL_FAILURE; + } + + return WDI_STATUS_E_FAILURE; +}/*WDI_HAL_2_WDI_STATUS*/ + +/*Convert WDI request type into HAL request type*/ +WPT_STATIC WPT_INLINE tHalHostMsgType +WDI_2_HAL_REQ_TYPE +( + WDI_RequestEnumType wdiReqType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiReqType ) + { + case WDI_START_REQ: + return WLAN_HAL_START_REQ; + case WDI_STOP_REQ: + return WLAN_HAL_STOP_REQ; + case WDI_INIT_SCAN_REQ: + return WLAN_HAL_INIT_SCAN_REQ; + case WDI_START_SCAN_REQ: + return WLAN_HAL_START_SCAN_REQ; + case WDI_END_SCAN_REQ: + return WLAN_HAL_END_SCAN_REQ; + case WDI_FINISH_SCAN_REQ: + return WLAN_HAL_FINISH_SCAN_REQ; + case WDI_JOIN_REQ: + return WLAN_HAL_JOIN_REQ; + case WDI_CONFIG_BSS_REQ: + return WLAN_HAL_CONFIG_BSS_REQ; + case WDI_DEL_BSS_REQ: + return WLAN_HAL_DELETE_BSS_REQ; + case WDI_POST_ASSOC_REQ: + return WLAN_HAL_POST_ASSOC_REQ; + case WDI_DEL_STA_REQ: + return WLAN_HAL_DELETE_STA_REQ; + case WDI_SET_BSS_KEY_REQ: + return WLAN_HAL_SET_BSSKEY_REQ; + case WDI_RMV_BSS_KEY_REQ: + return WLAN_HAL_RMV_BSSKEY_REQ; + case WDI_SET_STA_KEY_REQ: + return WLAN_HAL_SET_STAKEY_REQ; + case WDI_RMV_STA_KEY_REQ: + return WLAN_HAL_RMV_STAKEY_REQ; + case WDI_SET_STA_BCAST_KEY_REQ: + return WLAN_HAL_SET_BCASTKEY_REQ; + case WDI_RMV_STA_BCAST_KEY_REQ: + //Some conflict in the old code - check this: return WLAN_HAL_RMV_BCASTKEY_REQ; + return WLAN_HAL_RMV_STAKEY_REQ; + case WDI_ADD_TS_REQ: + return WLAN_HAL_ADD_TS_REQ; + case WDI_DEL_TS_REQ: + return WLAN_HAL_DEL_TS_REQ; + case WDI_UPD_EDCA_PRMS_REQ: + return WLAN_HAL_UPD_EDCA_PARAMS_REQ; + case WDI_ADD_BA_REQ: + return WLAN_HAL_ADD_BA_REQ; + case WDI_DEL_BA_REQ: + return WLAN_HAL_DEL_BA_REQ; +#ifdef FEATURE_WLAN_ESE + case WDI_TSM_STATS_REQ: + return WLAN_HAL_TSM_STATS_REQ; +#endif + case WDI_CH_SWITCH_REQ: + return WLAN_HAL_CH_SWITCH_REQ; + case WDI_CONFIG_STA_REQ: + return WLAN_HAL_CONFIG_STA_REQ; + case WDI_SET_LINK_ST_REQ: + return WLAN_HAL_SET_LINK_ST_REQ; + case WDI_GET_STATS_REQ: + return WLAN_HAL_GET_STATS_REQ; + case WDI_UPDATE_CFG_REQ: + return WLAN_HAL_UPDATE_CFG_REQ; + case WDI_ADD_BA_SESSION_REQ: + return WLAN_HAL_ADD_BA_SESSION_REQ; + case WDI_TRIGGER_BA_REQ: + return WLAN_HAL_TRIGGER_BA_REQ; + case WDI_UPD_BCON_PRMS_REQ: + return WLAN_HAL_UPDATE_BEACON_REQ; + case WDI_SND_BCON_REQ: + return WLAN_HAL_SEND_BEACON_REQ; + case WDI_UPD_PROBE_RSP_TEMPLATE_REQ: + return WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ; + case WDI_SET_MAX_TX_POWER_REQ: + return WLAN_HAL_SET_MAX_TX_POWER_REQ; + case WDI_SET_MAX_TX_POWER_PER_BAND_REQ: + return WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ; + case WDI_SET_TX_POWER_REQ: + return WLAN_HAL_SET_TX_POWER_REQ; + case WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ: + return WLAN_HAL_SET_P2P_GONOA_REQ; +#ifdef FEATURE_WLAN_TDLS + case WDI_TDLS_LINK_ESTABLISH_REQ: + return WLAN_HAL_TDLS_LINK_ESTABLISHED_REQ; + case WDI_TDLS_CHAN_SWITCH_REQ: + return WLAN_HAL_TDLS_CHAN_SWITCH_REQ; +#endif + case WDI_ENTER_IMPS_REQ: + return WLAN_HAL_ENTER_IMPS_REQ; + case WDI_EXIT_IMPS_REQ: + return WLAN_HAL_EXIT_IMPS_REQ; + case WDI_ENTER_BMPS_REQ: + return WLAN_HAL_ENTER_BMPS_REQ; + case WDI_EXIT_BMPS_REQ: + return WLAN_HAL_EXIT_BMPS_REQ; + case WDI_ENTER_UAPSD_REQ: + return WLAN_HAL_ENTER_UAPSD_REQ; + case WDI_EXIT_UAPSD_REQ: + return WLAN_HAL_EXIT_UAPSD_REQ; + case WDI_SET_UAPSD_PARAM_REQ: + return WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ; + case WDI_UPDATE_UAPSD_PARAM_REQ: + return WLAN_HAL_UPDATE_UAPSD_PARAM_REQ; + case WDI_CONFIGURE_RXP_FILTER_REQ: + return WLAN_HAL_CONFIGURE_RXP_FILTER_REQ; + case WDI_SET_BEACON_FILTER_REQ: + return WLAN_HAL_ADD_BCN_FILTER_REQ; + case WDI_REM_BEACON_FILTER_REQ: + return WLAN_HAL_REM_BCN_FILTER_REQ; + case WDI_SET_RSSI_THRESHOLDS_REQ: + return WLAN_HAL_SET_RSSI_THRESH_REQ; + case WDI_HOST_OFFLOAD_REQ: + return WLAN_HAL_HOST_OFFLOAD_REQ; + case WDI_WOWL_ADD_BC_PTRN_REQ: + return WLAN_HAL_ADD_WOWL_BCAST_PTRN; + case WDI_WOWL_DEL_BC_PTRN_REQ: + return WLAN_HAL_DEL_WOWL_BCAST_PTRN; + case WDI_WOWL_ENTER_REQ: + return WLAN_HAL_ENTER_WOWL_REQ; + case WDI_WOWL_EXIT_REQ: + return WLAN_HAL_EXIT_WOWL_REQ; + case WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ: + return WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ; + case WDI_NV_DOWNLOAD_REQ: + return WLAN_HAL_DOWNLOAD_NV_REQ; + case WDI_FLUSH_AC_REQ: + return WLAN_HAL_TL_HAL_FLUSH_AC_REQ; + case WDI_BTAMP_EVENT_REQ: + return WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ; +#ifdef WLAN_FEATURE_VOWIFI_11R + case WDI_AGGR_ADD_TS_REQ: + return WLAN_HAL_AGGR_ADD_TS_REQ; +#endif /* WLAN_FEATURE_VOWIFI_11R */ + case WDI_FTM_CMD_REQ: + return WLAN_HAL_PROCESS_PTT_REQ; + case WDI_ADD_STA_SELF_REQ: + return WLAN_HAL_ADD_STA_SELF_REQ; + case WDI_DEL_STA_SELF_REQ: + return WLAN_HAL_DEL_STA_SELF_REQ; +#ifdef FEATURE_OEM_DATA_SUPPORT + case WDI_START_OEM_DATA_REQ: + return WLAN_HAL_START_OEM_DATA_REQ; +#endif /* FEATURE_OEM_DATA_SUPPORT */ + case WDI_HOST_RESUME_REQ: + return WLAN_HAL_HOST_RESUME_REQ; + case WDI_HOST_SUSPEND_IND: + return WLAN_HAL_HOST_SUSPEND_IND; + case WDI_TRAFFIC_STATS_IND: + return WLAN_HAL_CLASS_B_STATS_IND; +#ifdef WLAN_FEATURE_11W + case WDI_EXCLUDE_UNENCRYPTED_IND: + return WLAN_HAL_EXCLUDE_UNENCRYPTED_IND; +#endif + case WDI_KEEP_ALIVE_REQ: + return WLAN_HAL_KEEP_ALIVE_REQ; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case WDI_ROAM_SCAN_OFFLOAD_REQ: + return WLAN_ROAM_SCAN_OFFLOAD_REQ; +#endif +#ifdef FEATURE_WLAN_SCAN_PNO + case WDI_SET_PREF_NETWORK_REQ: + return WLAN_HAL_SET_PREF_NETWORK_REQ; + case WDI_SET_RSSI_FILTER_REQ: + return WLAN_HAL_SET_RSSI_FILTER_REQ; + case WDI_UPDATE_SCAN_PARAMS_REQ: + return WLAN_HAL_UPDATE_SCAN_PARAM_REQ; +#endif // FEATURE_WLAN_SCAN_PNO + case WDI_SET_TX_PER_TRACKING_REQ: + return WLAN_HAL_SET_TX_PER_TRACKING_REQ; +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WDI_8023_MULTICAST_LIST_REQ: + return WLAN_HAL_8023_MULTICAST_LIST_REQ; + case WDI_RECEIVE_FILTER_SET_FILTER_REQ: + return WLAN_HAL_SET_PACKET_FILTER_REQ; + case WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ: + return WLAN_HAL_PACKET_FILTER_MATCH_COUNT_REQ; + case WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ: + return WLAN_HAL_CLEAR_PACKET_FILTER_REQ; +#endif // WLAN_FEATURE_PACKET_FILTERING + case WDI_HAL_DUMP_CMD_REQ: + return WLAN_HAL_DUMP_COMMAND_REQ; +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WDI_GTK_OFFLOAD_REQ: + return WLAN_HAL_GTK_OFFLOAD_REQ; + case WDI_GTK_OFFLOAD_GETINFO_REQ: + return WLAN_HAL_GTK_OFFLOAD_GETINFO_REQ; +#endif /* WLAN_FEATURE_GTK_OFFLOAD */ + + case WDI_INIT_SCAN_CON_REQ: + return WLAN_HAL_INIT_SCAN_CON_REQ; + case WDI_SET_POWER_PARAMS_REQ: + return WLAN_HAL_SET_POWER_PARAMS_REQ; + case WDI_SET_TM_LEVEL_REQ: + return WLAN_HAL_SET_THERMAL_MITIGATION_REQ; + case WDI_FEATURE_CAPS_EXCHANGE_REQ: + return WLAN_HAL_FEATURE_CAPS_EXCHANGE_REQ; +#ifdef WLAN_FEATURE_11AC + case WDI_UPDATE_VHT_OP_MODE_REQ: + return WLAN_HAL_UPDATE_VHT_OP_MODE_REQ; +#endif + case WDI_GET_ROAM_RSSI_REQ: + return WLAN_HAL_GET_ROAM_RSSI_REQ; + case WDI_DHCP_START_IND: + return WLAN_HAL_DHCP_START_IND; + case WDI_DHCP_STOP_IND: + return WLAN_HAL_DHCP_STOP_IND; +#ifdef FEATURE_WLAN_LPHB + case WDI_LPHB_CFG_REQ: + return WLAN_HAL_LPHB_CFG_REQ; +#endif /* FEATURE_WLAN_LPHB */ + case WDI_ADD_PERIODIC_TX_PATTERN_IND: + return WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND; + case WDI_DEL_PERIODIC_TX_PATTERN_IND: + return WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND; +#ifdef WLAN_FEATURE_RMC + case WDI_RMC_RULER_REQ: + return WLAN_HAL_RMC_RULER_REQ; + case WDI_RMC_UPDATE_IND: + return WLAN_HAL_RMC_UPDATE_IND; + case WDI_HAL_IBSS_PEER_INFO_REQ: + return WLAN_HAL_GET_IBSS_PEER_INFO_REQ; +#endif /* WLAN_FEATURE_RMC */ + case WDI_RATE_UPDATE_IND: + return WLAN_HAL_RATE_UPDATE_IND; + +#ifdef FEATURE_WLAN_BATCH_SCAN + case WDI_SET_BATCH_SCAN_REQ: + return WLAN_HAL_BATCHSCAN_SET_REQ; + case WDI_STOP_BATCH_SCAN_IND: + return WLAN_HAL_BATCHSCAN_STOP_IND; + case WDI_TRIGGER_BATCH_SCAN_RESULT_IND: + return WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND; +#endif + +#ifdef WLAN_FEATURE_RMC + case WDI_TX_FAIL_MONITOR_IND: + return WLAN_HAL_TX_FAIL_MONITOR_IND; +#endif + + case WDI_START_HT40_OBSS_SCAN_IND: + return WLAN_HAL_START_HT40_OBSS_SCAN_IND; + case WDI_STOP_HT40_OBSS_SCAN_IND: + return WLAN_HAL_STOP_HT40_OBSS_SCAN_IND; + case WDI_UPDATE_CHAN_REQ: + return WLAN_HAL_UPDATE_CHANNEL_LIST_REQ; + case WDI_CH_SWITCH_REQ_V1: + return WLAN_HAL_CH_SWITCH_V1_REQ; + case WDI_GET_BCN_MISS_RATE_REQ: + return WLAN_HAL_GET_BCN_MISS_RATE_REQ; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case WDI_LL_STATS_SET_REQ: + return WLAN_HAL_LL_SET_STATS_REQ; + case WDI_LL_STATS_GET_REQ: + return WLAN_HAL_LL_GET_STATS_REQ; + case WDI_LL_STATS_CLEAR_REQ: + return WLAN_HAL_LL_CLEAR_STATS_REQ; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + case WDI_EXTSCAN_START_REQ: + return WLAN_HAL_EXT_SCAN_START_REQ; + case WDI_EXTSCAN_STOP_REQ: + return WLAN_HAL_EXT_SCAN_STOP_REQ; + case WDI_EXTSCAN_GET_CACHED_RESULTS_REQ: + return WLAN_HAL_EXT_SCAN_GET_SCAN_REQ; + case WDI_EXTSCAN_GET_CAPABILITIES_REQ: + return WLAN_HAL_EXT_SCAN_GET_CAP_REQ; + case WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ: + return WLAN_HAL_BSSID_HOTLIST_SET_REQ; + case WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ: + return WLAN_HAL_BSSID_HOTLIST_RESET_REQ; + case WDI_HIGH_PRIORITY_DATA_INFO_IND: + return WLAN_HAL_HIGH_PRIORITY_DATA_INFO_REQ; +#endif /* WLAN_FEATURE_EXTSCAN */ + case WDI_SPOOF_MAC_ADDR_REQ: + return WLAN_HAL_MAC_SPOOFED_SCAN_REQ; + case WDI_GET_FW_STATS_REQ: + return WLAN_HAL_FW_STATS_REQ; + case WDI_ENCRYPT_MSG_REQ: + return WLAN_HAL_ENCRYPT_DATA_REQ; + case WDI_FW_LOGGING_INIT_REQ: + return WLAN_HAL_FW_LOGGING_INIT_REQ; + case WDI_GET_FRAME_LOG_REQ: + return WLAN_HAL_GET_FRAME_LOG_REQ; + case WDI_NAN_REQUEST: + return WLAN_HAL_NAN_REQ; + case WDI_SET_RTS_CTS_HTVHT_IND: + return WLAN_HAL_SET_RTS_CTS_HTVHT_IND; + case WDI_MON_START_REQ: + return WLAN_HAL_ENABLE_MONITOR_MODE_REQ; + case WDI_MON_STOP_REQ: + return WLAN_HAL_DISABLE_MONITOR_MODE_REQ; + case WDI_FW_LOGGING_DXE_DONE_IND: + return WLAN_HAL_FW_LOGGING_DXE_DONE_IND; + case WDI_FATAL_EVENT_LOGGING_REQ: + return WLAN_HAL_FATAL_EVENT_LOGGING_REQ; + case WDI_SEND_FREQ_RANGE_CONTROL_IND: + return WLAN_HAL_SEND_FREQ_RANGE_CONTROL_IND; + case WDI_FWR_MEM_DUMP_REQ: + return WLAN_HAL_FW_MEMORY_DUMP_REQ; + case WDI_START_RSSI_MONITOR_REQ: + return WLAN_HAL_START_RSSI_MONITORING_REQ; + case WDI_STOP_RSSI_MONITOR_REQ: + return WLAN_HAL_STOP_RSSI_MONITORING_REQ; + case WDI_WIFI_CONFIG_SET_REQ: + return WLAN_HAL_WIFI_CONFIG_SET_PARAMS_REQ; + case WDI_START_OEM_DATA_REQ_IND_NEW: + return WLAN_HAL_START_OEM_DATA_REQ_IND_NEW; + case WDI_ANTENNA_DIVERSITY_SELECTION_REQ: + return WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_REQ; + case WDI_MODIFY_ROAM_PARAMS_IND: + return WLAN_HAL_MODIFY_ROAM_PARAMS_IND; + case WDI_SET_ALLOWED_ACTION_FRAMES_IND: + return WLAN_HAL_SET_ALLOWED_ACTION_FRAMES_IND; + case WDI_SET_AP_FIND_IND: + return WLAN_HAL_QRF_AP_FIND_COMMAND; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case WDI_PER_ROAM_SCAN_OFFLOAD_REQ: + return WLAN_HAL_SET_PER_ROAM_CONFIG_REQ; + case WDI_PER_ROAM_SCAN_TRIGGER_REQ: + return WLAN_HAL_PER_ROAM_SCAN_TRIGGER_REQ; +#endif +#ifdef SAP_AUTH_OFFLOAD + case WDI_PROCESS_SAP_AUTH_OFFLOAD_IND: + return WLAN_HAL_SAP_AUTH_OFFLOAD_IND; +#endif +#ifdef DHCP_SERVER_OFFLOAD + case WDI_DHCP_SERVER_OFFLOAD_REQ: + return WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ; +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + case WDI_MDNS_ENABLE_OFFLOAD_REQ: + return WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ; + case WDI_MDNS_FQDN_OFFLOAD_REQ: + return WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ; + case WDI_MDNS_RESP_OFFLOAD_REQ: + return WLAN_HAL_MDNS_RESP_OFFLOAD_REQ; + case WDI_MDNS_STATS_OFFLOAD_REQ: + return WLAN_HAL_MDNS_STATS_OFFLOAD_REQ; +#endif /* MDNS_OFFLOAD */ + case WDI_CAP_TSF_REQ: + return WLAN_HAL_CAPTURE_GET_TSF_TSTAMP; + case WDI_GET_TSF_REQ: + return WLAN_HAL_CAPTURE_GET_TSF_TSTAMP; + case WDI_FW_ARP_STATS_REQ: + return WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ; + case WDI_FW_GET_ARP_STATS_REQ: + return WLAN_HAL_FW_GET_ARP_STATS_REQ; + default: + return WLAN_HAL_MSG_MAX; + } + +}/*WDI_2_HAL_REQ_TYPE*/ + +/*Convert WDI response type into HAL response type*/ +WPT_STATIC WPT_INLINE WDI_ResponseEnumType +HAL_2_WDI_RSP_TYPE +( + tHalHostMsgType halMsg +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( halMsg ) + { + case WLAN_HAL_START_RSP: + return WDI_START_RESP; + case WLAN_HAL_STOP_RSP: + return WDI_STOP_RESP; + case WLAN_HAL_INIT_SCAN_RSP: + return WDI_INIT_SCAN_RESP; + case WLAN_HAL_START_SCAN_RSP: + return WDI_START_SCAN_RESP; + case WLAN_HAL_END_SCAN_RSP: + return WDI_END_SCAN_RESP; + case WLAN_HAL_FINISH_SCAN_RSP: + return WDI_FINISH_SCAN_RESP; + case WLAN_HAL_CONFIG_STA_RSP: + return WDI_CONFIG_STA_RESP; + case WLAN_HAL_DELETE_STA_RSP: + return WDI_DEL_STA_RESP; + case WLAN_HAL_CONFIG_BSS_RSP: + return WDI_CONFIG_BSS_RESP; + case WLAN_HAL_DELETE_BSS_RSP: + return WDI_DEL_BSS_RESP; + case WLAN_HAL_JOIN_RSP: + return WDI_JOIN_RESP; + case WLAN_HAL_POST_ASSOC_RSP: + return WDI_POST_ASSOC_RESP; + case WLAN_HAL_SET_BSSKEY_RSP: + return WDI_SET_BSS_KEY_RESP; + case WLAN_HAL_SET_STAKEY_RSP: + return WDI_SET_STA_KEY_RESP; + case WLAN_HAL_RMV_BSSKEY_RSP: + return WDI_RMV_BSS_KEY_RESP; + case WLAN_HAL_RMV_STAKEY_RSP: + return WDI_RMV_STA_KEY_RESP; + case WLAN_HAL_SET_BCASTKEY_RSP: + return WDI_SET_STA_BCAST_KEY_RESP; + //Some conflict in the old code - check this: case WLAN_HAL_RMV_BCASTKEY_RSP: + // return WDI_RMV_STA_BCAST_KEY_RESP; + case WLAN_HAL_ADD_TS_RSP: + return WDI_ADD_TS_RESP; + case WLAN_HAL_DEL_TS_RSP: + return WDI_DEL_TS_RESP; + case WLAN_HAL_UPD_EDCA_PARAMS_RSP: + return WDI_UPD_EDCA_PRMS_RESP; + case WLAN_HAL_ADD_BA_RSP: + return WDI_ADD_BA_RESP; + case WLAN_HAL_DEL_BA_RSP: + return WDI_DEL_BA_RESP; +#ifdef FEATURE_WLAN_ESE + case WLAN_HAL_TSM_STATS_RSP: + return WDI_TSM_STATS_RESP; +#endif + case WLAN_HAL_CH_SWITCH_RSP: + return WDI_CH_SWITCH_RESP; + case WLAN_HAL_SET_LINK_ST_RSP: + return WDI_SET_LINK_ST_RESP; + case WLAN_HAL_GET_STATS_RSP: + return WDI_GET_STATS_RESP; + case WLAN_HAL_UPDATE_CFG_RSP: + return WDI_UPDATE_CFG_RESP; + case WLAN_HAL_ADD_BA_SESSION_RSP: + return WDI_ADD_BA_SESSION_RESP; + case WLAN_HAL_TRIGGER_BA_RSP: + return WDI_TRIGGER_BA_RESP; + case WLAN_HAL_UPDATE_BEACON_RSP: + return WDI_UPD_BCON_PRMS_RESP; + case WLAN_HAL_SEND_BEACON_RSP: + return WDI_SND_BCON_RESP; + case WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP: + return WDI_UPD_PROBE_RSP_TEMPLATE_RESP; + /*Indications*/ + case WLAN_HAL_RSSI_NOTIFICATION_IND: + return WDI_HAL_RSSI_NOTIFICATION_IND; + case WLAN_HAL_MISSED_BEACON_IND: + return WDI_HAL_MISSED_BEACON_IND; + case WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND: + return WDI_HAL_UNKNOWN_ADDR2_FRAME_RX_IND; + case WLAN_HAL_MIC_FAILURE_IND: + return WDI_HAL_MIC_FAILURE_IND; + case WLAN_HAL_FATAL_ERROR_IND: + return WDI_HAL_FATAL_ERROR_IND; + case WLAN_HAL_DELETE_STA_CONTEXT_IND: + return WDI_HAL_DEL_STA_IND; + case WLAN_HAL_COEX_IND: + return WDI_HAL_COEX_IND; + case WLAN_HAL_OTA_TX_COMPL_IND: + return WDI_HAL_TX_COMPLETE_IND; + case WLAN_HAL_P2P_NOA_ATTR_IND: + return WDI_HAL_P2P_NOA_ATTR_IND; + case WLAN_HAL_P2P_NOA_START_IND: + return WDI_HAL_P2P_NOA_START_IND; + case WLAN_HAL_DEL_BA_IND: + return WDI_HAL_DEL_BA_IND; + case WLAN_HAL_TX_PER_HIT_IND: + return WDI_HAL_TX_PER_HIT_IND; + case WLAN_HAL_SET_MAX_TX_POWER_RSP: + return WDI_SET_MAX_TX_POWER_RESP; + case WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP: + return WDI_SET_MAX_TX_POWER_PER_BAND_RSP; + case WLAN_HAL_SET_TX_POWER_RSP: + return WDI_SET_TX_POWER_RESP; + case WLAN_HAL_SET_P2P_GONOA_RSP: + return WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP; +#ifdef FEATURE_WLAN_TDLS + case WLAN_HAL_TDLS_LINK_ESTABLISHED_RSP: + return WDI_TDLS_LINK_ESTABLISH_REQ_RESP; + case WLAN_HAL_TDLS_CHAN_SWITCH_RSP: + return WDI_TDLS_CHAN_SWITCH_REQ_RESP; + case WLAN_HAL_TDLS_IND: + return WDI_HAL_TDLS_IND; +#endif + case WLAN_HAL_ENTER_IMPS_RSP: + return WDI_ENTER_IMPS_RESP; + case WLAN_HAL_EXIT_IMPS_RSP: + return WDI_EXIT_IMPS_RESP; + case WLAN_HAL_ENTER_BMPS_RSP: + return WDI_ENTER_BMPS_RESP; + case WLAN_HAL_EXIT_BMPS_RSP: + return WDI_EXIT_BMPS_RESP; + case WLAN_HAL_ENTER_UAPSD_RSP: + return WDI_ENTER_UAPSD_RESP; + case WLAN_HAL_EXIT_UAPSD_RSP: + return WDI_EXIT_UAPSD_RESP; + case WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP: + return WDI_SET_UAPSD_PARAM_RESP; + case WLAN_HAL_UPDATE_UAPSD_PARAM_RSP: + return WDI_UPDATE_UAPSD_PARAM_RESP; + case WLAN_HAL_CONFIGURE_RXP_FILTER_RSP: + return WDI_CONFIGURE_RXP_FILTER_RESP; + case WLAN_HAL_ADD_BCN_FILTER_RSP: + return WDI_SET_BEACON_FILTER_RESP; + case WLAN_HAL_REM_BCN_FILTER_RSP: + return WDI_REM_BEACON_FILTER_RESP; + case WLAN_HAL_SET_RSSI_THRESH_RSP: + return WDI_SET_RSSI_THRESHOLDS_RESP; + case WLAN_HAL_HOST_OFFLOAD_RSP: + return WDI_HOST_OFFLOAD_RESP; + case WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP: + return WDI_WOWL_ADD_BC_PTRN_RESP; + case WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP: + return WDI_WOWL_DEL_BC_PTRN_RESP; + case WLAN_HAL_ENTER_WOWL_RSP: + return WDI_WOWL_ENTER_RESP; + case WLAN_HAL_EXIT_WOWL_RSP: + return WDI_WOWL_EXIT_RESP; + case WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP: + return WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_RESP; + case WLAN_HAL_DOWNLOAD_NV_RSP: + return WDI_NV_DOWNLOAD_RESP; + case WLAN_HAL_TL_HAL_FLUSH_AC_RSP: + return WDI_FLUSH_AC_RESP; + case WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP: + return WDI_BTAMP_EVENT_RESP; + case WLAN_HAL_PROCESS_PTT_RSP: + return WDI_FTM_CMD_RESP; + case WLAN_HAL_ADD_STA_SELF_RSP: + return WDI_ADD_STA_SELF_RESP; +case WLAN_HAL_DEL_STA_SELF_RSP: + return WDI_DEL_STA_SELF_RESP; +#ifdef FEATURE_OEM_DATA_SUPPORT + case WLAN_HAL_START_OEM_DATA_RSP: + return WDI_START_OEM_DATA_RESP; +#endif /* FEATURE_OEM_DATA_SUPPORT */ + case WLAN_HAL_HOST_RESUME_RSP: + return WDI_HOST_RESUME_RESP; + case WLAN_HAL_KEEP_ALIVE_RSP: + return WDI_KEEP_ALIVE_RESP; +#ifdef FEATURE_WLAN_SCAN_PNO + case WLAN_HAL_SET_PREF_NETWORK_RSP: + return WDI_SET_PREF_NETWORK_RESP; + case WLAN_HAL_SET_RSSI_FILTER_RSP: + return WDI_SET_RSSI_FILTER_RESP; + case WLAN_HAL_UPDATE_SCAN_PARAM_RSP: + return WDI_UPDATE_SCAN_PARAMS_RESP; + case WLAN_HAL_PREF_NETW_FOUND_IND: + return WDI_HAL_PREF_NETWORK_FOUND_IND; +#endif // FEATURE_WLAN_SCAN_PNO +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case WLAN_ROAM_SCAN_OFFLOAD_RSP: + return WDI_ROAM_SCAN_OFFLOAD_RESP; +#endif + case WLAN_HAL_SET_TX_PER_TRACKING_RSP: + return WDI_SET_TX_PER_TRACKING_RESP; +#ifdef WLAN_FEATURE_PACKET_FILTERING + case WLAN_HAL_8023_MULTICAST_LIST_RSP: + return WDI_8023_MULTICAST_LIST_RESP; + case WLAN_HAL_SET_PACKET_FILTER_RSP: + return WDI_RECEIVE_FILTER_SET_FILTER_RESP; + case WLAN_HAL_PACKET_FILTER_MATCH_COUNT_RSP: + return WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP; + case WLAN_HAL_CLEAR_PACKET_FILTER_RSP: + return WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP; +#endif // WLAN_FEATURE_PACKET_FILTERING + + case WLAN_HAL_DUMP_COMMAND_RSP: + return WDI_HAL_DUMP_CMD_RESP; + case WLAN_HAL_SET_POWER_PARAMS_RSP: + return WDI_SET_POWER_PARAMS_RESP; +#ifdef WLAN_FEATURE_VOWIFI_11R + case WLAN_HAL_AGGR_ADD_TS_RSP: + return WDI_AGGR_ADD_TS_RESP; +#endif + +#ifdef WLAN_FEATURE_GTK_OFFLOAD + case WLAN_HAL_GTK_OFFLOAD_RSP: + return WDI_GTK_OFFLOAD_RESP; + case WLAN_HAL_GTK_OFFLOAD_GETINFO_RSP: + return WDI_GTK_OFFLOAD_GETINFO_RESP; +#endif /* WLAN_FEATURE_GTK_OFFLOAD */ +#ifdef WLAN_WAKEUP_EVENTS + case WLAN_HAL_WAKE_REASON_IND: + return WDI_HAL_WAKE_REASON_IND; +#endif // WLAN_WAKEUP_EVENTS + + case WLAN_HAL_SET_THERMAL_MITIGATION_RSP: + return WDI_SET_TM_LEVEL_RESP; + case WLAN_HAL_FEATURE_CAPS_EXCHANGE_RSP: + return WDI_FEATURE_CAPS_EXCHANGE_RESP; +#ifdef WLAN_FEATURE_11AC + case WLAN_HAL_UPDATE_VHT_OP_MODE_RSP: + return WDI_UPDATE_VHT_OP_MODE_RESP; +#endif +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WLAN_HAL_GET_ROAM_RSSI_RSP: + return WDI_GET_ROAM_RSSI_RESP; +#endif + +#ifdef FEATURE_WLAN_LPHB + case WLAN_HAL_LPHB_IND: + return WDI_HAL_LPHB_IND; + case WLAN_HAL_LPHB_CFG_RSP: + return WDI_LPHB_CFG_RESP; +#endif /* FEATURE_WLAN_LPHB */ + + case WLAN_HAL_IBSS_PEER_INACTIVITY_IND: + return WDI_HAL_IBSS_PEER_INACTIVITY_IND; + case WLAN_HAL_PERIODIC_TX_PTRN_FW_IND: + return WDI_HAL_PERIODIC_TX_PTRN_FW_IND; + +#ifdef WLAN_FEATURE_RMC + case WLAN_HAL_RMC_RULER_RSP: + return WDI_RMC_RULER_RESP; + case WLAN_HAL_RMC_UPDATE_IND: + return WDI_RMC_UPDATE_IND_TO_HOST; + case WLAN_HAL_GET_IBSS_PEER_INFO_RSP: + return WDI_HAL_IBSS_PEER_INFO_RSP; +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_BATCH_SCAN + case WLAN_HAL_BATCHSCAN_SET_RSP: + return WDI_SET_BATCH_SCAN_RESP; + case WLAN_HAL_BATCHSCAN_RESULT_IND: + return WDI_BATCHSCAN_RESULT_IND; +#endif // FEATURE_WLAN_BATCH_SCAN + +#ifdef WLAN_FEATURE_RMC + case WLAN_HAL_TX_FAIL_IND: + return WDI_HAL_TX_FAIL_IND; +#endif /* WLAN_FEATURE_RMC */ + +#ifdef FEATURE_WLAN_CH_AVOID + case WLAN_HAL_AVOID_FREQ_RANGE_IND: + return WDI_HAL_CH_AVOID_IND; +#endif /* FEATURE_WLAN_CH_AVOID */ + case WLAN_HAL_UPDATE_CHANNEL_LIST_RSP: + return WDI_UPDATE_CHAN_RESP; + case WLAN_HAL_PRINT_REG_INFO_IND: + return WDI_PRINT_REG_INFO_IND; + case WLAN_HAL_CH_SWITCH_V1_RSP: + return WDI_CH_SWITCH_RESP_V1; + case WLAN_HAL_GET_BCN_MISS_RATE_RSP: + return WDI_GET_BCN_MISS_RATE_RSP; +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case WLAN_HAL_LL_SET_STATS_RSP: + return WDI_LL_STATS_SET_RSP; + case WLAN_HAL_LL_GET_STATS_RSP: + return WDI_LL_STATS_GET_RSP; + case WLAN_HAL_LL_CLEAR_STATS_RSP: + return WDI_LL_STATS_CLEAR_RSP; + case WLAN_HAL_LL_NOTIFY_STATS: + return WDI_HAL_LL_STATS_RESULTS_IND; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + case WLAN_HAL_EXT_SCAN_START_RSP: + return WDI_EXTSCAN_START_RSP; + case WLAN_HAL_EXT_SCAN_STOP_RSP: + return WDI_EXTSCAN_STOP_RSP; + case WLAN_HAL_EXT_SCAN_GET_CAP_RSP: + return WDI_EXTSCAN_GET_CAPABILITIES_RSP; + case WLAN_HAL_EXT_SCAN_GET_SCAN_RSP: + return WDI_EXTSCAN_GET_CACHED_RESULTS_RSP; + case WLAN_HAL_BSSID_HOTLIST_SET_RSP: + return WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP; + case WLAN_HAL_BSSID_HOTLIST_RESET_RSP: + return WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP; + case WLAN_HAL_EXT_SCAN_PROGRESS_IND: + return WDI_HAL_EXTSCAN_PROGRESS_IND; + case WLAN_HAL_EXT_SCAN_RESULT_AVAILABLE_IND: + return WDI_HAL_EXTSCAN_SCAN_AVAILABLE_IND; + case WLAN_HAL_EXT_SCAN_RESULT_IND: + return WDI_HAL_EXTSCAN_RESULT_IND; + case WLAN_HAL_BSSID_HOTLIST_RESULT_IND: + return WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND; +#endif /* WLAN_FEATURE_EXTSCAN */ + case WLAN_HAL_MAC_SPOOFED_SCAN_RSP: + return WDI_SPOOF_MAC_ADDR_RSP; + case WLAN_HAL_FW_STATS_RSP: + return WDI_GET_FW_STATS_RSP; + case WLAN_HAL_ENCRYPT_DATA_RSP: + return WDI_ENCRYPT_MSG_RSP; + case WLAN_HAL_FW_LOGGING_INIT_RSP: + return WDI_FW_LOGGING_INIT_RSP; + case WLAN_HAL_GET_FRAME_LOG_RSP: + return WDI_GET_FRAME_LOG_RSP; + case WLAN_HAL_NAN_RSP: + return WDI_NAN_RESPONSE; + case WLAN_HAL_NAN_EVT: + return WDI_HAL_NAN_EVENT; + case WLAN_HAL_LOST_LINK_PARAMETERS_IND: + return WDI_HAL_LOST_LINK_PARAMS_IND; + case WLAN_HAL_ENABLE_MONITOR_MODE_RSP: + return WDI_MON_START_RSP; + case WLAN_HAL_DISABLE_MONITOR_MODE_RSP: + return WDI_MON_STOP_RSP; + case WLAN_HAL_FATAL_EVENT_LOGGING_RSP: + return WDI_FATAL_EVENT_LOGGING_RSP; + case WLAN_HAL_FW_MEMORY_DUMP_RSP: + return WDI_FWR_MEM_DUMP_RSP; + case WLAN_HAL_START_RSSI_MONITORING_RSP: + return WDI_START_RSSI_MONITOR_RSP; + case WLAN_HAL_STOP_RSSI_MONITORING_RSP: + return WDI_STOP_RSSI_MONITOR_RSP; + case WLAN_HAL_RSSI_MONITORING_IND: + return WDI_HAL_RSSI_BREACHED_IND; + case WLAN_HAL_WIFI_CONFIG_SET_PARAMS_RSP: + return WDI_WIFI_CONFIG_SET_RSP; +#ifdef FEATURE_OEM_DATA_SUPPORT + case WLAN_HAL_START_OEM_DATA_RSP_IND_NEW: + return WDI_HAL_START_OEM_DATA_RSP_IND_NEW; +#endif /* FEATURE_OEM_DATA_SUPPORT */ + case WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_RSP: + return WDI_ANTENNA_DIVERSITY_SELECTION_RSP; +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + case WLAN_HAL_SET_PER_ROAM_CONFIG_RSP: + return WDI_PER_ROAM_SCAN_OFFLOAD_RSP; + case WLAN_HAL_PER_ROAM_SCAN_TRIGGER_RSP: + return WDI_PER_ROAM_SCAN_TRIGGER_RSP; +#endif +#ifdef DHCP_SERVER_OFFLOAD + case WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP: + return WDI_DHCP_SERVER_OFFLOAD_RSP; +#endif /* DHCP_SERVER_OFFLOAD */ +#ifdef MDNS_OFFLOAD + case WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP: + return WDI_MDNS_ENABLE_OFFLOAD_RSP; + case WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP: + return WDI_MDNS_FQDN_OFFLOAD_RSP; + case WLAN_HAL_MDNS_RESP_OFFLOAD_RSP: + return WDI_MDNS_RESP_OFFLOAD_RSP; + case WLAN_HAL_MDNS_STATS_OFFLOAD_RSP: + return WDI_MDNS_STATS_OFFLOAD_RSP; +#endif /* MDNS_OFFLOAD */ +#ifdef WLAN_FEATURE_APFIND + case WLAN_HAL_QRF_PREF_NETW_FOUND_IND: + return WDI_HAL_QRF_PREF_NETWORK_FOUND_IND; +#endif + case WLAN_HAL_CAPTURE_GET_TSF_TSTAMP_RSP: + return WDI_CAPTURE_GET_TSF_TSTAMP_RSP; + case WLAN_HAL_FW_SET_CLEAR_ARP_STATS_RSP: + return WDI_FW_ARP_STATS_RSP; + case WLAN_HAL_FW_GET_ARP_STATS_RSP: + return WDI_FW_GET_ARP_STATS_RSP; + default: + return eDRIVER_TYPE_MAX; + } + +}/*HAL_2_WDI_RSP_TYPE*/ + + +/*Convert WDI driver type into HAL driver type*/ +WPT_STATIC WPT_INLINE tDriverType +WDI_2_HAL_DRV_TYPE +( + WDI_DriverType wdiDriverType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiDriverType ) + { + case WDI_DRIVER_TYPE_PRODUCTION: + return eDRIVER_TYPE_PRODUCTION; + case WDI_DRIVER_TYPE_MFG: + return eDRIVER_TYPE_MFG; + case WDI_DRIVER_TYPE_DVT: + return eDRIVER_TYPE_DVT; + } + + return eDRIVER_TYPE_MAX; +}/*WDI_2_HAL_DRV_TYPE*/ + + +/*Convert WDI stop reason into HAL stop reason*/ +WPT_STATIC WPT_INLINE tHalStopType +WDI_2_HAL_STOP_REASON +( + WDI_StopType wdiDriverType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiDriverType ) + { + case WDI_STOP_TYPE_SYS_RESET: + return HAL_STOP_TYPE_SYS_RESET; + case WDI_STOP_TYPE_SYS_DEEP_SLEEP: + return HAL_STOP_TYPE_SYS_DEEP_SLEEP; + case WDI_STOP_TYPE_RF_KILL: + return HAL_STOP_TYPE_RF_KILL; + } + + return HAL_STOP_TYPE_MAX; +}/*WDI_2_HAL_STOP_REASON*/ + + +/*Convert WDI scan mode type into HAL scan mode type*/ +WPT_STATIC WPT_INLINE eHalSysMode +WDI_2_HAL_SCAN_MODE +( + WDI_ScanMode wdiScanMode +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiScanMode ) + { + case WDI_SCAN_MODE_NORMAL: + return eHAL_SYS_MODE_NORMAL; + case WDI_SCAN_MODE_LEARN: + return eHAL_SYS_MODE_LEARN; + case WDI_SCAN_MODE_SCAN: + return eHAL_SYS_MODE_SCAN; + case WDI_SCAN_MODE_PROMISC: + return eHAL_SYS_MODE_PROMISC; + case WDI_SCAN_MODE_SUSPEND_LINK: + return eHAL_SYS_MODE_SUSPEND_LINK; + case WDI_SCAN_MODE_ROAM_SCAN: + return eHAL_SYS_MODE_ROAM_SCAN; + case WDI_SCAN_MODE_ROAM_SUSPEND_LINK: + return eHAL_SYS_MODE_ROAM_SUSPEND_LINK; + } + + return eHAL_SYS_MODE_MAX; +}/*WDI_2_HAL_SCAN_MODE*/ + +/*Convert WDI sec ch offset into HAL sec ch offset type*/ +WPT_STATIC WPT_INLINE ePhyChanBondState +WDI_2_HAL_SEC_CH_OFFSET +( + WDI_HTSecondaryChannelOffset wdiSecChOffset +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiSecChOffset ) + { + case WDI_SECONDARY_CHANNEL_OFFSET_NONE: + return PHY_SINGLE_CHANNEL_CENTERED; + case WDI_SECONDARY_CHANNEL_OFFSET_UP: + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + case WDI_SECONDARY_CHANNEL_OFFSET_DOWN: + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; +#ifdef WLAN_FEATURE_11AC + case WDI_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + case WDI_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + case WDI_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + case WDI_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + case WDI_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + case WDI_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + case WDI_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; +#endif + default: + break; + } + + return PHY_CHANNEL_BONDING_STATE_MAX; +}/*WDI_2_HAL_SEC_CH_OFFSET*/ + +/*Convert WDI BSS type into HAL BSS type*/ +WPT_STATIC WPT_INLINE tSirBssType +WDI_2_HAL_BSS_TYPE +( + WDI_BssType wdiBSSType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiBSSType ) + { + case WDI_INFRASTRUCTURE_MODE: + return eSIR_INFRASTRUCTURE_MODE; + case WDI_INFRA_AP_MODE: + return eSIR_INFRA_AP_MODE; + case WDI_IBSS_MODE: + return eSIR_IBSS_MODE; + case WDI_BTAMP_STA_MODE: + return eSIR_BTAMP_STA_MODE; + case WDI_BTAMP_AP_MODE: + return eSIR_BTAMP_AP_MODE; + case WDI_BSS_AUTO_MODE: + return eSIR_AUTO_MODE; + } + + return eSIR_DONOT_USE_BSS_TYPE; +}/*WDI_2_HAL_BSS_TYPE*/ + +/*Convert WDI NW type into HAL NW type*/ +WPT_STATIC WPT_INLINE tSirNwType +WDI_2_HAL_NW_TYPE +( + WDI_NwType wdiNWType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch( wdiNWType ) + { + case WDI_11A_NW_TYPE: + return eSIR_11A_NW_TYPE; + case WDI_11B_NW_TYPE: + return eSIR_11B_NW_TYPE; + case WDI_11G_NW_TYPE: + return eSIR_11G_NW_TYPE; + case WDI_11N_NW_TYPE: + return eSIR_11N_NW_TYPE; + } + + return eSIR_DONOT_USE_NW_TYPE; +}/*WDI_2_HAL_NW_TYPE*/ + +/*Convert WDI chanel bonding type into HAL cb type*/ +WPT_STATIC WPT_INLINE ePhyChanBondState +WDI_2_HAL_CB_STATE +( + WDI_PhyChanBondState wdiCbState +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch ( wdiCbState ) + { + case WDI_PHY_SINGLE_CHANNEL_CENTERED: + return PHY_SINGLE_CHANNEL_CENTERED; + case WDI_PHY_DOUBLE_CHANNEL_LOW_PRIMARY: + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + case WDI_PHY_DOUBLE_CHANNEL_CENTERED: + return PHY_DOUBLE_CHANNEL_CENTERED; + case WDI_PHY_DOUBLE_CHANNEL_HIGH_PRIMARY: + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; +#ifdef WLAN_FEATURE_11AC + case WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED; + case WDI_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED: + return PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED; + case WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED: + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED; + case WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + case WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW: + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + case WDI_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH: + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + case WDI_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH: + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; +#endif + case WDI_MAX_CB_STATE: + default: + break; + } + + return PHY_CHANNEL_BONDING_STATE_MAX; +}/*WDI_2_HAL_CB_STATE*/ + +/*Convert WDI chanel bonding type into HAL cb type*/ +WPT_STATIC WPT_INLINE tSirMacHTOperatingMode +WDI_2_HAL_HT_OPER_MODE +( + WDI_HTOperatingMode wdiHTOperMode +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch ( wdiHTOperMode ) + { + case WDI_HT_OP_MODE_PURE: + return eSIR_HT_OP_MODE_PURE; + case WDI_HT_OP_MODE_OVERLAP_LEGACY: + return eSIR_HT_OP_MODE_OVERLAP_LEGACY; + case WDI_HT_OP_MODE_NO_LEGACY_20MHZ_HT: + return eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT; + case WDI_HT_OP_MODE_MIXED: + return eSIR_HT_OP_MODE_MIXED; + } + + return eSIR_HT_OP_MODE_MAX; +}/*WDI_2_HAL_HT_OPER_MODE*/ + +/*Convert WDI mimo PS type into HAL mimo PS type*/ +WPT_STATIC WPT_INLINE tSirMacHTMIMOPowerSaveState +WDI_2_HAL_MIMO_PS +( + WDI_HTMIMOPowerSaveState wdiHTOperMode +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch ( wdiHTOperMode ) + { + case WDI_HT_MIMO_PS_STATIC: + return eSIR_HT_MIMO_PS_STATIC; + case WDI_HT_MIMO_PS_DYNAMIC: + return eSIR_HT_MIMO_PS_DYNAMIC; + case WDI_HT_MIMO_PS_NA: + return eSIR_HT_MIMO_PS_NA; + case WDI_HT_MIMO_PS_NO_LIMIT: + return eSIR_HT_MIMO_PS_NO_LIMIT; + } + + return eSIR_HT_MIMO_PS_MAX; +}/*WDI_2_HAL_MIMO_PS*/ + +/*Convert WDI ENC type into HAL ENC type*/ +WPT_STATIC WPT_INLINE tAniEdType +WDI_2_HAL_ENC_TYPE +( + WDI_EncryptType wdiEncType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch ( wdiEncType ) + { + case WDI_ENCR_NONE: + return eSIR_ED_NONE; + + case WDI_ENCR_WEP40: + return eSIR_ED_WEP40; + + case WDI_ENCR_WEP104: + return eSIR_ED_WEP104; + + case WDI_ENCR_TKIP: + return eSIR_ED_TKIP; + + case WDI_ENCR_CCMP: + return eSIR_ED_CCMP; + + case WDI_ENCR_AES_128_CMAC: + return eSIR_ED_AES_128_CMAC; +#if defined(FEATURE_WLAN_WAPI) + case WDI_ENCR_WPI: + return eSIR_ED_WPI; +#endif + default: + return eSIR_ED_NOT_IMPLEMENTED; + } + +}/*WDI_2_HAL_ENC_TYPE*/ + +/*Convert WDI WEP type into HAL WEP type*/ +WPT_STATIC WPT_INLINE tAniWepType +WDI_2_HAL_WEP_TYPE +( + WDI_WepType wdiWEPType +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch ( wdiWEPType ) + { + case WDI_WEP_STATIC: + return eSIR_WEP_STATIC; + + case WDI_WEP_DYNAMIC: + return eSIR_WEP_DYNAMIC; + } + + return eSIR_WEP_MAX; +}/*WDI_2_HAL_WEP_TYPE*/ + +WPT_STATIC WPT_INLINE tSirLinkState +WDI_2_HAL_LINK_STATE +( + WDI_LinkStateType wdiLinkState +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + switch ( wdiLinkState ) + { + case WDI_LINK_IDLE_STATE: + return eSIR_LINK_IDLE_STATE; + + case WDI_LINK_PREASSOC_STATE: + return eSIR_LINK_PREASSOC_STATE; + + case WDI_LINK_POSTASSOC_STATE: + return eSIR_LINK_POSTASSOC_STATE; + + case WDI_LINK_AP_STATE: + return eSIR_LINK_AP_STATE; + + case WDI_LINK_IBSS_STATE: + return eSIR_LINK_IBSS_STATE; + + case WDI_LINK_BTAMP_PREASSOC_STATE: + return eSIR_LINK_BTAMP_PREASSOC_STATE; + + case WDI_LINK_BTAMP_POSTASSOC_STATE: + return eSIR_LINK_BTAMP_POSTASSOC_STATE; + + case WDI_LINK_BTAMP_AP_STATE: + return eSIR_LINK_BTAMP_AP_STATE; + + case WDI_LINK_BTAMP_STA_STATE: + return eSIR_LINK_BTAMP_STA_STATE; + + case WDI_LINK_LEARN_STATE: + return eSIR_LINK_LEARN_STATE; + + case WDI_LINK_SCAN_STATE: + return eSIR_LINK_SCAN_STATE; + + case WDI_LINK_FINISH_SCAN_STATE: + return eSIR_LINK_FINISH_SCAN_STATE; + + case WDI_LINK_INIT_CAL_STATE: + return eSIR_LINK_INIT_CAL_STATE; + + case WDI_LINK_FINISH_CAL_STATE: + return eSIR_LINK_FINISH_CAL_STATE; + + case WDI_LINK_LISTEN_STATE: + return eSIR_LINK_LISTEN_STATE; + + case WDI_LINK_SEND_ACTION_STATE: + return eSIR_LINK_SEND_ACTION_STATE; + +#ifdef WLAN_FEATURE_LFR_MBB + case WDI_LINK_PRE_AUTH_REASSOC_STATE: + return eSIR_LINK_PRE_AUTH_REASSOC_STATE; +#endif + + default: + return eSIR_LINK_MAX; + } +} + +/*Translate a STA Context from WDI into HAL*/ +WPT_STATIC WPT_INLINE +void +WDI_CopyWDIStaCtxToHALStaCtx +( + tConfigStaParams* phalConfigSta, + WDI_ConfigStaReqInfoType* pwdiConfigSta +) +{ + wpt_uint8 i; +#ifdef WLAN_FEATURE_11AC + /* Get the Version 1 Handler */ + tConfigStaParams_V1* phalConfigSta_V1 = NULL; + if (WDI_getFwWlanFeatCaps(DOT11AC)) + { + phalConfigSta_V1 = (tConfigStaParams_V1*)phalConfigSta; + } +#endif + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + + wpalMemoryCopy(phalConfigSta->bssId, + pwdiConfigSta->macBSSID, WDI_MAC_ADDR_LEN); + + wpalMemoryCopy(phalConfigSta->staMac, + pwdiConfigSta->macSTA, WDI_MAC_ADDR_LEN); + + phalConfigSta->assocId = pwdiConfigSta->usAssocId; + phalConfigSta->staType = pwdiConfigSta->wdiSTAType; + phalConfigSta->shortPreambleSupported = pwdiConfigSta->ucShortPreambleSupported; + phalConfigSta->listenInterval = pwdiConfigSta->usListenInterval; + phalConfigSta->wmmEnabled = pwdiConfigSta->ucWMMEnabled; + phalConfigSta->htCapable = pwdiConfigSta->ucHTCapable; + phalConfigSta->txChannelWidthSet = pwdiConfigSta->ucTXChannelWidthSet; + phalConfigSta->rifsMode = pwdiConfigSta->ucRIFSMode; + phalConfigSta->lsigTxopProtection = pwdiConfigSta->ucLSIGTxopProtection; + phalConfigSta->maxAmpduSize = pwdiConfigSta->ucMaxAmpduSize; + phalConfigSta->maxAmpduDensity = pwdiConfigSta->ucMaxAmpduDensity; + phalConfigSta->maxAmsduSize = pwdiConfigSta->ucMaxAmsduSize; + phalConfigSta->fShortGI40Mhz = pwdiConfigSta->ucShortGI40Mhz; + phalConfigSta->fShortGI20Mhz = pwdiConfigSta->ucShortGI20Mhz; + phalConfigSta->rmfEnabled = pwdiConfigSta->ucRMFEnabled; + phalConfigSta->action = pwdiConfigSta->wdiAction; + phalConfigSta->uAPSD = pwdiConfigSta->ucAPSD; + phalConfigSta->maxSPLen = pwdiConfigSta->ucMaxSPLen; + phalConfigSta->greenFieldCapable = pwdiConfigSta->ucGreenFieldCapable; + phalConfigSta->delayedBASupport = pwdiConfigSta->ucDelayedBASupport; + phalConfigSta->us32MaxAmpduDuration = pwdiConfigSta->us32MaxAmpduDuratio; + phalConfigSta->fDsssCckMode40Mhz = pwdiConfigSta->ucDsssCckMode40Mhz; + phalConfigSta->encryptType = pwdiConfigSta->ucEncryptType; + + phalConfigSta->mimoPS = WDI_2_HAL_MIMO_PS(pwdiConfigSta->wdiMIMOPS); + + phalConfigSta->supportedRates.opRateMode = + pwdiConfigSta->wdiSupportedRates.opRateMode; + for(i = 0; i < SIR_NUM_11B_RATES; i ++) + { + phalConfigSta->supportedRates.llbRates[i] = + pwdiConfigSta->wdiSupportedRates.llbRates[i]; + } + for(i = 0; i < SIR_NUM_11A_RATES; i ++) + { + phalConfigSta->supportedRates.llaRates[i] = + pwdiConfigSta->wdiSupportedRates.llaRates[i]; + } + for(i = 0; i < SIR_NUM_POLARIS_RATES; i ++) + { + phalConfigSta->supportedRates.aniLegacyRates[i] = + pwdiConfigSta->wdiSupportedRates.aLegacyRates[i]; + } + phalConfigSta->supportedRates.aniEnhancedRateBitmap = + pwdiConfigSta->wdiSupportedRates.uEnhancedRateBitmap; + for(i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i ++) + { + phalConfigSta->supportedRates.supportedMCSSet[i] = + pwdiConfigSta->wdiSupportedRates.aSupportedMCSSet[i]; + } + phalConfigSta->supportedRates.rxHighestDataRate = + pwdiConfigSta->wdiSupportedRates.aRxHighestDataRate; + +#ifdef WLAN_FEATURE_11AC + if(phalConfigSta_V1 != NULL) + { + phalConfigSta_V1->supportedRates.vhtRxMCSMap = pwdiConfigSta->wdiSupportedRates.vhtRxMCSMap; + phalConfigSta_V1->supportedRates.vhtRxHighestDataRate = pwdiConfigSta->wdiSupportedRates.vhtRxHighestDataRate; + phalConfigSta_V1->supportedRates.vhtTxMCSMap = pwdiConfigSta->wdiSupportedRates.vhtTxMCSMap; + phalConfigSta_V1->supportedRates.vhtTxHighestDataRate = pwdiConfigSta->wdiSupportedRates.vhtTxHighestDataRate; + } +#endif + + phalConfigSta->p2pCapableSta = pwdiConfigSta->ucP2pCapableSta ; + +#ifdef WLAN_FEATURE_11AC + if(phalConfigSta_V1 != NULL) + { + phalConfigSta_V1->vhtCapable = pwdiConfigSta->ucVhtCapableSta; + phalConfigSta_V1->vhtTxChannelWidthSet = pwdiConfigSta->ucVhtTxChannelWidthSet; + phalConfigSta_V1->vhtTxBFEnabled = pwdiConfigSta->ucVhtTxBFEnabled; + phalConfigSta_V1->vhtTxMUBformeeCapable = pwdiConfigSta->vhtTxMUBformeeCapable; + phalConfigSta_V1->htLdpcEnabled = pwdiConfigSta->ucHtLdpcEnabled; + phalConfigSta_V1->vhtLdpcEnabled = pwdiConfigSta->ucVhtLdpcEnabled; + + } +#endif +}/*WDI_CopyWDIStaCtxToHALStaCtx*/; + +/*Translate a Rate set info from WDI into HAL*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIRateSetToHALRateSet +( + tSirMacRateSet* pHalRateSet, + WDI_RateSet* pwdiRateSet +) +{ + wpt_uint8 i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + pHalRateSet->numRates = ( pwdiRateSet->ucNumRates <= SIR_MAC_RATESET_EID_MAX )? + pwdiRateSet->ucNumRates:SIR_MAC_RATESET_EID_MAX; + + for ( i = 0; i < pHalRateSet->numRates; i++ ) + { + pHalRateSet->rate[i] = pwdiRateSet->aRates[i]; + } + +}/*WDI_CopyWDIRateSetToHALRateSet*/ + + +/*Translate an EDCA Parameter Record from WDI into HAL*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIEDCAParamsToHALEDCAParams +( + tSirMacEdcaParamRecord* phalEdcaParam, + WDI_EdcaParamRecord* pWDIEdcaParam +) +{ + /*Lightweight function - no sanity checks and no unecessary code to increase + the chances of getting inlined*/ + + phalEdcaParam->aci.rsvd = pWDIEdcaParam->wdiACI.rsvd; + phalEdcaParam->aci.aci = pWDIEdcaParam->wdiACI.aci; + phalEdcaParam->aci.acm = pWDIEdcaParam->wdiACI.acm; + phalEdcaParam->aci.aifsn = pWDIEdcaParam->wdiACI.aifsn; + + phalEdcaParam->cw.max = pWDIEdcaParam->wdiCW.max; + phalEdcaParam->cw.min = pWDIEdcaParam->wdiCW.min; + phalEdcaParam->txoplimit = pWDIEdcaParam->usTXOPLimit; +}/*WDI_CopyWDIEDCAParamsToHALEDCAParams*/ + + +/*Copy a management frame header from WDI fmt into HAL fmt*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr +( + tSirMacMgmtHdr* pmacMgmtHdr, + WDI_MacMgmtHdr* pwdiMacMgmtHdr +) +{ + pmacMgmtHdr->fc.protVer = pwdiMacMgmtHdr->fc.protVer; + pmacMgmtHdr->fc.type = pwdiMacMgmtHdr->fc.type; + pmacMgmtHdr->fc.subType = pwdiMacMgmtHdr->fc.subType; + pmacMgmtHdr->fc.toDS = pwdiMacMgmtHdr->fc.toDS; + pmacMgmtHdr->fc.fromDS = pwdiMacMgmtHdr->fc.fromDS; + pmacMgmtHdr->fc.moreFrag = pwdiMacMgmtHdr->fc.moreFrag; + pmacMgmtHdr->fc.retry = pwdiMacMgmtHdr->fc.retry; + pmacMgmtHdr->fc.powerMgmt = pwdiMacMgmtHdr->fc.powerMgmt; + pmacMgmtHdr->fc.moreData = pwdiMacMgmtHdr->fc.moreData; + pmacMgmtHdr->fc.wep = pwdiMacMgmtHdr->fc.wep; + pmacMgmtHdr->fc.order = pwdiMacMgmtHdr->fc.order; + + pmacMgmtHdr->durationLo = pwdiMacMgmtHdr->durationLo; + pmacMgmtHdr->durationHi = pwdiMacMgmtHdr->durationHi; + + wpalMemoryCopy(pmacMgmtHdr->da, + pwdiMacMgmtHdr->da, 6); + wpalMemoryCopy(pmacMgmtHdr->sa, + pwdiMacMgmtHdr->sa, 6); + wpalMemoryCopy(pmacMgmtHdr->bssId, + pwdiMacMgmtHdr->bssId, 6); + + pmacMgmtHdr->seqControl.fragNum = pwdiMacMgmtHdr->seqControl.fragNum; + pmacMgmtHdr->seqControl.seqNumLo = pwdiMacMgmtHdr->seqControl.seqNumLo; + pmacMgmtHdr->seqControl.seqNumHi = pwdiMacMgmtHdr->seqControl.seqNumHi; + +}/*WDI_CopyWDIMgmFrameHdrToHALMgmFrameHdr*/ + + +/*Copy config bss parameters from WDI fmt into HAL fmt*/ +WPT_STATIC WPT_INLINE void +WDI_CopyWDIConfigBSSToHALConfigBSS +( + tConfigBssParams* phalConfigBSS, + WDI_ConfigBSSReqInfoType* pwdiConfigBSS +) +{ + + wpt_uint8 keyIndex = 0; +#ifdef WLAN_FEATURE_11AC + /* Get the Version 1 Handler */ + tConfigBssParams_V1* phalConfigBSS_V1 = NULL; + if (WDI_getFwWlanFeatCaps(DOT11AC)) + phalConfigBSS_V1 = (tConfigBssParams_V1*)phalConfigBSS; +#endif + + wpalMemoryCopy( phalConfigBSS->bssId, + pwdiConfigBSS->macBSSID, + WDI_MAC_ADDR_LEN); + +#ifdef HAL_SELF_STA_PER_BSS + wpalMemoryCopy( phalConfigBSS->selfMacAddr, + pwdiConfigBSS->macSelfAddr, + WDI_MAC_ADDR_LEN); +#endif + + phalConfigBSS->bssType = WDI_2_HAL_BSS_TYPE(pwdiConfigBSS->wdiBSSType); + + phalConfigBSS->operMode = pwdiConfigBSS->ucOperMode; + phalConfigBSS->nwType = WDI_2_HAL_NW_TYPE(pwdiConfigBSS->wdiNWType); + + phalConfigBSS->shortSlotTimeSupported = + pwdiConfigBSS->ucShortSlotTimeSupported; + phalConfigBSS->llaCoexist = pwdiConfigBSS->ucllaCoexist; + phalConfigBSS->llbCoexist = pwdiConfigBSS->ucllbCoexist; + phalConfigBSS->llgCoexist = pwdiConfigBSS->ucllgCoexist; + phalConfigBSS->ht20Coexist = pwdiConfigBSS->ucHT20Coexist; + phalConfigBSS->llnNonGFCoexist = pwdiConfigBSS->ucllnNonGFCoexist; + phalConfigBSS->fLsigTXOPProtectionFullSupport = + pwdiConfigBSS->ucTXOPProtectionFullSupport; + phalConfigBSS->fRIFSMode = pwdiConfigBSS->ucRIFSMode; + phalConfigBSS->beaconInterval = pwdiConfigBSS->usBeaconInterval; + phalConfigBSS->dtimPeriod = pwdiConfigBSS->ucDTIMPeriod; + phalConfigBSS->txChannelWidthSet = pwdiConfigBSS->ucTXChannelWidthSet; + phalConfigBSS->currentOperChannel = pwdiConfigBSS->ucCurrentOperChannel; + phalConfigBSS->currentExtChannel = pwdiConfigBSS->ucCurrentExtChannel; + phalConfigBSS->action = pwdiConfigBSS->wdiAction; + phalConfigBSS->htCapable = pwdiConfigBSS->ucHTCapable; + phalConfigBSS->obssProtEnabled = pwdiConfigBSS->ucObssProtEnabled; + phalConfigBSS->rmfEnabled = pwdiConfigBSS->ucRMFEnabled; + + phalConfigBSS->htOperMode = + WDI_2_HAL_HT_OPER_MODE(pwdiConfigBSS->wdiHTOperMod); + + phalConfigBSS->dualCTSProtection = pwdiConfigBSS->ucDualCTSProtection; + phalConfigBSS->ucMaxProbeRespRetryLimit = pwdiConfigBSS->ucMaxProbeRespRetryLimit; + phalConfigBSS->bHiddenSSIDEn = pwdiConfigBSS->bHiddenSSIDEn; + + if (vos_is_probe_rsp_offload_enabled()) + phalConfigBSS->bProxyProbeRespEn = 1; + else + phalConfigBSS->bProxyProbeRespEn = pwdiConfigBSS->bProxyProbeRespEn; + +#ifdef WLAN_FEATURE_VOWIFI + phalConfigBSS->maxTxPower = pwdiConfigBSS->cMaxTxPower; +#endif + + /*! Used 32 as magic number because that is how the ssid is declared inside the + hal header - hal needs a macro for it */ + phalConfigBSS->ssId.length = + (pwdiConfigBSS->wdiSSID.ucLength <= 32)? + pwdiConfigBSS->wdiSSID.ucLength : 32; + wpalMemoryCopy(phalConfigBSS->ssId.ssId, + pwdiConfigBSS->wdiSSID.sSSID, + phalConfigBSS->ssId.length); + + WDI_CopyWDIStaCtxToHALStaCtx( &phalConfigBSS->staContext, + &pwdiConfigBSS->wdiSTAContext); + + WDI_CopyWDIRateSetToHALRateSet( &phalConfigBSS->rateSet, + &pwdiConfigBSS->wdiRateSet); + + phalConfigBSS->edcaParamsValid = pwdiConfigBSS->ucEDCAParamsValid; + + if(phalConfigBSS->edcaParamsValid) + { + WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acbe, + &pwdiConfigBSS->wdiBEEDCAParams); + WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acbk, + &pwdiConfigBSS->wdiBKEDCAParams); + WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acvi, + &pwdiConfigBSS->wdiVIEDCAParams); + WDI_CopyWDIEDCAParamsToHALEDCAParams( &phalConfigBSS->acvo, + &pwdiConfigBSS->wdiVOEDCAParams); + } + + phalConfigBSS->halPersona = pwdiConfigBSS->ucPersona; + + phalConfigBSS->bSpectrumMgtEnable = pwdiConfigBSS->bSpectrumMgtEn; + +#ifdef WLAN_FEATURE_VOWIFI_11R + + phalConfigBSS->extSetStaKeyParamValid = + pwdiConfigBSS->bExtSetStaKeyParamValid; + + if( phalConfigBSS->extSetStaKeyParamValid ) + { + /*----------------------------------------------------------------------- + Copy the STA Key parameters into the HAL message + -----------------------------------------------------------------------*/ + phalConfigBSS->extSetStaKeyParam.encType = + WDI_2_HAL_ENC_TYPE (pwdiConfigBSS->wdiExtSetKeyParam.wdiEncType); + + phalConfigBSS->extSetStaKeyParam.wepType = + WDI_2_HAL_WEP_TYPE (pwdiConfigBSS->wdiExtSetKeyParam.wdiWEPType ); + + phalConfigBSS->extSetStaKeyParam.staIdx = pwdiConfigBSS->wdiExtSetKeyParam.ucSTAIdx; + + phalConfigBSS->extSetStaKeyParam.defWEPIdx = pwdiConfigBSS->wdiExtSetKeyParam.ucDefWEPIdx; + + phalConfigBSS->extSetStaKeyParam.singleTidRc = pwdiConfigBSS->wdiExtSetKeyParam.ucSingleTidRc; + + for(keyIndex = 0; keyIndex < pwdiConfigBSS->wdiExtSetKeyParam.ucNumKeys ; + keyIndex++) + { + phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyId = + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyId; + phalConfigBSS->extSetStaKeyParam.key[keyIndex].unicast = + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].unicast; + phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyDirection = + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyDirection; + wpalMemoryCopy(phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyRsc, + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyRsc, + WDI_MAX_KEY_RSC_LEN); + phalConfigBSS->extSetStaKeyParam.key[keyIndex].paeRole = + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].paeRole; + phalConfigBSS->extSetStaKeyParam.key[keyIndex].keyLength = + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].keyLength; + wpalMemoryCopy(phalConfigBSS->extSetStaKeyParam.key[keyIndex].key, + pwdiConfigBSS->wdiExtSetKeyParam.wdiKey[keyIndex].key, + WDI_MAX_KEY_LENGTH); + } + } + else/* phalConfigBSS->extSetStaKeyParamValid is not set */ + { + wpalMemoryZero( &phalConfigBSS->extSetStaKeyParam, + sizeof(phalConfigBSS->extSetStaKeyParam) ); + } + +#endif /*WLAN_FEATURE_VOWIFI_11R*/ + +#ifdef WLAN_FEATURE_11AC + if(phalConfigBSS_V1 != NULL) + { + phalConfigBSS_V1->vhtCapable = pwdiConfigBSS->ucVhtCapableSta; + phalConfigBSS_V1->vhtTxChannelWidthSet = pwdiConfigBSS->ucVhtTxChannelWidthSet; + } +#endif + +}/*WDI_CopyWDIConfigBSSToHALConfigBSS*/ + + +/*Extract the request CB function and user data from a request structure + pointed to by user data */ +WPT_STATIC WPT_INLINE void +WDI_ExtractRequestCBFromEvent +( + WDI_EventInfoType* pEvent, + WDI_ReqStatusCb* ppfnReqCB, + void** ppUserData +) +{ + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + switch ( pEvent->wdiRequest ) + { + case WDI_START_REQ: + *ppfnReqCB = ((WDI_StartReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_StartReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_STOP_REQ: + *ppfnReqCB = ((WDI_StopReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_StopReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_INIT_SCAN_REQ: + *ppfnReqCB = ((WDI_InitScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_InitScanReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_START_SCAN_REQ: + *ppfnReqCB = ((WDI_StartScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_StartScanReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_END_SCAN_REQ: + *ppfnReqCB = ((WDI_EndScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_EndScanReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_FINISH_SCAN_REQ: + *ppfnReqCB = ((WDI_FinishScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_FinishScanReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_JOIN_REQ: + *ppfnReqCB = ((WDI_JoinReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_JoinReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_CONFIG_BSS_REQ: + *ppfnReqCB = ((WDI_ConfigBSSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_ConfigBSSReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_DEL_BSS_REQ: + *ppfnReqCB = ((WDI_DelBSSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_DelBSSReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_POST_ASSOC_REQ: + *ppfnReqCB = ((WDI_PostAssocReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_PostAssocReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_DEL_STA_REQ: + *ppfnReqCB = ((WDI_DelSTAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_DelSTAReqParamsType*)pEvent->pEventData)->pUserData; + break; + + case WDI_ADD_STA_SELF_REQ: + *ppfnReqCB = ((WDI_AddSTASelfReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_AddSTASelfReqParamsType*)pEvent->pEventData)->pUserData; + break; + + case WDI_DEL_STA_SELF_REQ: + *ppfnReqCB = ((WDI_DelSTASelfReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_DelSTASelfReqParamsType*)pEvent->pEventData)->pUserData; + break; + + case WDI_SET_BSS_KEY_REQ: + *ppfnReqCB = ((WDI_SetBSSKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetBSSKeyReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_RMV_BSS_KEY_REQ: + *ppfnReqCB = ((WDI_RemoveBSSKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_RemoveBSSKeyReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SET_STA_KEY_REQ: + *ppfnReqCB = ((WDI_SetSTAKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetSTAKeyReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_RMV_STA_KEY_REQ: + *ppfnReqCB = ((WDI_RemoveSTAKeyReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_RemoveSTAKeyReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_ADD_TS_REQ: + *ppfnReqCB = ((WDI_AddTSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_AddTSReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_DEL_TS_REQ: + *ppfnReqCB = ((WDI_DelTSReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_DelTSReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_UPD_EDCA_PRMS_REQ: + *ppfnReqCB = ((WDI_UpdateEDCAParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_UpdateEDCAParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_ADD_BA_SESSION_REQ: + *ppfnReqCB = ((WDI_AddBASessionReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_AddBASessionReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_DEL_BA_REQ: + *ppfnReqCB = ((WDI_DelBAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_DelBAReqParamsType*)pEvent->pEventData)->pUserData; + break; +#ifdef FEATURE_WLAN_ESE + case WDI_TSM_STATS_REQ: + *ppfnReqCB = ((WDI_TSMStatsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_TSMStatsReqParamsType*)pEvent->pEventData)->pUserData; + break; +#endif + case WDI_CH_SWITCH_REQ: + *ppfnReqCB = ((WDI_SwitchChReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SwitchChReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_CH_SWITCH_REQ_V1: + *ppfnReqCB = ((WDI_SwitchChReqParamsType_V1*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SwitchChReqParamsType_V1*)pEvent->pEventData)->pUserData; + break; + case WDI_CONFIG_STA_REQ: + *ppfnReqCB = ((WDI_ConfigSTAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_ConfigSTAReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SET_LINK_ST_REQ: + *ppfnReqCB = ((WDI_SetLinkReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetLinkReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_GET_STATS_REQ: + *ppfnReqCB = ((WDI_GetStatsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_GetStatsReqParamsType*)pEvent->pEventData)->pUserData; + break; +#if defined WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR) + case WDI_GET_ROAM_RSSI_REQ: + *ppfnReqCB = ((WDI_GetRoamRssiReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_GetRoamRssiReqParamsType*)pEvent->pEventData)->pUserData; + break; +#endif + case WDI_UPDATE_CFG_REQ: + *ppfnReqCB = ((WDI_UpdateCfgReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_UpdateCfgReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_ADD_BA_REQ: + *ppfnReqCB = ((WDI_AddBAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_AddBAReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_TRIGGER_BA_REQ: + *ppfnReqCB = ((WDI_TriggerBAReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_TriggerBAReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_UPD_BCON_PRMS_REQ: + *ppfnReqCB = ((WDI_UpdateBeaconParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_UpdateBeaconParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SND_BCON_REQ: + *ppfnReqCB = ((WDI_SendBeaconParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SendBeaconParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_ENTER_BMPS_REQ: + *ppfnReqCB = ((WDI_EnterBmpsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_EnterBmpsReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_EXIT_BMPS_REQ: + *ppfnReqCB = ((WDI_ExitBmpsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_ExitBmpsReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_ENTER_IMPS_REQ: + *ppfnReqCB = ((WDI_EnterImpsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_EnterImpsReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_ENTER_UAPSD_REQ: + *ppfnReqCB = ((WDI_EnterUapsdReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_EnterUapsdReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_EXIT_UAPSD_REQ: + *ppfnReqCB = ((WDI_ExitUapsdReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_ExitUapsdReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SET_UAPSD_PARAM_REQ: + *ppfnReqCB = ((WDI_SetUapsdAcParamsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetUapsdAcParamsReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_UPDATE_UAPSD_PARAM_REQ: + *ppfnReqCB = ((WDI_UpdateUapsdReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_UpdateUapsdReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_CONFIGURE_RXP_FILTER_REQ: + *ppfnReqCB = ((WDI_ConfigureRxpFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_ConfigureRxpFilterReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SET_BEACON_FILTER_REQ: + *ppfnReqCB = ((WDI_BeaconFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_BeaconFilterReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_REM_BEACON_FILTER_REQ: + *ppfnReqCB = ((WDI_RemBeaconFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_RemBeaconFilterReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SET_RSSI_THRESHOLDS_REQ: + *ppfnReqCB = ((WDI_SetRSSIThresholdsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetRSSIThresholdsReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_HOST_OFFLOAD_REQ: + *ppfnReqCB = ((WDI_HostOffloadReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_HostOffloadReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_WOWL_ADD_BC_PTRN_REQ: + *ppfnReqCB = ((WDI_WowlAddBcPtrnReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_WowlAddBcPtrnReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_WOWL_DEL_BC_PTRN_REQ: + *ppfnReqCB = ((WDI_WowlDelBcPtrnReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_WowlDelBcPtrnReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_WOWL_ENTER_REQ: + *ppfnReqCB = ((WDI_WowlEnterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_WowlEnterReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_WOWL_EXIT_REQ: + *ppfnReqCB = ((WDI_WowlExitReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_WowlExitReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ: + *ppfnReqCB = ((WDI_ConfigureAppsCpuWakeupStateReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_ConfigureAppsCpuWakeupStateReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_FLUSH_AC_REQ: + *ppfnReqCB = ((WDI_FlushAcReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_FlushAcReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_BTAMP_EVENT_REQ: + *ppfnReqCB = ((WDI_BtAmpEventParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_BtAmpEventParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_KEEP_ALIVE_REQ: + *ppfnReqCB = ((WDI_KeepAliveReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_KeepAliveReqParamsType*)pEvent->pEventData)->pUserData; + break; +#if defined FEATURE_WLAN_SCAN_PNO + case WDI_SET_PREF_NETWORK_REQ: + *ppfnReqCB = ((WDI_PNOScanReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_PNOScanReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_SET_RSSI_FILTER_REQ: + *ppfnReqCB = ((WDI_SetRssiFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetRssiFilterReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_UPDATE_SCAN_PARAMS_REQ: + *ppfnReqCB = ((WDI_UpdateScanParamsInfoType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_UpdateScanParamsInfoType*)pEvent->pEventData)->pUserData; + break; +#endif + case WDI_SET_TX_PER_TRACKING_REQ: + *ppfnReqCB = ((WDI_SetTxPerTrackingReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetTxPerTrackingReqParamsType*)pEvent->pEventData)->pUserData; + break; +#if defined WLAN_FEATURE_PACKET_FILTERING + case WDI_8023_MULTICAST_LIST_REQ: + *ppfnReqCB = ((WDI_RcvFltPktSetMcListReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_RcvFltPktSetMcListReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_RECEIVE_FILTER_SET_FILTER_REQ: + *ppfnReqCB = ((WDI_SetRcvPktFilterReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetRcvPktFilterReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ: + *ppfnReqCB = ((WDI_RcvFltPktMatchCntReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_RcvFltPktMatchCntReqParamsType*)pEvent->pEventData)->pUserData; + break; + case WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ: + *ppfnReqCB = ((WDI_RcvFltPktClearReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_RcvFltPktClearReqParamsType*)pEvent->pEventData)->pUserData; + break; +#endif + case WDI_SET_POWER_PARAMS_REQ: + *ppfnReqCB = ((WDI_SetPowerParamsReqParamsType*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_SetPowerParamsReqParamsType*)pEvent->pEventData)->pUserData; + break; +#if defined WLAN_FEATURE_GTK_OFFLOAD + case WDI_GTK_OFFLOAD_REQ: + *ppfnReqCB = ((WDI_GtkOffloadReqMsg*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_GtkOffloadReqMsg*)pEvent->pEventData)->pUserData; + break; + case WDI_GTK_OFFLOAD_GETINFO_REQ: + *ppfnReqCB = ((WDI_GtkOffloadGetInfoReqMsg*)pEvent->pEventData)->wdiReqStatusCB; + *ppUserData = ((WDI_GtkOffloadGetInfoReqMsg*)pEvent->pEventData)->pUserData; + break; +#endif + + default: + *ppfnReqCB = NULL; + *ppUserData = NULL; + break; + } +}/*WDI_ExtractRequestCBFromEvent*/ + + +/** + @brief WDI_IsHwFrameTxTranslationCapable checks to see if HW + frame xtl is enabled for a particular STA. + + WDI_PostAssocReq must have been called. + + @param uSTAIdx: STA index + + @see WDI_PostAssocReq + @return Result of the function call +*/ +wpt_boolean +WDI_IsHwFrameTxTranslationCapable +( + wpt_uint8 uSTAIdx +) +{ + /*!! FIX ME - this must eventually be per station - for now just feedback + uma value*/ + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + +#ifdef WLAN_SOFTAP_VSTA_FEATURE + if (IS_VSTA_IDX(uSTAIdx)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "STA %d is a Virtual STA, " + "HW frame translation disabled", uSTAIdx); + return eWLAN_PAL_FALSE; + } +#endif + + return gWDICb.bFrameTransEnabled; +}/*WDI_IsHwFrameTxTranslationCapable*/ + + +/** + @brief WDI_IsSelfSTA - check if staid is self sta index + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + + @return Result of the function call +*/ +wpt_boolean WDI_IsSelfSTA( void* pWDICtx, wpt_uint8 ucSTAIdx ) +{ + wpt_uint8 ucSTAType; + + if( WDI_STATableGetStaType( (WDI_ControlBlockType*)pWDICtx, + ucSTAIdx,&ucSTAType) == WDI_STATUS_SUCCESS) + { + if( ucSTAType == WDI_STA_ENTRY_SELF ) + return eWLAN_PAL_TRUE; + } + + return eWLAN_PAL_FALSE; +} + + + +#ifdef FEATURE_WLAN_SCAN_PNO +/** + @brief WDI_SetPreferredNetworkList + + @param pwdiPNOScanReqParams: the Set PNO as specified + by the Device Interface + + wdiPNOScanCb: callback for passing back the response + of the Set PNO operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetPreferredNetworkReq +( + WDI_PNOScanReqParamsType* pwdiPNOScanReqParams, + WDI_PNOScanCb wdiPNOScanCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_PREF_NETWORK_REQ; + wdiEventData.pEventData = pwdiPNOScanReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiPNOScanReqParams); + wdiEventData.pCBfnc = wdiPNOScanCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief WDI_SetRssiFilterReq + + @param pwdiRssiFilterReqParams: the Set RSSI Filter as + specified by the Device Interface + + wdiRssiFilterCb: callback for passing back the response + of the Set RSSI Filter operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetRssiFilterReq +( + WDI_SetRssiFilterReqParamsType* pwdiRssiFilterReqParams, + WDI_RssiFilterCb wdiRssiFilterCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_RSSI_FILTER_REQ; + wdiEventData.pEventData = pwdiRssiFilterReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiRssiFilterReqParams); + wdiEventData.pCBfnc = wdiRssiFilterCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_SetRssiFilterReq*/ + +/** + @brief WDI_UpdateScanParamsReq + + @param pwdiUpdateScanParamsInfoType: the Update Scan Params as specified + by the Device Interface + + wdiUpdateScanParamsCb: callback for passing back the response + of the Set PNO operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_UpdateScanParamsReq +( + WDI_UpdateScanParamsInfoType* pwdiUpdateScanParamsInfoType, + WDI_UpdateScanParamsCb wdiUpdateScanParamsCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPDATE_SCAN_PARAMS_REQ; + wdiEventData.pEventData = pwdiUpdateScanParamsInfoType; + wdiEventData.uEventDataSize = sizeof(*pwdiUpdateScanParamsInfoType); + wdiEventData.pCBfnc = wdiUpdateScanParamsCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Helper function to pack Set Preferred Network List + Request parameters + + @param pWDICtx: pointer to the WLAN DAL context + pwdiPNOScanReqParams: pointer to the info received + from upper layers + ppSendBuffer, pSize - out pointers of the packed buffer + and its size + + @return Result of the function call +*/ + +WDI_Status +WDI_PackPreferredNetworkList +( + WDI_ControlBlockType* pWDICtx, + WDI_PNOScanReqParamsType* pwdiPNOScanReqParams, + wpt_uint8** ppSendBuffer, + wpt_uint16* pSize +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tpPrefNetwListParams pPrefNetwListParams = NULL; + wpt_uint8 i; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_PREF_NETWORK_REQ, + sizeof(tPrefNetwListParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tPrefNetwListParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set PNO req %p", + pwdiPNOScanReqParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pPrefNetwListParams = (tpPrefNetwListParams)(pSendBuffer + usDataOffset); + + /*------------------------------------------------------------------------- + Fill prefNetwListParams from pwdiPNOScanReqParams->wdiPNOScanInfo + -------------------------------------------------------------------------*/ + pPrefNetwListParams->enable = + pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable; + pPrefNetwListParams->modePNO = + pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO; + + pPrefNetwListParams->ucNetworksCount = + (pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount < + WLAN_HAL_PNO_MAX_SUPP_NETWORKS)? + pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount : + WLAN_HAL_PNO_MAX_SUPP_NETWORKS; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI SET PNO: Enable %d, Mode %d, Netw Count %d", + pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable, + pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO, + pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount); + + for ( i = 0; i < pPrefNetwListParams->ucNetworksCount; i++ ) + { + /*SSID of the BSS*/ + pPrefNetwListParams->aNetworks[i].ssId.length + = pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.ucLength; + + wpalMemoryCopy( pPrefNetwListParams->aNetworks[i].ssId.ssId, + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.sSSID, + pPrefNetwListParams->aNetworks[i].ssId.length); + + /*Authentication type for the network*/ + pPrefNetwListParams->aNetworks[i].authentication = + (tAuthType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiAuth; + + /*Encryption type for the network*/ + pPrefNetwListParams->aNetworks[i].encryption = + (tEdType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiEncryption; + + /*Indicate the channel on which the Network can be found + 0 - if all channels */ + pPrefNetwListParams->aNetworks[i].ucChannelCount = + (pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ucChannelCount < + WLAN_HAL_PNO_MAX_NETW_CHANNELS)? + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ucChannelCount : + WLAN_HAL_PNO_MAX_NETW_CHANNELS; + + wpalMemoryCopy(pPrefNetwListParams->aNetworks[i].aChannels, + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].aChannels, + pPrefNetwListParams->aNetworks[i].ucChannelCount); + + /*Indicates the RSSI threshold for the network to be considered*/ + pPrefNetwListParams->aNetworks[i].rssiThreshold = + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].rssiThreshold; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI SET PNO: SSID %d %s", + pPrefNetwListParams->aNetworks[i].ssId.length, + pPrefNetwListParams->aNetworks[i].ssId.ssId); + } + + pPrefNetwListParams->scanTimers.ucScanTimersCount = + (pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount < + WLAN_HAL_PNO_MAX_SCAN_TIMERS)? + pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount : + WLAN_HAL_PNO_MAX_SCAN_TIMERS; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI SET PNO: Scan timers count %d 24G P %d 5G Probe %d", + pPrefNetwListParams->scanTimers.ucScanTimersCount, + pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize, + pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize); + + for ( i = 0; i < pPrefNetwListParams->scanTimers.ucScanTimersCount; i++ ) + { + pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerValue = + pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerValue; + pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerRepeat = + pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerRepeat; + } + + /*Copy the probe template*/ + pPrefNetwListParams->us24GProbeSize = + (pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize< + WLAN_HAL_PNO_MAX_PROBE_SIZE)? + pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize: + WLAN_HAL_PNO_MAX_PROBE_SIZE; + + wpalMemoryCopy(pPrefNetwListParams->a24GProbeTemplate, + pwdiPNOScanReqParams->wdiPNOScanInfo.a24GProbeTemplate, + pPrefNetwListParams->us24GProbeSize); + + pPrefNetwListParams->us5GProbeSize = + (pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize < + WLAN_HAL_PNO_MAX_PROBE_SIZE)? + pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize: + WLAN_HAL_PNO_MAX_PROBE_SIZE; + + wpalMemoryCopy(pPrefNetwListParams->a5GProbeTemplate, + pwdiPNOScanReqParams->wdiPNOScanInfo.a5GProbeTemplate, + pPrefNetwListParams->us5GProbeSize); + + /*Set the output values*/ + *ppSendBuffer = pSendBuffer; + *pSize = usSendSize; + + return WDI_STATUS_SUCCESS; +}/*WDI_PackPreferredNetworkList*/ + +/** + @brief Helper function to pack Set Preferred Network List + Request parameters + + @param pWDICtx: pointer to the WLAN DAL context + pwdiPNOScanReqParams: pointer to the info received + from upper layers + ppSendBuffer, pSize - out pointers of the packed buffer + and its size + + @return Result of the function call +*/ + +WDI_Status +WDI_PackPreferredNetworkListNew +( + WDI_ControlBlockType* pWDICtx, + WDI_PNOScanReqParamsType* pwdiPNOScanReqParams, + wpt_uint8** ppSendBuffer, + wpt_uint16* pSize +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tpPrefNetwListParamsNew pPrefNetwListParams; + wpt_uint8 i; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_PREF_NETWORK_REQ, + sizeof(tPrefNetwListParamsNew), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tPrefNetwListParamsNew) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set PNO req %p", + pwdiPNOScanReqParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pPrefNetwListParams = (tpPrefNetwListParamsNew)(pSendBuffer + usDataOffset); + + /*------------------------------------------------------------------------- + Fill prefNetwListParams from pwdiPNOScanReqParams->wdiPNOScanInfo + -------------------------------------------------------------------------*/ + pPrefNetwListParams->enable = + pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable; + pPrefNetwListParams->modePNO = + pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO; + + pPrefNetwListParams->ucNetworksCount = + (pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount < + WLAN_HAL_PNO_MAX_SUPP_NETWORKS)? + pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount : + WLAN_HAL_PNO_MAX_SUPP_NETWORKS; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI SET PNO: Enable %d, Mode %d, Netw Count %d", + pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable, + pwdiPNOScanReqParams->wdiPNOScanInfo.wdiModePNO, + pwdiPNOScanReqParams->wdiPNOScanInfo.ucNetworksCount); + + for ( i = 0; i < pPrefNetwListParams->ucNetworksCount; i++ ) + { + /*SSID of the BSS*/ + pPrefNetwListParams->aNetworks[i].ssId.length + = pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.ucLength; + + wpalMemoryCopy( pPrefNetwListParams->aNetworks[i].ssId.ssId, + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ssId.sSSID, + pPrefNetwListParams->aNetworks[i].ssId.length); + + /*Authentication type for the network*/ + pPrefNetwListParams->aNetworks[i].authentication = + (tAuthType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiAuth; + + /*Encryption type for the network*/ + pPrefNetwListParams->aNetworks[i].encryption = + (tEdType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiEncryption; + + /*SSID bcast type for the network*/ + pPrefNetwListParams->aNetworks[i].bcastNetworkType = + (tSSIDBcastType)pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].wdiBcastNetworkType; + + /*Indicate the channel on which the Network can be found + 0 - if all channels */ + pPrefNetwListParams->aNetworks[i].ucChannelCount = + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].ucChannelCount; + + wpalMemoryCopy(pPrefNetwListParams->aNetworks[i].aChannels, + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].aChannels, + pPrefNetwListParams->aNetworks[i].ucChannelCount); + + /*Indicates the RSSI threshold for the network to be considered*/ + pPrefNetwListParams->aNetworks[i].rssiThreshold = + pwdiPNOScanReqParams->wdiPNOScanInfo.aNetworks[i].rssiThreshold; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI SET PNO: SSID %d %s", + pPrefNetwListParams->aNetworks[i].ssId.length, + pPrefNetwListParams->aNetworks[i].ssId.ssId); + } + + pPrefNetwListParams->scanTimers.ucScanTimersCount = + (pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount < + WLAN_HAL_PNO_MAX_SCAN_TIMERS)? + pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.ucScanTimersCount : + WLAN_HAL_PNO_MAX_SCAN_TIMERS; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI SET PNO: Scan timers count %d 24G P %d 5G Probe %d", + pPrefNetwListParams->scanTimers.ucScanTimersCount, + pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize, + pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize); + + for ( i = 0; i < pPrefNetwListParams->scanTimers.ucScanTimersCount; i++ ) + { + pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerValue = + pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerValue; + pPrefNetwListParams->scanTimers.aTimerValues[i].uTimerRepeat = + pwdiPNOScanReqParams->wdiPNOScanInfo.scanTimers.aTimerValues[i].uTimerRepeat; + } + + /*Copy the probe template*/ + pPrefNetwListParams->us24GProbeSize = + (pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize< + WLAN_HAL_PNO_MAX_PROBE_SIZE)? + pwdiPNOScanReqParams->wdiPNOScanInfo.us24GProbeSize: + WLAN_HAL_PNO_MAX_PROBE_SIZE; + + wpalMemoryCopy(pPrefNetwListParams->a24GProbeTemplate, + pwdiPNOScanReqParams->wdiPNOScanInfo.a24GProbeTemplate, + pPrefNetwListParams->us24GProbeSize); + + pPrefNetwListParams->us5GProbeSize = + (pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize < + WLAN_HAL_PNO_MAX_PROBE_SIZE)? + pwdiPNOScanReqParams->wdiPNOScanInfo.us5GProbeSize: + WLAN_HAL_PNO_MAX_PROBE_SIZE; + + wpalMemoryCopy(pPrefNetwListParams->a5GProbeTemplate, + pwdiPNOScanReqParams->wdiPNOScanInfo.a5GProbeTemplate, + pPrefNetwListParams->us5GProbeSize); + + + /*Set the output values*/ + *ppSendBuffer = pSendBuffer; + *pSize = usSendSize; + + return WDI_STATUS_SUCCESS; +}/*WDI_PackPreferredNetworkListNew*/ + +/** + @brief Process Set Preferred Network List Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPreferredNetworkReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_PNOScanReqParamsType* pwdiPNOScanReqParams = NULL; + WDI_PNOScanCb wdiPNOScanCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiPNOScanReqParams = (WDI_PNOScanReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiPNOScanCb = (WDI_PNOScanCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /*---------------------------------------------------------------------- + Avoid Enable PNO during any active session or an ongoing session + Allow only if SAP auth offload feature is enabled + ----------------------------------------------------------------------*/ + if ((pwdiPNOScanReqParams->wdiPNOScanInfo.bEnable && + WDI_GetActiveSessionsCount(pWDICtx, NULL, eWLAN_PAL_FALSE)) && + !WDI_getFwWlanFeatCaps(SAP_OFFLOADS)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s:(Active/Ongoing Session) - Fail request", __func__); + + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Pack the PNO request structure based on version + -------------------------------------------------------------------------*/ + if ( pWDICtx->wdiPNOVersion > 0 ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: PNO new version %d ", __func__, + pWDICtx->wdiPNOVersion); + + wdiStatus = WDI_PackPreferredNetworkListNew( pWDICtx, pwdiPNOScanReqParams, + &pSendBuffer, &usSendSize); + } + else + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: PNO old version %d ", __func__, + pWDICtx->wdiPNOVersion); + + wdiStatus = WDI_PackPreferredNetworkList( pWDICtx, pwdiPNOScanReqParams, + &pSendBuffer, &usSendSize); + } + + if (( WDI_STATUS_SUCCESS != wdiStatus )|| + ( NULL == pSendBuffer )||( 0 == usSendSize )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: failed to pack request parameters", __func__); + WDI_ASSERT(0); + return wdiStatus; + } + + pWDICtx->wdiReqStatusCB = pwdiPNOScanReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiPNOScanReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiPNOScanCb, pEventData->pUserData, WDI_SET_PREF_NETWORK_RESP); +} + +/** + @brief Process Set RSSI Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRssiFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetRssiFilterReqParamsType* pwdiRssiFilterReqParams = NULL; + WDI_RssiFilterCb wdiRssiFilterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 ucRssiThreshold; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiRssiFilterReqParams = (WDI_SetRssiFilterReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiRssiFilterCb = (WDI_RssiFilterCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_RSSI_FILTER_REQ, + sizeof(ucRssiThreshold), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(ucRssiThreshold) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set PNO req %p %p %p", + pEventData, pwdiRssiFilterReqParams, wdiRssiFilterCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ucRssiThreshold = pwdiRssiFilterReqParams->rssiThreshold; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &ucRssiThreshold, + sizeof(ucRssiThreshold)); + + pWDICtx->wdiReqStatusCB = pwdiRssiFilterReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRssiFilterReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRssiFilterCb, pEventData->pUserData, WDI_SET_RSSI_FILTER_RESP); +} +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +/** + @brief WDI_RoamScanOffloadReq + + @param pwdiRoamScanOffloadReqParams: the LookupReq as specified + by the Device Interface + + wdiRoamOffloadScancb: callback for passing back the response + of the Roam Candidate Lookup Req operation received from the + device + + pUserData: user data will be passed back with the + callback + @return Result of the function call +*/ +WDI_Status +WDI_RoamScanOffloadReq +( + WDI_RoamScanOffloadReqParamsType* pwdiRoamScanOffloadReqParams, + WDI_RoamOffloadScanCb wdiRoamOffloadScancb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData = {{0}}; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ROAM_SCAN_OFFLOAD_REQ; + wdiEventData.pEventData = pwdiRoamScanOffloadReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiRoamScanOffloadReqParams); + wdiEventData.pCBfnc = wdiRoamOffloadScancb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_PERRoamScanOffloadReq(WDI_PERRoamOffloadScanInfo + *pwdiPERRoamScanOffloadReqParams, + WDI_PERRoamOffloadScanCb wdiPERRoamOffloadScancb, + void *pUserData) +{ + WDI_EventInfoType wdiEventData = {{0}}; + + if (eWLAN_PAL_FALSE == gWDIInitialized) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_PER_ROAM_SCAN_OFFLOAD_REQ; + wdiEventData.pEventData = pwdiPERRoamScanOffloadReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiPERRoamScanOffloadReqParams); + wdiEventData.pCBfnc = wdiPERRoamOffloadScancb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_PERRoamScanTriggerReq(WDI_PERRoamTriggerScanInfo + *pwdiPERRoamScanTriggerReqParams, + WDI_PERRoamTriggerScanCb wdiPERRoamTriggerScancb, + void *pUserData) +{ + WDI_EventInfoType wdiEventData = {{0}}; + if (eWLAN_PAL_FALSE == gWDIInitialized) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_PER_ROAM_SCAN_TRIGGER_REQ; + wdiEventData.pEventData = pwdiPERRoamScanTriggerReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiPERRoamScanTriggerReqParams); + wdiEventData.pCBfnc = wdiPERRoamTriggerScancb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +void +WDI_wdiEdTypeEncToEdTypeEnc(tEdType *EdType, WDI_EdType wdiEdType) +{ + switch (wdiEdType) + { + case WDI_ED_NONE: + *EdType = eED_NONE; + break; + case WDI_ED_WEP40: + case WDI_ED_WEP104: + *EdType = eED_WEP; + break; + case WDI_ED_TKIP: + *EdType = eED_TKIP; + break; + case WDI_ED_CCMP: +#ifdef WLAN_FEATURE_11W + case WDI_ED_AES_128_CMAC: +#endif + *EdType = eED_CCMP; + break; +#ifdef FEATURE_WLAN_WAPI + case WDI_ED_WPI: + *EdType = eED_WPI; + break; +#endif + case WDI_ED_ANY: + *EdType = eED_ANY; + break; + + default: + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Unknown Encryption Type", __func__); + break; + } +} + +/** + @brief Helper function to pack Start Roam Candidate Lookup + Request parameters + + @param pWDICtx: pointer to the WLAN DAL context + pwdiRoamScanOffloadReqParams: pointer to the info received + from upper layers + ppSendBuffer, pSize - out pointers of the packed buffer + and its size + + @return Result of the function call +*/ + +WDI_Status +WDI_PackRoamScanOffloadParams +( + WDI_ControlBlockType* pWDICtx, + WDI_RoamScanOffloadReqParamsType* pwdiRoamScanOffloadReqParams, + wpt_uint8** ppSendBuffer, + wpt_uint16* pSize +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tpRoamCandidateListParams pRoamCandidateListParams = NULL; + wpt_uint8 i; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_ROAM_SCAN_OFFLOAD_REQ, + sizeof(tRoamCandidateListParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tRoamCandidateListParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Start Roam Candidate Lookup Req %p", + pwdiRoamScanOffloadReqParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pRoamCandidateListParams = (tpRoamCandidateListParams)(pSendBuffer + usDataOffset); + wpalMemoryZero(pRoamCandidateListParams, sizeof(tRoamCandidateListParams)); + pRoamCandidateListParams->RoamScanOffloadEnabled = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.RoamScanOffloadEnabled; + wpalMemoryCopy(pRoamCandidateListParams->ConnectedNetwork.currAPbssid, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.currAPbssid, + HAL_MAC_ADDR_LEN); + pRoamCandidateListParams->ConnectedNetwork.authentication = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.authentication; + WDI_wdiEdTypeEncToEdTypeEnc(&pRoamCandidateListParams->ConnectedNetwork.encryption, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.encryption); + WDI_wdiEdTypeEncToEdTypeEnc(&pRoamCandidateListParams->ConnectedNetwork.mcencryption, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.mcencryption); + + pRoamCandidateListParams->ConnectedNetwork.ssId.length + = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ssId.ucLength; + wpalMemoryCopy( pRoamCandidateListParams->ConnectedNetwork.ssId.ssId, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ssId.sSSID, + pRoamCandidateListParams->ConnectedNetwork.ssId.length); + wpalMemoryCopy(pRoamCandidateListParams->ConnectedNetwork.ChannelCache, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ChannelCache, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ChannelCount ); + pRoamCandidateListParams->ConnectedNetwork.ChannelCount = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ConnectedNetwork.ChannelCount; + pRoamCandidateListParams->ChannelCacheType = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ChannelCacheType ; + pRoamCandidateListParams->LookupThreshold = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.LookupThreshold; + pRoamCandidateListParams->RxSensitivityThreshold = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.RxSensitivityThreshold; + pRoamCandidateListParams->RoamRssiDiff = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.RoamRssiDiff ; + pRoamCandidateListParams->MAWCEnabled = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MAWCEnabled ; + pRoamCandidateListParams->Command = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.Command ; + pRoamCandidateListParams->StartScanReason = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.StartScanReason ; + pRoamCandidateListParams->NeighborScanTimerPeriod = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborScanTimerPeriod ; + pRoamCandidateListParams->NeighborRoamScanRefreshPeriod = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborRoamScanRefreshPeriod ; + pRoamCandidateListParams->NeighborScanChannelMinTime = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborScanChannelMinTime ; + pRoamCandidateListParams->NeighborScanChannelMaxTime = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.NeighborScanChannelMaxTime ; + pRoamCandidateListParams->EmptyRefreshScanPeriod = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.EmptyRefreshScanPeriod ; + pRoamCandidateListParams->IsESEEnabled = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.IsESEEnabled ; + wpalMemoryCopy(pRoamCandidateListParams->ValidChannelList, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelList, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelCount); + pRoamCandidateListParams->ValidChannelCount = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.ValidChannelCount; + pRoamCandidateListParams->WeakZoneRssiThresholdForRoam = + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.WeakZoneRssiThresholdForRoam; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, + "Values are ssid = %s, RoamOffloadScan=%d,Command=%d," + "StartScanReason=%d,NeighborScanTimerPeriod=%d," + "NeighborRoamScanRefreshPeriod=%d,NeighborScanChannelMinTime=%d," + "NeighborScanChannelMaxTime = %d,EmptyRefreshScanPeriod=%d," + "mdiePresent=%d,MDID=%d, auth=%d, uce=%d, mce=%d, nProbes=%d," + "HomeAwayTime=%d RssiThesholdForRoam=%d", + pRoamCandidateListParams->ConnectedNetwork.ssId.ssId, + pRoamCandidateListParams->RoamScanOffloadEnabled, + pRoamCandidateListParams->Command, + pRoamCandidateListParams->StartScanReason, + pRoamCandidateListParams->NeighborScanTimerPeriod, + pRoamCandidateListParams->NeighborRoamScanRefreshPeriod, + pRoamCandidateListParams->NeighborScanChannelMinTime, + pRoamCandidateListParams->NeighborScanChannelMaxTime, + pRoamCandidateListParams->EmptyRefreshScanPeriod, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mdiePresent, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mobilityDomain, + pRoamCandidateListParams->ConnectedNetwork.authentication, + pRoamCandidateListParams->ConnectedNetwork.encryption, + pRoamCandidateListParams->ConnectedNetwork.mcencryption, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.nProbes, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.HomeAwayTime, + pRoamCandidateListParams->WeakZoneRssiThresholdForRoam); + pRoamCandidateListParams->us24GProbeSize = + (pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us24GProbeSize< + WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE)? + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us24GProbeSize: + WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE; + wpalMemoryCopy(pRoamCandidateListParams->a24GProbeTemplate, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.a24GProbeTemplate, + pRoamCandidateListParams->us24GProbeSize); + pRoamCandidateListParams->us5GProbeSize = + (pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us5GProbeSize< + WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE)? + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.us5GProbeSize: + WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE; + wpalMemoryCopy(pRoamCandidateListParams->a5GProbeTemplate, + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.a5GProbeTemplate, + pRoamCandidateListParams->us5GProbeSize); + pRoamCandidateListParams->MDID.mdiePresent = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mdiePresent; + pRoamCandidateListParams->MDID.mobilityDomain = pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.MDID.mobilityDomain; + pRoamCandidateListParams->nProbes = + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.nProbes; + pRoamCandidateListParams->HomeAwayTime = + pwdiRoamScanOffloadReqParams->wdiRoamOffloadScanInfo.HomeAwayTime; + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,"Valid Channel List"); + for (i=0; iValidChannelCount ; i++) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO_HIGH,"%d", pRoamCandidateListParams->ValidChannelList[i]); + } + + + /*Set the output values*/ + *ppSendBuffer = pSendBuffer; + *pSize = usSendSize; + return WDI_STATUS_SUCCESS; +}/*WDI_PackRoamScanOffloadParams*/ + +/** + @brief Process Start Roam Candidate Lookup Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRoamScanOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RoamScanOffloadReqParamsType* pwdiRoamScanOffloadReqParams = NULL; + WDI_RoamOffloadScanCb wdiRoamOffloadScancb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiRoamScanOffloadReqParams = (WDI_RoamScanOffloadReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiRoamOffloadScancb = (WDI_RoamOffloadScanCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Pack the Start Roam Candidate Lookup request structure based on version + -------------------------------------------------------------------------*/ + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Packing Roam Candidate Lookup request ", __func__); + + wdiStatus = WDI_PackRoamScanOffloadParams( pWDICtx, pwdiRoamScanOffloadReqParams, + &pSendBuffer, &usSendSize); + + if (( WDI_STATUS_SUCCESS != wdiStatus )|| + ( NULL == pSendBuffer )||( 0 == usSendSize )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: failed to pack request parameters", __func__); + WDI_ASSERT(0); + return wdiStatus; + } + + pWDICtx->wdiReqStatusCB = pwdiRoamScanOffloadReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRoamScanOffloadReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send WDI_ROAM_SCAN_OFFLOAD_REQ to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRoamOffloadScancb, pEventData->pUserData, WDI_ROAM_SCAN_OFFLOAD_RESP); +} + + +WDI_Status +WDI_ProcessPERRoamScanOffloadReq(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData) +{ + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + wpt_uint8 *pSendBuffer = NULL; + WDI_PERRoamOffloadScanInfo *wdiPERRoamOffloadReq = NULL; + WDI_PERRoamOffloadScanCb wdiPERRoamOffloadScancb = NULL; + tSetPerRoamConfigReq halPERRoamConfigReq; + + if (!pEventData) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: *pEventdata is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiPERRoamOffloadReq = (WDI_PERRoamOffloadScanInfo *)pEventData->pEventData; + wdiPERRoamOffloadScancb = (WDI_PERRoamOffloadScanCb)pEventData->pCBfnc; + + if (!wdiPERRoamOffloadReq || !wdiPERRoamOffloadScancb) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_PER_ROAM_SCAN_OFFLOAD_REQ, + sizeof(halPERRoamConfigReq.perRoamConfigParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halPERRoamConfigReq.perRoamConfigParams)))) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer halPERRoamConfigReq Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halPERRoamConfigReq.perRoamConfigParams.request_id = + wdiPERRoamOffloadReq->requestId; + halPERRoamConfigReq.perRoamConfigParams.waitPeriodForNextPERScan = + wdiPERRoamOffloadReq->waitPeriodForNextPERScan; + halPERRoamConfigReq.perRoamConfigParams.rateUpThreshold = + wdiPERRoamOffloadReq->rateUpThreshold; + halPERRoamConfigReq.perRoamConfigParams.rateDownThreshold = + wdiPERRoamOffloadReq->rateDownThreshold; + halPERRoamConfigReq.perRoamConfigParams.isPERRoamCCAEnabled = + wdiPERRoamOffloadReq->isPERRoamCCAEnabled; + halPERRoamConfigReq.perRoamConfigParams.PERRoamFullScanThreshold = + wdiPERRoamOffloadReq->PERRoamFullScanThreshold; + halPERRoamConfigReq.perRoamConfigParams.PERroamTriggerPercent = + wdiPERRoamOffloadReq->PERroamTriggerPercent; + halPERRoamConfigReq.perRoamConfigParams.PERtimerThreshold = + wdiPERRoamOffloadReq->PERtimerThreshold; + + halPERRoamConfigReq.perRoamConfigParams.reserved = 0; + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halPERRoamConfigReq.perRoamConfigParams, + sizeof(halPERRoamConfigReq.perRoamConfigParams)); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "waitPeriodForNextPERScan=%d rateUpThreshold=%d rateDownThreshold=%d isPERRoamCCAEnabled=%d", + halPERRoamConfigReq.perRoamConfigParams.waitPeriodForNextPERScan, + halPERRoamConfigReq.perRoamConfigParams.rateUpThreshold, + halPERRoamConfigReq.perRoamConfigParams.rateDownThreshold, + halPERRoamConfigReq.perRoamConfigParams.isPERRoamCCAEnabled); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "PERtimerThreshold=%d PERroamTriggerPercent =%d PERRoamFullScanThreshold %d", + halPERRoamConfigReq.perRoamConfigParams.PERtimerThreshold, + halPERRoamConfigReq.perRoamConfigParams.PERroamTriggerPercent, + halPERRoamConfigReq.perRoamConfigParams.PERRoamFullScanThreshold); + + return WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize, + wdiPERRoamOffloadScancb, pEventData->pUserData, + WDI_PER_ROAM_SCAN_OFFLOAD_RSP); +} + +WDI_Status +WDI_ProcessPERRoamScanTriggerReq(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData) +{ + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + wpt_uint8 *pSendBuffer = NULL; + WDI_PERRoamTriggerScanCb wdiPERRoamTriggerScancb = NULL; + WDI_PERRoamTriggerScanInfo *wdiPERRoamTriggerReq; + tStartRoamScanReq halPERRoamTriggerReq; + + if (!pEventData) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: pEventdata is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiPERRoamTriggerReq = (WDI_PERRoamTriggerScanInfo *) pEventData->pEventData; + wdiPERRoamTriggerScancb = (WDI_PERRoamTriggerScanCb)pEventData->pCBfnc; + + if (!wdiPERRoamTriggerReq || !wdiPERRoamTriggerScancb) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_PER_ROAM_SCAN_TRIGGER_REQ, + sizeof(halPERRoamTriggerReq.startRoamScanTriggerParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halPERRoamTriggerReq.startRoamScanTriggerParams)))) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halPERRoamTriggerReq.startRoamScanTriggerParams.roamScanReq = + wdiPERRoamTriggerReq->roamScanReq; + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halPERRoamTriggerReq.startRoamScanTriggerParams, + sizeof(halPERRoamTriggerReq.startRoamScanTriggerParams)); + + return WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize, + wdiPERRoamTriggerScancb, pEventData->pUserData, + WDI_PER_ROAM_SCAN_TRIGGER_RSP); +} + + + + +/** + @brief Process Start Roam Candidate Lookup Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRoamScanOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_RoamOffloadScanCb wdiRoamOffloadScancb = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRoamOffloadScancb = (WDI_RoamOffloadScanCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiRoamOffloadScancb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/* WDI_ProcessRoamScanOffloadRsp */ + +WDI_Status +WDI_ProcessPERRoamScanOffloadRsp(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_PERRoamOffloadScanCb wdiPERRoamOffloadScancb = NULL; + + if ((NULL == pWDICtx) || (NULL == pEventData) || + (NULL == pEventData->pEventData)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiPERRoamOffloadScancb = (WDI_PERRoamOffloadScanCb)pWDICtx->pfncRspCB; + + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiPERRoamOffloadScancb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/* WDI_ProcessPERRoamScanOffloadRsp */ + +WDI_Status +WDI_ProcessPERRoamScanTriggerRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_PERRoamOffloadScanCb wdiPERRoamTriggerScancb = NULL; + + if ((NULL == pWDICtx) || (NULL == pEventData) || + (NULL == pEventData->pEventData)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiPERRoamTriggerScancb = (WDI_PERRoamTriggerScanCb)pWDICtx->pfncRspCB; + + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /* Notify UMAC */ + wdiPERRoamTriggerScancb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/* WDI_ProcessPERRoamScanTriggerRsp */ +#endif + +#ifdef WLAN_FEATURE_APFIND +#define FIND_AP_WAKELOCK_TIMEOUT 1000 +/** + @brief Process QRF Preferred Network Found Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessQRFPrefNetworkFoundInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s:%d Enter", __func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (NULL == pWDICtx) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + vos_wake_lock_timeout_release(&pWDICtx->find_ap_lock, + FIND_AP_WAKELOCK_TIMEOUT, + WIFI_POWER_EVENT_WAKELOCK_FIND_AP_INDICATION); + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_AP_FOUND_IND; + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; +} +#endif + +/** + @brief Process Update Scan Params function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_PackUpdateScanParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_UpdateScanParamsInfoType* pwdiUpdateScanParams, + wpt_uint8** ppSendBuffer, + wpt_uint16* pSize +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tUpdateScanParams updateScanParams = {0}; + + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Begin WDI Update Scan Parameters Old Style Params"); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_SCAN_PARAMS_REQ, + sizeof(updateScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(updateScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Update Scan Params req %p", + pwdiUpdateScanParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + // + // Fill updateScanParams from pwdiUpdateScanParams->wdiUpdateScanParamsInfo + // + + updateScanParams.b11dEnabled = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dEnabled; + updateScanParams.b11dResolved = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dResolved; + + updateScanParams.ucChannelCount = + (pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount < + WLAN_HAL_PNO_MAX_NETW_CHANNELS)? + pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount : + WLAN_HAL_PNO_MAX_NETW_CHANNELS; + + wpalMemoryCopy( updateScanParams.aChannels, + pwdiUpdateScanParams->wdiUpdateScanParamsInfo.aChannels, + updateScanParams.ucChannelCount); + + + updateScanParams.usActiveMinChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMinChTime; + updateScanParams.usActiveMaxChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMaxChTime; + updateScanParams.usPassiveMinChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMinChTime; + updateScanParams.usPassiveMaxChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMaxChTime; + updateScanParams.cbState = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.cbState; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &updateScanParams, + sizeof(updateScanParams)); + + pWDICtx->wdiReqStatusCB = pwdiUpdateScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateScanParams->pUserData; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "End Update Scan Parameters Old Style"); + + /*Set the output values*/ + *ppSendBuffer = pSendBuffer; + *pSize = usSendSize; + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Update Scan Params function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_PackUpdateScanParamsReqEx +( + WDI_ControlBlockType* pWDICtx, + WDI_UpdateScanParamsInfoType* pwdiUpdateScanParams, + wpt_uint8** ppSendBuffer, + wpt_uint16* pSize +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tUpdateScanParamsEx updateScanParams = {0}; + + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_SCAN_PARAMS_REQ, + sizeof(updateScanParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(updateScanParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Update Scan Params Ex req %p", + pwdiUpdateScanParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + // + // Fill updateScanParams from pwdiUpdateScanParams->wdiUpdateScanParamsInfo + // + + updateScanParams.b11dEnabled = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dEnabled; + updateScanParams.b11dResolved = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.b11dResolved; + + updateScanParams.ucChannelCount = + (pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount < + WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX)? + pwdiUpdateScanParams->wdiUpdateScanParamsInfo.ucChannelCount : + WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX; + + wpalMemoryCopy( updateScanParams.aChannels, + pwdiUpdateScanParams->wdiUpdateScanParamsInfo.aChannels, + updateScanParams.ucChannelCount); + + + updateScanParams.usActiveMinChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMinChTime; + updateScanParams.usActiveMaxChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usActiveMaxChTime; + updateScanParams.usPassiveMinChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMinChTime; + updateScanParams.usPassiveMaxChTime = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.usPassiveMaxChTime; + updateScanParams.cbState = pwdiUpdateScanParams->wdiUpdateScanParamsInfo.cbState; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &updateScanParams, + sizeof(updateScanParams)); + + pWDICtx->wdiReqStatusCB = pwdiUpdateScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateScanParams->pUserData; + + /*Set the output values*/ + *ppSendBuffer = pSendBuffer; + *pSize = usSendSize; + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Update Scan Params function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateScanParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateScanParamsInfoType* pwdiUpdateScanParams = NULL; + WDI_UpdateScanParamsCb wdiUpdateScanParamsCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiUpdateScanParams = (WDI_UpdateScanParamsInfoType*)pEventData->pEventData)) || + ( NULL == (wdiUpdateScanParamsCb = (WDI_UpdateScanParamsCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Begin WDI Update Scan Parameters"); + + // + // Fill updateScanParams from pwdiUpdateScanParams->wdiUpdateScanParamsInfo + // + if ( pWDICtx->wlanVersion.revision < 1 ) + { + wdiStatus = WDI_PackUpdateScanParamsReq( pWDICtx, pwdiUpdateScanParams, + &pSendBuffer, &usSendSize); + } + else + { + wdiStatus = WDI_PackUpdateScanParamsReqEx( pWDICtx, pwdiUpdateScanParams, + &pSendBuffer, &usSendSize); + } + + if(WDI_STATUS_SUCCESS != wdiStatus) + { + //memory allocation failed + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiUpdateScanParamsCb, pEventData->pUserData, + WDI_UPDATE_SCAN_PARAMS_RESP); +} + +/** + @brief Process Update Channel Params function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateChannelParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateChReqParamsType *pwdiUpdateChanListParams = NULL; + WDI_UpdateChannelRspCb wdiUpdateChanParamsCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tUpdateChannelReqType *updateChannelParams; + wpt_uint32 usUpdateChanParamSize; + wpt_uint8 num_channels = 0; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiUpdateChanListParams = (WDI_UpdateChReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiUpdateChanParamsCb = (WDI_UpdateChannelRspCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + num_channels = pwdiUpdateChanListParams->wdiUpdateChanParams.numchan; + usUpdateChanParamSize = sizeof(tUpdateChannelReqType); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_UPDATE_CHAN_REQ, usUpdateChanParamSize, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usUpdateChanParamSize))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Update Channel Params req %p", + pwdiUpdateChanListParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + updateChannelParams = (tUpdateChannelReqType *)(pSendBuffer + usDataOffset); + + updateChannelParams->numChan = num_channels; + wpalMemoryCopy(&updateChannelParams->chanParam, + pwdiUpdateChanListParams->wdiUpdateChanParams.pchanParam, + sizeof(WDI_UpdateChannelReqinfoType) * num_channels); + + pWDICtx->wdiReqStatusCB = pwdiUpdateChanListParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateChanListParams->pUserData; + + /*------------------------------------------------------------------------- + Send Update channel request to fw + -------------------------------------------------------------------------*/ + return WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize, + wdiUpdateChanParamsCb, pEventData->pUserData, + WDI_UPDATE_CHAN_RESP); +} + +/** + @brief Process Preferred Network Found Indication function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessPrefNetworkFoundInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tpPrefNetwFoundParams pNetwFoundParams; + wpt_uint32 msgsize; + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + pNetwFoundParams = (tpPrefNetwFoundParams)(pEventData->pEventData); + + msgsize = sizeof(tPrefNetwFoundParams) + pNetwFoundParams->frameLength; + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData = + (wpt_uint8 *)wpalMemoryAllocate(msgsize); + + if (NULL == wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: fail to allocate memory", __func__); + return WDI_STATUS_MEM_FAILURE; + } + + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength = + (pNetwFoundParams->ssId.length < 32 )? + pNetwFoundParams->ssId.length : 32; + wpalMemoryCopy( wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.sSSID, + pNetwFoundParams->ssId.ssId, + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength); + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.rssi = pNetwFoundParams->rssi; + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.frameLength = + pNetwFoundParams->frameLength; + wpalMemoryCopy( wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData, + (wpt_uint8 *)pEventData->pEventData + sizeof(tPrefNetwFoundParams), + pNetwFoundParams->frameLength); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_PREF_NETWORK_FOUND_IND; + + // DEBUG + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "[PNO WDI] PREF_NETWORK_FOUND_IND Type (%d) data (SSID=%.*s, LENGTH=%u, RSSI=%u)", + wdiInd.wdiIndicationType, + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength, + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.sSSID, + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.ssId.ucLength, + wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.rssi ); + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + vos_mem_free( wdiInd.wdiIndicationData.wdiPrefNetworkFoundInd.pData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process PNO Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPreferredNetworkRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_PNOScanCb wdiPNOScanCb = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + wdiPNOScanCb = (WDI_PNOScanCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiPNOScanCb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetPreferredNetworkRsp*/ + +/** + @brief Process RSSI Filter Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetRssiFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_RssiFilterCb wdiRssiFilterCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRssiFilterCb = (WDI_RssiFilterCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiRssiFilterCb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetRssiFilterRsp*/ + +/** + @brief Process Update Scan Params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateScanParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + tUpdateScanParamsResp halUpdScanParams; + WDI_UpdateScanParamsCb wdiUpdateScanParamsCb = NULL; + wpt_uint32 uStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Process UPD scan params ptr : %p", + __func__, pEventData->pEventData); + + wdiUpdateScanParamsCb = (WDI_UpdateScanParamsCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( (void *)&halUpdScanParams.status, + pEventData->pEventData, + sizeof(halUpdScanParams.status)); + + uStatus = halUpdScanParams.status; + + /*Extract PNO version - 1st bit of the status */ + pWDICtx->wdiPNOVersion = (uStatus & WDI_PNO_VERSION_MASK)? 1:0; + + /*Remove version bit*/ + uStatus = uStatus & ( ~(WDI_PNO_VERSION_MASK)); + + wdiStatus = WDI_HAL_2_WDI_STATUS(uStatus); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "UPD Scan Parameters rsp with status: %d", + halUpdScanParams.status); + + /*Notify UMAC*/ + wdiUpdateScanParamsCb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif // FEATURE_WLAN_SCAN_PNO + +#ifdef WLAN_FEATURE_PACKET_FILTERING +WDI_Status +WDI_8023MulticastListReq +( + WDI_RcvFltPktSetMcListReqParamsType* pwdiRcvFltPktSetMcListReqInfo, + WDI_8023MulticastListCb wdi8023MulticastListCallback, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_8023_MULTICAST_LIST_REQ; + wdiEventData.pEventData = pwdiRcvFltPktSetMcListReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiRcvFltPktSetMcListReqInfo); + wdiEventData.pCBfnc = wdi8023MulticastListCallback; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_ReceiveFilterSetFilterReq +( + WDI_SetRcvPktFilterReqParamsType* pwdiSetRcvPktFilterReqInfo, + WDI_ReceiveFilterSetFilterCb wdiReceiveFilterSetFilterCallback, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RECEIVE_FILTER_SET_FILTER_REQ; + wdiEventData.pEventData = pwdiSetRcvPktFilterReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiSetRcvPktFilterReqInfo) + + (pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams - 1) + * sizeof(WDI_RcvPktFilterFieldParams); + wdiEventData.pCBfnc = wdiReceiveFilterSetFilterCallback; + wdiEventData.pUserData = pUserData; + + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_FilterMatchCountReq +( + WDI_RcvFltPktMatchCntReqParamsType* pwdiRcvFltPktMatchCntReqInfo, + WDI_FilterMatchCountCb wdiFilterMatchCountCallback, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ; + wdiEventData.pEventData = pwdiRcvFltPktMatchCntReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiRcvFltPktMatchCntReqInfo); + wdiEventData.pCBfnc = wdiFilterMatchCountCallback; + wdiEventData.pUserData = pUserData; + + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_ReceiveFilterClearFilterReq +( + WDI_RcvFltPktClearReqParamsType* pwdiRcvFltPktClearReqInfo, + WDI_ReceiveFilterClearFilterCb wdiReceiveFilterClearFilterCallback, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ; + wdiEventData.pEventData = pwdiRcvFltPktClearReqInfo; + wdiEventData.uEventDataSize = sizeof(*pwdiRcvFltPktClearReqInfo); + wdiEventData.pCBfnc = wdiReceiveFilterClearFilterCallback; + wdiEventData.pUserData = pUserData; + + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Process 8023 Multicast List Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_Process8023MulticastListReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RcvFltPktSetMcListReqParamsType* pwdiFltPktSetMcListReqParamsType = NULL; + WDI_8023MulticastListCb wdi8023MulticastListCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tpHalRcvFltMcAddrListType pRcvFltMcAddrListType; + wpt_uint8 i; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + pRcvFltMcAddrListType = wpalMemoryAllocate(sizeof(tHalRcvFltMcAddrListType)) ; + if( NULL == pRcvFltMcAddrListType ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Failed to alloc in WDI_Process8023MulticastListReq"); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiFltPktSetMcListReqParamsType = + (WDI_RcvFltPktSetMcListReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdi8023MulticastListCb = + (WDI_8023MulticastListCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + wpalMemoryFree(pRcvFltMcAddrListType); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiFltPktSetMcListReqParamsType->mcAddrList.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + wpalMemoryFree(pRcvFltMcAddrListType); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_8023_MULTICAST_LIST_REQ, + sizeof(tHalRcvFltMcAddrListType), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalRcvFltMcAddrListType)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in " + "WDI_Process8023MulticastListReq() %p %p %p", + pEventData, pwdiFltPktSetMcListReqParamsType, + wdi8023MulticastListCb); + wpalMemoryFree(pRcvFltMcAddrListType); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pRcvFltMcAddrListType->cMulticastAddr = + pwdiFltPktSetMcListReqParamsType->mcAddrList.ulMulticastAddrCnt; + for( i = 0; i < pRcvFltMcAddrListType->cMulticastAddr; i++ ) + { + wpalMemoryCopy(pRcvFltMcAddrListType->multicastAddr[i], + pwdiFltPktSetMcListReqParamsType->mcAddrList.multicastAddr[i], + sizeof(tSirMacAddr)); + } + + pRcvFltMcAddrListType->bssIdx = pBSSSes->ucBSSIdx; + wpalMemoryCopy( pSendBuffer+usDataOffset, + pRcvFltMcAddrListType, + sizeof(tHalRcvFltMcAddrListType)); + + pWDICtx->wdiReqStatusCB = pwdiFltPktSetMcListReqParamsType->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiFltPktSetMcListReqParamsType->pUserData; + + + wpalMemoryFree(pRcvFltMcAddrListType); + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdi8023MulticastListCb, pEventData->pUserData, + WDI_8023_MULTICAST_LIST_RESP); +} + +/** + @brief Process Receive Filter Set Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterSetFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetRcvPktFilterReqParamsType* pwdiSetRcvPktFilterReqInfo = NULL; + WDI_ReceiveFilterSetFilterCb wdiReceiveFilterSetFilterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint32 usRcvPktFilterCfgSize; + tHalRcvPktFilterCfgType *pRcvPktFilterCfg = NULL; + wpt_uint8 i; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + tHalSessionizedRcvPktFilterCfgType *pSessRcvPktFilterCfg = NULL; + wpt_uint32 usSessRcvPktFilterCfgSize; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiSetRcvPktFilterReqInfo = + (WDI_SetRcvPktFilterReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiReceiveFilterSetFilterCb = + (WDI_ReceiveFilterSetFilterCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + return WDI_STATUS_E_FAILURE; + } + + if( WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION) ) + { + + usSessRcvPktFilterCfgSize = sizeof(tHalSessionizedRcvPktFilterCfgType) + + ((pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams - 1) + * sizeof(tHalSessionizedRcvPktFilterCfgType)); + + pSessRcvPktFilterCfg = (tHalSessionizedRcvPktFilterCfgType *)wpalMemoryAllocate( + usSessRcvPktFilterCfgSize); + + if(NULL == pSessRcvPktFilterCfg) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to allocate memory for " + "tHalRcvPktFilterCfgType: %p %p %p ", + __func__, pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(pSessRcvPktFilterCfg, usSessRcvPktFilterCfgSize); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RECEIVE_FILTER_SET_FILTER_REQ, + usSessRcvPktFilterCfgSize, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usSessRcvPktFilterCfgSize))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in " + "WDI_ProcessReceiveFilterSetFilterReq() %p %p %p", + pEventData, pwdiSetRcvPktFilterReqInfo, + wdiReceiveFilterSetFilterCb); + WDI_ASSERT(0); + wpalMemoryFree(pSessRcvPktFilterCfg); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "UsData Off %d UsSend %d cfg %p",usDataOffset, + usSendSize,pSessRcvPktFilterCfg); + + pSessRcvPktFilterCfg->filterId = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterId; + pSessRcvPktFilterCfg->filterType = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterType; + pSessRcvPktFilterCfg->numParams = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams; + pSessRcvPktFilterCfg->coleasceTime = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.coalesceTime; + + pSessRcvPktFilterCfg->bssIdx = pBSSSes->ucBSSIdx; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Out: FID %d FT %d",pSessRcvPktFilterCfg->filterId, + pSessRcvPktFilterCfg->filterType); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "NParams %d CT %d",pSessRcvPktFilterCfg->numParams, + pSessRcvPktFilterCfg->coleasceTime); + + for ( i = 0; i < pSessRcvPktFilterCfg->numParams; i++ ) + { + pSessRcvPktFilterCfg->paramsData[i].protocolLayer = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].protocolLayer; + pSessRcvPktFilterCfg->paramsData[i].cmpFlag = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].cmpFlag; + pSessRcvPktFilterCfg->paramsData[i].dataOffset = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataOffset; + pSessRcvPktFilterCfg->paramsData[i].dataLength = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataLength; + + wpalMemoryCopy(&pSessRcvPktFilterCfg->paramsData[i].compareData, + &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].compareData, + 8); + wpalMemoryCopy(&pSessRcvPktFilterCfg->paramsData[i].dataMask, + &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataMask, + 8); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Out:Proto %d Comp Flag %d", + pSessRcvPktFilterCfg->paramsData[i].protocolLayer, + pSessRcvPktFilterCfg->paramsData[i].cmpFlag); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Data Offset %d Data Len %d", + pSessRcvPktFilterCfg->paramsData[i].dataOffset, + pSessRcvPktFilterCfg->paramsData[i].dataLength); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "CData: %d:%d:%d:%d:%d:%d", + pSessRcvPktFilterCfg->paramsData[i].compareData[0], + pSessRcvPktFilterCfg->paramsData[i].compareData[1], + pSessRcvPktFilterCfg->paramsData[i].compareData[2], + pSessRcvPktFilterCfg->paramsData[i].compareData[3], + pSessRcvPktFilterCfg->paramsData[i].compareData[4], + pSessRcvPktFilterCfg->paramsData[i].compareData[5]); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "MData: %d:%d:%d:%d:%d:%d", + pSessRcvPktFilterCfg->paramsData[i].dataMask[0], + pSessRcvPktFilterCfg->paramsData[i].dataMask[1], + pSessRcvPktFilterCfg->paramsData[i].dataMask[2], + pSessRcvPktFilterCfg->paramsData[i].dataMask[3], + pSessRcvPktFilterCfg->paramsData[i].dataMask[4], + pSessRcvPktFilterCfg->paramsData[i].dataMask[5]); + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + pSessRcvPktFilterCfg, + usSessRcvPktFilterCfgSize); + + + pWDICtx->wdiReqStatusCB = pwdiSetRcvPktFilterReqInfo->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetRcvPktFilterReqInfo->pUserData; + + wpalMemoryFree(pSessRcvPktFilterCfg); + + } + /*If SLM_SESSIONIZATION is not supported then do this */ + else + { + usRcvPktFilterCfgSize = sizeof(tHalRcvPktFilterCfgType) + + ((pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams - 1) + * sizeof(tHalRcvPktFilterParams)); + + pRcvPktFilterCfg = (tHalRcvPktFilterCfgType *)wpalMemoryAllocate( + usRcvPktFilterCfgSize); + + if(NULL == pRcvPktFilterCfg) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to allocate memory for " + "tHalRcvPktFilterCfgType: %p %p %p ", + __func__, pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(pRcvPktFilterCfg, usRcvPktFilterCfgSize); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_RECEIVE_FILTER_SET_FILTER_REQ, + usRcvPktFilterCfgSize, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usRcvPktFilterCfgSize))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in " + "WDI_ProcessReceiveFilterSetFilterReq() %p %p %p", + pEventData, pwdiSetRcvPktFilterReqInfo, + wdiReceiveFilterSetFilterCb); + WDI_ASSERT(0); + wpalMemoryFree(pRcvPktFilterCfg); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "UsData Off %d UsSend %d cfg %d",usDataOffset, + usSendSize,usRcvPktFilterCfgSize); + + pRcvPktFilterCfg->filterId = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterId; + pRcvPktFilterCfg->filterType = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.filterType; + pRcvPktFilterCfg->numParams = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.numFieldParams; + pRcvPktFilterCfg->coalesceTime = pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.coalesceTime; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Out: FID %d FT %d",pRcvPktFilterCfg->filterId, + pRcvPktFilterCfg->filterType); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "NParams %d CT %d",pRcvPktFilterCfg->numParams, + pRcvPktFilterCfg->coalesceTime); + + for ( i = 0; i < pRcvPktFilterCfg->numParams; i++ ) + { + pRcvPktFilterCfg->paramsData[i].protocolLayer = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].protocolLayer; + pRcvPktFilterCfg->paramsData[i].cmpFlag = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].cmpFlag; + pRcvPktFilterCfg->paramsData[i].dataOffset = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataOffset; + pRcvPktFilterCfg->paramsData[i].dataLength = + pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataLength; + + wpalMemoryCopy(&pRcvPktFilterCfg->paramsData[i].compareData, + &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].compareData, + 8); + wpalMemoryCopy(&pRcvPktFilterCfg->paramsData[i].dataMask, + &pwdiSetRcvPktFilterReqInfo->wdiPktFilterCfg.paramsData[i].dataMask, + 8); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Out:Proto %d Comp Flag %d", + pRcvPktFilterCfg->paramsData[i].protocolLayer, + pRcvPktFilterCfg->paramsData[i].cmpFlag); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Data Offset %d Data Len %d", + pRcvPktFilterCfg->paramsData[i].dataOffset, + pRcvPktFilterCfg->paramsData[i].dataLength); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "CData: %d:%d:%d:%d:%d:%d", + pRcvPktFilterCfg->paramsData[i].compareData[0], + pRcvPktFilterCfg->paramsData[i].compareData[1], + pRcvPktFilterCfg->paramsData[i].compareData[2], + pRcvPktFilterCfg->paramsData[i].compareData[3], + pRcvPktFilterCfg->paramsData[i].compareData[4], + pRcvPktFilterCfg->paramsData[i].compareData[5]); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "MData: %d:%d:%d:%d:%d:%d", + pRcvPktFilterCfg->paramsData[i].dataMask[0], + pRcvPktFilterCfg->paramsData[i].dataMask[1], + pRcvPktFilterCfg->paramsData[i].dataMask[2], + pRcvPktFilterCfg->paramsData[i].dataMask[3], + pRcvPktFilterCfg->paramsData[i].dataMask[4], + pRcvPktFilterCfg->paramsData[i].dataMask[5]); + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + pRcvPktFilterCfg, + usRcvPktFilterCfgSize); + + + pWDICtx->wdiReqStatusCB = pwdiSetRcvPktFilterReqInfo->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiSetRcvPktFilterReqInfo->pUserData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + wpalMemoryFree(pRcvPktFilterCfg); + } + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiReceiveFilterSetFilterCb, pEventData->pUserData, + WDI_RECEIVE_FILTER_SET_FILTER_RESP); +} + +/** + @brief Process Packet Filter Match Count Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFilterMatchCountReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RcvFltPktMatchCntReqParamsType* pwdiRcvFltPktMatchCntReqParamsType = + NULL; + WDI_FilterMatchCountCb wdiFilterMatchCountCb = + NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalRcvFltPktMatchCntReqParams rcvFltPktMatchCntReqParam = {0}; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiRcvFltPktMatchCntReqParamsType = + (WDI_RcvFltPktMatchCntReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiFilterMatchCountCb = + (WDI_FilterMatchCountCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentBSSSesIdx = WDI_FindAssocSession( pWDICtx, + pwdiRcvFltPktMatchCntReqParamsType->bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_REQ, + sizeof(tHalRcvFltPktMatchCntReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalRcvFltPktMatchCntReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in " + "WDI_ProcessFilterMatchCountReq() %p %p %p", + pEventData, pwdiRcvFltPktMatchCntReqParamsType, + wdiFilterMatchCountCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + rcvFltPktMatchCntReqParam.bssIdx = pBSSSes->ucBSSIdx; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &rcvFltPktMatchCntReqParam, + sizeof(rcvFltPktMatchCntReqParam)); + + // + // Don't need to fill send buffer other than header + // + pWDICtx->wdiReqStatusCB = pwdiRcvFltPktMatchCntReqParamsType->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRcvFltPktMatchCntReqParamsType->pUserData; + + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiFilterMatchCountCb, + pEventData->pUserData, + WDI_PACKET_COALESCING_FILTER_MATCH_COUNT_RESP); +} + +/** + @brief Process Receive Filter Clear Filter Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterClearFilterReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RcvFltPktClearReqParamsType* pwdiRcvFltPktClearReqParamsType = NULL; + WDI_ReceiveFilterClearFilterCb wdiRcvFltPktClearFilterCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalRcvFltPktClearParam rcvFltPktClearParam; + wpt_uint8 ucCurrentSessionId = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiRcvFltPktClearReqParamsType = + (WDI_RcvFltPktClearReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiRcvFltPktClearFilterCb = + (WDI_ReceiveFilterClearFilterCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ucCurrentSessionId = WDI_FindAssocSession( pWDICtx, + pwdiRcvFltPktClearReqParamsType->filterClearParam.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_RECEIVE_FILTER_CLEAR_FILTER_REQ, + sizeof(tHalRcvFltPktClearParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalRcvFltPktClearParam)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in " + "WDI_ProcessReceiveFilterClearFilterReq() %p %p %p", + pEventData, pwdiRcvFltPktClearReqParamsType, + wdiRcvFltPktClearFilterCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + rcvFltPktClearParam.status = pwdiRcvFltPktClearReqParamsType-> + filterClearParam.status; + rcvFltPktClearParam.filterId = pwdiRcvFltPktClearReqParamsType-> + filterClearParam.filterId; + + rcvFltPktClearParam.bssIdx = pBSSSes->ucBSSIdx; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &rcvFltPktClearParam, + sizeof(rcvFltPktClearParam)); + + pWDICtx->wdiReqStatusCB = pwdiRcvFltPktClearReqParamsType->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRcvFltPktClearReqParamsType->pUserData; + + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRcvFltPktClearFilterCb, pEventData->pUserData, + WDI_RECEIVE_FILTER_CLEAR_FILTER_RESP); +} + +/** + @brief Process 8023 Multicast List Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_Process8023MulticastListRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_8023MulticastListCb wdi8023MulticastListCb; + tHalRcvFltPktSetMcListRspType halRcvFltPktSetMcListRsp; + WDI_RcvFltPktSetMcListRspParamsType wdiRcvFltPktSetMcListRspInfo; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi8023MulticastListCb = (WDI_8023MulticastListCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halRcvFltPktSetMcListRsp, + pEventData->pEventData, + sizeof(halRcvFltPktSetMcListRsp)); + + wdiRcvFltPktSetMcListRspInfo.wdiStatus = + WDI_HAL_2_WDI_STATUS(halRcvFltPktSetMcListRsp.status); + wdiRcvFltPktSetMcListRspInfo.bssIdx = + halRcvFltPktSetMcListRsp.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiRcvFltPktSetMcListRspInfo.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + /*Notify UMAC*/ + wdi8023MulticastListCb(&wdiRcvFltPktSetMcListRspInfo, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Set Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterSetFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_ReceiveFilterSetFilterCb wdiReceiveFilterSetFilterCb; + tHalSetPktFilterRspParams halSetPktFilterRspParams; + WDI_SetRcvPktFilterRspParamsType wdiSetRcvPktFilterRspInfo; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiReceiveFilterSetFilterCb = (WDI_ReceiveFilterSetFilterCb)pWDICtx-> + pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halSetPktFilterRspParams, + pEventData->pEventData, + sizeof(halSetPktFilterRspParams)); + + wdiSetRcvPktFilterRspInfo.bssIdx = halSetPktFilterRspParams.bssIdx; + wdiSetRcvPktFilterRspInfo.wdiStatus = WDI_HAL_2_WDI_STATUS(halSetPktFilterRspParams.status); + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiSetRcvPktFilterRspInfo.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + /*Notify UMAC*/ + wdiReceiveFilterSetFilterCb(&wdiSetRcvPktFilterRspInfo, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Packet Filter Match Count Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFilterMatchCountRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_FilterMatchCountCb wdiFilterMatchCountCb; + tHalRcvFltPktMatchRspParams halRcvFltrPktMatachRsp; + WDI_RcvFltPktMatchCntRspParamsType wdiRcvFltPktMatchRspParams; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiFilterMatchCountCb = (WDI_FilterMatchCountCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halRcvFltrPktMatachRsp, + pEventData->pEventData, + sizeof(halRcvFltrPktMatachRsp)); + + wdiRcvFltPktMatchRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halRcvFltrPktMatachRsp.status); + wdiRcvFltPktMatchRspParams.bssIdx = halRcvFltrPktMatachRsp.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiRcvFltPktMatchRspParams.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + /*Notify UMAC*/ + wdiFilterMatchCountCb(&wdiRcvFltPktMatchRspParams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Receive Filter Clear Filter Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessReceiveFilterClearFilterRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_ReceiveFilterClearFilterCb wdiReceiveFilterClearFilterCb; + tHalRcvFltPktClearParam halRcvFltPktClearRspMsg; + WDI_RcvFltPktClearRspParamsType wdiRcvFltPktClearRspParamsType; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiReceiveFilterClearFilterCb = (WDI_ReceiveFilterClearFilterCb)pWDICtx-> + pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halRcvFltPktClearRspMsg, + pEventData->pEventData, + sizeof(halRcvFltPktClearRspMsg)); + + wdiRcvFltPktClearRspParamsType.wdiStatus = + WDI_HAL_2_WDI_STATUS(halRcvFltPktClearRspMsg.status); + wdiRcvFltPktClearRspParamsType.bssIdx = + halRcvFltPktClearRspMsg.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiRcvFltPktClearRspParamsType.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + /*Notify UMAC*/ + wdiReceiveFilterClearFilterCb(&wdiRcvFltPktClearRspParamsType, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_PACKET_FILTERING + +/** + @brief Process Shutdown Rsp function + There is no shutdown response comming from HAL + - function just kept for simmetry + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessShutdownRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + /*There is no shutdown response comming from HAL - function just kept for + simmetry */ + WDI_ASSERT(0); + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessShutdownRsp*/ + +/** + @brief WDI_SetPowerParamsReq + + @param pwdiPowerParamsReqParams: the Set Power Params as + specified by the Device Interface + + wdiPowerParamsCb: callback for passing back the response + of the Set Power Params operation received from the + device + + pUserData: user data will be passed back with the + callback + + @return Result of the function call +*/ +WDI_Status +WDI_SetPowerParamsReq +( + WDI_SetPowerParamsReqParamsType* pwdiPowerParamsReqParams, + WDI_SetPowerParamsCb wdiPowerParamsCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_POWER_PARAMS_REQ; + wdiEventData.pEventData = pwdiPowerParamsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiPowerParamsReqParams); + wdiEventData.pCBfnc = wdiPowerParamsCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +}/*WDI_SetPowerParamsReq*/ + +/** + @brief Process Set Power Params Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPowerParamsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetPowerParamsReqParamsType* pwdiPowerParamsReqParams = NULL; + WDI_SetPowerParamsCb wdiPowerParamsCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSetPowerParamsType powerParams; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiPowerParamsReqParams = (WDI_SetPowerParamsReqParamsType*)pEventData->pEventData)) || + ( NULL == (wdiPowerParamsCb = (WDI_SetPowerParamsCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_POWER_PARAMS_REQ, + sizeof(powerParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(powerParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set PNO req %p %p %p", + pEventData, pwdiPowerParamsReqParams, wdiPowerParamsCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Ignore DTIM */ + powerParams.uIgnoreDTIM = + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uIgnoreDTIM; + + /*DTIM Period*/ + powerParams.uDTIMPeriod = + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uDTIMPeriod; + + /* Listen Interval */ + powerParams.uListenInterval= + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uListenInterval; + + /* Broadcast Multicas Filter */ + powerParams.uBcastMcastFilter = + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uBcastMcastFilter; + + /* Beacon Early Termination */ + powerParams.uEnableBET = + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uEnableBET; + + /* Beacon Early Termination Interval */ + powerParams.uBETInterval = + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uBETInterval; + + /* MAX LI for modulated DTIM */ + powerParams.uMaxLIModulatedDTIM = + pwdiPowerParamsReqParams->wdiSetPowerParamsInfo.uMaxLIModulatedDTIM; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &powerParams, + sizeof(powerParams)); + + pWDICtx->wdiReqStatusCB = pwdiPowerParamsReqParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiPowerParamsReqParams->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiPowerParamsCb, pEventData->pUserData, WDI_SET_POWER_PARAMS_RESP); +} + +/** + @brief Process Power Params Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetPowerParamsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetPowerParamsCb wdiPowerParamsCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiPowerParamsCb = (WDI_SetPowerParamsCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiPowerParamsCb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetPowerParamsRsp*/ + +/** + @brief WDI_dhcpStartInd + Host will send an event to the FW when DHCP is initiated + + @param + WDI_DHCPInd: DHCP Indication + @see + @return Result of the function call +*/ +WDI_Status +WDI_dhcpStartInd +( + WDI_DHCPInd *wdiDHCPInd +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_DHCP_START_IND; + wdiEventData.pEventData = wdiDHCPInd; + wdiEventData.uEventDataSize = sizeof(WDI_DHCPInd); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief WDI_dhcpStopInd + Host will send an event to the FW when DHCP is completed + + @param + WDI_DHCPInd: DHCP Indication + @see + @return Result of the function call +*/ +WDI_Status +WDI_dhcpStopInd +( + WDI_DHCPInd *wdiDHCPInd +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_DHCP_STOP_IND; + wdiEventData.pEventData = wdiDHCPInd; + wdiEventData.uEventDataSize = sizeof(WDI_DHCPInd); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +#ifdef WLAN_FEATURE_RMC +/** + @brief WDI_TXFailMonitorInd + Host will send an event to the FW to start TX Fail Monitor + + @param + WDI_TXFailMonitorInd + @see + @return Result of the function call +*/ +WDI_Status +WDI_TXFailMonitorStartStopInd +( + WDI_TXFailMonitorInd *wdiTXFailMonitorInd +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_TX_FAIL_MONITOR_IND; + wdiEventData.pEventData = wdiTXFailMonitorInd; + wdiEventData.uEventDataSize = sizeof(wdiTXFailMonitorInd); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} +#endif /* WLAN_FEATURE_RMC */ + +/** + @brief Process DHCP Start Indication message and post it to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDHCPStartInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usLen = 0; + WDI_DHCPInd* pwdiDHCPInd = NULL; + tDHCPInfo* pDHCPInfo; + WDI_Status wdiStatus; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiDHCPInd = (WDI_DHCPInd*)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_DHCP_START_IND, + sizeof(tDHCPInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in DHCP Start req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pDHCPInfo = (tDHCPInfo*)(pSendBuffer+usDataOffset); + pDHCPInfo->device_mode = pwdiDHCPInd->device_mode; + wpalMemoryCopy(pDHCPInfo->macAddr, pwdiDHCPInd->macAddr, + WDI_MAC_ADDR_LEN); + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + /*------------------------------------------------------------------------- + Send DHCP Start Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +}/*WDI_ProcessDHCPStartInd*/ + +/** + @brief Process DHCP Stop indication message and post it to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessDHCPStopInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usLen = 0; + WDI_DHCPInd* pwdiDHCPInd = NULL; + tDHCPInfo* pDHCPInfo; + WDI_Status wdiStatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiDHCPInd = (WDI_DHCPInd*)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_DHCP_STOP_IND, + sizeof(tDHCPInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in DHCP Start req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pDHCPInfo = (tDHCPInfo*)(pSendBuffer+usDataOffset); + pDHCPInfo->device_mode = pwdiDHCPInd->device_mode; + wpalMemoryCopy(pDHCPInfo->macAddr, pwdiDHCPInd->macAddr, + WDI_MAC_ADDR_LEN); + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send DHCP Stop indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; + +}/*WDI_ProcessDHCPStopInd*/ + +#ifdef WLAN_FEATURE_RMC +/** + @brief Process TX Fail monitor indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTXFailMonitor +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usLen = 0; + WDI_TXFailMonitorInd* pwdiTxFailMonitorInd = NULL; + tTXFailMonitorInfo* pTXFailMonitorInfo; + WDI_Status wdiStatus; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiTxFailMonitorInd = (WDI_TXFailMonitorInd*)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_TX_FAIL_MONITOR_IND, + sizeof(tDHCPInfo), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in DHCP Start req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pTXFailMonitorInfo = (tTXFailMonitorInfo*)pSendBuffer+usDataOffset; + pTXFailMonitorInfo->tx_fail_count = pwdiTxFailMonitorInd->tx_fail_count; + + pWDICtx->pReqStatusUserData = pwdiTxFailMonitorInd->pUserData; + pWDICtx->wdiReqStatusCB = pwdiTxFailMonitorInd->wdiReqStatusCB; + /*------------------------------------------------------------------------- + Send TX Fail Monitor start/stop indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + + return (wdiStatus != WDI_STATUS_SUCCESS)?wdiStatus:WDI_STATUS_SUCCESS_SYNC; +}/*WDI_ProcessTXFailMonitor*/ +#endif /* WLAN_FEATURE_RMC */ + +#ifdef WLAN_FEATURE_GTK_OFFLOAD +/** + @brief WDI_GTKOffloadReq will be called when the upper MAC + wants to set GTK Rekey Counter while in power save. Upon + the call of this API the WLAN DAL will pack and send a + HAL GTK offload request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiGtkOffloadParams: the GTK offload as specified + by the Device Interface + + wdiGtkOffloadCb: callback for passing back the response + of the GTK offload operation received from the device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_GTKOffloadReq +( + WDI_GtkOffloadReqMsg* pwdiGtkOffloadReqMsg, + WDI_GtkOffloadCb wdiGtkOffloadCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GTK_OFFLOAD_REQ; + wdiEventData.pEventData = pwdiGtkOffloadReqMsg; + wdiEventData.uEventDataSize = sizeof(*pwdiGtkOffloadReqMsg); + wdiEventData.pCBfnc = wdiGtkOffloadCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief WDI_GTKOffloadGetInfoReq will be called when the upper + MAC wants to get GTK Rekey Counter while in power save. + Upon the call of this API the WLAN DAL will pack and + send a HAL GTK offload request message to the lower RIVA + sub-system if DAL is in state STARTED. + + In state BUSY this request will be queued. Request won't + be allowed in any other state. + + WDI_PostAssocReq must have been called. + + @param pwdiGtkOffloadGetInfoReqMsg: the GTK Offload + Information Message as specified by the + Device Interface + + wdiGtkOffloadGetInfoCb: callback for passing back the + response of the GTK offload operation received from the + device + + pUserData: user data will be passed back with the + callback + + @see WDI_PostAssocReq + @return Result of the function call +*/ +WDI_Status +WDI_GTKOffloadGetInfoReq +( + WDI_GtkOffloadGetInfoReqMsg* pwdiGtkOffloadGetInfoReqMsg, + WDI_GtkOffloadGetInfoCb wdiGtkOffloadGetInfoCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GTK_OFFLOAD_GETINFO_REQ; + wdiEventData.pEventData = pwdiGtkOffloadGetInfoReqMsg; + wdiEventData.uEventDataSize = sizeof(*pwdiGtkOffloadGetInfoReqMsg); + wdiEventData.pCBfnc = wdiGtkOffloadGetInfoCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + + +/** + @brief Process set GTK Offload Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GtkOffloadReqMsg* pwdiGtkOffloadReqMsg = NULL; + WDI_GtkOffloadCb wdiGtkOffloadCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalGtkOffloadReqParams gtkOffloadReqParams = {0}; + wpt_uint8 ucCurrentSessionId = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiGtkOffloadReqMsg = (WDI_GtkOffloadReqMsg*)pEventData->pEventData)) || + ( NULL == (wdiGtkOffloadCb = (WDI_GtkOffloadCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GTK_OFFLOAD_REQ, + sizeof(gtkOffloadReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(gtkOffloadReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in GTK offload req %p %p %p", + pEventData, pwdiGtkOffloadReqMsg, wdiGtkOffloadCb); + WDI_ASSERT(0); + goto failRequest; + } + + // + // Fill gtkOffloadReqParams from pwdiGtkOffloadReqMsg->gtkOffloadReqParams + // + ucCurrentSessionId = WDI_FindAssocSession( pWDICtx, + pwdiGtkOffloadReqMsg->gtkOffloadReqParams.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist", __func__); + goto fail; + } + + gtkOffloadReqParams.bssIdx = pBSSSes->ucBSSIdx; + + gtkOffloadReqParams.ulFlags = pwdiGtkOffloadReqMsg->gtkOffloadReqParams.ulFlags; + // Copy KCK + wpalMemoryCopy(&(gtkOffloadReqParams.aKCK[0]), &(pwdiGtkOffloadReqMsg->gtkOffloadReqParams.aKCK[0]), 16); + // Copy KEK + wpalMemoryCopy(&(gtkOffloadReqParams.aKEK[0]), &(pwdiGtkOffloadReqMsg->gtkOffloadReqParams.aKEK[0]), 16); + // Copy KeyReplayCounter + wpalMemoryCopy(&(gtkOffloadReqParams.ullKeyReplayCounter), &(pwdiGtkOffloadReqMsg->gtkOffloadReqParams.ullKeyReplayCounter), sizeof(v_U64_t)); + + wpalMemoryCopy( pSendBuffer+usDataOffset, + >kOffloadReqParams, + sizeof(gtkOffloadReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiGtkOffloadReqMsg->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiGtkOffloadReqMsg->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiGtkOffloadCb, pEventData->pUserData, WDI_GTK_OFFLOAD_RESP); + +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +} + + +/** + @brief Process GTK Offload Get Information Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadGetInfoReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GtkOffloadGetInfoReqMsg* pwdiGtkOffloadGetInfoReqMsg = NULL; + WDI_GtkOffloadGetInfoCb wdiGtkOffloadGetInfoCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalGtkOffloadGetInfoReqParams halGtkOffloadGetInfoReqParams; + wpt_uint8 ucCurrentSessionId = 0; + WDI_BSSSessionType* pBSSSes = NULL; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiGtkOffloadGetInfoReqMsg = (WDI_GtkOffloadGetInfoReqMsg*)pEventData->pEventData)) || + ( NULL == (wdiGtkOffloadGetInfoCb = (WDI_GtkOffloadGetInfoCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + goto failRequest; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_GTK_OFFLOAD_GETINFO_REQ, + sizeof(halGtkOffloadGetInfoReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < ( usDataOffset + sizeof(halGtkOffloadGetInfoReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in WDI_ProcessGTKOffloadGetInfoReq() %p %p %p", + pEventData, pwdiGtkOffloadGetInfoReqMsg, wdiGtkOffloadGetInfoCb); + WDI_ASSERT(0); + goto failRequest; + } + ucCurrentSessionId = WDI_FindAssocSession( pWDICtx, + pwdiGtkOffloadGetInfoReqMsg->WDI_GtkOffloadGetInfoReqParams.bssId, + &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s : Association for this BSSID does not exist",__func__); + goto fail; + } + halGtkOffloadGetInfoReqParams.bssIdx = pBSSSes->ucBSSIdx; + + // + // Don't need to fill send buffer other than header + // + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halGtkOffloadGetInfoReqParams, + sizeof(halGtkOffloadGetInfoReqParams)); + + pWDICtx->wdiReqStatusCB = pwdiGtkOffloadGetInfoReqMsg->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiGtkOffloadGetInfoReqMsg->pUserData; + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiGtkOffloadGetInfoCb, pEventData->pUserData, WDI_GTK_OFFLOAD_GETINFO_RESP); +fail: + // Release the message buffer so we don't leak + wpalMemoryFree(pSendBuffer); + +failRequest: + //WDA should have failure check to avoid the memory leak + return WDI_STATUS_E_FAILURE; +} + +/** + @brief Process host offload Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGtkOffloadRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_GtkOffloadCb wdiGtkOffloadCb = NULL; + tHalGtkOffloadRspParams halGtkOffloadRspParams; + WDI_GtkOffloadRspParams wdiGtkOffloadRsparams; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGtkOffloadCb = (WDI_GtkOffloadCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halGtkOffloadRspParams, + pEventData->pEventData, + sizeof(halGtkOffloadRspParams)); + + wdiGtkOffloadRsparams.ulStatus = + WDI_HAL_2_WDI_STATUS(halGtkOffloadRspParams.ulStatus); + wdiGtkOffloadRsparams.bssIdx = + halGtkOffloadRspParams.bssIdx; + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiGtkOffloadRsparams.ulStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + + /*Notify UMAC*/ + wdiGtkOffloadCb( &wdiGtkOffloadRsparams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process GTK Offload Get Information Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGTKOffloadGetInfoRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + eHalStatus halStatus; + WDI_GtkOffloadGetInfoCb wdiGtkOffloadGetInfoCb = NULL; + tHalGtkOffloadGetInfoRspParams halGtkOffloadGetInfoRspParams; + WDI_GtkOffloadGetInfoRspParams wdiGtkOffloadGetInfoRsparams; + WDI_BSSSessionType* pBSSSes = NULL; + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGtkOffloadGetInfoCb = (WDI_GtkOffloadGetInfoCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + if(WDI_getFwWlanFeatCaps(SLM_SESSIONIZATION)) + { + wpalMemoryCopy( &halGtkOffloadGetInfoRspParams, + pEventData->pEventData, + sizeof(halGtkOffloadGetInfoRspParams)); + + wdiGtkOffloadGetInfoRsparams.ulStatus = + WDI_HAL_2_WDI_STATUS(halGtkOffloadGetInfoRspParams.ulStatus); + wdiGtkOffloadGetInfoRsparams.ullKeyReplayCounter = + halGtkOffloadGetInfoRspParams.ullKeyReplayCounter; + wdiGtkOffloadGetInfoRsparams.ulTotalRekeyCount = + halGtkOffloadGetInfoRspParams.ulTotalRekeyCount; + wdiGtkOffloadGetInfoRsparams.ulGTKRekeyCount = + halGtkOffloadGetInfoRspParams.ulGTKRekeyCount; + wdiGtkOffloadGetInfoRsparams.ulIGTKRekeyCount = + halGtkOffloadGetInfoRspParams.ulIGTKRekeyCount; + + wpalMutexAcquire(&pWDICtx->wptMutex); + WDI_FindAssocSessionByBSSIdx(pWDICtx, halGtkOffloadGetInfoRspParams.bssIdx, + &pBSSSes); + + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Association sequence for this BSS does not exist or " + "association no longer in progress - mysterious HAL response"); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wpalMemoryCopy(wdiGtkOffloadGetInfoRsparams.bssId, pBSSSes->macBSSID, + sizeof (wpt_macAddr)); + wpalMutexRelease(&pWDICtx->wptMutex); + } + else + { + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiGtkOffloadGetInfoRsparams.ulStatus = WDI_HAL_2_WDI_STATUS(halStatus); + } + /*Notify UMAC*/ + //wdiUpdateScanParamsCb(wdiStatus, pWDICtx->pRspCBUserData); + //wdiReceiveFilterClearFilterCb(wdiStatus, pWDICtx->pRspCBUserData); + wdiGtkOffloadGetInfoCb(&wdiGtkOffloadGetInfoRsparams, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif // WLAN_FEATURE_GTK_OFFLOAD + +#ifdef WLAN_WAKEUP_EVENTS +WDI_Status +WDI_ProcessWakeReasonInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType *pWdiInd; + tpWakeReasonParams pWakeReasonParams; + wpt_uint32 allocSize = 0; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "+%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + pWakeReasonParams = (tpWakeReasonParams)(pEventData->pEventData); + + allocSize = sizeof(WDI_LowLevelIndType) + (pWakeReasonParams->ulStoredDataLen - 1); + + //Allocate memory for WDI_WakeReasonIndType structure + pWdiInd = wpalMemoryAllocate(allocSize) ; + + if(NULL == pWdiInd) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Failed to allocate memory for WDI_WakeReasonIndType: %p %p %p ", + __func__, pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(pWdiInd, allocSize); + + /* Fill in the indication parameters*/ + // Fill wdiInd.wdiIndicationData.wakeReasonInd structure from wakeReasonInd.wakeReasonParams + pWdiInd->wdiIndicationType = WDI_WAKE_REASON_IND; + pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulReason = pWakeReasonParams->ulReason; + pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulReasonArg = pWakeReasonParams->ulReasonArg; + pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulStoredDataLen = pWakeReasonParams->ulStoredDataLen; + pWdiInd->wdiIndicationData.wdiWakeReasonInd.ulActualDataLen = pWakeReasonParams->ulActualDataLen; + wpalMemoryCopy( (void *)&(pWdiInd->wdiIndicationData.wdiWakeReasonInd.aDataStart[0]), + &(pWakeReasonParams->aDataStart[0]), + pWakeReasonParams->ulStoredDataLen); + + + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( pWdiInd, pWDICtx->pIndUserData ); + } + + //Free memory allocated for WDI_WakeReasonIndType structure + wpalMemoryFree(pWdiInd); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "-%s", __func__); + + return WDI_STATUS_SUCCESS; +} +#endif // WLAN_WAKEUP_EVENTS + +void WDI_GetWcnssCompiledApiVersion +( + WDI_WlanVersionType *pWcnssApiVersion +) +{ + pWcnssApiVersion->major = WLAN_HAL_VER_MAJOR; + pWcnssApiVersion->minor = WLAN_HAL_VER_MINOR; + pWcnssApiVersion->version = WLAN_HAL_VER_VERSION; + pWcnssApiVersion->revision = WLAN_HAL_VER_REVISION; +} + +/** + @brief Process Set TM Level Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTmLevelRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_SetTmLevelCb wdiSetTmLevelCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetTmLevelCb = (WDI_SetPowerParamsCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiSetTmLevelCb(wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessSetTmLevelRsp*/ + +/** + @brief Process Set Thermal Mitigation level Changed request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetTmLevelReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetTmLevelReqType *pwdiSetTmLevelReq = NULL; + WDI_SetTmLevelCb wdiSetTmLevelCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSetThermalMitgationType halTmMsg; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiSetTmLevelReq = (WDI_SetTmLevelReqType*)pEventData->pEventData)) || + ( NULL == (wdiSetTmLevelCb = (WDI_SetTmLevelCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_SET_TM_LEVEL_REQ, + sizeof(halTmMsg), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halTmMsg) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in Set PNO req %p %p %p", + pEventData, pwdiSetTmLevelReq, wdiSetTmLevelCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halTmMsg.thermalMitMode = pwdiSetTmLevelReq->tmMode; + halTmMsg.thermalMitLevel = pwdiSetTmLevelReq->tmLevel; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halTmMsg, + sizeof(halTmMsg)); + + pWDICtx->pReqStatusUserData = pwdiSetTmLevelReq->pUserData; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiSetTmLevelCb, pEventData->pUserData, WDI_SET_TM_LEVEL_RESP); +} + +/* Fill the value from the global features enabled array to the global capabilities + * bitmap struct + */ +static void +FillAllFeatureCaps(tWlanFeatCaps *fCaps, placeHolderInCapBitmap *enabledFeat, wpt_int8 len) +{ + wpt_int8 i; + for (i=0; ifeatCaps[0], + gpHostWlanFeatCaps->featCaps[1], + gpHostWlanFeatCaps->featCaps[2], + gpHostWlanFeatCaps->featCaps[3] + ); + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "Host Capability"); + WDI_TraceHostFWCapabilities(gpHostWlanFeatCaps->featCaps); + wdiEventData.wdiRequest = WDI_FEATURE_CAPS_EXCHANGE_REQ; + wdiEventData.pEventData = gpHostWlanFeatCaps; + wdiEventData.uEventDataSize = fCapsStructSize; + wdiEventData.pCBfnc = wdiFeatureCapsExchangeCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Disable Active mode offload in Host + + @param void + @see + @return void +*/ +void +WDI_disableCapablityFeature(wpt_uint8 feature_index) +{ + supportEnabledFeatures[feature_index] = 0; + return; +} + +/** + @brief Process Host-FW Capability Exchange Request function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFeatureCapsExchangeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usLen = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + /* Call back function is NULL since not required for cap exchange req */ + if (( NULL == pEventData ) || + ( NULL == (tWlanFeatCaps *)pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + usLen = sizeof(tWlanFeatCaps); + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_FEATURE_CAPS_EXCHANGE_REQ, + usLen, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in feat caps exchange req %p %p", + pEventData, (tWlanFeatCaps *)pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Host Caps - %x %x %x %x", + ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[0], + ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[1], + ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[2], + ((tWlanFeatCaps *)pEventData->pEventData)->featCaps[3] + ); + + /* Copy host caps after the offset in the send buffer */ + wpalMemoryCopy( pSendBuffer+usDataOffset, + (tWlanFeatCaps *)pEventData->pEventData, + usLen); + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + (WDI_StartRspCb)pEventData->pCBfnc, + pEventData->pUserData, WDI_FEATURE_CAPS_EXCHANGE_RESP); + +}/*WDI_ProcessFeatureCapsExchangeReq*/ + +/** + @brief Process Host-FW Capability Exchange Response function + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFeatureCapsExchangeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_featureCapsExchangeCb wdiFeatureCapsExchangeCb; + wpt_int32 fCapsStructSize; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + /* It will go here when riva is old (doesn't understand this msg) and host is new */ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Allocate memory separately for global variable carrying FW caps */ + fCapsStructSize = sizeof(tWlanFeatCaps); + gpFwWlanFeatCaps = wpalMemoryAllocate(fCapsStructSize); + if ( NULL == gpFwWlanFeatCaps ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Cannot allocate memory for host capability info"); + WDI_ASSERT(0); + return WDI_STATUS_MEM_FAILURE; + } + + /*------------------------------------------------------------------------- + Unpack HAL Response Message - the header was already extracted by the + main Response Handling procedure + -------------------------------------------------------------------------*/ + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + + wpalMemoryCopy(gpFwWlanFeatCaps,(tWlanFeatCaps *) pEventData -> pEventData, + fCapsStructSize); + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "FW caps %x %x %x %x", + gpFwWlanFeatCaps->featCaps[0], + gpFwWlanFeatCaps->featCaps[1], + gpFwWlanFeatCaps->featCaps[2], + gpFwWlanFeatCaps->featCaps[3] + ); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, "Firmware Capability"); + WDI_TraceHostFWCapabilities(gpFwWlanFeatCaps->featCaps); + wdiFeatureCapsExchangeCb = (WDI_featureCapsExchangeCb) pWDICtx -> pfncRspCB; + + /*Notify UMAC - there is no callback right now but can be used in future if reqd */ + if (wdiFeatureCapsExchangeCb != NULL) + wdiFeatureCapsExchangeCb(NULL, NULL); + + return WDI_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_11AC +WDI_Status +WDI_ProcessUpdateVHTOpModeRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateVHTOpModeCb wdiVHTOpModeCb = NULL; + WDI_Status wdiStatus; + eHalStatus halStatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiVHTOpModeCb = (WDI_UpdateVHTOpModeCb)pEventData->pCBfnc; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + /*Notify UMAC*/ + wdiVHTOpModeCb( wdiStatus, pEventData->pUserData); + + return WDI_STATUS_SUCCESS; +} +#endif +/** + @brief WDI_getHostWlanFeatCaps + WDI API that returns whether the feature passed to it as enum value in + "placeHolderInCapBitmap" is supported by Host or not. It uses WDI global + variable storing host capability bitmap to find this. This can be used by + other moduels to decide certain things like call different APIs based on + whether a particular feature is supported. + + @param + + feat_enum_value: enum value for the feature as in placeHolderInCapBitmap in wlan_hal_msg.h. + + @see + @return + 0 - if the feature is NOT supported in host + any non-zero value - if the feature is SUPPORTED in host. +*/ +wpt_uint8 WDI_getHostWlanFeatCaps(wpt_uint8 feat_enum_value) +{ + wpt_uint8 featSupported = 0; + if (gpHostWlanFeatCaps != NULL) + { + getFeatCaps(gpHostWlanFeatCaps, feat_enum_value, featSupported); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Caps exchange feature NOT supported. Return NOT SUPPORTED for %u feature", feat_enum_value); + } + return featSupported; +} + +/** + @brief WDI_getFwWlanFeatCaps + WDI API that returns whether the feature passed to it as enum value in + "placeHolderInCapBitmap" is supported by FW or not. It uses WDI global + variable storing host capability bitmap to find this. This can be used by + other moduels to decide certain things like call different APIs based on + whether a particular feature is supported. + + @param + + feat_enum_value: enum value for the feature as in placeHolderInCapBitmap + in wlan_hal_msg.h. + + @see + @return + 0 - if the feature is NOT supported in FW + any non-zero value - if the feature is SUPPORTED in FW. +*/ +wpt_uint8 WDI_getFwWlanFeatCaps(wpt_uint8 feat_enum_value) +{ + wpt_uint8 featSupported = 0; + if (gpFwWlanFeatCaps != NULL) + { + getFeatCaps(gpFwWlanFeatCaps, feat_enum_value, featSupported); + } + else + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Caps exchange feature NOT supported. Return NOT SUPPORTED for %u feature", feat_enum_value); + } + return featSupported; +} + +wpt_uint8 WDI_selectCbMode( wpt_uint8 channel, wpt_uint8 ChannelBW ) +{ + /* 5gHz Channel */ + if( channel >= 34 && channel <= 165 ) + { + if( ChannelBW == 80 && WDI_getFwWlanFeatCaps(DOT11AC) ) + { + if ( channel== 36 || channel == 52 || channel == 100 || + channel == 116 || channel == 149 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW; + } + else if ( channel == 40 || channel == 56 || channel == 104 || + channel == 120 || channel == 153 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW; + } + else if ( channel == 44 || channel == 60 || channel == 108 || + channel == 124 || channel == 157 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH; + } + else if ( channel == 48 || channel == 64 || channel == 112 || + channel == 128 || channel == 144 || channel == 161 ) + { + return PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH; + } + else if ( channel == 165 ) + { + return PHY_SINGLE_CHANNEL_CENTERED; + } + } + + else + { + if ( channel== 40 || channel == 48 || channel == 56 || + channel == 64 || channel == 104 || channel == 112 || + channel == 120 || channel == 128 || channel == 136 || + channel == 144 || channel == 153 || channel == 161 ) + { + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + } + else if ( channel== 36 || channel == 44 || channel == 52 || + channel == 60 || channel == 100 || channel == 108 || + channel == 116 || channel == 124 || channel == 132 || + channel == 140 || channel == 149 || channel == 157 ) + { + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + } + else if ( channel == 165 ) + { + return PHY_SINGLE_CHANNEL_CENTERED; + } + } + } + + /* 2.4Ghz Channel */ + if( ChannelBW == 40 && WDI_getFwWlanFeatCaps(HT40_OBSS_SCAN) ) + { + if (channel >= 1 && channel <= 7) + return PHY_DOUBLE_CHANNEL_LOW_PRIMARY; + else if (channel >= 8 && channel <= 13) + return PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; + else if (channel ==14) + return PHY_SINGLE_CHANNEL_CENTERED; + } + return PHY_SINGLE_CHANNEL_CENTERED; +} + +#ifdef WLAN_FEATURE_11AC +WDI_Status +WDI_ProcessUpdateVHTOpModeReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_UpdateVHTOpMode* pwdiVHTOpModeParams = NULL; + WDI_UpdateVHTOpModeCb wdiVHTOpModeCb = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiVHTOpModeParams = (WDI_UpdateVHTOpMode*)pEventData->pEventData)) || + ( NULL == (wdiVHTOpModeCb = (WDI_UpdateVHTOpModeCb)pEventData->pCBfnc))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, WDI_UPDATE_VHT_OP_MODE_REQ, + sizeof(WDI_UpdateVHTOpMode), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(WDI_UpdateVHTOpMode) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in update vht opMode req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "pwdiVHTOpModeParams->opMode=%d, pwdiVHTOpModeParams->staId=%d", pwdiVHTOpModeParams->opMode, pwdiVHTOpModeParams->staId); + + wpalMemoryCopy( pSendBuffer+usDataOffset, pwdiVHTOpModeParams, + sizeof(WDI_UpdateVHTOpMode)); + + /*------------------------------------------------------------------------- + Send Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiVHTOpModeCb, + pEventData->pUserData, WDI_UPDATE_VHT_OP_MODE_RESP); + +} + +WDI_Status +WDI_UpdateVHTOpModeReq +( + WDI_UpdateVHTOpMode *pData, + WDI_UpdateVHTOpModeCb wdiUpdateVHTOpModeCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_UPDATE_VHT_OP_MODE_REQ; + wdiEventData.pEventData = pData; + wdiEventData.uEventDataSize = sizeof(WDI_UpdateVHTOpMode); + wdiEventData.pCBfnc = wdiUpdateVHTOpModeCb; + wdiEventData.pUserData = pUserData; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "pData->opMode=%d, pData->staId=%d", pData->opMode, pData->staId); + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} +#endif + +/** + @brief WDI_TransportChannelDebug - + Display DXE Channel debugging information + User may request to display DXE channel snapshot + Or if host driver detects any abnormal stcuk may display + + @param displaySnapshot : Display DXE snapshot option + @param debugFlags : Enable stall detect features + defined by WPAL_DeviceDebugFlags + These features may effect + data performance. + @see + @return none +*/ +void WDI_TransportChannelDebug +( + wpt_boolean displaySnapshot, + wpt_uint8 debugFlags +) +{ + WDTS_ChannelDebug(displaySnapshot, debugFlags); + return; +} + +/** + @brief WDI_TransportKickDxe - + Request Kick DXE when HDD TX time out happen + + @param none + @see + @return none +*/ +void WDI_TransportKickDxe() +{ + WDTS_ChannelKickDxe(); + return; +} + +/** + @brief WDI_SsrTimerCB + Callback function for SSR timer, if this is called then the graceful + shutdown for Riva did not happen. + + @param pUserData : user data to timer + + @see + @return none +*/ +void +WDI_SsrTimerCB +( + void *pUserData +) +{ + WDI_ControlBlockType* pWDICtx = (WDI_ControlBlockType*)pUserData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if (NULL == pWDICtx ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return; + } + wpalRivaSubystemRestart(); + + return; + +}/*WDI_SsrTimerCB*/ + +/** + @brief WDI_SetEnableSSR - + This API is called to enable/disable SSR on WDI timeout. + + @param enableSSR : enable/disable SSR + + @see + @return none +*/ +void WDI_SetEnableSSR(wpt_boolean enableSSR) +{ + gWDICb.bEnableSSR = enableSSR; +} + +/** + * WDI_SetMgmtPktViaWQ5() - Set INI params sendMgmtPktViaWQ5 to Control + * Block Type. + * @sendMgmtPktViaWQ5: INI params to enable/disable sending mgmt pkt via WQ5. + * + * Return: void + */ +void WDI_SetMgmtPktViaWQ5(wpt_boolean sendMgmtPktViaWQ5) +{ + gWDICb.sendMgmtPktViaWQ5 = sendMgmtPktViaWQ5; +} + + +#ifdef FEATURE_WLAN_LPHB +/** + @brief WDI_ProcessLphbInd - + This function will be invoked when FW detects low power + heart beat failure + + @param pWDICtx : wdi context + pEventData : indication data + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLphbInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalLowPowerHeartBeatIndParam lphbIndicationParam; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pWDICtx) || (NULL == pEventData) || + (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy(&lphbIndicationParam, + pEventData->pEventData, + sizeof(tHalLowPowerHeartBeatIndParam)); + + wdiInd.wdiIndicationType = WDI_LPHB_IND; + wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.bssIdx = + lphbIndicationParam.bssIdx; + wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.sessionIdx = + lphbIndicationParam.sessionIdx; + wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.protocolType = + lphbIndicationParam.protocolType; + wdiInd.wdiIndicationData.wdiLPHBTimeoutInd.eventReason = + lphbIndicationParam.eventReason; + /*Notify UMAC*/ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData); + } + + return WDI_STATUS_SUCCESS; +} + +/** + @brief WDI_ProcessLphbCfgRsp - + LPHB configuration response from FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return Result of the function call +*/ +WDI_Status WDI_ProcessLphbCfgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_LphbCfgCb wdiLphbCfgCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pWDICtx) || (NULL == pEventData) || + (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiLphbCfgCb = (WDI_LphbCfgCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "LPHB Cfg Rsp Return status %d", wdiStatus); + /*Notify UMAC*/ + if (NULL != wdiLphbCfgCb) + { + wdiLphbCfgCb(wdiStatus, pWDICtx->pRspCBUserData); + } + + return WDI_STATUS_SUCCESS; +} + +/** + @brief WDI_ProcessLPHBConfReq - + LPHB configuration request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status WDI_ProcessLPHBConfReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LPHBReq *pLphbReqParams; + WDI_Status wdiStatus; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalLowPowerHeartBeatReq *halLphbReqRarams; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pEventData) || (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in Suspend ind",__func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pLphbReqParams = (WDI_LPHBReq *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_LPHB_CFG_REQ, + sizeof(tHalLowPowerHeartBeatReqMsg), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(tHalLowPowerHeartBeatReqMsg)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in LPHB Ind "); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halLphbReqRarams = (tHalLowPowerHeartBeatReq *)(pSendBuffer + usDataOffset); + wpalMemoryZero(halLphbReqRarams, sizeof(tHalLowPowerHeartBeatReq)); + + halLphbReqRarams->lowPowerHeartBeatCmdType = + (tANI_U16)(++pLphbReqParams->cmd); + switch ((tANI_U16)pLphbReqParams->cmd) + { + case WDI_LPHB_SET_EN_PARAMS_INDID: + halLphbReqRarams->sessionIdx = + pLphbReqParams->params.lphbEnableReq.session; + halLphbReqRarams->options.control.heartBeatEnable = + pLphbReqParams->params.lphbEnableReq.enable; + halLphbReqRarams->options.control.heartBeatType = + pLphbReqParams->params.lphbEnableReq.item; + break; + + case WDI_LPHB_SET_TCP_PARAMS_INDID: + halLphbReqRarams->sessionIdx = + pLphbReqParams->params.lphbTcpParamReq.session; + halLphbReqRarams->options.tcpParams.timeOutSec = + pLphbReqParams->params.lphbTcpParamReq.timeout; + wpalMemoryCopy(&halLphbReqRarams->options.tcpParams.hostIpv4Addr, + &pLphbReqParams->params.lphbTcpParamReq.dev_ip, + sizeof(v_U32_t)); + wpalMemoryCopy(&halLphbReqRarams->options.tcpParams.destIpv4Addr, + &pLphbReqParams->params.lphbTcpParamReq.srv_ip, + sizeof(v_U32_t)); + + wpalMemoryCopy(halLphbReqRarams->options.tcpParams.gatewayMacAddr, + pLphbReqParams->params.lphbTcpParamReq.gateway_mac, + WDI_MAC_ADDR_LEN); + + halLphbReqRarams->options.tcpParams.hostPort = + pLphbReqParams->params.lphbTcpParamReq.src_port; + halLphbReqRarams->options.tcpParams.destPort = + pLphbReqParams->params.lphbTcpParamReq.dst_port; + halLphbReqRarams->options.tcpParams.timePeriodSec = + pLphbReqParams->params.lphbTcpParamReq.timePeriodSec; + halLphbReqRarams->options.tcpParams.tcpSn = + pLphbReqParams->params.lphbTcpParamReq.tcpSn; + break; + + case WDI_LPHB_SET_TCP_PKT_FILTER_INDID: + halLphbReqRarams->sessionIdx = + pLphbReqParams->params.lphbTcpFilterReq.session; + halLphbReqRarams->options.tcpUdpFilter.offset = + pLphbReqParams->params.lphbTcpFilterReq.offset; + halLphbReqRarams->options.tcpUdpFilter.filterLength = + pLphbReqParams->params.lphbTcpFilterReq.length; + wpalMemoryCopy(halLphbReqRarams->options.tcpUdpFilter.filter, + pLphbReqParams->params.lphbTcpFilterReq.filter, + WDI_LPHB_FILTER_LEN); + break; + + case WDI_LPHB_SET_UDP_PARAMS_INDID: + halLphbReqRarams->sessionIdx = + pLphbReqParams->params.lphbUdpParamReq.session; + halLphbReqRarams->options.udpParams.timeOutSec = + pLphbReqParams->params.lphbUdpParamReq.timeout; + halLphbReqRarams->options.udpParams.timePeriodSec = + pLphbReqParams->params.lphbUdpParamReq.interval; + wpalMemoryCopy(&halLphbReqRarams->options.udpParams.hostIpv4Addr, + &pLphbReqParams->params.lphbUdpParamReq.dev_ip, + sizeof(v_U32_t)); + wpalMemoryCopy(&halLphbReqRarams->options.udpParams.destIpv4Addr, + &pLphbReqParams->params.lphbUdpParamReq.srv_ip, + sizeof(v_U32_t)); + + wpalMemoryCopy(halLphbReqRarams->options.udpParams.gatewayMacAddr, + pLphbReqParams->params.lphbUdpParamReq.gateway_mac, + WDI_MAC_ADDR_LEN); + + halLphbReqRarams->options.udpParams.hostPort = + pLphbReqParams->params.lphbUdpParamReq.src_port; + halLphbReqRarams->options.udpParams.destPort = + pLphbReqParams->params.lphbUdpParamReq.dst_port; + break; + + case WDI_LPHB_SET_UDP_PKT_FILTER_INDID: + halLphbReqRarams->sessionIdx = + pLphbReqParams->params.lphbUdpFilterReq.session; + halLphbReqRarams->options.tcpUdpFilter.offset = + pLphbReqParams->params.lphbUdpFilterReq.offset; + halLphbReqRarams->options.tcpUdpFilter.filterLength = + pLphbReqParams->params.lphbUdpFilterReq.length; + wpalMemoryCopy(halLphbReqRarams->options.tcpUdpFilter.filter, + pLphbReqParams->params.lphbUdpFilterReq.filter, + WDI_LPHB_FILTER_LEN); + break; + + case WDI_LPHB_SET_NETWORK_INFO_INDID: + /* NA */ + break; + + default: + break; + } + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + -------------------------------------------------------------------------*/ + pWDICtx->pfncRspCB = pEventData->pCBfnc; + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer, + usSendSize, pWDICtx->pfncRspCB, + pWDICtx->pReqStatusUserData, + WDI_LPHB_CFG_RESP); + + return wdiStatus; +} + +/** + @brief WDI_LPHBConfReq - + LPHB configuration request API + + @param lphbconfParam : configuration parameter + usrData : client context + lphbCfgCb : callback function pointer + + @see + @return Success or fail status code +*/ +WDI_Status WDI_LPHBConfReq(void *lphbconfParam, + void *usrData, WDI_LphbCfgCb lphbCfgCb) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_LPHB_CFG_REQ; + wdiEventData.pEventData = lphbconfParam; + wdiEventData.uEventDataSize = sizeof(WDI_LPHBReq); + wdiEventData.pCBfnc = lphbCfgCb; + wdiEventData.pUserData = usrData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} +#endif /* FEATURE_WLAN_LPHB */ + +/** + @brief WDI_ProcessIbssPeerInactivityInd + Process peer inactivity indication coming from HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInactivityInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tIbssPeerInactivityIndMsg halIbssIndMsg; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halIbssIndMsg.ibssPeerInactivityIndParams, + pEventData->pEventData, + sizeof(halIbssIndMsg.ibssPeerInactivityIndParams) ); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_IBSS_PEER_INACTIVITY_IND; + + wdiInd.wdiIndicationData.wdiIbssPeerInactivityInd.bssIdx + = halIbssIndMsg.ibssPeerInactivityIndParams.bssIdx; + + wdiInd.wdiIndicationData.wdiIbssPeerInactivityInd.staIdx + = halIbssIndMsg.ibssPeerInactivityIndParams.staIdx; + + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiIbssPeerInactivityInd.staMacAddr, + halIbssIndMsg.ibssPeerInactivityIndParams.staAddr, + sizeof(tSirMacAddr)); + + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + + return WDI_STATUS_SUCCESS; + +} /*WDI_ProcessIbssPeerInactivityInd*/ + + +/** +*@brief WDI_RateUpdateInd will be called when the upper MAC + requests the device to set rates. + + + @param wdiRateUpdateIndParams: + + + @see + @return Result of the function call +*/ +WDI_Status +WDI_RateUpdateInd +( + WDI_RateUpdateIndParams *wdiRateUpdateIndParams +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RATE_UPDATE_IND; + wdiEventData.pEventData = wdiRateUpdateIndParams; + wdiEventData.uEventDataSize = sizeof(WDI_RateUpdateIndParams); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/* WDI_RateUpdateInd */ + +/** + @brief Process Rate Update Indication and post it to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRateUpdateInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_RateUpdateIndParams *pwdiRateUpdateInd = NULL; + tHalRateUpdateInd *pRateUpdateInd; + WDI_Status wdiStatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiRateUpdateInd = (WDI_RateUpdateIndParams *)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_RATE_UPDATE_IND, + sizeof(tHalRateUpdateParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(tHalRateUpdateParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Rate Update Indication %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pRateUpdateInd = (tHalRateUpdateInd *)pSendBuffer; + + /* Copy the bssid */ + wpalMemoryCopy(pRateUpdateInd->halRateUpdateParams.bssid, + pwdiRateUpdateInd->bssid, WDI_MAC_ADDR_LEN); + + /* Copy the tx flags */ + pRateUpdateInd->halRateUpdateParams.ucastDataRateTxFlag = + pwdiRateUpdateInd->ucastDataRateTxFlag; + pRateUpdateInd->halRateUpdateParams.rmcDataRateTxFlag = + pwdiRateUpdateInd->rmcDataRateTxFlag; + pRateUpdateInd->halRateUpdateParams.mcastDataRate24GHzTxFlag = + pwdiRateUpdateInd->mcastDataRate24GHzTxFlag; + pRateUpdateInd->halRateUpdateParams.mcastDataRate5GHzTxFlag = + pwdiRateUpdateInd->mcastDataRate5GHzTxFlag; + + /* Copy the tx rates */ + pRateUpdateInd->halRateUpdateParams.ucastDataRate = + pwdiRateUpdateInd->ucastDataRate; + pRateUpdateInd->halRateUpdateParams.rmcDataRate = + pwdiRateUpdateInd->rmcDataRate; + pRateUpdateInd->halRateUpdateParams.mcastDataRate24GHz = + pwdiRateUpdateInd->mcastDataRate24GHz; + pRateUpdateInd->halRateUpdateParams.mcastDataRate5GHz = + pwdiRateUpdateInd->mcastDataRate5GHz; + + /*------------------------------------------------------------------------- + Send Rate Update Indication to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pwdiRateUpdateInd->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiRateUpdateInd->pUserData; + + wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize); + + return (wdiStatus != WDI_STATUS_SUCCESS) ? + wdiStatus : WDI_STATUS_SUCCESS_SYNC; + +} /* WDI_ProcessRateUpdateInd */ + +#ifdef WLAN_FEATURE_RMC +WDI_Status +WDI_ProcessRMCRulerResp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tHalRmcRulerRspMsg halRmcRulerRspMsg; + WDI_RmcRulerRspCb wdiRmcRulerRspCb; + WDI_RmcRspParamsType wdiRmcRsp; + + /* Sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + wdiRmcRulerRspCb = (WDI_RmcRulerRspCb)pWDICtx->pfncRspCB; + + /* Extract indication and send it to UMAC */ + wpalMemoryCopy( &halRmcRulerRspMsg.rulerRspParams, + pEventData->pEventData, + sizeof(halRmcRulerRspMsg.rulerRspParams) ); + + wdiRmcRsp.status = halRmcRulerRspMsg.rulerRspParams.status; + wpalMemoryCopy(wdiRmcRsp.mcastTransmitter, + &halRmcRulerRspMsg.rulerRspParams.mcastTransmitter, + sizeof(wdiRmcRsp.mcastTransmitter)); + wpalMemoryCopy(wdiRmcRsp.mcastGroup, + &halRmcRulerRspMsg.rulerRspParams.mcastGroup, + sizeof(wdiRmcRsp.mcastGroup)); + + switch (halRmcRulerRspMsg.rulerRspParams.cmd) + { + default: + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid command %d", __func__, + halRmcRulerRspMsg.rulerRspParams.cmd); + return WDI_STATUS_E_FAILURE; + + case WLAN_HAL_SUGGEST_RULER: + { + /* Fill in the indication parameters */ + wdiRmcRsp.cmd = eWDI_SUGGEST_RULER_CMD; + wpalMemoryCopy(wdiRmcRsp.ruler, + &halRmcRulerRspMsg.rulerRspParams.ruler, + sizeof(halRmcRulerRspMsg.rulerRspParams.ruler)); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s Suggest_Ruler", __func__); + break; + } + + case WLAN_HAL_BECOME_RULER: + { + /* Fill in the indication parameters */ + wdiRmcRsp.cmd = eWDI_BECOME_RULER_CMD; + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s Become_Ruler", __func__); + break; + } + } + + /* Notify UMAC */ + wdiRmcRulerRspCb(&wdiRmcRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_ProcessRMCUpdateIndToHost +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalRmcUpdateInd halRmcUpdateInd; + + /* Sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + /* Extract indication and send it to UMAC */ + wpalMemoryCopy( &halRmcUpdateInd.rulerIndParams, + pEventData->pEventData, + sizeof(halRmcUpdateInd.rulerIndParams) ); + + switch (halRmcUpdateInd.rulerIndParams.indication) + { + default: + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid command %d", __func__, + halRmcUpdateInd.rulerIndParams.indication); + return WDI_STATUS_E_FAILURE; + + case WLAN_HAL_RULER_PICK_NEW: + { + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_RMC_RULER_PICK_NEW; + wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.indication + = halRmcUpdateInd.rulerIndParams.indication; + wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.role + = halRmcUpdateInd.rulerIndParams.role; + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd. \ + mcastTransmitter, + &halRmcUpdateInd.rulerIndParams.mcastTransmitter, + sizeof(tSirMacAddr) ); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.mcastGroup, + &halRmcUpdateInd.rulerIndParams.mcastGroup, + sizeof(tSirMacAddr) ); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.mcastRuler, + &halRmcUpdateInd.rulerIndParams.mcastRuler, + sizeof(tSirMacAddr) ); + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRmcPickNewRulerInd.ruler, + &halRmcUpdateInd.rulerIndParams.ruler, + sizeof(tSirMacAddr) * HAL_NUM_MAX_RULERS ); + break; + } + } + + + /* Notify UMAC */ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_RmcRulerReq +( + WDI_RmcRulerReqParams *wdiRmcRulerReqParams, + WDI_RmcRulerRspCb wdiRmcRulerRspCb, + void *usrData +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RMC_RULER_REQ; + wdiEventData.pEventData = wdiRmcRulerReqParams; + wdiEventData.uEventDataSize = sizeof(WDI_RmcRulerReqParams); + wdiEventData.pCBfnc = wdiRmcRulerRspCb; + wdiEventData.pUserData = usrData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} /* WDI_RmcRulerReq */ + +WDI_Status +WDI_RmcUpdateInd +( + WDI_RmcUpdateIndParams *wdiRmcUpdateIndParams +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_RMC_UPDATE_IND; + wdiEventData.pEventData = wdiRmcUpdateIndParams; + wdiEventData.uEventDataSize = sizeof(WDI_RmcUpdateIndParams); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/* WDI_RmcUpdateInd */ + +WDI_Status +WDI_ProcessRMCRulerReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_RmcRulerReqParams *pwdiRulerReq = NULL; + tHalRmcRulerReqMsg *pRulerReq; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiRulerReq = (WDI_RmcRulerReqParams *)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_RMC_RULER_REQ, + sizeof(tHalRmcRulerReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(tHalRmcRulerReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Ruler Req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pRulerReq = (tHalRmcRulerReqMsg *)pSendBuffer; + pRulerReq->rulerReqParams.cmd = pwdiRulerReq->cmd; + wpalMemoryCopy(pRulerReq->rulerReqParams.mcastTransmitter, + pwdiRulerReq->mcastTransmitter, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(pRulerReq->rulerReqParams.mcastGroup, + pwdiRulerReq->mcastGroup, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(pRulerReq->rulerReqParams.blacklist, + pwdiRulerReq->blacklist, + WDI_MAC_ADDR_LEN * HAL_NUM_MAX_RULERS); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + pWDICtx->pfncRspCB = pEventData->pCBfnc; + + wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer, + usSendSize, pWDICtx->pfncRspCB, + pWDICtx->pReqStatusUserData, + WDI_RMC_RULER_RESP); + return wdiStatus; + +} /* WDI_ProcessRMCRulerReq */ + +/** + @brief Process Update Indication and post it to HAL + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRMCUpdateInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_RmcUpdateIndParams *pwdiUpdateInd = NULL; + tHalRmcUpdateInd *pUpdateInd; + WDI_Status wdiStatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiUpdateInd = (WDI_RmcUpdateIndParams *)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_RMC_UPDATE_IND, + sizeof(tHalRmcUpdateIndParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(tHalRmcUpdateIndParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in RMC Update Indication %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pUpdateInd = (tHalRmcUpdateInd *)pSendBuffer; + + pUpdateInd->rulerIndParams.indication = pwdiUpdateInd->indication; + pUpdateInd->rulerIndParams.role = pwdiUpdateInd->role; + + wpalMemoryCopy(pUpdateInd->rulerIndParams.mcastTransmitter, + pwdiUpdateInd->mcastTransmitter, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(pUpdateInd->rulerIndParams.mcastGroup, + pwdiUpdateInd->mcastGroup, WDI_MAC_ADDR_LEN); + wpalMemoryCopy(pUpdateInd->rulerIndParams.mcastRuler, + pwdiUpdateInd->mcastRuler, WDI_MAC_ADDR_LEN); + /* Zero out parameters not needed for this command */ + wpalMemoryZero(pUpdateInd->rulerIndParams.ruler, + WDI_MAC_ADDR_LEN * HAL_NUM_MAX_RULERS); + + + /*------------------------------------------------------------------------- + Send Update Indication to HAL + -------------------------------------------------------------------------*/ + pWDICtx->wdiReqStatusCB = pwdiUpdateInd->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiUpdateInd->pUserData; + + wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize); + + return (wdiStatus != WDI_STATUS_SUCCESS) ? + wdiStatus : WDI_STATUS_SUCCESS_SYNC; + +} /* WDI_ProcessRMCUpdateInd */ + +/** + @brief Process peer info req + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_IbssPeerInfoReq +( + WDI_IbssPeerInfoReqType* wdiPeerInfoReqParams, + WDI_IbssPeerInfoReqCb wdiIbssPeerInfoReqCb, + void* pUserData +) +{ + + WDI_EventInfoType wdiEventData; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_HAL_IBSS_PEER_INFO_REQ; + wdiEventData.pEventData = wdiPeerInfoReqParams; + wdiEventData.uEventDataSize = sizeof(WDI_IbssPeerInfoReqType); + wdiEventData.pCBfnc = wdiIbssPeerInfoReqCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Process peer info req + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInfoReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_IbssPeerInfoReqType *pwdiInfoReq = NULL; + tHalIbssPeerInfoReq *pPeerInfoReq; + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiInfoReq = (WDI_IbssPeerInfoReqType *)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_HAL_IBSS_PEER_INFO_REQ, + sizeof(tHalIbssPeerInfoReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(tHalIbssPeerInfoReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in IBSS Peer Info Req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pPeerInfoReq = (tHalIbssPeerInfoReq *)pSendBuffer; + if (VOS_FALSE == pwdiInfoReq->wdiAllPeerInfoReqd) + { + if (pSTATable[pwdiInfoReq->wdiStaIdx].valid) + { + pPeerInfoReq->ibssPeerInfoReqParams.bssIdx = + pSTATable[pwdiInfoReq->wdiStaIdx].bssIdx; + } + else + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to find BSSIDX for STAIDX %d ", + pwdiInfoReq->wdiStaIdx); + return WDI_STATUS_E_FAILURE; + } + } + else + pPeerInfoReq->ibssPeerInfoReqParams.bssIdx = 0; + + pPeerInfoReq->ibssPeerInfoReqParams.staIdx = pwdiInfoReq->wdiStaIdx; + pPeerInfoReq->ibssPeerInfoReqParams.allPeerInfoReqd = pwdiInfoReq->wdiAllPeerInfoReqd; + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + pWDICtx->pfncRspCB = pEventData->pCBfnc; + + /*------------------------------------------------------------------------- + Send IBSS Peer Info request to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer, + usSendSize, pWDICtx->pfncRspCB, + pWDICtx->pReqStatusUserData, + WDI_HAL_IBSS_PEER_INFO_RSP); + return wdiStatus; +} + +/** + @brief Process peer info resp + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessIbssPeerInfoRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_IbssPeerInfoReqCb wdiPeerInfoCb = NULL; + tHalIbssPeerParams *pHalPeerInfoParams; + WDI_IbssPeerInfoRspParams wdiPeerInfoRspParams; + wpt_uint32 allocSize=0; + WDI_IbssPeerInfoParams *pPeerInfoParams = NULL; + wpt_uint8 wdiCount=0; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + wdiPeerInfoCb = (WDI_IbssPeerInfoReqCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + pHalPeerInfoParams = + ((tHalIbssPeerInfoRspParams *)pEventData->pEventData)->ibssPeerParams; + wdiPeerInfoRspParams.wdiStatus = + WDI_HAL_2_WDI_STATUS(((tHalIbssPeerInfoRspParams *)pEventData->pEventData)->status); + wdiPeerInfoRspParams.wdiNumPeers = + ((tHalIbssPeerInfoRspParams *)pEventData->pEventData)->numOfPeers; + + if (!wdiPeerInfoRspParams.wdiNumPeers) { + wdiPeerInfoRspParams.wdiPeerInfoParams = NULL; + goto error; + } + if (wdiPeerInfoRspParams.wdiNumPeers >= + WDI_MAX_IBSS_PEER_SUPPORED_STAS) { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Number of stations %d exceed max supported stations %d set max", + wdiPeerInfoRspParams.wdiNumPeers, + WDI_MAX_IBSS_PEER_SUPPORED_STAS); + wdiPeerInfoRspParams.wdiNumPeers = + WDI_MAX_IBSS_PEER_SUPPORED_STAS - 1; + } + /* Size of peer info data received from DAL */ + allocSize = (sizeof(WDI_IbssPeerInfoParams) * (wdiPeerInfoRspParams.wdiNumPeers)); + + pPeerInfoParams = (WDI_IbssPeerInfoParams*)wpalMemoryAllocate(allocSize); + + if (NULL == pPeerInfoParams) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to allocate memory in ibss peer info response %p %p %p ", + pWDICtx, pEventData, pEventData->pEventData); + wdiPeerInfoRspParams.wdiPeerInfoParams = NULL; + goto error; + } + + for (wdiCount = 0; wdiCount < wdiPeerInfoRspParams.wdiNumPeers; wdiCount++) + { + tHalIbssPeerParams *pHalTemp = &pHalPeerInfoParams[wdiCount]; + WDI_IbssPeerInfoParams *pWdiTemp = &pPeerInfoParams[wdiCount]; + pWdiTemp->wdiStaIdx = pHalTemp->staIdx; + pWdiTemp->wdiRssi = pHalTemp->rssi; + pWdiTemp->wdiMcsIndex = pHalTemp->mcsIndex; + pWdiTemp->wdiTxRate = pHalTemp->txRate; + pWdiTemp->wdiTxRateFlags = pHalTemp->txRateFlags; + } + + wdiPeerInfoRspParams.wdiPeerInfoParams = pPeerInfoParams; +error: + /*Notify UMAC*/ + if (wdiPeerInfoCb) + { + wdiPeerInfoCb(&wdiPeerInfoRspParams, pWDICtx->pRspCBUserData); + } + + /* Free the allocation */ + if(pPeerInfoParams) + vos_mem_free (pPeerInfoParams); + + return WDI_STATUS_SUCCESS; +} +#endif +#ifdef FEATURE_WLAN_BATCH_SCAN + +/** + @brief Process stop batch indication from WDA + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStopBatchScanInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalBatchScanStopIndParam *pHalInd = NULL; + WDI_StopBatchScanIndType *pWdiInd = NULL; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pWdiInd = (WDI_StopBatchScanIndType *)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_STOP_BATCH_SCAN_IND, + sizeof(tHalBatchScanStopIndParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalBatchScanStopIndParam)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in stop batch scan ind %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalInd = (tHalBatchScanStopIndParam *)(pSendBuffer + usDataOffset); + pHalInd->param = pWdiInd->param; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send Stop batch scan indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + +/** + @brief This API is called to trigger batch scan results from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessTriggerBatchScanResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalBatchScanTriggerResultParam *pHalInd = NULL; + WDI_TriggerBatchScanResultIndType *pWdiInd = NULL; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pWdiInd = (WDI_TriggerBatchScanResultIndType *)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_TRIGGER_BATCH_SCAN_RESULT_IND, + sizeof(tHalBatchScanTriggerResultParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalBatchScanTriggerResultParam)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in stop batch scan ind %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalInd = (tHalBatchScanTriggerResultParam *)(pSendBuffer + usDataOffset); + pHalInd->param = pWdiInd->param; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send trigger batch scan result indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + + +/** + @brief Process set batch scan response from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSetBatchScanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetBatchScanCb wdiSetBatchScanCb; + WDI_SetBatchScanRspType *pSetBatchScanRsp; + + tHalBatchScanSetRspParam *pHalSetBatchScanRsp; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*sanity check*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiSetBatchScanCb = (WDI_SetBatchScanCb)pWDICtx->pfncRspCB; + if ( NULL == wdiSetBatchScanCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: call back function is NULL", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pSetBatchScanRsp = wpalMemoryAllocate(sizeof(WDI_SetBatchScanRspType)); + + if (NULL == pSetBatchScanRsp) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Failed to allocate memory in set batch scan response %p %p %p ", + pWDICtx, pEventData, pEventData->pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* extract response and send it to UMAC */ + pHalSetBatchScanRsp = (tHalBatchScanSetRspParam *)pEventData->pEventData; + + pSetBatchScanRsp->nScansToBatch = pHalSetBatchScanRsp->supportedMscan; + + /* Notify UMAC */ + wdiSetBatchScanCb(pSetBatchScanRsp, pWDICtx->pRspCBUserData); + + wpalMemoryFree(pSetBatchScanRsp); + + return WDI_STATUS_SUCCESS; +}/* WDI_ProcessSetBatchScanRsp */ + +/** + @brief Process batch scan result indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBatchScanResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + void *pBatchScanResultInd; + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* extract response and send it to UMAC */ + pBatchScanResultInd = (void *)pEventData->pEventData; + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_BATCH_SCAN_RESULT_IND; + + wdiInd.wdiIndicationData.pBatchScanResult = pBatchScanResultInd; + + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + return WDI_STATUS_SUCCESS; +} /*End of WDI_ProcessBatchScanResultInd*/ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/** + @brief Process Link Layer Statistics Result indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessLinkLayerStatsResultsInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + void *pLinkLayerStatsInd; + WDI_LLstatsResultsType *halLLStatsResults; + wpt_macAddr macAddr; + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: Event RESULTS Indication", __func__); + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* extract response and send it to UMAC */ + pLinkLayerStatsInd = (void *)pEventData->pEventData; + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_LL_STATS_RESULTS_IND; + + wdiInd.wdiIndicationData.wdiLinkLayerStatsResults.pLinkLayerStatsResults + = pLinkLayerStatsInd; + + halLLStatsResults = (WDI_LLstatsResultsType *) pLinkLayerStatsInd; + + + /* Need to fill in the MAC address */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableGetStaMacAddr(pWDICtx, + halLLStatsResults->iface_id, + &macAddr)) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + " ifaceId: %u does not exist in the WDI Station Table", + halLLStatsResults->iface_id); + + return WDI_STATUS_E_FAILURE; + } + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiLinkLayerStatsResults.macAddr, + macAddr, WDI_MAC_ADDR_LEN); + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "ifaceId: %u, macAddr: %pM \n", halLLStatsResults->iface_id, + wdiInd.wdiIndicationData.wdiLinkLayerStatsResults.macAddr); + + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + return WDI_STATUS_SUCCESS; +} /* End of WDI_ProcessLinkLayerStatsResultsInd */ +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/** + @brief WDI_ProcessSetBatchScanReq - + Set batch scan request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status WDI_ProcessSetBatchScanReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetBatchScanReqType *pWdiReq; + WDI_Status wdiStatus; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalBatchScanSetParams *pHalReq; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*sanity check*/ + if ((NULL == pEventData) || (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters in set batch scan request", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + pWdiReq = (WDI_SetBatchScanReqType *)pEventData->pEventData; + + + /*get message buffer*/ + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_SET_BATCH_SCAN_REQ, + sizeof(tHalBatchScanSetParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + sizeof(tHalBatchScanSetParams)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Unable to get send buffer for SET_BATCH_SCAN_REQ "); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalReq = (tHalBatchScanSetParams *)(pSendBuffer + usDataOffset); + + pHalReq->rtt = pWdiReq->rtt; + pHalReq->rfBand = pWdiReq->rfBand; + pHalReq->bestNetworks = pWdiReq->bestNetwork; + pHalReq->scanInterval = pWdiReq->scanFrequency; + pHalReq->numScan2Batch = pWdiReq->numberOfScansToBatch; + + /*send set batch scan request to fw*/ + pWDICtx->pfncRspCB = pEventData->pCBfnc; + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + wdiStatus = WDI_SendMsg(pWDICtx, pSendBuffer, + usSendSize, pWDICtx->pfncRspCB, + pWDICtx->pReqStatusUserData, + WDI_SET_BATCH_SCAN_RESP); + + return wdiStatus; +} + +/** + @brief WDI_SetBatchScanReq + This API is called to set batch scan request in FW + + @param pBatchScanReqParam : pointer to set batch scan re param + usrData : Client context + setBatchScanRspCb : set batch scan resp callback + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_SetBatchScanReq +( + void *pBatchScanReqParam, + void *usrData, + WDI_SetBatchScanCb setBatchScanRspCb +) +{ + WDI_EventInfoType wdiEventData; + + /*sanity check*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /* fill in event data and post to the main FSM */ + wdiEventData.wdiRequest = WDI_SET_BATCH_SCAN_REQ; + wdiEventData.pEventData = pBatchScanReqParam; + wdiEventData.uEventDataSize = sizeof(WDI_SetBatchScanReqType); + wdiEventData.pCBfnc = setBatchScanRspCb; + wdiEventData.pUserData = usrData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_StopbatchScanInd: Send stop batch scan indication to FW + + @param None + + @see + + @return Status of the request +*/ +WDI_Status +WDI_StopBatchScanInd(WDI_StopBatchScanIndType *pWdiReq) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_STOP_BATCH_SCAN_IND; + wdiEventData.pEventData = pWdiReq; + wdiEventData.uEventDataSize = sizeof(WDI_StopBatchScanIndType); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_TriggerBatchScanResultInd + This API is called to pull batch scan result from FW + + @param pWdiReq : pointer to get batch scan ind param + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_TriggerBatchScanResultInd +( + WDI_TriggerBatchScanResultIndType *pWdiReq +) +{ + WDI_EventInfoType wdiEventData; + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_TRIGGER_BATCH_SCAN_RESULT_IND; + wdiEventData.pEventData = pWdiReq; + wdiEventData.uEventDataSize = sizeof(WDI_TriggerBatchScanResultIndType); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} +#endif /*FEATURE_WLAN_BATCH_SCAN*/ + +/** + @brief Process Update Channel Rsp function (called when a response is + being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessUpdateChanRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + WDI_UpdateChannelRspCb wdiUpdateChanRspCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiUpdateChanRspCb = (WDI_UpdateChannelRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + wdiUpdateChanRspCb( wdiStatus, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessUpdateChanRsp*/ + +#ifdef FEATURE_WLAN_CH_AVOID +/** + @brief v -WDI_ProcessChAvoidInd + + + @param pWDICtx : wdi context + pEventData : indication data + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessChAvoidInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalAvoidFreqRangeIndParams chAvoidIndicationParam; + wpt_uint16 rangeLoop; + wpt_uint32 dataSize; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if ((NULL == pWDICtx) || (NULL == pEventData) || + (NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + dataSize = sizeof(tHalAvoidFreqRangeIndParams); + if (dataSize > pEventData->uEventDataSize) + dataSize = pEventData->uEventDataSize; + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy(&chAvoidIndicationParam, + pEventData->pEventData, + dataSize); + + /* Avoid Over flow */ + if (WLAN_HAL_MAX_AVOID_FREQ_RANGE < chAvoidIndicationParam.avoidCnt) + chAvoidIndicationParam.avoidCnt = WLAN_HAL_MAX_AVOID_FREQ_RANGE; + + wdiInd.wdiIndicationType = WDI_CH_AVOID_IND; + wdiInd.wdiIndicationData.wdiChAvoidInd.avoidRangeCount = + chAvoidIndicationParam.avoidCnt; + wpalMemoryCopy((void *)wdiInd.wdiIndicationData.wdiChAvoidInd.avoidFreqRange, + (void *)chAvoidIndicationParam.avoidRange, + wdiInd.wdiIndicationData.wdiChAvoidInd.avoidRangeCount * + sizeof(WDI_ChAvoidFreqType)); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: band count %d", __func__, + wdiInd.wdiIndicationData.wdiChAvoidInd.avoidRangeCount); + for (rangeLoop = 0; rangeLoop < chAvoidIndicationParam.avoidCnt; rangeLoop++) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: srart freq %d, end freq %d", __func__, + wdiInd.wdiIndicationData.wdiChAvoidInd.avoidFreqRange[rangeLoop].startFreq, + wdiInd.wdiIndicationData.wdiChAvoidInd.avoidFreqRange[rangeLoop].endFreq); + } + + /*Notify UMAC*/ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData); + } + + return WDI_STATUS_SUCCESS; +} + +#endif /* FEATURE_WLAN_CH_AVOID */ + +/** + @brief Process OBSS Start scan result indication + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHT40OBSSScanInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usLen = 0; + WDI_HT40ObssScanIndType *pwdiHT40OBSSScanInd = NULL; + WDI_HT40ObssScanParamsType *pwdiHT40OBSSScanParams = NULL; + tHT40ObssScanIndType* pHT40ObssScanInd = NULL; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiHT40OBSSScanParams = (WDI_HT40ObssScanParamsType*)pEventData->pEventData; + + pwdiHT40OBSSScanInd = &pwdiHT40OBSSScanParams->wdiHT40ObssScanParam; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_START_HT40_OBSS_SCAN_IND, + sizeof(tHT40ObssScanIndType), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in HT40 OBSS Start req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pHT40ObssScanInd = (tHT40ObssScanIndType*)(pSendBuffer+usDataOffset); + pHT40ObssScanInd->cmdType = pwdiHT40OBSSScanInd->cmdType; + pHT40ObssScanInd->scanType = pwdiHT40OBSSScanInd->scanType; + pHT40ObssScanInd->OBSSScanPassiveDwellTime = + pwdiHT40OBSSScanInd->OBSSScanPassiveDwellTime; + pHT40ObssScanInd->OBSSScanActiveDwellTime = + pwdiHT40OBSSScanInd->OBSSScanActiveDwellTime; + pHT40ObssScanInd->BSSChannelWidthTriggerScanInterval = + pwdiHT40OBSSScanInd->BSSChannelWidthTriggerScanInterval; + pHT40ObssScanInd->OBSSScanPassiveTotalPerChannel = + pwdiHT40OBSSScanInd->OBSSScanPassiveTotalPerChannel; + pHT40ObssScanInd->OBSSScanActiveTotalPerChannel = + pwdiHT40OBSSScanInd->OBSSScanActiveTotalPerChannel; + pHT40ObssScanInd->BSSWidthChannelTransitionDelayFactor = + pwdiHT40OBSSScanInd->BSSWidthChannelTransitionDelayFactor; + pHT40ObssScanInd->OBSSScanActivityThreshold = + pwdiHT40OBSSScanInd->OBSSScanActivityThreshold; + pHT40ObssScanInd->selfStaIdx = + pwdiHT40OBSSScanInd->selfStaIdx; + pHT40ObssScanInd->bssIdx = + pwdiHT40OBSSScanInd->bssIdx; + pHT40ObssScanInd->currentOperatingClass = + pwdiHT40OBSSScanInd->currentOperatingClass; + pHT40ObssScanInd->fortyMHZIntolerent = + pwdiHT40OBSSScanInd->fortyMHZIntolerent; + pHT40ObssScanInd->channelCount = + pwdiHT40OBSSScanInd->channelCount; + + wpalMemoryCopy(pHT40ObssScanInd->channels, pwdiHT40OBSSScanInd->channels, + WDI_ROAM_SCAN_MAX_CHANNELS); + pHT40ObssScanInd->ieFieldLen = + pwdiHT40OBSSScanInd->ieFieldLen; + + wpalMemoryCopy(pHT40ObssScanInd->ieField, pwdiHT40OBSSScanInd->ieField, + WDI_ROAM_SCAN_MAX_PROBE_SIZE); + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + pWDICtx->wdiReqStatusCB = pwdiHT40OBSSScanParams->wdiReqStatusCB; + pWDICtx->pReqStatusUserData = pwdiHT40OBSSScanParams->pUserData; + + /*------------------------------------------------------------------------- + Send OBSS Start Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; + +} /*End of WDI_ProcessHT40OBSSStartScanInd*/ + + +/** + @brief wdi_HT40OBSSScanInd + This API is called to start OBSS scan + + @param pWdiReq : pointer to get ind param + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_HT40OBSSScanInd +( + WDI_HT40ObssScanParamsType *pWdiReq +) +{ + WDI_EventInfoType wdiEventData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_START_HT40_OBSS_SCAN_IND; + wdiEventData.pEventData = pWdiReq; + wdiEventData.uEventDataSize = sizeof(WDI_HT40ObssScanParamsType); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Process OBSS Stop scan result + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessHT40OBSSStopScanInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint16 usLen = 0; + wpt_uint8 *wdiBssIdx = 0; + tANI_U8 *bssIdx = 0; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + bssIdx = (wpt_uint8*)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_STOP_HT40_OBSS_SCAN_IND, + sizeof(tANI_U8), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + usLen ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in HT40 OBSS Start req %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + bssIdx = (tANI_U8*)pSendBuffer+usDataOffset; + bssIdx = wdiBssIdx; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + /*------------------------------------------------------------------------- + Send DHCP Start Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} /*End of WDI_ProcessHT40OBSSStopScanInd*/ + +/** + @brief WDI_HT40OBSSStopScanInd + This API is called to start OBSS scan + @param pWdiReq : pointer to get ind param + @see + @return SUCCESS or FAIL +*/ +WDI_Status WDI_HT40OBSSStopScanInd +( + wpt_uint8 bssIdx +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_STOP_HT40_OBSS_SCAN_IND; + wdiEventData.pEventData = &bssIdx; + wdiEventData.uEventDataSize = sizeof(wpt_uint8); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_printRegInfo +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tHalRegDebugInfo *pRegTable; + tHalRegDebugInfoParams *pRegParams; + uint32 cnt=0; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: ", __func__); + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pRegParams = (tHalRegDebugInfoParams *)pEventData->pEventData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: regCount: %x scenario: %x reasonCode: %x", __func__, + pRegParams->regCount, pRegParams->scenario, pRegParams->reasonCode); + + pRegTable = (tHalRegDebugInfo *)(pRegParams+1); //data starts after regParams + + if (pRegParams->regCount <= 0) + { + WPAL_TRACE (eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s incorrect parameters passed", __func__); + return WDI_STATUS_E_FAILURE; + } + + while(pRegParams->regCount--) + { + WPAL_TRACE (eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%x: %x", pRegTable[cnt].regAddr, pRegTable[cnt].regValue); + cnt++; + } + + return WDI_STATUS_SUCCESS; +} + +/* + * FUNCTION: WDI_delBaInd + * send the delBA to peer. + */ + +WDI_Status +WDI_delBaInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + +) +{ + tHalWlanDelBaIndMsg halDelBaInd; + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + + /* Parameters need to be unpacked according to HAL struct*/ + wpalMemoryCopy( &halDelBaInd, + pEventData->pEventData, + sizeof(halDelBaInd)); + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_DEL_BA_IND; + + wdiInd.wdiIndicationData.wdiDeleteBAInd.staIdx = halDelBaInd.staIdx; + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteBAInd.peerMacAddr, + halDelBaInd.peerMacAddr, WDI_MAC_ADDR_LEN); + + wdiInd.wdiIndicationData.wdiDeleteBAInd.baTID = halDelBaInd.baTID; + wdiInd.wdiIndicationData.wdiDeleteBAInd.baDirection = halDelBaInd.baDirection; + wdiInd.wdiIndicationData.wdiDeleteBAInd.reasonCode = halDelBaInd.reasonCode; + + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiDeleteBAInd.bssId, + halDelBaInd.bssId, WDI_MAC_ADDR_LEN); + if ( pWDICtx->wdiLowLevelIndCB ) + { + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + + return WDI_STATUS_SUCCESS; + + +} + +/* + * FUNCTION: WDI_ProcessGetBcnMissRateRsp + * send the response to PE with beacon miss count + * received from WDI. + */ +WDI_Status +WDI_ProcessGetBcnMissRateRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetBcnMissRateCb wdiGetBcnMissRateCb; + tpHalBcnMissRateRspParams pHalBcnMissRateRsp; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "In %s",__func__); + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalBcnMissRateRsp = (tHalBcnMissRateRspParams *)pEventData->pEventData; + wdiGetBcnMissRateCb = (WDI_GetBcnMissRateCb)pWDICtx->pfncRspCB; + + /*Notify UMAC*/ + wdiGetBcnMissRateCb(pHalBcnMissRateRsp->status, + pHalBcnMissRateRsp->bcnMissCnt, pWDICtx->pRspCBUserData); + return WDI_STATUS_SUCCESS; +} + +/* + * FUNCTION: WDI_ProcessGetBcnMissRateReq + * Request to WDI to get missed beacon rate. + */ +WDI_Status +WDI_ProcessGetBcnMissRateReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint8 ucCurrentBSSSesIdx = 0; + WDI_BSSSessionType* pBSSSes = NULL; + WDI_GetBcnMissRateCb *wdiGetBcnMissRateCb; + tHalBcnMissRateReqParams halBcnMissRateReq; + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGetBcnMissRateCb = (WDI_GetBcnMissRateCb *)pEventData->pCBfnc; + + wpalMutexAcquire(&pWDICtx->wptMutex); + + ucCurrentBSSSesIdx = WDI_FindAssocSession(pWDICtx, + pEventData->pEventData, &pBSSSes); + if ( NULL == pBSSSes ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Association sequence for this BSS does not yet exist. macBSSID" + MAC_ADDRESS_STR, __func__, + MAC_ADDR_ARRAY((wpt_uint8 *)(pEventData->pEventData))); + wpalMutexRelease(&pWDICtx->wptMutex); + return WDI_STATUS_E_NOT_ALLOWED; + } + wpalMutexRelease(&pWDICtx->wptMutex); + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, WDI_GET_BCN_MISS_RATE_REQ, + sizeof(tHalBcnMissRateReqParams), + &pSendBuffer, &usDataOffset, &usSendSize)) || + ( usSendSize < (usDataOffset + sizeof(tHalBcnMissRateReqParams)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in get WDI_GET_BCN_MISS_RATE_REQ %p", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pWDICtx->wdiReqStatusCB = NULL; + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + halBcnMissRateReq.bssIdx = ucCurrentBSSSesIdx; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halBcnMissRateReq, + sizeof(tHalBcnMissRateReqParams)); + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, wdiGetBcnMissRateCb, + pEventData->pUserData, WDI_GET_BCN_MISS_RATE_RSP); +} + +/** + @brief WDI_GetBcnMissRate + + @param pUserData: user data will be passed back with the + callback + WDI_GetBcnMissRateCb: callback for passing back the response + of the get stats operation received from the device + bssid: bssid, to send bssIdx to FW + + @return SUCCESS or FAIL +*/ +WDI_Status WDI_GetBcnMissRate( void *pUserData, + WDI_GetBcnMissRateCb wdiGetBcnMissRateCb, + tANI_U8 *bssid ) +{ + WDI_EventInfoType wdiEventData; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GET_BCN_MISS_RATE_REQ; + wdiEventData.pEventData = bssid; + wdiEventData.uEventDataSize = sizeof(tSirMacAddr); + wdiEventData.pCBfnc = wdiGetBcnMissRateCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/* + * FUNCTION: WDI_ProcessGetFwStatsRsp + * send the response with FW stats asked. + */ +WDI_Status + WDI_ProcessGetFwStatsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FWStatsGetRspCb wdiGetFwstatsCb; + tpHalfwStatsRspParams pHalFwstatsRsp; + WDI_FWStatsResults fwStats; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pHalFwstatsRsp = (tHalfwStatsRspParams *)pEventData->pEventData; + wdiGetFwstatsCb = (WDI_FWStatsGetRspCb) pWDICtx->pfncRspCB; + + if(pHalFwstatsRsp->length) + { + switch( pHalFwstatsRsp->type ) + { + case FW_UBSP_STATS: + { + ubspFwStats *ubspStatsfromFw; + + fwStats.type = pHalFwstatsRsp->type; + ubspStatsfromFw = (ubspFwStats *) pHalFwstatsRsp->data; + fwStats.wdiFwStatsData.ubspStats.ubsp_enter_cnt = + ubspStatsfromFw->ubsp_enter_cnt; + fwStats.wdiFwStatsData.ubspStats.ubsp_jump_ddr_cnt = + ubspStatsfromFw->ubsp_jump_ddr_cnt; + } + break; + default: + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: No handling for stats type %d", __func__, + pHalFwstatsRsp->type); + wdiGetFwstatsCb(WDI_STATUS_E_FAILURE, + NULL, pWDICtx->pRspCBUserData); + return WDI_STATUS_E_FAILURE; + } + } + wdiGetFwstatsCb(WDI_STATUS_SUCCESS, &fwStats , pWDICtx->pRspCBUserData); + } + else + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Length = 0 for type %d return failure ", __func__, + pHalFwstatsRsp->type); + wdiGetFwstatsCb(WDI_STATUS_E_FAILURE, + NULL, pWDICtx->pRspCBUserData); + return WDI_STATUS_E_FAILURE; + } + return WDI_STATUS_SUCCESS; +} + +/* + * FUNCTION: WDI_ProcessGetFwStatsReq + * Request to WDI to get FW Stats. + */ +WDI_Status + WDI_ProcessGetFwStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_FWStatsGetRspCb *wdiGetFwstatsCb; + tHalfwStatsReqParams halFwStatsReq; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGetFwstatsCb = (WDI_FWStatsGetRspCb *)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, WDI_GET_FW_STATS_REQ, + sizeof(tHalfwStatsReqParams), + &pSendBuffer, &usDataOffset, &usSendSize)) || + ( usSendSize < (usDataOffset + sizeof(tHalfwStatsReqParams)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in get WDI_GET_FW_STAS_REQ %p", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pWDICtx->wdiReqStatusCB = NULL; + pWDICtx->pReqStatusUserData = pEventData->pEventData; + halFwStatsReq.type = *((wpt_uint32 *)(pEventData->pEventData)); + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halFwStatsReq, + sizeof(tHalfwStatsReqParams)); + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, wdiGetFwstatsCb, + pEventData->pUserData, WDI_GET_FW_STATS_RSP); +} + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/** + @brief WDI_LLStatsSetReq + This API is called to set link layer stats request in FW + + @param pwdiLLStatsSetReqParams : pointer to set link layer request params + wdiLLStatsSetRspCb : set link layer stats resp callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_LLStatsSetReq(WDI_LLStatsSetReqType* pwdiLLStatsSetReqParams, + WDI_LLStatsSetRspCb wdiLLStatsSetRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_LL_STATS_SET_REQ; + wdiEventData.pEventData = pwdiLLStatsSetReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiLLStatsSetReqParams); + wdiEventData.pCBfnc = wdiLLStatsSetRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessLLStatsSetReq - + Set Link Layer Stats request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessLLStatsSetReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LLStatsSetReqType* pwdiLLStatsSetReqParams; + WDI_LLStatsSetRspCb wdiLLStatsSetCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalMacLlSetStatsReqParams halLLStatsSetParams; + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiLLStatsSetReqParams = (WDI_LLStatsSetReqType*)pEventData->pEventData; + wdiLLStatsSetCb = (WDI_LLStatsSetRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_LL_STATS_SET_REQ, + sizeof(tHalMacLlSetStatsReqParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halLLStatsSetParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiLLStatsSetReqParams, wdiLLStatsSetCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + /* Need to fill in the self STA Index */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDICtx, + pwdiLLStatsSetReqParams->macAddr, + &halLLStatsSetParams.sta_id)) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + MAC_ADDRESS_STR + ": This station does not exist in the WDI Station Table", + MAC_ADDR_ARRAY(pwdiLLStatsSetReqParams->macAddr)); + + wpalMemoryFree(pSendBuffer); + return WDI_STATUS_E_FAILURE; + } + + halLLStatsSetParams.req_id = pwdiLLStatsSetReqParams->reqId; + halLLStatsSetParams.mpdu_size_threshold = + pwdiLLStatsSetReqParams->mpduSizeThreshold; + halLLStatsSetParams.aggressive_statistics_gathering = + pwdiLLStatsSetReqParams->aggressiveStatisticsGathering; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsSetParams.req_id = %u", + halLLStatsSetParams.req_id); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsSetParams.sta_id = %u", + halLLStatsSetParams.sta_id); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsSetParams.mpdu_size_threshold = %u", + halLLStatsSetParams.mpdu_size_threshold); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsSetParams.aggressive_statistics_gathering = %u", + halLLStatsSetParams.aggressive_statistics_gathering); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halLLStatsSetParams, + sizeof(halLLStatsSetParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + /*------------------------------------------------------------------------- + Send Clear Link Layer Stats Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiLLStatsSetCb, pEventData->pUserData, + WDI_LL_STATS_SET_RSP); +} + +/** + @brief WDI_LLStatsGetReq + This API is called to get link layer stats request in FW + + @param pwdiLLStatsGetReqParams : pointer to set link layer request params + wdiLLStatsGetRspCb : get link layer stats resp callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_LLStatsGetReq(WDI_LLStatsGetReqType* pwdiLLStatsGetReqParams, + WDI_LLStatsGetRspCb wdiLLStatsGetRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_LL_STATS_GET_REQ; + wdiEventData.pEventData = pwdiLLStatsGetReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiLLStatsGetReqParams); + wdiEventData.pCBfnc = wdiLLStatsGetRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessLLStatsGetReq - + Get Link Layer Stats request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessLLStatsGetReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LLStatsGetReqType* pwdiLLStatsGetReqParams; + WDI_LLStatsGetRspCb wdiLLStatsGetCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalMacLlGetStatsReqParams halLLStatsGetParams; + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiLLStatsGetReqParams = (WDI_LLStatsGetReqType*)pEventData->pEventData; + wdiLLStatsGetCb = (WDI_LLStatsGetRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_LL_STATS_GET_REQ, + sizeof(tHalMacLlGetStatsReqParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halLLStatsGetParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiLLStatsGetReqParams, wdiLLStatsGetCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /* Need to fill in the self STA Index */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDICtx, + pwdiLLStatsGetReqParams->macAddr, + &halLLStatsGetParams.sta_id)) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + MAC_ADDRESS_STR + ": This station does not exist in the WDI Station Table", + MAC_ADDR_ARRAY(pwdiLLStatsGetReqParams->macAddr)); + + wpalMemoryFree(pSendBuffer); + return WDI_STATUS_E_FAILURE; + } + + halLLStatsGetParams.req_id = pwdiLLStatsGetReqParams->reqId; + halLLStatsGetParams.param_id_mask = pwdiLLStatsGetReqParams->paramIdMask; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsGetParams.req_id = %u", + halLLStatsGetParams.req_id); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsGetParams.staId = %u", + halLLStatsGetParams.sta_id); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halLLStatsGetParams.Mask = %u", + halLLStatsGetParams.param_id_mask); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halLLStatsGetParams, + sizeof(halLLStatsGetParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + /*------------------------------------------------------------------------- + Send Clear Link Layer Stats Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiLLStatsGetCb, pEventData->pUserData, + WDI_LL_STATS_GET_RSP); +} + +/** + @brief WDI_LLStatsClearReq + This API is called to clear link layer stats request in FW + + @param pwdiLLStatsClearReqParams : pointer to clear link layer request params + wdiLLStatsSetRspCb : clear link layer stats resp callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_LLStatsClearReq(WDI_LLStatsClearReqType* pwdiLLStatsClearReqParams, + WDI_LLStatsClearRspCb wdiLLStatsClearRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_LL_STATS_CLEAR_REQ; + wdiEventData.pEventData = pwdiLLStatsClearReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiLLStatsClearReqParams); + wdiEventData.pCBfnc = wdiLLStatsClearRspCb; + wdiEventData.pUserData = pUserData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s:%d Enter", __func__, __LINE__); + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessLLStatsClearReq - + Clear Link Layer Stats request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessLLStatsClearReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LLStatsClearReqType* pwdiLLStatsClearReqParams; + WDI_LLStatsClearRspCb wdiLLStatsClearCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalMacLlClearStatsReqParams halLLStatsClearParams; + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiLLStatsClearReqParams = (WDI_LLStatsClearReqType*)pEventData->pEventData; + wdiLLStatsClearCb = (WDI_LLStatsClearRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_LL_STATS_CLEAR_REQ, + sizeof(tHalMacLlClearStatsReqParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halLLStatsClearParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiLLStatsClearReqParams, wdiLLStatsClearCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /* Need to fill in the self STA Index */ + if ( WDI_STATUS_SUCCESS != + WDI_STATableFindStaidByAddr(pWDICtx, + pwdiLLStatsClearReqParams->macAddr, + &halLLStatsClearParams.sta_id)) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + MAC_ADDRESS_STR + ": This station does not exist in the WDI Station Table", + MAC_ADDR_ARRAY(pwdiLLStatsClearReqParams->macAddr)); + + wpalMemoryFree(pSendBuffer); + return WDI_STATUS_E_FAILURE; + } + + halLLStatsClearParams.req_id = pwdiLLStatsClearReqParams->reqId; + halLLStatsClearParams.stats_clear_req_mask = + pwdiLLStatsClearReqParams->statsClearReqMask; + halLLStatsClearParams.stop_req = pwdiLLStatsClearReqParams->stopReq; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s:HAL req_id = %d", __func__, halLLStatsClearParams.req_id); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: HAL sta_id = %d", __func__, halLLStatsClearParams.sta_id); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: HAL stats_clear_req_mask = 0x%X", __func__, + halLLStatsClearParams.stats_clear_req_mask); + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: HAL stop_req = %d", __func__, halLLStatsClearParams.stop_req); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halLLStatsClearParams, + sizeof(halLLStatsClearParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + /*------------------------------------------------------------------------- + Send Clear Link Layer Stats Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiLLStatsClearCb, pEventData->pUserData, + WDI_LL_STATS_CLEAR_RSP); +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +WDI_Status WDI_FWStatsGetReq( void* pUserData, + WDI_FWStatsGetRspCb wdiFWStatsGetRspCb, + wpt_uint32 stats) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_GET_FW_STATS_REQ; + wdiEventData.pEventData = (void *)&stats; + wdiEventData.uEventDataSize = sizeof(wpt_uint32); + wdiEventData.pCBfnc = wdiFWStatsGetRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} + +WDI_Status +WDI_MonStartReq(WDI_MonStartReqType* pwdiMonStartReqParams, + WDI_MonModeRspCb wdiMonModeRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_MON_START_REQ; + wdiEventData.pEventData = pwdiMonStartReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiMonStartReqParams); + wdiEventData.pCBfnc = wdiMonModeRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_ProcessMonStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_MonStartReqType* pwdiMonStartReqParams; + WDI_MonModeRspCb wdiMonStartCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalEnableMonitorModeReqParams halEnableMonitorModeParams; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiMonStartReqParams = (WDI_MonStartReqType*)pEventData->pEventData; + wdiMonStartCb = (WDI_MonModeRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_MON_START_REQ, + sizeof(tHalEnableMonitorModeReqParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halEnableMonitorModeParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiMonStartReqParams, wdiMonStartCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halEnableMonitorModeParams.channelNumber = pwdiMonStartReqParams->ChannelNo; + halEnableMonitorModeParams.cbState = WDI_selectCbMode(pwdiMonStartReqParams->ChannelNo, + pwdiMonStartReqParams->ChannelBW); + halEnableMonitorModeParams.maxAmpduLen = 0x1FFFF; + halEnableMonitorModeParams.maxMpduInAmpduLen = 0xF20-0x4C; + halEnableMonitorModeParams.crcCheckEnabled = pwdiMonStartReqParams->crcCheckEnabled; + halEnableMonitorModeParams.numMacFilters = pwdiMonStartReqParams->numOfMacFilters; + wpalMemoryCopy(halEnableMonitorModeParams.macFilters[0].macAddr, + pwdiMonStartReqParams->mmFilters[0].macAddr, + sizeof( wpt_macAddr )); + halEnableMonitorModeParams.macFilters[0].isA1filteringNeeded = pwdiMonStartReqParams->mmFilters[0].isA1filter; + halEnableMonitorModeParams.macFilters[0].isA2filteringNeeded = pwdiMonStartReqParams->mmFilters[0].isA2filter; + halEnableMonitorModeParams.macFilters[0].isA3filteringNeeded = pwdiMonStartReqParams->mmFilters[0].isA3filter; + halEnableMonitorModeParams.typeSubtypeBitmap = pwdiMonStartReqParams->typeSubtypeBitmap; + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halEnableMonitorModeParams, + sizeof(halEnableMonitorModeParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiMonStartCb, pEventData->pUserData, + WDI_MON_START_RSP); +} + +#ifdef DHCP_SERVER_OFFLOAD +/** + * wdi_dhcp_server_offload_rsp() - wdi api for the dhcp server response + * @wdi_ctx: pointer to the wdi context + * @event_data: pointer to the event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_dhcp_server_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_dhcp_srv_offload_rsp_callback = + (wdi_dhcp_srv_offload_rsp_cb)wdi_ctx->pfncRspCB; + + wdi_dhcp_srv_offload_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * wdi_mdns_enable_offload_rsp() - wdi api for the mdns enable response + * @wdi_ctx: pointer to the wdi context + * @event_data: pointer to the event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_mdns_enable_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_mdns_enable_rsp_cb wdi_mdns_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_rsp_callback = + (wdi_mdns_enable_rsp_cb)wdi_ctx->pfncRspCB; + + wdi_mdns_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + * wdi_mdns_fqdn_offload_rsp() - wdi api for the mdns fqdn response + * @wdi_ctx: pointer to the wdi context + * @event_data: pointer to the event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_mdns_fqdn_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_mdns_enable_rsp_cb wdi_mdns_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_rsp_callback = + (wdi_mdns_enable_rsp_cb)wdi_ctx->pfncRspCB; + + wdi_mdns_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + * wdi_mdns_resp_offload_rsp() - wdi api for the mdns resp response + * @wdi_ctx: pointer to the wdi context + * @event_data: pointer to the event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_mdns_resp_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_mdns_resp_rsp_cb wdi_mdns_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_rsp_callback = + (wdi_mdns_resp_rsp_cb)wdi_ctx->pfncRspCB; + + wdi_mdns_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + * wdi_get_mdns_stats_offload_rsp() - wdi api for the mdns stats response + * @wdi_ctx: pointer to the wdi context + * @event_data: pointer to the event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_get_mdns_stats_offload_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_get_stats_rsp_cb wdi_mdns_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_rsp_callback = + (wdi_get_stats_rsp_cb)wdi_ctx->pfncRspCB; + + wdi_mdns_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif /* MDNS_OFFLOAD */ + +WDI_Status +WDI_ProcessMonStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_MonModeRspCb wdiMonStartRspCb; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Enter ", __func__); + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiMonStartRspCb = (WDI_MonModeRspCb)pWDICtx->pfncRspCB; + + wdiMonStartRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_MonStopReq(WDI_MonModeRspCb wdiMonModeRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_MON_STOP_REQ; + wdiEventData.pEventData = NULL; + wdiEventData.uEventDataSize = sizeof(NULL); + wdiEventData.pCBfnc = wdiMonModeRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_ProcessMonStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_MonModeRspCb wdiMonStopCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + wpt_uint8 resetConfiguration; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiMonStopCb = (WDI_MonModeRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_MON_STOP_REQ, + sizeof(wpt_uint8), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(wpt_uint8) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p", __func__, + pEventData, wdiMonStopCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &resetConfiguration, + sizeof(wpt_uint8)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiMonStopCb, pEventData->pUserData, + WDI_MON_STOP_RSP); +} + +WDI_Status +WDI_ProcessMonStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_MonModeRspCb wdiMonStopRspCb; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Enter ", __func__); + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiMonStopRspCb = (WDI_MonModeRspCb)pWDICtx->pfncRspCB; + + wdiMonStopRspCb(pWDICtx->pRspCBUserData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +#ifdef WLAN_FEATURE_EXTSCAN + +/** + @brief Process EXTSCAN BUffer full indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanProgressInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_EXTSCAN_PROGRESS_IND; + + /* extract response and send it to UMAC */ + wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData; + + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + return WDI_STATUS_SUCCESS; + +} /* End of WDI_ProcessEXTScanProgressInd */ + + +/** + @brief Process EXTScan Scan Available indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanScanAvailableInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_EXTSCAN_SCAN_AVAILABLE_IND; + + /* extract response and send it to UMAC */ + wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData; + + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + return WDI_STATUS_SUCCESS; +} /* End of WDI_ProcessEXTScanScanDoneInd */ + +/** + @brief Process EXTScan Result Indication indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_EXTSCAN_SCAN_RESULT_IND; + + /* extract response and send it to UMAC */ + wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData; + + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + return WDI_STATUS_SUCCESS; +} /* End of WDI_ProcessEXTScanResultInd */ + +/** + @brief Process EXTScan BSSID Hotlist Result Indication indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanBssidHotListResultInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_EXTSCAN_BSSID_HOTLIST_RESULT_IND; + + /* extract response and send it to UMAC */ + wdiInd.wdiIndicationData.pEXTScanIndData = (void *)pEventData->pEventData; + + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + return WDI_STATUS_SUCCESS; +} /* End of WDI_ProcessEXTScanBssidHotListResultInd */ + +/** + @brief WDI_EXTScanGetCapabilitiesReq + + @param WDI_EXTScanGetCapabilitiesReqParams: Req parameter for the FW + WDI_EXTScanGetCapabilitiesRspCb: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_EXTScanGetCapabilitiesReq( + WDI_EXTScanGetCapabilitiesReqParams* pwdiEXTScanGetCapabilitiesReqParams, + WDI_EXTScanGetCapabilitiesRspCb wdiEXTScanGetCapabilitiesRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d ",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_EXTSCAN_GET_CAPABILITIES_REQ; + wdiEventData.pEventData = pwdiEXTScanGetCapabilitiesReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEXTScanGetCapabilitiesReqParams); + wdiEventData.pCBfnc = wdiEXTScanGetCapabilitiesRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessEXTScanGetCapabilitiesReq - + Extended Scan Get Capability request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessEXTScanGetCapabilitiesReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanGetCapabilitiesReqParams* pwdiEXTScanGetCapabilitiesReqParams; + WDI_EXTScanGetCapabilitiesRspCb wdiEXTScanGetCapabilitiesRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalExtScanGetCapReq halEXTScanGetCapReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiEXTScanGetCapabilitiesReqParams = + (WDI_EXTScanGetCapabilitiesReqParams* )pEventData->pEventData; + wdiEXTScanGetCapabilitiesRspCb = + (WDI_EXTScanGetCapabilitiesRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_EXTSCAN_GET_CAPABILITIES_REQ, + sizeof(halEXTScanGetCapReqParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halEXTScanGetCapReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiEXTScanGetCapabilitiesReqParams, + wdiEXTScanGetCapabilitiesRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halEXTScanGetCapReqParams.requestId = + pwdiEXTScanGetCapabilitiesReqParams->requestId; + halEXTScanGetCapReqParams.sessionId = + pwdiEXTScanGetCapabilitiesReqParams->sessionId; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " requestId %u " + " sessionId %u ", + halEXTScanGetCapReqParams.requestId, + halEXTScanGetCapReqParams.sessionId); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halEXTScanGetCapReqParams, + sizeof(halEXTScanGetCapReqParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + + /*------------------------------------------------------------------------- + Send EXTScan Stop Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEXTScanGetCapabilitiesRspCb, pEventData->pUserData, + WDI_EXTSCAN_GET_CAPABILITIES_RSP); +} + +/** + @brief WDI_EXTScanGetCachedResultsReq + + @param WDI_EXTScanGetCachedResultsReqParams: Req parameter for the FW + WDI_EXTScanGetCachedResultsRspCb: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ + +WDI_Status +WDI_EXTScanGetCachedResultsReq( + WDI_EXTScanGetCachedResultsReqParams* pwdiEXTScanGetCachedResultsReqParams, + WDI_EXTScanGetCachedResultsRspCb wdiEXTScanGetCachedResultsRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_EXTSCAN_GET_CACHED_RESULTS_REQ; + wdiEventData.pEventData = pwdiEXTScanGetCachedResultsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEXTScanGetCachedResultsReqParams); + wdiEventData.pCBfnc = wdiEXTScanGetCachedResultsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessEXTScanGetCachedResultsReq - + Extended Scan Get Cached Result request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessEXTScanGetCachedResultsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanGetCachedResultsReqParams* pwdiEXTScanGetCachedResultsReqParams; + WDI_EXTScanGetCachedResultsRspCb wdiEXTScanGetCachedResultsCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalExtScanGetScanReq halEXTScanGetScanReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiEXTScanGetCachedResultsReqParams = + (WDI_EXTScanGetCachedResultsReqParams*)pEventData->pEventData; + wdiEXTScanGetCachedResultsCb = + (WDI_EXTScanGetCachedResultsRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_EXTSCAN_GET_CACHED_RESULTS_REQ, + sizeof(tHalExtScanGetScanReq), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halEXTScanGetScanReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiEXTScanGetCachedResultsReqParams, + wdiEXTScanGetCachedResultsCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halEXTScanGetScanReqParams.requestId = + pwdiEXTScanGetCachedResultsReqParams->requestId; + halEXTScanGetScanReqParams.sessionId = + pwdiEXTScanGetCachedResultsReqParams->sessionId; + halEXTScanGetScanReqParams.flush = + pwdiEXTScanGetCachedResultsReqParams->flush; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " requestId %u " + " sessionId %u " + " flush %u ", + halEXTScanGetScanReqParams.requestId, + halEXTScanGetScanReqParams.sessionId, + halEXTScanGetScanReqParams.flush); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halEXTScanGetScanReqParams, + sizeof(halEXTScanGetScanReqParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + + /*------------------------------------------------------------------------- + Send EXTScan Stop Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEXTScanGetCachedResultsCb, pEventData->pUserData, + WDI_EXTSCAN_GET_CACHED_RESULTS_RSP); +} + +/** + @brief WDI_EXTScanStopReq + + @param WDI_EXTScanStopReqParams: Req parameter for the FW + WDI_EXTScanStopRspCb: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_EXTScanStopReq(WDI_EXTScanStopReqParams* pwdiEXTScanStopReqParams, + WDI_EXTScanStopRspCb wdiEXTScanStopRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d ",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_EXTSCAN_STOP_REQ; + wdiEventData.pEventData = pwdiEXTScanStopReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEXTScanStopReqParams); + wdiEventData.pCBfnc = wdiEXTScanStopRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessEXTScanStopReq - + Extended Scan Stop request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessEXTScanStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanStopReqParams* pwdiEXTScanStopReqParams; + WDI_EXTScanStopRspCb wdiEXTScanStopCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tHalExtScanStopReq halEXTScanStopReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d ",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiEXTScanStopReqParams = (WDI_EXTScanStopReqParams*)pEventData->pEventData; + wdiEXTScanStopCb = (WDI_EXTScanStopRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_EXTSCAN_STOP_REQ, + sizeof(tHalExtScanStopReq), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halEXTScanStopReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiEXTScanStopReqParams, wdiEXTScanStopCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halEXTScanStopReqParams.requestId = + pwdiEXTScanStopReqParams->requestId; + halEXTScanStopReqParams.sessionId = + pwdiEXTScanStopReqParams->sessionId; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " halEXTScanStopReqParams.requestId %u " + " halEXTScanStopReqParams.sessionId %u ", + halEXTScanStopReqParams.requestId, + halEXTScanStopReqParams.sessionId); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halEXTScanStopReqParams, + sizeof(halEXTScanStopReqParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + + /*------------------------------------------------------------------------- + Send EXTScan Stop Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEXTScanStopCb, pEventData->pUserData, + WDI_EXTSCAN_STOP_RSP); +} + +/** + @brief WDI_EXTScanStartReq + + @param WDI_EXTScanStartReqParams: Req parameter for the FW + WDI_EXTScanStartRspCb: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_EXTScanStartReq(WDI_EXTScanStartReqParams* pwdiEXTScanStartReqParams, + WDI_EXTScanStartRspCb wdiEXTScanStartRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_EXTSCAN_START_REQ; + wdiEventData.pEventData = pwdiEXTScanStartReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEXTScanStartReqParams); + wdiEventData.pCBfnc = wdiEXTScanStartRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessEXTScanStartReq - + Extended Scan Start Request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessEXTScanStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanStartReqParams* pwdiEXTScanStartReqParams; + WDI_EXTScanStartRspCb wdiEXTScanStartCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tpHalExtScanStartReq pHalExtScanStartReqParams; + int i = 0; + int j = 0; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiEXTScanStartReqParams = + (WDI_EXTScanStartReqParams*)pEventData->pEventData; + wdiEXTScanStartCb = (WDI_EXTScanStartRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_EXTSCAN_START_REQ, + sizeof(tHalExtScanStartReq), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalExtScanStartReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiEXTScanStartReqParams, wdiEXTScanStartCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalExtScanStartReqParams = + (tpHalExtScanStartReq ) (pSendBuffer + usDataOffset); + + pHalExtScanStartReqParams->basePeriod = pwdiEXTScanStartReqParams->basePeriod; + pHalExtScanStartReqParams->maxApPerScan = + pwdiEXTScanStartReqParams->maxAPperScan; + pHalExtScanStartReqParams->reportThresholdPercent = + pwdiEXTScanStartReqParams->reportThresholdPercent; + pHalExtScanStartReqParams->reportThresholdNumScans = + pwdiEXTScanStartReqParams->reportThresholdNumScans; + pHalExtScanStartReqParams->requestId = pwdiEXTScanStartReqParams->requestId; + pHalExtScanStartReqParams->sessionId = pwdiEXTScanStartReqParams->sessionId; + pHalExtScanStartReqParams->numBuckets = pwdiEXTScanStartReqParams->numBuckets; + pHalExtScanStartReqParams->homeAwayTime = pwdiEXTScanStartReqParams->homeAwayTime; + + for( i = 0; i < WDI_WLAN_EXTSCAN_MAX_BUCKETS ; i++ ) + { + pHalExtScanStartReqParams->bucketData[i].bucketId = + pwdiEXTScanStartReqParams->buckets[i].bucket; + pHalExtScanStartReqParams->bucketData[i].channelBand = + pwdiEXTScanStartReqParams->buckets[i].band; + pHalExtScanStartReqParams->bucketData[i].period = + pwdiEXTScanStartReqParams->buckets[i].period; + pHalExtScanStartReqParams->bucketData[i].reportEvents = + pwdiEXTScanStartReqParams->buckets[i].reportEvents; + pHalExtScanStartReqParams->bucketData[i].max_period = + pwdiEXTScanStartReqParams->buckets[i].max_period; + pHalExtScanStartReqParams->bucketData[i].exponent = + pwdiEXTScanStartReqParams->buckets[i].exponent; + pHalExtScanStartReqParams->bucketData[i].step_count = + pwdiEXTScanStartReqParams->buckets[i].step_count; + pHalExtScanStartReqParams->bucketData[i].numChannels = + pwdiEXTScanStartReqParams->buckets[i].numChannels; + + for( j = 0; j< WDI_WLAN_EXTSCAN_MAX_CHANNELS; j++) + { + pHalExtScanStartReqParams->bucketData[i].channelList[j].channel = + pwdiEXTScanStartReqParams->buckets[i].channels[j].channel; + pHalExtScanStartReqParams->bucketData[i].channelList[j].dwellTimeMs = + pwdiEXTScanStartReqParams->buckets[i].channels[j].dwellTimeMs; + pHalExtScanStartReqParams->bucketData[i].channelList[j].passive = + pwdiEXTScanStartReqParams->buckets[i].channels[j].passive; + } + + } + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + " basePeriod %u maxApPerScan %u reportThresholdPercent %u" + "reportThresholdNumScans %u requestId %u" + " sessionId %u numBuckets%u homeAwayTime %u", + pHalExtScanStartReqParams->basePeriod, + pHalExtScanStartReqParams->maxApPerScan, + pHalExtScanStartReqParams->reportThresholdPercent, + pHalExtScanStartReqParams->reportThresholdNumScans, + pHalExtScanStartReqParams->requestId, + pHalExtScanStartReqParams->sessionId, + pHalExtScanStartReqParams->numBuckets, + pHalExtScanStartReqParams->homeAwayTime); + + for( i = 0; i < pHalExtScanStartReqParams->numBuckets ; i++ ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO , + " %d) bucketId %u channelBand %u period %u " + " reportEvents %u numChannels %u " + "max_period %u exponent %u step_count %u",i, + pHalExtScanStartReqParams->bucketData[i].bucketId, + pHalExtScanStartReqParams->bucketData[i].channelBand, + pHalExtScanStartReqParams->bucketData[i].period, + pHalExtScanStartReqParams->bucketData[i].reportEvents, + pHalExtScanStartReqParams->bucketData[i].numChannels, + pHalExtScanStartReqParams->bucketData[i].max_period, + pHalExtScanStartReqParams->bucketData[i].exponent, + pHalExtScanStartReqParams->bucketData[i].step_count); + + for( j = 0; j< pHalExtScanStartReqParams->bucketData[i].numChannels; j++) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%d) channel %u dwellTimeMs %u passive %u ",j, + pHalExtScanStartReqParams->bucketData[i].channelList[j].channel, + pHalExtScanStartReqParams->bucketData[i].channelList[j].dwellTimeMs, + pHalExtScanStartReqParams->bucketData[i].channelList[j].passive); + } + + } + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + /*------------------------------------------------------------------------- + Send EXTSCAN Start Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEXTScanStartCb, pEventData->pUserData, + WDI_EXTSCAN_START_RSP); +} + +/** + @brief WDI_EXTScanSetBSSIDHotlistReq + + @param WDI_EXTScanSetBSSIDHotlistReqParams: Req parameter for the FW + WDI_EXTScanSetBSSIDHotlistRspCb: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_EXTScanSetBSSIDHotlistReq( + WDI_EXTScanSetBSSIDHotlistReqParams* pwdiEXTScanSetBSSIDHotlistReqParams, + WDI_EXTScanSetBSSIDHotlistRspCb wdiEXTScanSetBSSIDHotlistRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter ",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ; + wdiEventData.pEventData = pwdiEXTScanSetBSSIDHotlistReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEXTScanSetBSSIDHotlistReqParams); + wdiEventData.pCBfnc = wdiEXTScanSetBSSIDHotlistRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessEXTScanSetBSSIDHotlistReq - + Extended Scan Set BSSSID Hotlist Request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessEXTScanSetBSSIDHotlistReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanSetBSSIDHotlistReqParams* pwdiEXTScanSetBSSIDHotlistReqParams; + WDI_EXTScanSetBSSIDHotlistRspCb wdiEXTScanSetBSSIDHotlistRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tpHalBssidHotlistSetReq pHalBssidHotlistSetReqParams; + int i; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiEXTScanSetBSSIDHotlistReqParams = + (WDI_EXTScanSetBSSIDHotlistReqParams *)pEventData->pEventData; + wdiEXTScanSetBSSIDHotlistRspCb = + (WDI_EXTScanSetBSSIDHotlistRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_EXTSCAN_SET_BSSID_HOTLIST_REQ, + sizeof(tHalBssidHotlistSetReq), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalBssidHotlistSetReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiEXTScanSetBSSIDHotlistReqParams, + wdiEXTScanSetBSSIDHotlistRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pHalBssidHotlistSetReqParams = + (tpHalBssidHotlistSetReq) (pSendBuffer + usDataOffset); + + pHalBssidHotlistSetReqParams->requestId = + pwdiEXTScanSetBSSIDHotlistReqParams->requestId; + + pHalBssidHotlistSetReqParams->sessionId = + pwdiEXTScanSetBSSIDHotlistReqParams->sessionId; + + pHalBssidHotlistSetReqParams->lostBssidSampleSize = + pwdiEXTScanSetBSSIDHotlistReqParams->lostBssidSampleSize; + + pHalBssidHotlistSetReqParams->numBssid = + pwdiEXTScanSetBSSIDHotlistReqParams->numBssid; + + for( i = 0; i < WLAN_HAL_EXT_SCAN_MAX_HOTLIST_APS; i++){ + + wpalMemoryCopy(pHalBssidHotlistSetReqParams->ap[i].bssid, + pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].bssid, + WDI_MAC_ADDR_LEN); + + pHalBssidHotlistSetReqParams->ap[i].lowRssiThreshold = + pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].low; + + pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold = + pwdiEXTScanSetBSSIDHotlistReqParams->ap[i].high; + + } + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "ReqID %u sessionId %u numBssid %u lostBssidSampleSize: %u", + pHalBssidHotlistSetReqParams->requestId, + pHalBssidHotlistSetReqParams->sessionId, + pHalBssidHotlistSetReqParams->numBssid, + pHalBssidHotlistSetReqParams->lostBssidSampleSize); + + for( i = 0; i < pHalBssidHotlistSetReqParams->numBssid; i++){ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s %d %d) BSSID: %pM lowRssiThreshold %d highRssiThreshold %d", + __func__, __LINE__, i, + pHalBssidHotlistSetReqParams->ap[i].bssid, + pHalBssidHotlistSetReqParams->ap[i].lowRssiThreshold, + pHalBssidHotlistSetReqParams->ap[i].highRssiThreshold); + + } + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + + /*------------------------------------------------------------------------- + Send EXTScan Stop Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEXTScanSetBSSIDHotlistRspCb, pEventData->pUserData, + WDI_EXTSCAN_SET_HOTLIST_BSSID_RSP); +} + +/** + @brief WDI_EXTScanResetBSSIDHotlistReq + + @param WDI_EXTScanResetBSSIDHotlistReqParams: Req parameter for the FW + WDI_EXTScanResetBSSIDHotlistRspCb: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_EXTScanResetBSSIDHotlistReq( + WDI_EXTScanResetBSSIDHotlistReqParams* pwdiEXTScanResetBSSIDHotlistReqParams, + WDI_EXTScanResetBSSIDHotlistRspCb wdiEXTScanResetBSSIDHotlistRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ; + wdiEventData.pEventData = pwdiEXTScanResetBSSIDHotlistReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiEXTScanResetBSSIDHotlistReqParams); + wdiEventData.pCBfnc = wdiEXTScanResetBSSIDHotlistRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessEXTScanResetBSSIDHotlistReq - + Extended Scan reset BSSID hotlist Request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessEXTScanResetBSSIDHotlistReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanResetBSSIDHotlistReqParams* pwdiEXTScanResetBSSIDHotlistReqParams; + WDI_EXTScanResetBSSIDHotlistRspCb wdiEXTScanResetBSSIDHotlistRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tpHalHotlistResetReq pHalHotlistResetReqParams; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pwdiEXTScanResetBSSIDHotlistReqParams = + (WDI_EXTScanResetBSSIDHotlistReqParams *)pEventData->pEventData; + wdiEXTScanResetBSSIDHotlistRspCb = + (WDI_EXTScanResetBSSIDHotlistRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_EXTSCAN_RESET_BSSID_HOTLIST_REQ, + sizeof(tHalHotlistResetReq), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalHotlistResetReq) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiEXTScanResetBSSIDHotlistReqParams, + wdiEXTScanResetBSSIDHotlistRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pHalHotlistResetReqParams = + (tpHalHotlistResetReq) (pSendBuffer+usDataOffset); + + pHalHotlistResetReqParams->requestId = + pwdiEXTScanResetBSSIDHotlistReqParams->requestId; + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + /*------------------------------------------------------------------------- + Send EXTScan Stop Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiEXTScanResetBSSIDHotlistRspCb, pEventData->pUserData, + WDI_EXTSCAN_RESET_HOTLIST_BSSID_RSP); +} + +/** + @brief WDI_HighPriorityDataInfoInd + + @param pHighPriorityDataInfoIndParams: Req parameter for the FW + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_HighPriorityDataInfoInd +( + WDI_HighPriorityDataInfoIndParams* pHighPriorityDataInfoIndParams +) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d",__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_HIGH_PRIORITY_DATA_INFO_IND; + wdiEventData.pEventData = pHighPriorityDataInfoIndParams; + wdiEventData.uEventDataSize = sizeof(*pHighPriorityDataInfoIndParams); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessHighPriorityDataInfoInd - + Send WFD indication to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessHighPriorityDataInfoInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_HighPriorityDataInfoIndParams* pHighPriorityDataInfoIndParams; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tpHalHighPriorityDataInfoInd pHalHighPriorityDataInfoIndParams; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d",__func__, __LINE__); + + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHighPriorityDataInfoIndParams = + (WDI_HighPriorityDataInfoIndParams *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_HIGH_PRIORITY_DATA_INFO_IND, + sizeof(tHalHighPriorityDataInfoInd), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalHighPriorityDataInfoInd) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p", __func__, + pEventData, pHighPriorityDataInfoIndParams); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pHalHighPriorityDataInfoIndParams = + (tpHalHighPriorityDataInfoInd) (pSendBuffer+usDataOffset); + + pHalHighPriorityDataInfoIndParams->pause = + pHighPriorityDataInfoIndParams->pause; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + /*------------------------------------------------------------------------- + Send HIGH_PRIORITY_DATA_INFO Request to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + +/** + @brief Process Extended Scan Start Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanStartRspCb wdiEXTScanStartRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d",__func__, __LINE__); + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanStartRspCb = (WDI_EXTScanStartRspCb)pWDICtx->pfncRspCB; + if ( NULL == wdiEXTScanStartRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Callback function Invalid", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanStartRspCb((void *)pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + + +/** + @brief Process Extended Scan Stop Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanStopRspCb wdiEXTScanStopRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d",__func__, __LINE__); + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanStopRspCb = (WDI_EXTScanStartRspCb)pWDICtx->pfncRspCB; + if ( NULL == wdiEXTScanStopRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Callback function Invalid", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanStopRspCb((void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Extended Scan Get Cached Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanGetCachedResultsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanGetCachedResultsRspCb wdiEXTScanGetCachedResultsRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanGetCachedResultsRspCb = (WDI_EXTScanStartRspCb)pWDICtx->pfncRspCB; + if ( NULL == wdiEXTScanGetCachedResultsRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Callback function Invalid", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanGetCachedResultsRspCb( + (void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Extended Scan Get Capabilityu Rsp function (called when a response + is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanGetCapabilitiesRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanGetCapabilitiesRspCb wdiEXTScanGetCapabilitiesRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d ",__func__, __LINE__); + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanGetCapabilitiesRspCb = + (WDI_EXTScanGetCapabilitiesRspCb)pWDICtx->pfncRspCB; + if ( NULL == wdiEXTScanGetCapabilitiesRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Callback function Invalid", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanGetCapabilitiesRspCb( + (void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Extended Scan Set hotlist BSSID Rsp function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanSetHotlistBSSIDRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanSetBSSIDHotlistRspCb wdiEXTScanSetBSSIDHotlistRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d ",__func__, __LINE__); + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanSetBSSIDHotlistRspCb = + (WDI_EXTScanSetBSSIDHotlistRspCb)pWDICtx->pfncRspCB; + if ( NULL == wdiEXTScanSetBSSIDHotlistRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Callback function Invalid", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanSetBSSIDHotlistRspCb( + (void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Extended Scan Reset Hotlist BSSID Rsp function (called + when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessEXTScanResetHotlistBSSIDRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_EXTScanResetBSSIDHotlistRspCb wdiEXTScanResetBSSIDHotlistRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d ",__func__, __LINE__); + + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanResetBSSIDHotlistRspCb = + (WDI_EXTScanResetBSSIDHotlistRspCb)pWDICtx->pfncRspCB; + if ( NULL == wdiEXTScanResetBSSIDHotlistRspCb) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Callback function Invalid", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEXTScanResetBSSIDHotlistRspCb( + (void *) pEventData->pEventData, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_EXTSCAN */ + +/** + @brief WDI_SetSpoofMacAddrReq: Send Spoof Mac Addr request to FW + + @param None + + @see + + @return Status of the request +*/ +WDI_Status +WDI_SetSpoofMacAddrReq +( + WDI_SpoofMacAddrInfoType* pWdiReq, + WDI_SetSpoofMacAddrRspCb spoofMacAddrRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------- + Sanity Check + ------------------------------------------------------------------------*/ + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request!"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------- + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SPOOF_MAC_ADDR_REQ; + wdiEventData.pEventData = pWdiReq; + wdiEventData.uEventDataSize = sizeof(WDI_SpoofMacAddrInfoType); + wdiEventData.pCBfnc = spoofMacAddrRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Process SpoofMacAddr Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSpoofMacAddrReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SpoofMacAddrInfoType* wdiSpoofMacAddr; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tMacSpoofedScanReqMsg halWlanSpoofMacAddr; + WDI_SetSpoofMacAddrRspCb wdiMacAddrSpoofCb; + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiSpoofMacAddr = (WDI_SpoofMacAddrInfoType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_SPOOF_MAC_ADDR_REQ, + sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Process Spoof Mac Addr Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy(halWlanSpoofMacAddr.tMacSpoofedScanReqParams.macAddr, + wdiSpoofMacAddr->macAddr, + sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams.macAddr)); + + wdiMacAddrSpoofCb = (WDI_SetSpoofMacAddrRspCb)pEventData->pCBfnc; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halWlanSpoofMacAddr.tMacSpoofedScanReqParams, + sizeof(halWlanSpoofMacAddr.tMacSpoofedScanReqParams)); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiMacAddrSpoofCb, pEventData->pUserData, WDI_SPOOF_MAC_ADDR_RSP); + + return wdiStatus; +} + +/** + @brief Process Spoof Mac Address Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessSpoofMacAddrRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tMacSpoofedScanResp halRsp; + WDI_SetSpoofMacAddrRspCb wdiSpoofMacAddrRspCb; + WDI_SpoofMacAddrRspParamType wdiSpoofMacAddrRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiSpoofMacAddrRspCb = (WDI_SetSpoofMacAddrRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp, + pEventData->pEventData, sizeof(halRsp)); + + wdiSpoofMacAddrRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status); + + /*Notify UMAC*/ + wdiSpoofMacAddrRspCb( + &wdiSpoofMacAddrRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Get Frame Log Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetFrameLogRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tGetFrameLogResp halRsp; + WDI_GetFrameLogRspCb wdiGetFrameLogRspCb; + WDI_GetFrameLogRspParamType wdiGetFrameLogRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGetFrameLogRspCb = (WDI_GetFrameLogRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp, + pEventData->pEventData, sizeof(halRsp)); + + wdiGetFrameLogRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status); + + /*Notify UMAC*/ + wdiGetFrameLogRspCb( &wdiGetFrameLogRsp, pWDICtx->pRspCBUserData ); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process RssiMonitorStartReq Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRssiMonitorStartReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RssiMonitorReqInfoType* wdiRssiMonitorStartReq; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalStartRssimonitoringReq halStartRssiMonitorReq; + WDI_RssiMonitorStartRspCb wdiRssiMonitorStartReqCb; + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiRssiMonitorStartReq = (WDI_RssiMonitorReqInfoType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_START_RSSI_MONITOR_REQ, + sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halStartRssiMonitorReq.startRssiMonitoringReqParams.request_id = + wdiRssiMonitorStartReq->requestId; + + halStartRssiMonitorReq.startRssiMonitoringReqParams.min_rssi = + wdiRssiMonitorStartReq->minRssi; + + halStartRssiMonitorReq.startRssiMonitoringReqParams.max_rssi = + wdiRssiMonitorStartReq->maxRssi; + wpalMemoryCopy(halStartRssiMonitorReq.startRssiMonitoringReqParams.bssId, + &(wdiRssiMonitorStartReq->currentBssId), + sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams.bssId)); + + wdiRssiMonitorStartReqCb = (WDI_RssiMonitorStartRspCb)pEventData->pCBfnc; + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halStartRssiMonitorReq.startRssiMonitoringReqParams, + sizeof(halStartRssiMonitorReq.startRssiMonitoringReqParams)); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + ------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRssiMonitorStartReqCb, pEventData->pUserData, WDI_START_RSSI_MONITOR_RSP); + + return wdiStatus; +} + + +/** + @brief Process FWLoggingInit Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRssiMonitorStopReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_RssiMonitorReqInfoType* wdiRssiMonitorStopReq; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalStopRssimonitoringReq halStopRssiMonitorReq; + WDI_RssiMonitorStopRspCb wdiRssiMonitorStopReqCb; + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiRssiMonitorStopReq = (WDI_RssiMonitorReqInfoType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_STOP_RSSI_MONITOR_REQ, + sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halStopRssiMonitorReq.stopRssiMonitoringParams.request_id = + wdiRssiMonitorStopReq->requestId; + + wpalMemoryCopy(halStopRssiMonitorReq.stopRssiMonitoringParams.bssId, + &(wdiRssiMonitorStopReq->currentBssId), + sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams.bssId)); + + wdiRssiMonitorStopReqCb = (WDI_RssiMonitorStopRspCb)pEventData->pCBfnc; + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halStopRssiMonitorReq.stopRssiMonitoringParams, + sizeof(halStopRssiMonitorReq.stopRssiMonitoringParams)); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + ------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiRssiMonitorStopReqCb, pEventData->pUserData, WDI_STOP_RSSI_MONITOR_RSP); + + return wdiStatus; +} + +/** + @brief Process MgmtFrame Logging Init Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRssiMonitorStopRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tHalStopRssimonitoringRspParams halRsp; + WDI_RssiMonitorStopRspCb wdiRssiMonitorStopRspCb; + WDI_RssiMonitorStopRspParamType wdiRssiMonitorStopRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiRssiMonitorStopRspCb = (WDI_RssiMonitorStopRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp)); + + wdiRssiMonitorStopRsp.status = WDI_HAL_2_WDI_STATUS(halRsp.status); + + /*Notify UMAC*/ + wdiRssiMonitorStopRspCb( &wdiRssiMonitorStopRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + + +/** + @brief Process MgmtFrame Logging Init Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessRssiMonitorStartRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tHalStartRssimonitoringRspParams halRsp; + WDI_RssiMonitorStartRspCb wdiRssiMonitorStartRspCb; + WDI_RssiMonitorStartRspParamType wdiRssiMonitorStartRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiRssiMonitorStartRspCb = (WDI_RssiMonitorStopRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp)); + + wdiRssiMonitorStartRsp.status = WDI_HAL_2_WDI_STATUS(halRsp.status); + + /*Notify UMAC*/ + wdiRssiMonitorStartRspCb( &wdiRssiMonitorStartRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process FWLoggingInit Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetFrameLogReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetFrameLogReqInfoType* wdiGetFrameLogReq; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tGetFrameLogReqMsg halGetFrameLogReq; + WDI_FWLoggingInitRspCb wdiGetFrameLogRspCb; + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiGetFrameLogReq = (WDI_GetFrameLogReqInfoType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_GET_FRAME_LOG_REQ, + sizeof(halGetFrameLogReq.tGetFrameLogReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halGetFrameLogReq.tGetFrameLogReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halGetFrameLogReq.tGetFrameLogReqParams.flags = + wdiGetFrameLogReq->flags; + + wdiGetFrameLogRspCb = (WDI_FWLoggingInitRspCb)pEventData->pCBfnc; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halGetFrameLogReq.tGetFrameLogReqParams, + sizeof(halGetFrameLogReq.tGetFrameLogReqParams)); + + /*------------------------------------------------------------------------- + Send Suspend Request to HAL + ------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiGetFrameLogRspCb, pEventData->pUserData, WDI_GET_FRAME_LOG_RSP); + + return wdiStatus; +} +/** + @brief Process MgmtFrame Logging Init Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFWFrameLoggingInitRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tFWLoggingInitResp halRsp; + WDI_FWLoggingInitRspCb wdiFWFrameLoggingInitRspCb; + WDI_FWLoggingInitRspParamType wdiFWLogginginitRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiFWFrameLoggingInitRspCb = (WDI_FWLoggingInitRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp)); + + wdiFWLogginginitRsp.status = WDI_HAL_2_WDI_STATUS(halRsp.status); + wdiFWLogginginitRsp.fw_mem_dump_max_size = halRsp.fw_dump_max_size; + + /*Notify UMAC*/ + wdiFWFrameLoggingInitRspCb( &wdiFWLogginginitRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Fwr Mem Dump Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status + WDI_ProcessFwrMemDumpRsp + +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tHalFwMemoryDumpRespMsg halRsp; + WDI_FwrMemDumpRspCb wdiFwrMemDumpRspCb; + WDI_FwrMemDumpRsp wdiFwrMemDumpRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiFwrMemDumpRspCb = (WDI_FwrMemDumpRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp.tFwMemoryDumpResp, pEventData->pEventData, sizeof(halRsp.tFwMemoryDumpResp)); + + wdiFwrMemDumpRsp.dump_status = WDI_HAL_2_WDI_STATUS(halRsp.tFwMemoryDumpResp.status); + + /*Notify UMAC*/ + wdiFwrMemDumpRspCb( &wdiFwrMemDumpRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_ProcessFWLoggingDXEdoneInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tFWLoggingDxeDoneInd *FWLoggingDxeDoneIndParams; + WDI_DS_LoggingSessionType *pLoggingSession; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_uint32 *pLogType; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (NULL == pEventData || + NULL == pEventData->pEventData) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pLogType = (wpt_uint32 *)pEventData->pEventData; + + pLoggingSession = (WDI_DS_LoggingSessionType *) + WDI_DS_GetLoggingSession(WDI_DS_GetDatapathContext( + (void *)pWDICtx)); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_FW_LOGGING_DXE_DONE_IND, + sizeof(tFWLoggingDxeDoneInd), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tFWLoggingDxeDoneInd) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in RTS CTS ind %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + FWLoggingDxeDoneIndParams = + (tFWLoggingDxeDoneInd*)(pSendBuffer + usDataOffset); + + wpalMemoryCopy(&FWLoggingDxeDoneIndParams->logBuffAddress, + &pLoggingSession->logBuffAddress, MAX_NUM_OF_BUFFER * + sizeof(FWLoggingDxeDoneIndParams->logBuffAddress[0])); + + FWLoggingDxeDoneIndParams->status = pLoggingSession->status; + FWLoggingDxeDoneIndParams->doneIndicationForSource = (wpt_uint16)*pLogType; + + wpalMemoryCopy(&FWLoggingDxeDoneIndParams->logBuffLength, + &pLoggingSession->logBuffLength, MAX_NUM_OF_BUFFER * + sizeof(FWLoggingDxeDoneIndParams->logBuffLength[0])); + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send FW_LOGGING_DXE_DONE_IND Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + + +/** + @brief Process Fatal Event Logs Rsp function + (called when a response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFatalEventLogsRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tHalFatalEventLoggingRspParams halRsp; + WDI_FatalEventLogsRspCb wdiFatalEventLogsRspCb; + WDI_FatalEventLogsRspParamType wdiFatalEventLogsRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiFatalEventLogsRspCb = (WDI_FatalEventLogsRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( &halRsp, pEventData->pEventData, sizeof(halRsp)); + + wdiFatalEventLogsRsp.wdiStatus = WDI_HAL_2_WDI_STATUS(halRsp.status); + + /*Notify UMAC*/ + wdiFatalEventLogsRspCb( &wdiFatalEventLogsRsp, + pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process FatalEventLogs Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ + +WDI_Status +WDI_ProcessFatalEventLogsReq + +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FatalEventLogsReqInfoType* wdiFatalEventLogsReq; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalFatalEventLoggingReqMsg halFatalEventLoggingReq; + WDI_FatalEventLogsRspCb wdiFatalEventLogsRspCb; + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiFatalEventLogsReq = + (WDI_FatalEventLogsReqInfoType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_FATAL_EVENT_LOGGING_REQ, + sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Fatal Event Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + halFatalEventLoggingReq.tFatalEventLoggingReqParams.reasonCode = + wdiFatalEventLogsReq->reason_code; + + wdiFatalEventLogsRspCb = (WDI_FatalEventLogsRspCb)pEventData->pCBfnc; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halFatalEventLoggingReq.tFatalEventLoggingReqParams, + sizeof(halFatalEventLoggingReq.tFatalEventLoggingReqParams)); + + /*------------------------------------------------------------------------- + Send Mgmt Logging Init Request to HAL + ------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiFatalEventLogsRspCb, pEventData->pUserData, + WDI_FATAL_EVENT_LOGGING_RSP); + + return wdiStatus; + + +} + +#ifdef DHCP_SERVER_OFFLOAD +/** + * wdi_dhcp_server_offload_req() - wdi api for dhcp server offload + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_dhcp_server_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_set_dhcp_server_offload_t *wdi_dhcp_server_info; + wpt_uint8 *buff = NULL; + wpt_uint16 data_offset = 0; + wpt_uint16 size = 0; + WDI_Status wdi_status; + hal_dhcp_srv_offload_req_msg_t dhcp_srv_offload_req; + wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_dhcp_server_info = (wdi_set_dhcp_server_offload_t *) + event_data->pEventData; + + /*------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_DHCP_SERVER_OFFLOAD_REQ, + sizeof(dhcp_srv_offload_req. + dhcp_srv_offload_req_params), + &buff, &data_offset, &size))|| + (size < (data_offset + + sizeof(dhcp_srv_offload_req.dhcp_srv_offload_req_params)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + dhcp_srv_offload_req.dhcp_srv_offload_req_params.bss_idx = + wdi_dhcp_server_info->bssidx; + dhcp_srv_offload_req.dhcp_srv_offload_req_params.enable = + wdi_dhcp_server_info->enable; + dhcp_srv_offload_req.dhcp_srv_offload_req_params.srv_ipv4 = + wdi_dhcp_server_info->srv_ipv4; + dhcp_srv_offload_req.dhcp_srv_offload_req_params.start_lsb = + wdi_dhcp_server_info->start_lsb; + dhcp_srv_offload_req.dhcp_srv_offload_req_params.num_client = + wdi_dhcp_server_info->num_client; + + wdi_dhcp_srv_offload_rsp_callback = (wdi_dhcp_srv_offload_rsp_cb) + event_data->pCBfnc; + + wpalMemoryCopy(buff+data_offset, + &dhcp_srv_offload_req.dhcp_srv_offload_req_params, + sizeof(dhcp_srv_offload_req. + dhcp_srv_offload_req_params)); + + /*------------------------------------------------------------------- + Send Suspend Request to HAL + -----------------------------------------------------------------*/ + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_dhcp_srv_offload_rsp_callback, + event_data->pUserData, + WDI_DHCP_SERVER_OFFLOAD_RSP); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} +#endif /* DHCP_SERVER_OFFLOAD */ + +#ifdef MDNS_OFFLOAD +/** + * wdi_mdns_enable_offload_req() - wdi api for dhcp server offload + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_mdns_enable_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data + ) +{ + wdi_mdns_enable_offload_cmd_req *wdi_mdns_enable_info; + wpt_uint8 *buff = NULL; + wpt_uint16 data_offset = 0; + wpt_uint16 size = 0; + WDI_Status wdi_status; + hal_mdns_enable_offload_req_msg_t mdns_enable_req; + wdi_mdns_enable_rsp_cb wdi_mdns_enable_rsp_callback;; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_enable_info = (wdi_mdns_enable_offload_cmd_req *) + event_data->pEventData; + + /*------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_MDNS_ENABLE_OFFLOAD_REQ, + sizeof(mdns_enable_req. + mdns_enable_req_params), + &buff, &data_offset, &size))|| + (size < (data_offset + + sizeof(mdns_enable_req.mdns_enable_req_params)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + mdns_enable_req.mdns_enable_req_params.bss_idx = + wdi_mdns_enable_info->bss_idx; + mdns_enable_req.mdns_enable_req_params.enable = + wdi_mdns_enable_info->enable; + + wdi_mdns_enable_rsp_callback = (wdi_mdns_enable_rsp_cb) + event_data->pCBfnc; + + wpalMemoryCopy(buff+data_offset, + &mdns_enable_req.mdns_enable_req_params, + sizeof(mdns_enable_req. + mdns_enable_req_params)); + + /*------------------------------------------------------------------- + Send Suspend Request to HAL + -----------------------------------------------------------------*/ + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_mdns_enable_rsp_callback, + event_data->pUserData, + WDI_MDNS_ENABLE_OFFLOAD_RSP); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} + +/** + * wdi_mdns_fqdn_offload_req() - wdi api for mdns fqdn offload + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_mdns_fqdn_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data + ) +{ + wdi_mdns_set_fqdn_cmd_req *wdi_mdns_fqdn_info; + wpt_uint8 *buff = NULL; + wpt_uint16 buf_size, data_offset = 0; + wpt_uint16 temp_size, size = 0; + WDI_Status wdi_status; + hal_mdns_fqdn_offload_req_param_t mdns_fqdn; + wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_rsp_callback;; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_fqdn_info = (wdi_mdns_set_fqdn_cmd_req *) + event_data->pEventData; + + mdns_fqdn.bss_idx = wdi_mdns_fqdn_info->bss_idx; + mdns_fqdn.type = wdi_mdns_fqdn_info->type; + mdns_fqdn.fqdn_len = wdi_mdns_fqdn_info->fqdn_len; + + buf_size = sizeof(mdns_fqdn) + mdns_fqdn.fqdn_len - + sizeof(mdns_fqdn.fqdn_data[1]); + + /*------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_MDNS_FQDN_OFFLOAD_REQ, + buf_size, + &buff, &data_offset, &size))|| + (size < (data_offset + buf_size))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_fqdn_rsp_callback = (wdi_mdns_fqdn_rsp_cb) + event_data->pCBfnc; + + temp_size = 0; + wpalMemoryCopy(buff+data_offset+temp_size, + &mdns_fqdn.bss_idx, + sizeof(mdns_fqdn.bss_idx)); + temp_size += sizeof(mdns_fqdn.bss_idx); + wpalMemoryCopy(buff+data_offset+temp_size, + &mdns_fqdn.type, + sizeof(mdns_fqdn.type)); + temp_size += sizeof(mdns_fqdn.type); + wpalMemoryCopy(buff+data_offset+temp_size, + &mdns_fqdn.fqdn_len, + sizeof(mdns_fqdn.fqdn_len)); + temp_size += sizeof(mdns_fqdn.fqdn_len); + wpalMemoryCopy(buff+data_offset+temp_size, + wdi_mdns_fqdn_info->fqdn_data, + wdi_mdns_fqdn_info->fqdn_len); + + /*------------------------------------------------------------------- + Send Suspend Request to HAL + -----------------------------------------------------------------*/ + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_mdns_fqdn_rsp_callback, + event_data->pUserData, + WDI_MDNS_FQDN_OFFLOAD_RSP); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} + +/** + * wdi_mdns_resp_offload_req() - wdi api for mdns response offload + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_mdns_resp_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data + ) +{ + wdi_mdns_set_resp_req *wdi_mdns_resp_info; + wpt_uint8 *buff = NULL; + wpt_uint16 buf_size, data_offset = 0; + wpt_uint16 temp_size, size = 0; + WDI_Status wdi_status; + hal_mdns_resp_offload_req_param_t mdns_resp; + wdi_mdns_resp_rsp_cb wdi_mdns_resp_rsp_callback;; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_resp_info = (wdi_mdns_set_resp_req *) + event_data->pEventData; + + mdns_resp.bss_idx = wdi_mdns_resp_info->bss_idx; + mdns_resp.ar_count = wdi_mdns_resp_info->ar_count; + mdns_resp.resp_len = wdi_mdns_resp_info->resp_len; + + buf_size = sizeof(mdns_resp) + mdns_resp.resp_len - + sizeof(mdns_resp.resp_data[1]); + + /*------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_MDNS_RESP_OFFLOAD_REQ, + buf_size, + &buff, &data_offset, &size))|| + (size < (data_offset + buf_size))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_resp_rsp_callback = (wdi_mdns_resp_rsp_cb) + event_data->pCBfnc; + + temp_size = 0; + wpalMemoryCopy(buff+data_offset+temp_size, + &mdns_resp.bss_idx, + sizeof(mdns_resp.bss_idx)); + temp_size += sizeof(mdns_resp.bss_idx); + wpalMemoryCopy(buff+data_offset+temp_size, + &mdns_resp.ar_count, + sizeof(mdns_resp.ar_count)); + temp_size += sizeof(mdns_resp.ar_count); + wpalMemoryCopy(buff+data_offset+temp_size, + &mdns_resp.resp_len, + sizeof(mdns_resp.resp_len)); + temp_size += sizeof(mdns_resp.resp_len); + wpalMemoryCopy(buff+data_offset+temp_size, + &wdi_mdns_resp_info->resp_data, + wdi_mdns_resp_info->resp_len); + + /*------------------------------------------------------------------- + Send Suspend Request to HAL + -----------------------------------------------------------------*/ + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_mdns_resp_rsp_callback, + event_data->pUserData, + WDI_MDNS_RESP_OFFLOAD_RSP); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} + +/** + * wdi_get_mdns_stats_offload_req() - wdi api for mdns stats offload + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_get_mdns_stats_offload_req +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data + ) +{ + wdi_mdns_get_stats_req *wdi_mdns_stats_info; + wpt_uint8 *buff = NULL; + wpt_uint16 data_offset = 0; + wpt_uint16 size = 0; + WDI_Status wdi_status; + hal_mdns_stats_offload_req_msg_t mdns_stats_req; + wdi_get_stats_rsp_cb wdi_mdns_stats_rsp_callback;; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------ + Sanity check + ------------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_mdns_stats_info = (wdi_mdns_get_stats_req *) + event_data->pEventData; + + /*------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_MDNS_STATS_OFFLOAD_REQ, + sizeof(mdns_stats_req. + mdns_stats_req_params), + &buff, &data_offset, &size))|| + (size < (data_offset + + sizeof(mdns_stats_req.mdns_stats_req_params)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetFrameLog Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + mdns_stats_req.mdns_stats_req_params.bss_idx = + wdi_mdns_stats_info->bss_idx; + + wdi_mdns_stats_rsp_callback = (wdi_get_stats_rsp_cb) + event_data->pCBfnc; + + wpalMemoryCopy(buff+data_offset, + &mdns_stats_req.mdns_stats_req_params, + sizeof(mdns_stats_req. + mdns_stats_req_params)); + + /*------------------------------------------------------------------- + Send Suspend Request to HAL + -----------------------------------------------------------------*/ + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_mdns_stats_rsp_callback, + event_data->pUserData, + WDI_MDNS_STATS_OFFLOAD_RSP); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} +#endif /* MDNS_OFFLOAD */ + +/** + @brief Process FWLoggingInit Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessFWLoggingInitReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FWLoggingInitReqInfoType* wdiFWLoggingInitReq; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalFWLoggingInitReqMsg halFWLoggingInitReq; + WDI_FWLoggingInitRspCb wdiFWLoggingInitRspCb; + + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiFWLoggingInitReq = + (WDI_FWLoggingInitReqInfoType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_FW_LOGGING_INIT_REQ, + sizeof(halFWLoggingInitReq.tFWLoggingInitReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halFWLoggingInitReq.tFWLoggingInitReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Process Mgmt Logging Init Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halFWLoggingInitReq.tFWLoggingInitReqParams.enableFlag= + wdiFWLoggingInitReq->enableFlag; + halFWLoggingInitReq.tFWLoggingInitReqParams.frameSize= + wdiFWLoggingInitReq->frameSize; + halFWLoggingInitReq.tFWLoggingInitReqParams.frameType= + wdiFWLoggingInitReq->frameType; + halFWLoggingInitReq.tFWLoggingInitReqParams.bufferMode= + wdiFWLoggingInitReq->bufferMode; + halFWLoggingInitReq.tFWLoggingInitReqParams.continuousFrameLogging= + wdiFWLoggingInitReq->continuousFrameLogging; + halFWLoggingInitReq.tFWLoggingInitReqParams.minLogBuffSize= + wdiFWLoggingInitReq->minLogBufferSize; + halFWLoggingInitReq.tFWLoggingInitReqParams.maxLogBuffSize= + wdiFWLoggingInitReq->maxLogBufferSize; + halFWLoggingInitReq.tFWLoggingInitReqParams.logMailBoxAddr= + (tANI_U64)(uintptr_t)(WDI_DS_GetLoggingMbPhyAddr(pWDICtx)); + halFWLoggingInitReq.tFWLoggingInitReqParams.logMailBoxVer= + MAILBOX_VERSION_V1; + + wdiFWLoggingInitRspCb = (WDI_FWLoggingInitRspCb)pEventData->pCBfnc; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halFWLoggingInitReq.tFWLoggingInitReqParams, + sizeof(halFWLoggingInitReq.tFWLoggingInitReqParams)); + + /*------------------------------------------------------------------------- + Send Mgmt Logging Init Request to HAL + ------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiFWLoggingInitRspCb, pEventData->pUserData, + WDI_FW_LOGGING_INIT_RSP); + + return wdiStatus; +} + +/** + @brief Process FwrMemDumpReq Request + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status + WDI_ProcessFwrMemDumpReq + +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_FwrMemDumpReqType * wdiFwrMemDumpReq; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_Status wdiStatus; + tHalFwMemoryDumpReqMsg halFwrMemDumpReq; + WDI_FwrMemDumpRspCb wdiFwrMemDumpRspCb; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiFwrMemDumpReq = (WDI_FwrMemDumpReqType *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_FWR_MEM_DUMP_REQ, + sizeof(halFwrMemDumpReq.tFwMemoryDumpReqParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + (usSendSize < (usDataOffset + + sizeof(halFwrMemDumpReq.tFwMemoryDumpReqParam)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Process Fwr Mem Dump Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiFwrMemDumpRspCb = (WDI_FwrMemDumpRspCb)pEventData->pCBfnc; + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halFwrMemDumpReq.tFwMemoryDumpReqParam, + sizeof(halFwrMemDumpReq.tFwMemoryDumpReqParam)); + + /*------------------------------------------------------------------------- + Send Fwr Mem Dump Request to HAL + ------------------------------------------------------------------------*/ + wdiStatus = WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiFwrMemDumpRspCb, pEventData->pUserData, + WDI_FWR_MEM_DUMP_RSP); + return wdiStatus; +} + +/** + @brief WDI_EncryptMsgReq + + @param pwdiEncryptMsgParams: Req parameter for the FW + wdiEncryptMsgCbRsp: callback for passing back the response + of the Req operation received from the device + pUserData: user data will be passed back with the callback + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_EncryptMsgReq(void* pwdiEncryptMsgParams, + WDI_EncryptMsgRspCb wdiEncryptMsgCbRsp, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter" ,__func__, __LINE__); + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_ENCRYPT_MSG_REQ; + wdiEventData.pEventData = pwdiEncryptMsgParams; + wdiEventData.uEventDataSize = sizeof(wpt_pkt80211); + wdiEventData.pCBfnc = wdiEncryptMsgCbRsp; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/* + * FUNCTION: WDI_ProcessEncryptMsgReq + * Request to WDI to encrypt the given message. + * + * @param pWDICtx: pointer to the WLAN DAL context + * pEventData: pointer to the event information structure + * + * @return Result of the function call + */ + +WDI_Status +WDI_ProcessEncryptMsgReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + WDI_EncryptMsgRspCb* wdiEncMsgCb; + tSetEncryptedDataParams *pHalEncryptDataReq; + wpt_pkt80211 *pkt = NULL; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pEventData->pCBfnc ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiEncMsgCb = (WDI_EncryptMsgRspCb*)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, WDI_ENCRYPT_MSG_REQ, + sizeof(tSetEncryptedDataReqMsg), + &pSendBuffer, &usDataOffset, &usSendSize)) || + ( usSendSize < (usDataOffset + sizeof(tSetEncryptedDataReqMsg)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in get WDI_ENCRYPT_MSG_REQ %p", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pWDICtx->wdiReqStatusCB = NULL; + pWDICtx->pReqStatusUserData = pEventData->pUserData; + pkt = (wpt_pkt80211 *)pEventData->pEventData; + + pHalEncryptDataReq = &((tSetEncryptedDataReqMsg *)(pSendBuffer))->encryptedDataParams; + wpalMemoryZero(pHalEncryptDataReq, sizeof(tSetEncryptedDataParams)); + + wpalMemoryCopy(&pHalEncryptDataReq->macHeader, &pkt->macHeader, 32); + + pHalEncryptDataReq->encParams.keyParams.key[0].keyId = + pkt->encParams.keyParams.key[0].keyId; + + wpalMemoryCopy(&pHalEncryptDataReq->encParams.keyParams.key[0].key[0], + &pkt->encParams.keyParams.key[0].key[0], 16); + + wpalMemoryCopy(&pHalEncryptDataReq->encParams.pn, &pkt->encParams.pn, 6); + + pHalEncryptDataReq->data.length = pkt->data.length; + wpalMemoryCopy(&pHalEncryptDataReq->data.data[0], &pkt->data.data[0], pkt->data.length); + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, wdiEncMsgCb, + pEventData->pUserData, WDI_ENCRYPT_MSG_RSP); +} + +/* + * FUNCTION: WDI_ProcessEncryptMsgRsp + * Receives the encrypted message from the firmware + * @param pWDICtx: pointer to the WLAN DAL context + * pEventData: pointer to the event information structure + * + * @return Result of the function call + */ +WDI_Status +WDI_ProcessEncryptMsgRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + tpSetEncryptedDataRspParams pSetEncryptedDataRsp; + WDI_EncryptMsgRspCb wdiEncryptMsgRspCb; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "In %s",__func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pSetEncryptedDataRsp = (tpSetEncryptedDataRspParams)pEventData->pEventData; + + wdiEncryptMsgRspCb = (WDI_EncryptMsgRspCb)pWDICtx->pfncRspCB; + + wdiEncryptMsgRspCb(WDI_STATUS_SUCCESS, + pEventData->pEventData, + pWDICtx->pRspCBUserData); + return WDI_STATUS_SUCCESS; +} + +WDI_Status +WDI_NanRequest +( + WDI_NanRequestType *pwdiNanRequest, + void *usrData +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI_NanRequest %zu %d", sizeof(*pwdiNanRequest), + pwdiNanRequest->request_data_len); + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_NAN_REQUEST; + wdiEventData.pEventData = pwdiNanRequest; + wdiEventData.uEventDataSize = sizeof(*pwdiNanRequest) + + pwdiNanRequest->request_data_len; + wdiEventData.pUserData = usrData; + wdiEventData.pCBfnc = NULL; + + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +WDI_Status +WDI_ProcessNanRequest +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_NanRequestType *pwdiNanRequest = NULL; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WDI_ProcessNanRequest"); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || + ( NULL == (pwdiNanRequest = (WDI_NanRequestType*)pEventData->pEventData))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __FUNCTION__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS + != WDI_GetMessageBuffer( pWDICtx, + WDI_NAN_REQUEST, + pwdiNanRequest->request_data_len, + &pSendBuffer, + &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + pwdiNanRequest->request_data_len))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in NAN request %p %p", + pEventData, pwdiNanRequest); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryCopy( pSendBuffer+usDataOffset, + pwdiNanRequest->request_data, + pwdiNanRequest->request_data_len); + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + vos_mem_free( pEventData->pUserData); + + /*------------------------------------------------------------------------- + Send NAN Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, + pSendBuffer, + usSendSize, + NULL, + NULL, + WDI_NAN_RESPONSE); +} + +/** + @brief Process NAN Response function (called when a + response is being received over the bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNanResponse +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_Status wdiStatus; + eHalStatus halStatus; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halStatus = *((eHalStatus*)pEventData->pEventData); + wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s : Received NAN response, status : %d", __FUNCTION__, wdiStatus); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessNanResponse*/ + + +/** + @brief Process NAN Event function (called when + an indication is being received over the + bus from HAL) + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessNanEvent +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT( 0 ); + return WDI_STATUS_E_FAILURE; + } + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Received NAN event", __func__); + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wdiInd.wdiIndicationType = WDI_NAN_EVENT_IND; + wdiInd.wdiIndicationData.wdiNanEvent.event_data_len = + pEventData->uEventDataSize; + wdiInd.wdiIndicationData.wdiNanEvent.event_data = + pEventData->pEventData; + + /*Notify UMAC*/ + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + + return WDI_STATUS_SUCCESS; +}/*WDI_ProcessNanEvent*/ + + +WDI_Status +WDI_Process_RssiBreachedInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalRssiMonitorIndParams *halRssiBreachedInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + halRssiBreachedInd = pEventData->pEventData; + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_RSSI_BREACHED_IND; + wdiInd.wdiIndicationData.wdiRssiBreachedInd.request_id = + halRssiBreachedInd->request_id; + wpalMemoryCopy(wdiInd.wdiIndicationData.wdiRssiBreachedInd.bssId, + halRssiBreachedInd->bssId, + WDI_MAC_ADDR_LEN); + wdiInd.wdiIndicationData.wdiRssiBreachedInd.rssi = + halRssiBreachedInd->rssi; + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: session_id %d, rssi : %d, bssId: " MAC_ADDRESS_STR" ", __func__, + wdiInd.wdiIndicationData.wdiRssiBreachedInd.request_id, + wdiInd.wdiIndicationData.wdiRssiBreachedInd.rssi, + MAC_ADDR_ARRAY(wdiInd.wdiIndicationData.wdiRssiBreachedInd.bssId)); + /*Notify UMAC*/ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData); + } + + return WDI_STATUS_SUCCESS; + +} + + +WDI_Status +WDI_Process_LostLinkParamInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + tHalLostLinkParametersIndParams halLostLinkParamInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*------------------------------------------------------------------------- + Extract indication and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy( (void *)&halLostLinkParamInd, + pEventData->pEventData, + sizeof(tHalLostLinkParametersIndParams)); + + + /*Fill in the indication parameters*/ + wdiInd.wdiIndicationType = WDI_LOST_LINK_PARAMS_IND; + wpalMemoryCopy((void *)&wdiInd.wdiIndicationData.wdiLostLinkParamsInd, + (void *)&halLostLinkParamInd, + sizeof(WDI_LostLinkParamsIndType)); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: bssIdx %d, rssi : %d, selfMacAddr: " MAC_ADDRESS_STR", linkFlCnt: %d," + "linkFlTx : %d,lastDataRate : %d", __func__, + wdiInd.wdiIndicationData.wdiLostLinkParamsInd.bssIdx, + wdiInd.wdiIndicationData.wdiLostLinkParamsInd.rssi, + MAC_ADDR_ARRAY(wdiInd.wdiIndicationData.wdiLostLinkParamsInd.selfMacAddr), + wdiInd.wdiIndicationData.wdiLostLinkParamsInd.linkFlCnt, + wdiInd.wdiIndicationData.wdiLostLinkParamsInd.linkFlTx, + wdiInd.wdiIndicationData.wdiLostLinkParamsInd.lastDataRate); + /*Notify UMAC*/ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB(&wdiInd, pWDICtx->pIndUserData); + } + + return WDI_STATUS_SUCCESS; + +} + +WDI_Status +WDI_ProcessSetRtsCtsHtvhtInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint32 *rtsCtsVal; + tHalRtsCtsHtvhtIndParams *rtsCtsHtvhtIndParams; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + rtsCtsVal = (wpt_uint32*)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_SET_RTS_CTS_HTVHT_IND, + sizeof(tHalRtsCtsHtvhtIndParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalRtsCtsHtvhtIndParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in RTS CTS ind %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + rtsCtsHtvhtIndParams = + (tHalRtsCtsHtvhtIndParams*)(pSendBuffer + usDataOffset); + rtsCtsHtvhtIndParams->rtsCtsValue = *rtsCtsVal; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send SET_RTS_CTS_HTVHT Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + +WDI_Status +WDI_SetRtsCtsHTVhtInd +( + wpt_uint32 rtsCtsVal +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SET_RTS_CTS_HTVHT_IND; + wdiEventData.pEventData = (void *) &rtsCtsVal; + wdiEventData.uEventDataSize = sizeof(wpt_uint32); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/* WDI_SetRtsCtsHTVhtInd */ + +WDI_Status +WDI_ProcessEnableDisableCAEventInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + wpt_uint32 *val; + tHalAvoidFreqRangeCtrlParam *avoidFreqRangeCtrlParam; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + val = (wpt_uint32*)pEventData->pEventData; + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_SEND_FREQ_RANGE_CONTROL_IND, + sizeof(tHalAvoidFreqRangeCtrlParam), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalAvoidFreqRangeCtrlParam) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Channel Avoidance Ind %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + avoidFreqRangeCtrlParam = + (tHalAvoidFreqRangeCtrlParam*)(pSendBuffer + usDataOffset); + avoidFreqRangeCtrlParam->status = *val; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send AVOID_FREQ_RANGE_CONTROL_IND Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + +WDI_Status +WDI_EnableDisableCAEventInd +( + wpt_uint32 val +) +{ + WDI_EventInfoType wdiEventData; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_SEND_FREQ_RANGE_CONTROL_IND; + wdiEventData.pEventData = (void *) &val; + wdiEventData.uEventDataSize = sizeof(wpt_uint32); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} /* WDI_EnableDisableCAEventInd */ + +/** + @brief WDI_WifiConfigSetReq + This API is called to set WifiConfig params request in FW + + @param pwdiWifiConfigSetReqParams : pointer to set WifiCofig request params + wdiWifiConfigSetRspCb : WifiConfig stats resp callback + usrData : Client context + @see + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_WifiConfigSetReq(WDI_WifiConfigSetReqType* pwdiWifConfigSetReqParams, + WDI_WifiConfigSetRspCb wdiWifiConfigSetRspCb, + void* pUserData) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_WIFI_CONFIG_SET_REQ; + wdiEventData.pEventData = pwdiWifConfigSetReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiWifConfigSetReqParams); + wdiEventData.pCBfnc = wdiWifiConfigSetRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessWifiConfigReq - + Set WifiConfig request to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ + WDI_Status + WDI_ProcessWifiConfigReq + ( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ) + { + WDI_WifiConfigSetReqType* pwdiWifiConfigSetReqParams; + WDI_WifiConfigSetRspCb wdiWifiConfigSetRspCb; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tSetWifiConfigParamsReq halWifiConfigSetParams; + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiWifiConfigSetReqParams = (WDI_WifiConfigSetReqType*)pEventData->pEventData; + wdiWifiConfigSetRspCb = (WDI_WifiConfigSetRspCb)pEventData->pCBfnc; + + /*----------------------------------------------------------------------- + Get message buffer + ! TO DO : proper conversion into the HAL Message Request Format + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_WIFI_CONFIG_SET_REQ, + sizeof(halWifiConfigSetParams.wifiConfigParams), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(halWifiConfigSetParams.wifiConfigParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p %p", __func__, + pEventData, pwdiWifiConfigSetReqParams, wdiWifiConfigSetRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + halWifiConfigSetParams.wifiConfigParams.paramType = pwdiWifiConfigSetReqParams->paramType; + halWifiConfigSetParams.wifiConfigParams.paramValue = + pwdiWifiConfigSetReqParams->paramValue; + vos_mem_copy(halWifiConfigSetParams.wifiConfigParams.bssid, &(pwdiWifiConfigSetReqParams->bssId), + sizeof(tSirMacAddr)); + + wpalMemoryCopy(pSendBuffer+usDataOffset, + &halWifiConfigSetParams.wifiConfigParams, + sizeof(halWifiConfigSetParams.wifiConfigParams)); + + pWDICtx->pReqStatusUserData = pEventData->pUserData; + + /*------------------------------------------------------------------------- + Send Clear Link Layer Stats Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiWifiConfigSetRspCb, pEventData->pUserData, + WDI_WIFI_CONFIG_SET_RSP); + } + +WDI_Status +WDI_ProcessWificonfigSetRsp +( WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData ) + +{ + tHalSetWifiConfigRspParams halRsp; + WDI_WifiConfigSetRspCb wdiWifiConfigSetRspCb; + WDI_WifconfigSetRsp wdiWifconfigSetRsp; + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiWifiConfigSetRspCb = (WDI_WifiConfigSetRspCb)pWDICtx->pfncRspCB; + + /*------------------------------------------------------------------------- + Extract response and send it to UMAC + -------------------------------------------------------------------------*/ + wpalMemoryCopy(&halRsp, pEventData->pEventData, sizeof(halRsp)); + + wdiWifconfigSetRsp.wificonfigset_status = WDI_HAL_2_WDI_STATUS(halRsp.status); + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "WifiConfig RSP status = %d", + wdiWifconfigSetRsp.wificonfigset_status); + /*Notify UMAC*/ + wdiWifiConfigSetRspCb( &wdiWifconfigSetRsp, pWDICtx->pRspCBUserData); + + return WDI_STATUS_SUCCESS; +} + +#ifdef FEATURE_OEM_DATA_SUPPORT + +/** + @brief WDI_StartOemDataReqIndNew + + @param pOemDataReqNewConfig: Req parameter for the FW + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_StartOemDataReqIndNew +( + WDI_OemDataReqNewConfig *pOemDataReqNewConfig +) +{ + WDI_EventInfoType wdiEventData; + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_START_OEM_DATA_REQ_IND_NEW; + wdiEventData.pEventData = pOemDataReqNewConfig; + wdiEventData.uEventDataSize = sizeof(*pOemDataReqNewConfig); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief WDI_ProcessStartOemDataReqIndNew - + Send OEM Data request new indication to FW + + @param pWDICtx : wdi context + pEventData : indication data + + @see + @return none +*/ +WDI_Status +WDI_ProcessStartOemDataReqIndNew +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_OemDataReqNewConfig* wdiOemDataReqNewConfig; + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usSendSize = 0; + wpt_uint16 usDataOffset = 0; + tpStartOemDataReqParamsNew pHalStartOemDataReqParamsNew; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdiOemDataReqNewConfig = + (WDI_OemDataReqNewConfig *)pEventData->pEventData; + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( + pWDICtx, + WDI_START_OEM_DATA_REQ_IND_NEW, + sizeof(*pHalStartOemDataReqParamsNew), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(*pHalStartOemDataReqParamsNew) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in %s %p %p", __func__, + pEventData, wdiOemDataReqNewConfig); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pHalStartOemDataReqParamsNew = + (tpStartOemDataReqParamsNew) (pSendBuffer + usDataOffset); + + wpalMemoryCopy(pHalStartOemDataReqParamsNew, + wdiOemDataReqNewConfig, + sizeof(*pHalStartOemDataReqParamsNew)); + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: selfMacAddr: " MAC_ADDRESS_STR" ", __func__, + MAC_ADDR_ARRAY(pHalStartOemDataReqParamsNew->selfMacAddr)); + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + /*------------------------------------------------------------------------- + Send WDI_START_OEM_DATA_REQ_IND_NEW Request to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; +} + +/** + @brief Process OemDataRsp New Indication indication from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessStartOemDataRspIndNew +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_LowLevelIndType wdiInd; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: ", __func__); + + /* sanity check */ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Fill in the indication parameters */ + wdiInd.wdiIndicationType = WDI_START_OEM_DATA_RSP_IND_NEW; + + wdiInd.wdiIndicationData.wdiOemDataRspNew.pOemRspNewIndData = + (void *)pEventData->pEventData; + wdiInd.wdiIndicationData.wdiOemDataRspNew.OemRspNewLen = + pEventData->uEventDataSize; + /* Notify UMAC */ + if (pWDICtx->wdiLowLevelIndCB) + { + pWDICtx->wdiLowLevelIndCB( &wdiInd, pWDICtx->pIndUserData ); + } + else + { + VOS_TRACE( VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: WDILowLevelIndCb is null", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + return WDI_STATUS_SUCCESS; +} /* End of WDI_ProcessEXTScanResultInd */ + +/** + @brief Process Current Antenna Index information from FW + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetCurrentAntennaIndexRsp +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_AntennaDivSelRspCb wdiGetCurrentAntennaIndexRspCb; + tHalAntennaDiversitySelectionRspParams *pHalAntDivSelRsp; + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pWDICtx ) || ( NULL == pEventData ) || + ( NULL == pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pHalAntDivSelRsp = + (tHalAntennaDiversitySelectionRspParams*)pEventData->pEventData; + wdiGetCurrentAntennaIndexRspCb = (WDI_AntennaDivSelRspCb)pWDICtx->pfncRspCB; + + if (pHalAntDivSelRsp->status != 0) + { + wdiGetCurrentAntennaIndexRspCb(WDI_STATUS_E_FAILURE, + (void *)pHalAntDivSelRsp, pWDICtx->pRspCBUserData); + } + else + { + wdiGetCurrentAntennaIndexRspCb(WDI_STATUS_SUCCESS, + (void *)pHalAntDivSelRsp, + pWDICtx->pRspCBUserData); + } + + return WDI_STATUS_SUCCESS; +} + +/** + @brief Process Get Current Antenna Index request command + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessGetCurrentAntennaIndex +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalAntennaDiversitySelectionReqParams halAntDivSelReq; + WDI_AntennaDivSelRspCb wdiGetCurrentAntennaIndexRspCb; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ) || + ( NULL == pEventData->pCBfnc )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + wdiGetCurrentAntennaIndexRspCb = (WDI_AntennaDivSelRspCb)pEventData->pCBfnc; + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_ANTENNA_DIVERSITY_SELECTION_REQ, + sizeof(tHalAntennaDiversitySelectionReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(tHalAntennaDiversitySelectionReqParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetCurrentAntennaIndex %p", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pWDICtx->wdiReqStatusCB = NULL; + pWDICtx->pReqStatusUserData = pEventData->pEventData; + halAntDivSelReq.reserved = *((wpt_uint32 *)(pEventData->pEventData)); + wpalMemoryCopy( pSendBuffer+usDataOffset, + &halAntDivSelReq, + sizeof(tHalAntennaDiversitySelectionReqParams)); + + /*------------------------------------------------------------------------- + Send Get STA Request to HAL + -------------------------------------------------------------------------*/ + return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize, + wdiGetCurrentAntennaIndexRspCb, + pEventData->pUserData, + WDI_ANTENNA_DIVERSITY_SELECTION_RSP); +} + +/** + @brief WDI_GetCurrentAntennaIndex + + @param pOemDataReqNewConfig: Req parameter for the FW + + @return SUCCESS or FAIL +*/ +WDI_Status +WDI_GetCurrentAntennaIndex +( + void *pUserData, + WDI_AntennaDivSelRspCb wdiAntennaDivSelRspCb, + wpt_uint32 reserved +) +{ + WDI_EventInfoType wdiEventData; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_ANTENNA_DIVERSITY_SELECTION_REQ; + wdiEventData.pEventData = (void *)&reserved; + wdiEventData.uEventDataSize = sizeof(wpt_uint32); + wdiEventData.pCBfnc = wdiAntennaDivSelRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + @brief Process Set beacon miss penalty count command + + @param pWDICtx: pointer to the WLAN DAL context + pEventData: pointer to the event information structure + + @see + @return Result of the function call +*/ +WDI_Status +WDI_ProcessBcnMissPenaltyCount +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tHalModifyRoamParamsIndParams halModifyRoamParams; + WDI_ModifyRoamParamsReqType *modifyRoamParams; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_MODIFY_ROAM_PARAMS_IND, + sizeof(tHalModifyRoamParamsIndParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tHalModifyRoamParamsIndParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer for Modify roam req params %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + modifyRoamParams = (WDI_ModifyRoamParamsReqType *)pEventData->pEventData; + halModifyRoamParams.param = modifyRoamParams->param; + halModifyRoamParams.value = modifyRoamParams->value; + wpalMemoryCopy( pSendBuffer+usDataOffset, &halModifyRoamParams, + sizeof(halModifyRoamParams)); + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + /*------------------------------------------------------------------------- + Send WDI_MODIFY_ROAM_PARAMS_IND to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; + +} + +/** + @brief WDI_SetBcnMissPenaltyCount + + @param params: Req parameter for the FW + + @return SUCCESS or FAIL +*/ + +WDI_Status +WDI_SetBcnMissPenaltyCount +( + WDI_ModifyRoamParamsReqType *params +) +{ + WDI_EventInfoType wdiEventData; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*------------------------------------------------------------------------ + Sanity Check + ------------------------------------------------------------------------*/ + if ( eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + /*------------------------------------------------------------------------ + Fill in Event data and post to the Main FSM + ------------------------------------------------------------------------*/ + wdiEventData.wdiRequest = WDI_MODIFY_ROAM_PARAMS_IND; + wdiEventData.pEventData = (void *)params; + wdiEventData.uEventDataSize = sizeof(*params); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} /* WDI_SetBcnMissPenaltyCount */ + +#endif + +#ifdef WLAN_FEATURE_APFIND +WDI_Status WDI_ProcessApFindInd(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + struct WDI_APFind_cmd *pwdiapFindRequestInd; + tQRFPrefNetwListParams *phalAPFindRequestParam; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_uint16 buffer_len = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + ------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiapFindRequestInd = (struct WDI_APFind_cmd *)pEventData->pEventData; + if (pwdiapFindRequestInd->data_len) + buffer_len = sizeof(tQRFPrefNetwListParams); + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_SET_AP_FIND_IND, + buffer_len, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tQRFPrefNetwListParams) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in QRF command %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + phalAPFindRequestParam = + (tQRFPrefNetwListParams *)(pSendBuffer + usDataOffset); + + wpalMemoryCopy(phalAPFindRequestParam, + &pwdiapFindRequestInd->data[0], + pwdiapFindRequestInd->data_len); + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send WDI_SET_AP_FIND_IND Indication to HAL + -------------------------------------------------------------------------*/ + + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + + return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC; + +} + +WDI_Status WDI_process_ap_find_cmd(struct WDI_APFind_cmd *params) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail req"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_SET_AP_FIND_IND; + wdiEventData.pEventData = params; + wdiEventData.uEventDataSize = sizeof(*params); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +} +#endif + +/** + * WDI_ProcessSetAllowedActionFramesInd() - Process Allowed action frames + * Indication message and post it to HAL + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + * Return: WDI_Status enumeration + */ +WDI_Status WDI_ProcessSetAllowedActionFramesInd(WDI_ControlBlockType *pWDICtx, + WDI_EventInfoType *pEventData) +{ + wpt_uint8 *pSendBuffer; + wpt_uint16 usDataOffset; + wpt_uint16 usSendSize; + wpt_uint16 usLen; + struct WDI_AllowedActionFramesInd* pwdiAllowedActionFramesInd; + tHalAllowedActionFrames* pAllowedActionFrames; + WDI_Status wdiStatus; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + if ((!pEventData) || (!pEventData->pEventData)) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_SET_ALLOWED_ACTION_FRAMES_IND, + sizeof(tHalAllowedActionFrames), + &pSendBuffer, &usDataOffset, + &usSendSize))|| + (usSendSize < (usDataOffset + usLen))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in Allowed Action Frames req %p", + pEventData); + return WDI_STATUS_E_FAILURE; + } + + pwdiAllowedActionFramesInd = + (struct WDI_AllowedActionFramesInd*)pEventData->pEventData; + pAllowedActionFrames = + (tHalAllowedActionFrames*)(pSendBuffer+usDataOffset); + pAllowedActionFrames->actionFramesBitMask = + pwdiAllowedActionFramesInd->bitmask; + pAllowedActionFrames->reserved = pwdiAllowedActionFramesInd->reserved; + + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + + wdiStatus = WDI_SendIndication(pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? + wdiStatus:WDI_STATUS_SUCCESS_SYNC; +}/*WDI_ProcessSetAllowedActionFramesInd*/ + +/** + * WDI_SetAllowedActionFramesInd() - Post Allowed Action Frames Indication to + * WDI Main Event Handler + * @params: pointer to the WDI_AllowedActionFramesInd structure + * + * Return: WDI_Status enumeration + */ +WDI_Status WDI_SetAllowedActionFramesInd( + struct WDI_AllowedActionFramesInd *params) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail req"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_SET_ALLOWED_ACTION_FRAMES_IND; + wdiEventData.pEventData = params; + wdiEventData.uEventDataSize = sizeof(*params); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + * WDI_ProcessSetArpStatsReq() - WDI api to process arp stats request + * @pWDICtx: wdi context + * @pEventData: event data + * + * Return: WDI_Status + */ +WDI_Status +WDI_ProcessSetArpStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_SetARPStatsParamsInfoType *pSetARPStatsReqParams; + WDI_SetARPStatsRspCb wdiSetARPStatsRspCb; + wpt_uint8* pSendBuffer; + wpt_uint16 usDataOffset; + wpt_uint16 usSendSize; + WDI_Status wdi_status; + tHalStatsArpReqMsg statsReqParams; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pWDICtx ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pSetARPStatsReqParams = + (WDI_SetARPStatsParamsInfoType *)pEventData->pEventData; + wdiSetARPStatsRspCb = (WDI_SetARPStatsRspCb)pEventData->pCBfnc; + + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, WDI_FW_ARP_STATS_REQ, + sizeof(statsReqParams.statsArpReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(statsReqParams.statsArpReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pSetARPStatsReqParams, wdiSetARPStatsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + statsReqParams.statsArpReqParams.set_clr = pSetARPStatsReqParams->flag; + statsReqParams.statsArpReqParams.pkt_type = + pSetARPStatsReqParams->pkt_type; + statsReqParams.statsArpReqParams.ip_addr = pSetARPStatsReqParams->ip_addr; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &statsReqParams.statsArpReqParams, + sizeof(statsReqParams.statsArpReqParams)); + + wdi_status = WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize, + wdiSetARPStatsRspCb, pEventData->pUserData, + WDI_FW_ARP_STATS_RSP); + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} + +/** + * WDI_SetARPStatsReq() - WDI api to process set arp stats request + * @pwdiSetStatsReqParams: pointer to set stats params + * @wdiSetStatsRspCb: pointer to set response callback + * @pUserData: user data + * + * Return: WDI_Status + */ +WDI_Status +WDI_SetARPStatsReq +( + WDI_SetARPStatsParamsInfoType* pwdiSetStatsReqParams, + WDI_SetARPStatsRspCb wdiSetStatsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_FW_ARP_STATS_REQ; + wdiEventData.pEventData = pwdiSetStatsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiSetStatsReqParams); + wdiEventData.pCBfnc = wdiSetStatsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_GetARPStatsReq*/ + +/** + * WDI_ProcessGetArpStatsReq() - WDI api to process get arp stats request + * @pWDICtx: wdi context + * @pEventData: event data + * + * Return: WDI_Status + */ +WDI_Status +WDI_ProcessGetArpStatsReq +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData +) +{ + WDI_GetARPStatsParamsInfoType *pGetARPStatsReqParams; + WDI_GetARPStatsRspCb wdiGetARPStatsRspCb; + wpt_uint8* pSendBuffer; + wpt_uint16 usDataOffset; + wpt_uint16 usSendSize; + WDI_Status wdi_status; + tHalStatsGetArpReqMsg statsReqParams; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Enter",__func__, __LINE__); + + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData) || + ( NULL == pWDICtx ) ) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + pGetARPStatsReqParams = + (WDI_GetARPStatsParamsInfoType *)pEventData->pEventData; + wdiGetARPStatsRspCb = (WDI_GetARPStatsRspCb)pEventData->pCBfnc; + + if ((WDI_STATUS_SUCCESS != WDI_GetMessageBuffer(pWDICtx, + WDI_FW_GET_ARP_STATS_REQ, + sizeof(statsReqParams.statsGetArpReqParams), + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + + sizeof(statsReqParams.statsGetArpReqParams)))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Unable to get send buffer in set bss key req %p %p %p", + pEventData, pGetARPStatsReqParams, wdiGetARPStatsRspCb); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + statsReqParams.statsGetArpReqParams.pkt_type = + pGetARPStatsReqParams->pkt_type; + + wpalMemoryCopy( pSendBuffer+usDataOffset, + &statsReqParams.statsGetArpReqParams, + sizeof(statsReqParams.statsGetArpReqParams)); + + wdi_status = WDI_SendMsg(pWDICtx, pSendBuffer, usSendSize, + wdiGetARPStatsRspCb, pEventData->pUserData, + WDI_FW_GET_ARP_STATS_RSP); + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: %d Exit",__func__, __LINE__); + return wdi_status; +} + +/** + * WDI_GetARPStatsReq() - WDI api to process get arp stats request + * @pwdiGetStatsReqParams: pointer to get stats params + * @wdiGetStatsRspCb: pointer to get response callback + * @pUserData: user data + * + * Return: WDI_Status + */ +WDI_Status +WDI_GetARPStatsReq +( + WDI_GetARPStatsParamsInfoType* pwdiGetStatsReqParams, + WDI_GetARPStatsRspCb wdiGetStatsRspCb, + void* pUserData +) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized ) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail request"); + + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_FW_GET_ARP_STATS_REQ; + wdiEventData.pEventData = pwdiGetStatsReqParams; + wdiEventData.uEventDataSize = sizeof(*pwdiGetStatsReqParams); + wdiEventData.pCBfnc = wdiGetStatsRspCb; + wdiEventData.pUserData = pUserData; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); + +}/*WDI_GetARPStatsReq*/ + + +#ifdef SAP_AUTH_OFFLOAD +/** + * WDI_ProcessSapAuthOffloadInd() - Process SAP AUTH ofload + * Indication message and post it to HAL + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + * Return: WDI_Status enumeration + */ +WDI_Status +WDI_ProcessSapAuthOffloadInd +( + WDI_ControlBlockType* pWDICtx, + WDI_EventInfoType* pEventData + ) +{ + wpt_uint8* pSendBuffer = NULL; + wpt_uint16 usDataOffset = 0; + wpt_uint16 usSendSize = 0; + tSapOffloadEnableMsg *sapOffloadEnableIndParam; + struct WDI_sap_ofl_enable_params *pwdiSapOflEnableParams; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + int buffer_len = 0; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s", __func__); + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (( NULL == pEventData ) || ( NULL == pEventData->pEventData )) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + /*----------------------------------------------------------------------- + Get message buffer + -----------------------------------------------------------------------*/ + pwdiSapOflEnableParams = + (struct WDI_sap_ofl_enable_params*)pEventData->pEventData; + + if (pwdiSapOflEnableParams->psk_len) + buffer_len = pwdiSapOflEnableParams->psk_len + + sizeof(tSapOffloadEnableMsg) - sizeof(tANI_U8); + else + buffer_len = sizeof(tSapOffloadEnableMsg); + + if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx, + WDI_PROCESS_SAP_AUTH_OFFLOAD_IND, + buffer_len, + &pSendBuffer, &usDataOffset, &usSendSize))|| + ( usSendSize < (usDataOffset + sizeof(tSapOffloadEnableMsg) ))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in SAP Auth offload Ind %p ", + pEventData); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + pwdiSapOflEnableParams = + (struct WDI_sap_ofl_enable_params*)pEventData->pEventData; + sapOffloadEnableIndParam = + (tSapOffloadEnableMsg*)(pSendBuffer + usDataOffset); + wpalMemoryCopy(&sapOffloadEnableIndParam->selfMacAddr, + &pwdiSapOflEnableParams->macAddr, sizeof(wpt_macAddr)); + + sapOffloadEnableIndParam->enable = pwdiSapOflEnableParams->enable; + sapOffloadEnableIndParam->rsn_authmode = + pwdiSapOflEnableParams->rsn_authmode; + sapOffloadEnableIndParam->rsn_ucastcipherset = + pwdiSapOflEnableParams->rsn_ucastcipherset; + sapOffloadEnableIndParam->rsn_mcastcipherset = + pwdiSapOflEnableParams->rsn_mcastcipherset; + sapOffloadEnableIndParam->psk_len = pwdiSapOflEnableParams->psk_len; + wpalMemoryCopy(&sapOffloadEnableIndParam->psk, &pwdiSapOflEnableParams->key, + pwdiSapOflEnableParams->psk_len); + pWDICtx->pReqStatusUserData = NULL; + pWDICtx->pfncRspCB = NULL; + /*------------------------------------------------------------------------- + Send SAP_AUTH_OFFLOAD_IND Indication to HAL + -------------------------------------------------------------------------*/ + wdiStatus = WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize); + return (wdiStatus != WDI_STATUS_SUCCESS) ? + wdiStatus:WDI_STATUS_SUCCESS_SYNC; + +} + +/** + * WDI_process_sap_auth_offload() - Process SAP AUTH offload + * Indication message and post it to HAL + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + * Return: WDI_Status enumeration + */ +WDI_Status WDI_process_sap_auth_offload( + struct WDI_sap_ofl_enable_params *params) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail req"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_PROCESS_SAP_AUTH_OFFLOAD_IND; + wdiEventData.pEventData = params; + wdiEventData.uEventDataSize = sizeof(*params); + wdiEventData.pCBfnc = NULL; + wdiEventData.pUserData = NULL; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + * wdi_process_cap_tsf_req() - Send Capture tsf request to FW. + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + * Return: WDI_Status enumeration + */ +WDI_Status wdi_process_cap_tsf_req(wdi_cap_tsf_params_t *wdi_cap_tsf_req, + wdi_tsf_rsp_cb wdi_cap_tsf_rsp_callback, + void *user_data) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail req"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_CAP_TSF_REQ; + wdiEventData.pEventData = wdi_cap_tsf_req; + wdiEventData.uEventDataSize = sizeof(*wdi_cap_tsf_req); + wdiEventData.pCBfnc = wdi_cap_tsf_rsp_callback; + wdiEventData.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} +/** + * wdi_process_get_tsf_req() - Send Get tsf request to FW. + * + * @pWDICtx: pointer to the WLAN DAL context + * @pEventData: pointer to the event information structure + * + * Return: WDI_Status enumeration + */ +WDI_Status wdi_process_get_tsf_req(wdi_cap_tsf_params_t *wdi_get_tsf_req, + wdi_tsf_rsp_cb wdi_tsf_rsp_callback, + void *user_data) +{ + WDI_EventInfoType wdiEventData; + + if (eWLAN_PAL_FALSE == gWDIInitialized) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WDI API call before module is initialized - Fail req"); + return WDI_STATUS_E_NOT_ALLOWED; + } + + wdiEventData.wdiRequest = WDI_GET_TSF_REQ; + wdiEventData.pEventData = wdi_get_tsf_req; + wdiEventData.uEventDataSize = sizeof(*wdi_get_tsf_req); + wdiEventData.pCBfnc = wdi_tsf_rsp_callback; + wdiEventData.pUserData = user_data; + + return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData); +} + +/** + * wdi_cap_tsf_req() - wdi api for capture tsf request + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status wdi_cap_tsf_req (WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data) +{ + + wdi_cap_tsf_params_t *wdi_cap_tsf_req_info; + wpt_uint8 *buff = NULL; + wpt_uint16 data_offset = 0; + wpt_uint16 size = 0; + WDI_Status wdi_status; + tHalCapTSFgetReqInd hal_cap_tsf_req; + wdi_tsf_rsp_cb wdi_tsf_rsp_callback; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: Enter",__func__ ); + /* Sanity check */ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) { + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_cap_tsf_req_info = (wdi_cap_tsf_params_t *) + event_data->pEventData; + + /* Get message buffer */ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_CAP_TSF_REQ, + sizeof(hal_cap_tsf_req. + capTSFget), + &buff, &data_offset, &size))|| + (size < (data_offset + + sizeof(hal_cap_tsf_req.capTSFget)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetTsfFrame Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + hal_cap_tsf_req.capTSFget.uBssIdx = wdi_cap_tsf_req_info->bss_idx; + hal_cap_tsf_req.capTSFget.capTSFget = wdi_cap_tsf_req_info->capTSFget; + + wdi_tsf_rsp_callback = (wdi_tsf_rsp_cb)event_data->pCBfnc; + + wpalMemoryCopy(buff+data_offset, + &hal_cap_tsf_req.capTSFget, + sizeof(hal_cap_tsf_req.capTSFget)); + + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_tsf_rsp_callback, + event_data->pUserData, + WDI_CAPTURE_GET_TSF_TSTAMP_RSP); + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: Exit",__func__); + + return wdi_status; +} + +/** + * wdi_get_tsf_req() - wdi api for get tsf request + * @wdi_ctx: pointer to wdi context + * @event_data: pointer to event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status wdi_get_tsf_req (WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data) +{ + + wdi_cap_tsf_params_t *wdi_cap_tsf_req_info; + wpt_uint8 *buff = NULL; + wpt_uint16 data_offset = 0; + wpt_uint16 size = 0; + WDI_Status wdi_status; + tHalCapTSFgetReqInd hal_cap_tsf_req; + wdi_tsf_rsp_cb wdi_tsf_rsp_callback; + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: Enter",__func__ ); + /* Sanity check */ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) { + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_cap_tsf_req_info = (wdi_cap_tsf_params_t *) + event_data->pEventData; + + /* Get message buffer */ + if (( WDI_STATUS_SUCCESS != + WDI_GetMessageBuffer(wdi_ctx, + WDI_CAP_TSF_REQ, + sizeof(hal_cap_tsf_req. + capTSFget), + &buff, &data_offset, &size))|| + (size < (data_offset + + sizeof(hal_cap_tsf_req.capTSFget)))) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Unable to get send buffer in GetTsfFrame Req"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + hal_cap_tsf_req.capTSFget.uBssIdx = wdi_cap_tsf_req_info->bss_idx; + hal_cap_tsf_req.capTSFget.capTSFget = wdi_cap_tsf_req_info->capTSFget; + + wdi_tsf_rsp_callback = (wdi_tsf_rsp_cb)event_data->pCBfnc; + + wpalMemoryCopy(buff+data_offset, + &hal_cap_tsf_req.capTSFget, + sizeof(hal_cap_tsf_req.capTSFget)); + + wdi_status = WDI_SendMsg(wdi_ctx, buff, size, + wdi_tsf_rsp_callback, + event_data->pUserData, + WDI_CAPTURE_GET_TSF_TSTAMP_RSP); + + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: Exit",__func__); + + return wdi_status; +} + +/** + * wdi_get_tsf_rsp() - wdi api for the get tsf response + * @wdi_ctx: pointer to the wdi context + * @event_data: pointer to the event data + * + * Return: WDI_Status + * WDI_STATUS_SUCCESS - success or else failure status + */ +WDI_Status +wdi_get_tsf_rsp +( + WDI_ControlBlockType *wdi_ctx, + WDI_EventInfoType *event_data +) +{ + wdi_tsf_rsp_cb wdi_tsf_rsp_callback; + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: Enter ", __func__); + /*------------------------------------------------------------------- + Sanity check + -----------------------------------------------------------------*/ + if ((NULL == wdi_ctx) || (NULL == event_data) || + (NULL == event_data->pEventData)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: Invalid parameters", __func__); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wdi_tsf_rsp_callback = + (wdi_tsf_rsp_cb)wdi_ctx->pfncRspCB; + + if (wdi_tsf_rsp_callback) + wdi_tsf_rsp_callback((void *) event_data->pEventData, + wdi_ctx->pRspCBUserData); + else { + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "wdi_tsf_rsp_callback is NULL!"); + return WDI_STATUS_E_FAILURE; + } + + return WDI_STATUS_SUCCESS; +} +#endif diff --git a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_dp.c b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_dp.c new file mode 100644 index 000000000000..25d627f23886 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_dp.c @@ -0,0 +1,1104 @@ +/* + * Copyright (c) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + + + + +/*=========================================================================== + + W L A N _ Q C T _ W D I _ D P. C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Abstraction + Layer Internal Utility routines to be used by the Data Path. + + The functions externalized by this module are to be only by the WDI data + path. + + The module leveraged as much as functionality as was possible from the HAL + in Libra/Volans. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-08-19 lti Created module + +===========================================================================*/ + +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_type.h" +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_i.h" +#include "wlan_qct_wdi_sta.h" +#include "wlan_qct_wdi_dp.h" +#include "wlan_qct_wdi_bd.h" +#include "wlan_qct_pal_trace.h" + +#include "wlan_qct_dev_defs.h" +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x" + +extern uint8 WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision); +extern uint8 WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(uint8 major, uint8 minor, uint8 version, uint8 revision); + + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------- + TID->QueueID mapping + --------------------------------------------------------------------------*/ +static wpt_uint8 btqmQosTid2QidMapping[] = +{ + BTQM_QID0, + BTQM_QID1, + BTQM_QID2, + BTQM_QID3, + BTQM_QID4, + BTQM_QID5, + BTQM_QID6, + BTQM_QID7 +}; +/*=========================================================================== + Helper Internal API + ===========================================================================*/ + +/** + @brief WDI_DP_UtilsInit - Intializes the parameters required to + interact with the data path + + @param pWDICtx: pointer to the main WDI Ctrl Block + + @return success always +*/ +WDI_Status +WDI_DP_UtilsInit +( + WDI_ControlBlockType* pWDICtx +) +{ + WDI_RxBdType* pAmsduRxBdFixMask; + + // WQ to be used for filling the TxBD + pWDICtx->ucDpuRF = BMUWQ_BTQM_TX_MGMT; + +#ifdef WLAN_PERF + pWDICtx->uBdSigSerialNum = 0; +#endif + + pAmsduRxBdFixMask = &pWDICtx->wdiRxAmsduBdFixMask; + + wpalMemoryFill(pAmsduRxBdFixMask,sizeof(WDI_RxBdType), 0xff); + + pAmsduRxBdFixMask->penultimatePduIdx = 0; + pAmsduRxBdFixMask->headPduIdx = 0; + pAmsduRxBdFixMask->tailPduIdx = 0; + pAmsduRxBdFixMask->mpduHeaderLength = 0; + pAmsduRxBdFixMask->mpduHeaderOffset = 0; + pAmsduRxBdFixMask->mpduDataOffset = 0; + pAmsduRxBdFixMask->pduCount = 0; + pAmsduRxBdFixMask->mpduLength = 0; + pAmsduRxBdFixMask->asf = 0; + pAmsduRxBdFixMask->esf = 0; + pAmsduRxBdFixMask->lsf = 0; + pAmsduRxBdFixMask->processOrder = 0; + pAmsduRxBdFixMask->sybFrameIdx = 0; + pAmsduRxBdFixMask->totalMsduSize = 0; + pAmsduRxBdFixMask->aduFeedback = 0; + + return WDI_STATUS_SUCCESS; +}/*WDI_DP_UtilsInit*/ + + +/** + @brief WDI_DP_UtilsExit - Clears the parameters required to + interact with the data path + + @param pWDICtx: pointer to the main WDI Ctrl Block + + @return success always +*/ +WDI_Status +WDI_DP_UtilsExit +( + WDI_ControlBlockType* pWDICtx +) +{ + return WDI_STATUS_SUCCESS; +}/*WDI_DP_UtilsExit*/ + +/** + @brief WDI_SwapBytes - Swap Bytes of a given buffer + + @param pBd: buffer to be swapped + nbSwap: number of bytes to swap + + @return none +*/ +WPT_STATIC WPT_INLINE void +WDI_SwapBytes +( + wpt_uint8 *pBd, + wpt_uint32 nbSwap +) +{ + wpt_uint32 *pU32; + wpt_uint32 nU32; + wpt_uint32 wc; + + nU32 = (((nbSwap) + 3)>>2); + + pU32 = (wpt_uint32 *)pBd; + for ( wc = 0; wc < nU32; wc++ ) + { + pU32[ wc ] = WPAL_BE32_TO_CPU( pU32[ wc ] ); + } +}/*WDI_SwapBytes*/ + +/** + @brief WDI_BmuGetQidForQOSTid - returns the BMU QID for a given + TID + + @param ucTid: TID + pQid: out QID + + @see + @return Result of the function call +*/ +WDI_Status +WDI_BmuGetQidForQOSTid +( + wpt_uint8 ucTid, + wpt_uint8* pQid +) +{ + if (ucTid > BTQM_QUEUE_TX_TID_7 ) + return WDI_STATUS_E_FAILURE; + + *pQid = btqmQosTid2QidMapping[ucTid]; + return WDI_STATUS_SUCCESS; +}/*WDI_BmuGetQidForQOSTid*/ + +#ifdef WLAN_PERF + +/** + @brief WDI_ComputeTxBdSignature - computes the BD signature + + @param pWDICtx: pointer to the global WDI context; + + pDestMacAddr: destination MAC address + + ucTid: TID of the frame + + ucDisableFrmXtl: Unicast destination + + @return the signature +*/ +static wpt_uint32 +WDI_ComputeTxBdSignature +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pDestMac, + wpt_uint8 ucTid, + wpt_uint8 ucUnicastDst +) +{ + wpt_uint16 *pMacU16 = (wpt_uint16 *) pDestMac; + + return ((pMacU16[0] ^ pMacU16[1] ^ pMacU16[2])<< WDI_TXBD_SIG_MACADDR_HASH_OFFSET | + pWDICtx->uBdSigSerialNum << WDI_TXBD_SIG_SERIAL_OFFSET | + ucTid << WDI_TXBD_SIG_TID_OFFSET | + ucUnicastDst << WDI_TXBD_SIG_UCAST_DATA_OFFSET); +}/*WDI_ComputeTxBdSignature*/ + + +/** + @brief WDI_TxBdFastFwd - evaluates if a frame can be fast + forwarded + + @param pWDICtx: Context to the WDI + pDestMac: Destination MAC + ucTid: packet TID pBDHeader + ucUnicastDst: is packet unicast + pTxBd: pointer to the BD header + usMpduLength: len + + @return 1 - if the frame can be fast fwd-ed ; 0 if not +*/ +wpt_uint32 +WDI_TxBdFastFwd +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8* pDestMac, + wpt_uint8 ucTid, + wpt_uint8 ucUnicastDst, + void* pTxBd, + wpt_uint16 usMpduLength + ) +{ + WDI_TxBdType* pBd = (WDI_TxBdType*) pTxBd; + wpt_uint32 uRetval = 0; +#ifdef WPT_LITTLE_BYTE_ENDIAN + wpt_uint16 usSwapped; + wpt_uint16* pU16 = (wpt_uint16 *) pTxBd; +#endif + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if( pBd->txBdSignature == + WDI_ComputeTxBdSignature(pWDICtx, pDestMac, ucTid, ucUnicastDst)) + { + +#ifdef WPT_LITTLE_BYTE_ENDIAN + /* When swap to BE format, mpduLength field is at 8th WORD location(16th byte) */ + usSwapped = wpt_cpu_to_be16(usMpduLength); + pU16[8] = usSwapped; +#else + /* Remove the #error when ported to a real BIG ENDIAN machine */ + // #error "Is host byte order really BIG endian?" + /* When host is already in BE format, no swapping needed.*/ + pBd->mpduLength = usMpduLength; +#endif + uRetval = 1; + } + return uRetval ; +}/*WDI_TxBdFastFwd*/ + +#endif /*WLAN_PERF*/ + +/*=========================================================================== + External API + ===========================================================================*/ + +/** + @brief WLANHAL_FillTxBd - Called by TL to fill in TxBD. + + Following are the highlights of the function + + 1. All unicast data packets are sent by data rate decided by TPE. + (i.e BD rates are disabled). + + 2. All u/mcast management packets would go in Broadcast + Management Rates + + 3. dpuNE would be disabled for all data packets + + 4. dpuNE would be enabled for all management packets + excluding packets when RMF is enabled + + 5. QID8 at self STA is for broadcast data which uses no ACK + policy. + + 6. QID9 at self STA, we use it for unicast mgmt and set ACK + policy to normal ACK. + + 7. QID10 at self STA, we use it for b/mcast mgmt and set ACK + policy to NO ACK. + + WDI DP Utilities modules must be initiatilized before this + API can be called. + + @param + + IN + pWDICtx: pointer to the global WDI context; + + ucTypeSubtype: 802.11 [5:4] ucType [3:0] subtype + + pDestMacAddr: destination MAC address + + pTid: ptr to TID of the frame + + ucDisableFrmXtl: When set, disables UMA HW frame + translation and WDI needs to fill in all BD + fields. When not set, UMA performs BD + filling and frame translation + + pTxBd: ptr to the TxBD + + ucTxFlag: different option setting for TX. + + ucProtMgmtFrame: for management frames, whether the frame is + protected (protect bit is set in FC) + + uTimeStamp: Timestamp when the frame was received from HDD. (usec) + + @return + The result code associated with performing the operation + +*/ + +WDI_Status +WDI_FillTxBd +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucTypeSubtype, + void* pDestMacAddr, + void* pAddr2, + wpt_uint8* pTid, + wpt_uint8 ucDisableFrmXtl, + void* pTxBd, + wpt_uint32 ucTxFlag, + wpt_uint8 ucProtMgmtFrame, + wpt_uint32 uTimeStamp, + wpt_uint8 isEapol, + wpt_uint8 isArp, + wpt_uint8* staIndex, + wpt_uint32 txBdToken +) +{ + wpt_uint8 ucTid = *pTid; + WDI_TxBdType* pBd = (WDI_TxBdType*) pTxBd; + WDI_Status wdiStatus = WDI_STATUS_SUCCESS; + wpt_uint8 ucUnicastDst = 0; + wpt_uint8 ucType = 0; + wpt_uint8 ucSubType = 0; + wpt_uint8 ucIsRMF = 0; + WDI_BSSSessionType* pBSSSes; + wpt_uint8 ucSTAType = 0; +#ifdef WLAN_PERF + wpt_uint32 uTxBdSignature = pBd->txBdSignature; +#endif + tANI_U8 useStaRateForBcastFrames = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------ + Get type and subtype of the frame first + ------------------------------------------------------------------------*/ + pBd->txBdToken = txBdToken; + + pBd->isArp = isArp; + + ucType = (ucTypeSubtype & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET; + ucSubType = (ucTypeSubtype & WDI_FRAME_SUBTYPE_MASK); + + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN, + "Type: %d/%d, MAC S: %08x. MAC D: %08x., Tid=%d, frmXlat=%d, pTxBD=%p ucTxFlag 0x%X", + ucType, ucSubType, + *((wpt_uint32 *) pAddr2), + *((wpt_uint32 *) pDestMacAddr), + ucTid, + !ucDisableFrmXtl, pTxBd, ucTxFlag ); + + + //logic to determine the version match between host and riva to find out when to enable using STA rate for bcast frames. + //determine if Riva vsersion and host version both are greater than or equal to 0.0.2 (major, minor, version). if yes then use STA rate + // instead of BD rate for BC/MC frames. Otherwise use old code to use BD rate instead. + { + if (WDA_IsWcnssWlanCompiledVersionGreaterThanOrEqual(0, 0, 2, 0) && + WDA_IsWcnssWlanReportedVersionGreaterThanOrEqual(0, 0, 2, 0)) + useStaRateForBcastFrames = 1; + } + + + /*----------------------------------------------------------------------- + * Set common fields in TxBD + * bdt: always HWBD_TYPE_GENERIC + dpuRF: This is not used in Gen6 since all WQs are explicitly + programmed to each HW module + * ucTid: from caller, ignored if frame is MGMT frame + * fwTxComplete0: always set to 0 + * txComplete1: If TxComp inrs is requested, enable TxComplete interrupt + * dpuFeedback/aduFeedback/reserved2: Always set to 0 + ap: ACK policy to be placed in Qos ctrl field. Ignored by HW if non + Qos ucType frames. + u/b: If Addr1 of this frame in its 802.11 form is unicast, set to 0. + Otherwise set to 1. + dpuNE: always set to 0. DPU also uses the privacy bit in 802.11 hdr + for encryption decision + -----------------------------------------------------------------------*/ + pBd->bdt = HWBD_TYPE_GENERIC; + + // Route all trigger enabled frames to FW WQ, for FW to suspend trigger frame generation + // when no traffic is exists on trigger enabled ACs + if(ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK) { + pBd->dpuRF = pWDICtx->ucDpuRF; + } else + { + pBd->dpuRF = BMUWQ_BTQM_TX_MGMT; + } + + if (ucTxFlag & WDI_USE_FW_IN_TX_PATH || + (pWDICtx->sendMgmtPktViaWQ5 && (ucType == WDI_MAC_MGMT_FRAME))) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "iType: %d SubType %d, MAC S: %08x. MAC D: %08x., Tid=%d", + ucType, ucSubType, + *((wpt_uint32 *) pAddr2), + *((wpt_uint32 *) pDestMacAddr), + ucTid); + + pBd->dpuRF = BMUWQ_FW_DPU_TX; + } + + pBd->tid = ucTid; + // Clear the reserved field as this field is used for defining special + // flow control BD. + pBd->reserved4 = 0; + pBd->fwTxComplete0 = 0; + + /* This bit is for host to register TxComplete Interrupt */ + pBd->txComplete1 = (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK) ? 1 : 0; + + pBd->ap = WDI_ACKPOLICY_ACK_REQUIRED; + pBd->dpuNE = WDI_NO_ENCRYPTION_DISABLED; + + ucUnicastDst = !(((wpt_uint8 *)pDestMacAddr)[0] & 0x01); + *((wpt_uint32 *)pBd + WDI_DPU_FEEDBACK_OFFSET) = 0; + + if(!ucUnicastDst) + { + pBd->ap = WDI_ACKPOLICY_ACK_NOTREQUIRED; + } + + if (ucType == WDI_MAC_DATA_FRAME) + { + + /* Set common fields for data frames (regardless FT enable/disable) + * bd_ssn: Let DPU auto generate seq # if QosData frame. All other + frames DPU generates seq using nonQos counter. + For QosNull, don't occupy one Qos seq # to avoid a potential + hole seen in reorder buffer when BA is enabled. + + * bd_rate:HW default or broadcast data rate + * rmf: RMF doesn't apply for data frames. Always set to 0 + * u/b: If Addr1 of this frame in its 802.11 form is unicast, + set to 0. Otherwise set to 1. + * Sanity: Force disable HW frame translation if incoming frame is + NULL data frame + */ + + if ((ucSubType & WDI_MAC_DATA_QOS_DATA)&& + (ucSubType != WDI_MAC_DATA_QOS_NULL)) + { + pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_QOS; + } + else + { + pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS; + } + + /* Unicast/Mcast decision: + * In Infra STA role, all frames to AP are unicast frames. + * For IBSS, then check the actual DA MAC address + This implementation doesn't support multi BSS and AP case. + if(eSYSTEM_STA_IN_IBSS_ROLE == systemRole) + ucUnicastDst = !(((wpt_uint8 *)pDestMacAddr)[0] & 0x01); + else + ucUnicastDst = WDI_DEFAULT_UNICAST_ENABLED; + + The above is original HAL code - however to make implementation + more elastic and supportive of concurrency scenarios we shall just + assume that bcast bit of MAC adddress cannot be set if addr is not + bcast: (!! may want to revisit this during testing) + */ + + //Broadcast frames buffering don't work well if BD rate is used in AP mode. + //always use STA rate for data frames. + //never use BD rate for BC/MC frames in AP mode. + + + if (useStaRateForBcastFrames) + { + pBd->bdRate = WDI_TXBD_BDRATE_DEFAULT; + } + else + { + pBd->bdRate = (ucUnicastDst)? WDI_TXBD_BDRATE_DEFAULT : WDI_BDRATE_BCDATA_FRAME; + } +#ifdef FEATURE_WLAN_TDLS + if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) + { + pBd->bdRate = WDI_BDRATE_CTRL_FRAME; + } +#endif + + if(ucTxFlag & WDI_USE_BD_RATE_1_MASK) + { + pBd->bdRate = WDI_BDRATE_BCDATA_FRAME; + } + else if(ucTxFlag & WDI_USE_BD_RATE_2_MASK) + { + pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME; + } + else if(ucTxFlag & WDI_USE_BD_RATE_3_MASK) + { + pBd->bdRate = WDI_BDRATE_CTRL_FRAME; + } + + pBd->rmf = WDI_RMF_DISABLED; + + /* sanity: Might already be set by caller, but enforce it here again */ + if( WDI_MAC_DATA_NULL == (ucSubType & ~WDI_MAC_DATA_QOS_DATA)) + { + ucDisableFrmXtl = 1; + if (ucTxFlag & WDI_TXCOMP_REQUESTED_MASK) + { + /*Send to FW to transmit NULL frames.*/ + pBd->dpuRF = BMUWQ_FW_TRANSMIT; + } + else + { +#ifdef LIBRA_WAPI_SUPPORT + if (ucTxFlag & WDI_WAPI_STA_MASK) + { + pBd->dpuRF = BMUWQ_WAPI_DPU_TX; + /*set NE bit to 1 for the null/qos null frames*/ + pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED; + } +#endif + } + } +#if defined(WLAN_PERF) || defined(FEATURE_WLAN_WAPI) || defined(LIBRA_WAPI_SUPPORT) + //For not-NULL data frames + else + { +#if defined(FEATURE_WLAN_WAPI) + //If caller doesn't want this frame to be encrypted, for example, WAI packets + if( (ucTxFlag & WDI_TX_NO_ENCRYPTION_MASK) ) + { + pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED; + } +#endif //defined(FEATURE_WLAN_WAPI) +#ifdef LIBRA_WAPI_SUPPORT + if (ucTxFlag & WDI_WAPI_STA_MASK) + { + pBd->dpuRF = BMUWQ_WAPI_DPU_TX; + } +#endif //LIBRA_WAPI_SUPPORT +#if defined(WLAN_PERF) + uTxBdSignature = WDI_ComputeTxBdSignature(pWDICtx, pDestMacAddr, ucTid, ucUnicastDst); +#endif //defined(WLAN_PERF) + } +#endif + } + else if (ucType == WDI_MAC_MGMT_FRAME) + { + + /*-------------------------------------------------------------------- + * Set common fields for mgmt frames + * bd_ssn: Always let DPU auto generate seq # from the nonQos + sequence number counter. + * bd_rate:unicast mgmt frames will go at lower rate (multicast rate). + * multicast mgmt frames will go at the STA rate as in AP mode + * buffering has an issue at HW if BD rate is used. + * rmf: NOT SET here. would be set later after STA id lookup is done. + * Sanity: Force HW frame translation OFF for mgmt frames. + --------------------------------------------------------------------*/ + /* apply to both ucast/mcast mgmt frames */ + /* Probe requests are sent using BD rate */ + if( ucSubType == WDI_MAC_MGMT_PROBE_REQ ) + { + pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME; + } + else + { + if (useStaRateForBcastFrames) + { + pBd->bdRate = (ucUnicastDst)? WDI_BDRATE_BCMGMT_FRAME : WDI_TXBD_BDRATE_DEFAULT; + } + else + { + pBd->bdRate = WDI_BDRATE_BCMGMT_FRAME; + } + } + if ( ucTxFlag & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) + { + pBd->bdRate = WDI_BDRATE_CTRL_FRAME; + } + + pBd->bd_ssn = WDI_TXBD_BD_SSN_FILL_DPU_NON_QOS; + if((ucSubType == WDI_MAC_MGMT_ACTION) || (ucSubType == WDI_MAC_MGMT_DEAUTH) || + (ucSubType == WDI_MAC_MGMT_DISASSOC)) + ucIsRMF = 1; + ucDisableFrmXtl = 1; + } + else + { // Control Packet + /* We should never get a control packet, asserting here since something + is wrong */ + WDI_ASSERT(0); + } + + pBd->ub = !ucUnicastDst; + + /* Fast path: Leverage UMA for BD filling/frame translation. + * Must be a data frame to request for FT. + * When HW frame translation is enabled, UMA fills in the following fields: + * DPU Sig + * DPU descriptor index + * Updates MPDU header offset, data offset, MPDU length after translation + * STA id + * BTQM Queue ID + */ + + pBd->ft = pWDICtx->bFrameTransEnabled & !ucDisableFrmXtl; + + if( !pBd->ft) + { + /* - Slow path: Frame translation is disabled. Need to set the + following fields: + * STA id + * DPU Sig + * DPU descriptor index + * BTQM Queue ID + * - For mgmt frames, also update rmf bits + */ + + WDI_StaStruct* pSta = (WDI_StaStruct*) pWDICtx->staTable; + wpt_uint8 ucStaId; + + /* Disable frame translation*/ + pBd->ft = 0; +#ifdef WLAN_PERF + /* Mark the BD could not be reused */ + uTxBdSignature = WDI_TXBD_SIG_MGMT_MAGIC; +#endif + if((ucTxFlag & WDI_USE_SELF_STA_REQUESTED_MASK) && + !(ucIsRMF && ucProtMgmtFrame)) + { +#ifdef HAL_SELF_STA_PER_BSS + // Get the (self) station index from ADDR2, which should be the self MAC addr + wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx, + *(wpt_macAddr*)pAddr2, &ucStaId ); + if (WDI_STATUS_SUCCESS != wdiStatus) + { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "WDI_STATableFindStaidByAddr failed"); + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, "STA ID = %d " MAC_ADDRESS_STR, + ucStaId, MAC_ADDR_ARRAY(*(wpt_macAddr*)pAddr2)); + return WDI_STATUS_E_NOT_ALLOWED; + } +#else + ucStaId = pWDICtx->ucSelfStaId; +#endif + } + else + { + /* + _____________________________________________________________________________________________ + | | | Data || Mgmt | + |____|_______|_______________________________________||_______________________________________| + | | Mode | DestAddr | Addr2 (selfMac) || DestAddr | Addr2 (selfMac) | + |____|_______|___________________|___________________||___________________|___________________| + | | | | || | | + | | STA | DestAddr->staIdx | When DestAddr || DestAddr->staIdx | - | + | | | | lookup fails, || | | + | | | | Addr2->staIdx || | | + |U/C | IBSS | DestAddr->staIdx | - || DestAddr->staIdx | - | + | | SoftAP| DestAddr->staIdx | - || DestAddr->staIdx | When DestAddr | + | | | | || | lookup fails, | + | | | | || | Addr2->StaIdx | + | | Idle | N/A | N/A || - | Addr2->StaIdx | + |____|_______|___________________|___________________||___________________|___________________| + | | | | || | | + | | STA | N/A | N/A || - | Addr2->staIdx-> | + | | | | || | bssIdx->bcasStaIdx| + |B/C | IBSS | - | Addr2->staIdx-> || - | Addr2->staIdx-> | + | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx| + | | SoftAP| - | Addr2->staIdx-> || - | Addr2->staIdx-> | + | | | | bssIdx->bcasStaIdx|| | bssIdx->bcasStaIdx| + | | Idle | N/A | N/A || - | Addr2->staIdx-> | + | | | | || | bssIdx->bcasStaIdx| + |____|_______|___________________|___________________||___________________|___________________|*/ + // Get the station index based on the above table + if( ucUnicastDst ) + { + wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx, + *(wpt_macAddr*)pDestMacAddr, &ucStaId ); + // In STA mode the unicast data frame could be + // transmitted to a DestAddr for which there might not be an entry in + // HAL STA table and the lookup would fail. In such cases use the Addr2 + // (self MAC address) to get the selfStaIdx. + // From SelfStaIdx, get BSSIdx and use BSS MacAddr to get the staIdx + // corresponding to peerSta(AP). + // Drop frames only it is a data frame. Management frames can still + // go out using selfStaIdx. + + + if (WDI_STATUS_SUCCESS != wdiStatus) + { + if(ucType == WDI_MAC_MGMT_FRAME) + { + //For management frames, use self staIdx if peer sta + //entry is not found. + wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx, + *(wpt_macAddr*)pAddr2, &ucStaId ); + } + else + { + if( !ucDisableFrmXtl ) + { + // FrameTranslation in HW is enanled. This means, + // pDestMacaddress may be unknown. Get the station index + // for ADDR2, which should be the self MAC addr + wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx, + *(wpt_macAddr*)pAddr2, &ucStaId ); + if (WDI_STATUS_SUCCESS == wdiStatus) + { + //Found self Sta index. + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + wpt_uint8 bssIdx = 0; + + pBSSSes = NULL; + //Initialize WDI status to error. + wdiStatus = WDI_STATUS_E_NOT_ALLOWED; + + //Check if its BSSIdx is valid. + if (pSTATable[ucStaId].bssIdx != WDI_BSS_INVALID_IDX) + { + //Use BSSIdx to get the association sequence and use + //macBssId to get the peerMac Address(MacBSSID). + bssIdx = WDI_FindAssocSessionByBSSIdx( pWDICtx, + pSTATable[ucStaId].bssIdx, + &pBSSSes); + + if ( NULL != pBSSSes ) + { + //Get staId from the peerMac. + wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx, + pBSSSes->macBSSID, &ucStaId ); + } + } + } + } + } + //wdiStatus will be success if it found valid peerStaIdx + //Otherwise return failure. + if(WDI_STATUS_SUCCESS != wdiStatus ) + { + return WDI_STATUS_E_NOT_ALLOWED; + } + } + } + else + { + // For bcast frames use the bcast station index + wpt_uint8 bssSessIdx; + + // Get the station index for ADDR2, which should be the self MAC addr + wdiStatus = WDI_STATableFindStaidByAddr( pWDICtx, + *(wpt_macAddr*)pAddr2, &ucStaId ); + if (WDI_STATUS_SUCCESS != wdiStatus) + { + return WDI_STATUS_E_NOT_ALLOWED; + } + + // Get the Bss Index related to the staId + bssSessIdx = pSta[ucStaId].bssIdx; + + // Get the broadcast station index for this bss + (void) WDI_FindAssocSessionByBSSIdx( pWDICtx, bssSessIdx, + &pBSSSes ); + if (NULL == pBSSSes) + { + // session not found ?!? + return WDI_STATUS_E_FAILURE; + } + ucStaId = pBSSSes->bcastStaIdx; + } + } + + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO,"StaId:%d and ucTxFlag:%02x", ucStaId, ucTxFlag); + + pBd->staIndex = ucStaId; + + *staIndex = ucStaId; + + pSta += ucStaId; // Go to the curresponding station's station table + + if(ucType == WDI_MAC_MGMT_FRAME) + { + if (ucUnicastDst) + { + /* If no ack is requested use the bcast queue */ + if (ucTxFlag & WDI_USE_NO_ACK_REQUESTED_MASK) + { + pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT; + } + else + { + /* Assigning Queue Id configured to Ack */ + pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_MGMT; + } + } + else + { + /* Assigning to Queue Id configured to No Ack */ + pBd->queueId = BTQM_QUEUE_SELF_STA_BCAST_MGMT; + } + + if(ucIsRMF && pSta->rmfEnabled) + { + pBd->dpuNE = !ucProtMgmtFrame; + pBd->rmf = 1; + if(!ucUnicastDst) + pBd->dpuDescIdx = pSta->bcastMgmtDpuIndex; /* IGTK */ + else + pBd->dpuDescIdx = pSta->dpuIndex; /* PTK */ + } + else + { + pBd->dpuNE = WDI_NO_ENCRYPTION_ENABLED; + pBd->rmf = 0; + pBd->dpuDescIdx = pSta->dpuIndex; /* PTK for both u/mcast mgmt frames */ + } + } + else + { + /* data frames */ + /* TID->QID is one-to-one mapping, the same way as followed in H/W */ + wpt_uint8 queueId = 0; + + + WDI_STATableGetStaType(pWDICtx, ucStaId, &ucSTAType); + if(!ucUnicastDst) +#ifdef WLAN_FEATURE_RMC + /*Check for RMC enabled bit if set then + queue frames in QID 5 else 0*/ + if ( ucTxFlag & WDI_RMC_REQUESTED_MASK ) + pBd->queueId = BTQM_QID5; + else +#endif + pBd->queueId = BTQM_QID0; +#ifndef HAL_SELF_STA_PER_BSS + else if( ucUnicastDst && (ucStaId == pWDICtx->ucSelfStaId)) + pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA; +#else + else if( ucUnicastDst && (ucSTAType == WDI_STA_ENTRY_SELF)) + pBd->queueId = BTQM_QUEUE_SELF_STA_UCAST_DATA; +#endif + else if (pSta->qosEnabled) + { + WDI_BmuGetQidForQOSTid( ucTid, &queueId); + pBd->queueId = (wpt_uint32) queueId; + } + else + pBd->queueId = BTQM_QUEUE_TX_nQOS; + + if(ucUnicastDst) + { + pBd->dpuDescIdx = pSta->dpuIndex; /*unicast data frames: PTK*/ + } + else + { + pBd->dpuDescIdx = pSta->bcastDpuIndex; /* mcast data frames: GTK*/ + } + } + + pBd->dpuSignature = pSta->dpuSig; + + /* ! Re-analize this assumption + - original code from HAL is below - however WDI does not have access to a + DPU index table - so it just stores the signature that it receives from HAL upon + post assoc + if(eHAL_STATUS_SUCCESS == halDpu_GetSignature(pMac, pSta->dpuIndex, &ucDpuSig)) + pBd->dpuSignature = ucDpuSig; + else{ + WPAL_TRACE( WPT_WDI_CONTROL_MODULE, WPT_MSG_LEVEL_HIGH, "halDpu_GetSignature() failed for dpuId = %d\n", pBd->dpuDescIdx)); + return VOS_STATUS_E_FAILURE; + } */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE + // if this is a Virtual Station or statype is TDLS and trig enabled mask + // set then change the DPU Routing Flag so + // that the frame will be routed to Firmware for queuing & transmit + if (IS_VSTA_IDX(ucStaId) || + ( +#ifdef FEATURE_WLAN_TDLS + (ucSTAType == WDI_STA_ENTRY_TDLS_PEER ) && +#endif + (ucTxFlag & WDI_TRIGGER_ENABLED_AC_MASK)) || isEapol) + { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_INFO, + "Sending EAPOL pakcet over WQ5 MAC S: %08x. MAC D: %08x.", + *((wpt_uint32 *) pAddr2), + *((wpt_uint32 *) pDestMacAddr)); + pBd->dpuRF = BMUWQ_FW_DPU_TX; + } +#endif + + } + + /*------------------------------------------------------------------------ + Over SDIO bus, SIF won't swap data bytes to/from data FIFO. + In order for MAC modules to recognize BD in Riva's default endian + format (Big endian) + * All BD fields need to be swaped here + ------------------------------------------------------------------------*/ + WDI_SwapTxBd((wpt_uint8 *)pBd); + +#ifdef WLAN_PERF + /* Save the BD signature. This field won't be swapped and remains in host + byte order */ + pBd->txBdSignature = uTxBdSignature ; +#endif + + return wdiStatus; +}/*WDI_FillTxBd*/ + + +/** + @brief WDI_RxBD_GetFrameTypeSubType - Called by the data path + to retrieve the type/subtype of the received frame. + + @param pvBDHeader: Void pointer to the RxBD buffer. + usFrmCtrl: the frame ctrl of the 802.11 header + + @return A byte which contains both type and subtype info. LSB four bytes + (b0 to b3)is subtype and b5-b6 is type info. +*/ + +wpt_uint8 +WDI_RxBD_GetFrameTypeSubType +( + void* _pvBDHeader, + wpt_uint16 usFrmCtrl +) +{ + WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader; + wpt_uint8 typeSubType; + WDI_MacFrameCtl wdiFrmCtl; + + if (pRxBd->ft != WDI_RX_BD_FT_DONE) + { + if (pRxBd->asf) + { + typeSubType = (WDI_MAC_DATA_FRAME << WDI_FRAME_TYPE_OFFSET) | + WDI_MAC_DATA_QOS_DATA; + } else { + wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl)); + typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) | + wdiFrmCtl.subType; + } + } + else + { + wpalMemoryCopy(&wdiFrmCtl, &usFrmCtrl, sizeof(wdiFrmCtl)); + typeSubType = (wdiFrmCtl.type << WDI_FRAME_TYPE_OFFSET) | + wdiFrmCtl.subType; + } + + return typeSubType; +}/*WDI_RxBD_GetFrameTypeSubType*/ + +/** + @brief WDI_SwapRxBd swaps the RX BD. + + + @param pBd - pointer to the BD (in/out) + + @return None +*/ +void +WDI_SwapRxBd(wpt_uint8 *pBd) +{ +#ifndef WDI_BIG_BYTE_ENDIAN + WDI_SwapBytes(pBd , WDI_RX_BD_HEADER_SIZE); +#endif +}/*WDI_SwapRxBd*/ + + +/** + @brief WDI_SwapTxBd - Swaps the TX BD + + @param pBd - pointer to the BD (in/out) + + @return none +*/ +void +WDI_SwapTxBd(wpt_uint8 *pBd) +{ +#ifndef WDI_BIG_BYTE_ENDIAN + WDI_SwapBytes(pBd , WDI_TX_BD_HEADER_SIZE); +#endif +}/*WDI_SwapTxBd*/ + +/*! TO DO: - check if we still need this for RIVA*/ +/** + @brief WDI_RxAmsduBdFix - fix for HW issue for AMSDU + + + @param pWDICtx: Context to the WDI + pBDHeader - pointer to the BD header + + @return None +*/ +void +WDI_RxAmsduBdFix +( + WDI_ControlBlockType* pWDICtx, + void* _pvBDHeader +) +{ + WDI_RxBdType* pRxBd = (WDI_RxBdType*) _pvBDHeader; + wpt_uint32 *pModBd, *pMaskBd, *pFirstBd, i; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + if (pRxBd->asf) + { + if (pRxBd->sybFrameIdx == 0) + { + //copy the BD of first AMSDU + pWDICtx->wdiRxAmsduFirstBdCache = *pRxBd; + } + else + { + pModBd = (wpt_uint32*)pRxBd; + pMaskBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduBdFixMask; + pFirstBd = (wpt_uint32*)&pWDICtx->wdiRxAmsduFirstBdCache; + + for (i = 0; i < sizeof(WDI_RxBdType)/sizeof(wpt_uint32 *); i++) + { + //modified BD = zero out non AMSDU related fields in this BD | + // non AMSDU related fields from the first BD. + pModBd[i] = (pModBd[i] & ~pMaskBd[i]) | + (pFirstBd[i] & pMaskBd[i]); + } + } + } + return; +}/*WDI_RxAmsduBdFix*/ + diff --git a/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c new file mode 100644 index 000000000000..0038a7b3009e --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/CP/src/wlan_qct_wdi_sta.c @@ -0,0 +1,751 @@ +/* + * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + W L A N _ Q C T _ W D I _ S T A . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Device Abstraction + Layer Station Table Management Entity. + + The functions externalized by this module are internal APIs for DAL Core + and can only be called by it. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why +---------- --- -------------------------------------------------------- +2010-08-09 lti Created module + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_i.h" +#include "wlan_qct_wdi_sta.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_trace.h" + + +/*---------------------------------------------------------------------------- + * Function definition + * -------------------------------------------------------------------------*/ +/** + @brief WDI_STATableInit - Initializes the STA tables. + Allocates the necesary memory. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status WDI_STATableInit +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_uint8 ucMaxStations; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + ucMaxStations = (wpt_uint8) pWDICtx->ucMaxStations; + + /*---------------------------------------------------------------------- + Allocate the memory for sta table + ------------------------------------------------------------------------*/ + pWDICtx->staTable = wpalMemoryAllocate(ucMaxStations * sizeof(WDI_StaStruct)); + + if (NULL == pWDICtx->staTable) + { + + WDI_STATableClose(pWDICtx); + + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Error allocating memory on WDI_STATableInit"); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero( pWDICtx->staTable, ucMaxStations * sizeof( WDI_StaStruct )); + +#ifndef HAL_SELF_STA_PER_BSS + // Initialize the Self STAID to an invalid value + pWDICtx->ucSelfStaId = WDI_STA_INVALID_IDX; +#endif + + return WDI_STATUS_SUCCESS; +}/*WDI_STATableInit*/ + +/** + @brief WDI_STATableStart - resets the max and number values of + STAtions + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableStart +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_uint8 ucMaxStations; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + ucMaxStations = (wpt_uint8) pWDICtx->ucMaxStations; + + return WDI_STATUS_SUCCESS; +}/*WDI_STATableStart*/ + +/** + @brief WDI_STATableStop - clears the sta table + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableStop +( + WDI_ControlBlockType* pWDICtx +) +{ + wpt_uint8 ucMaxStations; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + +#ifndef HAL_SELF_STA_PER_BSS + /* Clean up the Self STAID */ + pWDICtx->ucSelfStaId = WDI_STA_INVALID_IDX; +#endif + + ucMaxStations = pWDICtx->ucMaxStations; + + wpalMemoryZero( (void *) pWDICtx->staTable, + ucMaxStations * sizeof( WDI_StaStruct )); + + return WDI_STATUS_SUCCESS; +}/*WDI_STATableStop*/ + +/** + @brief WDI_STATableClose - frees the resources used by the STA + table. + + + @param pWDICtx: pointer to the WLAN DAL context + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableClose +( + WDI_ControlBlockType* pWDICtx +) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + + // Free memory + if (pWDICtx->staTable != NULL) + wpalMemoryFree( pWDICtx->staTable); + + pWDICtx->staTable = NULL; + return status; +}/*WDI_STATableClose*/ + + +/** + @brief WDI_STATableAddSta - Function to Add Station + + + @param pWDICtx: pointer to the WLAN DAL context + pwdiParam: station parameters + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableAddSta +( + void* ctx, + WDI_AddStaParams* pwdiParam +) +{ + wpt_uint8 ucSTAIdx = 0; + WDI_ControlBlockType* pWDICtx = ctx; + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*----------------------------------------------------------------------- + Sanity check + - station ids are allocated by the HAL located on RIVA SS - they must + always be valid + -----------------------------------------------------------------------*/ + if (( pwdiParam->ucSTAIdx == WDI_STA_INVALID_IDX) || + ( pwdiParam->ucSTAIdx >= pWDICtx->ucMaxStations )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Station id sent by HAL is invalid - not OK"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + ucSTAIdx = pwdiParam->ucSTAIdx; + + /*Since we are not the allocator of STA Ids but HAL is - just set flag to + valid*/ + pSTATable[ucSTAIdx].valid = 1; + + + // Save the STA type - this is used for lookup + WDI_STATableSetStaType(pWDICtx, ucSTAIdx, pwdiParam->ucStaType); + WDI_STATableSetStaQosEnabled(pWDICtx, ucSTAIdx, + (wpt_uint8)(pwdiParam->ucWmmEnabled | pwdiParam->ucHTCapable) ); + +#ifdef WLAN_PERF + pWDICtx->uBdSigSerialNum ++; +#endif + + wpalMemoryCopy(pSTATable[ucSTAIdx].macBSSID, + pwdiParam->macBSSID, WDI_MAC_ADDR_LEN); + + /*------------------------------------------------------------------------ + Set DPU Related Information + ------------------------------------------------------------------------*/ + pSTATable[ucSTAIdx].dpuIndex = pwdiParam->dpuIndex; + pSTATable[ucSTAIdx].dpuSig = pwdiParam->dpuSig; + + pSTATable[ucSTAIdx].bcastDpuIndex = pwdiParam->bcastDpuIndex; + pSTATable[ucSTAIdx].bcastDpuSignature = pwdiParam->bcastDpuSignature; + + pSTATable[ucSTAIdx].bcastMgmtDpuIndex = pwdiParam->bcastMgmtDpuIndex; + pSTATable[ucSTAIdx].bcastMgmtDpuSignature = pwdiParam->bcastMgmtDpuSignature; + + /*Robust Mgmt Frame enabled */ + pSTATable[ucSTAIdx].rmfEnabled = pwdiParam->ucRmfEnabled; + + pSTATable[ucSTAIdx].bssIdx = pwdiParam->ucBSSIdx; + + /* Now update the STA entry with the new MAC address */ + if(WDI_STATUS_SUCCESS != WDI_STATableSetStaAddr( pWDICtx, + ucSTAIdx, + pwdiParam->staMacAddr)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to update station entry - internal failure"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + /* Now update the STA entry with the new BSSID address */ + if(WDI_STATUS_SUCCESS != WDI_STATableSetBSSID( pWDICtx, + ucSTAIdx, + pwdiParam->macBSSID)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Failed to update station entry - internal failure"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + return WDI_STATUS_SUCCESS; +}/*WDI_AddSta*/ + +/** + @brief WDI_STATableDelSta - Function to Delete a Station + + + @param void: pointer to the WLAN DAL context + ucSTAIdx: station to be deleted + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableDelSta +( + void* ctx, + wpt_uint8 ucSTAIdx +) +{ + WDI_ControlBlockType* pWDICtx = ctx; + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*----------------------------------------------------------------------- + Sanity check + - station ids are allocated by the HAL located on RIVA SS - they must + always be valid + -----------------------------------------------------------------------*/ + if(( ucSTAIdx == WDI_STA_INVALID_IDX )|| + ( ucSTAIdx >= pWDICtx->ucMaxStations )) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "STA Id invalid on Del STA - internal failure"); + WDI_ASSERT(0); + return WDI_STATUS_E_FAILURE; + } + + wpalMemoryZero(&pSTATable[ucSTAIdx], sizeof(pSTATable[ucSTAIdx])); + pSTATable->valid = 0; + return WDI_STATUS_SUCCESS; +}/*WDI_STATableDelSta*/ + +/** + @brief WDI_STATableBSSDelSta - Function to Delete Stations in this BSS + + + @param pWDICtx: pointer to the WLAN DAL context + ucBSSIdx: BSS index + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableBSSDelSta +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucBSSIdx +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + wpt_uint8 ucSTAIdx; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + for (ucSTAIdx = 0; (ucSTAIdx < pWDICtx->ucMaxStations); ucSTAIdx++) + { + if( (pSTATable[ucSTAIdx].ucStaType == WDI_STA_ENTRY_PEER) && + (pSTATable[ucSTAIdx].bssIdx == ucBSSIdx)) + { + WDI_STATableDelSta(pWDICtx, ucSTAIdx); + } + } + + return WDI_STATUS_SUCCESS; +}/*WDI_STATableBSSDelSta*/ + + +/** + @brief WDI_STATableGetStaBSSIDAddr - Gets the BSSID associated + with this station + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + pmacBSSID: out BSSID for this STA + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaBSSIDAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr* pmacBSSID +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + wpalMemoryCopy(*pmacBSSID, pSTATable[ucSTAIdx].macBSSID, WDI_MAC_ADDR_LEN); + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableGetStaQosEnabled*/ + + +/** + @brief WDI_STATableGetStaQosEnabled - Gets is qos is enabled + for a sta + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + qosEnabled: out qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaQosEnabled +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8* qosEnabled +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid) && qosEnabled) + { + *qosEnabled = pSTATable[ucSTAIdx].qosEnabled; + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableGetStaQosEnabled*/ + +/** + @brief WDI_STATableSetStaQosEnabled - set qos mode for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + qosEnabled: qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaQosEnabled +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 qosEnabled +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + pSTATable[ucSTAIdx].qosEnabled = qosEnabled; + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableSetStaQosEnabled*/ + +/** + @brief WDI_STATableGetStaType - get sta type for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + pStaType: qos enabled + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaType +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8* pStaType +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + *pStaType = pSTATable[ucSTAIdx].ucStaType; + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableGetStaType*/ + +/** + @brief WDI_STATableSetStaType - sets sta type for STA + + + @param pWDICtx: pointer to the WLAN DAL context + ucSTAIdx: station index + staType: sta type + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaType +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 staType +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + pSTATable[ucSTAIdx].ucStaType = staType; + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableSetStaType*/ + + +/** + @brief WDI_CompareMacAddr - compare the MAC address + + + @param addr1: address 1 + addr2: address 2 + + @see + @return Result of the function call +*/ +WPT_STATIC WPT_INLINE wpt_uint8 +WDI_CompareMacAddr +( + wpt_uint8 addr1[], + wpt_uint8 addr2[] +) +{ +#if defined( _X86_ ) + wpt_uint32 align = (0x3 & ((wpt_uint32) addr1 | (wpt_uint32) addr2 )); + + if( align ==0){ + return ((*((wpt_uint16 *) &(addr1[4])) == *((wpt_uint16 *) &(addr2[4])))&& + (*((wpt_uint32 *) addr1) == *((wpt_uint32 *) addr2))); + }else if(align == 2){ + return ((*((wpt_uint16 *) &addr1[4]) == *((wpt_uint16 *) &addr2[4])) && + (*((wpt_uint16 *) &addr1[2]) == *((wpt_uint16 *) &addr2[2])) && + (*((wpt_uint16 *) &addr1[0]) == *((wpt_uint16 *) &addr2[0]))); + }else{ + return ( (addr1[5]==addr2[5])&& + (addr1[4]==addr2[4])&& + (addr1[3]==addr2[3])&& + (addr1[2]==addr2[2])&& + (addr1[1]==addr2[1])&& + (addr1[0]==addr2[0])); + } +#else + return ( (addr1[0]==addr2[0])&& + (addr1[1]==addr2[1])&& + (addr1[2]==addr2[2])&& + (addr1[3]==addr2[3])&& + (addr1[4]==addr2[4])&& + (addr1[5]==addr2[5])); +#endif +}/*WDI_CompareMacAddr*/ + + +/** + @brief WDI_STATableFindStaidByAddr - Given a station mac address, search + for the corresponding station index from the Station Table. + + @param pWDICtx: WDI Context pointer + staAddr: station address + pucStaId: output station id + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableFindStaidByAddr +( + void * context, + wpt_macAddr staAddr, + wpt_uint8* pucStaId +) +{ + WDI_Status wdiStatus = WDI_STATUS_E_FAILURE; + WDI_ControlBlockType* pWDICtx = context; + wpt_uint8 i; + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + + for (i=0; i < pWDICtx->ucMaxStations; i++, pSTATable++) + { + if ( (pSTATable->valid == 1) && (WDI_CompareMacAddr(pSTATable->staAddr, staAddr)) ) + { + *pucStaId = i; + wdiStatus = WDI_STATUS_SUCCESS; + break; + } + } + return wdiStatus; +}/*WDI_STATableFindStaidByAddr*/ + +/** + @brief WDI_STATableGetStaAddr - get station address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8** pStaAddr +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + *pStaAddr = pSTATable[ucSTAIdx].staAddr; + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableGetStaAddr*/ + +/** + @brief WDI_STATableGetStaMacAddr - get station MAC address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station MAC address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableGetStaMacAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr* staMacAddr +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + wpalMemoryCopy(staMacAddr, pSTATable[ucSTAIdx].staAddr, + WDI_MAC_ADDR_LEN); + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableGetStaMacAddr*/ + +/** + @brief WDI_STATableSetStaAddr - set station address + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetStaAddr +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr staAddr +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + wpalMemoryCopy (pSTATable[ucSTAIdx].staAddr, staAddr, 6); + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableSetStaAddr*/ + +/** + @brief WDI_STATableSetBSSID - set station corresponding BSSID + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + pStaAddr: output station address + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetBSSID +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_macAddr macBSSID +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + wpalMemoryCopy (pSTATable[ucSTAIdx].macBSSID, macBSSID, 6); + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableSetBSSID*/ + +/** + @brief WDI_STATableSetBSSIdx - set station corresponding BSS index + + @param pWDICtx: WDI Context pointer + ucSTAIdx: station index + ucBSSIdx: BSS index + + @see + @return Result of the function call +*/ +WDI_Status +WDI_STATableSetBSSIdx +( + WDI_ControlBlockType* pWDICtx, + wpt_uint8 ucSTAIdx, + wpt_uint8 ucBSSIdx +) +{ + WDI_StaStruct* pSTATable = (WDI_StaStruct*) pWDICtx->staTable; + if ((ucSTAIdx < pWDICtx->ucMaxStations) && (pSTATable[ucSTAIdx].valid)) + { + pSTATable[ucSTAIdx].bssIdx = ucBSSIdx; + return WDI_STATUS_SUCCESS; + } + else + return WDI_STATUS_E_FAILURE; +}/*WDI_STATableSetBSSIdx*/ + diff --git a/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h b/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h new file mode 100644 index 000000000000..4f88b99f6c05 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds.h @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2012-2013, 2016-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_WTI_DS_H ) +#define __WLAN_QCT_WTI_DS_H + +/**========================================================================= + * + * \file wlan_qct_wdi_ds.h + * + * \brief define Dataservice API + * + * WLAN Device Abstraction layer External API for Dataservice + * DESCRIPTION + * This file contains the external API exposed by the + * wlan device abstarction layer module. + * + */ + + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_wdi.h" + + +typedef struct +{ + wpt_uint32 txFlags; + wpt_uint8 ac; + wpt_uint8 isEapol:1; //0 - not eapol 1 - eapol + wpt_uint8 isWai:1; //WAPI 0 - not WAI 1 WAI + wpt_uint8 isArp:1; //0 - not ARP 1 - ARP + wpt_uint8 fdisableFrmXlt:1; //0 - Let ADU do FT. 1 - bypass ADU FT + wpt_uint8 qosEnabled:1; //0 - non-Qos 1 - Qos + wpt_uint8 fenableWDS:1; //0 - not WDS 1 WDS + wpt_uint8 reserved1:2; + wpt_uint8 typeSubtype; + wpt_uint8 fUP; + wpt_uint8 fSTAMACAddress[6]; + wpt_uint8 addr2MACAddress[6]; + wpt_uint8 frmType; + wpt_uint8 fStaType; + wpt_uint8 fProtMgmtFrame; + wpt_uint16 fPktlen; + wpt_status txCompleteStatus; + wpt_uint8 staIdx; + wpt_uint32 txBdToken; +} WDI_DS_TxMetaInfoType; + + +typedef enum +{ + WDI_DS_OPCODE_INVALID = 0, + WDI_DS_OPCODE_QCUR_FWDBUF = 1, + WDI_DS_OPCODE_FWDBUF_FWDCUR = 2, + WDI_DS_OPCODE_QCUR = 3, + WDI_DS_OPCODE_FWDBUF_QUEUECUR = 4, + WDI_DS_OPCODE_FWDBUF_DROPCUR = 5, + WDI_DS_OPCODE_FWDALL_DROPCUR = 6, + WDI_DS_OPCODE_FWDALL_QCUR = 7, + WDI_DS_OPCODE_TEARDOWN = 8, + WDI_DS_OPCODE_DROPCUR = 9, + WDI_DS_OPCODE_MAX +}WDI_DS_BAOpCodeEnumType; + +#define WDI_DS_LOG_PKT_TYPE_LEN 4 +typedef enum +{ + WDI_DS_PACKET_LOG = 1<<0, + + // Insert new values before this + + // If the value of WDI_DS_MAX LOG is increased please + // make sure to change the data type of + // WDI_DS_RxMetaInfoType.loggingData from wpt_uint8 + // to accommodate more values + WDI_DS_MAX_LOG = 1<<31 +}WDI_DS_LoggingDataEnumType; + +typedef struct +{ + wpt_uint8 staId; + wpt_uint8 addr3Idx; + wpt_uint8 rxChannel; + wpt_uint8 type:2; + wpt_uint8 subtype:4; + wpt_uint8 rfBand:2; + + wpt_uint16 rtsf:1; //For beacon only. 1 ~V Riva TSF is bigger(later) than the one received + wpt_uint16 bsf:1; //1 Riva sends the last beacon, 0 not. + wpt_uint16 unknownUcastPkt:1; //1 ~V unicast frame received with unknown A2 + wpt_uint16 scan:1; //1 frame received in scan state. 0 not. + wpt_uint16 dpuSig:3; //DPU signature + wpt_uint16 ft:1; //0~Wframe translation is not done. 1~Wdone + wpt_uint16 ne:1; //1 ~V frame is not encrypted OTA. This is for WAPI~Rs WAI packet. + wpt_uint16 llcr:1; // Has the LLC been stripped by H/W + wpt_uint16 bcast:1; //0 ~V unicast frame 1 ~V broadcast/multicast frame + wpt_uint16 tid:4; + wpt_uint16 reserved1:1; + wpt_uint8 dpuFeedback; + wpt_int8 snr; + + wpt_uint32 currentPktSeqNo:12; /*current sequence number */ + wpt_uint32 ampdu_reorderOpcode:4; + wpt_uint32 ampdu_reorderSlotIdx:6; + wpt_uint32 ampdu_reorderFwdIdx:6; + wpt_uint32 reserved3:4; + + wpt_uint16 amsdu_size; + wpt_uint32 amsdu_asf:1; + wpt_uint32 amsdu_esf:1; + wpt_uint32 amsdu_lsf:1; + wpt_uint32 amsdu_aef:1; + wpt_uint32 reserved2:4; + + wpt_uint8 *mpduHeaderPtr; + wpt_uint8 *mpduDataPtr; + wpt_uint32 mpduLength; + wpt_uint32 mpduHeaderLength; + + wpt_uint32 rateIndex; + wpt_uint32 rxpFlags; + wpt_uint32 mclkRxTimestamp; + + //Flow control frames + wpt_uint8 fc; + wpt_uint32 fcSTATxQStatus:16; + wpt_uint32 fcSTAThreshIndMask:16; + wpt_uint32 fcSTAPwrSaveStateMask:16; + wpt_uint32 fcSTAValidMask:16; + + wpt_uint16 fcStaTxDisabledBitmap; + wpt_uint8 fcSTATxQLen[12]; // one byte per STA. + wpt_uint8 fcSTACurTxRate[12]; // current Tx rate for each sta. + + wpt_uint64 replayCount; + + wpt_uint32 rssi0; + wpt_uint32 rssi1; + +#ifdef WLAN_FEATURE_11W + wpt_uint32 rmf:1; +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + wpt_uint32 offloadScanLearn; + wpt_uint32 roamCandidateInd; + wpt_uint32 perRoamCndInd; +#endif +#ifdef WLAN_FEATURE_EXTSCAN + wpt_uint32 extscanBuffer; +#endif + wpt_uint32 loggingData; + wpt_uint32 indType; +} WDI_DS_RxMetaInfoType; + +typedef struct sPktMetaInfo +{ + union + { + WDI_DS_TxMetaInfoType txMetaInfo; + WDI_DS_RxMetaInfoType rxMetaInfo; + } u; +} WDI_DS_MetaInfoType; + +typedef struct +{ + wpt_uint16 status; + wpt_boolean active; + wpt_uint64 logBuffAddress[MAX_NUM_OF_BUFFER]; + wpt_uint32 logBuffLength[MAX_NUM_OF_BUFFER]; + /* Log type i.e. Mgmt frame = 0, QXDM = 1, FW Mem dump = 2 */ + wpt_uint8 logType; + /* Indicate if Last segment of log is received*/ + wpt_boolean done; + wpt_uint16 reasonCode; +} WDI_DS_LoggingSessionType; + + +/*---------------------------------------------------------------------------- + * WDI_AddStaParams + * -------------------------------------------------------------------------*/ +typedef struct +{ + wpt_uint8 ucSTAIdx; + wpt_uint8 ucWmmEnabled; + wpt_uint8 ucHTCapable; + + /* MAC Address of STA */ + wpt_macAddr staMacAddr; + + /*MAC Address of the BSS*/ + wpt_macAddr macBSSID; + + /* Field to indicate if this is sta entry for itself STA adding entry for itself + * or remote (AP adding STA after successful association. + * This may or may not be required in production driver. + * 0 - Self, 1 other/remote, 2 - bssid + */ + wpt_uint8 ucStaType; + + + /*DPU Information*/ + wpt_uint8 dpuIndex; // DPU table index + wpt_uint8 dpuSig; // DPU signature + wpt_uint8 bcastDpuIndex; + wpt_uint8 bcastDpuSignature; + wpt_uint8 bcastMgmtDpuIndex; + wpt_uint8 bcastMgmtDpuSignature; + + + /*RMF enabled/disabled*/ + wpt_uint8 ucRmfEnabled; + + /* Index into the BSS Session table */ + wpt_uint8 ucBSSIdx; + +}WDI_AddStaParams; + + +WPT_STATIC WPT_INLINE WDI_DS_RxMetaInfoType* WDI_DS_ExtractRxMetaData (wpt_packet *pFrame) +{ + WDI_DS_RxMetaInfoType * pRxMetadata = + &((WDI_DS_MetaInfoType *)WPAL_PACKET_GET_METAINFO_POINTER(pFrame))->u.rxMetaInfo; + return pRxMetadata; +} + + +WPT_STATIC WPT_INLINE WDI_DS_TxMetaInfoType* WDI_DS_ExtractTxMetaData (wpt_packet *pFrame) +{ + WDI_DS_TxMetaInfoType * pTxMetadata = + &((WDI_DS_MetaInfoType *)WPAL_PACKET_GET_METAINFO_POINTER(pFrame))->u.txMetaInfo; + return pTxMetadata; +} + + +typedef void (*WDI_DS_TxCompleteCallback)(void *pContext, wpt_packet *pFrame); +typedef void (*WDI_DS_RxPacketCallback) (void *pContext, wpt_packet *pFrame); +typedef void (*WDI_DS_TxFlowControlCallback)(void *pContext, wpt_uint8 ac_mask); +typedef void (*WDI_DS_RxLogCallback)(wpt_uint8 logType); + + + +/* DAL registration function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * pfnTxCompleteCallback:Callback function that is to be invoked to return + * packets which have been transmitted. + * pfnRxPacketCallback:Callback function that is to be invoked to deliver + * packets which have been received + * pfnTxFlowControlCallback:Callback function that is to be invoked to + * indicate/clear congestion. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +WDI_Status WDI_DS_Register( void *pContext, + WDI_DS_TxCompleteCallback pfnTxCompleteCallback, + WDI_DS_RxPacketCallback pfnRxPacketCallback, + WDI_DS_TxFlowControlCallback pfnTxFlowControlCallback, + WDI_DS_RxLogCallback pfnRxLogCallback, + void *pCallbackContext); + + + +/* DAL Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * pFrame:Refernce to PAL frame. + * more: Does the invokee have more than one packet pending? + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxPacket(void *pContext, + wpt_packet *pFrame, + wpt_boolean more); + + +/* DAL Transmit Complete function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * ucTxResReq:TX resource number required by TL + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxComplete(void *pContext, wpt_uint32 ucTxResReq); + +/* DAL Suspend Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxSuspend(void *pContext); + + +/* DAL Resume Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxResume(void *pContext); + +/* DAL Get Reserved resource by STA + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * wdiResPool: MemPool, MGMT ot DATA + * staId: STA ID + * Return Value: Number of reserved resouce count + * + */ +wpt_uint32 WDI_DS_GetReservedResCountPerSTA(void *pContext, + WDI_ResPoolType wdiResPool, + wpt_uint8 staId); + +/* DAL ADD STA into memPool + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * staId: STA ID + * Return Value: SUCCESS or FAIL + * + */ +WDI_Status WDI_DS_AddSTAMemPool(void *pContext, wpt_uint8 staIndex); +/** + @brief WDI_STATableFindStaidByAddr - Given a station mac address, search + for the corresponding station index from the Station Table. + + @param pWDICtx: Context pointer +staAddr: station address +pucStaId: output station id + +@see +@return Result of the function call +*/ +WDI_Status +WDI_STATableFindStaidByAddr +( + void* pWDICtx, + wpt_macAddr staAddr, + wpt_uint8* pucStaId + ); + +/** + * @brief WDI_STATableAddSta - Function to Add Station + * + * + * @param pWDICtx: pointer to the WLAN DAL context + * pwdiParam: station parameters + * + * @see + * @return Result of the function call + * */ +WDI_Status +WDI_STATableAddSta +( + void* pWDICtx, + WDI_AddStaParams* pwdiParam + ); + + +/** + * @brief WDI_STATableDelSta - Function to Delete a Station + * + * + * @param pWDICtx: pointer to the WLAN DAL context + * ucSTAIdx: station to be deleted + * + * @see + * @return Result of the function call + */ +WDI_Status +WDI_STATableDelSta +( + void* pWDICtx, + wpt_uint8 ucSTAIdx + ); + +/* DAL Remove STA from memPool + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * staId: STA ID + * Return Value: SUCCESS or FAIL + * + */ +WDI_Status WDI_DS_DelSTAMemPool(void *pContext, wpt_uint8 staIndex); + +/* DAL Set STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_SetStaIdxPerBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 staIdx); + +/* DAL Get STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_GetStaIdxFromBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 *staIdx); + +/* DAL Clear STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_ClearStaIdxPerBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 staIdx); + +/* @brief: WDI_DS_GetTrafficStats + * This function should be invoked to fetch the current stats + * Parameters: + * pStats:Pointer to the collected stats + * len: length of buffer pointed to by pStats + * Return Status: None + */ +void WDI_DS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len); + +/* @brief: WDI_DS_DeactivateTrafficStats + * This function should be invoked to deactivate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDI_DS_DeactivateTrafficStats(void); + +/* @brief: WDI_DS_ActivateTrafficStats + * This function should be invoked to activate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDI_DS_ActivateTrafficStats(void); + +/* @brief: WDI_DS_ClearTrafficStats + * This function should be invoked to clear all past stats + * Parameters: None + * Return Status: None + */ +void WDI_DS_ClearTrafficStats(void); + +void *WDI_DS_GetLoggingMbPhyAddr(void *pContext); +void *WDI_DS_GetLoggingMbAddr(void *pContext); +void *WDI_DS_GetLoggingSession(void *pContext); +#endif diff --git a/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h b/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h new file mode 100644 index 000000000000..3a5f53d7fda3 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/DP/inc/wlan_qct_wdi_ds_i.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_WDI_DS_I_H ) +#define __WLAN_QCT_WDI_DS_I_H + +/**========================================================================= + * + * \file wlan_qct_wdi_ds_i.h + * + * \brief define Dataservice API + * + * WLAN Device Abstraction layer External API for Dataservice + * DESCRIPTION + * This file contains the external API exposed by the + * wlan device abstarction layer module. + * + */ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_dxe.h" +#include "wlan_hal_msg.h" + +#define WDI_DS_MAX_CHUNK_SIZE 128 +#define WDI_802_11_MAX_HEADER_LEN 40 + + +/*The number of resources (BD headers) available for the HI priority DXE + channel + DXE will use 1 descriptor for the BD header and 1 for the data => + This is true for LA but not EA. EA sends down 3~4 MDL chain per a packet. + Now we set it the same with free DXE decriptor number*/ +#define WDI_DS_HI_PRI_RES_NUM (WLANDXE_HI_PRI_RES_NUM) + +/*The number of resources (BD headers) available for the Low priority DXE + channel - see above +*/ +#define WDI_DS_LO_PRI_RES_NUM (WLANDXE_LO_PRI_RES_NUM) + +/*The number of BD headers available in the system for Tx must match the number + of DXE descriptors available for actual transmission, otherwise we have to + manage two diffrent level of resource pools*/ + +#define WDI_MAC_ADDR_SIZE ( 6 ) +/*802.3 header definitions*/ +#define WDI_802_3_HEADER_LEN 14 +/* Offset of DA field in a 802.3 header*/ +#define WDI_802_3_HEADER_DA_OFFSET 0 +/*802.11 header definitions - header len without QOS ctrl field*/ +#define WDI_802_11_HEADER_LEN 24 +/*802.11 header length + QOS ctrl field*/ +#define WDI_MPDU_HEADER_LEN 26 +/*802.11 header definitions*/ +#define WDI_802_11_MAX_HEADER_LEN 40 +/*802.11 header definitions - qos ctrl field len*/ +#define WDI_802_11_HEADER_QOS_CTL 2 +/*802.11 ADDR4 MAC addr field len */ +#define WDI_802_11_HEADER_ADDR4_LEN WDI_MAC_ADDR_SIZE + + + + + +typedef enum +{ + DTI_TRACE_LEVEL_FATAL, + DTI_TRACE_LEVEL_ERROR, + DTI_TRACE_LEVEL_WARN, + DTI_TRACE_LEVEL_INFO + +} DTI_TRACE_LEVEL; + +WPT_STATIC WPT_INLINE void DTI_TRACE ( DTI_TRACE_LEVEL level, ...) { }; + +/* !!! MAX NUM STA is not identified yet, 16 is correct value, + but need to get from correct common def + This should be identified ASAP */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define WDI_DS_MAX_STA_ID 41 +#else +#define WDI_DS_MAX_STA_ID 16 +#endif +/* !!! MAX NUM SUPPORTED BSS is not identified yet, 2 is correct value, + but need to get from correct common def + This should be identified ASAP */ +#define WDI_DS_MAX_SUPPORTED_BSS 2 + +#define WDI_DS_INDEX_INVALID 0xFF + +/* Mem Pool resorce count per STA data type */ +typedef struct { + wpt_uint8 validIdx; + wpt_uint8 STAIndex; + wpt_uint32 numChunkReservedBySTA; + /* Mutex, is not needed for counter operation + since all TX Data frame operations will happen only TX thread + All of the TX data frame operations are serialized, no pre-emption will happen + This is just for place holder */ + wpt_mutex resourceCountLock; +} WDI_DS_BdMemPoolSTAType; + +typedef struct { + void *pVirtBaseAddress; + void *pPhysBaseAddress; + wpt_uint32 poolSize; + wpt_uint32 numChunks; + wpt_uint32 chunkSize; + wpt_uint32* AllocationBitmap; + WDI_DS_BdMemPoolSTAType numChunkSTA[WDI_DS_MAX_STA_ID + 1]; +} WDI_DS_BdMemPoolType; + +/* STA index associated with BSS index data type */ +typedef struct +{ + wpt_uint8 isUsed; + wpt_uint8 bssIdx; + wpt_uint8 staIdx; +} WDI_DS_staIdxPerBssIdxType; + +typedef struct +{ + void * pLoggingMbVirtAddress; + void * pLoggingMbPhysAddress; + WDI_DS_LoggingSessionType loggingSession; +} WDI_DS_LoggingMbType; + +WDI_Status WDI_DS_MemPoolCreate(WDI_DS_BdMemPoolType *memPool, wpt_uint8 chunkSize, wpt_uint8 numChunks); +void *WDI_DS_MemPoolAlloc(WDI_DS_BdMemPoolType *memPool, void **pPhysAddress, WDI_ResPoolType wdiResPool); +void WDI_DS_MemPoolFree(WDI_DS_BdMemPoolType *memPool, void *pVirtAddress, void *pPhysAddress); +void WDI_DS_MemPoolDestroy(WDI_DS_BdMemPoolType *memPool); + +WDI_Status WDI_DS_LoggingMbCreate(WDI_DS_LoggingMbType *pLoggingMailbox, wpt_uint8 size); +void WDI_DS_LoggingMbDestroy(WDI_DS_LoggingMbType *pLoggingMailbox); + +typedef struct +{ + void *pcontext; + void *pCallbackContext; + wpt_uint8 suspend; + WDI_DS_BdMemPoolType mgmtMemPool; + WDI_DS_BdMemPoolType dataMemPool; + WDI_DS_RxPacketCallback receiveFrameCB; + WDI_DS_TxCompleteCallback txCompleteCB; + WDI_DS_TxFlowControlCallback txResourceCB; + WDI_DS_RxLogCallback rxLogCB; + WDI_DS_staIdxPerBssIdxType staIdxPerBssIdxTable[WDI_DS_MAX_SUPPORTED_BSS]; + WDI_DS_LoggingMbType loggingMbContext; +} WDI_DS_ClientDataType; + +WPT_STATIC WPT_INLINE void WDI_GetBDPointers(wpt_packet *pFrame, void **pVirt, void **pPhys) +{ + *pVirt = WPAL_PACKET_GET_BD_POINTER(pFrame); + *pPhys = WPAL_PACKET_GET_BD_PHYS(pFrame); +} + + +WPT_STATIC WPT_INLINE void WDI_SetBDPointers(wpt_packet *pFrame, void *pVirt, void *pPhys) +{ + WPAL_PACKET_SET_BD_POINTER(pFrame, pVirt); + WPAL_PACKET_SET_BD_PHYS(pFrame, pPhys); +} + + +void +WDI_DS_PrepareBDHeader ( + wpt_packet* palPacket, + wpt_uint8 ucDisableHWFrmXtl, + wpt_uint8 alignment +); + +/** + @brief Returns the available number of resources (BD headers) + available for TX + + @param pMemPool: pointer to the BD memory pool + + @see + @return Result of the function call +*/ +wpt_uint32 WDI_DS_GetAvailableResCount(WDI_DS_BdMemPoolType *pMemPool); + +/** + @brief WDI_DS_GetreservedResCountPerSTA + Returns the Reserved number of resources (BD headers) + available for TX + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +wpt_uint32 WDI_DS_MemPoolGetRsvdResCountPerSTA(WDI_DS_BdMemPoolType *pMemPool, wpt_uint8 staId); + +/** + @brief WDI_DS_MemPoolAddSTA + Add NEW STA into mempool + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +WDI_Status WDI_DS_MemPoolAddSTA(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staIndex); + +/** + @brief WDI_DS_MemPoolAddSTA + Remove STA from mempool + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +WDI_Status WDI_DS_MemPoolDelSTA(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staIndex); + +/** + @brief Increase reserved TX resource count by specific STA + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +void WDI_DS_MemPoolIncreaseReserveCount(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staId); + +/** + @brief Decrease reserved TX resource count by specific STA + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +void WDI_DS_MemPoolDecreaseReserveCount(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staId); +#endif diff --git a/drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_bd.c b/drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_bd.c new file mode 100644 index 000000000000..b29efa728395 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_bd.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + * + * \file wlan_qct_dti_bd.c + * + * \brief Datapath utilities file. + * + * WLAN Device Abstraction layer External API for Dataservice + * DESCRIPTION + * This file contains the external API implemntation exposed by the + * wlan device abstarction layer module. + * + */ + +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_wdi_ds_i.h" +#include "wlan_qct_wdi_dts.h" +#include "wlan_qct_wdi_dp.h" +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_packet.h" + + + +/*========================================================================== + * + FUNCTION WDI_DS_PrepareBDHeader + + DESCRIPTION + function for preparing BD header before HAL processing. + + PARAMETERS + + IN +palPacket: PAL packet pointer + + +RETURN VALUE +No return. + +SIDE EFFECTS + +============================================================================*/ +void +WDI_DS_PrepareBDHeader (wpt_packet* palPacket, + wpt_uint8 ucDisableHWFrmXtl, wpt_uint8 alignment) +{ + void* pvBDHeader; + wpt_uint8 ucHeaderOffset; + wpt_uint8 ucHeaderLen; + wpt_uint8 ucQosEnabled; + wpt_uint8 ucWDSEnabled; + wpt_uint32 ucMpduLen; + wpt_uint32 ucPktLen; + WDI_DS_TxMetaInfoType *pTxMetadata; + + + /* Extract reuqired information from Metadata */ + pvBDHeader = WPAL_PACKET_GET_BD_POINTER(palPacket); + pTxMetadata = WDI_DS_ExtractTxMetaData(palPacket); + ucQosEnabled = pTxMetadata->qosEnabled; + ucWDSEnabled = pTxMetadata->fenableWDS; + + WPAL_PACKET_SET_BD_LENGTH(palPacket, WDI_TX_BD_HEADER_SIZE); + + /*--------------------------------------------------------------------- + Fill MPDU info fields: + - MPDU data start offset + - MPDU header start offset + - MPDU header length + - MPDU length - this is a 16b field - needs swapping + --------------------------------------------------------------------*/ + + if ( ucDisableHWFrmXtl ) { + ucHeaderOffset = WDI_TX_BD_HEADER_SIZE; + ucHeaderLen = WDI_802_11_HEADER_LEN; + if ( 0 != ucQosEnabled ) { + ucHeaderLen += WDI_802_11_HEADER_QOS_CTL; + } + if ( 0 != ucWDSEnabled) { + ucHeaderLen += WDI_802_11_HEADER_ADDR4_LEN; + } + } else { + ucHeaderOffset = WDI_TX_BD_HEADER_SIZE+WDI_802_11_MAX_HEADER_LEN; + ucHeaderLen = WDI_802_3_HEADER_LEN; + } + + WDI_TX_BD_SET_MPDU_HEADER_LEN( pvBDHeader, ucHeaderLen); + WDI_TX_BD_SET_MPDU_HEADER_OFFSET( pvBDHeader, ucHeaderOffset); + WDI_TX_BD_SET_MPDU_DATA_OFFSET( pvBDHeader, + ucHeaderOffset + ucHeaderLen + alignment); + + // pkt length from PAL API. Need to change in case of HW FT used + ucPktLen = wpalPacketGetLength( palPacket ); // This includes BD length + /** This is the length (in number of bytes) of the entire MPDU + (header and data). Note that the length INCLUDES FCS field. */ + ucMpduLen = ucPktLen - WPAL_PACKET_GET_BD_LENGTH( palPacket ); + WDI_TX_BD_SET_MPDU_LEN( pvBDHeader, ucMpduLen ); + + DTI_TRACE( DTI_TRACE_LEVEL_INFO, + "WLAN DTI: VALUES ARE HLen=%x Hoff=%x doff=%x len=%x ex=%d", + ucHeaderLen, ucHeaderOffset, + (ucHeaderOffset + ucHeaderLen + alignment), + pTxMetadata->fPktlen, alignment); + +}/* WDI_DS_PrepareBDHeader */ + +/*========================================================================== + * + FUNCTIONS WDI_DS_MemPoolXXX + + DESCRIPTION + APIs for managing the BD header memory pool + PARAMETERS + + IN +WDI_DS_BdMemPoolType: Memory pool pointer + + + +============================================================================*/ + +/* + * Create a memory pool which is DMA capabale + */ +WDI_Status WDI_DS_MemPoolCreate(WDI_DS_BdMemPoolType *memPool, wpt_uint8 chunkSize, + wpt_uint8 numChunks) +{ + wpt_uint8 staLoop; + + //Allocate all the max size and align them to a double word boundary. The first 8 bytes are control bytes. + memPool->numChunks = 0; + memPool->chunkSize = chunkSize + 16 - (chunkSize%8); + memPool->pVirtBaseAddress = wpalDmaMemoryAllocate((numChunks * memPool->chunkSize), + &(memPool->pPhysBaseAddress)); + + if( memPool->pVirtBaseAddress == 0) + return WDI_STATUS_E_FAILURE; + + memPool->AllocationBitmap = (wpt_uint32*)wpalMemoryAllocate( (numChunks/32 + 1) * sizeof(wpt_uint32)); + if( NULL == memPool->AllocationBitmap) + return WDI_STATUS_E_FAILURE; + wpalMemoryZero(memPool->AllocationBitmap, (numChunks/32+1)*sizeof(wpt_uint32)); + + //Initialize resource infor per STA + for(staLoop = 0; staLoop < WDI_DS_MAX_STA_ID; staLoop++) + { + memPool->numChunkSTA[staLoop].STAIndex = 0xFF; + memPool->numChunkSTA[staLoop].numChunkReservedBySTA = 0; + memPool->numChunkSTA[staLoop].validIdx = 0; + } + + return WDI_STATUS_SUCCESS; +} + +/* + * Destroy the memory pool + */ +void WDI_DS_MemPoolDestroy(WDI_DS_BdMemPoolType *memPool) +{ + //Allocate all the max size. + wpalDmaMemoryFree(memPool->pVirtBaseAddress); + wpalMemoryFree(memPool->AllocationBitmap); + wpalMemoryZero(memPool, sizeof(*memPool)); +} + +WDI_Status WDI_DS_LoggingMbCreate(WDI_DS_LoggingMbType *pLoggingMailbox, wpt_uint8 size) +{ + pLoggingMailbox->pLoggingMbVirtAddress = wpalDmaMemoryAllocate(size, + &(pLoggingMailbox->pLoggingMbPhysAddress)); + if (pLoggingMailbox->pLoggingMbVirtAddress == 0) + return WDI_STATUS_E_FAILURE; + return WDI_STATUS_SUCCESS; +} + +void *WDI_DS_GetLoggingMbPhyAddr(void *pContext) +{ + WDI_DS_ClientDataType *pClientData = WDI_DS_GetDatapathContext(pContext); + + return pClientData->loggingMbContext.pLoggingMbPhysAddress; +} + +void *WDI_DS_GetLoggingMbAddr(void *pContext) +{ + WDI_DS_ClientDataType *pClientData = pContext; + + return pClientData->loggingMbContext.pLoggingMbVirtAddress; +} + +void*WDI_DS_GetLoggingSession(void *pContext) +{ + WDI_DS_ClientDataType *pClientData = pContext; + + return &pClientData->loggingMbContext.loggingSession; +} + +void WDI_DS_LoggingMbDestroy(WDI_DS_LoggingMbType *pLoggingMailbox) +{ + wpalDmaMemoryFree(pLoggingMailbox->pLoggingMbVirtAddress); +} + +/* + * Allocate chunk memory + */ +WPT_STATIC WPT_INLINE int find_leading_zero_and_setbit(wpt_uint32 *bitmap, wpt_uint32 maxNumPool) +{ + wpt_uint32 i,j, word; + int ret_val = -1; + + for(i=0; i < (maxNumPool/32 + 1); i++){ + j = 0; + word = bitmap[i]; + for(j=0; j< 32; j++){ + if((word & 1) == 0) { + bitmap[i] |= (1 << j); + return((i<<5) + j); + } + word >>= 1; + } + } + return ret_val; +} + +void *WDI_DS_MemPoolAlloc(WDI_DS_BdMemPoolType *memPool, void **pPhysAddress, + WDI_ResPoolType wdiResPool) +{ + wpt_uint32 index; + void *pVirtAddress; + wpt_uint32 maxNumPool; + switch(wdiResPool) + { + case WDI_MGMT_POOL_ID: + maxNumPool = WDI_DS_HI_PRI_RES_NUM; + break; + case WDI_DATA_POOL_ID: + maxNumPool = WDI_DS_LO_PRI_RES_NUM; + break; + default: + return NULL; + } + + if(maxNumPool == memPool->numChunks) + { + return NULL; + } + //Find the leading 0 in the allocation bitmap + + if((index = find_leading_zero_and_setbit(memPool->AllocationBitmap, maxNumPool)) == -EPERM) + { + //DbgBreakPoint(); + DTI_TRACE( DTI_TRACE_LEVEL_INFO, "WDI_DS_MemPoolAlloc: index:%d(NULL), numChunks:%d", + index, memPool->numChunks ); + return NULL; + } + memPool->numChunks++; + // The first 8 bytes are reserved for internal use for control bits and hash. + pVirtAddress = (wpt_uint8 *)memPool->pVirtBaseAddress + (memPool->chunkSize * index) + 8; + *pPhysAddress = (wpt_uint8 *)memPool->pPhysBaseAddress + (memPool->chunkSize * index) + 8; + + DTI_TRACE( DTI_TRACE_LEVEL_INFO, "WDI_DS_MemPoolAlloc: index:%d, numChunks:%d", index, memPool->numChunks ); + + return pVirtAddress; + +} + +/* + * Free chunk memory + */ +void WDI_DS_MemPoolFree(WDI_DS_BdMemPoolType *memPool, void *pVirtAddress, void *pPhysAddress) +{ + wpt_uint32 index = + ((wpt_uint8 *)pVirtAddress - (wpt_uint8 *)memPool->pVirtBaseAddress - 8)/memPool->chunkSize; + wpt_uint32 word = memPool->AllocationBitmap[index/32]; + word &= ~(1<<(index%32)); + memPool->AllocationBitmap[index/32] = word; + memPool->numChunks--; + + //DbgPrint( "WDI_DS_MemPoolFree: index:%d, numChunks:%d", index, memPool->numChunks ); +} + + +/** + @brief Returns the available number of resources (BD headers) + available for TX + + @param pMemPool: pointer to the BD memory pool + + @see + @return Result of the function call +*/ +wpt_uint32 WDI_DS_GetAvailableResCount(WDI_DS_BdMemPoolType *pMemPool) +{ + return pMemPool->numChunks; +} + +/** + @brief WDI_DS_MemPoolAddSTA + Add NEW STA into mempool + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +WDI_Status WDI_DS_MemPoolAddSTA(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staIndex) +{ + if(memPool->numChunkSTA[staIndex].STAIndex != 0xFF) + { + /* Already using this slot? Do nothing */ + return WDI_STATUS_SUCCESS; + } + + memPool->numChunkSTA[staIndex].STAIndex = staIndex; + memPool->numChunkSTA[staIndex].numChunkReservedBySTA = 0; + memPool->numChunkSTA[staIndex].validIdx = 1; + return WDI_STATUS_SUCCESS; +} + +/** + @brief WDI_DS_MemPoolAddSTA + Remove STA from mempool + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + + @see + @return Result of the function call +*/ +WDI_Status WDI_DS_MemPoolDelSTA(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staIndex) +{ + if(memPool->numChunkSTA[staIndex].STAIndex == 0xFF) + { + /* Empty this slot? error, bad argument */ + return WDI_STATUS_E_FAILURE; + } + + memPool->numChunkSTA[staIndex].STAIndex = 0xFF; + memPool->numChunkSTA[staIndex].numChunkReservedBySTA = 0; + memPool->numChunkSTA[staIndex].validIdx = 0; + return WDI_STATUS_SUCCESS; +} + +/** + @brief Returns the reserved number of resources (BD headers) per STA + available for TX + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +wpt_uint32 WDI_DS_MemPoolGetRsvdResCountPerSTA(WDI_DS_BdMemPoolType *pMemPool, wpt_uint8 staId) +{ + return pMemPool->numChunkSTA[staId].numChunkReservedBySTA; +} + +/** + @brief Increase reserved TX resource count by specific STA + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +void WDI_DS_MemPoolIncreaseReserveCount(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staId) +{ + + if((memPool->numChunkSTA[staId].validIdx) && (staId < WDI_DS_MAX_STA_ID)) + { + memPool->numChunkSTA[staId].numChunkReservedBySTA++; + } + return; +} + +/** + @brief Decrease reserved TX resource count by specific STA + + @param pMemPool: pointer to the BD memory pool + @param staId STA ID + @see + @return Result of the function call +*/ +void WDI_DS_MemPoolDecreaseReserveCount(WDI_DS_BdMemPoolType *memPool, wpt_uint8 staId) +{ + if(0 == memPool->numChunkSTA[staId].numChunkReservedBySTA) + { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, + "SAT %d reserved resource count cannot be smaller than 0", staId ); + return; + } + + if((memPool->numChunkSTA[staId].validIdx) && (staId < WDI_DS_MAX_STA_ID)) + { + memPool->numChunkSTA[staId].numChunkReservedBySTA--; + } + return; +} diff --git a/drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_ds.c b/drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_ds.c new file mode 100644 index 000000000000..ac4512a83cd8 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/DP/src/wlan_qct_wdi_ds.c @@ -0,0 +1,566 @@ +/* + * Copyright (c) 2012-2013, 2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + * + * \file wlan_qct_wdi_ds.c + * + * \brief define Dataservice API + * + * WLAN Device Abstraction layer External API for Dataservice + * DESCRIPTION + * This file contains the external API implemntation exposed by the + * wlan device abstarction layer module. + * + */ + + +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_i.h" +#include "wlan_qct_wdi_ds.h" +#include "wlan_qct_wdi_ds_i.h" +#include "wlan_qct_wdi_dts.h" +#include "wlan_qct_wdi_dp.h" +#include "wlan_qct_wdi_sta.h" + + + + +/* DAL registration function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * pfnTxCompleteCallback:Callback function that is to be invoked to return + * packets which have been transmitted. + * pfnRxPacketCallback:Callback function that is to be invoked to deliver + * packets which have been received + * pfnTxFlowControlCallback:Callback function that is to be invoked to + * indicate/clear congestion. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +WDI_Status WDI_DS_Register( void *pContext, + WDI_DS_TxCompleteCallback pfnTxCompleteCallback, + WDI_DS_RxPacketCallback pfnRxPacketCallback, + WDI_DS_TxFlowControlCallback pfnTxFlowControlCallback, + WDI_DS_RxLogCallback pfnRxLogCallback, + void *pCallbackContext) +{ + WDI_DS_ClientDataType *pClientData; + wpt_uint8 bssLoop; + + // Do Sanity checks + if (NULL == pContext || + NULL == pCallbackContext || + NULL == pfnTxCompleteCallback || + NULL == pfnRxPacketCallback || + NULL == pfnTxFlowControlCallback) { + return WDI_STATUS_E_FAILURE; + } + + pClientData = (WDI_DS_ClientDataType *)WDI_DS_GetDatapathContext(pContext); + if (NULL == pClientData) + { + return WDI_STATUS_MEM_FAILURE; + } + + // Store callbacks in client structure + pClientData->pcontext = pContext; + pClientData->receiveFrameCB = pfnRxPacketCallback; + pClientData->txCompleteCB = pfnTxCompleteCallback; + pClientData->txResourceCB = pfnTxFlowControlCallback; + pClientData->rxLogCB = pfnRxLogCallback; + pClientData->pCallbackContext = pCallbackContext; + + for(bssLoop = 0; bssLoop < WDI_DS_MAX_SUPPORTED_BSS; bssLoop++) + { + pClientData->staIdxPerBssIdxTable[bssLoop].isUsed = 0; + pClientData->staIdxPerBssIdxTable[bssLoop].bssIdx = WDI_DS_INDEX_INVALID; + pClientData->staIdxPerBssIdxTable[bssLoop].staIdx = WDI_DS_INDEX_INVALID; + } + return WDI_STATUS_SUCCESS; +} + + + +/* DAL Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * pFrame:Refernce to PAL frame. + * more: Does the invokee have more than one packet pending? + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxPacket(void *pContext, + wpt_packet *pFrame, + wpt_boolean more) +{ + WDI_DS_ClientDataType *pClientData; + wpt_uint8 ucSwFrameTXXlation; + wpt_uint8 ucUP; + wpt_uint8 ucTypeSubtype; + wpt_uint8 isEapol; + wpt_uint8 isArp; + wpt_uint8 alignment; + wpt_uint32 ucTxFlag; + wpt_uint8 ucProtMgmtFrame; + wpt_uint8* pSTAMACAddress; + wpt_uint8* pAddr2MACAddress; + WDI_DS_TxMetaInfoType *pTxMetadata; + void *physBDHeader, *pvBDHeader; + wpt_uint8 ucType; + WDI_DS_BdMemPoolType *pMemPool; + wpt_uint8 ucBdPoolType; + wpt_uint8 staId; + WDI_Status wdiStatus; + + // Do Sanity checks + if (NULL == pContext) + { + return WDI_STATUS_E_FAILURE; + } + + pClientData = (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + if (NULL == pClientData || pClientData->suspend) + { + return WDI_STATUS_E_FAILURE; + } + + // extract metadata from PAL packet + pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); + ucSwFrameTXXlation = pTxMetadata->fdisableFrmXlt; + ucTypeSubtype = pTxMetadata->typeSubtype; + ucUP = pTxMetadata->fUP; + isEapol = pTxMetadata->isEapol; + isArp = pTxMetadata->isArp; + ucTxFlag = pTxMetadata->txFlags; + ucProtMgmtFrame = pTxMetadata->fProtMgmtFrame; + pSTAMACAddress = &(pTxMetadata->fSTAMACAddress[0]); + pAddr2MACAddress = &(pTxMetadata->addr2MACAddress[0]); + + /*------------------------------------------------------------------------ + Get type and subtype of the frame first + ------------------------------------------------------------------------*/ + ucType = (ucTypeSubtype & WDI_FRAME_TYPE_MASK) >> WDI_FRAME_TYPE_OFFSET; + switch(ucType) + { + case WDI_MAC_DATA_FRAME: +#ifdef FEATURE_WLAN_TDLS + /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) + Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() + should take managment path. As of today, only TDLS feature has special data frame + which needs to be treated as mgmt. + */ + if((!pTxMetadata->isEapol) && + ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) +#else + if(!pTxMetadata->isEapol) +#endif + { + pMemPool = &(pClientData->dataMemPool); + ucBdPoolType = WDI_DATA_POOL_ID; + break; + } + // intentional fall-through to handle eapol packet as mgmt + case WDI_MAC_MGMT_FRAME: + pMemPool = &(pClientData->mgmtMemPool); + ucBdPoolType = WDI_MGMT_POOL_ID; + break; + default: + return WDI_STATUS_E_FAILURE; + } + + // Allocate BD header from pool + pvBDHeader = WDI_DS_MemPoolAlloc(pMemPool, &physBDHeader, ucBdPoolType); + if(NULL == pvBDHeader) + return WDI_STATUS_E_FAILURE; + + WDI_SetBDPointers(pFrame, pvBDHeader, physBDHeader); + + alignment = 0; + WDI_DS_PrepareBDHeader(pFrame, ucSwFrameTXXlation, alignment); + if (pTxMetadata->isEapol) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "Packet Length is %d\n", pTxMetadata->fPktlen); + } + + if (pTxMetadata->isArp) + { + WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s :Transmitting ARP packet",__func__); + } + + wdiStatus = WDI_FillTxBd(pContext, ucTypeSubtype, pSTAMACAddress, pAddr2MACAddress, + &ucUP, 1, pvBDHeader, ucTxFlag /* No ACK */, ucProtMgmtFrame, 0, isEapol, isArp, + &staId, pTxMetadata->txBdToken); + + if(WDI_STATUS_SUCCESS != wdiStatus) + { + WDI_DS_MemPoolFree(pMemPool, pvBDHeader, physBDHeader); + return wdiStatus; + } + + pTxMetadata->staIdx = staId; + + // Send packet to transport layer. + if(eWLAN_PAL_STATUS_SUCCESS !=WDTS_TxPacket(pContext, pFrame)){ + WDI_DS_MemPoolFree(pMemPool, pvBDHeader, physBDHeader); + return WDI_STATUS_E_FAILURE; + } + + /* resource count only for data packet */ + // EAPOL packet doesn't use data mem pool if being treated as higher priority +#ifdef FEATURE_WLAN_TDLS + /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) + Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() + should take managment path. As of today, only TDLS feature has special data frame + which needs to be treated as mgmt. + */ + if((WDI_MAC_DATA_FRAME == ucType) && (!pTxMetadata->isEapol) && ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) +#else + if(WDI_MAC_DATA_FRAME == ucType && (!pTxMetadata->isEapol)) +#endif + { + WDI_DS_MemPoolIncreaseReserveCount(pMemPool, staId); + } + return WDI_STATUS_SUCCESS; +} + + +/* DAL Transmit Complete function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * ucTxResReq:TX resource number required by TL + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxComplete(void *pContext, wpt_uint32 ucTxResReq) +{ + // Do Sanity checks + if(NULL == pContext) + return WDI_STATUS_E_FAILURE; + + // Send notification to transport layer. + if(eWLAN_PAL_STATUS_SUCCESS !=WDTS_CompleteTx(pContext, ucTxResReq)) + { + return WDI_STATUS_E_FAILURE; + } + + return WDI_STATUS_SUCCESS; +} + +/* DAL Suspend Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxSuspend(void *pContext) +{ + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + pClientData->suspend = 1; + + return WDI_STATUS_SUCCESS; + +} + + +/* DAL Resume Transmit function. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ + + +WDI_Status WDI_DS_TxResume(void *pContext) +{ + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + + pClientData->suspend = 0; + + return WDI_STATUS_SUCCESS; +} + +/* DAL Get Available Resource Count. + * This is the number of free descririptor in DXE + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * wdiResPool: - identifier of resource pool + * Return Value: number of resources available + * This is the number of free descririptor in DXE + * + */ + +wpt_uint32 WDI_GetAvailableResCount(void *pContext,WDI_ResPoolType wdiResPool) +{ + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + + switch(wdiResPool) + { + case WDI_MGMT_POOL_ID: + return (WDI_DS_HI_PRI_RES_NUM - 2*WDI_DS_GetAvailableResCount(&pClientData->mgmtMemPool)); + case WDI_DATA_POOL_ID: + return WDTS_GetFreeTxDataResNumber(pContext); + default: + return 0; + } +} + +/* DAL Get resrved Resource Count per STA. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * wdiResPool: - identifier of resource pool + * staId: STA ID + * Return Value: number of resources reserved per STA + * + */ +wpt_uint32 WDI_DS_GetReservedResCountPerSTA(void *pContext,WDI_ResPoolType wdiResPool, wpt_uint8 staId) +{ + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + switch(wdiResPool) + { + case WDI_MGMT_POOL_ID: + return WDI_DS_MemPoolGetRsvdResCountPerSTA(&pClientData->mgmtMemPool, staId); + case WDI_DATA_POOL_ID: + return WDI_DS_MemPoolGetRsvdResCountPerSTA(&pClientData->dataMemPool, staId); + default: + return 0; + } +} + +/* DAL STA info add into memPool. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * staId: STA ID + * Return Value: number of resources reserved per STA + * + */ +WDI_Status WDI_DS_AddSTAMemPool(void *pContext, wpt_uint8 staIndex) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + + status = WDI_DS_MemPoolAddSTA(&pClientData->mgmtMemPool, staIndex); + if(WDI_STATUS_SUCCESS != status) + { + /* Add STA into MGMT memPool Fail */ + return status; + } + + status = WDI_DS_MemPoolAddSTA(&pClientData->dataMemPool, staIndex); + if(WDI_STATUS_SUCCESS != status) + { + /* Add STA into DATA memPool Fail */ + return status; + } + + return WDI_STATUS_SUCCESS; +} + +/* DAL STA info del from memPool. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * staId: STA ID + * Return Value: number of resources reserved per STA + * + */ +WDI_Status WDI_DS_DelSTAMemPool(void *pContext, wpt_uint8 staIndex) +{ + WDI_Status status = WDI_STATUS_SUCCESS; + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) WDI_DS_GetDatapathContext(pContext); + + status = WDI_DS_MemPoolDelSTA(&pClientData->mgmtMemPool, staIndex); + if(WDI_STATUS_SUCCESS != status) + { + /* Del STA from MGMT memPool Fail */ + return status; + } + status = WDI_DS_MemPoolDelSTA(&pClientData->dataMemPool, staIndex); + if(WDI_STATUS_SUCCESS != status) + { + /* Del STA from DATA memPool Fail */ + return status; + } + return WDI_STATUS_SUCCESS; +} + +/* DAL Set STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_SetStaIdxPerBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 staIdx) +{ + WDI_DS_ClientDataType *pClientData; + wpt_uint8 bssLoop; + + pClientData = (WDI_DS_ClientDataType *)WDI_DS_GetDatapathContext(pContext); + for (bssLoop = 0; bssLoop < WDI_DS_MAX_SUPPORTED_BSS; bssLoop++) + { + if ((pClientData->staIdxPerBssIdxTable[bssLoop].isUsed) && + (bssIdx == pClientData->staIdxPerBssIdxTable[bssLoop].bssIdx) && + (staIdx == pClientData->staIdxPerBssIdxTable[bssLoop].staIdx)) + { + return WDI_STATUS_SUCCESS; + } + + if (0 == pClientData->staIdxPerBssIdxTable[bssLoop].isUsed) + { + pClientData->staIdxPerBssIdxTable[bssLoop].bssIdx = bssIdx; + pClientData->staIdxPerBssIdxTable[bssLoop].staIdx = staIdx; + pClientData->staIdxPerBssIdxTable[bssLoop].isUsed = 1; + return WDI_STATUS_SUCCESS; + } + } + + /* Could not find empty slot */ + return WDI_STATUS_E_FAILURE; +} + +/* DAL Get STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_GetStaIdxFromBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 *staIdx) +{ + WDI_DS_ClientDataType *pClientData; + wpt_uint8 bssLoop; + + pClientData = (WDI_DS_ClientDataType *)WDI_DS_GetDatapathContext(pContext); + for(bssLoop = 0; bssLoop < WDI_DS_MAX_SUPPORTED_BSS; bssLoop++) + { + if(bssIdx == pClientData->staIdxPerBssIdxTable[bssLoop].bssIdx) + { + /* Found BSS index from slot */ + *staIdx = pClientData->staIdxPerBssIdxTable[bssLoop].staIdx; + return WDI_STATUS_SUCCESS; + } + } + + /* Could not find associated STA index with BSS index */ + return WDI_STATUS_E_FAILURE; +} + +/* DAL Clear STA index associated with BSS index. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * bssIdx: BSS index + * staId: STA index associated with BSS index + * Return Status: Found empty slot + * + */ +WDI_Status WDI_DS_ClearStaIdxPerBssIdx(void *pContext, wpt_uint8 bssIdx, wpt_uint8 staIdx) +{ + WDI_DS_ClientDataType *pClientData; + wpt_uint8 bssLoop; + + pClientData = (WDI_DS_ClientDataType *)WDI_DS_GetDatapathContext(pContext); + for(bssLoop = 0; bssLoop < WDI_DS_MAX_SUPPORTED_BSS; bssLoop++) + { + if((bssIdx == pClientData->staIdxPerBssIdxTable[bssLoop].bssIdx) && + (staIdx == pClientData->staIdxPerBssIdxTable[bssLoop].staIdx)) + { + pClientData->staIdxPerBssIdxTable[bssLoop].bssIdx = WDI_DS_INDEX_INVALID; + pClientData->staIdxPerBssIdxTable[bssLoop].staIdx = WDI_DS_INDEX_INVALID; + pClientData->staIdxPerBssIdxTable[bssLoop].isUsed = 0; + return WDI_STATUS_SUCCESS; + } + } + + /* Could not find associated STA index with BSS index */ + return WDI_STATUS_E_FAILURE; +} + +/* @brief: WDI_DS_GetTrafficStats + * This function should be invoked to fetch the current stats + * Parameters: + * pStats:Pointer to the collected stats + * len: length of buffer pointed to by pStats + * Return Status: None + */ +void WDI_DS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len) +{ + return WDTS_GetTrafficStats(pStats, len); +} + +/* @brief: WDI_DS_DeactivateTrafficStats + * This function should be invoked to deactivate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDI_DS_DeactivateTrafficStats(void) +{ + return WDTS_DeactivateTrafficStats(); +} + +/* @brief: WDI_DS_ActivateTrafficStats + * This function should be invoked to activate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDI_DS_ActivateTrafficStats(void) +{ + return WDTS_ActivateTrafficStats(); +} + +/* @brief: WDI_DS_ClearTrafficStats + * This function should be invoked to clear all past stats + * Parameters: None + * Return Status: None + */ +void WDI_DS_ClearTrafficStats(void) +{ + return WDTS_ClearTrafficStats(); +} + diff --git a/drivers/staging/prima/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h b/drivers/staging/prima/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h new file mode 100644 index 000000000000..daf87b06ded1 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/TRP/CTS/inc/wlan_qct_wdi_cts.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2012-2013,2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_WDI_CTS_H +#define WLAN_QCT_WDI_CTS_H + +/*=========================================================================== + + W L A N C O N T R O L T R A N S P O R T S E R V I C E + E X T E R N A L A P I + + +DESCRIPTION + This file contains the external API exposed by the wlan control transport + service module. + + +===========================================================================*/ + + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + +when who what, where, why +-------- --- ---------------------------------------------------------- +08/04/10 mss Created module. + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_pal_type.h" + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + #ifdef __cplusplus + extern "C" { + #endif + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/* Control Transport Service Handle Type*/ +typedef void* WCTS_HandleType; + +/*--------------------------------------------------------------------------- + WCTS_NotifyEventType + ---------------------------------------------------------------------------*/ +typedef enum +{ + WCTS_EVENT_OPEN, + WCTS_EVENT_CLOSE, + WCTS_EVENT_MAX +} WCTS_NotifyEventType; + +struct WdiSmdStats +{ + int smd_event_data; + int smd_event_open; + int smd_event_close; + int smd_event_status; + int smd_event_reopen_ready; + int smd_event_err; +}; + +/*---------------------------------------------------------------------------- + * WDI callback types + *--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- + WCTS_NotifyCBType + + DESCRIPTION + + This callback is invoked by the control transport when it wishes to send + up a notification like the ones mentioned above. + + PARAMETERS + + IN + wctsHandle: handle to the control transport service + wctsEvent: the event being notified + wctsNotifyCBData: the callback data of the user + + + RETURN VALUE + None +---------------------------------------------------------------------------*/ +typedef void (*WCTS_NotifyCBType) (WCTS_HandleType wctsHandle, + WCTS_NotifyEventType wctsEvent, + void* wctsNotifyCBData); + +/*--------------------------------------------------------------------------- + WCTS_RxMsgCBType + + DESCRIPTION + + This callback is invoked by the control transport when it wishes to send + up a packet received over the bus. Upon return of Rx callback, the ownership + of the message belongs to the CT and this one is free to deallocate any + buffer that was used to get this message. If WDI wishes to maintain the + information beyond the lifetime of the call, it must make a copy of it. + + PARAMETERS + + IN + wctsHandle: handle to the control transport service + pMsg: the packet + uLen: the packet length + wctsRxMsgCBData: the callback data of the user + + + RETURN VALUE + None +---------------------------------------------------------------------------*/ +typedef void (*WCTS_RxMsgCBType) (WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen, + void* wctsRxMsgCBData); + +/*--------------------------------------------------------------------------- + WCTS Transport Callbacks holder type + ---------------------------------------------------------------------------*/ +typedef struct +{ + WCTS_NotifyCBType wctsNotifyCB; + void* wctsNotifyCBData; + WCTS_RxMsgCBType wctsRxMsgCB; + void* wctsRxMsgCBData; +} WCTS_TransportCBsType; + +/*======================================================================== + * Function Declarations and Documentation + ==========================================================================*/ +/** + @brief This function is used by the DAL Core to initialize the Control + Transport for processing. It must be called prior to calling any + other APIs of the Control Transport. + + + @param szName: unique name for the channel that is to be opened + uSize: size of the channel that must be opened (should fit the + largest size of packet that the Dal Core wishes to send) + wctsCBs: a list of callbacks that the CT needs to use to send + notification and messages back to DAL + + @see + @return A handle that must be used for further communication with the CTS. + This is an opaque structure for the caller and it will be used in + all communications to and from the CTS. + +*/ +WCTS_HandleType +WCTS_OpenTransport +( + const wpt_uint8* szName, + wpt_uint32 uSize, + WCTS_TransportCBsType* wctsCBs +); + +/** + @brief This function is used by the DAL Core to to close the + Control Transport when its services are no longer + needed. Full close notification will be receive + asynchronously on the notification callback + registered on Open + + + @param wctsHandlehandle: received upon open + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_CloseTransport +( + WCTS_HandleType wctsHandle +); + +/** + @brief This function is used by the DAL Core to to send a + message over to the WLAN sub-system. + + Once a buffer has been passed into the Send Message + API, CT takes full ownership of it and it is responsible for + freeing the associated resources. (This prevents a memcpy in + case of a deffered write) + + The messages transported through the CT on both RX and TX are + flat memory buffers that can be accessed and manipulated + through standard memory functions. + + @param wctsHandlehandle: received upon open + pMsg: the message to be sent + uLen: the length of the message + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_SendMessage +( + WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen +); + +/** + @brief This helper function is used to clean up the pending + messages in the transport queue + + @param wctsHandlehandle: transport handle + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_ClearPendingQueue +( + WCTS_HandleType wctsHandle +); + +void WCTS_Dump_Smd_status(void); +#endif /* #ifndef WLAN_QCT_WDI_CTS_H */ diff --git a/drivers/staging/prima/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c b/drivers/staging/prima/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c new file mode 100644 index 000000000000..ddf4d4d71a5a --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/TRP/CTS/src/wlan_qct_wdi_cts.c @@ -0,0 +1,1003 @@ +/* + * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + + W L A N _ Q C T _ C T S . C + + OVERVIEW: + + This software unit holds the implementation of the WLAN Control Transport + Service Layer. + + The functions externalized by this module are to be called by the DAL Core + that wishes to use a platform agnostic API to communicate with the WLAN SS. + + DEPENDENCIES: + + Are listed for each API below. + + +===========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header$$DateTime$$Author$ + + + when who what, where, why + ---------- --- -------------------------------------------------------- + 2011-02-28 jtj Linux/Android implementation which utilizes SMD + 2010-08-09 mss Created module + +===========================================================================*/ + + + +/*=========================================================================== + + INCLUDE FILES FOR MODULE + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include "wlan_qct_wdi_cts.h" +#include "wlan_qct_pal_msg.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_os_list.h" +#include "wlan_qct_wdi.h" +#include "wlan_qct_wdi_i.h" +#ifdef CONFIG_ANDROID +#ifdef EXISTS_MSM_SMD +#include +#else +#include +#endif +#include +#else +#include "msm_smd.h" +#endif + +/* Global context for CTS handle, it is required to keep this + * transport open during SSR shutdown */ +static WCTS_HandleType gwctsHandle; +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/* Magic value to validate a WCTS CB (value is little endian ASCII: WCTS */ +#define WCTS_CB_MAGIC 0x53544357 + +/* time to wait for SMD channel to open (in msecs) */ +#define WCTS_SMD_OPEN_TIMEOUT 5000 + +/* time to wait for SMD channel to close (in msecs) */ +#define WCTS_SMD_CLOSE_TIMEOUT 5000 + +/* Global Variable for WDI SMD stats */ +static struct WdiSmdStats gWdiSmdStats; +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------- + WCTS_StateType + ---------------------------------------------------------------------------*/ +typedef enum +{ + WCTS_STATE_CLOSED, /* Closed */ + WCTS_STATE_OPEN_PENDING, /* Waiting for the OPEN event from SMD */ + WCTS_STATE_OPEN, /* Open event received from SMD */ + WCTS_STATE_DEFERRED, /* Write pending, SMD chennel is full */ + WCTS_STATE_REM_CLOSED, /* Remote end closed the SMD channel */ + WCTS_STATE_MAX +} WCTS_StateType; + +/*--------------------------------------------------------------------------- + Control Transport Control Block Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + WCTS_NotifyCBType wctsNotifyCB; + void* wctsNotifyCBData; + WCTS_RxMsgCBType wctsRxMsgCB; + void* wctsRxMsgCBData; + WCTS_StateType wctsState; + vos_spin_lock_t wctsStateLock; + smd_channel_t* wctsChannel; + wpt_list wctsPendingQueue; + wpt_uint32 wctsMagic; + wpt_msg wctsOpenMsg; + wpt_msg wctsDataMsg; + wpt_event wctsEvent; +} WCTS_ControlBlockType; + +/*--------------------------------------------------------------------------- + WDI CTS Buffer Type + ---------------------------------------------------------------------------*/ +typedef struct +{ + /*Node for linking pending buffers into a linked list */ + wpt_list_node node; + + /*Buffer associated with the request */ + void* pBuffer; + + /*Buffer Size*/ + int bufferSize; + +} WCTS_BufferType; + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + + + +/** + @brief Callback function for serializing WCTS Open + processing in the control context + @param + + pMsg - pointer to the message + + @see + @return void +*/ +static void +WCTS_PALOpenCallback +( + wpt_msg *pMsg +) +{ + WCTS_ControlBlockType* pWCTSCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /* extract our context from the message */ + pWCTSCb = pMsg->pContext; + + /*-------------------------------------------------------------------- + Sanity check + --------------------------------------------------------------------*/ + if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALOpenCallback: Invalid parameters received."); + return; + } + + if (WCTS_STATE_OPEN_PENDING != pWCTSCb->wctsState) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALOpenCallback: Invoke from invalid state %d.", + pWCTSCb->wctsState); + return; + } + + /* notified registered client that the channel is open */ + pWCTSCb->wctsState = WCTS_STATE_OPEN; + pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, + WCTS_EVENT_OPEN, + pWCTSCb->wctsNotifyCBData); + + /* signal event for WCTS_OpenTransport to proceed */ + wpalEventSet(&pWCTSCb->wctsEvent); + +}/*WCTS_PALOpenCallback*/ + + + +/** + @brief Callback function for serializing WCTS Read + processing in the control context + + @param pWCTSCb WCTS Control Block + + @see + @return void +*/ +static void +WCTS_PALReadCallback +( + WCTS_ControlBlockType* pWCTSCb +) +{ + void* buffer; + int packet_size; + int available; + int bytes_read; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*-------------------------------------------------------------------- + Sanity check + --------------------------------------------------------------------*/ + if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALReadCallback: Invalid parameter received."); + return; + } + + /* iterate until no more packets are available */ + while (1) { + /* check the length of the next packet */ + packet_size = smd_cur_packet_size(pWCTSCb->wctsChannel); + if (0 == packet_size) { + /* No more data to be read */ + return; + } + + /* Check how much of the data is available */ + available = smd_read_avail(pWCTSCb->wctsChannel); + if (available < packet_size) { + /* Entire packet not yet ready to be read -- + There will be another notification when it is ready */ + return; + } + + buffer = wpalMemoryAllocate(packet_size); + if (NULL == buffer) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALReadCallback: Memory allocation failure"); + WPAL_ASSERT(0); + return; + } + + bytes_read = smd_read(pWCTSCb->wctsChannel, + buffer, + packet_size); + + if (bytes_read != packet_size) { + /*Some problem, do not forward it to WDI.*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALReadCallback: Failed to read data from SMD"); + wpalMemoryFree(buffer); + WPAL_ASSERT(0); + return; + } + + /* forward the message to the registered handler */ + pWCTSCb->wctsRxMsgCB((WCTS_HandleType)pWCTSCb, + buffer, + packet_size, + pWCTSCb->wctsRxMsgCBData); + + /* Free the allocated buffer*/ + wpalMemoryZero(buffer, bytes_read); + wpalMemoryFree(buffer); + } + +} /*WCTS_PALReadCallback*/ + + + +/** + @brief Callback function for serializing WCTS Write + processing in the control context + + @param pWCTSCb WCTS Control Block + + @see + @return void +*/ +static void +WCTS_PALWriteCallback +( + WCTS_ControlBlockType* pWCTSCb +) +{ + wpt_list_node* pNode; + WCTS_BufferType* pBufferQueue; + void* pBuffer; + int len; + int available; + int written; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*-------------------------------------------------------------------- + Sanity check + --------------------------------------------------------------------*/ + if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALWriteCallback: Invalid parameter received."); + return; + } + + /* if we are not deferred, then there are no pending packets */ + if (WCTS_STATE_DEFERRED != pWCTSCb->wctsState) { + return; + } + + /* Keep sending deferred messages as long as there is room in + the channel. Note that we initially peek at the head of the + list to access the parameters for the next message; we don't + actually remove the next message from the deferred list until + we know the channel can handle it */ + while (eWLAN_PAL_STATUS_SUCCESS == + wpal_list_peek_front(&pWCTSCb->wctsPendingQueue, &pNode)) { + pBufferQueue = container_of(pNode, WCTS_BufferType, node); + pBuffer = pBufferQueue->pBuffer; + len = pBufferQueue->bufferSize; + + available = smd_write_avail(pWCTSCb->wctsChannel); + if (available < len) { + /* channel has no room for the next packet so we are done */ + return; + } + + /* there is room for the next message, so we can now remove + it from the deferred message queue and send it */ + wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode); + + /* note that pNode will be the same as when we peeked, so + there is no need to update pBuffer or len */ + + written = smd_write(pWCTSCb->wctsChannel, pBuffer, len); + if (written != len) { + /* Something went wrong */ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_PALWriteCallback: channel write failure"); + + /* we were unable to send the message that was at the head + of the deferred list. there is nothing else we can do + other than drop it, so we will just fall through to the + "success" processing. + hopefully the client can recover from this since there is + nothing else we can do here */ + } + + /* whether we had success or failure, reclaim all memory */ + wpalMemoryZero(pBuffer, len); + wpalMemoryFree(pBuffer); + wpalMemoryFree(pBufferQueue); + + /* we'll continue to iterate until the channel is full or all + of the deferred messages have been sent */ + } + + /* if we've exited the loop, then we have drained the deferred queue. + set the state to indicate we are no longer deferred, and turn off + the remote read interrupt */ + pWCTSCb->wctsState = WCTS_STATE_OPEN; + smd_disable_read_intr(pWCTSCb->wctsChannel); + +} /*WCTS_PALWriteCallback*/ + + + +/** + @brief Callback function for serializing SMD DATA Event + processing in the control context + @param + + pMsg - pointer to the message + + @see + @return void +*/ +static void +WCTS_PALDataCallback +( + wpt_msg *pMsg +) +{ + WCTS_ControlBlockType* pWCTSCb; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /* extract our context from the message */ + pWCTSCb = pMsg->pContext; + + /* process any incoming messages */ + WCTS_PALReadCallback(pWCTSCb); + + /* send any deferred messages */ + WCTS_PALWriteCallback(pWCTSCb); + +} /*WCTS_PALDataCallback*/ + +/** + @brief This helper function is used to clean up the pending + messages in the transport queue + + @param wctsHandlehandle: transport handle + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_ClearPendingQueue +( + WCTS_HandleType wctsHandle +) +{ + WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle; + wpt_list_node* pNode = NULL; + WCTS_BufferType* pBufferQueue = NULL; + void* pBuffer = NULL; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_ClearPendingQueue: Invalid parameters received."); + return eWLAN_PAL_STATUS_E_INVAL; + } + + /*Free the buffers in the pending queue.*/ + while (eWLAN_PAL_STATUS_SUCCESS == + wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) { + pBufferQueue = container_of(pNode, WCTS_BufferType, node); + pBuffer = pBufferQueue->pBuffer; + wpalMemoryFree(pBuffer); + wpalMemoryFree(pBufferQueue); + } + return eWLAN_PAL_STATUS_SUCCESS; + +}/*WCTS_ClearPendingQueue*/ + + +/** + * Notification callback when SMD needs to communicate asynchronously with + * the client. + * + * This callback function may be called from interrupt context; clients must + * not block or call any functions that block. + * + * @param[in] data The user-supplied data provided to smd_named_open_on_edge() + * @param[in] event The event that occurred + * + * @return void + */ + +static void +WCTS_NotifyCallback +( + void *data, + unsigned event +) +{ + wpt_msg *palMsg; + WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) data; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*-------------------------------------------------------------------- + Sanity check + --------------------------------------------------------------------*/ + if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Received unexpected SMD event %u", + __func__, event); + + /* TODO_PRIMA what error recovery options do we have? */ + return; + } + + /* Serialize processing in the control thread */ + switch (event) { + case SMD_EVENT_OPEN: + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_OPEN from SMD", __func__); + /* If the prev state was 'remote closed' then it is a Riva 'restart', + * subsystem restart re-init + */ + if (WCTS_STATE_REM_CLOSED == pWCTSCb->wctsState) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_OPEN in WCTS_STATE_REM_CLOSED state", + __func__); + /* call subsystem restart re-init function */ + wpalDriverReInit(); + return; + } + gWdiSmdStats.smd_event_open++; + palMsg = &pWCTSCb->wctsOpenMsg; + break; + + case SMD_EVENT_DATA: + if (WCTS_STATE_REM_CLOSED == pWCTSCb->wctsState) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: received SMD data when the state is remote closed ", + __func__); + /* we should not be getting any data now */ + return; + } + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_DATA from SMD", __func__); + palMsg = &pWCTSCb->wctsDataMsg; + gWdiSmdStats.smd_event_data++; + break; + + case SMD_EVENT_CLOSE: + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_CLOSE from SMD", __func__); + /* SMD channel was closed from the remote side, + * this would happen only when Riva crashed and SMD is + * closing the channel on behalf of Riva */ + vos_spin_lock_acquire(&pWCTSCb->wctsStateLock); + pWCTSCb->wctsState = WCTS_STATE_REM_CLOSED; + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_CLOSE WLAN driver going down now", + __func__); + vos_spin_lock_release(&pWCTSCb->wctsStateLock); + + /* subsystem restart: shutdown */ + wpalDriverShutdown(); + gWdiSmdStats.smd_event_close++; + return; + + case SMD_EVENT_STATUS: + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_STATUS from SMD", __func__); + gWdiSmdStats.smd_event_status++; + return; + + case SMD_EVENT_REOPEN_READY: + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "%s: received SMD_EVENT_REOPEN_READY from SMD", __func__); + + /* unlike other events which occur when our kernel threads are + running, this one is received when the threads are closed and + the rmmod thread is waiting. so just unblock that thread */ + wpalEventSet(&pWCTSCb->wctsEvent); + gWdiSmdStats.smd_event_reopen_ready++; + return; + + default: + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Unexpected event %u received from SMD", + __func__, event); + gWdiSmdStats.smd_event_err++; + + return; + } + + /* serialize this event */ + wpalPostCtrlMsg(WDI_GET_PAL_CTX(), palMsg); + +} /*WCTS_NotifyCallback*/ + + + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions + * -------------------------------------------------------------------------*/ + + +/** + @brief This function is used by the DAL Core to initialize the Control + Transport for processing. It must be called prior to calling any + other APIs of the Control Transport. + + + @param szName: unique name for the channel that is to be opened + uSize: size of the channel that must be opened (should fit the + largest size of packet that the Dal Core wishes to send) + wctsCBs: a list of callbacks that the CT needs to use to send + notification and messages back to DAL + + @see + @return A handle that must be used for further communication with the CTS. + This is an opaque structure for the caller and it will be used in + all communications to and from the CTS. + +*/ +WCTS_HandleType +WCTS_OpenTransport +( + const wpt_uint8* szName, + wpt_uint32 uSize, + WCTS_TransportCBsType* wctsCBs +) +{ + WCTS_ControlBlockType* pWCTSCb; + wpt_status status; + int smdstatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*--------------------------------------------------------------------- + Sanity check + ---------------------------------------------------------------------*/ + if ((NULL == wctsCBs) || (NULL == szName) || + (NULL == wctsCBs->wctsNotifyCB) || (NULL == wctsCBs->wctsRxMsgCB)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_OpenTransport: Invalid parameters received."); + + return NULL; + } + + /* This open is coming after a SSR, we don't need to reopen SMD, + * the SMD port was never closed during SSR*/ + if (gwctsHandle) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WCTS_OpenTransport port is already open"); + + pWCTSCb = gwctsHandle; + if (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "WCTS_OpenTransport: Invalid magic."); + return NULL; + } + pWCTSCb->wctsState = WCTS_STATE_OPEN; + + pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, + WCTS_EVENT_OPEN, + pWCTSCb->wctsNotifyCBData); + + /* we initially don't want read interrupts + (we only want them if we get into deferred write mode) */ + smd_disable_read_intr(pWCTSCb->wctsChannel); + + return (WCTS_HandleType)pWCTSCb; + } + + /* allocate a ControlBlock to hold all context */ + pWCTSCb = wpalMemoryAllocate(sizeof(*pWCTSCb)); + if (NULL == pWCTSCb) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_OpenTransport: Memory allocation failure."); + return NULL; + } + + /* make sure the control block is initialized. in particular we need + to make sure the embedded event and list structures are initialized + to prevent "magic number" tests from being run against uninitialized + values */ + wpalMemoryZero(pWCTSCb, sizeof(*pWCTSCb)); + + /*Initialise the event*/ + wpalEventInit(&pWCTSCb->wctsEvent); + + /* save the user-supplied information */ + pWCTSCb->wctsNotifyCB = wctsCBs->wctsNotifyCB; + pWCTSCb->wctsNotifyCBData = wctsCBs->wctsNotifyCBData; + pWCTSCb->wctsRxMsgCB = wctsCBs->wctsRxMsgCB; + pWCTSCb->wctsRxMsgCBData = wctsCBs->wctsRxMsgCBData; + + /* initialize the remaining fields */ + wpal_list_init(&pWCTSCb->wctsPendingQueue); + pWCTSCb->wctsMagic = WCTS_CB_MAGIC; + vos_spin_lock_init(&pWCTSCb->wctsStateLock); + pWCTSCb->wctsState = WCTS_STATE_OPEN_PENDING; + pWCTSCb->wctsChannel = NULL; + + /* since SMD will callback in interrupt context, we will used + * canned messages to serialize the SMD events into a thread + * context + */ + pWCTSCb->wctsOpenMsg.callback = WCTS_PALOpenCallback; + pWCTSCb->wctsOpenMsg.pContext = pWCTSCb; + pWCTSCb->wctsOpenMsg.type= WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG; + + pWCTSCb->wctsDataMsg.callback = WCTS_PALDataCallback; + pWCTSCb->wctsDataMsg.pContext = pWCTSCb; + pWCTSCb-> wctsDataMsg.type= WPAL_MC_MSG_SMD_NOTIF_DATA_SIG; + + /*--------------------------------------------------------------------- + Open the SMD channel + ---------------------------------------------------------------------*/ + + wpalEventReset(&pWCTSCb->wctsEvent); + smdstatus = smd_named_open_on_edge(szName, + SMD_APPS_WCNSS, + &pWCTSCb->wctsChannel, + pWCTSCb, + WCTS_NotifyCallback); + if (0 != smdstatus) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: smd_named_open_on_edge failed with status %d", + __func__, smdstatus); + goto fail; + } + + /* wait for the channel to be fully opened before we proceed */ + status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_OPEN_TIMEOUT); + if (eWLAN_PAL_STATUS_SUCCESS != status) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: failed to receive SMD_EVENT_OPEN", + __func__); + /* since we opened one end of the channel, close it */ + smdstatus = smd_close(pWCTSCb->wctsChannel); + if (0 != smdstatus) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: smd_close failed with status %d", + __func__, smdstatus); + } + goto fail; + } + + /* we initially don't want read interrupts + (we only want them if we get into deferred write mode) */ + smd_disable_read_intr(pWCTSCb->wctsChannel); + + /* we have successfully opened the SMD channel */ + gwctsHandle = pWCTSCb; + return (WCTS_HandleType)pWCTSCb; + + fail: + /* we were unable to open the SMD channel */ + pWCTSCb->wctsMagic = 0; + wpalMemoryFree(pWCTSCb); + return NULL; + +}/*WCTS_OpenTransport*/ + + + +/** + @brief This function is used by the DAL Core to close the + Control Transport when its services are no longer + needed. Full close notification will be receive + asynchronously on the notification callback + registered on Open + + + @param wctsHandlehandle: received upon open + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_CloseTransport +( + WCTS_HandleType wctsHandle +) +{ + WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle; + wpt_list_node* pNode = NULL; + WCTS_BufferType* pBufferQueue = NULL; + void* pBuffer = NULL; + wpt_status status; + int smdstatus; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_CloseTransport: Invalid parameters received."); + return eWLAN_PAL_STATUS_E_INVAL; + } + + /*Free the buffers in the pending queue.*/ + while (eWLAN_PAL_STATUS_SUCCESS == + wpal_list_remove_front(&pWCTSCb->wctsPendingQueue, &pNode)) { + pBufferQueue = container_of(pNode, WCTS_BufferType, node); + pBuffer = pBufferQueue->pBuffer; + wpalMemoryFree(pBuffer); + wpalMemoryFree(pBufferQueue); + } + + /* Reset the state */ + pWCTSCb->wctsState = WCTS_STATE_CLOSED; + + wpalEventReset(&pWCTSCb->wctsEvent); + smdstatus = smd_close(pWCTSCb->wctsChannel); + if (0 != smdstatus) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: smd_close failed with status %d", + __func__, smdstatus); + /* SMD did not successfully close the channel, therefore we + won't receive an asynchronous close notification so don't + bother to wait for an event that won't come */ + + } else { + /* close command was sent -- wait for the callback to complete */ + status = wpalEventWait(&pWCTSCb->wctsEvent, WCTS_SMD_CLOSE_TIMEOUT); + if (eWLAN_PAL_STATUS_SUCCESS != status) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: failed to receive SMD_EVENT_REOPEN_READY", + __func__); + } + + /* During the close sequence we deregistered from SMD. As part + of deregistration SMD will call back into our driver with an + event to let us know the channel is closed. We need to + insert a brief delay to allow that thread of execution to + exit our module. Otherwise our module may be unloaded while + there is still code running within the address space, and + that code will crash when the memory is unmapped */ + msleep(50); + } + + /* channel has (hopefully) been closed */ + pWCTSCb->wctsNotifyCB((WCTS_HandleType)pWCTSCb, + WCTS_EVENT_CLOSE, + pWCTSCb->wctsNotifyCBData); + vos_spin_lock_destroy(&pWCTSCb->wctsStateLock); + /* release the resource */ + pWCTSCb->wctsMagic = 0; + wpalMemoryFree(pWCTSCb); + gwctsHandle = NULL; + + return eWLAN_PAL_STATUS_SUCCESS; + +}/*WCTS_CloseTransport*/ + + + +/** + @brief This function is used by the DAL Core to to send a + message over to the WLAN sub-system. + + Once a buffer has been passed into the Send Message + API, CT takes full ownership of it and it is responsible for + freeing the associated resources. (This prevents a memcpy in + case of a deferred write) + + The messages transported through the CT on both RX and TX are + flat memory buffers that can be accessed and manipulated + through standard memory functions. + + @param wctsHandlehandle: received upon open + pMsg: the message to be sent + uLen: the length of the message + + @see + @return 0 for success +*/ +wpt_uint32 +WCTS_SendMessage +( + WCTS_HandleType wctsHandle, + void* pMsg, + wpt_uint32 uLen +) +{ + WCTS_ControlBlockType* pWCTSCb = (WCTS_ControlBlockType*) wctsHandle; + WCTS_BufferType* pBufferQueue; + int len; + int written = 0; + int available; + + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + /*-------------------------------------------------------------------- + Sanity check + --------------------------------------------------------------------*/ + if ((NULL == pWCTSCb) || (WCTS_CB_MAGIC != pWCTSCb->wctsMagic) || + (NULL == pMsg) || (0 == uLen) || (0x7fffffff < uLen)) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_SendMessage: Invalid parameters received."); + WPAL_ASSERT(0); + if (NULL != pMsg) { + wpalMemoryFree(pMsg); + } + return eWLAN_PAL_STATUS_E_INVAL; + } + + /* the SMD API uses int instead of uint, so change types here */ + len = (int)uLen; + + if (WCTS_STATE_OPEN == pWCTSCb->wctsState) { + available = smd_write_avail(pWCTSCb->wctsChannel); + if (available >= len) { + written = smd_write(pWCTSCb->wctsChannel, pMsg, len); + } + } else if (WCTS_STATE_DEFERRED == pWCTSCb->wctsState) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO, + "WCTS_SendMessage: FIFO space not available, the packets will be queued"); + } else { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_SendMessage: Channel in illegal state [%d].", + pWCTSCb->wctsState); + /* force following logic to reclaim the buffer */ + written = -1; + } + + if (-1 == written) { + /*Something wrong*/ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_SendMessage: Failed to send message over the bus."); + wpalMemoryFree(pMsg); + return eWLAN_PAL_STATUS_E_FAILURE; + } else if (written == len) { + /* Message sent! No deferred state, free the buffer*/ + wpalMemoryZero(pMsg, len); + wpalMemoryFree(pMsg); + } else { + /* This much data cannot be written at this time, + queue the rest of the data for later*/ + pBufferQueue = wpalMemoryAllocate(sizeof(WCTS_BufferType)); + if (NULL == pBufferQueue) { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "WCTS_SendMessage: Cannot allocate memory for queuing the buffer"); + wpalMemoryFree(pMsg); + WPAL_ASSERT(0); + return eWLAN_PAL_STATUS_E_NOMEM; + } + + pBufferQueue->bufferSize = len; + pBufferQueue->pBuffer = pMsg; + + if (eWLAN_PAL_STATUS_E_FAILURE == + wpal_list_insert_back(&pWCTSCb->wctsPendingQueue, + &pBufferQueue->node)) + { + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "pBufferQueue wpal_list_insert_back failed"); + wpalMemoryFree(pMsg); + wpalMemoryFree(pBufferQueue); + WPAL_ASSERT(0); + return eWLAN_PAL_STATUS_E_NOMEM; + } + + /* if we are not already in the deferred state, then transition + to that state. when we do so, we enable the remote read + interrupt so that we'll be notified when messages are read + from the remote end */ + vos_spin_lock_acquire(&pWCTSCb->wctsStateLock); + if ((WCTS_STATE_DEFERRED != pWCTSCb->wctsState) && + (WCTS_STATE_REM_CLOSED != pWCTSCb->wctsState)) { + + /* Mark the state as deferred.*/ + pWCTSCb->wctsState = WCTS_STATE_DEFERRED; + + smd_enable_read_intr(pWCTSCb->wctsChannel); + } + vos_spin_lock_release(&pWCTSCb->wctsStateLock); + + /*indicate to client that message was placed in deferred queue*/ + return eWLAN_PAL_STATUS_E_RESOURCES; + } + + return eWLAN_PAL_STATUS_SUCCESS; + +}/*WCTS_SendMessage*/ + +void WCTS_Dump_Smd_status(void) +{ + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Smd Read Stats: %d", gWdiSmdStats.smd_event_data); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Smd Open Stats: %d", gWdiSmdStats.smd_event_open); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Smd Close Stats: %d", gWdiSmdStats.smd_event_close); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Smd Status Stats: %d", gWdiSmdStats.smd_event_status); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Smd Reopen Stats: %d", gWdiSmdStats.smd_event_reopen_ready); + WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Smd Error Stats: %d", gWdiSmdStats.smd_event_err); +} diff --git a/drivers/staging/prima/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h b/drivers/staging/prima/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h new file mode 100644 index 000000000000..363c94637deb --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/TRP/DTS/inc/wlan_qct_wdi_dts.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_QCT_DTS_H +#define __WLAN_QCT_DTS_H + +#include "wlan_qct_wdi.h" + +/**========================================================================= + * + * \file wlan_qct_wdi_dts.h + * + * \brief define Datas Trnasport Service API + * + * WLAN Device Abstraction layer interface for Transport drivers (SDIO/DXE) + * DESCRIPTION + * This file contains the API exposed by the + * wlan device abstarction layer module for abstracting DXE/SDIO. + * + * + * Example usage for DXE. + * ---------------------- + * On Platform init + * DAL will then invoke WDTS_open + * + * On DAL init + * DAL will invike WDTS_start + * + * On transmit: + * DAL will invoke WDTS_TxPacket API + * + * On transmit complete: + * DXE will serialize into TX thread + * In TX thread it will invoke + * + * On receive: + * DXE will serialize into RX thread + * In TX thread it will invoke WDTS_RXPacket API + * + * On DXE ring full: + * DXE will serialize into TX thread + * In TX thread it will invoke WDTS_OOResourceNotification API + */ + +typedef enum +{ + WDTS_CHANNEL_TX_LOW_PRI, + WDTS_CHANNEL_TX_HIGH_PRI, + WDTS_CHANNEL_RX_LOW_PRI, + WDTS_CHANNEL_RX_HIGH_PRI, + WDTS_CHANNEL_RX_LOG, + WDTS_CHANNEL_RX_FW_LOG, + WDTS_CHANNEL_MAX +} WDTS_ChannelType; + +#define WDTS_TRANSPORT_CHANNELS_MASK \ + (1< unit in Mega bits per sec X 10 + gRateInfo[i].tputRate = ((gRateInfo[i].phyRate * macEff)/100); + // tputBmps --> unit in Bytes per msec = (tputRateX1024x1024)/(8x10X1000) ~= (tputRate*13) + gRateInfo[i].tputBpms = gRateInfo[i].tputRate * MB_PER_SEC_TO_BYTES_PER_MSEC; + // tputBpus --> unit in Bytes per usec: (+ 500) to round off to integral value + gRateInfo[i].tputBpus = ((gRateInfo[i].tputBpms + 500) / 1000); + if (gRateInfo[i].tputBpus == 0) + gRateInfo[i].tputBpus = 1; + + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "%4u, %4u, %5u, %2u", + gRateInfo[i].phyRate, + gRateInfo[i].tputRate, + gRateInfo[i].tputBpms, + gRateInfo[i].tputBpus ); + } +} + +/* Tx/Rx stats function + * This function should be invoked to fetch the current stats + * Parameters: + * pStats:Pointer to the collected stats + * len: length of buffer pointed to by pStats + * Return Status: None + */ +void WDTS_GetTrafficStats(WDI_TrafficStatsType** pStats, wpt_uint32 *len) +{ + if(gDsTrafficStats.running) + { + uint8 staIdx, rate; + WDI_TrafficStatsType *pNetTxRxStats = gDsTrafficStats.netTxRxStats; + wpalMemoryZero(pNetTxRxStats, sizeof(gDsTrafficStats.netTxRxStats)); + + for(staIdx = 0; staIdx < HAL_NUM_STA; staIdx++, pNetTxRxStats++) + { + pNetTxRxStats->txBytesPushed += gDsTrafficStats.txStats[staIdx].txBytesPushed; + pNetTxRxStats->txPacketsPushed+= gDsTrafficStats.txStats[staIdx].txPacketsPushed; + for(rate = 0; rate < WDTS_MAX_11B_RATE_NUM; rate++) + { + pNetTxRxStats->rxBytesRcvd += + gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd; + pNetTxRxStats->rxPacketsRcvd += + gDsTrafficStats.rxStats[staIdx][rate].rxPacketsRcvd; + pNetTxRxStats->rxTimeTotal += + gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd*DTS_11BRATE_TPUT_MULTIPLIER(rate); + } + for(rate = WDTS_MAX_11B_RATE_NUM; rate < WDTS_MAX_RATE_NUM; rate++) + { + pNetTxRxStats->rxBytesRcvd += + gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd; + pNetTxRxStats->rxPacketsRcvd += + gDsTrafficStats.rxStats[staIdx][rate].rxPacketsRcvd; + pNetTxRxStats->rxTimeTotal += + gDsTrafficStats.rxStats[staIdx][rate].rxBytesRcvd/DTS_RATE_TPUT(rate); + } + + pNetTxRxStats->rxTimeTotal = pNetTxRxStats->rxTimeTotal/1000; + + } + *pStats = gDsTrafficStats.netTxRxStats; + *len = sizeof(gDsTrafficStats.netTxRxStats); + } + else + { + *pStats = NULL; + *len = 0; + } +} + +/* WDTS_DeactivateTrafficStats + * This function should be invoked to deactivate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDTS_DeactivateTrafficStats(void) +{ + gDsTrafficStats.running = eWLAN_PAL_FALSE; +} + +/* WDTS_ActivateTrafficStats + * This function should be invoked to activate traffic stats collection + * Parameters: None + * Return Status: None + */ +void WDTS_ActivateTrafficStats(void) +{ + gDsTrafficStats.running = eWLAN_PAL_TRUE; +} + +/* WDTS_ClearTrafficStats + * This function should be invoked to clear traffic stats + * Parameters: None + * Return Status: None + */ +void WDTS_ClearTrafficStats(void) +{ + wpalMemoryZero(gDsTrafficStats.rxStats, sizeof(gDsTrafficStats.rxStats)); + wpalMemoryZero(gDsTrafficStats.txStats, sizeof(gDsTrafficStats.txStats)); +} + +/* DTS Tx packet complete function. + * This function should be invoked by the transport device to indicate + * transmit complete for a frame. + * Parameters: + * pContext:Cookie that should be passed back to the caller + * pFrame:Refernce to PAL frame. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_TxPacketComplete(void *pContext, wpt_packet *pFrame, wpt_status status) +{ + WDI_DS_ClientDataType *pClientData = (WDI_DS_ClientDataType*)(pContext); + WDI_DS_TxMetaInfoType *pTxMetadata; + void *pvBDHeader, *physBDHeader; + wpt_uint8 staIndex; + + // Do Sanity checks + if(NULL == pContext || NULL == pFrame){ + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_WARN, + "%s: Tx complete cannot proceed(%p:%p)", + __func__, pContext, pFrame); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + + // extract metadata from PAL packet + pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); + pTxMetadata->txCompleteStatus = status; + + // Free BD header from pool + WDI_GetBDPointers(pFrame, &pvBDHeader, &physBDHeader); + switch(pTxMetadata->frmType) + { + case WDI_MAC_DATA_FRAME: + /* note that EAPOL frame hasn't incremented ReserveCount. see + WDI_DS_TxPacket() in wlan_qct_wdi_ds.c + */ +#ifdef FEATURE_WLAN_TDLS + /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) + Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() + should take managment path. As of today, only TDLS feature has special data frame + which needs to be treated as mgmt. + */ + if((!pTxMetadata->isEapol) && + ((pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME) != WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME)) +#else + if(!pTxMetadata->isEapol) +#endif + { + /* SWAP BD header to get STA index for completed frame */ + WDI_SwapTxBd(pvBDHeader); + staIndex = (wpt_uint8)WDI_TX_BD_GET_STA_ID(pvBDHeader); + WDI_DS_MemPoolFree(&(pClientData->dataMemPool), pvBDHeader, physBDHeader); + WDI_DS_MemPoolDecreaseReserveCount(&(pClientData->dataMemPool), staIndex); + break; + } + // intentional fall-through to handle eapol packet as mgmt + case WDI_MAC_MGMT_FRAME: + WDI_DS_MemPoolFree(&(pClientData->mgmtMemPool), pvBDHeader, physBDHeader); + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO, + "%s: Management frame Tx complete status: %d", __func__, status); + break; + } + WDI_SetBDPointers(pFrame, 0, 0); + + // Invoke Tx complete callback + pClientData->txCompleteCB(pClientData->pCallbackContext, pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + +} + + +/*=============================================================================== + FUNCTION WLANTL_GetReplayCounterFromRxBD + + DESCRIPTION This function extracts 48-bit replay packet number from RX BD + + DEPENDENCIES Validity of replay check must be done before the function + is called + + PARAMETERS pucRxHeader pointer to RX BD header + + RETRUN v_U64_t Packet number extarcted from RX BD + + SIDE EFFECTS none + ===============================================================================*/ +v_U64_t +WDTS_GetReplayCounterFromRxBD +( + v_U8_t *pucRxBDHeader +) +{ + v_U64_t ullcurrentReplayCounter = 0; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* 48-bit replay counter is created as follows + from RX BD 6 byte PMI command: + Addr : AES/TKIP + 0x38 : pn3/tsc3 + 0x39 : pn2/tsc2 + 0x3a : pn1/tsc1 + 0x3b : pn0/tsc0 + + 0x3c : pn5/tsc5 + 0x3d : pn4/tsc4 */ + +#ifdef ANI_BIG_BYTE_ENDIAN + /* Getting 48-bit replay counter from the RX BD */ + ullcurrentReplayCounter = WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); + ullcurrentReplayCounter <<= 16; + ullcurrentReplayCounter |= (( WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0xFFFF0000) >> 16); + return ullcurrentReplayCounter; +#else + /* Getting 48-bit replay counter from the RX BD */ + ullcurrentReplayCounter = (WDI_RX_BD_GET_PMICMD_24TO25(pucRxBDHeader) & 0x0000FFFF); + ullcurrentReplayCounter <<= 32; + ullcurrentReplayCounter |= WDI_RX_BD_GET_PMICMD_20TO23(pucRxBDHeader); + return ullcurrentReplayCounter; +#endif +} + +/* Store RXBD, skb lenght, skb head, and skb end offset to global buffer. + * This function should be invoked when MPDU lenght + MPDU herader Offset + * if higher then 3872 bytes. + * Parameters: + * pFrame:Refernce to PAL frame. + * pBDHeader: BD header for PAL Frame. + * Return Value: v_VOID_t + * + */ +v_VOID_t +WDTS_StoreMetaInfo(wpt_packet *pFrame, wpt_uint8 *pBDHeader) +{ + wpt_uint8 usMPDUHLen; + wpt_boolean usAsf, usAef, usLsf, usESF; + wpt_uint16 usMPDULen; + wpt_uint32 usPmiCmd24to25; + struct WDTS_RxPktInfo *current_data = + &WDTS_Pkt_Data_Buff.PktInfo[WDTS_Pkt_Data_Buff.current_position]; + + vos_mem_copy(current_data->rx_bd, (void*)wpalPacketGetRawBuf(pFrame), + WDTS_MAX_RXDB_DATA_SIZE); + + usMPDULen = (wpt_uint16)WDI_RX_BD_GET_MPDU_LEN(pBDHeader); + usMPDUHLen = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_LEN(pBDHeader); + usAsf = (wpt_boolean)WDI_RX_BD_GET_ASF(pBDHeader); + usAef = (wpt_boolean)WDI_RX_BD_GET_AEF(pBDHeader); + usLsf = (wpt_boolean)WDI_RX_BD_GET_LSF(pBDHeader); + usESF = (wpt_boolean)WDI_RX_BD_GET_ESF(pBDHeader); + usPmiCmd24to25 = (wpt_uint32)WDI_RX_BD_GET_PMICMD_24TO25(pBDHeader); + + current_data->pFrame_head = wpalGetOSPktHead(pFrame); + current_data->pFrame_tail = wpalGetOSPktend(pFrame); + current_data->pFrame_len = wpalPacketGetLength(pFrame); + + WDTS_Pkt_Data_Buff.current_count++; + + /* Dump packet info */ + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "count: %d usMPDULen: 0x%x, usMPDUHLen: 0x%x, usAsf: %x," + "usAef: %x, usLsf: 0x%x, usESF: 0x%x, usPmiCmd24to25: 0x%x," + "skb_len: 0x%x",WDTS_Pkt_Data_Buff.current_count, usMPDULen, + usMPDUHLen, usAsf, usAef, usLsf, usESF, usPmiCmd24to25, + current_data->pFrame_len); + + WDTS_Pkt_Data_Buff.current_position++; + if(WDTS_Pkt_Data_Buff.current_position >= WDTS_MAX_NUMBER_OF_RX_PKT) + WDTS_Pkt_Data_Buff.current_position = 0; + + return; +} + +/** + *WDTS_RxPacketDump - Dump Rx packet details + *@pFrame: pointer to first Rx buffer received + *@pRxMetadata: pointer to RX packet Meta Info + * + *DTS utility to dump RX packet details. + * + *Return: None. + */ +static void WDTS_RxPacketDump(vos_pkt_t *pFrame, + WDI_DS_RxMetaInfoType *pRxMetadata) +{ + tpSirMacMgmtHdr pHdr; + + if (NULL == pRxMetadata) { + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s: RX Meta data info is NULL", __func__); + return; + } + + pHdr = (tpSirMacMgmtHdr)pRxMetadata->mpduHeaderPtr; + + /* RX packet type*/ + if (pRxMetadata->bcast) + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s RX Data frame is BC", __func__); + else if (pHdr->da[0] & 0x01) + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s RX Data frame is MC", __func__); + else + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s RX Data frame is UC", __func__); + + /* 802.11 packet type, subtype */ + if (WDI_MAC_MGMT_FRAME == pRxMetadata->type) { + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s: Management subtype:%d SA:"MAC_ADDRESS_STR" DA:" + MAC_ADDRESS_STR, __func__, pRxMetadata->subtype, + MAC_ADDR_ARRAY(pHdr->sa), MAC_ADDR_ARRAY(pHdr->da)); + vos_set_rx_wow_dump(false); + } else if (WDI_MAC_CTRL_FRAME == pRxMetadata->type) { + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s: Control subtype:%d SA:"MAC_ADDRESS_STR" DA:" + MAC_ADDRESS_STR, __func__, pRxMetadata->subtype, + MAC_ADDR_ARRAY(pHdr->sa), MAC_ADDR_ARRAY(pHdr->da)); + vos_set_rx_wow_dump(false); + } else if (WDI_MAC_DATA_FRAME == pRxMetadata->type) { + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s: Data subtype:%d SA:"MAC_ADDRESS_STR" DA:" + MAC_ADDRESS_STR, __func__, pRxMetadata->subtype, + MAC_ADDR_ARRAY(pHdr->sa), MAC_ADDR_ARRAY(pHdr->da)); + } else + VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_ERROR, + "%s: Unknown frame SA:"MAC_ADDRESS_STR, + __func__, MAC_ADDR_ARRAY(pHdr->sa)); +} + +/* DTS Rx packet function. + * This function should be invoked by the transport device to indicate + * reception of a frame. + * Parameters: + * pContext:Cookie that should be passed back to the caller + * pFrame:Refernce to PAL frame. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_RxPacket (void *pContext, wpt_packet *pFrame, WDTS_ChannelType channel) +{ + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType*)(pContext); + wpt_boolean bASF, bFSF, bLSF, bAEF; + wpt_uint8 ucMPDUHOffset, ucMPDUHLen, ucTid; + wpt_uint8 *pBDHeader; + wpt_uint16 usMPDUDOffset, usMPDULen; + WDI_DS_RxMetaInfoType *pRxMetadata; + wpt_uint8 isFcBd = 0; + WDI_DS_LoggingSessionType *pLoggingSession; + tPerPacketStats rxStats = {0}; + wpt_uint8 indType = 0; + + tpSirMacFrameCtl pMacFrameCtl; + // Do Sanity checks + if(NULL == pContext || NULL == pFrame){ + return eWLAN_PAL_STATUS_E_FAILURE; + } + + // Normal DMA transfer does not contain RxBD + if (WDTS_CHANNEL_RX_FW_LOG == channel) + { + pLoggingSession = (WDI_DS_LoggingSessionType *) + WDI_DS_GetLoggingSession(pContext); + wpalFwLogPktSerialize(pFrame, pLoggingSession->logType); + + return eWLAN_PAL_STATUS_SUCCESS; + } + + /*------------------------------------------------------------------------ + Extract BD header and check if valid + ------------------------------------------------------------------------*/ + pBDHeader = (wpt_uint8*)wpalPacketGetRawBuf(pFrame); + if(NULL == pBDHeader) + { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, + "WLAN TL:BD header received NULL - dropping packet"); + wpalPacketFree(pFrame); + return eWLAN_PAL_STATUS_E_FAILURE; + } + WDI_SwapRxBd(pBDHeader); + + ucMPDUHOffset = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_OFFSET(pBDHeader); + usMPDUDOffset = (wpt_uint16)WDI_RX_BD_GET_MPDU_D_OFFSET(pBDHeader); + usMPDULen = (wpt_uint16)WDI_RX_BD_GET_MPDU_LEN(pBDHeader); + ucMPDUHLen = (wpt_uint8)WDI_RX_BD_GET_MPDU_H_LEN(pBDHeader); + ucTid = (wpt_uint8)WDI_RX_BD_GET_TID(pBDHeader); + + /* If RX thread drain small size of frame from HW too fast + * Sometimes HW cannot handle interrupt fast enough + * And system crash might happen + * To avoid system crash, input 1usec delay each frame draining + * within host side, if frame size is smaller that threshold. + * This is SW work around, to fix HW problem + * Throughput and SnS test done successfully */ + if (usMPDULen < DTS_RX_DELAY_FRAMESIZE_THRESHOLD) + { + wpalBusyWait(1); + } + + /*------------------------------------------------------------------------ + Gather AMSDU information + ------------------------------------------------------------------------*/ + bASF = WDI_RX_BD_GET_ASF(pBDHeader); + bAEF = WDI_RX_BD_GET_AEF(pBDHeader); + bFSF = WDI_RX_BD_GET_ESF(pBDHeader); + bLSF = WDI_RX_BD_GET_LSF(pBDHeader); + isFcBd = WDI_RX_FC_BD_GET_FC(pBDHeader); + indType = WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader); + + DTI_TRACE( DTI_TRACE_LEVEL_INFO, + "WLAN TL:BD header processing data: HO %d DO %d Len %d HLen %d" + " Tid %d BD %d", + ucMPDUHOffset, usMPDUDOffset, usMPDULen, ucMPDUHLen, ucTid, + WDI_RX_BD_HEADER_SIZE); + + pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame); + + if (WDTS_CHANNEL_RX_LOG == channel) + { + if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset)) + { + /* Size of the packet tranferred by the DMA engine is + * greater than the the memory allocated for the skb + * Recover the SKB case of length is in same memory page + */ + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Invalid Frame size, might memory corrupted(%d+%d/%d)", + usMPDULen, ucMPDUHOffset, VPKT_SIZE_BUFFER_ALIGNED); + + // Store RXBD, skb head, tail and skb lenght in circular buffer + WDTS_StoreMetaInfo(pFrame, pBDHeader); + + if ((usMPDULen+ucMPDUHOffset) <= WDTS_MAX_PAGE_SIZE) + { + wpalRecoverTail(pFrame); + wpalPacketFree(pFrame); + } else { + //Recovery may cause adjoining buffer corruption + WPAL_BUG(0); + } + + return eWLAN_PAL_STATUS_SUCCESS; + } + + /* Firmware should send the Header offset as length + * of RxBd and data length should be populated to + * the length of total data being sent + */ + wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset); + wpalPacketRawTrimHead(pFrame, ucMPDUHOffset); + + if(indType) { + DTI_TRACE(DTI_TRACE_LEVEL_INFO, "indtype is %d size of pacekt is %lu", + indType, sizeof(WDI_RxBdType)); + if (WDI_RXBD_SAP_TX_STATS == indType) { + pRxMetadata->fc = 1; + pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + } + } + else { + // Invoke Rx complete callback + wpalLogPktSerialize(pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + } + } + else + { + pRxMetadata->loggingData = 0; + } + + if(!isFcBd) + { + /* When channel is WDTS_CHANNEL_RX_LOG firmware doesn't send MPDU header*/ + if ((usMPDUDOffset <= ucMPDUHOffset || usMPDULen < ucMPDUHLen) && + (WDTS_CHANNEL_RX_LOG != channel)) { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, + "WLAN TL:BD header corrupted - dropping packet"); + /* Drop packet ???? */ + wpalPacketFree(pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + } + + if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (!(bASF && !bFSF))){ + /* AMSDU case, ucMPDUHOffset = 0 it should be hancdled seperatly */ + /* Drop packet ???? */ + wpalPacketFree(pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + } + + /* AMSDU frame, but not first sub-frame + * No MPDU header, MPDU header offset is 0 + * Total frame size is actual frame size + MPDU data offset */ + if((ucMPDUHOffset < WDI_RX_BD_HEADER_SIZE) && (bASF && !bFSF)){ + ucMPDUHOffset = usMPDUDOffset; + } + + if (VPKT_SIZE_BUFFER_ALIGNED < (usMPDULen+ucMPDUHOffset)) + { + /* Size of the packet tranferred by the DMA engine is + * greater than the the memory allocated for the skb + * Recover the SKB case of length is in same memory page + */ + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_FATAL, + "Invalid Frame size, might memory corrupted(%d+%d/%d)", + usMPDULen, ucMPDUHOffset, VPKT_SIZE_BUFFER_ALIGNED); + + // Store RXBD, skb head, tail and skb lenght in circular buffer + WDTS_StoreMetaInfo(pFrame, pBDHeader); + + if ((usMPDULen+ucMPDUHOffset) <= WDTS_MAX_PAGE_SIZE) + { + wpalRecoverTail(pFrame); + wpalPacketFree(pFrame); + } else { + //Recovery may cause adjoining buffer corruption + WPAL_BUG(0); + } + + return eWLAN_PAL_STATUS_SUCCESS; + } + + if(eWLAN_PAL_STATUS_SUCCESS != wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset)) + { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "Invalid Frame Length, Frame dropped.."); + wpalPacketFree(pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + } + if(eWLAN_PAL_STATUS_SUCCESS != wpalPacketRawTrimHead(pFrame, ucMPDUHOffset)) + { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, "Failed to trim Raw Packet Head, Frame dropped.."); + wpalPacketFree(pFrame); + return eWLAN_PAL_STATUS_SUCCESS; + } + + pRxMetadata->fc = isFcBd; + pRxMetadata->staId = WDI_RX_BD_GET_STA_ID(pBDHeader); + pRxMetadata->addr3Idx = WDI_RX_BD_GET_ADDR3_IDX(pBDHeader); + pRxMetadata->rxChannel = WDI_RX_BD_GET_RX_CHANNEL(pBDHeader); + pRxMetadata->rfBand = WDI_RX_BD_GET_RFBAND(pBDHeader); + pRxMetadata->rtsf = WDI_RX_BD_GET_RTSF(pBDHeader); + pRxMetadata->bsf = WDI_RX_BD_GET_BSF(pBDHeader); + pRxMetadata->scan = WDI_RX_BD_GET_SCAN(pBDHeader); + pRxMetadata->dpuSig = WDI_RX_BD_GET_DPU_SIG(pBDHeader); + pRxMetadata->ft = WDI_RX_BD_GET_FT(pBDHeader); + pRxMetadata->ne = WDI_RX_BD_GET_NE(pBDHeader); + pRxMetadata->llcr = WDI_RX_BD_GET_LLCR(pBDHeader); + pRxMetadata->bcast = WDI_RX_BD_GET_UB(pBDHeader); + pRxMetadata->tid = ucTid; + pRxMetadata->dpuFeedback = WDI_RX_BD_GET_DPU_FEEDBACK(pBDHeader); + pRxMetadata->rateIndex = WDI_RX_BD_GET_RATEINDEX(pBDHeader); + pRxMetadata->rxpFlags = WDI_RX_BD_GET_RXPFLAGS(pBDHeader); + pRxMetadata->mclkRxTimestamp = WDI_RX_BD_GET_TIMESTAMP(pBDHeader); +#ifdef WLAN_FEATURE_11W + pRxMetadata->rmf = WDI_RX_BD_GET_RMF(pBDHeader); +#endif +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD + pRxMetadata->offloadScanLearn = WDI_RX_BD_GET_OFFLOADSCANLEARN(pBDHeader); + pRxMetadata->roamCandidateInd = WDI_RX_BD_GET_ROAMCANDIDATEIND(pBDHeader); + pRxMetadata->perRoamCndInd = WDI_RX_BD_GET_PER_ROAMCANDIDATEIND(pBDHeader); +#endif +#ifdef SAP_AUTH_OFFLOAD + /* Currently firmware use WDTS_CHANNEL_RX_LOG channel for two purpose. + * 1) For firmare logging information: driver will do special handling + * for those message. + * 2) When SAP offload is enabled: In this case, indication type is stored + * in pRxMetadata which will be used by LIM later. + */ + if (WDTS_CHANNEL_RX_LOG == channel) + { + pRxMetadata->indType = + (wpt_uint32)WDI_RX_BD_GET_PER_SAPOFFLOAD(pBDHeader); + if (pRxMetadata->indType == WDI_RXBD_MLME_STA_STATUS) + { + DTI_TRACE( DTI_TRACE_LEVEL_INFO, "%s: Indtype is %d\n", + __func__, pRxMetadata->indType); + pRxMetadata->type = WDI_MAC_MGMT_FRAME; + } + } + else + { + pRxMetadata->indType = 0; + } +#endif + +#ifdef WLAN_FEATURE_EXTSCAN + pRxMetadata->extscanBuffer = WDI_RX_BD_GET_EXTSCANFULLSCANRESIND(pBDHeader); +#endif + /* typeSubtype in BD doesn't look like correct. Fill from frame ctrl + TL does it for Volans but TL does not know BD for Prima. WDI should do it */ + if ( 0 == WDI_RX_BD_GET_FT(pBDHeader) ) { + if ( bASF ) { + pRxMetadata->subtype = WDI_MAC_DATA_QOS_DATA; + pRxMetadata->type = WDI_MAC_DATA_FRAME; + } else { + pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + ucMPDUHOffset); + pRxMetadata->subtype = pMacFrameCtl->subType; + pRxMetadata->type = pMacFrameCtl->type; + } + } else { + pMacFrameCtl = (tpSirMacFrameCtl)(((wpt_uint8*)pBDHeader) + WDI_RX_BD_HEADER_SIZE); + pRxMetadata->subtype = pMacFrameCtl->subType; + pRxMetadata->type = pMacFrameCtl->type; + } + + pRxMetadata->mpduHeaderPtr = pBDHeader + ucMPDUHOffset; + pRxMetadata->mpduDataPtr = pBDHeader + usMPDUDOffset; + pRxMetadata->mpduLength = usMPDULen; + pRxMetadata->mpduHeaderLength = ucMPDUHLen; + + /*------------------------------------------------------------------------ + Gather AMPDU information + ------------------------------------------------------------------------*/ + pRxMetadata->ampdu_reorderOpcode = (wpt_uint8)WDI_RX_BD_GET_BA_OPCODE(pBDHeader); + pRxMetadata->ampdu_reorderSlotIdx = (wpt_uint8)WDI_RX_BD_GET_BA_SI(pBDHeader); + pRxMetadata->ampdu_reorderFwdIdx = (wpt_uint8)WDI_RX_BD_GET_BA_FI(pBDHeader); + pRxMetadata->currentPktSeqNo = (wpt_uint16)WDI_RX_BD_GET_BA_CSN(pBDHeader); + + + /*------------------------------------------------------------------------ + Gather AMSDU information + ------------------------------------------------------------------------*/ + pRxMetadata->amsdu_asf = bASF; + pRxMetadata->amsdu_aef = bAEF; + pRxMetadata->amsdu_esf = bFSF; + pRxMetadata->amsdu_lsf = bLSF; + pRxMetadata->amsdu_size = WDI_RX_BD_GET_AMSDU_SIZE(pBDHeader); + + pRxMetadata->rssi0 = WDI_RX_BD_GET_RSSI0(pBDHeader); + pRxMetadata->rssi1 = WDI_RX_BD_GET_RSSI1(pBDHeader); + + + /* Missing: + wpt_uint32 fcSTATxQStatus:8; + wpt_uint32 fcSTAThreshIndMask:8; + wpt_uint32 fcSTAPwrSaveStateMask:8; + wpt_uint32 fcSTAValidMask:8; + + wpt_uint8 fcSTATxQLen[8]; // one byte per STA. + wpt_uint8 fcSTACurTxRate[8]; // current Tx rate for each sta. + unknownUcastPkt + */ + + pRxMetadata->replayCount = WDTS_GetReplayCounterFromRxBD(pBDHeader); + pRxMetadata->snr = WDI_RX_BD_GET_SNR(pBDHeader); + + /* + * PAL BD pointer information needs to be populated + */ + WPAL_PACKET_SET_BD_POINTER(pFrame, pBDHeader); + WPAL_PACKET_SET_BD_LENGTH(pFrame, sizeof(WDI_RxBdType)); + + if (((WDI_ControlBlockType *)pClientData->pcontext)->roamDelayStatsEnabled) + { + vos_record_roam_event(e_DXE_RX_PKT_TIME, (void *)pFrame, pRxMetadata->type); + } + if ((WLAN_LOG_LEVEL_ACTIVE == + vos_get_ring_log_level(RING_ID_PER_PACKET_STATS)) && + !(WDI_MAC_CTRL_FRAME == pRxMetadata->type)) + { + vos_mem_zero(&rxStats,sizeof(tPerPacketStats)); + /* Peer tx packet and it is an Rx packet for us */ + rxStats.is_rx= VOS_TRUE; + rxStats.tid = ucTid; + rxStats.rssi = (pRxMetadata->rssi0 > pRxMetadata->rssi1)? + pRxMetadata->rssi0 : pRxMetadata->rssi1; + rxStats.rate_idx = pRxMetadata->rateIndex; + rxStats.seq_num = pRxMetadata->currentPktSeqNo; + rxStats.dxe_timestamp = vos_timer_get_system_ticks(); + rxStats.data_len = + vos_copy_80211_data(pFrame, rxStats.data, pRxMetadata->type); + wpalPerPktSerialize(&rxStats); + } + + /* Dump first Rx packet after host wakeup */ + if (vos_get_rx_wow_dump()) + WDTS_RxPacketDump((vos_pkt_t*)pFrame, pRxMetadata); + + /* Invoke Rx complete callback */ + pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame); + } + else + { + wpalPacketSetRxLength(pFrame, usMPDULen+ucMPDUHOffset); + wpalPacketRawTrimHead(pFrame, ucMPDUHOffset); + + /* flow control related */ + pRxMetadata->fc = isFcBd; + pRxMetadata->mclkRxTimestamp = WDI_RX_BD_GET_TIMESTAMP(pBDHeader); + pRxMetadata->fcStaTxDisabledBitmap = WDI_RX_FC_BD_GET_STA_TX_DISABLED_BITMAP(pBDHeader); + pRxMetadata->fcSTAValidMask = WDI_RX_FC_BD_GET_STA_VALID_MASK(pBDHeader); + /* Invoke Rx complete callback */ + pClientData->receiveFrameCB(pClientData->pCallbackContext, pFrame); + } + + /* Log the RX Stats */ + if(gDsTrafficStats.running && pRxMetadata->staId < HAL_NUM_STA) + { + if(pRxMetadata->rateIndex < WDTS_MAX_RATE_NUM) + { + if(pRxMetadata->type == WDI_MAC_DATA_FRAME) + { + gDsTrafficStats.rxStats[pRxMetadata->staId][pRxMetadata->rateIndex].rxBytesRcvd += + pRxMetadata->mpduLength; + gDsTrafficStats.rxStats[pRxMetadata->staId][pRxMetadata->rateIndex].rxPacketsRcvd++; + } + } + } + return eWLAN_PAL_STATUS_SUCCESS; +} + + + +/* DTS Out of Resource packet function. + * This function should be invoked by the transport device to indicate + * the device is out of resources. + * Parameters: + * pContext:Cookie that should be passed back to the caller + * priority: indicates which channel is out of resource. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + */ +wpt_status WDTS_OOResourceNotification(void *pContext, WDTS_ChannelType channel, wpt_boolean on) +{ + WDI_DS_ClientDataType *pClientData = + (WDI_DS_ClientDataType *) pContext; + static wpt_uint8 ac_mask = 0x1f; + + // Do Sanity checks + if(NULL == pContext){ + return eWLAN_PAL_STATUS_E_FAILURE; + } + + if(on){ + ac_mask |= channel == WDTS_CHANNEL_TX_LOW_PRI? 0x0f : 0x10; + } else { + ac_mask &= channel == WDTS_CHANNEL_TX_LOW_PRI? 0x10 : 0x0f; + } + + + // Invoke OOR callback + pClientData->txResourceCB(pClientData->pCallbackContext, ac_mask); + return eWLAN_PAL_STATUS_SUCCESS; + +} + +void WDTS_LogRxDone(void *pContext) +{ + WDI_DS_LoggingSessionType *pLoggingSession; + + pLoggingSession = (WDI_DS_LoggingSessionType *) + WDI_DS_GetLoggingSession(pContext); + + if (NULL == pContext || pLoggingSession == NULL) + { + return; + } + /* check for done and Log type Mgmt frame = 0, QXDM = 1, FW Mem dump = 2 */ + if (pLoggingSession->done && pLoggingSession->logType <= VALID_FW_LOG_TYPES) + vos_process_done_indication(pLoggingSession->logType, + pLoggingSession->reasonCode); + + + if (pLoggingSession->logType == QXDM_LOGGING && + pLoggingSession->reasonCode) + pLoggingSession->logType = FATAL_EVENT; + ((WDI_DS_ClientDataType *)(pContext))->rxLogCB(pLoggingSession->logType); + + pLoggingSession->done = 0; + pLoggingSession->logType = 0; + pLoggingSession->reasonCode = 0; + + return; +} + +void WDTS_MbReceiveMsg(void *pContext) +{ + tpLoggingMailBox pLoggingMb; + WDI_DS_LoggingSessionType *pLoggingSession; + wpt_int8 i, noMem = 0; + wpt_uint32 totalLen = 0; + + pLoggingMb = (tpLoggingMailBox)WDI_DS_GetLoggingMbAddr(pContext); + pLoggingSession = (WDI_DS_LoggingSessionType *) + WDI_DS_GetLoggingSession(pContext); + + for(i = 0; i < MAX_NUM_OF_BUFFER; i++) + { + totalLen += pLoggingMb->logBuffLength[i]; + // Send done indication when the logbuffer size exceeds 128KB. + if (totalLen > MAX_LOG_BUFFER_LENGTH || pLoggingMb->logBuffLength[i] > MAX_LOG_BUFFER_LENGTH) + { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, " %d received invalid log buffer length", + totalLen); + // Done using Mailbox, zero out the memory. + wpalMemoryZero(pLoggingMb, sizeof(tLoggingMailBox)); + wpalMemoryZero(pLoggingSession, sizeof(WDI_DS_LoggingSessionType)); + //Set Status as Failure + pLoggingSession->status = WDTS_LOGGING_STATUS_ERROR; + WDTS_LogRxDone(pContext); + + return; + } + } + + totalLen = 0; + for(i = 0; i < MAX_NUM_OF_BUFFER; i++) + { + pLoggingSession->logBuffAddress[i] = pLoggingMb->logBuffAddress[i]; + if (!noMem) + { + pLoggingSession->logBuffLength[i] = gTransportDriver.setupLogTransfer( + pLoggingMb->logBuffAddress[i], + pLoggingMb->logBuffLength[i]); + } + else + { + pLoggingSession->logBuffLength[i] = 0; + continue; + } + + totalLen += pLoggingSession->logBuffLength[i]; + + if (pLoggingSession->logBuffLength[i] < pLoggingMb->logBuffLength[i]) + { + noMem = 1; + } + } + + pLoggingSession->done = pLoggingMb->done; + pLoggingSession->logType = pLoggingMb->logType; + pLoggingSession->reasonCode = pLoggingMb->reasonCode; + pLoggingSession->status = WDTS_LOGGING_STATUS_SUCCESS; + // Done using Mailbox, zero out the memory. + wpalMemoryZero(pLoggingMb, sizeof(tLoggingMailBox)); + + if (totalLen) + { + if (gTransportDriver.startLogTransfer() == eWLAN_PAL_STATUS_SUCCESS) + return; + } + + // Send Done event to upper layers, since we wont be getting any from DXE +} + +/* DTS open function. + * On open the transport device should initialize itself. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_openTransport( void *pContext) +{ + void *pDTDriverContext; + WDI_DS_ClientDataType *pClientData; + WDI_Status sWdiStatus = WDI_STATUS_SUCCESS; + WDTS_ClientCallbacks WDTSCb; + + pClientData = (WDI_DS_ClientDataType*) wpalMemoryAllocate(sizeof(WDI_DS_ClientDataType)); + if (!pClientData){ + return eWLAN_PAL_STATUS_E_NOMEM; + } + + pClientData->suspend = 0; + WDI_DS_AssignDatapathContext(pContext, (void*)pClientData); + + pDTDriverContext = gTransportDriver.open(); + if( NULL == pDTDriverContext ) + { + DTI_TRACE( DTI_TRACE_LEVEL_ERROR, " %s fail from transport open", __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + WDT_AssignTransportDriverContext(pContext, pDTDriverContext); + + WDTSCb.rxFrameReadyCB = WDTS_RxPacket; + WDTSCb.txCompleteCB = WDTS_TxPacketComplete; + WDTSCb.lowResourceCB = WDTS_OOResourceNotification; + WDTSCb.receiveMbMsgCB = WDTS_MbReceiveMsg; + WDTSCb.receiveLogCompleteCB = WDTS_LogRxDone; + gTransportDriver.register_client(pDTDriverContext, WDTSCb, (void*)pClientData); + + /* Create a memory pool for Mgmt BDheaders.*/ + sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->mgmtMemPool, WDI_DS_MAX_CHUNK_SIZE, + WDI_DS_HI_PRI_RES_NUM); + if (WDI_STATUS_SUCCESS != sWdiStatus){ + return eWLAN_PAL_STATUS_E_NOMEM; + } + + /* Create a memory pool for Data BDheaders.*/ + sWdiStatus = WDI_DS_MemPoolCreate(&pClientData->dataMemPool, WDI_DS_MAX_CHUNK_SIZE, + WDI_DS_LO_PRI_RES_NUM); + if (WDI_STATUS_SUCCESS != sWdiStatus){ + return eWLAN_PAL_STATUS_E_NOMEM; + } + + wpalMemoryZero(&gDsTrafficStats, sizeof(gDsTrafficStats)); + + sWdiStatus = WDI_DS_LoggingMbCreate(&pClientData->loggingMbContext, sizeof(tLoggingMailBox)); + if (WDI_STATUS_SUCCESS != sWdiStatus) + return eWLAN_PAL_STATUS_E_NOMEM; + + return eWLAN_PAL_STATUS_SUCCESS; + +} + + + +/* DTS start function. + * On start the transport device should start running. + * Parameters: + * pContext:Cookie that should be passed back to the caller along + * with the callback. + * + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_startTransport( void *pContext) +{ + void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); + gTransportDriver.start(pDTDriverContext); + return eWLAN_PAL_STATUS_SUCCESS; + +} + + +/* DTS Tx packet function. + * This function should be invoked by the DAL Dataservice to schedule transmit frame through DXE/SDIO. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * pFrame:Refernce to PAL frame. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_TxPacket(void *pContext, wpt_packet *pFrame) +{ + void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); + WDI_DS_TxMetaInfoType *pTxMetadata; + WDTS_ChannelType channel = WDTS_CHANNEL_TX_LOW_PRI; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + tPerPacketStats txPktStat = {0}; + + // extract metadata from PAL packet + pTxMetadata = WDI_DS_ExtractTxMetaData(pFrame); + + //Log the TX Stats + if(gDsTrafficStats.running && pTxMetadata->staIdx < HAL_NUM_STA) + { + if(pTxMetadata->frmType & WDI_MAC_DATA_FRAME) + { + gDsTrafficStats.txStats[pTxMetadata->staIdx].txBytesPushed += + pTxMetadata->fPktlen; + gDsTrafficStats.txStats[pTxMetadata->staIdx].txPacketsPushed += 1; + } + } + + // assign MDPU to correct channel?? + channel = (pTxMetadata->frmType & WDI_MAC_DATA_FRAME)? + /* EAPOL frame uses TX_HIGH_PRIORITY DXE channel + To make sure EAPOL (for second session) is pushed even if TX_LO channel + already reached to low resource condition + This can happen especially in MCC, high data traffic TX in first session + */ +#ifdef FEATURE_WLAN_TDLS + /* I utilizes TDLS mgmt frame always sent at BD_RATE2. (See limProcessTdls.c) + Assumption here is data frame sent by WDA_TxPacket() <- HalTxFrame/HalTxFrameWithComplete() + should take managment path. As of today, only TDLS feature has special data frame + which needs to be treated as mgmt. + */ + (((pTxMetadata->isEapol) || (pTxMetadata->txFlags & WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME))? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI; +#else + ((pTxMetadata->isEapol) ? WDTS_CHANNEL_TX_HIGH_PRI : WDTS_CHANNEL_TX_LOW_PRI) : WDTS_CHANNEL_TX_HIGH_PRI; +#endif + + if (pTxMetadata->isArp) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s :Transmitting ARP packet", __func__); + } + + // Send packet to Transport Driver. + status = gTransportDriver.xmit(pDTDriverContext, pFrame, channel); + if ((WLAN_LOG_LEVEL_ACTIVE == + vos_get_ring_log_level(RING_ID_PER_PACKET_STATS)) && + !(pTxMetadata->frmType & WDI_MAC_CTRL_FRAME)){ + + vos_mem_zero(&txPktStat,sizeof(tPerPacketStats)); + txPktStat.tid = pTxMetadata->fUP; + txPktStat.dxe_timestamp = vos_timer_get_system_ticks(); + /*HW limitation cant get the seq number*/ + txPktStat.seq_num = 0; + txPktStat.data_len = + vos_copy_80211_data((void *)pFrame, txPktStat.data, + pTxMetadata->frmType); + wpalPerPktSerialize(&txPktStat); + } + if (((WDI_ControlBlockType *)pContext)->roamDelayStatsEnabled) + { + vos_record_roam_event(e_DXE_FIRST_XMIT_TIME, (void *)pFrame, pTxMetadata->frmType); + } + return status; +} + +/* DTS Tx Complete function. + * This function should be invoked by the DAL Dataservice to notify tx completion to DXE/SDIO. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * ucTxResReq:TX resource number required by TL + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_CompleteTx(void *pContext, wpt_uint32 ucTxResReq) +{ + void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); + + // Notify completion to Transport Driver. + return gTransportDriver.txComplete(pDTDriverContext, ucTxResReq); +} + +/* DXE Set power state ACK callback. + * This callback function should be invoked by the DXE to notify WDI that set + * power state request is complete. + * Parameters: + * status: status of the set operation + * Return Value: None. + * + */ +void WDTS_SetPowerStateCb(wpt_status status, unsigned int dxePhyAddr) +{ + //print a msg + if(NULL != gSetPowerStateCbInfo.cback) + { + gSetPowerStateCbInfo.cback(status, dxePhyAddr, gSetPowerStateCbInfo.pUserData); + } +} + + +/* DTS Set power state function. + * This function should be invoked by the DAL to notify the WLAN device power state. + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * powerState:Power state of the WLAN device. + * Return Value: SUCCESS Set successfully in DXE control blk. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_SetPowerState(void *pContext, WDTS_PowerStateType powerState, + WDTS_SetPowerStateCbType cback) +{ + void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + if( cback ) + { + //save the cback & cookie + gSetPowerStateCbInfo.pUserData = pContext; + gSetPowerStateCbInfo.cback = cback; + status = gTransportDriver.setPowerState(pDTDriverContext, powerState, + WDTS_SetPowerStateCb); + } + else + { + status = gTransportDriver.setPowerState(pDTDriverContext, powerState, + NULL); + } + + return status; +} + +/* DTS Transport Channel Debug + * Display DXE Channel debugging information + * User may request to display DXE channel snapshot + * Or if host driver detects any abnormal stcuk may display + * Parameters: + * displaySnapshot : Display DXE snapshot option + * enableStallDetect : Enable stall detect feature + This feature will take effect to data performance + Not integrate till fully verification + * Return Value: NONE + * + */ +void WDTS_ChannelDebug(wpt_boolean displaySnapshot, wpt_uint8 debugFlags) +{ + gTransportDriver.channelDebug(displaySnapshot, debugFlags); + return; +} + +/* DTS Transport Channel Kick Dxe + * Request Kick DXE when HDD TX time out happen + * + * Parameters : NONE + * Return Value: NONE + * + */ +void WDTS_ChannelKickDxe() +{ + gTransportDriver.kickDxe(); + return; +} + +/* DTS Stop function. + * Stop Transport driver, ie DXE, SDIO + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_Stop(void *pContext) +{ + void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + status = gTransportDriver.stop(pDTDriverContext); + + wpalMemoryZero(&gDsTrafficStats, sizeof(gDsTrafficStats)); + + return status; +} + +/* DTS Stop function. + * Stop Transport driver, ie DXE, SDIO + * Parameters: + * pContext:Cookie that should be passed back to the caller along with the callback. + * Return Value: SUCCESS Completed successfully. + * FAILURE_XXX Request was rejected due XXX Reason. + * + */ +wpt_status WDTS_Close(void *pContext) +{ + void *pDTDriverContext = WDT_GetTransportDriverContext(pContext); + WDI_DS_ClientDataType *pClientData = WDI_DS_GetDatapathContext(pContext); + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + /*Destroy the mem pool for mgmt BD headers*/ + WDI_DS_MemPoolDestroy(&pClientData->mgmtMemPool); + + /*Destroy the mem pool for mgmt BD headers*/ + WDI_DS_MemPoolDestroy(&pClientData->dataMemPool); + + WDI_DS_LoggingMbDestroy(&pClientData->loggingMbContext); + + status = gTransportDriver.close(pDTDriverContext); + + wpalMemoryFree(pClientData); + + return status; +} + +/* Get free TX data descriptor number from DXE + * Parameters: + * pContext: Cookie that should be passed back to the caller along with the callback. + * Return Value: number of free descriptors for TX data channel + * + */ +wpt_uint32 WDTS_GetFreeTxDataResNumber(void *pContext) +{ + return + gTransportDriver.getFreeTxDataResNumber(WDT_GetTransportDriverContext(pContext)); +} diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_list.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_list.h new file mode 100644 index 000000000000..bbbf4928a8e5 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_list.h @@ -0,0 +1,450 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_LIST_H ) +#define __WLAN_QCT_OS_LIST_H + +/**========================================================================= + + \file wlan_qct_pal_list.h + + \brief define linked list PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent. It is with VOSS support. + + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +//Include vos_list.h here. For non-VOSS PAL, it needs to provide its own definition. +#include "vos_list.h" + +typedef vos_list_t wpt_list; +typedef vos_list_node_t wpt_list_node; + +#define WPAL_LIST_STATUS_BASIC_CHECK(status) ( VOS_IS_STATUS_SUCCESS(status) ? \ + eWLAN_PAL_STATUS_SUCCESS : eWLAN_PAL_STATUS_E_FAILURE ) + +#define WPAL_LIST_IS_VOS_STATUS_BUSY(status) (VOS_STATUS_E_BUSY == (status)) +#define WPAL_LIST_STATUS_BUSY_CHECK(status) ( VOS_IS_STATUS_SUCCESS(status) ? \ + eWLAN_PAL_STATUS_SUCCESS : (WPAL_LIST_IS_VOS_STATUS_BUSY(status) ? \ + eWLAN_PAL_STATUS_E_BUSY : eWLAN_PAL_STATUS_E_FAILURE) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_init() - initialize a wpt_list Linked List + + The \a wpal_list_init() function initializes the specified linked list + 'object'. Upon successful initialization, the state of the list + becomes initialized and available for use through the other wpt_list_xxx + APIs. + + A list must be initialized by calling wpal_list_init() before it + may be used in any other lock functions. + + Attempting to initialize an already initialized list results in + a failure. + + \param pList - pointer to the opaque list object to initialize + + \return eWLAN_PAL_STATUS_SUCCESS - list was successfully initialized and + is ready to be used. + + eWLAN_PAL_STATUS_E_RESOURCES - System resources (other than memory) + are unavailable to initilize the list + + eWLAN_PAL_STATUS_E_NOMEM - insufficient memory exists to initialize + the list + + eWLAN_PAL_STATUS_E_BUSY - The implementation has detected an attempt + to reinitialize the object referenced by list, a previously + initialized, but not yet destroyed, list. + + eWLAN_PAL_STATUS_E_FAULT - pList is an invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +#define wpal_list_init(pList) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_init( (vos_list_t *)(pList) ) ) + + +/**------------------------------------------------------------------------- + + \brief wpal_list_destroy() - Destroy a wpt_list List + + The \a wpal_list_destroy() function shall destroy the list object + referenced by pList. After a successful return from \a wpal_list_destroy() + the list object becomes, in effect, uninitialized. + + A destroyed lock object can be reinitialized using wpal_list_init(); + the results of otherwise referencing the object after it has been destroyed + are undefined. Calls to wpt_list functions to manipulate the list such + will fail if the list or has not been initialized or is destroyed. + Therefore, don't use the list after it has been destroyed until it has + been re-initialized. + + \param pLlist - pointer to the list object to be destroyed. + + \return eWLAN_PAL_STATUS_SUCCESS - list was successfully destroyed. + + eWLAN_PAL_STATUS_E_BUSY - The implementation has detected an attempt + to destroy the object referenced by pList that is still has + nodes. The list must be empty before it can be destroyed. + + eWLAN_PAL_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + eWLAN_PAL_STATUS_E_FAULT - pList is an invalid pointer. + \sa + + ----------------------------------------------------------------------------*/ +#define wpal_list_destroy(pList) \ + WPAL_LIST_STATUS_BUSY_CHECK( vos_list_destroy( (vos_list_t *)(pList) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_front() - insert node at front of a linked list + + The wpal_list_insert_front() API will insert a node at the front of + a properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_front( wpt_list *pList, wpt_list_node *pNode ); +#define wpal_list_insert_front(pList, pNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_front( (vos_list_t *)(pList), (vos_list_node_t *)(pNode) ) ) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_back() - insert node at back of a linked list + + The wpal_list_insert_back() API will insert a node at the back of + a properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be inserted + + \param pNode - Pointer to the list node to be inserted into the list. + + \return eWLAN_PAL__STATUS_SUCCESS - list node was successfully inserted onto + the back of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_back( wpt_list *pList, wpt_list_node *pNode ); +#define wpal_list_insert_back(pList, pNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_back( (vos_list_t *)(pList), (vos_list_node_t *)(pNode) ) ) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_remove_front() - remove node at front of a linked list + + The wpal_list_remove_front() API will remove a node at the front of + a properly initialized wpt_ist object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully removed from + the front of the list. + + eWLAN_PAL_STATUS_E_INVAL - The value specified by pList is not a valid, + initialized list object. + + eWLAN_PAL_STATUS_E_EMPTY - The specified is empty so nodes cannot be + removed. + + eWLAN_PAL_STATUS_E_FAULT - pList is an invalid pointer or ppNode is an + invalid pointer. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_remove_front( wpt_list *pList, wpt_list_node **ppNode ); +#define wpal_list_remove_front(pList, ppNode) \ + ((wpt_status)vos_list_remove_front( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) )) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_remove_back() - remove node at back of a linked list + + The wpal_list_remove_back() API will remove a node at the back of + a properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to a pointer to the list node to be removed + from the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully removed from + the back of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_remove_back( wpt_list *pList, wpt_list_node **ppNode ); +#define wpal_list_remove_back(pList, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_remove_back( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) ) ) + + +/*---------------------------------------------------------------------------- + + \brief wpal_list_size() - return the size of of a linked list + + The wpal_list_size() API will return the number of nodes on the + given wpt_list object. + + \param pList - Pointer to list object where the node will be counted + + \param pSize - Pointer to a size variable, where the size of the + list will be returned. + + \return eWLAN_PAL_STATUS_SUCCESS - list size of the properly initialized + wpt_list object has been returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_size( wpt_list *pList, wpt_uint32 *pSize ); +#define wpal_list_size(pList, pSize) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_size( (vos_list_t *)(pList), (v_SIZE_t *)(pSize) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_front() - peek at the node at front of a linked list + + The wpal_list_peek_front() API will return a pointer to the node at the + front of a properly initialized wpt_list object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the front of the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node at the front of the list was + successfully returned. + + eWLAN_PAL_STATUS_E_Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_front( wpt_list *pList, wpt_list_node **ppNode ); +#define wpal_list_peek_front(pList, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_front( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_back() - peek at the node at back of a linked list + + The wpal_list_peek_back() API will return a pointer to the node at the + back of a properly initialized wpt_list object. The node will *not* be + removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param ppNode - Pointer to a pointer to the list node that exists at + the back of the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node at the back of the list was + successfully returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_back( wpal_list *pList, wpt_list_node **ppNode ); +#define wpal_list_peek_back(pList, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_back( (vos_list_t *)(pList), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_next() - peek at the node after the specified node + + The wpal_list_peek_next() API will return a pointer to the node following the + specified node on a properly initialized wpt_list object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node that follows the + pNode node on the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node following pNode on the properly + initialized list is successfully returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_next( wpt_list *pList, wpt_list_node *pNode, +// wpt_list_node **ppNode ); +#define wpal_list_peek_next(pList, pNode, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_next( (vos_list_t *)(pList), (vos_list_node_t *)(pNode), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_peek_prev() - peek at the node before the specified node + + The wpal_list_peek_prev() API will return a pointer to the node before the + specified node on a properly initialized wpt_list object. The node will + *not* be removed from the list. + + \param pList - Pointer to list object of the list to be 'peeked' + + \param pNode - Pointer to the node that is being 'peeked' + + \param ppNode - Pointer to a pointer to the list node before the + pNode node on the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node before pNode on the properly + initialized list is successfully returned. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_peek_prev( wpt_list *pList, wpt_list_node *pNode, +// wpt_list_node **ppNode ); +#define wpal_list_peek_prev(pList, pNode, ppNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_peek_prev( (vos_list_t *)(pList), (vos_list_node_t *)(pNode), (vos_list_node_t **)(ppNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_before() - insert node at front of a specified + list node + + The wpal_list_insert_before() API will insert a node onto a properly + initialized wpt_list object in front of the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + in front of. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + eWLAN_PAL_STATUS_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_before( wpt_list *pList, +// wpt_list_node *pNodeToInsert, +// wpt_list_node *pNode ); +#define wpal_list_insert_before(pList, pNodeToInsert, pNode) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_before( (vos_list_t *)(pList), \ + (vos_list_node_t *)(pNodeToInsert), (vos_list_node_t *)(pNode) ) ) + +/**--------------------------------------------------------------------------- + + \brief wpal_list_insert_after() - insert node behind a specified list node + + The wpal_list_insert_after() API will insert a node onto a properly + initialized wpt_list object after the specified list node. + + \param pList - Pointer to list object where the node will be inserted + + \param pNodeToInsert - Pointer to the list node to be inserted into the list. + + \param pNode - Pointer to the list node where pNodeToInsert will be inserted + after. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully inserted onto + the front of the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_insert_after( wpt_list *pList, +// wpt_list_node *pNodeToInsert, +// wpt_list_node *pNode ); +#define wpal_list_insert_after(pList, pNodeToInsert, pNode) \ + (WPAL_LIST_STATUS_BASIC_CHECK( vos_list_insert_after((vos_list_t *)(pList), \ + (vos_list_node_t *)(pNodeToInsert), (vos_list_node_t *)(pNode) )) + + +/**--------------------------------------------------------------------------- + + \brief wpal_list_remove_node() - remove specified node from wpt_list list + + The wpal_list_remove_node() API will remove a specified node from the + properly initialized wpt_list object. + + \param pList - Pointer to list object where the node will be removed + + \param ppNode - Pointer to the node to be removed from the list. + + \return eWLAN_PAL_STATUS_SUCCESS - list node was successfully removed from + the list. + + eWLAN_PAL_STATUS_E_FAILURE - Failure. + + \sa + + --------------------------------------------------------------------------*/ +//wpt_status wpal_list_remove_node( wpt_list *pList, wpt_list_node *pNodeToRemove ); +#define wpal_list_remove_node(pList, pNodeToRemove) \ + WPAL_LIST_STATUS_BASIC_CHECK( vos_list_remove_node( (vos_list_t *)(pList), \ + (vos_list_node_t *)(pNodeToRemove) ) ) + + +#endif // __WLAN_QCT_OS_LIST_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_status.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_status.h new file mode 100644 index 000000000000..01eac26bedf4 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_status.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_STATUS_H ) +#define __WLAN_QCT_OS_STATUS_H + +/**========================================================================= + + \file wlan_qct_os_status.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent(Windows XP). + + + ========================================================================*/ + +#include "vos_status.h" + +/** + * \brief Macros to derive PAL STATUS from the VOS STATUS + */ + +#define WPAL_IS_VOS_STATUS_E_RESOURCES(status) ( VOS_STATUS_E_RESOURCES == (status)) +#define WPAL_IS_VOS_STATUS_E_NOMEM(status) ( VOS_STATUS_E_NOMEM == (status)) +#define WPAL_IS_VOS_STATUS_E_INVAL(status) ( VOS_STATUS_E_INVAL == (status)) +#define WPAL_IS_VOS_STATUS_E_FAULT(status) ( VOS_STATUS_E_FAULT == (status)) +#define WPAL_IS_VOS_STATUS_E_BUSY(status) ( VOS_STATUS_E_BUSY == (status)) +#define WPAL_IS_VOS_STATUS_E_CANCELED(status) ( VOS_STATUS_E_CANCELED == (status)) +#define WPAL_IS_VOS_STATUS_E_ABORTED(status) ( VOS_STATUS_E_ABORTED == (status)) +#define WPAL_IS_VOS_STATUS_E_NOSUPPORT(status) ( VOS_STATUS_E_NOSUPPORT == (status)) +#define WPAL_IS_VOS_STATUS_E_EMPTY(status) ( VOS_STATUS_E_EMPTY == (status)) +#define WPAL_IS_VOS_STATUS_E_EXISTS(status) ( VOS_STATUS_E_EXISTS == (status)) +#define WPAL_IS_VOS_STATUS_E_TIMEOUT(status) ( VOS_STATUS_E_TIMEOUT == (status)) + + +#define WPAL_STATUS_E_TIMEOUT_CHECK(status) ( WPAL_IS_VOS_STATUS_E_TIMEOUT(status)? eWLAN_PAL_STATUS_E_TIMEOUT : eWLAN_PAL_STATUS_E_FAILURE ) + +#define WPAL_STATUS_E_EXISTS_CHECK(status) ( WPAL_IS_VOS_STATUS_E_EXISTS(status)? eWLAN_PAL_STATUS_E_EXISTS : WPAL_STATUS_E_TIMEOUT_CHECK(status) ) + +#define WPAL_STATUS_E_EMPTY_CHECK(status) ( WPAL_IS_VOS_STATUS_E_EMPTY(status)? eWLAN_PAL_STATUS_E_EMPTY : WPAL_STATUS_E_EXISTS_CHECK(status) ) + +#define WPAL_STATUS_E_NOSUPPORT_CHECK(status) ( WPAL_IS_VOS_STATUS_E_NOSUPPORT(status)? eWLAN_PAL_STATUS_E_NOSUPPORT : WPAL_STATUS_E_EMPTY_CHECK(status) ) + +#define WPAL_STATUS_E_ABORTED_CHECK(status) ( WPAL_IS_VOS_STATUS_E_ABORTED(status)? eWLAN_PAL_STATUS_E_ABORTED : WPAL_STATUS_E_NOSUPPORT_CHECK(status) ) + +#define WPAL_STATUS_E_CANCELED_CHECK(status) ( WPAL_IS_VOS_STATUS_E_CANCELED(status)? eWLAN_PAL_STATUS_E_CANCELED : WPAL_STATUS_E_ABORTED_CHECK(status) ) + +#define WPAL_STATUS_E_BUSY_CHECK(status) ( WPAL_IS_VOS_STATUS_E_BUSY(status)? eWLAN_PAL_STATUS_E_BUSY : WPAL_STATUS_E_CANCELED_CHECK(status) ) + +#define WPAL_STATUS_E_FAULT_CHECK(status) ( WPAL_IS_VOS_STATUS_E_FAULT(status)? eWLAN_PAL_STATUS_E_FAULT : WPAL_STATUS_E_BUSY_CHECK(status) ) + +#define WPAL_STATUS_E_INVAL_CHECK(status) ( WPAL_IS_VOS_STATUS_E_INVAL(status)? eWLAN_PAL_STATUS_E_INVAL : WPAL_STATUS_E_FAULT_CHECK(status) ) + +#define WPAL_STATUS_E_NOMEM_CHECK(status) ( WPAL_IS_VOS_STATUS_E_NOMEM(status)? eWLAN_PAL_STATUS_E_NOMEM : WPAL_STATUS_E_INVAL_CHECK(status) ) + +#define WPAL_STATUS_E_RESOURCES_CHECK(status) ( WPAL_IS_VOS_STATUS_E_RESOURCES(status)? eWLAN_PAL_STATUS_E_RESOURCES : WPAL_STATUS_E_NOMEM_CHECK(status) ) + +#define WPAL_VOS_TO_WPAL_STATUS(status) ( VOS_IS_STATUS_SUCCESS(status)? eWLAN_PAL_STATUS_SUCCESS : WPAL_STATUS_E_RESOURCES_CHECK(status) ) + +#endif // __WLAN_QCT_OS_STATUS_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h new file mode 100644 index 000000000000..ae762321ab3a --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_sync.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_SYNC_H ) +#define __WLAN_QCT_OS_SYNC_H + +/**========================================================================= + + \file wlan_qct_os_sync.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent(LA). + + + ========================================================================*/ + +#include "vos_event.h" +#include "vos_lock.h" + +/*Reuse the vos lock and vos event*/ +typedef vos_lock_t wpt_mutex; +typedef vos_event_t wpt_event; + + +#endif // __WLAN_QCT_OS_SYNC_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h new file mode 100644 index 000000000000..162c2ca8a04b --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_timer.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_TIMER_H ) +#define __WLAN_QCT_OS_TIMER_H + +/**========================================================================= + + \file wlan_qct_os_timer.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent (Linux Android). + + + ========================================================================*/ + +#include "vos_timer.h" + +typedef struct +{ + vos_timer_t timerObj; +} wpt_os_timer; + + +#endif // __WLAN_QCT_OS_TIMER_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_trace.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_trace.h new file mode 100644 index 000000000000..03daccdaf9fc --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_trace.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_TRACE_H ) +#define __WLAN_QCT_OS_TRACE_H + +#include + +#if !defined(__printf) +#define __printf(a,b) +#endif + +#ifdef WLAN_DEBUG + +/**---------------------------------------------------------------------------- + + \brief WPAL_TRACE() / wpalTrace() - Trace / logging API + + Users wishing to add tracing information to their code should use + WPAL_TRACE. WPAL_TRACE() will compile into a call to wpalTrace() when + tracing is enabled. + + \param module - module identifier. A member of the wpt_moduleid + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the wpt_tracelevel + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param strFormat - format string. The message to be logged. This format + string contains printf-like replacement parameters, which follow + this parameter in the variable argument list. + + \return nothing + + --------------------------------------------------------------------------*/ +void __printf(3,4) wpalTrace( wpt_moduleid module, wpt_tracelevel level, + char *strFormat, ... ); + +/**---------------------------------------------------------------------------- + + \brief WPAL_DUMP() / wpalDump() - Trace / logging API + + Users wishing to add tracing memory dumps to their code should use + WPAL_DUMP. WPAL_DUMP() will compile into a call to wpalDump() when + tracing is enabled. + + \param module - module identifier. A member of the wpt_moduleid + enumeration that identifies the module performing the dump + + \param level - trace level. A member of the wpt_tracelevel + enumeration indicating the severity of the condition causing the + memory to be dumped. More severe conditions are more + likely to be logged. + + \param pMemory - memory. A pointer to the memory to be dumped + + \param length - length. How many bytes of memory to be dumped + + \return nothing + + --------------------------------------------------------------------------*/ +void wpalDump( wpt_moduleid module, wpt_tracelevel level, + wpt_uint8 *memory, wpt_uint32 length); + +#define WPAL_ASSERT( _condition ) do { \ + if ( ! ( _condition ) ) \ + { \ + printk(KERN_CRIT "VOS ASSERT in %s Line %d\n", __func__, __LINE__); \ + WARN_ON(1); \ + } \ + } while (0) +#else //WLAN_DEBUG + +static inline void wpalTrace( wpt_moduleid module, wpt_tracelevel level, + char *strFormat, ... ){}; +static inline void wpalDump( wpt_moduleid module, wpt_tracelevel level, + wpt_uint8 *memory, wpt_uint32 length) {}; +static inline void wpalTraceSetLevel( wpt_moduleid module, + wpt_tracelevel level, wpt_boolean on ) {}; +static inline void wpalTraceDisplay(void) {}; +#define WPAL_ASSERT(x) do {} while (0); + +#endif //WLAN_DEBUG + +#define WPAL_TRACE wpalTrace +#define WPAL_DUMP wpalDump + +#endif // __WLAN_QCT_OS_TRACE_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_type.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_type.h new file mode 100644 index 000000000000..a9a724e2c6aa --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_os_type.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_OS_TYPE_H ) +#define __WLAN_QCT_OS_TYPE_H + +/**========================================================================= + + \file wlan_qct_pal_type.h + + \brief define basi types PAL exports. wpt = (Wlan Pal Type) + + Definitions for platform dependent. This is for Linux/Android + + + ========================================================================*/ + +#include + +typedef u32 wpt_uint32; + +typedef s32 wpt_int32; + +typedef u16 wpt_uint16; + +typedef s16 wpt_int16; + +typedef u8 wpt_uint8; + +typedef wpt_uint8 wpt_byte; + +typedef s8 wpt_int8; + +typedef wpt_uint8 wpt_boolean; + +typedef u64 wpt_uint64; + +typedef s64 wpt_int64; + +#define WPT_INLINE __inline__ +#define WPT_STATIC static + + +#endif // __WLAN_QCT_OS_TYPE_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h new file mode 100644 index 000000000000..f0c6045d935a --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pack_align.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PACK_ALIGN_H ) +#define __WLAN_QCT_PACK_ALIGN_H + +/**========================================================================= + + \file wlan_pack_align.h + + \brief pack and align primitives + + Definitions for platform independent means of packing and aligning + data structures + + + ========================================================================*/ + +/* + + Place the macro WPT_PACK_START above a structure declaration to pack. We + are not going to allow modifying the pack size because pack size cannot be + specified in AMSS and GNU. Place the macro WPT_PACK_END below a structure + declaration to stop the pack. This requirement is necessitated by Windows + which need pragma based prolog and epilog. + + Pack-size > 1-byte is not supported since gcc and arm do not support that. + + Here are some examples + + 1. Pack-size 1-byte foo_t across all platforms + + WPT_PACK_START + typedef WPT_PACK_PRE struct foo_s { ... } WPT_PACK_POST foo_t; + WPT_PACK_END + + 2. 2-byte alignment for foo_t across all platforms + + typedef WPT_ALIGN_PRE(2) struct foo_s { ... } WPT_ALIGN_POST(2) foo_t; + + 3. Pack-size 1-byte and 2-byte alignment for foo_t across all platforms + + WPT_PACK_START + typedef WPT_PACK_PRE WPT_ALIGN_PRE(2) struct foo_s { ... } WPT_ALIGN_POST(2) WPT_PACK_POST foo_t; + WPT_PACK_END + +*/ + +#if defined __GNUC__ + + #define WPT_PACK_START + #define WPT_PACK_END + + #define WPT_PACK_PRE + #define WPT_PACK_POST __attribute__((__packed__)) + + #define WPT_ALIGN_PRE(__value) + #define WPT_ALIGN_POST(__value) __attribute__((__aligned__(__value))) + +#elif defined __arm + + #define WPT_PACK_START + #define WPT_PACK_END + + #define WPT_PACK_PRE __packed + #define WPT_PACK_POST + + #define WPT_ALIGN_PRE(__value) __align(__value) + #define WPT_ALIGN_POST(__value) + +#elif defined _MSC_VER + +#define WPT_PACK_START __pragma(pack(push,1)) +#define WPT_PACK_END __pragma(pack(pop)) + + #define WPT_PACK_PRE + #define WPT_PACK_POST + + #define WPT_ALIGN_PRE(__value) __declspec(align(__value)) + #define WPT_ALIGN_POST(__value) + +#else + + #error Unsupported compiler!!! + +#endif + +#endif // __WLAN_QCT_PACK_ALIGN_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h new file mode 100644 index 000000000000..aeacf6f58a02 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_api.h @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_API_H ) +#define __WLAN_QCT_PAL_API_H + +/**========================================================================= + + \file wlan_qct_pal_api.h + + \brief define general APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent + + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" + +#ifdef MEMORY_DEBUG +#include "vos_memory.h" +#endif /* MEMORY_DEBUG */ + +typedef struct sPalStruct +{ + /*?must check the data type*/ + void* devHandle; +} tPalContext; + +extern tPalContext gContext; + +/*********************************MACRO**********************/ + +// macro to get maximum of two values. +#define WPAL_MAX( _x, _y ) ( ( (_x) > (_y) ) ? (_x) : (_y) ) + +// macro to get minimum of two values +#define WPAL_MIN( _x, _y ) ( ( (_x) < (_y) ) ? (_x) : (_y) ) + +// macro to get the ceiling of an integer division operation... +#define WPAL_CEIL_DIV( _a, _b ) (( 0 != (_a) % (_b) ) ? ( (_a) / (_b) + 1 ) : ( (_a) / (_b) )) + +// macro to return the floor of an integer division operation +#define WPAL_FLOOR_DIV( _a, _b ) ( ( (_a) - ( (_a) % (_b) ) ) / (_b) ) + +#define WPAL_SWAP_U16(_x) \ + ( ( ( (_x) << 8 ) & 0xFF00 ) | ( ( (_x) >> 8 ) & 0x00FF ) ) + +#define WPAL_SWAP_U32(_x) \ + (( ( ( (_x) << 24 ) & 0xFF000000 ) | ( ( (_x) >> 24 ) & 0x000000FF ) ) | \ + ( ( ( (_x) << 8 ) & 0x00FF0000 ) | ( ( (_x) >> 8 ) & 0x0000FF00 ) )) + +// Endian operations for Big Endian and Small Endian modes +#ifndef ANI_BIG_BYTE_ENDIAN + +//This portion is for little-endian cpu +#define WPAL_CPU_TO_BE32(_x) WPAL_SWAP_U32(_x) +#define WPAL_BE32_TO_CPU(_x) WPAL_SWAP_U32(_x) +#define WPAL_CPU_TO_BE16(_x) WPAL_SWAP_U16(_x) +#define WPAL_BE16_TO_CPU(_x) WPAL_SWAP_U16(_x) +#define WPAL_CPU_TO_LE32(_x) (_x) +#define WPAL_LE32_TO_CPU(_x) (_x) +#define WPAL_CPU_TO_LE16(_x) (_x) +#define WPAL_LE16_TO_CPU(_x) (_x) + +#else //#ifndef ANI_BIG_BYTE_ENDIAN + +//This portion is for big-endian cpu +#define WPAL_CPU_TO_BE32(_x) (_x) +#define WPAL_BE32_TO_CPU(_x) (_x) +#define WPAL_CPU_TO_BE16(_x) (_x) +#define WPAL_BE16_TO_CPU(_x) (_x) +#define WPAL_CPU_TO_LE32(_x) WPAL_SWAP_U32(_x) +#define WPAL_LE32_TO_CPU(_x) WPAL_SWAP_U32(_x) +#define WPAL_CPU_TO_LE16(_x) WPAL_SWAP_U16(_x) +#define WPAL_LE16_TO_CPU(_x) WPAL_SWAP_U16(_x) + +#endif //#ifndef ANI_BIG_BYTE_ENDIAN + + +/*********************************Generic API*******************************/ +/*--------------------------------------------------------------------------- + wpalOpen - Initialize PAL + Param: + ppPalContext – pointer to a caller allocated pointer. It is opaque to caller. + Caller save the returned pointer for future use when calling + PAL APIs. If this is NULL, it means that PAL doesn't need it. + devHandle - pointer to the OS specific device handle + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalOpen(void **ppPalContext, void *devHandle); + +/*--------------------------------------------------------------------------- + wpalClose - Release PAL + Param: + pPalContext – pointer returned from wpalOpen. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalClose(void *pPalContext); + + +/*********************************Memory API********************************/ +#ifdef MEMORY_DEBUG +/* For Memory Debugging, Hook up PAL memory API to VOS memory API */ +#define wpalMemoryAllocate vos_mem_malloc +#define wpalMemoryFree vos_mem_free +#else + +/*--------------------------------------------------------------------------- + wpalMemoryAllocate - Allocate memory + Param: + size – number of bytes to allocate + Return: + A pointer to the allocated memory. + NULL – fail to allocate memory +---------------------------------------------------------------------------*/ +void *wpalMemoryAllocate(wpt_uint32 size); + +/*--------------------------------------------------------------------------- + wpalMemoryFree - Free allocated memory + Param: + pv – pointer to buffer to be freed + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryFree(void *pv); +#endif /* MEMORY_DEBUG */ + +/*--------------------------------------------------------------------------- + wpalMemoryCopy - copy memory + Param: + dest – address which data is copied to + src – address which data is copied from + size – number of bytes to copy + Return: + eWLAN_PAL_STATUS_SUCCESS + eWLAN_PAL_STATUS_INVALID_PARAM +---------------------------------------------------------------------------*/ +wpt_status wpalMemoryCopy(void * dest, void * src, wpt_uint32 size); + + +/*--------------------------------------------------------------------------- + wpalMemoryCompare - compare memory + Param: + buf1 – address of buffer1 + buf2 – address of buffer2 + size – number of bytes to compare + Return: + eWLAN_PAL_TRUE – if two buffers have same content + eWLAN_PAL_FALSE – not match +---------------------------------------------------------------------------*/ +wpt_boolean wpalMemoryCompare(void * buf1, void * buf2, wpt_uint32 size); + +/*--------------------------------------------------------------------------- + wpalMemoryZero - Zero memory + Param: + buf – address of buffer to be zero + size – number of bytes to zero + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryZero(void *buf, wpt_uint32 size); + + +/*--------------------------------------------------------------------------- + wpalMemoryFill - Fill memory with one pattern + Param: + buf – address of buffer to be zero + size – number of bytes to zero + bFill - one byte of data to fill in (size) bytes from the start of the buffer + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryFill(void *buf, wpt_uint32 size, wpt_byte bFill); + + +/*--------------------------------------------------------------------------- + wpalDmaMemoryAllocate - Allocate memory ready for DMA. Aligned at 4-byte + Param: + pPalContext - PAL context pointer + size – number of bytes to allocate + ppPhysicalAddr – Physical address of the buffer if allocation succeeds + Return: + A pointer to the allocated memory (virtual address). + NULL – fail to allocate memory +-----------------------------------------------------------------------------*/ +void *wpalDmaMemoryAllocate(wpt_uint32 size, void **ppPhysicalAddr); + +/*--------------------------------------------------------------------------- + wpalDmaMemoryFree - Free memory ready for DMA + Param: + pPalContext - PAL context pointer + pv – address for the buffer to be freed + Return: + None +---------------------------------------------------------------------------*/ +void wpalDmaMemoryFree(void *pv); + + + +/*--------------------------------------------------------------------------- + wpalDbgReadRegister - Read register from the WiFi BB chip + Param: + regAddr - register address + pregValue - return value from register if success + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDbgReadRegister(wpt_uint32 regAddr, wpt_uint32 *pregValue); + +/*--------------------------------------------------------------------------- + wpalDbgWriteRegister - Write a value to the register in the WiFi BB chip + Param: + regAddr - register address + regValue - value to be written + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDbgWriteRegister(wpt_uint32 regAddr, wpt_uint32 regValue); + +/*--------------------------------------------------------------------------- + wpalDbgReadMemory - Read memory from WiFi BB chip space + Param: + memAddr - address of memory + buf - output + len - length to be read + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDbgReadMemory(wpt_uint32 memAddr, wpt_uint8 *buf, wpt_uint32 len); + +/*--------------------------------------------------------------------------- + wpalDbgWriteMemory - Write a value to the memory in the WiFi BB chip space + Param: + memAddr - memory address + buf - vlaue to be written + len - length of buf + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDbgWriteMemory(wpt_uint32 memAddr, wpt_uint8 *buf, wpt_uint32 len); + +/*--------------------------------------------------------------------------- + wpalDriverShutdown - Shutdown WLAN driver + + This API is requied by SSR, call in to 'VOS shutdown' to shutdown WLAN + driver when Riva crashes. + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDriverShutdown(void); + +/*--------------------------------------------------------------------------- + wpalDriverShutdown - Re-init WLAN driver + + This API is requied by SSR, call in to 'VOS re-init' to re-init WLAN + driver. + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDriverReInit(void); + +/*--------------------------------------------------------------------------- + wpalRivaSubystemRestart - Initiate Riva SSR + + This API is called by WLAN driver to initiate Riva SSR + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalRivaSubystemRestart(void); + +/*--------------------------------------------------------------------------- + wpalWlanReload - Initiate WLAN Driver reload + + Param: + None + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalWlanReload(void); + +/*--------------------------------------------------------------------------- + wpalWcnssResetIntr - Trigger the reset FIQ to Riva + + Param: + None + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalWcnssResetIntr(void); + +/*--------------------------------------------------------------------------- + wpalWcnssIsProntoHwVer3 - Check for Pronto ver3 HW + + Param: + None + Return: + TRUE if Ponto Hw Ver 3 + Therefore use WQ6 instead of WQ23 for TX Low/High Priority Channel +---------------------------------------------------------------------------*/ +int wpalWcnssIsProntoHwVer3(void); +/*--------------------------------------------------------------------------- + wpalFwDumpReq - Trigger the dump commands to Firmware + + Param: + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + async -asynchronous event. Don't wait for completion. + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalFwDumpReq(wpt_uint32 cmd, wpt_uint32 arg1, wpt_uint32 arg2, + wpt_uint32 arg3, wpt_uint32 arg4, wpt_boolean async); + +/*--------------------------------------------------------------------------- + wpalDevicePanic - Trigger Device Panic + Trigger device panic to help debug + + Param: + NONE + + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalDevicePanic(void); + +/*--------------------------------------------------------------------------- + wpalIslogPInProgress - calls vos API vos_is_logp_in_progress() + + Param: + NONE + Return: + STATUS +--------------------------------------------------------------------------*/ +int wpalIslogPInProgress(void); + +/*--------------------------------------------------------------------------- + wpalIsSsrPanicOnFailure - calls vos API isSsrPanicOnFailure() + + Param: + NONE + Return: + STATUS +--------------------------------------------------------------------------*/ +int wpalIsSsrPanicOnFailure(void); + +int wpalGetDxeReplenishRXTimerVal(void); +int wpalIsDxeSSREnable(void); + +wpt_uint8 wpalIsFwLoggingEnabled(void); +wpt_uint8 wpalIsFwLoggingSupported(void); +wpt_uint8 wpalIsFwEvLoggingEnabled(void); +bool wpalIsArpPkt(void *pPacket); +void wpalUpdateTXArpFWdeliveredStats(void); +#endif // __WLAN_QCT_PAL_API_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h new file mode 100644 index 000000000000..bf13fe1b088c --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_device.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_QCT_PAL_DEVICE_H +#define WLAN_QCT_PAL_DEVICE_H +/* ==================================================================================================================== + + @file wlan_qct_pal_device.h + + @brief + This file contains the external API exposed by WLAN PAL Device specific functionalities + Copyright (c) 2011 Qualcomm Incorporated. All Rights Reserved + Qualcomm Confidential and Properietary + + * ==================================================================================================================*/ + +/* ==================================================================================================================== + EDIT HISTORY FOR FILE + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order + + When Who What, Where, Why + --------- -------- ------------------------------------------------------------------------------- + FEB/07/11 sch Create module + * ==================================================================================================================*/ + +/* ==================================================================================================================== + INCLUDE FILES FOR MODULES + * ==================================================================================================================*/ +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_pal_trace.h" + +/* ==================================================================================================================== + PREPROCESSORS AND DEFINITIONS + * ==================================================================================================================*/ +#define DXE_INTERRUPT_TX_COMPLE 0x02 +#define DXE_INTERRUPT_RX_READY 0x04 +#define WPAL_ISR_CLIENT_MAX 0x08 + +#define WPAL_SMSM_WLAN_TX_ENABLE 0x00000400 +#define WPAL_SMSM_WLAN_TX_RINGS_EMPTY 0x00000200 + +typedef enum +{ + WPAL_DEBUG_START_HEALTH_TIMER = 1<<0, + WPAL_DEBUG_TX_DESC_RESYNC = 1<<1, +} WPAL_DeviceDebugFlags; +/* ==================================================================================================================== + @ Function Name + wpalIsrType + + @ Description + DXE ISR functio prototype + DXE should register ISR function into platform + + @ Parameters + pVoid pDXEContext : DXE module control block + + @ Return + NONE + * ==================================================================================================================*/ +typedef void (* wpalIsrType)(void *usrCtxt); + +/* ==================================================================================================================== + GLOBAL FUNCTIONS + * ==================================================================================================================*/ +/* ==================================================================================================================== + @ Function Name + + @ Description + + @ Arguments + + @ Return value + + @ Note + + * ==================================================================================================================*/ +wpt_status wpalDeviceInit +( + void *devHandle +); + +/* ==================================================================================================================== + @ Function Name + + @ Description + + @ Arguments + + @ Return value + + @ Note + + * ==================================================================================================================*/ +wpt_status wpalDeviceClose +( + void *deviceC +); + +/* ========================================================================== + CLIENT SERVICE EXPOSE FUNCTIONS GENERIC + * =========================================================================*/ +/** + @brief wpalRegisterInterrupt provides a mechansim for client + to register support for a given interrupt + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can register to support one of these. It is expected that the core + DXE implementation will invoke this API twice, once for each interrupt. + + @param intType: Enumeration of the interrupt type (TX or RX) + @param callbackFunction: ISR function pointer + @param usrCtxt: User context passed back whenever the + callbackFunction is invoked + + @return SUCCESS if the registration was successful +*/ +wpt_status wpalRegisterInterrupt +( + wpt_uint32 intType, + wpalIsrType callbackFunction, + void *usrCtxt +); + +/** + @brief wpalUnRegisterInterrupt provides a mechansim for client + to un-register for a given interrupt + + When DXE stop, remove registered information from PAL + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return NONE +*/ + +void wpalUnRegisterInterrupt +( + wpt_uint32 intType +); + +/** + @brief wpalEnableInterrupt provides a mechansim for a client + to request that a given interrupt be enabled + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can request that the platform-specific adaptation layer allows a + given interrupt to occur. The expectation is that if a given + interrupt is not enabled, if the interrupt occurs then the APPS CPU + will not be interrupted. + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return SUCCESS if the interrupt was enabled +*/ +wpt_status wpalEnableInterrupt +( + wpt_uint32 intType +); + +/** + @brief wpalDisableInterrupt provides a mechansim for a client + to request that a given interrupt be disabled + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can request that the platform-specific adaptation layer not allow a + given interrupt to occur. The expectation is that if a given + interrupt is not enabled, if the interrupt occurs then the APPS CPU + will not be interrupted. + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return SUCCESS if the interrupt was disabled +*/ +wpt_status wpalDisableInterrupt +( + wpt_uint32 intType +); + +/** + @brief wpalWriteRegister provides a mechansim for a client + to write data into a hardware data register + + @param address: Physical memory address of the register + @param data: Data value to be written + + @return SUCCESS if the data was successfully written +*/ +wpt_status wpalReadRegister +( + wpt_uint32 address, + wpt_uint32 *data +); + +/** + @brief wpalReadRegister provides a mechansim for a client + to read data from a hardware data register + + @param address: Physical memory address of the register + @param data: Return location for value that is read + + @return SUCCESS if the data was successfully read +*/ +wpt_status wpalWriteRegister +( + wpt_uint32 address, + wpt_uint32 data +); + +/** + @brief wpalReadDeviceMemory provides a mechansim for a client + to read data from the hardware address space + + @param address: Start address of physical memory to be read + @param d_buffer: Virtual destination address to which the + data will be written + @param len: Number of bytes of data to be read + + @return SUCCESS if the data was successfully read +*/ +wpt_status wpalReadDeviceMemory +( + wpt_uint32 address, + wpt_uint8 *DestBuffer, + wpt_uint32 len +); + +/** + @brief wpalWriteDeviceMemory provides a mechansim for a client + to write data into the hardware address space + + @param address: Start address of physical memory to be written + @param s_buffer: Virtual source address from which the data will + be read + @param len: Number of bytes of data to be written + + @return SUCCESS if the data was successfully written +*/ +wpt_status wpalWriteDeviceMemory +( + wpt_uint32 address, + wpt_uint8 *srcBuffer, + wpt_uint32 len +); + +/** + @brief wpalNotifySmsm provides a mechansim for a client to + notify SMSM to start DXE engine and/or condition of Tx + ring buffer + + @param clrSt: bit(s) to be cleared on the MASK + @param setSt: bit(s) to be set on the MASK + + @return SUCCESS if the operation is successful +*/ +wpt_status wpalNotifySmsm +( + wpt_uint32 clrSt, + wpt_uint32 setSt +); + +/** + @brief wpalActivateRxInterrupt activates wpalRxIsr + + @param NONE + + @return NONE +*/ +void wpalActivateRxInterrupt(void); + +/** + @brief wpalInactivateRxInterrupt inactivates wpalRxIsr + + @param NONE + + @return NONE +*/ +void wpalInactivateRxInterrupt(void); + + +int wpal_get_int_state +( + wpt_uint32 intType +); + +#endif /* WLAN_QCT_PAL_DEVICE_H*/ diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h new file mode 100644 index 000000000000..4645c72ec974 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_list.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_LIST_H ) +#define __WLAN_QCT_PAL_LIST_H + +/**========================================================================= + + \file wlan_qct_pal_list.h + + \brief define linked list PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent. + + + ========================================================================*/ + +#include "wlan_qct_os_list.h" + + +#endif // __WLAN_QCT_PAL_LIST_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h new file mode 100644 index 000000000000..a059769790a0 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_msg.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_MSG_H ) +#define __WLAN_QCT_PAL_MSG_H + +/**========================================================================= + + \file wlan_qct_pal_msg.h + + \brief define general message APIs PAL exports to support legacy UMAC. + wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform dependent. Only work with legacy UMAC. + + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" + +/* Random signature to detect SMD OPEN NOTIFY */ +#define WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG 0x09E2 + +/* Random signature to detect SMD DATA NOTIFY */ +#define WPAL_MC_MSG_SMD_NOTIF_DATA_SIG 0xDA7A + +typedef struct swpt_msg wpt_msg; + +typedef void (*wpal_msg_callback)(wpt_msg *pMsg); + +struct swpt_msg +{ + wpt_uint16 type; + wpt_uint16 reserved; + void *ptr; + wpt_uint32 val; + wpal_msg_callback callback; + void *pContext; +}; + + +/*--------------------------------------------------------------------------- + wpalPostCtrlMsg – Post a message to control context so it can + be processed in that context. + Param: + pPalContext – A PAL context + pMsg – a pointer to called allocated object; Caller retain the ownership + after this API returns. +---------------------------------------------------------------------------*/ +wpt_status wpalPostCtrlMsg(void *pPalContext, wpt_msg *pMsg); + + +/*--------------------------------------------------------------------------- + wpalPostTxMsg – Post a message to TX context so it can be processed in that context. + Param: + pPalContext – A PAL context + pMsg – a pointer to called allocated object; Caller retain the ownership + after this API returns. +---------------------------------------------------------------------------*/ +wpt_status wpalPostTxMsg(void *pPalContext, wpt_msg *pMsg); + +/*--------------------------------------------------------------------------- + wpalPostRxMsg – Post a message to RX context so it can be processed in that context. + Param: + pPalContext – A PAL context + pMsg – a pointer to called allocated object; Caller retain the ownership + after this API returns. +---------------------------------------------------------------------------*/ +wpt_status wpalPostRxMsg(void *pPalContext, wpt_msg *pMsg); + + + +#endif // __WLAN_QCT_PAL_API_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h new file mode 100644 index 000000000000..e57fda9d6a60 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_packet.h @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_PACKET_H ) +#define __WLAN_QCT_PAL_PACKET_H + +/**========================================================================= + + \file wlan_qct_pal_packet.h + + \brief define PAL packet. wpt = (Wlan Pal Type) + + Definitions for platform independent. + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "vos_types.h" +#ifdef FEATURE_WLAN_DIAG_SUPPORT +#include "vos_diag_core_log.h" +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +// The size of the data buffer in vos/pal packets +// Explanation: +// MTU size = 1500 bytes +// Max number of BD/PDUs required to hold payload of 1500 = +// 12 PDUs (124 bytes each) + 1 BD (12 bytes for payload) = +// 13 BD/PDUs = 13 x 128 = 1664 bytes +// +// In case of A-MSDU with each MSDU having payload of 1500 bytes: +// 1st MSDU = requires 13 BD/PDUs as per the above equation. +// 2nd MSDU = HW inserts an extra BD to hold the information of the 2nd +// MSDU and the payload portion of this BD is unused which means to cover +// 1500 bytes we require 13 PDUs. +// So 13 PDUs + 1 BD = 14 BD/PDUs = 1792 bytes. +// +// HOWEVER +// In case of A-MSDU with errors, the ADU will push to the host up to +// 2346 bytes. If that is the 2nd or later MSDU the worst case is: +// 1 Prepended BD/PDU +// 1 BD/PDU containing the 1st 4 bytes of the delimiter +// 1 BD/PDU containing the last 10 bytes of the delimiter +// plus the first 114 of the payload +// 18 BD/PDUs containing the remaining 2232 bytes of the payload +// 2346 - 114 = 2232; 2232 / 124 = 18 +// So 21 BD/PDUs are required + +//The size of AMSDU frame per spec can be a max of 3839 bytes +// in BD/PDUs that means 30 (one BD = 128 bytes) +// we must add the size of the 802.11 header to that +#define VPKT_SIZE_BUFFER ((30 * 128) + 32) + +/* Transport channel count to report DIAG */ +#define WPT_NUM_TRPT_CHANNEL 8 +/* Transport channel name string size */ +#define WPT_TRPT_CHANNEL_NAME 4 + +typedef enum +{ + ///Packet is used to transmit 802.11 Management frames. + eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT, + ///Packet is used to transmit 802.11 Data frames. + eWLAN_PAL_PKT_TYPE_TX_802_11_DATA, + ///Packet is used to transmit 802.3 Data frames. + eWLAN_PAL_PKT_TYPE_TX_802_3_DATA, + ///Packet contains Received data of an unknown frame type + eWLAN_PAL_PKT_TYPE_RX_RAW +} wpt_packet_type; + + +typedef struct swpt_packet +{ + /* + Pointer to a buffer for BD for TX packets + For RX packets. The pBD MUST set to NULL. + PAL packet shall set the pointer point to the start of the flat buffer + where the BD starts. + */ + void *pBD; + //Physical address for pBD for DMA-able devices + void *pBDPhys; + //OS dependent strucutre used only by OS specific code. + void *pOSStruct; + void *pktMetaInfo; + wpt_packet_type pktType; + //The number of bytes pBD uses. It MUST be set to 0 for RX packets + wpt_uint16 BDLength; + + //Internal data for PAL packet implementation usage only + void *pInternalData; +} wpt_packet; + +typedef struct swpt_iterator +{ + void *pNext; + void *pCur; + void *pContext; +} wpt_iterator; + +/* Each specific channel dedicated information should be logged */ +typedef struct +{ + char channelName[WPT_TRPT_CHANNEL_NAME]; + v_U32_t numDesc; + v_U32_t numFreeDesc; + v_U32_t numRsvdDesc; + v_U32_t headDescOrder; + v_U32_t tailDescOrder; + v_U32_t ctrlRegVal; + v_U32_t statRegVal; + v_U32_t numValDesc; + v_U32_t numInvalDesc; +} wpt_log_data_stall_channel_type; + +/* Transport log context */ +typedef struct +{ + v_U32_t PowerState; + v_U32_t numFreeBd; + wpt_log_data_stall_channel_type dxeChannelInfo[WPT_NUM_TRPT_CHANNEL]; +} wpt_log_data_stall_type; + + +//pPkt is a pointer to wpt_packet +#define WPAL_PACKET_SET_BD_POINTER(pPkt, pBd) ( (pPkt)->pBD = (pBd) ) +#define WPAL_PACKET_GET_BD_POINTER(pPkt) ( (pPkt)->pBD ) +//Access the physical address of BD +#define WPAL_PACKET_SET_BD_PHYS(pPkt, pBdPhys) ( (pPkt)->pBDPhys = (pBdPhys) ) +#define WPAL_PACKET_GET_BD_PHYS(pPkt) ( (pPkt)->pBDPhys ) +#define WPAL_PACKET_SET_BD_LENGTH(pPkt, len) ( (pPkt)->BDLength = (len) ) +#define WPAL_PACKET_GET_BD_LENGTH(pPkt) ( (pPkt)->BDLength ) +#define WPAL_PACKET_SET_METAINFO_POINTER(pPkt, p) ( (pPkt)->pktMetaInfo = (p) ) +#define WPAL_PACKET_GET_METAINFO_POINTER(pPkt) ( (pPkt)->pktMetaInfo ) +#define WPAL_PACKET_SET_TYPE(pPkt, type) ( (pPkt)->pktType = (type) ) +#define WPAL_PACKET_GET_TYPE(pPkt) ( (pPkt)->pktType ) +#define WPAL_PACKET_SET_OS_STRUCT_POINTER(pPkt, pStruct) ( (pPkt)->pOSStruct = (pStruct) ) +#define WPAL_PACKET_GET_OS_STRUCT_POINTER(pPkt) ( (pPkt)->pOSStruct ) +#define WPAL_PACKET_IS_FLAT_BUF(pktType) ( (eWLAN_PAL_PKT_TYPE_RX_RAW == (pktType)) || \ + (eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == (pktType)) ) + +/* RX RAW packet alloc fail due to out of resource CB function type */ +typedef void ( *wpalPacketLowPacketCB )( wpt_packet *pPacket, void *usrData ); + + +/*--------------------------------------------------------------------------- + wpalPacketInit – Initialize all wpt_packet related objects. Allocate memory for wpt_packet. + Allocate memory for TX management frames and RX frames. + For our legacy UMAC, it is not needed because vos_packet contains wpt_packet. + Param: + pPalContext – A context PAL uses?? + Return: + eWLAN_PAL_STATUS_SUCCESS -- success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketInit(void *pPalContext); + +/*--------------------------------------------------------------------------- + wpalPacketClose – Free all allocated resource by wpalPacketInit. + For our legacy UMAC, it is not needed because vos_packet contains pal_packet. + Param: + pPalContext – A context PAL uses?? + Return: + eWLAN_PAL_STATUS_SUCCESS -- success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketClose(void *pPalContext); + + +/*--------------------------------------------------------------------------- + wpalPacketAlloc – Allocate a wpt_packet from PAL. + Param: + pPalContext – A context PAL uses?? + pktType – specify the type of wpt_packet to allocate + nPktSize - specify the maximum size of the packet buffer. + Return: + A pointer to the wpt_packet. NULL means fail. +---------------------------------------------------------------------------*/ +wpt_packet * wpalPacketAlloc(wpt_packet_type pktType, wpt_uint32 nPktSize, + wpalPacketLowPacketCB rxLowCB, void *usrdata); + +/*--------------------------------------------------------------------------- + wpalPacketFree – Free a wpt_packet chain for one particular type. + Packet type is carried in wpt_packet structure. + Param: + pPalContext – A context PAL uses?? + pPkt - pointer to a packet to be freed. + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketFree(wpt_packet *pPkt); + +/*--------------------------------------------------------------------------- + wpalPacketGetLength – Get number of bytes in a wpt_packet. + Param: + pPalContext – PAL context returned from PAL open + pPkt - pointer to a packet to be freed. + Return: + Length of the data include layer-2 headers. For example, if the frame is 802.3, + the length includes the ethernet header. +---------------------------------------------------------------------------*/ +wpt_uint32 wpalPacketGetLength(wpt_packet *pPkt); + +/*--------------------------------------------------------------------------- + wpalPacketRawTrimHead – Move the starting offset and reduce packet length. + The function can only be used with raw packets, + whose buffer is one piece and allocated by WLAN driver. + Param: + pPkt - pointer to a wpt_packet. + size – number of bytes to take off the head. + Return: + eWPAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalPacketRawTrimHead(wpt_packet *pPkt, wpt_uint32 size); + +/*--------------------------------------------------------------------------- + wpalPacketRawTrimTail – reduce the length of the packet. The function can + only be used with raw packets, whose buffer is one piece and + allocated by WLAN driver. This also reduce the length of the packet. + Param: + pPkt - pointer to a wpt_packet. + size – number of bytes to take of the packet length + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalPacketRawTrimTail(wpt_packet *pPkt, wpt_uint32 size); + + +/*--------------------------------------------------------------------------- + wpalPacketGetRawBuf – Return the starting buffer's virtual address for the RAW flat buffer + It is inline in hope of faster implementation for certain platform. + Param: + pPkt - pointer to a wpt_packet. + Return: + NULL - fail. + Otherwise the address of the starting of the buffer +---------------------------------------------------------------------------*/ +extern wpt_uint8 *wpalPacketGetRawBuf(wpt_packet *pPkt); + + +/*--------------------------------------------------------------------------- + wpalPacketSetRxLength – Set the valid data length on a RX packet. This function must + be called once per RX packet per receiving. It indicates the available data length from + the start of the buffer. + Param: + pPkt - pointer to a wpt_packet. + Return: + NULL - fail. + Otherwise the address of the starting of the buffer +---------------------------------------------------------------------------*/ +extern wpt_status wpalPacketSetRxLength(wpt_packet *pPkt, wpt_uint32 len); + + +/*--------------------------------------------------------------------------- + wpalIteratorInit – Initialize an interator by updating pCur to first item. + Param: + pIter – pointer to a caller allocated wpt_iterator + pPacket – pointer to a wpt_packet + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalIteratorInit(wpt_iterator *pIter, wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalIteratorNext – Get the address for the next item + Param: + pIter – pointer to a caller allocated wpt_iterator + pPacket – pointer to a wpt_packet + ppAddr – Caller allocated pointer to return the address of the item. For DMA-able devices, this is the physical address of the item. + pLen – To return the number of bytes in the item. + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalIteratorNext(wpt_iterator *pIter, wpt_packet *pPacket, void **ppAddr, wpt_uint32 *pLen); + + +/*--------------------------------------------------------------------------- + wpalLockPacketForTransfer – Packet must be locked before transfer can begin, + the lock will ensure that the DMA engine has access to the data packet + in a cache coherent manner + + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalLockPacketForTransfer( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalUnlockPacket – Once the transfer has been completed the packet should + be unlocked so that normal operation may resume + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalUnlockPacket( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalPacketGetFragCount – Get count of memory chains (fragments) + in a packet + Param: + pPacket – pointer to a wpt_packet + + Return: + memory fragment count in a packet +---------------------------------------------------------------------------*/ +wpt_int32 wpalPacketGetFragCount(wpt_packet *pPkt); + +/*--------------------------------------------------------------------------- + wpalIsPacketLocked – Check whether the Packet is locked for DMA. + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS + eWLAN_PAL_STATUS_E_FAILURE + eWLAN_PAL_STATUS_E_INVAL +---------------------------------------------------------------------------*/ +wpt_status wpalIsPacketLocked( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalGetNumRxRawPacket Query available RX RAW total buffer count + param: + numRxResource pointer of queried value + + return: + eWLAN_PAL_STATUS_SUCCESS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxRawPacket(wpt_uint32 *numRxResource); + +/*--------------------------------------------------------------------------- + wpalGetNumRxPacketAllocFailures Get number of times packet alloc failed + numRxResource pointer of queried value + + return: + eWLAN_PAL_STATUS_SUCCESS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxPacketAllocFailures(wpt_uint32 *numRxResource); + +/*--------------------------------------------------------------------------- + wpalGetNumRxFreePacket Query available RX Free buffer count + param: + numRxResource pointer of queried value + + return: + WPT_STATUS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxFreePacket(wpt_uint32 *numRxResource); + +/*--------------------------------------------------------------------------- + wpalPacketStallUpdateInfo – Update each channel information when stall + detected, also power state and free resource count + + Param: + powerState ? WLAN system power state when stall detected + numFreeBd ? Number of free resource count in HW + channelInfo ? Each channel specific information when stall happen + channelNum ? Channel number update information + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPacketStallUpdateInfo +( + v_U32_t *powerState, + v_U32_t *numFreeBd, + wpt_log_data_stall_channel_type *channelInfo, + v_U8_t channelNum +); + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/*--------------------------------------------------------------------------- + wpalPacketStallDumpLog – Trigger to send log packet to DIAG + Updated transport system information will be sent to DIAG + + Param: + NONE + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPacketStallDumpLog +( + void +); +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +/*--------------------------------------------------------------------------- + wpalLogPktSerialize - Serialize Logging data to logger thread + + Param: + wpt_packet pFrame - The packet which contains the logging data. + This packet has to be a VALID packet, as this + API will not do any checks on the validity of + the packet. + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalLogPktSerialize +( + wpt_packet *pFrame +); + + +/*--------------------------------------------------------------------------- + wpalFwLogPktSerialize - Serialize Logging data to logger thread + + Param: + wpt_packet pFrame - The packet which contains the logging data. + This packet has to be a VALID packet, as this + API will not do any checks on the validity of + the packet. + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalFwLogPktSerialize +( + wpt_packet *pFrame, wpt_uint32 pktType +); + +/*--------------------------------------------------------------------------- + wpalPerPktSerialize - Serialize perpkt data to logger thread + + Param: + + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPerPktSerialize +( + void *perPktStat +); + +/*--------------------------------------------------------------------------- + wpalGetOSPktHead – Get the head of OS spacific socket buffer + Param: + pPacket – pointer to a wpt_packet + + Return: + void* - success +---------------------------------------------------------------------------*/ +void* wpalGetOSPktHead( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalGetOSPktend – Get end pointer of OS spacific socket buffer + Param: + pPacket – pointer to a wpt_packet + + Return: + void* - success +---------------------------------------------------------------------------*/ +void* wpalGetOSPktend( wpt_packet *pPacket); + +/*--------------------------------------------------------------------------- + wpalRecoverTail – recover currupted skb tail. + Param: + pPacket – pointer to a wpt_packet + + Return: + void - success +---------------------------------------------------------------------------*/ +void wpalRecoverTail( wpt_packet *pPacket); + +#endif // __WLAN_QCT_PAL_PACKET_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h new file mode 100644 index 000000000000..99821f206e53 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_status.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_STATUS_H ) +#define __WLAN_QCT_PAL_STATUS_H + +/**========================================================================= + + \file wlan_qct_pal_status.h + + \brief define status PAL exports. wpt = (Wlan Pal Type) + + Definitions for platform independent. + + + ========================================================================*/ + +typedef enum +{ + /// Request succeeded! + eWLAN_PAL_STATUS_SUCCESS, + + /// Request failed because system resources (other than memory) to + /// fulfill request are not available. + eWLAN_PAL_STATUS_E_RESOURCES, + + /// Request failed because not enough memory is available to + /// fulfill the request. + eWLAN_PAL_STATUS_E_NOMEM, + + /// Request failed because there of an invalid request. This is + /// typically the result of invalid parameters on the request. + eWLAN_PAL_STATUS_E_INVAL, + + /// Request failed because handling the request would cause a + /// system fault. This error is typically returned when an + /// invalid pointer to memory is detected. + eWLAN_PAL_STATUS_E_FAULT, + + /// Request failed because device or resource is busy. + eWLAN_PAL_STATUS_E_BUSY, + + /// Request did not complete because it was canceled. + eWLAN_PAL_STATUS_E_CANCELED, + + /// Request did not complete because it was aborted. + eWLAN_PAL_STATUS_E_ABORTED, + + /// Request failed because the request is valid, though not supported + /// by the entity processing the request. + eWLAN_PAL_STATUS_E_NOSUPPORT, + + /// Request failed because of an empty condition + eWLAN_PAL_STATUS_E_EMPTY, + + /// Existance failure. Operation could not be completed because + /// something exists or does not exist. + eWLAN_PAL_STATUS_E_EXISTS, + + /// Operation timed out + eWLAN_PAL_STATUS_E_TIMEOUT, + + /// Request failed for some unknown reason. Note don't use this + /// status unless nothing else applies + eWLAN_PAL_STATUS_E_FAILURE, +} wpt_status; + + +#define WLAN_PAL_IS_STATUS_SUCCESS(status) ( eWLAN_PAL_STATUS_SUCCESS == (status) ) + +#endif // __WLAN_QCT_PAL_STATUS_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h new file mode 100644 index 000000000000..314263a7abd9 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_sync.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_SYNC_H ) +#define __WLAN_QCT_PAL_SYNC_H + +/**========================================================================= + + \file wlan_pal_sync.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent. + + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_os_sync.h" + + +#define WLAN_PAL_WAIT_INFINITE 0xFFFFFFFF + +/*--------------------------------------------------------------------------- + wpalMutexInit – initialize a mutex object + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexInit(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalMutexDelete – invalidate a mutex object + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexDelete(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalMutexAcquire – acquire a mutex object. It is blocked until the object is acquired. + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexAcquire(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalMutexRelease – Release a held mutex object + Param: + pMutex – a pointer to caller allocated object of wpt_mutex + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexRelease(wpt_mutex *pMutex); + +/*--------------------------------------------------------------------------- + wpalEventInit – initialize an event object + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventInit(wpt_event *pEvent); + +/*--------------------------------------------------------------------------- + wpalEventDelete – invalidate an event object + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventDelete(wpt_event *pEvent); + +/*--------------------------------------------------------------------------- + wpalEventWait – Wait on an event object + Param: + pEvent – a pointer to caller allocated object of wpt_event + timeout – timerout value at unit of milli-seconds. 0xffffffff means infinite wait + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventWait(wpt_event *pEvent, wpt_uint32 timeout); + +/*--------------------------------------------------------------------------- + wpalEventSet – Set an event object to signaled state + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventSet(wpt_event *pEvent); + +/*--------------------------------------------------------------------------- + wpalEventReset – Set an event object to non-signaled state + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventReset(wpt_event *pEvent); + + +#endif // __WLAN_QCT_PAL_SYNC_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h new file mode 100644 index 000000000000..c1750f5e551d --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_timer.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_TIMER_H ) +#define __WLAN_QCT_PAL_TIMER_H + +/**========================================================================= + + \file wlan_qct_pal_timer.h + + \brief define synchronization objects PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent. + + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" +#include "wlan_qct_os_timer.h" + + +typedef VOS_TIMER_STATE WPAL_TIMER_STATE; + +typedef void (*wpal_timer_callback)(void *pUserData); + +typedef struct +{ + wpt_os_timer timer; + wpal_timer_callback callback; + void *pUserData; +} wpt_timer; + + +/*--------------------------------------------------------------------------- + wpalTimerInit - initialize a wpt_timer object + Param: + pTimer - a pointer to caller allocated wpt_timer object + callback - A callback function + pUserData - A pointer to data pass as parameter of the callback function. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerInit(wpt_timer * pTimer, wpal_timer_callback callback, void *pUserData); + +/*--------------------------------------------------------------------------- + wpalTimerDelete - invalidate a wpt_timer object + Param: + pTimer - a pointer to caller allocated wpt_timer object + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerDelete(wpt_timer * pTimer); + +/*--------------------------------------------------------------------------- + wpalTimerStart - start a wpt_timer object with a timeout value + Param: + pTimer - a pointer to caller allocated wpt_timer object + timeout - timeout value of the timer. In unit of milli-seconds. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerStart(wpt_timer * pTimer, wpt_uint32 timeout); + +/*--------------------------------------------------------------------------- + wpalTimerStop - stop a wpt_timer object. Stop doesn’t guarantee the timer handler is not called if it is already timeout. + Param: + pTimer - a pointer to caller allocated wpt_timer object + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerStop(wpt_timer * pTimer); + +/*--------------------------------------------------------------------------- + wpalTimerGetCurStatus - Get the current status of timer + + pTimer - a pointer to caller allocated wpt_timer object + + return + WPAL_TIMER_STATE +---------------------------------------------------------------------------*/ +WPAL_TIMER_STATE wpalTimerGetCurStatus(wpt_timer * pTimer); + +/*--------------------------------------------------------------------------- + wpalGetSystemTime - Get the system time in milliseconds + + return + current time in milliseconds +---------------------------------------------------------------------------*/ +wpt_uint32 wpalGetSystemTime(void); + +/*--------------------------------------------------------------------------- + wpalGetArchCounterTime - Get time from physical counter + + return + MPM counter value +---------------------------------------------------------------------------*/ +wpt_uint64 wpalGetArchCounterTime(void); + +/*--------------------------------------------------------------------------- + wpalSleep - sleep for a specified interval + Param: + timeout - amount of time to sleep. In unit of milli-seconds. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalSleep(wpt_uint32 timeout); + +/*--------------------------------------------------------------------------- + wpalBusyWait - Thread busy wait with specified usec + Param: + usecDelay - amount of time to wait. In unit of micro-seconds. + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalBusyWait(wpt_uint32 usecDelay); + +#endif // __WLAN_QCT_PAL_TIMER_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_trace.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_trace.h new file mode 100644 index 000000000000..88caff9e0cca --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_trace.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_TRACE_H ) +#define __WLAN_QCT_PAL_TRACE_H + +/**========================================================================= + + \file wlan_qct_pal_api.h + + \brief define general APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform independent + + + ========================================================================*/ + +#include "wlan_qct_pal_type.h" +#include "wlan_qct_pal_status.h" + +typedef enum +{ + // NONE means NO traces will be logged. This value is in place for the + // vos_trace_setlevel() to allow the user to turn off all traces. + eWLAN_PAL_TRACE_LEVEL_NONE = 0, + + // the following trace levels are the ones that 'callers' of VOS_TRACE() + // can specify in for the VOS_TRACE_LEVEL parameter. Traces are classified + // by severity (FATAL being more serious than INFO for example). + eWLAN_PAL_TRACE_LEVEL_FATAL, + eWLAN_PAL_TRACE_LEVEL_ERROR, + eWLAN_PAL_TRACE_LEVEL_WARN, + eWLAN_PAL_TRACE_LEVEL_INFO, + eWLAN_PAL_TRACE_LEVEL_INFO_HIGH, + eWLAN_PAL_TRACE_LEVEL_INFO_MED, + eWLAN_PAL_TRACE_LEVEL_INFO_LOW, + + // ALL means all trace levels will be active. This value is in place for the + // vos_trace_setlevel() to allow the user to turn ON all traces. + eWLAN_PAL_TRACE_LEVEL_ALL, + + // not a real level. Used to identify the maximum number of + // VOS_TRACE_LEVELs defined. + eWLAN_PAL_TRACE_LEVEL_COUNT +} wpt_tracelevel; + +#include "wlan_qct_os_trace.h" + +/*---------------------------------------------------------------------------- + + \brief wpalTraceSetLevel() - Set the trace level for a particular module + + This is an external API that allows trace levels to be set for each module. + + \param module - id of the module whos trace level is being modified + \param level - trace level. A member of the wpt_tracelevel + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + \param on - boolean to indicate if tracing at the given level should be + enabled or disabled. + + \return nothing + + \sa + --------------------------------------------------------------------------*/ +void wpalTraceSetLevel( wpt_moduleid module, wpt_tracelevel level, + wpt_boolean on ); + +/**---------------------------------------------------------------------------- + + \brief wpalTraceCheckLevel() + + This is an external API that returns a boolean value to signify if a + particular trace level is set for the specified module. + + \param level - trace level. A member of the wpt_tracelevel enumeration + indicating the severity of the condition causing the trace + message to be issued. + + Note that individual trace levels are the only valid values + for this API. eWLAN_PAL_TRACE_LEVEL_NONE and eWLAN_PAL_TRACE_LEVEL_ALL + are not valid input and will return FALSE + + \return eWLAN_PAL_FALSE - the specified trace level for the specified module is OFF + + eWLAN_PAL_TRUE - the specified trace level for the specified module is ON + + \sa + --------------------------------------------------------------------------*/ +wpt_boolean wpalTraceCheckLevel( wpt_moduleid module, wpt_tracelevel level ); + + +/*---------------------------------------------------------------------------- + + \brief wpalTraceDisplay() - Display current state of trace level for + all modules + + This is an external API that allows trace levels to be displayed to + an end user + + \param none + + \return nothing + + \sa + --------------------------------------------------------------------------*/ +void wpalTraceDisplay(void); + +#define WPAL_BUG VOS_BUG +#endif // __WLAN_QCT_PAL_TRACE_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h new file mode 100644 index 000000000000..45046acd977b --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/inc/wlan_qct_pal_type.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __WLAN_QCT_PAL_TYPE_H ) +#define __WLAN_QCT_PAL_TYPE_H + +/**========================================================================= + + \file wlan_qct_pal_type.h + + \brief define basic types PAL exports. wpt = (Wlan Pal Type) + + Definitions for platform independent. + + + ========================================================================*/ +#include "wlan_qct_os_type.h" + +typedef wpt_uint8 wpt_macAddr[6]; + +enum +{ + eWLAN_PAL_FALSE = 0, + eWLAN_PAL_TRUE = 1, +}; + +typedef enum +{ + eWLAN_MODULE_DAL, + eWLAN_MODULE_DAL_CTRL, + eWLAN_MODULE_DAL_DATA, + eWLAN_MODULE_PAL, + + //Always the last one + eWLAN_MODULE_COUNT +} wpt_moduleid; + + +typedef struct +{ + //BIT order is most likely little endian. + //This structure is for netowkr-order byte array (or big-endian byte order) +#ifndef WLAN_PAL_BIG_ENDIAN_BIT + wpt_byte protVer :2; + wpt_byte type :2; + wpt_byte subType :4; + + wpt_byte toDS :1; + wpt_byte fromDS :1; + wpt_byte moreFrag :1; + wpt_byte retry :1; + wpt_byte powerMgmt :1; + wpt_byte moreData :1; + wpt_byte wep :1; + wpt_byte order :1; + +#else + + wpt_byte subType :4; + wpt_byte type :2; + wpt_byte protVer :2; + + wpt_byte order :1; + wpt_byte wep :1; + wpt_byte moreData :1; + wpt_byte powerMgmt :1; + wpt_byte retry :1; + wpt_byte moreFrag :1; + wpt_byte fromDS :1; + wpt_byte toDS :1; + +#endif + +} wpt_FrameCtrl; + +typedef struct +{ + /* Frame control field */ + wpt_FrameCtrl frameCtrl; + /* Duration ID */ + wpt_uint16 usDurationId; + /* Address 1 field */ + wpt_macAddr vA1; + /* Address 2 field */ + wpt_macAddr vA2; + /* Address 3 field */ + wpt_macAddr vA3; + /* Sequence control field */ + wpt_uint16 sSeqCtrl; + /* Optional A4 address */ + wpt_macAddr optvA4; + /* Optional QOS control field */ + wpt_uint16 usQosCtrl; +}wpt_80211Header; + +typedef struct +{ + wpt_macAddr dest; + wpt_macAddr sec; + wpt_uint16 lenOrType; +} wpt_8023Header; + + +#endif // __WLAN_QCT_PAL_TYPE_H diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c new file mode 100644 index 000000000000..a6019cbdbbf5 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_api.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2012,2014-2015,2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file wlan_qct_pal_api.c + + \brief Implementation general APIs PAL exports. + wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform Windows. + + + ========================================================================*/ + +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_pal_device.h" +#include "vos_trace.h" +#ifndef MEMORY_DEBUG +#include "vos_memory.h" +#endif /* MEMORY_DEBUG */ +#include "vos_sched.h" +#include "vos_api.h" + +#include "dma-mapping.h" +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)) +#include +#else +#include +#endif +#include + + +#define WPAL_GET_NDIS_HANDLE(p) ( ((tPalContext *)(p))->devHandle ) + +tPalContext gContext; + +//This structure need to be 4-byte aligned. No packing. +typedef struct +{ + wpt_uint32 length; + //The offset from beginning of the buffer where it is allocated + wpt_uint32 offset; + wpt_uint32 phyAddr; +} tPalDmaMemInfo; + +/*=========================================================================== + + FUNCTIONS + +===========================================================================*/ + +/** + * @brief Initialize PAL + * In case of QNP, this does nothing. + * @param ppPalContext pointer to a caller allocated pointer. It + * is opaque to caller. + * Caller save the returned pointer for future use when + * calling PAL APIs. + * @param devHandle pointer to the OS specific device handle. + * + * @return wpt_status eWLAN_PAL_STATUS_SUCCESS - success. Otherwise fail. + */ +wpt_status wpalOpen(void **ppPalContext, void *devHandle) +{ + wpt_status status; + + gContext.devHandle = devHandle; + + status = wpalDeviceInit(devHandle); + if (!WLAN_PAL_IS_STATUS_SUCCESS(status)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: wpalDeviceInit failed with status %u", + __func__, status); + } + + return status; +} + +/** + * @brief wpalClose - Release PAL + * In case of QNP, this does nothing. + * @param pPalContext pointer returned from wpalOpen. + * + * @return wpt_status eWLAN_PAL_STATUS_SUCCESS - success. Otherwise fail. + */ +wpt_status wpalClose(void *pPalContext) +{ + wpalDeviceClose(gContext.devHandle); + gContext.devHandle = NULL; + + return eWLAN_PAL_STATUS_SUCCESS; +} + +#ifndef MEMORY_DEBUG +/** + * @brief wpalMemoryAllocate - Allocate memory + * @param size number of bytes to allocate + * + * @return void* A pointer to the allocated memory. + * NULL - fail to allocate memory + */ +void *wpalMemoryAllocate(wpt_uint32 size) +{ + return vos_mem_malloc( size ); +} + +/** + * @brief wpalMemoryFree - Free allocated memory + * @param pv pointer to buffer to be freed + */ +void wpalMemoryFree(void *pv) +{ + vos_mem_free( pv ); +} +#endif /* MEMORY_DEBUG */ +/** + * @brief wpalMemoryCopy - copy memory + * @param dest address which data is copied to + * @param src address which data is copied from + * @param size number of bytes to copy + * + * @return wpt_status + * eWLAN_PAL_STATUS_SUCCESS + * eWLAN_PAL_STATUS_INVALID_PARAM + */ +wpt_status wpalMemoryCopy(void * dest, void * src, wpt_uint32 size) +{ + vos_mem_copy( dest, src, size ); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + * @brief wpalMemoryCompare - compare memory + * @param buf1 address of buffer1 + * @param buf2 address of buffer2 + * @param size number of bytes to compare + * + * @return wpt_boolean + * eWLAN_PAL_TRUE - if two buffers have same content + * eWLAN_PAL_FALSE - not match + */ +wpt_boolean wpalMemoryCompare(void * buf1, void * buf2, wpt_uint32 size) +{ + return (wpt_boolean)vos_mem_compare( buf1, buf2, size ); +} + + +/*--------------------------------------------------------------------------- + wpalMemoryZero - Zero memory + Param: + buf - address of buffer to be zero + size - number of bytes to zero + Return: + None +---------------------------------------------------------------------------*/ +void wpalMemoryZero(void *buf, wpt_uint32 size) +{ + vos_mem_zero( buf, size ); +} + +/** + * @brief wpalMemoryFill - Fill memory with one pattern + * @param buf address of buffer to be filled + * @param size number of bytes to fill + * @param bFill one byte of data to fill in (size) bytes from the start of the + * buffer + */ +void wpalMemoryFill(void *buf, wpt_uint32 size, wpt_byte bFill) +{ + vos_mem_set( buf, size, bFill ); +} + +/** + * @brief wpalDmaMemoryAllocate - Allocate memory ready for DMA. Aligned at 4-byte + * @param size number of bytes to allocate + * @param ppPhysicalAddr Physical address of the buffer if allocation succeeds + * + * @return void* A pointer to the allocated memory (virtual address). + * NULL - fail to allocate memory + */ +void *wpalDmaMemoryAllocate(wpt_uint32 size, void **ppPhysicalAddr) +{ + struct device *wcnss_device = (struct device *) gContext.devHandle; + void *pv = NULL; + dma_addr_t PhyAddr; + wpt_uint32 uAllocLen = size + sizeof(tPalDmaMemInfo); + + pv = dma_alloc_coherent(wcnss_device, uAllocLen, &PhyAddr, GFP_KERNEL); + if ( NULL == pv ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Unable to allocate DMA buffer", __func__); + return NULL; + } + wpalMemoryZero(pv, uAllocLen); + + + ((tPalDmaMemInfo *)pv)->length = uAllocLen; + ((tPalDmaMemInfo *)pv)->phyAddr = PhyAddr; + ((tPalDmaMemInfo *)pv)->offset = sizeof(tPalDmaMemInfo); + pv = (wpt_byte *)pv + sizeof(tPalDmaMemInfo); + *ppPhysicalAddr = (void*)PhyAddr + sizeof(tPalDmaMemInfo); + + + return (pv); +}/*wpalDmaMemoryAllocate*/ + + +/** + * @brief wpalDmaMemoryFree - Free memory ready for DMA + * @param pv address for the buffer to be freed + */ +void wpalDmaMemoryFree(void *pv) +{ + struct device *wcnss_device = (struct device *) gContext.devHandle; + + tPalDmaMemInfo *pMemInfo = (tPalDmaMemInfo *)(((wpt_byte *)pv) - + sizeof(tPalDmaMemInfo)); + if(pv) + { + pv = (wpt_byte *)pv - pMemInfo->offset; + dma_free_coherent(wcnss_device, pMemInfo->length, pv, pMemInfo->phyAddr); + } + +}/*wpalDmaMemoryFree*/ + +/** + * @brief wpalDbgReadRegister - Read register from the WiFi BB + chip + * @param regAddr - register address + * @param pregValue - return value from register if success + * @return + eWLAN_PAL_STATUS_SUCCESS - when everything is OK + */ +wpt_status wpalDbgReadRegister(wpt_uint32 regAddr, wpt_uint32 *pregValue) +{ + if (NULL == pregValue) + { + return eWLAN_PAL_STATUS_E_INVAL; + } + + return wpalReadRegister(regAddr, pregValue); +} + +/** + * @brief wpalDbgWriteRegister - Write a value to the register + * in the WiFi BB chip Param: + * @param regAddr - register address + * @param regValue - value to be written + * @return + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +*/ +wpt_status wpalDbgWriteRegister(wpt_uint32 regAddr, wpt_uint32 regValue) +{ + return wpalWriteRegister(regAddr, regValue); +} + +/** + * @brief + wpalDbgReadMemory - Read memory from WiFi BB chip space + * @param memAddr - address of memory + * @param buf - output + * @param len - length to be read + * @return + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +*/ +wpt_status wpalDbgReadMemory(wpt_uint32 memAddr, wpt_uint8 *buf, wpt_uint32 len) +{ + return wpalReadDeviceMemory(memAddr, buf, len); +} + +/** + * @brief + wpalDbgWriteMemory - Write a value to the memory in the WiFi BB chip space + * @param memAddr - memory address + * @param buf - vlaue to be written + * @param len - length of buf + * @return + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +*/ +wpt_status wpalDbgWriteMemory(wpt_uint32 memAddr, wpt_uint8 *buf, wpt_uint32 len) +{ + return wpalWriteDeviceMemory(memAddr, buf, len); +} + +/*--------------------------------------------------------------------------- + wpalDriverShutdown - Shutdown WLAN driver + + This API is requied by SSR, call in to 'VOS shutdown' to shutdown WLAN + driver when Riva crashes. + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDriverShutdown(void) +{ + VOS_STATUS vosStatus; + vosStatus = vos_wlanShutdown(); + + if (VOS_STATUS_SUCCESS == vosStatus) { + return eWLAN_PAL_STATUS_SUCCESS; + } + return eWLAN_PAL_STATUS_E_FAILURE; +} + +/*--------------------------------------------------------------------------- + wpalDriverShutdown - Re-init WLAN driver + + This API is requied by SSR, call in to 'VOS re-init' to re-init WLAN + driver. + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalDriverReInit(void) +{ + VOS_STATUS vosStatus; + + vosStatus = vos_wlanReInit(); + if (VOS_STATUS_SUCCESS == vosStatus) { + return eWLAN_PAL_STATUS_SUCCESS; + } + return eWLAN_PAL_STATUS_E_FAILURE; +} + +/*--------------------------------------------------------------------------- + wpalRivaSubystemRestart - Initiate Riva SSR + + This API is called by WLAN driver to initiate Riva SSR + + Param: + None + Return: + eWLAN_PAL_STATUS_SUCCESS - when everything is OK +---------------------------------------------------------------------------*/ +wpt_status wpalRivaSubystemRestart(void) +{ + /* call SSR only if driver is not in load/unload process. + * A WDI timeout during load/unload cannot be fixed thru + * SSR */ + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_WDI, NULL)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: loading/unloading in progress," + " SSR will be done at the end of unload", __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + if (0 == subsystem_restart("wcnss")) + { + return eWLAN_PAL_STATUS_SUCCESS; + } + return eWLAN_PAL_STATUS_E_FAILURE; +} + +/*--------------------------------------------------------------------------- + wpalWlanReload - Initiate WLAN Driver reload + + Param: + None + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalWlanReload(void) +{ + vos_wlanRestart(); + return; +} + +/*--------------------------------------------------------------------------- + wpalWcnssResetIntr - Trigger the reset FIQ to Riva + + Param: + None + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalWcnssResetIntr(void) +{ +#ifdef HAVE_WCNSS_RESET_INTR + wcnss_reset_fiq(true); +#endif + return; +} + +/*--------------------------------------------------------------------------- + wpalWcnssIsProntoHwVer3 - Check if Pronto Hw ver3 + + Param: + None + Return: + TRUE if Ponto Hw Ver 3 + Therefore use WQ6 instead of WQ23 for TX Low/High Priority Channel +---------------------------------------------------------------------------*/ +int wpalWcnssIsProntoHwVer3(void) +{ + return wcnss_is_hw_pronto_ver3(); +} + +/*--------------------------------------------------------------------------- + wpalIsFwLoggingEnabled - Check if Firmware will send logs using DXE + + Param: + None + Return: + Check the documentation of vos_is_fw_logging_enabled +---------------------------------------------------------------------------*/ +wpt_uint8 wpalIsFwLoggingEnabled(void) +{ + return vos_is_fw_logging_enabled(); +} + +/*--------------------------------------------------------------------------- + wpalIsFwLoggingEnabled - Check if Firmware will send running + logs using DXE + + Param: + None + Return: + Check the documentation of vos_is_fw_logging_enabled +---------------------------------------------------------------------------*/ +wpt_uint8 wpalIsFwEvLoggingEnabled(void) +{ + return vos_is_fw_ev_logging_enabled(); +} +/*--------------------------------------------------------------------------- + wpalIsFwLoggingSupported - Check if Firmware supports the fw->host + logging infrastructure + This API can only be called after fw caps + are exchanged. + + Param: + None + Return: + Check the documentation of vos_is_fw_logging_supported +---------------------------------------------------------------------------*/ +wpt_uint8 wpalIsFwLoggingSupported(void) +{ + return vos_is_fw_logging_supported(); +} + +/*--------------------------------------------------------------------------- + wpalFwDumpReq - Trigger the dump commands to Firmware + + Param: + cmd - Command No. to execute + arg1 - argument 1 to cmd + arg2 - argument 2 to cmd + arg3 - argument 3 to cmd + arg4 - argument 4 to cmd + async -asynchronous event. Don't wait for completion. + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalFwDumpReq(wpt_uint32 cmd, wpt_uint32 arg1, wpt_uint32 arg2, + wpt_uint32 arg3, wpt_uint32 arg4, wpt_boolean async) +{ + vos_fwDumpReq(cmd, arg1, arg2, arg3, arg4, async); + return; +} + +/*--------------------------------------------------------------------------- + wpalDevicePanic - Trigger Device Panic + Trigger device panic to help debug + + Param: + NONE + + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalDevicePanic(void) +{ + BUG_ON(1); + return; +} +/*--------------------------------------------------------------------------- + wpalIslogPInProgress - calls vos API vos_is_logp_in_progress() + + Param: + NONE + Return: + STATUS + ---------------------------------------------------------------------------*/ +int wpalIslogPInProgress(void) +{ + return vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL); +} + +/*--------------------------------------------------------------------------- + wpalIsSsrPanicOnFailure - calls vos API isSsrPanicOnFailure() + + Param: + NONE + Return: + STATUS + ---------------------------------------------------------------------------*/ +int wpalIsSsrPanicOnFailure(void) +{ + return isSsrPanicOnFailure(); +} + +int wpalGetDxeReplenishRXTimerVal(void) +{ + return vos_get_dxeReplenishRXTimerVal(); +} + +int wpalIsDxeSSREnable(void) +{ + return vos_get_dxeSSREnable(); +} + +bool wpalIsArpPkt(void *pPacket) +{ + vos_pkt_t *pkt = (vos_pkt_t*)pPacket; + + return vos_is_arp_pkt(pkt->pSkb, true); +} + +void wpalUpdateTXArpFWdeliveredStats(void) +{ + vos_update_arp_fw_tx_delivered(); +} diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_device.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_device.c new file mode 100644 index 000000000000..3a435653a891 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_device.c @@ -0,0 +1,850 @@ +/* + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + @file wlan_qct_pal_device.c + + @brief + + This file implements the device specific HW access interface + required by the WLAN Platform Abstraction Layer (WPAL) + +========================================================================*/ + +/*=========================================================================== + + EDIT HISTORY FOR FILE + + + This section contains comments describing changes made to the module. + Notice that changes are listed in reverse chronological order. + + + $Header:$ $DateTime: $ $Author: $ + + + when who what, where, why + ---------- --- ----------------------------------------------------------- + 2011-03-01 jtj Initial version for Linux/Android with Wcnss + +===========================================================================*/ + +/*---------------------------------------------------------------------------- + * Include Files + * -------------------------------------------------------------------------*/ +#include +#include +#include +#ifdef EXISTS_MSM_SMSM +#include +#else +#include +#endif +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_device.h" +#include "wlan_hdd_main.h" +#include "linux/wcnss_wlan.h" +#include + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Global Data Definitions + * -------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Static Variable Definitions + * -------------------------------------------------------------------------*/ + +typedef struct { + struct resource *wcnss_memory; + void __iomem *mmio; + int tx_irq; + wpalIsrType tx_isr; + void *tx_context; + int rx_irq; + wpalIsrType rx_isr; + void *rx_context; + int rx_registered; + int tx_registered; + u8 rx_isr_enabled; + u64 *rx_disable_return; + u64 *rx_enable_return; + u8 rx_isr_enable_failure; + u8 rx_isr_enable_partial_failure; + u8 tx_isr_enabled; +} wcnss_env; + +static wcnss_env gEnv; +static wcnss_env *gpEnv = NULL; + +#define WPAL_READ_REGISTER_RATELIMIT_INTERVAL 20*HZ +#define WPAL_READ_REGISTER_RATELIMIT_BURST 1 + +static DEFINE_RATELIMIT_STATE(wpalReadRegister_rs, \ + WPAL_READ_REGISTER_RATELIMIT_INTERVAL, \ + WPAL_READ_REGISTER_RATELIMIT_BURST); +/*---------------------------------------------------------------------------- + * Static Function Declarations and Definitions + * -------------------------------------------------------------------------*/ + +/** + @brief wpalTxIsr is the interrupt service routine which handles + the DXE TX Complete interrupt + + wpalTxIsr is registered with the Operating System to handle the + DXE TX Complete interrupt during system initialization. When a DXE + TX Complete interrupt occurs, it is dispatched to the handler which + had previously been registered via wpalRegisterInterrupt. + + @param irq: Enumeration of the interrupt that occurred + @param dev_id: User-supplied data passed back via the ISR + + @see wpalRegisterInterrupt + + @return IRQ_HANDLED since it is a dedicated interrupt +*/ +static irqreturn_t wpalTxIsr +( + int irq, + void *dev_id +) +{ + if ((NULL != gpEnv) && (NULL != gpEnv->tx_isr)) { + gpEnv->tx_isr(gpEnv->tx_context); + } + return IRQ_HANDLED; +} + + +/** + @brief wpalRxIsr is the interrupt service routine which handles + the DXE RX Available interrupt + + wpalRxIsr is registered with the Operating System to handle the + DXE RX Available interrupt during system initalization. When a DXE + RX Available interrupt occurs, it is dispatched to the handler which + had previously been registered via wpalRegisterInterrupt. + + @param irq: Enumeration of the interrupt that occurred + @param dev_id: User-supplied data passed back via the ISR + + @see wpalRegisterInterrupt + + @return IRQ_HANDLED since it is a dedicated interrupt +*/ +static irqreturn_t wpalRxIsr +( + int irq, + void *dev_id +) +{ + if ((NULL != gpEnv) && (NULL != gpEnv->rx_isr)) { + gpEnv->rx_isr(gpEnv->rx_context); + } + return IRQ_HANDLED; +} + +/*---------------------------------------------------------------------------- + * Externalized Function Definitions + * -------------------------------------------------------------------------*/ + + +/** + @brief wpalRegisterInterrupt provides a mechansim for client + to register support for a given interrupt + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can register to support one of these. It is expected that the core + DXE implementation will invoke this API twice, once for each interrupt. + + @param intType: Enumeration of the interrupt type (TX or RX) + @param callbackFunction: ISR function pointer + @param usrCtxt: User context passed back whenever the + callbackFunction is invoked + + @return SUCCESS if the registration was successful +*/ + +wpt_status wpalRegisterInterrupt +( + wpt_uint32 intType, + wpalIsrType callbackFunction, + void *usrCtxt +) +{ + if (NULL == gpEnv) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if (NULL == callbackFunction) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked with NULL callback", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + switch (intType) { + + case DXE_INTERRUPT_TX_COMPLE: + if (NULL != gpEnv->tx_isr) { + /* TX complete handler already registered */ + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: TX interrupt handler already registered", + __func__); + /* fall though and accept the new values */ + } + gpEnv->tx_isr = callbackFunction; + gpEnv->tx_context = usrCtxt; + break; + + case DXE_INTERRUPT_RX_READY: + if (NULL != gpEnv->rx_isr) { + /* RX complete handler already registered */ + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s: RX interrupt handler already registered", + __func__); + /* fall though and accept the new values */ + } + gpEnv->rx_isr = callbackFunction; + gpEnv->rx_context = usrCtxt; + break; + + default: + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Unknown interrupt type [%u]", + __func__, intType); + return eWLAN_PAL_STATUS_E_INVAL; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalUnRegisterInterrupt provides a mechansim for client + to un-register for a given interrupt + + When DXE stop, remove registered information from PAL + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return NONE +*/ + +void wpalUnRegisterInterrupt +( + wpt_uint32 intType +) +{ + if (NULL == gpEnv) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + return; + } + + switch (intType) { + + case DXE_INTERRUPT_TX_COMPLE: + disable_irq_nosync(gpEnv->tx_irq); + if (gpEnv->tx_registered) + { + free_irq(gpEnv->tx_irq, gpEnv); + gpEnv->tx_registered = 0; + } + gpEnv->tx_isr = NULL; + gpEnv->tx_context = NULL; + break; + + case DXE_INTERRUPT_RX_READY: + disable_irq_nosync(gpEnv->rx_irq); + if (gpEnv->rx_registered) + { + free_irq(gpEnv->rx_irq, gpEnv); + gpEnv->rx_registered = 0; + } + gpEnv->rx_isr = NULL; + gpEnv->rx_context = NULL; + break; + + default: + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Unknown interrupt type [%u]", + __func__, intType); + return; + } + + return; +} + +/** + @brief wpalEnableInterrupt provides a mechansim for a client + to request that a given interrupt be enabled + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can request that the platform-specific adaptation layer allows a + given interrupt to occur. The expectation is that if a given + interrupt is not enabled, if the interrupt occurs then the APPS CPU + will not be interrupted. + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return SUCCESS if the interrupt was enabled +*/ +wpt_status wpalEnableInterrupt +( + wpt_uint32 intType +) +{ + int ret; + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + switch (intType) + { + case DXE_INTERRUPT_RX_READY: + gpEnv->rx_enable_return = VOS_RETURN_ADDRESS; + if (!gpEnv->rx_registered) + { + gpEnv->rx_registered = 1; + ret = request_irq(gpEnv->rx_irq, wpalRxIsr, IRQF_TRIGGER_HIGH, + "wcnss_wlan", gpEnv); + if (ret) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: RX IRQ request failure", + __func__); + gpEnv->rx_isr_enable_failure = 1; + break; + } + + + ret = enable_irq_wake(gpEnv->rx_irq); + if (ret) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: enable_irq_wake failed for RX IRQ", + __func__); + gpEnv->rx_isr_enable_partial_failure = 1; + /* not fatal -- keep on going */ + } + } + else + { + enable_irq(gpEnv->rx_irq); + } + gpEnv->rx_isr_enabled = 1; + break; + case DXE_INTERRUPT_TX_COMPLE: + if (!gpEnv->tx_registered) + { + gpEnv->tx_registered = 1; + ret = request_irq(gpEnv->tx_irq, wpalTxIsr, IRQF_TRIGGER_HIGH, + "wcnss_wlan", gpEnv); + if (ret) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: TX IRQ request failure", + __func__); + break; + } + + + ret = enable_irq_wake(gpEnv->tx_irq); + if (ret) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: enable_irq_wake failed for TX IRQ", + __func__); + /* not fatal -- keep on going */ + } + } + else + { + enable_irq(gpEnv->tx_irq); + } + gpEnv->tx_isr_enabled = 1; + break; + default: + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: unknown interrupt: %d", + __func__, (int)intType); + status = eWLAN_PAL_STATUS_E_INVAL; + break; + } + /* on the integrated platform there is no platform-specific + interrupt control */ + return status; +} + +/** + @brief wpalDisableInterrupt provides a mechansim for a client + to request that a given interrupt be disabled + + The DXE interface supports two interrupts, TX Complete and RX + Available. This interface provides the mechanism whereby a client + can request that the platform-specific adaptation layer not allow a + given interrupt to occur. The expectation is that if a given + interrupt is not enabled, if the interrupt occurs then the APPS CPU + will not be interrupted. + + @param intType: Enumeration of the interrupt type (TX or RX) + + @return SUCCESS if the interrupt was disabled +*/ +wpt_status wpalDisableInterrupt +( + wpt_uint32 intType +) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + switch (intType) + { + case DXE_INTERRUPT_RX_READY: + gpEnv->rx_disable_return = VOS_RETURN_ADDRESS; + disable_irq_nosync(gpEnv->rx_irq); + gpEnv->rx_isr_enabled = 0; + break; + case DXE_INTERRUPT_TX_COMPLE: + disable_irq_nosync(gpEnv->tx_irq); + gpEnv->tx_isr_enabled = 0; + break; + default: + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: unknown interrupt: %d", + __func__, (int)intType); + status = eWLAN_PAL_STATUS_E_INVAL; + break; + } + + /* on the integrated platform there is no platform-specific + interrupt control */ + return status; +} + +/** + @brief wpalWriteRegister provides a mechansim for a client + to write data into a hardware data register + + @param address: Physical memory address of the register + @param data: Data value to be written + + @return SUCCESS if the data was successfully written +*/ +wpt_status wpalWriteRegister +( + wpt_uint32 address, + wpt_uint32 data +) +{ + /* if SSR is in progress, and WCNSS is not out of reset (re-init + * not invoked), then do not access WCNSS registers */ + if (NULL == gpEnv || wcnss_device_is_shutdown() || + (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && + !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + address = (address | gpEnv->wcnss_memory->start); + + if ((address < gpEnv->wcnss_memory->start) || + (address > gpEnv->wcnss_memory->end)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Register address 0x%0x out of range 0x%0x - 0x%0x", + __func__, address, + (u32) gpEnv->wcnss_memory->start, + (u32) gpEnv->wcnss_memory->end); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if (0 != (address & 0x3)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Register address 0x%0x is not word aligned", + __func__, address); + return eWLAN_PAL_STATUS_E_INVAL; + } + + wmb(); + writel_relaxed(data, gpEnv->mmio + (address - gpEnv->wcnss_memory->start)); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalReadRegister provides a mechansim for a client + to read data from a hardware data register + + @param address: Physical memory address of the register + @param data: Return location for value that is read + + @return SUCCESS if the data was successfully read +*/ +wpt_status wpalReadRegister +( + wpt_uint32 address, + wpt_uint32 *data +) +{ + /* if SSR is in progress, and WCNSS is not out of reset (re-init + * not invoked), then do not access WCNSS registers */ + if (NULL == gpEnv || wcnss_device_is_shutdown() || + (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && + !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { + /* Ratelimit wpalReadRegister failure messages which + * can flood serial console during improper system + * initialization or wcnss_device in shutdown state. + * wpalRegisterInterrupt() call to wpalReadRegister is + * likely to cause flooding. */ + if (__ratelimit(&wpalReadRegister_rs)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + } + return eWLAN_PAL_STATUS_E_INVAL; + } + + address = (address | gpEnv->wcnss_memory->start); + + if ((address < gpEnv->wcnss_memory->start) || + (address > gpEnv->wcnss_memory->end)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Register address 0x%0x out of range 0x%0x - 0x%0x", + __func__, address, + (u32) gpEnv->wcnss_memory->start, + (u32) gpEnv->wcnss_memory->end); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if (0 != (address & 0x3)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Register address 0x%0x is not word aligned", + __func__, address); + return eWLAN_PAL_STATUS_E_INVAL; + } + + *data = readl_relaxed(gpEnv->mmio + (address - gpEnv->wcnss_memory->start)); + rmb(); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalWriteDeviceMemory provides a mechansim for a client + to write data into the hardware address space + + @param address: Start address of physical memory to be written + @param s_buffer: Virtual source address from which the data will + be read + @param len: Number of bytes of data to be written + + @return SUCCESS if the data was successfully written +*/ +wpt_status wpalWriteDeviceMemory +( + wpt_uint32 address, + wpt_uint8* s_buffer, + wpt_uint32 len +) +{ + /* if SSR is in progress, and WCNSS is not out of reset (re-init + * not invoked), then do not access WCNSS registers */ + if (NULL == gpEnv || wcnss_device_is_shutdown() || + (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && + !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + address = (address | gpEnv->wcnss_memory->start); + + if ((address < gpEnv->wcnss_memory->start) || + ((address + len) > gpEnv->wcnss_memory->end)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Memory address 0x%0x len %d out of range 0x%0x - 0x%0x", + __func__, address, len, + (u32) gpEnv->wcnss_memory->start, + (u32) gpEnv->wcnss_memory->end); + return eWLAN_PAL_STATUS_E_INVAL; + } + + vos_mem_copy(gpEnv->mmio + (address - gpEnv->wcnss_memory->start), + s_buffer, len); + wmb(); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalReadDeviceMemory provides a mechansim for a client + to read data from the hardware address space + + @param address: Start address of physical memory to be read + @param d_buffer: Virtual destination address to which the + data will be written + @param len: Number of bytes of data to be read + + @return SUCCESS if the data was successfully read +*/ +wpt_status wpalReadDeviceMemory +( + wpt_uint32 address, + wpt_uint8* d_buffer, + wpt_uint32 len +) +{ + /* if SSR is in progress, and WCNSS is not out of reset (re-init + * not invoked), then do not access WCNSS registers */ + if (NULL == gpEnv || wcnss_device_is_shutdown() || + (vos_is_logp_in_progress(VOS_MODULE_ID_WDI, NULL) && + !vos_is_reinit_in_progress(VOS_MODULE_ID_WDI, NULL))) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + address = (address | gpEnv->wcnss_memory->start); + + if ((address < gpEnv->wcnss_memory->start) || + ((address + len) > gpEnv->wcnss_memory->end)) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: Memory address 0x%0x len %d out of range 0x%0x - 0x%0x", + __func__, address, len, + (u32) gpEnv->wcnss_memory->start, + (u32) gpEnv->wcnss_memory->end); + return eWLAN_PAL_STATUS_E_INVAL; + } + + vos_mem_copy(d_buffer, + gpEnv->mmio + (address - gpEnv->wcnss_memory->start), len); + rmb(); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalDeviceInit provides a mechanism to initialize the DXE + platform adaptation + + @param deviceCB: Implementation-specific device control block + + @see wpalDeviceClose + + @return SUCCESS if the DXE abstraction was opened +*/ +wpt_status wpalDeviceInit +( + void * devHandle +) +{ + struct device *wcnss_device = (struct device *)devHandle; + struct resource *wcnss_memory; + int tx_irq; + int rx_irq; + + if (NULL != gpEnv) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked after subsystem initialized", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if (NULL == wcnss_device) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invalid device", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + wcnss_memory = wcnss_wlan_get_memory_map(wcnss_device); + if (NULL == wcnss_memory) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: WCNSS memory map unavailable", + __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + tx_irq = wcnss_wlan_get_dxe_tx_irq(wcnss_device); + if (0 > tx_irq) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: WCNSS TX IRQ unavailable", + __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + rx_irq = wcnss_wlan_get_dxe_rx_irq(wcnss_device); + if (0 > rx_irq) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: WCNSS RX IRQ unavailable", + __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + gpEnv = &gEnv; + if (NULL == gpEnv) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: memory allocation failure", + __func__); + return eWLAN_PAL_STATUS_E_NOMEM; + } + + memset(gpEnv, 0, sizeof(*gpEnv)); + + gpEnv->wcnss_memory = wcnss_memory; + gpEnv->tx_irq = tx_irq; + gpEnv->rx_irq = rx_irq; + + /* note the we don't invoke request_mem_region(). + the memory described by wcnss_memory encompases the entire + register space (including BT and FM) and we do not want + exclusive access to that memory */ + + gpEnv->mmio = ioremap(wcnss_memory->start, resource_size(wcnss_memory)); + + if (NULL == gpEnv->mmio) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: memory remap failure", + __func__); + goto err_ioremap; + } + + gpEnv->tx_registered = 0; + gpEnv->rx_registered = 0; + + /* successfully allocated environment, memory and IRQs */ + return eWLAN_PAL_STATUS_SUCCESS; + + err_ioremap: + gpEnv = NULL; + + return eWLAN_PAL_STATUS_E_FAILURE; + +} + + +/** + @brief wpalDeviceClose provides a mechanism to deinitialize the DXE + platform adaptation + + @param deviceCB: Implementation-specific device control block + + @see wpalDeviceOpen + + @return SUCCESS if the DXE abstraction was closed +*/ +wpt_status wpalDeviceClose +( + void * deviceCB + ) +{ + if (NULL == gpEnv) { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: invoked before subsystem initialized", + __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if (gpEnv->rx_registered) + { + free_irq(gpEnv->rx_irq, gpEnv); + } + if (gpEnv->tx_registered) + { + free_irq(gpEnv->tx_irq, gpEnv); + } + iounmap(gpEnv->mmio); + gpEnv = NULL; + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/** + @brief wpalNotifySmsm provides a mechansim for a client to + notify SMSM to start DXE engine and/or condition of Tx + ring buffer + + @param clrSt: bit(s) to be cleared on the MASK + @param setSt: bit(s) to be set on the MASK + + @return SUCCESS if the operation is successful +*/ +wpt_status wpalNotifySmsm +( + wpt_uint32 clrSt, + wpt_uint32 setSt +) +{ + int rc; + rc = smsm_change_state(SMSM_APPS_STATE, clrSt, setSt); + if(0 != rc) + { + WPAL_TRACE(eWLAN_MODULE_DAL_DATA, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: smsm_change_state failed", + __func__); + return eWLAN_PAL_STATUS_E_FAILURE; + } + return eWLAN_PAL_STATUS_SUCCESS; +} + +/* Get Interrupt Status */ +int wpal_get_int_state +( + wpt_uint32 intType +) +{ + int ret; + ret = 0; + + switch (intType) + { + case DXE_INTERRUPT_RX_READY: + if (gpEnv->rx_isr_enabled == 1) + ret = 1; + break; + case DXE_INTERRUPT_TX_COMPLE: + if (gpEnv->tx_isr_enabled == 1) + ret = 1; + break; + default: + break; + } + + return ret; +} diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_msg.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_msg.c new file mode 100644 index 000000000000..e99b61e35797 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_msg.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file wlan_qct_pal_msg.c + + \brief Implementation message APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform with legacy UMAC support. + + + ========================================================================*/ + +#include "wlan_qct_pal_msg.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_trace.h" +#include "vos_mq.h" + + + +/*--------------------------------------------------------------------------- + wpalPostCtrlMsg - Post a message to control context so it can be processed in that context. + Param: + pPalContext - A PAL context + pMsg - a pointer to called allocated opaque object; +---------------------------------------------------------------------------*/ +wpt_status wpalPostCtrlMsg(void *pPalContext, wpt_msg *pMsg) +{ + wpt_status status = eWLAN_PAL_STATUS_E_FAILURE; + vos_msg_t msg; + + if (NULL == pMsg) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: NULL message pointer", __func__); + WPAL_ASSERT(0); + return status; + } + + if ((WPAL_MC_MSG_SMD_NOTIF_OPEN_SIG == pMsg->type) || + (WPAL_MC_MSG_SMD_NOTIF_DATA_SIG == pMsg->type)) + { + /* SMD NOTIFY MSG has none 0 vos MSG type + * If VOS MC MSG flush procedure detect this, + * Do not free MSG body */ + msg.type = pMsg->type; + } + else + { + /* Default MSG type + * VOS MC MSG flush procedure will free MSG body */ + msg.type = 0; + } + msg.reserved = 0; + msg.bodyval = 0; + msg.bodyptr = pMsg; + if(VOS_IS_STATUS_SUCCESS(vos_mq_post_message(VOS_MQ_ID_WDI, &msg))) + { + status = eWLAN_PAL_STATUS_SUCCESS; + } + else + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s fail to post msg %d", + __func__, pMsg->type); + } + + return status; +} + + + +/*--------------------------------------------------------------------------- + wpalPostTxMsg - Post a message to TX context so it can be processed in that context. + Param: + pPalContext - A PAL context PAL + pMsg - a pointer to called allocated opaque object; +---------------------------------------------------------------------------*/ +wpt_status wpalPostTxMsg(void *pPalContext, wpt_msg *pMsg) +{ + wpt_status status = eWLAN_PAL_STATUS_E_FAILURE; + vos_msg_t msg; + + if (NULL == pMsg) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: NULL message pointer", __func__); + WPAL_ASSERT(0); + return status; + } + + msg.type = 0; //This field is not used because VOSS doesn't check it. + msg.reserved = 0; + msg.bodyval = 0; + msg.bodyptr = pMsg; + if(VOS_IS_STATUS_SUCCESS(vos_tx_mq_serialize(VOS_MQ_ID_WDI, &msg))) + { + status = eWLAN_PAL_STATUS_SUCCESS; + } + else + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s fail to post msg %d", + __func__, pMsg->type); + } + + return status; +} + + +/*--------------------------------------------------------------------------- + wpalPostRxMsg - Post a message to RX context so it can be processed in that context. + Param: + pPalContext - A PAL context + pMsg - a pointer to called allocated opaque object; +---------------------------------------------------------------------------*/ +wpt_status wpalPostRxMsg(void *pPalContext, wpt_msg *pMsg) +{ + wpt_status status = eWLAN_PAL_STATUS_E_FAILURE; + vos_msg_t msg; + + if (NULL == pMsg) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s: NULL message pointer", __func__); + WPAL_ASSERT(0); + return status; + } + + msg.type = 0; //This field is not used because VOSS doesn't check it. + msg.reserved = 0; + msg.bodyval = 0; + msg.bodyptr = pMsg; + if(VOS_IS_STATUS_SUCCESS(vos_rx_mq_serialize(VOS_MQ_ID_WDI, &msg))) + { + status = eWLAN_PAL_STATUS_SUCCESS; + } + else + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s fail to post msg %d", + __func__, pMsg->type); + } + + return status; +} + diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c new file mode 100644 index 000000000000..da46cba72481 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c @@ -0,0 +1,1095 @@ +/* + * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file wlan_qct_pal_packet.c + + \brief Implementation for PAL packet. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform with VOSS packet support and LA. + + + ========================================================================*/ + +#include "wlan_qct_pal_packet.h" +#include "wlan_qct_pal_api.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_os_status.h" +#include "vos_packet.h" +#include "vos_trace.h" +#include "vos_list.h" +#include "vos_api.h" + +#include +#include "dma-mapping.h" +#include + +/*Per spec definition*/ +#define WPAL_ETHERNET_PAKCET_HEADER_SIZE 14 + +/*Per spec definition - not including QOS field*/ +#define WPAL_802_11_PACKET_HEADER_SIZE 24 + +/*p is a pointer to wpt_packet*/ +#define WPAL_TO_VOS_PKT(p) ((vos_pkt_t *)(p)) + + +typedef struct +{ + void* pPhyAddr; + wpt_uint32 uLen; +}wpt_iterator_info; + +/* Storage for DXE CB function pointer */ +static wpalPacketLowPacketCB wpalPacketAvailableCB; + +/* Temp storage for transport channel DIAG/LOG information + * Each channel will update information with different context + * Before send stored date to DIAG, + * temporary it should be stored */ +static wpt_log_data_stall_type wpalTrasportStallInfo; + +/* + wpalPacketInit is no-op for VOSS-support wpt_packet +*/ +wpt_status wpalPacketInit(void *pPalContext) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + + +/* + wpalPacketClose is no-op for VOSS-support wpt_packet +*/ +wpt_status wpalPacketClose(void *pPalContext) +{ + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalPacketRXLowResourceCB – RX RAW packer CB function + Param: + pPacket – Available RX packet + userData - PAL Client Context, DXE + Return: + Status +---------------------------------------------------------------------------*/ +VOS_STATUS wpalPacketRXLowResourceCB(vos_pkt_t *pPacket, v_VOID_t *userData) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + void* pData = NULL; + + if (NULL == pPacket) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Get new RX PAL packet fail"); + return VOS_STATUS_E_FAILURE; + } + vosStatus = vos_pkt_reserve_head_fast( pPacket, &pData, + VPKT_SIZE_BUFFER ); + if(VOS_STATUS_SUCCESS != vosStatus) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Prepare RX packet for DXE fail"); + return VOS_STATUS_E_FAILURE; + } + + if((NULL == wpalPacketAvailableCB) || (NULL == userData)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "Invalid ARG for new RX packet"); + return VOS_STATUS_E_FAILURE; + } + + wpalPacketAvailableCB( (wpt_packet *)pPacket, userData ); + + return VOS_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalPacketAlloc – Allocate a wpt_packet from PAL. + Param: + pktType – specify the type of wpt_packet to allocate + nPktSize - packet size + Return: + A pointer to the wpt_packet. NULL means fail. +---------------------------------------------------------------------------*/ +wpt_packet * wpalPacketAlloc(wpt_packet_type pktType, wpt_uint32 nPktSize, + wpalPacketLowPacketCB rxLowCB, void *usrData) +{ + VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; + wpt_packet* pPkt = NULL; + vos_pkt_t* pVosPkt = NULL; + void* pData = NULL; + v_U16_t allocLen; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + switch (pktType) + { + case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT: + vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_TX_802_11_MGMT, + nPktSize, 1, VOS_FALSE, + NULL, NULL /*no callback*/); + break; + + case eWLAN_PAL_PKT_TYPE_RX_RAW: + /* Set the wpalPacketAvailableCB before we try to get a VOS + * packet from the 'free list' and reset it if vos_pkt_get_packet() + * returns a valid packet. This order is required to avoid the + * race condition: + * 1. The below call to vos_pkt_get_packet() in RX_Thread determines + * that no more packets are available in the 'free list' and sets + * the low resource callbacks. + * 2. in parallel vos_pkt_return_packet() is called in MC_Thread for a + * Management frame before wpalPacketAlloc() gets a chance to set + * wpalPacketAvailableCB and since the 'low resource callbacks' + * are set the callback function - wpalPacketRXLowResourceCB is + * executed,but since wpalPacketAvailableCB is still NULL the low + * resource recovery fails. + */ + wpalPacketAvailableCB = rxLowCB; + + vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_RX_RAW, + nPktSize, 1, VOS_FALSE, + wpalPacketRXLowResourceCB, usrData); + + /* Reserve the entire raw rx buffer for DXE */ + if( vosStatus == VOS_STATUS_SUCCESS ) + { + wpalPacketAvailableCB = NULL; + vosStatus = vos_pkt_reserve_head_fast( pVosPkt, &pData, nPktSize ); + } + + if((NULL != pVosPkt) && (VOS_STATUS_E_RESOURCES != vosStatus)) + { + vos_pkt_get_packet_length(pVosPkt, &allocLen); + if (nPktSize != allocLen) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "RX packet alloc has problem, discard this frame, Len %d", allocLen); + vos_pkt_return_packet(pVosPkt); + return NULL; + } + } + break; + + default: + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " try to allocate unsupported packet type (%d)", pktType); + break; + } + + if(VOS_IS_STATUS_SUCCESS(vosStatus)) + { + pPkt = (wpt_packet *)pVosPkt; + } + + + return pPkt; +}/*wpalPacketAlloc*/ + + + +/*--------------------------------------------------------------------------- + wpalPacketFree – Free a wpt_packet chain for one particular type. + For our legacy UMAC, it is not needed because vos_packet contains pal_packet. + Param: + pPkt – pointer to a wpt_packet + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalPacketFree(wpt_packet *pPkt) +{ + VOS_STATUS vosStatus; + + if(NULL != pPkt->pInternalData) + { + wpalMemoryFree(pPkt->pInternalData); + } + vosStatus = vos_pkt_return_packet(WPAL_TO_VOS_PKT(pPkt)); + + //With VOSS support, we can cast between wpt_status and VOS_STATUS + return (wpt_status)vosStatus; +}/*wpalPacketFree*/ + + +/*--------------------------------------------------------------------------- + wpalPacketGetLength – Get number of bytes in a wpt_packet. It include the + bytes in a BD if it exist. + Param: + pPkt - pointer to a packet to be freed. + Return: + Length of the data include layer-2 headers. For example, if the frame + is 802.3, the length includes the ethernet header. +---------------------------------------------------------------------------*/ +wpt_uint32 wpalPacketGetLength(wpt_packet *pPkt) +{ + v_U16_t len = 0, pktLen = 0; + + // Validate the parameter pointers + if (unlikely(NULL == pPkt)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + + if( WPAL_PACKET_GET_BD_POINTER(pPkt) ) + { + len = WPAL_PACKET_GET_BD_LENGTH(pPkt); + } + if( VOS_IS_STATUS_SUCCESS(vos_pkt_get_packet_length(WPAL_TO_VOS_PKT(pPkt), &pktLen)) ) + { + len += pktLen; + } + else + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s failed", + __func__); + } + + return ((wpt_uint32)len); +}/*wpalPacketGetLength*/ + + +/*--------------------------------------------------------------------------- + wpalPacketRawTrimHead – Move the starting offset and return the head pointer + before the moving. The function can only be used with raw packets, + whose buffer is one piece and allocated by WLAN driver. This also + reduce the length of the packet. + Param: + pPkt - pointer to a wpt_packet. + size – number of bytes to take off the head. + Return: + A pointer to the original buffer head before the trimming. +---------------------------------------------------------------------------*/ +wpt_status wpalPacketRawTrimHead(wpt_packet *pPkt, wpt_uint32 size) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + // Validate the parameter pointers + if (unlikely(NULL == pPkt)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if ((eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) || + (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt))) + { + // Continue to trim the packet + } + else + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : neither 80211 managment packet nor RAW packet", __func__); + VOS_ASSERT(0); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if( !VOS_IS_STATUS_SUCCESS(vos_pkt_trim_head(WPAL_TO_VOS_PKT(pPkt), (v_SIZE_t)size)) ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s Invalid trim(%d)", + __func__, size); + status = eWLAN_PAL_STATUS_E_INVAL; + } + + return status; +}/*wpalPacketRawTrimHead*/ + +/*--------------------------------------------------------------------------- + wpalPacketRawTrimTail – reduce the length of the packet. + Param: + pPkt - pointer to a wpt_packet. + size – number of bytes to take of the packet length + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Otherwise fail. +---------------------------------------------------------------------------*/ +wpt_status wpalPacketRawTrimTail(wpt_packet *pPkt, wpt_uint32 size) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + + // Validate the parameter pointers + if (unlikely(NULL == pPkt)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if ((eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) || + (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt))) + { + // Continue to trim the packet + } + else + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : neither 80211 managment packet nor RAW packet", __func__); + VOS_ASSERT(0); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if( !VOS_IS_STATUS_SUCCESS(vos_pkt_trim_tail(WPAL_TO_VOS_PKT(pPkt), (v_SIZE_t)size)) ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, "%s Invalid trim(%d)", + __func__, size); + status = eWLAN_PAL_STATUS_E_INVAL; + } + + return status; +}/*wpalPacketRawTrimTail*/ + + +/*--------------------------------------------------------------------------- + wpalPacketGetRawBuf – Return the starting buffer virtual address for the RAW flat buffer + It is inline in hope of faster implementation for certain platform. For Winxp, it + will be slow. + Param: + pPkt - pointer to a wpt_packet. + Return: + NULL - fail. + Otherwise the address of the starting of the buffer +---------------------------------------------------------------------------*/ +wpt_uint8 *wpalPacketGetRawBuf(wpt_packet *pPkt) +{ + wpt_uint8 *pRet = NULL; + + // Validate the parameter pointers + if (unlikely(NULL == pPkt)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return NULL; + } + + //Since it is a flat buffer, all we need is to get one byte of offset 0 + if( (eWLAN_PAL_PKT_TYPE_RX_RAW == WPAL_PACKET_GET_TYPE(pPkt)) || + (eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT == WPAL_PACKET_GET_TYPE(pPkt)) ) + { + vos_pkt_peek_data(WPAL_TO_VOS_PKT(pPkt), 0, (v_VOID_t**)&pRet, 1); + WPAL_ASSERT(NULL != pRet); + } + + return pRet; +}/*wpalPacketGetRawBuf*/ + + +/*--------------------------------------------------------------------------- + wpalPacketSetRxLength – Set the valid data length on a RX packet. This function must + be called once per RX packet per receiving. It indicates the available data length from + the start of the buffer. + Param: + pPkt - pointer to a wpt_packet. + Return: + NULL - fail. + Otherwise the address of the starting of the buffer +---------------------------------------------------------------------------*/ +wpt_status wpalPacketSetRxLength(wpt_packet *pPkt, wpt_uint32 len) +{ + // Validate the parameter pointers + if (unlikely(NULL == pPkt)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + /*Only allowed for RX Raw packets */ + if( (eWLAN_PAL_PKT_TYPE_RX_RAW != WPAL_PACKET_GET_TYPE(pPkt))) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Invalid packet type(%d)", __func__, + WPAL_PACKET_GET_TYPE(pPkt)); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if(VOS_IS_STATUS_SUCCESS(vos_pkt_set_rx_length(WPAL_TO_VOS_PKT(pPkt), len))) + { + return eWLAN_PAL_STATUS_SUCCESS; + } + else + { + return eWLAN_PAL_STATUS_E_INVAL; + } +}/*wpalPacketSetRxLength*/ + +void wpalRecoverTail(wpt_packet *pFrame) +{ + // Validate the parameter pointers + if (unlikely(NULL == pFrame)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return; + } + + return vos_recover_tail(WPAL_TO_VOS_PKT(pFrame)); +} + +void* wpalGetOSPktHead(wpt_packet *pFrame) +{ + // Validate the parameter pointers + if (unlikely(NULL == pFrame)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return NULL; + } + + return vos_get_pkt_head(WPAL_TO_VOS_PKT(pFrame)); +} + +void* wpalGetOSPktend(wpt_packet *pFrame) +{ + // Validate the parameter pointers + if (unlikely(NULL == pFrame)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL packet pointer", __func__); + return 0; + } + + return vos_get_pkt_end(WPAL_TO_VOS_PKT(pFrame)); +} + +/* + Set of helper functions that will prepare packet for DMA transfer, + based on the type of transfer : - to and from the device + - following these calls the packet will be locked for DMA only, + CPU will not be able to modify it => the packet must be explicitly returned to + the CPU once the DMA transfer is complete +*/ +WPT_STATIC WPT_INLINE void* itGetOSPktAddrForDevice( wpt_packet *pPacket ) +{ + struct sk_buff *skb; + struct device *wcnss_device = (struct device *)gContext.devHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ( VOS_STATUS_SUCCESS != + vos_pkt_get_os_packet(WPAL_TO_VOS_PKT(pPacket), (void**)&skb, VOS_FALSE )) + { + return NULL; + } + else + { + /*Map skb data into dma-able memory + (changes will be commited from cache) */ + return (void*)dma_map_single( wcnss_device, skb->data, skb->len, DMA_TO_DEVICE ); + } +}/*itGetOSPktAddrForDevice*/ + +WPT_STATIC WPT_INLINE void* itGetOSPktAddrFromDevice( wpt_packet *pPacket ) +{ + struct sk_buff *skb; + struct device *wcnss_device = (struct device *)gContext.devHandle; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if ( VOS_STATUS_SUCCESS != + vos_pkt_get_os_packet(WPAL_TO_VOS_PKT(pPacket), (void**)&skb, VOS_FALSE )) + { + return NULL; + } + else + { + if((uintptr_t)skb->data == (uintptr_t)skb->tail) + { +#ifdef WLAN_BUG_ON_SKB_ERROR + wpalDevicePanic(); +#else + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s: skb->data == skb->tail. Attempting recovery " + "skb:%p, head:%p, tail:%p, data:%p", + __func__, skb, skb->head, skb->tail, skb->data); + + skb->data = skb->head; +#endif + } + /*Map skb data into dma-able memory + (changes will be commited from cache) */ + return (void*)dma_map_single( wcnss_device, skb->data, skb->len, DMA_FROM_DEVICE ); + } +}/*itGetOSPktAddrFromDevice*/ + +/* + Set of helper functions that will return a DMA-ed packet to the CPU, + based on the type of transfer : - to and from the device +*/ +WPT_STATIC WPT_INLINE void itReturnOSPktAddrForDevice( wpt_packet *pPacket, void* addr, wpt_uint32 size ) +{ + struct device *wcnss_device = (struct device *)gContext.devHandle; + + dma_unmap_single( wcnss_device, (dma_addr_t)addr, size, DMA_TO_DEVICE ); +} + +WPT_STATIC WPT_INLINE void itReturnOSPktAddrFromDevice( wpt_packet *pPacket, void* addr, wpt_uint32 size ) +{ + struct device *wcnss_device = (struct device *)gContext.devHandle; + + dma_unmap_single( wcnss_device, (dma_addr_t)addr, size, DMA_FROM_DEVICE ); +} + + +/*--------------------------------------------------------------------------- + wpalIteratorInit – Initialize an interator by updating pCur to first item. + Param: + pIter – pointer to a caller allocated wpt_iterator + pPacket – pointer to a wpt_packet + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalIteratorInit(wpt_iterator *pIter, wpt_packet *pPacket) +{ + wpt_status status = eWLAN_PAL_STATUS_SUCCESS; + wpt_iterator_info* pCurInfo = NULL; + wpt_iterator_info* pNextInfo = NULL; + wpt_iterator_info* pPktInfo = NULL; + + // Validate the parameter pointers + if (unlikely((NULL == pPacket)||(NULL==pIter))) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL input pointers %p %p", __func__, pPacket, pIter); + return eWLAN_PAL_STATUS_E_INVAL; + } + + pPktInfo = (wpt_iterator_info*)pPacket->pInternalData; + if (unlikely(NULL == pPktInfo)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : Invalid Packet Info", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + // if there is NO BD on this frame, then initialize the next pointer to + // point the first fragment. + if ( NULL == WPAL_PACKET_GET_BD_PHYS(pPacket) ) + { + pCurInfo = pPktInfo; + pNextInfo = NULL; + } + else + { + /*Allocate memory for the current info*/ + pCurInfo = wpalMemoryAllocate( sizeof(wpt_iterator_info) ); + + // Validate the memory allocation + if (unlikely(NULL == pCurInfo)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : Failed to allocate memory ", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + pCurInfo->pPhyAddr = WPAL_PACKET_GET_BD_PHYS(pPacket); + pCurInfo->uLen = WPAL_PACKET_GET_BD_LENGTH(pPacket); + + pNextInfo = pPktInfo; + } + + pIter->pCur = (void*)pCurInfo; + pIter->pNext = (void*)pNextInfo; + pIter->pContext = NULL; + + return status; +}/*wpalIteratorInit*/ + +/*--------------------------------------------------------------------------- + wpalIteratorNext – Get the address for the next item + Param: + pIter – pointer to a caller allocated wpt_iterator + pPacket – pointer to a wpt_packet + ppAddr – Caller allocated pointer to return the address of the item. + For DMA-able devices, this is the physical address of the item. + pLen – To return the number of bytes in the item. + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalIteratorNext(wpt_iterator *pIter, wpt_packet *pPacket, void **ppAddr, wpt_uint32 *pLen) +{ + wpt_iterator_info* pCurInfo = NULL; + /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ + + /*------------------------------------------------------------------------- + Sanity check + -------------------------------------------------------------------------*/ + if (unlikely(( NULL == pIter )||( NULL == pPacket ) || + ( NULL == ppAddr ) || ( NULL == pLen ))) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s Invalid input parameters", __func__ ); + return eWLAN_PAL_STATUS_E_INVAL; + } + + pCurInfo = (wpt_iterator_info*)pIter->pCur; + /*------------------------------------------------------------------------- + If current pointer is NULL - there is no data in the packet - return + -------------------------------------------------------------------------*/ + if( pIter->pCur == NULL ) + { + *ppAddr = NULL; + *pLen = 0; + return eWLAN_PAL_STATUS_SUCCESS; + } + + /*Address and length are kept in the current field*/ + *ppAddr = pCurInfo->pPhyAddr; + *pLen = pCurInfo->uLen; + + if( NULL == pIter->pNext ) + { + /*Save the iterator for cleanup*/ + pPacket->pInternalData = pIter->pCur; + pIter->pCur = NULL; + } + else + { + /*Release the memory saved for storing the BD information*/ + wpalMemoryFree(pCurInfo); + + /*For LA - the packet is represented by maximum 2 fields of data + - BD and actual data from sk buff */ + pIter->pCur = pIter->pNext; + pIter->pNext = NULL; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalLockPacketForTransfer – Map the data buffer from dma so that the + data is commited from cache and the cpu relinquishes + ownership of the buffer + + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalLockPacketForTransfer( wpt_packet *pPacket) +{ + void* pPhyData = NULL; + wpt_iterator_info* pInfo = NULL; + v_U16_t uLenData = 0; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL input pointer", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + switch(WPAL_PACKET_GET_TYPE(pPacket)) + { + /* For management frames, BD is allocated by WDI, header is in raw buffer, + rest of the frame is also in raw buffer */ + case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT: + { + /*TX Packets need to be DMA-ed to the device, perform DMA mapping + accordingly */ + pPhyData = (void*)itGetOSPktAddrForDevice( pPacket ); + } + break; + /* Data packets - BD (allocated by WDI), header (in VOSS header), + rest of the packet (DSM items) */ + case eWLAN_PAL_PKT_TYPE_TX_802_11_DATA: + case eWLAN_PAL_PKT_TYPE_TX_802_3_DATA: + { + /*TX Packets need to be DMA-ed to the device, perform DMA mapping + accordingly */ + pPhyData = (void*)itGetOSPktAddrForDevice( pPacket ); + } + break; + + /* For Raw RX, BD + header + rest of the packet is all contained in the raw + buffer */ + case eWLAN_PAL_PKT_TYPE_RX_RAW: + { + /*RX Packets need to be DMA-ed from the device, perform DMA mapping + accordingly */ + pPhyData = (void*)itGetOSPktAddrFromDevice( pPacket ); + } + break; + + default: + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " WLAN_PAL: %s: Invalid packet type %d!", __func__, + WPAL_PACKET_GET_TYPE(pPacket) ); + WPAL_ASSERT(0); + return eWLAN_PAL_STATUS_E_FAILURE; + } + } + + /*Get packet length*/ + vos_pkt_get_packet_length(WPAL_TO_VOS_PKT(pPacket),&uLenData); + + /*Allocate memory for the current info*/ + pInfo = wpalMemoryAllocate( sizeof(wpt_iterator_info) ); + + // Validate the memory allocation + if (unlikely(NULL == pInfo)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : Failed to allocate memory ", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + pInfo->pPhyAddr = pPhyData; + pInfo->uLen = uLenData; + + pPacket->pInternalData = pInfo; + return eWLAN_PAL_STATUS_SUCCESS; +}/*wpalLockPacketForTransfer*/ + +/*--------------------------------------------------------------------------- + wpalUnlockPacket – Unmap the data buffer from dma so that cpu can regain + ownership on it + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS - success +---------------------------------------------------------------------------*/ +wpt_status wpalUnlockPacket( wpt_packet *pPacket) +{ + + wpt_iterator_info* pInfo; + + // Validate the parameter pointers + if (unlikely(NULL == pPacket)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + "%s : NULL input pointer pPacket", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + pInfo = (wpt_iterator_info*)pPacket->pInternalData; + + // Validate pInfo + if (unlikely(NULL == pInfo)) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_FATAL, + "%s : NULL input pointer pInfo", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + switch(WPAL_PACKET_GET_TYPE(pPacket)) + { + /* For management frames, BD is allocated by WDI, header is in raw buffer, + rest of the frame is also in raw buffer */ + case eWLAN_PAL_PKT_TYPE_TX_802_11_MGMT: + { + /*TX Packets need to be DMA-ed to the device, perform DMA mapping + accordingly */ + itReturnOSPktAddrForDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen); + } + break; + /* Data packets - BD (allocated by WDI), header (in VOSS header), + rest of the packet (DSM items) */ + case eWLAN_PAL_PKT_TYPE_TX_802_11_DATA: + case eWLAN_PAL_PKT_TYPE_TX_802_3_DATA: + { + /*TX Packets need to be DMA-ed to the device, perform DMA mapping + accordingly */ + itReturnOSPktAddrForDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen); + } + break; + + /* For Raw RX, BD + header + rest of the packet is all contained in the raw + buffer */ + case eWLAN_PAL_PKT_TYPE_RX_RAW: + { + /*RX Packets need to be DMA-ed from the device, perform DMA mapping + accordingly */ + if(NULL == pInfo->pPhyAddr) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " WLAN_PAL: %s: RX frame was not locked properly", __func__); + } + else + { + itReturnOSPktAddrFromDevice(pPacket, pInfo->pPhyAddr, pInfo->uLen); + } + } + break; + + default: + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " WLAN_PAL: %s: Invalid packet type %d!", __func__, + WPAL_PACKET_GET_TYPE(pPacket) ); + WPAL_ASSERT(0); + return eWLAN_PAL_STATUS_E_FAILURE; + } + } + + wpalMemoryFree(pInfo); + pPacket->pInternalData = NULL; + return eWLAN_PAL_STATUS_SUCCESS; +}/*wpalUnlockPacket*/ + +/*--------------------------------------------------------------------------- + wpalIsPacketLocked – Check whether the Packet is locked for DMA. + Param: + pPacket – pointer to a wpt_packet + + Return: + eWLAN_PAL_STATUS_SUCCESS + eWLAN_PAL_STATUS_E_FAILURE + eWLAN_PAL_STATUS_E_INVAL +---------------------------------------------------------------------------*/ +wpt_status wpalIsPacketLocked( wpt_packet *pPacket) +{ + + wpt_iterator_info* pInfo; + + /* Validate the parameter pointers */ + if (NULL == pPacket) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_WARN, + "%s : NULL input pointer", __func__); + return eWLAN_PAL_STATUS_E_INVAL; + } + + /* Validate pInternalData */ + pInfo = (wpt_iterator_info*)pPacket->pInternalData; + return (NULL == pInfo)? eWLAN_PAL_STATUS_E_FAILURE : + eWLAN_PAL_STATUS_SUCCESS; +}/*wpalIsPacketLocked*/ + +/*--------------------------------------------------------------------------- + wpalGetNumRxRawPacket Query available RX RAW total buffer count + param: + numRxResource pointer of queried value + + return: + eWLAN_PAL_STATUS_SUCCESS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxRawPacket(wpt_uint32 *numRxResource) +{ + *numRxResource = (wpt_uint32)vos_pkt_get_num_of_rx_raw_pkts(); + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalGetNumRxPacketAllocFailures Get number of times packet alloc failed + numRxResource pointer of queried value + + return: + eWLAN_PAL_STATUS_SUCCESS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxPacketAllocFailures(wpt_uint32 *numRxResource) +{ + *numRxResource = (wpt_uint32)vos_pkt_get_num_of_rx_pkt_alloc_failures(); + + return eWLAN_PAL_STATUS_SUCCESS; +} +/*--------------------------------------------------------------------------- + wpalGetNumRxFreePacket Query available RX Free buffer count + param: + numRxResource pointer of queried value + + return: + WPT_STATUS +---------------------------------------------------------------------------*/ +wpt_status wpalGetNumRxFreePacket(wpt_uint32 *numRxResource) +{ + VOS_STATUS status; + + status = vos_pkt_get_available_buffer_pool(VOS_PKT_TYPE_RX_RAW, + (v_SIZE_t *)numRxResource); + + return WPAL_VOS_TO_WPAL_STATUS(status); +} + +/*--------------------------------------------------------------------------- + wpalPacketStallUpdateInfo – Update each channel information when stall + detected, also power state and free resource count + + Param: + powerState ? WLAN system power state when stall detected + numFreeBd ? Number of free resource count in HW + channelInfo ? Each channel specific information when stall happen + channelNum ? Channel number update information + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPacketStallUpdateInfo +( + v_U32_t *powerState, + v_U32_t *numFreeBd, + wpt_log_data_stall_channel_type *channelInfo, + v_U8_t channelNum +) +{ + /* Update power state when stall detected */ + if(NULL != powerState) + { + wpalTrasportStallInfo.PowerState = *powerState; + } + + /* Update HW free resource count */ + if(NULL != numFreeBd) + { + wpalTrasportStallInfo.numFreeBd = *numFreeBd; + } + + /* Update channel information */ + if(NULL != channelInfo) + { + wpalMemoryCopy(&wpalTrasportStallInfo.dxeChannelInfo[channelNum], + channelInfo, + sizeof(wpt_log_data_stall_channel_type)); + } + + return; +} + +#ifdef FEATURE_WLAN_DIAG_SUPPORT +/*--------------------------------------------------------------------------- + wpalPacketStallDumpLog – Trigger to send log packet to DIAG + Updated transport system information will be sent to DIAG + + Param: + NONE + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPacketStallDumpLog +( + void +) +{ + vos_log_data_stall_type *log_ptr = NULL; + + WLAN_VOS_DIAG_LOG_ALLOC(log_ptr, vos_log_data_stall_type, LOG_TRSP_DATA_STALL_C); + if(log_ptr) + { + log_ptr->PowerState = wpalTrasportStallInfo.PowerState; + log_ptr->numFreeBd = wpalTrasportStallInfo.numFreeBd; + wpalMemoryCopy(&log_ptr->dxeChannelInfo[0], + &wpalTrasportStallInfo.dxeChannelInfo[0], + WPT_NUM_TRPT_CHANNEL * sizeof(vos_log_data_stall_channel_type)); + pr_info("Stall log dump"); + WLAN_VOS_DIAG_LOG_REPORT(log_ptr); + } + + return; +} +#endif /* FEATURE_WLAN_DIAG_SUPPORT */ + +/*--------------------------------------------------------------------------- + wpalLogPktSerialize - Serialize Logging data to logger thread + + Param: + wpt_packet pFrame - The packet which contains the logging data. + This packet has to be a VALID packet, as this + API will not do any checks on the validity of + the packet. + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalLogPktSerialize +( + wpt_packet *pFrame +) +{ + WDI_DS_RxMetaInfoType *pRxMetadata; + void *pBuffer; + VOS_STATUS vosStatus; + + vosStatus = vos_pkt_peek_data(WPAL_TO_VOS_PKT(pFrame), 0, &pBuffer, + WDI_DS_LOG_PKT_TYPE_LEN); + + if (VOS_IS_STATUS_SUCCESS(vosStatus)) + { + // a VALID packet implies non NULL meta-data + pRxMetadata = WDI_DS_ExtractRxMetaData(pFrame); + pRxMetadata->loggingData = *((wpt_uint32 *)pBuffer); + + wpalPacketRawTrimHead(pFrame, WDI_DS_LOG_PKT_TYPE_LEN); + + vos_logger_pkt_serialize(WPAL_TO_VOS_PKT(pFrame), pRxMetadata->loggingData); + } + else + { + vos_pkt_return_packet(WPAL_TO_VOS_PKT(pFrame)); + } +} + +/*--------------------------------------------------------------------------- + wpalFwLogPktSerialize - Serialize Logging data to logger thread + + Param: + wpt_packet pFrame - The packet which contains the logging data. + This packet has to be a VALID packet, as this + API will not do any checks on the validity of + the packet. + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalFwLogPktSerialize +( + wpt_packet *pFrame, wpt_uint32 pktType +) +{ + vos_logger_pkt_serialize(WPAL_TO_VOS_PKT(pFrame), pktType); +} + + +/*--------------------------------------------------------------------------- + wpalPerPktSerialize - Serialize perpkt data to logger thread + + Param: + + + Return: + NONE + +---------------------------------------------------------------------------*/ +void wpalPerPktSerialize +( + void *perPktStat +) +{ + vos_per_pkt_stats_to_user(perPktStat); +} diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_sync.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_sync.c new file mode 100644 index 000000000000..8dc369a31afd --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_sync.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file wlan_qct_pal_sync.c + + \brief Implementation trace/logging APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform Windows and with legacy UMAC. + + + ========================================================================*/ + +#include "wlan_qct_pal_sync.h" +#include "wlan_qct_pal_trace.h" + +#include "wlan_qct_os_status.h" + +/** +wpalMutexInit() + +@brief + This function initializes a mutex object + +@param pMutex: a pointer to caller allocated object of wpt_mutex + +@return eWLAN_PAL_STATUS_SUCCESS if success. Fail otherwise. + +*/ +wpt_status wpalMutexInit(wpt_mutex *pMutex) +{ + /* Not doing sanity checks since VOS does them anyways */ + + if( vos_lock_init( (vos_lock_t*)pMutex ) != VOS_STATUS_SUCCESS ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " mutex init fail"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + @brief Invalidate a mutex object + + \param pMutex - a pointer to caller allocated object of wpt_mutex + + \return eWLAN_PAL_STATUS_SUCCESS if success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexDelete(wpt_mutex *pMutex) +{ + /* Not doing sanity checks since VOS does them anyways */ + + if( vos_lock_destroy( (vos_lock_t*)pMutex ) != VOS_STATUS_SUCCESS ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " mutex delete fail"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + @brief Acquire a mutex object. It is blocked until the object is acquired. + + \param pMutex - a pointer to caller allocated object of wpt_mutex + + \return eWLAN_PAL_STATUS_SUCCESS if success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexAcquire(wpt_mutex *pMutex) +{ + /* Not doing sanity checks since VOS does them anyways */ + + if( vos_lock_acquire( (vos_lock_t*)pMutex ) != VOS_STATUS_SUCCESS ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " mutex acquire fail"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + @brief Release a held mutex object + + \param pMutex - a pointer to caller allocated object of wpt_mutex + + \return eWLAN_PAL_STATUS_SUCCESS if success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalMutexRelease(wpt_mutex *pMutex) +{ + /* Not doing sanity checks since VOS does them anyways */ + + if( vos_lock_release( (vos_lock_t*)pMutex ) != VOS_STATUS_SUCCESS ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " mutex release"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + @brief Initialize an event object + + \param pEvent – a pointer to caller allocated object of wpt_event + + \return eWLAN_PAL_STATUS_SUCCESS if success. Fail otherwise. +------------------------------------------------------------------------*/ +wpt_status wpalEventInit(wpt_event *pEvent) +{ + /* Not doing sanity checks since VOS does them anyways */ + + if( vos_event_init( (vos_event_t*)pEvent ) != VOS_STATUS_SUCCESS ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " create event fail"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + @brief Invalidate an event object + + \param pEvent – a pointer to caller allocated object of wpt_event + + \return eWLAN_PAL_STATUS_SUCCESS if success. Fail otherwise. +------------------------------------------------------------------------*/ + +wpt_status wpalEventDelete(wpt_event *pEvent) +{ + /* Not doing sanity checks since VOS does them anyways */ + + if( vos_event_destroy( (vos_event_t*)pEvent ) != VOS_STATUS_SUCCESS ) + { + WPAL_TRACE(eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " delete event fail"); + return eWLAN_PAL_STATUS_E_FAILURE; + } + + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + @brief wpalEventWait – Wait on an event object + + \param + pEvent – a pointer to caller allocated object of wpt_event + timeout - timeout value at unit of milli-seconds. + 0xffffffff means infinite wait + + \return eWLAN_PAL_STATUS_SUCCESS - the wait was satisifed by one of the events + in the event array being set. The index into the event arry + that satisfied the wait can be found at *pEventIndex. + + eWLAN_PALSTATUS_E_TIMEOUT - the timeout interval elapsed before any of + the events were set. + + eWLAN_PAL_STATUS_E_INVAL - At least one of the values specified in + the event array refers to an uninitialized event object. The + invalid event is identified by the index in *pEventIndex. Note + that only the first uninitialized event is detected when this error + is returned. + + eWLAN_PAL_STATUS_E_EMPTY - the events array is empty. This condition + is detected by numEvents being 0 on input. + + eWLAN_PAL_STATUS_E_FAULT - event or pEventIndex is an invalid pointer. +---------------------------------------------------------------------------*/ +wpt_status wpalEventWait(wpt_event *pEvent, wpt_uint32 timeout) +{ + /* Not doing sanity checks since VOS does them anyways */ + + wpt_status status = eWLAN_PAL_STATUS_E_FAILURE; + VOS_STATUS vos_status = VOS_STATUS_E_FAILURE; + + /* In VOS timeout = 0 corresponds to infinite wait */ + timeout = ( timeout == WLAN_PAL_WAIT_INFINITE ? 0 : timeout ); + + vos_status = vos_wait_single_event( (vos_event_t*)pEvent, timeout ); + + status = WPAL_VOS_TO_WPAL_STATUS( vos_status ); + + return status; +} + +/*--------------------------------------------------------------------------- + wpalEventSet – Set an event object to signaled state + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventSet(wpt_event *pEvent) +{ + /* Not doing sanity checks since VOS does them anyways */ + + return ( WPAL_VOS_TO_WPAL_STATUS(vos_event_set( (vos_event_t*)pEvent )) ); +} + +/*--------------------------------------------------------------------------- + wpalEventReset – Set an event object to non-signaled state + Param: + pEvent – a pointer to caller allocated object of wpt_event + Return: + eWLAN_PAL_STATUS_SUCCESS – success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalEventReset(wpt_event *pEvent) +{ + /* Not doing sanity checks since VOS does them anyways */ + + return ( WPAL_VOS_TO_WPAL_STATUS(vos_event_reset( (vos_event_t*)pEvent )) ); +} + + diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_timer.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_timer.c new file mode 100644 index 000000000000..8bb86a12c18a --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_timer.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file wlan_qct_pal_timer.c + + \brief Implementation trace/logging APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for platform Windows. + + + ========================================================================*/ + +#include "wlan_qct_pal_timer.h" +#include "wlan_qct_pal_trace.h" +#include "wlan_qct_os_status.h" +#include "vos_threads.h" + +#include +#if defined(ANI_OS_TYPE_ANDROID) +#include +#endif + +/*--------------------------------------------------------------------------- + \brief wpalTimerCback - VOS timer callback function + + \param pUserdata - A cookie to data passed back in the callback function +---------------------------------------------------------------------------*/ +static void wpalTimerCback( void * userData ) +{ + wpt_timer *pTimer = (wpt_timer *)userData; + + if(NULL != pTimer->callback) + { + pTimer->callback(pTimer->pUserData); + } + else + { + WPAL_TRACE( eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_WARN, + " %s pTimer(%p) callback after deleted", + __func__, pTimer ); + } +}/*wpalTimerCback*/ + +/*--------------------------------------------------------------------------- + \brief wpalTimerInit - initialize a wpt_timer object + + \param pTimer - a pointer to caller allocated wpt_timer object + \param callback - A callback function + \param pUserData - A cookie to data passed back in the callback function + + \return wpt_status eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerInit(wpt_timer * pTimer, wpal_timer_callback callback, void *pUserData) +{ + /* Sanity Checks */ + if( pTimer == NULL || callback == NULL ) + { + WPAL_TRACE( eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s Wrong param pTimer(%p) callback(%p)", + __func__, pTimer, callback ); + return eWLAN_PAL_STATUS_E_INVAL; + } + + if ( vos_timer_init( &pTimer->timer.timerObj, VOS_TIMER_TYPE_SW, + wpalTimerCback, (void*)pTimer ) == VOS_STATUS_SUCCESS ) + { + pTimer->callback = callback; + pTimer->pUserData = pUserData; + return eWLAN_PAL_STATUS_SUCCESS; + } + + return eWLAN_PAL_STATUS_E_FAILURE; +}/*wpalTimerInit*/ + + +/*--------------------------------------------------------------------------- + \brief wpalTimerDelete - invalidate a wpt_timer object + + \param pTimer a pointer to caller allocated wpt_timer object + + \return eWLAN_PAL_STATUS_SUCCESS ?? success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerDelete(wpt_timer *pTimer) +{ + wpt_status status; + + /* Sanity Checks */ + if( pTimer == NULL ) + { + WPAL_TRACE( eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s Wrong param pTimer(%p)", + __func__, pTimer ); + return eWLAN_PAL_STATUS_E_INVAL; + } + + status = WPAL_VOS_TO_WPAL_STATUS( vos_timer_destroy(&pTimer->timer.timerObj)); + + if( status == eWLAN_PAL_STATUS_SUCCESS ) + { + pTimer->callback = NULL; + pTimer->pUserData = NULL; + } + + return status; +}/*wpalTimerDelete*/ + + +/*--------------------------------------------------------------------------- + wpalTimerStart - start a wpt_timer object with a timeout value + + \param pTimer - a pointer to caller allocated wpt_timer object + \param timeout - timeout value of the timer. In unit of milli-seconds + + \return + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerStart(wpt_timer * pTimer, wpt_uint32 timeout) +{ + /* Sanity Checks */ + if( pTimer == NULL ) + { + WPAL_TRACE( eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s Wrong param pTimer(%p)", + __func__, pTimer ); + return eWLAN_PAL_STATUS_E_INVAL; + } + return ( WPAL_VOS_TO_WPAL_STATUS( vos_timer_start( &pTimer->timer.timerObj, + timeout ) ) ); +}/*wpalTimerStart*/ + + +/*--------------------------------------------------------------------------- + \brief wpalTimerStop - stop a wpt_timer object. Stop doesn't guarantee the + timer handler is not called if it is already timeout. + + \param pTimer - a pointer to caller allocated wpt_timer object + + \return + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalTimerStop(wpt_timer * pTimer) +{ + /* Sanity Checks */ + if( pTimer == NULL ) + { + WPAL_TRACE( eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s Wrong param pTimer(%p)", + __func__, pTimer ); + return eWLAN_PAL_STATUS_E_INVAL; + } + return (WPAL_VOS_TO_WPAL_STATUS( vos_timer_stop( &pTimer->timer.timerObj ))); +}/*wpalTimerStop*/ + +/*--------------------------------------------------------------------------- + \brief wpalTimerGetCurStatus - Get the current status of timer + + \param pTimer - a pointer to caller allocated wpt_timer object + + \return + VOS_TIMER_STATE +---------------------------------------------------------------------------*/ +WPAL_TIMER_STATE wpalTimerGetCurStatus(wpt_timer * pTimer) +{ + /* Sanity Checks */ + if( pTimer == NULL ) + { + WPAL_TRACE( eWLAN_MODULE_PAL, eWLAN_PAL_TRACE_LEVEL_ERROR, + " %s Wrong param pTimer(%p)", + __func__, pTimer ); + return eWLAN_PAL_STATUS_E_INVAL; + } + return vos_timer_getCurrentState( &pTimer->timer.timerObj ); +}/*wpalTimerGetCurStatus*/ + +/*--------------------------------------------------------------------------- + \brief wpalGetSystemTime - Get the system time in milliseconds + + \return + current time in milliseconds +---------------------------------------------------------------------------*/ +wpt_uint32 wpalGetSystemTime(void) +{ + return vos_timer_get_system_time(); +}/*wpalGetSystemTime*/ + +/*--------------------------------------------------------------------------- + \brief wpalGetArchCounterTime - Get time from physical counter + + \return + MPM counter value +---------------------------------------------------------------------------*/ +#if defined(ANI_OS_TYPE_ANDROID) +wpt_uint64 wpalGetArchCounterTime(void) +{ + return arch_counter_get_cntpct(); +}/*wpalGetArchCounterTime*/ +#else +wpt_uint64 wpalGetArchCounterTime(void) +{ + return 0; +}/*wpalGetArchCounterTime*/ +#endif + +/*--------------------------------------------------------------------------- + wpalSleep - sleep for a specified interval + Param: + timeout - amount of time to sleep. In unit of milli-seconds. + Return: + eWLAN_PAL_STATUS_SUCCESS - success. Fail otherwise. +---------------------------------------------------------------------------*/ +wpt_status wpalSleep(wpt_uint32 timeout) +{ + vos_sleep( timeout ); + return eWLAN_PAL_STATUS_SUCCESS; +} + +/*--------------------------------------------------------------------------- + wpalBusyWait - Thread busy wait with specified usec + Param: + usecDelay - amount of time to wait. In unit of micro-seconds. + Return: + NONE +---------------------------------------------------------------------------*/ +void wpalBusyWait(wpt_uint32 usecDelay) +{ + vos_busy_wait(usecDelay); + return; +} diff --git a/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_trace.c b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_trace.c new file mode 100644 index 000000000000..91df19ecbcf0 --- /dev/null +++ b/drivers/staging/prima/CORE/WDI/WPAL/src/wlan_qct_pal_trace.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + + \file wlan_qct_pal_trace.c + + \brief Implementation trace/logging APIs PAL exports. wpt = (Wlan Pal Type) wpal = (Wlan PAL) + + Definitions for Linux/Android platform + + + ========================================================================*/ + +#include "wlan_qct_pal_trace.h" +#include "i_vos_types.h" + +#ifdef WLAN_DEBUG + + +/*-------------------------------------------------------------------------- + Preprocessor definitions and constants + ------------------------------------------------------------------------*/ + +#define WPAL_TRACE_BUFFER_SIZE ( 512 ) + +// macro to map wpal trace levels into the bitmask +#define WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( _level ) ( ( 1 << (_level) ) ) + +typedef struct +{ + // Trace level for a module, as a bitmask. The bits in this mask + // are ordered by wpt_tracelevel. For example, each bit represents + // one of the bits in wpt_tracelevel that may be turned on to have + // traces at that level logged, i.e. if eWLAN_PAL_TRACE_LEVEL_ERROR is + // == 2, then if bit 2 (low order) is turned ON, then ERROR traces + // will be printed to the trace log. + // + // Note that all bits turned OFF means no traces. + wpt_uint16 moduleTraceLevel; + + // 3 character string name for the module + wpt_uint8 moduleNameStr[ 4 ]; // 3 chars plus the NULL + +} moduleTraceInfo; + + +// Array of static data that contains all of the per module trace +// information. This includes the trace level for the module and +// the 3 character 'name' of the module for marking the trace logs. +moduleTraceInfo gTraceInfo[ eWLAN_MODULE_COUNT ] = +{ + { (1<= eWLAN_PAL_TRACE_LEVEL_COUNT )) + { + traceOn = eWLAN_PAL_FALSE; + } + else + { + traceOn = ( level & gTraceInfo[ module ].moduleTraceLevel ) ? eWLAN_PAL_TRUE : eWLAN_PAL_FALSE; + } + + return( traceOn ); +} + +void wpalTraceDisplay(void) +{ + wpt_moduleid moduleId; + + printk(KERN_CRIT + " 1)FATAL 2)ERROR 3)WARN 4)INFO " + "5)INFO_H 6)INFO_M 7)INFO_L\n"); + for (moduleId = 0; moduleId < eWLAN_MODULE_COUNT; ++moduleId) + { + printk(KERN_CRIT + "%2d)%s %s %s %s " + "%s %s %s %s\n", + (int)moduleId, + gTraceInfo[moduleId].moduleNameStr, + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_FATAL)) ? "X":" ", + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_ERROR)) ? "X":" ", + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_WARN)) ? "X":" ", + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_INFO)) ? "X":" ", + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_INFO_HIGH)) ? "X":" ", + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_INFO_MED)) ? "X":" ", + (gTraceInfo[moduleId].moduleTraceLevel & + (1 << eWLAN_PAL_TRACE_LEVEL_INFO_LOW)) ? "X":" " + ); + } + +} + +/*---------------------------------------------------------------------------- + + \brief wpalTrace() - Externally called trace function + + Checks the level of severity and accordingly prints the trace messages + + \param module - module identifier. A member of the wpt_moduleid + enumeration that identifies the module issuing the trace message. + + \param level - trace level. A member of the wpt_tracelevel + enumeration indicating the severity of the condition causing the + trace message to be issued. More severe conditions are more + likely to be logged. + + \param strFormat - format string. The message to be logged. This format + string contains printf-like replacement parameters, which follow + this parameter in the variable argument list. + + \return nothing + + \sa + + --------------------------------------------------------------------------*/ +void wpalTrace( wpt_moduleid module, wpt_tracelevel level, char *strFormat, ... ) +{ + wpt_uint8 strBuffer[ WPAL_TRACE_BUFFER_SIZE ]; + int n; + + // Print the trace message when the desired level bit is set in the module + // tracel level mask. + if ( gTraceInfo[ module ].moduleTraceLevel & WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( level ) ) + { + va_list val; + va_start(val, strFormat); + + // print the prefix string into the string buffer... + n = snprintf(strBuffer, WPAL_TRACE_BUFFER_SIZE, "wlan: [%d:%2s:%3s] ", + in_interrupt() ? 0 : current->pid, + (char *) TRACE_LEVEL_STR[ level ], + (char *) gTraceInfo[ module ].moduleNameStr); + + + // print the formatted log message after the prefix string. + // note we reserve space for the terminating NUL + if ((n >= 0) && (n < WPAL_TRACE_BUFFER_SIZE)) + { + vsnprintf(strBuffer + n, WPAL_TRACE_BUFFER_SIZE - n - 1, strFormat, val); + wpalOutput(level, strBuffer); + } + va_end(val); + } +} + +/**---------------------------------------------------------------------------- + + \brief WPAL_DUMP() / wpalDump() - Trace / logging API + + Users wishing to add tracing memory dumps to their code should use + WPAL_DUMP. WPAL_DUMP() will compile into a call to wpalDump() when + tracing is enabled. + + \param module - module identifier. A member of the wpt_moduleid + enumeration that identifies the module performing the dump + + \param level - trace level. A member of the wpt_tracelevel + enumeration indicating the severity of the condition causing the + memory to be dumped. More severe conditions are more + likely to be logged. + + \param pMemory - memory. A pointer to the memory to be dumped + + \param length - length. How many bytes of memory to be dumped + + \return nothing + + --------------------------------------------------------------------------*/ +// how many bytes do we output per line +#define BYTES_PER_LINE 16 + +// each byte takes 2 characters plus a space, plus need room for NUL +#define CHARS_PER_LINE ((BYTES_PER_LINE * 3) + 1) + +void wpalDump( wpt_moduleid module, wpt_tracelevel level, + wpt_uint8 *pMemory, wpt_uint32 length) +{ + char strBuffer[CHARS_PER_LINE]; + int n, num, offset; + + // Dump the memory when the desired level bit is set in the module + // tracel level mask. + if ( gTraceInfo[ module ].moduleTraceLevel & WPAL_TRACE_LEVEL_TO_MODULE_BITMASK( level ) ) + { + num = 0; + offset = 0; + while (length > 0) + { + n = snprintf(strBuffer + offset, CHARS_PER_LINE - offset - 1, + "%02X ", *pMemory); + offset += n; + num++; + length--; + pMemory++; + if (BYTES_PER_LINE == num) + { + wpalOutput(level, strBuffer); + num = 0; + offset = 0; + } + } + + if (offset > 0) + { + // partial line remains + wpalOutput(level, strBuffer); + } + } +} +#endif //WLAN_DEBUG diff --git a/drivers/staging/prima/Kbuild b/drivers/staging/prima/Kbuild new file mode 100644 index 000000000000..dfa683e67840 --- /dev/null +++ b/drivers/staging/prima/Kbuild @@ -0,0 +1,725 @@ +# We can build either as part of a standalone Kernel build or part +# of an Android build. Determine which mechanism is being used +ifeq ($(MODNAME),) + KERNEL_BUILD := 1 +else + KERNEL_BUILD := 0 +endif + +ifeq ($(KERNEL_BUILD),1) + # These are provided in Android-based builds + # Need to explicitly define for Kernel-based builds + MODNAME := wlan + WLAN_ROOT := drivers/staging/prima +endif + +ifeq ($(KERNEL_BUILD), 0) +# These are configurable via Kconfig for kernel-based builds +# Need to explicitly configure for Android-based builds + +#Flag to enable BlueTooth AMP feature + CONFIG_PRIMA_WLAN_BTAMP := n + +#Flag to enable Legacy Fast Roaming(LFR) + CONFIG_PRIMA_WLAN_LFR := y + +#Flag to enable Legacy Fast Roaming(LFR) Make Before Break + CONFIG_PRIMA_WLAN_LFR_MBB := y + +#JB kernel has PMKSA patches, hence enabling this flag + CONFIG_PRIMA_WLAN_OKC := y + +# JB kernel has CPU enablement patches, so enable + CONFIG_PRIMA_WLAN_11AC_HIGH_TP := y + +#Flag to enable mDNS feature + CONFIG_MDNS_OFFLOAD_SUPPORT := y + +#Flag to enable TDLS feature + CONFIG_QCOM_TDLS := y + +#Flag to enable Fast Transition (11r) feature + CONFIG_QCOM_VOWIFI_11R := y + +#Flag to enable Protected Managment Frames (11w) feature +ifneq ($(CONFIG_PRONTO_WLAN),) + CONFIG_WLAN_FEATURE_11W := y + endif + +#Flag to enable new Linux Regulatory implementation + CONFIG_ENABLE_LINUX_REG := y + +#Flag to enable offload packets feature + CONFIG_WLAN_OFFLOAD_PACKETS := y + + endif +#Flag to enable AP Find feature +CONFIG_WLAN_FEATURE_AP_FIND := y + +# Flag to enable feature Software AP Authentication Offload +SAP_AUTH_OFFLOAD := y + +# To enable CONFIG_QCOM_ESE_UPLOAD, dependent config +# CONFIG_QCOM_ESE must be enabled. +CONFIG_QCOM_ESE := n +CONFIG_QCOM_ESE_UPLOAD := n + +# Feature flags which are not (currently) configurable via Kconfig + +#Whether to build debug version +BUILD_DEBUG_VERSION := 1 + +#Enable this flag to build driver in diag version +BUILD_DIAG_VERSION := 1 + +#Do we panic on bug? default is to warn +PANIC_ON_BUG := 1 + +#Re-enable wifi on WDI timeout +RE_ENABLE_WIFI_ON_WDI_TIMEOUT := 0 + +ifeq ($(CONFIG_CFG80211),y) +HAVE_CFG80211 := 1 +else +ifeq ($(CONFIG_CFG80211),m) +HAVE_CFG80211 := 1 +else +HAVE_CFG80211 := 0 +endif +endif + +############ BAP ############ +BAP_DIR := CORE/BAP +BAP_INC_DIR := $(BAP_DIR)/inc +BAP_SRC_DIR := $(BAP_DIR)/src + +BAP_INC := -I$(WLAN_ROOT)/$(BAP_INC_DIR) \ + -I$(WLAN_ROOT)/$(BAP_SRC_DIR) + +BAP_OBJS := $(BAP_SRC_DIR)/bapApiData.o \ + $(BAP_SRC_DIR)/bapApiDebug.o \ + $(BAP_SRC_DIR)/bapApiExt.o \ + $(BAP_SRC_DIR)/bapApiHCBB.o \ + $(BAP_SRC_DIR)/bapApiInfo.o \ + $(BAP_SRC_DIR)/bapApiLinkCntl.o \ + $(BAP_SRC_DIR)/bapApiLinkSupervision.o \ + $(BAP_SRC_DIR)/bapApiStatus.o \ + $(BAP_SRC_DIR)/bapApiTimer.o \ + $(BAP_SRC_DIR)/bapModule.o \ + $(BAP_SRC_DIR)/bapRsn8021xAuthFsm.o \ + $(BAP_SRC_DIR)/bapRsn8021xPrf.o \ + $(BAP_SRC_DIR)/bapRsn8021xSuppRsnFsm.o \ + $(BAP_SRC_DIR)/bapRsnAsfPacket.o \ + $(BAP_SRC_DIR)/bapRsnSsmAesKeyWrap.o \ + $(BAP_SRC_DIR)/bapRsnSsmEapol.o \ + $(BAP_SRC_DIR)/bapRsnSsmReplayCtr.o \ + $(BAP_SRC_DIR)/bapRsnTxRx.o \ + $(BAP_SRC_DIR)/btampFsm.o \ + $(BAP_SRC_DIR)/btampHCI.o + +############ DXE ############ +DXE_DIR := CORE/DXE +DXE_INC_DIR := $(DXE_DIR)/inc +DXE_SRC_DIR := $(DXE_DIR)/src + +DXE_INC := -I$(WLAN_ROOT)/$(DXE_INC_DIR) \ + -I$(WLAN_ROOT)/$(DXE_SRC_DIR) + +DXE_OBJS = $(DXE_SRC_DIR)/wlan_qct_dxe.o \ + $(DXE_SRC_DIR)/wlan_qct_dxe_cfg_i.o + +############ HDD ############ +HDD_DIR := CORE/HDD +HDD_INC_DIR := $(HDD_DIR)/inc +HDD_SRC_DIR := $(HDD_DIR)/src + +HDD_INC := -I$(WLAN_ROOT)/$(HDD_INC_DIR) \ + -I$(WLAN_ROOT)/$(HDD_SRC_DIR) + +HDD_OBJS := $(HDD_SRC_DIR)/bap_hdd_main.o \ + $(HDD_SRC_DIR)/wlan_hdd_assoc.o \ + $(HDD_SRC_DIR)/wlan_hdd_cfg.o \ + $(HDD_SRC_DIR)/wlan_hdd_debugfs.o \ + $(HDD_SRC_DIR)/wlan_hdd_dev_pwr.o \ + $(HDD_SRC_DIR)/wlan_hdd_dp_utils.o \ + $(HDD_SRC_DIR)/wlan_hdd_early_suspend.o \ + $(HDD_SRC_DIR)/wlan_hdd_ftm.o \ + $(HDD_SRC_DIR)/wlan_hdd_hostapd.o \ + $(HDD_SRC_DIR)/wlan_hdd_main.o \ + $(HDD_SRC_DIR)/wlan_hdd_mib.o \ + $(HDD_SRC_DIR)/wlan_hdd_oemdata.o \ + $(HDD_SRC_DIR)/wlan_hdd_scan.o \ + $(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \ + $(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \ + $(HDD_SRC_DIR)/wlan_hdd_trace.o \ + $(HDD_SRC_DIR)/wlan_hdd_wext.o \ + $(HDD_SRC_DIR)/wlan_hdd_wmm.o \ + $(HDD_SRC_DIR)/wlan_hdd_wowl.o + +ifeq ($(HAVE_CFG80211),1) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \ + $(HDD_SRC_DIR)/wlan_hdd_p2p.o +endif + +ifeq ($(CONFIG_QCOM_TDLS),y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_tdls.o +endif + +############ MAC ############ +MAC_DIR := CORE/MAC +MAC_INC_DIR := $(MAC_DIR)/inc +MAC_SRC_DIR := $(MAC_DIR)/src + +MAC_INC := -I$(WLAN_ROOT)/$(MAC_INC_DIR) \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/dph \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/include \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/include \ + -I$(WLAN_ROOT)/$(MAC_SRC_DIR)/pe/lim + +MAC_CFG_OBJS := $(MAC_SRC_DIR)/cfg/cfgApi.o \ + $(MAC_SRC_DIR)/cfg/cfgDebug.o \ + $(MAC_SRC_DIR)/cfg/cfgParamName.o \ + $(MAC_SRC_DIR)/cfg/cfgProcMsg.o \ + $(MAC_SRC_DIR)/cfg/cfgSendMsg.o + +MAC_DPH_OBJS := $(MAC_SRC_DIR)/dph/dphHashTable.o + +MAC_LIM_OBJS := $(MAC_SRC_DIR)/pe/lim/limAIDmgmt.o \ + $(MAC_SRC_DIR)/pe/lim/limAdmitControl.o \ + $(MAC_SRC_DIR)/pe/lim/limApi.o \ + $(MAC_SRC_DIR)/pe/lim/limAssocUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limDebug.o \ + $(MAC_SRC_DIR)/pe/lim/limFT.o \ + $(MAC_SRC_DIR)/pe/lim/limIbssPeerMgmt.o \ + $(MAC_SRC_DIR)/pe/lim/limLinkMonitoringAlgo.o \ + $(MAC_SRC_DIR)/pe/lim/limLogDump.o \ + $(MAC_SRC_DIR)/pe/lim/limP2P.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessActionFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessAssocReqFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessAssocRspFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessAuthFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessBeaconFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessCfgUpdates.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessDeauthFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessDisassocFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessLmmMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessMessageQueue.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessMlmReqMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessMlmRspMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessProbeReqFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessProbeRspFrame.o \ + $(MAC_SRC_DIR)/pe/lim/limProcessSmeReqMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limPropExtsUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limRMC.o \ + $(MAC_SRC_DIR)/pe/lim/limRoamingAlgo.o \ + $(MAC_SRC_DIR)/pe/lim/limScanResultUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSecurityUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSendManagementFrames.o \ + $(MAC_SRC_DIR)/pe/lim/limSendMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limSendSmeRspMessages.o \ + $(MAC_SRC_DIR)/pe/lim/limSerDesUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSession.o \ + $(MAC_SRC_DIR)/pe/lim/limSessionUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limSmeReqUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limStaHashApi.o \ + $(MAC_SRC_DIR)/pe/lim/limTimerUtils.o \ + $(MAC_SRC_DIR)/pe/lim/limTrace.o \ + $(MAC_SRC_DIR)/pe/lim/limUtils.o + +ifeq ($(CONFIG_QCOM_ESE),y) +ifneq ($(CONFIG_QCOM_ESE_UPLOAD),y) +MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessEseFrame.o +endif +endif + +ifeq ($(CONFIG_QCOM_TDLS),y) +MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/limProcessTdls.o +endif + +ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y) +MAC_LIM_OBJS += $(MAC_SRC_DIR)/pe/lim/lim_mbb.o +endif + +MAC_PMM_OBJS := $(MAC_SRC_DIR)/pe/pmm/pmmAP.o \ + $(MAC_SRC_DIR)/pe/pmm/pmmApi.o \ + $(MAC_SRC_DIR)/pe/pmm/pmmDebug.o + +MAC_SCH_OBJS := $(MAC_SRC_DIR)/pe/sch/schApi.o \ + $(MAC_SRC_DIR)/pe/sch/schBeaconGen.o \ + $(MAC_SRC_DIR)/pe/sch/schBeaconProcess.o \ + $(MAC_SRC_DIR)/pe/sch/schDebug.o \ + $(MAC_SRC_DIR)/pe/sch/schMessage.o + +MAC_RRM_OBJS := $(MAC_SRC_DIR)/pe/rrm/rrmApi.o + +MAC_OBJS := $(MAC_CFG_OBJS) \ + $(MAC_DPH_OBJS) \ + $(MAC_LIM_OBJS) \ + $(MAC_PMM_OBJS) \ + $(MAC_SCH_OBJS) \ + $(MAC_RRM_OBJS) + +############ SAP ############ +SAP_DIR := CORE/SAP +SAP_INC_DIR := $(SAP_DIR)/inc +SAP_SRC_DIR := $(SAP_DIR)/src + +SAP_INC := -I$(WLAN_ROOT)/$(SAP_INC_DIR) \ + -I$(WLAN_ROOT)/$(SAP_SRC_DIR) + +SAP_OBJS := $(SAP_SRC_DIR)/sapApiLinkCntl.o \ + $(SAP_SRC_DIR)/sapChSelect.o \ + $(SAP_SRC_DIR)/sapFsm.o \ + $(SAP_SRC_DIR)/sapModule.o + +############ SME ############ +SME_DIR := CORE/SME +SME_INC_DIR := $(SME_DIR)/inc +SME_SRC_DIR := $(SME_DIR)/src + +SME_INC := -I$(WLAN_ROOT)/$(SME_INC_DIR) \ + -I$(WLAN_ROOT)/$(SME_SRC_DIR)/csr + +SME_CCM_OBJS := $(SME_SRC_DIR)/ccm/ccmApi.o \ + $(SME_SRC_DIR)/ccm/ccmLogDump.o + +SME_CSR_OBJS := $(SME_SRC_DIR)/csr/csrApiRoam.o \ + $(SME_SRC_DIR)/csr/csrApiScan.o \ + $(SME_SRC_DIR)/csr/csrCmdProcess.o \ + $(SME_SRC_DIR)/csr/csrLinkList.o \ + $(SME_SRC_DIR)/csr/csrLogDump.o \ + $(SME_SRC_DIR)/csr/csrNeighborRoam.o \ + $(SME_SRC_DIR)/csr/csrUtil.o + +ifeq ($(CONFIG_QCOM_ESE),y) +ifneq ($(CONFIG_QCOM_ESE_UPLOAD),y) +SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrEse.o +endif +endif + +ifeq ($(CONFIG_QCOM_TDLS),y) +SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csrTdlsProcess.o +endif + +ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y) +SME_CSR_OBJS += $(SME_SRC_DIR)/csr/csr_roam_mbb.o +endif + +SME_PMC_OBJS := $(SME_SRC_DIR)/pmc/pmcApi.o \ + $(SME_SRC_DIR)/pmc/pmc.o \ + $(SME_SRC_DIR)/pmc/pmcLogDump.o + +SME_QOS_OBJS := $(SME_SRC_DIR)/QoS/sme_Qos.o + +SME_CMN_OBJS := $(SME_SRC_DIR)/sme_common/sme_Api.o \ + $(SME_SRC_DIR)/sme_common/sme_FTApi.o \ + $(SME_SRC_DIR)/sme_common/sme_Trace.o + +SME_BTC_OBJS := $(SME_SRC_DIR)/btc/btcApi.o + +SME_OEM_DATA_OBJS := $(SME_SRC_DIR)/oemData/oemDataApi.o + +SME_P2P_OBJS = $(SME_SRC_DIR)/p2p/p2p_Api.o + +SME_RRM_OBJS := $(SME_SRC_DIR)/rrm/sme_rrm.o + +SME_NAN_OBJS = $(SME_SRC_DIR)/nan/nan_Api.o + + +SME_OBJS := $(SME_BTC_OBJS) \ + $(SME_CCM_OBJS) \ + $(SME_CMN_OBJS) \ + $(SME_CSR_OBJS) \ + $(SME_OEM_DATA_OBJS) \ + $(SME_P2P_OBJS) \ + $(SME_PMC_OBJS) \ + $(SME_QOS_OBJS) \ + $(SME_RRM_OBJS) \ + $(SME_NAN_OBJS) + +############ SVC ############ +SVC_DIR := CORE/SVC +SVC_INC_DIR := $(SVC_DIR)/inc +SVC_SRC_DIR := $(SVC_DIR)/src + +SVC_INC := -I$(WLAN_ROOT)/$(SVC_INC_DIR) \ + -I$(WLAN_ROOT)/$(SVC_DIR)/external + +BTC_SRC_DIR := $(SVC_SRC_DIR)/btc +BTC_OBJS := $(BTC_SRC_DIR)/wlan_btc_svc.o + +NLINK_SRC_DIR := $(SVC_SRC_DIR)/nlink +NLINK_OBJS := $(NLINK_SRC_DIR)/wlan_nlink_srv.o + +PTT_SRC_DIR := $(SVC_SRC_DIR)/ptt +PTT_OBJS := $(PTT_SRC_DIR)/wlan_ptt_sock_svc.o + +WLAN_LOGGING_SRC_DIR := $(SVC_SRC_DIR)/logging +WLAN_LOGGING_OBJS := $(WLAN_LOGGING_SRC_DIR)/wlan_logging_sock_svc.o + +SVC_OBJS := $(BTC_OBJS) \ + $(NLINK_OBJS) \ + $(PTT_OBJS) \ + $(WLAN_LOGGING_OBJS) + +############ SYS ############ +SYS_DIR := CORE/SYS + +SYS_INC := -I$(WLAN_ROOT)/$(SYS_DIR)/common/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/pal/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/platform/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/system/inc \ + -I$(WLAN_ROOT)/$(SYS_DIR)/legacy/src/utils/inc + +SYS_COMMON_SRC_DIR := $(SYS_DIR)/common/src +SYS_LEGACY_SRC_DIR := $(SYS_DIR)/legacy/src +SYS_OBJS := $(SYS_COMMON_SRC_DIR)/wlan_qct_sys.o \ + $(SYS_LEGACY_SRC_DIR)/pal/src/palApiComm.o \ + $(SYS_LEGACY_SRC_DIR)/pal/src/palTimer.o \ + $(SYS_LEGACY_SRC_DIR)/platform/src/VossWrapper.o \ + $(SYS_LEGACY_SRC_DIR)/system/src/macInitApi.o \ + $(SYS_LEGACY_SRC_DIR)/system/src/sysEntryFunc.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/dot11f.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/logApi.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/logDump.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/macTrace.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/parserApi.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/utilsApi.o \ + $(SYS_LEGACY_SRC_DIR)/utils/src/utilsParser.o + +############ TL ############ +TL_DIR := CORE/TL +TL_INC_DIR := $(TL_DIR)/inc +TL_SRC_DIR := $(TL_DIR)/src + +TL_INC := -I$(WLAN_ROOT)/$(TL_INC_DIR) \ + -I$(WLAN_ROOT)/$(TL_SRC_DIR) + +TL_OBJS := $(TL_SRC_DIR)/wlan_qct_tl.o \ + $(TL_SRC_DIR)/wlan_qct_tl_ba.o \ + $(TL_SRC_DIR)/wlan_qct_tl_hosupport.o \ + $(TL_SRC_DIR)/wlan_qct_tl_trace.o + +############ VOSS ############ +VOSS_DIR := CORE/VOSS +VOSS_INC_DIR := $(VOSS_DIR)/inc +VOSS_SRC_DIR := $(VOSS_DIR)/src + +VOSS_INC := -I$(WLAN_ROOT)/$(VOSS_INC_DIR) \ + -I$(WLAN_ROOT)/$(VOSS_SRC_DIR) + +VOSS_OBJS := $(VOSS_SRC_DIR)/vos_api.o \ + $(VOSS_SRC_DIR)/vos_event.o \ + $(VOSS_SRC_DIR)/vos_getBin.o \ + $(VOSS_SRC_DIR)/vos_list.o \ + $(VOSS_SRC_DIR)/vos_lock.o \ + $(VOSS_SRC_DIR)/vos_memory.o \ + $(VOSS_SRC_DIR)/vos_mq.o \ + $(VOSS_SRC_DIR)/vos_nvitem.o \ + $(VOSS_SRC_DIR)/vos_packet.o \ + $(VOSS_SRC_DIR)/vos_sched.o \ + $(VOSS_SRC_DIR)/vos_threads.o \ + $(VOSS_SRC_DIR)/vos_timer.o \ + $(VOSS_SRC_DIR)/vos_trace.o \ + $(VOSS_SRC_DIR)/vos_types.o \ + $(VOSS_SRC_DIR)/vos_utils.o \ + $(VOSS_SRC_DIR)/wlan_nv_parser.o \ + $(VOSS_SRC_DIR)/wlan_nv_stream_read.o \ + $(VOSS_SRC_DIR)/wlan_nv_template_builtin.o + +ifeq ($(BUILD_DIAG_VERSION),1) +VOSS_OBJS += $(VOSS_SRC_DIR)/vos_diag.o +endif + +############ WDA ############ +WDA_DIR := CORE/WDA +WDA_INC_DIR := $(WDA_DIR)/inc +WDA_SRC_DIR := $(WDA_DIR)/src + +WDA_INC := -I$(WLAN_ROOT)/$(WDA_INC_DIR) \ + -I$(WLAN_ROOT)/$(WDA_INC_DIR)/legacy \ + -I$(WLAN_ROOT)/$(WDA_SRC_DIR) + +WDA_OBJS := $(WDA_SRC_DIR)/wlan_qct_wda.o \ + $(WDA_SRC_DIR)/wlan_qct_wda_debug.o \ + $(WDA_SRC_DIR)/wlan_qct_wda_ds.o \ + $(WDA_SRC_DIR)/wlan_qct_wda_legacy.o \ + $(WDA_SRC_DIR)/wlan_nv.o + +############ WDI ############ +WDI_DIR := CORE/WDI + +WDI_CP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/CP/inc/ + +WDI_CP_SRC_DIR := $(WDI_DIR)/CP/src +WDI_CP_OBJS := $(WDI_CP_SRC_DIR)/wlan_qct_wdi.o \ + $(WDI_CP_SRC_DIR)/wlan_qct_wdi_dp.o \ + $(WDI_CP_SRC_DIR)/wlan_qct_wdi_sta.o + +WDI_DP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/DP/inc/ + +WDI_DP_SRC_DIR := $(WDI_DIR)/DP/src +WDI_DP_OBJS := $(WDI_DP_SRC_DIR)/wlan_qct_wdi_bd.o \ + $(WDI_DP_SRC_DIR)/wlan_qct_wdi_ds.o + +WDI_TRP_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/TRP/CTS/inc/ \ + -I$(WLAN_ROOT)/$(WDI_DIR)/TRP/DTS/inc/ + +WDI_TRP_CTS_SRC_DIR := $(WDI_DIR)/TRP/CTS/src +WDI_TRP_CTS_OBJS := $(WDI_TRP_CTS_SRC_DIR)/wlan_qct_wdi_cts.o + +WDI_TRP_DTS_SRC_DIR := $(WDI_DIR)/TRP/DTS/src +WDI_TRP_DTS_OBJS := $(WDI_TRP_DTS_SRC_DIR)/wlan_qct_wdi_dts.o + +WDI_TRP_OBJS := $(WDI_TRP_CTS_OBJS) \ + $(WDI_TRP_DTS_OBJS) + +WDI_WPAL_INC := -I$(WLAN_ROOT)/$(WDI_DIR)/WPAL/inc + +WDI_WPAL_SRC_DIR := $(WDI_DIR)/WPAL/src +WDI_WPAL_OBJS := $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_api.o \ + $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_device.o \ + $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_msg.o \ + $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_packet.o \ + $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_sync.o \ + $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_timer.o \ + $(WDI_WPAL_SRC_DIR)/wlan_qct_pal_trace.o + +WDI_INC := $(WDI_CP_INC) \ + $(WDI_DP_INC) \ + $(WDI_TRP_INC) \ + $(WDI_WPAL_INC) + +WDI_OBJS := $(WDI_CP_OBJS) \ + $(WDI_DP_OBJS) \ + $(WDI_TRP_OBJS) \ + $(WDI_WPAL_OBJS) + + +RIVA_INC := -I$(WLAN_ROOT)/riva/inc + +LINUX_INC := -Iinclude/linux + +INCS := $(BAP_INC) \ + $(DXE_INC) \ + $(HDD_INC) \ + $(LINUX_INC) \ + $(MAC_INC) \ + $(RIVA_INC) \ + $(SAP_INC) \ + $(SME_INC) \ + $(SVC_INC) \ + $(SYS_INC) \ + $(TL_INC) \ + $(VOSS_INC) \ + $(WDA_INC) \ + $(WDI_INC) + +OBJS := $(BAP_OBJS) \ + $(DXE_OBJS) \ + $(HDD_OBJS) \ + $(MAC_OBJS) \ + $(SAP_OBJS) \ + $(SME_OBJS) \ + $(SVC_OBJS) \ + $(SYS_OBJS) \ + $(TL_OBJS) \ + $(VOSS_OBJS) \ + $(WDA_OBJS) \ + $(WDI_OBJS) + +EXTRA_CFLAGS += $(INCS) +EXTRA_CFLAGS += -fno-pic + +CDEFINES := -DANI_BUS_TYPE_PLATFORM=1 \ + -DANI_LITTLE_BYTE_ENDIAN \ + -DANI_LITTLE_BIT_ENDIAN \ + -DQC_WLAN_CHIPSET_PRIMA \ + -DINTEGRATION_READY \ + -DDOT11F_LITTLE_ENDIAN_HOST \ + -DGEN6_ONWARDS \ + -DANI_COMPILER_TYPE_GCC \ + -DANI_OS_TYPE_ANDROID=6 \ + -DANI_LOGDUMP \ + -DWLAN_PERF \ + -DPTT_SOCK_SVC_ENABLE \ + -Wall\ + -D__linux__ \ + -DMSM_PLATFORM \ + -DHAL_SELF_STA_PER_BSS=1 \ + -DWLAN_FEATURE_VOWIFI_11R \ + -DWLAN_FEATURE_NEIGHBOR_ROAMING \ + -DWLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG \ + -DWLAN_FEATURE_VOWIFI_11R_DEBUG \ + -DFEATURE_WLAN_WAPI \ + -DFEATURE_OEM_DATA_SUPPORT\ + -DSOFTAP_CHANNEL_RANGE \ + -DWLAN_AP_STA_CONCURRENCY \ + -DFEATURE_WLAN_SCAN_PNO \ + -DWLAN_FEATURE_PACKET_FILTERING \ + -DWLAN_FEATURE_VOWIFI \ + -DWLAN_FEATURE_11AC \ + -DWLAN_FEATURE_P2P_DEBUG \ + -DWLAN_ENABLE_AGEIE_ON_SCAN_RESULTS \ + -DWLANTL_DEBUG\ + -DWLAN_NS_OFFLOAD \ + -DWLAN_ACTIVEMODE_OFFLOAD_FEATURE \ + -DWLAN_FEATURE_HOLD_RX_WAKELOCK \ + -DWLAN_SOFTAP_VSTA_FEATURE \ + -DWLAN_FEATURE_ROAM_SCAN_OFFLOAD \ + -DWLAN_FEATURE_GTK_OFFLOAD \ + -DWLAN_WAKEUP_EVENTS \ + -DWLAN_KD_READY_NOTIFIER \ + -DWLAN_FEATURE_RMC \ + -DWLAN_NL80211_TESTMODE \ + -DFEATURE_WLAN_BATCH_SCAN \ + -DFEATURE_WLAN_LPHB \ + -DFEATURE_WLAN_PAL_TIMER_DISABLE \ + -DFEATURE_WLAN_PAL_MEM_DISABLE \ + -DFEATURE_WLAN_CH144 \ + -DWLAN_BUG_ON_SKB_ERROR \ + -DWLAN_DXE_LOW_RESOURCE_TIMER \ + -DWLAN_LOGGING_SOCK_SVC_ENABLE \ + -DWLAN_FEATURE_LINK_LAYER_STATS \ + -DWLAN_FEATURE_EXTSCAN \ + -DFEATURE_EXT_LL_STAT \ + -DWLAN_VOWIFI_DEBUG \ + -DDHCP_SERVER_OFFLOAD \ + -DWLAN_FEATURE_TSF + +ifneq ($(CONFIG_PRONTO_WLAN),) +CDEFINES += -DWCN_PRONTO +CDEFINES += -DWCN_PRONTO_V1 +endif + +ifeq ($(BUILD_DEBUG_VERSION),1) +CDEFINES += -DWLAN_DEBUG \ + -DTRACE_RECORD \ + -DLIM_TRACE_RECORD \ + -DSME_TRACE_RECORD \ + -DPE_DEBUG_LOGW \ + -DPE_DEBUG_LOGE \ + -DDXE_TRACE \ + -DDEBUG +endif + +ifeq ($(CONFIG_SLUB_DEBUG_ON),y) +CDEFINES += -DTIMER_MANAGER +CDEFINES += -DMEMORY_DEBUG +endif + +ifeq ($(HAVE_CFG80211),1) +CDEFINES += -DWLAN_FEATURE_P2P +CDEFINES += -DWLAN_FEATURE_WFD +ifeq ($(CONFIG_QCOM_VOWIFI_11R),y) +CDEFINES += -DKERNEL_SUPPORT_11R_CFG80211 +CDEFINES += -DUSE_80211_WMMTSPEC_FOR_RIC +endif +endif + +ifeq ($(CONFIG_QCOM_ESE),y) +CDEFINES += -DFEATURE_WLAN_ESE +ifeq ($(CONFIG_QCOM_ESE_UPLOAD),y) +CDEFINES += -DFEATURE_WLAN_ESE_UPLOAD +endif +endif + +#normally, TDLS negative behavior is not needed +ifeq ($(CONFIG_QCOM_TDLS),y) +CDEFINES += -DFEATURE_WLAN_TDLS +CDEFINES += -DCONFIG_TDLS_IMPLICIT +endif + +ifeq ($(CONFIG_PRIMA_WLAN_BTAMP),y) +CDEFINES += -DWLAN_BTAMP_FEATURE +endif + +ifeq ($(CONFIG_PRIMA_WLAN_LFR),y) +CDEFINES += -DFEATURE_WLAN_LFR +endif + +ifeq ($(CONFIG_PRIMA_WLAN_LFR_MBB),y) +CDEFINES += -DWLAN_FEATURE_LFR_MBB +endif + +ifeq ($(CONFIG_PRIMA_WLAN_OKC),y) +CDEFINES += -DFEATURE_WLAN_OKC +endif + +ifeq ($(CONFIG_PRIMA_WLAN_11AC_HIGH_TP),y) +CDEFINES += -DWLAN_FEATURE_11AC_HIGH_TP +endif + +ifeq ($(BUILD_DIAG_VERSION),1) +CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT +CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_CSR +CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_LIM +endif + +# enable the MAC Address auto-generation feature +CDEFINES += -DWLAN_AUTOGEN_MACADDR_FEATURE + +ifeq ($(CONFIG_WLAN_FEATURE_11W),y) +CDEFINES += -DWLAN_FEATURE_11W +endif + +ifeq ($(PANIC_ON_BUG),1) +CDEFINES += -DPANIC_ON_BUG +endif + +ifeq ($(RE_ENABLE_WIFI_ON_WDI_TIMEOUT),1) +CDEFINES += -DWDI_RE_ENABLE_WIFI_ON_WDI_TIMEOUT +endif + +ifeq ($(KERNEL_BUILD),1) +CDEFINES += -DWLAN_OPEN_SOURCE +endif + +ifeq ($(findstring opensource, $(WLAN_ROOT)), opensource) +CDEFINES += -DWLAN_OPEN_SOURCE +endif + +ifeq ($(CONFIG_ENABLE_LINUX_REG), y) +CDEFINES += -DCONFIG_ENABLE_LINUX_REG +endif + +# Enable feature SAP Authentication Offload +ifeq ($(SAP_AUTH_OFFLOAD), y) +CDEFINES += -DSAP_AUTH_OFFLOAD +endif + +ifeq ($(CONFIG_WLAN_FEATURE_AP_FIND), y) +CDEFINES += -DWLAN_FEATURE_APFIND +endif + +CDEFINES += -DFEATURE_WLAN_CH_AVOID +CDEFINES += -DWLAN_FEATURE_AP_HT40_24G + +# Some kernel include files are being moved. Check to see if +# the old version of the files are present + +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/mach-msm/include/mach/msm_smd.h),) +CDEFINES += -DEXISTS_MSM_SMD +endif + +ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/mach-msm/include/mach/msm_smsm.h),) +CDEFINES += -DEXISTS_MSM_SMSM +endif + +# Fix build for GCC 4.7 +EXTRA_CFLAGS += -Wno-maybe-uninitialized -Wno-unused-function + +ifeq ($(CONFIG_WLAN_OFFLOAD_PACKETS),y) +CDEFINES += -DWLAN_FEATURE_OFFLOAD_PACKETS +endif + +ifeq ($(CONFIG_MDNS_OFFLOAD_SUPPORT), y) +CDEFINES += -DMDNS_OFFLOAD +endif + +KBUILD_CPPFLAGS += $(CDEFINES) + +# Module information used by KBuild framework +obj-$(CONFIG_PRIMA_WLAN) += $(MODNAME).o +obj-$(CONFIG_PRONTO_WLAN) += $(MODNAME).o +$(MODNAME)-y := $(OBJS) diff --git a/drivers/staging/prima/Kconfig b/drivers/staging/prima/Kconfig new file mode 100644 index 000000000000..e3fcf736961b --- /dev/null +++ b/drivers/staging/prima/Kconfig @@ -0,0 +1,60 @@ +comment "Qualcomm Atheros Prima WLAN module" + +config PRIMA_WLAN + + tristate "Qualcomm Atheros Prima WLAN module" + default n + help + Add support for the Qualcomm Atheros Prima WLAN module + +config PRONTO_WLAN + + tristate "Qualcomm Atheros Pronto WLAN module" + default n + help + Add support for the Qualcomm Atheros Pronto WLAN module + + +# depends on WLAN +# depends on CFG80211 +# depends on WCNSS_CORE + +if PRIMA_WLAN != n || PRONTO_WLAN != n + +config PRIMA_WLAN_BTAMP + bool "Enable the Prima WLAN BT-AMP feature" + default n + +config PRIMA_WLAN_LFR + bool "Enable the Prima WLAN Legacy Fast Roaming feature" + default n + +config PRIMA_WLAN_OKC + bool "Enable the Prima WLAN Opportunistic Key Caching feature" + default n + +config PRIMA_WLAN_11AC_HIGH_TP + bool "Enable the Prima WLAN 802.11ac High Throughput option (depends upon kernel support)" + default n + +config WLAN_FEATURE_11W + bool "Enable the WLAN 802.11w Protected Management Frames feature" + default n + +config QCOM_VOWIFI_11R + bool "Enable Fast Transition (11r) feature" + default n + +config ENABLE_LINUX_REG + bool "Enable linux regulatory feature" + default n + +config WLAN_OFFLOAD_PACKETS + bool "Enable offload packets feature" + default n + +config QCOM_TDLS + bool "Enable TDLS feature" + default n + +endif # PRIMA_WLAN || PRONTO_WLAN diff --git a/drivers/staging/prima/Makefile b/drivers/staging/prima/Makefile new file mode 100644 index 000000000000..d5c94f00a43c --- /dev/null +++ b/drivers/staging/prima/Makefile @@ -0,0 +1,17 @@ +default: all + +KBUILD_OPTIONS := WLAN_ROOT=$(PWD) +KBUILD_OPTIONS += MODNAME=wlan + +all:: + $(MAKE) -C $(KERNEL_SOURCE) $(KBUILD_OPTIONS) $(EXTRA_CFLAGS) ARCH=$(ARCH) \ + SUBDIRS=$(CURDIR) CC=${CC} modules + +modules_install: + $(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install + +clean:: + rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers + rm -rf .tmp_versions + + diff --git a/drivers/staging/prima/firmware_bin/WCNSS_cfg.dat b/drivers/staging/prima/firmware_bin/WCNSS_cfg.dat new file mode 100644 index 0000000000000000000000000000000000000000..0637816b8238eb9990803e1014ad42a1bd8d2c77 GIT binary patch literal 11514 zcmeI137izg6^CE%G&_4Sy(5aZJFdVWAhR3-B1)@-`&h4_MiFF1j0+43ii+CcqG(VD zk07D}Vo*`>zVTS&MLZ%JW8#T1@xlucjRAD?y`HI|ci4&ikZ3d%`|YcK_3Bl1RbTtZ zDhribQeds^AW|SAHnfF4Ek&APYq7K7(}&alhFK!b;Rp>Z?`KPSJ8Y>~P*fh5f|wHv z#Y)AlPDneqwd@1^VK_9acHBY;k96!JD25U!O*v8q%^?C#(vfnA!Zx1cw!m(ibnNY* zC2S8nz>Y8`7LwXzNOnpkWam`EJvA1Wx@24~hRb1>WJ0d?;_j}gQrRu#NCm{iiR~_q zUFkXY9?*(^X7>h!>GV@gGM0aQM0B z#8ym?%NJ03Zd`VU?l1&K!|8AdEP|!*0=x%bLyNk&>Yq!35%xRgOCmPKHxp5=@3u;WU^6r^6X= zCQOC1;A}VtJeUU4;asSL8E_t)4>REcxDb8?v*04Q7%qVnbC?a6CLQ-O?B#F;{5qMC zIn|DPCCr7ZU>;lz*T8S89hnacU?Kb#u7%&hqGZCp4z7nAU@_cC&YO~s`_PQAd$Z@* zOW+o9yLXY}Zny{Th5O)s zXm?TAeE_=@9)ySBVR!`U;Zd&J-?K-L#T@%_cmke;r(hZUA?e7|o+Hn|v+x}Jk@)9f zIlKTb!k^$J_%pl=e}TWkE8JJFlH)aa9p0e-o8rg{c#HPG!Q0~4e}{kIdk5Zy_wc{Z z{62t{@F9GJ?_=6N!F~#>;4^Zr#(oZK;0yQ?{s~{fzi3~JUB~shKIO>Q@C`J8%yz_r z0tiiXTsz9O3xyLMI}Alo3?)zsWyJ6Zm8!`iHCV0dv(}XM#Uh0qC~k$wwpe{8_k!_o zU#ZCZp)||G8|s=z(V~4`4N0hW)4KZfaULwe81?5Ko7kBxm?H-|KSkr1n&`Vk z>uPs~s5%2h+w>ev@n0u#k%oq}$4p)0v|eHYGd8!sx*vHfJ!U4vH@XhGZl;)boUW}F z9nQ>C=cDyn{iP+aDC~0HV!|~bSkKqNoVLa)-!KWKsglocVqGel&x~uVp0`;yvv#IU zZ4lizv+f>sU2L zj!Z?*UvudB>OOHx_(gr%hug(3=9;&hG8SZ1xwu~{dLHFa&%V}AU8YISUXZ)r3+)Nk-X{(PA6 zjnz(WCf@WlZFzGLpN-Abb?MUmj3tI3-;LE=p2qsV##YzYjHTZziXQ8^>NrX@s882H zkB#-)`4z*rK7+2Ij$?BAG5E}J&}y50uc%MgPuEiG+?M|M`VC>eNmI+w5CYWDrbTTq zr^YLFp!bQQF(yvO(7ze9Pw+cKkM*3@>bG&9K9!XsUAmNTRoI~dt0-Kkw+d6!719~% zjL~^ycWGH_7ZgdQwAx{tvf7dTt3+DU)`qsYgqww|LcS)W(R9A<(oU*6v~A_~>e02b zw9qQ(*se{unH?%CDJ~jY6KOtWQnGetoi}yvoGWH6oPW){{d;!n{N;sD;4IzFi8bax>{isaB&lOVB5aP%9YoaolX#C3@ zd9Xs9bYEE(l~Y+mjStHhoMC@Oh4|C*-G zWlvfEWexgM(coWWx}J5^be(hkGlKr24e{sY@t==Bn?DdgGf(^ldHfeP>33w7==Gee z9b4l~oia&g&8$nxm0}fGmStPq09G@r$O>B}REi~cj)0o zWFO-4X~;e4Z#3k6Q;yvW_JjSQH*<8c2QbG2>l0|j3H0N*te+m1KGc29xZaU|^^V;i zI{?s(-9h9WoJ!b3utUMujEOlI4j~4;*glN8X7pki?m1|=4qC2*mg}J9Ix!19czf6j z4uT_L0?dGUa63E&Z@}kJj2>J8d&3|Y1*gG9a4p;q&%-;g4vyxWqBG)h4CgU|@s5R& z%xM&w+;PlhG;^$h<6%s_-jtj1_3ew|kC#2iz$U zxl8!J1~lZmv3+@~^+QAMkA{2?#{ctPhQV43rgVB()dNFP2 z#qMM9I6MJQrqGL-i?0{Q9Q$c_2A+lI0KHhA_Z(RcFTjh?STBx9Rxc*ctMD427u#>Z zo7`I~$bnug=*99j{n3lX*NbU?7v2-}V)y|6O85|by_or-7rW@iE_$*1Su$d;rY%P= zmVjPtuO;6)SPx&rH;mbUl}8h9Rxh6Ihz-r45W;|7>=s88QUV#h*lvz)903Q)AxaES zPyc&uOX$e@HbLa=G79C&f`UM*->eq2|%i{Wt=dA0JPgmAF2A!|w)Z_68qk7DTakiwt z$g+oxD%!`CVBPp~t(m$RdrRrcCZCR{=WW)`tY5yl>E7wzLRviiMF;gYiZ2pzbA22K zi-~9X{Jp=}n#JD~EaO&P+20S{hh-Ve{(Ki*nN-<(MeB`<*^EZcZ$H?~Zr`4G6C=#E zs^K~pL%#08c#Uc5xuAZ%pMU6c(|P>Z%KzJ%nRkz|x?koRY-%k`TT}a*8=rfv>U*H3 zsgC$^V@+7_nXb1R(DvY5wZ5ga=NP$6Zhw6<$GYA+2YZK_AI}ABEgr8U2ZA(E&|3phY7@Z`GoGP5URV UMeEbae{^AZcm5A)(YJK?Hy~E=RR910 literal 0 HcmV?d00001 diff --git a/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini b/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini new file mode 100644 index 000000000000..dbb09688542b --- /dev/null +++ b/drivers/staging/prima/firmware_bin/WCNSS_qcom_cfg.ini @@ -0,0 +1,529 @@ +# This file allows user to override the factory + +# defaults for the WLAN Driver + + +# Enable IMPS or not +gEnableImps=1 + +# Enable/Disable Idle Scan + +gEnableIdleScan=0 + + +# Enable/Disable vsta based on MAX Assoc limit +gEnableVSTASupport=1 + + +# Increase sleep duration (seconds) during IMPS +# 0 implies no periodic wake up from IMPS. Periodic wakeup is +# unnecessary if Idle Scan is disabled. +gImpsModSleepTime=0 + + +# Enable BMPS or not +gEnableBmps=1 + +# Enable suspend or not + +# 1: Enable standby, 2: Enable Deep sleep, 3: Enable Mcast/Bcast Filter + +gEnableSuspend=3 + +# Phy Mode (auto, b, g, n, etc) +# Valid values are 0-9, with 0 = Auto, 4 = 11n, 9 = 11ac +gDot11Mode=0 + + +# CSR Roaming Enable(1) Disable(0) + +gRoamingTime=0 + + +# Assigned MAC Addresses - This will be used until NV items are in place + +# Each byte of MAC address is represented in Hex format as XX + +Intf0MacAddress=000AF58989FF +Intf1MacAddress=000AF58989FE +Intf2MacAddress=000AF58989FD + +Intf3MacAddress=000AF58989FC + + +# UAPSD service interval for VO,VI, BE, BK traffic + +InfraUapsdVoSrvIntv=0 + +InfraUapsdViSrvIntv=0 + +InfraUapsdBeSrvIntv=0 + +InfraUapsdBkSrvIntv=0 + +# Flag to allow STA send AddTspec even when ACM is Off +gAddTSWhenACMIsOff=1 + +# Make 1x1 the default antenna configuration + +gNumRxAnt=1 + + +# Beacon filtering frequency (unit in beacon intervals) + +gNthBeaconFilter=50 + + +# Enable WAPI or not + +# WAPIIsEnabled=0 + + +# Flags to filter Mcast abd Bcast RX packets. + +# Value 0: No filtering, 1: Filter all Multicast. + +# 2: Filter all Broadcast. 3: Filter all Mcast abd Bcast + +McastBcastFilter=3 + + +#Flag to enable HostARPOffload feature or not + +hostArpOffload=1 + + +#Flag to enable HostNSOffload feature or not + +hostNSOffload=0 + +#SoftAP Related Parameters + +# AP MAc addr + +gAPMacAddr=000AF589dcab + + +# 802.11n Protection flag + +gEnableApProt=1 + + +#Enable OBSS protection + +gEnableApOBSSProt=1 + + +#Enable/Disable UAPSD for SoftAP + +gEnableApUapsd=1 + + +# Fixed Rate + +gFixedRate=0 + + +# Maximum Tx power + +# gTxPowerCap=30 + + +# Fragmentation Threshold + +# gFragmentationThreshold=2346 + + +# RTS threshold + +RTSThreshold=2347 + + +# Intra-BSS forward + +gDisableIntraBssFwd=0 + + +# WMM Enable/Disable + +WmmIsEnabled=0 + + +# 802.11d support + +g11dSupportEnabled=1 + +# 802.11h support + +g11hSupportEnabled=1 + +# ESE Support and fast transition +EseEnabled=0 +ImplicitQosIsEnabled=0 +gNeighborScanTimerPeriod=200 + +gNeighborLookupThreshold=76 +gNeighborReassocThreshold=81 + +gNeighborScanChannelMinTime=20 +gNeighborScanChannelMaxTime=30 +gMaxNeighborReqTries=3 + +# Legacy (non-ESE, non-802.11r) Fast Roaming Support +# To enable, set FastRoamEnabled=1 +# To disable, set FastRoamEnabled=0 +FastRoamEnabled=1 + +#Check if the AP to which we are roaming is better than current AP in terms of RSSI. +#Checking is disabled if set to Zero.Otherwise it will use this value as to how better +#the RSSI of the new/roamable AP should be for roaming +RoamRssiDiff=3 + +# If the RSSI of any available candidate is better than currently associated +# AP by at least gImmediateRoamRssiDiff, then being to roam immediately (without +# registering for reassoc threshold). +# NOTE: Value of 0 means that we would register for reassoc threshold. +gImmediateRoamRssiDiff=10 + +# To enable, set gRoamIntraBand=1 (Roaming within band) +# To disable, set gRoamIntraBand=0 (Roaming across band) + +gRoamIntraBand=0 + +#SAP Country code + +# Default Country Code is 2 bytes, 3rd byte is optional indoor or out door. + +# Example + +# US Indoor, USI + +# Korea Outdoor, KRO + +# Japan without optional byte, JP + +# France without optional byte, FR + +#gAPCntryCode=USI + + +#Short Guard Interval Enable/disable + +gShortGI20Mhz=1 + +gShortGI40Mhz=1 + + +#Auto Shutdown Value in seconds. A value of 0 means Auto shutoff is disabled + +gAPAutoShutOff=0 + + +# SAP auto channel selection configuration + +# 0 = disable auto channel selection + +# 1 = enable auto channel selection, channel provided by supplicant will be ignored + +gApAutoChannelSelection=1 + + +# Listen Energy Detect Mode Configuration + +# Valid values 0-128 + +# 128 means disable Energy Detect feature + +# 0-9 are threshold code and 7 is recommended value from system if feature is to be enabled. + +# 10-128 are reserved. + +# The EDET threshold mapping is as follows in 3dB step: + +# 0 = -60 dBm + +# 1 = -63 dBm + +# 2 = -66 dBm + +# ... + +# 7 = -81 dBm + +# 8 = -84 dBm + +# 9 = -87 dBm + +# Note: Any of these settings are valid. Setting 0 would yield the highest power saving (in a noisy environment) at the cost of more range. The range impact is approximately #calculated as: + +# + +# Range Loss (dB) = EDET threshold level (dBm) + 97 dBm. + +# + +gEnablePhyAgcListenMode=128 + + +#Preferred channel to start BT AMP AP mode (0 means, any channel) + +BtAmpPreferredChannel=0 + + +#Preferred band (both or 2.4 only or 5 only) + +BandCapability=0 + + +#Beacon Early Termination (1 = enable the BET feature, 0 = disable) + +enableBeaconEarlyTermination=0 + +beaconEarlyTerminationWakeInterval=3 + + +#Bluetooth Alternate Mac Phy (1 = enable the BT AMP feature, 0 = disable) + +gEnableBtAmp=0 + + +#SOFTAP Channel Range selection + +gAPChannelSelectStartChannel=1 + +gAPChannelSelectEndChannel=11 + + +#SOFTAP Channel Range selection Operating band + +# 0:2.4GHZ 1: LOW-5GHZ 2:MID-5GHZ 3:HIGH-5GHZ 4: 4.9HZ BAND 5: 5GHZ BAND + +gAPChannelSelectOperatingBand=0 + + +#Channel Bonding +gChannelBondingMode5GHz=1 +gChannelBondingMode24GHz=1 + +#Enable Keep alive with non-zero period value + +#gStaKeepAlivePeriod = 30 + +#Say gGoKeepAlivePeriod(5 seconds) and gGoLinkMonitorPeriod(10 seconds). +#For every 10 seconds DUT send Qos Null frame(i.e., Keep Alive frame if link is idle for last 10 seconds.) +#For both active and power save clients. + +#Power save clients: DUT set TIM bit from 10th second onwards and till client honors TIM bit. +#If doesn't honor for 5 seconds then DUT remove client. + +#Active clients: DUT send Qos Null frame for 10th seconds onwards if it is not success still we try on +#11th second if not tries on 12th and so on till 15th second. Hence before disconnection DUT will send 5 NULL frames. +#Hence in any case DUT will detect client got removed in (10+5) seconds. i.e., (gGoKeepAlivePeriod + gGoLinkMonitorPeriod).. + +#gGoLinkMonitorPeriod/ gApLinkMonitorPeriod is period where link is idle and it is period +#where we send NULL frame. + +#gApLinkMonitorPeriod = 10 + +#gGoLinkMonitorPeriod = 10 + +#gGoKeepAlivePeriod/gApKeepAlivePeriod is time to spend to check whether frame are succeed to send or not. +#Hence total effective detection time is gGoLinkMonitorPeriod+ gGoKeepAlivePeriod/gApLinkMonitorPeriod+ gApKeepAlivePeriod. + + +gGoKeepAlivePeriod=30 + +gApKeepAlivePeriod=10 + + +#If set will start with active scan after driver load, otherwise will start with + +#passive scan to find out the domain + +gEnableBypass11d=1 + + +#If set to 0, will not scan DFS channels + +gEnableDFSChnlScan=1 + + +gVhtChannelWidth=2 +gEnableLogp=1 + + +# Enable Automatic Tx Power control + +gEnableAutomaticTxPowerControl=0 + +# 0 for OLPC 1 for CLPC and SCPC +gEnableCloseLoop=1 + +#Data Inactivity Timeout when in powersave (in ms) +gDataInactivityTimeout=200 + +# VHT Tx/Rx MCS values +# Valid values are 0,1,2. If commented out, the default value is 0. +# 0=MCS0-7, 1=MCS0-8, 2=MCS0-9 +gVhtRxMCS=2 +gVhtTxMCS=2 + +# Enable CRDA regulatory support by settings default country code +#gCrdaDefaultCountryCode=TW + +# Scan Timing Parameters +# gPassiveMaxChannelTime=110 +# gPassiveMinChannelTime=60 +# gActiveMaxChannelTime=40 +# gActiveMinChannelTime=20 + +#If set to 0, MCC is not allowed. +gEnableMCCMode=1 + +# 1=enable STBC; 0=disable STBC +gEnableRXSTBC=1 + +# Enable Active mode offload +gEnableActiveModeOffload=1 + +#Enable Scan Results Aging based on timer +#Timer value is in seconds +#If Set to 0 it will not enable the feature +gScanAgingTime=0 + +#Enable Power saving mechanism Based on Android Framework +#If set to 0 Driver internally control the Power saving mechanism +#If set to 1 Android Framwrok control the Power saving mechanism +isAndroidPsEn=0 + +#disable LDPC in STA mode if the AP is TXBF capable +gDisableLDPCWithTxbfAP=1 + +#Enable thermal mitigation +gThermalMitigationEnable=1 + +gEnableFastRoamInConcurrency=1 + +#List of Country codes for which 11ac needs to be disabled +#Each country code must be delimited by comma(,) +gListOfNon11acCountryCode=RU,UA,ZA + +#Maxium Channel time in msec +gMaxMediumTime = 5480 + +# 802.11K support +gRrmEnable=1 +gRrmOperChanMax=8 +gRrmNonOperChanMax=8 +gRrmRandIntvl=100 + +#Scan offload +gEnableDirectedScanOffload=0 + +#FlexConnect Power Factor +#Default is set to 0 (disable) +gFlexConnectPowerFactor=0 + +#SAP/P2P-GO mode traffic monitor +gEnableTrafficMonitor=1 +gTrafficIdleTimeout=3000 + +#Disable/Enable Strict FCC Regulatory +# 0 to disable, 1 to enable +gEnableStrictRegulatoryForFCC=1 + +#Enable/Disable Modulated DTIM feature +gEnableModulatedDTIM=3 + +#max LI value for modulated DTIM +gMaxLIModulatedDTIM=3 + +#Enable/Disable Link Layer Statistics Feature +gEnableLLStats=1 + +#Enable/Disable EXTScan Feature +gEnableEXTScan=1 + +#Enable/Disable TDLS Feature +gEnableTDLSSupport=1 + +#Enable/Disable TDLS Implicit Trigger +gEnableTDLSImplicitTrigger=0 + +#Enable/Disable TDLS Buffer Sta +gEnableTDLSBufferSta=1 + +#Enable/Disable RTS-CTS for HT,VHT +#Bit mask value to enable RTS/CTS for different modes +#For 2.4 GHz, HT20 - 0x0001 i.e 1, for 2.4 GHz, HT40 - 0x0002 i.e 2 +#For 2.4 GHz, VHT20 - 0x0004 i.e 4, for 2.4 GHz, VHT40 - 0x0008 i.e 8 +#For 5 GHz, HT20 - 0x0100 i.e 256, for 5 GHz, HT40 - 0x0200 i.e 512 +#For 5 GHz, VHT20 - 0x0400 i.e 1024, for 5 GHz, VHT40 - 0x0800 i.e 2048 +#For 5 GHz, VHT80 - 0x1000 i.e 4096 +#Can be enabled for multiple modes +#For enabling in both HT20 and HT40 of 2.4 GHz - 0x0003 i.e 3 +#Default is set to 0 (disable) +gEnableRtsCtsHtVht=0 + +#Enable delACK +gEnableDelAck=1 + +#Compute interval for delack +gTcpDelAckComputeInterval=2000 + +#Delack set higher limit +gTcpDelAckThresholdHigh=17000 + +#Delack set lower limit +gTcpDelAckThresholdLow=12000 + +# Enable or Disable DHCP Server offload +# 1=Enable, 0=Disable (default) +gDHCPServerOffloadEnable=0 + +# Set max number of DHCP Clients +# Its value could not be greater than 2(default) +#gDHCPMaxNumClients=2 + +# Set DHCP server IP +# 4th field could not be greater than 99, that is xxx.xxx.xxx.0 ~ xxx.xxx.xxx.99 +# 1st field could not be within the range of 224 ~ 239 (multicast IP address) +# 192.168.1.2(default) +#gDHCPServerIP=192.168.1.2 + +# Set DHCP pool start Lsb +# min 100 (default) +# max 255 +gDHCPStartLsb=100 + +# mDNS enable +gMDNSOffloadEnable=1 +# mDNS FQDN query +gMDNSFqdn="_GoProRemote._tcp.local" +# mDNS UFQDN query +gMDNSUniqueFqdn="service._GoProRemote._tcp.local" +# mDNS response typeA +gMDNSResponseTypeA="goprobp-D89685121212.local" +# mDNS response typeAIpv4Addr +gMDNSResponseTypeAIpv4Addr=0xc0a80102 +# mDNS response typeTXT +gMDNSResponseTypeTXT="GoProBP-D89685121212._GoProRemote._tcp.local" +# mDNS response typeTXTContent +gMDNSResponseTypeTXTContent="Device=HERO 3+-BAWA Model=BAWA Version=HD3.11.02.00 Wifi Version=4.0.36.0 Protocol Version=2" +# mDNS response typePTR +gMDNSResponseTypePTR="_GoProRemote._tcp.local" +# mDNS response typePTRDomainName +gMDNSResponseTypePTRDomainName="GoProBP-D89685121212._GoProRemote._tcp.local" +# mDNS response typeSRV +gMDNSResponseTypeSRV="GoProBP-D89685121212._GoProRemote._tcp.local" +# mDNS response typeSRVTarget +gMDNSResponseTypeSRVTarget="goprobp-D89685121212.local" +# mDNS response typeSRVPriority +gMDNSResponseTypeSRVPriority=0 +# mDNS response typeSRVWeight +gMDNSResponseTypeSRVWeight=0 + +END + +# Note: Configuration parser would not read anything past the END marker + diff --git a/drivers/staging/prima/riva/inc/halCompiler.h b/drivers/staging/prima/riva/inc/halCompiler.h new file mode 100644 index 000000000000..2c4762d3139a --- /dev/null +++ b/drivers/staging/prima/riva/inc/halCompiler.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*========================================================================== + * + * @file: aniCompiler.h + * + * @brief: This file tries to abstract the differences among compilers. + * Supported compilers are: + * ARM RVCT compiler + * + * @author: Kumar Anand + * + * + *=========================================================================*/ +#ifndef __ANI_COMPILER_ABSTRACT_H +#define __ANI_COMPILER_ABSTRACT_H + +/* + * 1. GNU C/C++ Compiler + * + * How to detect gcc : __GNUC__ + * How to detect gcc version : + * major version : __GNUC__ (2 = 2.x, 3 = 3.x, 4 = 4.x) + * minor version : __GNUC_MINOR__ + * + * 2. Microsoft C/C++ Compiler + * + * How to detect msc : _MSC_VER + * How to detect msc version : + * _MSC_VER (1200 = MSVC 6.0, 1300 = MSVC 7.0, ...) + * + * 3. Intel C/C++ Compiler + * + * How to detect icc : __INTEL_COMPILER, __ICC (legacy), __ECC (legacy) + * How to detect icc version : + * __INTEL_COMPILER, __ICC, __ECC (700 = 7.0, 900 = 9.0, ...) + * + * 4. Other compilers (not supported) + * + * Borland : __BORLANDC__ + * Greenhills : __ghs + * Metrowerks : __MWERKS__ + * SGI MIPSpro : __sgi + */ + +/* + * Packing directives : These are used to force compiler to pack bits and + * bytes in the data structure. C standard does not regulate this strictly, + * and many things are to compiler implementation. Many compilers support + * compiler specific directives or options that allow different packing + * and alignment. + * + * Alignment directives : Compiler may think packed data structures have + * no specific alignment requirement. Then compiler may generate multiple + * byte accesses to access two byte or four bytes data structures. This + * affects on performance especially for RISC systems. If some data + * structure is located on specific alignment always, alignment directives + * help compiler generate more efficient codes. + */ + +#undef __ANI_COMPILER_PRAGMA_PACK_STACK +#undef __ANI_COMPILER_PRAGMA_PACK + +#if defined(_MSC_VER) +#define __ANI_COMPILER_PRAGMA_PACK_STACK 1 +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#define PACKED +#define PACKED_POST +#define ALIGN(__value) +#elif defined(__INTEL_COMPILER) || defined(__ICC) || defined(__ECC) +#define __ANI_COMPILER_PRAGMA_PACK 1 +#define __ani_attr_pre_packed +#define __ani_attr_packed +#define __ani_attr_aligned_2 +#define __ani_attr_aligned_4 +#define __ani_attr_aligned_8 +#define __ani_attr_aligned_16 +#define __ani_attr_aligned_32 +#define PACKED +#define PACKED_POST +#define ALIGN(__value) +#elif defined(__GNUC__) +#define __ani_attr_pre_packed +#define __ani_attr_packed __attribute__((packed)) +#define __ani_attr_aligned_2 __attribute__((aligned(2))) +#define __ani_attr_aligned_4 __attribute__((aligned(4))) +#define __ani_attr_aligned_8 __attribute__((aligned(8))) +#define __ani_attr_aligned_16 __attribute__((aligned(16))) +#define __ani_attr_aligned_32 __attribute__((aligned(32))) +#ifndef PACKED +#define PACKED +#endif +#ifndef PACKED_POST +#define PACKED_POST __attribute__((packed)) +#endif +#ifndef ALIGN +#define ALIGN(__value) __attribute__((aligned(__value))) +#endif +#elif defined(ANI_COMPILER_TYPE_RVCT) +/* Nothing defined so far */ + +/* + * RIVA 1.2 and Pronto uses ARMCT5.1 compiler and it throws lot of warning when __align() is used in structure definitions. + * __attribute__((aligned())) is GNU compiler attribute that is accepted by ARM compiler and resolves the warnings. + */ +#if (__ARMCC_VERSION > 400000) +#define __ani_attr_packed +#define __ani_attr_pre_packed __packed +#define __ani_attr_aligned_2 __attribute__((aligned(2))) +#define __ani_attr_aligned_4 __attribute__((aligned(4))) +#define __ani_attr_aligned_8 __attribute__((aligned(8))) +#define __ani_attr_aligned_16 __attribute__((aligned(16))) +#define __ani_attr_aligned_32 __attribute__((aligned(32))) +#define PACKED __packed +#define PACKED_POST +#define ALIGN(__value) __align(__value) +#define PREPACK __packed +#define POSTPACK +#else +#define __ani_attr_packed +#define __ani_attr_pre_packed __packed +#define __ani_attr_aligned_2 __align(2) +#define __ani_attr_aligned_4 __align(4) +#define __ani_attr_aligned_8 __align(8) +#define __ani_attr_aligned_16 __align(16) +#define __ani_attr_aligned_32 __align(32) +#define PACKED __packed +#define PACKED_POST +#define ALIGN(__value) __align(__value) +#endif + +#else +#error "Unknown compiler" +#endif + +#ifndef PACKED_PRE +#define PACKED_PRE __ani_attr_pre_packed +#endif + +#ifndef ALIGN_4 +#define ALIGN_4 __ani_attr_aligned_4 +#endif + +#endif //__ANI_COMPILER_ABSTRACT_H + diff --git a/drivers/staging/prima/riva/inc/halLegacyPalTypes.h b/drivers/staging/prima/riva/inc/halLegacyPalTypes.h new file mode 100644 index 000000000000..75808b6bf9d6 --- /dev/null +++ b/drivers/staging/prima/riva/inc/halLegacyPalTypes.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2012-2013, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#if !defined( __LEGACYPALTYPES_H__ ) +#define __LEGACYPALTYPES_H__ + +/*========================================================================== + * + * @file: halLegacyPalTypes.h + * + * @brief: Exports and types for the Platform Abstraction Layer typedefs. + * + * @author: Kumar Anand + * + * + *=========================================================================*/ + +#include "qwlanfw_defs.h" + +/* Common type definitions */ +typedef uint8 tANI_U8; +typedef int8 tANI_S8; +typedef uint16 tANI_U16; +typedef int16 tANI_S16; +typedef uint32 tANI_U32; +typedef int32 tANI_S32; + +#ifndef BUILD_QWPTTSTATIC +typedef uint64 tANI_U64; +#endif + +typedef byte tANI_BYTE; +typedef boolean tANI_BOOLEAN; +typedef unsigned long tANI_TIMESTAMP; + +#endif /*__LEGACYPALTYPES_H__*/ diff --git a/drivers/staging/prima/riva/inc/pttFrameGen.h b/drivers/staging/prima/riva/inc/pttFrameGen.h new file mode 100644 index 000000000000..ed6ab8d3eec9 --- /dev/null +++ b/drivers/staging/prima/riva/inc/pttFrameGen.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file pttFrameGen.h + + \brief Definitions for PTT frame generation + + $Id$ + + + ========================================================================== */ + +#ifndef PTTFRAMEGEN_H +#define PTTFRAMEGEN_H + + +//#define MAX_PKT_GEN_BUF_ENTRY (HAL_HIF_MAX_TX_RING_ENTRY >> 1) + + + +#define MAX_PAYLOAD_SIZE 2400 +#define MAX_TX_PAYLOAD_SIZE 4096 + +typedef enum { + TEST_PAYLOAD_NONE, + TEST_PAYLOAD_FILL_BYTE, + TEST_PAYLOAD_RANDOM, + TEST_PAYLOAD_RAMP, + TEST_PAYLOAD_TEMPLATE, + TEST_PAYLOAD_MAX = 0X3FFFFFFF, //dummy value to set enum to 4 bytes +} ePayloadContents; + + +#define MAC_ADDR_SIZE ( 6 ) + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 numTestPackets; + tANI_U32 interFrameSpace; + eHalPhyRates rate; + ePayloadContents payloadContents; + tANI_U16 payloadLength; + tANI_U8 payloadFillByte; + tANI_BOOLEAN pktAutoSeqNum; //seq num setting (hw or not) for packet gen + + tANI_U8 addr1[MAC_ADDR_SIZE]; + tANI_U8 addr2[MAC_ADDR_SIZE]; + tANI_U8 addr3[MAC_ADDR_SIZE]; + tANI_U8 tx_mode; + tANI_BOOLEAN crc; //0 = no FCS calculated = power detector works = receive won't work?, + //1 = crc calculated = receive works, but power detector workaround doesn't + + ePhyDbgPreamble preamble; +} sPttFrameGenParams; + + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 legacy; //11g OFDM preamble + tANI_U32 gfSimo20; //greenfield preamble + tANI_U32 mmSimo20; //mixed mode preamble + tANI_U32 gfSimo40; //greenfield preamble + tANI_U32 mmSimo40; //mixed mode preamble + tANI_U32 txbShort; //11b short + tANI_U32 txbLong; //11b long + tANI_U32 acSimo204080; //11ac SIMO 20,40,80 + tANI_U32 total; +} sTxFrameCounters; + +#endif diff --git a/drivers/staging/prima/riva/inc/pttModule.h b/drivers/staging/prima/riva/inc/pttModule.h new file mode 100644 index 000000000000..7f9cce0462b5 --- /dev/null +++ b/drivers/staging/prima/riva/inc/pttModule.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + + + pttModule.h: global variable structure for pttModule + Author: Mark Nelson + Date: 6/27/05 + + History - + Date Modified by Modification Information + -------------------------------------------------------------------------- + + */ + +#ifndef PTTMODULE_H +#define PTTMODULE_H +#include +#include + +#ifdef BUILD_QWPTTSTATIC +#include "wlan_hal_msg.h" // it is needed to build qwptt static lib +#endif + +// Max NV fragment size +#define MAX_NV_BIN_SIZE 2000 + +enum +{ + PTT_STATUS_SUCCESS = 0, + PTT_STATUS_FAILURE = 1, + PTT_MAX_VAL = 0XFFFF, +}; +typedef tANI_U32 eQWPttStatus; + + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 drvMjr; + tANI_U16 drvMnr; + tANI_U16 drvPtch; + tANI_U16 drvBld; + tANI_U16 pttMax; + tANI_U16 pttMin; + //FwVersionInfo fwVer; +} sBuildReleaseParams; + +typedef PACKED_PRE struct PACKED_POST { + tANI_BOOLEAN agPktsDisabled; //802.11ag + tANI_BOOLEAN bPktsDisabled; //802.11b + tANI_BOOLEAN slrPktsDisabled; //deprecated in Riva + tANI_BOOLEAN n40PktsDisabled; //11N 40 + tANI_BOOLEAN ac80PktsDisabled; //11AC 80 + tANI_BOOLEAN rsvd; +} sRxTypesDisabled; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 totalRxPackets; + tANI_U32 totalMacRxPackets; + tANI_U32 totalMacFcsErrPackets; +} sRxFrameCounters; + + + + +/* GRAB RAM types */ +//TODO: Change Grab RAM interface as appropriate to Taurus +typedef enum { + GRAB_RAM_RXFIR, + GRAB_RAM_ADC, + GRAB_RAM_ADC_80, + GRAB_RAM_MAX_VAL = 0XFFFF, +} eGrabRamType; + +#define GRAB_RAM_SIZE 6000 +#define GRAB_RAM_SIZE_80MHZ_1_CHAIN 12000 + + + +/// Enum used to specify the trigger type for the aniGrabRam API +typedef enum eGramDumpTrigType { + eGRAM_DUMP_UNTRIGGERED, + eGRAM_DUMP_TRIG_ON_11A, + eGRAM_DUMP_TRIG_ON_11B, + eGRAM_DUMP_TRIG_ON_11A_OR_11B +} tGramDumpTrigType; + +typedef PACKED_PRE struct PACKED_POST { + //common to both transmit chains + eHalPhyRates rate; //current rate + ePhyChanBondState cbState; //current Channel bonded state + + tANI_U8 channelId; //current channel Id + tANI_U8 pwrTemplateIndex; //5-bit template index used for the current rate + tANI_U8 reserved[2]; + + //specific transmit chain power + tTxChainPower txChains[PHY_MAX_TX_CHAINS]; //output power for Tx chains +} tTxPowerReport; + +#define RXP_MAX_FILTER_IDX 64 + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 rxpFilterForFTMPER[RXP_MAX_FILTER_IDX]; + uint32 max_pktlen; + uint32 flt_disable0; + uint32 flt_disable1; + uint32 config2; + uint32 push_wq_ctrl; + uint32 push_wq_ctrl2; + uint32 extra_frame_flt; +} sMACConfig; + + +typedef PACKED_PRE struct PACKED_POST { + /* + * The idea here is to store only those things which cannot be + * handled directly within the individual function calls. + * Most things will go straight to registers or come from registers. + */ + sPttFrameGenParams frameGenParams; + tANI_U8 payload[MAX_PAYLOAD_SIZE]; + + //Tx Waveform Gen Service + tANI_U16 numWfmSamples; + tANI_BOOLEAN wfmEnabled; + tANI_BOOLEAN wfmStored; + + //Tx Frame Power Service + tTxGain forcedTxGain[PHY_MAX_TX_CHAINS]; //use TXPWR_OVERRIDE for wfm, and fill gain table otherwise + tANI_U8 tpcPowerLut[PHY_MAX_TX_CHAINS][TPC_MEM_POWER_LUT_DEPTH]; + tTxGain tpcGainLut[PHY_MAX_TX_CHAINS][TPC_MEM_GAIN_LUT_DEPTH]; + + //Tx Frame Gen Service + tANI_BOOLEAN frameGenEnabled; + tANI_BOOLEAN phyDbgFrameGen; //this says use phyDbg for frames - leave this in place until we know that PhyDbg will suffice + + // for FTM PER feature + tANI_U8 tx_mode; + + tANI_BOOLEAN ftm_per_settings_saved; + + //Rx Gain Service + sRxChainsAgcEnable agcEnables; + + tANI_U32 *pADCCaptureCache; //pointer to allocate ADC capture cache + + //TX_TIMER adcRssiStatsTimer; //Create adc rssi stat collection timer + + sRxChainsRssi rssi; +} tPttModuleVariables; + +#ifdef WCN_PRONTO +extern sMACConfig macConfig; +#endif + +#endif /* PTTMODULE_H */ diff --git a/drivers/staging/prima/riva/inc/pttMsgApi.h b/drivers/staging/prima/riva/inc/pttMsgApi.h new file mode 100644 index 000000000000..21669808c453 --- /dev/null +++ b/drivers/staging/prima/riva/inc/pttMsgApi.h @@ -0,0 +1,964 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + + + pttMsgApi.h: Contains messages to PTT Module for physical layer testing + Author: Mark Nelson + Date: 6/21/05 + + History - + Date Modified by Modification Information + -------------------------------------------------------------------------- + + */ + +#ifndef PTT_MSG_API_H +#define PTT_MSG_API_H + +#include "halCompiler.h" +#include "wlan_nv.h" +#include "wlan_phy.h" +#include "pttFrameGen.h" +#include "pttModule.h" + +#include "halLegacyPalTypes.h" + +typedef tANI_U8 tQWPTT_U8; +typedef tANI_S8 tQWPTT_S8; + +typedef tANI_U16 tQWPTT_U16; +typedef tANI_S16 tQWPTT_S16; + +typedef tANI_U32 tQWPTT_U32; +typedef tANI_S32 tQWPTT_S32; + +typedef tANI_U8 tQWPTT_BYTE; +typedef tANI_S9 tQWPTT_S9; + +typedef tANI_U8 tQWPTT_BOOLEAN; + +#define PTT_MEM_ACCESS_MAX_SIZE 256 + +//Messages to/from socket or pttApi.c +typedef enum { + PTT_MSG_TYPES_BEGIN = 0x3000, + + // Init + PTT_MSG_INIT = PTT_MSG_TYPES_BEGIN, //extra: internal only + +//NV Service + PTT_MSG_GET_TPC_CAL_STATE_OBSOLETE = 0x3011, + PTT_MSG_RESET_TPC_CAL_STATE_OBSOLETE = 0x3012, + + PTT_MSG_SET_NV_CKSUM_OBSOLETE = 0x3013, + PTT_MSG_GET_NV_CKSUM_OBSOLETE = 0x3014, + PTT_MSG_GET_NV_TABLE = 0x3016, + PTT_MSG_SET_NV_TABLE = 0x3017, + PTT_MSG_SET_NV_IMAGE_OBSOLETE = 0x3018, + PTT_MSG_BLANK_NV = 0x3019, + PTT_MSG_GET_NV_IMAGE_OBSOLETE = 0x301E, + PTT_MSG_DEL_NV_TABLE = 0x301F, + PTT_MSG_GET_NV_FIELD = 0x3020, + PTT_MSG_SET_NV_FIELD = 0x3021, + PTT_MSG_STORE_NV_TABLE = 0x3022, + PTT_MSG_SET_REG_DOMAIN = 0x3023, + +//new NV format Service + PTT_MSG_GET_NV_BIN = 0x3030, + PTT_MSG_SET_NV_BIN = 0x3031, + PTT_MSG_GET_DICTIONARY = 0x3032, + +//Device Register Access + PTT_MSG_DBG_READ_REGISTER = 0x3040, + PTT_MSG_DBG_WRITE_REGISTER = 0x3041, + PTT_MSG_API_WRITE_REGISTER_OBSOLETE = 0x3042, + PTT_MSG_API_READ_REGISTER_OBSOLETE = 0x3043, + PTT_MSG_DBG_READ_MEMORY = 0x3044, + PTT_MSG_DBG_WRITE_MEMORY = 0x3045, + +//Device MAC Test Setup + PTT_MSG_ENABLE_CHAINS = 0x304F, + PTT_MSG_SET_CHANNEL = 0x3050, + +//Tx Waveform Gen Service + PTT_MSG_SET_WAVEFORM = 0x3071, + PTT_MSG_SET_TX_WAVEFORM_GAIN = 0x3072, + PTT_MSG_GET_WAVEFORM_POWER_ADC = 0x3073, + PTT_MSG_START_WAVEFORM = 0x3074, + PTT_MSG_STOP_WAVEFORM = 0x3075, + PTT_MSG_SET_RX_WAVEFORM_GAIN = 0x3076, + PTT_MSG_SET_TX_WAVEFORM_GAIN_PRIMA_V1 = 0x3077, + +//Tx Frame Gen Service + PTT_MSG_CONFIG_TX_PACKET_GEN = 0x3081, + PTT_MSG_START_STOP_TX_PACKET_GEN = 0x3082, + PTT_MSG_POLL_TX_PACKET_PROGRESS_OBSOLETE = 0x3083, + PTT_MSG_FRAME_GEN_STOP_IND_OBSOLETE = 0x3088, + PTT_MSG_QUERY_TX_STATUS = 0x3089, + + +//Tx Frame Power Service + PTT_MSG_CLOSE_TPC_LOOP = 0x30A0, + +//open loop service + PTT_MSG_SET_PACKET_TX_GAIN_TABLE = 0x30A1, + PTT_MSG_SET_PACKET_TX_GAIN_INDEX = 0x30A2, + PTT_MSG_FORCE_PACKET_TX_GAIN = 0x30A3, + +//closed loop(CLPC) service + PTT_MSG_SET_PWR_INDEX_SOURCE = 0x30A4, + PTT_MSG_SET_TX_POWER = 0x30A5, + PTT_MSG_GET_TX_POWER_REPORT = 0x30A7, + PTT_MSG_SAVE_TX_PWR_CAL_TABLE_OBSOLETE = 0x30A8, + PTT_MSG_SET_POWER_LUT = 0x30A9, + PTT_MSG_GET_POWER_LUT = 0x30AA, + PTT_MSG_GET_PACKET_TX_GAIN_TABLE = 0x30AB, + PTT_MSG_SAVE_TX_PWR_FREQ_TABLE_OBSOLETE = 0x30AC, + PTT_MSG_CLPC_TEMP_COMPENSATION_OBSOLETE = 0x30AD, + +//Rx Gain Service + PTT_MSG_DISABLE_AGC_TABLES = 0x30D0, + PTT_MSG_ENABLE_AGC_TABLES = 0x30D1, + PTT_MSG_SET_AGC_TABLES_OBSOLETE = 0x30D2, + PTT_MSG_GET_RX_RSSI = 0x30D3, + PTT_MSG_GET_AGC_TABLE_OBSOLETE = 0x30D5, + +//Rx Frame Catcher Service + PTT_MSG_SET_RX_DISABLE_MODE = 0x30D4, + PTT_MSG_GET_RX_PKT_COUNTS = 0x30E0, + PTT_MSG_RESET_RX_PACKET_STATISTICS = 0x30E2, + PTT_MSG_GET_UNI_CAST_MAC_PKT_RX_RSSI = 0x30E3, + PTT_MSG_GET_UNI_CAST_MAC_PKT_RX_RSSI_CONFIG = 0x30E4, + +//Rx Symbol Service + PTT_MSG_GRAB_RAM = 0x30F0, + PTT_MSG_GRAB_RAM_ONE_CHAIN_OBSOLETE = 0x30F1, + +//Phy Calibration Service + PTT_MSG_RX_IQ_CAL = 0x3100, + PTT_MSG_RX_DCO_CAL = 0x3101, + PTT_MSG_TX_CARRIER_SUPPRESS_CAL = 0x3102, + PTT_MSG_TX_IQ_CAL = 0x3103, + PTT_MSG_EXECUTE_INITIAL_CALS = 0x3104, + PTT_MSG_HDET_CAL = 0x3105, + PTT_MSG_VCO_LINEARITY_CAL_OBSOLETE = 0x3106, + +//Phy Calibration Override Service + PTT_MSG_SET_TX_CARRIER_SUPPRESS_CORRECT = 0x3110, + PTT_MSG_GET_TX_CARRIER_SUPPRESS_CORRECT = 0x3111, + PTT_MSG_SET_TX_IQ_CORRECT = 0x3112, + PTT_MSG_GET_TX_IQ_CORRECT = 0x3113, + PTT_MSG_SET_RX_IQ_CORRECT = 0x3114, + PTT_MSG_GET_RX_IQ_CORRECT = 0x3115, + PTT_MSG_SET_RX_DCO_CORRECT = 0x3116, + PTT_MSG_GET_RX_DCO_CORRECT = 0x3117, + PTT_MSG_SET_TX_IQ_PHASE_NV_TABLE_OBSOLETE = 0x3118, + PTT_MSG_GET_HDET_CORRECT_OBSOLETE = 0x3119, + +//RF Chip Access + PTT_MSG_GET_TEMP_ADC = 0x3202, + PTT_MSG_READ_RF_REG = 0x3203, + PTT_MSG_WRITE_RF_REG = 0x3204, + PTT_MSG_GET_RF_VERSION = 0x3205, + +//Deep sleep support + PTT_MSG_DEEP_SLEEP = 0x3220, + PTT_MSG_READ_SIF_BAR4_REGISTER = 0x3221, + PTT_MSG_WRITE_SIF_BAR4_REGISTER = 0x3222, + PTT_MSG_ENTER_FULL_POWER = 0x3223, + +//Misc + PTT_MSG_SYSTEM_RESET = 0x32A0, //is there any meaning for this in Gen6? + PTT_MSG_LOG_DUMP = 0x32A1, + PTT_MSG_GET_BUILD_RELEASE_NUMBER = 0x32A2, + + +//Messages for Socket App + PTT_MSG_ADAPTER_DISABLED_RSP_OBSOLETE = 0x32A3, + PTT_MSG_ENABLE_ADAPTER = 0x32A4, + PTT_MSG_DISABLE_ADAPTER = 0x32A5, + PTT_MSG_PAUSE_RSP_OBSOLETE = 0x32A6, + PTT_MSG_CONTINUE_RSP_OBSOLETE = 0x32A7, + + PTT_MSG_HALPHY_INIT = 0x32A8, + PTT_MSG_TEST_RXIQ_CAL = 0x32A9, + PTT_MSG_START_TONE_GEN = 0x32AA, + PTT_MSG_STOP_TONE_GEN = 0x32AB, + PTT_MSG_RX_IM2_CAL = 0x32AC, + PTT_MSG_SET_RX_IM2_CORRECT = 0x31AD, + PTT_MSG_GET_RX_IM2_CORRECT = 0x31AE, + PTT_MSG_TEST_DPD_CAL = 0x32AF, // not handle + PTT_MSG_SET_CALCONTROL_BITMAP = 0x32B0, + +//[RY] specific new messages for PRIMA + PTT_MSG_START_WAVEFORM_RF = 0x32B1, + PTT_MSG_STOP_WAVEFORM_RF = 0x32B2, + PTT_MSG_HKDAC_TX_IQ_CAL = 0x32B3, + PTT_MSG_SET_HKADC_TX_IQ_CORRECT = 0x32B4, + PTT_MSG_GET_HKADC_TX_IQ_CORRECT = 0x32B5, + PTT_MSG_SET_DPD_CORRECT = 0x32B6, + PTT_MSG_GET_DPD_CORRECT = 0x32B7, + PTT_MSG_SET_WAVEFORM_RF = 0x32B8, + PTT_MSG_LNA_BAND_CAL = 0x32B9, + PTT_MSG_GET_LNA_BAND_CORRECT = 0x32BA, + PTT_MSG_SET_LNA_BAND_CORRECT = 0x32BB, + PTT_MSG_DPD_CAL = 0x32BC, + +// Suffix'ed Message ID to differential from existing Message name. +// =============================================================== + PTT_MSG_GET_NV_TABLE_PRIMA_V1 = 0x32BD, + PTT_MSG_SET_NV_TABLE_PRIMA_V1 = 0x32BE, + PTT_MSG_RX_IQ_CAL_PRIMA_V1 = 0x32BF, + PTT_MSG_TX_IQ_CAL_PRIMA_V1 = 0x32C0, + PTT_MSG_SET_TX_IQ_CORRECT_PRIMA_V1 = 0x32C1, + PTT_MSG_GET_TX_IQ_CORRECT_PRIMA_V1 = 0x32C2, + PTT_MSG_SET_RX_IQ_CORRECT_PRIMA_V1 = 0x32C3, + PTT_MSG_GET_RX_IQ_CORRECT_PRIMA_V1 = 0x32C4, + PTT_MSG_START_WAVEFORM_PRIMA_V1 = 0x32C5, + PTT_MSG_FORCE_PACKET_TX_GAIN_PRIMA_V1 = 0x32C6, + PTT_MSG_CLPC_CAL_SETUP_PRIMA_V1 = 0x32C7, + PTT_MSG_CLPC_CAL_RESTORE_PRIMA_V1 = 0x32C8, + PTT_MSG_CLOSE_TPC_LOOP_PRIMA_V1 = 0x32C9, + PTT_MSG_SW_CLPC_CAL_PRIMA_V1 = 0x32CA, + PTT_MSG_CLPC_CAL_EXTRA_MEASUREMENT_PRIMA_V1 = 0x32CB, + PTT_MSG_PRIMA_GENERIC_CMD = 0x32CC, + PTT_MSG_DIGITAL_PIN_CONNECTIVITY_TEST_RES = 0X32CD, + + PTT_MSG_EXIT = 0x32ff, + PTT_MAX_MSG_ID = PTT_MSG_EXIT +} ePttMsgId; + +enum +{ + PTT_MSG_PRIMA_GENERIC_CMD_FAST_SET_CHANNEL = 0x0, +}; + +#define PTT_MSG_TYPES_BEGIN_30 PTT_MSG_TYPES_BEGIN +#define PTT_MSG_TYPES_BEGIN_31 PTT_MSG_TYPES_BEGIN + 0x100 +#define PTT_MSG_TYPES_BEGIN_32 PTT_MSG_TYPES_BEGIN + 0x200 + +// for FTM PER feature +enum { +Legacy_FTM = 0, +FTM_PER_TX = 1, +FTM_PER_RX = 2, +}; + +#ifndef tANI_BOOLEAN +#define tANI_BOOLEAN tANI_U8 +#endif + + + +/****************************************************************************************************************** + PTT MESSAGES +******************************************************************************************************************/ +//Init +typedef PACKED_PRE struct PACKED_POST { + tPttModuleVariables ptt; +} tMsgPttMsgInit; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 tableSize; + tANI_U32 chunkSize; + eNvTable nvTable; +} tMsgPttGetNvTable; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 tableSize; + tANI_U32 chunkSize; + eNvTable nvTable; +} tMsgPttSetNvTable; + +typedef PACKED_PRE struct PACKED_POST { + eNvTable nvTable; +} tMsgPttDelNvTable; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttBlankNv; + +typedef PACKED_PRE struct PACKED_POST { + eNvField nvField; + uNvFields fieldData; +} tMsgPttGetNvField; + +typedef PACKED_PRE struct PACKED_POST { + eNvField nvField; + uNvFields fieldData; +} tMsgPttSetNvField; + +typedef PACKED_PRE struct PACKED_POST { + eNvTable nvTable; +} tMsgPttStoreNvTable; + +typedef PACKED_PRE struct PACKED_POST { + eRegDomainId regDomainId; +} tMsgPttSetRegDomain; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 tableSize; + tANI_U32 chunkSize; + eNvTable nvTable; + tANI_U8 nvData[MAX_NV_BIN_SIZE]; +} tMsgPttGetNvBin; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 tableSize; + tANI_U32 chunkSize; + eNvTable nvTable; + tANI_U8 nvData[MAX_NV_BIN_SIZE]; +} tMsgPttSetNvBin; + +//Device Register Access +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 regAddr; + tANI_U32 regValue; +} tMsgPttDbgReadRegister; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 regAddr; + tANI_U32 regValue; +} tMsgPttDbgWriteRegister; + +#define PTT_READ_MEM_MAX 512 +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 memAddr; + tANI_U32 nBytes; + tANI_U32 pMemBuf[PTT_READ_MEM_MAX]; //caller should allocate space +} tMsgPttDbgReadMemory; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 memAddr; + tANI_U32 nBytes; + tANI_U32 pMemBuf[PTT_READ_MEM_MAX]; +} tMsgPttDbgWriteMemory; + +//Device MAC Test Setup +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 chId; + ePhyChanBondState cbState; +} tMsgPttSetChannel; + +typedef PACKED_PRE struct PACKED_POST { + ePhyChainSelect chainSelect; +} tMsgPttEnableChains; + +typedef tIQSamples tWaveformSample; + +//Tx Waveform Gen Service +typedef PACKED_PRE struct PACKED_POST { + tWaveformSample waveform[MAX_TEST_WAVEFORM_SAMPLES]; + tANI_U16 numSamples; + tANI_BOOLEAN clk80; + tANI_U8 reserved[1]; +} tMsgPttSetWaveform; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + tANI_U8 gain; +} tMsgPttSetTxWaveformGain; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + tANI_U32 gain; +} tMsgPttSetTxWaveformGain_PRIMA_V1; + +typedef PACKED_PRE struct PACKED_POST { + ePhyRxChains rxChain; + tANI_U8 gain; +} tMsgPttSetRxWaveformGain; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsPowerAdcReadings txPowerAdc; +} tMsgPttGetWaveformPowerAdc; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttStopWaveform; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttClpcCalSetup_PRIMA_V1; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 setup_measure; + tANI_U16 setup_txDmdPwrOffset; + tANI_U16 measure_totalExtraPt; + tANI_U16 measure_currentMeasurePtIdx; + tANI_U8 plut[256]; +} tMsgPttClpcCalExtraMeasurement_PRIMA_V1; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttClpcCalRestore_PRIMA_V1; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 startIndex; + tANI_U32 numSamples; +} tMsgPttStartWaveform; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 startIndex; + tANI_U32 numSamples; +} tMsgPttStartWaveform_PRIMA_V1; + +// Added for PRIMA +typedef PACKED_PRE struct PACKED_POST { + tWaveformSample waveform[MAX_TEST_WAVEFORM_SAMPLES]; + tANI_U16 numSamples; + tANI_BOOLEAN clk80; + tANI_U8 reserved[1]; +} tMsgPttSetWaveformRF; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 startIndex; + tANI_U32 numSamples; +} tMsgPttStartWaveformRF; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttStopWaveformRF; + +//Tx Frame Gen Service +typedef PACKED_PRE struct PACKED_POST { + sPttFrameGenParams frameParams; +} tMsgPttConfigTxPacketGen; + +typedef PACKED_PRE struct PACKED_POST { + tANI_BOOLEAN startStop; + tANI_U8 reserved[3]; +} tMsgPttStartStopTxPacketGen; + +typedef PACKED_PRE struct PACKED_POST { + sTxFrameCounters numFrames; + tANI_BOOLEAN status; + tANI_U8 reserved[3]; +} tMsgPttQueryTxStatus; + +//Tx Frame Power Service +typedef PACKED_PRE struct PACKED_POST { + tANI_BOOLEAN tpcClose; + tANI_U8 reserved[3]; +} tMsgPttCloseTpcLoop; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 tpcClose; +} tMsgPttCloseTpcLoop_PRIMA_V1; + + + //open loop service +typedef PACKED_PRE struct PACKED_POST { + + ePhyTxChains txChain; + tANI_U8 minIndex; + tANI_U8 maxIndex; + tANI_U8 reserved[2]; + tANI_U8 gainTable[TPC_MEM_GAIN_LUT_DEPTH]; +} tMsgPttSetPacketTxGainTable; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + tANI_U8 gainTable[TPC_MEM_GAIN_LUT_DEPTH]; +} tMsgPttGetPacketTxGainTable; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 index; + tANI_U8 reserved[3]; +} tMsgPttSetPacketTxGainIndex; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + tANI_U8 gain; + tANI_U8 reserved[3]; +} tMsgPttForcePacketTxGain; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + tANI_U32 gain; +} tMsgPttForcePacketTxGain_PRIMA_V1; + + +typedef PACKED_PRE struct PACKED_POST { + ePowerTempIndexSource indexSource; +} tMsgPttSetPwrIndexSource; + +typedef PACKED_PRE struct PACKED_POST { + t2Decimal dbmPwr; + tANI_U8 reserved[2]; +} tMsgPttSetTxPower; + +typedef tTxPowerReport tMsgPttGetTxPowerReport; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + + tANI_U8 minIndex; + tANI_U8 maxIndex; + tANI_U8 reserved[2]; + + tANI_U8 powerLut[TPC_MEM_POWER_LUT_DEPTH]; +} tMsgPttSetPowerLut; + +typedef PACKED_PRE struct PACKED_POST { + ePhyTxChains txChain; + + tANI_U8 powerLut[TPC_MEM_POWER_LUT_DEPTH]; +} tMsgPttGetPowerLut; + + +//Rx Gain Service +typedef PACKED_PRE struct PACKED_POST { + sRxChainsAgcDisable gains; +} tMsgPttDisableAgcTables; + + +typedef PACKED_PRE struct PACKED_POST { + sRxChainsAgcEnable enables; +} tMsgPttEnableAgcTables; + +typedef PACKED_PRE struct PACKED_POST { + sRxChainsRssi rssi; +} tMsgPttGetRxRssi; + +typedef PACKED_PRE struct PACKED_POST { + sRxChainsRssi rssi; +}tMsgPttGetUnicastMacPktRxRssi; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 conf; +}tMsgPttGetUnicastMacPktRxRssiConf_PRIMA_V1; + +//Rx Frame Catcher Service +typedef PACKED_PRE struct PACKED_POST { + sRxTypesDisabled disabled; +} tMsgPttSetRxDisableMode; + +typedef PACKED_PRE struct PACKED_POST { + sRxFrameCounters counters; +} tMsgPttGetRxPktCounts; + + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttResetRxPacketStatistics; + + + + + +//ADC Sample Service +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 startSample; //index of first requested sample, 0 causes new capture + tANI_U32 numSamples; //number of samples to transfer to host + eGrabRamSampleType sampleType; + tGrabRamSample grabRam[MAX_REQUESTED_GRAB_RAM_SAMPLES]; +} tMsgPttGrabRam; + + +//Phy Calibration Service +typedef PACKED_PRE struct PACKED_POST { + sRxChainsIQCalValues calValues; + eGainSteps gain; +} tMsgPttRxIqCal; + +typedef PACKED_PRE struct PACKED_POST { + tRxChainsDcoCorrections calValues; + tANI_U8 gain; +} tMsgPttRxDcoCal; + +typedef PACKED_PRE struct PACKED_POST { + tRxChainsIm2Corrections calValues; + eGainSteps gain; + tANI_U8 im2CalOnly; +} tMsgPttRxIm2Cal; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsLoCorrections calValues; + tANI_U8 reserve[2]; + eGainSteps gain; +} tMsgPttTxCarrierSuppressCal; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsIQCalValues calValues; + tANI_U8 reserve[2]; + eGainSteps gain; +} tMsgPttTxIqCal; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsHKIQCalValues calValues; + eGainSteps gain; +} tMsgPttHKdacTxIqCal; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 unused; +} tMsgPttExecuteInitialCals; + +typedef PACKED_PRE struct PACKED_POST { + sRfHdetCalValues hdetCalValues; +} tMsgPttHdetCal; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 clpcMode; + tANI_U16 txCmdPwr; + tANI_U16 pwrMax_pwrMin; + tANI_U16 step; + tANI_U8 plut[256]; +} tMsgPttClpcSwCal_PRIMA_V1; + + +//Phy Calibration Override Service +typedef PACKED_PRE struct PACKED_POST { + sTxChainsLoCorrections calValues; + tANI_U8 reserve[2]; + eGainSteps gain; +} tMsgPttSetTxCarrierSuppressCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsLoCorrections calValues; + tANI_U8 reserve[2]; + eGainSteps gain; +} tMsgPttGetTxCarrierSuppressCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsIQCalValues calValues; + tANI_U8 reserve[2]; + eGainSteps gain; +} tMsgPttSetTxIqCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsIQCalValues calValues; + tANI_U8 reserve[2]; + eGainSteps gain; +} tMsgPttGetTxIqCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsHKIQCalValues calValues; + eGainSteps gain; +} tMsgPttHKdacSetTxIqCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsHKIQCalValues calValues; + eGainSteps gain; +} tMsgPttHKdacGetTxIqCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sRxChainsIQCalValues calValues; + eGainSteps gain; +} tMsgPttSetRxIqCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sRxChainsIQCalValues calValues; + eGainSteps gain; +} tMsgPttGetRxIqCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tRxChainsDcoCorrections calValues; + tANI_U8 gain; +} tMsgPttSetRxDcoCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tRxChainsDcoCorrections calValues; + tANI_U8 gain; +} tMsgPttGetRxDcoCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tRxChainsIm2Corrections calValues; + tANI_U8 dummy; +} tMsgPttSetRxIm2Correct; + +typedef PACKED_PRE struct PACKED_POST { + tRxChainsIm2Corrections calValues; + tANI_U8 dummy; +} tMsgPttGetRxIm2Correct; + +typedef PACKED_PRE struct PACKED_POST { + eRfTempSensor tempSensor; + tTempADCVal tempAdc; + tANI_U8 reserved[4 - sizeof(tTempADCVal)]; +} tMsgPttGetTempAdc; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 addr; + tANI_U32 mask; + tANI_U32 shift; + tANI_U32 value; +} tMsgPttReadRfField; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 addr; + tANI_U32 mask; + tANI_U32 shift; + tANI_U32 value; +} tMsgPttWriteRfField; + +//SIF bar4 Register Access +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 sifRegAddr; + tANI_U32 sifRegValue; +} tMsgPttReadSifBar4Register; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 sifRegAddr; + tANI_U32 sifRegValue; +} tMsgPttWriteSifBar4Register; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttDeepSleep; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttEnterFullPower; + +//Misc. +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 notUsed; +} tMsgPttSystemReset; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 cmd; + tANI_U32 arg1; + tANI_U32 arg2; + tANI_U32 arg3; + tANI_U32 arg4; +} tMsgPttLogDump; + +typedef PACKED_PRE struct PACKED_POST { + sBuildReleaseParams relParams; +} tMsgPttGetBuildReleaseNumber; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 revId; +} tMsgPttGetRFVersion; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 option; //dummy variable +} tMsgPttCalControlBitmap; + +//#ifdef VERIFY_HALPHY_SIMV_MODEL + + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 option; //dummy variable +} tMsgPttHalPhyInit; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 option; //dummy variable +} tMsgPttRxIQTest; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsDPDCalValues calValues; + eGainSteps gain; +} tMsgPttDpdCal; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 lutIdx; + tANI_U8 band; +} tMsgPttStartToneGen; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 option; //dummy variable +} tMsgPttStopToneGen; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsLnaBandCalValues calValues; + eGainSteps gain; +} tMsgPttLnaBandCal; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsLnaBandCalValues calValues; + eGainSteps gain; +} tMsgPttGetLnaBandCalCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsLnaBandCalValues calValues; + eGainSteps gain; +} tMsgPttSetLnaBandCalCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsDPDCalValues calValues; + eGainSteps gain; +}tMsgPttSetDPDCorrect; + +typedef PACKED_PRE struct PACKED_POST { + sTxChainsDPDCalValues calValues; + eGainSteps gain; +}tMsgPttGetDPDCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tQWPTT_U32 cmdIdx; + tQWPTT_U32 param1; + tQWPTT_U32 param2; + tQWPTT_U32 param3; + tQWPTT_U32 param4; +} tMsgPttPrimaGenericCmd; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 testID; + tANI_U16 result; +} tMsgPttPinConnTestRes; +//#endif + +/****************************************************************************************************************** + END OF PTT MESSAGES +******************************************************************************************************************/ + +typedef PACKED_PRE union PACKED_POST pttMsgUnion{ +//typedef union pttMsgUnion { + tMsgPttMsgInit MsgInit; + tMsgPttGetNvTable GetNvTable; + tMsgPttSetNvTable SetNvTable; + tMsgPttDelNvTable DelNvTable; + tMsgPttBlankNv BlankNv; + tMsgPttStoreNvTable StoreNvTable; + tMsgPttSetRegDomain SetRegDomain; + tMsgPttGetNvField GetNvField; + tMsgPttSetNvField SetNvField; + tMsgPttGetNvBin GetNvBin; + tMsgPttSetNvBin SetNvBin; + tMsgPttDbgReadRegister DbgReadRegister; + tMsgPttDbgWriteRegister DbgWriteRegister; + tMsgPttDbgReadMemory DbgReadMemory; + tMsgPttDbgWriteMemory DbgWriteMemory; + tMsgPttEnableChains EnableChains; + tMsgPttSetChannel SetChannel; + tMsgPttSetWaveform SetWaveform; + tMsgPttSetTxWaveformGain SetTxWaveformGain; + tMsgPttSetTxWaveformGain_PRIMA_V1 SetTxWaveformGain_PRIMA_V1; + tMsgPttGetWaveformPowerAdc GetWaveformPowerAdc; + tMsgPttStartWaveform StartWaveform; + tMsgPttStartWaveform_PRIMA_V1 StartWaveform_PRIMA_V1; + tMsgPttStopWaveform StopWaveform; + tMsgPttSetRxWaveformGain SetRxWaveformGain; + tMsgPttConfigTxPacketGen ConfigTxPacketGen; + tMsgPttStartStopTxPacketGen StartStopTxPacketGen; + tMsgPttQueryTxStatus QueryTxStatus; + tMsgPttCloseTpcLoop CloseTpcLoop; + tMsgPttCloseTpcLoop_PRIMA_V1 CloseTpcLoop_PRIMA_V1; + tMsgPttSetPacketTxGainTable SetPacketTxGainTable; + tMsgPttGetPacketTxGainTable GetPacketTxGainTable; + tMsgPttSetPacketTxGainIndex SetPacketTxGainIndex; + tMsgPttForcePacketTxGain ForcePacketTxGain; + tMsgPttForcePacketTxGain_PRIMA_V1 ForcePacketTxGain_PRIMA_V1; + tMsgPttSetPwrIndexSource SetPwrIndexSource; + tMsgPttSetTxPower SetTxPower; + tMsgPttGetTxPowerReport GetTxPowerReport; + tMsgPttSetPowerLut SetPowerLut; + tMsgPttGetPowerLut GetPowerLut; + tMsgPttDisableAgcTables DisableAgcTables; + tMsgPttEnableAgcTables EnableAgcTables; + tMsgPttGetRxRssi GetRxRssi; + tMsgPttGetUnicastMacPktRxRssi GetUnicastMacPktRxRssi; + tMsgPttGetUnicastMacPktRxRssiConf_PRIMA_V1 GetUnicastMacPktRxRssiConf_PRIMA_V1; + tMsgPttSetRxDisableMode SetRxDisableMode; + tMsgPttGetRxPktCounts GetRxPktCounts; + tMsgPttResetRxPacketStatistics ResetRxPacketStatistics; + tMsgPttGrabRam GrabRam; + tMsgPttRxIqCal RxIqCal; + tMsgPttRxDcoCal RxDcoCal; + tMsgPttRxIm2Cal RxIm2Cal; + + tMsgPttExecuteInitialCals ExecuteInitialCals; + tMsgPttTxCarrierSuppressCal TxCarrierSuppressCal; + tMsgPttTxIqCal TxIqCal; + tMsgPttHKdacTxIqCal HKdacTxIqCal; + tMsgPttClpcCalSetup_PRIMA_V1 ClpcCalSetup_PRIMA_V1; + tMsgPttClpcCalRestore_PRIMA_V1 ClpcCalRestore_PRIMA_V1; + tMsgPttHdetCal HdetCal; + tMsgPttClpcSwCal_PRIMA_V1 ClpcSwCal_PRIMA_V1; + tMsgPttClpcCalExtraMeasurement_PRIMA_V1 ClpcCalExtraMeasurement_PRIMA_V1; + tMsgPttSetTxCarrierSuppressCorrect SetTxCarrierSuppressCorrect; + tMsgPttGetTxCarrierSuppressCorrect GetTxCarrierSuppressCorrect; + tMsgPttSetTxIqCorrect SetTxIqCorrect; + tMsgPttGetTxIqCorrect GetTxIqCorrect; + tMsgPttSetRxIqCorrect SetRxIqCorrect; + tMsgPttGetRxIqCorrect GetRxIqCorrect; + tMsgPttSetRxDcoCorrect SetRxDcoCorrect; + tMsgPttGetRxDcoCorrect GetRxDcoCorrect; + tMsgPttSetRxIm2Correct SetRxIm2Correct; + tMsgPttGetRxIm2Correct GetRxIm2Correct; + tMsgPttHKdacSetTxIqCorrect HKdacSetTxIqCorrect; + tMsgPttHKdacGetTxIqCorrect HKdacGetTxIqCorrect; + + tMsgPttGetTempAdc GetTempAdc; + tMsgPttReadRfField ReadRfField; + tMsgPttWriteRfField WriteRfField; + tMsgPttCalControlBitmap SetCalControlBitmap; + +//#ifdef VERIFY_HALPHY_SIMV_MODEL + + tMsgPttHalPhyInit InitOption; + tMsgPttRxIQTest RxIQTest; + tMsgPttDpdCal DpdCal; + tMsgPttStartToneGen StartToneGen; + tMsgPttStopToneGen StopToneGen; +//#endif + tMsgPttDeepSleep DeepSleep; + tMsgPttReadSifBar4Register ReadSifBar4Register; + tMsgPttWriteSifBar4Register WriteSifBar4Register; + tMsgPttEnterFullPower EnterFullPower; + tMsgPttSystemReset SystemReset; + tMsgPttLogDump LogDump; + tMsgPttGetBuildReleaseNumber GetBuildReleaseNumber; + tMsgPttGetRFVersion GetRFVersion; + +//[RY] added for PRIMA + tMsgPttSetWaveformRF SetWaveformRF; + tMsgPttStopWaveformRF StopWaveformRF; + tMsgPttStartWaveformRF StartWaveformRF; + tMsgPttLnaBandCal LnaBandCal; + tMsgPttGetLnaBandCalCorrect GetLnaBandCalCorrect; + tMsgPttSetLnaBandCalCorrect SetLnaBandCalCorrect; + tMsgPttGetDPDCorrect GetDPDCorrect; + tMsgPttSetDPDCorrect SetDPDCorrect; + tMsgPttDpdCal DPDCal; + tMsgPttPrimaGenericCmd PrimaGenericCmd; + tMsgPttPinConnTestRes PinConnTestRes; +} uPttMsgs; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 msgId; + tANI_U16 msgBodyLength; //actually, the length of all the fields in this structure + eQWPttStatus msgResponse; + uPttMsgs msgBody; +} tPttMsgbuffer, *tpPttMsgbuffer; + + +typedef PACKED_PRE struct PACKED_POST { + /* + * success or failure + */ + tANI_U32 status; + tPttMsgbuffer pttMsgBuffer; +} tProcessPttRspParams, *tpProcessPttRspParams; + +/* End of Ptt Parameters */ + +#endif diff --git a/drivers/staging/prima/riva/inc/wlan_hal_cfg.h b/drivers/staging/prima/riva/inc/wlan_hal_cfg.h new file mode 100644 index 000000000000..8c4f277c0459 --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_hal_cfg.h @@ -0,0 +1,1116 @@ +/* + * Copyright (c) 2012-2013,2016,2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*========================================================================== + * + * @file: wlan_hal_cfg.h + * + * @brief: Exports and types WLAN HAL configuration + * + * @author: Kumar Anand + * + * + *=========================================================================*/ + +#ifndef __WLAN_HAL_CFG_H__ +#define __WLAN_HAL_CFG_H__ + +/*------------------------------------------------------------------------- + Include Files +-------------------------------------------------------------------------*/ +#include "qwlanfw_defs.h" + +/*------------------------------------------------------------------------- + Preprocessor definitions and constants +-------------------------------------------------------------------------*/ +/* RIVA API version in format W.X.Y.Z is converted to a UINT32 integer */ +#define WLAN_HAL_CONSTRUCT_API_VERSION(W,X,Y,Z) (((W)<<24)+((X)<<16)+((Y)<<8)+(Z)) +#define IS_VERSION_BEFORE_VOWIFI(VER_FROM_HOST) \ + ((VER_FROM_HOST)<=WLAN_HAL_CONSTRUCT_API_VERSION(0,0,2,0))?1:0 + +/*------------------------------------------------------------------------- + Configuration Parameter IDs +-------------------------------------------------------------------------*/ +#define QWLAN_HAL_CFG_STA_ID 0 +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA 1 +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA 2 +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE 3 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN 4 +#define QWLAN_HAL_CFG_CAL_PERIOD 5 +#define QWLAN_HAL_CFG_CAL_CONTROL 6 +#define QWLAN_HAL_CFG_PROXIMITY 7 +#define QWLAN_HAL_CFG_NETWORK_DENSITY 8 +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME 9 +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU 10 +#define QWLAN_HAL_CFG_RTS_THRESHOLD 11 +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT 12 +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT 13 +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD 14 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO 15 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE 16 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO 17 +#define QWLAN_HAL_CFG_FIXED_RATE 18 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY 19 +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY 20 +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY 21 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION 22 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ 23 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ 24 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ 25 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ 26 +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS 27 +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT 28 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER 29 +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR 30 +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE 31 +#define QWLAN_HAL_CFG_STATS_PERIOD 32 +#define QWLAN_HAL_CFG_CFP_MAX_DURATION 33 +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED 34 +#define QWLAN_HAL_CFG_DTIM_PERIOD 35 +#define QWLAN_HAL_CFG_EDCA_WMM_ACBK 36 +#define QWLAN_HAL_CFG_EDCA_WMM_ACBE 37 +#define QWLAN_HAL_CFG_EDCA_WMM_ACVO 38 +#define QWLAN_HAL_CFG_EDCA_WMM_ACVI 39 +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH 40 +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS 41 +#define QWLAN_HAL_CFG_RPE_POLLING_THRESHOLD 42 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG 43 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG 44 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG 45 +#define QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG 46 +#define QWLAN_HAL_CFG_NO_OF_ONCHIP_REORDER_SESSIONS 47 +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL 48 +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD 49 +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER 50 +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL 51 +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD 52 +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD 53 +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE 54 +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM 55 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM 56 +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE 57 +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT 58 +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN 59 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI 60 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS 61 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI 62 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS 63 +#define QWLAN_HAL_CFG_TX_PWR_CTRL_ENABLE 64 +#define QWLAN_HAL_CFG_VALID_RADAR_CHANNEL_LIST 65 +#define QWLAN_HAL_CFG_TX_POWER_24_20 66 +#define QWLAN_HAL_CFG_TX_POWER_24_40 67 +#define QWLAN_HAL_CFG_TX_POWER_50_20 68 +#define QWLAN_HAL_CFG_TX_POWER_50_40 69 +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING 70 +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL 71 +#define QCOM_WLAN_CFG_MAX_TX_POWER_2_4 72 +#define QCOM_WLAN_CFG_MAX_TX_POWER_5 73 +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD 74 +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP 75 +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE 76 +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK 77 +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS 78 +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT 79 +#define QWLAN_HAL_CFG_WCNSS_API_VERSION 80 +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT 81 +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT 82 +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST 83 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT 84 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT 85 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT 86 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT 87 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN 88 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN 89 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN 90 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN 91 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT 92 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN 93 +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC 94 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP 95 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO 96 +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER 97 +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT 98 +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION 99 +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER 100 +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT 101 +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT 102 +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER 103 +#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE 104 +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER 105 +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT 106 +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT 107 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE 108 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK 109 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME 110 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP 111 +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY 112 +#define QWLAN_HAL_CFG_ATH_DISABLE 113 +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR 114 +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE 115 +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE 116 +#define QWLAN_HAL_CFG_MWS_COEX_V1_WAN_FREQ 117 +#define QWLAN_HAL_CFG_MWS_COEX_V1_WLAN_FREQ 118 +#define QWLAN_HAL_CFG_MWS_COEX_V1_CONFIG 119 +#define QWLAN_HAL_CFG_MWS_COEX_V1_CONFIG2 120 +#define QWLAN_HAL_CFG_MWS_COEX_V2_WAN_FREQ 121 +#define QWLAN_HAL_CFG_MWS_COEX_V2_WLAN_FREQ 122 +#define QWLAN_HAL_CFG_MWS_COEX_V2_CONFIG 123 +#define QWLAN_HAL_CFG_MWS_COEX_V2_CONFIG2 124 +#define QWLAN_HAL_CFG_MWS_COEX_V3_WAN_FREQ 125 +#define QWLAN_HAL_CFG_MWS_COEX_V3_WLAN_FREQ 126 +#define QWLAN_HAL_CFG_MWS_COEX_V3_CONFIG 127 +#define QWLAN_HAL_CFG_MWS_COEX_V3_CONFIG2 128 +#define QWLAN_HAL_CFG_MWS_COEX_V4_WAN_FREQ 129 +#define QWLAN_HAL_CFG_MWS_COEX_V4_WLAN_FREQ 130 +#define QWLAN_HAL_CFG_MWS_COEX_V4_CONFIG 131 +#define QWLAN_HAL_CFG_MWS_COEX_V4_CONFIG2 132 +#define QWLAN_HAL_CFG_MWS_COEX_V5_WAN_FREQ 133 +#define QWLAN_HAL_CFG_MWS_COEX_V5_WLAN_FREQ 134 +#define QWLAN_HAL_CFG_MWS_COEX_V5_CONFIG 135 +#define QWLAN_HAL_CFG_MWS_COEX_V5_CONFIG2 136 +#define QWLAN_HAL_CFG_MWS_COEX_V6_WAN_FREQ 137 +#define QWLAN_HAL_CFG_MWS_COEX_V6_WLAN_FREQ 138 +#define QWLAN_HAL_CFG_MWS_COEX_V6_CONFIG 139 +#define QWLAN_HAL_CFG_MWS_COEX_V6_CONFIG2 140 +#define QWLAN_HAL_CFG_MWS_COEX_V7_WAN_FREQ 141 +#define QWLAN_HAL_CFG_MWS_COEX_V7_WLAN_FREQ 142 +#define QWLAN_HAL_CFG_MWS_COEX_V7_CONFIG 143 +#define QWLAN_HAL_CFG_MWS_COEX_V7_CONFIG2 144 +#define QWLAN_HAL_CFG_MWS_COEX_V8_WAN_FREQ 145 +#define QWLAN_HAL_CFG_MWS_COEX_V8_WLAN_FREQ 146 +#define QWLAN_HAL_CFG_MWS_COEX_V8_CONFIG 147 +#define QWLAN_HAL_CFG_MWS_COEX_V8_CONFIG2 148 +#define QWLAN_HAL_CFG_MWS_COEX_V9_WAN_FREQ 149 +#define QWLAN_HAL_CFG_MWS_COEX_V9_WLAN_FREQ 150 +#define QWLAN_HAL_CFG_MWS_COEX_V9_CONFIG 151 +#define QWLAN_HAL_CFG_MWS_COEX_V9_CONFIG2 152 +#define QWLAN_HAL_CFG_MWS_COEX_V10_WAN_FREQ 153 +#define QWLAN_HAL_CFG_MWS_COEX_V10_WLAN_FREQ 154 +#define QWLAN_HAL_CFG_MWS_COEX_V10_CONFIG 155 +#define QWLAN_HAL_CFG_MWS_COEX_V10_CONFIG2 156 +#define QWLAN_HAL_CFG_MWS_COEX_MODEM_BACKOFF 157 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG1 158 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG2 159 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG3 160 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG4 161 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG5 162 +#define QWLAN_HAL_CFG_MWS_COEX_CONFIG6 163 +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF 164 +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT 165 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN 166 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN 167 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN 168 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN 169 +#define QWLAN_HAL_CFG_RMC_FIXED_RATE 170 +#define QWLAN_HAL_CFG_ASD_PROBE_INTERVAL 171 +#define QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD 172 +#define QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD 173 +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO 174 +#define QWLAN_HAL_CFG_SHORT_PREAMBLE 175 +#define QWLAN_HAL_CFG_SHORT_SLOT_TIME 176 +#define QWLAN_HAL_CFG_DELAYED_BA 177 +#define QWLAN_HAL_CFG_IMMEDIATE_BA 178 +#define QWLAN_HAL_CFG_DOT11_MODE 179 +#define QWLAN_HAL_CFG_HT_CAPS 180 +#define QWLAN_HAL_CFG_AMPDU_PARAMS 181 +#define QWLAN_HAL_CFG_TX_BF_INFO 182 +#define QWLAN_HAL_CFG_ASC_CAP_INFO 183 +#define QWLAN_HAL_CFG_EXT_HT_CAPS 184 +#define QWLAN_HAL_CFG_QOS_ENABLED 185 +#define QWLAN_HAL_CFG_WME_ENABLED 186 +#define QWLAN_HAL_CFG_WSM_ENABLED 187 +#define QWLAN_HAL_CFG_WMM_ENABLED 188 +#define QWLAN_HAL_CFG_UAPSD_PER_AC_BITMASK 189 +#define QWLAN_HAL_CFG_MCS_RATES 190 +#define QWLAN_HAL_CFG_VHT_CAPS 191 +#define QWLAN_HAL_CFG_VHT_RX_SUPP_MCS 192 +#define QWLAN_HAL_CFG_VHT_TX_SUPP_MCS 193 +#define QWLAN_HAL_CFG_RA_FILTER_ENABLE 194 +#define QWLAN_HAL_CFG_RA_RATE_LIMIT_INTERVAL 195 +#define QWLAN_HAL_CFG_BTC_FATAL_HID_NSNIFF_BLK_GUIDANCE 196 +#define QWLAN_HAL_CFG_BTC_CRITICAL_HID_NSNIFF_BLK_GUIDANCE 197 +#define QWLAN_HAL_CFG_BTC_DYN_A2DP_TX_QUEUE_THOLD 198 +#define QWLAN_HAL_CFG_BTC_DYN_OPP_TX_QUEUE_THOLD 199 +#define QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT 200 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP 201 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT 202 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT 203 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW 204 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW 205 +#define QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE 206 +#define QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS 207 +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS 208 +#define QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE 209 +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE 210 +#define QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF 211 +#define QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT 212 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN 213 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN 214 +#define QWLAN_HAL_CFG_LINK_FAIL_TX_CNT 215 +#define QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES 216 +#define QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT 217 +#define QWLAN_HAL_CFG_EXT_SCAN_CONC_MODE 218 +#define QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE 219 +#define QWLAN_HAL_CFG_SAR_BOFFSET_CORRECTION_ENABLE 220 +#define QWLAN_HAL_CFG_UNITS_OF_BCN_WAIT_TIME 221 +#define QWLAN_HAL_CFG_CONS_BCNMISS_COUNT 222 +#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL 223 +#define QWLAN_HAL_CFG_DISABLE_SCAN_DURING_SCO 224 +#define QWLAN_HAL_CFG_TRIGGER_NULLFRAME_BEFORE_HB 225 + +#define QWLAN_HAL_CFG_MAX_PARAMS 226 + +/* Total number of Integer CFGs. This is used while allocating the memory for TLV */ +#define QWLAN_HAL_CFG_INTEGER_PARAM 226 + +/*------------------------------------------------------------------------- + Configuration Parameter min, max, defaults +-------------------------------------------------------------------------*/ + +/* QWLAN_HAL_CFG_STA_ID*/ +#define QWLAN_HAL_CFG_STA_ID_STADEF "000AF5898989" +#define QCOM_WLAN_CFG_STA_ID_LEN 6 + +/* QWLAN_HAL_CFG_CURRENT_TX_ANTENNA */ +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA_STAMIN 1 +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA_STAMAX 1 +#define QWLAN_HAL_CFG_CURRENT_TX_ANTENNA_STADEF 1 + +/* QWLAN_HAL_CFG_CURRENT_RX_ANTENNA */ +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA_STAMIN 1 +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA_STAMAX 2 +#define QWLAN_HAL_CFG_CURRENT_RX_ANTENNA_STADEF 1 + +/* QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE */ +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE_STAMIN 0 +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE_STAMAX 1 +#define QWLAN_HAL_CFG_LOW_GAIN_OVERRIDE_STADEF 0 + +/* QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN */ +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_STAMIN 0 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_STAMAX 65535 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_STADEF 785 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_OFF 0 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_ON 1 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_TX 2 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_RX 3 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_MASK 15 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_CHAIN_0_OFFSET 0 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_CHAIN_1_OFFSET 4 +#define QWLAN_HAL_CFG_POWER_STATE_PER_CHAIN_CHAIN_2_OFFSET 8 + +/* QWLAN_HAL_CFG_CAL_PERIOD */ +#define QWLAN_HAL_CFG_CAL_PERIOD_STAMIN 2 +#define QWLAN_HAL_CFG_CAL_PERIOD_STAMAX 10 +#define QWLAN_HAL_CFG_CAL_PERIOD_STADEF 5 + +/* QWLAN_HAL_CFG_CAL_CONTROL */ +#define QWLAN_HAL_CFG_CAL_CONTROL_STAMIN 0 +#define QWLAN_HAL_CFG_CAL_CONTROL_STAMAX 1 +#define QWLAN_HAL_CFG_CAL_CONTROL_STADEF 0 +#define QWLAN_HAL_CFG_CAL_CONTROL_CAL_ON 0 +#define QWLAN_HAL_CFG_CAL_CONTROL_CAL_OFF 1 + +/* QWLAN_HAL_CFG_PROXIMITY */ +#define QWLAN_HAL_CFG_PROXIMITY_STAMIN 0 +#define QWLAN_HAL_CFG_PROXIMITY_STAMAX 1 +#define QWLAN_HAL_CFG_PROXIMITY_STADEF 0 +#define QWLAN_HAL_CFG_PROXIMITY_OFF 0 +#define QWLAN_HAL_CFG_PROXIMITY_ON 1 + +/* QWLAN_HAL_CFG_NETWORK_DENSITY */ +#define QWLAN_HAL_CFG_NETWORK_DENSITY_STAMIN 0 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_STAMAX 3 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_STADEF 3 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_LOW 0 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_MEDIUM 1 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_HIGH 2 +#define QWLAN_HAL_CFG_NETWORK_DENSITY_ADAPTIVE 3 + +/* QWLAN_HAL_CFG_MAX_MEDIUM_TIME */ +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME_STAMAX 65535 +#define QWLAN_HAL_CFG_MAX_MEDIUM_TIME_STADEF 1024 + +/* QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU */ +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU_STAMAX 65535 +#define QWLAN_HAL_CFG_MAX_MPDUS_IN_AMPDU_STADEF 64 + +/* QWLAN_HAL_CFG_RTS_THRESHOLD */ +#define QWLAN_HAL_CFG_RTS_THRESHOLD_STAMIN 0 +#define QWLAN_HAL_CFG_RTS_THRESHOLD_STAMAX 2347 +#define QWLAN_HAL_CFG_RTS_THRESHOLD_STADEF 2347 + +/* QWLAN_HAL_CFG_SHORT_RETRY_LIMIT */ +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT_STAMIN 0 +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT_STAMAX 255 +#define QWLAN_HAL_CFG_SHORT_RETRY_LIMIT_STADEF 15 + +/* QWLAN_HAL_CFG_LONG_RETRY_LIMIT */ +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT_STAMIN 0 +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT_STAMAX 255 +#define QWLAN_HAL_CFG_LONG_RETRY_LIMIT_STADEF 15 + +/* QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD */ +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD_STAMIN 256 +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD_STAMAX 8000 +#define QWLAN_HAL_CFG_FRAGMENTATION_THRESHOLD_STADEF 8000 + +/* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO */ +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ZERO_STADEF 5 + +/* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE */ +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_ONE_STADEF 10 + +/* QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO */ +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_THRESHOLD_TWO_STADEF 15 + +#define QWLAN_HAL_CFG_FIXED_RATE_AUTO 0 +#define QWLAN_HAL_CFG_FIXED_RATE_1MBPS 1 +#define QWLAN_HAL_CFG_FIXED_RATE_2MBPS 2 +#define QWLAN_HAL_CFG_FIXED_RATE_5_5MBPS 3 +#define QWLAN_HAL_CFG_FIXED_RATE_11MBPS 4 +#define QWLAN_HAL_CFG_FIXED_RATE_6MBPS 5 +#define QWLAN_HAL_CFG_FIXED_RATE_9MBPS 6 +#define QWLAN_HAL_CFG_FIXED_RATE_12MBPS 7 +#define QWLAN_HAL_CFG_FIXED_RATE_18MBPS 8 +#define QWLAN_HAL_CFG_FIXED_RATE_24MBPS 9 +#define QWLAN_HAL_CFG_FIXED_RATE_36MBPS 10 +#define QWLAN_HAL_CFG_FIXED_RATE_48MBPS 11 +#define QWLAN_HAL_CFG_FIXED_RATE_54MBPS 12 +#define QWLAN_HAL_CFG_FIXED_RATE_6_5MBPS_MCS0_20MHZ_SIMO 13 +#define QWLAN_HAL_CFG_FIXED_RATE_13MBPS_MCS1_20MHZ_SIMO 14 +#define QWLAN_HAL_CFG_FIXED_RATE_19_5MBPS_MCS2_20MHZ_SIMO 15 +#define QWLAN_HAL_CFG_FIXED_RATE_26MBPS_MCS3_20MHZ_SIMO 16 +#define QWLAN_HAL_CFG_FIXED_RATE_39MBPS_MCS4_20MHZ_SIMO 17 +#define QWLAN_HAL_CFG_FIXED_RATE_52MBPS_MCS5_20MHZ_SIMO 18 +#define QWLAN_HAL_CFG_FIXED_RATE_58_5MBPS_MCS6_20MHZ_SIMO 19 +#define QWLAN_HAL_CFG_FIXED_RATE_65MBPS_MCS7_20MHZ_SIMO 20 +#define QWLAN_HAL_CFG_FIXED_RATE_7_2MBPS_MCS0_20MHZ_SIMO_SGI 21 +#define QWLAN_HAL_CFG_FIXED_RATE_14_4MBPS_MCS1_20MHZ_SIMO_SGI 22 +#define QWLAN_HAL_CFG_FIXED_RATE_21_7MBPS_MCS2_20MHZ_SIMO_SGI 23 +#define QWLAN_HAL_CFG_FIXED_RATE_28_9MBPS_MCS3_20MHZ_SIMO_SGI 24 +#define QWLAN_HAL_CFG_FIXED_RATE_43_3MBPS_MCS4_20MHZ_SIMO_SGI 25 +#define QWLAN_HAL_CFG_FIXED_RATE_57_8MBPS_MCS5_20MHZ_SIMO_SGI 26 +#define QWLAN_HAL_CFG_FIXED_RATE_65MBPS_MCS6_20MHZ_SIMO_SGI 27 +#define QWLAN_HAL_CFG_FIXED_RATE_72_2MBPS_MCS7_20MHZ_SIMO_SGI 28 +#define QWLAN_HAL_CFG_FIXED_RATE_13_5MBPS_MCS0_40MHZ_SIMO 29 +#define QWLAN_HAL_CFG_FIXED_RATE_27MBPS_MCS1_40MHZ_SIMO 30 +#define QWLAN_HAL_CFG_FIXED_RATE_40_5MBPS_MCS2_40MHZ_SIMO 31 +#define QWLAN_HAL_CFG_FIXED_RATE_54MBPS_MCS3_40MHZ_SIMO 32 +#define QWLAN_HAL_CFG_FIXED_RATE_81MBPS_MCS4_40MHZ_SIMO 33 +#define QWLAN_HAL_CFG_FIXED_RATE_108MBPS_MCS5_40MHZ_SIMO 34 +#define QWLAN_HAL_CFG_FIXED_RATE_121_5MBPS_MCS6_40MHZ_SIMO 35 +#define QWLAN_HAL_CFG_FIXED_RATE_135MBPS_MCS7_40MHZ_SIMO 36 +#define QWLAN_HAL_CFG_FIXED_RATE_15MBPS_MCS0_40MHZ_SIMO_SGI 37 +#define QWLAN_HAL_CFG_FIXED_RATE_30MBPS_MCS1_40MHZ_SIMO_SGI 38 +#define QWLAN_HAL_CFG_FIXED_RATE_45MBPS_MCS2_40MHZ_SIMO_SGI 39 +#define QWLAN_HAL_CFG_FIXED_RATE_60MBPS_MCS3_40MHZ_SIMO_SGI 40 +#define QWLAN_HAL_CFG_FIXED_RATE_90MBPS_MCS4_40MHZ_SIMO_SGI 41 +#define QWLAN_HAL_CFG_FIXED_RATE_120MBPS_MCS5_40MHZ_SIMO_SGI 42 +#define QWLAN_HAL_CFG_FIXED_RATE_135MBPS_MCS6_40MHZ_SIMO_SGI 43 +#define QWLAN_HAL_CFG_FIXED_RATE_150MBPS_MCS7_40MHZ_SIMO_SGI 44 + +/* QWLAN_HAL_CFG_FIXED_RATE + * Follwing rates in user configuration are mapped to TPE rates + * Mapping is defined in the gHalUserFixedRateCfgToTpeRateTable + */ +#define QWLAN_HAL_CFG_FIXED_RATE_STAMIN 0 +#define QWLAN_HAL_CFG_FIXED_RATE_STAMAX 226 +#define QWLAN_HAL_CFG_FIXED_RATE_STADEF QWLAN_HAL_CFG_FIXED_RATE_AUTO + +/* QWLAN_HAL_CFG_RMC_FIXED_RATE + * Follwing rates in user configuration are mapped to TPE rates + * Mapping is defined in the gHalUserFixedRateCfgToTpeRateTable + */ +#define QWLAN_HAL_CFG_RMC_FIXED_RATE_STAMIN 0 +#define QWLAN_HAL_CFG_RMC_FIXED_RATE_STAMAX 226 +#define QWLAN_HAL_CFG_RMC_FIXED_RATE_STADEF QWLAN_HAL_CFG_FIXED_RATE_24MBPS + +/* QWLAN_HAL_CFG_RETRYRATE_POLICY */ +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_STAMIN 0 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_STAMAX 255 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_STADEF 4 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_MIN_SUPPORTED 0 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_PRIMARY 1 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_RESERVED 2 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_CLOSEST 3 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_AUTOSELECT 4 +#define QWLAN_HAL_CFG_RETRYRATE_POLICY_MAX 5 + +/* QWLAN_HAL_CFG_RETRYRATE_SECONDARY */ +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY_STAMIN 0 +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY_STAMAX 255 +#define QWLAN_HAL_CFG_RETRYRATE_SECONDARY_STADEF 0 + +/* QWLAN_HAL_CFG_RETRYRATE_TERTIARY */ +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY_STAMIN 0 +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY_STAMAX 255 +#define QWLAN_HAL_CFG_RETRYRATE_TERTIARY_STADEF 0 + +/* QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION */ +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_STAMIN 0 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_STAMAX 5 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_STADEF 5 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_DISABLE 0 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_CTS 1 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_RTS 2 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_DUAL_CTS 3 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_RTS_ALWAYS 4 +#define QWLAN_HAL_CFG_FORCE_POLICY_PROTECTION_AUTO 5 + +/* QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ */ +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_1MBPS + +/* QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ */ +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_6MBPS + +/* QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ */ +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_1MBPS + +/* QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ */ +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMIN 0 +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ_STAMAX QWLAN_HAL_CFG_FIXED_RATE_STAMAX +#define QWLAN_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ_STADEF QWLAN_HAL_CFG_FIXED_RATE_6MBPS + +/* QWLAN_HAL_CFG_MAX_BA_SESSIONS */ +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS_STAMAX 64 +#define QWLAN_HAL_CFG_MAX_BA_SESSIONS_STADEF 40 + +/* QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT */ +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMIN 1 +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT_STAMAX 255 +#define QWLAN_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT_STADEF 20 + +/* QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT */ +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT_STAMIN 0 +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT_STAMAX 255 +#define QWLAN_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT_STADEF 300 + +/* QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER */ +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER_STAMIN 0 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER_STAMAX 1 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_FILTER_STADEF 1 + +/* QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR */ +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR_STAMIN 0 +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR_STAMAX 1 +#define QWLAN_HAL_CFG_PS_ENABLE_RSSI_MONITOR_STADEF 1 + +/* QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE */ +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMIN 1 +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STAMAX 20 +#define QWLAN_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE_STADEF 20 + +/* QWLAN_HAL_CFG_STATS_PERIOD */ +#define QWLAN_HAL_CFG_STATS_PERIOD_STAMIN 1 +#define QWLAN_HAL_CFG_STATS_PERIOD_STAMAX 10 +#define QWLAN_HAL_CFG_STATS_PERIOD_STADEF 10 + +/* QWLAN_HAL_CFG_CFP_MAX_DURATION */ +#define QWLAN_HAL_CFG_CFP_MAX_DURATION_STAMIN 0 +#define QWLAN_HAL_CFG_CFP_MAX_DURATION_STAMAX 65535 +#define QWLAN_HAL_CFG_CFP_MAX_DURATION_STADEF 30000 + +/* QWLAN_HAL_CFG_FRAME_TRANS_ENABLED */ +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED_STAMIN 0 +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED_STAMAX 1 +#define QWLAN_HAL_CFG_FRAME_TRANS_ENABLED_STADEF 0 + +/* QWLAN_HAL_CFG_DTIM_PERIOD */ +#define QWLAN_HAL_CFG_DTIM_PERIOD_STAMIN 0 +#define QWLAN_HAL_CFG_DTIM_PERIOD_STAMAX 65535 +#define QWLAN_HAL_CFG_DTIM_PERIOD_STADEF 1 + +/* QWLAN_HAL_CFG_BA_THRESHOLD_HIGH */ +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH_STAMIN 0 +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH_STAMAX 65535 +#define QWLAN_HAL_CFG_BA_THRESHOLD_HIGH_STADEF 1 + +/* QWLAN_HAL_CFG_MAX_BA_BUFFERS */ +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS_STAMIN 0 +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS_STAMAX 2560 +#define QWLAN_HAL_CFG_MAX_BA_BUFFERS_STADEF 2560 + + + +/* ACM, AIFSN, [CWmin, CWmax, TxOp]-11A/11B/11G + * Cwmin and Cwmax are two bytes each, MSB first. So Cwmax of [03 FF] is + * equivalent to 0x03ff = 1023*/ +#define QWLAN_HAL_CFG_EDCA_PROFILE_ACM_IDX 0 /* byte[0] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_AIFSN_IDX 1 /* byte[1] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMINA_IDX 2 /* byte[2] & byte [3] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMAXA_IDX 4 /* byte[4] & byte [5] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_TXOPA_IDX 6 /* byte[6] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMINB_IDX 7 /* byte[7] & byte [8] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMAXB_IDX 9 /* byte[9] & byte [10] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_TXOPB_IDX 11 /* byte[11]*/ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMING_IDX 12 /* byte[12] & byte [13] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_CWMAXG_IDX 14 /* byte[14] & byte [15] */ +#define QWLAN_HAL_CFG_EDCA_PROFILE_TXOPG_IDX 16 /* byte[16]*/ +#define QWLAN_HAL_CFG_EDCA_PARAM_MAX_LEN 20 + +/* QWLAN_HAL_CFG_EDCA_WMM_ACBK */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACBK_DEFAULT "0007000F03FF00001F03FF00000F03FF00" + +/* QWLAN_HAL_CFG_EDCA_WMM_ACBE */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACBE_DEFAULT "0003000F03FF00001F03FF00000F03FF00" + +/* QWLAN_HAL_CFG_EDCA_WMM_ACVI */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACVI_DEFAULT "00020007000F5E000F001FBC0007000F5E" + +/* QWLAN_HAL_CFG_EDCA_WMM_ACVO */ +#define QWLAN_HAL_CFG_EDCA_WMM_ACVO_DEFAULT "0002000300072F0007000F66000300072F" + + +/* QWLAN_HAL_CFG_RPE_POLLING_THRESHOLD */ +#define QWLAN_CFG_RPE_POLLING_THRESHOLD_STAMIN 0 +#define QWLAN_CFG_RPE_POLLING_THRESHOLD_STAMAX 65535 +#define QWLAN_CFG_RPE_POLLING_THRESHOLD_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG_STADEF 30 + +/* QWLAN_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG */ +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMIN 0 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STAMAX 65535 +#define QWLAN_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG_STADEF 30 + +/* QWLAN_HAL_CFG_NO_OF_ONCHIP_REORDER_SESSIONS */ +#define QWLAN_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMIN 0 +#define QWLAN_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STAMAX 2 +#define QWLAN_CFG_NO_OF_ONCHIP_REORDER_SESSIONS_STADEF 1 + +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL_STAMIN 0 +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL_STAMAX 65535 +#define QWLAN_HAL_CFG_PS_LISTEN_INTERVAL_STADEF 1 + +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD_STAMIN 0 +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD_STAMAX 65535 +#define QWLAN_HAL_CFG_PS_HEART_BEAT_THRESHOLD_STADEF 40 + +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER_STAMIN 0 +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER_STAMAX 255 +#define QWLAN_HAL_CFG_PS_NTH_BEACON_FILTER_STADEF 10 + +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL_STAMIN 0 +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL_STAMAX 255 +#define QWLAN_HAL_CFG_PS_MAX_PS_POLL_STADEF 0 + +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD_STAMIN 0 +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD_STAMAX 10 +#define QWLAN_HAL_CFG_PS_MIN_RSSI_THRESHOLD_STADEF 10 + +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD_STAMIN 0 +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD_STAMAX 255 +#define QWLAN_HAL_CFG_PS_RSSI_FILTER_PERIOD_STADEF 20 + +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE_STAMIN 0 +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE_STAMAX 1 +#define QWLAN_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE_STADEF 0 + +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM_STAMIN 0 +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM_STAMAX 1 +#define QWLAN_HAL_CFG_PS_IGNORE_DTIM_STADEF 0 + +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM_STAMIN 0 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM_STAMAX 1 +#define QWLAN_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM_STADEF 0 + +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE_STAMIN 0 +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE_STAMAX 255 +#define QWLAN_HAL_CFG_DYNAMIC_PS_POLL_VALUE_STADEF 0 + +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMIN 0 +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STAMAX 80 +#define QWLAN_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT_STADEF 0 + +/* QWLAN_HAL_CFG_TX_PWR_CTRL_ENABLE */ +#define QWLAN_CFG_TX_PWR_CTRL_ENABLE_STAMIN 0 +#define QWLAN_CFG_TX_PWR_CTRL_ENABLE_STAMAX 1 +#define QWLAN_CFG_TX_PWR_CTRL_ENABLE_STADEF 1 + +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN_STAMIN 0 +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN_STAMAX 1 +#define QWLAN_HAL_CFG_TELE_BCN_WAKEUP_EN_STADEF 0 + +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_STAMIN 0 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_STAMAX 7 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_STADEF 3 + +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMIN 5 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STAMAX 255 +#define QWLAN_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS_STADEF 10 + +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_STAMIN 0 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_STAMAX 7 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_STADEF 5 + +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMIN 5 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STAMAX 255 +#define QWLAN_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS_STADEF 15 + +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING_STAMIN 0 +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING_STAMAX 3 +#define QWLAN_HAL_CFG_MCAST_BCAST_FILTER_SETTING_STADEF 0 + +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL_STAMIN 1 +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL_STAMAX 255 +#define QWLAN_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL_STADEF 5 + +/*Values to be added in hexadecimal*/ +/* QWLAN_HAL_CFG_VALID_RADAR_LIST */ +#define QWLAN_HAL_CFG_VALID_RADAR_CHANNEL_LIST_DEFAULT "36" +#define QWLAN_HAL_CFG_RADAR_CHANNEL_LIST_LEN 20 + +/* QWLAN_HAL_CFG_TX_POWER_24_20 */ +#define QWLAN_WLAN_TX_POWER_24_20_DEFAULT 299 +#define QWLAN_WLAN_TX_POWER_24_20_MIN 299 +#define QWLAN_WLAN_TX_POWER_24_20_MAX 299 + +/* QWLAN_HAL_CFG_TX_POWER_24_40 */ +#define QWLAN_WLAN_TX_POWER_24_40_DEFAULT 300 +#define QWLAN_WLAN_TX_POWER_24_40_MIN 299 +#define QWLAN_WLAN_TX_POWER_24_40_MAX 299 + +/* QWLAN_HAL_CFG_TX_POWER_50_20 */ +#define QWLAN_WLAN_TX_POWER_50_20_DEFAULT 301 +#define QWLAN_WLAN_TX_POWER_50_20_MIN 299 +#define QWLAN_WLAN_TX_POWER_50_20_MAX 299 + +/* QWLAN_HAL_CFG_TX_POWER_50_40 */ +#define QWLAN_WLAN_TX_POWER_50_40_DEFAULT 302 +#define QWLAN_WLAN_TX_POWER_50_40_MIN 299 +#define QWLAN_WLAN_TX_POWER_50_40_MAX 299 + +/* QCOM_WLAN_CFG_MAX_TX_POWER_2_4 */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_2_4_LEN 128 +/* byte[0] = 0x01 = First Channel; byte[1] = 0x0E = 14 = MaxChannels; byte[2] = 0x14 = 20 = Tx Power (dBm) */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_2_4_DEFAULT "010E14" + +/* QCOM_WLAN_CFG_MAX_TX_POWER_5 */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_5_LEN 128 +/* byte[0] = 0x24 = 36 = First Channel; byte[1] = 0x82 = 130 = MaxChannels; byte[2] = 0x14 = 20 = Tx Power (dBm) */ +#define QCOM_WLAN_CFG_MAX_TX_POWER_5_DEFAULT "248214" + + +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMIN 0 +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STAMAX 65535 +#define QWLAN_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD_STADEF 0 + +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_CLOSE_LOOP_DEF 0 + +/* QWLAN_HAL_CFG_BTC_EXECUTION_MODE */ +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE_MIN 0 +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE_MAX 5 +#define QWLAN_HAL_CFG_BTC_EXECUTION_MODE_DEF 0 + +/* QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK */ +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_MIN 0 +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_MAX 255 +#define QWLAN_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK_DEF 0 + +/* QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS */ +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_MIN 0 +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_MAX 255 +#define QWLAN_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS_DEF 15 + +/* QWLAN_HAL_CFG_WCNSS_API_VERSION */ +#define QWLAN_HAL_CFG_WCNSS_API_VERSION_MIN 0 /* equivalent to 0.0.0.0 */ +#define QWLAN_HAL_CFG_WCNSS_API_VERSION_MAX 4294967295U /* equivalent to 255.255.255.255 */ +#define QWLAN_HAL_CFG_WCNSS_API_VERSION_DEF 0 /* equivalent to 0.0.0.0 */ + +/* QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT */ +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT_MIN 1 +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT_MAX 255 +#define QWLAN_HAL_CFG_AP_KEEPALIVE_TIMEOUT_DEF 20 + +/* QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT */ +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT_MIN 1 +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT_MAX 255 +#define QWLAN_HAL_CFG_GO_KEEPALIVE_TIMEOUT_DEF 20 + +/* QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST */ +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_MC_ADDR_LIST_DEF 0 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_BT_DEF 120000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_BT_DEF 10000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_BT_DEF 10000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT_MIN 5000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_BT_DEF 10000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN_DEF 30000 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN_DEF 0 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN_DEF 0 + +/* QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN */ +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_STATIC_LEN_LE_WLAN_DEF 0 + +/* QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT */ +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT_MIN 25000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT_MAX 500000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_BT_DEF 250000 + +/* QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN */ +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN_MIN 15000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN_MAX 500000 +#define QWLAN_HAL_CFG_BTC_DYN_MAX_LEN_WLAN_DEF 45000 + +/* QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC */ +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC_MIN 0 +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC_MAX 100 +#define QWLAN_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC_DEF 1 + +/* QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP */ +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP_MIN 0 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP_MAX 1 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_A2DP_DEF 1 + +/* QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO */ +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO_MIN 0 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO_MAX 1 +#define QWLAN_HAL_CFG_BTC_DHCP_PROT_ON_SCO_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER */ +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_UNICAST_FILTER_DEF 0 + +/* QWLAN_HAL_CFG_MAX_ASSOC_LIMIT */ +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT_MIN 10 +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT_MAX 32 +#define QWLAN_HAL_CFG_MAX_ASSOC_LIMIT_DEF 10 + +/* QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION */ +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER */ +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT */ +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_DETECT_PS_SUPPORT_DEF 0 + +/* QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT */ +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT_MIN 3 +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT_MAX 30 +#define QWLAN_HAL_CFG_AP_LINK_MONITOR_TIMEOUT_DEF 10 + +/* QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT */ +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT_MIN 3 +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT_MAX 30 +#define QWLAN_HAL_CFG_GO_LINK_MONITOR_TIMEOUT_DEF 10 + +/*QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER*/ +/*This value is multiplied to ChannelDwellTime + *i.e If value is 300 then ChannelDwellTime is (3*ChannelDwelltime)*/ +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_MIN 0 +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_MAX 300 +#define QWLAN_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER_DEF 300 + +/* QWLAN_HAL_CFG_ENABLE_TDLS_MODE */ +#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_TDLS_MODE_DEF 0 +/* QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER */ +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_NAT_KEEP_ALIVE_FILTER_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT */ +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_SAP_OBSS_PROT_DEF 0 + +/* QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT */ +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT_STAMIN 1 +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT_STAMAX 255 +#define QWLAN_HAL_CFG_PSPOLL_DATA_RECEP_TIMEOUT_STADEF 20 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE_MIN 0 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE_MAX 1 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_BUFFER_STA_CAPABLE_DEF 0 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_MASK */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK_MIN 0 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK_MAX 0xf +#define QWLAN_HAL_CFG_TDLS_PUAPSD_MASK_DEF 0 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME_MIN 0 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME_MAX 10 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_INACTIVITY_TIME_DEF 0 + +/* QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP */ +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP_MIN 10 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP_MAX 20 +#define QWLAN_HAL_CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD_IN_SP_DEF 10 + +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_DEF 60000 + +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_ACTIVE_BT_LEN_DEF 90000 + +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_WLAN_LEN_DEF 30000 + +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_SAP_STATIC_OPP_WLAN_ACTIVE_BT_LEN_DEF 30000 + +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO_MIN 0 +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO_MAX 1 +#define QWLAN_HAL_CFG_BTC_CTS2S_ON_STA_DURING_SCO_DEF 0 + +/* QWLAN_HAL_CFG_ANTENNA_DIVERSITY */ +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY_DEF 0 +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY_MIN 0 +#define QWLAN_HAL_CFG_ANTENNA_DIVERSITY_MAX 3 + +#define QWLAN_HAL_CFG_ATH_DEF 0 +#define QWLAN_HAL_CFG_ATH_MIN 0 +#define QWLAN_HAL_CFG_ATH_MAX 1 + +/* QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR */ +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR_DEF 0 +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR_MIN 0 +#define QWLAN_HAL_CFG_FLEXCONNECT_POWER_FACTOR_MAX 9 + +/* QWLAN_HAL_CFG_ENABLE_MCC_ADAPTIVE_RX_DRAIN_FEATURE */ +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_ADAPTIVE_RX_DRAIN_FEATURE_DEF 1 + +/* QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE */ +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE_MIN 0 +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE_MAX 1 +#define QWLAN_HAL_CFG_TDLS_OFF_CHANNEL_CAPABLE_DEF 0 + +/* QWLAN_HAL_CFG_MWS_COEX_XXXX */ +#define QWLAN_HAL_CFG_MWS_COEX_DEF 0 +#define QWLAN_HAL_CFG_MWS_COEX_MIN 0 +#define QWLAN_HAL_CFG_MWS_COEX_MAX 0xFFFFFFFF +#define QWLAN_HAL_CFG_MWS_COEX_MAX_VICTIM 10 +#define QWLAN_HAL_CFG_MWS_COEX_MAX_CONFIG 6 + +/* QWLAN_HAL_CFG_SAR_POWER_BACKOFF */ +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF_DEF 13 +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF_MIN 1 +#define QWLAN_HAL_CFG_SAR_POWER_BACKOFF_MAX 21 + +/*Once the period expires the RSSI will be compared with Threshold + * and if needed trigger events will be raised + */ +#define QWLAN_HAL_CFG_ASD_PROBE_INTERVAL_DEF 50 +#define QWLAN_HAL_CFG_ASD_PROBE_INTERVAL_MIN 10 +#define QWLAN_HAL_CFG_ASD_PROBE_INTERVAL_MAX 100 + +/* RSSI Threshold used to trigger probing activity/selection process*/ +#define QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD_DEF -75 +#define QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD_MIN -120 +#define QWLAN_HAL_CFG_ASD_TRIGGER_THRESHOLD_MAX 0 + +/*RSSI Hysteresis Threshold for RSSI-RTT*/ +#define QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_DEF 50 +#define QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_MIN 50 +#define QWLAN_HAL_CFG_ASD_RTT_RSSI_HYST_THRESHOLD_MAX 100 + +/* QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT */ +#define QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT_DEF 6000 +#define QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT_MAX 60000 +#define QWLAN_HAL_CFG_LINK_FAIL_TIMEOUT_MIN 1000 + +/* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP */ +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP_MIN 0 // 0 is a special case which means ignore this rule +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP_MAX 500 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_SP_DEF 10 + +/* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT */ +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MIN 0 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MAX 5000 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_DEF 50 + +/* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT */ +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MIN 0 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MAX 5000 +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_DEF 50 + +/* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW */ +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_MIN 50 // In milliseconds - 50ms +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_MAX 50000 // 50 sec +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_RX_CNT_MEAS_WINDOW_DEF 500 // 500ms + +/* QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW */ +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_MIN 50 // In milliseconds - 50ms +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_MAX 50000 // 50 sec +#define QWLAN_HAL_CFG_MAX_UAPSD_CONSEC_TX_CNT_MEAS_WINDOW_DEF 500 // 500ms + +/* QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE */ +#define QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_MIN 0 +#define QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_MAX 255 +#define QWLAN_HAL_CFG_MAX_PSPOLL_IN_WMM_UAPSD_PS_MODE_DEF 0 + +/* QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS */ +#define QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_MIN 1 // Cannot be 0 since otherwise switching from Active to PS mode will fail +#define QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_MAX 255 +#define QWLAN_HAL_CFG_MAX_UAPSD_INACTIVITY_INTERVALS_DEF 10 + +/* QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS */ +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS_MAX 1 +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_WMMPS_DEF 1 + +/* QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE */ +#define QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE_MIN 0 +#define QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE_MAX 12288 +#define QWLAN_HAL_CFG_BURST_MODE_BE_TXOP_VALUE_DEF 0 + +/* QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE */ +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE_DEF 0 +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE_MIN 0 +#define QWLAN_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE_MAX 65535 + +/* QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF */ +#define QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF_DEF 1 +#define QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF_MIN 0 +#define QWLAN_HAL_CFG_BTC_FAST_WLAN_CONN_PREF_MAX 1 + +/* QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT */ +/* Bit mask value to enable RTS/CTS for different modes + * for 2.4 GHz, HT20 - 0x0001, for 2.4 GHz, HT40 - 0x0002 + * for 2.4 GHz, VHT20 - 0x0004, for 2.4 GHz, VHT40 - 0x0008 + * for 5 GHz, HT20 - 0x0100, for 5 GHz, HT40 - 0x0200 + * for 5 GHz, VHT20 - 0x0400, for 5 GHz, VHT40 - 0x0800 + * for 5 GHz, VHT80 - 0x1000 + */ +#define QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT_MIN 0x0000 +#define QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT_MAX 0x1f0f +#define QWLAN_HAL_CFG_ENABLE_RTSCTS_HTVHT_DEF 0x0000 + +/* QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN */ +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_WLAN_LEN_DEF 40000 +/* QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN */ +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MIN 0 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_MAX 250000 +#define QWLAN_HAL_CFG_BTC_STATIC_OPP_WLAN_IDLE_BT_LEN_DEF 40000 +/* QWLAN_HAL_CFG_LINK_FAIL_TX_CNT */ +#define QWLAN_HAL_CFG_LINK_FAIL_TX_CNT_MIN 50 +#define QWLAN_HAL_CFG_LINK_FAIL_TX_CNT_MAX 1000 +#define QWLAN_HAL_CFG_LINK_FAIL_TX_CNT_DEF 200 +/*QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES*/ +#define QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES_MIN 0 +#define QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES_MAX 1 +#define QWLAN_HAL_CFG_TOGGLE_ARP_BDRATES_DEF 0 +/* QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT */ +#define QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT_DISABLE 0 +#define QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT_ENABLE 1 +#define QWLAN_HAL_CFG_OPTIMIZE_CA_EVENT_DEFAULT 0 + +#define QWLAN_HAL_CFG_EXT_SCAN_CONC_MODE_DEF 1 +#define QWLAN_HAL_CFG_EXT_SCAN_CONC_MODE_MIN 0 +#define QWLAN_HAL_CFG_EXT_SCAN_CONC_MODE_MAX 2 + +/* QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE */ +#define QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE_MIN 0 +#define QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE_MAX 1 +#define QWLAN_HAL_CFG_BAR_WAKEUP_HOST_DISABLE_DEF 0 + +/* QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL */ +#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MIN 0 +#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_MAX 1 +#define QWLAN_HAL_CFG_BTC_DISABLE_WLAN_LINK_CRITICAL_DEF 0 + +#endif //__WLAN_HAL_CFG_H__ diff --git a/drivers/staging/prima/riva/inc/wlan_hal_msg.h b/drivers/staging/prima/riva/inc/wlan_hal_msg.h new file mode 100644 index 000000000000..64b090a26ffd --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_hal_msg.h @@ -0,0 +1,9705 @@ + +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*========================================================================== + * + * @file: wlan_hal_msg.h + * + * @brief: Exports and types for messages sent to HAL from WDI + * + * @author: Kumar Anand + * + * + *=========================================================================*/ + +#ifndef _WLAN_HAL_MSG_H_ +#define _WLAN_HAL_MSG_H_ + +#include "halLegacyPalTypes.h" +#include "halCompiler.h" +#include "wlan_qct_dev_defs.h" +#include "wlan_nv.h" + +/*--------------------------------------------------------------------------- + API VERSIONING INFORMATION + + The RIVA API is versioned as MAJOR.MINOR.VERSION.REVISION + The MAJOR is incremented for major product/architecture changes + (and then MINOR/VERSION/REVISION are zeroed) + The MINOR is incremented for minor product/architecture changes + (and then VERSION/REVISION are zeroed) + The VERSION is incremented if a significant API change occurs + (and then REVISION is zeroed) + The REVISION is incremented if an insignificant API change occurs + or if a new API is added + All values are in the range 0..255 (ie they are 8-bit values) + ---------------------------------------------------------------------------*/ +#define WLAN_HAL_VER_MAJOR 1 +#define WLAN_HAL_VER_MINOR 5 +#define WLAN_HAL_VER_VERSION 1 +#define WLAN_HAL_VER_REVISION 2 + +/*--------------------------------------------------------------------------- + Commom Type definitons + ---------------------------------------------------------------------------*/ + +#define DISA_MAX_PAYLOAD_SIZE 1600 + +//This is to force compiler to use the maximum of an int ( 4 bytes ) +#define WLAN_HAL_MAX_ENUM_SIZE 0x7FFFFFFF +#define WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE 0x7FFF + +//Max no. of transmit categories +#define STACFG_MAX_TC 8 + +//The maximum value of access category +#define WLAN_HAL_MAX_AC 4 + +typedef tANI_U8 tSirMacAddr[6]; +typedef tANI_U8 tHalIpv4Addr[4]; + +#define HAL_MAC_ADDR_LEN 6 +#define HAL_IPV4_ADDR_LEN 4 + +#define WLAN_HAL_STA_INVALID_IDX 0xFF +#define WLAN_HAL_BSS_INVALID_IDX 0xFF + +//Default Beacon template size +#define BEACON_TEMPLATE_SIZE 0x180 + + +//Max Tx Data Rate samples +#define MAX_TX_RATE_SAMPLES 10 +//Max Beacon Rssi samples +#define MAX_BCN_RSSI_SAMPLES 10 + +//Param Change Bitmap sent to HAL +#define PARAM_BCN_INTERVAL_CHANGED (1 << 0) +#define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) +#define PARAM_SHORT_SLOT_TIME_CHANGED (1 << 2) +#define PARAM_llACOEXIST_CHANGED (1 << 3) +#define PARAM_llBCOEXIST_CHANGED (1 << 4) +#define PARAM_llGCOEXIST_CHANGED (1 << 5) +#define PARAM_HT20MHZCOEXIST_CHANGED (1<<6) +#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7) +#define PARAM_RIFS_MODE_CHANGED (1<<8) +#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9) +#define PARAM_OBSS_MODE_CHANGED (1<<10) +#define PARAM_BEACON_UPDATE_MASK (PARAM_BCN_INTERVAL_CHANGED|PARAM_SHORT_PREAMBLE_CHANGED|PARAM_SHORT_SLOT_TIME_CHANGED|PARAM_llACOEXIST_CHANGED |PARAM_llBCOEXIST_CHANGED|\ + PARAM_llGCOEXIST_CHANGED|PARAM_HT20MHZCOEXIST_CHANGED|PARAM_NON_GF_DEVICES_PRESENT_CHANGED|PARAM_RIFS_MODE_CHANGED|PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED| PARAM_OBSS_MODE_CHANGED) + +/*Dump command response Buffer size*/ +#define DUMPCMD_RSP_BUFFER 500 + +/*Version string max length (including NUL) */ +#define WLAN_HAL_VERSION_LENGTH 64 + +#define WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE 450 +/* 80 is actually NUM_RF_CHANNELS_V2, but beyond V2, this number will be ignored by FW */ +#define WLAN_HAL_ROAM_SCAN_MAX_CHANNELS 80 +#define WLAN_HAL_ROAM_SACN_PMK_SIZE 32 +#define WLAN_HAL_ROAM_SCAN_RESERVED_BYTES 19 + +#define WLAN_HAL_EXT_SCAN_MAX_CHANNELS 16 +#define WLAN_HAL_EXT_SCAN_MAX_BUCKETS 16 +#define WLAN_HAL_EXT_SCAN_MAX_HOTLIST_APS 128 +#define WLAN_HAL_EXT_SCAN_MAX_HOTLIST_SSIDS 8 + +#define WLAN_HAL_EXT_SCAN_MAX_RSSI_SAMPLE_SIZE 8 + +/* For Logging enhancement feature currently max 2 address will be passed */ +/* In future we may pass 3 address and length in suspend mode corner case */ +#define MAX_NUM_OF_BUFFER 3 + +/* Log types */ +typedef enum +{ + MGMT_FRAME_LOGS = 0, + QXDM_LOGGING = 1, + FW_MEMORY_DUMP = 2, + FATAL_EVENT = 3 +}tHalFrameLoggingType; + +/* Log size */ +typedef enum +{ + LOG_SIZE_4K = 0, + LOG_SIZE_8K = 1, + LOG_SIZE_12K = 2, + LOG_SIZE_16K = 3, + LOG_SIZE_32K = 4, + LOG_SIZE_64K = 5, + LOG_SIZE_96K = 6 +}tHalLogBuffSize; + +/* Message types for messages exchanged between WDI and HAL */ +typedef enum +{ + //Init/De-Init + WLAN_HAL_START_REQ = 0, + WLAN_HAL_START_RSP = 1, + WLAN_HAL_STOP_REQ = 2, + WLAN_HAL_STOP_RSP = 3, + + //Scan + WLAN_HAL_INIT_SCAN_REQ = 4, + WLAN_HAL_INIT_SCAN_RSP = 5, + WLAN_HAL_START_SCAN_REQ = 6, + WLAN_HAL_START_SCAN_RSP = 7 , + WLAN_HAL_END_SCAN_REQ = 8, + WLAN_HAL_END_SCAN_RSP = 9, + WLAN_HAL_FINISH_SCAN_REQ = 10, + WLAN_HAL_FINISH_SCAN_RSP = 11, + + // HW STA configuration/deconfiguration + WLAN_HAL_CONFIG_STA_REQ = 12, + WLAN_HAL_CONFIG_STA_RSP = 13, + WLAN_HAL_DELETE_STA_REQ = 14, + WLAN_HAL_DELETE_STA_RSP = 15, + WLAN_HAL_CONFIG_BSS_REQ = 16, + WLAN_HAL_CONFIG_BSS_RSP = 17, + WLAN_HAL_DELETE_BSS_REQ = 18, + WLAN_HAL_DELETE_BSS_RSP = 19, + + //Infra STA asscoiation + WLAN_HAL_JOIN_REQ = 20, + WLAN_HAL_JOIN_RSP = 21, + WLAN_HAL_POST_ASSOC_REQ = 22, + WLAN_HAL_POST_ASSOC_RSP = 23, + + //Security + WLAN_HAL_SET_BSSKEY_REQ = 24, + WLAN_HAL_SET_BSSKEY_RSP = 25, + WLAN_HAL_SET_STAKEY_REQ = 26, + WLAN_HAL_SET_STAKEY_RSP = 27, + WLAN_HAL_RMV_BSSKEY_REQ = 28, + WLAN_HAL_RMV_BSSKEY_RSP = 29, + WLAN_HAL_RMV_STAKEY_REQ = 30, + WLAN_HAL_RMV_STAKEY_RSP = 31, + + //Qos Related + WLAN_HAL_ADD_TS_REQ = 32, + WLAN_HAL_ADD_TS_RSP = 33, + WLAN_HAL_DEL_TS_REQ = 34, + WLAN_HAL_DEL_TS_RSP = 35, + WLAN_HAL_UPD_EDCA_PARAMS_REQ = 36, + WLAN_HAL_UPD_EDCA_PARAMS_RSP = 37, + WLAN_HAL_ADD_BA_REQ = 38, + WLAN_HAL_ADD_BA_RSP = 39, + WLAN_HAL_DEL_BA_REQ = 40, + WLAN_HAL_DEL_BA_RSP = 41, + + WLAN_HAL_CH_SWITCH_REQ = 42, + WLAN_HAL_CH_SWITCH_RSP = 43, + WLAN_HAL_SET_LINK_ST_REQ = 44, + WLAN_HAL_SET_LINK_ST_RSP = 45, + WLAN_HAL_GET_STATS_REQ = 46, + WLAN_HAL_GET_STATS_RSP = 47, + WLAN_HAL_UPDATE_CFG_REQ = 48, + WLAN_HAL_UPDATE_CFG_RSP = 49, + + WLAN_HAL_MISSED_BEACON_IND = 50, + WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND = 51, + WLAN_HAL_MIC_FAILURE_IND = 52, + WLAN_HAL_FATAL_ERROR_IND = 53, + WLAN_HAL_SET_KEYDONE_MSG = 54, + + //NV Interface + WLAN_HAL_DOWNLOAD_NV_REQ = 55, + WLAN_HAL_DOWNLOAD_NV_RSP = 56, + + WLAN_HAL_ADD_BA_SESSION_REQ = 57, + WLAN_HAL_ADD_BA_SESSION_RSP = 58, + WLAN_HAL_TRIGGER_BA_REQ = 59, + WLAN_HAL_TRIGGER_BA_RSP = 60, + WLAN_HAL_UPDATE_BEACON_REQ = 61, + WLAN_HAL_UPDATE_BEACON_RSP = 62, + WLAN_HAL_SEND_BEACON_REQ = 63, + WLAN_HAL_SEND_BEACON_RSP = 64, + + WLAN_HAL_SET_BCASTKEY_REQ = 65, + WLAN_HAL_SET_BCASTKEY_RSP = 66, + WLAN_HAL_DELETE_STA_CONTEXT_IND = 67, + WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ = 68, + WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP = 69, + + // PTT interface support + WLAN_HAL_PROCESS_PTT_REQ = 70, + WLAN_HAL_PROCESS_PTT_RSP = 71, + + // BTAMP related events + WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ = 72, + WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP = 73, + WLAN_HAL_TL_HAL_FLUSH_AC_REQ = 74, + WLAN_HAL_TL_HAL_FLUSH_AC_RSP = 75, + + WLAN_HAL_ENTER_IMPS_REQ = 76, + WLAN_HAL_EXIT_IMPS_REQ = 77, + WLAN_HAL_ENTER_BMPS_REQ = 78, + WLAN_HAL_EXIT_BMPS_REQ = 79, + WLAN_HAL_ENTER_UAPSD_REQ = 80, + WLAN_HAL_EXIT_UAPSD_REQ = 81, + WLAN_HAL_UPDATE_UAPSD_PARAM_REQ = 82, + WLAN_HAL_CONFIGURE_RXP_FILTER_REQ = 83, + WLAN_HAL_ADD_BCN_FILTER_REQ = 84, + WLAN_HAL_REM_BCN_FILTER_REQ = 85, + WLAN_HAL_ADD_WOWL_BCAST_PTRN = 86, + WLAN_HAL_DEL_WOWL_BCAST_PTRN = 87, + WLAN_HAL_ENTER_WOWL_REQ = 88, + WLAN_HAL_EXIT_WOWL_REQ = 89, + WLAN_HAL_HOST_OFFLOAD_REQ = 90, + WLAN_HAL_SET_RSSI_THRESH_REQ = 91, + WLAN_HAL_GET_RSSI_REQ = 92, + WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ = 93, + WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ = 94, + + WLAN_HAL_ENTER_IMPS_RSP = 95, + WLAN_HAL_EXIT_IMPS_RSP = 96, + WLAN_HAL_ENTER_BMPS_RSP = 97, + WLAN_HAL_EXIT_BMPS_RSP = 98, + WLAN_HAL_ENTER_UAPSD_RSP = 99, + WLAN_HAL_EXIT_UAPSD_RSP = 100, + WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP = 101, + WLAN_HAL_UPDATE_UAPSD_PARAM_RSP = 102, + WLAN_HAL_CONFIGURE_RXP_FILTER_RSP = 103, + WLAN_HAL_ADD_BCN_FILTER_RSP = 104, + WLAN_HAL_REM_BCN_FILTER_RSP = 105, + WLAN_HAL_SET_RSSI_THRESH_RSP = 106, + WLAN_HAL_HOST_OFFLOAD_RSP = 107, + WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP = 108, + WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP = 109, + WLAN_HAL_ENTER_WOWL_RSP = 110, + WLAN_HAL_EXIT_WOWL_RSP = 111, + WLAN_HAL_RSSI_NOTIFICATION_IND = 112, + WLAN_HAL_GET_RSSI_RSP = 113, + WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP = 114, + + //11k related events + WLAN_HAL_SET_MAX_TX_POWER_REQ = 115, + WLAN_HAL_SET_MAX_TX_POWER_RSP = 116, + + //11R related msgs + WLAN_HAL_AGGR_ADD_TS_REQ = 117, + WLAN_HAL_AGGR_ADD_TS_RSP = 118, + + //P2P WLAN_FEATURE_P2P + WLAN_HAL_SET_P2P_GONOA_REQ = 119, + WLAN_HAL_SET_P2P_GONOA_RSP = 120, + + //WLAN Dump commands + WLAN_HAL_DUMP_COMMAND_REQ = 121, + WLAN_HAL_DUMP_COMMAND_RSP = 122, + + //OEM_DATA FEATURE SUPPORT + WLAN_HAL_START_OEM_DATA_REQ = 123, + WLAN_HAL_START_OEM_DATA_RSP = 124, + + //ADD SELF STA REQ and RSP + WLAN_HAL_ADD_STA_SELF_REQ = 125, + WLAN_HAL_ADD_STA_SELF_RSP = 126, + + //DEL SELF STA SUPPORT + WLAN_HAL_DEL_STA_SELF_REQ = 127, + WLAN_HAL_DEL_STA_SELF_RSP = 128, + + // Coex Indication + WLAN_HAL_COEX_IND = 129, + + // Tx Complete Indication + WLAN_HAL_OTA_TX_COMPL_IND = 130, + + //Host Suspend/resume messages + WLAN_HAL_HOST_SUSPEND_IND = 131, + WLAN_HAL_HOST_RESUME_REQ = 132, + WLAN_HAL_HOST_RESUME_RSP = 133, + + WLAN_HAL_SET_TX_POWER_REQ = 134, + WLAN_HAL_SET_TX_POWER_RSP = 135, + WLAN_HAL_GET_TX_POWER_REQ = 136, + WLAN_HAL_GET_TX_POWER_RSP = 137, + + WLAN_HAL_P2P_NOA_ATTR_IND = 138, + + WLAN_HAL_ENABLE_RADAR_DETECT_REQ = 139, + WLAN_HAL_ENABLE_RADAR_DETECT_RSP = 140, + WLAN_HAL_GET_TPC_REPORT_REQ = 141, + WLAN_HAL_GET_TPC_REPORT_RSP = 142, + WLAN_HAL_RADAR_DETECT_IND = 143, + WLAN_HAL_RADAR_DETECT_INTR_IND = 144, + WLAN_HAL_KEEP_ALIVE_REQ = 145, + WLAN_HAL_KEEP_ALIVE_RSP = 146, + + /*PNO messages*/ + WLAN_HAL_SET_PREF_NETWORK_REQ = 147, + WLAN_HAL_SET_PREF_NETWORK_RSP = 148, + WLAN_HAL_SET_RSSI_FILTER_REQ = 149, + WLAN_HAL_SET_RSSI_FILTER_RSP = 150, + WLAN_HAL_UPDATE_SCAN_PARAM_REQ = 151, + WLAN_HAL_UPDATE_SCAN_PARAM_RSP = 152, + WLAN_HAL_PREF_NETW_FOUND_IND = 153, + + WLAN_HAL_SET_TX_PER_TRACKING_REQ = 154, + WLAN_HAL_SET_TX_PER_TRACKING_RSP = 155, + WLAN_HAL_TX_PER_HIT_IND = 156, + + WLAN_HAL_8023_MULTICAST_LIST_REQ = 157, + WLAN_HAL_8023_MULTICAST_LIST_RSP = 158, + + WLAN_HAL_SET_PACKET_FILTER_REQ = 159, + WLAN_HAL_SET_PACKET_FILTER_RSP = 160, + WLAN_HAL_PACKET_FILTER_MATCH_COUNT_REQ = 161, + WLAN_HAL_PACKET_FILTER_MATCH_COUNT_RSP = 162, + WLAN_HAL_CLEAR_PACKET_FILTER_REQ = 163, + WLAN_HAL_CLEAR_PACKET_FILTER_RSP = 164, + /*This is temp fix. Should be removed once + * Host and Riva code is in sync*/ + WLAN_HAL_INIT_SCAN_CON_REQ = 165, + + WLAN_HAL_SET_POWER_PARAMS_REQ = 166, + WLAN_HAL_SET_POWER_PARAMS_RSP = 167, + + WLAN_HAL_TSM_STATS_REQ = 168, + WLAN_HAL_TSM_STATS_RSP = 169, + + // wake reason indication (WOW) + WLAN_HAL_WAKE_REASON_IND = 170, + // GTK offload support + WLAN_HAL_GTK_OFFLOAD_REQ = 171, + WLAN_HAL_GTK_OFFLOAD_RSP = 172, + WLAN_HAL_GTK_OFFLOAD_GETINFO_REQ = 173, + WLAN_HAL_GTK_OFFLOAD_GETINFO_RSP = 174, + + WLAN_HAL_FEATURE_CAPS_EXCHANGE_REQ = 175, + WLAN_HAL_FEATURE_CAPS_EXCHANGE_RSP = 176, + WLAN_HAL_EXCLUDE_UNENCRYPTED_IND = 177, + + WLAN_HAL_SET_THERMAL_MITIGATION_REQ = 178, + WLAN_HAL_SET_THERMAL_MITIGATION_RSP = 179, + + WLAN_HAL_UPDATE_VHT_OP_MODE_REQ = 182, + WLAN_HAL_UPDATE_VHT_OP_MODE_RSP = 183, + + WLAN_HAL_P2P_NOA_START_IND = 184, + + WLAN_HAL_GET_ROAM_RSSI_REQ = 185, + WLAN_HAL_GET_ROAM_RSSI_RSP = 186, + + WLAN_HAL_CLASS_B_STATS_IND = 187, + WLAN_HAL_DEL_BA_IND = 188, + WLAN_HAL_DHCP_START_IND = 189, + WLAN_HAL_DHCP_STOP_IND = 190, + WLAN_ROAM_SCAN_OFFLOAD_REQ = 191, + WLAN_ROAM_SCAN_OFFLOAD_RSP = 192, + WLAN_HAL_WIFI_PROXIMITY_REQ = 193, + WLAN_HAL_WIFI_PROXIMITY_RSP = 194, + + WLAN_HAL_START_SPECULATIVE_PS_POLLS_REQ = 195, + WLAN_HAL_START_SPECULATIVE_PS_POLLS_RSP = 196, + WLAN_HAL_STOP_SPECULATIVE_PS_POLLS_IND = 197, + + WLAN_HAL_TDLS_LINK_ESTABLISHED_REQ = 198, + WLAN_HAL_TDLS_LINK_ESTABLISHED_RSP = 199, + WLAN_HAL_TDLS_LINK_TEARDOWN_REQ = 200, + WLAN_HAL_TDLS_LINK_TEARDOWN_RSP = 201, + WLAN_HAL_TDLS_IND = 202, + WLAN_HAL_IBSS_PEER_INACTIVITY_IND = 203, + + /* Scan Offload APIs */ + WLAN_HAL_START_SCAN_OFFLOAD_REQ = 204, + WLAN_HAL_START_SCAN_OFFLOAD_RSP = 205, + WLAN_HAL_STOP_SCAN_OFFLOAD_REQ = 206, + WLAN_HAL_STOP_SCAN_OFFLOAD_RSP = 207, + WLAN_HAL_UPDATE_CHANNEL_LIST_REQ = 208, + WLAN_HAL_UPDATE_CHANNEL_LIST_RSP = 209, + WLAN_HAL_OFFLOAD_SCAN_EVENT_IND = 210, + + /* APIs to offload TCP/UDP Heartbeat handshakes */ + WLAN_HAL_LPHB_CFG_REQ = 211, + WLAN_HAL_LPHB_CFG_RSP = 212, + WLAN_HAL_LPHB_IND = 213, + + WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND = 214, + WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND = 215, + WLAN_HAL_PERIODIC_TX_PTRN_FW_IND = 216, + + // Events to set Per-Band Tx Power Limit + WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ = 217, + WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP = 218, + + WLAN_HAL_RMC_RULER_REQ = 219, + WLAN_HAL_RMC_RULER_RSP = 220, + WLAN_HAL_RMC_UPDATE_IND = 221, + + /* Batchscan */ + WLAN_HAL_BATCHSCAN_SET_REQ = 222, + WLAN_HAL_BATCHSCAN_SET_RSP = 223, + WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND = 224, + WLAN_HAL_BATCHSCAN_RESULT_IND = 225, + WLAN_HAL_BATCHSCAN_STOP_IND = 226, + + WLAN_HAL_GET_IBSS_PEER_INFO_REQ = 227, + WLAN_HAL_GET_IBSS_PEER_INFO_RSP = 228, + + WLAN_HAL_RATE_UPDATE_IND = 229, + + /* Tx Fail for weak link notification */ + WLAN_HAL_TX_FAIL_MONITOR_IND = 230, + WLAN_HAL_TX_FAIL_IND = 231, + + /* Multi-hop IP routing offload */ + WLAN_HAL_IP_FORWARD_TABLE_UPDATE_IND = 232, + + /* Channel avoidance for LTE Coex */ + WLAN_HAL_AVOID_FREQ_RANGE_IND = 233, + + /* Fast Roam Offload Synchup request protocol */ + /* TODO_LFR3 : change this value accordingly before final check-in */ + WLAN_HAL_ROAM_OFFLOAD_SYNCH_IND = 234, + WLAN_HAL_ROAM_OFFLOAD_SYNCH_CNF = 235, + + WLAN_HAL_MOTION_START_EVENT_REQ = 250, + WLAN_HAL_MOTION_STOP_EVENT_REQ = 251, + + /* Channel Switch Request version 1 */ + WLAN_HAL_CH_SWITCH_V1_REQ = 252, + WLAN_HAL_CH_SWITCH_V1_RSP = 253, + + /* 2G4 HT40 OBSS scan */ + WLAN_HAL_START_HT40_OBSS_SCAN_IND = 254, + WLAN_HAL_STOP_HT40_OBSS_SCAN_IND = 255,/* next free entry in tHalHostMsgType. */ + + /* WLAN NAN Messages */ + WLAN_HAL_NAN_FIRST = 256, + WLAN_HAL_NAN_REQ = WLAN_HAL_NAN_FIRST, + WLAN_HAL_NAN_RSP = 257, + WLAN_HAL_NAN_EVT = 258, + WLAN_HAL_NAN_LAST = WLAN_HAL_NAN_EVT, + WLAN_HAL_PRINT_REG_INFO_IND = 259, + + WLAN_HAL_GET_BCN_MISS_RATE_REQ = 260, + WLAN_HAL_GET_BCN_MISS_RATE_RSP = 261, + + /* WLAN LINK LAYER STATS Messages */ + WLAN_HAL_LL_SET_STATS_REQ = 262, + WLAN_HAL_LL_SET_STATS_RSP = 263, + WLAN_HAL_LL_GET_STATS_REQ = 264, + WLAN_HAL_LL_GET_STATS_RSP = 265, + WLAN_HAL_LL_CLEAR_STATS_REQ = 266, + WLAN_HAL_LL_CLEAR_STATS_RSP = 267, + WLAN_HAL_LL_NOTIFY_STATS = 268, + WLAN_HAL_LL_LAST = WLAN_HAL_LL_NOTIFY_STATS, + + /* WLAN EXT_SCAN Messages */ + WLAN_HAL_EXT_SCAN_START_REQ = 269, + WLAN_HAL_EXT_SCAN_START_RSP = 270, + WLAN_HAL_EXT_SCAN_GET_CAP_REQ = 271, + WLAN_HAL_EXT_SCAN_GET_CAP_RSP = 272, + WLAN_HAL_EXT_SCAN_STOP_REQ = 273, + WLAN_HAL_EXT_SCAN_STOP_RSP = 274, + WLAN_HAL_EXT_SCAN_GET_SCAN_REQ = 275, + WLAN_HAL_EXT_SCAN_GET_SCAN_RSP = 276, + + WLAN_HAL_BSSID_HOTLIST_SET_REQ = 277, + WLAN_HAL_BSSID_HOTLIST_SET_RSP = 278, + WLAN_HAL_BSSID_HOTLIST_RESET_REQ = 279, + WLAN_HAL_BSSID_HOTLIST_RESET_RSP = 280, + + WLAN_HAL_SIG_RSSI_SET_REQ = 281, + WLAN_HAL_SIG_RSSI_SET_RSP = 282, + WLAN_HAL_SIG_RSSI_RESET_REQ = 283, + WLAN_HAL_SIG_RSSI_RESET_RSP = 284, + + WLAN_HAL_EXT_SCAN_RESULT_IND = 285, + WLAN_HAL_BSSID_HOTLIST_RESULT_IND = 286, + WLAN_HAL_SIG_RSSI_RESULT_IND = 287, + WLAN_HAL_EXT_SCAN_PROGRESS_IND = 288, + WLAN_HAL_EXT_SCAN_RESULT_AVAILABLE_IND = 289, + WLAN_HAL_TDLS_CHAN_SWITCH_REQ = 290, + WLAN_HAL_TDLS_CHAN_SWITCH_RSP = 291, + WLAN_HAL_MAC_SPOOFED_SCAN_REQ = 292, + WLAN_HAL_MAC_SPOOFED_SCAN_RSP = 293, + /* LGE DISA encrypt-decrypt Messages */ + WLAN_HAL_ENCRYPT_DATA_REQ = 294, + WLAN_HAL_ENCRYPT_DATA_RSP = 295, + + WLAN_HAL_FW_STATS_REQ = 296, + WLAN_HAL_FW_STATS_RSP = 297, + WLAN_HAL_FW_LOGGING_INIT_REQ = 298, + WLAN_HAL_FW_LOGGING_INIT_RSP = 299, + WLAN_HAL_GET_FRAME_LOG_REQ = 300, + WLAN_HAL_GET_FRAME_LOG_RSP = 301, + + /* Monitor Mode */ + WLAN_HAL_ENABLE_MONITOR_MODE_REQ = 302, + WLAN_HAL_ENABLE_MONITOR_MODE_RSP = 303, + + WLAN_HAL_DISABLE_MONITOR_MODE_REQ = 304, + WLAN_HAL_DISABLE_MONITOR_MODE_RSP = 305, + + WLAN_HAL_SET_RTS_CTS_HTVHT_IND = 306, + // FW Logging + WLAN_HAL_FATAL_EVENT_LOGGING_REQ = 307, + WLAN_HAL_FATAL_EVENT_LOGGING_RSP = 308, + WLAN_HAL_FW_MEMORY_DUMP_REQ = 309, + WLAN_HAL_FW_MEMORY_DUMP_RSP = 310, + WLAN_HAL_FW_LOGGING_DXE_DONE_IND = 311, + WLAN_HAL_LOST_LINK_PARAMETERS_IND = 312, + WLAN_HAL_SEND_FREQ_RANGE_CONTROL_IND = 313, + + WLAN_HAL_SSID_HOTLIST_SET_REQ = 314, + WLAN_HAL_SSID_HOTLIST_SET_RSP = 315, + WLAN_HAL_SSID_HOTLIST_RESET_REQ = 316, + WLAN_HAL_SSID_HOTLIST_RESET_RSP = 317, + + WLAN_HAL_SSID_HOTLIST_RESULT_IND = 318, + + /* WFD Session Information to start/stop Scan */ + WLAN_HAL_HIGH_PRIORITY_DATA_INFO_REQ = 319, + + WLAN_HAL_START_RSSI_MONITORING_REQ = 321, + WLAN_HAL_START_RSSI_MONITORING_RSP = 322, + WLAN_HAL_RSSI_MONITORING_IND = 323, + WLAN_HAL_STOP_RSSI_MONITORING_REQ = 324, + WLAN_HAL_STOP_RSSI_MONITORING_RSP = 325, + + //RTT3 SUPPORT + WLAN_HAL_START_OEM_DATA_REQ_IND_NEW = 326, + WLAN_HAL_START_OEM_DATA_RSP_IND_NEW = 327, + + WLAN_HAL_WIFI_CONFIG_SET_PARAMS_REQ = 328, + WLAN_HAL_WIFI_CONFIG_SET_PARAMS_RSP = 329, + + WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_REQ = 330, + WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_RSP = 331, + WLAN_HAL_MODIFY_ROAM_PARAMS_IND = 332, + WLAN_HAL_SET_ALLOWED_ACTION_FRAMES_IND = 333, + + /* PER based roaming support */ + WLAN_HAL_SET_PER_ROAM_CONFIG_REQ = 334, + WLAN_HAL_SET_PER_ROAM_CONFIG_RSP = 335, + WLAN_HAL_PER_ROAM_SCAN_TRIGGER_REQ = 336, + WLAN_HAL_PER_ROAM_SCAN_TRIGGER_RSP = 337, + + WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ = 339, + WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP = 340, + WLAN_HAL_SAP_AUTH_OFFLOAD_IND = 341, + WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ = 342, + WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP = 343, + WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ = 344, + WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP = 345, + WLAN_HAL_MDNS_RESP_OFFLOAD_REQ = 346, + WLAN_HAL_MDNS_RESP_OFFLOAD_RSP = 347, + WLAN_HAL_MDNS_STATS_OFFLOAD_REQ = 348, + WLAN_HAL_MDNS_STATS_OFFLOAD_RSP = 349, + + /* QRF Support */ + WLAN_HAL_QRF_AP_FIND_COMMAND = 350, + WLAN_HAL_QRF_PREF_NETW_FOUND_IND = 351, + WLAN_HAL_CAPTURE_GET_TSF_TSTAMP = 352, + WLAN_HAL_CAPTURE_GET_TSF_TSTAMP_RSP = 353, + /* ARP DEBUG stats*/ + WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ = 354, + WLAN_HAL_FW_SET_CLEAR_ARP_STATS_RSP = 355, + WLAN_HAL_FW_GET_ARP_STATS_REQ = 356, + WLAN_HAL_FW_GET_ARP_STATS_RSP = 357, + + WLAN_HAL_MSG_MAX = WLAN_HAL_MSG_TYPE_MAX_ENUM_SIZE +}tHalHostMsgType; + +/* Enumeration for Version */ +typedef enum +{ + WLAN_HAL_MSG_VERSION0 = 0, + WLAN_HAL_MSG_VERSION1 = 1, + WLAN_HAL_MSG_WCNSS_CTRL_VERSION = 0x7FFF, /*define as 2 bytes data*/ + WLAN_HAL_MSG_VERSION_MAX_FIELD = WLAN_HAL_MSG_WCNSS_CTRL_VERSION +}tHalHostMsgVersion; + +/* Enumeration for Boolean - False/True, On/Off */ +typedef enum tagAniBoolean +{ + eANI_BOOLEAN_FALSE = 0, + eANI_BOOLEAN_TRUE, + eANI_BOOLEAN_OFF = 0, + eANI_BOOLEAN_ON = 1, + eANI_BOOLEAN_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ +} eAniBoolean; + +typedef enum +{ + eDRIVER_TYPE_PRODUCTION = 0, + eDRIVER_TYPE_MFG = 1, + eDRIVER_TYPE_DVT = 2, + eDRIVER_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tDriverType; + +typedef enum +{ + HAL_STOP_TYPE_SYS_RESET, + HAL_STOP_TYPE_SYS_DEEP_SLEEP, + HAL_STOP_TYPE_RF_KILL, + HAL_STOP_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tHalStopType; + +typedef enum +{ + eHAL_SYS_MODE_NORMAL, + eHAL_SYS_MODE_LEARN, + eHAL_SYS_MODE_SCAN, + eHAL_SYS_MODE_PROMISC, + eHAL_SYS_MODE_SUSPEND_LINK, + eHAL_SYS_MODE_ROAM_SCAN, + eHAL_SYS_MODE_ROAM_SUSPEND_LINK, + eHAL_SYS_MODE_OEM_DATA, + eHAL_SYS_MODE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} eHalSysMode; + +typedef enum +{ + eHAL_CHANNEL_SWITCH_SOURCE_SCAN, + eHAL_CHANNEL_SWITCH_SOURCE_LISTEN, + eHAL_CHANNEL_SWITCH_SOURCE_MCC, + eHAL_CHANNEL_SWITCH_SOURCE_CSA, + eHAL_CHANNEL_SWITCH_SOURCE_CONFIG_BSS, + eHAL_CHANNEL_SWITCH_SOURCE_CONFIG_STA, + eHAL_CHANNEL_SWITCH_SOURCE_JOIN_REQ, + eHAL_CHANNEL_SWITCH_SOURCE_INNAV, + eHAL_CHANNEL_SWITCH_SOURCE_WCA, + eHAL_CHANNEL_SWITCH_SOURCE_MLME, + eHAL_CHANNEL_SWITCH_SOURCE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} eHalChanSwitchSource; + +typedef enum +{ + PHY_SINGLE_CHANNEL_CENTERED = 0, // 20MHz IF bandwidth centered on IF carrier + PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, // 40MHz IF bandwidth with lower 20MHz supporting the primary channel + PHY_DOUBLE_CHANNEL_CENTERED = 2, // 40MHz IF bandwidth centered on IF carrier + PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, // 40MHz IF bandwidth with higher 20MHz supporting the primary channel +#ifdef WLAN_FEATURE_11AC + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, //20/40MHZ offset LOW 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, //20/40MHZ offset CENTERED 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, //20/40MHZ offset HIGH 40/80MHZ offset CENTERED + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7,//20/40MHZ offset LOW 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, //20/40MHZ offset HIGH 40/80MHZ offset LOW + PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, //20/40MHZ offset LOW 40/80MHZ offset HIGH + PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10,//20/40MHZ offset-HIGH 40/80MHZ offset HIGH +#endif + PHY_CHANNEL_BONDING_STATE_MAX = WLAN_HAL_MAX_ENUM_SIZE +}ePhyChanBondState; + +// Spatial Multiplexing(SM) Power Save mode +typedef enum eSirMacHTMIMOPowerSaveState +{ + eSIR_HT_MIMO_PS_STATIC = 0, // Static SM Power Save mode + eSIR_HT_MIMO_PS_DYNAMIC = 1, // Dynamic SM Power Save mode + eSIR_HT_MIMO_PS_NA = 2, // reserved + eSIR_HT_MIMO_PS_NO_LIMIT = 3, // SM Power Save disabled + eSIR_HT_MIMO_PS_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSirMacHTMIMOPowerSaveState; + +/* each station added has a rate mode which specifies the sta attributes */ +typedef enum eStaRateMode { + eSTA_TAURUS = 0, + eSTA_TITAN, + eSTA_POLARIS, + eSTA_11b, + eSTA_11bg, + eSTA_11a, + eSTA_11n, +#ifdef WLAN_FEATURE_11AC + eSTA_11ac, +#endif + eSTA_INVALID_RATE_MODE = WLAN_HAL_MAX_ENUM_SIZE +} tStaRateMode, *tpStaRateMode; + +#define SIR_NUM_11B_RATES 4 //1,2,5.5,11 +#define SIR_NUM_11A_RATES 8 //6,9,12,18,24,36,48,54 +#define SIR_NUM_POLARIS_RATES 3 //72,96,108 + +#define SIR_MAC_MAX_SUPPORTED_MCS_SET 16 + + +typedef enum eSirBssType +{ + eSIR_INFRASTRUCTURE_MODE, + eSIR_INFRA_AP_MODE, //Added for softAP support + eSIR_IBSS_MODE, + eSIR_BTAMP_STA_MODE, //Added for BT-AMP support + eSIR_BTAMP_AP_MODE, //Added for BT-AMP support + eSIR_AUTO_MODE, + eSIR_DONOT_USE_BSS_TYPE = WLAN_HAL_MAX_ENUM_SIZE +} tSirBssType; + +typedef enum eSirNwType +{ + eSIR_11A_NW_TYPE, + eSIR_11B_NW_TYPE, + eSIR_11G_NW_TYPE, + eSIR_11N_NW_TYPE, + eSIR_DONOT_USE_NW_TYPE = WLAN_HAL_MAX_ENUM_SIZE +} tSirNwType; + +typedef tANI_U16 tSirMacBeaconInterval; + +#define SIR_MAC_RATESET_EID_MAX 12 + +typedef enum eSirMacHTOperatingMode +{ + eSIR_HT_OP_MODE_PURE, // No Protection + eSIR_HT_OP_MODE_OVERLAP_LEGACY, // Overlap Legacy device present, protection is optional + eSIR_HT_OP_MODE_NO_LEGACY_20MHZ_HT, // No legacy device, but 20 MHz HT present + eSIR_HT_OP_MODE_MIXED, // Protection is required + eSIR_HT_OP_MODE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSirMacHTOperatingMode; + +/// Encryption type enum used with peer +typedef enum eAniEdType +{ + eSIR_ED_NONE, + eSIR_ED_WEP40, + eSIR_ED_WEP104, + eSIR_ED_TKIP, + eSIR_ED_CCMP, + eSIR_ED_WPI, + eSIR_ED_AES_128_CMAC, + eSIR_ED_NOT_IMPLEMENTED = WLAN_HAL_MAX_ENUM_SIZE +} tAniEdType; + +#define WLAN_MAX_KEY_RSC_LEN 16 +#define WLAN_WAPI_KEY_RSC_LEN 16 + +/// MAX key length when ULA is used +#define SIR_MAC_MAX_KEY_LENGTH 32 +#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4 + +/// Enum to specify whether key is used +/// for TX only, RX only or both +typedef enum eAniKeyDirection +{ + eSIR_TX_ONLY, + eSIR_RX_ONLY, + eSIR_TX_RX, + eSIR_TX_DEFAULT, + eSIR_DONOT_USE_KEY_DIRECTION = WLAN_HAL_MAX_ENUM_SIZE +} tAniKeyDirection; + +typedef enum eAniWepType +{ + eSIR_WEP_STATIC, + eSIR_WEP_DYNAMIC, + eSIR_WEP_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tAniWepType; + +typedef enum eSriLinkState { + + eSIR_LINK_IDLE_STATE = 0, + eSIR_LINK_PREASSOC_STATE = 1, + eSIR_LINK_POSTASSOC_STATE = 2, + eSIR_LINK_AP_STATE = 3, + eSIR_LINK_IBSS_STATE = 4, + + /* BT-AMP Case */ + eSIR_LINK_BTAMP_PREASSOC_STATE = 5, + eSIR_LINK_BTAMP_POSTASSOC_STATE = 6, + eSIR_LINK_BTAMP_AP_STATE = 7, + eSIR_LINK_BTAMP_STA_STATE = 8, + + /* Reserved for HAL Internal Use */ + eSIR_LINK_LEARN_STATE = 9, + eSIR_LINK_SCAN_STATE = 10, + eSIR_LINK_FINISH_SCAN_STATE = 11, + eSIR_LINK_INIT_CAL_STATE = 12, + eSIR_LINK_FINISH_CAL_STATE = 13, +#ifdef WLAN_FEATURE_P2P + eSIR_LINK_LISTEN_STATE = 14, + eSIR_LINK_SEND_ACTION_STATE = 15, +#endif +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + eSIR_LINK_FT_PREASSOC_STATE = 16, +#endif +#ifdef WLAN_FEATURE_LFR_MBB + eSIR_LINK_PRE_AUTH_REASSOC_STATE = 17, +#endif + eSIR_LINK_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSirLinkState; + +typedef enum +{ + HAL_SUMMARY_STATS_INFO = 0x00000001, + HAL_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, + HAL_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, + HAL_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, + HAL_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, + HAL_PER_STA_STATS_INFO = 0x00000020, + HAL_PER_TX_PKT_STATS_INFO = 0x00000040 +}eHalStatsMask; + +/* BT-AMP events type */ +typedef enum +{ + BTAMP_EVENT_CONNECTION_START, + BTAMP_EVENT_CONNECTION_STOP, + BTAMP_EVENT_CONNECTION_TERMINATED, + BTAMP_EVENT_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE, //This and beyond are invalid values +} tBtAmpEventType; + +//*************************************************************** + + +/*******************PE Statistics*************************/ +typedef enum +{ + PE_SUMMARY_STATS_INFO = 0x00000001, + PE_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, + PE_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, + PE_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, + PE_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, + PE_PER_STA_STATS_INFO = 0x00000020, + PE_PER_TX_PKT_STATS_INFO = 0x00000040, + PE_STATS_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE //This and beyond are invalid values +}ePEStatsMask; + + +/******************************LINK LAYER Statitics**********************/ + +typedef int wifi_radio; +typedef int wifi_channel; +typedef int wifi_tx_rate; + +/* channel operating width */ +typedef enum { + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, +} wifi_channel_width; + +typedef enum { + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, // if done by firmware/driver + WIFI_EAPOL_COMPLETED = 5, // if done by firmware/driver +} wifi_connection_state; + +typedef enum { + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +} wifi_roam_state; + +typedef enum { + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + } wifi_interface_mode; + +#define WIFI_CAPABILITY_QOS 0x00000001 // set for QOS association +#define WIFI_CAPABILITY_PROTECTED 0x00000002 // set for protected association (802.11 beacon frame control protected bit set) +#define WIFI_CAPABILITY_INTERWORKING 0x00000004 // set if 802.11 Extended Capabilities element interworking bit is set +#define WIFI_CAPABILITY_HS20 0x00000008 // set for HS20 association +#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 // set is 802.11 Extended Capabilities element UTF-8 SSID bit is set +#define WIFI_CAPABILITY_COUNTRY 0x00000020 // set is 802.11 Country Element is present + +typedef PACKED_PRE struct PACKED_POST +{ + wifi_interface_mode mode; // interface mode + tANI_U8 mac_addr[6]; // interface mac address (self) + wifi_connection_state state; // connection state (valid for STA, CLI only) + wifi_roam_state roaming; // roaming state + tANI_U32 capabilities; // WIFI_CAPABILITY_XXX (self) + tANI_U8 ssid[33]; // null terminated SSID + tANI_U8 bssid[6]; // bssid + tANI_U8 ap_country_str[3]; // country string advertised by AP + tANI_U8 country_str[3]; // country string for this association +} wifi_interface_info; + +/* channel information */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_channel_width width; // channel width (20, 40, 80, 80+80, 160) + wifi_channel center_freq; // primary 20 MHz channel + wifi_channel center_freq0; // center frequency (MHz) first segment + wifi_channel center_freq1; // center frequency (MHz) second segment +} wifi_channel_info; + +/* wifi rate info */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 preamble :3; // 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved + tANI_U32 nss :2; // 0:1x1, 1:2x2, 3:3x3, 4:4x4 + tANI_U32 bw :3; // 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz + tANI_U32 rateMcsIdx :8; // OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps + // HT/VHT it would be mcs index + tANI_U32 reserved :16; // reserved + tANI_U32 bitrate; // units of 100 Kbps +} wifi_rate; + +/* channel statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_channel_info channel; // channel + tANI_U32 on_time; // msecs the radio is awake (32 bits number accruing over time) + tANI_U32 cca_busy_time; // msecs the CCA register is busy (32 bits number accruing over time) +} wifi_channel_stats; + +/* radio statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_radio radio; // wifi radio (if multiple radio supported) + tANI_U32 on_time; // msecs the radio is awake (32 bits number accruing over time) + tANI_U32 tx_time; // msecs the radio is transmitting (32 bits number accruing over time) + tANI_U32 rx_time; // msecs the radio is in active receive (32 bits number accruing over time) + tANI_U32 on_time_scan; // msecs the radio is awake due to all scan (32 bits number accruing over time) + tANI_U32 on_time_nbd; // msecs the radio is awake due to NAN (32 bits number accruing over time) + tANI_U32 on_time_gscan; // msecs the radio is awake due to G?scan (32 bits number accruing over time) + tANI_U32 on_time_roam_scan; // msecs the radio is awake due to roam?scan (32 bits number accruing over time) + tANI_U32 on_time_pno_scan; // msecs the radio is awake due to PNO scan (32 bits number accruing over time) + tANI_U32 on_time_hs20; // msecs the radio is awake due to HS2.0 scans and GAS exchange (32 bits number accruing over time) + tANI_U32 num_channels; // number of channels + wifi_channel_stats channels[1]; // channel statistics +} wifi_radio_stat; + +/* per rate statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_rate rate; // rate information * + tANI_U32 tx_mpdu; // number of successfully transmitted data pkts (ACK rcvd) * + tANI_U32 rx_mpdu; // number of received data pkts + tANI_U32 mpdu_lost; // number of data packet losses (no ACK) + tANI_U32 retries; // total number of data pkt retries * + tANI_U32 retries_short; // number of short data pkt retries + tANI_U32 retries_long; // number of long data pkt retries +} wifi_rate_stat; + +/* access categories */ +typedef enum { + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +} wifi_traffic_ac; + +/* wifi peer type */ +typedef enum +{ + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +} wifi_peer_type; + +/* per peer statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_peer_type type; // peer type (AP, TDLS, GO etc.) + tANI_U8 peer_mac_address[6]; // mac address + tANI_U32 capabilities; // peer WIFI_CAPABILITY_XXX + tANI_U32 num_rate; // number of rates + wifi_rate_stat rate_stats[1]; // per rate statistics, number of entries = num_rate +} wifi_peer_info; + +/* per access category statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_traffic_ac ac; // access category (VI, VO, BE, BK) + tANI_U32 tx_mpdu; // number of successfully transmitted unicast data pkts (ACK rcvd) + tANI_U32 rx_mpdu; // number of received unicast mpdus + tANI_U32 tx_mcast; // number of succesfully transmitted multicast data packets + // STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent + tANI_U32 rx_mcast; // number of received multicast data packets + tANI_U32 rx_ampdu; // number of received unicast a-mpdus + tANI_U32 tx_ampdu; // number of transmitted unicast a-mpdus + tANI_U32 mpdu_lost; // number of data pkt losses (no ACK) + tANI_U32 retries; // total number of data pkt retries + tANI_U32 retries_short; // number of short data pkt retries + tANI_U32 retries_long; // number of long data pkt retries + tANI_U32 contention_time_min; // data pkt min contention time (usecs) + tANI_U32 contention_time_max; // data pkt max contention time (usecs) + tANI_U32 contention_time_avg; // data pkt avg contention time (usecs) + tANI_U32 contention_num_samples; // num of data pkts used for contention statistics +} wifi_wmm_ac_stat; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U64 average_tsf_offset; + tANI_U32 leaky_ap_avg_num_frames_leaked; + tANI_U32 leaky_ap_guard_time; + tANI_U32 leaky_ap_detected; +} wifi_iface_leaky_ap_info; + +/* Interface statistics - corresponding to 2nd most LSB in wifi statistics bitmap for getting statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + wifi_interface_info info; // current state of the interface + tANI_U32 beacon_rx; // access point beacon received count from connected AP + tANI_U32 mgmt_rx; // access point mgmt frames received count from connected AP (including Beacon) + tANI_U32 mgmt_action_rx; // action frames received count + tANI_U32 mgmt_action_tx; // action frames transmit count + tANI_U32 rssi_mgmt; // access Point Beacon and Management frames RSSI (averaged) + tANI_U32 rssi_data; // access Point Data Frames RSSI (averaged) from connected AP + tANI_U32 rssi_ack; // access Point ACK RSSI (averaged) from connected AP + wifi_wmm_ac_stat AccessclassStats[WIFI_AC_MAX]; // per ac data packet statistics + wifi_iface_leaky_ap_info leakyApInfo; +} wifi_iface_stat; + +/* Peer statistics - corresponding to 3rd most LSB in wifi statistics bitmap for getting statistics */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 num_peers; // number of peers + wifi_peer_info peer_info[1]; // per peer statistics +} wifi_peer_stat; + +/* wifi statistics bitmap for getting statistics */ +#define WMI_LINK_STATS_RADIO 0x00000001 +#define WMI_LINK_STATS_IFACE 0x00000002 +#define WMI_LINK_STATS_ALL_PEER 0x00000004 +#define WMI_LINK_STATS_PER_PEER 0x00000008 + +/* wifi statistics bitmap for clearing statistics */ +#define WIFI_STATS_RADIO 0x00000001 // all radio statistics +#define WIFI_STATS_RADIO_CCA 0x00000002 // cca_busy_time (within radio statistics) +#define WIFI_STATS_RADIO_CHANNELS 0x00000004 // all channel statistics (within radio statistics) +#define WIFI_STATS_RADIO_SCAN 0x00000008 // all scan statistics (within radio statistics) +#define WIFI_STATS_IFACE 0x00000010 // all interface statistics +#define WIFI_STATS_IFACE_TXRATE 0x00000020 // all tx rate statistics (within interface statistics) +#define WIFI_STATS_IFACE_AC 0x00000040 // all ac statistics (within interface statistics) +#define WIFI_STATS_IFACE_CONTENTION 0x00000080 // all contention (min, max, avg) statistics (within ac statisctics) + + +/*--------------------------------------------------------------------------- + Message definitons - All the messages below need to be packed + ---------------------------------------------------------------------------*/ + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack(push, 1) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#pragma pack(1) +#else +#endif + +/// Definition for HAL API Version. +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 revision; + tANI_U8 version; + tANI_U8 minor; + tANI_U8 major; +} tWcnssWlanVersion, *tpWcnssWlanVersion; + +/// Definition for Encryption Keys +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 keyId; + tANI_U8 unicast; // 0 for multicast + tAniKeyDirection keyDirection; + tANI_U8 keyRsc[WLAN_MAX_KEY_RSC_LEN]; // Usage is unknown + tANI_U8 paeRole; // =1 for authenticator,=0 for supplicant + tANI_U16 keyLength; + tANI_U8 key[SIR_MAC_MAX_KEY_LENGTH]; +} tSirKeys, *tpSirKeys; + + +//SetStaKeyParams Moving here since it is shared by configbss/setstakey msgs +typedef PACKED_PRE struct PACKED_POST +{ + /*STA Index*/ + tANI_U16 staIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*STATIC/DYNAMIC - valid only for WEP*/ + tAniWepType wepType; + + /*Default WEP key, valid only for static WEP, must between 0 and 3.*/ + tANI_U8 defWEPIdx; + + /* valid only for non-static WEP encyrptions */ + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + tANI_U8 singleTidRc; + +} tSetStaKeyParams, *tpSetStaKeyParams; + + + +/* 4-byte control message header used by HAL*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalHostMsgType msgType:16; + tHalHostMsgVersion msgVersion:16; + tANI_U32 msgLen; +} tHalMsgHeader, *tpHalMsgHeader; + +/* Config format required by HAL for each CFG item*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Cfg Id. The Id required by HAL is exported by HAL + * in shared header file between UMAC and HAL.*/ + tANI_U16 uCfgId; + + /* Length of the Cfg. This parameter is used to go to next cfg + * in the TLV format.*/ + tANI_U16 uCfgLen; + + /* Padding bytes for unaligned address's */ + tANI_U16 uCfgPadBytes; + + /* Reserve bytes for making cfgVal to align address */ + tANI_U16 uCfgReserve; + + /* Following the uCfgLen field there should be a 'uCfgLen' bytes + * containing the uCfgValue ; tANI_U8 uCfgValue[uCfgLen] */ +} tHalCfg, *tpHalCfg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST sHalMacStartParameters +{ + /* Drive Type - Production or FTM etc */ + tDriverType driverType; + + /*Length of the config buffer*/ + tANI_U32 uConfigBufferLen; + + /* Following this there is a TLV formatted buffer of length + * "uConfigBufferLen" bytes containing all config values. + * The TLV is expected to be formatted like this: + * 0 15 31 31+CFG_LEN-1 length-1 + * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| + */ +} tHalMacStartParameters, *tpHalMacStartParameters; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalMacStartReqMsg messages should be + * header.msgLen = sizeof(tHalMacStartReqMsg) + uConfigBufferLen */ + tHalMsgHeader header; + tHalMacStartParameters startReqParams; +} tHalMacStartReqMsg, *tpHalMacStartReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST sHalMacStartRspParameters +{ + /*success or failure */ + tANI_U16 status; + + /*Max number of STA supported by the device*/ + tANI_U8 ucMaxStations; + + /*Max number of BSS supported by the device*/ + tANI_U8 ucMaxBssids; + + /*API Version */ + tWcnssWlanVersion wcnssWlanVersion; + + /*CRM build information */ + tANI_U8 wcnssCrmVersionString[WLAN_HAL_VERSION_LENGTH]; + + /*hardware/chipset/misc version information */ + tANI_U8 wcnssWlanVersionString[WLAN_HAL_VERSION_LENGTH]; + +} tHalMacStartRspParams, *tpHalMacStartRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacStartRspParams startRspParams; +} tHalMacStartRspMsg, *tpHalMacStartRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_STOP_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*The reason for which the device is being stopped*/ + tHalStopType reason; + +}tHalMacStopReqParams, *tpHalMacStopReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacStopReqParams stopReqParams; +} tHalMacStopReqMsg, *tpHalMacStopReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_STOP_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalMacStopRspParams, *tpHalMacStopRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacStopRspParams stopRspParams; +} tHalMacStopRspMsg, *tpHalMacStopRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_UPDATE_CFG_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Length of the config buffer. Allows UMAC to update multiple CFGs */ + tANI_U32 uConfigBufferLen; + + /* Following this there is a TLV formatted buffer of length + * "uConfigBufferLen" bytes containing all config values. + * The TLV is expected to be formatted like this: + * 0 15 31 31+CFG_LEN-1 length-1 + * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| + */ +} tHalUpdateCfgReqParams, *tpHalUpdateCfgReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalUpdateCfgReqMsg messages should be + * header.msgLen = sizeof(tHalUpdateCfgReqMsg) + uConfigBufferLen */ + tHalMsgHeader header; + tHalUpdateCfgReqParams updateCfgReqParams; +} tHalUpdateCfgReqMsg, *tpHalUpdateCfgReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_UPDATE_CFG_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + +}tHalUpdateCfgRspParams, *tpHalUpdateCfgRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalUpdateCfgRspParams updateCfgRspParams; +} tHalUpdateCfgRspMsg, *tpHalUpdateCfgRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_INIT_SCAN_REQ +---------------------------------------------------------------------------*/ + +/// Frame control field format (2 bytes) +typedef __ani_attr_pre_packed struct sSirMacFrameCtl +{ + +#ifndef ANI_LITTLE_BIT_ENDIAN + + tANI_U8 subType :4; + tANI_U8 type :2; + tANI_U8 protVer :2; + + tANI_U8 order :1; + tANI_U8 wep :1; + tANI_U8 moreData :1; + tANI_U8 powerMgmt :1; + tANI_U8 retry :1; + tANI_U8 moreFrag :1; + tANI_U8 fromDS :1; + tANI_U8 toDS :1; + +#else + + tANI_U8 protVer :2; + tANI_U8 type :2; + tANI_U8 subType :4; + + tANI_U8 toDS :1; + tANI_U8 fromDS :1; + tANI_U8 moreFrag :1; + tANI_U8 retry :1; + tANI_U8 powerMgmt :1; + tANI_U8 moreData :1; + tANI_U8 wep :1; + tANI_U8 order :1; + +#endif + +} __ani_attr_packed tSirMacFrameCtl, *tpSirMacFrameCtl; + +/// Sequence control field +typedef __ani_attr_pre_packed struct sSirMacSeqCtl +{ + tANI_U8 fragNum : 4; + tANI_U8 seqNumLo : 4; + tANI_U8 seqNumHi : 8; +} __ani_attr_packed tSirMacSeqCtl, *tpSirMacSeqCtl; + +/// Management header format +typedef __ani_attr_pre_packed struct sSirMacMgmtHdr +{ + tSirMacFrameCtl fc; + tANI_U8 durationLo; + tANI_U8 durationHi; + tANI_U8 da[6]; + tANI_U8 sa[6]; + tANI_U8 bssId[6]; + tSirMacSeqCtl seqControl; +} __ani_attr_packed tSirMacMgmtHdr, *tpSirMacMgmtHdr; + +/// Scan Entry to hold active BSS idx's +typedef __ani_attr_pre_packed struct sSirScanEntry +{ + tANI_U8 bssIdx[HAL_NUM_BSSID]; + tANI_U8 activeBSScnt; +}__ani_attr_packed tSirScanEntry, *ptSirScanEntry; + +typedef PACKED_PRE struct PACKED_POST { + + /*LEARN - AP Role + SCAN - STA Role*/ + eHalSysMode scanMode; + + /*BSSID of the BSS*/ + tSirMacAddr bssid; + + /*Whether BSS needs to be notified*/ + tANI_U8 notifyBss; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + tANI_U8 frameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + tANI_U8 frameLength; + + /* Following the framelength there is a MAC frame buffer if frameLength + is non-zero. */ + tSirMacMgmtHdr macMgmtHdr; + + /*Entry to hold number of active BSS idx's*/ + tSirScanEntry scanEntry; + +} tInitScanParams, * tpInitScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tInitScanParams initScanParams; +} tHalInitScanReqMsg, *tpHalInitScanReqMsg; + +typedef PACKED_PRE struct PACKED_POST { + + /*LEARN - AP Role + SCAN - STA Role*/ + eHalSysMode scanMode; + + /*BSSID of the BSS*/ + tSirMacAddr bssid; + + /*Whether BSS needs to be notified*/ + tANI_U8 notifyBss; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + tANI_U8 frameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + tANI_U8 frameLength; + + /* Following the framelength there is a MAC frame buffer if frameLength + is non-zero. */ + tSirMacMgmtHdr macMgmtHdr; + + /*Entry to hold number of active BSS idx's*/ + tSirScanEntry scanEntry; + + /* Single NoA usage in Scanning */ + tANI_U8 useNoA; + + /* Indicates the scan duration (in ms) */ + tANI_U16 scanDuration; + +} tInitScanConParams, * tpInitScanConParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tInitScanConParams initScanParams; +} tHalInitScanConReqMsg, *tpHalInitScanConReqMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_INIT_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalInitScanRspParams, *tpHalInitScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalInitScanRspParams initScanRspParams; +} tHalInitScanRspMsg, *tpHalInitScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_SCAN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Indicates the channel to scan*/ + tANI_U8 scanChannel; + + } tStartScanParams, * tpStartScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartScanParams startScanParams; +} tHalStartScanReqMsg, *tpHalStartScanReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalMotionEventReqMsg, *tpHalMotionEventReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_START_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + tANI_U32 startTSF[2]; + tPowerdBm txMgmtPower; + +}tHalStartScanRspParams, *tpHalStartScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStartScanRspParams startScanRspParams; +} tHalStartScanRspMsg, *tpHalStartScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_END_SCAN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Indicates the channel to stop scanning. Not used really. But retained + for symmetry with "start Scan" message. It can also help in error + check if needed.*/ + tANI_U8 scanChannel; + +} tEndScanParams, *tpEndScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEndScanParams endScanParams; +} tHalEndScanReqMsg, *tpHalEndScanReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_END_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalEndScanRspParams, *tpHalEndScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEndScanRspParams endScanRspParams; +} tHalEndScanRspMsg, *tpHalEndScanRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_FINISH_SCAN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Identifies the operational state of the AP/STA + * LEARN - AP Role SCAN - STA Role */ + eHalSysMode scanMode; + + /*Operating channel to tune to.*/ + tANI_U8 currentOperChannel; + + /*Channel Bonding state If 20/40 MHz is operational, this will indicate the + 40 MHz extension channel in combination with the control channel*/ + ePhyChanBondState cbState; + + /*BSSID of the BSS*/ + tSirMacAddr bssid; + + /*Whether BSS needs to be notified*/ + tANI_U8 notifyBss; + + /*Kind of frame to be used for notifying the BSS (Data Null, QoS Null, or + CTS to Self). Must always be a valid frame type.*/ + tANI_U8 frameType; + + /*UMAC has the option of passing the MAC frame to be used for notifying + the BSS. If non-zero, HAL will use the MAC frame buffer pointed to by + macMgmtHdr. If zero, HAL will generate the appropriate MAC frame based on + frameType.*/ + tANI_U8 frameLength; + + /*Following the framelength there is a MAC frame buffer if frameLength + is non-zero.*/ + tSirMacMgmtHdr macMgmtHdr; + + /*Entry to hold number of active BSS idx's*/ + tSirScanEntry scanEntry; + +} tFinishScanParams, *tpFinishScanParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tFinishScanParams finishScanParams; +} tHalFinishScanReqMsg, *tpHalFinishScanReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_FINISH_SCAN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +}tHalFinishScanRspParams, *tpHalFinishScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalFinishScanRspParams finishScanRspParams; +} tHalFinishScanRspMsg, *tpHalFinishScanRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tSetStaKeyParams keyParams; + uint8 pn[6]; +} tHalEncConfigParams; + +typedef PACKED_PRE struct PACKED_POST +{ + uint16 length; + uint8 data[DISA_MAX_PAYLOAD_SIZE]; +} tHalDisaPayload; + +typedef PACKED_PRE struct PACKED_POST +{ +#ifdef BYTE_ORDER_BIG_ENDIAN + uint8 reserved1 : 1; + uint8 ackpolicy : 2; + uint8 eosp : 1; + uint8 tid : 4; + + uint8 appsbufferstate : 8; +#else + uint8 appsbufferstate : 8; + + uint8 tid : 4; + uint8 eosp : 1; + uint8 ackpolicy : 2; + uint8 reserved1 : 1; +#endif +} tHalQosCtrlFieldType; + +typedef PACKED_PRE struct PACKED_POST + { +#ifdef BYTE_ORDER_BIG_ENDIAN + uint16 subtype : 4; + uint16 type : 2; + uint16 protocol : 2; + + uint16 order : 1; + uint16 wep : 1; + uint16 moredata : 1; + uint16 pm : 1; + uint16 retry : 1; + uint16 morefrag : 1; + uint16 fromds : 1; + uint16 tods : 1; +#else + + uint16 tods : 1; + uint16 fromds : 1; + uint16 morefrag : 1; + uint16 retry : 1; + uint16 pm : 1; + uint16 moredata : 1; + uint16 wep : 1; + uint16 order : 1; + + uint16 protocol : 2; + uint16 type : 2; + uint16 subtype : 4; +#endif +} tHalFrmCtrlType; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Frame control field */ + tHalFrmCtrlType fc; + /* Duration ID */ + uint16 usDurationId; + /* Address 1 field */ + uint8 vA1[HAL_MAC_ADDR_LEN]; + /* Address 2 field */ + uint8 vA2[HAL_MAC_ADDR_LEN]; + /* Address 3 field */ + uint8 vA3[HAL_MAC_ADDR_LEN]; + /* Sequence control field */ + uint16 seqNum; + /* Optional A4 address */ + uint8 optvA4[HAL_MAC_ADDR_LEN]; + /* Optional QOS control field */ + tHalQosCtrlFieldType usQosCtrl; +} tHal80211Header; + +typedef PACKED_PRE struct PACKED_POST +{ + tHal80211Header macHeader; + tHalEncConfigParams encParams; + tHalDisaPayload data; +} tSetEncryptedDataParams, *tpSetEncryptedDataParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetEncryptedDataParams encryptedDataParams; +} tSetEncryptedDataReqMsg, *tpSetEncryptedDataReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tHalDisaPayload encryptedPayload; +} tSetEncryptedDataRspParams, *tpSetEncryptedDataRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetEncryptedDataRspParams encryptedDataRspParams; +} tSetEncryptedDataRspMsg, *tpSetEncryptedDataRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_STA_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST { + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + tStaRateMode opRateMode; + // 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps + tANI_U16 llbRates[SIR_NUM_11B_RATES]; + tANI_U16 llaRates[SIR_NUM_11A_RATES]; + tANI_U16 aniLegacyRates[SIR_NUM_POLARIS_RATES]; + tANI_U16 reserved; + + //Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + //First 26 bits are reserved for those Titan rates and + //the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved. + tANI_U32 aniEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + tANI_U8 supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + tANI_U16 rxHighestDataRate; + +} tSirSupportedRates, *tpSirSupportedRates; + +typedef PACKED_PRE struct PACKED_POST +{ + /*BSSID of STA*/ + tSirMacAddr bssId; + + /*ASSOC ID, as assigned by UMAC*/ + tANI_U16 assocId; + + /* STA entry Type: 0 - Self, 1 - Other/Peer, 2 - BSSID, 3 - BCAST */ + tANI_U8 staType; + + /*Short Preamble Supported.*/ + tANI_U8 shortPreambleSupported; + + /*MAC Address of STA*/ + tSirMacAddr staMac; + + /*Listen interval of the STA*/ + tANI_U16 listenInterval; + + /*Support for 11e/WMM*/ + tANI_U8 wmmEnabled; + + /*11n HT capable STA*/ + tANI_U8 htCapable; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*RIFS mode 0 - NA, 1 - Allowed */ + tANI_U8 rifsMode; + + /*L-SIG TXOP Protection mechanism + 0 - No Support, 1 - Supported + SG - there is global field */ + tANI_U8 lsigTxopProtection; + + /*Max Ampdu Size supported by STA. TPE programming. + 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ + tANI_U8 maxAmpduSize; + + /*Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4)*/ + tANI_U8 maxAmpduDensity; + + /*Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes*/ + tANI_U8 maxAmsduSize; + + /*Short GI support for 40Mhz packets*/ + tANI_U8 fShortGI40Mhz; + + /*Short GI support for 20Mhz packets*/ + tANI_U8 fShortGI20Mhz; + + /*Robust Management Frame (RMF) enabled/disabled*/ + tANI_U8 rmfEnabled; + + /* The unicast encryption type in the association */ + tANI_U32 encryptType; + + /*HAL should update the existing STA entry, if this flag is set. UMAC + will set this flag in case of RE-ASSOC, where we want to reuse the old + STA ID. 0 = Add, 1 = Update*/ + tANI_U8 action; + + /*U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /*Max SP Length*/ + tANI_U8 maxSPLen; + + /*11n Green Field preamble support + 0 - Not supported, 1 - Supported */ + tANI_U8 greenFieldCapable; + + /*MIMO Power Save mode*/ + tSirMacHTMIMOPowerSaveState mimoPS; + + /*Delayed BA Support*/ + tANI_U8 delayedBASupport; + + /*Max AMPDU duration in 32us*/ + tANI_U8 us32MaxAmpduDuration; + + /*HT STA should set it to 1 if it is enabled in BSS. HT STA should set + it to 0 if AP does not support it. This indication is sent to HAL and + HAL uses this flag to pickup up appropriate 40Mhz rates.*/ + tANI_U8 fDsssCckMode40Mhz; + + /* Valid STA Idx when action=Update. Set to 0xFF when invalid! + Retained for backward compalibity with existing HAL code*/ + tANI_U8 staIdx; + + /* BSSID of BSS to which station is associated. Set to 0xFF when invalid. + Retained for backward compalibity with existing HAL code*/ + tANI_U8 bssIdx; + + tANI_U8 p2pCapableSta; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 reserved; + + /*These rates are the intersection of peer and self capabilities.*/ + tSirSupportedRates supportedRates; + +} tConfigStaParams, *tpConfigStaParams; + +/*------------------------------------------------------------------------ + * WLAN_HAL_CONFIG_STA_REQ + * ----------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST { + /* + * For Self STA Entry: this represents Self Mode. + * For Peer Stations, this represents the mode of the peer. + * On Station: + * --this mode is updated when PE adds the Self Entry. + * -- OR when PE sends 'ADD_BSS' message and station context in BSS is used to indicate the mode of the AP. + * ON AP: + * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry for that BSS is used + * to indicate the self mode of the AP. + * -- OR when a station is associated, PE sends 'ADD_STA' message with this mode updated. + */ + + tStaRateMode opRateMode; + // 11b, 11a and aniLegacyRates are IE rates which gives rate in unit of 500Kbps + tANI_U16 llbRates[SIR_NUM_11B_RATES]; + tANI_U16 llaRates[SIR_NUM_11A_RATES]; + tANI_U16 aniLegacyRates[SIR_NUM_POLARIS_RATES]; + tANI_U16 reserved; + + //Taurus only supports 26 Titan Rates(no ESF/concat Rates will be supported) + //First 26 bits are reserved for those Titan rates and + //the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are reserved. + tANI_U32 aniEnhancedRateBitmap; //Titan and Taurus Rates + + /* + * 0-76 bits used, remaining reserved + * bits 0-15 and 32 should be set. + */ + tANI_U8 supportedMCSSet[SIR_MAC_MAX_SUPPORTED_MCS_SET]; + + /* + * RX Highest Supported Data Rate defines the highest data + * rate that the STA is able to receive, in unites of 1Mbps. + * This value is derived from "Supported MCS Set field" inside + * the HT capability element. + */ + tANI_U16 rxHighestDataRate; + + /* Indicates the Maximum MCS that can be received for each number + * of spacial streams */ + tANI_U16 vhtRxMCSMap; + + /*Indicate the highest VHT data rate that the STA is able to receive*/ + tANI_U16 vhtRxHighestDataRate; + + /* Indicates the Maximum MCS that can be transmitted for each number + * of spacial streams */ + tANI_U16 vhtTxMCSMap; + + /*Indicate the highest VHT data rate that the STA is able to transmit*/ + tANI_U16 vhtTxHighestDataRate; + +} tSirSupportedRates_V1, *tpSirSupportedRates_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + /*BSSID of STA*/ + tSirMacAddr bssId; + + /*ASSOC ID, as assigned by UMAC*/ + tANI_U16 assocId; + + /* STA entry Type: 0 - Self, 1 - Other/Peer, 2 - BSSID, 3 - BCAST */ + tANI_U8 staType; + + /*Short Preamble Supported.*/ + tANI_U8 shortPreambleSupported; + + /*MAC Address of STA*/ + tSirMacAddr staMac; + + /*Listen interval of the STA*/ + tANI_U16 listenInterval; + + /*Support for 11e/WMM*/ + tANI_U8 wmmEnabled; + + /*11n HT capable STA*/ + tANI_U8 htCapable; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*RIFS mode 0 - NA, 1 - Allowed */ + tANI_U8 rifsMode; + + /*L-SIG TXOP Protection mechanism + 0 - No Support, 1 - Supported + SG - there is global field */ + tANI_U8 lsigTxopProtection; + + /*Max Ampdu Size supported by STA. TPE programming. + 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ + tANI_U8 maxAmpduSize; + + /*Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4)*/ + tANI_U8 maxAmpduDensity; + + /*Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes*/ + tANI_U8 maxAmsduSize; + + /*Short GI support for 40Mhz packets*/ + tANI_U8 fShortGI40Mhz; + + /*Short GI support for 20Mhz packets*/ + tANI_U8 fShortGI20Mhz; + + /*Robust Management Frame (RMF) enabled/disabled*/ + tANI_U8 rmfEnabled; + + /* The unicast encryption type in the association */ + tANI_U32 encryptType; + + /*HAL should update the existing STA entry, if this flag is set. UMAC + will set this flag in case of RE-ASSOC, where we want to reuse the old + STA ID. 0 = Add, 1 = Update*/ + tANI_U8 action; + + /*U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /*Max SP Length*/ + tANI_U8 maxSPLen; + + /*11n Green Field preamble support + 0 - Not supported, 1 - Supported */ + tANI_U8 greenFieldCapable; + + /*MIMO Power Save mode*/ + tSirMacHTMIMOPowerSaveState mimoPS; + + /*Delayed BA Support*/ + tANI_U8 delayedBASupport; + + /*Max AMPDU duration in 32us*/ + tANI_U8 us32MaxAmpduDuration; + + /*HT STA should set it to 1 if it is enabled in BSS. HT STA should set + it to 0 if AP does not support it. This indication is sent to HAL and + HAL uses this flag to pickup up appropriate 40Mhz rates.*/ + tANI_U8 fDsssCckMode40Mhz; + + /* Valid STA Idx when action=Update. Set to 0xFF when invalid! + Retained for backward compalibity with existing HAL code*/ + tANI_U8 staIdx; + + /* BSSID of BSS to which station is associated. Set to 0xFF when invalid. + Retained for backward compalibity with existing HAL code*/ + tANI_U8 bssIdx; + + tANI_U8 p2pCapableSta; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 htLdpcEnabled:1; + tANI_U8 vhtLdpcEnabled:1; + tANI_U8 vhtTxBFEnabled:1; + tANI_U8 vhtTxMUBformeeCapable:1; + tANI_U8 reserved:4; + + /*These rates are the intersection of peer and self capabilities.*/ + tSirSupportedRates_V1 supportedRates; + + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; + +} tConfigStaParams_V1, *tpConfigStaParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + PACKED_PRE union PACKED_POST { + tConfigStaParams configStaParams; + tConfigStaParams_V1 configStaParams_V1; + } uStaParams; +} tConfigStaReqMsg, *tpConfigStaReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_STA_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Station index; valid only when 'status' field value SUCCESS */ + tANI_U8 staIdx; + + /* BSSID Index of BSS to which the station is associated */ + tANI_U8 bssIdx; + + /* DPU Index for PTK */ + tANI_U8 dpuIndex; + + /* DPU Index for GTK */ + tANI_U8 bcastDpuIndex; + + /*DPU Index for IGTK */ + tANI_U8 bcastMgmtDpuIdx; + + /*PTK DPU signature*/ + tANI_U8 ucUcastSig; + + /*GTK DPU isignature*/ + tANI_U8 ucBcastSig; + + /* IGTK DPU signature*/ + tANI_U8 ucMgmtSig; + + tANI_U8 p2pCapableSta; + +}tConfigStaRspParams, *tpConfigStaRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigStaRspParams configStaRspParams; +}tConfigStaRspMsg, *tpConfigStaRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_STA_REQ +---------------------------------------------------------------------------*/ + +/* Delete STA Request params */ +typedef PACKED_PRE struct PACKED_POST +{ + /* Index of STA to delete */ + tANI_U8 staIdx; +} tDeleteStaParams, *tpDeleteStaParams; + +/* Delete STA Request message*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteStaParams delStaParams; +} tDeleteStaReqMsg, *tpDeleteStaReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_STA_RSP +---------------------------------------------------------------------------*/ + +/* Delete STA Response Params */ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Index of STA deleted */ + tANI_U8 staId; +} tDeleteStaRspParams, *tpDeleteStaRspParams; + +/* Delete STA Response message*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteStaRspParams delStaRspParams; +} tDeleteStaRspMsg, *tpDeleteStaRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_BSS_REQ +---------------------------------------------------------------------------*/ + +//12 Bytes long because this structure can be used to represent rate +//and extended rate set IEs. The parser assume this to be at least 12 +typedef __ani_attr_pre_packed struct sSirMacRateSet +{ + tANI_U8 numRates; + tANI_U8 rate[SIR_MAC_RATESET_EID_MAX]; +} __ani_attr_packed tSirMacRateSet; + +// access category record +typedef __ani_attr_pre_packed struct sSirMacAciAifsn +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 rsvd : 1; + tANI_U8 aci : 2; + tANI_U8 acm : 1; + tANI_U8 aifsn : 4; +#else + tANI_U8 aifsn : 4; + tANI_U8 acm : 1; + tANI_U8 aci : 2; + tANI_U8 rsvd : 1; +#endif +} __ani_attr_packed tSirMacAciAifsn; + +// contention window size +typedef __ani_attr_pre_packed struct sSirMacCW +{ +#ifndef ANI_LITTLE_BIT_ENDIAN + tANI_U8 max : 4; + tANI_U8 min : 4; +#else + tANI_U8 min : 4; + tANI_U8 max : 4; +#endif +} __ani_attr_packed tSirMacCW; + +typedef __ani_attr_pre_packed struct sSirMacEdcaParamRecord +{ + tSirMacAciAifsn aci; + tSirMacCW cw; + tANI_U16 txoplimit; +} __ani_attr_packed tSirMacEdcaParamRecord; + +typedef __ani_attr_pre_packed struct sSirMacSSid +{ + tANI_U8 length; + tANI_U8 ssId[32]; +} __ani_attr_packed tSirMacSSid; + +// Concurrency role. These are generic IDs that identify the various roles +// in the software system. +typedef enum { + HAL_STA_MODE=0, + HAL_STA_SAP_MODE=1, // to support softAp mode . This is misleading. It means AP MODE only. + HAL_P2P_CLIENT_MODE, + HAL_P2P_GO_MODE, + HAL_MONITOR_MODE, +} tHalConMode; + +//This is a bit pattern to be set for each mode +//bit 0 - sta mode +//bit 1 - ap mode +//bit 2 - p2p client mode +//bit 3 - p2p go mode +typedef enum +{ + HAL_STA=1, + HAL_SAP=2, + HAL_STA_SAP=3, //to support sta, softAp mode . This means STA+AP mode + HAL_P2P_CLIENT=4, + HAL_P2P_GO=8, + HAL_MAX_CONCURRENCY_PERSONA=4 +} tHalConcurrencyMode; + +// IFACE PERSONA for different Operating modes +typedef enum +{ + HAL_IFACE_UNKNOWN=0, + HAL_IFACE_STA_MODE=1, + HAL_IFACE_P2P_MODE=2, + HAL_IFACE_MAX=0x7FFFFFFF, +} tHalIfacePersona; + +typedef PACKED_PRE struct PACKED_POST +{ + /* BSSID */ + tSirMacAddr bssId; + + /* Self Mac Address */ + tSirMacAddr selfMacAddr; + + /* BSS type */ + tSirBssType bssType; + + /*Operational Mode: AP =0, STA = 1*/ + tANI_U8 operMode; + + /*Network Type*/ + tSirNwType nwType; + + /*Used to classify PURE_11G/11G_MIXED to program MTU*/ + tANI_U8 shortSlotTimeSupported; + + /*Co-exist with 11a STA*/ + tANI_U8 llaCoexist; + + /*Co-exist with 11b STA*/ + tANI_U8 llbCoexist; + + /*Co-exist with 11g STA*/ + tANI_U8 llgCoexist; + + /*Coexistence with 11n STA*/ + tANI_U8 ht20Coexist; + + /*Non GF coexist flag*/ + tANI_U8 llnNonGFCoexist; + + /*TXOP protection support*/ + tANI_U8 fLsigTXOPProtectionFullSupport; + + /*RIFS mode*/ + tANI_U8 fRIFSMode; + + /*Beacon Interval in TU*/ + tSirMacBeaconInterval beaconInterval; + + /*DTIM period*/ + tANI_U8 dtimPeriod; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*Operating channel*/ + tANI_U8 currentOperChannel; + + /*Extension channel for channel bonding*/ + tANI_U8 currentExtChannel; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 reserved; + + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*HAL should update the existing BSS entry, if this flag is set. + UMAC will set this flag in case of reassoc, where we want to resue the + the old BSSID and still return success 0 = Add, 1 = Update*/ + tANI_U8 action; + + /* MAC Rate Set */ + tSirMacRateSet rateSet; + + /*Enable/Disable HT capabilities of the BSS*/ + tANI_U8 htCapable; + + // Enable/Disable OBSS protection + tANI_U8 obssProtEnabled; + + /*RMF enabled/disabled*/ + tANI_U8 rmfEnabled; + + /*HT Operating Mode operating mode of the 802.11n STA*/ + tSirMacHTOperatingMode htOperMode; + + /*Dual CTS Protection: 0 - Unused, 1 - Used*/ + tANI_U8 dualCTSProtection; + + /* Probe Response Max retries */ + tANI_U8 ucMaxProbeRespRetryLimit; + + /* To Enable Hidden ssid */ + tANI_U8 bHiddenSSIDEn; + + /* To Enable Disable FW Proxy Probe Resp */ + tANI_U8 bProxyProbeRespEn; + + /* Boolean to indicate if EDCA params are valid. UMAC might not have valid + EDCA params or might not desire to apply EDCA params during config BSS. + 0 implies Not Valid ; Non-Zero implies valid*/ + tANI_U8 edcaParamsValid; + + /*EDCA Parameters for Best Effort Access Category*/ + tSirMacEdcaParamRecord acbe; + + /*EDCA Parameters forBackground Access Category*/ + tSirMacEdcaParamRecord acbk; + + /*EDCA Parameters for Video Access Category*/ + tSirMacEdcaParamRecord acvi; + + /*EDCA Parameters for Voice Access Category*/ + tSirMacEdcaParamRecord acvo; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +#endif + + /* Persona for the BSS can be STA,AP,GO,CLIENT value same as tHalConMode */ + tANI_U8 halPersona; + + tANI_U8 bSpectrumMgtEnable; + + /*HAL fills in the tx power used for mgmt frames in txMgmtPower*/ + tANI_S8 txMgmtPower; + /*maxTxPower has max power to be used after applying the power constraint if any */ + tANI_S8 maxTxPower; + /*Context of the station being added in HW + Add a STA entry for "itself" - + On AP - Add the AP itself in an "STA context" + On STA - Add the AP to which this STA is joining in an "STA context" */ + tConfigStaParams staContext; +} tConfigBssParams, * tpConfigBssParams; + + +/*-------------------------------------------------------------------------- + * WLAN_HAL_CONFIG_BSS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* BSSID */ + tSirMacAddr bssId; + + /* Self Mac Address */ + tSirMacAddr selfMacAddr; + + /* BSS type */ + tSirBssType bssType; + + /*Operational Mode: AP =0, STA = 1*/ + tANI_U8 operMode; + + /*Network Type*/ + tSirNwType nwType; + + /*Used to classify PURE_11G/11G_MIXED to program MTU*/ + tANI_U8 shortSlotTimeSupported; + + /*Co-exist with 11a STA*/ + tANI_U8 llaCoexist; + + /*Co-exist with 11b STA*/ + tANI_U8 llbCoexist; + + /*Co-exist with 11g STA*/ + tANI_U8 llgCoexist; + + /*Coexistence with 11n STA*/ + tANI_U8 ht20Coexist; + + /*Non GF coexist flag*/ + tANI_U8 llnNonGFCoexist; + + /*TXOP protection support*/ + tANI_U8 fLsigTXOPProtectionFullSupport; + /*RIFS mode*/ + tANI_U8 fRIFSMode; + + /*Beacon Interval in TU*/ + tSirMacBeaconInterval beaconInterval; + + /*DTIM period*/ + tANI_U8 dtimPeriod; + + /*TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz*/ + tANI_U8 txChannelWidthSet; + + /*Operating channel*/ + tANI_U8 currentOperChannel; + + /*Extension channel for channel bonding*/ + tANI_U8 currentExtChannel; + + /*Reserved to align next field on a dword boundary*/ + tANI_U8 reserved; + + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*HAL should update the existing BSS entry, if this flag is set. + UMAC will set this flag in case of reassoc, where we want to resue the + the old BSSID and still return success 0 = Add, 1 = Update*/ + tANI_U8 action; + + /* MAC Rate Set */ + tSirMacRateSet rateSet; + + /*Enable/Disable HT capabilities of the BSS*/ + tANI_U8 htCapable; + + // Enable/Disable OBSS protection + tANI_U8 obssProtEnabled; + + /*RMF enabled/disabled*/ + tANI_U8 rmfEnabled; + + /*HT Operating Mode operating mode of the 802.11n STA*/ + tSirMacHTOperatingMode htOperMode; + + /*Dual CTS Protection: 0 - Unused, 1 - Used*/ + tANI_U8 dualCTSProtection; + + /* Probe Response Max retries */ + tANI_U8 ucMaxProbeRespRetryLimit; + + /* To Enable Hidden ssid */ + tANI_U8 bHiddenSSIDEn; + + /* To Enable Disable FW Proxy Probe Resp */ + tANI_U8 bProxyProbeRespEn; + + /* Boolean to indicate if EDCA params are valid. UMAC might not have valid + EDCA params or might not desire to apply EDCA params during config BSS. + 0 implies Not Valid ; Non-Zero implies valid*/ + tANI_U8 edcaParamsValid; + + /*EDCA Parameters for Best Effort Access Category*/ + tSirMacEdcaParamRecord acbe; + + /*EDCA Parameters forBackground Access Category*/ + tSirMacEdcaParamRecord acbk; + + /*EDCA Parameters for Video Access Category*/ + tSirMacEdcaParamRecord acvi; + + /*EDCA Parameters for Voice Access Category*/ + tSirMacEdcaParamRecord acvo; + +#ifdef WLAN_FEATURE_VOWIFI_11R + tANI_U8 extSetStaKeyParamValid; //Ext Bss Config Msg if set + tSetStaKeyParams extSetStaKeyParam; //SetStaKeyParams for ext bss msg +#endif + + /* Persona for the BSS can be STA,AP,GO,CLIENT value same as tHalConMode */ + tANI_U8 halPersona; + + tANI_U8 bSpectrumMgtEnable; + + /*HAL fills in the tx power used for mgmt frames in txMgmtPower*/ + tANI_S8 txMgmtPower; + /*maxTxPower has max power to be used after applying the power constraint if any */ + tANI_S8 maxTxPower; + /*Context of the station being added in HW + Add a STA entry for "itself" - + On AP - Add the AP itself in an "STA context" + On STA - Add the AP to which this STA is joining in an "STA context" */ + tConfigStaParams_V1 staContext; + + tANI_U8 vhtCapable; + tANI_U8 vhtTxChannelWidthSet; +} tConfigBssParams_V1, * tpConfigBssParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + PACKED_PRE union PACKED_POST { + tConfigBssParams configBssParams; + tConfigBssParams_V1 configBssParams_V1; + }uBssParams; +} tConfigBssReqMsg, *tpConfigBssReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CONFIG_BSS_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + + /* BSS index allocated by HAL */ + tANI_U8 bssIdx; + + /* DPU descriptor index for PTK */ + tANI_U8 dpuDescIndx; + + /* PTK DPU signature */ + tANI_U8 ucastDpuSignature; + + /* DPU descriptor index for GTK*/ + tANI_U8 bcastDpuDescIndx; + + /* GTK DPU signature */ + tANI_U8 bcastDpuSignature; + + /*DPU descriptor for IGTK*/ + tANI_U8 mgmtDpuDescIndx; + + /* IGTK DPU signature */ + tANI_U8 mgmtDpuSignature; + + /* Station Index for BSS entry*/ + tANI_U8 bssStaIdx; + + /* Self station index for this BSS */ + tANI_U8 bssSelfStaIdx; + + /* Bcast station for buffering bcast frames in AP role */ + tANI_U8 bssBcastStaIdx; + + /*MAC Address of STA(PEER/SELF) in staContext of configBSSReq*/ + tSirMacAddr staMac; + + /*HAL fills in the tx power used for mgmt frames in this field. */ + tANI_S8 txMgmtPower; + +} tConfigBssRspParams, * tpConfigBssRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigBssRspParams configBssRspParams; +} tConfigBssRspMsg, *tpConfigBssRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_BSS_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* BSS index to be deleted */ + tANI_U8 bssIdx; + +} tDeleteBssParams, *tpDeleteBssParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteBssParams deleteBssParams; +} tDeleteBssReqMsg, *tpDeleteBssReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_DELETE_BSS_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + + /* BSS index that has been deleted */ + tANI_U8 bssIdx; + +} tDeleteBssRspParams, *tpDeleteBssRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteBssRspParams deleteBssRspParams; +} tDeleteBssRspMsg, *tpDeleteBssRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_JOIN_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Indicates the BSSID to which STA is going to associate*/ + tSirMacAddr bssId; + + /*Indicates the channel to switch to.*/ + tANI_U8 ucChannel; + + /* Self STA MAC */ + tSirMacAddr selfStaMacAddr; + + /*Local power constraint*/ + tANI_U8 ucLocalPowerConstraint; + + /*Secondary channel offset */ + ePhyChanBondState secondaryChannelOffset; + + /*link State*/ + tSirLinkState linkState; + + /* Max TX power */ + tANI_S8 maxTxPower; + +} tHalJoinReqParams, *tpHalJoinReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalJoinReqParams joinReqParams; +} tHalJoinReqMsg, *tpHalJoinReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_JOIN_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* HAL fills in the tx power used for mgmt frames in this field */ + tPowerdBm txMgmtPower; + +}tHalJoinRspParams, *tpHalJoinRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalJoinRspParams joinRspParams; +}tHalJoinRspMsg, *tpHalJoinRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_POST_ASSOC_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tConfigStaParams configStaParams; + tConfigBssParams configBssParams; +} tPostAssocReqParams, *tpPostAssocReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPostAssocReqParams postAssocReqParams; +} tPostAssocReqMsg, *tpPostAssocReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_POST_ASSOC_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tConfigStaRspParams configStaRspParams; + tConfigBssRspParams configBssRspParams; +} tPostAssocRspParams, *tpPostAssocRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPostAssocRspParams postAssocRspParams; +} tPostAssocRspMsg, *tpPostAssocRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_BSSKEY_REQ +---------------------------------------------------------------------------*/ + +/* + * This is used by PE to create a set of WEP keys for a given BSS. + */ +typedef PACKED_PRE struct PACKED_POST +{ + /*BSS Index of the BSS*/ + tANI_U8 bssIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*Number of keys*/ + tANI_U8 numKeys; + + /*Array of keys.*/ + tSirKeys key[SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS]; + + /*Control for Replay Count, 1= Single TID based replay count on Tx + 0 = Per TID based replay count on TX */ + tANI_U8 singleTidRc; +} tSetBssKeyParams, *tpSetBssKeyParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetBssKeyParams setBssKeyParams; +} tSetBssKeyReqMsg, *tpSetBssKeyReqMsg; + +/* tagged version of set bss key */ +typedef PACKED_PRE struct PACKED_POST +{ + tSetBssKeyReqMsg Msg; + uint32 Tag; +} tSetBssKeyReqMsgTagged; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_BSSKEY_RSP +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +} tSetBssKeyRspParams, *tpSetBssKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetBssKeyRspParams setBssKeyRspParams; +} tSetBssKeyRspMsg, *tpSetBssKeyRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_STAKEY_REQ, +---------------------------------------------------------------------------*/ + +/* + * This is used by PE to configure the key information on a given station. + * When the secType is WEP40 or WEP104, the defWEPIdx is used to locate + * a preconfigured key from a BSS the station assoicated with; otherwise + * a new key descriptor is created based on the key field. + */ + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetStaKeyParams setStaKeyParams; +} tSetStaKeyReqMsg, *tpSetStaKeyReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_SET_STAKEY_RSP, +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +} tSetStaKeyRspParams, *tpSetStaKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetStaKeyRspParams setStaKeyRspParams; +} tSetStaKeyRspMsg, *tpSetStaKeyRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_BSSKEY_REQ, +---------------------------------------------------------------------------*/ +/* + * This is used by PE to remove keys for a given BSS. + */ +typedef PACKED_PRE struct PACKED_POST + +{ + /*BSS Index of the BSS*/ + tANI_U8 bssIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*Key Id*/ + tANI_U8 keyId; + + /*STATIC/DYNAMIC. Used in Nullifying in Key Descriptors for Static/Dynamic keys*/ + tAniWepType wepType; + +} tRemoveBssKeyParams, *tpRemoveBssKeyParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveBssKeyParams removeBssKeyParams; +} tRemoveBssKeyReqMsg, *tpRemoveBssKeyReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_BSSKEY_RSP, +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + +} tRemoveBssKeyRspParams, *tpRemoveBssKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveBssKeyRspParams removeBssKeyRspParams; +} tRemoveBssKeyRspMsg, *tpRemoveBssKeyRspMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_STAKEY_REQ, +---------------------------------------------------------------------------*/ +/* + * This is used by PE to Remove the key information on a given station. + */ +typedef PACKED_PRE struct PACKED_POST +{ + /*STA Index*/ + tANI_U16 staIdx; + + /*Encryption Type used with peer*/ + tAniEdType encType; + + /*Key Id*/ + tANI_U8 keyId; + + /*Whether to invalidate the Broadcast key or Unicast key. In case of WEP, + the same key is used for both broadcast and unicast.*/ + tANI_BOOLEAN unicast; + +} tRemoveStaKeyParams, *tpRemoveStaKeyParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveStaKeyParams removeStaKeyParams; +} tRemoveStaKeyReqMsg, *tpRemoveStaKeyReqMsg; + +/*--------------------------------------------------------------------------- + WLAN_HAL_RMV_STAKEY_RSP, +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tRemoveStaKeyRspParams, *tpRemoveStaKeyRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemoveStaKeyRspParams removeStaKeyRspParams; +} tRemoveStaKeyRspMsg, *tpRemoveStaKeyRspMsg; + +#ifdef FEATURE_OEM_DATA_SUPPORT + +#ifndef OEM_DATA_REQ_SIZE +#define OEM_DATA_REQ_SIZE 134 +#endif + +#ifndef OEM_DATA_RSP_SIZE +#define OEM_DATA_RSP_SIZE 1968 +#endif + +/*------------------------------------------------------------------------- +WLAN_HAL_START_OEM_DATA_REQ +--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tSirMacAddr selfMacAddr; + tANI_U8 oemDataReq[OEM_DATA_REQ_SIZE]; +} tStartOemDataReqParams, *tpStartOemDataReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartOemDataReqParams startOemDataReqParams; +} tStartOemDataReqMsg, *tpStartOemDataReqMsg; + +/*------------------------------------------------------------------------- +WLAN_HAL_START_OEM_DATA_RSP +--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 oemDataRsp[OEM_DATA_RSP_SIZE]; +} tStartOemDataRspParams, *tpStartOemDataRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartOemDataRspParams startOemDataRspParams; +} tStartOemDataRspMsg, *tpStartOemDataRspMsg; + +#ifndef NEW_OEM_DATA_REQ_SIZE +#define NEW_OEM_DATA_REQ_SIZE 292 +#endif + +#ifndef NEW_OEM_DATA_RSP_SIZE +#define NEW_OEM_DATA_RSP_SIZE 2100 +#endif + +/*------------------------------------------------------------------------- +WLAN_HAL_START_OEM_DATA_REQ_IND_NEW------------------------------------ +--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + tANI_U8 reserved[2]; + tANI_U8 oemDataReq[NEW_OEM_DATA_REQ_SIZE]; +} tStartOemDataReqParamsNew, *tpStartOemDataReqParamsNew; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartOemDataReqParamsNew startOemDataReqParams; +} tStartOemDataReqMsgNew, *tpStartOemDataReqMsgNew; + +/*------------------------------------------------------------------------- +WLAN_HAL_START_OEM_DATA_RSP_IND_NEW------------------------------------ +--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 oemDataRsp[NEW_OEM_DATA_RSP_SIZE]; +} tStartOemDataRspParamsNew, *tpStartOemDataRspParamsNew; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tStartOemDataRspParamsNew startOemDataReqParams; +} tStartOemDataRspMsgNew, *tpStartOemDataRspMsgNew; + +#endif + +/*--------------------------------------------------------------------------- +WLAN_HAL_CH_SWITCH_V1_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Channel number */ + tANI_U8 channelNumber; + + /* Local power constraint */ + tANI_U8 localPowerConstraint; + + /*Secondary channel offset */ + ePhyChanBondState secondaryChannelOffset; + + //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm txMgmtPower; + + /* Max TX power */ + tPowerdBm maxTxPower; + + /* Self STA MAC */ + tSirMacAddr selfStaMacAddr; + + /*VO WIFI comment: BSSID needed to identify session. As the request has + * power constraints, this should be applied only to that session + * Since MTU timing and EDCA are sessionized, this struct needs to be + * sessionized and bssid needs to be out of the VOWifi feature flag + * V IMP: Keep bssId field at the end of this msg. It is used to + * mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since + * it is at the end of this struct + */ + tSirMacAddr bssId; + + /* Source of Channel Switch */ + eHalChanSwitchSource channelSwitchSrc; + +} tSwitchChannelParams_V1, *tpSwitchChannelParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSwitchChannelParams_V1 switchChannelParams_V1; +} tSwitchChannelReqMsg_V1, *tpSwitchChannelReqMsg_V1; + +/*--------------------------------------------------------------------------- +WLAN_HAL_CH_SWITCH_V1_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Status */ + tANI_U32 status; + + /* Channel number - same as in request*/ + tANI_U8 channelNumber; + + /* HAL fills in the tx power used for mgmt frames in this field */ + tPowerdBm txMgmtPower; + + /* BSSID needed to identify session - same as in request*/ + tSirMacAddr bssId; + + /* Source of Channel Switch */ + eHalChanSwitchSource channelSwitchSrc; + +} tSwitchChannelRspParams_V1, *tpSwitchChannelRspParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSwitchChannelRspParams_V1 channelSwitchRspParams_V1; +} tSwitchChannelRspMsg_V1, *tpSwitchChannelRspMsg_V1; + +/*--------------------------------------------------------------------------- +WLAN_HAL_CH_SWITCH_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Channel number */ + tANI_U8 channelNumber; + + /* Local power constraint */ + tANI_U8 localPowerConstraint; + + /*Secondary channel offset */ + ePhyChanBondState secondaryChannelOffset; + + //HAL fills in the tx power used for mgmt frames in this field. + tPowerdBm txMgmtPower; + + /* Max TX power */ + tPowerdBm maxTxPower; + + /* Self STA MAC */ + tSirMacAddr selfStaMacAddr; + + /*VO WIFI comment: BSSID needed to identify session. As the request has power constraints, + this should be applied only to that session*/ + /* Since MTU timing and EDCA are sessionized, this struct needs to be sessionized and + * bssid needs to be out of the VOWifi feature flag */ + /* V IMP: Keep bssId field at the end of this msg. It is used to mantain backward compatbility + * by way of ignoring if using new host/old FW or old host/new FW since it is at the end of this struct + */ + tSirMacAddr bssId; + +}tSwitchChannelParams, *tpSwitchChannelParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSwitchChannelParams switchChannelParams; +} tSwitchChannelReqMsg, *tpSwitchChannelReqMsg; + +/*--------------------------------------------------------------------------- +WLAN_HAL_CH_SWITCH_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Status */ + tANI_U32 status; + + /* Channel number - same as in request*/ + tANI_U8 channelNumber; + + /* HAL fills in the tx power used for mgmt frames in this field */ + tPowerdBm txMgmtPower; + + /* BSSID needed to identify session - same as in request*/ + tSirMacAddr bssId; + +}tSwitchChannelRspParams, *tpSwitchChannelRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSwitchChannelRspParams switchChannelRspParams; +} tSwitchChannelRspMsg, *tpSwitchChannelRspMsg; + +/*--------------------------------------------------------------------------- +WLAN_HAL_UPD_EDCA_PARAMS_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*BSS Index*/ + tANI_U16 bssIdx; + + /* Best Effort */ + tSirMacEdcaParamRecord acbe; + + /* Background */ + tSirMacEdcaParamRecord acbk; + + /* Video */ + tSirMacEdcaParamRecord acvi; + + /* Voice */ + tSirMacEdcaParamRecord acvo; + +} tEdcaParams, *tpEdcaParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEdcaParams edcaParams; +} tUpdateEdcaParamsReqMsg, *tpUpdateEdcaParamsReqMsg; + +/*--------------------------------------------------------------------------- +WLAN_HAL_UPD_EDCA_PARAMS_RSP +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tEdcaRspParams, *tpEdcaRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEdcaRspParams edcaRspParams; +} tUpdateEdcaParamsRspMsg, *tpUpdateEdcaParamsRspMsg; + + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_STATS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST + +{ + /* Index of STA to which the statistics */ + tANI_U16 staIdx; + + /* Encryption mode */ + tANI_U8 encMode; + + /* status */ + tANI_U32 status; + + /* Statistics */ + tANI_U32 sendBlocks; + tANI_U32 recvBlocks; + tANI_U32 replays; + tANI_U8 micErrorCnt; + tANI_U32 protExclCnt; + tANI_U16 formatErrCnt; + tANI_U16 unDecryptableCnt; + tANI_U32 decryptErrCnt; + tANI_U32 decryptOkCnt; +} tDpuStatsParams, * tpDpuStatsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Valid STA Idx for per STA stats request */ + tANI_U32 staId; + + /* Categories of stats requested as specified in eHalStatsMask*/ + tANI_U32 statsMask; +}tHalStatsReqParams, *tpHalStatsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsReqParams statsReqParams; +} tHalStatsReqMsg, *tpHalStatsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_STATS_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 retry_cnt[4]; //Total number of packets(per AC) that were successfully transmitted with retries + tANI_U32 multiple_retry_cnt[4]; //The number of MSDU packets and MMPDU frames per AC that the 802.11 + // station successfully transmitted after more than one retransmission attempt + + tANI_U32 tx_frm_cnt[4]; //Total number of packets(per AC) that were successfully transmitted + //(with and without retries, including multi-cast, broadcast) + tANI_U32 rx_frm_cnt; //Total number of packets that were successfully received + //(after appropriate filter rules including multi-cast, broadcast) + tANI_U32 frm_dup_cnt; //Total number of duplicate frames received successfully + tANI_U32 fail_cnt[4]; //Total number packets(per AC) failed to transmit + tANI_U32 rts_fail_cnt; //Total number of RTS/CTS sequence failures for transmission of a packet + tANI_U32 ack_fail_cnt; //Total number packets failed transmit because of no ACK from the remote entity + tANI_U32 rts_succ_cnt; //Total number of RTS/CTS sequence success for transmission of a packet + tANI_U32 rx_discard_cnt; //The sum of the receive error count and dropped-receive-buffer error count. + //HAL will provide this as a sum of (FCS error) + (Fail get BD/PDU in HW) + tANI_U32 rx_error_cnt; //The receive error count. HAL will provide the RxP FCS error global counter. + tANI_U32 tx_byte_cnt; //The sum of the transmit-directed byte count, transmit-multicast byte count + //and transmit-broadcast byte count. HAL will sum TPE UC/MC/BCAST global counters + //to provide this. +}tAniSummaryStatsInfo, *tpAniSummaryStatsInfo; + + +// defines tx_rate_flags +typedef enum eTxRateInfo +{ + eHAL_TX_RATE_LEGACY = 0x1, /* Legacy rates */ + eHAL_TX_RATE_HT20 = 0x2, /* HT20 rates */ + eHAL_TX_RATE_HT40 = 0x4, /* HT40 rates */ + eHAL_TX_RATE_SGI = 0x8, /* Rate with Short guard interval */ + eHAL_TX_RATE_LGI = 0x10, /* Rate with Long guard interval */ + eHAL_TX_RATE_VHT20 = 0x20, /* VHT 20 rates */ + eHAL_TX_RATE_VHT40 = 0x40, /* VHT 20 rates */ + eHAL_TX_RATE_VHT80 = 0x80, /* VHT 20 rates */ + eHAL_TX_RATE_VIRT = 0x100, /* Virtual Rate */ + eHAL_TX_RATE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tTxrateinfoflags, tTxRateInfoFlags; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames + tANI_U32 promiscuous_rx_frag_cnt; //The number of MPDU frames received by the 802.11 station for MSDU packets + //or MMPDU frames when a promiscuous packet filter was enabled + tANI_U32 rx_input_sensitivity; //The receiver input sensitivity referenced to a FER of 8% at an MPDU length + //of 1024 bytes at the antenna connector. Each element of the array shall correspond + //to a supported rate and the order shall be the same as the supporteRates parameter. + tANI_U32 max_pwr; //The maximum transmit power in dBm upto one decimal. + //for eg: if it is 10.5dBm, the value would be 105 + tANI_U32 sync_fail_cnt; //Number of times the receiver failed to synchronize with the incoming signal + //after detecting the sync in the preamble of the transmitted PLCP protocol data unit. + + tANI_U32 tx_rate; //Legacy transmit rate, in units of 500 kbit/sec, for the most + //recently transmitted frame + tANI_U32 mcs_index; //mcs index for HT20 and HT40 rates + tANI_U32 tx_rate_flags; //to differentiate between HT20 and + //HT40 rates; short and long guard interval +}tAniGlobalClassAStatsInfo, *tpAniGlobalClassAStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rx_wep_unencrypted_frm_cnt; //The number of unencrypted received MPDU frames that the MAC layer discarded when + //the IEEE 802.11 dot11ExcludeUnencrypted management information base (MIB) object + //is enabled + tANI_U32 rx_mic_fail_cnt; //The number of received MSDU packets that that the 802.11 station discarded + //because of MIC failures + tANI_U32 tkip_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a TKIP ICV error + tANI_U32 aes_ccmp_format_err; //The number of received MPDU frames that the 802.11 discarded because of an + //invalid AES-CCMP format + tANI_U32 aes_ccmp_replay_cnt; //The number of received MPDU frames that the 802.11 station discarded because of + //the AES-CCMP replay protection procedure + tANI_U32 aes_ccmp_decrpt_err; //The number of received MPDU frames that the 802.11 station discarded because of + //errors detected by the AES-CCMP decryption algorithm + tANI_U32 wep_undecryptable_cnt; //The number of encrypted MPDU frames received for which a WEP decryption key was + //not available on the 802.11 station + tANI_U32 wep_icv_err; //The number of encrypted MPDU frames that the 802.11 station failed to decrypt + //because of a WEP ICV error + tANI_U32 rx_decrypt_succ_cnt; //The number of received encrypted packets that the 802.11 station successfully + //decrypted + tANI_U32 rx_decrypt_fail_cnt; //The number of encrypted packets that the 802.11 station failed to decrypt + +}tAniGlobalSecurityStats, *tpAniGlobalSecurityStats; + +typedef PACKED_PRE struct PACKED_POST +{ + tAniGlobalSecurityStats ucStats; + tAniGlobalSecurityStats mcbcStats; +}tAniGlobalClassBStatsInfo, *tpAniGlobalClassBStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rx_amsdu_cnt; //This counter shall be incremented for a received A-MSDU frame with the stations + //MAC address in the address 1 field or an A-MSDU frame with a group address in the + //address 1 field + tANI_U32 rx_ampdu_cnt; //This counter shall be incremented when the MAC receives an AMPDU from the PHY + tANI_U32 tx_20_frm_cnt; //This counter shall be incremented when a Frame is transmitted only on the + //primary channel + tANI_U32 rx_20_frm_cnt; //This counter shall be incremented when a Frame is received only on the primary channel + tANI_U32 rx_mpdu_in_ampdu_cnt; //This counter shall be incremented by the number of MPDUs received in the A-MPDU + //when an A-MPDU is received + tANI_U32 ampdu_delimiter_crc_err; //This counter shall be incremented when an MPDU delimiter has a CRC error when this + //is the first CRC error in the received AMPDU or when the previous delimiter has been + //decoded correctly +}tAniGlobalClassCStatsInfo, *tpAniGlobalClassCStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 tx_frag_cnt[4]; //The number of MPDU frames that the 802.11 station transmitted and acknowledged + //through a received 802.11 ACK frame + tANI_U32 tx_ampdu_cnt; //This counter shall be incremented when an A-MPDU is transmitted + tANI_U32 tx_mpdu_in_ampdu_cnt; //This counter shall increment by the number of MPDUs in the AMPDU when an A-MPDU + //is transmitted +}tAniPerStaStatsInfo, *tpAniPerStaStatsInfo; + +// The following stats are averaged over the time between two consecutive GET_STATS_REQ messages. +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 lastTxRate; // 802.11 data rate at which the last data frame is transmitted. + tANI_U32 txAvgRetry; // Average number of retries per 10 packets. + tANI_U32 reserved; + tANI_U32 reserved1; +}tAniPerTxPktStatsInfo, *tpAniPerTxPktStatsInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + + /* STA Idx */ + tANI_U32 staId; + + /* Categories of STATS being returned as per eHalStatsMask*/ + tANI_U32 statsMask; + + /* message type is same as the request type */ + tANI_U16 msgType; + + /* length of the entire request, includes the pStatsBuf length too */ + tANI_U16 msgLen; + +} tHalStatsRspParams, *tpHalStatsRspParams; + + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsRspParams statsRspParams; +} tHalStatsRspMsg, *tpHalStatsRspMsg; + + /*--------------------------------------------------------------------------- + * WLAN_HAL_SET_RTS_CTS_HTVHT_IND + *---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 rtsCtsValue; +}tHalRtsCtsHtvhtIndParams, *tpHalRtsCtsHtvhtIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRtsCtsHtvhtIndParams rtsCtsHtvhtIndParams; +} tHalRtsCtsHtvhtIndMsg, *tpHalRtsCtsHtvhtIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_STATS_REQ + *---------------------------------------------------------------------------*/ + typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 type; +}tHalfwStatsReqParams, *tpHalfwStatsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalfwStatsReqParams fwstatsReqParams; +} tHalfwStatsReqMsg, *tpHalfwStatsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_STATS_RSP + *---------------------------------------------------------------------------*/ + typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 type; + tANI_U32 length; + tANI_U8 data[1]; + +}tHalfwStatsRspParams, *tpHalfwStatsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalfwStatsRspParams fwstatsRspParams; +} tHalfwStatsRspMsg, *tpHalfwStatsRspMsg; + +typedef enum +{ + FW_UBSP_STATS = 1, +} fwstatstype; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_LINK_ST_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssid; + tSirLinkState state; + tSirMacAddr selfMacAddr; +} tLinkStateParams, *tpLinkStateParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tLinkStateParams linkStateParams; +} tSetLinkStateReqMsg, *tpSetLinkStateReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_LINK_ST_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tLinkStateRspParams, *tpLinkStateRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tLinkStateRspParams linkStateRspParams; +} tSetLinkStateRspMsg, *tpSetLinkStateRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_TS_REQ + *--------------------------------------------------------------------------*/ + +/* TSPEC Params */ +typedef __ani_attr_pre_packed struct sSirMacTSInfoTfc +{ + tANI_U16 trafficType : 1; + tANI_U16 tsid : 4; + tANI_U16 direction : 2; + tANI_U16 accessPolicy : 2; + tANI_U16 aggregation : 1; + tANI_U16 psb : 1; + tANI_U16 userPrio : 3; + tANI_U16 ackPolicy : 2; +} __ani_attr_packed tSirMacTSInfoTfc; + +/* Flag to schedule the traffic type */ +typedef __ani_attr_pre_packed struct sSirMacTSInfoSch +{ + tANI_U8 schedule : 1; + tANI_U8 rsvd : 7; +} __ani_attr_packed tSirMacTSInfoSch; + +/* Traffic and scheduling info */ +typedef __ani_attr_pre_packed struct sSirMacTSInfo +{ + tSirMacTSInfoTfc traffic; + tSirMacTSInfoSch schedule; +} __ani_attr_packed tSirMacTSInfo; + +/* Information elements */ +typedef __ani_attr_pre_packed struct sSirMacTspecIE +{ + tANI_U8 type; + tANI_U8 length; + tSirMacTSInfo tsinfo; + tANI_U16 nomMsduSz; + tANI_U16 maxMsduSz; + tANI_U32 minSvcInterval; + tANI_U32 maxSvcInterval; + tANI_U32 inactInterval; + tANI_U32 suspendInterval; + tANI_U32 svcStartTime; + tANI_U32 minDataRate; + tANI_U32 meanDataRate; + tANI_U32 peakDataRate; + tANI_U32 maxBurstSz; + tANI_U32 delayBound; + tANI_U32 minPhyRate; + tANI_U16 surplusBw; + tANI_U16 mediumTime; +}__ani_attr_packed tSirMacTspecIE; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TSPEC handler uniquely identifying a TSPEC for a STA in a BSS */ + tANI_U16 tspecIdx; + + /* To program TPE with required parameters */ + tSirMacTspecIE tspec; + + /* U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /* These parameters are for all the access categories */ + tANI_U32 srvInterval[WLAN_HAL_MAX_AC]; // Service Interval + tANI_U32 susInterval[WLAN_HAL_MAX_AC]; // Suspend Interval + tANI_U32 delayInterval[WLAN_HAL_MAX_AC]; // Delay Interval + +} tAddTsParams, *tpAddTsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddTsParams addTsParams; +} tAddTsReqMsg, *tpAddTsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_TS_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tAddTsRspParams, *tpAddTsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddTsRspParams addTsRspParams; +} tAddTsRspMsg, *tpAddTsRspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_TS_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TSPEC identifier uniquely identifying a TSPEC for a STA in a BSS */ + tANI_U16 tspecIdx; + + /* To lookup station id using the mac address */ + tSirMacAddr bssId; + +} tDelTsParams, *tpDelTsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelTsParams delTsParams; +} tDelTsReqMsg, *tpDelTsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_TS_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; +} tDelTsRspParams, *tpDelTsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelTsRspParams delTsRspParams; +} tDelTsRspMsg, *tpDelTsRspMsg; + +/* End of TSpec Parameters */ + +/* Start of BLOCK ACK related Parameters */ + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_SESSION_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* Peer MAC Address */ + tSirMacAddr peerMacAddr; + + /* ADDBA Action Frame dialog token + HAL will not interpret this object */ + tANI_U8 baDialogToken; + + /* TID for which the BA is being setup + This identifies the TC or TS of interest */ + tANI_U8 baTID; + + /* 0 - Delayed BA (Not supported) + 1 - Immediate BA */ + tANI_U8 baPolicy; + + /* Indicates the number of buffers for this TID (baTID) + NOTE - This is the requested buffer size. When this + is processed by HAL and subsequently by HDD, it is + possible that HDD may change this buffer size. Any + change in the buffer size should be noted by PE and + advertized appropriately in the ADDBA response */ + tANI_U16 baBufferSize; + + /* BA timeout in TU's 0 means no timeout will occur */ + tANI_U16 baTimeout; + + /* b0..b3 - Fragment Number - Always set to 0 + b4..b15 - Starting Sequence Number of first MSDU + for which this BA is setup */ + tANI_U16 baSSN; + + /* ADDBA direction + 1 - Originator + 0 - Recipient */ + tANI_U8 baDirection; +} tAddBASessionParams, *tpAddBASessionParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBASessionParams addBASessionParams; +}tAddBASessionReqMsg, *tpAddBASessionReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_SESSION_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Dialog token */ + tANI_U8 baDialogToken; + + /* TID for which the BA session has been setup */ + tANI_U8 baTID; + + /* BA Buffer Size allocated for the current BA session */ + tANI_U8 baBufferSize; + + tANI_U8 baSessionID; + + /* Reordering Window buffer */ + tANI_U8 winSize; + + /*Station Index to id the sta */ + tANI_U8 STAID; + + /* Starting Sequence Number */ + tANI_U16 SSN; +} tAddBASessionRspParams, *tpAddBASessionRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBASessionRspParams addBASessionRspParams; +} tAddBASessionRspMsg, *tpAddBASessionRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Session Id */ + tANI_U8 baSessionID; + + /* Reorder Window Size */ + tANI_U8 winSize; + +#ifdef FEATURE_ON_CHIP_REORDERING + tANI_BOOLEAN isReorderingDoneOnChip; +#endif +} tAddBAParams, *tpAddBAParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBAParams addBAParams; +} tAddBAReqMsg, *tpAddBAReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BA_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Dialog token */ + tANI_U8 baDialogToken; + +} tAddBARspParams, *tpAddBARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddBARspParams addBARspParams; +} tAddBARspMsg, *tpAddBARspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TRIGGER_BA_REQ + *--------------------------------------------------------------------------*/ + + +typedef struct sAddBaInfo +{ + tANI_U16 fBaEnable : 1; + tANI_U16 startingSeqNum: 12; + tANI_U16 reserved : 3; +}tAddBaInfo, *tpAddBaInfo; + +typedef struct sTriggerBaRspCandidate +{ + tSirMacAddr staAddr; + tAddBaInfo baInfo[STACFG_MAX_TC]; +}tTriggerBaRspCandidate, *tpTriggerBaRspCandidate; + +typedef struct sTriggerBaCandidate +{ + tANI_U8 staIdx; + tANI_U8 tidBitmap; +}tTriggerBaReqCandidate, *tptTriggerBaReqCandidate; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Session Id */ + tANI_U8 baSessionID; + + /* baCandidateCnt is followed by trigger BA + * Candidate List(tTriggerBaCandidate) + */ + tANI_U16 baCandidateCnt; + +} tTriggerBAParams, *tpTriggerBAParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTriggerBAParams triggerBAParams; +} tTriggerBAReqMsg, *tpTriggerBAReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TRIGGER_BA_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + + /* TO SUPPORT BT-AMP */ + tSirMacAddr bssId; + + /* success or failure */ + tANI_U32 status; + + /* baCandidateCnt is followed by trigger BA + * Rsp Candidate List(tTriggerRspBaCandidate) + */ + tANI_U16 baCandidateCnt; + + +} tTriggerBARspParams, *tpTriggerBARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTriggerBARspParams triggerBARspParams; +} tTriggerBARspMsg, *tpTriggerBARspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_BA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TID for which the BA session is being deleted */ + tANI_U8 baTID; + + /* DELBA direction + 1 - Originator + 0 - Recipient */ + tANI_U8 baDirection; +} tDelBAParams, *tpDelBAParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelBAParams delBAParams; +} tDelBAReqMsg, *tpDelBAReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_BA_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tDelBARspParams, *tpDelBARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelBARspParams delBARspParams; +} tDelBARspMsg, *tpDelBARspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TSM_STATS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Traffic Id */ + tANI_U8 tsmTID; + + tSirMacAddr bssId; +} tTsmStatsParams, *tpTsmStatsParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTsmStatsParams tsmStatsParams; +} tTsmStatsReqMsg, *tpTsmStatsReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TSM_STATS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + /* Uplink Packet Queue delay */ + tANI_U16 UplinkPktQueueDly; + + /* Uplink Packet Queue delay histogram */ + tANI_U16 UplinkPktQueueDlyHist[4]; + + /* Uplink Packet Transmit delay */ + tANI_U32 UplinkPktTxDly; + + /* Uplink Packet loss */ + tANI_U16 UplinkPktLoss; + + /* Uplink Packet count */ + tANI_U16 UplinkPktCount; + + /* Roaming count */ + tANI_U8 RoamingCount; + + /* Roaming Delay */ + tANI_U16 RoamingDly; +} tTsmStatsRspParams, *tpTsmStatsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTsmStatsRspParams tsmStatsRspParams; +} tTsmStatsRspMsg, *tpTsmStatsRspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_KEYDONE_MSG + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*bssid of the keys */ + tANI_U8 bssidx; + tANI_U8 encType; +} tSetKeyDoneParams, *tpSetKeyDoneParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetKeyDoneParams setKeyDoneParams; +} tSetKeyDoneMsg, *tpSetKeyDoneMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DOWNLOAD_NV_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Fragment sequence number of the NV Image. Note that NV Image might not + * fit into one message due to size limitation of the SMD channel FIFO. UMAC + * can hence choose to chop the NV blob into multiple fragments starting with + * seqeunce number 0, 1, 2 etc. The last fragment MUST be indicated by + * marking the isLastFragment field to 1. Note that all the NV blobs would be + * concatenated together by HAL without any padding bytes in between.*/ + tANI_U16 fragNumber; + + /* Is this the last fragment? When set to 1 it indicates that no more fragments + * will be sent by UMAC and HAL can concatenate all the NV blobs rcvd & proceed + * with the parsing. HAL would generate a WLAN_HAL_DOWNLOAD_NV_RSP to the + * WLAN_HAL_DOWNLOAD_NV_REQ after it receives each fragment */ + tANI_U16 isLastFragment; + + /* NV Image size (number of bytes) */ + tANI_U32 nvImgBufferSize; + + /* Following the 'nvImageBufferSize', there should be nvImageBufferSize + * bytes of NV Image i.e. uint8[nvImageBufferSize] */ +} tHalNvImgDownloadReqParams, *tpHalNvImgDownloadReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalNvImgDownloadReqMsg messages should be + * header.msgLen = sizeof(tHalNvImgDownloadReqMsg) + nvImgBufferSize */ + tHalMsgHeader header; + tHalNvImgDownloadReqParams nvImageReqParams; +} tHalNvImgDownloadReqMsg, *tpHalNvImgDownloadReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DOWNLOAD_NV_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure. HAL would generate a WLAN_HAL_DOWNLOAD_NV_RSP + * after each fragment */ + tANI_U32 status; +} tHalNvImgDownloadRspParams, *tpHalNvImgDownloadRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalNvImgDownloadRspParams nvImageRspParams; +} tHalNvImgDownloadRspMsg, *tpHalNvImgDownloadRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_STORE_NV_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* NV Item */ + eNvTable tableID; + + /* Size of NV Blob */ + tANI_U32 nvBlobSize; + + /* Following the 'nvBlobSize', there should be nvBlobSize bytes of + * NV blob i.e. uint8[nvBlobSize] */ +} tHalNvStoreParams, *tpHalNvStoreParams; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Note: The length specified in tHalNvStoreInd messages should be + * header.msgLen = sizeof(tHalNvStoreInd) + nvBlobSize */ + tHalMsgHeader header; + tHalNvStoreParams nvStoreParams; +} tHalNvStoreInd, *tpHalNvStoreInd; + +/* End of Block Ack Related Parameters */ + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MIC_FAILURE_IND + *--------------------------------------------------------------------------*/ + +#define SIR_CIPHER_SEQ_CTR_SIZE 6 + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr srcMacAddr; //address used to compute MIC + tSirMacAddr taMacAddr; //transmitter address + tSirMacAddr dstMacAddr; + tANI_U8 multicast; + tANI_U8 IV1; // first byte of IV + tANI_U8 keyId; // second byte of IV + tANI_U8 TSC[SIR_CIPHER_SEQ_CTR_SIZE]; // sequence number + tSirMacAddr rxMacAddr; // receive address +} tSirMicFailureInfo, *tpSirMicFailureInfo; + +/* Definition for MIC failure indication + MAC reports this each time a MIC failure occures on Rx TKIP packet + */ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssId; // BSSID + tSirMicFailureInfo info; +} tSirMicFailureInd, *tpSirMicFailureInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSirMicFailureInd micFailureInd; +} tMicFailureIndMsg, *tpMicFailureIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 opMode; + tANI_U16 staId; +}tUpdateVHTOpMode, *tpUpdateVHTOpMode; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateVHTOpMode updateVhtOpMode; +} tUpdateVhtOpModeReqMsg, *tpUpdateVhtOpModeReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tUpdateVhtOpModeParamsRsp, *tpUpdateVhtOpModeParamsRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateVhtOpModeParamsRsp updateVhtOpModeRspParam; +} tUpdateVhtOpModeParamsRspMsg, *tpUpdateVhtOpModeParamsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_UPDATE_BEACON_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + + tANI_U8 bssIdx; + + //shortPreamble mode. HAL should update all the STA rates when it + //receives this message + tANI_U8 fShortPreamble; + //short Slot time. + tANI_U8 fShortSlotTime; + //Beacon Interval + tANI_U16 beaconInterval; + //Protection related + tANI_U8 llaCoexist; + tANI_U8 llbCoexist; + tANI_U8 llgCoexist; + tANI_U8 ht20MhzCoexist; + tANI_U8 llnNonGFCoexist; + tANI_U8 fLsigTXOPProtectionFullSupport; + tANI_U8 fRIFSMode; + + tANI_U16 paramChangeBitmap; +}tUpdateBeaconParams, *tpUpdateBeaconParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateBeaconParams updateBeaconParam; +} tUpdateBeaconReqMsg, *tpUpdateBeaconReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_UPDATE_BEACON_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tUpdateBeaconRspParams, *tpUpdateBeaconRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateBeaconRspParams updateBeaconRspParam; +} tUpdateBeaconRspMsg, *tpUpdateBeaconRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SEND_BEACON_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 beaconLength; //length of the template. + tANI_U8 beacon[BEACON_TEMPLATE_SIZE]; // Beacon data. + tSirMacAddr bssId; + tANI_U32 timIeOffset; //TIM IE offset from the beginning of the template. + tANI_U16 p2pIeOffset; //P2P IE offset from the begining of the template +}tSendBeaconParams, *tpSendBeaconParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendBeaconParams sendBeaconParam; +}tSendBeaconReqMsg, *tpSendBeaconReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SEND_BEACON_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tSendBeaconRspParams, *tpSendBeaconRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendBeaconRspParams sendBeaconRspParam; +} tSendBeaconRspMsg, *tpSendBeaconRspMsg; + +#ifdef FEATURE_5GHZ_BAND + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENABLE_RADAR_DETECT_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr BSSID; + tANI_U8 channel; +}tSirEnableRadarInfoType, *tptSirEnableRadarInfoType; + + +typedef PACKED_PRE struct PACKED_POST +{ + /* Link Parameters */ + tSirEnableRadarInfoType EnableRadarInfo; +}tEnableRadarReqParams, *tpEnableRadarReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEnableRadarReqParams enableRadarReqParams; +}tEnableRadarReqMsg, *tpEnableRadarReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENABLE_RADAR_DETECT_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Link Parameters */ + tSirMacAddr BSSID; + /* success or failure */ + tANI_U32 status; +}tEnableRadarRspParams, *tpEnableRadarRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tEnableRadarRspParams enableRadarRspParams; +}tEnableRadarRspMsg, *tpEnableRadarRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_RADAR_DETECT_INTR_IND + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 radarDetChannel; +}tRadarDetectIntrIndParams, *tpRadarDetectIntrIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRadarDetectIntrIndParams radarDetectIntrIndParams; +}tRadarDetectIntrIndMsg, *tptRadarDetectIntrIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_RADAR_DETECT_IND + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*channel number in which the RADAR detected*/ + tANI_U8 channelNumber; + + /*RADAR pulse width*/ + tANI_U16 radarPulseWidth; // in usecond + + /*Number of RADAR pulses */ + tANI_U16 numRadarPulse; +}tRadarDetectIndParams,*tpRadarDetectIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRadarDetectIndParams radarDetectIndParams; +}tRadarDetectIndMsg, *tptRadarDetectIndMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_GET_TPC_REPORT_REQ + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr sta; + tANI_U8 dialogToken; + tANI_U8 txpower; +}tSirGetTpcReportReqParams, *tpSirGetTpcReportReqParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSirGetTpcReportReqParams getTpcReportReqParams; +}tSirGetTpcReportReqMsg, *tpSirGetTpcReportReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_TPC_REPORT_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSirGetTpcReportRspParams, *tpSirGetTpcReportRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSirGetTpcReportRspParams getTpcReportRspParams; +}tSirGetTpcReportRspMsg, *tpSirGetTpcReportRspMsg; + +#endif + +/*--------------------------------------------------------------------------- + *WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 pProbeRespTemplate[BEACON_TEMPLATE_SIZE]; + tANI_U32 probeRespTemplateLen; + tANI_U32 ucProxyProbeReqValidIEBmap[8]; + tSirMacAddr bssId; + +}tSendProbeRespReqParams, *tpSendProbeRespReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendProbeRespReqParams sendProbeRespReqParams ; +}tSendProbeRespReqMsg, *tpSendProbeRespReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssId; + tANI_U32 probeRespTemplateLen; + tANI_U32 ucProxyProbeReqValidIEBmap[8]; + tANI_U8 pProbeRespTemplate[1]; //Variable length array +}tSendProbeRespReqParams_V1, *tpSendProbeRespReqParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendProbeRespReqParams_V1 sendProbeRespReqParams_v1; +}tSendProbeRespReqMsg_V1, *tpSendProbeRespReqMsg_V1; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSendProbeRespRspParams, *tpSendProbeRespRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendProbeRespRspParams sendProbeRespRspParams; +}tSendProbeRespRspMsg, *tpSendProbeRespRspMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_UNKNOWN_ADDR2_FRAME_RX_IND + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSendUnkownFrameRxIndParams, *tpSendUnkownFrameRxIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSendUnkownFrameRxIndParams sendUnkownFrameRxIndParams; +}tSendUnkownFrameRxIndMsg, *tpSendUnkownFrameRxIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_DELETE_STA_CONTEXT_IND + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 assocId; + tANI_U16 staId; + tSirMacAddr bssId; // TO SUPPORT BT-AMP + // HAL copies bssid from the sta table. + tSirMacAddr addr2; // + tANI_U16 reasonCode; // To unify the keepalive / unknown A2 / tim-based disa + +}tDeleteStaContextParams, *tpDeleteStaContextParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDeleteStaContextParams deleteStaContextParams; +}tDeleteStaContextIndMsg, *tpDeleteStaContextIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U8 assocId; + tANI_U8 staIdx; + tANI_U8 bssIdx; + tANI_U8 uReasonCode; + tANI_U32 uStatus; +#ifdef WLAN_FEATURE_ROAM_OFFLOAD + tANI_U8 staAddr[6]; + tANI_U8 bssId[6]; +#endif +} tIndicateDelSta, *tpIndicateDelSta; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SIGNAL_BTAMP_EVENT_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tBtAmpEventType btAmpEventType; + +}tBtAmpEventParams, *tpBtAmpEventParams; + + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tBtAmpEventParams btAmpEventParams; +}tBtAmpEventMsg, *tpBtAmpEventMsg; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SIGNAL_BTAMP_EVENT_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tBtAmpEventRspParams, *tpBtAmpEventRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tBtAmpEventRspParams btAmpEventRspParams; +}tBtAmpEventRsp, *tpBtAmpEventRsp; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_TL_HAL_FLUSH_AC_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + +}tTlHalFlushAcParams, *tpTlHalFlushAcParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTlHalFlushAcParams tlHalFlushAcParam; +}tTlHalFlushAcReq, *tpTlHalFlushAcReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_TL_HAL_FLUSH_AC_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + // Station Index. originates from HAL + tANI_U8 ucSTAId; + + // TID for which the transmit queue is being flushed + tANI_U8 ucTid; + + /* success or failure */ + tANI_U32 status; +}tTlHalFlushAcRspParams, *tpTlHalFlushAcRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTlHalFlushAcRspParams tlHalFlushAcRspParam; +}tTlHalFlushAcRspMsg, *tpTlHalFlushAcRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_IMPS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalEnterImpsReqMsg, *tpHalEnterImpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_IMPS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalExitImpsReqMsg, *tpHalExitImpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_BMPS_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; + //TBTT value derived from the last beacon +#ifndef BUILD_QWPTTSTATIC + tANI_U64 tbtt; +#endif + tANI_U8 dtimCount; + //DTIM period given to HAL during association may not be valid, + //if association is based on ProbeRsp instead of beacon. + tANI_U8 dtimPeriod; + + // For ESE and 11R Roaming + tANI_U32 rssiFilterPeriod; + tANI_U32 numBeaconPerRssiAverage; + tANI_U8 bRssiFilterEnable; + +} tHalEnterBmpsReqParams, *tpHalEnterBmpsReqParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterBmpsReqParams enterBmpsReq; +} tHalEnterBmpsReqMsg, *tpHalEnterBmpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_PRINT_REG_INFO_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + uint32 regAddr; + uint32 regValue; +} tHalRegDebugInfo, *tpRegDebugInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 regCount; + uint32 scenario; + uint32 reasonCode; +} tHalRegDebugInfoParams, *tpRegDebugInfoParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRegDebugInfoParams regParams; +} tHalRegDebugInfoMsg, *tpRegDebugInfoMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_BMPS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 sendDataNull; + tANI_U8 bssIdx; +} tHalExitBmpsReqParams, *tpHalExitBmpsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitBmpsReqParams exitBmpsReqParams; +} tHalExitBmpsReqMsg, *tpHalExitBmpsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MISSED_BEACON_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; +} tHalMissedBeaconIndParams, *tpHalMissedBeaconIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMissedBeaconIndParams missedBeaconIndParams; +} tHalMissedBeaconIndMsg, *tpHalMissedBeaconIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BCN_FILTER_REQ + *--------------------------------------------------------------------------*/ +/* Beacon Filtering data structures */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 offset; + tANI_U8 value; + tANI_U8 bitMask; + tANI_U8 ref; +} tEidByteInfo, *tpEidByteInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 capabilityInfo; + tANI_U16 capabilityMask; + tANI_U16 beaconInterval; + tANI_U16 ieNum; + tANI_U8 bssIdx; + tANI_U8 reserved; +} tBeaconFilterMsg, *tpBeaconFilterMsg; + +/* The above structure would be followed by multiple of below mentioned structure */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 elementId; + tANI_U8 checkIePresence; + tEidByteInfo byte; +} tBeaconFilterIe, *tpBeaconFilterIe; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tBeaconFilterMsg addBcnFilterParams; +} tHalAddBcnFilterReqMsg, *tpHalAddBcnFilterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_REM_BCN_FILTER_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 ucIeCount; + tANI_U8 ucRemIeId[1]; +} tRemBeaconFilterMsg, *tpRemBeaconFilterMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRemBeaconFilterMsg remBcnFilterParams; +} tHalRemBcnFilterReqMsg, *tpHalRemBcnFilterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +#define HAL_IPV4_ARP_REPLY_OFFLOAD 0 +#define HAL_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 +#define HAL_IPV6_NS_OFFLOAD 2 +#define HAL_IPV6_ADDR_LEN 16 +#define HAL_MAC_ADDR_LEN 6 +#define HAL_OFFLOAD_DISABLE 0 +#define HAL_OFFLOAD_ENABLE 1 +#define HAL_OFFLOAD_BCAST_FILTER_ENABLE 0x2 +#define HAL_OFFLOAD_MCAST_FILTER_ENABLE 0x4 +#define HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE (HAL_OFFLOAD_ENABLE|HAL_OFFLOAD_BCAST_FILTER_ENABLE) +#define HAL_OFFLOAD_IPV6NS_AND_MCAST_FILTER_ENABLE (HAL_OFFLOAD_ENABLE|HAL_OFFLOAD_MCAST_FILTER_ENABLE) + +typedef PACKED_PRE struct PACKED_POST _tHalNSOffloadParams +{ + tANI_U8 srcIPv6Addr[HAL_IPV6_ADDR_LEN]; + tANI_U8 selfIPv6Addr[HAL_IPV6_ADDR_LEN]; + //Only support 2 possible Network Advertisement IPv6 address + tANI_U8 targetIPv6Addr1[HAL_IPV6_ADDR_LEN]; + tANI_U8 targetIPv6Addr2[HAL_IPV6_ADDR_LEN]; + tANI_U8 selfMacAddr[HAL_MAC_ADDR_LEN]; + tANI_U8 srcIPv6AddrValid : 1; + tANI_U8 targetIPv6Addr1Valid : 1; + tANI_U8 targetIPv6Addr2Valid : 1; + tANI_U8 reserved1 : 5; + tANI_U8 reserved2; //make it DWORD aligned + tANI_U8 bssIdx; + tANI_U32 slotIndex; // slot index for this offload +} tHalNSOffloadParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 offloadType; + tANI_U8 enableOrDisable; + PACKED_PRE union PACKED_POST + { + tANI_U8 hostIpv4Addr [4]; + tANI_U8 hostIpv6Addr [HAL_IPV6_ADDR_LEN]; + } params; +} tHalHostOffloadReq, *tpHalHostOffloadReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHostOffloadReq hostOffloadParams; + tHalNSOffloadParams nsOffloadParams; +} tHalHostOffloadReqMsg, *tpHalHostOffloadReqMsg; + + +#ifdef FEATURE_WLAN_LPHB +typedef enum +{ + WIFI_HB_SET_ENABLE = 0x0001, + WIFI_HB_SET_TCP_PARAMS = 0x0002, + WIFI_HB_SET_TCP_PKT_FILTER = 0x0003, + WIFI_HB_SET_UDP_PARAMS = 0x0004, + WIFI_HB_SET_UDP_PKT_FILTER = 0x0005, + WIFI_HB_SET_NETWORK_INFO = 0x0006, +}tLowPowerHeartBeatCmdType ; + +#define MAX_FLITER_SIZE 64 +/*--------------------------------------------------------------------------- + *FEATURE_WLAN_LPHB REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + uint32 hostIpv4Addr; + uint32 destIpv4Addr; + uint16 hostPort; + uint16 destPort; + uint16 timeOutSec; // in seconds + tSirMacAddr gatewayMacAddr; + uint16 timePeriodSec; // in seconds + uint32 tcpSn; +} tlowPowerHeartBeatParamsTcpStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 hostIpv4Addr; + uint32 destIpv4Addr; + uint16 hostPort; + uint16 destPort; + uint16 timePeriodSec;// in seconds + uint16 timeOutSec; // in seconds + tSirMacAddr gatewayMacAddr; +} tlowPowerHeartBeatParamsUdpStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 offset; + uint32 filterLength; + uint8 filter[MAX_FLITER_SIZE]; +} tlowPowerHeartBeatFilterStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 heartBeatEnable; + uint8 heartBeatType; //TCP or UDP +} tlowPowerHeartBeatEnableStruct; + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 dummy; +} tlowPowerHeartBeatNetworkInfoStruct; + + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 sessionIdx; + uint16 lowPowerHeartBeatCmdType; + PACKED_PRE union PACKED_PRO + { + tlowPowerHeartBeatEnableStruct control; + tlowPowerHeartBeatFilterStruct tcpUdpFilter; + tlowPowerHeartBeatParamsTcpStruct tcpParams; + tlowPowerHeartBeatParamsUdpStruct udpParams; + tlowPowerHeartBeatNetworkInfoStruct info; + }options; +} tHalLowPowerHeartBeatReq, *tpHalLowPowerHeartBeatReq; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLowPowerHeartBeatReq lowPowerHeartBeatParams; +} tHalLowPowerHeartBeatReqMsg, *tpHalLowPowerHeartBeatReqMsg; + +/*--------------------------------------------------------------------------- + * FEATURE_WLAN_LPHB RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + uint8 sessionIdx; + uint32 status; + uint16 lowPowerHeartBeatCmdType; +}tHalLowPowerHeartBeatRspParams, *tpHalLowPowerHeartBeatRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLowPowerHeartBeatRspParams lowPowerHeartBeatRspParams; +}tHalLowPowerHeartBeatRspMsg, *tpHalLowPowerHeartBeatRspMsg; + + +/*--------------------------------------------------------------------------- + * FEATURE_WLAN_LPHB IND + *--------------------------------------------------------------------------*/ +#define WIFI_HB_EVENT_TCP_RX_TIMEOUT 0x0001 +#define WIFI_HB_EVENT_UDP_RX_TIMEOUT 0x0002 + +#define WIFI_LPHB_EVENT_REASON_TIMEOUT 0x01 +#define WIFI_LPHB_EVENT_REASON_FW_ON_MONITOR 0x02 +#define WIFI_LPHB_EVENT_REASON_FW_OFF_MONITOR 0x03 + + +#define WIFI_LPHB_PROTO_UDP 0x01 +#define WIFI_LPHB_PROTO_TCP 0x02 + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 bssIdx; + uint8 sessionIdx; + uint8 protocolType; /*TCP or UDP*/ + uint8 eventReason; + +}tHalLowPowerHeartBeatIndParam,*tpHalLowPowerHeartBeatIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLowPowerHeartBeatIndParam lowPowerHeartBeatIndParams; +}tHalLowPowerHeartBeatIndMsg, *tpHalLowPowerHeartBeatIndMsg; + +#endif + +#ifdef FEATURE_WLAN_BATCH_SCAN + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BATCHSCAN_SET_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Scan Frerquency - default to 30Sec*/ + tANI_U32 scanInterval; + tANI_U32 numScan2Batch; + tANI_U32 bestNetworks; + tANI_U8 rfBand; + tANI_U8 rtt; +} tHalBatchScanSetParams, *tpHalBatchScanSetParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanSetParams batchScanParams; +} tHalBatchScanSetReqMsg, *tpHalBatchScanSetReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BATCHSCAN_SET_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 supportedMscan; +} tHalBatchScanSetRspParam, *tpHalBatchScanSetRspParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanSetRspParam setBatchScanRspParam; +} tHalBatchScanSetRspMsg, *tpHalBatchScanSetRspMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_BATCHSCAN_STOP_IND +*--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 param; +} tHalBatchScanStopIndParam, *tpHalBatchScanStopIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanStopIndParam param; +} tHalBatchScanStopIndMsg, *tpHalBatchScanStopIndMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_BATCHSCAN_TRIGGER_RESULT_IND +*--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 param; +} tHalBatchScanTriggerResultParam, *tpHalBatchScanTriggerResultParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanTriggerResultParam param; +} tHalBatchScanTriggerResultIndMsg, *tpHalBatchScanTriggerResultIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BATCHSCAN_GET_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssid[6]; /* BSSID */ + tANI_U8 ssid[33]; /* SSID */ + tANI_U8 ch; /* Channel */ + tANI_S8 rssi; /* RSSI or Level */ + /* Timestamp when Network was found. Used to calculate age based on timestamp in GET_RSP msg header */ + tANI_U32 timestamp; +} tHalBatchScanNetworkInfo, *tpHalBatchScanNetworkInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 scanId; /* Scan List ID. */ + /* No of AP in a Scan Result. Should be same as bestNetwork in SET_REQ msg */ + tANI_U32 numNetworksInScanList; + /* Variable data ptr: Number of AP in Scan List */ + /* following numNetworkInScanList is data of type tHalBatchScanNetworkInfo + * of sizeof(tHalBatchScanNetworkInfo) * numNetworkInScanList */ + tANI_U8 scanList[1]; +} tHalBatchScanList, *tpHalBatchScanList; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 timestamp; + tANI_U32 numScanLists; + boolean isLastResult; + /* Variable Data ptr: Number of Scan Lists*/ + /* following isLastResult is data of type tHalBatchScanList + * of sizeof(tHalBatchScanList) * numScanLists*/ + tANI_U8 scanResults[1]; +} tHalBatchScanResultIndParam, *tpHalBatchScanResultIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBatchScanResultIndParam resultIndMsgParam; +} tHalBatchScanResultIndMsg, *tpHalBatchScanResultIndMsg; + +#endif + +/*--------------------------------------------------------------------------- + * WLAN_HAL_KEEP_ALIVE_REQ + *--------------------------------------------------------------------------*/ +/* Packet Types. */ +#define HAL_KEEP_ALIVE_NULL_PKT 1 +#define HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 + +/* Enable or disable keep alive */ +#define HAL_KEEP_ALIVE_DISABLE 0 +#define HAL_KEEP_ALIVE_ENABLE 1 + +/* Keep Alive request. */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 packetType; + tANI_U32 timePeriod; + tHalIpv4Addr hostIpv4Addr; + tHalIpv4Addr destIpv4Addr; + tSirMacAddr destMacAddr; + tANI_U8 bssIdx; +} tHalKeepAliveReq, *tpHalKeepAliveReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalKeepAliveReq KeepAliveParams; +} tHalKeepAliveReqMsg, *tpHalKeepAliveReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_RSSI_THRESH_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_S8 ucRssiThreshold1 : 8; + tANI_S8 ucRssiThreshold2 : 8; + tANI_S8 ucRssiThreshold3 : 8; + tANI_U8 bRssiThres1PosNotify : 1; + tANI_U8 bRssiThres1NegNotify : 1; + tANI_U8 bRssiThres2PosNotify : 1; + tANI_U8 bRssiThres2NegNotify : 1; + tANI_U8 bRssiThres3PosNotify : 1; + tANI_U8 bRssiThres3NegNotify : 1; + tANI_U8 bReserved10 : 2; +} tHalRSSIThresholds, *tpHalRSSIThresholds; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRSSIThresholds rssiThreshParams; +} tHalRSSIThresholdReqMsg, *tpHalRSSIThresholdReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_UAPSD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bkDeliveryEnabled:1; + tANI_U8 beDeliveryEnabled:1; + tANI_U8 viDeliveryEnabled:1; + tANI_U8 voDeliveryEnabled:1; + tANI_U8 bkTriggerEnabled:1; + tANI_U8 beTriggerEnabled:1; + tANI_U8 viTriggerEnabled:1; + tANI_U8 voTriggerEnabled:1; + tANI_U8 bssIdx; +} tUapsdReqParams, *tpUapsdReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUapsdReqParams enterUapsdParams; +} tHalEnterUapsdReqMsg, *tpHalEnterUapsdReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_UAPSD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U8 bssIdx; +} tHalExitUapsdReqMsg, *tpHalExitUapsdReqMsg; + +#define HAL_PERIODIC_TX_PTRN_MAX_SIZE 1536 +#define HAL_MAXNUM_PERIODIC_TX_PTRNS 6 +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_PERIODIC_TX_PTRN_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 selfStaIdx:8; + tANI_U32 ucPtrnId:8; // Pattern ID + tANI_U32 usPtrnSize:16; // Non-Zero Pattern size + tANI_U32 uPtrnIntervalMs; // In msec + tANI_U8 ucPattern[HAL_PERIODIC_TX_PTRN_MAX_SIZE]; // Pattern buffer +} tHalAddPeriodicTxPtrn, *tpHalAddPeriodicTxPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAddPeriodicTxPtrn ptrnParams; +} tHalAddPeriodicTxPtrnIndMsg, *tpHalAddPeriodicTxPtrnIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_PERIODIC_TX_PTRN_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 selfStaIdx:8; + tANI_U32 rsvd:24; + /* Bitmap of pattern IDs that needs to be deleted */ + tANI_U32 uPatternIdBitmap; +} tHalDelPeriodicTxPtrn, *tpHalDelPeriodicTxPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDelPeriodicTxPtrn ptrnParams; +} tHalDelPeriodicTxPtrnIndMsg, *tpHalDelPeriodicTxPtrnIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_PERIODIC_TX_PTRN_FW_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Type of Failure indication */ + tANI_U32 bssIdx:8; + tANI_U32 selfStaIdx:8; + tANI_U32 rsvd:16; + tANI_U32 status; + tANI_U32 patternIdBitmap; +} tHalPeriodicTxPtrnFwInd, *tpHalPeriodicTxPtrnFwInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalPeriodicTxPtrnFwInd fwIndParams; +} tHalPeriodicTxPtrnFwIndMsg, *tpHalPeriodicTxPtrnFwIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_WOWL_BCAST_PTRN + *--------------------------------------------------------------------------*/ +#define HAL_WOWL_BCAST_PATTERN_MAX_SIZE 128 +#define HAL_WOWL_BCAST_MAX_NUM_PATTERNS 16 + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 ucPatternId; // Pattern ID + // Pattern byte offset from beginning of the 802.11 packet to start of the + // wake-up pattern + tANI_U8 ucPatternByteOffset; + tANI_U8 ucPatternSize; // Non-Zero Pattern size + tANI_U8 ucPattern[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern + tANI_U8 ucPatternMaskSize; // Non-zero pattern mask size + tANI_U8 ucPatternMask[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Pattern mask + tANI_U8 ucPatternExt[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern + tANI_U8 ucPatternMaskExt[HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; // Extra pattern mask + tANI_U8 bssIdx; +} tHalWowlAddBcastPtrn, *tpHalWowlAddBcastPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlAddBcastPtrn ptrnParams; +} tHalWowlAddBcastPtrnReqMsg, *tpHalWowlAddBcastPtrnReqMsg; + + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_WOWL_BCAST_PTRN + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Pattern ID of the wakeup pattern to be deleted */ + tANI_U8 ucPatternId; + tANI_U8 bssIdx; +} tHalWowlDelBcastPtrn, *tpHalWowlDelBcastPtrn; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlDelBcastPtrn ptrnParams; +} tHalWowlDelBcastPtrnReqMsg, *tpHalWowlDelBcastPtrnReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_WOWL_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* Enables/disables magic packet filtering */ + tANI_U8 ucMagicPktEnable; + + /* Magic pattern */ + tSirMacAddr magicPtrn; + + /* Enables/disables packet pattern filtering in firmware. + Enabling this flag enables broadcast pattern matching + in Firmware. If unicast pattern matching is also desired, + ucUcastPatternFilteringEnable flag must be set tot true + as well + */ + tANI_U8 ucPatternFilteringEnable; + + /* Enables/disables unicast packet pattern filtering. + This flag specifies whether we want to do pattern match + on unicast packets as well and not just broadcast packets. + This flag has no effect if the ucPatternFilteringEnable + (main controlling flag) is set to false + */ + tANI_U8 ucUcastPatternFilteringEnable; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Channel Switch Action Frame. + */ + tANI_U8 ucWowChnlSwitchRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Deauthentication Frame. + */ + tANI_U8 ucWowDeauthRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it receives the + * Disassociation Frame. + */ + tANI_U8 ucWowDisassocRcv; + + /* This configuration is valid only when magicPktEnable=1. + * It requests hardware to wake up when it has missed + * consecutive beacons. This is a hardware register + * configuration (NOT a firmware configuration). + */ + tANI_U8 ucWowMaxMissedBeacons; + + /* This configuration is valid only when magicPktEnable=1. + * This is a timeout value in units of microsec. It requests + * hardware to unconditionally wake up after it has stayed + * in WoWLAN mode for some time. Set 0 to disable this feature. + */ + tANI_U8 ucWowMaxSleepUsec; + + /* This configuration directs the WoW packet filtering to look for EAP-ID + * requests embedded in EAPOL frames and use this as a wake source. + */ + tANI_U8 ucWoWEAPIDRequestEnable; + + /* This configuration directs the WoW packet filtering to look for EAPOL-4WAY + * requests and use this as a wake source. + */ + tANI_U8 ucWoWEAPOL4WayEnable; + + /* This configuration allows a host wakeup on an network scan offload match. + */ + tANI_U8 ucWowNetScanOffloadMatch; + + /* This configuration allows a host wakeup on any GTK rekeying error. + */ + tANI_U8 ucWowGTKRekeyError; + + /* This configuration allows a host wakeup on BSS connection loss. + */ + tANI_U8 ucWoWBSSConnLoss; + + tANI_U8 bssIdx; + +} tHalWowlEnterParams, *tpHalWowlEnterParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlEnterParams enterWowlParams; +} tHalWowlEnterReqMsg, *tpHalWowlEnterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_WOWL_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; + +} tHalWowlExitParams, *tpHalWowlExitParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWowlExitParams exitWowlParams; +} tHalWowlExitReqMsg, *tpHalWowlExitReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_RSSI_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +} tHalGetRssiReqMsg, *tpHalGetRssiReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Valid STA Idx for per STA stats request */ + tANI_U32 staId; + +}tHalRoamRssiReqParams, *tpHalRoamRssiReqParams; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_ROAM_RSSI_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRoamRssiReqParams roamRssiReqParams; +} tHalGetRoamRssiReqMsg, *tpHalGetRoamRssiReqMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_UAPSD_AC_PARAMS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 staidx; // STA index + tANI_U8 ac; // Access Category + tANI_U8 up; // User Priority + tANI_U32 srvInterval; // Service Interval + tANI_U32 susInterval; // Suspend Interval + tANI_U32 delayInterval; // Delay Interval +} tUapsdInfo, tpUapsdInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUapsdInfo enableUapsdAcParams; +} tHalSetUapsdAcParamsReqMsg, *tpHalSetUapsdAcParamsReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_RXP_FILTER_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 setMcstBcstFilterSetting; + tANI_U8 setMcstBcstFilter; +} tHalConfigureRxpFilterReqParams, tpHalConfigureRxpFilterReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureRxpFilterReqParams configureRxpFilterReqParams; +} tHalConfigureRxpFilterReqMsg, *tpHalConfigureRxpFilterReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_IMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalEnterImpsRspParams, *tpHalEnterImpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterImpsRspParams enterImpsRspParams; +} tHalEnterImpsRspMsg, *tpHalEnterImpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_IMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalExitImpsRspParams, *tpHalExitImpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitImpsRspParams exitImpsRspParams; +} tHalExitImpsRspMsg, *tpHalExitImpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_BMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalEnterBmpsRspParams, *tpHalEnterBmpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterBmpsRspParams enterBmpsRspParams; +} tHalEnterBmpsRspMsg, *tpHalEnterBmpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_BMPS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalExitBmpsRspParams, *tpHalExitBmpsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitBmpsRspParams exitBmpsRspParams; +} tHalExitBmpsRspMsg, *tpHalExitBmpsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_UAPSD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +}tUapsdRspParams, *tpUapsdRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUapsdRspParams enterUapsdRspParams; +} tHalEnterUapsdRspMsg, *tpHalEnterUapsdRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_UAPSD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalExitUapsdRspParams, *tpHalExitUapsdRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitUapsdRspParams exitUapsdRspParams; +} tHalExitUapsdRspMsg, *tpHalExitUapsdRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_RSSI_NOTIFICATION_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 bRssiThres1PosCross : 1; + tANI_U32 bRssiThres1NegCross : 1; + tANI_U32 bRssiThres2PosCross : 1; + tANI_U32 bRssiThres2NegCross : 1; + tANI_U32 bRssiThres3PosCross : 1; + tANI_U32 bRssiThres3NegCross : 1; + tANI_U32 avgRssi : 8; + tANI_U32 uBssIdx : 8; + tANI_U32 isBTCoexCompromise : 1; + tANI_U32 bReserved : 9; + tANI_S8 refRssiThreshold1; + tANI_S8 refRssiThreshold2; + tANI_S8 refRssiThreshold3; +} tHalRSSINotification, *tpHalRSSINotification; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRSSINotification rssiNotificationParams; +} tHalRSSINotificationIndMsg, *tpHalRSSINotificationIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_RSSI_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_S8 rssi; +} tHalGetRssiParams, *tpHalGetRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalGetRssiParams rssiRspParams; +} tHalGetRssiRspMsg, *tpHalGetRssiRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_ROAM_RSSI_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + tANI_U8 staId; + tANI_S8 rssi; +} tHalGetRoamRssiParams, *tpHalGetRoamRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalGetRoamRssiParams roamRssiRspParams; +} tHalGetRoamRssiRspMsg, *tpHalGetRoamRssiRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ENTER_WOWL_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalEnterWowlRspParams, *tpHalEnterWowlRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnterWowlRspParams enterWowlRspParams; +} tHalWowlEnterRspMsg, *tpHalWowlEnterRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXIT_WOWL_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalExitWowlRspParams, *tpHalExitWowlRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExitWowlRspParams exitWowlRspParams; +} tHalWowlExitRspMsg, *tpHalWowlExitRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_BCN_FILTER_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalAddBcnFilterRspParams, *tpHalAddBcnFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAddBcnFilterRspParams addBcnFilterRspParams; +} tHalAddBcnFilterRspMsg, *tpHalAddBcnFilterRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_REM_BCN_FILTER_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalRemBcnFilterRspParams, *tpHalRemBcnFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRemBcnFilterRspParams remBcnFilterRspParams; +} tHalRemBcnFilterRspMsg, *tpHalRemBcnFilterRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ADD_WOWL_BCAST_PTRN_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalAddWowlBcastPtrnRspParams, *tpHalAddWowlBcastPtrnRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAddWowlBcastPtrnRspParams addWowlBcastPtrnRspParams; +} tHalAddWowlBcastPtrnRspMsg, *tpHalAddWowlBcastPtrnRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DEL_WOWL_BCAST_PTRN_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalDelWowlBcastPtrnRspParams, *tpHalDelWowlBcastPtrnRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDelWowlBcastPtrnRspParams delWowlBcastRspParams; +} tHalDelWowlBcastPtrnRspMsg, *tpHalDelWowlBcastPtrnRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalHostOffloadRspParams, *tpHalHostOffloadRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHostOffloadRspParams hostOffloadRspParams; +} tHalHostOffloadRspMsg, *tpHalHostOffloadRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_KEEP_ALIVE_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalKeepAliveRspParams, *tpHalKeepAliveRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalKeepAliveRspParams keepAliveRspParams; +} tHalKeepAliveRspMsg, *tpHalKeepAliveRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_RSSI_THRESH_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalSetRssiThreshRspParams, *tpHalSetRssiThreshRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSetRssiThreshRspParams setRssiThreshRspParams; +} tHalSetRssiThreshRspMsg, *tpHalSetRssiThreshRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_UAPSD_AC_PARAMS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalSetUapsdAcParamsRspParams, *tpHalSetUapsdAcParamsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSetUapsdAcParamsRspParams setUapsdAcParamsRspParams; +} tHalSetUapsdAcParamsRspMsg, *tpHalSetUapsdAcParamsRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_RXP_FILTER_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalConfigureRxpFilterRspParams, *tpHalConfigureRxpFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureRxpFilterRspParams configureRxpFilterRspParams; +} tHalConfigureRxpFilterRspMsg, *tpHalConfigureRxpFilterRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_MAX_TX_POWER_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr bssId; // BSSID is needed to identify which session issued this request. As + //the request has power constraints, this should be applied only to that session + tSirMacAddr selfStaMacAddr; + //In request, + //power == MaxTx power to be used. + tPowerdBm power; + +}tSetMaxTxPwrParams, *tpSetMaxTxPwrParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrParams setMaxTxPwrParams; +}tSetMaxTxPwrReq, *tpSetMaxTxPwrReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_MAX_TX_POWER_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + //power == tx power used for management frames. + tPowerdBm power; + + /* success or failure */ + tANI_U32 status; +}tSetMaxTxPwrRspParams, *tpSetMaxTxPwrRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrRspParams setMaxTxPwrRspParams; +}tSetMaxTxPwrRspMsg, *tpSetMaxTxPwrRspMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ + *--------------------------------------------------------------------------*/ + +/* Band types for WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_REQ between WDI and HAL */ +typedef enum +{ + WLAN_HAL_SET_MAX_TX_POWER_BAND_ALL = 0, + // For 2.4GHz or 5GHz bands + WLAN_HAL_SET_MAX_TX_POWER_BAND_2_4_GHZ, + WLAN_HAL_SET_MAX_TX_POWER_BAND_5_0_GHZ, + // End of valid enums + WLAN_HAL_SET_MAX_TX_POWER_BAND_MAX = WLAN_HAL_MAX_ENUM_SIZE, +}tHalSetMaxTxPwrBandInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalSetMaxTxPwrBandInfo bandInfo; // 2_4_GHZ or 5_0_GHZ + tPowerdBm power; // In request, power == MaxTx power to be used. +}tSetMaxTxPwrPerBandParams, *tpSetMaxTxPwrPerBandParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrPerBandParams setMaxTxPwrPerBandParams; +}tSetMaxTxPwrPerBandReq, *tpSetMaxTxPwrPerBandReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_MAX_TX_POWER_PER_BAND_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + //power == tx power used for management frames. + tPowerdBm power; + + /* success or failure */ + tANI_U32 status; +}tSetMaxTxPwrPerBandRspParams, *tpSetMaxTxPwrPerBandRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetMaxTxPwrPerBandRspParams setMaxTxPwrPerBandRspParams; +}tSetMaxTxPwrPerBandRspMsg, *tpSetMaxTxPwrPerBandRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_TX_POWER_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* TX Power in milli watts */ + tANI_U32 txPower; + tANI_U8 bssIdx; +}tSetTxPwrReqParams, *tpSetTxPwrReqParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetTxPwrReqParams setTxPwrReqParams; +}tSetTxPwrReqMsg, *tpSetTxPwrReqMsg; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_TX_POWER_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSetTxPwrRspParams, *tpSetTxPwrRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetTxPwrRspParams setTxPwrRspParams; +}tSetTxPwrRspMsg, *tpSetTxPwrRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_GET_TX_POWER_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 staId; +}tGetTxPwrReqParams, *tpGetTxPwrReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tGetTxPwrReqParams getTxPwrReqParams; +}tGetTxPwrReqMsg, *tpGetTxPwrReqMsg; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_GET_TX_POWER_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + /* TX Power in milli watts */ + tANI_U32 txPower; +}tGetTxPwrRspParams, *tpGetTxPwrRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tGetTxPwrRspParams getTxPwrRspParams; +}tGetTxPwrRspMsg, *tpGetTxPwrRspMsg; + +#ifdef WLAN_FEATURE_P2P +/*--------------------------------------------------------------------------- + *WLAN_HAL_SET_P2P_GONOA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 opp_ps; + tANI_U32 ctWindow; + tANI_U8 count; + tANI_U32 duration; + tANI_U32 interval; + tANI_U32 single_noa_duration; + tANI_U8 psSelection; +}tSetP2PGONOAParams, *tpSetP2PGONOAParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetP2PGONOAParams setP2PGONOAParams; +}tSetP2PGONOAReq, *tpSetP2PGONOAReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_SET_P2P_GONOA_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +}tSetP2PGONOARspParams, *tpSetP2PGONOARspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetP2PGONOARspParams setP2PGONOARspParams; +}tSetP2PGONOARspMsg, *tpSetP2PGONOARspMsg; +#endif + +/*--------------------------------------------------------------------------- + *WLAN_HAL_ADD_SELF_STA_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + tANI_U32 status; +}tAddStaSelfParams, *tpAddStaSelfParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddStaSelfParams addStaSelfParams; +}tAddStaSelfReq, *tpAddStaSelfReq; + +/* This V1 structure carries additionally the IFACE PERSONA + of the interface as compared to the legacy control + message */ +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + tANI_U32 status; + tHalIfacePersona iface_persona; +}tAddStaSelfParams_V1, *tpAddStaSelfParams_V1; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddStaSelfParams_V1 addStaSelfParams_V1; +}tAddStaSelfReq_V1, *tpAddStaSelfReq_V1; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_ADD_SELF_STA_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + /*Self STA Index */ + tANI_U8 selfStaIdx; + + /* DPU Index (IGTK, PTK, GTK all same) */ + tANI_U8 dpuIdx; + + /* DPU Signature */ + tANI_U8 dpuSignature; + +}tAddStaSelfRspParams, *tpAddStaSelfRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAddStaSelfRspParams addStaSelfRspParams; +}tAddStaSelfRspMsg, *tpAddStaSelfRspMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_DEL_STA_SELF_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + +}tDelStaSelfParams, *tpDelStaSelfParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelStaSelfParams delStaSelfParams; +} tDelStaSelfReqMsg, *tpDelStaSelfReqMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_DEL_STA_SELF_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*success or failure */ + tANI_U32 status; + + tSirMacAddr selfMacAddr; +}tDelStaSelfRspParams, *tpDelStaSelfRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tDelStaSelfRspParams delStaSelfRspParams; +} tDelStaSelfRspMsg, *tpDelStaSelfRspMsg; + + +#ifdef WLAN_FEATURE_VOWIFI_11R + +/*--------------------------------------------------------------------------- + *WLAN_HAL_AGGR_ADD_TS_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Station Index */ + tANI_U16 staIdx; + + /* TSPEC handler uniquely identifying a TSPEC for a STA in a BSS */ + /* This will carry the bitmap with the bit positions representing different AC.s*/ + tANI_U16 tspecIdx; + + /* Tspec info per AC To program TPE with required parameters */ + tSirMacTspecIE tspec[WLAN_HAL_MAX_AC]; + + /* U-APSD Flags: 1b per AC. Encoded as follows: + b7 b6 b5 b4 b3 b2 b1 b0 = + X X X X BE BK VI VO */ + tANI_U8 uAPSD; + + /* These parameters are for all the access categories */ + tANI_U32 srvInterval[WLAN_HAL_MAX_AC]; // Service Interval + tANI_U32 susInterval[WLAN_HAL_MAX_AC]; // Suspend Interval + tANI_U32 delayInterval[WLAN_HAL_MAX_AC]; // Delay Interval + +}tAggrAddTsParams, *tpAggrAddTsParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAggrAddTsParams aggrAddTsParam; +}tAggrAddTsReq, *tpAggrAddTsReq; + +/*--------------------------------------------------------------------------- +*WLAN_HAL_AGGR_ADD_TS_RSP +*--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status0; + /* FIXME PRIMA for future use for 11R */ + tANI_U32 status1; +}tAggrAddTsRspParams, *tpAggrAddTsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tAggrAddTsRspParams aggrAddTsRspParam; +}tAggrAddTsRspMsg, *tpAggrAddTsRspMsg; + +#endif + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 isAppsCpuAwake; +} tHalConfigureAppsCpuWakeupStateReqParams, *tpHalConfigureAppsCpuWakeupStatReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureAppsCpuWakeupStateReqParams appsStateReqParams; +} tHalConfigureAppsCpuWakeupStateReqMsg, *tpHalConfigureAppsCpuWakeupStateReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalConfigureAppsCpuWakeupStateRspParams, *tpHalConfigureAppsCpuWakeupStateRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalConfigureAppsCpuWakeupStateRspParams appsStateRspParams; +} tHalConfigureAppsCpuWakeupStateRspMsg, *tpHalConfigureAppsCpuWakeupStateRspMsg; +/*--------------------------------------------------------------------------- + * WLAN_HAL_DUMP_COMMAND_REQ + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 argument1; + tANI_U32 argument2; + tANI_U32 argument3; + tANI_U32 argument4; + tANI_U32 argument5; + +}tHalDumpCmdReqParams,*tpHalDumpCmdReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDumpCmdReqParams dumpCmdReqParams; +} tHalDumpCmdReqMsg, *tpHalDumpCmdReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DUMP_COMMAND_RSP + *--------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + /*Length of the responce message*/ + tANI_U32 rspLength; + /*FiXME: Currently considering the the responce will be less than 100bytes */ + tANI_U8 rspBuffer[DUMPCMD_RSP_BUFFER]; + +} tHalDumpCmdRspParams, *tpHalDumpCmdRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDumpCmdRspParams dumpCmdRspParams; +} tHalDumpCmdRspMsg, *tpHalDumpCmdRspMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_COEX_IND + *-------------------------------------------------------------------------*/ +#define WLAN_COEX_IND_DATA_SIZE (4) +#define WLAN_COEX_IND_TYPE_DISABLE_HB_MONITOR (0) +#define WLAN_COEX_IND_TYPE_ENABLE_HB_MONITOR (1) +#define WLAN_COEX_IND_TYPE_SCANS_ARE_COMPROMISED_BY_COEX (2) +#define WLAN_COEX_IND_TYPE_SCANS_ARE_NOT_COMPROMISED_BY_COEX (3) +#define WLAN_COEX_IND_TYPE_DISABLE_AGGREGATION_IN_2p4 (4) +#define WLAN_COEX_IND_TYPE_ENABLE_AGGREGATION_IN_2p4 (5) +#define WLAN_COEX_IND_TYPE_ENABLE_UAPSD (6) +#define WLAN_COEX_IND_TYPE_DISABLE_UAPSD (7) +#define WLAN_COEX_IND_TYPE_CXM_FEATURES_NOTIFICATION (8) +#define WLAN_COEX_IND_TYPE_HID_CONNECTED_WLAN_CONNECTED_IN_2p4 (9) +#define WLAN_COEX_IND_TYPE_HID_DISCONNECTED_WLAN_CONNECTED_IN_2p4 (10) + +typedef PACKED_PRE struct PACKED_POST +{ + /*Coex Indication Type*/ + tANI_U32 coexIndType; + + /*Coex Indication Data*/ + tANI_U32 coexIndData[WLAN_COEX_IND_DATA_SIZE]; +}tCoexIndParams,*tpCoexIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tCoexIndParams coexIndParams; +}tCoexIndMsg, *tpCoexIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_OTA_TX_COMPL_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /*Tx Complete Indication Success or Failure*/ + tANI_U32 status; + /* Dialog token */ + tANI_U32 dialogToken; +}tTxComplParams,*tpTxComplParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTxComplParams txComplParams; +}tTxComplIndMsg, *tpTxComplIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_SUSPEND_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 configuredMcstBcstFilterSetting; + tANI_U32 activeSessionCount; +}tHalWlanHostSuspendIndParam,*tpHalWlanHostSuspendIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanHostSuspendIndParam suspendIndParams; +}tHalWlanHostSuspendIndMsg, *tpHalWlanHostSuspendIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXCLUDE_UNENCRYTED_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_BOOLEAN bDot11ExcludeUnencrypted; + tSirMacAddr bssId; +}tHalWlanExcludeUnEncryptedIndParam,*tpHalWlanExcludeUnEncryptedIndParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanExcludeUnEncryptedIndParam excludeUnEncryptedIndParams; +}tHalWlanExcludeUnEncrptedIndMsg, *tpHalWlanExcludeUnEncrptedIndMsg; + +#ifdef WLAN_FEATURE_P2P +/*--------------------------------------------------------------------------- + *WLAN_HAL_NOA_ATTR_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 index ; + tANI_U8 oppPsFlag ; + tANI_U16 ctWin ; + + tANI_U16 uNoa1IntervalCnt; + tANI_U16 bssIdx; + tANI_U32 uNoa1Duration; + tANI_U32 uNoa1Interval; + tANI_U32 uNoa1StartTime; + + tANI_U16 uNoa2IntervalCnt; + tANI_U16 rsvd2; + tANI_U32 uNoa2Duration; + tANI_U32 uNoa2Interval; + tANI_U32 uNoa2StartTime; + + tANI_U32 status; +}tNoaAttrIndParams, *tpNoaAttrIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tNoaAttrIndParams noaAttrIndParams; +}tNoaAttrIndMsg, *tpNoaAttrIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_NOA_START_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U32 bssIdx; +}tNoaStartIndParams, *tpNoaStartIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tNoaStartIndParams noaStartIndParams; +}tNoaStartIndMsg, tpNoaStartIndMsg; +#endif + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_RESUME_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 configuredMcstBcstFilterSetting; +}tHalWlanHostResumeReqParam,*tpHalWlanHostResumeReqParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanHostResumeReqParam resumeReqParams; +}tHalWlanHostResumeReqMsg, *tpHalWlanHostResumeReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HOST_RESUME_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalHostResumeRspParams, *tpHalHostResumeRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHostResumeRspParams hostResumeRspParams; +} tHalHostResumeRspMsg, *tpHalHostResumeRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 staIdx; + // Peer MAC Address, whose BA session has timed out + tSirMacAddr peerMacAddr; + // TID for which a BA session timeout is being triggered + tANI_U8 baTID; + // DELBA direction + // 1 - Originator + // 0 - Recipient + tANI_U8 baDirection; + tANI_U32 reasonCode; + tSirMacAddr bssId; // TO SUPPORT BT-AMP +} tHalWlanDelBaIndMsg, *tpHalWlanDelBaIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalWlanDelBaIndMsg hostdelBaParam; +} tHalDelBAIndMsg, *tpHalDelBAIndMsg; + +/*--------------------------------------------------------------------------- + *PNO Messages + *-------------------------------------------------------------------------*/ +/* Max number of channels that a network can be found on*/ +/* WLAN_HAL_PNO_MAX_NETW_CHANNELS and WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX should + * be changed at same time + */ +#define WLAN_HAL_PNO_MAX_NETW_CHANNELS 60 + +/*Max number of channels that a network can be found on*/ +#define WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX 60 + +/*Maximum numbers of networks supported by PNO*/ +#define WLAN_HAL_PNO_MAX_SUPP_NETWORKS 16 + +/*The number of scan time intervals that can be programmed into PNO*/ +#define WLAN_HAL_PNO_MAX_SCAN_TIMERS 10 + +/*Maximum size of the probe template*/ +#define WLAN_HAL_PNO_MAX_PROBE_SIZE 450 + +/*Type of PNO enabling + Immediate - scanning will start immediately and PNO procedure will + be repeated based on timer + Suspend - scanning will start at suspend + Resume - scanning will start on system resume + Delay - start the scan timer to trigger PNO scan + */ +typedef enum +{ + ePNO_MODE_IMMEDIATE, + ePNO_MODE_ON_SUSPEND, + ePNO_MODE_ON_RESUME, + ePNO_MODE_DELAY, + ePNO_MODE_PROXIMITY, // FEATURE_WIFI_PROXIMITY + ePNO_MODE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} ePNOMode; + +/*Authentication type*/ +typedef enum +{ + eAUTH_TYPE_ANY = 0, + eAUTH_TYPE_OPEN_SYSTEM = 1, + + // Upper layer authentication types + eAUTH_TYPE_WPA = 2, + eAUTH_TYPE_WPA_PSK = 3, + + eAUTH_TYPE_RSN = 4, + eAUTH_TYPE_RSN_PSK = 5, + eAUTH_TYPE_FT_RSN = 6, + eAUTH_TYPE_FT_RSN_PSK = 7, + eAUTH_TYPE_WAPI_WAI_CERTIFICATE = 8, + eAUTH_TYPE_WAPI_WAI_PSK = 9, + eAUTH_TYPE_CCKM_WPA = 10, + eAUTH_TYPE_CCKM_RSN = 11, + eAUTH_TYPE_RSN_PSK_SHA256 = 12, + eAUTH_TYPE_RSN_8021X_SHA256 = 13, + + eAUTH_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE + +}tAuthType; + +/* Encryption type */ +typedef enum eEdType +{ + eED_ANY = 0, + eED_NONE = 1, + eED_WEP = 2, + eED_TKIP = 3, + eED_CCMP = 4, + eED_WPI = 5, + + eED_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tEdType; + +/* SSID broadcast type */ +typedef enum eSSIDBcastType +{ + eBCAST_UNKNOWN = 0, + eBCAST_NORMAL = 1, + eBCAST_HIDDEN = 2, + + eBCAST_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tSSIDBcastType; + +/* + The network description for which PNO will have to look for +*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*Authentication type for the network*/ + tAuthType authentication; + + /*Encryption type for the network*/ + tEdType encryption; + + /*Indicate the channel on which the Network can be found + 0 - if all channels */ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS]; + + /*Indicates the RSSI threshold for the network to be considered*/ + tANI_U8 rssiThreshold; +}tNetworkType; + +typedef PACKED_PRE struct PACKED_POST +{ + /*How much it should wait */ + tANI_U32 uTimerValue; + + /*How many times it should repeat that wait value + 0 - keep using this timer until PNO is disabled*/ + tANI_U32 uTimerRepeat; + + /*e.g: 2 3 + 4 0 + - it will wait 2s between consecutive scans for 3 times + - after that it will wait 4s between consecutive scans until disabled*/ +}tScanTimer; + +/* + The network parameters to be sent to the PNO algorithm +*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*set to 0 if you wish for PNO to use its default telescopic timer*/ + tANI_U8 ucScanTimersCount; + + /*A set value represents the amount of time that PNO will wait between + two consecutive scan procedures + If the desired is for a uniform timer that fires always at the exact same + interval - one single value is to be set + If there is a desire for a more complex - telescopic like timer multiple + values can be set - once PNO reaches the end of the array it will + continue scanning at intervals presented by the last value*/ + tScanTimer aTimerValues[WLAN_HAL_PNO_MAX_SCAN_TIMERS]; + +}tScanTimersType; + +typedef PACKED_PRE struct PACKED_POST { + + /*Enable PNO*/ + tANI_U32 enable; + + /*Immediate, On Suspend, On Resume*/ + ePNOMode modePNO; + + /*Number of networks sent for PNO*/ + tANI_U32 ucNetworksCount; + + /*The networks that PNO needs to look for*/ + tNetworkType aNetworks[WLAN_HAL_PNO_MAX_SUPP_NETWORKS]; + + /*The scan timers required for PNO*/ + tScanTimersType scanTimers; + + /*Probe template for 2.4GHz band*/ + tANI_U16 us24GProbeSize; + tANI_U8 a24GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + tANI_U16 us5GProbeSize; + tANI_U8 a5GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + +} tPrefNetwListParams, * tpPrefNetwListParams; + +/* + Preferred network list request +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPrefNetwListParams prefNetwListParams; +} tSetPrefNetwListReq, *tpSetPrefNetwListReq; + + +/* + The network description for which PNO will have to look for +*/ +typedef PACKED_PRE struct PACKED_POST +{ + /*SSID of the BSS*/ + tSirMacSSid ssId; + + /*Authentication type for the network*/ + tAuthType authentication; + + /*Encryption type for the network*/ + tEdType encryption; + + /*SSID broadcast type, normal, hidden or unknown*/ + tSSIDBcastType bcastNetworkType; + + /*Indicate the channel on which the Network can be found + 0 - if all channels */ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS]; + + /*Indicates the RSSI threshold for the network to be considered*/ + tANI_U8 rssiThreshold; +}tNetworkTypeNew; + +typedef PACKED_PRE struct PACKED_POST { + + /*Enable PNO*/ + tANI_U32 enable; + + /*Immediate, On Suspend, On Resume*/ + ePNOMode modePNO; + + /*Number of networks sent for PNO*/ + tANI_U32 ucNetworksCount; + + /*The networks that PNO needs to look for*/ + tNetworkTypeNew aNetworks[WLAN_HAL_PNO_MAX_SUPP_NETWORKS]; + + /*The scan timers required for PNO*/ + tScanTimersType scanTimers; + + /*Probe template for 2.4GHz band*/ + tANI_U16 us24GProbeSize; + tANI_U8 a24GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + + /*Probe template for 5GHz band*/ + tANI_U16 us5GProbeSize; + tANI_U8 a5GProbeTemplate[WLAN_HAL_PNO_MAX_PROBE_SIZE]; + +} tPrefNetwListParamsNew, * tpPrefNetwListParamsNew; + +/* + Preferred network list request new +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPrefNetwListParamsNew prefNetwListParams; +} tSetPrefNetwListReqNew, *tpSetPrefNetwListReqNew; + +#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacSSid ssId; + tANI_U8 currAPbssid[HAL_MAC_ADDR_LEN]; + tANI_U32 authentication; + tEdType encryption; + tEdType mcencryption; + tANI_U8 ChannelCount; + tANI_U8 ChannelCache[WLAN_HAL_ROAM_SCAN_MAX_CHANNELS]; +}tRoamNetworkType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 mdiePresent; + tANI_U16 mobilityDomain; +}tMobilityDomainInfo; + +typedef PACKED_PRE struct PACKED_POST { + eAniBoolean RoamScanOffloadEnabled; + tANI_S8 LookupThreshold; + tANI_U8 RoamRssiDiff; + tANI_U8 ChannelCacheType; + tANI_U8 Command; + tANI_U8 StartScanReason; + tANI_U16 NeighborScanTimerPeriod; + tANI_U16 NeighborRoamScanRefreshPeriod; + tANI_U16 NeighborScanChannelMinTime; + tANI_U16 NeighborScanChannelMaxTime; + tANI_U16 EmptyRefreshScanPeriod; + tANI_U8 ValidChannelCount; + tANI_U8 ValidChannelList[WLAN_HAL_ROAM_SCAN_MAX_CHANNELS]; + eAniBoolean IsESEEnabled; + + tANI_U16 us24GProbeSize; + tANI_U8 a24GProbeTemplate[WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE]; + tANI_U16 us5GProbeSize; + tANI_U8 a5GProbeTemplate[WLAN_HAL_ROAM_SCAN_MAX_PROBE_SIZE]; + /* Add Reserved bytes */ + tANI_U8 nProbes; + tANI_U16 HomeAwayTime; + eAniBoolean MAWCEnabled; + tANI_S8 RxSensitivityThreshold; + tANI_U8 RoamOffloadEnabled; + tANI_U8 PMK[WLAN_HAL_ROAM_SACN_PMK_SIZE]; + tANI_U8 Prefer5GHz; + tANI_U8 RoamRssiCatGap; + tANI_U8 Select5GHzMargin; + tANI_U8 WeakZoneRssiThresholdForRoam; + tANI_U8 ReservedBytes[WLAN_HAL_ROAM_SCAN_RESERVED_BYTES]; + tRoamNetworkType ConnectedNetwork; + tMobilityDomainInfo MDID; +} tRoamCandidateListParams, * tpRoamCandidateListParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRoamCandidateListParams RoamScanOffloadNetwListParams; +} tSetRoamScanOffloadReq, *tpRoamScanOffloadReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + + /* status of the request - just to indicate that PNO has acknowledged + * the request and will start scanning */ + tANI_U32 status; +} tSetRoamOffloadScanResp, *tpSetRoamOffloadScanResp; +#endif + +/* + Preferred network list response +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + + /* status of the request - just to indicate that PNO has acknowledged + * the request and will start scanning*/ + tANI_U32 status; +} tSetPrefNetwListResp, *tpSetPrefNetwListResp; + +/* + Preferred network indication parameters +*/ +typedef PACKED_PRE struct PACKED_POST { + + /*Network that was found with the highest RSSI*/ + tSirMacSSid ssId; + + /*Indicates the RSSI */ + tANI_U8 rssi; + + //The MPDU frame length of a beacon or probe rsp. data is the start of the frame + tANI_U16 frameLength; + +} tPrefNetwFoundParams, * tpPrefNetwFoundParams; + +/* + Preferred network found indication +*/ +typedef PACKED_PRE struct PACKED_POST { + + tHalMsgHeader header; + tPrefNetwFoundParams prefNetwFoundParams; +} tPrefNetwFoundInd, *tpPrefNetwFoundInd; + + +typedef PACKED_PRE struct PACKED_POST { + + /*RSSI Threshold*/ + tANI_U8 ucRssiThreshold; + +} tRssiFilterParams, * tpRssiFilterParams; + +/* + RSSI Filter request +*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tRssiFilterParams prefRSSIFilterParams; +} tSetRssiFilterReq, *tpSetRssiFilterReq; + +/* + Set RSSI filter resp +*/ +typedef PACKED_PRE struct PACKED_POST{ + tHalMsgHeader header; + /*status of the request */ + tANI_U32 status; +} tSetRssiFilterResp, *tpSetRssiFilterResp; +/* + Update scan params +*/ +typedef PACKED_PRE struct PACKED_POST +{ + + /*Host setting for 11d*/ + tANI_U8 b11dEnabled; + + /*Lets PNO know that host has determined the regulatory domain*/ + tANI_U8 b11dResolved; + + /*Channels on which PNO is allowed to scan*/ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS]; + + /*Minimum channel time*/ + tANI_U16 usActiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usActiveMaxChTime; + + /*Minimum channel time*/ + tANI_U16 usPassiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usPassiveMaxChTime; + + /*Cb State*/ + ePhyChanBondState cbState; + +} tUpdateScanParams, * tpUpdateScanParams; + +/* + Update scan params +*/ +typedef PACKED_PRE struct PACKED_POST +{ + + /*Host setting for 11d*/ + tANI_U8 b11dEnabled; + + /*Lets PNO know that host has determined the regulatory domain*/ + tANI_U8 b11dResolved; + + /*Channels on which PNO is allowed to scan*/ + tANI_U8 ucChannelCount; + tANI_U8 aChannels[WLAN_HAL_PNO_MAX_NETW_CHANNELS_EX]; + + /*Minimum channel time*/ + tANI_U16 usActiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usActiveMaxChTime; + + /*Minimum channel time*/ + tANI_U16 usPassiveMinChTime; + + /*Maximum channel time*/ + tANI_U16 usPassiveMaxChTime; + + /*Cb State*/ + ePhyChanBondState cbState; + +} tUpdateScanParamsEx, * tpUpdateScanParamsEx; + +/* + Update scan params - sent from host to PNO + to be used during PNO scanning +*/ +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + tUpdateScanParams scanParams; +} tUpdateScanParamsReq, *tpUpdateScanParamsReq; + +/* + Update scan params - sent from host to PNO + to be used during PNO scanning +*/ +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + tUpdateScanParamsEx scanParams; +} tUpdateScanParamsReqEx, *tpUpdateScanParamsReqEx; + +/* + Update scan params - sent from host to PNO + to be used during PNO scanning +*/ +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + + /*status of the request */ + tANI_U32 status; + +} tUpdateScanParamsResp, *tpUpdateScanParamsResp; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_TX_PER_TRACKING_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 ucTxPerTrackingEnable; /* 0: disable, 1:enable */ + tANI_U8 ucTxPerTrackingPeriod; /* Check period, unit is sec. */ + tANI_U8 ucTxPerTrackingRatio; /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. */ + tANI_U32 uTxPerTrackingWatermark; /* A watermark of check number, once the tx packet exceed this number, we do the check, default is 5 */ +} tHalTxPerTrackingReqParam, *tpHalTxPerTrackingReqParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalTxPerTrackingReqParam txPerTrackingParams; +} tHalSetTxPerTrackingReqMsg, *tpHalSetTxPerTrackingReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_TX_PER_TRACKING_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; +} tHalTxPerTrackingRspParams, *tpHalTxPerTrackingRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalTxPerTrackingRspParams txPerTrackingRspParams; +} tHalSetTxPerTrackingRspMsg, *tpHalSetTxPerTrackingRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_TX_PER_HIT_IND + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; +}tTxPerHitIndMsg, *tpTxPerHitIndMsg; + +/*--------------------------------------------------------------------------- + *******************Packet Filtering Definitions Begin******************* + *--------------------------------------------------------------------------*/ +#define HAL_PROTOCOL_DATA_LEN 8 +#define HAL_MAX_NUM_MULTICAST_ADDRESS 240 +#define HAL_MAX_NUM_FILTERS 20 +#define HAL_MAX_CMP_PER_FILTER 10 + +typedef enum +{ + HAL_RCV_FILTER_TYPE_INVALID, + HAL_RCV_FILTER_TYPE_FILTER_PKT, + HAL_RCV_FILTER_TYPE_BUFFER_PKT, + HAL_RCV_FILTER_TYPE_MAX_ENUM_SIZE +}tHalReceivePacketFilterType; + +typedef enum +{ + HAL_FILTER_PROTO_TYPE_INVALID, + HAL_FILTER_PROTO_TYPE_MAC, + HAL_FILTER_PROTO_TYPE_ARP, + HAL_FILTER_PROTO_TYPE_IPV4, + HAL_FILTER_PROTO_TYPE_IPV6, + HAL_FILTER_PROTO_TYPE_UDP, + HAL_FILTER_PROTO_TYPE_MAX +}tHalRcvPktFltProtocolType; + +typedef enum +{ + HAL_FILTER_CMP_TYPE_INVALID, + HAL_FILTER_CMP_TYPE_EQUAL, + HAL_FILTER_CMP_TYPE_MASK_EQUAL, + HAL_FILTER_CMP_TYPE_NOT_EQUAL, + HAL_FILTER_CMP_TYPE_MAX +}tHalRcvPktFltCmpFlagType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 protocolLayer; + tANI_U8 cmpFlag; + tANI_U16 dataLength; /* Length of the data to compare */ + tANI_U8 dataOffset; /* from start of the respective frame header */ + tANI_U8 reserved; /* Reserved field */ + tANI_U8 compareData[HAL_PROTOCOL_DATA_LEN]; /* Data to compare */ + tANI_U8 dataMask[HAL_PROTOCOL_DATA_LEN]; /* Mask to be applied on the received packet data before compare */ +}tHalRcvPktFilterParams, *tpHalRcvPktFilterParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 filterId; + tANI_U8 filterType; + tANI_U8 numParams; + tANI_U32 coalesceTime; + tHalRcvPktFilterParams paramsData[1]; +}tHalRcvPktFilterCfgType, *tpHalRcvPktFilterCfgType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 filterId; + tANI_U8 filterType; + tANI_U8 numParams; + tANI_U32 coleasceTime; + tANI_U8 bssIdx; + tHalRcvPktFilterParams paramsData[1]; +}tHalSessionizedRcvPktFilterCfgType, *tpHalSessionizedRcvPktFilterCfgType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvPktFilterCfgType pktFilterCfg; +} tHalSetRcvPktFilterReqMsg, *tpHalSetRcvPktFilterReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 dataOffset; /* from start of the respective frame header */ + tANI_U32 cMulticastAddr; + tSirMacAddr multicastAddr[HAL_MAX_NUM_MULTICAST_ADDRESS]; + tANI_U8 bssIdx; +} tHalRcvFltMcAddrListType, *tpHalRcvFltMcAddrListType; + +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + tANI_U8 bssIdx; +} tHalSetPktFilterRspParams, *tpHalSetPktFilterRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSetPktFilterRspParams pktFilterRspParams; +} tHalSetPktFilterRspMsg, *tpHalSetPktFilterRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; +} tHalRcvFltPktMatchCntReqParams, *tpHalRcvFltPktMatchCntReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktMatchCntReqParams pktMatchCntReqParams; +} tHalRcvFltPktMatchCntReqMsg, *tpHalRcvFltPktMatchCntReqMsg; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 filterId; + tANI_U32 matchCnt; +} tHalRcvFltPktMatchCnt; +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; + tANI_U32 matchCnt; + tHalRcvFltPktMatchCnt filterMatchCnt[HAL_MAX_NUM_FILTERS]; + tANI_U8 bssIdx; +} tHalRcvFltPktMatchRspParams, *tptHalRcvFltPktMatchRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktMatchRspParams fltPktMatchRspParams; +} tHalRcvFltPktMatchCntRspMsg, *tpHalRcvFltPktMatchCntRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; /* only valid for response message */ + tANI_U8 filterId; + tANI_U8 bssIdx; +}tHalRcvFltPktClearParam, *tpHalRcvFltPktClearParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktClearParam filterClearParam; +} tHalRcvFltPktClearReqMsg, *tpHalRcvFltPktClearReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktClearParam filterClearParam; +} tHalRcvFltPktClearRspMsg, *tpHalRcvFltPktClearRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U8 bssIdx; +}tHalRcvFltPktSetMcListRspType, *tpHalRcvFltPktSetMcListRspType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltMcAddrListType mcAddrList; +} tHalRcvFltPktSetMcListReqMsg, *tpHalRcvFltPktSetMcListReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRcvFltPktSetMcListRspType rspParam; +} tHalRcvFltPktSetMcListRspMsg, *tpHalRcvFltPktSetMcListRspMsg; + + +/*--------------------------------------------------------------------------- + *******************Packet Filtering Definitions End******************* + *--------------------------------------------------------------------------*/ + +/* + * There are two versions of this message + * Version 1 : Base version + * Current version : Base version + Max LI modulated DTIM + */ +typedef PACKED_PRE struct PACKED_POST +{ + /* Ignore DTIM */ + tANI_U32 uIgnoreDTIM; + + /*DTIM Period*/ + tANI_U32 uDTIMPeriod; + + /* Listen Interval */ + tANI_U32 uListenInterval; + + /* Broadcast Multicast Filter */ + tANI_U32 uBcastMcastFilter; + + /* Beacon Early Termination */ + tANI_U32 uEnableBET; + + /* Beacon Early Termination Interval */ + tANI_U32 uBETInterval; +}tSetPowerParamsVer1Type, *tpSetPowerParamsVer1Type; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetPowerParamsVer1Type powerParams; +} tSetPowerParamsVer1ReqMsg, *tpSetPowerParamsVer1ReqMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Ignore DTIM */ + tANI_U32 uIgnoreDTIM; + + /*DTIM Period*/ + tANI_U32 uDTIMPeriod; + + /* Listen Interval */ + tANI_U32 uListenInterval; + + /* Broadcast Multicast Filter */ + tANI_U32 uBcastMcastFilter; + + /* Beacon Early Termination */ + tANI_U32 uEnableBET; + + /* Beacon Early Termination Interval */ + tANI_U32 uBETInterval; + + /* MAX LI for modulated DTIM */ + tANI_U32 uMaxLIModulatedDTIM; +}tSetPowerParamsType, *tpSetPowerParamsType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetPowerParamsType powerParams; +} tSetPowerParamsReqMsg, *tpSetPowerParamsReqMsg; + +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + + /*status of the request */ + tANI_U32 status; + +} tSetPowerParamsResp, *tpSetPowerParamsResp; + +/*--------------------------------------------------------------------------- + ****************Capability bitmap exchange definitions and macros starts************* + *--------------------------------------------------------------------------*/ + +typedef enum { + MCC = 0, + P2P = 1, + DOT11AC = 2, + SLM_SESSIONIZATION = 3, + DOT11AC_OPMODE = 4, + SAP32STA = 5, + TDLS = 6, + P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7, + WLANACTIVE_OFFLOAD = 8, + BEACON_OFFLOAD = 9, + SCAN_OFFLOAD = 10, + ROAM_OFFLOAD = 11, + BCN_MISS_OFFLOAD = 12, + STA_POWERSAVE = 13, + STA_ADVANCED_PWRSAVE = 14, + AP_UAPSD = 15, + AP_DFS = 16, + BLOCKACK = 17, + PHY_ERR = 18, + BCN_FILTER = 19, + RTT = 20, + RATECTRL = 21, + WOW = 22, + WLAN_ROAM_SCAN_OFFLOAD = 23, + SPECULATIVE_PS_POLL = 24, + SCAN_SCH = 25, + IBSS_HEARTBEAT_OFFLOAD = 26, + WLAN_SCAN_OFFLOAD = 27, + WLAN_PERIODIC_TX_PTRN = 28, + ADVANCE_TDLS = 29, + BATCH_SCAN = 30, + FW_IN_TX_PATH = 31, + EXTENDED_NSOFFLOAD_SLOT = 32, + CH_SWITCH_V1 = 33, + HT40_OBSS_SCAN = 34, + UPDATE_CHANNEL_LIST = 35, + WLAN_MCADDR_FLT = 36, + WLAN_CH144 = 37, + NAN = 38, + TDLS_SCAN_COEXISTENCE = 39, + LINK_LAYER_STATS_MEAS = 40, + MU_MIMO = 41, + EXTENDED_SCAN = 42, + DYNAMIC_WMM_PS = 43, + MAC_SPOOFED_SCAN = 44, + BMU_ERROR_GENERIC_RECOVERY = 45, + DISA = 46, + FW_STATS = 47, + WPS_PRBRSP_TMPL = 48, + BCN_IE_FLT_DELTA = 49, + TDLS_OFF_CHANNEL = 51, + RTT3 = 52, + MGMT_FRAME_LOGGING = 53, + ENHANCED_TXBD_COMPLETION = 54, + LOGGING_ENHANCEMENT = 55, + EXT_SCAN_ENHANCED = 56, + MEMORY_DUMP_SUPPORTED = 57, + PER_PKT_STATS_SUPPORTED = 58, + EXT_LL_STAT = 60, + WIFI_CONFIG = 61, + ANTENNA_DIVERSITY_SELECTION = 62, + PER_BASED_ROAMING = 63, + SAP_MODE_WOW = 64, + SAP_OFFLOADS = 65, + SAP_BUFF_ALLOC = 66, + MAKE_BEFORE_BREAK = 67, + NUD_DEBUG = 68, + /* 69 reserved for FATAL_EVENT_LOGGING */ + /* 70 reserved for WIFI_DUAL_BAND_ENABLE */ + PROBE_RSP_TEMPLATE_VER1 = 71, + MAX_FEATURE_SUPPORTED = 128, +} placeHolderInCapBitmap; + +typedef PACKED_PRE struct PACKED_POST{ + + tANI_U32 featCaps[4]; +} tWlanFeatCaps, *tpWlanFeatCaps; + +typedef PACKED_PRE struct PACKED_POST{ + + tHalMsgHeader header; + tWlanFeatCaps wlanFeatCaps; + +} tWlanFeatCapsMsg, *tpWlanFeatCapsMsg; + +#define IS_MCC_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(MCC))) +#define IS_SLM_SESSIONIZATION_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(SLM_SESSIONIZATION))) +#define IS_FEATURE_SUPPORTED_BY_HOST(featEnumValue) (!!halMsg_GetHostWlanFeatCaps(featEnumValue)) +#define IS_WLANACTIVE_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(WLANACTIVE_OFFLOAD))) +#define IS_WLAN_ROAM_SCAN_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(WLAN_ROAM_SCAN_OFFLOAD))) +#define IS_IBSS_HEARTBEAT_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(IBSS_HEARTBEAT_OFFLOAD))) +#define IS_SCAN_OFFLOAD_SUPPORTED_BY_HOST (!!(halMsg_GetHostWlanFeatCaps(WLAN_SCAN_OFFLOAD))) +#define IS_CH_SWITCH_V1_SUPPORTED_BY_HOST ((!!(halMsg_GetHostWlanFeatCaps(CH_SWITCH_V1)))) +#define IS_TDLS_SCAN_COEXISTENCE_SUPPORTED_BY_HOST ((!!(halMsg_GetHostWlanFeatCaps(TDLS_SCAN_COEXISTENCE)))) +#define IS_DYNAMIC_WMM_PS_SUPPORTED_BY_HOST ((!!(halMsg_GetHostWlanFeatCaps(DYNAMIC_WMM_PS)))) +#define IS_MAC_SPOOF_SCAN_SUPPORTED_BY_HOST ((!!(halMsg_GetHostWlanFeatCaps(MAC_SPOOFED_SCAN)))) +#define IS_NEW_BMU_ERROR_RECOVERY_SUPPORTED_BY_HOST ((!!(halMsg_GetHostWlanFeatCaps(BMU_ERROR_GENERIC_RECOVERY)))) +#define IS_ENHANCED_TXBD_COMPLETION_SUPPORTED_BY_HOST ((!!(halMsg_GetHostWlanFeatCaps(ENHANCED_TXBD_COMPLETION)))) + +tANI_U8 halMsg_GetHostWlanFeatCaps(tANI_U8 feat_enum_value); + +#define setFeatCaps(a,b) { tANI_U32 arr_index, bit_index; \ + if ((b)<=127) { \ + arr_index = (b)/32; \ + bit_index = (b)%32; \ + if(arr_index < 4) \ + (a)->featCaps[arr_index] |= (1<featCaps[arr_index] & (1<featCaps[arr_index] &= ~(1<info |= (1 << flag); \ + } while(0) + +#define WLAN_HAL_GET_CHANNEL_FLAG(pwlan_hal_update_channel,flag) \ + (((pwlan_hal_update_channel)->info & (1 << flag)) >> flag) + +#define WLAN_HAL_SET_CHANNEL_MIN_POWER(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_1 &= 0xffffff00; \ + (pwlan_hal_update_channel)->reg_info_1 |= (val&0xff); \ + } while(0) +#define WLAN_HAL_GET_CHANNEL_MIN_POWER(pwlan_hal_update_channel) ((pwlan_hal_update_channel)->reg_info_1 & 0xff ) + +#define WLAN_HAL_SET_CHANNEL_MAX_POWER(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_1 &= 0xffff00ff; \ + (pwlan_hal_update_channel)->reg_info_1 |= ((val&0xff) << 8); \ + } while(0) +#define WLAN_HAL_GET_CHANNEL_MAX_POWER(pwlan_hal_update_channel) ( (((pwlan_hal_update_channel)->reg_info_1) >> 8) & 0xff ) + +#define WLAN_HAL_SET_CHANNEL_REG_POWER(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_1 &= 0xff00ffff; \ + (pwlan_hal_update_channel)->reg_info_1 |= ((val&0xff) << 16); \ + } while(0) +#define WLAN_HAL_GET_CHANNEL_REG_POWER(pwlan_hal_update_channel) ( (((pwlan_hal_update_channel)->reg_info_1) >> 16) & 0xff ) +#define WLAN_HAL_SET_CHANNEL_REG_CLASSID(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_1 &= 0x00ffffff; \ + (pwlan_hal_update_channel)->reg_info_1 |= ((val&0xff) << 24); \ + } while(0) +#define WLAN_HAL_GET_CHANNEL_REG_CLASSID(pwlan_hal_update_channel) ( (((pwlan_hal_update_channel)->reg_info_1) >> 24) & 0xff ) + +#define WLAN_HAL_SET_CHANNEL_ANTENNA_MAX(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_2 &= 0xffffff00; \ + (pwlan_hal_update_channel)->reg_info_2 |= (val&0xff); \ + } while(0) +#define WLAN_HAL_GET_CHANNEL_ANTENNA_MAX(pwlan_hal_update_channel) ((pwlan_hal_update_channel)->reg_info_2 & 0xff ) + +#define WLAN_HAL_SET_CHANNEL_MAX_TX_POWER(pwlan_hal_update_channel,val) do { \ + (pwlan_hal_update_channel)->reg_info_2 &= 0xffff00ff; \ + (pwlan_hal_update_channel)->reg_info_2 |= ((val&0xff)<<8); \ + } while(0) +#define WLAN_HAL_GET_CHANNEL_MAX_TX_POWER(pwlan_hal_update_channel) ( (((pwlan_hal_update_channel)->reg_info_2)>>8) & 0xff ) + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 numChan; + tUpdateChannelParam chanParam[WLAN_HAL_ROAM_SCAN_MAX_CHANNELS]; +} tUpdateChannelReqType; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_UPDATE_CHANNEL_LIST_REQ + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tUpdateChannelReqType updateChannelParams; +} tHalUpdateChannelReqMsg, *tpHalUpdateChannelReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_UPDATE_CHANNEL_LIST_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + + /*status of the request - just to indicate SO has acknowledged + * * the request and will start scanning*/ + tANI_U32 status; +} tHalUpdateChannelRspMsg, *tpHalUpdateChannelRspMsg; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_RMC_RULER_REQ + *-------------------------------------------------------------------------*/ + +#define HAL_MAX_RMC_SESSIONS 2 + +#define HAL_NUM_MAX_RULERS 8 + +typedef enum +{ + WLAN_HAL_SUGGEST_RULER, + WLAN_HAL_BECOME_RULER, + WLAN_HAL_RULER_CMD_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tRulerReqCmdType, tRulerRspCmdType; + +typedef PACKED_PRE struct PACKED_POST +{ + tRulerReqCmdType cmd; + + /* MAC address of MCAST Transmitter (source) */ + tSirMacAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + tSirMacAddr mcastGroup; + + /* Optional black list for cmd = WLAN_HAL_SUGGEST_RULER */ + tSirMacAddr blacklist[HAL_NUM_MAX_RULERS]; +} tHalRmcRulerReqParams, *tpHalRmcRulerReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRmcRulerReqParams rulerReqParams; +} tHalRmcRulerReqMsg, *tpHalRmcRulerReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_RMC_RULER_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* success or failure */ + tANI_U32 status; + + /* Command Type */ + tRulerRspCmdType cmd; + + /* MAC address of MCAST Transmitter (source) */ + tSirMacAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + tSirMacAddr mcastGroup; + + /* List of candidates for cmd = WLAN_HAL_SUGGEST_RULER*/ + tSirMacAddr ruler[HAL_NUM_MAX_RULERS]; + +} tHalRmcRulerRspParams, *tpHalRmcRulerRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRmcRulerRspParams rulerRspParams; +} tHalRmcRulerRspMsg, *tpHalRmcRulerRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_RMC_UPDATE_IND + *-------------------------------------------------------------------------*/ +typedef enum +{ + WLAN_HAL_RULER_ACCEPTED, //Host-->FW + WLAN_HAL_RULER_CANCELED, //Host-->FW + WLAN_HAL_RULER_PICK_NEW, //FW-->Host + WLAN_HAL_RULER_IND_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tRmcUpdateIndType; + +typedef enum +{ + WLAN_HAL_RMC_RULER_ROLE, + WLAN_HAL_RMC_TRANSMITTER_ROLE, + WLAN_HAL_RMC_ROLE_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tRmcRoleType; + +typedef PACKED_PRE struct PACKED_POST +{ + tRmcUpdateIndType indication; + + /* Role of the entity generating this indication */ + tRmcRoleType role; + + /* MAC address of MCAST Transmitter (source) */ + tSirMacAddr mcastTransmitter; + + /* MAC Address of Multicast Group (01-00-5E-xx-xx-xx) */ + tSirMacAddr mcastGroup; + + tSirMacAddr mcastRuler; + + /* Candidate list for indication = WLAN_HAL_RULER_PICK_NEW */ + tSirMacAddr ruler[HAL_NUM_MAX_RULERS]; +} tHalRmcUpdateIndParams, *tpHalRmcUpdateIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRmcUpdateIndParams rulerIndParams; +} tHalRmcUpdateInd, *tpHalRmcUpdateInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 staIdx; // Station Idx; + tANI_U32 txRate; // Legacy transmit rate, in units of 500 kbit/sec, + // for the most recently transmitted frame + tANI_U32 mcsIndex; // mcs index for HT20 and HT40 rates + tANI_U32 txRateFlags; // to differentiate between HT20 and + // HT40 rates; short and long guard interval + tANI_S8 rssi; // RSSI of the last received beacon +}tHalIbssPeerParams, *tpHalIbssPeerParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; // success or failure + tANI_U8 numOfPeers; // Number of Peers for + // which stats are being reported + tHalIbssPeerParams ibssPeerParams[1]; // Stats of peer in IBSS +}tHalIbssPeerInfoRspParams, *tpHalIbssPeerInfoRspParams; + +// WLAN_HAL_GET_IBSS_PEER_INFO_RSP +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalIbssPeerInfoRspParams ibssPeerInfoRspParams; +}tHalIbssPeerInfoRsp, *tpHalIbssPeerInfoRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; // Bss Index + tANI_BOOLEAN allPeerInfoReqd; // If set, all IBSS peers stats are reported + tANI_U8 staIdx; // If allPeerInfoReqd is not set, + // only stats of peer with + // staIdx is reported +}tHalIbssPeerInfoReqParams, *tpHalIbssPeerInfoReqParams; + +// WLAN_HAL_GET_IBSS_PEER_INFO_REQ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalIbssPeerInfoReqParams ibssPeerInfoReqParams; +}tHalIbssPeerInfoReq, *tpHalIbssPeerInfoReq; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ROAM_OFFLOAD_SYNCH_IND + *-------------------------------------------------------------------------*/ +typedef enum +{ + /* reassociation is done, but couldn't finish security handshake */ + WLAN_HAL_ROAM_AUTH_STATUS_CONNECTED = 1, + + /* roam has successfully completed by firmware */ + WLAN_HAL_ROAM_AUTH_STATUS_AUTHENTICATED = 2, + + /* UNKONW error */ + WLAN_HAL_ROAM_AUTH_STATUS_UNKONWN = WLAN_HAL_MAX_ENUM_SIZE +}tHalRoamOffloadRoamAuthStatus; + +typedef enum +{ + WLAN_HAL_ROAM_TYPE_WPA_PSK, + WLAN_HAL_ROAM_TYPE_WPA2_PSK, + WLAN_HAL_ROAM_TYPE_OKC, + WLAN_HAL_ROAM_TYPE_CCKM, + WLAN_HAL_ROAM_TYPE_FT, + WLAN_HAL_ROAM_TYPE_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tHalRoamOffloadType; + +typedef PACKED_PRE struct PACKED_POST +{ + /* Offset of beacon / probe resp in this structure. Offset from the starting of the message */ + tANI_U16 beaconProbeRespOffset; + + /* Length of beaon / probe resp. */ + tANI_U16 beaconProbeRespLength; + + /* Offset of reassoc resp in this structure. Offset from the starting of the message */ + tANI_U16 reassocRespOffset; + + /* Length of reassoc resp. */ + tANI_U16 reassocRespLength; + + /* 0 for probe response frame, 1 for beacon frame, */ + tANI_U8 isBeacon; + + /* staIdx of old AP */ + tANI_U8 oldStaIdx; + + /* note : from bssIdx field to txMgmtPower are exactly mapped to + tConfigBssRspParams */ + /* bssIdx of new roamed AP */ + tANI_U8 bssIdx; + + /* DPU descriptor index for PTK */ + tANI_U8 dpuDescIndx; + + /* PTK DPU signature */ + tANI_U8 ucastDpuSignature; + + /* DPU descriptor index for GTK*/ + tANI_U8 bcastDpuDescIndx; + + /* GTK DPU signature */ + tANI_U8 bcastDpuSignature; + + /*DPU descriptor for IGTK*/ + tANI_U8 mgmtDpuDescIndx; + + /* IGTK DPU signature */ + tANI_U8 mgmtDpuSignature; + + /* Station Index for BSS entry*/ + tANI_U8 staIdx; + + /* Self station index for this BSS */ + tANI_U8 selfStaIdx; + + /* Bcast station for buffering bcast frames in AP role */ + tANI_U8 bcastStaIdx; + + /* MAC address of roamed AP */ + tSirMacAddr bssid; + + /*HAL fills in the tx power used for mgmt frames in this field. */ + tANI_S8 txMgmtPower; + + /* success or failure */ + tHalRoamOffloadRoamAuthStatus authStatus; + + /* TODO : add more info as needed */ + + /* beaconProbeRespOffset points to starting of beacon/probe resp frame */ + /* Beacon or probe resp from new AP. This is in 802.11 + frame format starting with MAC header. */ + /* Up to beaconProbeRespLength */ + + /* reassocRespOffset points to starting of reassoc resp frame */ + /* Reassoc resp from new AP. This is in 802.11 + frame format starting with MAC header. */ + /* Up to reassocRespLength */ + +} tHalRoamOffloadSynchIndParams, *tpHalRoamOffloadSynchIndParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRoamOffloadSynchIndParams params; +} tHalRoamOffloadSynchInd, *tpHalRoamOffloadSynchInd; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_ROAM_OFFLOAD_SYNCH_CNF + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* MAC address of new AP indicated by FW in RoamOffloadSynchInd */ + tSirMacAddr bssid; +} tHalRoamOffloadSynchCnfParams, *tpHalRoamOffloadSynchCnfParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRoamOffloadSynchCnfParams params; +} tHalRoamOffloadSynchCnfMsg, *tpHalRoamOffloadSynchCnfMsg; + + +/*--------------------------------------------------------------------------- + WLAN_HAL_RATE_UPDATE_IND + *-------------------------------------------------------------------------*/ + typedef PACKED_PRE struct PACKED_POST +{ + /* 0 implies UCAST RA, positive value implies fixed rate, -1 implies ignore this param */ + tANI_S32 ucastDataRate; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags ucastDataRateTxFlag; + + /* BSSID - Optional. 00-00-00-00-00-00 implies apply to all BCAST STAs */ + tSirMacAddr bssid; + + /* 0 implies MCAST RA, positive value implies fixed rate, -1 implies ignore */ + tANI_S32 rmcDataRate; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags rmcDataRateTxFlag; + + /* Default (non-RMC) MCAST(or BCAST) fixed rate in 2.4 GHz, 0 implies ignore */ + tANI_U32 mcastDataRate24GHz; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags mcastDataRate24GHzTxFlag; + + /* Default (non-RMC) MCAST(or BCAST) fixed rate in 5 GHz, 0 implies ignore */ + tANI_U32 mcastDataRate5GHz; //unit Mbpsx10 + + /* TX flag to differentiate between HT20, HT40 etc */ + tTxRateInfoFlags mcastDataRate5GHzTxFlag; + +} tHalRateUpdateParams, *tpHalRateUpdateParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRateUpdateParams halRateUpdateParams; +} tHalRateUpdateInd, * tpHalRateUpdateInd; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_TX_FAIL_IND +*--------------------------------------------------------------------------*/ +// Northbound indication from FW to host on weak link detection +typedef PACKED_PRE struct PACKED_POST +{ + // Sequence number increases by 1 whenever the device driver + // sends a notification event. This is cleared as 0 when the + // JOIN IBSS commamd is issued + tANI_U16 seqNo; + tANI_U16 staId; + tANI_U8 macAddr[HAL_MAC_ADDR_LEN]; +} tHalTXFailIndParams, *tpHalTXFailIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalTXFailIndParams txFailIndParams; +} tHalTXFailIndMsg, *tpHalTXFailIndMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_TX_FAIL_MONITOR_IND +*--------------------------------------------------------------------------*/ +// Southbound message from Host to monitor the Tx failures +typedef PACKED_PRE struct PACKED_POST +{ + // tx_fail_count = 0 should disable the TX Fail monitor, non-zero value should enable it. + tANI_U8 tx_fail_count; +} tTXFailMonitorInfo, *tpTXFailMonitorInfo; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tTXFailMonitorInfo txFailMonitor; +} tTXFailMonitorInd, *tpTXFailMonitorInd; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_AVOID_FREQ_RANGE_IND + *-------------------------------------------------------------------------*/ + +#define WLAN_HAL_MAX_AVOID_FREQ_RANGE 15 + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 startFreq; + tANI_U32 endFreq; +} tHalFreqRange, *tpHalFreqRange; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 avoidCnt; + tHalFreqRange avoidRange[WLAN_HAL_MAX_AVOID_FREQ_RANGE]; +} tHalAvoidFreqRangeIndParams, *tpHalAvoidFreqRangeIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAvoidFreqRangeIndParams freqRangeIndParams; +} tHalAvoidFreqRangeInd, *tpHalAvoidFreqRangeInd; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_START_HT40_OBSS_SCAN_IND + *-------------------------------------------------------------------------*/ + +typedef enum +{ + WLAN_HAL_HT40_OBSS_SCAN_PARAM_START, + WLAN_HAL_HT40_OBSS_SCAN_PARAM_UPDATE, + WLAN_HAL_HT40_OBSS_SCAN_CMD_MAX = WLAN_HAL_MAX_ENUM_SIZE +}tHT40OBssScanCmdType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHT40OBssScanCmdType cmdType; + + tSirScanType scanType; + tANI_U16 OBSSScanPassiveDwellTime; // In TUs + tANI_U16 OBSSScanActiveDwellTime; // In TUs + tANI_U16 BSSChannelWidthTriggerScanInterval; // In seconds + tANI_U16 OBSSScanPassiveTotalPerChannel; // In TUs + tANI_U16 OBSSScanActiveTotalPerChannel; // In TUs + tANI_U16 BSSWidthChannelTransitionDelayFactor; + tANI_U16 OBSSScanActivityThreshold; + + tANI_U8 selfStaIdx; + tANI_U8 bssIdx; + tANI_U8 fortyMHZIntolerent; + tANI_U8 channelCount; + tANI_U8 channels[WLAN_HAL_ROAM_SCAN_MAX_CHANNELS]; + tANI_U8 currentOperatingClass; + + tANI_U16 ieFieldLen; + tANI_U8 ieField[WLAN_HAL_PNO_MAX_PROBE_SIZE]; +}tHT40ObssScanIndType, *tpHT40ObssScanIndType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHT40ObssScanIndType scanHT40ObssScanParams; +} tHalStartHT40ObssScanIndMsg, *tpHalStartHT40ObssScanIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_STOP_HT40_OBSS_SCAN_IND + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U8 bssIdx; +} tHalStopHT40OBSSScanIndMsg, *tpHalStopHT40OBSSScanIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_BCN_MISS_RATE_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Valid BSS Idx for beacon miss rate */ + tANI_U8 bssIdx; + +}tHalBcnMissRateReqParams, *tpHalBcnMissRateReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBcnMissRateReqParams bcnMissRateReqParams; +} tHalBcnMissRateReqMsg, *tpHalBcnMissRateReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_BCN_MISS_RATE_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U32 bcnMissCnt; +}tHalBcnMissRateRspParams, *tpHalBcnMissRateRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBcnMissRateRspParams bcnMissRateRspParams; +}tHalBcnMissRateRspMsg, *tpHalBcnMissRateRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_ALLOWED_ACTION_FRAMES_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 actionFramesBitMask; + tANI_U32 reserved; +}tHalAllowedActionFrames, *tpHalAllowedActionFrames; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAllowedActionFrames allowedActionFrames; +}tHalAllowedActionFramesReqInd, *tpHalAllowedActionFramesReqInd; + +/*-------------------------------------------------------------------------- +* WLAN_HAL_LL_SET_STATS_REQ +*---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 req_id; + tANI_U8 sta_id; + tANI_U32 mpdu_size_threshold; // threshold to classify the pkts as short or long + tANI_U32 aggressive_statistics_gathering; // set for field debug mode. Driver should collect all statistics regardless of performance impact. +} tHalMacLlSetStatsReqParams, *tpHalMacLlSetStatsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacLlSetStatsReqParams LlSetStatsReqParams; +} tHalMacLlSetStatsReq, *tpHalMacLlSetStatsReq; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_SET_STATS_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U32 resp_id; + tANI_U8 iface_id; +} tHalMacLlSetStatsRspParams, *tpHalMacLlSetStatsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacLlSetStatsRspParams LlSetStatsRspParams; +} tHalMacLlSetStatsRsp, *tpHalMacLlSetStatsRsp; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_GET_STATS_REQ +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 req_id; + tANI_U8 sta_id; + tANI_U32 param_id_mask; +} tHalMacLlGetStatsReqParams, *tpHalMacLlGetStatsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacLlGetStatsReqParams LlGetStatsReqParams; +} tHalMacLlGetStatsReq, *tpHalMacLlGetStatsReq; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_GET_STATS_RSP +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U32 resp_id; + tANI_U8 iface_id; +} tHalMacLlGetStatsRspParams, *tpHalMacLlGetStatsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacLlGetStatsRspParams LlGetStatsRspParams; +} tHalMacLlGetStatsRsp, *tpHalMacLlGetStatsRsp; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_CLEAR_STATS_REQ +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 req_id; + tANI_U8 sta_id; + tANI_U32 stats_clear_req_mask; + tANI_U8 stop_req; +} tHalMacLlClearStatsReqParams, *tpHalMacLlClearStatsReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacLlClearStatsReqParams LlClearStatsReqParams; +} tHalMacLlClearStatsReq, *tpHalMacLlClearStatsReq; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_CLEAR_STATS_RSP +---------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U8 sta_id; + tANI_U32 resp_id; + tANI_U32 stats_clear_rsp_mask; + tANI_U8 stop_req_status; +} tHalMacLlClearStatsRspParams, *tpHalMacLlClearStatsRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalMacLlClearStatsRspParams LlClearStatsRspParams; +} tHalMacLlClearStatsRsp, *tpHalMacLlClearStatsRsp; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_NOTIFY_STATS +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U32 param_id; + tANI_U8 iface_id; + tANI_U32 resp_id; + tANI_U32 more_result_to_follow; + tANI_U8 result[1]; +} tHalMacLlNotifyStats, *tpHalMacLlNotifyStats; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_START_REQ + *-------------------------------------------------------------------------*/ + +typedef enum +{ + EXT_SCAN_CHANNEL_BAND_UNSPECIFIED = 0x0000, + EXT_SCAN_CHANNEL_BAND_BG = 0x0001, // 2.4 GHz + EXT_SCAN_CHANNEL_BAND_A = 0x0002, // 5 GHz without DFS + EXT_SCAN_CHANNEL_BAND_A_DFS = 0x0004, // 5 GHz DFS only + EXT_SCAN_CHANNEL_BAND_A_WITH_DFS = 0x0006, // 5 GHz with DFS + EXT_SCAN_CHANNEL_BAND_ABG = 0x0003, // 2.4 GHz + 5 GHz; no DFS + EXT_SCAN_CHANNEL_BAND_ABG_WITH_DFS = 0x0007, // 2.4 GHz + 5 GHz with DFS + EXT_SCAN_CHANNEL_BAND_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tExtScanChannelBandMask; + +#define WLAN_HAL_EXT_SCAN_MAX_HOTLIST_SSIDS 8 +#define WLAN_HAL_EXT_SCAN_MAX_AP_CACHE_PER_SCAN 32 + +#define WLAN_HAL_EXT_SCAN_FLAG_INTERRUPTED 1 + +#define WLAN_HAL_EXT_SCAN_REPORT_EVENTS_BUFFER_FULL 0 +#define WLAN_HAL_EXT_SCAN_REPORT_EVENTS_EACH_SCAN 1 +#define WLAN_HAL_EXT_SCAN_REPORT_EVENTS_FULL_RESULTS 2 +#define WLAN_HAL_EXT_SCAN_REPORT_EVENTS_NO_BATCH 4 + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 channel; // frequency + tANI_U32 dwellTimeMs; // dwell time hint + tANI_U8 passive; // 0 => active, + // 1 => passive scan; ignored for DFS +}tExtScanChannelSpec, *tpExtScanChannelSpec; + +typedef PACKED_PRE struct PACKED_POST + { + /* bucket index, 0 based */ + tANI_U8 bucketId; + /* when equal to EXT_SCAN_CHANNEL_BAND_UNSPECIFIED, use channel list */ + tExtScanChannelBandMask channelBand; + /* period (milliseconds) for each bucket defines the periodicity of bucket */ + tANI_U32 period; + /* This is a bit field; which defines following bits - + * REPORT_EVENTS_BUFFER_FULL => report only when scan history + is % full + * REPORT_EVENTS_EACH_SCAN => report a scan completion event + after scan + * REPORT_EVENTS_FULL_RESULTS => forward scan results + (beacons/probe responses + IEs) in real time to HAL, in addition + to completion events + Note: To keep backward compatibility, fire completion events + regardless of REPORT_EVENTS_EACH_SCAN. + * REPORT_EVENTS_NO_BATCH => controls batching, + 0 => batching, 1 => no batching + */ + tANI_U8 reportEvents; + /* number of channels */ + tANI_U8 numChannels; + // new Exponential Scan params + tANI_U32 max_period; + tANI_U32 exponent; + tANI_U32 step_count; + /* if channels to scan. In the TLV channelList[] */ + tExtScanChannelSpec channelList[WLAN_HAL_EXT_SCAN_MAX_CHANNELS]; +}tExtScanBucketData, *tpExtScanBucketData; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U8 sessionId; + /* Base period (milliseconds) used by scan buckets to define periodicity + of the scans */ + tANI_U32 basePeriod; + /* number of APs to store in each scan in the BSSID/RSSI history buffer + (keep the most significant, i.e. stronger RSSI) */ + tANI_U32 maxApPerScan; + /* in %, when buffer is this much full, wake up host */ + tANI_U32 reportThresholdPercent; + /* in number of scans, wake up AP after these many scans */ + tANI_U32 reportThresholdNumScans; + /* This will be off channel minimum time */ + tANI_U16 neighborScanChannelMinTime; + /* This will be out off channel max time */ + tANI_U16 neighborScanChannelMaxTime; + /* This will be the home (BSS) channel time */ + tANI_U16 homeAwayTime; + /* number of buckets (maximum 8) */ + tANI_U8 numBuckets; + /* Buckets data */ + tExtScanBucketData bucketData[WLAN_HAL_EXT_SCAN_MAX_BUCKETS]; +} tHalExtScanStartReq, *tpHalExtScanStartReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanStartReq extScanStartReq; +}tHalExtScanStartReqMsg, *tpHalExtScanStartReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_START_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalExtScanStartRsp, *tpHalExtScanStartRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanStartRsp extScanStartRsp; +}tHalExtScanStartRspMsg, *tpHalExtScanStartRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_GET_CAP_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U8 sessionId; +}tHalExtScanGetCapReq, *tpHalExtScanGetCapReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanGetCapReq extScanGetCapReq; +}tHalExtScanGetCapReqMsg, *tpHalExtScanGetCapReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_GET_CAP_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; + + tANI_U32 scanCacheSize; + tANI_U32 scanBuckets; + tANI_U32 maxApPerScan; + tANI_U32 maxRssiSampleSize; + tANI_U32 maxScanReportingThreshold; + + tANI_U32 maxHotlistAPs; + tANI_U32 maxHotlistSSIDs; + + tANI_U32 maxBssidHistoryEntries; +}tHalExtScanGetCapRsp, *tpHalExtScanGetCapRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanGetCapRsp extScanGetCapRsp; +}tHalExtScanGetCapRspMsg, *tpHalExtScanGetCapRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_GET_SCAN_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U8 sessionId; + /* + * 1 return cached results and flush it + * 0 return cached results and do not flush + */ + tANI_BOOLEAN flush; +}tHalExtScanGetScanReq, *tpHalExtScanGetScanReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanGetScanReq getScanReq; +}tHalExtScanGetScanReqMsg, *tpHalExtScanGetScanReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_GET_SCAN_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalExtScanGetScanRsp, *tpHalExtScanGetScanRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanGetScanRsp getScanRsp; +}tHalExtScanGetScanRspMsg, *tpHalExtScanGetScanRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_RESULT_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U64 ts; // time of discovery + tANI_U8 ssid[32+1]; // null terminated SSID + tSirMacAddr bssid; // BSSID + tANI_U32 channel; // channel frequency in MHz + tANI_S32 rssi; // RSSI in dBm + tANI_U32 rtt; // RTT in nanoseconds - not expected + tANI_U32 rttSd; // standard deviation in rtt - not expected + tANI_U16 beaconPeriod; // period advertised in the beacon + tANI_U16 capability; // capabilities advertised in the beacon + tANI_U16 ieLength; // size of the ie_data blob + tANI_U8 ieData[1]; // blob of all the information elements found in the beacon +} tHalExtScanResultParams, *tpHalExtScanResultParams; + +/* Get the GSCAN cached scan results */ +typedef struct { + tANI_U16 scan_id; // a unique identifier for the scan unit + tANI_U8 flags; // a bitmask with additional + // information about scan + tANI_U8 num_results; // number of bssids retrieved by the scan + tHalExtScanResultParams results[WLAN_HAL_EXT_SCAN_MAX_AP_CACHE_PER_SCAN]; + // scan results - one for each bssid +} tHalExtScanCachedResultParams, *tpHalExtScanCachedResultParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U32 requestId; + tANI_U32 scanResultSize; + tANI_BOOLEAN moreData; + tANI_U8 extScanResult[1]; +}tHalExtScanResultIndMsg, *tpHalExtScanResultIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_STOP_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U8 sessionId; +}tHalExtScanStopReq, *tpHalExtScanStopReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanStopReq extScanStopReq; +}tHalExtScanStopReqMsg, *tpHalExtScanStopReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_STOP_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalExtScanStopRsp, *tpHalExtScanStopRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanStopRsp extScanStopRsp; +}tHalExtScanStopRspMsg, *tpHalExtScanStopRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_PROGRESS_IND + *-------------------------------------------------------------------------*/ + +typedef enum +{ + WLAN_HAL_EXT_SCAN_BUFFER_FULL, + WLAN_HAL_EXT_SCAN_COMPLETE, + WLAN_HAL_EXT_SCAN_MAX = WLAN_HAL_MAX_ENUM_SIZE +} tHalExtScanProgressEventType; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; + tHalExtScanProgressEventType extScanEventType; +}tHalExtScanProgressInd, *tpHalExtScanProgressInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanProgressInd extScanProgressInd; +}tHalExtScanProgressIndMsg, *tpHalExtScanProgressIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_EXT_SCAN_RESULT_AVAILABLE_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 numOfScanResAvailable; +}tHalExtScanResAvailableInd, tpHalExtScanResAvailableInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalExtScanResAvailableInd extScanResAvailableInd; +}tHalExtScanResAvailableIndMsg, *tpHalExtScanResAvailableIndMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + /* AP BSSID */ + tSirMacAddr bssid; + /* low threshold - used in L for significant_change - not used in L for + hotlist*/ + tANI_S32 lowRssiThreshold; + /* high threshold - used in L for significant rssi - used in L for hotlist */ + tANI_S32 highRssiThreshold; +} tApThresholdParams, *tpApThresholdParams; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BSSID_HOTLIST_SET_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U8 sessionId; + tANI_U32 lostBssidSampleSize; + // number of hotlist APs + tANI_U32 numBssid; + // hotlist APs + tApThresholdParams ap[WLAN_HAL_EXT_SCAN_MAX_HOTLIST_APS]; +} tHalBssidHotlistSetReq, *tpHalBssidHotlistSetReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalBssidHotlistSetReq bssidHotlistSetReq; +}tHalHotlistSetReqMsg, *tpHalHotlistSetReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BSSID_HOTLIST_SET_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalHotlistSetRsp, *tpHalHotlistSetRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHotlistSetRsp hotlistSetRsp; +}tHalHotlistSetRspMsg, *tpHalHotlistSetRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BSSID_HOTLIST_RESET_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; +}tHalHotlistResetReq, *tpHalHotlistResetReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHotlistResetReq hotlistResetReq; +}tHalHotlistResetReqMsg, *tpHalHotlistResetReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BSSID_HOTLIST_RESET_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalHotlistResetRsp, *tpHalHotlistResetRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHotlistResetRsp hotlistResetRsp; +}tHalHotlistResetRspMsg, *tpHalHotlistResetRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_BSSID_HOTLIST_RESULT_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U32 requestId; + tANI_U32 numHotlistBss; + tANI_BOOLEAN moreData; + tANI_U8 bssHotlist[1]; +}tHalHotlistResultIndMsg, *tpHalHotlistResultIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SSID_HOTLIST_SET_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* SSID */ + char ssid [32+1]; + /* low threshold - used in L for significant_change - not used in L for + hotlist*/ + tANI_S32 lowRssiThreshold; + /* high threshold - used in L for significant rssi - used in L for hotlist */ + tANI_S32 highRssiThreshold; + /* band */ + tANI_U32 band; + } tSsidThresholdParams, *tpSsidThresholdParams; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U8 sessionId; + tANI_U32 lostSsidSampleSize; + // number of hotlist SSIDs + tANI_U32 numSsid; + // hotlist SSIDs + tSsidThresholdParams ssid[WLAN_HAL_EXT_SCAN_MAX_HOTLIST_SSIDS]; +} tHalSsidHotlistSetReq, *tpHalSsidHotlistSetReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSsidHotlistSetReq ssidHotlistSetReq; +}tHalSsidHotlistSetReqMsg, *tpHalSsidHotlistSetReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SSID_HOTLIST_SET_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalSsidHotlistSetRsp, *tpHalSsidHotlistSetRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSsidHotlistSetRsp hotlistSetRsp; +}tHalSsidHotlistSetRspMsg, *tpHalSsidHotlistSetRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SSID_HOTLIST_RESET_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; +}tHalSsidHotlistResetReq, *tpHalSsidHotlistResetReq; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSsidHotlistResetReq hotlistResetReq; +}tHalSsidHotlistResetReqMsg, *tpHalSsidHotlistResetReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SSID_HOTLIST_RESET_RSP + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 requestId; + tANI_U32 status; +}tHalSsidHotlistResetRsp, *tpHalSsidHotlistResetRsp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalSsidHotlistResetRsp hotlistResetRsp; +}tHalSsidHotlistResetRspMsg, *tpHalSsidHotlistResetRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SSID_HOTLIST_RESULT_IND + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U32 requestId; + tANI_BOOLEAN ssid_found; + tANI_U32 numHotlistSsid; + tANI_BOOLEAN moreData; + tANI_U8 ssidHotlist[1]; // pointer to list of type tHalExtScanResultParams +}tHalSsidHotlistResultIndMsg, *tpHalSsidHotlistResultIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_HIGH_PRIORITY_DATA_INFO_REQ + *-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_BOOLEAN pause; // 1 -> pause, 0 -> unpause + tANI_U32 reserved; //reserved for future use +}tHalHighPriorityDataInfoInd, *tpHalHighPriorityDataInfoInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalHighPriorityDataInfoInd highPriorityDataInfoInd; +}tHalHighPriorityDataInfoIndMsg, *tpHalHighPriorityDataInfoIndMsg; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_MAC_SPOOFED_SCAN_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 macAddr[6]; + tANI_U32 reserved1; + tANI_U32 reserved2; +}tMacSpoofedScanReqType, * tpMacSpoofedScanReqType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tMacSpoofedScanReqType tMacSpoofedScanReqParams; +} tMacSpoofedScanReqMsg, * tpMacSpoofedScanReqMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_MAC_SPOOFED_SCAN_RSP +*-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U32 reserved1; +} tMacSpoofedScanResp, * tpMacSpoofedScanResp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tMacSpoofedScanResp tMacSpoofedScanRespParams; +} tMacSpoofedScanRespMsg, * tpMacSpoofedScanRespMsg; +/*--------------------------------------------------------------------------- + *WLAN_HAL_GET_FRAME_LOG_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 flags; +}tGetFrameLogReqType, * tpGetFrameLogReqType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tGetFrameLogReqType tGetFrameLogReqParams; +} tGetFrameLogReqMsg, * tpGetFrameLogReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_GET_FRAME_LOG_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tGetFrameLogResp, * tpGetFrameLogResp; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tGetFrameLogResp tGetFrameLogRespParams; +} tGetFrameLogRespMsg, * tpGetFrameLogRespMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FATAL_EVENT_LOGGING_REQ + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 reasonCode; +}tHalFatalEventLoggingReqParams, *tpHalFatalEventLoggingReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalFatalEventLoggingReqParams tFatalEventLoggingReqParams; +}tHalFatalEventLoggingReqMsg, *tpHalFatalEventLoggingReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FATAL_EVENT_LOGGING_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ tANI_U32 status; +}tHalFatalEventLoggingRspParams, *tpHalFatalEventLoggingRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalFatalEventLoggingRspParams tFatalEventLoggingRspParams; +}tHalFatalEventLoggingRspMsg, *tpHalFatalEventLoggingRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_LOST_LINK_PARAMETERS_IND + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bssIdx; + tANI_U8 rssi; + tSirMacAddr selfMacAddr; + tANI_U32 linkFlCnt; + tANI_U32 linkFlTx; + tANI_U32 lastDataRate; + tANI_U32 rsvd1; + tANI_U32 rsvd2; +}tHalLostLinkParametersIndParams, *tpHalLostLinkParametersIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalLostLinkParametersIndParams lostLinkParameters; +}tHalLostLinkParametersIndMsg, *tpHalLostLinkParametersIndMsg; + + +/*--------------------------------------------------------------------------- + *WLAN_HAL_FW_LOGGING_INIT_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + /* BIT0 - enable frame logging + * BIT1 - enableBMUHWtracing + * BIT2 - enableQXDMlogging + * BIT3 - enableUElogDpuTxp + */ + tANI_U8 enableFlag; + tANI_U8 frameType; + tANI_U8 frameSize; + tANI_U8 bufferMode; + /* Host mem address to be used as logmailbox */ + tANI_U64 logMailBoxAddr; + /* firmware will wakeup the host to send logs always */ + tANI_U8 continuousFrameLogging; + /* Logging mail box version */ + tANI_U8 logMailBoxVer; + /* Max ring size in firmware to log msgs when host is suspended state */ + tANI_U8 maxLogBuffSize; + /* when firmware log reaches this threshold and + * if host is awake it will push the logs. + */ + tANI_U8 minLogBuffSize; + /* Reserved for future purpose */ + tANI_U32 reserved0; + tANI_U32 reserved1; + tANI_U32 reserved2; +}tFWLoggingInitReqType, * tpFWLoggingInitReqType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tFWLoggingInitReqType tFWLoggingInitReqParams; +} tHalFWLoggingInitReqMsg, * tpHalFWLoggingInitReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_LOGGING_INIT_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + /* FW mail box address */ + tANI_U64 logMailBoxAddr; + /* Logging mail box version */ + tANI_U8 logMailBoxVer; + /* Qshrink is enabled */ + tANI_BOOLEAN logCompressEnabled; + /* fw_dump_max_size is used to tell fwr mem dump size */ + tANI_U32 fw_dump_max_size; + /* Reserved for future purpose */ + tANI_U32 reserved1; + tANI_U32 reserved2; +} tFWLoggingInitResp, * tpFWLoggingInitResp; + + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 request_id; + tSirMacAddr bssId; + tANI_S8 min_rssi; + tANI_S8 max_rssi; +} tHalStartRssiMonitoringReqParams, * tpHalStartRssiMonitoringReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStartRssiMonitoringReqParams startRssiMonitoringReqParams; +}tHalStartRssimonitoringReq, * tpHalStartRssimonitoringReq; + +//Following structure will be used for WLAN_HAL_START_RSSI_MONITORING_RSP +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 request_id; + tANI_U32 status; +} tHalStartRssimonitoringRspParams, * tpHalStartRssimonitoringRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStartRssimonitoringRspParams startRssimonitoringRspParams; +}tHalStartRssimonitoringRsp, * tpHalStartRssimonitoringRsp; + +//Following structures will be used for WLAN_HAL_RSSI_MONITORING_IND +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 request_id; + tSirMacAddr bssId; + tANI_S8 rssi; +} tHalRssiMonitorIndParams, * tpHalRssiMonitorIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalRssiMonitorIndParams RssiMonitorIndParams; +}tHalRssiMonitorInd, * tpHalRssiMonitorInd; + + +//Following structures will be used for WLAN_HAL_STOP_RSSI_MONITORING_REQ +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 request_id; + tSirMacAddr bssId; +} tHalStopRssiMonitoringParams, * tpHalStopRssiMonitoringParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStopRssiMonitoringParams stopRssiMonitoringParams; +}tHalStopRssimonitoringReq, * tpHalStopRssimonitoringReq; + +//Following structures will be used for WLAN_HAL_STOP_RSSI_MONITORING_RSP +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 request_id; + tANI_U32 status; +} tHalStopRssimonitoringRspParams, * tpHalStopRssimonitoringRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStopRssimonitoringRspParams stopRssimonitoringRspParams; +}tHalStopRssimonitoringRsp, * tpHalStopRssimonitoringRsp; + + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tFWLoggingInitResp tFWLoggingInitRespParams; +} tFWLoggingInitRespMsg, * tpFWLoggingInitRespMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_PER_ROAM_CONFIG_REQ + *---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 request_id; + tANI_U32 isPERRoamCCAEnabled; + tANI_U32 rateUpThreshold; + tANI_U32 rateDownThreshold; + tANI_U32 waitPeriodForNextPERScan; + tANI_U32 PERtimerThreshold; + tANI_U32 PERroamTriggerPercent; + tANI_S16 PERRoamFullScanThreshold; + tANI_U16 reserved; +} tPerRoamConfigParams, * tpPerRoamConfigParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tPerRoamConfigParams perRoamConfigParams; +} tSetPerRoamConfigReq, * tpSetPerRoamConfigReq; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_SET_PER_ROAM_CONFIG_RSP + *---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success or Failure */ + tANI_U32 status; +} tConfigPerRoamRspParams, * tpConfigPerRoamRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigPerRoamRspParams configPerRoamRspParams; +} tSetPerRoamConfigRsp, * tpSetPerRoamConfigRsp; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_PER_ROAM_SCAN_TRIGGER_REQ + *---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST { + bool roamScanReq; +} tStartRoamScanTriggerParams, * tpStartRoamScanTriggerParams; + +typedef PACKED_PRE struct PACKED_POST { + + tHalMsgHeader header; + tStartRoamScanTriggerParams startRoamScanTriggerParams; +} tStartRoamScanReq, *tpStartRoamScanReq; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_PER_ROAM_SCAN_TRIGGER_RSP + *---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success /Failure / Nil result */ + tANI_U32 status; +} tConfigRoamScanRspParams, * tpConfigRoamScanRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigRoamScanRspParams configRoamScanRspParams; +} tSetRoamScanConfigRsp, * tpSetRoamScanConfigRsp; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_CAPTURE_GET_TSF_TSTAMP +*-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + uint8 uBssIdx; + boolean capTSFget; +}tHalCapTSFget, *tptHalCapTSFget; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalCapTSFget capTSFget; +}tHalCapTSFgetReqInd, *tpHalCapTSFgetReqInd; + +/*--------------------------------------------------------------------------- + WLAN_HAL_CAPTURE_GET_TSF_TSTAMP_RSP +---------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + /* Success /Failure / Nil result */ + tANI_U32 status; + tANI_U32 tsf_lo; + tANI_U32 tsf_hi; +} tConfigcapTSFgetRspParams, * tptConfigcapTSFgetRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tConfigcapTSFgetRspParams configcapTSFgetRspParams; +} tcapGetTSFConfigRsp, * tpcapGetTSFConfigRsp; + + +#define PER_ROAM_MAX_AP_CNT 30 +#define PER_ROAM_MAX_CANDIDATE_CNT 15 + +/* Candidate Information to be shared in the Candidate Indication, + * similar to what is sent in legacy roaming with following additional info + */ + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 channelNumber; + tANI_U8 channelCCA; + tANI_U8 otherApCount; + tANI_S8 otherApRssi[PER_ROAM_MAX_AP_CNT]; +} tCandidateChannelInfo, * tpCandidateChannelInfo; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 candidateCount; + tCandidateChannelInfo channelInfo[PER_ROAM_MAX_CANDIDATE_CNT]; +} tPerRoamScanResult, * tpPerRoamScanResult; + + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_LOGGING_DXE_DONE_IND + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 status; + tANI_U16 doneIndicationForSource; + tANI_U32 logBuffLength[MAX_NUM_OF_BUFFER]; + tANI_U64 logBuffAddress[MAX_NUM_OF_BUFFER]; +} tFWLoggingDxeDoneInd, * tpFWLoggingDxeDoneInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tFWLoggingDxeDoneInd tFWLoggingDxeDoneIndParams; +} tFWLoggingDxeDoneIndMsg, * tpFWLoggingDxeDoneIndMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_APFIND_CMDID + * ---------------------------------------------------------------------------*/ + +#define MAX_ARRAY_SIZE 1000 +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 msg_version:4; + tANI_U16 msg_id:12; + tANI_U16 msg_len:16; + tANI_U16 handle; + tANI_U16 transaction_id; +} tApfindMsgHeader, *tpApfindMsgHeader; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 type; + tANI_U16 length; + tANI_U8* value; +} tApfindTlv, *tpApfindTlv; + +typedef PACKED_PRE struct PACKED_POST +{ + tApfindMsgHeader apFindHeader; + tANI_U8 ptlv[MAX_ARRAY_SIZE]; +} tQRFPrefNetwListParams, *tpQRFPrefNetwListParams; + +typedef enum +{ + APFIND_MSG_ID_ERROR_RSP = 0, + APFIND_MSG_ID_ENABLE_REQ = 1, + APFIND_MSG_ID_SET_SSID = 2, + APFIND_MSG_ID_SET_MAC = 3, + APFIND_MSG_ID_SET_PARAMS = 4, +} tApfindMsgId; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tQRFPrefNetwListParams qRFprefNetwListParams; +} tQRFSetPrefNetwListReq, *tpQRFSetPrefNetwListReq; + +#define QRF_MAX_SUPPORTED_NETWORKS 10 + +typedef PACKED_PRE struct PACKED_POST { + /*Network that was found with the highest RSSI*/ + tSirMacSSid ssId; + /*Indicates the RSSI */ + tANI_U8 rssi; + /* The MPDU frame length of a beacon or probe rsp. + * data is the start of the frame + */ + tANI_U16 frameLength; +} tQrfNetwFoundParam, *tpQrfNetwFoundParam; + +typedef PACKED_PRE struct PACKED_POST { + uint8 netwCount; + tQrfNetwFoundParam qrfNetwParams[QRF_MAX_SUPPORTED_NETWORKS]; +} tQrfPrefNetwFoundParams, * tpQrfPrefNetwFoundParams; + +/* + * Preferred network found indication + */ +typedef PACKED_PRE struct PACKED_POST { + tHalMsgHeader header; + tQrfPrefNetwFoundParams qrfPrefNetwFoundParams; +} tQrfPrefNetwFoundInd, *tpQrfPrefNetwFoundInd; + + +/*--------------------------------------------------------------------------- + * Logging mail box structure + *-------------------------------------------------------------------------*/ + +#define MAILBOX_VERSION_V1 0x1 + +typedef PACKED_PRE struct PACKED_POST +{ + /* Logging mail box version */ + tANI_U8 logMbVersion; + /* Current logging buffer address */ + tANI_U64 logBuffAddress[MAX_NUM_OF_BUFFER]; + /* Current logging buffer length */ + tANI_U32 logBuffLength[MAX_NUM_OF_BUFFER]; + /* Flush reason code 0: Host requested Non zero FW FATAL event*/ + tANI_U16 reasonCode; + /* Log type i.e. Mgmt frame = 0, QXDM = 1, FW Mem dump = 2 */ + tANI_U8 logType; + /* Indicate if Last segment of log is received*/ + tANI_BOOLEAN done; +}tLoggingMailBox, *tpLoggingMailBox; + +/*--------------------------------------------------------------------------- + *WLAN_HAL_FW_MEMORY_DUMP_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 reserved; +}tHalFwMemoryDumpReqType, * tpHalFwMemoryDumpReqType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalFwMemoryDumpReqType tFwMemoryDumpReqParam; +} tHalFwMemoryDumpReqMsg, * tpHalFwMemoryDumpReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_MEMORY_DUMP_RSP + *-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} tHalFwMemoryDumpRespType, * tpHalFwMemoryDumpRespType; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalFwMemoryDumpRespType tFwMemoryDumpResp; +} tHalFwMemoryDumpRespMsg, * tpHalFwMemoryDumpRespMsg; + + +/*--------------------------------------------------------------------------- +* WLAN_HAL_ENABLE_MONITOR_MODE_REQ +*-------------------------------------------------------------------------*/ + +/* only 1 filter is supported as of now */ +#define NUM_FILTERS_SUPPORTED 1 + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr macAddr; + tANI_U8 isA1filteringNeeded; + tANI_U8 isA2filteringNeeded; + tANI_U8 isA3filteringNeeded; +}tHalMacFilter, *tpHalMacFilter; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 channelNumber; + ePhyChanBondState cbState; + + tANI_U32 maxAmpduLen; + tANI_U32 maxMpduInAmpduLen; + + tANI_U8 crcCheckEnabled; + + /* value is "1" for this FR. "0" means no filter, RECEIVE ALL PACKETS */ + tANI_U8 numMacFilters; + tHalMacFilter macFilters[NUM_FILTERS_SUPPORTED]; + + /* Each bit position maps to IEEE convention of typeSubtype */ + tANI_U64 typeSubtypeBitmap; + + tANI_U64 reserved; + +}tHalEnableMonitorModeReqParams, *tpHalEnableMonitorModeReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnableMonitorModeReqParams enableMonitorModeReqParams; +}tHalEnableMonitorModeReqMsg, *tpHalEnableMonitorModeReqMsg; + + +/*--------------------------------------------------------------------------- +* WLAN_HAL_ENABLE_MONITOR_MODE_RSP +*-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +}tHalEnableMonitorModeRspParams, *tpHalEnableMonitorModeRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalEnableMonitorModeRspParams enableMonitorModeRspParams; +}tHalEnableMonitorModeRspMsg, *tpHalEnableMonitorModeRspMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_DISABLE_MONITOR_MODE_REQ +*-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tANI_U8 resetConfiguration; +}tHalDisableMonitorModeReqMsg, *tpHalDisableMonitorModeReqMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_DISABLE_MONITOR_MODE_RSP +*-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +}tHalDisableMonitorModeRspParams, *tpHalDisableMonitorModeRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalDisableMonitorModeRspParams disableMonitorModeRspParams; +}tHalDisableMonitorModeRspMsg, *tpHalDisableMonitorModeRspMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 status; +}tHalAvoidFreqRangeCtrlParam, *tpHalAvoidFreqRangeCtrlParam; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 paramType; + tANI_U32 paramValue; + tSirMacAddr bssid; +} tSetWifiConfigParams, *tpSetWifiConfigParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSetWifiConfigParams wifiConfigParams; +} tSetWifiConfigParamsReq, *tpSetWifiConfigParamsReq; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U32 status; +} tHalSetWifiConfigRspParams, * tpHalSetWifiConfigRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + + tHalSetWifiConfigRspParams setWifiConfigRspParams; +} tHalSetWifiConfigRsp, *tpHalSetWifiConfigRsp; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_REQ +*-------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 reserved; +} tHalAntennaDiversitySelectionReqParams, *tpHalAntennaDiversitySelectionReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalAntennaDiversitySelectionReqParams AntDivSelReqParams; +}tHalAntennaDiversitySelectionReqMsg; + +/*--------------------------------------------------------------------------- +* WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_RSP +*-------------------------------------------------------------------------*/ + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 status; + tANI_U32 selectedAntennaId; + tANI_U32 reserved; +} tHalAntennaDiversitySelectionRspParams, *tpHalAntennaDiversitySelectionRspParams; + +/* WDI_MODIFY_ROAM_PARAMS_IND */ +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 param; + tANI_U32 value; +} tHalModifyRoamParamsIndParams, *tpHalModifyRoamParamsIndParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalModifyRoamParamsIndParams modifyRoamParamsReqParams; +} tHalModifyRoamParamsInd, *tpHalModifyRoamParamsInd; + +typedef PACKED_PRE struct PACKED_POST +{ + tSirMacAddr selfMacAddr; + tANI_U32 enable; + tSirMacSSid ssId; + tANI_U32 rsn_authmode; + tANI_U32 rsn_ucastcipherset; + tANI_U32 rsn_mcastcipherset; + tANI_U32 rsn_mcastmgmtcipherset; + tANI_U32 channel; + tANI_U32 psk_len; + tANI_U8 psk[1]; +} tSapOffloadEnableMsg, *tpSapOffloadEnableMsg; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tSapOffloadEnableMsg SapOffloadEnableMsg; +} tHalSapoffloadEnable, *tpHalSapoffloadEnable; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bss_idx; + tANI_U32 enable; + tANI_U32 srv_ipv4; /* server IP */ + tANI_U32 start_lsb; /* starting address assigned to client */ + tANI_U32 num_client; /* number of clients we support */ +} hal_dhcp_srv_offload_req_param_t, *hal_dhcp_srv_offload_req_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_dhcp_srv_offload_req_param_t dhcp_srv_offload_req_params; +} hal_dhcp_srv_offload_req_msg_t; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} hal_dhcp_srv_offload_rsp_param_t, *hal_dhcp_srv_offload_rsp_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_dhcp_srv_offload_rsp_param_t dhcp_srv_offload_rsp_params; +} hal_dhcp_srv_offload_rsp_msg_t, *hal_dhcp_srv_offload_rsp_msg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bss_idx; + tANI_U32 enable; +} hal_mdns_enable_offload_req_param_t, *hal_mdns_enable_offload_req_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_enable_offload_req_param_t mdns_enable_req_params; +} hal_mdns_enable_offload_req_msg_t; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} hal_mdns_enable_offload_rsp_param_t, *hal_mdns_enable_offload_rsp_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_enable_offload_rsp_param_t mdns_enable_rsp_params; +} hal_mdns_enable_offload_rsp_msg_t, *hal_mdns_enable_offload_rsp_msg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bss_idx; + tANI_U32 type; + tANI_U32 fqdn_len; + tANI_U8 fqdn_data[1]; +} hal_mdns_fqdn_offload_req_param_t, *hal_mdns_fqdn_offload_req_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_fqdn_offload_req_param_t mdns_fqdn_req_params; +} hal_mdns_fqdn_offload_req_msg_t; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} hal_mdns_fqdn_offload_rsp_param_t, *hal_mdns_fqdn_offload_rsp_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_fqdn_offload_rsp_param_t mdns_fqdn_rsp_params; +} hal_mdns_fqdn_offload_rsp_msg_t, *hal_mdns_fqdn_offload_rsp_msg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_RESP_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bss_idx; + tANI_U32 ar_count; + tANI_U32 resp_len; + tANI_U8 resp_data[1]; +} hal_mdns_resp_offload_req_param_t, *hal_mdns_resp_offload_req_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_resp_offload_req_param_t mdns_resp_req_params; +} hal_mdns_resp_offload_req_msg_t; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_RESP_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; +} hal_mdns_resp_offload_rsp_param_t, *hal_mdns_resp_offload_rsp_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_resp_offload_rsp_param_t mdns_rsp_params; +} hal_mdns_resp_offload_rsp_msg_t, *hal_mdns_resp_offload_rsp_msg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_STATS_OFFLOAD_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bss_idx; +} hal_mdns_stats_offload_req_param_t, *hal_mdns_stats_offload_req_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_stats_offload_req_param_t mdns_stats_req_params; +} hal_mdns_stats_offload_req_msg_t; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_MDNS_STATS_OFFLOAD_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 bss_idx; + tANI_U32 current_ts; + tANI_U32 last_query_ts; + tANI_U32 last_rsp_ts; + tANI_U32 tot_queries; + tANI_U32 tot_matches; + tANI_U32 tot_rsp; + tANI_U32 status; +} hal_mdns_stats_offload_rsp_param_t, *hal_mdns_stats_offload_rsp_params; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + hal_mdns_stats_offload_rsp_param_t mdns_stats_rsp_params; +} hal_mdns_stats_offload_rsp_msg_t, *hal_mdns_stats_offload_rsp_msg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_SET_CLEAR_ARP_STATS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 set_clr; /*1 set and 0 reset*/ + tANI_U8 pkt_type; /* Default 1: ARP */ + tANI_U32 ip_addr; /*GW ipv4 address */ +} tHalStatsArpReqParams, *tpHalStatsArpReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsArpReqParams statsArpReqParams; +} tHalStatsArpReqMsg, *tpHalStatsArpReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_SET_CLEAR_ARP_STATS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; //success or failure +} tHalStatsArpRspParams, *tpHalStatsArpRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsArpRspParams statsArpRspParams; +} tHalStatsArpRspMsg, *tpHalStatsArpRspMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_GET_ARP_STATS_REQ + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 pkt_type; /* Furture purpose */ +} tHalStatsGetArpReqParams, *tpHalStatsGetArpReqParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tHalStatsGetArpReqParams statsGetArpReqParams; +} tHalStatsGetArpReqMsg, *tpHalStatsGetArpReqMsg; + +/*--------------------------------------------------------------------------- + * WLAN_HAL_FW_GET_ARP_STATS_RSP + *--------------------------------------------------------------------------*/ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 status; + tANI_U16 dad; + tANI_U16 arpReqRcvdInFW; + tANI_U16 ackedArpReqCnt; + tANI_U16 arpRspCnt; + tANI_U8 data[1]; +} tdbugArpStatsgetRspParams, *tpdbugArpStatsgetRspParams; + +typedef PACKED_PRE struct PACKED_POST +{ + tHalMsgHeader header; + tdbugArpStatsgetRspParams fwArpstatsRspParams; +} tHalARPfwStatsRspMsg, *tpHalARPfwStatsRspMsg; + +#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK) +#pragma pack(pop) +#elif defined(__ANI_COMPILER_PRAGMA_PACK) +#else +#endif + +#endif /* _WLAN_HAL_MSG_H_ */ diff --git a/drivers/staging/prima/riva/inc/wlan_nv.h b/drivers/staging/prima/riva/inc/wlan_nv.h new file mode 100644 index 000000000000..b99666c2bb30 --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_nv.h @@ -0,0 +1,845 @@ +/* + * Copyright (c) 2012, 2016 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** ------------------------------------------------------------------------- * + ------------------------------------------------------------------------- * + + + \file wlan_nv.h + + \brief Types for NV implementation + Anything that needs to be publicly available should + be in this file + + $Id$ + + + ========================================================================== */ + +#if !defined( __WLAN_NV_H ) +#define __WLAN_NV_H + +#include "halLegacyPalTypes.h" +#include "halCompiler.h" + +//From HAL/inc/halNv.h +typedef enum +{ + //Common Nv Fields + NV_COMMON_PRODUCT_ID, // 0 + NV_COMMON_PRODUCT_BANDS, // 1 + NV_COMMON_NUM_OF_TX_CHAINS, // 2 + NV_COMMON_NUM_OF_RX_CHAINS, // 3 + NV_COMMON_MAC_ADDR, // 4 + NV_COMMON_MFG_SERIAL_NUMBER, // 5 + NV_COMMON_WLAN_NV_REV_ID, // 6 + NV_COMMON_COUPLER_TYPE, // 7 + NV_COMMON_NV_VERSION, // 8 + NV_COMMON_RESERVED, // 9 + + NUM_NV_FIELDS, + NV_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ + +}eNvField; + + +#define NV_FIELD_MAC_ADDR_SIZE 6 +#define NV_FIELD_MFG_SN_SIZE 40 +typedef enum +{ + PRODUCT_BAND_11_B_G = 0, //Gen6.0 is only this setting + PRODUCT_BAND_11_A_B_G = 1, + PRODUCT_BAND_11_A = 2, + + NUM_PRODUCT_BANDS, + NUM_PRODUCT_BANDS_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}eNvProductBands; //NV_COMMON_PRODUCT_BANDS + +#define EXTERNAL_PA 1 +#define INTERNAL_PA 0 + +#define EXTERNAL_LNA 1 +#define INTERNAL_LNA 0 + +#define EXTERNAL_COUPLER 1 +#define INTERNAL_COUPLER 0 + +#define EXTERNAL_PDET 1 +#define INTERNAL_PDET 0 + +#define DPD_ENABLED 1 +#define DPD_DISABLED 0 + +#define TPC_MODE_OPEN_LOOP 0 +#define TPC_MODE_SCPC 1 +#define TPC_MODE_CLPC_MODE2 2 +#define TPC_MODE_CLPC_MODE3 3 + +#define PA_POLARITY_TX_UNUSED 0 +#define PA_POLARITY_TX_POSITIVE 1 +#define PA_POLARITY_TX_NEGATIVE 2 +#define PA_POLARITY_RX_UNUSED 0 +#define PA_POLARITY_RX_POSITIVE 1 +#define PA_POLARITY_RX_NEGATIVE 2 + +#define NV_VERSION_INVALID 0xFF +#define NV_VERSION_11N_11AC_COUPER_TYPE 0 +#define NV_VERSION_11N_11AC_FW_CONFIG 1 +#define NV_VERSION_LPDC_FW_CONFIG 2 +#ifdef FEATURE_WLAN_CH144 +#define NV_VERSION_CH144_CONFIG 3 +#endif /* FEATURE_WLAN_CH144 */ + +#ifdef WCN_PRONTO +#ifdef FEATURE_WLAN_CH144 +#define WLAN_NV_VERSION NV_VERSION_CH144_CONFIG +#else +#define WLAN_NV_VERSION NV_VERSION_LPDC_FW_CONFIG +#endif /* FEATURE_WLAN_CH144 */ +#else //WCN_PRONTO +#define WLAN_NV_VERSION NV_VERSION_11N_11AC_FW_CONFIG +#endif //WCN_PRONTO + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 macAddr1[NV_FIELD_MAC_ADDR_SIZE]; /* Default, not change name for compatibility */ + uint8 macAddr2[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr3[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr4[NV_FIELD_MAC_ADDR_SIZE]; +} sMacAddr; + +typedef PACKED_PRE union PACKED_POST +{ + //common NV fields + uint16 productId; + uint8 productBands; + uint8 wlanNvRevId; + uint8 numOfTxChains; + uint8 numOfRxChains; + sMacAddr macAddr; + uint8 mfgSN[NV_FIELD_MFG_SN_SIZE]; + uint8 couplerType; + uint8 nvVersion; +} uNvFields; + + +//format of common part of nv +typedef PACKED_PRE struct PACKED_POST +{ + //always ensure fields are aligned to 32-bit boundaries + uint16 productId; + uint8 productBands; + uint8 wlanNvRevId; //0: WCN1312, 1: WCN1314, 2: WCN3660 + + uint8 numOfTxChains; + uint8 numOfRxChains; + uint8 macAddr[NV_FIELD_MAC_ADDR_SIZE]; /* Default, not change name for compatibility */ + uint8 macAddr2[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr3[NV_FIELD_MAC_ADDR_SIZE]; + uint8 macAddr4[NV_FIELD_MAC_ADDR_SIZE]; + uint8 mfgSN[NV_FIELD_MFG_SN_SIZE]; + uint8 couplerType; + uint8 nvVersion; +} sNvFields; + + +//From wlanfw/inc/halPhyTypes.h + +typedef int8 tPowerdBm; //power in signed 8-bit integer, no decimal places + +typedef PACKED_PRE union PACKED_POST +{ + uint32 measurement; //measured values can be passed to pttApi, but are maintained to 2 decimal places internally + int16 reported; //used internally only - reported values only maintain 2 decimals places +}uAbsPwrPrecision; + +typedef enum +{ + PHY_TX_CHAIN_0 = 0, + + NUM_PHY_MAX_TX_CHAINS = 1, + PHY_MAX_TX_CHAINS = NUM_PHY_MAX_TX_CHAINS, + PHY_ALL_TX_CHAINS, + + //possible tx chain combinations + PHY_NO_TX_CHAINS, + PHY_TX_CHAIN_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}ePhyTxChains; + +//From wlanfw/inc/halRfTypes.h + +typedef enum +{ + REG_DOMAIN_FCC, + REG_DOMAIN_ETSI, + REG_DOMAIN_JAPAN, + REG_DOMAIN_WORLD, + REG_DOMAIN_N_AMER_EXC_FCC, + REG_DOMAIN_APAC, + REG_DOMAIN_KOREA, + REG_DOMAIN_HI_5GHZ, + REG_DOMAIN_NO_5GHZ, + + NUM_REG_DOMAINS, + NUM_REG_DOMAINS_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}eRegDomainId; + +typedef enum +{ + RF_SUBBAND_2_4_GHZ = 0, + RF_SUBBAND_5_LOW_GHZ = 1, //Low & Mid U-NII + RF_SUBBAND_5_MID_GHZ = 2, //ETSI + RF_SUBBAND_5_HIGH_GHZ = 3, //High U-NII + RF_SUBBAND_4_9_GHZ = 4, //Japanese + + + NUM_RF_SUBBANDS, + + MAX_RF_SUBBANDS, + INVALID_RF_SUBBAND, + + RF_BAND_2_4_GHZ = 0, + RF_BAND_5_GHZ = 1, + NUM_RF_BANDS, + BOTH_RF_BANDS, + RF_SUBBAND_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +}eRfSubBand; + +struct chan_to_ht_40_index_map { + uint16 ht_40_minus_index; + uint16 ht_40_plus_index; +}; + +typedef enum +{ + RF_CHAN_BOND_HT40_MINUS = 0, + RF_CHAN_BOND_HT40_PLUS +}eChannnelBondingTypes; + +typedef enum +{ + //2.4GHz Band + RF_CHAN_1 = 0, + RF_CHAN_2, + RF_CHAN_3, + RF_CHAN_4, + RF_CHAN_5, + RF_CHAN_6, + RF_CHAN_7, + RF_CHAN_8, + RF_CHAN_9, + RF_CHAN_10, + RF_CHAN_11, + RF_CHAN_12, + RF_CHAN_13, + RF_CHAN_14, + + //4.9GHz Band + RF_CHAN_240, + RF_CHAN_244, + RF_CHAN_248, + RF_CHAN_252, + RF_CHAN_208, + RF_CHAN_212, + RF_CHAN_216, + + //5GHz Low & Mid U-NII Band + RF_CHAN_36, + RF_CHAN_40, + RF_CHAN_44, + RF_CHAN_48, + RF_CHAN_52, + RF_CHAN_56, + RF_CHAN_60, + RF_CHAN_64, + + //5GHz Mid Band - ETSI & FCC + RF_CHAN_100, + RF_CHAN_104, + RF_CHAN_108, + RF_CHAN_112, + RF_CHAN_116, + RF_CHAN_120, + RF_CHAN_124, + RF_CHAN_128, + RF_CHAN_132, + RF_CHAN_136, + RF_CHAN_140, +#ifdef FEATURE_WLAN_CH144 + RF_CHAN_144, +#endif /* FEATURE_WLAN_CH144 */ + //5GHz High U-NII Band + RF_CHAN_149, + RF_CHAN_153, + RF_CHAN_157, + RF_CHAN_161, + RF_CHAN_165, + + //CHANNEL BONDED CHANNELS + RF_CHAN_BOND_3, + RF_CHAN_BOND_4, + RF_CHAN_BOND_5, + RF_CHAN_BOND_6, + RF_CHAN_BOND_7, + RF_CHAN_BOND_8, + RF_CHAN_BOND_9, + RF_CHAN_BOND_10, + RF_CHAN_BOND_11, + RF_CHAN_BOND_242, //4.9GHz Band + RF_CHAN_BOND_246, + RF_CHAN_BOND_250, + RF_CHAN_BOND_210, + RF_CHAN_BOND_214, + RF_CHAN_BOND_38, //5GHz Low & Mid U-NII Band + RF_CHAN_BOND_42, + RF_CHAN_BOND_46, + RF_CHAN_BOND_50, + RF_CHAN_BOND_54, + RF_CHAN_BOND_58, + RF_CHAN_BOND_62, + RF_CHAN_BOND_102, //5GHz Mid Band - ETSI & FCC + RF_CHAN_BOND_106, + RF_CHAN_BOND_110, + RF_CHAN_BOND_114, + RF_CHAN_BOND_118, + RF_CHAN_BOND_122, + RF_CHAN_BOND_126, + RF_CHAN_BOND_130, + RF_CHAN_BOND_134, + RF_CHAN_BOND_138, +#ifdef FEATURE_WLAN_CH144 + RF_CHAN_BOND_142, +#endif /* FEATURE_WLAN_CH144 */ + RF_CHAN_BOND_151, //5GHz High U-NII Band + RF_CHAN_BOND_155, + RF_CHAN_BOND_159, + RF_CHAN_BOND_163, + + NUM_RF_CHANNELS, + + MIN_2_4GHZ_CHANNEL = RF_CHAN_1, + MAX_2_4GHZ_CHANNEL = RF_CHAN_14, + + MIN_5GHZ_CHANNEL = RF_CHAN_240, + MAX_5GHZ_CHANNEL = RF_CHAN_165, + NUM_5GHZ_CHANNELS = (MAX_5GHZ_CHANNEL - MIN_5GHZ_CHANNEL + 1), + + MIN_20MHZ_RF_CHANNEL = RF_CHAN_1, + MAX_20MHZ_RF_CHANNEL = RF_CHAN_165, + NUM_20MHZ_RF_CHANNELS = (MAX_20MHZ_RF_CHANNEL - MIN_20MHZ_RF_CHANNEL + 1), + + MIN_40MHZ_RF_CHANNEL = RF_CHAN_BOND_3, + MAX_40MHZ_RF_CHANNEL = RF_CHAN_BOND_163, + NUM_40MHZ_RF_CHANNELS = (MAX_40MHZ_RF_CHANNEL - MIN_40MHZ_RF_CHANNEL + 1), + + MIN_CB_2_4GHZ_CHANNEL = RF_CHAN_BOND_3, + MAX_CB_2_4GHZ_CHANNEL = RF_CHAN_BOND_11, + + MIN_CB_5GHZ_CHANNEL = RF_CHAN_BOND_242, + MAX_CB_5GHZ_CHANNEL = RF_CHAN_BOND_163, + + NUM_TPC_2_4GHZ_CHANNELS = 14, + NUM_TPC_5GHZ_CHANNELS = NUM_5GHZ_CHANNELS, + + INVALID_RF_CHANNEL = 0xBAD, + RF_CHANNEL_INVALID_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ +}eRfChannels; + +typedef enum +{ + RF_CHAN_1_1 = RF_CHAN_1, + RF_CHAN_2_1 = RF_CHAN_2, + RF_CHAN_3_1 = RF_CHAN_3, + RF_CHAN_4_1 = RF_CHAN_4, + RF_CHAN_5_1 = RF_CHAN_5, + RF_CHAN_6_1 = RF_CHAN_6, + RF_CHAN_7_1 = RF_CHAN_7, + RF_CHAN_8_1 = RF_CHAN_8, + RF_CHAN_9_1 = RF_CHAN_9, + RF_CHAN_10_1 = RF_CHAN_10, + RF_CHAN_11_1 = RF_CHAN_11, + RF_CHAN_12_1 = RF_CHAN_12, + RF_CHAN_13_1 = RF_CHAN_13, + RF_CHAN_14_1 = RF_CHAN_14, +// The above params are used for scripts. + NUM_2_4GHZ_CHANNELS, +}eRfChannels_2_4GHz; + +enum +{ + NV_CHANNEL_DISABLE, + NV_CHANNEL_ENABLE, + NV_CHANNEL_DFS, + NV_CHANNEL_INVALID +}; +typedef uint8 eNVChannelEnabledType; + +typedef PACKED_PRE struct PACKED_POST +{ + eNVChannelEnabledType enabled; + tPowerdBm pwrLimit; +}sRegulatoryChannel; + +typedef PACKED_PRE struct PACKED_POST +{ + sRegulatoryChannel channels[NUM_RF_CHANNELS]; + uAbsPwrPrecision antennaGain[NUM_RF_SUBBANDS]; + uAbsPwrPrecision bRatePowerOffset[NUM_2_4GHZ_CHANNELS]; + uAbsPwrPrecision gnRatePowerOffset[NUM_RF_CHANNELS]; +}ALIGN_4 sRegulatoryDomains; + +typedef PACKED_PRE struct PACKED_POST +{ + int16 bRssiOffset[NUM_RF_CHANNELS]; + int16 gnRssiOffset[NUM_RF_CHANNELS]; +}ALIGN_4 sRssiChannelOffsets; + +typedef PACKED_PRE struct PACKED_POST +{ + uint16 targetFreq; //number in MHz + uint16 channelNum; //channel number as in the eRfChannels enumeration + eRfSubBand band; //band that this channel belongs to +}tRfChannelProps; + +typedef enum +{ + MODE_802_11B = 0, + MODE_802_11AG = 1, + MODE_802_11N = 2, + NUM_802_11_MODES, + MODE_802_11_INVALID = 0x7FFFFFFF /* define as 4 bytes data */ +} e80211Modes; + +#define HW_CAL_VALUES_VALID_BMAP_UNUSED 0 //Value +//Bit mask +#define HW_CAL_VALUES_VALID_BMAP_SLEEP_TIME_OVERHEAD_2G_MASK 0x1 +#define HW_CAL_VALUES_VALID_BMAP_SLEEP_TIME_OVERHEAD_5G_MASK 0x2 +#define HW_CAL_VALUES_VALID_BMAP_SLEEP_TIME_OVERHEAD_xLNA_5G_MASK 0x4 +#define HW_CAL_VALUES_VALID_TXBBF_SEL_9MHZ_MASK 0x8 +#define HW_CAL_VALUES_VALID_CUSTOM_TCXO_REG8_MASK 0x10 +#define HW_CAL_VALUES_VALID_CUSTOM_TCXO_REG9_MASK 0x20 +#define HW_CAL_VALUES_VALID_ANTENNA_DIVERSITY_ENABLED_MASK 0x40 +#define HW_CAL_VALUES_VALID_CUSTOM_RC_DELAY_MASK 0x80 + +//From wlanfw/inc/halPhyCalMemory.h +typedef PACKED_PRE struct PACKED_POST +{ + uint16 psSlpTimeOvrHd2G; + uint16 psSlpTimeOvrHd5G; + + uint16 psSlpTimeOvrHdxLNA5G; + uint8 nv_TxBBFSel9MHz : 1; + uint8 hwParam1 : 7; + uint8 hwParam2; + + uint16 custom_tcxo_reg8; + uint16 custom_tcxo_reg9; + + uint32 hwParam3; + uint32 hwParam4; + uint32 hwParam5; + uint32 hwParam6; + uint32 hwParam7; + uint32 hwParam8; + uint32 hwParam9; + uint32 hwParam10; + uint32 hwParam11; +}sCalData; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 validBmap; //use eNvCalID + sCalData calData; +}sHwCalValues; + +typedef PACKED_PRE struct PACKED_POST +{ + uint32 txFirFilterMode; +}sTxBbFilterMode; + +typedef PACKED_PRE struct PACKED_POST +{ + int16 ofdmPwrOffset; + int16 rsvd; +}sOfdmCmdPwrOffset; + +//From wlanfw/inc/halPhyCfg.h +typedef uint8 tTpcLutValue; + +#define MAX_TPC_CAL_POINTS (8) + +typedef uint8 tPowerDetect; //7-bit power detect reading + +typedef PACKED_PRE struct PACKED_POST +{ + tPowerDetect pwrDetAdc; //= SENSED_PWR register, which reports the 8-bit ADC + // the stored ADC value gets shifted to 7-bits as the index to the LUT + tPowerDetect adjustedPwrDet; //7-bit value that goes into the LUT at the LUT[pwrDet] location + //MSB set if extraPrecision.hi8_adjustedPwrDet is used +}tTpcCaldPowerPoint; + +typedef tTpcCaldPowerPoint tTpcCaldPowerTable[NUM_PHY_MAX_TX_CHAINS][MAX_TPC_CAL_POINTS]; + +typedef PACKED_PRE struct PACKED_POST +{ + tTpcCaldPowerTable empirical; //calibrated power points +}tTpcConfig; + +//From wlanfw/inc/phyTxPower.h +#ifndef TPC_MEM_POWER_LUT_DEPTH +#define TPC_MEM_POWER_LUT_DEPTH 256 +#endif + +typedef tTpcLutValue tTpcPowerTable[NUM_PHY_MAX_TX_CHAINS][TPC_MEM_POWER_LUT_DEPTH]; + +typedef PACKED_PRE struct PACKED_POST +{ + tTpcConfig *pwrSampled; //points to CLPC data in calMemory +}tPhyTxPowerBand; + +//From halPhyRates.h +typedef enum +{ + //802.11b Rates + HAL_PHY_RATE_11B_LONG_1_MBPS, + HAL_PHY_RATE_11B_LONG_2_MBPS, + HAL_PHY_RATE_11B_LONG_5_5_MBPS, + HAL_PHY_RATE_11B_LONG_11_MBPS, + HAL_PHY_RATE_11B_SHORT_2_MBPS, + HAL_PHY_RATE_11B_SHORT_5_5_MBPS, + HAL_PHY_RATE_11B_SHORT_11_MBPS, + + //Spica_Virgo 11A 20MHz Rates + HAL_PHY_RATE_11A_6_MBPS, + HAL_PHY_RATE_11A_9_MBPS, + HAL_PHY_RATE_11A_12_MBPS, + HAL_PHY_RATE_11A_18_MBPS, + HAL_PHY_RATE_11A_24_MBPS, + HAL_PHY_RATE_11A_36_MBPS, + HAL_PHY_RATE_11A_48_MBPS, + HAL_PHY_RATE_11A_54_MBPS, + + // 11A 20MHz Rates + HAL_PHY_RATE_11A_DUP_6_MBPS, + HAL_PHY_RATE_11A_DUP_9_MBPS, + HAL_PHY_RATE_11A_DUP_12_MBPS, + HAL_PHY_RATE_11A_DUP_18_MBPS, + HAL_PHY_RATE_11A_DUP_24_MBPS, + HAL_PHY_RATE_11A_DUP_36_MBPS, + HAL_PHY_RATE_11A_DUP_48_MBPS, + HAL_PHY_RATE_11A_DUP_54_MBPS, + + //MCS Index #0-7 (20/40MHz) + HAL_PHY_RATE_MCS_1NSS_6_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_13_MBPS, + HAL_PHY_RATE_MCS_1NSS_19_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_26_MBPS, + HAL_PHY_RATE_MCS_1NSS_39_MBPS, + HAL_PHY_RATE_MCS_1NSS_52_MBPS, + HAL_PHY_RATE_MCS_1NSS_58_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_65_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_7_2_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_14_4_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_21_7_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_28_9_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_43_3_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_57_8_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_65_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_72_2_MBPS, + + //MCS Index #8-15 (20/40MHz) + HAL_PHY_RATE_MCS_1NSS_CB_13_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_27_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_40_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_54_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_81_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_108_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_121_5_MBPS, + HAL_PHY_RATE_MCS_1NSS_CB_135_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_15_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_30_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_45_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_60_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_90_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_120_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_135_MBPS, + HAL_PHY_RATE_MCS_1NSS_MM_SG_CB_150_MBPS, + +#ifdef WLAN_FEATURE_11AC + /*11A duplicate 80MHz Rates*/ + HAL_PHY_RATE_11AC_DUP_6_MBPS, + HAL_PHY_RATE_11AC_DUP_9_MBPS, + HAL_PHY_RATE_11AC_DUP_12_MBPS, + HAL_PHY_RATE_11AC_DUP_18_MBPS, + HAL_PHY_RATE_11AC_DUP_24_MBPS, + HAL_PHY_RATE_11AC_DUP_36_MBPS, + HAL_PHY_RATE_11AC_DUP_48_MBPS, + HAL_PHY_RATE_11AC_DUP_54_MBPS, + + /*11AC rate 20MHZ Normal GI*/ + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_6_5_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_13_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_19_5_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_26_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_39_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_52_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_58_5_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_65_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_78_MBPS, +#ifdef WCN_PRONTO + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_NGI_86_5_MBPS, +#endif + + /*11AC rate 20MHZ Shortl GI*/ + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_7_2_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_14_4_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_21_6_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_28_8_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_43_3_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_57_7_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_65_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_72_2_MBPS, + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_86_6_MBPS, +#ifdef WCN_PRONTO + HAL_PHY_RATE_VHT_20MHZ_MCS_1NSS_SGI_96_1_MBPS, +#endif + + /*11AC rates 40MHZ normal GI*/ + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_13_5_MBPS , + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_27_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_40_5_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_54_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_81_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_108_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_121_5_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_135_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_162_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_NGI_180_MBPS, + + /*11AC rates 40MHZ short GI*/ + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_15_MBPS , + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_30_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_45_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_60_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_90_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_120_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_135_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_150_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_180_MBPS, + HAL_PHY_RATE_VHT_40MHZ_MCS_1NSS_CB_SGI_200_MBPS, + + /*11AC rates 80 MHZ normal GI*/ + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_29_3_MBPS , + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_58_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_87_8_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_117_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_175_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_234_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_263_3_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_292_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_351_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_NGI_390_MBPS, + + /*11AC rates 80 MHZ short GI*/ + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_32_5_MBPS , + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_65_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_97_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_130_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_195_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_260_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_292_5_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_325_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_390_MBPS, + HAL_PHY_RATE_VHT_80MHZ_MCS_1NSS_CB_SGI_433_3_MBPS, +#endif //WLAN_FEATURE_11AC + + NUM_HAL_PHY_RATES, + HAL_PHY_RATE_INVALID, + MIN_RATE_INDEX = 0, + MAX_RATE_INDEX = NUM_HAL_PHY_RATES - 1, + HAL_PHY_RATE_INVALID_MAX_FIELD = 0x7FFFFFFF /* define as 4 bytes data */ +}eHalPhyRates; + +#define NUM_RATE_POWER_GROUPS NUM_HAL_PHY_RATES //total number of rate power groups including the CB_RATE_POWER_OFFSET +typedef uAbsPwrPrecision tRateGroupPwr[NUM_HAL_PHY_RATES]; + +//From halNvTables.h +#define NV_FIELD_COUNTRY_CODE_SIZE 3 +typedef PACKED_PRE struct PACKED_POST +{ + uint8 regDomain; //from eRegDomainId + uint8 countryCode[NV_FIELD_COUNTRY_CODE_SIZE]; // string identifier +}sDefaultCountry; + + +#define GF_PA_BIAS_SELECT_MASK 0X7 //(3 bits) +#define TSMC_PA_BIAS_SELECT_MASK 0x7 //(3 bits) + +#define GF_PA_BIAS_SELECT_1 0X0 +#define GF_PA_BIAS_SELECT_2 0X1 + +#define TSMC_PA_BIAS_SELECT_1 0X0 +#define TSMC_PA_BIAS_SELECT_2 0X1 +#define TSMC_PA_BIAS_SELECT_3 0x2 + + +#define EXT_PA_CTRL_POLARITY_DEFAULT 0X0 +#define EXT_PA_CTRL_POLARITY_VALID 0X80 + +#define EXT_PA_CTRL0_POLARITY_MASK 0X3 +#define EXT_PA_CTRL0_POLARITY_OFFSET 0X0 +#define EXT_PA_CTRL1_POLARITY_MASK 0XC +#define EXT_PA_CTRL1_POLARITY_OFFSET 0X2 + +#define EXT_PA_CTRL_POLARITY_ZERO 0X1 +#define EXT_PA_CTRL_POLARITY_ONE 0X2 + +#define GF_TX_PWR_ADJUST_2G_MASK 0XF0000 +#define GF_TX_PWR_ADJUST_2G_OFFSET 16 +#define GF_TX_PWR_ADJUST_5G_LOW_MASK 0XF00000 +#define GF_TX_PWR_ADJUST_5G_LOW_OFFSET 20 +#define GF_TX_PWR_ADJUST_5G_MID_MASK 0XF000000 +#define GF_TX_PWR_ADJUST_5G_MID_OFFSET 24 +#define GF_TX_PWR_ADJUST_5G_HIGH_MASK 0XF0000000 +#define GF_TX_PWR_ADJUST_5G_HIGH_OFFSET 28 + + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 skuID; + uint8 tpcMode2G; + uint8 tpcMode5G; + uint8 configItem1; + + uint8 xPA2G; + uint8 xPA5G; + uint8 extPaCtrl0Polarity; + uint8 extPaCtrl1Polarity; + + uint8 xLNA2G; + uint8 xLNA5G; + uint8 xCoupler2G; + uint8 xCoupler5G; + + uint8 xPdet2G; + uint8 xPdet5G; + uint8 enableDPD2G; + uint8 enableDPD5G; + + uint8 pdadcSelect2G; + uint8 pdadcSelect5GLow; + uint8 pdadcSelect5GMid; + uint8 pdadcSelect5GHigh; + + uint32 configItem2; + uint32 configItem3; + uint32 configItem4; +}sFwConfig; + + +#define NUM_RF_VR_RATE 13 +typedef uAbsPwrPrecision tRateGroupPwrVR[NUM_RF_VR_RATE]; + +typedef PACKED_PRE union PACKED_POST +{ + tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; // NV_TABLE_RATE_POWER_SETTINGS + sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; // NV_TABLE_REGULATORY_DOMAINS + sDefaultCountry defaultCountryTable; // NV_TABLE_DEFAULT_COUNTRY + tTpcPowerTable plutCharacterized[NUM_RF_CHANNELS]; // NV_TABLE_TPC_POWER_TABLE + int16 plutPdadcOffset[NUM_RF_CHANNELS]; // NV_TABLE_TPC_PDADC_OFFSETS + tRateGroupPwrVR pwrOptimum_virtualRate[NUM_RF_SUBBANDS]; // NV_TABLE_VIRTUAL_RATE + sFwConfig fwConfig; // NV_TABLE_FW_CONFIG + sRssiChannelOffsets rssiChanOffsets[2]; // NV_TABLE_RSSI_CHANNEL_OFFSETS + sHwCalValues hwCalValues; // NV_TABLE_HW_CAL_VALUES + int16 antennaPathLoss[NUM_RF_CHANNELS]; // NV_TABLE_ANTENNA_PATH_LOSS + int16 pktTypePwrLimits[NUM_802_11_MODES][NUM_RF_CHANNELS]; // NV_TABLE_PACKET_TYPE_POWER_LIMITS + sOfdmCmdPwrOffset ofdmCmdPwrOffset; // NV_TABLE_OFDM_CMD_PWR_OFFSET + sTxBbFilterMode txbbFilterMode; // NV_TABLE_TX_BB_FILTER_MODE +}ALIGN_4 uNvTables; + +//From halPhy.h +typedef tPowerdBm tChannelPwrLimit; + +typedef PACKED_PRE struct PACKED_POST +{ + uint8 chanId; + tChannelPwrLimit pwr; +} ALIGN_4 tChannelListWithPower; + +//From HAL/inc/halNvTables.h +typedef enum +{ + NV_FIELDS_IMAGE = 0, //contains all fields + + NV_TABLE_RATE_POWER_SETTINGS = 2, + NV_TABLE_REGULATORY_DOMAINS = 3, + NV_TABLE_DEFAULT_COUNTRY = 4, + NV_TABLE_TPC_POWER_TABLE = 5, + NV_TABLE_TPC_PDADC_OFFSETS = 6, + NV_TABLE_HW_CAL_VALUES = 7, + NV_TABLE_RSSI_CHANNEL_OFFSETS = 9, + NV_TABLE_CAL_MEMORY = 10, //cal memory structure from halPhyCalMemory.h preceded by status + NV_TABLE_FW_CONFIG = 11, + NV_TABLE_ANTENNA_PATH_LOSS = 12, + NV_TABLE_PACKET_TYPE_POWER_LIMITS = 13, + NV_TABLE_OFDM_CMD_PWR_OFFSET = 14, + NV_TABLE_TX_BB_FILTER_MODE = 15, + NV_TABLE_VIRTUAL_RATE = 18, + + NUM_NV_TABLE_IDS, + NV_ALL_TABLES = 0xFFF, + NV_BINARY_IMAGE = 0x1000, + NV_MAX_TABLE = 0x7FFFFFFF /* define as 4 bytes data */ +}eNvTable; + +typedef PACKED_PRE struct PACKED_POST +{ + tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; // NV_TABLE_RATE_POWER_SETTINGS + sRegulatoryDomains regDomains[NUM_REG_DOMAINS]; // NV_TABLE_REGULATORY_DOMAINS + sDefaultCountry defaultCountryTable; // NV_TABLE_DEFAULT_COUNTRY + tTpcPowerTable plutCharacterized[NUM_RF_CHANNELS]; // NV_TABLE_TPC_POWER_TABLE + int16 plutPdadcOffset[NUM_RF_CHANNELS]; // NV_TABLE_TPC_PDADC_OFFSETS + tRateGroupPwrVR pwrOptimum_virtualRate[NUM_RF_SUBBANDS]; // NV_TABLE_VIRTUAL_RATE + sFwConfig fwConfig; // NV_TABLE_FW_CONFIG + sRssiChannelOffsets rssiChanOffsets[2]; // NV_TABLE_RSSI_CHANNEL_OFFSETS + sHwCalValues hwCalValues; // NV_TABLE_HW_CAL_VALUES + int16 antennaPathLoss[NUM_RF_CHANNELS]; // NV_TABLE_ANTENNA_PATH_LOSS + int16 pktTypePwrLimits[NUM_802_11_MODES][NUM_RF_CHANNELS]; // NV_TABLE_PACKET_TYPE_POWER_LIMITS + sOfdmCmdPwrOffset ofdmCmdPwrOffset; // NV_TABLE_OFDM_CMD_PWR_OFFSET + sTxBbFilterMode txbbFilterMode; // NV_TABLE_TX_BB_FILTER_MODE +}ALIGN_4 sNvTables; + +typedef PACKED_PRE struct PACKED_POST +{ + sNvFields fields; + sNvTables tables; +}ALIGN_4 sHalNv; + +extern const sHalNv nvDefaults; + +#endif + diff --git a/drivers/staging/prima/riva/inc/wlan_nv2.h b/drivers/staging/prima/riva/inc/wlan_nv2.h new file mode 100644 index 000000000000..e74e5fe0482f --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_nv2.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/**========================================================================= + ========================================================================*/ +/** ------------------------------------------------------------------------- * + + ------------------------------------------------------------------------- * + + + \file wlan_nv2.h + + \brief Types for NV implementation + Anything that needs to be publicly available should + be in this file + + $Id$ + + + ========================================================================== */ + +#if !defined( __WLAN_NV2_H ) +#define __WLAN_NV2_H + +#include "halLegacyPalTypes.h" +#include "halCompiler.h" +#include "wlan_nv.h" + +/* From here, NV2 No CH144 support reduced structure + * This structure will be used for NV2 backward compatibility */ + +typedef enum +{ + //2.4GHz Band + RF_CHAN_1_V2 = 0, + RF_CHAN_2_V2 = 1, + RF_CHAN_3_V2 = 2, + RF_CHAN_4_V2 = 3, + RF_CHAN_5_V2 = 4, + RF_CHAN_6_V2 = 5, + RF_CHAN_7_V2 = 6, + RF_CHAN_8_V2 = 7, + RF_CHAN_9_V2 = 8, + RF_CHAN_10_V2 = 9, + RF_CHAN_11_V2 = 10, + RF_CHAN_12_V2 = 11, + RF_CHAN_13_V2 = 12, + RF_CHAN_14_V2 = 13, + + //4.9GHz Band + RF_CHAN_240_V2 = 14, + RF_CHAN_244_V2 = 15, + RF_CHAN_248_V2 = 16, + RF_CHAN_252_V2 = 17, + RF_CHAN_208_V2 = 18, + RF_CHAN_212_V2 = 19, + RF_CHAN_216_V2 = 20, + + //5GHz Low & Mid U-NII Band + RF_CHAN_36_V2 = 21, + RF_CHAN_40_V2 = 22, + RF_CHAN_44_V2 = 23, + RF_CHAN_48_V2 = 24, + RF_CHAN_52_V2 = 25, + RF_CHAN_56_V2 = 26, + RF_CHAN_60_V2 = 27, + RF_CHAN_64_V2 = 28, + + //5GHz Mid Band - ETSI & FCC + RF_CHAN_100_V2 = 29, + RF_CHAN_104_V2 = 30, + RF_CHAN_108_V2 = 31, + RF_CHAN_112_V2 = 32, + RF_CHAN_116_V2 = 33, + RF_CHAN_120_V2 = 34, + RF_CHAN_124_V2 = 35, + RF_CHAN_128_V2 = 36, + RF_CHAN_132_V2 = 37, + RF_CHAN_136_V2 = 38, + RF_CHAN_140_V2 = 39, + + //5GHz High U-NII Band + RF_CHAN_149_V2 = 40, + RF_CHAN_153_V2 = 41, + RF_CHAN_157_V2 = 42, + RF_CHAN_161_V2 = 43, + RF_CHAN_165_V2 = 44, + + //CHANNEL BONDED CHANNELS + RF_CHAN_BOND_3_V2 = 45, + RF_CHAN_BOND_4_V2 = 46, + RF_CHAN_BOND_5_V2 = 47, + RF_CHAN_BOND_6_V2 = 48, + RF_CHAN_BOND_7_V2 = 49, + RF_CHAN_BOND_8_V2 = 50, + RF_CHAN_BOND_9_V2 = 51, + RF_CHAN_BOND_10_V2 = 52, + RF_CHAN_BOND_11_V2 = 53, + RF_CHAN_BOND_242_V2 = 54, //4.9GHz Band + RF_CHAN_BOND_246_V2 = 55, + RF_CHAN_BOND_250_V2 = 56, + RF_CHAN_BOND_210_V2 = 57, + RF_CHAN_BOND_214_V2 = 58, + RF_CHAN_BOND_38_V2 = 59, //5GHz Low & Mid U-NII Band + RF_CHAN_BOND_42_V2 = 60, + RF_CHAN_BOND_46_V2 = 61, + RF_CHAN_BOND_50_V2 = 62, + RF_CHAN_BOND_54_V2 = 63, + RF_CHAN_BOND_58_V2 = 64, + RF_CHAN_BOND_62_V2 = 65, + RF_CHAN_BOND_102_V2 = 66, //5GHz Mid Band - ETSI & FCC + RF_CHAN_BOND_106_V2 = 67, + RF_CHAN_BOND_110_V2 = 68, + RF_CHAN_BOND_114_V2 = 69, + RF_CHAN_BOND_118_V2 = 70, + RF_CHAN_BOND_122_V2 = 71, + RF_CHAN_BOND_126_V2 = 72, + RF_CHAN_BOND_130_V2 = 73, + RF_CHAN_BOND_134_V2 = 74, + RF_CHAN_BOND_138_V2 = 75, + RF_CHAN_BOND_151_V2 = 76, //5GHz High U-NII Band + RF_CHAN_BOND_155_V2 = 77, + RF_CHAN_BOND_159_V2 = 78, + RF_CHAN_BOND_163_V2 = 79, + + NUM_RF_CHANNELS_V2, + + MIN_2_4GHZ_CHANNEL_V2 = RF_CHAN_1_V2, + MAX_2_4GHZ_CHANNEL_V2 = RF_CHAN_14_V2, + + MIN_5GHZ_CHANNEL_V2 = RF_CHAN_240_V2, + MAX_5GHZ_CHANNEL_V2 = RF_CHAN_165_V2, + NUM_5GHZ_CHANNELS_V2 = (MAX_5GHZ_CHANNEL_V2 - MIN_5GHZ_CHANNEL_V2 + 1), + + MIN_20MHZ_RF_CHANNEL_V2 = RF_CHAN_1_V2, + MAX_20MHZ_RF_CHANNEL_V2 = RF_CHAN_165_V2, + NUM_20MHZ_RF_CHANNELS_V2 = (MAX_20MHZ_RF_CHANNEL_V2 - MIN_20MHZ_RF_CHANNEL_V2 + 1), + + MIN_40MHZ_RF_CHANNEL_V2 = RF_CHAN_BOND_3_V2, + MAX_40MHZ_RF_CHANNEL_V2 = RF_CHAN_BOND_163_V2, + NUM_40MHZ_RF_CHANNELS_V2 = (MAX_40MHZ_RF_CHANNEL_V2 - MIN_40MHZ_RF_CHANNEL_V2 + 1), + + MIN_CB_2_4GHZ_CHANNEL_V2 = RF_CHAN_BOND_3_V2, + MAX_CB_2_4GHZ_CHANNEL_V2 = RF_CHAN_BOND_11_V2, + + MIN_CB_5GHZ_CHANNEL_V2 = RF_CHAN_BOND_242_V2, + MAX_CB_5GHZ_CHANNEL_V2 = RF_CHAN_BOND_163_V2, + + NUM_TPC_2_4GHZ_CHANNELS_V2 = 14, + NUM_TPC_5GHZ_CHANNELS_V2 = NUM_5GHZ_CHANNELS_V2, + + INVALID_RF_CHANNEL_V2 = 0xBAD, + RF_CHANNEL_INVALID_MAX_FIELD_V2 = 0x7FFFFFFF /* define as 4 bytes data */ +}eRfChannelsV2; + +typedef PACKED_PRE struct PACKED_POST +{ + sRegulatoryChannel channels[NUM_RF_CHANNELS_V2]; + uAbsPwrPrecision antennaGain[NUM_RF_SUBBANDS]; + uAbsPwrPrecision bRatePowerOffset[NUM_2_4GHZ_CHANNELS]; + uAbsPwrPrecision gnRatePowerOffset[NUM_RF_CHANNELS_V2]; +}ALIGN_4 sRegulatoryDomainsV2; + +typedef PACKED_PRE struct PACKED_POST +{ + int16 bRssiOffset[NUM_RF_CHANNELS_V2]; + int16 gnRssiOffset[NUM_RF_CHANNELS_V2]; +}ALIGN_4 sRssiChannelOffsetsV2; + +typedef PACKED_PRE union PACKED_POST +{ + tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; // NV_TABLE_RATE_POWER_SETTINGS + sRegulatoryDomainsV2 regDomains[NUM_REG_DOMAINS]; // NV_TABLE_REGULATORY_DOMAINS + sDefaultCountry defaultCountryTable; // NV_TABLE_DEFAULT_COUNTRY + tTpcPowerTable plutCharacterized[NUM_RF_CHANNELS_V2]; // NV_TABLE_TPC_POWER_TABLE + int16 plutPdadcOffset[NUM_RF_CHANNELS_V2]; // NV_TABLE_TPC_PDADC_OFFSETS + tRateGroupPwrVR pwrOptimum_virtualRate[NUM_RF_SUBBANDS]; // NV_TABLE_VIRTUAL_RATE + sFwConfig fwConfig; // NV_TABLE_FW_CONFIG + sRssiChannelOffsetsV2 rssiChanOffsets[2]; // NV_TABLE_RSSI_CHANNEL_OFFSETS + sHwCalValues hwCalValues; // NV_TABLE_HW_CAL_VALUES + int16 antennaPathLoss[NUM_RF_CHANNELS_V2]; // NV_TABLE_ANTENNA_PATH_LOSS + int16 pktTypePwrLimits[NUM_802_11_MODES][NUM_RF_CHANNELS_V2]; // NV_TABLE_PACKET_TYPE_POWER_LIMITS + sOfdmCmdPwrOffset ofdmCmdPwrOffset; // NV_TABLE_OFDM_CMD_PWR_OFFSET + sTxBbFilterMode txbbFilterMode; // NV_TABLE_TX_BB_FILTER_MODE +}ALIGN_4 uNvTablesV2; + +typedef PACKED_PRE struct PACKED_POST +{ + tRateGroupPwr pwrOptimum[NUM_RF_SUBBANDS]; // NV_TABLE_RATE_POWER_SETTINGS + sRegulatoryDomainsV2 regDomains[NUM_REG_DOMAINS]; // NV_TABLE_REGULATORY_DOMAINS + sDefaultCountry defaultCountryTable; // NV_TABLE_DEFAULT_COUNTRY + tTpcPowerTable plutCharacterized[NUM_RF_CHANNELS_V2]; // NV_TABLE_TPC_POWER_TABLE + int16 plutPdadcOffset[NUM_RF_CHANNELS_V2]; // NV_TABLE_TPC_PDADC_OFFSETS + tRateGroupPwrVR pwrOptimum_virtualRate[NUM_RF_SUBBANDS]; // NV_TABLE_VIRTUAL_RATE + sFwConfig fwConfig; // NV_TABLE_FW_CONFIG + sRssiChannelOffsetsV2 rssiChanOffsets[2]; // NV_TABLE_RSSI_CHANNEL_OFFSETS + sHwCalValues hwCalValues; // NV_TABLE_HW_CAL_VALUES + int16 antennaPathLoss[NUM_RF_CHANNELS_V2]; // NV_TABLE_ANTENNA_PATH_LOSS + int16 pktTypePwrLimits[NUM_802_11_MODES][NUM_RF_CHANNELS_V2]; // NV_TABLE_PACKET_TYPE_POWER_LIMITS + sOfdmCmdPwrOffset ofdmCmdPwrOffset; // NV_TABLE_OFDM_CMD_PWR_OFFSET + sTxBbFilterMode txbbFilterMode; // NV_TABLE_TX_BB_FILTER_MODE +}ALIGN_4 sNvTablesV2; + +typedef PACKED_PRE struct PACKED_POST +{ + sNvFields fields; + sNvTablesV2 tables; +}ALIGN_4 sHalNvV2; + +extern const sHalNvV2 nvDefaultsV2; + +#endif + diff --git a/drivers/staging/prima/riva/inc/wlan_phy.h b/drivers/staging/prima/riva/inc/wlan_phy.h new file mode 100644 index 000000000000..59ba019494b6 --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_phy.h @@ -0,0 +1,919 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_PHY_H +#define WLAN_PHY_H +/*============================================================================ +@file wlan_phy.h + +Contains definitions of all PHY related structures that aree needed by FTM/PTT +============================================================================*/ +#include + +/* Currently this structure holds the information about the current calibration mode. +In future, if anymore info is needed, that can be added here */ +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 currentCalibration; +} sCalibrationInfo; + +typedef PACKED_PRE struct PACKED_POST { + tANI_S16 I; //ADC sample of PHY_I_RAIL + tANI_S16 Q; //ADC sample of PHY_Q_RAIL +}tIQSamples; + +typedef tIQSamples tIQAdc; +typedef tIQSamples tIQDac; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 maxGainIndex; + tANI_U8 topGainDb; + tANI_U8 bottomGainDb; + tANI_U8 unused[1]; +}tAsicAgc; + +#define TXFIR_MEM QWLAN_TXFIR_TXCAL_MEM0_MREG +#define TXFIR_MEM_GAIN_MULT (16) //bytes per gain +#define TXFIR_MEM_PER_CHAIN (16 * TXFIR_MEM_GAIN_MULT) //# of gains per chain * bytes per gain + +typedef tIQAdc tTxCarrierError; + +#define ONE_MICROSECOND (160) +#define DEFAULT_INTERFRAME_SPACE (ONE_MICROSECOND * 10) //10 microseconds + +typedef enum { + PHYDBG_TX_IDLE = 0, + PHYDBG_TX_START = 1, + PHYDBG_TX_WARMUP = 2, + PHYDBG_TX_INFD = 3, + PHYDBG_TX_CMD = 4, + PHYDBG_TX_SVC = 5, + PHYDBG_TX_PYLDF = 6, + PHYDBG_TX_PYLDR = 7, + PHYDBG_TX_CRC = 8, + PHYDBG_TX_FLUSH = 9, + PHYDBG_TX_TXDONEWAIT = 10, + PHYDBG_TX_TIFWAIT = 11 +} ePhyDbgTxStatus; + +typedef enum { + PHYDBG_PREAMBLE_OFDM, + PHYDBG_PREAMBLE_GREENFIELD, + PHYDBG_PREAMBLE_MIXED, + PHYDBG_PREAMBLE_SHORTB, + PHYDBG_PREAMBLE_LONGB, + + PHYDBG_LDPC_PREAMBLE_OFDM = 0x10, + PHYDBG_LDPC_PREAMBLE_GREENFIELD = 0x11, + PHYDBG_LDPC_PREAMBLE_MIXED = 0x12 +} ePhyDbgPreamble; + + +//grab ram +#ifdef VERIFY_HALPHY_SIMV_MODEL +#define GRAB_RAM_DBLOCK_SIZE (256) //number of samples in full capture +#else +#define GRAB_RAM_DBLOCK_SIZE (1024) //number of samples in full capture +#endif + +#define MAX_REQUESTED_GRAB_RAM_SAMPLES 256 //only allow 256 samples at a time +#define GRAB_RAM_BUFFER_DEPTH (4*1024) //maximum grab ram size in full capture +#define LAST_GRAB_RAM_SAMPLE_INDEX (GRAB_RAM_BUFFER_DEPTH - 1) + + +typedef PACKED_PRE struct PACKED_POST { + tIQAdc rx0; +} tGrabRamSample; + + +enum { + GRABRAM_RAWADC = 0, + GRABRAM_POSTIQ +}; +typedef tANI_U32 eGrabRamSampleType; + +typedef tANI_S8 tANI_S6; +typedef tANI_S16 tANI_S9; +typedef tANI_S16 tANI_S10; +typedef tANI_S16 tANI_S12; +typedef tANI_U16 tANI_U10; + + + +//convert float to a format that preserves enough accuracy to be used by driver +typedef tANI_S16 t2Decimal; +#define CONVERT_TO_2DECIMAL_PLACES(x) (x * 100) +#define CONVERT_FROM_2DECIMAL_PLACES(x) (x / 100) + +#ifndef PTT_FLOAT +#define PTT_FLOAT tANI_U32 // driver code can't include float, +//so this reserves space in our structures to allow floating point measurements +#endif + +typedef enum +{ + PHY_RX_CHAIN_0 = 0, + + PHY_MAX_RX_CHAINS = 1, + PHY_ALL_RX_CHAINS, + PHY_NO_RX_CHAINS +}ePhyRxChains; + +typedef enum +{ + PHY_I_RAIL = 0, + PHY_Q_RAIL = 1, + PHY_NUM_IQ_RAILS +}ePhyIQ; + +//[RY] extend total gain steps to 24 + +enum +{ + TX_GAIN_STEP_0, + TX_GAIN_STEP_1, + TX_GAIN_STEP_2, + TX_GAIN_STEP_3, + TX_GAIN_STEP_4, + TX_GAIN_STEP_5, + TX_GAIN_STEP_6, + TX_GAIN_STEP_7, + TX_GAIN_STEP_8, + TX_GAIN_STEP_9, + TX_GAIN_STEP_10, + TX_GAIN_STEP_11, + TX_GAIN_STEP_12, + TX_GAIN_STEP_13, + TX_GAIN_STEP_14, + TX_GAIN_STEP_15, + TX_GAIN_STEP_16, + TX_GAIN_STEP_17, + TX_GAIN_STEP_18, + TX_GAIN_STEP_19, + TX_GAIN_STEP_20, + TX_GAIN_STEP_21, + TX_GAIN_STEP_22, + TX_GAIN_STEP_23, + TX_GAIN_STEP_24, + TX_GAIN_STEP_25, + TX_GAIN_STEP_26, + TX_GAIN_STEP_27, + TX_GAIN_STEP_28, + TX_GAIN_STEP_29, + TX_GAIN_STEP_30, + TX_GAIN_STEP_31, + + RX_GAIN_STEP_0 = 0, + RX_GAIN_STEP_1, + RX_GAIN_STEP_2, + RX_GAIN_STEP_3, + RX_GAIN_STEP_4, + RX_GAIN_STEP_5, + RX_GAIN_STEP_6, + RX_GAIN_STEP_7, + RX_GAIN_STEP_8, + RX_GAIN_STEP_9, + RX_GAIN_STEP_10, + RX_GAIN_STEP_11, + RX_GAIN_STEP_12, + RX_GAIN_STEP_13, + RX_GAIN_STEP_14, + RX_GAIN_STEP_15, + + NUM_TX_GAIN_STEPS = 32, + MAX_TX_GAIN_STEP = TX_GAIN_STEP_31, + + NUM_RX_GAIN_STEPS = 16, + MAX_RX_GAIN_STEP = RX_GAIN_STEP_15, +}; +typedef tANI_U32 eGainSteps; + + +//[RY] new for PRIMA +#define DPD_RESPONSE_SIZE 128 +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 dpdCalFailCnt; //Count for number of times DPD cal failed. + tANI_U8 dpdCalSuccessCnt; //Count for number of times DPD cal passed. + tANI_U8 dpdColdBootRepeatCalStatus; + tANI_U8 dpdLastIteration; + tANI_S16 dpd_threshold[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_aoffset[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_again[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_poffset[DPD_RESPONSE_SIZE]; + tANI_S16 dpd_pgain[DPD_RESPONSE_SIZE]; + tANI_S32 dpd_sample[20]; + tANI_U8 dpd_try; + tANI_U8 band; +}sDPDcorrectionCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sDPDcorrectionCalValues dpd[PHY_MAX_TX_CHAINS]; +}sTxChainsDPDCalValues; + + +//[RY] RX IQ correction coefficients Memory +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 coeff_i[5]; + tANI_S9 coeff_q[5]; +}sIQCalValues; + +//[RY], added for RIVA +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 iq_ampimb_coeff; + tANI_S16 txloleakage_i; // raw data is 6-bit 2's compliment + tANI_S16 txloleakage_q; // raw data is 6-bit 2's compliment +}sTXIQCalValues; + +//[RY], added for RIVA +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 iqphaseimb_coeff_i[5]; + tANI_S9 iqphaseimb_coeff_q[5]; +}sTXIQPhaseImbCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sIQCalValues iq[PHY_MAX_RX_CHAINS]; +}sRxChainsIQCalValues; + +//[RY] change for PRIMA +typedef PACKED_PRE struct PACKED_POST { + sTXIQCalValues iq[PHY_MAX_TX_CHAINS]; + sTXIQPhaseImbCalValues iqImb[PHY_MAX_TX_CHAINS]; +}sTxChainsIQCalValues; + +typedef PACKED_PRE struct PACKED_POST { + tANI_S9 co_i[3]; + tANI_S9 co_q[3]; +}sHKIQCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sHKIQCalValues co[PHY_MAX_TX_CHAINS]; +}sTxChainsHKIQCalValues; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 lna_code; //wlan_lna_5g_control1,wl_5g_lna_load_ctune + tANI_U8 gm_code; //wlan_rxgm_5g_control4,wlgm_ctune +}sLnaBandCalValues; + +typedef PACKED_PRE struct PACKED_POST { + sLnaBandCalValues lnaCode[PHY_MAX_RX_CHAINS]; +}sTxChainsLnaBandCalValues; + +typedef tANI_U16 t_mW; //milliWatts +typedef tANI_U8 tPwrTemplateIndex; //5-bit number used as the index into the tx gain tables + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 txPowerAdc[PHY_MAX_TX_CHAINS]; +}sTxChainsPowerAdcReadings; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 agcGain; +}tRxGain; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 rx[PHY_MAX_RX_CHAINS]; +}sRxChainsData; + +typedef sRxChainsData sRxChainsRssi; +typedef sRxChainsData sRxChainsAgcDisable; + +typedef PACKED_PRE struct PACKED_POST { + tANI_BOOLEAN rx[PHY_MAX_RX_CHAINS]; +}sRxChainsBoolean; + +typedef sRxChainsBoolean sRxChainsAgcEnable; + +#define NUM_AGC_GAINS 64 +typedef tRxGain sAgcGainLut[NUM_AGC_GAINS]; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_S6 iLo; + tANI_S6 qLo; +}sTxFirLoCorrect; + +typedef tIQAdc sTxLoCorrectBB[PHY_MAX_TX_CHAINS][NUM_TX_GAIN_STEPS]; + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U32 txIqLoCache[PHY_MAX_TX_CHAINS][NUM_TX_GAIN_STEPS][4]; + tANI_U32 spatialRotation; +}tAsicTxFir; + +//Tx Power Config +//A collection of selected calibrated power points at selected frequencies. +//The algorithm does not need to know any particulars about which frequencies or cal points, +// just the linearized adjustments at the selected calibration points +#define MAX_TPC_CHANNELS (NUM_RF_CHANNELS) +#define START_TPC_CHANNEL (2412) +#define END_TPC_CHANNEL (2484) + +#define MAX_PWR_LUT_DBM (24) +#define MIN_PWR_LUT_DBM (8) + + +/* The reason that MAX_PWR_LUT_DBM_2DEC_PLACES is not simply (MAX_PWR_LUT_DBM * 100) is due to the fact + that we are interpolating the 5-bit power template index from this range compared to a LUT range of 0 to 127. + There is an expectation that this power range is evenly divided in 0.5dBm steps. + We expect that a commanded 13dBm would yield a power template index of 10, where a power template index of 0 would represent 8dBm. + If we used an even 2400 to represent the max power, then the calculation for 13dBm actually returns 9: + (127 - 0)*((1300 - 800)/(2400 - 800))+0 = 39.6875 = 39. When shifted to 5 bits, =9. Not what we wanted. + What we need to do is find the 2-decimal place power that corresponds as closely as possible to the 127 in the 0 to 127 range. + For the 800 to 2400 range, that comes out to 2386.5, so 2386. So again for a commanded power of 13dBm: + (127 - 0)*((1300 - 800)/(2386 - 800))+0 = 40.0378 = 40. When shifted to 5-bits, = 10, which is what we wanted. + +*/ + +#define MIN_PWR_LUT_DBM_2DEC_PLACES (MIN_PWR_LUT_DBM * 100) +#define MAX_PWR_LUT_DBM_2DEC_PLACES ((MAX_PWR_LUT_DBM * 100) - (1 + (100 * (MAX_PWR_LUT_DBM - MIN_PWR_LUT_DBM))/TPC_MEM_POWER_LUT_DEPTH)) + +//macro provides a quick conversion of dbm value between MIN_PWR_LUT_DBM and MAX_PWR_LUT_DBM to a power template index(0 to 31) +//based on convention, which may not hold true in the future. +#define CONVERT_DBM_GINDEX(dbm) (((dbm - MIN_PWR_LUT_DBM) * 32) / (MAX_PWR_LUT_DBM - MIN_PWR_LUT_DBM)) + +typedef tANI_U8 tTxGainCombo; //7-bit gain value used to get the power measurement + +typedef PACKED_PRE struct PACKED_POST +{ + tPowerDetect min; + tPowerDetect max; +}tPwrTemplateRange; + + + +/* + The following union affords backward compatibility with txGain usage with band-specific tTpcConfig tables. + Due to my finding that 7-bits is not enough precision, we need to reuse the txGain space as extra precision bits + for the adjustedPwrDet. My spreadsheet shows that we need at least 4 bits more precision. + To know which usage, the MSB of adjustedPwrDet can be set to signify the extra precision in place of the txGain, which isn't used anyway. + We just need to be careful not to interpret a pre-existing table's txGain as extra precision. +*/ + + typedef union + { + tTxGainCombo txGain; //7-bit gain used to measure the pwrDetAdc value + tANI_U8 hi8_adjustedPwrDet; //if the MSB is set in adjustedPwrDet, then these are extra bits of precision + }uExtraLutBits; + + +typedef PACKED_PRE struct PACKED_POST +{ + t2Decimal min; //sometimes used for comparing chain powers + t2Decimal max; //sometimes used for comparing chain powers +}tPowerdBmRange; //absolute power measurement precision maintained to two decimal places + + +typedef tANI_U16 tRfADCVal; +typedef tRfADCVal tTempADCVal; + +typedef PACKED_PRE struct PACKED_POST +{ + tRfADCVal pdadc_offset; + tANI_U8 reserved[2]; +}tTpcParams; + + +//these definitions used as indexing to power per channel per rate table stored in NV +#define CB_RATE_POWER_OFFSET 0 +#define CB_RATE_POWER_OFFSET_LAST_INDEX 60 //last index where we would apply the CB_RATE_POWER_OFFSET + +/* TX Power Calibration & Report Types */ + + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U8 temperatureAdc; //= 5 bit temperature measured at time sample was taken + tANI_U8 txGain; //= 7 bit gain value used to get the power measurement + tANI_U8 pwrDetAdc; //= 8 bit ADC power detect value + tANI_U8 reserved; + uAbsPwrPrecision absPowerMeasured; //= dBm measurement, will be truncated to two decimal places + }tTpcCalPoint; + + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U16 numTpcCalPoints; + tANI_U16 reserved; + tTpcCalPoint chain[MAX_TPC_CAL_POINTS]; + }tTpcChainData; + + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U16 freq; //frequency in MHz + tANI_U16 reserved; + tTpcChainData empirical[PHY_MAX_TX_CHAINS]; //TPC samples passed in + }tTpcFreqData; + + typedef PACKED_PRE struct PACKED_POST + { + tANI_U8 numChannels; + tANI_U8 reserved[3]; + tTpcFreqData calValues[MAX_TPC_CHANNELS]; + }sTpcFreqCalTable; + + +typedef PACKED_PRE struct PACKED_POST { + tPowerDetect lut; //7-bit value in the power Lookup Table + tANI_U8 reserved[3]; + + uAbsPwrPrecision abs; //LUT value conversion to absolute dBm +}tTxPowerLutOutput; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U8 gain; //8-bit coarse(bits 4-7) & fine(bits 0-3) gain commanded for the current index + tPowerDetect adc; //8-bit power ADC sampled during the packet preamble + tANI_U16 rawAdc; //11-bit power raw ADC sampled + + tTxPowerLutOutput indexMinMatch; //minimum LUT matching power that satisfies the power template index setting + tTxPowerLutOutput indexMaxMatch; //maximum LUT matching power that satisfies the power template index setting + tTxPowerLutOutput output; //output power values corresponding to power ADC index +}tTxChainPower; + +extern const tRfChannelProps rfChannels[NUM_RF_CHANNELS]; + +typedef enum +{ + RF_CAL_TONE_28NEG, + RF_CAL_TONE_24NEG, + RF_CAL_TONE_20NEG, + RF_CAL_TONE_16NEG, + RF_CAL_TONE_12NEG, + RF_CAL_TONE_8NEG, + RF_CAL_TONE_4NEG, + RF_CAL_TONE_4POS, + RF_CAL_TONE_8POS, + RF_CAL_TONE_12POS, + RF_CAL_TONE_16POS, + RF_CAL_TONE_20POS, + RF_CAL_TONE_24POS, + RF_CAL_TONE_28POS, + + NUM_RF_TONES, + + MIN_RF_TONE = RF_CAL_TONE_28NEG, + MAX_RF_TONE = RF_CAL_TONE_28POS +}eRfTones; + +typedef tANI_U8 tDcoCorrect; +typedef tANI_S8 tIm2Correct; + +typedef PACKED_PRE struct PACKED_POST { + tDcoCorrect IDcoCorrect; + tDcoCorrect QDcoCorrect; + tANI_U8 dcRange; +}tRxDcoCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tRxDcoCorrect dco[PHY_MAX_RX_CHAINS]; +}tRxChainsDcoCorrections; + +typedef PACKED_PRE struct PACKED_POST { + tIm2Correct ICorrect; + tIm2Correct QCorrect; +}tRxIm2Correct; + +typedef PACKED_PRE struct PACKED_POST { + tRxIm2Correct dco[PHY_MAX_RX_CHAINS]; +}tRxChainsIm2Corrections; + +typedef PACKED_PRE struct PACKED_POST { + tDcoCorrect IDcoCorrect; + tDcoCorrect QDcoCorrect; +}tTxLoCorrect; + +typedef PACKED_PRE struct PACKED_POST { + tTxLoCorrect txLo[PHY_MAX_TX_CHAINS]; +}sTxChainsLoCorrections; + + +//tDcoCorrect is needed to define rf specific structures + +#define NUM_RF_RX_GAIN_STEPS (128) +#define MAX_RF_RX_GAIN_STEP (NUM_RF_RX_GAIN_STEPS - 1) + +#define NUM_RF_TX_GAIN_STEPS (16) +#define MAX_RF_TX_GAIN_STEP (NUM_RF_TX_GAIN_STEPS - 1) + +#define RF_AGC_GAIN_LUT_DEPTH (128) +#define NUM_RF_DCO_VALUES (128) //There are only 32 DCO values, but our algorithm it makes more sense for us to access these by AGC gain index +#define MAX_RF_DCO_VALUE (NUM_RF_DCO_VALUES - 1) + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 gainReg1; //GEMINI_REG_RX_GC_0 (lna + mix + tia + bq1 + bq2 + pga) +}tRfRxGain; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U16 bbf_gain_cnt; + tANI_U16 bbf_lin_adj; + tANI_U16 lo_mix_da_gain_cntl; + tANI_U16 pa_gain_cntl; + tANI_U16 da_pa_bias_1_cnt; + tANI_U16 da_pa_bias_2_cntl; +}tRfTxGain; + +typedef PACKED_PRE struct PACKED_POST +{ + //TODO:define this struct for Gemini + tANI_U8 rxIf; + tANI_U8 txIf; + tANI_U8 txRf; + tANI_U8 reserved; +}sRfSpecificFilterSettings; + +typedef sRfSpecificFilterSettings sRfChannelFilterSettings[NUM_RF_CHANNELS]; + + +typedef PACKED_PRE struct PACKED_POST +{ + tANI_U8 hdet_ctl_ext_atten; + tANI_U8 hdet_dcoc_code; + tANI_U8 hdet_dcoc_ib_rcal_en; + tANI_U8 hdet_dcoc_ib_scal_en; +}sRfNvCalValues; //stored in QFUSE + + + +typedef enum +{ + SYNTH_UNLOCKED, + SYNTH_LOCK +}eRfSynthLock; + +typedef enum +{ + TEMP_SENSOR_PA, + TEMP_SENSOR_RX +}eRfTempSensor; + +typedef enum +{ + TEMPERATURE_BIN_0, //-30 to 5 C + TEMPERATURE_BIN_1, //5 to 45 C + TEMPERATURE_BIN_2, //45 to 85 C + TEMPERATURE_BIN_3, //85 to 125 C + NUM_TEMPERATURE_BINS +}eTemperatureBins; + +typedef PACKED_PRE struct PACKED_POST { + tANI_U16 hdetDcocCode; + tANI_U16 hdetDcoOffset; +}sRfHdetCalValues; + +#define TPC_TXPWR_ENABLE_MASK QWLAN_TPC_TXPWR_ENABLE_EN_MASK + + +#define TPC_MEM_TX0_PWR_LUT_OFFSET QWLAN_TPC_POWERDET0_RAM_MREG +#define TPC_MEM_TX1_PWR_LUT_OFFSET QWLAN_TPC_POWERDET1_RAM_MREG +#define TPC_MEM_TX2_PWR_LUT_OFFSET QWLAN_TPC_POWERDET2_RAM_MREG +#define TPC_MEM_TX3_PWR_LUT_OFFSET QWLAN_TPC_POWERDET3_RAM_MREG +#define TPC_MEM_TX0_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT0_MREG +#define TPC_MEM_TX1_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT1_MREG +#define TPC_MEM_TX2_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT2_MREG +#define TPC_MEM_TX3_GAIN_LUT_OFFSET QWLAN_TPC_GAIN_LUT3_MREG + +//these masks are the same for both chains +#define TPC_POWERDET_MASK QWLAN_TPC_POWERDET0_RAM_POWER_MASK +#define TPC_GAIN_RF_MASK QWLAN_TPC_GAIN_LUT0_RF_GAIN_MASK +#define TPC_GAIN_RF_OFFSET QWLAN_TPC_GAIN_LUT0_RF_GAIN_OFFSET +#define TPC_GAIN_DIG_MASK QWLAN_TPC_GAIN_LUT0_DIG_GAIN_MASK + + +#define TPC_MEM_GAIN_LUT_DEPTH 32 + + +#define TPC_ADC_CTRL_REG QWLAN_TPC_ADC_CTRL_GET_ADC_REG +#define TPC_ADC_GET_MASK QWLAN_TPC_ADC_CTRL_GET_ADC_GET_ADC_MASK + +#define TPC_ADC_FAILED_MASK QWLAN_TPC_ADC_STATUS_FAILED_MASK +#define TPC_ADC_BUSY_P_MASK QWLAN_TPC_ADC_STATUS_BUSY_P_MASK +#define TPC_ADC_BUSY_T_MASK QWLAN_TPC_ADC_STATUS_BUSY_T_MASK + + +#define MSK_1 0x1 +#define MSK_2 0x3 +#define MSK_3 0x7 +#define MSK_4 0xF +#define MSK_5 0x1F +#define MSK_6 0x3F +#define MSK_7 0x7F +#define MSK_8 0xFF +#define MSK_9 0x1FF +#define MSK_10 0x3FF +#define MSK_11 0x7FF +#define MSK_12 0xFFF +#define MSK_13 0x1FFF +#define MSK_14 0x3FFF +#define MSK_15 0x7FFF +#define MSK_16 0xFFFF +#define MSK_17 0x1FFFF +#define MSK_18 0x3FFFF +#define MSK_19 0x7FFFF +#define MSK_20 0xFFFFF +#define MSK_21 0x1FFFFF +#define MSK_22 0x3FFFFF +#define MSK_23 0x7FFFFF +#define MSK_24 0xFFFFFF +#define MSK_25 0x1FFFFFF +#define MSK_26 0x3FFFFFF +#define MSK_27 0x7FFFFFF +#define MSK_28 0xFFFFFFF +#define MSK_29 0x1FFFFFFF +#define MSK_30 0x3FFFFFFF +#define MSK_31 0x7FFFFFFF +#define MSK_32 0xFFFFFFFF + + +#define COARSE_GAIN_MASK MSK_4 +#define COARSE_GAIN_OFFSET 4 +#define FINE_GAIN_MASK MSK_4 //the upper most bit overlaps the coarse gain and should not be used for TPC LUT data +#define FINE_GAIN_OFFSET 0 + +typedef enum +{ + TPC_COARSE_TXPWR_0, + TPC_COARSE_TXPWR_1, + TPC_COARSE_TXPWR_2, + TPC_COARSE_TXPWR_3, + TPC_COARSE_TXPWR_4, + TPC_COARSE_TXPWR_5, + TPC_COARSE_TXPWR_6, + TPC_COARSE_TXPWR_7, + TPC_COARSE_TXPWR_8, + TPC_COARSE_TXPWR_9, + TPC_COARSE_TXPWR_10, + TPC_COARSE_TXPWR_11, + TPC_COARSE_TXPWR_12, + TPC_COARSE_TXPWR_13, + TPC_COARSE_TXPWR_14, + TPC_COARSE_TXPWR_15, + TPC_COARSE_TXPWR_16, + TPC_COARSE_TXPWR_17, + TPC_COARSE_TXPWR_18, + TPC_COARSE_TXPWR_19, + TPC_COARSE_TXPWR_20, + TPC_COARSE_TXPWR_21, + TPC_COARSE_TXPWR_22, + TPC_COARSE_TXPWR_23, + TPC_COARSE_TXPWR_24, + TPC_COARSE_TXPWR_25, + TPC_COARSE_TXPWR_26, + TPC_COARSE_TXPWR_27, + TPC_COARSE_TXPWR_28, + TPC_COARSE_TXPWR_29, + TPC_COARSE_TXPWR_30, + TPC_COARSE_TXPWR_31, + NUM_TPC_COARSE_STEPS = TPC_COARSE_TXPWR_31 - TPC_COARSE_TXPWR_0 + 1, + MIN_TPC_COARSE_TXPWR = TPC_COARSE_TXPWR_0, + MAX_TPC_COARSE_TXPWR = TPC_COARSE_TXPWR_31 +}eTxCoarseGain; //refers to the external RF power adjustment + +typedef enum +{ + TPC_FINE_TXPWR_0, + TPC_FINE_TXPWR_1, + TPC_FINE_TXPWR_2, + TPC_FINE_TXPWR_3, + TPC_FINE_TXPWR_4, + TPC_FINE_TXPWR_5, + TPC_FINE_TXPWR_6, + TPC_FINE_TXPWR_7, + TPC_FINE_TXPWR_8, + TPC_FINE_TXPWR_9, + TPC_FINE_TXPWR_10, + TPC_FINE_TXPWR_11, + TPC_FINE_TXPWR_12, + TPC_FINE_TXPWR_13, + TPC_FINE_TXPWR_14, + TPC_FINE_TXPWR_15, + MIN_TPC_FINE_TXPWR = TPC_FINE_TXPWR_0, + MAX_TPC_FINE_TXPWR = TPC_FINE_TXPWR_15 +}eTxFineGain; //refers to the internal TxFIR power adjustment + +typedef PACKED_PRE struct PACKED_POST { + eTxCoarseGain coarsePwr; + eTxFineGain finePwr; +}tTxGain; + +//for 30second periodic interrupt, do this every 5 minutes +#define HAL_PHY_PERIODIC_CAL_ITER_LIMIT 10 + +typedef enum +{ + //these show which rx and tx chains are enabled, other chains are disable accordingly + //Production modes + PHY_CHAIN_SEL_R0_T0_ON, + + PHY_CHAIN_SEL_BT_R0_T0_ON, //simultaneous bluetooth receive enabled + + + //test modes + PHY_CHAIN_SEL_R0_ON, + PHY_CHAIN_SEL_T0_ON, + PHY_CHAIN_SEL_NO_RX_TX, + + MAX_PHY_CHAIN_SEL, + INVALID_PHY_CHAIN_SEL, + PHY_CHAIN_SEL_ANT_0, //append for antenna 0 selection + PHY_CHAIN_SEL_ANT_1, //append for antenna 1 selection + + PHY_MAX_CHAIN_SELECT = 0x7FFFFFFF /* define as 4 bytes data */ +}ePhyChainSelect; + +typedef enum +{ +#ifdef CHANNEL_BONDED_CAPABLE + + PHY_CCA_40MHZ_SOURCE = 0, +#endif + + PHY_CCA_20MHZ_SOURCE = 1 +}ePhyCCASource; + +typedef enum +{ + PHY_CCA_FORCED_ON = 0, + PHY_CCA_ED = 1, + PHY_CCA_CD = 2, + PHY_CCA_CD_AND_CS = 3, + PHY_CCA_ED_AND_CD = 4, + PHY_CCA_ED_OR_CD = 5, + PHY_CCA_ED_AND_CD_AND_CS = 6, + PHY_CCA_ED_OR_CD_AND_CS = 7, + PHY_CCA_SEC_ED40_AND_NOR_PKTDET40_PKTDET20 = 8, + PHY_CCA_SEC_BUSY = 9 +}ePhyCCAMode; + +typedef enum +{ + PHY_RX_DISABLE_NONE = 0, + PHY_RX_DISABLE_11AG = 0x00000001, + PHY_RX_DISABLE_11B = 0x00000002, + PHY_RX_DISABLE_11N40 = 0x00000004, + PHY_RX_DISABLE_11AC80 = 0x00000008, + + PHY_RX_DISABLE_11ABG = (PHY_RX_DISABLE_11AG | PHY_RX_DISABLE_11B), + PHY_RX_DISABLE_ALL_TYPES = (PHY_RX_DISABLE_11B | PHY_RX_DISABLE_11AG | + PHY_RX_DISABLE_11N40 | PHY_RX_DISABLE_11AC80), +}ePhyRxDisabledPktTypes; + + +// Enum for network density setting. +typedef enum +{ + PHY_NW_DENSITY_LOW = 0, + PHY_NW_DENSITY_MED, + PHY_NW_DENSITY_HIGH, + PHY_NW_DENSITY_ADAPTIVE +} ePhyNwDensity; + + +typedef enum +{ + ALL_CALS, //RxDco 1st, TxLO 2nd + RX_DCO_CAL_ONLY, + RX_IM2_CAL_ONLY, + RX_DCO_IM2_CAL, + TX_LO_CAL_ONLY, + RX_IQ_CAL_ONLY, + TX_IQ_CAL_ONLY, + HKDAC_TX_IQ_CAL_ONLY, + NO_CALS = 0xFF +}eCalSelection; + + +//supports testing of closed-loop power control +typedef enum +{ + FORCE_CLOSED_LOOP_GAIN = 0, //phyDbg pkt gen only uses gain index 0 when we are taking measurements with the closed-loop gain + FORCE_POWER_TEMPLATE_INDEX = 1, //only use forced power template index + FIXED_POWER_DBM = 2, //only use to specify fixed power, ignoring rate/channel/reg limits + REGULATORY_POWER_LIMITS = 3, //use production power Lut settings limited by power limit table per channel + RATE_POWER_NON_LIMITED = 4, //use power specified per rate and channel group, but don't limit power by channel + POWER_INDX_SRC_MAX_VAL = 0x7FFFFFFF, //dummy val to set enum to 4 bytes +}ePowerTempIndexSource; + +#define BIT_0 0x00000001 +#define BIT_1 0x00000002 +#define BIT_2 0x00000004 +#define BIT_3 0x00000008 +#define BIT_4 0x00000010 +#define BIT_5 0x00000020 +#define BIT_6 0x00000040 +#define BIT_7 0x00000080 +#define BIT_8 0x00000100 +#define BIT_9 0x00000200 +#define BIT_10 0x00000400 +#define BIT_11 0x00000800 +#define BIT_12 0x00001000 +#define BIT_13 0x00002000 +#define BIT_14 0x00004000 +#define BIT_15 0x00008000 +#define BIT_16 0x00010000 +#define BIT_17 0x00020000 +#define BIT_18 0x00040000 +#define BIT_19 0x00080000 +#define BIT_20 0x00100000 +#define BIT_21 0x00200000 +#define BIT_22 0x00400000 +#define BIT_23 0x00800000 +#define BIT_24 0x01000000 +#define BIT_25 0x02000000 +#define BIT_26 0x04000000 +#define BIT_27 0x08000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + +#define WFM_CLK_80 BIT_3 +#define WFM_START BIT_0 +#define WFM_STOP BIT_1 + +#define WFM_MEM_I_DATA_MASK (0x7FF) +#define WFM_MEM_Q_DATA_OFFSET (0xB) +#define WFM_MEM_Q_DATA_MASK (0x3FF800) + +typedef enum +{ + WAVE_SINGLE_SHOT = 0, + WAVE_CONTINUOUS = BIT_2 +}eWaveMode; + +typedef enum +{ + RATE_240 = 0, + RATE_160 = 1, + RATE_120 = 2, + RATE_80 = 3, + RATE_40 = 4, + RATE_20 = 5, +}eWaveRate; + +#define MAX_TONE_AMPLITUDE (2^11) // peak to peak + +#define MAX_TEST_WAVEFORM_SAMPLES 500 + +#define NUM_RX_IMB_CAL_TONES 4 + +#define CAL_WFM_TX_TONE_8_START_IDX 0 +#define CAL_WFM_TX_TONE_8_STOP_IDX 255 +#define CAL_WFM_TX_TONE_MINUS_8_START_IDX 256 +#define CAL_WFM_TX_TONE_MINUS_8_STOP_IDX 511 +#define CAL_WFM_RX_TONE_START_IDX 512 +#define CAL_WFM_RX_TONE_STOP_IDX 767 + +#define B_RATE_CAL_ADJUSTMENT -150 +#define GN_RATE_BANDEDGE_ADJUSTMENT -100 + +#define TPC_INDEX_WIFI_DIRECT 0 +#define TPC_INDEX_LOW_POWER 1 +#define MIN_TPC_GAIN_INDEX 0 //Index 0 used for Wifi Direct +#define TPC_GAIN_LUT_PWR_SLOPE 2 +#define MAX_TPC_GAIN_LUT_DBM (22) +#define MIN_TPC_GAIN_LUT_DBM (6) + +#define MAX_TPC_GAIN_LUT_DBM_2DEC_PLACES (MAX_TPC_GAIN_LUT_DBM * 100) +#define MIN_TPC_GAIN_LUT_DBM_2DEC_PLACES (MIN_TPC_GAIN_LUT_DBM * 100) + +typedef enum +{ + RF_BANDWIDTH_20MHZ = 20, + RF_BANDWIDTH_40MHZ = 40, + RF_BANDWIDTH_80MHZ = 80, + RF_MIN_BANDWIDTH = RF_BANDWIDTH_20MHZ, + RF_MAX_BANDWIDTH = RF_BANDWIDTH_80MHZ, + RF_BANDWIDTH_INVALID = 0x7FFFFFFF +}eRfBandwidth; + +#endif /* WLAN_PHY_H */ diff --git a/drivers/staging/prima/riva/inc/wlan_qct_dev_defs.h b/drivers/staging/prima/riva/inc/wlan_qct_dev_defs.h new file mode 100644 index 000000000000..1f2e55304dad --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_qct_dev_defs.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * + * @file: wlan_qct_dev_defs.h + * + * @brief: This file contains the hardware related definitions. + * + */ + +#ifndef __WLAN_QCT_DEV_DEFS_H +#define __WLAN_QCT_DEV_DEFS_H + + +/* -------------------------------------------------------------------- + * HW definitions for WLAN Chip + * -------------------------------------------------------------------- + */ + +#ifdef WCN_PRONTO + +#ifdef WLAN_SOFTAP_VSTA_FEATURE +//supports both V1 and V2 +#define HAL_NUM_ASSOC_STA 32 // HAL_NUM_STA - No of GP STAs - 2 (1 self Sta + 1 Bcast Sta) +#define HAL_NUM_STA 41 +#define HAL_NUM_HW_STA 16 + +#define HAL_NUM_GPSTA 4 +#define HAL_NUM_UMA_DESC_ENTRIES HAL_NUM_HW_STA // or HAL_NUM_STA + +#define HAL_NUM_BSSID 2 +#define HAL_NUM_STA_WITHOUT_VSTA 12 +#define HAL_NUM_STA_INCLUDING_VSTA 32 + +#define HAL_NUM_VSTA (HAL_NUM_STA - HAL_NUM_HW_STA) +#define QWLANFW_MAX_NUM_VSTA (HAL_NUM_VSTA) +#define QWLANFW_VSTA_INVALID_IDX (HAL_NUM_STA+1) +#define QWLAN_VSTA_MIN_IDX (HAL_NUM_HW_STA) +#define QWLANFW_NUM_GPSTA (HAL_NUM_GPSTA) + +// For Pronto +#define HAL_NUM_STA_WITHOUT_VSTA_PRONTO_V1 9 +#define HAL_NUM_STA_WITHOUT_VSTA_PRONTO_V2 (HAL_NUM_STA_WITHOUT_VSTA) + +#define IS_VSTA_VALID_IDX(__x) \ + ((__x) != QWLANFW_VSTA_INVALID_IDX) + +#define IS_VSTA_IDX(__x) \ + (((__x) >= QWLAN_VSTA_MIN_IDX) && ((__x) < HAL_NUM_STA)) + +#define GET_VSTA_INDEX_FOR_STA_INDEX(__idx) ((__idx) - QWLAN_VSTA_MIN_IDX) + +// is the STA a General Purpose STA? +#define IS_GPSTA_IDX(__x) \ + (((__x) >= (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) && \ + ((__x) < HAL_NUM_HW_STA)) + +// is the STA a HW STA (excluding GP STAs) +#define IS_HWSTA_IDX(__x) \ + ((__x) < (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) + +#define HAL_NUM_STA_INCLUDING_VSTA 32 + +#elif WCN_PRONTO_V1 + +/* In Pronto 1.0 TPE descriptor size is increased to 1K per station + * but not the cMEM allocated for hardware descriptors. Due to this + * memory limitation the number of stations are limited to 9 and BSS + * to 2 respectively. + * + * In Pronto 2.0, TPE descriptor size is reverted + * back to 512 bytes and hence more stations and BSSs can be supported + * from Pronto 2.0 + * + * In Pronto 1.0, 9 HW stations are supported including BCAST STA(staId 0) + * and SELF STA(staId 1). So total ASSOC stations which can connect to + * Pronto 1.0 Softap = 9 - 1(self sta) - 1(Bcast sta) = 7 stations + */ +#define HAL_NUM_HW_STA 9 +#define HAL_NUM_STA (HAL_NUM_HW_STA) +#define HAL_NUM_BSSID 2 +#define HAL_NUM_UMA_DESC_ENTRIES 9 +#define HAL_NUM_ASSOC_STA 7 + + +#else /* WCN_PRONTO_V1 */ + +#define HAL_NUM_HW_STA 14 +#define HAL_NUM_STA (HAL_NUM_HW_STA) +#define HAL_NUM_BSSID 4 +#define HAL_NUM_UMA_DESC_ENTRIES 14 +#define HAL_NUM_ASSOC_STA 12 + + +#endif /* WCN_PRONTO_V1 and WLAN_SOFTAP_VSTA_FEATURE*/ +#else /* WCN_PRONTO */ + +/* + * Riva supports 16 stations in hardware + * + * Riva without Virtual STA feature can only support 12 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 10 Soft AP Stations (hard) + * + * Riva with Virtual STA feature supports 38 stations: + * 1 Broadcast STA (hard) + * 1 "Self" STA (hard) + * 4 General Purpose Stations to support Virtual STAs (hard) + * 32 Soft AP Stations (10 hard/22 virtual) + * + * To support concurrency with Vsta, number of stations are increased to 41 (from 38). + * 1 for the second interface. + * 1 for reserving an infra peer STA index (hard) for the other interface. + * 1 for P2P device role. + */ +#ifdef WLAN_SOFTAP_VSTA_FEATURE +#define HAL_NUM_ASSOC_STA 32 +#define HAL_NUM_STA 41 +#define HAL_NUM_HW_STA 16 +#define HAL_NUM_GPSTA 4 +#define HAL_NUM_VSTA (HAL_NUM_STA - HAL_NUM_HW_STA) + +#define QWLANFW_MAX_NUM_VSTA HAL_NUM_VSTA +#define QWLANFW_VSTA_INVALID_IDX (HAL_NUM_STA+1) +#define QWLAN_VSTA_MIN_IDX HAL_NUM_HW_STA +#define QWLANFW_NUM_GPSTA HAL_NUM_GPSTA + + +#define IS_VSTA_VALID_IDX(__x) \ + ((__x) != QWLANFW_VSTA_INVALID_IDX) + +#define IS_VSTA_IDX(__x) \ + (((__x) >= QWLAN_VSTA_MIN_IDX) && ((__x) < HAL_NUM_STA)) + +#define GET_VSTA_INDEX_FOR_STA_INDEX(__idx) ((__idx) - QWLAN_VSTA_MIN_IDX) + +// is the STA a General Purpose STA? +#define IS_GPSTA_IDX(__x) \ + (((__x) >= (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) && \ + ((__x) < HAL_NUM_HW_STA)) + +// is the STA a HW STA (excluding GP STAs) +#define IS_HWSTA_IDX(__x) \ + ((__x) < (HAL_NUM_HW_STA-HAL_NUM_GPSTA)) + +#define HAL_NUM_STA_INCLUDING_VSTA 32 +#define HAL_NUM_STA_WITHOUT_VSTA 12 + +#else +#define HAL_NUM_STA 12 +#define HAL_NUM_ASSOC_STA 10 +#define HAL_NUM_HW_STA 12 +#endif + +#define HAL_NUM_BSSID 2 +#define HAL_NUM_UMA_DESC_ENTRIES HAL_NUM_HW_STA + +#endif /* WCN_PRONTO */ + +#ifdef FEATURE_WLAN_TDLS +#define CXM_TDLS_MAX_NUM_STA 32 +#endif + +#define HAL_INVALID_BSSIDX HAL_NUM_BSSID + +#define MAX_NUM_OF_BACKOFFS 8 +#define HAL_MAX_ASSOC_ID HAL_NUM_STA + +#define WLANHAL_TX_BD_HEADER_SIZE 40 //FIXME_PRIMA - Revisit +#define WLANHAL_RX_BD_HEADER_SIZE 76 + +/* + * From NOVA Mac Arch document + * Encryp. mode The encryption mode + * 000: Encryption functionality is not enabled + * 001: Encryption is set to WEP + * 010: Encryption is set to WEP 104 + * 011: Encryption is set to TKIP + * 100: Encryption is set to AES + * 101 - 111: Reserved for future + */ + +#define HAL_ENC_POLICY_NULL 0 +#define HAL_ENC_POLICY_WEP40 1 +#define HAL_ENC_POLICY_WEP104 2 +#define HAL_ENC_POLICY_TKIP 3 +#define HAL_ENC_POLICY_AES_CCM 4 + +/* --------------------------------------------------------------------- */ +/* BMU */ +/* --------------------------------------------------------------------- */ + +/* + * BMU WQ assignment, as per Prima Programmer's Guide - FIXME_PRIMA: Revisit + * + */ + +typedef enum sBmuWqId { + + /* ====== In use WQs ====== */ + + /* BMU */ + BMUWQ_BMU_IDLE_BD = 0, + BMUWQ_BMU_IDLE_PDU = 1, + + /* RxP */ + BMUWQ_RXP_UNKNWON_ADDR = 2, /* currently unhandled by HAL */ + + /* DPU RX */ + BMUWQ_DPU_RX = 3, + + /* DPU TX */ + BMUWQ_DPU_TX = 6, + + /* Firmware */ + BMUWQ_FW_TRANSMIT = 12, /* DPU Tx->FW Tx */ + BMUWQ_FW_RECV = 7, /* DPU Rx->FW Rx */ + + BMUWQ_FW_RPE_RECV = 16, /* RXP/RPE Rx->FW Rx */ + FW_SCO_WQ = BMUWQ_FW_RPE_RECV, + + /* DPU Error */ + BMUWQ_DPU_ERROR_WQ = 8, + + /* DXE RX */ + BMUWQ_DXE_RX = 11, + + BMUWQ_DXE_RX_HI = 4, + + /* ADU/UMA */ + BMUWQ_ADU_UMA_TX = 23, + BMUWQ_ADU_UMA_RX = 24, + + /* BMU BTQM */ + BMUWQ_BTQM = 25, + + /* Special WQ for BMU to dropping all frames coming to this WQ ID */ + BMUWQ_SINK = 255, + +#ifdef WCN_PRONTO + BMUWQ_BMU_CMEM_IDLE_BD = 27, + /* Total BMU WQ count in Pronto */ + BMUWQ_NUM = 28, + + //WQs 17 through 22 are enabled in Pronto. So, set not supported mask to 0. + BMUWQ_NOT_SUPPORTED_MASK = 0x0, +#else + /* Total BMU WQ count in Prima */ + BMUWQ_NUM = 27, + + //Prima has excluded support for WQs 17 through 22. + BMUWQ_NOT_SUPPORTED_MASK = 0x7e0000, +#endif //WCN_PRONTO + + + /* Aliases */ + BMUWQ_BTQM_TX_MGMT = BMUWQ_BTQM, + BMUWQ_BTQM_TX_DATA = BMUWQ_BTQM, + BMUWQ_BMU_WQ2 = BMUWQ_RXP_UNKNWON_ADDR, + BMUWQ_FW_DPU_TX = 5, + + //WQ where all the frames with addr1/addr2/addr3 with value 254/255 go to. + BMUWQ_FW_RECV_EXCEPTION = 14, //using BMUWQ_FW_MESSAGE WQ for this purpose. + + //WQ where all frames with unknown Addr2 filter exception cases frames will pushed if FW wants host to + //send deauth to the sender. + BMUWQ_HOST_RX_UNKNOWN_ADDR2_FRAMES = 15, //using BMUWQ_FW_DXECH2_0 for this purpose. + + /* ====== Unused/Reserved WQ ====== */ + + /* ADU/UMA Error WQ */ + BMUWQ_ADU_UMA_TX_ERROR_WQ = 13, /* Not in use by HAL */ + BMUWQ_ADU_UMA_RX_ERROR_WQ = 10, /* Not in use by HAL */ + + /* DPU Error WQ2 */ + BMUWQ_DPU_ERROR_WQ2 = 9, /* Not in use by HAL */ + + /* FW WQs */ + //This WQ is being used for RXP to push in frames in exception cases ( addr1/add2/addr3 254/255) + //BMUWQ_FW_MESG = 14, /* DxE Tx->FW, Not in use by FW */ + //BMUWQ_FW_DXECH2_0 = 15, /* BD/PDU<->MEM conversion using DxE CH2. Not in use by FW */ + BMUWQ_FW_DXECH2_1 = 16, /* BD/PDU<->MEM conversion using DxE CH2. Not in use by FW */ + + /* NDPA Addr3 workaround */ + BMUWQ_RXP_DEFAULT_PUSH_WQ = 17, +/* These WQs are not supported in Volans + BMUWQ_BMU_WQ17 = 17, + BMUWQ_BMU_WQ18 = 18, + BMUWQ_BMU_WQ19 = 19, + BMUWQ_BMU_WQ20 = 20, + BMUWQ_BMU_WQ21 = 21, + BMUWQ_BMU_WQ22 = 22 +*/ +} tBmuWqId; + +typedef enum +{ + BTQM_QID0 = 0, + BTQM_QID1, + BTQM_QID2, + BTQM_QID3, + BTQM_QID4, + BTQM_QID5, + BTQM_QID6, + BTQM_QID7, + BTQM_QID8, + BTQM_QID9, + BTQM_QID10, + + BTQM_QUEUE_TX_TID_0 = BTQM_QID0, + BTQM_QUEUE_TX_TID_1, + BTQM_QUEUE_TX_TID_2, + BTQM_QUEUE_TX_TID_3, + BTQM_QUEUE_TX_TID_4, + BTQM_QUEUE_TX_TID_5, + BTQM_QUEUE_TX_TID_6, + BTQM_QUEUE_TX_TID_7, + + + /* Queue Id <-> BO + */ + BTQM_QUEUE_TX_nQOS = BTQM_QID8, + BTQM_QUEUE_SELF_STA_BCAST_MGMT = BTQM_QID10, + BTQM_QUEUE_SELF_STA_UCAST_MGMT = BTQM_QID9, + BTQM_QUEUE_SELF_STA_UCAST_DATA = BTQM_QID9, + BTQM_QUEUE_NULL_FRAME = BTQM_QID9, + BTQM_QUEUE_SELF_STA_PROBE_RSP = BTQM_QID9, + BTQM_QUEUE_TX_AC_BE = BTQM_QUEUE_TX_TID_0, + BTQM_QUEUE_TX_AC_BK = BTQM_QUEUE_TX_TID_2, + BTQM_QUEUE_TX_AC_VI = BTQM_QUEUE_TX_TID_4, + BTQM_QUEUE_TX_AC_VO = BTQM_QUEUE_TX_TID_6 +}tBtqmQId; + +#define STACFG_MAX_TC 8 + +/* --------------------------------------------------------------------- */ +/* BD type*/ +/* --------------------------------------------------------------------- */ +#define HWBD_TYPE_GENERIC 0 /* generic BD format */ +#define HWBD_TYPE_FRAG 1 /* fragmentation BD format*/ + +/*---------------------------------------------------------------------- */ +/* HW Tx power */ +/*---------------------------------------------------------------------- */ +#ifdef WLAN_HAL_PRIMA + #define WLAN_SOC_PRIMA_MAX_TX_POWER 22 + #define WLAN_SOC_PRIMA_MIN_TX_POWER 6 +#else + /* add more platforms here */ + #define WLAN_SOC_PRIMA_MAX_TX_POWER 22 + #define WLAN_SOC_PRIMA_MIN_TX_POWER 6 +#endif //#ifdef WCN_PRIMA + +#endif /* __WLAN_QCT_DEV_DEFS_H */ diff --git a/drivers/staging/prima/riva/inc/wlan_status_code.h b/drivers/staging/prima/riva/inc/wlan_status_code.h new file mode 100644 index 000000000000..9b452253e2e0 --- /dev/null +++ b/drivers/staging/prima/riva/inc/wlan_status_code.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2012 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/*=========================================================================== + * + * @file: wlan_status_code.h + * + * @brief: Common header file containing all the status codes + * All status codes have been consolidated into one enum + * + * @author: Kumar Anand + * + *=========================================================================*/ + +#ifndef __WLAN_STATUS_CODE_H__ +#define __WLAN_STATUS_CODE_H__ + +/*------------------------------------------------------------------------- + Include Files +-------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + * Preprocessor Definitions and Constants + * -------------------------------------------------------------------------*/ + +/* This is to force compiler to use the maximum of an int ( 4 bytes ) */ +#define WLAN_STATUS_MAX_ENUM_SIZE 0x7FFFFFFF + +/*---------------------------------------------------------------------------- + * Type Declarations + * -------------------------------------------------------------------------*/ + +typedef enum +{ + /* PAL Request succeeded!*/ + PAL_STATUS_SUCCESS = 0, + + /* HAL Request succeeded!*/ + eHAL_STATUS_SUCCESS = 0, + + /* Request failed because there of an invalid request. This is + typically the result of invalid parameters on the request*/ + PAL_STATUS_INVAL, + + /* Request refused because a request is already in place and + another cannot be handled currently */ + PAL_STATUS_ALREADY, + + /* Request failed because of an empty condition */ + PAL_STATUS_EMPTY, + + /* Request failed for some unknown reason. */ + PAL_STATUS_FAILURE, + + /* HAL general failure */ + eHAL_STATUS_FAILURE, + + /* Invalid Param*/ + eHAL_STATUS_INVALID_PARAMETER, + + /* Invalid Station Index*/ + eHAL_STATUS_INVALID_STAIDX, + + /* DPU descriptor table full*/ + eHAL_STATUS_DPU_DESCRIPTOR_TABLE_FULL, + + /* No interrupts */ + eHAL_STATUS_NO_INTERRUPTS, + + /* Interrupt present */ + eHAL_STATUS_INTERRUPT_PRESENT, + + /* Stable Table is full */ + eHAL_STATUS_STA_TABLE_FULL, + + /* Duplicate Station found */ + eHAL_STATUS_DUPLICATE_STA, + + /* BSSID is invalid */ + eHAL_STATUS_BSSID_INVALID, + + /* STA is invalid */ + eHAL_STATUS_STA_INVALID, + + /* BSSID is is duplicate */ + eHAL_STATUS_DUPLICATE_BSSID, + + /* BSS Idx is invalid */ + eHAL_STATUS_INVALID_BSSIDX, + + /* BSSID Table is full */ + eHAL_STATUS_BSSID_TABLE_FULL, + + /* Invalid DPU signature*/ + eHAL_STATUS_INVALID_SIGNATURE, + + /* Invalid key Id */ + eHAL_STATUS_INVALID_KEYID, + + /* Already on requested channel */ + eHAL_STATUS_SET_CHAN_ALREADY_ON_REQUESTED_CHAN, + + /* UMA descriptor table is full */ + eHAL_STATUS_UMA_DESCRIPTOR_TABLE_FULL, + + /* MIC Key table is full */ + eHAL_STATUS_DPU_MICKEY_TABLE_FULL, + + /* A-MPDU/BA related Error codes */ + eHAL_STATUS_BA_RX_BUFFERS_FULL, + eHAL_STATUS_BA_RX_MAX_SESSIONS_REACHED, + eHAL_STATUS_BA_RX_INVALID_SESSION_ID, + + eHAL_STATUS_TIMER_START_FAILED, + eHAL_STATUS_TIMER_STOP_FAILED, + eHAL_STATUS_FAILED_ALLOC, + + /* Scan failure codes */ + eHAL_STATUS_NOTIFY_BSS_FAIL, + + /* Self STA not deleted as reference count is not zero */ + eHAL_STATUS_DEL_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO, + + /* Self STA not added as entry already exists*/ + eHAL_STATUS_ADD_STA_SELF_IGNORED_REF_COUNT_NOT_ZERO, + + /* Message from SLM has failure status */ + eHAL_STATUS_FW_SEND_MSG_FAILED, + + /* BSS disconnect status : beacon miss */ + eHAL_STATUS_BSS_DISCONN_BEACON_MISS, + /* BSS disconnect status : deauth */ + eHAL_STATUS_BSS_DISCONN_DEAUTH, + /* BSS disconnect status : disassoc */ + eHAL_STATUS_BSS_DISCONN_DISASSOC, + + /* Data abort happened in PHY sw */ + eHAL_STATUS_PHY_DATA_ABORT, + + /* Invalid NV field */ + eHAL_STATUS_PHY_INVALID_NV_FIELD, + + /* WLAN boot test failed */ + eHAL_STATUS_WLAN_BOOT_TEST_FAILURE, + + /* Max status value */ + eHAL_STATUS_MAX_VALUE = WLAN_STATUS_MAX_ENUM_SIZE + +} palStatus, eHalStatus; + +/* Helper Macros */ +#define PAL_IS_STATUS_SUCCESS(status) (PAL_STATUS_SUCCESS == (status)) +#define HAL_STATUS_SUCCESS( status ) (eHAL_STATUS_SUCCESS == (status)) + +#endif //__WLAN_STATUS_CODE_H__ From 68357dfbccbd41008709358e289e2e8bd611d9da Mon Sep 17 00:00:00 2001 From: Vitaliy Tomin Date: Sat, 30 Sep 2017 22:50:48 +0800 Subject: [PATCH 80/86] msm: camera: Reset to LA.UM.5.6.r1-05700-89xx.0 Change-Id: I2ffa569198c35c5dbab762c6306d6161c23fc695 --- drivers/media/platform/msm/camera_v2/Kconfig | 59 +- .../msm/camera_v2/common/cam_soc_api.c | 7 +- .../platform/msm/camera_v2/fd/msm_fd_dev.c | 23 +- .../platform/msm/camera_v2/fd/msm_fd_dev.h | 3 +- .../media/platform/msm/camera_v2/isp/Makefile | 9 +- .../platform/msm/camera_v2/isp/msm_buf_mgr.c | 15 +- .../msm/camera_v2/isp/msm_buf_mgr_32.c | 1264 ---------- .../msm/camera_v2/isp/msm_buf_mgr_32.h | 203 -- .../platform/msm/camera_v2/isp/msm_isp.h | 11 +- .../platform/msm/camera_v2/isp/msm_isp32.c | 490 ++-- .../platform/msm/camera_v2/isp/msm_isp40.c | 38 +- .../platform/msm/camera_v2/isp/msm_isp44.c | 27 +- .../platform/msm/camera_v2/isp/msm_isp46.c | 27 +- .../platform/msm/camera_v2/isp/msm_isp47.c | 31 +- .../platform/msm/camera_v2/isp/msm_isp47.h | 3 - .../platform/msm/camera_v2/isp/msm_isp48.c | 4 - .../platform/msm/camera_v2/isp/msm_isp_32.c | 594 ----- .../platform/msm/camera_v2/isp/msm_isp_32.h | 599 ----- .../msm/camera_v2/isp/msm_isp_axi_util.c | 202 +- .../msm/camera_v2/isp/msm_isp_axi_util.h | 1 - .../msm/camera_v2/isp/msm_isp_axi_util_32.c | 2083 ----------------- .../msm/camera_v2/isp/msm_isp_axi_util_32.h | 69 - .../msm/camera_v2/isp/msm_isp_stats_util.c | 5 +- .../msm/camera_v2/isp/msm_isp_stats_util_32.c | 708 ------ .../msm/camera_v2/isp/msm_isp_stats_util_32.h | 27 - .../platform/msm/camera_v2/isp/msm_isp_util.c | 344 +-- .../platform/msm/camera_v2/isp/msm_isp_util.h | 23 - .../msm/camera_v2/isp/msm_isp_util_32.c | 1919 --------------- .../msm/camera_v2/isp/msm_isp_util_32.h | 81 - .../platform/msm/camera_v2/ispif/Makefile | 6 +- .../platform/msm/camera_v2/ispif/msm_ispif.c | 377 +-- .../platform/msm/camera_v2/ispif/msm_ispif.h | 3 +- .../msm/camera_v2/ispif/msm_ispif_32.c | 1578 ------------- .../msm/camera_v2/ispif/msm_ispif_32.h | 69 - .../msm/camera_v2/ispif/msm_ispif_hwreg_v1.h | 6 - .../msm/camera_v2/ispif/msm_ispif_hwreg_v2.h | 8 - .../msm/camera_v2/ispif/msm_ispif_hwreg_v3.h | 7 - .../msm/camera_v2/jpeg_10/msm_jpeg_hw.c | 35 +- .../msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c | 126 +- .../msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h | 6 +- .../msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c | 85 +- drivers/media/platform/msm/camera_v2/msm.c | 23 - drivers/media/platform/msm/camera_v2/msm.h | 6 +- .../msm_buf_mgr/msm_generic_buf_mgr.c | 11 +- .../platform/msm/camera_v2/msm_vb2/msm_vb2.c | 3 + .../msm/camera_v2/pproc/cpp/msm_cpp.c | 148 +- .../msm/camera_v2/pproc/vpe/msm_vpe.c | 19 +- .../msm/camera_v2/pproc/vpe/msm_vpe.h | 3 +- .../camera_v2/sensor/actuator/msm_actuator.c | 9 +- .../msm/camera_v2/sensor/cci/msm_cci.c | 10 +- .../msm/camera_v2/sensor/csid/msm_csid.c | 2 +- .../msm/camera_v2/sensor/csiphy/msm_csiphy.c | 18 +- .../msm/camera_v2/sensor/csiphy/msm_csiphy.h | 1 - .../msm/camera_v2/sensor/flash/msm_flash.c | 55 +- .../msm/camera_v2/sensor/flash/msm_flash.h | 5 +- .../platform/msm/camera_v2/sensor/io/Makefile | 3 +- .../camera_v2/sensor/io/msm_camera_cci_i2c.c | 10 +- .../camera_v2/sensor/io/msm_camera_dt_util.c | 7 +- .../msm/camera_v2/sensor/io/msm_camera_i2c.h | 56 - .../camera_v2/sensor/io/msm_camera_qup_i2c.c | 40 +- .../camera_v2/sensor/io/msm_camera_tz_i2c.c | 1093 --------- .../msm/camera_v2/sensor/ir_cut/msm_ir_cut.c | 3 + .../msm/camera_v2/sensor/ir_led/msm_ir_led.c | 126 +- .../msm/camera_v2/sensor/ir_led/msm_ir_led.h | 7 +- .../msm/camera_v2/sensor/msm_sensor.c | 46 - .../msm/camera_v2/sensor/msm_sensor.h | 4 +- .../msm/camera_v2/sensor/msm_sensor_driver.c | 80 +- .../msm/camera_v2/sensor/ois/msm_ois.c | 11 +- include/media/msm_cam_sensor.h | 1 - include/media/msmb_isp.h | 17 +- include/uapi/media/msm_cam_sensor.h | 2 +- include/uapi/media/msm_camsensor_sdk.h | 3 - include/uapi/media/msm_jpeg_dma.h | 8 +- include/uapi/media/msmb_isp.h | 91 +- 74 files changed, 762 insertions(+), 12334 deletions(-) delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.c delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.h delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_32.c delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_32.h delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.h mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.c delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.h delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c delete mode 100644 drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.h mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c delete mode 100644 drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.c delete mode 100644 drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.h mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c delete mode 100644 drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c diff --git a/drivers/media/platform/msm/camera_v2/Kconfig b/drivers/media/platform/msm/camera_v2/Kconfig index 673d60cb5a6f..f084d07eb6ca 100644 --- a/drivers/media/platform/msm/camera_v2/Kconfig +++ b/drivers/media/platform/msm/camera_v2/Kconfig @@ -1,5 +1,5 @@ config MSM_CAMERA_SENSOR - bool "QTI MSM camera sensor support" + bool "Qualcomm MSM camera sensor support" depends on MSMB_CAMERA select NEW_LEDS select LEDS_CLASS @@ -10,7 +10,7 @@ config MSM_CAMERA_SENSOR subdev APIs. config MSM_CPP - bool "QTI MSM Camera Post Processing Engine support" + bool "Qualcomm MSM Camera Post Processing Engine support" depends on MSMB_CAMERA ---help--- Enable support for Camera Post-processing Engine @@ -19,7 +19,7 @@ config MSM_CPP APIs. config MSM_CCI - bool "QTI MSM Camera Control Interface support" + bool "Qualcomm MSM Camera Control Interface support" depends on MSMB_CAMERA ---help--- Enable support for Camera Control Interface driver only @@ -29,7 +29,7 @@ config MSM_CCI GPIO and data frames. config MSM_CSI20_HEADER - bool "QTI MSM CSI 2.0 Header" + bool "Qualcomm MSM CSI 2.0 Header" depends on MSMB_CAMERA ---help--- Enable support for CSI drivers to include 2.0 @@ -39,7 +39,7 @@ config MSM_CSI20_HEADER 8930 and 8064 platforms. config MSM_CSI22_HEADER - bool "QTI MSM CSI 2.2 Header" + bool "Qualcomm MSM CSI 2.2 Header" depends on MSMB_CAMERA ---help--- Enable support for CSI drivers to include 2.2 @@ -49,7 +49,7 @@ config MSM_CSI22_HEADER platform. config MSM_CSI30_HEADER - bool "QTI MSM CSI 3.0 Header" + bool "Qualcomm MSM CSI 3.0 Header" depends on MSMB_CAMERA ---help--- Enable support for CSI drivers to include 3.0 @@ -59,7 +59,7 @@ config MSM_CSI30_HEADER 8064 platforms. config MSM_CSI31_HEADER - bool "QTI MSM CSI 3.1 Header" + bool "Qualcomm MSM CSI 3.1 Header" depends on MSMB_CAMERA ---help--- Enable support for CSI drivers to include 3.0 @@ -69,7 +69,7 @@ config MSM_CSI31_HEADER APQ8084 platform. config MSM_CSIPHY - bool "QTI MSM Camera Serial Interface Physical receiver support" + bool "Qualcomm MSM Camera Serial Interface Physical receiver support" depends on MSMB_CAMERA ---help--- Enable support for Camera Serial Interface @@ -78,7 +78,7 @@ config MSM_CSIPHY signalling. config MSM_CSID - bool "QTI MSM Camera Serial Interface decoder support" + bool "Qualcomm MSM Camera Serial Interface decoder support" depends on MSMB_CAMERA ---help--- Enable support for Camera Serial Interface decoder. @@ -87,7 +87,7 @@ config MSM_CSID and datatype. config MSM_EEPROM - bool "QTI MSM Camera ROM Interface for Calibration support" + bool "Qualcomm MSM Camera ROM Interface for Calibration support" depends on MSMB_CAMERA ---help--- Enable support for ROM Interface for Calibration @@ -95,17 +95,8 @@ config MSM_EEPROM and also provides support for writing data in case of FLASH ROM. Currently supports I2C, CCI and SPI protocol -config MSM_ISP_V1 - bool "QTI MSM Image Signal Processing interface support" - depends on MSMB_CAMERA - ---help--- - Enable support for Image Signal Processing interface module. - This module acts as a crossbar between CSID and VFE. Output - of any CID of CSID can be routed to of of pixel or raw - data interface in VFE. - config MSM_ISPIF - bool "QTI MSM Image Signal Processing interface support" + bool "Qualcomm MSM Image Signal Processing interface support" depends on MSMB_CAMERA ---help--- Enable support for Image Signal Processing interface module. @@ -114,7 +105,7 @@ config MSM_ISPIF data interface in VFE. config MSM_ISPIF_V1 - bool "QTI MSM Image Signal Processing interface support" + bool "Qualcomm MSM Image Signal Processing interface support" depends on MSMB_CAMERA ---help--- Enable support for Image Signal Processing interface module. @@ -123,7 +114,7 @@ config MSM_ISPIF_V1 or raw data interface in VFE. config MSM_ISPIF_V2 - bool "QTI MSM Image Signal Processing interface support" + bool "Qualcomm MSM Image Signal Processing interface support" depends on MSMB_CAMERA ---help--- Enable support for Image Signal Processing interface module. @@ -213,7 +204,7 @@ config OV12830 2 lanes max fps is 18, 4 lanes max fps is 24. config MSM_V4L2_VIDEO_OVERLAY_DEVICE - tristate "QTI MSM V4l2 video overlay device" + tristate "Qualcomm MSM V4l2 video overlay device" ---help--- Enables support for the MSM V4L2 video overlay driver. This allows video rendering @@ -221,8 +212,8 @@ config MSM_V4L2_VIDEO_OVERLAY_DEVICE APIs, by using /dev/videoX device config MSMB_JPEG - tristate "QTI MSM Jpeg Encoder Engine support" - depends on MSMB_CAMERA && (ARCH_MSM8974 || ARCH_MSM8226 || ARCH_APQ8084 || ARCH_MSM8916 || ARCH_MSM8953 || ARCH_MSM) + tristate "Qualcomm MSM Jpeg Encoder Engine support" + depends on MSMB_CAMERA && (ARCH_MSM8974 || ARCH_MSM8226 || ARCH_APQ8084 || ARCH_MSM8916 || ARCH_MSM) ---help--- Enable support for Jpeg Encoder/Decoder Engine for 8974. @@ -230,7 +221,7 @@ config MSMB_JPEG for the JPEG 1.0 encoder and decoder. config MSM_GEMINI - tristate "QTI MSM Gemini JPEG engine support" + tristate "Qualcomm MSM Gemini JPEG engine support" depends on MSMB_CAMERA && (ARCH_MSM7X30 || ARCH_MSM8X60 || ARCH_MSM8960) ---help--- Enables support for the Gemini JPEG encoder @@ -239,26 +230,14 @@ config MSM_GEMINI for JPEG encoding functionality. config MSM_FD - tristate "QTI MSM FD face detection engine support" + tristate "Qualcomm MSM FD face detection engine support" depends on MSMB_CAMERA ---help--- Enables support for the MSM FD face detection engine. config MSM_JPEGDMA - tristate "QTI MSM Jpeg dma" + tristate "Qualcomm Technologies Inc. MSM Jpeg dma" depends on MSMB_CAMERA select V4L2_MEM2MEM_DEV ---help--- Enable support for Jpeg dma engine. - -config MSM_SEC_CCI_TA_NAME - string "Name of TA to handle Secure CCI transactions" - depends on MSM_CCI - default "seccamdemo64" - -config MSM_SEC_CCI_DEBUG - bool "QTI MSM Secure CCI Relay Debug" - depends on MSM_CCI - ---help--- - Enables simulation of secure camera for Secure CCI Realy - debugging. diff --git a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c index 2ffeb5234887..7f5e49809a26 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c @@ -1006,11 +1006,8 @@ uint32_t msm_camera_unregister_bus_client(enum cam_bus_client id) mutex_destroy(&g_cv[id].lock); msm_bus_scale_unregister_client(g_cv[id].bus_client); - g_cv[id].bus_client = 0; - g_cv[id].num_usecases = 0; - g_cv[id].num_paths = 0; - g_cv[id].vector_index = 0; - g_cv[id].dyn_vote = 0; + msm_bus_cl_clear_pdata(g_cv[id].pdata); + memset(&g_cv[id], 0, sizeof(struct msm_cam_bus_pscale_data)); return 0; } diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c index f49ccfc5282c..1377eb27eba8 100644 --- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c +++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -432,7 +432,6 @@ static int msm_fd_open(struct file *file) ctx->vb2_q.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ctx->vb2_q.io_modes = VB2_USERPTR; ctx->vb2_q.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - mutex_init(&ctx->lock); ret = vb2_queue_init(&ctx->vb2_q); if (ret < 0) { dev_err(device->dev, "Error queue init\n"); @@ -483,9 +482,7 @@ static int msm_fd_release(struct file *file) msm_cpp_vbif_register_error_handler((void *)ctx, VBIF_CLIENT_FD, NULL); - mutex_lock(&ctx->lock); vb2_queue_release(&ctx->vb2_q); - mutex_unlock(&ctx->lock); vfree(ctx->stats); @@ -515,9 +512,7 @@ static unsigned int msm_fd_poll(struct file *file, struct fd_ctx *ctx = msm_fd_ctx_from_fh(file->private_data); unsigned int ret; - mutex_lock(&ctx->lock); ret = vb2_poll(&ctx->vb2_q, file, wait); - mutex_unlock(&ctx->lock); if (atomic_read(&ctx->subscribed_for_event)) { poll_wait(file, &ctx->fh.wait, wait); @@ -755,9 +750,9 @@ static int msm_fd_reqbufs(struct file *file, int ret; struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh); - mutex_lock(&ctx->lock); + mutex_lock(&ctx->fd_device->recovery_lock); ret = vb2_reqbufs(&ctx->vb2_q, req); - mutex_unlock(&ctx->lock); + mutex_unlock(&ctx->fd_device->recovery_lock); return ret; } @@ -773,9 +768,9 @@ static int msm_fd_qbuf(struct file *file, void *fh, int ret; struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh); - mutex_lock(&ctx->lock); + mutex_lock(&ctx->fd_device->recovery_lock); ret = vb2_qbuf(&ctx->vb2_q, pb); - mutex_unlock(&ctx->lock); + mutex_unlock(&ctx->fd_device->recovery_lock); return ret; } @@ -792,9 +787,9 @@ static int msm_fd_dqbuf(struct file *file, int ret; struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh); - mutex_lock(&ctx->lock); + mutex_lock(&ctx->fd_device->recovery_lock); ret = vb2_dqbuf(&ctx->vb2_q, pb, file->f_flags & O_NONBLOCK); - mutex_unlock(&ctx->lock); + mutex_unlock(&ctx->fd_device->recovery_lock); return ret; } @@ -810,9 +805,7 @@ static int msm_fd_streamon(struct file *file, struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh); int ret; - mutex_lock(&ctx->lock); ret = vb2_streamon(&ctx->vb2_q, buf_type); - mutex_unlock(&ctx->lock); if (ret < 0) dev_err(ctx->fd_device->dev, "Stream on fails\n"); @@ -831,9 +824,7 @@ static int msm_fd_streamoff(struct file *file, struct fd_ctx *ctx = msm_fd_ctx_from_fh(fh); int ret; - mutex_lock(&ctx->lock); ret = vb2_streamoff(&ctx->vb2_q, buf_type); - mutex_unlock(&ctx->lock); if (ret < 0) dev_err(ctx->fd_device->dev, "Stream off fails\n"); diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h index a7615a65d2fc..4155eb8a6faf 100644 --- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h +++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -161,7 +161,6 @@ struct fd_ctx { struct msm_fd_mem_pool mem_pool; struct msm_fd_stats *stats; struct msm_fd_buf_handle work_buf; - struct mutex lock; }; /* diff --git a/drivers/media/platform/msm/camera_v2/isp/Makefile b/drivers/media/platform/msm/camera_v2/isp/Makefile index 4c6586e2616c..621d81d381a1 100644 --- a/drivers/media/platform/msm/camera_v2/isp/Makefile +++ b/drivers/media/platform/msm/camera_v2/isp/Makefile @@ -1,10 +1,5 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io ccflags-y += -Idrivers/media/platform/msm/camera_v2/common/ -ifeq ($(CONFIG_MSM_ISP_V1),y) -obj-$(CONFIG_MSMB_CAMERA) += msm_isp_32.o msm_buf_mgr_32.o msm_isp_util_32.o msm_isp_axi_util_32.o msm_isp_stats_util_32.o -obj-$(CONFIG_MSMB_CAMERA) += msm_isp32.o -else -obj-$(CONFIG_MSMB_CAMERA) += msm_isp.o msm_buf_mgr.o msm_isp_util.o msm_isp_axi_util.o msm_isp_stats_util.o -obj-$(CONFIG_MSMB_CAMERA) += msm_isp47.o msm_isp46.o msm_isp44.o msm_isp40.o -endif +obj-$(CONFIG_MSMB_CAMERA) += msm_buf_mgr.o msm_isp_util.o msm_isp_axi_util.o msm_isp_stats_util.o +obj-$(CONFIG_MSMB_CAMERA) += msm_isp48.o msm_isp47.o msm_isp46.o msm_isp44.o msm_isp40.o msm_isp.o diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index 8b5095ac959e..7bc8f9cd5ebf 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -30,7 +30,6 @@ #include "msm.h" #include "msm_buf_mgr.h" #include "cam_smmu_api.h" -#include "msm_isp_util.h" #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) @@ -750,7 +749,6 @@ static int msm_isp_update_put_buf_cnt(struct msm_isp_buf_mgr *buf_mgr, if (-ENOTEMPTY == rc) { pr_err("%s: Error! Uncleared put_buf_mask for pingpong(%d) from vfe %d bufq 0x%x buf_idx %d\n", __func__, pingpong_bit, id, bufq_handle, buf_index); - msm_isp_dump_ping_pong_mismatch(); rc = -EFAULT; } spin_unlock_irqrestore(&bufq->bufq_lock, flags); @@ -1287,40 +1285,39 @@ static int msm_isp_deinit_isp_buf_mgr( int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr, unsigned int cmd, void *arg) { - int rc = -EINVAL; switch (cmd) { case VIDIOC_MSM_ISP_REQUEST_BUF: { struct msm_isp_buf_request *buf_req = arg; - rc = buf_mgr->ops->request_buf(buf_mgr, buf_req); + buf_mgr->ops->request_buf(buf_mgr, buf_req); break; } case VIDIOC_MSM_ISP_ENQUEUE_BUF: { struct msm_isp_qbuf_info *qbuf_info = arg; - rc = buf_mgr->ops->enqueue_buf(buf_mgr, qbuf_info); + buf_mgr->ops->enqueue_buf(buf_mgr, qbuf_info); break; } case VIDIOC_MSM_ISP_DEQUEUE_BUF: { struct msm_isp_qbuf_info *qbuf_info = arg; - rc = buf_mgr->ops->dequeue_buf(buf_mgr, qbuf_info); + buf_mgr->ops->dequeue_buf(buf_mgr, qbuf_info); break; } case VIDIOC_MSM_ISP_RELEASE_BUF: { struct msm_isp_buf_request *buf_req = arg; - rc = buf_mgr->ops->release_buf(buf_mgr, buf_req->handle); + buf_mgr->ops->release_buf(buf_mgr, buf_req->handle); break; } case VIDIOC_MSM_ISP_UNMAP_BUF: { struct msm_isp_unmap_buf_req *unmap_req = arg; - rc = buf_mgr->ops->unmap_buf(buf_mgr, unmap_req->fd); + buf_mgr->ops->unmap_buf(buf_mgr, unmap_req->fd); break; } } - return rc; + return 0; } static int msm_isp_buf_mgr_debug(struct msm_isp_buf_mgr *buf_mgr, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.c deleted file mode 100644 index 3203d44b0fba..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include - -#include - -#include "msm.h" -#include "msm_buf_mgr_32.h" - -#undef CDBG -#define CDBG(fmt, args...) pr_debug(fmt, ##args) - -struct msm_isp_bufq *msm_isp_get_bufq( - struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle) -{ - struct msm_isp_bufq *bufq = NULL; - uint32_t bufq_index = bufq_handle & 0xFF; - - if ((bufq_handle == 0) || - (bufq_index > buf_mgr->num_buf_q) || - (bufq_index >= BUF_MGR_NUM_BUF_Q)) - return NULL; - - bufq = &buf_mgr->bufq[bufq_index]; - if (bufq->bufq_handle == bufq_handle) - return bufq; - - return NULL; -} - -static struct msm_isp_buffer *msm_isp_get_buf_ptr( - struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index) -{ - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return buf_info; - } - - if (bufq->num_bufs <= buf_index) { - pr_err("%s: Invalid buf index\n", __func__); - return buf_info; - } - buf_info = &bufq->bufs[buf_index]; - return buf_info; -} - -static uint32_t msm_isp_get_buf_handle( - struct msm_isp_buf_mgr *buf_mgr, - uint32_t session_id, uint32_t stream_id) -{ - int i; - - if ((buf_mgr->buf_handle_cnt << 8) == 0) - buf_mgr->buf_handle_cnt++; - - for (i = 0; i < buf_mgr->num_buf_q; i++) { - if (buf_mgr->bufq[i].session_id == session_id && - buf_mgr->bufq[i].stream_id == stream_id) - return 0; - } - - for (i = 0; i < buf_mgr->num_buf_q; i++) { - if (buf_mgr->bufq[i].bufq_handle == 0) { - memset(&buf_mgr->bufq[i], - 0, sizeof(struct msm_isp_bufq)); - buf_mgr->bufq[i].bufq_handle = - (++buf_mgr->buf_handle_cnt) << 8 | i; - return buf_mgr->bufq[i].bufq_handle; - } - } - return 0; -} - -static int msm_isp_free_buf_handle(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle) -{ - struct msm_isp_bufq *bufq = - msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) - return -EINVAL; - memset(bufq, 0, sizeof(struct msm_isp_bufq)); - return 0; -} - -static void msm_isp_copy_planes_from_v4l2_buffer( - struct msm_isp_qbuf_buffer *qbuf_buf, - const struct v4l2_buffer *v4l2_buf) -{ - int i; - - qbuf_buf->num_planes = v4l2_buf->length; - for (i = 0; i < qbuf_buf->num_planes; i++) { - qbuf_buf->planes[i].addr = v4l2_buf->m.planes[i].m.userptr; - qbuf_buf->planes[i].offset = v4l2_buf->m.planes[i].data_offset; - } -} - -static int msm_isp_prepare_isp_buf(struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_buffer *buf_info, - struct msm_isp_qbuf_buffer *qbuf_buf) -{ - int i, rc = -1; - struct msm_isp_buffer_mapped_info *mapped_info; - struct buffer_cmd *buf_pending = NULL; - int domain_num; - - if (buf_mgr->secure_enable == NON_SECURE_MODE) - domain_num = buf_mgr->iommu_domain_num; - else - domain_num = buf_mgr->iommu_domain_num_secure; - - for (i = 0; i < qbuf_buf->num_planes; i++) { - mapped_info = &buf_info->mapped_info[i]; - mapped_info->handle = - ion_import_dma_buf(buf_mgr->client, - qbuf_buf->planes[i].addr); - if (IS_ERR_OR_NULL(mapped_info->handle)) { - pr_err("%s: buf has null/error ION handle %pK\n", - __func__, mapped_info->handle); - goto ion_map_error; - } - if (ion_map_iommu(buf_mgr->client, mapped_info->handle, - domain_num, 0, SZ_4K, - 0, &(mapped_info->paddr), - &(mapped_info->len), 0, 0) < 0) { - rc = -EINVAL; - pr_err("%s: cannot map address", __func__); - ion_free(buf_mgr->client, mapped_info->handle); - goto ion_map_error; - } - mapped_info->paddr += qbuf_buf->planes[i].offset; - CDBG("%s: plane: %d addr:%lu\n", - __func__, i, (unsigned long)mapped_info->paddr); - - buf_pending = kzalloc(sizeof(struct buffer_cmd), GFP_ATOMIC); - if (!buf_pending) - return rc; - - buf_pending->mapped_info = mapped_info; - list_add_tail(&buf_pending->list, &buf_mgr->buffer_q); - } - buf_info->num_planes = qbuf_buf->num_planes; - return 0; -ion_map_error: - for (--i; i >= 0; i--) { - mapped_info = &buf_info->mapped_info[i]; - ion_unmap_iommu(buf_mgr->client, mapped_info->handle, - buf_mgr->iommu_domain_num, 0); - ion_free(buf_mgr->client, mapped_info->handle); - } - return rc; -} - -static void msm_isp_unprepare_v4l2_buf( - struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_buffer *buf_info) -{ - int i; - struct msm_isp_buffer_mapped_info *mapped_info; - struct buffer_cmd *buf_pending = NULL; - int domain_num; - - if (buf_mgr->secure_enable == NON_SECURE_MODE) - domain_num = buf_mgr->iommu_domain_num; - else - domain_num = buf_mgr->iommu_domain_num_secure; - - for (i = 0; i < buf_info->num_planes; i++) { - mapped_info = &buf_info->mapped_info[i]; - - list_for_each_entry(buf_pending, &buf_mgr->buffer_q, list) { - if (!buf_pending) - break; - - if (buf_pending->mapped_info == mapped_info) { - ion_unmap_iommu(buf_mgr->client, - mapped_info->handle, - domain_num, 0); - ion_free(buf_mgr->client, mapped_info->handle); - - list_del_init(&buf_pending->list); - kfree(buf_pending); - break; - } - } - } -} - -static int msm_isp_buf_prepare(struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_qbuf_info *info, struct vb2_buffer *vb2_buf) -{ - int rc = -1; - unsigned long flags; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - struct msm_isp_qbuf_buffer buf; - - buf_info = msm_isp_get_buf_ptr(buf_mgr, - info->handle, info->buf_idx); - if (!buf_info) { - pr_err("Invalid buffer prepare\n"); - return rc; - } - - bufq = msm_isp_get_bufq(buf_mgr, buf_info->bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - - spin_lock_irqsave(&bufq->bufq_lock, flags); - if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { - rc = buf_info->state; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; - } - - if (buf_info->state != MSM_ISP_BUFFER_STATE_INITIALIZED) { - pr_err("%s: Invalid buffer state: %d\n", - __func__, buf_info->state); - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; - } - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - - if (vb2_buf) { - msm_isp_copy_planes_from_v4l2_buffer(&buf, &vb2_buf->v4l2_buf); - buf_info->vb2_buf = vb2_buf; - } else { - buf = info->buffer; - } - - rc = msm_isp_prepare_isp_buf(buf_mgr, buf_info, &buf); - if (rc < 0) { - pr_err("%s: Prepare buffer error\n", __func__); - return rc; - } - spin_lock_irqsave(&bufq->bufq_lock, flags); - buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; -} - -static int msm_isp_buf_unprepare(struct msm_isp_buf_mgr *buf_mgr, - uint32_t buf_handle) -{ - int rc = -1, i; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, buf_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - - for (i = 0; i < bufq->num_bufs; i++) { - buf_info = msm_isp_get_buf_ptr(buf_mgr, buf_handle, i); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - return rc; - } - if (buf_info->state == MSM_ISP_BUFFER_STATE_UNUSED || - buf_info->state == - MSM_ISP_BUFFER_STATE_INITIALIZED) - continue; - - if (MSM_ISP_BUFFER_SRC_HAL == BUF_SRC(bufq->stream_id)) { - if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED || - buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) - buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf, - bufq->session_id, bufq->stream_id); - } - msm_isp_unprepare_v4l2_buf(buf_mgr, buf_info); - } - return 0; -} - -static int msm_isp_get_buf_by_index(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct msm_isp_buffer **buf_info) -{ - int rc = -EINVAL; - unsigned long flags; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *temp_buf_info; - uint32_t i = 0; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - - spin_lock_irqsave(&bufq->bufq_lock, flags); - if (buf_index >= bufq->num_bufs) { - pr_err("%s: Invalid buf index: %d max: %d\n", __func__, - buf_index, bufq->num_bufs); - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; - } - - *buf_info = NULL; - for (i = 0; bufq->num_bufs; i++) { - temp_buf_info = &bufq->bufs[i]; - if (temp_buf_info && temp_buf_info->buf_idx == buf_index) { - *buf_info = temp_buf_info; - break; - } - } - - if (*buf_info) { - pr_debug("Found buf in isp buf mgr"); - rc = 0; - } - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; -} - - -static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, - uint32_t bufq_handle, struct msm_isp_buffer **buf_info) -{ - int rc = -1; - unsigned long flags; - struct msm_isp_buffer *temp_buf_info; - struct msm_isp_bufq *bufq = NULL; - struct vb2_buffer *vb2_buf = NULL; - struct buffer_cmd *buf_pending = NULL; - struct msm_isp_buffer_mapped_info *mped_info_tmp1; - struct msm_isp_buffer_mapped_info *mped_info_tmp2; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - if (!bufq->bufq_handle) { - pr_err("%s: Invalid bufq handle\n", __func__); - return rc; - } - - *buf_info = NULL; - spin_lock_irqsave(&bufq->bufq_lock, flags); - if (bufq->buf_type == ISP_SHARE_BUF) { - list_for_each_entry(temp_buf_info, - &bufq->share_head, share_list) { - if (!temp_buf_info->buf_used[id]) { - temp_buf_info->buf_used[id] = 1; - temp_buf_info->buf_get_count++; - if (temp_buf_info->buf_get_count == - bufq->buf_client_count) - list_del_init( - &temp_buf_info->share_list); - if (temp_buf_info->buf_reuse_flag) { - kfree(temp_buf_info); - } else { - *buf_info = temp_buf_info; - rc = 0; - } - spin_unlock_irqrestore( - &bufq->bufq_lock, flags); - return rc; - } - } - } - - switch (BUF_SRC(bufq->stream_id)) { - case MSM_ISP_BUFFER_SRC_NATIVE: - list_for_each_entry(temp_buf_info, &bufq->head, list) { - if (temp_buf_info->state == - MSM_ISP_BUFFER_STATE_QUEUED) { - - list_for_each_entry(buf_pending, - &buf_mgr->buffer_q, list) { - if (!buf_pending) - break; - mped_info_tmp1 = - buf_pending->mapped_info; - mped_info_tmp2 = - &temp_buf_info->mapped_info[0]; - - if (mped_info_tmp1 == mped_info_tmp2 - && (mped_info_tmp1->len == - mped_info_tmp2->len) - && (mped_info_tmp1->paddr == - mped_info_tmp2->paddr)){ - /* found one buf */ - list_del_init( - &temp_buf_info->list); - *buf_info = temp_buf_info; - break; - } - } - break; - } - } - break; - case MSM_ISP_BUFFER_SRC_HAL: - vb2_buf = buf_mgr->vb2_ops->get_buf( - bufq->session_id, bufq->stream_id); - if (vb2_buf) { - if (vb2_buf->v4l2_buf.index < bufq->num_bufs) { - - list_for_each_entry(buf_pending, - &buf_mgr->buffer_q, list) { - if (!buf_pending) - break; - mped_info_tmp1 = - buf_pending->mapped_info; - mped_info_tmp2 = - &bufq->bufs[vb2_buf->v4l2_buf.index] - .mapped_info[0]; - - if (mped_info_tmp1 == mped_info_tmp2 - && (mped_info_tmp1->len == - mped_info_tmp2->len) - && (mped_info_tmp1->paddr == - mped_info_tmp2->paddr)) { - *buf_info = - &bufq->bufs[vb2_buf->v4l2_buf.index]; - (*buf_info)->vb2_buf = vb2_buf; - break; - } - } - } else { - pr_err("%s: Incorrect buf index %d\n", - __func__, vb2_buf->v4l2_buf.index); - rc = -EINVAL; - } - } - break; - case MSM_ISP_BUFFER_SRC_SCRATCH: - /* In scratch buf case we have only on buffer in queue. - * We return every time same buffer. */ - *buf_info = list_entry(bufq->head.next, typeof(**buf_info), - list); - break; - default: - pr_err("%s: Incorrect buf source.\n", __func__); - rc = -EINVAL; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; - } - - if (!(*buf_info)) { - if (bufq->buf_type == ISP_SHARE_BUF) { - temp_buf_info = kzalloc( - sizeof(struct msm_isp_buffer), GFP_ATOMIC); - if (temp_buf_info) { - temp_buf_info->buf_reuse_flag = 1; - temp_buf_info->buf_used[id] = 1; - temp_buf_info->buf_get_count = 1; - list_add_tail(&temp_buf_info->share_list, - &bufq->share_head); - *buf_info = temp_buf_info; - } else - rc = -ENOMEM; - } - } else { - (*buf_info)->state = MSM_ISP_BUFFER_STATE_DEQUEUED; - if (bufq->buf_type == ISP_SHARE_BUF) { - memset((*buf_info)->buf_used, 0, - sizeof(uint8_t) * bufq->buf_client_count); - (*buf_info)->buf_used[id] = 1; - (*buf_info)->buf_get_count = 1; - (*buf_info)->buf_put_count = 0; - (*buf_info)->buf_reuse_flag = 0; - list_add_tail(&(*buf_info)->share_list, - &bufq->share_head); - } - rc = 0; - } - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; -} - -static int msm_isp_put_buf(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index) -{ - int rc = -1; - unsigned long flags; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - - buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - return rc; - } - - - buf_info->buf_get_count = 0; - buf_info->buf_put_count = 0; - memset(buf_info->buf_used, 0, sizeof(buf_info->buf_used)); - - spin_lock_irqsave(&bufq->bufq_lock, flags); - switch (buf_info->state) { - case MSM_ISP_BUFFER_STATE_PREPARED: - if (MSM_ISP_BUFFER_SRC_SCRATCH == BUF_SRC(bufq->stream_id)) - list_add_tail(&buf_info->list, &bufq->head); - case MSM_ISP_BUFFER_STATE_DEQUEUED: - case MSM_ISP_BUFFER_STATE_DIVERTED: - if (MSM_ISP_BUFFER_SRC_NATIVE == BUF_SRC(bufq->stream_id)) - list_add_tail(&buf_info->list, &bufq->head); - else if (MSM_ISP_BUFFER_SRC_HAL == BUF_SRC(bufq->stream_id)) - buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf, - bufq->session_id, bufq->stream_id); - buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; - rc = 0; - break; - case MSM_ISP_BUFFER_STATE_DISPATCHED: - buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; - rc = 0; - break; - case MSM_ISP_BUFFER_STATE_QUEUED: - rc = 0; - break; - default: - pr_err("%s: incorrect state = %d", - __func__, buf_info->state); - break; - } - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - - return rc; -} - -static int msm_isp_put_buf_unsafe(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index) -{ - int rc = -1; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - - buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - return rc; - } - - switch (buf_info->state) { - case MSM_ISP_BUFFER_STATE_PREPARED: - case MSM_ISP_BUFFER_STATE_DEQUEUED: - case MSM_ISP_BUFFER_STATE_DIVERTED: - if (BUF_SRC(bufq->stream_id)) - list_add_tail(&buf_info->list, &bufq->head); - else - buf_mgr->vb2_ops->put_buf(buf_info->vb2_buf, - bufq->session_id, bufq->stream_id); - buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; - rc = 0; - break; - case MSM_ISP_BUFFER_STATE_DISPATCHED: - buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; - rc = 0; - break; - case MSM_ISP_BUFFER_STATE_QUEUED: - rc = 0; - break; - default: - pr_err("%s: incorrect state = %d", - __func__, buf_info->state); - break; - } - - return rc; -} - -static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct timeval *tv, uint32_t frame_id, uint32_t output_format) -{ - int rc = -1; - unsigned long flags; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - enum msm_isp_buffer_state state; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("Invalid bufq\n"); - return rc; - } - - buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - return rc; - } - - spin_lock_irqsave(&bufq->bufq_lock, flags); - state = buf_info->state; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - - if (state == MSM_ISP_BUFFER_STATE_DEQUEUED || - state == MSM_ISP_BUFFER_STATE_DIVERTED) { - spin_lock_irqsave(&bufq->bufq_lock, flags); - if (bufq->buf_type == ISP_SHARE_BUF) { - buf_info->buf_put_count++; - if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) { - rc = buf_info->buf_put_count; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; - } - } - buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - if (MSM_ISP_BUFFER_SRC_HAL == BUF_SRC(bufq->stream_id)) { - buf_info->vb2_buf->v4l2_buf.timestamp = *tv; - buf_info->vb2_buf->v4l2_buf.sequence = frame_id; - buf_info->vb2_buf->v4l2_buf.reserved = output_format; - buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf, - bufq->session_id, bufq->stream_id, - frame_id, tv, output_format); - } else { - rc = msm_isp_put_buf(buf_mgr, buf_info->bufq_handle, - buf_info->buf_idx); - if (rc < 0) { - pr_err("%s: Buf put failed\n", __func__); - return rc; - } - } - } - - return 0; -} - -static int msm_isp_flush_buf(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type) -{ - int rc = -1, i; - unsigned long flags; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("Invalid bufq\n"); - return rc; - } - - for (i = 0; i < bufq->num_bufs; i++) { - buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, i); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - continue; - } - spin_lock_irqsave(&bufq->bufq_lock, flags); - if (flush_type == MSM_ISP_BUFFER_FLUSH_DIVERTED && - buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { - buf_info->state = MSM_ISP_BUFFER_STATE_QUEUED; - } else if (flush_type == MSM_ISP_BUFFER_FLUSH_ALL) { - if (buf_info->state == MSM_ISP_BUFFER_STATE_DIVERTED) { - CDBG("%s: no need to queue Diverted buffer\n", - __func__); - } else if (buf_info->state == - MSM_ISP_BUFFER_STATE_DEQUEUED) { - if (buf_info->buf_get_count == - ISP_SHARE_BUF_CLIENT) { - msm_isp_put_buf_unsafe(buf_mgr, - bufq_handle, buf_info->buf_idx); - } else { - buf_info->state = - MSM_ISP_BUFFER_STATE_DEQUEUED; - buf_info->buf_get_count = 0; - buf_info->buf_put_count = 0; - memset(buf_info->buf_used, 0, - sizeof(uint8_t) * 2); - } - } - } - - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - } - - return 0; -} - -static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct timeval *tv, uint32_t frame_id) -{ - int rc = -1; - unsigned long flags; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("Invalid bufq\n"); - return rc; - } - - buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - return rc; - } - - spin_lock_irqsave(&bufq->bufq_lock, flags); - if (bufq->buf_type == ISP_SHARE_BUF) { - buf_info->buf_put_count++; - if (buf_info->buf_put_count != ISP_SHARE_BUF_CLIENT) { - rc = buf_info->buf_put_count; - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - return rc; - } - } - - if (buf_info->state == MSM_ISP_BUFFER_STATE_DEQUEUED) { - buf_info->state = MSM_ISP_BUFFER_STATE_DIVERTED; - buf_info->tv = tv; - buf_info->frame_id = frame_id; - } - spin_unlock_irqrestore(&bufq->bufq_lock, flags); - - return 0; -} - -static int msm_isp_buf_enqueue(struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_qbuf_info *info) -{ - int rc = -1, buf_state; - struct msm_isp_bufq *bufq = NULL; - struct msm_isp_buffer *buf_info = NULL; - - buf_state = msm_isp_buf_prepare(buf_mgr, info, NULL); - if (buf_state < 0) { - pr_err("%s: Buf prepare failed\n", __func__); - return -EINVAL; - } - - if (buf_state == MSM_ISP_BUFFER_STATE_DIVERTED) { - buf_info = msm_isp_get_buf_ptr(buf_mgr, - info->handle, info->buf_idx); - if (!buf_info) { - pr_err("%s: buf not found\n", __func__); - return rc; - } - if (info->dirty_buf) { - rc = msm_isp_put_buf(buf_mgr, - info->handle, info->buf_idx); - } else { - bufq = msm_isp_get_bufq(buf_mgr, info->handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - if (BUF_SRC(bufq->stream_id)) - pr_err("%s: Invalid native buffer state\n", - __func__); - else - rc = msm_isp_buf_done(buf_mgr, - info->handle, info->buf_idx, - buf_info->tv, buf_info->frame_id, 0); - } - } else { - bufq = msm_isp_get_bufq(buf_mgr, info->handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return rc; - } - if (MSM_ISP_BUFFER_SRC_HAL != BUF_SRC(bufq->stream_id)) { - rc = msm_isp_put_buf(buf_mgr, - info->handle, info->buf_idx); - if (rc < 0) { - pr_err("%s: Buf put failed\n", __func__); - return rc; - } - } - } - return rc; -} - -static int msm_isp_get_bufq_handle(struct msm_isp_buf_mgr *buf_mgr, - uint32_t session_id, uint32_t stream_id) -{ - int i; - - for (i = 0; i < buf_mgr->num_buf_q; i++) { - if (buf_mgr->bufq[i].session_id == session_id && - buf_mgr->bufq[i].stream_id == stream_id) { - return buf_mgr->bufq[i].bufq_handle; - } - } - pr_err("%s: No match found 0x%x 0x%x\n", __func__, - session_id, stream_id); - return 0; -} - -static int msm_isp_get_buf_src(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t *buf_src) -{ - struct msm_isp_bufq *bufq = NULL; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("%s: Invalid bufq\n", __func__); - return -EINVAL; - } - *buf_src = BUF_SRC(bufq->stream_id); - - return 0; -} - -static int msm_isp_request_bufq(struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_buf_request *buf_request) -{ - int rc = -1, i; - struct msm_isp_bufq *bufq = NULL; - - CDBG("%s: E\n", __func__); - - if (!buf_request->num_buf || buf_request->num_buf > VIDEO_MAX_FRAME) { - pr_err("Invalid buffer request\n"); - return rc; - } - - buf_request->handle = msm_isp_get_buf_handle(buf_mgr, - buf_request->session_id, buf_request->stream_id); - if (!buf_request->handle) { - pr_err("Invalid buffer handle\n"); - return rc; - } - - bufq = msm_isp_get_bufq(buf_mgr, buf_request->handle); - if (!bufq) { - pr_err("Invalid buffer queue\n"); - return rc; - } - - bufq->bufs = kzalloc(sizeof(struct msm_isp_buffer) * - buf_request->num_buf, GFP_KERNEL); - if (!bufq->bufs) { - msm_isp_free_buf_handle(buf_mgr, buf_request->handle); - return rc; - } - - spin_lock_init(&bufq->bufq_lock); - bufq->bufq_handle = buf_request->handle; - bufq->session_id = buf_request->session_id; - bufq->stream_id = buf_request->stream_id; - bufq->num_bufs = buf_request->num_buf; - bufq->buf_type = buf_request->buf_type; - if (bufq->buf_type == ISP_SHARE_BUF) - bufq->buf_client_count = ISP_SHARE_BUF_CLIENT; - INIT_LIST_HEAD(&bufq->head); - INIT_LIST_HEAD(&bufq->share_head); - for (i = 0; i < buf_request->num_buf; i++) { - bufq->bufs[i].state = MSM_ISP_BUFFER_STATE_INITIALIZED; - bufq->bufs[i].bufq_handle = bufq->bufq_handle; - bufq->bufs[i].buf_idx = i; - } - - return 0; -} - -static int msm_isp_release_bufq(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle) -{ - struct msm_isp_bufq *bufq = NULL; - int rc = -1; - - bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); - if (!bufq) { - pr_err("Invalid bufq release\n"); - return rc; - } - - msm_isp_buf_unprepare(buf_mgr, bufq_handle); - - kfree(bufq->bufs); - msm_isp_free_buf_handle(buf_mgr, bufq_handle); - return 0; -} - -static void msm_isp_release_all_bufq( - struct msm_isp_buf_mgr *buf_mgr) -{ - struct msm_isp_bufq *bufq = NULL; - int i; - - for (i = 0; i < buf_mgr->num_buf_q; i++) { - bufq = &buf_mgr->bufq[i]; - if (!bufq->bufq_handle) - continue; - msm_isp_buf_unprepare(buf_mgr, bufq->bufq_handle); - - kfree(bufq->bufs); - msm_isp_free_buf_handle(buf_mgr, bufq->bufq_handle); - } -} - -static void msm_isp_register_ctx(struct msm_isp_buf_mgr *buf_mgr, - struct device **iommu_ctx1, struct device **iommu_ctx2, - int num_iommu_ctx, int secure_num_iommu_ctx) -{ - int i; - - buf_mgr->num_iommu_ctx = num_iommu_ctx; - for (i = 0; i < num_iommu_ctx; i++) - buf_mgr->iommu_ctx[i] = iommu_ctx1[i]; - - buf_mgr->num_iommu_secure_ctx = secure_num_iommu_ctx; - for (i = 0; i < secure_num_iommu_ctx; i++) - buf_mgr->iommu_secure_ctx[i] = iommu_ctx2[i]; -} - -static int msm_isp_attach_ctx(struct msm_isp_buf_mgr *buf_mgr, - struct msm_vfe_smmu_attach_cmd *cmd) -{ - int rc, i; - - if (cmd->security_mode == NON_SECURE_MODE) { - /*non secure mode*/ - for (i = 0; i < buf_mgr->num_iommu_ctx; i++) { - - if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] == 0) { - /* attach only once */ - rc = iommu_attach_device( - buf_mgr->iommu_domain, - buf_mgr->iommu_ctx[i]); - if (rc) { - pr_err("%s: non-secure attach error bank: %d, rc : %d\n", - __func__, i, rc); - return -EINVAL; - } - } - buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i]++; - } - } else { - /*secure mode*/ - for (i = 0; i < buf_mgr->num_iommu_secure_ctx; i++) { - - if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] == 0) { - /* attach only once */ - rc = iommu_attach_device( - buf_mgr->iommu_domain_secure, - buf_mgr->iommu_secure_ctx[i]); - if (rc) { - pr_err("%s: secure attach error bank: %d, rc : %d\n", - __func__, i, rc); - return -EINVAL; - } - } - buf_mgr->attach_ref_cnt[SECURE_MODE][i]++; - } - } - buf_mgr->attach_state = MSM_ISP_BUF_MGR_ATTACH; - return 0; -} - -static int msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr) -{ - int i; - - if (buf_mgr->attach_state == MSM_ISP_BUF_MGR_DETACH || - buf_mgr->open_count) - return 0; - - if (buf_mgr->secure_enable == NON_SECURE_MODE) { - /*non secure mode*/ - for (i = 0; i < buf_mgr->num_iommu_ctx; i++) { - /*Detach only if ref count is one*/ - if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] == 1) { - iommu_detach_device(buf_mgr->iommu_domain, - buf_mgr->iommu_ctx[i]); - } - if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] > 0) - --buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i]; - } - } else { - /*secure mode*/ - for (i = 0; i < buf_mgr->num_iommu_secure_ctx; i++) { - /*Detach only if ref count is one*/ - if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] == 1) { - iommu_detach_device( - buf_mgr->iommu_domain_secure, - buf_mgr->iommu_secure_ctx[i]); - } - if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] > 0) - --buf_mgr->attach_ref_cnt[SECURE_MODE][i]; - } - } - buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH; - return 0; -} - -int msm_isp_smmu_attach(struct msm_isp_buf_mgr *buf_mgr, - void *arg) -{ - struct msm_vfe_smmu_attach_cmd *cmd = arg; - int rc = 0; - - pr_debug("%s: cmd->security_mode : %d\n", __func__, cmd->security_mode); - if (cmd->iommu_attach_mode == IOMMU_ATTACH) { - buf_mgr->secure_enable = cmd->security_mode; - rc = msm_isp_attach_ctx(buf_mgr, cmd); - if (rc < 0) { - pr_err("%s: smmu attach error, rc :%d\n", __func__, rc); - goto iommu_error; - } - } else - msm_isp_detach_ctx(buf_mgr); - -iommu_error: - return rc; -} - - -static int msm_isp_init_isp_buf_mgr( - struct msm_isp_buf_mgr *buf_mgr, - const char *ctx_name, uint16_t num_buf_q) -{ - int rc = -1; - - if (buf_mgr->open_count++) - return 0; - - if (!num_buf_q) { - pr_err("Invalid buffer queue number\n"); - return rc; - } - CDBG("%s: E\n", __func__); - - INIT_LIST_HEAD(&buf_mgr->buffer_q); - buf_mgr->num_buf_q = num_buf_q; - buf_mgr->bufq = - kzalloc(sizeof(struct msm_isp_bufq) * num_buf_q, - GFP_KERNEL); - if (!buf_mgr->bufq) { - pr_err("Bufq malloc error\n"); - goto bufq_error; - } - buf_mgr->client = msm_ion_client_create(ctx_name); - buf_mgr->buf_handle_cnt = 0; - buf_mgr->pagefault_debug = 0; - return 0; -bufq_error: - return rc; -} - -static int msm_isp_deinit_isp_buf_mgr( - struct msm_isp_buf_mgr *buf_mgr) -{ - if (buf_mgr->open_count > 0) - buf_mgr->open_count--; - - if (buf_mgr->open_count) - return 0; - msm_isp_release_all_bufq(buf_mgr); - ion_client_destroy(buf_mgr->client); - kfree(buf_mgr->bufq); - buf_mgr->num_buf_q = 0; - buf_mgr->pagefault_debug = 0; - msm_isp_detach_ctx(buf_mgr); - return 0; -} - -int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr, - unsigned int cmd, void *arg) -{ - switch (cmd) { - case VIDIOC_MSM_ISP_REQUEST_BUF: { - struct msm_isp_buf_request *buf_req = arg; - - buf_mgr->ops->request_buf(buf_mgr, buf_req); - break; - } - case VIDIOC_MSM_ISP_ENQUEUE_BUF: { - struct msm_isp_qbuf_info *qbuf_info = arg; - - buf_mgr->ops->enqueue_buf(buf_mgr, qbuf_info); - break; - } - case VIDIOC_MSM_ISP_RELEASE_BUF: { - struct msm_isp_buf_request *buf_req = arg; - - buf_mgr->ops->release_buf(buf_mgr, buf_req->handle); - break; - } - } - return 0; -} - -int msm_isp_buf_mgr_debug(struct msm_isp_buf_mgr *buf_mgr) -{ - struct msm_isp_buffer *bufs = NULL; - uint32_t i = 0, j = 0, k = 0, rc = 0; - - if (!buf_mgr) { - pr_err_ratelimited("%s: %d] NULL buf_mgr\n", - __func__, __LINE__); - return -EINVAL; - } - for (i = 0; i < BUF_MGR_NUM_BUF_Q; i++) { - if (buf_mgr->bufq[i].bufq_handle != 0) { - pr_err("%s:%d handle %x\n", __func__, i, - buf_mgr->bufq[i].bufq_handle); - pr_err("%s:%d session_id %d, stream_id %x,", - __func__, i, buf_mgr->bufq[i].session_id, - buf_mgr->bufq[i].stream_id); - pr_err("num_bufs %d, handle %x, type %d\n", - buf_mgr->bufq[i].num_bufs, - buf_mgr->bufq[i].bufq_handle, - buf_mgr->bufq[i].buf_type); - for (j = 0; j < buf_mgr->bufq[i].num_bufs; j++) { - bufs = &buf_mgr->bufq[i].bufs[j]; - if (!bufs) { - pr_err("bufs at %d is NULL breaking\n", - j); - break; - } - pr_err("%s:%d buf_idx %d, frame_id %d,", - __func__, j, bufs->buf_idx, - bufs->frame_id); - pr_err("num_planes %d, state %d\n", - bufs->num_planes, bufs->state); - for (k = 0; k < bufs->num_planes; k++) { - pr_err("%s:%d paddr %x, len %lu,", - __func__, k, (unsigned int) - bufs->mapped_info[k].paddr, - bufs->mapped_info[k].len); - pr_err(" ion handle %pK\n", - bufs->mapped_info[k].handle); - } - } - } - } - buf_mgr->pagefault_debug = 1; - return rc; -} - -static struct msm_isp_buf_ops isp_buf_ops = { - .request_buf = msm_isp_request_bufq, - .enqueue_buf = msm_isp_buf_enqueue, - .release_buf = msm_isp_release_bufq, - .get_bufq_handle = msm_isp_get_bufq_handle, - .get_buf_src = msm_isp_get_buf_src, - .get_buf = msm_isp_get_buf, - .get_buf_by_index = msm_isp_get_buf_by_index, - .put_buf = msm_isp_put_buf, - .flush_buf = msm_isp_flush_buf, - .buf_done = msm_isp_buf_done, - .buf_divert = msm_isp_buf_divert, - .register_ctx = msm_isp_register_ctx, - .buf_mgr_init = msm_isp_init_isp_buf_mgr, - .buf_mgr_deinit = msm_isp_deinit_isp_buf_mgr, - .buf_mgr_debug = msm_isp_buf_mgr_debug, - .get_bufq = msm_isp_get_bufq, -}; - -int msm_isp_create_isp_buf_mgr( - struct msm_isp_buf_mgr *buf_mgr, - struct msm_sd_req_vb2_q *vb2_ops, - struct msm_iova_layout *iova_layout) -{ - int rc = 0; - int i = 0, j = 0; - - if (buf_mgr->init_done) - return rc; - - buf_mgr->iommu_domain_num = msm_register_domain(iova_layout); - if (buf_mgr->iommu_domain_num < 0) { - pr_err("%s: Invalid iommu domain number\n", __func__); - rc = -1; - goto iommu_domain_error; - } - - buf_mgr->iommu_domain = msm_get_iommu_domain( - buf_mgr->iommu_domain_num); - if (!buf_mgr->iommu_domain) { - pr_err("%s: Invalid iommu domain\n", __func__); - rc = -1; - goto iommu_domain_error; - } - buf_mgr->ops = &isp_buf_ops; - buf_mgr->vb2_ops = vb2_ops; - buf_mgr->open_count = 0; - buf_mgr->pagefault_debug = 0; - buf_mgr->secure_enable = NON_SECURE_MODE; - buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH; - - for (i = 0; i < MAX_PROTECTION_MODE; i++) - for (j = 0; j < MAX_IOMMU_CTX; j++) - buf_mgr->attach_ref_cnt[i][j] = 0; - return 0; -iommu_domain_error: - return rc; -} - -int msm_isp_create_secure_domain( - struct msm_isp_buf_mgr *buf_mgr, - struct msm_iova_layout *iova_layout) -{ - int rc = 0; - - if (buf_mgr->init_done) - return rc; - buf_mgr->iommu_domain_num_secure = msm_register_domain(iova_layout); - if (buf_mgr->iommu_domain_num_secure < 0) { - pr_err("%s: Invalid iommu domain number\n", __func__); - rc = -1; - goto iommu_domain_error; - } - - buf_mgr->iommu_domain_secure = msm_get_iommu_domain( - buf_mgr->iommu_domain_num_secure); - if (!buf_mgr->iommu_domain_secure) { - pr_err("%s: Invalid iommu domain\n", __func__); - rc = -1; - goto iommu_domain_error; - } - return 0; -iommu_domain_error: - return rc; -} diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.h deleted file mode 100644 index e1b442ce1208..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr_32.h +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _MSM_ISP_BUF_H_ -#define _MSM_ISP_BUF_H_ - -#include -#include -#include "msm_sd.h" - -/* Buffer type could be userspace / HAL. - * Userspase could provide native or scratch buffer. */ -#define BUF_SRC(id) ( \ - (id & ISP_SCRATCH_BUF_BIT) ? MSM_ISP_BUFFER_SRC_SCRATCH : \ - (id & ISP_NATIVE_BUF_BIT) ? MSM_ISP_BUFFER_SRC_NATIVE : \ - MSM_ISP_BUFFER_SRC_HAL) - -#define ISP_SHARE_BUF_CLIENT 2 -#define BUF_MGR_NUM_BUF_Q 28 -#define MAX_IOMMU_CTX 2 - -struct msm_isp_buf_mgr; - -enum msm_isp_buffer_src_t { - MSM_ISP_BUFFER_SRC_HAL, - MSM_ISP_BUFFER_SRC_NATIVE, - MSM_ISP_BUFFER_SRC_SCRATCH, - MSM_ISP_BUFFER_SRC_MAX, -}; - -enum msm_isp_buffer_state { - MSM_ISP_BUFFER_STATE_UNUSED, /* not used */ - MSM_ISP_BUFFER_STATE_INITIALIZED, /* REQBUF done */ - MSM_ISP_BUFFER_STATE_PREPARED, /* BUF mapped */ - MSM_ISP_BUFFER_STATE_QUEUED, /* buf queued */ - MSM_ISP_BUFFER_STATE_DEQUEUED, /* in use in VFE */ - MSM_ISP_BUFFER_STATE_DIVERTED, /* Sent to other hardware*/ - MSM_ISP_BUFFER_STATE_DISPATCHED, /* Sent to HAL*/ -}; - -enum msm_isp_buffer_flush_t { - MSM_ISP_BUFFER_FLUSH_DIVERTED, - MSM_ISP_BUFFER_FLUSH_ALL, -}; - -enum msm_isp_buf_mgr_state { - MSM_ISP_BUF_MGR_ATTACH, - MSM_ISP_BUF_MGR_DETACH, -}; - -struct msm_isp_buffer_mapped_info { - unsigned long len; - dma_addr_t paddr; - struct ion_handle *handle; -}; - -struct buffer_cmd { - struct list_head list; - struct msm_isp_buffer_mapped_info *mapped_info; -}; - -struct msm_isp_buffer { - /*Common Data structure*/ - int num_planes; - struct msm_isp_buffer_mapped_info mapped_info[VIDEO_MAX_PLANES]; - int buf_idx; - uint32_t bufq_handle; - uint32_t frame_id; - struct timeval *tv; - - /*Native buffer*/ - struct list_head list; - enum msm_isp_buffer_state state; - - /*Vb2 buffer data*/ - struct vb2_buffer *vb2_buf; - - /*Share buffer cache state*/ - struct list_head share_list; - uint8_t buf_used[ISP_SHARE_BUF_CLIENT]; - uint8_t buf_get_count; - uint8_t buf_put_count; - uint8_t buf_reuse_flag; -}; - -struct msm_isp_bufq { - uint32_t session_id; - uint32_t stream_id; - uint32_t num_bufs; - uint32_t bufq_handle; - enum msm_isp_buf_type buf_type; - struct msm_isp_buffer *bufs; - spinlock_t bufq_lock; - - /*Native buffer queue*/ - struct list_head head; - /*Share buffer cache queue*/ - struct list_head share_head; - uint8_t buf_client_count; -}; - -struct msm_isp_buf_ops { - int (*request_buf)(struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_buf_request *buf_request); - - int (*enqueue_buf)(struct msm_isp_buf_mgr *buf_mgr, - struct msm_isp_qbuf_info *info); - - int (*release_buf)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle); - - int (*get_bufq_handle)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t session_id, uint32_t stream_id); - - int (*get_buf_src)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t *buf_src); - - int (*get_buf)(struct msm_isp_buf_mgr *buf_mgr, uint32_t id, - uint32_t bufq_handle, struct msm_isp_buffer **buf_info); - - int (*get_buf_by_index)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct msm_isp_buffer **buf_info); - - int (*put_buf)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index); - - int (*flush_buf)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, enum msm_isp_buffer_flush_t flush_type); - - int (*buf_done)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct timeval *tv, uint32_t frame_id, uint32_t output_format); - int (*buf_divert)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle, uint32_t buf_index, - struct timeval *tv, uint32_t frame_id); - void (*register_ctx)(struct msm_isp_buf_mgr *buf_mgr, - struct device **iommu_ctx1, struct device **iommu_ctx2, - int num_iommu_ctx1, int num_iommu_ctx2); - int (*buf_mgr_init)(struct msm_isp_buf_mgr *buf_mgr, - const char *ctx_name, uint16_t num_buf_q); - int (*buf_mgr_deinit)(struct msm_isp_buf_mgr *buf_mgr); - int (*buf_mgr_debug)(struct msm_isp_buf_mgr *buf_mgr); - struct msm_isp_bufq * (*get_bufq)(struct msm_isp_buf_mgr *buf_mgr, - uint32_t bufq_handle); -}; - -struct msm_isp_buf_mgr { - int init_done; - uint32_t open_count; - uint32_t pagefault_debug; - spinlock_t lock; - uint16_t num_buf_q; - struct msm_isp_bufq *bufq; - - struct ion_client *client; - struct msm_isp_buf_ops *ops; - uint32_t buf_handle_cnt; - - struct msm_sd_req_vb2_q *vb2_ops; - - /*IOMMU specific*/ - int iommu_domain_num; - struct iommu_domain *iommu_domain; - - /*Add secure domain num and domain */ - int iommu_domain_num_secure; - struct iommu_domain *iommu_domain_secure; - - /*Add secure mode*/ - int secure_enable; - - int num_iommu_ctx; - struct device *iommu_ctx[2]; - struct list_head buffer_q; - int num_iommu_secure_ctx; - struct device *iommu_secure_ctx[2]; - int attach_ref_cnt[MAX_PROTECTION_MODE][MAX_IOMMU_CTX]; - enum msm_isp_buf_mgr_state attach_state; -}; - -int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr, - struct msm_sd_req_vb2_q *vb2_ops, struct msm_iova_layout *iova_layout); - -int msm_isp_proc_buf_cmd(struct msm_isp_buf_mgr *buf_mgr, - unsigned int cmd, void *arg); - -int msm_isp_create_secure_domain(struct msm_isp_buf_mgr *buf_mgr, - struct msm_iova_layout *iova_layout); - -int msm_isp_smmu_attach(struct msm_isp_buf_mgr *buf_mgr, - void *arg); - -#endif /* _MSM_ISP_BUF_H_ */ diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index d64877ca1ed5..63a36a1b2398 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -134,8 +134,6 @@ struct msm_isp_timestamp { }; struct msm_vfe_irq_ops { - void (*read_irq_status_and_clear)(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1); void (*read_irq_status)(struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1); void (*process_reg_update)(struct vfe_device *vfe_dev, @@ -187,7 +185,6 @@ struct msm_vfe_axi_ops { struct msm_vfe_axi_stream *stream_info); void (*clear_wm_irq_mask)(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info); - void (*clear_irq_mask)(struct vfe_device *vfe_dev); void (*cfg_wm_reg)(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info, @@ -448,10 +445,9 @@ struct msm_vfe_axi_stream { uint32_t runtime_num_burst_capture; uint32_t runtime_output_format; - enum msm_stream_rdi_input_type rdi_input_type; + enum msm_stream_memory_input_t memory_input; struct msm_isp_sw_framskip sw_skip; uint8_t sw_ping_pong_bit; - uint8_t sw_sof_ping_pong_bit; }; struct msm_vfe_axi_composite_info { @@ -468,7 +464,6 @@ enum msm_vfe_camif_state { struct msm_vfe_src_info { uint32_t frame_id; - uint32_t session_id; uint32_t reg_update_frame_id; uint8_t active; uint8_t flag; @@ -785,8 +780,6 @@ struct vfe_device { /* before halt irq info */ uint32_t recovery_irq0_mask; uint32_t recovery_irq1_mask; - /* Store the buf_idx for pd stats RDI stream */ - uint8_t pd_buf_idx; uint32_t ms_frame_id; }; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c index 97c34528868e..a0195a934c83 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -12,17 +12,21 @@ #include #include -#include #include "msm_isp32.h" -#include "msm_isp_util_32.h" -#include "msm_isp_axi_util_32.h" -#include "msm_isp_stats_util_32.h" -#include "msm_isp_32.h" +#include "msm_isp_util.h" +#include "msm_isp_axi_util.h" +#include "msm_isp_stats_util.h" +#include "msm_isp.h" #include "msm.h" #include "msm_camera_io_util.h" -#define VFE32_BURST_LEN 3 +static const struct platform_device_id msm_vfe32_dev_id[] = { + {"msm_vfe32", (kernel_ulong_t) &vfe32_hw_info}, + {} +}; + +#define VFE32_BURST_LEN 2 #define VFE32_UB_SIZE 1024 #define VFE32_UB_SIZE_32KB 2048 #define VFE32_EQUAL_SLICE_UB 194 @@ -32,7 +36,7 @@ #define VFE32_XBAR_BASE(idx) (0x40 + 0x4 * (idx / 4)) #define VFE32_XBAR_SHIFT(idx) ((idx % 4) * 8) #define VFE32_PING_PONG_BASE(wm, ping_pong) \ - (VFE32_WM_BASE(wm) + 0x4 * (1 + (~(ping_pong >> wm) & 0x1))) + (VFE32_WM_BASE(wm) + 0x4 * (1 + ((~ping_pong) & 0x1))) static uint8_t stats_pingpong_offset_map[] = { 7, 8, 9, 10, 11, 12, 13}; @@ -56,6 +60,16 @@ static struct msm_cam_clk_info msm_vfe32_2_clk_info[] = { {"csi_vfe_clk", -1}, }; +static uint32_t msm_vfe32_ub_reg_offset(struct vfe_device *vfe_dev, int idx) +{ + return (VFE32_WM_BASE(idx) + 0xC); +} + +static uint32_t msm_vfe32_get_ub_size(struct vfe_device *vfe_dev) +{ + return MSM_ISP32_TOTAL_WM_UB; +} + static int32_t msm_vfe32_init_qos_parms(struct vfe_device *vfe_dev, struct msm_vfe_hw_init_parms *qos_parms, struct msm_vfe_hw_init_parms *ds_parms) @@ -276,6 +290,8 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev) pr_err("%s: vfe ioremap failed\n", __func__); goto vfe_remap_failed; } + vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = + vfe_dev->vfe_base; vfe_dev->vfe_vbif_base = ioremap(vfe_dev->vfe_vbif_mem->start, resource_size(vfe_dev->vfe_vbif_mem)); @@ -320,12 +336,14 @@ static int msm_vfe32_init_hardware(struct vfe_device *vfe_dev) static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev) { + msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x1C); + msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x20); + disable_irq(vfe_dev->vfe_irq->start); free_irq(vfe_dev->vfe_irq->start, vfe_dev); tasklet_kill(&vfe_dev->vfe_tasklet); + msm_isp_flush_tasklet(vfe_dev); iounmap(vfe_dev->vfe_vbif_base); vfe_dev->vfe_vbif_base = NULL; - iounmap(vfe_dev->vfe_base); - vfe_dev->vfe_base = NULL; if (vfe_dev->vfe_clk_idx == 1) msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_1_clk_info, vfe_dev->vfe_clk, @@ -334,6 +352,9 @@ static void msm_vfe32_release_hardware(struct vfe_device *vfe_dev) msm_cam_clk_enable(&vfe_dev->pdev->dev, msm_vfe32_2_clk_info, vfe_dev->vfe_clk, ARRAY_SIZE(msm_vfe32_2_clk_info), 0); + vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL; + iounmap(vfe_dev->vfe_base); + vfe_dev->vfe_base = NULL; kfree(vfe_dev->vfe_clk); regulator_disable(vfe_dev->fs_vfe); msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id); @@ -366,11 +387,6 @@ static void msm_vfe32_init_hardware_reg(struct vfe_device *vfe_dev) msm_camera_io_w_mb(0x1CFFFFFF, vfe_dev->vfe_base + 0x20); msm_camera_io_w(0xFFFFFFFF, vfe_dev->vfe_base + 0x24); msm_camera_io_w_mb(0x1FFFFFFF, vfe_dev->vfe_base + 0x28); - msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x6FC); - msm_camera_io_w(0x10000000, vfe_dev->vfe_base + VFE32_RDI_BASE(1)); - msm_camera_io_w(0x10000000, vfe_dev->vfe_base + VFE32_RDI_BASE(2)); - msm_camera_io_w(0x0, vfe_dev->vfe_base + VFE32_XBAR_BASE(0)); - msm_camera_io_w(0x0, vfe_dev->vfe_base + VFE32_XBAR_BASE(4)); } @@ -386,30 +402,13 @@ static void msm_vfe32_clear_status_reg(struct vfe_device *vfe_dev) static void msm_vfe32_process_reset_irq(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1) { - if (irq_status1 & BIT(23)) { - if (vfe_dev->vfe_reset_timeout_processed == 1) { - pr_err("%s:vfe reset was processed.\n", __func__); - return; - } + if (irq_status1 & BIT(23)) complete(&vfe_dev->reset_complete); - } } static void msm_vfe32_process_halt_irq(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1) { - if (irq_status1 & (1 << 24)) - msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x1D8); -} - -static void msm_vfe32_process_epoch_irq(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts) -{ - if (!(irq_status0 & 0x18)) - return; - if (irq_status0 & (1 << 3)) - msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts); } static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev, @@ -425,10 +424,9 @@ static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev, && vfe_dev->axi_data.src_info[VFE_PIX_0]. pix_stream_count == 0) { msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts); - if (vfe_dev->axi_data.stream_update) - msm_isp_axi_stream_update(vfe_dev, - (1 << VFE_PIX_0)); - msm_isp_update_framedrop_reg(vfe_dev, (1 << VFE_PIX_0)); + if (vfe_dev->axi_data.stream_update[VFE_PIX_0]) + msm_isp_axi_stream_update(vfe_dev, VFE_PIX_0); + msm_isp_update_framedrop_reg(vfe_dev, VFE_PIX_0); } } } @@ -493,20 +491,7 @@ static void msm_vfe32_process_violation_status(struct vfe_device *vfe_dev) static void msm_vfe32_get_overflow_mask(uint32_t *overflow_mask) { - *overflow_mask = 0x003FFF7E; -} - -static void msm_vfe32_get_rdi_wm_mask(struct vfe_device *vfe_dev, - uint32_t *rdi_wm_mask) -{ - *rdi_wm_mask = vfe_dev->axi_data.rdi_wm_mask; -} - -static void msm_vfe32_get_irq_mask(struct vfe_device *vfe_dev, - uint32_t *irq0_mask, uint32_t *irq1_mask) -{ - *irq0_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x1C); - *irq1_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20); + *overflow_mask = 0x0; } static void msm_vfe32_process_error_status(struct vfe_device *vfe_dev) @@ -614,114 +599,104 @@ static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, struct msm_isp_timestamp *ts) { - uint8_t input_src = 0x0; + uint32_t rdi_status; + enum msm_vfe_input_src i; + if (!(irq_status0 & 0x20) && !(irq_status1 & 0x1C000000)) return; if (irq_status0 & BIT(5)) { - msm_isp_notify(vfe_dev, ISP_EVENT_REG_UPDATE, VFE_PIX_0, ts); - input_src |= (1 << VFE_PIX_0); - } - if (irq_status1 & BIT(26)) { - msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_RAW_0, ts); - input_src |= (1 << VFE_RAW_0); - } - if (irq_status1 & BIT(27)) { - msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_RAW_1, ts); - input_src |= (1 << VFE_RAW_1); - } - if (irq_status1 & BIT(28)) { - msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_RAW_2, ts); - input_src |= (1 << VFE_RAW_2); + msm_isp_notify(vfe_dev, ISP_EVENT_SOF, VFE_PIX_0, ts); + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, + VFE_PIX_0); + if (vfe_dev->axi_data.stream_update[VFE_PIX_0]) { + rdi_status = msm_camera_io_r(vfe_dev->vfe_base + + VFE32_XBAR_BASE(0)); + rdi_status |= msm_camera_io_r(vfe_dev->vfe_base + + VFE32_XBAR_BASE(4)); + + if ((rdi_status & BIT(7)) && (!(irq_status0 & 0x20))) + return; + } + if (atomic_read(&vfe_dev->stats_data.stats_update)) + msm_isp_stats_stream_update(vfe_dev); } - if (vfe_dev->axi_data.stream_update) - msm_isp_axi_stream_update(vfe_dev, input_src); - if (atomic_read(&vfe_dev->stats_data.stats_update)) - msm_isp_stats_stream_update(vfe_dev); - if (vfe_dev->axi_data.stream_update || - atomic_read(&vfe_dev->stats_data.stats_update)) { - if (input_src & (1 << VFE_PIX_0)) { - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, (1 << VFE_PIX_0)); + for (i = VFE_RAW_0; i <= VFE_RAW_2; i++) { + if (irq_status1 & BIT(26 + (i - VFE_RAW_0))) { + msm_isp_notify(vfe_dev, ISP_EVENT_SOF, i, ts); + if (vfe_dev->axi_data.stream_update[i]) + msm_isp_axi_stream_update(vfe_dev, i); + msm_isp_update_framedrop_reg(vfe_dev, i); + + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, + i); } } - msm_isp_update_framedrop_reg(vfe_dev, input_src); - msm_isp_update_stats_framedrop_reg(vfe_dev); + msm_isp_update_error_frame_count(vfe_dev); - if ((input_src & (1 << VFE_RAW_0)) || - (input_src & (1 << VFE_RAW_1)) || - (input_src & (1 << VFE_RAW_2))) { - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, input_src); - } return; } -static void msm_vfe32_reg_update( - struct vfe_device *vfe_dev, uint32_t input_src) +static void msm_vfe32_process_epoch_irq(struct vfe_device *vfe_dev, + uint32_t irq_status0, uint32_t irq_status1, + struct msm_isp_timestamp *ts) { - msm_camera_io_w_mb(input_src, vfe_dev->vfe_base + 0x260); + /* Not supported */ } -static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev, - uint32_t first_start, uint32_t blocking) +static void msm_vfe32_reg_update(struct vfe_device *vfe_dev, + enum msm_vfe_input_src frame_src) { - long rc = 0; - uint32_t irq_status1; - - if (blocking) { - init_completion(&vfe_dev->reset_complete); - msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4); - vfe_dev->vfe_reset_timeout_processed = 0; - rc = wait_for_completion_timeout( - &vfe_dev->reset_complete, msecs_to_jiffies(500)); - } else { - msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4); + if (vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) { + msm_camera_io_w_mb(0xF, + vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + + 0x260); + msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260); + } else if (!vfe_dev->is_split) { + msm_camera_io_w_mb(0xF, vfe_dev->vfe_base + 0x260); } +} - if (blocking && rc <= 0) { - /*read ISP status register*/ - irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x30); - pr_err("%s: handling vfe reset time out error. irq_status1 0x%x\n", - __func__, irq_status1); - if (irq_status1 & BIT(23)) { - pr_err("%s: vfe reset has done actually\n", __func__); - vfe_dev->vfe_reset_timeout_processed = 1; - return 1; - } - } - return rc; +static long msm_vfe32_reset_hardware(struct vfe_device *vfe_dev, + uint32_t first_start, uint32_t blocking) +{ + init_completion(&vfe_dev->reset_complete); + msm_camera_io_w_mb(0x3FF, vfe_dev->vfe_base + 0x4); + return wait_for_completion_timeout( + &vfe_dev->reset_complete, msecs_to_jiffies(50)); } static void msm_vfe32_axi_reload_wm( - struct vfe_device *vfe_dev, uint32_t reload_mask) + struct vfe_device *vfe_dev, void __iomem *vfe_base, + uint32_t reload_mask) { if (!vfe_dev->pdev->dev.of_node) { /*vfe32 A-family: 8960*/ - msm_camera_io_w_mb(reload_mask, vfe_dev->vfe_base + 0x38); + msm_camera_io_w_mb(reload_mask, vfe_base + 0x38); } else { /*vfe32 B-family: 8610*/ - msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x28); - msm_camera_io_w(0x1C800000, vfe_dev->vfe_base + 0x20); - msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x18); - msm_camera_io_w(0x9AAAAAAA , vfe_dev->vfe_base + 0x600); - msm_camera_io_w(reload_mask, vfe_dev->vfe_base + 0x38); + msm_camera_io_w(0x0, vfe_base + 0x24); + msm_camera_io_w(0x0, vfe_base + 0x28); + msm_camera_io_w(0x0, vfe_base + 0x20); + msm_camera_io_w_mb(0x1, vfe_base + 0x18); + msm_camera_io_w(0x9AAAAAAA , vfe_base + 0x600); + msm_camera_io_w(reload_mask, vfe_base + 0x38); } } -static void msm_vfe32_axi_enable_wm(struct vfe_device *vfe_dev, +static void msm_vfe32_axi_enable_wm(void __iomem *vfe_base, uint8_t wm_idx, uint8_t enable) { uint32_t val = msm_camera_io_r( - vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx)); + vfe_base + VFE32_WM_BASE(wm_idx)); if (enable) val |= 0x1; else val &= ~0x1; msm_camera_io_w_mb(val, - vfe_dev->vfe_base + VFE32_WM_BASE(wm_idx)); + vfe_base + VFE32_WM_BASE(wm_idx)); } static void msm_vfe32_axi_cfg_comp_mask(struct vfe_device *vfe_dev, @@ -776,34 +751,22 @@ static void msm_vfe32_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, msm_camera_io_w(irq_mask, vfe_dev->vfe_base + 0x1C); } -static void msm_vfe32_cfg_framedrop(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) +static void msm_vfe32_cfg_framedrop(void __iomem *vfe_base, + struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern, + uint32_t framedrop_period) { - uint32_t framedrop_pattern = 0, framedrop_period = 0; - - if (stream_info->runtime_init_frame_drop == 0) { - framedrop_pattern = stream_info->framedrop_pattern; - framedrop_period = stream_info->framedrop_period; - } - - if (stream_info->stream_type == BURST_STREAM && - stream_info->runtime_burst_frame_count == 0) { - framedrop_pattern = 0; - framedrop_period = 0; - } - if (stream_info->stream_src == PIX_ENCODER) { - msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x504); - msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x508); - msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x50C); - msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x510); + msm_camera_io_w(framedrop_period - 1, vfe_base + 0x504); + msm_camera_io_w(framedrop_period - 1, vfe_base + 0x508); + msm_camera_io_w(framedrop_pattern, vfe_base + 0x50C); + msm_camera_io_w(framedrop_pattern, vfe_base + 0x510); } else if (stream_info->stream_src == PIX_VIEWFINDER) { - msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x514); - msm_camera_io_w(framedrop_period, vfe_dev->vfe_base + 0x518); - msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x51C); - msm_camera_io_w(framedrop_pattern, vfe_dev->vfe_base + 0x520); + msm_camera_io_w(framedrop_period - 1, vfe_base + 0x514); + msm_camera_io_w(framedrop_period - 1, vfe_base + 0x518); + msm_camera_io_w(framedrop_pattern, vfe_base + 0x51C); + msm_camera_io_w(framedrop_pattern, vfe_base + 0x520); } - msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x260); + msm_camera_io_w_mb(0x1, vfe_base + 0x260); } static void msm_vfe32_clear_framedrop(struct vfe_device *vfe_dev, @@ -967,9 +930,9 @@ static void msm_vfe32_update_camif_state( if (update_state == ENABLE_CAMIF) { val = msm_camera_io_r(vfe_dev->vfe_base + 0x1C); - val |= 0x19; + val |= 0x1; msm_camera_io_w_mb(val, vfe_dev->vfe_base + 0x1C); - msm_camera_io_w_mb(0xA, vfe_dev->vfe_base + 0x200); + val = msm_camera_io_r(vfe_dev->vfe_base + 0x1E4); bus_en = ((vfe_dev->axi_data.src_info[ @@ -980,7 +943,6 @@ static void msm_vfe32_update_camif_state( val &= 0xFFFFFF3F; val = val | bus_en << 7 | vfe_en << 6; msm_camera_io_w(val, vfe_dev->vfe_base + 0x1E4); - msm_camera_io_w_mb(0x4, vfe_dev->vfe_base + 0x1E0); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1E0); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1; } else if (update_state == DISABLE_CAMIF) { @@ -1061,8 +1023,6 @@ static void msm_vfe32_axi_clear_wm_reg( { uint32_t val = 0; uint32_t wm_base = VFE32_WM_BASE(stream_info->wm[plane_idx]); - /* FRAME BASED */ - msm_camera_io_w(val, vfe_dev->vfe_base + wm_base); /*WR_IMAGE_SIZE*/ msm_camera_io_w(val, vfe_dev->vfe_base + wm_base + 0x10); /*WR_BUFFER_CFG*/ @@ -1138,94 +1098,20 @@ static void msm_vfe32_axi_clear_wm_xbar_reg( msm_camera_io_w(xbar_reg_cfg, vfe_dev->vfe_base + VFE32_XBAR_BASE(wm)); } -static void msm_vfe32_cfg_axi_ub_equal_default(struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint32_t total_image_size = 0; - uint32_t num_used_wms = 0; - uint32_t prop_size = 0; - uint32_t wm_ub_size; - uint64_t delta; - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i] > 0) { - num_used_wms++; - total_image_size += axi_data->wm_image_size[i]; - } - } - prop_size = MSM_ISP32_TOTAL_WM_UB - - axi_data->hw_info->min_wm_ub * num_used_wms; - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (axi_data->free_wm[i]) { - delta = - (uint64_t)(axi_data->wm_image_size[i] * - prop_size); - do_div(delta, total_image_size); - wm_ub_size = axi_data->hw_info->min_wm_ub + - (uint32_t)delta; - msm_camera_io_w(ub_offset << 16 | - (wm_ub_size - 1), vfe_dev->vfe_base + - VFE32_WM_BASE(i) + 0xC); - ub_offset += wm_ub_size; - } else { - msm_camera_io_w(0, - vfe_dev->vfe_base + VFE32_WM_BASE(i) + 0xC); - } - } -} - -static void msm_vfe32_cfg_axi_ub_equal_slicing(struct vfe_device *vfe_dev) -{ - int i; - uint32_t ub_offset = 0; - uint32_t final_ub_slice_size; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (ub_offset + VFE32_EQUAL_SLICE_UB > VFE32_AXI_SLICE_UB) { - final_ub_slice_size = VFE32_AXI_SLICE_UB - ub_offset; - msm_camera_io_w(ub_offset << 16 | - (final_ub_slice_size - 1), vfe_dev->vfe_base + - VFE32_WM_BASE(i) + 0xC); - ub_offset += final_ub_slice_size; - } else { - msm_camera_io_w(ub_offset << 16 | - (VFE32_EQUAL_SLICE_UB - 1), vfe_dev->vfe_base + - VFE32_WM_BASE(i) + 0xC); - ub_offset += VFE32_EQUAL_SLICE_UB; - } - } -} - -static void msm_vfe32_cfg_axi_ub(struct vfe_device *vfe_dev) -{ - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT; - if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) - msm_vfe32_cfg_axi_ub_equal_slicing(vfe_dev); - else - msm_vfe32_cfg_axi_ub_equal_default(vfe_dev); -} - -static void msm_vfe32_update_ping_pong_addr(struct vfe_device *vfe_dev, - uint8_t wm_idx, uint32_t pingpong_status, dma_addr_t paddr) +static void msm_vfe32_update_ping_pong_addr(void __iomem *vfe_base, + uint8_t wm_idx, uint32_t pingpong_bit, dma_addr_t paddr, + int32_t buf_size) { uint32_t paddr32 = (paddr & 0xFFFFFFFF); - msm_camera_io_w(paddr32, vfe_dev->vfe_base + - VFE32_PING_PONG_BASE(wm_idx, pingpong_status)); + msm_camera_io_w(paddr32, vfe_base + + VFE32_PING_PONG_BASE(wm_idx, pingpong_bit)); } static int msm_vfe32_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { + uint32_t halt_mask; uint32_t axi_busy_flag = true; - /* Keep only halt and restart mask */ - msm_camera_io_w(0x01800000, vfe_dev->vfe_base + 0x20); - /*Clear IRQ Status */ - msm_camera_io_w(0xFE7FFFFF, vfe_dev->vfe_base + 0x28); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8); while (axi_busy_flag) { if (msm_camera_io_r( @@ -1233,27 +1119,10 @@ static int msm_vfe32_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) axi_busy_flag = false; } msm_camera_io_w_mb(0, vfe_dev->vfe_base + 0x1D8); - return 0; -} - -static int msm_vfe32_axi_restart(struct vfe_device *vfe_dev, - uint32_t blocking, uint32_t enable_camif) -{ - vfe_dev->hw_info->vfe_ops.core_ops.restore_irq_mask(vfe_dev); - - /*Clear IRQ Status */ - msm_camera_io_w(0xFE7FFFFF, vfe_dev->vfe_base + 0x28); - msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x1D8); - msm_camera_io_w_mb(0xA, vfe_dev->vfe_base + 0x200); - /* Start AXI */ - msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x1D8); - vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, 0xF); - memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); - atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - if (enable_camif) { - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, ENABLE_CAMIF); - } + halt_mask = msm_camera_io_r(vfe_dev->vfe_base + 0x20); + halt_mask &= 0xFEFFFFFF; + /* Disable AXI IRQ */ + msm_camera_io_w_mb(halt_mask, vfe_dev->vfe_base + 0x20); return 0; } @@ -1307,24 +1176,8 @@ static int msm_vfe32_stats_check_streams( } static void msm_vfe32_stats_cfg_comp_mask(struct vfe_device *vfe_dev, - uint32_t stats_mask, uint8_t enable) + uint32_t stats_mask, uint8_t comp_idx, uint8_t enable) { - uint32_t i = 0; - atomic_t *stats_comp; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - - stats_mask = stats_mask & 0x7F; - - for (i = 0; - i < vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; i++) { - stats_comp = &stats_data->stats_comp_mask[i]; - if (enable) - atomic_add(stats_mask, stats_comp); - else - atomic_sub(stats_mask, stats_comp); - ISP_DBG("%s: comp_mask: %x\n", - __func__, atomic_read(&stats_data->stats_comp_mask[i])); - } return; } @@ -1387,6 +1240,12 @@ static void msm_vfe32_stats_cfg_ub(struct vfe_device *vfe_dev) return; } +static bool msm_vfe32_is_module_cfg_lock_needed( + uint32_t reg_offset) +{ + return false; +} + static void msm_vfe32_stats_enable_module(struct vfe_device *vfe_dev, uint32_t stats_mask, uint8_t enable) { @@ -1424,13 +1283,13 @@ static void msm_vfe32_stats_enable_module(struct vfe_device *vfe_dev, msm_camera_io_w(module_cfg, vfe_dev->vfe_base + 0x10); } -static void msm_vfe32_stats_update_ping_pong_addr(struct vfe_device *vfe_dev, +static void msm_vfe32_stats_update_ping_pong_addr(void __iomem *vfe_base, struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status, dma_addr_t paddr) { uint32_t paddr32 = (paddr & 0xFFFFFFFF); int stats_idx = STATS_IDX(stream_info->stream_handle); - msm_camera_io_w(paddr32, vfe_dev->vfe_base + + msm_camera_io_w(paddr32, vfe_base + VFE32_STATS_PING_PONG_BASE(stats_idx, pingpong_status)); } @@ -1521,27 +1380,13 @@ static void msm_vfe32_get_error_mask(uint32_t *error_mask0, *error_mask1 = 0x007FFFFF; } - -static void msm_vfe32_restore_irq_mask(struct vfe_device *vfe_dev) -{ - msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask0, - vfe_dev->vfe_base + 0x1C); - msm_camera_io_w(vfe_dev->error_info.overflow_recover_irq_mask1, - vfe_dev->vfe_base + 0x20); -} - -static void msm_vfe32_get_halt_restart_mask(uint32_t *irq0_mask, - uint32_t *irq1_mask) -{ - *irq1_mask = 0x01800000; -} - struct msm_vfe_axi_hardware_info msm_vfe32_axi_hw_info = { - .num_wm = 6, + .num_wm = 5, .num_comp_mask = 3, .num_rdi = 3, .num_rdi_master = 3, .min_wm_ub = 64, + .scratch_buf_range = SZ_32M, }; static struct msm_vfe_stats_hardware_info msm_vfe32_stats_hw_info = { @@ -1553,22 +1398,7 @@ static struct msm_vfe_stats_hardware_info msm_vfe32_stats_hw_info = { 1 << MSM_ISP_STATS_SKIN | 1 << MSM_ISP_STATS_BHIST, .stats_ping_pong_offset = stats_pingpong_offset_map, .num_stats_type = VFE32_NUM_STATS_TYPE, - .num_stats_comp_mask = 1, -}; - -static struct v4l2_subdev_core_ops msm_vfe32_subdev_core_ops = { - .ioctl = msm_isp_ioctl, - .subscribe_event = msm_isp_subscribe_event, - .unsubscribe_event = msm_isp_unsubscribe_event, -}; - -static struct v4l2_subdev_ops msm_vfe32_subdev_ops = { - .core = &msm_vfe32_subdev_core_ops, -}; - -static struct v4l2_subdev_internal_ops msm_vfe32_internal_ops = { - .open = msm_isp_open_node, - .close = msm_isp_close_node, + .num_stats_comp_mask = 0, }; struct msm_vfe_hardware_info vfe32_hw_info = { @@ -1582,9 +1412,9 @@ struct msm_vfe_hardware_info vfe32_hw_info = { .process_reset_irq = msm_vfe32_process_reset_irq, .process_halt_irq = msm_vfe32_process_halt_irq, .process_reg_update = msm_vfe32_process_reg_update, - .process_epoch_irq = msm_vfe32_process_epoch_irq, .process_axi_irq = msm_isp_process_axi_irq, .process_stats_irq = msm_isp_process_stats_irq, + .process_epoch_irq = msm_vfe32_process_epoch_irq, }, .axi_ops = { .reload_wm = msm_vfe32_axi_reload_wm, @@ -1600,14 +1430,15 @@ struct msm_vfe_hardware_info vfe32_hw_info = { .clear_wm_reg = msm_vfe32_axi_clear_wm_reg, .cfg_wm_xbar_reg = msm_vfe32_axi_cfg_wm_xbar_reg, .clear_wm_xbar_reg = msm_vfe32_axi_clear_wm_xbar_reg, - .cfg_ub = msm_vfe32_cfg_axi_ub, + .cfg_ub = msm_vfe47_cfg_axi_ub, .update_ping_pong_addr = msm_vfe32_update_ping_pong_addr, .get_comp_mask = msm_vfe32_get_comp_mask, .get_wm_mask = msm_vfe32_get_wm_mask, .get_pingpong_status = msm_vfe32_get_pingpong_status, .halt = msm_vfe32_axi_halt, - .restart = msm_vfe32_axi_restart, + .ub_reg_offset = msm_vfe32_ub_reg_offset, + .get_ub_size = msm_vfe32_get_ub_size, }, .core_ops = { .reg_update = msm_vfe32_reg_update, @@ -1622,13 +1453,11 @@ struct msm_vfe_hardware_info vfe32_hw_info = { .release_hw = msm_vfe32_release_hardware, .get_platform_data = msm_vfe32_get_platform_data, .get_error_mask = msm_vfe32_get_error_mask, - .get_overflow_mask = msm_vfe32_get_overflow_mask, - .get_rdi_wm_mask = msm_vfe32_get_rdi_wm_mask, - .get_irq_mask = msm_vfe32_get_irq_mask, - .restore_irq_mask = msm_vfe32_restore_irq_mask, - .get_halt_restart_mask = - msm_vfe32_get_halt_restart_mask, .process_error_status = msm_vfe32_process_error_status, + .get_overflow_mask = msm_vfe32_get_overflow_mask, + .is_module_cfg_lock_needed = + msm_vfe32_is_module_cfg_lock_needed, + .ahb_clk_cfg = NULL, }, .stats_ops = { .get_stats_idx = msm_vfe32_get_stats_idx, @@ -1646,12 +1475,47 @@ struct msm_vfe_hardware_info vfe32_hw_info = { .get_wm_mask = msm_vfe32_stats_get_wm_mask, .get_frame_id = msm_vfe32_stats_get_frame_id, .get_pingpong_status = msm_vfe32_get_pingpong_status, + .enable_stats_wm = NULL, }, }, .dmi_reg_offset = 0x5A0, .axi_hw_info = &msm_vfe32_axi_hw_info, .stats_hw_info = &msm_vfe32_stats_hw_info, - .subdev_ops = &msm_vfe32_subdev_ops, - .subdev_internal_ops = &msm_vfe32_internal_ops, }; EXPORT_SYMBOL(vfe32_hw_info); + +static const struct of_device_id msm_vfe32_dt_match[] = { + { + .compatible = "qcom,vfe32", + .data = &vfe32_hw_info, + }, + {} +}; + +MODULE_DEVICE_TABLE(of, msm_vfe32_dt_match); + +static struct platform_driver vfe32_driver = { + .probe = vfe_hw_probe, + .driver = { + .name = "msm_vfe32", + .owner = THIS_MODULE, + .of_match_table = msm_vfe32_dt_match, + }, + .id_table = msm_vfe32_dev_id, +}; + +static int __init msm_vfe32_init_module(void) +{ + return platform_driver_register(&vfe32_driver); +} + +static void __exit msm_vfe32_exit_module(void) +{ + platform_driver_unregister(&vfe32_driver); +} + +module_init(msm_vfe32_init_module); +module_exit(msm_vfe32_exit_module); +MODULE_DESCRIPTION("MSM VFE32 driver"); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 299c576fb5bc..3af953e26897 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -571,7 +571,7 @@ static void msm_vfe40_process_error_status(struct vfe_device *vfe_dev) msm_isp_update_last_overflow_ab_ib(vfe_dev); } -static void msm_vfe40_read_irq_status_and_clear(struct vfe_device *vfe_dev, +static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1) { *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38); @@ -609,13 +609,6 @@ static void msm_vfe40_read_irq_status_and_clear(struct vfe_device *vfe_dev, } -static void msm_vfe40_read_irq_status(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1) -{ - *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38); - *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C); -} - static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, struct msm_isp_timestamp *ts) @@ -717,12 +710,6 @@ static void msm_vfe40_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { - if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { - pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); - spin_unlock_irqrestore(&vfe_dev->reg_update_lock, - flags); - return; - } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + 0x378); @@ -868,12 +855,6 @@ static void msm_vfe40_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, MSM_ISP_IRQ_DISABLE); } -static void msm_vfe40_axi_clear_irq_mask(struct vfe_device *vfe_dev) -{ - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x28); - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C); -} - static void msm_vfe40_cfg_framedrop(void __iomem *vfe_base, struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern, uint32_t framedrop_period) @@ -1793,18 +1774,11 @@ static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev, memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - if (enable_camif && - vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux - != EXTERNAL_READ){ + if (enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, ENABLE_CAMIF); } - if (vfe_dev->fetch_engine_info.is_busy == 1) { - vfe_dev->fetch_engine_info.is_busy = 0; - msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x378); - msm_camera_io_w_mb(0x10000, vfe_dev->vfe_base + 0x4C); - msm_camera_io_w_mb(0x20000, vfe_dev->vfe_base + 0x4C); - } + return 0; } @@ -2202,8 +2176,6 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .vfe_ops = { .irq_ops = { .read_irq_status = msm_vfe40_read_irq_status, - .read_irq_status_and_clear = - msm_vfe40_read_irq_status_and_clear, .process_camif_irq = msm_vfe40_process_input_irq, .process_reset_irq = msm_vfe40_process_reset_irq, .process_halt_irq = msm_vfe40_process_halt_irq, @@ -2223,8 +2195,6 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .clear_comp_mask = msm_vfe40_axi_clear_comp_mask, .cfg_wm_irq_mask = msm_vfe40_axi_cfg_wm_irq_mask, .clear_wm_irq_mask = msm_vfe40_axi_clear_wm_irq_mask, - .clear_irq_mask = - msm_vfe40_axi_clear_irq_mask, .cfg_framedrop = msm_vfe40_cfg_framedrop, .clear_framedrop = msm_vfe40_clear_framedrop, .cfg_wm_reg = msm_vfe40_axi_cfg_wm_reg, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c index 090a5a6584ef..e422d35a2e48 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -397,7 +397,7 @@ static void msm_vfe44_process_error_status(struct vfe_device *vfe_dev) } } -static void msm_vfe44_read_irq_status_and_clear(struct vfe_device *vfe_dev, +static void msm_vfe44_read_irq_status(struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1) { *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38); @@ -425,13 +425,6 @@ static void msm_vfe44_read_irq_status_and_clear(struct vfe_device *vfe_dev, } -static void msm_vfe44_read_irq_status(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1) -{ - *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x38); - *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x3C); -} - static void msm_vfe44_process_reg_update(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, struct msm_isp_timestamp *ts) @@ -558,12 +551,6 @@ static void msm_vfe44_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { - if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { - pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); - spin_unlock_irqrestore(&vfe_dev->reg_update_lock, - flags); - return; - } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + 0x378); @@ -689,12 +676,6 @@ static void msm_vfe44_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, MSM_ISP_IRQ_DISABLE); } -static void msm_vfe44_axi_clear_irq_mask(struct vfe_device *vfe_dev) -{ - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x28); - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x2C); -} - static void msm_vfe44_cfg_framedrop(void __iomem *vfe_base, struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern, uint32_t framedrop_period) @@ -1791,8 +1772,6 @@ struct msm_vfe_hardware_info vfe44_hw_info = { .vfe_ops = { .irq_ops = { .read_irq_status = msm_vfe44_read_irq_status, - .read_irq_status_and_clear = - msm_vfe44_read_irq_status_and_clear, .process_camif_irq = msm_vfe44_process_input_irq, .process_reset_irq = msm_vfe44_process_reset_irq, .process_halt_irq = msm_vfe44_process_halt_irq, @@ -1812,8 +1791,6 @@ struct msm_vfe_hardware_info vfe44_hw_info = { .clear_comp_mask = msm_vfe44_axi_clear_comp_mask, .cfg_wm_irq_mask = msm_vfe44_axi_cfg_wm_irq_mask, .clear_wm_irq_mask = msm_vfe44_axi_clear_wm_irq_mask, - .clear_irq_mask = - msm_vfe44_axi_clear_irq_mask, .cfg_framedrop = msm_vfe44_cfg_framedrop, .clear_framedrop = msm_vfe44_clear_framedrop, .cfg_wm_reg = msm_vfe44_axi_cfg_wm_reg, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c index eae645b93bef..7217dedd9292 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -341,7 +341,7 @@ static void msm_vfe46_process_error_status(struct vfe_device *vfe_dev) pr_err("%s: status bf scale bus overflow\n", __func__); } -static void msm_vfe46_read_irq_status_and_clear(struct vfe_device *vfe_dev, +static void msm_vfe46_read_irq_status(struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1) { *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C); @@ -365,13 +365,6 @@ static void msm_vfe46_read_irq_status_and_clear(struct vfe_device *vfe_dev, } -static void msm_vfe46_read_irq_status(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1) -{ - *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C); - *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70); -} - static void msm_vfe46_process_reg_update(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, struct msm_isp_timestamp *ts) @@ -498,12 +491,6 @@ static void msm_vfe46_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { - if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { - pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); - spin_unlock_irqrestore(&vfe_dev->reg_update_lock, - flags); - return; - } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] + 0x3D8); @@ -630,12 +617,6 @@ static void msm_vfe46_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, MSM_ISP_IRQ_DISABLE); } -static void msm_vfe46_axi_clear_irq_mask(struct vfe_device *vfe_dev) -{ - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x5C); - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); -} - static void msm_vfe46_cfg_framedrop(void __iomem *vfe_base, struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern, uint32_t framedrop_period) @@ -1879,8 +1860,6 @@ struct msm_vfe_hardware_info vfe46_hw_info = { .vfe_ops = { .irq_ops = { .read_irq_status = msm_vfe46_read_irq_status, - .read_irq_status_and_clear = - msm_vfe46_read_irq_status_and_clear, .process_camif_irq = msm_vfe46_process_input_irq, .process_reset_irq = msm_vfe46_process_reset_irq, .process_halt_irq = msm_vfe46_process_halt_irq, @@ -1900,8 +1879,6 @@ struct msm_vfe_hardware_info vfe46_hw_info = { .clear_comp_mask = msm_vfe46_axi_clear_comp_mask, .cfg_wm_irq_mask = msm_vfe46_axi_cfg_wm_irq_mask, .clear_wm_irq_mask = msm_vfe46_axi_clear_wm_irq_mask, - .clear_irq_mask = - msm_vfe46_axi_clear_irq_mask, .cfg_framedrop = msm_vfe46_cfg_framedrop, .clear_framedrop = msm_vfe46_clear_framedrop, .cfg_wm_reg = msm_vfe46_axi_cfg_wm_reg, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 7bb003b66def..8bc46c8b3f56 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -53,10 +53,8 @@ #ifdef CONFIG_MSM_CAMERA_AUTOMOTIVE #define UB_CFG_POLICY MSM_WM_UB_EQUAL_SLICING -#define VFE47_NUM_WM 4 #else #define UB_CFG_POLICY MSM_WM_UB_CFG_DEFAULT -#define VFE47_NUM_WM 7 #endif static uint32_t stats_base_addr[] = { @@ -550,7 +548,7 @@ void msm_vfe47_process_error_status(struct vfe_device *vfe_dev) pr_err("%s: status dsp error\n", __func__); } -void msm_vfe47_read_irq_status_and_clear(struct vfe_device *vfe_dev, +void msm_vfe47_read_irq_status(struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1) { *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C); @@ -575,13 +573,6 @@ void msm_vfe47_read_irq_status_and_clear(struct vfe_device *vfe_dev, } -void msm_vfe47_read_irq_status(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1) -{ - *irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C); - *irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70); -} - void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, struct msm_isp_timestamp *ts) @@ -714,12 +705,6 @@ void msm_vfe47_reg_update(struct vfe_device *vfe_dev, vfe_dev->reg_update_requested; if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { - if (!vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0]) { - pr_err("%s vfe_base for ISP_VFE0 is NULL\n", __func__); - spin_unlock_irqrestore(&vfe_dev->reg_update_lock, - flags); - return; - } msm_camera_io_w_mb(update_mask, vfe_dev->common_data->dual_vfe_res-> vfe_base[ISP_VFE0] + 0x4AC); @@ -856,12 +841,6 @@ void msm_vfe47_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, MSM_ISP_IRQ_DISABLE); } -void msm_vfe47_axi_clear_irq_mask(struct vfe_device *vfe_dev) -{ - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x5C); - msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); -} - void msm_vfe47_cfg_framedrop(void __iomem *vfe_base, struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern, uint32_t framedrop_period) @@ -1789,7 +1768,7 @@ void msm_vfe47_cfg_axi_ub(struct vfe_device *vfe_dev, { struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - axi_data->wm_ub_cfg_policy = UB_CFG_POLICY; + axi_data->wm_ub_cfg_policy = MSM_WM_UB_CFG_DEFAULT; if (axi_data->wm_ub_cfg_policy == MSM_WM_UB_EQUAL_SLICING) msm_vfe47_cfg_axi_ub_equal_slicing(vfe_dev); else @@ -2707,7 +2686,7 @@ void msm_vfe47_get_halt_restart_mask(uint32_t *irq0_mask, } static struct msm_vfe_axi_hardware_info msm_vfe47_axi_hw_info = { - .num_wm = VFE47_NUM_WM, + .num_wm = 7, .num_comp_mask = 3, .num_rdi = 3, .num_rdi_master = 3, @@ -2737,8 +2716,6 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .vfe_ops = { .irq_ops = { .read_irq_status = msm_vfe47_read_irq_status, - .read_irq_status_and_clear = - msm_vfe47_read_irq_status_and_clear, .process_camif_irq = msm_vfe47_process_input_irq, .process_reset_irq = msm_vfe47_process_reset_irq, .process_halt_irq = msm_vfe47_process_halt_irq, @@ -2758,8 +2735,6 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .clear_comp_mask = msm_vfe47_axi_clear_comp_mask, .cfg_wm_irq_mask = msm_vfe47_axi_cfg_wm_irq_mask, .clear_wm_irq_mask = msm_vfe47_axi_clear_wm_irq_mask, - .clear_irq_mask = - msm_vfe47_axi_clear_irq_mask, .cfg_framedrop = msm_vfe47_cfg_framedrop, .clear_framedrop = msm_vfe47_clear_framedrop, .cfg_wm_reg = msm_vfe47_axi_cfg_wm_reg, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h index aa23a87e2554..282808250193 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.h @@ -32,8 +32,6 @@ extern struct msm_vfe_hardware_info vfe47_hw_info; void msm_vfe47_read_irq_status(struct vfe_device *vfe_dev, uint32_t *irq_status0, uint32_t *irq_status1); -void msm_vfe47_read_irq_status_and_clear(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1); void msm_vfe47_enable_camif_error(struct vfe_device *vfe_dev, int enable); void msm_vfe47_process_reg_update(struct vfe_device *vfe_dev, @@ -60,7 +58,6 @@ void msm_vfe47_axi_cfg_wm_irq_mask(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info); void msm_vfe47_axi_clear_wm_irq_mask(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info); -void msm_vfe47_axi_clear_irq_mask(struct vfe_device *vfe_dev); void msm_vfe47_cfg_framedrop(void __iomem *vfe_base, struct msm_vfe_axi_stream *stream_info, uint32_t framedrop_pattern, uint32_t framedrop_period); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c index 67978a2b7607..8f058a86b615 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp48.c @@ -227,8 +227,6 @@ struct msm_vfe_hardware_info vfe48_hw_info = { .vfe_ops = { .irq_ops = { .read_irq_status = msm_vfe47_read_irq_status, - .read_irq_status_and_clear = - msm_vfe47_read_irq_status_and_clear, .process_camif_irq = msm_vfe47_process_input_irq, .process_reset_irq = msm_vfe47_process_reset_irq, .process_halt_irq = msm_vfe47_process_halt_irq, @@ -248,8 +246,6 @@ struct msm_vfe_hardware_info vfe48_hw_info = { .clear_comp_mask = msm_vfe47_axi_clear_comp_mask, .cfg_wm_irq_mask = msm_vfe47_axi_cfg_wm_irq_mask, .clear_wm_irq_mask = msm_vfe47_axi_clear_wm_irq_mask, - .clear_irq_mask = - msm_vfe47_axi_clear_irq_mask, .cfg_framedrop = msm_vfe47_cfg_framedrop, .clear_framedrop = msm_vfe47_clear_framedrop, .cfg_wm_reg = msm_vfe47_axi_cfg_wm_reg, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_32.c deleted file mode 100644 index 550dc978dc4a..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_32.c +++ /dev/null @@ -1,594 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_isp_32.h" -#include "msm_isp_util_32.h" -#include "msm_isp_axi_util_32.h" -#include "msm_isp_stats_util_32.h" -#include "msm_sd.h" -#include "msm_isp32.h" - -static struct msm_sd_req_vb2_q vfe_vb2_ops; - -static const struct of_device_id msm_vfe_dt_match[] = { - { - .compatible = "qcom,vfe32", - .data = &vfe32_hw_info, - }, - {} -}; - -MODULE_DEVICE_TABLE(of, msm_vfe_dt_match); - -static const struct platform_device_id msm_vfe_dev_id[] = { - {"msm_vfe32", (kernel_ulong_t) &vfe32_hw_info}, - {} -}; -#define MAX_OVERFLOW_COUNTERS 29 -#define OVERFLOW_LENGTH 1024 -#define OVERFLOW_BUFFER_LENGTH 64 -static char stat_line[OVERFLOW_LENGTH]; - -static struct msm_isp_buf_mgr vfe_buf_mgr; -struct msm_isp_statistics stats; -struct msm_isp_ub_info ub_info; -static int msm_isp_enable_debugfs(struct vfe_device *vfe_dev, - struct msm_isp_bw_req_info *isp_req_hist); -static char *stats_str[MAX_OVERFLOW_COUNTERS] = { - "imgmaster0_overflow_cnt", - "imgmaster1_overflow_cnt", - "imgmaster2_overflow_cnt", - "imgmaster3_overflow_cnt", - "imgmaster4_overflow_cnt", - "imgmaster5_overflow_cnt", - "imgmaster6_overflow_cnt", - "be_overflow_cnt", - "bg_overflow_cnt", - "bf_overflow_cnt", - "awb_overflow_cnt", - "rs_overflow_cnt", - "cs_overflow_cnt", - "ihist_overflow_cnt", - "skinbhist_overflow_cnt", - "bfscale_overflow_cnt", - "ISP_VFE0_client_info.active", - "ISP_VFE0_client_info.ab", - "ISP_VFE0_client_info.ib", - "ISP_VFE1_client_info.active", - "ISP_VFE1_client_info.ab", - "ISP_VFE1_client_info.ib", - "ISP_CPP_client_info.active", - "ISP_CPP_client_info.ab", - "ISP_CPP_client_info.ib", - "ISP_last_overflow.ab", - "ISP_last_overflow.ib", - "ISP_VFE_CLK_RATE", - "ISP_CPP_CLK_RATE", -}; - -#define MAX_DEPTH_BW_REQ_HISTORY 25 -#define MAX_BW_HISTORY_BUFF_LEN 6144 -#define MAX_BW_HISTORY_LINE_BUFF_LEN 512 - -#define MAX_UB_INFO_BUFF_LEN 1024 -#define MAX_UB_INFO_LINE_BUFF_LEN 256 - -static struct msm_isp_bw_req_info - msm_isp_bw_request_history[MAX_DEPTH_BW_REQ_HISTORY]; -static int msm_isp_bw_request_history_idx; -static char bw_request_history_buff[MAX_BW_HISTORY_BUFF_LEN]; -static char ub_info_buffer[MAX_UB_INFO_BUFF_LEN]; -static spinlock_t req_history_lock; -static int vfe_debugfs_statistics_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t vfe_debugfs_statistics_read(struct file *t_file, char *t_char, - size_t t_size_t, loff_t *t_loff_t) -{ - int i; - uint64_t *ptr; - char buffer[OVERFLOW_BUFFER_LENGTH] = {0}; - struct vfe_device *vfe_dev = (struct vfe_device *) - t_file->private_data; - struct msm_isp_statistics *stats = vfe_dev->stats; - - memset(stat_line, 0, sizeof(stat_line)); - msm_isp_util_get_bandwidth_stats(vfe_dev, stats); - ptr = (uint64_t *)(stats); - for (i = 0; i < MAX_OVERFLOW_COUNTERS; i++) { - strlcat(stat_line, stats_str[i], sizeof(stat_line)); - strlcat(stat_line, " ", sizeof(stat_line)); - snprintf(buffer, sizeof(buffer), "%llu", ptr[i]); - strlcat(stat_line, buffer, sizeof(stat_line)); - strlcat(stat_line, "\r\n", sizeof(stat_line)); - } - return simple_read_from_buffer(t_char, t_size_t, - t_loff_t, stat_line, strlen(stat_line)); -} - -static ssize_t vfe_debugfs_statistics_write(struct file *t_file, - const char *t_char, size_t t_size_t, loff_t *t_loff_t) -{ - struct vfe_device *vfe_dev = (struct vfe_device *) - t_file->private_data; - struct msm_isp_statistics *stats = vfe_dev->stats; - - memset(stats, 0, sizeof(struct msm_isp_statistics)); - - return sizeof(struct msm_isp_statistics); -} - -static int bw_history_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t bw_history_read(struct file *t_file, char *t_char, - size_t t_size_t, loff_t *t_loff_t) -{ - int i; - char *out_buffer = bw_request_history_buff; - char line_buffer[MAX_BW_HISTORY_LINE_BUFF_LEN] = {0}; - struct msm_isp_bw_req_info *isp_req_hist = - (struct msm_isp_bw_req_info *) t_file->private_data; - - memset(out_buffer, 0, MAX_BW_HISTORY_BUFF_LEN); - - snprintf(line_buffer, sizeof(line_buffer), - "Bus bandwidth request history in chronological order:\n"); - strlcat(out_buffer, line_buffer, sizeof(bw_request_history_buff)); - - snprintf(line_buffer, sizeof(line_buffer), - "MSM_ISP_MIN_AB = %u, MSM_ISP_MIN_IB = %u\n\n", - MSM_ISP_MIN_AB, MSM_ISP_MIN_IB); - strlcat(out_buffer, line_buffer, sizeof(bw_request_history_buff)); - - for (i = 0; i < MAX_DEPTH_BW_REQ_HISTORY; i++) { - snprintf(line_buffer, sizeof(line_buffer), - "idx = %d, client = %u, timestamp = %llu, ab = %llu, ib = %llu\n" - "ISP0.active = %x, ISP0.ab = %llu, ISP0.ib = %llu\n" - "ISP1.active = %x, ISP1.ab = %llu, ISP1.ib = %llu\n" - "CPP.active = %x, CPP.ab = %llu, CPP.ib = %llu\n\n", - i, isp_req_hist[i].client, isp_req_hist[i].timestamp, - isp_req_hist[i].total_ab, isp_req_hist[i].total_ib, - isp_req_hist[i].client_info[0].active, - isp_req_hist[i].client_info[0].ab, - isp_req_hist[i].client_info[0].ib, - isp_req_hist[i].client_info[1].active, - isp_req_hist[i].client_info[1].ab, - isp_req_hist[i].client_info[1].ib, - isp_req_hist[i].client_info[2].active, - isp_req_hist[i].client_info[2].ab, - isp_req_hist[i].client_info[2].ib); - strlcat(out_buffer, line_buffer, - sizeof(bw_request_history_buff)); - } - return simple_read_from_buffer(t_char, t_size_t, - t_loff_t, out_buffer, strlen(out_buffer)); -} - -static ssize_t bw_history_write(struct file *t_file, - const char *t_char, size_t t_size_t, loff_t *t_loff_t) -{ - struct msm_isp_bw_req_info *isp_req_hist = - (struct msm_isp_bw_req_info *) t_file->private_data; - - memset(isp_req_hist, 0, sizeof(msm_isp_bw_request_history)); - msm_isp_bw_request_history_idx = 0; - return sizeof(msm_isp_bw_request_history); -} - -static int ub_info_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t ub_info_read(struct file *t_file, char *t_char, - size_t t_size_t, loff_t *t_loff_t) -{ - int i; - char *out_buffer = ub_info_buffer; - char line_buffer[MAX_UB_INFO_LINE_BUFF_LEN] = {0}; - struct vfe_device *vfe_dev = - (struct vfe_device *) t_file->private_data; - struct msm_isp_ub_info *ub_info = vfe_dev->ub_info; - - memset(out_buffer, 0, MAX_UB_INFO_LINE_BUFF_LEN); - snprintf(line_buffer, sizeof(line_buffer), - "wm_ub_policy_type = %d\n" - "num_wm = %d\n" - "wm_ub = %d\n", - ub_info->policy, ub_info->num_wm, ub_info->wm_ub); - strlcat(out_buffer, line_buffer, - sizeof(ub_info_buffer)); - for (i = 0; i < ub_info->num_wm; i++) { - snprintf(line_buffer, sizeof(line_buffer), - "data[%d] = 0x%x, addr[%d] = 0x%llx\n", - i, ub_info->data[i], i, ub_info->addr[i]); - strlcat(out_buffer, line_buffer, - sizeof(ub_info_buffer)); - } - - return simple_read_from_buffer(t_char, t_size_t, - t_loff_t, out_buffer, strlen(out_buffer)); -} - -static ssize_t ub_info_write(struct file *t_file, - const char *t_char, size_t t_size_t, loff_t *t_loff_t) -{ - struct vfe_device *vfe_dev = - (struct vfe_device *) t_file->private_data; - struct msm_isp_ub_info *ub_info = vfe_dev->ub_info; - - memset(ub_info, 0, sizeof(struct msm_isp_ub_info)); - - return sizeof(struct msm_isp_ub_info); -} - -static const struct file_operations vfe_debugfs_error = { - .open = vfe_debugfs_statistics_open, - .read = vfe_debugfs_statistics_read, - .write = vfe_debugfs_statistics_write, -}; - -static const struct file_operations bw_history_ops = { - .open = bw_history_open, - .read = bw_history_read, - .write = bw_history_write, -}; - -static const struct file_operations ub_info_ops = { - .open = ub_info_open, - .read = ub_info_read, - .write = ub_info_write, -}; - -static int msm_isp_enable_debugfs(struct vfe_device *vfe_dev, - struct msm_isp_bw_req_info *isp_req_hist) -{ - struct dentry *debugfs_base; - char dirname[32] = {0}; - - snprintf(dirname, sizeof(dirname), "msm_isp%d", vfe_dev->pdev->id); - debugfs_base = debugfs_create_dir(dirname, NULL); - if (!debugfs_base) - return -ENOMEM; - if (!debugfs_create_file("stats", S_IRUGO | S_IWUSR, debugfs_base, - vfe_dev, &vfe_debugfs_error)) - return -ENOMEM; - - if (!debugfs_create_file("bw_req_history", S_IRUGO | S_IWUSR, - debugfs_base, isp_req_hist, &bw_history_ops)) - return -ENOMEM; - - if (!debugfs_create_file("ub_info", S_IRUGO | S_IWUSR, - debugfs_base, vfe_dev, &ub_info_ops)) - return -ENOMEM; - - return 0; -} - -void msm_isp_update_req_history(uint32_t client, uint64_t ab, - uint64_t ib, - struct msm_isp_bandwidth_info *client_info, - unsigned long long ts) -{ - int i; - - spin_lock(&req_history_lock); - msm_isp_bw_request_history[msm_isp_bw_request_history_idx].client = - client; - msm_isp_bw_request_history[msm_isp_bw_request_history_idx].timestamp = - ts; - msm_isp_bw_request_history[msm_isp_bw_request_history_idx].total_ab = - ab; - msm_isp_bw_request_history[msm_isp_bw_request_history_idx].total_ib = - ib; - - for (i = 0; i < MAX_ISP_CLIENT; i++) { - msm_isp_bw_request_history[msm_isp_bw_request_history_idx]. - client_info[i].active = client_info[i].active; - msm_isp_bw_request_history[msm_isp_bw_request_history_idx]. - client_info[i].ab = client_info[i].ab; - msm_isp_bw_request_history[msm_isp_bw_request_history_idx]. - client_info[i].ib = client_info[i].ib; - } - - msm_isp_bw_request_history_idx = (msm_isp_bw_request_history_idx + 1) - % MAX_DEPTH_BW_REQ_HISTORY; - spin_unlock(&req_history_lock); -} - -#ifdef CONFIG_COMPAT -static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg) -{ - long rc; - - if (is_compat_task()) { - struct msm_isp32_event_data32 *event_data32; - struct msm_isp32_event_data *event_data; - struct v4l2_event isp_event; - struct v4l2_event *isp_event_user; - - memset(&isp_event, 0, sizeof(isp_event)); - rc = v4l2_event_dequeue(vfh, &isp_event, - file->f_flags & O_NONBLOCK); - if (rc) - return rc; - event_data = (struct msm_isp32_event_data *) - isp_event.u.data; - isp_event_user = (struct v4l2_event *)arg; - memcpy(isp_event_user, &isp_event, - sizeof(*isp_event_user)); - event_data32 = (struct msm_isp32_event_data32 *) - isp_event_user->u.data; - memset(event_data32, 0, - sizeof(struct msm_isp32_event_data32)); - event_data32->timestamp.tv_sec = - event_data->timestamp.tv_sec; - event_data32->timestamp.tv_usec = - event_data->timestamp.tv_usec; - event_data32->mono_timestamp.tv_sec = - event_data->mono_timestamp.tv_sec; - event_data32->mono_timestamp.tv_usec = - event_data->mono_timestamp.tv_usec; - event_data32->input_intf = event_data->input_intf; - event_data32->frame_id = event_data->frame_id; - memcpy(&(event_data32->u), &(event_data->u), - sizeof(event_data32->u)); - } else { - rc = v4l2_event_dequeue(vfh, arg, - file->f_flags & O_NONBLOCK); - } - return rc; -} -#else -static long msm_isp_dqevent(struct file *file, struct v4l2_fh *vfh, void *arg) -{ - return v4l2_event_dequeue(vfh, arg, - file->f_flags & O_NONBLOCK); -} -#endif - -static long msm_isp_subdev_do_ioctl( - struct file *file, unsigned int cmd, void *arg) -{ - struct video_device *vdev = video_devdata(file); - struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); - struct v4l2_fh *vfh = file->private_data; - - switch (cmd) { - case VIDIOC_DQEVENT: { - if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) - return -ENOIOCTLCMD; - return msm_isp_dqevent(file, vfh, arg); - } - break; - case VIDIOC_SUBSCRIBE_EVENT: - return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); - - case VIDIOC_UNSUBSCRIBE_EVENT: - return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); - - default: - return v4l2_subdev_call(sd, core, ioctl, cmd, arg); - } -} - -static long msm_isp_subdev_fops_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - return video_usercopy(file, cmd, arg, msm_isp_subdev_do_ioctl); -} - -static struct v4l2_file_operations msm_isp_v4l2_subdev_fops = { -#ifdef CONFIG_COMPAT - .compat_ioctl32 = msm_isp_subdev_fops_ioctl, -#endif - .unlocked_ioctl = msm_isp_subdev_fops_ioctl -}; - -static int vfe_probe(struct platform_device *pdev) -{ - struct vfe_device *vfe_dev; - /*struct msm_cam_subdev_info sd_info;*/ - const struct of_device_id *match_dev; - int rc = 0; - - struct msm_iova_partition vfe_partition = { - .start = SZ_128K, - .size = SZ_2G - SZ_128K, - }; - struct msm_iova_layout vfe_layout = { - .partitions = &vfe_partition, - .npartitions = 1, - .client_name = "vfe", - .domain_flags = 0, - }; - - vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL); - if (!vfe_dev) { - rc = -ENOMEM; - goto end; - } - vfe_dev->stats = kzalloc(sizeof(struct msm_isp_statistics), GFP_KERNEL); - if (!vfe_dev->stats) { - rc = -ENOMEM; - goto probe_fail1; - } - - vfe_dev->ub_info = kzalloc(sizeof(struct msm_isp_ub_info), GFP_KERNEL); - if (!vfe_dev->ub_info) { - rc = -ENOMEM; - goto probe_fail2; - } - if (pdev->dev.of_node) { - of_property_read_u32((&pdev->dev)->of_node, - "cell-index", &pdev->id); - match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev); - if (!match_dev) { - pr_err("%s: No vfe hardware info\n", __func__); - rc = -EINVAL; - goto probe_fail3; - } - vfe_dev->hw_info = - (struct msm_vfe_hardware_info *) match_dev->data; - } else { - vfe_dev->hw_info = (struct msm_vfe_hardware_info *) - platform_get_device_id(pdev)->driver_data; - } - - if (!vfe_dev->hw_info) { - pr_err("%s: No vfe hardware info\n", __func__); - rc = -EINVAL; - goto probe_fail3; - } - ISP_DBG("%s: device id = %d\n", __func__, pdev->id); - - vfe_dev->pdev = pdev; - rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev); - if (rc < 0) { - pr_err("%s: failed to get platform resources\n", __func__); - rc = -ENOMEM; - goto probe_fail3; - } - - INIT_LIST_HEAD(&vfe_dev->tasklet_q); - tasklet_init(&vfe_dev->vfe_tasklet, - msm_isp_do_tasklet, (unsigned long)vfe_dev); - - v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops); - vfe_dev->subdev.sd.internal_ops = - vfe_dev->hw_info->subdev_internal_ops; - snprintf(vfe_dev->subdev.sd.name, - ARRAY_SIZE(vfe_dev->subdev.sd.name), - "vfe"); - vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; - v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev); - platform_set_drvdata(pdev, &vfe_dev->subdev.sd); - mutex_init(&vfe_dev->realtime_mutex); - mutex_init(&vfe_dev->core_mutex); - spin_lock_init(&vfe_dev->tasklet_lock); - spin_lock_init(&vfe_dev->shared_data_lock); - spin_lock_init(&req_history_lock); - media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0); - vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; - vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE; - vfe_dev->subdev.sd.entity.name = pdev->name; - vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2; - rc = msm_sd_register(&vfe_dev->subdev); - if (rc != 0) { - pr_err("%s: msm_sd_register error = %d\n", __func__, rc); - goto probe_fail3; - } - - msm_isp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner; - msm_isp_v4l2_subdev_fops.open = v4l2_subdev_fops.open; - msm_isp_v4l2_subdev_fops.release = v4l2_subdev_fops.release; - msm_isp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll; - - vfe_dev->subdev.sd.devnode->fops = &msm_isp_v4l2_subdev_fops; - - vfe_dev->buf_mgr = &vfe_buf_mgr; - v4l2_subdev_notify(&vfe_dev->subdev.sd, - MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops); - rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr, - &vfe_vb2_ops, &vfe_layout); - if (rc < 0) { - pr_err("%s: Unable to create buffer manager\n", __func__); - rc = -EINVAL; - goto probe_fail3; - } - /* create secure context banks*/ - if (vfe_dev->hw_info->num_iommu_secure_ctx) { - /*secure vfe layout*/ - struct msm_iova_layout vfe_secure_layout = { - .partitions = &vfe_partition, - .npartitions = 1, - .client_name = "vfe_secure", - .domain_flags = 0, - .is_secure = MSM_IOMMU_DOMAIN_SECURE, - }; - rc = msm_isp_create_secure_domain(vfe_dev->buf_mgr, - &vfe_secure_layout); - if (rc < 0) { - pr_err("%s: fail to create secure domain\n", __func__); - msm_sd_unregister(&vfe_dev->subdev); - rc = -EINVAL; - goto probe_fail3; - } - } - msm_isp_enable_debugfs(vfe_dev, msm_isp_bw_request_history); - vfe_dev->buf_mgr->ops->register_ctx(vfe_dev->buf_mgr, - &vfe_dev->iommu_ctx[0], &vfe_dev->iommu_secure_ctx[0], - vfe_dev->hw_info->num_iommu_ctx, - vfe_dev->hw_info->num_iommu_secure_ctx); - - vfe_dev->buf_mgr->init_done = 1; - vfe_dev->vfe_open_cnt = 0; - return rc; - -probe_fail3: - kfree(vfe_dev->ub_info); -probe_fail2: - kfree(vfe_dev->stats); -probe_fail1: - kfree(vfe_dev); -end: - return rc; -} - -static struct platform_driver vfe_driver = { - .probe = vfe_probe, - .driver = { - .name = "msm_vfe", - .owner = THIS_MODULE, - .of_match_table = msm_vfe_dt_match, - }, - .id_table = msm_vfe_dev_id, -}; - -static int __init msm_vfe_init_module(void) -{ - return platform_driver_register(&vfe_driver); -} - -static void __exit msm_vfe_exit_module(void) -{ - platform_driver_unregister(&vfe_driver); -} - -module_init(msm_vfe_init_module); -module_exit(msm_vfe_exit_module); -MODULE_DESCRIPTION("MSM VFE driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_32.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_32.h deleted file mode 100644 index 3c94da71d46a..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_32.h +++ /dev/null @@ -1,599 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __MSM_VFE_H__ -#define __MSM_VFE_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_buf_mgr_32.h" - -#define VFE40_8974V1_VERSION 0x10000018 -#define VFE40_8974V2_VERSION 0x1001001A -#define VFE40_8974V3_VERSION 0x1001001B -#define VFE40_8x26_VERSION 0x20000013 -#define VFE40_8x26V2_VERSION 0x20010014 -#define VFE40_8916_VERSION 0x10030000 -#define VFE40_8939_VERSION 0x10040000 -#define VFE32_8909_VERSION 0x30600 - -#define MAX_IOMMU_CTX 2 -#define MAX_NUM_WM 7 -#define MAX_NUM_RDI 3 -#define MAX_NUM_RDI_MASTER 3 -#define MAX_NUM_COMPOSITE_MASK 4 -#define MAX_NUM_STATS_COMP_MASK 2 -#define MAX_INIT_FRAME_DROP 31 -#define ISP_Q2 (1 << 2) -#define ISP_Q10 (1 << 10) - -#define VFE_PING_FLAG 0xFFFFFFFF -#define VFE_PONG_FLAG 0x0 - -#define VFE_MAX_CFG_TIMEOUT 3000 -#define VFE_CLK_INFO_MAX 16 -#define STATS_COMP_BIT_MASK 0xFF0000 - -#define MSM_ISP_MIN_AB 11000000 -#define MSM_ISP_MIN_IB 11000000 - -struct vfe_device; -struct msm_vfe_axi_stream; -struct msm_vfe_stats_stream; - -struct vfe_subscribe_info { - struct v4l2_fh *vfh; - uint32_t active; -}; - -enum msm_isp_pack_fmt { - QCOM, - MIPI, - DPCM6, - DPCM8, - PLAIN8, - PLAIN16, - MAX_ISP_PACK_FMT, -}; - -enum msm_isp_camif_update_state { - NO_UPDATE, - ENABLE_CAMIF, - DISABLE_CAMIF, - DISABLE_CAMIF_IMMEDIATELY -}; - -struct msm_isp_timestamp { - /*Monotonic clock for v4l2 buffer*/ - struct timeval buf_time; - /*Monotonic clock for VT */ - struct timeval vt_time; - /*Wall clock for userspace event*/ - struct timeval event_time; -}; - -struct msm_vfe_irq_ops { - void (*read_irq_status)(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1); - void (*process_reg_update)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); - void (*process_epoch_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); - void (*process_reset_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1); - void (*process_halt_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1); - void (*process_camif_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); - void (*process_axi_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); - void (*process_stats_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); -}; - -struct msm_vfe_axi_ops { - void (*reload_wm)(struct vfe_device *vfe_dev, - uint32_t reload_mask); - void (*enable_wm)(struct vfe_device *vfe_dev, - uint8_t wm_idx, uint8_t enable); - int32_t (*cfg_io_format)(struct vfe_device *vfe_dev, - enum msm_vfe_axi_stream_src stream_src, - uint32_t io_format); - void (*cfg_framedrop)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - void (*clear_framedrop)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - void (*cfg_comp_mask)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - void (*clear_comp_mask)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - void (*cfg_wm_irq_mask)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - void (*clear_wm_irq_mask)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - - void (*cfg_wm_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, - uint8_t plane_idx); - void (*clear_wm_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx); - - void (*cfg_wm_xbar_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, - uint8_t plane_idx); - void (*clear_wm_xbar_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, uint8_t plane_idx); - - void (*cfg_ub)(struct vfe_device *vfe_dev); - - void (*update_ping_pong_addr)(struct vfe_device *vfe_dev, - uint8_t wm_idx, uint32_t pingpong_status, dma_addr_t paddr); - - uint32_t (*get_wm_mask)(uint32_t irq_status0, uint32_t irq_status1); - uint32_t (*get_comp_mask)(uint32_t irq_status0, uint32_t irq_status1); - uint32_t (*get_pingpong_status)(struct vfe_device *vfe_dev); - int (*halt)(struct vfe_device *vfe_dev, uint32_t blocking); - int (*restart)(struct vfe_device *vfe_dev, uint32_t blocking, - uint32_t enable_camif); - void (*update_cgc_override)(struct vfe_device *vfe_dev, - uint8_t wm_idx, uint8_t cgc_override); -}; - -struct msm_vfe_core_ops { - void (*reg_update)(struct vfe_device *vfe_dev, uint32_t input_src); - long (*reset_hw)(struct vfe_device *vfe_dev, uint32_t first_start, - uint32_t blocking_call); - int (*init_hw)(struct vfe_device *vfe_dev); - void (*init_hw_reg)(struct vfe_device *vfe_dev); - void (*clear_status_reg)(struct vfe_device *vfe_dev); - void (*release_hw)(struct vfe_device *vfe_dev); - void (*cfg_input_mux)(struct vfe_device *vfe_dev, - struct msm_vfe_pix_cfg *pix_cfg); - int (*start_fetch_eng)(struct vfe_device *vfe_dev, - void *arg); - void (*update_camif_state)(struct vfe_device *vfe_dev, - enum msm_isp_camif_update_state update_state); - void (*cfg_rdi_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_rdi_cfg *rdi_cfg, - enum msm_vfe_input_src input_src); - int (*get_platform_data)(struct vfe_device *vfe_dev); - void (*get_error_mask)(uint32_t *error_mask0, uint32_t *error_mask1); - void (*process_error_status)(struct vfe_device *vfe_dev); - void (*get_overflow_mask)(uint32_t *overflow_mask); - void (*get_irq_mask)(struct vfe_device *vfe_dev, - uint32_t *irq0_mask, uint32_t *irq1_mask); - void (*restore_irq_mask)(struct vfe_device *vfe_dev); - void (*get_halt_restart_mask)(uint32_t *irq0_mask, - uint32_t *irq1_mask); - void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev, - uint32_t *rdi_wm_mask); -}; -struct msm_vfe_stats_ops { - int (*get_stats_idx)(enum msm_isp_stats_type stats_type); - int (*check_streams)(struct msm_vfe_stats_stream *stream_info); - void (*cfg_framedrop)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info); - void (*clear_framedrop)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info); - void (*cfg_comp_mask)(struct vfe_device *vfe_dev, - uint32_t stats_mask, uint8_t enable); - void (*cfg_wm_irq_mask)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info); - void (*clear_wm_irq_mask)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info); - - void (*cfg_wm_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info); - void (*clear_wm_reg)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info); - - void (*cfg_ub)(struct vfe_device *vfe_dev); - - void (*enable_module)(struct vfe_device *vfe_dev, - uint32_t stats_mask, uint8_t enable); - - void (*update_ping_pong_addr)(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info, - uint32_t pingpong_status, dma_addr_t paddr); - - uint32_t (*get_frame_id)(struct vfe_device *vfe_dev); - uint32_t (*get_wm_mask)(uint32_t irq_status0, uint32_t irq_status1); - uint32_t (*get_comp_mask)(uint32_t irq_status0, uint32_t irq_status1); - uint32_t (*get_pingpong_status)(struct vfe_device *vfe_dev); - - void (*update_cgc_override)(struct vfe_device *vfe_dev, - uint32_t stats_mask, uint8_t enable); -}; - -struct msm_vfe_ops { - struct msm_vfe_irq_ops irq_ops; - struct msm_vfe_axi_ops axi_ops; - struct msm_vfe_core_ops core_ops; - struct msm_vfe_stats_ops stats_ops; -}; - -struct msm_vfe_hardware_info { - int num_iommu_ctx; - /* secure iommu ctx nums */ - int num_iommu_secure_ctx; - int vfe_clk_idx; - struct msm_vfe_ops vfe_ops; - struct msm_vfe_axi_hardware_info *axi_hw_info; - struct msm_vfe_stats_hardware_info *stats_hw_info; - struct v4l2_subdev_internal_ops *subdev_internal_ops; - struct v4l2_subdev_ops *subdev_ops; - uint32_t dmi_reg_offset; -}; - -struct msm_vfe_axi_hardware_info { - uint8_t num_wm; - uint8_t num_rdi; - uint8_t num_rdi_master; - uint8_t num_comp_mask; - uint32_t min_wm_ub; -}; - -enum msm_vfe_axi_state { - AVAILABLE, - INACTIVE, - ACTIVE, - PAUSED, - START_PENDING, - STOP_PENDING, - PAUSE_PENDING, - RESUME_PENDING, - STARTING, - STOPPING, - PAUSING, - RESUMING, -}; - -enum msm_vfe_axi_cfg_update_state { - NO_AXI_CFG_UPDATE, - APPLYING_UPDATE_RESUME, - UPDATE_REQUESTED, -}; - -#define VFE_NO_DROP 0xFFFFFFFF -#define VFE_DROP_EVERY_2FRAME 0x55555555 -#define VFE_DROP_EVERY_4FRAME 0x11111111 -#define VFE_DROP_EVERY_8FRAME 0x01010101 -#define VFE_DROP_EVERY_16FRAME 0x00010001 -#define VFE_DROP_EVERY_32FRAME 0x00000001 - -enum msm_vfe_axi_stream_type { - CONTINUOUS_STREAM, - BURST_STREAM, -}; - -struct msm_vfe_axi_stream { - uint32_t frame_id; - enum msm_vfe_axi_state state; - enum msm_vfe_axi_stream_src stream_src; - uint8_t num_planes; - uint8_t wm[MAX_PLANES_PER_STREAM]; - uint32_t output_format;/*Planar/RAW/Misc*/ - struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM]; - uint8_t comp_mask_index; - struct msm_isp_buffer *buf[2]; - uint32_t session_id; - uint32_t stream_id; - uint32_t bufq_handle; - uint32_t bufq_scratch_handle; - uint32_t controllable_output; - uint32_t stream_handle; - uint32_t request_frm_num; - uint8_t buf_divert; - enum msm_vfe_axi_stream_type stream_type; - uint32_t frame_based; - enum msm_vfe_frame_skip_pattern frame_skip_pattern; - uint32_t framedrop_period; - uint32_t framedrop_pattern; - uint32_t num_burst_capture;/*number of frame to capture*/ - uint32_t init_frame_drop; - uint32_t burst_frame_count;/*number of sof before burst stop*/ - uint8_t framedrop_update; - spinlock_t lock; - - /*Bandwidth calculation info*/ - uint32_t max_width; - /*Based on format plane size in Q2. e.g NV12 = 1.5*/ - uint32_t format_factor; - uint32_t bandwidth; - - /*Run time update variables*/ - uint32_t runtime_init_frame_drop; - uint32_t runtime_burst_frame_count;/*number of sof before burst stop*/ - uint32_t runtime_num_burst_capture; - uint8_t runtime_framedrop_update; - uint8_t runtime_framedrop_update_burst; - uint32_t runtime_output_format; - enum msm_stream_memory_input_t memory_input; -}; - -struct msm_vfe_axi_composite_info { - uint32_t stream_handle; - uint32_t stream_composite_mask; -}; - -struct msm_vfe_src_info { - uint32_t frame_id; - uint8_t active; - uint8_t pix_stream_count; - uint8_t raw_stream_count; - enum msm_vfe_inputmux input_mux; - uint32_t width; - long pixel_clock; - uint32_t input_format;/*V4L2 pix format with bayer pattern*/ - uint32_t last_updt_frm_id; -}; - -struct msm_vfe_fetch_engine_info { - uint32_t session_id; - uint32_t stream_id; - uint32_t bufq_handle; - uint32_t buf_idx; - uint8_t is_busy; -}; - -enum msm_wm_ub_cfg_type { - MSM_WM_UB_CFG_DEFAULT, - MSM_WM_UB_EQUAL_SLICING, - MSM_WM_UB_CFG_MAX_NUM -}; - -struct msm_vfe_axi_shared_data { - struct msm_vfe_axi_hardware_info *hw_info; - struct msm_vfe_axi_stream stream_info[VFE_AXI_SRC_MAX]; - uint32_t free_wm[MAX_NUM_WM]; - uint32_t wm_image_size[MAX_NUM_WM]; - enum msm_wm_ub_cfg_type wm_ub_cfg_policy; - uint8_t num_used_wm; - uint8_t num_active_stream; - uint8_t num_rdi_stream; - uint8_t num_pix_stream; - uint32_t rdi_wm_mask; - struct msm_vfe_axi_composite_info - composite_info[MAX_NUM_COMPOSITE_MASK]; - uint8_t num_used_composite_mask; - uint32_t stream_update; - atomic_t axi_cfg_update; - enum msm_isp_camif_update_state pipeline_update; - struct msm_vfe_src_info src_info[VFE_SRC_MAX]; - uint16_t stream_handle_cnt; - uint32_t event_mask; -}; - -struct msm_vfe_stats_hardware_info { - uint32_t stats_capability_mask; - uint8_t *stats_ping_pong_offset; - uint8_t num_stats_type; - uint8_t num_stats_comp_mask; -}; - -enum msm_vfe_stats_state { - STATS_AVAILABLE, - STATS_INACTIVE, - STATS_ACTIVE, - STATS_START_PENDING, - STATS_STOP_PENDING, - STATS_STARTING, - STATS_STOPPING, -}; - -struct msm_vfe_stats_stream { - uint32_t session_id; - uint32_t stream_id; - uint32_t stream_handle; - uint32_t composite_flag; - enum msm_isp_stats_type stats_type; - enum msm_vfe_stats_state state; - uint32_t framedrop_pattern; - uint32_t framedrop_period; - uint32_t irq_subsample_pattern; - uint32_t init_stats_frame_drop; - - uint32_t buffer_offset; - struct msm_isp_buffer *buf[2]; - uint32_t bufq_handle; -}; - -struct msm_vfe_stats_shared_data { - struct msm_vfe_stats_stream stream_info[MSM_ISP_STATS_MAX]; - uint8_t num_active_stream; - atomic_t stats_comp_mask[MAX_NUM_STATS_COMP_MASK]; - uint32_t reg_mask; - uint16_t stream_handle_cnt; - atomic_t stats_update; -}; - -struct msm_vfe_tasklet_queue_cmd { - struct list_head list; - uint32_t vfeInterruptStatus0; - uint32_t vfeInterruptStatus1; - struct msm_isp_timestamp ts; - uint8_t cmd_used; -}; - -#define MSM_VFE_TASKLETQ_SIZE 200 - -enum msm_vfe_overflow_state { - NO_OVERFLOW, - OVERFLOW_DETECTED, - HALT_REQUESTED, - RESTART_REQUESTED, -}; - -struct msm_vfe_error_info { - atomic_t overflow_state; - uint32_t overflow_recover_irq_mask0; - uint32_t overflow_recover_irq_mask1; - uint32_t error_mask0; - uint32_t error_mask1; - uint32_t violation_status; - uint32_t camif_status; - uint32_t stream_framedrop_count[MAX_NUM_STREAM]; - uint32_t stats_framedrop_count[MSM_ISP_STATS_MAX]; - uint32_t info_dump_frame_count; - uint32_t error_count; -}; - -struct msm_isp_statistics { - int64_t imagemaster0_overflow; - int64_t imagemaster1_overflow; - int64_t imagemaster2_overflow; - int64_t imagemaster3_overflow; - int64_t imagemaster4_overflow; - int64_t imagemaster5_overflow; - int64_t imagemaster6_overflow; - int64_t be_overflow; - int64_t bg_overflow; - int64_t bf_overflow; - int64_t awb_overflow; - int64_t rs_overflow; - int64_t cs_overflow; - int64_t ihist_overflow; - int64_t skinbhist_overflow; - int64_t bfscale_overflow; - - int64_t isp_vfe0_active; - int64_t isp_vfe0_ab; - int64_t isp_vfe0_ib; - - int64_t isp_vfe1_active; - int64_t isp_vfe1_ab; - int64_t isp_vfe1_ib; - - int64_t isp_cpp_active; - int64_t isp_cpp_ab; - int64_t isp_cpp_ib; - - int64_t last_overflow_ab; - int64_t last_overflow_ib; - - int64_t vfe_clk_rate; - int64_t cpp_clk_rate; -}; - -enum msm_isp_hw_client { - ISP_VFE0, - ISP_VFE1, - ISP_CPP, - MAX_ISP_CLIENT, -}; - -struct msm_isp_bandwidth_info { - uint32_t active; - uint64_t ab; - uint64_t ib; -}; - -struct msm_isp_bw_req_info { - uint32_t client; - unsigned long long timestamp; - uint64_t total_ab; - uint64_t total_ib; - struct msm_isp_bandwidth_info client_info[MAX_ISP_CLIENT]; -}; - -#define MSM_ISP_MAX_WM 7 -struct msm_isp_ub_info { - enum msm_wm_ub_cfg_type policy; - uint8_t num_wm; - uint32_t wm_ub; - uint32_t data[MSM_ISP_MAX_WM]; - uint64_t addr[MSM_ISP_MAX_WM]; -}; - -struct msm_vfe_hw_init_parms { - const char *entries; - const char *regs; - const char *settings; -}; - -struct vfe_device { - struct platform_device *pdev; - struct msm_sd_subdev subdev; - struct resource *vfe_irq; - struct resource *vfe_mem; - struct resource *vfe_vbif_mem; - struct resource *vfe_io; - struct resource *vfe_vbif_io; - void __iomem *vfe_base; - void __iomem *vfe_vbif_base; - - struct device *iommu_ctx[MAX_IOMMU_CTX]; - /*Add secure context banks*/ - struct device *iommu_secure_ctx[MAX_IOMMU_CTX]; - - struct regulator *fs_vfe; - struct clk **vfe_clk; - uint32_t num_clk; - - uint32_t bus_perf_client; - - struct completion reset_complete; - struct completion halt_complete; - struct completion stream_config_complete; - struct completion stats_config_complete; - struct mutex realtime_mutex; - struct mutex core_mutex; - - atomic_t irq_cnt; - uint8_t taskletq_idx; - spinlock_t tasklet_lock; - spinlock_t shared_data_lock; - struct list_head tasklet_q; - struct tasklet_struct vfe_tasklet; - struct msm_vfe_tasklet_queue_cmd - tasklet_queue_cmd[MSM_VFE_TASKLETQ_SIZE]; - - uint32_t vfe_hw_version; - struct msm_vfe_hardware_info *hw_info; - struct msm_vfe_axi_shared_data axi_data; - struct msm_vfe_stats_shared_data stats_data; - struct msm_vfe_error_info error_info; - struct msm_isp_buf_mgr *buf_mgr; - int dump_reg; - int vfe_clk_idx; - uint32_t vfe_open_cnt; - uint8_t vt_enable; - uint8_t ignore_error; - struct msm_isp_statistics *stats; - struct msm_vfe_fetch_engine_info fetch_engine_info; - uint64_t msm_isp_last_overflow_ab; - uint64_t msm_isp_last_overflow_ib; - uint64_t msm_isp_vfe_clk_rate; - struct msm_isp_ub_info *ub_info; - uint32_t vfe_ub_policy; - uint32_t isp_sof_debug; - uint8_t reset_pending; - uint32_t bus_util_factor; - uint8_t vfe_reset_timeout_processed; -}; - -#endif diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 6a339a97a671..1e1b5af4b12f 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -14,9 +14,8 @@ #include #include "msm_isp_util.h" #include "msm_isp_axi_util.h" -#include "trace/events/msm_cam.h" - +#define HANDLE_TO_IDX(handle) (handle & 0xFF) #define ISP_SOF_DEBUG_COUNT 0 static int msm_isp_update_dual_HW_ms_info_at_start( struct vfe_device *vfe_dev, @@ -249,9 +248,6 @@ int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data, stream_info->runtime_output_format = stream_info->output_format; stream_info->stream_src = stream_cfg_cmd->stream_src; stream_info->frame_based = stream_cfg_cmd->frame_base; - axi_data->src_info[SRC_TO_INTF(stream_info->stream_src)].session_id = - stream_cfg_cmd->session_id; - return 0; } @@ -599,7 +595,6 @@ static int msm_isp_check_epoch_status(struct vfe_device **vfe_dev, vfe_dev_cur->pdev->id, vfe_dev_cur->common_data->dual_vfe_res-> epoch_sync_mask); - msm_isp_dump_ping_pong_mismatch(); goto fatal; } @@ -728,9 +723,8 @@ void msm_isp_reset_framedrop(struct vfe_device *vfe_dev, stream_info->runtime_num_burst_capture); } -static void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, - struct msm_isp_timestamp *ts, struct msm_isp_sof_info *sof_info, - enum msm_vfe_input_src frame_src) +void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, + struct msm_isp_timestamp *ts, struct msm_isp_sof_info *sof_info) { struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data; @@ -754,12 +748,10 @@ static void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, sof_info->regs_not_updated = vfe_dev->reg_update_requested; } - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { struct msm_vfe_axi_stream *temp_stream_info; + stream_info = &axi_data->stream_info[i]; - if (SRC_TO_INTF(stream_info->stream_src) != frame_src) - continue; stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); /* @@ -797,20 +789,23 @@ static void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, sof_info->axi_updating_mask |= 1 << stream_idx; } - /* report frame drop per stream */ - i = stream_info->bufq_handle[VFE_BUF_QUEUE_DEFAULT] & - 0xFF; - if (vfe_dev->error_info.stream_framedrop_count[i]) { - ISP_DBG("%s: get buf failed i %d\n", __func__, - i); - sof_info->stream_get_buf_fail_mask |= (1 << i); - vfe_dev->error_info. - stream_framedrop_count[i] = 0; - } } vfe_dev->reg_updated = 0; + /* report frame drop per stream */ + if (vfe_dev->error_info.framedrop_flag) { + for (i = 0; i < BUF_MGR_NUM_BUF_Q; i++) { + if (vfe_dev->error_info.stream_framedrop_count[i]) { + ISP_DBG("%s: get buf failed i %d\n", __func__, + i); + sof_info->stream_get_buf_fail_mask |= (1 << i); + vfe_dev->error_info. + stream_framedrop_count[i] = 0; + } + } + vfe_dev->error_info.framedrop_flag = 0; + } } void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, @@ -821,8 +816,8 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, enum msm_vfe_dual_hw_type dual_hw_type; enum msm_vfe_dual_hw_ms_type ms_type; struct msm_vfe_sof_info *master_sof_info = NULL; - int32_t time, master_time, delta, i; - uint32_t sof_incr = 0, temp_frame_id; + int32_t time, master_time, delta; + uint32_t sof_incr = 0; uint32_t master_last_slave_diff = 0; uint32_t last_curr_diff = 0; unsigned long flags; @@ -833,32 +828,9 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, ts); dual_hw_type = vfe_dev->axi_data.src_info[frame_src].dual_hw_type; - ms_type = vfe_dev->axi_data.src_info[frame_src]. - dual_hw_ms_info.dual_hw_ms_type; - src_info = vfe_dev->axi_data.src_info; - - if (src_info[frame_src].frame_id == 0) { - for (i = VFE_PIX_0; i < VFE_SRC_MAX; i++) { - if (i == frame_src) - continue; - - if (src_info[frame_src].session_id != - src_info[i].session_id) - continue; - - if (src_info[i].active == 0) - continue; - - if (i == VFE_PIX_0) - temp_frame_id = src_info[i].frame_id - 1; - else - temp_frame_id = src_info[i].frame_id; - - if (src_info[frame_src].frame_id < temp_frame_id) - src_info[frame_src].frame_id = temp_frame_id; - } - } - + ms_type = + vfe_dev->axi_data.src_info[frame_src]. + dual_hw_ms_info.dual_hw_ms_type; /* * Increment frame_id if * 1. Not Master Slave @@ -958,42 +930,12 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, flags); } -static void msm_isp_update_pd_stats_idx(struct vfe_device *vfe_dev, - enum msm_vfe_input_src frame_src) -{ - struct msm_vfe_axi_stream *pd_stream_info = NULL; - uint32_t pingpong_status = 0, pingpong_bit = 0; - struct msm_isp_buffer *done_buf = NULL; - - if (frame_src < VFE_RAW_0 || frame_src > VFE_RAW_2) - return; - - pd_stream_info = &(vfe_dev->common_data->dual_vfe_res-> - axi_data[vfe_dev->pdev->id]-> - stream_info[RDI_INTF_0 + frame_src - VFE_RAW_0]); - - if (pd_stream_info && (pd_stream_info->state == ACTIVE) && - (pd_stream_info->rdi_input_type == - MSM_CAMERA_RDI_PDAF)) { - pingpong_status = vfe_dev->hw_info->vfe_ops.axi_ops. - get_pingpong_status(vfe_dev); - pingpong_bit = ((pingpong_status >> - pd_stream_info->wm[0]) & 0x1); - done_buf = pd_stream_info->buf[pingpong_bit]; - if (done_buf) - vfe_dev->pd_buf_idx = done_buf->buf_idx; - else - vfe_dev->pd_buf_idx = 0xF; - } -} - void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts) { struct msm_isp_event_data event_data; struct msm_vfe_sof_info *sof_info = NULL, *self_sof = NULL; enum msm_vfe_dual_hw_ms_type ms_type; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; int i, j; unsigned long flags; @@ -1001,15 +943,6 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, switch (event_type) { case ISP_EVENT_SOF: - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { - if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) == - frame_src) { - /* update ping pong bit for controllable */ - /* output */ - axi_data->stream_info[i].sw_sof_ping_pong_bit = - axi_data->stream_info[i].sw_ping_pong_bit; - } - } if (frame_src == VFE_PIX_0) { if (vfe_dev->isp_sof_debug < ISP_SOF_DEBUG_COUNT) pr_err("%s: PIX0 frame id: %u\n", __func__, @@ -1035,9 +968,6 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, ISP_DBG("%s: vfe %d frame_src %d frame id: %u\n", __func__, vfe_dev->pdev->id, frame_src, vfe_dev->axi_data.src_info[frame_src].frame_id); - trace_msm_cam_isp_bufcount("msm_isp_notify:", - vfe_dev->pdev->id, - vfe_dev->axi_data.src_info[frame_src].frame_id, frame_src); /* * Cannot support dual_cam and framedrop same time in union. @@ -1091,15 +1021,9 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, } else { if (frame_src <= VFE_RAW_2) { msm_isp_check_for_output_error(vfe_dev, ts, - &event_data.u.sof_info, frame_src); + &event_data.u.sof_info); } } - /* - * Get and store the buf idx for PD stats - * this is to send the PD stats buffer address - * in BF stats done. - */ - msm_isp_update_pd_stats_idx(vfe_dev, frame_src); break; default: @@ -1263,7 +1187,7 @@ int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) return -EINVAL; } - stream_info->rdi_input_type = stream_cfg_cmd->rdi_input_type; + stream_info->memory_input = stream_cfg_cmd->memory_input; vfe_dev->reg_update_requested &= ~(BIT(SRC_TO_INTF(stream_info->stream_src))); @@ -1547,11 +1471,12 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, { int i, j; uint32_t update_state; - unsigned long flags; + unsigned long flags, flags1; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; struct msm_vfe_axi_stream *stream_info; int num_stream = 0; + spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, flags); for (i = 0; i < VFE_AXI_SRC_MAX; i++) { if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) != frame_src) { @@ -1565,7 +1490,7 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, !stream_info->controllable_output) || stream_info->state == AVAILABLE) continue; - spin_lock_irqsave(&stream_info->lock, flags); + spin_lock_irqsave(&stream_info->lock, flags1); if (stream_info->state == PAUSING) { /*AXI Stopped, apply update*/ stream_info->state = PAUSED; @@ -1579,8 +1504,10 @@ void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, } else if (stream_info->state == RESUMING) { msm_isp_update_dual_HW_axi(vfe_dev, stream_info); } - spin_unlock_irqrestore(&stream_info->lock, flags); + spin_unlock_irqrestore(&stream_info->lock, flags1); } + spin_unlock_irqrestore(&vfe_dev->common_data->common_dev_data_lock, + flags); if (num_stream) update_state = atomic_dec_return( &axi_data->axi_cfg_update[frame_src]); @@ -2087,10 +2014,6 @@ static int msm_isp_process_done_buf(struct vfe_device *vfe_dev, } } - trace_msm_cam_isp_bufcount("msm_isp_process_done_buf:", - vfe_dev->pdev->id, frame_id, - SRC_TO_INTF(stream_info->stream_src)); - buf_event.frame_id = frame_id; buf_event.timestamp = *time_stamp; buf_event.u.buf_done.session_id = stream_info->session_id; @@ -2295,10 +2218,8 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; uint64_t total_pix_bandwidth = 0, total_rdi_bandwidth = 0; - uint64_t total_fe_bandwidth = 0; uint32_t num_pix_streams = 0; uint64_t total_bandwidth = 0; - int bpp = 0; for (i = 0; i < VFE_AXI_SRC_MAX; i++) { stream_info = &axi_data->stream_info[i]; @@ -2322,16 +2243,7 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev, } } - if (axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ - && num_pix_streams){ - bpp = msm_isp_get_bit_per_pixel(axi_data-> - src_info[VFE_PIX_0].input_format); - total_fe_bandwidth = - (axi_data->src_info[VFE_PIX_0].pixel_clock / 8) * bpp; - } - - total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth + - total_fe_bandwidth; + total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth; rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, (total_bandwidth + vfe_dev->hw_info->min_ab), (total_bandwidth + vfe_dev->hw_info->min_ib)); @@ -2526,14 +2438,9 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); return rc; } - /* Donot update frame_id for FE */ - if (!(SRC_TO_INTF(stream_info->stream_src) - == VFE_PIX_0 && - axi_data->src_info[VFE_PIX_0].input_mux - == EXTERNAL_READ)) - axi_data->src_info[SRC_TO_INTF(stream_info-> - stream_src)].frame_id = reset_cmd->frame_id; + axi_data->src_info[SRC_TO_INTF(stream_info-> + stream_src)].frame_id = reset_cmd->frame_id; msm_isp_reset_burst_count_and_frame_drop(vfe_dev, stream_info); } @@ -3063,13 +2970,7 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, intf < VFE_SRC_MAX) { vfe_dev->axi_data.src_info[intf].active = 0; vfe_dev->axi_data.src_info[intf].flag = 0; - /* reset frame_id for RDI path */ - if (halt) { - vfe_dev-> - axi_data.src_info[intf].frame_id = 0; - vfe_dev-> - axi_data.src_info[intf].eof_id = 0; - } + } } else src_mask |= (1 << intf); @@ -3115,13 +3016,6 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, if (src_mask & (1 << i)) { vfe_dev->axi_data.src_info[i].active = 0; vfe_dev->axi_data.src_info[i].flag = 0; - /* reset frame_id for RDI path */ - if (halt) { - vfe_dev-> - axi_data.src_info[i].frame_id = 0; - vfe_dev-> - axi_data.src_info[i].eof_id = 0; - } } } } @@ -3337,16 +3231,23 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, } frame_src = SRC_TO_INTF(stream_info->stream_src); - trace_msm_cam_isp_bufcount("msm_isp_request_frame:", - vfe_dev->pdev->id, frame_id, frame_src); - + pingpong_status = + vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status( + vfe_dev); + /* + * If PIX stream is active then RDI path uses SOF frame ID of PIX + * In case of standalone RDI streaming, SOF are used from + * individual intf. + */ /* * If frame_id = 1 then no eof check is needed */ - if (((frame_src == VFE_PIX_0) && ((frame_id != + if (((vfe_dev->axi_data.src_info[VFE_PIX_0].active) && ((frame_id != vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id + vfe_dev-> - axi_data.src_info[VFE_PIX_0].sof_counter_step))) || - ((frame_src != VFE_PIX_0) && (frame_id != + axi_data.src_info[VFE_PIX_0].sof_counter_step) || + (frame_id <= vfe_dev-> + axi_data.src_info[VFE_PIX_0].eof_id + 1))) || + ((!vfe_dev->axi_data.src_info[VFE_PIX_0].active) && (frame_id != vfe_dev->axi_data.src_info[frame_src].frame_id + vfe_dev-> axi_data.src_info[frame_src].sof_counter_step)) || stream_info->undelivered_request_cnt >= MAX_BUFFERS_IN_HW) { @@ -3454,12 +3355,7 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, dual_vfe_res->wm_reload_mask[vfe_id] = 0; } stream_info->sw_ping_pong_bit = 0; - stream_info->sw_sof_ping_pong_bit = 0; } else if (stream_info->undelivered_request_cnt == 2) { - if (stream_info->sw_sof_ping_pong_bit) - pingpong_status = VFE_PING_FLAG; - else - pingpong_status = VFE_PONG_FLAG; rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, pingpong_status, 0); if (rc) { @@ -3867,7 +3763,6 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, spin_unlock_irqrestore(&stream_info->lock, flags); pr_err("%s: Write master ping pong mismatch. Status: 0x%x\n", __func__, pingpong_status); - msm_isp_dump_ping_pong_mismatch(); msm_isp_halt_send_error(vfe_dev, ISP_EVENT_PING_PONG_MISMATCH); return; @@ -3945,6 +3840,7 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, vfe_dev->error_info.stream_framedrop_count[ stream_info->bufq_handle[ VFE_BUF_QUEUE_DEFAULT] & 0xFF]++; + vfe_dev->error_info.framedrop_flag = 1; } spin_unlock_irqrestore(&stream_info->lock, flags); return; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h index f0df70695212..1fb9f4e0b49a 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h @@ -14,7 +14,6 @@ #include "msm_isp.h" -#define HANDLE_TO_IDX(handle) (handle & 0xFF) #define SRC_TO_INTF(src) \ ((src < RDI_INTF_0 || src == VFE_AXI_SRC_MAX) ? VFE_PIX_0 : \ (VFE_RAW_0 + src - RDI_INTF_0)) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c deleted file mode 100644 index c7578b587812..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.c +++ /dev/null @@ -1,2083 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include "msm_isp_util_32.h" -#include "msm_isp_axi_util_32.h" - -#define SRC_TO_INTF(src) \ - ((src < RDI_INTF_0 || src == VFE_AXI_SRC_MAX) ? VFE_PIX_0 : \ - (VFE_RAW_0 + src - RDI_INTF_0)) - -#define HANDLE_TO_IDX(handle) (handle & 0xFF) - -int msm_isp_axi_create_stream( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd) -{ - uint32_t i = stream_cfg_cmd->stream_src; - - if (i >= VFE_AXI_SRC_MAX) { - pr_err("%s:%d invalid stream_src %d\n", __func__, __LINE__, - stream_cfg_cmd->stream_src); - return -EINVAL; - } - - if ((axi_data->stream_handle_cnt << 8) == 0) - axi_data->stream_handle_cnt++; - - stream_cfg_cmd->axi_stream_handle = - (++axi_data->stream_handle_cnt) << 8 | i; - - memset(&axi_data->stream_info[i], 0, - sizeof(struct msm_vfe_axi_stream)); - spin_lock_init(&axi_data->stream_info[i].lock); - axi_data->stream_info[i].session_id = stream_cfg_cmd->session_id; - axi_data->stream_info[i].stream_id = stream_cfg_cmd->stream_id; - axi_data->stream_info[i].buf_divert = stream_cfg_cmd->buf_divert; - axi_data->stream_info[i].state = INACTIVE; - axi_data->stream_info[i].stream_handle = - stream_cfg_cmd->axi_stream_handle; - axi_data->stream_info[i].controllable_output = - stream_cfg_cmd->controllable_output; - if (stream_cfg_cmd->controllable_output) - stream_cfg_cmd->frame_skip_pattern = SKIP_ALL; - return 0; -} - -void msm_isp_axi_destroy_stream( - struct msm_vfe_axi_shared_data *axi_data, int stream_idx) -{ - if (axi_data->stream_info[stream_idx].state != AVAILABLE) { - axi_data->stream_info[stream_idx].state = AVAILABLE; - axi_data->stream_info[stream_idx].stream_handle = 0; - } else { - pr_err("%s: stream does not exist\n", __func__); - } -} - -int msm_isp_validate_axi_request(struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd) -{ - int rc = -1, i; - struct msm_vfe_axi_stream *stream_info = NULL; - - if (HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle) < MAX_NUM_STREAM) { - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)]; - } else { - pr_err("%s: Invalid axi_stream_handle\n", __func__); - return rc; - } - - if (!stream_info) { - pr_err("%s: Stream info is NULL\n", __func__); - return -EINVAL; - } - - switch (stream_cfg_cmd->output_format) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - case V4L2_PIX_FMT_SBGGR14: - case V4L2_PIX_FMT_SGBRG14: - case V4L2_PIX_FMT_SGRBG14: - case V4L2_PIX_FMT_SRGGB14: - case V4L2_PIX_FMT_QBGGR8: - case V4L2_PIX_FMT_QGBRG8: - case V4L2_PIX_FMT_QGRBG8: - case V4L2_PIX_FMT_QRGGB8: - case V4L2_PIX_FMT_QBGGR10: - case V4L2_PIX_FMT_QGBRG10: - case V4L2_PIX_FMT_QGRBG10: - case V4L2_PIX_FMT_QRGGB10: - case V4L2_PIX_FMT_QBGGR12: - case V4L2_PIX_FMT_QGBRG12: - case V4L2_PIX_FMT_QGRBG12: - case V4L2_PIX_FMT_QRGGB12: - case V4L2_PIX_FMT_QBGGR14: - case V4L2_PIX_FMT_QGBRG14: - case V4L2_PIX_FMT_QGRBG14: - case V4L2_PIX_FMT_QRGGB14: - case V4L2_PIX_FMT_P16BGGR10: - case V4L2_PIX_FMT_P16GBRG10: - case V4L2_PIX_FMT_P16GRBG10: - case V4L2_PIX_FMT_P16RGGB10: - case V4L2_PIX_FMT_JPEG: - case V4L2_PIX_FMT_META: - stream_info->num_planes = 1; - stream_info->format_factor = ISP_Q2; - break; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV14: - case V4L2_PIX_FMT_NV41: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - stream_info->num_planes = 2; - stream_info->format_factor = 1.5 * ISP_Q2; - break; - /*TD: Add more image format*/ - default: - msm_isp_print_fourcc_error(__func__, - stream_cfg_cmd->output_format); - return rc; - } - - if (axi_data->hw_info->num_wm - axi_data->num_used_wm < - stream_info->num_planes) { - pr_err("%s: No free write masters\n", __func__); - return rc; - } - - if ((stream_info->num_planes > 1) && - (axi_data->hw_info->num_comp_mask - - axi_data->num_used_composite_mask < 1)) { - pr_err("%s: No free composite mask\n", __func__); - return rc; - } - - if (stream_cfg_cmd->init_frame_drop >= MAX_INIT_FRAME_DROP) { - pr_err("%s: Invalid skip pattern\n", __func__); - return rc; - } - - if (stream_cfg_cmd->frame_skip_pattern >= MAX_SKIP) { - pr_err("%s: Invalid skip pattern\n", __func__); - return rc; - } - - for (i = 0; i < stream_info->num_planes; i++) { - stream_info->plane_cfg[i] = stream_cfg_cmd->plane_cfg[i]; - stream_info->max_width = max(stream_info->max_width, - stream_cfg_cmd->plane_cfg[i].output_width); - } - - stream_info->output_format = stream_cfg_cmd->output_format; - stream_info->runtime_output_format = stream_info->output_format; - stream_info->stream_src = stream_cfg_cmd->stream_src; - stream_info->frame_based = stream_cfg_cmd->frame_base; - return 0; -} - -static uint32_t msm_isp_axi_get_plane_size( - struct msm_vfe_axi_stream *stream_info, int plane_idx) -{ - uint32_t size = 0; - struct msm_vfe_axi_plane_cfg *plane_cfg = stream_info->plane_cfg; - - switch (stream_info->output_format) { - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - case V4L2_PIX_FMT_QBGGR8: - case V4L2_PIX_FMT_QGBRG8: - case V4L2_PIX_FMT_QGRBG8: - case V4L2_PIX_FMT_QRGGB8: - case V4L2_PIX_FMT_JPEG: - case V4L2_PIX_FMT_META: - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - case V4L2_PIX_FMT_QBGGR10: - case V4L2_PIX_FMT_QGBRG10: - case V4L2_PIX_FMT_QGRBG10: - case V4L2_PIX_FMT_QRGGB10: - /* TODO: fix me */ - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - case V4L2_PIX_FMT_QBGGR12: - case V4L2_PIX_FMT_QGBRG12: - case V4L2_PIX_FMT_QGRBG12: - case V4L2_PIX_FMT_QRGGB12: - case V4L2_PIX_FMT_SBGGR14: - case V4L2_PIX_FMT_SGBRG14: - case V4L2_PIX_FMT_SGRBG14: - case V4L2_PIX_FMT_SRGGB14: - case V4L2_PIX_FMT_QBGGR14: - case V4L2_PIX_FMT_QGBRG14: - case V4L2_PIX_FMT_QGRBG14: - case V4L2_PIX_FMT_QRGGB14: - /* TODO: fix me */ - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - case V4L2_PIX_FMT_P16BGGR10: - case V4L2_PIX_FMT_P16GBRG10: - case V4L2_PIX_FMT_P16GRBG10: - case V4L2_PIX_FMT_P16RGGB10: - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - if (plane_cfg[plane_idx].output_plane_format == Y_PLANE) - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - else - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - case V4L2_PIX_FMT_NV14: - case V4L2_PIX_FMT_NV41: - if (plane_cfg[plane_idx].output_plane_format == Y_PLANE) - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - else - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - size = plane_cfg[plane_idx].output_height * - plane_cfg[plane_idx].output_width; - break; - /*TD: Add more image format*/ - default: - msm_isp_print_fourcc_error(__func__, - stream_info->output_format); - break; - } - return size; -} - -void msm_isp_axi_reserve_wm(struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info) -{ - int i, j; - - for (i = 0; i < stream_info->num_planes; i++) { - for (j = 0; j < axi_data->hw_info->num_wm; j++) { - if (!axi_data->free_wm[j]) { - axi_data->free_wm[j] = - stream_info->stream_handle; - axi_data->wm_image_size[j] = - msm_isp_axi_get_plane_size( - stream_info, i); - axi_data->num_used_wm++; - break; - } - } - stream_info->wm[i] = j; - } -} - -void msm_isp_axi_free_wm(struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info) -{ - int i; - - for (i = 0; i < stream_info->num_planes; i++) { - axi_data->free_wm[stream_info->wm[i]] = 0; - axi_data->num_used_wm--; - } - if (stream_info->stream_src <= IDEAL_RAW) - axi_data->num_pix_stream++; - else if (stream_info->stream_src < VFE_AXI_SRC_MAX) - axi_data->num_rdi_stream++; -} - -void msm_isp_axi_reserve_comp_mask( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info) -{ - int i; - uint8_t comp_mask = 0; - - for (i = 0; i < stream_info->num_planes; i++) - comp_mask |= 1 << stream_info->wm[i]; - - for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) { - if (!axi_data->composite_info[i].stream_handle) { - axi_data->composite_info[i].stream_handle = - stream_info->stream_handle; - axi_data->composite_info[i]. - stream_composite_mask = comp_mask; - axi_data->num_used_composite_mask++; - break; - } - } - stream_info->comp_mask_index = i; -} - -void msm_isp_axi_free_comp_mask(struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info) -{ - axi_data->composite_info[stream_info->comp_mask_index]. - stream_composite_mask = 0; - axi_data->composite_info[stream_info->comp_mask_index]. - stream_handle = 0; - axi_data->num_used_composite_mask--; -} - -int msm_isp_axi_get_bufq_handles( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - int rc = 0; - - if (stream_info->stream_id & ISP_SCRATCH_BUF_BIT) { - stream_info->bufq_handle = - vfe_dev->buf_mgr->ops->get_bufq_handle( - vfe_dev->buf_mgr, stream_info->session_id, - stream_info->stream_id & ~ISP_SCRATCH_BUF_BIT); - if (stream_info->bufq_handle == 0) { - pr_err("%s: Stream 0x%x has no valid buffer queue\n", - __func__, (unsigned int)stream_info->stream_id); - rc = -EINVAL; - return rc; - } - - stream_info->bufq_scratch_handle = - vfe_dev->buf_mgr->ops->get_bufq_handle( - vfe_dev->buf_mgr, stream_info->session_id, - stream_info->stream_id); - if (stream_info->bufq_scratch_handle == 0) { - pr_err("%s: Stream 0x%x has no valid buffer queue\n", - __func__, (unsigned int)stream_info->stream_id); - rc = -EINVAL; - return rc; - } - } else { - stream_info->bufq_handle = - vfe_dev->buf_mgr->ops->get_bufq_handle( - vfe_dev->buf_mgr, stream_info->session_id, - stream_info->stream_id); - if (stream_info->bufq_handle == 0) { - pr_err("%s: Stream 0x%x has no valid buffer queue\n", - __func__, (unsigned int)stream_info->stream_id); - rc = -EINVAL; - return rc; - } - } - return rc; -} - -int msm_isp_axi_check_stream_state( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd) -{ - int rc = 0, i; - unsigned long flags; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_vfe_axi_stream *stream_info; - enum msm_vfe_axi_state valid_state = - (stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) - return -EINVAL; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= - MAX_NUM_STREAM) { - return -EINVAL; - } - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - spin_lock_irqsave(&stream_info->lock, flags); - if (stream_info->state != valid_state) { - if ((stream_info->state == PAUSING || - stream_info->state == PAUSED || - stream_info->state == RESUME_PENDING || - stream_info->state == RESUMING) && - (stream_cfg_cmd->cmd == STOP_STREAM || - stream_cfg_cmd->cmd == STOP_IMMEDIATELY)) { - stream_info->state = ACTIVE; - } else { - pr_err("%s: Invalid stream state: %d\n", - __func__, stream_info->state); - spin_unlock_irqrestore( - &stream_info->lock, flags); - rc = -EINVAL; - break; - } - } - spin_unlock_irqrestore(&stream_info->lock, flags); - - if (stream_cfg_cmd->cmd == START_STREAM) { - rc = msm_isp_axi_get_bufq_handles(vfe_dev, stream_info); - if (rc) - break; - } - } - return rc; -} - -void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev, - uint8_t input_src) -{ - int i; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_vfe_axi_stream *stream_info; - - for (i = 0; i < MAX_NUM_STREAM; i++) { - stream_info = &axi_data->stream_info[i]; - if (stream_info->state != ACTIVE) - continue; - - if (stream_info->runtime_framedrop_update) { - stream_info->runtime_init_frame_drop--; - if (stream_info->runtime_init_frame_drop == 0) { - stream_info->runtime_framedrop_update = 0; - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_framedrop(vfe_dev, stream_info); - } - } - if (stream_info->stream_type == BURST_STREAM && - ((1 << SRC_TO_INTF(stream_info->stream_src)) & - input_src)) { - if (stream_info->runtime_framedrop_update_burst) { - stream_info->runtime_framedrop_update_burst = 0; - stream_info->runtime_burst_frame_count = - stream_info->runtime_init_frame_drop + - (stream_info->runtime_num_burst_capture - - 1) * - (stream_info->framedrop_period + 1) + 1; - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_framedrop(vfe_dev, stream_info); - } else { - stream_info->runtime_burst_frame_count--; - if (stream_info-> - runtime_burst_frame_count == 0) { - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_framedrop(vfe_dev, stream_info); - } - } - } - } -} - -void msm_isp_reset_framedrop(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - stream_info->runtime_init_frame_drop = stream_info->init_frame_drop; - stream_info->runtime_burst_frame_count = - stream_info->burst_frame_count; - stream_info->runtime_num_burst_capture = - stream_info->num_burst_capture; - stream_info->runtime_framedrop_update = stream_info->framedrop_update; - vfe_dev->hw_info->vfe_ops.axi_ops.cfg_framedrop(vfe_dev, stream_info); -} - -void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, - enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts) -{ - struct msm_isp32_event_data event_data; - - memset(&event_data, 0, sizeof(event_data)); - switch (event_type) { - case ISP_EVENT_SOF: - if ((frame_src == VFE_PIX_0) && (vfe_dev->isp_sof_debug < 5)) { - pr_err("%s: PIX0 frame id: %u\n", __func__, - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); - vfe_dev->isp_sof_debug++; - } - vfe_dev->axi_data.src_info[frame_src].frame_id++; - if (vfe_dev->axi_data.src_info[frame_src].frame_id == 0) - vfe_dev->axi_data.src_info[frame_src].frame_id = 1; - ISP_DBG("%s: frame_src %d frame id: %u\n", __func__, - frame_src, - vfe_dev->axi_data.src_info[frame_src].frame_id); - break; - case ISP_EVENT_REG_UPDATE: - vfe_dev->axi_data.src_info[frame_src].last_updt_frm_id = 0; - break; - default: - break; - } - - event_data.input_intf = frame_src; - event_data.frame_id = vfe_dev->axi_data.src_info[frame_src].frame_id; - event_data.timestamp = ts->event_time; - event_data.mono_timestamp = ts->buf_time; - msm_isp_send_event(vfe_dev, event_type | frame_src, &event_data); -} - -void msm_isp_calculate_framedrop( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd) -{ - uint32_t framedrop_period = 0; - struct msm_vfe_axi_stream *stream_info = NULL; - - if (HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle) < MAX_NUM_STREAM) { - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)]; - } else { - pr_err("%s: Invalid stream handle", __func__); - return; - } - if (!stream_info) { - pr_err("%s: Stream info is NULL\n", __func__); - return; - } - - framedrop_period = msm_isp_get_framedrop_period( - stream_cfg_cmd->frame_skip_pattern); - stream_info->frame_skip_pattern = - stream_cfg_cmd->frame_skip_pattern; - if (stream_cfg_cmd->frame_skip_pattern == SKIP_ALL) - stream_info->framedrop_pattern = 0x0; - else - stream_info->framedrop_pattern = 0x1; - stream_info->framedrop_period = framedrop_period - 1; - - if (stream_cfg_cmd->init_frame_drop < framedrop_period) { - stream_info->framedrop_pattern <<= - stream_cfg_cmd->init_frame_drop; - stream_info->init_frame_drop = 0; - stream_info->framedrop_update = 0; - } else { - stream_info->init_frame_drop = stream_cfg_cmd->init_frame_drop; - stream_info->framedrop_update = 1; - } - - if (stream_cfg_cmd->burst_count > 0) { - stream_info->stream_type = BURST_STREAM; - stream_info->num_burst_capture = - stream_cfg_cmd->burst_count; - stream_info->burst_frame_count = - stream_cfg_cmd->init_frame_drop + - (stream_cfg_cmd->burst_count - 1) * - framedrop_period + 1; - } else { - stream_info->stream_type = CONTINUOUS_STREAM; - stream_info->burst_frame_count = 0; - stream_info->num_burst_capture = 0; - } -} - -void msm_isp_calculate_bandwidth( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info) -{ - int bpp = 0; - - if (stream_info->stream_src < RDI_INTF_0) { - stream_info->bandwidth = - (axi_data->src_info[VFE_PIX_0].pixel_clock / - axi_data->src_info[VFE_PIX_0].width) * - stream_info->max_width; - stream_info->bandwidth = (unsigned long)stream_info->bandwidth * - stream_info->format_factor / ISP_Q2; - } else { - int rdi = SRC_TO_INTF(stream_info->stream_src); - - bpp = msm_isp_get_bit_per_pixel(stream_info->output_format); - if (rdi < VFE_SRC_MAX) - stream_info->bandwidth = - (axi_data->src_info[rdi].pixel_clock / 8) * bpp; - else - pr_err("%s: Invalid rdi interface\n", __func__); - } -} - -#ifdef CONFIG_MSM_AVTIMER -void msm_isp_start_avtimer(void) -{ - avcs_core_open(); - avcs_core_disable_power_collapse(1); -} - -static inline void msm_isp_get_avtimer_ts( - struct msm_isp_timestamp *time_stamp) -{ - int rc = 0; - uint32_t avtimer_usec = 0; - uint64_t avtimer_tick = 0; - - rc = avcs_core_query_timer(&avtimer_tick); - if (rc < 0) { - pr_err("%s: Error: Invalid AVTimer Tick, rc=%d\n", - __func__, rc); - /* In case of error return zero AVTimer Tick Value */ - time_stamp->vt_time.tv_sec = 0; - time_stamp->vt_time.tv_usec = 0; - } else { - avtimer_usec = do_div(avtimer_tick, USEC_PER_SEC); - time_stamp->vt_time.tv_sec = (uint32_t)(avtimer_tick); - time_stamp->vt_time.tv_usec = avtimer_usec; - pr_debug("%s: AVTimer TS = %u:%u\n", __func__, - (uint32_t)(avtimer_tick), avtimer_usec); - } -} -#else -void msm_isp_start_avtimer(void) -{ - pr_err("AV Timer is not supported\n"); -} - -static inline void msm_isp_get_avtimer_ts( - struct msm_isp_timestamp *time_stamp) -{ - pr_err_ratelimited("%s: Error: AVTimer driver not available\n", - __func__); - time_stamp->vt_time.tv_sec = 0; - time_stamp->vt_time.tv_usec = 0; -} -#endif - -int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0, i; - uint32_t io_format = 0; - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd = arg; - struct msm_vfe_axi_stream *stream_info; - - rc = msm_isp_axi_create_stream( - &vfe_dev->axi_data, stream_cfg_cmd); - if (rc) { - pr_err("%s: create stream failed\n", __func__); - return rc; - } - - rc = msm_isp_validate_axi_request( - &vfe_dev->axi_data, stream_cfg_cmd); - if (rc) { - pr_err("%s: Request validation failed\n", __func__); - if (HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle) < - MAX_NUM_STREAM) - msm_isp_axi_destroy_stream(&vfe_dev->axi_data, - HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)); - return rc; - } - stream_info = &vfe_dev->axi_data. - stream_info[HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)]; - if (!stream_info) { - pr_err("%s: can not find stream handle %x\n", __func__, - stream_cfg_cmd->axi_stream_handle); - return -EINVAL; - } - - stream_info->memory_input = stream_cfg_cmd->memory_input; - - msm_isp_axi_reserve_wm(&vfe_dev->axi_data, stream_info); - - if (stream_info->stream_src < RDI_INTF_0) { - io_format = vfe_dev->axi_data.src_info[VFE_PIX_0].input_format; - if (stream_info->stream_src == CAMIF_RAW || - stream_info->stream_src == IDEAL_RAW) { - if (stream_info->stream_src == CAMIF_RAW && - io_format != stream_info->output_format) - pr_debug("%s: Overriding input format\n", - __func__); - - io_format = stream_info->output_format; - } - rc = vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format( - vfe_dev, stream_info->stream_src, io_format); - if (rc) { - pr_err("%s: cfg io format failed\n", __func__); - msm_isp_axi_free_wm(&vfe_dev->axi_data, - stream_info); - msm_isp_axi_destroy_stream(&vfe_dev->axi_data, - HANDLE_TO_IDX( - stream_cfg_cmd->axi_stream_handle)); - return rc; - } - } - - msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd); - if (stream_cfg_cmd->vt_enable && !vfe_dev->vt_enable) { - vfe_dev->vt_enable = stream_cfg_cmd->vt_enable; - msm_isp_start_avtimer(); - } - if (stream_info->num_planes > 1) { - msm_isp_axi_reserve_comp_mask( - &vfe_dev->axi_data, stream_info); - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_comp_mask(vfe_dev, stream_info); - } else { - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_wm_irq_mask(vfe_dev, stream_info); - } - - for (i = 0; i < stream_info->num_planes; i++) { - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_wm_reg(vfe_dev, stream_info, i); - - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_wm_xbar_reg(vfe_dev, stream_info, i); - } - return rc; -} - -int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0, i; - struct msm_vfe_axi_stream_release_cmd *stream_release_cmd = arg; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_stream_cfg_cmd stream_cfg; - - - if (HANDLE_TO_IDX(stream_release_cmd->stream_handle) >= - MAX_NUM_STREAM) { - pr_err("%s: Invalid stream handle\n", __func__); - return -EINVAL; - } - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_release_cmd->stream_handle)]; - if (stream_info->state == AVAILABLE) { - pr_err("%s: Stream already released\n", __func__); - return -EINVAL; - } else if (stream_info->state != INACTIVE) { - stream_cfg.cmd = STOP_STREAM; - stream_cfg.num_streams = 1; - stream_cfg.stream_handle[0] = stream_release_cmd->stream_handle; - msm_isp_cfg_axi_stream(vfe_dev, (void *) &stream_cfg); - } - - for (i = 0; i < stream_info->num_planes; i++) { - vfe_dev->hw_info->vfe_ops.axi_ops. - clear_wm_reg(vfe_dev, stream_info, i); - - vfe_dev->hw_info->vfe_ops.axi_ops. - clear_wm_xbar_reg(vfe_dev, stream_info, i); - } - - if (stream_info->num_planes > 1) { - vfe_dev->hw_info->vfe_ops.axi_ops. - clear_comp_mask(vfe_dev, stream_info); - msm_isp_axi_free_comp_mask(&vfe_dev->axi_data, stream_info); - } else { - vfe_dev->hw_info->vfe_ops.axi_ops. - clear_wm_irq_mask(vfe_dev, stream_info); - } - - vfe_dev->hw_info->vfe_ops.axi_ops.clear_framedrop(vfe_dev, stream_info); - msm_isp_axi_free_wm(axi_data, stream_info); - - msm_isp_axi_destroy_stream(&vfe_dev->axi_data, - HANDLE_TO_IDX(stream_release_cmd->stream_handle)); - - return rc; -} - -static void msm_isp_axi_stream_enable_cfg( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - int i; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - if (stream_info->state == INACTIVE) - return; - for (i = 0; i < stream_info->num_planes; i++) { - if (stream_info->state == START_PENDING || - stream_info->state == RESUME_PENDING) { - vfe_dev->hw_info->vfe_ops.axi_ops. - enable_wm(vfe_dev, stream_info->wm[i], 1); - } else { - vfe_dev->hw_info->vfe_ops.axi_ops. - enable_wm(vfe_dev, stream_info->wm[i], 0); - /* Issue a reg update for Raw Snapshot Case - * since we dont have reg update ack - */ - if (stream_info->stream_src == CAMIF_RAW || - stream_info->stream_src == IDEAL_RAW) { - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, (1 << VFE_PIX_0)); - } - } - } - - if (stream_info->state == START_PENDING) - axi_data->num_active_stream++; - else if (stream_info->state == STOP_PENDING) - axi_data->num_active_stream--; -} - -void msm_isp_axi_stream_update(struct vfe_device *vfe_dev, uint8_t input_src) -{ - int i; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - for (i = 0; i < MAX_NUM_STREAM; i++) { - if (axi_data->stream_info[i].state == START_PENDING || - axi_data->stream_info[i].state == - STOP_PENDING) { - if ((1 << - SRC_TO_INTF(axi_data->stream_info[i]. - stream_src)) & - input_src) { - msm_isp_axi_stream_enable_cfg( - vfe_dev, &axi_data->stream_info[i]); - axi_data->stream_info[i].state = - axi_data->stream_info[i].state == - START_PENDING ? STARTING : STOPPING; - } - } else if (axi_data->stream_info[i].state == STARTING || - axi_data->stream_info[i].state == STOPPING) { - if ((1 << - SRC_TO_INTF(axi_data->stream_info[i]. - stream_src)) & - input_src) { - axi_data->stream_info[i].state = - axi_data->stream_info[i].state == STARTING ? - ACTIVE : INACTIVE; - vfe_dev->axi_data.stream_update--; - } - } - } - - if (vfe_dev->axi_data.pipeline_update == DISABLE_CAMIF || - (vfe_dev->axi_data.pipeline_update == - DISABLE_CAMIF_IMMEDIATELY)) { - vfe_dev->hw_info->vfe_ops.stats_ops. - enable_module(vfe_dev, 0xFF, 0); - vfe_dev->axi_data.pipeline_update = NO_UPDATE; - } - - if (vfe_dev->axi_data.stream_update == 0) - complete(&vfe_dev->stream_config_complete); -} - -static void msm_isp_reload_ping_pong_offset(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - int i, j; - uint32_t flag; - struct msm_isp_buffer *buf; - - for (i = 0; i < 2; i++) { - buf = stream_info->buf[i]; - if (!buf) - continue; - flag = i ? VFE_PONG_FLAG : VFE_PING_FLAG; - for (j = 0; j < stream_info->num_planes; j++) { - vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr( - vfe_dev, stream_info->wm[j], flag, - buf->mapped_info[j].paddr + - stream_info->plane_cfg[j].plane_addr_offset); - } - } -} - -void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev) -{ - int i, j; - uint32_t update_state; - unsigned long flags; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_vfe_axi_stream *stream_info; - - for (i = 0; i < MAX_NUM_STREAM; i++) { - stream_info = &axi_data->stream_info[i]; - if (stream_info->stream_type == BURST_STREAM || - stream_info->state == AVAILABLE) - continue; - spin_lock_irqsave(&stream_info->lock, flags); - if (stream_info->state == PAUSING) { - /*AXI Stopped, apply update*/ - stream_info->state = PAUSED; - msm_isp_reload_ping_pong_offset(vfe_dev, stream_info); - for (j = 0; j < stream_info->num_planes; j++) - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_wm_reg(vfe_dev, stream_info, j); - /*Resume AXI*/ - stream_info->state = RESUME_PENDING; - msm_isp_axi_stream_enable_cfg( - vfe_dev, &axi_data->stream_info[i]); - stream_info->state = RESUMING; - } else if (stream_info->state == RESUMING) { - stream_info->runtime_output_format = - stream_info->output_format; - stream_info->state = ACTIVE; - } - spin_unlock_irqrestore(&stream_info->lock, flags); - } - - update_state = atomic_dec_return(&axi_data->axi_cfg_update); -} - -static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - int i; - struct msm_isp_buffer *buf = stream_info->buf[0]; - - for (i = 0; i < stream_info->num_planes; i++) - vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr( - vfe_dev, stream_info->wm[i], - VFE_PONG_FLAG, buf->mapped_info[i].paddr + - stream_info->plane_cfg[i].plane_addr_offset); - stream_info->buf[1] = buf; -} - -static void msm_isp_get_done_buf(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, - struct msm_isp_buffer **done_buf) -{ - uint32_t pingpong_bit = 0, i; - - pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1); - for (i = 0; i < stream_info->num_planes; i++) { - if (pingpong_bit != - (~(pingpong_status >> stream_info->wm[i]) & 0x1)) { - pr_debug("%s: Write master ping pong mismatch. Status: 0x%x\n", - __func__, pingpong_status); - } - } - - *done_buf = stream_info->buf[pingpong_bit]; - - if (stream_info->controllable_output) { - stream_info->buf[pingpong_bit] = NULL; - stream_info->request_frm_num--; - } -} - -static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, - uint32_t pingpong_bit) -{ - int i, rc = -1; - struct msm_isp_buffer *buf = NULL; - uint32_t bufq_handle = 0, frame_id = 0; - uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); - - if (stream_idx >= MAX_NUM_STREAM) { - pr_err("%s: Invalid stream_idx", __func__); - return rc; - } - - if (stream_info->controllable_output && !stream_info->request_frm_num) - return 0; - - frame_id = vfe_dev->axi_data. - src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; - if (frame_id && stream_info->frame_id && - stream_info->frame_id == frame_id) { - /* This could happen if reg update ack is delayed */ - pr_err("%s: Duplicate frame streamId:%d stream_fid:%d frame_id:%d\n", - __func__, stream_info->stream_id, stream_info->frame_id, - frame_id); - vfe_dev->error_info.stream_framedrop_count[stream_idx]++; - return rc; - } - - bufq_handle = stream_info->bufq_handle; - if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX) - rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr, - vfe_dev->pdev->id, bufq_handle, &buf); - else { - pr_err("%s: Invalid stream index\n", __func__); - rc = -1; - } - - if (rc < 0) { - vfe_dev->error_info.stream_framedrop_count[stream_idx]++; - return rc; - } - - if (buf->num_planes != stream_info->num_planes) { - pr_err("%s: Invalid buffer\n", __func__); - rc = -EINVAL; - goto buf_error; - } - - for (i = 0; i < stream_info->num_planes; i++) - vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr( - vfe_dev, stream_info->wm[i], - pingpong_status, buf->mapped_info[i].paddr + - stream_info->plane_cfg[i].plane_addr_offset); - - stream_info->buf[pingpong_bit] = buf; - - return 0; -buf_error: - vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx); - return rc; -} - -static void msm_isp_process_done_buf(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf, - struct msm_isp_timestamp *ts) -{ - int rc; - struct msm_isp32_event_data buf_event; - struct timeval *time_stamp; - uint32_t stream_idx = HANDLE_TO_IDX(stream_info->stream_handle); - uint32_t frame_id; - uint32_t buf_src; - - memset(&buf_event, 0, sizeof(buf_event)); - - if (stream_idx >= MAX_NUM_STREAM) { - pr_err("%s: Invalid stream_idx", __func__); - return; - } - - if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX) - frame_id = vfe_dev->axi_data. - src_info[SRC_TO_INTF(stream_info->stream_src)].frame_id; - else { - pr_err("%s: Invalid stream index, put buf back to vb2 queue\n", - __func__); - vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx); - return; - } - - if (buf && ts) { - if (vfe_dev->vt_enable) { - msm_isp_get_avtimer_ts(ts); - time_stamp = &ts->vt_time; - } else - time_stamp = &ts->buf_time; - - rc = vfe_dev->buf_mgr->ops->get_buf_src(vfe_dev->buf_mgr, - buf->bufq_handle, &buf_src); - if (stream_info->buf_divert && rc == 0 && - buf_src != MSM_ISP_BUFFER_SRC_SCRATCH) { - rc = vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx, - time_stamp, frame_id); - /* Buf divert return value represent whether the buf - * can be diverted. A positive return value means - * other ISP hardware is still processing the frame. - */ - if (rc == 0) { - buf_event.input_intf = - SRC_TO_INTF(stream_info->stream_src); - buf_event.frame_id = frame_id; - buf_event.timestamp = *time_stamp; - buf_event.u.buf_done.session_id = - stream_info->session_id; - buf_event.u.buf_done.stream_id = - stream_info->stream_id; - buf_event.u.buf_done.handle = - stream_info->bufq_handle; - buf_event.u.buf_done.buf_idx = buf->buf_idx; - buf_event.u.buf_done.output_format = - stream_info->runtime_output_format; - msm_isp_send_event(vfe_dev, - ISP_EVENT_BUF_DIVERT + stream_idx, - &buf_event); - } - } else { - buf_event.input_intf = - SRC_TO_INTF(stream_info->stream_src); - buf_event.frame_id = frame_id; - buf_event.timestamp = ts->buf_time; - buf_event.u.buf_done.session_id = - stream_info->session_id; - buf_event.u.buf_done.stream_id = - stream_info->stream_id; - buf_event.u.buf_done.output_format = - stream_info->runtime_output_format; - msm_isp_send_event(vfe_dev, - ISP_EVENT_BUF_DONE, &buf_event); - vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx, - time_stamp, frame_id, - stream_info->runtime_output_format); - } - } -} - -static enum msm_isp_camif_update_state - msm_isp_get_camif_update_state(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd) -{ - int i; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint8_t pix_stream_cnt = 0, cur_pix_stream_cnt; - - cur_pix_stream_cnt = - axi_data->src_info[VFE_PIX_0].pix_stream_count + - axi_data->src_info[VFE_PIX_0].raw_stream_count; - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - stream_info = - &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - if (stream_info->stream_src < RDI_INTF_0) - pix_stream_cnt++; - } - - if ((pix_stream_cnt) && - (axi_data->src_info[VFE_PIX_0].input_mux != EXTERNAL_READ)) { - - if (cur_pix_stream_cnt == 0 && pix_stream_cnt && - stream_cfg_cmd->cmd == START_STREAM) - return ENABLE_CAMIF; - else if (cur_pix_stream_cnt && - (cur_pix_stream_cnt - pix_stream_cnt) == 0 && - stream_cfg_cmd->cmd == STOP_STREAM) - return DISABLE_CAMIF; - else if (cur_pix_stream_cnt && - (cur_pix_stream_cnt - pix_stream_cnt) == 0 && - stream_cfg_cmd->cmd == STOP_IMMEDIATELY) - return DISABLE_CAMIF_IMMEDIATELY; - } - - return NO_UPDATE; -} - -static void msm_isp_update_camif_output_count( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd) -{ - int i; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) - return; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= - MAX_NUM_STREAM) { - return; - } - stream_info = - &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - if (stream_info->stream_src >= RDI_INTF_0) - continue; - if (stream_info->stream_src == PIX_ENCODER || - stream_info->stream_src == PIX_VIEWFINDER || - stream_info->stream_src == PIX_VIDEO || - stream_info->stream_src == IDEAL_RAW) { - if (stream_cfg_cmd->cmd == START_STREAM) - vfe_dev->axi_data.src_info[VFE_PIX_0]. - pix_stream_count++; - else - vfe_dev->axi_data.src_info[VFE_PIX_0]. - pix_stream_count--; - } else if (stream_info->stream_src == CAMIF_RAW) { - if (stream_cfg_cmd->cmd == START_STREAM) - vfe_dev->axi_data.src_info[VFE_PIX_0]. - raw_stream_count++; - else - vfe_dev->axi_data.src_info[VFE_PIX_0]. - raw_stream_count--; - } - } -} - - -static void msm_isp_update_rdi_output_count( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd) -{ - int i; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) - return; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) - > MAX_NUM_STREAM) - return; - stream_info = - &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - if (stream_info->stream_src < RDI_INTF_0) - continue; - if (stream_info->stream_src == RDI_INTF_0) { - if (stream_cfg_cmd->cmd == START_STREAM) - vfe_dev->axi_data.src_info[VFE_RAW_0]. - raw_stream_count++; - else - vfe_dev->axi_data.src_info[VFE_RAW_0]. - raw_stream_count--; - } else if (stream_info->stream_src == RDI_INTF_1) { - if (stream_cfg_cmd->cmd == START_STREAM) - vfe_dev->axi_data.src_info[VFE_RAW_1]. - raw_stream_count++; - else - vfe_dev->axi_data.src_info[VFE_RAW_1]. - raw_stream_count--; - } else if (stream_info->stream_src == RDI_INTF_2) { - if (stream_cfg_cmd->cmd == START_STREAM) - vfe_dev->axi_data.src_info[VFE_RAW_2]. - raw_stream_count++; - else - vfe_dev->axi_data.src_info[VFE_RAW_2]. - raw_stream_count--; - } - - } -} - -static uint8_t msm_isp_get_curr_stream_cnt( - struct vfe_device *vfe_dev) -{ - uint8_t curr_stream_cnt = 0; - - curr_stream_cnt = vfe_dev->axi_data.src_info[VFE_RAW_0]. - raw_stream_count + - vfe_dev->axi_data.src_info[VFE_RAW_1]. - raw_stream_count + - vfe_dev->axi_data.src_info[VFE_RAW_2]. - raw_stream_count + - vfe_dev->axi_data.src_info[VFE_PIX_0]. - pix_stream_count + - vfe_dev->axi_data.src_info[VFE_PIX_0]. - raw_stream_count; - - return curr_stream_cnt; -} - -/*Factor in Q2 format*/ -#define ISP_DEFAULT_FORMAT_FACTOR 6 -#define ISP_BUS_UTILIZATION_FACTOR 1536 /* 1.5 in Q10 format */ -static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev) -{ - int i, rc = 0; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint64_t total_pix_bandwidth = 0, total_rdi_bandwidth = 0; - uint32_t num_pix_streams = 0; - uint32_t num_rdi_streams = 0; - uint32_t total_streams = 0; - uint64_t total_bandwidth = 0; - uint32_t bus_util_factor = ISP_BUS_UTILIZATION_FACTOR; - - for (i = 0; i < MAX_NUM_STREAM; i++) { - stream_info = &axi_data->stream_info[i]; - if (stream_info->state == ACTIVE || - stream_info->state == START_PENDING) { - if (stream_info->stream_src < RDI_INTF_0) { - total_pix_bandwidth += stream_info->bandwidth; - num_pix_streams++; - } else { - total_rdi_bandwidth += stream_info->bandwidth; - num_rdi_streams++; - } - } - } - total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth; - total_streams = num_pix_streams + num_rdi_streams; - if (vfe_dev->bus_util_factor) - bus_util_factor = vfe_dev->bus_util_factor; - ISP_DBG("%s: bus_util_factor = %u\n", __func__, bus_util_factor); - - if (total_streams == 1) - rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, - total_bandwidth , - (total_bandwidth * bus_util_factor / ISP_Q10)); - else - rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, - (total_bandwidth + MSM_ISP_MIN_AB), (total_bandwidth * - bus_util_factor / ISP_Q10 + MSM_ISP_MIN_IB)); - if (rc < 0) - pr_err("%s: update failed\n", __func__); - - return rc; -} - -static int msm_isp_axi_wait_for_cfg_done(struct vfe_device *vfe_dev, - enum msm_isp_camif_update_state camif_update) -{ - int rc; - unsigned long flags; - - spin_lock_irqsave(&vfe_dev->shared_data_lock, flags); - init_completion(&vfe_dev->stream_config_complete); - vfe_dev->axi_data.pipeline_update = camif_update; - spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags); - rc = wait_for_completion_timeout( - &vfe_dev->stream_config_complete, - msecs_to_jiffies(VFE_MAX_CFG_TIMEOUT)); - if (rc == 0) { - pr_err("%s: wait timeout\n", __func__); - rc = -1; - } else { - rc = 0; - } - return rc; -} - -static int msm_isp_init_stream_ping_pong_reg( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - int rc = 0; - /*Set address for both PING & PONG register */ - rc = msm_isp_cfg_ping_pong_address(vfe_dev, - stream_info, VFE_PING_FLAG, 0); - if (rc < 0) { - pr_err("%s: No free buffer for ping\n", - __func__); - return rc; - } - - /* For burst stream of one capture, only one buffer - * is allocated. Duplicate ping buffer address to pong - * buffer to ensure hardware write to a valid address - */ - if (stream_info->stream_type == BURST_STREAM && - stream_info->runtime_num_burst_capture <= 1) { - msm_isp_cfg_pong_address(vfe_dev, stream_info); - } else { - rc = msm_isp_cfg_ping_pong_address(vfe_dev, - stream_info, VFE_PONG_FLAG, 1); - if (rc < 0) { - pr_err("%s: No free buffer for pong\n", - __func__); - return rc; - } - } - return rc; -} - -static void msm_isp_deinit_stream_ping_pong_reg( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info) -{ - int i; - - for (i = 0; i < 2; i++) { - struct msm_isp_buffer *buf; - - buf = stream_info->buf[i]; - if (buf) { - vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx); - } - } -} - -static void msm_isp_get_stream_wm_mask( - struct msm_vfe_axi_stream *stream_info, - uint32_t *wm_reload_mask) -{ - int i; - - for (i = 0; i < stream_info->num_planes; i++) - *wm_reload_mask |= (1 << stream_info->wm[i]); -} - -int msm_isp_axi_halt(struct vfe_device *vfe_dev, - struct msm_vfe_axi_halt_cmd *halt_cmd) -{ - int rc = 0; - - if (halt_cmd->overflow_detected) { - /*Store current IRQ mask*/ - if (vfe_dev->error_info.overflow_recover_irq_mask0 == 0) { - vfe_dev->hw_info->vfe_ops.core_ops.get_irq_mask(vfe_dev, - &vfe_dev->error_info.overflow_recover_irq_mask0, - &vfe_dev->error_info.overflow_recover_irq_mask1); - } - atomic_set(&vfe_dev->error_info.overflow_state, - OVERFLOW_DETECTED); - } - - rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1); - - if (halt_cmd->stop_camif) { - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY); - } - - return rc; -} - -int msm_isp_axi_reset(struct vfe_device *vfe_dev, - struct msm_vfe_axi_reset_cmd *reset_cmd) -{ - int rc = 0, i, j; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_isp_bufq *bufq = NULL; - - if (!reset_cmd) { - pr_err("%s: NULL pointer reset cmd %pK\n", __func__, reset_cmd); - rc = -1; - return rc; - } - - rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, - 0, reset_cmd->blocking); - - for (i = 0, j = 0; j < axi_data->num_active_stream && - i < MAX_NUM_STREAM; i++, j++) { - stream_info = &axi_data->stream_info[i]; - if (stream_info->stream_src >= VFE_AXI_SRC_MAX) { - rc = -1; - pr_err("%s invalid stream src = %d\n", __func__, - stream_info->stream_src); - break; - } - if (stream_info->state != ACTIVE) { - j--; - continue; - } - - bufq = vfe_dev->buf_mgr->ops->get_bufq(vfe_dev->buf_mgr, - stream_info->bufq_handle); - if (!bufq) { - pr_err("%s: bufq null %pK by handle %x\n", __func__, - bufq, stream_info->bufq_handle); - continue; - } - - if (bufq->buf_type != ISP_SHARE_BUF) { - msm_isp_deinit_stream_ping_pong_reg(vfe_dev, - stream_info); - } else { - vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, - stream_info->bufq_handle, - MSM_ISP_BUFFER_FLUSH_ALL); - } - axi_data->src_info[SRC_TO_INTF(stream_info->stream_src)]. - frame_id = reset_cmd->frame_id; - msm_isp_reset_burst_count_and_frame_drop(vfe_dev, stream_info); - } - - if (rc < 0) - pr_err("%s Error! reset hw Timed out\n", __func__); - - return rc; -} - -int msm_isp_axi_restart(struct vfe_device *vfe_dev, - struct msm_vfe_axi_restart_cmd *restart_cmd) -{ - int rc = 0, i, j; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint32_t wm_reload_mask = 0x0; - - for (i = 0, j = 0; j < axi_data->num_active_stream && - i < MAX_NUM_STREAM; i++, j++) { - stream_info = &axi_data->stream_info[i]; - if (stream_info->state != ACTIVE) { - j--; - continue; - } - msm_isp_get_stream_wm_mask(stream_info, &wm_reload_mask); - msm_isp_init_stream_ping_pong_reg(vfe_dev, stream_info); - } - - vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, wm_reload_mask); - rc = vfe_dev->hw_info->vfe_ops.axi_ops.restart(vfe_dev, 0, - restart_cmd->enable_camif); - if (rc < 0) - pr_err("%s Error restarting HW\n", __func__); - - return rc; -} - -static int msm_isp_axi_update_cgc_override(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd, - uint8_t cgc_override) -{ - int i = 0, j = 0; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) - return -EINVAL; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= - MAX_NUM_STREAM) { - return -EINVAL; - } - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - for (j = 0; j < stream_info->num_planes; j++) { - if (vfe_dev->hw_info->vfe_ops.axi_ops. - update_cgc_override) - vfe_dev->hw_info->vfe_ops.axi_ops. - update_cgc_override(vfe_dev, - stream_info->wm[j], cgc_override); - } - } - return 0; -} - -static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd, - enum msm_isp_camif_update_state camif_update) -{ - int i, rc = 0; - uint8_t src_state, wait_for_complete = 0; - uint32_t wm_reload_mask = 0x0; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint8_t init_frm_drop = 0; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) - return -EINVAL; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= - MAX_NUM_STREAM) { - return -EINVAL; - } - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - if (SRC_TO_INTF(stream_info->stream_src) < VFE_SRC_MAX) - src_state = axi_data->src_info[ - SRC_TO_INTF(stream_info->stream_src)].active; - else { - pr_err("%s: invalid src info index\n", __func__); - return -EINVAL; - } - - msm_isp_calculate_bandwidth(axi_data, stream_info); - msm_isp_reset_framedrop(vfe_dev, stream_info); - init_frm_drop = stream_info->init_frame_drop; - msm_isp_get_stream_wm_mask(stream_info, &wm_reload_mask); - rc = msm_isp_init_stream_ping_pong_reg(vfe_dev, stream_info); - if (rc < 0) { - pr_err("%s: No buffer for stream %d\n", - __func__, - HANDLE_TO_IDX( - stream_cfg_cmd->stream_handle[i])); - return rc; - } - - stream_info->state = START_PENDING; - if (src_state) { - wait_for_complete = 1; - } else { - if (vfe_dev->dump_reg) - msm_camera_io_dump_2(vfe_dev->vfe_base, 0x900); - - /*Configure AXI start bits to start immediately*/ - msm_isp_axi_stream_enable_cfg(vfe_dev, stream_info); - stream_info->state = ACTIVE; - } - if (SRC_TO_INTF(stream_info->stream_src) != VFE_PIX_0 && - stream_info->stream_src < VFE_AXI_SRC_MAX) { - vfe_dev->axi_data.src_info[SRC_TO_INTF( - stream_info->stream_src)].frame_id = - init_frm_drop; - } - } - msm_isp_update_stream_bandwidth(vfe_dev); - vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, wm_reload_mask); - vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, 0xF); - msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd); - msm_isp_update_rdi_output_count(vfe_dev, stream_cfg_cmd); - if (camif_update == ENABLE_CAMIF) { - atomic_set(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW); - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id = 0; - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, camif_update); - } - - if (wait_for_complete) { - vfe_dev->axi_data.stream_update = stream_cfg_cmd->num_streams; - rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update); - } - - return rc; -} - -static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd, - enum msm_isp_camif_update_state camif_update) -{ - int i, rc = 0; - uint8_t wait_for_complete_for_this_stream = 0, cur_stream_cnt = 0; - uint8_t wait_for_complete = 0; - struct msm_vfe_axi_stream *stream_info = NULL; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - int ext_read = - axi_data->src_info[VFE_PIX_0].input_mux == EXTERNAL_READ; - - if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM || - stream_cfg_cmd->num_streams == 0) - return -EINVAL; - - msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd); - msm_isp_update_rdi_output_count(vfe_dev, stream_cfg_cmd); - cur_stream_cnt = msm_isp_get_curr_stream_cnt(vfe_dev); - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i]) >= - MAX_NUM_STREAM) { - return -EINVAL; - } - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - wait_for_complete_for_this_stream = 0; - stream_info->state = STOP_PENDING; - if (stream_info->stream_src == CAMIF_RAW || - stream_info->stream_src == IDEAL_RAW) { - /* We dont get reg update IRQ for raw snapshot - * so frame skip cant be ocnfigured - */ - if ((camif_update != DISABLE_CAMIF_IMMEDIATELY) && - (!ext_read)) - wait_for_complete_for_this_stream = 1; - } else if (stream_info->stream_type == BURST_STREAM && - stream_info->runtime_num_burst_capture == 0) { - /* Configure AXI writemasters to stop immediately - * since for burst case, write masters already skip - * all frames. - */ - if (stream_info->stream_src == RDI_INTF_0 || - stream_info->stream_src == RDI_INTF_1 || - stream_info->stream_src == RDI_INTF_2) - wait_for_complete_for_this_stream = 1; - } else { - if ((camif_update != DISABLE_CAMIF_IMMEDIATELY) && - (!ext_read) && - !(stream_info->stream_src == RDI_INTF_0 || - stream_info->stream_src == RDI_INTF_1 || - stream_info->stream_src == RDI_INTF_2)) - wait_for_complete_for_this_stream = 1; - } - if (!wait_for_complete_for_this_stream) { - msm_isp_axi_stream_enable_cfg(vfe_dev, stream_info); - stream_info->state = INACTIVE; - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, 0xF); - } - wait_for_complete |= wait_for_complete_for_this_stream; - } - if (wait_for_complete) { - vfe_dev->axi_data.stream_update = stream_cfg_cmd->num_streams; - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, 0xF); - rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update); - if (rc < 0) { - pr_err("%s: wait for config done failed\n", __func__); - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX( - stream_cfg_cmd->stream_handle[i])]; - stream_info->state = STOP_PENDING; - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, 0xF); - msm_isp_axi_stream_enable_cfg( - vfe_dev, stream_info); - stream_info->state = INACTIVE; - } - } - } - if (camif_update == DISABLE_CAMIF) { - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, DISABLE_CAMIF); - } else if ((camif_update == DISABLE_CAMIF_IMMEDIATELY) || - (ext_read)) { - /*during stop immediately, stop output then stop input*/ - if (!ext_read) - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, - DISABLE_CAMIF_IMMEDIATELY); - } - if (cur_stream_cnt == 0) { - vfe_dev->ignore_error = 1; - vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1); - vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 1, 1); - vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); - vfe_dev->ignore_error = 0; - } - msm_isp_update_stream_bandwidth(vfe_dev); - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])]; - msm_isp_deinit_stream_ping_pong_reg(vfe_dev, stream_info); - } - - return rc; -} - - -int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0; - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd = arg; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - enum msm_isp_camif_update_state camif_update; - - rc = msm_isp_axi_check_stream_state(vfe_dev, stream_cfg_cmd); - if (rc < 0) { - pr_err("%s: Invalid stream state\n", __func__); - return rc; - } - - if (axi_data->num_active_stream == 0) { - /*Configure UB*/ - vfe_dev->hw_info->vfe_ops.axi_ops.cfg_ub(vfe_dev); - } - camif_update = msm_isp_get_camif_update_state(vfe_dev, stream_cfg_cmd); - - if (stream_cfg_cmd->cmd == START_STREAM) { - msm_isp_axi_update_cgc_override(vfe_dev, stream_cfg_cmd, 1); - - rc = msm_isp_start_axi_stream( - vfe_dev, stream_cfg_cmd, camif_update); - } else { - rc = msm_isp_stop_axi_stream( - vfe_dev, stream_cfg_cmd, camif_update); - - msm_isp_axi_update_cgc_override(vfe_dev, stream_cfg_cmd, 0); - } - - if (rc < 0) - pr_err("%s: start/stop stream failed\n", __func__); - return rc; -} - -static int msm_isp_request_frame(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, uint32_t request_frm_num) -{ - struct msm_vfe32_axi_stream_request_cmd stream_cfg_cmd; - int rc = 0; - uint32_t pingpong_status, pingpong_bit, wm_reload_mask = 0x0; - - if (!stream_info->controllable_output) - return 0; - - if (!request_frm_num) { - pr_err("%s: Invalid frame request.\n", __func__); - return -EINVAL; - } - - stream_info->request_frm_num += request_frm_num; - - stream_cfg_cmd.axi_stream_handle = stream_info->stream_handle; - stream_cfg_cmd.frame_skip_pattern = NO_SKIP; - stream_cfg_cmd.init_frame_drop = 0; - stream_cfg_cmd.burst_count = stream_info->request_frm_num; - msm_isp_calculate_framedrop(&vfe_dev->axi_data, &stream_cfg_cmd); - msm_isp_reset_framedrop(vfe_dev, stream_info); - - if (stream_info->request_frm_num != request_frm_num) { - pingpong_status = - vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status( - vfe_dev); - pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1); - - if (!stream_info->buf[pingpong_bit]) { - rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, - pingpong_status, pingpong_bit); - if (rc) { - pr_err("%s:%d fail to set ping pong address\n", - __func__, __LINE__); - return rc; - } - } - - if (!stream_info->buf[!pingpong_bit] && request_frm_num > 1) { - rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, - ~pingpong_status, !pingpong_bit); - if (rc) { - pr_err("%s:%d fail to set ping pong address\n", - __func__, __LINE__); - return rc; - } - } - } else { - if (!stream_info->buf[0]) { - rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, - VFE_PING_FLAG, 0); - if (rc) { - pr_err("%s:%d fail to set ping pong address\n", - __func__, __LINE__); - return rc; - } - } - - if (!stream_info->buf[1] && request_frm_num > 1) { - rc = msm_isp_cfg_ping_pong_address(vfe_dev, stream_info, - VFE_PONG_FLAG, 1); - if (rc) { - pr_err("%s:%d fail to set ping pong address\n", - __func__, __LINE__); - return rc; - } - } - - msm_isp_get_stream_wm_mask(stream_info, &wm_reload_mask); - vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, - wm_reload_mask); - } - - return rc; -} - -int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0, i, j; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - struct msm_vfe_axi_stream_update_cmd *update_cmd = arg; - struct msm_vfe_axi_stream_cfg_update_info *update_info; - - if (update_cmd->update_type == UPDATE_STREAM_AXI_CONFIG && - atomic_read(&axi_data->axi_cfg_update)) { - pr_err("%s: AXI stream config updating\n", __func__); - return -EBUSY; - } - - /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/ - if (update_cmd->num_streams > MAX_NUM_STREAM) - return -EINVAL; - - for (i = 0; i < update_cmd->num_streams; i++) { - update_info = &update_cmd->update_info[i]; - /*check array reference bounds*/ - if (HANDLE_TO_IDX(update_info->stream_handle) >= - MAX_NUM_STREAM) { - return -EINVAL; - } - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(update_info->stream_handle)]; - if (stream_info->state != ACTIVE && - stream_info->state != INACTIVE) { - pr_err("%s: Invalid stream state\n", __func__); - return -EINVAL; - } - } - - for (i = 0; i < update_cmd->num_streams; i++) { - update_info = &update_cmd->update_info[i]; - stream_info = &axi_data->stream_info[ - HANDLE_TO_IDX(update_info->stream_handle)]; - - switch (update_cmd->update_type) { - case ENABLE_STREAM_BUF_DIVERT: - stream_info->buf_divert = 1; - break; - case DISABLE_STREAM_BUF_DIVERT: - stream_info->buf_divert = 0; - vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr, - stream_info->bufq_handle, - MSM_ISP_BUFFER_FLUSH_DIVERTED); - break; - case UPDATE_STREAM_FRAMEDROP_PATTERN: { - uint32_t framedrop_period = - msm_isp_get_framedrop_period( - update_info->skip_pattern); - if (update_info->skip_pattern == SKIP_ALL) - stream_info->framedrop_pattern = 0x0; - else - stream_info->framedrop_pattern = 0x1; - stream_info->framedrop_period = framedrop_period - 1; - if (stream_info->stream_type == BURST_STREAM) { - stream_info->runtime_framedrop_update_burst = 1; - } else { - stream_info->runtime_init_frame_drop = 0; - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_framedrop(vfe_dev, stream_info); - } - break; - } - case UPDATE_STREAM_AXI_CONFIG: { - for (j = 0; j < stream_info->num_planes; j++) { - stream_info->plane_cfg[j] = - update_info->plane_cfg[j]; - } - stream_info->output_format = update_info->output_format; - if (stream_info->state == ACTIVE) { - stream_info->state = PAUSE_PENDING; - msm_isp_axi_stream_enable_cfg( - vfe_dev, stream_info); - stream_info->state = PAUSING; - atomic_set(&axi_data->axi_cfg_update, - UPDATE_REQUESTED); - } else { - for (j = 0; j < stream_info->num_planes; j++) - vfe_dev->hw_info->vfe_ops.axi_ops. - cfg_wm_reg(vfe_dev, stream_info, j); - stream_info->runtime_output_format = - stream_info->output_format; - } - break; - } - case UPDATE_STREAM_REQUEST_FRAMES: { - rc = msm_isp_request_frame(vfe_dev, stream_info, - update_info->frame_id); - if (rc) - pr_err("%s failed to request frame!\n", - __func__); - break; - } - default: - pr_err("%s: Invalid update type\n", __func__); - return -EINVAL; - } - } - return rc; -} - -void msm_isp_process_axi_irq(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts) -{ - int i, rc = 0; - struct msm_isp_buffer *done_buf = NULL; - uint32_t comp_mask = 0, wm_mask = 0; - uint32_t pingpong_status, stream_idx; - struct msm_vfe_axi_stream *stream_info; - struct msm_vfe_axi_composite_info *comp_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - uint32_t pingpong_bit = 0, frame_id = 0; - - comp_mask = vfe_dev->hw_info->vfe_ops.axi_ops. - get_comp_mask(irq_status0, irq_status1); - wm_mask = vfe_dev->hw_info->vfe_ops.axi_ops. - get_wm_mask(irq_status0, irq_status1); - if (!(comp_mask || wm_mask)) - return; - - ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0); - pingpong_status = - vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev); - for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) { - rc = 0; - comp_info = &axi_data->composite_info[i]; - if (comp_mask & (1 << i)) { - stream_idx = HANDLE_TO_IDX(comp_info->stream_handle); - if ((!comp_info->stream_handle) || - (stream_idx >= MAX_NUM_STREAM)) { - pr_err("%s: Invalid handle for composite irq\n", - __func__); - } else { - stream_idx = - HANDLE_TO_IDX(comp_info->stream_handle); - stream_info = - &axi_data->stream_info[stream_idx]; - - pingpong_bit = (~(pingpong_status >> - stream_info->wm[0]) & 0x1); - - if (stream_info->stream_type == BURST_STREAM) - stream_info-> - runtime_num_burst_capture--; - - msm_isp_get_done_buf(vfe_dev, stream_info, - pingpong_status, &done_buf); - if (stream_info->stream_type == - CONTINUOUS_STREAM || - stream_info-> - runtime_num_burst_capture > 1) { - rc = msm_isp_cfg_ping_pong_address( - vfe_dev, stream_info, - pingpong_status, - pingpong_bit); - } - frame_id = vfe_dev->axi_data. - src_info[SRC_TO_INTF( - stream_info->stream_src)]. - frame_id; - stream_info->frame_id = frame_id; - ISP_DBG("%s: stream id:%d frame id:%d\n", - __func__, stream_info->stream_id, - stream_info->frame_id); - if (done_buf && !rc) - msm_isp_process_done_buf(vfe_dev, - stream_info, done_buf, ts); - } - } - wm_mask &= ~(comp_info->stream_composite_mask); - } - - for (i = 0; i < axi_data->hw_info->num_wm; i++) { - if (wm_mask & (1 << i)) { - stream_idx = HANDLE_TO_IDX(axi_data->free_wm[i]); - if ((!axi_data->free_wm[i]) || - (stream_idx >= MAX_NUM_STREAM)) { - pr_err("%s: Invalid handle for wm irq\n", - __func__); - continue; - } - stream_info = &axi_data->stream_info[stream_idx]; - - pingpong_bit = (~(pingpong_status >> - stream_info->wm[0]) & 0x1); - - if (stream_info->stream_type == BURST_STREAM) - stream_info->runtime_num_burst_capture--; - - msm_isp_get_done_buf(vfe_dev, stream_info, - pingpong_status, &done_buf); - if (stream_info->stream_type == CONTINUOUS_STREAM || - stream_info->runtime_num_burst_capture > 1) { - rc = msm_isp_cfg_ping_pong_address(vfe_dev, - stream_info, pingpong_status, - pingpong_bit); - } - stream_info->frame_id = frame_id; - ISP_DBG("%s: stream id:%d frame id:%d\n", - __func__, stream_info->stream_id, - stream_info->frame_id); - if (done_buf && !rc) - msm_isp_process_done_buf(vfe_dev, - stream_info, done_buf, ts); - } - } -} -int msm_isp_user_buf_done(struct vfe_device *vfe_dev, - struct msm_isp32_event_data *buf_cmd) -{ - int rc = 0; - struct msm_isp32_event_data buf_event; - - memset(&buf_event, 0, sizeof(buf_event)); - buf_event.input_intf = buf_cmd->input_intf; - buf_event.frame_id = buf_cmd->frame_id; - buf_event.timestamp = buf_cmd->timestamp; - buf_event.u.buf_done.session_id = - buf_cmd->u.buf_done.session_id; - buf_event.u.buf_done.stream_id = - buf_cmd->u.buf_done.stream_id; - buf_event.u.buf_done.output_format = - buf_cmd->u.buf_done.output_format; - buf_event.u.buf_done.buf_idx = - buf_cmd->u.buf_done.buf_idx; - buf_event.u.buf_done.handle = - buf_cmd->u.buf_done.handle; - - vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, - buf_event.u.buf_done.handle, - buf_event.u.buf_done.buf_idx, - &buf_event.timestamp, buf_event.frame_id, - buf_event.u.buf_done.output_format); - return rc; -} diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.h deleted file mode 100644 index 633a14c01f80..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util_32.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __MSM_ISP_AXI_UTIL_H__ -#define __MSM_ISP_AXI_UTIL_H__ - -#include "msm_isp_32.h" - -int msm_isp_axi_create_stream( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd); - -void msm_isp_axi_destroy_stream( - struct msm_vfe_axi_shared_data *axi_data, int stream_idx); - -int msm_isp_validate_axi_request( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd); - -void msm_isp_axi_reserve_wm( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info); - -void msm_isp_axi_reserve_comp_mask( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe_axi_stream *stream_info); - -int msm_isp_axi_check_stream_state( - struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd); - -void msm_isp_calculate_framedrop( - struct msm_vfe_axi_shared_data *axi_data, - struct msm_vfe32_axi_stream_request_cmd *stream_cfg_cmd); -void msm_isp_reset_framedrop(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info); - -int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg); -void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev); -int msm_isp_axi_halt(struct vfe_device *vfe_dev, - struct msm_vfe_axi_halt_cmd *halt_cmd); -int msm_isp_axi_reset(struct vfe_device *vfe_dev, - struct msm_vfe_axi_reset_cmd *reset_cmd); -int msm_isp_axi_restart(struct vfe_device *vfe_dev, - struct msm_vfe_axi_restart_cmd *restart_cmd); -int msm_isp_user_buf_done(struct vfe_device *vfe_dev, - struct msm_isp32_event_data *buf_cmd); -void msm_isp_axi_stream_update(struct vfe_device *vfe_dev, - uint8_t input_src); - -void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev, - uint8_t input_src); -void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type, - enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts); -void msm_isp_process_axi_irq(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); -#endif /* __MSM_ISP_AXI_UTIL_H__ */ diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c old mode 100644 new mode 100755 index efe53cc6e3ac..7e3f29198e42 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -250,9 +250,6 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, *comp_stats_type_mask |= 1 << stream_info->stats_type; } - stats_event->pd_stats_idx = 0xF; - if (stream_info->stats_type == MSM_ISP_STATS_BF) - stats_event->pd_stats_idx = vfe_dev->pd_buf_idx; } return rc; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.c deleted file mode 100644 index c896a0ff4660..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.c +++ /dev/null @@ -1,708 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include "msm_isp_util_32.h" -#include "msm_isp_stats_util_32.h" - -static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info, uint32_t pingpong_status, - struct msm_isp_buffer **done_buf) -{ - int rc = -1; - struct msm_isp_buffer *buf; - uint32_t pingpong_bit = 0; - uint32_t bufq_handle = stream_info->bufq_handle; - uint32_t stats_pingpong_offset; - uint32_t stats_idx = STATS_IDX(stream_info->stream_handle); - - if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type || - stats_idx >= MSM_ISP_STATS_MAX) { - pr_err("%s Invalid stats index %d", __func__, stats_idx); - return -EINVAL; - } - - stats_pingpong_offset = - vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset[ - stats_idx]; - - pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1); - rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr, - vfe_dev->pdev->id, bufq_handle, &buf); - if (rc < 0) { - vfe_dev->error_info.stats_framedrop_count[stats_idx]++; - return rc; - } - - if (buf->num_planes != 1) { - pr_err("%s: Invalid buffer\n", __func__); - rc = -EINVAL; - goto buf_error; - } - - vfe_dev->hw_info->vfe_ops.stats_ops.update_ping_pong_addr( - vfe_dev, stream_info, - pingpong_status, buf->mapped_info[0].paddr + - stream_info->buffer_offset); - - if (stream_info->buf[pingpong_bit] && done_buf) - *done_buf = stream_info->buf[pingpong_bit]; - - stream_info->buf[pingpong_bit] = buf; - return 0; -buf_error: - vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx); - return rc; -} - -void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts) -{ - int i, j, rc; - struct msm_isp32_event_data buf_event; - struct msm_isp_stats_event *stats_event = &buf_event.u.stats; - struct msm_isp_buffer *done_buf; - struct msm_vfe_stats_stream *stream_info = NULL; - uint32_t pingpong_status; - uint32_t comp_stats_type_mask = 0, atomic_stats_mask = 0; - uint32_t stats_comp_mask = 0, stats_irq_mask = 0; - uint32_t num_stats_comp_mask = - vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; - stats_comp_mask = vfe_dev->hw_info->vfe_ops.stats_ops. - get_comp_mask(irq_status0, irq_status1); - stats_irq_mask = vfe_dev->hw_info->vfe_ops.stats_ops. - get_wm_mask(irq_status0, irq_status1); - if (!(stats_comp_mask || stats_irq_mask)) - return; - ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0); - - /* - * If any of composite mask is set, clear irq bits from mask, - * they will be restored by comp mask - */ - if (stats_comp_mask) { - for (j = 0; j < num_stats_comp_mask; j++) { - stats_irq_mask &= ~atomic_read( - &vfe_dev->stats_data.stats_comp_mask[j]); - } - } - - for (j = 0; j < num_stats_comp_mask; j++) { - atomic_stats_mask = atomic_read( - &vfe_dev->stats_data.stats_comp_mask[j]); - if (!stats_comp_mask) { - stats_irq_mask &= ~atomic_stats_mask; - } else { - /* restore irq bits from composite mask */ - if (stats_comp_mask & (1 << j)) - stats_irq_mask |= atomic_stats_mask; - } - /* if no irq bits set from this composite mask continue*/ - if (!stats_irq_mask) - continue; - memset(&buf_event, 0, sizeof(struct msm_isp32_event_data)); - buf_event.timestamp = ts->event_time; - buf_event.frame_id = - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; - buf_event.input_intf = VFE_PIX_0; - pingpong_status = vfe_dev->hw_info-> - vfe_ops.stats_ops.get_pingpong_status(vfe_dev); - - for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; - i++) { - if (!(stats_irq_mask & (1 << i))) - continue; - - stats_irq_mask &= ~(1 << i); - stream_info = &vfe_dev->stats_data.stream_info[i]; - done_buf = NULL; - msm_isp_stats_cfg_ping_pong_address(vfe_dev, - stream_info, pingpong_status, &done_buf); - if (done_buf) { - rc = vfe_dev->buf_mgr->ops->buf_divert( - vfe_dev->buf_mgr, done_buf->bufq_handle, - done_buf->buf_idx, &ts->buf_time, - vfe_dev->axi_data. - src_info[VFE_PIX_0].frame_id); - if (rc != 0) - continue; - - stats_event->stats_buf_idxs - [stream_info->stats_type] = - done_buf->buf_idx; - if (!stream_info->composite_flag) { - stats_event->stats_mask = - 1 << stream_info->stats_type; - ISP_DBG("%s: stats frameid: 0x%x %d\n", - __func__, buf_event.frame_id, - stream_info->stats_type); - msm_isp_send_event(vfe_dev, - ISP_EVENT_STATS_NOTIFY + - stream_info->stats_type, - &buf_event); - } else { - comp_stats_type_mask |= - 1 << stream_info->stats_type; - } - } - } - - if (comp_stats_type_mask) { - ISP_DBG("%s: comp_stats frameid: 0x%x, 0x%x\n", - __func__, buf_event.frame_id, - comp_stats_type_mask); - stats_event->stats_mask = comp_stats_type_mask; - msm_isp_send_event(vfe_dev, - ISP_EVENT_COMP_STATS_NOTIFY, &buf_event); - comp_stats_type_mask = 0; - } - } -} - -int msm_isp_stats_create_stream(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream_request_cmd *stream_req_cmd) -{ - int rc = -1; - struct msm_vfe_stats_stream *stream_info = NULL; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - uint32_t stats_idx; - - if (!(vfe_dev->hw_info->stats_hw_info->stats_capability_mask & - (1 << stream_req_cmd->stats_type))) { - pr_err("%s: Stats type not supported\n", __func__); - return rc; - } - - stats_idx = vfe_dev->hw_info->vfe_ops.stats_ops. - get_stats_idx(stream_req_cmd->stats_type); - - if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, stats_idx); - return -EINVAL; - } - - stream_info = &stats_data->stream_info[stats_idx]; - if (stream_info->state != STATS_AVAILABLE) { - pr_err("%s: Stats already requested\n", __func__); - return rc; - } - - if (stream_req_cmd->framedrop_pattern >= MAX_SKIP) { - pr_err("%s: Invalid framedrop pattern\n", __func__); - return rc; - } - - if (stream_req_cmd->irq_subsample_pattern >= MAX_SKIP) { - pr_err("%s: Invalid irq subsample pattern\n", __func__); - return rc; - } - - stream_info->session_id = stream_req_cmd->session_id; - stream_info->stream_id = stream_req_cmd->stream_id; - stream_info->composite_flag = stream_req_cmd->composite_flag; - stream_info->stats_type = stream_req_cmd->stats_type; - stream_info->buffer_offset = stream_req_cmd->buffer_offset; - stream_info->framedrop_pattern = stream_req_cmd->framedrop_pattern; - stream_info->init_stats_frame_drop = stream_req_cmd->init_frame_drop; - stream_info->irq_subsample_pattern = - stream_req_cmd->irq_subsample_pattern; - stream_info->state = STATS_INACTIVE; - - if ((vfe_dev->stats_data.stream_handle_cnt << 8) == 0) - vfe_dev->stats_data.stream_handle_cnt++; - - stream_req_cmd->stream_handle = - (++vfe_dev->stats_data.stream_handle_cnt) << 8 | stats_idx; - - stream_info->stream_handle = stream_req_cmd->stream_handle; - return 0; -} - -int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = -1; - struct msm_vfe_stats_stream_request_cmd *stream_req_cmd = arg; - struct msm_vfe_stats_stream *stream_info = NULL; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - uint32_t framedrop_period; - uint32_t stats_idx; - - rc = msm_isp_stats_create_stream(vfe_dev, stream_req_cmd); - if (rc < 0) { - pr_err("%s: create stream failed\n", __func__); - return rc; - } - - stats_idx = STATS_IDX(stream_req_cmd->stream_handle); - - if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, stats_idx); - return -EINVAL; - } - - stream_info = &stats_data->stream_info[stats_idx]; - - framedrop_period = msm_isp_get_framedrop_period( - stream_req_cmd->framedrop_pattern); - - if (stream_req_cmd->framedrop_pattern == SKIP_ALL) - stream_info->framedrop_pattern = 0x0; - else - stream_info->framedrop_pattern = 0x1; - stream_info->framedrop_period = framedrop_period - 1; - - if (!stream_info->composite_flag) - vfe_dev->hw_info->vfe_ops.stats_ops. - cfg_wm_irq_mask(vfe_dev, stream_info); - - if (stream_info->init_stats_frame_drop == 0) - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg(vfe_dev, - stream_info); - - return rc; -} - -int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = -1; - struct msm_vfe_stats_stream_cfg_cmd stream_cfg_cmd; - struct msm_vfe_stats_stream_release_cmd *stream_release_cmd = arg; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - int stats_idx = STATS_IDX(stream_release_cmd->stream_handle); - struct msm_vfe_stats_stream *stream_info = NULL; - - if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, stats_idx); - return -EINVAL; - } - - stream_info = &stats_data->stream_info[stats_idx]; - if (stream_info->state == STATS_AVAILABLE) { - pr_err("%s: stream already release\n", __func__); - return rc; - } else if (stream_info->state != STATS_INACTIVE) { - stream_cfg_cmd.enable = 0; - stream_cfg_cmd.num_streams = 1; - stream_cfg_cmd.stream_handle[0] = - stream_release_cmd->stream_handle; - rc = msm_isp_cfg_stats_stream(vfe_dev, &stream_cfg_cmd); - } - - if (!stream_info->composite_flag) - vfe_dev->hw_info->vfe_ops.stats_ops. - clear_wm_irq_mask(vfe_dev, stream_info); - - vfe_dev->hw_info->vfe_ops.stats_ops.clear_wm_reg(vfe_dev, stream_info); - memset(stream_info, 0, sizeof(struct msm_vfe_stats_stream)); - return 0; -} - -static int msm_isp_init_stats_ping_pong_reg( - struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info) -{ - int rc = 0; - - stream_info->bufq_handle = - vfe_dev->buf_mgr->ops->get_bufq_handle( - vfe_dev->buf_mgr, stream_info->session_id, - stream_info->stream_id); - if (stream_info->bufq_handle == 0) { - pr_err("%s: no buf configured for stream: 0x%x\n", - __func__, stream_info->stream_handle); - return -EINVAL; - } - - rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, - stream_info, VFE_PING_FLAG, NULL); - if (rc < 0) { - pr_err("%s: No free buffer for ping\n", __func__); - return rc; - } - rc = msm_isp_stats_cfg_ping_pong_address(vfe_dev, - stream_info, VFE_PONG_FLAG, NULL); - if (rc < 0) { - pr_err("%s: No free buffer for pong\n", __func__); - return rc; - } - return rc; -} - -static void msm_isp_deinit_stats_ping_pong_reg( - struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream *stream_info) -{ - int i; - struct msm_isp_buffer *buf; - - for (i = 0; i < 2; i++) { - buf = stream_info->buf[i]; - if (buf) - vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr, - buf->bufq_handle, buf->buf_idx); - } -} - -void msm_isp_update_stats_framedrop_reg(struct vfe_device *vfe_dev) -{ - int i; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - struct msm_vfe_stats_stream *stream_info = NULL; - - for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) { - stream_info = &stats_data->stream_info[i]; - if (stream_info->state != STATS_ACTIVE) - continue; - - if (stream_info->init_stats_frame_drop) { - stream_info->init_stats_frame_drop--; - if (stream_info->init_stats_frame_drop == 0) { - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg( - vfe_dev, stream_info); - } - } - } -} - -void msm_isp_stats_stream_update(struct vfe_device *vfe_dev) -{ - int i; - uint32_t stats_mask = 0, comp_stats_mask = 0; - uint32_t enable = 0; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - - for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) { - if (stats_data->stream_info[i].state == STATS_START_PENDING || - stats_data->stream_info[i].state == - STATS_STOP_PENDING) { - stats_mask |= i; - enable = stats_data->stream_info[i].state == - STATS_START_PENDING ? 1 : 0; - stats_data->stream_info[i].state = - stats_data->stream_info[i].state == - STATS_START_PENDING ? - STATS_STARTING : STATS_STOPPING; - vfe_dev->hw_info->vfe_ops.stats_ops.enable_module( - vfe_dev, BIT(i), enable); - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask( - vfe_dev, BIT(i), enable); - } else if (stats_data->stream_info[i].state == STATS_STARTING || - stats_data->stream_info[i].state == STATS_STOPPING) { - if (stats_data->stream_info[i].composite_flag) - comp_stats_mask |= i; - stats_data->stream_info[i].state = - stats_data->stream_info[i].state == - STATS_STARTING ? STATS_ACTIVE : STATS_INACTIVE; - } - } - atomic_sub(1, &stats_data->stats_update); - if (!atomic_read(&stats_data->stats_update)) - complete(&vfe_dev->stats_config_complete); -} - -static int msm_isp_stats_wait_for_cfg_done(struct vfe_device *vfe_dev) -{ - int rc; - - init_completion(&vfe_dev->stats_config_complete); - atomic_set(&vfe_dev->stats_data.stats_update, 2); - rc = wait_for_completion_timeout( - &vfe_dev->stats_config_complete, - msecs_to_jiffies(VFE_MAX_CFG_TIMEOUT)); - if (rc == 0) { - pr_err("%s: wait timeout\n", __func__); - rc = -1; - } else { - rc = 0; - } - return rc; -} - -static int msm_isp_stats_update_cgc_override(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd) -{ - int i; - uint32_t stats_mask = 0, idx; - - if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) { - pr_err("%s invalid num_streams %d\n", __func__, - stream_cfg_cmd->num_streams); - return -EINVAL; - } - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]); - - if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, idx); - return -EINVAL; - } - stats_mask |= 1 << idx; - } - - if (vfe_dev->hw_info->vfe_ops.stats_ops.update_cgc_override) { - vfe_dev->hw_info->vfe_ops.stats_ops.update_cgc_override( - vfe_dev, stats_mask, stream_cfg_cmd->enable); - } - return 0; -} - -static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd) -{ - int i, rc = 0; - uint32_t stats_mask = 0, idx; - uint32_t comp_stats_mask[MAX_NUM_STATS_COMP_MASK] = {0}; - uint32_t num_stats_comp_mask = 0; - struct msm_vfe_stats_stream *stream_info; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - - if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) { - pr_err("%s invalid num_streams %d\n", __func__, - stream_cfg_cmd->num_streams); - return -EINVAL; - } - - num_stats_comp_mask = - vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; - rc = vfe_dev->hw_info->vfe_ops.stats_ops.check_streams( - stats_data->stream_info); - if (rc < 0) - return rc; - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]); - - if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, idx); - return -EINVAL; - } - - stream_info = &stats_data->stream_info[idx]; - if (stream_info->stream_handle != - stream_cfg_cmd->stream_handle[i]) { - pr_err("%s: Invalid stream handle: 0x%x received\n", - __func__, stream_cfg_cmd->stream_handle[i]); - continue; - } - - if (stream_info->composite_flag > num_stats_comp_mask) { - pr_err("%s: comp grp %d exceed max %d\n", - __func__, stream_info->composite_flag, - num_stats_comp_mask); - return -EINVAL; - } - rc = msm_isp_init_stats_ping_pong_reg(vfe_dev, stream_info); - if (rc < 0) { - pr_err("%s: No buffer for stream%d type:%d stmID:0x%x\n", - __func__, idx, stream_info->stats_type, - stream_info->stream_id); - return rc; - } - - if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) - stream_info->state = STATS_START_PENDING; - else - stream_info->state = STATS_ACTIVE; - - stats_data->num_active_stream++; - stats_mask |= 1 << idx; - - if (stream_info->composite_flag > 0) - comp_stats_mask[stream_info->composite_flag-1] |= - 1 << idx; - - ISP_DBG("%s: stats_mask %x %x active streams %d\n", - __func__, comp_stats_mask[0], - comp_stats_mask[1], - stats_data->num_active_stream); - - } - - if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) { - rc = msm_isp_stats_wait_for_cfg_done(vfe_dev); - } else { - vfe_dev->hw_info->vfe_ops.stats_ops.enable_module( - vfe_dev, stats_mask, stream_cfg_cmd->enable); - for (i = 0; i < num_stats_comp_mask; i++) { - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask( - vfe_dev, comp_stats_mask[i], 1); - } - } - return rc; -} - -static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev, - struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd) -{ - int i, rc = 0; - uint32_t stats_mask = 0, idx; - uint32_t comp_stats_mask[MAX_NUM_STATS_COMP_MASK] = {0}; - uint32_t num_stats_comp_mask = 0; - struct msm_vfe_stats_stream *stream_info; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - - num_stats_comp_mask = - vfe_dev->hw_info->stats_hw_info->num_stats_comp_mask; - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - - idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]); - - if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, idx); - return -EINVAL; - } - - stream_info = &stats_data->stream_info[idx]; - if (stream_info->stream_handle != - stream_cfg_cmd->stream_handle[i]) { - pr_err("%s: Invalid stream handle: 0x%x received\n", - __func__, stream_cfg_cmd->stream_handle[i]); - continue; - } - - if (stream_info->composite_flag > num_stats_comp_mask) { - pr_err("%s: comp grp %d exceed max %d\n", - __func__, stream_info->composite_flag, - num_stats_comp_mask); - return -EINVAL; - } - - if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) - stream_info->state = STATS_STOP_PENDING; - else - stream_info->state = STATS_INACTIVE; - - stats_data->num_active_stream--; - stats_mask |= 1 << idx; - - if (stream_info->composite_flag > 0) - comp_stats_mask[stream_info->composite_flag-1] |= - 1 << idx; - - ISP_DBG("%s: stats_mask %x %x active streams %d\n", - __func__, comp_stats_mask[0], - comp_stats_mask[1], - stats_data->num_active_stream); - } - - if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) { - rc = msm_isp_stats_wait_for_cfg_done(vfe_dev); - } else { - vfe_dev->hw_info->vfe_ops.stats_ops.enable_module( - vfe_dev, stats_mask, stream_cfg_cmd->enable); - for (i = 0; i < num_stats_comp_mask; i++) { - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_comp_mask( - vfe_dev, comp_stats_mask[i], 0); - } - } - - for (i = 0; i < stream_cfg_cmd->num_streams; i++) { - idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]); - - if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s Invalid stats index %d", __func__, idx); - return -EINVAL; - } - - stream_info = &stats_data->stream_info[idx]; - msm_isp_deinit_stats_ping_pong_reg(vfe_dev, stream_info); - } - return rc; -} - -int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0; - struct msm_vfe_stats_stream_cfg_cmd *stream_cfg_cmd = arg; - - if (vfe_dev->stats_data.num_active_stream == 0) - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_ub(vfe_dev); - - if (stream_cfg_cmd->num_streams > MSM_ISP_STATS_MAX) { - pr_err("%s invalid num_streams %d\n", __func__, - stream_cfg_cmd->num_streams); - return -EINVAL; - } - - if (stream_cfg_cmd->enable) { - msm_isp_stats_update_cgc_override(vfe_dev, stream_cfg_cmd); - - rc = msm_isp_start_stats_stream(vfe_dev, stream_cfg_cmd); - } else { - rc = msm_isp_stop_stats_stream(vfe_dev, stream_cfg_cmd); - - msm_isp_stats_update_cgc_override(vfe_dev, stream_cfg_cmd); - } - - return rc; -} - -int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0, i; - struct msm_vfe_stats_stream *stream_info; - struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data; - struct msm_vfe_axi_stream_update_cmd *update_cmd = arg; - struct msm_vfe_axi_stream_cfg_update_info *update_info = NULL; - - /*validate request*/ - for (i = 0; i < update_cmd->num_streams; i++) { - update_info = &update_cmd->update_info[i]; - /*check array reference bounds*/ - if (STATS_IDX(update_info->stream_handle) - > vfe_dev->hw_info->stats_hw_info->num_stats_type) { - pr_err("%s: stats idx %d out of bound!", __func__, - STATS_IDX(update_info->stream_handle)); - return -EINVAL; - } - } - - for (i = 0; i < update_cmd->num_streams; i++) { - update_info = &update_cmd->update_info[i]; - stream_info = &stats_data->stream_info[ - STATS_IDX(update_info->stream_handle)]; - if (stream_info->stream_handle != - update_info->stream_handle) { - pr_err("%s: stats stream handle %x %x mismatch!\n", - __func__, stream_info->stream_handle, - update_info->stream_handle); - continue; - } - - switch (update_cmd->update_type) { - case UPDATE_STREAM_STATS_FRAMEDROP_PATTERN: { - uint32_t framedrop_period = - msm_isp_get_framedrop_period( - update_info->skip_pattern); - if (update_info->skip_pattern == SKIP_ALL) - stream_info->framedrop_pattern = 0x0; - else - stream_info->framedrop_pattern = 0x1; - stream_info->framedrop_period = framedrop_period - 1; - if (stream_info->init_stats_frame_drop == 0) - vfe_dev->hw_info->vfe_ops.stats_ops.cfg_wm_reg( - vfe_dev, stream_info); - break; - } - - default: - pr_err("%s: Invalid update type\n", __func__); - return -EINVAL; - } - } - return rc; -} diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.h deleted file mode 100644 index 121d209cb59b..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util_32.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __MSM_ISP_STATS_UTIL_H__ -#define __MSM_ISP_STATS_UTIL_H__ - -#include "msm_isp_32.h" -#define STATS_IDX(idx) (idx & 0xFF) - -void msm_isp_process_stats_irq(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct msm_isp_timestamp *ts); -void msm_isp_stats_stream_update(struct vfe_device *vfe_dev); -int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg); -void msm_isp_update_stats_framedrop_reg(struct vfe_device *vfe_dev); -#endif /* __MSM_ISP_STATS_UTIL_H__ */ diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index e7f7f4db9f5f..7d1882c2c271 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -20,8 +20,6 @@ #include "msm_isp_stats_util.h" #include "msm_camera_io_util.h" #include "cam_smmu_api.h" -#define CREATE_TRACE_POINTS -#include "trace/events/msm_cam.h" #define MAX_ISP_V4l2_EVENTS 100 #define MAX_ISP_REG_LIST 100 @@ -29,10 +27,6 @@ static DEFINE_MUTEX(bandwidth_mgr_mutex); static struct msm_isp_bandwidth_mgr isp_bandwidth_mgr; static uint64_t msm_isp_cpp_clk_rate; -static struct dump_ping_pong_state dump_data; -static struct dump_ping_pong_state tasklet_data; -static DEFINE_SPINLOCK(dump_irq_lock); -static DEFINE_SPINLOCK(dump_tasklet_lock); #define VFE40_8974V2_VERSION 0x1001001A @@ -351,34 +345,6 @@ int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, return msm_isp_process_event_subscription(fh, sub, false); } -static int msm_isp_update_fe_frame_id(struct vfe_device *vfe_dev, - void *arg) -{ - struct msm_vfe_update_fe_frame_id *session_frameid = arg; - int rc = 0; - /* - * For Offline VFE, HAL expects same frame id - * for offline output which it requested in do_reprocess. - */ - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id = - session_frameid->frame_id; - return rc; -} - -static int msm_isp_restart_fe(struct vfe_device *vfe_dev, - void *arg) -{ - struct msm_vfe_restart_fe_cmd *rst_fe = arg; - int rc = 0; - /* - * In case of overflow recovery - * restart fetch engine - */ - if (rst_fe->restart_fe) - vfe_dev->fetch_engine_info.is_busy = 1; - return rc; -} - static int msm_isp_start_fetch_engine(struct vfe_device *vfe_dev, void *arg) { @@ -408,9 +374,13 @@ static int msm_isp_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, fe_cfg->frame_id; if (fe_cfg->offline_pass == OFFLINE_SECOND_PASS) { - stream_info = &vfe_dev->axi_data.stream_info[ - HANDLE_TO_IDX(fe_cfg->output_stream_id)]; - if (!stream_info) { + for (i = 0; i < VFE_AXI_SRC_MAX; i++) { + stream_info = &vfe_dev->axi_data.stream_info[i]; + if (stream_info->stream_id == fe_cfg->output_stream_id) + break; + } + + if (i == VFE_AXI_SRC_MAX) { pr_err("%s: Couldn't find streamid 0x%X\n", __func__, fe_cfg->output_stream_id); return -EINVAL; @@ -526,9 +496,6 @@ static int msm_isp_cfg_rdi(struct vfe_device *vfe_dev, return -EINVAL; } - vfe_dev->axi_data. - src_info[input_cfg->input_src].sof_counter_step = 1; - vfe_dev->axi_data.src_info[input_cfg->input_src].pixel_clock = input_cfg->input_pix_clk; vfe_dev->hw_info->vfe_ops.core_ops.cfg_rdi_reg( @@ -598,10 +565,13 @@ static int msm_isp_set_dual_HW_master_slave_mode( } /* No lock needed here since ioctl lock protects 2 session from race */ - /* Reset master SOF which refer slave in increment_frame_id function */ + /* reset master SOF which refer slave in increment_frame_id function + * + */ vfe_dev->common_data->ms_resource.master_sof_info.frame_id = 0; vfe_dev->common_data->ms_resource.master_sof_info.mono_timestamp_ms = 0; - /* Reset slave frame_id so that master will not jump */ + /* we have only 1 slave so reset it frame_id so that master will + * not jump*/ vfe_dev->common_data->ms_resource.slave_sof_info[0].frame_id = 0; if (src_info != NULL && dual_hw_ms_cmd->dual_hw_ms_type == MS_TYPE_MASTER) { @@ -958,19 +928,6 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, rc = msm_isp_start_fetch_engine_multi_pass(vfe_dev, arg); mutex_unlock(&vfe_dev->core_mutex); break; - - case VIDIOC_MSM_ISP_RESTART_FE: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_restart_fe(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - - case VIDIOC_MSM_ISP_UPDATE_FE_FRAME_ID: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_update_fe_frame_id(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_REG_UPDATE_CMD: if (arg) { enum msm_vfe_input_src frame_src = @@ -1787,38 +1744,11 @@ void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev) static int msm_isp_process_iommu_page_fault(struct vfe_device *vfe_dev) { int rc = vfe_dev->buf_mgr->pagefault_debug_disable; - uint32_t irq_status0, irq_status1; - uint32_t overflow_mask; - unsigned long irq_flags; - /* Check if any overflow bit is set */ - vfe_dev->hw_info->vfe_ops.core_ops. - get_overflow_mask(&overflow_mask); - vfe_dev->hw_info->vfe_ops.irq_ops. - read_irq_status(vfe_dev, &irq_status0, &irq_status1); - overflow_mask &= irq_status1; - spin_lock_irqsave( - &vfe_dev->common_data->common_dev_data_lock, irq_flags); - if (overflow_mask || - atomic_read(&vfe_dev->error_info.overflow_state) != - NO_OVERFLOW) { - spin_unlock_irqrestore( - &vfe_dev->common_data->common_dev_data_lock, irq_flags); - pr_err_ratelimited("%s: overflow detected during IOMMU\n", - __func__); - /* Don't treat the Overflow + Page fault scenario as fatal. - * Instead try to do a recovery. Using an existing event as - * as opposed to creating a new event. - */ - msm_isp_halt_send_error(vfe_dev, ISP_EVENT_PING_PONG_MISMATCH); - } else { - spin_unlock_irqrestore( - &vfe_dev->common_data->common_dev_data_lock, irq_flags); - pr_err("%s:%d] VFE%d Handle Page fault! vfe_dev %pK\n", - __func__, __LINE__, vfe_dev->pdev->id, vfe_dev); - vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 0); - msm_isp_halt_send_error(vfe_dev, ISP_EVENT_IOMMU_P_FAULT); - } + pr_err("%s:%d] VFE%d Handle Page fault! vfe_dev %pK\n", __func__, + __LINE__, vfe_dev->pdev->id, vfe_dev); + + msm_isp_halt_send_error(vfe_dev, ISP_EVENT_IOMMU_P_FAULT); if (vfe_dev->buf_mgr->pagefault_debug_disable == 0) { vfe_dev->buf_mgr->pagefault_debug_disable = 1; @@ -1861,8 +1791,6 @@ void msm_isp_process_overflow_irq( uint32_t force_overflow) { uint32_t overflow_mask; - unsigned long flags; - struct msm_isp_event_data error_event; /* if there are no active streams - do not start recovery */ if (!vfe_dev->axi_data.num_active_stream) @@ -1886,86 +1814,71 @@ void msm_isp_process_overflow_irq( if (!force_overflow) overflow_mask &= *irq_status1; - if (!overflow_mask) - return; - - spin_lock_irqsave(&vfe_dev->common_data->common_dev_data_lock, - flags); - if (atomic_cmpxchg(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW, OVERFLOW_DETECTED)) { - spin_unlock_irqrestore( - &vfe_dev->common_data->common_dev_data_lock, - flags); - return; - } - if (vfe_dev->reset_pending == 1) { - pr_err("%s:%d failed: overflow %x during reset\n", - __func__, __LINE__, overflow_mask); - /* Clear overflow bits since reset is pending */ - *irq_status1 &= ~overflow_mask; - spin_unlock_irqrestore(&vfe_dev->common_data-> - common_dev_data_lock, flags); - return; - } - ISP_DBG("%s: VFE%d Bus overflow detected: start recovery!\n", - __func__, vfe_dev->pdev->id); - - trace_msm_cam_isp_overflow(vfe_dev, *irq_status0, *irq_status1); - - /* maks off irq for current vfe */ - vfe_dev->recovery_irq0_mask = vfe_dev->irq0_mask; - vfe_dev->recovery_irq1_mask = vfe_dev->irq1_mask; + if (overflow_mask) { + struct msm_isp_event_data error_event; - vfe_dev->hw_info->vfe_ops.core_ops. - set_halt_restart_mask(vfe_dev); - vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 0); - /* mask off other vfe if dual vfe is used */ - if (vfe_dev->is_split) { - uint32_t other_vfe_id; - struct vfe_device *other_vfe_dev; - - other_vfe_id = (vfe_dev->pdev->id == ISP_VFE0) ? - ISP_VFE1 : ISP_VFE0; - other_vfe_dev = vfe_dev->common_data-> - dual_vfe_res->vfe_dev[other_vfe_id]; - if (other_vfe_dev) { - other_vfe_dev->recovery_irq0_mask = - other_vfe_dev->irq0_mask; - other_vfe_dev->recovery_irq1_mask = - other_vfe_dev->irq1_mask; + if (vfe_dev->reset_pending == 1) { + pr_err("%s:%d failed: overflow %x during reset\n", + __func__, __LINE__, overflow_mask); + /* Clear overflow bits since reset is pending */ + *irq_status1 &= ~overflow_mask; + return; } - atomic_cmpxchg(&(vfe_dev->common_data->dual_vfe_res-> - vfe_dev[other_vfe_id]-> - error_info.overflow_state), + ISP_DBG("%s: VFE%d Bus overflow detected: start recovery!\n", + __func__, vfe_dev->pdev->id); + + /* maks off irq for current vfe */ + atomic_cmpxchg(&vfe_dev->error_info.overflow_state, NO_OVERFLOW, OVERFLOW_DETECTED); + vfe_dev->recovery_irq0_mask = vfe_dev->irq0_mask; + vfe_dev->recovery_irq1_mask = vfe_dev->irq1_mask; vfe_dev->hw_info->vfe_ops.core_ops. - set_halt_restart_mask(vfe_dev->common_data-> - dual_vfe_res->vfe_dev[other_vfe_id]); - if (other_vfe_dev) { - other_vfe_dev->hw_info->vfe_ops.axi_ops. - halt(other_vfe_dev, 0); + set_halt_restart_mask(vfe_dev); + + /* mask off other vfe if dual vfe is used */ + if (vfe_dev->is_split) { + uint32_t other_vfe_id; + struct vfe_device *other_vfe_dev; + + other_vfe_id = (vfe_dev->pdev->id == ISP_VFE0) ? + ISP_VFE1 : ISP_VFE0; + other_vfe_dev = vfe_dev->common_data-> + dual_vfe_res->vfe_dev[other_vfe_id]; + if (other_vfe_dev) { + other_vfe_dev->recovery_irq0_mask = + other_vfe_dev->irq0_mask; + other_vfe_dev->recovery_irq1_mask = + other_vfe_dev->irq1_mask; + } + + atomic_cmpxchg(&(vfe_dev->common_data->dual_vfe_res-> + vfe_dev[other_vfe_id]-> + error_info.overflow_state), + NO_OVERFLOW, OVERFLOW_DETECTED); + + vfe_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(vfe_dev->common_data-> + dual_vfe_res->vfe_dev[other_vfe_id]); } - } - /* reset irq status so skip further process */ - *irq_status0 = 0; - *irq_status1 = 0; + /* reset irq status so skip further process */ + *irq_status0 = 0; + *irq_status1 = 0; - /* send overflow event as needed */ - if (atomic_read(&vfe_dev->error_info.overflow_state) - != HALT_ENFORCED) { - memset(&error_event, 0, sizeof(error_event)); - error_event.frame_id = - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; - error_event.u.error_info.err_type = - ISP_ERROR_BUS_OVERFLOW; - msm_isp_send_event(vfe_dev, - ISP_EVENT_ERROR, &error_event); + /* send overflow event as needed */ + if (atomic_read(&vfe_dev->error_info.overflow_state) + != HALT_ENFORCED) { + memset(&error_event, 0, sizeof(error_event)); + error_event.frame_id = + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; + error_event.u.error_info.err_type = + ISP_ERROR_BUS_OVERFLOW; + msm_isp_send_event(vfe_dev, + ISP_EVENT_ERROR, &error_event); + } } - spin_unlock_irqrestore(&vfe_dev->common_data-> - common_dev_data_lock, flags); } void msm_isp_reset_burst_count_and_frame_drop( @@ -2014,7 +1927,7 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data) uint32_t error_mask0, error_mask1; vfe_dev->hw_info->vfe_ops.irq_ops. - read_irq_status_and_clear(vfe_dev, &irq_status0, &irq_status1); + read_irq_status(vfe_dev, &irq_status0, &irq_status1); if ((irq_status0 == 0) && (irq_status1 == 0)) { ISP_DBG("%s:VFE%d irq_status0 & 1 are both 0\n", @@ -2045,50 +1958,13 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data) ISP_DBG("%s: error_mask0/1 & error_count are set!\n", __func__); return IRQ_HANDLED; } - dump_data.vfe_dev = (struct vfe_device *) data; - if (vfe_dev->is_split && - (vfe_dev->common_data->dual_vfe_res->vfe_dev[ - !vfe_dev->pdev->id]) && - (vfe_dev->common_data->dual_vfe_res->vfe_dev[ - !vfe_dev->pdev->id]->vfe_open_cnt)) { - spin_lock(&dump_irq_lock); - dump_data.arr[dump_data.first].current_vfe_irq. - vfe_id = vfe_dev->pdev->id; - dump_data.arr[dump_data.first].current_vfe_irq. - irq_status0 = irq_status0; - dump_data.arr[dump_data.first].current_vfe_irq. - irq_status1 = irq_status1; - dump_data.arr[dump_data.first].current_vfe_irq. - ping_pong_status = ping_pong_status; - - dump_data.arr[dump_data.first].other_vfe. - vfe_id = (!vfe_dev->pdev->id); - vfe_dev->hw_info->vfe_ops.irq_ops. - read_irq_status( - vfe_dev->common_data->dual_vfe_res->vfe_dev[ - !vfe_dev->pdev->id], - &dump_data.arr[dump_data.first].other_vfe.irq_status0, - &dump_data.arr[dump_data.first].other_vfe.irq_status1); - dump_data.arr[dump_data.first].other_vfe. - ping_pong_status = - vfe_dev->hw_info->vfe_ops.axi_ops. - get_pingpong_status( - vfe_dev->common_data->dual_vfe_res->vfe_dev[ - !vfe_dev->pdev->id]); - msm_isp_get_timestamp(&dump_data.arr[dump_data.first]. - other_vfe.ts, vfe_dev); - dump_data.first = - (dump_data.first + 1) % MAX_ISP_PING_PONG_DUMP_SIZE; - dump_data.fill_count++; - spin_unlock(&dump_irq_lock); - } + msm_isp_enqueue_tasklet_cmd(vfe_dev, irq_status0, irq_status1, ping_pong_status); return IRQ_HANDLED; } - void msm_isp_do_tasklet(unsigned long data) { unsigned long flags; @@ -2124,24 +2000,6 @@ void msm_isp_do_tasklet(unsigned long data) spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); ISP_DBG("%s: vfe_id %d status0: 0x%x status1: 0x%x\n", __func__, vfe_dev->pdev->id, irq_status0, irq_status1); - if (vfe_dev->is_split) { - spin_lock(&dump_tasklet_lock); - tasklet_data.arr[tasklet_data.first]. - current_vfe_irq.vfe_id = vfe_dev->pdev->id; - tasklet_data.arr[tasklet_data.first]. - current_vfe_irq.core = smp_processor_id(); - tasklet_data.arr[tasklet_data.first]. - current_vfe_irq.irq_status0 = irq_status0; - tasklet_data.arr[tasklet_data.first]. - current_vfe_irq.irq_status1 = irq_status1; - tasklet_data.arr[tasklet_data.first]. - current_vfe_irq.ping_pong_status = pingpong_status; - tasklet_data.arr[tasklet_data.first]. - current_vfe_irq.ts = ts; - tasklet_data.first = - (tasklet_data.first + 1) % MAX_ISP_PING_PONG_DUMP_SIZE; - spin_unlock(&dump_tasklet_lock); - } irq_ops->process_reset_irq(vfe_dev, irq_status0, irq_status1); irq_ops->process_halt_irq(vfe_dev, @@ -2200,8 +2058,6 @@ static void msm_vfe_iommu_fault_handler(struct iommu_domain *domain, if (vfe_dev->vfe_open_cnt > 0) { atomic_set(&vfe_dev->error_info.overflow_state, HALT_ENFORCED); - pr_err_ratelimited("%s: fault address is %lx\n", - __func__, iova); msm_isp_process_iommu_page_fault(vfe_dev); } else { pr_err("%s: no handling, vfe open cnt = %d\n", @@ -2435,57 +2291,3 @@ void msm_isp_save_framedrop_values(struct vfe_device *vfe_dev, spin_unlock_irqrestore(&stream_info->lock, flags); } } - -void msm_isp_dump_irq_debug(void) -{ - uint32_t index, count, i; - - if (dump_data.fill_count > MAX_ISP_PING_PONG_DUMP_SIZE) { - index = dump_data.first; - count = MAX_ISP_PING_PONG_DUMP_SIZE; - } else { - index = 0; - count = dump_data.first; - } - for (i = 0; i < count; i++) { - trace_msm_cam_ping_pong_debug_dump(dump_data.arr[index]); - index = (index + 1) % MAX_ISP_PING_PONG_DUMP_SIZE; - } -} - -void msm_isp_dump_taskelet_debug(void) -{ - uint32_t index, count, i; - - if (tasklet_data.fill_count > MAX_ISP_PING_PONG_DUMP_SIZE) { - index = tasklet_data.first; - count = MAX_ISP_PING_PONG_DUMP_SIZE; - } else { - index = 0; - count = tasklet_data.first; - } - for (i = 0; i < count; i++) { - trace_msm_cam_tasklet_debug_dump(tasklet_data.arr[index]); - index = (index + 1) % MAX_ISP_PING_PONG_DUMP_SIZE; - } -} - -void msm_isp_dump_ping_pong_mismatch(void) -{ - int i; - - spin_lock(&dump_tasklet_lock); - for (i = 0; i < MAX_VFE; i++) { - dump_data.vfe_dev->hw_info->vfe_ops.axi_ops. - clear_irq_mask( - dump_data.vfe_dev->common_data->dual_vfe_res->vfe_dev[i]); - synchronize_irq( - (uint32_t)dump_data.vfe_dev->common_data->dual_vfe_res->vfe_dev[ - i]->vfe_irq->start); - } - trace_msm_cam_string(" ***** msm_isp_dump_irq_debug ****"); - msm_isp_dump_irq_debug(); - trace_msm_cam_string(" ***** msm_isp_dump_taskelet_debug ****"); - msm_isp_dump_taskelet_debug(); - spin_unlock(&dump_tasklet_lock); -} diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h index 561b9c28d842..9d68fecafaa0 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h @@ -25,30 +25,7 @@ #endif #define ALT_VECTOR_IDX(x) {x = 3 - x; } -#define MAX_ISP_PING_PONG_DUMP_SIZE 20 -struct ping_pong_state { - uint32_t vfe_id; - uint32_t irq_status0; - uint32_t irq_status1; - uint32_t ping_pong_status; - uint32_t core; - struct msm_isp_timestamp ts; -}; -struct dual_vfe_state { - struct ping_pong_state current_vfe_irq; - struct ping_pong_state other_vfe; -}; -struct dump_ping_pong_state { - struct dual_vfe_state arr[MAX_ISP_PING_PONG_DUMP_SIZE]; - uint32_t first; - uint32_t fill_count; - struct vfe_device *vfe_dev; -}; -void msm_isp_dump_ping_pong_mismatch(void); -void msm_isp_get_status(struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1); -void msm_isp_dump_taskelet_debug(void); uint32_t msm_isp_get_framedrop_period( enum msm_vfe_frame_skip_pattern frame_skip_pattern); void msm_isp_reset_burst_count_and_frame_drop( diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c deleted file mode 100644 index 54a1bdde0fe5..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.c +++ /dev/null @@ -1,1919 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include - -#include "msm.h" -#include "msm_isp_util_32.h" -#include "msm_isp_axi_util_32.h" -#include "msm_isp_stats_util_32.h" -#include "msm_camera_io_util.h" - -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif - -#define MAX_ISP_V4l2_EVENTS 100 -#define MAX_ISP_REG_LIST 100 -static DEFINE_MUTEX(bandwidth_mgr_mutex); -static struct msm_isp_bandwidth_mgr isp_bandwidth_mgr; - -static uint64_t msm_isp_cpp_clk_rate; - -#define VFE40_8974V2_VERSION 0x1001001A -static struct msm_bus_vectors msm_isp_init_vectors[] = { - { - .src = MSM_BUS_MASTER_VFE, - .dst = MSM_BUS_SLAVE_EBI_CH0, - .ab = 0, - .ib = 0, - }, -}; - -static struct msm_bus_vectors msm_isp_ping_vectors[] = { - { - .src = MSM_BUS_MASTER_VFE, - .dst = MSM_BUS_SLAVE_EBI_CH0, - .ab = MSM_ISP_MIN_AB, - .ib = MSM_ISP_MIN_IB, - }, -}; - -static struct msm_bus_vectors msm_isp_pong_vectors[] = { - { - .src = MSM_BUS_MASTER_VFE, - .dst = MSM_BUS_SLAVE_EBI_CH0, - .ab = MSM_ISP_MIN_AB, - .ib = MSM_ISP_MIN_IB, - }, -}; - -static struct msm_bus_paths msm_isp_bus_client_config[] = { - { - ARRAY_SIZE(msm_isp_init_vectors), - msm_isp_init_vectors, - }, - { - ARRAY_SIZE(msm_isp_ping_vectors), - msm_isp_ping_vectors, - }, - { - ARRAY_SIZE(msm_isp_pong_vectors), - msm_isp_pong_vectors, - }, -}; - -static struct msm_bus_scale_pdata msm_isp_bus_client_pdata = { - msm_isp_bus_client_config, - ARRAY_SIZE(msm_isp_bus_client_config), - .name = "msm_camera_isp", -}; - - -void msm_camera_io_dump_2(void __iomem *addr, int size) -{ - char line_str[128], *p_str; - int i; - u32 *p = (u32 *) addr; - u32 data; - - pr_err("%s: %pK %d\n", __func__, addr, size); - line_str[0] = '\0'; - p_str = line_str; - for (i = 0; i < size/4; i++) { - if (i % 4 == 0) { -#ifdef CONFIG_COMPAT - snprintf(p_str, 20, "%016lx: ", (unsigned long) p); - p_str += 18; -#else - snprintf(p_str, 12, "%08lx: ", (unsigned long) p); - p_str += 10; -#endif - } - data = readl_relaxed(p++); - snprintf(p_str, 12, "%08x ", data); - p_str += 9; - if ((i + 1) % 4 == 0) { - pr_err("%s\n", line_str); - line_str[0] = '\0'; - p_str = line_str; - } - } - if (line_str[0] != '\0') - pr_err("%s\n", line_str); -} - -void msm_isp_print_fourcc_error(const char *origin, uint32_t fourcc_format) -{ - int i; - char text[5]; - - text[4] = '\0'; - for (i = 0; i < 4; i++) { - text[i] = (char)(((fourcc_format) >> (i * 8)) & 0xFF); - if ((text[i] < '0') || (text[i] > 'z')) { - pr_err("%s: Invalid output format %d (unprintable)\n", - origin, fourcc_format); - return; - } - } - pr_err("%s: Invalid output format %s\n", - origin, text); -} - -int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client) -{ - int rc = 0; - - mutex_lock(&bandwidth_mgr_mutex); - isp_bandwidth_mgr.client_info[client].active = 1; - if (isp_bandwidth_mgr.use_count++) { - mutex_unlock(&bandwidth_mgr_mutex); - return rc; - } - isp_bandwidth_mgr.bus_client = - msm_bus_scale_register_client(&msm_isp_bus_client_pdata); - if (!isp_bandwidth_mgr.bus_client) { - pr_err("%s: client register failed\n", __func__); - mutex_unlock(&bandwidth_mgr_mutex); - return -EINVAL; - } - - isp_bandwidth_mgr.bus_vector_active_idx = 1; - msm_bus_scale_client_update_request( - isp_bandwidth_mgr.bus_client, - isp_bandwidth_mgr.bus_vector_active_idx); - - mutex_unlock(&bandwidth_mgr_mutex); - return 0; -} - -int msm_isp_update_bandwidth(enum msm_isp_hw_client client, - uint64_t ab, uint64_t ib) -{ - int i; - struct msm_bus_paths *path; - - mutex_lock(&bandwidth_mgr_mutex); - if (!isp_bandwidth_mgr.use_count || - !isp_bandwidth_mgr.bus_client) { - pr_err("%s:error bandwidth manager inactive use_cnt:%d bus_clnt:%d\n", - __func__, isp_bandwidth_mgr.use_count, - isp_bandwidth_mgr.bus_client); - return -EINVAL; - } - - isp_bandwidth_mgr.client_info[client].ab = ab; - isp_bandwidth_mgr.client_info[client].ib = ib; - ALT_VECTOR_IDX(isp_bandwidth_mgr.bus_vector_active_idx); - path = - &(msm_isp_bus_client_pdata.usecase[ - isp_bandwidth_mgr.bus_vector_active_idx]); - path->vectors[0].ab = 0; - path->vectors[0].ib = 0; - for (i = 0; i < MAX_ISP_CLIENT; i++) { - if (isp_bandwidth_mgr.client_info[i].active) { - path->vectors[0].ab += - isp_bandwidth_mgr.client_info[i].ab; - path->vectors[0].ib += - isp_bandwidth_mgr.client_info[i].ib; - } - } - ISP_DBG("%s: Total AB = %llu IB = %llu\n", __func__, - path->vectors[0].ab, path->vectors[0].ib); - msm_bus_scale_client_update_request(isp_bandwidth_mgr.bus_client, - isp_bandwidth_mgr.bus_vector_active_idx); - /* Insert into circular buffer */ - msm_isp_update_req_history(isp_bandwidth_mgr.bus_client, - path->vectors[0].ab, - path->vectors[0].ib, - isp_bandwidth_mgr.client_info, - sched_clock()); - mutex_unlock(&bandwidth_mgr_mutex); - return 0; -} - -void msm_isp_deinit_bandwidth_mgr(enum msm_isp_hw_client client) -{ - if (client >= MAX_ISP_CLIENT) { - pr_err("invalid Client id %d", client); - return; - } - mutex_lock(&bandwidth_mgr_mutex); - memset(&isp_bandwidth_mgr.client_info[client], 0, - sizeof(struct msm_isp_bandwidth_info)); - if (--isp_bandwidth_mgr.use_count) { - mutex_unlock(&bandwidth_mgr_mutex); - return; - } - - if (!isp_bandwidth_mgr.bus_client) { - pr_err("%s:%d error: bus client invalid\n", __func__, __LINE__); - mutex_unlock(&bandwidth_mgr_mutex); - return; - } - - msm_bus_scale_client_update_request( - isp_bandwidth_mgr.bus_client, 0); - msm_bus_scale_unregister_client(isp_bandwidth_mgr.bus_client); - isp_bandwidth_mgr.bus_client = 0; - mutex_unlock(&bandwidth_mgr_mutex); -} - -void msm_isp_util_get_bandwidth_stats(struct vfe_device *vfe_dev, - struct msm_isp_statistics *stats) -{ - stats->isp_vfe0_active = isp_bandwidth_mgr.client_info[ISP_VFE0].active; - stats->isp_vfe0_ab = isp_bandwidth_mgr.client_info[ISP_VFE0].ab; - stats->isp_vfe0_ib = isp_bandwidth_mgr.client_info[ISP_VFE0].ib; - - stats->isp_vfe1_active = isp_bandwidth_mgr.client_info[ISP_VFE1].active; - stats->isp_vfe1_ab = isp_bandwidth_mgr.client_info[ISP_VFE1].ab; - stats->isp_vfe1_ib = isp_bandwidth_mgr.client_info[ISP_VFE1].ib; - - stats->isp_cpp_active = isp_bandwidth_mgr.client_info[ISP_CPP].active; - stats->isp_cpp_ab = isp_bandwidth_mgr.client_info[ISP_CPP].ab; - stats->isp_cpp_ib = isp_bandwidth_mgr.client_info[ISP_CPP].ib; - stats->last_overflow_ab = vfe_dev->msm_isp_last_overflow_ab; - stats->last_overflow_ib = vfe_dev->msm_isp_last_overflow_ib; - stats->vfe_clk_rate = vfe_dev->msm_isp_vfe_clk_rate; - stats->cpp_clk_rate = msm_isp_cpp_clk_rate; -} - -void msm_isp_util_update_last_overflow_ab_ib(struct vfe_device *vfe_dev) -{ - struct msm_bus_paths *path; - path = &(msm_isp_bus_client_pdata.usecase[ - isp_bandwidth_mgr.bus_vector_active_idx]); - vfe_dev->msm_isp_last_overflow_ab = path->vectors[0].ab; - vfe_dev->msm_isp_last_overflow_ib = path->vectors[0].ib; -} - -void msm_isp_util_update_clk_rate(long clock_rate) -{ - msm_isp_cpp_clk_rate = clock_rate; -} - -uint32_t msm_isp_get_framedrop_period( - enum msm_vfe_frame_skip_pattern frame_skip_pattern) -{ - switch (frame_skip_pattern) { - case NO_SKIP: - case EVERY_2FRAME: - case EVERY_3FRAME: - case EVERY_4FRAME: - case EVERY_5FRAME: - case EVERY_6FRAME: - case EVERY_7FRAME: - case EVERY_8FRAME: - return frame_skip_pattern + 1; - case EVERY_16FRAME: - return 16; - case EVERY_32FRAME: - return 32; - case SKIP_ALL: - return 1; - default: - return 1; - } - return 1; -} - -int msm_isp_get_clk_info(struct vfe_device *vfe_dev, - struct platform_device *pdev, struct msm_cam_clk_info *vfe_clk_info) -{ - int i, count, rc; - uint32_t rates[VFE_CLK_INFO_MAX]; - - struct device_node *of_node; - - of_node = pdev->dev.of_node; - - count = of_property_count_strings(of_node, "clock-names"); - - ISP_DBG("count = %d\n", count); - if (count <= 0) { - pr_err("no clocks found in device tree, count=%d", count); - return 0; - } - - if (count > VFE_CLK_INFO_MAX) { - pr_err("invalid count=%d, max is %d\n", count, - VFE_CLK_INFO_MAX); - return -EINVAL; - } - - for (i = 0; i < count; i++) { - rc = of_property_read_string_index(of_node, "clock-names", - i, &(vfe_clk_info[i].clk_name)); - ISP_DBG("clock-names[%d] = %s\n", i, vfe_clk_info[i].clk_name); - if (rc < 0) { - pr_err("%s failed %d\n", __func__, __LINE__); - return rc; - } - } - rc = of_property_read_u32_array(of_node, "qcom,clock-rates", - rates, count); - if (rc < 0) { - pr_err("%s failed %d\n", __func__, __LINE__); - return rc; - } - for (i = 0; i < count; i++) { - vfe_clk_info[i].clk_rate = - (rates[i] == 0) ? (long)-1 : rates[i]; - ISP_DBG("clk_rate[%d] = %ld\n", i, vfe_clk_info[i].clk_rate); - } - vfe_dev->num_clk = count; - return 0; -} - -static inline void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp) -{ - struct timespec ts; - - ktime_get_ts(&ts); - time_stamp->buf_time.tv_sec = ts.tv_sec; - time_stamp->buf_time.tv_usec = ts.tv_nsec/1000; - do_gettimeofday(&(time_stamp->event_time)); -} - -int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) -{ - struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); - int rc = 0; - - rc = v4l2_event_subscribe(fh, sub, MAX_ISP_V4l2_EVENTS, NULL); - if (rc == 0) { - if (sub->type == V4L2_EVENT_ALL) { - int i; - - vfe_dev->axi_data.event_mask = 0; - for (i = 0; i < ISP_EVENT_MAX; i++) - vfe_dev->axi_data.event_mask |= (1 << i); - } else { - int event_idx = sub->type - ISP_EVENT_BASE; - - vfe_dev->axi_data.event_mask |= (1 << event_idx); - } - } - return rc; -} - -int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub) -{ - struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); - int rc = 0; - - rc = v4l2_event_unsubscribe(fh, sub); - if (sub->type == V4L2_EVENT_ALL) { - vfe_dev->axi_data.event_mask = 0; - } else { - int event_idx = sub->type - ISP_EVENT_BASE; - - vfe_dev->axi_data.event_mask &= ~(1 << event_idx); - } - return rc; -} - -static int msm_isp_get_max_clk_rate(struct vfe_device *vfe_dev, long *rate) -{ - int clk_idx = 0; - unsigned long max_value = ~0; - long round_rate = 0; - - if (!vfe_dev || !rate) { - pr_err("%s:%d failed: vfe_dev %pK rate %pK\n", - __func__, __LINE__, vfe_dev, rate); - return -EINVAL; - } - - *rate = 0; - if (!vfe_dev->hw_info) { - pr_err("%s:%d failed: vfe_dev->hw_info %pK\n", __func__, - __LINE__, vfe_dev->hw_info); - return -EINVAL; - } - - clk_idx = vfe_dev->hw_info->vfe_clk_idx; - if (clk_idx >= vfe_dev->num_clk) { - pr_err("%s:%d failed: clk_idx %d max array size %d\n", - __func__, __LINE__, clk_idx, - vfe_dev->num_clk); - return -EINVAL; - } - - round_rate = clk_round_rate(vfe_dev->vfe_clk[clk_idx], max_value); - if (round_rate < 0) { - pr_err("%s: Invalid vfe clock rate\n", __func__); - return -EINVAL; - } - - *rate = round_rate; - return 0; -} - -static int msm_isp_set_clk_rate(struct vfe_device *vfe_dev, long *rate) -{ - int rc = 0; - int clk_idx = vfe_dev->hw_info->vfe_clk_idx; - long round_rate = - clk_round_rate(vfe_dev->vfe_clk[clk_idx], *rate); - if (round_rate < 0) { - pr_err("%s: Invalid vfe clock rate\n", __func__); - return round_rate; - } - - rc = clk_set_rate(vfe_dev->vfe_clk[clk_idx], round_rate); - if (rc < 0) { - pr_err("%s: Vfe set rate error\n", __func__); - return rc; - } - *rate = round_rate; - vfe_dev->msm_isp_vfe_clk_rate = round_rate; - return 0; -} - -void msm_isp_fetch_engine_done_notify(struct vfe_device *vfe_dev, - struct msm_vfe_fetch_engine_info *fetch_engine_info) -{ - struct msm_isp32_event_data fe_rd_done_event; - - if (!fetch_engine_info->is_busy) - return; - memset(&fe_rd_done_event, 0, sizeof(struct msm_isp32_event_data)); - fe_rd_done_event.frame_id = - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; - fe_rd_done_event.u.buf_done.session_id = fetch_engine_info->session_id; - fe_rd_done_event.u.buf_done.stream_id = fetch_engine_info->stream_id; - fe_rd_done_event.u.buf_done.handle = fetch_engine_info->bufq_handle; - fe_rd_done_event.u.buf_done.buf_idx = fetch_engine_info->buf_idx; - ISP_DBG("%s:VFE%d ISP_EVENT_FE_READ_DONE buf_idx %d\n", - __func__, vfe_dev->pdev->id, fetch_engine_info->buf_idx); - fetch_engine_info->is_busy = 0; - msm_isp_send_event(vfe_dev, ISP_EVENT_FE_READ_DONE, &fe_rd_done_event); -} - -int msm_isp_cfg_pix(struct vfe_device *vfe_dev, - struct msm_vfe_input_cfg *input_cfg) -{ - int rc = 0; - - if (vfe_dev->axi_data.src_info[VFE_PIX_0].active) { - pr_err("%s: pixel path is active\n", __func__); - return -EINVAL; - } - - vfe_dev->axi_data.src_info[VFE_PIX_0].pixel_clock = - input_cfg->input_pix_clk; - vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux = - input_cfg->d.pix_cfg.input_mux; - vfe_dev->axi_data.src_info[VFE_PIX_0].input_format = - input_cfg->d.pix_cfg.input_format; - - rc = msm_isp_set_clk_rate(vfe_dev, - &vfe_dev->axi_data.src_info[VFE_PIX_0].pixel_clock); - if (rc < 0) { - pr_err("%s: clock set rate failed\n", __func__); - return rc; - } - - ISP_DBG("%s: input mux is %d CAMIF %d io_format 0x%x\n", __func__, - input_cfg->d.pix_cfg.input_mux, CAMIF, - input_cfg->d.pix_cfg.input_format); - - if (input_cfg->d.pix_cfg.input_mux == CAMIF) { - vfe_dev->axi_data.src_info[VFE_PIX_0].width = - input_cfg->d.pix_cfg.camif_cfg.pixels_per_line; - } else if (input_cfg->d.pix_cfg.input_mux == EXTERNAL_READ) { - vfe_dev->axi_data.src_info[VFE_PIX_0].width = - input_cfg->d.pix_cfg.fetch_engine_cfg.buf_stride; - } - vfe_dev->hw_info->vfe_ops.core_ops.cfg_input_mux( - vfe_dev, &input_cfg->d.pix_cfg); - return rc; -} - -int msm_isp_cfg_rdi(struct vfe_device *vfe_dev, - struct msm_vfe_input_cfg *input_cfg) -{ - int rc = 0; - - if (vfe_dev->axi_data.src_info[input_cfg->input_src].active) { - pr_err("%s: RAW%d path is active\n", __func__, - input_cfg->input_src - VFE_RAW_0); - return -EINVAL; - } - - vfe_dev->axi_data.src_info[input_cfg->input_src].pixel_clock = - input_cfg->input_pix_clk; - vfe_dev->hw_info->vfe_ops.core_ops.cfg_rdi_reg( - vfe_dev, &input_cfg->d.rdi_cfg, input_cfg->input_src); - return rc; -} - -int msm_isp_cfg_input(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0; - struct msm_vfe_input_cfg *input_cfg = arg; - - switch (input_cfg->input_src) { - case VFE_PIX_0: - rc = msm_isp_cfg_pix(vfe_dev, input_cfg); - break; - case VFE_RAW_0: - case VFE_RAW_1: - case VFE_RAW_2: - rc = msm_isp_cfg_rdi(vfe_dev, input_cfg); - break; - default: - pr_err("%s: Invalid input source\n", __func__); - rc = -EINVAL; - } - return rc; -} - -static int msm_isp_proc_cmd_list_unlocked(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0; - uint32_t count = 0; - struct msm_vfe_cfg_cmd_list *proc_cmd = - (struct msm_vfe_cfg_cmd_list *)arg; - struct msm_vfe_cfg_cmd_list cmd, cmd_next; - struct msm_vfe_cfg_cmd2 cfg_cmd; - - if (!vfe_dev || !arg) { - pr_err("%s:%d failed: vfe_dev %pK arg %pK", __func__, __LINE__, - vfe_dev, arg); - return -EINVAL; - } - - rc = msm_isp_proc_cmd(vfe_dev, &proc_cmd->cfg_cmd); - if (rc < 0) - pr_err("%s:%d failed: rc %d", __func__, __LINE__, rc); - - cmd = *proc_cmd; - - while (cmd.next) { - if (cmd.next_size != sizeof(struct msm_vfe_cfg_cmd_list)) { - pr_err("%s:%d failed: next size %u != expected %zu\n", - __func__, __LINE__, cmd.next_size, - sizeof(struct msm_vfe_cfg_cmd_list)); - break; - } - if (++count >= MAX_ISP_REG_LIST) { - pr_err("%s:%d Error exceeding the max register count:%u\n", - __func__, __LINE__, count); - rc = -EFAULT; - break; - } - if (copy_from_user(&cmd_next, (void __user *)cmd.next, - sizeof(struct msm_vfe_cfg_cmd_list))) { - rc = -EFAULT; - continue; - } - - cfg_cmd = cmd_next.cfg_cmd; - - rc = msm_isp_proc_cmd(vfe_dev, &cfg_cmd); - if (rc < 0) - pr_err("%s:%d failed: rc %d", __func__, __LINE__, rc); - - cmd = cmd_next; - } - return rc; -} - -#ifdef CONFIG_COMPAT -struct msm_vfe_cfg_cmd2_32 { - uint16_t num_cfg; - uint16_t cmd_len; - compat_caddr_t cfg_data; - compat_caddr_t cfg_cmd; -}; - -struct msm_vfe_cfg_cmd_list_32 { - struct msm_vfe_cfg_cmd2_32 cfg_cmd; - compat_caddr_t next; - uint32_t next_size; -}; - -#define VIDIOC_MSM_VFE_REG_CFG_COMPAT \ - _IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_vfe_cfg_cmd2_32) -#define VIDIOC_MSM_VFE_REG_LIST_CFG_COMPAT \ - _IOWR('V', BASE_VIDIOC_PRIVATE+14, struct msm_vfe_cfg_cmd_list_32) - -static void msm_isp_compat_to_proc_cmd(struct msm_vfe_cfg_cmd2 *proc_cmd, - struct msm_vfe_cfg_cmd2_32 *proc_cmd_ptr32) -{ - proc_cmd->num_cfg = proc_cmd_ptr32->num_cfg; - proc_cmd->cmd_len = proc_cmd_ptr32->cmd_len; - proc_cmd->cfg_data = compat_ptr(proc_cmd_ptr32->cfg_data); - proc_cmd->cfg_cmd = compat_ptr(proc_cmd_ptr32->cfg_cmd); -} - -static int msm_isp_proc_cmd_list_compat(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0; - uint32_t count = 0; - struct msm_vfe_cfg_cmd_list_32 *proc_cmd = - (struct msm_vfe_cfg_cmd_list_32 *)arg; - struct msm_vfe_cfg_cmd_list_32 cmd, cmd_next; - struct msm_vfe_cfg_cmd2 current_cmd; - - if (!vfe_dev || !arg) { - pr_err("%s:%d failed: vfe_dev %pK arg %pK", __func__, __LINE__, - vfe_dev, arg); - return -EINVAL; - } - msm_isp_compat_to_proc_cmd(¤t_cmd, &proc_cmd->cfg_cmd); - rc = msm_isp_proc_cmd(vfe_dev, ¤t_cmd); - if (rc < 0) - pr_err("%s:%d failed: rc %d", __func__, __LINE__, rc); - - cmd = *proc_cmd; - - while (NULL != compat_ptr(cmd.next)) { - if (cmd.next_size != sizeof(struct msm_vfe_cfg_cmd_list_32)) { - pr_err("%s:%d failed: next size %u != expected %zu\n", - __func__, __LINE__, cmd.next_size, - sizeof(struct msm_vfe_cfg_cmd_list)); - break; - } - if (++count >= MAX_ISP_REG_LIST) { - pr_err("%s:%d Error exceeding the max register count:%u\n", - __func__, __LINE__, count); - rc = -EFAULT; - break; - } - if (copy_from_user(&cmd_next, compat_ptr(cmd.next), - sizeof(struct msm_vfe_cfg_cmd_list_32))) { - rc = -EFAULT; - continue; - } - - msm_isp_compat_to_proc_cmd(¤t_cmd, &cmd_next.cfg_cmd); - rc = msm_isp_proc_cmd(vfe_dev, ¤t_cmd); - if (rc < 0) - pr_err("%s:%d failed: rc %d", __func__, __LINE__, rc); - - cmd = cmd_next; - } - return rc; -} - -static int msm_isp_proc_cmd_list(struct vfe_device *vfe_dev, void *arg) -{ - if (is_compat_task()) - return msm_isp_proc_cmd_list_compat(vfe_dev, arg); - else - return msm_isp_proc_cmd_list_unlocked(vfe_dev, arg); -} -#else /* CONFIG_COMPAT */ -static int msm_isp_proc_cmd_list(struct vfe_device *vfe_dev, void *arg) -{ - return msm_isp_proc_cmd_list_unlocked(vfe_dev, arg); -} -#endif /* CONFIG_COMPAT */ - - -static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, - unsigned int cmd, void *arg) -{ - long rc = 0; - struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); - - if (!vfe_dev || !vfe_dev->vfe_base) { - pr_err("%s:%d failed: invalid params %pK\n", - __func__, __LINE__, vfe_dev); - if (vfe_dev) - pr_err("%s:%d failed %pK\n", __func__, - __LINE__, vfe_dev->vfe_base); - return -EINVAL; - } - - /* use real time mutex for hard real-time ioctls such as - * buffer operations and register updates. - * Use core mutex for other ioctls that could take - * longer time to complete such as start/stop ISP streams - * which blocks until the hardware start/stop streaming - */ - ISP_DBG("%s cmd: %d\n", __func__, _IOC_TYPE(cmd)); - switch (cmd) { - case VIDIOC_MSM_VFE_REG_CFG: { - mutex_lock(&vfe_dev->realtime_mutex); - rc = msm_isp_proc_cmd(vfe_dev, arg); - mutex_unlock(&vfe_dev->realtime_mutex); - break; - } - case VIDIOC_MSM_VFE_REG_LIST_CFG: { - mutex_lock(&vfe_dev->realtime_mutex); - rc = msm_isp_proc_cmd_list(vfe_dev, arg); - mutex_unlock(&vfe_dev->realtime_mutex); - break; - } - case VIDIOC_MSM_ISP_REQUEST_BUF: - case VIDIOC_MSM_ISP_ENQUEUE_BUF: - case VIDIOC_MSM_ISP_RELEASE_BUF: { - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_proc_buf_cmd(vfe_dev->buf_mgr, cmd, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - } - case VIDIOC_MSM_ISP32_REQUEST_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_request_axi_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_RELEASE_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_release_axi_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_CFG_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_cfg_axi_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_AXI_HALT: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_axi_halt(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_AXI_RESET: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_axi_reset(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_AXI_RESTART: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_axi_restart(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_INPUT_CFG: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_cfg_input(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_FETCH_ENG_START: - mutex_lock(&vfe_dev->core_mutex); - rc = vfe_dev->hw_info->vfe_ops.core_ops. - start_fetch_eng(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_REG_UPDATE_CMD: - if (arg) { - enum msm_vfe_input_src frame_src = - *((enum msm_vfe_input_src *)arg); - vfe_dev->hw_info->vfe_ops.core_ops. - reg_update(vfe_dev, (1 << frame_src)); - vfe_dev->axi_data.src_info[frame_src].last_updt_frm_id = - vfe_dev->axi_data.src_info[frame_src].frame_id; - } - break; - case VIDIOC_MSM_ISP_SET_SRC_STATE: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_set_src_state(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_request_stats_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_RELEASE_STATS_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_release_stats_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_CFG_STATS_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_cfg_stats_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_UPDATE_STATS_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_update_stats_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_UPDATE_STREAM: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_update_axi_stream(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case VIDIOC_MSM_ISP_SMMU_ATTACH: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_smmu_attach(vfe_dev->buf_mgr, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case MSM_SD_NOTIFY_FREEZE: - vfe_dev->isp_sof_debug = 0; - break; - case VIDIOC_MSM_ISP_BUF_DONE: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_user_buf_done(vfe_dev, arg); - mutex_unlock(&vfe_dev->core_mutex); - break; - case MSM_SD_SHUTDOWN: - while (vfe_dev->vfe_open_cnt != 0) - msm_isp_close_node(sd, NULL); - break; - - default: - pr_err_ratelimited("%s: Invalid ISP command\n", __func__); - rc = -EINVAL; - } - return rc; -} - - -#ifdef CONFIG_COMPAT -static long msm_isp_ioctl_compat(struct v4l2_subdev *sd, - unsigned int cmd, void *arg) -{ - struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); - long rc = 0; - - if (!vfe_dev || !vfe_dev->vfe_base) { - pr_err("%s:%d failed: invalid params %pK\n", - __func__, __LINE__, vfe_dev); - if (vfe_dev) - pr_err("%s:%d failed %pK\n", __func__, - __LINE__, vfe_dev->vfe_base); - return -EINVAL; - } - - switch (cmd) { - case VIDIOC_MSM_VFE_REG_CFG_COMPAT: { - struct msm_vfe_cfg_cmd2 proc_cmd; - - mutex_lock(&vfe_dev->realtime_mutex); - msm_isp_compat_to_proc_cmd(&proc_cmd, - (struct msm_vfe_cfg_cmd2_32 *) arg); - rc = msm_isp_proc_cmd(vfe_dev, &proc_cmd); - mutex_unlock(&vfe_dev->realtime_mutex); - break; - } - case VIDIOC_MSM_VFE_REG_LIST_CFG_COMPAT: { - mutex_lock(&vfe_dev->realtime_mutex); - rc = msm_isp_proc_cmd_list(vfe_dev, arg); - mutex_unlock(&vfe_dev->realtime_mutex); - break; - } - default: - return msm_isp_ioctl_unlocked(sd, cmd, arg); - } - - return rc; -} - -long msm_isp_ioctl(struct v4l2_subdev *sd, - unsigned int cmd, void *arg) -{ - return msm_isp_ioctl_compat(sd, cmd, arg); -} -#else /* CONFIG_COMPAT */ -long msm_isp_ioctl(struct v4l2_subdev *sd, - unsigned int cmd, void *arg) -{ - return msm_isp_ioctl_unlocked(sd, cmd, arg); -} -#endif /* CONFIG_COMPAT */ - -static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, - struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd, - uint32_t *cfg_data, uint32_t cmd_len) -{ - if (!vfe_dev || !reg_cfg_cmd) { - pr_err("%s:%d failed: vfe_dev %pK reg_cfg_cmd %pK\n", __func__, - __LINE__, vfe_dev, reg_cfg_cmd); - return -EINVAL; - } - if ((reg_cfg_cmd->cmd_type != VFE_CFG_MASK) && - (!cfg_data || !cmd_len)) { - pr_err("%s:%d failed: cmd type %d cfg_data %pK cmd_len %d\n", - __func__, __LINE__, reg_cfg_cmd->cmd_type, cfg_data, - cmd_len); - return -EINVAL; - } - - /* Validate input parameters */ - switch (reg_cfg_cmd->cmd_type) { - case VFE_WRITE: - case VFE_READ: - case VFE_WRITE_MB: { - if ((reg_cfg_cmd->u.rw_info.reg_offset > - (UINT_MAX - reg_cfg_cmd->u.rw_info.len)) || - ((reg_cfg_cmd->u.rw_info.reg_offset + - reg_cfg_cmd->u.rw_info.len) > - resource_size(vfe_dev->vfe_mem)) || - (reg_cfg_cmd->u.rw_info.reg_offset & 0x3)) { - pr_err("%s:%d reg_offset %d len %d res %d\n", - __func__, __LINE__, - reg_cfg_cmd->u.rw_info.reg_offset, - reg_cfg_cmd->u.rw_info.len, - (uint32_t)resource_size(vfe_dev->vfe_mem)); - return -EINVAL; - } - - if ((reg_cfg_cmd->u.rw_info.cmd_data_offset > - (UINT_MAX - reg_cfg_cmd->u.rw_info.len)) || - ((reg_cfg_cmd->u.rw_info.cmd_data_offset + - reg_cfg_cmd->u.rw_info.len) > cmd_len)) { - pr_err("%s:%d cmd_data_offset %d len %d cmd_len %d\n", - __func__, __LINE__, - reg_cfg_cmd->u.rw_info.cmd_data_offset, - reg_cfg_cmd->u.rw_info.len, cmd_len); - return -EINVAL; - } - break; - } - - case VFE_WRITE_DMI_16BIT: - case VFE_WRITE_DMI_32BIT: - case VFE_WRITE_DMI_64BIT: - case VFE_READ_DMI_16BIT: - case VFE_READ_DMI_32BIT: - case VFE_READ_DMI_64BIT: { - if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT || - reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { - if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <= - reg_cfg_cmd->u.dmi_info.lo_tbl_offset) || - (reg_cfg_cmd->u.dmi_info.hi_tbl_offset - - reg_cfg_cmd->u.dmi_info.lo_tbl_offset != - (sizeof(uint32_t)))) { - pr_err("%s:%d hi %d lo %d\n", - __func__, __LINE__, - reg_cfg_cmd->u.dmi_info.hi_tbl_offset, - reg_cfg_cmd->u.dmi_info.hi_tbl_offset); - return -EINVAL; - } - if (reg_cfg_cmd->u.dmi_info.len <= sizeof(uint32_t)) { - pr_err("%s:%d len %d\n", - __func__, __LINE__, - reg_cfg_cmd->u.dmi_info.len); - return -EINVAL; - } - if (((UINT_MAX - - reg_cfg_cmd->u.dmi_info.hi_tbl_offset) < - (reg_cfg_cmd->u.dmi_info.len - - sizeof(uint32_t))) || - ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset + - reg_cfg_cmd->u.dmi_info.len - - sizeof(uint32_t)) > cmd_len)) { - pr_err("%s:%d hi_tbl_offset %d len %d cmd %d\n", - __func__, __LINE__, - reg_cfg_cmd->u.dmi_info.hi_tbl_offset, - reg_cfg_cmd->u.dmi_info.len, cmd_len); - return -EINVAL; - } - } - if ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset > - (UINT_MAX - reg_cfg_cmd->u.dmi_info.len)) || - ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset + - reg_cfg_cmd->u.dmi_info.len) > cmd_len)) { - pr_err("%s:%d lo_tbl_offset %d len %d cmd_len %d\n", - __func__, __LINE__, - reg_cfg_cmd->u.dmi_info.lo_tbl_offset, - reg_cfg_cmd->u.dmi_info.len, cmd_len); - return -EINVAL; - } - break; - } - - default: - break; - } - - switch (reg_cfg_cmd->cmd_type) { - case VFE_WRITE: { - msm_camera_io_memcpy(vfe_dev->vfe_base + - reg_cfg_cmd->u.rw_info.reg_offset, - cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4, - reg_cfg_cmd->u.rw_info.len); - break; - } - case VFE_WRITE_MB: { - msm_camera_io_memcpy_mb(vfe_dev->vfe_base + - reg_cfg_cmd->u.rw_info.reg_offset, - cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4, - reg_cfg_cmd->u.rw_info.len); - break; - } - case VFE_CFG_MASK: { - uint32_t temp; - - if ((UINT_MAX - sizeof(temp) < - reg_cfg_cmd->u.mask_info.reg_offset) || - (resource_size(vfe_dev->vfe_mem) < - reg_cfg_cmd->u.mask_info.reg_offset + - sizeof(temp)) || - (reg_cfg_cmd->u.mask_info.reg_offset & 0x3)) { - pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__); - return -EINVAL; - } - temp = msm_camera_io_r(vfe_dev->vfe_base + - reg_cfg_cmd->u.mask_info.reg_offset); - - temp &= ~reg_cfg_cmd->u.mask_info.mask; - temp |= reg_cfg_cmd->u.mask_info.val; - msm_camera_io_w(temp, vfe_dev->vfe_base + - reg_cfg_cmd->u.mask_info.reg_offset); - break; - } - case VFE_WRITE_DMI_16BIT: - case VFE_WRITE_DMI_32BIT: - case VFE_WRITE_DMI_64BIT: { - int i; - uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL; - uint32_t hi_val, lo_val, lo_val1; - - if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { - hi_tbl_ptr = cfg_data + - reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4; - } - lo_tbl_ptr = cfg_data + - reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4; - if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) - reg_cfg_cmd->u.dmi_info.len = - reg_cfg_cmd->u.dmi_info.len / 2; - for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) { - lo_val = *lo_tbl_ptr++; - if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) { - lo_val1 = lo_val & 0x0000FFFF; - lo_val = (lo_val & 0xFFFF0000)>>16; - msm_camera_io_w(lo_val1, vfe_dev->vfe_base + - vfe_dev->hw_info->dmi_reg_offset + 0x4); - } else if (reg_cfg_cmd->cmd_type == - VFE_WRITE_DMI_64BIT) { - lo_tbl_ptr++; - hi_val = *hi_tbl_ptr; - hi_tbl_ptr = hi_tbl_ptr + 2; - msm_camera_io_w(hi_val, vfe_dev->vfe_base + - vfe_dev->hw_info->dmi_reg_offset); - } - msm_camera_io_w(lo_val, vfe_dev->vfe_base + - vfe_dev->hw_info->dmi_reg_offset + 0x4); - } - break; - } - case VFE_READ_DMI_16BIT: - case VFE_READ_DMI_32BIT: - case VFE_READ_DMI_64BIT: { - int i; - uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL; - uint32_t hi_val, lo_val, lo_val1; - - if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { - hi_tbl_ptr = cfg_data + - reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4; - } - - lo_tbl_ptr = cfg_data + - reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4; - - if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) - reg_cfg_cmd->u.dmi_info.len = - reg_cfg_cmd->u.dmi_info.len / 2; - - for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) { - lo_val = msm_camera_io_r(vfe_dev->vfe_base + - vfe_dev->hw_info->dmi_reg_offset + 0x4); - - if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_16BIT) { - lo_val1 = msm_camera_io_r(vfe_dev->vfe_base + - vfe_dev->hw_info->dmi_reg_offset + 0x4); - lo_val |= lo_val1 << 16; - } - *lo_tbl_ptr++ = lo_val; - if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { - hi_val = msm_camera_io_r(vfe_dev->vfe_base + - vfe_dev->hw_info->dmi_reg_offset); - *hi_tbl_ptr = hi_val; - hi_tbl_ptr += 2; - lo_tbl_ptr++; - } - } - break; - } - case VFE_HW_UPDATE_LOCK: { - uint32_t update_id = - vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id; - if (update_id) { - ISP_DBG("%s hw_update_lock fail cur_id %u,last_id %u\n", - __func__, - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id, - update_id); - return -EINVAL; - } - break; - } - case VFE_HW_UPDATE_UNLOCK: { - if (vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id - != *cfg_data) { - ISP_DBG("hw_updt over frm bound,strt_id %u end_id %d\n", - *cfg_data, - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); - } - vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id = - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; - break; - } - case VFE_READ: { - int i; - uint32_t *data_ptr = cfg_data + - reg_cfg_cmd->u.rw_info.cmd_data_offset/4; - for (i = 0; i < reg_cfg_cmd->u.rw_info.len/4; i++) { - if ((data_ptr < cfg_data) || - (UINT_MAX / sizeof(*data_ptr) < - (data_ptr - cfg_data)) || - (sizeof(*data_ptr) * (data_ptr - cfg_data) >= - cmd_len)) - return -EINVAL; - *data_ptr++ = msm_camera_io_r(vfe_dev->vfe_base + - reg_cfg_cmd->u.rw_info.reg_offset); - reg_cfg_cmd->u.rw_info.reg_offset += 4; - } - break; - } - case GET_MAX_CLK_RATE: { - int rc = 0; - unsigned long rate; - - if (cmd_len != sizeof(__u32)) { - pr_err("%s:%d failed: invalid cmd len %u exp %zu\n", - __func__, __LINE__, cmd_len, - sizeof(__u32)); - return -EINVAL; - } - rc = msm_isp_get_max_clk_rate(vfe_dev, &rate); - if (rc < 0) { - pr_err("%s:%d failed: rc %d\n", __func__, __LINE__, rc); - return -EINVAL; - } - - *(__u32 *)cfg_data = (__u32)rate; - - break; - } - case GET_ISP_ID: { - uint32_t *isp_id = NULL; - - if (cmd_len < sizeof(uint32_t)) { - pr_err("%s:%d failed: invalid cmd len %u exp %zu\n", - __func__, __LINE__, cmd_len, - sizeof(uint32_t)); - return -EINVAL; - } - - isp_id = (uint32_t *)cfg_data; - *isp_id = vfe_dev->pdev->id; - break; - } - case SET_WM_UB_SIZE: - break; - case SET_UB_POLICY: { - - if (cmd_len < sizeof(vfe_dev->vfe_ub_policy)) { - pr_err("%s:%d failed: invalid cmd len %u exp %zu\n", - __func__, __LINE__, cmd_len, - sizeof(vfe_dev->vfe_ub_policy)); - return -EINVAL; - } - vfe_dev->vfe_ub_policy = *cfg_data; - break; - } - default: - break; - } - return 0; -} - -int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg) -{ - int rc = 0, i; - struct msm_vfe_cfg_cmd2 *proc_cmd = arg; - struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd; - uint32_t *cfg_data = NULL; - - if (!proc_cmd->num_cfg) { - pr_err("%s: Passed num_cfg as 0\n", __func__); - return -EINVAL; - } - - reg_cfg_cmd = kzalloc(sizeof(struct msm_vfe_reg_cfg_cmd)* - proc_cmd->num_cfg, GFP_KERNEL); - if (!reg_cfg_cmd) { - rc = -ENOMEM; - goto reg_cfg_failed; - } - - if (copy_from_user(reg_cfg_cmd, - (void __user *)(proc_cmd->cfg_cmd), - sizeof(struct msm_vfe_reg_cfg_cmd) * proc_cmd->num_cfg)) { - rc = -EFAULT; - goto copy_cmd_failed; - } - - if (proc_cmd->cmd_len > 0 && - proc_cmd->cmd_len < UINT16_MAX) { - cfg_data = kzalloc(proc_cmd->cmd_len, GFP_KERNEL); - if (!cfg_data) { - pr_err("%s: cfg_data alloc failed\n", __func__); - rc = -ENOMEM; - goto cfg_data_failed; - } - - if (copy_from_user(cfg_data, - (void __user *)(proc_cmd->cfg_data), - proc_cmd->cmd_len)) { - rc = -EFAULT; - goto copy_cmd_failed; - } - } - - for (i = 0; i < proc_cmd->num_cfg; i++) - rc = msm_isp_send_hw_cmd(vfe_dev, ®_cfg_cmd[i], - cfg_data, proc_cmd->cmd_len); - - if (copy_to_user(proc_cmd->cfg_data, - cfg_data, proc_cmd->cmd_len)) { - rc = -EFAULT; - goto copy_cmd_failed; - } - -copy_cmd_failed: - kfree(cfg_data); -cfg_data_failed: - kfree(reg_cfg_cmd); -reg_cfg_failed: - return rc; -} - -int msm_isp_send_event(struct vfe_device *vfe_dev, - uint32_t event_type, - struct msm_isp32_event_data *event_data) -{ - struct v4l2_event isp_event; - - memset(&isp_event, 0, sizeof(struct v4l2_event)); - isp_event.id = 0; - isp_event.type = event_type; - - memcpy(&isp_event.u.data[0], event_data, - sizeof(struct msm_isp32_event_data)); - v4l2_event_queue(vfe_dev->subdev.sd.devnode, &isp_event); - return 0; -} - -#define CAL_WORD(width, M, N) ((width * M + N - 1) / N) - -int msm_isp_cal_word_per_line(uint32_t output_format, - uint32_t pixel_per_line) -{ - int val = -1; - - switch (output_format) { - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - case V4L2_PIX_FMT_QBGGR8: - case V4L2_PIX_FMT_QGBRG8: - case V4L2_PIX_FMT_QGRBG8: - case V4L2_PIX_FMT_QRGGB8: - case V4L2_PIX_FMT_JPEG: - case V4L2_PIX_FMT_META: - val = CAL_WORD(pixel_per_line, 1, 8); - break; - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - val = CAL_WORD(pixel_per_line, 5, 32); - break; - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - val = CAL_WORD(pixel_per_line, 3, 16); - break; - case V4L2_PIX_FMT_SBGGR14: - case V4L2_PIX_FMT_SGBRG14: - case V4L2_PIX_FMT_SGRBG14: - case V4L2_PIX_FMT_SRGGB14: - val = CAL_WORD(pixel_per_line, 7, 32); - break; - case V4L2_PIX_FMT_QBGGR10: - case V4L2_PIX_FMT_QGBRG10: - case V4L2_PIX_FMT_QGRBG10: - case V4L2_PIX_FMT_QRGGB10: - val = CAL_WORD(pixel_per_line, 1, 6); - break; - case V4L2_PIX_FMT_QBGGR12: - case V4L2_PIX_FMT_QGBRG12: - case V4L2_PIX_FMT_QGRBG12: - case V4L2_PIX_FMT_QRGGB12: - val = CAL_WORD(pixel_per_line, 1, 5); - break; - case V4L2_PIX_FMT_QBGGR14: - case V4L2_PIX_FMT_QGBRG14: - case V4L2_PIX_FMT_QGRBG14: - case V4L2_PIX_FMT_QRGGB14: - val = CAL_WORD(pixel_per_line, 1, 4); - break; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV14: - case V4L2_PIX_FMT_NV41: - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - val = CAL_WORD(pixel_per_line, 1, 8); - break; - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - val = CAL_WORD(pixel_per_line, 2, 8); - break; - case V4L2_PIX_FMT_P16BGGR10: - case V4L2_PIX_FMT_P16GBRG10: - case V4L2_PIX_FMT_P16GRBG10: - case V4L2_PIX_FMT_P16RGGB10: - val = CAL_WORD(pixel_per_line, 1, 4); - break; - /*TD: Add more image format*/ - default: - msm_isp_print_fourcc_error(__func__, output_format); - break; - } - return val; -} - -enum msm_isp_pack_fmt msm_isp_get_pack_format(uint32_t output_format) -{ - switch (output_format) { - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - case V4L2_PIX_FMT_SBGGR14: - case V4L2_PIX_FMT_SGBRG14: - case V4L2_PIX_FMT_SGRBG14: - case V4L2_PIX_FMT_SRGGB14: - return MIPI; - case V4L2_PIX_FMT_QBGGR8: - case V4L2_PIX_FMT_QGBRG8: - case V4L2_PIX_FMT_QGRBG8: - case V4L2_PIX_FMT_QRGGB8: - case V4L2_PIX_FMT_QBGGR10: - case V4L2_PIX_FMT_QGBRG10: - case V4L2_PIX_FMT_QGRBG10: - case V4L2_PIX_FMT_QRGGB10: - case V4L2_PIX_FMT_QBGGR12: - case V4L2_PIX_FMT_QGBRG12: - case V4L2_PIX_FMT_QGRBG12: - case V4L2_PIX_FMT_QRGGB12: - case V4L2_PIX_FMT_QBGGR14: - case V4L2_PIX_FMT_QGBRG14: - case V4L2_PIX_FMT_QGRBG14: - case V4L2_PIX_FMT_QRGGB14: - return QCOM; - case V4L2_PIX_FMT_P16BGGR10: - case V4L2_PIX_FMT_P16GBRG10: - case V4L2_PIX_FMT_P16GRBG10: - case V4L2_PIX_FMT_P16RGGB10: - return PLAIN16; - default: - msm_isp_print_fourcc_error(__func__, output_format); - break; - } - return -EINVAL; -} - -int msm_isp_get_bit_per_pixel(uint32_t output_format) -{ - switch (output_format) { - case V4L2_PIX_FMT_Y4: - return 4; - case V4L2_PIX_FMT_Y6: - return 6; - case V4L2_PIX_FMT_SBGGR8: - case V4L2_PIX_FMT_SGBRG8: - case V4L2_PIX_FMT_SGRBG8: - case V4L2_PIX_FMT_SRGGB8: - case V4L2_PIX_FMT_QBGGR8: - case V4L2_PIX_FMT_QGBRG8: - case V4L2_PIX_FMT_QGRBG8: - case V4L2_PIX_FMT_QRGGB8: - case V4L2_PIX_FMT_JPEG: - case V4L2_PIX_FMT_META: - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV14: - case V4L2_PIX_FMT_NV41: - case V4L2_PIX_FMT_YVU410: - case V4L2_PIX_FMT_YVU420: - case V4L2_PIX_FMT_YUYV: - case V4L2_PIX_FMT_YYUV: - case V4L2_PIX_FMT_YVYU: - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_VYUY: - case V4L2_PIX_FMT_YUV422P: - case V4L2_PIX_FMT_YUV411P: - case V4L2_PIX_FMT_Y41P: - case V4L2_PIX_FMT_YUV444: - case V4L2_PIX_FMT_YUV555: - case V4L2_PIX_FMT_YUV565: - case V4L2_PIX_FMT_YUV32: - case V4L2_PIX_FMT_YUV410: - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_GREY: - case V4L2_PIX_FMT_PAL8: - case V4L2_PIX_FMT_UV8: - case MSM_V4L2_PIX_FMT_META: - return 8; - case V4L2_PIX_FMT_SBGGR10: - case V4L2_PIX_FMT_SGBRG10: - case V4L2_PIX_FMT_SGRBG10: - case V4L2_PIX_FMT_SRGGB10: - case V4L2_PIX_FMT_QBGGR10: - case V4L2_PIX_FMT_QGBRG10: - case V4L2_PIX_FMT_QGRBG10: - case V4L2_PIX_FMT_QRGGB10: - case V4L2_PIX_FMT_Y10: - case V4L2_PIX_FMT_Y10BPACK: - case V4L2_PIX_FMT_P16BGGR10: - case V4L2_PIX_FMT_P16GBRG10: - case V4L2_PIX_FMT_P16GRBG10: - case V4L2_PIX_FMT_P16RGGB10: - return 10; - case V4L2_PIX_FMT_SBGGR12: - case V4L2_PIX_FMT_SGBRG12: - case V4L2_PIX_FMT_SGRBG12: - case V4L2_PIX_FMT_SRGGB12: - case V4L2_PIX_FMT_QBGGR12: - case V4L2_PIX_FMT_QGBRG12: - case V4L2_PIX_FMT_QGRBG12: - case V4L2_PIX_FMT_QRGGB12: - case V4L2_PIX_FMT_Y12: - return 12; - case V4L2_PIX_FMT_SBGGR14: - case V4L2_PIX_FMT_SGBRG14: - case V4L2_PIX_FMT_SGRBG14: - case V4L2_PIX_FMT_SRGGB14: - case V4L2_PIX_FMT_QBGGR14: - case V4L2_PIX_FMT_QGBRG14: - case V4L2_PIX_FMT_QGRBG14: - case V4L2_PIX_FMT_QRGGB14: - return 14; - case V4L2_PIX_FMT_NV16: - case V4L2_PIX_FMT_NV61: - case V4L2_PIX_FMT_Y16: - return 16; - /*TD: Add more image format*/ - default: - msm_isp_print_fourcc_error(__func__, output_format); - pr_err("%s: Invalid output format %x\n", - __func__, output_format); - return -EINVAL; - } -} - -void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev) -{ - struct msm_vfe_error_info *error_info = &vfe_dev->error_info; - - error_info->info_dump_frame_count++; -} - -void msm_isp_process_error_info(struct vfe_device *vfe_dev) -{ - int i; - uint8_t num_stats_type = - vfe_dev->hw_info->stats_hw_info->num_stats_type; - struct msm_vfe_error_info *error_info = &vfe_dev->error_info; - static DEFINE_RATELIMIT_STATE(rs, - DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); - static DEFINE_RATELIMIT_STATE(rs_stats, - DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); - - if (error_info->error_count == 1 || - !(error_info->info_dump_frame_count % 100)) { - vfe_dev->hw_info->vfe_ops.core_ops. - process_error_status(vfe_dev); - error_info->error_mask0 = 0; - error_info->error_mask1 = 0; - error_info->camif_status = 0; - error_info->violation_status = 0; - for (i = 0; i < MAX_NUM_STREAM; i++) { - if (error_info->stream_framedrop_count[i] != 0 && - __ratelimit(&rs)) { - pr_err("%s: Stream[%d]: dropped %d frames\n", - __func__, i, - error_info->stream_framedrop_count[i]); - error_info->stream_framedrop_count[i] = 0; - } - } - for (i = 0; i < num_stats_type; i++) { - if (error_info->stats_framedrop_count[i] != 0 && - __ratelimit(&rs_stats)) { - pr_err("%s: Stats stream[%d]: dropped %d frames\n", - __func__, i, - error_info->stats_framedrop_count[i]); - error_info->stats_framedrop_count[i] = 0; - } - } - } -} - -static inline void msm_isp_update_error_info(struct vfe_device *vfe_dev, - uint32_t error_mask0, uint32_t error_mask1) -{ - vfe_dev->error_info.error_mask0 |= error_mask0; - vfe_dev->error_info.error_mask1 |= error_mask1; - vfe_dev->error_info.error_count++; -} - -static void msm_isp_process_overflow_irq( - struct vfe_device *vfe_dev, - uint32_t *irq_status0, uint32_t *irq_status1) -{ - uint32_t overflow_mask; - - /* if there are no active streams - do not start recovery */ - if (!vfe_dev->axi_data.num_active_stream) - return; - - /*Mask out all other irqs if recovery is started*/ - if (atomic_read(&vfe_dev->error_info.overflow_state) != NO_OVERFLOW) { - uint32_t halt_restart_mask0, halt_restart_mask1; - - vfe_dev->hw_info->vfe_ops.core_ops. - get_halt_restart_mask(&halt_restart_mask0, - &halt_restart_mask1); - *irq_status0 &= halt_restart_mask0; - *irq_status1 &= halt_restart_mask1; - - return; - } - - /*Check if any overflow bit is set*/ - vfe_dev->hw_info->vfe_ops.core_ops. - get_overflow_mask(&overflow_mask); - overflow_mask &= *irq_status1; - - if (overflow_mask) { - struct msm_isp32_event_data error_event; - - if (vfe_dev->reset_pending == 1) { - pr_err("%s:%d failed: overflow %x during reset\n", - __func__, __LINE__, overflow_mask); - /* Clear overflow bits since reset is pending */ - *irq_status1 &= ~overflow_mask; - return; - } - - ISP_DBG("%s: Bus overflow detected: 0x%x, start recovery!\n", - __func__, overflow_mask); - atomic_set(&vfe_dev->error_info.overflow_state, - OVERFLOW_DETECTED); - /*Store current IRQ mask*/ - vfe_dev->hw_info->vfe_ops.core_ops.get_irq_mask(vfe_dev, - &vfe_dev->error_info.overflow_recover_irq_mask0, - &vfe_dev->error_info.overflow_recover_irq_mask1); - - /*Halt the hardware & Clear all other IRQ mask*/ - vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 0); - - /*Stop CAMIF Immediately*/ - vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY); - - /*Update overflow state*/ - *irq_status0 = 0; - *irq_status1 = 0; - - memset(&error_event, 0, sizeof(error_event)); - error_event.frame_id = - vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; - error_event.u.error_info.error_mask = 1 << ISP_WM_BUS_OVERFLOW; - msm_isp_send_event(vfe_dev, - ISP_EVENT_WM_BUS_OVERFLOW, &error_event); - } -} - -void msm_isp_reset_burst_count_and_frame_drop( - struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info) -{ - uint32_t framedrop_period = 0; - - if (stream_info->state != ACTIVE || - stream_info->stream_type != BURST_STREAM) { - return; - } - if (stream_info->num_burst_capture != 0) { - framedrop_period = msm_isp_get_framedrop_period( - stream_info->frame_skip_pattern); - stream_info->burst_frame_count = - stream_info->init_frame_drop + - (stream_info->num_burst_capture - 1) * - framedrop_period + 1; - msm_isp_reset_framedrop(vfe_dev, stream_info); - } -} - -irqreturn_t msm_isp_process_irq(int irq_num, void *data) -{ - unsigned long flags; - struct msm_vfe_tasklet_queue_cmd *queue_cmd; - struct vfe_device *vfe_dev = (struct vfe_device *) data; - uint32_t irq_status0, irq_status1; - uint32_t error_mask0, error_mask1; - - vfe_dev->hw_info->vfe_ops.irq_ops. - read_irq_status(vfe_dev, &irq_status0, &irq_status1); - - if ((irq_status0 == 0) && (irq_status1 == 0)) { - pr_err_ratelimited("%s:VFE%d irq_status0 & 1 are both 0\n", - __func__, vfe_dev->pdev->id); - return IRQ_HANDLED; - } - - msm_isp_process_overflow_irq(vfe_dev, - &irq_status0, &irq_status1); - - vfe_dev->hw_info->vfe_ops.core_ops. - get_error_mask(&error_mask0, &error_mask1); - error_mask0 &= irq_status0; - error_mask1 &= irq_status1; - irq_status0 &= ~error_mask0; - irq_status1 &= ~error_mask1; - if (!vfe_dev->ignore_error && - ((error_mask0 != 0) || (error_mask1 != 0))) - msm_isp_update_error_info(vfe_dev, error_mask0, error_mask1); - - if ((irq_status0 == 0) && (irq_status1 == 0) && - (!(((error_mask0 != 0) || (error_mask1 != 0)) && - vfe_dev->error_info.error_count == 1))) { - ISP_DBG("%s: error_mask0/1 & error_count are set!\n", __func__); - return IRQ_HANDLED; - } - - spin_lock_irqsave(&vfe_dev->tasklet_lock, flags); - queue_cmd = &vfe_dev->tasklet_queue_cmd[vfe_dev->taskletq_idx]; - if (queue_cmd->cmd_used) { - pr_err_ratelimited("%s: Tasklet queue overflow: %d\n", - __func__, vfe_dev->pdev->id); - list_del(&queue_cmd->list); - } else { - atomic_add(1, &vfe_dev->irq_cnt); - } - queue_cmd->vfeInterruptStatus0 = irq_status0; - queue_cmd->vfeInterruptStatus1 = irq_status1; - msm_isp_get_timestamp(&queue_cmd->ts); - queue_cmd->cmd_used = 1; - vfe_dev->taskletq_idx = - (vfe_dev->taskletq_idx + 1) % MSM_VFE_TASKLETQ_SIZE; - list_add_tail(&queue_cmd->list, &vfe_dev->tasklet_q); - spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); - tasklet_schedule(&vfe_dev->vfe_tasklet); - return IRQ_HANDLED; -} - -void msm_isp_do_tasklet(unsigned long data) -{ - unsigned long flags; - struct vfe_device *vfe_dev = (struct vfe_device *) data; - struct msm_vfe_irq_ops *irq_ops = &vfe_dev->hw_info->vfe_ops.irq_ops; - struct msm_vfe_tasklet_queue_cmd *queue_cmd; - struct msm_isp_timestamp ts; - uint32_t irq_status0, irq_status1; - - while (atomic_read(&vfe_dev->irq_cnt)) { - spin_lock_irqsave(&vfe_dev->tasklet_lock, flags); - queue_cmd = list_first_entry(&vfe_dev->tasklet_q, - struct msm_vfe_tasklet_queue_cmd, list); - - if (!queue_cmd) { - atomic_set(&vfe_dev->irq_cnt, 0); - spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); - return; - } - atomic_sub(1, &vfe_dev->irq_cnt); - list_del(&queue_cmd->list); - queue_cmd->cmd_used = 0; - irq_status0 = queue_cmd->vfeInterruptStatus0; - irq_status1 = queue_cmd->vfeInterruptStatus1; - ts = queue_cmd->ts; - spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); - ISP_DBG("%s: status0: 0x%x status1: 0x%x\n", - __func__, irq_status0, irq_status1); - irq_ops->process_reset_irq(vfe_dev, - irq_status0, irq_status1); - irq_ops->process_halt_irq(vfe_dev, - irq_status0, irq_status1); - if (atomic_read(&vfe_dev->error_info.overflow_state) - != NO_OVERFLOW) { - pr_err("%s: Recovery in processing, Ignore IRQs!!!\n", - __func__); - continue; - } - msm_isp_process_error_info(vfe_dev); - irq_ops->process_camif_irq(vfe_dev, - irq_status0, irq_status1, &ts); - irq_ops->process_axi_irq(vfe_dev, - irq_status0, irq_status1, &ts); - irq_ops->process_stats_irq(vfe_dev, - irq_status0, irq_status1, &ts); - irq_ops->process_reg_update(vfe_dev, - irq_status0, irq_status1, &ts); - irq_ops->process_epoch_irq(vfe_dev, - irq_status0, irq_status1, &ts); - } -} - -int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg) -{ - struct msm_vfe_axi_src_state *src_state = arg; - - if (src_state->input_src >= VFE_SRC_MAX) - return -EINVAL; - vfe_dev->axi_data.src_info[src_state->input_src].active = - src_state->src_active; - vfe_dev->axi_data.src_info[src_state->input_src].frame_id = - src_state->src_frame_id; - return 0; -} - -static int msm_vfe_iommu_fault_handler(struct iommu_domain *domain, - struct device *dev, unsigned long iova, int flags, void *token) -{ - struct vfe_device *vfe_dev = NULL; - - if (token) { - vfe_dev = (struct vfe_device *)token; - if (!vfe_dev->buf_mgr || !vfe_dev->buf_mgr->ops) { - pr_err("%s:%d] buf_mgr %pK\n", __func__, - __LINE__, vfe_dev->buf_mgr); - goto end; - } - if (!vfe_dev->buf_mgr->pagefault_debug) { - pr_err("%s:%d] vfe_dev %pK id %d\n", __func__, - __LINE__, vfe_dev, vfe_dev->pdev->id); - vfe_dev->buf_mgr->ops->buf_mgr_debug(vfe_dev->buf_mgr); - } - } else { - ISP_DBG("%s:%d] no token received: %pK\n", - __func__, __LINE__, token); - goto end; - } -end: - return -ENOSYS; -} - -int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); - long rc = 0; - - ISP_DBG("%s\n", __func__); - - mutex_lock(&vfe_dev->realtime_mutex); - mutex_lock(&vfe_dev->core_mutex); - - if (vfe_dev->vfe_open_cnt++ && vfe_dev->vfe_base) { - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return 0; - } - - if (vfe_dev->vfe_base) { - pr_err("%s:%d invalid params cnt %d base %pK\n", __func__, - __LINE__, vfe_dev->vfe_open_cnt, vfe_dev->vfe_base); - vfe_dev->vfe_base = NULL; - } - - vfe_dev->reset_pending = 0; - vfe_dev->isp_sof_debug = 0; - - if (vfe_dev->hw_info->vfe_ops.core_ops.init_hw(vfe_dev) < 0) { - pr_err("%s: init hardware failed\n", __func__); - vfe_dev->vfe_open_cnt--; - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return -EBUSY; - } - - memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); - atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); - - vfe_dev->hw_info->vfe_ops.core_ops.clear_status_reg(vfe_dev); - - rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 1, 1); - if (rc <= 0) { - pr_err("%s: reset timeout\n", __func__); - vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev); - vfe_dev->vfe_open_cnt--; - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return -EINVAL; - } - vfe_dev->vfe_hw_version = msm_camera_io_r(vfe_dev->vfe_base); - ISP_DBG("%s: HW Version: 0x%x\n", __func__, vfe_dev->vfe_hw_version); - - vfe_dev->hw_info->vfe_ops.core_ops.init_hw_reg(vfe_dev); - - vfe_dev->buf_mgr->ops->buf_mgr_init(vfe_dev->buf_mgr, - "msm_isp", BUF_MGR_NUM_BUF_Q); - - memset(&vfe_dev->axi_data, 0, sizeof(struct msm_vfe_axi_shared_data)); - memset(&vfe_dev->stats_data, 0, - sizeof(struct msm_vfe_stats_shared_data)); - memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); - memset(&vfe_dev->fetch_engine_info, 0, - sizeof(vfe_dev->fetch_engine_info)); - vfe_dev->axi_data.hw_info = vfe_dev->hw_info->axi_hw_info; - vfe_dev->taskletq_idx = 0; - vfe_dev->vt_enable = 0; - vfe_dev->bus_util_factor = 0; - rc = of_property_read_u32(vfe_dev->pdev->dev.of_node, - "bus-util-factor", &vfe_dev->bus_util_factor); - if (rc < 0) - ISP_DBG("%s: Use default bus utilization factor\n", __func__); - iommu_set_fault_handler(vfe_dev->buf_mgr->iommu_domain, - msm_vfe_iommu_fault_handler, vfe_dev); - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return 0; -} - -#ifdef CONFIG_MSM_AVTIMER -void msm_isp_end_avtimer(void) -{ - avcs_core_disable_power_collapse(0); -} -#else -void msm_isp_end_avtimer(void) -{ - pr_err("AV Timer is not supported\n"); -} -#endif - -int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - long rc = 0; - struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); - - ISP_DBG("%s E\n", __func__); - mutex_lock(&vfe_dev->realtime_mutex); - mutex_lock(&vfe_dev->core_mutex); - - if (!vfe_dev->vfe_open_cnt) { - pr_err("%s invalid state open cnt %d\n", __func__, - vfe_dev->vfe_open_cnt); - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return -EINVAL; - } - - if (--vfe_dev->vfe_open_cnt) { - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return 0; - } - - rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 1); - if (rc < 0) - pr_err("%s: halt timeout rc=%ld\n", __func__, rc); - - vfe_dev->buf_mgr->ops->buf_mgr_deinit(vfe_dev->buf_mgr); - vfe_dev->hw_info->vfe_ops.core_ops.release_hw(vfe_dev); - if (vfe_dev->vt_enable) { - msm_isp_end_avtimer(); - vfe_dev->vt_enable = 0; - } - mutex_unlock(&vfe_dev->core_mutex); - mutex_unlock(&vfe_dev->realtime_mutex); - return 0; -} diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.h deleted file mode 100644 index 781198517bd6..000000000000 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util_32.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __MSM_ISP_UTIL_H__ -#define __MSM_ISP_UTIL_H__ - -#include "msm_isp_32.h" -#include - -/* #define CONFIG_MSM_ISP_DBG 1 */ - -#ifdef CONFIG_MSM_ISP_DBG -#define ISP_DBG(fmt, args...) printk(fmt, ##args) -#else -#define ISP_DBG(fmt, args...) pr_debug(fmt, ##args) -#endif - -#define ALT_VECTOR_IDX(x) {x = 3 - x; } - -struct msm_isp_bandwidth_mgr { - uint32_t bus_client; - uint32_t bus_vector_active_idx; - uint32_t use_count; - struct msm_isp_bandwidth_info client_info[MAX_ISP_CLIENT]; -}; - -uint32_t msm_isp_get_framedrop_period( - enum msm_vfe_frame_skip_pattern frame_skip_pattern); -void msm_isp_reset_burst_count_and_frame_drop( - struct vfe_device *vfe_dev, struct msm_vfe_axi_stream *stream_info); - -int msm_isp_init_bandwidth_mgr(enum msm_isp_hw_client client); -int msm_isp_update_bandwidth(enum msm_isp_hw_client client, - uint64_t ab, uint64_t ib); -void msm_isp_util_get_bandwidth_stats(struct vfe_device *vfe_dev, - struct msm_isp_statistics *stats); -void msm_isp_util_update_last_overflow_ab_ib(struct vfe_device *vfe_dev); -void msm_isp_util_update_clk_rate(long clock_rate); -void msm_isp_update_req_history(uint32_t client, uint64_t ab, - uint64_t ib, - struct msm_isp_bandwidth_info *client_info, - unsigned long long ts); -void msm_isp_deinit_bandwidth_mgr(enum msm_isp_hw_client client); - -int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub); - -int msm_isp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - struct v4l2_event_subscription *sub); - -int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg); -int msm_isp_send_event(struct vfe_device *vfe_dev, - uint32_t type, struct msm_isp32_event_data *event_data); -int msm_isp_cal_word_per_line(uint32_t output_format, - uint32_t pixel_per_line); -int msm_isp_get_bit_per_pixel(uint32_t output_format); -enum msm_isp_pack_fmt msm_isp_get_pack_format(uint32_t output_format); -irqreturn_t msm_isp_process_irq(int irq_num, void *data); -int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg); -void msm_isp_do_tasklet(unsigned long data); -void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev); -void msm_isp_process_error_info(struct vfe_device *vfe_dev); -int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); -int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); -long msm_isp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); -int msm_isp_get_clk_info(struct vfe_device *vfe_dev, - struct platform_device *pdev, struct msm_cam_clk_info *vfe_clk_info); -void msm_isp_fetch_engine_done_notify(struct vfe_device *vfe_dev, - struct msm_vfe_fetch_engine_info *fetch_engine_info); -void msm_camera_io_dump_2(void __iomem *addr, int size); -void msm_isp_print_fourcc_error(const char *origin, uint32_t fourcc_format); - -#endif /* __MSM_ISP_UTIL_H__ */ diff --git a/drivers/media/platform/msm/camera_v2/ispif/Makefile b/drivers/media/platform/msm/camera_v2/ispif/Makefile index 7a98fd0334a0..236ec7340c56 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/Makefile +++ b/drivers/media/platform/msm/camera_v2/ispif/Makefile @@ -1,8 +1,4 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2 +ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io -ccflags-y += -Idrivers/media/platform/msm/camera_v2/common/ -ifeq ($(CONFIG_MSM_ISP_V1),y) -obj-$(CONFIG_MSM_CSID) += msm_ispif_32.o -else obj-$(CONFIG_MSM_CSID) += msm_ispif.o -endif \ No newline at end of file diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c old mode 100644 new mode 100755 index 61cf0d811edb..5ea58c980690 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -47,37 +47,19 @@ #define ISPIF_TIMEOUT_SLEEP_US 1000 #define ISPIF_TIMEOUT_ALL_US 1000000 -#define ISPIF_SOF_DEBUG_COUNT 0 - -/* 3D Threshold value according guidelines for line width 1280 */ -#define STEREO_DEFAULT_3D_THRESHOLD 0x36 - -/* - * Overflows before restarting interface during stereo usecase - * to give some tolerance for cases when the two sensors sync fails - * this value is chosen by experiment - */ -#define MAX_PIX_OVERFLOW_ERROR_COUNT 10 -static int pix_overflow_error_count[VFE_MAX] = { 0 }; +#define ISPIF_SOF_DEBUG_COUNT 0 #undef CDBG #ifdef CONFIG_MSMB_CAMERA_DEBUG #define CDBG(fmt, args...) pr_debug(fmt, ##args) #else -#define CDBG(fmt, args...) +#define CDBG(fmt, args...) do { } while (0) #endif -/* Backward interface compatibility for 3D THRESHOLD calculation */ -#define ISPIF_USE_DEFAULT_THRESHOLD (0) -#define ISPIF_CALCULATE_THRESHOLD (1) - static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable); static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); static long msm_ispif_subdev_ioctl_unlocked(struct v4l2_subdev *sd, unsigned int cmd, void *arg); -static long msm_ispif_dispatch_cmd(enum ispif_cfg_type_t cmd, - struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params); int msm_ispif_get_clk_info(struct ispif_device *ispif_dev, struct platform_device *pdev); @@ -272,7 +254,16 @@ static long msm_ispif_cmd_ext(struct v4l2_subdev *sd, } mutex_lock(&ispif->mutex); - rc = msm_ispif_dispatch_cmd(pcdata.cfg_type, ispif, params); + switch (pcdata.cfg_type) { + case ISPIF_CFG2: + rc = msm_ispif_config2(ispif, params); + msm_ispif_io_dump_reg(ispif); + break; + default: + pr_err("%s: invalid cfg_type\n", __func__); + rc = -EINVAL; + break; + } mutex_unlock(&ispif->mutex); kfree(params); return rc; @@ -459,7 +450,7 @@ static int msm_ispif_reset_hw(struct ispif_device *ispif) /* This is set when device is 8974 */ ispif->clk_idx = 1; } - memset(ispif->stereo_configured, 0, sizeof(ispif->stereo_configured)); + atomic_set(&ispif->reset_trig[VFE0], 1); /* initiate reset of ISPIF */ msm_camera_io_w(ISPIF_RST_CMD_MASK, @@ -867,33 +858,15 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg( return cids_mask; } - -static uint16_t msm_ispif_get_right_cids_mask_from_cfg( - struct msm_ispif_right_param_entry *entry, int num_cids) -{ - int i; - uint16_t cids_mask = 0; - - BUG_ON(!entry); - - for (i = 0; i < num_cids && i < MAX_CID_CH_v2; i++) { - if (entry->cids[i] < CID_MAX) - cids_mask |= (1 << entry->cids[i]); - } - - return cids_mask; -} - static int msm_ispif_config(struct ispif_device *ispif, void *data) { int rc = 0, i = 0; - uint16_t cid_mask = 0; - uint16_t cid_right_mask = 0; + uint16_t cid_mask; enum msm_ispif_intftype intftype; enum msm_ispif_vfe_intf vfe_intf; - struct msm_ispif_param_data_ext *params = - (struct msm_ispif_param_data_ext *)data; + struct msm_ispif_param_data *params = + (struct msm_ispif_param_data *)data; BUG_ON(!ispif); BUG_ON(!params); @@ -943,15 +916,9 @@ static int msm_ispif_config(struct ispif_device *ispif, return -EINVAL; } - if (ispif->csid_version >= CSID_VERSION_V30) { + if (ispif->csid_version >= CSID_VERSION_V30) msm_ispif_select_clk_mux(ispif, intftype, params->entries[i].csid, vfe_intf); - if (intftype == PIX0 && params->stereo_enable && - params->right_entries[i].csid < CSID_MAX) - msm_ispif_select_clk_mux(ispif, PIX1, - params->right_entries[i].csid, - vfe_intf); - } rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf); if (rc) { @@ -962,26 +929,10 @@ static int msm_ispif_config(struct ispif_device *ispif, msm_ispif_sel_csid_core(ispif, intftype, params->entries[i].csid, vfe_intf); - if (intftype == PIX0 && params->stereo_enable && - params->right_entries[i].csid < CSID_MAX) - /* configure right stereo csid */ - msm_ispif_sel_csid_core(ispif, PIX1, - params->right_entries[i].csid, vfe_intf); - cid_mask = msm_ispif_get_cids_mask_from_cfg( ¶ms->entries[i]); msm_ispif_enable_intf_cids(ispif, intftype, cid_mask, vfe_intf, 1); - if (params->stereo_enable) - cid_right_mask = msm_ispif_get_right_cids_mask_from_cfg( - ¶ms->right_entries[i], - params->entries[i].num_cids); - else - cid_right_mask = 0; - if (cid_right_mask && params->stereo_enable) - /* configure right stereo cids */ - msm_ispif_enable_intf_cids(ispif, PIX1, - cid_right_mask, vfe_intf, 1); if (params->entries[i].crop_enable) msm_ispif_enable_crop(ispif, intftype, vfe_intf, params->entries[i].crop_start_pixel, @@ -1014,44 +965,8 @@ static int msm_ispif_config(struct ispif_device *ispif, return rc; } -static void msm_ispif_config_stereo(struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params, int use_line_width) { - - int i; - enum msm_ispif_vfe_intf vfe_intf; - uint32_t stereo_3d_threshold = STEREO_DEFAULT_3D_THRESHOLD; - - if (params->num > MAX_PARAM_ENTRIES) - return; - - for (i = 0; i < params->num; i++) { - vfe_intf = params->entries[i].vfe_intf; - if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { - pr_err("%s: invalid interface type %d\n", __func__, - vfe_intf); - return; - } - if (params->entries[i].intftype == PIX0 && - params->stereo_enable && - params->right_entries[i].csid < CSID_MAX && - !ispif->stereo_configured[vfe_intf]) { - msm_camera_io_w_mb(0x3, - ispif->base + ISPIF_VFE_m_OUTPUT_SEL(vfe_intf)); - if (use_line_width && - (params->line_width[vfe_intf] > 0)) - stereo_3d_threshold = - (params->line_width[vfe_intf] + - 2 * 6 - 1) / (2 * 6); - msm_camera_io_w_mb(stereo_3d_threshold, - ispif->base + - ISPIF_VFE_m_3D_THRESHOLD(vfe_intf)); - ispif->stereo_configured[vfe_intf] = 1; - } - } -} - static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits, - struct msm_ispif_param_data_ext *params) + struct msm_ispif_param_data *params) { uint8_t vc; int i, k; @@ -1096,19 +1011,6 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits, ispif->applied_intf_cmd[vfe_intf].intf_cmd |= (cmd_bits << (vc * 2 + intf_type * 8)); } - if (intf_type == PIX0 && params->stereo_enable && - params->right_entries[i].cids[k] < CID_MAX) { - cid = params->right_entries[i].cids[k]; - vc = cid / 4; - - /* fill right stereo command */ - /* zero 2 bits */ - ispif->applied_intf_cmd[vfe_intf].intf_cmd &= - ~(0x3 << (vc * 2 + PIX1 * 8)); - /* set cmd bits */ - ispif->applied_intf_cmd[vfe_intf].intf_cmd |= - (cmd_bits << (vc * 2 + PIX1 * 8)); - } } /* cmd for PIX0, PIX1, RDI0, RDI1 */ if (ispif->applied_intf_cmd[vfe_intf].intf_cmd != 0xFFFFFFFF) @@ -1125,7 +1027,7 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits, } static int msm_ispif_stop_immediately(struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params) + struct msm_ispif_param_data *params) { int i, rc = 0; uint16_t cid_mask = 0; @@ -1153,24 +1055,13 @@ static int msm_ispif_stop_immediately(struct ispif_device *ispif, ¶ms->entries[i]); msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype, cid_mask, params->entries[i].vfe_intf, 0); - if (params->stereo_enable) { - ispif->stereo_configured[ - params->entries[i].vfe_intf] = 0; - cid_mask = msm_ispif_get_right_cids_mask_from_cfg( - ¶ms->right_entries[i], - params->entries[i].num_cids); - if (cid_mask) - msm_ispif_enable_intf_cids(ispif, - params->entries[i].intftype, cid_mask, - params->entries[i].vfe_intf, 0); - } } return rc; } static int msm_ispif_start_frame_boundary(struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params) + struct msm_ispif_param_data *params) { int rc = 0; @@ -1186,15 +1077,13 @@ static int msm_ispif_start_frame_boundary(struct ispif_device *ispif, rc = -EINVAL; return rc; } - - msm_ispif_config_stereo(ispif, params, ISPIF_USE_DEFAULT_THRESHOLD); msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params); return rc; } static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params) + struct msm_ispif_param_data *params) { int rc = 0, i; long timeout = 0; @@ -1336,11 +1225,10 @@ static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, } static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params) + struct msm_ispif_param_data *params) { int i, rc = 0; uint16_t cid_mask = 0; - uint16_t cid_right_mask = 0; uint32_t intf_addr; enum msm_ispif_vfe_intf vfe_intf; uint32_t stop_flag = 0; @@ -1378,13 +1266,6 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, for (i = 0; i < params->num; i++) { cid_mask = msm_ispif_get_cids_mask_from_cfg(¶ms->entries[i]); - if (params->stereo_enable) - cid_right_mask = - msm_ispif_get_right_cids_mask_from_cfg( - ¶ms->right_entries[i], - params->entries[i].num_cids); - else - cid_right_mask = 0; vfe_intf = params->entries[i].vfe_intf; switch (params->entries[i].intftype) { @@ -1416,26 +1297,10 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, ISPIF_TIMEOUT_ALL_US); if (rc < 0) pr_err("ISPIF stop frame boundary timeout\n"); - if (cid_right_mask) { - ispif->stereo_configured[ - params->entries[i].vfe_intf] = 0; - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1); - rc = readl_poll_timeout(ispif->base + intf_addr, - stop_flag, - (stop_flag & 0xF) == 0xF, - ISPIF_TIMEOUT_SLEEP_US, - ISPIF_TIMEOUT_ALL_US); - if (rc < 0) - pr_err("ISPIF stop frame boundary timeout\n"); - } /* disable CIDs in CID_MASK register */ msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype, cid_mask, vfe_intf, 0); - if (cid_right_mask) - msm_ispif_enable_intf_cids(ispif, - params->entries[i].intftype, cid_right_mask, - params->entries[i].vfe_intf, 0); } end: @@ -1456,14 +1321,6 @@ static void ispif_process_irq(struct ispif_device *ispif, ispif->sof_count[vfe_id].sof_cnt[PIX0]++; ispif->ispif_sof_debug++; } - if (out[vfe_id].ispifIrqStatus1 & - ISPIF_IRQ_STATUS_PIX_SOF_MASK) { - if (ispif->ispif_sof_debug < ISPIF_SOF_DEBUG_COUNT*2) - pr_err("%s: PIX1 frame id: %u\n", __func__, - ispif->sof_count[vfe_id].sof_cnt[PIX1]); - ispif->sof_count[vfe_id].sof_cnt[PIX1]++; - ispif->ispif_sof_debug++; - } if (out[vfe_id].ispifIrqStatus0 & ISPIF_IRQ_STATUS_RDI0_SOF_MASK) { if (ispif->ispif_rdi0_debug < ISPIF_SOF_DEBUG_COUNT) @@ -1490,54 +1347,12 @@ static void ispif_process_irq(struct ispif_device *ispif, } } -static int msm_ispif_reconfig_3d_output(struct ispif_device *ispif, - enum msm_ispif_vfe_intf vfe_id) -{ - uint32_t reg_data; - - BUG_ON(!ispif); - - if (!((vfe_id == VFE0) || (vfe_id == VFE1))) { - pr_err("%s;%d Cannot reconfigure 3D mode for VFE%d", __func__, - __LINE__ , vfe_id); - return -EINVAL; - } - pr_info("%s;%d Reconfiguring 3D mode for VFE%d", __func__, __LINE__, - vfe_id); - reg_data = 0xFFFCFFFC; - msm_camera_io_w_mb(reg_data, ispif->base + - ISPIF_VFE_m_INTF_CMD_0(vfe_id)); - msm_camera_io_w_mb(reg_data, ispif->base + - ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); - - if (vfe_id == VFE0) { - reg_data = 0; - reg_data |= (PIX_0_VFE_RST_STB | PIX_1_VFE_RST_STB | - STROBED_RST_EN | PIX_0_CSID_RST_STB | - PIX_1_CSID_RST_STB | PIX_OUTPUT_0_MISR_RST_STB); - msm_camera_io_w_mb(reg_data, ispif->base + ISPIF_RST_CMD_ADDR); - } else { - reg_data = 0; - reg_data |= (PIX_0_VFE_RST_STB | PIX_1_VFE_RST_STB | - STROBED_RST_EN | PIX_0_CSID_RST_STB | - PIX_1_CSID_RST_STB | PIX_OUTPUT_0_MISR_RST_STB); - msm_camera_io_w_mb(reg_data, ispif->base + - ISPIF_RST_CMD_1_ADDR); - } - - reg_data = 0xFFFDFFFD; - msm_camera_io_w_mb(reg_data, ispif->base + - ISPIF_VFE_m_INTF_CMD_0(vfe_id)); - return 0; -} - static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, void *data) { struct ispif_device *ispif = (struct ispif_device *)data; bool fatal_err = false; int i = 0; - uint32_t reg_data; BUG_ON(!ispif); BUG_ON(!out); @@ -1588,12 +1403,6 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, fatal_err = true; } - if (out[VFE0].ispifIrqStatus1 & PIX_INTF_1_OVERFLOW_IRQ) { - pr_err_ratelimited("%s: VFE0 pix1 overflow.\n", - __func__); - fatal_err = true; - } - if (out[VFE0].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) { pr_err_ratelimited("%s: VFE0 rdi0 overflow.\n", __func__); @@ -1626,12 +1435,6 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, fatal_err = true; } - if (out[VFE1].ispifIrqStatus1 & PIX_INTF_1_OVERFLOW_IRQ) { - pr_err_ratelimited("%s: VFE1 pix1 overflow.\n", - __func__); - fatal_err = true; - } - if (out[VFE1].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) { pr_err_ratelimited("%s: VFE1 rdi0 overflow.\n", __func__); @@ -1653,43 +1456,6 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, ispif_process_irq(ispif, out, VFE1); } - if ((out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) || - (out[VFE0].ispifIrqStatus1 & PIX_INTF_0_OVERFLOW_IRQ) || - (out[VFE0].ispifIrqStatus2 & (L_R_SOF_MISMATCH_ERR_IRQ | - L_R_EOF_MISMATCH_ERR_IRQ | L_R_SOL_MISMATCH_ERR_IRQ))) { - reg_data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_OUTPUT_SEL(VFE0)); - if ((reg_data & 0x03) == VFE_PIX_INTF_SEL_3D) { - pix_overflow_error_count[VFE0]++; - if (pix_overflow_error_count[VFE0] >= - MAX_PIX_OVERFLOW_ERROR_COUNT) { - msm_ispif_reconfig_3d_output(ispif, VFE0); - pix_overflow_error_count[VFE0] = 0; - } - fatal_err = false; - } - } - - if (ispif->vfe_info.num_vfe > 1) { - if ((out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) || - (out[VFE1].ispifIrqStatus1 & PIX_INTF_0_OVERFLOW_IRQ) || - (out[VFE1].ispifIrqStatus2 & (L_R_SOF_MISMATCH_ERR_IRQ | - L_R_EOF_MISMATCH_ERR_IRQ | L_R_SOL_MISMATCH_ERR_IRQ))) { - reg_data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_OUTPUT_SEL(VFE1)); - if ((reg_data & 0x03) == VFE_PIX_INTF_SEL_3D) { - pix_overflow_error_count[VFE1]++; - if (pix_overflow_error_count[VFE1] >= - MAX_PIX_OVERFLOW_ERROR_COUNT) { - msm_ispif_reconfig_3d_output(ispif, - VFE1); - pix_overflow_error_count[VFE1] = 0; - } - } - fatal_err = false; - } - } - if (fatal_err == true) { pr_err_ratelimited("%s: fatal error, stop ispif immediately\n", __func__); @@ -1745,11 +1511,6 @@ static int msm_ispif_init(struct ispif_device *ispif, return rc; } - rc = msm_camera_enable_irq(ispif->irq, 1); - if (rc < 0) { - pr_err("%s: Error enabling IRQs\n", __func__); - return rc; - } /* can we set to zero? */ ispif->applied_intf_cmd[VFE0].intf_cmd = 0xFFFFFFFF; ispif->applied_intf_cmd[VFE0].intf_cmd1 = 0xFFFFFFFF; @@ -1806,100 +1567,61 @@ static void msm_ispif_release(struct ispif_device *ispif) pr_err("%s: failed to remove vote for AHB\n", __func__); } -static long msm_ispif_dispatch_cmd(enum ispif_cfg_type_t cmd, - struct ispif_device *ispif, - struct msm_ispif_param_data_ext *params) +static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg) { long rc = 0; + struct ispif_cfg_data *pcdata = (struct ispif_cfg_data *)arg; + struct ispif_device *ispif = + (struct ispif_device *)v4l2_get_subdevdata(sd); - switch (cmd) { + BUG_ON(!sd); + BUG_ON(!pcdata); + + mutex_lock(&ispif->mutex); + switch (pcdata->cfg_type) { + case ISPIF_ENABLE_REG_DUMP: + ispif->enb_dump_reg = pcdata->reg_dump; /* save dump config */ + break; + case ISPIF_INIT: + rc = msm_ispif_init(ispif, pcdata->csid_version); + msm_ispif_io_dump_reg(ispif); + break; case ISPIF_CFG: - rc = msm_ispif_config(ispif, params); + rc = msm_ispif_config(ispif, &pcdata->params); msm_ispif_io_dump_reg(ispif); break; case ISPIF_START_FRAME_BOUNDARY: - rc = msm_ispif_start_frame_boundary(ispif, params); + rc = msm_ispif_start_frame_boundary(ispif, &pcdata->params); msm_ispif_io_dump_reg(ispif); break; case ISPIF_RESTART_FRAME_BOUNDARY: - rc = msm_ispif_restart_frame_boundary(ispif, params); + rc = msm_ispif_restart_frame_boundary(ispif, &pcdata->params); msm_ispif_io_dump_reg(ispif); break; + case ISPIF_STOP_FRAME_BOUNDARY: - rc = msm_ispif_stop_frame_boundary(ispif, params); + rc = msm_ispif_stop_frame_boundary(ispif, &pcdata->params); msm_ispif_io_dump_reg(ispif); break; case ISPIF_STOP_IMMEDIATELY: - rc = msm_ispif_stop_immediately(ispif, params); + rc = msm_ispif_stop_immediately(ispif, &pcdata->params); msm_ispif_io_dump_reg(ispif); break; case ISPIF_RELEASE: msm_ispif_reset(ispif); msm_ispif_reset_hw(ispif); break; - case ISPIF_CFG2: - rc = msm_ispif_config2(ispif, params); - msm_ispif_io_dump_reg(ispif); - break; - case ISPIF_CFG_STEREO: - msm_ispif_config_stereo(ispif, params, - ISPIF_CALCULATE_THRESHOLD); - break; - default: - pr_err("%s: invalid cfg_type\n", __func__); - rc = -EINVAL; - break; - } - return rc; -} - -static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg) -{ - long rc = 0; - struct ispif_cfg_data *pcdata = (struct ispif_cfg_data *)arg; - struct ispif_device *ispif = - (struct ispif_device *)v4l2_get_subdevdata(sd); - int i; - struct msm_ispif_param_data_ext params; - - BUG_ON(!sd); - BUG_ON(!pcdata); - mutex_lock(&ispif->mutex); - switch (pcdata->cfg_type) { - case ISPIF_ENABLE_REG_DUMP: - /* save dump config */ - ispif->enb_dump_reg = pcdata->reg_dump; - break; - case ISPIF_INIT: - rc = msm_ispif_init(ispif, pcdata->csid_version); - msm_ispif_io_dump_reg(ispif); - break; case ISPIF_SET_VFE_INFO: rc = msm_ispif_set_vfe_info(ispif, &pcdata->vfe_info); break; default: - memset(¶ms, 0, sizeof(params)); - if (pcdata->params.num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid num entries %u\n", __func__, - pcdata->params.num); - rc = -EINVAL; - } else { - params.num = pcdata->params.num; - for (i = 0; i < pcdata->params.num; i++) - memcpy(¶ms.entries[i], - &pcdata->params.entries[i], - sizeof(struct msm_ispif_params_entry)); - params.stereo_enable = 0; - rc = msm_ispif_dispatch_cmd(pcdata->cfg_type, ispif, - ¶ms); - } + pr_err("%s: invalid cfg_type\n", __func__); + rc = -EINVAL; break; } mutex_unlock(&ispif->mutex); - return rc; } - static struct v4l2_file_operations msm_ispif_v4l2_subdev_fops; static long msm_ispif_subdev_ioctl_unlocked(struct v4l2_subdev *sd, @@ -1961,6 +1683,9 @@ static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) rc = msm_ispif_clk_ahb_enable(ispif, 1); if (rc) goto ahb_clk_enable_fail; + rc = msm_camera_enable_irq(ispif->irq, 1); + if (rc) + goto irq_enable_fail; } /* mem remap is done in init when the clock is on */ ispif->open_cnt++; @@ -1968,6 +1693,8 @@ static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return rc; ahb_clk_enable_fail: msm_ispif_set_regulators(ispif->ispif_vdd, ispif->ispif_vdd_count, 0); +irq_enable_fail: + msm_ispif_clk_ahb_enable(ispif, 0); unlock: mutex_unlock(&ispif->mutex); return rc; diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h index 3e6680c63ee5..61e8f1dd7aff 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -77,6 +77,5 @@ struct ispif_device { int ispif_vdd_count; struct regulator *vfe_vdd[ISPIF_VFE_VDD_INFO_MAX]; int vfe_vdd_count; - int stereo_configured[VFE_MAX]; }; #endif diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.c deleted file mode 100644 index 7c12fb9af6c4..000000000000 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.c +++ /dev/null @@ -1,1578 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_ispif_32.h" -#include "msm.h" -#include "msm_sd.h" -#include "msm_camera_io_util.h" - -#ifdef CONFIG_MSM_ISPIF_V1 -#include "msm_ispif_hwreg_v1.h" -#else -#include "msm_ispif_hwreg_v2.h" -#endif - -#define V4L2_IDENT_ISPIF 50001 -#define MSM_ISPIF_DRV_NAME "msm_ispif" - -#define ISPIF_INTF_CMD_DISABLE_FRAME_BOUNDARY 0x00 -#define ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY 0x01 -#define ISPIF_INTF_CMD_DISABLE_IMMEDIATELY 0x02 - -#define ISPIF_TIMEOUT_SLEEP_US 1000 -#define ISPIF_TIMEOUT_ALL_US 1000000 - -#undef CDBG -#ifdef CONFIG_MSMB_CAMERA_DEBUG -#define CDBG(fmt, args...) pr_debug(fmt, ##args) -#else -#define CDBG(fmt, args...) do { } while (0) -#endif - -static void msm_ispif_io_dump_reg(struct ispif_device *ispif) -{ - if (!ispif->enb_dump_reg) - return; - - if (!ispif->base) { - pr_err("%s: null pointer for the ispif base\n", __func__); - return; - } - - msm_camera_io_dump(ispif->base, 0x250, 0); -} - - -static inline int msm_ispif_is_intf_valid(uint32_t csid_version, - uint8_t intf_type) -{ - return (((csid_version <= CSID_VERSION_V22 - && intf_type != VFE0) || - (intf_type >= VFE_MAX)) - ? false : true); -} - -static struct msm_cam_clk_info ispif_8626_reset_clk_info[] = { - {"ispif_ahb_clk", NO_SET_RATE}, - {"csi0_src_clk", NO_SET_RATE}, - {"csi0_clk", NO_SET_RATE}, - {"csi0_pix_clk", NO_SET_RATE}, - {"csi0_rdi_clk", NO_SET_RATE}, - {"csi1_src_clk", NO_SET_RATE}, - {"csi1_clk", NO_SET_RATE}, - {"csi1_pix_clk", NO_SET_RATE}, - {"csi1_rdi_clk", NO_SET_RATE}, - {"camss_vfe_vfe0_clk", NO_SET_RATE}, - {"camss_csi_vfe0_clk", NO_SET_RATE}, -}; - -static struct msm_cam_clk_info ispif_8974_ahb_clk_info[ISPIF_CLK_INFO_MAX]; - -static struct msm_cam_clk_info ispif_8974_reset_clk_info[] = { - {"csi0_src_clk", INIT_RATE}, - {"csi0_clk", NO_SET_RATE}, - {"csi0_pix_clk", NO_SET_RATE}, - {"csi0_rdi_clk", NO_SET_RATE}, - {"csi1_src_clk", INIT_RATE}, - {"csi1_clk", NO_SET_RATE}, - {"csi1_pix_clk", NO_SET_RATE}, - {"csi1_rdi_clk", NO_SET_RATE}, - {"csi2_src_clk", INIT_RATE}, - {"csi2_clk", NO_SET_RATE}, - {"csi2_pix_clk", NO_SET_RATE}, - {"csi2_rdi_clk", NO_SET_RATE}, - {"csi3_src_clk", INIT_RATE}, - {"csi3_clk", NO_SET_RATE}, - {"csi3_pix_clk", NO_SET_RATE}, - {"csi3_rdi_clk", NO_SET_RATE}, - {"vfe0_clk_src", INIT_RATE}, - {"camss_vfe_vfe0_clk", NO_SET_RATE}, - {"camss_csi_vfe0_clk", NO_SET_RATE}, - {"vfe1_clk_src", INIT_RATE}, - {"camss_vfe_vfe1_clk", NO_SET_RATE}, - {"camss_csi_vfe1_clk", NO_SET_RATE}, -}; - -static int msm_ispif_reset_hw(struct ispif_device *ispif) -{ - int rc = 0; - long timeout = 0; - struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; - struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)]; - - ispif->clk_idx = 0; - - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 1); - if (rc < 0) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8626_reset_clk_info, reset_clk1, - ARRAY_SIZE(ispif_8626_reset_clk_info), 1); - if (rc < 0) { - pr_err("%s: cannot enable clock, error = %d", - __func__, rc); - } else { - /* This is set when device is 8x26 */ - ispif->clk_idx = 2; - } - } else { - /* This is set when device is 8974 */ - ispif->clk_idx = 1; - } - - init_completion(&ispif->reset_complete[VFE0]); - if (ispif->hw_num_isps > 1) - init_completion(&ispif->reset_complete[VFE1]); - - /* initiate reset of ISPIF */ - msm_camera_io_w(ISPIF_RST_CMD_MASK, - ispif->base + ISPIF_RST_CMD_ADDR); - if (ispif->hw_num_isps > 1) - msm_camera_io_w(ISPIF_RST_CMD_1_MASK, - ispif->base + ISPIF_RST_CMD_1_ADDR); - - timeout = wait_for_completion_timeout( - &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); - CDBG("%s: VFE0 done\n", __func__); - - if (timeout <= 0) { - pr_err("%s: VFE0 reset wait timeout\n", __func__); - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 0); - if (rc < 0) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8626_reset_clk_info, reset_clk1, - ARRAY_SIZE(ispif_8626_reset_clk_info), 0); - if (rc < 0) - pr_err("%s: VFE0 reset wait timeout\n", - __func__); - } - return -ETIMEDOUT; - } - - if (ispif->hw_num_isps > 1) { - timeout = wait_for_completion_timeout( - &ispif->reset_complete[VFE1], - msecs_to_jiffies(500)); - CDBG("%s: VFE1 done\n", __func__); - if (timeout <= 0) { - pr_err("%s: VFE1 reset wait timeout\n", __func__); - msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 0); - return -ETIMEDOUT; - } - } - - if (ispif->clk_idx == 1) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 0); - if (rc < 0) { - pr_err("%s: cannot disable clock, error = %d", - __func__, rc); - } - } - - if (ispif->clk_idx == 2) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8626_reset_clk_info, reset_clk1, - ARRAY_SIZE(ispif_8626_reset_clk_info), 0); - if (rc < 0) { - pr_err("%s: cannot disable clock, error = %d", - __func__, rc); - } - } - - return rc; -} - -int msm_ispif_get_ahb_clk_info(struct ispif_device *ispif_dev, - struct platform_device *pdev, - struct msm_cam_clk_info *ahb_clk_info) -{ - uint32_t num_ahb_clk = 0; - int i, count, rc; - uint32_t rates[ISPIF_CLK_INFO_MAX]; - - struct device_node *of_node; - - of_node = pdev->dev.of_node; - - count = of_property_count_strings(of_node, "clock-names"); - - CDBG("count = %d\n", count); - if (count <= 0) { - pr_err("no clocks found in device tree, count=%d", count); - return 0; - } - - if (count > ISPIF_CLK_INFO_MAX) { - pr_err("invalid count=%d, max is %d\n", count, - ISPIF_CLK_INFO_MAX); - return -EINVAL; - } - - rc = of_property_read_u32_array(of_node, "qcom,clock-rates", - rates, count); - if (rc < 0) { - pr_err("%s failed %d\n", __func__, __LINE__); - return rc; - } - for (i = 0; i < count; i++) { - rc = of_property_read_string_index(of_node, "clock-names", - i, &(ahb_clk_info[num_ahb_clk].clk_name)); - CDBG("clock-names[%d] = %s\n", - i, ahb_clk_info[i].clk_name); - if (rc < 0) { - pr_err("%s failed %d\n", __func__, __LINE__); - return rc; - } - if (strnstr(ahb_clk_info[num_ahb_clk].clk_name, "ahb", - sizeof(ahb_clk_info[num_ahb_clk].clk_name))) { - ahb_clk_info[num_ahb_clk].clk_rate = - (rates[i] == 0) ? (long)-1 : rates[i]; - CDBG("clk_rate[%d] = %ld\n", i, - ahb_clk_info[i].clk_rate); - num_ahb_clk++; - } - } - ispif_dev->num_ahb_clk = num_ahb_clk; - return 0; -} - -static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable) -{ - int rc = 0; - - if (ispif->csid_version < CSID_VERSION_V30) { - /* Older ISPIF versiond don't need ahb clokc */ - return 0; - } - - rc = msm_ispif_get_ahb_clk_info(ispif, ispif->pdev, - ispif_8974_ahb_clk_info); - if (rc < 0) { - pr_err("%s: msm_isp_get_clk_info() failed", __func__); - return -EFAULT; - } - - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_ahb_clk_info, ispif->ahb_clk, - ispif->num_ahb_clk, enable); - if (rc < 0) { - pr_err("%s: cannot enable clock, error = %d", - __func__, rc); - } - - return rc; -} - -static int msm_ispif_reset(struct ispif_device *ispif) -{ - int rc = 0; - int i; - - BUG_ON(!ispif); - - memset(ispif->sof_count, 0, sizeof(ispif->sof_count)); - for (i = 0; i < ispif->vfe_info.num_vfe; i++) { - - msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT, - ispif->base + ISPIF_VFE_m_CTRL_0(i)); - msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i)); - msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i)); - msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i)); - msm_camera_io_w(0xFFFFFFFF, ispif->base + - ISPIF_VFE_m_IRQ_CLEAR_0(i)); - msm_camera_io_w(0xFFFFFFFF, ispif->base + - ISPIF_VFE_m_IRQ_CLEAR_1(i)); - msm_camera_io_w(0xFFFFFFFF, ispif->base + - ISPIF_VFE_m_IRQ_CLEAR_2(i)); - - msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i)); - - msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, - ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); - msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, - ispif->base + ISPIF_VFE_m_INTF_CMD_1(i)); - pr_debug("%s: base %pK", __func__, ispif->base); - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0)); - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1)); - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0)); - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1)); - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 2)); - - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0)); - msm_camera_io_w(0, ispif->base + - ISPIF_VFE_m_PIX_INTF_n_CROP(i, 1)); - } - - msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + - ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); - - return rc; -} - -/* -static int msm_ispif_subdev_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) -{ - BUG_ON(!chip); - chip->ident = V4L2_IDENT_ISPIF; - chip->revision = 0; - return 0; -} -*/ - -static void msm_ispif_sel_csid_core(struct ispif_device *ispif, - uint8_t intftype, uint8_t csid, uint8_t vfe_intf) -{ - uint32_t data; - - BUG_ON(!ispif); - - if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - return; - } - - data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_INPUT_SEL(vfe_intf)); - switch (intftype) { - case PIX0: - data &= ~(BIT(1) | BIT(0)); - data |= (uint32_t)csid; - break; - case RDI0: - data &= ~(BIT(5) | BIT(4)); - data |= (uint32_t)(csid << 4); - break; - case PIX1: - data &= ~(BIT(9) | BIT(8)); - data |= (uint32_t)(csid << 8); - break; - case RDI1: - data &= ~(BIT(13) | BIT(12)); - data |= (uint32_t)(csid << 12); - break; - case RDI2: - data &= ~(BIT(21) | BIT(20)); - data |= (uint32_t)(csid << 20); - break; - } - - msm_camera_io_w_mb(data, ispif->base + - ISPIF_VFE_m_INPUT_SEL(vfe_intf)); -} - -static void msm_ispif_enable_crop(struct ispif_device *ispif, - uint8_t intftype, uint8_t vfe_intf, uint16_t start_pixel, - uint16_t end_pixel) -{ - uint32_t data; - - BUG_ON(!ispif); - - if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - return; - } - - data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_CTRL_0(vfe_intf)); - data |= (1 << (intftype + 7)); - if (intftype == PIX0) - data |= 1 << PIX0_LINE_BUF_EN_BIT; - msm_camera_io_w(data, - ispif->base + ISPIF_VFE_m_CTRL_0(vfe_intf)); - - if (intftype == PIX0) - msm_camera_io_w_mb(start_pixel | (end_pixel << 16), - ispif->base + ISPIF_VFE_m_PIX_INTF_n_CROP(vfe_intf, 0)); - else if (intftype == PIX1) - msm_camera_io_w_mb(start_pixel | (end_pixel << 16), - ispif->base + ISPIF_VFE_m_PIX_INTF_n_CROP(vfe_intf, 1)); - else { - pr_err("%s: invalid intftype=%d\n", __func__, intftype); - BUG_ON(1); - return; - } -} - -static void msm_ispif_enable_intf_cids(struct ispif_device *ispif, - uint8_t intftype, uint16_t cid_mask, uint8_t vfe_intf, uint8_t enable) -{ - uint32_t intf_addr, data; - - BUG_ON(!ispif); - - if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - return; - } - - switch (intftype) { - case PIX0: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe_intf, 0); - break; - case RDI0: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe_intf, 0); - break; - case PIX1: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe_intf, 1); - break; - case RDI1: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe_intf, 1); - break; - case RDI2: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe_intf, 2); - break; - default: - pr_err("%s: invalid intftype=%d\n", __func__, intftype); - BUG_ON(1); - return; - } - - data = msm_camera_io_r(ispif->base + intf_addr); - if (enable) - data |= (uint32_t)cid_mask; - else - data &= ~((uint32_t)cid_mask); - msm_camera_io_w_mb(data, ispif->base + intf_addr); -} - -static int msm_ispif_validate_intf_status(struct ispif_device *ispif, - uint8_t intftype, uint8_t vfe_intf) -{ - int rc = 0; - uint32_t data = 0; - - BUG_ON(!ispif); - - if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - return -EINVAL; - } - - switch (intftype) { - case PIX0: - data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0)); - break; - case RDI0: - data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0)); - break; - case PIX1: - data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1)); - break; - case RDI1: - data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1)); - break; - case RDI2: - data = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2)); - break; - } - if ((data & 0xf) != 0xf) - rc = -EBUSY; - return rc; -} - -static void msm_ispif_select_clk_mux(struct ispif_device *ispif, - uint8_t intftype, uint8_t csid, uint8_t vfe_intf) -{ - uint32_t data = 0; - - switch (intftype) { - case PIX0: - data = msm_camera_io_r(ispif->clk_mux_base); - data &= ~(0xf << (vfe_intf * 8)); - data |= (csid << (vfe_intf * 8)); - msm_camera_io_w(data, ispif->clk_mux_base); - break; - - case RDI0: - data = msm_camera_io_r(ispif->clk_mux_base + - ISPIF_RDI_CLK_MUX_SEL_ADDR); - data &= ~(0xf << (vfe_intf * 12)); - data |= (csid << (vfe_intf * 12)); - msm_camera_io_w(data, ispif->clk_mux_base + - ISPIF_RDI_CLK_MUX_SEL_ADDR); - break; - - case PIX1: - data = msm_camera_io_r(ispif->clk_mux_base); - data &= ~(0xf0 << (vfe_intf * 8)); - data |= (csid << (4 + (vfe_intf * 8))); - msm_camera_io_w(data, ispif->clk_mux_base); - break; - - case RDI1: - data = msm_camera_io_r(ispif->clk_mux_base + - ISPIF_RDI_CLK_MUX_SEL_ADDR); - data &= ~(0xf << (4 + (vfe_intf * 12))); - data |= (csid << (4 + (vfe_intf * 12))); - msm_camera_io_w(data, ispif->clk_mux_base + - ISPIF_RDI_CLK_MUX_SEL_ADDR); - break; - - case RDI2: - data = msm_camera_io_r(ispif->clk_mux_base + - ISPIF_RDI_CLK_MUX_SEL_ADDR); - data &= ~(0xf << (8 + (vfe_intf * 12))); - data |= (csid << (8 + (vfe_intf * 12))); - msm_camera_io_w(data, ispif->clk_mux_base + - ISPIF_RDI_CLK_MUX_SEL_ADDR); - break; - } - CDBG("%s intftype %d data %x\n", __func__, intftype, data); - /* ensure clk mux is enabled */ - mb(); -} - -static uint16_t msm_ispif_get_cids_mask_from_cfg( - struct msm_ispif_params_entry *entry) -{ - int i; - uint16_t cids_mask = 0; - - BUG_ON(!entry); - - for (i = 0; i < entry->num_cids && i < MAX_CID_CH_v2; i++) - cids_mask |= (1 << entry->cids[i]); - - return cids_mask; -} - -static int msm_ispif_config(struct ispif_device *ispif, - struct msm_ispif_param_data *params) -{ - int rc = 0, i = 0; - uint16_t cid_mask; - enum msm_ispif_intftype intftype; - enum msm_ispif_vfe_intf vfe_intf; - - BUG_ON(!ispif); - BUG_ON(!params); - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - if (params->num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid param entries %d\n", __func__, - params->num); - rc = -EINVAL; - return rc; - } - - for (i = 0; i < params->num; i++) { - vfe_intf = params->entries[i].vfe_intf; - if (vfe_intf >= VFE_MAX) { - pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__, - __LINE__, i, vfe_intf); - return -EINVAL; - } - if (!msm_ispif_is_intf_valid(ispif->csid_version, - vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - return -EINVAL; - } - msm_camera_io_w(0x0, ispif->base + - ISPIF_VFE_m_IRQ_MASK_0(vfe_intf)); - msm_camera_io_w(0x0, ispif->base + - ISPIF_VFE_m_IRQ_MASK_1(vfe_intf)); - msm_camera_io_w_mb(0x0, ispif->base + - ISPIF_VFE_m_IRQ_MASK_2(vfe_intf)); - } - - for (i = 0; i < params->num; i++) { - intftype = params->entries[i].intftype; - - vfe_intf = params->entries[i].vfe_intf; - - CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__, - intftype, vfe_intf, params->entries[i].csid); - - if ((intftype >= INTF_MAX) || - (vfe_intf >= ispif->vfe_info.num_vfe) || - (ispif->csid_version <= CSID_VERSION_V22 && - (vfe_intf > VFE0))) { - pr_err("%s: VFEID %d and CSID version %d mismatch\n", - __func__, vfe_intf, ispif->csid_version); - return -EINVAL; - } - - if (ispif->csid_version >= CSID_VERSION_V30) - msm_ispif_select_clk_mux(ispif, intftype, - params->entries[i].csid, vfe_intf); - - rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf); - if (rc) { - pr_err("%s:validate_intf_status failed, rc = %d\n", - __func__, rc); - return rc; - } - - msm_ispif_sel_csid_core(ispif, intftype, - params->entries[i].csid, vfe_intf); - cid_mask = msm_ispif_get_cids_mask_from_cfg( - ¶ms->entries[i]); - msm_ispif_enable_intf_cids(ispif, intftype, - cid_mask, vfe_intf, 1); - if (params->entries[i].crop_enable) - msm_ispif_enable_crop(ispif, intftype, vfe_intf, - params->entries[i].crop_start_pixel, - params->entries[i].crop_end_pixel); - } - - for (vfe_intf = 0; vfe_intf < 2; vfe_intf++) { - msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base + - ISPIF_VFE_m_IRQ_MASK_0(vfe_intf)); - - msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base + - ISPIF_VFE_m_IRQ_CLEAR_0(vfe_intf)); - - msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base + - ISPIF_VFE_m_IRQ_MASK_1(vfe_intf)); - - msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base + - ISPIF_VFE_m_IRQ_CLEAR_1(vfe_intf)); - - msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base + - ISPIF_VFE_m_IRQ_MASK_2(vfe_intf)); - - msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base + - ISPIF_VFE_m_IRQ_CLEAR_2(vfe_intf)); - } - - msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + - ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); - - return rc; -} - -static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits, - struct msm_ispif_param_data *params) -{ - uint8_t vc; - int i, k; - enum msm_ispif_intftype intf_type; - enum msm_ispif_cid cid; - enum msm_ispif_vfe_intf vfe_intf; - - BUG_ON(!ispif); - BUG_ON(!params); - - for (i = 0; i < params->num; i++) { - vfe_intf = params->entries[i].vfe_intf; - if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - return; - } - if (params->entries[i].num_cids > MAX_CID_CH_v2) { - pr_err("%s: out of range of cid_num %d\n", - __func__, params->entries[i].num_cids); - return; - } - } - - for (i = 0; i < params->num; i++) { - intf_type = params->entries[i].intftype; - vfe_intf = params->entries[i].vfe_intf; - for (k = 0; k < params->entries[i].num_cids; k++) { - cid = params->entries[i].cids[k]; - vc = cid / 4; - if (intf_type == RDI2) { - /* zero out two bits */ - ispif->applied_intf_cmd[vfe_intf].intf_cmd1 &= - ~(0x3 << (vc * 2 + 8)); - /* set cmd bits */ - ispif->applied_intf_cmd[vfe_intf].intf_cmd1 |= - (cmd_bits << (vc * 2 + 8)); - } else { - /* zero 2 bits */ - ispif->applied_intf_cmd[vfe_intf].intf_cmd &= - ~(0x3 << (vc * 2 + intf_type * 8)); - /* set cmd bits */ - ispif->applied_intf_cmd[vfe_intf].intf_cmd |= - (cmd_bits << (vc * 2 + intf_type * 8)); - } - } - /* cmd for PIX0, PIX1, RDI0, RDI1 */ - if (ispif->applied_intf_cmd[vfe_intf].intf_cmd != 0xFFFFFFFF) - msm_camera_io_w_mb( - ispif->applied_intf_cmd[vfe_intf].intf_cmd, - ispif->base + ISPIF_VFE_m_INTF_CMD_0(vfe_intf)); - - /* cmd for RDI2 */ - if (ispif->applied_intf_cmd[vfe_intf].intf_cmd1 != 0xFFFFFFFF) - msm_camera_io_w_mb( - ispif->applied_intf_cmd[vfe_intf].intf_cmd1, - ispif->base + ISPIF_VFE_m_INTF_CMD_1(vfe_intf)); - } -} - -static int msm_ispif_stop_immediately(struct ispif_device *ispif, - struct msm_ispif_param_data *params) -{ - int i, rc = 0; - uint16_t cid_mask = 0; - - BUG_ON(!ispif); - BUG_ON(!params); - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - - if (params->num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid param entries %d\n", __func__, - params->num); - rc = -EINVAL; - return rc; - } - msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_DISABLE_IMMEDIATELY, params); - - /* after stop the interface we need to unmask the CID enable bits */ - for (i = 0; i < params->num; i++) { - cid_mask = msm_ispif_get_cids_mask_from_cfg( - ¶ms->entries[i]); - msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype, - cid_mask, params->entries[i].vfe_intf, 0); - } - - return rc; -} - -static int msm_ispif_start_frame_boundary(struct ispif_device *ispif, - struct msm_ispif_param_data *params) -{ - int rc = 0; - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - if (params->num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid param entries %d\n", __func__, - params->num); - rc = -EINVAL; - return rc; - } - - msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params); - - return rc; -} - -static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, - struct msm_ispif_param_data *params) -{ - int rc = 0, i; - long timeout = 0; - uint16_t cid_mask; - enum msm_ispif_intftype intftype; - enum msm_ispif_vfe_intf vfe_intf; - uint32_t vfe_mask = 0; - uint32_t intf_addr; - struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; - struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)]; - - ispif->clk_idx = 0; - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - if (params->num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid param entries %d\n", __func__, - params->num); - rc = -EINVAL; - return rc; - } - - for (i = 0; i < params->num; i++) { - vfe_intf = params->entries[i].vfe_intf; - if (vfe_intf >= VFE_MAX) { - pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__, - __LINE__, i, vfe_intf); - return -EINVAL; - } - vfe_mask |= (1 << vfe_intf); - } - - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 1); - if (rc < 0) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8626_reset_clk_info, reset_clk1, - ARRAY_SIZE(ispif_8626_reset_clk_info), 1); - if (rc < 0) { - pr_err("%s: cannot enable clock, error = %d", - __func__, rc); - } else { - /* This is set when device is 8x26 */ - ispif->clk_idx = 2; - } - } else { - /* This is set when device is 8974 */ - ispif->clk_idx = 1; - } - - if (vfe_mask & (1 << VFE0)) { - init_completion(&ispif->reset_complete[VFE0]); - pr_err("%s Init completion VFE0\n", __func__); - /* initiate reset of ISPIF */ - msm_camera_io_w(0x00001FF9, - ispif->base + ISPIF_RST_CMD_ADDR); - } - if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { - init_completion(&ispif->reset_complete[VFE1]); - pr_err("%s Init completion VFE1\n", __func__); - msm_camera_io_w(0x00001FF9, - ispif->base + ISPIF_RST_CMD_1_ADDR); - } - - if (vfe_mask & (1 << VFE0)) { - timeout = wait_for_completion_timeout( - &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); - if (timeout <= 0) { - pr_err("%s: VFE0 reset wait timeout\n", __func__); - rc = -ETIMEDOUT; - goto disable_clk; - } - } - - if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { - timeout = wait_for_completion_timeout( - &ispif->reset_complete[VFE1], - msecs_to_jiffies(500)); - if (timeout <= 0) { - pr_err("%s: VFE1 reset wait timeout\n", __func__); - rc = -ETIMEDOUT; - goto disable_clk; - } - } - - pr_info("%s: ISPIF reset hw done", __func__); - - if (ispif->clk_idx == 1) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 0); - if (rc < 0) { - pr_err("%s: cannot disable clock, error = %d", - __func__, rc); - goto end; - } - } - - if (ispif->clk_idx == 2) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8626_reset_clk_info, reset_clk1, - ARRAY_SIZE(ispif_8626_reset_clk_info), 0); - if (rc < 0) { - pr_err("%s: cannot disable clock, error = %d", - __func__, rc); - goto end; - } - } - - for (i = 0; i < params->num; i++) { - intftype = params->entries[i].intftype; - vfe_intf = params->entries[i].vfe_intf; - - switch (params->entries[0].intftype) { - case PIX0: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0); - break; - case RDI0: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0); - break; - case PIX1: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1); - break; - case RDI1: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1); - break; - case RDI2: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2); - break; - default: - pr_err("%s: invalid intftype=%d\n", __func__, - params->entries[i].intftype); - rc = -EPERM; - goto end; - } - - msm_ispif_intf_cmd(ispif, - ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params); - } - - for (i = 0; i < params->num; i++) { - intftype = params->entries[i].intftype; - - vfe_intf = params->entries[i].vfe_intf; - - - cid_mask = msm_ispif_get_cids_mask_from_cfg( - ¶ms->entries[i]); - - msm_ispif_enable_intf_cids(ispif, intftype, - cid_mask, vfe_intf, 1); - } - -end: - return rc; -disable_clk: - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8974_reset_clk_info, reset_clk, - ARRAY_SIZE(ispif_8974_reset_clk_info), 0); - if (rc < 0) { - rc = msm_cam_clk_enable(&ispif->pdev->dev, - ispif_8626_reset_clk_info, reset_clk1, - ARRAY_SIZE(ispif_8626_reset_clk_info), 0); - if (rc < 0) - pr_err("%s: cannot enable clock, error = %d", - __func__, rc); - } - - return -ETIMEDOUT; -} - -static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, - struct msm_ispif_param_data *params) -{ - int i, rc = 0; - uint16_t cid_mask = 0; - uint32_t intf_addr; - enum msm_ispif_vfe_intf vfe_intf; - uint32_t stop_flag = 0; - - BUG_ON(!ispif); - BUG_ON(!params); - - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - - if (params->num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid param entries %d\n", __func__, - params->num); - rc = -EINVAL; - return rc; - } - - for (i = 0; i < params->num; i++) { - if (!msm_ispif_is_intf_valid(ispif->csid_version, - params->entries[i].vfe_intf)) { - pr_err("%s: invalid interface type\n", __func__); - rc = -EINVAL; - goto end; - } - } - - msm_ispif_intf_cmd(ispif, - ISPIF_INTF_CMD_DISABLE_FRAME_BOUNDARY, params); - - for (i = 0; i < params->num; i++) { - cid_mask = - msm_ispif_get_cids_mask_from_cfg(¶ms->entries[i]); - vfe_intf = params->entries[i].vfe_intf; - - switch (params->entries[i].intftype) { - case PIX0: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0); - break; - case RDI0: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0); - break; - case PIX1: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1); - break; - case RDI1: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1); - break; - case RDI2: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2); - break; - default: - pr_err("%s: invalid intftype=%d\n", __func__, - params->entries[i].intftype); - rc = -EPERM; - goto end; - } - - rc = readl_poll_timeout(ispif->base + intf_addr, stop_flag, - (stop_flag & 0xF) == 0xF, - ISPIF_TIMEOUT_SLEEP_US, - ISPIF_TIMEOUT_ALL_US); - if (rc < 0) - goto end; - - /* disable CIDs in CID_MASK register */ - msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype, - cid_mask, vfe_intf, 0); - } - -end: - return rc; -} - -static void ispif_process_irq(struct ispif_device *ispif, - struct ispif_irq_status *out, enum msm_ispif_vfe_intf vfe_id) -{ - BUG_ON(!ispif); - BUG_ON(!out); - - if (out[vfe_id].ispifIrqStatus0 & - ISPIF_IRQ_STATUS_PIX_SOF_MASK) { - if (ispif->ispif_sof_debug < 5) - pr_err("%s: PIX0 frame id: %u\n", __func__, - ispif->sof_count[vfe_id].sof_cnt[PIX0]); - ispif->sof_count[vfe_id].sof_cnt[PIX0]++; - ispif->ispif_sof_debug++; - } - if (out[vfe_id].ispifIrqStatus0 & - ISPIF_IRQ_STATUS_RDI0_SOF_MASK) { - ispif->sof_count[vfe_id].sof_cnt[RDI0]++; - } - if (out[vfe_id].ispifIrqStatus1 & - ISPIF_IRQ_STATUS_RDI1_SOF_MASK) { - ispif->sof_count[vfe_id].sof_cnt[RDI1]++; - } - if (out[vfe_id].ispifIrqStatus2 & - ISPIF_IRQ_STATUS_RDI2_SOF_MASK) { - ispif->sof_count[vfe_id].sof_cnt[RDI2]++; - } -} - -static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, - void *data) -{ - struct ispif_device *ispif = (struct ispif_device *)data; - - BUG_ON(!ispif); - BUG_ON(!out); - - out[VFE0].ispifIrqStatus0 = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_IRQ_STATUS_0(VFE0)); - msm_camera_io_w(out[VFE0].ispifIrqStatus0, - ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(VFE0)); - - out[VFE0].ispifIrqStatus1 = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_IRQ_STATUS_1(VFE0)); - msm_camera_io_w(out[VFE0].ispifIrqStatus1, - ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(VFE0)); - - out[VFE0].ispifIrqStatus2 = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_IRQ_STATUS_2(VFE0)); - msm_camera_io_w_mb(out[VFE0].ispifIrqStatus2, - ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE0)); - - if (ispif->vfe_info.num_vfe > 1) { - out[VFE1].ispifIrqStatus0 = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_IRQ_STATUS_0(VFE1)); - msm_camera_io_w(out[VFE1].ispifIrqStatus0, - ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(VFE1)); - - out[VFE1].ispifIrqStatus1 = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_IRQ_STATUS_1(VFE1)); - msm_camera_io_w(out[VFE1].ispifIrqStatus1, - ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(VFE1)); - - out[VFE1].ispifIrqStatus2 = msm_camera_io_r(ispif->base + - ISPIF_VFE_m_IRQ_STATUS_2(VFE1)); - msm_camera_io_w_mb(out[VFE1].ispifIrqStatus2, - ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE1)); - } - msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + - ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); - - if (out[VFE0].ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) { - if (out[VFE0].ispifIrqStatus0 & RESET_DONE_IRQ) - complete(&ispif->reset_complete[VFE0]); - - if (out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) - pr_err("%s: VFE0 pix0 overflow.\n", __func__); - - if (out[VFE0].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) - pr_err("%s: VFE0 rdi0 overflow.\n", __func__); - - if (out[VFE0].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ) - pr_err("%s: VFE0 rdi1 overflow.\n", __func__); - - if (out[VFE0].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ) - pr_err("%s: VFE0 rdi2 overflow.\n", __func__); - - ispif_process_irq(ispif, out, VFE0); - } - if (ispif->hw_num_isps > 1) { - if (out[VFE1].ispifIrqStatus0 & RESET_DONE_IRQ) - complete(&ispif->reset_complete[VFE1]); - - if (out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) - pr_err("%s: VFE1 pix0 overflow.\n", __func__); - - if (out[VFE1].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) - pr_err("%s: VFE1 rdi0 overflow.\n", __func__); - - if (out[VFE1].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ) - pr_err("%s: VFE1 rdi1 overflow.\n", __func__); - - if (out[VFE1].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ) - pr_err("%s: VFE1 rdi2 overflow.\n", __func__); - - ispif_process_irq(ispif, out, VFE1); - } -} - -static irqreturn_t msm_io_ispif_irq(int irq_num, void *data) -{ - struct ispif_irq_status irq[VFE_MAX]; - - msm_ispif_read_irq_status(irq, data); - return IRQ_HANDLED; -} - -static int msm_ispif_set_vfe_info(struct ispif_device *ispif, - struct msm_ispif_vfe_info *vfe_info) -{ - if (!vfe_info || (vfe_info->num_vfe <= 0) || - ((uint32_t)(vfe_info->num_vfe) > ispif->hw_num_isps)) { - pr_err("Invalid VFE info: %pK %d\n", vfe_info, - (vfe_info ? vfe_info->num_vfe:0)); - return -EINVAL; - } - - memcpy(&ispif->vfe_info, vfe_info, sizeof(struct msm_ispif_vfe_info)); - - return 0; -} - -static int msm_ispif_init(struct ispif_device *ispif, - uint32_t csid_version) -{ - int rc = 0; - - BUG_ON(!ispif); - - if (ispif->ispif_state == ISPIF_POWER_UP) { - pr_err("%s: ispif already initted state = %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - - /* can we set to zero? */ - ispif->applied_intf_cmd[VFE0].intf_cmd = 0xFFFFFFFF; - ispif->applied_intf_cmd[VFE0].intf_cmd1 = 0xFFFFFFFF; - ispif->applied_intf_cmd[VFE1].intf_cmd = 0xFFFFFFFF; - ispif->applied_intf_cmd[VFE1].intf_cmd1 = 0xFFFFFFFF; - memset(ispif->sof_count, 0, sizeof(ispif->sof_count)); - - ispif->csid_version = csid_version; - - if (ispif->csid_version >= CSID_VERSION_V30) { - if (!ispif->clk_mux_mem || !ispif->clk_mux_io) { - pr_err("%s csi clk mux mem %pK io %pK\n", __func__, - ispif->clk_mux_mem, ispif->clk_mux_io); - rc = -ENOMEM; - return rc; - } - ispif->clk_mux_base = ioremap(ispif->clk_mux_mem->start, - resource_size(ispif->clk_mux_mem)); - if (!ispif->clk_mux_base) { - pr_err("%s: clk_mux_mem ioremap failed\n", __func__); - rc = -ENOMEM; - return rc; - } - } - - ispif->base = ioremap(ispif->mem->start, - resource_size(ispif->mem)); - if (!ispif->base) { - rc = -ENOMEM; - pr_err("%s: nomem\n", __func__); - goto end; - } - rc = request_irq(ispif->irq->start, msm_io_ispif_irq, - IRQF_TRIGGER_RISING, "ispif", ispif); - if (rc) { - pr_err("%s: request_irq error = %d\n", __func__, rc); - goto error_irq; - } - - rc = msm_ispif_clk_ahb_enable(ispif, 1); - if (rc) { - pr_err("%s: ahb_clk enable failed", __func__); - goto error_ahb; - } - - msm_ispif_reset_hw(ispif); - - rc = msm_ispif_reset(ispif); - if (rc == 0) { - ispif->ispif_state = ISPIF_POWER_UP; - CDBG("%s: power up done\n", __func__); - goto end; - } - -error_ahb: - free_irq(ispif->irq->start, ispif); -error_irq: - iounmap(ispif->base); - -end: - return rc; -} - -static void msm_ispif_release(struct ispif_device *ispif) -{ - BUG_ON(!ispif); - - if (!ispif->base) { - pr_err("%s: ispif base is NULL\n", __func__); - return; - } - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - return; - } - - /* make sure no streaming going on */ - msm_ispif_reset(ispif); - - msm_ispif_clk_ahb_enable(ispif, 0); - - free_irq(ispif->irq->start, ispif); - - iounmap(ispif->base); - - iounmap(ispif->clk_mux_base); - - ispif->ispif_state = ISPIF_POWER_DOWN; -} - -static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg) -{ - long rc = 0; - struct ispif_cfg_data *pcdata = (struct ispif_cfg_data *)arg; - struct ispif_device *ispif = - (struct ispif_device *)v4l2_get_subdevdata(sd); - - BUG_ON(!sd); - BUG_ON(!pcdata); - - mutex_lock(&ispif->mutex); - switch (pcdata->cfg_type) { - case ISPIF_ENABLE_REG_DUMP: - ispif->enb_dump_reg = pcdata->reg_dump; /* save dump config */ - break; - case ISPIF_INIT: - rc = msm_ispif_init(ispif, pcdata->csid_version); - msm_ispif_io_dump_reg(ispif); - break; - case ISPIF_CFG: - rc = msm_ispif_config(ispif, &pcdata->params); - msm_ispif_io_dump_reg(ispif); - break; - case ISPIF_START_FRAME_BOUNDARY: - rc = msm_ispif_start_frame_boundary(ispif, &pcdata->params); - msm_ispif_io_dump_reg(ispif); - break; - case ISPIF_RESTART_FRAME_BOUNDARY: - rc = msm_ispif_restart_frame_boundary(ispif, &pcdata->params); - msm_ispif_io_dump_reg(ispif); - break; - - case ISPIF_STOP_FRAME_BOUNDARY: - rc = msm_ispif_stop_frame_boundary(ispif, &pcdata->params); - msm_ispif_io_dump_reg(ispif); - break; - case ISPIF_STOP_IMMEDIATELY: - rc = msm_ispif_stop_immediately(ispif, &pcdata->params); - msm_ispif_io_dump_reg(ispif); - break; - case ISPIF_RELEASE: - msm_ispif_release(ispif); - break; - case ISPIF_SET_VFE_INFO: - rc = msm_ispif_set_vfe_info(ispif, &pcdata->vfe_info); - break; - default: - pr_err("%s: invalid cfg_type\n", __func__); - rc = -EINVAL; - break; - } - mutex_unlock(&ispif->mutex); - return rc; -} -static struct v4l2_file_operations msm_ispif_v4l2_subdev_fops; - -static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd, - unsigned int cmd, void *arg) -{ - struct ispif_device *ispif = - (struct ispif_device *)v4l2_get_subdevdata(sd); - - switch (cmd) { - case VIDIOC_MSM_ISPIF_CFG: - return msm_ispif_cmd(sd, arg); - case MSM_SD_NOTIFY_FREEZE: { - ispif->ispif_sof_debug = 0; - return 0; - } - case MSM_SD_SHUTDOWN: { - struct ispif_device *ispif = - (struct ispif_device *)v4l2_get_subdevdata(sd); - if (ispif && ispif->base) { - mutex_lock(&ispif->mutex); - msm_ispif_release(ispif); - mutex_unlock(&ispif->mutex); - } - return 0; - } - default: - pr_err_ratelimited("%s: invalid cmd 0x%x received\n", - __func__, cmd); - return -ENOIOCTLCMD; - } -} - -static long msm_ispif_subdev_do_ioctl( - struct file *file, unsigned int cmd, void *arg) -{ - struct video_device *vdev = video_devdata(file); - struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); - - return msm_ispif_subdev_ioctl(sd, cmd, arg); -} - -static long msm_ispif_subdev_fops_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - return video_usercopy(file, cmd, arg, msm_ispif_subdev_do_ioctl); -} - -static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - struct ispif_device *ispif = v4l2_get_subdevdata(sd); - - mutex_lock(&ispif->mutex); - /* mem remap is done in init when the clock is on */ - ispif->open_cnt++; - mutex_unlock(&ispif->mutex); - return 0; -} - -static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - int rc = 0; - struct ispif_device *ispif = v4l2_get_subdevdata(sd); - - if (!ispif) { - pr_err("%s: invalid input\n", __func__); - return -EINVAL; - } - - mutex_lock(&ispif->mutex); - if (ispif->open_cnt == 0) { - pr_err("%s: Invalid close\n", __func__); - rc = -ENODEV; - goto end; - } - ispif->open_cnt--; - if (ispif->open_cnt == 0) - msm_ispif_release(ispif); -end: - mutex_unlock(&ispif->mutex); - return rc; -} - -static struct v4l2_subdev_core_ops msm_ispif_subdev_core_ops = { - /* .g_chip_ident = &msm_ispif_subdev_g_chip_ident, */ - .ioctl = &msm_ispif_subdev_ioctl, -}; - -static const struct v4l2_subdev_ops msm_ispif_subdev_ops = { - .core = &msm_ispif_subdev_core_ops, -}; - -static const struct v4l2_subdev_internal_ops msm_ispif_internal_ops = { - .open = ispif_open_node, - .close = ispif_close_node, -}; - -static int ispif_probe(struct platform_device *pdev) -{ - int rc; - struct ispif_device *ispif; - - ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL); - if (!ispif) - return -ENOMEM; - - if (pdev->dev.of_node) { - of_property_read_u32((&pdev->dev)->of_node, - "cell-index", &pdev->id); - rc = of_property_read_u32((&pdev->dev)->of_node, - "qcom,num-isps", &ispif->hw_num_isps); - if (rc) - /* backward compatibility */ - ispif->hw_num_isps = 1; - /* not an error condition */ - rc = 0; - } - - mutex_init(&ispif->mutex); - ispif->mem = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "ispif"); - if (!ispif->mem) { - pr_err("%s: no mem resource?\n", __func__); - rc = -ENODEV; - goto error; - } - ispif->irq = platform_get_resource_byname(pdev, - IORESOURCE_IRQ, "ispif"); - if (!ispif->irq) { - pr_err("%s: no irq resource?\n", __func__); - rc = -ENODEV; - goto error; - } - ispif->io = request_mem_region(ispif->mem->start, - resource_size(ispif->mem), pdev->name); - if (!ispif->io) { - pr_err("%s: no valid mem region\n", __func__); - rc = -EBUSY; - goto error; - } - ispif->clk_mux_mem = platform_get_resource_byname(pdev, - IORESOURCE_MEM, "csi_clk_mux"); - if (ispif->clk_mux_mem) { - ispif->clk_mux_io = request_mem_region( - ispif->clk_mux_mem->start, - resource_size(ispif->clk_mux_mem), - ispif->clk_mux_mem->name); - if (!ispif->clk_mux_io) - pr_err("%s: no valid csi_mux region\n", __func__); - } - - v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops); - ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops; - ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - - snprintf(ispif->msm_sd.sd.name, - ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME); - v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif); - - platform_set_drvdata(pdev, &ispif->msm_sd.sd); - - media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0); - ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; - ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF; - ispif->msm_sd.sd.entity.name = pdev->name; - ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1; - rc = msm_sd_register(&ispif->msm_sd); - if (rc) { - pr_err("%s: msm_sd_register error = %d\n", __func__, rc); - goto error; - } - msm_ispif_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner; - msm_ispif_v4l2_subdev_fops.open = v4l2_subdev_fops.open; - msm_ispif_v4l2_subdev_fops.unlocked_ioctl = msm_ispif_subdev_fops_ioctl; - msm_ispif_v4l2_subdev_fops.release = v4l2_subdev_fops.release; - msm_ispif_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll; -#ifdef CONFIG_COMPAT - msm_ispif_v4l2_subdev_fops.compat_ioctl32 = msm_ispif_subdev_fops_ioctl; -#endif - ispif->msm_sd.sd.devnode->fops = &msm_ispif_v4l2_subdev_fops; - ispif->pdev = pdev; - ispif->ispif_state = ISPIF_POWER_DOWN; - ispif->open_cnt = 0; - return 0; - -error: - mutex_destroy(&ispif->mutex); - kfree(ispif); - return rc; -} - -static const struct of_device_id msm_ispif_dt_match[] = { - {.compatible = "qcom,ispif"}, - {} -}; - -MODULE_DEVICE_TABLE(of, msm_ispif_dt_match); - -static struct platform_driver ispif_driver = { - .probe = ispif_probe, - .driver = { - .name = MSM_ISPIF_DRV_NAME, - .owner = THIS_MODULE, - .of_match_table = msm_ispif_dt_match, - }, -}; - -static int __init msm_ispif_init_module(void) -{ - return platform_driver_register(&ispif_driver); -} - -static void __exit msm_ispif_exit_module(void) -{ - platform_driver_unregister(&ispif_driver); -} - -module_init(msm_ispif_init_module); -module_exit(msm_ispif_exit_module); -MODULE_DESCRIPTION("MSM ISP Interface driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.h deleted file mode 100644 index f2c0851f18f8..000000000000 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_32.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef MSM_ISPIF_H -#define MSM_ISPIF_H - -#include -#include -#include -#include -#include "msm_sd.h" - -#define ISPIF_CLK_INFO_MAX 24 - -struct ispif_irq_status { - uint32_t ispifIrqStatus0; - uint32_t ispifIrqStatus1; - uint32_t ispifIrqStatus2; -}; - -enum msm_ispif_state_t { - ISPIF_POWER_UP, - ISPIF_POWER_DOWN, -}; -struct ispif_sof_count { - uint32_t sof_cnt[INTF_MAX]; -}; - -struct ispif_intf_cmd { - uint32_t intf_cmd; - uint32_t intf_cmd1; -}; - -struct ispif_device { - struct platform_device *pdev; - struct msm_sd_subdev msm_sd; - struct resource *mem; - struct resource *clk_mux_mem; - struct resource *irq; - struct resource *io; - struct resource *clk_mux_io; - void __iomem *base; - void __iomem *clk_mux_base; - struct mutex mutex; - uint8_t start_ack_pending; - uint32_t csid_version; - int enb_dump_reg; - uint32_t open_cnt; - struct ispif_sof_count sof_count[VFE_MAX]; - struct ispif_intf_cmd applied_intf_cmd[VFE_MAX]; - enum msm_ispif_state_t ispif_state; - struct msm_ispif_vfe_info vfe_info; - struct clk *ahb_clk[ISPIF_CLK_INFO_MAX]; - struct completion reset_complete[VFE_MAX]; - uint32_t hw_num_isps; - uint32_t num_ahb_clk; - uint32_t clk_idx; - uint32_t ispif_sof_debug; -}; -#endif diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h index 49d7d0f7624e..d488ca618537 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h @@ -87,12 +87,6 @@ #define MISC_LOGIC_RST_STB BIT(1) #define STROBED_RST_EN BIT(0) -#define VFE_PIX_INTF_SEL_3D 0x3 -#define PIX_OUTPUT_0_MISR_RST_STB BIT(16) -#define L_R_SOF_MISMATCH_ERR_IRQ BIT(16) -#define L_R_EOF_MISMATCH_ERR_IRQ BIT(17) -#define L_R_SOL_MISMATCH_ERR_IRQ BIT(18) - #define ISPIF_RST_CMD_MASK 0xFE1C77FF #define ISPIF_RST_CMD_1_MASK 0xFFFFFFFF /* undefined */ diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h index 9abf55efc46c..8ae61dc2d4f6 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h @@ -22,7 +22,6 @@ #define ISPIF_VFE(m) ((m) * 0x200) #define ISPIF_VFE_m_CTRL_0(m) (0x200 + ISPIF_VFE(m)) -#define ISPIF_VFE_m_CTRL_1(m) (0x204 + ISPIF_VFE(m)) #define ISPIF_VFE_m_IRQ_MASK_0(m) (0x208 + ISPIF_VFE(m)) #define ISPIF_VFE_m_IRQ_MASK_1(m) (0x20C + ISPIF_VFE(m)) #define ISPIF_VFE_m_IRQ_MASK_2(m) (0x210 + ISPIF_VFE(m)) @@ -72,12 +71,6 @@ #define MISC_LOGIC_RST_STB BIT(1) #define STROBED_RST_EN BIT(0) -#define VFE_PIX_INTF_SEL_3D 0x3 -#define PIX_OUTPUT_0_MISR_RST_STB BIT(16) -#define L_R_SOF_MISMATCH_ERR_IRQ BIT(16) -#define L_R_EOF_MISMATCH_ERR_IRQ BIT(17) -#define L_R_SOL_MISMATCH_ERR_IRQ BIT(18) - #define ISPIF_RST_CMD_MASK 0xFE0F1FFF #define ISPIF_RST_CMD_1_MASK 0xFC0F1FF9 @@ -85,7 +78,6 @@ #define ISPIF_RST_CMD_1_MASK_RESTART 0x00001FF9 #define PIX_INTF_0_OVERFLOW_IRQ BIT(12) -#define PIX_INTF_1_OVERFLOW_IRQ BIT(12) #define RAW_INTF_0_OVERFLOW_IRQ BIT(25) #define RAW_INTF_1_OVERFLOW_IRQ BIT(25) #define RAW_INTF_2_OVERFLOW_IRQ BIT(12) diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h index b18c177572e4..a5c0ad1b5dce 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h @@ -74,12 +74,6 @@ #define MISC_LOGIC_RST_STB BIT(1) #define STROBED_RST_EN BIT(0) -#define VFE_PIX_INTF_SEL_3D 0x3 -#define PIX_OUTPUT_0_MISR_RST_STB BIT(16) -#define L_R_SOF_MISMATCH_ERR_IRQ BIT(16) -#define L_R_EOF_MISMATCH_ERR_IRQ BIT(17) -#define L_R_SOL_MISMATCH_ERR_IRQ BIT(18) - #define ISPIF_RST_CMD_MASK 0xFE7F1FFF #define ISPIF_RST_CMD_1_MASK 0xFC7F1FF9 @@ -87,7 +81,6 @@ #define ISPIF_RST_CMD_1_MASK_RESTART 0x7F1FF9 #define PIX_INTF_0_OVERFLOW_IRQ BIT(12) -#define PIX_INTF_1_OVERFLOW_IRQ BIT(12) #define RAW_INTF_0_OVERFLOW_IRQ BIT(25) #define RAW_INTF_1_OVERFLOW_IRQ BIT(25) #define RAW_INTF_2_OVERFLOW_IRQ BIT(12) diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c index 821833d53905..e40869d41a5d 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c +++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -903,45 +903,26 @@ int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, uint32_t m_cmds, void msm_jpeg_io_dump(void *base, int size) { - char line_str[128]; + char line_str[128], *p_str; void __iomem *addr = (void __iomem *)base; int i; u32 *p = (u32 *) addr; - size_t offset = 0; - size_t used = 0; - size_t min_range = 0; - size_t sizeof_line_str = sizeof(line_str); u32 data; JPEG_DBG_HIGH("%s:%d] %pK %d", __func__, __LINE__, addr, size); line_str[0] = '\0'; + p_str = line_str; for (i = 0; i < size/4; i++) { if (i % 4 == 0) { - used = snprintf(line_str + offset, - sizeof_line_str - offset, "%pK ", p); - if ((used < min_range) || - (offset + used >= sizeof_line_str)) { - JPEG_PR_ERR("%s\n", line_str); - offset = 0; - line_str[0] = '\0'; - } else { - offset += used; - } + snprintf(p_str, 12, "%08lx: ", (unsigned long)p); + p_str += 10; } data = msm_camera_io_r(p++); - used = snprintf(line_str + offset, - sizeof_line_str - offset, "%08x ", data); - if ((used < min_range) || - (offset + used >= sizeof_line_str)) { - JPEG_PR_ERR("%s\n", line_str); - offset = 0; - line_str[0] = '\0'; - } else { - offset += used; - } + snprintf(p_str, 12, "%08x ", data); + p_str += 9; if ((i + 1) % 4 == 0) { JPEG_DBG_HIGH("%s\n", line_str); line_str[0] = '\0'; - offset = 0; + p_str = line_str; } } if (line_str[0] != '\0') diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c index fad858d7fe89..2e641bcea09b 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -70,18 +72,31 @@ static struct msm_jpegdma_format formats[] = { .planes[1] = JPEGDMA_PLANE_TYPE_CBCR, }, { - .name = "YUV 4:2:0 planar, YCbCr", - .fourcc = V4L2_PIX_FMT_YUV420, + .name = "YVU 4:2:0 planar, YCrCb", + .fourcc = V4L2_PIX_FMT_YVU420, .depth = 12, .num_planes = 3, - .colplane_h = 2, - .colplane_v = 2, + .colplane_h = 1, + .colplane_v = 4, .h_align = 2, .v_align = 2, .planes[0] = JPEGDMA_PLANE_TYPE_Y, .planes[1] = JPEGDMA_PLANE_TYPE_CR, .planes[2] = JPEGDMA_PLANE_TYPE_CB, }, + { + .name = "YUV 4:2:0 planar, YCbCr", + .fourcc = V4L2_PIX_FMT_YUV420, + .depth = 12, + .num_planes = 3, + .colplane_h = 1, + .colplane_v = 4, + .h_align = 2, + .v_align = 2, + .planes[0] = JPEGDMA_PLANE_TYPE_Y, + .planes[1] = JPEGDMA_PLANE_TYPE_CB, + .planes[2] = JPEGDMA_PLANE_TYPE_CR, + }, }; /* @@ -111,6 +126,21 @@ static inline void msm_jpegdma_schedule_next_config(struct jpegdma_ctx *ctx) ctx->config_idx = (ctx->config_idx + 1) % MSM_JPEGDMA_MAX_CONFIGS; } +/* + * msm_jpegdma_cast_long_to_buff_ptr - Cast long to buffer pointer. + * @vaddr: vaddr as long + * @buff_ptr_head: buffer pointer head + */ +static inline void msm_jpegdma_cast_long_to_buff_ptr(unsigned long vaddr, + struct msm_jpeg_dma_buff **buff_ptr_head) +{ +#ifdef CONFIG_COMPAT + *buff_ptr_head = compat_ptr(vaddr); +#else + *buff_ptr_head = (struct msm_jpeg_dma_buff *) vaddr; +#endif +} + /* * msm_jpegdma_get_format_idx - Get jpeg dma format lookup index. * @ctx: Pointer to dma ctx. @@ -196,7 +226,8 @@ static void msm_jpegdma_align_format(struct v4l2_format *f, int format_idx) if (formats[format_idx].num_planes > 1) for (i = 1; i < formats[format_idx].num_planes; i++) size_image += (f->fmt.pix.bytesperline * - (f->fmt.pix.height / formats[format_idx].colplane_v)); + (f->fmt.pix.height / + formats[format_idx].colplane_v)); f->fmt.pix.sizeimage = size_image; f->fmt.pix.field = V4L2_FIELD_NONE; @@ -250,6 +281,9 @@ static int msm_jpegdma_update_hw_config(struct jpegdma_ctx *ctx) size.fps = ctx->timeperframe.denominator / ctx->timeperframe.numerator; + size.in_offset = ctx->in_offset; + size.out_offset = ctx->out_offset; + size.format = formats[ctx->format_idx]; msm_jpegdma_fill_size_from_ctx(ctx, &size); @@ -362,7 +396,9 @@ static void msm_jpegdma_stop_streaming(struct vb2_queue *q) dev_err(ctx->jdma_device->dev, "Ctx wait timeout\n"); ret = -ETIME; } - msm_jpegdma_hw_put(ctx->jdma_device); + + if (ctx->jdma_device->ref_count > 0) + msm_jpegdma_hw_put(ctx->jdma_device); } /* Videobuf2 queue callbacks. */ @@ -385,13 +421,31 @@ static void *msm_jpegdma_get_userptr(void *alloc_ctx, { struct msm_jpegdma_device *dma = alloc_ctx; struct msm_jpegdma_buf_handle *buf; + struct msm_jpeg_dma_buff __user *up_buff; + struct msm_jpeg_dma_buff kp_buff; int ret; + msm_jpegdma_cast_long_to_buff_ptr(vaddr, &up_buff); + + if (!access_ok(VERIFY_READ, up_buff, + sizeof(struct msm_jpeg_dma_buff)) || + get_user(kp_buff.fd, &up_buff->fd)) { + dev_err(dma->dev, "Error getting user data\n"); + return ERR_PTR(-ENOMEM); + } + + if (!access_ok(VERIFY_WRITE, up_buff, + sizeof(struct msm_jpeg_dma_buff)) || + put_user(kp_buff.fd, &up_buff->fd)) { + dev_err(dma->dev, "Error putting user data\n"); + return ERR_PTR(-ENOMEM); + } + buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM); - ret = msm_jpegdma_hw_map_buffer(dma, vaddr, buf); + ret = msm_jpegdma_hw_map_buffer(dma, kp_buff.fd, buf); if (ret < 0 || buf->size < size) goto error; @@ -438,7 +492,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->drv_priv = ctx; src_vq->mem_ops = &msm_jpegdma_vb2_mem_ops; src_vq->ops = &msm_jpegdma_vb2_q_ops; - src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->buf_struct_size = sizeof(struct vb2_buffer); src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(src_vq); @@ -452,7 +506,7 @@ static int msm_jpegdma_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->drv_priv = ctx; dst_vq->mem_ops = &msm_jpegdma_vb2_mem_ops; dst_vq->ops = &msm_jpegdma_vb2_q_ops; - dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->buf_struct_size = sizeof(struct vb2_buffer); dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; ret = vb2_queue_init(dst_vq); @@ -528,7 +582,9 @@ static int msm_jpegdma_release(struct file *file) struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(file->private_data); /* release all the resources */ - msm_jpegdma_hw_put(ctx->jdma_device); + if (ctx->jdma_device->ref_count > 0) + msm_jpegdma_hw_put(ctx->jdma_device); + atomic_set(&ctx->active, 0); complete_all(&ctx->completion); v4l2_m2m_ctx_release(ctx->m2m_ctx); @@ -771,16 +827,50 @@ static int msm_jpegdma_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(fh); + struct msm_jpeg_dma_buff __user *up_buff; + struct msm_jpeg_dma_buff kp_buff; int ret; + msm_jpegdma_cast_long_to_buff_ptr(buf->m.userptr, &up_buff); mutex_lock(&ctx->lock); + if (!access_ok(VERIFY_READ, up_buff, + sizeof(struct msm_jpeg_dma_buff)) || + get_user(kp_buff.fd, &up_buff->fd) || + get_user(kp_buff.offset, &up_buff->offset)) { + dev_err(ctx->jdma_device->dev, "Error getting user data\n"); + mutex_unlock(&ctx->lock); + return -EFAULT; + } + + if (!access_ok(VERIFY_WRITE, up_buff, + sizeof(struct msm_jpeg_dma_buff)) || + put_user(kp_buff.fd, &up_buff->fd) || + put_user(kp_buff.offset, &up_buff->offset)) { + dev_err(ctx->jdma_device->dev, "Error putting user data\n"); + mutex_unlock(&ctx->lock); + return -EFAULT; + } + + switch (buf->type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + ctx->in_offset = kp_buff.offset; + dev_dbg(ctx->jdma_device->dev, "input buf offset %d\n", + ctx->in_offset); + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + ctx->out_offset = kp_buff.offset; + dev_dbg(ctx->jdma_device->dev, "output buf offset %d\n", + ctx->out_offset); + break; + } + + if (atomic_read(&ctx->active)) + ret = msm_jpegdma_update_hw_config(ctx); ret = v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); if (ret < 0) dev_err(ctx->jdma_device->dev, "QBuf fail\n"); - mutex_unlock(&ctx->lock); - return ret; } @@ -813,14 +903,10 @@ static int msm_jpegdma_streamon(struct file *file, if (!msm_jpegdma_config_ok(ctx)) return -EINVAL; - mutex_lock(&ctx->lock); - ret = v4l2_m2m_streamon(file, ctx->m2m_ctx, buf_type); if (ret < 0) dev_err(ctx->jdma_device->dev, "Stream on fail\n"); - mutex_unlock(&ctx->lock); - return ret; } @@ -952,13 +1038,10 @@ static int msm_jpegdma_s_crop(struct file *file, void *fh, return -EINVAL; mutex_lock(&ctx->lock); - ctx->crop = crop->c; if (atomic_read(&ctx->active)) ret = msm_jpegdma_update_hw_config(ctx); - mutex_unlock(&ctx->lock); - return ret; } @@ -1001,7 +1084,7 @@ static int msm_jpegdma_s_parm(struct file *file, void *fh, return -EINVAL; if (!a->parm.output.timeperframe.numerator || - !a->parm.output.timeperframe.denominator) + !a->parm.output.timeperframe.denominator) return -EINVAL; /* Frame rate is not supported during streaming */ @@ -1135,6 +1218,7 @@ void msm_jpegdma_isr_processing_done(struct msm_jpegdma_device *dma) struct jpegdma_ctx *ctx; mutex_lock(&dma->lock); + ctx = v4l2_m2m_get_curr_priv(dma->m2m_dev); if (ctx) { mutex_lock(&ctx->lock); diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h index adb8b94f098c..98ae6977d896 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h @@ -22,7 +22,7 @@ /* Max number of clocks defined in device tree */ #define MSM_JPEGDMA_MAX_CLK 10 /* Core clock index */ -#define MSM_JPEGDMA_CORE_CLK 0 +#define MSM_JPEGDMA_CORE_CLK "core_clk" /* Max number of regulators defined in device tree */ #define MSM_JPEGDMA_MAX_REGULATOR_NUM 3 /* Max number of planes supported */ @@ -109,6 +109,8 @@ struct msm_jpegdma_size_config { struct msm_jpegdma_size out_size; struct msm_jpegdma_format format; unsigned int fps; + unsigned int in_offset; + unsigned int out_offset; }; /* @@ -262,6 +264,8 @@ struct jpegdma_ctx { struct v4l2_format format_out; struct v4l2_rect crop; struct v4l2_fract timeperframe; + unsigned int in_offset; + unsigned int out_offset; unsigned int config_idx; struct msm_jpegdma_plane_config plane_config[MSM_JPEGDMA_MAX_CONFIGS]; diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c index f3ceaad21bf5..a1b814b5f475 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c @@ -165,6 +165,23 @@ static int msm_jpegdma_hw_get_num_pipes(struct msm_jpegdma_device *dma) return num_pipes; } +/* + * msm_jpegdma_hw_get_clock_index - Get clock index by name + * @dma: Pointer to dma device. + * @clk_name: clock name. + */ +int msm_jpegdma_hw_get_clock_index(struct msm_jpegdma_device *dma, + const char *clk_name) +{ + uint32_t i = 0; + + for (i = 0; i < dma->num_clk; i++) { + if (!strcmp(clk_name, dma->jpeg_clk_info[i].clk_name)) + return i; + } + return -EINVAL; +} + /* * msm_jpegdma_hw_reset - Reset jpeg dma core. * @dma: Pointer to dma device. @@ -782,12 +799,20 @@ static int msm_jpegdma_hw_calc_speed(struct msm_jpegdma_device *dma, u64 height; u64 real_clock; u64 calc_rate; + int core_clk_idx; width = size->in_size.width + size->in_size.left; height = size->in_size.height + size->in_size.top; calc_rate = (width * height * size->format.depth * size->fps) / 16; - real_clock = clk_round_rate(dma->clk[MSM_JPEGDMA_CORE_CLK], calc_rate); + core_clk_idx = msm_jpegdma_hw_get_clock_index(dma, + MSM_JPEGDMA_CORE_CLK); + if (core_clk_idx < 0) { + dev_err(dma->dev, "Can get clock index for dma %s\n", + MSM_JPEGDMA_CORE_CLK); + } + + real_clock = clk_round_rate(dma->clk[core_clk_idx], calc_rate); if (real_clock < 0) { dev_err(dma->dev, "Can not round core clock\n"); return -EINVAL; @@ -817,6 +842,7 @@ static int msm_jpegdma_hw_set_speed(struct msm_jpegdma_device *dma, struct msm_jpegdma_speed new_sp; struct msm_jpegdma_size_config new_size; int ret; + int core_clk_idx; if (dma->active_clock_rate >= speed->core_clock) return 0; @@ -830,7 +856,14 @@ static int msm_jpegdma_hw_set_speed(struct msm_jpegdma_device *dma, return -EINVAL; } - ret = clk_set_rate(dma->clk[MSM_JPEGDMA_CORE_CLK], new_sp.core_clock); + core_clk_idx = msm_jpegdma_hw_get_clock_index(dma, + MSM_JPEGDMA_CORE_CLK); + if (core_clk_idx < 0) { + dev_err(dma->dev, "Can get clock index for dma %s\n", + MSM_JPEGDMA_CORE_CLK); + } + + ret = clk_set_rate(dma->clk[core_clk_idx], new_sp.core_clock); if (ret < 0) { dev_err(dma->dev, "Fail Core clock rate %d\n", ret); return -EINVAL; @@ -1022,13 +1055,20 @@ int msm_jpegdma_hw_set_config(struct msm_jpegdma_device *dma, plane_cfg->plane[0].active_pipes = dma->hw_num_pipes; plane_cfg->plane[0].type = size_cfg->format.planes[0]; msm_jpegdma_hw_calc_config(size_cfg, &plane_cfg->plane[0]); + + in_offset = size_cfg->in_offset; + out_offset = size_cfg->out_offset; + + msm_jpegdma_hw_add_plane_offset(&plane_cfg->plane[0], + in_offset, out_offset); + if (size_cfg->format.num_planes == 1) return 0; - in_offset = size_cfg->in_size.scanline * - size_cfg->in_size.stride; - out_offset = size_cfg->out_size.scanline * - size_cfg->out_size.stride; + in_offset += (size_cfg->in_size.scanline * + size_cfg->in_size.stride); + out_offset += (size_cfg->out_size.scanline * + size_cfg->out_size.stride); memset(&plane_size, 0x00, sizeof(plane_size)); for (i = 1; i < size_cfg->format.num_planes; i++) { @@ -1336,7 +1376,8 @@ int msm_jpegdma_hw_get_qos(struct msm_jpegdma_device *dma) unsigned int cnt; const void *property; - property = of_get_property(dma->dev->of_node, "qcom,qos-regs", &cnt); + property = of_get_property(dma->dev->of_node, + "qcom,qos-reg-settings", &cnt); if (!property || !cnt) { dev_dbg(dma->dev, "Missing qos settings\n"); return 0; @@ -1347,9 +1388,9 @@ int msm_jpegdma_hw_get_qos(struct msm_jpegdma_device *dma) if (!dma->qos_regs) return -ENOMEM; - for (i = 0; i < cnt; i++) { + for (i = 0; i < cnt; i = i + 2) { ret = of_property_read_u32_index(dma->dev->of_node, - "qcom,qos-regs", i, + "qcom,qos-reg-settings", i, &dma->qos_regs[i].reg); if (ret < 0) { dev_err(dma->dev, "can not read qos reg %d\n", i); @@ -1357,7 +1398,7 @@ int msm_jpegdma_hw_get_qos(struct msm_jpegdma_device *dma) } ret = of_property_read_u32_index(dma->dev->of_node, - "qcom,qos-settings", i, + "qcom,qos-reg-settings", i + 1, &dma->qos_regs[i].val); if (ret < 0) { dev_err(dma->dev, "can not read qos setting %d\n", i); @@ -1397,7 +1438,8 @@ int msm_jpegdma_hw_get_vbif(struct msm_jpegdma_device *dma) unsigned int cnt; const void *property; - property = of_get_property(dma->dev->of_node, "qcom,vbif-regs", &cnt); + property = of_get_property(dma->dev->of_node, "qcom,vbif-reg-settings", + &cnt); if (!property || !cnt) { dev_dbg(dma->dev, "Missing vbif settings\n"); return 0; @@ -1408,9 +1450,9 @@ int msm_jpegdma_hw_get_vbif(struct msm_jpegdma_device *dma) if (!dma->vbif_regs) return -ENOMEM; - for (i = 0; i < cnt; i++) { + for (i = 0; i < cnt; i = i + 2) { ret = of_property_read_u32_index(dma->dev->of_node, - "qcom,vbif-regs", i, + "qcom,vbif-reg-settings", i, &dma->vbif_regs[i].reg); if (ret < 0) { dev_err(dma->dev, "can not read vbif reg %d\n", i); @@ -1418,7 +1460,7 @@ int msm_jpegdma_hw_get_vbif(struct msm_jpegdma_device *dma) } ret = of_property_read_u32_index(dma->dev->of_node, - "qcom,vbif-settings", i, + "qcom,vbif-reg-settings", i + 1, &dma->vbif_regs[i].val); if (ret < 0) { dev_err(dma->dev, "can not read vbif setting %d\n", i); @@ -1459,8 +1501,8 @@ int msm_jpegdma_hw_get_prefetch(struct msm_jpegdma_device *dma) unsigned int cnt; const void *property; - property = of_get_property(dma->dev->of_node, "qcom,prefetch-regs", - &cnt); + property = of_get_property(dma->dev->of_node, + "qcom,prefetch-reg-settings", &cnt); if (!property || !cnt) { dev_dbg(dma->dev, "Missing prefetch settings\n"); return 0; @@ -1472,9 +1514,9 @@ int msm_jpegdma_hw_get_prefetch(struct msm_jpegdma_device *dma) if (!dma->prefetch_regs) return -ENOMEM; - for (i = 0; i < cnt; i++) { + for (i = 0; i < cnt; i = i + 2) { ret = of_property_read_u32_index(dma->dev->of_node, - "qcom,prefetch-regs", i, + "qcom,prefetch-reg-settings", i, &dma->prefetch_regs[i].reg); if (ret < 0) { dev_err(dma->dev, "can not read prefetch reg %d\n", i); @@ -1482,7 +1524,7 @@ int msm_jpegdma_hw_get_prefetch(struct msm_jpegdma_device *dma) } ret = of_property_read_u32_index(dma->dev->of_node, - "qcom,prefetch-settings", i, + "qcom,prefetch-reg-settings", i + 1, &dma->prefetch_regs[i].val); if (ret < 0) { dev_err(dma->dev, "can not read prefetch setting %d\n", @@ -1598,6 +1640,9 @@ int msm_jpegdma_hw_get(struct msm_jpegdma_device *dma) msm_jpegdma_hw_config_qos(dma); msm_jpegdma_hw_config_vbif(dma); + msm_camera_register_threaded_irq(dma->pdev, dma->irq, NULL, + msm_jpegdma_hw_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING, + dev_name(&dma->pdev->dev), dma); msm_jpegdma_hw_enable_irq(dma); ret = msm_jpegdma_hw_reset(dma); @@ -1710,6 +1755,7 @@ static int msm_jpegdma_hw_attach_iommu(struct msm_jpegdma_device *dma) static void msm_jpegdma_hw_detach_iommu(struct msm_jpegdma_device *dma) { mutex_lock(&dma->lock); + if (dma->iommu_attached_cnt == 0) { dev_err(dma->dev, "There is no attached device\n"); mutex_unlock(&dma->lock); @@ -1720,6 +1766,7 @@ static void msm_jpegdma_hw_detach_iommu(struct msm_jpegdma_device *dma) cam_smmu_ops(dma->iommu_hndl, CAM_SMMU_DETACH); cam_smmu_destroy_handle(dma->iommu_hndl); } + mutex_unlock(&dma->lock); } diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c index e685d50d1e6c..a0a0737807db 100644 --- a/drivers/media/platform/msm/camera_v2/msm.c +++ b/drivers/media/platform/msm/camera_v2/msm.c @@ -34,7 +34,6 @@ static struct v4l2_device *msm_v4l2_dev; static struct list_head ordered_sd_list; -static struct mutex ordered_sd_mtx; static struct pm_qos_request msm_v4l2_pm_qos_request; @@ -387,11 +386,6 @@ static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev, struct msm_sd_subdev *temp_sd; list_for_each_entry(temp_sd, sd_list, list) { - if (temp_sd == msm_subdev) { - pr_err("%s :Fail to add the same sd %d\n", - __func__, __LINE__); - return; - } if (msm_subdev->close_seq < temp_sd->close_seq) { list_add_tail(&msm_subdev->list, &temp_sd->list); return; @@ -408,9 +402,7 @@ int msm_sd_register(struct msm_sd_subdev *msm_subdev) if (WARN_ON(!msm_v4l2_dev) || WARN_ON(!msm_v4l2_dev->dev)) return -EIO; - mutex_lock(&ordered_sd_mtx); msm_add_sd_in_position(msm_subdev, &ordered_sd_list); - mutex_unlock(&ordered_sd_mtx); return __msm_sd_register_subdev(&msm_subdev->sd); } EXPORT_SYMBOL(msm_sd_register); @@ -731,16 +723,6 @@ static long msm_private_ioctl(struct file *file, void *fh, if (!event_data) return -EINVAL; - switch (cmd) { - case MSM_CAM_V4L2_IOCTL_NOTIFY: - case MSM_CAM_V4L2_IOCTL_CMD_ACK: - case MSM_CAM_V4L2_IOCTL_NOTIFY_DEBUG: - case MSM_CAM_V4L2_IOCTL_NOTIFY_ERROR: - break; - default: - return -ENOTTY; - } - memset(&event, 0, sizeof(struct v4l2_event)); session_id = event_data->session_id; stream_id = event_data->stream_id; @@ -809,13 +791,11 @@ static long msm_private_ioctl(struct file *file, void *fh, __func__); } - mutex_lock(&ordered_sd_mtx); if (!list_empty(&msm_v4l2_dev->subdevs)) { list_for_each_entry(msm_sd, &ordered_sd_list, list) __msm_sd_notify_freeze_subdevs(msm_sd, event_data->status); } - mutex_unlock(&ordered_sd_mtx); } break; @@ -1000,11 +980,9 @@ static int msm_close(struct file *filep) struct msm_sd_subdev *msm_sd; /*stop all hardware blocks immediately*/ - mutex_lock(&ordered_sd_mtx); if (!list_empty(&msm_v4l2_dev->subdevs)) list_for_each_entry(msm_sd, &ordered_sd_list, list) __msm_sd_close_subdevs(msm_sd, &sd_close); - mutex_unlock(&ordered_sd_mtx); /* remove msm_v4l2_pm_qos_request */ msm_pm_qos_remove_request(); @@ -1360,7 +1338,6 @@ static int msm_probe(struct platform_device *pdev) msm_init_queue(msm_session_q); spin_lock_init(&msm_eventq_lock); spin_lock_init(&msm_pid_lock); - mutex_init(&ordered_sd_mtx); INIT_LIST_HEAD(&ordered_sd_list); cam_debugfs_root = debugfs_create_dir(MSM_CAM_LOGSYNC_FILE_BASEDIR, diff --git a/drivers/media/platform/msm/camera_v2/msm.h b/drivers/media/platform/msm/camera_v2/msm.h index fec8ea484884..39797de41cce 100644 --- a/drivers/media/platform/msm/camera_v2/msm.h +++ b/drivers/media/platform/msm/camera_v2/msm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -29,11 +29,11 @@ #include #include -/* Setting MAX timeout to 10seconds considering +/* Setting MAX timeout to 6.5seconds considering * backend will operate @ .6fps in certain usecases * like Long exposure usecase and isp needs max of 2 frames * to stop the hardware which will be around 3 seconds*/ -#define MSM_POST_EVT_TIMEOUT 10000 +#define MSM_POST_EVT_TIMEOUT 6500 #define MSM_POST_EVT_NOTIMEOUT 0xFFFFFFFF #define MSM_CAMERA_STREAM_CNT_BITS 32 diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index 4e03a7eac022..d0b265a78797 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -297,12 +297,11 @@ static void msm_buf_mngr_sd_shutdown(struct msm_buf_mngr_device *dev, if (!list_empty(&dev->buf_qhead)) { list_for_each_entry_safe(bufs, save, &dev->buf_qhead, entry) { + pr_info("%s: Delete invalid bufs =%pK, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n", + __func__, (void *)bufs, session->session, + bufs->session_id, bufs->stream_id, + bufs->index); if (session->session == bufs->session_id) { - pr_info("%s: Delete invalid bufs =%pK, session_id=%u, bufs->ses_id=%d, str_id=%d, idx=%d\n", - __func__, (void *)bufs, - session->session, - bufs->session_id, bufs->stream_id, - bufs->index); list_del_init(&bufs->entry); kfree(bufs); } diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c index 69d3a2ba1cba..a1e37b3c8162 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c @@ -290,6 +290,7 @@ static struct vb2_buffer *msm_vb2_get_buf(int session_id, end: spin_unlock_irqrestore(&stream->stream_lock, flags); read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return vb2_buf; } @@ -336,9 +337,11 @@ static struct vb2_buffer *msm_vb2_get_buf_by_idx(int session_id, end: spin_unlock_irqrestore(&stream->stream_lock, flags); read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return vb2_buf; } + static int msm_vb2_put_buf(struct vb2_buffer *vb, int session_id, unsigned int stream_id) { diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index f98d1ef10d25..6f644d870b2c 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -44,7 +44,7 @@ #define ENABLE_CPP_LOW 0 -#define CPP_CMD_TIMEOUT_MS 50 +#define CPP_CMD_TIMEOUT_MS 300 #define MSM_CPP_INVALID_OFFSET 0x00000000 #define MSM_CPP_NOMINAL_CLOCK 266670000 #define MSM_CPP_TURBO_CLOCK 320000000 @@ -120,8 +120,6 @@ static void msm_cpp_set_micro_irq_mask(struct cpp_device *cpp_dev, static void msm_cpp_flush_queue_and_release_buffer(struct cpp_device *cpp_dev, int queue_len); static int msm_cpp_dump_frame_cmd(struct msm_cpp_frame_info_t *frame_info); -static int msm_cpp_dump_addr(struct cpp_device *cpp_dev, - struct msm_cpp_frame_info_t *frame_info); static int32_t msm_cpp_reset_vbif_and_load_fw(struct cpp_device *cpp_dev); #if CONFIG_MSM_CPP_DBG @@ -665,137 +663,6 @@ static int32_t msm_cpp_poll_rx_empty(void __iomem *cpp_base) return rc; } -static int msm_cpp_dump_addr(struct cpp_device *cpp_dev, - struct msm_cpp_frame_info_t *frame_info) -{ - int32_t s_base, p_base; - uint32_t rd_off, wr0_off, wr1_off, wr2_off, wr3_off; - uint32_t wr0_mdata_off, wr1_mdata_off, wr2_mdata_off, wr3_mdata_off; - uint32_t rd_ref_off, wr_ref_off; - uint32_t s_size, p_size; - uint8_t tnr_enabled, ubwc_enabled, cds_en; - int32_t i = 0; - uint32_t *cpp_frame_msg; - - cpp_frame_msg = frame_info->cpp_cmd_msg; - - /* Update stripe/plane size and base offsets */ - s_base = cpp_dev->payload_params.stripe_base; - s_size = cpp_dev->payload_params.stripe_size; - p_base = cpp_dev->payload_params.plane_base; - p_size = cpp_dev->payload_params.plane_size; - - /* Fetch engine Offset */ - rd_off = cpp_dev->payload_params.rd_pntr_off; - /* Write engine offsets */ - wr0_off = cpp_dev->payload_params.wr_0_pntr_off; - wr1_off = wr0_off + 1; - wr2_off = wr1_off + 1; - wr3_off = wr2_off + 1; - /* Reference engine offsets */ - rd_ref_off = cpp_dev->payload_params.rd_ref_pntr_off; - wr_ref_off = cpp_dev->payload_params.wr_ref_pntr_off; - /* Meta data offsets */ - wr0_mdata_off = - cpp_dev->payload_params.wr_0_meta_data_wr_pntr_off; - wr1_mdata_off = (wr0_mdata_off + 1); - wr2_mdata_off = (wr1_mdata_off + 1); - wr3_mdata_off = (wr2_mdata_off + 1); - - tnr_enabled = ((frame_info->feature_mask & TNR_MASK) >> 2); - ubwc_enabled = ((frame_info->feature_mask & UBWC_MASK) >> 5); - cds_en = ((frame_info->feature_mask & CDS_MASK) >> 6); - - for (i = 0; i < frame_info->num_strips; i++) { - pr_err("stripe %d: in %x, out1 %x out2 %x, out3 %x, out4 %x\n", - i, cpp_frame_msg[s_base + rd_off + i * s_size], - cpp_frame_msg[s_base + wr0_off + i * s_size], - cpp_frame_msg[s_base + wr1_off + i * s_size], - cpp_frame_msg[s_base + wr2_off + i * s_size], - cpp_frame_msg[s_base + wr3_off + i * s_size]); - - if (tnr_enabled) { - pr_err("stripe %d: read_ref %x, write_ref %x\n", i, - cpp_frame_msg[s_base + rd_ref_off + i * s_size], - cpp_frame_msg[s_base + wr_ref_off + i * s_size] - ); - } - - if (cds_en) { - pr_err("stripe %d:, dsdn_off %x\n", i, - cpp_frame_msg[s_base + rd_ref_off + i * s_size] - ); - } - - if (ubwc_enabled) { - pr_err("stripe %d: metadata %x, %x, %x, %x\n", i, - cpp_frame_msg[s_base + wr0_mdata_off + - i * s_size], - cpp_frame_msg[s_base + wr1_mdata_off + - i * s_size], - cpp_frame_msg[s_base + wr2_mdata_off + - i * s_size], - cpp_frame_msg[s_base + wr3_mdata_off + - i * s_size] - ); - } - - } - return 0; -} - -static void msm_cpp_iommu_fault_handler(struct iommu_domain *domain, - struct device *dev, unsigned long iova, int flags, void *token) -{ - struct cpp_device *cpp_dev = NULL; - struct msm_cpp_frame_info_t *processed_frame[MAX_CPP_PROCESSING_FRAME]; - int32_t i = 0, queue_len = 0; - struct msm_device_queue *queue = NULL; - int32_t rc = 0; - - if (token) { - cpp_dev = token; - disable_irq(cpp_dev->irq->start); - if (atomic_read(&cpp_timer.used)) { - atomic_set(&cpp_timer.used, 0); - del_timer_sync(&cpp_timer.cpp_timer); - } - mutex_lock(&cpp_dev->mutex); - tasklet_kill(&cpp_dev->cpp_tasklet); - rc = cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin); - if (rc < 0) { - pr_err("load fw failure %d-retry\n", rc); - rc = msm_cpp_reset_vbif_and_load_fw(cpp_dev); - if (rc < 0) { - msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8); - mutex_unlock(&cpp_dev->mutex); - return; - } - } - queue = &cpp_timer.data.cpp_dev->processing_q; - queue_len = queue->len; - if (!queue_len) { - pr_err("%s:%d: Invalid queuelen\n", __func__, __LINE__); - msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8); - mutex_unlock(&cpp_dev->mutex); - return; - } - for (i = 0; i < queue_len; i++) { - if (cpp_timer.data.processed_frame[i]) { - processed_frame[i] = - cpp_timer.data.processed_frame[i]; - pr_err("Fault on identity=0x%x, frame_id=%03d\n", - processed_frame[i]->identity, - processed_frame[i]->frame_id); - msm_cpp_dump_addr(cpp_dev, processed_frame[i]); - msm_cpp_dump_frame_cmd(processed_frame[i]); - } - } - msm_cpp_flush_queue_and_release_buffer(cpp_dev, queue_len); - msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8); - mutex_unlock(&cpp_dev->mutex); - } -} static int cpp_init_mem(struct cpp_device *cpp_dev) { @@ -812,9 +679,6 @@ static int cpp_init_mem(struct cpp_device *cpp_dev) return -ENODEV; cpp_dev->iommu_hdl = iommu_hdl; - cam_smmu_reg_client_page_fault_handler( - cpp_dev->iommu_hdl, - msm_cpp_iommu_fault_handler, cpp_dev); return 0; } @@ -4319,7 +4183,7 @@ static int cpp_probe(struct platform_device *pdev) cpp_dev->state = CPP_STATE_BOOT; rc = cpp_init_hardware(cpp_dev); if (rc < 0) - goto bus_de_init; + goto cpp_probe_init_error; media_entity_init(&cpp_dev->msm_sd.sd.entity, 0, NULL, 0); cpp_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; @@ -4358,7 +4222,7 @@ static int cpp_probe(struct platform_device *pdev) if (!cpp_dev->work) { pr_err("no enough memory\n"); rc = -ENOMEM; - goto bus_de_init; + goto cpp_probe_init_error; } INIT_WORK((struct work_struct *)cpp_dev->work, msm_cpp_do_timeout_work); @@ -4378,12 +4242,6 @@ static int cpp_probe(struct platform_device *pdev) else CPP_DBG("FAILED."); return rc; - -bus_de_init: - if (cpp_dev->bus_master_flag) - msm_cpp_deinit_bandwidth_mgr(cpp_dev); - else - msm_isp_deinit_bandwidth_mgr(ISP_CPP); cpp_probe_init_error: media_entity_cleanup(&cpp_dev->msm_sd.sd.entity); msm_sd_unregister(&cpp_dev->msm_sd); diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c index d7fb2449582c..f2f1dca81f18 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c +++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1054,16 +1054,10 @@ static int vpe_reset(struct vpe_device *vpe_dev) return rc; } -static int vpe_update_scale_coef(struct vpe_device *vpe_dev, uint32_t *p) +static void vpe_update_scale_coef(struct vpe_device *vpe_dev, uint32_t *p) { uint32_t i, offset; offset = *p; - - if (offset > VPE_SCALE_COEFF_MAX_N-VPE_SCALE_COEFF_NUM) { - pr_err("%s: invalid offset %d passed in", __func__, offset); - return -EINVAL; - } - for (i = offset; i < (VPE_SCALE_COEFF_NUM + offset); i++) { VPE_DBG("Setting scale table %d\n", i); msm_camera_io_w(*(++p), @@ -1071,8 +1065,6 @@ static int vpe_update_scale_coef(struct vpe_device *vpe_dev, uint32_t *p) msm_camera_io_w(*(++p), vpe_dev->base + VPE_SCALE_COEFF_MSBn(i)); } - - return 0; } static void vpe_input_plane_config(struct vpe_device *vpe_dev, uint32_t *p) @@ -1110,16 +1102,13 @@ static void vpe_operation_config(struct vpe_device *vpe_dev, uint32_t *p) */ static void msm_vpe_transaction_setup(struct vpe_device *vpe_dev, void *data) { - int i, rc = 0; + int i; void *iter = data; vpe_mem_dump("vpe_transaction", data, VPE_TRANSACTION_SETUP_CONFIG_LEN); for (i = 0; i < VPE_NUM_SCALER_TABLES; ++i) { - rc = vpe_update_scale_coef(vpe_dev, (uint32_t *)iter); - if (rc != 0) - return; - + vpe_update_scale_coef(vpe_dev, (uint32_t *)iter); iter += VPE_SCALER_CONFIG_LEN; } vpe_input_plane_config(vpe_dev, (uint32_t *)iter); diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.h b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.h index 0c55ff70309e..f1869a2b9776 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.h +++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -70,7 +70,6 @@ #define VPE_SCALE_COEFF_LSBn(n) (0x50400 + 8 * (n)) #define VPE_SCALE_COEFF_MSBn(n) (0x50404 + 8 * (n)) #define VPE_SCALE_COEFF_NUM 32 -#define VPE_SCALE_COEFF_MAX_N 127 /*********** end of register offset ********************/ diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c old mode 100644 new mode 100755 index 39cdae9dad15..f3a2fe034872 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -1940,16 +1940,15 @@ static int32_t msm_actuator_platform_probe(struct platform_device *pdev) } rc = msm_sensor_driver_get_gpio_data(&(msm_actuator_t->gconf), (&pdev->dev)->of_node); - if (-ENODEV == rc) { - pr_notice("No valid actuator GPIOs data\n"); - } else if (rc < 0) { - pr_err("Error Actuator GPIOs\n"); + if (rc < 0) { + pr_err("%s: No/Error Actuator GPIOs\n", __func__); } else { msm_actuator_t->cam_pinctrl_status = 1; rc = msm_camera_pinctrl_init( &(msm_actuator_t->pinctrl_info), &(pdev->dev)); if (rc < 0) { - pr_err("ERR: Error in reading actuator pinctrl\n"); + pr_err("ERR:%s: Error in reading actuator pinctrl\n", + __func__); msm_actuator_t->cam_pinctrl_status = 0; } } diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index 859a7c3c6426..7a9977d9409b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1330,10 +1330,6 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, CDBG("%s:%d master %d\n", __func__, __LINE__, master); if (master < MASTER_MAX && master >= 0) { mutex_lock(&cci_dev->cci_master_info[master].mutex); - mutex_lock(&cci_dev->cci_master_info[master]. - mutex_q[PRIORITY_QUEUE]); - mutex_lock(&cci_dev->cci_master_info[master]. - mutex_q[SYNC_QUEUE]); flush_workqueue(cci_dev->write_wq[master]); /* Re-initialize the completion */ reinit_completion(&cci_dev-> @@ -1358,10 +1354,6 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd, if (rc <= 0) pr_err("%s:%d wait failed %d\n", __func__, __LINE__, rc); - mutex_unlock(&cci_dev->cci_master_info[master]. - mutex_q[SYNC_QUEUE]); - mutex_unlock(&cci_dev->cci_master_info[master]. - mutex_q[PRIORITY_QUEUE]); mutex_unlock(&cci_dev->cci_master_info[master].mutex); } return 0; diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c index a89f33208e7b..bcac5592c193 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c @@ -305,7 +305,7 @@ static int msm_csid_config(struct csid_device *csid_dev, if (!msm_csid_find_max_clk_rate(csid_dev)) pr_err("msm_csid_find_max_clk_rate failed\n"); - clk_rate = ((int)csid_params->csi_clk > 0) ? + clk_rate = (csid_params->csi_clk > 0) ? (csid_params->csi_clk) : csid_dev->csid_max_clk; clk_rate = msm_camera_clk_set_rate(&csid_dev->pdev->dev, diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c index 91c69263090d..d1bb9af3d8da 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c @@ -483,7 +483,7 @@ static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev, return rc; } - clk_rate = ((int)csiphy_params->csiphy_clk > 0) + clk_rate = (csiphy_params->csiphy_clk > 0) ? csiphy_params->csiphy_clk : csiphy_dev->csiphy_max_clk; clk_rate = msm_camera_clk_set_rate(&csiphy_dev->pdev->dev, @@ -1209,7 +1209,6 @@ static int32_t msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg) break; } csiphy_dev->csiphy_sof_debug = SOF_DEBUG_DISABLE; - csiphy_dev->is_combo_mode = csiphy_params.combo_mode; rc = msm_csiphy_lane_config(csiphy_dev, &csiphy_params); break; case CSIPHY_RELEASE: @@ -1220,14 +1219,7 @@ static int32_t msm_csiphy_cmd(struct csiphy_device *csiphy_dev, void *arg) rc = -EFAULT; break; } - if ((csiphy_dev->is_combo_mode == 1) && - (csiphy_dev->ref_count == 2)) { - /*CSIPHY is running in Combo mode do - not power down core*/ - csiphy_dev->ref_count--; - } else { - rc = msm_csiphy_release(csiphy_dev, &csi_lane_params); - } + rc = msm_csiphy_release(csiphy_dev, &csi_lane_params); break; default: pr_err("%s: %d failed\n", __func__, __LINE__); @@ -1337,7 +1329,7 @@ static const struct v4l2_subdev_ops msm_csiphy_subdev_ops = { static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, struct platform_device *pdev) { - int i, rc = 0; + int i, rc; char *csi_3p_clk_name = "csi_phy_3p_clk"; char *csi_3p_clk_src_name = "csiphy_3p_clk_src"; uint32_t clk_cnt = 0; @@ -1353,7 +1345,6 @@ static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, if (csiphy_dev->num_all_clk > CSIPHY_NUM_CLK_MAX) { pr_err("%s: invalid count=%zu, max is %d\n", __func__, csiphy_dev->num_all_clk, CSIPHY_NUM_CLK_MAX); - rc = -EINVAL; goto MAX_CLK_ERROR; } @@ -1397,14 +1388,13 @@ static int msm_csiphy_get_clk_info(struct csiphy_device *csiphy_dev, } csiphy_dev->num_clk = clk_cnt; - return rc; MAX_CLK_ERROR: msm_camera_put_clk_info(csiphy_dev->pdev, &csiphy_dev->csiphy_all_clk_info, &csiphy_dev->csiphy_all_clk, csiphy_dev->num_all_clk); - return rc; + return 0; } static int csiphy_probe(struct platform_device *pdev) diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h index eb2310583955..07a08110885b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h +++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.h @@ -169,7 +169,6 @@ struct csiphy_device { uint8_t num_irq_registers; uint32_t csiphy_sof_debug; uint32_t csiphy_sof_debug_count; - uint32_t is_combo_mode; struct camera_vreg_t *csiphy_vreg; struct regulator *csiphy_reg_ptr[MAX_REGULATOR]; int32_t regulator_count; diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c index 88d99fd7fd6a..680e7d946a2b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c @@ -152,7 +152,7 @@ static int32_t msm_flash_i2c_write_table( conf_array.size = settings->size; /* Validate the settings size */ - if ((!conf_array.size) || (conf_array.size > MAX_I2C_REG_SET)) { + if((!conf_array.size) || (conf_array.size > MAX_I2C_REG_SET)) { pr_err("failed: invalid size %d", conf_array.size); return -EINVAL; } @@ -515,8 +515,7 @@ static int32_t msm_flash_init_prepare( struct msm_flash_cfg_data_t flash_data_k; struct msm_flash_init_info_t flash_init_info; int32_t i = 0; - - if (!is_compat_task()) { + if(!is_compat_task()) { /*for 64-bit usecase,it need copy the data to local memory*/ flash_data_k.cfg_type = flash_data->cfg_type; for (i = 0; i < MAX_LED_TRIGGERS; i++) { @@ -528,7 +527,7 @@ static int32_t msm_flash_init_prepare( flash_data_k.cfg.flash_init_info = &flash_init_info; if (copy_from_user(&flash_init_info, - (void __user *)(flash_data->cfg.flash_init_info), + (void *)(flash_data->cfg.flash_init_info), sizeof(struct msm_flash_init_info_t))) { pr_err("%s copy_from_user failed %d\n", __func__, __LINE__); @@ -556,7 +555,7 @@ static int32_t msm_flash_init_prepare( flash_data_k.cfg.flash_init_info = &flash_init_info; if (copy_from_user(&flash_init_info, - (void __user *)(flash_data->cfg.flash_init_info), + (void *)(flash_data->cfg.flash_init_info), sizeof(struct msm_flash_init_info_t))) { pr_err("%s copy_from_user failed %d\n", __func__, __LINE__); @@ -643,6 +642,11 @@ static int32_t msm_flash_release( struct msm_flash_ctrl_t *flash_ctrl) { int32_t rc = 0; + if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_RELEASE) { + pr_err("%s:%d Invalid flash state = %d", + __func__, __LINE__, flash_ctrl->flash_state); + return 0; + } rc = flash_ctrl->func_tbl->camera_flash_off(flash_ctrl, NULL); if (rc < 0) { @@ -670,49 +674,24 @@ static int32_t msm_flash_config(struct msm_flash_ctrl_t *flash_ctrl, rc = msm_flash_init_prepare(flash_ctrl, flash_data); break; case CFG_FLASH_RELEASE: - if (flash_ctrl->flash_state != MSM_CAMERA_FLASH_RELEASE) { + if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT) rc = flash_ctrl->func_tbl->camera_flash_release( flash_ctrl); - } else { - CDBG(pr_fmt("Invalid state : %d\n"), - flash_ctrl->flash_state); - } break; case CFG_FLASH_OFF: - if ((flash_ctrl->flash_state != MSM_CAMERA_FLASH_RELEASE) && - (flash_ctrl->flash_state != MSM_CAMERA_FLASH_OFF)) { + if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT) rc = flash_ctrl->func_tbl->camera_flash_off( flash_ctrl, flash_data); - if (!rc) - flash_ctrl->flash_state = MSM_CAMERA_FLASH_OFF; - } else { - CDBG(pr_fmt("Invalid state : %d\n"), - flash_ctrl->flash_state); - } break; case CFG_FLASH_LOW: - if ((flash_ctrl->flash_state == MSM_CAMERA_FLASH_OFF) || - (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT)) { + if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT) rc = flash_ctrl->func_tbl->camera_flash_low( flash_ctrl, flash_data); - if (!rc) - flash_ctrl->flash_state = MSM_CAMERA_FLASH_LOW; - } else { - CDBG(pr_fmt("Invalid state : %d\n"), - flash_ctrl->flash_state); - } break; case CFG_FLASH_HIGH: - if ((flash_ctrl->flash_state == MSM_CAMERA_FLASH_OFF) || - (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT)) { + if (flash_ctrl->flash_state == MSM_CAMERA_FLASH_INIT) rc = flash_ctrl->func_tbl->camera_flash_high( flash_ctrl, flash_data); - if (!rc) - flash_ctrl->flash_state = MSM_CAMERA_FLASH_HIGH; - } else { - CDBG(pr_fmt("Invalid state : %d\n"), - flash_ctrl->flash_state); - } break; default: rc = -EFAULT; @@ -1011,11 +990,9 @@ static int32_t msm_flash_get_dt_data(struct device_node *of_node, /* Read the gpio information from device tree */ rc = msm_sensor_driver_get_gpio_data( &(fctrl->power_info.gpio_conf), of_node); - if (-ENODEV == rc) { - pr_notice("No valid flash GPIOs data\n"); - rc = 0; - } else if (rc < 0) { - pr_err("Error flash GPIOs rc %d\n", rc); + if (rc < 0) { + pr_err("%s:%d msm_sensor_driver_get_gpio_data failed rc %d\n", + __func__, __LINE__, rc); return rc; } diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h index d21f81bbc48a..c82e48cddcaf 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h +++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2009-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -27,9 +27,6 @@ enum msm_camera_flash_state_t { MSM_CAMERA_FLASH_INIT, - MSM_CAMERA_FLASH_OFF, - MSM_CAMERA_FLASH_LOW, - MSM_CAMERA_FLASH_HIGH, MSM_CAMERA_FLASH_RELEASE, }; diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile index 549c35a806f7..ec958697ae13 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/Makefile +++ b/drivers/media/platform/msm/camera_v2/sensor/io/Makefile @@ -2,5 +2,4 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2/ ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci -ccflags-y += -Idrivers/misc/ -obj-$(CONFIG_MSMB_CAMERA) += msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_spi.o msm_camera_dt_util.o msm_camera_tz_i2c.o +obj-$(CONFIG_MSMB_CAMERA) += msm_camera_cci_i2c.o msm_camera_qup_i2c.o msm_camera_spi.o msm_camera_dt_util.o diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index bca16dc85443..27d4f5e78cc8 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -17,15 +17,13 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) #define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args) -#define MAX_I2C_ADDR_TYPE_SIZE (MSM_CAMERA_I2C_3B_ADDR + 1) -#define MAX_I2C_DATA_TYPE_SIZE (MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA + 1) int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t *data, enum msm_camera_i2c_data_type data_type) { int32_t rc = -EFAULT; - unsigned char buf[MAX_I2C_ADDR_TYPE_SIZE + MAX_I2C_DATA_TYPE_SIZE]; + unsigned char buf[client->addr_type+data_type]; struct msm_camera_cci_ctrl cci_ctrl; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR @@ -72,8 +70,8 @@ int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client, return rc; if (num_byte > I2C_REG_DATA_MAX) { - S_I2C_DBG("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", - __func__, num_byte, I2C_REG_DATA_MAX); + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); return rc; } diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c index b0fd8277e203..8b2db504295e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c @@ -217,10 +217,7 @@ int msm_sensor_get_sub_module_index(struct device_node *of_node, pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR; } - if (of_device_is_available(src_node)) - sensor_info->subdev_id[SUB_MODULE_ACTUATOR] = val; - else - CDBG("%s:%d actuator disabled!\n", __func__, __LINE__); + sensor_info->subdev_id[SUB_MODULE_ACTUATOR] = val; of_node_put(src_node); src_node = NULL; } @@ -1371,7 +1368,7 @@ int32_t msm_sensor_driver_get_gpio_data( gpio_array_size = of_gpio_count(of_node); CDBG("gpio count %d\n", gpio_array_size); if (gpio_array_size <= 0) - return -ENODEV; + return 0; gconf = kzalloc(sizeof(struct msm_camera_gpio_conf), GFP_KERNEL); diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h index 785dd54d65e1..0fbe35713d8e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_i2c.h @@ -152,60 +152,4 @@ int32_t msm_camera_qup_i2c_poll(struct msm_camera_i2c_client *client, uint32_t addr, uint16_t data, enum msm_camera_i2c_data_type data_type, uint32_t delay_ms); -int32_t msm_camera_tz_i2c_register_sensor(void *s_ctrl_p); - -int32_t msm_camera_tz_i2c_power_up(struct msm_camera_i2c_client *client); - -int32_t msm_camera_tz_i2c_power_down(struct msm_camera_i2c_client *client); - -int32_t msm_camera_tz_i2c_read(struct msm_camera_i2c_client *client, - uint32_t addr, uint16_t *data, - enum msm_camera_i2c_data_type data_type); - -int32_t msm_camera_tz_i2c_read_seq(struct msm_camera_i2c_client *client, - uint32_t addr, uint8_t *data, uint32_t num_byte); - -int32_t msm_camera_tz_i2c_write(struct msm_camera_i2c_client *client, - uint32_t addr, uint16_t data, - enum msm_camera_i2c_data_type data_type); - -int32_t msm_camera_tz_i2c_write_seq(struct msm_camera_i2c_client *client, - uint32_t addr, uint8_t *data, uint32_t num_byte); - -int32_t msm_camera_tz_i2c_write_table( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting); - -int32_t msm_camera_tz_i2c_write_table_async( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting); - -int32_t msm_camera_tz_i2c_write_table_sync( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting); - -int32_t msm_camera_tz_i2c_write_table_sync_block( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting); - -int32_t msm_camera_tz_i2c_write_seq_table( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_seq_reg_setting *write_setting); - -int32_t msm_camera_tz_i2c_write_table_w_microdelay( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting); - -int32_t msm_camera_tz_i2c_write_conf_tbl( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size, - enum msm_camera_i2c_data_type data_type); - -int32_t msm_sensor_tz_i2c_util(struct msm_camera_i2c_client *client, - uint16_t cci_cmd); - -int32_t msm_camera_tz_i2c_poll(struct msm_camera_i2c_client *client, - uint32_t addr, uint16_t data, - enum msm_camera_i2c_data_type data_type); - #endif diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c index 8c12c7604ce2..7d218662215e 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -82,14 +82,14 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, return rc; if (client->addr_type > UINT_MAX - data_type) { - S_I2C_DBG("%s: integer overflow prevented\n", __func__); - return rc; + pr_err("%s: integer overflow prevented\n", __func__); + return rc; } buf = kzalloc(client->addr_type+data_type, GFP_KERNEL); if (!buf) { - S_I2C_DBG("%s:%d no memory\n", __func__, __LINE__); - return -ENOMEM; + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; } if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { @@ -130,19 +130,19 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, return rc; if (num_byte > I2C_REG_DATA_MAX) { - S_I2C_DBG("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", - __func__, num_byte, I2C_REG_DATA_MAX); - return rc; + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); + return rc; } if (client->addr_type > UINT_MAX - num_byte) { - S_I2C_DBG("%s: integer overflow prevented\n", __func__); - return rc; + pr_err("%s: integer overflow prevented\n", __func__); + return rc; } buf = kzalloc(client->addr_type+num_byte, GFP_KERNEL); if (!buf) { - S_I2C_DBG("%s:%d no memory\n", __func__, __LINE__); - return -ENOMEM; + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; } if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { @@ -269,7 +269,6 @@ int32_t msm_camera_qup_i2c_write_table(struct msm_camera_i2c_client *client, int32_t rc = -EFAULT; struct msm_camera_i2c_reg_array *reg_setting; uint16_t client_addr_type; - int retry = 0; if (!client || !write_setting) return rc; @@ -287,20 +286,11 @@ int32_t msm_camera_qup_i2c_write_table(struct msm_camera_i2c_client *client, for (i = 0; i < write_setting->size; i++) { CDBG("%s addr 0x%x data 0x%x\n", __func__, reg_setting->reg_addr, reg_setting->reg_data); - do { - rc = msm_camera_qup_i2c_write(client, - reg_setting->reg_addr, reg_setting->reg_data, - write_setting->data_type); - if (rc >= 0) - break; - } while (retry++ < 2); - if (rc < 0) { - pr_err("FAILED: %s addr 0x%x data 0x%x\n", __func__, - reg_setting->reg_addr, reg_setting->reg_data); + rc = msm_camera_qup_i2c_write(client, reg_setting->reg_addr, + reg_setting->reg_data, write_setting->data_type); + if (rc < 0) break; - } - retry = 0; reg_setting++; } if (write_setting->delay > 20) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c deleted file mode 100644 index 5a330db0f9a5..000000000000 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_tz_i2c.c +++ /dev/null @@ -1,1093 +0,0 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "qseecom_kernel.h" -#include "msm_camera_i2c.h" -#include "msm_camera_io_util.h" -#include "msm_cci.h" -#include "msm_sensor.h" - -#define QSEECOM_SBUFF_SIZE SZ_128K -#define MAX_TA_NAME 32 -#define EMPTY_QSEECOM_HANDLE NULL - -#ifndef CONFIG_MSM_SEC_CCI_TA_NAME - #define CONFIG_MSM_SEC_CCI_TA_NAME "seccamdemo64" -#endif /* CONFIG_MSM_SEC_CCI_TA_NAME */ - -/* Update version major number in case the HLOS-TA interface is changed*/ -#define TA_IF_VERSION_MAJ 0 -#define TA_IF_VERSION_MIN 1 - -#undef CDBG -#ifdef CONFIG_MSM_SEC_CCI_DEBUG - -#define CDBG(fmt, args...) pr_info(CONFIG_MSM_SEC_CCI_TA_NAME "::%s:%d - " fmt,\ - __func__, __LINE__, ##args) -#define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \ - ((ret < 0) ? i2c_fn(__VA_ARGS__):ret) - -#else /* CONFIG_MSM_SEC_CCI_DEBUG */ - -#define CDBG(fmt, args...) pr_info("%s:%d - " fmt, __func__, __LINE__, ##args) -#define TZ_I2C_FN_RETURN(ret, i2c_fn, ...) \ - ((ret < 0) ? -EFAULT:ret) - -#endif /* CONFIG_MSM_SEC_CCI_DEBUG */ - -#pragma pack(push, msm_camera_tz_i2c, 1) - -enum msm_camera_tz_i2c_cmd_id_t { - TZ_I2C_CMD_GET_NONE, - TZ_I2C_CMD_GET_IF_VERSION, - TZ_I2C_CMD_POWER_UP, - TZ_I2C_CMD_POWER_DOWN, - TZ_I2C_CMD_CCI_GENERIC, - TZ_I2C_CMD_CCI_READ, - TZ_I2C_CMD_CCI_READ_SEQ, - TZ_I2C_CMD_CCI_WRITE, - TZ_I2C_CMD_CCI_WRITE_SEQ, - TZ_I2C_CMD_CCI_WRITE_TABLE_ASYNC, - TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC, - TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC_BLOCK, - TZ_I2C_CMD_CCI_WRITE_TABLE, - TZ_I2C_CMD_CCI_WRITE_SEQ_TABLE, - TZ_I2C_CMD_CCI_WRITE_TABLE_W_MICRODELAY, - TZ_I2C_CMD_CCI_POLL, - TZ_I2C_CMD_CCI_WRITE_CONF_TBL, - TZ_I2C_CMD_CCI_UTIL, -}; - -enum msm_camera_tz_i2c_status_t { - TZ_I2C_STATUS_SUCCESS = 0, - TZ_I2C_STATUS_GENERAL_FAILURE = -1, - TZ_I2C_STATUS_INVALID_INPUT_PARAMS = -2, - TZ_I2C_STATUS_INVALID_SENSOR_ID = -3, - TZ_I2C_STATUS_BYPASS = -4, - TZ_I2C_STATUS_ERR_SIZE = 0x7FFFFFFF -}; - -struct msm_camera_tz_i2c_generic_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; -}; - -struct msm_camera_tz_i2c_generic_rsp_t { - enum msm_camera_tz_i2c_status_t rc; -}; - -#define msm_camera_tz_i2c_get_if_version_req_t msm_camera_tz_i2c_generic_req_t - -struct msm_camera_tz_i2c_get_if_version_rsp_t { - enum msm_camera_tz_i2c_status_t rc; - uint32_t if_version_maj; - uint32_t if_version_min; -}; - -struct msm_camera_tz_i2c_power_up_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; - int32_t sensor_id; -}; - -#define msm_camera_tz_i2c_power_up_rsp_t msm_camera_tz_i2c_generic_rsp_t - -struct msm_camera_tz_i2c_power_down_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; - int32_t sensor_id; -}; - -#define msm_camera_tz_i2c_power_down_rsp_t msm_camera_tz_i2c_generic_rsp_t - -struct msm_camera_tz_i2c_cci_generic_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; - int32_t sensor_id; - enum msm_camera_tz_i2c_cmd_id_t cci_cmd_id; - uint32_t cci_i2c_master; - uint16_t sid; - uint16_t cid; -}; - -#define msm_camera_tz_i2c_cci_generic_rsp_t msm_camera_tz_i2c_generic_rsp_t - -struct msm_camera_tz_i2c_cci_read_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; - int32_t sensor_id; - uint32_t cci_i2c_master; - uint16_t sid; - uint16_t cid; - uint32_t addr; - uint32_t data_type; -}; - -struct msm_camera_tz_i2c_cci_read_rsp_t { - enum msm_camera_tz_i2c_status_t rc; - uint16_t data; -}; - -struct msm_camera_tz_i2c_cci_write_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; - int32_t sensor_id; - uint32_t cci_i2c_master; - uint16_t sid; - uint16_t cid; - uint32_t addr; - uint16_t data; - uint32_t data_type; -}; - -#define msm_camera_tz_i2c_cci_write_rsp_t msm_camera_tz_i2c_generic_rsp_t - -struct msm_camera_tz_i2c_cci_util_req_t { - enum msm_camera_tz_i2c_cmd_id_t cmd_id; - int32_t sensor_id; - uint32_t cci_i2c_master; - uint16_t sid; - uint16_t cid; - uint16_t cci_cmd; -}; - -#define msm_camera_tz_i2c_cci_util_rsp_t msm_camera_tz_i2c_generic_rsp_t - -#pragma pack(pop, msm_camera_tz_i2c) - -struct msm_camera_tz_i2c_sensor_info_t { - struct msm_sensor_ctrl_t *s_ctrl; - struct msm_camera_i2c_fn_t *saved_sensor_i2c_fn; - uint32_t secure; - uint32_t ta_enabled; - struct qseecom_handle *ta_qseecom_handle; - const char *ta_name; -}; - -struct msm_camera_tz_i2c_ctrl_t { - struct mutex lock; - uint32_t lock_ready; - uint32_t secure_mode; -}; - -static struct msm_camera_tz_i2c_ctrl_t msm_camera_tz_i2c_ctrl; - -static struct msm_camera_tz_i2c_sensor_info_t sensor_info[MAX_CAMERAS] = { - {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME}, - {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME}, - {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME}, - {NULL, NULL, 0, 0, NULL, CONFIG_MSM_SEC_CCI_TA_NAME}, -}; - -static int32_t msm_camera_tz_i2c_is_sensor_secure( - struct msm_camera_i2c_client *client) -{ - uint32_t index; - - if (client == NULL) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - CDBG("Enter\n"); - for (index = 0; index < MAX_CAMERAS; index++) { - if ((sensor_info[index].s_ctrl != NULL) && - sensor_info[index].secure && - (sensor_info[index].s_ctrl->sensor_i2c_client == - client)) { - CDBG("Found secure sensor ID = %d\n", - sensor_info[index].s_ctrl->id); - return sensor_info[index].s_ctrl->id; - } - } - return -EINVAL; -} - -static int32_t get_cmd_rsp_buffers( - struct qseecom_handle *ta_qseecom_handle, - void **cmd, int *cmd_len, - void **rsp, int *rsp_len) -{ - - CDBG("Enter\n"); - if ((ta_qseecom_handle == NULL) || - (cmd == NULL) || (cmd_len == NULL) || - (rsp == NULL) || (rsp_len == NULL)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - if (*cmd_len & QSEECOM_ALIGN_MASK) - *cmd_len = QSEECOM_ALIGN(*cmd_len); - - if (*rsp_len & QSEECOM_ALIGN_MASK) - *rsp_len = QSEECOM_ALIGN(*rsp_len); - - if ((*rsp_len + *cmd_len) > QSEECOM_SBUFF_SIZE) { - pr_err("%s:%d - Shared buffer too small to hold cmd=%d and rsp=%d\n", - __func__, __LINE__, - *cmd_len, *rsp_len); - return -ENOMEM; - } - - *cmd = ta_qseecom_handle->sbuf; - *rsp = ta_qseecom_handle->sbuf + *cmd_len; - return 0; -} - -static int32_t msm_camera_tz_i2c_ta_get_if_version( - struct qseecom_handle *ta_qseecom_handle, - uint32_t *if_version_maj, - uint32_t *if_version_min) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_get_if_version_req_t *cmd; - struct msm_camera_tz_i2c_get_if_version_rsp_t *rsp; - int32_t rc = 0; - - CDBG("Enter\n"); - if ((ta_qseecom_handle == NULL) || - (if_version_maj == NULL) || (if_version_min == NULL)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - cmd_len = sizeof(struct msm_camera_tz_i2c_get_if_version_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_get_if_version_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_GET_IF_VERSION; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Unable to get if version info, rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - - if (rsp->rc < 0) { - CDBG("TZ I2C App error, rc=%d\n", rsp->rc); - rc = -EFAULT; - } else { - *if_version_maj = rsp->if_version_maj; - *if_version_min = rsp->if_version_min; - CDBG("TZ I2C If version %d.%d\n", *if_version_maj, - *if_version_min); - } - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_power_up( - struct qseecom_handle *ta_qseecom_handle, - int32_t sensor_id, - uint32_t *sensor_secure) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_power_up_req_t *cmd; - struct msm_camera_tz_i2c_power_up_rsp_t *rsp; - int32_t rc = 0; - - CDBG("Enter\n"); - - if (sensor_secure == NULL) - return -EINVAL; - - *sensor_secure = 0; - if ((ta_qseecom_handle == NULL) || - (sensor_secure == NULL) || - (sensor_id < 0) || - (sensor_id >= MAX_CAMERAS)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - cmd_len = sizeof(struct msm_camera_tz_i2c_power_up_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_power_up_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_POWER_UP; - cmd->sensor_id = sensor_id; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Unable to get sensor secure status, rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - - if (rsp->rc == TZ_I2C_STATUS_SUCCESS) - *sensor_secure = 1; - CDBG("Sensor %d is %s\n", sensor_id, - (*sensor_secure)?"SECURE":"NON-SECURE"); - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_power_down( - struct qseecom_handle *ta_qseecom_handle, - int32_t sensor_id) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_power_down_req_t *cmd; - struct msm_camera_tz_i2c_power_down_rsp_t *rsp; - int32_t rc = 0; - - CDBG("Enter\n"); - - if ((ta_qseecom_handle == NULL) || - (sensor_id < 0) || - (sensor_id >= MAX_CAMERAS)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - cmd_len = sizeof(struct msm_camera_tz_i2c_power_down_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_power_down_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_POWER_DOWN; - cmd->sensor_id = sensor_id; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Failed: rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_cci_generic( - struct msm_camera_i2c_client *client, - enum msm_camera_tz_i2c_cmd_id_t cci_cmd_id) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_cci_generic_req_t *cmd; - struct msm_camera_tz_i2c_cci_generic_rsp_t *rsp; - int32_t rc = 0; - struct qseecom_handle *ta_qseecom_handle; - int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - - if ((client == NULL) || - (sensor_id < 0) || - (sensor_id >= MAX_CAMERAS)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, cci_cmd_id=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - cci_cmd_id); - - ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle; - cmd_len = sizeof(struct msm_camera_tz_i2c_cci_generic_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_cci_generic_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_CCI_GENERIC; - cmd->sensor_id = sensor_id; - cmd->cci_cmd_id = cci_cmd_id; - cmd->cci_i2c_master = client->cci_client->cci_i2c_master; - cmd->sid = client->cci_client->sid; - cmd->cid = client->cci_client->cid; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Failed: rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - rc = rsp->rc; - CDBG("Done: rc=%d, cci_cmd_id=%d\n", rc, cci_cmd_id); - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_cci_read( - struct msm_camera_i2c_client *client, - uint32_t addr, - uint16_t *data, - enum msm_camera_i2c_data_type data_type) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_cci_read_req_t *cmd; - struct msm_camera_tz_i2c_cci_read_rsp_t *rsp; - int32_t rc = 0; - struct qseecom_handle *ta_qseecom_handle; - int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - - if ((client == NULL) || - (data == NULL) || - (sensor_id < 0) || - (sensor_id >= MAX_CAMERAS)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, Addr=0x%X, Type=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - addr, - data_type); - - ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle; - cmd_len = sizeof(struct msm_camera_tz_i2c_cci_read_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_cci_read_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_CCI_READ; - cmd->sensor_id = sensor_id; - cmd->cci_i2c_master = client->cci_client->cci_i2c_master; - cmd->sid = client->cci_client->sid; - cmd->cid = client->cci_client->cid; - cmd->addr = addr; - cmd->data_type = data_type; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Failed: rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - rc = rsp->rc; - *data = rsp->data; - - CDBG("Done: rc=%d, addr=0x%X, data=0x%X\n", rc, - addr, *data); - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_cci_write( - struct msm_camera_i2c_client *client, - uint32_t addr, - uint16_t data, - enum msm_camera_i2c_data_type data_type) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_cci_write_req_t *cmd; - struct msm_camera_tz_i2c_cci_write_rsp_t *rsp; - int32_t rc = 0; - struct qseecom_handle *ta_qseecom_handle; - int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - - if ((client == NULL) || - (sensor_id < 0) || - (sensor_id >= MAX_CAMERAS)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, Addr=0x%X, Data=0x%X Type=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - addr, - data, - data_type); - - ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle; - cmd_len = sizeof(struct msm_camera_tz_i2c_cci_write_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_cci_write_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_CCI_WRITE; - cmd->sensor_id = sensor_id; - cmd->cci_i2c_master = client->cci_client->cci_i2c_master; - cmd->sid = client->cci_client->sid; - cmd->cid = client->cci_client->cid; - cmd->addr = addr; - cmd->data = data; - cmd->data_type = data_type; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Failed:, rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - rc = rsp->rc; - - CDBG("Done: rc=%d, addr=0x%X, data=0x%X\n", rc, - addr, data); - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_cci_util( - struct msm_camera_i2c_client *client, - uint16_t cci_cmd) -{ - int32_t cmd_len, rsp_len; - struct msm_camera_tz_i2c_cci_util_req_t *cmd; - struct msm_camera_tz_i2c_cci_util_rsp_t *rsp; - int32_t rc = 0; - struct qseecom_handle *ta_qseecom_handle; - int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - - if ((client == NULL) || - (sensor_id < 0) || - (sensor_id >= MAX_CAMERAS)) { - pr_err("%s:%d - Bad parameters\n", - __func__, __LINE__); - return -EINVAL; - } - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, cci_cmd=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - cci_cmd); - - ta_qseecom_handle = sensor_info[sensor_id].ta_qseecom_handle; - cmd_len = sizeof(struct msm_camera_tz_i2c_cci_util_req_t); - rsp_len = sizeof(struct msm_camera_tz_i2c_cci_util_rsp_t); - - rc = get_cmd_rsp_buffers(ta_qseecom_handle, - (void **)&cmd, &cmd_len, (void **)&rsp, &rsp_len); - if (!rc) { - cmd->cmd_id = TZ_I2C_CMD_CCI_UTIL; - cmd->sensor_id = sensor_id; - cmd->cci_i2c_master = client->cci_client->cci_i2c_master; - cmd->sid = client->cci_client->sid; - cmd->cid = client->cci_client->cid; - cmd->cci_cmd = cci_cmd; - - rc = qseecom_send_command(ta_qseecom_handle, - (void *)cmd, cmd_len, (void *)rsp, rsp_len); - - if (rc < 0) { - pr_err("%s:%d - Failed: rc=%d\n", - __func__, __LINE__, - rc); - return rc; - } - rc = rsp->rc; - CDBG("Done: rc=%d, cci_cmd=%d\n", rc, cci_cmd); - } - return rc; -} - -static int32_t msm_camera_tz_i2c_ta_probe( - struct msm_camera_i2c_client *client) -{ - int32_t sensor_id = -1; - - CDBG("Enter\n"); - sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - if ((sensor_id >= 0) && sensor_info[sensor_id].ta_enabled - && msm_camera_tz_i2c_ctrl.lock_ready) { - mutex_lock(&msm_camera_tz_i2c_ctrl.lock); - return sensor_id; - } - return -EINVAL; -} - -static int32_t msm_camera_tz_i2c_ta_done(void) -{ - int32_t rc = 0; - - CDBG("Enter\n"); - if (msm_camera_tz_i2c_ctrl.lock_ready) - mutex_unlock(&msm_camera_tz_i2c_ctrl.lock); - return rc; -} - -int32_t msm_camera_tz_i2c_power_up( - struct msm_camera_i2c_client *client) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - - if (!msm_camera_tz_i2c_ctrl.lock_ready) { - msm_camera_tz_i2c_ctrl.lock_ready = 1; - mutex_init(&msm_camera_tz_i2c_ctrl.lock); - } - - CDBG("Enter (sensor_id=%d)\n", sensor_id); - if (sensor_id >= 0) { - ktime_t startTime; - - mutex_lock(&msm_camera_tz_i2c_ctrl.lock); - if (msm_camera_tz_i2c_ctrl.secure_mode) { - mutex_unlock(&msm_camera_tz_i2c_ctrl.lock); - return rc; - } - startTime = ktime_get(); - - CDBG("Switch to secure mode (secure sensor=%d)\n", - sensor_id); - /* Start the TA */ - if ((sensor_info[sensor_id].ta_qseecom_handle == NULL) - && (sensor_info[sensor_id].ta_name != NULL) && - ('\0' != sensor_info[sensor_id].ta_name[0])) { - uint32_t if_version_maj = 0; - uint32_t if_version_min = 0; - - sensor_info[sensor_id].ta_enabled = 0; - rc = qseecom_start_app( - &sensor_info[sensor_id].ta_qseecom_handle, - (char *)sensor_info[sensor_id].ta_name, - QSEECOM_SBUFF_SIZE); - if (!rc) { - rc = msm_camera_tz_i2c_ta_get_if_version( - sensor_info[sensor_id]. - ta_qseecom_handle, - &if_version_maj, &if_version_min); - } - - if (!rc) { - if (if_version_maj != TA_IF_VERSION_MAJ) { - CDBG("TA ver mismatch %d.%d != %d.%d\n", - if_version_maj, if_version_min, - TA_IF_VERSION_MAJ, - TA_IF_VERSION_MIN); - rc = qseecom_shutdown_app( - &sensor_info[sensor_id]. - ta_qseecom_handle); - sensor_info[sensor_id].ta_qseecom_handle - = EMPTY_QSEECOM_HANDLE; - rc = -EFAULT; - } else { - uint32_t sensor_secure = 0; - /*Notify TA & get sensor secure status*/ - rc = msm_camera_tz_i2c_ta_power_up( - sensor_info[sensor_id]. - ta_qseecom_handle, - sensor_id, - &sensor_secure); - if (!rc && sensor_secure) - /* Sensor validated by TA*/ - sensor_info[sensor_id]. - ta_enabled = 1; - else { - qseecom_shutdown_app( - &sensor_info[sensor_id]. - ta_qseecom_handle); - sensor_info[sensor_id]. - ta_qseecom_handle - = EMPTY_QSEECOM_HANDLE; - rc = -EFAULT; - } - } - } - } - CDBG("Init TA %s - %s(%d) - %llu\n", - sensor_info[sensor_id].ta_name, - (sensor_info[sensor_id].ta_enabled)?"Ok" : - "Failed", rc, ktime_us_delta(ktime_get(), - startTime)); - if (!rc) - msm_camera_tz_i2c_ctrl.secure_mode++; - mutex_unlock(&msm_camera_tz_i2c_ctrl.lock); - } - return rc; -} - -int32_t msm_camera_tz_i2c_power_down( - struct msm_camera_i2c_client *client) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_is_sensor_secure(client); - - if (!msm_camera_tz_i2c_ctrl.lock_ready) { - msm_camera_tz_i2c_ctrl.lock_ready = 1; - mutex_init(&msm_camera_tz_i2c_ctrl.lock); - } - - CDBG("Enter (sensor_id=%d)\n", sensor_id); - if ((sensor_id >= 0) && (msm_camera_tz_i2c_ctrl.secure_mode != 0)) { - mutex_lock(&msm_camera_tz_i2c_ctrl.lock); - if (msm_camera_tz_i2c_ctrl.secure_mode == 1) { - ktime_t startTime = ktime_get(); - - CDBG("Switch to non-secure mode (secure sensor=%d)\n", - sensor_id); - /* Shutdown the TA */ - if (sensor_info[sensor_id].ta_qseecom_handle != NULL) { - msm_camera_tz_i2c_ta_power_down( - sensor_info[sensor_id]. - ta_qseecom_handle, - sensor_id); - rc = qseecom_shutdown_app(&sensor_info[ - sensor_id].ta_qseecom_handle); - sensor_info[sensor_id].ta_qseecom_handle - = EMPTY_QSEECOM_HANDLE; - } - CDBG("Unload TA %s - %s(%d) - %llu\n", - sensor_info[sensor_id].ta_name, - (!rc)?"Ok":"Failed", rc, - ktime_us_delta(ktime_get(), startTime)); - } - msm_camera_tz_i2c_ctrl.secure_mode--; - mutex_unlock(&msm_camera_tz_i2c_ctrl.lock); - } - return rc; -} - -int32_t msm_camera_tz_i2c_register_sensor( - void *s_ctrl_p) -{ - struct msm_sensor_ctrl_t *s_ctrl = (struct msm_sensor_ctrl_t *)s_ctrl_p; - - if (s_ctrl == NULL) { - pr_err("%s:%d - invalid parameter)\n", - __func__, __LINE__); - return -EINVAL; - } - if (s_ctrl->id >= MAX_CAMERAS) { - pr_err("%s:%d - invalid ID: %d\n", - __func__, __LINE__, s_ctrl->id); - return -EINVAL; - } - - CDBG("id=%d, client=%pK\n", s_ctrl->id, s_ctrl); - sensor_info[s_ctrl->id].s_ctrl = s_ctrl; - sensor_info[s_ctrl->id].secure = s_ctrl->is_secure; - return 0; -} - -int32_t msm_camera_tz_i2c_read(struct msm_camera_i2c_client *client, - uint32_t addr, uint16_t *data, - enum msm_camera_i2c_data_type data_type) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, addr=0x%08X\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - addr); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_read( - client, addr, data, data_type); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_read, client, addr, data, data_type); -} - -int32_t msm_camera_tz_i2c_read_seq(struct msm_camera_i2c_client *client, - uint32_t addr, uint8_t *data, uint32_t num_byte) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, addr=0x%08X, num=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - addr, - num_byte); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_READ_SEQ); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_read_seq, client, addr, data, num_byte); -} - -int32_t msm_camera_tz_i2c_write(struct msm_camera_i2c_client *client, - uint32_t addr, uint16_t data, - enum msm_camera_i2c_data_type data_type) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, addr=0x%08X\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - addr); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_write( - client, addr, data, data_type); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write, client, addr, data, data_type); -} - -int32_t msm_camera_tz_i2c_write_seq(struct msm_camera_i2c_client *client, - uint32_t addr, uint8_t *data, uint32_t num_byte) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, addr=0x%08X, num=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, - addr, - num_byte); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_SEQ); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_seq, client, addr, data, num_byte); -} - -int32_t msm_camera_tz_i2c_write_table_async( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_TABLE_ASYNC); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_table_async, client, write_setting); -} - -int32_t msm_camera_tz_i2c_write_table_sync( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_table_sync, client, write_setting); -} - -int32_t msm_camera_tz_i2c_write_table_sync_block( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_TABLE_SYNC_BLOCK); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_table_sync_block, client, - write_setting); -} - -int32_t msm_camera_tz_i2c_write_table( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_TABLE); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_table, client, write_setting); -} - -int32_t msm_camera_tz_i2c_write_seq_table( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_seq_reg_setting *write_setting) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_SEQ_TABLE); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_seq_table, client, write_setting); -} - -int32_t msm_camera_tz_i2c_write_table_w_microdelay( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_setting *write_setting) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_TABLE_W_MICRODELAY); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_table_w_microdelay, client, - write_setting); -} - -int32_t msm_camera_tz_i2c_poll(struct msm_camera_i2c_client *client, - uint32_t addr, uint16_t data, - enum msm_camera_i2c_data_type data_type) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_POLL); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_poll, client, addr, data, data_type); -} - -int32_t msm_camera_tz_i2c_write_conf_tbl( - struct msm_camera_i2c_client *client, - struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size, - enum msm_camera_i2c_data_type data_type) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_generic( - client, TZ_I2C_CMD_CCI_WRITE_CONF_TBL); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_camera_cci_i2c_write_conf_tbl, client, reg_conf_tbl, size, - data_type); -} - -int32_t msm_sensor_tz_i2c_util(struct msm_camera_i2c_client *client, - uint16_t cci_cmd) -{ - int32_t rc = -EFAULT; - int32_t sensor_id = msm_camera_tz_i2c_ta_probe(client); - - CDBG("Sensor=%d, MS=%d, SID=%d, CID=%d, cci_cmd=%d\n", - sensor_id, - client->cci_client->cci_i2c_master, - client->cci_client->sid, - client->cci_client->cid, cci_cmd); - - if (sensor_id >= 0) { - rc = msm_camera_tz_i2c_ta_cci_util(client, cci_cmd); - msm_camera_tz_i2c_ta_done(); - } - return TZ_I2C_FN_RETURN(rc, - msm_sensor_cci_i2c_util, client, cci_cmd); -} diff --git a/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c b/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c index 9a5023ac167f..e8f74f8beb1b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c @@ -83,6 +83,7 @@ static int32_t msm_ir_cut_release( return 0; } + rc = ir_cut_ctrl->func_tbl->camera_ir_cut_on(ir_cut_ctrl, NULL); if (rc < 0) { pr_err("%s:%d camera_ir_cut_on failed rc = %d", __func__, __LINE__, rc); @@ -269,6 +270,8 @@ static int32_t msm_ir_cut_handle_init( return -EINVAL; } + rc = ir_cut_ctrl->func_tbl->camera_ir_cut_init( + ir_cut_ctrl, ir_cut_data); if (rc < 0) { pr_err("%s:%d camera_ir_cut_init failed rc = %d", __func__, __LINE__, rc); diff --git a/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c b/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c index 70b4b8dce2be..cfcdb124f44f 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c @@ -15,7 +15,6 @@ #include #include -#include #include "msm_ir_led.h" #include "msm_camera_dt_util.h" @@ -42,6 +41,7 @@ static int32_t msm_ir_led_get_subdev_id( { uint32_t *subdev_id = (uint32_t *)arg; + CDBG("Enter\n"); if (!subdev_id) { pr_err("subdevice ID is not valid\n"); return -EINVAL; @@ -54,6 +54,7 @@ static int32_t msm_ir_led_get_subdev_id( *subdev_id = ir_led_ctrl->pdev->id; CDBG("subdev_id %d\n", *subdev_id); + CDBG("Exit\n"); return 0; } @@ -63,64 +64,45 @@ static int32_t msm_ir_led_init( { int32_t rc = 0; + CDBG("Enter\n"); + rc = ir_led_ctrl->func_tbl->camera_ir_led_off(ir_led_ctrl, ir_led_data); + CDBG("Exit\n"); return rc; } static int32_t msm_ir_led_release( - struct msm_ir_led_ctrl_t *ir_led_ctrl, - struct msm_ir_led_cfg_data_t *ir_led_data) + struct msm_ir_led_ctrl_t *ir_led_ctrl) { - int32_t rc = -EFAULT; + int32_t rc = 0; if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_RELEASE) { pr_err("Invalid ir_led state = %d\n", ir_led_ctrl->ir_led_state); - return rc; + return 0; } - rc = ir_led_ctrl->func_tbl->camera_ir_led_off(ir_led_ctrl, ir_led_data); + rc = ir_led_ctrl->func_tbl->camera_ir_led_off(ir_led_ctrl, NULL); if (rc < 0) { pr_err("camera_ir_led_off failed (%d)\n", rc); return rc; } ir_led_ctrl->ir_led_state = MSM_CAMERA_IR_LED_RELEASE; - - return rc; + return 0; } static int32_t msm_ir_led_off(struct msm_ir_led_ctrl_t *ir_led_ctrl, struct msm_ir_led_cfg_data_t *ir_led_data) { - int32_t rc = 0; - - CDBG("pwm duty on(ns) %d, pwm period(ns) %d\n", - ir_led_data->pwm_duty_on_ns, ir_led_data->pwm_period_ns); - - if (ir_led_data->pwm_period_ns <= 0) - ir_led_data->pwm_period_ns = DEFAULT_PWM_TIME_PERIOD_NS; - - if (ir_led_data->pwm_duty_on_ns != 0) - ir_led_data->pwm_duty_on_ns = DEFAULT_PWM_DUTY_CYCLE_NS; - - if (ir_led_ctrl->pwm_dev) { - rc = pwm_config(ir_led_ctrl->pwm_dev, - ir_led_data->pwm_duty_on_ns, - ir_led_data->pwm_period_ns); - - if (rc) { - pr_err("PWM config failed (%d)\n", rc); - return rc; - } - /*workaround to disable pwm_module*/ - udelay(50); + CDBG("Enter\n"); + if (ir_led_ctrl->pwm_dev) pwm_disable(ir_led_ctrl->pwm_dev); - } else { - CDBG("pwm device is null\n"); - } + else + pr_err("pwm device is null\n"); + CDBG("Exit\n"); return 0; } @@ -128,7 +110,7 @@ static int32_t msm_ir_led_on( struct msm_ir_led_ctrl_t *ir_led_ctrl, struct msm_ir_led_cfg_data_t *ir_led_data) { - int32_t rc = 0; + int rc; CDBG("pwm duty on(ns) %d, pwm period(ns) %d\n", ir_led_data->pwm_duty_on_ns, ir_led_data->pwm_period_ns); @@ -147,9 +129,9 @@ static int32_t msm_ir_led_on( pr_err("PWM enable failed(%d)\n", rc); return rc; } - } else { - CDBG("pwm device is null\n"); - } + } else + pr_err("pwm device is null\n"); + return 0; } @@ -162,10 +144,12 @@ static int32_t msm_ir_led_handle_init( enum msm_ir_led_driver_type ir_led_driver_type = ir_led_ctrl->ir_led_driver_type; + CDBG("Enter\n"); + if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT) { pr_err("Invalid ir_led state = %d\n", ir_led_ctrl->ir_led_state); - return rc; + return 0; } for (i = 0; i < ARRAY_SIZE(ir_led_table); i++) { @@ -191,8 +175,8 @@ static int32_t msm_ir_led_handle_init( ir_led_ctrl->ir_led_state = MSM_CAMERA_IR_LED_INIT; - CDBG("IR LED STATE intialised Successfully\n"); - return rc; + CDBG("Exit\n"); + return 0; } static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl, @@ -202,10 +186,10 @@ static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl, struct msm_ir_led_cfg_data_t *ir_led_data = (struct msm_ir_led_cfg_data_t *) argp; - CDBG("type %d\n", ir_led_data->cfg_type); - mutex_lock(ir_led_ctrl->ir_led_mutex); + CDBG("type %d\n", ir_led_data->cfg_type); + switch (ir_led_data->cfg_type) { case CFG_IR_LED_INIT: rc = msm_ir_led_handle_init(ir_led_ctrl, ir_led_data); @@ -213,7 +197,7 @@ static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl, case CFG_IR_LED_RELEASE: if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT) rc = ir_led_ctrl->func_tbl->camera_ir_led_release( - ir_led_ctrl, ir_led_data); + ir_led_ctrl); break; case CFG_IR_LED_OFF: if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT) @@ -232,7 +216,7 @@ static int32_t msm_ir_led_config(struct msm_ir_led_ctrl_t *ir_led_ctrl, mutex_unlock(ir_led_ctrl->ir_led_mutex); - CDBG("Exit (%d): type %d\n", rc, ir_led_data->cfg_type); + CDBG("Exit: type %d\n", ir_led_data->cfg_type); return rc; } @@ -242,7 +226,8 @@ static long msm_ir_led_subdev_ioctl(struct v4l2_subdev *sd, { struct msm_ir_led_ctrl_t *fctrl = NULL; void __user *argp = (void __user *)arg; - struct msm_ir_led_cfg_data_t ir_led_data = {0}; + + CDBG("Enter\n"); if (!sd) { pr_err(" v4l2 ir led subdevice is NULL\n"); @@ -265,13 +250,13 @@ static long msm_ir_led_subdev_ioctl(struct v4l2_subdev *sd, pr_err("No call back funcions\n"); return -EINVAL; } else { - return fctrl->func_tbl->camera_ir_led_release(fctrl, - &ir_led_data); + return fctrl->func_tbl->camera_ir_led_release(fctrl); } default: pr_err_ratelimited("invalid cmd %d\n", cmd); return -ENOIOCTLCMD; } + CDBG("Exit\n"); } static struct v4l2_subdev_core_ops msm_ir_led_subdev_core_ops = { @@ -282,13 +267,39 @@ static struct v4l2_subdev_ops msm_ir_led_subdev_ops = { .core = &msm_ir_led_subdev_core_ops, }; -static const struct v4l2_subdev_internal_ops msm_ir_led_internal_ops; +static int msm_ir_led_close(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh) { + + int rc = 0; + struct msm_ir_led_ctrl_t *ir_led_ctrl = v4l2_get_subdevdata(sd); + + if (!ir_led_ctrl) { + pr_err("v4l2 subdevice data read failed\n"); + return -EINVAL; + } + + CDBG("Enter\n"); + + if (ir_led_ctrl->ir_led_state == MSM_CAMERA_IR_LED_INIT) + rc = ir_led_ctrl->func_tbl->camera_ir_led_release( + ir_led_ctrl); + + CDBG("Exit (%d)\n", rc); + + return rc; +} + +static const struct v4l2_subdev_internal_ops msm_ir_led_internal_ops = { + .close = msm_ir_led_close, +}; static int32_t msm_ir_led_get_dt_data(struct device_node *of_node, struct msm_ir_led_ctrl_t *fctrl) { int32_t rc = 0; + CDBG("called\n"); + /* Read the sub device */ rc = of_property_read_u32(of_node, "cell-index", &fctrl->pdev->id); if (rc < 0) { @@ -312,6 +323,7 @@ static long msm_ir_led_subdev_do_ioctl( (struct msm_ir_led_cfg_data_t32 *)arg; struct msm_ir_led_cfg_data_t ir_led_data; + CDBG("Enter\n"); ir_led_data.cfg_type = u32->cfg_type; ir_led_data.pwm_duty_on_ns = u32->pwm_duty_on_ns; ir_led_data.pwm_period_ns = u32->pwm_period_ns; @@ -326,6 +338,7 @@ static long msm_ir_led_subdev_do_ioctl( rc = msm_ir_led_subdev_ioctl(sd, cmd, &ir_led_data); + CDBG("Exit\n"); return rc; } @@ -341,6 +354,7 @@ static int32_t msm_ir_led_platform_probe(struct platform_device *pdev) int32_t rc = 0; struct msm_ir_led_ctrl_t *ir_led_ctrl = NULL; + CDBG("Enter\n"); if (!pdev->dev.of_node) { pr_err("IR LED device node is not present in device tree\n"); return -EINVAL; @@ -356,20 +370,16 @@ static int32_t msm_ir_led_platform_probe(struct platform_device *pdev) /* Reading PWM device node */ ir_led_ctrl->pwm_dev = of_pwm_get(pdev->dev.of_node, NULL); - if (PTR_ERR(ir_led_ctrl->pwm_dev) == -EPROBE_DEFER) { - pr_info("Deferring probe...Cannot get PWM device\n"); - return -EPROBE_DEFER; - } - if (IS_ERR(ir_led_ctrl->pwm_dev)) { rc = PTR_ERR(ir_led_ctrl->pwm_dev); - CDBG("Cannot get PWM device (%d)\n", rc); + pr_err("Cannot get PWM device (%d)\n", rc); ir_led_ctrl->pwm_dev = NULL; } rc = msm_ir_led_get_dt_data(pdev->dev.of_node, ir_led_ctrl); if (rc < 0) { pr_err("msm_ir_led_get_dt_data failed\n"); + devm_kfree(&pdev->dev, ir_led_ctrl); return -EINVAL; } @@ -391,12 +401,7 @@ static int32_t msm_ir_led_platform_probe(struct platform_device *pdev) ir_led_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; ir_led_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_IR_LED; ir_led_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1; - - rc = msm_sd_register(&ir_led_ctrl->msm_sd); - if (rc < 0) { - pr_err("sub dev register failed for ir_led device\n"); - return rc; - } + msm_sd_register(&ir_led_ctrl->msm_sd); CDBG("ir_led sd name = %s\n", ir_led_ctrl->msm_sd.sd.entity.name); @@ -426,6 +431,7 @@ static int __init msm_ir_led_init_module(void) { int32_t rc = 0; + CDBG("Enter\n"); rc = platform_driver_register(&msm_ir_led_platform_driver); if (!rc) return rc; diff --git a/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.h b/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.h index 240c7cba5b75..a0923ffc81da 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.h +++ b/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.h @@ -24,10 +24,6 @@ #define DEFINE_MSM_MUTEX(mutexname) \ static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) -/* Default frequency is taken as 15KHz*/ -#define DEFAULT_PWM_TIME_PERIOD_NS 66667 -#define DEFAULT_PWM_DUTY_CYCLE_NS 0 - enum msm_camera_ir_led_state_t { MSM_CAMERA_IR_LED_INIT, MSM_CAMERA_IR_LED_RELEASE, @@ -43,8 +39,7 @@ struct msm_ir_led_ctrl_t; struct msm_ir_led_func_t { int32_t (*camera_ir_led_init)(struct msm_ir_led_ctrl_t *, struct msm_ir_led_cfg_data_t *); - int32_t (*camera_ir_led_release)(struct msm_ir_led_ctrl_t *, - struct msm_ir_led_cfg_data_t *); + int32_t (*camera_ir_led_release)(struct msm_ir_led_ctrl_t *); int32_t (*camera_ir_led_off)(struct msm_ir_led_ctrl_t *, struct msm_ir_led_cfg_data_t *); int32_t (*camera_ir_led_on)(struct msm_ir_led_ctrl_t *, diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c index 87848350255a..35963d5bc561 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c @@ -21,9 +21,6 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) -static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl; -static struct msm_camera_i2c_fn_t msm_sensor_secure_func_tbl; - static void msm_sensor_adjust_mclk(struct msm_camera_power_ctrl_t *ctrl) { int idx; @@ -135,11 +132,6 @@ int msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl) __func__, __LINE__, power_info, sensor_i2c_client); return -EINVAL; } - - /* Power down secure session if it exist*/ - if (s_ctrl->is_secure) - msm_camera_tz_i2c_power_down(sensor_i2c_client); - return msm_camera_power_down(power_info, sensor_device_type, sensor_i2c_client); } @@ -178,27 +170,7 @@ int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl) if (s_ctrl->set_mclk_23880000) msm_sensor_adjust_mclk(power_info); - CDBG("Sensor %d tagged as %s\n", s_ctrl->id, - (s_ctrl->is_secure)?"SECURE":"NON-SECURE"); - for (retry = 0; retry < 3; retry++) { - if (s_ctrl->is_secure) { - rc = msm_camera_tz_i2c_power_up(sensor_i2c_client); - if (rc < 0) { -#ifdef CONFIG_MSM_SEC_CCI_DEBUG - CDBG("Secure Sensor %d use cci\n", s_ctrl->id); - /* session is not secure */ - s_ctrl->sensor_i2c_client->i2c_func_tbl = - &msm_sensor_cci_func_tbl; -#else /* CONFIG_MSM_SEC_CCI_DEBUG */ - return rc; -#endif /* CONFIG_MSM_SEC_CCI_DEBUG */ - } else { - /* session is secure */ - s_ctrl->sensor_i2c_client->i2c_func_tbl = - &msm_sensor_secure_func_tbl; - } - } rc = msm_camera_power_up(power_info, s_ctrl->sensor_device_type, sensor_i2c_client); if (rc < 0) @@ -1480,21 +1452,6 @@ static struct msm_camera_i2c_fn_t msm_sensor_qup_func_tbl = { .i2c_write_table_sync_block = msm_camera_qup_i2c_write_table, }; -static struct msm_camera_i2c_fn_t msm_sensor_secure_func_tbl = { - .i2c_read = msm_camera_tz_i2c_read, - .i2c_read_seq = msm_camera_tz_i2c_read_seq, - .i2c_write = msm_camera_tz_i2c_write, - .i2c_write_table = msm_camera_tz_i2c_write_table, - .i2c_write_seq_table = msm_camera_tz_i2c_write_seq_table, - .i2c_write_table_w_microdelay = - msm_camera_tz_i2c_write_table_w_microdelay, - .i2c_util = msm_sensor_tz_i2c_util, - .i2c_write_conf_tbl = msm_camera_tz_i2c_write_conf_tbl, - .i2c_write_table_async = msm_camera_tz_i2c_write_table_async, - .i2c_write_table_sync = msm_camera_tz_i2c_write_table_sync, - .i2c_write_table_sync_block = msm_camera_tz_i2c_write_table_sync_block, -}; - int32_t msm_sensor_init_default_params(struct msm_sensor_ctrl_t *s_ctrl) { struct msm_camera_cci_client *cci_client = NULL; @@ -1528,9 +1485,6 @@ int32_t msm_sensor_init_default_params(struct msm_sensor_ctrl_t *s_ctrl) /* Get CCI subdev */ cci_client->cci_subdev = msm_cci_get_subdev(); - if (s_ctrl->is_secure) - msm_camera_tz_i2c_register_sensor((void *)s_ctrl); - /* Update CCI / I2C function table */ if (!s_ctrl->sensor_i2c_client->i2c_func_tbl) s_ctrl->sensor_i2c_client->i2c_func_tbl = diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h index 8f55f453bf03..bd12588eada9 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -88,8 +88,6 @@ struct msm_sensor_ctrl_t { enum msm_camera_stream_type_t camera_stream_type; uint32_t set_mclk_23880000; uint8_t is_csid_tg_mode; - uint32_t is_secure; - uint8_t bypass_video_node_creation; }; int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp); diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c old mode 100644 new mode 100755 index 8a0e310ca92a..85fbf162ea4d --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c @@ -10,7 +10,7 @@ * GNU General Public License for more details. */ -#define SENSOR_DRIVER_I2C "camera" +#define SENSOR_DRIVER_I2C "i2c_camera" /* Header file declaration */ #include "msm_sensor.h" #include "msm_sd.h" @@ -86,14 +86,11 @@ static int32_t msm_sensor_driver_create_i2c_v4l_subdev struct i2c_client *client = s_ctrl->sensor_i2c_client->client; CDBG("%s %s I2c probe succeeded\n", __func__, client->name); - if (0 == s_ctrl->bypass_video_node_creation) { - rc = camera_init_v4l2(&client->dev, &session_id); - if (rc < 0) { - pr_err("failed: camera_init_i2c_v4l2 rc %d", rc); - return rc; - } + rc = camera_init_v4l2(&client->dev, &session_id); + if (rc < 0) { + pr_err("failed: camera_init_i2c_v4l2 rc %d", rc); + return rc; } - CDBG("%s rc %d session_id %d\n", __func__, rc, session_id); snprintf(s_ctrl->msm_sd.sd.name, sizeof(s_ctrl->msm_sd.sd.name), "%s", @@ -108,11 +105,7 @@ static int32_t msm_sensor_driver_create_i2c_v4l_subdev s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; s_ctrl->sensordata->sensor_info->session_id = session_id; s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; - rc = msm_sd_register(&s_ctrl->msm_sd); - if (rc < 0) { - pr_err("failed: msm_sd_register rc %d", rc); - return rc; - } + msm_sd_register(&s_ctrl->msm_sd); msm_sensor_v4l2_subdev_fops = v4l2_subdev_fops; #ifdef CONFIG_COMPAT msm_sensor_v4l2_subdev_fops.compat_ioctl32 = @@ -130,14 +123,11 @@ static int32_t msm_sensor_driver_create_v4l_subdev int32_t rc = 0; uint32_t session_id = 0; - if (0 == s_ctrl->bypass_video_node_creation) { - rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id); - if (rc < 0) { - pr_err("failed: camera_init_v4l2 rc %d", rc); - return rc; - } + rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id); + if (rc < 0) { + pr_err("failed: camera_init_v4l2 rc %d", rc); + return rc; } - CDBG("rc %d session_id %d", rc, session_id); s_ctrl->sensordata->sensor_info->session_id = session_id; @@ -152,11 +142,7 @@ static int32_t msm_sensor_driver_create_v4l_subdev s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; - rc = msm_sd_register(&s_ctrl->msm_sd); - if (rc < 0) { - pr_err("failed: msm_sd_register rc %d", rc); - return rc; - } + msm_sd_register(&s_ctrl->msm_sd); msm_cam_copy_v4l2_subdev_fops(&msm_sensor_v4l2_subdev_fops); #ifdef CONFIG_COMPAT msm_sensor_v4l2_subdev_fops.compat_ioctl32 = @@ -720,8 +706,6 @@ int32_t msm_sensor_driver_probe(void *setting, slave_info32->sensor_init_params; slave_info->output_format = slave_info32->output_format; - slave_info->bypass_video_node_creation = - !!slave_info32->bypass_video_node_creation; kfree(slave_info32); } else #endif @@ -734,21 +718,6 @@ int32_t msm_sensor_driver_probe(void *setting, } } - if (strlen(slave_info->sensor_name) >= MAX_SENSOR_NAME || - strlen(slave_info->eeprom_name) >= MAX_SENSOR_NAME || - strlen(slave_info->actuator_name) >= MAX_SENSOR_NAME || - strlen(slave_info->ois_name) >= MAX_SENSOR_NAME) { - pr_err("failed: name len greater than 32.\n"); - pr_err("sensor name len:%zu, eeprom name len: %zu.\n", - strlen(slave_info->sensor_name), - strlen(slave_info->eeprom_name)); - pr_err("actuator name len: %zu, ois name len:%zu.\n", - strlen(slave_info->actuator_name), - strlen(slave_info->ois_name)); - rc = -EINVAL; - goto free_slave_info; - } - /* Print slave info */ CDBG("camera id %d Slave addr 0x%X addr_type %d\n", slave_info->camera_id, slave_info->slave_addr, @@ -764,8 +733,7 @@ int32_t msm_sensor_driver_probe(void *setting, slave_info->sensor_init_params.position); CDBG("mount %d", slave_info->sensor_init_params.sensor_mount_angle); - CDBG("bypass video node creation %d", - slave_info->bypass_video_node_creation); + /* Validate camera id */ if (slave_info->camera_id >= MAX_CAMERAS) { pr_err("failed: invalid camera id %d max %d", @@ -925,8 +893,11 @@ int32_t msm_sensor_driver_probe(void *setting, pr_err("%s probe succeeded", slave_info->sensor_name); - s_ctrl->bypass_video_node_creation = - slave_info->bypass_video_node_creation; + /* + Set probe succeeded flag to 1 so that no other camera shall + * probed on this slot + */ + s_ctrl->is_probe_succeed = 1; /* * Update the subdevice id of flash-src based on availability in kernel. @@ -968,7 +939,7 @@ int32_t msm_sensor_driver_probe(void *setting, } /* Update sensor mount angle and position in media entity flag */ is_yuv = (slave_info->output_format == MSM_SENSOR_YCBCR) ? 1 : 0; - mount_pos = ((s_ctrl->is_secure & 0x1) << 26) | is_yuv << 25 | + mount_pos = is_yuv << 25 | (s_ctrl->sensordata->sensor_info->position << 16) | ((s_ctrl->sensordata-> sensor_info->sensor_mount_angle / 90) << 8); @@ -980,11 +951,6 @@ int32_t msm_sensor_driver_probe(void *setting, msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name); - /* - * Set probe succeeded flag to 1 so that no other camera shall - * probed on this slot - */ - s_ctrl->is_probe_succeed = 1; return rc; camera_power_down: @@ -1060,16 +1026,6 @@ static int32_t msm_sensor_driver_get_dt_data(struct msm_sensor_ctrl_t *s_ctrl) goto FREE_VREG_DATA; } - /* Get custom mode */ - rc = of_property_read_u32(of_node, "qcom,secure", - &s_ctrl->is_secure); - CDBG("qcom,secure = %d, rc %d", s_ctrl->is_secure, rc); - if (rc < 0) { - /* Set default to non-secure mode */ - s_ctrl->is_secure = 0; - rc = 0; - } - /* Get CCI master */ rc = of_property_read_u32(of_node, "qcom,cci-master", &s_ctrl->cci_i2c_master); diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c index 5a70eea3a00b..a2794d680cf8 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c +++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c @@ -615,13 +615,11 @@ static long msm_ois_subdev_ioctl(struct v4l2_subdev *sd, pr_err("o_ctrl->i2c_client.i2c_func_tbl NULL\n"); return -EINVAL; } - mutex_lock(o_ctrl->ois_mutex); rc = msm_ois_power_down(o_ctrl); if (rc < 0) { pr_err("%s:%d OIS Power down failed\n", __func__, __LINE__); } - mutex_unlock(o_ctrl->ois_mutex); return msm_ois_close(sd, NULL); default: return -ENOIOCTLCMD; @@ -893,16 +891,15 @@ static int32_t msm_ois_platform_probe(struct platform_device *pdev) rc = msm_sensor_driver_get_gpio_data(&(msm_ois_t->gconf), (&pdev->dev)->of_node); - if (-ENODEV == rc) { - pr_notice("No valid OIS GPIOs data\n"); - } else if (rc < 0) { - pr_err("Error OIS GPIO\n"); + if (rc < 0) { + pr_err("%s: No/Error OIS GPIO\n", __func__); } else { msm_ois_t->cam_pinctrl_status = 1; rc = msm_camera_pinctrl_init( &(msm_ois_t->pinctrl_info), &(pdev->dev)); if (rc < 0) { - pr_err("ERR: Error in reading OIS pinctrl\n"); + pr_err("ERR:%s: Error in reading OIS pinctrl\n", + __func__); msm_ois_t->cam_pinctrl_status = 0; } } diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h index 762f1c51620c..75d0912aa459 100644 --- a/include/media/msm_cam_sensor.h +++ b/include/media/msm_cam_sensor.h @@ -41,7 +41,6 @@ struct msm_camera_sensor_slave_info32 { uint8_t is_init_params_valid; struct msm_sensor_init_params sensor_init_params; enum msm_sensor_output_format_t output_format; - uint8_t bypass_video_node_creation; }; struct msm_camera_csid_lut_params32 { diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h index 085bd7038094..22e90462573c 100644 --- a/include/media/msmb_isp.h +++ b/include/media/msmb_isp.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,18 +28,7 @@ struct msm_isp_event_data32 { struct msm_isp_sof_info sof_info; } u; }; - -struct msm_isp32_event_data32 { - struct compat_timeval timestamp; - struct compat_timeval mono_timestamp; - enum msm_vfe_input_src input_intf; - uint32_t frame_id; - union { - struct msm_isp_stats_event stats; - struct msm_isp_buf_event buf_done; - struct msm_isp32_error_info error_info; - } u; -}; +#endif #endif -#endif /* __MSMB_ISP__ */ + diff --git a/include/uapi/media/msm_cam_sensor.h b/include/uapi/media/msm_cam_sensor.h index 5b164a8fbf00..3f0e0f7596ab 100644 --- a/include/uapi/media/msm_cam_sensor.h +++ b/include/uapi/media/msm_cam_sensor.h @@ -302,7 +302,7 @@ struct msm_eeprom_cfg_data { enum eeprom_cfg_type_t cfgtype; uint8_t is_supported; union { - char eeprom_name[MAX_SENSOR_NAME]; + char eeprom_name[MAX_EEPROM_NAME]; struct eeprom_get_t get_data; struct eeprom_read_t read_data; struct eeprom_write_t write_data; diff --git a/include/uapi/media/msm_camsensor_sdk.h b/include/uapi/media/msm_camsensor_sdk.h index 83927c614e91..ad0825e33217 100644 --- a/include/uapi/media/msm_camsensor_sdk.h +++ b/include/uapi/media/msm_camsensor_sdk.h @@ -48,8 +48,6 @@ #define MSM_EEPROM_MEMORY_MAP_MAX_SIZE 80 #define MSM_EEPROM_MAX_MEM_MAP_CNT 8 -#define MSM_SENSOR_BYPASS_VIDEO_NODE 1 - enum msm_sensor_camera_id_t { CAMERA_0, CAMERA_1, @@ -302,7 +300,6 @@ struct msm_camera_sensor_slave_info { unsigned char is_init_params_valid; struct msm_sensor_init_params sensor_init_params; enum msm_sensor_output_format_t output_format; - uint8_t bypass_video_node_creation; }; struct msm_camera_i2c_reg_array { diff --git a/include/uapi/media/msm_jpeg_dma.h b/include/uapi/media/msm_jpeg_dma.h index 44fa4ed8af52..df3c7ee5b7cf 100644 --- a/include/uapi/media/msm_jpeg_dma.h +++ b/include/uapi/media/msm_jpeg_dma.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,4 +18,10 @@ /* msm jpeg dma control ID's */ #define V4L2_CID_JPEG_DMA_SPEED (V4L2_CID_PRIVATE_BASE) +/* msm_jpeg_dma_buf */ +struct msm_jpeg_dma_buff { + int32_t fd; + uint32_t offset; +}; + #endif /* __UAPI_MSM_JPEG_DMA__ */ diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h index 2387aedcc05f..364f6544a35a 100644 --- a/include/uapi/media/msmb_isp.h +++ b/include/uapi/media/msmb_isp.h @@ -17,7 +17,6 @@ #define ISP1_BIT (0x10000 << 2) #define ISP_META_CHANNEL_BIT (0x10000 << 3) #define ISP_SCRATCH_BUF_BIT (0x10000 << 4) -#define ISP_PDAF_CHANNEL_BIT (0x10000 << 5) #define ISP_OFFLINE_STATS_BIT (0x10000 << 5) #define ISP_SVHDR_IN_BIT (0x10000 << 6) /* RDI hw stream for SVHDR */ #define ISP_SVHDR_OUT_BIT (0x10000 << 7) /* SVHDR output bufq stream*/ @@ -300,12 +299,6 @@ enum msm_stream_memory_input_t { MEMORY_INPUT_ENABLED }; -enum msm_stream_rdi_input_type { - MSM_CAMERA_RDI_MIN, - MSM_CAMERA_RDI_PDAF, - MSM_CAMERA_RDI_MAX, -}; - struct msm_vfe_axi_stream_request_cmd { uint32_t session_id; uint32_t stream_id; @@ -318,29 +311,6 @@ struct msm_vfe_axi_stream_request_cmd { uint32_t hfr_mode; uint8_t frame_base; - uint32_t init_frame_drop; /*MAX 31 Frames*/ - enum msm_vfe_frame_skip_pattern frame_skip_pattern; - uint8_t buf_divert; /* if TRUE no vb2 buf done. */ - /*Return values*/ - uint32_t axi_stream_handle; - uint32_t controllable_output; - uint32_t burst_len; - /* Flag indicating memory input stream */ - enum msm_stream_rdi_input_type rdi_input_type; -}; - -struct msm_vfe32_axi_stream_request_cmd { - uint32_t session_id; - uint32_t stream_id; - uint32_t vt_enable; - uint32_t output_format;/*Planar/RAW/Misc*/ - enum msm_vfe_axi_stream_src stream_src; /*CAMIF/IDEAL/RDIs*/ - struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM]; - - uint32_t burst_count; - uint32_t hfr_mode; - uint8_t frame_base; - uint32_t init_frame_drop; /*MAX 31 Frames*/ enum msm_vfe_frame_skip_pattern frame_skip_pattern; uint8_t buf_divert; /* if TRUE no vb2 buf done. */ @@ -356,11 +326,6 @@ struct msm_vfe_axi_stream_release_cmd { uint32_t stream_handle; }; -struct msm_vfe_update_fe_frame_id { - uint32_t frame_id; -}; - - enum msm_vfe_axi_stream_cmd { STOP_STREAM, START_STREAM, @@ -439,10 +404,6 @@ struct msm_vfe_axi_restart_cmd { uint32_t enable_camif; }; -struct msm_vfe_restart_fe_cmd { - uint32_t restart_fe; -}; - struct msm_vfe_axi_stream_update_cmd { uint32_t num_streams; enum msm_vfe_axi_stream_update_type update_type; @@ -711,9 +672,7 @@ enum msm_isp_event_idx { ISP_PING_PONG_MISMATCH = 12, ISP_REG_UPDATE_MISSING = 13, ISP_BUF_FATAL_ERROR = 14, - ISP_EVENT_MAX = 15, - ISP_WM_BUS_OVERFLOW = 16, - ISP_CAMIF_ERROR = 17 + ISP_EVENT_MAX = 15 }; #define ISP_EVENT_OFFSET 8 @@ -743,8 +702,6 @@ enum msm_isp_event_idx { #define ISP_EVENT_REG_UPDATE_MISSING (ISP_EVENT_BASE + ISP_REG_UPDATE_MISSING) #define ISP_EVENT_BUF_FATAL_ERROR (ISP_EVENT_BASE + ISP_BUF_FATAL_ERROR) #define ISP_EVENT_STREAM_UPDATE_DONE (ISP_STREAM_EVENT_BASE) -#define ISP_EVENT_CAMIF_ERROR (ISP_EVENT_BASE + ISP_CAMIF_ERROR) -#define ISP_EVENT_WM_BUS_OVERFLOW (ISP_EVENT_BASE + ISP_WM_BUS_OVERFLOW) /* The msm_v4l2_event_data structure should match the * v4l2_event.u.data field. @@ -768,7 +725,6 @@ struct msm_isp_fetch_eng_event { struct msm_isp_stats_event { uint32_t stats_mask; /* 4 bytes */ uint8_t stats_buf_idxs[MSM_ISP_STATS_MAX]; /* 11 bytes */ - uint8_t pd_stats_idx; }; struct msm_isp_stream_ack { @@ -793,11 +749,6 @@ struct msm_isp_error_info { uint32_t stream_id_mask; }; -struct msm_isp32_error_info { - /* 1 << msm_isp_event_idx */ - uint32_t error_mask; -}; - /* This structure reports delta between master and slave */ struct msm_isp_ms_delta_info { uint8_t num_delta_info; @@ -866,25 +817,6 @@ struct msm_isp_event_data { } u; /* union can have max 52 bytes */ }; -struct msm_isp32_event_data { - /*Wall clock except for buffer divert events - *which use monotonic clock - */ - struct timeval timestamp; - /* Monotonic timestamp since bootup */ - struct timeval mono_timestamp; - enum msm_vfe_input_src input_intf; - uint32_t frame_id; - union { - /* Sent for Stats_Done event */ - struct msm_isp_stats_event stats; - /* Sent for Buf_Divert event */ - struct msm_isp_buf_event buf_done; - struct msm_isp32_error_info error_info; - } u; /* union can have max 52 bytes */ - uint32_t is_skip_pproc; -}; - enum msm_vfe_ahb_clk_vote { MSM_ISP_CAMERA_AHB_SVS_VOTE = 1, MSM_ISP_CAMERA_AHB_TURBO_VOTE = 2, @@ -956,9 +888,6 @@ enum msm_isp_ioctl_cmd_code { MSM_ISP_MAP_BUF_START_MULTI_PASS_FE, MSM_ISP_CFG_HW_STATE, MSM_ISP_AHB_CLK_CFG, - MSM_ISP_UPDATE_FE_FRAME_ID, - MSM_ISP_RESTART_FE, - MSM_ISP32_REQUEST_STREAM, }; #define VIDIOC_MSM_VFE_REG_CFG \ @@ -981,10 +910,6 @@ enum msm_isp_ioctl_cmd_code { _IOWR('V', MSM_ISP_REQUEST_STREAM, \ struct msm_vfe_axi_stream_request_cmd) -#define VIDIOC_MSM_ISP32_REQUEST_STREAM \ - _IOWR('V', MSM_ISP32_REQUEST_STREAM, \ - struct msm_vfe32_axi_stream_request_cmd) - #define VIDIOC_MSM_ISP_CFG_STREAM \ _IOWR('V', MSM_ISP_CFG_STREAM, \ struct msm_vfe_axi_stream_cfg_cmd) @@ -1045,10 +970,6 @@ enum msm_isp_ioctl_cmd_code { _IOWR('V', MSM_ISP_AXI_RESTART, \ struct msm_vfe_axi_restart_cmd) -#define VIDIOC_MSM_ISP_RESTART_FE \ - _IOWR('V', MSM_ISP_RESTART_FE,\ - struct msm_vfe_restart_fe_cmd) - #define VIDIOC_MSM_ISP_FETCH_ENG_START \ _IOWR('V', MSM_ISP_FETCH_ENG_START, \ struct msm_vfe_fetch_eng_start) @@ -1065,10 +986,6 @@ enum msm_isp_ioctl_cmd_code { _IOWR('V', MSM_ISP_MAP_BUF_START_FE, \ struct msm_vfe_fetch_eng_start) -#define VIDIOC_MSM_ISP_UPDATE_FE_FRAME_ID \ - _IOWR('V', MSM_ISP_UPDATE_FE_FRAME_ID, \ - struct msm_vfe_update_fe_frame_id) - #define VIDIOC_MSM_ISP_UNMAP_BUF \ _IOWR('V', MSM_ISP_UNMAP_BUF, \ struct msm_isp_unmap_buf_req) @@ -1087,8 +1004,4 @@ enum msm_isp_ioctl_cmd_code { #define VIDIOC_MSM_ISP_AHB_CLK_CFG \ _IOWR('V', MSM_ISP_AHB_CLK_CFG, struct msm_isp_ahb_clk_cfg) - -#define VIDIOC_MSM_ISP_BUF_DONE \ - _IOWR('V', BASE_VIDIOC_PRIVATE+21, struct msm_isp32_event_data) - -#endif/* __MSMB_ISP__ */ +#endif /* __MSMB_ISP__ */ From 70eaf3685122fafde43b2b87aad2ea2f27d5003a Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Sat, 20 May 2017 12:39:30 +0000 Subject: [PATCH 81/86] Revert "msm: isp: Add support for VFE resolution limit" This reverts commit ebdc70c8efc13e523fcc42bb0a582f0f0febafdc. --- .../devicetree/bindings/media/video/msm-vfe.txt | 15 ++++++--------- .../media/platform/msm/camera_v2/isp/msm_isp.h | 1 - .../platform/msm/camera_v2/isp/msm_isp47.c | 17 ++--------------- .../platform/msm/camera_v2/isp/msm_isp_util.c | 14 -------------- include/uapi/media/msmb_isp.h | 10 +++------- 5 files changed, 11 insertions(+), 46 deletions(-) diff --git a/Documentation/devicetree/bindings/media/video/msm-vfe.txt b/Documentation/devicetree/bindings/media/video/msm-vfe.txt index c41bd4ed86ed..39a4bd1601e6 100644 --- a/Documentation/devicetree/bindings/media/video/msm-vfe.txt +++ b/Documentation/devicetree/bindings/media/video/msm-vfe.txt @@ -23,7 +23,6 @@ Required properties for child node: Only needed for child node. - "vfe" - Required. - "vfe_vbif" - Optional for "vfe32". Required for "vfe40". - - "vfe_fuse" - Optional. - interrupts : should contain the vfe interrupt. - interrupt-names : should specify relevant names to each interrupts property defined. @@ -53,10 +52,9 @@ Example: vfe0: qcom,vfe0@fda10000 { cell-index = <0>; compatible = "qcom,vfe44"; - reg = <0xfda10000 0x1000>, - <0xfda40000 0x200>, - <0xa4174 0x8>; - reg-names = "vfe", "vfe_vbif", "vfe_fuse"; + reg = <0xfda10000 0x1000>; + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; interrupts = <0 57 0>; interrupt-names = "vfe"; vdd-supply = <&gdsc_vfe>; @@ -107,10 +105,9 @@ vfe0: qcom,vfe0@fda10000 { vfe1: qcom,vfe1@fda14000 { cell-index = <1>; compatible = "qcom,vfe44"; - reg = <0xfda14000 0x1000>, - <0xfda40000 0x200>, - <0xa4174 0x8>; - reg-names = "vfe", "vfe_vbif", "vfe_fuse"; + reg = <0xfda14000 0x1000>; + <0xfda40000 0x200>; + reg-names = "vfe", "vfe_vbif"; interrupts = <0 58 0>; interrupt-names = "vfe"; vdd-supply = <&gdsc_vfe>; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 63a36a1b2398..386bb9a078b7 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -760,7 +760,6 @@ struct vfe_device { uint32_t is_split; uint32_t dual_vfe_enable; unsigned long page_fault_addr; - uint32_t vfe_hw_limit; /* Debug variables */ int dump_reg; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 8bc46c8b3f56..ba075551dab9 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2575,8 +2575,6 @@ int msm_vfe47_enable_regulators(struct vfe_device *vfe_dev, int enable) int msm_vfe47_get_platform_data(struct vfe_device *vfe_dev) { int rc = 0; - void __iomem *vfe_fuse_base; - uint32_t vfe_fuse_base_size; vfe_dev->vfe_base = msm_camera_get_reg_base(vfe_dev->pdev, "vfe", 0); if (!vfe_dev->vfe_base) @@ -2601,18 +2599,7 @@ int msm_vfe47_get_platform_data(struct vfe_device *vfe_dev) rc = -ENOMEM; goto get_res_fail; } - vfe_dev->vfe_hw_limit = 0; - vfe_fuse_base = msm_camera_get_reg_base(vfe_dev->pdev, - "vfe_fuse", 0); - vfe_fuse_base_size = msm_camera_get_res_size(vfe_dev->pdev, - "vfe_fuse"); - if (vfe_fuse_base) { - if (vfe_fuse_base_size) - vfe_dev->vfe_hw_limit = - (msm_camera_io_r(vfe_fuse_base) >> 7) & 0x3; - msm_camera_put_reg_base(vfe_dev->pdev, vfe_fuse_base, - "vfe_fuse", 0); - } + rc = vfe_dev->hw_info->vfe_ops.platform_ops.get_regulators(vfe_dev); if (rc) goto get_regulator_fail; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 7d1882c2c271..b34588778438 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1380,20 +1380,6 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, vfe_dev->vfe_ub_policy = *cfg_data; break; } - case GET_VFE_HW_LIMIT: { - uint32_t *hw_limit = NULL; - - if (cmd_len < sizeof(uint32_t)) { - pr_err("%s:%d failed: invalid cmd len %u exp %zu\n", - __func__, __LINE__, cmd_len, - sizeof(uint32_t)); - return -EINVAL; - } - - hw_limit = (uint32_t *)cfg_data; - *hw_limit = vfe_dev->vfe_hw_limit; - break; - } } return 0; } diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h index 364f6544a35a..9fbcacac4930 100644 --- a/include/uapi/media/msmb_isp.h +++ b/include/uapi/media/msmb_isp.h @@ -23,8 +23,6 @@ #define ISP_STATS_STREAM_BIT 0x80000000 -#define VFE_HW_LIMIT 1 - struct msm_vfe_cfg_cmd_list; enum ISP_START_PIXEL_PATTERN { @@ -463,7 +461,6 @@ enum msm_vfe_reg_cfg_type { VFE_HW_UPDATE_UNLOCK, SET_WM_UB_SIZE, SET_UB_POLICY, - GET_VFE_HW_LIMIT, }; struct msm_vfe_cfg_cmd2 { @@ -887,7 +884,6 @@ enum msm_isp_ioctl_cmd_code { MSM_ISP_FETCH_ENG_MULTI_PASS_START, MSM_ISP_MAP_BUF_START_MULTI_PASS_FE, MSM_ISP_CFG_HW_STATE, - MSM_ISP_AHB_CLK_CFG, }; #define VIDIOC_MSM_VFE_REG_CFG \ @@ -990,6 +986,9 @@ enum msm_isp_ioctl_cmd_code { _IOWR('V', MSM_ISP_UNMAP_BUF, \ struct msm_isp_unmap_buf_req) +#define VIDIOC_MSM_ISP_AHB_CLK_CFG \ + _IOWR('V', BASE_VIDIOC_PRIVATE+25, struct msm_isp_ahb_clk_cfg) + #define VIDIOC_MSM_ISP_FETCH_ENG_MULTI_PASS_START \ _IOWR('V', MSM_ISP_FETCH_ENG_MULTI_PASS_START, \ struct msm_vfe_fetch_eng_multi_pass_start) @@ -1001,7 +1000,4 @@ enum msm_isp_ioctl_cmd_code { #define VIDIOC_MSM_ISP_CFG_HW_STATE \ _IOWR('V', MSM_ISP_CFG_HW_STATE, \ struct msm_vfe_axi_stream_cfg_cmd) - -#define VIDIOC_MSM_ISP_AHB_CLK_CFG \ - _IOWR('V', MSM_ISP_AHB_CLK_CFG, struct msm_isp_ahb_clk_cfg) #endif /* __MSMB_ISP__ */ From 5af29f89dd30ef89644ed4f1104cd70ff26ba5d0 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Sat, 20 May 2017 15:57:28 +0000 Subject: [PATCH 82/86] Revert "msm: camera: isp: Handle standby mode for B+M" This reverts commit 12895349181eee37f58049a5f6c6872bf585e81c. --- .../msm/camera_v2/isp/msm_isp_axi_util.c | 27 +++++++------------ .../msm/camera_v2/isp/msm_isp_axi_util.h | 2 -- .../platform/msm/camera_v2/isp/msm_isp_util.c | 6 ----- include/uapi/media/msmb_isp.h | 12 --------- 4 files changed, 9 insertions(+), 38 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 1e1b5af4b12f..44bc5fe90429 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -17,6 +17,7 @@ #define HANDLE_TO_IDX(handle) (handle & 0xFF) #define ISP_SOF_DEBUG_COUNT 0 + static int msm_isp_update_dual_HW_ms_info_at_start( struct vfe_device *vfe_dev, enum msm_vfe_input_src stream_src, @@ -2211,10 +2212,9 @@ static void msm_isp_update_camif_output_count( /*Factor in Q2 format*/ #define ISP_DEFAULT_FORMAT_FACTOR 6 #define ISP_BUS_UTILIZATION_FACTOR 6 -int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev, - enum msm_vfe_hw_state hw_state) +static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev) { - int i, rc = 0, frame_src, ms_type; + int i, rc = 0; struct msm_vfe_axi_stream *stream_info; struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; uint64_t total_pix_bandwidth = 0, total_rdi_bandwidth = 0; @@ -2223,15 +2223,6 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev, for (i = 0; i < VFE_AXI_SRC_MAX; i++) { stream_info = &axi_data->stream_info[i]; - frame_src = SRC_TO_INTF(stream_info->stream_src); - ms_type = vfe_dev->axi_data.src_info[frame_src]. - dual_hw_ms_info.dual_hw_ms_type; - if (hw_state == HW_STATE_SLEEP) { - rc = msm_isp_update_bandwidth( - ISP_VFE0 + vfe_dev->pdev->id, 0, 0); - return rc; - } - if (stream_info->state == ACTIVE || stream_info->state == START_PENDING) { if (stream_info->stream_src < RDI_INTF_0) { @@ -2242,11 +2233,11 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev, } } } - total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth; - rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, - (total_bandwidth + vfe_dev->hw_info->min_ab), - (total_bandwidth + vfe_dev->hw_info->min_ib)); + rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, + (total_bandwidth + vfe_dev->hw_info->min_ab), + (total_bandwidth + vfe_dev->hw_info->min_ib)); + if (rc < 0) pr_err("%s: update failed\n", __func__); @@ -2848,7 +2839,7 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev, } } } - msm_isp_update_stream_bandwidth(vfe_dev, stream_cfg_cmd->hw_state); + msm_isp_update_stream_bandwidth(vfe_dev); vfe_dev->hw_info->vfe_ops.axi_ops.reload_wm(vfe_dev, vfe_dev->vfe_base, wm_reload_mask); msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd); @@ -3040,7 +3031,7 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, } msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd); - msm_isp_update_stream_bandwidth(vfe_dev, stream_cfg_cmd->hw_state); + msm_isp_update_stream_bandwidth(vfe_dev); for (i = 0; i < stream_cfg_cmd->num_streams; i++) { stream_info = &axi_data->stream_info[ diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h index 1fb9f4e0b49a..4f036374a8b1 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h @@ -51,8 +51,6 @@ void msm_isp_reset_framedrop(struct vfe_device *vfe_dev, int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg); void msm_isp_get_avtimer_ts(struct msm_isp_timestamp *time_stamp); int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg); -int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev, - enum msm_vfe_hw_state hw_state); int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg); int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg); void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index b34588778438..3208d8e5bf09 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -857,12 +857,6 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd, rc = msm_isp_cfg_axi_stream(vfe_dev, arg); mutex_unlock(&vfe_dev->core_mutex); break; - case VIDIOC_MSM_ISP_CFG_HW_STATE: - mutex_lock(&vfe_dev->core_mutex); - rc = msm_isp_update_stream_bandwidth(vfe_dev, - *(enum msm_vfe_hw_state *)arg); - mutex_unlock(&vfe_dev->core_mutex); - break; case VIDIOC_MSM_ISP_AXI_HALT: mutex_lock(&vfe_dev->core_mutex); rc = msm_isp_axi_halt(vfe_dev, arg); diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h index 9fbcacac4930..e4d41d4072c5 100644 --- a/include/uapi/media/msmb_isp.h +++ b/include/uapi/media/msmb_isp.h @@ -330,18 +330,11 @@ enum msm_vfe_axi_stream_cmd { STOP_IMMEDIATELY, }; -enum msm_vfe_hw_state { - HW_STATE_NONE, - HW_STATE_SLEEP, - HW_STATE_AWAKE, -}; - struct msm_vfe_axi_stream_cfg_cmd { uint8_t num_streams; uint32_t stream_handle[VFE_AXI_SRC_MAX]; enum msm_vfe_axi_stream_cmd cmd; uint8_t sync_frame_id_src; - enum msm_vfe_hw_state hw_state; }; enum msm_vfe_axi_stream_update_type { @@ -883,7 +876,6 @@ enum msm_isp_ioctl_cmd_code { MSM_ISP_UNMAP_BUF, MSM_ISP_FETCH_ENG_MULTI_PASS_START, MSM_ISP_MAP_BUF_START_MULTI_PASS_FE, - MSM_ISP_CFG_HW_STATE, }; #define VIDIOC_MSM_VFE_REG_CFG \ @@ -996,8 +988,4 @@ enum msm_isp_ioctl_cmd_code { #define VIDIOC_MSM_ISP_MAP_BUF_START_MULTI_PASS_FE \ _IOWR('V', MSM_ISP_MAP_BUF_START_MULTI_PASS_FE, \ struct msm_vfe_fetch_eng_multi_pass_start) - -#define VIDIOC_MSM_ISP_CFG_HW_STATE \ - _IOWR('V', MSM_ISP_CFG_HW_STATE, \ - struct msm_vfe_axi_stream_cfg_cmd) #endif /* __MSMB_ISP__ */ From cb2e73e80261cd3eb2bb4f00033cddc7f8be7846 Mon Sep 17 00:00:00 2001 From: TheScarastic Date: Thu, 18 May 2017 07:54:09 +0000 Subject: [PATCH 83/86] drivers: camera_v2: Import Camera changes --- .../msm/camera_v2/sensor/cci/msm_cci.c | 2 +- .../msm/camera_v2/sensor/csid/msm_csid.c | 2 +- .../msm/camera_v2/sensor/eeprom/msm_eeprom.c | 22 +++++++++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c index 7a9977d9409b..586b693b0fb3 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c +++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c @@ -32,7 +32,7 @@ #define CYCLES_PER_MICRO_SEC_DEFAULT 4915 #define CCI_MAX_DELAY 1000000 -#define CCI_TIMEOUT msecs_to_jiffies(500) +#define CCI_TIMEOUT msecs_to_jiffies(800) /* TODO move this somewhere else */ #define MSM_CCI_DRV_NAME "msm_cci" diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c index bcac5592c193..5b9b2e908561 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c +++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c @@ -62,7 +62,7 @@ #define FALSE 0 #define MAX_LANE_COUNT 4 -#define CSID_TIMEOUT msecs_to_jiffies(100) +#define CSID_TIMEOUT msecs_to_jiffies(500) #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) diff --git a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c index dd2f9192e32f..e6e48edc611b 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c +++ b/drivers/media/platform/msm/camera_v2/sensor/eeprom/msm_eeprom.c @@ -1,4 +1,5 @@ /* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (C) 2017 XiaoMi, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -152,6 +153,10 @@ static int read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl, struct msm_eeprom_board_info *eb_info; uint8_t *memptr = block->mapdata; + uint8_t sensor_id[2] = {0}; + + pr_err("%s %d\n", __func__, __LINE__); + if (!e_ctrl) { pr_err("%s e_ctrl is NULL", __func__); return -EINVAL; @@ -159,6 +164,19 @@ static int read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl, eb_info = e_ctrl->eboard_info; + if (1) { + e_ctrl->i2c_client.addr_type = 2; + rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_read_seq( + &(e_ctrl->i2c_client), 0x0000, + sensor_id, 2); + if (rc < 0) { + pr_err("%s %d error\n", __func__, __LINE__); + return rc; + } + + CDBG("%s %d addr [0x0000] = %x, [0x0001] = %x\n", __func__, __LINE__, sensor_id[0], sensor_id[1]); + } + for (j = 0; j < block->num_map; j++) { if (emap[j].saddr.addr) { eb_info->i2c_slaveaddr = emap[j].saddr.addr; @@ -415,7 +433,7 @@ static int eeprom_parse_memory_map(struct msm_eeprom_ctrl_t *e_ctrl, } memptr = e_ctrl->cal_data.mapdata; for (i = 0; i < e_ctrl->cal_data.num_data; i++) - CDBG("memory_data[%d] = 0x%X\n", i, memptr[i]); + CDBG("%s %d memory_data[%d] = 0x%X\n", __func__, __LINE__, i, memptr[i]); return rc; clean_up: @@ -1722,7 +1740,7 @@ static int msm_eeprom_platform_probe(struct platform_device *pdev) goto power_down; } for (j = 0; j < e_ctrl->cal_data.num_data; j++) - CDBG("memory_data[%d] = 0x%X\n", j, + CDBG("%s %d memory_data[%d] = 0x%X\n", __func__, __LINE__, j, e_ctrl->cal_data.mapdata[j]); e_ctrl->is_supported |= msm_eeprom_match_crc(&e_ctrl->cal_data); From 745b9cd84dde9da08f5b55b6f73fb213cf14012f Mon Sep 17 00:00:00 2001 From: Animesh Kishore Date: Tue, 11 Apr 2017 19:40:24 +0530 Subject: [PATCH 84/86] msm: mdss: Add multi-rectangle validation support Rectangle number is being passed to kernel from userspace. Added required validation checks. CRs-Fixed: 2000464 Change-Id: I179caa1a86beb9a8f5f3f9b9ef489bf1fd12c73e Signed-off-by: Animesh Kishore --- drivers/video/msm/mdss/mdss_compat_utils.c | 1 + drivers/video/msm/mdss/mdss_compat_utils.h | 3 +- drivers/video/msm/mdss/mdss_mdp_layer.c | 213 +++++++++++++-------- include/uapi/linux/msm_mdp_ext.h | 14 +- 4 files changed, 144 insertions(+), 87 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c index 558c2d7c1dde..8c94cdc1ef65 100644 --- a/drivers/video/msm/mdss/mdss_compat_utils.c +++ b/drivers/video/msm/mdss/mdss_compat_utils.c @@ -222,6 +222,7 @@ static struct mdp_input_layer *__create_layer_list( layer->flags = layer32->flags; layer->pipe_ndx = layer32->pipe_ndx; + layer->rect_num = layer32->rect_num; layer->horz_deci = layer32->horz_deci; layer->vert_deci = layer32->vert_deci; layer->z_order = layer32->z_order; diff --git a/drivers/video/msm/mdss/mdss_compat_utils.h b/drivers/video/msm/mdss/mdss_compat_utils.h index e89142d82ad0..be39296c317d 100644 --- a/drivers/video/msm/mdss/mdss_compat_utils.h +++ b/drivers/video/msm/mdss/mdss_compat_utils.h @@ -515,7 +515,8 @@ struct mdp_input_layer32 { struct mdp_layer_buffer buffer; compat_caddr_t pp_info; int error_code; - uint32_t reserved[6]; + uint32_t rect_num; + uint32_t reserved[5]; }; struct mdp_output_layer32 { diff --git a/drivers/video/msm/mdss/mdss_mdp_layer.c b/drivers/video/msm/mdss/mdss_mdp_layer.c index 3ff446cd1d51..729dd1388921 100644 --- a/drivers/video/msm/mdss/mdss_mdp_layer.c +++ b/drivers/video/msm/mdss/mdss_mdp_layer.c @@ -1513,115 +1513,157 @@ static int __multirect_validate_mode(struct msm_fb_data_type *mfd, return 0; } -static int __update_multirect_info(struct msm_fb_data_type *mfd, - struct mdss_mdp_validate_info_t *validate_info_list, - struct mdp_input_layer *layer_list, int ndx, int layer_cnt) +/* + * linear search for a layer with given source pipe and rectangle number. + * If rectangle number is invalid, it's dropped from search criteria + */ +static int find_layer(enum mdss_mdp_sspp_index pnum, + int rect_num, + struct mdp_input_layer *layer_list, + size_t layer_cnt, int start_index) { - struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - struct mdss_mdp_validate_info_t *vinfo[MDSS_MDP_PIPE_MAX_RECTS]; - int i, ptype, max_rects, mode; - int cnt = 1; + int i; - mode = __multirect_layer_flags_to_mode(layer_list[ndx].flags); - if (IS_ERR_VALUE(mode)) - return mode; + if (start_index < 0) + start_index = 0; - pr_debug("layer #%d pipe_ndx=%d multirect mode=%d\n", - ndx, layer_list[ndx].pipe_ndx, mode); + if (start_index >= layer_cnt) + return -EINVAL; - vinfo[0] = &validate_info_list[ndx]; - vinfo[0]->layer = &layer_list[ndx]; - vinfo[0]->multirect.mode = mode; - vinfo[0]->multirect.num = MDSS_MDP_PIPE_RECT0; - vinfo[0]->multirect.next = NULL; + for (i = start_index; i < layer_cnt; i++) { + if (get_pipe_num_from_ndx(layer_list[i].pipe_ndx) == pnum && + (rect_num < MDSS_MDP_PIPE_RECT0 || + rect_num >= MDSS_MDP_PIPE_MAX_RECTS || + layer_list[i].rect_num == rect_num)) + return i; + } - /* nothing to be done if multirect is disabled */ - if (mode == MDSS_MDP_PIPE_MULTIRECT_NONE) - return cnt; + return -ENOENT; /* no match found */ +} - ptype = get_pipe_type_from_ndx(layer_list[ndx].pipe_ndx); - if (ptype == MDSS_MDP_PIPE_TYPE_INVALID) { - pr_err("invalid pipe ndx %d\n", layer_list[ndx].pipe_ndx); - return -EINVAL; - } +static int __validate_multirect_param(struct msm_fb_data_type *mfd, + struct mdss_mdp_validate_info_t *validate_info_list, + struct mdp_input_layer *layer_list, + int ndx, size_t layer_count) +{ + int multirect_mode; + int pnum; + int rect_num; + + /* populate v_info with default values */ + validate_info_list[ndx].layer = &layer_list[ndx]; + validate_info_list[ndx].multirect.max_rects = MDSS_MDP_PIPE_MAX_RECTS; + validate_info_list[ndx].multirect.next = NULL; + validate_info_list[ndx].multirect.num = MDSS_MDP_PIPE_RECT0; + validate_info_list[ndx].multirect.mode = MDSS_MDP_PIPE_MULTIRECT_NONE; + + multirect_mode = __multirect_layer_flags_to_mode( + layer_list[ndx].flags); + if (IS_ERR_VALUE(multirect_mode)) + return multirect_mode; - max_rects = mdata->rects_per_sspp[ptype] ? : 1; + /* nothing to be done if multirect is disabled */ + if (multirect_mode == MDSS_MDP_PIPE_MULTIRECT_NONE) + return 0; - for (i = ndx + 1; i < layer_cnt; i++) { - if (layer_list[ndx].pipe_ndx == layer_list[i].pipe_ndx) { - if (cnt >= max_rects) { - pr_err("more than %d layers of type %d with same pipe_ndx=%d indexes=%d %d\n", - max_rects, ptype, - layer_list[ndx].pipe_ndx, ndx, i); - return -EINVAL; - } + validate_info_list[ndx].multirect.mode = multirect_mode; - mode = __multirect_layer_flags_to_mode( - layer_list[i].flags); - if (IS_ERR_VALUE(mode)) - return mode; + pnum = get_pipe_num_from_ndx(layer_list[ndx].pipe_ndx); + if (get_pipe_type_from_num(pnum) != MDSS_MDP_PIPE_TYPE_DMA) { + pr_err("Multirect not supported on pipe ndx 0x%x\n", + layer_list[ndx].pipe_ndx); + return -EINVAL; + } - if (mode != vinfo[0]->multirect.mode) { - pr_err("unable to set different multirect modes for pipe_ndx=%d (%d %d)\n", - layer_list[ndx].pipe_ndx, ndx, i); - return -EINVAL; - } + rect_num = layer_list[ndx].rect_num; + if (rect_num >= MDSS_MDP_PIPE_MAX_RECTS) + return -EINVAL; + validate_info_list[ndx].multirect.num = rect_num; - pr_debug("found matching pair for pipe_ndx=%d (%d %d)\n", - layer_list[i].pipe_ndx, ndx, i); + return 0; +} - vinfo[cnt] = &validate_info_list[i]; - vinfo[cnt]->multirect.num = cnt; - vinfo[cnt]->multirect.next = vinfo[0]->layer; - vinfo[cnt]->multirect.mode = mode; - vinfo[cnt]->layer = &layer_list[i]; +static int __update_multirect_info(struct msm_fb_data_type *mfd, + struct mdss_mdp_validate_info_t *validate_info_list, + struct mdp_input_layer *layer_list, + int ndx, size_t layer_cnt, int is_rect_num_valid) +{ + int ret; + int pair_rect_num = -1; + int pair_index; + + if (!is_rect_num_valid) + layer_list[ndx].rect_num = MDSS_MDP_PIPE_RECT0; + + ret = __validate_multirect_param(mfd, validate_info_list, + layer_list, ndx, layer_cnt); + /* return if we hit error or multirectangle mode is disabled. */ + if (IS_ERR_VALUE(ret) || + (!ret && validate_info_list[ndx].multirect.mode == + MDSS_MDP_PIPE_MULTIRECT_NONE)) + return ret; - vinfo[cnt - 1]->multirect.next = vinfo[cnt]->layer; - cnt++; - } - } + if (is_rect_num_valid) + pair_rect_num = (validate_info_list[ndx].multirect.num == + MDSS_MDP_PIPE_RECT0) ? MDSS_MDP_PIPE_RECT1 : + MDSS_MDP_PIPE_RECT0; - if (cnt == 1) { - pr_err("multirect mode enabled but unable to find extra rects for pipe_ndx=%x\n", + pair_index = find_layer(get_pipe_num_from_ndx( + layer_list[ndx].pipe_ndx), pair_rect_num, + layer_list, layer_cnt, ndx + 1); + if (IS_ERR_VALUE(pair_index)) { + pr_err("Multirect pair not found for pipe ndx 0x%x\n", layer_list[ndx].pipe_ndx); return -EINVAL; } - return cnt; + if (!is_rect_num_valid) + layer_list[pair_index].rect_num = MDSS_MDP_PIPE_RECT1; + + ret = __validate_multirect_param(mfd, validate_info_list, + layer_list, pair_index, layer_cnt); + if (IS_ERR_VALUE(ret) || + (validate_info_list[ndx].multirect.mode != + validate_info_list[pair_index].multirect.mode)) + return -EINVAL; + + validate_info_list[ndx].multirect.next = &layer_list[pair_index]; + validate_info_list[pair_index].multirect.next = &layer_list[ndx]; + + return 0; } static int __validate_multirect(struct msm_fb_data_type *mfd, - struct mdss_mdp_validate_info_t *validate_info_list, - struct mdp_input_layer *layer_list, int ndx, int layer_cnt) + struct mdss_mdp_validate_info_t *validate_info_list, + struct mdp_input_layer *layer_list, + int ndx, size_t layer_cnt, int is_rect_num_valid) { - struct mdp_input_layer *layers[MDSS_MDP_PIPE_MAX_RECTS] = { 0 }; - int i, cnt, rc; - - cnt = __update_multirect_info(mfd, validate_info_list, - layer_list, ndx, layer_cnt); - if (IS_ERR_VALUE(cnt)) - return cnt; - - if (cnt <= 1) { - /* nothing to validate in single rect mode */ - return 0; - } else if (cnt > 2) { - pr_err("unsupported multirect configuration, multirect cnt=%d\n", - cnt); - return -EINVAL; - } + int ret; + int i; + struct mdp_input_layer *layers[MDSS_MDP_PIPE_MAX_RECTS]; + struct mdp_input_layer *pair_layer; + + ret = __update_multirect_info(mfd, validate_info_list, + layer_list, ndx, layer_cnt, is_rect_num_valid); + /* return if we hit error or multirectangle mode is disabled. */ + if (IS_ERR_VALUE(ret) || + (!ret && validate_info_list[ndx].multirect.mode == + MDSS_MDP_PIPE_MULTIRECT_NONE)) + return ret; - layers[0] = validate_info_list[ndx].layer; - layers[1] = validate_info_list[ndx].multirect.next; + layers[validate_info_list[ndx].multirect.num] = &layer_list[ndx]; + pair_layer = validate_info_list[ndx].multirect.next; + layers[pair_layer->rect_num] = pair_layer; + /* check against smart DMA v1.0 restrictions */ for (i = 0; i < ARRAY_SIZE(__multirect_validators); i++) { - if (!__multirect_validators[i](layers, cnt)) + if (!__multirect_validators[i](layers, + MDSS_MDP_PIPE_MAX_RECTS)) return -EINVAL; } - - rc = __multirect_validate_mode(mfd, layers, cnt); - if (IS_ERR_VALUE(rc)) - return rc; + ret = __multirect_validate_mode(mfd, layers, MDSS_MDP_PIPE_MAX_RECTS); + if (IS_ERR_VALUE(ret)) + return ret; return 0; } @@ -1693,14 +1735,14 @@ static int __validate_layers(struct msm_fb_data_type *mfd, if (!validate_info_list[i].layer) { ret = __validate_multirect(mfd, validate_info_list, - layer_list, i, layer_count); + layer_list, i, layer_count, + !!(commit->flags & MDP_COMMIT_RECT_NUM)); if (ret) { pr_err("error validating multirect config. ret=%d i=%d\n", ret, i); goto end; } } - rect_num = validate_info_list[i].multirect.num; BUG_ON(rect_num >= MDSS_MDP_PIPE_MAX_RECTS); @@ -2062,7 +2104,8 @@ int mdss_mdp_layer_pre_commit(struct msm_fb_data_type *mfd, for (i = 0; i < layer_count; i++) { if (!validate_info_list[i].layer) { ret = __update_multirect_info(mfd, validate_info_list, - layer_list, i, layer_count); + layer_list, i, layer_count, + !!(commit->flags & MDP_COMMIT_RECT_NUM)); if (IS_ERR_VALUE(ret)) { pr_err("error updating multirect config. ret=%d i=%d\n", ret, i); diff --git a/include/uapi/linux/msm_mdp_ext.h b/include/uapi/linux/msm_mdp_ext.h index 96c80dd50d85..75318e8337de 100644 --- a/include/uapi/linux/msm_mdp_ext.h +++ b/include/uapi/linux/msm_mdp_ext.h @@ -138,6 +138,12 @@ VALIDATE/COMMIT FLAG CONFIGURATION */ #define MDP_COMMIT_SYNC_FENCE_WAIT 0x04 +/* + * Flag to indicate that rectangle number is being assigned + * by userspace in multi-rectangle mode + */ +#define MDP_COMMIT_RECT_NUM 0x2000 + #define MDP_COMMIT_VERSION_1_0 0x00010000 #define OUT_LAYER_COLOR_SPACE @@ -314,8 +320,14 @@ struct mdp_input_layer { */ int error_code; + /* + * For source pipes supporting multi-rectangle, this field identifies + * the rectangle index of the source pipe. + */ + uint32_t rect_num; + /* 32bits reserved value for future usage. */ - uint32_t reserved[6]; + uint32_t reserved[5]; }; struct mdp_output_layer { From dd0e25af078856028437c6594cdc525434db627e Mon Sep 17 00:00:00 2001 From: Benjamin Chan Date: Wed, 26 Apr 2017 15:10:37 -0400 Subject: [PATCH 85/86] msm: mdss: Retrict use of DMA Multi-Rect for FB pan_display For non-atomic display commit that use pan_display, it is not possible to use multi-rect feature from the DMA pipe. This fix is to reject any multi-rect DMA pipe being used in the commit when all the non multi-rect DMA pipes are not available. CRs-Fixed: 2036486 Change-Id: I16722d62650807b5f46ca2bb544653f43a01edf1 Signed-off-by: Benjamin Chan --- drivers/video/msm/mdss/mdss_mdp_overlay.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index 6006a390a512..cfd2094c41af 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -3427,6 +3427,13 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd) goto iommu_disable; } + if (l_pipe_allocated && + (l_pipe->multirect.num == MDSS_MDP_PIPE_RECT1)) { + pr_err("Invalid: L_Pipe-%d is assigned for RECT-%d\n", + l_pipe->num, l_pipe->multirect.num); + goto pipe_release; + } + if (mdss_mdp_pipe_map(l_pipe)) { pr_err("unable to map base pipe\n"); goto pipe_release; @@ -3474,6 +3481,16 @@ static void mdss_mdp_overlay_pan_display(struct msm_fb_data_type *mfd) goto pipe_release; } + if (l_pipe_allocated && r_pipe_allocated && + (l_pipe->num != r_pipe->num) && + (r_pipe->multirect.num == + MDSS_MDP_PIPE_RECT1)) { + pr_err("Invalid: L_Pipe-%d,RECT-%d R_Pipe-%d,RECT-%d\n", + l_pipe->num, l_pipe->multirect.num, + r_pipe->num, l_pipe->multirect.num); + goto iommu_disable; + } + if (mdss_mdp_pipe_map(r_pipe)) { pr_err("unable to map right base pipe\n"); goto pipe_release; From 8ad26d10da62c56935079e16ac6a122f0eed71dd Mon Sep 17 00:00:00 2001 From: "dukwung.kim" Date: Thu, 7 Dec 2017 18:37:32 +0530 Subject: [PATCH 86/86] power: qpnp-smbcharger: init power supply type as USB If power supply type is POWER_SUPPLY_TYPE_UNKNOWN at bootup, some userspace apps, such as heathd, fail to parse power supply properties. So, set power supply type to USB when the charger is not plugged during bootup. Change-Id: Iad3881b0fadb36ace6e5f2de6eaeac11f33a532c Signed-off-by: dukwung.kim Signed-off-by: choongryeol.lee --- drivers/power/qpnp-smbcharger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c index 75c0f1b6dea5..a5a0618cbf24 100644 --- a/drivers/power/qpnp-smbcharger.c +++ b/drivers/power/qpnp-smbcharger.c @@ -4930,7 +4930,7 @@ printk("set_usb_charge_mode_par off = %d\n", set_usb_charge_mode_par); /* cancel/wait for hvdcp pending work if any */ cancel_delayed_work_sync(&chip->hvdcp_det_work); smbchg_relax(chip, PM_DETECT_HVDCP); - smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN); + smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_USB); if (chip->parallel.use_parallel_aicl) { complete_all(&chip->hvdcp_det_done);